summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
Diffstat (limited to 'indra')
-rwxr-xr-x[-rw-r--r--]indra/CMakeLists.txt112
-rwxr-xr-x[-rw-r--r--]indra/cmake/00-Common.cmake85
-rwxr-xr-x[-rw-r--r--]indra/cmake/APR.cmake2
-rwxr-xr-x[-rw-r--r--]indra/cmake/Audio.cmake0
-rwxr-xr-x[-rw-r--r--]indra/cmake/BerkeleyDB.cmake0
-rwxr-xr-x[-rw-r--r--]indra/cmake/Boost.cmake94
-rwxr-xr-x[-rw-r--r--]indra/cmake/BuildVersion.cmake62
-rwxr-xr-x[-rw-r--r--]indra/cmake/CARes.cmake0
-rwxr-xr-x[-rw-r--r--]indra/cmake/CMakeCopyIfDifferent.cmake0
-rwxr-xr-x[-rw-r--r--]indra/cmake/CMakeLists.txt54
-rw-r--r--indra/cmake/CSharpMacros.cmake142
-rwxr-xr-x[-rw-r--r--]indra/cmake/CURL.cmake0
-rw-r--r--indra/cmake/ConfigurePkgConfig.cmake74
-rwxr-xr-x[-rw-r--r--]indra/cmake/Copy3rdPartyLibs.cmake80
-rw-r--r--indra/cmake/CopyBackToSource.cmake16
-rwxr-xr-x[-rw-r--r--]indra/cmake/DBusGlib.cmake0
-rwxr-xr-x[-rw-r--r--]indra/cmake/DeploySharedLibs.cmake0
-rwxr-xr-x[-rw-r--r--]indra/cmake/DirectX.cmake6
-rwxr-xr-x[-rw-r--r--]indra/cmake/DragDrop.cmake3
-rwxr-xr-x[-rw-r--r--]indra/cmake/EXPAT.cmake0
-rwxr-xr-x[-rw-r--r--]indra/cmake/ExamplePlugin.cmake0
-rw-r--r--indra/cmake/Externals.cmake34
-rw-r--r--indra/cmake/FMOD.cmake39
-rw-r--r--indra/cmake/FMODEX.cmake46
-rwxr-xr-x[-rw-r--r--]indra/cmake/FindAPR.cmake0
-rwxr-xr-x[-rw-r--r--]indra/cmake/FindAutobuild.cmake0
-rwxr-xr-x[-rw-r--r--]indra/cmake/FindBerkeleyDB.cmake0
-rwxr-xr-x[-rw-r--r--]indra/cmake/FindCARes.cmake0
-rw-r--r--indra/cmake/FindELFIO.cmake48
-rw-r--r--indra/cmake/FindFMOD.cmake44
-rw-r--r--indra/cmake/FindFMODEX.cmake65
-rwxr-xr-x[-rw-r--r--]indra/cmake/FindGLH.cmake0
-rwxr-xr-x[-rw-r--r--]indra/cmake/FindGoogleBreakpad.cmake0
-rwxr-xr-x[-rw-r--r--]indra/cmake/FindGooglePerfTools.cmake0
-rwxr-xr-xindra/cmake/FindHUNSPELL.cmake38
-rwxr-xr-x[-rw-r--r--]indra/cmake/FindJsonCpp.cmake0
-rw-r--r--indra/cmake/FindLLQtWebkit.cmake62
-rw-r--r--indra/cmake/FindMT.cmake15
-rw-r--r--indra/cmake/FindMono.cmake68
-rw-r--r--indra/cmake/FindMySQL.cmake48
-rwxr-xr-x[-rw-r--r--]indra/cmake/FindNDOF.cmake0
-rwxr-xr-x[-rw-r--r--]indra/cmake/FindOpenJPEG.cmake0
-rwxr-xr-x[-rw-r--r--]indra/cmake/FindSCP.cmake0
-rw-r--r--indra/cmake/FindSVN.cmake34
-rwxr-xr-x[-rw-r--r--]indra/cmake/FindXmlRpcEpi.cmake0
-rwxr-xr-x[-rw-r--r--]indra/cmake/FindZLIB.cmake0
-rwxr-xr-x[-rw-r--r--]indra/cmake/FreeType.cmake8
-rw-r--r--indra/cmake/GLEXT.cmake8
-rwxr-xr-x[-rw-r--r--]indra/cmake/GLH.cmake0
-rwxr-xr-x[-rw-r--r--]indra/cmake/GLOD.cmake2
-rwxr-xr-x[-rw-r--r--]indra/cmake/GStreamer010Plugin.cmake0
-rwxr-xr-x[-rw-r--r--]indra/cmake/GetPrerequisites_2_8.cmake0
-rwxr-xr-x[-rw-r--r--]indra/cmake/Glui.cmake0
-rwxr-xr-x[-rw-r--r--]indra/cmake/Glut.cmake0
-rwxr-xr-x[-rw-r--r--]indra/cmake/GoogleBreakpad.cmake3
-rwxr-xr-x[-rw-r--r--]indra/cmake/GoogleMock.cmake0
-rwxr-xr-x[-rw-r--r--]indra/cmake/GooglePerfTools.cmake40
-rwxr-xr-xindra/cmake/Havok.cmake137
-rwxr-xr-xindra/cmake/Hunspell.cmake22
-rwxr-xr-x[-rw-r--r--]indra/cmake/JPEG.cmake0
-rwxr-xr-x[-rw-r--r--]indra/cmake/JsonCpp.cmake0
-rw-r--r--indra/cmake/LLAddBuildTest.cmake12
-rw-r--r--indra/cmake/LLAppearance.cmake17
-rw-r--r--indra/cmake/LLAppearanceUtility.cmake12
-rwxr-xr-x[-rw-r--r--]indra/cmake/LLAudio.cmake0
-rwxr-xr-x[-rw-r--r--]indra/cmake/LLCharacter.cmake0
-rwxr-xr-x[-rw-r--r--]indra/cmake/LLCommon.cmake6
-rw-r--r--indra/cmake/LLConvexDecomposition.cmake12
-rwxr-xr-xindra/cmake/LLCoreHttp.cmake16
-rwxr-xr-x[-rw-r--r--]indra/cmake/LLCrashLogger.cmake0
-rw-r--r--indra/cmake/LLDatabase.cmake10
-rwxr-xr-x[-rw-r--r--]indra/cmake/LLImage.cmake0
-rwxr-xr-x[-rw-r--r--]indra/cmake/LLImageJ2COJ.cmake0
-rwxr-xr-x[-rw-r--r--]indra/cmake/LLInventory.cmake0
-rwxr-xr-x[-rw-r--r--]indra/cmake/LLKDU.cmake0
-rwxr-xr-x[-rw-r--r--]indra/cmake/LLLogin.cmake0
-rwxr-xr-x[-rw-r--r--]indra/cmake/LLMath.cmake0
-rwxr-xr-x[-rw-r--r--]indra/cmake/LLMessage.cmake0
-rwxr-xr-xindra/cmake/LLPhysicsExtensions.cmake35
-rwxr-xr-x[-rw-r--r--]indra/cmake/LLPlugin.cmake0
-rwxr-xr-x[-rw-r--r--]indra/cmake/LLPrimitive.cmake7
-rwxr-xr-x[-rw-r--r--]indra/cmake/LLRender.cmake22
-rw-r--r--indra/cmake/LLScene.cmake7
-rwxr-xr-x[-rw-r--r--]indra/cmake/LLSharedLibs.cmake0
-rwxr-xr-x[-rw-r--r--]indra/cmake/LLTestCommand.cmake3
-rwxr-xr-x[-rw-r--r--]indra/cmake/LLUI.cmake0
-rwxr-xr-x[-rw-r--r--]indra/cmake/LLVFS.cmake0
-rwxr-xr-x[-rw-r--r--]indra/cmake/LLWindow.cmake17
-rwxr-xr-x[-rw-r--r--]indra/cmake/LLXML.cmake4
-rw-r--r--indra/cmake/LLXUIXML.cmake7
-rwxr-xr-x[-rw-r--r--]indra/cmake/LScript.cmake0
-rwxr-xr-x[-rw-r--r--]indra/cmake/Linking.cmake8
-rwxr-xr-x[-rw-r--r--]indra/cmake/MediaPluginBase.cmake0
-rw-r--r--indra/cmake/MonoDeps.cmake48
-rw-r--r--indra/cmake/MonoEmbed.cmake57
-rw-r--r--indra/cmake/MySQL.cmake26
-rwxr-xr-x[-rw-r--r--]indra/cmake/NDOF.cmake0
-rwxr-xr-xindra/cmake/NVAPI.cmake16
-rwxr-xr-x[-rw-r--r--]indra/cmake/OPENAL.cmake0
-rwxr-xr-x[-rw-r--r--]indra/cmake/OpenGL.cmake14
-rwxr-xr-x[-rw-r--r--]indra/cmake/OpenJPEG.cmake0
-rwxr-xr-x[-rw-r--r--]indra/cmake/OpenSSL.cmake0
-rwxr-xr-x[-rw-r--r--]indra/cmake/PNG.cmake0
-rwxr-xr-x[-rw-r--r--]indra/cmake/PluginAPI.cmake0
-rwxr-xr-x[-rw-r--r--]indra/cmake/Prebuilt.cmake5
-rwxr-xr-x[-rw-r--r--]indra/cmake/PulseAudio.cmake0
-rwxr-xr-x[-rw-r--r--]indra/cmake/Python.cmake2
-rwxr-xr-x[-rw-r--r--]indra/cmake/QuickTimePlugin.cmake0
-rwxr-xr-x[-rw-r--r--]indra/cmake/TemplateCheck.cmake0
-rwxr-xr-x[-rw-r--r--]indra/cmake/Tut.cmake0
-rwxr-xr-x[-rw-r--r--]indra/cmake/UI.cmake2
-rwxr-xr-x[-rw-r--r--]indra/cmake/UnixInstall.cmake0
-rwxr-xr-x[-rw-r--r--]indra/cmake/Variables.cmake93
-rwxr-xr-x[-rw-r--r--]indra/cmake/ViewerMiscLibs.cmake8
-rwxr-xr-x[-rw-r--r--]indra/cmake/VisualLeakDetector.cmake3
-rwxr-xr-x[-rw-r--r--]indra/cmake/WebKitLibPlugin.cmake0
-rwxr-xr-x[-rw-r--r--]indra/cmake/XmlRpcEpi.cmake0
-rwxr-xr-x[-rw-r--r--]indra/cmake/ZLIB.cmake0
-rwxr-xr-x[-rw-r--r--]indra/cmake/cmake_dummy.cpp0
-rwxr-xr-x[-rw-r--r--]indra/cmake/run_build_test.py30
-rwxr-xr-x[-rw-r--r--]indra/copy_win_scripts/CMakeLists.txt0
-rwxr-xr-x[-rw-r--r--]indra/copy_win_scripts/start-client.py0
-rwxr-xr-x[-rw-r--r--]indra/edit-me-to-trigger-new-build.txt6
-rwxr-xr-x[-rw-r--r--]indra/fix-incredibuild.py0
-rwxr-xr-x[-rw-r--r--]indra/integration_tests/CMakeLists.txt0
-rwxr-xr-x[-rw-r--r--]indra/integration_tests/llimage_libtest/CMakeLists.txt3
-rwxr-xr-x[-rw-r--r--]indra/integration_tests/llimage_libtest/llimage_libtest.cpp70
-rwxr-xr-x[-rw-r--r--]indra/integration_tests/llimage_libtest/llimage_libtest.h0
-rwxr-xr-x[-rw-r--r--]indra/integration_tests/llui_libtest/CMakeLists.txt12
-rwxr-xr-x[-rw-r--r--]indra/integration_tests/llui_libtest/llui_libtest.cpp29
-rwxr-xr-x[-rw-r--r--]indra/integration_tests/llui_libtest/llui_libtest.h0
-rwxr-xr-x[-rw-r--r--]indra/integration_tests/llui_libtest/llwidgetreg.cpp0
-rwxr-xr-x[-rw-r--r--]indra/integration_tests/llui_libtest/llwidgetreg.h0
-rwxr-xr-x[-rw-r--r--]indra/lib/python/indra/__init__.py0
-rwxr-xr-x[-rw-r--r--]indra/lib/python/indra/base/__init__.py0
-rwxr-xr-x[-rw-r--r--]indra/lib/python/indra/base/cllsd_test.py0
-rwxr-xr-x[-rw-r--r--]indra/lib/python/indra/base/config.py0
-rwxr-xr-x[-rw-r--r--]indra/lib/python/indra/base/llsd.py0
-rwxr-xr-x[-rw-r--r--]indra/lib/python/indra/base/lluuid.py0
-rwxr-xr-x[-rw-r--r--]indra/lib/python/indra/base/metrics.py0
-rwxr-xr-x[-rw-r--r--]indra/lib/python/indra/ipc/__init__.py0
-rwxr-xr-x[-rw-r--r--]indra/lib/python/indra/ipc/compatibility.py0
-rwxr-xr-x[-rw-r--r--]indra/lib/python/indra/ipc/httputil.py0
-rwxr-xr-x[-rw-r--r--]indra/lib/python/indra/ipc/llmessage.py0
-rwxr-xr-x[-rw-r--r--]indra/lib/python/indra/ipc/llsdhttp.py0
-rwxr-xr-x[-rw-r--r--]indra/lib/python/indra/ipc/mysql_pool.py0
-rwxr-xr-x[-rw-r--r--]indra/lib/python/indra/ipc/russ.py0
-rwxr-xr-x[-rw-r--r--]indra/lib/python/indra/ipc/servicebuilder.py0
-rwxr-xr-x[-rw-r--r--]indra/lib/python/indra/ipc/siesta.py0
-rwxr-xr-x[-rw-r--r--]indra/lib/python/indra/ipc/siesta_test.py0
-rwxr-xr-x[-rw-r--r--]indra/lib/python/indra/ipc/tokenstream.py0
-rwxr-xr-x[-rw-r--r--]indra/lib/python/indra/ipc/webdav.py0
-rwxr-xr-x[-rw-r--r--]indra/lib/python/indra/ipc/xml_rpc.py0
-rwxr-xr-x[-rw-r--r--]indra/lib/python/indra/util/__init__.py0
-rwxr-xr-x[-rw-r--r--]indra/lib/python/indra/util/fastest_elementtree.py0
-rwxr-xr-x[-rw-r--r--]indra/lib/python/indra/util/helpformatter.py0
-rwxr-xr-x[-rw-r--r--]indra/lib/python/indra/util/iterators.py0
-rwxr-xr-x[-rw-r--r--]indra/lib/python/indra/util/llmanifest.py225
-rwxr-xr-x[-rw-r--r--]indra/lib/python/indra/util/llsubprocess.py0
-rw-r--r--indra/lib/python/indra/util/llversion.py107
-rwxr-xr-x[-rw-r--r--]indra/lib/python/indra/util/named_query.py0
-rwxr-xr-x[-rw-r--r--]indra/lib/python/indra/util/shutil2.py0
-rwxr-xr-x[-rw-r--r--]indra/lib/python/indra/util/term.py0
-rwxr-xr-x[-rw-r--r--]indra/lib/python/indra/util/test_win32_manifest.py0
-rwxr-xr-x[-rw-r--r--]indra/lib/python/uuid.py0
-rwxr-xr-x[-rw-r--r--]indra/linux_crash_logger/CMakeLists.txt11
-rwxr-xr-x[-rw-r--r--]indra/linux_crash_logger/linux_crash_logger.cpp0
-rwxr-xr-x[-rw-r--r--]indra/linux_crash_logger/llcrashloggerlinux.cpp0
-rwxr-xr-x[-rw-r--r--]indra/linux_crash_logger/llcrashloggerlinux.h0
-rw-r--r--indra/linux_updater/CMakeLists.txt12
-rw-r--r--indra/linux_updater/linux_updater.cpp157
-rw-r--r--indra/llappearance/CMakeLists.txt118
-rw-r--r--indra/llappearance/llavatarappearance.cpp1953
-rw-r--r--indra/llappearance/llavatarappearance.h448
-rw-r--r--indra/llappearance/llavatarappearancedefines.cpp268
-rw-r--r--indra/llappearance/llavatarappearancedefines.h231
-rw-r--r--indra/llappearance/llavatarjoint.cpp326
-rw-r--r--indra/llappearance/llavatarjoint.h140
-rw-r--r--indra/llappearance/llavatarjointmesh.cpp375
-rw-r--r--indra/llappearance/llavatarjointmesh.h145
-rw-r--r--indra/llappearance/lldriverparam.cpp619
-rw-r--r--indra/llappearance/lldriverparam.h144
-rw-r--r--indra/llappearance/lljointpickname.h49
-rw-r--r--indra/llappearance/lllocaltextureobject.cpp213
-rw-r--r--indra/llappearance/lllocaltextureobject.h86
-rw-r--r--indra/llappearance/llpolymesh.cpp1048
-rw-r--r--indra/llappearance/llpolymesh.h369
-rw-r--r--indra/llappearance/llpolymorph.cpp802
-rw-r--r--indra/llappearance/llpolymorph.h197
-rw-r--r--indra/llappearance/llpolyskeletaldistortion.cpp293
-rw-r--r--indra/llappearance/llpolyskeletaldistortion.h131
-rw-r--r--indra/llappearance/lltexglobalcolor.cpp152
-rw-r--r--indra/llappearance/lltexglobalcolor.h83
-rw-r--r--indra/llappearance/lltexlayer.cpp2022
-rw-r--r--indra/llappearance/lltexlayer.h315
-rw-r--r--indra/llappearance/lltexlayerparams.cpp570
-rw-r--r--indra/llappearance/lltexlayerparams.h219
-rw-r--r--indra/llappearance/lltexturemanagerbridge.cpp32
-rw-r--r--indra/llappearance/lltexturemanagerbridge.h46
-rw-r--r--indra/llappearance/llviewervisualparam.cpp163
-rw-r--r--indra/llappearance/llviewervisualparam.h110
-rw-r--r--indra/llappearance/llwearable.cpp781
-rw-r--r--indra/llappearance/llwearable.h142
-rw-r--r--indra/llappearance/llwearabledata.cpp360
-rw-r--r--indra/llappearance/llwearabledata.h109
-rw-r--r--indra/llappearance/llwearabletype.cpp171
-rw-r--r--indra/llappearance/llwearabletype.h86
-rwxr-xr-x[-rw-r--r--]indra/llaudio/CMakeLists.txt32
-rwxr-xr-x[-rw-r--r--]indra/llaudio/llaudiodecodemgr.cpp22
-rwxr-xr-x[-rw-r--r--]indra/llaudio/llaudiodecodemgr.h0
-rwxr-xr-x[-rw-r--r--]indra/llaudio/llaudioengine.cpp28
-rwxr-xr-x[-rw-r--r--]indra/llaudio/llaudioengine.h34
-rw-r--r--indra/llaudio/llaudioengine_fmod.cpp781
-rw-r--r--indra/llaudio/llaudioengine_fmod.h124
-rw-r--r--indra/llaudio/llaudioengine_fmodex.cpp762
-rw-r--r--indra/llaudio/llaudioengine_fmodex.h128
-rwxr-xr-x[-rw-r--r--]indra/llaudio/llaudioengine_openal.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llaudio/llaudioengine_openal.h0
-rwxr-xr-x[-rw-r--r--]indra/llaudio/lllistener.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llaudio/lllistener.h0
-rwxr-xr-x[-rw-r--r--]indra/llaudio/lllistener_ds3d.h0
-rw-r--r--indra/llaudio/lllistener_fmod.cpp125
-rw-r--r--indra/llaudio/lllistener_fmod.h58
-rw-r--r--indra/llaudio/lllistener_fmodex.cpp135
-rw-r--r--indra/llaudio/lllistener_fmodex.h65
-rwxr-xr-x[-rw-r--r--]indra/llaudio/lllistener_openal.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llaudio/lllistener_openal.h0
-rwxr-xr-x[-rw-r--r--]indra/llaudio/llstreamingaudio.h2
-rw-r--r--indra/llaudio/llstreamingaudio_fmod.cpp356
-rw-r--r--indra/llaudio/llstreamingaudio_fmod.h62
-rw-r--r--indra/llaudio/llstreamingaudio_fmodex.cpp392
-rw-r--r--indra/llaudio/llstreamingaudio_fmodex.h73
-rwxr-xr-x[-rw-r--r--]indra/llaudio/llvorbisencode.cpp2
-rwxr-xr-x[-rw-r--r--]indra/llaudio/llvorbisencode.h0
-rwxr-xr-x[-rw-r--r--]indra/llaudio/llwindgen.h28
-rwxr-xr-x[-rw-r--r--]indra/llcharacter/CMakeLists.txt13
-rwxr-xr-x[-rw-r--r--]indra/llcharacter/llanimationstates.cpp4
-rwxr-xr-x[-rw-r--r--]indra/llcharacter/llanimationstates.h2
-rwxr-xr-x[-rw-r--r--]indra/llcharacter/llbvhconsts.h2
-rwxr-xr-x[-rw-r--r--]indra/llcharacter/llbvhloader.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llcharacter/llbvhloader.h0
-rwxr-xr-x[-rw-r--r--]indra/llcharacter/llcharacter.cpp8
-rwxr-xr-x[-rw-r--r--]indra/llcharacter/llcharacter.h9
-rwxr-xr-x[-rw-r--r--]indra/llcharacter/lleditingmotion.cpp5
-rwxr-xr-x[-rw-r--r--]indra/llcharacter/lleditingmotion.h0
-rwxr-xr-x[-rw-r--r--]indra/llcharacter/llgesture.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llcharacter/llgesture.h0
-rwxr-xr-x[-rw-r--r--]indra/llcharacter/llhandmotion.cpp60
-rwxr-xr-x[-rw-r--r--]indra/llcharacter/llhandmotion.h0
-rwxr-xr-x[-rw-r--r--]indra/llcharacter/llheadrotmotion.cpp1
-rwxr-xr-x[-rw-r--r--]indra/llcharacter/llheadrotmotion.h0
-rwxr-xr-x[-rw-r--r--]indra/llcharacter/lljoint.cpp30
-rwxr-xr-x[-rw-r--r--]indra/llcharacter/lljoint.h8
-rwxr-xr-x[-rw-r--r--]indra/llcharacter/lljointsolverrp3.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llcharacter/lljointsolverrp3.h0
-rwxr-xr-x[-rw-r--r--]indra/llcharacter/lljointstate.h0
-rwxr-xr-x[-rw-r--r--]indra/llcharacter/llkeyframefallmotion.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llcharacter/llkeyframefallmotion.h0
-rwxr-xr-x[-rw-r--r--]indra/llcharacter/llkeyframemotion.cpp4
-rwxr-xr-x[-rw-r--r--]indra/llcharacter/llkeyframemotion.h0
-rwxr-xr-x[-rw-r--r--]indra/llcharacter/llkeyframemotionparam.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llcharacter/llkeyframemotionparam.h0
-rwxr-xr-x[-rw-r--r--]indra/llcharacter/llkeyframestandmotion.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llcharacter/llkeyframestandmotion.h0
-rwxr-xr-x[-rw-r--r--]indra/llcharacter/llkeyframewalkmotion.cpp1
-rwxr-xr-x[-rw-r--r--]indra/llcharacter/llkeyframewalkmotion.h0
-rwxr-xr-x[-rw-r--r--]indra/llcharacter/llmotion.cpp1
-rwxr-xr-x[-rw-r--r--]indra/llcharacter/llmotion.h0
-rwxr-xr-x[-rw-r--r--]indra/llcharacter/llmotioncontroller.cpp23
-rwxr-xr-x[-rw-r--r--]indra/llcharacter/llmotioncontroller.h6
-rwxr-xr-x[-rw-r--r--]indra/llcharacter/llmultigesture.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llcharacter/llmultigesture.h0
-rwxr-xr-x[-rw-r--r--]indra/llcharacter/llpose.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llcharacter/llpose.h0
-rwxr-xr-x[-rw-r--r--]indra/llcharacter/llstatemachine.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llcharacter/llstatemachine.h0
-rwxr-xr-x[-rw-r--r--]indra/llcharacter/lltargetingmotion.cpp1
-rwxr-xr-x[-rw-r--r--]indra/llcharacter/lltargetingmotion.h0
-rwxr-xr-x[-rw-r--r--]indra/llcharacter/llvisualparam.cpp33
-rwxr-xr-x[-rw-r--r--]indra/llcharacter/llvisualparam.h17
-rwxr-xr-x[-rw-r--r--]indra/llcharacter/tests/lljoint_test.cpp6
-rwxr-xr-x[-rw-r--r--]indra/llcommon/CMakeLists.txt35
-rwxr-xr-x[-rw-r--r--]indra/llcommon/bitpack.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/bitpack.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/ctype_workaround.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/doublelinkedlist.h0
-rwxr-xr-xindra/llcommon/fix_macros.h25
-rwxr-xr-x[-rw-r--r--]indra/llcommon/imageids.cpp3
-rwxr-xr-x[-rw-r--r--]indra/llcommon/imageids.h1
-rwxr-xr-x[-rw-r--r--]indra/llcommon/indra_constants.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/indra_constants.h1
-rwxr-xr-x[-rw-r--r--]indra/llcommon/is_approx_equal_fraction.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/linden_common.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/linked_lists.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/ll_template_cast.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llaccountingcost.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llagentconstants.h0
-rw-r--r--indra/llcommon/llalignedarray.h139
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llallocator.cpp35
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llallocator.h6
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llallocator_heap_profile.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llallocator_heap_profile.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llapp.cpp66
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llapp.h2
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llapr.cpp4
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llapr.h12
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llassettype.cpp1
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llassettype.h3
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llassoclist.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llavatarconstants.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llavatarname.cpp131
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llavatarname.h62
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llbase32.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llbase32.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llbase64.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llbase64.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llboost.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llchat.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llclickaction.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llcommon.cpp1
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llcommon.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llcommonutils.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llcommonutils.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llcoros.cpp19
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llcoros.h12
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llcrc.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llcrc.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llcriticaldamp.cpp1
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llcriticaldamp.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llcursortypes.cpp6
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llcursortypes.h6
-rwxr-xr-x[-rw-r--r--]indra/llcommon/lldarray.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/lldarrayptr.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/lldate.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/lldate.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/lldefs.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/lldeleteutils.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/lldependencies.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/lldependencies.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/lldepthstack.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/lldictionary.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/lldictionary.h2
-rwxr-xr-x[-rw-r--r--]indra/llcommon/lldlinked.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/lldoubledispatch.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/lldqueueptr.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llendianswizzle.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llenum.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llerror.cpp42
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llerror.h20
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llerrorcontrol.h82
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llerrorlegacy.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llerrorthread.cpp7
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llerrorthread.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llevent.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llevent.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/lleventapi.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/lleventapi.h1
-rwxr-xr-x[-rw-r--r--]indra/llcommon/lleventcoro.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/lleventcoro.h16
-rwxr-xr-x[-rw-r--r--]indra/llcommon/lleventdispatcher.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/lleventdispatcher.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/lleventemitter.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/lleventfilter.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/lleventfilter.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llevents.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llevents.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/lleventtimer.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/lleventtimer.h1
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llextendedstatus.h0
-rwxr-xr-xindra/llcommon/llfasttimer.cpp658
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llfasttimer.h365
-rw-r--r--indra/llcommon/llfasttimer_class.cpp921
-rw-r--r--indra/llcommon/llfasttimer_class.h276
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llfile.cpp895
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llfile.h419
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llfindlocale.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llfindlocale.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llfixedbuffer.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llfixedbuffer.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llfoldertype.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llformat.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llformat.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llframetimer.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llframetimer.h0
-rwxr-xr-xindra/llcommon/llhandle.h216
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llhash.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llheartbeat.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llheartbeat.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llhttpstatuscodes.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llindexedqueue.h0
-rwxr-xr-xindra/llcommon/llinitparam.cpp463
-rwxr-xr-xindra/llcommon/llinitparam.h2717
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llinstancetracker.cpp15
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llinstancetracker.h62
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llkeythrottle.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llkeyusetracker.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/lllazy.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/lllazy.h0
-rwxr-xr-xindra/llcommon/llleap.cpp459
-rwxr-xr-xindra/llcommon/llleap.h81
-rwxr-xr-xindra/llcommon/llleaplistener.cpp287
-rwxr-xr-xindra/llcommon/llleaplistener.h73
-rwxr-xr-x[-rw-r--r--]indra/llcommon/lllinkedqueue.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/lllistenerwrapper.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llliveappconfig.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llliveappconfig.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/lllivefile.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/lllivefile.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/lllocalidhashmap.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/lllog.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/lllog.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/lllslconstants.h29
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llmap.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llmd5.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llmd5.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llmemory.cpp43
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llmemory.h185
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llmemorystream.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llmemorystream.h0
-rw-r--r--indra/llcommon/llmemtype.cpp232
-rw-r--r--indra/llcommon/llmemtype.h242
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llmetricperformancetester.cpp2
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llmetricperformancetester.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llmetrics.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llmetrics.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llmortician.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llmortician.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llnametable.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/lloptioninterface.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/lloptioninterface.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llpointer.h6
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llpreprocessor.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llpriqueuemap.h0
-rwxr-xr-xindra/llcommon/llprocess.cpp1351
-rwxr-xr-xindra/llcommon/llprocess.h553
-rw-r--r--indra/llcommon/llprocesslauncher.cpp357
-rw-r--r--indra/llcommon/llprocesslauncher.h90
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llprocessor.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llprocessor.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llptrskiplist.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llptrskipmap.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llptrto.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llptrto.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llqueuedthread.cpp4
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llqueuedthread.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llrand.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llrand.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llrefcount.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llrefcount.h19
-rwxr-xr-xindra/llcommon/llregistry.h360
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llrun.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llrun.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llsafehandle.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llsd.cpp6
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llsd.h6
-rwxr-xr-xindra/llcommon/llsdparam.cpp341
-rwxr-xr-xindra/llcommon/llsdparam.h126
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llsdserialize.cpp88
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llsdserialize.h18
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llsdserialize_xml.cpp14
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llsdserialize_xml.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llsdutil.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llsdutil.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llsecondlifeurls.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llsecondlifeurls.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llsimplehash.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llsingleton.cpp1
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llsingleton.h143
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llskiplist.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llskipmap.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llsmoothstep.h0
-rwxr-xr-xindra/llcommon/llsortedvector.h152
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llstack.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llstacktrace.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llstacktrace.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llstat.cpp1044
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llstat.h289
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llstatenums.h77
-rw-r--r--indra/llcommon/llstaticstringtable.h82
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llstl.h51
-rwxr-xr-xindra/llcommon/llstreamqueue.cpp24
-rwxr-xr-xindra/llcommon/llstreamqueue.h240
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llstreamtools.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llstreamtools.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llstrider.h10
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llstring.cpp36
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llstring.h597
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llstringtable.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llstringtable.h8
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llsys.cpp268
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llsys.h3
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llthread.cpp37
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llthread.h75
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llthreadsafequeue.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llthreadsafequeue.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/lltimer.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/lltimer.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/lltreeiterators.h0
-rwxr-xr-xindra/llcommon/lltypeinfolookup.h117
-rwxr-xr-x[-rw-r--r--]indra/llcommon/lluri.cpp65
-rwxr-xr-x[-rw-r--r--]indra/llcommon/lluri.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/lluuid.cpp208
-rwxr-xr-x[-rw-r--r--]indra/llcommon/lluuid.h176
-rwxr-xr-x[-rw-r--r--]indra/llcommon/lluuidhashmap.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llversionserver.h2
-rw-r--r--indra/llcommon/llversionviewer.h41
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llworkerthread.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/llworkerthread.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/metaclass.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/metaclass.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/metaclasst.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/metaproperty.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/metaproperty.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/metapropertyt.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/reflective.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/reflective.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/reflectivet.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/roles_constants.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/stdenums.h3
-rwxr-xr-x[-rw-r--r--]indra/llcommon/stdtypes.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/string_table.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/stringize.h0
-rwxr-xr-xindra/llcommon/tests/StringVec.h37
-rwxr-xr-x[-rw-r--r--]indra/llcommon/tests/bitpack_test.cpp15
-rwxr-xr-x[-rw-r--r--]indra/llcommon/tests/commonmisc_test.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/tests/listener.h21
-rwxr-xr-x[-rw-r--r--]indra/llcommon/tests/llallocator_heap_profile_test.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/tests/llallocator_test.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/tests/llbase64_test.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/tests/lldate_test.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/tests/lldependencies_test.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/tests/llerror_test.cpp226
-rwxr-xr-x[-rw-r--r--]indra/llcommon/tests/lleventcoro_test.cpp49
-rwxr-xr-x[-rw-r--r--]indra/llcommon/tests/lleventdispatcher_test.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/tests/lleventfilter_test.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/tests/llframetimer_test.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/tests/llinstancetracker_test.cpp68
-rwxr-xr-x[-rw-r--r--]indra/llcommon/tests/lllazy_test.cpp0
-rwxr-xr-xindra/llcommon/tests/llleap_test.cpp691
-rwxr-xr-x[-rw-r--r--]indra/llcommon/tests/llmemtype_test.cpp0
-rwxr-xr-xindra/llcommon/tests/llprocess_test.cpp1259
-rwxr-xr-x[-rw-r--r--]indra/llcommon/tests/llprocessor_test.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/tests/llrand_test.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/tests/llsdserialize_test.cpp279
-rwxr-xr-x[-rw-r--r--]indra/llcommon/tests/llsingleton_test.cpp0
-rwxr-xr-xindra/llcommon/tests/llstreamqueue_test.cpp197
-rwxr-xr-x[-rw-r--r--]indra/llcommon/tests/llstring_test.cpp118
-rwxr-xr-x[-rw-r--r--]indra/llcommon/tests/lltreeiterators_test.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/tests/lluri_test.cpp94
-rwxr-xr-x[-rw-r--r--]indra/llcommon/tests/reflection_test.cpp2
-rw-r--r--indra/llcommon/tests/setpython.py19
-rwxr-xr-x[-rw-r--r--]indra/llcommon/tests/stringize_test.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/tests/wrapllerrs.h129
-rwxr-xr-x[-rw-r--r--]indra/llcommon/timer.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/timing.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/timing.h0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/u64.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llcommon/u64.h0
-rwxr-xr-xindra/llcorehttp/CMakeLists.txt186
-rwxr-xr-xindra/llcorehttp/_httpinternal.h151
-rwxr-xr-xindra/llcorehttp/_httplibcurl.cpp373
-rwxr-xr-xindra/llcorehttp/_httplibcurl.h129
-rwxr-xr-xindra/llcorehttp/_httpopcancel.cpp73
-rwxr-xr-xindra/llcorehttp/_httpopcancel.h78
-rwxr-xr-xindra/llcorehttp/_httpoperation.cpp248
-rwxr-xr-xindra/llcorehttp/_httpoperation.h262
-rwxr-xr-xindra/llcorehttp/_httpoprequest.cpp886
-rwxr-xr-xindra/llcorehttp/_httpoprequest.h218
-rwxr-xr-xindra/llcorehttp/_httpopsetget.cpp97
-rwxr-xr-xindra/llcorehttp/_httpopsetget.h83
-rwxr-xr-xindra/llcorehttp/_httpopsetpriority.cpp63
-rwxr-xr-xindra/llcorehttp/_httpopsetpriority.h73
-rwxr-xr-xindra/llcorehttp/_httppolicy.cpp367
-rwxr-xr-xindra/llcorehttp/_httppolicy.h161
-rwxr-xr-xindra/llcorehttp/_httppolicyclass.cpp125
-rwxr-xr-xindra/llcorehttp/_httppolicyclass.h59
-rwxr-xr-xindra/llcorehttp/_httppolicyglobal.cpp175
-rwxr-xr-xindra/llcorehttp/_httppolicyglobal.h66
-rwxr-xr-xindra/llcorehttp/_httpreadyqueue.h124
-rwxr-xr-xindra/llcorehttp/_httpreplyqueue.cpp107
-rwxr-xr-xindra/llcorehttp/_httpreplyqueue.h108
-rwxr-xr-xindra/llcorehttp/_httprequestqueue.cpp161
-rwxr-xr-xindra/llcorehttp/_httprequestqueue.h141
-rwxr-xr-xindra/llcorehttp/_httpretryqueue.h94
-rwxr-xr-xindra/llcorehttp/_httpservice.cpp348
-rwxr-xr-xindra/llcorehttp/_httpservice.h224
-rwxr-xr-xindra/llcorehttp/_mutex.h55
-rwxr-xr-xindra/llcorehttp/_refcounted.cpp45
-rwxr-xr-xindra/llcorehttp/_refcounted.h126
-rwxr-xr-xindra/llcorehttp/_thread.h123
-rwxr-xr-xindra/llcorehttp/bufferarray.cpp352
-rwxr-xr-xindra/llcorehttp/bufferarray.h137
-rwxr-xr-xindra/llcorehttp/bufferstream.cpp285
-rwxr-xr-xindra/llcorehttp/bufferstream.h153
-rwxr-xr-xindra/llcorehttp/examples/http_texture_load.cpp947
-rwxr-xr-xindra/llcorehttp/httpcommon.cpp211
-rwxr-xr-xindra/llcorehttp/httpcommon.h317
-rwxr-xr-xindra/llcorehttp/httphandler.h88
-rwxr-xr-xindra/llcorehttp/httpheaders.cpp44
-rwxr-xr-xindra/llcorehttp/httpheaders.h87
-rwxr-xr-xindra/llcorehttp/httpoptions.cpp73
-rwxr-xr-xindra/llcorehttp/httpoptions.h106
-rwxr-xr-xindra/llcorehttp/httprequest.cpp504
-rwxr-xr-xindra/llcorehttp/httprequest.h535
-rwxr-xr-xindra/llcorehttp/httpresponse.cpp91
-rwxr-xr-xindra/llcorehttp/httpresponse.h166
-rwxr-xr-xindra/llcorehttp/tests/llcorehttp_test.cpp175
-rwxr-xr-xindra/llcorehttp/tests/llcorehttp_test.h64
-rwxr-xr-xindra/llcorehttp/tests/test_allocator.cpp184
-rwxr-xr-xindra/llcorehttp/tests/test_allocator.h47
-rwxr-xr-xindra/llcorehttp/tests/test_bufferarray.hpp432
-rwxr-xr-xindra/llcorehttp/tests/test_bufferstream.hpp304
-rwxr-xr-xindra/llcorehttp/tests/test_httpheaders.hpp108
-rwxr-xr-xindra/llcorehttp/tests/test_httpoperation.hpp125
-rwxr-xr-xindra/llcorehttp/tests/test_httprequest.hpp2873
-rwxr-xr-xindra/llcorehttp/tests/test_httprequestqueue.hpp186
-rwxr-xr-xindra/llcorehttp/tests/test_httpstatus.hpp265
-rwxr-xr-xindra/llcorehttp/tests/test_llcorehttp_peer.py274
-rwxr-xr-xindra/llcorehttp/tests/test_refcounted.hpp156
-rwxr-xr-xindra/llcorehttp/tests/testrunner.py265
-rwxr-xr-x[-rw-r--r--]indra/llcrashlogger/CMakeLists.txt4
-rwxr-xr-x[-rw-r--r--]indra/llcrashlogger/llcrashlogger.cpp4
-rwxr-xr-x[-rw-r--r--]indra/llcrashlogger/llcrashlogger.h0
-rwxr-xr-x[-rw-r--r--]indra/llimage/CMakeLists.txt13
-rwxr-xr-x[-rw-r--r--]indra/llimage/llimage.cpp158
-rwxr-xr-x[-rw-r--r--]indra/llimage/llimage.h36
-rwxr-xr-x[-rw-r--r--]indra/llimage/llimagebmp.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llimage/llimagebmp.h0
-rwxr-xr-x[-rw-r--r--]indra/llimage/llimagedimensionsinfo.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llimage/llimagedimensionsinfo.h0
-rwxr-xr-x[-rw-r--r--]indra/llimage/llimagedxt.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llimage/llimagedxt.h0
-rwxr-xr-x[-rw-r--r--]indra/llimage/llimagej2c.cpp89
-rwxr-xr-x[-rw-r--r--]indra/llimage/llimagej2c.h10
-rwxr-xr-x[-rw-r--r--]indra/llimage/llimagejpeg.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llimage/llimagejpeg.h0
-rwxr-xr-x[-rw-r--r--]indra/llimage/llimagepng.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llimage/llimagepng.h0
-rwxr-xr-x[-rw-r--r--]indra/llimage/llimagetga.cpp12
-rwxr-xr-x[-rw-r--r--]indra/llimage/llimagetga.h0
-rwxr-xr-x[-rw-r--r--]indra/llimage/llimageworker.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llimage/llimageworker.h0
-rwxr-xr-x[-rw-r--r--]indra/llimage/llmapimagetype.h0
-rwxr-xr-x[-rw-r--r--]indra/llimage/llpngwrapper.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llimage/llpngwrapper.h0
-rwxr-xr-x[-rw-r--r--]indra/llimage/tests/llimageworker_test.cpp3
-rwxr-xr-x[-rw-r--r--]indra/llimagej2coj/CMakeLists.txt0
-rwxr-xr-x[-rw-r--r--]indra/llimagej2coj/llimagej2coj.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llimagej2coj/llimagej2coj.h0
-rwxr-xr-x[-rw-r--r--]indra/llinventory/CMakeLists.txt0
-rwxr-xr-x[-rw-r--r--]indra/llinventory/llcategory.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llinventory/llcategory.h0
-rwxr-xr-x[-rw-r--r--]indra/llinventory/lleconomy.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llinventory/lleconomy.h0
-rwxr-xr-x[-rw-r--r--]indra/llinventory/llinventory.cpp56
-rwxr-xr-x[-rw-r--r--]indra/llinventory/llinventory.h10
-rwxr-xr-x[-rw-r--r--]indra/llinventory/llinventorydefines.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llinventory/llinventorydefines.h0
-rwxr-xr-x[-rw-r--r--]indra/llinventory/llinventorytype.cpp3
-rwxr-xr-x[-rw-r--r--]indra/llinventory/llinventorytype.h50
-rwxr-xr-x[-rw-r--r--]indra/llinventory/lllandmark.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llinventory/lllandmark.h0
-rwxr-xr-x[-rw-r--r--]indra/llinventory/llnotecard.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llinventory/llnotecard.h0
-rwxr-xr-x[-rw-r--r--]indra/llinventory/llparcel.cpp180
-rwxr-xr-x[-rw-r--r--]indra/llinventory/llparcel.h27
-rwxr-xr-x[-rw-r--r--]indra/llinventory/llparcelflags.h0
-rwxr-xr-x[-rw-r--r--]indra/llinventory/llpermissions.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llinventory/llpermissions.h0
-rwxr-xr-x[-rw-r--r--]indra/llinventory/llpermissionsflags.h0
-rwxr-xr-x[-rw-r--r--]indra/llinventory/llsaleinfo.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llinventory/llsaleinfo.h0
-rwxr-xr-x[-rw-r--r--]indra/llinventory/lltransactionflags.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llinventory/lltransactionflags.h0
-rwxr-xr-x[-rw-r--r--]indra/llinventory/lltransactiontypes.h0
-rwxr-xr-x[-rw-r--r--]indra/llinventory/lluserrelations.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llinventory/lluserrelations.h0
-rwxr-xr-x[-rw-r--r--]indra/llinventory/tests/inventorymisc_test.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llinventory/tests/llparcel_test.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llkdu/CMakeLists.txt5
-rwxr-xr-x[-rw-r--r--]indra/llkdu/llimagej2ckdu.cpp332
-rwxr-xr-x[-rw-r--r--]indra/llkdu/llimagej2ckdu.h2
-rwxr-xr-x[-rw-r--r--]indra/llkdu/llkdumem.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llkdu/llkdumem.h1
-rwxr-xr-x[-rw-r--r--]indra/llkdu/tests/llimagej2ckdu_test.cpp45
-rwxr-xr-x[-rw-r--r--]indra/llmath/CMakeLists.txt6
-rwxr-xr-x[-rw-r--r--]indra/llmath/camera.h0
-rwxr-xr-x[-rw-r--r--]indra/llmath/coordframe.h0
-rwxr-xr-x[-rw-r--r--]indra/llmath/llbbox.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmath/llbbox.h0
-rwxr-xr-x[-rw-r--r--]indra/llmath/llbboxlocal.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmath/llbboxlocal.h0
-rwxr-xr-x[-rw-r--r--]indra/llmath/llcalc.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmath/llcalc.h0
-rwxr-xr-x[-rw-r--r--]indra/llmath/llcalcparser.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmath/llcalcparser.h0
-rwxr-xr-x[-rw-r--r--]indra/llmath/llcamera.cpp86
-rwxr-xr-x[-rw-r--r--]indra/llmath/llcamera.h45
-rwxr-xr-x[-rw-r--r--]indra/llmath/llcoord.h0
-rwxr-xr-x[-rw-r--r--]indra/llmath/llcoordframe.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmath/llcoordframe.h0
-rwxr-xr-x[-rw-r--r--]indra/llmath/llinterp.h0
-rwxr-xr-x[-rw-r--r--]indra/llmath/llline.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmath/llline.h0
-rwxr-xr-x[-rw-r--r--]indra/llmath/llmath.h6
-rwxr-xr-x[-rw-r--r--]indra/llmath/llmatrix3a.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmath/llmatrix3a.h2
-rwxr-xr-x[-rw-r--r--]indra/llmath/llmatrix3a.inl0
-rwxr-xr-x[-rw-r--r--]indra/llmath/llmatrix4a.h13
-rwxr-xr-x[-rw-r--r--]indra/llmath/llmodularmath.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmath/llmodularmath.h0
-rwxr-xr-x[-rw-r--r--]indra/llmath/lloctree.h143
-rwxr-xr-x[-rw-r--r--]indra/llmath/llperlin.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmath/llperlin.h0
-rwxr-xr-x[-rw-r--r--]indra/llmath/llplane.h4
-rwxr-xr-x[-rw-r--r--]indra/llmath/llquantize.h0
-rwxr-xr-x[-rw-r--r--]indra/llmath/llquaternion.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmath/llquaternion.h0
-rwxr-xr-x[-rw-r--r--]indra/llmath/llquaternion2.h0
-rwxr-xr-x[-rw-r--r--]indra/llmath/llquaternion2.inl0
-rwxr-xr-x[-rw-r--r--]indra/llmath/llrect.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmath/llrect.h0
-rwxr-xr-x[-rw-r--r--]indra/llmath/llsdutil_math.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmath/llsdutil_math.h0
-rwxr-xr-x[-rw-r--r--]indra/llmath/llsimdmath.h31
-rwxr-xr-x[-rw-r--r--]indra/llmath/llsimdtypes.h0
-rwxr-xr-x[-rw-r--r--]indra/llmath/llsimdtypes.inl2
-rwxr-xr-x[-rw-r--r--]indra/llmath/llsphere.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmath/llsphere.h0
-rwxr-xr-x[-rw-r--r--]indra/llmath/lltreenode.h0
-rwxr-xr-x[-rw-r--r--]indra/llmath/llvector4a.cpp50
-rwxr-xr-x[-rw-r--r--]indra/llmath/llvector4a.h12
-rwxr-xr-x[-rw-r--r--]indra/llmath/llvector4a.inl34
-rwxr-xr-x[-rw-r--r--]indra/llmath/llvector4logical.h2
-rwxr-xr-x[-rw-r--r--]indra/llmath/llvolume.cpp2522
-rwxr-xr-x[-rw-r--r--]indra/llmath/llvolume.h116
-rwxr-xr-x[-rw-r--r--]indra/llmath/llvolumemgr.cpp3
-rwxr-xr-x[-rw-r--r--]indra/llmath/llvolumemgr.h0
-rwxr-xr-x[-rw-r--r--]indra/llmath/llvolumeoctree.cpp72
-rwxr-xr-x[-rw-r--r--]indra/llmath/llvolumeoctree.h43
-rwxr-xr-x[-rw-r--r--]indra/llmath/m3math.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmath/m3math.h0
-rwxr-xr-x[-rw-r--r--]indra/llmath/m4math.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmath/m4math.h0
-rwxr-xr-x[-rw-r--r--]indra/llmath/raytrace.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmath/raytrace.h0
-rwxr-xr-xindra/llmath/tests/alignment_test.cpp141
-rwxr-xr-x[-rw-r--r--]indra/llmath/tests/llbbox_test.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmath/tests/llbboxlocal_test.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmath/tests/llmodularmath_test.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmath/tests/llquaternion_test.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmath/tests/llrect_test.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmath/tests/m3math_test.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmath/tests/mathmisc_test.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmath/tests/v2math_test.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmath/tests/v3color_test.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmath/tests/v3dmath_test.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmath/tests/v3math_test.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmath/tests/v4color_test.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmath/tests/v4coloru_test.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmath/tests/v4math_test.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmath/tests/xform_test.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmath/v2math.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmath/v2math.h0
-rwxr-xr-x[-rw-r--r--]indra/llmath/v3color.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmath/v3color.h1
-rwxr-xr-x[-rw-r--r--]indra/llmath/v3dmath.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmath/v3dmath.h0
-rwxr-xr-x[-rw-r--r--]indra/llmath/v3math.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmath/v3math.h0
-rwxr-xr-x[-rw-r--r--]indra/llmath/v4color.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmath/v4color.h2
-rwxr-xr-x[-rw-r--r--]indra/llmath/v4coloru.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmath/v4coloru.h0
-rwxr-xr-x[-rw-r--r--]indra/llmath/v4math.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmath/v4math.h0
-rwxr-xr-x[-rw-r--r--]indra/llmath/xform.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmath/xform.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/CMakeLists.txt3
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llares.cpp29
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llares.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llareslistener.cpp9
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llareslistener.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llassetstorage.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llassetstorage.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llavatarnamecache.cpp330
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llavatarnamecache.h39
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llblowfishcipher.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llblowfishcipher.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llbuffer.cpp24
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llbuffer.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llbufferstream.cpp9
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llbufferstream.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llcachename.cpp14
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llcachename.h2
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llchainio.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llchainio.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llcipher.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llcircuit.cpp2
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llcircuit.h4
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llclassifiedflags.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llclassifiedflags.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llcurl.cpp410
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llcurl.h88
-rwxr-xr-x[-rw-r--r--]indra/llmessage/lldatapacker.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/lldatapacker.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/lldbstrings.h12
-rwxr-xr-x[-rw-r--r--]indra/llmessage/lldispatcher.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/lldispatcher.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/lleventflags.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llfiltersd2xmlrpc.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llfiltersd2xmlrpc.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llfollowcamparams.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llhost.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llhost.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llhttpassetstorage.cpp2
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llhttpassetstorage.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llhttpclient.cpp44
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llhttpclient.h19
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llhttpclientadapter.cpp3
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llhttpclientadapter.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llhttpclientinterface.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llhttpnode.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llhttpnode.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llhttpnodeadapter.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llhttpsender.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llhttpsender.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llinstantmessage.cpp17
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llinstantmessage.h57
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llinvite.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/lliobuffer.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/lliobuffer.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/lliohttpserver.cpp21
-rwxr-xr-x[-rw-r--r--]indra/llmessage/lliohttpserver.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/lliopipe.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/lliopipe.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/lliosocket.cpp25
-rwxr-xr-x[-rw-r--r--]indra/llmessage/lliosocket.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llioutil.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llioutil.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llloginflags.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llmail.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llmail.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llmessagebuilder.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llmessagebuilder.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llmessageconfig.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llmessageconfig.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llmessagereader.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llmessagereader.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llmessagesenderinterface.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llmessagetemplate.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llmessagetemplate.h3
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llmessagetemplateparser.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llmessagetemplateparser.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llmessagethrottle.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llmessagethrottle.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llmime.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llmime.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llmsgvariabletype.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llnamevalue.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llnamevalue.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llnullcipher.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llnullcipher.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llpacketack.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llpacketack.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llpacketbuffer.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llpacketbuffer.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llpacketring.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llpacketring.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llpartdata.cpp282
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llpartdata.h61
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llproxy.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llproxy.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llpumpio.cpp25
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llpumpio.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llqueryflags.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llregionflags.h65
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llregionhandle.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llregionpresenceverifier.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llregionpresenceverifier.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llsdappservices.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llsdappservices.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llsdhttpserver.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llsdhttpserver.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llsdmessage.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llsdmessage.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llsdmessagebuilder.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llsdmessagebuilder.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llsdmessagereader.cpp2
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llsdmessagereader.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llsdrpcclient.cpp10
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llsdrpcclient.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llsdrpcserver.cpp8
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llsdrpcserver.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llservice.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llservice.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llservicebuilder.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llservicebuilder.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llstoredmessage.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llstoredmessage.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/lltaskname.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llteleportflags.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/lltemplatemessagebuilder.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/lltemplatemessagebuilder.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/lltemplatemessagedispatcher.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/lltemplatemessagedispatcher.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/lltemplatemessagereader.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/lltemplatemessagereader.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llthrottle.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llthrottle.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/lltransfermanager.cpp60
-rwxr-xr-x[-rw-r--r--]indra/llmessage/lltransfermanager.h4
-rwxr-xr-x[-rw-r--r--]indra/llmessage/lltransfersourceasset.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/lltransfersourceasset.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/lltransfersourcefile.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/lltransfersourcefile.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/lltransfertargetfile.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/lltransfertargetfile.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/lltransfertargetvfile.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/lltransfertargetvfile.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/lltrustedmessageservice.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/lltrustedmessageservice.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llurlrequest.cpp67
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llurlrequest.h9
-rwxr-xr-x[-rw-r--r--]indra/llmessage/lluseroperation.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/lluseroperation.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llvehicleparams.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llxfer.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llxfer.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llxfer_file.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llxfer_file.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llxfer_mem.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llxfer_mem.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llxfer_vfile.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llxfer_vfile.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llxfermanager.cpp13
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llxfermanager.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llxorcipher.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/llxorcipher.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/machine.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/machine.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/mean_collision_data.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/message.cpp3
-rwxr-xr-x[-rw-r--r--]indra/llmessage/message.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/message_prehash.cpp10
-rwxr-xr-x[-rw-r--r--]indra/llmessage/message_prehash.h10
-rwxr-xr-x[-rw-r--r--]indra/llmessage/message_string_table.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/net.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/net.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/partsyspacket.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/partsyspacket.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/patch_code.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/patch_code.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/patch_dct.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/patch_dct.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/patch_idct.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/sound_ids.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/sound_ids.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/tests/commtest.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/tests/llareslistener_test.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/tests/llavatarnamecache_test.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/tests/llcurl_stub.cpp17
-rwxr-xr-x[-rw-r--r--]indra/llmessage/tests/llhost_test.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/tests/llhttpclient_test.cpp118
-rwxr-xr-x[-rw-r--r--]indra/llmessage/tests/llhttpclientadapter_test.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/tests/llmime_test.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/tests/llmockhttpclient.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/tests/llnamevalue_test.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/tests/llpartdata_test.cpp256
-rwxr-xr-x[-rw-r--r--]indra/llmessage/tests/llregionpresenceverifier_test.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/tests/llsdmessage_test.cpp36
-rwxr-xr-x[-rw-r--r--]indra/llmessage/tests/lltemplatemessagedispatcher_test.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/tests/lltesthttpclientadapter.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/tests/lltesthttpclientadapter.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/tests/lltestmessagesender.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/tests/lltestmessagesender.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/tests/lltrustedmessageservice_test.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/tests/llxfer_file_test.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/tests/networkio.h0
-rwxr-xr-x[-rw-r--r--]indra/llmessage/tests/test_llsdmessage_peer.py46
-rwxr-xr-x[-rw-r--r--]indra/llmessage/tests/testrunner.py0
-rwxr-xr-x[-rw-r--r--]indra/llplugin/CMakeLists.txt4
-rwxr-xr-x[-rw-r--r--]indra/llplugin/llpluginclassmedia.cpp2
-rwxr-xr-x[-rw-r--r--]indra/llplugin/llpluginclassmedia.h0
-rwxr-xr-x[-rw-r--r--]indra/llplugin/llpluginclassmediaowner.h0
-rwxr-xr-x[-rw-r--r--]indra/llplugin/llplugincookiestore.cpp28
-rwxr-xr-x[-rw-r--r--]indra/llplugin/llplugincookiestore.h3
-rwxr-xr-x[-rw-r--r--]indra/llplugin/llplugininstance.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llplugin/llplugininstance.h0
-rwxr-xr-x[-rw-r--r--]indra/llplugin/llpluginmessage.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llplugin/llpluginmessage.h0
-rwxr-xr-x[-rw-r--r--]indra/llplugin/llpluginmessageclasses.h0
-rwxr-xr-x[-rw-r--r--]indra/llplugin/llpluginmessagepipe.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llplugin/llpluginmessagepipe.h0
-rwxr-xr-x[-rw-r--r--]indra/llplugin/llpluginprocesschild.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llplugin/llpluginprocesschild.h0
-rwxr-xr-x[-rw-r--r--]indra/llplugin/llpluginprocessparent.cpp49
-rwxr-xr-x[-rw-r--r--]indra/llplugin/llpluginprocessparent.h20
-rwxr-xr-x[-rw-r--r--]indra/llplugin/llpluginsharedmemory.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llplugin/llpluginsharedmemory.h0
-rwxr-xr-x[-rw-r--r--]indra/llplugin/slplugin/CMakeLists.txt13
-rwxr-xr-x[-rw-r--r--]indra/llplugin/slplugin/slplugin-objc.h24
-rwxr-xr-x[-rw-r--r--]indra/llplugin/slplugin/slplugin-objc.mm101
-rwxr-xr-x[-rw-r--r--]indra/llplugin/slplugin/slplugin.cpp131
-rwxr-xr-x[-rw-r--r--]indra/llplugin/slplugin/slplugin_info.plist0
-rwxr-xr-x[-rw-r--r--]indra/llplugin/tests/llplugincookiestore_test.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llprimitive/CMakeLists.txt19
-rwxr-xr-x[-rw-r--r--]indra/llprimitive/legacy_object_types.h0
-rw-r--r--indra/llprimitive/llmaterial.cpp227
-rw-r--r--indra/llprimitive/llmaterial.h155
-rw-r--r--indra/llprimitive/llmaterialid.cpp183
-rw-r--r--indra/llprimitive/llmaterialid.h76
-rwxr-xr-x[-rw-r--r--]indra/llprimitive/llmaterialtable.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llprimitive/llmaterialtable.h0
-rwxr-xr-x[-rw-r--r--]indra/llprimitive/llmediaentry.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llprimitive/llmediaentry.h0
-rwxr-xr-x[-rw-r--r--]indra/llprimitive/llmodel.cpp214
-rwxr-xr-x[-rw-r--r--]indra/llprimitive/llmodel.h4
-rwxr-xr-x[-rw-r--r--]indra/llprimitive/llprimitive.cpp220
-rwxr-xr-x[-rw-r--r--]indra/llprimitive/llprimitive.h44
-rwxr-xr-x[-rw-r--r--]indra/llprimitive/llprimlinkinfo.h0
-rwxr-xr-x[-rw-r--r--]indra/llprimitive/llprimtexturelist.cpp21
-rwxr-xr-x[-rw-r--r--]indra/llprimitive/llprimtexturelist.h4
-rwxr-xr-x[-rw-r--r--]indra/llprimitive/lltextureanim.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llprimitive/lltextureanim.h0
-rwxr-xr-x[-rw-r--r--]indra/llprimitive/lltextureentry.cpp42
-rwxr-xr-x[-rw-r--r--]indra/llprimitive/lltextureentry.h22
-rwxr-xr-x[-rw-r--r--]indra/llprimitive/lltree_common.h0
-rwxr-xr-x[-rw-r--r--]indra/llprimitive/lltreeparams.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llprimitive/lltreeparams.h0
-rwxr-xr-x[-rw-r--r--]indra/llprimitive/llvolumemessage.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llprimitive/llvolumemessage.h0
-rwxr-xr-x[-rw-r--r--]indra/llprimitive/llvolumexml.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llprimitive/llvolumexml.h0
-rwxr-xr-x[-rw-r--r--]indra/llprimitive/material_codes.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llprimitive/material_codes.h0
-rwxr-xr-x[-rw-r--r--]indra/llprimitive/object_flags.h65
-rwxr-xr-x[-rw-r--r--]indra/llprimitive/tests/llmediaentry_test.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llprimitive/tests/llmessagesystem_stub.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llprimitive/tests/llprimitive_test.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llrender/CMakeLists.txt73
-rwxr-xr-x[-rw-r--r--]indra/llrender/llcubemap.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llrender/llcubemap.h0
-rwxr-xr-x[-rw-r--r--]indra/llrender/llfontbitmapcache.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llrender/llfontbitmapcache.h0
-rwxr-xr-x[-rw-r--r--]indra/llrender/llfontfreetype.cpp7
-rwxr-xr-x[-rw-r--r--]indra/llrender/llfontfreetype.h0
-rwxr-xr-x[-rw-r--r--]indra/llrender/llfontgl.cpp21
-rwxr-xr-x[-rw-r--r--]indra/llrender/llfontgl.h4
-rwxr-xr-x[-rw-r--r--]indra/llrender/llfontregistry.cpp32
-rwxr-xr-x[-rw-r--r--]indra/llrender/llfontregistry.h4
-rwxr-xr-x[-rw-r--r--]indra/llrender/llgl.cpp186
-rwxr-xr-x[-rw-r--r--]indra/llrender/llgl.h42
-rwxr-xr-x[-rw-r--r--]indra/llrender/llgldbg.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llrender/llgldbg.h0
-rwxr-xr-x[-rw-r--r--]indra/llrender/llglheaders.h33
-rwxr-xr-x[-rw-r--r--]indra/llrender/llglslshader.cpp455
-rwxr-xr-x[-rw-r--r--]indra/llrender/llglslshader.h90
-rwxr-xr-x[-rw-r--r--]indra/llrender/llglstates.h5
-rw-r--r--indra/llrender/llgltexture.cpp396
-rw-r--r--indra/llrender/llgltexture.h199
-rwxr-xr-x[-rw-r--r--]indra/llrender/llgltypes.h0
-rwxr-xr-x[-rw-r--r--]indra/llrender/llimagegl.cpp379
-rwxr-xr-x[-rw-r--r--]indra/llrender/llimagegl.h63
-rwxr-xr-x[-rw-r--r--]indra/llrender/llpostprocess.cpp59
-rwxr-xr-x[-rw-r--r--]indra/llrender/llpostprocess.h3
-rwxr-xr-x[-rw-r--r--]indra/llrender/llrender.cpp132
-rwxr-xr-x[-rw-r--r--]indra/llrender/llrender.h10
-rw-r--r--indra/llrender/llrender2dutils.cpp1608
-rw-r--r--indra/llrender/llrender2dutils.h163
-rwxr-xr-xindra/llrender/llrendernavprim.cpp59
-rwxr-xr-xindra/llrender/llrendernavprim.h49
-rwxr-xr-x[-rw-r--r--]indra/llrender/llrendersphere.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llrender/llrendersphere.h0
-rwxr-xr-x[-rw-r--r--]indra/llrender/llrendertarget.cpp187
-rwxr-xr-x[-rw-r--r--]indra/llrender/llrendertarget.h24
-rwxr-xr-x[-rw-r--r--]indra/llrender/llshadermgr.cpp136
-rwxr-xr-x[-rw-r--r--]indra/llrender/llshadermgr.h56
-rwxr-xr-x[-rw-r--r--]indra/llrender/lltexture.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llrender/lltexture.h7
-rw-r--r--indra/llrender/lluiimage.cpp243
-rw-r--r--indra/llrender/lluiimage.h126
-rwxr-xr-x[-rw-r--r--]indra/llrender/llvertexbuffer.cpp539
-rwxr-xr-x[-rw-r--r--]indra/llrender/llvertexbuffer.h51
-rwxr-xr-x[-rw-r--r--]indra/llui/CMakeLists.txt34
-rwxr-xr-x[-rw-r--r--]indra/llui/llaccordionctrl.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llui/llaccordionctrl.h0
-rwxr-xr-x[-rw-r--r--]indra/llui/llaccordionctrltab.cpp2
-rwxr-xr-x[-rw-r--r--]indra/llui/llaccordionctrltab.h0
-rwxr-xr-x[-rw-r--r--]indra/llui/llbadge.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llui/llbadge.h0
-rwxr-xr-x[-rw-r--r--]indra/llui/llbadgeholder.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llui/llbadgeholder.h0
-rwxr-xr-x[-rw-r--r--]indra/llui/llbadgeowner.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llui/llbadgeowner.h0
-rwxr-xr-x[-rw-r--r--]indra/llui/llbutton.cpp89
-rwxr-xr-x[-rw-r--r--]indra/llui/llbutton.h10
-rwxr-xr-x[-rw-r--r--]indra/llui/llcallbackmap.h0
-rwxr-xr-xindra/llui/llchatentry.cpp259
-rwxr-xr-xindra/llui/llchatentry.h106
-rwxr-xr-x[-rw-r--r--]indra/llui/llcheckboxctrl.cpp14
-rwxr-xr-x[-rw-r--r--]indra/llui/llcheckboxctrl.h2
-rwxr-xr-x[-rw-r--r--]indra/llui/llclipboard.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llui/llclipboard.h0
-rwxr-xr-x[-rw-r--r--]indra/llui/llcombobox.cpp12
-rwxr-xr-x[-rw-r--r--]indra/llui/llcombobox.h2
-rwxr-xr-x[-rw-r--r--]indra/llui/llcommandmanager.cpp6
-rwxr-xr-x[-rw-r--r--]indra/llui/llcommandmanager.h13
-rwxr-xr-x[-rw-r--r--]indra/llui/llconsole.cpp2
-rwxr-xr-x[-rw-r--r--]indra/llui/llconsole.h1
-rwxr-xr-x[-rw-r--r--]indra/llui/llcontainerview.cpp18
-rwxr-xr-x[-rw-r--r--]indra/llui/llcontainerview.h0
-rwxr-xr-x[-rw-r--r--]indra/llui/llctrlselectioninterface.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llui/llctrlselectioninterface.h0
-rwxr-xr-x[-rw-r--r--]indra/llui/lldockablefloater.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llui/lldockablefloater.h0
-rwxr-xr-x[-rw-r--r--]indra/llui/lldockcontrol.cpp31
-rwxr-xr-x[-rw-r--r--]indra/llui/lldockcontrol.h4
-rwxr-xr-x[-rw-r--r--]indra/llui/lldraghandle.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llui/lldraghandle.h0
-rwxr-xr-x[-rw-r--r--]indra/llui/lleditmenuhandler.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llui/lleditmenuhandler.h0
-rwxr-xr-x[-rw-r--r--]indra/llui/llf32uictrl.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llui/llf32uictrl.h0
-rwxr-xr-x[-rw-r--r--]indra/llui/llfiltereditor.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llui/llfiltereditor.h0
-rwxr-xr-xindra/llui/llflashtimer.cpp100
-rwxr-xr-xindra/llui/llflashtimer.h73
-rwxr-xr-x[-rw-r--r--]indra/llui/llflatlistview.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llui/llflatlistview.h0
-rwxr-xr-x[-rw-r--r--]indra/llui/llfloater.cpp339
-rwxr-xr-x[-rw-r--r--]indra/llui/llfloater.h39
-rwxr-xr-x[-rw-r--r--]indra/llui/llfloaterreg.cpp87
-rwxr-xr-x[-rw-r--r--]indra/llui/llfloaterreg.h0
-rwxr-xr-x[-rw-r--r--]indra/llui/llfloaterreglistener.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llui/llfloaterreglistener.h0
-rwxr-xr-x[-rw-r--r--]indra/llui/llflyoutbutton.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llui/llflyoutbutton.h0
-rwxr-xr-x[-rw-r--r--]indra/llui/llfocusmgr.cpp4
-rwxr-xr-x[-rw-r--r--]indra/llui/llfocusmgr.h2
-rwxr-xr-xindra/llui/llfolderview.cpp1954
-rwxr-xr-xindra/llui/llfolderview.h399
-rw-r--r--indra/llui/llfolderviewitem.cpp2109
-rw-r--r--indra/llui/llfolderviewitem.h457
-rwxr-xr-xindra/llui/llfolderviewmodel.cpp68
-rwxr-xr-xindra/llui/llfolderviewmodel.h445
-rwxr-xr-x[-rw-r--r--]indra/llui/llfunctorregistry.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llui/llfunctorregistry.h2
-rw-r--r--indra/llui/llhandle.h181
-rwxr-xr-x[-rw-r--r--]indra/llui/llhelp.h0
-rwxr-xr-x[-rw-r--r--]indra/llui/lliconctrl.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llui/lliconctrl.h0
-rwxr-xr-x[-rw-r--r--]indra/llui/llkeywords.cpp5
-rwxr-xr-x[-rw-r--r--]indra/llui/llkeywords.h0
-rwxr-xr-x[-rw-r--r--]indra/llui/lllayoutstack.cpp153
-rwxr-xr-x[-rw-r--r--]indra/llui/lllayoutstack.h15
-rwxr-xr-x[-rw-r--r--]indra/llui/lllazyvalue.h0
-rwxr-xr-x[-rw-r--r--]indra/llui/lllineeditor.cpp311
-rwxr-xr-x[-rw-r--r--]indra/llui/lllineeditor.h30
-rwxr-xr-x[-rw-r--r--]indra/llui/llloadingindicator.cpp2
-rwxr-xr-x[-rw-r--r--]indra/llui/llloadingindicator.h6
-rwxr-xr-x[-rw-r--r--]indra/llui/lllocalcliprect.cpp8
-rwxr-xr-x[-rw-r--r--]indra/llui/lllocalcliprect.h0
-rwxr-xr-x[-rw-r--r--]indra/llui/llmenubutton.cpp78
-rwxr-xr-x[-rw-r--r--]indra/llui/llmenubutton.h11
-rwxr-xr-x[-rw-r--r--]indra/llui/llmenugl.cpp239
-rwxr-xr-x[-rw-r--r--]indra/llui/llmenugl.h54
-rwxr-xr-x[-rw-r--r--]indra/llui/llmodaldialog.cpp37
-rwxr-xr-x[-rw-r--r--]indra/llui/llmodaldialog.h2
-rwxr-xr-x[-rw-r--r--]indra/llui/llmultifloater.cpp47
-rwxr-xr-x[-rw-r--r--]indra/llui/llmultifloater.h16
-rwxr-xr-x[-rw-r--r--]indra/llui/llmultislider.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llui/llmultislider.h0
-rwxr-xr-x[-rw-r--r--]indra/llui/llmultisliderctrl.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llui/llmultisliderctrl.h0
-rwxr-xr-x[-rw-r--r--]indra/llui/llnotificationptr.h0
-rwxr-xr-x[-rw-r--r--]indra/llui/llnotifications.cpp551
-rwxr-xr-x[-rw-r--r--]indra/llui/llnotifications.h306
-rw-r--r--indra/llui/llnotificationslistener.cpp11
-rwxr-xr-x[-rw-r--r--]indra/llui/llnotificationsutil.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llui/llnotificationsutil.h0
-rwxr-xr-x[-rw-r--r--]indra/llui/llnotificationtemplate.h56
-rwxr-xr-x[-rw-r--r--]indra/llui/llnotificationvisibilityrule.h0
-rwxr-xr-x[-rw-r--r--]indra/llui/llpanel.cpp18
-rwxr-xr-x[-rw-r--r--]indra/llui/llpanel.h2
-rwxr-xr-x[-rw-r--r--]indra/llui/llprogressbar.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llui/llprogressbar.h0
-rwxr-xr-x[-rw-r--r--]indra/llui/llradiogroup.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llui/llradiogroup.h0
-rwxr-xr-x[-rw-r--r--]indra/llui/llresizebar.cpp171
-rwxr-xr-x[-rw-r--r--]indra/llui/llresizebar.h52
-rwxr-xr-x[-rw-r--r--]indra/llui/llresizehandle.cpp58
-rwxr-xr-x[-rw-r--r--]indra/llui/llresizehandle.h0
-rwxr-xr-x[-rw-r--r--]indra/llui/llresmgr.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llui/llresmgr.h0
-rwxr-xr-x[-rw-r--r--]indra/llui/llrngwriter.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llui/llrngwriter.h0
-rwxr-xr-x[-rw-r--r--]indra/llui/llscrollbar.cpp5
-rwxr-xr-x[-rw-r--r--]indra/llui/llscrollbar.h3
-rwxr-xr-x[-rw-r--r--]indra/llui/llscrollcontainer.cpp37
-rwxr-xr-x[-rw-r--r--]indra/llui/llscrollcontainer.h4
-rwxr-xr-x[-rw-r--r--]indra/llui/llscrollingpanellist.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llui/llscrollingpanellist.h0
-rwxr-xr-x[-rw-r--r--]indra/llui/llscrolllistcell.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llui/llscrolllistcell.h0
-rwxr-xr-x[-rw-r--r--]indra/llui/llscrolllistcolumn.cpp6
-rwxr-xr-x[-rw-r--r--]indra/llui/llscrolllistcolumn.h0
-rwxr-xr-x[-rw-r--r--]indra/llui/llscrolllistctrl.cpp235
-rwxr-xr-x[-rw-r--r--]indra/llui/llscrolllistctrl.h37
-rwxr-xr-x[-rw-r--r--]indra/llui/llscrolllistitem.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llui/llscrolllistitem.h0
-rw-r--r--indra/llui/llsdparam.cpp342
-rw-r--r--indra/llui/llsdparam.h126
-rwxr-xr-x[-rw-r--r--]indra/llui/llsearcheditor.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llui/llsearcheditor.h0
-rwxr-xr-x[-rw-r--r--]indra/llui/llslider.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llui/llslider.h0
-rwxr-xr-x[-rw-r--r--]indra/llui/llsliderctrl.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llui/llsliderctrl.h0
-rwxr-xr-xindra/llui/llspellcheck.cpp509
-rwxr-xr-xindra/llui/llspellcheck.h93
-rwxr-xr-xindra/llui/llspellcheckmenuhandler.h46
-rwxr-xr-x[-rw-r--r--]indra/llui/llspinctrl.cpp5
-rwxr-xr-x[-rw-r--r--]indra/llui/llspinctrl.h1
-rwxr-xr-x[-rw-r--r--]indra/llui/llstatbar.cpp2
-rwxr-xr-x[-rw-r--r--]indra/llui/llstatbar.h0
-rwxr-xr-x[-rw-r--r--]indra/llui/llstatgraph.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llui/llstatgraph.h0
-rwxr-xr-x[-rw-r--r--]indra/llui/llstatview.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llui/llstatview.h0
-rwxr-xr-x[-rw-r--r--]indra/llui/llstyle.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llui/llstyle.h0
-rwxr-xr-x[-rw-r--r--]indra/llui/lltabcontainer.cpp121
-rwxr-xr-x[-rw-r--r--]indra/llui/lltabcontainer.h16
-rwxr-xr-x[-rw-r--r--]indra/llui/lltextbase.cpp547
-rwxr-xr-x[-rw-r--r--]indra/llui/lltextbase.h100
-rwxr-xr-x[-rw-r--r--]indra/llui/lltextbox.cpp15
-rwxr-xr-x[-rw-r--r--]indra/llui/lltextbox.h0
-rwxr-xr-x[-rw-r--r--]indra/llui/lltexteditor.cpp271
-rwxr-xr-x[-rw-r--r--]indra/llui/lltexteditor.h23
-rwxr-xr-x[-rw-r--r--]indra/llui/lltextparser.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llui/lltextparser.h0
-rwxr-xr-x[-rw-r--r--]indra/llui/lltextutil.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llui/lltextutil.h0
-rwxr-xr-x[-rw-r--r--]indra/llui/lltextvalidate.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llui/lltextvalidate.h0
-rwxr-xr-x[-rw-r--r--]indra/llui/lltimectrl.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llui/lltimectrl.h0
-rwxr-xr-x[-rw-r--r--]indra/llui/lltoggleablemenu.cpp9
-rwxr-xr-x[-rw-r--r--]indra/llui/lltoggleablemenu.h4
-rwxr-xr-x[-rw-r--r--]indra/llui/lltoolbar.cpp38
-rwxr-xr-x[-rw-r--r--]indra/llui/lltoolbar.h5
-rwxr-xr-x[-rw-r--r--]indra/llui/lltooltip.cpp20
-rwxr-xr-x[-rw-r--r--]indra/llui/lltooltip.h4
-rwxr-xr-x[-rw-r--r--]indra/llui/lltrans.cpp (renamed from indra/llxuixml/lltrans.cpp)0
-rwxr-xr-x[-rw-r--r--]indra/llui/lltrans.h (renamed from indra/llxuixml/lltrans.h)0
-rwxr-xr-x[-rw-r--r--]indra/llui/lltransutil.cpp13
-rwxr-xr-x[-rw-r--r--]indra/llui/lltransutil.h0
-rwxr-xr-x[-rw-r--r--]indra/llui/llui.cpp1695
-rwxr-xr-x[-rw-r--r--]indra/llui/llui.h155
-rwxr-xr-x[-rw-r--r--]indra/llui/lluicolor.cpp (renamed from indra/llxuixml/lluicolor.cpp)0
-rwxr-xr-x[-rw-r--r--]indra/llui/lluicolor.h (renamed from indra/llxuixml/lluicolor.h)0
-rwxr-xr-x[-rw-r--r--]indra/llui/lluicolortable.cpp18
-rwxr-xr-x[-rw-r--r--]indra/llui/lluicolortable.h0
-rwxr-xr-x[-rw-r--r--]indra/llui/lluiconstants.h0
-rwxr-xr-x[-rw-r--r--]indra/llui/lluictrl.cpp20
-rwxr-xr-x[-rw-r--r--]indra/llui/lluictrl.h0
-rwxr-xr-x[-rw-r--r--]indra/llui/lluictrlfactory.cpp73
-rwxr-xr-x[-rw-r--r--]indra/llui/lluictrlfactory.h50
-rwxr-xr-x[-rw-r--r--]indra/llui/lluifwd.h0
-rw-r--r--indra/llui/lluiimage.cpp199
-rw-r--r--indra/llui/lluiimage.h124
-rwxr-xr-x[-rw-r--r--]indra/llui/lluistring.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llui/lluistring.h0
-rwxr-xr-x[-rw-r--r--]indra/llui/llundo.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llui/llundo.h0
-rwxr-xr-x[-rw-r--r--]indra/llui/llurlaction.cpp75
-rwxr-xr-x[-rw-r--r--]indra/llui/llurlaction.h7
-rwxr-xr-x[-rw-r--r--]indra/llui/llurlentry.cpp36
-rwxr-xr-x[-rw-r--r--]indra/llui/llurlentry.h16
-rwxr-xr-x[-rw-r--r--]indra/llui/llurlmatch.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llui/llurlmatch.h0
-rwxr-xr-x[-rw-r--r--]indra/llui/llurlregistry.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llui/llurlregistry.h0
-rwxr-xr-x[-rw-r--r--]indra/llui/llview.cpp97
-rwxr-xr-x[-rw-r--r--]indra/llui/llview.h1
-rwxr-xr-x[-rw-r--r--]indra/llui/llviewborder.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llui/llviewborder.h0
-rw-r--r--indra/llui/llviewereventrecorder.cpp296
-rw-r--r--indra/llui/llviewereventrecorder.h103
-rwxr-xr-x[-rw-r--r--]indra/llui/llviewinject.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llui/llviewinject.h0
-rwxr-xr-x[-rw-r--r--]indra/llui/llviewmodel.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llui/llviewmodel.h1
-rwxr-xr-x[-rw-r--r--]indra/llui/llviewquery.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llui/llviewquery.h0
-rwxr-xr-x[-rw-r--r--]indra/llui/llwindowshade.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llui/llwindowshade.h0
-rwxr-xr-xindra/llui/llxuiparser.cpp1780
-rwxr-xr-xindra/llui/llxuiparser.h244
-rwxr-xr-x[-rw-r--r--]indra/llui/tests/llurlentry_stub.cpp48
-rwxr-xr-x[-rw-r--r--]indra/llui/tests/llurlentry_test.cpp17
-rwxr-xr-x[-rw-r--r--]indra/llui/tests/llurlmatch_test.cpp52
-rwxr-xr-x[-rw-r--r--]indra/llvfs/CMakeLists.txt12
-rwxr-xr-x[-rw-r--r--]indra/llvfs/lldir.cpp521
-rwxr-xr-x[-rw-r--r--]indra/llvfs/lldir.h111
-rwxr-xr-x[-rw-r--r--]indra/llvfs/lldir_linux.cpp2
-rwxr-xr-x[-rw-r--r--]indra/llvfs/lldir_linux.h2
-rwxr-xr-x[-rw-r--r--]indra/llvfs/lldir_mac.cpp239
-rwxr-xr-x[-rw-r--r--]indra/llvfs/lldir_mac.h10
-rwxr-xr-x[-rw-r--r--]indra/llvfs/lldir_solaris.cpp2
-rwxr-xr-x[-rw-r--r--]indra/llvfs/lldir_solaris.h2
-rwxr-xr-x[-rw-r--r--]indra/llvfs/lldir_win32.cpp4
-rwxr-xr-x[-rw-r--r--]indra/llvfs/lldir_win32.h2
-rwxr-xr-x[-rw-r--r--]indra/llvfs/lldirguard.h0
-rwxr-xr-x[-rw-r--r--]indra/llvfs/lldiriterator.cpp7
-rwxr-xr-x[-rw-r--r--]indra/llvfs/lldiriterator.h0
-rwxr-xr-x[-rw-r--r--]indra/llvfs/lllfsthread.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llvfs/lllfsthread.h0
-rwxr-xr-x[-rw-r--r--]indra/llvfs/llpidlock.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llvfs/llpidlock.h0
-rwxr-xr-x[-rw-r--r--]indra/llvfs/llvfile.cpp5
-rwxr-xr-x[-rw-r--r--]indra/llvfs/llvfile.h0
-rwxr-xr-x[-rw-r--r--]indra/llvfs/llvfs.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llvfs/llvfs.h0
-rwxr-xr-xindra/llvfs/llvfs_objc.h43
-rwxr-xr-xindra/llvfs/llvfs_objc.mm108
-rwxr-xr-x[-rw-r--r--]indra/llvfs/llvfsthread.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llvfs/llvfsthread.h0
-rwxr-xr-x[-rw-r--r--]indra/llvfs/tests/lldir_test.cpp346
-rwxr-xr-x[-rw-r--r--]indra/llvfs/tests/lldiriterator_test.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llwindow/CMakeLists.txt90
-rwxr-xr-x[-rw-r--r--]indra/llwindow/GL/glh_extensions.h4
-rwxr-xr-x[-rw-r--r--]indra/llwindow/GL/glh_genext.h0
-rw-r--r--indra/llwindow/llappdelegate-objc.h48
-rwxr-xr-x[-rw-r--r--]indra/llwindow/lldragdropwin32.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llwindow/lldragdropwin32.h2
-rwxr-xr-x[-rw-r--r--]indra/llwindow/lldxhardware.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llwindow/lldxhardware.h0
-rwxr-xr-x[-rw-r--r--]indra/llwindow/llkeyboard.cpp2
-rwxr-xr-x[-rw-r--r--]indra/llwindow/llkeyboard.h17
-rwxr-xr-x[-rw-r--r--]indra/llwindow/llkeyboardheadless.cpp7
-rwxr-xr-x[-rw-r--r--]indra/llwindow/llkeyboardheadless.h3
-rwxr-xr-x[-rw-r--r--]indra/llwindow/llkeyboardmacosx.cpp54
-rwxr-xr-x[-rw-r--r--]indra/llwindow/llkeyboardmacosx.h10
-rwxr-xr-x[-rw-r--r--]indra/llwindow/llkeyboardsdl.cpp20
-rwxr-xr-x[-rw-r--r--]indra/llwindow/llkeyboardsdl.h0
-rwxr-xr-x[-rw-r--r--]indra/llwindow/llkeyboardwin32.cpp60
-rwxr-xr-x[-rw-r--r--]indra/llwindow/llkeyboardwin32.h0
-rwxr-xr-x[-rw-r--r--]indra/llwindow/llmousehandler.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llwindow/llmousehandler.h0
-rw-r--r--indra/llwindow/llopenglview-objc.h111
-rw-r--r--indra/llwindow/llopenglview-objc.mm692
-rwxr-xr-x[-rw-r--r--]indra/llwindow/llpreeditor.h0
-rwxr-xr-x[-rw-r--r--]indra/llwindow/llwindow.cpp7
-rwxr-xr-x[-rw-r--r--]indra/llwindow/llwindow.h3
-rwxr-xr-x[-rw-r--r--]indra/llwindow/llwindowcallbacks.cpp1
-rwxr-xr-x[-rw-r--r--]indra/llwindow/llwindowcallbacks.h0
-rwxr-xr-x[-rw-r--r--]indra/llwindow/llwindowheadless.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llwindow/llwindowheadless.h0
-rwxr-xr-x[-rw-r--r--]indra/llwindow/llwindowmacosx-objc.h118
-rwxr-xr-x[-rw-r--r--]indra/llwindow/llwindowmacosx-objc.mm386
-rwxr-xr-x[-rw-r--r--]indra/llwindow/llwindowmacosx.cpp2853
-rwxr-xr-x[-rw-r--r--]indra/llwindow/llwindowmacosx.h70
-rwxr-xr-x[-rw-r--r--]indra/llwindow/llwindowmesaheadless.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llwindow/llwindowmesaheadless.h0
-rwxr-xr-x[-rw-r--r--]indra/llwindow/llwindowsdl.cpp64
-rwxr-xr-x[-rw-r--r--]indra/llwindow/llwindowsdl.h2
-rwxr-xr-x[-rw-r--r--]indra/llwindow/llwindowwin32.cpp35
-rwxr-xr-x[-rw-r--r--]indra/llwindow/llwindowwin32.h0
-rwxr-xr-x[-rw-r--r--]indra/llxml/CMakeLists.txt8
-rwxr-xr-x[-rw-r--r--]indra/llxml/llcontrol.cpp180
-rwxr-xr-x[-rw-r--r--]indra/llxml/llcontrol.h68
-rwxr-xr-x[-rw-r--r--]indra/llxml/llcontrolgroupreader.h0
-rwxr-xr-x[-rw-r--r--]indra/llxml/llxmlnode.cpp97
-rwxr-xr-x[-rw-r--r--]indra/llxml/llxmlnode.h5
-rwxr-xr-x[-rw-r--r--]indra/llxml/llxmlparser.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llxml/llxmlparser.h0
-rwxr-xr-x[-rw-r--r--]indra/llxml/llxmltree.cpp0
-rwxr-xr-x[-rw-r--r--]indra/llxml/llxmltree.h0
-rwxr-xr-x[-rw-r--r--]indra/llxml/tests/llcontrol_test.cpp6
-rw-r--r--indra/llxuixml/CMakeLists.txt45
-rw-r--r--indra/llxuixml/llinitparam.cpp469
-rw-r--r--indra/llxuixml/llinitparam.h2299
-rw-r--r--indra/llxuixml/llregistry.h351
-rw-r--r--indra/llxuixml/llxuiparser.cpp1756
-rw-r--r--indra/llxuixml/llxuiparser.h242
-rwxr-xr-x[-rw-r--r--]indra/lscript/CMakeLists.txt0
-rwxr-xr-x[-rw-r--r--]indra/lscript/llscriptresource.h0
-rwxr-xr-x[-rw-r--r--]indra/lscript/llscriptresourceconsumer.h0
-rwxr-xr-x[-rw-r--r--]indra/lscript/llscriptresourcepool.h0
-rwxr-xr-x[-rw-r--r--]indra/lscript/lscript_alloc.h0
-rwxr-xr-x[-rw-r--r--]indra/lscript/lscript_byteconvert.h0
-rwxr-xr-x[-rw-r--r--]indra/lscript/lscript_byteformat.h8
-rwxr-xr-x[-rw-r--r--]indra/lscript/lscript_compile/CMakeLists.txt9
-rw-r--r--indra/lscript/lscript_compile/bison.bat9
-rwxr-xr-x[-rw-r--r--]indra/lscript/lscript_compile/indra.l78
-rwxr-xr-x[-rw-r--r--]indra/lscript/lscript_compile/indra.y7
-rwxr-xr-x[-rw-r--r--]indra/lscript/lscript_compile/lscript_alloc.cpp0
-rwxr-xr-x[-rw-r--r--]indra/lscript/lscript_compile/lscript_bytecode.cpp0
-rwxr-xr-x[-rw-r--r--]indra/lscript/lscript_compile/lscript_bytecode.h0
-rwxr-xr-x[-rw-r--r--]indra/lscript/lscript_compile/lscript_error.cpp0
-rwxr-xr-x[-rw-r--r--]indra/lscript/lscript_compile/lscript_error.h0
-rwxr-xr-x[-rw-r--r--]indra/lscript/lscript_compile/lscript_heap.cpp0
-rwxr-xr-x[-rw-r--r--]indra/lscript/lscript_compile/lscript_heap.h0
-rwxr-xr-x[-rw-r--r--]indra/lscript/lscript_compile/lscript_resource.cpp0
-rwxr-xr-x[-rw-r--r--]indra/lscript/lscript_compile/lscript_resource.h0
-rwxr-xr-x[-rw-r--r--]indra/lscript/lscript_compile/lscript_scope.cpp0
-rwxr-xr-x[-rw-r--r--]indra/lscript/lscript_compile/lscript_scope.h0
-rwxr-xr-x[-rw-r--r--]indra/lscript/lscript_compile/lscript_tree.cpp0
-rwxr-xr-x[-rw-r--r--]indra/lscript/lscript_compile/lscript_tree.h0
-rwxr-xr-x[-rw-r--r--]indra/lscript/lscript_compile/lscript_typecheck.cpp0
-rwxr-xr-x[-rw-r--r--]indra/lscript/lscript_compile/lscript_typecheck.h0
-rwxr-xr-x[-rw-r--r--]indra/lscript/lscript_compile/windows/unistd.h0
-rwxr-xr-x[-rw-r--r--]indra/lscript/lscript_execute.h0
-rwxr-xr-x[-rw-r--r--]indra/lscript/lscript_execute/CMakeLists.txt3
-rwxr-xr-x[-rw-r--r--]indra/lscript/lscript_execute/llscriptresource.cpp0
-rwxr-xr-x[-rw-r--r--]indra/lscript/lscript_execute/llscriptresourceconsumer.cpp0
-rwxr-xr-x[-rw-r--r--]indra/lscript/lscript_execute/llscriptresourcepool.cpp0
-rwxr-xr-x[-rw-r--r--]indra/lscript/lscript_execute/lscript_execute.cpp11
-rwxr-xr-x[-rw-r--r--]indra/lscript/lscript_execute/lscript_heapruntime.cpp0
-rwxr-xr-x[-rw-r--r--]indra/lscript/lscript_execute/lscript_heapruntime.h0
-rwxr-xr-x[-rw-r--r--]indra/lscript/lscript_execute/lscript_readlso.cpp11
-rwxr-xr-x[-rw-r--r--]indra/lscript/lscript_execute/lscript_readlso.h0
-rwxr-xr-x[-rw-r--r--]indra/lscript/lscript_export.h0
-rwxr-xr-x[-rw-r--r--]indra/lscript/lscript_http.h0
-rwxr-xr-x[-rw-r--r--]indra/lscript/lscript_library.h0
-rwxr-xr-x[-rw-r--r--]indra/lscript/lscript_library/CMakeLists.txt3
-rwxr-xr-x[-rw-r--r--]indra/lscript/lscript_library/lscript_alloc.cpp0
-rwxr-xr-x[-rw-r--r--]indra/lscript/lscript_library/lscript_export.cpp0
-rwxr-xr-x[-rw-r--r--]indra/lscript/lscript_library/lscript_library.cpp0
-rwxr-xr-x[-rw-r--r--]indra/lscript/lscript_rt_interface.h0
-rwxr-xr-x[-rw-r--r--]indra/mac_crash_logger/CMakeLists.txt9
-rwxr-xr-xindra/mac_crash_logger/CrashReporter.nibbin0 -> 32286 bytes
-rw-r--r--indra/mac_crash_logger/CrashReporter.nib/classes.nib8
-rw-r--r--indra/mac_crash_logger/CrashReporter.nib/info.nib18
-rw-r--r--indra/mac_crash_logger/CrashReporter.nib/objects.xib68
-rwxr-xr-xindra/mac_crash_logger/CrashReporter.xib3895
-rwxr-xr-x[-rw-r--r--]indra/mac_crash_logger/Info.plist8
-rwxr-xr-x[-rw-r--r--]indra/mac_crash_logger/llcrashloggermac.cpp171
-rwxr-xr-x[-rw-r--r--]indra/mac_crash_logger/llcrashloggermac.h1
-rwxr-xr-xindra/mac_crash_logger/llcrashloggermacdelegate.h52
-rwxr-xr-xindra/mac_crash_logger/llcrashloggermacdelegate.mm75
-rwxr-xr-x[-rw-r--r--]indra/mac_crash_logger/mac_crash_logger.cpp12
-rw-r--r--indra/mac_updater/AutoUpdater.nib/classes.nib4
-rw-r--r--indra/mac_updater/AutoUpdater.nib/info.nib14
-rw-r--r--indra/mac_updater/AutoUpdater.nib/objects.xib56
-rw-r--r--indra/mac_updater/CMakeLists.txt73
-rw-r--r--indra/mac_updater/Info.plist26
-rw-r--r--indra/mac_updater/mac_updater.cpp13
-rwxr-xr-x[-rw-r--r--]indra/media_plugins/CMakeLists.txt0
-rwxr-xr-x[-rw-r--r--]indra/media_plugins/base/CMakeLists.txt5
-rwxr-xr-x[-rw-r--r--]indra/media_plugins/base/media_plugin_base.cpp0
-rwxr-xr-x[-rw-r--r--]indra/media_plugins/base/media_plugin_base.exp0
-rwxr-xr-x[-rw-r--r--]indra/media_plugins/base/media_plugin_base.h0
-rwxr-xr-x[-rw-r--r--]indra/media_plugins/example/CMakeLists.txt5
-rwxr-xr-x[-rw-r--r--]indra/media_plugins/example/media_plugin_example.cpp0
-rwxr-xr-x[-rw-r--r--]indra/media_plugins/gstreamer010/CMakeLists.txt5
-rwxr-xr-x[-rw-r--r--]indra/media_plugins/gstreamer010/llmediaimplgstreamer.h0
-rwxr-xr-x[-rw-r--r--]indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.cpp0
-rwxr-xr-x[-rw-r--r--]indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.h0
-rwxr-xr-x[-rw-r--r--]indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms_raw.inc0
-rwxr-xr-x[-rw-r--r--]indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms_rawv.inc0
-rwxr-xr-x[-rw-r--r--]indra/media_plugins/gstreamer010/llmediaimplgstreamertriviallogging.h0
-rwxr-xr-x[-rw-r--r--]indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.cpp3
-rwxr-xr-x[-rw-r--r--]indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.h0
-rwxr-xr-x[-rw-r--r--]indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp0
-rwxr-xr-x[-rw-r--r--]indra/media_plugins/quicktime/CMakeLists.txt5
-rwxr-xr-x[-rw-r--r--]indra/media_plugins/quicktime/media_plugin_quicktime.cpp48
-rwxr-xr-x[-rw-r--r--]indra/media_plugins/webkit/CMakeLists.txt5
-rwxr-xr-x[-rw-r--r--]indra/media_plugins/webkit/dummy_volume_catcher.cpp0
-rwxr-xr-x[-rw-r--r--]indra/media_plugins/webkit/linux_volume_catcher.cpp0
-rwxr-xr-x[-rw-r--r--]indra/media_plugins/webkit/linux_volume_catcher_pa_syms.inc0
-rwxr-xr-x[-rw-r--r--]indra/media_plugins/webkit/linux_volume_catcher_paglib_syms.inc0
-rwxr-xr-x[-rw-r--r--]indra/media_plugins/webkit/mac_volume_catcher.cpp8
-rwxr-xr-x[-rw-r--r--]indra/media_plugins/webkit/media_plugin_webkit.cpp0
-rwxr-xr-x[-rw-r--r--]indra/media_plugins/webkit/volume_catcher.h0
-rwxr-xr-x[-rw-r--r--]indra/media_plugins/webkit/windows_volume_catcher.cpp52
-rwxr-xr-x[-rw-r--r--]indra/media_plugins/winmmshim/CMakeLists.txt0
-rwxr-xr-x[-rw-r--r--]indra/media_plugins/winmmshim/forwarding_api.cpp0
-rwxr-xr-x[-rw-r--r--]indra/media_plugins/winmmshim/forwarding_api.h0
-rwxr-xr-x[-rw-r--r--]indra/media_plugins/winmmshim/winmm.def0
-rwxr-xr-x[-rw-r--r--]indra/media_plugins/winmmshim/winmm_shim.cpp2
-rwxr-xr-x[-rw-r--r--]indra/newview/CMakeLists.txt464
-rwxr-xr-x[-rw-r--r--]indra/newview/English.lproj/InfoPlist.strings4
-rwxr-xr-x[-rw-r--r--]indra/newview/English.lproj/language.txt0
-rwxr-xr-x[-rw-r--r--]indra/newview/German.lproj/language.txt0
-rwxr-xr-x[-rw-r--r--]indra/newview/Info-SecondLife.plist30
-rwxr-xr-x[-rw-r--r--]indra/newview/Info-SecondLifeVorbis.plist0
-rwxr-xr-x[-rw-r--r--]indra/newview/Japanese.lproj/language.txt0
-rwxr-xr-x[-rw-r--r--]indra/newview/Korean.lproj/language.txt0
-rw-r--r--indra/newview/SecondLife.nibbin0 -> 12348 bytes
-rw-r--r--indra/newview/SecondLife.nib/classes.nib4
-rw-r--r--indra/newview/SecondLife.nib/info.nib23
-rw-r--r--indra/newview/SecondLife.nib/objects.xib259
-rw-r--r--indra/newview/SecondLife.xib1136
-rw-r--r--indra/newview/VIEWER_VERSION.txt1
-rwxr-xr-x[-rw-r--r--]indra/newview/VertexCache.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/ViewerInstall.cmake0
-rwxr-xr-x[-rw-r--r--]indra/newview/VorbisFramework.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/CA.pem0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/anim.ini0
-rwxr-xr-xindra/newview/app_settings/autoreplace.xml8330
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/cmd_line.xml371
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/commands.xml75
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/foldertypes.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/grass.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/high_graphics.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/ignorable_dialogs.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/keys.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/keywords.ini147
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/lindenlab.pem0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/llsd.xsd0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/logcontrol.xml10
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/low_graphics.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/mid_graphics.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/settings.xml1677
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/settings_crash_behavior.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/settings_files.xml3
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/settings_minimal.xml5
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/settings_per_account.xml146
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/avatar/avatarF.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/avatar/avatarSkinV.glsl4
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/avatar/avatarV.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/avatar/eyeballF.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/avatar/eyeballV.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl16
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/avatar/pickAvatarF.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/avatar/pickAvatarV.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl582
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/alphaNonIndexedF.glsl89
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/alphaNonIndexedNoColorF.glsl84
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/alphaSkinnedV.glsl144
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl166
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/deferred/attachmentShadowF.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/deferred/attachmentShadowV.glsl5
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/deferred/avatarAlphaNoColorV.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/avatarAlphaV.glsl153
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/deferred/avatarEyesV.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl12
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl4
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/deferred/avatarShadowV.glsl6
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/deferred/avatarV.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl50
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/deferred/blurLightV.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl8
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/deferred/bumpSkinnedV.glsl6
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl6
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/deferred/cloudsV.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/deferred/cofF.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl8
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl10
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl8
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl8
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl15
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/deferred/diffuseNoColorV.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/deferred/diffuseSkinnedV.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl2
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/deferred/dofCombineF.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/deferred/emissiveF.glsl2
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/deferred/emissiveV.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl138
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyF.glsl72
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyV.glsl67
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl13
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/deferred/fxaaF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/giF.glsl190
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl47
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/deferred/impostorV.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/deferred/luminanceV.glsl0
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/materialF.glsl788
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/materialV.glsl145
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl82
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/deferred/multiPointLightV.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl123
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/deferred/normgenF.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/deferred/normgenV.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl57
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/deferred/pointLightV.glsl10
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl0
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl67
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/deferred/postDeferredNoDoFF.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/deferred/postDeferredNoTCV.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/deferred/postDeferredV.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/deferred/postgiF.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskF.glsl24
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskV.glsl22
-rwxr-xr-xindra/newview/app_settings/shaders/class1/deferred/shadowCubeV.glsl50
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl5
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/deferred/shadowV.glsl8
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/deferred/skyF.glsl2
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/deferred/skyV.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl195
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/deferred/softenLightV.glsl2
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl222
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/srgb.glsl46
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/srgb_mac.glsl54
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/deferred/starsF.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/deferred/starsV.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/deferred/sunLightF.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/deferred/sunLightNoFragCoordV.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl19
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/deferred/sunLightV.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl8
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/deferred/treeF.glsl8
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/deferred/treeShadowF.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/deferred/treeShadowV.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/deferred/treeV.glsl0
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/underWaterF.glsl157
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/deferred/waterF.glsl73
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/deferred/waterV.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/effects/glowExtractF.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/effects/glowExtractV.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/effects/glowF.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/effects/glowV.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/environment/terrainF.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/environment/terrainV.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/environment/terrainWaterF.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/environment/waterF.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/environment/waterV.glsl13
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/interface/alphamaskF.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/interface/alphamaskV.glsl0
-rwxr-xr-xindra/newview/app_settings/shaders/class1/interface/clipF.glsl46
-rwxr-xr-xindra/newview/app_settings/shaders/class1/interface/clipV.glsl38
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/interface/customalphaF.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/interface/customalphaV.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/interface/debugF.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/interface/debugV.glsl0
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/downsampleDepthF.glsl65
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/downsampleDepthRectF.glsl67
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/downsampleDepthV.glsl59
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/interface/glowcombineF.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/interface/glowcombineFXAAF.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/interface/glowcombineFXAAV.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/interface/glowcombineV.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/interface/highlightF.glsl0
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/highlightNormV.glsl42
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/highlightSpecV.glsl42
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/interface/highlightV.glsl0
-rwxr-xr-xindra/newview/app_settings/shaders/class1/interface/occlusionCubeV.glsl38
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/interface/occlusionF.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/interface/occlusionV.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/interface/onetexturenocolorF.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/interface/onetexturenocolorV.glsl0
-rwxr-xr-xindra/newview/app_settings/shaders/class1/interface/pathfindingF.glsl37
-rwxr-xr-xindra/newview/app_settings/shaders/class1/interface/pathfindingNoNormalV.glsl42
-rwxr-xr-xindra/newview/app_settings/shaders/class1/interface/pathfindingV.glsl54
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/interface/solidcolorF.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/interface/solidcolorV.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/interface/splattexturerectF.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/interface/splattexturerectV.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/interface/twotextureaddF.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/interface/twotextureaddV.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/interface/uiF.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/interface/uiV.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskF.glsl4
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskNonIndexedF.glsl4
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/lighting/lightF.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/lighting/lightFullbrightAlphaMaskF.glsl6
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl6
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/lighting/lightFullbrightNonIndexedAlphaMaskF.glsl8
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/lighting/lightFullbrightNonIndexedF.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyF.glsl2
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyNonIndexedF.glsl2
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterF.glsl2
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterNonIndexedF.glsl2
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterAlphaMaskF.glsl6
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterF.glsl2
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterNonIndexedAlphaMaskF.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterNonIndexedF.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/lighting/lightFuncSpecularV.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/lighting/lightFuncV.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/lighting/lightNonIndexedF.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/lighting/lightShinyF.glsl2
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/lighting/lightShinyNonIndexedF.glsl2
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterF.glsl2
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterNonIndexedF.glsl2
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/lighting/lightSpecularV.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/lighting/lightV.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskF.glsl4
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskNonIndexedF.glsl4
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/lighting/lightWaterF.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/lighting/lightWaterNonIndexedF.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/lighting/sumLightsSpecularV.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/lighting/sumLightsV.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/objects/bumpF.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/objects/bumpV.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/objects/emissiveSkinnedV.glsl6
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/objects/emissiveV.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/objects/fullbrightF.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/objects/fullbrightNoColorV.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/objects/fullbrightShinyF.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/objects/fullbrightShinySkinnedV.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/objects/fullbrightShinyV.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/objects/fullbrightShinyWaterF.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/objects/fullbrightSkinnedV.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/objects/fullbrightV.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/objects/fullbrightWaterF.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/objects/impostorF.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/objects/impostorV.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/objects/indexedTextureF.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/objects/indexedTextureV.glsl4
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/objects/nonindexedTextureV.glsl0
-rwxr-xr-xindra/newview/app_settings/shaders/class1/objects/previewF.glsl41
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/objects/previewV.glsl57
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/objects/shinyF.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/objects/shinySimpleSkinnedV.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/objects/shinyV.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/objects/shinyWaterF.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/objects/simpleF.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/objects/simpleNoColorV.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/objects/simpleNonIndexedV.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/objects/simpleSkinnedV.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/objects/simpleTexGenV.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/objects/simpleV.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/objects/simpleWaterF.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/objects/treeV.glsl0
-rwxr-xr-xindra/newview/app_settings/shaders/class1/transform/binormalV.glsl36
-rwxr-xr-xindra/newview/app_settings/shaders/class1/transform/colorV.glsl36
-rwxr-xr-xindra/newview/app_settings/shaders/class1/transform/normalV.glsl36
-rwxr-xr-xindra/newview/app_settings/shaders/class1/transform/positionV.glsl40
-rwxr-xr-xindra/newview/app_settings/shaders/class1/transform/texcoordV.glsl35
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/windlight/atmosphericsF.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/windlight/atmosphericsHelpersV.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/windlight/atmosphericsV.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsF.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsV.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsWaterF.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsWaterV.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/windlight/gammaF.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class1/windlight/transportF.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class2/avatar/eyeballV.glsl0
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl166
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedF.glsl180
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedNoColorF.glsl178
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/alphaSkinnedV.glsl155
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl150
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/avatarAlphaV.glsl153
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl148
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl211
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class2/deferred/softenLightV.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl236
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl104
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl110
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class2/deferred/sunLightV.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class2/lighting/sumLightsSpecularV.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class2/lighting/sumLightsV.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class2/windlight/atmosphericsHelpersV.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class2/windlight/atmosphericsV.glsl2
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsF.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsV.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsWaterF.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsWaterV.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class2/windlight/cloudsV.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class2/windlight/gammaF.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class2/windlight/skyF.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class2/windlight/skyV.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class2/windlight/transportF.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class3/avatar/avatarV.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class3/lighting/sumLightsSpecularV.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/class3/lighting/sumLightsV.glsl0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/shaders/shader_hierarchy.txt0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/static_data.db2bin576578 -> 576578 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/static_index.db2bin9894 -> 9894 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/std_bump.ini0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/toolbars.xml1
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/trees.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/ultra_graphics.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/viewerart.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/windlight/clouds2.tgabin262935 -> 262935 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/windlight/days/Colder%20Tones.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/windlight/days/Default.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/windlight/days/Dynamic%20Richness.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/windlight/days/Pirate%27s%20Dream.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/windlight/days/Psycho%20Strobe%21.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/windlight/days/Tropicalia.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/windlight/days/Weird-O.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/windlight/postprocesseffects.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/windlight/skies/A%2D12AM.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/windlight/skies/A%2D12PM.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/windlight/skies/A%2D3AM.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/windlight/skies/A%2D3PM.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/windlight/skies/A%2D6AM.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/windlight/skies/A%2D6PM.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/windlight/skies/A%2D9AM.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/windlight/skies/A%2D9PM.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/windlight/skies/Barcelona.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/windlight/skies/Blizzard.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/windlight/skies/Blue%20Midday.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/windlight/skies/Coastal%20Afternoon.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/windlight/skies/Coastal%20Sunset.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/windlight/skies/Default.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/windlight/skies/Desert%20Sunset.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/windlight/skies/Fine%20Day.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/windlight/skies/Fluffy%20Big%20Clouds.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/windlight/skies/Foggy.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/windlight/skies/Funky%20Funky%20Funky.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/windlight/skies/Funky%20Funky.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/windlight/skies/Gelatto.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/windlight/skies/Ghost.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/windlight/skies/Incongruent%20Truths.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/windlight/skies/Midday%201.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/windlight/skies/Midday%202.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/windlight/skies/Midday%203.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/windlight/skies/Midday%204.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/windlight/skies/Midday.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/windlight/skies/Midnight.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/windlight/skies/Night.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/windlight/skies/Pirate.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/windlight/skies/Purple.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/windlight/skies/Sailor%27s%20Delight.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/windlight/skies/Sheer%20Surreality.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/windlight/skies/Sunrise.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/windlight/skies/Sunset.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/windlight/water/Default.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/windlight/water/Glassy.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/windlight/water/Murky.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/windlight/water/Pond.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/windlight/water/SNAKE%21%21%21.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/windlight/water/Second%20Plague.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/windlight/water/Valdez.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/build_win32_appConfig.py0
-rwxr-xr-x[-rw-r--r--]indra/newview/character/attentions.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/character/attentionsN.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/character/avatar_eye.llmbin16011 -> 16011 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/avatar_eye_1.llmbin5591 -> 5591 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/avatar_eyelashes.llmbin65637 -> 65637 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/avatar_hair.llmbin690581 -> 690581 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/avatar_hair_1.llmbin5031 -> 5031 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/avatar_hair_2.llmbin3261 -> 3261 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/avatar_hair_3.llmbin1845 -> 1845 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/avatar_hair_4.llmbin927 -> 927 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/avatar_hair_5.llmbin927 -> 927 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/avatar_head.llmbin1665493 -> 1665493 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/avatar_head_1.llmbin7875 -> 7875 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/avatar_head_2.llmbin3675 -> 3675 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/avatar_head_3.llmbin1797 -> 1797 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/avatar_head_4.llmbin1239 -> 1239 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/avatar_lad.xml27
-rwxr-xr-x[-rw-r--r--]indra/newview/character/avatar_lower_body.llmbin337125 -> 337125 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/avatar_lower_body_1.llmbin7083 -> 7083 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/avatar_lower_body_2.llmbin4107 -> 4107 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/avatar_lower_body_3.llmbin2115 -> 2115 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/avatar_lower_body_4.llmbin1629 -> 1629 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/avatar_skeleton.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/character/avatar_skirt.llmbin72497 -> 72497 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/avatar_skirt_1.llmbin1899 -> 1899 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/avatar_skirt_2.llmbin1551 -> 1551 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/avatar_skirt_3.llmbin1191 -> 1191 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/avatar_skirt_4.llmbin843 -> 843 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/avatar_upper_body.llmbin929297 -> 929297 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/avatar_upper_body_1.llmbin15627 -> 15627 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/avatar_upper_body_2.llmbin8991 -> 8991 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/avatar_upper_body_3.llmbin4557 -> 4557 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/avatar_upper_body_4.llmbin3453 -> 3453 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/blush_alpha.tgabin17352 -> 17352 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/body_skingrain.tgabin262188 -> 262188 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/bodyfreckles_alpha.tgabin257249 -> 257249 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/bump_face_wrinkles.tgabin25243 -> 25243 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/bump_head_base.tgabin105525 -> 105525 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/bump_lowerbody_base.tgabin112782 -> 112782 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/bump_pants_wrinkles.tgabin83183 -> 83183 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/bump_shirt_wrinkles.tgabin81501 -> 81501 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/bump_upperbody_base.tgabin147581 -> 147581 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/checkerboard.tgabin16428 -> 16428 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/eyebrows_alpha.tgabin9469 -> 9469 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/eyeliner_alpha.tgabin4720 -> 4720 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/eyeshadow_inner_alpha.tgabin5466 -> 5466 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/eyeshadow_outer_alpha.tgabin7382 -> 7382 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/eyewhite.tgabin42353 -> 42353 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/facehair_chincurtains_alpha.tgabin34610 -> 34610 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/facehair_moustache_alpha.tgabin14017 -> 14017 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/facehair_sideburns_alpha.tgabin27328 -> 27328 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/facehair_soulpatch_alpha.tgabin11277 -> 11277 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/freckles_alpha.tgabin140558 -> 140558 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/genepool.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/character/glove_length_alpha.tgabin49745 -> 49745 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/gloves_fingers_alpha.tgabin39616 -> 39616 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/head_alpha.tgabin6066 -> 6066 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/head_color.tgabin70715 -> 70715 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/head_hair.tgabin75600 -> 75600 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/head_highlights_alpha.tgabin20503 -> 20503 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/head_shading_alpha.tgabin35304 -> 35304 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/head_skingrain.tgabin262376 -> 262376 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/jacket_length_lower_alpha.tgabin9768 -> 9768 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/jacket_length_upper_alpha.tgabin14617 -> 14617 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/jacket_open_lower_alpha.tgabin19732 -> 19732 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/jacket_open_upper_alpha.tgabin41606 -> 41606 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/lipgloss_alpha.tgabin4738 -> 4738 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/lips_mask.tgabin6110 -> 6110 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/lipstick_alpha.tgabin7966 -> 7966 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/lowerbody_color.tgabin135395 -> 135395 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/lowerbody_highlights_alpha.tgabin8695 -> 8695 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/lowerbody_shading_alpha.tgabin41766 -> 41766 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/nailpolish_alpha.tgabin4656 -> 4656 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/pants_length_alpha.tgabin26843 -> 26843 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/pants_waist_alpha.tgabin10487 -> 10487 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/rosyface_alpha.tgabin44382 -> 44382 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/rouge_alpha.tgabin44382 -> 44382 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/shirt_bottom_alpha.tgabin32242 -> 32242 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/shirt_collar_alpha.tgabin14417 -> 14417 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/shirt_collar_back_alpha.tgabin12789 -> 12789 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/shirt_sleeve_alpha.tgabin72196 -> 72196 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/shoe_height_alpha.tgabin24461 -> 24461 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/skirt_length_alpha.tgabin4114 -> 4114 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/skirt_slit_back_alpha.tgabin90350 -> 90350 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/skirt_slit_front_alpha.tgabin90350 -> 90350 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/skirt_slit_left_alpha.tgabin82006 -> 82006 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/skirt_slit_right_alpha.tgabin91410 -> 91410 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/underpants_trial_female.tgabin48063 -> 48063 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/underpants_trial_male.tgabin144983 -> 144983 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/undershirt_trial_female.tgabin81390 -> 81390 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/upperbody_color.tgabin23348 -> 23348 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/upperbody_highlights_alpha.tgabin6509 -> 6509 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/upperbody_shading_alpha.tgabin25297 -> 25297 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/character/upperbodyfreckles_alpha.tgabin180104 -> 180104 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/cursors_mac/UI_CURSOR_ARROW.tifbin14336 -> 14336 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/cursors_mac/UI_CURSOR_ARROWDRAG.tifbin14368 -> 14368 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/cursors_mac/UI_CURSOR_ARROWLOCKED.tifbin14376 -> 14376 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/cursors_mac/UI_CURSOR_GRABLOCKED.tifbin14392 -> 14392 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/cursors_mac/UI_CURSOR_NO.tifbin14380 -> 14380 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/cursors_mac/UI_CURSOR_NOLOCKED.tifbin14416 -> 14416 bytes
-rwxr-xr-xindra/newview/cursors_mac/UI_CURSOR_PATHFINDING.tifbin0 -> 504 bytes
-rwxr-xr-xindra/newview/cursors_mac/UI_CURSOR_PATHFINDING_END.tifbin0 -> 556 bytes
-rwxr-xr-xindra/newview/cursors_mac/UI_CURSOR_PATHFINDING_END_ADD.tifbin0 -> 570 bytes
-rwxr-xr-xindra/newview/cursors_mac/UI_CURSOR_PATHFINDING_START.tifbin0 -> 532 bytes
-rwxr-xr-xindra/newview/cursors_mac/UI_CURSOR_PATHFINDING_START_ADD.tifbin0 -> 550 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/cursors_mac/UI_CURSOR_SIZENESW.tifbin14336 -> 14336 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/cursors_mac/UI_CURSOR_SIZENS.tifbin14344 -> 14344 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/cursors_mac/UI_CURSOR_SIZENWSE.tifbin14340 -> 14340 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/cursors_mac/UI_CURSOR_SIZEWE.tifbin14328 -> 14328 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/cursors_mac/UI_CURSOR_TOOLBUY.tifbin59044 -> 59044 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/cursors_mac/UI_CURSOR_TOOLCAMERA.tifbin14356 -> 14356 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/cursors_mac/UI_CURSOR_TOOLCREATE.tifbin14368 -> 14368 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/cursors_mac/UI_CURSOR_TOOLFOCUS.tifbin14348 -> 14348 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/cursors_mac/UI_CURSOR_TOOLGRAB.tifbin14364 -> 14364 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/cursors_mac/UI_CURSOR_TOOLLAND.tifbin14348 -> 14348 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/cursors_mac/UI_CURSOR_TOOLMEDIAOPEN.tifbin41228 -> 41228 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/cursors_mac/UI_CURSOR_TOOLOPEN.tifbin58560 -> 58560 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/cursors_mac/UI_CURSOR_TOOLPAN.tifbin14368 -> 14368 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/cursors_mac/UI_CURSOR_TOOLPAUSE.tifbin41224 -> 41224 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/cursors_mac/UI_CURSOR_TOOLPICKOBJECT3.tifbin14392 -> 14392 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/cursors_mac/UI_CURSOR_TOOLPLAY.tifbin41224 -> 41224 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/cursors_mac/UI_CURSOR_TOOLROTATE.tifbin14380 -> 14380 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/cursors_mac/UI_CURSOR_TOOLSCALE.tifbin14384 -> 14384 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/cursors_mac/UI_CURSOR_TOOLSIT.tifbin58464 -> 58464 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/cursors_mac/UI_CURSOR_TOOLTRANSLATE.tifbin14388 -> 14388 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/cursors_mac/UI_CURSOR_TOOLZOOMIN.tifbin14364 -> 14364 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/cursors_mac/UI_CURSOR_WORKING.tifbin14392 -> 14392 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/da.lproj/language.txt0
-rwxr-xr-x[-rw-r--r--]indra/newview/es.lproj/language.txt0
-rwxr-xr-x[-rw-r--r--]indra/newview/featuretable.txt169
-rwxr-xr-x[-rw-r--r--]indra/newview/featuretable_linux.txt172
-rwxr-xr-x[-rw-r--r--]indra/newview/featuretable_mac.txt172
-rwxr-xr-x[-rw-r--r--]indra/newview/featuretable_solaris.txt0
-rwxr-xr-x[-rw-r--r--]indra/newview/featuretable_xp.txt174
-rw-r--r--indra/newview/fmod_hidden_symbols.exp240
-rw-r--r--indra/newview/fmodwrapper.cpp37
-rwxr-xr-x[-rw-r--r--]indra/newview/fonts/DejaVu-license.txt0
-rwxr-xr-x[-rw-r--r--]indra/newview/fonts/DejaVuSans-Bold.ttfbin573136 -> 573136 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/fonts/DejaVuSans-BoldOblique.ttfbin524056 -> 524056 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/fonts/DejaVuSans-Oblique.ttfbin523804 -> 523804 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/fonts/DejaVuSans.ttfbin622280 -> 622280 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/fonts/DejaVuSansMono.ttfbin321524 -> 321524 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/fr.lproj/language.txt0
-rwxr-xr-x[-rw-r--r--]indra/newview/generate_breakpad_symbols.py51
-rwxr-xr-x[-rw-r--r--]indra/newview/gpu_table.txt1038
-rwxr-xr-x[-rw-r--r--]indra/newview/groupchatlistener.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/groupchatlistener.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/hu.lproj/language.txt0
-rwxr-xr-x[-rw-r--r--]indra/newview/icons/beta/secondlife.icnsbin242261 -> 242261 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/icons/beta/secondlife.icobin78692 -> 78692 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/icons/beta/secondlife_128.pngbin18268 -> 18268 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/icons/beta/secondlife_16.pngbin3536 -> 3536 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/icons/beta/secondlife_256.BMPbin196662 -> 196662 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/icons/beta/secondlife_256.pngbin49418 -> 49418 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/icons/beta/secondlife_32.pngbin4767 -> 4767 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/icons/beta/secondlife_48.pngbin6438 -> 6438 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/icons/beta/secondlife_512.pngbin151779 -> 151779 bytes
-rw-r--r--indra/newview/icons/development/secondlife.icnsbin233026 -> 0 bytes
-rw-r--r--indra/newview/icons/development/secondlife.icobin77117 -> 0 bytes
-rw-r--r--indra/newview/icons/development/secondlife_128.pngbin17499 -> 0 bytes
-rw-r--r--indra/newview/icons/development/secondlife_16.pngbin3471 -> 0 bytes
-rw-r--r--indra/newview/icons/development/secondlife_256.BMPbin196662 -> 0 bytes
-rw-r--r--indra/newview/icons/development/secondlife_256.pngbin47952 -> 0 bytes
-rw-r--r--indra/newview/icons/development/secondlife_32.pngbin4649 -> 0 bytes
-rw-r--r--indra/newview/icons/development/secondlife_48.pngbin6190 -> 0 bytes
-rw-r--r--indra/newview/icons/development/secondlife_512.pngbin147689 -> 0 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/icons/project/secondlife.icnsbin235133 -> 235133 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/icons/project/secondlife.icobin77791 -> 77791 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/icons/project/secondlife_128.pngbin17706 -> 17706 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/icons/project/secondlife_16.pngbin3471 -> 3471 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/icons/project/secondlife_256.BMPbin196662 -> 196662 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/icons/project/secondlife_256.pngbin48488 -> 48488 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/icons/project/secondlife_32.pngbin4675 -> 4675 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/icons/project/secondlife_48.pngbin6195 -> 6195 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/icons/project/secondlife_512.pngbin149145 -> 149145 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/icons/release/secondlife.icnsbin228390 -> 228390 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/icons/release/secondlife.icobin77552 -> 77552 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/icons/release/secondlife_128.pngbin17198 -> 17198 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/icons/release/secondlife_16.pngbin3524 -> 3524 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/icons/release/secondlife_256.BMPbin196662 -> 196662 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/icons/release/secondlife_256.pngbin47946 -> 47946 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/icons/release/secondlife_32.pngbin4746 -> 4746 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/icons/release/secondlife_48.pngbin6249 -> 6249 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/icons/release/secondlife_512.pngbin147963 -> 147963 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/icons/test/secondlife.icnsbin232905 -> 232905 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/icons/test/secondlife.icobin76861 -> 76861 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/icons/test/secondlife_128.pngbin17156 -> 17156 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/icons/test/secondlife_16.pngbin3471 -> 3471 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/icons/test/secondlife_256.BMPbin196662 -> 196662 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/icons/test/secondlife_256.pngbin47522 -> 47522 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/icons/test/secondlife_32.pngbin4644 -> 4644 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/icons/test/secondlife_48.pngbin6115 -> 6115 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/icons/test/secondlife_512.pngbin146971 -> 146971 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/installers/darwin/dmg-cleanup.applescript0
-rwxr-xr-x[-rw-r--r--]indra/newview/installers/darwin/fix_application_icon_position.sh0
-rwxr-xr-x[-rw-r--r--]indra/newview/installers/darwin/release-dmg/Applications-alias.r0
-rwxr-xr-x[-rw-r--r--]indra/newview/installers/darwin/release-dmg/_DS_Storebin12292 -> 12292 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/installers/darwin/release-dmg/_VolumeIcon.icnsbin98049 -> 98049 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/installers/darwin/release-dmg/background.jpgbin75112 -> 75112 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/installers/windows/FILES_ARE_UNICODE_UTF-16LE.txt0
-rwxr-xr-x[-rw-r--r--]indra/newview/installers/windows/install_icon.BMPbin262198 -> 262198 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/installers/windows/install_icon.icobin367958 -> 367958 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/installers/windows/installer_template.nsi0
-rwxr-xr-x[-rw-r--r--]indra/newview/installers/windows/lang_da.nsibin7108 -> 7108 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/installers/windows/lang_de.nsibin8260 -> 8260 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/installers/windows/lang_en-us.nsibin7542 -> 7542 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/installers/windows/lang_es.nsibin7846 -> 7846 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/installers/windows/lang_fr.nsibin8114 -> 8114 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/installers/windows/lang_it.nsibin7438 -> 7438 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/installers/windows/lang_ja.nsibin6302 -> 6302 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/installers/windows/lang_pl.nsibin7450 -> 7450 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/installers/windows/lang_pt-br.nsibin7832 -> 7832 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/installers/windows/lang_ru.nsibin7598 -> 7598 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/installers/windows/lang_tr.nsibin7722 -> 7722 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/installers/windows/lang_zh.nsibin5824 -> 5824 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/installers/windows/language_menu.nsibin1448 -> 1448 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/installers/windows/uninstall_icon.BMPbin262198 -> 262198 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/installers/windows/uninstall_icon.icobin367958 -> 367958 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/it.lproj/language.txt0
-rwxr-xr-x[-rw-r--r--]indra/newview/licenses-linux.txt0
-rwxr-xr-x[-rw-r--r--]indra/newview/licenses-mac.txt0
-rwxr-xr-x[-rw-r--r--]indra/newview/licenses-solaris.txt0
-rwxr-xr-x[-rw-r--r--]indra/newview/licenses-win32.txt0
-rwxr-xr-x[-rw-r--r--]indra/newview/linux_tools/client-readme-joystick.txt0
-rwxr-xr-x[-rw-r--r--]indra/newview/linux_tools/client-readme-voice.txt0
-rwxr-xr-x[-rw-r--r--]indra/newview/linux_tools/client-readme.txt0
-rwxr-xr-xindra/newview/linux_tools/wrapper.sh65
-rwxr-xr-x[-rw-r--r--]indra/newview/llaccountingcostmanager.cpp4
-rwxr-xr-x[-rw-r--r--]indra/newview/llaccountingcostmanager.h0
-rwxr-xr-xindra/newview/llagent.cpp1001
-rwxr-xr-x[-rw-r--r--]indra/newview/llagent.h103
-rwxr-xr-x[-rw-r--r--]indra/newview/llagentaccess.cpp25
-rwxr-xr-x[-rw-r--r--]indra/newview/llagentaccess.h10
-rwxr-xr-x[-rw-r--r--]indra/newview/llagentcamera.cpp42
-rwxr-xr-x[-rw-r--r--]indra/newview/llagentcamera.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llagentdata.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llagentdata.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llagentlanguage.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llagentlanguage.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llagentlistener.cpp11
-rwxr-xr-x[-rw-r--r--]indra/newview/llagentlistener.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llagentpicksinfo.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llagentpicksinfo.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llagentpilot.cpp2
-rwxr-xr-x[-rw-r--r--]indra/newview/llagentpilot.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llagentui.cpp10
-rwxr-xr-x[-rw-r--r--]indra/newview/llagentui.h1
-rwxr-xr-x[-rw-r--r--]indra/newview/llagentwearables.cpp486
-rwxr-xr-x[-rw-r--r--]indra/newview/llagentwearables.h75
-rwxr-xr-x[-rw-r--r--]indra/newview/llagentwearablesfetch.cpp17
-rwxr-xr-x[-rw-r--r--]indra/newview/llagentwearablesfetch.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llanimstatelabels.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llanimstatelabels.h0
-rwxr-xr-xindra/newview/llappcorehttp.cpp192
-rwxr-xr-xindra/newview/llappcorehttp.h86
-rw-r--r--indra/newview/llappdelegate-objc.mm157
-rwxr-xr-x[-rw-r--r--]indra/newview/llappearance.h8
-rwxr-xr-x[-rw-r--r--]indra/newview/llappearancemgr.cpp1386
-rwxr-xr-x[-rw-r--r--]indra/newview/llappearancemgr.h48
-rwxr-xr-x[-rw-r--r--]indra/newview/llappviewer.cpp1465
-rwxr-xr-x[-rw-r--r--]indra/newview/llappviewer.h38
-rwxr-xr-x[-rw-r--r--]indra/newview/llappviewerlinux.cpp9
-rwxr-xr-x[-rw-r--r--]indra/newview/llappviewerlinux.h2
-rwxr-xr-x[-rw-r--r--]indra/newview/llappviewerlinux_api.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llappviewerlinux_api.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/llappviewerlinux_api_dbus.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llappviewerlinux_api_dbus.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llappviewerlinux_api_dbus_syms_raw.inc0
-rwxr-xr-x[-rw-r--r--]indra/newview/llappviewerlistener.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llappviewerlistener.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llappviewermacosx.cpp305
-rwxr-xr-x[-rw-r--r--]indra/newview/llappviewermacosx.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llappviewerwin32.cpp138
-rwxr-xr-x[-rw-r--r--]indra/newview/llappviewerwin32.h2
-rwxr-xr-x[-rw-r--r--]indra/newview/llassetuploadqueue.cpp7
-rwxr-xr-x[-rw-r--r--]indra/newview/llassetuploadqueue.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llassetuploadresponders.cpp33
-rwxr-xr-x[-rw-r--r--]indra/newview/llassetuploadresponders.h6
-rwxr-xr-x[-rw-r--r--]indra/newview/llattachmentsmgr.cpp6
-rwxr-xr-x[-rw-r--r--]indra/newview/llattachmentsmgr.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llaudiosourcevo.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llaudiosourcevo.h0
-rwxr-xr-xindra/newview/llautoreplace.cpp802
-rwxr-xr-xindra/newview/llautoreplace.h227
-rwxr-xr-xindra/newview/llavataractions.cpp295
-rwxr-xr-x[-rw-r--r--]indra/newview/llavataractions.h49
-rwxr-xr-xindra/newview/llavatariconctrl.cpp39
-rwxr-xr-x[-rw-r--r--]indra/newview/llavatariconctrl.h20
-rwxr-xr-x[-rw-r--r--]indra/newview/llavatarlist.cpp61
-rwxr-xr-x[-rw-r--r--]indra/newview/llavatarlist.h3
-rwxr-xr-x[-rw-r--r--]indra/newview/llavatarlistitem.cpp51
-rwxr-xr-x[-rw-r--r--]indra/newview/llavatarlistitem.h6
-rwxr-xr-x[-rw-r--r--]indra/newview/llavatarpropertiesprocessor.cpp9
-rwxr-xr-x[-rw-r--r--]indra/newview/llavatarpropertiesprocessor.h0
-rw-r--r--indra/newview/llavatarrenderinfoaccountant.cpp398
-rw-r--r--indra/newview/llavatarrenderinfoaccountant.h56
-rwxr-xr-xindra/newview/llblockedlistitem.cpp114
-rwxr-xr-xindra/newview/llblockedlistitem.h73
-rwxr-xr-xindra/newview/llblocklist.cpp362
-rwxr-xr-xindra/newview/llblocklist.h155
-rwxr-xr-x[-rw-r--r--]indra/newview/llbox.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llbox.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llbreadcrumbview.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llbreadcrumbview.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llbreastmotion.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llbreastmotion.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llbrowsernotification.cpp8
-rwxr-xr-x[-rw-r--r--]indra/newview/llbuycurrencyhtml.cpp4
-rwxr-xr-x[-rw-r--r--]indra/newview/llbuycurrencyhtml.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llcallbacklist.cpp49
-rwxr-xr-x[-rw-r--r--]indra/newview/llcallbacklist.h6
-rw-r--r--indra/newview/llcallfloater.cpp821
-rw-r--r--indra/newview/llcallfloater.h273
-rwxr-xr-x[-rw-r--r--]indra/newview/llcallingcard.cpp19
-rwxr-xr-x[-rw-r--r--]indra/newview/llcallingcard.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llcapabilitylistener.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llcapabilitylistener.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llcapabilityprovider.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llcaphttpsender.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llcaphttpsender.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llchannelmanager.cpp4
-rwxr-xr-x[-rw-r--r--]indra/newview/llchannelmanager.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llchatbar.cpp46
-rwxr-xr-x[-rw-r--r--]indra/newview/llchatbar.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llchathistory.cpp424
-rwxr-xr-x[-rw-r--r--]indra/newview/llchathistory.h8
-rwxr-xr-x[-rw-r--r--]indra/newview/llchatitemscontainerctrl.cpp53
-rwxr-xr-x[-rw-r--r--]indra/newview/llchatitemscontainerctrl.h8
-rwxr-xr-x[-rw-r--r--]indra/newview/llchatmsgbox.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llchatmsgbox.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llchiclet.cpp942
-rwxr-xr-x[-rw-r--r--]indra/newview/llchiclet.h457
-rwxr-xr-x[-rw-r--r--]indra/newview/llchicletbar.cpp101
-rwxr-xr-x[-rw-r--r--]indra/newview/llchicletbar.h14
-rwxr-xr-x[-rw-r--r--]indra/newview/llclassifiedinfo.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llclassifiedinfo.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llclassifiedstatsresponder.cpp5
-rwxr-xr-x[-rw-r--r--]indra/newview/llclassifiedstatsresponder.h2
-rwxr-xr-x[-rw-r--r--]indra/newview/llcofwearables.cpp6
-rwxr-xr-x[-rw-r--r--]indra/newview/llcofwearables.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llcolorswatch.cpp4
-rwxr-xr-x[-rw-r--r--]indra/newview/llcolorswatch.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llcommanddispatcherlistener.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llcommanddispatcherlistener.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llcommandhandler.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llcommandlineparser.cpp207
-rwxr-xr-x[-rw-r--r--]indra/newview/llcommandlineparser.h2
-rwxr-xr-xindra/newview/llcommunicationchannel.cpp113
-rwxr-xr-xindra/newview/llcommunicationchannel.h66
-rwxr-xr-x[-rw-r--r--]indra/newview/llcompilequeue.cpp12
-rwxr-xr-x[-rw-r--r--]indra/newview/llcompilequeue.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llconfirmationmanager.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llconfirmationmanager.h0
-rwxr-xr-xindra/newview/llconversationlog.cpp615
-rwxr-xr-xindra/newview/llconversationlog.h216
-rwxr-xr-xindra/newview/llconversationloglist.cpp537
-rwxr-xr-xindra/newview/llconversationloglist.h153
-rwxr-xr-xindra/newview/llconversationloglistitem.cpp184
-rwxr-xr-xindra/newview/llconversationloglistitem.h86
-rwxr-xr-xindra/newview/llconversationmodel.cpp710
-rw-r--r--indra/newview/llconversationmodel.h313
-rw-r--r--indra/newview/llconversationview.cpp749
-rw-r--r--indra/newview/llconversationview.h181
-rwxr-xr-x[-rw-r--r--]indra/newview/llcurrencyuimanager.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llcurrencyuimanager.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llcylinder.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llcylinder.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/lldateutil.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/lldateutil.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/lldaycyclemanager.cpp2
-rwxr-xr-x[-rw-r--r--]indra/newview/lldaycyclemanager.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/lldebugmessagebox.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/lldebugmessagebox.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/lldebugview.cpp37
-rwxr-xr-x[-rw-r--r--]indra/newview/lldebugview.h0
-rwxr-xr-xindra/newview/lldeferredsounds.cpp45
-rwxr-xr-xindra/newview/lldeferredsounds.h46
-rwxr-xr-x[-rw-r--r--]indra/newview/lldelayedgestureerror.cpp8
-rwxr-xr-x[-rw-r--r--]indra/newview/lldelayedgestureerror.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/lldirpicker.cpp146
-rwxr-xr-x[-rw-r--r--]indra/newview/lldirpicker.h11
-rwxr-xr-x[-rw-r--r--]indra/newview/lldndbutton.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/lldndbutton.h0
-rwxr-xr-xindra/newview/lldonotdisturbnotificationstorage.cpp343
-rwxr-xr-xindra/newview/lldonotdisturbnotificationstorage.h78
-rwxr-xr-x[-rw-r--r--]indra/newview/lldrawable.cpp268
-rwxr-xr-x[-rw-r--r--]indra/newview/lldrawable.h38
-rwxr-xr-x[-rw-r--r--]indra/newview/lldrawpool.cpp79
-rwxr-xr-x[-rw-r--r--]indra/newview/lldrawpool.h28
-rwxr-xr-x[-rw-r--r--]indra/newview/lldrawpoolalpha.cpp279
-rwxr-xr-x[-rw-r--r--]indra/newview/lldrawpoolalpha.h9
-rwxr-xr-x[-rw-r--r--]indra/newview/lldrawpoolavatar.cpp551
-rwxr-xr-x[-rw-r--r--]indra/newview/lldrawpoolavatar.h73
-rwxr-xr-x[-rw-r--r--]indra/newview/lldrawpoolbump.cpp56
-rwxr-xr-x[-rw-r--r--]indra/newview/lldrawpoolbump.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/lldrawpoolground.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/lldrawpoolground.h0
-rw-r--r--indra/newview/lldrawpoolmaterials.cpp224
-rw-r--r--indra/newview/lldrawpoolmaterials.h75
-rwxr-xr-x[-rw-r--r--]indra/newview/lldrawpoolsimple.cpp308
-rwxr-xr-x[-rw-r--r--]indra/newview/lldrawpoolsimple.h53
-rwxr-xr-x[-rw-r--r--]indra/newview/lldrawpoolsky.cpp1
-rwxr-xr-x[-rw-r--r--]indra/newview/lldrawpoolsky.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/lldrawpoolterrain.cpp52
-rwxr-xr-x[-rw-r--r--]indra/newview/lldrawpoolterrain.h1
-rwxr-xr-x[-rw-r--r--]indra/newview/lldrawpooltree.cpp16
-rwxr-xr-x[-rw-r--r--]indra/newview/lldrawpooltree.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/lldrawpoolwater.cpp81
-rwxr-xr-x[-rw-r--r--]indra/newview/lldrawpoolwater.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/lldrawpoolwlsky.cpp17
-rwxr-xr-x[-rw-r--r--]indra/newview/lldrawpoolwlsky.h0
-rw-r--r--indra/newview/lldriverparam.cpp634
-rw-r--r--indra/newview/lldriverparam.h128
-rwxr-xr-x[-rw-r--r--]indra/newview/lldynamictexture.cpp6
-rwxr-xr-x[-rw-r--r--]indra/newview/lldynamictexture.h16
-rwxr-xr-x[-rw-r--r--]indra/newview/llemote.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llemote.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llenvmanager.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llenvmanager.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llestateinfomodel.cpp28
-rwxr-xr-x[-rw-r--r--]indra/newview/llestateinfomodel.h25
-rwxr-xr-x[-rw-r--r--]indra/newview/lleventnotifier.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/lleventnotifier.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/lleventpoll.cpp12
-rwxr-xr-x[-rw-r--r--]indra/newview/lleventpoll.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llexpandabletextbox.cpp4
-rwxr-xr-x[-rw-r--r--]indra/newview/llexpandabletextbox.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llexternaleditor.cpp73
-rwxr-xr-x[-rw-r--r--]indra/newview/llexternaleditor.h6
-rwxr-xr-x[-rw-r--r--]indra/newview/llface.cpp1853
-rwxr-xr-x[-rw-r--r--]indra/newview/llface.h65
-rwxr-xr-x[-rw-r--r--]indra/newview/llface.inl0
-rw-r--r--indra/newview/llfacebookconnect.cpp582
-rw-r--r--indra/newview/llfacebookconnect.h106
-rwxr-xr-x[-rw-r--r--]indra/newview/llfasttimerview.cpp57
-rwxr-xr-x[-rw-r--r--]indra/newview/llfasttimerview.h4
-rwxr-xr-x[-rw-r--r--]indra/newview/llfavoritesbar.cpp331
-rwxr-xr-x[-rw-r--r--]indra/newview/llfavoritesbar.h113
-rwxr-xr-x[-rw-r--r--]indra/newview/llfeaturemanager.cpp261
-rwxr-xr-x[-rw-r--r--]indra/newview/llfeaturemanager.h38
-rwxr-xr-x[-rw-r--r--]indra/newview/llfilepicker.cpp593
-rwxr-xr-x[-rw-r--r--]indra/newview/llfilepicker.h16
-rw-r--r--indra/newview/llfilepicker_mac.h58
-rw-r--r--indra/newview/llfilepicker_mac.mm133
-rwxr-xr-x[-rw-r--r--]indra/newview/llfilteredwearablelist.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfilteredwearablelist.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfirstuse.cpp2
-rwxr-xr-x[-rw-r--r--]indra/newview/llfirstuse.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llflexibleobject.cpp253
-rwxr-xr-x[-rw-r--r--]indra/newview/llflexibleobject.h15
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterabout.cpp12
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterabout.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterauction.cpp1
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterauction.h0
-rwxr-xr-xindra/newview/llfloaterautoreplacesettings.cpp665
-rwxr-xr-xindra/newview/llfloaterautoreplacesettings.h117
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloateravatar.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloateravatar.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloateravatarpicker.cpp258
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloateravatarpicker.h17
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloateravatartextures.cpp15
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloateravatartextures.h4
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterbeacons.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterbeacons.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterbuildoptions.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterbuildoptions.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterbulkpermission.cpp38
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterbulkpermission.h16
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterbump.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterbump.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterbuy.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterbuy.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterbuycontents.cpp23
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterbuycontents.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterbuycurrency.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterbuycurrency.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterbuycurrencyhtml.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterbuycurrencyhtml.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterbuyland.cpp4
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterbuyland.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterbvhpreview.cpp59
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterbvhpreview.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloatercamera.cpp4
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloatercamera.h0
-rwxr-xr-xindra/newview/llfloaterchatvoicevolume.cpp44
-rwxr-xr-xindra/newview/llfloaterchatvoicevolume.h44
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloatercolorpicker.cpp38
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloatercolorpicker.h4
-rwxr-xr-xindra/newview/llfloaterconversationlog.cpp134
-rwxr-xr-xindra/newview/llfloaterconversationlog.h56
-rwxr-xr-xindra/newview/llfloaterconversationpreview.cpp204
-rwxr-xr-xindra/newview/llfloaterconversationpreview.h68
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterdeleteenvpreset.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterdeleteenvpreset.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterdestinations.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterdestinations.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterdisplayname.cpp20
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterdisplayname.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloatereditdaycycle.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloatereditdaycycle.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloatereditsky.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloatereditsky.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloatereditwater.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloatereditwater.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterenvironmentsettings.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterenvironmentsettings.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterevent.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterevent.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterfonttest.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterfonttest.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloatergesture.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloatergesture.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloatergodtools.cpp46
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloatergodtools.h14
-rw-r--r--indra/newview/llfloatergotoline.cpp160
-rw-r--r--indra/newview/llfloatergotoline.h66
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloatergroupinvite.cpp8
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloatergroupinvite.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloatergroups.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloatergroups.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterhandler.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterhandler.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterhardwaresettings.cpp23
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterhardwaresettings.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterhelpbrowser.cpp10
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterhelpbrowser.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterhud.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterhud.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterimagepreview.cpp22
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterimagepreview.h0
-rwxr-xr-xindra/newview/llfloaterimcontainer.cpp2219
-rwxr-xr-xindra/newview/llfloaterimcontainer.h225
-rwxr-xr-xindra/newview/llfloaterimnearbychat.cpp894
-rwxr-xr-xindra/newview/llfloaterimnearbychat.h119
-rwxr-xr-xindra/newview/llfloaterimnearbychathandler.cpp649
-rwxr-xr-xindra/newview/llfloaterimnearbychathandler.h54
-rwxr-xr-xindra/newview/llfloaterimnearbychatlistener.cpp100
-rwxr-xr-xindra/newview/llfloaterimnearbychatlistener.h50
-rwxr-xr-xindra/newview/llfloaterimsession.cpp1303
-rwxr-xr-xindra/newview/llfloaterimsession.h201
-rwxr-xr-xindra/newview/llfloaterimsessiontab.cpp1115
-rwxr-xr-xindra/newview/llfloaterimsessiontab.h220
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterinspect.cpp46
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterinspect.h8
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterinventory.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterinventory.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterjoystick.cpp4
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterjoystick.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterlagmeter.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterlagmeter.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterland.cpp139
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterland.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterlandholdings.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterlandholdings.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloatermap.cpp18
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloatermap.h1
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloatermediasettings.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloatermediasettings.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloatermemleak.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloatermemleak.h0
-rwxr-xr-xindra/newview/llfloatermodelpreview.cpp226
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloatermodelpreview.h14
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloatermodeluploadbase.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloatermodeluploadbase.h0
-rw-r--r--indra/newview/llfloatermodelwizard.cpp795
-rw-r--r--indra/newview/llfloatermodelwizard.h140
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaternamedesc.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaternamedesc.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaternotificationsconsole.cpp38
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaternotificationsconsole.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterobjectweights.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterobjectweights.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloateropenobject.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloateropenobject.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloateroutbox.cpp84
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloateroutbox.h2
-rwxr-xr-xindra/newview/llfloaterpathfindingcharacters.cpp326
-rwxr-xr-xindra/newview/llfloaterpathfindingcharacters.h99
-rwxr-xr-xindra/newview/llfloaterpathfindingconsole.cpp1273
-rwxr-xr-xindra/newview/llfloaterpathfindingconsole.h220
-rwxr-xr-xindra/newview/llfloaterpathfindinglinksets.cpp804
-rwxr-xr-xindra/newview/llfloaterpathfindinglinksets.h142
-rwxr-xr-xindra/newview/llfloaterpathfindingobjects.cpp884
-rwxr-xr-xindra/newview/llfloaterpathfindingobjects.h179
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterpay.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterpay.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterperms.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterperms.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterpostprocess.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterpostprocess.h0
-rwxr-xr-xindra/newview/llfloaterpreference.cpp446
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterpreference.h44
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterproperties.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterproperties.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterregiondebugconsole.cpp2
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterregiondebugconsole.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterregioninfo.cpp255
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterregioninfo.h4
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterreporter.cpp39
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterreporter.h1
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterscriptdebug.cpp2
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterscriptdebug.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterscriptlimits.cpp31
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterscriptlimits.h8
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloatersearch.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloatersearch.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloatersellland.cpp22
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloatersellland.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloatersettingsdebug.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloatersettingsdebug.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloatersidepanelcontainer.cpp31
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloatersidepanelcontainer.h2
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloatersnapshot.cpp1004
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloatersnapshot.h1
-rw-r--r--indra/newview/llfloatersocial.cpp920
-rw-r--r--indra/newview/llfloatersocial.h165
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloatersounddevices.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloatersounddevices.h0
-rwxr-xr-xindra/newview/llfloaterspellchecksettings.cpp491
-rwxr-xr-xindra/newview/llfloaterspellchecksettings.h68
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloatertelehub.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloatertelehub.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloatertestinspectors.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloatertestinspectors.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloatertestlistview.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloatertestlistview.h0
-rwxr-xr-xindra/newview/llfloatertexturefetchdebugger.cpp472
-rwxr-xr-xindra/newview/llfloatertexturefetchdebugger.h76
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloatertools.cpp45
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloatertools.h4
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloatertopobjects.cpp106
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloatertopobjects.h4
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloatertos.cpp6
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloatertos.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloatertoybox.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloatertoybox.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloatertranslationsettings.cpp23
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloatertranslationsettings.h1
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloateruipreview.cpp121
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloateruipreview.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterurlentry.cpp3
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterurlentry.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloatervoiceeffect.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloatervoiceeffect.h0
-rwxr-xr-xindra/newview/llfloatervoicevolume.cpp220
-rwxr-xr-xindra/newview/llfloatervoicevolume.h35
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterwebcontent.cpp90
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterwebcontent.h7
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterwebprofile.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterwebprofile.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterwhitelistentry.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterwhitelistentry.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterwindowsize.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterwindowsize.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterworldmap.h0
-rw-r--r--indra/newview/llfolderview.cpp2624
-rw-r--r--indra/newview/llfolderview.h375
-rw-r--r--indra/newview/llfoldervieweventlistener.h103
-rw-r--r--indra/newview/llfolderviewitem.cpp2906
-rw-r--r--indra/newview/llfolderviewitem.h576
-rwxr-xr-xindra/newview/llfolderviewmodelinventory.cpp323
-rwxr-xr-xindra/newview/llfolderviewmodelinventory.h117
-rwxr-xr-x[-rw-r--r--]indra/newview/llfollowcam.cpp1
-rwxr-xr-x[-rw-r--r--]indra/newview/llfollowcam.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llfriendcard.cpp8
-rwxr-xr-x[-rw-r--r--]indra/newview/llfriendcard.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llgesturelistener.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llgesturelistener.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llgesturemgr.cpp10
-rwxr-xr-x[-rw-r--r--]indra/newview/llgesturemgr.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llgiveinventory.cpp68
-rwxr-xr-x[-rw-r--r--]indra/newview/llgiveinventory.h7
-rwxr-xr-x[-rw-r--r--]indra/newview/llglsandbox.cpp8
-rwxr-xr-x[-rw-r--r--]indra/newview/llgroupactions.cpp129
-rwxr-xr-x[-rw-r--r--]indra/newview/llgroupactions.h8
-rwxr-xr-x[-rw-r--r--]indra/newview/llgroupiconctrl.cpp3
-rwxr-xr-x[-rw-r--r--]indra/newview/llgroupiconctrl.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llgrouplist.cpp6
-rwxr-xr-x[-rw-r--r--]indra/newview/llgrouplist.h13
-rwxr-xr-x[-rw-r--r--]indra/newview/llgroupmgr.cpp254
-rwxr-xr-x[-rw-r--r--]indra/newview/llgroupmgr.h17
-rw-r--r--indra/newview/llhasheduniqueid.cpp55
-rw-r--r--indra/newview/llhasheduniqueid.h34
-rwxr-xr-x[-rw-r--r--]indra/newview/llhints.cpp4
-rwxr-xr-x[-rw-r--r--]indra/newview/llhints.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llhomelocationresponder.cpp4
-rwxr-xr-x[-rw-r--r--]indra/newview/llhomelocationresponder.h2
-rwxr-xr-x[-rw-r--r--]indra/newview/llhudeffect.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llhudeffect.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llhudeffectbeam.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llhudeffectbeam.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llhudeffectblob.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llhudeffectblob.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llhudeffectlookat.cpp2
-rwxr-xr-x[-rw-r--r--]indra/newview/llhudeffectlookat.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llhudeffectpointat.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llhudeffectpointat.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llhudeffecttrail.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llhudeffecttrail.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llhudicon.cpp21
-rwxr-xr-x[-rw-r--r--]indra/newview/llhudicon.h4
-rwxr-xr-x[-rw-r--r--]indra/newview/llhudmanager.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llhudmanager.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llhudnametag.cpp290
-rwxr-xr-x[-rw-r--r--]indra/newview/llhudnametag.h4
-rwxr-xr-x[-rw-r--r--]indra/newview/llhudobject.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llhudobject.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llhudrender.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llhudrender.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llhudtext.cpp5
-rwxr-xr-x[-rw-r--r--]indra/newview/llhudtext.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llhudview.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llhudview.h0
-rw-r--r--indra/newview/llimfloater.cpp1193
-rw-r--r--indra/newview/llimfloater.h182
-rw-r--r--indra/newview/llimfloatercontainer.cpp164
-rw-r--r--indra/newview/llimfloatercontainer.h70
-rwxr-xr-x[-rw-r--r--]indra/newview/llimhandler.cpp118
-rwxr-xr-x[-rw-r--r--]indra/newview/llimpanel.cpp7
-rwxr-xr-x[-rw-r--r--]indra/newview/llimpanel.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llimview.cpp656
-rwxr-xr-x[-rw-r--r--]indra/newview/llimview.h66
-rwxr-xr-x[-rw-r--r--]indra/newview/llinspect.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llinspect.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llinspectavatar.cpp516
-rwxr-xr-x[-rw-r--r--]indra/newview/llinspectavatar.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llinspectgroup.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llinspectgroup.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llinspectobject.cpp9
-rwxr-xr-x[-rw-r--r--]indra/newview/llinspectobject.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llinspectremoteobject.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llinspectremoteobject.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llinspecttoast.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llinspecttoast.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llinventoryactions.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llinventorybridge.cpp917
-rwxr-xr-x[-rw-r--r--]indra/newview/llinventorybridge.h116
-rwxr-xr-x[-rw-r--r--]indra/newview/llinventoryclipboard.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llinventoryclipboard.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llinventoryfilter.cpp425
-rwxr-xr-x[-rw-r--r--]indra/newview/llinventoryfilter.h199
-rwxr-xr-x[-rw-r--r--]indra/newview/llinventoryfunctions.cpp186
-rwxr-xr-x[-rw-r--r--]indra/newview/llinventoryfunctions.h59
-rwxr-xr-x[-rw-r--r--]indra/newview/llinventoryicon.cpp122
-rwxr-xr-x[-rw-r--r--]indra/newview/llinventoryicon.h54
-rwxr-xr-x[-rw-r--r--]indra/newview/llinventoryitemslist.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llinventoryitemslist.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llinventorylistitem.cpp3
-rwxr-xr-x[-rw-r--r--]indra/newview/llinventorylistitem.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llinventorymodel.cpp161
-rwxr-xr-x[-rw-r--r--]indra/newview/llinventorymodel.h13
-rwxr-xr-x[-rw-r--r--]indra/newview/llinventorymodelbackgroundfetch.cpp20
-rwxr-xr-x[-rw-r--r--]indra/newview/llinventorymodelbackgroundfetch.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llinventoryobserver.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llinventoryobserver.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llinventorypanel.cpp656
-rwxr-xr-x[-rw-r--r--]indra/newview/llinventorypanel.h120
-rwxr-xr-x[-rw-r--r--]indra/newview/lljoystickbutton.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/lljoystickbutton.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/lllandmarkactions.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/lllandmarkactions.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/lllandmarklist.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/lllandmarklist.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/lllightconstants.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/lllistbrowser.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/lllistbrowser.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/lllistcontextmenu.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/lllistcontextmenu.h2
-rwxr-xr-x[-rw-r--r--]indra/newview/lllistview.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/lllistview.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/lllocalbitmaps.cpp175
-rwxr-xr-x[-rw-r--r--]indra/newview/lllocalbitmaps.h11
-rw-r--r--indra/newview/lllocaltextureobject.cpp212
-rw-r--r--indra/newview/lllocaltextureobject.h87
-rwxr-xr-x[-rw-r--r--]indra/newview/lllocationhistory.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/lllocationhistory.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/lllocationinputctrl.cpp76
-rwxr-xr-x[-rw-r--r--]indra/newview/lllocationinputctrl.h30
-rwxr-xr-x[-rw-r--r--]indra/newview/lllogchat.cpp696
-rwxr-xr-x[-rw-r--r--]indra/newview/lllogchat.h57
-rwxr-xr-x[-rw-r--r--]indra/newview/llloginhandler.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llloginhandler.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/lllogininstance.cpp92
-rwxr-xr-x[-rw-r--r--]indra/newview/lllogininstance.h5
-rwxr-xr-x[-rw-r--r--]indra/newview/lllookshistorypanel.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llmachineid.cpp18
-rwxr-xr-x[-rw-r--r--]indra/newview/llmachineid.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llmainlooprepeater.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llmainlooprepeater.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llmanip.cpp11
-rwxr-xr-x[-rw-r--r--]indra/newview/llmanip.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llmaniprotate.cpp257
-rwxr-xr-x[-rw-r--r--]indra/newview/llmaniprotate.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llmanipscale.cpp35
-rwxr-xr-x[-rw-r--r--]indra/newview/llmanipscale.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llmaniptranslate.cpp66
-rwxr-xr-x[-rw-r--r--]indra/newview/llmaniptranslate.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llmarketplacefunctions.cpp16
-rwxr-xr-x[-rw-r--r--]indra/newview/llmarketplacefunctions.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llmarketplacenotifications.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llmarketplacenotifications.h0
-rw-r--r--indra/newview/llmaterialmgr.cpp789
-rw-r--r--indra/newview/llmaterialmgr.h132
-rwxr-xr-x[-rw-r--r--]indra/newview/llmediactrl.cpp48
-rwxr-xr-x[-rw-r--r--]indra/newview/llmediactrl.h1
-rwxr-xr-x[-rw-r--r--]indra/newview/llmediadataclient.cpp10
-rwxr-xr-x[-rw-r--r--]indra/newview/llmediadataclient.h4
-rw-r--r--indra/newview/llmemoryview.cpp333
-rw-r--r--indra/newview/llmemoryview.h62
-rwxr-xr-xindra/newview/llmenuoptionpathfindingrebakenavmesh.cpp245
-rwxr-xr-xindra/newview/llmenuoptionpathfindingrebakenavmesh.h85
-rwxr-xr-xindra/newview/llmeshrepository.cpp241
-rwxr-xr-x[-rw-r--r--]indra/newview/llmeshrepository.h9
-rwxr-xr-x[-rw-r--r--]indra/newview/llmimetypes.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llmimetypes.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llmorphview.cpp2
-rwxr-xr-x[-rw-r--r--]indra/newview/llmorphview.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llmoveview.cpp17
-rwxr-xr-x[-rw-r--r--]indra/newview/llmoveview.h2
-rwxr-xr-x[-rw-r--r--]indra/newview/llmutelist.cpp42
-rwxr-xr-x[-rw-r--r--]indra/newview/llmutelist.h2
-rwxr-xr-x[-rw-r--r--]indra/newview/llnamebox.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llnamebox.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llnameeditor.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llnameeditor.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llnamelistctrl.cpp73
-rwxr-xr-x[-rw-r--r--]indra/newview/llnamelistctrl.h68
-rwxr-xr-x[-rw-r--r--]indra/newview/llnavigationbar.cpp9
-rwxr-xr-x[-rw-r--r--]indra/newview/llnavigationbar.h1
-rw-r--r--indra/newview/llnearbychat.cpp338
-rw-r--r--indra/newview/llnearbychat.h83
-rw-r--r--indra/newview/llnearbychatbar.cpp672
-rw-r--r--indra/newview/llnearbychatbar.h97
-rw-r--r--indra/newview/llnearbychatbarlistener.cpp100
-rw-r--r--indra/newview/llnearbychatbarlistener.h50
-rw-r--r--indra/newview/llnearbychathandler.cpp635
-rw-r--r--indra/newview/llnearbychathandler.h55
-rwxr-xr-x[-rw-r--r--]indra/newview/llnetmap.cpp7
-rwxr-xr-x[-rw-r--r--]indra/newview/llnetmap.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llnotificationalerthandler.cpp117
-rwxr-xr-x[-rw-r--r--]indra/newview/llnotificationgrouphandler.cpp65
-rwxr-xr-x[-rw-r--r--]indra/newview/llnotificationhandler.h237
-rwxr-xr-x[-rw-r--r--]indra/newview/llnotificationhandlerutil.cpp287
-rwxr-xr-x[-rw-r--r--]indra/newview/llnotificationhinthandler.cpp27
-rwxr-xr-x[-rw-r--r--]indra/newview/llnotificationmanager.cpp100
-rwxr-xr-x[-rw-r--r--]indra/newview/llnotificationmanager.h17
-rwxr-xr-x[-rw-r--r--]indra/newview/llnotificationofferhandler.cpp199
-rwxr-xr-x[-rw-r--r--]indra/newview/llnotificationscripthandler.cpp107
-rwxr-xr-x[-rw-r--r--]indra/newview/llnotificationstorage.cpp218
-rwxr-xr-x[-rw-r--r--]indra/newview/llnotificationstorage.h36
-rwxr-xr-x[-rw-r--r--]indra/newview/llnotificationtiphandler.cpp122
-rwxr-xr-x[-rw-r--r--]indra/newview/lloutfitobserver.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/lloutfitobserver.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/lloutfitslist.cpp30
-rwxr-xr-x[-rw-r--r--]indra/newview/lloutfitslist.h10
-rwxr-xr-x[-rw-r--r--]indra/newview/lloutputmonitorctrl.cpp114
-rwxr-xr-x[-rw-r--r--]indra/newview/lloutputmonitorctrl.h19
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelappearancetab.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelappearancetab.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelavatar.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelavatar.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelavatartag.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelavatartag.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelblockedlist.cpp168
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelblockedlist.h38
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelclassified.cpp1
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelclassified.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelcontents.cpp6
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelcontents.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llpaneleditwearable.cpp112
-rwxr-xr-x[-rw-r--r--]indra/newview/llpaneleditwearable.h32
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelface.cpp1975
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelface.h438
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelgenerictip.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelgenerictip.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelgroup.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelgroup.h2
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelgroupgeneral.cpp121
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelgroupgeneral.h6
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelgroupinvite.cpp99
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelgroupinvite.h4
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelgrouplandmoney.cpp6
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelgrouplandmoney.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelgroupnotices.cpp6
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelgroupnotices.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelgrouproles.cpp169
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelgrouproles.h9
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelhome.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelhome.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelimcontrolpanel.cpp397
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelimcontrolpanel.h56
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelland.cpp2
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelland.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanellandaudio.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanellandaudio.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanellandmarkinfo.cpp18
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanellandmarkinfo.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanellandmarks.cpp188
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanellandmarks.h3
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanellandmedia.cpp1
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanellandmedia.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanellogin.cpp562
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanellogin.h19
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelloginlistener.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelloginlistener.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelmaininventory.cpp142
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelmaininventory.h4
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelmarketplaceinbox.cpp24
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelmarketplaceinbox.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelmarketplaceinboxinventory.cpp146
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelmarketplaceinboxinventory.h19
-rw-r--r--indra/newview/llpanelmarketplaceoutboxinventory.cpp156
-rw-r--r--indra/newview/llpanelmarketplaceoutboxinventory.h78
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelme.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelme.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelmediasettingsgeneral.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelmediasettingsgeneral.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelmediasettingspermissions.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelmediasettingspermissions.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelmediasettingssecurity.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelmediasettingssecurity.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelnearbymedia.cpp2
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelnearbymedia.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelobject.cpp76
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelobject.h7
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelobjectinventory.cpp185
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelobjectinventory.h11
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelonlinestatus.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelonlinestatus.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llpaneloutfitedit.cpp37
-rwxr-xr-x[-rw-r--r--]indra/newview/llpaneloutfitedit.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llpaneloutfitsinventory.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llpaneloutfitsinventory.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelpeople.cpp477
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelpeople.h45
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelpeoplemenus.cpp184
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelpeoplemenus.h34
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelpermissions.cpp59
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelpermissions.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelpick.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelpick.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelplaceinfo.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelplaceinfo.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelplaceprofile.cpp12
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelplaceprofile.h2
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelplaces.cpp2
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelplaces.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelplacestab.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelplacestab.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelprimmediacontrols.cpp18
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelprimmediacontrols.h1
-rwxr-xr-xindra/newview/llpanelprofile.cpp20
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelsnapshot.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelsnapshot.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelsnapshotinventory.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelsnapshotlocal.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelsnapshotoptions.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelsnapshotpostcard.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelsnapshotprofile.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelteleporthistory.cpp5
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelteleporthistory.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llpaneltiptoast.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llpaneltiptoast.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llpaneltopinfobar.cpp14
-rwxr-xr-x[-rw-r--r--]indra/newview/llpaneltopinfobar.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelvoicedevicesettings.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelvoicedevicesettings.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelvoiceeffect.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelvoiceeffect.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelvolume.cpp50
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelvolume.h4
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelvolumepulldown.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelvolumepulldown.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelwearing.cpp15
-rwxr-xr-x[-rw-r--r--]indra/newview/llpanelwearing.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llparcelselection.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llparcelselection.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llparticipantlist.cpp741
-rwxr-xr-x[-rw-r--r--]indra/newview/llparticipantlist.h152
-rwxr-xr-x[-rw-r--r--]indra/newview/llpatchvertexarray.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llpatchvertexarray.h0
-rwxr-xr-xindra/newview/llpathfindingcharacter.cpp99
-rwxr-xr-xindra/newview/llpathfindingcharacter.h63
-rwxr-xr-xindra/newview/llpathfindingcharacterlist.cpp69
-rwxr-xr-xindra/newview/llpathfindingcharacterlist.h47
-rwxr-xr-xindra/newview/llpathfindinglinkset.cpp408
-rwxr-xr-xindra/newview/llpathfindinglinkset.h114
-rwxr-xr-xindra/newview/llpathfindinglinksetlist.cpp210
-rwxr-xr-xindra/newview/llpathfindinglinksetlist.h58
-rwxr-xr-xindra/newview/llpathfindingmanager.cpp1056
-rwxr-xr-xindra/newview/llpathfindingmanager.h127
-rwxr-xr-xindra/newview/llpathfindingnavmesh.cpp206
-rwxr-xr-xindra/newview/llpathfindingnavmesh.h91
-rwxr-xr-xindra/newview/llpathfindingnavmeshstatus.cpp145
-rwxr-xr-xindra/newview/llpathfindingnavmeshstatus.h77
-rwxr-xr-xindra/newview/llpathfindingnavmeshzone.cpp423
-rwxr-xr-xindra/newview/llpathfindingnavmeshzone.h128
-rwxr-xr-xindra/newview/llpathfindingobject.cpp200
-rwxr-xr-xindra/newview/llpathfindingobject.h92
-rwxr-xr-xindra/newview/llpathfindingobjectlist.cpp122
-rwxr-xr-xindra/newview/llpathfindingobjectlist.h68
-rwxr-xr-xindra/newview/llpathfindingpathtool.cpp467
-rwxr-xr-xindra/newview/llpathfindingpathtool.h138
-rwxr-xr-xindra/newview/llpersistentnotificationstorage.cpp182
-rwxr-xr-xindra/newview/llpersistentnotificationstorage.h66
-rwxr-xr-x[-rw-r--r--]indra/newview/llphysicsmotion.cpp90
-rwxr-xr-x[-rw-r--r--]indra/newview/llphysicsmotion.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llphysicsshapebuilderutil.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llphysicsshapebuilderutil.h0
-rw-r--r--indra/newview/llpipelinelistener.cpp216
-rw-r--r--indra/newview/llpipelinelistener.h41
-rwxr-xr-xindra/newview/llplacesfolderview.cpp74
-rwxr-xr-xindra/newview/llplacesfolderview.h72
-rwxr-xr-x[-rw-r--r--]indra/newview/llplacesinventorybridge.cpp50
-rwxr-xr-x[-rw-r--r--]indra/newview/llplacesinventorybridge.h3
-rwxr-xr-x[-rw-r--r--]indra/newview/llplacesinventorypanel.cpp120
-rwxr-xr-x[-rw-r--r--]indra/newview/llplacesinventorypanel.h37
-rw-r--r--indra/newview/llpolymesh.cpp1261
-rw-r--r--indra/newview/llpolymesh.h438
-rw-r--r--indra/newview/llpolymorph.cpp718
-rw-r--r--indra/newview/llpolymorph.h182
-rwxr-xr-x[-rw-r--r--]indra/newview/llpopupview.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llpopupview.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llpostcard.cpp1
-rwxr-xr-x[-rw-r--r--]indra/newview/llpostcard.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llpreview.cpp17
-rwxr-xr-x[-rw-r--r--]indra/newview/llpreview.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llpreviewanim.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llpreviewanim.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llpreviewgesture.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llpreviewgesture.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llpreviewnotecard.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llpreviewnotecard.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llpreviewscript.cpp29
-rwxr-xr-x[-rw-r--r--]indra/newview/llpreviewscript.h3
-rwxr-xr-x[-rw-r--r--]indra/newview/llpreviewsound.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llpreviewsound.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llpreviewtexture.cpp28
-rwxr-xr-x[-rw-r--r--]indra/newview/llpreviewtexture.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llproductinforequest.cpp6
-rwxr-xr-x[-rw-r--r--]indra/newview/llproductinforequest.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llprogressview.cpp38
-rwxr-xr-x[-rw-r--r--]indra/newview/llprogressview.h7
-rwxr-xr-x[-rw-r--r--]indra/newview/llrecentpeople.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llrecentpeople.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llregioninfomodel.cpp14
-rwxr-xr-x[-rw-r--r--]indra/newview/llregioninfomodel.h2
-rwxr-xr-x[-rw-r--r--]indra/newview/llregionposition.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llregionposition.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llremoteparcelrequest.cpp6
-rwxr-xr-x[-rw-r--r--]indra/newview/llremoteparcelrequest.h2
-rwxr-xr-x[-rw-r--r--]indra/newview/llresourcedata.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llrootview.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llsavedsettingsglue.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llsavedsettingsglue.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llsaveoutfitcombobtn.cpp4
-rwxr-xr-x[-rw-r--r--]indra/newview/llsaveoutfitcombobtn.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llsceneview.cpp2
-rwxr-xr-x[-rw-r--r--]indra/newview/llsceneview.h2
-rwxr-xr-x[-rw-r--r--]indra/newview/llscreenchannel.cpp180
-rwxr-xr-x[-rw-r--r--]indra/newview/llscreenchannel.h16
-rwxr-xr-x[-rw-r--r--]indra/newview/llscriptfloater.cpp123
-rwxr-xr-x[-rw-r--r--]indra/newview/llscriptfloater.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llscrollingpanelparam.cpp6
-rwxr-xr-x[-rw-r--r--]indra/newview/llscrollingpanelparam.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llscrollingpanelparambase.cpp2
-rwxr-xr-x[-rw-r--r--]indra/newview/llscrollingpanelparambase.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llsearchcombobox.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llsearchcombobox.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llsearchhistory.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llsearchhistory.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llsecapi.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llsecapi.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llsechandler_basic.cpp12
-rwxr-xr-x[-rw-r--r--]indra/newview/llsechandler_basic.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llselectmgr.cpp1023
-rwxr-xr-x[-rw-r--r--]indra/newview/llselectmgr.h67
-rwxr-xr-x[-rw-r--r--]indra/newview/llshareavatarhandler.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llsidepanelappearance.cpp53
-rwxr-xr-x[-rw-r--r--]indra/newview/llsidepanelappearance.h9
-rwxr-xr-x[-rw-r--r--]indra/newview/llsidepanelinventory.cpp24
-rwxr-xr-x[-rw-r--r--]indra/newview/llsidepanelinventory.h2
-rwxr-xr-x[-rw-r--r--]indra/newview/llsidepanelinventorysubpanel.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llsidepanelinventorysubpanel.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llsidepaneliteminfo.cpp2
-rwxr-xr-x[-rw-r--r--]indra/newview/llsidepaneliteminfo.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llsidepaneltaskinfo.cpp73
-rwxr-xr-x[-rw-r--r--]indra/newview/llsidepaneltaskinfo.h3
-rwxr-xr-x[-rw-r--r--]indra/newview/llsidetraypanelcontainer.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llsidetraypanelcontainer.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llsimplestat.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llsky.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llsky.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llslurl.cpp64
-rwxr-xr-x[-rw-r--r--]indra/newview/llslurl.h8
-rw-r--r--indra/newview/llsnapshotlivepreview.cpp874
-rw-r--r--indra/newview/llsnapshotlivepreview.h164
-rwxr-xr-x[-rw-r--r--]indra/newview/llspatialpartition.cpp1055
-rwxr-xr-x[-rw-r--r--]indra/newview/llspatialpartition.h151
-rwxr-xr-x[-rw-r--r--]indra/newview/llspeakers.cpp210
-rwxr-xr-x[-rw-r--r--]indra/newview/llspeakers.h15
-rwxr-xr-x[-rw-r--r--]indra/newview/llspeakingindicatormanager.cpp46
-rwxr-xr-x[-rw-r--r--]indra/newview/llspeakingindicatormanager.h5
-rwxr-xr-x[-rw-r--r--]indra/newview/llsplitbutton.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llsplitbutton.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llsprite.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llsprite.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llsrv.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llsrv.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llstartup.cpp219
-rwxr-xr-x[-rw-r--r--]indra/newview/llstartup.h6
-rwxr-xr-x[-rw-r--r--]indra/newview/llstartuplistener.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llstartuplistener.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llstatusbar.cpp2
-rwxr-xr-x[-rw-r--r--]indra/newview/llstatusbar.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llstylemap.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llstylemap.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llsurface.cpp26
-rwxr-xr-x[-rw-r--r--]indra/newview/llsurface.h4
-rwxr-xr-x[-rw-r--r--]indra/newview/llsurfacepatch.cpp14
-rwxr-xr-x[-rw-r--r--]indra/newview/llsurfacepatch.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llsyswellitem.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llsyswellitem.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llsyswellwindow.cpp364
-rwxr-xr-x[-rw-r--r--]indra/newview/llsyswellwindow.h77
-rwxr-xr-x[-rw-r--r--]indra/newview/lltable.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llteleporthistory.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llteleporthistory.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llteleporthistorystorage.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llteleporthistorystorage.h0
-rw-r--r--indra/newview/lltexglobalcolor.cpp152
-rw-r--r--indra/newview/lltexglobalcolor.h83
-rw-r--r--indra/newview/lltexlayer.cpp2506
-rw-r--r--indra/newview/lltexlayer.h380
-rw-r--r--indra/newview/lltexlayerparams.cpp568
-rw-r--r--indra/newview/lltexlayerparams.h193
-rwxr-xr-x[-rw-r--r--]indra/newview/lltextureatlas.cpp3
-rwxr-xr-x[-rw-r--r--]indra/newview/lltextureatlas.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/lltextureatlasmanager.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/lltextureatlasmanager.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/lltexturecache.cpp216
-rwxr-xr-x[-rw-r--r--]indra/newview/lltexturecache.h19
-rwxr-xr-x[-rw-r--r--]indra/newview/lltexturectrl.cpp161
-rwxr-xr-x[-rw-r--r--]indra/newview/lltexturectrl.h20
-rw-r--r--indra/newview/lltexturefetch.cpp3087
-rwxr-xr-x[-rw-r--r--]indra/newview/lltexturefetch.h482
-rwxr-xr-x[-rw-r--r--]indra/newview/lltextureinfo.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/lltextureinfo.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/lltextureinfodetails.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/lltextureinfodetails.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/lltexturestats.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/lltexturestats.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/lltexturestatsuploader.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/lltexturestatsuploader.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/lltextureview.cpp430
-rwxr-xr-x[-rw-r--r--]indra/newview/lltextureview.h35
-rwxr-xr-x[-rw-r--r--]indra/newview/lltoast.cpp46
-rwxr-xr-x[-rw-r--r--]indra/newview/lltoast.h9
-rwxr-xr-x[-rw-r--r--]indra/newview/lltoastalertpanel.cpp3
-rwxr-xr-x[-rw-r--r--]indra/newview/lltoastalertpanel.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/lltoastgroupnotifypanel.cpp11
-rwxr-xr-x[-rw-r--r--]indra/newview/lltoastgroupnotifypanel.h5
-rwxr-xr-x[-rw-r--r--]indra/newview/lltoastimpanel.cpp26
-rwxr-xr-x[-rw-r--r--]indra/newview/lltoastimpanel.h14
-rwxr-xr-x[-rw-r--r--]indra/newview/lltoastnotifypanel.cpp612
-rwxr-xr-x[-rw-r--r--]indra/newview/lltoastnotifypanel.h35
-rwxr-xr-x[-rw-r--r--]indra/newview/lltoastpanel.cpp59
-rwxr-xr-x[-rw-r--r--]indra/newview/lltoastpanel.h10
-rwxr-xr-xindra/newview/lltoastscriptquestion.cpp130
-rwxr-xr-xindra/newview/lltoastscriptquestion.h49
-rwxr-xr-x[-rw-r--r--]indra/newview/lltoastscripttextbox.cpp2
-rwxr-xr-x[-rw-r--r--]indra/newview/lltoastscripttextbox.h2
-rwxr-xr-x[-rw-r--r--]indra/newview/lltool.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/lltool.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/lltoolbarview.cpp37
-rwxr-xr-x[-rw-r--r--]indra/newview/lltoolbarview.h6
-rwxr-xr-x[-rw-r--r--]indra/newview/lltoolbrush.cpp2
-rwxr-xr-x[-rw-r--r--]indra/newview/lltoolbrush.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/lltoolcomp.cpp2
-rwxr-xr-x[-rw-r--r--]indra/newview/lltoolcomp.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/lltooldraganddrop.cpp170
-rwxr-xr-x[-rw-r--r--]indra/newview/lltooldraganddrop.h17
-rwxr-xr-x[-rw-r--r--]indra/newview/lltoolface.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/lltoolface.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/lltoolfocus.cpp10
-rwxr-xr-x[-rw-r--r--]indra/newview/lltoolfocus.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/lltoolgrab.cpp18
-rwxr-xr-x[-rw-r--r--]indra/newview/lltoolgrab.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/lltoolgun.cpp2
-rwxr-xr-x[-rw-r--r--]indra/newview/lltoolgun.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/lltoolindividual.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/lltoolindividual.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/lltoolmgr.cpp2
-rwxr-xr-x[-rw-r--r--]indra/newview/lltoolmgr.h6
-rwxr-xr-x[-rw-r--r--]indra/newview/lltoolmorph.cpp4
-rwxr-xr-x[-rw-r--r--]indra/newview/lltoolmorph.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/lltoolobjpicker.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/lltoolobjpicker.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/lltoolpie.cpp52
-rwxr-xr-x[-rw-r--r--]indra/newview/lltoolpie.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/lltoolpipette.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/lltoolpipette.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/lltoolplacer.cpp4
-rwxr-xr-x[-rw-r--r--]indra/newview/lltoolplacer.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/lltoolselect.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/lltoolselect.h2
-rwxr-xr-x[-rw-r--r--]indra/newview/lltoolselectland.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/lltoolselectland.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/lltoolselectrect.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/lltoolselectrect.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/lltoolview.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/lltoolview.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/lltracker.cpp2
-rwxr-xr-x[-rw-r--r--]indra/newview/lltracker.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/lltransientdockablefloater.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/lltransientdockablefloater.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/lltransientfloatermgr.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/lltransientfloatermgr.h0
-rwxr-xr-xindra/newview/lltranslate.h4
-rwxr-xr-x[-rw-r--r--]indra/newview/lluiconstants.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/lluilistener.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/lluilistener.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/lluploaddialog.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/lluploaddialog.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/lluploadfloaterobservers.cpp5
-rwxr-xr-x[-rw-r--r--]indra/newview/lluploadfloaterobservers.h2
-rwxr-xr-x[-rw-r--r--]indra/newview/llurl.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llurl.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llurldispatcher.cpp12
-rwxr-xr-x[-rw-r--r--]indra/newview/llurldispatcher.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llurldispatcherlistener.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llurldispatcherlistener.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llurlhistory.cpp25
-rwxr-xr-x[-rw-r--r--]indra/newview/llurlhistory.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llurllineeditorctrl.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llurllineeditorctrl.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llurlwhitelist.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llurlwhitelist.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llvectorperfoptions.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llvectorperfoptions.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llversioninfo.cpp55
-rwxr-xr-x[-rw-r--r--]indra/newview/llversioninfo.h1
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewchildren.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewchildren.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewerassetstats.cpp6
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewerassetstats.h5
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewerassetstorage.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewerassetstorage.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewerassettype.cpp2
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewerassettype.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewerattachmenu.cpp2
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewerattachmenu.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llvieweraudio.cpp112
-rwxr-xr-x[-rw-r--r--]indra/newview/llvieweraudio.h7
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewercamera.cpp6
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewercamera.h13
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewerchat.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewerchat.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewercontrol.cpp84
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewercontrol.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewercontrollistener.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewercontrollistener.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewerdisplay.cpp149
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewerdisplay.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewerdisplayname.cpp17
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewerdisplayname.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewerfloaterreg.cpp48
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewerfloaterreg.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewerfoldertype.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewergenericmessage.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewergenericmessage.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewergesture.cpp6
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewergesture.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewerhelp.cpp6
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewerhelp.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewerhelputil.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewerhelputil.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewerhome.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewerhome.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewerinventory.cpp523
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewerinventory.h92
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewerjoint.cpp473
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewerjoint.h108
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewerjointattachment.cpp24
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewerjointattachment.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewerjointmesh.cpp307
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewerjointmesh.h98
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewerjoystick.cpp2
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewerjoystick.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewerkeyboard.cpp22
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewerkeyboard.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewerlayer.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewerlayer.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewermedia.cpp48
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewermedia.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewermedia_streamingaudio.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewermedia_streamingaudio.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewermediafocus.cpp2
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewermediafocus.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewermediaobserver.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewermenu.cpp916
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewermenu.h23
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewermenufile.cpp10
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewermenufile.h0
-rwxr-xr-xindra/newview/llviewermessage.cpp1442
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewermessage.h18
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewernetwork.cpp753
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewernetwork.h211
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewerobject.cpp768
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewerobject.h106
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewerobjectlist.cpp256
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewerobjectlist.h8
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewerparcelmedia.cpp2
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewerparcelmedia.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewerparcelmediaautoplay.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewerparcelmediaautoplay.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewerparcelmgr.cpp84
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewerparcelmgr.h11
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewerparceloverlay.cpp1
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewerparceloverlay.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewerpartsim.cpp70
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewerpartsim.h17
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewerpartsource.cpp97
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewerpartsource.h4
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewerprecompiledheaders.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewerprecompiledheaders.h13
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewerregion.cpp254
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewerregion.h90
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewershadermgr.cpp997
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewershadermgr.h94
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewerstats.cpp414
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewerstats.h193
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewerstatsrecorder.cpp189
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewerstatsrecorder.h82
-rwxr-xr-xindra/newview/llviewertexlayer.cpp748
-rw-r--r--indra/newview/llviewertexlayer.h180
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewertexteditor.cpp10
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewertexteditor.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewertexture.cpp1085
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewertexture.h216
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewertextureanim.cpp26
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewertextureanim.h11
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewertexturelist.cpp450
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewertexturelist.h27
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewerthrottle.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewerthrottle.h0
-rw-r--r--indra/newview/llviewervisualparam.cpp164
-rw-r--r--indra/newview/llviewervisualparam.h109
-rw-r--r--indra/newview/llviewerwearable.cpp656
-rw-r--r--indra/newview/llviewerwearable.h104
-rwxr-xr-xindra/newview/llviewerwindow.cpp665
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewerwindow.h48
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewerwindowlistener.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewerwindowlistener.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llvlcomposition.cpp16
-rwxr-xr-x[-rw-r--r--]indra/newview/llvlcomposition.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llvlmanager.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llvlmanager.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llvoavatar.cpp4627
-rwxr-xr-x[-rw-r--r--]indra/newview/llvoavatar.h546
-rw-r--r--indra/newview/llvoavatardefines.cpp262
-rw-r--r--indra/newview/llvoavatardefines.h228
-rwxr-xr-x[-rw-r--r--]indra/newview/llvoavatarself.cpp1112
-rwxr-xr-x[-rw-r--r--]indra/newview/llvoavatarself.h124
-rwxr-xr-x[-rw-r--r--]indra/newview/llvocache.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llvocache.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llvograss.cpp214
-rwxr-xr-x[-rw-r--r--]indra/newview/llvograss.h11
-rwxr-xr-x[-rw-r--r--]indra/newview/llvoground.cpp15
-rwxr-xr-x[-rw-r--r--]indra/newview/llvoground.h2
-rwxr-xr-x[-rw-r--r--]indra/newview/llvoicecallhandler.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llvoicechannel.cpp12
-rwxr-xr-x[-rw-r--r--]indra/newview/llvoicechannel.h2
-rwxr-xr-x[-rw-r--r--]indra/newview/llvoiceclient.cpp13
-rwxr-xr-x[-rw-r--r--]indra/newview/llvoiceclient.h7
-rwxr-xr-x[-rw-r--r--]indra/newview/llvoicevisualizer.cpp48
-rwxr-xr-x[-rw-r--r--]indra/newview/llvoicevisualizer.h11
-rwxr-xr-x[-rw-r--r--]indra/newview/llvoicevivox.cpp1173
-rwxr-xr-x[-rw-r--r--]indra/newview/llvoicevivox.h34
-rwxr-xr-x[-rw-r--r--]indra/newview/llvoinventorylistener.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llvoinventorylistener.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llvopartgroup.cpp699
-rwxr-xr-x[-rw-r--r--]indra/newview/llvopartgroup.h42
-rwxr-xr-x[-rw-r--r--]indra/newview/llvosky.cpp13
-rwxr-xr-x[-rw-r--r--]indra/newview/llvosky.h2
-rwxr-xr-x[-rw-r--r--]indra/newview/llvosurfacepatch.cpp98
-rwxr-xr-x[-rw-r--r--]indra/newview/llvosurfacepatch.h8
-rwxr-xr-x[-rw-r--r--]indra/newview/llvotree.cpp164
-rwxr-xr-x[-rw-r--r--]indra/newview/llvotree.h15
-rwxr-xr-x[-rw-r--r--]indra/newview/llvotreenew.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llvovolume.cpp2193
-rwxr-xr-x[-rw-r--r--]indra/newview/llvovolume.h30
-rwxr-xr-x[-rw-r--r--]indra/newview/llvowater.cpp15
-rwxr-xr-x[-rw-r--r--]indra/newview/llvowater.h2
-rwxr-xr-x[-rw-r--r--]indra/newview/llvowlsky.cpp22
-rwxr-xr-x[-rw-r--r--]indra/newview/llvowlsky.h2
-rwxr-xr-x[-rw-r--r--]indra/newview/llwatchdog.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llwatchdog.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llwaterparammanager.cpp15
-rwxr-xr-x[-rw-r--r--]indra/newview/llwaterparammanager.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llwaterparamset.cpp2
-rwxr-xr-x[-rw-r--r--]indra/newview/llwaterparamset.h15
-rw-r--r--indra/newview/llwearable.cpp1285
-rw-r--r--indra/newview/llwearable.h165
-rwxr-xr-x[-rw-r--r--]indra/newview/llwearableitemslist.cpp12
-rwxr-xr-x[-rw-r--r--]indra/newview/llwearableitemslist.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llwearablelist.cpp54
-rwxr-xr-x[-rw-r--r--]indra/newview/llwearablelist.h13
-rw-r--r--indra/newview/llwearabletype.cpp159
-rw-r--r--indra/newview/llwearabletype.h76
-rwxr-xr-x[-rw-r--r--]indra/newview/llweb.cpp4
-rwxr-xr-x[-rw-r--r--]indra/newview/llweb.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llwebprofile.cpp5
-rwxr-xr-x[-rw-r--r--]indra/newview/llwebprofile.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llwebsharing.cpp16
-rwxr-xr-x[-rw-r--r--]indra/newview/llwebsharing.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llwind.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llwind.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llwindebug.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llwindebug.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llwindowlistener.cpp9
-rwxr-xr-x[-rw-r--r--]indra/newview/llwindowlistener.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llwlanimator.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llwlanimator.h1
-rwxr-xr-x[-rw-r--r--]indra/newview/llwldaycycle.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llwldaycycle.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llwlhandlers.cpp27
-rwxr-xr-x[-rw-r--r--]indra/newview/llwlhandlers.h5
-rwxr-xr-x[-rw-r--r--]indra/newview/llwlparammanager.cpp8
-rwxr-xr-x[-rw-r--r--]indra/newview/llwlparammanager.h1
-rwxr-xr-x[-rw-r--r--]indra/newview/llwlparamset.cpp64
-rwxr-xr-x[-rw-r--r--]indra/newview/llwlparamset.h10
-rwxr-xr-x[-rw-r--r--]indra/newview/llworld.cpp50
-rwxr-xr-x[-rw-r--r--]indra/newview/llworld.h6
-rwxr-xr-x[-rw-r--r--]indra/newview/llworldmap.cpp18
-rwxr-xr-x[-rw-r--r--]indra/newview/llworldmap.h1
-rwxr-xr-x[-rw-r--r--]indra/newview/llworldmapmessage.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llworldmapmessage.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llworldmapview.cpp9
-rwxr-xr-x[-rw-r--r--]indra/newview/llworldmapview.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llworldmipmap.cpp16
-rwxr-xr-x[-rw-r--r--]indra/newview/llworldmipmap.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llxmlrpclistener.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llxmlrpclistener.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/llxmlrpctransaction.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/llxmlrpctransaction.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/macmain.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/macutil_Prefix.h3
-rwxr-xr-x[-rw-r--r--]indra/newview/macview.r0
-rwxr-xr-x[-rw-r--r--]indra/newview/macview_Prefix.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/nl.lproj/language.txt0
-rwxr-xr-x[-rw-r--r--]indra/newview/noise.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/noise.h5
-rwxr-xr-x[-rw-r--r--]indra/newview/pipeline.cpp3271
-rwxr-xr-x[-rw-r--r--]indra/newview/pipeline.h147
-rwxr-xr-x[-rw-r--r--]indra/newview/pl.lproj/language.txt0
-rwxr-xr-x[-rw-r--r--]indra/newview/pt.lproj/language.txt0
-rwxr-xr-x[-rw-r--r--]indra/newview/res-sdl/arrow.BMPbin2102 -> 2102 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res-sdl/arrowcop.BMPbin3126 -> 3126 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res-sdl/arrowcopmulti.BMPbin3126 -> 3126 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res-sdl/arrowdrag.BMPbin2102 -> 2102 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res-sdl/circleandline.BMPbin2102 -> 2102 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res-sdl/cross.BMPbin2102 -> 2102 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res-sdl/hand.BMPbin2102 -> 2102 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res-sdl/ibeam.BMPbin2102 -> 2102 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res-sdl/llarrow.BMPbin2102 -> 2102 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res-sdl/llarrowdrag.BMPbin2102 -> 2102 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res-sdl/llarrowdragmulti.BMPbin3126 -> 3126 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res-sdl/llarrowlocked.BMPbin2102 -> 2102 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res-sdl/llgrablocked.BMPbin2102 -> 2102 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res-sdl/llno.BMPbin2102 -> 2102 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res-sdl/llnolocked.BMPbin2102 -> 2102 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res-sdl/lltoolcamera.BMPbin2102 -> 2102 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res-sdl/lltoolcreate.BMPbin2102 -> 2102 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res-sdl/lltoolfocus.BMPbin2102 -> 2102 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res-sdl/lltoolgrab.BMPbin2102 -> 2102 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res-sdl/lltoolland.BMPbin2102 -> 2102 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res-sdl/lltoolpan.BMPbin2102 -> 2102 bytes
-rwxr-xr-xindra/newview/res-sdl/lltoolpathfinding.BMPbin0 -> 3126 bytes
-rwxr-xr-xindra/newview/res-sdl/lltoolpathfindingpathend.BMPbin0 -> 3126 bytes
-rwxr-xr-xindra/newview/res-sdl/lltoolpathfindingpathendadd.BMPbin0 -> 3126 bytes
-rwxr-xr-xindra/newview/res-sdl/lltoolpathfindingpathstart.BMPbin0 -> 3126 bytes
-rwxr-xr-xindra/newview/res-sdl/lltoolpathfindingpathstartadd.BMPbin0 -> 3126 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res-sdl/lltoolpipette.BMPbin3126 -> 3126 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res-sdl/lltoolrotate.BMPbin2102 -> 2102 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res-sdl/lltoolscale.BMPbin2102 -> 2102 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res-sdl/lltooltranslate.BMPbin2102 -> 2102 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res-sdl/lltoolzoomin.BMPbin2102 -> 2102 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res-sdl/lltoolzoomout.BMPbin2102 -> 2102 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res-sdl/sizenesw.BMPbin2102 -> 2102 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res-sdl/sizens.BMPbin2102 -> 2102 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res-sdl/sizenwse.BMPbin2102 -> 2102 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res-sdl/sizewe.BMPbin2102 -> 2102 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res-sdl/toolbuy.BMPbin3126 -> 3126 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res-sdl/toolmediaopen.BMPbin3128 -> 3128 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res-sdl/toolopen.BMPbin3126 -> 3126 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res-sdl/toolpause.BMPbin3128 -> 3128 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res-sdl/toolpickobject.BMPbin2102 -> 2102 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res-sdl/toolpickobject2.BMPbin2102 -> 2102 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res-sdl/toolpickobject3.BMPbin2102 -> 2102 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res-sdl/toolplay.BMPbin3128 -> 3128 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res-sdl/toolsit.BMPbin3126 -> 3126 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res-sdl/wait.BMPbin2102 -> 2102 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res-sdl/working.BMPbin2102 -> 2102 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res/arrow.curbin326 -> 326 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res/arrowcop.curbin326 -> 326 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res/arrowcopmulti.curbin326 -> 326 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res/arrowdrag.curbin326 -> 326 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res/bitmap2.bmpbin25118 -> 25118 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res/circleandline.curbin326 -> 326 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res/have_artwork_bundle.marker0
-rwxr-xr-x[-rw-r--r--]indra/newview/res/icon1.icobin766 -> 766 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res/install_icon.BMPbin262198 -> 262198 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res/llarrow.curbin326 -> 326 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res/llarrowdrag.curbin326 -> 326 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res/llarrowdragmulti.curbin326 -> 326 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res/llarrowlocked.curbin326 -> 326 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res/llgrablocked.curbin326 -> 326 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res/llno.curbin326 -> 326 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res/llnolocked.curbin326 -> 326 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res/lltoolcamera.curbin326 -> 326 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res/lltoolcreate.curbin326 -> 326 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res/lltoolfocus.curbin326 -> 326 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res/lltoolgrab.curbin326 -> 326 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res/lltoolland.curbin326 -> 326 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res/lltoolpan.curbin326 -> 326 bytes
-rwxr-xr-xindra/newview/res/lltoolpathfinding.curbin0 -> 2238 bytes
-rwxr-xr-xindra/newview/res/lltoolpathfindingpathend.curbin0 -> 2238 bytes
-rwxr-xr-xindra/newview/res/lltoolpathfindingpathendadd.curbin0 -> 2238 bytes
-rwxr-xr-xindra/newview/res/lltoolpathfindingpathstart.curbin0 -> 2238 bytes
-rwxr-xr-xindra/newview/res/lltoolpathfindingpathstartadd.curbin0 -> 2238 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res/lltoolpipette.curbin326 -> 326 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res/lltoolrotate.curbin326 -> 326 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res/lltoolscale.curbin326 -> 326 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res/lltooltranslate.curbin326 -> 326 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res/lltoolzoomin.curbin326 -> 326 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res/lltoolzoomout.curbin326 -> 326 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res/loginbackground.bmpbin336054 -> 336054 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res/resource.h0
-rwxr-xr-x[-rw-r--r--]indra/newview/res/toolbuy.curbin4286 -> 4286 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res/toolmediaopen.curbin2238 -> 2238 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res/toolopen.curbin4286 -> 4286 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res/toolpause.curbin2238 -> 2238 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res/toolpickobject.curbin326 -> 326 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res/toolpickobject2.curbin326 -> 326 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res/toolpickobject3.curbin326 -> 326 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res/toolpipette.curbin326 -> 326 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res/toolplay.curbin2238 -> 2238 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res/toolsit.curbin4286 -> 4286 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res/uninstall_icon.BMPbin262198 -> 262198 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/res/viewerRes.rc16
-rwxr-xr-x[-rw-r--r--]indra/newview/ru.lproj/language.txt0
-rwxr-xr-x[-rw-r--r--]indra/newview/secondlife-i686.supp0
-rwxr-xr-x[-rw-r--r--]indra/newview/secondlife.icnsbin180809 -> 180809 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/secondlife_firstlook.icnsbin274109 -> 274109 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/colors.xml81
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/html/btn_purplepill_bg.pngbin3564 -> 3564 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/html/da/loading/loading.html0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/html/de/loading-error/index.html0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/html/de/loading/loading.html0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/html/en-us/help-offline/index.html0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/html/en-us/loading-error/index.html0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/html/en-us/loading/loading.html0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/html/en-us/loading/sl_logo_rotate_black.gifbin7426 -> 7426 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/html/es/loading-error/index.html0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/html/es/loading/loading.html0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/html/fr/loading-error/index.html0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/html/fr/loading/loading.html0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/html/hu/loading/loading.html0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/html/it/loading/loading.html0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/html/ja/loading-error/index.html0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/html/ja/loading/loading.html0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/html/ko/loading-error/index.html0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/html/nl/loading/loading.html0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/html/pl/loading/loading.html0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/html/pt/loading-error/index.html0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/html/pt/loading/loading.html0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/html/ru/loading/loading.html0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/html/tr/loading/loading.html0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/html/uk/loading/loading.html0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/html/unabletoconnect.pngbin15849 -> 15849 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/html/zh/loading-error/index.html0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/html/zh/loading/loading.html0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/Blank.pngbin110 -> 110 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/Rounded_Rect.pngbin338 -> 338 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/alpha_gradient.tgabin300 -> 300 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/alpha_gradient_2d.j2cbin4325 -> 4325 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/arrow_down.tgabin1068 -> 1068 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/arrow_up.tgabin1068 -> 1068 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/avatar_thumb_bkgrnd.pngbin17692 -> 17692 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/badge_note.j2cbin2040 -> 2040 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/badge_ok.j2cbin2043 -> 2043 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/badge_warn.j2cbin2043 -> 2043 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/bottomtray/Cam_Avatar_Off.pngbin527 -> 527 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/bottomtray/Cam_FreeCam_Off.pngbin365 -> 365 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/bottomtray/Cam_Orbit_Off.pngbin532 -> 532 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/bottomtray/Cam_Pan_Off.pngbin328 -> 328 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/bottomtray/Cam_Preset_Back_Off.pngbin49285 -> 49285 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/bottomtray/Cam_Preset_Back_On.pngbin50855 -> 50855 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/bottomtray/Cam_Preset_Eye_Off.pngbin914 -> 914 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/bottomtray/Cam_Preset_Front_Off.pngbin50394 -> 50394 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/bottomtray/Cam_Preset_Front_On.pngbin50127 -> 50127 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/bottomtray/Cam_Preset_Side_Off.pngbin49268 -> 49268 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/bottomtray/Cam_Preset_Side_On.pngbin50209 -> 50209 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/bottomtray/Cam_Rotate_In.pngbin407 -> 407 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/bottomtray/Cam_Rotate_Out.pngbin3271 -> 3271 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/bottomtray/Cam_Tracking_In.pngbin328 -> 328 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/bottomtray/Cam_Tracking_Out.pngbin787 -> 787 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/bottomtray/ChatBarHandle.pngbin2808 -> 2808 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/bottomtray/DownArrow.pngbin139 -> 139 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/bottomtray/Mouselook_View_Off.pngbin51189 -> 51189 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/bottomtray/Mouselook_View_On.pngbin53113 -> 53113 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/bottomtray/Move_Fly_Off.pngbin3347 -> 3347 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/bottomtray/Move_Run_Off.pngbin496 -> 496 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/bottomtray/Move_Walk_Off.pngbin515 -> 515 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/bottomtray/Movement_Backward_Off.pngbin354 -> 354 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/bottomtray/Movement_Backward_On.pngbin353 -> 353 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/bottomtray/Movement_Down_Off.pngbin51706 -> 51706 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/bottomtray/Movement_Down_On.pngbin50907 -> 50907 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/bottomtray/Movement_Forward_Off.pngbin322 -> 322 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/bottomtray/Movement_Forward_On.pngbin321 -> 321 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/bottomtray/Movement_Left_Off.pngbin51016 -> 51016 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/bottomtray/Movement_Left_On.pngbin51806 -> 51806 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/bottomtray/Movement_Right_Off.pngbin49845 -> 49845 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/bottomtray/Movement_Right_On.pngbin50161 -> 50161 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/bottomtray/Movement_TurnLeft_Off.pngbin431 -> 431 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/bottomtray/Movement_TurnLeft_On.pngbin430 -> 430 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/bottomtray/Movement_TurnRight_Off.pngbin432 -> 432 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/bottomtray/Movement_TurnRight_On.pngbin427 -> 427 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/bottomtray/Movement_Up_Off.pngbin53763 -> 53763 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/bottomtray/Movement_Up_On.pngbin51965 -> 51965 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/bottomtray/Notices_Unread.pngbin3693 -> 3693 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/bottomtray/Object_View_Off.pngbin55000 -> 55000 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/bottomtray/Object_View_On.pngbin51183 -> 51183 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/bottomtray/PanOrbit_Off.pngbin51539 -> 51539 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/bottomtray/Snapshot_Off.pngbin3204 -> 3204 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/bottomtray/Unread_Chiclet.pngbin334 -> 334 bytes
-rw-r--r--indra/newview/skins/default/textures/bottomtray/Unread_IM.pngbin458 -> 0 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl1.pngbin557 -> 557 bytes
-rw-r--r--indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl1_Dark.pngbin602 -> 0 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl2.pngbin663 -> 663 bytes
-rw-r--r--indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl2_Dark.pngbin669 -> 0 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl3.pngbin607 -> 607 bytes
-rw-r--r--indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl3_Dark.pngbin639 -> 0 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/bottomtray/VoicePTT_Off.pngbin461 -> 461 bytes
-rw-r--r--indra/newview/skins/default/textures/bottomtray/VoicePTT_Off_Dark.pngbin547 -> 0 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/bottomtray/VoicePTT_On.pngbin451 -> 451 bytes
-rw-r--r--indra/newview/skins/default/textures/bottomtray/VoicePTT_On_Dark.pngbin526 -> 0 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/bottomtray/WellButton_Lit.pngbin309 -> 309 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/bottomtray/WellButton_Lit_Selected.pngbin309 -> 309 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/build/Object_Cone.pngbin481 -> 481 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/build/Object_Cone_Selected.pngbin576 -> 576 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/build/Object_Cube.pngbin370 -> 370 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/build/Object_Cube_Selected.pngbin477 -> 477 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/build/Object_Cylinder.pngbin373 -> 373 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/build/Object_Cylinder_Selected.pngbin443 -> 443 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/build/Object_Grass.pngbin456 -> 456 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/build/Object_Grass_Selected.pngbin757 -> 757 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/build/Object_Hemi_Cone.pngbin441 -> 441 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/build/Object_Hemi_Cone_Selected.pngbin531 -> 531 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/build/Object_Hemi_Cylinder.pngbin378 -> 378 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/build/Object_Hemi_Cylinder_Selected.pngbin463 -> 463 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/build/Object_Hemi_Sphere.pngbin545 -> 545 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/build/Object_Hemi_Sphere_Selected.pngbin696 -> 696 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/build/Object_Prism.pngbin395 -> 395 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/build/Object_Prism_Selected.pngbin485 -> 485 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/build/Object_Pyramid.pngbin452 -> 452 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/build/Object_Pyramid_Selected.pngbin594 -> 594 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/build/Object_Ring.pngbin615 -> 615 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/build/Object_Ring_Selected.pngbin738 -> 738 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/build/Object_Sphere.pngbin737 -> 737 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/build/Object_Sphere_Selected.pngbin1003 -> 1003 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/build/Object_Tetrahedron.pngbin411 -> 411 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/build/Object_Tetrahedron_Selected.pngbin558 -> 558 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/build/Object_Torus.pngbin803 -> 803 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/build/Object_Torus_Selected.pngbin825 -> 825 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/build/Object_Tree.pngbin737 -> 737 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/build/Object_Tree_Selected.pngbin839 -> 839 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/build/Object_Tube.pngbin460 -> 460 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/build/Object_Tube_Selected.pngbin552 -> 552 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/build/Tool_Create.pngbin705 -> 705 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/build/Tool_Dozer.pngbin492 -> 492 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/build/Tool_Face.pngbin304 -> 304 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/build/Tool_Grab.pngbin417 -> 417 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/build/Tool_Zoom.pngbin533 -> 533 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/button_anim_pause.tgabin4140 -> 4140 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/button_anim_pause_selected.tgabin4140 -> 4140 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/button_anim_play.tgabin4140 -> 4140 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/button_anim_play_selected.tgabin4140 -> 4140 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/checker.pngbin130 -> 130 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/cloud-particle.j2cbin4049 -> 4049 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/color_swatch_alpha.tgabin16428 -> 16428 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/containers/Accordion_ArrowClosed_Off.pngbin175 -> 175 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/containers/Accordion_ArrowClosed_Press.pngbin175 -> 175 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/containers/Accordion_ArrowOpened_Off.pngbin169 -> 169 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/containers/Accordion_ArrowOpened_Press.pngbin169 -> 169 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/containers/Accordion_Off.pngbin239 -> 239 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/containers/Accordion_Over.pngbin206 -> 206 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/containers/Accordion_Press.pngbin200 -> 200 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/containers/Accordion_Selected.pngbin228 -> 228 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/containers/Container.pngbin673 -> 673 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/containers/TabTop_Left_Off.pngbin339 -> 339 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/containers/TabTop_Left_Selected.pngbin458 -> 458 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/containers/TabTop_Middle_Off.pngbin258 -> 258 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/containers/TabTop_Middle_Selected.pngbin367 -> 367 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/containers/TabTop_Right_Off.pngbin357 -> 357 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/containers/TabTop_Right_Selected.pngbin474 -> 474 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/containers/Toolbar_Left_Flash.pngbin356 -> 356 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/containers/Toolbar_Left_Off.pngbin306 -> 306 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/containers/Toolbar_Left_Over.pngbin310 -> 310 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/containers/Toolbar_Left_Selected.pngbin380 -> 380 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/containers/Toolbar_Middle_Flash.pngbin316 -> 316 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/containers/Toolbar_Middle_Off.pngbin224 -> 224 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/containers/Toolbar_Middle_Over.pngbin228 -> 228 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/containers/Toolbar_Middle_Selected.pngbin296 -> 296 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/containers/Toolbar_Right_Flash.pngbin428 -> 428 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/containers/Toolbar_Right_Off.pngbin302 -> 302 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/containers/Toolbar_Right_Over.pngbin297 -> 297 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/containers/Toolbar_Right_Selected.pngbin377 -> 377 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/crosshairs.tgabin300 -> 300 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/default_land_picture.j2cbin24492 -> 24492 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/default_profile_picture.j2cbin1512 -> 1512 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/direction_arrow.tgabin1068 -> 1068 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/down_arrow.pngbin2936 -> 2936 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/eye_button_active.tgabin3116 -> 3116 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/eye_button_inactive.tgabin3116 -> 3116 bytes
-rw-r--r--indra/newview/skins/default/textures/flatnormal.tgabin0 -> 92 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/folder_arrow.tgabin4140 -> 4140 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/foot_shadow.j2cbin1647 -> 1647 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/green_checkmark.pngbin414 -> 414 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icn_media_movie.tgabin4140 -> 4140 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icn_media_web.tgabin4140 -> 4140 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icon_avatar_offline.tgabin1068 -> 1068 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icon_avatar_online.tgabin1068 -> 1068 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icon_diurnal.tgabin6162 -> 6162 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icon_for_sale_adult.tgabin743 -> 743 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icon_top_pick.tgabin1068 -> 1068 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/AddItem_Disabled.pngbin186 -> 186 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/AddItem_Off.pngbin184 -> 184 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/AddItem_Press.pngbin181 -> 181 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/AudioMute_Off.pngbin600 -> 600 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/AudioMute_Over.pngbin587 -> 587 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Audio_Off.pngbin467 -> 467 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Audio_Press.pngbin477 -> 477 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/BackArrow_Off.pngbin227 -> 227 bytes
-rwxr-xr-xindra/newview/skins/default/textures/icons/Conv_log_inbox.pngbin0 -> 556 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/Conv_toolbar_add_person.pngbin0 -> 373 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/Conv_toolbar_arrow_ne.pngbin0 -> 215 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/Conv_toolbar_arrow_sw.pngbin0 -> 211 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/Conv_toolbar_call_log.pngbin0 -> 546 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/Conv_toolbar_close.pngbin0 -> 275 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/Conv_toolbar_collapse.pngbin0 -> 345 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/Conv_toolbar_expand.pngbin0 -> 342 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/Conv_toolbar_hang_up.pngbin0 -> 459 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/Conv_toolbar_open_call.pngbin0 -> 366 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/Conv_toolbar_plus.pngbin0 -> 144 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/Conv_toolbar_sort.pngbin0 -> 230 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Copy.pngbin481 -> 481 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/DownArrow_Off.pngbin217 -> 217 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Edit_Wrench.pngbin3000 -> 3000 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/ExternalBrowser_Off.pngbin279 -> 279 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/Facebook.pngbin0 -> 365 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Female.pngbin309 -> 309 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/ForSale_Badge.pngbin5727 -> 5727 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/ForwardArrow_Off.pngbin220 -> 220 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/ForwardArrow_Press.pngbin220 -> 220 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Generic_Group.pngbin1523 -> 1523 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Generic_Group_Large.pngbin7507 -> 7507 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Generic_Object_Small.pngbin410 -> 410 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Generic_Person.pngbin3280 -> 3280 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Generic_Person_Large.pngbin51508 -> 51508 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Hierarchy_View_Disabled.pngbin178 -> 178 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Hierarchy_View_On.pngbin2839 -> 2839 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Icon_For_Sale.pngbin572 -> 572 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Info.pngbin351 -> 351 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Info_Over.pngbin376 -> 376 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Info_Small.pngbin371 -> 371 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Inv_Alpha.pngbin319 -> 319 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Inv_Animation.pngbin496 -> 496 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Inv_BodyShape.pngbin641 -> 641 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Inv_CallingCard.pngbin295 -> 295 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Inv_Clothing.pngbin253 -> 253 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Inv_Eye.pngbin491 -> 491 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Inv_FolderClosed.pngbin219 -> 219 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Inv_FolderOpen.pngbin361 -> 361 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Inv_Gesture.pngbin408 -> 408 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Inv_Gloves.pngbin366 -> 366 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Inv_Hair.pngbin377 -> 377 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Inv_Invalid.pngbin329 -> 329 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Inv_Jacket.pngbin591 -> 591 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Inv_Landmark.pngbin582 -> 582 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Inv_Link.pngbin2857 -> 2857 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Inv_LinkFolder.pngbin296 -> 296 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Inv_LinkItem.pngbin296 -> 296 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Inv_LookFolderClosed.pngbin391 -> 391 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Inv_LookFolderOpen.pngbin538 -> 538 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Inv_LostClosed.pngbin3033 -> 3033 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Inv_LostOpen.pngbin3223 -> 3223 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Inv_Mesh.pngbin3263 -> 3263 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Inv_Notecard.pngbin222 -> 222 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Inv_Object.pngbin333 -> 333 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Inv_Object_Multi.pngbin774 -> 774 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Inv_Pants.pngbin377 -> 377 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Inv_Physics.pngbin539 -> 539 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Inv_Script.pngbin469 -> 469 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Inv_Shirt.pngbin402 -> 402 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Inv_Shoe.pngbin54133 -> 54133 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Inv_Skin.pngbin393 -> 393 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Inv_Skirt.pngbin494 -> 494 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Inv_Snapshot.pngbin535 -> 535 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Inv_Socks.pngbin358 -> 358 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Inv_Sound.pngbin404 -> 404 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Inv_SysClosed.pngbin3153 -> 3153 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Inv_SysOpen.pngbin3251 -> 3251 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Inv_Tattoo.pngbin416 -> 416 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Inv_Texture.pngbin157 -> 157 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Inv_TrashClosed.pngbin2978 -> 2978 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Inv_TrashOpen.pngbin2970 -> 2970 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Inv_Underpants.pngbin418 -> 418 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Inv_Undershirt.pngbin208 -> 208 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/List_View_Disabled.pngbin158 -> 158 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/List_View_On.pngbin160 -> 160 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Lock.pngbin343 -> 343 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Locked_Icon.pngbin306 -> 306 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Male.pngbin302 -> 302 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Microphone_On.pngbin340 -> 340 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/MinusItem_Disabled.pngbin173 -> 173 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/MinusItem_Off.pngbin178 -> 178 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/MinusItem_Press.pngbin172 -> 172 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/OptionsMenu_Disabled.pngbin343 -> 343 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/OptionsMenu_Off.pngbin336 -> 336 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/OptionsMenu_Press.pngbin318 -> 318 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/OutboxPush_Disabled.pngbin1848 -> 1848 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/OutboxPush_Off.pngbin1835 -> 1835 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/OutboxPush_On.pngbin1851 -> 1851 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/OutboxPush_On_Over.pngbin1863 -> 1863 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/OutboxPush_Over.pngbin1826 -> 1826 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/OutboxPush_Press.pngbin1891 -> 1891 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/OutboxPush_Progress_1.pngbin1848 -> 1848 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/OutboxPush_Progress_2.pngbin1807 -> 1807 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/OutboxPush_Progress_3.pngbin1819 -> 1819 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/OutboxPush_Progress_4.pngbin1894 -> 1894 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/OutboxPush_Progress_5.pngbin1921 -> 1921 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/OutboxPush_Progress_6.pngbin1853 -> 1853 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/OutboxPush_Selected.pngbin1894 -> 1894 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/OutboxPush_Selected_Disabled.pngbin1840 -> 1840 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/OutboxPush_Selected_Over.pngbin1870 -> 1870 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/OutboxPush_Selected_Press.pngbin1912 -> 1912 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Parcel_BuildNo_Dark.pngbin516 -> 516 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Parcel_BuildNo_Light.pngbin505 -> 505 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Parcel_Build_Dark.pngbin343 -> 343 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Parcel_DamageNo_Dark.pngbin457 -> 457 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Parcel_Damage_Dark.pngbin325 -> 325 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Parcel_Exp_Color.pngbin272 -> 272 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Parcel_FlyNo_Dark.pngbin3221 -> 3221 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Parcel_FlyNo_Light.pngbin3235 -> 3235 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Parcel_Fly_Dark.pngbin3077 -> 3077 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Parcel_ForSale_Light.pngbin561 -> 561 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Parcel_Health_Dark.pngbin285 -> 285 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Parcel_M_Dark.pngbin348 -> 348 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Parcel_M_Light.pngbin335 -> 335 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Parcel_PG_Dark.pngbin400 -> 400 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Parcel_PG_Light.pngbin403 -> 403 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Parcel_PushNo_Dark.pngbin523 -> 523 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Parcel_PushNo_Light.pngbin516 -> 516 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Parcel_Push_Dark.pngbin430 -> 430 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Parcel_R_Dark.pngbin357 -> 357 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Parcel_R_Light.pngbin355 -> 355 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Parcel_ScriptsNo_Dark.pngbin620 -> 620 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Parcel_Scripts_Dark.pngbin471 -> 471 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Parcel_SeeAVsOff_Dark.pngbin3194 -> 3194 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Parcel_SeeAVsOff_Light.pngbin3189 -> 3189 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Parcel_SeeAVsOn_Dark.pngbin3011 -> 3011 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Parcel_SeeAVsOn_Light.pngbin3011 -> 3011 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Parcel_VoiceNo_Dark.pngbin492 -> 492 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Parcel_VoiceNo_Light.pngbin516 -> 516 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Parcel_Voice_Dark.pngbin380 -> 380 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Parcel_Voice_Light.pngbin405 -> 405 bytes
-rwxr-xr-xindra/newview/skins/default/textures/icons/Pathfinding_Dirty.pngbin0 -> 553 bytes
-rwxr-xr-xindra/newview/skins/default/textures/icons/Pathfinding_Disabled.pngbin0 -> 384 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Pause_Off.pngbin163 -> 163 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Pause_Over.pngbin160 -> 160 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Pause_Press.pngbin156 -> 156 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Person_Check.pngbin3824 -> 3824 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Person_Star.pngbin3762 -> 3762 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Play_Off.pngbin293 -> 293 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Play_Over.pngbin258 -> 258 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Play_Press.pngbin287 -> 287 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Progress_1.pngbin470 -> 470 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Progress_10.pngbin461 -> 461 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Progress_11.pngbin475 -> 475 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Progress_12.pngbin455 -> 455 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Progress_2.pngbin453 -> 453 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Progress_3.pngbin454 -> 454 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Progress_4.pngbin454 -> 454 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Progress_5.pngbin468 -> 468 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Progress_6.pngbin462 -> 462 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Progress_7.pngbin469 -> 469 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Progress_8.pngbin454 -> 454 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Progress_9.pngbin469 -> 469 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Refresh_Off.pngbin483 -> 483 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/SL_Logo.pngbin3999 -> 3999 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Search_Icon.pngbin552 -> 552 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Shirt_Large.pngbin471 -> 471 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Shop.pngbin3052 -> 3052 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/SkipBackward_Off.pngbin293 -> 293 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/SkipForward_Off.pngbin304 -> 304 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/StopReload_Off.pngbin533 -> 533 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/StopReload_Over.pngbin529 -> 529 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Stop_Off.pngbin148 -> 148 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Sync_Disabled.pngbin1187 -> 1187 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Sync_Enabled.pngbin1168 -> 1168 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Sync_Progress_1.pngbin1149 -> 1149 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Sync_Progress_2.pngbin1147 -> 1147 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Sync_Progress_3.pngbin1211 -> 1211 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Sync_Progress_4.pngbin1205 -> 1205 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Sync_Progress_5.pngbin1137 -> 1137 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Sync_Progress_6.pngbin1164 -> 1164 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/TrashItem_Disabled.pngbin196 -> 196 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/TrashItem_Off.pngbin201 -> 201 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/TrashItem_Press.pngbin201 -> 201 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/UnZoom_Off.pngbin423 -> 423 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/UpArrow_Off.pngbin219 -> 219 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/VoicePTT_Lvl1.pngbin557 -> 557 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/VoicePTT_Lvl2.pngbin663 -> 663 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/VoicePTT_Lvl3.pngbin607 -> 607 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/VoicePTT_Off.pngbin461 -> 461 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/VoicePTT_On.pngbin451 -> 451 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Web_Profile_Off.pngbin2961 -> 2961 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/YouAreHere_Badge.pngbin6143 -> 6143 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/Zoom_Off.pngbin435 -> 435 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/avaline_default_icon.jpgbin3951 -> 3951 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/back_arrow_off.pngbin3775 -> 3775 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/back_arrow_over.pngbin3792 -> 3792 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/back_arrow_press.pngbin3844 -> 3844 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/check_mark.pngbin3166 -> 3166 bytes
-rwxr-xr-xindra/newview/skins/default/textures/icons/collapse_to_one_line.pngbin0 -> 538 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/edit_mine.pngbin639 -> 639 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/edit_theirs.pngbin634 -> 634 bytes
-rwxr-xr-xindra/newview/skins/default/textures/icons/expand_one_liner.pngbin0 -> 545 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/map_placeholder.pngbin0 -> 7694 bytes
-rwxr-xr-xindra/newview/skins/default/textures/icons/nearby_chat_icon.pngbin0 -> 399 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/object_icon.pngbin410 -> 410 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/pop_up_caution.pngbin3158 -> 3158 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/see_me_online.pngbin330 -> 330 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/see_on_map.pngbin613 -> 613 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/icons/unknown_icon.pngbin884 -> 884 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/jump_left_in.tgabin812 -> 812 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/jump_left_out.tgabin812 -> 812 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/jump_right_in.tgabin812 -> 812 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/jump_right_out.tgabin812 -> 812 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/lag_status_critical.tgabin4140 -> 4140 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/lag_status_good.tgabin658 -> 658 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/lag_status_warning.tgabin658 -> 658 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/legend.tgabin1068 -> 1068 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/locked_image.j2cbin6140 -> 6140 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/map_avatar_16.tgabin1068 -> 1068 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/map_avatar_32.tgabin2894 -> 2894 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/map_avatar_8.tgabin300 -> 300 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/map_avatar_above_32.tgabin2909 -> 2909 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/map_avatar_below_32.tgabin3037 -> 3037 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/map_avatar_unknown_32.tgabin4140 -> 4140 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/map_avatar_you_32.tgabin3395 -> 3395 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/map_event.tgabin1068 -> 1068 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/map_home.tgabin1068 -> 1068 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/map_infohub.tgabin1068 -> 1068 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/map_telehub.tgabin1068 -> 1068 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/map_track_16.tgabin1068 -> 1068 bytes
-rw-r--r--indra/newview/skins/default/textures/materials_ui_x_24.pngbin0 -> 602 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/menu_separator.pngbin2831 -> 2831 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/missing_asset.tgabin2511 -> 2511 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/model_wizard/progress_bar_bg.pngbin3180 -> 3180 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/model_wizard/progress_light.pngbin2979 -> 2979 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/navbar/Arrow_Left_Off.pngbin382 -> 382 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/navbar/Arrow_Right_Off.pngbin380 -> 380 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/navbar/BuyArrow_Over.pngbin294 -> 294 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/navbar/BuyArrow_Press.pngbin294 -> 294 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/navbar/Favorite_Link_Over.pngbin191 -> 191 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/navbar/Favorite_Star_Active.pngbin704 -> 704 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/navbar/Favorite_Star_Off.pngbin444 -> 444 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/navbar/Favorite_Star_Over.pngbin445 -> 445 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/navbar/Favorite_Star_Press.pngbin616 -> 616 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/navbar/FileMenu_Divider.pngbin116 -> 116 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/navbar/Flag.pngbin338 -> 338 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/navbar/Help_Press.pngbin384 -> 384 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/navbar/Home_Off.pngbin379 -> 379 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/navbar/Info_Off.pngbin608 -> 608 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/navbar/Info_Over.pngbin622 -> 622 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/navbar/Info_Press.pngbin605 -> 605 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/navbar/Lock.pngbin302 -> 302 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/navbar/NavBar_BG.pngbin195 -> 195 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/navbar/NavBar_BG_NoFav_Bevel.pngbin231 -> 231 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/navbar/NavBar_BG_NoNav_Bevel.pngbin218 -> 218 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/navbar/Row_Selection.pngbin231 -> 231 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/navbar/Search.pngbin3182 -> 3182 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/navbar/separator.pngbin2826 -> 2826 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/notify_caution_icon.tgabin4140 -> 4140 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/pixiesmall.j2cbin2845 -> 2845 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/red_x.pngbin624 -> 624 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/rounded_square.j2cbin1074 -> 1074 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/script_error.j2cbin8132 -> 8132 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/silhouette.j2cbin1460 -> 1460 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/slim_icon_16_viewer.tgabin1032 -> 1032 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/snapshot_download.pngbin1226 -> 1226 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/snapshot_email.pngbin1231 -> 1231 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/spacer24.tgabin2348 -> 2348 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/tabarea.tgabin1340 -> 1340 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/taskpanel/Activate_Checkmark.pngbin435 -> 435 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/taskpanel/Sidebar_Icon_Dock_Foreground.pngbin2899 -> 2899 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/taskpanel/Sidebar_Icon_Dock_Press.pngbin2886 -> 2886 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/taskpanel/Sidebar_Icon_Undock_Foreground.pngbin2896 -> 2896 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/taskpanel/Sidebar_Icon_Undock_Press.pngbin2920 -> 2920 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/taskpanel/TabIcon_Close_Off.pngbin305 -> 305 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/taskpanel/TabIcon_Home_Selected.pngbin790 -> 790 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/taskpanel/TabIcon_Me_Off.pngbin297 -> 297 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/taskpanel/TabIcon_Open_Off.pngbin294 -> 294 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/taskpanel/TabIcon_People_Off.pngbin367 -> 367 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/taskpanel/TabIcon_Places_Off.pngbin405 -> 405 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/taskpanel/TabIcon_Things_Off.pngbin223 -> 223 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/taskpanel/TaskPanel_Tab_Off.pngbin272 -> 272 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/taskpanel/TaskPanel_Tab_Selected.pngbin325 -> 325 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/tearoff_pressed.tgabin513 -> 513 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/tearoffbox.tgabin408 -> 408 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/textures.xml47
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/toolbar_icons/appearance.pngbin1205 -> 1205 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/toolbar_icons/avatars.pngbin1432 -> 1432 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/toolbar_icons/build.pngbin1246 -> 1246 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/toolbar_icons/caret_bottom.pngbin195 -> 195 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/toolbar_icons/caret_left.pngbin948 -> 948 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/toolbar_icons/caret_right.pngbin949 -> 949 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/toolbar_icons/chat.pngbin1277 -> 1277 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/toolbar_icons/destinations.pngbin1297 -> 1297 bytes
-rw-r--r--indra/newview/skins/default/textures/toolbar_icons/facebook.pngbin0 -> 2974 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/toolbar_icons/gestures.pngbin1675 -> 1675 bytes
-rw-r--r--indra/newview/skins/default/textures/toolbar_icons/highlighting.pngbin0 -> 457 bytes
-rw-r--r--indra/newview/skins/default/textures/toolbar_icons/highlighting_selected.pngbin0 -> 615 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/toolbar_icons/howto.pngbin1306 -> 1306 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/toolbar_icons/inventory.pngbin1114 -> 1114 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/toolbar_icons/land.pngbin1123 -> 1123 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/toolbar_icons/map.pngbin1206 -> 1206 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/toolbar_icons/marketplace.pngbin1311 -> 1311 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/toolbar_icons/mini_cart.pngbin2987 -> 2987 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/toolbar_icons/mini_map.pngbin1766 -> 1766 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/toolbar_icons/move.pngbin1328 -> 1328 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/toolbar_icons/nearbyvoice.pngbin1479 -> 1479 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/toolbar_icons/outbox.pngbin1521 -> 1521 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/toolbar_icons/people.pngbin1313 -> 1313 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/toolbar_icons/picks.pngbin1396 -> 1396 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/toolbar_icons/places.pngbin1391 -> 1391 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/toolbar_icons/preferences.pngbin1587 -> 1587 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/toolbar_icons/profile.pngbin1180 -> 1180 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/toolbar_icons/search.pngbin1406 -> 1406 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/toolbar_icons/snapshot.pngbin1142 -> 1142 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/toolbar_icons/speak.pngbin1253 -> 1253 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/toolbar_icons/view.pngbin1487 -> 1487 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/transparent.j2cbin172 -> 172 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/up_arrow.pngbin2930 -> 2930 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/uv_test1.j2cbin1206 -> 1206 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/uv_test2.tgabin1308 -> 1308 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/voice_meter_dot.j2cbin499 -> 499 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/voice_meter_rings.j2cbin2518 -> 2518 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/white.tgabin178 -> 178 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/Arrow_Down.pngbin3066 -> 3066 bytes
-rwxr-xr-xindra/newview/skins/default/textures/widgets/Arrow_Left.pngbin0 -> 311 bytes
-rwxr-xr-xindra/newview/skins/default/textures/widgets/Arrow_Right.pngbin0 -> 313 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/Arrow_Small_Left.pngbin223 -> 223 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/Arrow_Small_Right.pngbin217 -> 217 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/Arrow_Small_Up.pngbin382 -> 382 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/Arrow_Up.pngbin363 -> 363 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/Badge_Background.pngbin1352 -> 1352 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/Badge_Border.pngbin1565 -> 1565 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Left_Disabled.pngbin3576 -> 3576 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Left_Off.pngbin4309 -> 4309 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Left_Over.pngbin4272 -> 4272 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Left_Press.pngbin4278 -> 4278 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Middle_Disabled.pngbin3425 -> 3425 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Middle_Off.pngbin4151 -> 4151 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Middle_Over.pngbin4137 -> 4137 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Middle_Press.pngbin4200 -> 4200 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Right_Disabled.pngbin3169 -> 3169 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Right_Off.pngbin3845 -> 3845 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Right_Over.pngbin3867 -> 3867 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Right_Press.pngbin3915 -> 3915 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/Checkbox_Disabled.pngbin306 -> 306 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/Checkbox_Off.pngbin322 -> 322 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/Checkbox_On.pngbin577 -> 577 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/Checkbox_On_Disabled.pngbin558 -> 558 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/Checkbox_On_Press.pngbin612 -> 612 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/Checkbox_Press.pngbin373 -> 373 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/ComboButton_Disabled.pngbin450 -> 450 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/ComboButton_Hover.pngbin0 -> 459 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/ComboButton_Off.pngbin470 -> 470 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/ComboButton_On.pngbin486 -> 486 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/ComboButton_Selected.pngbin539 -> 539 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/ComboButton_UpOff.pngbin466 -> 466 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/ComboButton_UpSelected.pngbin536 -> 536 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/DisclosureArrow_Opened_Off.pngbin173 -> 173 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/DropDown_Disabled.pngbin600 -> 600 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/DropDown_Off.pngbin603 -> 603 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/DropDown_On.pngbin638 -> 638 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/DropDown_Press.pngbin679 -> 679 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/DropTarget.pngbin479 -> 479 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/Error_Tag_Background.pngbin1354 -> 1354 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/Linden_Dollar_Alert.pngbin66186 -> 66186 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/Linden_Dollar_Background.pngbin56298 -> 56298 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/ListItem_Over.pngbin244 -> 244 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/ListItem_Select.pngbin251 -> 251 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/MarketplaceBtn_Off.pngbin1067 -> 1067 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/MarketplaceBtn_Selected.pngbin1086 -> 1086 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/New_Tag_Background.pngbin957 -> 957 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/New_Tag_Border.pngbin969 -> 969 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/ProgressBar.pngbin316 -> 316 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/ProgressTrack.pngbin192 -> 192 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/PushButton_Disabled.pngbin461 -> 461 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/PushButton_Off.pngbin464 -> 464 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/PushButton_On.pngbin490 -> 490 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/PushButton_On_Selected.pngbin572 -> 572 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/PushButton_Over.pngbin457 -> 457 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/PushButton_Press.pngbin520 -> 520 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/PushButton_Selected.pngbin520 -> 520 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/PushButton_Selected_Disabled.pngbin490 -> 490 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/PushButton_Selected_Press.pngbin572 -> 572 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/RadioButton_Disabled.pngbin541 -> 541 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/RadioButton_Off.pngbin563 -> 563 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/RadioButton_On.pngbin627 -> 627 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/RadioButton_On_Disabled.pngbin605 -> 605 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/RadioButton_On_Press.pngbin641 -> 641 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/RadioButton_Press.pngbin589 -> 589 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/ScrollArrow_Down.pngbin239 -> 239 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/ScrollArrow_Down_Opaque.pngbin355 -> 355 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/ScrollArrow_Down_Over_Opaque.pngbin315 -> 315 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/ScrollArrow_Left.pngbin271 -> 271 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/ScrollArrow_Left_Opaque.pngbin311 -> 311 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/ScrollArrow_Left_Over_Opaque.pngbin330 -> 330 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/ScrollArrow_Right.pngbin260 -> 260 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/ScrollArrow_Right_Opaque.pngbin311 -> 311 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/ScrollArrow_Right_Over_Opaque.pngbin324 -> 324 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/ScrollArrow_Up.pngbin262 -> 262 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/ScrollArrow_Up_Opaque.pngbin352 -> 352 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/ScrollArrow_Up_Over_Opaque.pngbin329 -> 329 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/ScrollThumb_Horiz.pngbin364 -> 364 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/ScrollThumb_Vert.pngbin323 -> 323 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/ScrollTrack_Horiz.pngbin153 -> 153 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/ScrollTrack_Vert.pngbin150 -> 150 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Disabled.pngbin378 -> 378 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Off.pngbin386 -> 386 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Over.pngbin384 -> 384 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Press.pngbin455 -> 455 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Selected.pngbin455 -> 455 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Selected_Disabled.pngbin404 -> 404 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Selected_Over.pngbin394 -> 394 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Selected_Press.pngbin495 -> 495 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_Disabled.pngbin277 -> 277 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_Selected.pngbin359 -> 359 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_Selected_Disabled.pngbin308 -> 308 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_Selected_Press.pngbin393 -> 393 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Disabled.pngbin380 -> 380 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Off.pngbin391 -> 391 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_On_Selected.pngbin502 -> 502 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Over.pngbin398 -> 398 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Press.pngbin459 -> 459 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Selected.pngbin459 -> 459 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Selected_Disabled.pngbin420 -> 420 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Selected_Press.pngbin502 -> 502 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/SliderThumb_Disabled.pngbin475 -> 475 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/SliderThumb_Off.pngbin475 -> 475 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/SliderThumb_Press.pngbin470 -> 470 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/SliderTrack_Horiz.pngbin225 -> 225 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/SliderTrack_Vert.pngbin232 -> 232 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/Stepper_Down_Off.pngbin300 -> 300 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/Stepper_Down_Press.pngbin343 -> 343 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/Stepper_Up_Off.pngbin315 -> 315 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/Stepper_Up_Press.pngbin384 -> 384 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/TextField_Active.pngbin225 -> 225 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/TextField_Disabled.pngbin225 -> 225 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/TextField_Off.pngbin224 -> 224 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/TextField_Search_Active.pngbin923 -> 923 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/TextField_Search_Disabled.pngbin943 -> 943 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/TextField_Search_Off.pngbin958 -> 958 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/Tooltip.pngbin2910 -> 2910 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/bevel_background.pngbin365 -> 365 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/buy_off.pngbin399 -> 399 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/buy_over.pngbin415 -> 415 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/buy_press.pngbin461 -> 461 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/horizontal_drag_handle.pngbin0 -> 197 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/jump_left_in.pngbin342 -> 342 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/jump_left_out.pngbin321 -> 321 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/jump_right_in.pngbin320 -> 320 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/widgets/jump_right_out.pngbin315 -> 315 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/vertical_drag_handle.pngbin0 -> 196 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/windows/Dragbar.pngbin348 -> 348 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/windows/Flyout_Left.pngbin271 -> 271 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/windows/Flyout_Pointer.pngbin236 -> 236 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/windows/Flyout_Right.pngbin280 -> 280 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/windows/Icon_Close_Foreground.pngbin2871 -> 2871 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/windows/Icon_Close_Press.pngbin263 -> 263 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/windows/Icon_Close_Toast.pngbin460 -> 460 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/windows/Icon_Dock_Foreground.pngbin263 -> 263 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/windows/Icon_Dock_Press.pngbin263 -> 263 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/windows/Icon_Gear_Background.pngbin370 -> 370 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/windows/Icon_Gear_Foreground.pngbin371 -> 371 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/windows/Icon_Gear_Press.pngbin365 -> 365 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/windows/Icon_Help_Foreground.pngbin3084 -> 3084 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/windows/Icon_Help_Press.pngbin3062 -> 3062 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/windows/Icon_Minimize_Foreground.pngbin2839 -> 2839 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/windows/Icon_Minimize_Press.pngbin2839 -> 2839 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/windows/Icon_Restore_Foreground.pngbin2955 -> 2955 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/windows/Icon_Restore_Press.pngbin2971 -> 2971 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/windows/Icon_Undock_Foreground.pngbin268 -> 268 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/windows/Inspector_Background.pngbin348 -> 348 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/windows/Inspector_Hover.pngbin414 -> 414 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/windows/Inspector_I.pngbin548 -> 548 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/windows/Resize_Corner.pngbin137 -> 137 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/windows/Toast_Background.pngbin349 -> 349 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/windows/Toast_CloseBtn.pngbin471 -> 471 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/windows/Toast_Over.pngbin400 -> 400 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/windows/Volume_Background.pngbin589 -> 589 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/windows/Wearables_Divider.pngbin97 -> 97 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/windows/Window_Background.pngbin509 -> 509 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/windows/Window_Foreground.pngbin508 -> 508 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/windows/Window_NoTitle_Background.pngbin289 -> 289 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/windows/Window_NoTitle_Foreground.pngbin290 -> 290 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/windows/hint_arrow_down.pngbin3170 -> 3170 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/windows/hint_arrow_left.pngbin3059 -> 3059 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/windows/hint_arrow_lower_left.pngbin3081 -> 3081 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/windows/hint_arrow_right.pngbin3112 -> 3112 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/windows/hint_arrow_up.pngbin3219 -> 3219 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/windows/hint_background.pngbin4316 -> 4316 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/windows/startup_logo.pngbin2457 -> 2457 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/windows/yellow_gradient.pngbin3634 -> 3634 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/world/BeaconArrow.pngbin994 -> 994 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/world/CameraDragDot.pngbin3101 -> 3101 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/world/NoEntryLines.pngbin3523 -> 3523 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/textures/world/NoEntryPassLines.pngbin1267 -> 1267 bytes
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_about.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_about_land.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_activeim.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_animation_preview.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_auction.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_avatar_picker.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_avatar_textures.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_beacons.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_build_options.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_bulk_perms.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_bumps.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_buy_contents.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_buy_currency.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_buy_currency_html.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_buy_land.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_buy_object.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_camera.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_choose_group.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_color_picker.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_critical.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_display_name.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_event.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_font_test.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_gesture.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_god_tools.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_hardware_settings.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_help_browser.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_hud.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_im_container.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_im_session.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_image_preview.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_import_collada.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_incoming_call.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_inspect.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_inventory.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_inventory_item_properties.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_inventory_view_finder.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_joystick.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_lagmeter.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_land_holdings.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_live_lsleditor.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_lsl_guide.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_map.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_media_browser.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_media_settings.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_mem_leaking.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_model_preview.xml0
-rw-r--r--indra/newview/skins/default/xui/da/floater_model_wizard.xml241
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_moveview.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_mute_object.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_nearby_chat.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_openobject.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_outgoing_call.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_pay.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_pay_object.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_perm_prefs.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_postcard.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_preferences.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_preview_animation.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_preview_gesture.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_preview_notecard.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_preview_sound.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_preview_texture.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_price_for_listing.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_publish_classified.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_region_debug_console.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_region_info.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_report_abuse.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_script_debug.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_script_debug_panel.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_script_limits.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_script_preview.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_script_queue.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_script_search.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_search.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_select_key.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_sell_land.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_settings_debug.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_snapshot.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_sound_devices.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_sound_preview.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_stats.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_sys_well.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_telehub.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_texture_ctrl.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_tools.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_top_objects.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_tos.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_url_entry.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_voice_controls.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_voice_effect.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_web_content.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_whitelist_entry.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_window_size.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/floater_world_map.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/inspect_avatar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/inspect_group.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/inspect_object.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/inspect_remote_object.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/language_settings.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/menu_add_wearable_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/menu_attachment_other.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/menu_attachment_self.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/menu_avatar_icon.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/menu_avatar_other.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/menu_avatar_self.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/menu_bottomtray.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/menu_cof_attachment.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/menu_cof_body_part.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/menu_cof_clothing.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/menu_cof_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/menu_edit.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/menu_favorites.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/menu_gesture_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/menu_group_plus.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/menu_hide_navbar.xml0
-rw-r--r--indra/newview/skins/default/xui/da/menu_im_well_button.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/menu_imchiclet_adhoc.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/menu_imchiclet_group.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/menu_imchiclet_p2p.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/menu_inspect_avatar_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/menu_inspect_object_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/menu_inspect_self_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/menu_inv_offer_chiclet.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/menu_inventory.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/menu_inventory_add.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/menu_inventory_gear_default.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/menu_land.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/menu_landmark.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/menu_login.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/menu_media_ctrl.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/menu_mini_map.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/menu_model_import_gear_default.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/menu_navbar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/menu_nearby_chat.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/menu_notification_well_button.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/menu_object.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/menu_object_icon.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/menu_outfit_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/menu_outfit_tab.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/menu_participant_list.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/menu_people_friends_view_sort.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/menu_people_groups.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/menu_people_groups_view_sort.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/menu_people_nearby.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/menu_people_nearby_multiselect.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/menu_people_nearby_view_sort.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/menu_people_recent_view_sort.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/menu_picks.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/menu_picks_plus.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/menu_place.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/menu_place_add_button.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/menu_places_gear_folder.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/menu_places_gear_landmark.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/menu_profile_overflow.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/menu_save_outfit.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/menu_script_chiclet.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/menu_slurl.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/menu_teleport_history_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/menu_teleport_history_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/menu_teleport_history_tab.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/menu_text_editor.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/menu_topinfobar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/menu_url_agent.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/menu_url_group.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/menu_url_http.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/menu_url_inventory.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/menu_url_map.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/menu_url_objectim.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/menu_url_parcel.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/menu_url_slapp.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/menu_url_slurl.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/menu_url_teleport.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/menu_viewer.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/menu_wearable_list_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/menu_wearing_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/menu_wearing_tab.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/mime_types.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/mime_types_linux.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/mime_types_mac.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/notifications.xml1
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/outfit_accordion_tab.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_active_object_row.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_adhoc_control_panel.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_avatar_list_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_block_list_sidetray.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_body_parts_list_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_bodyparts_list_button_bar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_bottomtray.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_bottomtray_lite.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_classified_info.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_clothing_list_button_bar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_clothing_list_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_cof_wearables.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_deletable_wearable_list_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_dummy_clothing_list_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_edit_alpha.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_edit_classified.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_edit_eyes.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_edit_gloves.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_edit_hair.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_edit_jacket.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_edit_pants.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_edit_physics.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_edit_pick.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_edit_profile.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_edit_shape.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_edit_shirt.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_edit_shoes.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_edit_skin.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_edit_skirt.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_edit_socks.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_edit_tattoo.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_edit_underpants.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_edit_undershirt.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_edit_wearable.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_group_control_panel.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_group_general.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_group_info_sidetray.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_group_invite.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_group_land_money.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_group_list_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_group_notices.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_group_notify.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_group_roles.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_im_control_panel.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_inventory_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_landmark_info.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_landmarks.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_login.xml32
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_main_inventory.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_me.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_media_settings_general.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_media_settings_permissions.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_media_settings_security.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_navigation_bar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_nearby_chat_bar.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_nearby_media.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_notify_textbox.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_online_status_toast.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_outfit_edit.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_outfits_inventory.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_outfits_inventory_gear_default.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_outfits_list.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_outfits_wearing.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_people.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_pick_info.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_picks.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_place_profile.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_places.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_preferences_advanced.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_preferences_alerts.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_preferences_chat.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_preferences_colors.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_preferences_general.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_preferences_graphics1.xml10
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_preferences_move.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_preferences_privacy.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_preferences_setup.xml5
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_preferences_sound.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_prim_media_controls.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_region_covenant.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_region_debug.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_region_estate.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_region_general.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_region_terrain.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_region_texture.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_script_ed.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_script_limits_my_avatar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_script_limits_region_memory.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_scrolling_param.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_scrolling_param_base.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_side_tray.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_side_tray_tab_caption.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_sound_devices.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_stand_stop_flying.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_status_bar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_teleport_history.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_teleport_history_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_voice_effect.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/panel_world_map.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/role_actions.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/sidepanel_appearance.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/sidepanel_inventory.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/sidepanel_item_info.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/sidepanel_task_info.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/strings.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/teleport_strings.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/da/xui_version.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_about.xml23
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_about_land.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_activeim.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_animation_anim_preview.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_animation_bvh_preview.xml0
-rw-r--r--indra/newview/skins/default/xui/de/floater_animation_preview.xml188
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_auction.xml0
-rwxr-xr-xindra/newview/skins/default/xui/de/floater_autoreplace.xml32
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_avatar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_avatar_picker.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_avatar_textures.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_beacons.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_build_options.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_bulk_perms.xml7
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_bumps.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_buy_contents.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_buy_currency.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_buy_currency_html.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_buy_land.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_buy_object.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_camera.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_chat_bar.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_choose_group.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_color_picker.xml0
-rw-r--r--indra/newview/skins/default/xui/de/floater_conversation_log.xml8
-rw-r--r--indra/newview/skins/default/xui/de/floater_conversation_preview.xml7
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_critical.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_delete_env_preset.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_destinations.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_display_name.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_edit_day_cycle.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_edit_sky_preset.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_edit_water_preset.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_environment_settings.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_event.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_fast_timers.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_font_test.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_gesture.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_god_tools.xml0
-rw-r--r--indra/newview/skins/default/xui/de/floater_goto_line.xml7
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_hardware_settings.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_help_browser.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_how_to.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_hud.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_im_container.xml29
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_im_session.xml59
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_image_preview.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_import_collada.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_incoming_call.xml10
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_inspect.xml0
-rw-r--r--indra/newview/skins/default/xui/de/floater_inventory.xml16
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_inventory_item_properties.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_inventory_view_finder.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_joystick.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_lagmeter.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_land_holdings.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_live_lsleditor.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_lsl_guide.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_map.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_media_browser.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_media_settings.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_mem_leaking.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_merchant_outbox.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_model_preview.xml35
-rw-r--r--indra/newview/skins/default/xui/de/floater_model_wizard.xml208
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_moveview.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_mute_object.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_my_appearance.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_my_inventory.xml0
-rw-r--r--indra/newview/skins/default/xui/de/floater_nearby_chat.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_notification.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_notifications_console.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_object_weights.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_openobject.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_outfit_save_as.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_outgoing_call.xml0
-rwxr-xr-xindra/newview/skins/default/xui/de/floater_pathfinding_characters.xml57
-rwxr-xr-xindra/newview/skins/default/xui/de/floater_pathfinding_console.xml121
-rwxr-xr-xindra/newview/skins/default/xui/de/floater_pathfinding_linksets.xml167
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_pay.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_pay_object.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_people.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_perm_prefs.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_picks.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_places.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_post_process.xml0
-rw-r--r--indra/newview/skins/default/xui/de/floater_postcard.xml36
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_preferences.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_preferences_proxy.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_preview_animation.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_preview_gesture.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_preview_notecard.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_preview_sound.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_preview_texture.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_price_for_listing.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_publish_classified.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_region_debug_console.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_region_info.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_report_abuse.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_script_debug.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_script_debug_panel.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_script_limits.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_script_preview.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_script_queue.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_script_search.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_search.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_select_key.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_sell_land.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_settings_debug.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_snapshot.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_sound_devices.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_sound_preview.xml0
-rwxr-xr-xindra/newview/skins/default/xui/de/floater_spellcheck.xml18
-rwxr-xr-xindra/newview/skins/default/xui/de/floater_spellcheck_import.xml6
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_stats.xml9
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_sys_well.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_telehub.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_test_layout_stacks.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_test_text_vertical_aligment.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_texture_ctrl.xml32
-rwxr-xr-xindra/newview/skins/default/xui/de/floater_texture_fetch_debugger.xml77
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_tools.xml18
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_top_objects.xml14
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_tos.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_toybox.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_translation_settings.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_url_entry.xml0
-rw-r--r--indra/newview/skins/default/xui/de/floater_voice_chat_volume.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_voice_controls.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_voice_effect.xml2
-rw-r--r--indra/newview/skins/default/xui/de/floater_voice_volume.xml8
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_web_content.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_whitelist_entry.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_window_size.xml15
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/floater_world_map.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/inspect_avatar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/inspect_group.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/inspect_object.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/inspect_remote_object.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/language_settings.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/menu_add_wearable_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/menu_attachment_other.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/menu_attachment_self.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/menu_avatar_icon.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/menu_avatar_other.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/menu_avatar_self.xml2
-rw-r--r--indra/newview/skins/default/xui/de/menu_bottomtray.xml17
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/menu_cof_attachment.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/menu_cof_body_part.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/menu_cof_clothing.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/menu_cof_gear.xml6
-rw-r--r--indra/newview/skins/default/xui/de/menu_conversation.xml32
-rw-r--r--indra/newview/skins/default/xui/de/menu_conversation_log_gear.xml15
-rw-r--r--indra/newview/skins/default/xui/de/menu_conversation_log_view.xml7
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/menu_edit.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/menu_favorites.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/menu_gesture_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/menu_group_plus.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/menu_hide_navbar.xml0
-rw-r--r--indra/newview/skins/default/xui/de/menu_im_conversation.xml15
-rw-r--r--indra/newview/skins/default/xui/de/menu_im_session_showmodes.xml7
-rw-r--r--indra/newview/skins/default/xui/de/menu_im_well_button.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/menu_imchiclet_adhoc.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/menu_imchiclet_group.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/menu_imchiclet_p2p.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/menu_inspect_avatar_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/menu_inspect_object_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/menu_inspect_self_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/menu_inv_offer_chiclet.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/menu_inventory.xml1
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/menu_inventory_add.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/menu_inventory_gear_default.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/menu_land.xml1
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/menu_landmark.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/menu_login.xml8
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/menu_media_ctrl.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/menu_mini_map.xml0
-rw-r--r--indra/newview/skins/default/xui/de/menu_mode_change.xml5
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/menu_model_import_gear_default.xml0
-rw-r--r--indra/newview/skins/default/xui/de/menu_mute_particle.xml5
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/menu_navbar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/menu_nearby_chat.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/menu_notification_well_button.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/menu_object.xml3
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/menu_object_icon.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/menu_outfit_gear.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/menu_outfit_tab.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/menu_participant_list.xml0
-rw-r--r--indra/newview/skins/default/xui/de/menu_participant_view.xml13
-rw-r--r--indra/newview/skins/default/xui/de/menu_people_blocked_gear.xml5
-rw-r--r--indra/newview/skins/default/xui/de/menu_people_blocked_plus.xml5
-rw-r--r--indra/newview/skins/default/xui/de/menu_people_blocked_view.xml5
-rw-r--r--indra/newview/skins/default/xui/de/menu_people_friends_view.xml8
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/menu_people_friends_view_sort.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/menu_people_groups.xml2
-rw-r--r--indra/newview/skins/default/xui/de/menu_people_groups_view.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/menu_people_groups_view_sort.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/menu_people_nearby.xml23
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/menu_people_nearby_multiselect.xml14
-rw-r--r--indra/newview/skins/default/xui/de/menu_people_nearby_view.xml8
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/menu_people_nearby_view_sort.xml0
-rw-r--r--indra/newview/skins/default/xui/de/menu_people_recent_view.xml6
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/menu_people_recent_view_sort.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/menu_picks.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/menu_picks_plus.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/menu_place.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/menu_place_add_button.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/menu_places_gear_folder.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/menu_places_gear_landmark.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/menu_profile_overflow.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/menu_save_outfit.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/menu_script_chiclet.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/menu_slurl.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/menu_teleport_history_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/menu_teleport_history_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/menu_teleport_history_tab.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/menu_text_editor.xml7
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/menu_toolbars.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/menu_topinfobar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/menu_url_agent.xml5
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/menu_url_group.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/menu_url_http.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/menu_url_inventory.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/menu_url_map.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/menu_url_objectim.xml3
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/menu_url_parcel.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/menu_url_slapp.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/menu_url_slurl.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/menu_url_teleport.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/menu_viewer.xml58
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/menu_wearable_list_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/menu_wearing_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/menu_wearing_tab.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/mime_types.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/mime_types_linux.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/mime_types_mac.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/notifications.xml1108
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/outfit_accordion_tab.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_active_object_row.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_adhoc_control_panel.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_avatar_list_item.xml1
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_avatar_tag.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_block_list_sidetray.xml15
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_body_parts_list_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_bodyparts_list_button_bar.xml0
-rw-r--r--indra/newview/skins/default/xui/de/panel_bottomtray.xml47
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_bottomtray_lite.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_chat_header.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_chiclet_bar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_classified_info.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_clothing_list_button_bar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_clothing_list_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_cof_wearables.xml0
-rw-r--r--indra/newview/skins/default/xui/de/panel_conversation_list_item.xml8
-rw-r--r--indra/newview/skins/default/xui/de/panel_conversation_log_list_item.xml6
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_deletable_wearable_list_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_dummy_clothing_list_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_edit_alpha.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_edit_classified.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_edit_eyes.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_edit_gloves.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_edit_hair.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_edit_jacket.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_edit_pants.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_edit_physics.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_edit_pick.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_edit_profile.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_edit_shape.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_edit_shirt.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_edit_shoes.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_edit_skin.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_edit_skirt.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_edit_socks.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_edit_tattoo.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_edit_underpants.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_edit_undershirt.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_edit_wearable.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_group_control_panel.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_group_general.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_group_info_sidetray.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_group_invite.xml3
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_group_land_money.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_group_list_item.xml1
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_group_notices.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_group_notify.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_group_roles.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_im_control_panel.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_instant_message.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_inventory_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_landmark_info.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_landmarks.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_login.xml34
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_main_inventory.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_me.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_media_settings_general.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_media_settings_permissions.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_media_settings_security.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_navigation_bar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_nearby_chat.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_nearby_chat_bar.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_nearby_media.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_notifications_channel.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_notify_textbox.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_online_status_toast.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_outbox_inventory.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_outfit_edit.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_outfits_inventory.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_outfits_inventory_gear_default.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_outfits_list.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_outfits_wearing.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_people.xml91
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_pick_info.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_picks.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_place_profile.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_places.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_postcard_message.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_postcard_settings.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_preferences_advanced.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_preferences_alerts.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_preferences_chat.xml126
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_preferences_colors.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_preferences_general.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_preferences_graphics1.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_preferences_move.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_preferences_privacy.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_preferences_setup.xml1
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_preferences_sound.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_prim_media_controls.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_region_covenant.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_region_debug.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_region_environment.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_region_estate.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_region_general.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_region_terrain.xml0
-rw-r--r--indra/newview/skins/default/xui/de/panel_region_texture.xml57
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_script_ed.xml1
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_script_limits_my_avatar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_script_limits_region_memory.xml0
-rwxr-xr-xindra/newview/skins/default/xui/de/panel_script_question_toast.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_scrolling_param.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_scrolling_param_base.xml0
-rw-r--r--indra/newview/skins/default/xui/de/panel_side_tray.xml29
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_side_tray_tab_caption.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_sidetray_home_tab.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_snapshot_inventory.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_snapshot_local.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_snapshot_options.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_snapshot_postcard.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_snapshot_profile.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_sound_devices.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_stand_stop_flying.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_status_bar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_sys_well_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_teleport_history.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_teleport_history_item.xml0
-rw-r--r--indra/newview/skins/default/xui/de/panel_tools_texture.xml116
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_voice_effect.xml0
-rwxr-xr-xindra/newview/skins/default/xui/de/panel_volume_pulldown.xml15
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/panel_world_map.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/role_actions.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/sidepanel_appearance.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/sidepanel_inventory.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/sidepanel_item_info.xml3
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/sidepanel_task_info.xml10
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/strings.xml146
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/teleport_strings.xml6
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/de/xui_version.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/accordion_drag.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/accordion_parent.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/alert_button.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/alert_check_box.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/alert_icon.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/alert_line_editor.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/favorites_bar_button.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_aaa.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_about.xml23
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_about_land.xml76
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_activeim.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_animation_anim_preview.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_animation_bvh_preview.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_auction.xml0
-rwxr-xr-xindra/newview/skins/default/xui/en/floater_autoreplace.xml289
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_avatar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_avatar_picker.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_avatar_textures.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_beacons.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_build_options.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_bulk_perms.xml19
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_bumps.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_buy_contents.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_buy_currency.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_buy_currency_html.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_buy_land.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_buy_object.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_camera.xml4
-rw-r--r--indra/newview/skins/default/xui/en/floater_chat_bar.xml84
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_choose_group.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_color_picker.xml0
-rwxr-xr-xindra/newview/skins/default/xui/en/floater_conversation_log.xml84
-rwxr-xr-xindra/newview/skins/default/xui/en/floater_conversation_preview.xml64
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_critical.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_delete_env_preset.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_destinations.xml6
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_display_name.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_edit_day_cycle.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_edit_sky_preset.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_edit_water_preset.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_environment_settings.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_event.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_fast_timers.xml0
-rw-r--r--indra/newview/skins/default/xui/en/floater_fbc_web.xml9
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_font_test.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_gesture.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_god_tools.xml0
-rw-r--r--indra/newview/skins/default/xui/en/floater_goto_line.xml44
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_hardware_settings.xml22
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_help_browser.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_how_to.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_hud.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_im_container.xml206
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_im_session.xml371
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_image_preview.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_import_collada.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_incoming_call.xml58
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_inspect.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_inventory_item_properties.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_inventory_view_finder.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_joystick.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_lagmeter.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_land_holdings.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_live_lsleditor.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_lsl_guide.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_map.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_media_browser.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_media_settings.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_mem_leaking.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_merchant_outbox.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_model_preview.xml74
-rw-r--r--indra/newview/skins/default/xui/en/floater_model_wizard.xml841
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_moveview.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_mute_object.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_my_appearance.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_my_inventory.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_my_web_profile.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_notification.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_notifications_console.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_object_weights.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_openobject.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_outfit_save_as.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_outgoing_call.xml0
-rwxr-xr-xindra/newview/skins/default/xui/en/floater_pathfinding_characters.xml209
-rwxr-xr-xindra/newview/skins/default/xui/en/floater_pathfinding_console.xml419
-rwxr-xr-xindra/newview/skins/default/xui/en/floater_pathfinding_linksets.xml597
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_pay.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_pay_object.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_people.xml14
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_picks.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_places.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_post_process.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_preferences.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_preferences_proxy.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_preview_animation.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_preview_gesture.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_preview_notecard.xml1
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_preview_sound.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_preview_texture.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_price_for_listing.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_publish_classified.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_region_debug_console.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_region_info.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_report_abuse.xml1
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_script.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_script_debug.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_script_debug_panel.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_script_limits.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_script_preview.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_script_queue.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_script_search.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_search.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_select_key.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_sell_land.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_settings_debug.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_side_bar_tab.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_snapshot.xml18
-rw-r--r--indra/newview/skins/default/xui/en/floater_social.xml101
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_sound_devices.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_sound_preview.xml0
-rwxr-xr-xindra/newview/skins/default/xui/en/floater_spellcheck.xml160
-rwxr-xr-xindra/newview/skins/default/xui/en/floater_spellcheck_import.xml116
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_stats.xml100
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_sys_well.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_telehub.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_test_button.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_test_checkbox.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_test_combobox.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_test_inspectors.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_test_layout.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_test_layout_stacks.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_test_line_editor.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_test_list_view.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_test_navigation_bar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_test_radiogroup.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_test_slider.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_test_spinner.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_test_text_editor.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_test_text_vertical_aligment.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_test_textbox.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_test_toolbar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_test_widgets.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_texture_ctrl.xml10
-rwxr-xr-xindra/newview/skins/default/xui/en/floater_texture_fetch_debugger.xml428
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_tools.xml643
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_top_objects.xml62
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_tos.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_toybox.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_translation_settings.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_ui_preview.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_url_entry.xml0
-rwxr-xr-xindra/newview/skins/default/xui/en/floater_voice_chat_volume.xml48
-rw-r--r--indra/newview/skins/default/xui/en/floater_voice_controls.xml155
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_voice_effect.xml3
-rwxr-xr-xindra/newview/skins/default/xui/en/floater_voice_volume.xml59
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_web_content.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_web_profile.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_whitelist_entry.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_window_size.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/floater_world_map.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/fonts.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/inspect_avatar.xml100
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/inspect_group.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/inspect_object.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/inspect_remote_object.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/inspect_toast.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/inspector_info_ctrl.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/language_settings.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/main_view.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/menu_add_wearable_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/menu_attachment_other.xml54
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/menu_attachment_self.xml19
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/menu_avatar_icon.xml70
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/menu_avatar_other.xml58
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/menu_avatar_self.xml20
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/menu_cof_attachment.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/menu_cof_body_part.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/menu_cof_clothing.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/menu_cof_gear.xml2
-rwxr-xr-xindra/newview/skins/default/xui/en/menu_conversation.xml216
-rwxr-xr-xindra/newview/skins/default/xui/en/menu_conversation_log_gear.xml152
-rwxr-xr-xindra/newview/skins/default/xui/en/menu_conversation_log_view.xml45
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/menu_edit.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/menu_favorites.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/menu_gesture_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/menu_group_plus.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/menu_hide_navbar.xml0
-rwxr-xr-xindra/newview/skins/default/xui/en/menu_im_conversation.xml101
-rwxr-xr-xindra/newview/skins/default/xui/en/menu_im_session_showmodes.xml49
-rw-r--r--indra/newview/skins/default/xui/en/menu_im_well_button.xml16
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/menu_imchiclet_adhoc.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/menu_imchiclet_group.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/menu_imchiclet_p2p.xml0
-rw-r--r--indra/newview/skins/default/xui/en/menu_inspect_avatar_gear.xml143
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/menu_inspect_object_gear.xml2
-rw-r--r--indra/newview/skins/default/xui/en/menu_inspect_self_gear.xml252
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/menu_inv_offer_chiclet.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/menu_inventory.xml16
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/menu_inventory_add.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/menu_inventory_gear_default.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/menu_land.xml11
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/menu_landmark.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/menu_login.xml15
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/menu_media_ctrl.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/menu_mini_map.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/menu_model_import_gear_default.xml0
-rw-r--r--indra/newview/skins/default/xui/en/menu_mute_particle.xml15
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/menu_navbar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/menu_nearby_chat.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/menu_notification_well_button.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/menu_object.xml351
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/menu_object_icon.xml18
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/menu_outfit_gear.xml14
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/menu_outfit_tab.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/menu_participant_list.xml0
-rwxr-xr-xindra/newview/skins/default/xui/en/menu_participant_view.xml112
-rwxr-xr-xindra/newview/skins/default/xui/en/menu_people_blocked_gear.xml26
-rwxr-xr-xindra/newview/skins/default/xui/en/menu_people_blocked_plus.xml20
-rwxr-xr-xindra/newview/skins/default/xui/en/menu_people_blocked_view.xml26
-rwxr-xr-xindra/newview/skins/default/xui/en/menu_people_friends_view.xml53
-rw-r--r--indra/newview/skins/default/xui/en/menu_people_friends_view_sort.xml47
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/menu_people_groups.xml27
-rwxr-xr-xindra/newview/skins/default/xui/en/menu_people_groups_view.xml17
-rw-r--r--indra/newview/skins/default/xui/en/menu_people_groups_view_sort.xml26
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/menu_people_nearby.xml107
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/menu_people_nearby_multiselect.xml14
-rwxr-xr-xindra/newview/skins/default/xui/en/menu_people_nearby_view.xml53
-rw-r--r--indra/newview/skins/default/xui/en/menu_people_nearby_view_sort.xml57
-rwxr-xr-xindra/newview/skins/default/xui/en/menu_people_recent_view.xml35
-rw-r--r--indra/newview/skins/default/xui/en/menu_people_recent_view_sort.xml39
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/menu_picks.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/menu_picks_plus.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/menu_place.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/menu_place_add_button.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/menu_places_gear_folder.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/menu_places_gear_landmark.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/menu_profile_overflow.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/menu_save_outfit.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/menu_script_chiclet.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/menu_slurl.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/menu_teleport_history_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/menu_teleport_history_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/menu_teleport_history_tab.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/menu_text_editor.xml79
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/menu_toolbars.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/menu_topinfobar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/menu_url_agent.xml27
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/menu_url_group.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/menu_url_http.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/menu_url_inventory.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/menu_url_map.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/menu_url_objectim.xml9
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/menu_url_parcel.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/menu_url_slapp.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/menu_url_slurl.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/menu_url_teleport.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/menu_viewer.xml533
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/menu_wearable_list_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/menu_wearing_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/menu_wearing_tab.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/mime_types.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/mime_types_linux.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/mime_types_mac.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/notification_visibility.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/notifications.xml2787
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/outfit_accordion_tab.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_active_object_row.xml0
-rw-r--r--indra/newview/skins/default/xui/en/panel_activeim_row.xml97
-rw-r--r--indra/newview/skins/default/xui/en/panel_adhoc_control_panel.xml95
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_avatar_list_item.xml1
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_avatar_tag.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_block_list_sidetray.xml163
-rwxr-xr-xindra/newview/skins/default/xui/en/panel_blocked_list_item.xml71
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_body_parts_list_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_bodyparts_list_button_bar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_bottomtray_lite.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_chat_header.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_chat_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_chat_separator.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_chiclet_bar.xml48
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_classified_info.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_classifieds_list_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_clothing_list_button_bar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_clothing_list_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_cof_wearables.xml0
-rwxr-xr-xindra/newview/skins/default/xui/en/panel_conversation_list_item.xml98
-rwxr-xr-xindra/newview/skins/default/xui/en/panel_conversation_log_list_item.xml107
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_deletable_wearable_list_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_dummy_clothing_list_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_edit_alpha.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_edit_classified.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_edit_eyes.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_edit_gloves.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_edit_hair.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_edit_jacket.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_edit_pants.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_edit_physics.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_edit_pick.xml1
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_edit_profile.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_edit_shape.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_edit_shirt.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_edit_shoes.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_edit_skin.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_edit_skirt.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_edit_socks.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_edit_tattoo.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_edit_underpants.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_edit_undershirt.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_edit_wearable.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_generic_tip.xml0
-rw-r--r--indra/newview/skins/default/xui/en/panel_group_control_panel.xml109
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_group_general.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_group_invite.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_group_land_money.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_group_list_item.xml1
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_group_notices.xml8
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_group_notify.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_group_roles.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_hint.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_hint_image.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_hud.xml0
-rw-r--r--indra/newview/skins/default/xui/en/panel_im_control_panel.xml166
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_inbox_inventory.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_instant_message.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_inventory_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_landmark_info.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_landmarks.xml16
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_login.xml475
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_main_inventory.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_me.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_media_settings_general.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_media_settings_permissions.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_media_settings_security.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_navigation_bar.xml3
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_nearby_chat.xml22
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml3
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_nearby_media.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_notification.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_notifications_channel.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_notify_textbox.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_online_status_toast.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_outbox_inventory.xml25
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_outfit_edit.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_outfits_inventory.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_outfits_inventory_gear_default.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_outfits_list.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_outfits_wearing.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_people.xml957
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_pick_info.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_pick_list_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_picks.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_place_profile.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_places.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_postcard_message.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_postcard_settings.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_preferences_advanced.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_preferences_alerts.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_preferences_chat.xml772
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_preferences_colors.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_preferences_general.xml6
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml155
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_preferences_move.xml12
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_preferences_privacy.xml226
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_preferences_setup.xml12
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_preferences_sound.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_prim_media_controls.xml26
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_progress.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_region_covenant.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_region_debug.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_region_environment.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_region_estate.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_region_general.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_region_terrain.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_script_ed.xml5
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_script_limits_my_avatar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_script_limits_region_memory.xml0
-rwxr-xr-xindra/newview/skins/default/xui/en/panel_script_question_toast.xml55
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_scrolling_param.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_scrolling_param_base.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_side_tray_tab_caption.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_sidetray_home_tab.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_snapshot_inventory.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_snapshot_local.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_snapshot_options.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_snapshot_postcard.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_snapshot_profile.xml0
-rw-r--r--indra/newview/skins/default/xui/en/panel_social_account.xml75
-rw-r--r--indra/newview/skins/default/xui/en/panel_social_photo.xml152
-rw-r--r--indra/newview/skins/default/xui/en/panel_social_place.xml132
-rw-r--r--indra/newview/skins/default/xui/en/panel_social_status.xml67
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_sound_devices.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_stand_stop_flying.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_status_bar.xml3
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_sys_well_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_teleport_history.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_teleport_history_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_toast.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_toolbar_view.xml4
-rw-r--r--indra/newview/skins/default/xui/en/panel_tools_texture.xml766
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_topinfo_bar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_voice_effect.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_volume_pulldown.xml318
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/panel_world_map.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/role_actions.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/sidepanel_appearance.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/sidepanel_inventory.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/sidepanel_item_info.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/sidepanel_task_info.xml42
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/strings.xml337
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/teleport_strings.xml8
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/accordion.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/accordion_tab.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/avatar_icon.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/avatar_list_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/badge.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/bodyparts_list_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/button.xml0
-rwxr-xr-xindra/newview/skins/default/xui/en/widgets/chat_editor.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/chat_history.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/check_box.xml0
-rw-r--r--indra/newview/skins/default/xui/en/widgets/chiclet_im_adhoc.xml55
-rw-r--r--indra/newview/skins/default/xui/en/widgets/chiclet_im_group.xml56
-rw-r--r--indra/newview/skins/default/xui/en/widgets/chiclet_im_p2p.xml56
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/chiclet_offer.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/chiclet_panel.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/chiclet_script.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/clothing_list_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/color_swatch.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/combo_box.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/context_menu.xml0
-rw-r--r--indra/newview/skins/default/xui/en/widgets/conversation_view_participant.xml42
-rwxr-xr-xindra/newview/skins/default/xui/en/widgets/conversation_view_session.xml16
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/deletable_wearable_list_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/drop_down.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/dummy_clothing_list_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/expandable_text.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/filter_editor.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/flat_list_view.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/floater.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/flyout_button.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/folder_view_item.xml8
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/gesture_combo_list.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/group_icon.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/hint_popup.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/icon.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/inbox_folder_view_folder.xml8
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/inbox_folder_view_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/inbox_inventory_panel.xml3
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/inspector.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/inventory_list_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/inventory_panel.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/joystick_rotate.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/layout_stack.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/line_editor.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/list_view.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/loading_indicator.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/location_input.xml17
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/menu.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/menu_bar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/menu_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/menu_item_call.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/menu_item_check.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/menu_item_separator.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/menu_item_tear_off.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/multi_slider.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/multi_slider_bar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/name_editor.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/name_list.xml0
-rw-r--r--indra/newview/skins/default/xui/en/widgets/outbox_folder_view_folder.xml9
-rw-r--r--indra/newview/skins/default/xui/en/widgets/outbox_inventory_panel.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/output_monitor.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/panel.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/panel_camera_item.xml0
-rw-r--r--indra/newview/skins/default/xui/en/widgets/person_tab_view.xml13
-rw-r--r--indra/newview/skins/default/xui/en/widgets/person_view.xml127
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/progress_bar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/radio_group.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/radio_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/scroll_bar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/scroll_column_header.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/scroll_container.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/scroll_list.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/scrolling_panel_list.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/search_combo_box.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/search_editor.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/side_tray.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/sidetray_tab.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/simple_text_editor.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/slider.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/slider_bar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/spinner.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/split_button.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/tab_container.xml15
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/talk_button.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/teleport_history_menu_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/text.xml1
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/text_editor.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/textbase.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/texture_picker.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/time.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/toggleable_menu.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/tool_tip.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/toolbar.xml12
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/ui_ctrl.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/view_border.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/web_browser.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/widgets/window_shade.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/en/xui_version.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_about.xml23
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_about_land.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_activeim.xml0
-rw-r--r--indra/newview/skins/default/xui/es/floater_animation_preview.xml187
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_auction.xml0
-rwxr-xr-xindra/newview/skins/default/xui/es/floater_autoreplace.xml32
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_avatar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_avatar_picker.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_avatar_textures.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_beacons.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_build_options.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_bulk_perms.xml7
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_bumps.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_buy_contents.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_buy_currency.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_buy_currency_html.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_buy_land.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_buy_object.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_camera.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_chat_bar.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_choose_group.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_color_picker.xml0
-rw-r--r--indra/newview/skins/default/xui/es/floater_conversation_log.xml8
-rw-r--r--indra/newview/skins/default/xui/es/floater_conversation_preview.xml7
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_critical.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_delete_env_preset.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_destinations.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_display_name.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_edit_day_cycle.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_edit_sky_preset.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_edit_water_preset.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_environment_settings.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_event.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_fast_timers.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_font_test.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_gesture.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_god_tools.xml0
-rw-r--r--indra/newview/skins/default/xui/es/floater_goto_line.xml7
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_hardware_settings.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_help_browser.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_how_to.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_hud.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_im_container.xml29
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_im_session.xml59
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_image_preview.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_import_collada.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_incoming_call.xml10
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_inspect.xml0
-rw-r--r--indra/newview/skins/default/xui/es/floater_inventory.xml16
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_inventory_item_properties.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_inventory_view_finder.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_joystick.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_lagmeter.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_land_holdings.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_live_lsleditor.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_lsl_guide.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_map.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_media_browser.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_media_settings.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_mem_leaking.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_merchant_outbox.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_model_preview.xml35
-rw-r--r--indra/newview/skins/default/xui/es/floater_model_wizard.xml208
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_moveview.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_mute_object.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_my_appearance.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_my_inventory.xml0
-rw-r--r--indra/newview/skins/default/xui/es/floater_nearby_chat.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_object_weights.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_openobject.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_outfit_save_as.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_outgoing_call.xml0
-rwxr-xr-xindra/newview/skins/default/xui/es/floater_pathfinding_characters.xml57
-rwxr-xr-xindra/newview/skins/default/xui/es/floater_pathfinding_console.xml121
-rwxr-xr-xindra/newview/skins/default/xui/es/floater_pathfinding_linksets.xml167
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_pay.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_pay_object.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_people.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_perm_prefs.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_picks.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_places.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_post_process.xml0
-rw-r--r--indra/newview/skins/default/xui/es/floater_postcard.xml37
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_preferences.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_preferences_proxy.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_preview_animation.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_preview_gesture.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_preview_notecard.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_preview_sound.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_preview_texture.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_price_for_listing.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_publish_classified.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_region_debug_console.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_region_info.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_report_abuse.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_script_debug.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_script_debug_panel.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_script_limits.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_script_preview.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_script_queue.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_script_search.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_search.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_select_key.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_sell_land.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_settings_debug.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_snapshot.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_sound_devices.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_sound_preview.xml0
-rwxr-xr-xindra/newview/skins/default/xui/es/floater_spellcheck.xml18
-rwxr-xr-xindra/newview/skins/default/xui/es/floater_spellcheck_import.xml6
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_stats.xml9
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_sys_well.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_telehub.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_test_layout_stacks.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_texture_ctrl.xml32
-rwxr-xr-xindra/newview/skins/default/xui/es/floater_texture_fetch_debugger.xml77
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_tools.xml18
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_top_objects.xml10
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_tos.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_toybox.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_translation_settings.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_url_entry.xml0
-rw-r--r--indra/newview/skins/default/xui/es/floater_voice_chat_volume.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_voice_controls.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_voice_effect.xml2
-rw-r--r--indra/newview/skins/default/xui/es/floater_voice_volume.xml8
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_web_content.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_whitelist_entry.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_window_size.xml15
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/floater_world_map.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/inspect_avatar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/inspect_group.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/inspect_object.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/inspect_remote_object.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/language_settings.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/menu_add_wearable_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/menu_attachment_other.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/menu_attachment_self.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/menu_avatar_icon.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/menu_avatar_other.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/menu_avatar_self.xml2
-rw-r--r--indra/newview/skins/default/xui/es/menu_bottomtray.xml17
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/menu_cof_attachment.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/menu_cof_body_part.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/menu_cof_clothing.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/menu_cof_gear.xml6
-rw-r--r--indra/newview/skins/default/xui/es/menu_conversation.xml32
-rw-r--r--indra/newview/skins/default/xui/es/menu_conversation_log_gear.xml15
-rw-r--r--indra/newview/skins/default/xui/es/menu_conversation_log_view.xml7
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/menu_edit.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/menu_favorites.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/menu_gesture_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/menu_group_plus.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/menu_hide_navbar.xml0
-rw-r--r--indra/newview/skins/default/xui/es/menu_im_conversation.xml15
-rw-r--r--indra/newview/skins/default/xui/es/menu_im_session_showmodes.xml7
-rw-r--r--indra/newview/skins/default/xui/es/menu_im_well_button.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/menu_imchiclet_adhoc.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/menu_imchiclet_group.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/menu_imchiclet_p2p.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/menu_inspect_avatar_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/menu_inspect_object_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/menu_inspect_self_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/menu_inv_offer_chiclet.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/menu_inventory.xml1
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/menu_inventory_add.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/menu_inventory_gear_default.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/menu_land.xml1
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/menu_landmark.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/menu_login.xml8
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/menu_media_ctrl.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/menu_mini_map.xml0
-rw-r--r--indra/newview/skins/default/xui/es/menu_mode_change.xml5
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/menu_model_import_gear_default.xml0
-rw-r--r--indra/newview/skins/default/xui/es/menu_mute_particle.xml5
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/menu_navbar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/menu_nearby_chat.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/menu_notification_well_button.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/menu_object.xml3
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/menu_object_icon.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/menu_outfit_gear.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/menu_outfit_tab.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/menu_participant_list.xml0
-rw-r--r--indra/newview/skins/default/xui/es/menu_participant_view.xml13
-rw-r--r--indra/newview/skins/default/xui/es/menu_people_blocked_gear.xml5
-rw-r--r--indra/newview/skins/default/xui/es/menu_people_blocked_plus.xml5
-rw-r--r--indra/newview/skins/default/xui/es/menu_people_blocked_view.xml5
-rw-r--r--indra/newview/skins/default/xui/es/menu_people_friends_view.xml8
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/menu_people_friends_view_sort.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/menu_people_groups.xml2
-rw-r--r--indra/newview/skins/default/xui/es/menu_people_groups_view.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/menu_people_groups_view_sort.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/menu_people_nearby.xml23
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/menu_people_nearby_multiselect.xml14
-rw-r--r--indra/newview/skins/default/xui/es/menu_people_nearby_view.xml8
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/menu_people_nearby_view_sort.xml0
-rw-r--r--indra/newview/skins/default/xui/es/menu_people_recent_view.xml6
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/menu_people_recent_view_sort.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/menu_picks.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/menu_picks_plus.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/menu_place.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/menu_place_add_button.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/menu_places_gear_folder.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/menu_places_gear_landmark.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/menu_profile_overflow.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/menu_save_outfit.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/menu_script_chiclet.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/menu_slurl.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/menu_teleport_history_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/menu_teleport_history_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/menu_teleport_history_tab.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/menu_text_editor.xml7
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/menu_toolbars.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/menu_topinfobar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/menu_url_agent.xml5
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/menu_url_group.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/menu_url_http.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/menu_url_inventory.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/menu_url_map.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/menu_url_objectim.xml3
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/menu_url_parcel.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/menu_url_slapp.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/menu_url_slurl.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/menu_url_teleport.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/menu_viewer.xml60
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/menu_wearable_list_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/menu_wearing_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/menu_wearing_tab.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/mime_types.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/mime_types_linux.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/mime_types_mac.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/notifications.xml1140
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/outfit_accordion_tab.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_active_object_row.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_adhoc_control_panel.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_avatar_list_item.xml1
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_block_list_sidetray.xml15
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_body_parts_list_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_bodyparts_list_button_bar.xml0
-rw-r--r--indra/newview/skins/default/xui/es/panel_bottomtray.xml47
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_bottomtray_lite.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_chiclet_bar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_classified_info.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_clothing_list_button_bar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_clothing_list_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_cof_wearables.xml0
-rw-r--r--indra/newview/skins/default/xui/es/panel_conversation_list_item.xml8
-rw-r--r--indra/newview/skins/default/xui/es/panel_conversation_log_list_item.xml6
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_deletable_wearable_list_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_dummy_clothing_list_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_edit_alpha.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_edit_classified.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_edit_eyes.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_edit_gloves.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_edit_hair.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_edit_jacket.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_edit_pants.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_edit_physics.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_edit_pick.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_edit_profile.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_edit_shape.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_edit_shirt.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_edit_shoes.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_edit_skin.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_edit_skirt.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_edit_socks.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_edit_tattoo.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_edit_underpants.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_edit_undershirt.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_edit_wearable.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_group_control_panel.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_group_general.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_group_info_sidetray.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_group_invite.xml3
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_group_land_money.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_group_list_item.xml1
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_group_notices.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_group_notify.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_group_roles.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_im_control_panel.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_inventory_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_landmark_info.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_landmarks.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_login.xml34
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_main_inventory.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_me.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_media_settings_general.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_media_settings_permissions.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_media_settings_security.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_navigation_bar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_nearby_chat.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_nearby_chat_bar.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_nearby_media.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_notify_textbox.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_online_status_toast.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_outbox_inventory.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_outfit_edit.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_outfits_inventory.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_outfits_inventory_gear_default.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_outfits_list.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_outfits_wearing.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_people.xml91
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_pick_info.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_picks.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_place_profile.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_places.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_postcard_message.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_postcard_settings.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_preferences_advanced.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_preferences_alerts.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_preferences_chat.xml126
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_preferences_colors.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_preferences_general.xml5
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_preferences_graphics1.xml10
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_preferences_move.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_preferences_privacy.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_preferences_setup.xml3
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_preferences_sound.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_prim_media_controls.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_region_covenant.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_region_debug.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_region_environment.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_region_estate.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_region_general.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_region_terrain.xml0
-rw-r--r--indra/newview/skins/default/xui/es/panel_region_texture.xml57
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_script_ed.xml1
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_script_limits_my_avatar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_script_limits_region_memory.xml0
-rwxr-xr-xindra/newview/skins/default/xui/es/panel_script_question_toast.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_scrolling_param.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_scrolling_param_base.xml0
-rw-r--r--indra/newview/skins/default/xui/es/panel_side_tray.xml29
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_side_tray_tab_caption.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_snapshot_inventory.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_snapshot_local.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_snapshot_options.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_snapshot_postcard.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_snapshot_profile.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_sound_devices.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_stand_stop_flying.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_status_bar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_teleport_history.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_teleport_history_item.xml0
-rw-r--r--indra/newview/skins/default/xui/es/panel_tools_texture.xml116
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_voice_effect.xml0
-rwxr-xr-xindra/newview/skins/default/xui/es/panel_volume_pulldown.xml14
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/panel_world_map.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/role_actions.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/sidepanel_appearance.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/sidepanel_inventory.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/sidepanel_item_info.xml3
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/sidepanel_task_info.xml10
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/strings.xml147
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/teleport_strings.xml6
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/es/xui_version.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_about.xml25
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_about_land.xml10
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_activeim.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_animation_anim_preview.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_animation_bvh_preview.xml0
-rw-r--r--indra/newview/skins/default/xui/fr/floater_animation_preview.xml189
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_auction.xml0
-rwxr-xr-xindra/newview/skins/default/xui/fr/floater_autoreplace.xml32
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_avatar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_avatar_picker.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_avatar_textures.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_beacons.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_build_options.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_bulk_perms.xml7
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_bumps.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_buy_contents.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_buy_currency.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_buy_currency_html.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_buy_land.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_buy_object.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_camera.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_chat_bar.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_choose_group.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_color_picker.xml0
-rw-r--r--indra/newview/skins/default/xui/fr/floater_conversation_log.xml8
-rw-r--r--indra/newview/skins/default/xui/fr/floater_conversation_preview.xml7
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_critical.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_delete_env_preset.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_destinations.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_display_name.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_edit_day_cycle.xml10
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_edit_sky_preset.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_edit_water_preset.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_environment_settings.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_event.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_fast_timers.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_font_test.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_gesture.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_god_tools.xml4
-rw-r--r--indra/newview/skins/default/xui/fr/floater_goto_line.xml7
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_hardware_settings.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_help_browser.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_how_to.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_hud.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_im_container.xml29
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_im_session.xml59
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_image_preview.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_import_collada.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_incoming_call.xml10
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_inspect.xml0
-rw-r--r--indra/newview/skins/default/xui/fr/floater_inventory.xml16
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_inventory_item_properties.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_inventory_view_finder.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_joystick.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_lagmeter.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_land_holdings.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_live_lsleditor.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_lsl_guide.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_map.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_media_browser.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_media_settings.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_mem_leaking.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_merchant_outbox.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_model_preview.xml51
-rw-r--r--indra/newview/skins/default/xui/fr/floater_model_wizard.xml208
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_moveview.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_mute_object.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_my_appearance.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_my_inventory.xml0
-rw-r--r--indra/newview/skins/default/xui/fr/floater_nearby_chat.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_notification.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_notifications_console.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_object_weights.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_openobject.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_outfit_save_as.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_outgoing_call.xml0
-rwxr-xr-xindra/newview/skins/default/xui/fr/floater_pathfinding_characters.xml57
-rwxr-xr-xindra/newview/skins/default/xui/fr/floater_pathfinding_console.xml121
-rwxr-xr-xindra/newview/skins/default/xui/fr/floater_pathfinding_linksets.xml167
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_pay.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_pay_object.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_people.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_perm_prefs.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_picks.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_places.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_post_process.xml0
-rw-r--r--indra/newview/skins/default/xui/fr/floater_postcard.xml36
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_preferences.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_preferences_proxy.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_preview_animation.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_preview_gesture.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_preview_notecard.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_preview_sound.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_preview_texture.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_price_for_listing.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_publish_classified.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_region_debug_console.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_region_info.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_report_abuse.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_script_debug.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_script_debug_panel.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_script_limits.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_script_preview.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_script_queue.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_script_search.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_search.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_select_key.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_sell_land.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_settings_debug.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_snapshot.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_sound_devices.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_sound_preview.xml0
-rwxr-xr-xindra/newview/skins/default/xui/fr/floater_spellcheck.xml18
-rwxr-xr-xindra/newview/skins/default/xui/fr/floater_spellcheck_import.xml6
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_stats.xml11
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_sys_well.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_telehub.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_test_layout_stacks.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_test_text_vertical_aligment.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_texture_ctrl.xml32
-rwxr-xr-xindra/newview/skins/default/xui/fr/floater_texture_fetch_debugger.xml77
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_tools.xml20
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_top_objects.xml22
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_tos.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_toybox.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_translation_settings.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_url_entry.xml0
-rw-r--r--indra/newview/skins/default/xui/fr/floater_voice_chat_volume.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_voice_controls.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_voice_effect.xml2
-rw-r--r--indra/newview/skins/default/xui/fr/floater_voice_volume.xml8
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_web_content.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_whitelist_entry.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_window_size.xml15
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/floater_world_map.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/fonts.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/inspect_avatar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/inspect_group.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/inspect_object.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/inspect_remote_object.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/language_settings.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/menu_add_wearable_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/menu_attachment_other.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/menu_attachment_self.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/menu_avatar_icon.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/menu_avatar_other.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/menu_avatar_self.xml2
-rw-r--r--indra/newview/skins/default/xui/fr/menu_bottomtray.xml17
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/menu_cof_attachment.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/menu_cof_body_part.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/menu_cof_clothing.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/menu_cof_gear.xml6
-rw-r--r--indra/newview/skins/default/xui/fr/menu_conversation.xml32
-rw-r--r--indra/newview/skins/default/xui/fr/menu_conversation_log_gear.xml15
-rw-r--r--indra/newview/skins/default/xui/fr/menu_conversation_log_view.xml7
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/menu_edit.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/menu_favorites.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/menu_gesture_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/menu_group_plus.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/menu_hide_navbar.xml0
-rw-r--r--indra/newview/skins/default/xui/fr/menu_im_conversation.xml15
-rw-r--r--indra/newview/skins/default/xui/fr/menu_im_session_showmodes.xml7
-rw-r--r--indra/newview/skins/default/xui/fr/menu_im_well_button.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/menu_imchiclet_adhoc.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/menu_imchiclet_group.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/menu_imchiclet_p2p.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/menu_inspect_avatar_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/menu_inspect_object_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/menu_inspect_self_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/menu_inv_offer_chiclet.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/menu_inventory.xml1
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/menu_inventory_add.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/menu_inventory_gear_default.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/menu_land.xml1
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/menu_landmark.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/menu_login.xml8
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/menu_media_ctrl.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/menu_mini_map.xml0
-rw-r--r--indra/newview/skins/default/xui/fr/menu_mode_change.xml5
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/menu_model_import_gear_default.xml0
-rw-r--r--indra/newview/skins/default/xui/fr/menu_mute_particle.xml5
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/menu_navbar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/menu_nearby_chat.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/menu_notification_well_button.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/menu_object.xml3
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/menu_object_icon.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/menu_outfit_gear.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/menu_outfit_tab.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/menu_participant_list.xml0
-rw-r--r--indra/newview/skins/default/xui/fr/menu_participant_view.xml13
-rw-r--r--indra/newview/skins/default/xui/fr/menu_people_blocked_gear.xml5
-rw-r--r--indra/newview/skins/default/xui/fr/menu_people_blocked_plus.xml5
-rw-r--r--indra/newview/skins/default/xui/fr/menu_people_blocked_view.xml5
-rw-r--r--indra/newview/skins/default/xui/fr/menu_people_friends_view.xml8
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/menu_people_friends_view_sort.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/menu_people_groups.xml2
-rw-r--r--indra/newview/skins/default/xui/fr/menu_people_groups_view.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/menu_people_groups_view_sort.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/menu_people_nearby.xml23
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/menu_people_nearby_multiselect.xml14
-rw-r--r--indra/newview/skins/default/xui/fr/menu_people_nearby_view.xml8
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/menu_people_nearby_view_sort.xml0
-rw-r--r--indra/newview/skins/default/xui/fr/menu_people_recent_view.xml6
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/menu_people_recent_view_sort.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/menu_picks.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/menu_picks_plus.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/menu_place.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/menu_place_add_button.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/menu_places_gear_folder.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/menu_places_gear_landmark.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/menu_profile_overflow.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/menu_save_outfit.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/menu_script_chiclet.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/menu_slurl.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/menu_teleport_history_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/menu_teleport_history_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/menu_teleport_history_tab.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/menu_text_editor.xml7
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/menu_toolbars.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/menu_topinfobar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/menu_url_agent.xml5
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/menu_url_group.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/menu_url_http.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/menu_url_inventory.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/menu_url_map.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/menu_url_objectim.xml3
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/menu_url_parcel.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/menu_url_slapp.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/menu_url_slurl.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/menu_url_teleport.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/menu_viewer.xml68
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/menu_wearable_list_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/menu_wearing_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/menu_wearing_tab.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/mime_types.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/mime_types_linux.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/mime_types_mac.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/notifications.xml1111
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/outfit_accordion_tab.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_active_object_row.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_adhoc_control_panel.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_avatar_list_item.xml1
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_avatar_tag.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_block_list_sidetray.xml15
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_body_parts_list_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_bodyparts_list_button_bar.xml0
-rw-r--r--indra/newview/skins/default/xui/fr/panel_bottomtray.xml47
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_bottomtray_lite.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_chat_header.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_chiclet_bar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_classified_info.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_clothing_list_button_bar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_clothing_list_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_cof_wearables.xml0
-rw-r--r--indra/newview/skins/default/xui/fr/panel_conversation_list_item.xml8
-rw-r--r--indra/newview/skins/default/xui/fr/panel_conversation_log_list_item.xml6
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_deletable_wearable_list_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_dummy_clothing_list_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_edit_alpha.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_edit_classified.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_edit_eyes.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_edit_gloves.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_edit_hair.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_edit_jacket.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_edit_pants.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_edit_physics.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_edit_pick.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_edit_profile.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_edit_shape.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_edit_shirt.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_edit_shoes.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_edit_skin.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_edit_skirt.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_edit_socks.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_edit_tattoo.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_edit_underpants.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_edit_undershirt.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_edit_wearable.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_group_control_panel.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_group_general.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_group_info_sidetray.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_group_invite.xml3
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_group_land_money.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_group_list_item.xml1
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_group_notices.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_group_notify.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_group_roles.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_im_control_panel.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_instant_message.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_inventory_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_landmark_info.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_landmarks.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_login.xml34
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_main_inventory.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_me.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_media_settings_general.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_media_settings_permissions.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_media_settings_security.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_navigation_bar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_nearby_chat.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_nearby_chat_bar.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_nearby_media.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_notifications_channel.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_notify_textbox.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_online_status_toast.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_outbox_inventory.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_outfit_edit.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_outfits_inventory.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_outfits_inventory_gear_default.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_outfits_list.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_outfits_wearing.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_people.xml91
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_pick_info.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_picks.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_place_profile.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_places.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_postcard_message.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_postcard_settings.xml6
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_preferences_advanced.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_preferences_alerts.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_preferences_chat.xml126
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_preferences_colors.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_preferences_general.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_preferences_graphics1.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_preferences_move.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_preferences_privacy.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_preferences_setup.xml1
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_preferences_sound.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_prim_media_controls.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_region_covenant.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_region_debug.xml6
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_region_environment.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_region_estate.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_region_general.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_region_terrain.xml4
-rw-r--r--indra/newview/skins/default/xui/fr/panel_region_texture.xml72
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_script_ed.xml1
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_script_limits_my_avatar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_script_limits_region_memory.xml0
-rwxr-xr-xindra/newview/skins/default/xui/fr/panel_script_question_toast.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_scrolling_param.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_scrolling_param_base.xml0
-rw-r--r--indra/newview/skins/default/xui/fr/panel_side_tray.xml29
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_side_tray_tab_caption.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_sidetray_home_tab.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_snapshot_inventory.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_snapshot_local.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_snapshot_options.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_snapshot_postcard.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_snapshot_profile.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_sound_devices.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_stand_stop_flying.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_status_bar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_sys_well_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_teleport_history.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_teleport_history_item.xml0
-rw-r--r--indra/newview/skins/default/xui/fr/panel_tools_texture.xml116
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_voice_effect.xml0
-rwxr-xr-xindra/newview/skins/default/xui/fr/panel_volume_pulldown.xml14
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/panel_world_map.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/role_actions.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/sidepanel_appearance.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/sidepanel_inventory.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/sidepanel_item_info.xml3
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/sidepanel_task_info.xml10
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/strings.xml150
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/teleport_strings.xml6
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/fr/xui_version.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_about.xml23
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_about_land.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_activeim.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_animation_anim_preview.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_animation_bvh_preview.xml0
-rw-r--r--indra/newview/skins/default/xui/it/floater_animation_preview.xml187
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_auction.xml0
-rwxr-xr-xindra/newview/skins/default/xui/it/floater_autoreplace.xml32
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_avatar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_avatar_picker.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_avatar_textures.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_beacons.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_build_options.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_bulk_perms.xml7
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_bumps.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_buy_contents.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_buy_currency.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_buy_currency_html.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_buy_land.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_buy_object.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_camera.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_chat_bar.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_choose_group.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_color_picker.xml0
-rw-r--r--indra/newview/skins/default/xui/it/floater_conversation_log.xml8
-rw-r--r--indra/newview/skins/default/xui/it/floater_conversation_preview.xml7
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_critical.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_delete_env_preset.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_destinations.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_display_name.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_edit_day_cycle.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_edit_sky_preset.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_edit_water_preset.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_environment_settings.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_event.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_fast_timers.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_font_test.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_gesture.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_god_tools.xml0
-rw-r--r--indra/newview/skins/default/xui/it/floater_goto_line.xml7
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_hardware_settings.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_help_browser.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_how_to.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_hud.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_im_container.xml29
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_im_session.xml59
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_image_preview.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_import_collada.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_incoming_call.xml10
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_inspect.xml0
-rw-r--r--indra/newview/skins/default/xui/it/floater_inventory.xml16
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_inventory_item_properties.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_inventory_view_finder.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_joystick.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_lagmeter.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_land_holdings.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_live_lsleditor.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_lsl_guide.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_map.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_media_browser.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_media_settings.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_mem_leaking.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_merchant_outbox.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_model_preview.xml35
-rw-r--r--indra/newview/skins/default/xui/it/floater_model_wizard.xml208
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_moveview.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_mute_object.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_my_appearance.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_my_inventory.xml0
-rw-r--r--indra/newview/skins/default/xui/it/floater_nearby_chat.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_object_weights.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_openobject.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_outfit_save_as.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_outgoing_call.xml0
-rwxr-xr-xindra/newview/skins/default/xui/it/floater_pathfinding_characters.xml57
-rwxr-xr-xindra/newview/skins/default/xui/it/floater_pathfinding_console.xml121
-rwxr-xr-xindra/newview/skins/default/xui/it/floater_pathfinding_linksets.xml167
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_pay.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_pay_object.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_people.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_perm_prefs.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_picks.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_places.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_post_process.xml0
-rw-r--r--indra/newview/skins/default/xui/it/floater_postcard.xml40
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_preferences.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_preferences_proxy.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_preview_animation.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_preview_gesture.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_preview_notecard.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_preview_sound.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_preview_texture.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_price_for_listing.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_publish_classified.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_region_debug_console.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_region_info.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_report_abuse.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_script_debug.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_script_debug_panel.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_script_limits.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_script_preview.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_script_queue.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_script_search.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_search.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_select_key.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_sell_land.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_settings_debug.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_snapshot.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_sound_devices.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_sound_preview.xml0
-rwxr-xr-xindra/newview/skins/default/xui/it/floater_spellcheck.xml18
-rwxr-xr-xindra/newview/skins/default/xui/it/floater_spellcheck_import.xml6
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_stats.xml9
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_sys_well.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_telehub.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_test_layout_stacks.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_test_text_vertical_aligment.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_texture_ctrl.xml32
-rwxr-xr-xindra/newview/skins/default/xui/it/floater_texture_fetch_debugger.xml77
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_tools.xml18
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_top_objects.xml10
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_tos.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_toybox.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_translation_settings.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_url_entry.xml0
-rw-r--r--indra/newview/skins/default/xui/it/floater_voice_chat_volume.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_voice_controls.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_voice_effect.xml2
-rw-r--r--indra/newview/skins/default/xui/it/floater_voice_volume.xml8
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_web_content.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_whitelist_entry.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_window_size.xml15
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/floater_world_map.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/inspect_avatar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/inspect_group.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/inspect_object.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/inspect_remote_object.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/language_settings.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/menu_add_wearable_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/menu_attachment_other.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/menu_attachment_self.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/menu_avatar_icon.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/menu_avatar_other.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/menu_avatar_self.xml2
-rw-r--r--indra/newview/skins/default/xui/it/menu_bottomtray.xml17
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/menu_cof_attachment.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/menu_cof_body_part.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/menu_cof_clothing.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/menu_cof_gear.xml6
-rw-r--r--indra/newview/skins/default/xui/it/menu_conversation.xml32
-rw-r--r--indra/newview/skins/default/xui/it/menu_conversation_log_gear.xml15
-rw-r--r--indra/newview/skins/default/xui/it/menu_conversation_log_view.xml7
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/menu_edit.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/menu_favorites.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/menu_gesture_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/menu_group_plus.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/menu_hide_navbar.xml0
-rw-r--r--indra/newview/skins/default/xui/it/menu_im_conversation.xml15
-rw-r--r--indra/newview/skins/default/xui/it/menu_im_session_showmodes.xml7
-rw-r--r--indra/newview/skins/default/xui/it/menu_im_well_button.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/menu_imchiclet_adhoc.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/menu_imchiclet_group.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/menu_imchiclet_p2p.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/menu_inspect_avatar_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/menu_inspect_object_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/menu_inspect_self_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/menu_inv_offer_chiclet.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/menu_inventory.xml1
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/menu_inventory_add.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/menu_inventory_gear_default.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/menu_land.xml1
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/menu_landmark.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/menu_login.xml8
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/menu_media_ctrl.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/menu_mini_map.xml0
-rw-r--r--indra/newview/skins/default/xui/it/menu_mode_change.xml5
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/menu_model_import_gear_default.xml0
-rw-r--r--indra/newview/skins/default/xui/it/menu_mute_particle.xml5
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/menu_navbar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/menu_nearby_chat.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/menu_notification_well_button.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/menu_object.xml3
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/menu_object_icon.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/menu_outfit_gear.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/menu_outfit_tab.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/menu_participant_list.xml0
-rw-r--r--indra/newview/skins/default/xui/it/menu_participant_view.xml13
-rw-r--r--indra/newview/skins/default/xui/it/menu_people_blocked_gear.xml5
-rw-r--r--indra/newview/skins/default/xui/it/menu_people_blocked_plus.xml5
-rw-r--r--indra/newview/skins/default/xui/it/menu_people_blocked_view.xml5
-rw-r--r--indra/newview/skins/default/xui/it/menu_people_friends_view.xml8
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/menu_people_friends_view_sort.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/menu_people_groups.xml2
-rw-r--r--indra/newview/skins/default/xui/it/menu_people_groups_view.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/menu_people_groups_view_sort.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/menu_people_nearby.xml23
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/menu_people_nearby_multiselect.xml14
-rw-r--r--indra/newview/skins/default/xui/it/menu_people_nearby_view.xml8
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/menu_people_nearby_view_sort.xml0
-rw-r--r--indra/newview/skins/default/xui/it/menu_people_recent_view.xml6
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/menu_people_recent_view_sort.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/menu_picks.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/menu_picks_plus.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/menu_place.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/menu_place_add_button.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/menu_places_gear_folder.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/menu_places_gear_landmark.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/menu_profile_overflow.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/menu_save_outfit.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/menu_script_chiclet.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/menu_slurl.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/menu_teleport_history_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/menu_teleport_history_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/menu_teleport_history_tab.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/menu_text_editor.xml7
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/menu_toolbars.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/menu_topinfobar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/menu_url_agent.xml5
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/menu_url_group.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/menu_url_http.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/menu_url_inventory.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/menu_url_map.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/menu_url_objectim.xml3
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/menu_url_parcel.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/menu_url_slapp.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/menu_url_slurl.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/menu_url_teleport.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/menu_viewer.xml62
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/menu_wearable_list_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/menu_wearing_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/menu_wearing_tab.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/mime_types.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/mime_types_linux.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/mime_types_mac.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/notifications.xml1115
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/outfit_accordion_tab.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_active_object_row.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_adhoc_control_panel.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_avatar_list_item.xml1
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_block_list_sidetray.xml15
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_body_parts_list_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_bodyparts_list_button_bar.xml0
-rw-r--r--indra/newview/skins/default/xui/it/panel_bottomtray.xml47
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_bottomtray_lite.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_chiclet_bar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_classified_info.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_clothing_list_button_bar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_clothing_list_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_cof_wearables.xml0
-rw-r--r--indra/newview/skins/default/xui/it/panel_conversation_list_item.xml8
-rw-r--r--indra/newview/skins/default/xui/it/panel_conversation_log_list_item.xml6
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_deletable_wearable_list_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_dummy_clothing_list_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_edit_alpha.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_edit_classified.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_edit_eyes.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_edit_gloves.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_edit_hair.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_edit_jacket.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_edit_pants.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_edit_physics.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_edit_pick.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_edit_profile.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_edit_shape.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_edit_shirt.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_edit_shoes.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_edit_skin.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_edit_skirt.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_edit_socks.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_edit_tattoo.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_edit_underpants.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_edit_undershirt.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_edit_wearable.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_group_control_panel.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_group_general.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_group_info_sidetray.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_group_invite.xml3
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_group_land_money.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_group_list_item.xml1
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_group_notices.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_group_notify.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_group_roles.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_im_control_panel.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_inventory_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_landmark_info.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_landmarks.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_login.xml32
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_main_inventory.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_me.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_media_settings_general.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_media_settings_permissions.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_media_settings_security.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_navigation_bar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_nearby_chat.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_nearby_chat_bar.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_nearby_media.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_notify_textbox.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_online_status_toast.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_outbox_inventory.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_outfit_edit.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_outfits_inventory.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_outfits_inventory_gear_default.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_outfits_list.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_outfits_wearing.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_people.xml91
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_pick_info.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_picks.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_place_profile.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_places.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_postcard_message.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_postcard_settings.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_preferences_advanced.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_preferences_alerts.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_preferences_chat.xml126
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_preferences_colors.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_preferences_general.xml5
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_preferences_graphics1.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_preferences_move.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_preferences_privacy.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_preferences_setup.xml3
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_preferences_sound.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_prim_media_controls.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_region_covenant.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_region_debug.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_region_environment.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_region_estate.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_region_general.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_region_terrain.xml0
-rw-r--r--indra/newview/skins/default/xui/it/panel_region_texture.xml57
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_script_ed.xml1
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_script_limits_my_avatar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_script_limits_region_memory.xml0
-rwxr-xr-xindra/newview/skins/default/xui/it/panel_script_question_toast.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_scrolling_param.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_scrolling_param_base.xml0
-rw-r--r--indra/newview/skins/default/xui/it/panel_side_tray.xml29
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_side_tray_tab_caption.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_snapshot_inventory.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_snapshot_local.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_snapshot_options.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_snapshot_postcard.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_snapshot_profile.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_sound_devices.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_stand_stop_flying.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_status_bar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_teleport_history.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_teleport_history_item.xml0
-rw-r--r--indra/newview/skins/default/xui/it/panel_tools_texture.xml116
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_voice_effect.xml0
-rwxr-xr-xindra/newview/skins/default/xui/it/panel_volume_pulldown.xml15
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/panel_world_map.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/role_actions.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/sidepanel_appearance.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/sidepanel_inventory.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/sidepanel_item_info.xml3
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/sidepanel_task_info.xml10
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/strings.xml147
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/it/teleport_strings.xml6
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_about.xml23
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_about_land.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_activeim.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_animation_anim_preview.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_animation_bvh_preview.xml0
-rw-r--r--indra/newview/skins/default/xui/ja/floater_animation_preview.xml187
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_auction.xml0
-rwxr-xr-xindra/newview/skins/default/xui/ja/floater_autoreplace.xml32
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_avatar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_avatar_picker.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_avatar_textures.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_beacons.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_build_options.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_bulk_perms.xml7
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_bumps.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_buy_contents.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_buy_currency.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_buy_currency_html.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_buy_land.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_buy_object.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_camera.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_chat_bar.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_choose_group.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_color_picker.xml0
-rw-r--r--indra/newview/skins/default/xui/ja/floater_conversation_log.xml8
-rw-r--r--indra/newview/skins/default/xui/ja/floater_conversation_preview.xml7
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_critical.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_delete_env_preset.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_destinations.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_display_name.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_edit_day_cycle.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_edit_sky_preset.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_edit_water_preset.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_environment_settings.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_event.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_fast_timers.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_font_test.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_gesture.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_god_tools.xml0
-rw-r--r--indra/newview/skins/default/xui/ja/floater_goto_line.xml7
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_hardware_settings.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_help_browser.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_how_to.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_hud.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_im_container.xml29
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_im_session.xml59
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_image_preview.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_import_collada.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_incoming_call.xml10
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_inspect.xml0
-rw-r--r--indra/newview/skins/default/xui/ja/floater_inventory.xml16
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_inventory_item_properties.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_inventory_view_finder.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_joystick.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_lagmeter.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_land_holdings.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_live_lsleditor.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_lsl_guide.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_map.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_media_browser.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_media_settings.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_mem_leaking.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_merchant_outbox.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_model_preview.xml35
-rw-r--r--indra/newview/skins/default/xui/ja/floater_model_wizard.xml208
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_moveview.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_mute_object.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_my_appearance.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_my_inventory.xml0
-rw-r--r--indra/newview/skins/default/xui/ja/floater_nearby_chat.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_notification.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_notifications_console.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_object_weights.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_openobject.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_outfit_save_as.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_outgoing_call.xml0
-rwxr-xr-xindra/newview/skins/default/xui/ja/floater_pathfinding_characters.xml57
-rwxr-xr-xindra/newview/skins/default/xui/ja/floater_pathfinding_console.xml121
-rwxr-xr-xindra/newview/skins/default/xui/ja/floater_pathfinding_linksets.xml167
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_pay.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_pay_object.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_people.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_perm_prefs.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_picks.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_places.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_post_process.xml0
-rw-r--r--indra/newview/skins/default/xui/ja/floater_postcard.xml42
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_preferences.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_preferences_proxy.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_preview_animation.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_preview_gesture.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_preview_notecard.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_preview_sound.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_preview_texture.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_price_for_listing.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_publish_classified.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_region_debug_console.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_region_info.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_report_abuse.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_script_debug.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_script_debug_panel.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_script_limits.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_script_preview.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_script_queue.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_script_search.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_search.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_select_key.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_sell_land.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_settings_debug.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_snapshot.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_sound_devices.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_sound_preview.xml0
-rwxr-xr-xindra/newview/skins/default/xui/ja/floater_spellcheck.xml18
-rwxr-xr-xindra/newview/skins/default/xui/ja/floater_spellcheck_import.xml6
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_stats.xml9
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_sys_well.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_telehub.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_test_layout_stacks.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_test_text_vertical_aligment.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_texture_ctrl.xml32
-rwxr-xr-xindra/newview/skins/default/xui/ja/floater_texture_fetch_debugger.xml77
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_tools.xml18
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_top_objects.xml10
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_tos.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_toybox.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_translation_settings.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_url_entry.xml0
-rw-r--r--indra/newview/skins/default/xui/ja/floater_voice_chat_volume.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_voice_controls.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_voice_effect.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/floater_voice_volume.xml8
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_web_content.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_whitelist_entry.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_window_size.xml15
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/floater_world_map.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/inspect_avatar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/inspect_group.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/inspect_object.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/inspect_remote_object.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/language_settings.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/menu_add_wearable_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/menu_attachment_other.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/menu_attachment_self.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/menu_avatar_icon.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/menu_avatar_other.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/menu_avatar_self.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/menu_bottomtray.xml17
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/menu_cof_attachment.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/menu_cof_body_part.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/menu_cof_clothing.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/menu_cof_gear.xml6
-rw-r--r--indra/newview/skins/default/xui/ja/menu_conversation.xml32
-rw-r--r--indra/newview/skins/default/xui/ja/menu_conversation_log_gear.xml15
-rw-r--r--indra/newview/skins/default/xui/ja/menu_conversation_log_view.xml7
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/menu_edit.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/menu_favorites.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/menu_gesture_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/menu_group_plus.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/menu_hide_navbar.xml0
-rw-r--r--indra/newview/skins/default/xui/ja/menu_im_conversation.xml15
-rw-r--r--indra/newview/skins/default/xui/ja/menu_im_session_showmodes.xml7
-rw-r--r--indra/newview/skins/default/xui/ja/menu_im_well_button.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/menu_imchiclet_adhoc.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/menu_imchiclet_group.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/menu_imchiclet_p2p.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/menu_inspect_avatar_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/menu_inspect_object_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/menu_inspect_self_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/menu_inv_offer_chiclet.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/menu_inventory.xml1
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/menu_inventory_add.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/menu_inventory_gear_default.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/menu_land.xml1
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/menu_landmark.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/menu_login.xml8
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/menu_media_ctrl.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/menu_mini_map.xml0
-rw-r--r--indra/newview/skins/default/xui/ja/menu_mode_change.xml5
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/menu_model_import_gear_default.xml0
-rw-r--r--indra/newview/skins/default/xui/ja/menu_mute_particle.xml5
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/menu_navbar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/menu_nearby_chat.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/menu_notification_well_button.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/menu_object.xml3
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/menu_object_icon.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/menu_outfit_gear.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/menu_outfit_tab.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/menu_participant_list.xml0
-rw-r--r--indra/newview/skins/default/xui/ja/menu_participant_view.xml13
-rw-r--r--indra/newview/skins/default/xui/ja/menu_people_blocked_gear.xml5
-rw-r--r--indra/newview/skins/default/xui/ja/menu_people_blocked_plus.xml5
-rw-r--r--indra/newview/skins/default/xui/ja/menu_people_blocked_view.xml5
-rw-r--r--indra/newview/skins/default/xui/ja/menu_people_friends_view.xml8
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/menu_people_friends_view_sort.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/menu_people_groups.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/menu_people_groups_view.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/menu_people_groups_view_sort.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/menu_people_nearby.xml23
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/menu_people_nearby_multiselect.xml14
-rw-r--r--indra/newview/skins/default/xui/ja/menu_people_nearby_view.xml8
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/menu_people_nearby_view_sort.xml0
-rw-r--r--indra/newview/skins/default/xui/ja/menu_people_recent_view.xml6
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/menu_people_recent_view_sort.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/menu_picks.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/menu_picks_plus.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/menu_place.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/menu_place_add_button.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/menu_places_gear_folder.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/menu_places_gear_landmark.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/menu_profile_overflow.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/menu_save_outfit.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/menu_script_chiclet.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/menu_slurl.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/menu_teleport_history_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/menu_teleport_history_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/menu_teleport_history_tab.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/menu_text_editor.xml7
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/menu_toolbars.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/menu_topinfobar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/menu_url_agent.xml5
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/menu_url_group.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/menu_url_http.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/menu_url_inventory.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/menu_url_map.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/menu_url_objectim.xml3
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/menu_url_parcel.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/menu_url_slapp.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/menu_url_slurl.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/menu_url_teleport.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/menu_viewer.xml64
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/menu_wearable_list_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/menu_wearing_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/menu_wearing_tab.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/mime_types.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/mime_types_linux.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/mime_types_mac.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/notifications.xml1117
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/outfit_accordion_tab.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_active_object_row.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_adhoc_control_panel.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_avatar_list_item.xml1
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_avatar_tag.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_block_list_sidetray.xml15
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_body_parts_list_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_bodyparts_list_button_bar.xml0
-rw-r--r--indra/newview/skins/default/xui/ja/panel_bottomtray.xml47
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_bottomtray_lite.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_chat_header.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_chiclet_bar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_classified_info.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_clothing_list_button_bar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_clothing_list_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_cof_wearables.xml0
-rw-r--r--indra/newview/skins/default/xui/ja/panel_conversation_list_item.xml8
-rw-r--r--indra/newview/skins/default/xui/ja/panel_conversation_log_list_item.xml6
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_deletable_wearable_list_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_dummy_clothing_list_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_edit_alpha.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_edit_classified.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_edit_eyes.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_edit_gloves.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_edit_hair.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_edit_jacket.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_edit_pants.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_edit_physics.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_edit_pick.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_edit_profile.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_edit_shape.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_edit_shirt.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_edit_shoes.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_edit_skin.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_edit_skirt.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_edit_socks.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_edit_tattoo.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_edit_underpants.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_edit_undershirt.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_edit_wearable.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_group_control_panel.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_group_general.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_group_info_sidetray.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_group_invite.xml3
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_group_land_money.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_group_list_item.xml1
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_group_notices.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_group_notify.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_group_roles.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_im_control_panel.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_instant_message.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_inventory_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_landmark_info.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_landmarks.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_login.xml32
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_main_inventory.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_me.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_media_settings_general.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_media_settings_permissions.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_media_settings_security.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_navigation_bar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_nearby_chat.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_nearby_chat_bar.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_nearby_media.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_notifications_channel.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_notify_textbox.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_online_status_toast.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_outbox_inventory.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_outfit_edit.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_outfits_inventory.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_outfits_inventory_gear_default.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_outfits_list.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_outfits_wearing.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_people.xml93
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_pick_info.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_picks.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_place_profile.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_places.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_postcard_message.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_postcard_settings.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_preferences_advanced.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_preferences_alerts.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_preferences_chat.xml126
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_preferences_colors.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_preferences_general.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_preferences_graphics1.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_preferences_move.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_preferences_privacy.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_preferences_setup.xml1
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_preferences_sound.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_prim_media_controls.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_region_covenant.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_region_debug.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_region_environment.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_region_estate.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_region_general.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_region_terrain.xml0
-rw-r--r--indra/newview/skins/default/xui/ja/panel_region_texture.xml58
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_script_ed.xml1
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_script_limits_my_avatar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_script_limits_region_memory.xml0
-rwxr-xr-xindra/newview/skins/default/xui/ja/panel_script_question_toast.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_scrolling_param.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_scrolling_param_base.xml0
-rw-r--r--indra/newview/skins/default/xui/ja/panel_side_tray.xml29
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_side_tray_tab_caption.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_sidetray_home_tab.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_snapshot_inventory.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_snapshot_local.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_snapshot_options.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_snapshot_postcard.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_snapshot_profile.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_sound_devices.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_stand_stop_flying.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_status_bar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_sys_well_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_teleport_history.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_teleport_history_item.xml0
-rw-r--r--indra/newview/skins/default/xui/ja/panel_tools_texture.xml116
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_voice_effect.xml0
-rwxr-xr-xindra/newview/skins/default/xui/ja/panel_volume_pulldown.xml14
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/panel_world_map.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/role_actions.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/sidepanel_appearance.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/sidepanel_inventory.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/sidepanel_item_info.xml5
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/sidepanel_task_info.xml10
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/strings.xml146
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/teleport_strings.xml8
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ja/xui_version.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_about.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_about_land.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_activeim.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_animation_preview.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_auction.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_avatar_picker.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_avatar_textures.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_beacons.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_build_options.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_bulk_perms.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_bumps.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_buy_contents.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_buy_currency.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_buy_currency_html.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_buy_land.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_buy_object.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_camera.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_choose_group.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_color_picker.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_critical.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_display_name.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_event.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_font_test.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_gesture.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_god_tools.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_hardware_settings.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_help_browser.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_hud.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_im_container.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_im_session.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_image_preview.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_incoming_call.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_inspect.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_inventory.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_inventory_item_properties.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_inventory_view_finder.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_joystick.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_lagmeter.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_land_holdings.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_live_lsleditor.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_lsl_guide.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_map.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_media_browser.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_media_settings.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_mem_leaking.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_moveview.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_mute_object.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_nearby_chat.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_openobject.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_outgoing_call.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_pay.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_pay_object.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_perm_prefs.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_post_process.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_postcard.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_preferences.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_preview_animation.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_preview_gesture.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_preview_notecard.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_preview_sound.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_preview_texture.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_publish_classified.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_region_debug_console.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_region_info.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_report_abuse.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_script_debug.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_script_debug_panel.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_script_limits.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_script_preview.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_script_queue.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_script_search.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_search.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_select_key.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_sell_land.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_settings_debug.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_snapshot.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_sound_preview.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_stats.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_sys_well.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_telehub.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_texture_ctrl.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_tools.xml5
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_top_objects.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_tos.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_url_entry.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_voice_controls.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_voice_effect.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_web_content.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_whitelist_entry.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_window_size.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/floater_world_map.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/inspect_avatar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/inspect_group.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/inspect_object.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/inspect_remote_object.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/language_settings.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/menu_add_wearable_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/menu_attachment_other.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/menu_attachment_self.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/menu_avatar_icon.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/menu_avatar_other.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/menu_avatar_self.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/menu_bottomtray.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/menu_cof_attachment.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/menu_cof_body_part.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/menu_cof_clothing.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/menu_cof_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/menu_edit.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/menu_favorites.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/menu_gesture_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/menu_group_plus.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/menu_hide_navbar.xml0
-rw-r--r--indra/newview/skins/default/xui/pl/menu_im_well_button.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/menu_imchiclet_adhoc.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/menu_imchiclet_group.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/menu_imchiclet_p2p.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/menu_inspect_avatar_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/menu_inspect_object_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/menu_inspect_self_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/menu_inv_offer_chiclet.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/menu_inventory.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/menu_inventory_add.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/menu_inventory_gear_default.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/menu_land.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/menu_landmark.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/menu_login.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/menu_media_ctrl.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/menu_mini_map.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/menu_navbar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/menu_nearby_chat.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/menu_notification_well_button.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/menu_object.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/menu_object_icon.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/menu_outfit_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/menu_outfit_tab.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/menu_participant_list.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/menu_people_friends_view_sort.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/menu_people_groups.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/menu_people_groups_view_sort.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/menu_people_nearby.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/menu_people_nearby_multiselect.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/menu_people_nearby_view_sort.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/menu_people_recent_view_sort.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/menu_picks.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/menu_picks_plus.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/menu_place.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/menu_place_add_button.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/menu_places_gear_folder.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/menu_places_gear_landmark.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/menu_profile_overflow.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/menu_save_outfit.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/menu_script_chiclet.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/menu_slurl.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/menu_teleport_history_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/menu_teleport_history_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/menu_teleport_history_tab.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/menu_text_editor.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/menu_topinfobar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/menu_url_agent.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/menu_url_group.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/menu_url_http.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/menu_url_inventory.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/menu_url_map.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/menu_url_objectim.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/menu_url_parcel.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/menu_url_slapp.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/menu_url_slurl.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/menu_url_teleport.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/menu_viewer.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/menu_wearable_list_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/menu_wearing_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/menu_wearing_tab.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/mime_types.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/mime_types_linux.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/mime_types_mac.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/notifications.xml1
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/outfit_accordion_tab.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_active_object_row.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_adhoc_control_panel.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_avatar_list_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_block_list_sidetray.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_body_parts_list_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_bodyparts_list_button_bar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_bottomtray.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_bottomtray_lite.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_classified_info.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_clothing_list_button_bar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_clothing_list_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_cof_wearables.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_deletable_wearable_list_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_dummy_clothing_list_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_edit_alpha.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_edit_classified.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_edit_eyes.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_edit_gloves.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_edit_hair.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_edit_jacket.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_edit_pants.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_edit_physics.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_edit_pick.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_edit_profile.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_edit_shape.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_edit_shirt.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_edit_shoes.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_edit_skin.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_edit_skirt.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_edit_socks.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_edit_tattoo.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_edit_underpants.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_edit_undershirt.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_edit_wearable.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_group_control_panel.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_group_general.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_group_info_sidetray.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_group_invite.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_group_land_money.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_group_list_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_group_notices.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_group_notify.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_group_roles.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_im_control_panel.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_inventory_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_landmark_info.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_landmarks.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_login.xml31
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_main_inventory.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_me.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_media_settings_general.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_media_settings_permissions.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_media_settings_security.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_navigation_bar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_nearby_chat_bar.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_nearby_media.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_notify_textbox.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_online_status_toast.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_outfit_edit.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_outfits_inventory.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_outfits_inventory_gear_default.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_outfits_list.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_outfits_wearing.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_people.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_pick_info.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_picks.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_place_profile.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_places.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_preferences_advanced.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_preferences_alerts.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_preferences_chat.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_preferences_colors.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_preferences_general.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_preferences_graphics1.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_preferences_move.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_preferences_privacy.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_preferences_setup.xml5
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_preferences_sound.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_prim_media_controls.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_region_covenant.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_region_debug.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_region_estate.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_region_general.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_region_terrain.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_region_texture.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_script_ed.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_script_limits_my_avatar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_script_limits_region_memory.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_scrolling_param.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_scrolling_param_base.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_side_tray.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_side_tray_tab_caption.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_stand_stop_flying.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_status_bar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_teleport_history.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_teleport_history_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_voice_effect.xml0
-rwxr-xr-xindra/newview/skins/default/xui/pl/panel_volume_pulldown.xml14
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/panel_world_map.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/role_actions.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/sidepanel_appearance.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/sidepanel_inventory.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/sidepanel_item_info.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/sidepanel_task_info.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/strings.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/teleport_strings.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pl/xui_version.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_about.xml23
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_about_land.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_activeim.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_animation_anim_preview.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_animation_bvh_preview.xml0
-rw-r--r--indra/newview/skins/default/xui/pt/floater_animation_preview.xml187
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_auction.xml0
-rwxr-xr-xindra/newview/skins/default/xui/pt/floater_autoreplace.xml32
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_avatar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_avatar_picker.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_avatar_textures.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_beacons.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_build_options.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_bulk_perms.xml7
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_bumps.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_buy_contents.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_buy_currency.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_buy_currency_html.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_buy_land.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_buy_object.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_camera.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_chat_bar.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_choose_group.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_color_picker.xml0
-rw-r--r--indra/newview/skins/default/xui/pt/floater_conversation_log.xml8
-rw-r--r--indra/newview/skins/default/xui/pt/floater_conversation_preview.xml7
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_critical.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_delete_env_preset.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_destinations.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_display_name.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_edit_day_cycle.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_edit_sky_preset.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_edit_water_preset.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_environment_settings.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_event.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_fast_timers.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_font_test.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_gesture.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_god_tools.xml0
-rw-r--r--indra/newview/skins/default/xui/pt/floater_goto_line.xml7
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_hardware_settings.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_help_browser.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_how_to.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_hud.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_im_container.xml29
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_im_session.xml59
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_image_preview.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_import_collada.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_incoming_call.xml8
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_inspect.xml0
-rw-r--r--indra/newview/skins/default/xui/pt/floater_inventory.xml16
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_inventory_item_properties.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_inventory_view_finder.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_joystick.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_lagmeter.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_land_holdings.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_live_lsleditor.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_lsl_guide.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_map.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_media_browser.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_media_settings.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_mem_leaking.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_merchant_outbox.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_model_preview.xml35
-rw-r--r--indra/newview/skins/default/xui/pt/floater_model_wizard.xml208
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_moveview.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_mute_object.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_my_appearance.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_my_inventory.xml0
-rw-r--r--indra/newview/skins/default/xui/pt/floater_nearby_chat.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_object_weights.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_openobject.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_outfit_save_as.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_outgoing_call.xml0
-rwxr-xr-xindra/newview/skins/default/xui/pt/floater_pathfinding_characters.xml57
-rwxr-xr-xindra/newview/skins/default/xui/pt/floater_pathfinding_console.xml121
-rwxr-xr-xindra/newview/skins/default/xui/pt/floater_pathfinding_linksets.xml167
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_pay.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_pay_object.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_people.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_perm_prefs.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_picks.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_places.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_post_process.xml0
-rw-r--r--indra/newview/skins/default/xui/pt/floater_postcard.xml40
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_preferences.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_preferences_proxy.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_preview_animation.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_preview_gesture.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_preview_notecard.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_preview_sound.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_preview_texture.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_price_for_listing.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_publish_classified.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_region_debug_console.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_region_info.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_report_abuse.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_script_debug.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_script_debug_panel.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_script_limits.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_script_preview.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_script_queue.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_script_search.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_search.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_select_key.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_sell_land.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_settings_debug.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_snapshot.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_sound_devices.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_sound_preview.xml0
-rwxr-xr-xindra/newview/skins/default/xui/pt/floater_spellcheck.xml18
-rwxr-xr-xindra/newview/skins/default/xui/pt/floater_spellcheck_import.xml6
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_stats.xml9
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_sys_well.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_telehub.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_test_layout_stacks.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_test_text_vertical_aligment.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_texture_ctrl.xml32
-rwxr-xr-xindra/newview/skins/default/xui/pt/floater_texture_fetch_debugger.xml77
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_tools.xml18
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_top_objects.xml10
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_tos.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_toybox.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_translation_settings.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_url_entry.xml0
-rw-r--r--indra/newview/skins/default/xui/pt/floater_voice_chat_volume.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_voice_controls.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_voice_effect.xml2
-rw-r--r--indra/newview/skins/default/xui/pt/floater_voice_volume.xml8
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_web_content.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_whitelist_entry.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_window_size.xml15
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/floater_world_map.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/inspect_avatar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/inspect_group.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/inspect_object.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/inspect_remote_object.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/language_settings.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/menu_add_wearable_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/menu_attachment_other.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/menu_attachment_self.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/menu_avatar_icon.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/menu_avatar_other.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/menu_avatar_self.xml2
-rw-r--r--indra/newview/skins/default/xui/pt/menu_bottomtray.xml17
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/menu_cof_attachment.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/menu_cof_body_part.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/menu_cof_clothing.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/menu_cof_gear.xml6
-rw-r--r--indra/newview/skins/default/xui/pt/menu_conversation.xml32
-rw-r--r--indra/newview/skins/default/xui/pt/menu_conversation_log_gear.xml15
-rw-r--r--indra/newview/skins/default/xui/pt/menu_conversation_log_view.xml7
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/menu_edit.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/menu_favorites.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/menu_gesture_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/menu_group_plus.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/menu_hide_navbar.xml0
-rw-r--r--indra/newview/skins/default/xui/pt/menu_im_conversation.xml15
-rw-r--r--indra/newview/skins/default/xui/pt/menu_im_session_showmodes.xml7
-rw-r--r--indra/newview/skins/default/xui/pt/menu_im_well_button.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/menu_imchiclet_adhoc.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/menu_imchiclet_group.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/menu_imchiclet_p2p.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/menu_inspect_avatar_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/menu_inspect_object_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/menu_inspect_self_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/menu_inv_offer_chiclet.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/menu_inventory.xml1
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/menu_inventory_add.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/menu_inventory_gear_default.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/menu_land.xml1
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/menu_landmark.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/menu_login.xml8
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/menu_media_ctrl.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/menu_mini_map.xml0
-rw-r--r--indra/newview/skins/default/xui/pt/menu_mode_change.xml5
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/menu_model_import_gear_default.xml0
-rw-r--r--indra/newview/skins/default/xui/pt/menu_mute_particle.xml5
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/menu_navbar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/menu_nearby_chat.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/menu_notification_well_button.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/menu_object.xml3
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/menu_object_icon.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/menu_outfit_gear.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/menu_outfit_tab.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/menu_participant_list.xml0
-rw-r--r--indra/newview/skins/default/xui/pt/menu_participant_view.xml13
-rw-r--r--indra/newview/skins/default/xui/pt/menu_people_blocked_gear.xml5
-rw-r--r--indra/newview/skins/default/xui/pt/menu_people_blocked_plus.xml5
-rw-r--r--indra/newview/skins/default/xui/pt/menu_people_blocked_view.xml5
-rw-r--r--indra/newview/skins/default/xui/pt/menu_people_friends_view.xml8
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/menu_people_friends_view_sort.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/menu_people_groups.xml2
-rw-r--r--indra/newview/skins/default/xui/pt/menu_people_groups_view.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/menu_people_groups_view_sort.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/menu_people_nearby.xml23
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/menu_people_nearby_multiselect.xml14
-rw-r--r--indra/newview/skins/default/xui/pt/menu_people_nearby_view.xml8
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/menu_people_nearby_view_sort.xml0
-rw-r--r--indra/newview/skins/default/xui/pt/menu_people_recent_view.xml6
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/menu_people_recent_view_sort.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/menu_picks.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/menu_picks_plus.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/menu_place.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/menu_place_add_button.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/menu_places_gear_folder.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/menu_places_gear_landmark.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/menu_profile_overflow.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/menu_save_outfit.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/menu_script_chiclet.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/menu_slurl.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/menu_teleport_history_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/menu_teleport_history_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/menu_teleport_history_tab.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/menu_text_editor.xml7
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/menu_toolbars.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/menu_topinfobar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/menu_url_agent.xml5
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/menu_url_group.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/menu_url_http.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/menu_url_inventory.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/menu_url_map.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/menu_url_objectim.xml3
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/menu_url_parcel.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/menu_url_slapp.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/menu_url_slurl.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/menu_url_teleport.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/menu_viewer.xml66
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/menu_wearable_list_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/menu_wearing_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/menu_wearing_tab.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/mime_types.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/mime_types_linux.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/mime_types_mac.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/notifications.xml1127
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/outfit_accordion_tab.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_active_object_row.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_adhoc_control_panel.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_avatar_list_item.xml1
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_block_list_sidetray.xml15
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_body_parts_list_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_bodyparts_list_button_bar.xml0
-rw-r--r--indra/newview/skins/default/xui/pt/panel_bottomtray.xml47
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_bottomtray_lite.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_chiclet_bar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_classified_info.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_clothing_list_button_bar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_clothing_list_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_cof_wearables.xml0
-rw-r--r--indra/newview/skins/default/xui/pt/panel_conversation_list_item.xml8
-rw-r--r--indra/newview/skins/default/xui/pt/panel_conversation_log_list_item.xml6
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_deletable_wearable_list_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_dummy_clothing_list_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_edit_alpha.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_edit_classified.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_edit_eyes.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_edit_gloves.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_edit_hair.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_edit_jacket.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_edit_pants.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_edit_physics.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_edit_pick.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_edit_profile.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_edit_shape.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_edit_shirt.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_edit_shoes.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_edit_skin.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_edit_skirt.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_edit_socks.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_edit_tattoo.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_edit_underpants.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_edit_undershirt.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_edit_wearable.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_group_control_panel.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_group_general.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_group_info_sidetray.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_group_invite.xml3
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_group_land_money.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_group_list_item.xml1
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_group_notices.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_group_notify.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_group_roles.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_im_control_panel.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_inventory_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_landmark_info.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_landmarks.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_login.xml35
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_main_inventory.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_me.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_media_settings_general.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_media_settings_permissions.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_media_settings_security.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_navigation_bar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_nearby_chat.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_nearby_chat_bar.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_nearby_media.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_notify_textbox.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_online_status_toast.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_outbox_inventory.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_outfit_edit.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_outfits_inventory.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_outfits_inventory_gear_default.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_outfits_list.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_outfits_wearing.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_people.xml91
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_pick_info.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_picks.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_place_profile.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_places.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_postcard_message.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_postcard_settings.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_preferences_advanced.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_preferences_alerts.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_preferences_chat.xml126
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_preferences_colors.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_preferences_general.xml5
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_preferences_graphics1.xml10
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_preferences_move.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_preferences_privacy.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_preferences_setup.xml3
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_preferences_sound.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_prim_media_controls.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_region_covenant.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_region_debug.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_region_environment.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_region_estate.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_region_general.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_region_terrain.xml0
-rw-r--r--indra/newview/skins/default/xui/pt/panel_region_texture.xml57
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_script_ed.xml1
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_script_limits_my_avatar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_script_limits_region_memory.xml0
-rwxr-xr-xindra/newview/skins/default/xui/pt/panel_script_question_toast.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_scrolling_param.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_scrolling_param_base.xml0
-rw-r--r--indra/newview/skins/default/xui/pt/panel_side_tray.xml29
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_side_tray_tab_caption.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_snapshot_inventory.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_snapshot_local.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_snapshot_options.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_snapshot_postcard.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_snapshot_profile.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_sound_devices.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_stand_stop_flying.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_status_bar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_teleport_history.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_teleport_history_item.xml0
-rw-r--r--indra/newview/skins/default/xui/pt/panel_tools_texture.xml116
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_voice_effect.xml0
-rwxr-xr-xindra/newview/skins/default/xui/pt/panel_volume_pulldown.xml14
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/panel_world_map.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/role_actions.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/sidepanel_appearance.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/sidepanel_inventory.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/sidepanel_item_info.xml3
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/sidepanel_task_info.xml10
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/strings.xml147
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/teleport_strings.xml6
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/pt/xui_version.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_aaa.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_about.xml23
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_about_land.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_activeim.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_animation_anim_preview.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_animation_bvh_preview.xml0
-rw-r--r--indra/newview/skins/default/xui/ru/floater_animation_preview.xml183
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_auction.xml2
-rwxr-xr-xindra/newview/skins/default/xui/ru/floater_autoreplace.xml32
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_avatar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_avatar_picker.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_avatar_textures.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_beacons.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_build_options.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_bulk_perms.xml9
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_bumps.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_buy_contents.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_buy_currency.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_buy_currency_html.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_buy_land.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_buy_object.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_camera.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_chat_bar.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_choose_group.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_color_picker.xml0
-rw-r--r--indra/newview/skins/default/xui/ru/floater_conversation_log.xml8
-rw-r--r--indra/newview/skins/default/xui/ru/floater_conversation_preview.xml7
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_critical.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_delete_env_preset.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_destinations.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_display_name.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_edit_day_cycle.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_edit_sky_preset.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_edit_water_preset.xml0
-rw-r--r--indra/newview/skins/default/xui/ru/floater_env_settings.xml25
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_environment_settings.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_event.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_fast_timers.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_font_test.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_gesture.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_god_tools.xml0
-rw-r--r--indra/newview/skins/default/xui/ru/floater_goto_line.xml7
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_hardware_settings.xml6
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_help_browser.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_how_to.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_hud.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_im_container.xml29
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_im_session.xml59
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_image_preview.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_import_collada.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_incoming_call.xml10
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_inspect.xml0
-rw-r--r--indra/newview/skins/default/xui/ru/floater_inventory.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_inventory_item_properties.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_inventory_view_finder.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_joystick.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_lagmeter.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_land_holdings.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_live_lsleditor.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_lsl_guide.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_map.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_media_browser.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_media_settings.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_mem_leaking.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_merchant_outbox.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_model_preview.xml35
-rw-r--r--indra/newview/skins/default/xui/ru/floater_model_wizard.xml208
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_moveview.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_mute_object.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_my_appearance.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_my_inventory.xml0
-rw-r--r--indra/newview/skins/default/xui/ru/floater_nearby_chat.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_notification.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_notifications_console.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_object_weights.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_openobject.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_outfit_save_as.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_outgoing_call.xml0
-rwxr-xr-xindra/newview/skins/default/xui/ru/floater_pathfinding_characters.xml57
-rwxr-xr-xindra/newview/skins/default/xui/ru/floater_pathfinding_console.xml121
-rwxr-xr-xindra/newview/skins/default/xui/ru/floater_pathfinding_linksets.xml167
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_pay.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_pay_object.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_people.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_perm_prefs.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_picks.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_places.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_post_process.xml0
-rw-r--r--indra/newview/skins/default/xui/ru/floater_postcard.xml33
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_preferences.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_preferences_proxy.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_preview_animation.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_preview_gesture.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_preview_notecard.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_preview_sound.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_preview_texture.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_price_for_listing.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_publish_classified.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_region_debug_console.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_region_info.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_report_abuse.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_script_debug.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_script_debug_panel.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_script_limits.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_script_preview.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_script_queue.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_script_search.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_search.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_select_key.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_sell_land.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_settings_debug.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_snapshot.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_sound_devices.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_sound_preview.xml0
-rwxr-xr-xindra/newview/skins/default/xui/ru/floater_spellcheck.xml18
-rwxr-xr-xindra/newview/skins/default/xui/ru/floater_spellcheck_import.xml6
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_stats.xml9
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_sys_well.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_telehub.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_test_layout_stacks.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_test_text_vertical_aligment.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_texture_ctrl.xml18
-rwxr-xr-xindra/newview/skins/default/xui/ru/floater_texture_fetch_debugger.xml77
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_tools.xml24
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_top_objects.xml10
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_tos.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_toybox.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_translation_settings.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_url_entry.xml0
-rw-r--r--indra/newview/skins/default/xui/ru/floater_voice_chat_volume.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_voice_controls.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_voice_effect.xml2
-rw-r--r--indra/newview/skins/default/xui/ru/floater_voice_volume.xml8
-rw-r--r--indra/newview/skins/default/xui/ru/floater_water.xml70
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_web_content.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_whitelist_entry.xml0
-rw-r--r--indra/newview/skins/default/xui/ru/floater_windlight_options.xml167
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_window_size.xml15
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/floater_world_map.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/inspect_avatar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/inspect_group.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/inspect_object.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/inspect_remote_object.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/menu_add_wearable_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/menu_attachment_other.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/menu_attachment_self.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/menu_avatar_icon.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/menu_avatar_other.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/menu_avatar_self.xml2
-rw-r--r--indra/newview/skins/default/xui/ru/menu_bottomtray.xml17
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/menu_cof_attachment.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/menu_cof_body_part.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/menu_cof_clothing.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/menu_cof_gear.xml2
-rw-r--r--indra/newview/skins/default/xui/ru/menu_conversation.xml32
-rw-r--r--indra/newview/skins/default/xui/ru/menu_conversation_log_gear.xml15
-rw-r--r--indra/newview/skins/default/xui/ru/menu_conversation_log_view.xml7
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/menu_edit.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/menu_favorites.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/menu_gesture_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/menu_group_plus.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/menu_hide_navbar.xml0
-rw-r--r--indra/newview/skins/default/xui/ru/menu_im_conversation.xml15
-rw-r--r--indra/newview/skins/default/xui/ru/menu_im_session_showmodes.xml7
-rw-r--r--indra/newview/skins/default/xui/ru/menu_im_well_button.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/menu_imchiclet_adhoc.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/menu_imchiclet_group.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/menu_imchiclet_p2p.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/menu_inspect_avatar_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/menu_inspect_object_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/menu_inspect_self_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/menu_inv_offer_chiclet.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/menu_inventory.xml1
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/menu_inventory_add.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/menu_inventory_gear_default.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/menu_land.xml1
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/menu_landmark.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/menu_login.xml8
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/menu_media_ctrl.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/menu_mini_map.xml0
-rw-r--r--indra/newview/skins/default/xui/ru/menu_mode_change.xml5
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/menu_model_import_gear_default.xml0
-rw-r--r--indra/newview/skins/default/xui/ru/menu_mute_particle.xml5
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/menu_navbar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/menu_nearby_chat.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/menu_notification_well_button.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/menu_object.xml3
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/menu_object_icon.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/menu_outfit_gear.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/menu_outfit_tab.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/menu_participant_list.xml0
-rw-r--r--indra/newview/skins/default/xui/ru/menu_participant_view.xml13
-rw-r--r--indra/newview/skins/default/xui/ru/menu_people_blocked_gear.xml5
-rw-r--r--indra/newview/skins/default/xui/ru/menu_people_blocked_plus.xml5
-rw-r--r--indra/newview/skins/default/xui/ru/menu_people_blocked_view.xml5
-rw-r--r--indra/newview/skins/default/xui/ru/menu_people_friends_view.xml8
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/menu_people_friends_view_sort.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/menu_people_groups.xml2
-rw-r--r--indra/newview/skins/default/xui/ru/menu_people_groups_view.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/menu_people_groups_view_sort.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/menu_people_nearby.xml23
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/menu_people_nearby_multiselect.xml14
-rw-r--r--indra/newview/skins/default/xui/ru/menu_people_nearby_view.xml8
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/menu_people_nearby_view_sort.xml0
-rw-r--r--indra/newview/skins/default/xui/ru/menu_people_recent_view.xml6
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/menu_people_recent_view_sort.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/menu_picks.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/menu_picks_plus.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/menu_place.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/menu_place_add_button.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/menu_places_gear_folder.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/menu_places_gear_landmark.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/menu_profile_overflow.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/menu_save_outfit.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/menu_script_chiclet.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/menu_slurl.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/menu_teleport_history_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/menu_teleport_history_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/menu_teleport_history_tab.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/menu_text_editor.xml7
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/menu_toolbars.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/menu_topinfobar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/menu_url_agent.xml5
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/menu_url_group.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/menu_url_http.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/menu_url_inventory.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/menu_url_map.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/menu_url_objectim.xml3
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/menu_url_parcel.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/menu_url_slapp.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/menu_url_slurl.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/menu_url_teleport.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/menu_viewer.xml50
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/menu_wearable_list_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/menu_wearing_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/menu_wearing_tab.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/mime_types.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/mime_types_linux.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/mime_types_mac.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/notifications.xml1091
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_active_object_row.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_adhoc_control_panel.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_avatar_list_item.xml1
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_avatar_tag.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_block_list_sidetray.xml15
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_body_parts_list_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_bodyparts_list_button_bar.xml0
-rw-r--r--indra/newview/skins/default/xui/ru/panel_bottomtray.xml47
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_bottomtray_lite.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_chat_header.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_chiclet_bar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_classified_info.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_clothing_list_button_bar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_clothing_list_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_cof_wearables.xml0
-rw-r--r--indra/newview/skins/default/xui/ru/panel_conversation_list_item.xml8
-rw-r--r--indra/newview/skins/default/xui/ru/panel_conversation_log_list_item.xml6
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_deletable_wearable_list_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_dummy_clothing_list_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_edit_alpha.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_edit_classified.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_edit_eyes.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_edit_gloves.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_edit_hair.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_edit_jacket.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_edit_pants.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_edit_physics.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_edit_pick.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_edit_profile.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_edit_shape.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_edit_shirt.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_edit_shoes.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_edit_skin.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_edit_skirt.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_edit_socks.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_edit_tattoo.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_edit_underpants.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_edit_undershirt.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_edit_wearable.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_group_control_panel.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_group_general.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_group_info_sidetray.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_group_invite.xml3
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_group_land_money.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_group_list_item.xml1
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_group_notices.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_group_notify.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_group_roles.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_im_control_panel.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_instant_message.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_inventory_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_landmark_info.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_landmarks.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_login.xml32
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_main_inventory.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_me.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_media_settings_general.xml10
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_media_settings_permissions.xml12
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_media_settings_security.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_navigation_bar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_nearby_chat.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_nearby_chat_bar.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_nearby_media.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_notify_textbox.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_online_status_toast.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_outbox_inventory.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_outfit_edit.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_outfits_inventory.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_outfits_inventory_gear_default.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_outfits_list.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_outfits_wearing.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_people.xml91
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_pick_info.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_picks.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_place_profile.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_places.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_postcard_message.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_postcard_settings.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_preferences_advanced.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_preferences_alerts.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_preferences_chat.xml126
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_preferences_colors.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_preferences_general.xml6
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_preferences_graphics1.xml22
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_preferences_move.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_preferences_privacy.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_preferences_setup.xml9
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_preferences_sound.xml8
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_prim_media_controls.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_region_covenant.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_region_debug.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_region_environment.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_region_estate.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_region_general.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_region_terrain.xml0
-rw-r--r--indra/newview/skins/default/xui/ru/panel_region_texture.xml54
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_script_ed.xml1
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_script_limits_my_avatar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_script_limits_region_memory.xml0
-rwxr-xr-xindra/newview/skins/default/xui/ru/panel_script_question_toast.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_scrolling_param.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_scrolling_param_base.xml0
-rw-r--r--indra/newview/skins/default/xui/ru/panel_side_tray.xml29
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_side_tray_tab_caption.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_snapshot_inventory.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_snapshot_local.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_snapshot_options.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_snapshot_postcard.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_snapshot_profile.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_sound_devices.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_stand_stop_flying.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_status_bar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_teleport_history.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_teleport_history_item.xml0
-rw-r--r--indra/newview/skins/default/xui/ru/panel_tools_texture.xml116
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_voice_effect.xml0
-rwxr-xr-xindra/newview/skins/default/xui/ru/panel_volume_pulldown.xml14
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/panel_world_map.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/role_actions.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/sidepanel_appearance.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/sidepanel_inventory.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/sidepanel_item_info.xml3
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/sidepanel_task_info.xml10
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/strings.xml144
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/ru/teleport_strings.xml6
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_aaa.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_about.xml23
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_about_land.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_activeim.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_animation_anim_preview.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_animation_bvh_preview.xml0
-rw-r--r--indra/newview/skins/default/xui/tr/floater_animation_preview.xml186
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_auction.xml0
-rwxr-xr-xindra/newview/skins/default/xui/tr/floater_autoreplace.xml32
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_avatar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_avatar_picker.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_avatar_textures.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_beacons.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_build_options.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_bulk_perms.xml7
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_bumps.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_buy_contents.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_buy_currency.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_buy_currency_html.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_buy_land.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_buy_object.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_camera.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_chat_bar.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_choose_group.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_color_picker.xml0
-rw-r--r--indra/newview/skins/default/xui/tr/floater_conversation_log.xml8
-rw-r--r--indra/newview/skins/default/xui/tr/floater_conversation_preview.xml7
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_critical.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_delete_env_preset.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_destinations.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_display_name.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_edit_day_cycle.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_edit_sky_preset.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_edit_water_preset.xml0
-rw-r--r--indra/newview/skins/default/xui/tr/floater_env_settings.xml25
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_environment_settings.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_event.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_fast_timers.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_font_test.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_gesture.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_god_tools.xml0
-rw-r--r--indra/newview/skins/default/xui/tr/floater_goto_line.xml7
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_hardware_settings.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_help_browser.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_how_to.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_hud.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_im_container.xml29
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_im_session.xml59
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_image_preview.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_import_collada.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_incoming_call.xml10
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_inspect.xml0
-rw-r--r--indra/newview/skins/default/xui/tr/floater_inventory.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_inventory_item_properties.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_inventory_view_finder.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_joystick.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_lagmeter.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_land_holdings.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_live_lsleditor.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_lsl_guide.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_map.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_media_browser.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_media_settings.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_mem_leaking.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_merchant_outbox.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_model_preview.xml35
-rw-r--r--indra/newview/skins/default/xui/tr/floater_model_wizard.xml208
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_moveview.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_mute_object.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_my_appearance.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_my_inventory.xml0
-rw-r--r--indra/newview/skins/default/xui/tr/floater_nearby_chat.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_notification.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_notifications_console.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_object_weights.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_openobject.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_outfit_save_as.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_outgoing_call.xml0
-rwxr-xr-xindra/newview/skins/default/xui/tr/floater_pathfinding_characters.xml57
-rwxr-xr-xindra/newview/skins/default/xui/tr/floater_pathfinding_console.xml121
-rwxr-xr-xindra/newview/skins/default/xui/tr/floater_pathfinding_linksets.xml167
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_pay.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_pay_object.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_people.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_perm_prefs.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_picks.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_places.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_post_process.xml0
-rw-r--r--indra/newview/skins/default/xui/tr/floater_postcard.xml33
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_preferences.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_preferences_proxy.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_preview_animation.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_preview_gesture.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_preview_notecard.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_preview_sound.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_preview_texture.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_price_for_listing.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_publish_classified.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_region_debug_console.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_region_info.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_report_abuse.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_script_debug.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_script_debug_panel.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_script_limits.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_script_preview.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_script_queue.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_script_search.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_search.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_select_key.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_sell_land.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_settings_debug.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_snapshot.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_sound_devices.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_sound_preview.xml0
-rwxr-xr-xindra/newview/skins/default/xui/tr/floater_spellcheck.xml18
-rwxr-xr-xindra/newview/skins/default/xui/tr/floater_spellcheck_import.xml6
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_stats.xml9
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_sys_well.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_telehub.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_test_layout_stacks.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_test_text_vertical_aligment.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_texture_ctrl.xml14
-rwxr-xr-xindra/newview/skins/default/xui/tr/floater_texture_fetch_debugger.xml77
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_tools.xml18
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_top_objects.xml10
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_tos.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_toybox.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_translation_settings.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_url_entry.xml0
-rw-r--r--indra/newview/skins/default/xui/tr/floater_voice_chat_volume.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_voice_controls.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_voice_effect.xml2
-rw-r--r--indra/newview/skins/default/xui/tr/floater_voice_volume.xml8
-rw-r--r--indra/newview/skins/default/xui/tr/floater_water.xml70
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_web_content.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_whitelist_entry.xml0
-rw-r--r--indra/newview/skins/default/xui/tr/floater_windlight_options.xml167
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_window_size.xml15
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/floater_world_map.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/inspect_avatar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/inspect_group.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/inspect_object.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/inspect_remote_object.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/menu_add_wearable_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/menu_attachment_other.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/menu_attachment_self.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/menu_avatar_icon.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/menu_avatar_other.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/menu_avatar_self.xml2
-rw-r--r--indra/newview/skins/default/xui/tr/menu_bottomtray.xml17
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/menu_cof_attachment.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/menu_cof_body_part.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/menu_cof_clothing.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/menu_cof_gear.xml2
-rw-r--r--indra/newview/skins/default/xui/tr/menu_conversation.xml32
-rw-r--r--indra/newview/skins/default/xui/tr/menu_conversation_log_gear.xml15
-rw-r--r--indra/newview/skins/default/xui/tr/menu_conversation_log_view.xml7
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/menu_edit.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/menu_favorites.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/menu_gesture_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/menu_group_plus.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/menu_hide_navbar.xml0
-rw-r--r--indra/newview/skins/default/xui/tr/menu_im_conversation.xml15
-rw-r--r--indra/newview/skins/default/xui/tr/menu_im_session_showmodes.xml7
-rw-r--r--indra/newview/skins/default/xui/tr/menu_im_well_button.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/menu_imchiclet_adhoc.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/menu_imchiclet_group.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/menu_imchiclet_p2p.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/menu_inspect_avatar_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/menu_inspect_object_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/menu_inspect_self_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/menu_inv_offer_chiclet.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/menu_inventory.xml1
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/menu_inventory_add.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/menu_inventory_gear_default.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/menu_land.xml1
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/menu_landmark.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/menu_login.xml8
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/menu_media_ctrl.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/menu_mini_map.xml0
-rw-r--r--indra/newview/skins/default/xui/tr/menu_mode_change.xml5
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/menu_model_import_gear_default.xml0
-rw-r--r--indra/newview/skins/default/xui/tr/menu_mute_particle.xml5
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/menu_navbar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/menu_nearby_chat.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/menu_notification_well_button.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/menu_object.xml3
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/menu_object_icon.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/menu_outfit_gear.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/menu_outfit_tab.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/menu_participant_list.xml0
-rw-r--r--indra/newview/skins/default/xui/tr/menu_participant_view.xml13
-rw-r--r--indra/newview/skins/default/xui/tr/menu_people_blocked_gear.xml5
-rw-r--r--indra/newview/skins/default/xui/tr/menu_people_blocked_plus.xml5
-rw-r--r--indra/newview/skins/default/xui/tr/menu_people_blocked_view.xml5
-rw-r--r--indra/newview/skins/default/xui/tr/menu_people_friends_view.xml8
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/menu_people_friends_view_sort.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/menu_people_groups.xml2
-rw-r--r--indra/newview/skins/default/xui/tr/menu_people_groups_view.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/menu_people_groups_view_sort.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/menu_people_nearby.xml23
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/menu_people_nearby_multiselect.xml14
-rw-r--r--indra/newview/skins/default/xui/tr/menu_people_nearby_view.xml8
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/menu_people_nearby_view_sort.xml0
-rw-r--r--indra/newview/skins/default/xui/tr/menu_people_recent_view.xml6
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/menu_people_recent_view_sort.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/menu_picks.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/menu_picks_plus.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/menu_place.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/menu_place_add_button.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/menu_places_gear_folder.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/menu_places_gear_landmark.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/menu_profile_overflow.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/menu_save_outfit.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/menu_script_chiclet.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/menu_slurl.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/menu_teleport_history_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/menu_teleport_history_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/menu_teleport_history_tab.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/menu_text_editor.xml7
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/menu_toolbars.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/menu_topinfobar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/menu_url_agent.xml5
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/menu_url_group.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/menu_url_http.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/menu_url_inventory.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/menu_url_map.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/menu_url_objectim.xml3
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/menu_url_parcel.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/menu_url_slapp.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/menu_url_slurl.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/menu_url_teleport.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/menu_viewer.xml64
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/menu_wearable_list_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/menu_wearing_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/menu_wearing_tab.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/mime_types.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/mime_types_linux.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/mime_types_mac.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/notifications.xml1097
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_active_object_row.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_adhoc_control_panel.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_avatar_list_item.xml1
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_avatar_tag.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_block_list_sidetray.xml15
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_body_parts_list_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_bodyparts_list_button_bar.xml0
-rw-r--r--indra/newview/skins/default/xui/tr/panel_bottomtray.xml47
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_bottomtray_lite.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_chat_header.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_chiclet_bar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_classified_info.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_clothing_list_button_bar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_clothing_list_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_cof_wearables.xml0
-rw-r--r--indra/newview/skins/default/xui/tr/panel_conversation_list_item.xml8
-rw-r--r--indra/newview/skins/default/xui/tr/panel_conversation_log_list_item.xml6
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_deletable_wearable_list_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_dummy_clothing_list_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_edit_alpha.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_edit_classified.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_edit_eyes.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_edit_gloves.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_edit_hair.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_edit_jacket.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_edit_pants.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_edit_physics.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_edit_pick.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_edit_profile.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_edit_shape.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_edit_shirt.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_edit_shoes.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_edit_skin.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_edit_skirt.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_edit_socks.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_edit_tattoo.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_edit_underpants.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_edit_undershirt.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_edit_wearable.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_group_control_panel.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_group_general.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_group_info_sidetray.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_group_invite.xml3
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_group_land_money.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_group_list_item.xml1
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_group_notices.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_group_notify.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_group_roles.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_im_control_panel.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_instant_message.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_inventory_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_landmark_info.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_landmarks.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_login.xml32
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_main_inventory.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_me.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_media_settings_general.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_media_settings_permissions.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_media_settings_security.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_navigation_bar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_nearby_chat.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_nearby_chat_bar.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_nearby_media.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_notify_textbox.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_online_status_toast.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_outbox_inventory.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_outfit_edit.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_outfits_inventory.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_outfits_inventory_gear_default.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_outfits_list.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_outfits_wearing.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_people.xml91
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_pick_info.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_picks.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_place_profile.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_places.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_postcard_message.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_postcard_settings.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_preferences_advanced.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_preferences_alerts.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_preferences_chat.xml126
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_preferences_colors.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_preferences_general.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_preferences_graphics1.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_preferences_move.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_preferences_privacy.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_preferences_setup.xml1
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_preferences_sound.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_prim_media_controls.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_region_covenant.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_region_debug.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_region_environment.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_region_estate.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_region_general.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_region_terrain.xml0
-rw-r--r--indra/newview/skins/default/xui/tr/panel_region_texture.xml54
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_script_ed.xml1
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_script_limits_my_avatar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_script_limits_region_memory.xml0
-rwxr-xr-xindra/newview/skins/default/xui/tr/panel_script_question_toast.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_scrolling_param.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_scrolling_param_base.xml0
-rw-r--r--indra/newview/skins/default/xui/tr/panel_side_tray.xml29
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_side_tray_tab_caption.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_snapshot_inventory.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_snapshot_local.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_snapshot_options.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_snapshot_postcard.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_snapshot_profile.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_sound_devices.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_stand_stop_flying.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_status_bar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_teleport_history.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_teleport_history_item.xml0
-rw-r--r--indra/newview/skins/default/xui/tr/panel_tools_texture.xml116
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_voice_effect.xml0
-rwxr-xr-xindra/newview/skins/default/xui/tr/panel_volume_pulldown.xml14
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/panel_world_map.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/role_actions.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/sidepanel_appearance.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/sidepanel_inventory.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/sidepanel_item_info.xml3
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/sidepanel_task_info.xml10
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/strings.xml146
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/tr/teleport_strings.xml6
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_aaa.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_about.xml87
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_about_land.xml243
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_activeim.xml2
-rwxr-xr-xindra/newview/skins/default/xui/zh/floater_animation_anim_preview.xml11
-rwxr-xr-xindra/newview/skins/default/xui/zh/floater_animation_bvh_preview.xml186
-rw-r--r--indra/newview/skins/default/xui/zh/floater_animation_preview.xml186
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_auction.xml12
-rwxr-xr-xindra/newview/skins/default/xui/zh/floater_autoreplace.xml32
-rwxr-xr-xindra/newview/skins/default/xui/zh/floater_avatar.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_avatar_picker.xml10
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_avatar_textures.xml14
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_beacons.xml26
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_build_options.xml29
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_bulk_perms.xml15
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_bumps.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_buy_contents.xml12
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_buy_currency.xml16
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_buy_currency_html.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_buy_land.xml124
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_buy_object.xml14
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_camera.xml23
-rwxr-xr-xindra/newview/skins/default/xui/zh/floater_chat_bar.xml7
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_choose_group.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_color_picker.xml8
-rw-r--r--indra/newview/skins/default/xui/zh/floater_conversation_log.xml8
-rw-r--r--indra/newview/skins/default/xui/zh/floater_conversation_preview.xml7
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_critical.xml0
-rwxr-xr-xindra/newview/skins/default/xui/zh/floater_delete_env_preset.xml35
-rwxr-xr-xindra/newview/skins/default/xui/zh/floater_destinations.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_display_name.xml10
-rwxr-xr-xindra/newview/skins/default/xui/zh/floater_edit_day_cycle.xml104
-rwxr-xr-xindra/newview/skins/default/xui/zh/floater_edit_sky_preset.xml143
-rwxr-xr-xindra/newview/skins/default/xui/zh/floater_edit_water_preset.xml72
-rw-r--r--indra/newview/skins/default/xui/zh/floater_env_settings.xml25
-rwxr-xr-xindra/newview/skins/default/xui/zh/floater_environment_settings.xml36
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_event.xml4
-rwxr-xr-xindra/newview/skins/default/xui/zh/floater_fast_timers.xml10
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_font_test.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_gesture.xml6
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_god_tools.xml86
-rw-r--r--indra/newview/skins/default/xui/zh/floater_goto_line.xml7
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_hardware_settings.xml28
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_help_browser.xml0
-rwxr-xr-xindra/newview/skins/default/xui/zh/floater_how_to.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_hud.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_im_container.xml29
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_im_session.xml59
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_image_preview.xml2
-rwxr-xr-xindra/newview/skins/default/xui/zh/floater_import_collada.xml23
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_incoming_call.xml18
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_inspect.xml10
-rw-r--r--indra/newview/skins/default/xui/zh/floater_inventory.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_inventory_item_properties.xml16
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_inventory_view_finder.xml11
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_joystick.xml74
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_lagmeter.xml28
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_land_holdings.xml16
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_live_lsleditor.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_lsl_guide.xml10
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_map.xml36
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_media_browser.xml12
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_media_settings.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_mem_leaking.xml12
-rwxr-xr-xindra/newview/skins/default/xui/zh/floater_merchant_outbox.xml27
-rwxr-xr-xindra/newview/skins/default/xui/zh/floater_model_preview.xml312
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_moveview.xml20
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_mute_object.xml4
-rwxr-xr-xindra/newview/skins/default/xui/zh/floater_my_appearance.xml4
-rwxr-xr-xindra/newview/skins/default/xui/zh/floater_my_inventory.xml2
-rw-r--r--indra/newview/skins/default/xui/zh/floater_nearby_chat.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_notification.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_notifications_console.xml0
-rwxr-xr-xindra/newview/skins/default/xui/zh/floater_object_weights.xml28
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_openobject.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_outfit_save_as.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_outgoing_call.xml20
-rwxr-xr-xindra/newview/skins/default/xui/zh/floater_pathfinding_characters.xml57
-rwxr-xr-xindra/newview/skins/default/xui/zh/floater_pathfinding_console.xml121
-rwxr-xr-xindra/newview/skins/default/xui/zh/floater_pathfinding_linksets.xml167
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_pay.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_pay_object.xml4
-rwxr-xr-xindra/newview/skins/default/xui/zh/floater_people.xml7
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_perm_prefs.xml4
-rwxr-xr-xindra/newview/skins/default/xui/zh/floater_picks.xml2
-rwxr-xr-xindra/newview/skins/default/xui/zh/floater_places.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_post_process.xml36
-rw-r--r--indra/newview/skins/default/xui/zh/floater_postcard.xml33
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_preferences.xml6
-rwxr-xr-xindra/newview/skins/default/xui/zh/floater_preferences_proxy.xml40
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_preview_animation.xml6
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_preview_gesture.xml32
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_preview_notecard.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_preview_sound.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_preview_texture.xml20
-rwxr-xr-xindra/newview/skins/default/xui/zh/floater_price_for_listing.xml18
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_publish_classified.xml8
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_region_debug_console.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_region_info.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_report_abuse.xml92
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_script_debug.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_script_debug_panel.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_script_limits.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_script_preview.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_script_queue.xml6
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_script_search.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_search.xml6
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_select_key.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_sell_land.xml26
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_settings_debug.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_snapshot.xml123
-rwxr-xr-xindra/newview/skins/default/xui/zh/floater_sound_devices.xml7
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_sound_preview.xml0
-rwxr-xr-xindra/newview/skins/default/xui/zh/floater_spellcheck.xml18
-rwxr-xr-xindra/newview/skins/default/xui/zh/floater_spellcheck_import.xml6
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_stats.xml87
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_sys_well.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_telehub.xml28
-rwxr-xr-xindra/newview/skins/default/xui/zh/floater_test_layout_stacks.xml2
-rwxr-xr-xindra/newview/skins/default/xui/zh/floater_test_text_vertical_aligment.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_texture_ctrl.xml22
-rwxr-xr-xindra/newview/skins/default/xui/zh/floater_texture_fetch_debugger.xml77
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_tools.xml322
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_top_objects.xml36
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_tos.xml4
-rwxr-xr-xindra/newview/skins/default/xui/zh/floater_toybox.xml11
-rwxr-xr-xindra/newview/skins/default/xui/zh/floater_translation_settings.xml58
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_url_entry.xml0
-rw-r--r--indra/newview/skins/default/xui/zh/floater_voice_chat_volume.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_voice_controls.xml8
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_voice_effect.xml149
-rw-r--r--indra/newview/skins/default/xui/zh/floater_voice_volume.xml8
-rw-r--r--indra/newview/skins/default/xui/zh/floater_water.xml70
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_web_content.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_whitelist_entry.xml0
-rw-r--r--indra/newview/skins/default/xui/zh/floater_windlight_options.xml167
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_window_size.xml15
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/floater_world_map.xml18
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/inspect_avatar.xml10
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/inspect_group.xml8
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/inspect_object.xml26
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/inspect_remote_object.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/menu_add_wearable_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/menu_attachment_other.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/menu_attachment_self.xml6
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/menu_avatar_icon.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/menu_avatar_other.xml6
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/menu_avatar_self.xml10
-rw-r--r--indra/newview/skins/default/xui/zh/menu_bottomtray.xml17
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/menu_cof_attachment.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/menu_cof_body_part.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/menu_cof_clothing.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/menu_cof_gear.xml2
-rw-r--r--indra/newview/skins/default/xui/zh/menu_conversation.xml32
-rw-r--r--indra/newview/skins/default/xui/zh/menu_conversation_log_gear.xml15
-rw-r--r--indra/newview/skins/default/xui/zh/menu_conversation_log_view.xml7
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/menu_edit.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/menu_favorites.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/menu_gesture_gear.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/menu_group_plus.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/menu_hide_navbar.xml2
-rw-r--r--indra/newview/skins/default/xui/zh/menu_im_conversation.xml15
-rw-r--r--indra/newview/skins/default/xui/zh/menu_im_session_showmodes.xml7
-rw-r--r--indra/newview/skins/default/xui/zh/menu_im_well_button.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/menu_imchiclet_adhoc.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/menu_imchiclet_group.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/menu_imchiclet_p2p.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/menu_inspect_avatar_gear.xml8
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/menu_inspect_object_gear.xml9
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/menu_inspect_self_gear.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/menu_inv_offer_chiclet.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/menu_inventory.xml46
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/menu_inventory_add.xml6
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/menu_inventory_gear_default.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/menu_land.xml5
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/menu_landmark.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/menu_login.xml18
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/menu_media_ctrl.xml3
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/menu_mini_map.xml8
-rwxr-xr-xindra/newview/skins/default/xui/zh/menu_model_import_gear_default.xml8
-rw-r--r--indra/newview/skins/default/xui/zh/menu_mute_particle.xml5
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/menu_navbar.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/menu_nearby_chat.xml8
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/menu_notification_well_button.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/menu_object.xml15
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/menu_object_icon.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/menu_outfit_gear.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/menu_outfit_tab.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/menu_participant_list.xml18
-rw-r--r--indra/newview/skins/default/xui/zh/menu_participant_view.xml13
-rw-r--r--indra/newview/skins/default/xui/zh/menu_people_blocked_gear.xml5
-rw-r--r--indra/newview/skins/default/xui/zh/menu_people_blocked_plus.xml5
-rw-r--r--indra/newview/skins/default/xui/zh/menu_people_blocked_view.xml5
-rw-r--r--indra/newview/skins/default/xui/zh/menu_people_friends_view.xml8
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/menu_people_friends_view_sort.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/menu_people_groups.xml6
-rw-r--r--indra/newview/skins/default/xui/zh/menu_people_groups_view.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/menu_people_groups_view_sort.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/menu_people_nearby.xml23
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/menu_people_nearby_multiselect.xml14
-rw-r--r--indra/newview/skins/default/xui/zh/menu_people_nearby_view.xml8
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/menu_people_nearby_view_sort.xml3
-rw-r--r--indra/newview/skins/default/xui/zh/menu_people_recent_view.xml6
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/menu_people_recent_view_sort.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/menu_picks.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/menu_picks_plus.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/menu_place.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/menu_place_add_button.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/menu_places_gear_folder.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/menu_places_gear_landmark.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/menu_profile_overflow.xml6
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/menu_save_outfit.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/menu_script_chiclet.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/menu_slurl.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/menu_teleport_history_gear.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/menu_teleport_history_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/menu_teleport_history_tab.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/menu_text_editor.xml9
-rwxr-xr-xindra/newview/skins/default/xui/zh/menu_toolbars.xml7
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/menu_topinfobar.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/menu_url_agent.xml5
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/menu_url_group.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/menu_url_http.xml6
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/menu_url_inventory.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/menu_url_map.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/menu_url_objectim.xml3
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/menu_url_parcel.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/menu_url_slapp.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/menu_url_slurl.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/menu_url_teleport.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/menu_viewer.xml427
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/menu_wearable_list_item.xml8
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/menu_wearing_gear.xml1
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/menu_wearing_tab.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/mime_types.xml10
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/mime_types_linux.xml10
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/mime_types_mac.xml12
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/notifications.xml2949
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_active_object_row.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_adhoc_control_panel.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_avatar_list_item.xml19
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_avatar_tag.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_block_list_sidetray.xml15
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_body_parts_list_item.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_bodyparts_list_button_bar.xml2
-rw-r--r--indra/newview/skins/default/xui/zh/panel_bottomtray.xml47
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_bottomtray_lite.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_chat_header.xml0
-rwxr-xr-xindra/newview/skins/default/xui/zh/panel_chiclet_bar.xml15
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_classified_info.xml26
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_clothing_list_button_bar.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_clothing_list_item.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_cof_wearables.xml2
-rw-r--r--indra/newview/skins/default/xui/zh/panel_conversation_list_item.xml8
-rw-r--r--indra/newview/skins/default/xui/zh/panel_conversation_log_list_item.xml6
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_deletable_wearable_list_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_dummy_clothing_list_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_edit_alpha.xml10
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_edit_classified.xml26
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_edit_eyes.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_edit_gloves.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_edit_hair.xml8
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_edit_jacket.xml6
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_edit_pants.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_edit_physics.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_edit_pick.xml6
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_edit_profile.xml26
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_edit_shape.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_edit_shirt.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_edit_shoes.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_edit_skin.xml14
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_edit_skirt.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_edit_socks.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_edit_tattoo.xml8
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_edit_underpants.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_edit_undershirt.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_edit_wearable.xml30
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_group_control_panel.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_group_general.xml28
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_group_info_sidetray.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_group_invite.xml19
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_group_land_money.xml34
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_group_list_item.xml1
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_group_notices.xml14
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_group_notify.xml6
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_group_roles.xml31
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_im_control_panel.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_instant_message.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_inventory_item.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_landmark_info.xml16
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_landmarks.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_login.xml34
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_main_inventory.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_me.xml7
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_media_settings_general.xml16
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_media_settings_permissions.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_media_settings_security.xml8
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_navigation_bar.xml35
-rwxr-xr-xindra/newview/skins/default/xui/zh/panel_navmesh_rebake.xml6
-rwxr-xr-xindra/newview/skins/default/xui/zh/panel_nearby_chat.xml8
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_nearby_chat_bar.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_nearby_media.xml18
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_notify_textbox.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_online_status_toast.xml0
-rwxr-xr-xindra/newview/skins/default/xui/zh/panel_outbox_inventory.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_outfit_edit.xml10
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_outfits_inventory.xml8
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_outfits_inventory_gear_default.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_outfits_list.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_outfits_wearing.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_people.xml109
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_pick_info.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_picks.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_place_profile.xml44
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_places.xml4
-rwxr-xr-xindra/newview/skins/default/xui/zh/panel_postcard_message.xml21
-rwxr-xr-xindra/newview/skins/default/xui/zh/panel_postcard_settings.xml23
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_preferences_advanced.xml13
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_preferences_alerts.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_preferences_chat.xml150
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_preferences_colors.xml11
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_preferences_general.xml35
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_preferences_graphics1.xml26
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_preferences_move.xml31
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_preferences_privacy.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_preferences_setup.xml26
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_preferences_sound.xml34
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_prim_media_controls.xml24
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_region_covenant.xml22
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_region_debug.xml6
-rwxr-xr-xindra/newview/skins/default/xui/zh/panel_region_environment.xml33
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_region_estate.xml12
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_region_general.xml13
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_region_terrain.xml53
-rw-r--r--indra/newview/skins/default/xui/zh/panel_region_texture.xml54
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_script_ed.xml7
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_script_limits_my_avatar.xml6
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_script_limits_region_memory.xml8
-rwxr-xr-xindra/newview/skins/default/xui/zh/panel_script_question_toast.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_scrolling_param.xml0
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_scrolling_param_base.xml0
-rw-r--r--indra/newview/skins/default/xui/zh/panel_side_tray.xml29
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_side_tray_tab_caption.xml0
-rwxr-xr-xindra/newview/skins/default/xui/zh/panel_snapshot_inventory.xml21
-rwxr-xr-xindra/newview/skins/default/xui/zh/panel_snapshot_local.xml39
-rwxr-xr-xindra/newview/skins/default/xui/zh/panel_snapshot_options.xml7
-rwxr-xr-xindra/newview/skins/default/xui/zh/panel_snapshot_postcard.xml17
-rwxr-xr-xindra/newview/skins/default/xui/zh/panel_snapshot_profile.xml28
-rwxr-xr-xindra/newview/skins/default/xui/zh/panel_sound_devices.xml25
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_stand_stop_flying.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_status_bar.xml7
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_teleport_history.xml4
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_teleport_history_item.xml0
-rw-r--r--indra/newview/skins/default/xui/zh/panel_tools_texture.xml116
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_voice_effect.xml0
-rwxr-xr-xindra/newview/skins/default/xui/zh/panel_volume_pulldown.xml14
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/panel_world_map.xml46
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/role_actions.xml114
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/sidepanel_appearance.xml2
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/sidepanel_inventory.xml25
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/sidepanel_item_info.xml23
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/sidepanel_task_info.xml50
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/strings.xml2486
-rwxr-xr-x[-rw-r--r--]indra/newview/skins/default/xui/zh/teleport_strings.xml30
-rw-r--r--indra/newview/skins/paths.xml10
-rwxr-xr-x[-rw-r--r--]indra/newview/tests/gpus_results.txt0
-rwxr-xr-x[-rw-r--r--]indra/newview/tests/gpus_seen.txt0
-rwxr-xr-x[-rw-r--r--]indra/newview/tests/llagentaccess_test.cpp110
-rwxr-xr-x[-rw-r--r--]indra/newview/tests/llcapabilitylistener_test.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/tests/lldateutil_test.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/tests/lldir_stub.cpp4
-rwxr-xr-x[-rw-r--r--]indra/newview/tests/llglslshader_stub.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/tests/lllogininstance_test.cpp52
-rwxr-xr-x[-rw-r--r--]indra/newview/tests/llmediadataclient_test.cpp5
-rwxr-xr-x[-rw-r--r--]indra/newview/tests/llpipeline_stub.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/tests/llremoteparcelrequest_test.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/tests/llsecapi_test.cpp4
-rwxr-xr-x[-rw-r--r--]indra/newview/tests/llsechandler_basic_test.cpp4
-rwxr-xr-x[-rw-r--r--]indra/newview/tests/llsimplestat_test.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/tests/llsky_stub.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/tests/llslurl_test.cpp203
-rwxr-xr-x[-rw-r--r--]indra/newview/tests/lltextureinfo_test.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/tests/lltextureinfodetails_test.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/tests/lltexturestatsuploader_test.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/tests/lltranslate_test.cpp9
-rwxr-xr-x[-rw-r--r--]indra/newview/tests/llversioninfo_test.cpp28
-rwxr-xr-x[-rw-r--r--]indra/newview/tests/llviewerassetstats_test.cpp11
-rwxr-xr-x[-rw-r--r--]indra/newview/tests/llviewerhelputil_test.cpp4
-rwxr-xr-x[-rw-r--r--]indra/newview/tests/llviewernetwork_test.cpp711
-rwxr-xr-x[-rw-r--r--]indra/newview/tests/llviewershadermgr_stub.cpp0
-rw-r--r--indra/newview/tests/llviewertexture_stub.cpp34
-rwxr-xr-x[-rw-r--r--]indra/newview/tests/llwlanimator_stub.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/tests/llwldaycycle_stub.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/tests/llwlparammanager_test.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/tests/llwlparamset_stub.cpp0
-rwxr-xr-x[-rw-r--r--]indra/newview/tests/llworldmap_test.cpp6
-rwxr-xr-x[-rw-r--r--]indra/newview/tests/llworldmipmap_test.cpp4
-rwxr-xr-x[-rw-r--r--]indra/newview/tests/llxmlrpclistener_test.cpp4
-rwxr-xr-x[-rw-r--r--]indra/newview/tests/test_llxmlrpc_peer.py0
-rwxr-xr-x[-rw-r--r--]indra/newview/tr.lproj/language.txt0
-rwxr-xr-x[-rw-r--r--]indra/newview/uk.lproj/language.txt0
-rwxr-xr-x[-rw-r--r--]indra/newview/viewer_manifest.py596
-rwxr-xr-x[-rw-r--r--]indra/newview/zh-Hans.lproj/language.txt0
-rwxr-xr-x[-rw-r--r--]indra/test/CMakeLists.txt4
-rwxr-xr-x[-rw-r--r--]indra/test/blowfish.1.bin0
-rwxr-xr-x[-rw-r--r--]indra/test/blowfish.2.binbin40 -> 40 bytes
-rwxr-xr-x[-rw-r--r--]indra/test/blowfish.digits.txt0
-rwxr-xr-xindra/test/catch_and_store_what_in.h86
-rwxr-xr-x[-rw-r--r--]indra/test/debug.h0
-rwxr-xr-x[-rw-r--r--]indra/test/io.cpp10
-rwxr-xr-x[-rw-r--r--]indra/test/llapp_tut.cpp0
-rwxr-xr-x[-rw-r--r--]indra/test/llassetuploadqueue_tut.cpp0
-rwxr-xr-x[-rw-r--r--]indra/test/llblowfish_tut.cpp0
-rwxr-xr-x[-rw-r--r--]indra/test/llbuffer_tut.cpp1
-rwxr-xr-x[-rw-r--r--]indra/test/lldatapacker_tut.cpp0
-rwxr-xr-x[-rw-r--r--]indra/test/lldoubledispatch_tut.cpp0
-rwxr-xr-x[-rw-r--r--]indra/test/llevents_tut.cpp78
-rwxr-xr-x[-rw-r--r--]indra/test/llhttpdate_tut.cpp0
-rwxr-xr-x[-rw-r--r--]indra/test/llhttpnode_tut.cpp0
-rwxr-xr-x[-rw-r--r--]indra/test/lliohttpserver_tut.cpp0
-rwxr-xr-x[-rw-r--r--]indra/test/llmessageconfig_tut.cpp0
-rwxr-xr-x[-rw-r--r--]indra/test/llmessagetemplateparser_tut.cpp0
-rwxr-xr-x[-rw-r--r--]indra/test/llpermissions_tut.cpp10
-rwxr-xr-x[-rw-r--r--]indra/test/llpipeutil.cpp0
-rwxr-xr-x[-rw-r--r--]indra/test/llpipeutil.h0
-rwxr-xr-x[-rw-r--r--]indra/test/llsaleinfo_tut.cpp3
-rwxr-xr-x[-rw-r--r--]indra/test/llscriptresource_tut.cpp0
-rwxr-xr-x[-rw-r--r--]indra/test/llsd_new_tut.cpp0
-rwxr-xr-x[-rw-r--r--]indra/test/llsdmessagebuilder_tut.cpp0
-rwxr-xr-x[-rw-r--r--]indra/test/llsdmessagereader_tut.cpp0
-rwxr-xr-x[-rw-r--r--]indra/test/llsdtraits.h0
-rwxr-xr-x[-rw-r--r--]indra/test/llsdutil_tut.cpp0
-rwxr-xr-x[-rw-r--r--]indra/test/llservicebuilder_tut.cpp0
-rwxr-xr-x[-rw-r--r--]indra/test/llstreamtools_tut.cpp53
-rwxr-xr-x[-rw-r--r--]indra/test/lltemplatemessagebuilder_tut.cpp4
-rwxr-xr-x[-rw-r--r--]indra/test/lltimestampcache_tut.cpp0
-rwxr-xr-x[-rw-r--r--]indra/test/lltranscode_tut.cpp0
-rwxr-xr-x[-rw-r--r--]indra/test/lltut.cpp0
-rwxr-xr-x[-rw-r--r--]indra/test/lltut.h0
-rwxr-xr-x[-rw-r--r--]indra/test/lluserrelations_tut.cpp0
-rwxr-xr-x[-rw-r--r--]indra/test/lluuidhashmap_tut.cpp142
-rwxr-xr-x[-rw-r--r--]indra/test/llxorcipher_tut.cpp0
-rwxr-xr-xindra/test/manageapr.h46
-rwxr-xr-x[-rw-r--r--]indra/test/message_tut.cpp0
-rwxr-xr-x[-rw-r--r--]indra/test/mock_http_client.cpp0
-rwxr-xr-x[-rw-r--r--]indra/test/mock_http_client.h0
-rwxr-xr-xindra/test/namedtempfile.h205
-rwxr-xr-x[-rw-r--r--]indra/test/prim_linkability_tut.cpp0
-rwxr-xr-x[-rw-r--r--]indra/test/test.cpp167
-rwxr-xr-x[-rw-r--r--]indra/test/test.h0
-rwxr-xr-x[-rw-r--r--]indra/test/test_llmanifest.py0
-rw-r--r--indra/test_apps/llfbconnecttest/CMakeLists.txt304
-rw-r--r--indra/test_apps/llfbconnecttest/bookmarks.txt4
-rw-r--r--indra/test_apps/llfbconnecttest/llfbconnecttest.cpp2394
-rw-r--r--indra/test_apps/llfbconnecttest/llfbconnecttest.h207
-rwxr-xr-x[-rw-r--r--]indra/test_apps/llplugintest/CMakeLists.txt5
-rwxr-xr-x[-rw-r--r--]indra/test_apps/llplugintest/bookmarks.txt0
-rwxr-xr-x[-rw-r--r--]indra/test_apps/llplugintest/llmediaplugintest.cpp0
-rwxr-xr-x[-rw-r--r--]indra/test_apps/llplugintest/llmediaplugintest.h0
-rwxr-xr-x[-rw-r--r--]indra/tools/vstool/README.txt0
-rwxr-xr-x[-rw-r--r--]indra/tools/vstool/VSTool.csproj0
-rwxr-xr-x[-rw-r--r--]indra/tools/vstool/VSTool.sln0
-rwxr-xr-x[-rw-r--r--]indra/tools/vstool/main.cs0
-rwxr-xr-x[-rw-r--r--]indra/viewer_components/CMakeLists.txt0
-rwxr-xr-x[-rw-r--r--]indra/viewer_components/login/CMakeLists.txt11
-rwxr-xr-x[-rw-r--r--]indra/viewer_components/login/lllogin.cpp47
-rwxr-xr-x[-rw-r--r--]indra/viewer_components/login/lllogin.h0
-rwxr-xr-x[-rw-r--r--]indra/viewer_components/login/tests/lllogin_test.cpp0
-rwxr-xr-x[-rw-r--r--]indra/viewer_components/updater/CMakeLists.txt10
-rwxr-xr-x[-rw-r--r--]indra/viewer_components/updater/llupdatechecker.cpp162
-rwxr-xr-x[-rw-r--r--]indra/viewer_components/updater/llupdatechecker.h75
-rwxr-xr-x[-rw-r--r--]indra/viewer_components/updater/llupdatedownloader.cpp231
-rwxr-xr-x[-rw-r--r--]indra/viewer_components/updater/llupdatedownloader.h2
-rwxr-xr-x[-rw-r--r--]indra/viewer_components/updater/llupdateinstaller.cpp22
-rwxr-xr-x[-rw-r--r--]indra/viewer_components/updater/llupdateinstaller.h0
-rwxr-xr-x[-rw-r--r--]indra/viewer_components/updater/llupdaterservice.cpp223
-rwxr-xr-x[-rw-r--r--]indra/viewer_components/updater/llupdaterservice.h13
-rw-r--r--indra/viewer_components/updater/scripts/darwin/janitor.py133
-rw-r--r--indra/viewer_components/updater/scripts/darwin/messageframe.py66
-rw-r--r--indra/viewer_components/updater/scripts/darwin/update_install10
-rwxr-xr-xindra/viewer_components/updater/scripts/darwin/update_install.py400
-rwxr-xr-x[-rw-r--r--]indra/viewer_components/updater/scripts/linux/update_install222
-rwxr-xr-x[-rw-r--r--]indra/viewer_components/updater/tests/llupdaterservice_test.cpp44
-rwxr-xr-x[-rw-r--r--]indra/win_crash_logger/CMakeLists.txt5
-rwxr-xr-x[-rw-r--r--]indra/win_crash_logger/StdAfx.cpp0
-rwxr-xr-x[-rw-r--r--]indra/win_crash_logger/StdAfx.h0
-rwxr-xr-x[-rw-r--r--]indra/win_crash_logger/ll_icon.icobin2238 -> 2238 bytes
-rwxr-xr-x[-rw-r--r--]indra/win_crash_logger/llcrashloggerwindows.cpp0
-rwxr-xr-x[-rw-r--r--]indra/win_crash_logger/llcrashloggerwindows.h0
-rwxr-xr-x[-rw-r--r--]indra/win_crash_logger/resource.h0
-rwxr-xr-x[-rw-r--r--]indra/win_crash_logger/win_crash_logger.cpp0
-rwxr-xr-x[-rw-r--r--]indra/win_crash_logger/win_crash_logger.h0
-rwxr-xr-x[-rw-r--r--]indra/win_crash_logger/win_crash_logger.icobin1078 -> 1078 bytes
-rwxr-xr-x[-rw-r--r--]indra/win_crash_logger/win_crash_logger.rc0
-rwxr-xr-x[-rw-r--r--]indra/win_updater/CMakeLists.txt0
-rwxr-xr-x[-rw-r--r--]indra/win_updater/updater.cpp0
8546 files changed, 213833 insertions, 100912 deletions
diff --git a/indra/CMakeLists.txt b/indra/CMakeLists.txt
index 4b1bf49d07..410d25ad97 100644..100755
--- a/indra/CMakeLists.txt
+++ b/indra/CMakeLists.txt
@@ -3,14 +3,8 @@
# cmake_minimum_required should appear before any
# other commands to guarantee full compatibility
# with the version specified
-
-# The "cmake -E touch" command was released with 2.4.8.
-cmake_minimum_required(VERSION 2.4.8 FATAL_ERROR)
-
-# This makes cmake 2.6 not complain about version 2.4 compatibility.
-if (COMMAND cmake_policy)
- cmake_policy(SET CMP0003 OLD)
-endif (COMMAND cmake_policy)
+## prior to 2.8, the add_custom_target commands used in setting the version did not work correctly
+cmake_minimum_required(VERSION 2.8.8 FATAL_ERROR)
set(ROOT_PROJECT_NAME "SecondLife" CACHE STRING
"The root project/makefile/solution name. Defaults to SecondLife.")
@@ -19,13 +13,7 @@ project(${ROOT_PROJECT_NAME})
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
include(Variables)
-
-if (DARWIN)
- # 2.6.4 fixes a Mac bug in get_target_property(... "SLPlugin" LOCATION):
- # before that version it returns "pathname/SLPlugin", whereas the correct
- # answer is "pathname/SLPlugin.app/Contents/MacOS/SLPlugin".
- cmake_minimum_required(VERSION 2.6.4 FATAL_ERROR)
-endif (DARWIN)
+include(BuildVersion)
if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING
@@ -41,8 +29,10 @@ endif ("${CMAKE_SOURCE_DIR}/../autobuild.xml" IS_NEWER_THAN "${CMAKE_BINARY_DIR}
add_subdirectory(cmake)
add_subdirectory(${LIBS_OPEN_PREFIX}llaudio)
+add_subdirectory(${LIBS_OPEN_PREFIX}llappearance)
add_subdirectory(${LIBS_OPEN_PREFIX}llcharacter)
add_subdirectory(${LIBS_OPEN_PREFIX}llcommon)
+add_subdirectory(${LIBS_OPEN_PREFIX}llcorehttp)
add_subdirectory(${LIBS_OPEN_PREFIX}llimage)
add_subdirectory(${LIBS_OPEN_PREFIX}llkdu)
add_subdirectory(${LIBS_OPEN_PREFIX}llimagej2coj)
@@ -62,73 +52,53 @@ if (WINDOWS AND EXISTS ${LIBS_CLOSED_DIR}copy_win_scripts)
endif (WINDOWS AND EXISTS ${LIBS_CLOSED_DIR}copy_win_scripts)
add_custom_target(viewer)
-if (VIEWER)
- add_subdirectory(${LIBS_OPEN_PREFIX}llcrashlogger)
- add_subdirectory(${LIBS_OPEN_PREFIX}llplugin)
- add_subdirectory(${LIBS_OPEN_PREFIX}llui)
- add_subdirectory(${LIBS_OPEN_PREFIX}llxuixml)
- add_subdirectory(${LIBS_OPEN_PREFIX}viewer_components)
+add_subdirectory(${LIBS_OPEN_PREFIX}llcrashlogger)
+add_subdirectory(${LIBS_OPEN_PREFIX}llplugin)
+add_subdirectory(${LIBS_OPEN_PREFIX}llui)
+add_subdirectory(${LIBS_OPEN_PREFIX}viewer_components)
- # Legacy C++ tests. Build always, run if LL_TESTS is true.
- add_subdirectory(${VIEWER_PREFIX}test)
+# Legacy C++ tests. Build always, run if LL_TESTS is true.
+add_subdirectory(${VIEWER_PREFIX}test)
- # viewer media plugins
- add_subdirectory(${LIBS_OPEN_PREFIX}media_plugins)
+# viewer media plugins
+add_subdirectory(${LIBS_OPEN_PREFIX}media_plugins)
# llplugin testbed code (is this the right way to include it?)
if (LL_TESTS AND NOT LINUX)
add_subdirectory(${VIEWER_PREFIX}test_apps/llplugintest)
+ add_subdirectory(${VIEWER_PREFIX}test_apps/llfbconnecttest)
endif (LL_TESTS AND NOT LINUX)
- if (LINUX)
- add_subdirectory(${VIEWER_PREFIX}linux_crash_logger)
- add_subdirectory(${VIEWER_PREFIX}linux_updater)
- add_dependencies(viewer linux-crash-logger-strip-target linux-updater)
- elseif (DARWIN)
- add_subdirectory(${VIEWER_PREFIX}mac_crash_logger)
- add_subdirectory(${VIEWER_PREFIX}mac_updater)
- add_dependencies(viewer mac-updater mac-crash-logger)
- elseif (WINDOWS)
- add_subdirectory(${VIEWER_PREFIX}win_crash_logger)
- # cmake EXISTS requires an absolute path, see indra/cmake/Variables.cmake
- if (EXISTS ${VIEWER_DIR}win_setup)
- add_subdirectory(${VIEWER_DIR}win_setup)
- endif (EXISTS ${VIEWER_DIR}win_setup)
- add_subdirectory(${VIEWER_PREFIX}win_updater)
- # add_dependencies(viewer windows-updater windows-setup windows-crash-logger)
- add_dependencies(viewer windows-updater windows-crash-logger)
- elseif (SOLARIS)
- add_subdirectory(solaris_crash_logger)
- add_dependencies(viewer solaris-crash-logger)
- endif (LINUX)
-
- add_subdirectory(${VIEWER_PREFIX}newview)
- add_dependencies(viewer secondlife-bin)
-endif (VIEWER)
-
-# Linux builds the viewer and server in 2 separate projects
-# In order for build server to work on linux,
-# the viewer project needs a server target.
-# This is not true for mac and windows.
-if (LINUX)
- add_custom_target(server)
+if (LINUX)
+ add_subdirectory(${VIEWER_PREFIX}linux_crash_logger)
+ add_subdirectory(${VIEWER_PREFIX}linux_updater)
+ if (INSTALL_PROPRIETARY)
+ include(LLAppearanceUtility)
+ add_subdirectory(${LLAPPEARANCEUTILITY_SRC_DIR} ${LLAPPEARANCEUTILITY_BIN_DIR})
+ endif (INSTALL_PROPRIETARY)
+ add_dependencies(viewer linux-crash-logger-strip-target linux-updater)
+elseif (DARWIN)
+ add_subdirectory(${VIEWER_PREFIX}mac_crash_logger)
+ add_dependencies(viewer mac-crash-logger)
+elseif (WINDOWS)
+ add_subdirectory(${VIEWER_PREFIX}win_crash_logger)
+ # cmake EXISTS requires an absolute path, see indra/cmake/Variables.cmake
+ if (EXISTS ${VIEWER_DIR}win_setup)
+ add_subdirectory(${VIEWER_DIR}win_setup)
+ endif (EXISTS ${VIEWER_DIR}win_setup)
+ add_subdirectory(${VIEWER_PREFIX}win_updater)
+ # add_dependencies(viewer windows-updater windows-setup windows-crash-logger)
+ add_dependencies(viewer windows-updater windows-crash-logger)
+elseif (SOLARIS)
+ add_subdirectory(solaris_crash_logger)
+ add_dependencies(viewer solaris-crash-logger)
endif (LINUX)
-if (SERVER)
- if (NOT LINUX)
- add_custom_target(server)
- endif (NOT LINUX)
- include(${SERVER_PREFIX}Server.cmake)
-endif (SERVER)
-
-# Windows builds include tools like VFS tool
-if (SERVER)
- if (WINDOWS)
- add_subdirectory(${SERVER_PREFIX}tools)
- endif (WINDOWS)
-endif (SERVER)
+
+add_subdirectory(${VIEWER_PREFIX}newview)
+add_dependencies(viewer secondlife-bin)
if (LL_TESTS)
- # Define after the custom viewer and server targets are created so
+ # Define after the custom targets are created so
# individual apps can add themselves as dependencies
add_subdirectory(${INTEGRATION_TESTS_PREFIX}integration_tests)
endif (LL_TESTS)
diff --git a/indra/cmake/00-Common.cmake b/indra/cmake/00-Common.cmake
index 98eeed09b3..87484f4ae3 100644..100755
--- a/indra/cmake/00-Common.cmake
+++ b/indra/cmake/00-Common.cmake
@@ -2,6 +2,9 @@
#
# Compilation options shared by all Second Life components.
+if(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED)
+set(${CMAKE_CURRENT_LIST_FILE}_INCLUDED "YES")
+
include(Variables)
# Portable compilation flags.
@@ -51,6 +54,7 @@ if (WINDOWS)
set(CMAKE_CXX_FLAGS_RELEASE
"${CMAKE_CXX_FLAGS_RELEASE} ${LL_CXX_FLAGS} /O2 /Zi /MD /MP /Ob2 -D_SECURE_STL=0 -D_HAS_ITERATOR_DEBUGGING=0"
CACHE STRING "C++ compiler release options" FORCE)
+ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /LARGEADDRESSAWARE")
set(CMAKE_CXX_STANDARD_LIBRARIES "")
set(CMAKE_C_STANDARD_LIBRARIES "")
@@ -69,6 +73,7 @@ if (WINDOWS)
/Oy-
/Zc:wchar_t-
/arch:SSE2
+ /fp:fast
)
# Are we using the crummy Visual Studio KDU build workaround?
@@ -126,6 +131,17 @@ if (LINUX)
# Let's actually get a numerical version of gxx's version
STRING(REGEX REPLACE ".* ([0-9])\\.([0-9])\\.([0-9]).*" "\\1\\2\\3" CXX_VERSION_NUMBER ${CXX_VERSION})
+ # Hacks to work around gcc 4.1 TC build pool machines which can't process pragma warning disables
+ # This is pure rubbish; I wish there was another way.
+ #
+ if(${CXX_VERSION_NUMBER} LESS 420)
+ set(CMAKE_CXX_FLAGS "-Wno-deprecated -Wno-uninitialized -Wno-unused-variable -Wno-unused-function ${CMAKE_CXX_FLAGS}")
+ endif (${CXX_VERSION_NUMBER} LESS 420)
+
+ if(${CXX_VERSION_NUMBER} GREATER 459)
+ set(CMAKE_CXX_FLAGS "-Wno-deprecated -Wno-unused-but-set-variable -Wno-unused-variable ${CMAKE_CXX_FLAGS}")
+ endif (${CXX_VERSION_NUMBER} GREATER 459)
+
# gcc 4.3 and above don't like the LL boost and also
# cause warnings due to our use of deprecated headers
if(${CXX_VERSION_NUMBER} GREATER 429)
@@ -148,41 +164,21 @@ if (LINUX)
-pthread
)
- if (SERVER)
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ftemplate-depth-60")
- if (EXISTS /etc/debian_version)
- FILE(READ /etc/debian_version DEBIAN_VERSION)
- else (EXISTS /etc/debian_version)
- set(DEBIAN_VERSION "")
- endif (EXISTS /etc/debian_version)
-
- if (NOT DEBIAN_VERSION STREQUAL "3.1")
- add_definitions(-DCTYPE_WORKAROUND)
- endif (NOT DEBIAN_VERSION STREQUAL "3.1")
-
- if (EXISTS /usr/lib/mysql4/mysql)
- link_directories(/usr/lib/mysql4/mysql)
- endif (EXISTS /usr/lib/mysql4/mysql)
-
- endif (SERVER)
-
- if (VIEWER)
- add_definitions(-DAPPID=secondlife)
- add_definitions(-fvisibility=hidden)
- # don't catch SIGCHLD in our base application class for the viewer - some of our 3rd party libs may need their *own* SIGCHLD handler to work. Sigh! The viewer doesn't need to catch SIGCHLD anyway.
- add_definitions(-DLL_IGNORE_SIGCHLD)
- if (WORD_SIZE EQUAL 32)
- add_definitions(-march=pentium4)
- endif (WORD_SIZE EQUAL 32)
- add_definitions(-mfpmath=sse)
- #add_definitions(-ftree-vectorize) # THIS CRASHES GCC 3.1-3.2
- if (NOT STANDALONE)
- # this stops us requiring a really recent glibc at runtime
- add_definitions(-fno-stack-protector)
- # linking can be very memory-hungry, especially the final viewer link
- set(CMAKE_CXX_LINK_FLAGS "-Wl,--no-keep-memory")
- endif (NOT STANDALONE)
- endif (VIEWER)
+ add_definitions(-DAPPID=secondlife)
+ add_definitions(-fvisibility=hidden)
+ # don't catch SIGCHLD in our base application class for the viewer - some of our 3rd party libs may need their *own* SIGCHLD handler to work. Sigh! The viewer doesn't need to catch SIGCHLD anyway.
+ add_definitions(-DLL_IGNORE_SIGCHLD)
+ if (WORD_SIZE EQUAL 32)
+ add_definitions(-march=pentium4)
+ endif (WORD_SIZE EQUAL 32)
+ add_definitions(-mfpmath=sse)
+ #add_definitions(-ftree-vectorize) # THIS CRASHES GCC 3.1-3.2
+ if (NOT STANDALONE)
+ # this stops us requiring a really recent glibc at runtime
+ add_definitions(-fno-stack-protector)
+ # linking can be very memory-hungry, especially the final viewer link
+ set(CMAKE_CXX_LINK_FLAGS "-Wl,--no-keep-memory")
+ endif (NOT STANDALONE)
set(CMAKE_CXX_FLAGS_DEBUG "-fno-inline ${CMAKE_CXX_FLAGS_DEBUG}")
set(CMAKE_CXX_FLAGS_RELEASE "-O2 ${CMAKE_CXX_FLAGS_RELEASE}")
@@ -190,21 +186,20 @@ endif (LINUX)
if (DARWIN)
- # NOTE (per http://lists.apple.com/archives/darwin-dev/2008/Jan/msg00232.html):
- # > Why the bus error? What am I doing wrong?
- # This is a known issue where getcontext(3) is writing past the end of the
- # ucontext_t struct when _XOPEN_SOURCE is not defined (rdar://problem/5578699 ).
- # As a workaround, define _XOPEN_SOURCE before including ucontext.h.
- add_definitions(-DLL_DARWIN=1 -D_XOPEN_SOURCE)
- set(CMAKE_CXX_LINK_FLAGS "-Wl,-headerpad_max_install_names,-search_paths_first")
+ add_definitions(-DLL_DARWIN=1)
+ set(CMAKE_CXX_LINK_FLAGS "-Wl,-no_compact_unwind -Wl,-headerpad_max_install_names,-search_paths_first")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_CXX_LINK_FLAGS}")
- set(DARWIN_extra_cstar_flags "-mlong-branch")
+ set(DARWIN_extra_cstar_flags "-mlong-branch -g")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${DARWIN_extra_cstar_flags}")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${DARWIN_extra_cstar_flags}")
# NOTE: it's critical that the optimization flag is put in front.
# NOTE: it's critical to have both CXX_FLAGS and C_FLAGS covered.
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O0 ${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
set(CMAKE_C_FLAGS_RELWITHDEBINFO "-O0 ${CMAKE_C_FLAGS_RELWITHDEBINFO}")
+ if (XCODE_VERSION GREATER 4.2)
+ set(ENABLE_SIGNING TRUE)
+ set(SIGNING_IDENTITY "Developer ID Application: Linden Research, Inc.")
+ endif (XCODE_VERSION GREATER 4.2)
endif (DARWIN)
@@ -248,6 +243,4 @@ else (STANDALONE)
)
endif (STANDALONE)
-if(SERVER)
- include_directories(${LIBS_PREBUILT_DIR}/include/havok)
-endif(SERVER)
+endif(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED)
diff --git a/indra/cmake/APR.cmake b/indra/cmake/APR.cmake
index daafa00fe2..a87027f5f6 100644..100755
--- a/indra/cmake/APR.cmake
+++ b/indra/cmake/APR.cmake
@@ -49,9 +49,7 @@ else (STANDALONE)
set(APR_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/apr-1)
if (LINUX)
- if (VIEWER)
list(APPEND APRUTIL_LIBRARIES ${DB_LIBRARIES} uuid)
- endif (VIEWER)
list(APPEND APRUTIL_LIBRARIES ${DB_LIBRARIES} rt)
endif (LINUX)
endif (STANDALONE)
diff --git a/indra/cmake/Audio.cmake b/indra/cmake/Audio.cmake
index d23bc2f9c6..d23bc2f9c6 100644..100755
--- a/indra/cmake/Audio.cmake
+++ b/indra/cmake/Audio.cmake
diff --git a/indra/cmake/BerkeleyDB.cmake b/indra/cmake/BerkeleyDB.cmake
index 57b53f46ff..57b53f46ff 100644..100755
--- a/indra/cmake/BerkeleyDB.cmake
+++ b/indra/cmake/BerkeleyDB.cmake
diff --git a/indra/cmake/Boost.cmake b/indra/cmake/Boost.cmake
index 2135f0584c..cff762e1f0 100644..100755
--- a/indra/cmake/Boost.cmake
+++ b/indra/cmake/Boost.cmake
@@ -7,18 +7,26 @@ set(Boost_FIND_REQUIRED ON)
if (STANDALONE)
include(FindBoost)
+ set(BOOST_CONTEXT_LIBRARY boost_context-mt)
+ set(BOOST_FILESYSTEM_LIBRARY boost_filesystem-mt)
set(BOOST_PROGRAM_OPTIONS_LIBRARY boost_program_options-mt)
set(BOOST_REGEX_LIBRARY boost_regex-mt)
set(BOOST_SIGNALS_LIBRARY boost_signals-mt)
set(BOOST_SYSTEM_LIBRARY boost_system-mt)
- set(BOOST_FILESYSTEM_LIBRARY boost_filesystem-mt)
+ set(BOOST_THREAD_LIBRARY boost_thread-mt)
else (STANDALONE)
use_prebuilt_binary(boost)
set(Boost_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include)
+ set(BOOST_VERSION "1.52")
if (WINDOWS)
- set(BOOST_VERSION 1_45)
if(MSVC80)
+ set(BOOST_CONTEXT_LIBRARY
+ optimized libboost_context-vc80-mt-${BOOST_VERSION}
+ debug libboost_context-vc80-mt-gd-${BOOST_VERSION})
+ set(BOOST_FILESYSTEM_LIBRARY
+ optimized libboost_filesystem-vc80-mt-${BOOST_VERSION}
+ debug libboost_filesystem-vc80-mt-gd-${BOOST_VERSION})
set(BOOST_PROGRAM_OPTIONS_LIBRARY
optimized libboost_program_options-vc80-mt-${BOOST_VERSION}
debug libboost_program_options-vc80-mt-gd-${BOOST_VERSION})
@@ -31,28 +39,76 @@ else (STANDALONE)
set(BOOST_SYSTEM_LIBRARY
optimized libboost_system-vc80-mt-${BOOST_VERSION}
debug libboost_system-vc80-mt-gd-${BOOST_VERSION})
- set(BOOST_FILESYSTEM_LIBRARY
- optimized libboost_filesystem-vc80-mt-${BOOST_VERSION}
- debug libboost_filesystem-vc80-mt-gd-${BOOST_VERSION})
+ set(BOOST_THREAD_LIBRARY
+ optimized libboost_thread-vc80-mt-${BOOST_VERSION}
+ debug libboost_thread-vc80-mt-gd-${BOOST_VERSION})
else(MSVC80)
# MSVC 10.0 config
+ set(BOOST_CONTEXT_LIBRARY
+ optimized libboost_context-mt
+ debug libboost_context-mt-gd)
+ set(BOOST_FILESYSTEM_LIBRARY
+ optimized libboost_filesystem-mt
+ debug libboost_filesystem-mt-gd)
set(BOOST_PROGRAM_OPTIONS_LIBRARY
- optimized libboost_program_options-vc100-mt-${BOOST_VERSION}
- debug libboost_program_options-vc100-mt-gd-${BOOST_VERSION})
+ optimized libboost_program_options-mt
+ debug libboost_program_options-mt-gd)
set(BOOST_REGEX_LIBRARY
- optimized libboost_regex-vc100-mt-${BOOST_VERSION}
- debug libboost_regex-vc100-mt-gd-${BOOST_VERSION})
+ optimized libboost_regex-mt
+ debug libboost_regex-mt-gd)
+ set(BOOST_SIGNALS_LIBRARY
+ optimized libboost_signals-mt
+ debug libboost_signals-mt-gd)
set(BOOST_SYSTEM_LIBRARY
- optimized libboost_system-vc100-mt-${BOOST_VERSION}
- debug libboost_system-vc100-mt-gd-${BOOST_VERSION})
- set(BOOST_FILESYSTEM_LIBRARY
- optimized libboost_filesystem-vc100-mt-${BOOST_VERSION}
- debug libboost_filesystem-vc100-mt-gd-${BOOST_VERSION})
+ optimized libboost_system-mt
+ debug libboost_system-mt-gd)
+ set(BOOST_THREAD_LIBRARY
+ optimized libboost_thread-mt
+ debug libboost_thread-mt-gd)
endif (MSVC80)
- elseif (DARWIN OR LINUX)
- set(BOOST_PROGRAM_OPTIONS_LIBRARY boost_program_options)
- set(BOOST_REGEX_LIBRARY boost_regex)
- set(BOOST_SYSTEM_LIBRARY boost_system)
- set(BOOST_FILESYSTEM_LIBRARY boost_filesystem)
+ elseif (LINUX)
+ set(BOOST_CONTEXT_LIBRARY
+ optimized boost_context-mt
+ debug boost_context-mt-d)
+ set(BOOST_FILESYSTEM_LIBRARY
+ optimized boost_filesystem-mt
+ debug boost_filesystem-mt-d)
+ set(BOOST_PROGRAM_OPTIONS_LIBRARY
+ optimized boost_program_options-mt
+ debug boost_program_options-mt-d)
+ set(BOOST_REGEX_LIBRARY
+ optimized boost_regex-mt
+ debug boost_regex-mt-d)
+ set(BOOST_SIGNALS_LIBRARY
+ optimized boost_signals-mt
+ debug boost_signals-mt-d)
+ set(BOOST_SYSTEM_LIBRARY
+ optimized boost_system-mt
+ debug boost_system-mt-d)
+ set(BOOST_THREAD_LIBRARY
+ optimized boost_thread-mt
+ debug boost_thread-mt-d)
+ elseif (DARWIN)
+ set(BOOST_CONTEXT_LIBRARY
+ optimized boost_context-mt
+ debug boost_context-mt-d)
+ set(BOOST_FILESYSTEM_LIBRARY
+ optimized boost_filesystem-mt
+ debug boost_filesystem-mt-d)
+ set(BOOST_PROGRAM_OPTIONS_LIBRARY
+ optimized boost_program_options-mt
+ debug boost_program_options-mt-d)
+ set(BOOST_REGEX_LIBRARY
+ optimized boost_regex-mt
+ debug boost_regex-mt-d)
+ set(BOOST_SIGNALS_LIBRARY
+ optimized boost_signals-mt
+ debug boost_signals-mt-d)
+ set(BOOST_SYSTEM_LIBRARY
+ optimized boost_system-mt
+ debug boost_system-mt-d)
+ set(BOOST_THREAD_LIBRARY
+ optimized boost_thread-mt
+ debug boost_thread-mt-d)
endif (WINDOWS)
endif (STANDALONE)
diff --git a/indra/cmake/BuildVersion.cmake b/indra/cmake/BuildVersion.cmake
index 60a519c9af..e4b63dc7cb 100644..100755
--- a/indra/cmake/BuildVersion.cmake
+++ b/indra/cmake/BuildVersion.cmake
@@ -1,18 +1,52 @@
# -*- cmake -*-
+# Construct the viewer version number based on the indra/VIEWER_VERSION file
-include(Python)
+if (NOT DEFINED VIEWER_SHORT_VERSION) # will be true in indra/, false in indra/newview/
+ set(VIEWER_VERSION_BASE_FILE "${CMAKE_CURRENT_SOURCE_DIR}/newview/VIEWER_VERSION.txt")
-macro (build_version _target)
- execute_process(
- COMMAND ${PYTHON_EXECUTABLE} ${SCRIPTS_DIR}/build_version.py
- llversion${_target}.h ${LLCOMMON_INCLUDE_DIRS}
- OUTPUT_VARIABLE ${_target}_VERSION
- OUTPUT_STRIP_TRAILING_WHITESPACE
- )
+ if ( EXISTS ${VIEWER_VERSION_BASE_FILE} )
+ file(STRINGS ${VIEWER_VERSION_BASE_FILE} VIEWER_SHORT_VERSION REGEX "^[0-9]+\\.[0-9]+\\.[0-9]+")
+ string(REGEX REPLACE "^([0-9]+)\\.[0-9]+\\.[0-9]+" "\\1" VIEWER_VERSION_MAJOR ${VIEWER_SHORT_VERSION})
+ string(REGEX REPLACE "^[0-9]+\\.([0-9]+)\\.[0-9]+" "\\1" VIEWER_VERSION_MINOR ${VIEWER_SHORT_VERSION})
+ string(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.([0-9]+)" "\\1" VIEWER_VERSION_PATCH ${VIEWER_SHORT_VERSION})
- if (${_target}_VERSION)
- message(STATUS "Version of ${_target} is ${${_target}_VERSION}")
- else (${_target}_VERSION)
- message(SEND_ERROR "Could not determine ${_target} version")
- endif (${_target}_VERSION)
-endmacro (build_version)
+ if (DEFINED ENV{revision})
+ set(VIEWER_VERSION_REVISION $ENV{revision})
+ message("Revision (from environment): ${VIEWER_VERSION_REVISION}")
+
+ else (DEFINED ENV{revision})
+ find_program(MERCURIAL hg)
+ find_program(WORDCOUNT wc)
+ find_program(SED sed)
+ if (DEFINED MERCURIAL AND DEFINED WORDCOUNT AND DEFINED SED)
+ execute_process(
+ COMMAND ${MERCURIAL} log -r tip:0 --template '\\n'
+ COMMAND ${WORDCOUNT} -l
+ COMMAND ${SED} "s/ //g"
+ OUTPUT_VARIABLE VIEWER_VERSION_REVISION
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ )
+ if ("${VIEWER_VERSION_REVISION}" MATCHES "^[0-9]+$")
+ message("Revision (from hg) ${VIEWER_VERSION_REVISION}")
+ else ("${VIEWER_VERSION_REVISION}" MATCHES "^[0-9]+$")
+ message("Revision not set (repository not found?); using 0")
+ set(VIEWER_VERSION_REVISION 0 )
+ endif ("${VIEWER_VERSION_REVISION}" MATCHES "^[0-9]+$")
+ else (DEFINED MERCURIAL AND DEFINED WORDCOUNT AND DEFINED SED)
+ message("Revision not set: 'hg', 'wc' or 'sed' not found; using 0")
+ set(VIEWER_VERSION_REVISION 0)
+ endif (DEFINED MERCURIAL AND DEFINED WORDCOUNT AND DEFINED SED)
+ endif (DEFINED ENV{revision})
+ message("Building '${VIEWER_CHANNEL}' Version ${VIEWER_SHORT_VERSION}.${VIEWER_VERSION_REVISION}")
+ else ( EXISTS ${VIEWER_VERSION_BASE_FILE} )
+ message(SEND_ERROR "Cannot get viewer version from '${VIEWER_VERSION_BASE_FILE}'")
+ endif ( EXISTS ${VIEWER_VERSION_BASE_FILE} )
+
+ set(VIEWER_CHANNEL_VERSION_DEFINES
+ "LL_VIEWER_CHANNEL=\"${VIEWER_CHANNEL}\""
+ "LL_VIEWER_VERSION_MAJOR=${VIEWER_VERSION_MAJOR}"
+ "LL_VIEWER_VERSION_MINOR=${VIEWER_VERSION_MINOR}"
+ "LL_VIEWER_VERSION_PATCH=${VIEWER_VERSION_PATCH}"
+ "LL_VIEWER_VERSION_BUILD=${VIEWER_VERSION_REVISION}"
+ )
+endif (NOT DEFINED VIEWER_SHORT_VERSION)
diff --git a/indra/cmake/CARes.cmake b/indra/cmake/CARes.cmake
index b0dac5b12f..b0dac5b12f 100644..100755
--- a/indra/cmake/CARes.cmake
+++ b/indra/cmake/CARes.cmake
diff --git a/indra/cmake/CMakeCopyIfDifferent.cmake b/indra/cmake/CMakeCopyIfDifferent.cmake
index 55e71ff153..55e71ff153 100644..100755
--- a/indra/cmake/CMakeCopyIfDifferent.cmake
+++ b/indra/cmake/CMakeCopyIfDifferent.cmake
diff --git a/indra/cmake/CMakeLists.txt b/indra/cmake/CMakeLists.txt
index 279d577a27..10a23ea068 100644..100755
--- a/indra/cmake/CMakeLists.txt
+++ b/indra/cmake/CMakeLists.txt
@@ -14,47 +14,66 @@ set(cmake_SOURCE_FILES
Boost.cmake
BuildVersion.cmake
CARes.cmake
- CURL.cmake
CMakeCopyIfDifferent.cmake
+ ConfigurePkgConfig.cmake
+ CURL.cmake
Copy3rdPartyLibs.cmake
- CSharpMacros.cmake
DBusGlib.cmake
+ DeploySharedLibs.cmake
DirectX.cmake
+ DragDrop.cmake
EXPAT.cmake
+ ExamplePlugin.cmake
FindAPR.cmake
+ FindAutobuild.cmake
FindBerkeleyDB.cmake
FindCARes.cmake
- FindELFIO.cmake
- FindFMOD.cmake
+ FindFMODEX.cmake
+ FindGLH.cmake
+ FindGoogleBreakpad.cmake
FindGooglePerfTools.cmake
- FindMono.cmake
- FindMySQL.cmake
+ FindHUNSPELL.cmake
+ FindJsonCpp.cmake
+ FindNDOF.cmake
FindOpenJPEG.cmake
+ FindSCP.cmake
FindXmlRpcEpi.cmake
FindZLIB.cmake
- FMOD.cmake
+ FMODEX.cmake
FreeType.cmake
+ GLEXT.cmake
+ GLH.cmake
GLOD.cmake
GStreamer010Plugin.cmake
+ GetPrerequisites_2_8.cmake
+ Glui.cmake
+ Glut.cmake
+ GoogleBreakpad.cmake
+ GoogleMock.cmake
GooglePerfTools.cmake
+ Havok.cmake
+ Hunspell.cmake
JPEG.cmake
+ JsonCpp.cmake
LLAddBuildTest.cmake
+ LLAppearance.cmake
+ LLAppearanceUtility.cmake
LLAudio.cmake
LLCharacter.cmake
LLCommon.cmake
- LLConvexDecomposition.cmake
LLCrashLogger.cmake
- LLDatabase.cmake
LLImage.cmake
LLImageJ2COJ.cmake
LLInventory.cmake
LLKDU.cmake
+ LLLogin.cmake
LLMath.cmake
LLMessage.cmake
+ LLPhysicsExtensions.cmake
LLPlugin.cmake
LLPrimitive.cmake
LLRender.cmake
- LLScene.cmake
+ LLSharedLibs.cmake
LLTestCommand.cmake
LLUI.cmake
LLVFS.cmake
@@ -62,21 +81,26 @@ set(cmake_SOURCE_FILES
LLXML.cmake
LScript.cmake
Linking.cmake
- MonoEmbed.cmake
- MySQL.cmake
+ MediaPluginBase.cmake
NDOF.cmake
OPENAL.cmake
OpenGL.cmake
OpenJPEG.cmake
OpenSSL.cmake
PNG.cmake
- Python.cmake
+ PluginAPI.cmake
Prebuilt.cmake
+ PulseAudio.cmake
+ Python.cmake
+ QuickTimePlugin.cmake
TemplateCheck.cmake
Tut.cmake
UI.cmake
UnixInstall.cmake
Variables.cmake
+ ViewerMiscLibs.cmake
+ VisualLeakDetector.cmake
+ WebKitLibPlugin.cmake
XmlRpcEpi.cmake
ZLIB.cmake
)
@@ -87,10 +111,6 @@ set(master_SOURCE_FILES
../CMakeLists.txt
)
-if (SERVER)
- list(APPEND master_SOURCE_FILES ../Server.cmake)
-endif (SERVER)
-
source_group("Master Rules" FILES ${master_SOURCE_FILES})
set_source_files_properties(${cmake_SOURCE_FILES} ${master_SOURCE_FILES}
diff --git a/indra/cmake/CSharpMacros.cmake b/indra/cmake/CSharpMacros.cmake
deleted file mode 100644
index a4dd815043..0000000000
--- a/indra/cmake/CSharpMacros.cmake
+++ /dev/null
@@ -1,142 +0,0 @@
-# - This is a support module for easy Mono/C# handling with CMake
-# It defines the following macros:
-#
-# ADD_CS_LIBRARY (<target> <source>)
-# ADD_CS_EXECUTABLE (<target> <source>)
-# INSTALL_GAC (<target>)
-#
-# Note that the order of the arguments is important.
-#
-# You can optionally set the variable CS_FLAGS to tell the macros whether
-# to pass additional flags to the compiler. This is particularly useful to
-# set assembly references, unsafe code, etc... These flags are always reset
-# after the target was added so you don't have to care about that.
-#
-# copyright (c) 2007 Arno Rehn arno@arnorehn.de
-#
-# Redistribution and use is allowed according to the terms of the GPL license.
-
-
-# ----- support macros -----
-MACRO(GET_CS_LIBRARY_TARGET_DIR)
- IF (NOT LIBRARY_OUTPUT_PATH)
- SET(CS_LIBRARY_TARGET_DIR ${CMAKE_CURRENT_BINARY_DIR})
- ELSE (NOT LIBRARY_OUTPUT_PATH)
- SET(CS_LIBRARY_TARGET_DIR ${LIBRARY_OUTPUT_PATH})
- ENDIF (NOT LIBRARY_OUTPUT_PATH)
-ENDMACRO(GET_CS_LIBRARY_TARGET_DIR)
-
-MACRO(GET_CS_EXECUTABLE_TARGET_DIR)
- IF (NOT EXECUTABLE_OUTPUT_PATH)
- SET(CS_EXECUTABLE_TARGET_DIR ${CMAKE_CURRENT_BINARY_DIR})
- ELSE (NOT EXECUTABLE_OUTPUT_PATH)
- SET(CS_EXECUTABLE_TARGET_DIR ${EXECUTABLE_OUTPUT_PATH})
- ENDIF (NOT EXECUTABLE_OUTPUT_PATH)
-ENDMACRO(GET_CS_EXECUTABLE_TARGET_DIR)
-
-MACRO(MAKE_PROPER_FILE_LIST)
- FOREACH(file ${ARGN})
- # first assume it's a relative path
- FILE(GLOB globbed ${CMAKE_CURRENT_SOURCE_DIR}/${file})
- IF(globbed)
- FILE(TO_NATIVE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/${file} native)
- ELSE(globbed)
- FILE(TO_NATIVE_PATH ${file} native)
- ENDIF(globbed)
- SET(proper_file_list ${proper_file_list} ${native})
- SET(native "")
- ENDFOREACH(file)
-ENDMACRO(MAKE_PROPER_FILE_LIST)
-# ----- end support macros -----
-
-MACRO(ADD_CS_LIBRARY target)
- GET_CS_LIBRARY_TARGET_DIR()
-
- SET(target_DLL "${CS_LIBRARY_TARGET_DIR}/${target}.dll")
- MAKE_PROPER_FILE_LIST(${ARGN})
- FILE(RELATIVE_PATH relative_path ${CMAKE_BINARY_DIR} ${target_DLL})
-
- SET(target_KEY "${CMAKE_CURRENT_SOURCE_DIR}/${target}.key")
- SET(target_CS_FLAGS "${CS_FLAGS}")
- IF(${target}_CS_FLAGS)
- LIST(APPEND target_CS_FLAGS ${${target}_CS_FLAGS})
- ENDIF(${target}_CS_FLAGS)
- IF(EXISTS ${target_KEY})
- LIST(APPEND target_CS_FLAGS -keyfile:${target_KEY})
- ENDIF(EXISTS ${target_KEY})
-
- FOREACH(ref ${${target}_REFS})
- SET(ref_DLL ${CMAKE_CURRENT_BINARY_DIR}/${ref}.dll)
- IF(EXISTS ${ref_DLL})
- LIST(APPEND target_CS_FLAGS -r:${ref_DLL})
- ELSE(EXISTS ${ref_DLL})
- LIST(APPEND target_CS_FLAGS -r:${ref})
- ENDIF(EXISTS ${ref_DLL})
- ENDFOREACH(ref ${${target}_REFS})
-
- ADD_CUSTOM_COMMAND (OUTPUT ${target_DLL}
- COMMAND ${MCS_EXECUTABLE} ${target_CS_FLAGS} -out:${target_DLL} -target:library ${proper_file_list}
- MAIN_DEPENDENCY ${proper_file_list}
- DEPENDS ${ARGN}
- COMMENT "Building ${relative_path}")
- ADD_CUSTOM_TARGET (${target} ALL DEPENDS ${target_DLL})
-
- FOREACH(ref ${${target}_REFS})
- GET_TARGET_PROPERTY(is_target ${ref} TYPE)
- IF(is_target)
- ADD_DEPENDENCIES(${target} ${ref})
- ENDIF(is_target)
- ENDFOREACH(ref ${${target}_REFS})
-
- SET(relative_path "")
- SET(proper_file_list "")
-ENDMACRO(ADD_CS_LIBRARY)
-
-MACRO(ADD_CS_EXECUTABLE target)
- GET_CS_EXECUTABLE_TARGET_DIR()
-
- # Seems like cmake doesn't like the ".exe" ending for custom commands.
- # If we call it ${target}.exe, 'make' will later complain about a missing rule.
- # Create a fake target instead.
- SET(target_EXE "${CS_EXECUTABLE_TARGET_DIR}/${target}.exe")
- SET(target_TOUCH "${CS_EXECUTABLE_TARGET_DIR}/${target}.exe-built")
- GET_DIRECTORY_PROPERTY(clean ADDITIONAL_MAKE_CLEAN_FILES)
- LIST(APPEND clean ${target}.exe)
- SET_DIRECTORY_PROPERTIES(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${clean}")
- MAKE_PROPER_FILE_LIST(${ARGN})
- FILE(RELATIVE_PATH relative_path ${CMAKE_BINARY_DIR} ${target_EXE})
- SET(target_CS_FLAGS "${CS_FLAGS}")
-
- FOREACH(ref ${${target}_REFS})
- SET(ref_DLL ${CMAKE_CURRENT_SOURCE_DIR}/${ref}.dll)
- IF(EXISTS ${ref_DLL})
- LIST(APPEND target_CS_FLAGS -r:${ref_DLL})
- ELSE(EXISTS ${ref_DLL})
- LIST(APPEND target_CS_FLAGS -r:${ref})
- ENDIF(EXISTS ${ref_DLL})
- ENDFOREACH(ref ${${target}_REFS})
-
- ADD_CUSTOM_COMMAND (OUTPUT "${target_TOUCH}"
- COMMAND ${MCS_EXECUTABLE} ${target_CS_FLAGS} -out:${target_EXE} ${proper_file_list}
- COMMAND ${CMAKE_COMMAND} -E touch ${target_TOUCH}
- MAIN_DEPENDENCY ${ARGN}
- DEPENDS ${ARGN}
- COMMENT "Building ${relative_path}")
- ADD_CUSTOM_TARGET ("${target}" ALL DEPENDS "${target_TOUCH}")
-
- FOREACH(ref ${${target}_REFS})
- GET_TARGET_PROPERTY(is_target ${ref} TYPE)
- IF(is_target)
- ADD_DEPENDENCIES(${target} ${ref})
- ENDIF(is_target)
- ENDFOREACH(ref ${${target}_REFS})
-
- SET(relative_path "")
- SET(proper_file_list "")
-ENDMACRO(ADD_CS_EXECUTABLE)
-
-MACRO(INSTALL_GAC target)
- GET_CS_LIBRARY_TARGET_DIR()
-
- INSTALL(CODE "EXECUTE_PROCESS(COMMAND ${GACUTIL_EXECUTABLE} -i ${CS_LIBRARY_TARGET_DIR}/${target}.dll -package 2.0)")
-ENDMACRO(INSTALL_GAC target)
diff --git a/indra/cmake/CURL.cmake b/indra/cmake/CURL.cmake
index 9aba08e573..9aba08e573 100644..100755
--- a/indra/cmake/CURL.cmake
+++ b/indra/cmake/CURL.cmake
diff --git a/indra/cmake/ConfigurePkgConfig.cmake b/indra/cmake/ConfigurePkgConfig.cmake
new file mode 100644
index 0000000000..82ee3e7a5b
--- /dev/null
+++ b/indra/cmake/ConfigurePkgConfig.cmake
@@ -0,0 +1,74 @@
+# -*- cmake -*-
+
+SET(DEBUG_PKG_CONFIG "YES")
+
+# Don't change this if manually set by user.
+IF("$ENV{PKG_CONFIG_LIBDIR}" STREQUAL "")
+
+ # Guess at architecture-specific system library paths.
+ if (WORD_SIZE EQUAL 32)
+ SET(PKG_CONFIG_NO_MULTI_GUESS /usr/lib32 /usr/lib)
+ SET(PKG_CONFIG_NO_MULTI_LOCAL_GUESS /usr/local/lib32 /usr/local/lib)
+ SET(PKG_CONFIG_MULTI_GUESS /usr/lib/i386-linux-gnu)
+ SET(PKG_CONFIG_MULTI_LOCAL_GUESS /usr/local/lib/i386-linux-gnu)
+ else (WORD_SIZE EQUAL 32)
+ SET(PKG_CONFIG_NO_MULTI_GUESS /usr/lib64 /usr/lib)
+ SET(PKG_CONFIG_NO_MULTI_LOCAL_GUESS /usr/local/lib64 /usr/local/lib)
+ SET(PKG_CONFIG_MULTI_GUESS /usr/local/lib/x86_64-linux-gnu)
+ SET(PKG_CONFIG_MULTI_LOCAL_GUESS /usr/local/lib/x86_64-linux-gnu)
+ endif (WORD_SIZE EQUAL 32)
+
+ # Use DPKG architecture, if available.
+ IF (${DPKG_ARCH})
+ SET(PKG_CONFIG_MULTI_GUESS /usr/lib/${DPKG_ARCH})
+ SET(PKG_CONFIG_MULTI_LOCAL_GUESS /usrlocal/lib/${DPKG_ARCH})
+ ENDIF (${DPKG_ARCH})
+
+ # Explicitly include anything listed in PKG_CONFIG_PATH
+ string(REPLACE ":" ";" PKG_CONFIG_PATH_LIST "$ENV{PKG_CONFIG_PATH}")
+ FOREACH(PKG_CONFIG_DIR ${PKG_CONFIG_PATH_LIST})
+ SET(VALID_PKG_LIBDIRS "${VALID_PKG_LIBDIRS}:${PKG_CONFIG_DIR}/pkgconfig")
+ ENDFOREACH(PKG_CONFIG_DIR)
+
+ # Look for valid pkgconfig directories.
+ FIND_PATH(PKG_CONFIG_ENV pkgconfig ENV LD_LIBRARY_PATH)
+ FIND_PATH(PKG_CONFIG_MULTI pkgconfig HINT ${PKG_CONFIG_MULTI_GUESS})
+ FIND_PATH(PKG_CONFIG_MULTI_LOCAL pkgconfig HINT ${PKG_CONFIG_MULTI_LOCAL_GUESS})
+ FIND_PATH(PKG_CONFIG_NO_MULTI pkgconfig HINT ${PKG_CONFIG_NO_MULTI_GUESS})
+ FIND_PATH(PKG_CONFIG_NO_MULTI_LOCAL pkgconfig HINT ${PKG_CONFIG_NO_MULTI_LOCAL_GUESS})
+
+ # Add anything we found to our list.
+ IF(NOT PKG_CONFIG_ENV STREQUAL PKG_CONFIG_ENV-NOTFOUND)
+ SET(VALID_PKG_LIBDIRS "${VALID_PKG_LIBDIRS}:${PKG_CONFIG_ENV}/pkgconfig")
+ ENDIF(NOT PKG_CONFIG_ENV STREQUAL PKG_CONFIG_ENV-NOTFOUND)
+
+ IF(NOT PKG_CONFIG_MULTI STREQUAL PKG_CONFIG_MULTI-NOTFOUND)
+ SET(VALID_PKG_LIBDIRS "${VALID_PKG_LIBDIRS}:${PKG_CONFIG_MULTI}/pkgconfig")
+ ENDIF(NOT PKG_CONFIG_MULTI STREQUAL PKG_CONFIG_MULTI-NOTFOUND)
+
+ IF(NOT PKG_CONFIG_MULTI_LOCAL STREQUAL PKG_CONFIG_MULTI_LOCAL-NOTFOUND)
+ SET(VALID_PKG_LIBDIRS "${VALID_PKG_LIBDIRS}:${PKG_CONFIG_MULTI_LOCAL}/pkgconfig")
+ ENDIF(NOT PKG_CONFIG_MULTI_LOCAL STREQUAL PKG_CONFIG_MULTI_LOCAL-NOTFOUND)
+
+ IF(NOT PKG_CONFIG_NO_MULTI STREQUAL PKG_CONFIG_NO_MULTI-NOTFOUND)
+ SET(VALID_PKG_LIBDIRS "${VALID_PKG_LIBDIRS}:${PKG_CONFIG_NO_MULTI}/pkgconfig")
+ ENDIF(NOT PKG_CONFIG_NO_MULTI STREQUAL PKG_CONFIG_NO_MULTI-NOTFOUND)
+
+ IF(NOT PKG_CONFIG_NO_MULTI_LOCAL STREQUAL PKG_CONFIG_NO_MULTI_LOCAL-NOTFOUND)
+ SET(VALID_PKG_LIBDIRS "${VALID_PKG_LIBDIRS}:${PKG_CONFIG_NO_MULTI_LOCAL}/pkgconfig")
+ ENDIF(NOT PKG_CONFIG_NO_MULTI_LOCAL STREQUAL PKG_CONFIG_NO_MULTI_LOCAL-NOTFOUND)
+
+ # Also add some non-architecture specific package locations.
+ SET(VALID_PKG_LIBDIRS "${VALID_PKG_LIBDIRS}:/usr/share/pkgconfig:/usr/local/share/pkgconfig")
+
+ # Remove first unwanted ':'
+ string(SUBSTRING ${VALID_PKG_LIBDIRS} 1 -1 VALID_PKG_LIBDIRS)
+
+ # Set PKG_CONFIG_LIBDIR environment.
+ SET(ENV{PKG_CONFIG_LIBDIR} ${VALID_PKG_LIBDIRS})
+ENDIF("$ENV{PKG_CONFIG_LIBDIR}" STREQUAL "")
+
+IF(DEBUG_PKG_CONFIG)
+ MESSAGE(STATUS "Using PKG_CONFIG_LIBDIR=$ENV{PKG_CONFIG_LIBDIR}")
+ENDIF(DEBUG_PKG_CONFIG)
+
diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake
index 394db362b1..44c2d3ac27 100644..100755
--- a/indra/cmake/Copy3rdPartyLibs.cmake
+++ b/indra/cmake/Copy3rdPartyLibs.cmake
@@ -20,6 +20,7 @@ if(WINDOWS)
set(vivox_src_dir "${ARCH_PREBUILT_DIRS_RELEASE}")
set(vivox_files
SLVoice.exe
+ ca-bundle.crt
libsndfile-1.dll
vivoxplatform.dll
vivoxsdk.dll
@@ -41,6 +42,7 @@ if(WINDOWS)
libeay32.dll
libcollada14dom22-d.dll
glod.dll
+ libhunspell.dll
)
set(release_src_dir "${ARCH_PREBUILT_DIRS_RELEASE}")
@@ -53,17 +55,17 @@ if(WINDOWS)
libeay32.dll
libcollada14dom22.dll
glod.dll
+ libhunspell.dll
)
- if(USE_GOOGLE_PERFTOOLS)
+ if(USE_TCMALLOC)
set(debug_files ${debug_files} libtcmalloc_minimal-debug.dll)
set(release_files ${release_files} libtcmalloc_minimal.dll)
- endif(USE_GOOGLE_PERFTOOLS)
+ endif(USE_TCMALLOC)
- if (FMOD)
- set(debug_files ${debug_files} fmod.dll)
- set(release_files ${release_files} fmod.dll)
- endif (FMOD)
+ if (FMODEX)
+ set(release_files ${release_files} fmodex.dll)
+ endif (FMODEX)
#*******************************
# Copy MS C runtime dlls, required for packaging.
@@ -194,6 +196,7 @@ elseif(DARWIN)
set(vivox_src_dir "${ARCH_PREBUILT_DIRS_RELEASE}")
set(vivox_files
SLVoice
+ ca-bundle.crt
libsndfile.dylib
libvivoxoal.dylib
libortp.dylib
@@ -212,15 +215,18 @@ elseif(DARWIN)
libexpat.1.5.2.dylib
libexpat.dylib
libGLOD.dylib
- libllqtwebkit.dylib
- libminizip.a
+ libllqtwebkit.dylib
+ libminizip.a
libndofdev.dylib
+ libhunspell-1.3.0.dylib
libexception_handler.dylib
- libcollada14dom.dylib
+ libcollada14dom.dylib
)
- # fmod is statically linked on darwin
- set(fmod_files "")
+ if (FMODEX)
+ set(debug_files ${debug_files} libfmodexL.dylib)
+ set(release_files ${release_files} libfmodex.dylib)
+ endif (FMODEX)
elseif(LINUX)
# linux is weird, multiple side by side configurations aren't supported
@@ -237,6 +243,7 @@ elseif(LINUX)
libvivoxplatform.so
libvivoxsdk.so
SLVoice
+ # ca-bundle.crt #No cert for linux. It is actually still 3.2SDK.
)
# *TODO - update this to use LIBS_PREBUILT_DIR and LL_ARCH_DIR variables
# or ARCH_PREBUILT_DIRS
@@ -251,33 +258,44 @@ elseif(LINUX)
libapr-1.so.0
libaprutil-1.so.0
libatk-1.0.so
- libbreakpad_client.so.0
+ libboost_context-mt.so.${BOOST_VERSION}.0
+ libboost_filesystem-mt.so.${BOOST_VERSION}.0
+ libboost_program_options-mt.so.${BOOST_VERSION}.0
+ libboost_regex-mt.so.${BOOST_VERSION}.0
+ libboost_signals-mt.so.${BOOST_VERSION}.0
+ libboost_system-mt.so.${BOOST_VERSION}.0
+ libboost_thread-mt.so.${BOOST_VERSION}.0
libcollada14dom.so
libcrypto.so.1.0.0
libdb-5.1.so
libexpat.so
libexpat.so.1
- libglod.so
+ libfreetype.so.6
+ libGLOD.so
libgmock_main.so
libgmock.so.0
libgmodule-2.0.so
libgobject-2.0.so
libgtest_main.so
libgtest.so.0
- libminizip.so
+ libhunspell-1.3.so.0.0.0
+ libminizip.so
libopenal.so
libopenjpeg.so
libssl.so
- libtcmalloc_minimal.so
libuuid.so.16
libuuid.so.16.0.22
libssl.so.1.0.0
libfontconfig.so.1.4.4
)
- if (FMOD)
- set(release_files ${release_files} "libfmod-3.75.so")
- endif (FMOD)
+ if (USE_TCMALLOC)
+ set(release_files ${release_files} "libtcmalloc_minimal.so")
+ endif (USE_TCMALLOC)
+
+ if (FMODEX)
+ set(release_file ${release_files} "libfmodex.so")
+ endif (FMODEX)
else(WINDOWS)
message(STATUS "WARNING: unrecognized platform for staging 3rd party libs, skipping...")
@@ -292,8 +310,6 @@ else(WINDOWS)
set(release_src_dir "${CMAKE_SOURCE_DIR}/../libraries/i686-linux/lib/release")
set(release_files "")
- set(fmod_files "")
-
set(debug_llkdu_src "")
set(debug_llkdu_dst "")
set(release_llkdu_src "")
@@ -356,30 +372,6 @@ copy_if_different(
)
set(third_party_targets ${third_party_targets} ${out_targets})
-if (FMOD_SDK_DIR)
- copy_if_different(
- ${FMOD_SDK_DIR}
- "${CMAKE_CURRENT_BINARY_DIR}/Debug"
- out_targets
- ${fmod_files}
- )
- set(all_targets ${all_targets} ${out_targets})
- copy_if_different(
- ${FMOD_SDK_DIR}
- "${CMAKE_CURRENT_BINARY_DIR}/Release"
- out_targets
- ${fmod_files}
- )
- set(all_targets ${all_targets} ${out_targets})
- copy_if_different(
- ${FMOD_SDK_DIR}
- "${CMAKE_CURRENT_BINARY_DIR}/RelWithDbgInfo"
- out_targets
- ${fmod_files}
- )
- set(all_targets ${all_targets} ${out_targets})
-endif (FMOD_SDK_DIR)
-
if(NOT STANDALONE)
add_custom_target(
stage_third_party_libs ALL
diff --git a/indra/cmake/CopyBackToSource.cmake b/indra/cmake/CopyBackToSource.cmake
deleted file mode 100644
index d217df9aec..0000000000
--- a/indra/cmake/CopyBackToSource.cmake
+++ /dev/null
@@ -1,16 +0,0 @@
-# -*- cmake -*-
-# Copies a binary back to the source directory
-
-MACRO(COPY_BACK_TO_SOURCE target)
- GET_TARGET_PROPERTY(FROM ${target} LOCATION)
- SET(TO ${CMAKE_CURRENT_SOURCE_DIR})
- #MESSAGE("TARGET ${target} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy ${FROM} ${TO}")
- ADD_CUSTOM_COMMAND(
- TARGET ${target} POST_BUILD
- COMMAND ${CMAKE_COMMAND} -E copy ${FROM} ${TO}
- DEPENDS ${FROM}
- COMMENT "Copying ${target} to ${CMAKE_CURRENT_BINARY_DIR}"
- )
-ENDMACRO(COPY_BACK_TO_SOURCE)
-
-
diff --git a/indra/cmake/DBusGlib.cmake b/indra/cmake/DBusGlib.cmake
index 83c08d3350..83c08d3350 100644..100755
--- a/indra/cmake/DBusGlib.cmake
+++ b/indra/cmake/DBusGlib.cmake
diff --git a/indra/cmake/DeploySharedLibs.cmake b/indra/cmake/DeploySharedLibs.cmake
index 663c272e50..663c272e50 100644..100755
--- a/indra/cmake/DeploySharedLibs.cmake
+++ b/indra/cmake/DeploySharedLibs.cmake
diff --git a/indra/cmake/DirectX.cmake b/indra/cmake/DirectX.cmake
index b2a18805d4..25163d0322 100644..100755
--- a/indra/cmake/DirectX.cmake
+++ b/indra/cmake/DirectX.cmake
@@ -1,8 +1,9 @@
# -*- cmake -*-
-if (VIEWER AND WINDOWS)
+if (WINDOWS)
find_path(DIRECTX_INCLUDE_DIR dxdiag.h
"$ENV{DXSDK_DIR}/Include"
+ "$ENV{PROGRAMFILES}/Microsoft DirectX SDK (June 2010)/Include"
"$ENV{PROGRAMFILES}/Microsoft DirectX SDK (August 2009)/Include"
"$ENV{PROGRAMFILES}/Microsoft DirectX SDK (March 2009)/Include"
"$ENV{PROGRAMFILES}/Microsoft DirectX SDK (August 2008)/Include"
@@ -25,6 +26,7 @@ if (VIEWER AND WINDOWS)
find_path(DIRECTX_LIBRARY_DIR dxguid.lib
"$ENV{DXSDK_DIR}/Lib/x86"
+ "$ENV{PROGRAMFILES}/Microsoft DirectX SDK (June 2010)/Lib/x86"
"$ENV{PROGRAMFILES}/Microsoft DirectX SDK (August 2009)/Lib/x86"
"$ENV{PROGRAMFILES}/Microsoft DirectX SDK (March 2009)/Lib/x86"
"$ENV{PROGRAMFILES}/Microsoft DirectX SDK (August 2008)/Lib/x86"
@@ -43,4 +45,4 @@ if (VIEWER AND WINDOWS)
message(FATAL_ERROR "Could not find DirectX SDK Libraries")
endif (DIRECTX_LIBRARY_DIR)
-endif (VIEWER AND WINDOWS)
+endif (WINDOWS)
diff --git a/indra/cmake/DragDrop.cmake b/indra/cmake/DragDrop.cmake
index c0424396e5..73ef59b18f 100644..100755
--- a/indra/cmake/DragDrop.cmake
+++ b/indra/cmake/DragDrop.cmake
@@ -1,7 +1,5 @@
# -*- cmake -*-
-if (VIEWER)
-
set(OS_DRAG_DROP ON CACHE BOOL "Build the viewer with OS level drag and drop turned on or off")
if (OS_DRAG_DROP)
@@ -20,4 +18,3 @@ if (VIEWER)
endif (OS_DRAG_DROP)
-endif (VIEWER)
diff --git a/indra/cmake/EXPAT.cmake b/indra/cmake/EXPAT.cmake
index acb15dc623..acb15dc623 100644..100755
--- a/indra/cmake/EXPAT.cmake
+++ b/indra/cmake/EXPAT.cmake
diff --git a/indra/cmake/ExamplePlugin.cmake b/indra/cmake/ExamplePlugin.cmake
index 599787ad21..599787ad21 100644..100755
--- a/indra/cmake/ExamplePlugin.cmake
+++ b/indra/cmake/ExamplePlugin.cmake
diff --git a/indra/cmake/Externals.cmake b/indra/cmake/Externals.cmake
deleted file mode 100644
index 26f3b56049..0000000000
--- a/indra/cmake/Externals.cmake
+++ /dev/null
@@ -1,34 +0,0 @@
-# -*- cmake -*-
-
-include(Python)
-include(FindSVN)
-
-macro (use_svn_external _binary _path _url _rev)
- if (NOT STANDALONE)
- if(${CMAKE_BINARY_DIR}/temp/sentinel_installed IS_NEWER_THAN ${CMAKE_BINARY_DIR}/temp/${_binary}_installed)
- if(SVN_FOUND)
- if(DEBUG_EXTERNALS)
- message("cd ${_path} && ${SVN_EXECUTABLE} checkout -r ${_rev} ${_url} ${_binary}")
- endif(DEBUG_EXTERNALS)
- execute_process(COMMAND ${SVN_EXECUTABLE}
- checkout
- -r ${_rev}
- ${_url}
- ${_binary}
- WORKING_DIRECTORY ${_path}
- RESULT_VARIABLE ${_binary}_installed
- )
- else(SVN_FOUND)
- message(FATAL_ERROR "Failed to find SVN_EXECUTABLE")
- endif(SVN_FOUND)
- file(WRITE ${CMAKE_BINARY_DIR}/temp/${_binary}_installed "${${_binary}_installed}")
- else(${CMAKE_BINARY_DIR}/temp/sentinel_installed IS_NEWER_THAN ${CMAKE_BINARY_DIR}/temp/${_binary}_installed)
- set(${_binary}_installed 0)
- endif(${CMAKE_BINARY_DIR}/temp/sentinel_installed IS_NEWER_THAN ${CMAKE_BINARY_DIR}/temp/${_binary}_installed)
- if(NOT ${_binary}_installed EQUAL 0)
- message(FATAL_ERROR
- "Failed to download or unpack prebuilt '${_binary}'."
- " Process returned ${${_binary}_installed}.")
- endif (NOT ${_binary}_installed EQUAL 0)
- endif (NOT STANDALONE)
-endmacro (use_svn_external _binary _path _url _rev)
diff --git a/indra/cmake/FMOD.cmake b/indra/cmake/FMOD.cmake
deleted file mode 100644
index 3586c1160a..0000000000
--- a/indra/cmake/FMOD.cmake
+++ /dev/null
@@ -1,39 +0,0 @@
-# -*- cmake -*-
-
-# FMOD can be set when launching the make using the argument -DFMOD:BOOL=ON
-# When building using proprietary binaries though (i.e. having access to LL private servers),
-# we always build with FMOD.
-# Open source devs should use the -DFMOD:BOOL=ON then if they want to build with FMOD, whether
-# they are using STANDALONE or not.
-if (INSTALL_PROPRIETARY)
- set(FMOD ON CACHE BOOL "Use FMOD sound library.")
-endif (INSTALL_PROPRIETARY)
-
-if (FMOD)
- if (STANDALONE)
- # In that case, we use the version of the library installed on the system
- set(FMOD_FIND_REQUIRED ON)
- include(FindFMOD)
- else (STANDALONE)
- if (FMOD_LIBRARY AND FMOD_INCLUDE_DIR)
- # If the path have been specified in the arguments, use that
- set(FMOD_LIBRARIES ${FMOD_LIBRARY})
- MESSAGE(STATUS "Using FMOD path: ${FMOD_LIBRARIES}, ${FMOD_INCLUDE_DIR}")
- else (FMOD_LIBRARY AND FMOD_INCLUDE_DIR)
- # If not, we're going to try to get the package listed in autobuild.xml
- # Note: if you're not using INSTALL_PROPRIETARY, the package URL should be local (file:/// URL)
- # as accessing the private LL location will fail if you don't have the credential
- include(Prebuilt)
- use_prebuilt_binary(fmod)
- if (WINDOWS)
- set(FMOD_LIBRARY fmod)
- elseif (DARWIN)
- set(FMOD_LIBRARY fmod)
- elseif (LINUX)
- set(FMOD_LIBRARY fmod-3.75)
- endif (WINDOWS)
- set(FMOD_LIBRARIES ${FMOD_LIBRARY})
- set(FMOD_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include)
- endif (FMOD_LIBRARY AND FMOD_INCLUDE_DIR)
- endif (STANDALONE)
-endif (FMOD)
diff --git a/indra/cmake/FMODEX.cmake b/indra/cmake/FMODEX.cmake
new file mode 100644
index 0000000000..65bc1cabeb
--- /dev/null
+++ b/indra/cmake/FMODEX.cmake
@@ -0,0 +1,46 @@
+# -*- cmake -*-
+
+# FMOD can be set when launching the make using the argument -DFMOD:BOOL=ON
+# When building using proprietary binaries though (i.e. having access to LL private servers),
+# we always build with FMODEX.
+# Open source devs should use the -DFMODEX:BOOL=ON then if they want to build with FMOD, whether
+# they are using STANDALONE or not.
+if (INSTALL_PROPRIETARY)
+ set(FMODEX ON CACHE BOOL "Using FMOD Ex sound library.")
+endif (INSTALL_PROPRIETARY)
+
+if (FMODEX)
+ if (STANDALONE)
+ # In that case, we use the version of the library installed on the system
+ set(FMODEX_FIND_REQUIRED ON)
+ include(FindFMODEX)
+ else (STANDALONE)
+ if (FMODEX_LIBRARY AND FMODEX_INCLUDE_DIR)
+ # If the path have been specified in the arguments, use that
+ set(FMODEX_LIBRARIES ${FMODEX_LIBRARY})
+ MESSAGE(STATUS "Using FMODEX path: ${FMODEX_LIBRARIES}, ${FMODEX_INCLUDE_DIR}")
+ else (FMODEX_LIBRARY AND FMODEX_INCLUDE_DIR)
+ # If not, we're going to try to get the package listed in autobuild.xml
+ # Note: if you're not using INSTALL_PROPRIETARY, the package URL should be local (file:/// URL)
+ # as accessing the private LL location will fail if you don't have the credential
+ include(Prebuilt)
+ use_prebuilt_binary(fmodex)
+ if (WINDOWS)
+ set(FMODEX_LIBRARY
+ debug fmodexL_vc
+ optimized fmodex_vc)
+ elseif (DARWIN)
+ set(FMODEX_LIBRARY
+ debug fmodexL
+ optimized fmodex)
+ elseif (LINUX)
+ set(FMODEX_LIBRARY
+ debug fmodexL
+ optimized fmodex)
+ endif (WINDOWS)
+ set(FMODEX_LIBRARIES ${FMODEX_LIBRARY})
+ set(FMODEX_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/fmodex)
+ endif (FMODEX_LIBRARY AND FMODEX_INCLUDE_DIR)
+ endif (STANDALONE)
+endif (FMODEX)
+
diff --git a/indra/cmake/FindAPR.cmake b/indra/cmake/FindAPR.cmake
index 906b6c9452..906b6c9452 100644..100755
--- a/indra/cmake/FindAPR.cmake
+++ b/indra/cmake/FindAPR.cmake
diff --git a/indra/cmake/FindAutobuild.cmake b/indra/cmake/FindAutobuild.cmake
index 4b5fd484ae..4b5fd484ae 100644..100755
--- a/indra/cmake/FindAutobuild.cmake
+++ b/indra/cmake/FindAutobuild.cmake
diff --git a/indra/cmake/FindBerkeleyDB.cmake b/indra/cmake/FindBerkeleyDB.cmake
index 2d633c74ec..2d633c74ec 100644..100755
--- a/indra/cmake/FindBerkeleyDB.cmake
+++ b/indra/cmake/FindBerkeleyDB.cmake
diff --git a/indra/cmake/FindCARes.cmake b/indra/cmake/FindCARes.cmake
index 1ed5b32913..1ed5b32913 100644..100755
--- a/indra/cmake/FindCARes.cmake
+++ b/indra/cmake/FindCARes.cmake
diff --git a/indra/cmake/FindELFIO.cmake b/indra/cmake/FindELFIO.cmake
deleted file mode 100644
index 8a5421ab9c..0000000000
--- a/indra/cmake/FindELFIO.cmake
+++ /dev/null
@@ -1,48 +0,0 @@
-# -*- cmake -*-
-
-# - Find ELFIO
-# Find the ELFIO includes and library
-# This module defines
-# ELFIO_INCLUDE_DIR, where to find elfio.h, etc.
-# ELFIO_LIBRARIES, the libraries needed to use ELFIO.
-# ELFIO_FOUND, If false, do not try to use ELFIO.
-# also defined, but not for general use are
-# ELFIO_LIBRARY, where to find the ELFIO library.
-
-FIND_PATH(ELFIO_INCLUDE_DIR ELFIO/ELFIO.h
-/usr/local/include
-/usr/include
-)
-
-SET(ELFIO_NAMES ${ELFIO_NAMES} ELFIO)
-FIND_LIBRARY(ELFIO_LIBRARY
- NAMES ${ELFIO_NAMES}
- PATHS /usr/lib /usr/local/lib
- )
-
-IF (ELFIO_LIBRARY AND ELFIO_INCLUDE_DIR)
- SET(ELFIO_LIBRARIES ${ELFIO_LIBRARY})
- SET(ELFIO_FOUND "YES")
-ELSE (ELFIO_LIBRARY AND ELFIO_INCLUDE_DIR)
- SET(ELFIO_FOUND "NO")
-ENDIF (ELFIO_LIBRARY AND ELFIO_INCLUDE_DIR)
-
-
-IF (ELFIO_FOUND)
- IF (NOT ELFIO_FIND_QUIETLY)
- MESSAGE(STATUS "Found ELFIO: ${ELFIO_LIBRARIES}")
- ENDIF (NOT ELFIO_FIND_QUIETLY)
-ELSE (ELFIO_FOUND)
- IF (ELFIO_FIND_REQUIRED)
- MESSAGE(FATAL_ERROR "Could not find ELFIO library")
- ENDIF (ELFIO_FIND_REQUIRED)
-ENDIF (ELFIO_FOUND)
-
-# Deprecated declarations.
-SET (NATIVE_ELFIO_INCLUDE_PATH ${ELFIO_INCLUDE_DIR} )
-GET_FILENAME_COMPONENT (NATIVE_ELFIO_LIB_PATH ${ELFIO_LIBRARY} PATH)
-
-MARK_AS_ADVANCED(
- ELFIO_LIBRARY
- ELFIO_INCLUDE_DIR
- )
diff --git a/indra/cmake/FindFMOD.cmake b/indra/cmake/FindFMOD.cmake
deleted file mode 100644
index 1ebbc8c96e..0000000000
--- a/indra/cmake/FindFMOD.cmake
+++ /dev/null
@@ -1,44 +0,0 @@
-# -*- cmake -*-
-
-# - Find FMOD
-# Find the FMOD includes and library
-# This module defines
-# FMOD_INCLUDE_DIR, where to find fmod.h and fmod_errors.h
-# FMOD_LIBRARIES, the libraries needed to use FMOD.
-# FMOD, If false, do not try to use FMOD.
-# also defined, but not for general use are
-# FMOD_LIBRARY, where to find the FMOD library.
-
-FIND_PATH(FMOD_INCLUDE_DIR fmod.h PATH_SUFFIXES fmod)
-
-SET(FMOD_NAMES ${FMOD_NAMES} fmod fmodvc fmodex fmod-3.75)
-FIND_LIBRARY(FMOD_LIBRARY
- NAMES ${FMOD_NAMES}
- PATH_SUFFIXES fmod
- )
-
-IF (FMOD_LIBRARY AND FMOD_INCLUDE_DIR)
- SET(FMOD_LIBRARIES ${FMOD_LIBRARY})
- SET(FMOD_FOUND "YES")
-ELSE (FMOD_LIBRARY AND FMOD_INCLUDE_DIR)
- SET(FMOD_FOUND "NO")
-ENDIF (FMOD_LIBRARY AND FMOD_INCLUDE_DIR)
-
-IF (FMOD_FOUND)
- IF (NOT FMOD_FIND_QUIETLY)
- MESSAGE(STATUS "Found FMOD: ${FMOD_LIBRARIES}")
- ENDIF (NOT FMOD_FIND_QUIETLY)
-ELSE (FMOD_FOUND)
- IF (FMOD_FIND_REQUIRED)
- MESSAGE(FATAL_ERROR "Could not find FMOD library")
- ENDIF (FMOD_FIND_REQUIRED)
-ENDIF (FMOD_FOUND)
-
-# Deprecated declarations.
-SET (NATIVE_FMOD_INCLUDE_PATH ${FMOD_INCLUDE_DIR} )
-GET_FILENAME_COMPONENT (NATIVE_FMOD_LIB_PATH ${FMOD_LIBRARY} PATH)
-
-MARK_AS_ADVANCED(
- FMOD_LIBRARY
- FMOD_INCLUDE_DIR
- )
diff --git a/indra/cmake/FindFMODEX.cmake b/indra/cmake/FindFMODEX.cmake
new file mode 100644
index 0000000000..b621727c0e
--- /dev/null
+++ b/indra/cmake/FindFMODEX.cmake
@@ -0,0 +1,65 @@
+# -*- cmake -*-
+
+# - Find FMODEX
+# Find the FMODEX includes and library
+# This module defines
+# FMODEX_INCLUDE_DIR, where to find fmod.h and fmod_errors.h
+# FMODEX_LIBRARIES, the libraries needed to use FMODEX.
+# FMODEX, If false, do not try to use FMODEX.
+# also defined, but not for general use are
+# FMODEX_LIBRARY, where to find the FMODEX library.
+
+FIND_PATH(FMODEX_INCLUDE_DIR fmod.h PATH_SUFFIXES fmod)
+
+SET(FMODEX_NAMES ${FMODEX_NAMES} fmodex fmodvc fmodexL_vc)
+FIND_LIBRARY(FMODEX_LIBRARY
+ NAMES ${FMODEX_NAMES}
+ PATH_SUFFIXES fmodex
+ )
+
+IF (FMODEX_SDK_DIR OR WINDOWS)
+ if(WINDOWS)
+ set(FMODEX_SDK_DIR "$ENV{PROGRAMFILES}/FMOD SoundSystem/FMOD Programmers API Windows" CACHE PATH "Path to FMODEX")
+ STRING(REGEX REPLACE "\\\\" "/" FMODEX_SDK_DIR ${FMODEX_SDK_DIR})
+ endif(WINDOWS)
+ find_library(FMODEX_LIBRARY
+ fmodex_vc fmodexL_vc
+ PATHS
+ ${FMODEX_SDK_DIR}/api/lib
+ ${FMODEX_SDK_DIR}/api
+ ${FMODEX_SDK_DIR}
+ )
+ find_path(FMODEX_INCLUDE_DIR fmod.h
+ ${FMODEX_SDK_DIR}/api/inc
+ ${FMODEX_SDK_DIR}/api
+ ${FMODEX_SDK_DIR}
+ )
+ find_path(FMODEX_INCLUDE_DIR fmod.h
+ ${FMODEX_SDK_DIR}/api/inc
+ ${FMODEX_SDK_DIR}/api
+ ${FMODEX_SDK_DIR}
+ )
+ IF (FMODEX_LIBRARY AND FMODEX_INCLUDE_DIR)
+ SET(FMODEX_LIBRARIES ${FMODEX_LIBRARY})
+ SET(FMODEX_FOUND "YES")
+ endif (FMODEX_LIBRARY AND FMODEX_INCLUDE_DIR)
+ENDIF (FMODEX_SDK_DIR OR WINDOWS)
+
+IF (FMODEX_FOUND)
+ IF (NOT FMODEX_FIND_QUIETLY)
+ MESSAGE(STATUS "Found FMODEX: ${FMODEX_LIBRARIES}")
+ ENDIF (NOT FMODEX_FIND_QUIETLY)
+ELSE (FMODEX_FOUND)
+ IF (FMODEX_FIND_REQUIRED)
+ MESSAGE(FATAL_ERROR "Could not find FMODEX library")
+ ENDIF (FMODEX_FIND_REQUIRED)
+ENDIF (FMODEX_FOUND)
+
+# Deprecated declarations.
+SET (NATIVE_FMODEX_INCLUDE_PATH ${FMODEX_INCLUDE_DIR} )
+GET_FILENAME_COMPONENT (NATIVE_FMODEX_LIB_PATH ${FMODEX_LIBRARY} PATH)
+
+MARK_AS_ADVANCED(
+ FMODEX_LIBRARY
+ FMODEX_INCLUDE_DIR
+ )
diff --git a/indra/cmake/FindGLH.cmake b/indra/cmake/FindGLH.cmake
index 3d16adaf03..3d16adaf03 100644..100755
--- a/indra/cmake/FindGLH.cmake
+++ b/indra/cmake/FindGLH.cmake
diff --git a/indra/cmake/FindGoogleBreakpad.cmake b/indra/cmake/FindGoogleBreakpad.cmake
index 1a0493be5e..1a0493be5e 100644..100755
--- a/indra/cmake/FindGoogleBreakpad.cmake
+++ b/indra/cmake/FindGoogleBreakpad.cmake
diff --git a/indra/cmake/FindGooglePerfTools.cmake b/indra/cmake/FindGooglePerfTools.cmake
index bb125d538e..bb125d538e 100644..100755
--- a/indra/cmake/FindGooglePerfTools.cmake
+++ b/indra/cmake/FindGooglePerfTools.cmake
diff --git a/indra/cmake/FindHUNSPELL.cmake b/indra/cmake/FindHUNSPELL.cmake
new file mode 100755
index 0000000000..6faf22959c
--- /dev/null
+++ b/indra/cmake/FindHUNSPELL.cmake
@@ -0,0 +1,38 @@
+# -*- cmake -*-
+
+# - Find HUNSPELL
+# This module defines
+# HUNSPELL_INCLUDE_DIR, where to find libhunspell.h, etc.
+# HUNSPELL_LIBRARY, the library needed to use HUNSPELL.
+# HUNSPELL_FOUND, If false, do not try to use HUNSPELL.
+
+find_path(HUNSPELL_INCLUDE_DIR hunspell.h
+ PATH_SUFFIXES hunspell
+ )
+
+set(HUNSPELL_NAMES ${HUNSPELL_NAMES} libhunspell-1.3.0 libhunspell)
+find_library(HUNSPELL_LIBRARY
+ NAMES ${HUNSPELL_NAMES}
+ )
+
+if (HUNSPELL_LIBRARY AND HUNSPELL_INCLUDE_DIR)
+ set(HUNSPELL_FOUND "YES")
+else (HUNSPELL_LIBRARY AND HUNSPELL_INCLUDE_DIR)
+ set(HUNSPELL_FOUND "NO")
+endif (HUNSPELL_LIBRARY AND HUNSPELL_INCLUDE_DIR)
+
+
+if (HUNSPELL_FOUND)
+ if (NOT HUNSPELL_FIND_QUIETLY)
+ message(STATUS "Found Hunspell: Library in '${HUNSPELL_LIBRARY}' and header in '${HUNSPELL_INCLUDE_DIR}' ")
+ endif (NOT HUNSPELL_FIND_QUIETLY)
+else (HUNSPELL_FOUND)
+ if (HUNSPELL_FIND_REQUIRED)
+ message(FATAL_ERROR " * * *\nCould not find HUNSPELL library! * * *")
+ endif (HUNSPELL_FIND_REQUIRED)
+endif (HUNSPELL_FOUND)
+
+mark_as_advanced(
+ HUNSPELL_LIBRARY
+ HUNSPELL_INCLUDE_DIR
+ )
diff --git a/indra/cmake/FindJsonCpp.cmake b/indra/cmake/FindJsonCpp.cmake
index 0b056ada58..0b056ada58 100644..100755
--- a/indra/cmake/FindJsonCpp.cmake
+++ b/indra/cmake/FindJsonCpp.cmake
diff --git a/indra/cmake/FindLLQtWebkit.cmake b/indra/cmake/FindLLQtWebkit.cmake
deleted file mode 100644
index 2f666d3bf0..0000000000
--- a/indra/cmake/FindLLQtWebkit.cmake
+++ /dev/null
@@ -1,62 +0,0 @@
-# -*- cmake -*-
-
-# - Find llqtwebkit
-# Find the llqtwebkit includes and library
-# This module defines
-# LLQTWEBKIT_INCLUDE_DIR, where to find llqtwebkit.h, etc.
-# LLQTWEBKIT_LIBRARY, the llqtwebkit library with full path.
-# LLQTWEBKIT_FOUND, If false, do not try to use llqtwebkit.
-# also defined, but not for general use are
-# LLQTWEBKIT_LIBRARIES, the libraries needed to use llqtwebkit.
-# LLQTWEBKIT_LIBRARY_DIRS, where to find the llqtwebkit library.
-# LLQTWEBKIT_DEFINITIONS - You should add_definitions(${LLQTWEBKIT_DEFINITIONS})
-# before compiling code that includes llqtwebkit library files.
-
-# Try to use pkg-config first.
-# This allows to have two different libllqtwebkit packages installed:
-# one for viewer 2.x and one for viewer 1.x.
-include(FindPkgConfig)
-if (PKG_CONFIG_FOUND)
- if (LLQtWebkit_FIND_REQUIRED AND LLQtWebkit_FIND_VERSION)
- set(_PACKAGE_ARGS libllqtwebkit>=${LLQtWebkit_FIND_VERSION} REQUIRED)
- else (LLQtWebkit_FIND_REQUIRED AND LLQtWebkit_FIND_VERSION)
- set(_PACKAGE_ARGS libllqtwebkit)
- endif (LLQtWebkit_FIND_REQUIRED AND LLQtWebkit_FIND_VERSION)
- if (NOT "${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_PATCH_VERSION}" VERSION_LESS "2.8.2")
- # As virtually nobody will have a pkg-config file for this, do this check always quiet.
- # Unfortunately cmake 2.8.2 or higher is required for pkg_check_modules to have a 'QUIET'.
- set(_PACKAGE_ARGS ${_PACKAGE_ARGS} QUIET)
- endif ()
- pkg_check_modules(LLQTWEBKIT ${_PACKAGE_ARGS})
-endif (PKG_CONFIG_FOUND)
-set(LLQTWEBKIT_DEFINITIONS ${LLQTWEBKIT_CFLAGS_OTHER})
-
-find_path(LLQTWEBKIT_INCLUDE_DIR llqtwebkit.h NO_SYSTEM_ENVIRONMENT_PATH HINTS ${LLQTWEBKIT_INCLUDE_DIRS})
-
-find_library(LLQTWEBKIT_LIBRARY NAMES llqtwebkit NO_SYSTEM_ENVIRONMENT_PATH HINTS ${LLQTWEBKIT_LIBRARY_DIRS})
-
-if (NOT PKG_CONFIG_FOUND OR NOT LLQTWEBKIT_FOUND) # If pkg-config couldn't find it, pretend we don't have pkg-config.
- set(LLQTWEBKIT_LIBRARIES llqtwebkit)
- get_filename_component(LLQTWEBKIT_LIBRARY_DIRS ${LLQTWEBKIT_LIBRARY} PATH)
-endif (NOT PKG_CONFIG_FOUND OR NOT LLQTWEBKIT_FOUND)
-
-# Handle the QUIETLY and REQUIRED arguments and set LLQTWEBKIT_FOUND
-# to TRUE if all listed variables are TRUE.
-include(FindPackageHandleStandardArgs)
-find_package_handle_standard_args(
- LLQTWEBKIT
- DEFAULT_MSG
- LLQTWEBKIT_LIBRARY
- LLQTWEBKIT_INCLUDE_DIR
- LLQTWEBKIT_LIBRARIES
- LLQTWEBKIT_LIBRARY_DIRS
- )
-
-mark_as_advanced(
- LLQTWEBKIT_LIBRARY
- LLQTWEBKIT_INCLUDE_DIR
- LLQTWEBKIT_LIBRARIES
- LLQTWEBKIT_LIBRARY_DIRS
- LLQTWEBKIT_DEFINITIONS
- )
-
diff --git a/indra/cmake/FindMT.cmake b/indra/cmake/FindMT.cmake
deleted file mode 100644
index 5239a4c2f5..0000000000
--- a/indra/cmake/FindMT.cmake
+++ /dev/null
@@ -1,15 +0,0 @@
-#Find the windows manifest tool.
-
-FIND_PROGRAM(HAVE_MANIFEST_TOOL NAMES mt
- PATHS
- "$ENV{PROGRAMFILES}/Microsoft Visual Studio 8/VC/bin"
- "$ENV{PROGRAMFILES}/Microsoft Visual Studio 8/Common7/Tools/Bin"
- "$ENV{PROGRAMFILES}/Microsoft Visual Studio 8/SDK/v2.0/Bin")
-IF(HAVE_MANIFEST_TOOL)
- MESSAGE(STATUS "Found Mainfest Tool. Embedding custom manifests.")
-ELSE(HAVE_MANIFEST_TOOL)
- MESSAGE(FATAL_ERROR "Manifest tool, mt.exe, can't be found.")
-ENDIF(HAVE_MANIFEST_TOOL)
-
-STRING(REPLACE "/MANIFEST" "/MANIFEST:NO" CMAKE_EXE_LINKER_FLAGS
- ${CMAKE_EXE_LINKER_FLAGS})
diff --git a/indra/cmake/FindMono.cmake b/indra/cmake/FindMono.cmake
deleted file mode 100644
index d956c48656..0000000000
--- a/indra/cmake/FindMono.cmake
+++ /dev/null
@@ -1,68 +0,0 @@
-# - Try to find the mono, mcs, gmcs and gacutil
-#
-# defines
-#
-# MONO_FOUND - system has mono, mcs, gmcs and gacutil
-# MONO_PATH - where to find 'mono'
-# MCS_PATH - where to find 'mcs'
-# GMCS_PATH - where to find 'gmcs'
-# GACUTIL_PATH - where to find 'gacutil'
-#
-# copyright (c) 2007 Arno Rehn arno@arnorehn.de
-#
-# Redistribution and use is allowed according to the terms of the GPL license.
-# Removed the check for gmcs
-
-FIND_PROGRAM (MONO_EXECUTABLE mono
- "$ENV{PROGRAMFILES}/Mono-1.9.1/bin"
- "$ENV{PROGRAMFILES}/Mono-1.2.6/bin"
- /bin
- /usr/bin
- /usr/local/bin
-)
-FIND_PROGRAM (MCS_EXECUTABLE mcs
- "$ENV{PROGRAMFILES}/Mono-1.9.1/bin"
- "$ENV{PROGRAMFILES}/Mono-1.2.6/bin"
- /bin
- /usr/bin
- /usr/local/bin
-)
-FIND_PROGRAM (GMCS_EXECUTABLE gmcs
- "$ENV{PROGRAMFILES}/Mono-1.9.1/bin"
- "$ENV{PROGRAMFILES}/Mono-1.2.6/bin"
- /bin
- /usr/bin
- /usr/local/bin
-)
-FIND_PROGRAM (GACUTIL_EXECUTABLE gacutil
- "$ENV{PROGRAMFILES}/Mono-1.9.1/bin"
- "$ENV{PROGRAMFILES}/Mono-1.2.6/bin"
- /bin
- /usr/bin
- /usr/local/bin
-)
-FIND_PROGRAM (ILASM_EXECUTABLE
- NAMES ilasm.bat ilasm
- NO_DEFAULT_PATH
- PATHS "$ENV{PROGRAMFILES}/Mono-1.9.1/bin" "$ENV{PROGRAMFILES}/Mono-1.2.6/bin" /bin /usr/bin /usr/local/bin
-)
-
-SET (MONO_FOUND FALSE)
-
-IF (MONO_EXECUTABLE AND MCS_EXECUTABLE AND GACUTIL_EXECUTABLE)
- SET (MONO_FOUND TRUE)
-ENDIF (MONO_EXECUTABLE AND MCS_EXECUTABLE AND GACUTIL_EXECUTABLE)
-
-IF (MONO_FOUND)
- IF (NOT Mono_FIND_QUIETLY)
- MESSAGE(STATUS "Found mono: ${MONO_EXECUTABLE}")
- MESSAGE(STATUS "Found mcs: ${MCS_EXECUTABLE}")
- MESSAGE(STATUS "Found gacutil: ${GACUTIL_EXECUTABLE}")
- ENDIF (NOT Mono_FIND_QUIETLY)
-ELSE (MONO_FOUND)
- IF (Mono_FIND_REQUIRED)
- MESSAGE(FATAL_ERROR "Could not find one or more of the following programs: mono, mcs, gacutil")
- ENDIF (Mono_FIND_REQUIRED)
-ENDIF (MONO_FOUND)
-
-MARK_AS_ADVANCED(MONO_EXECUTABLE MCS_EXECUTABLE GACUTIL_EXECUTABLE)
diff --git a/indra/cmake/FindMySQL.cmake b/indra/cmake/FindMySQL.cmake
deleted file mode 100644
index 431940328f..0000000000
--- a/indra/cmake/FindMySQL.cmake
+++ /dev/null
@@ -1,48 +0,0 @@
-# -*- cmake -*-
-
-# - Find MySQL
-# Find the MySQL includes and library
-# This module defines
-# MYSQL_INCLUDE_DIR, where to find mysql.h, etc.
-# MYSQL_LIBRARIES, the libraries needed to use Mysql.
-# MYSQL_FOUND, If false, do not try to use Mysql.
-# also defined, but not for general use are
-# MYSQL_LIBRARY, where to find the Mysql library.
-
-FIND_PATH(MYSQL_INCLUDE_DIR mysql/mysql.h
-/usr/local/include
-/usr/include
-)
-
-SET(MYSQL_NAMES ${MYSQL_NAMES} mysqlclient)
-FIND_LIBRARY(MYSQL_LIBRARY
- NAMES ${MYSQL_NAMES}
- PATHS /usr/lib/mysql /usr/lib /usr/local/lib/mysql /usr/local/lib
- )
-
-IF (MYSQL_LIBRARY AND MYSQL_INCLUDE_DIR)
- SET(MYSQL_LIBRARIES ${MYSQL_LIBRARY})
- SET(MYSQL_FOUND "YES")
-ELSE (MYSQL_LIBRARY AND MYSQL_INCLUDE_DIR)
- SET(MYSQL_FOUND "NO")
-ENDIF (MYSQL_LIBRARY AND MYSQL_INCLUDE_DIR)
-
-
-IF (MYSQL_FOUND)
- IF (NOT MYSQL_FIND_QUIETLY)
- MESSAGE(STATUS "Found MySQL: ${MYSQL_LIBRARIES}")
- ENDIF (NOT MYSQL_FIND_QUIETLY)
-ELSE (MYSQL_FOUND)
- IF (MYSQL_FIND_REQUIRED)
- MESSAGE(FATAL_ERROR "Could not find MySQL library")
- ENDIF (MYSQL_FIND_REQUIRED)
-ENDIF (MYSQL_FOUND)
-
-# Deprecated declarations.
-SET (NATIVE_MYSQL_INCLUDE_PATH ${MYSQL_INCLUDE_DIR} )
-GET_FILENAME_COMPONENT (NATIVE_MYSQL_LIB_PATH ${MYSQL_LIBRARY} PATH)
-
-MARK_AS_ADVANCED(
- MYSQL_LIBRARY
- MYSQL_INCLUDE_DIR
- )
diff --git a/indra/cmake/FindNDOF.cmake b/indra/cmake/FindNDOF.cmake
index 6dcf590a53..6dcf590a53 100644..100755
--- a/indra/cmake/FindNDOF.cmake
+++ b/indra/cmake/FindNDOF.cmake
diff --git a/indra/cmake/FindOpenJPEG.cmake b/indra/cmake/FindOpenJPEG.cmake
index 949384eec4..949384eec4 100644..100755
--- a/indra/cmake/FindOpenJPEG.cmake
+++ b/indra/cmake/FindOpenJPEG.cmake
diff --git a/indra/cmake/FindSCP.cmake b/indra/cmake/FindSCP.cmake
index ea02102908..ea02102908 100644..100755
--- a/indra/cmake/FindSCP.cmake
+++ b/indra/cmake/FindSCP.cmake
diff --git a/indra/cmake/FindSVN.cmake b/indra/cmake/FindSVN.cmake
deleted file mode 100644
index 3322be4ca9..0000000000
--- a/indra/cmake/FindSVN.cmake
+++ /dev/null
@@ -1,34 +0,0 @@
-# -*- cmake -*-
-#
-# Find the svn executable for exporting old svn:externals.
-#
-# Input variables:
-# SVN_FIND_REQUIRED - set this if configuration should fail without scp
-#
-# Output variables:
-#
-# SVN_FOUND - set if svn was found
-# SVN_EXECUTABLE - path to svn executable
-# SVN_BATCH_FLAG - how to put svn into batch mode
-
-
-SET(SVN_EXECUTABLE)
-FIND_PROGRAM(SVN_EXECUTABLE NAMES svn svn.exe)
-
-IF (SVN_EXECUTABLE)
- SET(SVN_FOUND ON)
-ELSE (SVN_EXECUTABLE)
- SET(SVN_FOUND OFF)
-ENDIF (SVN_EXECUTABLE)
-
-IF (SVN_FOUND)
- GET_FILENAME_COMPONENT(_svn_name ${SVN_EXECUTABLE} NAME_WE)
- SET(SVN_BATCH_FLAG --non-interactive)
-ELSE (SVN_FOUND)
- IF (SVN_FIND_REQUIRED)
- MESSAGE(FATAL_ERROR "Could not find svn executable")
- ENDIF (SVN_FIND_REQUIRED)
-ENDIF (SVN_FOUND)
-
-MARK_AS_ADVANCED(SVN_EXECUTABLE SVN_FOUND SVN_BATCH_FLAG)
-
diff --git a/indra/cmake/FindXmlRpcEpi.cmake b/indra/cmake/FindXmlRpcEpi.cmake
index ba217e7467..ba217e7467 100644..100755
--- a/indra/cmake/FindXmlRpcEpi.cmake
+++ b/indra/cmake/FindXmlRpcEpi.cmake
diff --git a/indra/cmake/FindZLIB.cmake b/indra/cmake/FindZLIB.cmake
index 03a7db9d6f..03a7db9d6f 100644..100755
--- a/indra/cmake/FindZLIB.cmake
+++ b/indra/cmake/FindZLIB.cmake
diff --git a/indra/cmake/FreeType.cmake b/indra/cmake/FreeType.cmake
index 43a9d282d0..c9a90a9a8d 100644..100755
--- a/indra/cmake/FreeType.cmake
+++ b/indra/cmake/FreeType.cmake
@@ -7,13 +7,7 @@ if (STANDALONE)
pkg_check_modules(FREETYPE REQUIRED freetype2)
else (STANDALONE)
use_prebuilt_binary(freetype)
- if (LINUX)
- set(FREETYPE_INCLUDE_DIRS
- ${LIBS_PREBUILT_DIR}/include)
- else (LINUX)
- set(FREETYPE_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include)
- endif (LINUX)
-
+ set(FREETYPE_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include)
set(FREETYPE_LIBRARIES freetype)
endif (STANDALONE)
diff --git a/indra/cmake/GLEXT.cmake b/indra/cmake/GLEXT.cmake
new file mode 100644
index 0000000000..0a3dd976b4
--- /dev/null
+++ b/indra/cmake/GLEXT.cmake
@@ -0,0 +1,8 @@
+# -*- cmake -*-
+include(Prebuilt)
+
+if (NOT STANDALONE)
+ use_prebuilt_binary(glext)
+ use_prebuilt_binary(glh_linear)
+ set(GLEXT_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include)
+endif (NOT STANDALONE)
diff --git a/indra/cmake/GLH.cmake b/indra/cmake/GLH.cmake
index 911dbe4017..911dbe4017 100644..100755
--- a/indra/cmake/GLH.cmake
+++ b/indra/cmake/GLH.cmake
diff --git a/indra/cmake/GLOD.cmake b/indra/cmake/GLOD.cmake
index 77221d55ed..6bdbaf621e 100644..100755
--- a/indra/cmake/GLOD.cmake
+++ b/indra/cmake/GLOD.cmake
@@ -6,4 +6,4 @@ if (NOT STANDALONE)
endif (NOT STANDALONE)
set(GLOD_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include)
-set(GLOD_LIBRARIES glod)
+set(GLOD_LIBRARIES GLOD)
diff --git a/indra/cmake/GStreamer010Plugin.cmake b/indra/cmake/GStreamer010Plugin.cmake
index d2d0699bcd..d2d0699bcd 100644..100755
--- a/indra/cmake/GStreamer010Plugin.cmake
+++ b/indra/cmake/GStreamer010Plugin.cmake
diff --git a/indra/cmake/GetPrerequisites_2_8.cmake b/indra/cmake/GetPrerequisites_2_8.cmake
index 05ec1539ba..05ec1539ba 100644..100755
--- a/indra/cmake/GetPrerequisites_2_8.cmake
+++ b/indra/cmake/GetPrerequisites_2_8.cmake
diff --git a/indra/cmake/Glui.cmake b/indra/cmake/Glui.cmake
index f62a56856c..f62a56856c 100644..100755
--- a/indra/cmake/Glui.cmake
+++ b/indra/cmake/Glui.cmake
diff --git a/indra/cmake/Glut.cmake b/indra/cmake/Glut.cmake
index 314da30652..314da30652 100644..100755
--- a/indra/cmake/Glut.cmake
+++ b/indra/cmake/Glut.cmake
diff --git a/indra/cmake/GoogleBreakpad.cmake b/indra/cmake/GoogleBreakpad.cmake
index 7498674042..96e22791ec 100644..100755
--- a/indra/cmake/GoogleBreakpad.cmake
+++ b/indra/cmake/GoogleBreakpad.cmake
@@ -15,5 +15,8 @@ else (STANDALONE)
if (WINDOWS)
set(BREAKPAD_EXCEPTION_HANDLER_LIBRARIES exception_handler crash_generation_client common)
endif (WINDOWS)
+ # yes, this does look dumb, no, it's not incorrect
+ #
+ set(BREAKPAD_INCLUDE_DIRECTORIES "${LIBS_PREBUILT_DIR}/include/google_breakpad" "${LIBS_PREBUILT_DIR}/include/google_breakpad/google_breakpad")
endif (STANDALONE)
diff --git a/indra/cmake/GoogleMock.cmake b/indra/cmake/GoogleMock.cmake
index c4c96a9af7..c4c96a9af7 100644..100755
--- a/indra/cmake/GoogleMock.cmake
+++ b/indra/cmake/GoogleMock.cmake
diff --git a/indra/cmake/GooglePerfTools.cmake b/indra/cmake/GooglePerfTools.cmake
index d9f91193be..f3fd008e49 100644..100755
--- a/indra/cmake/GooglePerfTools.cmake
+++ b/indra/cmake/GooglePerfTools.cmake
@@ -1,20 +1,34 @@
# -*- cmake -*-
include(Prebuilt)
+# If you want to enable or disable TCMALLOC in viewer builds, this is the place.
+# set ON or OFF as desired.
+set (USE_TCMALLOC OFF)
+
if (STANDALONE)
include(FindGooglePerfTools)
else (STANDALONE)
if (WINDOWS)
- use_prebuilt_binary(tcmalloc)
- set(TCMALLOC_LIBRARIES
- debug libtcmalloc_minimal-debug
- optimized libtcmalloc_minimal)
+ if (USE_TCMALLOC)
+ use_prebuilt_binary(gperftools)
+ set(TCMALLOC_LIBRARIES
+ debug libtcmalloc_minimal-debug
+ optimized libtcmalloc_minimal)
+ set(TCMALLOC_LINK_FLAGS "/INCLUDE:__tcmalloc")
+ else (USE_TCMALLOC)
+ set(TCMALLOC_LIBRARIES)
+ set(TCMALLOC_LINK_FLAGS)
+ endif (USE_TCMALLOC)
set(GOOGLE_PERFTOOLS_FOUND "YES")
endif (WINDOWS)
if (LINUX)
- use_prebuilt_binary(tcmalloc)
- set(TCMALLOC_LIBRARIES
- tcmalloc)
+ if (USE_TCMALLOC)
+ use_prebuilt_binary(gperftools)
+ set(TCMALLOC_LIBRARIES
+ tcmalloc)
+ else (USE_TCMALLOC)
+ set(TCMALLOC_LIBRARIES)
+ endif (USE_TCMALLOC)
set(PROFILER_LIBRARIES profiler)
set(GOOGLE_PERFTOOLS_INCLUDE_DIR
${LIBS_PREBUILT_DIR}/include)
@@ -29,13 +43,19 @@ if (GOOGLE_PERFTOOLS_FOUND)
endif (GOOGLE_PERFTOOLS_FOUND)
if (WINDOWS)
- set(USE_GOOGLE_PERFTOOLS ON)
+ set(USE_GOOGLE_PERFTOOLS ON)
endif (WINDOWS)
if (USE_GOOGLE_PERFTOOLS)
- set(TCMALLOC_FLAG -ULL_USE_TCMALLOC=1)
+ if (USE_TCMALLOC)
+ set(TCMALLOC_FLAG -DLL_USE_TCMALLOC=1)
+ else (USE_TCMALLOC)
+ set(TCMALLOC_FLAG -ULL_USE_TCMALLOC)
+ endif (USE_TCMALLOC)
+endif (USE_GOOGLE_PERFTOOLS)
+
+if (USE_GOOGLE_PERFTOOLS)
include_directories(${GOOGLE_PERFTOOLS_INCLUDE_DIR})
set(GOOGLE_PERFTOOLS_LIBRARIES ${TCMALLOC_LIBRARIES} ${STACKTRACE_LIBRARIES} ${PROFILER_LIBRARIES})
else (USE_GOOGLE_PERFTOOLS)
- set(TCMALLOC_FLAG -ULL_USE_TCMALLOC)
endif (USE_GOOGLE_PERFTOOLS)
diff --git a/indra/cmake/Havok.cmake b/indra/cmake/Havok.cmake
new file mode 100755
index 0000000000..8b7f01d20b
--- /dev/null
+++ b/indra/cmake/Havok.cmake
@@ -0,0 +1,137 @@
+# -*- cmake -*-
+
+if(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED)
+set(${CMAKE_CURRENT_LIST_FILE}_INCLUDED "YES")
+
+use_prebuilt_binary(havok-source)
+
+set(Havok_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include/havok/Source)
+list(APPEND Havok_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include/havok/Demo)
+
+set(HAVOK_DEBUG_LIBRARY_PATH ${LIBS_PREBUILT_DIR}/lib/debug/havok-fulldebug)
+set(HAVOK_RELEASE_LIBRARY_PATH ${LIBS_PREBUILT_DIR}/lib/release/havok)
+
+if (LL_DEBUG_HAVOK)
+ if (WIN32)
+ # Always link relwithdebinfo to havok-hybrid on windows.
+ set(HAVOK_RELWITHDEBINFO_LIBRARY_PATH ${LIBS_PREBUILT_DIR}/lib/debug/havok-hybrid)
+ else (WIN32)
+ set(HAVOK_RELWITHDEBINFO_LIBRARY_PATH ${LIBS_PREBUILT_DIR}/lib/debug/havok-fulldebug)
+ endif (WIN32)
+else (LL_DEBUG_HAVOK)
+ set(HAVOK_RELWITHDEBINFO_LIBRARY_PATH ${LIBS_PREBUILT_DIR}/lib/release/havok)
+endif (LL_DEBUG_HAVOK)
+
+set(HAVOK_LIBS
+ hkBase
+ hkCompat
+ hkGeometryUtilities
+ hkInternal
+ hkSerialize
+ hkSceneData
+ hkpCollide
+ hkpUtilities
+ hkpConstraintSolver
+ hkpDynamics
+ hkpInternal
+ hkaiInternal
+ hkaiPathfinding
+ hkaiAiPhysicsBridge
+ hkcdInternal
+ hkcdCollide
+ hkpVehicle
+ hkVisualize
+ hkaiVisualize
+ hkgpConvexDecomposition
+)
+
+unset(HK_DEBUG_LIBRARIES)
+unset(HK_RELEASE_LIBRARIES)
+unset(HK_RELWITHDEBINFO_LIBRARIES)
+
+# *TODO: Figure out why we need to extract like this...
+foreach(HAVOK_LIB ${HAVOK_LIBS})
+ find_library(HAVOK_DEBUG_LIB_${HAVOK_LIB} ${HAVOK_LIB} PATHS ${HAVOK_DEBUG_LIBRARY_PATH})
+ find_library(HAVOK_RELEASE_LIB_${HAVOK_LIB} ${HAVOK_LIB} PATHS ${HAVOK_RELEASE_LIBRARY_PATH})
+ find_library(HAVOK_RELWITHDEBINFO_LIB_${HAVOK_LIB} ${HAVOK_LIB} PATHS ${HAVOK_RELWITHDEBINFO_LIBRARY_PATH})
+
+ if(LINUX)
+ set(debug_dir "${HAVOK_DEBUG_LIBRARY_PATH}/${HAVOK_LIB}")
+ set(release_dir "${HAVOK_RELEASE_LIBRARY_PATH}/${HAVOK_LIB}")
+ set(relwithdebinfo_dir "${HAVOK_RELWITHDEBINFO_LIBRARY_PATH}/${HAVOK_LIB}")
+
+ # Try to avoid extracting havok library each time we run cmake.
+ if("${havok_${HAVOK_LIB}_extracted}" STREQUAL "" AND EXISTS "${CMAKE_BINARY_DIR}/temp/havok_${HAVOK_LIB}_extracted")
+ file(READ ${CMAKE_BINARY_DIR}/temp/havok_${HAVOK_LIB}_extracted "havok_${HAVOK_LIB}_extracted")
+ if(DEBUG_PREBUILT)
+ message(STATUS "havok_${HAVOK_LIB}_extracted: \"${havok_${HAVOK_LIB}_extracted}\"")
+ endif(DEBUG_PREBUILT)
+ endif("${havok_${HAVOK_LIB}_extracted}" STREQUAL "" AND EXISTS "${CMAKE_BINARY_DIR}/temp/havok_${HAVOK_LIB}_extracted")
+
+ if(${CMAKE_BINARY_DIR}/temp/havok-source_installed IS_NEWER_THAN ${CMAKE_BINARY_DIR}/temp/havok_${HAVOK_LIB}_extracted OR NOT ${havok_${HAVOK_LIB}_extracted} EQUAL 0)
+ if(DEBUG_PREBUILT)
+ MESSAGE(STATUS "Extracting ${HAVOK_LIB}...")
+ endif(DEBUG_PREBUILT)
+ set(cmd "mkdir")
+
+ if(DEBUG_PREBUILT)
+ MESSAGE(STATUS "${cmd} ${debug_dir}")
+ endif(DEBUG_PREBUILT)
+ exec_program( ${cmd} ${HAVOK_DEBUG_LIBRARY_PATH} ARGS ${debug_dir} OUTPUT_VARIABLE rv)
+
+ if(DEBUG_PREBUILT)
+ MESSAGE(STATUS "${cmd} ${release_dir}")
+ endif(DEBUG_PREBUILT)
+ exec_program( ${cmd} ${HAVOK_RELEASE_LIBRARY_PATH} ARGS ${release_dir} OUTPUT_VARIABLE rv)
+
+ if(DEBUG_PREBUILT)
+ MESSAGE(STATUS "${cmd} ${relwithdebinfo_dir}")
+ endif(DEBUG_PREBUILT)
+ exec_program( ${cmd} ${HAVOK_RELWITHDEBINFO_LIBRARY_PATH} ARGS ${relwithdebinfo_dir} OUTPUT_VARIABLE rv)
+
+ set(cmd "ar")
+ set(arg " -xv")
+ set(arg "${arg} ../lib${HAVOK_LIB}.a")
+ if(DEBUG_PREBUILT)
+ MESSAGE(STATUS "cd ${debug_dir} && ${cmd} ${arg}")
+ endif(DEBUG_PREBUILT)
+ exec_program( ${cmd} ${debug_dir} ARGS ${arg} OUTPUT_VARIABLE rv)
+
+ if(DEBUG_PREBUILT)
+ MESSAGE(STATUS "cd ${release_dir} && ${cmd} ${arg}")
+ endif(DEBUG_PREBUILT)
+ exec_program( ${cmd} ${release_dir} ARGS ${arg} OUTPUT_VARIABLE rv)
+
+ if(DEBUG_PREBUILT)
+ MESSAGE(STATUS "cd ${relwithdebinfo_dir} && ${cmd} ${arg}")
+ endif(DEBUG_PREBUILT)
+ exec_program( ${cmd} ${relwithdebinfo_dir} ARGS ${arg} OUTPUT_VARIABLE rv)
+
+ # Just assume success for now.
+ set(havok_${HAVOK_LIB}_extracted 0)
+ file(WRITE ${CMAKE_BINARY_DIR}/temp/havok_${HAVOK_LIB}_extracted "${havok_${HAVOK_LIB}_extracted}")
+
+ endif(${CMAKE_BINARY_DIR}/temp/havok-source_installed IS_NEWER_THAN ${CMAKE_BINARY_DIR}/temp/havok_${HAVOK_LIB}_extracted OR NOT ${havok_${HAVOK_LIB}_extracted} EQUAL 0)
+
+ file(GLOB extracted_debug "${debug_dir}/*.o")
+ file(GLOB extracted_release "${release_dir}/*.o")
+ file(GLOB extracted_relwithdebinfo "${relwithdebinfo_dir}/*.o")
+
+ if(DEBUG_PREBUILT)
+ MESSAGE(STATUS "extracted_debug ${debug_dir}/*.o")
+ MESSAGE(STATUS "extracted_release ${release_dir}/*.o")
+ MESSAGE(STATUS "extracted_relwithdebinfo ${relwithdebinfo_dir}/*.o")
+ endif(DEBUG_PREBUILT)
+
+ list(APPEND HK_DEBUG_LIBRARIES ${extracted_debug})
+ list(APPEND HK_RELEASE_LIBRARIES ${extracted_release})
+ list(APPEND HK_RELWITHDEBINFO_LIBRARIES ${extracted_relwithdebinfo})
+ else(LINUX)
+ # Win32
+ list(APPEND HK_DEBUG_LIBRARIES ${HAVOK_DEBUG_LIB_${HAVOK_LIB}})
+ list(APPEND HK_RELEASE_LIBRARIES ${HAVOK_RELEASE_LIB_${HAVOK_LIB}})
+ list(APPEND HK_RELWITHDEBINFO_LIBRARIES ${HAVOK_RELWITHDEBINFO_LIB_${HAVOK_LIB}})
+ endif (LINUX)
+endforeach(HAVOK_LIB)
+
+endif(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED)
diff --git a/indra/cmake/Hunspell.cmake b/indra/cmake/Hunspell.cmake
new file mode 100755
index 0000000000..0c9cf93316
--- /dev/null
+++ b/indra/cmake/Hunspell.cmake
@@ -0,0 +1,22 @@
+# -*- cmake -*-
+include(Prebuilt)
+
+set(HUNSPELL_FIND_QUIETLY ON)
+set(HUNSPELL_FIND_REQUIRED ON)
+
+if (STANDALONE)
+ include(FindHUNSPELL)
+else (STANDALONE)
+ use_prebuilt_binary(libhunspell)
+ if (WINDOWS)
+ set(HUNSPELL_LIBRARY libhunspell)
+ elseif(DARWIN)
+ set(HUNSPELL_LIBRARY hunspell-1.3.0)
+ elseif(LINUX)
+ set(HUNSPELL_LIBRARY hunspell-1.3)
+ else()
+ message(FATAL_ERROR "Invalid platform")
+ endif()
+ set(HUNSPELL_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include/hunspell)
+ use_prebuilt_binary(dictionaries)
+endif (STANDALONE)
diff --git a/indra/cmake/JPEG.cmake b/indra/cmake/JPEG.cmake
index 4f99efd602..4f99efd602 100644..100755
--- a/indra/cmake/JPEG.cmake
+++ b/indra/cmake/JPEG.cmake
diff --git a/indra/cmake/JsonCpp.cmake b/indra/cmake/JsonCpp.cmake
index 7ad73e5683..7ad73e5683 100644..100755
--- a/indra/cmake/JsonCpp.cmake
+++ b/indra/cmake/JsonCpp.cmake
diff --git a/indra/cmake/LLAddBuildTest.cmake b/indra/cmake/LLAddBuildTest.cmake
index 08feab6e36..9bb3077797 100644
--- a/indra/cmake/LLAddBuildTest.cmake
+++ b/indra/cmake/LLAddBuildTest.cmake
@@ -201,10 +201,22 @@ FUNCTION(LL_ADD_INTEGRATION_TEST
endif(TEST_DEBUG)
ADD_EXECUTABLE(INTEGRATION_TEST_${testname} ${source_files})
SET_TARGET_PROPERTIES(INTEGRATION_TEST_${testname} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${EXE_STAGING_DIR}")
+
if(STANDALONE)
SET_TARGET_PROPERTIES(INTEGRATION_TEST_${testname} PROPERTIES COMPILE_FLAGS -I"${TUT_INCLUDE_DIR}")
endif(STANDALONE)
+ # The following was copied to llcorehttp/CMakeLists.txt's texture_load target.
+ # Any changes made here should be replicated there.
+ if (WINDOWS)
+ SET_TARGET_PROPERTIES(INTEGRATION_TEST_${testname}
+ PROPERTIES
+ LINK_FLAGS "/debug /NODEFAULTLIB:LIBCMT /SUBSYSTEM:WINDOWS"
+ LINK_FLAGS_DEBUG "/NODEFAULTLIB:\"LIBCMT;LIBCMTD;MSVCRT\" /INCREMENTAL:NO"
+ LINK_FLAGS_RELEASE ""
+ )
+ endif (WINDOWS)
+
# Add link deps to the executable
if(TEST_DEBUG)
message(STATUS "TARGET_LINK_LIBRARIES(INTEGRATION_TEST_${testname} ${libraries})")
diff --git a/indra/cmake/LLAppearance.cmake b/indra/cmake/LLAppearance.cmake
new file mode 100644
index 0000000000..bd3795a526
--- /dev/null
+++ b/indra/cmake/LLAppearance.cmake
@@ -0,0 +1,17 @@
+# -*- cmake -*-
+
+include(Variables)
+
+set(LLAPPEARANCE_INCLUDE_DIRS
+ ${LIBS_OPEN_DIR}/llappearance
+ )
+
+if (BUILD_HEADLESS)
+ set(LLAPPEARANCE_HEADLESS_LIBRARIES
+ llappearanceheadless
+ )
+endif (BUILD_HEADLESS)
+
+set(LLAPPEARANCE_LIBRARIES llappearance)
+
+
diff --git a/indra/cmake/LLAppearanceUtility.cmake b/indra/cmake/LLAppearanceUtility.cmake
new file mode 100644
index 0000000000..bea45543de
--- /dev/null
+++ b/indra/cmake/LLAppearanceUtility.cmake
@@ -0,0 +1,12 @@
+# -*- cmake -*-
+include(Prebuilt)
+
+# Linux proprietary build only
+if (INSTALL_PROPRIETARY)
+ if(LINUX)
+ use_prebuilt_binary(llappearanceutility-source)
+ set(LLAPPEARANCEUTILITY_SRC_DIR ${LIBS_PREBUILT_DIR}/llappearanceutility/src)
+ set(LLAPPEARANCEUTILITY_BIN_DIR ${CMAKE_BINARY_DIR}/llappearanceutility)
+ endif (LINUX)
+endif (INSTALL_PROPRIETARY)
+
diff --git a/indra/cmake/LLAudio.cmake b/indra/cmake/LLAudio.cmake
index 7c248dfc72..7c248dfc72 100644..100755
--- a/indra/cmake/LLAudio.cmake
+++ b/indra/cmake/LLAudio.cmake
diff --git a/indra/cmake/LLCharacter.cmake b/indra/cmake/LLCharacter.cmake
index 9b2f5c4956..9b2f5c4956 100644..100755
--- a/indra/cmake/LLCharacter.cmake
+++ b/indra/cmake/LLCharacter.cmake
diff --git a/indra/cmake/LLCommon.cmake b/indra/cmake/LLCommon.cmake
index 17e211cb99..b52556a73e 100644..100755
--- a/indra/cmake/LLCommon.cmake
+++ b/indra/cmake/LLCommon.cmake
@@ -10,6 +10,8 @@ set(LLCOMMON_INCLUDE_DIRS
${LIBS_OPEN_DIR}/llcommon
${APRUTIL_INCLUDE_DIR}
${APR_INCLUDE_DIR}
+ )
+set(LLCOMMON_SYSTEM_INCLUDE_DIRS
${Boost_INCLUDE_DIRS}
)
@@ -22,9 +24,9 @@ else (LINUX)
set(LLCOMMON_LIBRARIES llcommon)
endif (LINUX)
-add_definitions(${TCMALLOC_FLAG})
+# add_definitions(${TCMALLOC_FLAG})
-set(LLCOMMON_LINK_SHARED ON CACHE BOOL "Build the llcommon target as a shared library.")
+set(LLCOMMON_LINK_SHARED OFF CACHE BOOL "Build the llcommon target as a static library.")
if(LLCOMMON_LINK_SHARED)
add_definitions(-DLL_COMMON_LINK_SHARED=1)
endif(LLCOMMON_LINK_SHARED)
diff --git a/indra/cmake/LLConvexDecomposition.cmake b/indra/cmake/LLConvexDecomposition.cmake
deleted file mode 100644
index 8e44504782..0000000000
--- a/indra/cmake/LLConvexDecomposition.cmake
+++ /dev/null
@@ -1,12 +0,0 @@
-# -*- cmake -*-
-include(Prebuilt)
-
-set(LLCONVEXDECOMP_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include)
-
-if (INSTALL_PROPRIETARY AND NOT STANDALONE)
- use_prebuilt_binary(llconvexdecomposition)
- set(LLCONVEXDECOMP_LIBRARY llconvexdecomposition)
-else (INSTALL_PROPRIETARY AND NOT STANDALONE)
- use_prebuilt_binary(llconvexdecompositionstub)
- set(LLCONVEXDECOMP_LIBRARY llconvexdecompositionstub)
-endif (INSTALL_PROPRIETARY AND NOT STANDALONE)
diff --git a/indra/cmake/LLCoreHttp.cmake b/indra/cmake/LLCoreHttp.cmake
new file mode 100755
index 0000000000..61e4b23d98
--- /dev/null
+++ b/indra/cmake/LLCoreHttp.cmake
@@ -0,0 +1,16 @@
+# -*- cmake -*-
+
+include(CARes)
+include(CURL)
+include(OpenSSL)
+include(Boost)
+
+set(LLCOREHTTP_INCLUDE_DIRS
+ ${LIBS_OPEN_DIR}/llcorehttp
+ ${CARES_INCLUDE_DIRS}
+ ${CURL_INCLUDE_DIRS}
+ ${OPENSSL_INCLUDE_DIRS}
+ ${BOOST_INCLUDE_DIRS}
+ )
+
+set(LLCOREHTTP_LIBRARIES llcorehttp)
diff --git a/indra/cmake/LLCrashLogger.cmake b/indra/cmake/LLCrashLogger.cmake
index f2cb83eb8b..f2cb83eb8b 100644..100755
--- a/indra/cmake/LLCrashLogger.cmake
+++ b/indra/cmake/LLCrashLogger.cmake
diff --git a/indra/cmake/LLDatabase.cmake b/indra/cmake/LLDatabase.cmake
deleted file mode 100644
index 6526101386..0000000000
--- a/indra/cmake/LLDatabase.cmake
+++ /dev/null
@@ -1,10 +0,0 @@
-# -*- cmake -*-
-
-include(MySQL)
-
-set(LLDATABASE_INCLUDE_DIRS
- ${LIBS_SERVER_DIR}/lldatabase
- ${MYSQL_INCLUDE_DIR}
- )
-
-set(LLDATABASE_LIBRARIES lldatabase)
diff --git a/indra/cmake/LLImage.cmake b/indra/cmake/LLImage.cmake
index ec3da89081..ec3da89081 100644..100755
--- a/indra/cmake/LLImage.cmake
+++ b/indra/cmake/LLImage.cmake
diff --git a/indra/cmake/LLImageJ2COJ.cmake b/indra/cmake/LLImageJ2COJ.cmake
index 1bcf205f2d..1bcf205f2d 100644..100755
--- a/indra/cmake/LLImageJ2COJ.cmake
+++ b/indra/cmake/LLImageJ2COJ.cmake
diff --git a/indra/cmake/LLInventory.cmake b/indra/cmake/LLInventory.cmake
index c3dc077a2b..c3dc077a2b 100644..100755
--- a/indra/cmake/LLInventory.cmake
+++ b/indra/cmake/LLInventory.cmake
diff --git a/indra/cmake/LLKDU.cmake b/indra/cmake/LLKDU.cmake
index e478b01f84..e478b01f84 100644..100755
--- a/indra/cmake/LLKDU.cmake
+++ b/indra/cmake/LLKDU.cmake
diff --git a/indra/cmake/LLLogin.cmake b/indra/cmake/LLLogin.cmake
index 47d171876a..47d171876a 100644..100755
--- a/indra/cmake/LLLogin.cmake
+++ b/indra/cmake/LLLogin.cmake
diff --git a/indra/cmake/LLMath.cmake b/indra/cmake/LLMath.cmake
index 893920ae6f..893920ae6f 100644..100755
--- a/indra/cmake/LLMath.cmake
+++ b/indra/cmake/LLMath.cmake
diff --git a/indra/cmake/LLMessage.cmake b/indra/cmake/LLMessage.cmake
index 0143d04fd7..0143d04fd7 100644..100755
--- a/indra/cmake/LLMessage.cmake
+++ b/indra/cmake/LLMessage.cmake
diff --git a/indra/cmake/LLPhysicsExtensions.cmake b/indra/cmake/LLPhysicsExtensions.cmake
new file mode 100755
index 0000000000..e6afee762e
--- /dev/null
+++ b/indra/cmake/LLPhysicsExtensions.cmake
@@ -0,0 +1,35 @@
+# -*- cmake -*-
+include(Prebuilt)
+
+# There are three possible solutions to provide the llphysicsextensions:
+# - The full source package, selected by -DHAVOK:BOOL=ON
+# - The stub source package, selected by -DHAVOK:BOOL=OFF
+# - The prebuilt package available to those with sublicenses, selected by -DHAVOK_TPV:BOOL=ON
+
+if (INSTALL_PROPRIETARY)
+ set(HAVOK ON CACHE BOOL "Use Havok physics library")
+endif (INSTALL_PROPRIETARY)
+
+
+# Note that the use_prebuilt_binary macros below do not in fact include binaries;
+# the llphysicsextensions_* packages are source only and are built here.
+# The source package and the stub package both build libraries of the same name.
+
+if (HAVOK)
+ include(Havok)
+ use_prebuilt_binary(llphysicsextensions_source)
+ set(LLPHYSICSEXTENSIONS_SRC_DIR ${LIBS_PREBUILT_DIR}/llphysicsextensions/src)
+ set(LLPHYSICSEXTENSIONS_LIBRARIES llphysicsextensions)
+
+elseif (HAVOK_TPV)
+ use_prebuilt_binary(llphysicsextensions_tpv)
+ set(LLPHYSICSEXTENSIONS_LIBRARIES llphysicsextensions_tpv)
+
+else (HAVOK)
+ use_prebuilt_binary(llphysicsextensions_stub)
+ set(LLPHYSICSEXTENSIONS_SRC_DIR ${LIBS_PREBUILT_DIR}/llphysicsextensions/stub)
+ set(LLPHYSICSEXTENSIONS_LIBRARIES llphysicsextensionsstub)
+
+endif (HAVOK)
+
+set(LLPHYSICSEXTENSIONS_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include/llphysicsextensions)
diff --git a/indra/cmake/LLPlugin.cmake b/indra/cmake/LLPlugin.cmake
index 399cb332dd..399cb332dd 100644..100755
--- a/indra/cmake/LLPlugin.cmake
+++ b/indra/cmake/LLPlugin.cmake
diff --git a/indra/cmake/LLPrimitive.cmake b/indra/cmake/LLPrimitive.cmake
index f15a2c2649..0d87ff579a 100644..100755
--- a/indra/cmake/LLPrimitive.cmake
+++ b/indra/cmake/LLPrimitive.cmake
@@ -2,6 +2,8 @@
# these should be moved to their own cmake file
include(Prebuilt)
+include(Boost)
+
use_prebuilt_binary(colladadom)
use_prebuilt_binary(pcre)
use_prebuilt_binary(libxml)
@@ -15,10 +17,7 @@ if (WINDOWS)
optimized llprimitive
debug libcollada14dom22-d
optimized libcollada14dom22
- debug libboost_filesystem-vc100-mt-gd-1_45
- optimized libboost_filesystem-vc100-mt-1_45
- debug libboost_system-vc100-mt-gd-1_45
- optimized libboost_system-vc100-mt-1_45
+ ${BOOST_SYSTEM_LIBRARIES}
)
else (WINDOWS)
set(LLPRIMITIVE_LIBRARIES
diff --git a/indra/cmake/LLRender.cmake b/indra/cmake/LLRender.cmake
index 8427928151..868922451f 100644..100755
--- a/indra/cmake/LLRender.cmake
+++ b/indra/cmake/LLRender.cmake
@@ -1,5 +1,6 @@
# -*- cmake -*-
+include(Variables)
include(FreeType)
include(GLH)
@@ -8,27 +9,12 @@ set(LLRENDER_INCLUDE_DIRS
${GLH_INCLUDE_DIR}
)
-if (SERVER AND LINUX)
- set(LLRENDER_LIBRARIES
+if (BUILD_HEADLESS)
+ set(LLRENDER_HEADLESS_LIBRARIES
llrenderheadless
)
-else (SERVER AND LINUX)
+endif (BUILD_HEADLESS)
set(LLRENDER_LIBRARIES
llrender
)
-endif (SERVER AND LINUX)
-# mapserver requires certain files to be copied so LL_MESA_HEADLESS can be set
-# differently for different object files.
-macro (copy_server_sources )
- foreach (PREFIX ${ARGV})
- add_custom_command(
- OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${PREFIX}_server.cpp
- COMMAND ${CMAKE_COMMAND}
- ARGS -E copy ${CMAKE_CURRENT_SOURCE_DIR}/${PREFIX}.cpp
- ${CMAKE_CURRENT_BINARY_DIR}/${PREFIX}_server.cpp
- DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${PREFIX}.cpp
- )
- list(APPEND server_SOURCE_FILES ${PREFIX}_server.cpp)
- endforeach (PREFIX ${_copied_SOURCES})
-endmacro (copy_server_sources _copied_SOURCES)
diff --git a/indra/cmake/LLScene.cmake b/indra/cmake/LLScene.cmake
deleted file mode 100644
index 96ad5085a2..0000000000
--- a/indra/cmake/LLScene.cmake
+++ /dev/null
@@ -1,7 +0,0 @@
-# -*- cmake -*-
-
-set(LLSCENE_INCLUDE_DIRS
- ${LIBS_SERVER_DIR}/llscene
- )
-
-set(LLSCENE_LIBRARIES llscene)
diff --git a/indra/cmake/LLSharedLibs.cmake b/indra/cmake/LLSharedLibs.cmake
index 14dd67f32f..14dd67f32f 100644..100755
--- a/indra/cmake/LLSharedLibs.cmake
+++ b/indra/cmake/LLSharedLibs.cmake
diff --git a/indra/cmake/LLTestCommand.cmake b/indra/cmake/LLTestCommand.cmake
index b5a0580a90..f75c23a5de 100644..100755
--- a/indra/cmake/LLTestCommand.cmake
+++ b/indra/cmake/LLTestCommand.cmake
@@ -9,6 +9,9 @@ MACRO(LL_TEST_COMMAND OUTVAR LD_LIBRARY_PATH)
FOREACH(dir ${LD_LIBRARY_PATH})
LIST(APPEND value "-l${dir}")
ENDFOREACH(dir)
+ # Enough different tests want to be able to find CMake's PYTHON_EXECUTABLE
+ # that we should just pop it into the environment for everybody.
+ LIST(APPEND value "-DPYTHON=${PYTHON_EXECUTABLE}")
LIST(APPEND value ${ARGN})
SET(${OUTVAR} ${value})
##IF(LL_TEST_VERBOSE)
diff --git a/indra/cmake/LLUI.cmake b/indra/cmake/LLUI.cmake
index 34de57108b..34de57108b 100644..100755
--- a/indra/cmake/LLUI.cmake
+++ b/indra/cmake/LLUI.cmake
diff --git a/indra/cmake/LLVFS.cmake b/indra/cmake/LLVFS.cmake
index 0fe87cdea6..0fe87cdea6 100644..100755
--- a/indra/cmake/LLVFS.cmake
+++ b/indra/cmake/LLVFS.cmake
diff --git a/indra/cmake/LLWindow.cmake b/indra/cmake/LLWindow.cmake
index b4bb9a078a..ad732ef650 100644..100755
--- a/indra/cmake/LLWindow.cmake
+++ b/indra/cmake/LLWindow.cmake
@@ -1,6 +1,7 @@
# -*- cmake -*-
-include(OpenGL)
+include(Variables)
+include(GLEXT)
include(Prebuilt)
if (STANDALONE)
@@ -13,17 +14,15 @@ if (STANDALONE)
SDL_LIBRARY
)
else (STANDALONE)
- use_prebuilt_binary(mesa)
- if (LINUX AND VIEWER)
+ if (LINUX)
use_prebuilt_binary(SDL)
set (SDL_FOUND TRUE)
set (SDL_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/i686-linux)
set (SDL_LIBRARY SDL directfb fusion direct)
- endif (LINUX AND VIEWER)
+ endif (LINUX)
endif (STANDALONE)
if (SDL_FOUND)
- add_definitions(-DLL_SDL=1)
include_directories(${SDL_INCLUDE_DIR})
endif (SDL_FOUND)
@@ -32,12 +31,12 @@ set(LLWINDOW_INCLUDE_DIRS
${LIBS_OPEN_DIR}/llwindow
)
-if (SERVER AND LINUX)
- set(LLWINDOW_LIBRARIES
+if (BUILD_HEADLESS)
+ set(LLWINDOW_HEADLESS_LIBRARIES
llwindowheadless
)
-else (SERVER AND LINUX)
+endif (BUILD_HEADLESS)
+
set(LLWINDOW_LIBRARIES
llwindow
)
-endif (SERVER AND LINUX)
diff --git a/indra/cmake/LLXML.cmake b/indra/cmake/LLXML.cmake
index 64dfdb604f..b093c76297 100644..100755
--- a/indra/cmake/LLXML.cmake
+++ b/indra/cmake/LLXML.cmake
@@ -5,8 +5,10 @@ include(EXPAT)
set(LLXML_INCLUDE_DIRS
${LIBS_OPEN_DIR}/llxml
- ${Boost_INCLUDE_DIRS}
${EXPAT_INCLUDE_DIRS}
)
+set(LLXML_SYSTEM_INCLUDE_DIRS
+ ${Boost_INCLUDE_DIRS}
+ )
set(LLXML_LIBRARIES llxml)
diff --git a/indra/cmake/LLXUIXML.cmake b/indra/cmake/LLXUIXML.cmake
deleted file mode 100644
index b8bfe48c77..0000000000
--- a/indra/cmake/LLXUIXML.cmake
+++ /dev/null
@@ -1,7 +0,0 @@
-# -*- cmake -*-
-
-set(LLXUIXML_INCLUDE_DIRS
- ${LIBS_OPEN_DIR}/llxuixml
- )
-
-set(LLXUIXML_LIBRARIES llxuixml)
diff --git a/indra/cmake/LScript.cmake b/indra/cmake/LScript.cmake
index 21e78fc2c0..21e78fc2c0 100644..100755
--- a/indra/cmake/LScript.cmake
+++ b/indra/cmake/LScript.cmake
diff --git a/indra/cmake/Linking.cmake b/indra/cmake/Linking.cmake
index 47f944f9a5..b9c9e531fc 100644..100755
--- a/indra/cmake/Linking.cmake
+++ b/indra/cmake/Linking.cmake
@@ -1,5 +1,8 @@
# -*- cmake -*-
+if(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED)
+set(${CMAKE_CURRENT_LIST_FILE}_INCLUDED "YES")
+
include(Variables)
set(ARCH_PREBUILT_DIRS ${AUTOBUILD_INSTALL_DIR}/lib)
@@ -38,9 +41,8 @@ if (NOT "${CMAKE_BUILD_TYPE}" STREQUAL "Release")
# packages/lib/release directory to deal with autobuild packages that don't
# provide (e.g.) lib/debug libraries.
list(APPEND AUTOBUILD_LIBS_INSTALL_DIRS ${ARCH_PREBUILT_DIRS_RELEASE})
- message(STATUS "CMAKE_BUILD_TYPE = ${CMAKE_BUILD_TYPE}, extending AUTOBUILD_LIBS_INSTALL_DIRS")
endif (NOT "${CMAKE_BUILD_TYPE}" STREQUAL "Release")
-message(STATUS "For ${CMAKE_BUILD_TYPE}, AUTOBUILD_LIBS_INSTALL_DIRS: ${AUTOBUILD_LIBS_INSTALL_DIRS}")
+
link_directories(${AUTOBUILD_LIBS_INSTALL_DIRS})
if (LINUX)
@@ -70,3 +72,5 @@ else (WINDOWS)
endif (WINDOWS)
mark_as_advanced(DL_LIBRARY PTHREAD_LIBRARY WINDOWS_LIBRARIES)
+
+endif(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED)
diff --git a/indra/cmake/MediaPluginBase.cmake b/indra/cmake/MediaPluginBase.cmake
index 2be035b641..2be035b641 100644..100755
--- a/indra/cmake/MediaPluginBase.cmake
+++ b/indra/cmake/MediaPluginBase.cmake
diff --git a/indra/cmake/MonoDeps.cmake b/indra/cmake/MonoDeps.cmake
deleted file mode 100644
index 52d5491563..0000000000
--- a/indra/cmake/MonoDeps.cmake
+++ /dev/null
@@ -1,48 +0,0 @@
-# -*- cmake -*-
-
-set(MONO_PREBUILT_LIBRARIES_DIR ${LIBS_PREBUILT_DIR}/mono/1.0)
-
-set(MONO_PREBUILT_LIBRARIES
- Iesi.Collections.dll
- Iesi.Collections.pdb
- Mono.CompilerServices.SymbolWriter.dll
- Mono.PEToolkit.dll
- Mono.PEToolkit.pdb
- Mono.Security.dll
- PEAPI.dll
- RAIL.dll
- RAIL.pdb
- )
-
- set(MONO_CORE_LIBRARIES
- System.dll
- System.Xml.dll
- mscorlib.dll)
-
-if(WINDOWS)
- set(MONO_DEPENDENCIES
- DomainCreator
- DomainRegister
- LslLibrary
- LslUserScript
- Script
- ScriptTypes
- TestFormat
- UserScript
- UThread
- UThreadInjector
- )
-else(WINDOWS)
- set(MONO_DEPENDENCIES
- DomainCreator_POST_BUILD
- DomainRegister_POST_BUILD
- LslLibrary_POST_BUILD
- LslUserScript_POST_BUILD
- Script_POST_BUILD
- ScriptTypes_POST_BUILD
- TestFormat_POST_BUILD
- UserScript_POST_BUILD
- UThread_POST_BUILD
- UThreadInjector_POST_BUILD
- )
-endif(WINDOWS)
diff --git a/indra/cmake/MonoEmbed.cmake b/indra/cmake/MonoEmbed.cmake
deleted file mode 100644
index 30890aed21..0000000000
--- a/indra/cmake/MonoEmbed.cmake
+++ /dev/null
@@ -1,57 +0,0 @@
-# -*- cmake -*-
-
-include(Prebuilt)
-use_prebuilt_binary(libmono)
-
-SET(GLIB_2_0 glib-2.0)
-
-if (WINDOWS)
- SET(MONO_LIB mono)
-else (WINDOWS)
- SET(MONO_LIB mono)
- SET(M_LIBRARIES m)
- SET(GTHREAD_2_0 gthread-2.0)
-endif(WINDOWS)
-
-
-IF (DARWIN)
-
- FIND_LIBRARY(MONO_LIBRARY NAMES Mono)
- # Find_file doesnt work as expected. Hardcode relative to Mono.framework.
- #FIND_FILE(GLIB_CONFIG glibconfig.h ${MONO_LIBRARY})
- #FIND_FILE(MONO_GLIB_LIBRARY glib.h ${MONO_LIBRARY})
- SET(MONO_GLIB_LIBRARY ${MONO_LIBRARY}/Headers/glib-2.0/)
- SET(GLIB_CONFIG ${MONO_LIBRARY}/Libraries/glib-2.0/include/)
- SET(MONO_LIB_DIRECTORY ${MONO_LIBRARY}/Libraries)
-
- IF (MONO_LIBRARY AND MONO_GLIB_LIBRARY AND GLIB_CONFIG)
- MESSAGE(STATUS "Found Mono for embedding")
- INCLUDE_DIRECTORIES(${MONO_GLIB_LIBRARY} ${GLIB_CONFIG})
- LINK_DIRECTORIES(${MONO_LIB_DIRECTORY})
- ELSE (MONO_LIBRARY AND MONO_GLIB_LIBRARY AND GLIB_CONFIG)
- MESSAGE(FATAL_ERROR "Mono not found for embedding")
- MESSAGE(${MONO_LIBRARY})
- MESSAGE(${MONO_GLIB_LIBRARY})
- MESSAGE(${GLIB_CONFIG})
- ENDIF (MONO_LIBRARY AND MONO_GLIB_LIBRARY AND GLIB_CONFIG)
-
-ELSE (DARWIN)
-
- SET(MONO_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include)
- SET(GLIB_2_0_PLATFORM_INCLUDE_DIR
- ${LIBS_PREBUILT_DIR}/include/glib-2.0)
- SET(GLIB_2_0_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/glib-2.0)
-
- INCLUDE_DIRECTORIES(
- ${MONO_INCLUDE_DIR}
- ${GLIB_2_0_PLATFORM_INCLUDE_DIR}
- ${GLIB_2_0_INCLUDE_DIR})
-
-ENDIF (DARWIN)
-
-SET(MONO_LIBRARIES
- ${MONO_LIB}
- ${M_LIBRARIES}
- ${GLIB_2_0}
- ${GTHREAD_2_0}
-)
diff --git a/indra/cmake/MySQL.cmake b/indra/cmake/MySQL.cmake
deleted file mode 100644
index 218482449d..0000000000
--- a/indra/cmake/MySQL.cmake
+++ /dev/null
@@ -1,26 +0,0 @@
-# -*- cmake -*-
-include(Linking)
-include(Prebuilt)
-
-use_prebuilt_binary(mysql)
-
-if (LINUX)
- if (WORD_SIZE EQUAL 32 OR DEBIAN_VERSION STREQUAL "3.1")
- set(MYSQL_LIBRARIES mysqlclient)
- set(MYSQL_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include)
- else (WORD_SIZE EQUAL 32 OR DEBIAN_VERSION STREQUAL "3.1")
- # Use the native MySQL library on a 64-bit system.
- set(MYSQL_FIND_QUIETLY ON)
- set(MYSQL_FIND_REQUIRED ON)
- include(FindMySQL)
- endif (WORD_SIZE EQUAL 32 OR DEBIAN_VERSION STREQUAL "3.1")
-elseif (WINDOWS)
- set(MYSQL_LIBRARIES mysqlclient)
- set(MYSQL_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include)
-elseif (DARWIN)
- set(MYSQL_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include)
- set(MYSQL_LIBRARIES
- optimized ${ARCH_PREBUILT_DIRS_RELEASE}/libmysqlclient.a
- debug ${ARCH_PREBUILT_DIRS_DEBUG}/libmysqlclient.a
- )
-endif (LINUX)
diff --git a/indra/cmake/NDOF.cmake b/indra/cmake/NDOF.cmake
index be6fe415f2..be6fe415f2 100644..100755
--- a/indra/cmake/NDOF.cmake
+++ b/indra/cmake/NDOF.cmake
diff --git a/indra/cmake/NVAPI.cmake b/indra/cmake/NVAPI.cmake
new file mode 100755
index 0000000000..105f442a30
--- /dev/null
+++ b/indra/cmake/NVAPI.cmake
@@ -0,0 +1,16 @@
+# -*- cmake -*-
+include(Prebuilt)
+
+set(NVAPI ON CACHE BOOL "Use NVAPI.")
+
+if (NVAPI)
+ if (WINDOWS)
+ use_prebuilt_binary(nvapi)
+ set(NVAPI_LIBRARY nvapi)
+ else (WINDOWS)
+ set(NVAPI_LIBRARY "")
+ endif (WINDOWS)
+else (NVAPI)
+ set(NVAPI_LIBRARY "")
+endif (NVAPI)
+
diff --git a/indra/cmake/OPENAL.cmake b/indra/cmake/OPENAL.cmake
index a3e1fb924e..a3e1fb924e 100644..100755
--- a/indra/cmake/OPENAL.cmake
+++ b/indra/cmake/OPENAL.cmake
diff --git a/indra/cmake/OpenGL.cmake b/indra/cmake/OpenGL.cmake
index 0a3dd976b4..2259c99293 100644..100755
--- a/indra/cmake/OpenGL.cmake
+++ b/indra/cmake/OpenGL.cmake
@@ -1,8 +1,12 @@
# -*- cmake -*-
+
+include(Variables)
include(Prebuilt)
-if (NOT STANDALONE)
- use_prebuilt_binary(glext)
- use_prebuilt_binary(glh_linear)
- set(GLEXT_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include)
-endif (NOT STANDALONE)
+if (BUILD_HEADLESS)
+ SET(OPENGL_glu_LIBRARY GLU)
+ SET(OPENGL_HEADLESS_LIBRARIES OSMesa16 dl GLU)
+endif (BUILD_HEADLESS)
+
+include(FindOpenGL)
+
diff --git a/indra/cmake/OpenJPEG.cmake b/indra/cmake/OpenJPEG.cmake
index fcc82c2f49..fcc82c2f49 100644..100755
--- a/indra/cmake/OpenJPEG.cmake
+++ b/indra/cmake/OpenJPEG.cmake
diff --git a/indra/cmake/OpenSSL.cmake b/indra/cmake/OpenSSL.cmake
index 2704912eb5..2704912eb5 100644..100755
--- a/indra/cmake/OpenSSL.cmake
+++ b/indra/cmake/OpenSSL.cmake
diff --git a/indra/cmake/PNG.cmake b/indra/cmake/PNG.cmake
index 913c575672..913c575672 100644..100755
--- a/indra/cmake/PNG.cmake
+++ b/indra/cmake/PNG.cmake
diff --git a/indra/cmake/PluginAPI.cmake b/indra/cmake/PluginAPI.cmake
index d1649e8248..d1649e8248 100644..100755
--- a/indra/cmake/PluginAPI.cmake
+++ b/indra/cmake/PluginAPI.cmake
diff --git a/indra/cmake/Prebuilt.cmake b/indra/cmake/Prebuilt.cmake
index dbb4dfc46c..ac0cbde253 100644..100755
--- a/indra/cmake/Prebuilt.cmake
+++ b/indra/cmake/Prebuilt.cmake
@@ -1,5 +1,8 @@
# -*- cmake -*-
+if(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED)
+set(${CMAKE_CURRENT_LIST_FILE}_INCLUDED "YES")
+
include(FindAutobuild)
if(INSTALL_PROPRIETARY)
include(FindSCP)
@@ -51,3 +54,5 @@ macro (use_prebuilt_binary _binary)
endif (NOT ${_binary}_installed EQUAL 0)
endif (NOT STANDALONE_${_binary})
endmacro (use_prebuilt_binary _binary)
+
+endif(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED)
diff --git a/indra/cmake/PulseAudio.cmake b/indra/cmake/PulseAudio.cmake
index 360a971058..360a971058 100644..100755
--- a/indra/cmake/PulseAudio.cmake
+++ b/indra/cmake/PulseAudio.cmake
diff --git a/indra/cmake/Python.cmake b/indra/cmake/Python.cmake
index 748c8c2bec..a81c9307fc 100644..100755
--- a/indra/cmake/Python.cmake
+++ b/indra/cmake/Python.cmake
@@ -23,7 +23,7 @@ if (WINDOWS)
elseif (EXISTS /etc/debian_version)
# On Debian and Ubuntu, avoid Python 2.4 if possible.
- find_program(PYTHON_EXECUTABLE python2.5 python2.3 python PATHS /usr/bin)
+ find_program(PYTHON_EXECUTABLE python PATHS /usr/bin)
if (PYTHON_EXECUTABLE)
set(PYTHONINTERP_FOUND ON)
diff --git a/indra/cmake/QuickTimePlugin.cmake b/indra/cmake/QuickTimePlugin.cmake
index 012f4e20d8..012f4e20d8 100644..100755
--- a/indra/cmake/QuickTimePlugin.cmake
+++ b/indra/cmake/QuickTimePlugin.cmake
diff --git a/indra/cmake/TemplateCheck.cmake b/indra/cmake/TemplateCheck.cmake
index 2fada2eda9..2fada2eda9 100644..100755
--- a/indra/cmake/TemplateCheck.cmake
+++ b/indra/cmake/TemplateCheck.cmake
diff --git a/indra/cmake/Tut.cmake b/indra/cmake/Tut.cmake
index 7488e9dcb0..7488e9dcb0 100644..100755
--- a/indra/cmake/Tut.cmake
+++ b/indra/cmake/Tut.cmake
diff --git a/indra/cmake/UI.cmake b/indra/cmake/UI.cmake
index 91e5258fb7..d0fd4df03a 100644..100755
--- a/indra/cmake/UI.cmake
+++ b/indra/cmake/UI.cmake
@@ -1,5 +1,6 @@
# -*- cmake -*-
include(Prebuilt)
+include(FreeType)
if (STANDALONE)
include(FindPkgConfig)
@@ -47,6 +48,7 @@ else (STANDALONE)
pangoft2-1.0
pangox-1.0
pangoxft-1.0
+ ${FREETYPE_LIBRARIES}
)
endif (LINUX)
diff --git a/indra/cmake/UnixInstall.cmake b/indra/cmake/UnixInstall.cmake
index 139be0a008..139be0a008 100644..100755
--- a/indra/cmake/UnixInstall.cmake
+++ b/indra/cmake/UnixInstall.cmake
diff --git a/indra/cmake/Variables.cmake b/indra/cmake/Variables.cmake
index 4cbf7aa043..22d0a7f0fe 100644..100755
--- a/indra/cmake/Variables.cmake
+++ b/indra/cmake/Variables.cmake
@@ -8,24 +8,20 @@
# DARWIN - Mac OS X
# LINUX - Linux
# WINDOWS - Windows
-#
-# What to build:
-#
-# VIEWER - viewer and other viewer-side components
-# SERVER - simulator and other server-side bits
# Relative and absolute paths to subtrees.
+if(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED)
+set(${CMAKE_CURRENT_LIST_FILE}_INCLUDED "YES")
+
if(NOT DEFINED COMMON_CMAKE_DIR)
set(COMMON_CMAKE_DIR "${CMAKE_SOURCE_DIR}/cmake")
endif(NOT DEFINED COMMON_CMAKE_DIR)
set(LIBS_CLOSED_PREFIX)
set(LIBS_OPEN_PREFIX)
-set(LIBS_SERVER_PREFIX)
set(SCRIPTS_PREFIX ../scripts)
-set(SERVER_PREFIX)
set(VIEWER_PREFIX)
set(INTEGRATION_TESTS_PREFIX)
set(LL_TESTS ON CACHE BOOL "Build and run unit and integration tests (disable for build timing runs to reduce variation")
@@ -43,9 +39,7 @@ else(LIBS_COMMON_DIR)
endif(LIBS_COMMON_DIR)
set(LIBS_OPEN_DIR ${LIBS_COMMON_DIR})
-set(LIBS_SERVER_DIR ${CMAKE_SOURCE_DIR}/${LIBS_SERVER_PREFIX})
set(SCRIPTS_DIR ${CMAKE_SOURCE_DIR}/${SCRIPTS_PREFIX})
-set(SERVER_DIR ${CMAKE_SOURCE_DIR}/${SERVER_PREFIX})
set(VIEWER_DIR ${CMAKE_SOURCE_DIR}/${VIEWER_PREFIX})
set(AUTOBUILD_INSTALL_DIR ${CMAKE_BINARY_DIR}/packages)
@@ -79,30 +73,81 @@ if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
# If someone has specified a word size, use that to determine the
# architecture. Otherwise, let the architecture specify the word size.
if (WORD_SIZE EQUAL 32)
+ #message(STATUS "WORD_SIZE is 32")
set(ARCH i686)
elseif (WORD_SIZE EQUAL 64)
+ #message(STATUS "WORD_SIZE is 64")
set(ARCH x86_64)
else (WORD_SIZE EQUAL 32)
+ #message(STATUS "WORD_SIZE is UNDEFINED")
execute_process(COMMAND uname -m COMMAND sed s/i.86/i686/
OUTPUT_VARIABLE ARCH OUTPUT_STRIP_TRAILING_WHITESPACE)
if (ARCH STREQUAL x86_64)
+ #message(STATUS "ARCH is detected as 64; ARCH is ${ARCH}")
set(WORD_SIZE 64)
else (ARCH STREQUAL x86_64)
+ #message(STATUS "ARCH is detected as 32; ARCH is ${ARCH}")
set(WORD_SIZE 32)
endif (ARCH STREQUAL x86_64)
endif (WORD_SIZE EQUAL 32)
+ if (WORD_SIZE EQUAL 32)
+ set(DEB_ARCHITECTURE i386)
+ set(FIND_LIBRARY_USE_LIB64_PATHS OFF)
+ set(CMAKE_SYSTEM_LIBRARY_PATH /usr/lib32 ${CMAKE_SYSTEM_LIBRARY_PATH})
+ else (WORD_SIZE EQUAL 32)
+ set(DEB_ARCHITECTURE amd64)
+ set(FIND_LIBRARY_USE_LIB64_PATHS ON)
+ endif (WORD_SIZE EQUAL 32)
+
+ execute_process(COMMAND dpkg-architecture -a${DEB_ARCHITECTURE} -qDEB_HOST_MULTIARCH
+ RESULT_VARIABLE DPKG_RESULT
+ OUTPUT_VARIABLE DPKG_ARCH
+ OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET)
+ #message (STATUS "DPKG_RESULT ${DPKG_RESULT}, DPKG_ARCH ${DPKG_ARCH}")
+ if (DPKG_RESULT EQUAL 0)
+ set(CMAKE_LIBRARY_ARCHITECTURE ${DPKG_ARCH})
+ set(CMAKE_SYSTEM_LIBRARY_PATH /usr/lib/${DPKG_ARCH} /usr/local/lib/${DPKG_ARCH} ${CMAKE_SYSTEM_LIBRARY_PATH})
+ endif (DPKG_RESULT EQUAL 0)
+
+ include(ConfigurePkgConfig)
+
set(LL_ARCH ${ARCH}_linux)
set(LL_ARCH_DIR ${ARCH}-linux)
+
+ if (INSTALL_PROPRIETARY)
+ # Only turn on headless if we can find osmesa libraries.
+ include(FindPkgConfig)
+ #pkg_check_modules(OSMESA osmesa)
+ #if (OSMESA_FOUND)
+ # set(BUILD_HEADLESS ON CACHE BOOL "Build headless libraries.")
+ #endif (OSMESA_FOUND)
+ endif (INSTALL_PROPRIETARY)
+
endif (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
set(DARWIN 1)
+ execute_process(
+ COMMAND sh -c "xcodebuild -version | grep Xcode | cut -d ' ' -f2 | cut -d'.' -f1-2"
+ OUTPUT_VARIABLE XCODE_VERSION )
+
# To support a different SDK update these Xcode settings:
- set(CMAKE_OSX_DEPLOYMENT_TARGET 10.5)
- set(CMAKE_OSX_SYSROOT /Developer/SDKs/MacOSX10.5.sdk)
- set(CMAKE_XCODE_ATTRIBUTE_GCC_VERSION "4.0")
+ if (XCODE_VERSION GREATER 4.5)
+ set(CMAKE_OSX_DEPLOYMENT_TARGET 10.8)
+ set(CMAKE_OSX_SYSROOT macosx10.8)
+ else (XCODE_VERSION GREATER 4.5)
+ if (XCODE_VERSION GREATER 4.2)
+ set(CMAKE_OSX_DEPLOYMENT_TARGET 10.6)
+ set(CMAKE_OSX_SYSROOT macosx10.7)
+ else (XCODE_VERSION GREATER 4.2)
+ set(CMAKE_OSX_DEPLOYMENT_TARGET 10.6)
+ set(CMAKE_OSX_SYSROOT macosx10.7)
+ endif (XCODE_VERSION GREATER 4.2)
+ endif (XCODE_VERSION GREATER 4.5)
+
+ set(CMAKE_XCODE_ATTRIBUTE_GCC_VERSION "com.apple.compilers.llvmgcc42")
set(CMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT dwarf-with-dsym)
# NOTE: To attempt an i386/PPC Universal build, add this on the configure line:
@@ -130,29 +175,19 @@ endif (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
# Default deploy grid
set(GRID agni CACHE STRING "Target Grid")
-set(VIEWER ON CACHE BOOL "Build Second Life viewer.")
-set(VIEWER_CHANNEL "LindenDeveloper" CACHE STRING "Viewer Channel Name")
-set(VIEWER_LOGIN_CHANNEL ${VIEWER_CHANNEL} CACHE STRING "Fake login channel for A/B Testing")
+set(VIEWER_CHANNEL "Second Life Test" CACHE STRING "Viewer Channel Name")
+
+if (XCODE_VERSION GREATER 4.2)
+ set(ENABLE_SIGNING OFF CACHE BOOL "Enable signing the viewer")
+ set(SIGNING_IDENTITY "" CACHE STRING "Specifies the signing identity to use, if necessary.")
+endif (XCODE_VERSION GREATER 4.2)
set(VERSION_BUILD "0" CACHE STRING "Revision number passed in from the outside")
set(STANDALONE OFF CACHE BOOL "Do not use Linden-supplied prebuilt libraries.")
set(UNATTENDED OFF CACHE BOOL "Should be set to ON for building with VC Express editions.")
-if (NOT STANDALONE AND EXISTS ${CMAKE_SOURCE_DIR}/llphysics)
- set(SERVER ON CACHE BOOL "Build Second Life server software.")
-endif (NOT STANDALONE AND EXISTS ${CMAKE_SOURCE_DIR}/llphysics)
-
-if (LINUX AND SERVER AND VIEWER)
- MESSAGE(FATAL_ERROR "
-The indra source does not currently support building SERVER and VIEWER at the same time.
-Please set one of these values to OFF in your CMake cache file.
-(either by running ccmake or by editing CMakeCache.txt by hand)
-For more information, please see JIRA DEV-14943 - Cmake Linux cannot build both VIEWER and SERVER in one build environment
- ")
-endif (LINUX AND SERVER AND VIEWER)
-
-
set(USE_PRECOMPILED_HEADERS ON CACHE BOOL "Enable use of precompiled header directives where supported.")
source_group("CMake Rules" FILES CMakeLists.txt)
+endif(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED)
diff --git a/indra/cmake/ViewerMiscLibs.cmake b/indra/cmake/ViewerMiscLibs.cmake
index df013b1665..5b00c989a4 100644..100755
--- a/indra/cmake/ViewerMiscLibs.cmake
+++ b/indra/cmake/ViewerMiscLibs.cmake
@@ -2,15 +2,9 @@
include(Prebuilt)
if (NOT STANDALONE)
+ use_prebuilt_binary(libhunspell)
use_prebuilt_binary(libuuid)
use_prebuilt_binary(slvoice)
use_prebuilt_binary(fontconfig)
endif(NOT STANDALONE)
-if(VIEWER AND NOT STANDALONE)
- if(EXISTS ${CMAKE_SOURCE_DIR}/newview/res/have_artwork_bundle.marker)
- message(STATUS "We seem to have an artwork bundle in the tree - brilliant.")
- else(EXISTS ${CMAKE_SOURCE_DIR}/newview/res/have_artwork_bundle.marker)
- message(FATAL_ERROR "Didn't find an artwork bundle - this needs to be downloaded separately and unpacked into this tree. You can probably get it from the same place you got your viewer source. Thanks!")
- endif(EXISTS ${CMAKE_SOURCE_DIR}/newview/res/have_artwork_bundle.marker)
-endif(VIEWER AND NOT STANDALONE)
diff --git a/indra/cmake/VisualLeakDetector.cmake b/indra/cmake/VisualLeakDetector.cmake
index d3ba554e46..6a20148b47 100644..100755
--- a/indra/cmake/VisualLeakDetector.cmake
+++ b/indra/cmake/VisualLeakDetector.cmake
@@ -1,7 +1,5 @@
# -*- cmake -*-
-if (VIEWER)
-
set(INCLUDE_VLD_CMAKE OFF CACHE BOOL "Build the Windows viewer with Visual Leak Detector turned on or off")
if (INCLUDE_VLD_CMAKE)
@@ -12,4 +10,3 @@ if (VIEWER)
endif (INCLUDE_VLD_CMAKE)
-endif (VIEWER)
diff --git a/indra/cmake/WebKitLibPlugin.cmake b/indra/cmake/WebKitLibPlugin.cmake
index d9df78bfc8..d9df78bfc8 100644..100755
--- a/indra/cmake/WebKitLibPlugin.cmake
+++ b/indra/cmake/WebKitLibPlugin.cmake
diff --git a/indra/cmake/XmlRpcEpi.cmake b/indra/cmake/XmlRpcEpi.cmake
index 5bd4848245..5bd4848245 100644..100755
--- a/indra/cmake/XmlRpcEpi.cmake
+++ b/indra/cmake/XmlRpcEpi.cmake
diff --git a/indra/cmake/ZLIB.cmake b/indra/cmake/ZLIB.cmake
index 48e5130ad5..48e5130ad5 100644..100755
--- a/indra/cmake/ZLIB.cmake
+++ b/indra/cmake/ZLIB.cmake
diff --git a/indra/cmake/cmake_dummy.cpp b/indra/cmake/cmake_dummy.cpp
index ae4475a73e..ae4475a73e 100644..100755
--- a/indra/cmake/cmake_dummy.cpp
+++ b/indra/cmake/cmake_dummy.cpp
diff --git a/indra/cmake/run_build_test.py b/indra/cmake/run_build_test.py
index ce2d1e0386..a2ef61c8fd 100644..100755
--- a/indra/cmake/run_build_test.py
+++ b/indra/cmake/run_build_test.py
@@ -46,6 +46,7 @@ $/LicenseInfo$
import os
import sys
+import signal
import subprocess
def main(command, libpath=[], vars={}):
@@ -113,6 +114,33 @@ def main(command, libpath=[], vars={}):
sys.stdout.flush()
return subprocess.call(command)
+# swiped from vita, sigh, seems like a Bad Idea to introduce dependency
+def translate_rc(rc):
+ """
+ Accept an rc encoded as for subprocess.Popen.returncode:
+ None means still running
+ int >= 0 means terminated voluntarily with specified rc
+ int < 0 means terminated by signal (-rc)
+
+ Return a string explaining the outcome. In case of a signal, try to
+ name the corresponding symbol from the 'signal' module.
+ """
+ if rc is None:
+ return "still running"
+
+ if rc >= 0:
+ return "terminated with rc %s" % rc
+
+ # Negative rc means the child was terminated by signal -rc.
+ rc = -rc
+ for attr in dir(signal):
+ if attr.startswith('SIG') and getattr(signal, attr) == rc:
+ strc = attr
+ break
+ else:
+ strc = str(rc)
+ return "terminated by signal %s" % strc
+
if __name__ == "__main__":
from optparse import OptionParser
parser = OptionParser(usage="usage: %prog [options] command args...")
@@ -140,5 +168,5 @@ if __name__ == "__main__":
vars=dict([(pair.split('=', 1) + [""])[:2] for pair in opts.vars]))
if rc not in (None, 0):
print >>sys.stderr, "Failure running: %s" % " ".join(args)
- print >>sys.stderr, "Error: %s" % rc
+ print >>sys.stderr, "Error %s: %s" % (rc, translate_rc(rc))
sys.exit((rc < 0) and 255 or rc)
diff --git a/indra/copy_win_scripts/CMakeLists.txt b/indra/copy_win_scripts/CMakeLists.txt
index 93a8c1d6d2..93a8c1d6d2 100644..100755
--- a/indra/copy_win_scripts/CMakeLists.txt
+++ b/indra/copy_win_scripts/CMakeLists.txt
diff --git a/indra/copy_win_scripts/start-client.py b/indra/copy_win_scripts/start-client.py
index 5699f5273f..5699f5273f 100644..100755
--- a/indra/copy_win_scripts/start-client.py
+++ b/indra/copy_win_scripts/start-client.py
diff --git a/indra/edit-me-to-trigger-new-build.txt b/indra/edit-me-to-trigger-new-build.txt
index e69de29bb2..774e8c0676 100644..100755
--- a/indra/edit-me-to-trigger-new-build.txt
+++ b/indra/edit-me-to-trigger-new-build.txt
@@ -0,0 +1,6 @@
+Wed Nov 7 00:25:19 UTC 2012
+
+
+
+
+
diff --git a/indra/fix-incredibuild.py b/indra/fix-incredibuild.py
index 98f16e9d97..98f16e9d97 100644..100755
--- a/indra/fix-incredibuild.py
+++ b/indra/fix-incredibuild.py
diff --git a/indra/integration_tests/CMakeLists.txt b/indra/integration_tests/CMakeLists.txt
index ced2b3dbcf..ced2b3dbcf 100644..100755
--- a/indra/integration_tests/CMakeLists.txt
+++ b/indra/integration_tests/CMakeLists.txt
diff --git a/indra/integration_tests/llimage_libtest/CMakeLists.txt b/indra/integration_tests/llimage_libtest/CMakeLists.txt
index af5c9fb2e7..36a7d38bb7 100644..100755
--- a/indra/integration_tests/llimage_libtest/CMakeLists.txt
+++ b/indra/integration_tests/llimage_libtest/CMakeLists.txt
@@ -16,6 +16,9 @@ include_directories(
${LLVFS_INCLUDE_DIRS}
${LLIMAGE_INCLUDE_DIRS}
)
+include_directories(SYSTEM
+ ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+ )
set(llimage_libtest_SOURCE_FILES
llimage_libtest.cpp
diff --git a/indra/integration_tests/llimage_libtest/llimage_libtest.cpp b/indra/integration_tests/llimage_libtest/llimage_libtest.cpp
index 48e876429d..034c816742 100644..100755
--- a/indra/integration_tests/llimage_libtest/llimage_libtest.cpp
+++ b/indra/integration_tests/llimage_libtest/llimage_libtest.cpp
@@ -54,6 +54,11 @@ static const char USAGE[] = "\n"
" -o, --output <file1 .. file2> OR <type>\n"
" List of image files to create (assumes same order as for input files)\n"
" OR 3 letters file type extension to convert each input file into.\n"
+" -load, --load_size <n>\n"
+" Portion of the input file to load, in bytes."
+" If (load == 0), it will load the whole file."
+" If (load == -1), it will load the size relevant to reach the requested discard level (see -d)."
+" Only valid for j2c images. Default is 0 (load whole file).\n"
" -r, --region <x0, y0, x1, y1>\n"
" Crop region applied to the input files in pixels.\n"
" Only used for j2c images. Default is no region cropping.\n"
@@ -104,22 +109,52 @@ void output_image_stats(LLPointer<LLImageFormatted> image, const std::string &fi
// Print out some statistical data on the image
std::cout << "Image stats for : " << filename << ", extension : " << image->getExtension() << std::endl;
- std::cout << " with : " << (int)(image->getWidth()) << ", height : " << (int)(image->getHeight()) << std::endl;
- std::cout << " comp : " << (int)(image->getComponents()) << ", levels : " << (int)(image->getDiscardLevel()) << std::endl;
- std::cout << " head : " << (int)(image->calcHeaderSize()) << ", data : " << (int)(image->getDataSize()) << std::endl;
+ std::cout << " with : " << (int)(image->getWidth()) << ", height : " << (int)(image->getHeight()) << std::endl;
+ std::cout << " comp : " << (int)(image->getComponents()) << ", levels : " << (int)(image->getLevels()) << std::endl;
+ std::cout << " head : " << (int)(image->calcHeaderSize()) << ", data : " << (int)(image->getDataSize()) << std::endl;
return;
}
// Load an image from file and return a raw (decompressed) instance of its data
-LLPointer<LLImageRaw> load_image(const std::string &src_filename, int discard_level, int* region, bool output_stats)
+LLPointer<LLImageRaw> load_image(const std::string &src_filename, int discard_level, int* region, int load_size, bool output_stats)
{
LLPointer<LLImageFormatted> image = create_image(src_filename);
- // This just loads the image file stream into a buffer. No decoding done.
- if (!image->load(src_filename))
+ // We support partial loading only for j2c images
+ if (image->getCodec() == IMG_CODEC_J2C)
{
- return NULL;
+ // Load the header
+ if (!image->load(src_filename, 600))
+ {
+ return NULL;
+ }
+ S32 h = ((LLImageJ2C*)(image.get()))->calcHeaderSize();
+ S32 d = (load_size > 0 ? ((LLImageJ2C*)(image.get()))->calcDiscardLevelBytes(load_size) : 0);
+ S8 r = ((LLImageJ2C*)(image.get()))->getRawDiscardLevel();
+ std::cout << "Merov debug : header = " << h << ", load_size = " << load_size << ", discard level = " << d << ", raw discard level = " << r << std::endl;
+ for (d = 0; d < MAX_DISCARD_LEVEL; d++)
+ {
+ S32 data_size = ((LLImageJ2C*)(image.get()))->calcDataSize(d);
+ std::cout << "Merov debug : discard_level = " << d << ", data_size = " << data_size << std::endl;
+ }
+ if (load_size < 0)
+ {
+ load_size = (discard_level != -1 ? ((LLImageJ2C*)(image.get()))->calcDataSize(discard_level) : 0);
+ }
+ // Load the requested byte range
+ if (!image->load(src_filename, load_size))
+ {
+ return NULL;
+ }
+ }
+ else
+ {
+ // This just loads the image file stream into a buffer. No decoding done.
+ if (!image->load(src_filename))
+ {
+ return NULL;
+ }
}
if( (image->getComponents() != 3) && (image->getComponents() != 4) )
@@ -205,7 +240,7 @@ void store_input_file(std::list<std::string> &input_filenames, const std::string
LLDirIterator iter(dir, name);
while (iter.next(next_name))
{
- std::string file_name = dir + gDirUtilp->getDirDelimiter() + next_name;
+ std::string file_name = gDirUtilp->add(dir, next_name);
input_filenames.push_back(file_name);
}
}
@@ -310,6 +345,7 @@ int main(int argc, char** argv)
bool image_stats = false;
int* region = NULL;
int discard_level = -1;
+ int load_size = 0;
int precincts_size = -1;
int blocks_size = -1;
int levels = 0;
@@ -396,6 +432,22 @@ int main(int argc, char** argv)
discard_level = llclamp(discard_level,0,5);
}
}
+ else if (!strcmp(argv[arg], "--load_size") || !strcmp(argv[arg], "-load"))
+ {
+ std::string value_str;
+ if ((arg + 1) < argc)
+ {
+ value_str = argv[arg+1];
+ }
+ if (((arg + 1) >= argc) || (value_str[0] == '-'))
+ {
+ std::cout << "No valid --load_size argument given, load_size ignored" << std::endl;
+ }
+ else
+ {
+ load_size = atoi(value_str.c_str());
+ }
+ }
else if (!strcmp(argv[arg], "--precincts") || !strcmp(argv[arg], "-p"))
{
std::string value_str;
@@ -510,7 +562,7 @@ int main(int argc, char** argv)
for (; in_file != in_end; ++in_file, ++out_file)
{
// Load file
- LLPointer<LLImageRaw> raw_image = load_image(*in_file, discard_level, region, image_stats);
+ LLPointer<LLImageRaw> raw_image = load_image(*in_file, discard_level, region, load_size, image_stats);
if (!raw_image)
{
std::cout << "Error: Image " << *in_file << " could not be loaded" << std::endl;
diff --git a/indra/integration_tests/llimage_libtest/llimage_libtest.h b/indra/integration_tests/llimage_libtest/llimage_libtest.h
index 63f3d46b50..63f3d46b50 100644..100755
--- a/indra/integration_tests/llimage_libtest/llimage_libtest.h
+++ b/indra/integration_tests/llimage_libtest/llimage_libtest.h
diff --git a/indra/integration_tests/llui_libtest/CMakeLists.txt b/indra/integration_tests/llui_libtest/CMakeLists.txt
index 1180460f4b..34e34c7e47 100644..100755
--- a/indra/integration_tests/llui_libtest/CMakeLists.txt
+++ b/indra/integration_tests/llui_libtest/CMakeLists.txt
@@ -18,7 +18,7 @@ include(LLWindow)
include(LLUI)
include(LLVFS) # ugh, needed for LLDir
include(LLXML)
-include(LLXUIXML)
+include(Hunspell)
include(Linking)
# include(Tut)
@@ -32,7 +32,11 @@ include_directories(
${LLVFS_INCLUDE_DIRS}
${LLWINDOW_INCLUDE_DIRS}
${LLXML_INCLUDE_DIRS}
- ${LLXUIXML_INCLUDE_DIRS}
+ ${LIBS_PREBUILD_DIR}/include/hunspell
+ )
+include_directories(SYSTEM
+ ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+ ${LLXML_SYSTEM_INCLUDE_DIRS}
)
set(llui_libtest_SOURCE_FILES
@@ -56,7 +60,8 @@ add_executable(llui_libtest ${llui_libtest_SOURCE_FILES})
# Link with OS-specific libraries for LLWindow dependency
if (DARWIN)
find_library(COCOA_LIBRARY Cocoa)
- set(OS_LIBRARIES ${COCOA_LIBRARY})
+ find_library(IOKIT_LIBRARY IOKit)
+ set(OS_LIBRARIES ${COCOA_LIBRARY} ${IOKIT_LIBRARY})
elseif (WINDOWS)
#ll_stack_trace needs this now...
list(APPEND WINDOWS_LIBRARIES dbghelp)
@@ -80,6 +85,7 @@ target_link_libraries(llui_libtest
${LLIMAGEJ2COJ_LIBRARIES}
${OS_LIBRARIES}
${GOOGLE_PERFTOOLS_LIBRARIES}
+ ${HUNSPELL_LIBRARY}
)
if (WINDOWS)
diff --git a/indra/integration_tests/llui_libtest/llui_libtest.cpp b/indra/integration_tests/llui_libtest/llui_libtest.cpp
index 217e26c3ca..38aa1bbeb2 100644..100755
--- a/indra/integration_tests/llui_libtest/llui_libtest.cpp
+++ b/indra/integration_tests/llui_libtest/llui_libtest.cpp
@@ -107,12 +107,6 @@ public:
};
TestImageProvider gTestImageProvider;
-static std::string get_xui_dir()
-{
- std::string delim = gDirUtilp->getDirDelimiter();
- return gDirUtilp->getSkinBaseDir() + delim + "default" + delim + "xui" + delim;
-}
-
void init_llui()
{
// Font lookup needs directory support
@@ -122,13 +116,12 @@ void init_llui()
const char* newview_path = "../../../newview";
#endif
gDirUtilp->initAppDirs("SecondLife", newview_path);
- gDirUtilp->setSkinFolder("default");
+ gDirUtilp->setSkinFolder("default", "en");
// colors are no longer stored in a LLControlGroup file
LLUIColorTable::instance().loadFromSettings();
- std::string config_filename = gDirUtilp->getExpandedFilename(
- LL_PATH_APP_SETTINGS, "settings.xml");
+ std::string config_filename = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "settings.xml");
gSavedSettings.loadFromFile(config_filename);
// See LLAppViewer::init()
@@ -143,9 +136,7 @@ void init_llui()
const bool no_register_widgets = false;
LLWidgetReg::initClass( no_register_widgets );
-
- // Unclear if this is needed
- LLUI::setupPaths();
+
// Otherwise we get translation warnings when setting up floaters
// (tooltips for buttons)
std::set<std::string> default_args;
@@ -157,7 +148,6 @@ void init_llui()
// otherwise it crashes.
LLFontGL::initClass(96.f, 1.f, 1.f,
gDirUtilp->getAppRODataDir(),
- LLUI::getXUIPaths(),
false ); // don't create gl textures
LLFloaterView::Params fvparams;
@@ -169,6 +159,14 @@ void init_llui()
gFloaterView = LLUICtrlFactory::create<LLFloaterView> (fvparams);
}
+/*==========================================================================*|
+static std::string get_xui_dir()
+{
+ std::string delim = gDirUtilp->getDirDelimiter();
+ return gDirUtilp->getSkinBaseDir() + delim + "default" + delim + "xui" + delim;
+}
+
+// buildFromFile() no longer supports generate-output-LLXMLNode
void export_test_floaters()
{
// Convert all test floaters to new XML format
@@ -191,7 +189,7 @@ void export_test_floaters()
floater->buildFromFile( filename,
// FALSE, // don't open floater
output_node);
- std::string out_filename = xui_dir + filename;
+ std::string out_filename = gDirUtilp->add(xui_dir, filename);
std::string::size_type extension_pos = out_filename.rfind(".xml");
out_filename.resize(extension_pos);
out_filename += "_new.xml";
@@ -203,6 +201,7 @@ void export_test_floaters()
fclose(floater_file);
}
}
+|*==========================================================================*/
int main(int argc, char** argv)
{
@@ -211,7 +210,7 @@ int main(int argc, char** argv)
init_llui();
- export_test_floaters();
+// export_test_floaters();
return 0;
}
diff --git a/indra/integration_tests/llui_libtest/llui_libtest.h b/indra/integration_tests/llui_libtest/llui_libtest.h
index d365ebb5e0..d365ebb5e0 100644..100755
--- a/indra/integration_tests/llui_libtest/llui_libtest.h
+++ b/indra/integration_tests/llui_libtest/llui_libtest.h
diff --git a/indra/integration_tests/llui_libtest/llwidgetreg.cpp b/indra/integration_tests/llui_libtest/llwidgetreg.cpp
index cbf6021119..cbf6021119 100644..100755
--- a/indra/integration_tests/llui_libtest/llwidgetreg.cpp
+++ b/indra/integration_tests/llui_libtest/llwidgetreg.cpp
diff --git a/indra/integration_tests/llui_libtest/llwidgetreg.h b/indra/integration_tests/llui_libtest/llwidgetreg.h
index 30b915eee2..30b915eee2 100644..100755
--- a/indra/integration_tests/llui_libtest/llwidgetreg.h
+++ b/indra/integration_tests/llui_libtest/llwidgetreg.h
diff --git a/indra/lib/python/indra/__init__.py b/indra/lib/python/indra/__init__.py
index 0c5053cf49..0c5053cf49 100644..100755
--- a/indra/lib/python/indra/__init__.py
+++ b/indra/lib/python/indra/__init__.py
diff --git a/indra/lib/python/indra/base/__init__.py b/indra/lib/python/indra/base/__init__.py
index 2904fd3380..2904fd3380 100644..100755
--- a/indra/lib/python/indra/base/__init__.py
+++ b/indra/lib/python/indra/base/__init__.py
diff --git a/indra/lib/python/indra/base/cllsd_test.py b/indra/lib/python/indra/base/cllsd_test.py
index 1f06898ffd..1f06898ffd 100644..100755
--- a/indra/lib/python/indra/base/cllsd_test.py
+++ b/indra/lib/python/indra/base/cllsd_test.py
diff --git a/indra/lib/python/indra/base/config.py b/indra/lib/python/indra/base/config.py
index adafa29b51..adafa29b51 100644..100755
--- a/indra/lib/python/indra/base/config.py
+++ b/indra/lib/python/indra/base/config.py
diff --git a/indra/lib/python/indra/base/llsd.py b/indra/lib/python/indra/base/llsd.py
index 4527b115f9..4527b115f9 100644..100755
--- a/indra/lib/python/indra/base/llsd.py
+++ b/indra/lib/python/indra/base/llsd.py
diff --git a/indra/lib/python/indra/base/lluuid.py b/indra/lib/python/indra/base/lluuid.py
index 369ae4e92f..369ae4e92f 100644..100755
--- a/indra/lib/python/indra/base/lluuid.py
+++ b/indra/lib/python/indra/base/lluuid.py
diff --git a/indra/lib/python/indra/base/metrics.py b/indra/lib/python/indra/base/metrics.py
index ff8380265f..ff8380265f 100644..100755
--- a/indra/lib/python/indra/base/metrics.py
+++ b/indra/lib/python/indra/base/metrics.py
diff --git a/indra/lib/python/indra/ipc/__init__.py b/indra/lib/python/indra/ipc/__init__.py
index 302bbf4a03..302bbf4a03 100644..100755
--- a/indra/lib/python/indra/ipc/__init__.py
+++ b/indra/lib/python/indra/ipc/__init__.py
diff --git a/indra/lib/python/indra/ipc/compatibility.py b/indra/lib/python/indra/ipc/compatibility.py
index b9045c22f3..b9045c22f3 100644..100755
--- a/indra/lib/python/indra/ipc/compatibility.py
+++ b/indra/lib/python/indra/ipc/compatibility.py
diff --git a/indra/lib/python/indra/ipc/httputil.py b/indra/lib/python/indra/ipc/httputil.py
index d53f34a771..d53f34a771 100644..100755
--- a/indra/lib/python/indra/ipc/httputil.py
+++ b/indra/lib/python/indra/ipc/httputil.py
diff --git a/indra/lib/python/indra/ipc/llmessage.py b/indra/lib/python/indra/ipc/llmessage.py
index 91fb36b72c..91fb36b72c 100644..100755
--- a/indra/lib/python/indra/ipc/llmessage.py
+++ b/indra/lib/python/indra/ipc/llmessage.py
diff --git a/indra/lib/python/indra/ipc/llsdhttp.py b/indra/lib/python/indra/ipc/llsdhttp.py
index cbe8ee1eca..cbe8ee1eca 100644..100755
--- a/indra/lib/python/indra/ipc/llsdhttp.py
+++ b/indra/lib/python/indra/ipc/llsdhttp.py
diff --git a/indra/lib/python/indra/ipc/mysql_pool.py b/indra/lib/python/indra/ipc/mysql_pool.py
index e5855a3091..e5855a3091 100644..100755
--- a/indra/lib/python/indra/ipc/mysql_pool.py
+++ b/indra/lib/python/indra/ipc/mysql_pool.py
diff --git a/indra/lib/python/indra/ipc/russ.py b/indra/lib/python/indra/ipc/russ.py
index ac780f128b..ac780f128b 100644..100755
--- a/indra/lib/python/indra/ipc/russ.py
+++ b/indra/lib/python/indra/ipc/russ.py
diff --git a/indra/lib/python/indra/ipc/servicebuilder.py b/indra/lib/python/indra/ipc/servicebuilder.py
index 0a0ce2b4e2..0a0ce2b4e2 100644..100755
--- a/indra/lib/python/indra/ipc/servicebuilder.py
+++ b/indra/lib/python/indra/ipc/servicebuilder.py
diff --git a/indra/lib/python/indra/ipc/siesta.py b/indra/lib/python/indra/ipc/siesta.py
index d867e71537..d867e71537 100644..100755
--- a/indra/lib/python/indra/ipc/siesta.py
+++ b/indra/lib/python/indra/ipc/siesta.py
diff --git a/indra/lib/python/indra/ipc/siesta_test.py b/indra/lib/python/indra/ipc/siesta_test.py
index a35eed2460..a35eed2460 100644..100755
--- a/indra/lib/python/indra/ipc/siesta_test.py
+++ b/indra/lib/python/indra/ipc/siesta_test.py
diff --git a/indra/lib/python/indra/ipc/tokenstream.py b/indra/lib/python/indra/ipc/tokenstream.py
index b96f26d3ff..b96f26d3ff 100644..100755
--- a/indra/lib/python/indra/ipc/tokenstream.py
+++ b/indra/lib/python/indra/ipc/tokenstream.py
diff --git a/indra/lib/python/indra/ipc/webdav.py b/indra/lib/python/indra/ipc/webdav.py
index 98b8499b6a..98b8499b6a 100644..100755
--- a/indra/lib/python/indra/ipc/webdav.py
+++ b/indra/lib/python/indra/ipc/webdav.py
diff --git a/indra/lib/python/indra/ipc/xml_rpc.py b/indra/lib/python/indra/ipc/xml_rpc.py
index 47536c10c3..47536c10c3 100644..100755
--- a/indra/lib/python/indra/ipc/xml_rpc.py
+++ b/indra/lib/python/indra/ipc/xml_rpc.py
diff --git a/indra/lib/python/indra/util/__init__.py b/indra/lib/python/indra/util/__init__.py
index b004e5804f..b004e5804f 100644..100755
--- a/indra/lib/python/indra/util/__init__.py
+++ b/indra/lib/python/indra/util/__init__.py
diff --git a/indra/lib/python/indra/util/fastest_elementtree.py b/indra/lib/python/indra/util/fastest_elementtree.py
index 4fcf662dd9..4fcf662dd9 100644..100755
--- a/indra/lib/python/indra/util/fastest_elementtree.py
+++ b/indra/lib/python/indra/util/fastest_elementtree.py
diff --git a/indra/lib/python/indra/util/helpformatter.py b/indra/lib/python/indra/util/helpformatter.py
index ba5c9b67d1..ba5c9b67d1 100644..100755
--- a/indra/lib/python/indra/util/helpformatter.py
+++ b/indra/lib/python/indra/util/helpformatter.py
diff --git a/indra/lib/python/indra/util/iterators.py b/indra/lib/python/indra/util/iterators.py
index 9013fa6303..9013fa6303 100644..100755
--- a/indra/lib/python/indra/util/iterators.py
+++ b/indra/lib/python/indra/util/iterators.py
diff --git a/indra/lib/python/indra/util/llmanifest.py b/indra/lib/python/indra/util/llmanifest.py
index c33a03034a..52b4acbc94 100644..100755
--- a/indra/lib/python/indra/util/llmanifest.py
+++ b/indra/lib/python/indra/util/llmanifest.py
@@ -41,6 +41,14 @@ import tarfile
import errno
import subprocess
+class ManifestError(RuntimeError):
+ """Use an exception more specific than generic Python RuntimeError"""
+ pass
+
+class MissingError(ManifestError):
+ """You specified a file that doesn't exist"""
+ pass
+
def path_ancestors(path):
drive, path = os.path.splitdrive(os.path.normpath(path))
result = []
@@ -76,30 +84,8 @@ def get_default_platform(dummy):
'darwin':'darwin'
}[sys.platform]
-def get_default_version(srctree):
- # look up llversion.h and parse out the version info
- paths = [os.path.join(srctree, x, 'llversionviewer.h') for x in ['llcommon', '../llcommon', '../../indra/llcommon.h']]
- for p in paths:
- if os.path.exists(p):
- contents = open(p, 'r').read()
- major = re.search("LL_VERSION_MAJOR\s=\s([0-9]+)", contents).group(1)
- minor = re.search("LL_VERSION_MINOR\s=\s([0-9]+)", contents).group(1)
- patch = re.search("LL_VERSION_PATCH\s=\s([0-9]+)", contents).group(1)
- build = re.search("LL_VERSION_BUILD\s=\s([0-9]+)", contents).group(1)
- return major, minor, patch, build
-
-def get_channel(srctree):
- # look up llversionserver.h and parse out the version info
- paths = [os.path.join(srctree, x, 'llversionviewer.h') for x in ['llcommon', '../llcommon', '../../indra/llcommon.h']]
- for p in paths:
- if os.path.exists(p):
- contents = open(p, 'r').read()
- channel = re.search("LL_CHANNEL\s=\s\"(.+)\";\s*$", contents, flags = re.M).group(1)
- return channel
-
-
DEFAULT_SRCTREE = os.path.dirname(sys.argv[0])
-DEFAULT_CHANNEL = 'Second Life Release'
+RELEASE_CHANNEL = 'Second Life Release'
ARGUMENTS=[
dict(name='actions',
@@ -132,10 +118,7 @@ ARGUMENTS=[
default=""),
dict(name='channel',
description="""The channel to use for updates, packaging, settings name, etc.""",
- default=get_channel),
- dict(name='login_channel',
- description="""The channel to use for login handshake/updates only.""",
- default=None),
+ default='CHANNEL UNSET'),
dict(name='installer_name',
description=""" The name of the file that the installer should be
packaged up into. Only used on Linux at the moment.""",
@@ -156,10 +139,13 @@ ARGUMENTS=[
contain the name of the final package in a form suitable
for use by a .bat file.""",
default=None),
- dict(name='version',
- description="""This specifies the version of Second Life that is
- being packaged up.""",
- default=get_default_version)
+ dict(name='versionfile',
+ description="""The name of a file containing the full version number."""),
+ dict(name='signature',
+ description="""This specifies an identity to sign the viewer with, if any.
+ If no value is supplied, the default signature will be used, if any. Currently
+ only used on Mac OS X.""",
+ default=None)
]
def usage(srctree=""):
@@ -180,6 +166,9 @@ def usage(srctree=""):
arg['description'] % nd)
def main():
+## import itertools
+## print ' '.join((("'%s'" % item) if ' ' in item else item)
+## for item in itertools.chain([sys.executable], sys.argv))
option_names = [arg['name'] + '=' for arg in ARGUMENTS]
option_names.append('help')
options, remainder = getopt.getopt(sys.argv[1:], "", option_names)
@@ -216,9 +205,14 @@ def main():
args[arg['name']] = default
# fix up version
- if isinstance(args.get('version'), str):
- args['version'] = args['version'].split('.')
-
+ if isinstance(args.get('versionfile'), str):
+ try: # read in the version string
+ vf = open(args['versionfile'], 'r')
+ args['version'] = vf.read().strip().split('.')
+ except:
+ print "Unable to read versionfile '%s'" % args['versionfile']
+ raise
+
# default and agni are default
if args['grid'] in ['default', 'agni']:
args['grid'] = ''
@@ -230,15 +224,98 @@ def main():
for opt in args:
print "Option:", opt, "=", args[opt]
+ # pass in sourceid as an argument now instead of an environment variable
+ try:
+ args['sourceid'] = os.environ["sourceid"]
+ except KeyError:
+ args['sourceid'] = ""
+
+ # Build base package.
+ touch = args.get('touch')
+ if touch:
+ print 'Creating base package'
+ args['package_id'] = "" # base package has no package ID
wm = LLManifest.for_platform(args['platform'], args.get('arch'))(args)
wm.do(*args['actions'])
-
+ # Store package file for later if making touched file.
+ base_package_file = ""
+ if touch:
+ print 'Created base package ', wm.package_file
+ base_package_file = "" + wm.package_file
+
+ # handle multiple packages if set
+ try:
+ additional_packages = os.environ["additional_packages"]
+ except KeyError:
+ additional_packages = ""
+ if additional_packages:
+ # Determine destination prefix / suffix for additional packages.
+ base_dest_postfix = args['dest']
+ base_dest_prefix = ""
+ base_dest_parts = args['dest'].split(os.sep)
+ if len(base_dest_parts) > 1:
+ base_dest_postfix = base_dest_parts[len(base_dest_parts) - 1]
+ base_dest_prefix = base_dest_parts[0]
+ i = 1
+ while i < len(base_dest_parts) - 1:
+ base_dest_prefix = base_dest_prefix + os.sep + base_dest_parts[i]
+ i = i + 1
+ # Determine touched prefix / suffix for additional packages.
+ base_touch_postfix = ""
+ base_touch_prefix = ""
+ if touch:
+ base_touch_postfix = touch
+ base_touch_parts = touch.split('/')
+ if "arwin" in args['platform']:
+ if len(base_touch_parts) > 1:
+ base_touch_postfix = base_touch_parts[len(base_touch_parts) - 1]
+ base_touch_prefix = base_touch_parts[0]
+ i = 1
+ while i < len(base_touch_parts) - 1:
+ base_touch_prefix = base_touch_prefix + '/' + base_touch_parts[i]
+ i = i + 1
+ else:
+ if len(base_touch_parts) > 2:
+ base_touch_postfix = base_touch_parts[len(base_touch_parts) - 2] + '/' + base_touch_parts[len(base_touch_parts) - 1]
+ base_touch_prefix = base_touch_parts[0]
+ i = 1
+ while i < len(base_touch_parts) - 2:
+ base_touch_prefix = base_touch_prefix + '/' + base_touch_parts[i]
+ i = i + 1
+ # Store base channel name.
+ base_channel_name = args['channel']
+ # Build each additional package.
+ package_id_list = additional_packages.split(" ")
+ for package_id in package_id_list:
+ try:
+ args['package_id'] = package_id
+ args['channel'] = base_channel_name + os.environ[package_id + "_viewer_channel_suffix"]
+ if package_id + "_sourceid" in os.environ:
+ args['sourceid'] = os.environ[package_id + "_sourceid"]
+ else:
+ args['sourceid'] = ""
+ args['dest'] = base_dest_prefix + os.sep + package_id + os.sep + base_dest_postfix
+ except KeyError:
+ sys.stderr.write("Failed to create package for package_id: %s" % package_id)
+ sys.stderr.flush()
+ continue
+ if touch:
+ print 'Creating additional package for ', package_id, ' in ', args['dest']
+ wm = LLManifest.for_platform(args['platform'], args.get('arch'))(args)
+ wm.do(*args['actions'])
+ if touch:
+ print 'Created additional package ', wm.package_file, ' for ', package_id
+ faketouch = base_touch_prefix + '/' + package_id + '/' + base_touch_postfix
+ fp = open(faketouch, 'w')
+ fp.write('set package_file=%s\n' % wm.package_file)
+ fp.close()
+
# Write out the package file in this format, so that it can easily be called
# and used in a .bat file - yeah, it sucks, but this is the simplest...
touch = args.get('touch')
if touch:
fp = open(touch, 'w')
- fp.write('set package_file=%s\n' % wm.package_file)
+ fp.write('set package_file=%s\n' % base_package_file)
fp.close()
print 'touched', touch
return 0
@@ -275,7 +352,7 @@ class LLManifest(object):
def default_grid(self):
return self.args.get('grid', None) == ''
def default_channel(self):
- return self.args.get('channel', None) == DEFAULT_CHANNEL
+ return self.args.get('channel', None) == RELEASE_CHANNEL
def construct(self):
""" Meant to be overriden by LLManifest implementors with code that
@@ -385,7 +462,7 @@ class LLManifest(object):
child.stdout.close()
status = child.wait()
if status:
- raise RuntimeError(
+ raise ManifestError(
"Command %s returned non-zero status (%s) \noutput:\n%s"
% (command, status, output) )
return output
@@ -395,14 +472,24 @@ class LLManifest(object):
a) verify that you really have created it
b) schedule it for cleanup"""
if not os.path.exists(path):
- raise RuntimeError, "Should be something at path " + path
+ raise ManifestError, "Should be something at path " + path
self.created_paths.append(path)
- def put_in_file(self, contents, dst):
+ def put_in_file(self, contents, dst, src=None):
# write contents as dst
- f = open(self.dst_path_of(dst), "wb")
- f.write(contents)
- f.close()
+ dst_path = self.dst_path_of(dst)
+ f = open(dst_path, "wb")
+ try:
+ f.write(contents)
+ finally:
+ f.close()
+
+ # Why would we create a file in the destination tree if not to include
+ # it in the installer? The default src=None (plus the fact that the
+ # src param is last) is to preserve backwards compatibility.
+ if src:
+ self.file_list.append([src, dst_path])
+ return dst_path
def replace_in(self, src, dst=None, searchdict={}):
if dst == None:
@@ -550,7 +637,7 @@ class LLManifest(object):
except (IOError, os.error), why:
errors.append((srcname, dstname, why))
if errors:
- raise RuntimeError, errors
+ raise ManifestError, errors
def cmakedirs(self, path):
@@ -598,11 +685,10 @@ class LLManifest(object):
def check_file_exists(self, path):
if not os.path.exists(path) and not os.path.islink(path):
- raise RuntimeError("Path %s doesn't exist" % (
- os.path.normpath(os.path.join(os.getcwd(), path)),))
+ raise MissingError("Path %s doesn't exist" % (os.path.abspath(path),))
- wildcard_pattern = re.compile('\*')
+ wildcard_pattern = re.compile(r'\*')
def expand_globs(self, src, dst):
src_list = glob.glob(src)
src_re, d_template = self.wildcard_regex(src.replace('\\', '/'),
@@ -611,11 +697,28 @@ class LLManifest(object):
d = src_re.sub(d_template, s.replace('\\', '/'))
yield os.path.normpath(s), os.path.normpath(d)
+ def path2basename(self, path, file):
+ """
+ It is a common idiom to write:
+ self.path(os.path.join(somedir, somefile), somefile)
+
+ So instead you can write:
+ self.path2basename(somedir, somefile)
+
+ Note that this is NOT the same as:
+ self.path(os.path.join(somedir, somefile))
+
+ which is the same as:
+ temppath = os.path.join(somedir, somefile)
+ self.path(temppath, temppath)
+ """
+ return self.path(os.path.join(path, file), file)
+
def path(self, src, dst=None):
sys.stdout.write("Processing %s => %s ... " % (src, dst))
sys.stdout.flush()
if src == None:
- raise RuntimeError("No source file, dst is " + dst)
+ raise ManifestError("No source file, dst is " + dst)
if dst == None:
dst = src
dst = os.path.join(self.get_dst_prefix(), dst)
@@ -637,15 +740,29 @@ class LLManifest(object):
else:
count += self.process_file(src, dst)
return count
- try:
- count = try_path(os.path.join(self.get_src_prefix(), src))
- except RuntimeError:
+
+ for pfx in self.get_src_prefix(), self.get_artwork_prefix(), self.get_build_prefix():
try:
- count = try_path(os.path.join(self.get_artwork_prefix(), src))
- except RuntimeError:
- count = try_path(os.path.join(self.get_build_prefix(), src))
+ count = try_path(os.path.join(pfx, src))
+ except MissingError:
+ # If src isn't a wildcard, and if that file doesn't exist in
+ # this pfx, try next pfx.
+ count = 0
+ continue
+
+ # Here try_path() didn't raise MissingError. Did it process any files?
+ if count:
+ break
+ # Even though try_path() didn't raise MissingError, it returned 0
+ # files. src is probably a wildcard meant for some other pfx. Loop
+ # back to try the next.
+
print "%d files" % count
+ # Let caller check whether we processed as many files as expected. In
+ # particular, let caller notice 0.
+ return count
+
def do(self, *actions):
self.actions = actions
self.construct()
diff --git a/indra/lib/python/indra/util/llsubprocess.py b/indra/lib/python/indra/util/llsubprocess.py
index 7e0e115d14..7e0e115d14 100644..100755
--- a/indra/lib/python/indra/util/llsubprocess.py
+++ b/indra/lib/python/indra/util/llsubprocess.py
diff --git a/indra/lib/python/indra/util/llversion.py b/indra/lib/python/indra/util/llversion.py
deleted file mode 100644
index ba6f567b60..0000000000
--- a/indra/lib/python/indra/util/llversion.py
+++ /dev/null
@@ -1,107 +0,0 @@
-#!/usr/bin/env python
-"""\
-@file llversion.py
-@brief Parses llcommon/llversionserver.h and llcommon/llversionviewer.h
- for the version string and channel string.
- Parses hg info for branch and revision.
-
-$LicenseInfo:firstyear=2006&license=mit$
-
-Copyright (c) 2006-2009, Linden Research, Inc.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-$/LicenseInfo$
-"""
-
-import re, sys, os, subprocess
-
-# Methods for gathering version information from
-# llversionviewer.h and llversionserver.h
-
-def get_src_root():
- indra_lib_python_indra_path = os.path.dirname(__file__)
- return os.path.abspath(os.path.realpath(indra_lib_python_indra_path + "/../../../../../"))
-
-def get_version_file_contents(version_type):
- filepath = get_src_root() + '/indra/llcommon/llversion%s.h' % version_type
- file = open(filepath,"r")
- file_str = file.read()
- file.close()
- return file_str
-
-def get_version(version_type):
- file_str = get_version_file_contents(version_type)
- m = re.search('const S32 LL_VERSION_MAJOR = (\d+);', file_str)
- VER_MAJOR = m.group(1)
- m = re.search('const S32 LL_VERSION_MINOR = (\d+);', file_str)
- VER_MINOR = m.group(1)
- m = re.search('const S32 LL_VERSION_PATCH = (\d+);', file_str)
- VER_PATCH = m.group(1)
- m = re.search('const S32 LL_VERSION_BUILD = (\d+);', file_str)
- VER_BUILD = m.group(1)
- version = "%(VER_MAJOR)s.%(VER_MINOR)s.%(VER_PATCH)s.%(VER_BUILD)s" % locals()
- return version
-
-def get_channel(version_type):
- file_str = get_version_file_contents(version_type)
- m = re.search('const char \* const LL_CHANNEL = "(.+)";', file_str)
- return m.group(1)
-
-def get_viewer_version():
- return get_version('viewer')
-
-def get_server_version():
- return get_version('server')
-
-def get_viewer_channel():
- return get_channel('viewer')
-
-def get_server_channel():
- return get_channel('server')
-
-# Methods for gathering hg information
-def get_hg_repo():
- child = subprocess.Popen(["hg","showconfig","paths.default"], stdout=subprocess.PIPE)
- output, error = child.communicate()
- status = child.returncode
- if status:
- print >> sys.stderr, error
- sys.exit(1)
- if not output:
- print >> sys.stderr, 'ERROR: cannot find repo we cloned from'
- sys.exit(1)
- return output
-
-def get_hg_changeset():
- # The right thing to do would be to use the *global* revision id:
- # "hg id -i"
- # For the moment though, we use the parent revision:
- child = subprocess.Popen(["hg","parents","--template","{rev}"], stdout=subprocess.PIPE)
- output, error = child.communicate()
- status = child.returncode
- if status:
- print >> sys.stderr, error
- sys.exit(1)
- lines = output.splitlines()
- if len(lines) > 1:
- print >> sys.stderr, 'ERROR: working directory has %d parents' % len(lines)
- return lines[0]
-
-def using_hg():
- return os.path.isdir(os.path.join(get_src_root(), '.hg'))
diff --git a/indra/lib/python/indra/util/named_query.py b/indra/lib/python/indra/util/named_query.py
index 6bf956107d..6bf956107d 100644..100755
--- a/indra/lib/python/indra/util/named_query.py
+++ b/indra/lib/python/indra/util/named_query.py
diff --git a/indra/lib/python/indra/util/shutil2.py b/indra/lib/python/indra/util/shutil2.py
index 9e2e7a6ded..9e2e7a6ded 100644..100755
--- a/indra/lib/python/indra/util/shutil2.py
+++ b/indra/lib/python/indra/util/shutil2.py
diff --git a/indra/lib/python/indra/util/term.py b/indra/lib/python/indra/util/term.py
index 8c316a1f12..8c316a1f12 100644..100755
--- a/indra/lib/python/indra/util/term.py
+++ b/indra/lib/python/indra/util/term.py
diff --git a/indra/lib/python/indra/util/test_win32_manifest.py b/indra/lib/python/indra/util/test_win32_manifest.py
index 0532cb0065..0532cb0065 100644..100755
--- a/indra/lib/python/indra/util/test_win32_manifest.py
+++ b/indra/lib/python/indra/util/test_win32_manifest.py
diff --git a/indra/lib/python/uuid.py b/indra/lib/python/uuid.py
index e956383cca..e956383cca 100644..100755
--- a/indra/lib/python/uuid.py
+++ b/indra/lib/python/uuid.py
diff --git a/indra/linux_crash_logger/CMakeLists.txt b/indra/linux_crash_logger/CMakeLists.txt
index 98ebdc7487..c0fc1b2be0 100644..100755
--- a/indra/linux_crash_logger/CMakeLists.txt
+++ b/indra/linux_crash_logger/CMakeLists.txt
@@ -12,6 +12,7 @@ include(LLVFS)
include(LLXML)
include(Linking)
include(UI)
+include(FreeType)
include_directories(
${LLCOMMON_INCLUDE_DIRS}
@@ -19,6 +20,15 @@ include_directories(
${LLMATH_INCLUDE_DIRS}
${LLVFS_INCLUDE_DIRS}
${LLXML_INCLUDE_DIRS}
+ ${FREETYPE_INCLUDE_DIRS}
+ )
+include_directories(SYSTEM
+ ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+ ${LLXML_SYSTEM_INCLUDE_DIRS}
+ )
+include_directories(SYSTEM
+ ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+ ${LLXML_SYSTEM_INCLUDE_DIRS}
)
set(linux_crash_logger_SOURCE_FILES
@@ -53,6 +63,7 @@ target_link_libraries(linux-crash-logger
${LLCOMMON_LIBRARIES}
${UI_LIBRARIES}
${DB_LIBRARIES}
+ ${FREETYPE_LIBRARIES}
)
add_custom_target(linux-crash-logger-target ALL
diff --git a/indra/linux_crash_logger/linux_crash_logger.cpp b/indra/linux_crash_logger/linux_crash_logger.cpp
index 99d0ad7e14..99d0ad7e14 100644..100755
--- a/indra/linux_crash_logger/linux_crash_logger.cpp
+++ b/indra/linux_crash_logger/linux_crash_logger.cpp
diff --git a/indra/linux_crash_logger/llcrashloggerlinux.cpp b/indra/linux_crash_logger/llcrashloggerlinux.cpp
index 62465f9937..62465f9937 100644..100755
--- a/indra/linux_crash_logger/llcrashloggerlinux.cpp
+++ b/indra/linux_crash_logger/llcrashloggerlinux.cpp
diff --git a/indra/linux_crash_logger/llcrashloggerlinux.h b/indra/linux_crash_logger/llcrashloggerlinux.h
index dae6c46651..dae6c46651 100644..100755
--- a/indra/linux_crash_logger/llcrashloggerlinux.h
+++ b/indra/linux_crash_logger/llcrashloggerlinux.h
diff --git a/indra/linux_updater/CMakeLists.txt b/indra/linux_updater/CMakeLists.txt
index 00a78b2a8f..4a9e82f9b6 100644
--- a/indra/linux_updater/CMakeLists.txt
+++ b/indra/linux_updater/CMakeLists.txt
@@ -8,21 +8,26 @@ include(CARes)
include(OpenSSL)
include(UI)
include(LLCommon)
+include(LLMessage)
include(LLVFS)
include(LLXML)
-include(LLXUIXML)
+include(LLUI)
include(Linking)
include_directories(
${LLCOMMON_INCLUDE_DIRS}
${LLVFS_INCLUDE_DIRS}
${LLXML_INCLUDE_DIRS}
- ${LLXUIXML_INCLUDE_DIRS}
+ ${LLUI_INCLUDE_DIRS}
${CURL_INCLUDE_DIRS}
${CARES_INCLUDE_DIRS}
${OPENSSL_INCLUDE_DIRS}
${UI_INCLUDE_DIRS}
)
+include_directories(SYSTEM
+ ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+ ${LLXML_SYSTEM_INCLUDE_DIRS}
+ )
set(linux_updater_SOURCE_FILES linux_updater.cpp)
@@ -40,9 +45,10 @@ target_link_libraries(linux-updater
${CARES_LIBRARIES}
${OPENSSL_LIBRARIES}
${CRYPTO_LIBRARIES}
+ ${LLMESSAGE_LIBRARIES}
${UI_LIBRARIES}
${LLXML_LIBRARIES}
- ${LLXUIXML_LIBRARIES}
+ ${LLUI_LIBRARIES}
${LLVFS_LIBRARIES}
${LLCOMMON_LIBRARIES}
)
diff --git a/indra/linux_updater/linux_updater.cpp b/indra/linux_updater/linux_updater.cpp
index eed00ac06e..86fa596aef 100644
--- a/indra/linux_updater/linux_updater.cpp
+++ b/indra/linux_updater/linux_updater.cpp
@@ -1,4 +1,4 @@
-/**
+/**
* @file linux_updater.cpp
* @author Kyle Ambroff <ambroff@lindenlab.com>, Tofu Linden
* @brief Viewer update program for unix platforms that support GTK+
@@ -6,21 +6,21 @@
* $LicenseInfo:firstyear=2008&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$
*/
@@ -34,10 +34,30 @@
#include "llfile.h"
#include "lldir.h"
#include "lldiriterator.h"
+
+/*==========================================================================*|
+// IQA-490: Use of LLTrans -- by this program at least -- appears to be buggy.
+// With it, the 3.3.2 beta 1 linux-updater.bin crashes; without it seems stable.
#include "llxmlnode.h"
#include "lltrans.h"
+|*==========================================================================*/
+
+static class LLTrans
+{
+public:
+ LLTrans();
+ static std::string getString(const std::string& key);
+
+private:
+ std::string _getString(const std::string& key) const;
+
+ typedef std::map<std::string, std::string> MessageMap;
+ MessageMap mMessages;
+} sLLTransInstance;
#include <curl/curl.h>
+#include <map>
+#include <boost/foreach.hpp>
extern "C" {
#include <gtk/gtk.h>
@@ -85,6 +105,8 @@ void init_default_trans_args()
bool translate_init(std::string comma_delim_path_list,
std::string base_xml_name)
{
+ return true;
+/*==========================================================================*|
init_default_trans_args();
// extract paths string vector from comma-delimited flat string
@@ -112,6 +134,7 @@ bool translate_init(std::string comma_delim_path_list,
LLTrans::parseStrings(root, default_trans_args);
return true;
}
+|*==========================================================================*/
}
@@ -151,7 +174,7 @@ void updater_app_ui_init(UpdaterAppState *app_state)
GTK_WIN_POS_CENTER_ALWAYS);
gtk_container_set_border_width(GTK_CONTAINER(app_state->window), 12);
- g_signal_connect(G_OBJECT(app_state->window), "delete-event",
+ g_signal_connect(G_OBJECT(app_state->window), "delete-event",
G_CALLBACK(on_window_closed), app_state);
vbox = gtk_vbox_new(FALSE, 6);
@@ -165,7 +188,7 @@ void updater_app_ui_init(UpdaterAppState *app_state)
summary_label = gtk_label_new(NULL);
gtk_label_set_use_markup(GTK_LABEL(summary_label), TRUE);
- gtk_label_set_markup(GTK_LABEL(summary_label),
+ gtk_label_set_markup(GTK_LABEL(summary_label),
label_ostr.str().c_str());
gtk_misc_set_alignment(GTK_MISC(summary_label), 0, 0.5);
gtk_box_pack_start(GTK_BOX(vbox), summary_label, FALSE, FALSE, 0);
@@ -195,9 +218,9 @@ void updater_app_ui_init(UpdaterAppState *app_state)
// set up progress bar, and update it roughly every 1/10 of a second
app_state->progress_bar = gtk_progress_bar_new();
- gtk_progress_bar_set_text(GTK_PROGRESS_BAR(app_state->progress_bar),
+ gtk_progress_bar_set_text(GTK_PROGRESS_BAR(app_state->progress_bar),
LLTrans::getString("UpdaterProgressBarTextWithEllipses").c_str());
- gtk_box_pack_start(GTK_BOX(vbox),
+ gtk_box_pack_start(GTK_BOX(vbox),
app_state->progress_bar, FALSE, TRUE, 0);
app_state->progress_update_timeout_id = g_timeout_add
(UPDATE_PROGRESS_TIMEOUT, progress_update_timeout, app_state);
@@ -228,7 +251,7 @@ std::string next_image_filename(std::string& image_path, LLDirIterator& iter)
{
std::string image_filename;
iter.next(image_filename);
- return image_path + "/" + image_filename;
+ return gDirUtilp->add(image_path, image_filename);
}
void on_window_closed(GtkWidget *sender, GdkEvent* event, gpointer data)
@@ -299,7 +322,7 @@ gpointer worker_thread_cb(gpointer data)
g_error_free(error);
throw 0;
}
-
+
if(tmp_local_filename != NULL)
{
app_state->file = tmp_local_filename;
@@ -342,7 +365,7 @@ gpointer worker_thread_cb(gpointer data)
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, TRUE);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, package_file);
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, FALSE);
- curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION,
+ curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION,
&download_progress_cb);
curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, app_state);
@@ -352,8 +375,8 @@ gpointer worker_thread_cb(gpointer data)
if (result)
{
- llerrs << "Failed to download update: "
- << app_state->url
+ llerrs << "Failed to download update: "
+ << app_state->url
<< llendl;
gdk_threads_enter();
@@ -365,7 +388,7 @@ gpointer worker_thread_cb(gpointer data)
throw 0;
}
}
-
+
// now pulse the progres bar back and forth while the package is
// being unpacked
gdk_threads_enter();
@@ -386,8 +409,8 @@ gpointer worker_thread_cb(gpointer data)
gdk_threads_enter();
display_error(app_state->window,
- LLTrans::getString("UpdaterFailInstallTitle"),
- LLTrans::getString("UpdaterFailUpdateDescriptive"));
+ LLTrans::getString("UpdaterFailInstallTitle"),
+ LLTrans::getString("UpdaterFailUpdateDescriptive"));
//"Failed to update " + app_state->app_name,
gdk_threads_leave();
throw 0;
@@ -402,8 +425,8 @@ gpointer worker_thread_cb(gpointer data)
gdk_threads_enter();
display_error(app_state->window,
- LLTrans::getString("UpdaterFailStartTitle"),
- LLTrans::getString("UpdaterFailUpdateDescriptive"));
+ LLTrans::getString("UpdaterFailStartTitle"),
+ LLTrans::getString("UpdaterFailUpdateDescriptive"));
gdk_threads_leave();
throw 0;
}
@@ -448,7 +471,7 @@ gboolean less_anal_gspawnsync(gchar **argv,
// restore SIGCHLD handler
sigaction(SIGCHLD, &sigchld_backup, NULL);
-
+
return rtn;
}
@@ -477,7 +500,7 @@ rename_with_sudo_fallback(const std::string& filename, const std::string& newnam
{
char *src_string_copy = g_strdup(filename.c_str());
char *dst_string_copy = g_strdup(newname.c_str());
- char* argv[] =
+ char* argv[] =
{
sudo_cmd,
mv_cmd,
@@ -492,8 +515,8 @@ rename_with_sudo_fallback(const std::string& filename, const std::string& newnam
if (!less_anal_gspawnsync(argv, &stderr_output,
&child_exit_status, &spawn_error))
{
- llwarns << "Failed to spawn child process: "
- << spawn_error->message
+ llwarns << "Failed to spawn child process: "
+ << spawn_error->message
<< llendl;
}
else if (child_exit_status)
@@ -506,7 +529,7 @@ rename_with_sudo_fallback(const std::string& filename, const std::string& newnam
{
// everything looks good, clear the error code
rtncode = 0;
- }
+ }
g_free(src_string_copy);
g_free(dst_string_copy);
@@ -531,7 +554,7 @@ gboolean install_package(std::string package_file, std::string destination)
}
llinfos << "Found tar command: " << tar_cmd << llendl;
- // Unpack the tarball in a temporary place first, then move it to
+ // Unpack the tarball in a temporary place first, then move it to
// its final destination
std::string tmp_dest_dir = gDirUtilp->getTempFilename();
if (LLFile::mkdir(tmp_dest_dir, 0744))
@@ -571,8 +594,8 @@ gboolean install_package(std::string package_file, std::string destination)
if (!less_anal_gspawnsync(argv, &stderr_output,
&child_exit_status, &untar_error))
{
- llwarns << "Failed to spawn child process: "
- << untar_error->message
+ llwarns << "Failed to spawn child process: "
+ << untar_error->message
<< llendl;
return FALSE;
}
@@ -605,8 +628,8 @@ gboolean install_package(std::string package_file, std::string destination)
if (rename_with_sudo_fallback(destination, backup_dir))
{
- llwarns << "Failed to move directory: '"
- << destination << "' -> '" << backup_dir
+ llwarns << "Failed to move directory: '"
+ << destination << "' -> '" << backup_dir
<< llendl;
return FALSE;
}
@@ -617,7 +640,7 @@ gboolean install_package(std::string package_file, std::string destination)
if (rename_with_sudo_fallback(tmp_dest_dir, destination))
{
llwarns << "Failed to move installation to the destination: "
- << destination
+ << destination
<< llendl;
return FALSE;
}
@@ -713,7 +736,7 @@ BOOL spawn_viewer(UpdaterAppState *app_state)
if (!success)
{
- llwarns << "Failed to launch viewer: " << error->message
+ llwarns << "Failed to launch viewer: " << error->message
<< llendl;
}
@@ -751,7 +774,7 @@ void parse_args_and_init(int argc, char **argv, UpdaterAppState *app_state)
else if ((!strcmp(argv[i], "--image-dir")) && (++i < argc))
{
app_state->image_dir = argv[i];
- app_state->image_dir_iter = new LLDirIterator(argv[i], "/*.jpg");
+ app_state->image_dir_iter = new LLDirIterator(argv[i], "*.jpg");
}
else if ((!strcmp(argv[i], "--dest")) && (++i < argc))
{
@@ -772,8 +795,8 @@ void parse_args_and_init(int argc, char **argv, UpdaterAppState *app_state)
}
}
- if (app_state->app_name.empty()
- || (app_state->url.empty() && app_state->file.empty())
+ if (app_state->app_name.empty()
+ || (app_state->url.empty() && app_state->file.empty())
|| app_state->dest_dir.empty())
{
show_usage_and_exit();
@@ -789,7 +812,6 @@ void parse_args_and_init(int argc, char **argv, UpdaterAppState *app_state)
int main(int argc, char **argv)
{
UpdaterAppState* app_state = new UpdaterAppState;
- GThread *worker_thread;
parse_args_and_init(argc, argv, app_state);
@@ -799,7 +821,7 @@ int main(int argc, char **argv)
(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, ""));
std::string old_log_file = gDirUtilp->getExpandedFilename
(LL_PATH_LOGS, "updater.log.old");
- std::string log_file =
+ std::string log_file =
gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "updater.log");
LLFile::rename(log_file, old_log_file);
LLError::logToFile(log_file);
@@ -819,8 +841,7 @@ int main(int argc, char **argv)
//llinfos << "SAMPLE TRANSLATION IS: " << LLTrans::getString("LoginInProgress") << llendl;
// create download thread
- worker_thread = g_thread_create
- (GThreadFunc(worker_thread_cb), app_state, FALSE, NULL);
+ g_thread_create(GThreadFunc(worker_thread_cb), app_state, FALSE, NULL);
gdk_threads_enter();
gtk_main();
@@ -841,3 +862,63 @@ int main(int argc, char **argv)
return success ? 0 : 1;
}
+/*****************************************************************************
+* Dummy LLTrans implementation (IQA-490)
+*****************************************************************************/
+static LLTrans sStaticStrings;
+
+// lookup
+std::string LLTrans::_getString(const std::string& key) const
+{
+ MessageMap::const_iterator found = mMessages.find(key);
+ if (found != mMessages.end())
+ {
+ return found->second;
+ }
+ LL_WARNS("linux_updater") << "No message for key '" << key
+ << "' -- add to LLTrans::LLTrans() in linux_updater.cpp"
+ << LL_ENDL;
+ return key;
+}
+
+// static lookup
+std::string LLTrans::getString(const std::string& key)
+{
+ return sLLTransInstance._getString(key);
+}
+
+// initialization
+LLTrans::LLTrans()
+{
+ typedef std::pair<const char*, const char*> Pair;
+ static const Pair data[] =
+ {
+ Pair("UpdaterFailDownloadTitle",
+ "Failed to download update"),
+ Pair("UpdaterFailInstallTitle",
+ "Failed to install update"),
+ Pair("UpdaterFailStartTitle",
+ "Failed to start viewer"),
+ Pair("UpdaterFailUpdateDescriptive",
+ "An error occurred while updating Second Life. "
+ "Please download the latest version from www.secondlife.com."),
+ Pair("UpdaterNowInstalling",
+ "Installing Second Life..."),
+ Pair("UpdaterNowUpdating",
+ "Now updating Second Life..."),
+ Pair("UpdaterProgressBarText",
+ "Downloading update"),
+ Pair("UpdaterProgressBarTextWithEllipses",
+ "Downloading update..."),
+ Pair("UpdaterUpdatingDescriptive",
+ "Your Second Life Viewer is being updated to the latest release. "
+ "This may take some time, so please be patient."),
+ Pair("UpdaterWindowTitle",
+ "Second Life Update")
+ };
+
+ BOOST_FOREACH(Pair pair, data)
+ {
+ mMessages[pair.first] = pair.second;
+ }
+}
diff --git a/indra/llappearance/CMakeLists.txt b/indra/llappearance/CMakeLists.txt
new file mode 100644
index 0000000000..0dbd58b7cd
--- /dev/null
+++ b/indra/llappearance/CMakeLists.txt
@@ -0,0 +1,118 @@
+# -*- cmake -*-
+
+project(llappearance)
+
+include(00-Common)
+include(LLCommon)
+include(LLCharacter)
+include(LLImage)
+include(LLInventory)
+include(LLMath)
+include(LLMessage)
+include(LLRender)
+include(LLVFS)
+include(LLWindow)
+include(LLXML)
+include(Linking)
+
+include_directories(
+ ${LLCOMMON_INCLUDE_DIRS}
+ ${LLCHARACTER_INCLUDE_DIRS}
+ ${LLIMAGE_INCLUDE_DIRS}
+ ${LLINVENTORY_INCLUDE_DIRS}
+ ${LLMATH_INCLUDE_DIRS}
+ ${LLRENDER_INCLUDE_DIRS}
+ ${LLVFS_INCLUDE_DIRS}
+ ${LLWINDOW_INCLUDE_DIRS}
+ ${LLXML_INCLUDE_DIRS}
+ )
+
+set(llappearance_SOURCE_FILES
+ llavatarappearance.cpp
+ llavatarjoint.cpp
+ llavatarjointmesh.cpp
+ lldriverparam.cpp
+ lllocaltextureobject.cpp
+ llpolyskeletaldistortion.cpp
+ llpolymesh.cpp
+ llpolymorph.cpp
+ lltexglobalcolor.cpp
+ lltexlayer.cpp
+ lltexlayerparams.cpp
+ lltexturemanagerbridge.cpp
+ llwearable.cpp
+ llwearabledata.cpp
+ llwearabletype.cpp
+ llviewervisualparam.cpp
+ llavatarappearancedefines.cpp
+ )
+
+set(llappearance_HEADER_FILES
+ CMakeLists.txt
+
+ llavatarappearance.h
+ llavatarjoint.h
+ llavatarjointmesh.h
+ lldriverparam.h
+ lljointpickname.h
+ lllocaltextureobject.h
+ llpolyskeletaldistortion.h
+ llpolymesh.h
+ llpolymorph.h
+ lltexglobalcolor.h
+ lltexlayer.h
+ lltexlayerparams.h
+ lltexturemanagerbridge.h
+ llwearable.h
+ llwearabledata.h
+ llwearabletype.h
+ llviewervisualparam.h
+ llavatarappearancedefines.h
+ )
+
+set_source_files_properties(${llappearance_HEADER_FILES}
+ PROPERTIES HEADER_FILE_ONLY TRUE)
+
+list(APPEND llappearance_SOURCE_FILES ${llappearance_HEADER_FILES})
+
+add_library (llappearance ${llappearance_SOURCE_FILES})
+
+target_link_libraries(llappearance
+ ${LLCHARACTER_LIBRARIES}
+ ${LLINVENTORY_LIBRARIES}
+ ${LLIMAGE_LIBRARIES}
+ ${LLRENDER_LIBRARIES}
+ ${LLVFS_LIBRARIES}
+ ${LLMATH_LIBRARIES}
+ ${LLXML_LIBRARIES}
+ ${LLMATH_LIBRARIES}
+ ${LLCOMMON_LIBRARIES}
+ )
+
+if (BUILD_HEADLESS)
+ add_library (llappearanceheadless ${llappearance_SOURCE_FILES})
+
+ target_link_libraries(llappearanceheadless
+ ${LLCHARACTER_LIBRARIES}
+ ${LLINVENTORY_LIBRARIES}
+ ${LLIMAGE_LIBRARIES}
+ ${LLRENDERHEADLESS_LIBRARIES}
+ ${LLVFS_LIBRARIES}
+ ${LLMATH_LIBRARIES}
+ ${LLXML_LIBRARIES}
+ ${LLMATH_LIBRARIES}
+ ${LLCOMMON_LIBRARIES}
+ )
+endif (BUILD_HEADLESS)
+
+#add unit tests
+#if (LL_TESTS)
+# INCLUDE(LLAddBuildTest)
+# SET(llappearance_TEST_SOURCE_FILES
+# # no real unit tests yet!
+# )
+# LL_ADD_PROJECT_UNIT_TESTS(llappearance "${llappearance_TEST_SOURCE_FILES}")
+
+ #set(TEST_DEBUG on)
+# set(test_libs llappearance ${LLCOMMON_LIBRARIES})
+#endif (LL_TESTS)
diff --git a/indra/llappearance/llavatarappearance.cpp b/indra/llappearance/llavatarappearance.cpp
new file mode 100644
index 0000000000..3bb759d458
--- /dev/null
+++ b/indra/llappearance/llavatarappearance.cpp
@@ -0,0 +1,1953 @@
+/**
+ * @File llavatarappearance.cpp
+ * @brief Implementation of LLAvatarAppearance class
+ *
+ * $LicenseInfo:firstyear=2012&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$
+ */
+
+#if LL_MSVC
+// disable warning about boost::lexical_cast returning uninitialized data
+// when it fails to parse the string
+#pragma warning (disable:4701)
+#endif
+
+#include "linden_common.h"
+
+#include "llavatarappearance.h"
+#include "llavatarappearancedefines.h"
+#include "llavatarjointmesh.h"
+#include "imageids.h"
+#include "lldir.h"
+#include "lldeleteutils.h"
+#include "llpolymorph.h"
+#include "llpolymesh.h"
+#include "llpolyskeletaldistortion.h"
+#include "llstl.h"
+#include "lltexglobalcolor.h"
+#include "llwearabledata.h"
+
+
+#if LL_MSVC
+// disable boost::lexical_cast warning
+#pragma warning (disable:4702)
+#endif
+
+#include <boost/lexical_cast.hpp>
+
+using namespace LLAvatarAppearanceDefines;
+
+//-----------------------------------------------------------------------------
+// Constants
+//-----------------------------------------------------------------------------
+
+const std::string AVATAR_DEFAULT_CHAR = "avatar";
+const LLColor4 DUMMY_COLOR = LLColor4(0.5,0.5,0.5,1.0);
+
+/*********************************************************************************
+ ** **
+ ** Begin private LLAvatarAppearance Support classes
+ **
+ **/
+
+//------------------------------------------------------------------------
+// LLAvatarBoneInfo
+// Trans/Scale/Rot etc. info about each avatar bone. Used by LLVOAvatarSkeleton.
+//------------------------------------------------------------------------
+class LLAvatarBoneInfo
+{
+ friend class LLAvatarAppearance;
+ friend class LLAvatarSkeletonInfo;
+public:
+ LLAvatarBoneInfo() : mIsJoint(FALSE) {}
+ ~LLAvatarBoneInfo()
+ {
+ std::for_each(mChildList.begin(), mChildList.end(), DeletePointer());
+ }
+ BOOL parseXml(LLXmlTreeNode* node);
+
+private:
+ std::string mName;
+ BOOL mIsJoint;
+ LLVector3 mPos;
+ LLVector3 mRot;
+ LLVector3 mScale;
+ LLVector3 mPivot;
+ typedef std::vector<LLAvatarBoneInfo*> child_list_t;
+ child_list_t mChildList;
+};
+
+//------------------------------------------------------------------------
+// LLAvatarSkeletonInfo
+// Overall avatar skeleton
+//------------------------------------------------------------------------
+class LLAvatarSkeletonInfo
+{
+ friend class LLAvatarAppearance;
+public:
+ LLAvatarSkeletonInfo() :
+ mNumBones(0), mNumCollisionVolumes(0) {}
+ ~LLAvatarSkeletonInfo()
+ {
+ std::for_each(mBoneInfoList.begin(), mBoneInfoList.end(), DeletePointer());
+ }
+ BOOL parseXml(LLXmlTreeNode* node);
+ S32 getNumBones() const { return mNumBones; }
+ S32 getNumCollisionVolumes() const { return mNumCollisionVolumes; }
+
+private:
+ S32 mNumBones;
+ S32 mNumCollisionVolumes;
+ typedef std::vector<LLAvatarBoneInfo*> bone_info_list_t;
+ bone_info_list_t mBoneInfoList;
+};
+
+//-----------------------------------------------------------------------------
+// LLAvatarXmlInfo
+//-----------------------------------------------------------------------------
+
+LLAvatarAppearance::LLAvatarXmlInfo::LLAvatarXmlInfo()
+ : mTexSkinColorInfo(0), mTexHairColorInfo(0), mTexEyeColorInfo(0)
+{
+}
+
+LLAvatarAppearance::LLAvatarXmlInfo::~LLAvatarXmlInfo()
+{
+ std::for_each(mMeshInfoList.begin(), mMeshInfoList.end(), DeletePointer());
+ std::for_each(mSkeletalDistortionInfoList.begin(), mSkeletalDistortionInfoList.end(), DeletePointer());
+ std::for_each(mAttachmentInfoList.begin(), mAttachmentInfoList.end(), DeletePointer());
+ deleteAndClear(mTexSkinColorInfo);
+ deleteAndClear(mTexHairColorInfo);
+ deleteAndClear(mTexEyeColorInfo);
+ std::for_each(mLayerInfoList.begin(), mLayerInfoList.end(), DeletePointer());
+ std::for_each(mDriverInfoList.begin(), mDriverInfoList.end(), DeletePointer());
+ std::for_each(mMorphMaskInfoList.begin(), mMorphMaskInfoList.end(), DeletePointer());
+}
+
+
+/**
+ **
+ ** End LLAvatarAppearance Support classes
+ ** **
+ *********************************************************************************/
+
+//-----------------------------------------------------------------------------
+// Static Data
+//-----------------------------------------------------------------------------
+LLXmlTree LLAvatarAppearance::sXMLTree;
+LLXmlTree LLAvatarAppearance::sSkeletonXMLTree;
+LLAvatarSkeletonInfo* LLAvatarAppearance::sAvatarSkeletonInfo = NULL;
+LLAvatarAppearance::LLAvatarXmlInfo* LLAvatarAppearance::sAvatarXmlInfo = NULL;
+
+
+LLAvatarAppearance::LLAvatarAppearance(LLWearableData* wearable_data) :
+ LLCharacter(),
+ mIsDummy(FALSE),
+ mTexSkinColor( NULL ),
+ mTexHairColor( NULL ),
+ mTexEyeColor( NULL ),
+ mPelvisToFoot(0.f),
+ mHeadOffset(),
+ mRoot(NULL),
+ mWearableData(wearable_data)
+{
+ llassert_always(mWearableData);
+ mBakedTextureDatas.resize(LLAvatarAppearanceDefines::BAKED_NUM_INDICES);
+ for (U32 i = 0; i < mBakedTextureDatas.size(); i++ )
+ {
+ mBakedTextureDatas[i].mLastTextureID = IMG_DEFAULT_AVATAR;
+ mBakedTextureDatas[i].mTexLayerSet = NULL;
+ mBakedTextureDatas[i].mIsLoaded = false;
+ mBakedTextureDatas[i].mIsUsed = false;
+ mBakedTextureDatas[i].mMaskTexName = 0;
+ mBakedTextureDatas[i].mTextureIndex = LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::bakedToLocalTextureIndex((LLAvatarAppearanceDefines::EBakedTextureIndex)i);
+ }
+
+ mIsBuilt = FALSE;
+
+ mNumCollisionVolumes = 0;
+ mCollisionVolumes = NULL;
+}
+
+// virtual
+void LLAvatarAppearance::initInstance()
+{
+ //-------------------------------------------------------------------------
+ // initialize joint, mesh and shape members
+ //-------------------------------------------------------------------------
+ mRoot = createAvatarJoint();
+ mRoot->setName( "mRoot" );
+
+ for (LLAvatarAppearanceDictionary::MeshEntries::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getMeshEntries().begin();
+ iter != LLAvatarAppearanceDictionary::getInstance()->getMeshEntries().end();
+ ++iter)
+ {
+ const EMeshIndex mesh_index = iter->first;
+ const LLAvatarAppearanceDictionary::MeshEntry *mesh_dict = iter->second;
+ LLAvatarJoint* joint = createAvatarJoint();
+ joint->setName(mesh_dict->mName);
+ joint->setMeshID(mesh_index);
+ mMeshLOD.push_back(joint);
+
+ /* mHairLOD.setName("mHairLOD");
+ mHairMesh0.setName("mHairMesh0");
+ mHairMesh0.setMeshID(MESH_ID_HAIR);
+ mHairMesh1.setName("mHairMesh1"); */
+ for (U32 lod = 0; lod < mesh_dict->mLOD; lod++)
+ {
+ LLAvatarJointMesh* mesh = createAvatarJointMesh();
+ std::string mesh_name = "m" + mesh_dict->mName + boost::lexical_cast<std::string>(lod);
+ // We pre-pended an m - need to capitalize first character for camelCase
+ mesh_name[1] = toupper(mesh_name[1]);
+ mesh->setName(mesh_name);
+ mesh->setMeshID(mesh_index);
+ mesh->setPickName(mesh_dict->mPickName);
+ mesh->setIsTransparent(FALSE);
+ switch((int)mesh_index)
+ {
+ case MESH_ID_HAIR:
+ mesh->setIsTransparent(TRUE);
+ break;
+ case MESH_ID_SKIRT:
+ mesh->setIsTransparent(TRUE);
+ break;
+ case MESH_ID_EYEBALL_LEFT:
+ case MESH_ID_EYEBALL_RIGHT:
+ mesh->setSpecular( LLColor4( 1.0f, 1.0f, 1.0f, 1.0f ), 1.f );
+ break;
+ }
+
+ joint->mMeshParts.push_back(mesh);
+ }
+ }
+
+ //-------------------------------------------------------------------------
+ // associate baked textures with meshes
+ //-------------------------------------------------------------------------
+ for (LLAvatarAppearanceDictionary::MeshEntries::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getMeshEntries().begin();
+ iter != LLAvatarAppearanceDictionary::getInstance()->getMeshEntries().end();
+ ++iter)
+ {
+ const EMeshIndex mesh_index = iter->first;
+ const LLAvatarAppearanceDictionary::MeshEntry *mesh_dict = iter->second;
+ const EBakedTextureIndex baked_texture_index = mesh_dict->mBakedID;
+ // Skip it if there's no associated baked texture.
+ if (baked_texture_index == BAKED_NUM_INDICES) continue;
+
+ for (avatar_joint_mesh_list_t::iterator iter = mMeshLOD[mesh_index]->mMeshParts.begin();
+ iter != mMeshLOD[mesh_index]->mMeshParts.end();
+ ++iter)
+ {
+ LLAvatarJointMesh* mesh = (*iter);
+ mBakedTextureDatas[(int)baked_texture_index].mJointMeshes.push_back(mesh);
+ }
+ }
+
+ buildCharacter();
+
+}
+
+// virtual
+LLAvatarAppearance::~LLAvatarAppearance()
+{
+ deleteAndClear(mTexSkinColor);
+ deleteAndClear(mTexHairColor);
+ deleteAndClear(mTexEyeColor);
+
+ for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
+ {
+ deleteAndClear(mBakedTextureDatas[i].mTexLayerSet);
+ mBakedTextureDatas[i].mJointMeshes.clear();
+
+ for (morph_list_t::iterator iter2 = mBakedTextureDatas[i].mMaskedMorphs.begin();
+ iter2 != mBakedTextureDatas[i].mMaskedMorphs.end(); iter2++)
+ {
+ LLMaskedMorph* masked_morph = (*iter2);
+ delete masked_morph;
+ }
+ }
+
+ if (mRoot) mRoot->removeAllChildren();
+ mJointMap.clear();
+
+ clearSkeleton();
+ deleteAndClearArray(mCollisionVolumes);
+
+ deleteAndClear(mTexSkinColor);
+ deleteAndClear(mTexHairColor);
+ deleteAndClear(mTexEyeColor);
+
+ std::for_each(mPolyMeshes.begin(), mPolyMeshes.end(), DeletePairedPointer());
+ mPolyMeshes.clear();
+
+ for (avatar_joint_list_t::iterator jointIter = mMeshLOD.begin();
+ jointIter != mMeshLOD.end();
+ ++jointIter)
+ {
+ LLAvatarJoint* joint = *jointIter;
+ std::for_each(joint->mMeshParts.begin(), joint->mMeshParts.end(), DeletePointer());
+ joint->mMeshParts.clear();
+ }
+ std::for_each(mMeshLOD.begin(), mMeshLOD.end(), DeletePointer());
+ mMeshLOD.clear();
+}
+
+//static
+void LLAvatarAppearance::initClass()
+{
+ std::string xmlFile;
+
+ xmlFile = gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,AVATAR_DEFAULT_CHAR) + "_lad.xml";
+ BOOL success = sXMLTree.parseFile( xmlFile, FALSE );
+ if (!success)
+ {
+ llerrs << "Problem reading avatar configuration file:" << xmlFile << llendl;
+ }
+
+ // now sanity check xml file
+ LLXmlTreeNode* root = sXMLTree.getRoot();
+ if (!root)
+ {
+ llerrs << "No root node found in avatar configuration file: " << xmlFile << llendl;
+ return;
+ }
+
+ //-------------------------------------------------------------------------
+ // <linden_avatar version="1.0"> (root)
+ //-------------------------------------------------------------------------
+ if( !root->hasName( "linden_avatar" ) )
+ {
+ llerrs << "Invalid avatar file header: " << xmlFile << llendl;
+ }
+
+ std::string version;
+ static LLStdStringHandle version_string = LLXmlTree::addAttributeString("version");
+ if( !root->getFastAttributeString( version_string, version ) || (version != "1.0") )
+ {
+ llerrs << "Invalid avatar file version: " << version << " in file: " << xmlFile << llendl;
+ }
+
+ S32 wearable_def_version = 1;
+ static LLStdStringHandle wearable_definition_version_string = LLXmlTree::addAttributeString("wearable_definition_version");
+ root->getFastAttributeS32( wearable_definition_version_string, wearable_def_version );
+ LLWearable::setCurrentDefinitionVersion( wearable_def_version );
+
+ std::string mesh_file_name;
+
+ LLXmlTreeNode* skeleton_node = root->getChildByName( "skeleton" );
+ if (!skeleton_node)
+ {
+ llerrs << "No skeleton in avatar configuration file: " << xmlFile << llendl;
+ return;
+ }
+
+ std::string skeleton_file_name;
+ static LLStdStringHandle file_name_string = LLXmlTree::addAttributeString("file_name");
+ if (!skeleton_node->getFastAttributeString(file_name_string, skeleton_file_name))
+ {
+ llerrs << "No file name in skeleton node in avatar config file: " << xmlFile << llendl;
+ }
+
+ std::string skeleton_path;
+ skeleton_path = gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,skeleton_file_name);
+ if (!parseSkeletonFile(skeleton_path))
+ {
+ llerrs << "Error parsing skeleton file: " << skeleton_path << llendl;
+ }
+
+ // Process XML data
+
+ // avatar_skeleton.xml
+ if (sAvatarSkeletonInfo)
+ { //this can happen if a login attempt failed
+ delete sAvatarSkeletonInfo;
+ }
+ sAvatarSkeletonInfo = new LLAvatarSkeletonInfo;
+ if (!sAvatarSkeletonInfo->parseXml(sSkeletonXMLTree.getRoot()))
+ {
+ llerrs << "Error parsing skeleton XML file: " << skeleton_path << llendl;
+ }
+ // parse avatar_lad.xml
+ if (sAvatarXmlInfo)
+ { //this can happen if a login attempt failed
+ deleteAndClear(sAvatarXmlInfo);
+ }
+ sAvatarXmlInfo = new LLAvatarXmlInfo;
+ if (!sAvatarXmlInfo->parseXmlSkeletonNode(root))
+ {
+ llerrs << "Error parsing skeleton node in avatar XML file: " << skeleton_path << llendl;
+ }
+ if (!sAvatarXmlInfo->parseXmlMeshNodes(root))
+ {
+ llerrs << "Error parsing skeleton node in avatar XML file: " << skeleton_path << llendl;
+ }
+ if (!sAvatarXmlInfo->parseXmlColorNodes(root))
+ {
+ llerrs << "Error parsing skeleton node in avatar XML file: " << skeleton_path << llendl;
+ }
+ if (!sAvatarXmlInfo->parseXmlLayerNodes(root))
+ {
+ llerrs << "Error parsing skeleton node in avatar XML file: " << skeleton_path << llendl;
+ }
+ if (!sAvatarXmlInfo->parseXmlDriverNodes(root))
+ {
+ llerrs << "Error parsing skeleton node in avatar XML file: " << skeleton_path << llendl;
+ }
+ if (!sAvatarXmlInfo->parseXmlMorphNodes(root))
+ {
+ llerrs << "Error parsing skeleton node in avatar XML file: " << skeleton_path << llendl;
+ }
+}
+
+void LLAvatarAppearance::cleanupClass()
+{
+ deleteAndClear(sAvatarXmlInfo);
+ // *TODO: What about sAvatarSkeletonInfo ???
+ sSkeletonXMLTree.cleanup();
+ sXMLTree.cleanup();
+}
+
+using namespace LLAvatarAppearanceDefines;
+
+//------------------------------------------------------------------------
+// The viewer can only suggest a good size for the agent,
+// the simulator will keep it inside a reasonable range.
+void LLAvatarAppearance::computeBodySize()
+{
+ LLVector3 pelvis_scale = mPelvisp->getScale();
+
+ // some of the joints have not been cached
+ LLVector3 skull = mSkullp->getPosition();
+ //LLVector3 skull_scale = mSkullp->getScale();
+
+ LLVector3 neck = mNeckp->getPosition();
+ LLVector3 neck_scale = mNeckp->getScale();
+
+ LLVector3 chest = mChestp->getPosition();
+ LLVector3 chest_scale = mChestp->getScale();
+
+ // the rest of the joints have been cached
+ LLVector3 head = mHeadp->getPosition();
+ LLVector3 head_scale = mHeadp->getScale();
+
+ LLVector3 torso = mTorsop->getPosition();
+ LLVector3 torso_scale = mTorsop->getScale();
+
+ LLVector3 hip = mHipLeftp->getPosition();
+ LLVector3 hip_scale = mHipLeftp->getScale();
+
+ LLVector3 knee = mKneeLeftp->getPosition();
+ LLVector3 knee_scale = mKneeLeftp->getScale();
+
+ LLVector3 ankle = mAnkleLeftp->getPosition();
+ LLVector3 ankle_scale = mAnkleLeftp->getScale();
+
+ LLVector3 foot = mFootLeftp->getPosition();
+
+ F32 old_offset = mAvatarOffset.mV[VZ];
+
+ mAvatarOffset.mV[VZ] = getVisualParamWeight(AVATAR_HOVER);
+
+ mPelvisToFoot = hip.mV[VZ] * pelvis_scale.mV[VZ] -
+ knee.mV[VZ] * hip_scale.mV[VZ] -
+ ankle.mV[VZ] * knee_scale.mV[VZ] -
+ foot.mV[VZ] * ankle_scale.mV[VZ];
+
+ LLVector3 new_body_size;
+ new_body_size.mV[VZ] = mPelvisToFoot +
+ // the sqrt(2) correction below is an approximate
+ // correction to get to the top of the head
+ F_SQRT2 * (skull.mV[VZ] * head_scale.mV[VZ]) +
+ head.mV[VZ] * neck_scale.mV[VZ] +
+ neck.mV[VZ] * chest_scale.mV[VZ] +
+ chest.mV[VZ] * torso_scale.mV[VZ] +
+ torso.mV[VZ] * pelvis_scale.mV[VZ];
+
+ // TODO -- measure the real depth and width
+ new_body_size.mV[VX] = DEFAULT_AGENT_DEPTH;
+ new_body_size.mV[VY] = DEFAULT_AGENT_WIDTH;
+
+ mAvatarOffset.mV[VX] = 0.0f;
+ mAvatarOffset.mV[VY] = 0.0f;
+
+ // Certain configurations of avatars can force the overall height (with offset) to go negative.
+ // Enforce a constraint to make sure we don't go below 0.1 meters.
+ // Camera positioning and other things start to break down when your avatar is "walking" while being fully underground
+ if (new_body_size.mV[VZ] + mAvatarOffset.mV[VZ] < 0.1f)
+ {
+ mAvatarOffset.mV[VZ] = -(new_body_size.mV[VZ] - 0.11f); // avoid floating point rounding making the above check continue to fail.
+
+ llassert(new_body_size.mV[VZ] + mAvatarOffset.mV[VZ] >= 0.1f);
+
+ if (mWearableData && isSelf())
+ {
+ LLWearable* shape = mWearableData->getWearable(LLWearableType::WT_SHAPE, 0);
+ if (shape)
+ {
+ shape->setVisualParamWeight(AVATAR_HOVER, mAvatarOffset.mV[VZ], false);
+ }
+ }
+ }
+
+ if (new_body_size != mBodySize || old_offset != mAvatarOffset.mV[VZ])
+ {
+ mBodySize = new_body_size;
+ bodySizeChanged();
+ }
+}
+
+//-----------------------------------------------------------------------------
+// parseSkeletonFile()
+//-----------------------------------------------------------------------------
+BOOL LLAvatarAppearance::parseSkeletonFile(const std::string& filename)
+{
+ //-------------------------------------------------------------------------
+ // parse the file
+ //-------------------------------------------------------------------------
+ BOOL parsesuccess = sSkeletonXMLTree.parseFile( filename, FALSE );
+
+ if (!parsesuccess)
+ {
+ llerrs << "Can't parse skeleton file: " << filename << llendl;
+ return FALSE;
+ }
+
+ // now sanity check xml file
+ LLXmlTreeNode* root = sSkeletonXMLTree.getRoot();
+ if (!root)
+ {
+ llerrs << "No root node found in avatar skeleton file: " << filename << llendl;
+ return FALSE;
+ }
+
+ if( !root->hasName( "linden_skeleton" ) )
+ {
+ llerrs << "Invalid avatar skeleton file header: " << filename << llendl;
+ return FALSE;
+ }
+
+ std::string version;
+ static LLStdStringHandle version_string = LLXmlTree::addAttributeString("version");
+ if( !root->getFastAttributeString( version_string, version ) || (version != "1.0") )
+ {
+ llerrs << "Invalid avatar skeleton file version: " << version << " in file: " << filename << llendl;
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// setupBone()
+//-----------------------------------------------------------------------------
+BOOL LLAvatarAppearance::setupBone(const LLAvatarBoneInfo* info, LLJoint* parent, S32 &volume_num, S32 &joint_num)
+{
+ LLJoint* joint = NULL;
+
+ if (info->mIsJoint)
+ {
+ joint = getCharacterJoint(joint_num);
+ if (!joint)
+ {
+ llwarns << "Too many bones" << llendl;
+ return FALSE;
+ }
+ joint->setName( info->mName );
+ }
+ else // collision volume
+ {
+ if (volume_num >= (S32)mNumCollisionVolumes)
+ {
+ llwarns << "Too many bones" << llendl;
+ return FALSE;
+ }
+ joint = (&mCollisionVolumes[volume_num]);
+ joint->setName( info->mName );
+ }
+
+ // add to parent
+ if (parent)
+ {
+ parent->addChild( joint );
+ }
+
+ joint->setPosition(info->mPos);
+ joint->setRotation(mayaQ(info->mRot.mV[VX], info->mRot.mV[VY],
+ info->mRot.mV[VZ], LLQuaternion::XYZ));
+ joint->setScale(info->mScale);
+
+ joint->setDefaultFromCurrentXform();
+
+ if (info->mIsJoint)
+ {
+ joint->setSkinOffset( info->mPivot );
+ joint_num++;
+ }
+ else // collision volume
+ {
+ volume_num++;
+ }
+
+ // setup children
+ LLAvatarBoneInfo::child_list_t::const_iterator iter;
+ for (iter = info->mChildList.begin(); iter != info->mChildList.end(); ++iter)
+ {
+ LLAvatarBoneInfo *child_info = *iter;
+ if (!setupBone(child_info, joint, volume_num, joint_num))
+ {
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// allocateCharacterJoints()
+//-----------------------------------------------------------------------------
+BOOL LLAvatarAppearance::allocateCharacterJoints( U32 num )
+{
+ clearSkeleton();
+
+ for(S32 joint_num = 0; joint_num < (S32)num; joint_num++)
+ {
+ mSkeleton.push_back(createAvatarJoint(joint_num));
+ }
+
+ return TRUE;
+}
+
+
+//-----------------------------------------------------------------------------
+// buildSkeleton()
+//-----------------------------------------------------------------------------
+BOOL LLAvatarAppearance::buildSkeleton(const LLAvatarSkeletonInfo *info)
+{
+ //-------------------------------------------------------------------------
+ // allocate joints
+ //-------------------------------------------------------------------------
+ if (!allocateCharacterJoints(info->mNumBones))
+ {
+ llerrs << "Can't allocate " << info->mNumBones << " joints" << llendl;
+ return FALSE;
+ }
+
+ //-------------------------------------------------------------------------
+ // allocate volumes
+ //-------------------------------------------------------------------------
+ if (info->mNumCollisionVolumes)
+ {
+ if (!allocateCollisionVolumes(info->mNumCollisionVolumes))
+ {
+ llerrs << "Can't allocate " << info->mNumCollisionVolumes << " collision volumes" << llendl;
+ return FALSE;
+ }
+ }
+
+ S32 current_joint_num = 0;
+ S32 current_volume_num = 0;
+ LLAvatarSkeletonInfo::bone_info_list_t::const_iterator iter;
+ for (iter = info->mBoneInfoList.begin(); iter != info->mBoneInfoList.end(); ++iter)
+ {
+ LLAvatarBoneInfo *info = *iter;
+ if (!setupBone(info, NULL, current_volume_num, current_joint_num))
+ {
+ llerrs << "Error parsing bone in skeleton file" << llendl;
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// clearSkeleton()
+//-----------------------------------------------------------------------------
+void LLAvatarAppearance::clearSkeleton()
+{
+ std::for_each(mSkeleton.begin(), mSkeleton.end(), DeletePointer());
+ mSkeleton.clear();
+}
+
+//-----------------------------------------------------------------------------
+// LLAvatarAppearance::buildCharacter()
+// Deferred initialization and rebuild of the avatar.
+//-----------------------------------------------------------------------------
+void LLAvatarAppearance::buildCharacter()
+{
+ //-------------------------------------------------------------------------
+ // remove all references to our existing skeleton
+ // so we can rebuild it
+ //-------------------------------------------------------------------------
+ flushAllMotions();
+
+ //-------------------------------------------------------------------------
+ // remove all of mRoot's children
+ //-------------------------------------------------------------------------
+ mRoot->removeAllChildren();
+ mJointMap.clear();
+ mIsBuilt = FALSE;
+
+ //-------------------------------------------------------------------------
+ // clear mesh data
+ //-------------------------------------------------------------------------
+ for (avatar_joint_list_t::iterator jointIter = mMeshLOD.begin();
+ jointIter != mMeshLOD.end(); ++jointIter)
+ {
+ LLAvatarJoint* joint = *jointIter;
+ for (avatar_joint_mesh_list_t::iterator meshIter = joint->mMeshParts.begin();
+ meshIter != joint->mMeshParts.end(); ++meshIter)
+ {
+ LLAvatarJointMesh * mesh = *meshIter;
+ mesh->setMesh(NULL);
+ }
+ }
+
+ //-------------------------------------------------------------------------
+ // (re)load our skeleton and meshes
+ //-------------------------------------------------------------------------
+ LLTimer timer;
+
+ BOOL status = loadAvatar();
+ stop_glerror();
+
+// gPrintMessagesThisFrame = TRUE;
+ lldebugs << "Avatar load took " << timer.getElapsedTimeF32() << " seconds." << llendl;
+
+ if (!status)
+ {
+ if (isSelf())
+ {
+ llerrs << "Unable to load user's avatar" << llendl;
+ }
+ else
+ {
+ llwarns << "Unable to load other's avatar" << llendl;
+ }
+ return;
+ }
+
+ //-------------------------------------------------------------------------
+ // initialize "well known" joint pointers
+ //-------------------------------------------------------------------------
+ mPelvisp = mRoot->findJoint("mPelvis");
+ mTorsop = mRoot->findJoint("mTorso");
+ mChestp = mRoot->findJoint("mChest");
+ mNeckp = mRoot->findJoint("mNeck");
+ mHeadp = mRoot->findJoint("mHead");
+ mSkullp = mRoot->findJoint("mSkull");
+ mHipLeftp = mRoot->findJoint("mHipLeft");
+ mHipRightp = mRoot->findJoint("mHipRight");
+ mKneeLeftp = mRoot->findJoint("mKneeLeft");
+ mKneeRightp = mRoot->findJoint("mKneeRight");
+ mAnkleLeftp = mRoot->findJoint("mAnkleLeft");
+ mAnkleRightp = mRoot->findJoint("mAnkleRight");
+ mFootLeftp = mRoot->findJoint("mFootLeft");
+ mFootRightp = mRoot->findJoint("mFootRight");
+ mWristLeftp = mRoot->findJoint("mWristLeft");
+ mWristRightp = mRoot->findJoint("mWristRight");
+ mEyeLeftp = mRoot->findJoint("mEyeLeft");
+ mEyeRightp = mRoot->findJoint("mEyeRight");
+
+ //-------------------------------------------------------------------------
+ // Make sure "well known" pointers exist
+ //-------------------------------------------------------------------------
+ if (!(mPelvisp &&
+ mTorsop &&
+ mChestp &&
+ mNeckp &&
+ mHeadp &&
+ mSkullp &&
+ mHipLeftp &&
+ mHipRightp &&
+ mKneeLeftp &&
+ mKneeRightp &&
+ mAnkleLeftp &&
+ mAnkleRightp &&
+ mFootLeftp &&
+ mFootRightp &&
+ mWristLeftp &&
+ mWristRightp &&
+ mEyeLeftp &&
+ mEyeRightp))
+ {
+ llerrs << "Failed to create avatar." << llendl;
+ return;
+ }
+
+ //-------------------------------------------------------------------------
+ // initialize the pelvis
+ //-------------------------------------------------------------------------
+ mPelvisp->setPosition( LLVector3(0.0f, 0.0f, 0.0f) );
+
+ mIsBuilt = TRUE;
+ stop_glerror();
+
+}
+
+BOOL LLAvatarAppearance::loadAvatar()
+{
+// LLFastTimer t(FTM_LOAD_AVATAR);
+
+ // avatar_skeleton.xml
+ if( !buildSkeleton(sAvatarSkeletonInfo) )
+ {
+ llwarns << "avatar file: buildSkeleton() failed" << llendl;
+ return FALSE;
+ }
+
+ // avatar_lad.xml : <skeleton>
+ if( !loadSkeletonNode() )
+ {
+ llwarns << "avatar file: loadNodeSkeleton() failed" << llendl;
+ return FALSE;
+ }
+
+ // avatar_lad.xml : <mesh>
+ if( !loadMeshNodes() )
+ {
+ llwarns << "avatar file: loadNodeMesh() failed" << llendl;
+ return FALSE;
+ }
+
+ // avatar_lad.xml : <global_color>
+ if( sAvatarXmlInfo->mTexSkinColorInfo )
+ {
+ mTexSkinColor = new LLTexGlobalColor( this );
+ if( !mTexSkinColor->setInfo( sAvatarXmlInfo->mTexSkinColorInfo ) )
+ {
+ llwarns << "avatar file: mTexSkinColor->setInfo() failed" << llendl;
+ return FALSE;
+ }
+ }
+ else
+ {
+ llwarns << "<global_color> name=\"skin_color\" not found" << llendl;
+ return FALSE;
+ }
+ if( sAvatarXmlInfo->mTexHairColorInfo )
+ {
+ mTexHairColor = new LLTexGlobalColor( this );
+ if( !mTexHairColor->setInfo( sAvatarXmlInfo->mTexHairColorInfo ) )
+ {
+ llwarns << "avatar file: mTexHairColor->setInfo() failed" << llendl;
+ return FALSE;
+ }
+ }
+ else
+ {
+ llwarns << "<global_color> name=\"hair_color\" not found" << llendl;
+ return FALSE;
+ }
+ if( sAvatarXmlInfo->mTexEyeColorInfo )
+ {
+ mTexEyeColor = new LLTexGlobalColor( this );
+ if( !mTexEyeColor->setInfo( sAvatarXmlInfo->mTexEyeColorInfo ) )
+ {
+ llwarns << "avatar file: mTexEyeColor->setInfo() failed" << llendl;
+ return FALSE;
+ }
+ }
+ else
+ {
+ llwarns << "<global_color> name=\"eye_color\" not found" << llendl;
+ return FALSE;
+ }
+
+ // avatar_lad.xml : <layer_set>
+ if (sAvatarXmlInfo->mLayerInfoList.empty())
+ {
+ llwarns << "avatar file: missing <layer_set> node" << llendl;
+ return FALSE;
+ }
+
+ if (sAvatarXmlInfo->mMorphMaskInfoList.empty())
+ {
+ llwarns << "avatar file: missing <morph_masks> node" << llendl;
+ return FALSE;
+ }
+
+ // avatar_lad.xml : <morph_masks>
+ for (LLAvatarXmlInfo::morph_info_list_t::iterator iter = sAvatarXmlInfo->mMorphMaskInfoList.begin();
+ iter != sAvatarXmlInfo->mMorphMaskInfoList.end();
+ ++iter)
+ {
+ LLAvatarXmlInfo::LLAvatarMorphInfo *info = *iter;
+
+ EBakedTextureIndex baked = LLAvatarAppearanceDictionary::findBakedByRegionName(info->mRegion);
+ if (baked != BAKED_NUM_INDICES)
+ {
+ LLVisualParam* morph_param;
+ const std::string *name = &info->mName;
+ morph_param = getVisualParam(name->c_str());
+ if (morph_param)
+ {
+ BOOL invert = info->mInvert;
+ addMaskedMorph(baked, morph_param, invert, info->mLayer);
+ }
+ }
+
+ }
+
+ loadLayersets();
+
+ // avatar_lad.xml : <driver_parameters>
+ for (LLAvatarXmlInfo::driver_info_list_t::iterator iter = sAvatarXmlInfo->mDriverInfoList.begin();
+ iter != sAvatarXmlInfo->mDriverInfoList.end();
+ ++iter)
+ {
+ LLDriverParamInfo *info = *iter;
+ LLDriverParam* driver_param = new LLDriverParam( this );
+ if (driver_param->setInfo(info))
+ {
+ addVisualParam( driver_param );
+ driver_param->setParamLocation(isSelf() ? LOC_AV_SELF : LOC_AV_OTHER);
+ LLVisualParam*(LLAvatarAppearance::*avatar_function)(S32)const = &LLAvatarAppearance::getVisualParam;
+ if( !driver_param->linkDrivenParams(boost::bind(avatar_function,(LLAvatarAppearance*)this,_1 ), false))
+ {
+ llwarns << "could not link driven params for avatar " << getID().asString() << " param id: " << driver_param->getID() << llendl;
+ continue;
+ }
+ }
+ else
+ {
+ delete driver_param;
+ llwarns << "avatar file: driver_param->parseData() failed" << llendl;
+ return FALSE;
+ }
+ }
+
+
+ return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// loadSkeletonNode(): loads <skeleton> node from XML tree
+//-----------------------------------------------------------------------------
+BOOL LLAvatarAppearance::loadSkeletonNode ()
+{
+ mRoot->addChild( mSkeleton[0] );
+
+ // make meshes children before calling parent version of the function
+ for (avatar_joint_list_t::iterator iter = mMeshLOD.begin();
+ iter != mMeshLOD.end();
+ ++iter)
+ {
+ LLAvatarJoint *joint = *iter;
+ joint->mUpdateXform = FALSE;
+ joint->setMeshesToChildren();
+ }
+
+ mRoot->addChild(mMeshLOD[MESH_ID_HEAD]);
+ mRoot->addChild(mMeshLOD[MESH_ID_EYELASH]);
+ mRoot->addChild(mMeshLOD[MESH_ID_UPPER_BODY]);
+ mRoot->addChild(mMeshLOD[MESH_ID_LOWER_BODY]);
+ mRoot->addChild(mMeshLOD[MESH_ID_SKIRT]);
+ mRoot->addChild(mMeshLOD[MESH_ID_HEAD]);
+
+ LLAvatarJoint *skull = (LLAvatarJoint*)mRoot->findJoint("mSkull");
+ if (skull)
+ {
+ skull->addChild(mMeshLOD[MESH_ID_HAIR] );
+ }
+
+ LLAvatarJoint *eyeL = (LLAvatarJoint*)mRoot->findJoint("mEyeLeft");
+ if (eyeL)
+ {
+ eyeL->addChild( mMeshLOD[MESH_ID_EYEBALL_LEFT] );
+ }
+
+ LLAvatarJoint *eyeR = (LLAvatarJoint*)mRoot->findJoint("mEyeRight");
+ if (eyeR)
+ {
+ eyeR->addChild( mMeshLOD[MESH_ID_EYEBALL_RIGHT] );
+ }
+
+ // SKELETAL DISTORTIONS
+ {
+ LLAvatarXmlInfo::skeletal_distortion_info_list_t::iterator iter;
+ for (iter = sAvatarXmlInfo->mSkeletalDistortionInfoList.begin();
+ iter != sAvatarXmlInfo->mSkeletalDistortionInfoList.end();
+ ++iter)
+ {
+ LLPolySkeletalDistortionInfo *info = (LLPolySkeletalDistortionInfo*)*iter;
+ LLPolySkeletalDistortion *param = new LLPolySkeletalDistortion(this);
+ if (!param->setInfo(info))
+ {
+ delete param;
+ return FALSE;
+ }
+ else
+ {
+ addVisualParam(param);
+ param->setParamLocation(isSelf() ? LOC_AV_SELF : LOC_AV_OTHER);
+ }
+ }
+ }
+
+
+ return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// loadMeshNodes(): loads <mesh> nodes from XML tree
+//-----------------------------------------------------------------------------
+BOOL LLAvatarAppearance::loadMeshNodes()
+{
+ for (LLAvatarXmlInfo::mesh_info_list_t::const_iterator meshinfo_iter = sAvatarXmlInfo->mMeshInfoList.begin();
+ meshinfo_iter != sAvatarXmlInfo->mMeshInfoList.end();
+ ++meshinfo_iter)
+ {
+ const LLAvatarXmlInfo::LLAvatarMeshInfo *info = *meshinfo_iter;
+ const std::string &type = info->mType;
+ S32 lod = info->mLOD;
+
+ LLAvatarJointMesh* mesh = NULL;
+ U8 mesh_id = 0;
+ BOOL found_mesh_id = FALSE;
+
+ /* if (type == "hairMesh")
+ switch(lod)
+ case 0:
+ mesh = &mHairMesh0; */
+ for (LLAvatarAppearanceDictionary::MeshEntries::const_iterator mesh_iter = LLAvatarAppearanceDictionary::getInstance()->getMeshEntries().begin();
+ mesh_iter != LLAvatarAppearanceDictionary::getInstance()->getMeshEntries().end();
+ ++mesh_iter)
+ {
+ const EMeshIndex mesh_index = mesh_iter->first;
+ const LLAvatarAppearanceDictionary::MeshEntry *mesh_dict = mesh_iter->second;
+ if (type.compare(mesh_dict->mName) == 0)
+ {
+ mesh_id = mesh_index;
+ found_mesh_id = TRUE;
+ break;
+ }
+ }
+
+ if (found_mesh_id)
+ {
+ if (lod < (S32)mMeshLOD[mesh_id]->mMeshParts.size())
+ {
+ mesh = mMeshLOD[mesh_id]->mMeshParts[lod];
+ }
+ else
+ {
+ llwarns << "Avatar file: <mesh> has invalid lod setting " << lod << llendl;
+ return FALSE;
+ }
+ }
+ else
+ {
+ llwarns << "Ignoring unrecognized mesh type: " << type << llendl;
+ return FALSE;
+ }
+
+ // llinfos << "Parsing mesh data for " << type << "..." << llendl;
+
+ // If this isn't set to white (1.0), avatars will *ALWAYS* be darker than their surroundings.
+ // Do not touch!!!
+ mesh->setColor( LLColor4::white );
+
+ LLPolyMesh *poly_mesh = NULL;
+
+ if (!info->mReferenceMeshName.empty())
+ {
+ polymesh_map_t::const_iterator polymesh_iter = mPolyMeshes.find(info->mReferenceMeshName);
+ if (polymesh_iter != mPolyMeshes.end())
+ {
+ poly_mesh = LLPolyMesh::getMesh(info->mMeshFileName, polymesh_iter->second);
+ poly_mesh->setAvatar(this);
+ }
+ else
+ {
+ // This should never happen
+ LL_WARNS("Avatar") << "Could not find avatar mesh: " << info->mReferenceMeshName << LL_ENDL;
+ }
+ }
+ else
+ {
+ poly_mesh = LLPolyMesh::getMesh(info->mMeshFileName);
+ poly_mesh->setAvatar(this);
+ }
+
+ if( !poly_mesh )
+ {
+ llwarns << "Failed to load mesh of type " << type << llendl;
+ return FALSE;
+ }
+
+ // Multimap insert
+ mPolyMeshes.insert(std::make_pair(info->mMeshFileName, poly_mesh));
+
+ mesh->setMesh( poly_mesh );
+ mesh->setLOD( info->mMinPixelArea );
+
+ for (LLAvatarXmlInfo::LLAvatarMeshInfo::morph_info_list_t::const_iterator xmlinfo_iter = info->mPolyMorphTargetInfoList.begin();
+ xmlinfo_iter != info->mPolyMorphTargetInfoList.end();
+ ++xmlinfo_iter)
+ {
+ const LLAvatarXmlInfo::LLAvatarMeshInfo::morph_info_pair_t *info_pair = &(*xmlinfo_iter);
+ LLPolyMorphTarget *param = new LLPolyMorphTarget(mesh->getMesh());
+ if (!param->setInfo((LLPolyMorphTargetInfo*)info_pair->first))
+ {
+ delete param;
+ return FALSE;
+ }
+ else
+ {
+ if (info_pair->second)
+ {
+ addSharedVisualParam(param);
+ param->setParamLocation(isSelf() ? LOC_AV_SELF : LOC_AV_OTHER);
+ }
+ else
+ {
+ addVisualParam(param);
+ param->setParamLocation(isSelf() ? LOC_AV_SELF : LOC_AV_OTHER);
+ }
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// loadLayerSets()
+//-----------------------------------------------------------------------------
+BOOL LLAvatarAppearance::loadLayersets()
+{
+ BOOL success = TRUE;
+ for (LLAvatarXmlInfo::layer_info_list_t::const_iterator layerset_iter = sAvatarXmlInfo->mLayerInfoList.begin();
+ layerset_iter != sAvatarXmlInfo->mLayerInfoList.end();
+ ++layerset_iter)
+ {
+ LLTexLayerSetInfo *layerset_info = *layerset_iter;
+ if (isSelf())
+ {
+ // Construct a layerset for each one specified in avatar_lad.xml and initialize it as such.
+ LLTexLayerSet* layer_set = createTexLayerSet();
+
+ if (!layer_set->setInfo(layerset_info))
+ {
+ stop_glerror();
+ delete layer_set;
+ llwarns << "avatar file: layer_set->setInfo() failed" << llendl;
+ return FALSE;
+ }
+
+ // scan baked textures and associate the layerset with the appropriate one
+ EBakedTextureIndex baked_index = BAKED_NUM_INDICES;
+ for (LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().begin();
+ baked_iter != LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().end();
+ ++baked_iter)
+ {
+ const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = baked_iter->second;
+ if (layer_set->isBodyRegion(baked_dict->mName))
+ {
+ baked_index = baked_iter->first;
+ // ensure both structures are aware of each other
+ mBakedTextureDatas[baked_index].mTexLayerSet = layer_set;
+ layer_set->setBakedTexIndex(baked_index);
+ break;
+ }
+ }
+ // if no baked texture was found, warn and cleanup
+ if (baked_index == BAKED_NUM_INDICES)
+ {
+ llwarns << "<layer_set> has invalid body_region attribute" << llendl;
+ delete layer_set;
+ return FALSE;
+ }
+
+ // scan morph masks and let any affected layers know they have an associated morph
+ for (LLAvatarAppearance::morph_list_t::const_iterator morph_iter = mBakedTextureDatas[baked_index].mMaskedMorphs.begin();
+ morph_iter != mBakedTextureDatas[baked_index].mMaskedMorphs.end();
+ ++morph_iter)
+ {
+ LLMaskedMorph *morph = *morph_iter;
+ LLTexLayerInterface* layer = layer_set->findLayerByName(morph->mLayer);
+ if (layer)
+ {
+ layer->setHasMorph(TRUE);
+ }
+ else
+ {
+ llwarns << "Could not find layer named " << morph->mLayer << " to set morph flag" << llendl;
+ success = FALSE;
+ }
+ }
+ }
+ else // !isSelf()
+ {
+ // Construct a layerset for each one specified in avatar_lad.xml and initialize it as such.
+ LLTexLayerSetInfo *layerset_info = *layerset_iter;
+ layerset_info->createVisualParams(this);
+ }
+ }
+ return success;
+}
+
+//-----------------------------------------------------------------------------
+// getCharacterJoint()
+//-----------------------------------------------------------------------------
+LLJoint *LLAvatarAppearance::getCharacterJoint( U32 num )
+{
+ if ((S32)num >= mSkeleton.size()
+ || (S32)num < 0)
+ {
+ return NULL;
+ }
+ return mSkeleton[num];
+}
+
+
+//-----------------------------------------------------------------------------
+// getVolumePos()
+//-----------------------------------------------------------------------------
+LLVector3 LLAvatarAppearance::getVolumePos(S32 joint_index, LLVector3& volume_offset)
+{
+ if (joint_index > mNumCollisionVolumes)
+ {
+ return LLVector3::zero;
+ }
+
+ return mCollisionVolumes[joint_index].getVolumePos(volume_offset);
+}
+
+//-----------------------------------------------------------------------------
+// findCollisionVolume()
+//-----------------------------------------------------------------------------
+LLJoint* LLAvatarAppearance::findCollisionVolume(U32 volume_id)
+{
+ if ((S32)volume_id > mNumCollisionVolumes)
+ {
+ return NULL;
+ }
+
+ return &mCollisionVolumes[volume_id];
+}
+
+//-----------------------------------------------------------------------------
+// findCollisionVolume()
+//-----------------------------------------------------------------------------
+S32 LLAvatarAppearance::getCollisionVolumeID(std::string &name)
+{
+ for (S32 i = 0; i < mNumCollisionVolumes; i++)
+ {
+ if (mCollisionVolumes[i].getName() == name)
+ {
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+//-----------------------------------------------------------------------------
+// LLAvatarAppearance::getHeadMesh()
+//-----------------------------------------------------------------------------
+LLPolyMesh* LLAvatarAppearance::getHeadMesh()
+{
+ return mMeshLOD[MESH_ID_HEAD]->mMeshParts[0]->getMesh();
+}
+
+
+//-----------------------------------------------------------------------------
+// LLAvatarAppearance::getUpperBodyMesh()
+//-----------------------------------------------------------------------------
+LLPolyMesh* LLAvatarAppearance::getUpperBodyMesh()
+{
+ return mMeshLOD[MESH_ID_UPPER_BODY]->mMeshParts[0]->getMesh();
+}
+
+
+
+// virtual
+BOOL LLAvatarAppearance::isValid() const
+{
+ // This should only be called on ourself.
+ if (!isSelf())
+ {
+ llerrs << "Called LLAvatarAppearance::isValid() on when isSelf() == false" << llendl;
+ }
+ return TRUE;
+}
+
+
+// adds a morph mask to the appropriate baked texture structure
+void LLAvatarAppearance::addMaskedMorph(EBakedTextureIndex index, LLVisualParam* morph_target, BOOL invert, std::string layer)
+{
+ if (index < BAKED_NUM_INDICES)
+ {
+ LLMaskedMorph *morph = new LLMaskedMorph(morph_target, invert, layer);
+ mBakedTextureDatas[index].mMaskedMorphs.push_front(morph);
+ }
+}
+
+
+//static
+BOOL LLAvatarAppearance::teToColorParams( ETextureIndex te, U32 *param_name )
+{
+ switch( te )
+ {
+ case TEX_UPPER_SHIRT:
+ param_name[0] = 803; //"shirt_red";
+ param_name[1] = 804; //"shirt_green";
+ param_name[2] = 805; //"shirt_blue";
+ break;
+
+ case TEX_LOWER_PANTS:
+ param_name[0] = 806; //"pants_red";
+ param_name[1] = 807; //"pants_green";
+ param_name[2] = 808; //"pants_blue";
+ break;
+
+ case TEX_LOWER_SHOES:
+ param_name[0] = 812; //"shoes_red";
+ param_name[1] = 813; //"shoes_green";
+ param_name[2] = 817; //"shoes_blue";
+ break;
+
+ case TEX_LOWER_SOCKS:
+ param_name[0] = 818; //"socks_red";
+ param_name[1] = 819; //"socks_green";
+ param_name[2] = 820; //"socks_blue";
+ break;
+
+ case TEX_UPPER_JACKET:
+ case TEX_LOWER_JACKET:
+ param_name[0] = 834; //"jacket_red";
+ param_name[1] = 835; //"jacket_green";
+ param_name[2] = 836; //"jacket_blue";
+ break;
+
+ case TEX_UPPER_GLOVES:
+ param_name[0] = 827; //"gloves_red";
+ param_name[1] = 829; //"gloves_green";
+ param_name[2] = 830; //"gloves_blue";
+ break;
+
+ case TEX_UPPER_UNDERSHIRT:
+ param_name[0] = 821; //"undershirt_red";
+ param_name[1] = 822; //"undershirt_green";
+ param_name[2] = 823; //"undershirt_blue";
+ break;
+
+ case TEX_LOWER_UNDERPANTS:
+ param_name[0] = 824; //"underpants_red";
+ param_name[1] = 825; //"underpants_green";
+ param_name[2] = 826; //"underpants_blue";
+ break;
+
+ case TEX_SKIRT:
+ param_name[0] = 921; //"skirt_red";
+ param_name[1] = 922; //"skirt_green";
+ param_name[2] = 923; //"skirt_blue";
+ break;
+
+ case TEX_HEAD_TATTOO:
+ case TEX_LOWER_TATTOO:
+ case TEX_UPPER_TATTOO:
+ param_name[0] = 1071; //"tattoo_red";
+ param_name[1] = 1072; //"tattoo_green";
+ param_name[2] = 1073; //"tattoo_blue";
+ break;
+
+ default:
+ llassert(0);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+void LLAvatarAppearance::setClothesColor( ETextureIndex te, const LLColor4& new_color, BOOL upload_bake )
+{
+ U32 param_name[3];
+ if( teToColorParams( te, param_name ) )
+ {
+ setVisualParamWeight( param_name[0], new_color.mV[VX], upload_bake );
+ setVisualParamWeight( param_name[1], new_color.mV[VY], upload_bake );
+ setVisualParamWeight( param_name[2], new_color.mV[VZ], upload_bake );
+ }
+}
+
+LLColor4 LLAvatarAppearance::getClothesColor( ETextureIndex te )
+{
+ LLColor4 color;
+ U32 param_name[3];
+ if( teToColorParams( te, param_name ) )
+ {
+ color.mV[VX] = getVisualParamWeight( param_name[0] );
+ color.mV[VY] = getVisualParamWeight( param_name[1] );
+ color.mV[VZ] = getVisualParamWeight( param_name[2] );
+ }
+ return color;
+}
+
+// static
+LLColor4 LLAvatarAppearance::getDummyColor()
+{
+ return DUMMY_COLOR;
+}
+
+LLColor4 LLAvatarAppearance::getGlobalColor( const std::string& color_name ) const
+{
+ if (color_name=="skin_color" && mTexSkinColor)
+ {
+ return mTexSkinColor->getColor();
+ }
+ else if(color_name=="hair_color" && mTexHairColor)
+ {
+ return mTexHairColor->getColor();
+ }
+ if(color_name=="eye_color" && mTexEyeColor)
+ {
+ return mTexEyeColor->getColor();
+ }
+ else
+ {
+// return LLColor4( .5f, .5f, .5f, .5f );
+ return LLColor4( 0.f, 1.f, 1.f, 1.f ); // good debugging color
+ }
+}
+
+// Unlike most wearable functions, this works for both self and other.
+// virtual
+BOOL LLAvatarAppearance::isWearingWearableType(LLWearableType::EType type) const
+{
+ return mWearableData->getWearableCount(type) > 0;
+}
+
+LLTexLayerSet* LLAvatarAppearance::getAvatarLayerSet(EBakedTextureIndex baked_index) const
+{
+ /* switch(index)
+ case TEX_HEAD_BAKED:
+ case TEX_HEAD_BODYPAINT:
+ return mHeadLayerSet; */
+ return mBakedTextureDatas[baked_index].mTexLayerSet;
+}
+
+//-----------------------------------------------------------------------------
+// allocateCollisionVolumes()
+//-----------------------------------------------------------------------------
+BOOL LLAvatarAppearance::allocateCollisionVolumes( U32 num )
+{
+ deleteAndClearArray(mCollisionVolumes);
+ mNumCollisionVolumes = 0;
+
+ mCollisionVolumes = new LLAvatarJointCollisionVolume[num];
+ if (!mCollisionVolumes)
+ {
+ return FALSE;
+ }
+
+ mNumCollisionVolumes = num;
+ return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// LLAvatarBoneInfo::parseXml()
+//-----------------------------------------------------------------------------
+BOOL LLAvatarBoneInfo::parseXml(LLXmlTreeNode* node)
+{
+ if (node->hasName("bone"))
+ {
+ mIsJoint = TRUE;
+ static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name");
+ if (!node->getFastAttributeString(name_string, mName))
+ {
+ llwarns << "Bone without name" << llendl;
+ return FALSE;
+ }
+ }
+ else if (node->hasName("collision_volume"))
+ {
+ mIsJoint = FALSE;
+ static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name");
+ if (!node->getFastAttributeString(name_string, mName))
+ {
+ mName = "Collision Volume";
+ }
+ }
+ else
+ {
+ llwarns << "Invalid node " << node->getName() << llendl;
+ return FALSE;
+ }
+
+ static LLStdStringHandle pos_string = LLXmlTree::addAttributeString("pos");
+ if (!node->getFastAttributeVector3(pos_string, mPos))
+ {
+ llwarns << "Bone without position" << llendl;
+ return FALSE;
+ }
+
+ static LLStdStringHandle rot_string = LLXmlTree::addAttributeString("rot");
+ if (!node->getFastAttributeVector3(rot_string, mRot))
+ {
+ llwarns << "Bone without rotation" << llendl;
+ return FALSE;
+ }
+
+ static LLStdStringHandle scale_string = LLXmlTree::addAttributeString("scale");
+ if (!node->getFastAttributeVector3(scale_string, mScale))
+ {
+ llwarns << "Bone without scale" << llendl;
+ return FALSE;
+ }
+
+ if (mIsJoint)
+ {
+ static LLStdStringHandle pivot_string = LLXmlTree::addAttributeString("pivot");
+ if (!node->getFastAttributeVector3(pivot_string, mPivot))
+ {
+ llwarns << "Bone without pivot" << llendl;
+ return FALSE;
+ }
+ }
+
+ // parse children
+ LLXmlTreeNode* child;
+ for( child = node->getFirstChild(); child; child = node->getNextChild() )
+ {
+ LLAvatarBoneInfo *child_info = new LLAvatarBoneInfo;
+ if (!child_info->parseXml(child))
+ {
+ delete child_info;
+ return FALSE;
+ }
+ mChildList.push_back(child_info);
+ }
+ return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// LLAvatarSkeletonInfo::parseXml()
+//-----------------------------------------------------------------------------
+BOOL LLAvatarSkeletonInfo::parseXml(LLXmlTreeNode* node)
+{
+ static LLStdStringHandle num_bones_string = LLXmlTree::addAttributeString("num_bones");
+ if (!node->getFastAttributeS32(num_bones_string, mNumBones))
+ {
+ llwarns << "Couldn't find number of bones." << llendl;
+ return FALSE;
+ }
+
+ static LLStdStringHandle num_collision_volumes_string = LLXmlTree::addAttributeString("num_collision_volumes");
+ node->getFastAttributeS32(num_collision_volumes_string, mNumCollisionVolumes);
+
+ LLXmlTreeNode* child;
+ for( child = node->getFirstChild(); child; child = node->getNextChild() )
+ {
+ LLAvatarBoneInfo *info = new LLAvatarBoneInfo;
+ if (!info->parseXml(child))
+ {
+ delete info;
+ llwarns << "Error parsing bone in skeleton file" << llendl;
+ return FALSE;
+ }
+ mBoneInfoList.push_back(info);
+ }
+ return TRUE;
+}
+
+
+//-----------------------------------------------------------------------------
+// parseXmlSkeletonNode(): parses <skeleton> nodes from XML tree
+//-----------------------------------------------------------------------------
+BOOL LLAvatarAppearance::LLAvatarXmlInfo::parseXmlSkeletonNode(LLXmlTreeNode* root)
+{
+ LLXmlTreeNode* node = root->getChildByName( "skeleton" );
+ if( !node )
+ {
+ llwarns << "avatar file: missing <skeleton>" << llendl;
+ return FALSE;
+ }
+
+ LLXmlTreeNode* child;
+
+ // SKELETON DISTORTIONS
+ for (child = node->getChildByName( "param" );
+ child;
+ child = node->getNextNamedChild())
+ {
+ if (!child->getChildByName("param_skeleton"))
+ {
+ if (child->getChildByName("param_morph"))
+ {
+ llwarns << "Can't specify morph param in skeleton definition." << llendl;
+ }
+ else
+ {
+ llwarns << "Unknown param type." << llendl;
+ }
+ continue;
+ }
+
+ LLPolySkeletalDistortionInfo *info = new LLPolySkeletalDistortionInfo;
+ if (!info->parseXml(child))
+ {
+ delete info;
+ return FALSE;
+ }
+
+ mSkeletalDistortionInfoList.push_back(info);
+ }
+
+ // ATTACHMENT POINTS
+ for (child = node->getChildByName( "attachment_point" );
+ child;
+ child = node->getNextNamedChild())
+ {
+ LLAvatarAttachmentInfo* info = new LLAvatarAttachmentInfo();
+
+ static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name");
+ if (!child->getFastAttributeString(name_string, info->mName))
+ {
+ llwarns << "No name supplied for attachment point." << llendl;
+ delete info;
+ continue;
+ }
+
+ static LLStdStringHandle joint_string = LLXmlTree::addAttributeString("joint");
+ if (!child->getFastAttributeString(joint_string, info->mJointName))
+ {
+ llwarns << "No bone declared in attachment point " << info->mName << llendl;
+ delete info;
+ continue;
+ }
+
+ static LLStdStringHandle position_string = LLXmlTree::addAttributeString("position");
+ if (child->getFastAttributeVector3(position_string, info->mPosition))
+ {
+ info->mHasPosition = TRUE;
+ }
+
+ static LLStdStringHandle rotation_string = LLXmlTree::addAttributeString("rotation");
+ if (child->getFastAttributeVector3(rotation_string, info->mRotationEuler))
+ {
+ info->mHasRotation = TRUE;
+ }
+ static LLStdStringHandle group_string = LLXmlTree::addAttributeString("group");
+ if (child->getFastAttributeS32(group_string, info->mGroup))
+ {
+ if (info->mGroup == -1)
+ info->mGroup = -1111; // -1 = none parsed, < -1 = bad value
+ }
+
+ static LLStdStringHandle id_string = LLXmlTree::addAttributeString("id");
+ if (!child->getFastAttributeS32(id_string, info->mAttachmentID))
+ {
+ llwarns << "No id supplied for attachment point " << info->mName << llendl;
+ delete info;
+ continue;
+ }
+
+ static LLStdStringHandle slot_string = LLXmlTree::addAttributeString("pie_slice");
+ child->getFastAttributeS32(slot_string, info->mPieMenuSlice);
+
+ static LLStdStringHandle visible_in_first_person_string = LLXmlTree::addAttributeString("visible_in_first_person");
+ child->getFastAttributeBOOL(visible_in_first_person_string, info->mVisibleFirstPerson);
+
+ static LLStdStringHandle hud_attachment_string = LLXmlTree::addAttributeString("hud");
+ child->getFastAttributeBOOL(hud_attachment_string, info->mIsHUDAttachment);
+
+ mAttachmentInfoList.push_back(info);
+ }
+
+ return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// parseXmlMeshNodes(): parses <mesh> nodes from XML tree
+//-----------------------------------------------------------------------------
+BOOL LLAvatarAppearance::LLAvatarXmlInfo::parseXmlMeshNodes(LLXmlTreeNode* root)
+{
+ for (LLXmlTreeNode* node = root->getChildByName( "mesh" );
+ node;
+ node = root->getNextNamedChild())
+ {
+ LLAvatarMeshInfo *info = new LLAvatarMeshInfo;
+
+ // attribute: type
+ static LLStdStringHandle type_string = LLXmlTree::addAttributeString("type");
+ if( !node->getFastAttributeString( type_string, info->mType ) )
+ {
+ llwarns << "Avatar file: <mesh> is missing type attribute. Ignoring element. " << llendl;
+ delete info;
+ return FALSE; // Ignore this element
+ }
+
+ static LLStdStringHandle lod_string = LLXmlTree::addAttributeString("lod");
+ if (!node->getFastAttributeS32( lod_string, info->mLOD ))
+ {
+ llwarns << "Avatar file: <mesh> is missing lod attribute. Ignoring element. " << llendl;
+ delete info;
+ return FALSE; // Ignore this element
+ }
+
+ static LLStdStringHandle file_name_string = LLXmlTree::addAttributeString("file_name");
+ if( !node->getFastAttributeString( file_name_string, info->mMeshFileName ) )
+ {
+ llwarns << "Avatar file: <mesh> is missing file_name attribute. Ignoring: " << info->mType << llendl;
+ delete info;
+ return FALSE; // Ignore this element
+ }
+
+ static LLStdStringHandle reference_string = LLXmlTree::addAttributeString("reference");
+ node->getFastAttributeString( reference_string, info->mReferenceMeshName );
+
+ // attribute: min_pixel_area
+ static LLStdStringHandle min_pixel_area_string = LLXmlTree::addAttributeString("min_pixel_area");
+ static LLStdStringHandle min_pixel_width_string = LLXmlTree::addAttributeString("min_pixel_width");
+ if (!node->getFastAttributeF32( min_pixel_area_string, info->mMinPixelArea ))
+ {
+ F32 min_pixel_area = 0.1f;
+ if (node->getFastAttributeF32( min_pixel_width_string, min_pixel_area ))
+ {
+ // this is square root of pixel area (sensible to use linear space in defining lods)
+ min_pixel_area = min_pixel_area * min_pixel_area;
+ }
+ info->mMinPixelArea = min_pixel_area;
+ }
+
+ // Parse visual params for this node only if we haven't already
+ for (LLXmlTreeNode* child = node->getChildByName( "param" );
+ child;
+ child = node->getNextNamedChild())
+ {
+ if (!child->getChildByName("param_morph"))
+ {
+ if (child->getChildByName("param_skeleton"))
+ {
+ llwarns << "Can't specify skeleton param in a mesh definition." << llendl;
+ }
+ else
+ {
+ llwarns << "Unknown param type." << llendl;
+ }
+ continue;
+ }
+
+ LLPolyMorphTargetInfo *morphinfo = new LLPolyMorphTargetInfo();
+ if (!morphinfo->parseXml(child))
+ {
+ delete morphinfo;
+ delete info;
+ return -1;
+ }
+ BOOL shared = FALSE;
+ static LLStdStringHandle shared_string = LLXmlTree::addAttributeString("shared");
+ child->getFastAttributeBOOL(shared_string, shared);
+
+ info->mPolyMorphTargetInfoList.push_back(LLAvatarMeshInfo::morph_info_pair_t(morphinfo, shared));
+ }
+
+ mMeshInfoList.push_back(info);
+ }
+ return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// parseXmlColorNodes(): parses <global_color> nodes from XML tree
+//-----------------------------------------------------------------------------
+BOOL LLAvatarAppearance::LLAvatarXmlInfo::parseXmlColorNodes(LLXmlTreeNode* root)
+{
+ for (LLXmlTreeNode* color_node = root->getChildByName( "global_color" );
+ color_node;
+ color_node = root->getNextNamedChild())
+ {
+ std::string global_color_name;
+ static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name");
+ if (color_node->getFastAttributeString( name_string, global_color_name ) )
+ {
+ if( global_color_name == "skin_color" )
+ {
+ if (mTexSkinColorInfo)
+ {
+ llwarns << "avatar file: multiple instances of skin_color" << llendl;
+ return FALSE;
+ }
+ mTexSkinColorInfo = new LLTexGlobalColorInfo;
+ if( !mTexSkinColorInfo->parseXml( color_node ) )
+ {
+ deleteAndClear(mTexSkinColorInfo);
+ llwarns << "avatar file: mTexSkinColor->parseXml() failed" << llendl;
+ return FALSE;
+ }
+ }
+ else if( global_color_name == "hair_color" )
+ {
+ if (mTexHairColorInfo)
+ {
+ llwarns << "avatar file: multiple instances of hair_color" << llendl;
+ return FALSE;
+ }
+ mTexHairColorInfo = new LLTexGlobalColorInfo;
+ if( !mTexHairColorInfo->parseXml( color_node ) )
+ {
+ deleteAndClear(mTexHairColorInfo);
+ llwarns << "avatar file: mTexHairColor->parseXml() failed" << llendl;
+ return FALSE;
+ }
+ }
+ else if( global_color_name == "eye_color" )
+ {
+ if (mTexEyeColorInfo)
+ {
+ llwarns << "avatar file: multiple instances of eye_color" << llendl;
+ return FALSE;
+ }
+ mTexEyeColorInfo = new LLTexGlobalColorInfo;
+ if( !mTexEyeColorInfo->parseXml( color_node ) )
+ {
+ llwarns << "avatar file: mTexEyeColor->parseXml() failed" << llendl;
+ return FALSE;
+ }
+ }
+ }
+ }
+ return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// parseXmlLayerNodes(): parses <layer_set> nodes from XML tree
+//-----------------------------------------------------------------------------
+BOOL LLAvatarAppearance::LLAvatarXmlInfo::parseXmlLayerNodes(LLXmlTreeNode* root)
+{
+ for (LLXmlTreeNode* layer_node = root->getChildByName( "layer_set" );
+ layer_node;
+ layer_node = root->getNextNamedChild())
+ {
+ LLTexLayerSetInfo* layer_info = new LLTexLayerSetInfo();
+ if( layer_info->parseXml( layer_node ) )
+ {
+ mLayerInfoList.push_back(layer_info);
+ }
+ else
+ {
+ delete layer_info;
+ llwarns << "avatar file: layer_set->parseXml() failed" << llendl;
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// parseXmlDriverNodes(): parses <driver_parameters> nodes from XML tree
+//-----------------------------------------------------------------------------
+BOOL LLAvatarAppearance::LLAvatarXmlInfo::parseXmlDriverNodes(LLXmlTreeNode* root)
+{
+ LLXmlTreeNode* driver = root->getChildByName( "driver_parameters" );
+ if( driver )
+ {
+ for (LLXmlTreeNode* grand_child = driver->getChildByName( "param" );
+ grand_child;
+ grand_child = driver->getNextNamedChild())
+ {
+ if( grand_child->getChildByName( "param_driver" ) )
+ {
+ LLDriverParamInfo* driver_info = new LLDriverParamInfo();
+ if( driver_info->parseXml( grand_child ) )
+ {
+ mDriverInfoList.push_back(driver_info);
+ }
+ else
+ {
+ delete driver_info;
+ llwarns << "avatar file: driver_param->parseXml() failed" << llendl;
+ return FALSE;
+ }
+ }
+ }
+ }
+ return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// parseXmlDriverNodes(): parses <driver_parameters> nodes from XML tree
+//-----------------------------------------------------------------------------
+BOOL LLAvatarAppearance::LLAvatarXmlInfo::parseXmlMorphNodes(LLXmlTreeNode* root)
+{
+ LLXmlTreeNode* masks = root->getChildByName( "morph_masks" );
+ if( !masks )
+ {
+ return FALSE;
+ }
+
+ for (LLXmlTreeNode* grand_child = masks->getChildByName( "mask" );
+ grand_child;
+ grand_child = masks->getNextNamedChild())
+ {
+ LLAvatarMorphInfo* info = new LLAvatarMorphInfo();
+
+ static LLStdStringHandle name_string = LLXmlTree::addAttributeString("morph_name");
+ if (!grand_child->getFastAttributeString(name_string, info->mName))
+ {
+ llwarns << "No name supplied for morph mask." << llendl;
+ delete info;
+ continue;
+ }
+
+ static LLStdStringHandle region_string = LLXmlTree::addAttributeString("body_region");
+ if (!grand_child->getFastAttributeString(region_string, info->mRegion))
+ {
+ llwarns << "No region supplied for morph mask." << llendl;
+ delete info;
+ continue;
+ }
+
+ static LLStdStringHandle layer_string = LLXmlTree::addAttributeString("layer");
+ if (!grand_child->getFastAttributeString(layer_string, info->mLayer))
+ {
+ llwarns << "No layer supplied for morph mask." << llendl;
+ delete info;
+ continue;
+ }
+
+ // optional parameter. don't throw a warning if not present.
+ static LLStdStringHandle invert_string = LLXmlTree::addAttributeString("invert");
+ grand_child->getFastAttributeBOOL(invert_string, info->mInvert);
+
+ mMorphMaskInfoList.push_back(info);
+ }
+
+ return TRUE;
+}
+
+//virtual
+LLAvatarAppearance::LLMaskedMorph::LLMaskedMorph(LLVisualParam *morph_target, BOOL invert, std::string layer) :
+ mMorphTarget(morph_target),
+ mInvert(invert),
+ mLayer(layer)
+{
+ LLPolyMorphTarget *target = dynamic_cast<LLPolyMorphTarget*>(morph_target);
+ if (target)
+ {
+ target->addPendingMorphMask();
+ }
+}
+
+
+
diff --git a/indra/llappearance/llavatarappearance.h b/indra/llappearance/llavatarappearance.h
new file mode 100644
index 0000000000..bce2540258
--- /dev/null
+++ b/indra/llappearance/llavatarappearance.h
@@ -0,0 +1,448 @@
+/**
+ * @file llavatarappearance.h
+ * @brief Declaration of LLAvatarAppearance class
+ *
+ * $LicenseInfo:firstyear=2012&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$
+ */
+
+#ifndef LL_AVATAR_APPEARANCE_H
+#define LL_AVATAR_APPEARANCE_H
+
+#include "llcharacter.h"
+#include "llavatarappearancedefines.h"
+#include "llavatarjointmesh.h"
+#include "lldriverparam.h"
+#include "lltexlayer.h"
+#include "llviewervisualparam.h"
+#include "llxmltree.h"
+
+class LLTexLayerSet;
+class LLTexGlobalColor;
+class LLTexGlobalColorInfo;
+class LLWearableData;
+class LLAvatarBoneInfo;
+class LLAvatarSkeletonInfo;
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// LLAvatarAppearance
+//
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+class LLAvatarAppearance : public LLCharacter
+{
+ LOG_CLASS(LLAvatarAppearance);
+
+protected:
+ struct LLAvatarXmlInfo;
+
+/********************************************************************************
+ ** **
+ ** INITIALIZATION
+ **/
+private:
+ // Hide default constructor.
+ LLAvatarAppearance() {}
+
+public:
+ LLAvatarAppearance(LLWearableData* wearable_data);
+ virtual ~LLAvatarAppearance();
+
+ static void initClass(); // initializes static members
+ static void cleanupClass(); // Cleanup data that's only init'd once per class.
+ virtual void initInstance(); // Called after construction to initialize the instance.
+ virtual BOOL loadSkeletonNode();
+ BOOL loadMeshNodes();
+ BOOL loadLayersets();
+
+
+/** Initialization
+ ** **
+ *******************************************************************************/
+
+/********************************************************************************
+ ** **
+ ** INHERITED
+ **/
+
+ //--------------------------------------------------------------------
+ // LLCharacter interface and related
+ //--------------------------------------------------------------------
+public:
+ /*virtual*/ LLJoint* getCharacterJoint(U32 num);
+
+ /*virtual*/ const char* getAnimationPrefix() { return "avatar"; }
+ /*virtual*/ LLVector3 getVolumePos(S32 joint_index, LLVector3& volume_offset);
+ /*virtual*/ LLJoint* findCollisionVolume(U32 volume_id);
+ /*virtual*/ S32 getCollisionVolumeID(std::string &name);
+ /*virtual*/ LLPolyMesh* getHeadMesh();
+ /*virtual*/ LLPolyMesh* getUpperBodyMesh();
+
+/** Inherited
+ ** **
+ *******************************************************************************/
+
+/********************************************************************************
+ ** **
+ ** STATE
+ **/
+public:
+ virtual bool isSelf() const { return false; } // True if this avatar is for this viewer's agent
+ virtual BOOL isValid() const;
+ virtual BOOL isUsingServerBakes() const = 0;
+ virtual BOOL isUsingLocalAppearance() const = 0;
+ virtual BOOL isEditingAppearance() const = 0;
+
+ bool isBuilt() const { return mIsBuilt; }
+
+
+/** State
+ ** **
+ *******************************************************************************/
+
+/********************************************************************************
+ ** **
+ ** SKELETON
+ **/
+
+protected:
+ virtual LLAvatarJoint* createAvatarJoint() = 0;
+ virtual LLAvatarJoint* createAvatarJoint(S32 joint_num) = 0;
+ virtual LLAvatarJointMesh* createAvatarJointMesh() = 0;
+public:
+ F32 getPelvisToFoot() const { return mPelvisToFoot; }
+ /*virtual*/ LLJoint* getRootJoint() { return mRoot; }
+
+ LLVector3 mHeadOffset; // current head position
+ LLAvatarJoint *mRoot;
+
+ typedef std::map<std::string, LLJoint*> joint_map_t;
+ joint_map_t mJointMap;
+
+ void computeBodySize();
+
+
+protected:
+ static BOOL parseSkeletonFile(const std::string& filename);
+ virtual void buildCharacter();
+ virtual BOOL loadAvatar();
+ virtual void bodySizeChanged() = 0;
+
+ BOOL setupBone(const LLAvatarBoneInfo* info, LLJoint* parent, S32 &current_volume_num, S32 &current_joint_num);
+ BOOL allocateCharacterJoints(U32 num);
+ BOOL buildSkeleton(const LLAvatarSkeletonInfo *info);
+protected:
+ void clearSkeleton();
+ BOOL mIsBuilt; // state of deferred character building
+ typedef std::vector<LLAvatarJoint*> avatar_joint_list_t;
+ avatar_joint_list_t mSkeleton;
+
+ //--------------------------------------------------------------------
+ // Pelvis height adjustment members.
+ //--------------------------------------------------------------------
+public:
+ LLVector3 mBodySize;
+ LLVector3 mAvatarOffset;
+protected:
+ F32 mPelvisToFoot;
+
+ //--------------------------------------------------------------------
+ // Cached pointers to well known joints
+ //--------------------------------------------------------------------
+public:
+ LLJoint* mPelvisp;
+ LLJoint* mTorsop;
+ LLJoint* mChestp;
+ LLJoint* mNeckp;
+ LLJoint* mHeadp;
+ LLJoint* mSkullp;
+ LLJoint* mEyeLeftp;
+ LLJoint* mEyeRightp;
+ LLJoint* mHipLeftp;
+ LLJoint* mHipRightp;
+ LLJoint* mKneeLeftp;
+ LLJoint* mKneeRightp;
+ LLJoint* mAnkleLeftp;
+ LLJoint* mAnkleRightp;
+ LLJoint* mFootLeftp;
+ LLJoint* mFootRightp;
+ LLJoint* mWristLeftp;
+ LLJoint* mWristRightp;
+
+ //--------------------------------------------------------------------
+ // XML parse tree
+ //--------------------------------------------------------------------
+protected:
+ static LLXmlTree sXMLTree; // avatar config file
+ static LLXmlTree sSkeletonXMLTree; // avatar skeleton file
+
+ static LLAvatarSkeletonInfo* sAvatarSkeletonInfo;
+ static LLAvatarXmlInfo* sAvatarXmlInfo;
+
+
+/** Skeleton
+ ** **
+ *******************************************************************************/
+
+
+/********************************************************************************
+ ** **
+ ** RENDERING
+ **/
+public:
+ BOOL mIsDummy; // for special views
+
+ //--------------------------------------------------------------------
+ // Morph masks
+ //--------------------------------------------------------------------
+public:
+ void addMaskedMorph(LLAvatarAppearanceDefines::EBakedTextureIndex index, LLVisualParam* morph_target, BOOL invert, std::string layer);
+ virtual void applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_components, LLAvatarAppearanceDefines::EBakedTextureIndex index = LLAvatarAppearanceDefines::BAKED_NUM_INDICES) = 0;
+
+/** Rendering
+ ** **
+ *******************************************************************************/
+
+ //--------------------------------------------------------------------
+ // Composites
+ //--------------------------------------------------------------------
+public:
+ virtual void invalidateComposite(LLTexLayerSet* layerset, BOOL upload_result) = 0;
+
+/********************************************************************************
+ ** **
+ ** MESHES
+ **/
+
+public:
+ virtual void updateMeshTextures() = 0;
+ virtual void dirtyMesh() = 0; // Dirty the avatar mesh
+protected:
+ virtual void dirtyMesh(S32 priority) = 0; // Dirty the avatar mesh, with priority
+
+protected:
+ typedef std::multimap<std::string, LLPolyMesh*> polymesh_map_t;
+ polymesh_map_t mPolyMeshes;
+ avatar_joint_list_t mMeshLOD;
+
+/** Meshes
+ ** **
+ *******************************************************************************/
+
+/********************************************************************************
+ ** **
+ ** APPEARANCE
+ **/
+
+ //--------------------------------------------------------------------
+ // Clothing colors (convenience functions to access visual parameters)
+ //--------------------------------------------------------------------
+public:
+ void setClothesColor(LLAvatarAppearanceDefines::ETextureIndex te, const LLColor4& new_color, BOOL upload_bake);
+ LLColor4 getClothesColor(LLAvatarAppearanceDefines::ETextureIndex te);
+ static BOOL teToColorParams(LLAvatarAppearanceDefines::ETextureIndex te, U32 *param_name);
+
+ //--------------------------------------------------------------------
+ // Global colors
+ //--------------------------------------------------------------------
+public:
+ LLColor4 getGlobalColor(const std::string& color_name ) const;
+ virtual void onGlobalColorChanged(const LLTexGlobalColor* global_color, BOOL upload_bake) = 0;
+protected:
+ LLTexGlobalColor* mTexSkinColor;
+ LLTexGlobalColor* mTexHairColor;
+ LLTexGlobalColor* mTexEyeColor;
+
+ //--------------------------------------------------------------------
+ // Visibility
+ //--------------------------------------------------------------------
+public:
+ static LLColor4 getDummyColor();
+/** Appearance
+ ** **
+ *******************************************************************************/
+
+/********************************************************************************
+ ** **
+ ** WEARABLES
+ **/
+
+public:
+ LLWearableData* getWearableData() { return mWearableData; }
+ const LLWearableData* getWearableData() const { return mWearableData; }
+ virtual BOOL isTextureDefined(LLAvatarAppearanceDefines::ETextureIndex te, U32 index = 0 ) const = 0;
+ virtual BOOL isWearingWearableType(LLWearableType::EType type ) const;
+
+private:
+ LLWearableData* mWearableData;
+
+/********************************************************************************
+ ** **
+ ** BAKED TEXTURES
+ **/
+public:
+ LLTexLayerSet* getAvatarLayerSet(LLAvatarAppearanceDefines::EBakedTextureIndex baked_index) const;
+
+protected:
+ virtual LLTexLayerSet* createTexLayerSet() = 0;
+
+protected:
+ class LLMaskedMorph;
+ typedef std::deque<LLMaskedMorph *> morph_list_t;
+ struct BakedTextureData
+ {
+ LLUUID mLastTextureID;
+ LLTexLayerSet* mTexLayerSet; // Only exists for self
+ bool mIsLoaded;
+ bool mIsUsed;
+ LLAvatarAppearanceDefines::ETextureIndex mTextureIndex;
+ U32 mMaskTexName;
+ // Stores pointers to the joint meshes that this baked texture deals with
+ avatar_joint_mesh_list_t mJointMeshes;
+ morph_list_t mMaskedMorphs;
+ };
+ typedef std::vector<BakedTextureData> bakedtexturedata_vec_t;
+ bakedtexturedata_vec_t mBakedTextureDatas;
+
+/********************************************************************************
+ ** **
+ ** PHYSICS
+ **/
+
+ //--------------------------------------------------------------------
+ // Collision volumes
+ //--------------------------------------------------------------------
+public:
+ S32 mNumCollisionVolumes;
+ LLAvatarJointCollisionVolume* mCollisionVolumes;
+protected:
+ BOOL allocateCollisionVolumes(U32 num);
+
+/** Physics
+ ** **
+ *******************************************************************************/
+
+/********************************************************************************
+ ** **
+ ** SUPPORT CLASSES
+ **/
+
+ struct LLAvatarXmlInfo
+ {
+ LLAvatarXmlInfo();
+ ~LLAvatarXmlInfo();
+
+ BOOL parseXmlSkeletonNode(LLXmlTreeNode* root);
+ BOOL parseXmlMeshNodes(LLXmlTreeNode* root);
+ BOOL parseXmlColorNodes(LLXmlTreeNode* root);
+ BOOL parseXmlLayerNodes(LLXmlTreeNode* root);
+ BOOL parseXmlDriverNodes(LLXmlTreeNode* root);
+ BOOL parseXmlMorphNodes(LLXmlTreeNode* root);
+
+ struct LLAvatarMeshInfo
+ {
+ typedef std::pair<LLViewerVisualParamInfo*,BOOL> morph_info_pair_t; // LLPolyMorphTargetInfo stored here
+ typedef std::vector<morph_info_pair_t> morph_info_list_t;
+
+ LLAvatarMeshInfo() : mLOD(0), mMinPixelArea(.1f) {}
+ ~LLAvatarMeshInfo()
+ {
+ morph_info_list_t::iterator iter;
+ for (iter = mPolyMorphTargetInfoList.begin(); iter != mPolyMorphTargetInfoList.end(); iter++)
+ {
+ delete iter->first;
+ }
+ mPolyMorphTargetInfoList.clear();
+ }
+
+ std::string mType;
+ S32 mLOD;
+ std::string mMeshFileName;
+ std::string mReferenceMeshName;
+ F32 mMinPixelArea;
+ morph_info_list_t mPolyMorphTargetInfoList;
+ };
+ typedef std::vector<LLAvatarMeshInfo*> mesh_info_list_t;
+ mesh_info_list_t mMeshInfoList;
+
+ typedef std::vector<LLViewerVisualParamInfo*> skeletal_distortion_info_list_t; // LLPolySkeletalDistortionInfo stored here
+ skeletal_distortion_info_list_t mSkeletalDistortionInfoList;
+
+ struct LLAvatarAttachmentInfo
+ {
+ LLAvatarAttachmentInfo()
+ : mGroup(-1), mAttachmentID(-1), mPieMenuSlice(-1), mVisibleFirstPerson(FALSE),
+ mIsHUDAttachment(FALSE), mHasPosition(FALSE), mHasRotation(FALSE) {}
+ std::string mName;
+ std::string mJointName;
+ LLVector3 mPosition;
+ LLVector3 mRotationEuler;
+ S32 mGroup;
+ S32 mAttachmentID;
+ S32 mPieMenuSlice;
+ BOOL mVisibleFirstPerson;
+ BOOL mIsHUDAttachment;
+ BOOL mHasPosition;
+ BOOL mHasRotation;
+ };
+ typedef std::vector<LLAvatarAttachmentInfo*> attachment_info_list_t;
+ attachment_info_list_t mAttachmentInfoList;
+
+ LLTexGlobalColorInfo *mTexSkinColorInfo;
+ LLTexGlobalColorInfo *mTexHairColorInfo;
+ LLTexGlobalColorInfo *mTexEyeColorInfo;
+
+ typedef std::vector<LLTexLayerSetInfo*> layer_info_list_t;
+ layer_info_list_t mLayerInfoList;
+
+ typedef std::vector<LLDriverParamInfo*> driver_info_list_t;
+ driver_info_list_t mDriverInfoList;
+
+ struct LLAvatarMorphInfo
+ {
+ LLAvatarMorphInfo()
+ : mInvert(FALSE) {}
+ std::string mName;
+ std::string mRegion;
+ std::string mLayer;
+ BOOL mInvert;
+ };
+
+ typedef std::vector<LLAvatarMorphInfo*> morph_info_list_t;
+ morph_info_list_t mMorphMaskInfoList;
+ };
+
+
+ class LLMaskedMorph
+ {
+ public:
+ LLMaskedMorph(LLVisualParam *morph_target, BOOL invert, std::string layer);
+
+ LLVisualParam *mMorphTarget;
+ BOOL mInvert;
+ std::string mLayer;
+ };
+/** Support Classes
+ ** **
+ *******************************************************************************/
+};
+
+#endif // LL_AVATAR_APPEARANCE_H
diff --git a/indra/llappearance/llavatarappearancedefines.cpp b/indra/llappearance/llavatarappearancedefines.cpp
new file mode 100644
index 0000000000..f1c78946a1
--- /dev/null
+++ b/indra/llappearance/llavatarappearancedefines.cpp
@@ -0,0 +1,268 @@
+/**
+ * @file llavatarappearancedefines.cpp
+ * @brief Implementation of LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary
+ *
+ * $LicenseInfo:firstyear=2001&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 "llavatarappearancedefines.h"
+
+const S32 LLAvatarAppearanceDefines::SCRATCH_TEX_WIDTH = 512;
+const S32 LLAvatarAppearanceDefines::SCRATCH_TEX_HEIGHT = 512;
+const S32 LLAvatarAppearanceDefines::IMPOSTOR_PERIOD = 2;
+
+using namespace LLAvatarAppearanceDefines;
+
+/*********************************************************************************
+ * Edit this function to add/remove/change textures and mesh definitions for avatars.
+ */
+
+LLAvatarAppearanceDictionary::Textures::Textures()
+{
+ addEntry(TEX_HEAD_BODYPAINT, new TextureEntry("head_bodypaint", TRUE, BAKED_NUM_INDICES, "", LLWearableType::WT_SKIN));
+ addEntry(TEX_UPPER_SHIRT, new TextureEntry("upper_shirt", TRUE, BAKED_NUM_INDICES, "UIImgDefaultShirtUUID", LLWearableType::WT_SHIRT));
+ addEntry(TEX_LOWER_PANTS, new TextureEntry("lower_pants", TRUE, BAKED_NUM_INDICES, "UIImgDefaultPantsUUID", LLWearableType::WT_PANTS));
+ addEntry(TEX_EYES_IRIS, new TextureEntry("eyes_iris", TRUE, BAKED_NUM_INDICES, "UIImgDefaultEyesUUID", LLWearableType::WT_EYES));
+ addEntry(TEX_HAIR, new TextureEntry("hair_grain", TRUE, BAKED_NUM_INDICES, "UIImgDefaultHairUUID", LLWearableType::WT_HAIR));
+ addEntry(TEX_UPPER_BODYPAINT, new TextureEntry("upper_bodypaint", TRUE, BAKED_NUM_INDICES, "", LLWearableType::WT_SKIN));
+ addEntry(TEX_LOWER_BODYPAINT, new TextureEntry("lower_bodypaint", TRUE, BAKED_NUM_INDICES, "", LLWearableType::WT_SKIN));
+ addEntry(TEX_LOWER_SHOES, new TextureEntry("lower_shoes", TRUE, BAKED_NUM_INDICES, "UIImgDefaultShoesUUID", LLWearableType::WT_SHOES));
+ addEntry(TEX_LOWER_SOCKS, new TextureEntry("lower_socks", TRUE, BAKED_NUM_INDICES, "UIImgDefaultSocksUUID", LLWearableType::WT_SOCKS));
+ addEntry(TEX_UPPER_JACKET, new TextureEntry("upper_jacket", TRUE, BAKED_NUM_INDICES, "UIImgDefaultJacketUUID", LLWearableType::WT_JACKET));
+ addEntry(TEX_LOWER_JACKET, new TextureEntry("lower_jacket", TRUE, BAKED_NUM_INDICES, "UIImgDefaultJacketUUID", LLWearableType::WT_JACKET));
+ addEntry(TEX_UPPER_GLOVES, new TextureEntry("upper_gloves", TRUE, BAKED_NUM_INDICES, "UIImgDefaultGlovesUUID", LLWearableType::WT_GLOVES));
+ addEntry(TEX_UPPER_UNDERSHIRT, new TextureEntry("upper_undershirt", TRUE, BAKED_NUM_INDICES, "UIImgDefaultUnderwearUUID", LLWearableType::WT_UNDERSHIRT));
+ addEntry(TEX_LOWER_UNDERPANTS, new TextureEntry("lower_underpants", TRUE, BAKED_NUM_INDICES, "UIImgDefaultUnderwearUUID", LLWearableType::WT_UNDERPANTS));
+ addEntry(TEX_SKIRT, new TextureEntry("skirt", TRUE, BAKED_NUM_INDICES, "UIImgDefaultSkirtUUID", LLWearableType::WT_SKIRT));
+
+ addEntry(TEX_LOWER_ALPHA, new TextureEntry("lower_alpha", TRUE, BAKED_NUM_INDICES, "UIImgDefaultAlphaUUID", LLWearableType::WT_ALPHA));
+ addEntry(TEX_UPPER_ALPHA, new TextureEntry("upper_alpha", TRUE, BAKED_NUM_INDICES, "UIImgDefaultAlphaUUID", LLWearableType::WT_ALPHA));
+ addEntry(TEX_HEAD_ALPHA, new TextureEntry("head_alpha", TRUE, BAKED_NUM_INDICES, "UIImgDefaultAlphaUUID", LLWearableType::WT_ALPHA));
+ addEntry(TEX_EYES_ALPHA, new TextureEntry("eyes_alpha", TRUE, BAKED_NUM_INDICES, "UIImgDefaultAlphaUUID", LLWearableType::WT_ALPHA));
+ addEntry(TEX_HAIR_ALPHA, new TextureEntry("hair_alpha", TRUE, BAKED_NUM_INDICES, "UIImgDefaultAlphaUUID", LLWearableType::WT_ALPHA));
+
+ addEntry(TEX_HEAD_TATTOO, new TextureEntry("head_tattoo", TRUE, BAKED_NUM_INDICES, "", LLWearableType::WT_TATTOO));
+ addEntry(TEX_UPPER_TATTOO, new TextureEntry("upper_tattoo", TRUE, BAKED_NUM_INDICES, "", LLWearableType::WT_TATTOO));
+ addEntry(TEX_LOWER_TATTOO, new TextureEntry("lower_tattoo", TRUE, BAKED_NUM_INDICES, "", LLWearableType::WT_TATTOO));
+
+ addEntry(TEX_HEAD_BAKED, new TextureEntry("head-baked", FALSE, BAKED_HEAD, "head"));
+ addEntry(TEX_UPPER_BAKED, new TextureEntry("upper-baked", FALSE, BAKED_UPPER, "upper"));
+ addEntry(TEX_LOWER_BAKED, new TextureEntry("lower-baked", FALSE, BAKED_LOWER, "lower"));
+ addEntry(TEX_EYES_BAKED, new TextureEntry("eyes-baked", FALSE, BAKED_EYES, "eyes"));
+ addEntry(TEX_HAIR_BAKED, new TextureEntry("hair-baked", FALSE, BAKED_HAIR, "hair"));
+ addEntry(TEX_SKIRT_BAKED, new TextureEntry("skirt-baked", FALSE, BAKED_SKIRT, "skirt"));
+}
+
+LLAvatarAppearanceDictionary::BakedTextures::BakedTextures()
+{
+ // Baked textures
+ addEntry(BAKED_HEAD, new BakedEntry(TEX_HEAD_BAKED,
+ "head", "a4b9dc38-e13b-4df9-b284-751efb0566ff",
+ 3, TEX_HEAD_BODYPAINT, TEX_HEAD_TATTOO, TEX_HEAD_ALPHA,
+ 5, LLWearableType::WT_SHAPE, LLWearableType::WT_SKIN, LLWearableType::WT_HAIR, LLWearableType::WT_TATTOO, LLWearableType::WT_ALPHA));
+
+ addEntry(BAKED_UPPER, new BakedEntry(TEX_UPPER_BAKED,
+ "upper_body", "5943ff64-d26c-4a90-a8c0-d61f56bd98d4",
+ 7, TEX_UPPER_SHIRT,TEX_UPPER_BODYPAINT, TEX_UPPER_JACKET,
+ TEX_UPPER_GLOVES, TEX_UPPER_UNDERSHIRT, TEX_UPPER_TATTOO, TEX_UPPER_ALPHA,
+ 8, LLWearableType::WT_SHAPE, LLWearableType::WT_SKIN, LLWearableType::WT_SHIRT, LLWearableType::WT_JACKET, LLWearableType::WT_GLOVES, LLWearableType::WT_UNDERSHIRT, LLWearableType::WT_TATTOO, LLWearableType::WT_ALPHA));
+
+ addEntry(BAKED_LOWER, new BakedEntry(TEX_LOWER_BAKED,
+ "lower_body", "2944ee70-90a7-425d-a5fb-d749c782ed7d",
+ 8, TEX_LOWER_PANTS,TEX_LOWER_BODYPAINT,TEX_LOWER_SHOES, TEX_LOWER_SOCKS,
+ TEX_LOWER_JACKET, TEX_LOWER_UNDERPANTS, TEX_LOWER_TATTOO, TEX_LOWER_ALPHA,
+ 9, LLWearableType::WT_SHAPE, LLWearableType::WT_SKIN, LLWearableType::WT_PANTS, LLWearableType::WT_SHOES, LLWearableType::WT_SOCKS, LLWearableType::WT_JACKET, LLWearableType::WT_UNDERPANTS, LLWearableType::WT_TATTOO, LLWearableType::WT_ALPHA));
+
+ addEntry(BAKED_EYES, new BakedEntry(TEX_EYES_BAKED,
+ "eyes", "27b1bc0f-979f-4b13-95fe-b981c2ba9788",
+ 2, TEX_EYES_IRIS, TEX_EYES_ALPHA,
+ 2, LLWearableType::WT_EYES, LLWearableType::WT_ALPHA));
+
+ addEntry(BAKED_SKIRT, new BakedEntry(TEX_SKIRT_BAKED,
+ "skirt", "03e7e8cb-1368-483b-b6f3-74850838ba63",
+ 1, TEX_SKIRT,
+ 1, LLWearableType::WT_SKIRT));
+
+ addEntry(BAKED_HAIR, new BakedEntry(TEX_HAIR_BAKED,
+ "hair", "a60e85a9-74e8-48d8-8a2d-8129f28d9b61",
+ 2, TEX_HAIR, TEX_HAIR_ALPHA,
+ 2, LLWearableType::WT_HAIR, LLWearableType::WT_ALPHA));
+}
+
+LLAvatarAppearanceDictionary::MeshEntries::MeshEntries()
+{
+ // MeshEntries
+ addEntry(MESH_ID_HAIR, new MeshEntry(BAKED_HAIR, "hairMesh", 6, PN_4));
+ addEntry(MESH_ID_HEAD, new MeshEntry(BAKED_HEAD, "headMesh", 5, PN_5));
+ addEntry(MESH_ID_EYELASH, new MeshEntry(BAKED_HEAD, "eyelashMesh", 1, PN_0)); // no baked mesh associated currently
+ addEntry(MESH_ID_UPPER_BODY, new MeshEntry(BAKED_UPPER, "upperBodyMesh", 5, PN_1));
+ addEntry(MESH_ID_LOWER_BODY, new MeshEntry(BAKED_LOWER, "lowerBodyMesh", 5, PN_2));
+ addEntry(MESH_ID_EYEBALL_LEFT, new MeshEntry(BAKED_EYES, "eyeBallLeftMesh", 2, PN_3));
+ addEntry(MESH_ID_EYEBALL_RIGHT, new MeshEntry(BAKED_EYES, "eyeBallRightMesh", 2, PN_3));
+ addEntry(MESH_ID_SKIRT, new MeshEntry(BAKED_SKIRT, "skirtMesh", 5, PN_5));
+}
+
+/*
+ *
+ *********************************************************************************/
+
+LLAvatarAppearanceDictionary::LLAvatarAppearanceDictionary()
+{
+ createAssociations();
+}
+
+//virtual
+LLAvatarAppearanceDictionary::~LLAvatarAppearanceDictionary()
+{
+}
+
+// Baked textures are composites of textures; for each such composited texture,
+// map it to the baked texture.
+void LLAvatarAppearanceDictionary::createAssociations()
+{
+ for (BakedTextures::const_iterator iter = mBakedTextures.begin(); iter != mBakedTextures.end(); iter++)
+ {
+ const EBakedTextureIndex baked_index = (iter->first);
+ const BakedEntry *dict = (iter->second);
+
+ // For each texture that this baked texture index affects, associate those textures
+ // with this baked texture index.
+ for (texture_vec_t::const_iterator local_texture_iter = dict->mLocalTextures.begin();
+ local_texture_iter != dict->mLocalTextures.end();
+ local_texture_iter++)
+ {
+ const ETextureIndex local_texture_index = (ETextureIndex) *local_texture_iter;
+ mTextures[local_texture_index]->mIsUsedByBakedTexture = true;
+ mTextures[local_texture_index]->mBakedTextureIndex = baked_index;
+ }
+ }
+
+}
+
+LLAvatarAppearanceDictionary::TextureEntry::TextureEntry(const std::string &name,
+ bool is_local_texture,
+ EBakedTextureIndex baked_texture_index,
+ const std::string &default_image_name,
+ LLWearableType::EType wearable_type) :
+ LLDictionaryEntry(name),
+ mIsLocalTexture(is_local_texture),
+ mIsBakedTexture(!is_local_texture),
+ mIsUsedByBakedTexture(baked_texture_index != BAKED_NUM_INDICES),
+ mBakedTextureIndex(baked_texture_index),
+ mDefaultImageName(default_image_name),
+ mWearableType(wearable_type)
+{
+}
+
+LLAvatarAppearanceDictionary::MeshEntry::MeshEntry(EBakedTextureIndex baked_index,
+ const std::string &name,
+ U8 level,
+ LLJointPickName pick) :
+ LLDictionaryEntry(name),
+ mBakedID(baked_index),
+ mLOD(level),
+ mPickName(pick)
+{
+}
+LLAvatarAppearanceDictionary::BakedEntry::BakedEntry(ETextureIndex tex_index,
+ const std::string &name,
+ const std::string &hash_name,
+ U32 num_local_textures,
+ ... ) :
+ LLDictionaryEntry(name),
+ mWearablesHashID(LLUUID(hash_name)),
+ mTextureIndex(tex_index)
+{
+ va_list argp;
+
+ va_start(argp, num_local_textures);
+
+ // Read in local textures
+ for (U8 i=0; i < num_local_textures; i++)
+ {
+ ETextureIndex t = (ETextureIndex)va_arg(argp,int);
+ mLocalTextures.push_back(t);
+ }
+
+ // Read in number of wearables
+ const U32 num_wearables = (U32)va_arg(argp,int);
+ // Read in wearables
+ for (U8 i=0; i < num_wearables; i++)
+ {
+ LLWearableType::EType t = (LLWearableType::EType)va_arg(argp,int);
+ mWearables.push_back(t);
+ }
+}
+
+// static
+ETextureIndex LLAvatarAppearanceDictionary::bakedToLocalTextureIndex(EBakedTextureIndex index)
+{
+ return LLAvatarAppearanceDictionary::getInstance()->getBakedTexture(index)->mTextureIndex;
+}
+
+// static
+EBakedTextureIndex LLAvatarAppearanceDictionary::findBakedByRegionName(std::string name)
+{
+ U8 index = 0;
+ while (index < BAKED_NUM_INDICES)
+ {
+ const BakedEntry *be = LLAvatarAppearanceDictionary::getInstance()->getBakedTexture((EBakedTextureIndex) index);
+ if (be && be->mName.compare(name) == 0)
+ {
+ // baked texture found
+ return (EBakedTextureIndex) index;
+ }
+ index++;
+ }
+ // baked texture could not be found
+ return BAKED_NUM_INDICES;
+}
+
+// static
+EBakedTextureIndex LLAvatarAppearanceDictionary::findBakedByImageName(std::string name)
+{
+ U8 index = 0;
+ while (index < BAKED_NUM_INDICES)
+ {
+ const BakedEntry *be = LLAvatarAppearanceDictionary::getInstance()->getBakedTexture((EBakedTextureIndex) index);
+ if (be)
+ {
+ const TextureEntry *te = LLAvatarAppearanceDictionary::getInstance()->getTexture(be->mTextureIndex);
+ if (te && te->mDefaultImageName.compare(name) == 0)
+ {
+ // baked texture found
+ return (EBakedTextureIndex) index;
+ }
+ }
+ index++;
+ }
+ // baked texture could not be found
+ return BAKED_NUM_INDICES;
+}
+
+// static
+LLWearableType::EType LLAvatarAppearanceDictionary::getTEWearableType(ETextureIndex index )
+{
+ return getInstance()->getTexture(index)->mWearableType;
+}
+
diff --git a/indra/llappearance/llavatarappearancedefines.h b/indra/llappearance/llavatarappearancedefines.h
new file mode 100644
index 0000000000..8a1d2c4707
--- /dev/null
+++ b/indra/llappearance/llavatarappearancedefines.h
@@ -0,0 +1,231 @@
+/**
+ * @file llavatarappearancedefines.h
+ * @brief Various LLAvatarAppearance related definitions
+ * LLViewerObject
+ *
+ * $LicenseInfo:firstyear=2001&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$
+ */
+
+#ifndef LL_AVATARAPPEARANCE_DEFINES_H
+#define LL_AVATARAPPEARANCE_DEFINES_H
+
+#include <vector>
+#include "lljointpickname.h"
+#include "lldictionary.h"
+#include "llwearabletype.h"
+#include "lluuid.h"
+
+namespace LLAvatarAppearanceDefines
+{
+
+extern const S32 SCRATCH_TEX_WIDTH;
+extern const S32 SCRATCH_TEX_HEIGHT;
+extern const S32 IMPOSTOR_PERIOD;
+
+static const U32 AVATAR_HOVER = 11001;
+
+//--------------------------------------------------------------------
+// Enums
+//--------------------------------------------------------------------
+enum ETextureIndex
+{
+ TEX_INVALID = -1,
+ TEX_HEAD_BODYPAINT = 0,
+ TEX_UPPER_SHIRT,
+ TEX_LOWER_PANTS,
+ TEX_EYES_IRIS,
+ TEX_HAIR,
+ TEX_UPPER_BODYPAINT,
+ TEX_LOWER_BODYPAINT,
+ TEX_LOWER_SHOES,
+ TEX_HEAD_BAKED, // Pre-composited
+ TEX_UPPER_BAKED, // Pre-composited
+ TEX_LOWER_BAKED, // Pre-composited
+ TEX_EYES_BAKED, // Pre-composited
+ TEX_LOWER_SOCKS,
+ TEX_UPPER_JACKET,
+ TEX_LOWER_JACKET,
+ TEX_UPPER_GLOVES,
+ TEX_UPPER_UNDERSHIRT,
+ TEX_LOWER_UNDERPANTS,
+ TEX_SKIRT,
+ TEX_SKIRT_BAKED, // Pre-composited
+ TEX_HAIR_BAKED, // Pre-composited
+ TEX_LOWER_ALPHA,
+ TEX_UPPER_ALPHA,
+ TEX_HEAD_ALPHA,
+ TEX_EYES_ALPHA,
+ TEX_HAIR_ALPHA,
+ TEX_HEAD_TATTOO,
+ TEX_UPPER_TATTOO,
+ TEX_LOWER_TATTOO,
+ TEX_NUM_INDICES
+};
+
+enum EBakedTextureIndex
+{
+ BAKED_HEAD = 0,
+ BAKED_UPPER,
+ BAKED_LOWER,
+ BAKED_EYES,
+ BAKED_SKIRT,
+ BAKED_HAIR,
+ BAKED_NUM_INDICES
+};
+
+// Reference IDs for each mesh. Used as indices for vector of joints
+enum EMeshIndex
+{
+ MESH_ID_HAIR = 0,
+ MESH_ID_HEAD,
+ MESH_ID_EYELASH,
+ MESH_ID_UPPER_BODY,
+ MESH_ID_LOWER_BODY,
+ MESH_ID_EYEBALL_LEFT,
+ MESH_ID_EYEBALL_RIGHT,
+ MESH_ID_SKIRT,
+ MESH_ID_NUM_INDICES
+};
+
+//--------------------------------------------------------------------
+// Vector Types
+//--------------------------------------------------------------------
+typedef std::vector<ETextureIndex> texture_vec_t;
+typedef std::vector<EBakedTextureIndex> bakedtexture_vec_t;
+typedef std::vector<EMeshIndex> mesh_vec_t;
+typedef std::vector<LLWearableType::EType> wearables_vec_t;
+
+//------------------------------------------------------------------------
+// LLAvatarAppearanceDictionary
+//
+// Holds dictionary static entries for textures, baked textures, meshes, etc.; i.e.
+// information that is common to all avatars.
+//
+// This holds const data - it is initialized once and the contents never change after that.
+//------------------------------------------------------------------------
+class LLAvatarAppearanceDictionary : public LLSingleton<LLAvatarAppearanceDictionary>
+{
+ //--------------------------------------------------------------------
+ // Constructors and Destructors
+ //--------------------------------------------------------------------
+public:
+ LLAvatarAppearanceDictionary();
+ virtual ~LLAvatarAppearanceDictionary();
+private:
+ void createAssociations();
+
+ //--------------------------------------------------------------------
+ // Local and baked textures
+ //--------------------------------------------------------------------
+public:
+ struct TextureEntry : public LLDictionaryEntry
+ {
+ TextureEntry(const std::string &name, // this must match the xml name used by LLTexLayerInfo::parseXml
+ bool is_local_texture,
+ EBakedTextureIndex baked_texture_index = BAKED_NUM_INDICES,
+ const std::string& default_image_name = "",
+ LLWearableType::EType wearable_type = LLWearableType::WT_INVALID);
+ const std::string mDefaultImageName;
+ const LLWearableType::EType mWearableType;
+ // It's either a local texture xor baked
+ BOOL mIsLocalTexture;
+ BOOL mIsBakedTexture;
+ // If it's a local texture, it may be used by a baked texture
+ BOOL mIsUsedByBakedTexture;
+ EBakedTextureIndex mBakedTextureIndex;
+ };
+
+ struct Textures : public LLDictionary<ETextureIndex, TextureEntry>
+ {
+ Textures();
+ } mTextures;
+ const TextureEntry* getTexture(ETextureIndex index) const { return mTextures.lookup(index); }
+ const Textures& getTextures() const { return mTextures; }
+
+ //--------------------------------------------------------------------
+ // Meshes
+ //--------------------------------------------------------------------
+public:
+ struct MeshEntry : public LLDictionaryEntry
+ {
+ MeshEntry(EBakedTextureIndex baked_index,
+ const std::string &name, // names of mesh types as they are used in avatar_lad.xml
+ U8 level,
+ LLJointPickName pick);
+ // Levels of Detail for each mesh. Must match levels of detail present in avatar_lad.xml
+ // Otherwise meshes will be unable to be found, or levels of detail will be ignored
+ const U8 mLOD;
+ const EBakedTextureIndex mBakedID;
+ const LLJointPickName mPickName;
+ };
+
+ struct MeshEntries : public LLDictionary<EMeshIndex, MeshEntry>
+ {
+ MeshEntries();
+ } mMeshEntries;
+ const MeshEntry* getMeshEntry(EMeshIndex index) const { return mMeshEntries.lookup(index); }
+ const MeshEntries& getMeshEntries() const { return mMeshEntries; }
+
+ //--------------------------------------------------------------------
+ // Baked Textures
+ //--------------------------------------------------------------------
+public:
+ struct BakedEntry : public LLDictionaryEntry
+ {
+ BakedEntry(ETextureIndex tex_index,
+ const std::string &name, // unused, but necessary for templating.
+ const std::string &hash_name,
+ U32 num_local_textures, ... ); // # local textures, local texture list, # wearables, wearable list
+ // Local Textures
+ const ETextureIndex mTextureIndex;
+ texture_vec_t mLocalTextures;
+ // Wearables
+ const LLUUID mWearablesHashID;
+ wearables_vec_t mWearables;
+ };
+
+ struct BakedTextures: public LLDictionary<EBakedTextureIndex, BakedEntry>
+ {
+ BakedTextures();
+ } mBakedTextures;
+ const BakedEntry* getBakedTexture(EBakedTextureIndex index) const { return mBakedTextures.lookup(index); }
+ const BakedTextures& getBakedTextures() const { return mBakedTextures; }
+
+ //--------------------------------------------------------------------
+ // Convenience Functions
+ //--------------------------------------------------------------------
+public:
+ // Convert from baked texture to associated texture; e.g. BAKED_HEAD -> TEX_HEAD_BAKED
+ static ETextureIndex bakedToLocalTextureIndex(EBakedTextureIndex t);
+
+ // find a baked texture index based on its name
+ static EBakedTextureIndex findBakedByRegionName(std::string name);
+ static EBakedTextureIndex findBakedByImageName(std::string name);
+
+ // Given a texture entry, determine which wearable type owns it.
+ static LLWearableType::EType getTEWearableType(ETextureIndex index);
+
+}; // End LLAvatarAppearanceDictionary
+
+} // End namespace LLAvatarAppearanceDefines
+
+#endif //LL_AVATARAPPEARANCE_DEFINES_H
diff --git a/indra/llappearance/llavatarjoint.cpp b/indra/llappearance/llavatarjoint.cpp
new file mode 100644
index 0000000000..6ab341af64
--- /dev/null
+++ b/indra/llappearance/llavatarjoint.cpp
@@ -0,0 +1,326 @@
+/**
+ * @file llavatarjoint.cpp
+ * @brief Implementation of LLAvatarJoint class
+ *
+ * $LicenseInfo:firstyear=2001&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$
+ */
+
+//-----------------------------------------------------------------------------
+// Header Files
+//-----------------------------------------------------------------------------
+#include "llavatarjoint.h"
+
+#include "llgl.h"
+#include "llrender.h"
+#include "llmath.h"
+#include "llglheaders.h"
+#include "llavatarappearance.h"
+
+const F32 DEFAULT_AVATAR_JOINT_LOD = 0.0f;
+
+//-----------------------------------------------------------------------------
+// Static Data
+//-----------------------------------------------------------------------------
+BOOL LLAvatarJoint::sDisableLOD = FALSE;
+
+//-----------------------------------------------------------------------------
+// LLAvatarJoint()
+// Class Constructors
+//-----------------------------------------------------------------------------
+LLAvatarJoint::LLAvatarJoint() :
+ LLJoint()
+{
+ init();
+}
+
+LLAvatarJoint::LLAvatarJoint(const std::string &name, LLJoint *parent) :
+ LLJoint(name, parent)
+{
+ init();
+}
+
+LLAvatarJoint::LLAvatarJoint(S32 joint_num) :
+ LLJoint(joint_num)
+{
+ init();
+}
+
+
+void LLAvatarJoint::init()
+{
+ mValid = FALSE;
+ mComponents = SC_JOINT | SC_BONE | SC_AXES;
+ mMinPixelArea = DEFAULT_AVATAR_JOINT_LOD;
+ mPickName = PN_DEFAULT;
+ mVisible = TRUE;
+ mMeshID = 0;
+ mIsTransparent = FALSE;
+}
+
+
+//-----------------------------------------------------------------------------
+// ~LLAvatarJoint()
+// Class Destructor
+//-----------------------------------------------------------------------------
+LLAvatarJoint::~LLAvatarJoint()
+{
+}
+
+
+//--------------------------------------------------------------------
+// setValid()
+//--------------------------------------------------------------------
+void LLAvatarJoint::setValid( BOOL valid, BOOL recursive )
+{
+ //----------------------------------------------------------------
+ // set visibility for this joint
+ //----------------------------------------------------------------
+ mValid = valid;
+
+ //----------------------------------------------------------------
+ // set visibility for children
+ //----------------------------------------------------------------
+ if (recursive)
+ {
+ for (child_list_t::iterator iter = mChildren.begin();
+ iter != mChildren.end(); ++iter)
+ {
+ LLAvatarJoint* joint = (LLAvatarJoint*)(*iter);
+ joint->setValid(valid, TRUE);
+ }
+ }
+
+}
+
+//--------------------------------------------------------------------
+// setSkeletonComponents()
+//--------------------------------------------------------------------
+void LLAvatarJoint::setSkeletonComponents( U32 comp, BOOL recursive )
+{
+ mComponents = comp;
+ if (recursive)
+ {
+ for (child_list_t::iterator iter = mChildren.begin();
+ iter != mChildren.end(); ++iter)
+ {
+ LLAvatarJoint* joint = dynamic_cast<LLAvatarJoint*>(*iter);
+ joint->setSkeletonComponents(comp, recursive);
+ }
+ }
+}
+
+void LLAvatarJoint::setVisible(BOOL visible, BOOL recursive)
+{
+ mVisible = visible;
+
+ if (recursive)
+ {
+ for (child_list_t::iterator iter = mChildren.begin();
+ iter != mChildren.end(); ++iter)
+ {
+ LLAvatarJoint* joint = (LLAvatarJoint*)(*iter);
+ joint->setVisible(visible, recursive);
+ }
+ }
+}
+
+void LLAvatarJoint::updateFaceSizes(U32 &num_vertices, U32& num_indices, F32 pixel_area)
+{
+ for (child_list_t::iterator iter = mChildren.begin();
+ iter != mChildren.end(); ++iter)
+ {
+ LLAvatarJoint* joint = dynamic_cast<LLAvatarJoint*>(*iter);
+ joint->updateFaceSizes(num_vertices, num_indices, pixel_area);
+ }
+}
+
+void LLAvatarJoint::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind, bool terse_update)
+{
+ for (child_list_t::iterator iter = mChildren.begin();
+ iter != mChildren.end(); ++iter)
+ {
+ LLAvatarJoint* joint = dynamic_cast<LLAvatarJoint*>(*iter);
+ joint->updateFaceData(face, pixel_area, damp_wind, terse_update);
+ }
+}
+
+void LLAvatarJoint::updateJointGeometry()
+{
+ for (child_list_t::iterator iter = mChildren.begin();
+ iter != mChildren.end(); ++iter)
+ {
+ LLAvatarJoint* joint = dynamic_cast<LLAvatarJoint*>(*iter);
+ joint->updateJointGeometry();
+ }
+}
+
+
+BOOL LLAvatarJoint::updateLOD(F32 pixel_area, BOOL activate)
+{
+ BOOL lod_changed = FALSE;
+ BOOL found_lod = FALSE;
+
+ for (child_list_t::iterator iter = mChildren.begin();
+ iter != mChildren.end(); ++iter)
+ {
+ LLAvatarJoint* joint = dynamic_cast<LLAvatarJoint*>(*iter);
+ F32 jointLOD = joint->getLOD();
+
+ if (found_lod || jointLOD == DEFAULT_AVATAR_JOINT_LOD)
+ {
+ // we've already found a joint to enable, so enable the rest as alternatives
+ lod_changed |= joint->updateLOD(pixel_area, TRUE);
+ }
+ else
+ {
+ if (pixel_area >= jointLOD || sDisableLOD)
+ {
+ lod_changed |= joint->updateLOD(pixel_area, TRUE);
+ found_lod = TRUE;
+ }
+ else
+ {
+ lod_changed |= joint->updateLOD(pixel_area, FALSE);
+ }
+ }
+ }
+ return lod_changed;
+}
+
+void LLAvatarJoint::dump()
+{
+ for (child_list_t::iterator iter = mChildren.begin();
+ iter != mChildren.end(); ++iter)
+ {
+ LLAvatarJoint* joint = dynamic_cast<LLAvatarJoint*>(*iter);
+ joint->dump();
+ }
+}
+
+
+void LLAvatarJoint::setMeshesToChildren()
+{
+ removeAllChildren();
+ for (avatar_joint_mesh_list_t::iterator iter = mMeshParts.begin();
+ iter != mMeshParts.end(); iter++)
+ {
+ addChild((*iter));
+ }
+}
+//-----------------------------------------------------------------------------
+// LLAvatarJointCollisionVolume()
+//-----------------------------------------------------------------------------
+
+LLAvatarJointCollisionVolume::LLAvatarJointCollisionVolume()
+{
+ mUpdateXform = FALSE;
+}
+
+/*virtual*/
+U32 LLAvatarJointCollisionVolume::render( F32 pixelArea, BOOL first_pass, BOOL is_dummy )
+{
+ llerrs << "Cannot call render() on LLAvatarJointCollisionVolume" << llendl;
+ return 0;
+}
+
+LLVector3 LLAvatarJointCollisionVolume::getVolumePos(LLVector3 &offset)
+{
+ mUpdateXform = TRUE;
+
+ LLVector3 result = offset;
+ result.scaleVec(getScale());
+ result.rotVec(getWorldRotation());
+ result += getWorldPosition();
+
+ return result;
+}
+
+void LLAvatarJointCollisionVolume::renderCollision()
+{
+ updateWorldMatrix();
+
+ gGL.pushMatrix();
+ gGL.multMatrix( &mXform.getWorldMatrix().mMatrix[0][0] );
+
+ gGL.diffuseColor3f( 0.f, 0.f, 1.f );
+
+ gGL.begin(LLRender::LINES);
+
+ LLVector3 v[] =
+ {
+ LLVector3(1,0,0),
+ LLVector3(-1,0,0),
+ LLVector3(0,1,0),
+ LLVector3(0,-1,0),
+
+ LLVector3(0,0,-1),
+ LLVector3(0,0,1),
+ };
+
+ //sides
+ gGL.vertex3fv(v[0].mV);
+ gGL.vertex3fv(v[2].mV);
+
+ gGL.vertex3fv(v[0].mV);
+ gGL.vertex3fv(v[3].mV);
+
+ gGL.vertex3fv(v[1].mV);
+ gGL.vertex3fv(v[2].mV);
+
+ gGL.vertex3fv(v[1].mV);
+ gGL.vertex3fv(v[3].mV);
+
+
+ //top
+ gGL.vertex3fv(v[0].mV);
+ gGL.vertex3fv(v[4].mV);
+
+ gGL.vertex3fv(v[1].mV);
+ gGL.vertex3fv(v[4].mV);
+
+ gGL.vertex3fv(v[2].mV);
+ gGL.vertex3fv(v[4].mV);
+
+ gGL.vertex3fv(v[3].mV);
+ gGL.vertex3fv(v[4].mV);
+
+
+ //bottom
+ gGL.vertex3fv(v[0].mV);
+ gGL.vertex3fv(v[5].mV);
+
+ gGL.vertex3fv(v[1].mV);
+ gGL.vertex3fv(v[5].mV);
+
+ gGL.vertex3fv(v[2].mV);
+ gGL.vertex3fv(v[5].mV);
+
+ gGL.vertex3fv(v[3].mV);
+ gGL.vertex3fv(v[5].mV);
+
+ gGL.end();
+
+ gGL.popMatrix();
+}
+
+
+// End
diff --git a/indra/llappearance/llavatarjoint.h b/indra/llappearance/llavatarjoint.h
new file mode 100644
index 0000000000..fec91503c7
--- /dev/null
+++ b/indra/llappearance/llavatarjoint.h
@@ -0,0 +1,140 @@
+/**
+ * @file llavatarjoint.h
+ * @brief Implementation of LLAvatarJoint class
+ *
+ * $LicenseInfo:firstyear=2001&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$
+ */
+
+#ifndef LL_LLAVATARJOINT_H
+#define LL_LLAVATARJOINT_H
+
+//-----------------------------------------------------------------------------
+// Header Files
+//-----------------------------------------------------------------------------
+#include "lljoint.h"
+#include "lljointpickname.h"
+
+class LLFace;
+class LLAvatarJointMesh;
+
+extern const F32 DEFAULT_AVATAR_JOINT_LOD;
+
+//-----------------------------------------------------------------------------
+// class LLViewerJoint
+//-----------------------------------------------------------------------------
+class LLAvatarJoint :
+ public LLJoint
+{
+public:
+ LLAvatarJoint();
+ LLAvatarJoint(S32 joint_num);
+ // *TODO: Only used for LLVOAvatarSelf::mScreenp. *DOES NOT INITIALIZE mResetAfterRestoreOldXform*
+ LLAvatarJoint(const std::string &name, LLJoint *parent = NULL);
+ virtual ~LLAvatarJoint();
+
+ // Gets the validity of this joint
+ BOOL getValid() { return mValid; }
+
+ // Sets the validity of this joint
+ virtual void setValid( BOOL valid, BOOL recursive=FALSE );
+
+ // Returns true if this object is transparent.
+ // This is used to determine in which order to draw objects.
+ virtual BOOL isTransparent() { return mIsTransparent; }
+
+ // Returns true if this object should inherit scale modifiers from its immediate parent
+ virtual BOOL inheritScale() { return FALSE; }
+
+ enum Components
+ {
+ SC_BONE = 1,
+ SC_JOINT = 2,
+ SC_AXES = 4
+ };
+
+ // Selects which skeleton components to draw
+ void setSkeletonComponents( U32 comp, BOOL recursive = TRUE );
+
+ // Returns which skeleton components are enables for drawing
+ U32 getSkeletonComponents() { return mComponents; }
+
+ // Sets the level of detail for this node as a minimum
+ // pixel area threshold. If the current pixel area for this
+ // object is less than the specified threshold, the node is
+ // not traversed. In addition, if a value is specified (not
+ // default of 0.0), and the pixel area is larger than the
+ // specified minimum, the node is rendered, but no other siblings
+ // of this node under the same parent will be.
+ F32 getLOD() { return mMinPixelArea; }
+ void setLOD( F32 pixelArea ) { mMinPixelArea = pixelArea; }
+
+ void setPickName(LLJointPickName name) { mPickName = name; }
+ LLJointPickName getPickName() { return mPickName; }
+
+ void setVisible( BOOL visible, BOOL recursive );
+
+ // Takes meshes in mMeshParts and sets each one as a child joint
+ void setMeshesToChildren();
+
+ // LLViewerJoint interface
+ virtual U32 render( F32 pixelArea, BOOL first_pass = TRUE, BOOL is_dummy = FALSE ) = 0;
+ virtual void updateFaceSizes(U32 &num_vertices, U32& num_indices, F32 pixel_area);
+ virtual void updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind = FALSE, bool terse_update = false);
+ virtual BOOL updateLOD(F32 pixel_area, BOOL activate);
+ virtual void updateJointGeometry();
+ virtual void dump();
+
+
+public:
+ static BOOL sDisableLOD;
+ avatar_joint_mesh_list_t mMeshParts; //LLViewerJointMesh*
+ void setMeshID( S32 id ) {mMeshID = id;}
+
+protected:
+ void init();
+
+ BOOL mValid;
+ BOOL mIsTransparent;
+ U32 mComponents;
+ F32 mMinPixelArea;
+ LLJointPickName mPickName;
+ BOOL mVisible;
+ S32 mMeshID;
+};
+
+class LLAvatarJointCollisionVolume : public LLAvatarJoint
+{
+public:
+ LLAvatarJointCollisionVolume();
+ virtual ~LLAvatarJointCollisionVolume() {};
+
+ /*virtual*/ BOOL inheritScale() { return TRUE; }
+ /*virtual*/ U32 render( F32 pixelArea, BOOL first_pass = TRUE, BOOL is_dummy = FALSE );
+
+ void renderCollision();
+
+ LLVector3 getVolumePos(LLVector3 &offset);
+};
+
+#endif // LL_LLAVATARJOINT_H
+
+
diff --git a/indra/llappearance/llavatarjointmesh.cpp b/indra/llappearance/llavatarjointmesh.cpp
new file mode 100644
index 0000000000..4a5cff1dc3
--- /dev/null
+++ b/indra/llappearance/llavatarjointmesh.cpp
@@ -0,0 +1,375 @@
+/**
+ * @file LLAvatarJointMesh.cpp
+ * @brief Implementation of LLAvatarJointMesh class
+ *
+ * $LicenseInfo:firstyear=2001&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$
+ */
+
+//-----------------------------------------------------------------------------
+// Header Files
+//-----------------------------------------------------------------------------
+#include "linden_common.h"
+#include "imageids.h"
+#include "llfasttimer.h"
+#include "llrender.h"
+
+#include "llavatarjointmesh.h"
+#include "llavatarappearance.h"
+//#include "llapr.h"
+//#include "llbox.h"
+//#include "lldrawable.h"
+//#include "lldrawpoolavatar.h"
+//#include "lldrawpoolbump.h"
+//#include "lldynamictexture.h"
+//#include "llface.h"
+//#include "llgldbg.h"
+//#include "llglheaders.h"
+#include "lltexlayer.h"
+//#include "llviewercamera.h"
+//#include "llviewercontrol.h"
+//#include "llviewertexturelist.h"
+//#include "llsky.h"
+//#include "pipeline.h"
+//#include "llviewershadermgr.h"
+#include "llmath.h"
+#include "v4math.h"
+#include "m3math.h"
+#include "m4math.h"
+#include "llmatrix4a.h"
+
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+// LLAvatarJointMesh::LLSkinJoint
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// LLSkinJoint
+//-----------------------------------------------------------------------------
+LLSkinJoint::LLSkinJoint()
+{
+ mJoint = NULL;
+}
+
+//-----------------------------------------------------------------------------
+// ~LLSkinJoint
+//-----------------------------------------------------------------------------
+LLSkinJoint::~LLSkinJoint()
+{
+ mJoint = NULL;
+}
+
+
+//-----------------------------------------------------------------------------
+// LLSkinJoint::setupSkinJoint()
+//-----------------------------------------------------------------------------
+BOOL LLSkinJoint::setupSkinJoint( LLAvatarJoint *joint)
+{
+ // find the named joint
+ mJoint = joint;
+ if ( !mJoint )
+ {
+ llinfos << "Can't find joint" << llendl;
+ }
+
+ // compute the inverse root skin matrix
+ mRootToJointSkinOffset.clearVec();
+
+ LLVector3 rootSkinOffset;
+ while (joint)
+ {
+ rootSkinOffset += joint->getSkinOffset();
+ joint = (LLAvatarJoint*)joint->getParent();
+ }
+
+ mRootToJointSkinOffset = -rootSkinOffset;
+ mRootToParentJointSkinOffset = mRootToJointSkinOffset;
+ mRootToParentJointSkinOffset += mJoint->getSkinOffset();
+
+ return TRUE;
+}
+
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+// LLAvatarJointMesh
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+
+BOOL LLAvatarJointMesh::sPipelineRender = FALSE;
+EAvatarRenderPass LLAvatarJointMesh::sRenderPass = AVATAR_RENDER_PASS_SINGLE;
+U32 LLAvatarJointMesh::sClothingMaskImageName = 0;
+LLColor4 LLAvatarJointMesh::sClothingInnerColor;
+
+//-----------------------------------------------------------------------------
+// LLAvatarJointMesh()
+//-----------------------------------------------------------------------------
+LLAvatarJointMesh::LLAvatarJointMesh()
+ :
+ mTexture( NULL ),
+ mLayerSet( NULL ),
+ mTestImageName( 0 ),
+ mFaceIndexCount(0)
+{
+
+ mColor[0] = 1.0f;
+ mColor[1] = 1.0f;
+ mColor[2] = 1.0f;
+ mColor[3] = 1.0f;
+ mShiny = 0.0f;
+ mCullBackFaces = TRUE;
+
+ mMesh = NULL;
+
+ mNumSkinJoints = 0;
+ mSkinJoints = NULL;
+
+ mFace = NULL;
+
+ mMeshID = 0;
+ mUpdateXform = FALSE;
+
+ mValid = FALSE;
+
+ mIsTransparent = FALSE;
+}
+
+
+//-----------------------------------------------------------------------------
+// ~LLAvatarJointMesh()
+// Class Destructor
+//-----------------------------------------------------------------------------
+LLAvatarJointMesh::~LLAvatarJointMesh()
+{
+ mMesh = NULL;
+ mTexture = NULL;
+ freeSkinData();
+}
+
+
+//-----------------------------------------------------------------------------
+// LLAvatarJointMesh::allocateSkinData()
+//-----------------------------------------------------------------------------
+BOOL LLAvatarJointMesh::allocateSkinData( U32 numSkinJoints )
+{
+ mSkinJoints = new LLSkinJoint[ numSkinJoints ];
+ mNumSkinJoints = numSkinJoints;
+ return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// LLAvatarJointMesh::freeSkinData()
+//-----------------------------------------------------------------------------
+void LLAvatarJointMesh::freeSkinData()
+{
+ mNumSkinJoints = 0;
+ delete [] mSkinJoints;
+ mSkinJoints = NULL;
+}
+
+//--------------------------------------------------------------------
+// LLAvatarJointMesh::getColor()
+//--------------------------------------------------------------------
+void LLAvatarJointMesh::getColor( F32 *red, F32 *green, F32 *blue, F32 *alpha )
+{
+ *red = mColor[0];
+ *green = mColor[1];
+ *blue = mColor[2];
+ *alpha = mColor[3];
+}
+
+//--------------------------------------------------------------------
+// LLAvatarJointMesh::setColor()
+//--------------------------------------------------------------------
+void LLAvatarJointMesh::setColor( F32 red, F32 green, F32 blue, F32 alpha )
+{
+ mColor[0] = red;
+ mColor[1] = green;
+ mColor[2] = blue;
+ mColor[3] = alpha;
+}
+
+void LLAvatarJointMesh::setColor( const LLColor4& color )
+{
+ mColor = color;
+}
+
+
+//--------------------------------------------------------------------
+// LLAvatarJointMesh::getTexture()
+//--------------------------------------------------------------------
+//LLViewerTexture *LLAvatarJointMesh::getTexture()
+//{
+// return mTexture;
+//}
+
+//--------------------------------------------------------------------
+// LLAvatarJointMesh::setTexture()
+//--------------------------------------------------------------------
+void LLAvatarJointMesh::setTexture( LLGLTexture *texture )
+{
+ mTexture = texture;
+
+ // texture and dynamic_texture are mutually exclusive
+ if( texture )
+ {
+ mLayerSet = NULL;
+ //texture->bindTexture(0);
+ //texture->setClamp(TRUE, TRUE);
+ }
+}
+
+
+BOOL LLAvatarJointMesh::hasGLTexture() const
+{
+ return mTexture.notNull() && mTexture->hasGLTexture();
+}
+
+//--------------------------------------------------------------------
+// LLAvatarJointMesh::setLayerSet()
+// Sets the shape texture (takes precedence over normal texture)
+//--------------------------------------------------------------------
+void LLAvatarJointMesh::setLayerSet( LLTexLayerSet* layer_set )
+{
+ mLayerSet = layer_set;
+
+ // texture and dynamic_texture are mutually exclusive
+ if( layer_set )
+ {
+ mTexture = NULL;
+ }
+}
+
+BOOL LLAvatarJointMesh::hasComposite() const
+{
+ return (mLayerSet && mLayerSet->hasComposite());
+}
+
+
+//--------------------------------------------------------------------
+// LLAvatarJointMesh::getMesh()
+//--------------------------------------------------------------------
+LLPolyMesh *LLAvatarJointMesh::getMesh()
+{
+ return mMesh;
+}
+
+//-----------------------------------------------------------------------------
+// LLAvatarJointMesh::setMesh()
+//-----------------------------------------------------------------------------
+void LLAvatarJointMesh::setMesh( LLPolyMesh *mesh )
+{
+ // set the mesh pointer
+ mMesh = mesh;
+
+ // release any existing skin joints
+ freeSkinData();
+
+ if ( mMesh == NULL )
+ {
+ return;
+ }
+
+ // acquire the transform from the mesh object
+ setPosition( mMesh->getPosition() );
+ setRotation( mMesh->getRotation() );
+ setScale( mMesh->getScale() );
+
+ // create skin joints if necessary
+ if ( mMesh->hasWeights() && !mMesh->isLOD())
+ {
+ U32 numJointNames = mMesh->getNumJointNames();
+
+ allocateSkinData( numJointNames );
+ std::string *jointNames = mMesh->getJointNames();
+
+ U32 jn;
+ for (jn = 0; jn < numJointNames; jn++)
+ {
+ //llinfos << "Setting up joint " << jointNames[jn] << llendl;
+ LLAvatarJoint* joint = (LLAvatarJoint*)(getRoot()->findJoint(jointNames[jn]) );
+ mSkinJoints[jn].setupSkinJoint( joint );
+ }
+ }
+
+ // setup joint array
+ if (!mMesh->isLOD())
+ {
+ setupJoint((LLAvatarJoint*)getRoot());
+ }
+
+// llinfos << "joint render entries: " << mMesh->mJointRenderData.count() << llendl;
+}
+
+//-----------------------------------------------------------------------------
+// setupJoint()
+//-----------------------------------------------------------------------------
+void LLAvatarJointMesh::setupJoint(LLAvatarJoint* current_joint)
+{
+// llinfos << "Mesh: " << getName() << llendl;
+
+// S32 joint_count = 0;
+ U32 sj;
+ for (sj=0; sj<mNumSkinJoints; sj++)
+ {
+ LLSkinJoint &js = mSkinJoints[sj];
+
+ if (js.mJoint != current_joint)
+ {
+ continue;
+ }
+
+ // we've found a skinjoint for this joint..
+
+ // is the last joint in the array our parent?
+ if(mMesh->mJointRenderData.count() && mMesh->mJointRenderData[mMesh->mJointRenderData.count() - 1]->mWorldMatrix == &current_joint->getParent()->getWorldMatrix())
+ {
+ // ...then just add ourselves
+ LLAvatarJoint* jointp = js.mJoint;
+ mMesh->mJointRenderData.put(new LLJointRenderData(&jointp->getWorldMatrix(), &js));
+// llinfos << "joint " << joint_count << js.mJoint->getName() << llendl;
+// joint_count++;
+ }
+ // otherwise add our parent and ourselves
+ else
+ {
+ mMesh->mJointRenderData.put(new LLJointRenderData(&current_joint->getParent()->getWorldMatrix(), NULL));
+// llinfos << "joint " << joint_count << current_joint->getParent()->getName() << llendl;
+// joint_count++;
+ mMesh->mJointRenderData.put(new LLJointRenderData(&current_joint->getWorldMatrix(), &js));
+// llinfos << "joint " << joint_count << current_joint->getName() << llendl;
+// joint_count++;
+ }
+ }
+
+ // depth-first traversal
+ for (LLJoint::child_list_t::iterator iter = current_joint->mChildren.begin();
+ iter != current_joint->mChildren.end(); ++iter)
+ {
+ LLAvatarJoint* child_joint = (LLAvatarJoint*)(*iter);
+ setupJoint(child_joint);
+ }
+}
+
+
+// End
diff --git a/indra/llappearance/llavatarjointmesh.h b/indra/llappearance/llavatarjointmesh.h
new file mode 100644
index 0000000000..6486932cdf
--- /dev/null
+++ b/indra/llappearance/llavatarjointmesh.h
@@ -0,0 +1,145 @@
+/**
+ * @file llavatarjointmesh.h
+ * @brief Declaration of LLAvatarJointMesh class
+ *
+ * $LicenseInfo:firstyear=2001&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$
+ */
+
+#ifndef LL_LLAVATARJOINTMESH_H
+#define LL_LLAVATARJOINTMESH_H
+
+#include "llavatarjoint.h"
+#include "llgltexture.h"
+#include "llpolymesh.h"
+#include "v4color.h"
+
+class LLDrawable;
+class LLFace;
+class LLCharacter;
+class LLTexLayerSet;
+
+typedef enum e_avatar_render_pass
+{
+ AVATAR_RENDER_PASS_SINGLE,
+ AVATAR_RENDER_PASS_CLOTHING_INNER,
+ AVATAR_RENDER_PASS_CLOTHING_OUTER
+} EAvatarRenderPass;
+
+class LLSkinJoint
+{
+public:
+ LLSkinJoint();
+ ~LLSkinJoint();
+ BOOL setupSkinJoint( LLAvatarJoint *joint);
+
+ LLAvatarJoint *mJoint;
+ LLVector3 mRootToJointSkinOffset;
+ LLVector3 mRootToParentJointSkinOffset;
+};
+
+//-----------------------------------------------------------------------------
+// class LLViewerJointMesh
+//-----------------------------------------------------------------------------
+class LLAvatarJointMesh : public virtual LLAvatarJoint
+{
+protected:
+ LLColor4 mColor; // color value
+// LLColor4 mSpecular; // specular color (always white for now)
+ F32 mShiny; // shiny value
+ LLPointer<LLGLTexture> mTexture; // ptr to a global texture
+ LLTexLayerSet* mLayerSet; // ptr to a layer set owned by the avatar
+ U32 mTestImageName; // handle to a temporary texture for previewing uploads
+ LLPolyMesh* mMesh; // ptr to a global polymesh
+ BOOL mCullBackFaces; // true by default
+ LLFace* mFace; // ptr to a face w/ AGP copy of mesh
+
+ U32 mFaceIndexCount;
+
+ U32 mNumSkinJoints;
+ LLSkinJoint* mSkinJoints;
+ S32 mMeshID;
+
+public:
+ static BOOL sPipelineRender;
+ //RN: this is here for testing purposes
+ static U32 sClothingMaskImageName;
+ static EAvatarRenderPass sRenderPass;
+ static LLColor4 sClothingInnerColor;
+
+public:
+ // Constructor
+ LLAvatarJointMesh();
+
+ // Destructor
+ virtual ~LLAvatarJointMesh();
+
+ // Gets the shape color
+ void getColor( F32 *red, F32 *green, F32 *blue, F32 *alpha );
+
+ // Sets the shape color
+ void setColor( F32 red, F32 green, F32 blue, F32 alpha );
+ void setColor( const LLColor4& color );
+
+ // Sets the shininess
+ void setSpecular( const LLColor4& color, F32 shiny ) { /*mSpecular = color;*/ mShiny = shiny; };
+
+ // Sets the shape texture
+ void setTexture( LLGLTexture *texture );
+
+ BOOL hasGLTexture() const;
+
+ void setTestTexture( U32 name ) { mTestImageName = name; }
+
+ // Sets layer set responsible for a dynamic shape texture (takes precedence over normal texture)
+ void setLayerSet( LLTexLayerSet* layer_set );
+
+ BOOL hasComposite() const;
+
+ // Gets the poly mesh
+ LLPolyMesh *getMesh();
+
+ // Sets the poly mesh
+ void setMesh( LLPolyMesh *mesh );
+
+ // Sets up joint matrix data for rendering
+ void setupJoint(LLAvatarJoint* current_joint);
+
+ // Render time method to upload batches of joint matrices
+ void uploadJointMatrices();
+
+ // Sets ID for picking
+ void setMeshID( S32 id ) {mMeshID = id;}
+
+ // Gets ID for picking
+ S32 getMeshID() { return mMeshID; }
+
+ void setIsTransparent(BOOL is_transparent) { mIsTransparent = is_transparent; }
+
+private:
+ // Allocate skin data
+ BOOL allocateSkinData( U32 numSkinJoints );
+
+ // Free skin data
+ void freeSkinData();
+};
+
+#endif // LL_LLAVATARJOINTMESH_H
diff --git a/indra/llappearance/lldriverparam.cpp b/indra/llappearance/lldriverparam.cpp
new file mode 100644
index 0000000000..1f7e8b8652
--- /dev/null
+++ b/indra/llappearance/lldriverparam.cpp
@@ -0,0 +1,619 @@
+/**
+ * @file lldriverparam.cpp
+ * @brief A visual parameter that drives (controls) other visual parameters.
+ *
+ * $LicenseInfo:firstyear=2002&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 "lldriverparam.h"
+
+#include "llavatarappearance.h"
+#include "llwearable.h"
+#include "llwearabledata.h"
+
+//-----------------------------------------------------------------------------
+// LLDriverParamInfo
+//-----------------------------------------------------------------------------
+
+LLDriverParamInfo::LLDriverParamInfo() :
+ mDriverParam(NULL)
+{
+}
+
+BOOL LLDriverParamInfo::parseXml(LLXmlTreeNode* node)
+{
+ llassert( node->hasName( "param" ) && node->getChildByName( "param_driver" ) );
+
+ if( !LLViewerVisualParamInfo::parseXml( node ))
+ return FALSE;
+
+ LLXmlTreeNode* param_driver_node = node->getChildByName( "param_driver" );
+ if( !param_driver_node )
+ return FALSE;
+
+ for (LLXmlTreeNode* child = param_driver_node->getChildByName( "driven" );
+ child;
+ child = param_driver_node->getNextNamedChild())
+ {
+ S32 driven_id;
+ static LLStdStringHandle id_string = LLXmlTree::addAttributeString("id");
+ if( child->getFastAttributeS32( id_string, driven_id ) )
+ {
+ F32 min1 = mMinWeight;
+ F32 max1 = mMaxWeight;
+ F32 max2 = max1;
+ F32 min2 = max1;
+
+ // driven ________ //
+ // ^ /| |\ //
+ // | / | | \ //
+ // | / | | \ //
+ // | / | | \ //
+ // | / | | \ //
+ //-------|----|-------|----|-------> driver //
+ // | min1 max1 max2 min2
+
+ static LLStdStringHandle min1_string = LLXmlTree::addAttributeString("min1");
+ child->getFastAttributeF32( min1_string, min1 ); // optional
+ static LLStdStringHandle max1_string = LLXmlTree::addAttributeString("max1");
+ child->getFastAttributeF32( max1_string, max1 ); // optional
+ static LLStdStringHandle max2_string = LLXmlTree::addAttributeString("max2");
+ child->getFastAttributeF32( max2_string, max2 ); // optional
+ static LLStdStringHandle min2_string = LLXmlTree::addAttributeString("min2");
+ child->getFastAttributeF32( min2_string, min2 ); // optional
+
+ // Push these on the front of the deque, so that we can construct
+ // them in order later (faster)
+ mDrivenInfoList.push_front( LLDrivenEntryInfo( driven_id, min1, max1, max2, min2 ) );
+ }
+ else
+ {
+ llerrs << "<driven> Unable to resolve driven parameter: " << driven_id << llendl;
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+//virtual
+void LLDriverParamInfo::toStream(std::ostream &out)
+{
+ LLViewerVisualParamInfo::toStream(out);
+ out << "driver" << "\t";
+ out << mDrivenInfoList.size() << "\t";
+ for (entry_info_list_t::iterator iter = mDrivenInfoList.begin(); iter != mDrivenInfoList.end(); iter++)
+ {
+ LLDrivenEntryInfo driven = *iter;
+ out << driven.mDrivenID << "\t";
+ }
+
+ out << std::endl;
+
+ if(mDriverParam && mDriverParam->getAvatarAppearance()->isSelf() &&
+ mDriverParam->getAvatarAppearance()->isValid())
+ {
+ for (entry_info_list_t::iterator iter = mDrivenInfoList.begin(); iter != mDrivenInfoList.end(); iter++)
+ {
+ LLDrivenEntryInfo driven = *iter;
+ LLViewerVisualParam *param =
+ (LLViewerVisualParam*)mDriverParam->getAvatarAppearance()->getVisualParam(driven.mDrivenID);
+ if (param)
+ {
+ param->getInfo()->toStream(out);
+ if (param->getWearableType() != mWearableType)
+ {
+ if(param->getCrossWearable())
+ {
+ out << "cross-wearable" << "\t";
+ }
+ else
+ {
+ out << "ERROR!" << "\t";
+ }
+ }
+ else
+ {
+ out << "valid" << "\t";
+ }
+ }
+ else
+ {
+ llwarns << "could not get parameter " << driven.mDrivenID << " from avatar "
+ << mDriverParam->getAvatarAppearance()
+ << " for driver parameter " << getID() << llendl;
+ }
+ out << std::endl;
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// LLDriverParam
+//-----------------------------------------------------------------------------
+
+LLDriverParam::LLDriverParam(LLAvatarAppearance *appearance, LLWearable* wearable /* = NULL */) :
+ mCurrentDistortionParam( NULL ),
+ mAvatarAppearance(appearance),
+ mWearablep(wearable)
+{
+ llassert(mAvatarAppearance);
+ if (mWearablep)
+ {
+ llassert(mAvatarAppearance->isSelf());
+ }
+ mDefaultVec.clear();
+}
+
+LLDriverParam::~LLDriverParam()
+{
+}
+
+BOOL LLDriverParam::setInfo(LLDriverParamInfo *info)
+{
+ llassert(mInfo == NULL);
+ if (info->mID < 0)
+ return FALSE;
+ mInfo = info;
+ mID = info->mID;
+ info->mDriverParam = this;
+
+ setWeight(getDefaultWeight(), FALSE );
+
+ return TRUE;
+}
+
+/*virtual*/ LLViewerVisualParam* LLDriverParam::cloneParam(LLWearable* wearable) const
+{
+ llassert(wearable);
+ LLDriverParam *new_param = new LLDriverParam(mAvatarAppearance, wearable);
+ // FIXME DRANO this clobbers mWearablep, which means any code
+ // currently using mWearablep is wrong, or at least untested.
+ *new_param = *this;
+ //new_param->mWearablep = wearable;
+// new_param->mDriven.clear(); // clear driven list to avoid overwriting avatar driven params from wearables.
+ return new_param;
+}
+
+void LLDriverParam::setWeight(F32 weight, BOOL upload_bake)
+{
+ F32 min_weight = getMinWeight();
+ F32 max_weight = getMaxWeight();
+ if (mIsAnimating)
+ {
+ // allow overshoot when animating
+ mCurWeight = weight;
+ }
+ else
+ {
+ mCurWeight = llclamp(weight, min_weight, max_weight);
+ }
+
+ // driven ________
+ // ^ /| |\ ^
+ // | / | | \ |
+ // | / | | \ |
+ // | / | | \ |
+ // | / | | \ |
+ //-------|----|-------|----|-------> driver
+ // | min1 max1 max2 min2
+
+ for( entry_list_t::iterator iter = mDriven.begin(); iter != mDriven.end(); iter++ )
+ {
+ LLDrivenEntry* driven = &(*iter);
+ LLDrivenEntryInfo* info = driven->mInfo;
+
+ F32 driven_weight = 0.f;
+ F32 driven_min = driven->mParam->getMinWeight();
+ F32 driven_max = driven->mParam->getMaxWeight();
+
+ if (mIsAnimating)
+ {
+ // driven param doesn't interpolate (textures, for example)
+ if (!driven->mParam->getAnimating())
+ {
+ continue;
+ }
+ if( mCurWeight < info->mMin1 )
+ {
+ if (info->mMin1 == min_weight)
+ {
+ if (info->mMin1 == info->mMax1)
+ {
+ driven_weight = driven_max;
+ }
+ else
+ {
+ //up slope extrapolation
+ F32 t = (mCurWeight - info->mMin1) / (info->mMax1 - info->mMin1 );
+ driven_weight = driven_min + t * (driven_max - driven_min);
+ }
+ }
+ else
+ {
+ driven_weight = driven_min;
+ }
+
+ setDrivenWeight(driven,driven_weight,upload_bake);
+ continue;
+ }
+ else
+ if ( mCurWeight > info->mMin2 )
+ {
+ if (info->mMin2 == max_weight)
+ {
+ if (info->mMin2 == info->mMax2)
+ {
+ driven_weight = driven_max;
+ }
+ else
+ {
+ //down slope extrapolation
+ F32 t = (mCurWeight - info->mMax2) / (info->mMin2 - info->mMax2 );
+ driven_weight = driven_max + t * (driven_min - driven_max);
+ }
+ }
+ else
+ {
+ driven_weight = driven_min;
+ }
+
+ setDrivenWeight(driven,driven_weight,upload_bake);
+ continue;
+ }
+ }
+
+ driven_weight = getDrivenWeight(driven, mCurWeight);
+ setDrivenWeight(driven,driven_weight,upload_bake);
+ }
+}
+
+F32 LLDriverParam::getTotalDistortion()
+{
+ F32 sum = 0.f;
+ for( entry_list_t::iterator iter = mDriven.begin(); iter != mDriven.end(); iter++ )
+ {
+ LLDrivenEntry* driven = &(*iter);
+ sum += driven->mParam->getTotalDistortion();
+ }
+
+ return sum;
+}
+
+const LLVector4a &LLDriverParam::getAvgDistortion()
+{
+ // It's not actually correct to take the average of averages, but it good enough here.
+ LLVector4a sum;
+ sum.clear();
+ S32 count = 0;
+ for( entry_list_t::iterator iter = mDriven.begin(); iter != mDriven.end(); iter++ )
+ {
+ LLDrivenEntry* driven = &(*iter);
+ sum.add(driven->mParam->getAvgDistortion());
+ count++;
+ }
+ sum.mul( 1.f/(F32)count);
+
+ mDefaultVec = sum;
+ return mDefaultVec;
+}
+
+F32 LLDriverParam::getMaxDistortion()
+{
+ F32 max = 0.f;
+ for( entry_list_t::iterator iter = mDriven.begin(); iter != mDriven.end(); iter++ )
+ {
+ LLDrivenEntry* driven = &(*iter);
+ F32 param_max = driven->mParam->getMaxDistortion();
+ if( param_max > max )
+ {
+ max = param_max;
+ }
+ }
+
+ return max;
+}
+
+
+LLVector4a LLDriverParam::getVertexDistortion(S32 index, LLPolyMesh *poly_mesh)
+{
+ LLVector4a sum;
+ sum.clear();
+ for( entry_list_t::iterator iter = mDriven.begin(); iter != mDriven.end(); iter++ )
+ {
+ LLDrivenEntry* driven = &(*iter);
+ sum.add(driven->mParam->getVertexDistortion( index, poly_mesh ));
+ }
+ return sum;
+}
+
+const LLVector4a* LLDriverParam::getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh)
+{
+ mCurrentDistortionParam = NULL;
+ const LLVector4a* v = NULL;
+ for( entry_list_t::iterator iter = mDriven.begin(); iter != mDriven.end(); iter++ )
+ {
+ LLDrivenEntry* driven = &(*iter);
+ v = driven->mParam->getFirstDistortion( index, poly_mesh );
+ if( v )
+ {
+ mCurrentDistortionParam = driven->mParam;
+ break;
+ }
+ }
+
+ return v;
+};
+
+const LLVector4a* LLDriverParam::getNextDistortion(U32 *index, LLPolyMesh **poly_mesh)
+{
+ llassert( mCurrentDistortionParam );
+ if( !mCurrentDistortionParam )
+ {
+ return NULL;
+ }
+
+ LLDrivenEntry* driven = NULL;
+ entry_list_t::iterator iter;
+
+ // Set mDriven iteration to the right point
+ for( iter = mDriven.begin(); iter != mDriven.end(); iter++ )
+ {
+ driven = &(*iter);
+ if( driven->mParam == mCurrentDistortionParam )
+ {
+ break;
+ }
+ }
+
+ llassert(driven);
+ if (!driven)
+ {
+ return NULL; // shouldn't happen, but...
+ }
+
+ // We're already in the middle of a param's distortions, so get the next one.
+ const LLVector4a* v = driven->mParam->getNextDistortion( index, poly_mesh );
+ if( (!v) && (iter != mDriven.end()) )
+ {
+ // This param is finished, so start the next param. It might not have any
+ // distortions, though, so we have to loop to find the next param that does.
+ for( iter++; iter != mDriven.end(); iter++ )
+ {
+ driven = &(*iter);
+ v = driven->mParam->getFirstDistortion( index, poly_mesh );
+ if( v )
+ {
+ mCurrentDistortionParam = driven->mParam;
+ break;
+ }
+ }
+ }
+
+ return v;
+};
+
+S32 LLDriverParam::getDrivenParamsCount() const
+{
+ return mDriven.size();
+}
+
+const LLViewerVisualParam* LLDriverParam::getDrivenParam(S32 index) const
+{
+ if (0 > index || index >= mDriven.size())
+ {
+ return NULL;
+ }
+ return mDriven[index].mParam;
+}
+
+//-----------------------------------------------------------------------------
+// setAnimationTarget()
+//-----------------------------------------------------------------------------
+void LLDriverParam::setAnimationTarget( F32 target_value, BOOL upload_bake )
+{
+ LLVisualParam::setAnimationTarget(target_value, upload_bake);
+
+ for( entry_list_t::iterator iter = mDriven.begin(); iter != mDriven.end(); iter++ )
+ {
+ LLDrivenEntry* driven = &(*iter);
+ F32 driven_weight = getDrivenWeight(driven, mTargetWeight);
+
+ // this isn't normally necessary, as driver params handle interpolation of their driven params
+ // but texture params need to know to assume their final value at beginning of interpolation
+ driven->mParam->setAnimationTarget(driven_weight, upload_bake);
+ }
+}
+
+//-----------------------------------------------------------------------------
+// stopAnimating()
+//-----------------------------------------------------------------------------
+void LLDriverParam::stopAnimating(BOOL upload_bake)
+{
+ LLVisualParam::stopAnimating(upload_bake);
+
+ for( entry_list_t::iterator iter = mDriven.begin(); iter != mDriven.end(); iter++ )
+ {
+ LLDrivenEntry* driven = &(*iter);
+ driven->mParam->setAnimating(FALSE);
+ }
+}
+
+/*virtual*/
+BOOL LLDriverParam::linkDrivenParams(visual_param_mapper mapper, BOOL only_cross_params)
+{
+ BOOL success = TRUE;
+ LLDriverParamInfo::entry_info_list_t::iterator iter;
+ for (iter = getInfo()->mDrivenInfoList.begin(); iter != getInfo()->mDrivenInfoList.end(); ++iter)
+ {
+ LLDrivenEntryInfo *driven_info = &(*iter);
+ S32 driven_id = driven_info->mDrivenID;
+
+ // check for already existing links. Do not overwrite.
+ BOOL found = FALSE;
+ for (entry_list_t::iterator driven_iter = mDriven.begin(); driven_iter != mDriven.end() && !found; ++driven_iter)
+ {
+ if (driven_iter->mInfo->mDrivenID == driven_id)
+ {
+ found = TRUE;
+ }
+ }
+
+ if (!found)
+ {
+ LLViewerVisualParam* param = (LLViewerVisualParam*)mapper(driven_id);
+ if (param) param->setParamLocation(this->getParamLocation());
+ bool push = param && (!only_cross_params || param->getCrossWearable());
+ if (push)
+ {
+ mDriven.push_back(LLDrivenEntry( param, driven_info ));
+ }
+ else
+ {
+ success = FALSE;
+ }
+ }
+ }
+
+ return success;
+}
+
+void LLDriverParam::resetDrivenParams()
+{
+ mDriven.clear();
+ mDriven.reserve(getInfo()->mDrivenInfoList.size());
+}
+
+void LLDriverParam::updateCrossDrivenParams(LLWearableType::EType driven_type)
+{
+ bool needs_update = (getWearableType()==driven_type);
+
+ // if the driver has a driven entry for the passed-in wearable type, we need to refresh the value
+ for( entry_list_t::iterator iter = mDriven.begin(); iter != mDriven.end(); iter++ )
+ {
+ LLDrivenEntry* driven = &(*iter);
+ if (driven && driven->mParam && driven->mParam->getCrossWearable() && driven->mParam->getWearableType() == driven_type)
+ {
+ needs_update = true;
+ }
+ }
+
+
+ if (needs_update)
+ {
+ LLWearableType::EType driver_type = (LLWearableType::EType)getWearableType();
+
+ // If we've gotten here, we've added a new wearable of type "type"
+ // Thus this wearable needs to get updates from the driver wearable.
+ // The call to setVisualParamWeight seems redundant, but is necessary
+ // as the number of driven wearables has changed since the last update. -Nyx
+ LLWearable *wearable = mAvatarAppearance->getWearableData()->getTopWearable(driver_type);
+ if (wearable)
+ {
+ wearable->setVisualParamWeight(mID, wearable->getVisualParamWeight(mID), false);
+ }
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// getDrivenWeight()
+//-----------------------------------------------------------------------------
+F32 LLDriverParam::getDrivenWeight(const LLDrivenEntry* driven, F32 input_weight)
+{
+ F32 min_weight = getMinWeight();
+ F32 max_weight = getMaxWeight();
+ const LLDrivenEntryInfo* info = driven->mInfo;
+
+ F32 driven_weight = 0.f;
+ F32 driven_min = driven->mParam->getMinWeight();
+ F32 driven_max = driven->mParam->getMaxWeight();
+
+ if( input_weight <= info->mMin1 )
+ {
+ if( info->mMin1 == info->mMax1 &&
+ info->mMin1 <= min_weight)
+ {
+ driven_weight = driven_max;
+ }
+ else
+ {
+ driven_weight = driven_min;
+ }
+ }
+ else
+ if( input_weight <= info->mMax1 )
+ {
+ F32 t = (input_weight - info->mMin1) / (info->mMax1 - info->mMin1 );
+ driven_weight = driven_min + t * (driven_max - driven_min);
+ }
+ else
+ if( input_weight <= info->mMax2 )
+ {
+ driven_weight = driven_max;
+ }
+ else
+ if( input_weight <= info->mMin2 )
+ {
+ F32 t = (input_weight - info->mMax2) / (info->mMin2 - info->mMax2 );
+ driven_weight = driven_max + t * (driven_min - driven_max);
+ }
+ else
+ {
+ if (info->mMax2 >= max_weight)
+ {
+ driven_weight = driven_max;
+ }
+ else
+ {
+ driven_weight = driven_min;
+ }
+ }
+
+ return driven_weight;
+}
+
+void LLDriverParam::setDrivenWeight(LLDrivenEntry *driven, F32 driven_weight, bool upload_bake)
+{
+ bool use_self = false;
+ if(mWearablep &&
+ mAvatarAppearance->isValid() &&
+ driven->mParam->getCrossWearable())
+ {
+ LLWearable* wearable = dynamic_cast<LLWearable*> (mWearablep);
+ if (mAvatarAppearance->getWearableData()->isOnTop(wearable))
+ {
+ use_self = true;
+ }
+ }
+
+ if (use_self)
+ {
+ // call setWeight through LLVOAvatarSelf so other wearables can be updated with the correct values
+ mAvatarAppearance->setVisualParamWeight( (LLVisualParam*)driven->mParam, driven_weight, upload_bake );
+ }
+ else
+ {
+ driven->mParam->setWeight( driven_weight, upload_bake );
+ }
+}
diff --git a/indra/llappearance/lldriverparam.h b/indra/llappearance/lldriverparam.h
new file mode 100644
index 0000000000..040c9cf5be
--- /dev/null
+++ b/indra/llappearance/lldriverparam.h
@@ -0,0 +1,144 @@
+/**
+ * @file lldriverparam.h
+ * @brief A visual parameter that drives (controls) other visual parameters.
+ *
+ * $LicenseInfo:firstyear=2002&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$
+ */
+
+#ifndef LL_LLDRIVERPARAM_H
+#define LL_LLDRIVERPARAM_H
+
+#include "llviewervisualparam.h"
+#include "llwearabletype.h"
+
+class LLAvatarAppearance;
+class LLDriverParam;
+class LLWearable;
+
+//-----------------------------------------------------------------------------
+
+struct LLDrivenEntryInfo
+{
+ LLDrivenEntryInfo( S32 id, F32 min1, F32 max1, F32 max2, F32 min2 )
+ : mDrivenID( id ), mMin1( min1 ), mMax1( max1 ), mMax2( max2 ), mMin2( min2 ) {}
+ S32 mDrivenID;
+ F32 mMin1;
+ F32 mMax1;
+ F32 mMax2;
+ F32 mMin2;
+};
+
+struct LLDrivenEntry
+{
+ LLDrivenEntry( LLViewerVisualParam* param, LLDrivenEntryInfo *info )
+ : mParam( param ), mInfo( info ) {}
+ LLViewerVisualParam* mParam;
+ LLDrivenEntryInfo* mInfo;
+};
+
+//-----------------------------------------------------------------------------
+
+class LLDriverParamInfo : public LLViewerVisualParamInfo
+{
+ friend class LLDriverParam;
+public:
+ LLDriverParamInfo();
+ /*virtual*/ ~LLDriverParamInfo() {};
+
+ /*virtual*/ BOOL parseXml(LLXmlTreeNode* node);
+
+ /*virtual*/ void toStream(std::ostream &out);
+
+protected:
+ typedef std::deque<LLDrivenEntryInfo> entry_info_list_t;
+ entry_info_list_t mDrivenInfoList;
+ LLDriverParam* mDriverParam; // backpointer
+};
+
+//-----------------------------------------------------------------------------
+
+LL_ALIGN_PREFIX(16)
+class LLDriverParam : public LLViewerVisualParam
+{
+private:
+ // Hide the default constructor. Force construction with LLAvatarAppearance.
+ LLDriverParam() {}
+public:
+ LLDriverParam(LLAvatarAppearance *appearance, LLWearable* wearable = NULL);
+ ~LLDriverParam();
+
+ void* operator new(size_t size)
+ {
+ return ll_aligned_malloc_16(size);
+ }
+
+ void operator delete(void* ptr)
+ {
+ ll_aligned_free_16(ptr);
+ }
+
+ // Special: These functions are overridden by child classes
+ LLDriverParamInfo* getInfo() const { return (LLDriverParamInfo*)mInfo; }
+ // This sets mInfo and calls initialization functions
+ BOOL setInfo(LLDriverParamInfo *info);
+
+ LLAvatarAppearance* getAvatarAppearance() { return mAvatarAppearance; }
+ const LLAvatarAppearance* getAvatarAppearance() const { return mAvatarAppearance; }
+
+ void updateCrossDrivenParams(LLWearableType::EType driven_type);
+
+ /*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable) const;
+
+ // LLVisualParam Virtual functions
+ /*virtual*/ void apply( ESex sex ) {} // apply is called separately for each driven param.
+ /*virtual*/ void setWeight(F32 weight, BOOL upload_bake);
+ /*virtual*/ void setAnimationTarget( F32 target_value, BOOL upload_bake );
+ /*virtual*/ void stopAnimating(BOOL upload_bake);
+ /*virtual*/ BOOL linkDrivenParams(visual_param_mapper mapper, BOOL only_cross_params);
+ /*virtual*/ void resetDrivenParams();
+
+ // LLViewerVisualParam Virtual functions
+ /*virtual*/ F32 getTotalDistortion();
+ /*virtual*/ const LLVector4a& getAvgDistortion();
+ /*virtual*/ F32 getMaxDistortion();
+ /*virtual*/ LLVector4a getVertexDistortion(S32 index, LLPolyMesh *poly_mesh);
+ /*virtual*/ const LLVector4a* getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh);
+ /*virtual*/ const LLVector4a* getNextDistortion(U32 *index, LLPolyMesh **poly_mesh);
+
+ S32 getDrivenParamsCount() const;
+ const LLViewerVisualParam* getDrivenParam(S32 index) const;
+
+protected:
+ F32 getDrivenWeight(const LLDrivenEntry* driven, F32 input_weight);
+ void setDrivenWeight(LLDrivenEntry *driven, F32 driven_weight, bool upload_bake);
+
+
+ LL_ALIGN_16(LLVector4a mDefaultVec); // temp holder
+ typedef std::vector<LLDrivenEntry> entry_list_t;
+ entry_list_t mDriven;
+ LLViewerVisualParam* mCurrentDistortionParam;
+ // Backlink only; don't make this an LLPointer.
+ LLAvatarAppearance* mAvatarAppearance;
+ LLWearable* mWearablep;
+} LL_ALIGN_POSTFIX(16);
+
+#endif // LL_LLDRIVERPARAM_H
diff --git a/indra/llappearance/lljointpickname.h b/indra/llappearance/lljointpickname.h
new file mode 100644
index 0000000000..1d41a761fc
--- /dev/null
+++ b/indra/llappearance/lljointpickname.h
@@ -0,0 +1,49 @@
+/**
+ * @file lljointpickname.h
+ * @brief Defines OpenGL seleciton stack names
+ *
+ * $LicenseInfo:firstyear=2001&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$
+ */
+
+
+#ifndef LL_LLJOINTPICKNAME_H
+#define LL_LLJOINTPICKNAME_H
+
+class LLAvatarJointMesh;
+
+// Sets the OpenGL selection stack name that is pushed and popped
+// with this joint state. The default value indicates that no name
+// should be pushed/popped.
+enum LLJointPickName
+{
+ PN_DEFAULT = -1,
+ PN_0 = 0,
+ PN_1 = 1,
+ PN_2 = 2,
+ PN_3 = 3,
+ PN_4 = 4,
+ PN_5 = 5
+};
+
+typedef std::vector<LLAvatarJointMesh*> avatar_joint_mesh_list_t;
+
+#endif // LL_LLJOINTPICKNAME_H
diff --git a/indra/llappearance/lllocaltextureobject.cpp b/indra/llappearance/lllocaltextureobject.cpp
new file mode 100644
index 0000000000..7e36a06797
--- /dev/null
+++ b/indra/llappearance/lllocaltextureobject.cpp
@@ -0,0 +1,213 @@
+/**
+ * @file lllocaltextureobject.cpp
+ *
+ * $LicenseInfo:firstyear=2009&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 "lllocaltextureobject.h"
+
+#include "llimage.h"
+#include "llrender.h"
+#include "lltexlayer.h"
+#include "llgltexture.h"
+#include "lluuid.h"
+#include "llwearable.h"
+
+
+LLLocalTextureObject::LLLocalTextureObject() :
+ mIsBakedReady(FALSE),
+ mDiscard(MAX_DISCARD_LEVEL+1)
+{
+ mImage = NULL;
+}
+
+LLLocalTextureObject::LLLocalTextureObject(LLGLTexture* image, const LLUUID& id) :
+ mIsBakedReady(FALSE),
+ mDiscard(MAX_DISCARD_LEVEL+1)
+{
+ mImage = image;
+ gGL.getTexUnit(0)->bind(mImage);
+ mID = id;
+}
+
+LLLocalTextureObject::LLLocalTextureObject(const LLLocalTextureObject& lto) :
+ mImage(lto.mImage),
+ mID(lto.mID),
+ mIsBakedReady(lto.mIsBakedReady),
+ mDiscard(lto.mDiscard)
+{
+ U32 num_layers = lto.getNumTexLayers();
+ mTexLayers.reserve(num_layers);
+ for (U32 index = 0; index < num_layers; index++)
+ {
+ LLTexLayer* original_layer = lto.getTexLayer(index);
+ if (!original_layer)
+ {
+ llerrs << "could not clone Local Texture Object: unable to extract texlayer!" << llendl;
+ continue;
+ }
+
+ LLTexLayer* new_layer = new LLTexLayer(*original_layer);
+ new_layer->setLTO(this);
+ mTexLayers.push_back(new_layer);
+ }
+}
+
+LLLocalTextureObject::~LLLocalTextureObject()
+{
+}
+
+LLGLTexture* LLLocalTextureObject::getImage() const
+{
+ return mImage;
+}
+
+LLTexLayer* LLLocalTextureObject::getTexLayer(U32 index) const
+{
+ if (index >= getNumTexLayers())
+ {
+ return NULL;
+ }
+
+ return mTexLayers[index];
+}
+
+LLTexLayer* LLLocalTextureObject::getTexLayer(const std::string &name)
+{
+ for( tex_layer_vec_t::iterator iter = mTexLayers.begin(); iter != mTexLayers.end(); iter++)
+ {
+ LLTexLayer *layer = *iter;
+ if (layer->getName().compare(name) == 0)
+ {
+ return layer;
+ }
+ }
+
+ return NULL;
+}
+
+U32 LLLocalTextureObject::getNumTexLayers() const
+{
+ return mTexLayers.size();
+}
+
+LLUUID LLLocalTextureObject::getID() const
+{
+ return mID;
+}
+
+S32 LLLocalTextureObject::getDiscard() const
+{
+ return mDiscard;
+}
+
+BOOL LLLocalTextureObject::getBakedReady() const
+{
+ return mIsBakedReady;
+}
+
+void LLLocalTextureObject::setImage(LLGLTexture* new_image)
+{
+ mImage = new_image;
+}
+
+BOOL LLLocalTextureObject::setTexLayer(LLTexLayer *new_tex_layer, U32 index)
+{
+ if (index >= getNumTexLayers() )
+ {
+ return FALSE;
+ }
+
+ if (new_tex_layer == NULL)
+ {
+ return removeTexLayer(index);
+ }
+
+ LLTexLayer *layer = new LLTexLayer(*new_tex_layer);
+ layer->setLTO(this);
+
+ if (mTexLayers[index])
+ {
+ delete mTexLayers[index];
+ }
+ mTexLayers[index] = layer;
+
+ return TRUE;
+}
+
+BOOL LLLocalTextureObject::addTexLayer(LLTexLayer *new_tex_layer, LLWearable *wearable)
+{
+ if (new_tex_layer == NULL)
+ {
+ return FALSE;
+ }
+
+ LLTexLayer *layer = new LLTexLayer(*new_tex_layer, wearable);
+ layer->setLTO(this);
+ mTexLayers.push_back(layer);
+ return TRUE;
+}
+
+BOOL LLLocalTextureObject::addTexLayer(LLTexLayerTemplate *new_tex_layer, LLWearable *wearable)
+{
+ if (new_tex_layer == NULL)
+ {
+ return FALSE;
+ }
+
+ LLTexLayer *layer = new LLTexLayer(*new_tex_layer, this, wearable);
+ layer->setLTO(this);
+ mTexLayers.push_back(layer);
+ return TRUE;
+}
+
+BOOL LLLocalTextureObject::removeTexLayer(U32 index)
+{
+ if (index >= getNumTexLayers())
+ {
+ return FALSE;
+ }
+ tex_layer_vec_t::iterator iter = mTexLayers.begin();
+ iter += index;
+
+ delete *iter;
+ mTexLayers.erase(iter);
+ return TRUE;
+}
+
+void LLLocalTextureObject::setID(LLUUID new_id)
+{
+ mID = new_id;
+}
+
+void LLLocalTextureObject::setDiscard(S32 new_discard)
+{
+ mDiscard = new_discard;
+}
+
+void LLLocalTextureObject::setBakedReady(BOOL ready)
+{
+ mIsBakedReady = ready;
+}
+
diff --git a/indra/llappearance/lllocaltextureobject.h b/indra/llappearance/lllocaltextureobject.h
new file mode 100644
index 0000000000..9b9f41fd19
--- /dev/null
+++ b/indra/llappearance/lllocaltextureobject.h
@@ -0,0 +1,86 @@
+/**
+ * @file lllocaltextureobject.h
+ * @brief LLLocalTextureObject class header file
+ *
+ * $LicenseInfo:firstyear=2009&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$
+ */
+
+#ifndef LL_LOCALTEXTUREOBJECT_H
+#define LL_LOCALTEXTUREOBJECT_H
+
+#include <boost/shared_ptr.hpp>
+
+#include "llpointer.h"
+#include "llgltexture.h"
+
+class LLTexLayer;
+class LLTexLayerTemplate;
+class LLWearable;
+
+// Stores all relevant information for a single texture
+// assumed to have ownership of all objects referred to -
+// will delete objects when being replaced or if object is destroyed.
+class LLLocalTextureObject
+{
+public:
+ LLLocalTextureObject();
+ LLLocalTextureObject(LLGLTexture* image, const LLUUID& id);
+ LLLocalTextureObject(const LLLocalTextureObject& lto);
+ ~LLLocalTextureObject();
+
+ LLGLTexture* getImage() const;
+ LLTexLayer* getTexLayer(U32 index) const;
+ LLTexLayer* getTexLayer(const std::string &name);
+ U32 getNumTexLayers() const;
+ LLUUID getID() const;
+ S32 getDiscard() const;
+ BOOL getBakedReady() const;
+
+ void setImage(LLGLTexture* new_image);
+ BOOL setTexLayer(LLTexLayer *new_tex_layer, U32 index);
+ BOOL addTexLayer(LLTexLayer *new_tex_layer, LLWearable *wearable);
+ BOOL addTexLayer(LLTexLayerTemplate *new_tex_layer, LLWearable *wearable);
+ BOOL removeTexLayer(U32 index);
+
+ void setID(LLUUID new_id);
+ void setDiscard(S32 new_discard);
+ void setBakedReady(BOOL ready);
+
+protected:
+
+private:
+
+ LLPointer<LLGLTexture> mImage;
+ // NOTE: LLLocalTextureObject should be the exclusive owner of mTexEntry and mTexLayer
+ // using shared pointers here only for smart assignment & cleanup
+ // do NOT create new shared pointers to these objects, or keep pointers to them around
+ typedef std::vector<LLTexLayer*> tex_layer_vec_t;
+ tex_layer_vec_t mTexLayers;
+
+ LLUUID mID;
+
+ BOOL mIsBakedReady;
+ S32 mDiscard;
+};
+
+ #endif // LL_LOCALTEXTUREOBJECT_H
+
diff --git a/indra/llappearance/llpolymesh.cpp b/indra/llappearance/llpolymesh.cpp
new file mode 100644
index 0000000000..a01457246e
--- /dev/null
+++ b/indra/llappearance/llpolymesh.cpp
@@ -0,0 +1,1048 @@
+/**
+ * @file llpolymesh.cpp
+ * @brief Implementation of LLPolyMesh class
+ *
+ * $LicenseInfo:firstyear=2001&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$
+ */
+
+//-----------------------------------------------------------------------------
+// Header Files
+//-----------------------------------------------------------------------------
+#include "linden_common.h"
+#include "llpolymesh.h"
+#include "llfasttimer.h"
+#include "llmemory.h"
+
+//#include "llviewercontrol.h"
+#include "llxmltree.h"
+#include "llavatarappearance.h"
+#include "llwearable.h"
+#include "lldir.h"
+#include "llvolume.h"
+#include "llendianswizzle.h"
+
+
+#define HEADER_ASCII "Linden Mesh 1.0"
+#define HEADER_BINARY "Linden Binary Mesh 1.0"
+
+//extern LLControlGroup gSavedSettings; // read only
+
+LLPolyMorphData *clone_morph_param_duplicate(const LLPolyMorphData *src_data,
+ const std::string &name);
+LLPolyMorphData *clone_morph_param_direction(const LLPolyMorphData *src_data,
+ const LLVector3 &direction,
+ const std::string &name);
+LLPolyMorphData *clone_morph_param_cleavage(const LLPolyMorphData *src_data,
+ F32 scale,
+ const std::string &name);
+
+//-----------------------------------------------------------------------------
+// Global table of loaded LLPolyMeshes
+//-----------------------------------------------------------------------------
+LLPolyMesh::LLPolyMeshSharedDataTable LLPolyMesh::sGlobalSharedMeshList;
+
+//-----------------------------------------------------------------------------
+// LLPolyMeshSharedData()
+//-----------------------------------------------------------------------------
+LLPolyMeshSharedData::LLPolyMeshSharedData()
+{
+ mNumVertices = 0;
+ mBaseCoords = NULL;
+ mBaseNormals = NULL;
+ mBaseBinormals = NULL;
+ mTexCoords = NULL;
+ mDetailTexCoords = NULL;
+ mWeights = NULL;
+ mHasWeights = FALSE;
+ mHasDetailTexCoords = FALSE;
+
+ mNumFaces = 0;
+ mFaces = NULL;
+
+ mNumJointNames = 0;
+ mJointNames = NULL;
+
+ mTriangleIndices = NULL;
+ mNumTriangleIndices = 0;
+
+ mReferenceData = NULL;
+
+ mLastIndexOffset = -1;
+}
+
+//-----------------------------------------------------------------------------
+// ~LLPolyMeshSharedData()
+//-----------------------------------------------------------------------------
+LLPolyMeshSharedData::~LLPolyMeshSharedData()
+{
+ freeMeshData();
+ for_each(mMorphData.begin(), mMorphData.end(), DeletePointer());
+ mMorphData.clear();
+}
+
+//-----------------------------------------------------------------------------
+// setupLOD()
+//-----------------------------------------------------------------------------
+void LLPolyMeshSharedData::setupLOD(LLPolyMeshSharedData* reference_data)
+{
+ mReferenceData = reference_data;
+
+ if (reference_data)
+ {
+ mBaseCoords = reference_data->mBaseCoords;
+ mBaseNormals = reference_data->mBaseNormals;
+ mBaseBinormals = reference_data->mBaseBinormals;
+ mTexCoords = reference_data->mTexCoords;
+ mDetailTexCoords = reference_data->mDetailTexCoords;
+ mWeights = reference_data->mWeights;
+ mHasWeights = reference_data->mHasWeights;
+ mHasDetailTexCoords = reference_data->mHasDetailTexCoords;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// LLPolyMeshSharedData::freeMeshData()
+//-----------------------------------------------------------------------------
+void LLPolyMeshSharedData::freeMeshData()
+{
+ if (!mReferenceData)
+ {
+ mNumVertices = 0;
+
+ ll_aligned_free_16(mBaseCoords);
+ mBaseCoords = NULL;
+
+ ll_aligned_free_16(mBaseNormals);
+ mBaseNormals = NULL;
+
+ ll_aligned_free_16(mBaseBinormals);
+ mBaseBinormals = NULL;
+
+ ll_aligned_free_16(mTexCoords);
+ mTexCoords = NULL;
+
+ ll_aligned_free_16(mDetailTexCoords);
+ mDetailTexCoords = NULL;
+
+ ll_aligned_free_16(mWeights);
+ mWeights = NULL;
+ }
+
+ mNumFaces = 0;
+ delete [] mFaces;
+ mFaces = NULL;
+
+ mNumJointNames = 0;
+ delete [] mJointNames;
+ mJointNames = NULL;
+
+ delete [] mTriangleIndices;
+ mTriangleIndices = NULL;
+
+// mVertFaceMap.deleteAllData();
+}
+
+// compate_int is used by the qsort function to sort the index array
+int compare_int(const void *a, const void *b);
+
+//-----------------------------------------------------------------------------
+// genIndices()
+//-----------------------------------------------------------------------------
+void LLPolyMeshSharedData::genIndices(S32 index_offset)
+{
+ if (index_offset == mLastIndexOffset)
+ {
+ return;
+ }
+
+ delete []mTriangleIndices;
+ mTriangleIndices = new U32[mNumTriangleIndices];
+
+ S32 cur_index = 0;
+ for (S32 i = 0; i < mNumFaces; i++)
+ {
+ mTriangleIndices[cur_index] = mFaces[i][0] + index_offset;
+ cur_index++;
+ mTriangleIndices[cur_index] = mFaces[i][1] + index_offset;
+ cur_index++;
+ mTriangleIndices[cur_index] = mFaces[i][2] + index_offset;
+ cur_index++;
+ }
+
+ mLastIndexOffset = index_offset;
+}
+
+//--------------------------------------------------------------------
+// LLPolyMeshSharedData::getNumKB()
+//--------------------------------------------------------------------
+U32 LLPolyMeshSharedData::getNumKB()
+{
+ U32 num_kb = sizeof(LLPolyMesh);
+
+ if (!isLOD())
+ {
+ num_kb += mNumVertices *
+ ( sizeof(LLVector3) + // coords
+ sizeof(LLVector3) + // normals
+ sizeof(LLVector2) ); // texCoords
+ }
+
+ if (mHasDetailTexCoords && !isLOD())
+ {
+ num_kb += mNumVertices * sizeof(LLVector2); // detailTexCoords
+ }
+
+ if (mHasWeights && !isLOD())
+ {
+ num_kb += mNumVertices * sizeof(float); // weights
+ }
+
+ num_kb += mNumFaces * sizeof(LLPolyFace); // faces
+
+ num_kb /= 1024;
+ return num_kb;
+}
+
+//-----------------------------------------------------------------------------
+// LLPolyMeshSharedData::allocateVertexData()
+//-----------------------------------------------------------------------------
+BOOL LLPolyMeshSharedData::allocateVertexData( U32 numVertices )
+{
+ U32 i;
+ mBaseCoords = (LLVector4a*) ll_aligned_malloc_16(numVertices*sizeof(LLVector4a));
+ mBaseNormals = (LLVector4a*) ll_aligned_malloc_16(numVertices*sizeof(LLVector4a));
+ mBaseBinormals = (LLVector4a*) ll_aligned_malloc_16(numVertices*sizeof(LLVector4a));
+ mTexCoords = (LLVector2*) ll_aligned_malloc_16(numVertices*sizeof(LLVector2));
+ mDetailTexCoords = (LLVector2*) ll_aligned_malloc_16(numVertices*sizeof(LLVector2));
+ mWeights = (F32*) ll_aligned_malloc_16(numVertices*sizeof(F32));
+ for (i = 0; i < numVertices; i++)
+ {
+ mBaseCoords[i].clear();
+ mBaseNormals[i].clear();
+ mBaseBinormals[i].clear();
+ mTexCoords[i].clear();
+ mWeights[i] = 0.f;
+ }
+ mNumVertices = numVertices;
+ return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// LLPolyMeshSharedData::allocateFaceData()
+//-----------------------------------------------------------------------------
+BOOL LLPolyMeshSharedData::allocateFaceData( U32 numFaces )
+{
+ mFaces = new LLPolyFace[ numFaces ];
+ mNumFaces = numFaces;
+ mNumTriangleIndices = mNumFaces * 3;
+ return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// LLPolyMeshSharedData::allocateJointNames()
+//-----------------------------------------------------------------------------
+BOOL LLPolyMeshSharedData::allocateJointNames( U32 numJointNames )
+{
+ mJointNames = new std::string[ numJointNames ];
+ mNumJointNames = numJointNames;
+ return TRUE;
+}
+
+//--------------------------------------------------------------------
+// LLPolyMeshSharedData::loadMesh()
+//--------------------------------------------------------------------
+BOOL LLPolyMeshSharedData::loadMesh( const std::string& fileName )
+{
+ //-------------------------------------------------------------------------
+ // Open the file
+ //-------------------------------------------------------------------------
+ if(fileName.empty())
+ {
+ llerrs << "Filename is Empty!" << llendl;
+ return FALSE;
+ }
+ LLFILE* fp = LLFile::fopen(fileName, "rb"); /*Flawfinder: ignore*/
+ if (!fp)
+ {
+ llerrs << "can't open: " << fileName << llendl;
+ return FALSE;
+ }
+
+ //-------------------------------------------------------------------------
+ // Read a chunk
+ //-------------------------------------------------------------------------
+ char header[128]; /*Flawfinder: ignore*/
+ if (fread(header, sizeof(char), 128, fp) != 128)
+ {
+ llwarns << "Short read" << llendl;
+ }
+
+ //-------------------------------------------------------------------------
+ // Check for proper binary header
+ //-------------------------------------------------------------------------
+ BOOL status = FALSE;
+ if ( strncmp(header, HEADER_BINARY, strlen(HEADER_BINARY)) == 0 ) /*Flawfinder: ignore*/
+ {
+ lldebugs << "Loading " << fileName << llendl;
+
+ //----------------------------------------------------------------
+ // File Header (seek past it)
+ //----------------------------------------------------------------
+ fseek(fp, 24, SEEK_SET);
+
+ //----------------------------------------------------------------
+ // HasWeights
+ //----------------------------------------------------------------
+ U8 hasWeights;
+ size_t numRead = fread(&hasWeights, sizeof(U8), 1, fp);
+ if (numRead != 1)
+ {
+ llerrs << "can't read HasWeights flag from " << fileName << llendl;
+ return FALSE;
+ }
+ if (!isLOD())
+ {
+ mHasWeights = (hasWeights==0) ? FALSE : TRUE;
+ }
+
+ //----------------------------------------------------------------
+ // HasDetailTexCoords
+ //----------------------------------------------------------------
+ U8 hasDetailTexCoords;
+ numRead = fread(&hasDetailTexCoords, sizeof(U8), 1, fp);
+ if (numRead != 1)
+ {
+ llerrs << "can't read HasDetailTexCoords flag from " << fileName << llendl;
+ return FALSE;
+ }
+
+ //----------------------------------------------------------------
+ // Position
+ //----------------------------------------------------------------
+ LLVector3 position;
+ numRead = fread(position.mV, sizeof(float), 3, fp);
+ llendianswizzle(position.mV, sizeof(float), 3);
+ if (numRead != 3)
+ {
+ llerrs << "can't read Position from " << fileName << llendl;
+ return FALSE;
+ }
+ setPosition( position );
+
+ //----------------------------------------------------------------
+ // Rotation
+ //----------------------------------------------------------------
+ LLVector3 rotationAngles;
+ numRead = fread(rotationAngles.mV, sizeof(float), 3, fp);
+ llendianswizzle(rotationAngles.mV, sizeof(float), 3);
+ if (numRead != 3)
+ {
+ llerrs << "can't read RotationAngles from " << fileName << llendl;
+ return FALSE;
+ }
+
+ U8 rotationOrder;
+ numRead = fread(&rotationOrder, sizeof(U8), 1, fp);
+
+ if (numRead != 1)
+ {
+ llerrs << "can't read RotationOrder from " << fileName << llendl;
+ return FALSE;
+ }
+
+ rotationOrder = 0;
+
+ setRotation( mayaQ( rotationAngles.mV[0],
+ rotationAngles.mV[1],
+ rotationAngles.mV[2],
+ (LLQuaternion::Order)rotationOrder ) );
+
+ //----------------------------------------------------------------
+ // Scale
+ //----------------------------------------------------------------
+ LLVector3 scale;
+ numRead = fread(scale.mV, sizeof(float), 3, fp);
+ llendianswizzle(scale.mV, sizeof(float), 3);
+ if (numRead != 3)
+ {
+ llerrs << "can't read Scale from " << fileName << llendl;
+ return FALSE;
+ }
+ setScale( scale );
+
+ //-------------------------------------------------------------------------
+ // Release any existing mesh geometry
+ //-------------------------------------------------------------------------
+ freeMeshData();
+
+ U16 numVertices = 0;
+
+ //----------------------------------------------------------------
+ // NumVertices
+ //----------------------------------------------------------------
+ if (!isLOD())
+ {
+ numRead = fread(&numVertices, sizeof(U16), 1, fp);
+ llendianswizzle(&numVertices, sizeof(U16), 1);
+ if (numRead != 1)
+ {
+ llerrs << "can't read NumVertices from " << fileName << llendl;
+ return FALSE;
+ }
+
+ allocateVertexData( numVertices );
+
+ for (U16 i = 0; i < numVertices; ++i)
+ {
+ //----------------------------------------------------------------
+ // Coords
+ //----------------------------------------------------------------
+ numRead = fread(&mBaseCoords[i], sizeof(float), 3, fp);
+ llendianswizzle(&mBaseCoords[i], sizeof(float), 3);
+ if (numRead != 3)
+ {
+ llerrs << "can't read Coordinates from " << fileName << llendl;
+ return FALSE;
+ }
+ }
+
+ for (U16 i = 0; i < numVertices; ++i)
+ {
+ //----------------------------------------------------------------
+ // Normals
+ //----------------------------------------------------------------
+ numRead = fread(&mBaseNormals[i], sizeof(float), 3, fp);
+ llendianswizzle(&mBaseNormals[i], sizeof(float), 3);
+ if (numRead != 3)
+ {
+ llerrs << " can't read Normals from " << fileName << llendl;
+ return FALSE;
+ }
+ }
+
+ for (U16 i = 0; i < numVertices; ++i)
+ {
+ //----------------------------------------------------------------
+ // Binormals
+ //----------------------------------------------------------------
+ numRead = fread(&mBaseBinormals[i], sizeof(float), 3, fp);
+ llendianswizzle(&mBaseBinormals[i], sizeof(float), 3);
+ if (numRead != 3)
+ {
+ llerrs << " can't read Binormals from " << fileName << llendl;
+ return FALSE;
+ }
+ }
+
+ //----------------------------------------------------------------
+ // TexCoords
+ //----------------------------------------------------------------
+ numRead = fread(mTexCoords, 2*sizeof(float), numVertices, fp);
+ llendianswizzle(mTexCoords, sizeof(float), 2*numVertices);
+ if (numRead != numVertices)
+ {
+ llerrs << "can't read TexCoords from " << fileName << llendl;
+ return FALSE;
+ }
+
+ //----------------------------------------------------------------
+ // DetailTexCoords
+ //----------------------------------------------------------------
+ if (mHasDetailTexCoords)
+ {
+ numRead = fread(mDetailTexCoords, 2*sizeof(float), numVertices, fp);
+ llendianswizzle(mDetailTexCoords, sizeof(float), 2*numVertices);
+ if (numRead != numVertices)
+ {
+ llerrs << "can't read DetailTexCoords from " << fileName << llendl;
+ return FALSE;
+ }
+ }
+
+ //----------------------------------------------------------------
+ // Weights
+ //----------------------------------------------------------------
+ if (mHasWeights)
+ {
+ numRead = fread(mWeights, sizeof(float), numVertices, fp);
+ llendianswizzle(mWeights, sizeof(float), numVertices);
+ if (numRead != numVertices)
+ {
+ llerrs << "can't read Weights from " << fileName << llendl;
+ return FALSE;
+ }
+ }
+ }
+
+ //----------------------------------------------------------------
+ // NumFaces
+ //----------------------------------------------------------------
+ U16 numFaces;
+ numRead = fread(&numFaces, sizeof(U16), 1, fp);
+ llendianswizzle(&numFaces, sizeof(U16), 1);
+ if (numRead != 1)
+ {
+ llerrs << "can't read NumFaces from " << fileName << llendl;
+ return FALSE;
+ }
+ allocateFaceData( numFaces );
+
+
+ //----------------------------------------------------------------
+ // Faces
+ //----------------------------------------------------------------
+ U32 i;
+ U32 numTris = 0;
+ for (i = 0; i < numFaces; i++)
+ {
+ S16 face[3];
+ numRead = fread(face, sizeof(U16), 3, fp);
+ llendianswizzle(face, sizeof(U16), 3);
+ if (numRead != 3)
+ {
+ llerrs << "can't read Face[" << i << "] from " << fileName << llendl;
+ return FALSE;
+ }
+ if (mReferenceData)
+ {
+ llassert(face[0] < mReferenceData->mNumVertices);
+ llassert(face[1] < mReferenceData->mNumVertices);
+ llassert(face[2] < mReferenceData->mNumVertices);
+ }
+
+ if (isLOD())
+ {
+ // store largest index in case of LODs
+ for (S32 j = 0; j < 3; j++)
+ {
+ if (face[j] > mNumVertices - 1)
+ {
+ mNumVertices = face[j] + 1;
+ }
+ }
+ }
+ mFaces[i][0] = face[0];
+ mFaces[i][1] = face[1];
+ mFaces[i][2] = face[2];
+
+// S32 j;
+// for(j = 0; j < 3; j++)
+// {
+// LLDynamicArray<S32> *face_list = mVertFaceMap.getIfThere(face[j]);
+// if (!face_list)
+// {
+// face_list = new LLDynamicArray<S32>;
+// mVertFaceMap.addData(face[j], face_list);
+// }
+// face_list->put(i);
+// }
+
+ numTris++;
+ }
+
+ lldebugs << "verts: " << numVertices
+ << ", faces: " << numFaces
+ << ", tris: " << numTris
+ << llendl;
+
+ //----------------------------------------------------------------
+ // NumSkinJoints
+ //----------------------------------------------------------------
+ if (!isLOD())
+ {
+ U16 numSkinJoints = 0;
+ if ( mHasWeights )
+ {
+ numRead = fread(&numSkinJoints, sizeof(U16), 1, fp);
+ llendianswizzle(&numSkinJoints, sizeof(U16), 1);
+ if (numRead != 1)
+ {
+ llerrs << "can't read NumSkinJoints from " << fileName << llendl;
+ return FALSE;
+ }
+ allocateJointNames( numSkinJoints );
+ }
+
+ //----------------------------------------------------------------
+ // SkinJoints
+ //----------------------------------------------------------------
+ for (i=0; i < numSkinJoints; i++)
+ {
+ char jointName[64+1];
+ numRead = fread(jointName, sizeof(jointName)-1, 1, fp);
+ jointName[sizeof(jointName)-1] = '\0'; // ensure nul-termination
+ if (numRead != 1)
+ {
+ llerrs << "can't read Skin[" << i << "].Name from " << fileName << llendl;
+ return FALSE;
+ }
+
+ std::string *jn = &mJointNames[i];
+ *jn = jointName;
+ }
+
+ //-------------------------------------------------------------------------
+ // look for morph section
+ //-------------------------------------------------------------------------
+ char morphName[64+1];
+ morphName[sizeof(morphName)-1] = '\0'; // ensure nul-termination
+ while(fread(&morphName, sizeof(char), 64, fp) == 64)
+ {
+ if (!strcmp(morphName, "End Morphs"))
+ {
+ // we reached the end of the morphs
+ break;
+ }
+ LLPolyMorphData* morph_data = new LLPolyMorphData(std::string(morphName));
+
+ BOOL result = morph_data->loadBinary(fp, this);
+
+ if (!result)
+ {
+ delete morph_data;
+ continue;
+ }
+
+ mMorphData.insert(morph_data);
+
+ if (!strcmp(morphName, "Breast_Female_Cleavage"))
+ {
+ mMorphData.insert(clone_morph_param_cleavage(morph_data,
+ .75f,
+ "Breast_Physics_LeftRight_Driven"));
+ }
+
+ if (!strcmp(morphName, "Breast_Female_Cleavage"))
+ {
+ mMorphData.insert(clone_morph_param_duplicate(morph_data,
+ "Breast_Physics_InOut_Driven"));
+ }
+ if (!strcmp(morphName, "Breast_Gravity"))
+ {
+ mMorphData.insert(clone_morph_param_duplicate(morph_data,
+ "Breast_Physics_UpDown_Driven"));
+ }
+
+ if (!strcmp(morphName, "Big_Belly_Torso"))
+ {
+ mMorphData.insert(clone_morph_param_direction(morph_data,
+ LLVector3(0,0,0.05f),
+ "Belly_Physics_Torso_UpDown_Driven"));
+ }
+
+ if (!strcmp(morphName, "Big_Belly_Legs"))
+ {
+ mMorphData.insert(clone_morph_param_direction(morph_data,
+ LLVector3(0,0,0.05f),
+ "Belly_Physics_Legs_UpDown_Driven"));
+ }
+
+ if (!strcmp(morphName, "skirt_belly"))
+ {
+ mMorphData.insert(clone_morph_param_direction(morph_data,
+ LLVector3(0,0,0.05f),
+ "Belly_Physics_Skirt_UpDown_Driven"));
+ }
+
+ if (!strcmp(morphName, "Small_Butt"))
+ {
+ mMorphData.insert(clone_morph_param_direction(morph_data,
+ LLVector3(0,0,0.05f),
+ "Butt_Physics_UpDown_Driven"));
+ }
+ if (!strcmp(morphName, "Small_Butt"))
+ {
+ mMorphData.insert(clone_morph_param_direction(morph_data,
+ LLVector3(0,0.03f,0),
+ "Butt_Physics_LeftRight_Driven"));
+ }
+ }
+
+ S32 numRemaps;
+ if (fread(&numRemaps, sizeof(S32), 1, fp) == 1)
+ {
+ llendianswizzle(&numRemaps, sizeof(S32), 1);
+ for (S32 i = 0; i < numRemaps; i++)
+ {
+ S32 remapSrc;
+ S32 remapDst;
+ if (fread(&remapSrc, sizeof(S32), 1, fp) != 1)
+ {
+ llerrs << "can't read source vertex in vertex remap data" << llendl;
+ break;
+ }
+ if (fread(&remapDst, sizeof(S32), 1, fp) != 1)
+ {
+ llerrs << "can't read destination vertex in vertex remap data" << llendl;
+ break;
+ }
+ llendianswizzle(&remapSrc, sizeof(S32), 1);
+ llendianswizzle(&remapDst, sizeof(S32), 1);
+
+ mSharedVerts[remapSrc] = remapDst;
+ }
+ }
+ }
+
+ status = TRUE;
+ }
+ else
+ {
+ llerrs << "invalid mesh file header: " << fileName << llendl;
+ status = FALSE;
+ }
+
+ if (0 == mNumJointNames)
+ {
+ allocateJointNames(1);
+ }
+
+ fclose( fp );
+
+ return status;
+}
+
+//-----------------------------------------------------------------------------
+// getSharedVert()
+//-----------------------------------------------------------------------------
+const S32 *LLPolyMeshSharedData::getSharedVert(S32 vert)
+{
+ if (mSharedVerts.count(vert) > 0)
+ {
+ return &mSharedVerts[vert];
+ }
+ return NULL;
+}
+
+//-----------------------------------------------------------------------------
+// getUV()
+//-----------------------------------------------------------------------------
+const LLVector2 &LLPolyMeshSharedData::getUVs(U32 index)
+{
+ // TODO: convert all index variables to S32
+ llassert((S32)index < mNumVertices);
+
+ return mTexCoords[index];
+}
+
+//-----------------------------------------------------------------------------
+// LLPolyMesh()
+//-----------------------------------------------------------------------------
+LLPolyMesh::LLPolyMesh(LLPolyMeshSharedData *shared_data, LLPolyMesh *reference_mesh)
+{
+ llassert(shared_data);
+
+ mSharedData = shared_data;
+ mReferenceMesh = reference_mesh;
+ mAvatarp = NULL;
+ mVertexData = NULL;
+
+ mCurVertexCount = 0;
+ mFaceIndexCount = 0;
+ mFaceIndexOffset = 0;
+ mFaceVertexCount = 0;
+ mFaceVertexOffset = 0;
+
+ if (shared_data->isLOD() && reference_mesh)
+ {
+ mCoords = reference_mesh->mCoords;
+ mNormals = reference_mesh->mNormals;
+ mScaledNormals = reference_mesh->mScaledNormals;
+ mBinormals = reference_mesh->mBinormals;
+ mScaledBinormals = reference_mesh->mScaledBinormals;
+ mTexCoords = reference_mesh->mTexCoords;
+ mClothingWeights = reference_mesh->mClothingWeights;
+ }
+ else
+ {
+ // Allocate memory without initializing every vector
+ // NOTE: This makes asusmptions about the size of LLVector[234]
+ S32 nverts = mSharedData->mNumVertices;
+ //make sure it's an even number of verts for alignment
+ nverts += nverts%2;
+ S32 nfloats = nverts * (
+ 4 + //coords
+ 4 + //normals
+ 4 + //weights
+ 2 + //coords
+ 4 + //scaled normals
+ 4 + //binormals
+ 4); //scaled binormals
+
+ //use 16 byte aligned vertex data to make LLPolyMesh SSE friendly
+ mVertexData = (F32*) ll_aligned_malloc_16(nfloats*4);
+ S32 offset = 0;
+ mCoords = (LLVector4a*)(mVertexData + offset); offset += 4*nverts;
+ mNormals = (LLVector4a*)(mVertexData + offset); offset += 4*nverts;
+ mClothingWeights = (LLVector4a*)(mVertexData + offset); offset += 4*nverts;
+ mTexCoords = (LLVector2*)(mVertexData + offset); offset += 2*nverts;
+ mScaledNormals = (LLVector4a*)(mVertexData + offset); offset += 4*nverts;
+ mBinormals = (LLVector4a*)(mVertexData + offset); offset += 4*nverts;
+ mScaledBinormals = (LLVector4a*)(mVertexData + offset); offset += 4*nverts;
+ initializeForMorph();
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// ~LLPolyMesh()
+//-----------------------------------------------------------------------------
+LLPolyMesh::~LLPolyMesh()
+{
+ S32 i;
+ for (i = 0; i < mJointRenderData.count(); i++)
+ {
+ delete mJointRenderData[i];
+ mJointRenderData[i] = NULL;
+ }
+
+ ll_aligned_free_16(mVertexData);
+
+}
+
+
+//-----------------------------------------------------------------------------
+// LLPolyMesh::getMesh()
+//-----------------------------------------------------------------------------
+LLPolyMesh *LLPolyMesh::getMesh(const std::string &name, LLPolyMesh* reference_mesh)
+{
+ //-------------------------------------------------------------------------
+ // search for an existing mesh by this name
+ //-------------------------------------------------------------------------
+ LLPolyMeshSharedData* meshSharedData = get_if_there(sGlobalSharedMeshList, name, (LLPolyMeshSharedData*)NULL);
+ if (meshSharedData)
+ {
+// llinfos << "Polymesh " << name << " found in global mesh table." << llendl;
+ LLPolyMesh *poly_mesh = new LLPolyMesh(meshSharedData, reference_mesh);
+ return poly_mesh;
+ }
+
+ //-------------------------------------------------------------------------
+ // if not found, create a new one, add it to the list
+ //-------------------------------------------------------------------------
+ std::string full_path;
+ full_path = gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,name);
+
+ LLPolyMeshSharedData *mesh_data = new LLPolyMeshSharedData();
+ if (reference_mesh)
+ {
+ mesh_data->setupLOD(reference_mesh->getSharedData());
+ }
+ if ( ! mesh_data->loadMesh( full_path ) )
+ {
+ delete mesh_data;
+ return NULL;
+ }
+
+ LLPolyMesh *poly_mesh = new LLPolyMesh(mesh_data, reference_mesh);
+
+// llinfos << "Polymesh " << name << " added to global mesh table." << llendl;
+ sGlobalSharedMeshList[name] = poly_mesh->mSharedData;
+
+ return poly_mesh;
+}
+
+//-----------------------------------------------------------------------------
+// LLPolyMesh::freeAllMeshes()
+//-----------------------------------------------------------------------------
+void LLPolyMesh::freeAllMeshes()
+{
+ // delete each item in the global lists
+ for_each(sGlobalSharedMeshList.begin(), sGlobalSharedMeshList.end(), DeletePairedPointer());
+ sGlobalSharedMeshList.clear();
+}
+
+LLPolyMeshSharedData *LLPolyMesh::getSharedData() const
+{
+ return mSharedData;
+}
+
+
+//--------------------------------------------------------------------
+// LLPolyMesh::dumpDiagInfo()
+//--------------------------------------------------------------------
+void LLPolyMesh::dumpDiagInfo()
+{
+ // keep track of totals
+ U32 total_verts = 0;
+ U32 total_faces = 0;
+ U32 total_kb = 0;
+
+ std::string buf;
+
+ llinfos << "-----------------------------------------------------" << llendl;
+ llinfos << " Global PolyMesh Table (DEBUG only)" << llendl;
+ llinfos << " Verts Faces Mem(KB) Name" << llendl;
+ llinfos << "-----------------------------------------------------" << llendl;
+
+ // print each loaded mesh, and it's memory usage
+ for(LLPolyMeshSharedDataTable::iterator iter = sGlobalSharedMeshList.begin();
+ iter != sGlobalSharedMeshList.end(); ++iter)
+ {
+ const std::string& mesh_name = iter->first;
+ LLPolyMeshSharedData* mesh = iter->second;
+
+ S32 num_verts = mesh->mNumVertices;
+ S32 num_faces = mesh->mNumFaces;
+ U32 num_kb = mesh->getNumKB();
+
+ buf = llformat("%8d %8d %8d %s", num_verts, num_faces, num_kb, mesh_name.c_str());
+ llinfos << buf << llendl;
+
+ total_verts += num_verts;
+ total_faces += num_faces;
+ total_kb += num_kb;
+ }
+
+ llinfos << "-----------------------------------------------------" << llendl;
+ buf = llformat("%8d %8d %8d TOTAL", total_verts, total_faces, total_kb );
+ llinfos << buf << llendl;
+ llinfos << "-----------------------------------------------------" << llendl;
+}
+
+//-----------------------------------------------------------------------------
+// getWritableCoords()
+//-----------------------------------------------------------------------------
+LLVector4a *LLPolyMesh::getWritableCoords()
+{
+ return mCoords;
+}
+
+//-----------------------------------------------------------------------------
+// getWritableNormals()
+//-----------------------------------------------------------------------------
+LLVector4a *LLPolyMesh::getWritableNormals()
+{
+ return mNormals;
+}
+
+//-----------------------------------------------------------------------------
+// getWritableBinormals()
+//-----------------------------------------------------------------------------
+LLVector4a *LLPolyMesh::getWritableBinormals()
+{
+ return mBinormals;
+}
+
+
+//-----------------------------------------------------------------------------
+// getWritableClothingWeights()
+//-----------------------------------------------------------------------------
+LLVector4a *LLPolyMesh::getWritableClothingWeights()
+{
+ return mClothingWeights;
+}
+
+//-----------------------------------------------------------------------------
+// getWritableTexCoords()
+//-----------------------------------------------------------------------------
+LLVector2 *LLPolyMesh::getWritableTexCoords()
+{
+ return mTexCoords;
+}
+
+//-----------------------------------------------------------------------------
+// getScaledNormals()
+//-----------------------------------------------------------------------------
+LLVector4a *LLPolyMesh::getScaledNormals()
+{
+ return mScaledNormals;
+}
+
+//-----------------------------------------------------------------------------
+// getScaledBinormals()
+//-----------------------------------------------------------------------------
+LLVector4a *LLPolyMesh::getScaledBinormals()
+{
+ return mScaledBinormals;
+}
+
+
+//-----------------------------------------------------------------------------
+// initializeForMorph()
+//-----------------------------------------------------------------------------
+void LLPolyMesh::initializeForMorph()
+{
+ LLVector4a::memcpyNonAliased16((F32*) mCoords, (F32*) mSharedData->mBaseCoords, sizeof(LLVector4a) * mSharedData->mNumVertices);
+ LLVector4a::memcpyNonAliased16((F32*) mNormals, (F32*) mSharedData->mBaseNormals, sizeof(LLVector4a) * mSharedData->mNumVertices);
+ LLVector4a::memcpyNonAliased16((F32*) mScaledNormals, (F32*) mSharedData->mBaseNormals, sizeof(LLVector4a) * mSharedData->mNumVertices);
+ LLVector4a::memcpyNonAliased16((F32*) mBinormals, (F32*) mSharedData->mBaseNormals, sizeof(LLVector4a) * mSharedData->mNumVertices);
+ LLVector4a::memcpyNonAliased16((F32*) mScaledBinormals, (F32*) mSharedData->mBaseNormals, sizeof(LLVector4a) * mSharedData->mNumVertices);
+ LLVector4a::memcpyNonAliased16((F32*) mTexCoords, (F32*) mSharedData->mTexCoords, sizeof(LLVector2) * (mSharedData->mNumVertices + mSharedData->mNumVertices%2));
+
+ for (U32 i = 0; i < mSharedData->mNumVertices; ++i)
+ {
+ mClothingWeights[i].clear();
+ }
+}
+
+//-----------------------------------------------------------------------------
+// getMorphData()
+//-----------------------------------------------------------------------------
+LLPolyMorphData* LLPolyMesh::getMorphData(const std::string& morph_name)
+{
+ if (!mSharedData)
+ return NULL;
+ for (LLPolyMeshSharedData::morphdata_list_t::iterator iter = mSharedData->mMorphData.begin();
+ iter != mSharedData->mMorphData.end(); ++iter)
+ {
+ LLPolyMorphData *morph_data = *iter;
+ if (morph_data->getName() == morph_name)
+ {
+ return morph_data;
+ }
+ }
+ return NULL;
+}
+
+//-----------------------------------------------------------------------------
+// removeMorphData()
+//-----------------------------------------------------------------------------
+// // erasing but not deleting seems bad, but fortunately we don't actually use this...
+// void LLPolyMesh::removeMorphData(LLPolyMorphData *morph_target)
+// {
+// if (!mSharedData)
+// return;
+// mSharedData->mMorphData.erase(morph_target);
+// }
+
+//-----------------------------------------------------------------------------
+// deleteAllMorphData()
+//-----------------------------------------------------------------------------
+// void LLPolyMesh::deleteAllMorphData()
+// {
+// if (!mSharedData)
+// return;
+
+// for_each(mSharedData->mMorphData.begin(), mSharedData->mMorphData.end(), DeletePointer());
+// mSharedData->mMorphData.clear();
+// }
+
+//-----------------------------------------------------------------------------
+// getWritableWeights()
+//-----------------------------------------------------------------------------
+F32* LLPolyMesh::getWritableWeights() const
+{
+ return mSharedData->mWeights;
+}
+
+// End
diff --git a/indra/llappearance/llpolymesh.h b/indra/llappearance/llpolymesh.h
new file mode 100644
index 0000000000..ef1dfb1adb
--- /dev/null
+++ b/indra/llappearance/llpolymesh.h
@@ -0,0 +1,369 @@
+/**
+ * @file llpolymesh.h
+ * @brief Implementation of LLPolyMesh class
+ *
+ * $LicenseInfo:firstyear=2001&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$
+ */
+
+#ifndef LL_LLPOLYMESHINTERFACE_H
+#define LL_LLPOLYMESHINTERFACE_H
+
+#include <string>
+#include <map>
+#include "llstl.h"
+
+#include "v3math.h"
+#include "v2math.h"
+#include "llquaternion.h"
+#include "llpolymorph.h"
+#include "lljoint.h"
+//#include "lldarray.h"
+
+class LLSkinJoint;
+class LLAvatarAppearance;
+class LLWearable;
+
+//#define USE_STRIPS // Use tri-strips for rendering.
+
+//-----------------------------------------------------------------------------
+// LLPolyFace
+// A set of 4 vertex indices.
+// An LLPolyFace can represent either a triangle or quad.
+// If the last index is -1, it's a triangle.
+//-----------------------------------------------------------------------------
+typedef S32 LLPolyFace[3];
+
+//struct PrimitiveGroup;
+
+//-----------------------------------------------------------------------------
+// LLPolyMesh
+// A polyhedra consisting of any number of triangles and quads.
+// All instances contain a set of faces, and optionally may include
+// faces grouped into named face sets.
+//-----------------------------------------------------------------------------
+class LLPolyMorphTarget;
+
+class LLPolyMeshSharedData
+{
+ friend class LLPolyMesh;
+private:
+ // transform data
+ LLVector3 mPosition;
+ LLQuaternion mRotation;
+ LLVector3 mScale;
+
+ // vertex data
+ S32 mNumVertices;
+ LLVector4a *mBaseCoords;
+ LLVector4a *mBaseNormals;
+ LLVector4a *mBaseBinormals;
+ LLVector2 *mTexCoords;
+ LLVector2 *mDetailTexCoords;
+ F32 *mWeights;
+
+ BOOL mHasWeights;
+ BOOL mHasDetailTexCoords;
+
+ // face data
+ S32 mNumFaces;
+ LLPolyFace *mFaces;
+
+ // face set data
+ U32 mNumJointNames;
+ std::string* mJointNames;
+
+ // morph targets
+ typedef std::set<LLPolyMorphData*> morphdata_list_t;
+ morphdata_list_t mMorphData;
+
+ std::map<S32, S32> mSharedVerts;
+
+ LLPolyMeshSharedData* mReferenceData;
+ S32 mLastIndexOffset;
+
+public:
+ // Temporarily...
+ // Triangle indices
+ U32 mNumTriangleIndices;
+ U32 *mTriangleIndices;
+
+public:
+ LLPolyMeshSharedData();
+ ~LLPolyMeshSharedData();
+
+private:
+ void setupLOD(LLPolyMeshSharedData* reference_data);
+
+ // Frees all mesh memory resources
+ void freeMeshData();
+
+ void setPosition( const LLVector3 &pos ) { mPosition = pos; }
+ void setRotation( const LLQuaternion &rot ) { mRotation = rot; }
+ void setScale( const LLVector3 &scale ) { mScale = scale; }
+
+ BOOL allocateVertexData( U32 numVertices );
+
+ BOOL allocateFaceData( U32 numFaces );
+
+ BOOL allocateJointNames( U32 numJointNames );
+
+ // Retrieve the number of KB of memory used by this instance
+ U32 getNumKB();
+
+ // Load mesh data from file
+ BOOL loadMesh( const std::string& fileName );
+
+public:
+ void genIndices(S32 offset);
+
+ const LLVector2 &getUVs(U32 index);
+
+ const S32 *getSharedVert(S32 vert);
+
+ BOOL isLOD() { return (mReferenceData != NULL); }
+};
+
+
+class LLJointRenderData
+{
+public:
+ LLJointRenderData(const LLMatrix4* world_matrix, LLSkinJoint* skin_joint) : mWorldMatrix(world_matrix), mSkinJoint(skin_joint) {}
+ ~LLJointRenderData(){}
+
+ const LLMatrix4* mWorldMatrix;
+ LLSkinJoint* mSkinJoint;
+};
+
+
+class LLPolyMesh
+{
+public:
+
+ // Constructor
+ LLPolyMesh(LLPolyMeshSharedData *shared_data, LLPolyMesh *reference_mesh);
+
+ // Destructor
+ ~LLPolyMesh();
+
+ // Requests a mesh by name.
+ // If the mesh already exists in the global mesh table, it is returned,
+ // otherwise it is loaded from file, added to the table, and returned.
+ static LLPolyMesh *getMesh( const std::string &name, LLPolyMesh* reference_mesh = NULL);
+
+ // Frees all loaded meshes.
+ // This should only be called once you know there are no outstanding
+ // references to these objects. Generally, upon exit of the application.
+ static void freeAllMeshes();
+
+ //--------------------------------------------------------------------
+ // Transform Data Access
+ //--------------------------------------------------------------------
+ // Get position
+ const LLVector3 &getPosition() {
+ llassert (mSharedData);
+ return mSharedData->mPosition;
+ }
+
+ // Get rotation
+ const LLQuaternion &getRotation() {
+ llassert (mSharedData);
+ return mSharedData->mRotation;
+ }
+
+ // Get scale
+ const LLVector3 &getScale() {
+ llassert (mSharedData);
+ return mSharedData->mScale;
+ }
+
+ //--------------------------------------------------------------------
+ // Vertex Data Access
+ //--------------------------------------------------------------------
+ // Get number of vertices
+ U32 getNumVertices() {
+ llassert (mSharedData);
+ return mSharedData->mNumVertices;
+ }
+
+ // Returns whether or not the mesh has detail texture coords
+ BOOL hasDetailTexCoords() {
+ llassert (mSharedData);
+ return mSharedData->mHasDetailTexCoords;
+ }
+
+ // Returns whether or not the mesh has vertex weights
+ BOOL hasWeights() const{
+ llassert (mSharedData);
+ return mSharedData->mHasWeights;
+ }
+
+ // Get coords
+ const LLVector4a *getCoords() const{
+ return mCoords;
+ }
+
+ // non const version
+ LLVector4a *getWritableCoords();
+
+ // Get normals
+ const LLVector4a *getNormals() const{
+ return mNormals;
+ }
+
+ // Get normals
+ const LLVector4a *getBinormals() const{
+ return mBinormals;
+ }
+
+ // Get base mesh normals
+ const LLVector4a *getBaseNormals() const{
+ llassert(mSharedData);
+ return mSharedData->mBaseNormals;
+ }
+
+ // Get base mesh normals
+ const LLVector4a *getBaseBinormals() const{
+ llassert(mSharedData);
+ return mSharedData->mBaseBinormals;
+ }
+
+ // intermediate morphed normals and output normals
+ LLVector4a *getWritableNormals();
+ LLVector4a *getScaledNormals();
+
+ LLVector4a *getWritableBinormals();
+ LLVector4a *getScaledBinormals();
+
+ // Get texCoords
+ const LLVector2 *getTexCoords() const {
+ return mTexCoords;
+ }
+
+ // non const version
+ LLVector2 *getWritableTexCoords();
+
+ // Get detailTexCoords
+ const LLVector2 *getDetailTexCoords() const {
+ llassert (mSharedData);
+ return mSharedData->mDetailTexCoords;
+ }
+
+ // Get weights
+ const F32 *getWeights() const {
+ llassert (mSharedData);
+ return mSharedData->mWeights;
+ }
+
+ F32 *getWritableWeights() const;
+
+ LLVector4a *getWritableClothingWeights();
+
+ const LLVector4a *getClothingWeights()
+ {
+ return mClothingWeights;
+ }
+
+ //--------------------------------------------------------------------
+ // Face Data Access
+ //--------------------------------------------------------------------
+ // Get number of faces
+ S32 getNumFaces() {
+ llassert (mSharedData);
+ return mSharedData->mNumFaces;
+ }
+
+ // Get faces
+ LLPolyFace *getFaces() {
+ llassert (mSharedData);
+ return mSharedData->mFaces;
+ }
+
+ U32 getNumJointNames() {
+ llassert (mSharedData);
+ return mSharedData->mNumJointNames;
+ }
+
+ std::string *getJointNames() {
+ llassert (mSharedData);
+ return mSharedData->mJointNames;
+ }
+
+ LLPolyMorphData* getMorphData(const std::string& morph_name);
+// void removeMorphData(LLPolyMorphData *morph_target);
+// void deleteAllMorphData();
+
+ LLPolyMeshSharedData *getSharedData() const;
+ LLPolyMesh *getReferenceMesh() { return mReferenceMesh ? mReferenceMesh : this; }
+
+ // Get indices
+ U32* getIndices() { return mSharedData ? mSharedData->mTriangleIndices : NULL; }
+
+ BOOL isLOD() { return mSharedData && mSharedData->isLOD(); }
+
+ void setAvatar(LLAvatarAppearance* avatarp) { mAvatarp = avatarp; }
+ LLAvatarAppearance* getAvatar() { return mAvatarp; }
+
+ LLDynamicArray<LLJointRenderData*> mJointRenderData;
+
+ U32 mFaceVertexOffset;
+ U32 mFaceVertexCount;
+ U32 mFaceIndexOffset;
+ U32 mFaceIndexCount;
+ U32 mCurVertexCount;
+private:
+ void initializeForMorph();
+
+ // Dumps diagnostic information about the global mesh table
+ static void dumpDiagInfo();
+
+protected:
+ // mesh data shared across all instances of a given mesh
+ LLPolyMeshSharedData *mSharedData;
+ // Single array of floats for allocation / deletion
+ F32 *mVertexData;
+ // deformed vertices (resulting from application of morph targets)
+ LLVector4a *mCoords;
+ // deformed normals (resulting from application of morph targets)
+ LLVector4a *mScaledNormals;
+ // output normals (after normalization)
+ LLVector4a *mNormals;
+ // deformed binormals (resulting from application of morph targets)
+ LLVector4a *mScaledBinormals;
+ // output binormals (after normalization)
+ LLVector4a *mBinormals;
+ // weight values that mark verts as clothing/skin
+ LLVector4a *mClothingWeights;
+ // output texture coordinates
+ LLVector2 *mTexCoords;
+
+ LLPolyMesh *mReferenceMesh;
+
+ // global mesh list
+ typedef std::map<std::string, LLPolyMeshSharedData*> LLPolyMeshSharedDataTable;
+ static LLPolyMeshSharedDataTable sGlobalSharedMeshList;
+
+ // Backlink only; don't make this an LLPointer.
+ LLAvatarAppearance* mAvatarp;
+};
+
+#endif // LL_LLPOLYMESHINTERFACE_H
+
diff --git a/indra/llappearance/llpolymorph.cpp b/indra/llappearance/llpolymorph.cpp
new file mode 100644
index 0000000000..93c2f15a53
--- /dev/null
+++ b/indra/llappearance/llpolymorph.cpp
@@ -0,0 +1,802 @@
+/**
+ * @file llpolymorph.cpp
+ * @brief Implementation of LLPolyMesh class
+ *
+ * $LicenseInfo:firstyear=2001&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$
+ */
+
+//-----------------------------------------------------------------------------
+// Header Files
+//-----------------------------------------------------------------------------
+
+#include "llpolymorph.h"
+#include "llavatarappearance.h"
+#include "llavatarjoint.h"
+#include "llwearable.h"
+#include "llxmltree.h"
+#include "llendianswizzle.h"
+#include "llpolymesh.h"
+
+//#include "../tools/imdebug/imdebug.h"
+
+const F32 NORMAL_SOFTEN_FACTOR = 0.65f;
+
+//-----------------------------------------------------------------------------
+// LLPolyMorphData()
+//-----------------------------------------------------------------------------
+LLPolyMorphData::LLPolyMorphData(const std::string& morph_name)
+ : mName(morph_name)
+{
+ mNumIndices = 0;
+ mCurrentIndex = 0;
+ mTotalDistortion = 0.f;
+ mAvgDistortion.clear();
+ mMaxDistortion = 0.f;
+ mVertexIndices = NULL;
+ mCoords = NULL;
+ mNormals = NULL;
+ mBinormals = NULL;
+ mTexCoords = NULL;
+
+ mMesh = NULL;
+}
+
+LLPolyMorphData::LLPolyMorphData(const LLPolyMorphData &rhs) :
+ mName(rhs.mName),
+ mNumIndices(rhs.mNumIndices),
+ mTotalDistortion(rhs.mTotalDistortion),
+ mAvgDistortion(rhs.mAvgDistortion),
+ mMaxDistortion(rhs.mMaxDistortion),
+ mVertexIndices(NULL),
+ mCoords(NULL),
+ mNormals(NULL),
+ mBinormals(NULL),
+ mTexCoords(NULL)
+{
+ const S32 numVertices = mNumIndices;
+
+ U32 size = sizeof(LLVector4a)*numVertices;
+
+ mCoords = static_cast<LLVector4a*>( ll_aligned_malloc_16(size) );
+ mNormals = static_cast<LLVector4a*>( ll_aligned_malloc_16(size) );
+ mBinormals = static_cast<LLVector4a*>( ll_aligned_malloc_16(size) );
+ mTexCoords = new LLVector2[numVertices];
+ mVertexIndices = new U32[numVertices];
+
+ for (S32 v=0; v < numVertices; v++)
+ {
+ mCoords[v] = rhs.mCoords[v];
+ mNormals[v] = rhs.mNormals[v];
+ mBinormals[v] = rhs.mBinormals[v];
+ mTexCoords[v] = rhs.mTexCoords[v];
+ mVertexIndices[v] = rhs.mVertexIndices[v];
+ }
+}
+
+//-----------------------------------------------------------------------------
+// ~LLPolyMorphData()
+//-----------------------------------------------------------------------------
+LLPolyMorphData::~LLPolyMorphData()
+{
+ freeData();
+}
+
+//-----------------------------------------------------------------------------
+// loadBinary()
+//-----------------------------------------------------------------------------
+BOOL LLPolyMorphData::loadBinary(LLFILE *fp, LLPolyMeshSharedData *mesh)
+{
+ S32 numVertices;
+ S32 numRead;
+
+ numRead = fread(&numVertices, sizeof(S32), 1, fp);
+ llendianswizzle(&numVertices, sizeof(S32), 1);
+ if (numRead != 1)
+ {
+ llwarns << "Can't read number of morph target vertices" << llendl;
+ return FALSE;
+ }
+
+ //-------------------------------------------------------------------------
+ // free any existing data
+ //-------------------------------------------------------------------------
+ freeData();
+
+ //-------------------------------------------------------------------------
+ // allocate vertices
+ //-------------------------------------------------------------------------
+
+ U32 size = sizeof(LLVector4a)*numVertices;
+
+ mCoords = static_cast<LLVector4a*>(ll_aligned_malloc_16(size));
+ mNormals = static_cast<LLVector4a*>(ll_aligned_malloc_16(size));
+ mBinormals = static_cast<LLVector4a*>(ll_aligned_malloc_16(size));
+
+ mTexCoords = new LLVector2[numVertices];
+ // Actually, we are allocating more space than we need for the skiplist
+ mVertexIndices = new U32[numVertices];
+ mNumIndices = 0;
+ mTotalDistortion = 0.f;
+ mMaxDistortion = 0.f;
+ mAvgDistortion.clear();
+ mMesh = mesh;
+
+ //-------------------------------------------------------------------------
+ // read vertices
+ //-------------------------------------------------------------------------
+ for(S32 v = 0; v < numVertices; v++)
+ {
+ numRead = fread(&mVertexIndices[v], sizeof(U32), 1, fp);
+ llendianswizzle(&mVertexIndices[v], sizeof(U32), 1);
+ if (numRead != 1)
+ {
+ llwarns << "Can't read morph target vertex number" << llendl;
+ return FALSE;
+ }
+
+ if (mVertexIndices[v] > 10000)
+ {
+ llerrs << "Bad morph index: " << mVertexIndices[v] << llendl;
+ }
+
+
+ numRead = fread(&mCoords[v], sizeof(F32), 3, fp);
+ llendianswizzle(&mCoords[v], sizeof(F32), 3);
+ if (numRead != 3)
+ {
+ llwarns << "Can't read morph target vertex coordinates" << llendl;
+ return FALSE;
+ }
+
+ F32 magnitude = mCoords[v].getLength3().getF32();
+
+ mTotalDistortion += magnitude;
+ LLVector4a t;
+ t.setAbs(mCoords[v]);
+ mAvgDistortion.add(t);
+
+ if (magnitude > mMaxDistortion)
+ {
+ mMaxDistortion = magnitude;
+ }
+
+ numRead = fread(&mNormals[v], sizeof(F32), 3, fp);
+ llendianswizzle(&mNormals[v], sizeof(F32), 3);
+ if (numRead != 3)
+ {
+ llwarns << "Can't read morph target normal" << llendl;
+ return FALSE;
+ }
+
+ numRead = fread(&mBinormals[v], sizeof(F32), 3, fp);
+ llendianswizzle(&mBinormals[v], sizeof(F32), 3);
+ if (numRead != 3)
+ {
+ llwarns << "Can't read morph target binormal" << llendl;
+ return FALSE;
+ }
+
+
+ numRead = fread(&mTexCoords[v].mV, sizeof(F32), 2, fp);
+ llendianswizzle(&mTexCoords[v].mV, sizeof(F32), 2);
+ if (numRead != 2)
+ {
+ llwarns << "Can't read morph target uv" << llendl;
+ return FALSE;
+ }
+
+ mNumIndices++;
+ }
+
+ mAvgDistortion.mul(1.f/(F32)mNumIndices);
+ mAvgDistortion.normalize3fast();
+
+ return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// freeData()
+//-----------------------------------------------------------------------------
+void LLPolyMorphData::freeData()
+{
+ if (mCoords != NULL)
+ {
+ ll_aligned_free_16(mCoords);
+ mCoords = NULL;
+ }
+
+ if (mNormals != NULL)
+ {
+ ll_aligned_free_16(mNormals);
+ mNormals = NULL;
+ }
+
+ if (mBinormals != NULL)
+ {
+ ll_aligned_free_16(mBinormals);
+ mBinormals = NULL;
+ }
+
+ if (mTexCoords != NULL)
+ {
+ delete [] mTexCoords;
+ mTexCoords = NULL;
+ }
+
+ if (mVertexIndices != NULL)
+ {
+ delete [] mVertexIndices;
+ mVertexIndices = NULL;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// LLPolyMorphTargetInfo()
+//-----------------------------------------------------------------------------
+LLPolyMorphTargetInfo::LLPolyMorphTargetInfo()
+ : mIsClothingMorph(FALSE)
+{
+}
+
+BOOL LLPolyMorphTargetInfo::parseXml(LLXmlTreeNode* node)
+{
+ llassert( node->hasName( "param" ) && node->getChildByName( "param_morph" ) );
+
+ if (!LLViewerVisualParamInfo::parseXml(node))
+ return FALSE;
+
+ // Get mixed-case name
+ static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name");
+ if( !node->getFastAttributeString( name_string, mMorphName ) )
+ {
+ llwarns << "Avatar file: <param> is missing name attribute" << llendl;
+ return FALSE; // Continue, ignoring this tag
+ }
+
+ static LLStdStringHandle clothing_morph_string = LLXmlTree::addAttributeString("clothing_morph");
+ node->getFastAttributeBOOL(clothing_morph_string, mIsClothingMorph);
+
+ LLXmlTreeNode *paramNode = node->getChildByName("param_morph");
+
+ if (NULL == paramNode)
+ {
+ llwarns << "Failed to getChildByName(\"param_morph\")"
+ << llendl;
+ return FALSE;
+ }
+
+ for (LLXmlTreeNode* child_node = paramNode->getFirstChild();
+ child_node;
+ child_node = paramNode->getNextChild())
+ {
+ static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name");
+ if (child_node->hasName("volume_morph"))
+ {
+ std::string volume_name;
+ if (child_node->getFastAttributeString(name_string, volume_name))
+ {
+ LLVector3 scale;
+ static LLStdStringHandle scale_string = LLXmlTree::addAttributeString("scale");
+ child_node->getFastAttributeVector3(scale_string, scale);
+
+ LLVector3 pos;
+ static LLStdStringHandle pos_string = LLXmlTree::addAttributeString("pos");
+ child_node->getFastAttributeVector3(pos_string, pos);
+
+ mVolumeInfoList.push_back(LLPolyVolumeMorphInfo(volume_name,scale,pos));
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// LLPolyMorphTarget()
+//-----------------------------------------------------------------------------
+LLPolyMorphTarget::LLPolyMorphTarget(LLPolyMesh *poly_mesh)
+ : mMorphData(NULL), mMesh(poly_mesh),
+ mVertMask(NULL),
+ mLastSex(SEX_FEMALE),
+ mNumMorphMasksPending(0)
+{
+}
+
+//-----------------------------------------------------------------------------
+// ~LLPolyMorphTarget()
+//-----------------------------------------------------------------------------
+LLPolyMorphTarget::~LLPolyMorphTarget()
+{
+ if (mVertMask)
+ {
+ delete mVertMask;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// setInfo()
+//-----------------------------------------------------------------------------
+BOOL LLPolyMorphTarget::setInfo(LLPolyMorphTargetInfo* info)
+{
+ llassert(mInfo == NULL);
+ if (info->mID < 0)
+ return FALSE;
+ mInfo = info;
+ mID = info->mID;
+ setWeight(getDefaultWeight(), FALSE );
+
+ LLAvatarAppearance* avatarp = mMesh->getAvatar();
+ LLPolyMorphTargetInfo::volume_info_list_t::iterator iter;
+ for (iter = getInfo()->mVolumeInfoList.begin(); iter != getInfo()->mVolumeInfoList.end(); iter++)
+ {
+ LLPolyVolumeMorphInfo *volume_info = &(*iter);
+ for (S32 i = 0; i < avatarp->mNumCollisionVolumes; i++)
+ {
+ if (avatarp->mCollisionVolumes[i].getName() == volume_info->mName)
+ {
+ mVolumeMorphs.push_back(LLPolyVolumeMorph(&avatarp->mCollisionVolumes[i],
+ volume_info->mScale,
+ volume_info->mPos));
+ break;
+ }
+ }
+ }
+
+ std::string morph_param_name = getInfo()->mMorphName;
+
+ mMorphData = mMesh->getMorphData(morph_param_name);
+ if (!mMorphData)
+ {
+ const std::string driven_tag = "_Driven";
+ U32 pos = morph_param_name.find(driven_tag);
+ if (pos > 0)
+ {
+ morph_param_name = morph_param_name.substr(0,pos);
+ mMorphData = mMesh->getMorphData(morph_param_name);
+ }
+ }
+ if (!mMorphData)
+ {
+ llwarns << "No morph target named " << morph_param_name << " found in mesh." << llendl;
+ return FALSE; // Continue, ignoring this tag
+ }
+ return TRUE;
+}
+
+/*virtual*/ LLViewerVisualParam* LLPolyMorphTarget::cloneParam(LLWearable* wearable) const
+{
+ LLPolyMorphTarget *new_param = new LLPolyMorphTarget(mMesh);
+ *new_param = *this;
+ return new_param;
+}
+
+#if 0 // obsolete
+//-----------------------------------------------------------------------------
+// parseData()
+//-----------------------------------------------------------------------------
+BOOL LLPolyMorphTarget::parseData(LLXmlTreeNode* node)
+{
+ LLPolyMorphTargetInfo* info = new LLPolyMorphTargetInfo;
+
+ info->parseXml(node);
+ if (!setInfo(info))
+ {
+ delete info;
+ return FALSE;
+ }
+ return TRUE;
+}
+#endif
+
+//-----------------------------------------------------------------------------
+// getVertexDistortion()
+//-----------------------------------------------------------------------------
+LLVector4a LLPolyMorphTarget::getVertexDistortion(S32 requested_index, LLPolyMesh *mesh)
+{
+ if (!mMorphData || mMesh != mesh) return LLVector4a::getZero();
+
+ for(U32 index = 0; index < mMorphData->mNumIndices; index++)
+ {
+ if (mMorphData->mVertexIndices[index] == (U32)requested_index)
+ {
+ return mMorphData->mCoords[index];
+ }
+ }
+
+ return LLVector4a::getZero();
+}
+
+//-----------------------------------------------------------------------------
+// getFirstDistortion()
+//-----------------------------------------------------------------------------
+const LLVector4a *LLPolyMorphTarget::getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh)
+{
+ if (!mMorphData) return &LLVector4a::getZero();
+
+ LLVector4a* resultVec;
+ mMorphData->mCurrentIndex = 0;
+ if (mMorphData->mNumIndices)
+ {
+ resultVec = &mMorphData->mCoords[mMorphData->mCurrentIndex];
+ if (index != NULL)
+ {
+ *index = mMorphData->mVertexIndices[mMorphData->mCurrentIndex];
+ }
+ if (poly_mesh != NULL)
+ {
+ *poly_mesh = mMesh;
+ }
+
+ return resultVec;
+ }
+ return NULL;
+}
+
+//-----------------------------------------------------------------------------
+// getNextDistortion()
+//-----------------------------------------------------------------------------
+const LLVector4a *LLPolyMorphTarget::getNextDistortion(U32 *index, LLPolyMesh **poly_mesh)
+{
+ if (!mMorphData) return &LLVector4a::getZero();
+
+ LLVector4a* resultVec;
+ mMorphData->mCurrentIndex++;
+ if (mMorphData->mCurrentIndex < mMorphData->mNumIndices)
+ {
+ resultVec = &mMorphData->mCoords[mMorphData->mCurrentIndex];
+ if (index != NULL)
+ {
+ *index = mMorphData->mVertexIndices[mMorphData->mCurrentIndex];
+ }
+ if (poly_mesh != NULL)
+ {
+ *poly_mesh = mMesh;
+ }
+ return resultVec;
+ }
+ return NULL;
+}
+
+//-----------------------------------------------------------------------------
+// getTotalDistortion()
+//-----------------------------------------------------------------------------
+F32 LLPolyMorphTarget::getTotalDistortion()
+{
+ if (mMorphData)
+ {
+ return mMorphData->mTotalDistortion;
+ }
+ else
+ {
+ return 0.f;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// getAvgDistortion()
+//-----------------------------------------------------------------------------
+const LLVector4a& LLPolyMorphTarget::getAvgDistortion()
+{
+ if (mMorphData)
+ {
+ return mMorphData->mAvgDistortion;
+ }
+ else
+ {
+ return LLVector4a::getZero();
+ }
+}
+
+//-----------------------------------------------------------------------------
+// getMaxDistortion()
+//-----------------------------------------------------------------------------
+F32 LLPolyMorphTarget::getMaxDistortion()
+{
+ if (mMorphData)
+ {
+ return mMorphData->mMaxDistortion;
+ }
+ else
+ {
+ return 0.f;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// apply()
+//-----------------------------------------------------------------------------
+static LLFastTimer::DeclareTimer FTM_APPLY_MORPH_TARGET("Apply Morph");
+
+void LLPolyMorphTarget::apply( ESex avatar_sex )
+{
+ if (!mMorphData || mNumMorphMasksPending > 0)
+ {
+ return;
+ }
+
+ LLFastTimer t(FTM_APPLY_MORPH_TARGET);
+
+ mLastSex = avatar_sex;
+
+ // Check for NaN condition (NaN is detected if a variable doesn't equal itself.
+ if (mCurWeight != mCurWeight)
+ {
+ mCurWeight = 0.0;
+ }
+ if (mLastWeight != mLastWeight)
+ {
+ mLastWeight = mCurWeight+.001;
+ }
+
+ // perform differential update of morph
+ F32 delta_weight = ( getSex() & avatar_sex ) ? (mCurWeight - mLastWeight) : (getDefaultWeight() - mLastWeight);
+ // store last weight
+ mLastWeight += delta_weight;
+
+ if (delta_weight != 0.f)
+ {
+ llassert(!mMesh->isLOD());
+ LLVector4a *coords = mMesh->getWritableCoords();
+
+ LLVector4a *scaled_normals = mMesh->getScaledNormals();
+ LLVector4a *normals = mMesh->getWritableNormals();
+
+ LLVector4a *scaled_binormals = mMesh->getScaledBinormals();
+ LLVector4a *binormals = mMesh->getWritableBinormals();
+
+ LLVector4a *clothing_weights = mMesh->getWritableClothingWeights();
+ LLVector2 *tex_coords = mMesh->getWritableTexCoords();
+
+ F32 *maskWeightArray = (mVertMask) ? mVertMask->getMorphMaskWeights() : NULL;
+
+ for(U32 vert_index_morph = 0; vert_index_morph < mMorphData->mNumIndices; vert_index_morph++)
+ {
+ S32 vert_index_mesh = mMorphData->mVertexIndices[vert_index_morph];
+
+ F32 maskWeight = 1.f;
+ if (maskWeightArray)
+ {
+ maskWeight = maskWeightArray[vert_index_morph];
+ }
+
+
+ LLVector4a pos = mMorphData->mCoords[vert_index_morph];
+ pos.mul(delta_weight*maskWeight);
+ coords[vert_index_mesh].add(pos);
+
+ if (getInfo()->mIsClothingMorph && clothing_weights)
+ {
+ LLVector4a clothing_offset = mMorphData->mCoords[vert_index_morph];
+ clothing_offset.mul(delta_weight * maskWeight);
+ LLVector4a* clothing_weight = &clothing_weights[vert_index_mesh];
+ clothing_weight->add(clothing_offset);
+ clothing_weight->getF32ptr()[VW] = maskWeight;
+ }
+
+ // calculate new normals based on half angles
+ LLVector4a norm = mMorphData->mNormals[vert_index_morph];
+ norm.mul(delta_weight*maskWeight*NORMAL_SOFTEN_FACTOR);
+ scaled_normals[vert_index_mesh].add(norm);
+ norm = scaled_normals[vert_index_mesh];
+
+ // guard against degenerate input data before we create NaNs below!
+ //
+ norm.normalize3fast();
+ normals[vert_index_mesh] = norm;
+
+ // calculate new binormals
+ LLVector4a binorm = mMorphData->mBinormals[vert_index_morph];
+
+ // guard against degenerate input data before we create NaNs below!
+ //
+ if (!binorm.isFinite3() || (binorm.dot3(binorm).getF32() <= F_APPROXIMATELY_ZERO))
+ {
+ binorm.set(1,0,0,1);
+ }
+
+ binorm.mul(delta_weight*maskWeight*NORMAL_SOFTEN_FACTOR);
+ scaled_binormals[vert_index_mesh].add(binorm);
+ LLVector4a tangent;
+ tangent.setCross3(scaled_binormals[vert_index_mesh], norm);
+ LLVector4a& normalized_binormal = binormals[vert_index_mesh];
+
+ normalized_binormal.setCross3(norm, tangent);
+ normalized_binormal.normalize3fast();
+
+ tex_coords[vert_index_mesh] += mMorphData->mTexCoords[vert_index_morph] * delta_weight * maskWeight;
+ }
+
+ // now apply volume changes
+ for( volume_list_t::iterator iter = mVolumeMorphs.begin(); iter != mVolumeMorphs.end(); iter++ )
+ {
+ LLPolyVolumeMorph* volume_morph = &(*iter);
+ LLVector3 scale_delta = volume_morph->mScale * delta_weight;
+ LLVector3 pos_delta = volume_morph->mPos * delta_weight;
+
+ volume_morph->mVolume->setScale(volume_morph->mVolume->getScale() + scale_delta);
+ volume_morph->mVolume->setPosition(volume_morph->mVolume->getPosition() + pos_delta);
+ }
+ }
+
+ if (mNext)
+ {
+ mNext->apply(avatar_sex);
+ }
+}
+
+//-----------------------------------------------------------------------------
+// applyMask()
+//-----------------------------------------------------------------------------
+void LLPolyMorphTarget::applyMask(U8 *maskTextureData, S32 width, S32 height, S32 num_components, BOOL invert)
+{
+ LLVector4a *clothing_weights = getInfo()->mIsClothingMorph ? mMesh->getWritableClothingWeights() : NULL;
+
+ if (!mVertMask)
+ {
+ mVertMask = new LLPolyVertexMask(mMorphData);
+ mNumMorphMasksPending--;
+ }
+ else
+ {
+ // remove effect of previous mask
+ F32 *maskWeights = (mVertMask) ? mVertMask->getMorphMaskWeights() : NULL;
+
+ if (maskWeights)
+ {
+ LLVector4a *coords = mMesh->getWritableCoords();
+ LLVector4a *scaled_normals = mMesh->getScaledNormals();
+ LLVector4a *scaled_binormals = mMesh->getScaledBinormals();
+ LLVector2 *tex_coords = mMesh->getWritableTexCoords();
+
+ LLVector4Logical clothing_mask;
+ clothing_mask.clear();
+ clothing_mask.setElement<0>();
+ clothing_mask.setElement<1>();
+ clothing_mask.setElement<2>();
+
+
+ for(U32 vert = 0; vert < mMorphData->mNumIndices; vert++)
+ {
+ F32 lastMaskWeight = mLastWeight * maskWeights[vert];
+ S32 out_vert = mMorphData->mVertexIndices[vert];
+
+ // remove effect of existing masked morph
+ LLVector4a t;
+ t = mMorphData->mCoords[vert];
+ t.mul(lastMaskWeight);
+ coords[out_vert].sub(t);
+
+ t = mMorphData->mNormals[vert];
+ t.mul(lastMaskWeight*NORMAL_SOFTEN_FACTOR);
+ scaled_normals[out_vert].sub(t);
+
+ t = mMorphData->mBinormals[vert];
+ t.mul(lastMaskWeight*NORMAL_SOFTEN_FACTOR);
+ scaled_binormals[out_vert].sub(t);
+
+ tex_coords[out_vert] -= mMorphData->mTexCoords[vert] * lastMaskWeight;
+
+ if (clothing_weights)
+ {
+ LLVector4a clothing_offset = mMorphData->mCoords[vert];
+ clothing_offset.mul(lastMaskWeight);
+ LLVector4a* clothing_weight = &clothing_weights[out_vert];
+ LLVector4a t;
+ t.setSub(*clothing_weight, clothing_offset);
+ clothing_weight->setSelectWithMask(clothing_mask, t, *clothing_weight);
+ }
+ }
+ }
+ }
+
+ // set last weight to 0, since we've removed the effect of this morph
+ mLastWeight = 0.f;
+
+ mVertMask->generateMask(maskTextureData, width, height, num_components, invert, clothing_weights);
+
+ apply(mLastSex);
+}
+
+
+//-----------------------------------------------------------------------------
+// LLPolyVertexMask()
+//-----------------------------------------------------------------------------
+LLPolyVertexMask::LLPolyVertexMask(LLPolyMorphData* morph_data)
+{
+ mWeights = new F32[morph_data->mNumIndices];
+ mMorphData = morph_data;
+ mWeightsGenerated = FALSE;
+}
+
+//-----------------------------------------------------------------------------
+// ~LLPolyVertexMask()
+//-----------------------------------------------------------------------------
+LLPolyVertexMask::~LLPolyVertexMask()
+{
+ delete[] mWeights;
+}
+
+//-----------------------------------------------------------------------------
+// generateMask()
+//-----------------------------------------------------------------------------
+void LLPolyVertexMask::generateMask(U8 *maskTextureData, S32 width, S32 height, S32 num_components, BOOL invert, LLVector4a *clothing_weights)
+{
+// RN debug output that uses Image Debugger (http://www.cs.unc.edu/~baxter/projects/imdebug/)
+// BOOL debugImg = FALSE;
+// if (debugImg)
+// {
+// if (invert)
+// {
+// imdebug("lum rbga=rgba b=8 w=%d h=%d *-1 %p", width, height, maskTextureData);
+// }
+// else
+// {
+// imdebug("lum rbga=rgba b=8 w=%d h=%d %p", width, height, maskTextureData);
+// }
+// }
+ for (U32 index = 0; index < mMorphData->mNumIndices; index++)
+ {
+ S32 vertIndex = mMorphData->mVertexIndices[index];
+ const S32 *sharedVertIndex = mMorphData->mMesh->getSharedVert(vertIndex);
+ LLVector2 uvCoords;
+
+ if (sharedVertIndex)
+ {
+ uvCoords = mMorphData->mMesh->getUVs(*sharedVertIndex);
+ }
+ else
+ {
+ uvCoords = mMorphData->mMesh->getUVs(vertIndex);
+ }
+ U32 s = llclamp((U32)(uvCoords.mV[VX] * (F32)(width - 1)), (U32)0, (U32)width - 1);
+ U32 t = llclamp((U32)(uvCoords.mV[VY] * (F32)(height - 1)), (U32)0, (U32)height - 1);
+
+ mWeights[index] = ((F32) maskTextureData[((t * width + s) * num_components) + (num_components - 1)]) / 255.f;
+
+ if (invert)
+ {
+ mWeights[index] = 1.f - mWeights[index];
+ }
+
+ // now apply step function
+ // mWeights[index] = mWeights[index] > 0.95f ? 1.f : 0.f;
+
+ if (clothing_weights)
+ {
+ clothing_weights[vertIndex].getF32ptr()[VW] = mWeights[index];
+ }
+ }
+ mWeightsGenerated = TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// getMaskForMorphIndex()
+//-----------------------------------------------------------------------------
+F32* LLPolyVertexMask::getMorphMaskWeights()
+{
+ if (!mWeightsGenerated)
+ {
+ return NULL;
+ }
+
+ return mWeights;
+}
diff --git a/indra/llappearance/llpolymorph.h b/indra/llappearance/llpolymorph.h
new file mode 100644
index 0000000000..ee380ae7c3
--- /dev/null
+++ b/indra/llappearance/llpolymorph.h
@@ -0,0 +1,197 @@
+/**
+ * @file llpolymorph.h
+ * @brief Implementation of LLPolyMesh class
+ *
+ * $LicenseInfo:firstyear=2001&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$
+ */
+
+#ifndef LL_LLPOLYMORPH_H
+#define LL_LLPOLYMORPH_H
+
+#include <string>
+#include <vector>
+
+#include "llviewervisualparam.h"
+
+class LLAvatarJointCollisionVolume;
+class LLPolyMeshSharedData;
+class LLVector2;
+class LLAvatarJointCollisionVolume;
+class LLWearable;
+
+//-----------------------------------------------------------------------------
+// LLPolyMorphData()
+//-----------------------------------------------------------------------------
+LL_ALIGN_PREFIX(16)
+class LLPolyMorphData
+{
+public:
+ LLPolyMorphData(const std::string& morph_name);
+ ~LLPolyMorphData();
+ LLPolyMorphData(const LLPolyMorphData &rhs);
+
+ void* operator new(size_t size)
+ {
+ return ll_aligned_malloc_16(size);
+ }
+
+ void operator delete(void* ptr)
+ {
+ ll_aligned_free_16(ptr);
+ }
+
+ BOOL loadBinary(LLFILE* fp, LLPolyMeshSharedData *mesh);
+ const std::string& getName() { return mName; }
+
+public:
+ std::string mName;
+
+ // morphology
+ U32 mNumIndices;
+ U32* mVertexIndices;
+ U32 mCurrentIndex;
+ LLVector4a* mCoords;
+ LLVector4a* mNormals;
+ LLVector4a* mBinormals;
+ LLVector2* mTexCoords;
+
+ F32 mTotalDistortion; // vertex distortion summed over entire morph
+ F32 mMaxDistortion; // maximum single vertex distortion in a given morph
+ LL_ALIGN_16(LLVector4a mAvgDistortion); // average vertex distortion, to infer directionality of the morph
+ LLPolyMeshSharedData* mMesh;
+
+private:
+ void freeData();
+} LL_ALIGN_POSTFIX(16);
+
+
+//-----------------------------------------------------------------------------
+// LLPolyVertexMask()
+//-----------------------------------------------------------------------------
+class LLPolyVertexMask
+{
+public:
+ LLPolyVertexMask(LLPolyMorphData* morph_data);
+ ~LLPolyVertexMask();
+
+ void generateMask(U8 *maskData, S32 width, S32 height, S32 num_components, BOOL invert, LLVector4a *clothing_weights);
+ F32* getMorphMaskWeights();
+
+
+protected:
+ F32* mWeights;
+ LLPolyMorphData *mMorphData;
+ BOOL mWeightsGenerated;
+
+};
+
+//-----------------------------------------------------------------------------
+// LLPolyMorphTarget Data structs
+//-----------------------------------------------------------------------------
+struct LLPolyVolumeMorphInfo
+{
+ LLPolyVolumeMorphInfo(std::string &name, LLVector3 &scale, LLVector3 &pos)
+ : mName(name), mScale(scale), mPos(pos) {};
+
+ std::string mName;
+ LLVector3 mScale;
+ LLVector3 mPos;
+};
+
+struct LLPolyVolumeMorph
+{
+ LLPolyVolumeMorph(LLAvatarJointCollisionVolume* volume, LLVector3 scale, LLVector3 pos)
+ : mVolume(volume), mScale(scale), mPos(pos) {};
+
+ LLAvatarJointCollisionVolume* mVolume;
+ LLVector3 mScale;
+ LLVector3 mPos;
+};
+
+//-----------------------------------------------------------------------------
+// LLPolyMorphTargetInfo
+// Shared information for LLPolyMorphTargets
+//-----------------------------------------------------------------------------
+class LLPolyMorphTargetInfo : public LLViewerVisualParamInfo
+{
+ friend class LLPolyMorphTarget;
+public:
+ LLPolyMorphTargetInfo();
+ /*virtual*/ ~LLPolyMorphTargetInfo() {};
+
+ /*virtual*/ BOOL parseXml(LLXmlTreeNode* node);
+
+protected:
+ std::string mMorphName;
+ BOOL mIsClothingMorph;
+ typedef std::vector<LLPolyVolumeMorphInfo> volume_info_list_t;
+ volume_info_list_t mVolumeInfoList;
+};
+
+//-----------------------------------------------------------------------------
+// LLPolyMorphTarget
+// A set of vertex data associated with morph target.
+// These morph targets must be topologically consistent with a given Polymesh
+// (share face sets)
+//-----------------------------------------------------------------------------
+class LLPolyMorphTarget : public LLViewerVisualParam
+{
+public:
+ LLPolyMorphTarget(LLPolyMesh *poly_mesh);
+ ~LLPolyMorphTarget();
+
+ // Special: These functions are overridden by child classes
+ LLPolyMorphTargetInfo* getInfo() const { return (LLPolyMorphTargetInfo*)mInfo; }
+ // This sets mInfo and calls initialization functions
+ BOOL setInfo(LLPolyMorphTargetInfo *info);
+
+ /*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable) const;
+
+ // LLVisualParam Virtual functions
+ ///*virtual*/ BOOL parseData(LLXmlTreeNode* node);
+ /*virtual*/ void apply( ESex sex );
+
+ // LLViewerVisualParam Virtual functions
+ /*virtual*/ F32 getTotalDistortion();
+ /*virtual*/ const LLVector4a& getAvgDistortion();
+ /*virtual*/ F32 getMaxDistortion();
+ /*virtual*/ LLVector4a getVertexDistortion(S32 index, LLPolyMesh *poly_mesh);
+ /*virtual*/ const LLVector4a* getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh);
+ /*virtual*/ const LLVector4a* getNextDistortion(U32 *index, LLPolyMesh **poly_mesh);
+
+ void applyMask(U8 *maskData, S32 width, S32 height, S32 num_components, BOOL invert);
+ void addPendingMorphMask() { mNumMorphMasksPending++; }
+
+protected:
+ LLPolyMorphData* mMorphData;
+ LLPolyMesh* mMesh;
+ LLPolyVertexMask * mVertMask;
+ ESex mLastSex;
+ // number of morph masks that haven't been generated, must be 0 before this morph is applied
+ BOOL mNumMorphMasksPending;
+
+ typedef std::vector<LLPolyVolumeMorph> volume_list_t;
+ volume_list_t mVolumeMorphs;
+
+};
+
+#endif // LL_LLPOLYMORPH_H
diff --git a/indra/llappearance/llpolyskeletaldistortion.cpp b/indra/llappearance/llpolyskeletaldistortion.cpp
new file mode 100644
index 0000000000..4ba16691c2
--- /dev/null
+++ b/indra/llappearance/llpolyskeletaldistortion.cpp
@@ -0,0 +1,293 @@
+/**
+ * @file llpolyskeletaldistortion.cpp
+ * @brief Implementation of LLPolySkeletalDistortion classes
+ *
+ * $LicenseInfo:firstyear=2001&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$
+ */
+
+//-----------------------------------------------------------------------------
+// Header Files
+//-----------------------------------------------------------------------------
+#include "llpreprocessor.h"
+#include "llerrorlegacy.h"
+//#include "llcommon.h"
+//#include "llmemory.h"
+#include "llavatarappearance.h"
+#include "llavatarjoint.h"
+#include "llpolymorph.h"
+//#include "llviewercontrol.h"
+//#include "llxmltree.h"
+//#include "llvoavatar.h"
+#include "llwearable.h"
+//#include "lldir.h"
+//#include "llvolume.h"
+//#include "llendianswizzle.h"
+
+#include "llpolyskeletaldistortion.h"
+
+//-----------------------------------------------------------------------------
+// LLPolySkeletalDistortionInfo()
+//-----------------------------------------------------------------------------
+LLPolySkeletalDistortionInfo::LLPolySkeletalDistortionInfo()
+{
+}
+
+BOOL LLPolySkeletalDistortionInfo::parseXml(LLXmlTreeNode* node)
+{
+ llassert( node->hasName( "param" ) && node->getChildByName( "param_skeleton" ) );
+
+ if (!LLViewerVisualParamInfo::parseXml(node))
+ return FALSE;
+
+ LLXmlTreeNode* skeletalParam = node->getChildByName("param_skeleton");
+
+ if (NULL == skeletalParam)
+ {
+ llwarns << "Failed to getChildByName(\"param_skeleton\")"
+ << llendl;
+ return FALSE;
+ }
+
+ for( LLXmlTreeNode* bone = skeletalParam->getFirstChild(); bone; bone = skeletalParam->getNextChild() )
+ {
+ if (bone->hasName("bone"))
+ {
+ std::string name;
+ LLVector3 scale;
+ LLVector3 pos;
+ BOOL haspos = FALSE;
+
+ static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name");
+ if (!bone->getFastAttributeString(name_string, name))
+ {
+ llwarns << "No bone name specified for skeletal param." << llendl;
+ continue;
+ }
+
+ static LLStdStringHandle scale_string = LLXmlTree::addAttributeString("scale");
+ if (!bone->getFastAttributeVector3(scale_string, scale))
+ {
+ llwarns << "No scale specified for bone " << name << "." << llendl;
+ continue;
+ }
+
+ // optional offset deformation (translation)
+ static LLStdStringHandle offset_string = LLXmlTree::addAttributeString("offset");
+ if (bone->getFastAttributeVector3(offset_string, pos))
+ {
+ haspos = TRUE;
+ }
+ mBoneInfoList.push_back(LLPolySkeletalBoneInfo(name, scale, pos, haspos));
+ }
+ else
+ {
+ llwarns << "Unrecognized element " << bone->getName() << " in skeletal distortion" << llendl;
+ continue;
+ }
+ }
+ return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// LLPolySkeletalDistortion()
+//-----------------------------------------------------------------------------
+LLPolySkeletalDistortion::LLPolySkeletalDistortion(LLAvatarAppearance *avatarp)
+{
+ mAvatar = avatarp;
+ mDefaultVec.splat(0.001f);
+}
+
+//-----------------------------------------------------------------------------
+// ~LLPolySkeletalDistortion()
+//-----------------------------------------------------------------------------
+LLPolySkeletalDistortion::~LLPolySkeletalDistortion()
+{
+}
+
+BOOL LLPolySkeletalDistortion::setInfo(LLPolySkeletalDistortionInfo *info)
+{
+ llassert(mInfo == NULL);
+ if (info->mID < 0)
+ return FALSE;
+ mInfo = info;
+ mID = info->mID;
+ setWeight(getDefaultWeight(), FALSE );
+
+ LLPolySkeletalDistortionInfo::bone_info_list_t::iterator iter;
+ for (iter = getInfo()->mBoneInfoList.begin(); iter != getInfo()->mBoneInfoList.end(); iter++)
+ {
+ LLPolySkeletalBoneInfo *bone_info = &(*iter);
+ LLJoint* joint = mAvatar->getJoint(bone_info->mBoneName);
+ if (!joint)
+ {
+ llwarns << "Joint " << bone_info->mBoneName << " not found." << llendl;
+ continue;
+ }
+
+ if (mJointScales.find(joint) != mJointScales.end())
+ {
+ llwarns << "Scale deformation already supplied for joint " << joint->getName() << "." << llendl;
+ }
+
+ // store it
+ mJointScales[joint] = bone_info->mScaleDeformation;
+
+ // apply to children that need to inherit it
+ for (LLJoint::child_list_t::iterator iter = joint->mChildren.begin();
+ iter != joint->mChildren.end(); ++iter)
+ {
+ LLAvatarJoint* child_joint = (LLAvatarJoint*)(*iter);
+ if (child_joint->inheritScale())
+ {
+ LLVector3 childDeformation = LLVector3(child_joint->getScale());
+ childDeformation.scaleVec(bone_info->mScaleDeformation);
+ mJointScales[child_joint] = childDeformation;
+ }
+ }
+
+ if (bone_info->mHasPositionDeformation)
+ {
+ if (mJointOffsets.find(joint) != mJointOffsets.end())
+ {
+ llwarns << "Offset deformation already supplied for joint " << joint->getName() << "." << llendl;
+ }
+ mJointOffsets[joint] = bone_info->mPositionDeformation;
+ }
+ }
+ return TRUE;
+}
+
+/*virtual*/ LLViewerVisualParam* LLPolySkeletalDistortion::cloneParam(LLWearable* wearable) const
+{
+ LLPolySkeletalDistortion *new_param = new LLPolySkeletalDistortion(mAvatar);
+ *new_param = *this;
+ return new_param;
+}
+
+//-----------------------------------------------------------------------------
+// apply()
+//-----------------------------------------------------------------------------
+static LLFastTimer::DeclareTimer FTM_POLYSKELETAL_DISTORTION_APPLY("Skeletal Distortion");
+
+void LLPolySkeletalDistortion::apply( ESex avatar_sex )
+{
+ LLFastTimer t(FTM_POLYSKELETAL_DISTORTION_APPLY);
+
+ F32 effective_weight = ( getSex() & avatar_sex ) ? mCurWeight : getDefaultWeight();
+
+ LLJoint* joint;
+ joint_vec_map_t::iterator iter;
+
+ for (iter = mJointScales.begin();
+ iter != mJointScales.end();
+ iter++)
+ {
+ joint = iter->first;
+ LLVector3 newScale = joint->getScale();
+ LLVector3 scaleDelta = iter->second;
+ newScale = newScale + (effective_weight * scaleDelta) - (mLastWeight * scaleDelta);
+ joint->setScale(newScale);
+ }
+
+ for (iter = mJointOffsets.begin();
+ iter != mJointOffsets.end();
+ iter++)
+ {
+ joint = iter->first;
+ LLVector3 newPosition = joint->getPosition();
+ LLVector3 positionDelta = iter->second;
+ newPosition = newPosition + (effective_weight * positionDelta) - (mLastWeight * positionDelta);
+ joint->setPosition(newPosition);
+ }
+
+ if (mLastWeight != mCurWeight && !mIsAnimating)
+ {
+ mAvatar->setSkeletonSerialNum(mAvatar->getSkeletonSerialNum() + 1);
+ }
+ mLastWeight = mCurWeight;
+}
+
+
+LLPolyMorphData *clone_morph_param_duplicate(const LLPolyMorphData *src_data,
+ const std::string &name)
+{
+ LLPolyMorphData* cloned_morph_data = new LLPolyMorphData(*src_data);
+ cloned_morph_data->mName = name;
+ for (U32 v=0; v < cloned_morph_data->mNumIndices; v++)
+ {
+ cloned_morph_data->mCoords[v] = src_data->mCoords[v];
+ cloned_morph_data->mNormals[v] = src_data->mNormals[v];
+ cloned_morph_data->mBinormals[v] = src_data->mBinormals[v];
+ }
+ return cloned_morph_data;
+}
+
+LLPolyMorphData *clone_morph_param_direction(const LLPolyMorphData *src_data,
+ const LLVector3 &direction,
+ const std::string &name)
+{
+ LLPolyMorphData* cloned_morph_data = new LLPolyMorphData(*src_data);
+ cloned_morph_data->mName = name;
+ LLVector4a dir;
+ dir.load3(direction.mV);
+
+ for (U32 v=0; v < cloned_morph_data->mNumIndices; v++)
+ {
+ cloned_morph_data->mCoords[v] = dir;
+ cloned_morph_data->mNormals[v].clear();
+ cloned_morph_data->mBinormals[v].clear();
+ }
+ return cloned_morph_data;
+}
+
+LLPolyMorphData *clone_morph_param_cleavage(const LLPolyMorphData *src_data,
+ F32 scale,
+ const std::string &name)
+{
+ LLPolyMorphData* cloned_morph_data = new LLPolyMorphData(*src_data);
+ cloned_morph_data->mName = name;
+
+ LLVector4a sc;
+ sc.splat(scale);
+
+ LLVector4a nsc;
+ nsc.set(scale, -scale, scale, scale);
+
+ for (U32 v=0; v < cloned_morph_data->mNumIndices; v++)
+ {
+ if (cloned_morph_data->mCoords[v][1] < 0)
+ {
+ cloned_morph_data->mCoords[v].setMul(src_data->mCoords[v],nsc);
+ cloned_morph_data->mNormals[v].setMul(src_data->mNormals[v],nsc);
+ cloned_morph_data->mBinormals[v].setMul(src_data->mBinormals[v],nsc);
+ }
+ else
+ {
+ cloned_morph_data->mCoords[v].setMul(src_data->mCoords[v],sc);
+ cloned_morph_data->mNormals[v].setMul(src_data->mNormals[v], sc);
+ cloned_morph_data->mBinormals[v].setMul(src_data->mBinormals[v],sc);
+ }
+ }
+ return cloned_morph_data;
+}
+
+// End
diff --git a/indra/llappearance/llpolyskeletaldistortion.h b/indra/llappearance/llpolyskeletaldistortion.h
new file mode 100644
index 0000000000..774bc7dfa2
--- /dev/null
+++ b/indra/llappearance/llpolyskeletaldistortion.h
@@ -0,0 +1,131 @@
+/**
+ * @file llpolyskeletaldistortion.h
+ * @brief Implementation of LLPolyMesh class
+ *
+ * $LicenseInfo:firstyear=2001&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$
+ */
+
+#ifndef LL_LLPOLYSKELETALDISTORTION_H
+#define LL_LLPOLYSKELETALDISTORTION_H
+
+#include "llcommon.h"
+
+#include <string>
+#include <map>
+#include "llstl.h"
+
+#include "v3math.h"
+#include "v2math.h"
+#include "llquaternion.h"
+//#include "llpolymorph.h"
+#include "lljoint.h"
+#include "llviewervisualparam.h"
+//#include "lldarray.h"
+
+//class LLSkinJoint;
+class LLAvatarAppearance;
+
+//#define USE_STRIPS // Use tri-strips for rendering.
+
+//-----------------------------------------------------------------------------
+// LLPolySkeletalDeformationInfo
+// Shared information for LLPolySkeletalDeformations
+//-----------------------------------------------------------------------------
+struct LLPolySkeletalBoneInfo
+{
+ LLPolySkeletalBoneInfo(std::string &name, LLVector3 &scale, LLVector3 &pos, BOOL haspos)
+ : mBoneName(name),
+ mScaleDeformation(scale),
+ mPositionDeformation(pos),
+ mHasPositionDeformation(haspos) {}
+ std::string mBoneName;
+ LLVector3 mScaleDeformation;
+ LLVector3 mPositionDeformation;
+ BOOL mHasPositionDeformation;
+};
+
+LL_ALIGN_PREFIX(16)
+class LLPolySkeletalDistortionInfo : public LLViewerVisualParamInfo
+{
+ friend class LLPolySkeletalDistortion;
+public:
+
+ LLPolySkeletalDistortionInfo();
+ /*virtual*/ ~LLPolySkeletalDistortionInfo() {};
+
+ /*virtual*/ BOOL parseXml(LLXmlTreeNode* node);
+
+protected:
+ typedef std::vector<LLPolySkeletalBoneInfo> bone_info_list_t;
+ bone_info_list_t mBoneInfoList;
+};
+
+//-----------------------------------------------------------------------------
+// LLPolySkeletalDeformation
+// A set of joint scale data for deforming the avatar mesh
+//-----------------------------------------------------------------------------
+class LLPolySkeletalDistortion : public LLViewerVisualParam
+{
+public:
+ void* operator new(size_t size)
+ {
+ return ll_aligned_malloc_16(size);
+ }
+
+ void operator delete(void* ptr)
+ {
+ ll_aligned_free_16(ptr);
+ }
+
+ LLPolySkeletalDistortion(LLAvatarAppearance *avatarp);
+ ~LLPolySkeletalDistortion();
+
+ // Special: These functions are overridden by child classes
+ LLPolySkeletalDistortionInfo* getInfo() const { return (LLPolySkeletalDistortionInfo*)mInfo; }
+ // This sets mInfo and calls initialization functions
+ BOOL setInfo(LLPolySkeletalDistortionInfo *info);
+
+ /*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable) const;
+
+ // LLVisualParam Virtual functions
+ ///*virtual*/ BOOL parseData(LLXmlTreeNode* node);
+ /*virtual*/ void apply( ESex sex );
+
+ // LLViewerVisualParam Virtual functions
+ /*virtual*/ F32 getTotalDistortion() { return 0.1f; }
+ /*virtual*/ const LLVector4a& getAvgDistortion() { return mDefaultVec; }
+ /*virtual*/ F32 getMaxDistortion() { return 0.1f; }
+ /*virtual*/ LLVector4a getVertexDistortion(S32 index, LLPolyMesh *poly_mesh){return LLVector4a(0.001f, 0.001f, 0.001f);}
+ /*virtual*/ const LLVector4a* getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh){index = 0; poly_mesh = NULL; return &mDefaultVec;};
+ /*virtual*/ const LLVector4a* getNextDistortion(U32 *index, LLPolyMesh **poly_mesh){index = 0; poly_mesh = NULL; return NULL;};
+
+protected:
+ LL_ALIGN_16(LLVector4a mDefaultVec);
+ typedef std::map<LLJoint*, LLVector3> joint_vec_map_t;
+ joint_vec_map_t mJointScales;
+ joint_vec_map_t mJointOffsets;
+ // Backlink only; don't make this an LLPointer.
+ LLAvatarAppearance *mAvatar;
+} LL_ALIGN_POSTFIX(16);
+
+#endif // LL_LLPOLYSKELETALDISTORTION_H
+
diff --git a/indra/llappearance/lltexglobalcolor.cpp b/indra/llappearance/lltexglobalcolor.cpp
new file mode 100644
index 0000000000..f38b982104
--- /dev/null
+++ b/indra/llappearance/lltexglobalcolor.cpp
@@ -0,0 +1,152 @@
+/**
+ * @file lltexlayerglobalcolor.cpp
+ * @brief Color for texture layers.
+ *
+ * $LicenseInfo:firstyear=2008&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 "llavatarappearance.h"
+#include "lltexlayer.h"
+#include "lltexglobalcolor.h"
+
+class LLWearable;
+
+//-----------------------------------------------------------------------------
+// LLTexGlobalColor
+//-----------------------------------------------------------------------------
+
+LLTexGlobalColor::LLTexGlobalColor(LLAvatarAppearance* appearance)
+ :
+ mAvatarAppearance(appearance),
+ mInfo(NULL)
+{
+}
+
+LLTexGlobalColor::~LLTexGlobalColor()
+{
+ // mParamColorList are LLViewerVisualParam's and get deleted with ~LLCharacter()
+ //std::for_each(mParamColorList.begin(), mParamColorList.end(), DeletePointer());
+}
+
+BOOL LLTexGlobalColor::setInfo(LLTexGlobalColorInfo *info)
+{
+ llassert(mInfo == NULL);
+ mInfo = info;
+ //mID = info->mID; // No ID
+
+ mParamGlobalColorList.reserve(mInfo->mParamColorInfoList.size());
+ for (param_color_info_list_t::iterator iter = mInfo->mParamColorInfoList.begin();
+ iter != mInfo->mParamColorInfoList.end();
+ iter++)
+ {
+ LLTexParamGlobalColor* param_color = new LLTexParamGlobalColor(this);
+ if (!param_color->setInfo(*iter, TRUE))
+ {
+ mInfo = NULL;
+ return FALSE;
+ }
+ mParamGlobalColorList.push_back(param_color);
+ }
+
+ return TRUE;
+}
+
+LLColor4 LLTexGlobalColor::getColor() const
+{
+ // Sum of color params
+ if (mParamGlobalColorList.empty())
+ return LLColor4(1.f, 1.f, 1.f, 1.f);
+
+ LLColor4 net_color(0.f, 0.f, 0.f, 0.f);
+ LLTexLayer::calculateTexLayerColor(mParamGlobalColorList, net_color);
+ return net_color;
+}
+
+const std::string& LLTexGlobalColor::getName() const
+{
+ return mInfo->mName;
+}
+
+//-----------------------------------------------------------------------------
+// LLTexParamGlobalColor
+//-----------------------------------------------------------------------------
+LLTexParamGlobalColor::LLTexParamGlobalColor(LLTexGlobalColor* tex_global_color) :
+ LLTexLayerParamColor(tex_global_color->getAvatarAppearance()),
+ mTexGlobalColor(tex_global_color)
+{
+}
+
+/*virtual*/ LLViewerVisualParam* LLTexParamGlobalColor::cloneParam(LLWearable* wearable) const
+{
+ LLTexParamGlobalColor *new_param = new LLTexParamGlobalColor(mTexGlobalColor);
+ *new_param = *this;
+ return new_param;
+}
+
+void LLTexParamGlobalColor::onGlobalColorChanged(bool upload_bake)
+{
+ mAvatarAppearance->onGlobalColorChanged(mTexGlobalColor, upload_bake);
+}
+
+//-----------------------------------------------------------------------------
+// LLTexGlobalColorInfo
+//-----------------------------------------------------------------------------
+
+LLTexGlobalColorInfo::LLTexGlobalColorInfo()
+{
+}
+
+
+LLTexGlobalColorInfo::~LLTexGlobalColorInfo()
+{
+ for_each(mParamColorInfoList.begin(), mParamColorInfoList.end(), DeletePointer());
+}
+
+BOOL LLTexGlobalColorInfo::parseXml(LLXmlTreeNode* node)
+{
+ // name attribute
+ static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name");
+ if (!node->getFastAttributeString(name_string, mName))
+ {
+ llwarns << "<global_color> element is missing name attribute." << llendl;
+ return FALSE;
+ }
+ // <param> sub-element
+ for (LLXmlTreeNode* child = node->getChildByName("param");
+ child;
+ child = node->getNextNamedChild())
+ {
+ if (child->getChildByName("param_color"))
+ {
+ // <param><param_color/></param>
+ LLTexLayerParamColorInfo* info = new LLTexLayerParamColorInfo();
+ if (!info->parseXml(child))
+ {
+ delete info;
+ return FALSE;
+ }
+ mParamColorInfoList.push_back(info);
+ }
+ }
+ return TRUE;
+}
diff --git a/indra/llappearance/lltexglobalcolor.h b/indra/llappearance/lltexglobalcolor.h
new file mode 100644
index 0000000000..2867479876
--- /dev/null
+++ b/indra/llappearance/lltexglobalcolor.h
@@ -0,0 +1,83 @@
+/**
+ * @file lltexglobalcolor.h
+ * @brief This is global texture color info used by llavatarappearance.
+ *
+ * $LicenseInfo:firstyear=2008&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$
+ */
+
+#ifndef LL_LLTEXGLOBALCOLOR_H
+#define LL_LLTEXGLOBALCOLOR_H
+
+#include "lltexlayer.h"
+#include "lltexlayerparams.h"
+
+class LLAvatarAppearance;
+class LLWearable;
+class LLTexGlobalColorInfo;
+
+class LLTexGlobalColor
+{
+public:
+ LLTexGlobalColor( LLAvatarAppearance* appearance );
+ ~LLTexGlobalColor();
+
+ LLTexGlobalColorInfo* getInfo() const { return mInfo; }
+ // This sets mInfo and calls initialization functions
+ BOOL setInfo(LLTexGlobalColorInfo *info);
+
+ LLAvatarAppearance* getAvatarAppearance() const { return mAvatarAppearance; }
+ LLColor4 getColor() const;
+ const std::string& getName() const;
+
+private:
+ param_color_list_t mParamGlobalColorList;
+ LLAvatarAppearance* mAvatarAppearance; // just backlink, don't LLPointer
+ LLTexGlobalColorInfo *mInfo;
+};
+
+// Used by llavatarappearance to determine skin/eye/hair color.
+class LLTexGlobalColorInfo
+{
+ friend class LLTexGlobalColor;
+public:
+ LLTexGlobalColorInfo();
+ ~LLTexGlobalColorInfo();
+
+ BOOL parseXml(LLXmlTreeNode* node);
+
+private:
+ param_color_info_list_t mParamColorInfoList;
+ std::string mName;
+};
+
+class LLTexParamGlobalColor : public LLTexLayerParamColor
+{
+public:
+ LLTexParamGlobalColor(LLTexGlobalColor *tex_color);
+ /*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable) const;
+protected:
+ /*virtual*/ void onGlobalColorChanged(bool upload_bake);
+private:
+ LLTexGlobalColor* mTexGlobalColor;
+};
+
+#endif
diff --git a/indra/llappearance/lltexlayer.cpp b/indra/llappearance/lltexlayer.cpp
new file mode 100644
index 0000000000..a3a8616864
--- /dev/null
+++ b/indra/llappearance/lltexlayer.cpp
@@ -0,0 +1,2022 @@
+/**
+ * @file lltexlayer.cpp
+ * @brief A texture layer. Used for avatars.
+ *
+ * $LicenseInfo:firstyear=2002&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 "lltexlayer.h"
+
+#include "llavatarappearance.h"
+#include "llcrc.h"
+#include "imageids.h"
+#include "llimagej2c.h"
+#include "llimagetga.h"
+#include "lldir.h"
+#include "llvfile.h"
+#include "llvfs.h"
+#include "lltexlayerparams.h"
+#include "lltexturemanagerbridge.h"
+#include "../llui/llui.h"
+#include "llwearable.h"
+#include "llwearabledata.h"
+#include "llvertexbuffer.h"
+#include "llviewervisualparam.h"
+
+//#include "../tools/imdebug/imdebug.h"
+
+using namespace LLAvatarAppearanceDefines;
+
+// runway consolidate
+extern std::string self_av_string();
+
+class LLTexLayerInfo
+{
+ friend class LLTexLayer;
+ friend class LLTexLayerTemplate;
+ friend class LLTexLayerInterface;
+public:
+ LLTexLayerInfo();
+ ~LLTexLayerInfo();
+
+ BOOL parseXml(LLXmlTreeNode* node);
+ BOOL createVisualParams(LLAvatarAppearance *appearance);
+ BOOL isUserSettable() { return mLocalTexture != -1; }
+ S32 getLocalTexture() const { return mLocalTexture; }
+ BOOL getOnlyAlpha() const { return mUseLocalTextureAlphaOnly; }
+ std::string getName() const { return mName; }
+
+private:
+ std::string mName;
+
+ BOOL mWriteAllChannels; // Don't use masking. Just write RGBA into buffer,
+ LLTexLayerInterface::ERenderPass mRenderPass;
+
+ std::string mGlobalColor;
+ LLColor4 mFixedColor;
+
+ S32 mLocalTexture;
+ std::string mStaticImageFileName;
+ BOOL mStaticImageIsMask;
+ BOOL mUseLocalTextureAlphaOnly; // Ignore RGB channels from the input texture. Use alpha as a mask
+ BOOL mIsVisibilityMask;
+
+ typedef std::vector< std::pair< std::string,BOOL > > morph_name_list_t;
+ morph_name_list_t mMorphNameList;
+ param_color_info_list_t mParamColorInfoList;
+ param_alpha_info_list_t mParamAlphaInfoList;
+};
+
+//-----------------------------------------------------------------------------
+// LLTexLayerSetBuffer
+// The composite image that a LLViewerTexLayerSet writes to. Each LLViewerTexLayerSet has one.
+//-----------------------------------------------------------------------------
+
+LLTexLayerSetBuffer::LLTexLayerSetBuffer(LLTexLayerSet* const owner) :
+ mTexLayerSet(owner)
+{
+}
+
+LLTexLayerSetBuffer::~LLTexLayerSetBuffer()
+{
+}
+
+void LLTexLayerSetBuffer::pushProjection() const
+{
+ gGL.matrixMode(LLRender::MM_PROJECTION);
+ gGL.pushMatrix();
+ gGL.loadIdentity();
+ gGL.ortho(0.0f, getCompositeWidth(), 0.0f, getCompositeHeight(), -1.0f, 1.0f);
+
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.pushMatrix();
+ gGL.loadIdentity();
+}
+
+void LLTexLayerSetBuffer::popProjection() const
+{
+ gGL.matrixMode(LLRender::MM_PROJECTION);
+ gGL.popMatrix();
+
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.popMatrix();
+}
+
+// virtual
+void LLTexLayerSetBuffer::preRenderTexLayerSet()
+{
+ // Set up an ortho projection
+ pushProjection();
+}
+
+// virtual
+void LLTexLayerSetBuffer::postRenderTexLayerSet(BOOL success)
+{
+ popProjection();
+}
+
+BOOL LLTexLayerSetBuffer::renderTexLayerSet()
+{
+ // Default color mask for tex layer render
+ gGL.setColorMask(true, true);
+
+ BOOL success = TRUE;
+
+ bool use_shaders = LLGLSLShader::sNoFixedFunction;
+
+ if (use_shaders)
+ {
+ gAlphaMaskProgram.bind();
+ gAlphaMaskProgram.setMinimumAlpha(0.004f);
+ }
+ else
+ {
+ gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.00f);
+ }
+
+ LLVertexBuffer::unbind();
+
+ // Composite the color data
+ LLGLSUIDefault gls_ui;
+ success &= mTexLayerSet->render( getCompositeOriginX(), getCompositeOriginY(),
+ getCompositeWidth(), getCompositeHeight() );
+ gGL.flush();
+
+ midRenderTexLayerSet(success);
+
+ if (use_shaders)
+ {
+ gAlphaMaskProgram.unbind();
+ }
+
+ LLVertexBuffer::unbind();
+
+ // reset GL state
+ gGL.setColorMask(true, true);
+ gGL.setSceneBlendType(LLRender::BT_ALPHA);
+
+ return success;
+}
+
+//-----------------------------------------------------------------------------
+// LLTexLayerSetInfo
+// An ordered set of texture layers that get composited into a single texture.
+//-----------------------------------------------------------------------------
+
+LLTexLayerSetInfo::LLTexLayerSetInfo() :
+ mBodyRegion( "" ),
+ mWidth( 512 ),
+ mHeight( 512 ),
+ mClearAlpha( TRUE )
+{
+}
+
+LLTexLayerSetInfo::~LLTexLayerSetInfo( )
+{
+ std::for_each(mLayerInfoList.begin(), mLayerInfoList.end(), DeletePointer());
+}
+
+BOOL LLTexLayerSetInfo::parseXml(LLXmlTreeNode* node)
+{
+ llassert( node->hasName( "layer_set" ) );
+ if( !node->hasName( "layer_set" ) )
+ {
+ return FALSE;
+ }
+
+ // body_region
+ static LLStdStringHandle body_region_string = LLXmlTree::addAttributeString("body_region");
+ if( !node->getFastAttributeString( body_region_string, mBodyRegion ) )
+ {
+ llwarns << "<layer_set> is missing body_region attribute" << llendl;
+ return FALSE;
+ }
+
+ // width, height
+ static LLStdStringHandle width_string = LLXmlTree::addAttributeString("width");
+ if( !node->getFastAttributeS32( width_string, mWidth ) )
+ {
+ return FALSE;
+ }
+
+ static LLStdStringHandle height_string = LLXmlTree::addAttributeString("height");
+ if( !node->getFastAttributeS32( height_string, mHeight ) )
+ {
+ return FALSE;
+ }
+
+ // Optional alpha component to apply after all compositing is complete.
+ static LLStdStringHandle alpha_tga_file_string = LLXmlTree::addAttributeString("alpha_tga_file");
+ node->getFastAttributeString( alpha_tga_file_string, mStaticAlphaFileName );
+
+ static LLStdStringHandle clear_alpha_string = LLXmlTree::addAttributeString("clear_alpha");
+ node->getFastAttributeBOOL( clear_alpha_string, mClearAlpha );
+
+ // <layer>
+ for (LLXmlTreeNode* child = node->getChildByName( "layer" );
+ child;
+ child = node->getNextNamedChild())
+ {
+ LLTexLayerInfo* info = new LLTexLayerInfo();
+ if( !info->parseXml( child ))
+ {
+ delete info;
+ return FALSE;
+ }
+ mLayerInfoList.push_back( info );
+ }
+ return TRUE;
+}
+
+// creates visual params without generating layersets or layers
+void LLTexLayerSetInfo::createVisualParams(LLAvatarAppearance *appearance)
+{
+ //layer_info_list_t mLayerInfoList;
+ for (layer_info_list_t::iterator layer_iter = mLayerInfoList.begin();
+ layer_iter != mLayerInfoList.end();
+ layer_iter++)
+ {
+ LLTexLayerInfo *layer_info = *layer_iter;
+ layer_info->createVisualParams(appearance);
+ }
+}
+
+//-----------------------------------------------------------------------------
+// LLTexLayerSet
+// An ordered set of texture layers that get composited into a single texture.
+//-----------------------------------------------------------------------------
+
+BOOL LLTexLayerSet::sHasCaches = FALSE;
+
+LLTexLayerSet::LLTexLayerSet(LLAvatarAppearance* const appearance) :
+ mAvatarAppearance( appearance ),
+ mIsVisible( TRUE ),
+ mBakedTexIndex(LLAvatarAppearanceDefines::BAKED_HEAD),
+ mInfo( NULL )
+{
+}
+
+// virtual
+LLTexLayerSet::~LLTexLayerSet()
+{
+ deleteCaches();
+ std::for_each(mLayerList.begin(), mLayerList.end(), DeletePointer());
+ std::for_each(mMaskLayerList.begin(), mMaskLayerList.end(), DeletePointer());
+}
+
+//-----------------------------------------------------------------------------
+// setInfo
+//-----------------------------------------------------------------------------
+
+BOOL LLTexLayerSet::setInfo(const LLTexLayerSetInfo *info)
+{
+ llassert(mInfo == NULL);
+ mInfo = info;
+ //mID = info->mID; // No ID
+
+ mLayerList.reserve(info->mLayerInfoList.size());
+ for (LLTexLayerSetInfo::layer_info_list_t::const_iterator iter = info->mLayerInfoList.begin();
+ iter != info->mLayerInfoList.end();
+ iter++)
+ {
+ LLTexLayerInterface *layer = NULL;
+ if ( (*iter)->isUserSettable() )
+ {
+ layer = new LLTexLayerTemplate( this, getAvatarAppearance() );
+ }
+ else
+ {
+ layer = new LLTexLayer(this);
+ }
+ // this is the first time this layer (of either type) is being created - make sure you add the parameters to the avatar appearance
+ if (!layer->setInfo(*iter, NULL))
+ {
+ mInfo = NULL;
+ return FALSE;
+ }
+ if (!layer->isVisibilityMask())
+ {
+ mLayerList.push_back( layer );
+ }
+ else
+ {
+ mMaskLayerList.push_back(layer);
+ }
+ }
+
+ requestUpdate();
+
+ stop_glerror();
+
+ return TRUE;
+}
+
+#if 0 // obsolete
+//-----------------------------------------------------------------------------
+// parseData
+//-----------------------------------------------------------------------------
+
+BOOL LLTexLayerSet::parseData(LLXmlTreeNode* node)
+{
+ LLTexLayerSetInfo *info = new LLTexLayerSetInfo;
+
+ if (!info->parseXml(node))
+ {
+ delete info;
+ return FALSE;
+ }
+ if (!setInfo(info))
+ {
+ delete info;
+ return FALSE;
+ }
+ return TRUE;
+}
+#endif
+
+void LLTexLayerSet::deleteCaches()
+{
+ for( layer_list_t::iterator iter = mLayerList.begin(); iter != mLayerList.end(); iter++ )
+ {
+ LLTexLayerInterface* layer = *iter;
+ layer->deleteCaches();
+ }
+ for (layer_list_t::iterator iter = mMaskLayerList.begin(); iter != mMaskLayerList.end(); iter++)
+ {
+ LLTexLayerInterface* layer = *iter;
+ layer->deleteCaches();
+ }
+}
+
+
+BOOL LLTexLayerSet::render( S32 x, S32 y, S32 width, S32 height )
+{
+ BOOL success = TRUE;
+ mIsVisible = TRUE;
+
+ if (mMaskLayerList.size() > 0)
+ {
+ for (layer_list_t::iterator iter = mMaskLayerList.begin(); iter != mMaskLayerList.end(); iter++)
+ {
+ LLTexLayerInterface* layer = *iter;
+ if (layer->isInvisibleAlphaMask())
+ {
+ mIsVisible = FALSE;
+ }
+ }
+ }
+
+ bool use_shaders = LLGLSLShader::sNoFixedFunction;
+
+ LLGLSUIDefault gls_ui;
+ LLGLDepthTest gls_depth(GL_FALSE, GL_FALSE);
+ gGL.setColorMask(true, true);
+
+ // clear buffer area to ensure we don't pick up UI elements
+ {
+ gGL.flush();
+ LLGLDisable no_alpha(GL_ALPHA_TEST);
+ if (use_shaders)
+ {
+ gAlphaMaskProgram.setMinimumAlpha(0.0f);
+ }
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.color4f( 0.f, 0.f, 0.f, 1.f );
+
+ gl_rect_2d_simple( width, height );
+
+ gGL.flush();
+ if (use_shaders)
+ {
+ gAlphaMaskProgram.setMinimumAlpha(0.004f);
+ }
+ }
+
+ if (mIsVisible)
+ {
+ // composite color layers
+ for( layer_list_t::iterator iter = mLayerList.begin(); iter != mLayerList.end(); iter++ )
+ {
+ LLTexLayerInterface* layer = *iter;
+ if (layer->getRenderPass() == LLTexLayer::RP_COLOR)
+ {
+ gGL.flush();
+ success &= layer->render(x, y, width, height);
+ gGL.flush();
+ }
+ }
+
+ renderAlphaMaskTextures(x, y, width, height, false);
+
+ stop_glerror();
+ }
+ else
+ {
+ gGL.flush();
+
+ gGL.setSceneBlendType(LLRender::BT_REPLACE);
+ LLGLDisable no_alpha(GL_ALPHA_TEST);
+ if (use_shaders)
+ {
+ gAlphaMaskProgram.setMinimumAlpha(0.f);
+ }
+
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.color4f( 0.f, 0.f, 0.f, 0.f );
+
+ gl_rect_2d_simple( width, height );
+ gGL.setSceneBlendType(LLRender::BT_ALPHA);
+
+ gGL.flush();
+ if (use_shaders)
+ {
+ gAlphaMaskProgram.setMinimumAlpha(0.004f);
+ }
+ }
+
+ return success;
+}
+
+
+BOOL LLTexLayerSet::isBodyRegion(const std::string& region) const
+{
+ return mInfo->mBodyRegion == region;
+}
+
+const std::string LLTexLayerSet::getBodyRegionName() const
+{
+ return mInfo->mBodyRegion;
+}
+
+
+// virtual
+void LLTexLayerSet::asLLSD(LLSD& sd) const
+{
+ sd["visible"] = LLSD::Boolean(isVisible());
+ LLSD layer_list_sd;
+ layer_list_t::const_iterator layer_iter = mLayerList.begin();
+ layer_list_t::const_iterator layer_end = mLayerList.end();
+ for(; layer_iter != layer_end; ++layer_iter);
+ {
+ LLSD layer_sd;
+ //LLTexLayerInterface* layer = (*layer_iter);
+ //if (layer)
+ //{
+ // layer->asLLSD(layer_sd);
+ //}
+ layer_list_sd.append(layer_sd);
+ }
+ LLSD mask_list_sd;
+ LLSD info_sd;
+ sd["layers"] = layer_list_sd;
+ sd["masks"] = mask_list_sd;
+ sd["info"] = info_sd;
+}
+
+
+void LLTexLayerSet::destroyComposite()
+{
+ if( mComposite )
+ {
+ mComposite = NULL;
+ }
+}
+
+LLTexLayerSetBuffer* LLTexLayerSet::getComposite()
+{
+ if (!mComposite)
+ {
+ createComposite();
+ }
+ return mComposite;
+}
+
+const LLTexLayerSetBuffer* LLTexLayerSet::getComposite() const
+{
+ return mComposite;
+}
+
+static LLFastTimer::DeclareTimer FTM_GATHER_MORPH_MASK_ALPHA("gatherMorphMaskAlpha");
+void LLTexLayerSet::gatherMorphMaskAlpha(U8 *data, S32 origin_x, S32 origin_y, S32 width, S32 height)
+{
+ LLFastTimer t(FTM_GATHER_MORPH_MASK_ALPHA);
+ memset(data, 255, width * height);
+
+ for( layer_list_t::iterator iter = mLayerList.begin(); iter != mLayerList.end(); iter++ )
+ {
+ LLTexLayerInterface* layer = *iter;
+ layer->gatherAlphaMasks(data, origin_x, origin_y, width, height);
+ }
+
+ // Set alpha back to that of our alpha masks.
+ renderAlphaMaskTextures(origin_x, origin_y, width, height, true);
+}
+
+static LLFastTimer::DeclareTimer FTM_RENDER_ALPHA_MASK_TEXTURES("renderAlphaMaskTextures");
+void LLTexLayerSet::renderAlphaMaskTextures(S32 x, S32 y, S32 width, S32 height, bool forceClear)
+{
+ LLFastTimer t(FTM_RENDER_ALPHA_MASK_TEXTURES);
+ const LLTexLayerSetInfo *info = getInfo();
+
+ bool use_shaders = LLGLSLShader::sNoFixedFunction;
+
+ gGL.setColorMask(false, true);
+ gGL.setSceneBlendType(LLRender::BT_REPLACE);
+
+ // (Optionally) replace alpha with a single component image from a tga file.
+ if (!info->mStaticAlphaFileName.empty())
+ {
+ gGL.flush();
+ {
+ LLGLTexture* tex = LLTexLayerStaticImageList::getInstance()->getTexture(info->mStaticAlphaFileName, TRUE);
+ if( tex )
+ {
+ LLGLSUIDefault gls_ui;
+ gGL.getTexUnit(0)->bind(tex);
+ gGL.getTexUnit(0)->setTextureBlendType( LLTexUnit::TB_REPLACE );
+ gl_rect_2d_simple_tex( width, height );
+ }
+ }
+ gGL.flush();
+ }
+ else if (forceClear || info->mClearAlpha || (mMaskLayerList.size() > 0))
+ {
+ // Set the alpha channel to one (clean up after previous blending)
+ gGL.flush();
+ LLGLDisable no_alpha(GL_ALPHA_TEST);
+ if (use_shaders)
+ {
+ gAlphaMaskProgram.setMinimumAlpha(0.f);
+ }
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.color4f( 0.f, 0.f, 0.f, 1.f );
+
+ gl_rect_2d_simple( width, height );
+
+ gGL.flush();
+ if (use_shaders)
+ {
+ gAlphaMaskProgram.setMinimumAlpha(0.004f);
+ }
+ }
+
+ // (Optional) Mask out part of the baked texture with alpha masks
+ // will still have an effect even if mClearAlpha is set or the alpha component was replaced
+ if (mMaskLayerList.size() > 0)
+ {
+ gGL.setSceneBlendType(LLRender::BT_MULT_ALPHA);
+ gGL.getTexUnit(0)->setTextureBlendType( LLTexUnit::TB_REPLACE );
+ for (layer_list_t::iterator iter = mMaskLayerList.begin(); iter != mMaskLayerList.end(); iter++)
+ {
+ LLTexLayerInterface* layer = *iter;
+ gGL.flush();
+ layer->blendAlphaTexture(x,y,width, height);
+ gGL.flush();
+ }
+
+ }
+
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+ gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
+ gGL.setColorMask(true, true);
+ gGL.setSceneBlendType(LLRender::BT_ALPHA);
+}
+
+void LLTexLayerSet::applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_components)
+{
+ mAvatarAppearance->applyMorphMask(tex_data, width, height, num_components, mBakedTexIndex);
+}
+
+BOOL LLTexLayerSet::isMorphValid() const
+{
+ for(layer_list_t::const_iterator iter = mLayerList.begin(); iter != mLayerList.end(); iter++ )
+ {
+ const LLTexLayerInterface* layer = *iter;
+ if (layer && !layer->isMorphValid())
+ {
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+void LLTexLayerSet::invalidateMorphMasks()
+{
+ for( layer_list_t::iterator iter = mLayerList.begin(); iter != mLayerList.end(); iter++ )
+ {
+ LLTexLayerInterface* layer = *iter;
+ if (layer)
+ {
+ layer->invalidateMorphMasks();
+ }
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// LLTexLayerInfo
+//-----------------------------------------------------------------------------
+LLTexLayerInfo::LLTexLayerInfo() :
+ mWriteAllChannels( FALSE ),
+ mRenderPass(LLTexLayer::RP_COLOR),
+ mFixedColor( 0.f, 0.f, 0.f, 0.f ),
+ mLocalTexture( -1 ),
+ mStaticImageIsMask( FALSE ),
+ mUseLocalTextureAlphaOnly(FALSE),
+ mIsVisibilityMask(FALSE)
+{
+}
+
+LLTexLayerInfo::~LLTexLayerInfo( )
+{
+ std::for_each(mParamColorInfoList.begin(), mParamColorInfoList.end(), DeletePointer());
+ std::for_each(mParamAlphaInfoList.begin(), mParamAlphaInfoList.end(), DeletePointer());
+}
+
+BOOL LLTexLayerInfo::parseXml(LLXmlTreeNode* node)
+{
+ llassert( node->hasName( "layer" ) );
+
+ // name attribute
+ static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name");
+ if( !node->getFastAttributeString( name_string, mName ) )
+ {
+ return FALSE;
+ }
+
+ static LLStdStringHandle write_all_channels_string = LLXmlTree::addAttributeString("write_all_channels");
+ node->getFastAttributeBOOL( write_all_channels_string, mWriteAllChannels );
+
+ std::string render_pass_name;
+ static LLStdStringHandle render_pass_string = LLXmlTree::addAttributeString("render_pass");
+ if( node->getFastAttributeString( render_pass_string, render_pass_name ) )
+ {
+ if( render_pass_name == "bump" )
+ {
+ mRenderPass = LLTexLayer::RP_BUMP;
+ }
+ }
+
+ // Note: layers can have either a "global_color" attrib, a "fixed_color" attrib, or a <param_color> child.
+ // global color attribute (optional)
+ static LLStdStringHandle global_color_string = LLXmlTree::addAttributeString("global_color");
+ node->getFastAttributeString( global_color_string, mGlobalColor );
+
+ // Visibility mask (optional)
+ BOOL is_visibility;
+ static LLStdStringHandle visibility_mask_string = LLXmlTree::addAttributeString("visibility_mask");
+ if (node->getFastAttributeBOOL(visibility_mask_string, is_visibility))
+ {
+ mIsVisibilityMask = is_visibility;
+ }
+
+ // color attribute (optional)
+ LLColor4U color4u;
+ static LLStdStringHandle fixed_color_string = LLXmlTree::addAttributeString("fixed_color");
+ if( node->getFastAttributeColor4U( fixed_color_string, color4u ) )
+ {
+ mFixedColor.setVec( color4u );
+ }
+
+ // <texture> optional sub-element
+ for (LLXmlTreeNode* texture_node = node->getChildByName( "texture" );
+ texture_node;
+ texture_node = node->getNextNamedChild())
+ {
+ std::string local_texture_name;
+ static LLStdStringHandle tga_file_string = LLXmlTree::addAttributeString("tga_file");
+ static LLStdStringHandle local_texture_string = LLXmlTree::addAttributeString("local_texture");
+ static LLStdStringHandle file_is_mask_string = LLXmlTree::addAttributeString("file_is_mask");
+ static LLStdStringHandle local_texture_alpha_only_string = LLXmlTree::addAttributeString("local_texture_alpha_only");
+ if( texture_node->getFastAttributeString( tga_file_string, mStaticImageFileName ) )
+ {
+ texture_node->getFastAttributeBOOL( file_is_mask_string, mStaticImageIsMask );
+ }
+ else if (texture_node->getFastAttributeString(local_texture_string, local_texture_name))
+ {
+ texture_node->getFastAttributeBOOL( local_texture_alpha_only_string, mUseLocalTextureAlphaOnly );
+
+ /* if ("upper_shirt" == local_texture_name)
+ mLocalTexture = TEX_UPPER_SHIRT; */
+ mLocalTexture = TEX_NUM_INDICES;
+ for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getTextures().begin();
+ iter != LLAvatarAppearanceDictionary::getInstance()->getTextures().end();
+ iter++)
+ {
+ const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = iter->second;
+ if (local_texture_name == texture_dict->mName)
+ {
+ mLocalTexture = iter->first;
+ break;
+ }
+ }
+ if (mLocalTexture == TEX_NUM_INDICES)
+ {
+ llwarns << "<texture> element has invalid local_texture attribute: " << mName << " " << local_texture_name << llendl;
+ return FALSE;
+ }
+ }
+ else
+ {
+ llwarns << "<texture> element is missing a required attribute. " << mName << llendl;
+ return FALSE;
+ }
+ }
+
+ for (LLXmlTreeNode* maskNode = node->getChildByName( "morph_mask" );
+ maskNode;
+ maskNode = node->getNextNamedChild())
+ {
+ std::string morph_name;
+ static LLStdStringHandle morph_name_string = LLXmlTree::addAttributeString("morph_name");
+ if (maskNode->getFastAttributeString(morph_name_string, morph_name))
+ {
+ BOOL invert = FALSE;
+ static LLStdStringHandle invert_string = LLXmlTree::addAttributeString("invert");
+ maskNode->getFastAttributeBOOL(invert_string, invert);
+ mMorphNameList.push_back(std::pair<std::string,BOOL>(morph_name,invert));
+ }
+ }
+
+ // <param> optional sub-element (color or alpha params)
+ for (LLXmlTreeNode* child = node->getChildByName( "param" );
+ child;
+ child = node->getNextNamedChild())
+ {
+ if( child->getChildByName( "param_color" ) )
+ {
+ // <param><param_color/></param>
+ LLTexLayerParamColorInfo* info = new LLTexLayerParamColorInfo();
+ if (!info->parseXml(child))
+ {
+ delete info;
+ return FALSE;
+ }
+ mParamColorInfoList.push_back(info);
+ }
+ else if( child->getChildByName( "param_alpha" ) )
+ {
+ // <param><param_alpha/></param>
+ LLTexLayerParamAlphaInfo* info = new LLTexLayerParamAlphaInfo( );
+ if (!info->parseXml(child))
+ {
+ delete info;
+ return FALSE;
+ }
+ mParamAlphaInfoList.push_back(info);
+ }
+ }
+
+ return TRUE;
+}
+
+BOOL LLTexLayerInfo::createVisualParams(LLAvatarAppearance *appearance)
+{
+ BOOL success = TRUE;
+ for (param_color_info_list_t::iterator color_info_iter = mParamColorInfoList.begin();
+ color_info_iter != mParamColorInfoList.end();
+ color_info_iter++)
+ {
+ LLTexLayerParamColorInfo * color_info = *color_info_iter;
+ LLTexLayerParamColor* param_color = new LLTexLayerParamColor(appearance);
+ if (!param_color->setInfo(color_info, TRUE))
+ {
+ llwarns << "NULL TexLayer Color Param could not be added to visual param list. Deleting." << llendl;
+ delete param_color;
+ success = FALSE;
+ }
+ }
+
+ for (param_alpha_info_list_t::iterator alpha_info_iter = mParamAlphaInfoList.begin();
+ alpha_info_iter != mParamAlphaInfoList.end();
+ alpha_info_iter++)
+ {
+ LLTexLayerParamAlphaInfo * alpha_info = *alpha_info_iter;
+ LLTexLayerParamAlpha* param_alpha = new LLTexLayerParamAlpha(appearance);
+ if (!param_alpha->setInfo(alpha_info, TRUE))
+ {
+ llwarns << "NULL TexLayer Alpha Param could not be added to visual param list. Deleting." << llendl;
+ delete param_alpha;
+ success = FALSE;
+ }
+ }
+
+ return success;
+}
+
+LLTexLayerInterface::LLTexLayerInterface(LLTexLayerSet* const layer_set):
+ mTexLayerSet( layer_set ),
+ mMorphMasksValid( FALSE ),
+ mInfo(NULL),
+ mHasMorph(FALSE)
+{
+}
+
+LLTexLayerInterface::LLTexLayerInterface(const LLTexLayerInterface &layer, LLWearable *wearable):
+ mTexLayerSet( layer.mTexLayerSet ),
+ mInfo(NULL)
+{
+ // don't add visual params for cloned layers
+ setInfo(layer.getInfo(), wearable);
+
+ mHasMorph = layer.mHasMorph;
+}
+
+BOOL LLTexLayerInterface::setInfo(const LLTexLayerInfo *info, LLWearable* wearable ) // This sets mInfo and calls initialization functions
+{
+ // setInfo should only be called once. Code is not robust enough to handle redefinition of a texlayer.
+ // Not a critical warning, but could be useful for debugging later issues. -Nyx
+ if (mInfo != NULL)
+ {
+ llwarns << "mInfo != NULL" << llendl;
+ }
+ mInfo = info;
+ //mID = info->mID; // No ID
+
+ mParamColorList.reserve(mInfo->mParamColorInfoList.size());
+ for (param_color_info_list_t::const_iterator iter = mInfo->mParamColorInfoList.begin();
+ iter != mInfo->mParamColorInfoList.end();
+ iter++)
+ {
+ LLTexLayerParamColor* param_color;
+ if (!wearable)
+ {
+ param_color = new LLTexLayerParamColor(this);
+ if (!param_color->setInfo(*iter, TRUE))
+ {
+ mInfo = NULL;
+ return FALSE;
+ }
+ }
+ else
+ {
+ param_color = (LLTexLayerParamColor*)wearable->getVisualParam((*iter)->getID());
+ if (!param_color)
+ {
+ mInfo = NULL;
+ return FALSE;
+ }
+ }
+ mParamColorList.push_back( param_color );
+ }
+
+ mParamAlphaList.reserve(mInfo->mParamAlphaInfoList.size());
+ for (param_alpha_info_list_t::const_iterator iter = mInfo->mParamAlphaInfoList.begin();
+ iter != mInfo->mParamAlphaInfoList.end();
+ iter++)
+ {
+ LLTexLayerParamAlpha* param_alpha;
+ if (!wearable)
+ {
+ param_alpha = new LLTexLayerParamAlpha( this );
+ if (!param_alpha->setInfo(*iter, TRUE))
+ {
+ mInfo = NULL;
+ return FALSE;
+ }
+ }
+ else
+ {
+ param_alpha = (LLTexLayerParamAlpha*) wearable->getVisualParam((*iter)->getID());
+ if (!param_alpha)
+ {
+ mInfo = NULL;
+ return FALSE;
+ }
+ }
+ mParamAlphaList.push_back( param_alpha );
+ }
+
+ return TRUE;
+}
+
+/*virtual*/ void LLTexLayerInterface::requestUpdate()
+{
+ mTexLayerSet->requestUpdate();
+}
+
+const std::string& LLTexLayerInterface::getName() const
+{
+ return mInfo->mName;
+}
+
+ETextureIndex LLTexLayerInterface::getLocalTextureIndex() const
+{
+ return (ETextureIndex) mInfo->mLocalTexture;
+}
+
+LLWearableType::EType LLTexLayerInterface::getWearableType() const
+{
+ ETextureIndex te = getLocalTextureIndex();
+ if (TEX_INVALID == te)
+ {
+ LLWearableType::EType type = LLWearableType::WT_INVALID;
+ param_color_list_t::const_iterator color_iter = mParamColorList.begin();
+ param_alpha_list_t::const_iterator alpha_iter = mParamAlphaList.begin();
+
+ for (; color_iter != mParamColorList.end(); color_iter++)
+ {
+ LLTexLayerParamColor* param = *color_iter;
+ if (param)
+ {
+ LLWearableType::EType new_type = (LLWearableType::EType)param->getWearableType();
+ if (new_type != LLWearableType::WT_INVALID && new_type != type)
+ {
+ if (type != LLWearableType::WT_INVALID)
+ {
+ return LLWearableType::WT_INVALID;
+ }
+ type = new_type;
+ }
+ }
+ }
+
+ for (; alpha_iter != mParamAlphaList.end(); alpha_iter++)
+ {
+ LLTexLayerParamAlpha* param = *alpha_iter;
+ if (param)
+ {
+ LLWearableType::EType new_type = (LLWearableType::EType)param->getWearableType();
+ if (new_type != LLWearableType::WT_INVALID && new_type != type)
+ {
+ if (type != LLWearableType::WT_INVALID)
+ {
+ return LLWearableType::WT_INVALID;
+ }
+ type = new_type;
+ }
+ }
+ }
+
+ return type;
+ }
+ return LLAvatarAppearanceDictionary::getTEWearableType(te);
+}
+
+LLTexLayerInterface::ERenderPass LLTexLayerInterface::getRenderPass() const
+{
+ return mInfo->mRenderPass;
+}
+
+const std::string& LLTexLayerInterface::getGlobalColor() const
+{
+ return mInfo->mGlobalColor;
+}
+
+BOOL LLTexLayerInterface::isVisibilityMask() const
+{
+ return mInfo->mIsVisibilityMask;
+}
+
+void LLTexLayerInterface::invalidateMorphMasks()
+{
+ mMorphMasksValid = FALSE;
+}
+
+LLViewerVisualParam* LLTexLayerInterface::getVisualParamPtr(S32 index) const
+{
+ LLViewerVisualParam *result = NULL;
+ for (param_color_list_t::const_iterator color_iter = mParamColorList.begin(); color_iter != mParamColorList.end() && !result; ++color_iter)
+ {
+ if ((*color_iter)->getID() == index)
+ {
+ result = *color_iter;
+ }
+ }
+ for (param_alpha_list_t::const_iterator alpha_iter = mParamAlphaList.begin(); alpha_iter != mParamAlphaList.end() && !result; ++alpha_iter)
+ {
+ if ((*alpha_iter)->getID() == index)
+ {
+ result = *alpha_iter;
+ }
+ }
+
+ return result;
+}
+
+//-----------------------------------------------------------------------------
+// LLTexLayer
+// A single texture layer, consisting of:
+// * color, consisting of either
+// * one or more color parameters (weighted colors)
+// * a reference to a global color
+// * a fixed color with non-zero alpha
+// * opaque white (the default)
+// * (optional) a texture defined by either
+// * a GUID
+// * a texture entry index (TE)
+// * (optional) one or more alpha parameters (weighted alpha textures)
+//-----------------------------------------------------------------------------
+LLTexLayer::LLTexLayer(LLTexLayerSet* const layer_set) :
+ LLTexLayerInterface( layer_set ),
+ mLocalTextureObject(NULL)
+{
+}
+
+LLTexLayer::LLTexLayer(const LLTexLayer &layer, LLWearable *wearable) :
+ LLTexLayerInterface( layer, wearable ),
+ mLocalTextureObject(NULL)
+{
+}
+
+LLTexLayer::LLTexLayer(const LLTexLayerTemplate &layer_template, LLLocalTextureObject *lto, LLWearable *wearable) :
+ LLTexLayerInterface( layer_template, wearable ),
+ mLocalTextureObject(lto)
+{
+}
+
+LLTexLayer::~LLTexLayer()
+{
+ // mParamAlphaList and mParamColorList are LLViewerVisualParam's and get
+ // deleted with ~LLCharacter()
+ //std::for_each(mParamAlphaList.begin(), mParamAlphaList.end(), DeletePointer());
+ //std::for_each(mParamColorList.begin(), mParamColorList.end(), DeletePointer());
+
+ for( alpha_cache_t::iterator iter = mAlphaCache.begin();
+ iter != mAlphaCache.end(); iter++ )
+ {
+ U8* alpha_data = iter->second;
+ delete [] alpha_data;
+ }
+
+}
+
+void LLTexLayer::asLLSD(LLSD& sd) const
+{
+ // *TODO: Finish
+ sd["id"] = getUUID();
+}
+
+//-----------------------------------------------------------------------------
+// setInfo
+//-----------------------------------------------------------------------------
+
+BOOL LLTexLayer::setInfo(const LLTexLayerInfo* info, LLWearable* wearable )
+{
+ return LLTexLayerInterface::setInfo(info, wearable);
+}
+
+//static
+void LLTexLayer::calculateTexLayerColor(const param_color_list_t &param_list, LLColor4 &net_color)
+{
+ for (param_color_list_t::const_iterator iter = param_list.begin();
+ iter != param_list.end(); iter++)
+ {
+ const LLTexLayerParamColor* param = *iter;
+ LLColor4 param_net = param->getNetColor();
+ const LLTexLayerParamColorInfo *info = (LLTexLayerParamColorInfo *)param->getInfo();
+ switch(info->getOperation())
+ {
+ case LLTexLayerParamColor::OP_ADD:
+ net_color += param_net;
+ break;
+ case LLTexLayerParamColor::OP_MULTIPLY:
+ net_color = net_color * param_net;
+ break;
+ case LLTexLayerParamColor::OP_BLEND:
+ net_color = lerp(net_color, param_net, param->getWeight());
+ break;
+ default:
+ llassert(0);
+ break;
+ }
+ }
+ net_color.clamp();
+}
+
+/*virtual*/ void LLTexLayer::deleteCaches()
+{
+ // Only need to delete caches for alpha params. Color params don't hold extra memory
+ for (param_alpha_list_t::iterator iter = mParamAlphaList.begin();
+ iter != mParamAlphaList.end(); iter++ )
+ {
+ LLTexLayerParamAlpha* param = *iter;
+ param->deleteCaches();
+ }
+}
+
+BOOL LLTexLayer::render(S32 x, S32 y, S32 width, S32 height)
+{
+ LLGLEnable color_mat(GL_COLOR_MATERIAL);
+ // *TODO: Is this correct?
+ //gPipeline.disableLights();
+ stop_glerror();
+ if (!LLGLSLShader::sNoFixedFunction)
+ {
+ glDisable(GL_LIGHTING);
+ }
+ stop_glerror();
+
+ bool use_shaders = LLGLSLShader::sNoFixedFunction;
+
+ LLColor4 net_color;
+ BOOL color_specified = findNetColor(&net_color);
+
+ if (mTexLayerSet->getAvatarAppearance()->mIsDummy)
+ {
+ color_specified = true;
+ net_color = LLAvatarAppearance::getDummyColor();
+ }
+
+ BOOL success = TRUE;
+
+ // If you can't see the layer, don't render it.
+ if( is_approx_zero( net_color.mV[VW] ) )
+ {
+ return success;
+ }
+
+ BOOL alpha_mask_specified = FALSE;
+ param_alpha_list_t::const_iterator iter = mParamAlphaList.begin();
+ if( iter != mParamAlphaList.end() )
+ {
+ // If we have alpha masks, but we're skipping all of them, skip the whole layer.
+ // However, we can't do this optimization if we have morph masks that need updating.
+/* if (!mHasMorph)
+ {
+ BOOL skip_layer = TRUE;
+
+ while( iter != mParamAlphaList.end() )
+ {
+ const LLTexLayerParamAlpha* param = *iter;
+
+ if( !param->getSkip() )
+ {
+ skip_layer = FALSE;
+ break;
+ }
+
+ iter++;
+ }
+
+ if( skip_layer )
+ {
+ return success;
+ }
+ }//*/
+
+ const bool force_render = true;
+ renderMorphMasks(x, y, width, height, net_color, force_render);
+ alpha_mask_specified = TRUE;
+ gGL.flush();
+ gGL.blendFunc(LLRender::BF_DEST_ALPHA, LLRender::BF_ONE_MINUS_DEST_ALPHA);
+ }
+
+ gGL.color4fv( net_color.mV);
+
+ if( getInfo()->mWriteAllChannels )
+ {
+ gGL.flush();
+ gGL.setSceneBlendType(LLRender::BT_REPLACE);
+ }
+
+ if( (getInfo()->mLocalTexture != -1) && !getInfo()->mUseLocalTextureAlphaOnly )
+ {
+ {
+ LLGLTexture* tex = NULL;
+ if (mLocalTextureObject && mLocalTextureObject->getImage())
+ {
+ tex = mLocalTextureObject->getImage();
+ if (mLocalTextureObject->getID() == IMG_DEFAULT_AVATAR)
+ {
+ tex = NULL;
+ }
+ }
+ else
+ {
+ llinfos << "lto not defined or image not defined: " << getInfo()->getLocalTexture() << " lto: " << mLocalTextureObject << llendl;
+ }
+// if( mTexLayerSet->getAvatarAppearance()->getLocalTextureGL((ETextureIndex)getInfo()->mLocalTexture, &image_gl ) )
+ {
+ if( tex )
+ {
+ bool no_alpha_test = getInfo()->mWriteAllChannels;
+ LLGLDisable alpha_test(no_alpha_test ? GL_ALPHA_TEST : 0);
+ if (no_alpha_test)
+ {
+ if (use_shaders)
+ {
+ gAlphaMaskProgram.setMinimumAlpha(0.f);
+ }
+ }
+
+ LLTexUnit::eTextureAddressMode old_mode = tex->getAddressMode();
+
+ gGL.getTexUnit(0)->bind(tex, TRUE);
+ gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
+
+ gl_rect_2d_simple_tex( width, height );
+
+ gGL.getTexUnit(0)->setTextureAddressMode(old_mode);
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ if (no_alpha_test)
+ {
+ if (use_shaders)
+ {
+ gAlphaMaskProgram.setMinimumAlpha(0.004f);
+ }
+ }
+ }
+ }
+// else
+// {
+// success = FALSE;
+// }
+ }
+ }
+
+ if( !getInfo()->mStaticImageFileName.empty() )
+ {
+ {
+ LLGLTexture* tex = LLTexLayerStaticImageList::getInstance()->getTexture(getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask);
+ if( tex )
+ {
+ gGL.getTexUnit(0)->bind(tex, TRUE);
+ gl_rect_2d_simple_tex( width, height );
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ }
+ else
+ {
+ success = FALSE;
+ }
+ }
+ }
+
+ if(((-1 == getInfo()->mLocalTexture) ||
+ getInfo()->mUseLocalTextureAlphaOnly) &&
+ getInfo()->mStaticImageFileName.empty() &&
+ color_specified )
+ {
+ LLGLDisable no_alpha(GL_ALPHA_TEST);
+ if (use_shaders)
+ {
+ gAlphaMaskProgram.setMinimumAlpha(0.000f);
+ }
+
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.color4fv( net_color.mV );
+ gl_rect_2d_simple( width, height );
+ if (use_shaders)
+ {
+ gAlphaMaskProgram.setMinimumAlpha(0.004f);
+ }
+ }
+
+ if( alpha_mask_specified || getInfo()->mWriteAllChannels )
+ {
+ // Restore standard blend func value
+ gGL.flush();
+ gGL.setSceneBlendType(LLRender::BT_ALPHA);
+ stop_glerror();
+ }
+
+ if( !success )
+ {
+ llinfos << "LLTexLayer::render() partial: " << getInfo()->mName << llendl;
+ }
+ return success;
+}
+
+const U8* LLTexLayer::getAlphaData() const
+{
+ LLCRC alpha_mask_crc;
+ const LLUUID& uuid = getUUID();
+ alpha_mask_crc.update((U8*)(&uuid.mData), UUID_BYTES);
+
+ for (param_alpha_list_t::const_iterator iter = mParamAlphaList.begin(); iter != mParamAlphaList.end(); iter++)
+ {
+ const LLTexLayerParamAlpha* param = *iter;
+ // MULTI-WEARABLE: verify visual parameters used here
+ F32 param_weight = param->getWeight();
+ alpha_mask_crc.update((U8*)&param_weight, sizeof(F32));
+ }
+
+ U32 cache_index = alpha_mask_crc.getCRC();
+
+ alpha_cache_t::const_iterator iter2 = mAlphaCache.find(cache_index);
+ return (iter2 == mAlphaCache.end()) ? 0 : iter2->second;
+}
+
+BOOL LLTexLayer::findNetColor(LLColor4* net_color) const
+{
+ // Color is either:
+ // * one or more color parameters (weighted colors) (which may make use of a global color or fixed color)
+ // * a reference to a global color
+ // * a fixed color with non-zero alpha
+ // * opaque white (the default)
+
+ if( !mParamColorList.empty() )
+ {
+ if( !getGlobalColor().empty() )
+ {
+ net_color->setVec( mTexLayerSet->getAvatarAppearance()->getGlobalColor( getInfo()->mGlobalColor ) );
+ }
+ else if (getInfo()->mFixedColor.mV[VW])
+ {
+ net_color->setVec( getInfo()->mFixedColor );
+ }
+ else
+ {
+ net_color->setVec( 0.f, 0.f, 0.f, 0.f );
+ }
+
+ calculateTexLayerColor(mParamColorList, *net_color);
+ return TRUE;
+ }
+
+ if( !getGlobalColor().empty() )
+ {
+ net_color->setVec( mTexLayerSet->getAvatarAppearance()->getGlobalColor( getGlobalColor() ) );
+ return TRUE;
+ }
+
+ if( getInfo()->mFixedColor.mV[VW] )
+ {
+ net_color->setVec( getInfo()->mFixedColor );
+ return TRUE;
+ }
+
+ net_color->setToWhite();
+
+ return FALSE; // No need to draw a separate colored polygon
+}
+
+BOOL LLTexLayer::blendAlphaTexture(S32 x, S32 y, S32 width, S32 height)
+{
+ BOOL success = TRUE;
+
+ gGL.flush();
+
+ bool use_shaders = LLGLSLShader::sNoFixedFunction;
+
+ if( !getInfo()->mStaticImageFileName.empty() )
+ {
+ LLGLTexture* tex = LLTexLayerStaticImageList::getInstance()->getTexture( getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask );
+ if( tex )
+ {
+ LLGLSNoAlphaTest gls_no_alpha_test;
+ if (use_shaders)
+ {
+ gAlphaMaskProgram.setMinimumAlpha(0.f);
+ }
+ gGL.getTexUnit(0)->bind(tex, TRUE);
+ gl_rect_2d_simple_tex( width, height );
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ if (use_shaders)
+ {
+ gAlphaMaskProgram.setMinimumAlpha(0.004f);
+ }
+ }
+ else
+ {
+ success = FALSE;
+ }
+ }
+ else
+ {
+ if (getInfo()->mLocalTexture >=0 && getInfo()->mLocalTexture < TEX_NUM_INDICES)
+ {
+ LLGLTexture* tex = mLocalTextureObject->getImage();
+ if (tex)
+ {
+ LLGLSNoAlphaTest gls_no_alpha_test;
+ if (use_shaders)
+ {
+ gAlphaMaskProgram.setMinimumAlpha(0.f);
+ }
+ gGL.getTexUnit(0)->bind(tex);
+ gl_rect_2d_simple_tex( width, height );
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ success = TRUE;
+ if (use_shaders)
+ {
+ gAlphaMaskProgram.setMinimumAlpha(0.004f);
+ }
+ }
+ }
+ }
+
+ return success;
+}
+
+/*virtual*/ void LLTexLayer::gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height)
+{
+ addAlphaMask(data, originX, originY, width, height);
+}
+
+static LLFastTimer::DeclareTimer FTM_RENDER_MORPH_MASKS("renderMorphMasks");
+void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLColor4 &layer_color, bool force_render)
+{
+ if (!force_render && !hasMorph())
+ {
+ lldebugs << "skipping renderMorphMasks for " << getUUID() << llendl;
+ return;
+ }
+ LLFastTimer t(FTM_RENDER_MORPH_MASKS);
+ BOOL success = TRUE;
+
+ llassert( !mParamAlphaList.empty() );
+
+ bool use_shaders = LLGLSLShader::sNoFixedFunction;
+
+ if (use_shaders)
+ {
+ gAlphaMaskProgram.setMinimumAlpha(0.f);
+ }
+
+ gGL.setColorMask(false, true);
+
+ LLTexLayerParamAlpha* first_param = *mParamAlphaList.begin();
+ // Note: if the first param is a mulitply, multiply against the current buffer's alpha
+ if( !first_param || !first_param->getMultiplyBlend() )
+ {
+ LLGLDisable no_alpha(GL_ALPHA_TEST);
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+ // Clear the alpha
+ gGL.flush();
+ gGL.setSceneBlendType(LLRender::BT_REPLACE);
+
+ gGL.color4f( 0.f, 0.f, 0.f, 0.f );
+ gl_rect_2d_simple( width, height );
+ }
+
+ // Accumulate alphas
+ LLGLSNoAlphaTest gls_no_alpha_test;
+ gGL.color4f( 1.f, 1.f, 1.f, 1.f );
+ for (param_alpha_list_t::iterator iter = mParamAlphaList.begin(); iter != mParamAlphaList.end(); iter++)
+ {
+ LLTexLayerParamAlpha* param = *iter;
+ success &= param->render( x, y, width, height );
+ if (!success && !force_render)
+ {
+ lldebugs << "Failed to render param " << param->getID() << " ; skipping morph mask." << llendl;
+ return;
+ }
+ }
+
+ // Approximates a min() function
+ gGL.flush();
+ gGL.setSceneBlendType(LLRender::BT_MULT_ALPHA);
+
+ // Accumulate the alpha component of the texture
+ if( getInfo()->mLocalTexture != -1 )
+ {
+ LLGLTexture* tex = mLocalTextureObject->getImage();
+ if( tex && (tex->getComponents() == 4) )
+ {
+ LLGLSNoAlphaTest gls_no_alpha_test;
+ LLTexUnit::eTextureAddressMode old_mode = tex->getAddressMode();
+
+ gGL.getTexUnit(0)->bind(tex, TRUE);
+ gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
+
+ gl_rect_2d_simple_tex( width, height );
+
+ gGL.getTexUnit(0)->setTextureAddressMode(old_mode);
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ }
+ }
+
+ if( !getInfo()->mStaticImageFileName.empty() && getInfo()->mStaticImageIsMask )
+ {
+ LLGLTexture* tex = LLTexLayerStaticImageList::getInstance()->getTexture(getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask);
+ if( tex )
+ {
+ if( (tex->getComponents() == 4) || (tex->getComponents() == 1) )
+ {
+ LLGLSNoAlphaTest gls_no_alpha_test;
+ gGL.getTexUnit(0)->bind(tex, TRUE);
+ gl_rect_2d_simple_tex( width, height );
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ }
+ else
+ {
+ llwarns << "Skipping rendering of " << getInfo()->mStaticImageFileName
+ << "; expected 1 or 4 components." << llendl;
+ }
+ }
+ }
+
+ // Draw a rectangle with the layer color to multiply the alpha by that color's alpha.
+ // Note: we're still using gGL.blendFunc( GL_DST_ALPHA, GL_ZERO );
+ if ( !is_approx_equal(layer_color.mV[VW], 1.f) )
+ {
+ LLGLDisable no_alpha(GL_ALPHA_TEST);
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.color4fv(layer_color.mV);
+ gl_rect_2d_simple( width, height );
+ }
+
+ if (use_shaders)
+ {
+ gAlphaMaskProgram.setMinimumAlpha(0.004f);
+ }
+
+ LLGLSUIDefault gls_ui;
+
+ gGL.setColorMask(true, true);
+
+ if (hasMorph() && success)
+ {
+ LLCRC alpha_mask_crc;
+ const LLUUID& uuid = getUUID();
+ alpha_mask_crc.update((U8*)(&uuid.mData), UUID_BYTES);
+
+ for (param_alpha_list_t::const_iterator iter = mParamAlphaList.begin(); iter != mParamAlphaList.end(); iter++)
+ {
+ const LLTexLayerParamAlpha* param = *iter;
+ F32 param_weight = param->getWeight();
+ alpha_mask_crc.update((U8*)&param_weight, sizeof(F32));
+ }
+
+ U32 cache_index = alpha_mask_crc.getCRC();
+ U8* alpha_data = get_if_there(mAlphaCache,cache_index,(U8*)NULL);
+ if (!alpha_data)
+ {
+ // clear out a slot if we have filled our cache
+ S32 max_cache_entries = getTexLayerSet()->getAvatarAppearance()->isSelf() ? 4 : 1;
+ while ((S32)mAlphaCache.size() >= max_cache_entries)
+ {
+ alpha_cache_t::iterator iter2 = mAlphaCache.begin(); // arbitrarily grab the first entry
+ alpha_data = iter2->second;
+ delete [] alpha_data;
+ mAlphaCache.erase(iter2);
+ }
+ alpha_data = new U8[width * height];
+ mAlphaCache[cache_index] = alpha_data;
+ glReadPixels(x, y, width, height, GL_ALPHA, GL_UNSIGNED_BYTE, alpha_data);
+ }
+
+ getTexLayerSet()->getAvatarAppearance()->dirtyMesh();
+
+ mMorphMasksValid = TRUE;
+ getTexLayerSet()->applyMorphMask(alpha_data, width, height, 1);
+ }
+}
+
+static LLFastTimer::DeclareTimer FTM_ADD_ALPHA_MASK("addAlphaMask");
+void LLTexLayer::addAlphaMask(U8 *data, S32 originX, S32 originY, S32 width, S32 height)
+{
+ LLFastTimer t(FTM_ADD_ALPHA_MASK);
+ S32 size = width * height;
+ const U8* alphaData = getAlphaData();
+ if (!alphaData && hasAlphaParams())
+ {
+ LLColor4 net_color;
+ findNetColor( &net_color );
+ // TODO: eliminate need for layer morph mask valid flag
+ invalidateMorphMasks();
+ const bool force_render = false;
+ renderMorphMasks(originX, originY, width, height, net_color, force_render);
+ alphaData = getAlphaData();
+ }
+ if (alphaData)
+ {
+ for( S32 i = 0; i < size; i++ )
+ {
+ U8 curAlpha = data[i];
+ U16 resultAlpha = curAlpha;
+ resultAlpha *= ( ((U16)alphaData[i]) + 1);
+ resultAlpha = resultAlpha >> 8;
+ data[i] = (U8)resultAlpha;
+ }
+ }
+}
+
+/*virtual*/ BOOL LLTexLayer::isInvisibleAlphaMask() const
+{
+ if (mLocalTextureObject)
+ {
+ if (mLocalTextureObject->getID() == IMG_INVISIBLE)
+ {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+LLUUID LLTexLayer::getUUID() const
+{
+ LLUUID uuid;
+ if( getInfo()->mLocalTexture != -1 )
+ {
+ LLGLTexture* tex = mLocalTextureObject->getImage();
+ if (tex)
+ {
+ uuid = mLocalTextureObject->getID();
+ }
+ }
+ if( !getInfo()->mStaticImageFileName.empty() )
+ {
+ LLGLTexture* tex = LLTexLayerStaticImageList::getInstance()->getTexture(getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask);
+ if( tex )
+ {
+ uuid = tex->getID();
+ }
+ }
+ return uuid;
+}
+
+
+//-----------------------------------------------------------------------------
+// LLTexLayerTemplate
+// A single texture layer, consisting of:
+// * color, consisting of either
+// * one or more color parameters (weighted colors)
+// * a reference to a global color
+// * a fixed color with non-zero alpha
+// * opaque white (the default)
+// * (optional) a texture defined by either
+// * a GUID
+// * a texture entry index (TE)
+// * (optional) one or more alpha parameters (weighted alpha textures)
+//-----------------------------------------------------------------------------
+LLTexLayerTemplate::LLTexLayerTemplate(LLTexLayerSet* layer_set, LLAvatarAppearance* const appearance) :
+ LLTexLayerInterface(layer_set),
+ mAvatarAppearance( appearance )
+{
+}
+
+LLTexLayerTemplate::LLTexLayerTemplate(const LLTexLayerTemplate &layer) :
+ LLTexLayerInterface(layer),
+ mAvatarAppearance(layer.getAvatarAppearance())
+{
+}
+
+LLTexLayerTemplate::~LLTexLayerTemplate()
+{
+}
+
+//-----------------------------------------------------------------------------
+// setInfo
+//-----------------------------------------------------------------------------
+
+/*virtual*/ BOOL LLTexLayerTemplate::setInfo(const LLTexLayerInfo* info, LLWearable* wearable )
+{
+ return LLTexLayerInterface::setInfo(info, wearable);
+}
+
+U32 LLTexLayerTemplate::updateWearableCache() const
+{
+ mWearableCache.clear();
+
+ LLWearableType::EType wearable_type = getWearableType();
+ if (LLWearableType::WT_INVALID == wearable_type)
+ {
+ //this isn't a cloneable layer
+ return 0;
+ }
+ U32 num_wearables = getAvatarAppearance()->getWearableData()->getWearableCount(wearable_type);
+ U32 added = 0;
+ for (U32 i = 0; i < num_wearables; i++)
+ {
+ LLWearable* wearable = getAvatarAppearance()->getWearableData()->getWearable(wearable_type, i);
+ if (!wearable)
+ {
+ continue;
+ }
+ mWearableCache.push_back(wearable);
+ added++;
+ }
+ return added;
+}
+LLTexLayer* LLTexLayerTemplate::getLayer(U32 i) const
+{
+ if (mWearableCache.size() <= i)
+ {
+ return NULL;
+ }
+ LLWearable *wearable = mWearableCache[i];
+ LLLocalTextureObject *lto = NULL;
+ LLTexLayer *layer = NULL;
+ if (wearable)
+ {
+ lto = wearable->getLocalTextureObject(mInfo->mLocalTexture);
+ }
+ if (lto)
+ {
+ layer = lto->getTexLayer(getName());
+ }
+ return layer;
+}
+
+/*virtual*/ BOOL LLTexLayerTemplate::render(S32 x, S32 y, S32 width, S32 height)
+{
+ if(!mInfo)
+ {
+ return FALSE ;
+ }
+
+ BOOL success = TRUE;
+ updateWearableCache();
+ for (wearable_cache_t::const_iterator iter = mWearableCache.begin(); iter!= mWearableCache.end(); iter++)
+ {
+ LLWearable* wearable = NULL;
+ LLLocalTextureObject *lto = NULL;
+ LLTexLayer *layer = NULL;
+ wearable = *iter;
+ if (wearable)
+ {
+ lto = wearable->getLocalTextureObject(mInfo->mLocalTexture);
+ }
+ if (lto)
+ {
+ layer = lto->getTexLayer(getName());
+ }
+ if (layer)
+ {
+ wearable->writeToAvatar(mAvatarAppearance);
+ layer->setLTO(lto);
+ success &= layer->render(x,y,width,height);
+ }
+ }
+
+ return success;
+}
+
+/*virtual*/ BOOL LLTexLayerTemplate::blendAlphaTexture( S32 x, S32 y, S32 width, S32 height) // Multiplies a single alpha texture against the frame buffer
+{
+ BOOL success = TRUE;
+ U32 num_wearables = updateWearableCache();
+ for (U32 i = 0; i < num_wearables; i++)
+ {
+ LLTexLayer *layer = getLayer(i);
+ if (layer)
+ {
+ success &= layer->blendAlphaTexture(x,y,width,height);
+ }
+ }
+ return success;
+}
+
+/*virtual*/ void LLTexLayerTemplate::gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height)
+{
+ U32 num_wearables = updateWearableCache();
+ for (U32 i = 0; i < num_wearables; i++)
+ {
+ LLTexLayer *layer = getLayer(i);
+ if (layer)
+ {
+ layer->addAlphaMask(data, originX, originY, width, height);
+ }
+ }
+}
+
+/*virtual*/ void LLTexLayerTemplate::setHasMorph(BOOL newval)
+{
+ mHasMorph = newval;
+ U32 num_wearables = updateWearableCache();
+ for (U32 i = 0; i < num_wearables; i++)
+ {
+ LLTexLayer *layer = getLayer(i);
+ if (layer)
+ {
+ layer->setHasMorph(newval);
+ }
+ }
+}
+
+/*virtual*/ void LLTexLayerTemplate::deleteCaches()
+{
+ U32 num_wearables = updateWearableCache();
+ for (U32 i = 0; i < num_wearables; i++)
+ {
+ LLTexLayer *layer = getLayer(i);
+ if (layer)
+ {
+ layer->deleteCaches();
+ }
+ }
+}
+
+/*virtual*/ BOOL LLTexLayerTemplate::isInvisibleAlphaMask() const
+{
+ U32 num_wearables = updateWearableCache();
+ for (U32 i = 0; i < num_wearables; i++)
+ {
+ LLTexLayer *layer = getLayer(i);
+ if (layer)
+ {
+ if (layer->isInvisibleAlphaMask())
+ {
+ return TRUE;
+ }
+ }
+ }
+
+ return FALSE;
+}
+
+
+//-----------------------------------------------------------------------------
+// finds a specific layer based on a passed in name
+//-----------------------------------------------------------------------------
+LLTexLayerInterface* LLTexLayerSet::findLayerByName(const std::string& name)
+{
+ for (layer_list_t::iterator iter = mLayerList.begin(); iter != mLayerList.end(); iter++ )
+ {
+ LLTexLayerInterface* layer = *iter;
+ if (layer->getName() == name)
+ {
+ return layer;
+ }
+ }
+ for (layer_list_t::iterator iter = mMaskLayerList.begin(); iter != mMaskLayerList.end(); iter++ )
+ {
+ LLTexLayerInterface* layer = *iter;
+ if (layer->getName() == name)
+ {
+ return layer;
+ }
+ }
+ return NULL;
+}
+
+void LLTexLayerSet::cloneTemplates(LLLocalTextureObject *lto, LLAvatarAppearanceDefines::ETextureIndex tex_index, LLWearable *wearable)
+{
+ // initialize all texlayers with this texture type for this LTO
+ for( LLTexLayerSet::layer_list_t::iterator iter = mLayerList.begin(); iter != mLayerList.end(); iter++ )
+ {
+ LLTexLayerTemplate* layer = (LLTexLayerTemplate*)*iter;
+ if (layer->getInfo()->getLocalTexture() == (S32) tex_index)
+ {
+ lto->addTexLayer(layer, wearable);
+ }
+ }
+ for( LLTexLayerSet::layer_list_t::iterator iter = mMaskLayerList.begin(); iter != mMaskLayerList.end(); iter++ )
+ {
+ LLTexLayerTemplate* layer = (LLTexLayerTemplate*)*iter;
+ if (layer->getInfo()->getLocalTexture() == (S32) tex_index)
+ {
+ lto->addTexLayer(layer, wearable);
+ }
+ }
+}
+//-----------------------------------------------------------------------------
+// LLTexLayerStaticImageList
+//-----------------------------------------------------------------------------
+
+LLTexLayerStaticImageList::LLTexLayerStaticImageList() :
+ mGLBytes(0),
+ mTGABytes(0),
+ mImageNames(16384)
+{
+}
+
+LLTexLayerStaticImageList::~LLTexLayerStaticImageList()
+{
+ deleteCachedImages();
+}
+
+void LLTexLayerStaticImageList::dumpByteCount() const
+{
+ llinfos << "Avatar Static Textures " <<
+ "KB GL:" << (mGLBytes / 1024) <<
+ "KB TGA:" << (mTGABytes / 1024) << "KB" << llendl;
+}
+
+void LLTexLayerStaticImageList::deleteCachedImages()
+{
+ if( mGLBytes || mTGABytes )
+ {
+ llinfos << "Clearing Static Textures " <<
+ "KB GL:" << (mGLBytes / 1024) <<
+ "KB TGA:" << (mTGABytes / 1024) << "KB" << llendl;
+
+ //mStaticImageLists uses LLPointers, clear() will cause deletion
+
+ mStaticImageListTGA.clear();
+ mStaticImageList.clear();
+
+ mGLBytes = 0;
+ mTGABytes = 0;
+ }
+}
+
+// Note: in general, for a given image image we'll call either getImageTga() or getTexture().
+// We call getImageTga() if the image is used as an alpha gradient.
+// Otherwise, we call getTexture()
+
+// Returns an LLImageTGA that contains the encoded data from a tga file named file_name.
+// Caches the result to speed identical subsequent requests.
+static LLFastTimer::DeclareTimer FTM_LOAD_STATIC_TGA("getImageTGA");
+LLImageTGA* LLTexLayerStaticImageList::getImageTGA(const std::string& file_name)
+{
+ LLFastTimer t(FTM_LOAD_STATIC_TGA);
+ const char *namekey = mImageNames.addString(file_name);
+ image_tga_map_t::const_iterator iter = mStaticImageListTGA.find(namekey);
+ if( iter != mStaticImageListTGA.end() )
+ {
+ return iter->second;
+ }
+ else
+ {
+ std::string path;
+ path = gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,file_name);
+ LLPointer<LLImageTGA> image_tga = new LLImageTGA( path );
+ if( image_tga->getDataSize() > 0 )
+ {
+ mStaticImageListTGA[ namekey ] = image_tga;
+ mTGABytes += image_tga->getDataSize();
+ return image_tga;
+ }
+ else
+ {
+ return NULL;
+ }
+ }
+}
+
+// Returns a GL Image (without a backing ImageRaw) that contains the decoded data from a tga file named file_name.
+// Caches the result to speed identical subsequent requests.
+static LLFastTimer::DeclareTimer FTM_LOAD_STATIC_TEXTURE("getTexture");
+LLGLTexture* LLTexLayerStaticImageList::getTexture(const std::string& file_name, BOOL is_mask)
+{
+ LLFastTimer t(FTM_LOAD_STATIC_TEXTURE);
+ LLPointer<LLGLTexture> tex;
+ const char *namekey = mImageNames.addString(file_name);
+
+ texture_map_t::const_iterator iter = mStaticImageList.find(namekey);
+ if( iter != mStaticImageList.end() )
+ {
+ tex = iter->second;
+ }
+ else
+ {
+ llassert(gTextureManagerBridgep);
+ tex = gTextureManagerBridgep->getLocalTexture( FALSE );
+ LLPointer<LLImageRaw> image_raw = new LLImageRaw;
+ if( loadImageRaw( file_name, image_raw ) )
+ {
+ if( (image_raw->getComponents() == 1) && is_mask )
+ {
+ // Convert grayscale alpha masks from single channel into RGBA.
+ // Fill RGB with black to allow fixed function gl calls
+ // to match shader implementation.
+ LLPointer<LLImageRaw> alpha_image_raw = image_raw;
+ image_raw = new LLImageRaw(image_raw->getWidth(),
+ image_raw->getHeight(),
+ 4);
+
+ image_raw->copyUnscaledAlphaMask(alpha_image_raw, LLColor4U::black);
+ }
+ tex->createGLTexture(0, image_raw, 0, TRUE, LLGLTexture::LOCAL);
+
+ gGL.getTexUnit(0)->bind(tex);
+ tex->setAddressMode(LLTexUnit::TAM_CLAMP);
+
+ mStaticImageList [ namekey ] = tex;
+ mGLBytes += (S32)tex->getWidth() * tex->getHeight() * tex->getComponents();
+ }
+ else
+ {
+ tex = NULL;
+ }
+ }
+
+ return tex;
+}
+
+// Reads a .tga file, decodes it, and puts the decoded data in image_raw.
+// Returns TRUE if successful.
+static LLFastTimer::DeclareTimer FTM_LOAD_IMAGE_RAW("loadImageRaw");
+BOOL LLTexLayerStaticImageList::loadImageRaw(const std::string& file_name, LLImageRaw* image_raw)
+{
+ LLFastTimer t(FTM_LOAD_IMAGE_RAW);
+ BOOL success = FALSE;
+ std::string path;
+ path = gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,file_name);
+ LLPointer<LLImageTGA> image_tga = new LLImageTGA( path );
+ if( image_tga->getDataSize() > 0 )
+ {
+ // Copy data from tga to raw.
+ success = image_tga->decode( image_raw );
+ }
+
+ return success;
+}
+
diff --git a/indra/llappearance/lltexlayer.h b/indra/llappearance/lltexlayer.h
new file mode 100644
index 0000000000..959d6e499a
--- /dev/null
+++ b/indra/llappearance/lltexlayer.h
@@ -0,0 +1,315 @@
+/**
+ * @file lltexlayer.h
+ * @brief Texture layer classes. Used for avatars.
+ *
+ * $LicenseInfo:firstyear=2002&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$
+ */
+
+#ifndef LL_LLTEXLAYER_H
+#define LL_LLTEXLAYER_H
+
+#include <deque>
+#include "llglslshader.h"
+#include "llgltexture.h"
+#include "llavatarappearancedefines.h"
+#include "lltexlayerparams.h"
+
+class LLAvatarAppearance;
+class LLImageTGA;
+class LLImageRaw;
+class LLLocalTextureObject;
+class LLXmlTreeNode;
+class LLTexLayerSet;
+class LLTexLayerSetInfo;
+class LLTexLayerInfo;
+class LLTexLayerSetBuffer;
+class LLWearable;
+class LLViewerVisualParam;
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// LLTexLayerInterface
+//
+// Interface class to generalize functionality shared by LLTexLayer
+// and LLTexLayerTemplate.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+class LLTexLayerInterface
+{
+public:
+ enum ERenderPass
+ {
+ RP_COLOR,
+ RP_BUMP,
+ RP_SHINE
+ };
+
+ LLTexLayerInterface(LLTexLayerSet* const layer_set);
+ LLTexLayerInterface(const LLTexLayerInterface &layer, LLWearable *wearable);
+ virtual ~LLTexLayerInterface() {}
+
+ virtual BOOL render(S32 x, S32 y, S32 width, S32 height) = 0;
+ virtual void deleteCaches() = 0;
+ virtual BOOL blendAlphaTexture(S32 x, S32 y, S32 width, S32 height) = 0;
+ virtual BOOL isInvisibleAlphaMask() const = 0;
+
+ const LLTexLayerInfo* getInfo() const { return mInfo; }
+ virtual BOOL setInfo(const LLTexLayerInfo *info, LLWearable* wearable); // sets mInfo, calls initialization functions
+ LLWearableType::EType getWearableType() const;
+ LLAvatarAppearanceDefines::ETextureIndex getLocalTextureIndex() const;
+
+ const std::string& getName() const;
+ const LLTexLayerSet* const getTexLayerSet() const { return mTexLayerSet; }
+ LLTexLayerSet* const getTexLayerSet() { return mTexLayerSet; }
+
+ void invalidateMorphMasks();
+ virtual void setHasMorph(BOOL newval) { mHasMorph = newval; }
+ BOOL hasMorph() const { return mHasMorph; }
+ BOOL isMorphValid() const { return mMorphMasksValid; }
+
+ void requestUpdate();
+ virtual void gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height) = 0;
+ BOOL hasAlphaParams() const { return !mParamAlphaList.empty(); }
+
+ ERenderPass getRenderPass() const;
+ BOOL isVisibilityMask() const;
+
+ virtual void asLLSD(LLSD& sd) const {}
+
+protected:
+ const std::string& getGlobalColor() const;
+ LLViewerVisualParam* getVisualParamPtr(S32 index) const;
+
+protected:
+ LLTexLayerSet* const mTexLayerSet;
+ const LLTexLayerInfo* mInfo;
+ BOOL mMorphMasksValid;
+ BOOL mHasMorph;
+
+ // Layers can have either mParamColorList, mGlobalColor, or mFixedColor. They are looked for in that order.
+ param_color_list_t mParamColorList;
+ param_alpha_list_t mParamAlphaList;
+ // mGlobalColor name stored in mInfo
+ // mFixedColor value stored in mInfo
+};
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// LLTexLayerTemplate
+//
+// Only exists for llvoavatarself.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+class LLTexLayerTemplate : public LLTexLayerInterface
+{
+public:
+ LLTexLayerTemplate(LLTexLayerSet* const layer_set, LLAvatarAppearance* const appearance);
+ LLTexLayerTemplate(const LLTexLayerTemplate &layer);
+ /*virtual*/ ~LLTexLayerTemplate();
+ /*virtual*/ BOOL render(S32 x, S32 y, S32 width, S32 height);
+ /*virtual*/ BOOL setInfo(const LLTexLayerInfo *info, LLWearable* wearable); // This sets mInfo and calls initialization functions
+ /*virtual*/ BOOL blendAlphaTexture(S32 x, S32 y, S32 width, S32 height); // Multiplies a single alpha texture against the frame buffer
+ /*virtual*/ void gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height);
+ /*virtual*/ void setHasMorph(BOOL newval);
+ /*virtual*/ void deleteCaches();
+ /*virtual*/ BOOL isInvisibleAlphaMask() const;
+protected:
+ U32 updateWearableCache() const;
+ LLTexLayer* getLayer(U32 i) const;
+ LLAvatarAppearance* getAvatarAppearance() const { return mAvatarAppearance; }
+private:
+ LLAvatarAppearance* const mAvatarAppearance; // note: backlink only; don't make this an LLPointer.
+ typedef std::vector<LLWearable*> wearable_cache_t;
+ mutable wearable_cache_t mWearableCache; // mutable b/c most get- require updating this cache
+};
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// LLTexLayer
+//
+// A single texture layer. Only exists for llvoavatarself.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+class LLTexLayer : public LLTexLayerInterface
+{
+public:
+ LLTexLayer(LLTexLayerSet* const layer_set);
+ LLTexLayer(const LLTexLayer &layer, LLWearable *wearable);
+ LLTexLayer(const LLTexLayerTemplate &layer_template, LLLocalTextureObject *lto, LLWearable *wearable);
+ /*virtual*/ ~LLTexLayer();
+
+ /*virtual*/ BOOL setInfo(const LLTexLayerInfo *info, LLWearable* wearable); // This sets mInfo and calls initialization functions
+ /*virtual*/ BOOL render(S32 x, S32 y, S32 width, S32 height);
+
+ /*virtual*/ void deleteCaches();
+ const U8* getAlphaData() const;
+
+ BOOL findNetColor(LLColor4* color) const;
+ /*virtual*/ BOOL blendAlphaTexture(S32 x, S32 y, S32 width, S32 height); // Multiplies a single alpha texture against the frame buffer
+ /*virtual*/ void gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height);
+ void renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLColor4 &layer_color, bool force_render);
+ void addAlphaMask(U8 *data, S32 originX, S32 originY, S32 width, S32 height);
+ /*virtual*/ BOOL isInvisibleAlphaMask() const;
+
+ void setLTO(LLLocalTextureObject *lto) { mLocalTextureObject = lto; }
+ LLLocalTextureObject* getLTO() { return mLocalTextureObject; }
+
+ /*virtual*/ void asLLSD(LLSD& sd) const;
+
+ static void calculateTexLayerColor(const param_color_list_t &param_list, LLColor4 &net_color);
+protected:
+ LLUUID getUUID() const;
+ typedef std::map<U32, U8*> alpha_cache_t;
+ alpha_cache_t mAlphaCache;
+ LLLocalTextureObject* mLocalTextureObject;
+};
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// LLTexLayerSet
+//
+// An ordered set of texture layers that gets composited into a single texture.
+// Only exists for llvoavatarself.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+class LLTexLayerSet
+{
+ friend class LLTexLayerSetBuffer;
+public:
+ LLTexLayerSet(LLAvatarAppearance* const appearance);
+ virtual ~LLTexLayerSet();
+
+ LLTexLayerSetBuffer* getComposite();
+ const LLTexLayerSetBuffer* getComposite() const; // Do not create one if it doesn't exist.
+ virtual void createComposite() = 0;
+ void destroyComposite();
+ void gatherMorphMaskAlpha(U8 *data, S32 origin_x, S32 origin_y, S32 width, S32 height);
+
+ const LLTexLayerSetInfo* getInfo() const { return mInfo; }
+ BOOL setInfo(const LLTexLayerSetInfo *info); // This sets mInfo and calls initialization functions
+
+ BOOL render(S32 x, S32 y, S32 width, S32 height);
+ void renderAlphaMaskTextures(S32 x, S32 y, S32 width, S32 height, bool forceClear = false);
+
+ BOOL isBodyRegion(const std::string& region) const;
+ void applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_components);
+ BOOL isMorphValid() const;
+ virtual void requestUpdate() = 0;
+ void invalidateMorphMasks();
+ void deleteCaches();
+ LLTexLayerInterface* findLayerByName(const std::string& name);
+ void cloneTemplates(LLLocalTextureObject *lto, LLAvatarAppearanceDefines::ETextureIndex tex_index, LLWearable* wearable);
+
+ LLAvatarAppearance* getAvatarAppearance() const { return mAvatarAppearance; }
+ const std::string getBodyRegionName() const;
+ BOOL hasComposite() const { return (mComposite.notNull()); }
+ LLAvatarAppearanceDefines::EBakedTextureIndex getBakedTexIndex() const { return mBakedTexIndex; }
+ void setBakedTexIndex(LLAvatarAppearanceDefines::EBakedTextureIndex index) { mBakedTexIndex = index; }
+ BOOL isVisible() const { return mIsVisible; }
+
+ static BOOL sHasCaches;
+
+ virtual void asLLSD(LLSD& sd) const;
+
+protected:
+ typedef std::vector<LLTexLayerInterface *> layer_list_t;
+ layer_list_t mLayerList;
+ layer_list_t mMaskLayerList;
+ LLPointer<LLTexLayerSetBuffer> mComposite;
+ LLAvatarAppearance* const mAvatarAppearance; // note: backlink only; don't make this an LLPointer.
+ BOOL mIsVisible;
+
+ LLAvatarAppearanceDefines::EBakedTextureIndex mBakedTexIndex;
+ const LLTexLayerSetInfo* mInfo;
+};
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// LLTexLayerSetInfo
+//
+// Contains shared layer set data.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+class LLTexLayerSetInfo
+{
+ friend class LLTexLayerSet;
+public:
+ LLTexLayerSetInfo();
+ ~LLTexLayerSetInfo();
+ BOOL parseXml(LLXmlTreeNode* node);
+ void createVisualParams(LLAvatarAppearance *appearance);
+ S32 getWidth() const { return mWidth; }
+ S32 getHeight() const { return mHeight; }
+protected:
+ std::string mBodyRegion;
+ S32 mWidth;
+ S32 mHeight;
+ std::string mStaticAlphaFileName;
+ BOOL mClearAlpha; // Set alpha to 1 for this layerset (if there is no mStaticAlphaFileName)
+ typedef std::vector<LLTexLayerInfo*> layer_info_list_t;
+ layer_info_list_t mLayerInfoList;
+};
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// LLTexLayerSetBuffer
+//
+// The composite image that a LLTexLayerSet writes to. Each LLTexLayerSet has one.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+class LLTexLayerSetBuffer : public virtual LLRefCount
+{
+ LOG_CLASS(LLTexLayerSetBuffer);
+
+public:
+ LLTexLayerSetBuffer(LLTexLayerSet* const owner);
+ virtual ~LLTexLayerSetBuffer();
+
+protected:
+ void pushProjection() const;
+ void popProjection() const;
+ virtual void preRenderTexLayerSet();
+ virtual void midRenderTexLayerSet(BOOL success) {}
+ virtual void postRenderTexLayerSet(BOOL success);
+ virtual S32 getCompositeOriginX() const = 0;
+ virtual S32 getCompositeOriginY() const = 0;
+ virtual S32 getCompositeWidth() const = 0;
+ virtual S32 getCompositeHeight() const = 0;
+ BOOL renderTexLayerSet();
+
+ LLTexLayerSet* const mTexLayerSet;
+};
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// LLTexLayerStaticImageList
+//
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+class LLTexLayerStaticImageList : public LLSingleton<LLTexLayerStaticImageList>
+{
+public:
+ LLTexLayerStaticImageList();
+ ~LLTexLayerStaticImageList();
+ LLGLTexture* getTexture(const std::string& file_name, BOOL is_mask);
+ LLImageTGA* getImageTGA(const std::string& file_name);
+ void deleteCachedImages();
+ void dumpByteCount() const;
+protected:
+ BOOL loadImageRaw(const std::string& file_name, LLImageRaw* image_raw);
+private:
+ LLStringTable mImageNames;
+ typedef std::map<const char*, LLPointer<LLGLTexture> > texture_map_t;
+ texture_map_t mStaticImageList;
+ typedef std::map<const char*, LLPointer<LLImageTGA> > image_tga_map_t;
+ image_tga_map_t mStaticImageListTGA;
+ S32 mGLBytes;
+ S32 mTGABytes;
+};
+
+#endif // LL_LLTEXLAYER_H
diff --git a/indra/llappearance/lltexlayerparams.cpp b/indra/llappearance/lltexlayerparams.cpp
new file mode 100644
index 0000000000..6aae9a8cc1
--- /dev/null
+++ b/indra/llappearance/lltexlayerparams.cpp
@@ -0,0 +1,570 @@
+/**
+ * @file lltexlayerparams.cpp
+ * @brief Texture layer parameters
+ *
+ * $LicenseInfo:firstyear=2002&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 "lltexlayerparams.h"
+
+#include "llavatarappearance.h"
+#include "llimagetga.h"
+#include "llquantize.h"
+#include "lltexlayer.h"
+#include "lltexturemanagerbridge.h"
+#include "../llui/llui.h"
+#include "llwearable.h"
+
+//-----------------------------------------------------------------------------
+// LLTexLayerParam
+//-----------------------------------------------------------------------------
+LLTexLayerParam::LLTexLayerParam(LLTexLayerInterface *layer) :
+ mTexLayer(layer),
+ mAvatarAppearance(NULL)
+{
+ if (mTexLayer != NULL)
+ {
+ mAvatarAppearance = mTexLayer->getTexLayerSet()->getAvatarAppearance();
+ }
+ else
+ {
+ llerrs << "LLTexLayerParam constructor passed with NULL reference for layer!" << llendl;
+ }
+}
+
+LLTexLayerParam::LLTexLayerParam(LLAvatarAppearance *appearance) :
+ mTexLayer(NULL),
+ mAvatarAppearance(appearance)
+{
+}
+
+
+BOOL LLTexLayerParam::setInfo(LLViewerVisualParamInfo *info, BOOL add_to_appearance)
+{
+ LLViewerVisualParam::setInfo(info);
+
+ if (add_to_appearance)
+ {
+ mAvatarAppearance->addVisualParam( this);
+ this->setParamLocation(mAvatarAppearance->isSelf() ? LOC_AV_SELF : LOC_AV_OTHER);
+ }
+
+ return TRUE;
+}
+
+
+//-----------------------------------------------------------------------------
+// LLTexLayerParamAlpha
+//-----------------------------------------------------------------------------
+
+// static
+LLTexLayerParamAlpha::param_alpha_ptr_list_t LLTexLayerParamAlpha::sInstances;
+
+// static
+void LLTexLayerParamAlpha::dumpCacheByteCount()
+{
+ S32 gl_bytes = 0;
+ getCacheByteCount( &gl_bytes);
+ llinfos << "Processed Alpha Texture Cache GL:" << (gl_bytes/1024) << "KB" << llendl;
+}
+
+// static
+void LLTexLayerParamAlpha::getCacheByteCount(S32* gl_bytes)
+{
+ *gl_bytes = 0;
+
+ for (param_alpha_ptr_list_t::iterator iter = sInstances.begin();
+ iter != sInstances.end(); iter++)
+ {
+ LLTexLayerParamAlpha* instance = *iter;
+ LLGLTexture* tex = instance->mCachedProcessedTexture;
+ if (tex)
+ {
+ S32 bytes = (S32)tex->getWidth() * tex->getHeight() * tex->getComponents();
+
+ if (tex->hasGLTexture())
+ {
+ *gl_bytes += bytes;
+ }
+ }
+ }
+}
+
+LLTexLayerParamAlpha::LLTexLayerParamAlpha(LLTexLayerInterface* layer) :
+ LLTexLayerParam(layer),
+ mCachedProcessedTexture(NULL),
+ mNeedsCreateTexture(FALSE),
+ mStaticImageInvalid(FALSE),
+ mAvgDistortionVec(1.f, 1.f, 1.f),
+ mCachedEffectiveWeight(0.f)
+{
+ sInstances.push_front(this);
+}
+
+LLTexLayerParamAlpha::LLTexLayerParamAlpha(LLAvatarAppearance* appearance) :
+ LLTexLayerParam(appearance),
+ mCachedProcessedTexture(NULL),
+ mNeedsCreateTexture(FALSE),
+ mStaticImageInvalid(FALSE),
+ mAvgDistortionVec(1.f, 1.f, 1.f),
+ mCachedEffectiveWeight(0.f)
+{
+ sInstances.push_front(this);
+}
+
+
+LLTexLayerParamAlpha::~LLTexLayerParamAlpha()
+{
+ deleteCaches();
+ sInstances.remove(this);
+}
+
+/*virtual*/ LLViewerVisualParam* LLTexLayerParamAlpha::cloneParam(LLWearable* wearable) const
+{
+ LLTexLayerParamAlpha *new_param = new LLTexLayerParamAlpha(mTexLayer);
+ *new_param = *this;
+ return new_param;
+}
+
+void LLTexLayerParamAlpha::deleteCaches()
+{
+ mStaticImageTGA = NULL; // deletes image
+ mCachedProcessedTexture = NULL;
+ mStaticImageRaw = NULL;
+ mNeedsCreateTexture = FALSE;
+}
+
+BOOL LLTexLayerParamAlpha::getMultiplyBlend() const
+{
+ return ((LLTexLayerParamAlphaInfo *)getInfo())->mMultiplyBlend;
+}
+
+void LLTexLayerParamAlpha::setWeight(F32 weight, BOOL upload_bake)
+{
+ if (mIsAnimating || mTexLayer == NULL)
+ {
+ return;
+ }
+ F32 min_weight = getMinWeight();
+ F32 max_weight = getMaxWeight();
+ F32 new_weight = llclamp(weight, min_weight, max_weight);
+ U8 cur_u8 = F32_to_U8(mCurWeight, min_weight, max_weight);
+ U8 new_u8 = F32_to_U8(new_weight, min_weight, max_weight);
+ if (cur_u8 != new_u8)
+ {
+ mCurWeight = new_weight;
+
+ if ((mAvatarAppearance->getSex() & getSex()) &&
+ (mAvatarAppearance->isSelf() && !mIsDummy)) // only trigger a baked texture update if we're changing a wearable's visual param.
+ {
+ mAvatarAppearance->invalidateComposite(mTexLayer->getTexLayerSet(), upload_bake);
+ mTexLayer->invalidateMorphMasks();
+ }
+ }
+}
+
+void LLTexLayerParamAlpha::setAnimationTarget(F32 target_value, BOOL upload_bake)
+{
+ // do not animate dummy parameters
+ if (mIsDummy)
+ {
+ setWeight(target_value, upload_bake);
+ return;
+ }
+
+ mTargetWeight = target_value;
+ setWeight(target_value, upload_bake);
+ mIsAnimating = TRUE;
+ if (mNext)
+ {
+ mNext->setAnimationTarget(target_value, upload_bake);
+ }
+}
+
+void LLTexLayerParamAlpha::animate(F32 delta, BOOL upload_bake)
+{
+ if (mNext)
+ {
+ mNext->animate(delta, upload_bake);
+ }
+}
+
+BOOL LLTexLayerParamAlpha::getSkip() const
+{
+ if (!mTexLayer)
+ {
+ return TRUE;
+ }
+
+ const LLAvatarAppearance *appearance = mTexLayer->getTexLayerSet()->getAvatarAppearance();
+
+ if (((LLTexLayerParamAlphaInfo *)getInfo())->mSkipIfZeroWeight)
+ {
+ F32 effective_weight = (appearance->getSex() & getSex()) ? mCurWeight : getDefaultWeight();
+ if (is_approx_zero(effective_weight))
+ {
+ return TRUE;
+ }
+ }
+
+ LLWearableType::EType type = (LLWearableType::EType)getWearableType();
+ if ((type != LLWearableType::WT_INVALID) && !appearance->isWearingWearableType(type))
+ {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+static LLFastTimer::DeclareTimer FTM_TEX_LAYER_PARAM_ALPHA("alpha render");
+BOOL LLTexLayerParamAlpha::render(S32 x, S32 y, S32 width, S32 height)
+{
+ LLFastTimer t(FTM_TEX_LAYER_PARAM_ALPHA);
+ BOOL success = TRUE;
+
+ if (!mTexLayer)
+ {
+ return success;
+ }
+
+ F32 effective_weight = (mTexLayer->getTexLayerSet()->getAvatarAppearance()->getSex() & getSex()) ? mCurWeight : getDefaultWeight();
+ BOOL weight_changed = effective_weight != mCachedEffectiveWeight;
+ if (getSkip())
+ {
+ return success;
+ }
+
+ LLTexLayerParamAlphaInfo *info = (LLTexLayerParamAlphaInfo *)getInfo();
+ gGL.flush();
+ if (info->mMultiplyBlend)
+ {
+ gGL.blendFunc(LLRender::BF_DEST_ALPHA, LLRender::BF_ZERO); // Multiplication: approximates a min() function
+ }
+ else
+ {
+ gGL.setSceneBlendType(LLRender::BT_ADD); // Addition: approximates a max() function
+ }
+
+ if (!info->mStaticImageFileName.empty() && !mStaticImageInvalid)
+ {
+ if (mStaticImageTGA.isNull())
+ {
+ // Don't load the image file until we actually need it the first time. Like now.
+ mStaticImageTGA = LLTexLayerStaticImageList::getInstance()->getImageTGA(info->mStaticImageFileName);
+ // We now have something in one of our caches
+ LLTexLayerSet::sHasCaches |= mStaticImageTGA.notNull() ? TRUE : FALSE;
+
+ if (mStaticImageTGA.isNull())
+ {
+ llwarns << "Unable to load static file: " << info->mStaticImageFileName << llendl;
+ mStaticImageInvalid = TRUE; // don't try again.
+ return FALSE;
+ }
+ }
+
+ const S32 image_tga_width = mStaticImageTGA->getWidth();
+ const S32 image_tga_height = mStaticImageTGA->getHeight();
+ if (!mCachedProcessedTexture ||
+ (mCachedProcessedTexture->getWidth() != image_tga_width) ||
+ (mCachedProcessedTexture->getHeight() != image_tga_height) ||
+ (weight_changed))
+ {
+ mCachedEffectiveWeight = effective_weight;
+
+ if (!mCachedProcessedTexture)
+ {
+ llassert(gTextureManagerBridgep);
+ mCachedProcessedTexture = gTextureManagerBridgep->getLocalTexture(image_tga_width, image_tga_height, 1, FALSE);
+
+ // We now have something in one of our caches
+ LLTexLayerSet::sHasCaches |= mCachedProcessedTexture ? TRUE : FALSE;
+
+ mCachedProcessedTexture->setExplicitFormat(GL_ALPHA8, GL_ALPHA);
+ }
+
+ // Applies domain and effective weight to data as it is decoded. Also resizes the raw image if needed.
+ mStaticImageRaw = NULL;
+ mStaticImageRaw = new LLImageRaw;
+ mStaticImageTGA->decodeAndProcess(mStaticImageRaw, info->mDomain, effective_weight);
+ mNeedsCreateTexture = TRUE;
+ lldebugs << "Built Cached Alpha: " << info->mStaticImageFileName << ": (" << mStaticImageRaw->getWidth() << ", " << mStaticImageRaw->getHeight() << ") " << "Domain: " << info->mDomain << " Weight: " << effective_weight << llendl;
+ }
+
+ if (mCachedProcessedTexture)
+ {
+ {
+ // Create the GL texture, and then hang onto it for future use.
+ if (mNeedsCreateTexture)
+ {
+ mCachedProcessedTexture->createGLTexture(0, mStaticImageRaw);
+ mNeedsCreateTexture = FALSE;
+ gGL.getTexUnit(0)->bind(mCachedProcessedTexture);
+ mCachedProcessedTexture->setAddressMode(LLTexUnit::TAM_CLAMP);
+ }
+
+ LLGLSNoAlphaTest gls_no_alpha_test;
+ gGL.getTexUnit(0)->bind(mCachedProcessedTexture);
+ gl_rect_2d_simple_tex(width, height);
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ stop_glerror();
+ }
+ }
+
+ // Don't keep the cache for other people's avatars
+ // (It's not really a "cache" in that case, but the logic is the same)
+ if (!mAvatarAppearance->isSelf())
+ {
+ mCachedProcessedTexture = NULL;
+ }
+ }
+ else
+ {
+ LLGLDisable no_alpha(GL_ALPHA_TEST);
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.color4f(0.f, 0.f, 0.f, effective_weight);
+ gl_rect_2d_simple(width, height);
+ }
+
+ return success;
+}
+
+//-----------------------------------------------------------------------------
+// LLTexLayerParamAlphaInfo
+//-----------------------------------------------------------------------------
+LLTexLayerParamAlphaInfo::LLTexLayerParamAlphaInfo() :
+ mMultiplyBlend(FALSE),
+ mSkipIfZeroWeight(FALSE),
+ mDomain(0.f)
+{
+}
+
+BOOL LLTexLayerParamAlphaInfo::parseXml(LLXmlTreeNode* node)
+{
+ llassert(node->hasName("param") && node->getChildByName("param_alpha"));
+
+ if (!LLViewerVisualParamInfo::parseXml(node))
+ return FALSE;
+
+ LLXmlTreeNode* param_alpha_node = node->getChildByName("param_alpha");
+ if (!param_alpha_node)
+ {
+ return FALSE;
+ }
+
+ static LLStdStringHandle tga_file_string = LLXmlTree::addAttributeString("tga_file");
+ if (param_alpha_node->getFastAttributeString(tga_file_string, mStaticImageFileName))
+ {
+ // Don't load the image file until it's actually needed.
+ }
+// else
+// {
+// llwarns << "<param_alpha> element is missing tga_file attribute." << llendl;
+// }
+
+ static LLStdStringHandle multiply_blend_string = LLXmlTree::addAttributeString("multiply_blend");
+ param_alpha_node->getFastAttributeBOOL(multiply_blend_string, mMultiplyBlend);
+
+ static LLStdStringHandle skip_if_zero_string = LLXmlTree::addAttributeString("skip_if_zero");
+ param_alpha_node->getFastAttributeBOOL(skip_if_zero_string, mSkipIfZeroWeight);
+
+ static LLStdStringHandle domain_string = LLXmlTree::addAttributeString("domain");
+ param_alpha_node->getFastAttributeF32(domain_string, mDomain);
+
+ return TRUE;
+}
+
+
+
+
+LLTexLayerParamColor::LLTexLayerParamColor(LLTexLayerInterface* layer) :
+ LLTexLayerParam(layer),
+ mAvgDistortionVec(1.f, 1.f, 1.f)
+{
+}
+
+LLTexLayerParamColor::LLTexLayerParamColor(LLAvatarAppearance *appearance) :
+ LLTexLayerParam(appearance),
+ mAvgDistortionVec(1.f, 1.f, 1.f)
+{
+}
+
+LLTexLayerParamColor::~LLTexLayerParamColor()
+{
+}
+
+/*virtual*/ LLViewerVisualParam* LLTexLayerParamColor::cloneParam(LLWearable* wearable) const
+{
+ LLTexLayerParamColor *new_param = new LLTexLayerParamColor(mTexLayer);
+ *new_param = *this;
+ return new_param;
+}
+
+LLColor4 LLTexLayerParamColor::getNetColor() const
+{
+ const LLTexLayerParamColorInfo *info = (LLTexLayerParamColorInfo *)getInfo();
+
+ llassert(info->mNumColors >= 1);
+
+ F32 effective_weight = (mAvatarAppearance && (mAvatarAppearance->getSex() & getSex())) ? mCurWeight : getDefaultWeight();
+
+ S32 index_last = info->mNumColors - 1;
+ F32 scaled_weight = effective_weight * index_last;
+ S32 index_start = (S32) scaled_weight;
+ S32 index_end = index_start + 1;
+ if (index_start == index_last)
+ {
+ return info->mColors[index_last];
+ }
+ else
+ {
+ F32 weight = scaled_weight - index_start;
+ const LLColor4 *start = &info->mColors[ index_start ];
+ const LLColor4 *end = &info->mColors[ index_end ];
+ return LLColor4((1.f - weight) * start->mV[VX] + weight * end->mV[VX],
+ (1.f - weight) * start->mV[VY] + weight * end->mV[VY],
+ (1.f - weight) * start->mV[VZ] + weight * end->mV[VZ],
+ (1.f - weight) * start->mV[VW] + weight * end->mV[VW]);
+ }
+}
+
+void LLTexLayerParamColor::setWeight(F32 weight, BOOL upload_bake)
+{
+ if (mIsAnimating)
+ {
+ return;
+ }
+
+ const LLTexLayerParamColorInfo *info = (LLTexLayerParamColorInfo *)getInfo();
+ F32 min_weight = getMinWeight();
+ F32 max_weight = getMaxWeight();
+ F32 new_weight = llclamp(weight, min_weight, max_weight);
+ U8 cur_u8 = F32_to_U8(mCurWeight, min_weight, max_weight);
+ U8 new_u8 = F32_to_U8(new_weight, min_weight, max_weight);
+ if (cur_u8 != new_u8)
+ {
+ mCurWeight = new_weight;
+
+ if (info->mNumColors <= 0)
+ {
+ // This will happen when we set the default weight the first time.
+ return;
+ }
+
+ if ((mAvatarAppearance->getSex() & getSex()) && (mAvatarAppearance->isSelf() && !mIsDummy)) // only trigger a baked texture update if we're changing a wearable's visual param.
+ {
+ onGlobalColorChanged(upload_bake);
+ if (mTexLayer)
+ {
+ mAvatarAppearance->invalidateComposite(mTexLayer->getTexLayerSet(), upload_bake);
+ }
+ }
+
+// llinfos << "param " << mName << " = " << new_weight << llendl;
+ }
+}
+
+void LLTexLayerParamColor::setAnimationTarget(F32 target_value, BOOL upload_bake)
+{
+ // set value first then set interpolating flag to ignore further updates
+ mTargetWeight = target_value;
+ setWeight(target_value, upload_bake);
+ mIsAnimating = TRUE;
+ if (mNext)
+ {
+ mNext->setAnimationTarget(target_value, upload_bake);
+ }
+}
+
+void LLTexLayerParamColor::animate(F32 delta, BOOL upload_bake)
+{
+ if (mNext)
+ {
+ mNext->animate(delta, upload_bake);
+ }
+}
+
+//-----------------------------------------------------------------------------
+// LLTexLayerParamColorInfo
+//-----------------------------------------------------------------------------
+LLTexLayerParamColorInfo::LLTexLayerParamColorInfo() :
+ mOperation(LLTexLayerParamColor::OP_ADD),
+ mNumColors(0)
+{
+}
+
+BOOL LLTexLayerParamColorInfo::parseXml(LLXmlTreeNode *node)
+{
+ llassert(node->hasName("param") && node->getChildByName("param_color"));
+
+ if (!LLViewerVisualParamInfo::parseXml(node))
+ return FALSE;
+
+ LLXmlTreeNode* param_color_node = node->getChildByName("param_color");
+ if (!param_color_node)
+ {
+ return FALSE;
+ }
+
+ std::string op_string;
+ static LLStdStringHandle operation_string = LLXmlTree::addAttributeString("operation");
+ if (param_color_node->getFastAttributeString(operation_string, op_string))
+ {
+ LLStringUtil::toLower(op_string);
+ if (op_string == "add") mOperation = LLTexLayerParamColor::OP_ADD;
+ else if (op_string == "multiply") mOperation = LLTexLayerParamColor::OP_MULTIPLY;
+ else if (op_string == "blend") mOperation = LLTexLayerParamColor::OP_BLEND;
+ }
+
+ mNumColors = 0;
+
+ LLColor4U color4u;
+ for (LLXmlTreeNode* child = param_color_node->getChildByName("value");
+ child;
+ child = param_color_node->getNextNamedChild())
+ {
+ if ((mNumColors < MAX_COLOR_VALUES))
+ {
+ static LLStdStringHandle color_string = LLXmlTree::addAttributeString("color");
+ if (child->getFastAttributeColor4U(color_string, color4u))
+ {
+ mColors[ mNumColors ].setVec(color4u);
+ mNumColors++;
+ }
+ }
+ }
+ if (!mNumColors)
+ {
+ llwarns << "<param_color> is missing <value> sub-elements" << llendl;
+ return FALSE;
+ }
+
+ if ((mOperation == LLTexLayerParamColor::OP_BLEND) && (mNumColors != 1))
+ {
+ llwarns << "<param_color> with operation\"blend\" must have exactly one <value>" << llendl;
+ return FALSE;
+ }
+
+ return TRUE;
+}
diff --git a/indra/llappearance/lltexlayerparams.h b/indra/llappearance/lltexlayerparams.h
new file mode 100644
index 0000000000..b38d28d3eb
--- /dev/null
+++ b/indra/llappearance/lltexlayerparams.h
@@ -0,0 +1,219 @@
+/**
+ * @file lltexlayerparams.h
+ * @brief Texture layer parameters, used by lltexlayer.
+ *
+ * $LicenseInfo:firstyear=2002&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$
+ */
+
+#ifndef LL_LLTEXLAYERPARAMS_H
+#define LL_LLTEXLAYERPARAMS_H
+
+#include "llpointer.h"
+#include "v4color.h"
+#include "llviewervisualparam.h"
+
+class LLAvatarAppearance;
+class LLImageRaw;
+class LLImageTGA;
+class LLTexLayer;
+class LLTexLayerInterface;
+class LLGLTexture;
+class LLWearable;
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// LLTexLayerParam
+//
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+class LLTexLayerParam : public LLViewerVisualParam
+{
+public:
+ LLTexLayerParam(LLTexLayerInterface *layer);
+ LLTexLayerParam(LLAvatarAppearance *appearance);
+ /*virtual*/ BOOL setInfo(LLViewerVisualParamInfo *info, BOOL add_to_appearance);
+ /*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable) const = 0;
+
+protected:
+ LLTexLayerInterface* mTexLayer;
+ LLAvatarAppearance* mAvatarAppearance;
+};
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// LLTexLayerParamAlpha
+//
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL_ALIGN_PREFIX(16)
+class LLTexLayerParamAlpha : public LLTexLayerParam
+{
+public:
+ LLTexLayerParamAlpha( LLTexLayerInterface* layer );
+ LLTexLayerParamAlpha( LLAvatarAppearance* appearance );
+ /*virtual*/ ~LLTexLayerParamAlpha();
+
+ void* operator new(size_t size)
+ {
+ return ll_aligned_malloc_16(size);
+ }
+
+ void operator delete(void* ptr)
+ {
+ ll_aligned_free_16(ptr);
+ }
+
+ /*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable = NULL) const;
+
+ // LLVisualParam Virtual functions
+ ///*virtual*/ BOOL parseData(LLXmlTreeNode* node);
+ /*virtual*/ void apply( ESex avatar_sex ) {}
+ /*virtual*/ void setWeight(F32 weight, BOOL upload_bake);
+ /*virtual*/ void setAnimationTarget(F32 target_value, BOOL upload_bake);
+ /*virtual*/ void animate(F32 delta, BOOL upload_bake);
+
+ // LLViewerVisualParam Virtual functions
+ /*virtual*/ F32 getTotalDistortion() { return 1.f; }
+ /*virtual*/ const LLVector4a& getAvgDistortion() { return mAvgDistortionVec; }
+ /*virtual*/ F32 getMaxDistortion() { return 3.f; }
+ /*virtual*/ LLVector4a getVertexDistortion(S32 index, LLPolyMesh *poly_mesh) { return LLVector4a(1.f, 1.f, 1.f);}
+ /*virtual*/ const LLVector4a* getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh) { index = 0; poly_mesh = NULL; return &mAvgDistortionVec;};
+ /*virtual*/ const LLVector4a* getNextDistortion(U32 *index, LLPolyMesh **poly_mesh) { index = 0; poly_mesh = NULL; return NULL;};
+
+ // New functions
+ BOOL render( S32 x, S32 y, S32 width, S32 height );
+ BOOL getSkip() const;
+ void deleteCaches();
+ BOOL getMultiplyBlend() const;
+
+private:
+ LLPointer<LLGLTexture> mCachedProcessedTexture;
+ LLPointer<LLImageTGA> mStaticImageTGA;
+ LLPointer<LLImageRaw> mStaticImageRaw;
+ BOOL mNeedsCreateTexture;
+ BOOL mStaticImageInvalid;
+ LL_ALIGN_16(LLVector4a mAvgDistortionVec);
+ F32 mCachedEffectiveWeight;
+
+public:
+ // Global list of instances for gathering statistics
+ static void dumpCacheByteCount();
+ static void getCacheByteCount( S32* gl_bytes );
+
+ typedef std::list< LLTexLayerParamAlpha* > param_alpha_ptr_list_t;
+ static param_alpha_ptr_list_t sInstances;
+} LL_ALIGN_POSTFIX(16);
+class LLTexLayerParamAlphaInfo : public LLViewerVisualParamInfo
+{
+ friend class LLTexLayerParamAlpha;
+public:
+ LLTexLayerParamAlphaInfo();
+ /*virtual*/ ~LLTexLayerParamAlphaInfo() {};
+
+ /*virtual*/ BOOL parseXml(LLXmlTreeNode* node);
+
+private:
+ std::string mStaticImageFileName;
+ BOOL mMultiplyBlend;
+ BOOL mSkipIfZeroWeight;
+ F32 mDomain;
+};
+//
+// LLTexLayerParamAlpha
+//-----------------------------------------------------------------------------
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// LLTexLayerParamColor
+//
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+LL_ALIGN_PREFIX(16)
+class LLTexLayerParamColor : public LLTexLayerParam
+{
+public:
+ enum EColorOperation
+ {
+ OP_ADD = 0,
+ OP_MULTIPLY = 1,
+ OP_BLEND = 2,
+ OP_COUNT = 3 // Number of operations
+ };
+
+ LLTexLayerParamColor( LLTexLayerInterface* layer );
+ LLTexLayerParamColor( LLAvatarAppearance* appearance );
+
+ void* operator new(size_t size)
+ {
+ return ll_aligned_malloc_16(size);
+ }
+
+ void operator delete(void* ptr)
+ {
+ ll_aligned_free_16(ptr);
+ }
+
+ /* virtual */ ~LLTexLayerParamColor();
+
+ /*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable = NULL) const;
+
+ // LLVisualParam Virtual functions
+ ///*virtual*/ BOOL parseData(LLXmlTreeNode* node);
+ /*virtual*/ void apply( ESex avatar_sex ) {}
+ /*virtual*/ void setWeight(F32 weight, BOOL upload_bake);
+ /*virtual*/ void setAnimationTarget(F32 target_value, BOOL upload_bake);
+ /*virtual*/ void animate(F32 delta, BOOL upload_bake);
+
+
+ // LLViewerVisualParam Virtual functions
+ /*virtual*/ F32 getTotalDistortion() { return 1.f; }
+ /*virtual*/ const LLVector4a& getAvgDistortion() { return mAvgDistortionVec; }
+ /*virtual*/ F32 getMaxDistortion() { return 3.f; }
+ /*virtual*/ LLVector4a getVertexDistortion(S32 index, LLPolyMesh *poly_mesh) { return LLVector4a(1.f, 1.f, 1.f); }
+ /*virtual*/ const LLVector4a* getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh) { index = 0; poly_mesh = NULL; return &mAvgDistortionVec;};
+ /*virtual*/ const LLVector4a* getNextDistortion(U32 *index, LLPolyMesh **poly_mesh) { index = 0; poly_mesh = NULL; return NULL;};
+
+ // New functions
+ LLColor4 getNetColor() const;
+protected:
+ virtual void onGlobalColorChanged(bool upload_bake) {}
+private:
+ LL_ALIGN_16(LLVector4a mAvgDistortionVec);
+} LL_ALIGN_POSTFIX(16);
+
+class LLTexLayerParamColorInfo : public LLViewerVisualParamInfo
+{
+ friend class LLTexLayerParamColor;
+
+public:
+ LLTexLayerParamColorInfo();
+ virtual ~LLTexLayerParamColorInfo() {};
+ BOOL parseXml( LLXmlTreeNode* node );
+ LLTexLayerParamColor::EColorOperation getOperation() const { return mOperation; }
+private:
+ enum { MAX_COLOR_VALUES = 20 };
+ LLTexLayerParamColor::EColorOperation mOperation;
+ LLColor4 mColors[MAX_COLOR_VALUES];
+ S32 mNumColors;
+};
+
+typedef std::vector<LLTexLayerParamColor *> param_color_list_t;
+typedef std::vector<LLTexLayerParamAlpha *> param_alpha_list_t;
+typedef std::vector<LLTexLayerParamColorInfo *> param_color_info_list_t;
+typedef std::vector<LLTexLayerParamAlphaInfo *> param_alpha_info_list_t;
+
+#endif
diff --git a/indra/llappearance/lltexturemanagerbridge.cpp b/indra/llappearance/lltexturemanagerbridge.cpp
new file mode 100644
index 0000000000..33f2185e4f
--- /dev/null
+++ b/indra/llappearance/lltexturemanagerbridge.cpp
@@ -0,0 +1,32 @@
+ /**
+ * @file lltexturemanagerbridge.cpp
+ * @brief Defined a null texture manager bridge. Applications must provide their own bridge implementaton.
+ *
+ * $LicenseInfo:firstyear=2012&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 "lltexturemanagerbridge.h"
+
+// Define a null texture manager bridge. Applications must provide their own bridge implementaton.
+LLTextureManagerBridge* gTextureManagerBridgep = NULL;
+
+
diff --git a/indra/llappearance/lltexturemanagerbridge.h b/indra/llappearance/lltexturemanagerbridge.h
new file mode 100644
index 0000000000..4b814b522d
--- /dev/null
+++ b/indra/llappearance/lltexturemanagerbridge.h
@@ -0,0 +1,46 @@
+/**
+ * @file lltexturemanagerbridge.h
+ * @brief Bridge to an application-specific texture manager.
+ *
+ * $LicenseInfo:firstyear=2012&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$
+ */
+
+#ifndef LL_TEXTUREMANAGERBRIDGE_H
+#define LL_TEXTUREMANAGERBRIDGE_H
+
+#include "llavatarappearancedefines.h"
+#include "llpointer.h"
+#include "llgltexture.h"
+
+// Abstract bridge interface
+class LLTextureManagerBridge
+{
+public:
+ virtual LLPointer<LLGLTexture> getLocalTexture(BOOL usemipmaps = TRUE, BOOL generate_gl_tex = TRUE) = 0;
+ virtual LLPointer<LLGLTexture> getLocalTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps, BOOL generate_gl_tex = TRUE) = 0;
+ virtual LLGLTexture* getFetchedTexture(const LLUUID &image_id) = 0;
+};
+
+extern LLTextureManagerBridge* gTextureManagerBridgep;
+
+#endif // LL_TEXTUREMANAGERBRIDGE_H
+
diff --git a/indra/llappearance/llviewervisualparam.cpp b/indra/llappearance/llviewervisualparam.cpp
new file mode 100644
index 0000000000..cc81bcf118
--- /dev/null
+++ b/indra/llappearance/llviewervisualparam.cpp
@@ -0,0 +1,163 @@
+/**
+ * @file llviewervisualparam.cpp
+ * @brief Implementation of LLViewerVisualParam class
+ *
+ * $LicenseInfo:firstyear=2001&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$
+ */
+
+//-----------------------------------------------------------------------------
+// Header Files
+//-----------------------------------------------------------------------------
+#include "linden_common.h"
+
+#include "llviewervisualparam.h"
+#include "llxmltree.h"
+#include "llwearable.h"
+
+//-----------------------------------------------------------------------------
+// LLViewerVisualParamInfo()
+//-----------------------------------------------------------------------------
+LLViewerVisualParamInfo::LLViewerVisualParamInfo()
+ :
+ mWearableType( LLWearableType::WT_INVALID ),
+ mCrossWearable(FALSE),
+ mCamDist( 0.5f ),
+ mCamAngle( 0.f ),
+ mCamElevation( 0.f ),
+ mEditGroupDisplayOrder( 0 ),
+ mShowSimple(FALSE),
+ mSimpleMin(0.f),
+ mSimpleMax(100.f)
+{
+}
+
+LLViewerVisualParamInfo::~LLViewerVisualParamInfo()
+{
+}
+
+//-----------------------------------------------------------------------------
+// parseXml()
+//-----------------------------------------------------------------------------
+BOOL LLViewerVisualParamInfo::parseXml(LLXmlTreeNode *node)
+{
+ llassert( node->hasName( "param" ) );
+
+ if (!LLVisualParamInfo::parseXml(node))
+ return FALSE;
+
+ // VIEWER SPECIFIC PARAMS
+
+ std::string wearable;
+ static LLStdStringHandle wearable_string = LLXmlTree::addAttributeString("wearable");
+ if( node->getFastAttributeString( wearable_string, wearable) )
+ {
+ mWearableType = LLWearableType::typeNameToType( wearable );
+ }
+
+ static LLStdStringHandle edit_group_string = LLXmlTree::addAttributeString("edit_group");
+ if (!node->getFastAttributeString( edit_group_string, mEditGroup))
+ {
+ mEditGroup = "";
+ }
+
+ static LLStdStringHandle cross_wearable_string = LLXmlTree::addAttributeString("cross_wearable");
+ if (!node->getFastAttributeBOOL(cross_wearable_string, mCrossWearable))
+ {
+ mCrossWearable = FALSE;
+ }
+
+ // Optional camera offsets from the current joint center. Used for generating "hints" (thumbnails).
+ static LLStdStringHandle camera_distance_string = LLXmlTree::addAttributeString("camera_distance");
+ node->getFastAttributeF32( camera_distance_string, mCamDist );
+ static LLStdStringHandle camera_angle_string = LLXmlTree::addAttributeString("camera_angle");
+ node->getFastAttributeF32( camera_angle_string, mCamAngle ); // in degrees
+ static LLStdStringHandle camera_elevation_string = LLXmlTree::addAttributeString("camera_elevation");
+ node->getFastAttributeF32( camera_elevation_string, mCamElevation );
+
+ mCamAngle += 180;
+
+ static S32 params_loaded = 0;
+
+ // By default, parameters are displayed in the order in which they appear in the xml file.
+ // "edit_group_order" overriddes.
+ static LLStdStringHandle edit_group_order_string = LLXmlTree::addAttributeString("edit_group_order");
+ if( !node->getFastAttributeF32( edit_group_order_string, mEditGroupDisplayOrder ) )
+ {
+ mEditGroupDisplayOrder = (F32)params_loaded;
+ }
+
+ params_loaded++;
+
+ return TRUE;
+}
+
+/*virtual*/ void LLViewerVisualParamInfo::toStream(std::ostream &out)
+{
+ LLVisualParamInfo::toStream(out);
+
+ out << mWearableType << "\t";
+ out << mEditGroup << "\t";
+ out << mEditGroupDisplayOrder << "\t";
+}
+
+//-----------------------------------------------------------------------------
+// LLViewerVisualParam()
+//-----------------------------------------------------------------------------
+LLViewerVisualParam::LLViewerVisualParam()
+{
+}
+
+//-----------------------------------------------------------------------------
+// setInfo()
+//-----------------------------------------------------------------------------
+
+BOOL LLViewerVisualParam::setInfo(LLViewerVisualParamInfo *info)
+{
+ llassert(mInfo == NULL);
+ if (info->mID < 0)
+ return FALSE;
+ mInfo = info;
+ mID = info->mID;
+ setWeight(getDefaultWeight(), FALSE );
+ return TRUE;
+}
+
+/*
+//=============================================================================
+// These virtual functions should always be overridden,
+// but are included here for use as templates
+//=============================================================================
+
+//-----------------------------------------------------------------------------
+// parseData()
+//-----------------------------------------------------------------------------
+BOOL LLViewerVisualParam::parseData(LLXmlTreeNode *node)
+{
+ LLViewerVisualParamInfo* info = new LLViewerVisualParamInfo;
+
+ info->parseXml(node);
+ if (!setInfo(info))
+ return FALSE;
+
+ return TRUE;
+}
+*/
diff --git a/indra/llappearance/llviewervisualparam.h b/indra/llappearance/llviewervisualparam.h
new file mode 100644
index 0000000000..2826e6c316
--- /dev/null
+++ b/indra/llappearance/llviewervisualparam.h
@@ -0,0 +1,110 @@
+/**
+ * @file llviewervisualparam.h
+ * @brief viewer side visual params (with data file parsing)
+ *
+ * $LicenseInfo:firstyear=2001&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$
+ */
+
+#ifndef LL_LLViewerVisualParam_H
+#define LL_LLViewerVisualParam_H
+
+#include "v3math.h"
+#include "llstring.h"
+#include "llvisualparam.h"
+
+class LLWearable;
+
+//-----------------------------------------------------------------------------
+// LLViewerVisualParamInfo
+//-----------------------------------------------------------------------------
+class LLViewerVisualParamInfo : public LLVisualParamInfo
+{
+ friend class LLViewerVisualParam;
+public:
+ LLViewerVisualParamInfo();
+ /*virtual*/ ~LLViewerVisualParamInfo();
+
+ /*virtual*/ BOOL parseXml(LLXmlTreeNode* node);
+
+ /*virtual*/ void toStream(std::ostream &out);
+
+protected:
+ S32 mWearableType;
+ BOOL mCrossWearable;
+ std::string mEditGroup;
+ F32 mCamDist;
+ F32 mCamAngle; // degrees
+ F32 mCamElevation;
+ F32 mEditGroupDisplayOrder;
+ BOOL mShowSimple; // show edit controls when in "simple ui" mode?
+ F32 mSimpleMin; // when in simple UI, apply this minimum, range 0.f to 100.f
+ F32 mSimpleMax; // when in simple UI, apply this maximum, range 0.f to 100.f
+};
+
+//-----------------------------------------------------------------------------
+// LLViewerVisualParam
+// VIRTUAL CLASS
+// a viewer side interface class for a generalized parametric modification of the avatar mesh
+//-----------------------------------------------------------------------------
+LL_ALIGN_PREFIX(16)
+class LLViewerVisualParam : public LLVisualParam
+{
+public:
+ LLViewerVisualParam();
+ /*virtual*/ ~LLViewerVisualParam(){};
+
+ // Special: These functions are overridden by child classes
+ LLViewerVisualParamInfo *getInfo() const { return (LLViewerVisualParamInfo*)mInfo; };
+ // This sets mInfo and calls initialization functions
+ BOOL setInfo(LLViewerVisualParamInfo *info);
+
+ virtual LLViewerVisualParam* cloneParam(LLWearable* wearable) const = 0;
+
+ // LLVisualParam Virtual functions
+ ///*virtual*/ BOOL parseData(LLXmlTreeNode* node);
+
+ // New Virtual functions
+ virtual F32 getTotalDistortion() = 0;
+ virtual const LLVector4a& getAvgDistortion() = 0;
+ virtual F32 getMaxDistortion() = 0;
+ virtual LLVector4a getVertexDistortion(S32 index, LLPolyMesh *mesh) = 0;
+ virtual const LLVector4a* getFirstDistortion(U32 *index, LLPolyMesh **mesh) = 0;
+ virtual const LLVector4a* getNextDistortion(U32 *index, LLPolyMesh **mesh) = 0;
+
+ // interface methods
+ F32 getDisplayOrder() const { return getInfo()->mEditGroupDisplayOrder; }
+ S32 getWearableType() const { return getInfo()->mWearableType; }
+ const std::string& getEditGroup() const { return getInfo()->mEditGroup; }
+
+ F32 getCameraDistance() const { return getInfo()->mCamDist; }
+ F32 getCameraAngle() const { return getInfo()->mCamAngle; } // degrees
+ F32 getCameraElevation() const { return getInfo()->mCamElevation; }
+
+ BOOL getShowSimple() const { return getInfo()->mShowSimple; }
+ F32 getSimpleMin() const { return getInfo()->mSimpleMin; }
+ F32 getSimpleMax() const { return getInfo()->mSimpleMax; }
+
+ BOOL getCrossWearable() const { return getInfo()->mCrossWearable; }
+
+} LL_ALIGN_POSTFIX(16);
+
+#endif // LL_LLViewerVisualParam_H
diff --git a/indra/llappearance/llwearable.cpp b/indra/llappearance/llwearable.cpp
new file mode 100644
index 0000000000..d86a460511
--- /dev/null
+++ b/indra/llappearance/llwearable.cpp
@@ -0,0 +1,781 @@
+/**
+ * @file llwearable.cpp
+ * @brief LLWearable class implementation
+ *
+ * $LicenseInfo:firstyear=2002&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 "llavatarappearance.h"
+#include "lllocaltextureobject.h"
+#include "lltexlayer.h"
+#include "lltexturemanagerbridge.h"
+#include "llvisualparam.h"
+#include "llavatarappearancedefines.h"
+#include "llwearable.h"
+
+using namespace LLAvatarAppearanceDefines;
+
+// static
+S32 LLWearable::sCurrentDefinitionVersion = 1;
+
+// Private local functions
+static std::string terse_F32_to_string(F32 f);
+
+// virtual
+LLWearable::~LLWearable()
+{
+}
+
+const std::string& LLWearable::getTypeLabel() const
+{
+ return LLWearableType::getTypeLabel(mType);
+}
+
+const std::string& LLWearable::getTypeName() const
+{
+ return LLWearableType::getTypeName(mType);
+}
+
+LLAssetType::EType LLWearable::getAssetType() const
+{
+ return LLWearableType::getAssetType(mType);
+}
+
+BOOL LLWearable::exportFile(LLFILE* fp) const
+{
+ llofstream ofs(fp);
+ return exportStream(ofs);
+}
+
+// virtual
+BOOL LLWearable::exportStream( std::ostream& output_stream ) const
+{
+ if (!output_stream.good()) return FALSE;
+
+ // header and version
+ output_stream << "LLWearable version " << mDefinitionVersion << "\n";
+ // name
+ output_stream << mName << "\n";
+ // description
+ output_stream << mDescription << "\n";
+
+ // permissions
+ if( !mPermissions.exportLegacyStream( output_stream ) )
+ {
+ return FALSE;
+ }
+
+ // sale info
+ if( !mSaleInfo.exportLegacyStream( output_stream ) )
+ {
+ return FALSE;
+ }
+
+ // wearable type
+ output_stream << "type " << (S32) getType() << "\n";
+
+ // parameters
+ output_stream << "parameters " << mVisualParamIndexMap.size() << "\n";
+
+ for (visual_param_index_map_t::const_iterator iter = mVisualParamIndexMap.begin();
+ iter != mVisualParamIndexMap.end();
+ ++iter)
+ {
+ S32 param_id = iter->first;
+ const LLVisualParam* param = iter->second;
+ F32 param_weight = param->getWeight();
+ output_stream << param_id << " " << terse_F32_to_string( param_weight ) << "\n";
+ }
+
+ // texture entries
+ output_stream << "textures " << mTEMap.size() << "\n";
+
+ for (te_map_t::const_iterator iter = mTEMap.begin(); iter != mTEMap.end(); ++iter)
+ {
+ S32 te = iter->first;
+ const LLUUID& image_id = iter->second->getID();
+ output_stream << te << " " << image_id << "\n";
+ }
+ return TRUE;
+}
+
+void LLWearable::createVisualParams(LLAvatarAppearance *avatarp)
+{
+ for (LLViewerVisualParam* param = (LLViewerVisualParam*) avatarp->getFirstVisualParam();
+ param;
+ param = (LLViewerVisualParam*) avatarp->getNextVisualParam())
+ {
+ if (param->getWearableType() == mType)
+ {
+ LLVisualParam *clone_param = param->cloneParam(this);
+ clone_param->setParamLocation(LOC_UNKNOWN);
+ clone_param->setParamLocation(LOC_WEARABLE);
+ addVisualParam(clone_param);
+ }
+ }
+
+ // resync driver parameters to point to the newly cloned driven parameters
+ for (visual_param_index_map_t::iterator param_iter = mVisualParamIndexMap.begin();
+ param_iter != mVisualParamIndexMap.end();
+ ++param_iter)
+ {
+ LLVisualParam* param = param_iter->second;
+ LLVisualParam*(LLWearable::*wearable_function)(S32)const = &LLWearable::getVisualParam;
+ // need this line to disambiguate between versions of LLCharacter::getVisualParam()
+ LLVisualParam*(LLAvatarAppearance::*param_function)(S32)const = &LLAvatarAppearance::getVisualParam;
+ param->resetDrivenParams();
+ if(!param->linkDrivenParams(boost::bind(wearable_function,(LLWearable*)this, _1), false))
+ {
+ if( !param->linkDrivenParams(boost::bind(param_function,avatarp,_1 ), true))
+ {
+ llwarns << "could not link driven params for wearable " << getName() << " id: " << param->getID() << llendl;
+ continue;
+ }
+ }
+ }
+}
+
+void LLWearable::createLayers(S32 te, LLAvatarAppearance *avatarp)
+{
+ LLTexLayerSet *layer_set = NULL;
+ const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearanceDictionary::getInstance()->getTexture((ETextureIndex)te);
+ if (texture_dict->mIsUsedByBakedTexture)
+ {
+ const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex;
+
+ layer_set = avatarp->getAvatarLayerSet(baked_index);
+ }
+
+ if (layer_set)
+ {
+ layer_set->cloneTemplates(mTEMap[te], (ETextureIndex)te, this);
+ }
+ else
+ {
+ llerrs << "could not find layerset for LTO in wearable!" << llendl;
+ }
+}
+
+LLWearable::EImportResult LLWearable::importFile(LLFILE* fp, LLAvatarAppearance* avatarp )
+{
+ llifstream ifs(fp);
+ return importStream(ifs, avatarp);
+}
+
+// virtual
+LLWearable::EImportResult LLWearable::importStream( std::istream& input_stream, LLAvatarAppearance* avatarp )
+{
+ // *NOTE: changing the type or size of this buffer will require
+ // changes in the fscanf() code below.
+ // We are using a local max buffer size here to avoid issues
+ // if MAX_STRING size changes.
+ const U32 PARSE_BUFFER_SIZE = 2048;
+ char buffer[PARSE_BUFFER_SIZE]; /* Flawfinder: ignore */
+ char uuid_buffer[37]; /* Flawfinder: ignore */
+
+ // This data is being generated on the viewer.
+ // Impose some sane limits on parameter and texture counts.
+ const S32 MAX_WEARABLE_ASSET_TEXTURES = 100;
+ const S32 MAX_WEARABLE_ASSET_PARAMETERS = 1000;
+
+ if(!avatarp)
+ {
+ return LLWearable::FAILURE;
+ }
+
+ // read header and version
+ if (!getNextPopulatedLine(input_stream, buffer, PARSE_BUFFER_SIZE))
+ {
+ llwarns << "Failed to read wearable asset input stream." << llendl;
+ return LLWearable::FAILURE;
+ }
+ if ( 1 != sscanf( /* Flawfinder: ignore */
+ buffer,
+ "LLWearable version %d\n",
+ &mDefinitionVersion ) )
+ {
+ return LLWearable::BAD_HEADER;
+ }
+
+ // Hack to allow wearables with definition version 24 to still load.
+ // This should only affect lindens and NDA'd testers who have saved wearables in 2.0
+ // the extra check for version == 24 can be removed before release, once internal testers
+ // have loaded these wearables again. See hack pt 2 at bottom of function to ensure that
+ // these wearables get re-saved with version definition 22.
+ if( mDefinitionVersion > LLWearable::sCurrentDefinitionVersion && mDefinitionVersion != 24 )
+ {
+ llwarns << "Wearable asset has newer version (" << mDefinitionVersion << ") than XML (" << LLWearable::sCurrentDefinitionVersion << ")" << llendl;
+ return LLWearable::FAILURE;
+ }
+
+ // name may be empty
+ if (!input_stream.good())
+ {
+ llwarns << "Bad Wearable asset: early end of input stream "
+ << "while reading name" << llendl;
+ return LLWearable::FAILURE;
+ }
+ input_stream.getline(buffer, PARSE_BUFFER_SIZE);
+ mName = buffer;
+
+ // description may be empty
+ if (!input_stream.good())
+ {
+ llwarns << "Bad Wearable asset: early end of input stream "
+ << "while reading description" << llendl;
+ return LLWearable::FAILURE;
+ }
+ input_stream.getline(buffer, PARSE_BUFFER_SIZE);
+ mDescription = buffer;
+
+ // permissions may have extra empty lines before the correct line
+ if (!getNextPopulatedLine(input_stream, buffer, PARSE_BUFFER_SIZE))
+ {
+ llwarns << "Bad Wearable asset: early end of input stream "
+ << "while reading permissions" << llendl;
+ return LLWearable::FAILURE;
+ }
+ S32 perm_version = -1;
+ if ( 1 != sscanf( buffer, " permissions %d\n", &perm_version ) ||
+ perm_version != 0 )
+ {
+ llwarns << "Bad Wearable asset: missing valid permissions" << llendl;
+ return LLWearable::FAILURE;
+ }
+ if( !mPermissions.importLegacyStream( input_stream ) )
+ {
+ return LLWearable::FAILURE;
+ }
+
+ // sale info
+ if (!getNextPopulatedLine(input_stream, buffer, PARSE_BUFFER_SIZE))
+ {
+ llwarns << "Bad Wearable asset: early end of input stream "
+ << "while reading sale info" << llendl;
+ return LLWearable::FAILURE;
+ }
+ S32 sale_info_version = -1;
+ if ( 1 != sscanf( buffer, " sale_info %d\n", &sale_info_version ) ||
+ sale_info_version != 0 )
+ {
+ llwarns << "Bad Wearable asset: missing valid sale_info" << llendl;
+ return LLWearable::FAILURE;
+ }
+ // Sale info used to contain next owner perm. It is now in the
+ // permissions. Thus, we read that out, and fix legacy
+ // objects. It's possible this op would fail, but it should pick
+ // up the vast majority of the tasks.
+ BOOL has_perm_mask = FALSE;
+ U32 perm_mask = 0;
+ if( !mSaleInfo.importLegacyStream(input_stream, has_perm_mask, perm_mask) )
+ {
+ return LLWearable::FAILURE;
+ }
+ if(has_perm_mask)
+ {
+ // fair use fix.
+ if(!(perm_mask & PERM_COPY))
+ {
+ perm_mask |= PERM_TRANSFER;
+ }
+ mPermissions.setMaskNext(perm_mask);
+ }
+
+ // wearable type
+ if (!getNextPopulatedLine(input_stream, buffer, PARSE_BUFFER_SIZE))
+ {
+ llwarns << "Bad Wearable asset: early end of input stream "
+ << "while reading type" << llendl;
+ return LLWearable::FAILURE;
+ }
+ S32 type = -1;
+ if ( 1 != sscanf( buffer, "type %d\n", &type ) )
+ {
+ llwarns << "Bad Wearable asset: bad type" << llendl;
+ return LLWearable::FAILURE;
+ }
+ if( 0 <= type && type < LLWearableType::WT_COUNT )
+ {
+ setType((LLWearableType::EType)type, avatarp);
+ }
+ else
+ {
+ mType = LLWearableType::WT_COUNT;
+ llwarns << "Bad Wearable asset: bad type #" << type << llendl;
+ return LLWearable::FAILURE;
+ }
+
+ // parameters header
+ if (!getNextPopulatedLine(input_stream, buffer, PARSE_BUFFER_SIZE))
+ {
+ llwarns << "Bad Wearable asset: early end of input stream "
+ << "while reading parameters header" << llendl;
+ return LLWearable::FAILURE;
+ }
+ S32 num_parameters = -1;
+ if ( 1 != sscanf( buffer, "parameters %d\n", &num_parameters ) )
+ {
+ llwarns << "Bad Wearable asset: missing parameters block" << llendl;
+ return LLWearable::FAILURE;
+ }
+ if ( num_parameters > MAX_WEARABLE_ASSET_PARAMETERS )
+ {
+ llwarns << "Bad Wearable asset: too many parameters, "
+ << num_parameters << llendl;
+ return LLWearable::FAILURE;
+ }
+ if( num_parameters != mVisualParamIndexMap.size() )
+ {
+ llwarns << "Wearable parameter mismatch. Reading in "
+ << num_parameters << " from file, but created "
+ << mVisualParamIndexMap.size()
+ << " from avatar parameters. type: "
+ << getType() << llendl;
+ }
+
+ // parameters
+ S32 i;
+ for( i = 0; i < num_parameters; i++ )
+ {
+ if (!getNextPopulatedLine(input_stream, buffer, PARSE_BUFFER_SIZE))
+ {
+ llwarns << "Bad Wearable asset: early end of input stream "
+ << "while reading parameter #" << i << llendl;
+ return LLWearable::FAILURE;
+ }
+ S32 param_id = 0;
+ F32 param_weight = 0.f;
+ if ( 2 != sscanf( buffer, "%d %f\n", &param_id, &param_weight ) )
+ {
+ llwarns << "Bad Wearable asset: bad parameter, #" << i << llendl;
+ return LLWearable::FAILURE;
+ }
+ mSavedVisualParamMap[param_id] = param_weight;
+ }
+
+ // textures header
+ if (!getNextPopulatedLine(input_stream, buffer, PARSE_BUFFER_SIZE))
+ {
+ llwarns << "Bad Wearable asset: early end of input stream "
+ << "while reading textures header" << i << llendl;
+ return LLWearable::FAILURE;
+ }
+ S32 num_textures = -1;
+ if ( 1 != sscanf( buffer, "textures %d\n", &num_textures) )
+ {
+ llwarns << "Bad Wearable asset: missing textures block" << llendl;
+ return LLWearable::FAILURE;
+ }
+ if ( num_textures > MAX_WEARABLE_ASSET_TEXTURES )
+ {
+ llwarns << "Bad Wearable asset: too many textures, "
+ << num_textures << llendl;
+ return LLWearable::FAILURE;
+ }
+
+ // textures
+ for( i = 0; i < num_textures; i++ )
+ {
+ if (!getNextPopulatedLine(input_stream, buffer, PARSE_BUFFER_SIZE))
+ {
+ llwarns << "Bad Wearable asset: early end of input stream "
+ << "while reading textures #" << i << llendl;
+ return LLWearable::FAILURE;
+ }
+ S32 te = 0;
+ if ( 2 != sscanf( /* Flawfinder: ignore */
+ buffer,
+ "%d %36s\n",
+ &te, uuid_buffer) )
+ {
+ llwarns << "Bad Wearable asset: bad texture, #" << i << llendl;
+ return LLWearable::FAILURE;
+ }
+
+ if( !LLUUID::validate( uuid_buffer ) )
+ {
+ llwarns << "Bad Wearable asset: bad texture uuid: "
+ << uuid_buffer << llendl;
+ return LLWearable::FAILURE;
+ }
+ LLUUID id = LLUUID(uuid_buffer);
+ LLGLTexture* image = gTextureManagerBridgep->getFetchedTexture( id );
+ if( mTEMap.find(te) != mTEMap.end() )
+ {
+ delete mTEMap[te];
+ }
+ if( mSavedTEMap.find(te) != mSavedTEMap.end() )
+ {
+ delete mSavedTEMap[te];
+ }
+
+ LLUUID textureid(uuid_buffer);
+ mTEMap[te] = new LLLocalTextureObject(image, textureid);
+ mSavedTEMap[te] = new LLLocalTextureObject(image, textureid);
+ createLayers(te, avatarp);
+ }
+
+ // copy all saved param values to working params
+ revertValues();
+
+ return LLWearable::SUCCESS;
+}
+
+BOOL LLWearable::getNextPopulatedLine(std::istream& input_stream, char* buffer, U32 buffer_size)
+{
+ if (!input_stream.good())
+ {
+ return FALSE;
+ }
+
+ do
+ {
+ input_stream.getline(buffer, buffer_size);
+ }
+ while (input_stream.good() && buffer[0]=='\0');
+
+ return (buffer[0] != '\0');
+}
+
+
+void LLWearable::setType(LLWearableType::EType type, LLAvatarAppearance *avatarp)
+{
+ mType = type;
+ createVisualParams(avatarp);
+}
+
+
+LLLocalTextureObject* LLWearable::getLocalTextureObject(S32 index)
+{
+ te_map_t::iterator iter = mTEMap.find(index);
+ if( iter != mTEMap.end() )
+ {
+ LLLocalTextureObject* lto = iter->second;
+ return lto;
+ }
+ return NULL;
+}
+
+const LLLocalTextureObject* LLWearable::getLocalTextureObject(S32 index) const
+{
+ te_map_t::const_iterator iter = mTEMap.find(index);
+ if( iter != mTEMap.end() )
+ {
+ const LLLocalTextureObject* lto = iter->second;
+ return lto;
+ }
+ return NULL;
+}
+
+std::vector<LLLocalTextureObject*> LLWearable::getLocalTextureListSeq()
+{
+ std::vector<LLLocalTextureObject*> result;
+
+ for(te_map_t::const_iterator iter = mTEMap.begin();
+ iter != mTEMap.end(); iter++)
+ {
+ LLLocalTextureObject* lto = iter->second;
+ result.push_back(lto);
+ }
+
+ return result;
+}
+
+void LLWearable::setLocalTextureObject(S32 index, LLLocalTextureObject &lto)
+{
+ if( mTEMap.find(index) != mTEMap.end() )
+ {
+ mTEMap.erase(index);
+ }
+ mTEMap[index] = new LLLocalTextureObject(lto);
+}
+
+void LLWearable::revertValues()
+{
+ // FIXME DRANO - this triggers changes to driven params on avatar, potentially clobbering baked appearance.
+
+ //update saved settings so wearable is no longer dirty
+ // non-driver params first
+ for (param_map_t::const_iterator iter = mSavedVisualParamMap.begin(); iter != mSavedVisualParamMap.end(); iter++)
+ {
+ S32 id = iter->first;
+ F32 value = iter->second;
+ LLVisualParam *param = getVisualParam(id);
+ if(param && !dynamic_cast<LLDriverParam*>(param) )
+ {
+ setVisualParamWeight(id, value, TRUE);
+ }
+ }
+
+ //then driver params
+ for (param_map_t::const_iterator iter = mSavedVisualParamMap.begin(); iter != mSavedVisualParamMap.end(); iter++)
+ {
+ S32 id = iter->first;
+ F32 value = iter->second;
+ LLVisualParam *param = getVisualParam(id);
+ if(param && dynamic_cast<LLDriverParam*>(param) )
+ {
+ setVisualParamWeight(id, value, TRUE);
+ }
+ }
+
+ // make sure that saved values are sane
+ for (param_map_t::const_iterator iter = mSavedVisualParamMap.begin(); iter != mSavedVisualParamMap.end(); iter++)
+ {
+ S32 id = iter->first;
+ LLVisualParam *param = getVisualParam(id);
+ if( param )
+ {
+ mSavedVisualParamMap[id] = param->getWeight();
+ }
+ }
+
+ syncImages(mSavedTEMap, mTEMap);
+}
+
+void LLWearable::saveValues()
+{
+ //update saved settings so wearable is no longer dirty
+ mSavedVisualParamMap.clear();
+ for (visual_param_index_map_t::const_iterator iter = mVisualParamIndexMap.begin(); iter != mVisualParamIndexMap.end(); ++iter)
+ {
+ S32 id = iter->first;
+ LLVisualParam *wearable_param = iter->second;
+ F32 value = wearable_param->getWeight();
+ mSavedVisualParamMap[id] = value;
+ }
+
+ // Deep copy of mTEMap (copies only those tes that are current, filling in defaults where needed)
+ syncImages(mTEMap, mSavedTEMap);
+}
+
+void LLWearable::syncImages(te_map_t &src, te_map_t &dst)
+{
+ // Deep copy of src (copies only those tes that are current, filling in defaults where needed)
+ for( S32 te = 0; te < TEX_NUM_INDICES; te++ )
+ {
+ if (LLAvatarAppearanceDictionary::getTEWearableType((ETextureIndex) te) == mType)
+ {
+ te_map_t::const_iterator iter = src.find(te);
+ LLUUID image_id;
+ LLGLTexture *image = NULL;
+ LLLocalTextureObject *lto = NULL;
+ if(iter != src.end())
+ {
+ // there's a Local Texture Object in the source image map. Use this to populate the values to store in the destination image map.
+ lto = iter->second;
+ image = lto->getImage();
+ image_id = lto->getID();
+ }
+ else
+ {
+ // there is no Local Texture Object in the source image map. Get defaults values for populating the destination image map.
+ image_id = getDefaultTextureImageID((ETextureIndex) te);
+ image = gTextureManagerBridgep->getFetchedTexture( image_id );
+ }
+
+ if( dst.find(te) != dst.end() )
+ {
+ // there's already an entry in the destination map for the texture. Just update its values.
+ dst[te]->setImage(image);
+ dst[te]->setID(image_id);
+ }
+ else
+ {
+ // no entry found in the destination map, we need to create a new Local Texture Object
+ dst[te] = new LLLocalTextureObject(image, image_id);
+ }
+
+ if( lto )
+ {
+ // If we pulled values from a Local Texture Object in the source map, make sure the proper flags are set in the new (or updated) entry in the destination map.
+ dst[te]->setBakedReady(lto->getBakedReady());
+ dst[te]->setDiscard(lto->getDiscard());
+ }
+ }
+ }
+}
+
+void LLWearable::destroyTextures()
+{
+ for( te_map_t::iterator iter = mTEMap.begin(); iter != mTEMap.end(); ++iter )
+ {
+ LLLocalTextureObject *lto = iter->second;
+ delete lto;
+ }
+ mTEMap.clear();
+ for( te_map_t::iterator iter = mSavedTEMap.begin(); iter != mSavedTEMap.end(); ++iter )
+ {
+ LLLocalTextureObject *lto = iter->second;
+ delete lto;
+ }
+ mSavedTEMap.clear();
+}
+
+void LLWearable::addVisualParam(LLVisualParam *param)
+{
+ if( mVisualParamIndexMap[param->getID()] )
+ {
+ delete mVisualParamIndexMap[param->getID()];
+ }
+ param->setIsDummy(FALSE);
+ param->setParamLocation(LOC_WEARABLE);
+ mVisualParamIndexMap[param->getID()] = param;
+ mSavedVisualParamMap[param->getID()] = param->getDefaultWeight();
+}
+
+
+void LLWearable::setVisualParamWeight(S32 param_index, F32 value, BOOL upload_bake)
+{
+ if( is_in_map(mVisualParamIndexMap, param_index ) )
+ {
+ LLVisualParam *wearable_param = mVisualParamIndexMap[param_index];
+ wearable_param->setWeight(value, upload_bake);
+ }
+ else
+ {
+ llerrs << "LLWearable::setVisualParam passed invalid parameter index: " << param_index << " for wearable type: " << this->getName() << llendl;
+ }
+}
+
+F32 LLWearable::getVisualParamWeight(S32 param_index) const
+{
+ if( is_in_map(mVisualParamIndexMap, param_index ) )
+ {
+ const LLVisualParam *wearable_param = mVisualParamIndexMap.find(param_index)->second;
+ return wearable_param->getWeight();
+ }
+ else
+ {
+ llwarns << "LLWerable::getVisualParam passed invalid parameter index: " << param_index << " for wearable type: " << this->getName() << llendl;
+ }
+ return (F32)-1.0;
+}
+
+LLVisualParam* LLWearable::getVisualParam(S32 index) const
+{
+ visual_param_index_map_t::const_iterator iter = mVisualParamIndexMap.find(index);
+ return (iter == mVisualParamIndexMap.end()) ? NULL : iter->second;
+}
+
+
+void LLWearable::getVisualParams(visual_param_vec_t &list)
+{
+ visual_param_index_map_t::iterator iter = mVisualParamIndexMap.begin();
+ visual_param_index_map_t::iterator end = mVisualParamIndexMap.end();
+
+ // add all visual params to the passed-in vector
+ for( ; iter != end; ++iter )
+ {
+ list.push_back(iter->second);
+ }
+}
+
+void LLWearable::animateParams(F32 delta, BOOL upload_bake)
+{
+ for(visual_param_index_map_t::iterator iter = mVisualParamIndexMap.begin();
+ iter != mVisualParamIndexMap.end();
+ ++iter)
+ {
+ LLVisualParam *param = (LLVisualParam*) iter->second;
+ param->animate(delta, upload_bake);
+ }
+}
+
+LLColor4 LLWearable::getClothesColor(S32 te) const
+{
+ LLColor4 color;
+ U32 param_name[3];
+ if( LLAvatarAppearance::teToColorParams( (LLAvatarAppearanceDefines::ETextureIndex)te, param_name ) )
+ {
+ for( U8 index = 0; index < 3; index++ )
+ {
+ color.mV[index] = getVisualParamWeight(param_name[index]);
+ }
+ }
+ return color;
+}
+
+void LLWearable::setClothesColor( S32 te, const LLColor4& new_color, BOOL upload_bake )
+{
+ U32 param_name[3];
+ if( LLAvatarAppearance::teToColorParams( (LLAvatarAppearanceDefines::ETextureIndex)te, param_name ) )
+ {
+ for( U8 index = 0; index < 3; index++ )
+ {
+ setVisualParamWeight(param_name[index], new_color.mV[index], upload_bake);
+ }
+ }
+}
+
+void LLWearable::writeToAvatar(LLAvatarAppearance* avatarp)
+{
+ if (!avatarp) return;
+
+ // Pull params
+ for( LLVisualParam* param = avatarp->getFirstVisualParam(); param; param = avatarp->getNextVisualParam() )
+ {
+ // cross-wearable parameters are not authoritative, as they are driven by a different wearable. So don't copy the values to the
+ // avatar object if cross wearable. Cross wearable params get their values from the avatar, they shouldn't write the other way.
+ if( (((LLViewerVisualParam*)param)->getWearableType() == mType) && (!((LLViewerVisualParam*)param)->getCrossWearable()) )
+ {
+ S32 param_id = param->getID();
+ F32 weight = getVisualParamWeight(param_id);
+
+ avatarp->setVisualParamWeight( param_id, weight, FALSE );
+ }
+ }
+}
+
+
+std::string terse_F32_to_string(F32 f)
+{
+ std::string r = llformat("%.2f", f);
+ S32 len = r.length();
+
+ // "1.20" -> "1.2"
+ // "24.00" -> "24."
+ while (len > 0 && ('0' == r[len - 1]))
+ {
+ r.erase(len-1, 1);
+ len--;
+ }
+ if ('.' == r[len - 1])
+ {
+ // "24." -> "24"
+ r.erase(len-1, 1);
+ }
+ else if (('-' == r[0]) && ('0' == r[1]))
+ {
+ // "-0.59" -> "-.59"
+ r.erase(1, 1);
+ }
+ else if ('0' == r[0])
+ {
+ // "0.59" -> ".59"
+ r.erase(0, 1);
+ }
+ return r;
+}
+
diff --git a/indra/llappearance/llwearable.h b/indra/llappearance/llwearable.h
new file mode 100644
index 0000000000..6f5a1e14e8
--- /dev/null
+++ b/indra/llappearance/llwearable.h
@@ -0,0 +1,142 @@
+/**
+ * @file llwearable.h
+ * @brief LLWearable class header file
+ *
+ * $LicenseInfo:firstyear=2002&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$
+ */
+
+#ifndef LL_LLWEARABLE_H
+#define LL_LLWEARABLE_H
+
+#include "llavatarappearancedefines.h"
+#include "llextendedstatus.h"
+#include "llpermissions.h"
+#include "llsaleinfo.h"
+#include "llwearabletype.h"
+#include "lllocaltextureobject.h"
+
+class LLMD5;
+class LLVisualParam;
+class LLTexGlobalColorInfo;
+class LLTexGlobalColor;
+class LLAvatarAppearance;
+
+// Abstract class.
+class LLWearable
+{
+ //--------------------------------------------------------------------
+ // Constructors and destructors
+ //--------------------------------------------------------------------
+public:
+ virtual ~LLWearable();
+
+ //--------------------------------------------------------------------
+ // Accessors
+ //--------------------------------------------------------------------
+public:
+ LLWearableType::EType getType() const { return mType; }
+ void setType(LLWearableType::EType type, LLAvatarAppearance *avatarp);
+ const std::string& getName() const { return mName; }
+ void setName(const std::string& name) { mName = name; }
+ const std::string& getDescription() const { return mDescription; }
+ void setDescription(const std::string& desc) { mDescription = desc; }
+ const LLPermissions& getPermissions() const { return mPermissions; }
+ void setPermissions(const LLPermissions& p) { mPermissions = p; }
+ const LLSaleInfo& getSaleInfo() const { return mSaleInfo; }
+ void setSaleInfo(const LLSaleInfo& info) { mSaleInfo = info; }
+ const std::string& getTypeLabel() const;
+ const std::string& getTypeName() const;
+ LLAssetType::EType getAssetType() const;
+ S32 getDefinitionVersion() const { return mDefinitionVersion; }
+ void setDefinitionVersion( S32 new_version ) { mDefinitionVersion = new_version; }
+ static S32 getCurrentDefinitionVersion() { return LLWearable::sCurrentDefinitionVersion; }
+
+public:
+ typedef std::vector<LLVisualParam*> visual_param_vec_t;
+
+ virtual void writeToAvatar(LLAvatarAppearance* avatarp);
+
+ enum EImportResult
+ {
+ FAILURE = 0,
+ SUCCESS,
+ BAD_HEADER
+ };
+ BOOL exportFile(LLFILE* file) const;
+ EImportResult importFile(LLFILE* file, LLAvatarAppearance* avatarp );
+ virtual BOOL exportStream( std::ostream& output_stream ) const;
+ virtual EImportResult importStream( std::istream& input_stream, LLAvatarAppearance* avatarp );
+
+ static void setCurrentDefinitionVersion( S32 version ) { LLWearable::sCurrentDefinitionVersion = version; }
+ virtual LLUUID getDefaultTextureImageID(LLAvatarAppearanceDefines::ETextureIndex index) const = 0;
+
+ LLLocalTextureObject* getLocalTextureObject(S32 index);
+ const LLLocalTextureObject* getLocalTextureObject(S32 index) const;
+ std::vector<LLLocalTextureObject*> getLocalTextureListSeq();
+
+ void setLocalTextureObject(S32 index, LLLocalTextureObject &lto);
+ void addVisualParam(LLVisualParam *param);
+ void setVisualParamWeight(S32 index, F32 value, BOOL upload_bake);
+ F32 getVisualParamWeight(S32 index) const;
+ LLVisualParam* getVisualParam(S32 index) const;
+ void getVisualParams(visual_param_vec_t &list);
+ void animateParams(F32 delta, BOOL upload_bake);
+
+ LLColor4 getClothesColor(S32 te) const;
+ void setClothesColor( S32 te, const LLColor4& new_color, BOOL upload_bake );
+
+ virtual void revertValues();
+ virtual void saveValues();
+
+ // Something happened that requires the wearable to be updated (e.g. worn/unworn).
+ virtual void setUpdated() const = 0;
+
+ // Update the baked texture hash.
+ virtual void addToBakedTextureHash(LLMD5& hash) const = 0;
+
+protected:
+ typedef std::map<S32, LLLocalTextureObject*> te_map_t;
+ void syncImages(te_map_t &src, te_map_t &dst);
+ void destroyTextures();
+ void createVisualParams(LLAvatarAppearance *avatarp);
+ void createLayers(S32 te, LLAvatarAppearance *avatarp);
+ BOOL getNextPopulatedLine(std::istream& input_stream, char* buffer, U32 buffer_size);
+
+ static S32 sCurrentDefinitionVersion; // Depends on the current state of the avatar_lad.xml.
+ S32 mDefinitionVersion; // Depends on the state of the avatar_lad.xml when this asset was created.
+ std::string mName;
+ std::string mDescription;
+ LLPermissions mPermissions;
+ LLSaleInfo mSaleInfo;
+ LLWearableType::EType mType;
+
+ typedef std::map<S32, F32> param_map_t;
+ param_map_t mSavedVisualParamMap; // last saved version of visual params
+
+ typedef std::map<S32, LLVisualParam *> visual_param_index_map_t;
+ visual_param_index_map_t mVisualParamIndexMap;
+
+ te_map_t mTEMap; // maps TE to LocalTextureObject
+ te_map_t mSavedTEMap; // last saved version of TEMap
+};
+
+#endif // LL_LLWEARABLE_H
diff --git a/indra/llappearance/llwearabledata.cpp b/indra/llappearance/llwearabledata.cpp
new file mode 100644
index 0000000000..68fdcca782
--- /dev/null
+++ b/indra/llappearance/llwearabledata.cpp
@@ -0,0 +1,360 @@
+/**
+ * @file llwearabledata.cpp
+ * @brief LLWearableData class implementation
+ *
+ * $LicenseInfo:firstyear=2012&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 "llwearabledata.h"
+
+#include "llavatarappearance.h"
+#include "llavatarappearancedefines.h"
+#include "lldriverparam.h"
+#include "llmd5.h"
+
+LLWearableData::LLWearableData() :
+ mAvatarAppearance(NULL)
+{
+}
+
+// virtual
+LLWearableData::~LLWearableData()
+{
+}
+
+using namespace LLAvatarAppearanceDefines;
+
+LLWearable* LLWearableData::getWearable(const LLWearableType::EType type, U32 index)
+{
+ wearableentry_map_t::iterator wearable_iter = mWearableDatas.find(type);
+ if (wearable_iter == mWearableDatas.end())
+ {
+ return NULL;
+ }
+ wearableentry_vec_t& wearable_vec = wearable_iter->second;
+ if (index>=wearable_vec.size())
+ {
+ return NULL;
+ }
+ else
+ {
+ return wearable_vec[index];
+ }
+}
+
+void LLWearableData::setWearable(const LLWearableType::EType type, U32 index, LLWearable *wearable)
+{
+ LLWearable *old_wearable = getWearable(type,index);
+ if (!old_wearable)
+ {
+ pushWearable(type,wearable);
+ return;
+ }
+
+ wearableentry_map_t::iterator wearable_iter = mWearableDatas.find(type);
+ if (wearable_iter == mWearableDatas.end())
+ {
+ llwarns << "invalid type, type " << type << " index " << index << llendl;
+ return;
+ }
+ wearableentry_vec_t& wearable_vec = wearable_iter->second;
+ if (index>=wearable_vec.size())
+ {
+ llwarns << "invalid index, type " << type << " index " << index << llendl;
+ }
+ else
+ {
+ wearable_vec[index] = wearable;
+ old_wearable->setUpdated();
+ const BOOL removed = FALSE;
+ wearableUpdated(wearable, removed);
+ }
+}
+
+U32 LLWearableData::pushWearable(const LLWearableType::EType type,
+ LLWearable *wearable,
+ bool trigger_updated /* = true */)
+{
+ if (wearable == NULL)
+ {
+ // no null wearables please!
+ llwarns << "Null wearable sent for type " << type << llendl;
+ return MAX_CLOTHING_PER_TYPE;
+ }
+ if (type < LLWearableType::WT_COUNT || mWearableDatas[type].size() < MAX_CLOTHING_PER_TYPE)
+ {
+ mWearableDatas[type].push_back(wearable);
+ if (trigger_updated)
+ {
+ const BOOL removed = FALSE;
+ wearableUpdated(wearable, removed);
+ }
+ return mWearableDatas[type].size()-1;
+ }
+ return MAX_CLOTHING_PER_TYPE;
+}
+
+// virtual
+void LLWearableData::wearableUpdated(LLWearable *wearable, BOOL removed)
+{
+ wearable->setUpdated();
+ // FIXME DRANO avoid updating params via wearables when rendering server-baked appearance.
+#if 0
+ if (mAvatarAppearance->isUsingServerBakes() && !mAvatarAppearance->isUsingLocalAppearance())
+ {
+ return;
+ }
+#endif
+ if (!removed)
+ {
+ pullCrossWearableValues(wearable->getType());
+ }
+}
+
+void LLWearableData::popWearable(LLWearable *wearable)
+{
+ if (wearable == NULL)
+ {
+ // nothing to do here. move along.
+ return;
+ }
+
+ U32 index = getWearableIndex(wearable);
+ const LLWearableType::EType type = wearable->getType();
+
+ if (index < MAX_CLOTHING_PER_TYPE && index < getWearableCount(type))
+ {
+ popWearable(type, index);
+ }
+}
+
+void LLWearableData::popWearable(const LLWearableType::EType type, U32 index)
+{
+ LLWearable *wearable = getWearable(type, index);
+ if (wearable)
+ {
+ mWearableDatas[type].erase(mWearableDatas[type].begin() + index);
+ const BOOL removed = TRUE;
+ wearableUpdated(wearable, removed);
+ }
+}
+
+void LLWearableData::clearWearableType(const LLWearableType::EType type)
+{
+ wearableentry_map_t::iterator wearable_iter = mWearableDatas.find(type);
+ if (wearable_iter == mWearableDatas.end())
+ {
+ return;
+ }
+ wearableentry_vec_t& wearable_vec = wearable_iter->second;
+ wearable_vec.clear();
+}
+
+bool LLWearableData::swapWearables(const LLWearableType::EType type, U32 index_a, U32 index_b)
+{
+ wearableentry_map_t::iterator wearable_iter = mWearableDatas.find(type);
+ if (wearable_iter == mWearableDatas.end())
+ {
+ return false;
+ }
+
+ wearableentry_vec_t& wearable_vec = wearable_iter->second;
+ if (0 > index_a || index_a >= wearable_vec.size()) return false;
+ if (0 > index_b || index_b >= wearable_vec.size()) return false;
+
+ LLWearable* wearable = wearable_vec[index_a];
+ wearable_vec[index_a] = wearable_vec[index_b];
+ wearable_vec[index_b] = wearable;
+ return true;
+}
+
+void LLWearableData::pullCrossWearableValues(const LLWearableType::EType type)
+{
+ llassert(mAvatarAppearance);
+ // scan through all of the avatar's visual parameters
+ for (LLViewerVisualParam* param = (LLViewerVisualParam*) mAvatarAppearance->getFirstVisualParam();
+ param;
+ param = (LLViewerVisualParam*) mAvatarAppearance->getNextVisualParam())
+ {
+ if( param )
+ {
+ LLDriverParam *driver_param = dynamic_cast<LLDriverParam*>(param);
+ if(driver_param)
+ {
+ // parameter is a driver parameter, have it update its cross-driven params
+ driver_param->updateCrossDrivenParams(type);
+ }
+ }
+ }
+}
+
+
+U32 LLWearableData::getWearableIndex(const LLWearable *wearable) const
+{
+ if (wearable == NULL)
+ {
+ return MAX_CLOTHING_PER_TYPE;
+ }
+
+ const LLWearableType::EType type = wearable->getType();
+ wearableentry_map_t::const_iterator wearable_iter = mWearableDatas.find(type);
+ if (wearable_iter == mWearableDatas.end())
+ {
+ llwarns << "tried to get wearable index with an invalid type!" << llendl;
+ return MAX_CLOTHING_PER_TYPE;
+ }
+ const wearableentry_vec_t& wearable_vec = wearable_iter->second;
+ for(U32 index = 0; index < wearable_vec.size(); index++)
+ {
+ if (wearable_vec[index] == wearable)
+ {
+ return index;
+ }
+ }
+
+ return MAX_CLOTHING_PER_TYPE;
+}
+
+BOOL LLWearableData::isOnTop(LLWearable* wearable) const
+{
+ if (!wearable) return FALSE;
+ const LLWearableType::EType type = wearable->getType();
+ return ( getTopWearable(type) == wearable );
+}
+
+const LLWearable* LLWearableData::getWearable(const LLWearableType::EType type, U32 index) const
+{
+ wearableentry_map_t::const_iterator wearable_iter = mWearableDatas.find(type);
+ if (wearable_iter == mWearableDatas.end())
+ {
+ return NULL;
+ }
+ const wearableentry_vec_t& wearable_vec = wearable_iter->second;
+ if (index>=wearable_vec.size())
+ {
+ return NULL;
+ }
+ else
+ {
+ return wearable_vec[index];
+ }
+}
+
+LLWearable* LLWearableData::getTopWearable(const LLWearableType::EType type)
+{
+ U32 count = getWearableCount(type);
+ if ( count == 0)
+ {
+ return NULL;
+ }
+
+ return getWearable(type, count-1);
+}
+
+const LLWearable* LLWearableData::getTopWearable(const LLWearableType::EType type) const
+{
+ U32 count = getWearableCount(type);
+ if ( count == 0)
+ {
+ return NULL;
+ }
+
+ return getWearable(type, count-1);
+}
+
+LLWearable* LLWearableData::getBottomWearable(const LLWearableType::EType type)
+{
+ if (getWearableCount(type) == 0)
+ {
+ return NULL;
+ }
+
+ return getWearable(type, 0);
+}
+
+const LLWearable* LLWearableData::getBottomWearable(const LLWearableType::EType type) const
+{
+ if (getWearableCount(type) == 0)
+ {
+ return NULL;
+ }
+
+ return getWearable(type, 0);
+}
+
+U32 LLWearableData::getWearableCount(const LLWearableType::EType type) const
+{
+ wearableentry_map_t::const_iterator wearable_iter = mWearableDatas.find(type);
+ if (wearable_iter == mWearableDatas.end())
+ {
+ return 0;
+ }
+ const wearableentry_vec_t& wearable_vec = wearable_iter->second;
+ return wearable_vec.size();
+}
+
+U32 LLWearableData::getWearableCount(const U32 tex_index) const
+{
+ const LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getTEWearableType((LLAvatarAppearanceDefines::ETextureIndex)tex_index);
+ return getWearableCount(wearable_type);
+}
+
+LLUUID LLWearableData::computeBakedTextureHash(LLAvatarAppearanceDefines::EBakedTextureIndex baked_index,
+ BOOL generate_valid_hash) // Set to false if you want to upload the baked texture w/o putting it in the cache
+{
+ LLUUID hash_id;
+ bool hash_computed = false;
+ LLMD5 hash;
+ const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = LLAvatarAppearanceDictionary::getInstance()->getBakedTexture(baked_index);
+
+ for (U8 i=0; i < baked_dict->mWearables.size(); i++)
+ {
+ const LLWearableType::EType baked_type = baked_dict->mWearables[i];
+ const U32 num_wearables = getWearableCount(baked_type);
+ for (U32 index = 0; index < num_wearables; ++index)
+ {
+ const LLWearable* wearable = getWearable(baked_type,index);
+ if (wearable)
+ {
+ wearable->addToBakedTextureHash(hash);
+ hash_computed = true;
+ }
+ }
+ }
+ if (hash_computed)
+ {
+ hash.update((const unsigned char*)baked_dict->mWearablesHashID.mData, UUID_BYTES);
+
+ if (!generate_valid_hash)
+ {
+ invalidateBakedTextureHash(hash);
+ }
+ hash.finalize();
+ hash.raw_digest(hash_id.mData);
+ }
+
+ return hash_id;
+}
+
+
diff --git a/indra/llappearance/llwearabledata.h b/indra/llappearance/llwearabledata.h
new file mode 100644
index 0000000000..03bd179f25
--- /dev/null
+++ b/indra/llappearance/llwearabledata.h
@@ -0,0 +1,109 @@
+/**
+ * @file llwearabledata.h
+ * @brief LLWearableData class header file
+ *
+ * $LicenseInfo:firstyear=2012&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$
+ */
+
+#ifndef LL_WEARABLEDATA_H
+#define LL_WEARABLEDATA_H
+
+#include "llavatarappearancedefines.h"
+#include "llwearable.h"
+#include "llerror.h"
+
+class LLAvatarAppearance;
+
+class LLWearableData
+{
+ // *TODO: Figure out why this is causing compile error.
+ //LOG_CLASS(LLWearableData);
+
+ //--------------------------------------------------------------------
+ // Constructors / destructors / Initializers
+ //--------------------------------------------------------------------
+public:
+ LLWearableData();
+ virtual ~LLWearableData();
+
+ void setAvatarAppearance(LLAvatarAppearance* appearance) { mAvatarAppearance = appearance; }
+
+protected:
+ //--------------------------------------------------------------------
+ // Accessors
+ //--------------------------------------------------------------------
+public:
+ LLWearable* getWearable(const LLWearableType::EType type, U32 index /*= 0*/);
+ const LLWearable* getWearable(const LLWearableType::EType type, U32 index /*= 0*/) const;
+ LLWearable* getTopWearable(const LLWearableType::EType type);
+ const LLWearable* getTopWearable(const LLWearableType::EType type) const;
+ LLWearable* getBottomWearable(const LLWearableType::EType type);
+ const LLWearable* getBottomWearable(const LLWearableType::EType type) const;
+ U32 getWearableCount(const LLWearableType::EType type) const;
+ U32 getWearableCount(const U32 tex_index) const;
+ U32 getWearableIndex(const LLWearable *wearable) const;
+
+ BOOL isOnTop(LLWearable* wearable) const;
+
+ static const U32 MAX_CLOTHING_PER_TYPE = 5;
+
+ //--------------------------------------------------------------------
+ // Setters
+ //--------------------------------------------------------------------
+protected:
+ // Low-level data structure setter - public access is via setWearableItem, etc.
+ void setWearable(const LLWearableType::EType type, U32 index, LLWearable *wearable);
+ U32 pushWearable(const LLWearableType::EType type, LLWearable *wearable,
+ bool trigger_updated = true);
+ virtual void wearableUpdated(LLWearable *wearable, BOOL removed);
+ void popWearable(LLWearable *wearable);
+ void popWearable(const LLWearableType::EType type, U32 index);
+ void clearWearableType(const LLWearableType::EType type);
+ bool swapWearables(const LLWearableType::EType type, U32 index_a, U32 index_b);
+
+private:
+ void pullCrossWearableValues(const LLWearableType::EType type);
+
+ //--------------------------------------------------------------------
+ // Server Communication
+ //--------------------------------------------------------------------
+public:
+ LLUUID computeBakedTextureHash(LLAvatarAppearanceDefines::EBakedTextureIndex baked_index,
+ BOOL generate_valid_hash = TRUE);
+protected:
+ virtual void invalidateBakedTextureHash(LLMD5& hash) const {}
+
+ //--------------------------------------------------------------------
+ // Member variables
+ //--------------------------------------------------------------------
+protected:
+ LLAvatarAppearance* mAvatarAppearance;
+ typedef std::vector<LLWearable*> wearableentry_vec_t; // all wearables of a certain type (EG all shirts)
+ typedef std::map<LLWearableType::EType, wearableentry_vec_t> wearableentry_map_t; // wearable "categories" arranged by wearable type
+ wearableentry_map_t mWearableDatas;
+
+};
+
+
+
+#endif // LL_WEARABLEDATA_H
+
diff --git a/indra/llappearance/llwearabletype.cpp b/indra/llappearance/llwearabletype.cpp
new file mode 100644
index 0000000000..618e2a1941
--- /dev/null
+++ b/indra/llappearance/llwearabletype.cpp
@@ -0,0 +1,171 @@
+/**
+ * @file llwearabletype.cpp
+ * @brief LLWearableType class implementation
+ *
+ * $LicenseInfo:firstyear=2002&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 "llwearabletype.h"
+#include "llinventorytype.h"
+
+static LLTranslationBridge* sTrans = NULL;
+
+// static
+void LLWearableType::initClass(LLTranslationBridge* trans)
+{
+ sTrans = trans;
+}
+
+void LLWearableType::cleanupClass()
+{
+ delete sTrans;
+}
+
+struct WearableEntry : public LLDictionaryEntry
+{
+ WearableEntry(const std::string &name,
+ const std::string& default_new_name,
+ LLAssetType::EType assetType,
+ LLInventoryType::EIconName iconName,
+ BOOL disable_camera_switch = FALSE,
+ BOOL allow_multiwear = TRUE) :
+ LLDictionaryEntry(name),
+ mAssetType(assetType),
+ mDefaultNewName(default_new_name),
+ mLabel(sTrans->getString(name)),
+ mIconName(iconName),
+ mDisableCameraSwitch(disable_camera_switch),
+ mAllowMultiwear(allow_multiwear)
+ {
+
+ }
+ const LLAssetType::EType mAssetType;
+ const std::string mLabel;
+ const std::string mDefaultNewName; //keep mLabel for backward compatibility
+ LLInventoryType::EIconName mIconName;
+ BOOL mDisableCameraSwitch;
+ BOOL mAllowMultiwear;
+};
+
+class LLWearableDictionary : public LLSingleton<LLWearableDictionary>,
+ public LLDictionary<LLWearableType::EType, WearableEntry>
+{
+public:
+ LLWearableDictionary();
+};
+
+LLWearableDictionary::LLWearableDictionary()
+{
+ addEntry(LLWearableType::WT_SHAPE, new WearableEntry("shape", "New Shape", LLAssetType::AT_BODYPART, LLInventoryType::ICONNAME_BODYPART_SHAPE, FALSE, FALSE));
+ addEntry(LLWearableType::WT_SKIN, new WearableEntry("skin", "New Skin", LLAssetType::AT_BODYPART, LLInventoryType::ICONNAME_BODYPART_SKIN, FALSE, FALSE));
+ addEntry(LLWearableType::WT_HAIR, new WearableEntry("hair", "New Hair", LLAssetType::AT_BODYPART, LLInventoryType::ICONNAME_BODYPART_HAIR, FALSE, FALSE));
+ addEntry(LLWearableType::WT_EYES, new WearableEntry("eyes", "New Eyes", LLAssetType::AT_BODYPART, LLInventoryType::ICONNAME_BODYPART_EYES, FALSE, FALSE));
+ addEntry(LLWearableType::WT_SHIRT, new WearableEntry("shirt", "New Shirt", LLAssetType::AT_CLOTHING, LLInventoryType::ICONNAME_CLOTHING_SHIRT, FALSE, TRUE));
+ addEntry(LLWearableType::WT_PANTS, new WearableEntry("pants", "New Pants", LLAssetType::AT_CLOTHING, LLInventoryType::ICONNAME_CLOTHING_PANTS, FALSE, TRUE));
+ addEntry(LLWearableType::WT_SHOES, new WearableEntry("shoes", "New Shoes", LLAssetType::AT_CLOTHING, LLInventoryType::ICONNAME_CLOTHING_SHOES, FALSE, TRUE));
+ addEntry(LLWearableType::WT_SOCKS, new WearableEntry("socks", "New Socks", LLAssetType::AT_CLOTHING, LLInventoryType::ICONNAME_CLOTHING_SOCKS, FALSE, TRUE));
+ addEntry(LLWearableType::WT_JACKET, new WearableEntry("jacket", "New Jacket", LLAssetType::AT_CLOTHING, LLInventoryType::ICONNAME_CLOTHING_JACKET, FALSE, TRUE));
+ addEntry(LLWearableType::WT_GLOVES, new WearableEntry("gloves", "New Gloves", LLAssetType::AT_CLOTHING, LLInventoryType::ICONNAME_CLOTHING_GLOVES, FALSE, TRUE));
+ addEntry(LLWearableType::WT_UNDERSHIRT, new WearableEntry("undershirt", "New Undershirt", LLAssetType::AT_CLOTHING, LLInventoryType::ICONNAME_CLOTHING_UNDERSHIRT, FALSE, TRUE));
+ addEntry(LLWearableType::WT_UNDERPANTS, new WearableEntry("underpants", "New Underpants", LLAssetType::AT_CLOTHING, LLInventoryType::ICONNAME_CLOTHING_UNDERPANTS, FALSE, TRUE));
+ addEntry(LLWearableType::WT_SKIRT, new WearableEntry("skirt", "New Skirt", LLAssetType::AT_CLOTHING, LLInventoryType::ICONNAME_CLOTHING_SKIRT, FALSE, TRUE));
+ addEntry(LLWearableType::WT_ALPHA, new WearableEntry("alpha", "New Alpha", LLAssetType::AT_CLOTHING, LLInventoryType::ICONNAME_CLOTHING_ALPHA, FALSE, TRUE));
+ addEntry(LLWearableType::WT_TATTOO, new WearableEntry("tattoo", "New Tattoo", LLAssetType::AT_CLOTHING, LLInventoryType::ICONNAME_CLOTHING_TATTOO, FALSE, TRUE));
+
+ addEntry(LLWearableType::WT_PHYSICS, new WearableEntry("physics", "New Physics", LLAssetType::AT_CLOTHING, LLInventoryType::ICONNAME_CLOTHING_PHYSICS, TRUE, TRUE));
+
+ addEntry(LLWearableType::WT_INVALID, new WearableEntry("invalid", "Invalid Wearable", LLAssetType::AT_NONE, LLInventoryType::ICONNAME_NONE, FALSE, FALSE));
+ addEntry(LLWearableType::WT_NONE, new WearableEntry("none", "Invalid Wearable", LLAssetType::AT_NONE, LLInventoryType::ICONNAME_NONE, FALSE, FALSE));
+}
+
+// static
+LLWearableType::EType LLWearableType::typeNameToType(const std::string& type_name)
+{
+ const LLWearableDictionary *dict = LLWearableDictionary::getInstance();
+ const LLWearableType::EType wearable = dict->lookup(type_name);
+ return wearable;
+}
+
+// static
+const std::string& LLWearableType::getTypeName(LLWearableType::EType type)
+{
+ const LLWearableDictionary *dict = LLWearableDictionary::getInstance();
+ const WearableEntry *entry = dict->lookup(type);
+ if (!entry) return getTypeName(WT_INVALID);
+ return entry->mName;
+}
+
+//static
+const std::string& LLWearableType::getTypeDefaultNewName(LLWearableType::EType type)
+{
+ const LLWearableDictionary *dict = LLWearableDictionary::getInstance();
+ const WearableEntry *entry = dict->lookup(type);
+ if (!entry) return getTypeDefaultNewName(WT_INVALID);
+ return entry->mDefaultNewName;
+}
+
+// static
+const std::string& LLWearableType::getTypeLabel(LLWearableType::EType type)
+{
+ const LLWearableDictionary *dict = LLWearableDictionary::getInstance();
+ const WearableEntry *entry = dict->lookup(type);
+ if (!entry) return getTypeLabel(WT_INVALID);
+ return entry->mLabel;
+}
+
+// static
+LLAssetType::EType LLWearableType::getAssetType(LLWearableType::EType type)
+{
+ const LLWearableDictionary *dict = LLWearableDictionary::getInstance();
+ const WearableEntry *entry = dict->lookup(type);
+ if (!entry) return getAssetType(WT_INVALID);
+ return entry->mAssetType;
+}
+
+// static
+LLInventoryType::EIconName LLWearableType::getIconName(LLWearableType::EType type)
+{
+ const LLWearableDictionary *dict = LLWearableDictionary::getInstance();
+ const WearableEntry *entry = dict->lookup(type);
+ if (!entry) return getIconName(WT_INVALID);
+ return entry->mIconName;
+}
+
+// static
+BOOL LLWearableType::getDisableCameraSwitch(LLWearableType::EType type)
+{
+ const LLWearableDictionary *dict = LLWearableDictionary::getInstance();
+ const WearableEntry *entry = dict->lookup(type);
+ if (!entry) return FALSE;
+ return entry->mDisableCameraSwitch;
+}
+
+// static
+BOOL LLWearableType::getAllowMultiwear(LLWearableType::EType type)
+{
+ const LLWearableDictionary *dict = LLWearableDictionary::getInstance();
+ const WearableEntry *entry = dict->lookup(type);
+ if (!entry) return FALSE;
+ return entry->mAllowMultiwear;
+}
+
diff --git a/indra/llappearance/llwearabletype.h b/indra/llappearance/llwearabletype.h
new file mode 100644
index 0000000000..e51e6731d3
--- /dev/null
+++ b/indra/llappearance/llwearabletype.h
@@ -0,0 +1,86 @@
+/**
+ * @file llwearabletype.h
+ * @brief LLWearableType class header file
+ *
+ * $LicenseInfo:firstyear=2002&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$
+ */
+
+#ifndef LL_LLWEARABLETYPE_H
+#define LL_LLWEARABLETYPE_H
+
+#include "llassettype.h"
+#include "lldictionary.h"
+#include "llinventorytype.h"
+#include "llsingleton.h"
+
+class LLTranslationBridge
+{
+public:
+ virtual std::string getString(const std::string &xml_desc) = 0;
+};
+
+
+class LLWearableType
+{
+public:
+ enum EType
+ {
+ WT_SHAPE = 0,
+ WT_SKIN = 1,
+ WT_HAIR = 2,
+ WT_EYES = 3,
+ WT_SHIRT = 4,
+ WT_PANTS = 5,
+ WT_SHOES = 6,
+ WT_SOCKS = 7,
+ WT_JACKET = 8,
+ WT_GLOVES = 9,
+ WT_UNDERSHIRT = 10,
+ WT_UNDERPANTS = 11,
+ WT_SKIRT = 12,
+ WT_ALPHA = 13,
+ WT_TATTOO = 14,
+ WT_PHYSICS = 15,
+ WT_COUNT = 16,
+
+ WT_INVALID = 255,
+ WT_NONE = -1,
+ };
+
+ static void initClass(LLTranslationBridge* trans); // initializes static members
+ static void cleanupClass(); // initializes static members
+
+ static const std::string& getTypeName(EType type);
+ static const std::string& getTypeDefaultNewName(EType type);
+ static const std::string& getTypeLabel(EType type);
+ static LLAssetType::EType getAssetType(EType type);
+ static EType typeNameToType(const std::string& type_name);
+ static LLInventoryType::EIconName getIconName(EType type);
+ static BOOL getDisableCameraSwitch(EType type);
+ static BOOL getAllowMultiwear(EType type);
+
+protected:
+ LLWearableType() {}
+ ~LLWearableType() {}
+};
+
+#endif // LL_LLWEARABLETYPE_H
diff --git a/indra/llaudio/CMakeLists.txt b/indra/llaudio/CMakeLists.txt
index 632e5d46e3..1b2bdb9888 100644..100755
--- a/indra/llaudio/CMakeLists.txt
+++ b/indra/llaudio/CMakeLists.txt
@@ -5,7 +5,7 @@ project(llaudio)
include(00-Common)
include(Audio)
include(LLAudio)
-include(FMOD)
+include(FMODEX)
include(OPENAL)
include(LLCommon)
include(LLMath)
@@ -24,7 +24,6 @@ include_directories(
${VORBIS_INCLUDE_DIRS}
${OPENAL_LIB_INCLUDE_DIRS}
${FREEAULT_LIB_INCLUDE_DIRS}
- ${FMOD_INCLUDE_DIR}
)
set(llaudio_SOURCE_FILES
@@ -44,29 +43,22 @@ set(llaudio_HEADER_FILES
llwindgen.h
)
-if (FMOD)
+if (FMODEX)
include_directories(
- ${FMOD_INCLUDE_DIR}
+ ${FMODEX_INCLUDE_DIR}
)
-
list(APPEND llaudio_SOURCE_FILES
- llaudioengine_fmod.cpp
- lllistener_fmod.cpp
- llstreamingaudio_fmod.cpp
+ llaudioengine_fmodex.cpp
+ lllistener_fmodex.cpp
+ llstreamingaudio_fmodex.cpp
)
list(APPEND llaudio_HEADER_FILES
- llaudioengine_fmod.h
- lllistener_fmod.h
- llstreamingaudio_fmod.h
+ llaudioengine_fmodex.h
+ lllistener_fmodex.h
+ llstreamingaudio_fmodex.h
)
-
- if (LINUX OR DARWIN)
- set_source_files_properties(llaudioengine_fmod.cpp
- llstreamingaudio_fmod.cpp
- COMPILE_FLAGS -Wno-write-strings)
- endif (LINUX OR DARWIN)
-endif (FMOD)
+endif (FMODEX)
if (OPENAL)
list(APPEND llaudio_SOURCE_FILES
@@ -88,6 +80,10 @@ list(APPEND llaudio_SOURCE_FILES ${llaudio_HEADER_FILES})
add_library (llaudio ${llaudio_SOURCE_FILES})
target_link_libraries(
llaudio
+ ${LLCOMMON_LIBRARIES}
+ ${LLMATH_LIBRARIES}
+ ${LLMESSAGE_LIBRARIES}
+ ${LLVFS_LIBRARIES}
${VORBISENC_LIBRARIES}
${VORBISFILE_LIBRARIES}
${VORBIS_LIBRARIES}
diff --git a/indra/llaudio/llaudiodecodemgr.cpp b/indra/llaudio/llaudiodecodemgr.cpp
index 7f747c2eca..6c97a64ed7 100644..100755
--- a/indra/llaudio/llaudiodecodemgr.cpp
+++ b/indra/llaudio/llaudiodecodemgr.cpp
@@ -571,7 +571,8 @@ void LLAudioDecodeMgr::Impl::processQueue(const F32 num_secs)
llwarns << mCurrentDecodep->getUUID() << " has invalid vorbis data, aborting decode" << llendl;
mCurrentDecodep->flushBadFile();
LLAudioData *adp = gAudiop->getAudioData(mCurrentDecodep->getUUID());
- adp->setHasValidData(FALSE);
+ adp->setHasValidData(false);
+ adp->setHasCompletedDecode(true);
mCurrentDecodep = NULL;
done = TRUE;
}
@@ -586,11 +587,16 @@ void LLAudioDecodeMgr::Impl::processQueue(const F32 num_secs)
if (mCurrentDecodep->finishDecode())
{
// We finished!
- if (mCurrentDecodep->isValid() && mCurrentDecodep->isDone())
+ LLAudioData *adp = gAudiop->getAudioData(mCurrentDecodep->getUUID());
+ if (!adp)
{
- LLAudioData *adp = gAudiop->getAudioData(mCurrentDecodep->getUUID());
- adp->setHasDecodedData(TRUE);
- adp->setHasValidData(TRUE);
+ llwarns << "Missing LLAudioData for decode of " << mCurrentDecodep->getUUID() << llendl;
+ }
+ else if (mCurrentDecodep->isValid() && mCurrentDecodep->isDone())
+ {
+ adp->setHasCompletedDecode(true);
+ adp->setHasDecodedData(true);
+ adp->setHasValidData(true);
// At this point, we could see if anyone needs this sound immediately, but
// I'm not sure that there's a reason to - we need to poll all of the playing
@@ -599,7 +605,8 @@ void LLAudioDecodeMgr::Impl::processQueue(const F32 num_secs)
}
else
{
- llinfos << "Vorbis decode failed!!!" << llendl;
+ adp->setHasCompletedDecode(true);
+ llinfos << "Vorbis decode failed for " << mCurrentDecodep->getUUID() << llendl;
}
mCurrentDecodep = NULL;
}
@@ -667,16 +674,19 @@ BOOL LLAudioDecodeMgr::addDecodeRequest(const LLUUID &uuid)
if (gAudiop->hasDecodedFile(uuid))
{
// Already have a decoded version, don't need to decode it.
+ //llinfos << "addDecodeRequest for " << uuid << " has decoded file already" << llendl;
return TRUE;
}
if (gAssetStorage->hasLocalAsset(uuid, LLAssetType::AT_SOUND))
{
// Just put it on the decode queue.
+ //llinfos << "addDecodeRequest for " << uuid << " has local asset file already" << llendl;
mImpl->mDecodeQueue.push(uuid);
return TRUE;
}
+ //llinfos << "addDecodeRequest for " << uuid << " no file available" << llendl;
return FALSE;
}
diff --git a/indra/llaudio/llaudiodecodemgr.h b/indra/llaudio/llaudiodecodemgr.h
index e42fe8a40d..e42fe8a40d 100644..100755
--- a/indra/llaudio/llaudiodecodemgr.h
+++ b/indra/llaudio/llaudiodecodemgr.h
diff --git a/indra/llaudio/llaudioengine.cpp b/indra/llaudio/llaudioengine.cpp
index 5fa28cb902..06e752cf34 100644..100755
--- a/indra/llaudio/llaudioengine.cpp
+++ b/indra/llaudio/llaudioengine.cpp
@@ -839,6 +839,10 @@ void LLAudioEngine::triggerSound(const LLUUID &audio_uuid, const LLUUID& owner_i
asp->play(audio_uuid);
}
+void LLAudioEngine::triggerSound(SoundData& soundData)
+{
+ triggerSound(soundData.audio_uuid, soundData.owner_id, soundData.gain, soundData.type, soundData.pos_global);
+}
void LLAudioEngine::setListenerPos(LLVector3 aVec)
{
@@ -1221,10 +1225,11 @@ void LLAudioEngine::assetCallback(LLVFS *vfs, const LLUUID &uuid, LLAssetType::E
// Need to mark data as bad to avoid constant rerequests.
LLAudioData *adp = gAudiop->getAudioData(uuid);
if (adp)
- {
+ { // Make sure everything is cleared
adp->setHasValidData(false);
adp->setHasLocalData(false);
adp->setHasDecodedData(false);
+ adp->setHasCompletedDecode(true);
}
}
else
@@ -1237,6 +1242,7 @@ void LLAudioEngine::assetCallback(LLVFS *vfs, const LLUUID &uuid, LLAssetType::E
}
else
{
+ // llinfos << "Got asset callback with good audio data for " << uuid << ", making decode request" << llendl;
adp->setHasValidData(true);
adp->setHasLocalData(true);
gAudioDecodeMgrp->addDecodeRequest(uuid);
@@ -1304,16 +1310,18 @@ void LLAudioSource::update()
if (!getCurrentBuffer())
{
- if (getCurrentData())
+ LLAudioData *adp = getCurrentData();
+ if (adp)
{
// Hack - try and load the sound. Will do this as a callback
// on decode later.
- if (getCurrentData()->load() && getCurrentData()->getBuffer())
+ if (adp->load() && adp->getBuffer())
{
- play(getCurrentData()->getID());
+ play(adp->getID());
}
- else
+ else if (adp->hasCompletedDecode()) // Only mark corrupted after decode is done
{
+ llwarns << "Marking LLAudioSource corrupted for " << adp->getID() << llendl;
mCorrupted = true ;
}
}
@@ -1731,6 +1739,7 @@ LLAudioData::LLAudioData(const LLUUID &uuid) :
mBufferp(NULL),
mHasLocalData(false),
mHasDecodedData(false),
+ mHasCompletedDecode(false),
mHasValidData(true)
{
if (uuid.isNull())
@@ -1742,12 +1751,13 @@ LLAudioData::LLAudioData(const LLUUID &uuid) :
if (gAudiop && gAudiop->hasDecodedFile(uuid))
{
// Already have a decoded version, don't need to decode it.
- mHasLocalData = true;
- mHasDecodedData = true;
+ setHasLocalData(true);
+ setHasDecodedData(true);
+ setHasCompletedDecode(true);
}
else if (gAssetStorage && gAssetStorage->hasLocalAsset(uuid, LLAssetType::AT_SOUND))
{
- mHasLocalData = true;
+ setHasLocalData(true);
}
}
@@ -1786,5 +1796,3 @@ bool LLAudioData::load()
mBufferp->mAudioDatap = this;
return true;
}
-
-
diff --git a/indra/llaudio/llaudioengine.h b/indra/llaudio/llaudioengine.h
index 28b69e1973..da1629a1db 100644..100755
--- a/indra/llaudio/llaudioengine.h
+++ b/indra/llaudio/llaudioengine.h
@@ -42,7 +42,6 @@
#include "lllistener.h"
const F32 LL_WIND_UPDATE_INTERVAL = 0.1f;
-const F32 LL_ROLLOFF_MULTIPLIER_UNDER_WATER = 5.f; // How much sounds are weaker under water
const F32 LL_WIND_UNDERWATER_CENTER_FREQ = 20.f;
const F32 ATTACHED_OBJECT_TIMEOUT = 5.0f;
@@ -66,6 +65,7 @@ class LLAudioChannel;
class LLAudioChannelOpenAL;
class LLAudioBuffer;
class LLStreamingAudioInterface;
+struct SoundData;
//
@@ -144,6 +144,8 @@ public:
void triggerSound(const LLUUID &sound_id, const LLUUID& owner_id, const F32 gain,
const S32 type = LLAudioEngine::AUDIO_TYPE_NONE,
const LLVector3d &pos_global = LLVector3d::zero);
+ void triggerSound(SoundData& soundData);
+
bool preloadSound(const LLUUID &id);
void addAudioSource(LLAudioSource *asp);
@@ -372,10 +374,12 @@ public:
bool hasLocalData() const { return mHasLocalData; }
bool hasDecodedData() const { return mHasDecodedData; }
+ bool hasCompletedDecode() const { return mHasCompletedDecode; }
bool hasValidData() const { return mHasValidData; }
void setHasLocalData(const bool hld) { mHasLocalData = hld; }
void setHasDecodedData(const bool hdd) { mHasDecodedData = hdd; }
+ void setHasCompletedDecode(const bool hcd) { mHasCompletedDecode = hcd; }
void setHasValidData(const bool hvd) { mHasValidData = hvd; }
friend class LLAudioEngine; // Severe laziness, bad.
@@ -383,9 +387,10 @@ public:
protected:
LLUUID mID;
LLAudioBuffer *mBufferp; // If this data is being used by the audio system, a pointer to the buffer will be set here.
- bool mHasLocalData;
- bool mHasDecodedData;
- bool mHasValidData;
+ bool mHasLocalData; // Set true if the sound asset file is available locally
+ bool mHasDecodedData; // Set true if the sound file has been decoded
+ bool mHasCompletedDecode; // Set true when the sound is decoded
+ bool mHasValidData; // Set false if decoding failed, meaning the sound asset is bad
};
@@ -453,6 +458,27 @@ protected:
LLFrameTimer mLastUseTimer;
};
+struct SoundData
+{
+ LLUUID audio_uuid;
+ LLUUID owner_id;
+ F32 gain;
+ S32 type;
+ LLVector3d pos_global;
+
+ SoundData(const LLUUID &audio_uuid,
+ const LLUUID& owner_id,
+ const F32 gain,
+ const S32 type = LLAudioEngine::AUDIO_TYPE_NONE,
+ const LLVector3d &pos_global = LLVector3d::zero)
+ {
+ this->audio_uuid = audio_uuid;
+ this->owner_id = owner_id;
+ this->gain = gain;
+ this->type = type;
+ this->pos_global = pos_global;
+ }
+};
extern LLAudioEngine* gAudiop;
diff --git a/indra/llaudio/llaudioengine_fmod.cpp b/indra/llaudio/llaudioengine_fmod.cpp
deleted file mode 100644
index a40de9fa68..0000000000
--- a/indra/llaudio/llaudioengine_fmod.cpp
+++ /dev/null
@@ -1,781 +0,0 @@
-/**
- * @file audioengine_fmod.cpp
- * @brief Implementation of LLAudioEngine class abstracting the audio support as a FMOD 3D implementation
- *
- * $LicenseInfo:firstyear=2002&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 "llstreamingaudio.h"
-#include "llstreamingaudio_fmod.h"
-
-#include "llaudioengine_fmod.h"
-#include "lllistener_fmod.h"
-
-#include "llerror.h"
-#include "llmath.h"
-#include "llrand.h"
-
-#include "fmod.h"
-#include "fmod_errors.h"
-#include "lldir.h"
-#include "llapr.h"
-
-#include "sound_ids.h"
-
-
-extern "C" {
- void * F_CALLBACKAPI windCallback(void *originalbuffer, void *newbuffer, int length, void* userdata);
-}
-
-
-LLAudioEngine_FMOD::LLAudioEngine_FMOD()
-{
- mInited = false;
- mWindGen = NULL;
- mWindDSP = NULL;
-}
-
-
-LLAudioEngine_FMOD::~LLAudioEngine_FMOD()
-{
-}
-
-
-bool LLAudioEngine_FMOD::init(const S32 num_channels, void* userdata)
-{
- LLAudioEngine::init(num_channels, userdata);
-
- // Reserve one extra channel for the http stream.
- if (!FSOUND_SetMinHardwareChannels(num_channels + 1))
- {
- LL_WARNS("AppInit") << "FMOD::init[0](), error: " << FMOD_ErrorString(FSOUND_GetError()) << LL_ENDL;
- }
-
- LL_DEBUGS("AppInit") << "LLAudioEngine_FMOD::init() initializing FMOD" << LL_ENDL;
-
- F32 version = FSOUND_GetVersion();
- if (version < FMOD_VERSION)
- {
- LL_WARNS("AppInit") << "Error : You are using the wrong FMOD version (" << version
- << ")! You should be using FMOD " << FMOD_VERSION << LL_ENDL;
- //return false;
- }
-
- U32 fmod_flags = 0x0;
-
-#if LL_WINDOWS
- // Windows needs to know which window is frontmost.
- // This must be called before FSOUND_Init() per the FMOD docs.
- // This could be used to let FMOD handle muting when we lose focus,
- // but we don't actually want to do that because we want to distinguish
- // between minimized and not-focused states.
- if (!FSOUND_SetHWND(userdata))
- {
- LL_WARNS("AppInit") << "Error setting FMOD window: "
- << FMOD_ErrorString(FSOUND_GetError()) << LL_ENDL;
- return false;
- }
- // Play audio when we don't have focus.
- // (For example, IM client on top of us.)
- // This means we also try to play audio when minimized,
- // so we manually handle muting in that case. JC
- fmod_flags |= FSOUND_INIT_GLOBALFOCUS;
-#endif
-
-#if LL_LINUX
- // initialize the FMOD engine
-
- // This is a hack to use only FMOD's basic FPU mixer
- // when the LL_VALGRIND environmental variable is set,
- // otherwise valgrind will fall over on FMOD's MMX detection
- if (getenv("LL_VALGRIND")) /*Flawfinder: ignore*/
- {
- LL_INFOS("AppInit") << "Pacifying valgrind in FMOD init." << LL_ENDL;
- FSOUND_SetMixer(FSOUND_MIXER_QUALITY_FPU);
- }
-
- // If we don't set an output method, Linux FMOD always
- // decides on OSS and fails otherwise. So we'll manually
- // try ESD, then OSS, then ALSA.
- // Why this order? See SL-13250, but in short, OSS emulated
- // on top of ALSA is ironically more reliable than raw ALSA.
- // Ack, and ESD has more reliable failure modes - but has worse
- // latency - than all of them, so wins for now.
- bool audio_ok = false;
-
- if (!audio_ok)
- {
- if (NULL == getenv("LL_BAD_FMOD_ESD")) /*Flawfinder: ignore*/
- {
- LL_DEBUGS("AppInit") << "Trying ESD audio output..." << LL_ENDL;
- if(FSOUND_SetOutput(FSOUND_OUTPUT_ESD) &&
- FSOUND_Init(44100, num_channels, fmod_flags))
- {
- LL_DEBUGS("AppInit") << "ESD audio output initialized OKAY"
- << LL_ENDL;
- audio_ok = true;
- } else {
- LL_WARNS("AppInit") << "ESD audio output FAILED to initialize: "
- << FMOD_ErrorString(FSOUND_GetError()) << LL_ENDL;
- }
- } else {
- LL_DEBUGS("AppInit") << "ESD audio output SKIPPED" << LL_ENDL;
- }
- }
- if (!audio_ok)
- {
- if (NULL == getenv("LL_BAD_FMOD_OSS")) /*Flawfinder: ignore*/
- {
- LL_DEBUGS("AppInit") << "Trying OSS audio output..." << LL_ENDL;
- if(FSOUND_SetOutput(FSOUND_OUTPUT_OSS) &&
- FSOUND_Init(44100, num_channels, fmod_flags))
- {
- LL_DEBUGS("AppInit") << "OSS audio output initialized OKAY" << LL_ENDL;
- audio_ok = true;
- } else {
- LL_WARNS("AppInit") << "OSS audio output FAILED to initialize: "
- << FMOD_ErrorString(FSOUND_GetError()) << LL_ENDL;
- }
- } else {
- LL_DEBUGS("AppInit") << "OSS audio output SKIPPED" << LL_ENDL;
- }
- }
- if (!audio_ok)
- {
- if (NULL == getenv("LL_BAD_FMOD_ALSA")) /*Flawfinder: ignore*/
- {
- LL_DEBUGS("AppInit") << "Trying ALSA audio output..." << LL_ENDL;
- if(FSOUND_SetOutput(FSOUND_OUTPUT_ALSA) &&
- FSOUND_Init(44100, num_channels, fmod_flags))
- {
- LL_DEBUGS("AppInit") << "ALSA audio output initialized OKAY" << LL_ENDL;
- audio_ok = true;
- } else {
- LL_WARNS("AppInit") << "ALSA audio output FAILED to initialize: "
- << FMOD_ErrorString(FSOUND_GetError()) << LL_ENDL;
- }
- } else {
- LL_DEBUGS("AppInit") << "OSS audio output SKIPPED" << LL_ENDL;
- }
- }
- if (!audio_ok)
- {
- LL_WARNS("AppInit") << "Overall audio init failure." << LL_ENDL;
- return false;
- }
-
- // On Linux, FMOD causes a SIGPIPE for some netstream error
- // conditions (an FMOD bug); ignore SIGPIPE so it doesn't crash us.
- // NOW FIXED in FMOD 3.x since 2006-10-01.
- //signal(SIGPIPE, SIG_IGN);
-
- // We're interested in logging which output method we
- // ended up with, for QA purposes.
- switch (FSOUND_GetOutput())
- {
- case FSOUND_OUTPUT_NOSOUND: LL_DEBUGS("AppInit") << "Audio output: NoSound" << LL_ENDL; break;
- case FSOUND_OUTPUT_OSS: LL_DEBUGS("AppInit") << "Audio output: OSS" << LL_ENDL; break;
- case FSOUND_OUTPUT_ESD: LL_DEBUGS("AppInit") << "Audio output: ESD" << LL_ENDL; break;
- case FSOUND_OUTPUT_ALSA: LL_DEBUGS("AppInit") << "Audio output: ALSA" << LL_ENDL; break;
- default: LL_INFOS("AppInit") << "Audio output: Unknown!" << LL_ENDL; break;
- };
-
-#else // LL_LINUX
-
- // initialize the FMOD engine
- if (!FSOUND_Init(44100, num_channels, fmod_flags))
- {
- LL_WARNS("AppInit") << "Error initializing FMOD: "
- << FMOD_ErrorString(FSOUND_GetError()) << LL_ENDL;
- return false;
- }
-
-#endif
-
- // set up our favourite FMOD-native streaming audio implementation if none has already been added
- if (!getStreamingAudioImpl()) // no existing implementation added
- setStreamingAudioImpl(new LLStreamingAudio_FMOD());
-
- LL_DEBUGS("AppInit") << "LLAudioEngine_FMOD::init() FMOD initialized correctly" << LL_ENDL;
-
- mInited = true;
-
- return true;
-}
-
-
-std::string LLAudioEngine_FMOD::getDriverName(bool verbose)
-{
- if (verbose)
- {
- F32 version = FSOUND_GetVersion();
- return llformat("FMOD version %f", version);
- }
- else
- {
- return "FMOD";
- }
-}
-
-
-void LLAudioEngine_FMOD::allocateListener(void)
-{
- mListenerp = (LLListener *) new LLListener_FMOD();
- if (!mListenerp)
- {
- llwarns << "Listener creation failed" << llendl;
- }
-}
-
-
-void LLAudioEngine_FMOD::shutdown()
-{
- if (mWindDSP)
- {
- FSOUND_DSP_SetActive(mWindDSP,false);
- FSOUND_DSP_Free(mWindDSP);
- }
-
- stopInternetStream();
-
- LLAudioEngine::shutdown();
-
- llinfos << "LLAudioEngine_FMOD::shutdown() closing FMOD" << llendl;
- FSOUND_Close();
- llinfos << "LLAudioEngine_FMOD::shutdown() done closing FMOD" << llendl;
-
- delete mListenerp;
- mListenerp = NULL;
-}
-
-
-LLAudioBuffer * LLAudioEngine_FMOD::createBuffer()
-{
- return new LLAudioBufferFMOD();
-}
-
-
-LLAudioChannel * LLAudioEngine_FMOD::createChannel()
-{
- return new LLAudioChannelFMOD();
-}
-
-
-bool LLAudioEngine_FMOD::initWind()
-{
- if (!mWindGen)
- {
- bool enable;
-
- switch (FSOUND_GetMixer())
- {
- case FSOUND_MIXER_MMXP5:
- case FSOUND_MIXER_MMXP6:
- case FSOUND_MIXER_QUALITY_MMXP5:
- case FSOUND_MIXER_QUALITY_MMXP6:
- enable = (typeid(MIXBUFFERFORMAT) == typeid(S16));
- break;
- case FSOUND_MIXER_BLENDMODE:
- enable = (typeid(MIXBUFFERFORMAT) == typeid(S32));
- break;
- case FSOUND_MIXER_QUALITY_FPU:
- enable = (typeid(MIXBUFFERFORMAT) == typeid(F32));
- break;
- default:
- // FSOUND_GetMixer() does not return a valid mixer type on Darwin
- LL_INFOS("AppInit") << "Unknown FMOD mixer type, assuming default" << LL_ENDL;
- enable = true;
- break;
- }
-
- if (enable)
- {
- mWindGen = new LLWindGen<MIXBUFFERFORMAT>(FSOUND_GetOutputRate());
- }
- else
- {
- LL_WARNS("AppInit") << "Incompatible FMOD mixer type, wind noise disabled" << LL_ENDL;
- }
- }
-
- mNextWindUpdate = 0.0;
-
- if (mWindGen && !mWindDSP)
- {
- mWindDSP = FSOUND_DSP_Create(&windCallback, FSOUND_DSP_DEFAULTPRIORITY_CLEARUNIT + 20, mWindGen);
- }
- if (mWindDSP)
- {
- FSOUND_DSP_SetActive(mWindDSP, true);
- return true;
- }
-
- return false;
-}
-
-
-void LLAudioEngine_FMOD::cleanupWind()
-{
- if (mWindDSP)
- {
- FSOUND_DSP_SetActive(mWindDSP, false);
- FSOUND_DSP_Free(mWindDSP);
- mWindDSP = NULL;
- }
-
- delete mWindGen;
- mWindGen = NULL;
-}
-
-
-//-----------------------------------------------------------------------
-void LLAudioEngine_FMOD::updateWind(LLVector3 wind_vec, F32 camera_height_above_water)
-{
- LLVector3 wind_pos;
- F64 pitch;
- F64 center_freq;
-
- if (!mEnableWind)
- {
- return;
- }
-
- if (mWindUpdateTimer.checkExpirationAndReset(LL_WIND_UPDATE_INTERVAL))
- {
-
- // wind comes in as Linden coordinate (+X = forward, +Y = left, +Z = up)
- // need to convert this to the conventional orientation DS3D and OpenAL use
- // where +X = right, +Y = up, +Z = backwards
-
- wind_vec.setVec(-wind_vec.mV[1], wind_vec.mV[2], -wind_vec.mV[0]);
-
- // cerr << "Wind update" << endl;
-
- pitch = 1.0 + mapWindVecToPitch(wind_vec);
- center_freq = 80.0 * pow(pitch,2.5*(mapWindVecToGain(wind_vec)+1.0));
-
- mWindGen->mTargetFreq = (F32)center_freq;
- mWindGen->mTargetGain = (F32)mapWindVecToGain(wind_vec) * mMaxWindGain;
- mWindGen->mTargetPanGainR = (F32)mapWindVecToPan(wind_vec);
- }
-}
-
-/*
-//-----------------------------------------------------------------------
-void LLAudioEngine_FMOD::setSourceMinDistance(U16 source_num, F64 distance)
-{
- if (!mInited)
- {
- return;
- }
- if (mBuffer[source_num])
- {
- mMinDistance[source_num] = (F32) distance;
- if (!FSOUND_Sample_SetMinMaxDistance(mBuffer[source_num],mMinDistance[source_num], mMaxDistance[source_num]))
- {
- llwarns << "FMOD::setSourceMinDistance(" << source_num << "), error: " << FMOD_ErrorString(FSOUND_GetError()) << llendl;
- }
- }
-}
-
-//-----------------------------------------------------------------------
-void LLAudioEngine_FMOD::setSourceMaxDistance(U16 source_num, F64 distance)
-{
- if (!mInited)
- {
- return;
- }
- if (mBuffer[source_num])
- {
- mMaxDistance[source_num] = (F32) distance;
- if (!FSOUND_Sample_SetMinMaxDistance(mBuffer[source_num],mMinDistance[source_num], mMaxDistance[source_num]))
- {
- llwarns << "FMOD::setSourceMaxDistance(" << source_num << "), error: " << FMOD_ErrorString(FSOUND_GetError()) << llendl;
- }
- }
-}
-
-//-----------------------------------------------------------------------
-void LLAudioEngine_FMOD::get3DParams(S32 source_num, S32 *volume, S32 *freq, S32 *inside, S32 *outside, LLVector3 *orient, S32 *out_volume, F32 *min_dist, F32 *max_dist)
-{
- *volume = 0;
- *freq = 0;
- *inside = 0;
- *outside = 0;
- *orient = LLVector3::zero;
- *out_volume = 0;
- *min_dist = 0.f;
- *max_dist = 0.f;
-}
-
-*/
-
-
-//-----------------------------------------------------------------------
-void LLAudioEngine_FMOD::setInternalGain(F32 gain)
-{
- if (!mInited)
- {
- return;
- }
-
- gain = llclamp( gain, 0.0f, 1.0f );
- FSOUND_SetSFXMasterVolume( llround( 255.0f * gain ) );
-
- LLStreamingAudioInterface *saimpl = getStreamingAudioImpl();
- if ( saimpl )
- {
- // fmod likes its streaming audio channel gain re-asserted after
- // master volume change.
- saimpl->setGain(saimpl->getGain());
- }
-}
-
-//
-// LLAudioChannelFMOD implementation
-//
-
-LLAudioChannelFMOD::LLAudioChannelFMOD() : LLAudioChannel(), mChannelID(0), mLastSamplePos(0)
-{
-}
-
-
-LLAudioChannelFMOD::~LLAudioChannelFMOD()
-{
- cleanup();
-}
-
-
-bool LLAudioChannelFMOD::updateBuffer()
-{
- if (LLAudioChannel::updateBuffer())
- {
- // Base class update returned true, which means that we need to actually
- // set up the channel for a different buffer.
-
- LLAudioBufferFMOD *bufferp = (LLAudioBufferFMOD *)mCurrentSourcep->getCurrentBuffer();
-
- // Grab the FMOD sample associated with the buffer
- FSOUND_SAMPLE *samplep = bufferp->getSample();
- if (!samplep)
- {
- // This is bad, there should ALWAYS be a sample associated with a legit
- // buffer.
- llerrs << "No FMOD sample!" << llendl;
- return false;
- }
-
-
- // Actually play the sound. Start it off paused so we can do all the necessary
- // setup.
- mChannelID = FSOUND_PlaySoundEx(FSOUND_FREE, samplep, FSOUND_DSP_GetSFXUnit(), true);
-
- //llinfos << "Setting up channel " << std::hex << mChannelID << std::dec << llendl;
- }
-
- // If we have a source for the channel, we need to update its gain.
- if (mCurrentSourcep)
- {
- // SJB: warnings can spam and hurt framerate, disabling
- if (!FSOUND_SetVolume(mChannelID, llround(getSecondaryGain() * mCurrentSourcep->getGain() * 255.0f)))
- {
-// llwarns << "LLAudioChannelFMOD::updateBuffer error: " << FMOD_ErrorString(FSOUND_GetError()) << llendl;
- }
-
- if (!FSOUND_SetLoopMode(mChannelID, mCurrentSourcep->isLoop() ? FSOUND_LOOP_NORMAL : FSOUND_LOOP_OFF))
- {
-// llwarns << "Channel " << mChannelID << "Source ID: " << mCurrentSourcep->getID()
-// << " at " << mCurrentSourcep->getPositionGlobal() << llendl;
-// llwarns << "LLAudioChannelFMOD::updateBuffer error: " << FMOD_ErrorString(FSOUND_GetError()) << llendl;
- }
- }
-
- return true;
-}
-
-
-void LLAudioChannelFMOD::update3DPosition()
-{
- if (!mChannelID)
- {
- // We're not actually a live channel (i.e., we're not playing back anything)
- return;
- }
-
- LLAudioBufferFMOD *bufferp = (LLAudioBufferFMOD *)mCurrentBufferp;
- if (!bufferp)
- {
- // We don't have a buffer associated with us (should really have been picked up
- // by the above if.
- return;
- }
-
- if (mCurrentSourcep->isAmbient())
- {
- // Ambient sound, don't need to do any positional updates.
- bufferp->set3DMode(false);
- }
- else
- {
- // Localized sound. Update the position and velocity of the sound.
- bufferp->set3DMode(true);
-
- LLVector3 float_pos;
- float_pos.setVec(mCurrentSourcep->getPositionGlobal());
- if (!FSOUND_3D_SetAttributes(mChannelID, float_pos.mV, mCurrentSourcep->getVelocity().mV))
- {
- LL_DEBUGS("FMOD") << "LLAudioChannelFMOD::update3DPosition error: " << FMOD_ErrorString(FSOUND_GetError()) << LL_ENDL;
- }
- }
-}
-
-
-void LLAudioChannelFMOD::updateLoop()
-{
- if (!mChannelID)
- {
- // May want to clear up the loop/sample counters.
- return;
- }
-
- //
- // Hack: We keep track of whether we looped or not by seeing when the
- // sample position looks like it's going backwards. Not reliable; may
- // yield false negatives.
- //
- U32 cur_pos = FSOUND_GetCurrentPosition(mChannelID);
- if (cur_pos < (U32)mLastSamplePos)
- {
- mLoopedThisFrame = true;
- }
- mLastSamplePos = cur_pos;
-}
-
-
-void LLAudioChannelFMOD::cleanup()
-{
- if (!mChannelID)
- {
- //llinfos << "Aborting cleanup with no channelID." << llendl;
- return;
- }
-
- //llinfos << "Cleaning up channel: " << mChannelID << llendl;
- if (!FSOUND_StopSound(mChannelID))
- {
- LL_DEBUGS("FMOD") << "LLAudioChannelFMOD::cleanup error: " << FMOD_ErrorString(FSOUND_GetError()) << llendl;
- }
-
- mCurrentBufferp = NULL;
- mChannelID = 0;
-}
-
-
-void LLAudioChannelFMOD::play()
-{
- if (!mChannelID)
- {
- llwarns << "Playing without a channelID, aborting" << llendl;
- return;
- }
-
- if (!FSOUND_SetPaused(mChannelID, false))
- {
- llwarns << "LLAudioChannelFMOD::play error: " << FMOD_ErrorString(FSOUND_GetError()) << llendl;
- }
- getSource()->setPlayedOnce(true);
-}
-
-
-void LLAudioChannelFMOD::playSynced(LLAudioChannel *channelp)
-{
- LLAudioChannelFMOD *fmod_channelp = (LLAudioChannelFMOD*)channelp;
- if (!(fmod_channelp->mChannelID && mChannelID))
- {
- // Don't have channels allocated to both the master and the slave
- return;
- }
-
- U32 position = FSOUND_GetCurrentPosition(fmod_channelp->mChannelID) % mCurrentBufferp->getLength();
- // Try to match the position of our sync master
- if (!FSOUND_SetCurrentPosition(mChannelID, position))
- {
- llwarns << "LLAudioChannelFMOD::playSynced unable to set current position" << llendl;
- }
-
- // Start us playing
- play();
-}
-
-
-bool LLAudioChannelFMOD::isPlaying()
-{
- if (!mChannelID)
- {
- return false;
- }
-
- return FSOUND_IsPlaying(mChannelID) && (!FSOUND_GetPaused(mChannelID));
-}
-
-
-
-//
-// LLAudioBufferFMOD implementation
-//
-
-
-LLAudioBufferFMOD::LLAudioBufferFMOD()
-{
- mSamplep = NULL;
-}
-
-
-LLAudioBufferFMOD::~LLAudioBufferFMOD()
-{
- if (mSamplep)
- {
- // Clean up the associated FMOD sample if it exists.
- FSOUND_Sample_Free(mSamplep);
- mSamplep = NULL;
- }
-}
-
-
-bool LLAudioBufferFMOD::loadWAV(const std::string& filename)
-{
- // Try to open a wav file from disk. This will eventually go away, as we don't
- // really want to block doing this.
- if (filename.empty())
- {
- // invalid filename, abort.
- return false;
- }
-
- if (!LLAPRFile::isExist(filename, NULL, LL_APR_RPB))
- {
- // File not found, abort.
- return false;
- }
-
- if (mSamplep)
- {
- // If there's already something loaded in this buffer, clean it up.
- FSOUND_Sample_Free(mSamplep);
- mSamplep = NULL;
- }
-
- // Load up the wav file into an fmod sample
-#if LL_WINDOWS
- // MikeS. - Loading the sound file manually and then handing it over to FMOD,
- // since FMOD uses posix IO internally,
- // which doesn't work with unicode file paths.
- LLFILE* sound_file = LLFile::fopen(filename,"rb"); /* Flawfinder: ignore */
- if (sound_file)
- {
- fseek(sound_file,0,SEEK_END);
- U32 file_length = ftell(sound_file); //Find the length of the file by seeking to the end and getting the offset
- size_t read_count;
- fseek(sound_file,0,SEEK_SET); //Seek back to the beginning
- char* buffer = new char[file_length];
- llassert(buffer);
- read_count = fread((void*)buffer,file_length,1,sound_file);//Load it..
- if(ferror(sound_file)==0 && (read_count == 1)){//No read error, and we got 1 chunk of our size...
- unsigned int mode_flags = FSOUND_LOOP_NORMAL | FSOUND_LOADMEMORY;
- //FSOUND_16BITS | FSOUND_MONO | FSOUND_LOADMEMORY | FSOUND_LOOP_NORMAL;
- mSamplep = FSOUND_Sample_Load(FSOUND_UNMANAGED, buffer, mode_flags , 0, file_length);
- }
- delete[] buffer;
- fclose(sound_file);
- }
-#else
- mSamplep = FSOUND_Sample_Load(FSOUND_UNMANAGED, filename.c_str(), FSOUND_LOOP_NORMAL, 0, 0);
-#endif
-
- if (!mSamplep)
- {
- // We failed to load the file for some reason.
- llwarns << "Could not load data '" << filename << "': "
- << FMOD_ErrorString(FSOUND_GetError()) << llendl;
-
- //
- // If we EVER want to load wav files provided by end users, we need
- // to rethink this!
- //
- // file is probably corrupt - remove it.
- LLFile::remove(filename);
- return false;
- }
-
- // Everything went well, return true
- return true;
-}
-
-
-U32 LLAudioBufferFMOD::getLength()
-{
- if (!mSamplep)
- {
- return 0;
- }
-
- return FSOUND_Sample_GetLength(mSamplep);
-}
-
-
-void LLAudioBufferFMOD::set3DMode(bool use3d)
-{
- U16 current_mode = FSOUND_Sample_GetMode(mSamplep);
-
- if (use3d)
- {
- if (!FSOUND_Sample_SetMode(mSamplep, (current_mode & (~FSOUND_2D))))
- {
- llwarns << "LLAudioBufferFMOD::set3DMode error: " << FMOD_ErrorString(FSOUND_GetError()) << llendl;
- }
- }
- else
- {
- if (!FSOUND_Sample_SetMode(mSamplep, current_mode | FSOUND_2D))
- {
- llwarns << "LLAudioBufferFMOD::set3DMode error: " << FMOD_ErrorString(FSOUND_GetError()) << llendl;
- }
- }
-}
-
-
-void * F_CALLBACKAPI windCallback(void *originalbuffer, void *newbuffer, int length, void* userdata)
-{
- // originalbuffer = fmod's original mixbuffer.
- // newbuffer = the buffer passed from the previous DSP unit.
- // length = length in samples at this mix time.
- // userdata = user parameter passed through in FSOUND_DSP_Create.
-
- LLWindGen<LLAudioEngine_FMOD::MIXBUFFERFORMAT> *windgen =
- (LLWindGen<LLAudioEngine_FMOD::MIXBUFFERFORMAT> *)userdata;
-
- newbuffer = windgen->windGenerate((LLAudioEngine_FMOD::MIXBUFFERFORMAT *)newbuffer, length);
-
- return newbuffer;
-}
diff --git a/indra/llaudio/llaudioengine_fmod.h b/indra/llaudio/llaudioengine_fmod.h
deleted file mode 100644
index 4582a5d57e..0000000000
--- a/indra/llaudio/llaudioengine_fmod.h
+++ /dev/null
@@ -1,124 +0,0 @@
-/**
- * @file audioengine_fmod.h
- * @brief Definition of LLAudioEngine class abstracting the audio
- * support as a FMOD 3D implementation
- *
- * $LicenseInfo:firstyear=2002&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$
- */
-
-#ifndef LL_AUDIOENGINE_FMOD_H
-#define LL_AUDIOENGINE_FMOD_H
-
-#include "llaudioengine.h"
-#include "lllistener_fmod.h"
-#include "llwindgen.h"
-
-#include "fmod.h"
-
-class LLAudioStreamManagerFMOD;
-
-class LLAudioEngine_FMOD : public LLAudioEngine
-{
-public:
- LLAudioEngine_FMOD();
- virtual ~LLAudioEngine_FMOD();
-
- // initialization/startup/shutdown
- virtual bool init(const S32 num_channels, void *user_data);
- virtual std::string getDriverName(bool verbose);
- virtual void allocateListener();
-
- virtual void shutdown();
-
- /*virtual*/ bool initWind();
- /*virtual*/ void cleanupWind();
-
- /*virtual*/void updateWind(LLVector3 direction, F32 camera_height_above_water);
-
-#if LL_DARWIN
- typedef S32 MIXBUFFERFORMAT;
-#else
- typedef S16 MIXBUFFERFORMAT;
-#endif
-
-protected:
- /*virtual*/ LLAudioBuffer *createBuffer(); // Get a free buffer, or flush an existing one if you have to.
- /*virtual*/ LLAudioChannel *createChannel(); // Create a new audio channel.
-
- /*virtual*/ void setInternalGain(F32 gain);
-protected:
- static signed char F_CALLBACKAPI callbackMetaData(char* name, char* value, void* userdata);
-
- //F32 mMinDistance[MAX_BUFFERS];
- //F32 mMaxDistance[MAX_BUFFERS];
-
- bool mInited;
-
- // On Windows, userdata is the HWND of the application window.
- void* mUserData;
-
- LLWindGen<MIXBUFFERFORMAT> *mWindGen;
- FSOUND_DSPUNIT *mWindDSP;
-};
-
-
-class LLAudioChannelFMOD : public LLAudioChannel
-{
-public:
- LLAudioChannelFMOD();
- virtual ~LLAudioChannelFMOD();
-
-protected:
- /*virtual*/ void play();
- /*virtual*/ void playSynced(LLAudioChannel *channelp);
- /*virtual*/ void cleanup();
- /*virtual*/ bool isPlaying();
-
- /*virtual*/ bool updateBuffer();
- /*virtual*/ void update3DPosition();
- /*virtual*/ void updateLoop();
-
-protected:
- int mChannelID;
- S32 mLastSamplePos;
-};
-
-
-class LLAudioBufferFMOD : public LLAudioBuffer
-{
-public:
- LLAudioBufferFMOD();
- virtual ~LLAudioBufferFMOD();
-
- /*virtual*/ bool loadWAV(const std::string& filename);
- /*virtual*/ U32 getLength();
- friend class LLAudioChannelFMOD;
-
- void set3DMode(bool use3d);
-protected:
- FSOUND_SAMPLE *getSample() { return mSamplep; }
-protected:
- FSOUND_SAMPLE *mSamplep;
-};
-
-
-#endif // LL_AUDIOENGINE_FMOD_H
diff --git a/indra/llaudio/llaudioengine_fmodex.cpp b/indra/llaudio/llaudioengine_fmodex.cpp
new file mode 100644
index 0000000000..e9b74b8f41
--- /dev/null
+++ b/indra/llaudio/llaudioengine_fmodex.cpp
@@ -0,0 +1,762 @@
+/**
+ * @file audioengine_fmodex.cpp
+ * @brief Implementation of LLAudioEngine class abstracting the audio
+ * support as a FMODEX implementation
+ *
+ * $LicenseInfo:firstyear=2002&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 "llstreamingaudio.h"
+#include "llstreamingaudio_fmodex.h"
+
+#include "llaudioengine_fmodex.h"
+#include "lllistener_fmodex.h"
+
+#include "llerror.h"
+#include "llmath.h"
+#include "llrand.h"
+
+#include "fmod.hpp"
+#include "fmod_errors.h"
+#include "lldir.h"
+#include "llapr.h"
+
+#include "sound_ids.h"
+
+FMOD_RESULT F_CALLBACK windCallback(FMOD_DSP_STATE *dsp_state, float *inbuffer, float *outbuffer, unsigned int length, int inchannels, int outchannels);
+
+FMOD::ChannelGroup *LLAudioEngine_FMODEX::mChannelGroups[LLAudioEngine::AUDIO_TYPE_COUNT] = {0};
+
+LLAudioEngine_FMODEX::LLAudioEngine_FMODEX(bool enable_profiler)
+{
+ mInited = false;
+ mWindGen = NULL;
+ mWindDSP = NULL;
+ mSystem = NULL;
+ mEnableProfiler = enable_profiler;
+}
+
+
+LLAudioEngine_FMODEX::~LLAudioEngine_FMODEX()
+{
+}
+
+
+inline bool Check_FMOD_Error(FMOD_RESULT result, const char *string)
+{
+ if(result == FMOD_OK)
+ return false;
+ lldebugs << string << " Error: " << FMOD_ErrorString(result) << llendl;
+ return true;
+}
+
+void* F_STDCALL decode_alloc(unsigned int size, FMOD_MEMORY_TYPE type, const char *sourcestr)
+{
+ if(type & FMOD_MEMORY_STREAM_DECODE)
+ {
+ llinfos << "Decode buffer size: " << size << llendl;
+ }
+ else if(type & FMOD_MEMORY_STREAM_FILE)
+ {
+ llinfos << "Strean buffer size: " << size << llendl;
+ }
+ return new char[size];
+}
+void* F_STDCALL decode_realloc(void *ptr, unsigned int size, FMOD_MEMORY_TYPE type, const char *sourcestr)
+{
+ memset(ptr,0,size);
+ return ptr;
+}
+void F_STDCALL decode_dealloc(void *ptr, FMOD_MEMORY_TYPE type, const char *sourcestr)
+{
+ delete[] (char*)ptr;
+}
+
+bool LLAudioEngine_FMODEX::init(const S32 num_channels, void* userdata)
+{
+ U32 version;
+ FMOD_RESULT result;
+
+ LL_DEBUGS("AppInit") << "LLAudioEngine_FMODEX::init() initializing FMOD" << LL_ENDL;
+
+ //result = FMOD::Memory_Initialize(NULL, 0, &decode_alloc, &decode_realloc, &decode_dealloc, FMOD_MEMORY_STREAM_DECODE | FMOD_MEMORY_STREAM_FILE);
+ //if(Check_FMOD_Error(result, "FMOD::Memory_Initialize"))
+ // return false;
+
+ // turn off non-error log spam to fmod.log (TODO: why do we even have an fmod.log if we don't link against log lib?)
+ FMOD::Debug_SetLevel(FMOD_DEBUG_LEVEL_ERROR);
+
+ result = FMOD::System_Create(&mSystem);
+ if(Check_FMOD_Error(result, "FMOD::System_Create"))
+ return false;
+
+ //will call LLAudioEngine_FMODEX::allocateListener, which needs a valid mSystem pointer.
+ LLAudioEngine::init(num_channels, userdata);
+
+ result = mSystem->getVersion(&version);
+ Check_FMOD_Error(result, "FMOD::System::getVersion");
+
+ if (version < FMOD_VERSION)
+ {
+ LL_WARNS("AppInit") << "Error : You are using the wrong FMOD Ex version (" << version
+ << ")! You should be using FMOD Ex" << FMOD_VERSION << LL_ENDL;
+ }
+
+ result = mSystem->setSoftwareFormat(44100, FMOD_SOUND_FORMAT_PCM16, 0, 0, FMOD_DSP_RESAMPLER_LINEAR);
+ Check_FMOD_Error(result,"FMOD::System::setSoftwareFormat");
+
+ // In this case, all sounds, PLUS wind and stream will be software.
+ result = mSystem->setSoftwareChannels(num_channels + 2);
+ Check_FMOD_Error(result,"FMOD::System::setSoftwareChannels");
+
+ U32 fmod_flags = FMOD_INIT_NORMAL;
+ if(mEnableProfiler)
+ {
+ fmod_flags |= FMOD_INIT_ENABLE_PROFILE;
+ mSystem->createChannelGroup("None", &mChannelGroups[AUDIO_TYPE_NONE]);
+ mSystem->createChannelGroup("SFX", &mChannelGroups[AUDIO_TYPE_SFX]);
+ mSystem->createChannelGroup("UI", &mChannelGroups[AUDIO_TYPE_UI]);
+ mSystem->createChannelGroup("Ambient", &mChannelGroups[AUDIO_TYPE_AMBIENT]);
+ }
+
+#if LL_LINUX
+ bool audio_ok = false;
+
+ if (!audio_ok)
+ {
+ if (NULL == getenv("LL_BAD_FMOD_PULSEAUDIO")) /*Flawfinder: ignore*/
+ {
+ LL_DEBUGS("AppInit") << "Trying PulseAudio audio output..." << LL_ENDL;
+ if(mSystem->setOutput(FMOD_OUTPUTTYPE_PULSEAUDIO) == FMOD_OK &&
+ (result = mSystem->init(num_channels + 2, fmod_flags, 0)) == FMOD_OK)
+ {
+ LL_DEBUGS("AppInit") << "PulseAudio output initialized OKAY" << LL_ENDL;
+ audio_ok = true;
+ }
+ else
+ {
+ Check_FMOD_Error(result, "PulseAudio audio output FAILED to initialize");
+ }
+ }
+ else
+ {
+ LL_DEBUGS("AppInit") << "PulseAudio audio output SKIPPED" << LL_ENDL;
+ }
+ }
+ if (!audio_ok)
+ {
+ if (NULL == getenv("LL_BAD_FMOD_ALSA")) /*Flawfinder: ignore*/
+ {
+ LL_DEBUGS("AppInit") << "Trying ALSA audio output..." << LL_ENDL;
+ if(mSystem->setOutput(FMOD_OUTPUTTYPE_ALSA) == FMOD_OK &&
+ (result = mSystem->init(num_channels + 2, fmod_flags, 0)) == FMOD_OK)
+ {
+ LL_DEBUGS("AppInit") << "ALSA audio output initialized OKAY" << LL_ENDL;
+ audio_ok = true;
+ }
+ else
+ {
+ Check_FMOD_Error(result, "ALSA audio output FAILED to initialize");
+ }
+ }
+ else
+ {
+ LL_DEBUGS("AppInit") << "ALSA audio output SKIPPED" << LL_ENDL;
+ }
+ }
+ if (!audio_ok)
+ {
+ if (NULL == getenv("LL_BAD_FMOD_OSS")) /*Flawfinder: ignore*/
+ {
+ LL_DEBUGS("AppInit") << "Trying OSS audio output..." << LL_ENDL;
+ if(mSystem->setOutput(FMOD_OUTPUTTYPE_OSS) == FMOD_OK &&
+ (result = mSystem->init(num_channels + 2, fmod_flags, 0)) == FMOD_OK)
+ {
+ LL_DEBUGS("AppInit") << "OSS audio output initialized OKAY" << LL_ENDL;
+ audio_ok = true;
+ }
+ else
+ {
+ Check_FMOD_Error(result, "OSS audio output FAILED to initialize");
+ }
+ }
+ else
+ {
+ LL_DEBUGS("AppInit") << "OSS audio output SKIPPED" << LL_ENDL;
+ }
+ }
+ if (!audio_ok)
+ {
+ LL_WARNS("AppInit") << "Overall audio init failure." << LL_ENDL;
+ return false;
+ }
+
+ // We're interested in logging which output method we
+ // ended up with, for QA purposes.
+ FMOD_OUTPUTTYPE output_type;
+ mSystem->getOutput(&output_type);
+ switch (output_type)
+ {
+ case FMOD_OUTPUTTYPE_NOSOUND:
+ LL_INFOS("AppInit") << "Audio output: NoSound" << LL_ENDL; break;
+ case FMOD_OUTPUTTYPE_PULSEAUDIO:
+ LL_INFOS("AppInit") << "Audio output: PulseAudio" << LL_ENDL; break;
+ case FMOD_OUTPUTTYPE_ALSA:
+ LL_INFOS("AppInit") << "Audio output: ALSA" << LL_ENDL; break;
+ case FMOD_OUTPUTTYPE_OSS:
+ LL_INFOS("AppInit") << "Audio output: OSS" << LL_ENDL; break;
+ default:
+ LL_INFOS("AppInit") << "Audio output: Unknown!" << LL_ENDL; break;
+ };
+#else // LL_LINUX
+
+ // initialize the FMOD engine
+ result = mSystem->init( num_channels + 2, fmod_flags, 0);
+ if (result == FMOD_ERR_OUTPUT_CREATEBUFFER)
+ {
+ /*
+ Ok, the speaker mode selected isn't supported by this soundcard. Switch it
+ back to stereo...
+ */
+ result = mSystem->setSpeakerMode(FMOD_SPEAKERMODE_STEREO);
+ Check_FMOD_Error(result,"Error falling back to stereo mode");
+ /*
+ ... and re-init.
+ */
+ result = mSystem->init( num_channels + 2, fmod_flags, 0);
+ }
+ if(Check_FMOD_Error(result, "Error initializing FMOD Ex"))
+ return false;
+#endif
+
+ // set up our favourite FMOD-native streaming audio implementation if none has already been added
+ if (!getStreamingAudioImpl()) // no existing implementation added
+ setStreamingAudioImpl(new LLStreamingAudio_FMODEX(mSystem));
+
+ LL_INFOS("AppInit") << "LLAudioEngine_FMODEX::init() FMOD Ex initialized correctly" << LL_ENDL;
+
+ int r_numbuffers, r_samplerate, r_channels, r_bits;
+ unsigned int r_bufferlength;
+ mSystem->getDSPBufferSize(&r_bufferlength, &r_numbuffers);
+ LL_INFOS("AppInit") << "LLAudioEngine_FMODEX::init(): r_bufferlength=" << r_bufferlength << " bytes" << LL_ENDL;
+ LL_INFOS("AppInit") << "LLAudioEngine_FMODEX::init(): r_numbuffers=" << r_numbuffers << LL_ENDL;
+
+ mSystem->getSoftwareFormat(&r_samplerate, NULL, &r_channels, NULL, NULL, &r_bits);
+ LL_INFOS("AppInit") << "LLAudioEngine_FMODEX::init(): r_samplerate=" << r_samplerate << "Hz" << LL_ENDL;
+ LL_INFOS("AppInit") << "LLAudioEngine_FMODEX::init(): r_channels=" << r_channels << LL_ENDL;
+ LL_INFOS("AppInit") << "LLAudioEngine_FMODEX::init(): r_bits =" << r_bits << LL_ENDL;
+
+ char r_name[512];
+ mSystem->getDriverInfo(0, r_name, 511, 0);
+ r_name[511] = '\0';
+ LL_INFOS("AppInit") << "LLAudioEngine_FMODEX::init(): r_name=\"" << r_name << "\"" << LL_ENDL;
+
+ int latency = 100; // optimistic default - i suspect if sample rate is 0, everything breaks.
+ if ( r_samplerate != 0 )
+ latency = (int)(1000.0f * r_bufferlength * r_numbuffers / r_samplerate);
+ LL_INFOS("AppInit") << "LLAudioEngine_FMODEX::init(): latency=" << latency << "ms" << LL_ENDL;
+
+ mInited = true;
+
+ LL_INFOS("AppInit") << "LLAudioEngine_FMODEX::init(): initialization complete." << LL_ENDL;
+
+ return true;
+}
+
+
+std::string LLAudioEngine_FMODEX::getDriverName(bool verbose)
+{
+ llassert_always(mSystem);
+ if (verbose)
+ {
+ U32 version;
+ if(!Check_FMOD_Error(mSystem->getVersion(&version), "FMOD::System::getVersion"))
+ {
+ return llformat("FMOD Ex %1x.%02x.%02x", version >> 16, version >> 8 & 0x000000FF, version & 0x000000FF);
+ }
+ }
+ return "FMODEx";
+}
+
+
+void LLAudioEngine_FMODEX::allocateListener(void)
+{
+ mListenerp = (LLListener *) new LLListener_FMODEX(mSystem);
+ if (!mListenerp)
+ {
+ llwarns << "Listener creation failed" << llendl;
+ }
+}
+
+
+void LLAudioEngine_FMODEX::shutdown()
+{
+ stopInternetStream();
+
+ llinfos << "About to LLAudioEngine::shutdown()" << llendl;
+ LLAudioEngine::shutdown();
+
+ llinfos << "LLAudioEngine_FMODEX::shutdown() closing FMOD Ex" << llendl;
+ if ( mSystem ) // speculative fix for MAINT-2657
+ {
+ mSystem->close();
+ mSystem->release();
+ }
+ llinfos << "LLAudioEngine_FMODEX::shutdown() done closing FMOD Ex" << llendl;
+
+ delete mListenerp;
+ mListenerp = NULL;
+}
+
+
+LLAudioBuffer * LLAudioEngine_FMODEX::createBuffer()
+{
+ return new LLAudioBufferFMODEX(mSystem);
+}
+
+
+LLAudioChannel * LLAudioEngine_FMODEX::createChannel()
+{
+ return new LLAudioChannelFMODEX(mSystem);
+}
+
+bool LLAudioEngine_FMODEX::initWind()
+{
+ mNextWindUpdate = 0.0;
+
+ if (!mWindDSP)
+ {
+ FMOD_DSP_DESCRIPTION dspdesc;
+ memset(&dspdesc, 0, sizeof(FMOD_DSP_DESCRIPTION)); //Set everything to zero
+ strncpy(dspdesc.name,"Wind Unit", sizeof(dspdesc.name)); //Set name to "Wind Unit"
+ dspdesc.channels=2;
+ dspdesc.read = &windCallback; //Assign callback.
+ if(Check_FMOD_Error(mSystem->createDSP(&dspdesc, &mWindDSP), "FMOD::createDSP"))
+ return false;
+
+ if(mWindGen)
+ delete mWindGen;
+
+ float frequency = 44100;
+ mWindDSP->getDefaults(&frequency,0,0,0);
+ mWindGen = new LLWindGen<MIXBUFFERFORMAT>((U32)frequency);
+ mWindDSP->setUserData((void*)mWindGen);
+ }
+
+ if (mWindDSP)
+ {
+ mSystem->playDSP(FMOD_CHANNEL_FREE, mWindDSP, false, 0);
+ return true;
+ }
+ return false;
+}
+
+
+void LLAudioEngine_FMODEX::cleanupWind()
+{
+ if (mWindDSP)
+ {
+ mWindDSP->remove();
+ mWindDSP->release();
+ mWindDSP = NULL;
+ }
+
+ delete mWindGen;
+ mWindGen = NULL;
+}
+
+
+//-----------------------------------------------------------------------
+void LLAudioEngine_FMODEX::updateWind(LLVector3 wind_vec, F32 camera_height_above_water)
+{
+ LLVector3 wind_pos;
+ F64 pitch;
+ F64 center_freq;
+
+ if (!mEnableWind)
+ {
+ return;
+ }
+
+ if (mWindUpdateTimer.checkExpirationAndReset(LL_WIND_UPDATE_INTERVAL))
+ {
+
+ // wind comes in as Linden coordinate (+X = forward, +Y = left, +Z = up)
+ // need to convert this to the conventional orientation DS3D and OpenAL use
+ // where +X = right, +Y = up, +Z = backwards
+
+ wind_vec.setVec(-wind_vec.mV[1], wind_vec.mV[2], -wind_vec.mV[0]);
+
+ // cerr << "Wind update" << endl;
+
+ pitch = 1.0 + mapWindVecToPitch(wind_vec);
+ center_freq = 80.0 * pow(pitch,2.5*(mapWindVecToGain(wind_vec)+1.0));
+
+ mWindGen->mTargetFreq = (F32)center_freq;
+ mWindGen->mTargetGain = (F32)mapWindVecToGain(wind_vec) * mMaxWindGain;
+ mWindGen->mTargetPanGainR = (F32)mapWindVecToPan(wind_vec);
+ }
+}
+
+//-----------------------------------------------------------------------
+void LLAudioEngine_FMODEX::setInternalGain(F32 gain)
+{
+ if (!mInited)
+ {
+ return;
+ }
+
+ gain = llclamp( gain, 0.0f, 1.0f );
+
+ FMOD::ChannelGroup *master_group;
+ mSystem->getMasterChannelGroup(&master_group);
+
+ master_group->setVolume(gain);
+
+ LLStreamingAudioInterface *saimpl = getStreamingAudioImpl();
+ if ( saimpl )
+ {
+ // fmod likes its streaming audio channel gain re-asserted after
+ // master volume change.
+ saimpl->setGain(saimpl->getGain());
+ }
+}
+
+//
+// LLAudioChannelFMODEX implementation
+//
+
+LLAudioChannelFMODEX::LLAudioChannelFMODEX(FMOD::System *system) : LLAudioChannel(), mSystemp(system), mChannelp(NULL), mLastSamplePos(0)
+{
+}
+
+
+LLAudioChannelFMODEX::~LLAudioChannelFMODEX()
+{
+ cleanup();
+}
+
+bool LLAudioChannelFMODEX::updateBuffer()
+{
+ if (LLAudioChannel::updateBuffer())
+ {
+ // Base class update returned true, which means that we need to actually
+ // set up the channel for a different buffer.
+
+ LLAudioBufferFMODEX *bufferp = (LLAudioBufferFMODEX *)mCurrentSourcep->getCurrentBuffer();
+
+ // Grab the FMOD sample associated with the buffer
+ FMOD::Sound *soundp = bufferp->getSound();
+ if (!soundp)
+ {
+ // This is bad, there should ALWAYS be a sound associated with a legit
+ // buffer.
+ llerrs << "No FMOD sound!" << llendl;
+ return false;
+ }
+
+
+ // Actually play the sound. Start it off paused so we can do all the necessary
+ // setup.
+ if(!mChannelp)
+ {
+ FMOD_RESULT result = getSystem()->playSound(FMOD_CHANNEL_FREE, soundp, true, &mChannelp);
+ Check_FMOD_Error(result, "FMOD::System::playSound");
+ }
+
+ //llinfos << "Setting up channel " << std::hex << mChannelID << std::dec << llendl;
+ }
+
+ // If we have a source for the channel, we need to update its gain.
+ if (mCurrentSourcep)
+ {
+ // SJB: warnings can spam and hurt framerate, disabling
+ //FMOD_RESULT result;
+
+ mChannelp->setVolume(getSecondaryGain() * mCurrentSourcep->getGain());
+ //Check_FMOD_Error(result, "FMOD::Channel::setVolume");
+
+ mChannelp->setMode(mCurrentSourcep->isLoop() ? FMOD_LOOP_NORMAL : FMOD_LOOP_OFF);
+ /*if(Check_FMOD_Error(result, "FMOD::Channel::setMode"))
+ {
+ S32 index;
+ mChannelp->getIndex(&index);
+ llwarns << "Channel " << index << "Source ID: " << mCurrentSourcep->getID()
+ << " at " << mCurrentSourcep->getPositionGlobal() << llendl;
+ }*/
+ }
+
+ return true;
+}
+
+
+void LLAudioChannelFMODEX::update3DPosition()
+{
+ if (!mChannelp)
+ {
+ // We're not actually a live channel (i.e., we're not playing back anything)
+ return;
+ }
+
+ LLAudioBufferFMODEX *bufferp = (LLAudioBufferFMODEX *)mCurrentBufferp;
+ if (!bufferp)
+ {
+ // We don't have a buffer associated with us (should really have been picked up
+ // by the above if.
+ return;
+ }
+
+ if (mCurrentSourcep->isAmbient())
+ {
+ // Ambient sound, don't need to do any positional updates.
+ set3DMode(false);
+ }
+ else
+ {
+ // Localized sound. Update the position and velocity of the sound.
+ set3DMode(true);
+
+ LLVector3 float_pos;
+ float_pos.setVec(mCurrentSourcep->getPositionGlobal());
+ FMOD_RESULT result = mChannelp->set3DAttributes((FMOD_VECTOR*)float_pos.mV, (FMOD_VECTOR*)mCurrentSourcep->getVelocity().mV);
+ Check_FMOD_Error(result, "FMOD::Channel::set3DAttributes");
+ }
+}
+
+
+void LLAudioChannelFMODEX::updateLoop()
+{
+ if (!mChannelp)
+ {
+ // May want to clear up the loop/sample counters.
+ return;
+ }
+
+ //
+ // Hack: We keep track of whether we looped or not by seeing when the
+ // sample position looks like it's going backwards. Not reliable; may
+ // yield false negatives.
+ //
+ U32 cur_pos;
+ mChannelp->getPosition(&cur_pos,FMOD_TIMEUNIT_PCMBYTES);
+
+ if (cur_pos < (U32)mLastSamplePos)
+ {
+ mLoopedThisFrame = true;
+ }
+ mLastSamplePos = cur_pos;
+}
+
+
+void LLAudioChannelFMODEX::cleanup()
+{
+ if (!mChannelp)
+ {
+ //llinfos << "Aborting cleanup with no channel handle." << llendl;
+ return;
+ }
+
+ //llinfos << "Cleaning up channel: " << mChannelID << llendl;
+ Check_FMOD_Error(mChannelp->stop(),"FMOD::Channel::stop");
+
+ mCurrentBufferp = NULL;
+ mChannelp = NULL;
+}
+
+
+void LLAudioChannelFMODEX::play()
+{
+ if (!mChannelp)
+ {
+ llwarns << "Playing without a channel handle, aborting" << llendl;
+ return;
+ }
+
+ Check_FMOD_Error(mChannelp->setPaused(false), "FMOD::Channel::pause");
+
+ getSource()->setPlayedOnce(true);
+
+ if(LLAudioEngine_FMODEX::mChannelGroups[getSource()->getType()])
+ mChannelp->setChannelGroup(LLAudioEngine_FMODEX::mChannelGroups[getSource()->getType()]);
+}
+
+
+void LLAudioChannelFMODEX::playSynced(LLAudioChannel *channelp)
+{
+ LLAudioChannelFMODEX *fmod_channelp = (LLAudioChannelFMODEX*)channelp;
+ if (!(fmod_channelp->mChannelp && mChannelp))
+ {
+ // Don't have channels allocated to both the master and the slave
+ return;
+ }
+
+ U32 cur_pos;
+ if(Check_FMOD_Error(mChannelp->getPosition(&cur_pos,FMOD_TIMEUNIT_PCMBYTES), "Unable to retrieve current position"))
+ return;
+
+ cur_pos %= mCurrentBufferp->getLength();
+
+ // Try to match the position of our sync master
+ Check_FMOD_Error(mChannelp->setPosition(cur_pos,FMOD_TIMEUNIT_PCMBYTES),"Unable to set current position");
+
+ // Start us playing
+ play();
+}
+
+
+bool LLAudioChannelFMODEX::isPlaying()
+{
+ if (!mChannelp)
+ {
+ return false;
+ }
+
+ bool paused, playing;
+ mChannelp->getPaused(&paused);
+ mChannelp->isPlaying(&playing);
+ return !paused && playing;
+}
+
+
+//
+// LLAudioChannelFMODEX implementation
+//
+
+
+LLAudioBufferFMODEX::LLAudioBufferFMODEX(FMOD::System *system) : mSystemp(system), mSoundp(NULL)
+{
+}
+
+
+LLAudioBufferFMODEX::~LLAudioBufferFMODEX()
+{
+ if(mSoundp)
+ {
+ mSoundp->release();
+ mSoundp = NULL;
+ }
+}
+
+
+bool LLAudioBufferFMODEX::loadWAV(const std::string& filename)
+{
+ // Try to open a wav file from disk. This will eventually go away, as we don't
+ // really want to block doing this.
+ if (filename.empty())
+ {
+ // invalid filename, abort.
+ return false;
+ }
+
+ if (!LLAPRFile::isExist(filename, NULL, LL_APR_RPB))
+ {
+ // File not found, abort.
+ return false;
+ }
+
+ if (mSoundp)
+ {
+ // If there's already something loaded in this buffer, clean it up.
+ mSoundp->release();
+ mSoundp = NULL;
+ }
+
+ FMOD_MODE base_mode = FMOD_LOOP_NORMAL | FMOD_SOFTWARE;
+ FMOD_CREATESOUNDEXINFO exinfo;
+ memset(&exinfo,0,sizeof(exinfo));
+ exinfo.cbsize = sizeof(exinfo);
+ exinfo.suggestedsoundtype = FMOD_SOUND_TYPE_WAV; //Hint to speed up loading.
+ // Load up the wav file into an fmod sample
+#if LL_WINDOWS
+ FMOD_RESULT result = getSystem()->createSound((const char*)utf8str_to_utf16str(filename).c_str(), base_mode | FMOD_UNICODE, &exinfo, &mSoundp);
+#else
+ FMOD_RESULT result = getSystem()->createSound(filename.c_str(), base_mode, &exinfo, &mSoundp);
+#endif
+
+ if (result != FMOD_OK)
+ {
+ // We failed to load the file for some reason.
+ llwarns << "Could not load data '" << filename << "': " << FMOD_ErrorString(result) << llendl;
+
+ //
+ // If we EVER want to load wav files provided by end users, we need
+ // to rethink this!
+ //
+ // file is probably corrupt - remove it.
+ LLFile::remove(filename);
+ return false;
+ }
+
+ // Everything went well, return true
+ return true;
+}
+
+
+U32 LLAudioBufferFMODEX::getLength()
+{
+ if (!mSoundp)
+ {
+ return 0;
+ }
+
+ U32 length;
+ mSoundp->getLength(&length, FMOD_TIMEUNIT_PCMBYTES);
+ return length;
+}
+
+
+void LLAudioChannelFMODEX::set3DMode(bool use3d)
+{
+ FMOD_MODE current_mode;
+ if(mChannelp->getMode(&current_mode) != FMOD_OK)
+ return;
+ FMOD_MODE new_mode = current_mode;
+ new_mode &= ~(use3d ? FMOD_2D : FMOD_3D);
+ new_mode |= use3d ? FMOD_3D : FMOD_2D;
+
+ if(current_mode != new_mode)
+ {
+ mChannelp->setMode(new_mode);
+ }
+}
+
+
+FMOD_RESULT F_CALLBACK windCallback(FMOD_DSP_STATE *dsp_state, float *originalbuffer, float *newbuffer, unsigned int length, int inchannels, int outchannels)
+{
+ // originalbuffer = fmod's original mixbuffer.
+ // newbuffer = the buffer passed from the previous DSP unit.
+ // length = length in samples at this mix time.
+ // userdata = user parameter passed through in FSOUND_DSP_Create.
+
+ LLWindGen<LLAudioEngine_FMODEX::MIXBUFFERFORMAT> *windgen;
+ FMOD::DSP *thisdsp = (FMOD::DSP *)dsp_state->instance;
+
+ thisdsp->getUserData((void **)&windgen);
+ S32 channels, configwidth, configheight;
+ thisdsp->getInfo(0, 0, &channels, &configwidth, &configheight);
+
+ windgen->windGenerate((LLAudioEngine_FMODEX::MIXBUFFERFORMAT *)newbuffer, length);
+
+ return FMOD_OK;
+}
diff --git a/indra/llaudio/llaudioengine_fmodex.h b/indra/llaudio/llaudioengine_fmodex.h
new file mode 100644
index 0000000000..415a9ed0ef
--- /dev/null
+++ b/indra/llaudio/llaudioengine_fmodex.h
@@ -0,0 +1,128 @@
+/**
+ * @file audioengine_fmodex.h
+ * @brief Definition of LLAudioEngine class abstracting the audio
+ * support as a FMODEX implementation
+ *
+ * $LicenseInfo:firstyear=2002&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$
+ */
+
+#ifndef LL_AUDIOENGINE_FMODEX_H
+#define LL_AUDIOENGINE_FMODEX_H
+
+#include "llaudioengine.h"
+#include "llwindgen.h"
+
+//Stubs
+class LLAudioStreamManagerFMODEX;
+namespace FMOD
+{
+ class System;
+ class Channel;
+ class ChannelGroup;
+ class Sound;
+ class DSP;
+}
+
+//Interfaces
+class LLAudioEngine_FMODEX : public LLAudioEngine
+{
+public:
+ LLAudioEngine_FMODEX(bool enable_profiler);
+ virtual ~LLAudioEngine_FMODEX();
+
+ // initialization/startup/shutdown
+ virtual bool init(const S32 num_channels, void *user_data);
+ virtual std::string getDriverName(bool verbose);
+ virtual void allocateListener();
+
+ virtual void shutdown();
+
+ /*virtual*/ bool initWind();
+ /*virtual*/ void cleanupWind();
+
+ /*virtual*/void updateWind(LLVector3 direction, F32 camera_height_above_water);
+
+ typedef F32 MIXBUFFERFORMAT;
+
+ FMOD::System *getSystem() const {return mSystem;}
+protected:
+ /*virtual*/ LLAudioBuffer *createBuffer(); // Get a free buffer, or flush an existing one if you have to.
+ /*virtual*/ LLAudioChannel *createChannel(); // Create a new audio channel.
+
+ /*virtual*/ void setInternalGain(F32 gain);
+
+ bool mInited;
+
+ LLWindGen<MIXBUFFERFORMAT> *mWindGen;
+
+ FMOD::DSP *mWindDSP;
+ FMOD::System *mSystem;
+ bool mEnableProfiler;
+
+public:
+ static FMOD::ChannelGroup *mChannelGroups[LLAudioEngine::AUDIO_TYPE_COUNT];
+};
+
+
+class LLAudioChannelFMODEX : public LLAudioChannel
+{
+public:
+ LLAudioChannelFMODEX(FMOD::System *audioengine);
+ virtual ~LLAudioChannelFMODEX();
+
+protected:
+ /*virtual*/ void play();
+ /*virtual*/ void playSynced(LLAudioChannel *channelp);
+ /*virtual*/ void cleanup();
+ /*virtual*/ bool isPlaying();
+
+ /*virtual*/ bool updateBuffer();
+ /*virtual*/ void update3DPosition();
+ /*virtual*/ void updateLoop();
+
+ void set3DMode(bool use3d);
+protected:
+ FMOD::System *getSystem() const {return mSystemp;}
+ FMOD::System *mSystemp;
+ FMOD::Channel *mChannelp;
+ S32 mLastSamplePos;
+};
+
+
+class LLAudioBufferFMODEX : public LLAudioBuffer
+{
+public:
+ LLAudioBufferFMODEX(FMOD::System *audioengine);
+ virtual ~LLAudioBufferFMODEX();
+
+ /*virtual*/ bool loadWAV(const std::string& filename);
+ /*virtual*/ U32 getLength();
+ friend class LLAudioChannelFMODEX;
+protected:
+ FMOD::System *getSystem() const {return mSystemp;}
+ FMOD::System *mSystemp;
+ FMOD::Sound *getSound() const{ return mSoundp; }
+ FMOD::Sound *mSoundp;
+};
+
+
+#endif // LL_AUDIOENGINE_FMODEX_H
diff --git a/indra/llaudio/llaudioengine_openal.cpp b/indra/llaudio/llaudioengine_openal.cpp
index 34a057dcc0..34a057dcc0 100644..100755
--- a/indra/llaudio/llaudioengine_openal.cpp
+++ b/indra/llaudio/llaudioengine_openal.cpp
diff --git a/indra/llaudio/llaudioengine_openal.h b/indra/llaudio/llaudioengine_openal.h
index 6639d9dfe6..6639d9dfe6 100644..100755
--- a/indra/llaudio/llaudioengine_openal.h
+++ b/indra/llaudio/llaudioengine_openal.h
diff --git a/indra/llaudio/lllistener.cpp b/indra/llaudio/lllistener.cpp
index df2366c8c2..df2366c8c2 100644..100755
--- a/indra/llaudio/lllistener.cpp
+++ b/indra/llaudio/lllistener.cpp
diff --git a/indra/llaudio/lllistener.h b/indra/llaudio/lllistener.h
index 41836bf039..41836bf039 100644..100755
--- a/indra/llaudio/lllistener.h
+++ b/indra/llaudio/lllistener.h
diff --git a/indra/llaudio/lllistener_ds3d.h b/indra/llaudio/lllistener_ds3d.h
index 9150ccd5b9..9150ccd5b9 100644..100755
--- a/indra/llaudio/lllistener_ds3d.h
+++ b/indra/llaudio/lllistener_ds3d.h
diff --git a/indra/llaudio/lllistener_fmod.cpp b/indra/llaudio/lllistener_fmod.cpp
deleted file mode 100644
index 0138f4345e..0000000000
--- a/indra/llaudio/lllistener_fmod.cpp
+++ /dev/null
@@ -1,125 +0,0 @@
-/**
- * @file listener_fmod.cpp
- * @brief implementation of LISTENER class abstracting the audio
- * support as a FMOD 3D implementation (windows only)
- *
- * $LicenseInfo:firstyear=2002&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 "llaudioengine.h"
-#include "lllistener_fmod.h"
-#include "fmod.h"
-
-//-----------------------------------------------------------------------
-// constructor
-//-----------------------------------------------------------------------
-LLListener_FMOD::LLListener_FMOD()
-{
- init();
-}
-
-//-----------------------------------------------------------------------
-LLListener_FMOD::~LLListener_FMOD()
-{
-}
-
-//-----------------------------------------------------------------------
-void LLListener_FMOD::init(void)
-{
- // do inherited
- LLListener::init();
- mDopplerFactor = 1.0f;
- mRolloffFactor = 1.0f;
-}
-
-//-----------------------------------------------------------------------
-void LLListener_FMOD::translate(LLVector3 offset)
-{
- LLListener::translate(offset);
-
- FSOUND_3D_Listener_SetAttributes(mPosition.mV, NULL, mListenAt.mV[0],mListenAt.mV[1],mListenAt.mV[2], mListenUp.mV[0],mListenUp.mV[1],mListenUp.mV[2]);
-}
-
-//-----------------------------------------------------------------------
-void LLListener_FMOD::setPosition(LLVector3 pos)
-{
- LLListener::setPosition(pos);
-
- FSOUND_3D_Listener_SetAttributes(pos.mV, NULL, mListenAt.mV[0],mListenAt.mV[1],mListenAt.mV[2], mListenUp.mV[0],mListenUp.mV[1],mListenUp.mV[2]);
-}
-
-//-----------------------------------------------------------------------
-void LLListener_FMOD::setVelocity(LLVector3 vel)
-{
- LLListener::setVelocity(vel);
-
- FSOUND_3D_Listener_SetAttributes(NULL, vel.mV, mListenAt.mV[0],mListenAt.mV[1],mListenAt.mV[2], mListenUp.mV[0],mListenUp.mV[1],mListenUp.mV[2]);
-}
-
-//-----------------------------------------------------------------------
-void LLListener_FMOD::orient(LLVector3 up, LLVector3 at)
-{
- LLListener::orient(up, at);
-
- // Welcome to the transition between right and left
- // (coordinate systems, that is)
- // Leaving the at vector alone results in a L/R reversal
- // since DX is left-handed and we (LL, OpenGL, OpenAL) are right-handed
- at = -at;
-
- FSOUND_3D_Listener_SetAttributes(NULL, NULL, at.mV[0],at.mV[1],at.mV[2], up.mV[0],up.mV[1],up.mV[2]);
-}
-
-//-----------------------------------------------------------------------
-void LLListener_FMOD::commitDeferredChanges()
-{
- FSOUND_Update();
-}
-
-
-void LLListener_FMOD::setRolloffFactor(F32 factor)
-{
- mRolloffFactor = factor;
- FSOUND_3D_SetRolloffFactor(factor);
-}
-
-
-F32 LLListener_FMOD::getRolloffFactor()
-{
- return mRolloffFactor;
-}
-
-
-void LLListener_FMOD::setDopplerFactor(F32 factor)
-{
- mDopplerFactor = factor;
- FSOUND_3D_SetDopplerFactor(factor);
-}
-
-
-F32 LLListener_FMOD::getDopplerFactor()
-{
- return mDopplerFactor;
-}
-
-
diff --git a/indra/llaudio/lllistener_fmod.h b/indra/llaudio/lllistener_fmod.h
deleted file mode 100644
index 818da05d51..0000000000
--- a/indra/llaudio/lllistener_fmod.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/**
- * @file listener_fmod.h
- * @brief Description of LISTENER class abstracting the audio support
- * as an FMOD 3D implementation (windows and Linux)
- *
- * $LicenseInfo:firstyear=2002&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$
- */
-
-#ifndef LL_LISTENER_FMOD_H
-#define LL_LISTENER_FMOD_H
-
-#include "lllistener.h"
-
-class LLListener_FMOD : public LLListener
-{
- public:
- LLListener_FMOD();
- virtual ~LLListener_FMOD();
- virtual void init();
-
- virtual void translate(LLVector3 offset);
- virtual void setPosition(LLVector3 pos);
- virtual void setVelocity(LLVector3 vel);
- virtual void orient(LLVector3 up, LLVector3 at);
- virtual void commitDeferredChanges();
-
- virtual void setDopplerFactor(F32 factor);
- virtual F32 getDopplerFactor();
- virtual void setRolloffFactor(F32 factor);
- virtual F32 getRolloffFactor();
-
- protected:
- F32 mDopplerFactor;
- F32 mRolloffFactor;
-};
-
-#endif
-
-
diff --git a/indra/llaudio/lllistener_fmodex.cpp b/indra/llaudio/lllistener_fmodex.cpp
new file mode 100644
index 0000000000..2509a7aebc
--- /dev/null
+++ b/indra/llaudio/lllistener_fmodex.cpp
@@ -0,0 +1,135 @@
+/**
+ * @file listener_fmodex.cpp
+ * @brief Implementation of LISTENER class abstracting the audio
+ * support as a FMODEX implementation
+ *
+ * $LicenseInfo:firstyear=2002&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 "llaudioengine.h"
+#include "lllistener_fmodex.h"
+#include "fmod.hpp"
+
+//-----------------------------------------------------------------------
+// constructor
+//-----------------------------------------------------------------------
+LLListener_FMODEX::LLListener_FMODEX(FMOD::System *system)
+{
+ mSystem = system;
+ init();
+}
+
+//-----------------------------------------------------------------------
+LLListener_FMODEX::~LLListener_FMODEX()
+{
+}
+
+//-----------------------------------------------------------------------
+void LLListener_FMODEX::init(void)
+{
+ // do inherited
+ LLListener::init();
+ mDopplerFactor = 1.0f;
+ mRolloffFactor = 1.0f;
+}
+
+//-----------------------------------------------------------------------
+void LLListener_FMODEX::translate(LLVector3 offset)
+{
+ LLListener::translate(offset);
+
+ mSystem->set3DListenerAttributes(0, (FMOD_VECTOR*)mPosition.mV, NULL, (FMOD_VECTOR*)mListenAt.mV, (FMOD_VECTOR*)mListenUp.mV);
+}
+
+//-----------------------------------------------------------------------
+void LLListener_FMODEX::setPosition(LLVector3 pos)
+{
+ LLListener::setPosition(pos);
+
+ mSystem->set3DListenerAttributes(0, (FMOD_VECTOR*)mPosition.mV, NULL, (FMOD_VECTOR*)mListenAt.mV, (FMOD_VECTOR*)mListenUp.mV);
+}
+
+//-----------------------------------------------------------------------
+void LLListener_FMODEX::setVelocity(LLVector3 vel)
+{
+ LLListener::setVelocity(vel);
+
+ mSystem->set3DListenerAttributes(0, NULL, (FMOD_VECTOR*)mVelocity.mV, (FMOD_VECTOR*)mListenAt.mV, (FMOD_VECTOR*)mListenUp.mV);
+}
+
+//-----------------------------------------------------------------------
+void LLListener_FMODEX::orient(LLVector3 up, LLVector3 at)
+{
+ LLListener::orient(up, at);
+
+ // Welcome to the transition between right and left
+ // (coordinate systems, that is)
+ // Leaving the at vector alone results in a L/R reversal
+ // since DX is left-handed and we (LL, OpenGL, OpenAL) are right-handed
+ at = -at;
+
+ mSystem->set3DListenerAttributes(0, NULL, NULL, (FMOD_VECTOR*)at.mV, (FMOD_VECTOR*)up.mV);
+}
+
+//-----------------------------------------------------------------------
+void LLListener_FMODEX::commitDeferredChanges()
+{
+ mSystem->update();
+}
+
+
+void LLListener_FMODEX::setRolloffFactor(F32 factor)
+{
+ //An internal FMODEx optimization skips 3D updates if there have not been changes to the 3D sound environment.
+ //Sadly, a change in rolloff is not accounted for, thus we must touch the listener properties as well.
+ //In short: Changing the position ticks a dirtyflag inside fmodex, which makes it not skip 3D processing next update call.
+ if(mRolloffFactor != factor)
+ {
+ LLVector3 pos = mVelocity - LLVector3(0.f,0.f,.1f);
+ mSystem->set3DListenerAttributes(0, (FMOD_VECTOR*)pos.mV, NULL, NULL, NULL);
+ mSystem->set3DListenerAttributes(0, (FMOD_VECTOR*)mVelocity.mV, NULL, NULL, NULL);
+ }
+ mRolloffFactor = factor;
+ mSystem->set3DSettings(mDopplerFactor, 1.f, mRolloffFactor);
+}
+
+
+F32 LLListener_FMODEX::getRolloffFactor()
+{
+ return mRolloffFactor;
+}
+
+
+void LLListener_FMODEX::setDopplerFactor(F32 factor)
+{
+ mDopplerFactor = factor;
+ mSystem->set3DSettings(mDopplerFactor, 1.f, mRolloffFactor);
+}
+
+
+F32 LLListener_FMODEX::getDopplerFactor()
+{
+ return mDopplerFactor;
+}
+
+
diff --git a/indra/llaudio/lllistener_fmodex.h b/indra/llaudio/lllistener_fmodex.h
new file mode 100644
index 0000000000..073b65d53a
--- /dev/null
+++ b/indra/llaudio/lllistener_fmodex.h
@@ -0,0 +1,65 @@
+/**
+ * @file listener_fmodex.h
+ * @brief Description of LISTENER class abstracting the audio support
+ * as an FMOD 3D implementation (windows and Linux)
+ *
+ * $LicenseInfo:firstyear=2002&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$
+ */
+
+#ifndef LL_LISTENER_FMODEX_H
+#define LL_LISTENER_FMODEX_H
+
+#include "lllistener.h"
+
+//Stubs
+namespace FMOD
+{
+ class System;
+}
+
+//Interfaces
+class LLListener_FMODEX : public LLListener
+{
+ public:
+ LLListener_FMODEX(FMOD::System *system);
+ virtual ~LLListener_FMODEX();
+ virtual void init();
+
+ virtual void translate(LLVector3 offset);
+ virtual void setPosition(LLVector3 pos);
+ virtual void setVelocity(LLVector3 vel);
+ virtual void orient(LLVector3 up, LLVector3 at);
+ virtual void commitDeferredChanges();
+
+ virtual void setDopplerFactor(F32 factor);
+ virtual F32 getDopplerFactor();
+ virtual void setRolloffFactor(F32 factor);
+ virtual F32 getRolloffFactor();
+ protected:
+ FMOD::System *mSystem;
+ F32 mDopplerFactor;
+ F32 mRolloffFactor;
+};
+
+#endif
+
+
diff --git a/indra/llaudio/lllistener_openal.cpp b/indra/llaudio/lllistener_openal.cpp
index b3d4b02f09..b3d4b02f09 100644..100755
--- a/indra/llaudio/lllistener_openal.cpp
+++ b/indra/llaudio/lllistener_openal.cpp
diff --git a/indra/llaudio/lllistener_openal.h b/indra/llaudio/lllistener_openal.h
index cb163b11a5..cb163b11a5 100644..100755
--- a/indra/llaudio/lllistener_openal.h
+++ b/indra/llaudio/lllistener_openal.h
diff --git a/indra/llaudio/llstreamingaudio.h b/indra/llaudio/llstreamingaudio.h
index 20104af744..93479f9d59 100644..100755
--- a/indra/llaudio/llstreamingaudio.h
+++ b/indra/llaudio/llstreamingaudio.h
@@ -45,6 +45,8 @@ class LLStreamingAudioInterface
virtual void setGain(F32 vol) = 0;
virtual F32 getGain() = 0;
virtual std::string getURL() = 0;
+ virtual bool supportsAdjustableBufferSizes(){return false;}
+ virtual void setBufferSizes(U32 streambuffertime, U32 decodebuffertime){};
};
#endif // LL_STREAMINGAUDIO_H
diff --git a/indra/llaudio/llstreamingaudio_fmod.cpp b/indra/llaudio/llstreamingaudio_fmod.cpp
deleted file mode 100644
index bcdea771a7..0000000000
--- a/indra/llaudio/llstreamingaudio_fmod.cpp
+++ /dev/null
@@ -1,356 +0,0 @@
-/**
- * @file streamingaudio_fmod.cpp
- * @brief LLStreamingAudio_FMOD implementation
- *
- * $LicenseInfo:firstyear=2009&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 "llmath.h"
-
-#include "fmod.h"
-#include "fmod_errors.h"
-
-#include "llstreamingaudio_fmod.h"
-
-
-class LLAudioStreamManagerFMOD
-{
-public:
- LLAudioStreamManagerFMOD(const std::string& url);
- int startStream();
- bool stopStream(); // Returns true if the stream was successfully stopped.
- bool ready();
-
- const std::string& getURL() { return mInternetStreamURL; }
-
- int getOpenState();
-protected:
- FSOUND_STREAM* mInternetStream;
- bool mReady;
-
- std::string mInternetStreamURL;
-};
-
-
-
-//---------------------------------------------------------------------------
-// Internet Streaming
-//---------------------------------------------------------------------------
-LLStreamingAudio_FMOD::LLStreamingAudio_FMOD() :
- mCurrentInternetStreamp(NULL),
- mFMODInternetStreamChannel(-1),
- mGain(1.0f)
-{
- // Number of milliseconds of audio to buffer for the audio card.
- // Must be larger than the usual Second Life frame stutter time.
- FSOUND_Stream_SetBufferSize(200);
-
- // Here's where we set the size of the network buffer and some buffering
- // parameters. In this case we want a network buffer of 16k, we want it
- // to prebuffer 40% of that when we first connect, and we want it
- // to rebuffer 80% of that whenever we encounter a buffer underrun.
-
- // Leave the net buffer properties at the default.
- //FSOUND_Stream_Net_SetBufferProperties(20000, 40, 80);
-}
-
-
-LLStreamingAudio_FMOD::~LLStreamingAudio_FMOD()
-{
- // nothing interesting/safe to do.
-}
-
-
-void LLStreamingAudio_FMOD::start(const std::string& url)
-{
- //if (!mInited)
- //{
- // llwarns << "startInternetStream before audio initialized" << llendl;
- // return;
- //}
-
- // "stop" stream but don't clear url, etc. in case url == mInternetStreamURL
- stop();
-
- if (!url.empty())
- {
- llinfos << "Starting internet stream: " << url << llendl;
- mCurrentInternetStreamp = new LLAudioStreamManagerFMOD(url);
- mURL = url;
- }
- else
- {
- llinfos << "Set internet stream to null" << llendl;
- mURL.clear();
- }
-}
-
-
-void LLStreamingAudio_FMOD::update()
-{
- // Kill dead internet streams, if possible
- std::list<LLAudioStreamManagerFMOD *>::iterator iter;
- for (iter = mDeadStreams.begin(); iter != mDeadStreams.end();)
- {
- LLAudioStreamManagerFMOD *streamp = *iter;
- if (streamp->stopStream())
- {
- llinfos << "Closed dead stream" << llendl;
- delete streamp;
- mDeadStreams.erase(iter++);
- }
- else
- {
- iter++;
- }
- }
-
- // Don't do anything if there are no streams playing
- if (!mCurrentInternetStreamp)
- {
- return;
- }
-
- int open_state = mCurrentInternetStreamp->getOpenState();
-
- if (!open_state)
- {
- // Stream is live
-
- // start the stream if it's ready
- if (mFMODInternetStreamChannel < 0)
- {
- mFMODInternetStreamChannel = mCurrentInternetStreamp->startStream();
-
- if (mFMODInternetStreamChannel != -1)
- {
- // Reset volume to previously set volume
- setGain(getGain());
- FSOUND_SetPaused(mFMODInternetStreamChannel, false);
- }
- }
- }
-
- switch(open_state)
- {
- default:
- case 0:
- // success
- break;
- case -1:
- // stream handle is invalid
- llwarns << "InternetStream - invalid handle" << llendl;
- stop();
- return;
- case -2:
- // opening
- break;
- case -3:
- // failed to open, file not found, perhaps
- llwarns << "InternetStream - failed to open" << llendl;
- stop();
- return;
- case -4:
- // connecting
- break;
- case -5:
- // buffering
- break;
- }
-
-}
-
-void LLStreamingAudio_FMOD::stop()
-{
- if (mFMODInternetStreamChannel != -1)
- {
- FSOUND_SetPaused(mFMODInternetStreamChannel, true);
- FSOUND_SetPriority(mFMODInternetStreamChannel, 0);
- mFMODInternetStreamChannel = -1;
- }
-
- if (mCurrentInternetStreamp)
- {
- llinfos << "Stopping internet stream: " << mCurrentInternetStreamp->getURL() << llendl;
- if (mCurrentInternetStreamp->stopStream())
- {
- delete mCurrentInternetStreamp;
- }
- else
- {
- llwarns << "Pushing stream to dead list: " << mCurrentInternetStreamp->getURL() << llendl;
- mDeadStreams.push_back(mCurrentInternetStreamp);
- }
- mCurrentInternetStreamp = NULL;
- //mURL.clear();
- }
-}
-
-void LLStreamingAudio_FMOD::pause(int pauseopt)
-{
- if (pauseopt < 0)
- {
- pauseopt = mCurrentInternetStreamp ? 1 : 0;
- }
-
- if (pauseopt)
- {
- if (mCurrentInternetStreamp)
- {
- stop();
- }
- }
- else
- {
- start(getURL());
- }
-}
-
-
-// A stream is "playing" if it has been requested to start. That
-// doesn't necessarily mean audio is coming out of the speakers.
-int LLStreamingAudio_FMOD::isPlaying()
-{
- if (mCurrentInternetStreamp)
- {
- return 1; // Active and playing
- }
- else if (!mURL.empty())
- {
- return 2; // "Paused"
- }
- else
- {
- return 0;
- }
-}
-
-
-F32 LLStreamingAudio_FMOD::getGain()
-{
- return mGain;
-}
-
-
-std::string LLStreamingAudio_FMOD::getURL()
-{
- return mURL;
-}
-
-
-void LLStreamingAudio_FMOD::setGain(F32 vol)
-{
- mGain = vol;
-
- if (mFMODInternetStreamChannel != -1)
- {
- vol = llclamp(vol * vol, 0.f, 1.f);
- int vol_int = llround(vol * 255.f);
- FSOUND_SetVolumeAbsolute(mFMODInternetStreamChannel, vol_int);
- }
-}
-
-
-///////////////////////////////////////////////////////
-// manager of possibly-multiple internet audio streams
-
-LLAudioStreamManagerFMOD::LLAudioStreamManagerFMOD(const std::string& url) :
- mInternetStream(NULL),
- mReady(false)
-{
- mInternetStreamURL = url;
- mInternetStream = FSOUND_Stream_Open(url.c_str(), FSOUND_NORMAL | FSOUND_NONBLOCKING, 0, 0);
- if (!mInternetStream)
- {
- llwarns << "Couldn't open fmod stream, error "
- << FMOD_ErrorString(FSOUND_GetError())
- << llendl;
- mReady = false;
- return;
- }
-
- mReady = true;
-}
-
-int LLAudioStreamManagerFMOD::startStream()
-{
- // We need a live and opened stream before we try and play it.
- if (!mInternetStream || getOpenState())
- {
- llwarns << "No internet stream to start playing!" << llendl;
- return -1;
- }
-
- // Make sure the stream is set to 2D mode.
- FSOUND_Stream_SetMode(mInternetStream, FSOUND_2D);
-
- return FSOUND_Stream_PlayEx(FSOUND_FREE, mInternetStream, NULL, true);
-}
-
-bool LLAudioStreamManagerFMOD::stopStream()
-{
- if (mInternetStream)
- {
- int read_percent = 0;
- int status = 0;
- int bitrate = 0;
- unsigned int flags = 0x0;
- FSOUND_Stream_Net_GetStatus(mInternetStream, &status, &read_percent, &bitrate, &flags);
-
- bool close = true;
- switch (status)
- {
- case FSOUND_STREAM_NET_CONNECTING:
- close = false;
- break;
- case FSOUND_STREAM_NET_NOTCONNECTED:
- case FSOUND_STREAM_NET_BUFFERING:
- case FSOUND_STREAM_NET_READY:
- case FSOUND_STREAM_NET_ERROR:
- default:
- close = true;
- }
-
- if (close)
- {
- FSOUND_Stream_Close(mInternetStream);
- mInternetStream = NULL;
- return true;
- }
- else
- {
- return false;
- }
- }
- else
- {
- return true;
- }
-}
-
-int LLAudioStreamManagerFMOD::getOpenState()
-{
- int open_state = FSOUND_Stream_GetOpenState(mInternetStream);
- return open_state;
-}
diff --git a/indra/llaudio/llstreamingaudio_fmod.h b/indra/llaudio/llstreamingaudio_fmod.h
deleted file mode 100644
index 9970f0d03b..0000000000
--- a/indra/llaudio/llstreamingaudio_fmod.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/**
- * @file streamingaudio_fmod.h
- * @author Tofu Linden
- * @brief Definition of LLStreamingAudio_FMOD implementation
- *
- * $LicenseInfo:firstyear=2009&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$
- */
-
-#ifndef LL_STREAMINGAUDIO_FMOD_H
-#define LL_STREAMINGAUDIO_FMOD_H
-
-#include "stdtypes.h" // from llcommon
-
-#include "llstreamingaudio.h"
-
-class LLAudioStreamManagerFMOD;
-
-class LLStreamingAudio_FMOD : public LLStreamingAudioInterface
-{
- public:
- LLStreamingAudio_FMOD();
- /*virtual*/ ~LLStreamingAudio_FMOD();
-
- /*virtual*/ void start(const std::string& url);
- /*virtual*/ void stop();
- /*virtual*/ void pause(int pause);
- /*virtual*/ void update();
- /*virtual*/ int isPlaying();
- /*virtual*/ void setGain(F32 vol);
- /*virtual*/ F32 getGain();
- /*virtual*/ std::string getURL();
-
-private:
- LLAudioStreamManagerFMOD *mCurrentInternetStreamp;
- int mFMODInternetStreamChannel;
- std::list<LLAudioStreamManagerFMOD *> mDeadStreams;
-
- std::string mURL;
- F32 mGain;
-};
-
-
-#endif // LL_STREAMINGAUDIO_FMOD_H
diff --git a/indra/llaudio/llstreamingaudio_fmodex.cpp b/indra/llaudio/llstreamingaudio_fmodex.cpp
new file mode 100644
index 0000000000..42f30aa1c4
--- /dev/null
+++ b/indra/llaudio/llstreamingaudio_fmodex.cpp
@@ -0,0 +1,392 @@
+/**
+ * @file streamingaudio_fmodex.cpp
+ * @brief LLStreamingAudio_FMODEX implementation
+ *
+ * $LicenseInfo:firstyear=2002&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 "llmath.h"
+
+#include "fmod.hpp"
+#include "fmod_errors.h"
+
+#include "llstreamingaudio_fmodex.h"
+
+
+class LLAudioStreamManagerFMODEX
+{
+public:
+ LLAudioStreamManagerFMODEX(FMOD::System *system, const std::string& url);
+ FMOD::Channel* startStream();
+ bool stopStream(); // Returns true if the stream was successfully stopped.
+ bool ready();
+
+ const std::string& getURL() { return mInternetStreamURL; }
+
+ FMOD_OPENSTATE getOpenState(unsigned int* percentbuffered=NULL, bool* starving=NULL, bool* diskbusy=NULL);
+protected:
+ FMOD::System* mSystem;
+ FMOD::Channel* mStreamChannel;
+ FMOD::Sound* mInternetStream;
+ bool mReady;
+
+ std::string mInternetStreamURL;
+};
+
+
+
+//---------------------------------------------------------------------------
+// Internet Streaming
+//---------------------------------------------------------------------------
+LLStreamingAudio_FMODEX::LLStreamingAudio_FMODEX(FMOD::System *system) :
+ mSystem(system),
+ mCurrentInternetStreamp(NULL),
+ mFMODInternetStreamChannelp(NULL),
+ mGain(1.0f)
+{
+ // Number of milliseconds of audio to buffer for the audio card.
+ // Must be larger than the usual Second Life frame stutter time.
+ const U32 buffer_seconds = 10; //sec
+ const U32 estimated_bitrate = 128; //kbit/sec
+ mSystem->setStreamBufferSize(estimated_bitrate * buffer_seconds * 128/*bytes/kbit*/, FMOD_TIMEUNIT_RAWBYTES);
+
+ // Here's where we set the size of the network buffer and some buffering
+ // parameters. In this case we want a network buffer of 16k, we want it
+ // to prebuffer 40% of that when we first connect, and we want it
+ // to rebuffer 80% of that whenever we encounter a buffer underrun.
+
+ // Leave the net buffer properties at the default.
+ //FSOUND_Stream_Net_SetBufferProperties(20000, 40, 80);
+}
+
+
+LLStreamingAudio_FMODEX::~LLStreamingAudio_FMODEX()
+{
+ // nothing interesting/safe to do.
+}
+
+
+void LLStreamingAudio_FMODEX::start(const std::string& url)
+{
+ //if (!mInited)
+ //{
+ // llwarns << "startInternetStream before audio initialized" << llendl;
+ // return;
+ //}
+
+ // "stop" stream but don't clear url, etc. in case url == mInternetStreamURL
+ stop();
+
+ if (!url.empty())
+ {
+ llinfos << "Starting internet stream: " << url << llendl;
+ mCurrentInternetStreamp = new LLAudioStreamManagerFMODEX(mSystem,url);
+ mURL = url;
+ }
+ else
+ {
+ llinfos << "Set internet stream to null" << llendl;
+ mURL.clear();
+ }
+}
+
+
+void LLStreamingAudio_FMODEX::update()
+{
+ // Kill dead internet streams, if possible
+ std::list<LLAudioStreamManagerFMODEX *>::iterator iter;
+ for (iter = mDeadStreams.begin(); iter != mDeadStreams.end();)
+ {
+ LLAudioStreamManagerFMODEX *streamp = *iter;
+ if (streamp->stopStream())
+ {
+ llinfos << "Closed dead stream" << llendl;
+ delete streamp;
+ mDeadStreams.erase(iter++);
+ }
+ else
+ {
+ iter++;
+ }
+ }
+
+ // Don't do anything if there are no streams playing
+ if (!mCurrentInternetStreamp)
+ {
+ return;
+ }
+
+ unsigned int progress;
+ bool starving;
+ bool diskbusy;
+ FMOD_OPENSTATE open_state = mCurrentInternetStreamp->getOpenState(&progress, &starving, &diskbusy);
+
+ if (open_state == FMOD_OPENSTATE_READY)
+ {
+ // Stream is live
+
+ // start the stream if it's ready
+ if (!mFMODInternetStreamChannelp &&
+ (mFMODInternetStreamChannelp = mCurrentInternetStreamp->startStream()))
+ {
+ // Reset volume to previously set volume
+ setGain(getGain());
+ mFMODInternetStreamChannelp->setPaused(false);
+ }
+ }
+ else if(open_state == FMOD_OPENSTATE_ERROR)
+ {
+ stop();
+ return;
+ }
+
+ if(mFMODInternetStreamChannelp)
+ {
+ FMOD::Sound *sound = NULL;
+
+ if(mFMODInternetStreamChannelp->getCurrentSound(&sound) == FMOD_OK && sound)
+ {
+ FMOD_TAG tag;
+ S32 tagcount, dirtytagcount;
+
+ if(sound->getNumTags(&tagcount, &dirtytagcount) == FMOD_OK && dirtytagcount)
+ {
+ for(S32 i = 0; i < tagcount; ++i)
+ {
+ if(sound->getTag(NULL, i, &tag)!=FMOD_OK)
+ continue;
+
+ if (tag.type == FMOD_TAGTYPE_FMOD)
+ {
+ if (!strcmp(tag.name, "Sample Rate Change"))
+ {
+ llinfos << "Stream forced changing sample rate to " << *((float *)tag.data) << llendl;
+ mFMODInternetStreamChannelp->setFrequency(*((float *)tag.data));
+ }
+ continue;
+ }
+ }
+ }
+
+ if(starving)
+ {
+ bool paused = false;
+ mFMODInternetStreamChannelp->getPaused(&paused);
+ if(!paused)
+ {
+ llinfos << "Stream starvation detected! Pausing stream until buffer nearly full." << llendl;
+ llinfos << " (diskbusy="<<diskbusy<<")" << llendl;
+ llinfos << " (progress="<<progress<<")" << llendl;
+ mFMODInternetStreamChannelp->setPaused(true);
+ }
+ }
+ else if(progress > 80)
+ {
+ mFMODInternetStreamChannelp->setPaused(false);
+ }
+ }
+ }
+}
+
+void LLStreamingAudio_FMODEX::stop()
+{
+ if (mFMODInternetStreamChannelp)
+ {
+ mFMODInternetStreamChannelp->setPaused(true);
+ mFMODInternetStreamChannelp->setPriority(0);
+ mFMODInternetStreamChannelp = NULL;
+ }
+
+ if (mCurrentInternetStreamp)
+ {
+ llinfos << "Stopping internet stream: " << mCurrentInternetStreamp->getURL() << llendl;
+ if (mCurrentInternetStreamp->stopStream())
+ {
+ delete mCurrentInternetStreamp;
+ }
+ else
+ {
+ llwarns << "Pushing stream to dead list: " << mCurrentInternetStreamp->getURL() << llendl;
+ mDeadStreams.push_back(mCurrentInternetStreamp);
+ }
+ mCurrentInternetStreamp = NULL;
+ //mURL.clear();
+ }
+}
+
+void LLStreamingAudio_FMODEX::pause(int pauseopt)
+{
+ if (pauseopt < 0)
+ {
+ pauseopt = mCurrentInternetStreamp ? 1 : 0;
+ }
+
+ if (pauseopt)
+ {
+ if (mCurrentInternetStreamp)
+ {
+ stop();
+ }
+ }
+ else
+ {
+ start(getURL());
+ }
+}
+
+
+// A stream is "playing" if it has been requested to start. That
+// doesn't necessarily mean audio is coming out of the speakers.
+int LLStreamingAudio_FMODEX::isPlaying()
+{
+ if (mCurrentInternetStreamp)
+ {
+ return 1; // Active and playing
+ }
+ else if (!mURL.empty())
+ {
+ return 2; // "Paused"
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+
+F32 LLStreamingAudio_FMODEX::getGain()
+{
+ return mGain;
+}
+
+
+std::string LLStreamingAudio_FMODEX::getURL()
+{
+ return mURL;
+}
+
+
+void LLStreamingAudio_FMODEX::setGain(F32 vol)
+{
+ mGain = vol;
+
+ if (mFMODInternetStreamChannelp)
+ {
+ vol = llclamp(vol * vol, 0.f, 1.f); //should vol be squared here?
+
+ mFMODInternetStreamChannelp->setVolume(vol);
+ }
+}
+
+///////////////////////////////////////////////////////
+// manager of possibly-multiple internet audio streams
+
+LLAudioStreamManagerFMODEX::LLAudioStreamManagerFMODEX(FMOD::System *system, const std::string& url) :
+ mSystem(system),
+ mStreamChannel(NULL),
+ mInternetStream(NULL),
+ mReady(false)
+{
+ mInternetStreamURL = url;
+
+ FMOD_RESULT result = mSystem->createStream(url.c_str(), FMOD_2D | FMOD_NONBLOCKING | FMOD_IGNORETAGS, 0, &mInternetStream);
+
+ if (result!= FMOD_OK)
+ {
+ llwarns << "Couldn't open fmod stream, error "
+ << FMOD_ErrorString(result)
+ << llendl;
+ mReady = false;
+ return;
+ }
+
+ mReady = true;
+}
+
+FMOD::Channel *LLAudioStreamManagerFMODEX::startStream()
+{
+ // We need a live and opened stream before we try and play it.
+ if (!mInternetStream || getOpenState() != FMOD_OPENSTATE_READY)
+ {
+ llwarns << "No internet stream to start playing!" << llendl;
+ return NULL;
+ }
+
+ if(mStreamChannel)
+ return mStreamChannel; //Already have a channel for this stream.
+
+ mSystem->playSound(FMOD_CHANNEL_FREE, mInternetStream, true, &mStreamChannel);
+ return mStreamChannel;
+}
+
+bool LLAudioStreamManagerFMODEX::stopStream()
+{
+ if (mInternetStream)
+ {
+
+
+ bool close = true;
+ switch (getOpenState())
+ {
+ case FMOD_OPENSTATE_CONNECTING:
+ close = false;
+ break;
+ default:
+ close = true;
+ }
+
+ if (close)
+ {
+ mInternetStream->release();
+ mStreamChannel = NULL;
+ mInternetStream = NULL;
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ else
+ {
+ return true;
+ }
+}
+
+FMOD_OPENSTATE LLAudioStreamManagerFMODEX::getOpenState(unsigned int* percentbuffered, bool* starving, bool* diskbusy)
+{
+ FMOD_OPENSTATE state;
+ mInternetStream->getOpenState(&state, percentbuffered, starving, diskbusy);
+ return state;
+}
+
+void LLStreamingAudio_FMODEX::setBufferSizes(U32 streambuffertime, U32 decodebuffertime)
+{
+ mSystem->setStreamBufferSize(streambuffertime/1000*128*128, FMOD_TIMEUNIT_RAWBYTES);
+ FMOD_ADVANCEDSETTINGS settings;
+ memset(&settings,0,sizeof(settings));
+ settings.cbsize=sizeof(settings);
+ settings.defaultDecodeBufferSize = decodebuffertime;//ms
+ mSystem->setAdvancedSettings(&settings);
+}
diff --git a/indra/llaudio/llstreamingaudio_fmodex.h b/indra/llaudio/llstreamingaudio_fmodex.h
new file mode 100644
index 0000000000..1dee18ae7d
--- /dev/null
+++ b/indra/llaudio/llstreamingaudio_fmodex.h
@@ -0,0 +1,73 @@
+/**
+ * @file streamingaudio_fmodex.h
+ * @brief Definition of LLStreamingAudio_FMODEX implementation
+ *
+ * $LicenseInfo:firstyear=2002&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$
+ */
+
+#ifndef LL_STREAMINGAUDIO_FMODEX_H
+#define LL_STREAMINGAUDIO_FMODEX_H
+
+#include "stdtypes.h" // from llcommon
+
+#include "llstreamingaudio.h"
+#include "lltimer.h"
+
+//Stubs
+class LLAudioStreamManagerFMODEX;
+namespace FMOD
+{
+ class System;
+ class Channel;
+}
+
+//Interfaces
+class LLStreamingAudio_FMODEX : public LLStreamingAudioInterface
+{
+ public:
+ LLStreamingAudio_FMODEX(FMOD::System *system);
+ /*virtual*/ ~LLStreamingAudio_FMODEX();
+
+ /*virtual*/ void start(const std::string& url);
+ /*virtual*/ void stop();
+ /*virtual*/ void pause(int pause);
+ /*virtual*/ void update();
+ /*virtual*/ int isPlaying();
+ /*virtual*/ void setGain(F32 vol);
+ /*virtual*/ F32 getGain();
+ /*virtual*/ std::string getURL();
+
+ /*virtual*/ bool supportsAdjustableBufferSizes(){return true;}
+ /*virtual*/ void setBufferSizes(U32 streambuffertime, U32 decodebuffertime);
+private:
+ FMOD::System *mSystem;
+
+ LLAudioStreamManagerFMODEX *mCurrentInternetStreamp;
+ FMOD::Channel *mFMODInternetStreamChannelp;
+ std::list<LLAudioStreamManagerFMODEX *> mDeadStreams;
+
+ std::string mURL;
+ F32 mGain;
+};
+
+
+#endif // LL_STREAMINGAUDIO_FMODEX_H
diff --git a/indra/llaudio/llvorbisencode.cpp b/indra/llaudio/llvorbisencode.cpp
index 0e0c80a456..dfd5da12b3 100644..100755
--- a/indra/llaudio/llvorbisencode.cpp
+++ b/indra/llaudio/llvorbisencode.cpp
@@ -35,7 +35,7 @@
#include "llapr.h"
//#if LL_DARWIN
-// MBW -- XXX -- Getting rid of SecondLifeVorbis for now -- no fmod means no name collisions.
+// MBW -- XXX -- Getting rid of SecondLifeVorbis for now
#if 0
#include "VorbisFramework.h"
diff --git a/indra/llaudio/llvorbisencode.h b/indra/llaudio/llvorbisencode.h
index 6b22a2cb59..6b22a2cb59 100644..100755
--- a/indra/llaudio/llvorbisencode.h
+++ b/indra/llaudio/llvorbisencode.h
diff --git a/indra/llaudio/llwindgen.h b/indra/llaudio/llwindgen.h
index b9cecb60a1..ec58f76f5f 100644..100755
--- a/indra/llaudio/llwindgen.h
+++ b/indra/llaudio/llwindgen.h
@@ -27,6 +27,7 @@
#define WINDGEN_H
#include "llcommon.h"
+#include "llrand.h"
template <class MIXBUFFERFORMAT_T>
class LLWindGen
@@ -54,6 +55,8 @@ public:
}
const U32 getInputSamplingRate() { return mInputSamplingRate; }
+ const F32 getNextSample();
+ const F32 getClampedSample(bool clamp, F32 sample);
// newbuffer = the buffer passed from the previous DSP unit.
// numsamples = length in samples-per-channel at this mix time.
@@ -89,7 +92,7 @@ public:
// Start with white noise
// This expression is fragile, rearrange it and it will break!
- next_sample = (F32)rand() * (1.0f / (F32)(RAND_MAX / (U16_MAX / 8))) + (F32)(S16_MIN / 8);
+ next_sample = getNextSample();
// Apply a pinking filter
// Magic numbers taken from PKE method at http://www.firstpr.com.au/dsp/pink-noise/
@@ -126,25 +129,15 @@ public:
for (U8 i=mSubSamples; i && numsamples; --i, --numsamples)
{
mLastSample = mLastSample + delta;
- S32 sample_right = (S32)(mLastSample * mCurrentPanGainR);
- S32 sample_left = (S32)mLastSample - sample_right;
+ MIXBUFFERFORMAT_T sample_right = (MIXBUFFERFORMAT_T)getClampedSample(clip, mLastSample * mCurrentPanGainR);
+ MIXBUFFERFORMAT_T sample_left = (MIXBUFFERFORMAT_T)getClampedSample(clip, mLastSample - (F32)sample_right);
- if (!clip)
- {
- *cursamplep = (MIXBUFFERFORMAT_T)sample_left;
+ *cursamplep = sample_left;
++cursamplep;
- *cursamplep = (MIXBUFFERFORMAT_T)sample_right;
- ++cursamplep;
- }
- else
- {
- *cursamplep = (MIXBUFFERFORMAT_T)llclamp(sample_left, (S32)S16_MIN, (S32)S16_MAX);
- ++cursamplep;
- *cursamplep = (MIXBUFFERFORMAT_T)llclamp(sample_right, (S32)S16_MIN, (S32)S16_MAX);
+ *cursamplep = sample_right;
++cursamplep;
}
}
- }
return newbuffer;
}
@@ -173,4 +166,9 @@ private:
F32 mLastSample;
};
+template<class T> inline const F32 LLWindGen<T>::getNextSample() { return (F32)rand() * (1.0f / (F32)(RAND_MAX / (U16_MAX / 8))) + (F32)(S16_MIN / 8); }
+template<> inline const F32 LLWindGen<F32>::getNextSample() { return ll_frand()-.5f; }
+template<class T> inline const F32 LLWindGen<T>::getClampedSample(bool clamp, F32 sample) { return clamp ? (F32)llclamp((S32)sample,(S32)S16_MIN,(S32)S16_MAX) : sample; }
+template<> inline const F32 LLWindGen<F32>::getClampedSample(bool clamp, F32 sample) { return sample; }
+
#endif
diff --git a/indra/llcharacter/CMakeLists.txt b/indra/llcharacter/CMakeLists.txt
index a1712699eb..2573417b26 100644..100755
--- a/indra/llcharacter/CMakeLists.txt
+++ b/indra/llcharacter/CMakeLists.txt
@@ -16,6 +16,10 @@ include_directories(
${LLVFS_INCLUDE_DIRS}
${LLXML_INCLUDE_DIRS}
)
+include_directories(SYSTEM
+ ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+ ${LLXML_SYSTEM_INCLUDE_DIRS}
+ )
set(llcharacter_SOURCE_FILES
llanimationstates.cpp
@@ -76,6 +80,15 @@ list(APPEND llcharacter_SOURCE_FILES ${llcharacter_HEADER_FILES})
add_library (llcharacter ${llcharacter_SOURCE_FILES})
+target_link_libraries(
+ llcharacter
+ ${LLCOMMON_LIBRARIES}
+ ${LLMATH_LIBRARIES}
+ ${LLMESSAGE_LIBRARIES}
+ ${LLVFS_LIBRARIES}
+ ${LLXML_LIBRARIES}
+ )
+
# Add tests
if (LL_TESTS)
diff --git a/indra/llcharacter/llanimationstates.cpp b/indra/llcharacter/llanimationstates.cpp
index 155226cf17..c16cae1bbc 100644..100755
--- a/indra/llcharacter/llanimationstates.cpp
+++ b/indra/llcharacter/llanimationstates.cpp
@@ -46,7 +46,7 @@ LLUUID const ANIM_AGENT_BLOW_KISS ("db84829b-462c-ee83-1e27-9bbee66b
LLUUID const ANIM_AGENT_BORED ("b906c4ba-703b-1940-32a3-0c7f7d791510");
LLUUID const ANIM_AGENT_BOW ("82e99230-c906-1403-4d9c-3889dd98daba");
LLUUID const ANIM_AGENT_BRUSH ("349a3801-54f9-bf2c-3bd0-1ac89772af01");
-LLUUID const ANIM_AGENT_BUSY ("efcf670c-2d18-8128-973a-034ebc806b67");
+LLUUID const ANIM_AGENT_DO_NOT_DISTURB ("efcf670c-2d18-8128-973a-034ebc806b67");
LLUUID const ANIM_AGENT_CLAP ("9b0c1c4e-8ac7-7969-1494-28c874c4f668");
LLUUID const ANIM_AGENT_COURTBOW ("9ba1c942-08be-e43a-fb29-16ad440efc50");
LLUUID const ANIM_AGENT_CROUCH ("201f3fdf-cb1f-dbec-201f-7333e328ae7c");
@@ -211,7 +211,7 @@ LLAnimationLibrary::LLAnimationLibrary() :
mAnimMap[ANIM_AGENT_BORED]= mAnimStringTable.addString("express_bored");
mAnimMap[ANIM_AGENT_BOW]= mAnimStringTable.addString("bow");
mAnimMap[ANIM_AGENT_BRUSH]= mAnimStringTable.addString("brush");
- mAnimMap[ANIM_AGENT_BUSY]= mAnimStringTable.addString("busy");
+ mAnimMap[ANIM_AGENT_DO_NOT_DISTURB]= mAnimStringTable.addString("busy");
mAnimMap[ANIM_AGENT_CLAP]= mAnimStringTable.addString("clap");
mAnimMap[ANIM_AGENT_COURTBOW]= mAnimStringTable.addString("courtbow");
mAnimMap[ANIM_AGENT_CROUCH]= mAnimStringTable.addString("crouch");
diff --git a/indra/llcharacter/llanimationstates.h b/indra/llcharacter/llanimationstates.h
index aa6579ac8e..84185c3f92 100644..100755
--- a/indra/llcharacter/llanimationstates.h
+++ b/indra/llcharacter/llanimationstates.h
@@ -56,7 +56,7 @@ extern const LLUUID ANIM_AGENT_BLOW_KISS;
extern const LLUUID ANIM_AGENT_BORED;
extern const LLUUID ANIM_AGENT_BOW;
extern const LLUUID ANIM_AGENT_BRUSH;
-extern const LLUUID ANIM_AGENT_BUSY;
+extern const LLUUID ANIM_AGENT_DO_NOT_DISTURB;
extern const LLUUID ANIM_AGENT_CLAP;
extern const LLUUID ANIM_AGENT_COURTBOW;
extern const LLUUID ANIM_AGENT_CROUCH;
diff --git a/indra/llcharacter/llbvhconsts.h b/indra/llcharacter/llbvhconsts.h
index d363a6e595..b06c279b8f 100644..100755
--- a/indra/llcharacter/llbvhconsts.h
+++ b/indra/llcharacter/llbvhconsts.h
@@ -27,7 +27,7 @@
#ifndef LL_LLBVHCONSTS_H
#define LL_LLBVHCONSTS_H
-const F32 MAX_ANIM_DURATION = 30.f;
+const F32 MAX_ANIM_DURATION = 60.f;
typedef enum e_constraint_type
{
diff --git a/indra/llcharacter/llbvhloader.cpp b/indra/llcharacter/llbvhloader.cpp
index 2a0df26384..2a0df26384 100644..100755
--- a/indra/llcharacter/llbvhloader.cpp
+++ b/indra/llcharacter/llbvhloader.cpp
diff --git a/indra/llcharacter/llbvhloader.h b/indra/llcharacter/llbvhloader.h
index f816b76277..f816b76277 100644..100755
--- a/indra/llcharacter/llbvhloader.h
+++ b/indra/llcharacter/llbvhloader.h
diff --git a/indra/llcharacter/llcharacter.cpp b/indra/llcharacter/llcharacter.cpp
index c9fb8534f1..85cf1cd3f5 100644..100755
--- a/indra/llcharacter/llcharacter.cpp
+++ b/indra/llcharacter/llcharacter.cpp
@@ -189,6 +189,7 @@ void LLCharacter::requestStopMotion( LLMotion* motion)
//-----------------------------------------------------------------------------
static LLFastTimer::DeclareTimer FTM_UPDATE_ANIMATION("Update Animation");
static LLFastTimer::DeclareTimer FTM_UPDATE_HIDDEN_ANIMATION("Update Hidden Anim");
+static LLFastTimer::DeclareTimer FTM_UPDATE_MOTIONS("Update Motions");
void LLCharacter::updateMotions(e_update_t update_type)
{
@@ -206,7 +207,10 @@ void LLCharacter::updateMotions(e_update_t update_type)
mMotionController.unpauseAllMotions();
}
bool force_update = (update_type == FORCE_UPDATE);
- mMotionController.updateMotions(force_update);
+ {
+ LLFastTimer t(FTM_UPDATE_MOTIONS);
+ mMotionController.updateMotions(force_update);
+ }
}
}
@@ -282,7 +286,7 @@ void LLCharacter::removeAnimationData(std::string name)
//-----------------------------------------------------------------------------
// setVisualParamWeight()
//-----------------------------------------------------------------------------
-BOOL LLCharacter::setVisualParamWeight(LLVisualParam* which_param, F32 weight, BOOL upload_bake)
+BOOL LLCharacter::setVisualParamWeight(const LLVisualParam* which_param, F32 weight, BOOL upload_bake)
{
S32 index = which_param->getID();
visual_param_index_map_t::iterator index_iter = mVisualParamIndexMap.find(index);
diff --git a/indra/llcharacter/llcharacter.h b/indra/llcharacter/llcharacter.h
index 3ebb2bffb0..5740dbce77 100644..100755
--- a/indra/llcharacter/llcharacter.h
+++ b/indra/llcharacter/llcharacter.h
@@ -93,13 +93,6 @@ public:
// get the height & normal of the ground under a point
virtual void getGround(const LLVector3 &inPos, LLVector3 &outPos, LLVector3 &outNorm) = 0;
- // allocate an array of joints for the character skeleton
- // this must be overloaded to support joint subclasses,
- // and is called implicitly from buildSkeleton().
- // Note this must handle reallocation as it will be called
- // each time buildSkeleton() is called.
- virtual BOOL allocateCharacterJoints( U32 num ) = 0;
-
// skeleton joint accessor to support joint subclasses
virtual LLJoint *getCharacterJoint( U32 i ) = 0;
@@ -197,7 +190,7 @@ public:
void addVisualParam(LLVisualParam *param);
void addSharedVisualParam(LLVisualParam *param);
- virtual BOOL setVisualParamWeight(LLVisualParam *which_param, F32 weight, BOOL upload_bake = FALSE );
+ virtual BOOL setVisualParamWeight(const LLVisualParam *which_param, F32 weight, BOOL upload_bake = FALSE );
virtual BOOL setVisualParamWeight(const char* param_name, F32 weight, BOOL upload_bake = FALSE );
virtual BOOL setVisualParamWeight(S32 index, F32 weight, BOOL upload_bake = FALSE );
diff --git a/indra/llcharacter/lleditingmotion.cpp b/indra/llcharacter/lleditingmotion.cpp
index 66b3c2bd25..4e8c3268c5 100644..100755
--- a/indra/llcharacter/lleditingmotion.cpp
+++ b/indra/llcharacter/lleditingmotion.cpp
@@ -214,8 +214,10 @@ BOOL LLEditingMotion::onUpdate(F32 time, U8* joint_mask)
target = target * target_dist;
if (!target.isFinite())
{
- llerrs << "Non finite target in editing motion with target distance of " << target_dist <<
+ // Don't error out here, set a fail-safe target vector
+ llwarns << "Non finite target in editing motion with target distance of " << target_dist <<
" and focus point " << focus_pt << llendl;
+ target.setVec(1.f, 1.f, 1.f);
}
mTarget.setPosition( target + mParentJoint.getPosition());
@@ -256,3 +258,4 @@ void LLEditingMotion::onDeactivate()
// End
+
diff --git a/indra/llcharacter/lleditingmotion.h b/indra/llcharacter/lleditingmotion.h
index 7b1c8bb059..7b1c8bb059 100644..100755
--- a/indra/llcharacter/lleditingmotion.h
+++ b/indra/llcharacter/lleditingmotion.h
diff --git a/indra/llcharacter/llgesture.cpp b/indra/llcharacter/llgesture.cpp
index c23694639e..c23694639e 100644..100755
--- a/indra/llcharacter/llgesture.cpp
+++ b/indra/llcharacter/llgesture.cpp
diff --git a/indra/llcharacter/llgesture.h b/indra/llcharacter/llgesture.h
index 66b618c473..66b618c473 100644..100755
--- a/indra/llcharacter/llgesture.h
+++ b/indra/llcharacter/llgesture.h
diff --git a/indra/llcharacter/llhandmotion.cpp b/indra/llcharacter/llhandmotion.cpp
index 63937d8255..696dba0d95 100644..100755
--- a/indra/llcharacter/llhandmotion.cpp
+++ b/indra/llcharacter/llhandmotion.cpp
@@ -132,18 +132,68 @@ BOOL LLHandMotion::onUpdate(F32 time, U8* joint_mask)
{
if (mNewPose != HAND_POSE_RELAXED && mNewPose != mCurrentPose)
{
- mCharacter->setVisualParamWeight(gHandPoseNames[mNewPose], 0.f);
+ // Only set param weight for poses other than
+ // default (HAND_POSE_SPREAD); HAND_POSE_SPREAD
+ // is not an animatable morph!
+ if (mNewPose != HAND_POSE_SPREAD)
+ {
+ mCharacter->setVisualParamWeight(gHandPoseNames[mNewPose], 0.f);
+ }
+
+ // Reset morph weight for current pose back to its
+ // full extend or it might be stuck somewhere in the middle if a
+ // pose is requested and the old pose is requested again shortly
+ // after while still blending to the other pose!
+ if (mCurrentPose != HAND_POSE_SPREAD)
+ {
+ mCharacter->setVisualParamWeight(gHandPoseNames[mCurrentPose], 1.f);
+ }
+
+ // Update visual params now if we won't blend
+ if (mCurrentPose == HAND_POSE_RELAXED)
+ {
+ mCharacter->updateVisualParams();
+ }
}
mNewPose = HAND_POSE_RELAXED;
}
else
{
- // this is a new morph we didn't know about before
- if (*requestedHandPose != mNewPose && mNewPose != mCurrentPose && mNewPose != HAND_POSE_SPREAD)
+ // Sometimes we seem to get garbage here, with poses that are out of bounds.
+ // So check for a valid pose first.
+ if (*requestedHandPose >= 0 && *requestedHandPose < NUM_HAND_POSES)
+ {
+ // This is a new morph we didn't know about before:
+ // Reset morph weight for both current and new pose
+ // back their starting values while still blending.
+ if (*requestedHandPose != mNewPose && mNewPose != mCurrentPose)
+ {
+ if (mNewPose != HAND_POSE_SPREAD)
+ {
+ mCharacter->setVisualParamWeight(gHandPoseNames[mNewPose], 0.f);
+ }
+
+ // Reset morph weight for current pose back to its full extend
+ // or it might be stuck somewhere in the middle if a pose is
+ // requested and the old pose is requested again shortly after
+ // while still blending to the other pose!
+ if (mCurrentPose != HAND_POSE_SPREAD)
+ {
+ mCharacter->setVisualParamWeight(gHandPoseNames[mCurrentPose], 1.f);
+ }
+
+ // Update visual params now if we won't blend
+ if (mCurrentPose == *requestedHandPose)
+ {
+ mCharacter->updateVisualParams();
+ }
+ }
+ mNewPose = *requestedHandPose;
+ }
+ else
{
- mCharacter->setVisualParamWeight(gHandPoseNames[mNewPose], 0.f);
+ llwarns << "Requested hand pose out of range. Ignoring requested pose." << llendl;
}
- mNewPose = *requestedHandPose;
}
mCharacter->removeAnimationData("Hand Pose");
diff --git a/indra/llcharacter/llhandmotion.h b/indra/llcharacter/llhandmotion.h
index 08de7056c8..08de7056c8 100644..100755
--- a/indra/llcharacter/llhandmotion.h
+++ b/indra/llcharacter/llhandmotion.h
diff --git a/indra/llcharacter/llheadrotmotion.cpp b/indra/llcharacter/llheadrotmotion.cpp
index 15a58a8389..2b1aa194a9 100644..100755
--- a/indra/llcharacter/llheadrotmotion.cpp
+++ b/indra/llcharacter/llheadrotmotion.cpp
@@ -530,3 +530,4 @@ void LLEyeMotion::onDeactivate()
}
// End
+
diff --git a/indra/llcharacter/llheadrotmotion.h b/indra/llcharacter/llheadrotmotion.h
index 569dbef2dd..569dbef2dd 100644..100755
--- a/indra/llcharacter/llheadrotmotion.h
+++ b/indra/llcharacter/llheadrotmotion.h
diff --git a/indra/llcharacter/lljoint.cpp b/indra/llcharacter/lljoint.cpp
index 19907933cb..09a7c11a22 100644..100755
--- a/indra/llcharacter/lljoint.cpp
+++ b/indra/llcharacter/lljoint.cpp
@@ -40,7 +40,9 @@ S32 LLJoint::sNumTouches = 0;
// LLJoint()
// Class Constructor
//-----------------------------------------------------------------------------
-LLJoint::LLJoint()
+
+
+void LLJoint::init()
{
mName = "unnamed";
mParent = NULL;
@@ -48,7 +50,20 @@ LLJoint::LLJoint()
mXform.setScale(LLVector3(1.0f, 1.0f, 1.0f));
mDirtyFlags = MATRIX_DIRTY | ROTATION_DIRTY | POSITION_DIRTY;
mUpdateXform = TRUE;
- mJointNum = -1;
+}
+
+LLJoint::LLJoint() :
+ mJointNum(-1)
+{
+ init();
+ touch();
+ mResetAfterRestoreOldXform = false;
+}
+
+LLJoint::LLJoint(S32 joint_num) :
+ mJointNum(joint_num)
+{
+ init();
touch();
mResetAfterRestoreOldXform = false;
}
@@ -58,15 +73,12 @@ LLJoint::LLJoint()
// LLJoint()
// Class Constructor
//-----------------------------------------------------------------------------
-LLJoint::LLJoint(const std::string &name, LLJoint *parent)
+LLJoint::LLJoint(const std::string &name, LLJoint *parent) :
+ mJointNum(0)
{
- mName = "unnamed";
- mParent = NULL;
- mXform.setScaleChildOffset(TRUE);
- mXform.setScale(LLVector3(1.0f, 1.0f, 1.0f));
- mDirtyFlags = MATRIX_DIRTY | ROTATION_DIRTY | POSITION_DIRTY;
+ init();
mUpdateXform = FALSE;
- mJointNum = 0;
+ // *TODO: mResetAfterRestoreOldXform is not initialized!!!
setName(name);
if (parent)
diff --git a/indra/llcharacter/lljoint.h b/indra/llcharacter/lljoint.h
index dc3c58cf64..2b1e2005c6 100644..100755
--- a/indra/llcharacter/lljoint.h
+++ b/indra/llcharacter/lljoint.h
@@ -105,10 +105,15 @@ public:
public:
LLJoint();
+ LLJoint(S32 joint_num);
+ // *TODO: Only used for LLVOAvatarSelf::mScreenp. *DOES NOT INITIALIZE mResetAfterRestoreOldXform*
LLJoint( const std::string &name, LLJoint *parent=NULL );
-
virtual ~LLJoint();
+private:
+ void init();
+
+public:
// set name and parent
void setup( const std::string &name, LLJoint *parent=NULL );
@@ -178,7 +183,6 @@ public:
virtual BOOL isAnimatable() const { return TRUE; }
S32 getJointNum() const { return mJointNum; }
- void setJointNum(S32 joint_num) { mJointNum = joint_num; }
void restoreOldXform( void );
void restoreToDefaultXform( void );
diff --git a/indra/llcharacter/lljointsolverrp3.cpp b/indra/llcharacter/lljointsolverrp3.cpp
index 1331900791..1331900791 100644..100755
--- a/indra/llcharacter/lljointsolverrp3.cpp
+++ b/indra/llcharacter/lljointsolverrp3.cpp
diff --git a/indra/llcharacter/lljointsolverrp3.h b/indra/llcharacter/lljointsolverrp3.h
index 88b5d08710..88b5d08710 100644..100755
--- a/indra/llcharacter/lljointsolverrp3.h
+++ b/indra/llcharacter/lljointsolverrp3.h
diff --git a/indra/llcharacter/lljointstate.h b/indra/llcharacter/lljointstate.h
index b9c91f80b5..b9c91f80b5 100644..100755
--- a/indra/llcharacter/lljointstate.h
+++ b/indra/llcharacter/lljointstate.h
diff --git a/indra/llcharacter/llkeyframefallmotion.cpp b/indra/llcharacter/llkeyframefallmotion.cpp
index 60ab2e9929..60ab2e9929 100644..100755
--- a/indra/llcharacter/llkeyframefallmotion.cpp
+++ b/indra/llcharacter/llkeyframefallmotion.cpp
diff --git a/indra/llcharacter/llkeyframefallmotion.h b/indra/llcharacter/llkeyframefallmotion.h
index 7f0a2fdda2..7f0a2fdda2 100644..100755
--- a/indra/llcharacter/llkeyframefallmotion.h
+++ b/indra/llcharacter/llkeyframefallmotion.h
diff --git a/indra/llcharacter/llkeyframemotion.cpp b/indra/llcharacter/llkeyframemotion.cpp
index c6f45bffa2..07ef52228e 100644..100755
--- a/indra/llcharacter/llkeyframemotion.cpp
+++ b/indra/llcharacter/llkeyframemotion.cpp
@@ -672,7 +672,8 @@ BOOL LLKeyframeMotion::onActivate()
//-----------------------------------------------------------------------------
BOOL LLKeyframeMotion::onUpdate(F32 time, U8* joint_mask)
{
- llassert(time >= 0.f);
+ // llassert(time >= 0.f); // This will fire
+ time = llmax(0.f, time);
if (mJointMotionList->mLoop)
{
@@ -2304,3 +2305,4 @@ LLKeyframeMotion::JointConstraint::~JointConstraint()
}
// End
+
diff --git a/indra/llcharacter/llkeyframemotion.h b/indra/llcharacter/llkeyframemotion.h
index b1422b2b90..b1422b2b90 100644..100755
--- a/indra/llcharacter/llkeyframemotion.h
+++ b/indra/llcharacter/llkeyframemotion.h
diff --git a/indra/llcharacter/llkeyframemotionparam.cpp b/indra/llcharacter/llkeyframemotionparam.cpp
index 82fe8971f5..82fe8971f5 100644..100755
--- a/indra/llcharacter/llkeyframemotionparam.cpp
+++ b/indra/llcharacter/llkeyframemotionparam.cpp
diff --git a/indra/llcharacter/llkeyframemotionparam.h b/indra/llcharacter/llkeyframemotionparam.h
index 24e8141753..24e8141753 100644..100755
--- a/indra/llcharacter/llkeyframemotionparam.h
+++ b/indra/llcharacter/llkeyframemotionparam.h
diff --git a/indra/llcharacter/llkeyframestandmotion.cpp b/indra/llcharacter/llkeyframestandmotion.cpp
index 3f91532c8e..3f91532c8e 100644..100755
--- a/indra/llcharacter/llkeyframestandmotion.cpp
+++ b/indra/llcharacter/llkeyframestandmotion.cpp
diff --git a/indra/llcharacter/llkeyframestandmotion.h b/indra/llcharacter/llkeyframestandmotion.h
index c2634ecd6d..c2634ecd6d 100644..100755
--- a/indra/llcharacter/llkeyframestandmotion.h
+++ b/indra/llcharacter/llkeyframestandmotion.h
diff --git a/indra/llcharacter/llkeyframewalkmotion.cpp b/indra/llcharacter/llkeyframewalkmotion.cpp
index d52eb89a5c..69f064b615 100644..100755
--- a/indra/llcharacter/llkeyframewalkmotion.cpp
+++ b/indra/llcharacter/llkeyframewalkmotion.cpp
@@ -390,3 +390,4 @@ BOOL LLFlyAdjustMotion::onUpdate(F32 time, U8* joint_mask)
return TRUE;
}
+
diff --git a/indra/llcharacter/llkeyframewalkmotion.h b/indra/llcharacter/llkeyframewalkmotion.h
index 0e8d21b765..0e8d21b765 100644..100755
--- a/indra/llcharacter/llkeyframewalkmotion.h
+++ b/indra/llcharacter/llkeyframewalkmotion.h
diff --git a/indra/llcharacter/llmotion.cpp b/indra/llcharacter/llmotion.cpp
index 2551f125d0..a07f9f4d2e 100644..100755
--- a/indra/llcharacter/llmotion.cpp
+++ b/indra/llcharacter/llmotion.cpp
@@ -169,3 +169,4 @@ BOOL LLMotion::canDeprecate()
}
// End
+
diff --git a/indra/llcharacter/llmotion.h b/indra/llcharacter/llmotion.h
index 6e532aac2f..6e532aac2f 100644..100755
--- a/indra/llcharacter/llmotion.h
+++ b/indra/llcharacter/llmotion.h
diff --git a/indra/llcharacter/llmotioncontroller.cpp b/indra/llcharacter/llmotioncontroller.cpp
index bb892f4a7f..e9fb91ad73 100644..100755
--- a/indra/llcharacter/llmotioncontroller.cpp
+++ b/indra/llcharacter/llmotioncontroller.cpp
@@ -29,8 +29,6 @@
//-----------------------------------------------------------------------------
#include "linden_common.h"
-#include "llmemtype.h"
-
#include "llmotioncontroller.h"
#include "llkeyframemotion.h"
#include "llmath.h"
@@ -44,6 +42,7 @@ const U32 MAX_MOTION_INSTANCES = 32;
//-----------------------------------------------------------------------------
// Constants and statics
//-----------------------------------------------------------------------------
+F32 LLMotionController::sCurrentTimeFactor = 1.f;
LLMotionRegistry LLMotionController::sRegistry;
//-----------------------------------------------------------------------------
@@ -127,7 +126,7 @@ LLMotion *LLMotionRegistry::createMotion( const LLUUID &id )
// Class Constructor
//-----------------------------------------------------------------------------
LLMotionController::LLMotionController()
- : mTimeFactor(1.f),
+ : mTimeFactor(sCurrentTimeFactor),
mCharacter(NULL),
mAnimTime(0.f),
mPrevTimerElapsed(0.f),
@@ -335,7 +334,6 @@ void LLMotionController::removeMotionInstance(LLMotion* motionp)
//-----------------------------------------------------------------------------
LLMotion* LLMotionController::createMotion( const LLUUID &id )
{
- LLMemType mt(LLMemType::MTYPE_ANIMATION);
// do we have an instance of this motion for this character?
LLMotion *motion = findMotion(id);
@@ -542,6 +540,8 @@ void LLMotionController::updateIdleActiveMotions()
//-----------------------------------------------------------------------------
// updateMotionsByType()
//-----------------------------------------------------------------------------
+static LLFastTimer::DeclareTimer FTM_MOTION_ON_UPDATE("Motion onUpdate");
+
void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_type)
{
BOOL update_result = TRUE;
@@ -699,7 +699,10 @@ void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_ty
}
// perform motion update
- update_result = motionp->onUpdate(mAnimTime - motionp->mActivationTimestamp, last_joint_signature);
+ {
+ LLFastTimer t(FTM_MOTION_ON_UPDATE);
+ update_result = motionp->onUpdate(mAnimTime - motionp->mActivationTimestamp, last_joint_signature);
+ }
}
//**********************
@@ -810,7 +813,7 @@ void LLMotionController::updateMotions(bool force_update)
// Always cap the number of loaded motions
purgeExcessMotions();
-
+
// Update timing info for this time step.
if (!mPaused)
{
@@ -832,6 +835,7 @@ void LLMotionController::updateMotions(bool force_update)
}
updateLoadingMotions();
+
return;
}
@@ -850,7 +854,7 @@ void LLMotionController::updateMotions(bool force_update)
}
updateLoadingMotions();
-
+
resetJointSignatures();
if (mPaused && !force_update)
@@ -861,11 +865,12 @@ void LLMotionController::updateMotions(bool force_update)
{
// update additive motions
updateAdditiveMotions();
+
resetJointSignatures();
-
+
// update all regular motions
updateRegularMotions();
-
+
if (use_quantum)
{
mPoseBlender.blendAndCache(TRUE);
diff --git a/indra/llcharacter/llmotioncontroller.h b/indra/llcharacter/llmotioncontroller.h
index b996f708d2..52eaf557b1 100644..100755
--- a/indra/llcharacter/llmotioncontroller.h
+++ b/indra/llcharacter/llmotioncontroller.h
@@ -168,6 +168,9 @@ public:
const LLFrameTimer& getFrameTimer() { return mTimer; }
+ static F32 getCurrentTimeFactor() { return sCurrentTimeFactor; };
+ static void setCurrentTimeFactor(F32 factor) { sCurrentTimeFactor = factor; };
+
protected:
// internal operations act on motion instances directly
// as there can be duplicate motions per id during blending overlap
@@ -187,7 +190,8 @@ protected:
void deactivateStoppedMotions();
protected:
- F32 mTimeFactor;
+ F32 mTimeFactor; // 1.f for normal speed
+ static F32 sCurrentTimeFactor; // Value to use for initialization
static LLMotionRegistry sRegistry;
LLPoseBlender mPoseBlender;
diff --git a/indra/llcharacter/llmultigesture.cpp b/indra/llcharacter/llmultigesture.cpp
index e2d284834f..e2d284834f 100644..100755
--- a/indra/llcharacter/llmultigesture.cpp
+++ b/indra/llcharacter/llmultigesture.cpp
diff --git a/indra/llcharacter/llmultigesture.h b/indra/llcharacter/llmultigesture.h
index 92820159d4..92820159d4 100644..100755
--- a/indra/llcharacter/llmultigesture.h
+++ b/indra/llcharacter/llmultigesture.h
diff --git a/indra/llcharacter/llpose.cpp b/indra/llcharacter/llpose.cpp
index 55e1b6e9ea..55e1b6e9ea 100644..100755
--- a/indra/llcharacter/llpose.cpp
+++ b/indra/llcharacter/llpose.cpp
diff --git a/indra/llcharacter/llpose.h b/indra/llcharacter/llpose.h
index b486852605..b486852605 100644..100755
--- a/indra/llcharacter/llpose.h
+++ b/indra/llcharacter/llpose.h
diff --git a/indra/llcharacter/llstatemachine.cpp b/indra/llcharacter/llstatemachine.cpp
index e0454131a5..e0454131a5 100644..100755
--- a/indra/llcharacter/llstatemachine.cpp
+++ b/indra/llcharacter/llstatemachine.cpp
diff --git a/indra/llcharacter/llstatemachine.h b/indra/llcharacter/llstatemachine.h
index a2f7e59bd2..a2f7e59bd2 100644..100755
--- a/indra/llcharacter/llstatemachine.h
+++ b/indra/llcharacter/llstatemachine.h
diff --git a/indra/llcharacter/lltargetingmotion.cpp b/indra/llcharacter/lltargetingmotion.cpp
index 489aef923c..fa5f06328e 100644..100755
--- a/indra/llcharacter/lltargetingmotion.cpp
+++ b/indra/llcharacter/lltargetingmotion.cpp
@@ -169,3 +169,4 @@ void LLTargetingMotion::onDeactivate()
// End
+
diff --git a/indra/llcharacter/lltargetingmotion.h b/indra/llcharacter/lltargetingmotion.h
index 0971417e1e..0971417e1e 100644..100755
--- a/indra/llcharacter/lltargetingmotion.h
+++ b/indra/llcharacter/lltargetingmotion.h
diff --git a/indra/llcharacter/llvisualparam.cpp b/indra/llcharacter/llvisualparam.cpp
index 809b312abe..f7cb0f76b7 100644..100755
--- a/indra/llcharacter/llvisualparam.cpp
+++ b/indra/llcharacter/llvisualparam.cpp
@@ -168,7 +168,8 @@ LLVisualParam::LLVisualParam()
mIsAnimating( FALSE ),
mID( -1 ),
mInfo( 0 ),
- mIsDummy(FALSE)
+ mIsDummy(FALSE),
+ mParamLocation(LOC_UNKNOWN)
{
}
@@ -250,6 +251,7 @@ void LLVisualParam::setAnimationTarget(F32 target_value, BOOL upload_bake)
if (mIsDummy)
{
setWeight(target_value, upload_bake);
+ mTargetWeight = mCurWeight;
return;
}
@@ -319,3 +321,32 @@ void LLVisualParam::resetDrivenParams()
// nothing to do for non-driver parameters
return;
}
+
+const std::string param_location_name(const EParamLocation& loc)
+{
+ switch (loc)
+ {
+ case LOC_UNKNOWN: return "unknown";
+ case LOC_AV_SELF: return "self";
+ case LOC_AV_OTHER: return "other";
+ case LOC_WEARABLE: return "wearable";
+ default: return "error";
+ }
+}
+
+void LLVisualParam::setParamLocation(EParamLocation loc)
+{
+ if (mParamLocation == LOC_UNKNOWN || loc == LOC_UNKNOWN)
+ {
+ mParamLocation = loc;
+ }
+ else if (mParamLocation == loc)
+ {
+ // no action
+ }
+ else
+ {
+ lldebugs << "param location is already " << mParamLocation << ", not slamming to " << loc << llendl;
+ }
+}
+
diff --git a/indra/llcharacter/llvisualparam.h b/indra/llcharacter/llvisualparam.h
index 694e27f371..60ea7a369a 100644..100755
--- a/indra/llcharacter/llvisualparam.h
+++ b/indra/llcharacter/llvisualparam.h
@@ -50,6 +50,16 @@ enum EVisualParamGroup
NUM_VISUAL_PARAM_GROUPS
};
+enum EParamLocation
+{
+ LOC_UNKNOWN,
+ LOC_AV_SELF,
+ LOC_AV_OTHER,
+ LOC_WEARABLE
+};
+
+const std::string param_location_name(const EParamLocation& loc);
+
const S32 MAX_TRANSMITTED_VISUAL_PARAMS = 255;
//-----------------------------------------------------------------------------
@@ -89,6 +99,7 @@ protected:
// An interface class for a generalized parametric modification of the avatar mesh
// Contains data that is specific to each Avatar
//-----------------------------------------------------------------------------
+LL_ALIGN_PREFIX(16)
class LLVisualParam
{
public:
@@ -149,6 +160,9 @@ public:
void setIsDummy(BOOL is_dummy) { mIsDummy = is_dummy; }
+ void setParamLocation(EParamLocation loc);
+ EParamLocation getParamLocation() const { return mParamLocation; }
+
protected:
F32 mCurWeight; // current weight
F32 mLastWeight; // last weight
@@ -160,6 +174,7 @@ protected:
S32 mID; // id for storing weight/morphtarget compares compactly
LLVisualParamInfo *mInfo;
-};
+ EParamLocation mParamLocation; // where does this visual param live?
+} LL_ALIGN_POSTFIX(16);
#endif // LL_LLVisualParam_H
diff --git a/indra/llcharacter/tests/lljoint_test.cpp b/indra/llcharacter/tests/lljoint_test.cpp
index e92aa832d6..da151808f2 100644..100755
--- a/indra/llcharacter/tests/lljoint_test.cpp
+++ b/indra/llcharacter/tests/lljoint_test.cpp
@@ -150,11 +150,11 @@ namespace tut
template<> template<>
void lljoint_object::test<11>()
{
- LLJoint lljoint("parent");
S32 joint_num = 12;
- lljoint.setJointNum(joint_num);
+ LLJoint lljoint(joint_num);
+ lljoint.setName("parent");
S32 jointNum = lljoint.getJointNum();
- ensure("setJointNum()/getJointNum failed ", (jointNum == joint_num));
+ ensure("getJointNum failed ", (jointNum == joint_num));
}
template<> template<>
diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt
index 0a3eaec5c5..8eb0c6249d 100644..100755
--- a/indra/llcommon/CMakeLists.txt
+++ b/indra/llcommon/CMakeLists.txt
@@ -17,6 +17,7 @@ include_directories(
${EXPAT_INCLUDE_DIRS}
${LLCOMMON_INCLUDE_DIRS}
${ZLIB_INCLUDE_DIRS}
+ ${BREAKPAD_INCLUDE_DIRECTORIES}
)
# add_executable(lltreeiterators lltreeiterators.cpp)
@@ -53,7 +54,7 @@ set(llcommon_SOURCE_FILES
lleventfilter.cpp
llevents.cpp
lleventtimer.cpp
- llfasttimer_class.cpp
+ llfasttimer.cpp
llfile.cpp
llfindlocale.cpp
llfixedbuffer.cpp
@@ -61,26 +62,29 @@ set(llcommon_SOURCE_FILES
llformat.cpp
llframetimer.cpp
llheartbeat.cpp
+ llinitparam.cpp
llinstancetracker.cpp
+ llleap.cpp
+ llleaplistener.cpp
llliveappconfig.cpp
lllivefile.cpp
lllog.cpp
llmd5.cpp
llmemory.cpp
llmemorystream.cpp
- llmemtype.cpp
llmetrics.cpp
llmetricperformancetester.cpp
llmortician.cpp
lloptioninterface.cpp
llptrto.cpp
- llprocesslauncher.cpp
+ llprocess.cpp
llprocessor.cpp
llqueuedthread.cpp
llrand.cpp
llrefcount.cpp
llrun.cpp
llsd.cpp
+ llsdparam.cpp
llsdserialize.cpp
llsdserialize_xml.cpp
llsdutil.cpp
@@ -88,6 +92,7 @@ set(llcommon_SOURCE_FILES
llsingleton.cpp
llstat.cpp
llstacktrace.cpp
+ llstreamqueue.cpp
llstreamtools.cpp
llstring.cpp
llstringtable.cpp
@@ -111,11 +116,13 @@ set(llcommon_HEADER_FILES
bitpack.h
ctype_workaround.h
doublelinkedlist.h
+ fix_macros.h
imageids.h
indra_constants.h
linden_common.h
linked_lists.h
llaccountingcost.h
+ llalignedarray.h
llallocator.h
llallocator_heap_profile.h
llagentconstants.h
@@ -162,20 +169,23 @@ set(llcommon_HEADER_FILES
lleventemitter.h
llextendedstatus.h
llfasttimer.h
- llfasttimer_class.h
llfile.h
llfindlocale.h
llfixedbuffer.h
llfoldertype.h
llformat.h
llframetimer.h
+ llhandle.h
llhash.h
llheartbeat.h
llhttpstatuscodes.h
llindexedqueue.h
+ llinitparam.h
llinstancetracker.h
llkeythrottle.h
lllazy.h
+ llleap.h
+ llleaplistener.h
lllistenerwrapper.h
lllinkedqueue.h
llliveappconfig.h
@@ -187,7 +197,6 @@ set(llcommon_HEADER_FILES
llmd5.h
llmemory.h
llmemorystream.h
- llmemtype.h
llmetrics.h
llmetricperformancetester.h
llmortician.h
@@ -196,7 +205,7 @@ set(llcommon_HEADER_FILES
llpointer.h
llpreprocessor.h
llpriqueuemap.h
- llprocesslauncher.h
+ llprocess.h
llprocessor.h
llptrskiplist.h
llptrskipmap.h
@@ -204,10 +213,12 @@ set(llcommon_HEADER_FILES
llqueuedthread.h
llrand.h
llrefcount.h
+ llregistry.h
llrun.h
llrefcount.h
llsafehandle.h
llsd.h
+ llsdparam.h
llsdserialize.h
llsdserialize_xml.h
llsdutil.h
@@ -216,25 +227,28 @@ set(llcommon_HEADER_FILES
llsingleton.h
llskiplist.h
llskipmap.h
+ llsortedvector.h
llstack.h
llstacktrace.h
llstat.h
llstatenums.h
llstl.h
+ llstreamqueue.h
llstreamtools.h
llstrider.h
llstring.h
llstringtable.h
+ llstaticstringtable.h
llsys.h
llthread.h
llthreadsafequeue.h
lltimer.h
lltreeiterators.h
+ lltypeinfolookup.h
lluri.h
lluuid.h
lluuidhashmap.h
llversionserver.h
- llversionviewer.h
llworkerthread.h
ll_template_cast.h
metaclass.h
@@ -317,8 +331,7 @@ if (LL_TESTS)
LL_ADD_INTEGRATION_TEST(lllazy "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llprocessor "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llrand "" "${test_libs}")
- LL_ADD_INTEGRATION_TEST(llsdserialize "" "${test_libs}"
- "${PYTHON_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/tests/setpython.py")
+ LL_ADD_INTEGRATION_TEST(llsdserialize "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llsingleton "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llstring "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(lltreeiterators "" "${test_libs}")
@@ -326,6 +339,10 @@ if (LL_TESTS)
LL_ADD_INTEGRATION_TEST(reflection "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(stringize "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(lleventdispatcher "" "${test_libs}")
+ LL_ADD_INTEGRATION_TEST(lleventcoro "" "${test_libs};${BOOST_CONTEXT_LIBRARY}")
+ LL_ADD_INTEGRATION_TEST(llprocess "" "${test_libs}")
+ LL_ADD_INTEGRATION_TEST(llleap "" "${test_libs}")
+ LL_ADD_INTEGRATION_TEST(llstreamqueue "" "${test_libs}")
# *TODO - reenable these once tcmalloc libs no longer break the build.
#ADD_BUILD_TEST(llallocator llcommon)
diff --git a/indra/llcommon/bitpack.cpp b/indra/llcommon/bitpack.cpp
index cdcaba0765..cdcaba0765 100644..100755
--- a/indra/llcommon/bitpack.cpp
+++ b/indra/llcommon/bitpack.cpp
diff --git a/indra/llcommon/bitpack.h b/indra/llcommon/bitpack.h
index 037300dd14..037300dd14 100644..100755
--- a/indra/llcommon/bitpack.h
+++ b/indra/llcommon/bitpack.h
diff --git a/indra/llcommon/ctype_workaround.h b/indra/llcommon/ctype_workaround.h
index 552be9fb90..552be9fb90 100644..100755
--- a/indra/llcommon/ctype_workaround.h
+++ b/indra/llcommon/ctype_workaround.h
diff --git a/indra/llcommon/doublelinkedlist.h b/indra/llcommon/doublelinkedlist.h
index 0aeaa69df3..0aeaa69df3 100644..100755
--- a/indra/llcommon/doublelinkedlist.h
+++ b/indra/llcommon/doublelinkedlist.h
diff --git a/indra/llcommon/fix_macros.h b/indra/llcommon/fix_macros.h
new file mode 100755
index 0000000000..ef959decff
--- /dev/null
+++ b/indra/llcommon/fix_macros.h
@@ -0,0 +1,25 @@
+/**
+ * @file fix_macros.h
+ * @author Nat Goodspeed
+ * @date 2012-11-16
+ * @brief The Mac system headers seem to #define macros with obnoxiously
+ * generic names, preventing any library from using those names. We've
+ * had to fix these in so many places that it's worth making a header
+ * file to handle it.
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Copyright (c) 2012, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+// DON'T use an #include guard: every time we encounter this header, #undef
+// these macros all over again.
+
+// who injects MACROS with such generic names?! Grr.
+#ifdef equivalent
+#undef equivalent
+#endif
+
+#ifdef check
+#undef check
+#endif
diff --git a/indra/llcommon/imageids.cpp b/indra/llcommon/imageids.cpp
index fe11465221..7d647e5c36 100644..100755
--- a/indra/llcommon/imageids.cpp
+++ b/indra/llcommon/imageids.cpp
@@ -68,3 +68,6 @@ const LLUUID TERRAIN_MOUNTAIN_DETAIL ("303cd381-8560-7579-23f1-f0a880799740"); /
const LLUUID TERRAIN_ROCK_DETAIL ("53a2f406-4895-1d13-d541-d2e3b86bc19c"); // VIEWER
const LLUUID DEFAULT_WATER_NORMAL ("822ded49-9a6c-f61c-cb89-6df54f42cdf4"); // VIEWER
+
+const LLUUID IMG_CHECKERBOARD_RGBA ("2585a0f3-4163-6dd1-0f34-ad48cb909e25"); // dataserver
+
diff --git a/indra/llcommon/imageids.h b/indra/llcommon/imageids.h
index e0c2683fdc..18c8ecb074 100644..100755
--- a/indra/llcommon/imageids.h
+++ b/indra/llcommon/imageids.h
@@ -66,4 +66,5 @@ LL_COMMON_API extern const LLUUID TERRAIN_ROCK_DETAIL;
LL_COMMON_API extern const LLUUID DEFAULT_WATER_NORMAL;
+LL_COMMON_API extern const LLUUID IMG_CHECKERBOARD_RGBA;
#endif
diff --git a/indra/llcommon/indra_constants.cpp b/indra/llcommon/indra_constants.cpp
index d32ae6c041..d32ae6c041 100644..100755
--- a/indra/llcommon/indra_constants.cpp
+++ b/indra/llcommon/indra_constants.cpp
diff --git a/indra/llcommon/indra_constants.h b/indra/llcommon/indra_constants.h
index 0745696ef3..0da83720bd 100644..100755
--- a/indra/llcommon/indra_constants.h
+++ b/indra/llcommon/indra_constants.h
@@ -62,6 +62,7 @@ enum LAND_STAT_FLAGS
STAT_FILTER_BY_PARCEL = 0x00000001,
STAT_FILTER_BY_OWNER = 0x00000002,
STAT_FILTER_BY_OBJECT = 0x00000004,
+ STAT_FILTER_BY_PARCEL_NAME = 0x00000008,
STAT_REQUEST_LAST_ENTRY = 0x80000000,
};
diff --git a/indra/llcommon/is_approx_equal_fraction.h b/indra/llcommon/is_approx_equal_fraction.h
index 4a9b2e2725..4a9b2e2725 100644..100755
--- a/indra/llcommon/is_approx_equal_fraction.h
+++ b/indra/llcommon/is_approx_equal_fraction.h
diff --git a/indra/llcommon/linden_common.h b/indra/llcommon/linden_common.h
index 5cfcdab41c..5cfcdab41c 100644..100755
--- a/indra/llcommon/linden_common.h
+++ b/indra/llcommon/linden_common.h
diff --git a/indra/llcommon/linked_lists.h b/indra/llcommon/linked_lists.h
index 6b25295b7b..6b25295b7b 100644..100755
--- a/indra/llcommon/linked_lists.h
+++ b/indra/llcommon/linked_lists.h
diff --git a/indra/llcommon/ll_template_cast.h b/indra/llcommon/ll_template_cast.h
index c8f9a2f7eb..c8f9a2f7eb 100644..100755
--- a/indra/llcommon/ll_template_cast.h
+++ b/indra/llcommon/ll_template_cast.h
diff --git a/indra/llcommon/llaccountingcost.h b/indra/llcommon/llaccountingcost.h
index 0ef3b50c6d..0ef3b50c6d 100644..100755
--- a/indra/llcommon/llaccountingcost.h
+++ b/indra/llcommon/llaccountingcost.h
diff --git a/indra/llcommon/llagentconstants.h b/indra/llcommon/llagentconstants.h
index cd237da4eb..cd237da4eb 100644..100755
--- a/indra/llcommon/llagentconstants.h
+++ b/indra/llcommon/llagentconstants.h
diff --git a/indra/llcommon/llalignedarray.h b/indra/llcommon/llalignedarray.h
new file mode 100644
index 0000000000..ed8fd31205
--- /dev/null
+++ b/indra/llcommon/llalignedarray.h
@@ -0,0 +1,139 @@
+/**
+ * @file llalignedarray.h
+ * @brief A static array which obeys alignment restrictions and mimics std::vector accessors.
+ *
+ * $LicenseInfo:firstyear=2002&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$
+ */
+
+#ifndef LL_LLALIGNEDARRAY_H
+#define LL_LLALIGNEDARRAY_H
+
+#include "llmemory.h"
+
+template <class T, U32 alignment>
+class LLAlignedArray
+{
+public:
+ T* mArray;
+ U32 mElementCount;
+ U32 mCapacity;
+
+ LLAlignedArray();
+ ~LLAlignedArray();
+
+ void push_back(const T& elem);
+ U32 size() const { return mElementCount; }
+ void resize(U32 size);
+ T* append(S32 N);
+ T& operator[](int idx);
+ const T& operator[](int idx) const;
+};
+
+template <class T, U32 alignment>
+LLAlignedArray<T, alignment>::LLAlignedArray()
+{
+ llassert(alignment >= 16);
+ mArray = NULL;
+ mElementCount = 0;
+ mCapacity = 0;
+}
+
+template <class T, U32 alignment>
+LLAlignedArray<T, alignment>::~LLAlignedArray()
+{
+ ll_aligned_free(mArray);
+ mArray = NULL;
+ mElementCount = 0;
+ mCapacity = 0;
+}
+
+template <class T, U32 alignment>
+void LLAlignedArray<T, alignment>::push_back(const T& elem)
+{
+ T* old_buf = NULL;
+ if (mCapacity <= mElementCount)
+ {
+ mCapacity++;
+ mCapacity *= 2;
+ T* new_buf = (T*) ll_aligned_malloc(mCapacity*sizeof(T), alignment);
+ if (mArray)
+ {
+ ll_memcpy_nonaliased_aligned_16((char*)new_buf, (char*)mArray, sizeof(T)*mElementCount);
+ }
+ old_buf = mArray;
+ mArray = new_buf;
+ }
+
+ mArray[mElementCount++] = elem;
+
+ //delete old array here to prevent error on a.push_back(a[0])
+ ll_aligned_free(old_buf);
+}
+
+template <class T, U32 alignment>
+void LLAlignedArray<T, alignment>::resize(U32 size)
+{
+ if (mCapacity < size)
+ {
+ mCapacity = size+mCapacity*2;
+ T* new_buf = mCapacity > 0 ? (T*) ll_aligned_malloc(mCapacity*sizeof(T), alignment) : NULL;
+ if (mArray)
+ {
+ ll_memcpy_nonaliased_aligned_16((char*) new_buf, (char*) mArray, sizeof(T)*mElementCount);
+ ll_aligned_free(mArray);
+ }
+
+ /*for (U32 i = mElementCount; i < mCapacity; ++i)
+ {
+ new(new_buf+i) T();
+ }*/
+ mArray = new_buf;
+ }
+
+ mElementCount = size;
+}
+
+
+template <class T, U32 alignment>
+T& LLAlignedArray<T, alignment>::operator[](int idx)
+{
+ llassert(idx < mElementCount);
+ return mArray[idx];
+}
+
+template <class T, U32 alignment>
+const T& LLAlignedArray<T, alignment>::operator[](int idx) const
+{
+ llassert(idx < mElementCount);
+ return mArray[idx];
+}
+
+template <class T, U32 alignment>
+T* LLAlignedArray<T, alignment>::append(S32 N)
+{
+ U32 sz = size();
+ resize(sz+N);
+ return &((*this)[sz]);
+}
+
+#endif
+
diff --git a/indra/llcommon/llallocator.cpp b/indra/llcommon/llallocator.cpp
index 6f6abefc67..34fc28d8cc 100644..100755
--- a/indra/llcommon/llallocator.cpp
+++ b/indra/llcommon/llallocator.cpp
@@ -27,7 +27,7 @@
#include "linden_common.h"
#include "llallocator.h"
-#if LL_USE_TCMALLOC
+#if (LL_USE_TCMALLOC && LL_USE_HEAP_PROFILER)
#include "google/heap-profiler.h"
#include "google/commandlineflags_public.h"
@@ -35,28 +35,6 @@
DECLARE_bool(heap_profile_use_stack_trace);
//DECLARE_double(tcmalloc_release_rate);
-// static
-void LLAllocator::pushMemType(S32 type)
-{
- if(isProfiling())
- {
- PushMemType(type);
- }
-}
-
-// static
-S32 LLAllocator::popMemType()
-{
- if (isProfiling())
- {
- return PopMemType();
- }
- else
- {
- return -1;
- }
-}
-
void LLAllocator::setProfilingEnabled(bool should_enable)
{
// NULL disables dumping to disk
@@ -94,17 +72,6 @@ std::string LLAllocator::getRawProfile()
// stub implementations for when tcmalloc is disabled
//
-// static
-void LLAllocator::pushMemType(S32 type)
-{
-}
-
-// static
-S32 LLAllocator::popMemType()
-{
- return -1;
-}
-
void LLAllocator::setProfilingEnabled(bool should_enable)
{
}
diff --git a/indra/llcommon/llallocator.h b/indra/llcommon/llallocator.h
index a91dd57d14..d26ad73c5b 100644..100755
--- a/indra/llcommon/llallocator.h
+++ b/indra/llcommon/llallocator.h
@@ -29,16 +29,10 @@
#include <string>
-#include "llmemtype.h"
#include "llallocator_heap_profile.h"
class LL_COMMON_API LLAllocator {
friend class LLMemoryView;
- friend class LLMemType;
-
-private:
- static void pushMemType(S32 type);
- static S32 popMemType();
public:
void setProfilingEnabled(bool should_enable);
diff --git a/indra/llcommon/llallocator_heap_profile.cpp b/indra/llcommon/llallocator_heap_profile.cpp
index b574ef668b..b574ef668b 100644..100755
--- a/indra/llcommon/llallocator_heap_profile.cpp
+++ b/indra/llcommon/llallocator_heap_profile.cpp
diff --git a/indra/llcommon/llallocator_heap_profile.h b/indra/llcommon/llallocator_heap_profile.h
index 69300b829b..69300b829b 100644..100755
--- a/indra/llcommon/llallocator_heap_profile.h
+++ b/indra/llcommon/llallocator_heap_profile.h
diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp
index ed192a9975..67a98d5fb8 100644..100755
--- a/indra/llcommon/llapp.cpp
+++ b/indra/llcommon/llapp.cpp
@@ -69,10 +69,16 @@ bool windows_post_minidump_callback(const wchar_t* dump_path,
void setup_signals();
void default_unix_signal_handler(int signum, siginfo_t *info, void *);
+#if LL_LINUX
+#include "google_breakpad/minidump_descriptor.h"
+bool unix_minidump_callback(const google_breakpad::MinidumpDescriptor& minidump_desc, void* context, bool succeeded);
+#else
// Called by breakpad exception handler after the minidump has been generated.
bool unix_post_minidump_callback(const char *dump_dir,
const char *minidump_id,
void *context, bool succeeded);
+#endif
+
# if LL_DARWIN
/* OSX doesn't support SIGRT* */
S32 LL_SMACKDOWN_SIGNAL = SIGUSR1;
@@ -289,6 +295,7 @@ void LLApp::setupErrorHandling()
// occasionally checks to see if the app is in an error state, and sees if it needs to be run.
#if LL_WINDOWS
+#if LL_SEND_CRASH_REPORTS
// This sets a callback to handle w32 signals to the console window.
// The viewer shouldn't be affected, sicne its a windowed app.
SetConsoleCtrlHandler( (PHANDLER_ROUTINE) ConsoleCtrlHandler, TRUE);
@@ -300,7 +307,7 @@ void LLApp::setupErrorHandling()
mExceptionHandler = new google_breakpad::ExceptionHandler(
L"C:\\Temp\\", 0, windows_post_minidump_callback, 0, google_breakpad::ExceptionHandler::HANDLER_ALL);
}
-
+#endif
#else
//
// Start up signal handling.
@@ -312,7 +319,7 @@ void LLApp::setupErrorHandling()
// Add google breakpad exception handler configured for Darwin/Linux.
bool installHandler = true;
-#ifdef LL_DARWIN
+#if LL_DARWIN
// For the special case of Darwin, we do not want to install the handler if
// the process is being debugged as the app will exit with value ABRT (6) if
// we do. Unfortunately, the code below which performs that test relies on
@@ -345,14 +352,21 @@ void LLApp::setupErrorHandling()
installHandler = true;
}
#endif
-#endif
+
if(installHandler && (mExceptionHandler == 0))
{
std::string dumpPath = "/tmp/";
- mExceptionHandler = new google_breakpad::ExceptionHandler(dumpPath, 0, &unix_post_minidump_callback, 0, true);
+ mExceptionHandler = new google_breakpad::ExceptionHandler(dumpPath, 0, &unix_post_minidump_callback, 0, true, 0);
+ }
+#elif LL_LINUX
+ if(installHandler && (mExceptionHandler == 0))
+ {
+ google_breakpad::MinidumpDescriptor desc("/tmp");
+ new google_breakpad::ExceptionHandler(desc, 0, &unix_minidump_callback, 0, true, 0);
}
#endif
+#endif
startErrorThread();
}
@@ -409,6 +423,9 @@ void LLApp::setMiniDumpDir(const std::string &path)
wchar_t buffer[MAX_MINDUMP_PATH_LENGTH];
mbstowcs(buffer, path.c_str(), MAX_MINDUMP_PATH_LENGTH);
mExceptionHandler->set_dump_path(std::wstring(buffer));
+#elif LL_LINUX
+ google_breakpad::MinidumpDescriptor desc(path);
+ mExceptionHandler->set_minidump_descriptor(desc);
#else
mExceptionHandler->set_dump_path(path);
#endif
@@ -856,6 +873,43 @@ void default_unix_signal_handler(int signum, siginfo_t *info, void *)
}
}
+#if LL_LINUX
+bool unix_minidump_callback(const google_breakpad::MinidumpDescriptor& minidump_desc, void* context, bool succeeded)
+{
+ // Copy minidump file path into fixed buffer in the app instance to avoid
+ // heap allocations in a crash handler.
+
+ // path format: <dump_dir>/<minidump_id>.dmp
+ int dirPathLength = strlen(minidump_desc.path());
+
+ // The path must not be truncated.
+ llassert((dirPathLength + 5) <= LLApp::MAX_MINDUMP_PATH_LENGTH);
+
+ char * path = LLApp::instance()->getMiniDumpFilename();
+ S32 remaining = LLApp::MAX_MINDUMP_PATH_LENGTH;
+ strncpy(path, minidump_desc.path(), remaining);
+ remaining -= dirPathLength;
+ path += dirPathLength;
+ if (remaining > 0 && dirPathLength > 0 && path[-1] != '/')
+ {
+ *path++ = '/';
+ --remaining;
+ }
+
+ llinfos << "generated minidump: " << LLApp::instance()->getMiniDumpFilename() << llendl;
+ LLApp::runErrorHandler();
+
+#ifndef LL_RELEASE_FOR_DOWNLOAD
+ clear_signals();
+ return false;
+#else
+ return true;
+#endif
+
+}
+#endif
+
+
bool unix_post_minidump_callback(const char *dump_dir,
const char *minidump_id,
void *context, bool succeeded)
@@ -932,9 +986,9 @@ bool windows_post_minidump_callback(const wchar_t* dump_path,
}
llinfos << "generated minidump: " << LLApp::instance()->getMiniDumpFilename() << llendl;
- // *NOTE:Mani - this code is stolen from LLApp, where its never actually used.
+ // *NOTE:Mani - this code is stolen from LLApp, where its never actually used.
//OSMessageBox("Attach Debugger Now", "Error", OSMB_OK);
- // *TODO: Translate the signals/exceptions into cross-platform stuff
+ // *TODO: Translate the signals/exceptions into cross-platform stuff
// Windows implementation
llinfos << "Entering Windows Exception Handler..." << llendl;
diff --git a/indra/llcommon/llapp.h b/indra/llcommon/llapp.h
index a536a06ea5..afa06df23e 100644..100755
--- a/indra/llcommon/llapp.h
+++ b/indra/llcommon/llapp.h
@@ -38,7 +38,7 @@ typedef LLAtomic32<U32> LLAtomicU32;
class LLErrorThread;
class LLLiveFile;
#if LL_LINUX
-typedef struct siginfo siginfo_t;
+#include <signal.h>
#endif
typedef void (*LLAppErrorHandler)();
diff --git a/indra/llcommon/llapr.cpp b/indra/llcommon/llapr.cpp
index d1c44c9403..b7815b0e35 100644..100755
--- a/indra/llcommon/llapr.cpp
+++ b/indra/llcommon/llapr.cpp
@@ -226,9 +226,7 @@ void LLVolatileAPRPool::clearVolatileAPRPool()
llassert_always(mNumActiveRef > 0) ;
}
- //paranoia check if the pool is jammed.
- //will remove the check before going to release.
- llassert_always(mNumTotalRef < (FULL_VOLATILE_APR_POOL << 2)) ;
+ llassert(mNumTotalRef <= (FULL_VOLATILE_APR_POOL << 2)) ;
}
BOOL LLVolatileAPRPool::isFull()
diff --git a/indra/llcommon/llapr.h b/indra/llcommon/llapr.h
index af33ce666f..1fe7d98472 100644..100755
--- a/indra/llcommon/llapr.h
+++ b/indra/llcommon/llapr.h
@@ -164,14 +164,20 @@ public:
~LLAtomic32<Type>() {};
operator const Type() { apr_uint32_t data = apr_atomic_read32(&mData); return Type(data); }
+
+ Type CurrentValue() const { apr_uint32_t data = apr_atomic_read32(const_cast< volatile apr_uint32_t* >(&mData)); return Type(data); }
+
Type operator =(const Type& x) { apr_atomic_set32(&mData, apr_uint32_t(x)); return Type(mData); }
void operator -=(Type x) { apr_atomic_sub32(&mData, apr_uint32_t(x)); }
void operator +=(Type x) { apr_atomic_add32(&mData, apr_uint32_t(x)); }
Type operator ++(int) { return apr_atomic_inc32(&mData); } // Type++
- Type operator --(int) { return apr_atomic_dec32(&mData); } // Type--
+ Type operator --(int) { return apr_atomic_dec32(&mData); } // approximately --Type (0 if final is 0, non-zero otherwise)
+
+ Type operator ++() { return apr_atomic_inc32(&mData); } // Type++
+ Type operator --() { return apr_atomic_dec32(&mData); } // approximately --Type (0 if final is 0, non-zero otherwise)
private:
- apr_uint32_t mData;
+ volatile apr_uint32_t mData;
};
typedef LLAtomic32<U32> LLAtomicU32;
@@ -182,8 +188,10 @@ typedef LLAtomic32<S32> LLAtomicS32;
// abbreviated flags
#define LL_APR_R (APR_READ) // "r"
#define LL_APR_W (APR_CREATE|APR_TRUNCATE|APR_WRITE) // "w"
+#define LL_APR_A (APR_CREATE|APR_WRITE|APR_APPEND) // "w"
#define LL_APR_RB (APR_READ|APR_BINARY) // "rb"
#define LL_APR_WB (APR_CREATE|APR_TRUNCATE|APR_WRITE|APR_BINARY) // "wb"
+#define LL_APR_AB (APR_CREATE|APR_WRITE|APR_BINARY|APR_APPEND)
#define LL_APR_RPB (APR_READ|APR_WRITE|APR_BINARY) // "r+b"
#define LL_APR_WPB (APR_CREATE|APR_TRUNCATE|APR_READ|APR_WRITE|APR_BINARY) // "w+b"
diff --git a/indra/llcommon/llassettype.cpp b/indra/llcommon/llassettype.cpp
index 5e566d6c7c..5ae2df3994 100644..100755
--- a/indra/llcommon/llassettype.cpp
+++ b/indra/llcommon/llassettype.cpp
@@ -95,6 +95,7 @@ LLAssetDictionary::LLAssetDictionary()
addEntry(LLAssetType::AT_LINK_FOLDER, new AssetEntry("FOLDER_LINK", "link_f", "sym folder link", false, false, true));
addEntry(LLAssetType::AT_MESH, new AssetEntry("MESH", "mesh", "mesh", false, false, false));
addEntry(LLAssetType::AT_WIDGET, new AssetEntry("WIDGET", "widget", "widget", false, false, false));
+ addEntry(LLAssetType::AT_PERSON, new AssetEntry("PERSON", "person", "person", false, false, false));
addEntry(LLAssetType::AT_NONE, new AssetEntry("NONE", "-1", NULL, FALSE, FALSE, FALSE));
};
diff --git a/indra/llcommon/llassettype.h b/indra/llcommon/llassettype.h
index d538accbf7..69b01731e5 100644..100755
--- a/indra/llcommon/llassettype.h
+++ b/indra/llcommon/llassettype.h
@@ -112,6 +112,9 @@ public:
AT_WIDGET = 40,
// UI Widget: this is *not* an inventory asset type, only a viewer side asset (e.g. button, other ui items...)
+ AT_PERSON = 45,
+ // A user uuid which is not an inventory asset type, used in viewer only for adding a person to a chat via drag and drop.
+
AT_MESH = 49,
// Mesh data in our proprietary SLM format
diff --git a/indra/llcommon/llassoclist.h b/indra/llcommon/llassoclist.h
index 2950504155..2950504155 100644..100755
--- a/indra/llcommon/llassoclist.h
+++ b/indra/llcommon/llassoclist.h
diff --git a/indra/llcommon/llavatarconstants.h b/indra/llcommon/llavatarconstants.h
index f47f447b45..f47f447b45 100644..100755
--- a/indra/llcommon/llavatarconstants.h
+++ b/indra/llcommon/llavatarconstants.h
diff --git a/indra/llcommon/llavatarname.cpp b/indra/llcommon/llavatarname.cpp
index 3206843bf4..642bd82e90 100644..100755
--- a/indra/llcommon/llavatarname.cpp
+++ b/indra/llcommon/llavatarname.cpp
@@ -30,6 +30,7 @@
#include "llavatarname.h"
#include "lldate.h"
+#include "llframetimer.h"
#include "llsd.h"
// Store these in pre-built std::strings to avoid memory allocations in
@@ -42,6 +43,14 @@ static const std::string IS_DISPLAY_NAME_DEFAULT("is_display_name_default");
static const std::string DISPLAY_NAME_EXPIRES("display_name_expires");
static const std::string DISPLAY_NAME_NEXT_UPDATE("display_name_next_update");
+bool LLAvatarName::sUseDisplayNames = true;
+
+// Minimum time-to-live (in seconds) for a name entry.
+// Avatar name should always guarantee to expire reasonably soon by default
+// so if the failure to get a valid expiration time was due to something temporary
+// we will eventually request and get the right data.
+const F64 MIN_ENTRY_LIFETIME = 60.0;
+
LLAvatarName::LLAvatarName()
: mUsername(),
mDisplayName(),
@@ -61,6 +70,17 @@ bool LLAvatarName::operator<(const LLAvatarName& rhs) const
return mUsername < rhs.mUsername;
}
+//static
+void LLAvatarName::setUseDisplayNames(bool use)
+{
+ sUseDisplayNames = use;
+}
+//static
+bool LLAvatarName::useDisplayNames()
+{
+ return sUseDisplayNames;
+}
+
LLSD LLAvatarName::asLLSD() const
{
LLSD sd;
@@ -85,21 +105,75 @@ void LLAvatarName::fromLLSD(const LLSD& sd)
mExpires = expires.secondsSinceEpoch();
LLDate next_update = sd[DISPLAY_NAME_NEXT_UPDATE];
mNextUpdate = next_update.secondsSinceEpoch();
+
+ // Some avatars don't have explicit display names set. Force a legible display name here.
+ if (mDisplayName.empty())
+ {
+ mDisplayName = mUsername;
+ }
+}
+
+// Transform a string (typically provided by the legacy service) into a decent
+// avatar name instance.
+void LLAvatarName::fromString(const std::string& full_name)
+{
+ mDisplayName = full_name;
+ std::string::size_type index = full_name.find(' ');
+ if (index != std::string::npos)
+ {
+ // The name is in 2 parts (first last)
+ mLegacyFirstName = full_name.substr(0, index);
+ mLegacyLastName = full_name.substr(index+1);
+ if (mLegacyLastName != "Resident")
+ {
+ mUsername = mLegacyFirstName + "." + mLegacyLastName;
+ mDisplayName = full_name;
+ LLStringUtil::toLower(mUsername);
+ }
+ else
+ {
+ // Very old names do have a dummy "Resident" last name
+ // that we choose to hide from users.
+ mUsername = mLegacyFirstName;
+ mDisplayName = mLegacyFirstName;
+ }
+ }
+ else
+ {
+ mLegacyFirstName = full_name;
+ mLegacyLastName = "";
+ mUsername = full_name;
+ mDisplayName = full_name;
+ }
+ mIsDisplayNameDefault = true;
+ mIsTemporaryName = true;
+ setExpires(MIN_ENTRY_LIFETIME);
+}
+
+void LLAvatarName::setExpires(F64 expires)
+{
+ mExpires = LLFrameTimer::getTotalSeconds() + expires;
}
std::string LLAvatarName::getCompleteName() const
{
std::string name;
- if (mUsername.empty() || mIsDisplayNameDefault)
- // If the display name feature is off
- // OR this particular display name is defaulted (i.e. based on user name),
- // then display only the easier to read instance of the person's name.
+ if (sUseDisplayNames)
{
- name = mDisplayName;
+ if (mUsername.empty() || mIsDisplayNameDefault)
+ {
+ // If this particular display name is defaulted (i.e. based on user name),
+ // then display only the easier to read instance of the person's name.
+ name = mDisplayName;
+ }
+ else
+ {
+ name = mDisplayName + " (" + mUsername + ")";
+ }
}
else
{
- name = mDisplayName + " (" + mUsername + ")";
+ name = getUserName();
}
return name;
}
@@ -118,3 +192,48 @@ std::string LLAvatarName::getLegacyName() const
name += mLegacyLastName;
return name;
}
+
+std::string LLAvatarName::getDisplayName() const
+{
+ if (sUseDisplayNames)
+ {
+ return mDisplayName;
+ }
+ else
+ {
+ return getUserName();
+ }
+}
+
+std::string LLAvatarName::getUserName() const
+{
+ std::string name;
+ if (mLegacyLastName.empty() || (mLegacyLastName == "Resident"))
+ {
+ if (mLegacyFirstName.empty())
+ {
+ // If we cannot create a user name from the legacy strings, use the display name
+ name = mDisplayName;
+ }
+ else
+ {
+ // The last name might be empty if it defaulted to "Resident"
+ name = mLegacyFirstName;
+ }
+ }
+ else
+ {
+ name = mLegacyFirstName + " " + mLegacyLastName;
+ }
+ return name;
+}
+
+void LLAvatarName::dump() const
+{
+ LL_DEBUGS("AvNameCache") << "LLAvatarName: "
+ << "user '" << mUsername << "' "
+ << "display '" << mDisplayName << "' "
+ << "expires in " << mExpires - LLFrameTimer::getTotalSeconds() << " seconds"
+ << LL_ENDL;
+}
+
diff --git a/indra/llcommon/llavatarname.h b/indra/llcommon/llavatarname.h
index ba258d6d52..5d2fccc5ba 100644..100755
--- a/indra/llcommon/llavatarname.h
+++ b/indra/llcommon/llavatarname.h
@@ -39,23 +39,67 @@ public:
bool operator<(const LLAvatarName& rhs) const;
+ // Conversion to and from LLSD (cache file or server response)
LLSD asLLSD() const;
-
void fromLLSD(const LLSD& sd);
+ // Used only in legacy mode when the display name capability is not provided server side
+ // or to otherwise create a temporary valid item.
+ void fromString(const std::string& full_name);
+
+ // Set the name object to become invalid in "expires" seconds from now
+ void setExpires(F64 expires);
+
+ // Set and get the display name flag set by the user in preferences.
+ static void setUseDisplayNames(bool use);
+ static bool useDisplayNames();
+
+ // A name object is valid if not temporary and not yet expired (default is expiration not checked)
+ bool isValidName(F64 max_unrefreshed = 0.0f) const { return !mIsTemporaryName && (mExpires >= max_unrefreshed); }
+
+ // Return true if the name is made up from legacy or temporary data
+ bool isDisplayNameDefault() const { return mIsDisplayNameDefault; }
+
// For normal names, returns "James Linden (james.linden)"
// When display names are disabled returns just "James Linden"
std::string getCompleteName() const;
-
+
// Returns "James Linden" or "bobsmith123 Resident" for backwards
// compatibility with systems like voice and muting
// *TODO: Eliminate this in favor of username only
std::string getLegacyName() const;
+
+ // "José Sanchez" or "James Linden", UTF-8 encoded Unicode
+ // Takes the display name preference into account. This is truly the name that should
+ // be used for all UI where an avatar name has to be used unless we truly want something else (rare)
+ std::string getDisplayName() const;
+
+ // Returns "James Linden" or "bobsmith123 Resident"
+ // Used where we explicitely prefer or need a non UTF-8 legacy (ASCII) name
+ // Also used for backwards compatibility with systems like voice and muting
+ std::string getUserName() const;
+
+ // Returns "james.linden" or the legacy name for very old names
+ std::string getAccountName() const { return mUsername; }
+ // Debug print of the object
+ void dump() const;
+
+ // Names can change, so need to keep track of when name was
+ // last checked.
+ // Unix time-from-epoch seconds for efficiency
+ F64 mExpires;
+
+ // You can only change your name every N hours, so record
+ // when the next update is allowed
+ // Unix time-from-epoch seconds
+ F64 mNextUpdate;
+
+private:
// "bobsmith123" or "james.linden", US-ASCII only
std::string mUsername;
- // "Jose' Sanchez" or "James Linden", UTF-8 encoded Unicode
+ // "José Sanchez" or "James Linden", UTF-8 encoded Unicode
// Contains data whether or not user has explicitly set
// a display name; may duplicate their username.
std::string mDisplayName;
@@ -81,15 +125,9 @@ public:
// shown in UI, but are not serialized.
bool mIsTemporaryName;
- // Names can change, so need to keep track of when name was
- // last checked.
- // Unix time-from-epoch seconds for efficiency
- F64 mExpires;
-
- // You can only change your name every N hours, so record
- // when the next update is allowed
- // Unix time-from-epoch seconds
- F64 mNextUpdate;
+ // Global flag indicating if display name should be used or not
+ // This will affect the output of the high level "get" methods
+ static bool sUseDisplayNames;
};
#endif
diff --git a/indra/llcommon/llbase32.cpp b/indra/llcommon/llbase32.cpp
index 053ac0d32f..053ac0d32f 100644..100755
--- a/indra/llcommon/llbase32.cpp
+++ b/indra/llcommon/llbase32.cpp
diff --git a/indra/llcommon/llbase32.h b/indra/llcommon/llbase32.h
index eeb96d789d..eeb96d789d 100644..100755
--- a/indra/llcommon/llbase32.h
+++ b/indra/llcommon/llbase32.h
diff --git a/indra/llcommon/llbase64.cpp b/indra/llcommon/llbase64.cpp
index 4e82cf7f20..4e82cf7f20 100644..100755
--- a/indra/llcommon/llbase64.cpp
+++ b/indra/llcommon/llbase64.cpp
diff --git a/indra/llcommon/llbase64.h b/indra/llcommon/llbase64.h
index 16d2c217d0..16d2c217d0 100644..100755
--- a/indra/llcommon/llbase64.h
+++ b/indra/llcommon/llbase64.h
diff --git a/indra/llcommon/llboost.h b/indra/llcommon/llboost.h
index 57d958a51a..57d958a51a 100644..100755
--- a/indra/llcommon/llboost.h
+++ b/indra/llcommon/llboost.h
diff --git a/indra/llcommon/llchat.h b/indra/llcommon/llchat.h
index f5b242fdfc..f5b242fdfc 100644..100755
--- a/indra/llcommon/llchat.h
+++ b/indra/llcommon/llchat.h
diff --git a/indra/llcommon/llclickaction.h b/indra/llcommon/llclickaction.h
index 1f87d8eec3..1f87d8eec3 100644..100755
--- a/indra/llcommon/llclickaction.h
+++ b/indra/llcommon/llclickaction.h
diff --git a/indra/llcommon/llcommon.cpp b/indra/llcommon/llcommon.cpp
index 8be9e4f4de..b938b0e65a 100644..100755
--- a/indra/llcommon/llcommon.cpp
+++ b/indra/llcommon/llcommon.cpp
@@ -44,6 +44,7 @@ void LLCommon::initClass()
}
LLTimer::initClass();
LLThreadSafeRefCount::initThreadSafeRefCount();
+ assert_main_thread(); // Make sure we record the main thread
// LLWorkerThread::initClass();
// LLFrameCallbackManager::initClass();
}
diff --git a/indra/llcommon/llcommon.h b/indra/llcommon/llcommon.h
index ca9cad5d05..ca9cad5d05 100644..100755
--- a/indra/llcommon/llcommon.h
+++ b/indra/llcommon/llcommon.h
diff --git a/indra/llcommon/llcommonutils.cpp b/indra/llcommon/llcommonutils.cpp
index d82554c202..d82554c202 100644..100755
--- a/indra/llcommon/llcommonutils.cpp
+++ b/indra/llcommon/llcommonutils.cpp
diff --git a/indra/llcommon/llcommonutils.h b/indra/llcommon/llcommonutils.h
index 755dc41fb4..755dc41fb4 100644..100755
--- a/indra/llcommon/llcommonutils.h
+++ b/indra/llcommon/llcommonutils.h
diff --git a/indra/llcommon/llcoros.cpp b/indra/llcommon/llcoros.cpp
index 0b5829eb7e..baaddcaed1 100644..100755
--- a/indra/llcommon/llcoros.cpp
+++ b/indra/llcommon/llcoros.cpp
@@ -39,7 +39,12 @@
#include "llerror.h"
#include "stringize.h"
-LLCoros::LLCoros()
+LLCoros::LLCoros():
+ // MAINT-2724: default coroutine stack size too small on Windows.
+ // Previously we used
+ // boost::context::guarded_stack_allocator::default_stacksize();
+ // empirically this is 64KB on Windows and Linux. Try quadrupling.
+ mStackSize(256*1024)
{
// Register our cleanup() method for "mainloop" ticks
LLEventPumps::instance().obtain("mainloop").listen(
@@ -55,7 +60,7 @@ bool LLCoros::cleanup(const LLSD&)
// since last tick?
if (mi->second->exited())
{
- LL_INFOS("LLCoros") << "LLCoros: cleaning up coroutine " << mi->first << LL_ENDL;
+ LL_INFOS("LLCoros") << "LLCoros: cleaning up coroutine " << mi->first << LL_ENDL;
// The erase() call will invalidate its passed iterator value --
// so increment mi FIRST -- but pass its original value to
// erase(). This is what postincrement is all about.
@@ -89,7 +94,7 @@ std::string LLCoros::generateDistinctName(const std::string& prefix) const
{
if (mCoros.find(name) == mCoros.end())
{
- LL_INFOS("LLCoros") << "LLCoros: launching coroutine " << name << LL_ENDL;
+ LL_INFOS("LLCoros") << "LLCoros: launching coroutine " << name << LL_ENDL;
return name;
}
}
@@ -115,7 +120,7 @@ std::string LLCoros::getNameByID(const void* self_id) const
// passed to us comes.
for (CoroMap::const_iterator mi(mCoros.begin()), mend(mCoros.end()); mi != mend; ++mi)
{
- namespace coro_private = boost::coroutines::detail;
+ namespace coro_private = boost::dcoroutines::detail;
if (static_cast<void*>(coro_private::coroutine_accessor::get_impl(const_cast<coro&>(*mi->second)).get())
== self_id)
{
@@ -125,6 +130,12 @@ std::string LLCoros::getNameByID(const void* self_id) const
return "";
}
+void LLCoros::setStackSize(S32 stacksize)
+{
+ LL_INFOS("LLCoros") << "Setting coroutine stack size to " << stacksize << LL_ENDL;
+ mStackSize = stacksize;
+}
+
/*****************************************************************************
* MUST BE LAST
*****************************************************************************/
diff --git a/indra/llcommon/llcoros.h b/indra/llcommon/llcoros.h
index d75f28ec1a..01ee11da1a 100644..100755
--- a/indra/llcommon/llcoros.h
+++ b/indra/llcommon/llcoros.h
@@ -29,7 +29,7 @@
#if ! defined(LL_LLCOROS_H)
#define LL_LLCOROS_H
-#include <boost/coroutine/coroutine.hpp>
+#include <boost/dcoroutine/coroutine.hpp>
#include "llsingleton.h"
#include <boost/ptr_container/ptr_map.hpp>
#include <string>
@@ -78,8 +78,8 @@
class LL_COMMON_API LLCoros: public LLSingleton<LLCoros>
{
public:
- /// Canonical boost::coroutines::coroutine signature we use
- typedef boost::coroutines::coroutine<void()> coro;
+ /// Canonical boost::dcoroutines::coroutine signature we use
+ typedef boost::dcoroutines::coroutine<void()> coro;
/// Canonical 'self' type
typedef coro::self self;
@@ -125,7 +125,7 @@ public:
template <typename CALLABLE>
std::string launch(const std::string& prefix, const CALLABLE& callable)
{
- return launchImpl(prefix, new coro(callable));
+ return launchImpl(prefix, new coro(callable, mStackSize));
}
/**
@@ -152,6 +152,9 @@ public:
/// getName() by self.get_id()
std::string getNameByID(const void* self_id) const;
+ /// for delayed initialization
+ void setStackSize(S32 stacksize);
+
private:
friend class LLSingleton<LLCoros>;
LLCoros();
@@ -159,6 +162,7 @@ private:
std::string generateDistinctName(const std::string& prefix) const;
bool cleanup(const LLSD&);
+ S32 mStackSize;
typedef boost::ptr_map<std::string, coro> CoroMap;
CoroMap mCoros;
};
diff --git a/indra/llcommon/llcrc.cpp b/indra/llcommon/llcrc.cpp
index e80da0bb0d..e80da0bb0d 100644..100755
--- a/indra/llcommon/llcrc.cpp
+++ b/indra/llcommon/llcrc.cpp
diff --git a/indra/llcommon/llcrc.h b/indra/llcommon/llcrc.h
index 2d291d92a1..2d291d92a1 100644..100755
--- a/indra/llcommon/llcrc.h
+++ b/indra/llcommon/llcrc.h
diff --git a/indra/llcommon/llcriticaldamp.cpp b/indra/llcommon/llcriticaldamp.cpp
index 87d79b1ee0..49aac9ce75 100644..100755
--- a/indra/llcommon/llcriticaldamp.cpp
+++ b/indra/llcommon/llcriticaldamp.cpp
@@ -87,3 +87,4 @@ F32 LLCriticalDamp::getInterpolant(const F32 time_constant, BOOL use_cache)
return interpolant;
}
+
diff --git a/indra/llcommon/llcriticaldamp.h b/indra/llcommon/llcriticaldamp.h
index 52f052ae25..52f052ae25 100644..100755
--- a/indra/llcommon/llcriticaldamp.h
+++ b/indra/llcommon/llcriticaldamp.h
diff --git a/indra/llcommon/llcursortypes.cpp b/indra/llcommon/llcursortypes.cpp
index e987c397bd..ec60097195 100644..100755
--- a/indra/llcommon/llcursortypes.cpp
+++ b/indra/llcommon/llcursortypes.cpp
@@ -69,6 +69,12 @@ ECursorType getCursorFromString(const std::string& cursor_string)
cursor_string_table["UI_CURSOR_TOOLSIT"] = UI_CURSOR_TOOLSIT;
cursor_string_table["UI_CURSOR_TOOLBUY"] = UI_CURSOR_TOOLBUY;
cursor_string_table["UI_CURSOR_TOOLOPEN"] = UI_CURSOR_TOOLOPEN;
+ cursor_string_table["UI_CURSOR_TOOLPATHFINDING"] = UI_CURSOR_TOOLPATHFINDING;
+ cursor_string_table["UI_CURSOR_TOOLPATHFINDINGPATHSTART"] = UI_CURSOR_TOOLPATHFINDING_PATH_START;
+ cursor_string_table["UI_CURSOR_TOOLPATHFINDINGPATHSTARTADD"] = UI_CURSOR_TOOLPATHFINDING_PATH_START_ADD;
+ cursor_string_table["UI_CURSOR_TOOLPATHFINDINGPATHEND"] = UI_CURSOR_TOOLPATHFINDING_PATH_END;
+ cursor_string_table["UI_CURSOR_TOOLPATHFINDINGPATHENDADD"] = UI_CURSOR_TOOLPATHFINDING_PATH_END_ADD;
+ cursor_string_table["UI_CURSOR_TOOLNO"] = UI_CURSOR_TOOLNO;
}
std::map<std::string,U32>::const_iterator iter = cursor_string_table.find(cursor_string);
diff --git a/indra/llcommon/llcursortypes.h b/indra/llcommon/llcursortypes.h
index bacb0a80ba..cb6d6636a0 100644..100755
--- a/indra/llcommon/llcursortypes.h
+++ b/indra/llcommon/llcursortypes.h
@@ -65,6 +65,12 @@ enum ECursorType {
UI_CURSOR_TOOLSIT,
UI_CURSOR_TOOLBUY,
UI_CURSOR_TOOLOPEN,
+ UI_CURSOR_TOOLPATHFINDING,
+ UI_CURSOR_TOOLPATHFINDING_PATH_START,
+ UI_CURSOR_TOOLPATHFINDING_PATH_START_ADD,
+ UI_CURSOR_TOOLPATHFINDING_PATH_END,
+ UI_CURSOR_TOOLPATHFINDING_PATH_END_ADD,
+ UI_CURSOR_TOOLNO,
UI_CURSOR_COUNT // Number of elements in this enum (NOT a cursor)
};
diff --git a/indra/llcommon/lldarray.h b/indra/llcommon/lldarray.h
index 131b819c99..131b819c99 100644..100755
--- a/indra/llcommon/lldarray.h
+++ b/indra/llcommon/lldarray.h
diff --git a/indra/llcommon/lldarrayptr.h b/indra/llcommon/lldarrayptr.h
index c9a0b204d1..c9a0b204d1 100644..100755
--- a/indra/llcommon/lldarrayptr.h
+++ b/indra/llcommon/lldarrayptr.h
diff --git a/indra/llcommon/lldate.cpp b/indra/llcommon/lldate.cpp
index 030ef6a3c7..030ef6a3c7 100644..100755
--- a/indra/llcommon/lldate.cpp
+++ b/indra/llcommon/lldate.cpp
diff --git a/indra/llcommon/lldate.h b/indra/llcommon/lldate.h
index 7ff8b550ad..7ff8b550ad 100644..100755
--- a/indra/llcommon/lldate.h
+++ b/indra/llcommon/lldate.h
diff --git a/indra/llcommon/lldefs.h b/indra/llcommon/lldefs.h
index 5a4b8325f4..5a4b8325f4 100644..100755
--- a/indra/llcommon/lldefs.h
+++ b/indra/llcommon/lldefs.h
diff --git a/indra/llcommon/lldeleteutils.h b/indra/llcommon/lldeleteutils.h
index f250dc3028..f250dc3028 100644..100755
--- a/indra/llcommon/lldeleteutils.h
+++ b/indra/llcommon/lldeleteutils.h
diff --git a/indra/llcommon/lldependencies.cpp b/indra/llcommon/lldependencies.cpp
index 0e72c175cb..0e72c175cb 100644..100755
--- a/indra/llcommon/lldependencies.cpp
+++ b/indra/llcommon/lldependencies.cpp
diff --git a/indra/llcommon/lldependencies.h b/indra/llcommon/lldependencies.h
index e0294e271b..e0294e271b 100644..100755
--- a/indra/llcommon/lldependencies.h
+++ b/indra/llcommon/lldependencies.h
diff --git a/indra/llcommon/lldepthstack.h b/indra/llcommon/lldepthstack.h
index d9db54efc7..d9db54efc7 100644..100755
--- a/indra/llcommon/lldepthstack.h
+++ b/indra/llcommon/lldepthstack.h
diff --git a/indra/llcommon/lldictionary.cpp b/indra/llcommon/lldictionary.cpp
index e16c35ed6a..e16c35ed6a 100644..100755
--- a/indra/llcommon/lldictionary.cpp
+++ b/indra/llcommon/lldictionary.cpp
diff --git a/indra/llcommon/lldictionary.h b/indra/llcommon/lldictionary.h
index bc3bc3e74a..c752859a36 100644..100755
--- a/indra/llcommon/lldictionary.h
+++ b/indra/llcommon/lldictionary.h
@@ -30,6 +30,8 @@
#include <map>
#include <string>
+#include "llerror.h"
+
struct LL_COMMON_API LLDictionaryEntry
{
LLDictionaryEntry(const std::string &name);
diff --git a/indra/llcommon/lldlinked.h b/indra/llcommon/lldlinked.h
index 3f7c197be7..3f7c197be7 100644..100755
--- a/indra/llcommon/lldlinked.h
+++ b/indra/llcommon/lldlinked.h
diff --git a/indra/llcommon/lldoubledispatch.h b/indra/llcommon/lldoubledispatch.h
index 8ed295b6f1..8ed295b6f1 100644..100755
--- a/indra/llcommon/lldoubledispatch.h
+++ b/indra/llcommon/lldoubledispatch.h
diff --git a/indra/llcommon/lldqueueptr.h b/indra/llcommon/lldqueueptr.h
index 9fe08191e1..9fe08191e1 100644..100755
--- a/indra/llcommon/lldqueueptr.h
+++ b/indra/llcommon/lldqueueptr.h
diff --git a/indra/llcommon/llendianswizzle.h b/indra/llcommon/llendianswizzle.h
index 4c08074a9c..4c08074a9c 100644..100755
--- a/indra/llcommon/llendianswizzle.h
+++ b/indra/llcommon/llendianswizzle.h
diff --git a/indra/llcommon/llenum.h b/indra/llcommon/llenum.h
index f57b2bc0b5..f57b2bc0b5 100644..100755
--- a/indra/llcommon/llenum.h
+++ b/indra/llcommon/llenum.h
diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp
index e4381dbbd6..d2af004cde 100644..100755
--- a/indra/llcommon/llerror.cpp
+++ b/indra/llcommon/llerror.cpp
@@ -201,10 +201,7 @@ namespace {
virtual void recordMessage(LLError::ELevel level,
const std::string& message)
{
- llutf16string utf16str =
- wstring_to_utf16str(utf8str_to_wstring(message));
- utf16str += '\n';
- OutputDebugString(utf16str.c_str());
+ LL_WINDOWS_OUTPUT_DEBUG(message);
}
};
#endif
@@ -534,7 +531,7 @@ namespace
}
- void commonInit(const std::string& dir)
+ void commonInit(const std::string& dir, bool log_to_stderr = true)
{
LLError::Settings::reset();
@@ -542,7 +539,8 @@ namespace
LLError::setFatalFunction(LLError::crashAndLoop);
LLError::setTimeFunction(LLError::utcTime);
- if (shouldLogToStderr())
+ // log_to_stderr is only false in the unit and integration tests to keep builds quieter
+ if (log_to_stderr && shouldLogToStderr())
{
LLError::addRecorder(new RecordToStderr(stderrLogWantsTime()));
}
@@ -580,9 +578,9 @@ namespace LLError
#endif
}
- void initForApplication(const std::string& dir)
+ void initForApplication(const std::string& dir, bool log_to_stderr)
{
- commonInit(dir);
+ commonInit(dir, log_to_stderr);
}
void setPrintLocation(bool print)
@@ -654,9 +652,7 @@ namespace LLError
g.invalidateCallSites();
s.tagLevelMap[tag_name] = level;
}
-}
-namespace {
LLError::ELevel decodeLevel(std::string name)
{
static LevelMap level_names;
@@ -681,7 +677,9 @@ namespace {
return i->second;
}
-
+}
+
+namespace {
void setLevels(LevelMap& map, const LLSD& list, LLError::ELevel level)
{
LLSD::array_const_iterator i, end;
@@ -1400,5 +1398,27 @@ namespace LLError
{
sIndex = 0 ;
}
+
+#if LL_WINDOWS
+ void LLOutputDebugUTF8(const std::string& s)
+ {
+ // Be careful when calling OutputDebugString as it throws DBG_PRINTEXCEPTION_C
+ // which works just fine under the windows debugger, but can cause users who
+ // have enabled SEHOP exception chain validation to crash due to interactions
+ // between the Win 32-bit exception handling and boost coroutine fiber stacks. BUG-2707
+ //
+ if (IsDebuggerPresent())
+ {
+ // Need UTF16 for Unicode OutputDebugString
+ //
+ if (s.size())
+ {
+ OutputDebugString(utf8str_to_utf16str(s).c_str());
+ OutputDebugString(TEXT("\n"));
+ }
+ }
+ }
+#endif
+
}
diff --git a/indra/llcommon/llerror.h b/indra/llcommon/llerror.h
index b3e604f8e8..0b723aeb5d 100644..100755
--- a/indra/llcommon/llerror.h
+++ b/indra/llcommon/llerror.h
@@ -34,8 +34,7 @@
#include "llerrorlegacy.h"
#include "stdtypes.h"
-
-/* Error Logging Facility
+/** Error Logging Facility
Information for most users:
@@ -100,7 +99,6 @@
even release. Which means you can use them to help debug even when deployed
to a real grid.
*/
-
namespace LLError
{
enum ELevel
@@ -143,9 +141,13 @@ namespace LLError
CallSite(ELevel, const char* file, int line,
const std::type_info& class_info, const char* function, const char* broadTag, const char* narrowTag, bool printOnce);
+#ifdef LL_LIBRARY_INCLUDE
+ bool shouldLog();
+#else // LL_LIBRARY_INCLUDE
bool shouldLog()
{ return mCached ? mShouldLog : Log::shouldLog(*this); }
// this member function needs to be in-line for efficiency
+#endif // LL_LIBRARY_INCLUDE
void invalidate();
@@ -196,8 +198,20 @@ namespace LLError
static void clear() ;
static void end(std::ostringstream* _out) ;
};
+
+#if LL_WINDOWS
+ void LLOutputDebugUTF8(const std::string& s);
+#endif
+
}
+#if LL_WINDOWS
+ // Macro accepting a std::string for display in windows debugging console
+ #define LL_WINDOWS_OUTPUT_DEBUG(a) LLError::LLOutputDebugUTF8(a)
+#else
+ #define LL_WINDOWS_OUTPUT_DEBUG(a)
+#endif
+
//this is cheaper than llcallstacks if no need to output other variables to call stacks.
#define llpushcallstacks LLError::LLCallStacks::push(__FUNCTION__, __LINE__)
#define llcallstacks \
diff --git a/indra/llcommon/llerrorcontrol.h b/indra/llcommon/llerrorcontrol.h
index ed9de002f5..480654b1a2 100644..100755
--- a/indra/llcommon/llerrorcontrol.h
+++ b/indra/llcommon/llerrorcontrol.h
@@ -1,4 +1,4 @@
-/**
+/**
* @file llerrorcontrol.h
* @date December 2006
* @brief error message system control
@@ -6,21 +6,21 @@
* $LicenseInfo:firstyear=2007&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$
*/
@@ -38,7 +38,7 @@ class LLSD;
This is the part of the LLError namespace that manages the messages
produced by the logging. The logging support is defined in llerror.h.
Most files do not need to include this.
-
+
These implementations are in llerror.cpp.
*/
@@ -62,7 +62,7 @@ namespace LLError
// logs to stderr, syslog, and windows debug log
// the identity string is used for in the syslog
- LL_COMMON_API void initForApplication(const std::string& dir);
+ LL_COMMON_API void initForApplication(const std::string& dir, bool log_to_stderr = true);
// resets all logging settings to defaults needed by applicaitons
// logs to stderr and windows debug log
// sets up log configuration from the file logcontrol.xml in dir
@@ -72,7 +72,7 @@ namespace LLError
Settings that control what is logged.
Setting a level means log messages at that level or above.
*/
-
+
LL_COMMON_API void setPrintLocation(bool);
LL_COMMON_API void setDefaultLevel(LLError::ELevel);
LL_COMMON_API ELevel getDefaultLevel();
@@ -80,7 +80,8 @@ namespace LLError
LL_COMMON_API void setClassLevel(const std::string& class_name, LLError::ELevel);
LL_COMMON_API void setFileLevel(const std::string& file_name, LLError::ELevel);
LL_COMMON_API void setTagLevel(const std::string& file_name, LLError::ELevel);
-
+
+ LL_COMMON_API LLError::ELevel decodeLevel(std::string name);
LL_COMMON_API void configure(const LLSD&);
// the LLSD can configure all of the settings
// usually read automatically from the live errorlog.xml file
@@ -100,31 +101,31 @@ namespace LLError
// (by, for example, setting a class level to LEVEL_NONE), will keep
// the that message from causing the fatal funciton to be invoked.
- LL_COMMON_API FatalFunction getFatalFunction();
- // Retrieve the previously-set FatalFunction
-
- /// temporarily override the FatalFunction for the duration of a
- /// particular scope, e.g. for unit tests
- class LL_COMMON_API OverrideFatalFunction
- {
- public:
- OverrideFatalFunction(const FatalFunction& func):
- mPrev(getFatalFunction())
- {
- setFatalFunction(func);
- }
- ~OverrideFatalFunction()
- {
- setFatalFunction(mPrev);
- }
-
- private:
- FatalFunction mPrev;
- };
+ LL_COMMON_API FatalFunction getFatalFunction();
+ // Retrieve the previously-set FatalFunction
+
+ /// temporarily override the FatalFunction for the duration of a
+ /// particular scope, e.g. for unit tests
+ class LL_COMMON_API OverrideFatalFunction
+ {
+ public:
+ OverrideFatalFunction(const FatalFunction& func):
+ mPrev(getFatalFunction())
+ {
+ setFatalFunction(func);
+ }
+ ~OverrideFatalFunction()
+ {
+ setFatalFunction(mPrev);
+ }
+
+ private:
+ FatalFunction mPrev;
+ };
typedef std::string (*TimeFunction)();
LL_COMMON_API std::string utcTime();
-
+
LL_COMMON_API void setTimeFunction(TimeFunction);
// The function is use to return the current time, formatted for
// display by those error recorders that want the time included.
@@ -136,19 +137,27 @@ namespace LLError
// An object that handles the actual output or error messages.
public:
virtual ~Recorder();
-
+
virtual void recordMessage(LLError::ELevel, const std::string& message) = 0;
// use the level for better display, not for filtering
-
+
virtual bool wantsTime(); // default returns false
// override and return true if the recorder wants the time string
// included in the text of the message
};
-
+
+ /**
+ * @NOTE: addRecorder() conveys ownership to the underlying Settings
+ * object -- when destroyed, it will @em delete the passed Recorder*!
+ */
LL_COMMON_API void addRecorder(Recorder*);
+ /**
+ * @NOTE: removeRecorder() reclaims ownership of the Recorder*: its
+ * lifespan becomes the caller's problem.
+ */
LL_COMMON_API void removeRecorder(Recorder*);
// each error message is passed to each recorder via recordMessage()
-
+
LL_COMMON_API void logToFile(const std::string& filename);
LL_COMMON_API void logToFixedBuffer(LLLineBuffer*);
// Utilities to add recorders for logging to a file or a fixed buffer
@@ -166,10 +175,9 @@ namespace LLError
class Settings;
LL_COMMON_API Settings* saveAndResetSettings();
LL_COMMON_API void restoreSettings(Settings *);
-
+
LL_COMMON_API std::string abbreviateFile(const std::string& filePath);
LL_COMMON_API int shouldLogCallCount();
-
};
#endif // LL_LLERRORCONTROL_H
diff --git a/indra/llcommon/llerrorlegacy.h b/indra/llcommon/llerrorlegacy.h
index 37cee579cd..37cee579cd 100644..100755
--- a/indra/llcommon/llerrorlegacy.h
+++ b/indra/llcommon/llerrorlegacy.h
diff --git a/indra/llcommon/llerrorthread.cpp b/indra/llcommon/llerrorthread.cpp
index 902eaa3b72..950fcd6e83 100644..100755
--- a/indra/llcommon/llerrorthread.cpp
+++ b/indra/llcommon/llerrorthread.cpp
@@ -112,13 +112,8 @@ void LLErrorThread::run()
#if !LL_WINDOWS
U32 last_sig_child_count = 0;
#endif
- while (1)
+ while (! (LLApp::isError() || LLApp::isStopped()))
{
- if (LLApp::isError() || LLApp::isStopped())
- {
- // The application has stopped running, time to take action (maybe)
- break;
- }
#if !LL_WINDOWS
// Check whether or not the main thread had a sig child we haven't handled.
U32 current_sig_child_count = LLApp::getSigChildCount();
diff --git a/indra/llcommon/llerrorthread.h b/indra/llcommon/llerrorthread.h
index 474cef3a50..474cef3a50 100644..100755
--- a/indra/llcommon/llerrorthread.h
+++ b/indra/llcommon/llerrorthread.h
diff --git a/indra/llcommon/llevent.cpp b/indra/llcommon/llevent.cpp
index 633df01588..633df01588 100644..100755
--- a/indra/llcommon/llevent.cpp
+++ b/indra/llcommon/llevent.cpp
diff --git a/indra/llcommon/llevent.h b/indra/llcommon/llevent.h
index 8cd682b8bf..8cd682b8bf 100644..100755
--- a/indra/llcommon/llevent.h
+++ b/indra/llcommon/llevent.h
diff --git a/indra/llcommon/lleventapi.cpp b/indra/llcommon/lleventapi.cpp
index ff5459c1eb..ff5459c1eb 100644..100755
--- a/indra/llcommon/lleventapi.cpp
+++ b/indra/llcommon/lleventapi.cpp
diff --git a/indra/llcommon/lleventapi.h b/indra/llcommon/lleventapi.h
index 1a37d780b6..5991fe8fd5 100644..100755
--- a/indra/llcommon/lleventapi.h
+++ b/indra/llcommon/lleventapi.h
@@ -47,6 +47,7 @@ class LL_COMMON_API LLEventAPI: public LLDispatchListener,
typedef LLInstanceTracker<LLEventAPI, std::string> ibase;
public:
+
/**
* @param name LLEventPump name on which this LLEventAPI will listen. This
* also serves as the LLInstanceTracker instance key.
diff --git a/indra/llcommon/lleventcoro.cpp b/indra/llcommon/lleventcoro.cpp
index 81cc33fbba..81cc33fbba 100644..100755
--- a/indra/llcommon/lleventcoro.cpp
+++ b/indra/llcommon/lleventcoro.cpp
diff --git a/indra/llcommon/lleventcoro.h b/indra/llcommon/lleventcoro.h
index 88a5e6ec74..a42af63b65 100644..100755
--- a/indra/llcommon/lleventcoro.h
+++ b/indra/llcommon/lleventcoro.h
@@ -29,8 +29,8 @@
#if ! defined(LL_LLEVENTCORO_H)
#define LL_LLEVENTCORO_H
-#include <boost/coroutine/coroutine.hpp>
-#include <boost/coroutine/future.hpp>
+#include <boost/dcoroutine/coroutine.hpp>
+#include <boost/dcoroutine/future.hpp>
#include <boost/optional.hpp>
#include <string>
#include <stdexcept>
@@ -206,13 +206,13 @@ LLSD postAndWait(SELF& self, const LLSD& event, const LLEventPumpOrPumpName& req
const LLEventPumpOrPumpName& replyPump, const LLSD& replyPumpNamePath=LLSD())
{
// declare the future
- boost::coroutines::future<LLSD> future(self);
+ boost::dcoroutines::future<LLSD> future(self);
// make a callback that will assign a value to the future, and listen on
// the specified LLEventPump with that callback
std::string listenerName(LLEventDetail::listenerNameForCoro(self));
LLTempBoundListener connection(
replyPump.getPump().listen(listenerName,
- voidlistener(boost::coroutines::make_callback(future))));
+ voidlistener(boost::dcoroutines::make_callback(future))));
// skip the "post" part if requestPump is default-constructed
if (requestPump)
{
@@ -257,7 +257,7 @@ namespace LLEventDetail
* This helper is specifically for the two-pump version of waitForEventOn().
* We use a single future object, but we want to listen on two pumps with it.
* Since we must still adapt from (the callable constructed by)
- * boost::coroutines::make_callback() (void return) to provide an event
+ * boost::dcoroutines::make_callback() (void return) to provide an event
* listener (bool return), we've adapted LLVoidListener for the purpose. The
* basic idea is that we construct a distinct instance of WaitForEventOnHelper
* -- binding different instance data -- for each of the pumps. Then, when a
@@ -331,16 +331,16 @@ LLEventWithID postAndWait2(SELF& self, const LLSD& event,
const LLSD& replyPump1NamePath=LLSD())
{
// declare the future
- boost::coroutines::future<LLEventWithID> future(self);
+ boost::dcoroutines::future<LLEventWithID> future(self);
// either callback will assign a value to this future; listen on
// each specified LLEventPump with a callback
std::string name(LLEventDetail::listenerNameForCoro(self));
LLTempBoundListener connection0(
replyPump0.getPump().listen(name + "a",
- LLEventDetail::wfeoh(boost::coroutines::make_callback(future), 0)));
+ LLEventDetail::wfeoh(boost::dcoroutines::make_callback(future), 0)));
LLTempBoundListener connection1(
replyPump1.getPump().listen(name + "b",
- LLEventDetail::wfeoh(boost::coroutines::make_callback(future), 1)));
+ LLEventDetail::wfeoh(boost::dcoroutines::make_callback(future), 1)));
// skip the "post" part if requestPump is default-constructed
if (requestPump)
{
diff --git a/indra/llcommon/lleventdispatcher.cpp b/indra/llcommon/lleventdispatcher.cpp
index 5b6d4efbe9..5b6d4efbe9 100644..100755
--- a/indra/llcommon/lleventdispatcher.cpp
+++ b/indra/llcommon/lleventdispatcher.cpp
diff --git a/indra/llcommon/lleventdispatcher.h b/indra/llcommon/lleventdispatcher.h
index 7acc61de4e..7acc61de4e 100644..100755
--- a/indra/llcommon/lleventdispatcher.h
+++ b/indra/llcommon/lleventdispatcher.h
diff --git a/indra/llcommon/lleventemitter.h b/indra/llcommon/lleventemitter.h
index cd82fc56f9..cd82fc56f9 100644..100755
--- a/indra/llcommon/lleventemitter.h
+++ b/indra/llcommon/lleventemitter.h
diff --git a/indra/llcommon/lleventfilter.cpp b/indra/llcommon/lleventfilter.cpp
index d36a107254..d36a107254 100644..100755
--- a/indra/llcommon/lleventfilter.cpp
+++ b/indra/llcommon/lleventfilter.cpp
diff --git a/indra/llcommon/lleventfilter.h b/indra/llcommon/lleventfilter.h
index e822a664f5..e822a664f5 100644..100755
--- a/indra/llcommon/lleventfilter.h
+++ b/indra/llcommon/lleventfilter.h
diff --git a/indra/llcommon/llevents.cpp b/indra/llcommon/llevents.cpp
index 0855180dcd..0855180dcd 100644..100755
--- a/indra/llcommon/llevents.cpp
+++ b/indra/llcommon/llevents.cpp
diff --git a/indra/llcommon/llevents.h b/indra/llcommon/llevents.h
index 65b0fef354..65b0fef354 100644..100755
--- a/indra/llcommon/llevents.h
+++ b/indra/llcommon/llevents.h
diff --git a/indra/llcommon/lleventtimer.cpp b/indra/llcommon/lleventtimer.cpp
index 0d96e03da4..0d96e03da4 100644..100755
--- a/indra/llcommon/lleventtimer.cpp
+++ b/indra/llcommon/lleventtimer.cpp
diff --git a/indra/llcommon/lleventtimer.h b/indra/llcommon/lleventtimer.h
index 7f42623d01..dc918121e1 100644..100755
--- a/indra/llcommon/lleventtimer.h
+++ b/indra/llcommon/lleventtimer.h
@@ -36,6 +36,7 @@
class LL_COMMON_API LLEventTimer : public LLInstanceTracker<LLEventTimer>
{
public:
+
LLEventTimer(F32 period); // period is the amount of time between each call to tick() in seconds
LLEventTimer(const LLDate& time);
virtual ~LLEventTimer();
diff --git a/indra/llcommon/llextendedstatus.h b/indra/llcommon/llextendedstatus.h
index 8ce173d1ff..8ce173d1ff 100644..100755
--- a/indra/llcommon/llextendedstatus.h
+++ b/indra/llcommon/llextendedstatus.h
diff --git a/indra/llcommon/llfasttimer.cpp b/indra/llcommon/llfasttimer.cpp
new file mode 100755
index 0000000000..01b6e60d2b
--- /dev/null
+++ b/indra/llcommon/llfasttimer.cpp
@@ -0,0 +1,658 @@
+/**
+ * @file llfasttimer.cpp
+ * @brief Implementation of the fast timer.
+ *
+ * $LicenseInfo:firstyear=2004&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 "llfasttimer.h"
+
+#include "llmemory.h"
+#include "llprocessor.h"
+#include "llsingleton.h"
+#include "lltreeiterators.h"
+#include "llsdserialize.h"
+
+#include <boost/bind.hpp>
+
+
+#if LL_WINDOWS
+#include "lltimer.h"
+#elif LL_LINUX || LL_SOLARIS
+#include <sys/time.h>
+#include <sched.h>
+#include "lltimer.h"
+#elif LL_DARWIN
+#include <sys/time.h>
+#include "lltimer.h" // get_clock_count()
+#else
+#error "architecture not supported"
+#endif
+
+//////////////////////////////////////////////////////////////////////////////
+// statics
+
+S32 LLFastTimer::sCurFrameIndex = -1;
+S32 LLFastTimer::sLastFrameIndex = -1;
+U64 LLFastTimer::sLastFrameTime = LLFastTimer::getCPUClockCount64();
+bool LLFastTimer::sPauseHistory = 0;
+bool LLFastTimer::sResetHistory = 0;
+LLFastTimer::CurTimerData LLFastTimer::sCurTimerData;
+BOOL LLFastTimer::sLog = FALSE;
+std::string LLFastTimer::sLogName = "";
+BOOL LLFastTimer::sMetricLog = FALSE;
+LLMutex* LLFastTimer::sLogLock = NULL;
+std::queue<LLSD> LLFastTimer::sLogQueue;
+
+#if LL_LINUX || LL_SOLARIS
+U64 LLFastTimer::sClockResolution = 1000000000; // Nanosecond resolution
+#else
+U64 LLFastTimer::sClockResolution = 1000000; // Microsecond resolution
+#endif
+
+// FIXME: move these declarations to the relevant modules
+
+// helper functions
+typedef LLTreeDFSPostIter<LLFastTimer::NamedTimer, LLFastTimer::NamedTimer::child_const_iter> timer_tree_bottom_up_iterator_t;
+
+static timer_tree_bottom_up_iterator_t begin_timer_tree_bottom_up(LLFastTimer::NamedTimer& id)
+{
+ return timer_tree_bottom_up_iterator_t(&id,
+ boost::bind(boost::mem_fn(&LLFastTimer::NamedTimer::beginChildren), _1),
+ boost::bind(boost::mem_fn(&LLFastTimer::NamedTimer::endChildren), _1));
+}
+
+static timer_tree_bottom_up_iterator_t end_timer_tree_bottom_up()
+{
+ return timer_tree_bottom_up_iterator_t();
+}
+
+typedef LLTreeDFSIter<LLFastTimer::NamedTimer, LLFastTimer::NamedTimer::child_const_iter> timer_tree_dfs_iterator_t;
+
+
+static timer_tree_dfs_iterator_t begin_timer_tree(LLFastTimer::NamedTimer& id)
+{
+ return timer_tree_dfs_iterator_t(&id,
+ boost::bind(boost::mem_fn(&LLFastTimer::NamedTimer::beginChildren), _1),
+ boost::bind(boost::mem_fn(&LLFastTimer::NamedTimer::endChildren), _1));
+}
+
+static timer_tree_dfs_iterator_t end_timer_tree()
+{
+ return timer_tree_dfs_iterator_t();
+}
+
+// factory class that creates NamedTimers via static DeclareTimer objects
+class NamedTimerFactory : public LLSingleton<NamedTimerFactory>
+{
+public:
+ NamedTimerFactory()
+ : mTimerRoot(new LLFastTimer::NamedTimer("root"))
+ {
+ mRootFrameState.setNamedTimer(mTimerRoot);
+ mTimerRoot->setFrameState(&mRootFrameState);
+ mTimerRoot->mParent = mTimerRoot;
+ mTimerRoot->setCollapsed(false);
+ mRootFrameState.mParent = &mRootFrameState;
+ }
+
+ ~NamedTimerFactory()
+ {
+ std::for_each(mTimers.begin(), mTimers.end(), DeletePairedPointer());
+
+ delete mTimerRoot;
+ }
+
+ LLFastTimer::NamedTimer& createNamedTimer(const std::string& name, LLFastTimer::FrameState* state)
+ {
+ LLFastTimer::NamedTimer* timer = new LLFastTimer::NamedTimer(name);
+ timer->setFrameState(state);
+ timer->setParent(mTimerRoot);
+ mTimers.insert(std::make_pair(name, timer));
+
+ return *timer;
+ }
+
+ LLFastTimer::NamedTimer* getTimerByName(const std::string& name)
+ {
+ timer_map_t::iterator found_it = mTimers.find(name);
+ if (found_it != mTimers.end())
+ {
+ return found_it->second;
+ }
+ return NULL;
+ }
+
+ LLFastTimer::NamedTimer* getRootTimer() { return mTimerRoot; }
+
+ typedef std::multimap<std::string, LLFastTimer::NamedTimer*> timer_map_t;
+ timer_map_t::iterator beginTimers() { return mTimers.begin(); }
+ timer_map_t::iterator endTimers() { return mTimers.end(); }
+ S32 timerCount() { return mTimers.size(); }
+
+private:
+ timer_map_t mTimers;
+
+ LLFastTimer::NamedTimer* mTimerRoot;
+ LLFastTimer::FrameState mRootFrameState;
+};
+
+LLFastTimer::DeclareTimer::DeclareTimer(const std::string& name, bool open )
+: mTimer(NamedTimerFactory::instance().createNamedTimer(name, &mFrameState))
+{
+ mTimer.setCollapsed(!open);
+}
+
+LLFastTimer::DeclareTimer::DeclareTimer(const std::string& name)
+: mTimer(NamedTimerFactory::instance().createNamedTimer(name, &mFrameState))
+{
+}
+
+//static
+#if (LL_DARWIN || LL_LINUX || LL_SOLARIS) && !(defined(__i386__) || defined(__amd64__))
+U64 LLFastTimer::countsPerSecond() // counts per second for the *32-bit* timer
+{
+ return sClockResolution >> 8;
+}
+#else // windows or x86-mac or x86-linux or x86-solaris
+U64 LLFastTimer::countsPerSecond() // counts per second for the *32-bit* timer
+{
+#if LL_FASTTIMER_USE_RDTSC || !LL_WINDOWS
+ //getCPUFrequency returns MHz and sCPUClockFrequency wants to be in Hz
+ static U64 sCPUClockFrequency = U64(LLProcessorInfo().getCPUFrequency()*1000000.0);
+
+ // we drop the low-order byte in our timers, so report a lower frequency
+#else
+ // If we're not using RDTSC, each fasttimer tick is just a performance counter tick.
+ // Not redefining the clock frequency itself (in llprocessor.cpp/calculate_cpu_frequency())
+ // since that would change displayed MHz stats for CPUs
+ static bool firstcall = true;
+ static U64 sCPUClockFrequency;
+ if (firstcall)
+ {
+ QueryPerformanceFrequency((LARGE_INTEGER*)&sCPUClockFrequency);
+ firstcall = false;
+ }
+#endif
+ return sCPUClockFrequency >> 8;
+}
+#endif
+
+LLFastTimer::FrameState::FrameState()
+: mActiveCount(0),
+ mCalls(0),
+ mSelfTimeCounter(0),
+ mParent(NULL),
+ mLastCaller(NULL),
+ mMoveUpTree(false)
+{}
+
+
+LLFastTimer::NamedTimer::NamedTimer(const std::string& name)
+: mName(name),
+ mCollapsed(true),
+ mParent(NULL),
+ mTotalTimeCounter(0),
+ mCountAverage(0),
+ mCallAverage(0),
+ mNeedsSorting(false),
+ mFrameState(NULL)
+{
+ mCountHistory = new U32[HISTORY_NUM];
+ memset(mCountHistory, 0, sizeof(U32) * HISTORY_NUM);
+ mCallHistory = new U32[HISTORY_NUM];
+ memset(mCallHistory, 0, sizeof(U32) * HISTORY_NUM);
+}
+
+LLFastTimer::NamedTimer::~NamedTimer()
+{
+ delete[] mCountHistory;
+ delete[] mCallHistory;
+}
+
+std::string LLFastTimer::NamedTimer::getToolTip(S32 history_idx)
+{
+ F64 ms_multiplier = 1000.0 / (F64)LLFastTimer::countsPerSecond();
+ if (history_idx < 0)
+ {
+ // by default, show average number of call
+ return llformat("%s (%d ms, %d calls)", getName().c_str(), (S32)(getCountAverage() * ms_multiplier), (S32)getCallAverage());
+ }
+ else
+ {
+ return llformat("%s (%d ms, %d calls)", getName().c_str(), (S32)(getHistoricalCount(history_idx) * ms_multiplier), (S32)getHistoricalCalls(history_idx));
+ }
+}
+
+void LLFastTimer::NamedTimer::setParent(NamedTimer* parent)
+{
+ llassert_always(parent != this);
+ llassert_always(parent != NULL);
+
+ if (mParent)
+ {
+ // subtract our accumulated from previous parent
+ for (S32 i = 0; i < HISTORY_NUM; i++)
+ {
+ mParent->mCountHistory[i] -= mCountHistory[i];
+ }
+
+ // subtract average timing from previous parent
+ mParent->mCountAverage -= mCountAverage;
+
+ std::vector<NamedTimer*>& children = mParent->getChildren();
+ std::vector<NamedTimer*>::iterator found_it = std::find(children.begin(), children.end(), this);
+ if (found_it != children.end())
+ {
+ children.erase(found_it);
+ }
+ }
+
+ mParent = parent;
+ if (parent)
+ {
+ getFrameState().mParent = &parent->getFrameState();
+ parent->getChildren().push_back(this);
+ parent->mNeedsSorting = true;
+ }
+}
+
+S32 LLFastTimer::NamedTimer::getDepth()
+{
+ S32 depth = 0;
+ NamedTimer* timerp = mParent;
+ while(timerp)
+ {
+ depth++;
+ if (timerp->getParent() == timerp) break;
+ timerp = timerp->mParent;
+ }
+ return depth;
+}
+
+// static
+void LLFastTimer::NamedTimer::processTimes()
+{
+ if (sCurFrameIndex < 0) return;
+
+ buildHierarchy();
+ accumulateTimings();
+}
+
+// sort child timers by name
+struct SortTimerByName
+{
+ bool operator()(const LLFastTimer::NamedTimer* i1, const LLFastTimer::NamedTimer* i2)
+ {
+ return i1->getName() < i2->getName();
+ }
+};
+
+//static
+void LLFastTimer::NamedTimer::buildHierarchy()
+{
+ if (sCurFrameIndex < 0 ) return;
+
+ // set up initial tree
+ {
+ for (instance_iter it = beginInstances(); it != endInstances(); ++it)
+ {
+ NamedTimer& timer = *it;
+ if (&timer == NamedTimerFactory::instance().getRootTimer()) continue;
+
+ // bootstrap tree construction by attaching to last timer to be on stack
+ // when this timer was called
+ if (timer.getFrameState().mLastCaller && timer.mParent == NamedTimerFactory::instance().getRootTimer())
+ {
+ timer.setParent(timer.getFrameState().mLastCaller->mTimer);
+ // no need to push up tree on first use, flag can be set spuriously
+ timer.getFrameState().mMoveUpTree = false;
+ }
+ }
+ }
+
+ // bump timers up tree if they've been flagged as being in the wrong place
+ // do this in a bottom up order to promote descendants first before promoting ancestors
+ // this preserves partial order derived from current frame's observations
+ for(timer_tree_bottom_up_iterator_t it = begin_timer_tree_bottom_up(*NamedTimerFactory::instance().getRootTimer());
+ it != end_timer_tree_bottom_up();
+ ++it)
+ {
+ NamedTimer* timerp = *it;
+ // skip root timer
+ if (timerp == NamedTimerFactory::instance().getRootTimer()) continue;
+
+ if (timerp->getFrameState().mMoveUpTree)
+ {
+ // since ancestors have already been visited, reparenting won't affect tree traversal
+ //step up tree, bringing our descendants with us
+ LL_DEBUGS("FastTimers") << "Moving " << timerp->getName() << " from child of " << timerp->getParent()->getName() <<
+ " to child of " << timerp->getParent()->getParent()->getName() << LL_ENDL;
+ timerp->setParent(timerp->getParent()->getParent());
+ timerp->getFrameState().mMoveUpTree = false;
+
+ // don't bubble up any ancestors until descendants are done bubbling up
+ it.skipAncestors();
+ }
+ }
+
+ // sort timers by time last called, so call graph makes sense
+ for(timer_tree_dfs_iterator_t it = begin_timer_tree(*NamedTimerFactory::instance().getRootTimer());
+ it != end_timer_tree();
+ ++it)
+ {
+ NamedTimer* timerp = (*it);
+ if (timerp->mNeedsSorting)
+ {
+ std::sort(timerp->getChildren().begin(), timerp->getChildren().end(), SortTimerByName());
+ }
+ timerp->mNeedsSorting = false;
+ }
+}
+
+//static
+void LLFastTimer::NamedTimer::accumulateTimings()
+{
+ U32 cur_time = getCPUClockCount32();
+
+ // walk up stack of active timers and accumulate current time while leaving timing structures active
+ LLFastTimer* cur_timer = sCurTimerData.mCurTimer;
+ // root defined by parent pointing to self
+ CurTimerData* cur_data = &sCurTimerData;
+ while(cur_timer && cur_timer->mLastTimerData.mCurTimer != cur_timer)
+ {
+ U32 cumulative_time_delta = cur_time - cur_timer->mStartTime;
+ U32 self_time_delta = cumulative_time_delta - cur_data->mChildTime;
+ cur_data->mChildTime = 0;
+ cur_timer->mFrameState->mSelfTimeCounter += self_time_delta;
+ cur_timer->mStartTime = cur_time;
+
+ cur_data = &cur_timer->mLastTimerData;
+ cur_data->mChildTime += cumulative_time_delta;
+
+ cur_timer = cur_timer->mLastTimerData.mCurTimer;
+ }
+
+ // traverse tree in DFS post order, or bottom up
+ for(timer_tree_bottom_up_iterator_t it = begin_timer_tree_bottom_up(*NamedTimerFactory::instance().getRootTimer());
+ it != end_timer_tree_bottom_up();
+ ++it)
+ {
+ NamedTimer* timerp = (*it);
+ timerp->mTotalTimeCounter = timerp->getFrameState().mSelfTimeCounter;
+ for (child_const_iter child_it = timerp->beginChildren(); child_it != timerp->endChildren(); ++child_it)
+ {
+ timerp->mTotalTimeCounter += (*child_it)->mTotalTimeCounter;
+ }
+
+ S32 cur_frame = sCurFrameIndex;
+ if (cur_frame >= 0)
+ {
+ // update timer history
+ int hidx = cur_frame % HISTORY_NUM;
+
+ timerp->mCountHistory[hidx] = timerp->mTotalTimeCounter;
+ timerp->mCountAverage = ((U64)timerp->mCountAverage * cur_frame + timerp->mTotalTimeCounter) / (cur_frame+1);
+ timerp->mCallHistory[hidx] = timerp->getFrameState().mCalls;
+ timerp->mCallAverage = ((U64)timerp->mCallAverage * cur_frame + timerp->getFrameState().mCalls) / (cur_frame+1);
+ }
+ }
+}
+
+// static
+void LLFastTimer::NamedTimer::resetFrame()
+{
+ if (sLog)
+ { //output current frame counts to performance log
+
+ static S32 call_count = 0;
+ if (call_count % 100 == 0)
+ {
+ LL_DEBUGS("FastTimers") << "countsPerSecond (32 bit): " << countsPerSecond() << LL_ENDL;
+ LL_DEBUGS("FastTimers") << "get_clock_count (64 bit): " << get_clock_count() << llendl;
+ LL_DEBUGS("FastTimers") << "LLProcessorInfo().getCPUFrequency() " << LLProcessorInfo().getCPUFrequency() << LL_ENDL;
+ LL_DEBUGS("FastTimers") << "getCPUClockCount32() " << getCPUClockCount32() << LL_ENDL;
+ LL_DEBUGS("FastTimers") << "getCPUClockCount64() " << getCPUClockCount64() << LL_ENDL;
+ LL_DEBUGS("FastTimers") << "elapsed sec " << ((F64)getCPUClockCount64())/((F64)LLProcessorInfo().getCPUFrequency()*1000000.0) << LL_ENDL;
+ }
+ call_count++;
+
+ F64 iclock_freq = 1000.0 / countsPerSecond(); // good place to calculate clock frequency
+
+ F64 total_time = 0;
+ LLSD sd;
+
+ {
+ for (instance_iter it = beginInstances(); it != endInstances(); ++it)
+ {
+ NamedTimer& timer = *it;
+ FrameState& info = timer.getFrameState();
+ sd[timer.getName()]["Time"] = (LLSD::Real) (info.mSelfTimeCounter*iclock_freq);
+ sd[timer.getName()]["Calls"] = (LLSD::Integer) info.mCalls;
+
+ // computing total time here because getting the root timer's getCountHistory
+ // doesn't work correctly on the first frame
+ total_time = total_time + info.mSelfTimeCounter * iclock_freq;
+ }
+ }
+
+ sd["Total"]["Time"] = (LLSD::Real) total_time;
+ sd["Total"]["Calls"] = (LLSD::Integer) 1;
+
+ {
+ LLMutexLock lock(sLogLock);
+ sLogQueue.push(sd);
+ }
+ }
+
+ // reset for next frame
+ for (instance_iter it = beginInstances(); it != endInstances(); ++it)
+ {
+ NamedTimer& timer = *it;
+
+ FrameState& info = timer.getFrameState();
+ info.mSelfTimeCounter = 0;
+ info.mCalls = 0;
+ info.mLastCaller = NULL;
+ info.mMoveUpTree = false;
+ // update parent pointer in timer state struct
+ if (timer.mParent)
+ {
+ info.mParent = &timer.mParent->getFrameState();
+ }
+ }
+}
+
+//static
+void LLFastTimer::NamedTimer::reset()
+{
+ resetFrame(); // reset frame data
+
+ // walk up stack of active timers and reset start times to current time
+ // effectively zeroing out any accumulated time
+ U32 cur_time = getCPUClockCount32();
+
+ // root defined by parent pointing to self
+ CurTimerData* cur_data = &sCurTimerData;
+ LLFastTimer* cur_timer = cur_data->mCurTimer;
+ while(cur_timer && cur_timer->mLastTimerData.mCurTimer != cur_timer)
+ {
+ cur_timer->mStartTime = cur_time;
+ cur_data->mChildTime = 0;
+
+ cur_data = &cur_timer->mLastTimerData;
+ cur_timer = cur_data->mCurTimer;
+ }
+
+ // reset all history
+ {
+ for (instance_iter it = beginInstances(); it != endInstances(); ++it)
+ {
+ NamedTimer& timer = *it;
+ if (&timer != NamedTimerFactory::instance().getRootTimer())
+ {
+ timer.setParent(NamedTimerFactory::instance().getRootTimer());
+ }
+
+ timer.mCountAverage = 0;
+ timer.mCallAverage = 0;
+ memset(timer.mCountHistory, 0, sizeof(U32) * HISTORY_NUM);
+ memset(timer.mCallHistory, 0, sizeof(U32) * HISTORY_NUM);
+ }
+ }
+
+ sLastFrameIndex = 0;
+ sCurFrameIndex = 0;
+}
+
+U32 LLFastTimer::NamedTimer::getHistoricalCount(S32 history_index) const
+{
+ S32 history_idx = (getLastFrameIndex() + history_index) % LLFastTimer::NamedTimer::HISTORY_NUM;
+ return mCountHistory[history_idx];
+}
+
+U32 LLFastTimer::NamedTimer::getHistoricalCalls(S32 history_index ) const
+{
+ S32 history_idx = (getLastFrameIndex() + history_index) % LLFastTimer::NamedTimer::HISTORY_NUM;
+ return mCallHistory[history_idx];
+}
+
+LLFastTimer::FrameState& LLFastTimer::NamedTimer::getFrameState() const
+{
+ return *mFrameState;
+}
+
+std::vector<LLFastTimer::NamedTimer*>::const_iterator LLFastTimer::NamedTimer::beginChildren()
+{
+ return mChildren.begin();
+}
+
+std::vector<LLFastTimer::NamedTimer*>::const_iterator LLFastTimer::NamedTimer::endChildren()
+{
+ return mChildren.end();
+}
+
+std::vector<LLFastTimer::NamedTimer*>& LLFastTimer::NamedTimer::getChildren()
+{
+ return mChildren;
+}
+
+//static
+LLFastTimer::NamedTimer& LLFastTimer::NamedTimer::getRootNamedTimer()
+{
+ return *NamedTimerFactory::instance().getRootTimer();
+}
+
+//static
+void LLFastTimer::nextFrame()
+{
+ countsPerSecond(); // good place to calculate clock frequency
+ U64 frame_time = getCPUClockCount64();
+ if ((frame_time - sLastFrameTime) >> 8 > 0xffffffff)
+ {
+ llinfos << "Slow frame, fast timers inaccurate" << llendl;
+ }
+
+ if (!sPauseHistory)
+ {
+ NamedTimer::processTimes();
+ sLastFrameIndex = sCurFrameIndex++;
+ }
+
+ // get ready for next frame
+ NamedTimer::resetFrame();
+ sLastFrameTime = frame_time;
+}
+
+//static
+void LLFastTimer::dumpCurTimes()
+{
+ // accumulate timings, etc.
+ NamedTimer::processTimes();
+
+ F64 clock_freq = (F64)countsPerSecond();
+ F64 iclock_freq = 1000.0 / clock_freq; // clock_ticks -> milliseconds
+
+ // walk over timers in depth order and output timings
+ for(timer_tree_dfs_iterator_t it = begin_timer_tree(*NamedTimerFactory::instance().getRootTimer());
+ it != end_timer_tree();
+ ++it)
+ {
+ NamedTimer* timerp = (*it);
+ F64 total_time_ms = ((F64)timerp->getHistoricalCount(0) * iclock_freq);
+ // Don't bother with really brief times, keep output concise
+ if (total_time_ms < 0.1) continue;
+
+ std::ostringstream out_str;
+ for (S32 i = 0; i < timerp->getDepth(); i++)
+ {
+ out_str << "\t";
+ }
+
+
+ out_str << timerp->getName() << " "
+ << std::setprecision(3) << total_time_ms << " ms, "
+ << timerp->getHistoricalCalls(0) << " calls";
+
+ llinfos << out_str.str() << llendl;
+ }
+}
+
+//static
+void LLFastTimer::reset()
+{
+ NamedTimer::reset();
+}
+
+
+//static
+void LLFastTimer::writeLog(std::ostream& os)
+{
+ while (!sLogQueue.empty())
+ {
+ LLSD& sd = sLogQueue.front();
+ LLSDSerialize::toXML(sd, os);
+ LLMutexLock lock(sLogLock);
+ sLogQueue.pop();
+ }
+}
+
+//static
+const LLFastTimer::NamedTimer* LLFastTimer::getTimerByName(const std::string& name)
+{
+ return NamedTimerFactory::instance().getTimerByName(name);
+}
+
+LLFastTimer::LLFastTimer(LLFastTimer::FrameState* state)
+: mFrameState(state)
+{
+ U32 start_time = getCPUClockCount32();
+ mStartTime = start_time;
+ mFrameState->mActiveCount++;
+ LLFastTimer::sCurTimerData.mCurTimer = this;
+ LLFastTimer::sCurTimerData.mFrameState = mFrameState;
+ LLFastTimer::sCurTimerData.mChildTime = 0;
+ mLastTimerData = LLFastTimer::sCurTimerData;
+}
+
+
diff --git a/indra/llcommon/llfasttimer.h b/indra/llcommon/llfasttimer.h
index 2b25f2fabb..a99a1d88af 100644..100755
--- a/indra/llcommon/llfasttimer.h
+++ b/indra/llcommon/llfasttimer.h
@@ -1,6 +1,6 @@
/**
* @file llfasttimer.h
- * @brief Inline implementations of fast timers.
+ * @brief Declaration of a fast timer.
*
* $LicenseInfo:firstyear=2004&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -27,9 +27,366 @@
#ifndef LL_FASTTIMER_H
#define LL_FASTTIMER_H
-// Implementation of getCPUClockCount32() and getCPUClockCount64 are now in llfastertimer_class.cpp.
+#include "llinstancetracker.h"
-// pull in the actual class definition
-#include "llfasttimer_class.h"
+#define FAST_TIMER_ON 1
+#define DEBUG_FAST_TIMER_THREADS 1
+
+class LLMutex;
+
+#include <queue>
+#include "llsd.h"
+
+#define LL_FASTTIMER_USE_RDTSC 1
+
+
+LL_COMMON_API void assert_main_thread();
+
+class LL_COMMON_API LLFastTimer
+{
+public:
+ class NamedTimer;
+
+ struct LL_COMMON_API FrameState
+ {
+ FrameState();
+ void setNamedTimer(NamedTimer* timerp) { mTimer = timerp; }
+
+ U32 mSelfTimeCounter;
+ U32 mCalls;
+ FrameState* mParent; // info for caller timer
+ FrameState* mLastCaller; // used to bootstrap tree construction
+ NamedTimer* mTimer;
+ U16 mActiveCount; // number of timers with this ID active on stack
+ bool mMoveUpTree; // needs to be moved up the tree of timers at the end of frame
+ };
+
+ // stores a "named" timer instance to be reused via multiple LLFastTimer stack instances
+ class LL_COMMON_API NamedTimer
+ : public LLInstanceTracker<NamedTimer>
+ {
+ friend class DeclareTimer;
+ public:
+ ~NamedTimer();
+
+ enum { HISTORY_NUM = 300 };
+
+ const std::string& getName() const { return mName; }
+ NamedTimer* getParent() const { return mParent; }
+ void setParent(NamedTimer* parent);
+ S32 getDepth();
+ std::string getToolTip(S32 history_index = -1);
+
+ typedef std::vector<NamedTimer*>::const_iterator child_const_iter;
+ child_const_iter beginChildren();
+ child_const_iter endChildren();
+ std::vector<NamedTimer*>& getChildren();
+
+ void setCollapsed(bool collapsed) { mCollapsed = collapsed; }
+ bool getCollapsed() const { return mCollapsed; }
+
+ U32 getCountAverage() const { return mCountAverage; }
+ U32 getCallAverage() const { return mCallAverage; }
+
+ U32 getHistoricalCount(S32 history_index = 0) const;
+ U32 getHistoricalCalls(S32 history_index = 0) const;
+
+ static NamedTimer& getRootNamedTimer();
+
+ void setFrameState(FrameState* state) { mFrameState = state; state->setNamedTimer(this); }
+ FrameState& getFrameState() const;
+
+ private:
+ friend class LLFastTimer;
+ friend class NamedTimerFactory;
+
+ //
+ // methods
+ //
+ NamedTimer(const std::string& name);
+ // recursive call to gather total time from children
+ static void accumulateTimings();
+
+ // updates cumulative times and hierarchy,
+ // can be called multiple times in a frame, at any point
+ static void processTimes();
+
+ static void buildHierarchy();
+ static void resetFrame();
+ static void reset();
+
+ //
+ // members
+ //
+ FrameState* mFrameState;
+
+ std::string mName;
+
+ U32 mTotalTimeCounter;
+
+ U32 mCountAverage;
+ U32 mCallAverage;
+
+ U32* mCountHistory;
+ U32* mCallHistory;
+
+ // tree structure
+ NamedTimer* mParent; // NamedTimer of caller(parent)
+ std::vector<NamedTimer*> mChildren;
+ bool mCollapsed; // don't show children
+ bool mNeedsSorting; // sort children whenever child added
+ };
+
+ // used to statically declare a new named timer
+ class LL_COMMON_API DeclareTimer
+ : public LLInstanceTracker< DeclareTimer >
+ {
+ friend class LLFastTimer;
+ public:
+
+ DeclareTimer(const std::string& name, bool open);
+ DeclareTimer(const std::string& name);
+
+ NamedTimer& getNamedTimer() { return mTimer; }
+
+ private:
+ FrameState mFrameState;
+ NamedTimer& mTimer;
+ };
+
+public:
+ LLFastTimer(LLFastTimer::FrameState* state);
+
+ LL_FORCE_INLINE LLFastTimer(LLFastTimer::DeclareTimer& timer)
+ : mFrameState(&timer.mFrameState)
+ {
+#if FAST_TIMER_ON
+ LLFastTimer::FrameState* frame_state = mFrameState;
+ mStartTime = getCPUClockCount32();
+
+ frame_state->mActiveCount++;
+ frame_state->mCalls++;
+ // keep current parent as long as it is active when we are
+ frame_state->mMoveUpTree |= (frame_state->mParent->mActiveCount == 0);
+
+ LLFastTimer::CurTimerData* cur_timer_data = &LLFastTimer::sCurTimerData;
+ mLastTimerData = *cur_timer_data;
+ cur_timer_data->mCurTimer = this;
+ cur_timer_data->mFrameState = frame_state;
+ cur_timer_data->mChildTime = 0;
+#endif
+#if DEBUG_FAST_TIMER_THREADS
+#if !LL_RELEASE
+ assert_main_thread();
+#endif
+#endif
+ }
+
+ LL_FORCE_INLINE ~LLFastTimer()
+ {
+#if FAST_TIMER_ON
+ LLFastTimer::FrameState* frame_state = mFrameState;
+ U32 total_time = getCPUClockCount32() - mStartTime;
+
+ frame_state->mSelfTimeCounter += total_time - LLFastTimer::sCurTimerData.mChildTime;
+ frame_state->mActiveCount--;
+
+ // store last caller to bootstrap tree creation
+ // do this in the destructor in case of recursion to get topmost caller
+ frame_state->mLastCaller = mLastTimerData.mFrameState;
+
+ // we are only tracking self time, so subtract our total time delta from parents
+ mLastTimerData.mChildTime += total_time;
+
+ LLFastTimer::sCurTimerData = mLastTimerData;
+#endif
+ }
+
+public:
+ static LLMutex* sLogLock;
+ static std::queue<LLSD> sLogQueue;
+ static BOOL sLog;
+ static BOOL sMetricLog;
+ static std::string sLogName;
+ static bool sPauseHistory;
+ static bool sResetHistory;
+
+ // call this once a frame to reset timers
+ static void nextFrame();
+
+ // dumps current cumulative frame stats to log
+ // call nextFrame() to reset timers
+ static void dumpCurTimes();
+
+ // call this to reset timer hierarchy, averages, etc.
+ static void reset();
+
+ static U64 countsPerSecond();
+ static S32 getLastFrameIndex() { return sLastFrameIndex; }
+ static S32 getCurFrameIndex() { return sCurFrameIndex; }
+
+ static void writeLog(std::ostream& os);
+ static const NamedTimer* getTimerByName(const std::string& name);
+
+ struct CurTimerData
+ {
+ LLFastTimer* mCurTimer;
+ FrameState* mFrameState;
+ U32 mChildTime;
+ };
+ static CurTimerData sCurTimerData;
+
+private:
+
+
+ //////////////////////////////////////////////////////////////////////////////
+ //
+ // Important note: These implementations must be FAST!
+ //
+
+
+#if LL_WINDOWS
+ //
+ // Windows implementation of CPU clock
+ //
+
+ //
+ // NOTE: put back in when we aren't using platform sdk anymore
+ //
+ // because MS has different signatures for these functions in winnt.h
+ // need to rename them to avoid conflicts
+ //#define _interlockedbittestandset _renamed_interlockedbittestandset
+ //#define _interlockedbittestandreset _renamed_interlockedbittestandreset
+ //#include <intrin.h>
+ //#undef _interlockedbittestandset
+ //#undef _interlockedbittestandreset
+
+ //inline U32 LLFastTimer::getCPUClockCount32()
+ //{
+ // U64 time_stamp = __rdtsc();
+ // return (U32)(time_stamp >> 8);
+ //}
+ //
+ //// return full timer value, *not* shifted by 8 bits
+ //inline U64 LLFastTimer::getCPUClockCount64()
+ //{
+ // return __rdtsc();
+ //}
+
+ // shift off lower 8 bits for lower resolution but longer term timing
+ // on 1Ghz machine, a 32-bit word will hold ~1000 seconds of timing
+#if LL_FASTTIMER_USE_RDTSC
+ static U32 getCPUClockCount32()
+ {
+ U32 ret_val;
+ __asm
+ {
+ _emit 0x0f
+ _emit 0x31
+ shr eax,8
+ shl edx,24
+ or eax, edx
+ mov dword ptr [ret_val], eax
+ }
+ return ret_val;
+ }
+
+ // return full timer value, *not* shifted by 8 bits
+ static U64 getCPUClockCount64()
+ {
+ U64 ret_val;
+ __asm
+ {
+ _emit 0x0f
+ _emit 0x31
+ mov eax,eax
+ mov edx,edx
+ mov dword ptr [ret_val+4], edx
+ mov dword ptr [ret_val], eax
+ }
+ return ret_val;
+ }
+
+#else
+ //LL_COMMON_API U64 get_clock_count(); // in lltimer.cpp
+ // These use QueryPerformanceCounter, which is arguably fine and also works on AMD architectures.
+ static U32 getCPUClockCount32()
+ {
+ return (U32)(get_clock_count()>>8);
+ }
+
+ static U64 getCPUClockCount64()
+ {
+ return get_clock_count();
+ }
+
+#endif
+
+#endif
+
+
+#if (LL_LINUX || LL_SOLARIS) && !(defined(__i386__) || defined(__amd64__))
+ //
+ // Linux and Solaris implementation of CPU clock - non-x86.
+ // This is accurate but SLOW! Only use out of desperation.
+ //
+ // Try to use the MONOTONIC clock if available, this is a constant time counter
+ // with nanosecond resolution (but not necessarily accuracy) and attempts are
+ // made to synchronize this value between cores at kernel start. It should not
+ // be affected by CPU frequency. If not available use the REALTIME clock, but
+ // this may be affected by NTP adjustments or other user activity affecting
+ // the system time.
+ static U64 getCPUClockCount64()
+ {
+ struct timespec tp;
+
+#ifdef CLOCK_MONOTONIC // MONOTONIC supported at build-time?
+ if (-1 == clock_gettime(CLOCK_MONOTONIC,&tp)) // if MONOTONIC isn't supported at runtime then ouch, try REALTIME
+#endif
+ clock_gettime(CLOCK_REALTIME,&tp);
+
+ return (tp.tv_sec*sClockResolution)+tp.tv_nsec;
+ }
+
+ static U32 getCPUClockCount32()
+ {
+ return (U32)(getCPUClockCount64() >> 8);
+ }
+
+#endif // (LL_LINUX || LL_SOLARIS) && !(defined(__i386__) || defined(__amd64__))
+
+
+#if (LL_LINUX || LL_SOLARIS || LL_DARWIN) && (defined(__i386__) || defined(__amd64__))
+ //
+ // Mac+Linux+Solaris FAST x86 implementation of CPU clock
+ static U32 getCPUClockCount32()
+ {
+ U64 x;
+ __asm__ volatile (".byte 0x0f, 0x31": "=A"(x));
+ return (U32)(x >> 8);
+ }
+
+ static U64 getCPUClockCount64()
+ {
+ U64 x;
+ __asm__ volatile (".byte 0x0f, 0x31": "=A"(x));
+ return x;
+ }
+
+#endif
+
+ static U64 sClockResolution;
+
+ static S32 sCurFrameIndex;
+ static S32 sLastFrameIndex;
+ static U64 sLastFrameTime;
+
+ U32 mStartTime;
+ LLFastTimer::FrameState* mFrameState;
+ LLFastTimer::CurTimerData mLastTimerData;
+
+};
+
+typedef class LLFastTimer LLFastTimer;
#endif // LL_LLFASTTIMER_H
diff --git a/indra/llcommon/llfasttimer_class.cpp b/indra/llcommon/llfasttimer_class.cpp
deleted file mode 100644
index 463f558c2c..0000000000
--- a/indra/llcommon/llfasttimer_class.cpp
+++ /dev/null
@@ -1,921 +0,0 @@
-/**
- * @file llfasttimer_class.cpp
- * @brief Implementation of the fast timer.
- *
- * $LicenseInfo:firstyear=2004&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 "llfasttimer.h"
-
-#include "llmemory.h"
-#include "llprocessor.h"
-#include "llsingleton.h"
-#include "lltreeiterators.h"
-#include "llsdserialize.h"
-
-#include <boost/bind.hpp>
-
-
-#if LL_WINDOWS
-#include "lltimer.h"
-#elif LL_LINUX || LL_SOLARIS
-#include <sys/time.h>
-#include <sched.h>
-#include "lltimer.h"
-#elif LL_DARWIN
-#include <sys/time.h>
-#include "lltimer.h" // get_clock_count()
-#else
-#error "architecture not supported"
-#endif
-
-//////////////////////////////////////////////////////////////////////////////
-// statics
-
-S32 LLFastTimer::sCurFrameIndex = -1;
-S32 LLFastTimer::sLastFrameIndex = -1;
-U64 LLFastTimer::sLastFrameTime = LLFastTimer::getCPUClockCount64();
-bool LLFastTimer::sPauseHistory = 0;
-bool LLFastTimer::sResetHistory = 0;
-LLFastTimer::CurTimerData LLFastTimer::sCurTimerData;
-BOOL LLFastTimer::sLog = FALSE;
-std::string LLFastTimer::sLogName = "";
-BOOL LLFastTimer::sMetricLog = FALSE;
-LLMutex* LLFastTimer::sLogLock = NULL;
-std::queue<LLSD> LLFastTimer::sLogQueue;
-
-#define USE_RDTSC 0
-
-#if LL_LINUX || LL_SOLARIS
-U64 LLFastTimer::sClockResolution = 1000000000; // Nanosecond resolution
-#else
-U64 LLFastTimer::sClockResolution = 1000000; // Microsecond resolution
-#endif
-
-std::vector<LLFastTimer::FrameState>* LLFastTimer::sTimerInfos = NULL;
-U64 LLFastTimer::sTimerCycles = 0;
-U32 LLFastTimer::sTimerCalls = 0;
-
-
-// FIXME: move these declarations to the relevant modules
-
-// helper functions
-typedef LLTreeDFSPostIter<LLFastTimer::NamedTimer, LLFastTimer::NamedTimer::child_const_iter> timer_tree_bottom_up_iterator_t;
-
-static timer_tree_bottom_up_iterator_t begin_timer_tree_bottom_up(LLFastTimer::NamedTimer& id)
-{
- return timer_tree_bottom_up_iterator_t(&id,
- boost::bind(boost::mem_fn(&LLFastTimer::NamedTimer::beginChildren), _1),
- boost::bind(boost::mem_fn(&LLFastTimer::NamedTimer::endChildren), _1));
-}
-
-static timer_tree_bottom_up_iterator_t end_timer_tree_bottom_up()
-{
- return timer_tree_bottom_up_iterator_t();
-}
-
-typedef LLTreeDFSIter<LLFastTimer::NamedTimer, LLFastTimer::NamedTimer::child_const_iter> timer_tree_dfs_iterator_t;
-
-
-static timer_tree_dfs_iterator_t begin_timer_tree(LLFastTimer::NamedTimer& id)
-{
- return timer_tree_dfs_iterator_t(&id,
- boost::bind(boost::mem_fn(&LLFastTimer::NamedTimer::beginChildren), _1),
- boost::bind(boost::mem_fn(&LLFastTimer::NamedTimer::endChildren), _1));
-}
-
-static timer_tree_dfs_iterator_t end_timer_tree()
-{
- return timer_tree_dfs_iterator_t();
-}
-
-
-
-// factory class that creates NamedTimers via static DeclareTimer objects
-class NamedTimerFactory : public LLSingleton<NamedTimerFactory>
-{
-public:
- NamedTimerFactory()
- : mActiveTimerRoot(NULL),
- mTimerRoot(NULL),
- mAppTimer(NULL),
- mRootFrameState(NULL)
- {}
-
- /*virtual */ void initSingleton()
- {
- mTimerRoot = new LLFastTimer::NamedTimer("root");
-
- mActiveTimerRoot = new LLFastTimer::NamedTimer("Frame");
- mActiveTimerRoot->setCollapsed(false);
-
- mRootFrameState = new LLFastTimer::FrameState(mActiveTimerRoot);
- mRootFrameState->mParent = &mTimerRoot->getFrameState();
- mActiveTimerRoot->setParent(mTimerRoot);
-
- mAppTimer = new LLFastTimer(mRootFrameState);
- }
-
- ~NamedTimerFactory()
- {
- std::for_each(mTimers.begin(), mTimers.end(), DeletePairedPointer());
-
- delete mAppTimer;
- delete mActiveTimerRoot;
- delete mTimerRoot;
- delete mRootFrameState;
- }
-
- LLFastTimer::NamedTimer& createNamedTimer(const std::string& name)
- {
- timer_map_t::iterator found_it = mTimers.find(name);
- if (found_it != mTimers.end())
- {
- return *found_it->second;
- }
-
- LLFastTimer::NamedTimer* timer = new LLFastTimer::NamedTimer(name);
- timer->setParent(mTimerRoot);
- mTimers.insert(std::make_pair(name, timer));
-
- return *timer;
- }
-
- LLFastTimer::NamedTimer* getTimerByName(const std::string& name)
- {
- timer_map_t::iterator found_it = mTimers.find(name);
- if (found_it != mTimers.end())
- {
- return found_it->second;
- }
- return NULL;
- }
-
- LLFastTimer::NamedTimer* getActiveRootTimer() { return mActiveTimerRoot; }
- LLFastTimer::NamedTimer* getRootTimer() { return mTimerRoot; }
- const LLFastTimer* getAppTimer() { return mAppTimer; }
- LLFastTimer::FrameState& getRootFrameState() { return *mRootFrameState; }
-
- typedef std::map<std::string, LLFastTimer::NamedTimer*> timer_map_t;
- timer_map_t::iterator beginTimers() { return mTimers.begin(); }
- timer_map_t::iterator endTimers() { return mTimers.end(); }
- S32 timerCount() { return mTimers.size(); }
-
-private:
- timer_map_t mTimers;
-
- LLFastTimer::NamedTimer* mActiveTimerRoot;
- LLFastTimer::NamedTimer* mTimerRoot;
- LLFastTimer* mAppTimer;
- LLFastTimer::FrameState* mRootFrameState;
-};
-
-void update_cached_pointers_if_changed()
-{
- // detect when elements have moved and update cached pointers
- static LLFastTimer::FrameState* sFirstTimerAddress = NULL;
- if (&*(LLFastTimer::getFrameStateList().begin()) != sFirstTimerAddress)
- {
- LLFastTimer::DeclareTimer::updateCachedPointers();
- }
- sFirstTimerAddress = &*(LLFastTimer::getFrameStateList().begin());
-}
-
-LLFastTimer::DeclareTimer::DeclareTimer(const std::string& name, bool open )
-: mTimer(NamedTimerFactory::instance().createNamedTimer(name))
-{
- mTimer.setCollapsed(!open);
- mFrameState = &mTimer.getFrameState();
- update_cached_pointers_if_changed();
-}
-
-LLFastTimer::DeclareTimer::DeclareTimer(const std::string& name)
-: mTimer(NamedTimerFactory::instance().createNamedTimer(name))
-{
- mFrameState = &mTimer.getFrameState();
- update_cached_pointers_if_changed();
-}
-
-// static
-void LLFastTimer::DeclareTimer::updateCachedPointers()
-{
- // propagate frame state pointers to timer declarations
- for (instance_iter it = beginInstances(); it != endInstances(); ++it)
- {
- // update cached pointer
- it->mFrameState = &it->mTimer.getFrameState();
- }
-
- // also update frame states of timers on stack
- LLFastTimer* cur_timerp = LLFastTimer::sCurTimerData.mCurTimer;
- while(cur_timerp->mLastTimerData.mCurTimer != cur_timerp)
- {
- cur_timerp->mFrameState = &cur_timerp->mFrameState->mTimer->getFrameState();
- cur_timerp = cur_timerp->mLastTimerData.mCurTimer;
- }
-}
-
-//static
-#if (LL_DARWIN || LL_LINUX || LL_SOLARIS) && !(defined(__i386__) || defined(__amd64__))
-U64 LLFastTimer::countsPerSecond() // counts per second for the *32-bit* timer
-{
- return sClockResolution >> 8;
-}
-#else // windows or x86-mac or x86-linux or x86-solaris
-U64 LLFastTimer::countsPerSecond() // counts per second for the *32-bit* timer
-{
-#if USE_RDTSC || !LL_WINDOWS
- //getCPUFrequency returns MHz and sCPUClockFrequency wants to be in Hz
- static U64 sCPUClockFrequency = U64(LLProcessorInfo().getCPUFrequency()*1000000.0);
-
- // we drop the low-order byte in our timers, so report a lower frequency
-#else
- // If we're not using RDTSC, each fasttimer tick is just a performance counter tick.
- // Not redefining the clock frequency itself (in llprocessor.cpp/calculate_cpu_frequency())
- // since that would change displayed MHz stats for CPUs
- static bool firstcall = true;
- static U64 sCPUClockFrequency;
- if (firstcall)
- {
- QueryPerformanceFrequency((LARGE_INTEGER*)&sCPUClockFrequency);
- firstcall = false;
- }
-#endif
- return sCPUClockFrequency >> 8;
-}
-#endif
-
-LLFastTimer::FrameState::FrameState(LLFastTimer::NamedTimer* timerp)
-: mActiveCount(0),
- mCalls(0),
- mSelfTimeCounter(0),
- mParent(NULL),
- mLastCaller(NULL),
- mMoveUpTree(false),
- mTimer(timerp)
-{}
-
-
-LLFastTimer::NamedTimer::NamedTimer(const std::string& name)
-: mName(name),
- mCollapsed(true),
- mParent(NULL),
- mTotalTimeCounter(0),
- mCountAverage(0),
- mCallAverage(0),
- mNeedsSorting(false)
-{
- info_list_t& frame_state_list = getFrameStateList();
- mFrameStateIndex = frame_state_list.size();
- getFrameStateList().push_back(FrameState(this));
-
- mCountHistory = new U32[HISTORY_NUM];
- memset(mCountHistory, 0, sizeof(U32) * HISTORY_NUM);
- mCallHistory = new U32[HISTORY_NUM];
- memset(mCallHistory, 0, sizeof(U32) * HISTORY_NUM);
-}
-
-LLFastTimer::NamedTimer::~NamedTimer()
-{
- delete[] mCountHistory;
- delete[] mCallHistory;
-}
-
-std::string LLFastTimer::NamedTimer::getToolTip(S32 history_idx)
-{
- F64 ms_multiplier = 1000.0 / (F64)LLFastTimer::countsPerSecond();
- if (history_idx < 0)
- {
- // by default, show average number of call
- return llformat("%s (%d ms, %d calls)", getName().c_str(), (S32)(getCountAverage() * ms_multiplier), (S32)getCallAverage());
- }
- else
- {
- return llformat("%s (%d ms, %d calls)", getName().c_str(), (S32)(getHistoricalCount(history_idx) * ms_multiplier), (S32)getHistoricalCalls(history_idx));
- }
-}
-
-void LLFastTimer::NamedTimer::setParent(NamedTimer* parent)
-{
- llassert_always(parent != this);
- llassert_always(parent != NULL);
-
- if (mParent)
- {
- // subtract our accumulated from previous parent
- for (S32 i = 0; i < HISTORY_NUM; i++)
- {
- mParent->mCountHistory[i] -= mCountHistory[i];
- }
-
- // subtract average timing from previous parent
- mParent->mCountAverage -= mCountAverage;
-
- std::vector<NamedTimer*>& children = mParent->getChildren();
- std::vector<NamedTimer*>::iterator found_it = std::find(children.begin(), children.end(), this);
- if (found_it != children.end())
- {
- children.erase(found_it);
- }
- }
-
- mParent = parent;
- if (parent)
- {
- getFrameState().mParent = &parent->getFrameState();
- parent->getChildren().push_back(this);
- parent->mNeedsSorting = true;
- }
-}
-
-S32 LLFastTimer::NamedTimer::getDepth()
-{
- S32 depth = 0;
- NamedTimer* timerp = mParent;
- while(timerp)
- {
- depth++;
- timerp = timerp->mParent;
- }
- return depth;
-}
-
-// static
-void LLFastTimer::NamedTimer::processTimes()
-{
- if (sCurFrameIndex < 0) return;
-
- buildHierarchy();
- accumulateTimings();
-}
-
-// sort timer info structs by depth first traversal order
-struct SortTimersDFS
-{
- bool operator()(const LLFastTimer::FrameState& i1, const LLFastTimer::FrameState& i2)
- {
- return i1.mTimer->getFrameStateIndex() < i2.mTimer->getFrameStateIndex();
- }
-};
-
-// sort child timers by name
-struct SortTimerByName
-{
- bool operator()(const LLFastTimer::NamedTimer* i1, const LLFastTimer::NamedTimer* i2)
- {
- return i1->getName() < i2->getName();
- }
-};
-
-//static
-void LLFastTimer::NamedTimer::buildHierarchy()
-{
- if (sCurFrameIndex < 0 ) return;
-
- // set up initial tree
- {
- for (instance_iter it = beginInstances(); it != endInstances(); ++it)
- {
- NamedTimer& timer = *it;
- if (&timer == NamedTimerFactory::instance().getRootTimer()) continue;
-
- // bootstrap tree construction by attaching to last timer to be on stack
- // when this timer was called
- if (timer.getFrameState().mLastCaller && timer.mParent == NamedTimerFactory::instance().getRootTimer())
- {
- timer.setParent(timer.getFrameState().mLastCaller->mTimer);
- // no need to push up tree on first use, flag can be set spuriously
- timer.getFrameState().mMoveUpTree = false;
- }
- }
- }
-
- // bump timers up tree if they've been flagged as being in the wrong place
- // do this in a bottom up order to promote descendants first before promoting ancestors
- // this preserves partial order derived from current frame's observations
- for(timer_tree_bottom_up_iterator_t it = begin_timer_tree_bottom_up(*NamedTimerFactory::instance().getRootTimer());
- it != end_timer_tree_bottom_up();
- ++it)
- {
- NamedTimer* timerp = *it;
- // skip root timer
- if (timerp == NamedTimerFactory::instance().getRootTimer()) continue;
-
- if (timerp->getFrameState().mMoveUpTree)
- {
- // since ancestors have already been visited, reparenting won't affect tree traversal
- //step up tree, bringing our descendants with us
- //llinfos << "Moving " << timerp->getName() << " from child of " << timerp->getParent()->getName() <<
- // " to child of " << timerp->getParent()->getParent()->getName() << llendl;
- timerp->setParent(timerp->getParent()->getParent());
- timerp->getFrameState().mMoveUpTree = false;
-
- // don't bubble up any ancestors until descendants are done bubbling up
- it.skipAncestors();
- }
- }
-
- // sort timers by time last called, so call graph makes sense
- for(timer_tree_dfs_iterator_t it = begin_timer_tree(*NamedTimerFactory::instance().getRootTimer());
- it != end_timer_tree();
- ++it)
- {
- NamedTimer* timerp = (*it);
- if (timerp->mNeedsSorting)
- {
- std::sort(timerp->getChildren().begin(), timerp->getChildren().end(), SortTimerByName());
- }
- timerp->mNeedsSorting = false;
- }
-}
-
-//static
-void LLFastTimer::NamedTimer::accumulateTimings()
-{
- U32 cur_time = getCPUClockCount32();
-
- // walk up stack of active timers and accumulate current time while leaving timing structures active
- LLFastTimer* cur_timer = sCurTimerData.mCurTimer;
- // root defined by parent pointing to self
- CurTimerData* cur_data = &sCurTimerData;
- while(cur_timer->mLastTimerData.mCurTimer != cur_timer)
- {
- U32 cumulative_time_delta = cur_time - cur_timer->mStartTime;
- U32 self_time_delta = cumulative_time_delta - cur_data->mChildTime;
- cur_data->mChildTime = 0;
- cur_timer->mFrameState->mSelfTimeCounter += self_time_delta;
- cur_timer->mStartTime = cur_time;
-
- cur_data = &cur_timer->mLastTimerData;
- cur_data->mChildTime += cumulative_time_delta;
-
- cur_timer = cur_timer->mLastTimerData.mCurTimer;
- }
-
- // traverse tree in DFS post order, or bottom up
- for(timer_tree_bottom_up_iterator_t it = begin_timer_tree_bottom_up(*NamedTimerFactory::instance().getActiveRootTimer());
- it != end_timer_tree_bottom_up();
- ++it)
- {
- NamedTimer* timerp = (*it);
- timerp->mTotalTimeCounter = timerp->getFrameState().mSelfTimeCounter;
- for (child_const_iter child_it = timerp->beginChildren(); child_it != timerp->endChildren(); ++child_it)
- {
- timerp->mTotalTimeCounter += (*child_it)->mTotalTimeCounter;
- }
-
- S32 cur_frame = sCurFrameIndex;
- if (cur_frame >= 0)
- {
- // update timer history
- int hidx = cur_frame % HISTORY_NUM;
-
- timerp->mCountHistory[hidx] = timerp->mTotalTimeCounter;
- timerp->mCountAverage = ((U64)timerp->mCountAverage * cur_frame + timerp->mTotalTimeCounter) / (cur_frame+1);
- timerp->mCallHistory[hidx] = timerp->getFrameState().mCalls;
- timerp->mCallAverage = ((U64)timerp->mCallAverage * cur_frame + timerp->getFrameState().mCalls) / (cur_frame+1);
- }
- }
-}
-
-// static
-void LLFastTimer::NamedTimer::resetFrame()
-{
- if (sLog)
- { //output current frame counts to performance log
-
- static S32 call_count = 0;
- if (call_count % 100 == 0)
- {
- llinfos << "countsPerSecond (32 bit): " << countsPerSecond() << llendl;
- llinfos << "get_clock_count (64 bit): " << get_clock_count() << llendl;
- llinfos << "LLProcessorInfo().getCPUFrequency() " << LLProcessorInfo().getCPUFrequency() << llendl;
- llinfos << "getCPUClockCount32() " << getCPUClockCount32() << llendl;
- llinfos << "getCPUClockCount64() " << getCPUClockCount64() << llendl;
- llinfos << "elapsed sec " << ((F64)getCPUClockCount64())/((F64)LLProcessorInfo().getCPUFrequency()*1000000.0) << llendl;
- }
- call_count++;
-
- F64 iclock_freq = 1000.0 / countsPerSecond(); // good place to calculate clock frequency
-
- F64 total_time = 0;
- LLSD sd;
-
- {
- for (instance_iter it = beginInstances(); it != endInstances(); ++it)
- {
- NamedTimer& timer = *it;
- FrameState& info = timer.getFrameState();
- sd[timer.getName()]["Time"] = (LLSD::Real) (info.mSelfTimeCounter*iclock_freq);
- sd[timer.getName()]["Calls"] = (LLSD::Integer) info.mCalls;
-
- // computing total time here because getting the root timer's getCountHistory
- // doesn't work correctly on the first frame
- total_time = total_time + info.mSelfTimeCounter * iclock_freq;
- }
- }
-
- sd["Total"]["Time"] = (LLSD::Real) total_time;
- sd["Total"]["Calls"] = (LLSD::Integer) 1;
-
- {
- LLMutexLock lock(sLogLock);
- sLogQueue.push(sd);
- }
- }
-
-
- // tag timers by position in depth first traversal of tree
- S32 index = 0;
- for(timer_tree_dfs_iterator_t it = begin_timer_tree(*NamedTimerFactory::instance().getRootTimer());
- it != end_timer_tree();
- ++it)
- {
- NamedTimer* timerp = (*it);
-
- timerp->mFrameStateIndex = index;
- index++;
-
- llassert_always(timerp->mFrameStateIndex < (S32)getFrameStateList().size());
- }
-
- // sort timers by DFS traversal order to improve cache coherency
- std::sort(getFrameStateList().begin(), getFrameStateList().end(), SortTimersDFS());
-
- // update pointers into framestatelist now that we've sorted it
- DeclareTimer::updateCachedPointers();
-
- // reset for next frame
- {
- for (instance_iter it = beginInstances(); it != endInstances(); ++it)
- {
- NamedTimer& timer = *it;
-
- FrameState& info = timer.getFrameState();
- info.mSelfTimeCounter = 0;
- info.mCalls = 0;
- info.mLastCaller = NULL;
- info.mMoveUpTree = false;
- // update parent pointer in timer state struct
- if (timer.mParent)
- {
- info.mParent = &timer.mParent->getFrameState();
- }
- }
- }
-
- //sTimerCycles = 0;
- //sTimerCalls = 0;
-}
-
-//static
-void LLFastTimer::NamedTimer::reset()
-{
- resetFrame(); // reset frame data
-
- // walk up stack of active timers and reset start times to current time
- // effectively zeroing out any accumulated time
- U32 cur_time = getCPUClockCount32();
-
- // root defined by parent pointing to self
- CurTimerData* cur_data = &sCurTimerData;
- LLFastTimer* cur_timer = cur_data->mCurTimer;
- while(cur_timer->mLastTimerData.mCurTimer != cur_timer)
- {
- cur_timer->mStartTime = cur_time;
- cur_data->mChildTime = 0;
-
- cur_data = &cur_timer->mLastTimerData;
- cur_timer = cur_data->mCurTimer;
- }
-
- // reset all history
- {
- for (instance_iter it = beginInstances(); it != endInstances(); ++it)
- {
- NamedTimer& timer = *it;
- if (&timer != NamedTimerFactory::instance().getRootTimer())
- {
- timer.setParent(NamedTimerFactory::instance().getRootTimer());
- }
-
- timer.mCountAverage = 0;
- timer.mCallAverage = 0;
- memset(timer.mCountHistory, 0, sizeof(U32) * HISTORY_NUM);
- memset(timer.mCallHistory, 0, sizeof(U32) * HISTORY_NUM);
- }
- }
-
- sLastFrameIndex = 0;
- sCurFrameIndex = 0;
-}
-
-//static
-LLFastTimer::info_list_t& LLFastTimer::getFrameStateList()
-{
- if (!sTimerInfos)
- {
- sTimerInfos = new info_list_t();
- }
- return *sTimerInfos;
-}
-
-
-U32 LLFastTimer::NamedTimer::getHistoricalCount(S32 history_index) const
-{
- S32 history_idx = (getLastFrameIndex() + history_index) % LLFastTimer::NamedTimer::HISTORY_NUM;
- return mCountHistory[history_idx];
-}
-
-U32 LLFastTimer::NamedTimer::getHistoricalCalls(S32 history_index ) const
-{
- S32 history_idx = (getLastFrameIndex() + history_index) % LLFastTimer::NamedTimer::HISTORY_NUM;
- return mCallHistory[history_idx];
-}
-
-LLFastTimer::FrameState& LLFastTimer::NamedTimer::getFrameState() const
-{
- llassert_always(mFrameStateIndex >= 0);
- if (this == NamedTimerFactory::instance().getActiveRootTimer())
- {
- return NamedTimerFactory::instance().getRootFrameState();
- }
- return getFrameStateList()[mFrameStateIndex];
-}
-
-// static
-LLFastTimer::NamedTimer& LLFastTimer::NamedTimer::getRootNamedTimer()
-{
- return *NamedTimerFactory::instance().getActiveRootTimer();
-}
-
-std::vector<LLFastTimer::NamedTimer*>::const_iterator LLFastTimer::NamedTimer::beginChildren()
-{
- return mChildren.begin();
-}
-
-std::vector<LLFastTimer::NamedTimer*>::const_iterator LLFastTimer::NamedTimer::endChildren()
-{
- return mChildren.end();
-}
-
-std::vector<LLFastTimer::NamedTimer*>& LLFastTimer::NamedTimer::getChildren()
-{
- return mChildren;
-}
-
-//static
-void LLFastTimer::nextFrame()
-{
- countsPerSecond(); // good place to calculate clock frequency
- U64 frame_time = getCPUClockCount64();
- if ((frame_time - sLastFrameTime) >> 8 > 0xffffffff)
- {
- llinfos << "Slow frame, fast timers inaccurate" << llendl;
- }
-
- if (!sPauseHistory)
- {
- NamedTimer::processTimes();
- sLastFrameIndex = sCurFrameIndex++;
- }
-
- // get ready for next frame
- NamedTimer::resetFrame();
- sLastFrameTime = frame_time;
-}
-
-//static
-void LLFastTimer::dumpCurTimes()
-{
- // accumulate timings, etc.
- NamedTimer::processTimes();
-
- F64 clock_freq = (F64)countsPerSecond();
- F64 iclock_freq = 1000.0 / clock_freq; // clock_ticks -> milliseconds
-
- // walk over timers in depth order and output timings
- for(timer_tree_dfs_iterator_t it = begin_timer_tree(*NamedTimerFactory::instance().getRootTimer());
- it != end_timer_tree();
- ++it)
- {
- NamedTimer* timerp = (*it);
- F64 total_time_ms = ((F64)timerp->getHistoricalCount(0) * iclock_freq);
- // Don't bother with really brief times, keep output concise
- if (total_time_ms < 0.1) continue;
-
- std::ostringstream out_str;
- for (S32 i = 0; i < timerp->getDepth(); i++)
- {
- out_str << "\t";
- }
-
-
- out_str << timerp->getName() << " "
- << std::setprecision(3) << total_time_ms << " ms, "
- << timerp->getHistoricalCalls(0) << " calls";
-
- llinfos << out_str.str() << llendl;
- }
-}
-
-//static
-void LLFastTimer::reset()
-{
- NamedTimer::reset();
-}
-
-
-//static
-void LLFastTimer::writeLog(std::ostream& os)
-{
- while (!sLogQueue.empty())
- {
- LLSD& sd = sLogQueue.front();
- LLSDSerialize::toXML(sd, os);
- LLMutexLock lock(sLogLock);
- sLogQueue.pop();
- }
-}
-
-//static
-const LLFastTimer::NamedTimer* LLFastTimer::getTimerByName(const std::string& name)
-{
- return NamedTimerFactory::instance().getTimerByName(name);
-}
-
-LLFastTimer::LLFastTimer(LLFastTimer::FrameState* state)
-: mFrameState(state)
-{
- U32 start_time = getCPUClockCount32();
- mStartTime = start_time;
- mFrameState->mActiveCount++;
- LLFastTimer::sCurTimerData.mCurTimer = this;
- LLFastTimer::sCurTimerData.mFrameState = mFrameState;
- LLFastTimer::sCurTimerData.mChildTime = 0;
- mLastTimerData = LLFastTimer::sCurTimerData;
-}
-
-
-//////////////////////////////////////////////////////////////////////////////
-//
-// Important note: These implementations must be FAST!
-//
-
-
-#if LL_WINDOWS
-//
-// Windows implementation of CPU clock
-//
-
-//
-// NOTE: put back in when we aren't using platform sdk anymore
-//
-// because MS has different signatures for these functions in winnt.h
-// need to rename them to avoid conflicts
-//#define _interlockedbittestandset _renamed_interlockedbittestandset
-//#define _interlockedbittestandreset _renamed_interlockedbittestandreset
-//#include <intrin.h>
-//#undef _interlockedbittestandset
-//#undef _interlockedbittestandreset
-
-//inline U32 LLFastTimer::getCPUClockCount32()
-//{
-// U64 time_stamp = __rdtsc();
-// return (U32)(time_stamp >> 8);
-//}
-//
-//// return full timer value, *not* shifted by 8 bits
-//inline U64 LLFastTimer::getCPUClockCount64()
-//{
-// return __rdtsc();
-//}
-
-// shift off lower 8 bits for lower resolution but longer term timing
-// on 1Ghz machine, a 32-bit word will hold ~1000 seconds of timing
-#if USE_RDTSC
-U32 LLFastTimer::getCPUClockCount32()
-{
- U32 ret_val;
- __asm
- {
- _emit 0x0f
- _emit 0x31
- shr eax,8
- shl edx,24
- or eax, edx
- mov dword ptr [ret_val], eax
- }
- return ret_val;
-}
-
-// return full timer value, *not* shifted by 8 bits
-U64 LLFastTimer::getCPUClockCount64()
-{
- U64 ret_val;
- __asm
- {
- _emit 0x0f
- _emit 0x31
- mov eax,eax
- mov edx,edx
- mov dword ptr [ret_val+4], edx
- mov dword ptr [ret_val], eax
- }
- return ret_val;
-}
-
-std::string LLFastTimer::sClockType = "rdtsc";
-
-#else
-//LL_COMMON_API U64 get_clock_count(); // in lltimer.cpp
-// These use QueryPerformanceCounter, which is arguably fine and also works on AMD architectures.
-U32 LLFastTimer::getCPUClockCount32()
-{
- return (U32)(get_clock_count()>>8);
-}
-
-U64 LLFastTimer::getCPUClockCount64()
-{
- return get_clock_count();
-}
-
-std::string LLFastTimer::sClockType = "QueryPerformanceCounter";
-#endif
-
-#endif
-
-
-#if (LL_LINUX || LL_SOLARIS) && !(defined(__i386__) || defined(__amd64__))
-//
-// Linux and Solaris implementation of CPU clock - non-x86.
-// This is accurate but SLOW! Only use out of desperation.
-//
-// Try to use the MONOTONIC clock if available, this is a constant time counter
-// with nanosecond resolution (but not necessarily accuracy) and attempts are
-// made to synchronize this value between cores at kernel start. It should not
-// be affected by CPU frequency. If not available use the REALTIME clock, but
-// this may be affected by NTP adjustments or other user activity affecting
-// the system time.
-U64 LLFastTimer::getCPUClockCount64()
-{
- struct timespec tp;
-
-#ifdef CLOCK_MONOTONIC // MONOTONIC supported at build-time?
- if (-1 == clock_gettime(CLOCK_MONOTONIC,&tp)) // if MONOTONIC isn't supported at runtime then ouch, try REALTIME
-#endif
- clock_gettime(CLOCK_REALTIME,&tp);
-
- return (tp.tv_sec*LLFastTimer::sClockResolution)+tp.tv_nsec;
-}
-
-U32 LLFastTimer::getCPUClockCount32()
-{
- return (U32)(LLFastTimer::getCPUClockCount64() >> 8);
-}
-
-std::string LLFastTimer::sClockType = "clock_gettime";
-
-#endif // (LL_LINUX || LL_SOLARIS) && !(defined(__i386__) || defined(__amd64__))
-
-
-#if (LL_LINUX || LL_SOLARIS || LL_DARWIN) && (defined(__i386__) || defined(__amd64__))
-//
-// Mac+Linux+Solaris FAST x86 implementation of CPU clock
-U32 LLFastTimer::getCPUClockCount32()
-{
- U64 x;
- __asm__ volatile (".byte 0x0f, 0x31": "=A"(x));
- return (U32)(x >> 8);
-}
-
-U64 LLFastTimer::getCPUClockCount64()
-{
- U64 x;
- __asm__ volatile (".byte 0x0f, 0x31": "=A"(x));
- return x;
-}
-
-std::string LLFastTimer::sClockType = "rdtsc";
-#endif
-
diff --git a/indra/llcommon/llfasttimer_class.h b/indra/llcommon/llfasttimer_class.h
deleted file mode 100644
index f481e968a6..0000000000
--- a/indra/llcommon/llfasttimer_class.h
+++ /dev/null
@@ -1,276 +0,0 @@
-/**
- * @file llfasttimer_class.h
- * @brief Declaration of a fast timer.
- *
- * $LicenseInfo:firstyear=2004&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$
- */
-
-#ifndef LL_FASTTIMER_CLASS_H
-#define LL_FASTTIMER_CLASS_H
-
-#include "llinstancetracker.h"
-
-#define FAST_TIMER_ON 1
-#define TIME_FAST_TIMERS 0
-#define DEBUG_FAST_TIMER_THREADS 1
-
-class LLMutex;
-
-#include <queue>
-#include "llsd.h"
-
-LL_COMMON_API void assert_main_thread();
-
-class LL_COMMON_API LLFastTimer
-{
-public:
- class NamedTimer;
-
- struct LL_COMMON_API FrameState
- {
- FrameState(NamedTimer* timerp);
-
- U32 mSelfTimeCounter;
- U32 mCalls;
- FrameState* mParent; // info for caller timer
- FrameState* mLastCaller; // used to bootstrap tree construction
- NamedTimer* mTimer;
- U16 mActiveCount; // number of timers with this ID active on stack
- bool mMoveUpTree; // needs to be moved up the tree of timers at the end of frame
- };
-
- // stores a "named" timer instance to be reused via multiple LLFastTimer stack instances
- class LL_COMMON_API NamedTimer
- : public LLInstanceTracker<NamedTimer>
- {
- friend class DeclareTimer;
- public:
- ~NamedTimer();
-
- enum { HISTORY_NUM = 300 };
-
- const std::string& getName() const { return mName; }
- NamedTimer* getParent() const { return mParent; }
- void setParent(NamedTimer* parent);
- S32 getDepth();
- std::string getToolTip(S32 history_index = -1);
-
- typedef std::vector<NamedTimer*>::const_iterator child_const_iter;
- child_const_iter beginChildren();
- child_const_iter endChildren();
- std::vector<NamedTimer*>& getChildren();
-
- void setCollapsed(bool collapsed) { mCollapsed = collapsed; }
- bool getCollapsed() const { return mCollapsed; }
-
- U32 getCountAverage() const { return mCountAverage; }
- U32 getCallAverage() const { return mCallAverage; }
-
- U32 getHistoricalCount(S32 history_index = 0) const;
- U32 getHistoricalCalls(S32 history_index = 0) const;
-
- static NamedTimer& getRootNamedTimer();
-
- S32 getFrameStateIndex() const { return mFrameStateIndex; }
-
- FrameState& getFrameState() const;
-
- private:
- friend class LLFastTimer;
- friend class NamedTimerFactory;
-
- //
- // methods
- //
- NamedTimer(const std::string& name);
- // recursive call to gather total time from children
- static void accumulateTimings();
-
- // updates cumulative times and hierarchy,
- // can be called multiple times in a frame, at any point
- static void processTimes();
-
- static void buildHierarchy();
- static void resetFrame();
- static void reset();
-
- //
- // members
- //
- S32 mFrameStateIndex;
-
- std::string mName;
-
- U32 mTotalTimeCounter;
-
- U32 mCountAverage;
- U32 mCallAverage;
-
- U32* mCountHistory;
- U32* mCallHistory;
-
- // tree structure
- NamedTimer* mParent; // NamedTimer of caller(parent)
- std::vector<NamedTimer*> mChildren;
- bool mCollapsed; // don't show children
- bool mNeedsSorting; // sort children whenever child added
- };
-
- // used to statically declare a new named timer
- class LL_COMMON_API DeclareTimer
- : public LLInstanceTracker<DeclareTimer>
- {
- friend class LLFastTimer;
- public:
- DeclareTimer(const std::string& name, bool open);
- DeclareTimer(const std::string& name);
-
- static void updateCachedPointers();
-
- private:
- NamedTimer& mTimer;
- FrameState* mFrameState;
- };
-
-public:
- LLFastTimer(LLFastTimer::FrameState* state);
-
- LL_FORCE_INLINE LLFastTimer(LLFastTimer::DeclareTimer& timer)
- : mFrameState(timer.mFrameState)
- {
-#if TIME_FAST_TIMERS
- U64 timer_start = getCPUClockCount64();
-#endif
-#if FAST_TIMER_ON
- LLFastTimer::FrameState* frame_state = mFrameState;
- mStartTime = getCPUClockCount32();
-
- frame_state->mActiveCount++;
- frame_state->mCalls++;
- // keep current parent as long as it is active when we are
- frame_state->mMoveUpTree |= (frame_state->mParent->mActiveCount == 0);
-
- LLFastTimer::CurTimerData* cur_timer_data = &LLFastTimer::sCurTimerData;
- mLastTimerData = *cur_timer_data;
- cur_timer_data->mCurTimer = this;
- cur_timer_data->mFrameState = frame_state;
- cur_timer_data->mChildTime = 0;
-#endif
-#if TIME_FAST_TIMERS
- U64 timer_end = getCPUClockCount64();
- sTimerCycles += timer_end - timer_start;
-#endif
-#if DEBUG_FAST_TIMER_THREADS
-#if !LL_RELEASE
- assert_main_thread();
-#endif
-#endif
- }
-
- LL_FORCE_INLINE ~LLFastTimer()
- {
-#if TIME_FAST_TIMERS
- U64 timer_start = getCPUClockCount64();
-#endif
-#if FAST_TIMER_ON
- LLFastTimer::FrameState* frame_state = mFrameState;
- U32 total_time = getCPUClockCount32() - mStartTime;
-
- frame_state->mSelfTimeCounter += total_time - LLFastTimer::sCurTimerData.mChildTime;
- frame_state->mActiveCount--;
-
- // store last caller to bootstrap tree creation
- // do this in the destructor in case of recursion to get topmost caller
- frame_state->mLastCaller = mLastTimerData.mFrameState;
-
- // we are only tracking self time, so subtract our total time delta from parents
- mLastTimerData.mChildTime += total_time;
-
- LLFastTimer::sCurTimerData = mLastTimerData;
-#endif
-#if TIME_FAST_TIMERS
- U64 timer_end = getCPUClockCount64();
- sTimerCycles += timer_end - timer_start;
- sTimerCalls++;
-#endif
- }
-
-public:
- static LLMutex* sLogLock;
- static std::queue<LLSD> sLogQueue;
- static BOOL sLog;
- static BOOL sMetricLog;
- static std::string sLogName;
- static bool sPauseHistory;
- static bool sResetHistory;
- static U64 sTimerCycles;
- static U32 sTimerCalls;
-
- typedef std::vector<FrameState> info_list_t;
- static info_list_t& getFrameStateList();
-
-
- // call this once a frame to reset timers
- static void nextFrame();
-
- // dumps current cumulative frame stats to log
- // call nextFrame() to reset timers
- static void dumpCurTimes();
-
- // call this to reset timer hierarchy, averages, etc.
- static void reset();
-
- static U64 countsPerSecond();
- static S32 getLastFrameIndex() { return sLastFrameIndex; }
- static S32 getCurFrameIndex() { return sCurFrameIndex; }
-
- static void writeLog(std::ostream& os);
- static const NamedTimer* getTimerByName(const std::string& name);
-
- struct CurTimerData
- {
- LLFastTimer* mCurTimer;
- FrameState* mFrameState;
- U32 mChildTime;
- };
- static CurTimerData sCurTimerData;
- static std::string sClockType;
-
-private:
- static U32 getCPUClockCount32();
- static U64 getCPUClockCount64();
- static U64 sClockResolution;
-
- static S32 sCurFrameIndex;
- static S32 sLastFrameIndex;
- static U64 sLastFrameTime;
- static info_list_t* sTimerInfos;
-
- U32 mStartTime;
- LLFastTimer::FrameState* mFrameState;
- LLFastTimer::CurTimerData mLastTimerData;
-
-};
-
-typedef class LLFastTimer LLFastTimer;
-
-#endif // LL_LLFASTTIMER_CLASS_H
diff --git a/indra/llcommon/llfile.cpp b/indra/llcommon/llfile.cpp
index c32a776c3f..c3a0f0bfe0 100644..100755
--- a/indra/llcommon/llfile.cpp
+++ b/indra/llcommon/llfile.cpp
@@ -1,4 +1,4 @@
-/**
+/**
* @file llfile.cpp
* @author Michael Schlachter
* @date 2006-03-23
@@ -8,60 +8,196 @@
* $LicenseInfo:firstyear=2006&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$
*/
#if LL_WINDOWS
#include <windows.h>
+#include <stdlib.h> // Windows errno
+#else
+#include <errno.h>
#endif
#include "linden_common.h"
#include "llfile.h"
#include "llstring.h"
#include "llerror.h"
+#include "stringize.h"
using namespace std;
+static std::string empty;
+
+// Many of the methods below use OS-level functions that mess with errno. Wrap
+// variants of strerror() to report errors.
+
+#if LL_WINDOWS
+// On Windows, use strerror_s().
+std::string strerr(int errn)
+{
+ char buffer[256];
+ strerror_s(buffer, errn); // infers sizeof(buffer) -- love it!
+ return buffer;
+}
+
+typedef std::basic_ios<char,std::char_traits < char > > _Myios;
+
+#else
+// On Posix we want to call strerror_r(), but alarmingly, there are two
+// different variants. The one that returns int always populates the passed
+// buffer (except in case of error), whereas the other one always returns a
+// valid char* but might or might not populate the passed buffer. How do we
+// know which one we're getting? Define adapters for each and let the compiler
+// select the applicable adapter.
+
+// strerror_r() returns char*
+std::string message_from(int /*orig_errno*/, const char* /*buffer*/, size_t /*bufflen*/,
+ const char* strerror_ret)
+{
+ return strerror_ret;
+}
+
+// strerror_r() returns int
+std::string message_from(int orig_errno, const char* buffer, size_t bufflen,
+ int strerror_ret)
+{
+ if (strerror_ret == 0)
+ {
+ return buffer;
+ }
+ // Here strerror_r() has set errno. Since strerror_r() has already failed,
+ // seems like a poor bet to call it again to diagnose its own error...
+ int stre_errno = errno;
+ if (stre_errno == ERANGE)
+ {
+ return STRINGIZE("strerror_r() can't explain errno " << orig_errno
+ << " (" << bufflen << "-byte buffer too small)");
+ }
+ if (stre_errno == EINVAL)
+ {
+ return STRINGIZE("unknown errno " << orig_errno);
+ }
+ // Here we don't even understand the errno from strerror_r()!
+ return STRINGIZE("strerror_r() can't explain errno " << orig_errno
+ << " (error " << stre_errno << ')');
+}
+
+std::string strerr(int errn)
+{
+ char buffer[256];
+ // Select message_from() function matching the strerror_r() we have on hand.
+ return message_from(errn, buffer, sizeof(buffer),
+ strerror_r(errn, buffer, sizeof(buffer)));
+}
+#endif // ! LL_WINDOWS
+
+// On either system, shorthand call just infers global 'errno'.
+std::string strerr()
+{
+ return strerr(errno);
+}
+
+int warnif(const std::string& desc, const std::string& filename, int rc, int accept=0)
+{
+ if (rc < 0)
+ {
+ // Capture errno before we start emitting output
+ int errn = errno;
+ // For certain operations, a particular errno value might be
+ // acceptable -- e.g. stat() could permit ENOENT, mkdir() could permit
+ // EEXIST. Don't warn if caller explicitly says this errno is okay.
+ if (errn != accept)
+ {
+ LL_WARNS("LLFile") << "Couldn't " << desc << " '" << filename
+ << "' (errno " << errn << "): " << strerr(errn) << LL_ENDL;
+ }
+#if 0 && LL_WINDOWS // turn on to debug file-locking problems
+ // If the problem is "Permission denied," maybe it's because another
+ // process has the file open. Try to find out.
+ if (errn == EACCES) // *not* EPERM
+ {
+ // Only do any of this stuff (before LL_ENDL) if it will be logged.
+ LL_DEBUGS("LLFile") << empty;
+ const char* TEMP = getenv("TEMP");
+ if (! TEMP)
+ {
+ LL_CONT << "No $TEMP, not running 'handle'";
+ }
+ else
+ {
+ std::string tf(TEMP);
+ tf += "\\handle.tmp";
+ // http://technet.microsoft.com/en-us/sysinternals/bb896655
+ std::string cmd(STRINGIZE("handle \"" << filename
+ // "openfiles /query /v | fgrep -i \"" << filename
+ << "\" > \"" << tf << '"'));
+ LL_CONT << cmd;
+ if (system(cmd.c_str()) != 0)
+ {
+ LL_CONT << "\nDownload 'handle.exe' from http://technet.microsoft.com/en-us/sysinternals/bb896655";
+ }
+ else
+ {
+ std::ifstream inf(tf);
+ std::string line;
+ while (std::getline(inf, line))
+ {
+ LL_CONT << '\n' << line;
+ }
+ }
+ LLFile::remove(tf);
+ }
+ LL_CONT << LL_ENDL;
+ }
+#endif // LL_WINDOWS hack to identify processes holding file open
+ }
+ return rc;
+}
+
// static
int LLFile::mkdir(const std::string& dirname, int perms)
{
-#if LL_WINDOWS
+#if LL_WINDOWS
// permissions are ignored on Windows
std::string utf8dirname = dirname;
llutf16string utf16dirname = utf8str_to_utf16str(utf8dirname);
- return _wmkdir(utf16dirname.c_str());
+ int rc = _wmkdir(utf16dirname.c_str());
#else
- return ::mkdir(dirname.c_str(), (mode_t)perms);
+ int rc = ::mkdir(dirname.c_str(), (mode_t)perms);
#endif
+ // We often use mkdir() to ensure the existence of a directory that might
+ // already exist. Don't spam the log if it does.
+ return warnif("mkdir", dirname, rc, EEXIST);
}
// static
int LLFile::rmdir(const std::string& dirname)
{
-#if LL_WINDOWS
+#if LL_WINDOWS
// permissions are ignored on Windows
std::string utf8dirname = dirname;
llutf16string utf16dirname = utf8str_to_utf16str(utf8dirname);
- return _wrmdir(utf16dirname.c_str());
+ int rc = _wrmdir(utf16dirname.c_str());
#else
- return ::rmdir(dirname.c_str());
+ int rc = ::rmdir(dirname.c_str());
#endif
+ return warnif("rmdir", dirname, rc);
}
// static
@@ -108,10 +244,11 @@ int LLFile::remove(const std::string& filename)
#if LL_WINDOWS
std::string utf8filename = filename;
llutf16string utf16filename = utf8str_to_utf16str(utf8filename);
- return _wremove(utf16filename.c_str());
+ int rc = _wremove(utf16filename.c_str());
#else
- return ::remove(filename.c_str());
+ int rc = ::remove(filename.c_str());
#endif
+ return warnif("remove", filename, rc);
}
int LLFile::rename(const std::string& filename, const std::string& newname)
@@ -121,10 +258,11 @@ int LLFile::rename(const std::string& filename, const std::string& newname)
std::string utf8newname = newname;
llutf16string utf16filename = utf8str_to_utf16str(utf8filename);
llutf16string utf16newname = utf8str_to_utf16str(utf8newname);
- return _wrename(utf16filename.c_str(),utf16newname.c_str());
+ int rc = _wrename(utf16filename.c_str(),utf16newname.c_str());
#else
- return ::rename(filename.c_str(),newname.c_str());
+ int rc = ::rename(filename.c_str(),newname.c_str());
#endif
+ return warnif(STRINGIZE("rename to '" << newname << "' from"), filename, rc);
}
int LLFile::stat(const std::string& filename, llstat* filestatus)
@@ -132,23 +270,26 @@ int LLFile::stat(const std::string& filename, llstat* filestatus)
#if LL_WINDOWS
std::string utf8filename = filename;
llutf16string utf16filename = utf8str_to_utf16str(utf8filename);
- return _wstat(utf16filename.c_str(),filestatus);
+ int rc = _wstat(utf16filename.c_str(),filestatus);
#else
- return ::stat(filename.c_str(),filestatus);
+ int rc = ::stat(filename.c_str(),filestatus);
#endif
+ // We use stat() to determine existence (see isfile(), isdir()).
+ // Don't spam the log if the subject pathname doesn't exist.
+ return warnif("stat", filename, rc, ENOENT);
}
bool LLFile::isdir(const std::string& filename)
{
llstat st;
-
+
return stat(filename, &st) == 0 && S_ISDIR(st.st_mode);
}
bool LLFile::isfile(const std::string& filename)
{
llstat st;
-
+
return stat(filename, &st) == 0 && S_ISREG(st.st_mode);
}
@@ -185,9 +326,10 @@ const char *LLFile::tmpdir()
/***************** Modified file stream created to overcome the incorrect behaviour of posix fopen in windows *******************/
-#if USE_LLFILESTREAMS
+#if LL_WINDOWS
-LLFILE * LLFile::_Fiopen(const std::string& filename, std::ios::openmode mode,int) // protection currently unused
+LLFILE * LLFile::_Fiopen(const std::string& filename,
+ std::ios::openmode mode)
{ // open a file
static const char *mods[] =
{ // fopen mode strings corresponding to valid[i]
@@ -246,117 +388,690 @@ LLFILE * LLFile::_Fiopen(const std::string& filename, std::ios::openmode mode,in
return (0);
}
-/************** input file stream ********************************/
+#endif /* LL_WINDOWS */
-void llifstream::close()
-{ // close the C stream
- if (_Filebuffer && _Filebuffer->close() == 0)
+/************** llstdio file buffer ********************************/
+
+
+//llstdio_filebuf* llstdio_filebuf::open(const char *_Filename,
+// ios_base::openmode _Mode)
+//{
+//#if LL_WINDOWS
+// _Filet *_File;
+// if (is_open() || (_File = LLFILE::_Fiopen(_Filename, _Mode)) == 0)
+// return (0); // open failed
+//
+// _Init(_File, _Openfl);
+// _Initcvt(&_USE(_Mysb::getloc(), _Cvt));
+// return (this); // open succeeded
+//#else
+// std::filebuf* _file = std::filebuf::open(_Filename, _Mode);
+// if (NULL == _file) return NULL;
+// return this;
+//#endif
+//}
+
+
+// *TODO: Seek the underlying c stream for better cross-platform compatibility?
+#if !LL_WINDOWS
+llstdio_filebuf::int_type llstdio_filebuf::overflow(llstdio_filebuf::int_type __c)
+{
+ int_type __ret = traits_type::eof();
+ const bool __testeof = traits_type::eq_int_type(__c, __ret);
+ const bool __testout = _M_mode & ios_base::out;
+ if (__testout && !_M_reading)
{
- _Myios::setstate(ios_base::failbit); /*Flawfinder: ignore*/
+ if (this->pbase() < this->pptr())
+ {
+ // If appropriate, append the overflow char.
+ if (!__testeof)
+ {
+ *this->pptr() = traits_type::to_char_type(__c);
+ this->pbump(1);
+ }
+
+ // Convert pending sequence to external representation,
+ // and output.
+ if (_convert_to_external(this->pbase(),
+ this->pptr() - this->pbase()))
+ {
+ _M_set_buffer(0);
+ __ret = traits_type::not_eof(__c);
+ }
}
+ else if (_M_buf_size > 1)
+ {
+ // Overflow in 'uncommitted' mode: set _M_writing, set
+ // the buffer to the initial 'write' mode, and put __c
+ // into the buffer.
+ _M_set_buffer(0);
+ _M_writing = true;
+ if (!__testeof)
+ {
+ *this->pptr() = traits_type::to_char_type(__c);
+ this->pbump(1);
+ }
+ __ret = traits_type::not_eof(__c);
+ }
+ else
+ {
+ // Unbuffered.
+ char_type __conv = traits_type::to_char_type(__c);
+ if (__testeof || _convert_to_external(&__conv, 1))
+ {
+ _M_writing = true;
+ __ret = traits_type::not_eof(__c);
+ }
+ }
+ }
+ return __ret;
}
-void llifstream::open(const std::string& _Filename, /* Flawfinder: ignore */
- ios_base::openmode _Mode,
- int _Prot)
-{ // open a C stream with specified mode
-
- LLFILE* filep = LLFile::_Fiopen(_Filename,_Mode | ios_base::in, _Prot);
- if(filep == NULL)
+bool llstdio_filebuf::_convert_to_external(char_type* __ibuf,
+ std::streamsize __ilen)
+{
+ // Sizes of external and pending output.
+ streamsize __elen;
+ streamsize __plen;
+ if (__check_facet(_M_codecvt).always_noconv())
+ {
+ //__elen = _M_file.xsputn(reinterpret_cast<char*>(__ibuf), __ilen);
+ __elen = fwrite(reinterpret_cast<void*>(__ibuf), 1,
+ __ilen, _M_file.file());
+ __plen = __ilen;
+ }
+ else
+ {
+ // Worst-case number of external bytes needed.
+ // XXX Not done encoding() == -1.
+ streamsize __blen = __ilen * _M_codecvt->max_length();
+ char* __buf = static_cast<char*>(__builtin_alloca(__blen));
+
+ char* __bend;
+ const char_type* __iend;
+ codecvt_base::result __r;
+ __r = _M_codecvt->out(_M_state_cur, __ibuf, __ibuf + __ilen,
+ __iend, __buf, __buf + __blen, __bend);
+
+ if (__r == codecvt_base::ok || __r == codecvt_base::partial)
+ __blen = __bend - __buf;
+ else if (__r == codecvt_base::noconv)
{
- _Myios::setstate(ios_base::failbit); /*Flawfinder: ignore*/
- return;
+ // Same as the always_noconv case above.
+ __buf = reinterpret_cast<char*>(__ibuf);
+ __blen = __ilen;
+ }
+ else
+ __throw_ios_failure(__N("llstdio_filebuf::_convert_to_external "
+ "conversion error"));
+
+ //__elen = _M_file.xsputn(__buf, __blen);
+ __elen = fwrite(__buf, 1, __blen, _M_file.file());
+ __plen = __blen;
+
+ // Try once more for partial conversions.
+ if (__r == codecvt_base::partial && __elen == __plen)
+ {
+ const char_type* __iresume = __iend;
+ streamsize __rlen = this->pptr() - __iend;
+ __r = _M_codecvt->out(_M_state_cur, __iresume,
+ __iresume + __rlen, __iend, __buf,
+ __buf + __blen, __bend);
+ if (__r != codecvt_base::error)
+ {
+ __rlen = __bend - __buf;
+ //__elen = _M_file.xsputn(__buf, __rlen);
+ __elen = fwrite(__buf, 1, __rlen, _M_file.file());
+ __plen = __rlen;
+ }
+ else
+ {
+ __throw_ios_failure(__N("llstdio_filebuf::_convert_to_external "
+ "conversion error"));
+ }
+ }
}
- llassert(_Filebuffer == NULL);
- _Filebuffer = new _Myfb(filep);
- _ShouldClose = true;
- _Myios::init(_Filebuffer);
+ return __elen == __plen;
}
-bool llifstream::is_open() const
-{ // test if C stream has been opened
- if(_Filebuffer)
- return (_Filebuffer->is_open());
- return false;
+llstdio_filebuf::int_type llstdio_filebuf::underflow()
+{
+ int_type __ret = traits_type::eof();
+ const bool __testin = _M_mode & ios_base::in;
+ if (__testin)
+ {
+ if (_M_writing)
+ {
+ if (overflow() == traits_type::eof())
+ return __ret;
+ //_M_set_buffer(-1);
+ //_M_writing = false;
+ }
+ // Check for pback madness, and if so switch back to the
+ // normal buffers and jet outta here before expensive
+ // fileops happen...
+ _M_destroy_pback();
+
+ if (this->gptr() < this->egptr())
+ return traits_type::to_int_type(*this->gptr());
+
+ // Get and convert input sequence.
+ const size_t __buflen = _M_buf_size > 1 ? _M_buf_size - 1 : 1;
+
+ // Will be set to true if ::fread() returns 0 indicating EOF.
+ bool __got_eof = false;
+ // Number of internal characters produced.
+ streamsize __ilen = 0;
+ codecvt_base::result __r = codecvt_base::ok;
+ if (__check_facet(_M_codecvt).always_noconv())
+ {
+ //__ilen = _M_file.xsgetn(reinterpret_cast<char*>(this->eback()),
+ // __buflen);
+ __ilen = fread(reinterpret_cast<void*>(this->eback()), 1,
+ __buflen, _M_file.file());
+ if (__ilen == 0)
+ __got_eof = true;
+ }
+ else
+ {
+ // Worst-case number of external bytes.
+ // XXX Not done encoding() == -1.
+ const int __enc = _M_codecvt->encoding();
+ streamsize __blen; // Minimum buffer size.
+ streamsize __rlen; // Number of chars to read.
+ if (__enc > 0)
+ __blen = __rlen = __buflen * __enc;
+ else
+ {
+ __blen = __buflen + _M_codecvt->max_length() - 1;
+ __rlen = __buflen;
+ }
+ const streamsize __remainder = _M_ext_end - _M_ext_next;
+ __rlen = __rlen > __remainder ? __rlen - __remainder : 0;
+
+ // An imbue in 'read' mode implies first converting the external
+ // chars already present.
+ if (_M_reading && this->egptr() == this->eback() && __remainder)
+ __rlen = 0;
+
+ // Allocate buffer if necessary and move unconverted
+ // bytes to front.
+ if (_M_ext_buf_size < __blen)
+ {
+ char* __buf = new char[__blen];
+ if (__remainder)
+ __builtin_memcpy(__buf, _M_ext_next, __remainder);
+
+ delete [] _M_ext_buf;
+ _M_ext_buf = __buf;
+ _M_ext_buf_size = __blen;
+ }
+ else if (__remainder)
+ __builtin_memmove(_M_ext_buf, _M_ext_next, __remainder);
+
+ _M_ext_next = _M_ext_buf;
+ _M_ext_end = _M_ext_buf + __remainder;
+ _M_state_last = _M_state_cur;
+
+ do
+ {
+ if (__rlen > 0)
+ {
+ // Sanity check!
+ // This may fail if the return value of
+ // codecvt::max_length() is bogus.
+ if (_M_ext_end - _M_ext_buf + __rlen > _M_ext_buf_size)
+ {
+ __throw_ios_failure(__N("llstdio_filebuf::underflow "
+ "codecvt::max_length() "
+ "is not valid"));
+ }
+ //streamsize __elen = _M_file.xsgetn(_M_ext_end, __rlen);
+ streamsize __elen = fread(_M_ext_end, 1,
+ __rlen, _M_file.file());
+ if (__elen == 0)
+ __got_eof = true;
+ else if (__elen == -1)
+ break;
+ //_M_ext_end += __elen;
+ }
+
+ char_type* __iend = this->eback();
+ if (_M_ext_next < _M_ext_end)
+ {
+ __r = _M_codecvt->in(_M_state_cur, _M_ext_next,
+ _M_ext_end, _M_ext_next,
+ this->eback(),
+ this->eback() + __buflen, __iend);
+}
+ if (__r == codecvt_base::noconv)
+{
+ size_t __avail = _M_ext_end - _M_ext_buf;
+ __ilen = std::min(__avail, __buflen);
+ traits_type::copy(this->eback(),
+ reinterpret_cast<char_type*>
+ (_M_ext_buf), __ilen);
+ _M_ext_next = _M_ext_buf + __ilen;
+ }
+ else
+ __ilen = __iend - this->eback();
+
+ // _M_codecvt->in may return error while __ilen > 0: this is
+ // ok, and actually occurs in case of mixed encodings (e.g.,
+ // XML files).
+ if (__r == codecvt_base::error)
+ break;
+
+ __rlen = 1;
+ } while (__ilen == 0 && !__got_eof);
+ }
+
+ if (__ilen > 0)
+ {
+ _M_set_buffer(__ilen);
+ _M_reading = true;
+ __ret = traits_type::to_int_type(*this->gptr());
+ }
+ else if (__got_eof)
+ {
+ // If the actual end of file is reached, set 'uncommitted'
+ // mode, thus allowing an immediate write without an
+ // intervening seek.
+ _M_set_buffer(-1);
+ _M_reading = false;
+ // However, reaching it while looping on partial means that
+ // the file has got an incomplete character.
+ if (__r == codecvt_base::partial)
+ __throw_ios_failure(__N("llstdio_filebuf::underflow "
+ "incomplete character in file"));
+ }
+ else if (__r == codecvt_base::error)
+ __throw_ios_failure(__N("llstdio_filebuf::underflow "
+ "invalid byte sequence in file"));
+ else
+ __throw_ios_failure(__N("llstdio_filebuf::underflow "
+ "error reading the file"));
+ }
+ return __ret;
}
-llifstream::~llifstream()
-{
- if (_ShouldClose)
+
+std::streamsize llstdio_filebuf::xsgetn(char_type* __s, std::streamsize __n)
+{
+ // Clear out pback buffer before going on to the real deal...
+ streamsize __ret = 0;
+ if (_M_pback_init)
+ {
+ if (__n > 0 && this->gptr() == this->eback())
+ {
+ *__s++ = *this->gptr();
+ this->gbump(1);
+ __ret = 1;
+ --__n;
+ }
+ _M_destroy_pback();
+ }
+
+ // Optimization in the always_noconv() case, to be generalized in the
+ // future: when __n > __buflen we read directly instead of using the
+ // buffer repeatedly.
+ const bool __testin = _M_mode & ios_base::in;
+ const streamsize __buflen = _M_buf_size > 1 ? _M_buf_size - 1 : 1;
+
+ if (__n > __buflen && __check_facet(_M_codecvt).always_noconv()
+ && __testin && !_M_writing)
+ {
+ // First, copy the chars already present in the buffer.
+ const streamsize __avail = this->egptr() - this->gptr();
+ if (__avail != 0)
+ {
+ if (__avail == 1)
+ *__s = *this->gptr();
+ else
+ traits_type::copy(__s, this->gptr(), __avail);
+ __s += __avail;
+ this->gbump(__avail);
+ __ret += __avail;
+ __n -= __avail;
+ }
+
+ // Need to loop in case of short reads (relatively common
+ // with pipes).
+ streamsize __len;
+ for (;;)
+ {
+ //__len = _M_file.xsgetn(reinterpret_cast<char*>(__s), __n);
+ __len = fread(reinterpret_cast<void*>(__s), 1,
+ __n, _M_file.file());
+ if (__len == -1)
+ __throw_ios_failure(__N("llstdio_filebuf::xsgetn "
+ "error reading the file"));
+ if (__len == 0)
+ break;
+
+ __n -= __len;
+ __ret += __len;
+ if (__n == 0)
+ break;
+
+ __s += __len;
+ }
+
+ if (__n == 0)
+ {
+ _M_set_buffer(0);
+ _M_reading = true;
+ }
+ else if (__len == 0)
+ {
+ // If end of file is reached, set 'uncommitted'
+ // mode, thus allowing an immediate write without
+ // an intervening seek.
+ _M_set_buffer(-1);
+ _M_reading = false;
+ }
+ }
+ else
+ __ret += __streambuf_type::xsgetn(__s, __n);
+
+ return __ret;
+}
+
+std::streamsize llstdio_filebuf::xsputn(char_type* __s, std::streamsize __n)
+{
+ // Optimization in the always_noconv() case, to be generalized in the
+ // future: when __n is sufficiently large we write directly instead of
+ // using the buffer.
+ streamsize __ret = 0;
+ const bool __testout = _M_mode & ios_base::out;
+ if (__check_facet(_M_codecvt).always_noconv()
+ && __testout && !_M_reading)
+ {
+ // Measurement would reveal the best choice.
+ const streamsize __chunk = 1ul << 10;
+ streamsize __bufavail = this->epptr() - this->pptr();
+
+ // Don't mistake 'uncommitted' mode buffered with unbuffered.
+ if (!_M_writing && _M_buf_size > 1)
+ __bufavail = _M_buf_size - 1;
+
+ const streamsize __limit = std::min(__chunk, __bufavail);
+ if (__n >= __limit)
+ {
+ const streamsize __buffill = this->pptr() - this->pbase();
+ const char* __buf = reinterpret_cast<const char*>(this->pbase());
+ //__ret = _M_file.xsputn_2(__buf, __buffill,
+ // reinterpret_cast<const char*>(__s), __n);
+ if (__buffill)
+ {
+ __ret = fwrite(__buf, 1, __buffill, _M_file.file());
+ }
+ if (__ret == __buffill)
{
- close();
+ __ret += fwrite(reinterpret_cast<const char*>(__s), 1,
+ __n, _M_file.file());
+ }
+ if (__ret == __buffill + __n)
+ {
+ _M_set_buffer(0);
+ _M_writing = true;
+}
+ if (__ret > __buffill)
+ __ret -= __buffill;
+ else
+ __ret = 0;
+ }
+ else
+ __ret = __streambuf_type::xsputn(__s, __n);
}
- delete _Filebuffer;
+ else
+ __ret = __streambuf_type::xsputn(__s, __n);
+ return __ret;
}
+int llstdio_filebuf::sync()
+{
+ return (_M_file.sync() == 0 ? 0 : -1);
+}
+#endif
+
+/************** input file stream ********************************/
+
+
+llifstream::llifstream() : _M_filebuf(),
+#if LL_WINDOWS
+ std::istream(&_M_filebuf) {}
+#else
+ std::istream()
+{
+ this->init(&_M_filebuf);
+}
+#endif
+
+// explicit
llifstream::llifstream(const std::string& _Filename,
- ios_base::openmode _Mode,
- int _Prot)
- : std::basic_istream< char , std::char_traits< char > >(NULL,true),_Filebuffer(NULL),_ShouldClose(false)
+ ios_base::openmode _Mode) : _M_filebuf(),
+#if LL_WINDOWS
+ std::istream(&_M_filebuf)
+{
+ llutf16string wideName = utf8str_to_utf16str( _Filename );
+ if (_M_filebuf.open(wideName.c_str(), _Mode | ios_base::in) == 0)
+ {
+ _Myios::setstate(ios_base::failbit);
+ }
+}
+#else
+ std::istream()
+{
+ this->init(&_M_filebuf);
+ this->open(_Filename.c_str(), _Mode | ios_base::in);
+}
+#endif
-{ // construct with named file and specified mode
- open(_Filename, _Mode | ios_base::in, _Prot); /* Flawfinder: ignore */
+// explicit
+llifstream::llifstream(const char* _Filename,
+ ios_base::openmode _Mode) : _M_filebuf(),
+#if LL_WINDOWS
+ std::istream(&_M_filebuf)
+{
+ llutf16string wideName = utf8str_to_utf16str( _Filename );
+ if (_M_filebuf.open(wideName.c_str(), _Mode | ios_base::in) == 0)
+ {
+ _Myios::setstate(ios_base::failbit);
+}
+}
+#else
+ std::istream()
+{
+ this->init(&_M_filebuf);
+ this->open(_Filename, _Mode | ios_base::in);
}
+#endif
-/************** output file stream ********************************/
+// explicit
+llifstream::llifstream(_Filet *_File,
+ ios_base::openmode _Mode, size_t _Size) :
+ _M_filebuf(_File, _Mode, _Size),
+#if LL_WINDOWS
+ std::istream(&_M_filebuf) {}
+#else
+ std::istream()
+{
+ this->init(&_M_filebuf);
+}
+#endif
-bool llofstream::is_open() const
+#if !LL_WINDOWS
+// explicit
+llifstream::llifstream(int __fd,
+ ios_base::openmode _Mode, size_t _Size) :
+ _M_filebuf(__fd, _Mode, _Size),
+ std::istream()
+{
+ this->init(&_M_filebuf);
+}
+#endif
+
+bool llifstream::is_open() const
{ // test if C stream has been opened
- if(_Filebuffer)
- return (_Filebuffer->is_open());
- return false;
+ return _M_filebuf.is_open();
}
-void llofstream::open(const std::string& _Filename, /* Flawfinder: ignore */
- ios_base::openmode _Mode,
- int _Prot)
+void llifstream::open(const char* _Filename, ios_base::openmode _Mode)
{ // open a C stream with specified mode
- LLFILE* filep = LLFile::_Fiopen(_Filename,_Mode | ios_base::out, _Prot);
- if(filep == NULL)
+#if LL_WINDOWS
+ llutf16string wideName = utf8str_to_utf16str( _Filename );
+ if (_M_filebuf.open( wideName.c_str(), _Mode | ios_base::in) == 0)
{
- _Myios::setstate(ios_base::failbit); /*Flawfinder: ignore*/
- return;
+ _Myios::setstate(ios_base::failbit);
}
- llassert(_Filebuffer==NULL);
- _Filebuffer = new _Myfb(filep);
- _ShouldClose = true;
- _Myios::init(_Filebuffer);
+ else
+ {
+ _Myios::clear();
+ }
+#else
+ if (_M_filebuf.open(_Filename, _Mode | ios_base::in) == 0)
+ {
+ this->setstate(ios_base::failbit);
+ }
+ else
+ {
+ this->clear();
+ }
+#endif
}
-void llofstream::close()
+void llifstream::close()
{ // close the C stream
- if(is_open())
+ if (_M_filebuf.close() == 0)
{
- if (_Filebuffer->close() == 0)
- {
- _Myios::setstate(ios_base::failbit); /*Flawfinder: ignore*/
+#if LL_WINDOWS
+ _Myios::setstate(ios_base::failbit);
+#else
+ this->setstate(ios_base::failbit);
+#endif
}
- delete _Filebuffer;
- _Filebuffer = NULL;
- _ShouldClose = false;
}
+
+
+/************** output file stream ********************************/
+
+
+llofstream::llofstream() : _M_filebuf(),
+#if LL_WINDOWS
+ std::ostream(&_M_filebuf) {}
+#else
+ std::ostream()
+{
+ this->init(&_M_filebuf);
}
+#endif
+// explicit
llofstream::llofstream(const std::string& _Filename,
- std::ios_base::openmode _Mode,
- int _Prot)
- : std::basic_ostream<char,std::char_traits < char > >(NULL,true),_Filebuffer(NULL),_ShouldClose(false)
-{ // construct with named file and specified mode
- open(_Filename, _Mode , _Prot); /* Flawfinder: ignore */
+ ios_base::openmode _Mode) : _M_filebuf(),
+#if LL_WINDOWS
+ std::ostream(&_M_filebuf)
+{
+ llutf16string wideName = utf8str_to_utf16str( _Filename );
+ if (_M_filebuf.open( wideName.c_str(), _Mode | ios_base::out) == 0)
+ {
+ _Myios::setstate(ios_base::failbit);
+ }
+}
+#else
+ std::ostream()
+{
+ this->init(&_M_filebuf);
+ this->open(_Filename.c_str(), _Mode | ios_base::out);
+}
+#endif
+
+// explicit
+llofstream::llofstream(const char* _Filename,
+ ios_base::openmode _Mode) : _M_filebuf(),
+#if LL_WINDOWS
+ std::ostream(&_M_filebuf)
+{
+ llutf16string wideName = utf8str_to_utf16str( _Filename );
+ if (_M_filebuf.open( wideName.c_str(), _Mode | ios_base::out) == 0)
+ {
+ _Myios::setstate(ios_base::failbit);
+ }
+}
+#else
+ std::ostream()
+{
+ this->init(&_M_filebuf);
+ this->open(_Filename, _Mode | ios_base::out);
+}
+#endif
+
+// explicit
+llofstream::llofstream(_Filet *_File,
+ ios_base::openmode _Mode, size_t _Size) :
+ _M_filebuf(_File, _Mode, _Size),
+#if LL_WINDOWS
+ std::ostream(&_M_filebuf) {}
+#else
+ std::ostream()
+{
+ this->init(&_M_filebuf);
+}
+#endif
+
+#if !LL_WINDOWS
+// explicit
+llofstream::llofstream(int __fd,
+ ios_base::openmode _Mode, size_t _Size) :
+ _M_filebuf(__fd, _Mode, _Size),
+ std::ostream()
+{
+ this->init(&_M_filebuf);
+}
+#endif
+
+bool llofstream::is_open() const
+{ // test if C stream has been opened
+ return _M_filebuf.is_open();
}
-llofstream::~llofstream()
-{
- // destroy the object
- if (_ShouldClose)
+void llofstream::open(const char* _Filename, ios_base::openmode _Mode)
+{ // open a C stream with specified mode
+#if LL_WINDOWS
+ llutf16string wideName = utf8str_to_utf16str( _Filename );
+ if (_M_filebuf.open( wideName.c_str(), _Mode | ios_base::out) == 0)
+{
+ _Myios::setstate(ios_base::failbit);
+ }
+ else
+ {
+ _Myios::clear();
+ }
+#else
+ if (_M_filebuf.open(_Filename, _Mode | ios_base::out) == 0)
{
- close();
+ this->setstate(ios_base::failbit);
}
- delete _Filebuffer;
+ else
+ {
+ this->clear();
+ }
+#endif
}
-#endif // #if USE_LLFILESTREAMS
+void llofstream::close()
+{ // close the C stream
+ if (_M_filebuf.close() == 0)
+ {
+#if LL_WINDOWS
+ _Myios::setstate(ios_base::failbit);
+#else
+ this->setstate(ios_base::failbit);
+#endif
+ }
+}
/************** helper functions ********************************/
diff --git a/indra/llcommon/llfile.h b/indra/llcommon/llfile.h
index dd7d36513a..d59e68367e 100644..100755
--- a/indra/llcommon/llfile.h
+++ b/indra/llcommon/llfile.h
@@ -38,13 +38,6 @@
typedef FILE LLFILE;
#include <fstream>
-
-#ifdef LL_WINDOWS
-#define USE_LLFILESTREAMS 1
-#else
-#define USE_LLFILESTREAMS 0
-#endif
-
#include <sys/stat.h>
#if LL_WINDOWS
@@ -52,6 +45,8 @@ typedef FILE LLFILE;
typedef struct _stat llstat;
#else
typedef struct stat llstat;
+#include <ext/stdio_filebuf.h>
+#include <bits/postypes.h>
#endif
#ifndef S_ISREG
@@ -83,142 +78,342 @@ public:
static int stat(const std::string& filename,llstat* file_status);
static bool isdir(const std::string& filename);
static bool isfile(const std::string& filename);
- static LLFILE * _Fiopen(const std::string& filename, std::ios::openmode mode,int); // protection currently unused
+ static LLFILE * _Fiopen(const std::string& filename,
+ std::ios::openmode mode);
static const char * tmpdir();
};
+/**
+ * @brief Provides a layer of compatibility for C/POSIX.
+ *
+ * This is taken from both the GNU __gnu_cxx::stdio_filebuf extension and
+ * VC's basic_filebuf implementation.
+ * This file buffer provides extensions for working with standard C FILE*'s
+ * and POSIX file descriptors for platforms that support this.
+*/
+namespace
+{
+#if LL_WINDOWS
+typedef std::filebuf _Myfb;
+#else
+typedef __gnu_cxx::stdio_filebuf< char > _Myfb;
+typedef std::__c_file _Filet;
+#endif /* LL_WINDOWS */
+}
-#if USE_LLFILESTREAMS
-
-class LL_COMMON_API llifstream : public std::basic_istream < char , std::char_traits < char > >
+class LL_COMMON_API llstdio_filebuf : public _Myfb
{
- // input stream associated with a C stream
public:
- typedef std::basic_ifstream<char,std::char_traits < char > > _Myt;
- typedef std::basic_filebuf<char,std::char_traits< char > > _Myfb;
- typedef std::basic_ios<char,std::char_traits< char > > _Myios;
-
- llifstream()
- : std::basic_istream<char,std::char_traits< char > >(NULL,true),_Filebuffer(NULL),_ShouldClose(false)
- { // construct unopened
- }
+ /**
+ * deferred initialization / destruction
+ */
+ llstdio_filebuf() : _Myfb() {}
+ virtual ~llstdio_filebuf() {}
+
+ /**
+ * @param f An open @c FILE*.
+ * @param mode Same meaning as in a standard filebuf.
+ * @param size Optimal or preferred size of internal buffer, in chars.
+ * Defaults to system's @c BUFSIZ.
+ *
+ * This constructor associates a file stream buffer with an open
+ * C @c FILE*. The @c FILE* will not be automatically closed when the
+ * stdio_filebuf is closed/destroyed.
+ */
+ llstdio_filebuf(_Filet* __f, std::ios_base::openmode __mode,
+ //size_t __size = static_cast<size_t>(BUFSIZ)) :
+ size_t __size = static_cast<size_t>(1)) :
+#if LL_WINDOWS
+ _Myfb(__f) {}
+#else
+ _Myfb(__f, __mode, __size) {}
+#endif
- explicit llifstream(const std::string& _Filename,
- ios_base::openmode _Mode = ios_base::in,
- int _Prot = (int)ios_base::_Openprot);
-
- explicit llifstream(_Filet *_File)
- : std::basic_istream<char,std::char_traits< char > >(NULL,true),
- _Filebuffer(new _Myfb(_File)),
- _ShouldClose(false)
- { // construct with specified C stream
- }
- virtual ~llifstream();
-
- _Myfb *rdbuf() const
- { // return pointer to file buffer
- return _Filebuffer;
- }
- bool is_open() const;
- void open(const std::string& _Filename, /* Flawfinder: ignore */
- ios_base::openmode _Mode = ios_base::in,
- int _Prot = (int)ios_base::_Openprot);
- void close();
+ /**
+ * @brief Opens an external file.
+ * @param s The name of the file.
+ * @param mode The open mode flags.
+ * @return @c this on success, NULL on failure
+ *
+ * If a file is already open, this function immediately fails.
+ * Otherwise it tries to open the file named @a s using the flags
+ * given in @a mode.
+ */
+ //llstdio_filebuf* open(const char *_Filename,
+ // std::ios_base::openmode _Mode);
+
+ /**
+ * @param fd An open file descriptor.
+ * @param mode Same meaning as in a standard filebuf.
+ * @param size Optimal or preferred size of internal buffer, in chars.
+ *
+ * This constructor associates a file stream buffer with an open
+ * POSIX file descriptor. The file descriptor will be automatically
+ * closed when the stdio_filebuf is closed/destroyed.
+ */
+#if !LL_WINDOWS
+ llstdio_filebuf(int __fd, std::ios_base::openmode __mode,
+ //size_t __size = static_cast<size_t>(BUFSIZ)) :
+ size_t __size = static_cast<size_t>(1)) :
+ _Myfb(__fd, __mode, __size) {}
+#endif
-private:
- _Myfb* _Filebuffer; // the file buffer
- bool _ShouldClose;
+// *TODO: Seek the underlying c stream for better cross-platform compatibility?
+#if !LL_WINDOWS
+protected:
+ /** underflow() and uflow() functions are called to get the next
+ * character from the real input source when the buffer is empty.
+ * Buffered input uses underflow()
+ */
+ /*virtual*/ int_type underflow();
+
+ /* Convert internal byte sequence to external, char-based
+ * sequence via codecvt.
+ */
+ bool _convert_to_external(char_type*, std::streamsize);
+
+ /** The overflow() function is called to transfer characters to the
+ * real output destination when the buffer is full. A call to
+ * overflow(c) outputs the contents of the buffer plus the
+ * character c.
+ * Consume some sequence of the characters in the pending sequence.
+ */
+ /*virtual*/ int_type overflow(int_type __c = traits_type::eof());
+
+ /** sync() flushes the underlying @c FILE* stream.
+ */
+ /*virtual*/ int sync();
+
+ std::streamsize xsgetn(char_type*, std::streamsize);
+ std::streamsize xsputn(char_type*, std::streamsize);
+#endif
};
-class LL_COMMON_API llofstream : public std::basic_ostream< char , std::char_traits < char > >
+/**
+ * @brief Controlling input for files.
+ *
+ * This class supports reading from named files, using the inherited
+ * functions from std::basic_istream. To control the associated
+ * sequence, an instance of std::basic_filebuf (or a platform-specific derivative)
+ * which allows construction using a pre-exisintg file stream buffer.
+ * We refer to this std::basic_filebuf (or derivative) as @c sb.
+*/
+class LL_COMMON_API llifstream : public std::istream
{
+ // input stream associated with a C stream
public:
- typedef std::basic_ostream< char , std::char_traits < char > > _Myt;
- typedef std::basic_filebuf< char , std::char_traits < char > > _Myfb;
- typedef std::basic_ios<char,std::char_traits < char > > _Myios;
-
- llofstream()
- : std::basic_ostream<char,std::char_traits < char > >(NULL,true),_Filebuffer(NULL),_ShouldClose(false)
- { // construct unopened
- }
-
- explicit llofstream(const std::string& _Filename,
- std::ios_base::openmode _Mode = ios_base::out,
- int _Prot = (int)std::ios_base::_Openprot);
+ // Constructors:
+ /**
+ * @brief Default constructor.
+ *
+ * Initializes @c sb using its default constructor, and passes
+ * @c &sb to the base class initializer. Does not open any files
+ * (you haven't given it a filename to open).
+ */
+ llifstream();
+
+ /**
+ * @brief Create an input file stream.
+ * @param Filename String specifying the filename.
+ * @param Mode Open file in specified mode (see std::ios_base).
+ *
+ * @c ios_base::in is automatically included in @a mode.
+ */
+ explicit llifstream(const std::string& _Filename,
+ ios_base::openmode _Mode = ios_base::in);
+ explicit llifstream(const char* _Filename,
+ ios_base::openmode _Mode = ios_base::in);
+
+ /**
+ * @brief Create a stream using an open c file stream.
+ * @param File An open @c FILE*.
+ @param Mode Same meaning as in a standard filebuf.
+ @param Size Optimal or preferred size of internal buffer, in chars.
+ Defaults to system's @c BUFSIZ.
+ */
+ explicit llifstream(_Filet *_File,
+ ios_base::openmode _Mode = ios_base::in,
+ //size_t _Size = static_cast<size_t>(BUFSIZ));
+ size_t _Size = static_cast<size_t>(1));
+ /**
+ * @brief Create a stream using an open file descriptor.
+ * @param fd An open file descriptor.
+ @param Mode Same meaning as in a standard filebuf.
+ @param Size Optimal or preferred size of internal buffer, in chars.
+ Defaults to system's @c BUFSIZ.
+ */
+#if !LL_WINDOWS
+ explicit llifstream(int __fd,
+ ios_base::openmode _Mode = ios_base::in,
+ //size_t _Size = static_cast<size_t>(BUFSIZ));
+ size_t _Size = static_cast<size_t>(1));
+#endif
- explicit llofstream(_Filet *_File)
- : std::basic_ostream<char,std::char_traits < char > >(NULL,true),
- _Filebuffer(new _Myfb(_File)),//_File)
- _ShouldClose(false)
- { // construct with specified C stream
- }
-
- virtual ~llofstream();
-
- _Myfb *rdbuf() const
- { // return pointer to file buffer
- return _Filebuffer;
- }
-
+ /**
+ * @brief The destructor does nothing.
+ *
+ * The file is closed by the filebuf object, not the formatting
+ * stream.
+ */
+ virtual ~llifstream() {}
+
+ // Members:
+ /**
+ * @brief Accessing the underlying buffer.
+ * @return The current basic_filebuf buffer.
+ *
+ * This hides both signatures of std::basic_ios::rdbuf().
+ */
+ llstdio_filebuf* rdbuf() const
+ { return const_cast<llstdio_filebuf*>(&_M_filebuf); }
+
+ /**
+ * @brief Wrapper to test for an open file.
+ * @return @c rdbuf()->is_open()
+ */
bool is_open() const;
- void open(const std::string& _Filename,ios_base::openmode _Mode = ios_base::out,int _Prot = (int)ios_base::_Openprot); /* Flawfinder: ignore */
-
+ /**
+ * @brief Opens an external file.
+ * @param Filename The name of the file.
+ * @param Node The open mode flags.
+ *
+ * Calls @c llstdio_filebuf::open(s,mode|in). If that function
+ * fails, @c failbit is set in the stream's error state.
+ */
+ void open(const std::string& _Filename,
+ ios_base::openmode _Mode = ios_base::in)
+ { open(_Filename.c_str(), _Mode); }
+ void open(const char* _Filename,
+ ios_base::openmode _Mode = ios_base::in);
+
+ /**
+ * @brief Close the file.
+ *
+ * Calls @c llstdio_filebuf::close(). If that function
+ * fails, @c failbit is set in the stream's error state.
+ */
void close();
private:
- _Myfb *_Filebuffer; // the file buffer
- bool _ShouldClose;
-};
-
-
-
-#else
-//Use standard file streams on non windows platforms
-//#define llifstream std::ifstream
-//#define llofstream std::ofstream
-
-class LL_COMMON_API llifstream : public std::ifstream
-{
-public:
- llifstream() : std::ifstream()
- {
- }
-
- explicit llifstream(const std::string& _Filename, std::_Ios_Openmode _Mode = in)
- : std::ifstream(_Filename.c_str(), _Mode)
- {
- }
- void open(const std::string& _Filename, std::_Ios_Openmode _Mode = in) /* Flawfinder: ignore */
- {
- std::ifstream::open(_Filename.c_str(), _Mode);
- }
+ llstdio_filebuf _M_filebuf;
};
-class LL_COMMON_API llofstream : public std::ofstream
+/**
+ * @brief Controlling output for files.
+ *
+ * This class supports writing to named files, using the inherited
+ * functions from std::basic_ostream. To control the associated
+ * sequence, an instance of std::basic_filebuf (or a platform-specific derivative)
+ * which allows construction using a pre-exisintg file stream buffer.
+ * We refer to this std::basic_filebuf (or derivative) as @c sb.
+*/
+class LL_COMMON_API llofstream : public std::ostream
{
public:
- llofstream() : std::ofstream()
- {
- }
+ // Constructors:
+ /**
+ * @brief Default constructor.
+ *
+ * Initializes @c sb using its default constructor, and passes
+ * @c &sb to the base class initializer. Does not open any files
+ * (you haven't given it a filename to open).
+ */
+ llofstream();
+
+ /**
+ * @brief Create an output file stream.
+ * @param Filename String specifying the filename.
+ * @param Mode Open file in specified mode (see std::ios_base).
+ *
+ * @c ios_base::out|ios_base::trunc is automatically included in
+ * @a mode.
+ */
+ explicit llofstream(const std::string& _Filename,
+ ios_base::openmode _Mode = ios_base::out|ios_base::trunc);
+ explicit llofstream(const char* _Filename,
+ ios_base::openmode _Mode = ios_base::out|ios_base::trunc);
+
+ /**
+ * @brief Create a stream using an open c file stream.
+ * @param File An open @c FILE*.
+ @param Mode Same meaning as in a standard filebuf.
+ @param Size Optimal or preferred size of internal buffer, in chars.
+ Defaults to system's @c BUFSIZ.
+ */
+ explicit llofstream(_Filet *_File,
+ ios_base::openmode _Mode = ios_base::out,
+ //size_t _Size = static_cast<size_t>(BUFSIZ));
+ size_t _Size = static_cast<size_t>(1));
+
+ /**
+ * @brief Create a stream using an open file descriptor.
+ * @param fd An open file descriptor.
+ @param Mode Same meaning as in a standard filebuf.
+ @param Size Optimal or preferred size of internal buffer, in chars.
+ Defaults to system's @c BUFSIZ.
+ */
+#if !LL_WINDOWS
+ explicit llofstream(int __fd,
+ ios_base::openmode _Mode = ios_base::out,
+ //size_t _Size = static_cast<size_t>(BUFSIZ));
+ size_t _Size = static_cast<size_t>(1));
+#endif
- explicit llofstream(const std::string& _Filename, std::_Ios_Openmode _Mode = out)
- : std::ofstream(_Filename.c_str(), _Mode)
- {
- }
+ /**
+ * @brief The destructor does nothing.
+ *
+ * The file is closed by the filebuf object, not the formatting
+ * stream.
+ */
+ virtual ~llofstream() {}
+
+ // Members:
+ /**
+ * @brief Accessing the underlying buffer.
+ * @return The current basic_filebuf buffer.
+ *
+ * This hides both signatures of std::basic_ios::rdbuf().
+ */
+ llstdio_filebuf* rdbuf() const
+ { return const_cast<llstdio_filebuf*>(&_M_filebuf); }
+
+ /**
+ * @brief Wrapper to test for an open file.
+ * @return @c rdbuf()->is_open()
+ */
+ bool is_open() const;
- void open(const std::string& _Filename, std::_Ios_Openmode _Mode = out) /* Flawfinder: ignore */
- {
- std::ofstream::open(_Filename.c_str(), _Mode);
- }
+ /**
+ * @brief Opens an external file.
+ * @param Filename The name of the file.
+ * @param Node The open mode flags.
+ *
+ * Calls @c llstdio_filebuf::open(s,mode|out). If that function
+ * fails, @c failbit is set in the stream's error state.
+ */
+ void open(const std::string& _Filename,
+ ios_base::openmode _Mode = ios_base::out|ios_base::trunc)
+ { open(_Filename.c_str(), _Mode); }
+ void open(const char* _Filename,
+ ios_base::openmode _Mode = ios_base::out|ios_base::trunc);
+
+ /**
+ * @brief Close the file.
+ *
+ * Calls @c llstdio_filebuf::close(). If that function
+ * fails, @c failbit is set in the stream's error state.
+ */
+ void close();
+private:
+ llstdio_filebuf _M_filebuf;
};
-#endif
/**
* @breif filesize helpers.
diff --git a/indra/llcommon/llfindlocale.cpp b/indra/llcommon/llfindlocale.cpp
index cd7c0c7c09..cd7c0c7c09 100644..100755
--- a/indra/llcommon/llfindlocale.cpp
+++ b/indra/llcommon/llfindlocale.cpp
diff --git a/indra/llcommon/llfindlocale.h b/indra/llcommon/llfindlocale.h
index 6770db5774..6770db5774 100644..100755
--- a/indra/llcommon/llfindlocale.h
+++ b/indra/llcommon/llfindlocale.h
diff --git a/indra/llcommon/llfixedbuffer.cpp b/indra/llcommon/llfixedbuffer.cpp
index d394f179fb..d394f179fb 100644..100755
--- a/indra/llcommon/llfixedbuffer.cpp
+++ b/indra/llcommon/llfixedbuffer.cpp
diff --git a/indra/llcommon/llfixedbuffer.h b/indra/llcommon/llfixedbuffer.h
index 554cf48a4c..554cf48a4c 100644..100755
--- a/indra/llcommon/llfixedbuffer.h
+++ b/indra/llcommon/llfixedbuffer.h
diff --git a/indra/llcommon/llfoldertype.cpp b/indra/llcommon/llfoldertype.cpp
index f6d0f5bce8..f6d0f5bce8 100644..100755
--- a/indra/llcommon/llfoldertype.cpp
+++ b/indra/llcommon/llfoldertype.cpp
diff --git a/indra/llcommon/llformat.cpp b/indra/llcommon/llformat.cpp
index 3b2b3038ea..3b2b3038ea 100644..100755
--- a/indra/llcommon/llformat.cpp
+++ b/indra/llcommon/llformat.cpp
diff --git a/indra/llcommon/llformat.h b/indra/llcommon/llformat.h
index a4ec5e01de..a4ec5e01de 100644..100755
--- a/indra/llcommon/llformat.h
+++ b/indra/llcommon/llformat.h
diff --git a/indra/llcommon/llframetimer.cpp b/indra/llcommon/llframetimer.cpp
index ec64195b21..ec64195b21 100644..100755
--- a/indra/llcommon/llframetimer.cpp
+++ b/indra/llcommon/llframetimer.cpp
diff --git a/indra/llcommon/llframetimer.h b/indra/llcommon/llframetimer.h
index 45754f3785..45754f3785 100644..100755
--- a/indra/llcommon/llframetimer.h
+++ b/indra/llcommon/llframetimer.h
diff --git a/indra/llcommon/llhandle.h b/indra/llcommon/llhandle.h
new file mode 100755
index 0000000000..401e4d759a
--- /dev/null
+++ b/indra/llcommon/llhandle.h
@@ -0,0 +1,216 @@
+/**
+* @file llhandle.h
+* @brief "Handle" to an object (usually a floater) whose lifetime you don't
+* control.
+*
+* $LicenseInfo:firstyear=2001&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$
+*/
+#ifndef LLHANDLE_H
+#define LLHANDLE_H
+
+#include "llpointer.h"
+#include <boost/type_traits/is_convertible.hpp>
+#include <boost/utility/enable_if.hpp>
+
+/**
+ * Helper object for LLHandle. Don't instantiate these directly, used
+ * exclusively by LLHandle.
+ */
+class LLTombStone : public LLRefCount
+{
+public:
+ LLTombStone(void* target = NULL) : mTarget(target) {}
+
+ void setTarget(void* target) { mTarget = target; }
+ void* getTarget() const { return mTarget; }
+private:
+ mutable void* mTarget;
+};
+
+/**
+ * LLHandles are used to refer to objects whose lifetime you do not control or influence.
+ * Calling get() on a handle will return a pointer to the referenced object or NULL,
+ * if the object no longer exists. Note that during the lifetime of the returned pointer,
+ * you are assuming that the object will not be deleted by any action you perform,
+ * or any other thread, as normal when using pointers, so avoid using that pointer outside of
+ * the local code block.
+ *
+ * https://wiki.lindenlab.com/mediawiki/index.php?title=LLHandle&oldid=79669
+ *
+ * The implementation is like some "weak pointer" implementations. When we
+ * can't control the lifespan of the referenced object of interest, we can
+ * still instantiate a proxy object whose lifespan we DO control, and store in
+ * the proxy object a dumb pointer to the actual target. Then we just have to
+ * ensure that on destruction of the target object, the proxy's dumb pointer
+ * is set NULL.
+ *
+ * LLTombStone is our proxy object. LLHandle contains an LLPointer to the
+ * LLTombStone, so every copy of an LLHandle increments the LLTombStone's ref
+ * count as usual.
+ *
+ * One copy of the LLHandle, specifically the LLRootHandle, must be stored in
+ * the referenced object. Destroying the LLRootHandle is what NULLs the
+ * proxy's target pointer.
+ *
+ * Minor optimization: we want LLHandle's mTombStone to always be a valid
+ * LLPointer, saving some conditionals in dereferencing. That's the
+ * getDefaultTombStone() mechanism. The default LLTombStone object's target
+ * pointer is always NULL, so it's semantically identical to allowing
+ * mTombStone to be invalid.
+ */
+template <typename T>
+class LLHandle
+{
+ template <typename U> friend class LLHandle;
+ template <typename U> friend class LLHandleProvider;
+public:
+ LLHandle() : mTombStone(getDefaultTombStone()) {}
+
+ template<typename U>
+ LLHandle(const LLHandle<U>& other, typename boost::enable_if< typename boost::is_convertible<U*, T*> >::type* dummy = 0)
+ : mTombStone(other.mTombStone)
+ {}
+
+ bool isDead() const
+ {
+ return mTombStone->getTarget() == NULL;
+ }
+
+ void markDead()
+ {
+ mTombStone = getDefaultTombStone();
+ }
+
+ T* get() const
+ {
+ return reinterpret_cast<T*>(mTombStone->getTarget());
+ }
+
+ friend bool operator== (const LLHandle<T>& lhs, const LLHandle<T>& rhs)
+ {
+ return lhs.mTombStone == rhs.mTombStone;
+ }
+ friend bool operator!= (const LLHandle<T>& lhs, const LLHandle<T>& rhs)
+ {
+ return !(lhs == rhs);
+ }
+ friend bool operator< (const LLHandle<T>& lhs, const LLHandle<T>& rhs)
+ {
+ return lhs.mTombStone < rhs.mTombStone;
+ }
+ friend bool operator> (const LLHandle<T>& lhs, const LLHandle<T>& rhs)
+ {
+ return lhs.mTombStone > rhs.mTombStone;
+ }
+
+protected:
+ LLPointer<LLTombStone> mTombStone;
+
+private:
+ typedef T* pointer_t;
+ static LLPointer<LLTombStone>& getDefaultTombStone()
+ {
+ static LLPointer<LLTombStone> sDefaultTombStone = new LLTombStone;
+ return sDefaultTombStone;
+ }
+};
+
+/**
+ * LLRootHandle isa LLHandle which must be stored in the referenced object.
+ * You can either store it directly and explicitly bind(this), or derive from
+ * LLHandleProvider (q.v.) which automates that for you. The essential point
+ * is that destroying the LLRootHandle (as a consequence of destroying the
+ * referenced object) calls unbind(), setting the LLTombStone's target pointer
+ * NULL.
+ */
+template <typename T>
+class LLRootHandle : public LLHandle<T>
+{
+public:
+ typedef LLRootHandle<T> self_t;
+ typedef LLHandle<T> base_t;
+
+ LLRootHandle(T* object) { bind(object); }
+ LLRootHandle() {};
+ ~LLRootHandle() { unbind(); }
+
+ // this is redundant, since an LLRootHandle *is* an LLHandle
+ //LLHandle<T> getHandle() { return LLHandle<T>(*this); }
+
+ void bind(T* object)
+ {
+ // unbind existing tombstone
+ if (LLHandle<T>::mTombStone.notNull())
+ {
+ if (LLHandle<T>::mTombStone->getTarget() == (void*)object) return;
+ LLHandle<T>::mTombStone->setTarget(NULL);
+ }
+ // tombstone reference counted, so no paired delete
+ LLHandle<T>::mTombStone = new LLTombStone((void*)object);
+ }
+
+ void unbind()
+ {
+ LLHandle<T>::mTombStone->setTarget(NULL);
+ }
+
+ //don't allow copying of root handles, since there should only be one
+private:
+ LLRootHandle(const LLRootHandle& other) {};
+};
+
+/**
+ * Use this as a mixin for simple classes that need handles and when you don't
+ * want handles at multiple points of the inheritance hierarchy
+ */
+template <typename T>
+class LLHandleProvider
+{
+public:
+ LLHandle<T> getHandle() const
+ {
+ // perform lazy binding to avoid small tombstone allocations for handle
+ // providers whose handles are never referenced
+ mHandle.bind(static_cast<T*>(const_cast<LLHandleProvider<T>* >(this)));
+ return mHandle;
+ }
+
+ template <typename U>
+ LLHandle<U> getDerivedHandle(typename boost::enable_if< typename boost::is_convertible<U*, T*> >::type* dummy = 0) const
+ {
+ LLHandle<U> downcast_handle;
+ downcast_handle.mTombStone = getHandle().mTombStone;
+ return downcast_handle;
+ }
+
+protected:
+ typedef LLHandle<T> handle_type_t;
+ LLHandleProvider()
+ {
+ // provided here to enforce T deriving from LLHandleProvider<T>
+ }
+
+private:
+ mutable LLRootHandle<T> mHandle;
+};
+
+#endif
diff --git a/indra/llcommon/llhash.h b/indra/llcommon/llhash.h
index c077ebe93f..c077ebe93f 100644..100755
--- a/indra/llcommon/llhash.h
+++ b/indra/llcommon/llhash.h
diff --git a/indra/llcommon/llheartbeat.cpp b/indra/llcommon/llheartbeat.cpp
index 18a0c489bd..18a0c489bd 100644..100755
--- a/indra/llcommon/llheartbeat.cpp
+++ b/indra/llcommon/llheartbeat.cpp
diff --git a/indra/llcommon/llheartbeat.h b/indra/llcommon/llheartbeat.h
index 4a75fcc103..4a75fcc103 100644..100755
--- a/indra/llcommon/llheartbeat.h
+++ b/indra/llcommon/llheartbeat.h
diff --git a/indra/llcommon/llhttpstatuscodes.h b/indra/llcommon/llhttpstatuscodes.h
index 0173461dad..0173461dad 100644..100755
--- a/indra/llcommon/llhttpstatuscodes.h
+++ b/indra/llcommon/llhttpstatuscodes.h
diff --git a/indra/llcommon/llindexedqueue.h b/indra/llcommon/llindexedqueue.h
index aa2675d87d..aa2675d87d 100644..100755
--- a/indra/llcommon/llindexedqueue.h
+++ b/indra/llcommon/llindexedqueue.h
diff --git a/indra/llcommon/llinitparam.cpp b/indra/llcommon/llinitparam.cpp
new file mode 100755
index 0000000000..89c831d296
--- /dev/null
+++ b/indra/llcommon/llinitparam.cpp
@@ -0,0 +1,463 @@
+/**
+ * @file llinitparam.cpp
+ * @brief parameter block abstraction for creating complex objects and
+ * parsing construction parameters from xml and LLSD
+ *
+ * $LicenseInfo:firstyear=2008&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 "llinitparam.h"
+
+
+namespace LLInitParam
+{
+ //
+ // Param
+ //
+ Param::Param(BaseBlock* enclosing_block)
+ : mIsProvided(false)
+ {
+ const U8* my_addr = reinterpret_cast<const U8*>(this);
+ const U8* block_addr = reinterpret_cast<const U8*>(enclosing_block);
+ U32 enclosing_block_offset = 0x7FFFffff & (U32)(my_addr - block_addr);
+ mEnclosingBlockOffsetLow = enclosing_block_offset & 0x0000ffff;
+ mEnclosingBlockOffsetHigh = (enclosing_block_offset & 0x007f0000) >> 16;
+ }
+
+ //
+ // ParamDescriptor
+ //
+ ParamDescriptor::ParamDescriptor(param_handle_t p,
+ merge_func_t merge_func,
+ deserialize_func_t deserialize_func,
+ serialize_func_t serialize_func,
+ validation_func_t validation_func,
+ inspect_func_t inspect_func,
+ S32 min_count,
+ S32 max_count)
+ : mParamHandle(p),
+ mMergeFunc(merge_func),
+ mDeserializeFunc(deserialize_func),
+ mSerializeFunc(serialize_func),
+ mValidationFunc(validation_func),
+ mInspectFunc(inspect_func),
+ mMinCount(min_count),
+ mMaxCount(max_count),
+ mUserData(NULL)
+ {}
+
+ ParamDescriptor::ParamDescriptor()
+ : mParamHandle(0),
+ mMergeFunc(NULL),
+ mDeserializeFunc(NULL),
+ mSerializeFunc(NULL),
+ mValidationFunc(NULL),
+ mInspectFunc(NULL),
+ mMinCount(0),
+ mMaxCount(0),
+ mUserData(NULL)
+ {}
+
+ ParamDescriptor::~ParamDescriptor()
+ {
+ delete mUserData;
+ }
+
+ //
+ // Parser
+ //
+ Parser::~Parser()
+ {}
+
+ void Parser::parserWarning(const std::string& message)
+ {
+ if (mParseSilently) return;
+ llwarns << message << llendl;
+ }
+
+ void Parser::parserError(const std::string& message)
+ {
+ if (mParseSilently) return;
+ llerrs << message << llendl;
+ }
+
+
+ //
+ // BlockDescriptor
+ //
+ void BlockDescriptor::aggregateBlockData(BlockDescriptor& src_block_data)
+ {
+ mNamedParams.insert(src_block_data.mNamedParams.begin(), src_block_data.mNamedParams.end());
+ std::copy(src_block_data.mUnnamedParams.begin(), src_block_data.mUnnamedParams.end(), std::back_inserter(mUnnamedParams));
+ std::copy(src_block_data.mValidationList.begin(), src_block_data.mValidationList.end(), std::back_inserter(mValidationList));
+ std::copy(src_block_data.mAllParams.begin(), src_block_data.mAllParams.end(), std::back_inserter(mAllParams));
+ }
+
+ void BlockDescriptor::addParam(const ParamDescriptorPtr in_param, const char* char_name)
+ {
+ // create a copy of the param descriptor in mAllParams
+ // so other data structures can store a pointer to it
+ mAllParams.push_back(in_param);
+ ParamDescriptorPtr param(mAllParams.back());
+
+ std::string name(char_name);
+ if ((size_t)param->mParamHandle > mMaxParamOffset)
+ {
+ llerrs << "Attempted to register param with block defined for parent class, make sure to derive from LLInitParam::Block<YOUR_CLASS, PARAM_BLOCK_BASE_CLASS>" << llendl;
+ }
+
+ if (name.empty())
+ {
+ mUnnamedParams.push_back(param);
+ }
+ else
+ {
+ // don't use insert, since we want to overwrite existing entries
+ mNamedParams[name] = param;
+ }
+
+ if (param->mValidationFunc)
+ {
+ mValidationList.push_back(std::make_pair(param->mParamHandle, param->mValidationFunc));
+ }
+ }
+
+ BlockDescriptor::BlockDescriptor()
+ : mMaxParamOffset(0),
+ mInitializationState(UNINITIALIZED),
+ mCurrentBlockPtr(NULL)
+ {}
+
+ // called by each derived class in least to most derived order
+ void BaseBlock::init(BlockDescriptor& descriptor, BlockDescriptor& base_descriptor, size_t block_size)
+ {
+ descriptor.mCurrentBlockPtr = this;
+ descriptor.mMaxParamOffset = block_size;
+
+ switch(descriptor.mInitializationState)
+ {
+ case BlockDescriptor::UNINITIALIZED:
+ // copy params from base class here
+ descriptor.aggregateBlockData(base_descriptor);
+
+ descriptor.mInitializationState = BlockDescriptor::INITIALIZING;
+ break;
+ case BlockDescriptor::INITIALIZING:
+ descriptor.mInitializationState = BlockDescriptor::INITIALIZED;
+ break;
+ case BlockDescriptor::INITIALIZED:
+ // nothing to do
+ break;
+ }
+ }
+
+ param_handle_t BaseBlock::getHandleFromParam(const Param* param) const
+ {
+ const U8* param_address = reinterpret_cast<const U8*>(param);
+ const U8* baseblock_address = reinterpret_cast<const U8*>(this);
+ return (param_address - baseblock_address);
+ }
+
+ bool BaseBlock::submitValue(Parser::name_stack_t& name_stack, Parser& p, bool silent)
+ {
+ Parser::name_stack_range_t range = std::make_pair(name_stack.begin(), name_stack.end());
+ if (!deserializeBlock(p, range, true))
+ {
+ if (!silent)
+ {
+ p.parserWarning(llformat("Failed to parse parameter \"%s\"", p.getCurrentElementName().c_str()));
+ }
+ return false;
+ }
+ return true;
+ }
+
+
+ bool BaseBlock::validateBlock(bool emit_errors) const
+ {
+ const BlockDescriptor& block_data = mostDerivedBlockDescriptor();
+ for (BlockDescriptor::param_validation_list_t::const_iterator it = block_data.mValidationList.begin(); it != block_data.mValidationList.end(); ++it)
+ {
+ const Param* param = getParamFromHandle(it->first);
+ if (!it->second(param))
+ {
+ if (emit_errors)
+ {
+ llwarns << "Invalid param \"" << getParamName(block_data, param) << "\"" << llendl;
+ }
+ return false;
+ }
+ }
+ return true;
+ }
+
+ void BaseBlock::serializeBlock(Parser& parser, Parser::name_stack_t& name_stack, const LLInitParam::BaseBlock* diff_block) const
+ {
+ // named param is one like LLView::Params::follows
+ // unnamed param is like LLView::Params::rect - implicit
+ const BlockDescriptor& block_data = mostDerivedBlockDescriptor();
+
+ for (BlockDescriptor::param_list_t::const_iterator it = block_data.mUnnamedParams.begin();
+ it != block_data.mUnnamedParams.end();
+ ++it)
+ {
+ param_handle_t param_handle = (*it)->mParamHandle;
+ const Param* param = getParamFromHandle(param_handle);
+ ParamDescriptor::serialize_func_t serialize_func = (*it)->mSerializeFunc;
+ if (serialize_func)
+ {
+ const Param* diff_param = diff_block ? diff_block->getParamFromHandle(param_handle) : NULL;
+ serialize_func(*param, parser, name_stack, diff_param);
+ }
+ }
+
+ for(BlockDescriptor::param_map_t::const_iterator it = block_data.mNamedParams.begin();
+ it != block_data.mNamedParams.end();
+ ++it)
+ {
+ param_handle_t param_handle = it->second->mParamHandle;
+ const Param* param = getParamFromHandle(param_handle);
+ ParamDescriptor::serialize_func_t serialize_func = it->second->mSerializeFunc;
+ if (serialize_func && param->anyProvided())
+ {
+ // Ensure this param has not already been serialized
+ // Prevents <rect> from being serialized as its own tag.
+ bool duplicate = false;
+ for (BlockDescriptor::param_list_t::const_iterator it2 = block_data.mUnnamedParams.begin();
+ it2 != block_data.mUnnamedParams.end();
+ ++it2)
+ {
+ if (param_handle == (*it2)->mParamHandle)
+ {
+ duplicate = true;
+ break;
+ }
+ }
+
+ //FIXME: for now, don't attempt to serialize values under synonyms, as current parsers
+ // don't know how to detect them
+ if (duplicate)
+ {
+ continue;
+ }
+
+ name_stack.push_back(std::make_pair(it->first, !duplicate));
+ const Param* diff_param = diff_block ? diff_block->getParamFromHandle(param_handle) : NULL;
+ serialize_func(*param, parser, name_stack, diff_param);
+ name_stack.pop_back();
+ }
+ }
+ }
+
+ bool BaseBlock::inspectBlock(Parser& parser, Parser::name_stack_t name_stack, S32 min_count, S32 max_count) const
+ {
+ // named param is one like LLView::Params::follows
+ // unnamed param is like LLView::Params::rect - implicit
+ const BlockDescriptor& block_data = mostDerivedBlockDescriptor();
+
+ for (BlockDescriptor::param_list_t::const_iterator it = block_data.mUnnamedParams.begin();
+ it != block_data.mUnnamedParams.end();
+ ++it)
+ {
+ param_handle_t param_handle = (*it)->mParamHandle;
+ const Param* param = getParamFromHandle(param_handle);
+ ParamDescriptor::inspect_func_t inspect_func = (*it)->mInspectFunc;
+ if (inspect_func)
+ {
+ name_stack.push_back(std::make_pair("", true));
+ inspect_func(*param, parser, name_stack, (*it)->mMinCount, (*it)->mMaxCount);
+ name_stack.pop_back();
+ }
+ }
+
+ for(BlockDescriptor::param_map_t::const_iterator it = block_data.mNamedParams.begin();
+ it != block_data.mNamedParams.end();
+ ++it)
+ {
+ param_handle_t param_handle = it->second->mParamHandle;
+ const Param* param = getParamFromHandle(param_handle);
+ ParamDescriptor::inspect_func_t inspect_func = it->second->mInspectFunc;
+ if (inspect_func)
+ {
+ // Ensure this param has not already been inspected
+ bool duplicate = false;
+ for (BlockDescriptor::param_list_t::const_iterator it2 = block_data.mUnnamedParams.begin();
+ it2 != block_data.mUnnamedParams.end();
+ ++it2)
+ {
+ if (param_handle == (*it2)->mParamHandle)
+ {
+ duplicate = true;
+ break;
+ }
+ }
+
+ name_stack.push_back(std::make_pair(it->first, !duplicate));
+ inspect_func(*param, parser, name_stack, it->second->mMinCount, it->second->mMaxCount);
+ name_stack.pop_back();
+ }
+ }
+
+ return true;
+ }
+
+ bool BaseBlock::deserializeBlock(Parser& p, Parser::name_stack_range_t& name_stack_range, bool ignored)
+ {
+ BlockDescriptor& block_data = mostDerivedBlockDescriptor();
+ bool names_left = name_stack_range.first != name_stack_range.second;
+
+ bool new_name = names_left
+ ? name_stack_range.first->second
+ : true;
+
+ if (names_left)
+ {
+ const std::string& top_name = name_stack_range.first->first;
+
+ BlockDescriptor::param_map_t::iterator found_it = block_data.mNamedParams.find(top_name);
+ if (found_it != block_data.mNamedParams.end())
+ {
+ // find pointer to member parameter from offset table
+ Param* paramp = getParamFromHandle(found_it->second->mParamHandle);
+ ParamDescriptor::deserialize_func_t deserialize_func = found_it->second->mDeserializeFunc;
+
+ Parser::name_stack_range_t new_name_stack(name_stack_range.first, name_stack_range.second);
+ ++new_name_stack.first;
+ if (deserialize_func(*paramp, p, new_name_stack, new_name))
+ {
+ // value is no longer new, we know about it now
+ name_stack_range.first->second = false;
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ }
+
+ // try to parse unnamed parameters, in declaration order
+ for ( BlockDescriptor::param_list_t::iterator it = block_data.mUnnamedParams.begin();
+ it != block_data.mUnnamedParams.end();
+ ++it)
+ {
+ Param* paramp = getParamFromHandle((*it)->mParamHandle);
+ ParamDescriptor::deserialize_func_t deserialize_func = (*it)->mDeserializeFunc;
+
+ if (deserialize_func && deserialize_func(*paramp, p, name_stack_range, new_name))
+ {
+ return true;
+ }
+ }
+
+ // if no match, and no names left on stack, this is just an existence assertion of this block
+ // verify by calling readValue with NoParamValue type, an inherently unparseable type
+ if (!names_left)
+ {
+ Flag no_value;
+ return p.readValue(no_value);
+ }
+
+ return false;
+ }
+
+ void BaseBlock::addSynonym(Param& param, const std::string& synonym)
+ {
+ BlockDescriptor& block_data = mostDerivedBlockDescriptor();
+ if (block_data.mInitializationState == BlockDescriptor::INITIALIZING)
+ {
+ param_handle_t handle = getHandleFromParam(&param);
+
+ // check for invalid derivation from a paramblock (i.e. without using
+ // Block<T, Base_Class>
+ if ((size_t)handle > block_data.mMaxParamOffset)
+ {
+ llerrs << "Attempted to register param with block defined for parent class, make sure to derive from LLInitParam::Block<YOUR_CLASS, PARAM_BLOCK_BASE_CLASS>" << llendl;
+ }
+
+ ParamDescriptorPtr param_descriptor = findParamDescriptor(param);
+ if (param_descriptor)
+ {
+ if (synonym.empty())
+ {
+ block_data.mUnnamedParams.push_back(param_descriptor);
+ }
+ else
+ {
+ block_data.mNamedParams[synonym] = param_descriptor;
+ }
+ }
+ }
+ }
+
+ const std::string& BaseBlock::getParamName(const BlockDescriptor& block_data, const Param* paramp) const
+ {
+ param_handle_t handle = getHandleFromParam(paramp);
+ for (BlockDescriptor::param_map_t::const_iterator it = block_data.mNamedParams.begin(); it != block_data.mNamedParams.end(); ++it)
+ {
+ if (it->second->mParamHandle == handle)
+ {
+ return it->first;
+ }
+ }
+
+ return LLStringUtil::null;
+ }
+
+ ParamDescriptorPtr BaseBlock::findParamDescriptor(const Param& param)
+ {
+ param_handle_t handle = getHandleFromParam(&param);
+ BlockDescriptor& descriptor = mostDerivedBlockDescriptor();
+ BlockDescriptor::all_params_list_t::iterator end_it = descriptor.mAllParams.end();
+ for (BlockDescriptor::all_params_list_t::iterator it = descriptor.mAllParams.begin();
+ it != end_it;
+ ++it)
+ {
+ if ((*it)->mParamHandle == handle) return *it;
+ }
+ return ParamDescriptorPtr();
+ }
+
+ // take all provided params from other and apply to self
+ // NOTE: this requires that "other" is of the same derived type as this
+ bool BaseBlock::mergeBlock(BlockDescriptor& block_data, const BaseBlock& other, bool overwrite)
+ {
+ bool some_param_changed = false;
+ BlockDescriptor::all_params_list_t::const_iterator end_it = block_data.mAllParams.end();
+ for (BlockDescriptor::all_params_list_t::const_iterator it = block_data.mAllParams.begin();
+ it != end_it;
+ ++it)
+ {
+ const Param* other_paramp = other.getParamFromHandle((*it)->mParamHandle);
+ ParamDescriptor::merge_func_t merge_func = (*it)->mMergeFunc;
+ if (merge_func)
+ {
+ Param* paramp = getParamFromHandle((*it)->mParamHandle);
+ llassert(paramp->getEnclosingBlockOffset() == (*it)->mParamHandle);
+ some_param_changed |= merge_func(*paramp, *other_paramp, overwrite);
+ }
+ }
+ return some_param_changed;
+ }
+}
diff --git a/indra/llcommon/llinitparam.h b/indra/llcommon/llinitparam.h
new file mode 100755
index 0000000000..03ab0fb67f
--- /dev/null
+++ b/indra/llcommon/llinitparam.h
@@ -0,0 +1,2717 @@
+/**
+ * @file llinitparam.h
+ * @brief parameter block abstraction for creating complex objects and
+ * parsing construction parameters from xml and LLSD
+ *
+ * $LicenseInfo:firstyear=2008&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$
+ */
+
+#ifndef LL_LLPARAM_H
+#define LL_LLPARAM_H
+
+#include <vector>
+#include <boost/function.hpp>
+#include <boost/type_traits/is_convertible.hpp>
+#include <boost/type_traits/is_enum.hpp>
+#include <boost/unordered_map.hpp>
+#include <boost/shared_ptr.hpp>
+
+#include "llerror.h"
+#include "llstl.h"
+
+namespace LLTypeTags
+{
+ template <typename INNER_TYPE, int _SORT_ORDER>
+ struct TypeTagBase
+ {
+ typedef void is_tag_t;
+ typedef INNER_TYPE inner_t;
+ static const int SORT_ORDER=_SORT_ORDER;
+ };
+
+ template <int VAL1, int VAL2>
+ struct GreaterThan
+ {
+ static const bool value = VAL1 > VAL2;
+ };
+
+ template<typename ITEM, typename REST, bool NEEDS_SWAP = GreaterThan<ITEM::SORT_ORDER, REST::SORT_ORDER>::value >
+ struct Swap
+ {
+ typedef typename ITEM::template Cons<REST>::value_t value_t;
+ };
+
+ template<typename ITEM, typename REST>
+ struct Swap<ITEM, REST, true>
+ {
+ typedef typename REST::template Cons<Swap<ITEM, typename REST::inner_t>::value_t>::value_t value_t;
+ };
+
+ template<typename T, typename SORTABLE = void>
+ struct IsSortable
+ {
+ static const bool value = false;
+ };
+
+ template<typename T>
+ struct IsSortable<T, typename T::is_tag_t>
+ {
+ static const bool value = true;
+ };
+
+ template<typename ITEM, typename REST, bool IS_REST_SORTABLE = IsSortable<REST>::value>
+ struct InsertInto
+ {
+ typedef typename ITEM::template Cons<REST>::value_t value_t;
+ };
+
+ template<typename ITEM, typename REST>
+ struct InsertInto <ITEM, REST, true>
+ {
+ typedef typename Swap<ITEM, REST>::value_t value_t;
+ };
+
+ template<typename T, bool SORTABLE = IsSortable<T>::value>
+ struct Sorted
+ {
+ typedef T value_t;
+ };
+
+ template<typename T>
+ struct Sorted <T, true>
+ {
+ typedef typename InsertInto<T, typename Sorted<typename T::inner_t>::value_t>::value_t value_t;
+ };
+}
+
+namespace LLInitParam
+{
+ // used to indicate no matching value to a given name when parsing
+ struct Flag{};
+
+ template<typename T> const T& defaultValue() { static T value; return value; }
+
+ // wraps comparison operator between any 2 values of the same type
+ // specialize to handle cases where equality isn't defined well, or at all
+ template <typename T, bool IS_BOOST_FUNCTION = boost::is_convertible<T, boost::function_base>::value >
+ struct ParamCompare
+ {
+ static bool equals(const T &a, const T &b)
+ {
+ return a == b;
+ }
+ };
+
+ // boost function types are not comparable
+ template<typename T>
+ struct ParamCompare<T, true>
+ {
+ static bool equals(const T&a, const T &b)
+ {
+ return false;
+ }
+ };
+
+ template<>
+ struct ParamCompare<LLSD, false>
+ {
+ static bool equals(const LLSD &a, const LLSD &b) { return false; }
+ };
+
+ template<>
+ struct ParamCompare<Flag, false>
+ {
+ static bool equals(const Flag& a, const Flag& b) { return false; }
+ };
+
+
+ // helper functions and classes
+ typedef ptrdiff_t param_handle_t;
+ struct IS_A_BLOCK {};
+ struct NOT_BLOCK {};
+
+ // these templates allow us to distinguish between template parameters
+ // that derive from BaseBlock and those that don't
+ template<typename T, typename BLOCK_IDENTIFIER = void>
+ struct IsBlock
+ {
+ typedef NOT_BLOCK value_t;
+ };
+
+ template<typename T>
+ struct IsBlock<T, typename T::baseblock_base_class_t>
+ {
+ typedef IS_A_BLOCK value_t;
+ };
+
+ // ParamValue class directly manages the wrapped value
+ // by holding on to a copy (scalar params)
+ // or deriving from it (blocks)
+ // has specializations for custom value behavior
+ // and "tag" values like Lazy and Atomic
+ template<typename T, typename VALUE_IS_BLOCK = typename IsBlock<T>::value_t>
+ class ParamValue
+ {
+ typedef ParamValue<T, VALUE_IS_BLOCK> self_t;
+
+ public:
+ typedef T default_value_t;
+ typedef T value_t;
+
+ ParamValue(): mValue() {}
+ ParamValue(const default_value_t& other) : mValue(other) {}
+
+ void setValue(const value_t& val)
+ {
+ mValue = val;
+ }
+
+ const value_t& getValue() const
+ {
+ return mValue;
+ }
+
+ T& getValue()
+ {
+ return mValue;
+ }
+
+ protected:
+ T mValue;
+ };
+
+ template<typename T>
+ class ParamValue<T, IS_A_BLOCK>
+ : public T
+ {
+ typedef ParamValue<T, IS_A_BLOCK> self_t;
+ public:
+ typedef T default_value_t;
+ typedef T value_t;
+
+ ParamValue()
+ : T(),
+ mValidated(false)
+ {}
+
+ ParamValue(const default_value_t& other)
+ : T(other),
+ mValidated(false)
+ {}
+
+ void setValue(const value_t& val)
+ {
+ *this = val;
+ }
+
+ const value_t& getValue() const
+ {
+ return *this;
+ }
+
+ T& getValue()
+ {
+ return *this;
+ }
+
+ protected:
+ mutable bool mValidated; // lazy validation flag
+ };
+
+
+ // empty default implementation of key cache
+ // leverages empty base class optimization
+ template <typename T>
+ class TypeValues
+ : public ParamValue<typename LLTypeTags::Sorted<T>::value_t>
+ {
+ private:
+ struct Inaccessable{};
+ public:
+ typedef std::map<std::string, T> value_name_map_t;
+ typedef Inaccessable name_t;
+ typedef TypeValues<T> type_value_t;
+ typedef ParamValue<typename LLTypeTags::Sorted<T>::value_t> param_value_t;
+ typedef typename param_value_t::value_t value_t;
+
+ TypeValues(const typename param_value_t::value_t& val)
+ : param_value_t(val)
+ {}
+
+ void setValueName(const std::string& key) {}
+ std::string getValueName() const { return ""; }
+ std::string calcValueName(const value_t& value) const { return ""; }
+ void clearValueName() const {}
+
+ static bool getValueFromName(const std::string& name, value_t& value)
+ {
+ return false;
+ }
+
+ static bool valueNamesExist()
+ {
+ return false;
+ }
+
+ static std::vector<std::string>* getPossibleValues()
+ {
+ return NULL;
+ }
+
+ void assignNamedValue(const Inaccessable& name)
+ {}
+
+ operator const value_t&() const
+ {
+ return param_value_t::getValue();
+ }
+
+ const value_t& operator()() const
+ {
+ return param_value_t::getValue();
+ }
+
+ static value_name_map_t* getValueNames() {return NULL;}
+ };
+
+ // helper class to implement name value lookups
+ // and caching of last used name
+ template <typename T, typename DERIVED_TYPE = TypeValues<T>, bool IS_SPECIALIZED = true >
+ class TypeValuesHelper
+ : public ParamValue<typename LLTypeTags::Sorted<T>::value_t>
+ {
+ typedef TypeValuesHelper<T, DERIVED_TYPE, IS_SPECIALIZED> self_t;
+ public:
+ typedef typename std::map<std::string, T> value_name_map_t;
+ typedef std::string name_t;
+ typedef self_t type_value_t;
+ typedef ParamValue<typename LLTypeTags::Sorted<T>::value_t> param_value_t;
+ typedef typename param_value_t::value_t value_t;
+
+ TypeValuesHelper(const typename param_value_t::value_t& val)
+ : param_value_t(val)
+ {}
+
+ //TODO: cache key by index to save on param block size
+ void setValueName(const std::string& value_name)
+ {
+ mValueName = value_name;
+ }
+
+ std::string getValueName() const
+ {
+ return mValueName;
+ }
+
+ std::string calcValueName(const value_t& value) const
+ {
+ value_name_map_t* map = getValueNames();
+ for (typename value_name_map_t::iterator it = map->begin(), end_it = map->end();
+ it != end_it;
+ ++it)
+ {
+ if (ParamCompare<T>::equals(it->second, value))
+ {
+ return it->first;
+ }
+ }
+
+ return "";
+ }
+
+ void clearValueName() const
+ {
+ mValueName.clear();
+ }
+
+ static bool getValueFromName(const std::string& name, value_t& value)
+ {
+ value_name_map_t* map = getValueNames();
+ typename value_name_map_t::iterator found_it = map->find(name);
+ if (found_it == map->end()) return false;
+
+ value = found_it->second;
+ return true;
+ }
+
+ static bool valueNamesExist()
+ {
+ return !getValueNames()->empty();
+ }
+
+ static value_name_map_t* getValueNames()
+ {
+ static value_name_map_t sMap;
+ static bool sInitialized = false;
+
+ if (!sInitialized)
+ {
+ sInitialized = true;
+ DERIVED_TYPE::declareValues();
+ }
+ return &sMap;
+ }
+
+ static std::vector<std::string>* getPossibleValues()
+ {
+ static std::vector<std::string> sValues;
+
+ value_name_map_t* map = getValueNames();
+ for (typename value_name_map_t::iterator it = map->begin(), end_it = map->end();
+ it != end_it;
+ ++it)
+ {
+ sValues.push_back(it->first);
+ }
+ return &sValues;
+ }
+
+ static void declare(const std::string& name, const value_t& value)
+ {
+ (*getValueNames())[name] = value;
+ }
+
+ void operator ()(const std::string& name)
+ {
+ *this = name;
+ }
+
+ void assignNamedValue(const std::string& name)
+ {
+ if (getValueFromName(name, param_value_t::getValue()))
+ {
+ setValueName(name);
+ }
+ }
+
+ operator const value_t&() const
+ {
+ return param_value_t::getValue();
+ }
+
+ const value_t& operator()() const
+ {
+ return param_value_t::getValue();
+ }
+
+ protected:
+ static void getName(const std::string& name, const value_t& value)
+ {}
+
+ mutable std::string mValueName;
+ };
+
+ // string types can support custom named values, but need
+ // to disambiguate in code between a string that is a named value
+ // and a string that is a name
+ template <typename DERIVED_TYPE>
+ class TypeValuesHelper<std::string, DERIVED_TYPE, true>
+ : public TypeValuesHelper<std::string, DERIVED_TYPE, false>
+ {
+ public:
+ typedef TypeValuesHelper<std::string, DERIVED_TYPE, true> self_t;
+ typedef TypeValuesHelper<std::string, DERIVED_TYPE, false> base_t;
+ typedef std::string value_t;
+ typedef std::string name_t;
+ typedef self_t type_value_t;
+
+ TypeValuesHelper(const std::string& val)
+ : TypeValuesHelper(val)
+ {}
+
+ void operator ()(const std::string& name)
+ {
+ *this = name;
+ }
+
+ self_t& operator =(const std::string& name)
+ {
+ if (base_t::getValueFromName(name, ParamValue<std::string>::getValue()))
+ {
+ base_t::setValueName(name);
+ }
+ else
+ {
+ ParamValue<std::string>::setValue(name);
+ }
+ return *this;
+ }
+
+ operator const value_t&() const
+ {
+ return ParamValue<std::string>::getValue();
+ }
+
+ const value_t& operator()() const
+ {
+ return ParamValue<std::string>::getValue();
+ }
+
+ };
+
+ // parser base class with mechanisms for registering readers/writers/inspectors of different types
+ class LL_COMMON_API Parser
+ {
+ LOG_CLASS(Parser);
+ public:
+ typedef std::vector<std::pair<std::string, bool> > name_stack_t;
+ typedef std::pair<name_stack_t::iterator, name_stack_t::iterator> name_stack_range_t;
+ typedef std::vector<std::string> possible_values_t;
+
+ typedef bool (*parser_read_func_t)(Parser& parser, void* output);
+ typedef bool (*parser_write_func_t)(Parser& parser, const void*, name_stack_t&);
+ typedef boost::function<void (name_stack_t&, S32, S32, const possible_values_t*)> parser_inspect_func_t;
+
+ typedef std::map<const std::type_info*, parser_read_func_t> parser_read_func_map_t;
+ typedef std::map<const std::type_info*, parser_write_func_t> parser_write_func_map_t;
+ typedef std::map<const std::type_info*, parser_inspect_func_t> parser_inspect_func_map_t;
+
+ public:
+
+ Parser(parser_read_func_map_t& read_map, parser_write_func_map_t& write_map, parser_inspect_func_map_t& inspect_map)
+ : mParseSilently(false),
+ mParserReadFuncs(&read_map),
+ mParserWriteFuncs(&write_map),
+ mParserInspectFuncs(&inspect_map)
+ {}
+
+ virtual ~Parser();
+
+ template <typename T> bool readValue(T& param, typename boost::disable_if<boost::is_enum<T> >::type* dummy = 0)
+ {
+ parser_read_func_map_t::iterator found_it = mParserReadFuncs->find(&typeid(T));
+ if (found_it != mParserReadFuncs->end())
+ {
+ return found_it->second(*this, (void*)&param);
+ }
+
+ return false;
+ }
+
+ template <typename T> bool readValue(T& param, typename boost::enable_if<boost::is_enum<T> >::type* dummy = 0)
+ {
+ parser_read_func_map_t::iterator found_it = mParserReadFuncs->find(&typeid(T));
+ if (found_it != mParserReadFuncs->end())
+ {
+ return found_it->second(*this, (void*)&param);
+ }
+ else
+ {
+ found_it = mParserReadFuncs->find(&typeid(S32));
+ if (found_it != mParserReadFuncs->end())
+ {
+ S32 int_value;
+ bool parsed = found_it->second(*this, (void*)&int_value);
+ param = (T)int_value;
+ return parsed;
+ }
+ }
+ return false;
+ }
+
+ template <typename T> bool writeValue(const T& param, name_stack_t& name_stack)
+ {
+ parser_write_func_map_t::iterator found_it = mParserWriteFuncs->find(&typeid(T));
+ if (found_it != mParserWriteFuncs->end())
+ {
+ return found_it->second(*this, (const void*)&param, name_stack);
+ }
+ return false;
+ }
+
+ // dispatch inspection to registered inspection functions, for each parameter in a param block
+ template <typename T> bool inspectValue(name_stack_t& name_stack, S32 min_count, S32 max_count, const possible_values_t* possible_values)
+ {
+ parser_inspect_func_map_t::iterator found_it = mParserInspectFuncs->find(&typeid(T));
+ if (found_it != mParserInspectFuncs->end())
+ {
+ found_it->second(name_stack, min_count, max_count, possible_values);
+ return true;
+ }
+ return false;
+ }
+
+ virtual std::string getCurrentElementName() = 0;
+ virtual void parserWarning(const std::string& message);
+ virtual void parserError(const std::string& message);
+ void setParseSilently(bool silent) { mParseSilently = silent; }
+
+ protected:
+ template <typename T>
+ void registerParserFuncs(parser_read_func_t read_func, parser_write_func_t write_func = NULL)
+ {
+ mParserReadFuncs->insert(std::make_pair(&typeid(T), read_func));
+ mParserWriteFuncs->insert(std::make_pair(&typeid(T), write_func));
+ }
+
+ template <typename T>
+ void registerInspectFunc(parser_inspect_func_t inspect_func)
+ {
+ mParserInspectFuncs->insert(std::make_pair(&typeid(T), inspect_func));
+ }
+
+ bool mParseSilently;
+
+ private:
+ parser_read_func_map_t* mParserReadFuncs;
+ parser_write_func_map_t* mParserWriteFuncs;
+ parser_inspect_func_map_t* mParserInspectFuncs;
+ };
+
+ class Param;
+
+ // various callbacks and constraints associated with an individual param
+ struct LL_COMMON_API ParamDescriptor
+ {
+ struct UserData
+ {
+ virtual ~UserData() {}
+ };
+
+ typedef bool(*merge_func_t)(Param&, const Param&, bool);
+ typedef bool(*deserialize_func_t)(Param&, Parser&, Parser::name_stack_range_t&, bool);
+ typedef void(*serialize_func_t)(const Param&, Parser&, Parser::name_stack_t&, const Param* diff_param);
+ typedef void(*inspect_func_t)(const Param&, Parser&, Parser::name_stack_t&, S32 min_count, S32 max_count);
+ typedef bool(*validation_func_t)(const Param*);
+
+ ParamDescriptor(param_handle_t p,
+ merge_func_t merge_func,
+ deserialize_func_t deserialize_func,
+ serialize_func_t serialize_func,
+ validation_func_t validation_func,
+ inspect_func_t inspect_func,
+ S32 min_count,
+ S32 max_count);
+
+ ParamDescriptor();
+ ~ParamDescriptor();
+
+ param_handle_t mParamHandle;
+ merge_func_t mMergeFunc;
+ deserialize_func_t mDeserializeFunc;
+ serialize_func_t mSerializeFunc;
+ inspect_func_t mInspectFunc;
+ validation_func_t mValidationFunc;
+ S32 mMinCount;
+ S32 mMaxCount;
+ S32 mNumRefs;
+ UserData* mUserData;
+ };
+
+ typedef boost::shared_ptr<ParamDescriptor> ParamDescriptorPtr;
+
+ // each derived Block class keeps a static data structure maintaining offsets to various params
+ class LL_COMMON_API BlockDescriptor
+ {
+ public:
+ BlockDescriptor();
+
+ typedef enum e_initialization_state
+ {
+ UNINITIALIZED,
+ INITIALIZING,
+ INITIALIZED
+ } EInitializationState;
+
+ void aggregateBlockData(BlockDescriptor& src_block_data);
+ void addParam(ParamDescriptorPtr param, const char* name);
+
+ typedef boost::unordered_map<const std::string, ParamDescriptorPtr> param_map_t;
+ typedef std::vector<ParamDescriptorPtr> param_list_t;
+ typedef std::list<ParamDescriptorPtr> all_params_list_t;
+ typedef std::vector<std::pair<param_handle_t, ParamDescriptor::validation_func_t> > param_validation_list_t;
+
+ param_map_t mNamedParams; // parameters with associated names
+ param_list_t mUnnamedParams; // parameters with_out_ associated names
+ param_validation_list_t mValidationList; // parameters that must be validated
+ all_params_list_t mAllParams; // all parameters, owns descriptors
+ size_t mMaxParamOffset;
+ EInitializationState mInitializationState; // whether or not static block data has been initialized
+ class BaseBlock* mCurrentBlockPtr; // pointer to block currently being constructed
+ };
+
+ //TODO: implement in terms of owned_ptr
+ template<typename T>
+ class LazyValue
+ {
+ public:
+ LazyValue()
+ : mPtr(NULL)
+ {}
+
+ ~LazyValue()
+ {
+ delete mPtr;
+ }
+
+ LazyValue(const T& value)
+ {
+ mPtr = new T(value);
+ }
+
+ LazyValue(const LazyValue& other)
+ : mPtr(NULL)
+ {
+ *this = other;
+ }
+
+ LazyValue& operator = (const LazyValue& other)
+ {
+ if (!other.mPtr)
+ {
+ delete mPtr;
+ mPtr = NULL;
+ }
+ else
+ {
+ if (!mPtr)
+ {
+ mPtr = new T(*other.mPtr);
+ }
+ else
+ {
+ *mPtr = *(other.mPtr);
+ }
+ }
+ return *this;
+ }
+
+ bool operator==(const LazyValue& other) const
+ {
+ if (empty() || other.empty()) return false;
+ return *mPtr == *other.mPtr;
+ }
+
+ bool empty() const
+ {
+ return mPtr == NULL;
+ }
+
+ void set(const T& other)
+ {
+ if (!mPtr)
+ {
+ mPtr = new T(other);
+ }
+ else
+ {
+ *mPtr = other;
+ }
+ }
+
+ const T& get() const
+ {
+ return *ensureInstance();
+ }
+
+ T& get()
+ {
+ return *ensureInstance();
+ }
+
+ operator const T&() const
+ {
+ return get();
+ }
+
+ private:
+ // lazily allocate an instance of T
+ T* ensureInstance() const
+ {
+ if (mPtr == NULL)
+ {
+ mPtr = new T();
+ }
+ return mPtr;
+ }
+
+ private:
+
+ mutable T* mPtr;
+ };
+
+ // root class of all parameter blocks
+
+ class LL_COMMON_API BaseBlock
+ {
+ public:
+ // lift block tags into baseblock namespace so derived classes do not need to qualify them
+ typedef LLInitParam::IS_A_BLOCK IS_A_BLOCK;
+ typedef LLInitParam::NOT_BLOCK NOT_A_BLOCK;
+
+ template<typename T>
+ struct Sequential : public LLTypeTags::TypeTagBase<T, 2>
+ {
+ template <typename S> struct Cons { typedef Sequential<ParamValue<S> > value_t; };
+ template <typename S> struct Cons<Sequential<S> > { typedef Sequential<S> value_t; };
+ };
+
+ template<typename T>
+ struct Atomic : public LLTypeTags::TypeTagBase<T, 1>
+ {
+ template <typename S> struct Cons { typedef Atomic<ParamValue<S> > value_t; };
+ template <typename S> struct Cons<Atomic<S> > { typedef Atomic<S> value_t; };
+ };
+
+ template<typename T, typename BLOCK_T = typename IsBlock<T>::value_t >
+ struct Lazy : public LLTypeTags::TypeTagBase<T, 0>
+ {
+ template <typename S> struct Cons
+ {
+ typedef Lazy<ParamValue<S, BLOCK_T>, BLOCK_T> value_t;
+ };
+ template <typename S> struct Cons<Lazy<S, IS_A_BLOCK> >
+ {
+ typedef Lazy<S, IS_A_BLOCK> value_t;
+ };
+ template <typename S> struct Cons<Lazy<S, NOT_A_BLOCK> >
+ {
+ typedef Lazy<S, BLOCK_T> value_t;
+ };
+ };
+
+ // "Multiple" constraint types, put here in root class to avoid ambiguity during use
+ struct AnyAmount
+ {
+ enum { minCount = 0 };
+ enum { maxCount = U32_MAX };
+ };
+
+ template<U32 MIN_AMOUNT>
+ struct AtLeast
+ {
+ enum { minCount = MIN_AMOUNT };
+ enum { maxCount = U32_MAX };
+ };
+
+ template<U32 MAX_AMOUNT>
+ struct AtMost
+ {
+ enum { minCount = 0 };
+ enum { maxCount = MAX_AMOUNT };
+ };
+
+ template<U32 MIN_AMOUNT, U32 MAX_AMOUNT>
+ struct Between
+ {
+ enum { minCount = MIN_AMOUNT };
+ enum { maxCount = MAX_AMOUNT };
+ };
+
+ template<U32 EXACT_COUNT>
+ struct Exactly
+ {
+ enum { minCount = EXACT_COUNT };
+ enum { maxCount = EXACT_COUNT };
+ };
+
+ // this typedef identifies derived classes as being blocks
+ typedef void baseblock_base_class_t;
+ LOG_CLASS(BaseBlock);
+ friend class Param;
+
+ virtual ~BaseBlock() {}
+ bool submitValue(Parser::name_stack_t& name_stack, Parser& p, bool silent=false);
+
+ param_handle_t getHandleFromParam(const Param* param) const;
+ bool validateBlock(bool emit_errors = true) const;
+
+ Param* getParamFromHandle(const param_handle_t param_handle)
+ {
+ if (param_handle == 0) return NULL;
+
+ U8* baseblock_address = reinterpret_cast<U8*>(this);
+ return reinterpret_cast<Param*>(baseblock_address + param_handle);
+ }
+
+ const Param* getParamFromHandle(const param_handle_t param_handle) const
+ {
+ const U8* baseblock_address = reinterpret_cast<const U8*>(this);
+ return reinterpret_cast<const Param*>(baseblock_address + param_handle);
+ }
+
+ void addSynonym(Param& param, const std::string& synonym);
+
+ // Blocks can override this to do custom tracking of changes
+ virtual void paramChanged(const Param& changed_param, bool user_provided) {}
+
+ bool deserializeBlock(Parser& p, Parser::name_stack_range_t& name_stack_range, bool new_name);
+ void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const BaseBlock* diff_block = NULL) const;
+ bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const;
+
+ virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return getBlockDescriptor(); }
+ virtual BlockDescriptor& mostDerivedBlockDescriptor() { return getBlockDescriptor(); }
+
+ // take all provided params from other and apply to self
+ bool overwriteFrom(const BaseBlock& other)
+ {
+ return false;
+ }
+
+ // take all provided params that are not already provided, and apply to self
+ bool fillFrom(const BaseBlock& other)
+ {
+ return false;
+ }
+
+ ParamDescriptorPtr findParamDescriptor(const Param& param);
+
+ // take all provided params from other and apply to self
+ bool mergeBlock(BlockDescriptor& block_data, const BaseBlock& other, bool overwrite);
+
+ static BlockDescriptor& getBlockDescriptor()
+ {
+ static BlockDescriptor sBlockDescriptor;
+ return sBlockDescriptor;
+ }
+
+ protected:
+ void init(BlockDescriptor& descriptor, BlockDescriptor& base_descriptor, size_t block_size);
+
+
+ bool mergeBlockParam(bool source_provided, bool dst_provided, BlockDescriptor& block_data, const BaseBlock& source, bool overwrite)
+ {
+ return mergeBlock(block_data, source, overwrite);
+ }
+
+ private:
+ const std::string& getParamName(const BlockDescriptor& block_data, const Param* paramp) const;
+ };
+
+ class LL_COMMON_API Param
+ {
+ public:
+ void setProvided(bool is_provided = true)
+ {
+ mIsProvided = is_provided;
+ enclosingBlock().paramChanged(*this, is_provided);
+ }
+
+ Param& operator =(const Param& other)
+ {
+ mIsProvided = other.mIsProvided;
+ // don't change mEnclosingblockoffset
+ return *this;
+ }
+ protected:
+
+ bool anyProvided() const { return mIsProvided; }
+
+ Param(BaseBlock* enclosing_block);
+
+ // store pointer to enclosing block as offset to reduce space and allow for quick copying
+ BaseBlock& enclosingBlock() const
+ {
+ const U8* my_addr = reinterpret_cast<const U8*>(this);
+ // get address of enclosing BLOCK class using stored offset to enclosing BaseBlock class
+ return *const_cast<BaseBlock*>
+ (reinterpret_cast<const BaseBlock*>
+ (my_addr - (ptrdiff_t)getEnclosingBlockOffset()));
+ }
+
+ U32 getEnclosingBlockOffset() const
+ {
+ return ((U32)mEnclosingBlockOffsetHigh << 16) | (U32)mEnclosingBlockOffsetLow;
+ }
+
+ private:
+ friend class BaseBlock;
+
+ //24 bits for member offset field and 1 bit for provided flag
+ U16 mEnclosingBlockOffsetLow;
+ U8 mEnclosingBlockOffsetHigh:7;
+ U8 mIsProvided:1;
+
+ };
+
+ template<typename T, typename NAME_VALUE_LOOKUP = TypeValues<T> >
+ struct ParamIterator
+ {
+ typedef typename std::vector<typename NAME_VALUE_LOOKUP::type_value_t >::const_iterator const_iterator;
+ typedef typename std::vector<typename NAME_VALUE_LOOKUP::type_value_t >::iterator iterator;
+ };
+
+ // wrapper for parameter with a known type
+ // specialized to handle 4 cases:
+ // simple "scalar" value
+ // parameter that is itself a block
+ // multiple scalar values, stored in a vector
+ // multiple blocks, stored in a vector
+ template<typename T,
+ typename NAME_VALUE_LOOKUP = TypeValues<T>,
+ bool HAS_MULTIPLE_VALUES = false,
+ typename VALUE_IS_BLOCK = typename IsBlock<ParamValue<typename LLTypeTags::Sorted<T>::value_t> >::value_t>
+ class TypedParam
+ : public Param,
+ public NAME_VALUE_LOOKUP::type_value_t
+ {
+ protected:
+ typedef TypedParam<T, NAME_VALUE_LOOKUP, HAS_MULTIPLE_VALUES, VALUE_IS_BLOCK> self_t;
+ typedef ParamValue<typename LLTypeTags::Sorted<T>::value_t> param_value_t;
+ typedef typename param_value_t::default_value_t default_value_t;
+ typedef typename NAME_VALUE_LOOKUP::type_value_t named_value_t;
+ public:
+ typedef typename param_value_t::value_t value_t;
+
+ using named_value_t::operator();
+
+ TypedParam(BlockDescriptor& block_descriptor, const char* name, const default_value_t& value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)
+ : Param(block_descriptor.mCurrentBlockPtr),
+ named_value_t(value)
+ {
+ if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))
+ {
+ init(block_descriptor, validate_func, min_count, max_count, name);
+ }
+ }
+
+ bool isProvided() const { return Param::anyProvided(); }
+
+ static bool deserializeParam(Param& param, Parser& parser, Parser::name_stack_range_t& name_stack_range, bool new_name)
+ {
+ self_t& typed_param = static_cast<self_t&>(param);
+ // no further names in stack, attempt to parse value now
+ if (name_stack_range.first == name_stack_range.second)
+ {
+ std::string name;
+
+ // try to parse a known named value
+ if(named_value_t::valueNamesExist()
+ && parser.readValue(name)
+ && named_value_t::getValueFromName(name, typed_param.getValue()))
+ {
+ typed_param.setValueName(name);
+ typed_param.setProvided();
+ return true;
+ }
+ // try to read value directly
+ else if (parser.readValue(typed_param.getValue()))
+ {
+ typed_param.clearValueName();
+ typed_param.setProvided();
+ return true;
+ }
+ }
+ return false;
+ }
+
+ static void serializeParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, const Param* diff_param)
+ {
+ const self_t& typed_param = static_cast<const self_t&>(param);
+ if (!typed_param.isProvided()) return;
+
+ if (!name_stack.empty())
+ {
+ name_stack.back().second = true;
+ }
+
+ std::string key = typed_param.getValueName();
+
+ // first try to write out name of name/value pair
+
+ if (!key.empty())
+ {
+ if (!diff_param || !ParamCompare<std::string>::equals(static_cast<const self_t*>(diff_param)->getValueName(), key))
+ {
+ parser.writeValue(key, name_stack);
+ }
+ }
+ // then try to serialize value directly
+ else if (!diff_param || !ParamCompare<T>::equals(typed_param.getValue(), static_cast<const self_t*>(diff_param)->getValue()))
+ {
+ if (!parser.writeValue(typed_param.getValue(), name_stack))
+ {
+ std::string calculated_key = typed_param.calcValueName(typed_param.getValue());
+ if (calculated_key.size()
+ && (!diff_param
+ || !ParamCompare<std::string>::equals(static_cast<const self_t*>(diff_param)->getValueName(), calculated_key)))
+ {
+ parser.writeValue(calculated_key, name_stack);
+ }
+ }
+ }
+ }
+
+ static void inspectParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, S32 min_count, S32 max_count)
+ {
+ // tell parser about our actual type
+ parser.inspectValue<T>(name_stack, min_count, max_count, NULL);
+ // then tell it about string-based alternatives ("red", "blue", etc. for LLColor4)
+ if (named_value_t::getPossibleValues())
+ {
+ parser.inspectValue<std::string>(name_stack, min_count, max_count, named_value_t::getPossibleValues());
+ }
+ }
+
+ void set(const value_t& val, bool flag_as_provided = true)
+ {
+ named_value_t::clearValueName();
+ setValue(val);
+ setProvided(flag_as_provided);
+ }
+
+ self_t& operator =(const typename named_value_t::name_t& name)
+ {
+ named_value_t::assignNamedValue(name);
+ return *this;
+ }
+
+ protected:
+
+ self_t& operator =(const self_t& other)
+ {
+ param_value_t::operator =(other);
+ Param::operator =(other);
+ return *this;
+ }
+
+ static bool mergeWith(Param& dst, const Param& src, bool overwrite)
+ {
+ const self_t& src_typed_param = static_cast<const self_t&>(src);
+ self_t& dst_typed_param = static_cast<self_t&>(dst);
+
+ if (src_typed_param.isProvided()
+ && (overwrite || !dst_typed_param.isProvided()))
+ {
+ dst_typed_param.set(src_typed_param.getValue());
+ return true;
+ }
+ return false;
+ }
+ private:
+ void init( BlockDescriptor &block_descriptor, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count, const char* name )
+ {
+ ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor(
+ block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
+ &mergeWith,
+ &deserializeParam,
+ &serializeParam,
+ validate_func,
+ &inspectParam,
+ min_count, max_count));
+ block_descriptor.addParam(param_descriptor, name);
+ }
+ };
+
+ // parameter that is a block
+ template <typename T, typename NAME_VALUE_LOOKUP>
+ class TypedParam<T, NAME_VALUE_LOOKUP, false, IS_A_BLOCK>
+ : public Param,
+ public NAME_VALUE_LOOKUP::type_value_t
+ {
+ protected:
+ typedef ParamValue<typename LLTypeTags::Sorted<T>::value_t> param_value_t;
+ typedef typename param_value_t::default_value_t default_value_t;
+ typedef TypedParam<T, NAME_VALUE_LOOKUP, false, IS_A_BLOCK> self_t;
+ typedef typename NAME_VALUE_LOOKUP::type_value_t named_value_t;
+ public:
+ using named_value_t::operator();
+ typedef typename param_value_t::value_t value_t;
+
+ TypedParam(BlockDescriptor& block_descriptor, const char* name, const default_value_t& value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)
+ : Param(block_descriptor.mCurrentBlockPtr),
+ named_value_t(value)
+ {
+ if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))
+ {
+ init(block_descriptor, validate_func, min_count, max_count, name);
+ }
+ }
+
+ static bool deserializeParam(Param& param, Parser& parser, Parser::name_stack_range_t& name_stack_range, bool new_name)
+ {
+ self_t& typed_param = static_cast<self_t&>(param);
+
+ if (name_stack_range.first == name_stack_range.second)
+ { // try to parse a known named value
+ std::string name;
+
+ if(named_value_t::valueNamesExist()
+ && parser.readValue(name)
+ && named_value_t::getValueFromName(name, typed_param.getValue()))
+ {
+ typed_param.setValueName(name);
+ typed_param.setProvided();
+ return true;
+ }
+ }
+
+ if(typed_param.deserializeBlock(parser, name_stack_range, new_name))
+ { // attempt to parse block...
+ typed_param.clearValueName();
+ typed_param.setProvided();
+ return true;
+ }
+
+
+ return false;
+ }
+
+ static void serializeParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, const Param* diff_param)
+ {
+ const self_t& typed_param = static_cast<const self_t&>(param);
+ if (!typed_param.isProvided()) return;
+
+ if (!name_stack.empty())
+ {
+ name_stack.back().second = true;
+ }
+
+ std::string key = typed_param.getValueName();
+ if (!key.empty())
+ {
+ if (!diff_param || !ParamCompare<std::string>::equals(static_cast<const self_t*>(diff_param)->getValueName(), key))
+ {
+ parser.writeValue(key, name_stack);
+ }
+ }
+ else
+ {
+ typed_param.serializeBlock(parser, name_stack, static_cast<const self_t*>(diff_param));
+ }
+ }
+
+ static void inspectParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, S32 min_count, S32 max_count)
+ {
+ const self_t& typed_param = static_cast<const self_t&>(param);
+
+ // tell parser about our actual type
+ parser.inspectValue<value_t>(name_stack, min_count, max_count, NULL);
+ // then tell it about string-based alternatives ("red", "blue", etc. for LLColor4)
+ if (named_value_t::getPossibleValues())
+ {
+ parser.inspectValue<std::string>(name_stack, min_count, max_count, named_value_t::getPossibleValues());
+ }
+
+ typed_param.inspectBlock(parser, name_stack, min_count, max_count);
+ }
+
+ // a param-that-is-a-block is provided when the user has set one of its child params
+ // *and* the block as a whole validates
+ bool isProvided() const
+ {
+ // only validate block when it hasn't already passed validation with current data
+ if (Param::anyProvided() && !param_value_t::mValidated)
+ {
+ // a sub-block is "provided" when it has been filled in enough to be valid
+ param_value_t::mValidated = param_value_t::validateBlock(false);
+ }
+ return Param::anyProvided() && param_value_t::mValidated;
+ }
+
+ // assign block contents to this param-that-is-a-block
+ void set(const value_t& val, bool flag_as_provided = true)
+ {
+ setValue(val);
+ named_value_t::clearValueName();
+ // force revalidation of block
+ // next call to isProvided() will update provision status based on validity
+ param_value_t::mValidated = false;
+ setProvided(flag_as_provided);
+ }
+
+ self_t& operator =(const typename named_value_t::name_t& name)
+ {
+ named_value_t::assignNamedValue(name);
+ return *this;
+ }
+
+ // propagate changed status up to enclosing block
+ /*virtual*/ void paramChanged(const Param& changed_param, bool user_provided)
+ {
+ param_value_t::paramChanged(changed_param, user_provided);
+
+ if (user_provided)
+ {
+ // a child param has been explicitly changed
+ // so *some* aspect of this block is now provided
+ param_value_t::mValidated = false;
+ setProvided();
+ named_value_t::clearValueName();
+ }
+ else
+ {
+ Param::enclosingBlock().paramChanged(*this, user_provided);
+ }
+ }
+
+ protected:
+
+ self_t& operator =(const self_t& other)
+ {
+ param_value_t::operator =(other);
+ Param::operator =(other);
+ return *this;
+ }
+
+ static bool mergeWith(Param& dst, const Param& src, bool overwrite)
+ {
+ const self_t& src_typed_param = static_cast<const self_t&>(src);
+ self_t& dst_typed_param = static_cast<self_t&>(dst);
+
+ if (src_typed_param.anyProvided())
+ {
+ if (dst_typed_param.mergeBlockParam(src_typed_param.isProvided(), dst_typed_param.isProvided(), param_value_t::getBlockDescriptor(), src_typed_param, overwrite))
+ {
+ dst_typed_param.clearValueName();
+ dst_typed_param.setProvided(true);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private:
+ void init( BlockDescriptor &block_descriptor, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count, const char* name )
+ {
+ ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor(
+ block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
+ &mergeWith,
+ &deserializeParam,
+ &serializeParam,
+ validate_func,
+ &inspectParam,
+ min_count, max_count));
+ block_descriptor.addParam(param_descriptor, name);
+ }
+ };
+
+ // list of non-block parameters
+ template <typename VALUE_TYPE, typename NAME_VALUE_LOOKUP>
+ class TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, NOT_BLOCK>
+ : public Param
+ {
+ protected:
+ typedef TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, NOT_BLOCK> self_t;
+ typedef ParamValue<typename LLTypeTags::Sorted<VALUE_TYPE>::value_t> param_value_t;
+ typedef typename std::vector<typename NAME_VALUE_LOOKUP::type_value_t> container_t;
+ typedef container_t default_value_t;
+ typedef typename NAME_VALUE_LOOKUP::type_value_t named_value_t;
+
+ public:
+ typedef typename param_value_t::value_t value_t;
+
+ TypedParam(BlockDescriptor& block_descriptor, const char* name, const default_value_t& value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)
+ : Param(block_descriptor.mCurrentBlockPtr)
+ {
+ std::copy(value.begin(), value.end(), std::back_inserter(mValues));
+
+ if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))
+ {
+ init(block_descriptor, validate_func, min_count, max_count, name);
+
+ }
+ }
+
+ bool isProvided() const { return Param::anyProvided(); }
+
+ static bool deserializeParam(Param& param, Parser& parser, Parser::name_stack_range_t& name_stack_range, bool new_name)
+ {
+ Parser::name_stack_range_t new_name_stack_range(name_stack_range);
+ self_t& typed_param = static_cast<self_t&>(param);
+ value_t value;
+
+ // pop first element if empty string
+ if (new_name_stack_range.first != new_name_stack_range.second && new_name_stack_range.first->first.empty())
+ {
+ ++new_name_stack_range.first;
+ }
+
+ // no further names in stack, attempt to parse value now
+ if (name_stack_range.first == name_stack_range.second)
+ {
+ std::string name;
+
+ // try to parse a known named value
+ if(named_value_t::valueNamesExist()
+ && parser.readValue(name)
+ && named_value_t::getValueFromName(name, value))
+ {
+ typed_param.add(value);
+ typed_param.mValues.back().setValueName(name);
+ return true;
+ }
+ else if (parser.readValue(value)) // attempt to read value directly
+ {
+ typed_param.add(value);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ static void serializeParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, const Param* diff_param)
+ {
+ const self_t& typed_param = static_cast<const self_t&>(param);
+ if (!typed_param.isProvided()) return;
+
+ for (const_iterator it = typed_param.mValues.begin(), end_it = typed_param.mValues.end();
+ it != end_it;
+ ++it)
+ {
+ std::string key = it->getValueName();
+ name_stack.push_back(std::make_pair(std::string(), true));
+
+ if(key.empty())
+ // not parsed via name values, write out value directly
+ {
+ bool value_written = parser.writeValue(*it, name_stack);
+ if (!value_written)
+ {
+ std::string calculated_key = it->calcValueName(it->getValue());
+ if (!parser.writeValue(calculated_key, name_stack))
+ {
+ break;
+ }
+ }
+ }
+ else
+ {
+ if(!parser.writeValue(key, name_stack))
+ {
+ break;
+ }
+ }
+
+ name_stack.pop_back();
+ }
+ }
+
+ static void inspectParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, S32 min_count, S32 max_count)
+ {
+ parser.inspectValue<VALUE_TYPE>(name_stack, min_count, max_count, NULL);
+ if (named_value_t::getPossibleValues())
+ {
+ parser.inspectValue<std::string>(name_stack, min_count, max_count, named_value_t::getPossibleValues());
+ }
+ }
+
+ void set(const container_t& val, bool flag_as_provided = true)
+ {
+ mValues = val;
+ setProvided(flag_as_provided);
+ }
+
+ param_value_t& add()
+ {
+ mValues.push_back(value_t());
+ Param::setProvided();
+ return mValues.back();
+ }
+
+ self_t& add(const value_t& item)
+ {
+ mValues.push_back(item);
+ setProvided();
+ return *this;
+ }
+
+ self_t& add(const typename named_value_t::name_t& name)
+ {
+ value_t value;
+
+ // try to parse a per type named value
+ if (named_value_t::getValueFromName(name, value))
+ {
+ add(value);
+ mValues.back().setValueName(name);
+ }
+
+ return *this;
+ }
+
+ // implicit conversion
+ operator const container_t&() const { return mValues; }
+ // explicit conversion
+ const container_t& operator()() const { return mValues; }
+
+ typedef typename container_t::iterator iterator;
+ typedef typename container_t::const_iterator const_iterator;
+ iterator begin() { return mValues.begin(); }
+ iterator end() { return mValues.end(); }
+ const_iterator begin() const { return mValues.begin(); }
+ const_iterator end() const { return mValues.end(); }
+ bool empty() const { return mValues.empty(); }
+ size_t size() const { return mValues.size(); }
+
+ U32 numValidElements() const
+ {
+ return mValues.size();
+ }
+
+ protected:
+ static bool mergeWith(Param& dst, const Param& src, bool overwrite)
+ {
+ const self_t& src_typed_param = static_cast<const self_t&>(src);
+ self_t& dst_typed_param = static_cast<self_t&>(dst);
+
+ if (overwrite)
+ {
+ std::copy(src_typed_param.begin(), src_typed_param.end(), std::back_inserter(dst_typed_param.mValues));
+ }
+ else
+ {
+ container_t new_values(src_typed_param.mValues);
+ std::copy(dst_typed_param.begin(), dst_typed_param.end(), std::back_inserter(new_values));
+ std::swap(dst_typed_param.mValues, new_values);
+ }
+
+ if (src_typed_param.begin() != src_typed_param.end())
+ {
+ dst_typed_param.setProvided();
+ }
+ return true;
+ }
+
+ container_t mValues;
+
+ private:
+ void init( BlockDescriptor &block_descriptor, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count, const char* name )
+ {
+ ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor(
+ block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
+ &mergeWith,
+ &deserializeParam,
+ &serializeParam,
+ validate_func,
+ &inspectParam,
+ min_count, max_count));
+ block_descriptor.addParam(param_descriptor, name);
+ }
+ };
+
+ // list of block parameters
+ template <typename VALUE_TYPE, typename NAME_VALUE_LOOKUP>
+ class TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, IS_A_BLOCK>
+ : public Param
+ {
+ protected:
+ typedef TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, IS_A_BLOCK> self_t;
+ typedef ParamValue<typename LLTypeTags::Sorted<VALUE_TYPE>::value_t> param_value_t;
+ typedef typename std::vector<typename NAME_VALUE_LOOKUP::type_value_t> container_t;
+ typedef typename NAME_VALUE_LOOKUP::type_value_t named_value_t;
+ typedef container_t default_value_t;
+ typedef typename container_t::iterator iterator;
+ typedef typename container_t::const_iterator const_iterator;
+ public:
+ typedef typename param_value_t::value_t value_t;
+
+ TypedParam(BlockDescriptor& block_descriptor, const char* name, const default_value_t& value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)
+ : Param(block_descriptor.mCurrentBlockPtr)
+ {
+ std::copy(value.begin(), value.end(), back_inserter(mValues));
+
+ if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))
+ {
+ init(block_descriptor, validate_func, min_count, max_count, name);
+ }
+ }
+
+ bool isProvided() const { return Param::anyProvided(); }
+
+ static bool deserializeParam(Param& param, Parser& parser, Parser::name_stack_range_t& name_stack_range, bool new_name)
+ {
+ Parser::name_stack_range_t new_name_stack_range(name_stack_range);
+ self_t& typed_param = static_cast<self_t&>(param);
+ bool new_value = false;
+ bool new_array_value = false;
+
+ // pop first element if empty string
+ if (new_name_stack_range.first != new_name_stack_range.second && new_name_stack_range.first->first.empty())
+ {
+ new_array_value = new_name_stack_range.first->second;
+ ++new_name_stack_range.first;
+ }
+
+ if (new_name || new_array_value || typed_param.mValues.empty())
+ {
+ new_value = true;
+ typed_param.mValues.push_back(value_t());
+ }
+ param_value_t& value = typed_param.mValues.back();
+
+ if (name_stack_range.first == name_stack_range.second)
+ { // try to parse a known named value
+ std::string name;
+
+ if(named_value_t::valueNamesExist()
+ && parser.readValue(name)
+ && named_value_t::getValueFromName(name, value.getValue()))
+ {
+ typed_param.mValues.back().setValueName(name);
+ typed_param.setProvided();
+ return true;
+ }
+ }
+
+ // attempt to parse block...
+ if(value.deserializeBlock(parser, new_name_stack_range, new_name))
+ {
+ typed_param.setProvided();
+ if (new_array_value)
+ {
+ name_stack_range.first->second = false;
+ }
+ return true;
+ }
+
+
+ if (new_value)
+ { // failed to parse new value, pop it off
+ typed_param.mValues.pop_back();
+ }
+
+ return false;
+ }
+
+ static void serializeParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, const Param* diff_param)
+ {
+ const self_t& typed_param = static_cast<const self_t&>(param);
+ if (!typed_param.isProvided()) return;
+
+ for (const_iterator it = typed_param.mValues.begin(), end_it = typed_param.mValues.end();
+ it != end_it;
+ ++it)
+ {
+ name_stack.push_back(std::make_pair(std::string(), true));
+
+ std::string key = it->getValueName();
+ if (!key.empty())
+ {
+ parser.writeValue(key, name_stack);
+ }
+ // Not parsed via named values, write out value directly
+ // NOTE: currently we don't worry about removing default values in Multiple
+ else
+ {
+ it->serializeBlock(parser, name_stack, NULL);
+ }
+
+ name_stack.pop_back();
+ }
+ }
+
+ static void inspectParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, S32 min_count, S32 max_count)
+ {
+ const param_value_t& value_param = param_value_t(value_t());
+
+ // tell parser about our actual type
+ parser.inspectValue<value_t>(name_stack, min_count, max_count, NULL);
+ // then tell it about string-based alternatives ("red", "blue", etc. for LLColor4)
+ if (named_value_t::getPossibleValues())
+ {
+ parser.inspectValue<std::string>(name_stack, min_count, max_count, named_value_t::getPossibleValues());
+ }
+
+ value_param.inspectBlock(parser, name_stack, min_count, max_count);
+ }
+
+ void set(const container_t& val, bool flag_as_provided = true)
+ {
+ mValues = val;
+ setProvided(flag_as_provided);
+ }
+
+ param_value_t& add()
+ {
+ mValues.push_back(value_t());
+ setProvided();
+ return mValues.back();
+ }
+
+ self_t& add(const value_t& item)
+ {
+ mValues.push_back(item);
+ setProvided();
+ return *this;
+ }
+
+ self_t& add(const typename named_value_t::name_t& name)
+ {
+ value_t value;
+
+ // try to parse a per type named value
+ if (named_value_t::getValueFromName(name, value))
+ {
+ add(value);
+ mValues.back().setValueName(name);
+ }
+ return *this;
+ }
+
+ // implicit conversion
+ operator const container_t&() const { return mValues; }
+ // explicit conversion
+ const container_t& operator()() const { return mValues; }
+
+ iterator begin() { return mValues.begin(); }
+ iterator end() { return mValues.end(); }
+ const_iterator begin() const { return mValues.begin(); }
+ const_iterator end() const { return mValues.end(); }
+ bool empty() const { return mValues.empty(); }
+ size_t size() const { return mValues.size(); }
+
+ U32 numValidElements() const
+ {
+ U32 count = 0;
+ for (const_iterator it = mValues.begin(), end_it = mValues.end();
+ it != end_it;
+ ++it)
+ {
+ if(it->validateBlock(false)) count++;
+ }
+ return count;
+ }
+
+ protected:
+
+ static bool mergeWith(Param& dst, const Param& src, bool overwrite)
+ {
+ const self_t& src_typed_param = static_cast<const self_t&>(src);
+ self_t& dst_typed_param = static_cast<self_t&>(dst);
+
+ if (overwrite)
+ {
+ std::copy(src_typed_param.begin(), src_typed_param.end(), std::back_inserter(dst_typed_param.mValues));
+ }
+ else
+ {
+ container_t new_values(src_typed_param.mValues);
+ std::copy(dst_typed_param.begin(), dst_typed_param.end(), std::back_inserter(new_values));
+ std::swap(dst_typed_param.mValues, new_values);
+ }
+
+ if (src_typed_param.begin() != src_typed_param.end())
+ {
+ dst_typed_param.setProvided();
+ }
+
+ return true;
+ }
+
+ container_t mValues;
+
+ private:
+ void init( BlockDescriptor &block_descriptor, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count, const char* name )
+ {
+ ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor(
+ block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
+ &mergeWith,
+ &deserializeParam,
+ &serializeParam,
+ validate_func,
+ &inspectParam,
+ min_count, max_count));
+ block_descriptor.addParam(param_descriptor, name);
+ }
+ };
+
+ template <typename DERIVED_BLOCK, typename BASE_BLOCK = BaseBlock>
+ class ChoiceBlock : public BASE_BLOCK
+ {
+ typedef ChoiceBlock<DERIVED_BLOCK, BASE_BLOCK> self_t;
+ typedef ChoiceBlock<DERIVED_BLOCK, BASE_BLOCK> enclosing_block_t;
+ typedef BASE_BLOCK base_block_t;
+
+ LOG_CLASS(self_t);
+ public:
+ // take all provided params from other and apply to self
+ bool overwriteFrom(const self_t& other)
+ {
+ return static_cast<DERIVED_BLOCK*>(this)->mergeBlock(getBlockDescriptor(), other, true);
+ }
+
+ // take all provided params that are not already provided, and apply to self
+ bool fillFrom(const self_t& other)
+ {
+ return static_cast<DERIVED_BLOCK*>(this)->mergeBlock(getBlockDescriptor(), other, false);
+ }
+
+ bool mergeBlockParam(bool source_provided, bool dest_provided, BlockDescriptor& block_data, const self_t& source, bool overwrite)
+ {
+ bool source_override = source_provided && (overwrite || !dest_provided);
+
+ if (source_override || source.mCurChoice == mCurChoice)
+ {
+ return mergeBlock(block_data, source, overwrite);
+ }
+ return false;
+ }
+
+ // merge with other block
+ bool mergeBlock(BlockDescriptor& block_data, const self_t& other, bool overwrite)
+ {
+ mCurChoice = other.mCurChoice;
+ return base_block_t::mergeBlock(getBlockDescriptor(), other, overwrite);
+ }
+
+ // clear out old choice when param has changed
+ /*virtual*/ void paramChanged(const Param& changed_param, bool user_provided)
+ {
+ param_handle_t changed_param_handle = base_block_t::getHandleFromParam(&changed_param);
+ // if we have a new choice...
+ if (changed_param_handle != mCurChoice)
+ {
+ // clear provided flag on previous choice
+ Param* previous_choice = base_block_t::getParamFromHandle(mCurChoice);
+ if (previous_choice)
+ {
+ previous_choice->setProvided(false);
+ }
+ mCurChoice = changed_param_handle;
+ }
+ base_block_t::paramChanged(changed_param, user_provided);
+ }
+
+ virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return getBlockDescriptor(); }
+ virtual BlockDescriptor& mostDerivedBlockDescriptor() { return getBlockDescriptor(); }
+
+ protected:
+ ChoiceBlock()
+ : mCurChoice(0)
+ {
+ BaseBlock::init(getBlockDescriptor(), base_block_t::getBlockDescriptor(), sizeof(DERIVED_BLOCK));
+ }
+
+ // Alternatives are mutually exclusive wrt other Alternatives in the same block.
+ // One alternative in a block will always have isChosen() == true.
+ // At most one alternative in a block will have isProvided() == true.
+ template <typename T, typename NAME_VALUE_LOOKUP = typename TypeValues<T>::type_value_t >
+ class Alternative : public TypedParam<T, NAME_VALUE_LOOKUP, false>
+ {
+ typedef TypedParam<T, NAME_VALUE_LOOKUP, false> super_t;
+ typedef typename super_t::value_t value_t;
+ typedef typename super_t::default_value_t default_value_t;
+
+ public:
+ friend class ChoiceBlock<DERIVED_BLOCK>;
+
+ using super_t::operator =;
+
+ explicit Alternative(const char* name = "", const default_value_t& val = defaultValue<default_value_t>())
+ : super_t(DERIVED_BLOCK::getBlockDescriptor(), name, val, NULL, 0, 1),
+ mOriginalValue(val)
+ {
+ // assign initial choice to first declared option
+ DERIVED_BLOCK* blockp = ((DERIVED_BLOCK*)DERIVED_BLOCK::getBlockDescriptor().mCurrentBlockPtr);
+ if (LL_UNLIKELY(DERIVED_BLOCK::getBlockDescriptor().mInitializationState == BlockDescriptor::INITIALIZING))
+ {
+ if(blockp->mCurChoice == 0)
+ {
+ blockp->mCurChoice = Param::enclosingBlock().getHandleFromParam(this);
+ }
+ }
+ }
+
+ void choose()
+ {
+ static_cast<enclosing_block_t&>(Param::enclosingBlock()).paramChanged(*this, true);
+ }
+
+ void chooseAs(const value_t& val)
+ {
+ super_t::set(val);
+ }
+
+ void operator =(const value_t& val)
+ {
+ super_t::set(val);
+ }
+
+ void operator()(const value_t& val)
+ {
+ super_t::set(val);
+ }
+
+ operator const value_t&() const
+ {
+ return (*this)();
+ }
+
+ const value_t& operator()() const
+ {
+ if (static_cast<enclosing_block_t&>(Param::enclosingBlock()).getCurrentChoice() == this)
+ {
+ return super_t::getValue();
+ }
+ return mOriginalValue;
+ }
+
+ bool isChosen() const
+ {
+ return static_cast<enclosing_block_t&>(Param::enclosingBlock()).getCurrentChoice() == this;
+ }
+
+ private:
+ default_value_t mOriginalValue;
+ };
+
+ public:
+ static BlockDescriptor& getBlockDescriptor()
+ {
+ static BlockDescriptor sBlockDescriptor;
+ return sBlockDescriptor;
+ }
+
+ private:
+ param_handle_t mCurChoice;
+
+ const Param* getCurrentChoice() const
+ {
+ return base_block_t::getParamFromHandle(mCurChoice);
+ }
+ };
+
+ template <typename DERIVED_BLOCK, typename BASE_BLOCK = BaseBlock>
+ class Block
+ : public BASE_BLOCK
+ {
+ typedef Block<DERIVED_BLOCK, BASE_BLOCK> self_t;
+
+ protected:
+ typedef Block<DERIVED_BLOCK, BASE_BLOCK> block_t;
+
+ public:
+ typedef BASE_BLOCK base_block_t;
+
+ // take all provided params from other and apply to self
+ bool overwriteFrom(const self_t& other)
+ {
+ return static_cast<DERIVED_BLOCK*>(this)->mergeBlock(getBlockDescriptor(), other, true);
+ }
+
+ // take all provided params that are not already provided, and apply to self
+ bool fillFrom(const self_t& other)
+ {
+ return static_cast<DERIVED_BLOCK*>(this)->mergeBlock(getBlockDescriptor(), other, false);
+ }
+
+ virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return getBlockDescriptor(); }
+ virtual BlockDescriptor& mostDerivedBlockDescriptor() { return getBlockDescriptor(); }
+
+ protected:
+ Block()
+ {
+ //#pragma message("Parsing LLInitParam::Block")
+ BaseBlock::init(getBlockDescriptor(), BASE_BLOCK::getBlockDescriptor(), sizeof(DERIVED_BLOCK));
+ }
+
+ //
+ // Nested classes for declaring parameters
+ //
+ template <typename T, typename NAME_VALUE_LOOKUP = typename TypeValues<T>::type_value_t >
+ class Optional : public TypedParam<T, NAME_VALUE_LOOKUP, false>
+ {
+ typedef TypedParam<T, NAME_VALUE_LOOKUP, false> super_t;
+ typedef typename super_t::value_t value_t;
+ typedef typename super_t::default_value_t default_value_t;
+
+ public:
+ using super_t::operator();
+ using super_t::operator =;
+
+ explicit Optional(const char* name = "", const default_value_t& val = defaultValue<default_value_t>())
+ : super_t(DERIVED_BLOCK::getBlockDescriptor(), name, val, NULL, 0, 1)
+ {
+ //#pragma message("Parsing LLInitParam::Block::Optional")
+ }
+
+ Optional& operator =(const value_t& val)
+ {
+ set(val);
+ return *this;
+ }
+
+ DERIVED_BLOCK& operator()(const value_t& val)
+ {
+ super_t::set(val);
+ return static_cast<DERIVED_BLOCK&>(Param::enclosingBlock());
+ }
+ };
+
+ template <typename T, typename NAME_VALUE_LOOKUP = typename TypeValues<T>::type_value_t >
+ class Mandatory : public TypedParam<T, NAME_VALUE_LOOKUP, false>
+ {
+ typedef TypedParam<T, NAME_VALUE_LOOKUP, false> super_t;
+ typedef Mandatory<T, NAME_VALUE_LOOKUP> self_t;
+ typedef typename super_t::value_t value_t;
+ typedef typename super_t::default_value_t default_value_t;
+
+ public:
+ using super_t::operator();
+ using super_t::operator =;
+
+ // mandatory parameters require a name to be parseable
+ explicit Mandatory(const char* name = "", const default_value_t& val = defaultValue<default_value_t>())
+ : super_t(DERIVED_BLOCK::getBlockDescriptor(), name, val, &validate, 1, 1)
+ {}
+
+ Mandatory& operator =(const value_t& val)
+ {
+ set(val);
+ return *this;
+ }
+
+ DERIVED_BLOCK& operator()(const value_t& val)
+ {
+ super_t::set(val);
+ return static_cast<DERIVED_BLOCK&>(Param::enclosingBlock());
+ }
+
+ static bool validate(const Param* p)
+ {
+ // valid only if provided
+ return static_cast<const self_t*>(p)->isProvided();
+ }
+
+ };
+
+ template <typename T, typename RANGE = BaseBlock::AnyAmount, typename NAME_VALUE_LOOKUP = typename TypeValues<T>::type_value_t >
+ class Multiple : public TypedParam<T, NAME_VALUE_LOOKUP, true>
+ {
+ typedef TypedParam<T, NAME_VALUE_LOOKUP, true> super_t;
+ typedef Multiple<T, RANGE, NAME_VALUE_LOOKUP> self_t;
+ typedef typename super_t::container_t container_t;
+ typedef typename super_t::value_t value_t;
+
+ public:
+ typedef typename super_t::iterator iterator;
+ typedef typename super_t::const_iterator const_iterator;
+
+ explicit Multiple(const char* name = "")
+ : super_t(DERIVED_BLOCK::getBlockDescriptor(), name, container_t(), &validate, RANGE::minCount, RANGE::maxCount)
+ {}
+
+ Multiple& operator =(const container_t& val)
+ {
+ set(val);
+ return *this;
+ }
+
+ DERIVED_BLOCK& operator()(const container_t& val)
+ {
+ super_t::set(val);
+ return static_cast<DERIVED_BLOCK&>(Param::enclosingBlock());
+ }
+
+ static bool validate(const Param* paramp)
+ {
+ U32 num_valid = ((super_t*)paramp)->numValidElements();
+ return RANGE::minCount <= num_valid && num_valid <= RANGE::maxCount;
+ }
+ };
+
+ // can appear in data files, but will ignored during parsing
+ // cannot read or write in code
+ class Ignored : public Param
+ {
+ public:
+ explicit Ignored(const char* name)
+ : Param(DERIVED_BLOCK::getBlockDescriptor().mCurrentBlockPtr)
+ {
+ BlockDescriptor& block_descriptor = DERIVED_BLOCK::getBlockDescriptor();
+ if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))
+ {
+ ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor(
+ block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
+ NULL,
+ &deserializeParam,
+ NULL,
+ NULL,
+ NULL,
+ 0, S32_MAX));
+ block_descriptor.addParam(param_descriptor, name);
+ }
+ }
+
+ static bool deserializeParam(Param& param, Parser& parser, Parser::name_stack_range_t& name_stack_range, bool new_name)
+ {
+ if (name_stack_range.first == name_stack_range.second)
+ {
+ //std::string message = llformat("Deprecated value %s ignored", getName().c_str());
+ //parser.parserWarning(message);
+ return true;
+ }
+
+ return false;
+ }
+ };
+
+ // can appear in data files, or be written to in code, but data will be ignored
+ // cannot be read in code
+ class Deprecated : public Ignored
+ {
+ public:
+ explicit Deprecated(const char* name) : Ignored(name) {}
+
+ // dummy writer interfaces
+ template<typename T>
+ Deprecated& operator =(const T& val)
+ {
+ // do nothing
+ return *this;
+ }
+
+ template<typename T>
+ DERIVED_BLOCK& operator()(const T& val)
+ {
+ // do nothing
+ return static_cast<DERIVED_BLOCK&>(Param::enclosingBlock());
+ }
+
+ template<typename T>
+ void set(const T& val, bool flag_as_provided = true)
+ {
+ // do nothing
+ }
+ };
+
+ public:
+ static BlockDescriptor& getBlockDescriptor()
+ {
+ static BlockDescriptor sBlockDescriptor;
+ return sBlockDescriptor;
+ }
+
+ protected:
+ template <typename T, typename NAME_VALUE_LOOKUP, bool multiple, typename is_block>
+ void changeDefault(TypedParam<T, NAME_VALUE_LOOKUP, multiple, is_block>& param,
+ const typename TypedParam<T, NAME_VALUE_LOOKUP, multiple, is_block>::value_t& value)
+ {
+ if (!param.isProvided())
+ {
+ param.set(value, false);
+ }
+ }
+
+ };
+
+ template<typename T, typename BLOCK_T>
+ struct IsBlock<ParamValue<BaseBlock::Lazy<T, BaseBlock::IS_A_BLOCK>, BLOCK_T >, void>
+ {
+ typedef IS_A_BLOCK value_t;
+ };
+
+ template<typename T, typename BLOCK_T>
+ struct IsBlock<ParamValue<BaseBlock::Lazy<T, BaseBlock::NOT_A_BLOCK>, BLOCK_T >, void>
+ {
+ typedef NOT_BLOCK value_t;
+ };
+
+ template<typename T, typename BLOCK_IDENTIFIER>
+ struct IsBlock<ParamValue<BaseBlock::Atomic<T>, typename IsBlock<BaseBlock::Atomic<T> >::value_t >, BLOCK_IDENTIFIER>
+ {
+ typedef typename IsBlock<T>::value_t value_t;
+ };
+
+ template<typename T, typename BLOCK_IDENTIFIER>
+ struct IsBlock<ParamValue<BaseBlock::Sequential<T>, typename IsBlock<BaseBlock::Sequential<T> >::value_t >, BLOCK_IDENTIFIER>
+ {
+ typedef typename IsBlock<T>::value_t value_t;
+ };
+
+
+ template<typename T>
+ struct InnerMostType
+ {
+ typedef T value_t;
+ };
+
+ template<typename T>
+ struct InnerMostType<ParamValue<T, NOT_BLOCK> >
+ {
+ typedef typename InnerMostType<T>::value_t value_t;
+ };
+
+ template<typename T>
+ struct InnerMostType<ParamValue<T, IS_A_BLOCK> >
+ {
+ typedef typename InnerMostType<T>::value_t value_t;
+ };
+
+ template<typename T, typename BLOCK_T>
+ class ParamValue <BaseBlock::Atomic<T>, BLOCK_T>
+ {
+ typedef ParamValue <BaseBlock::Atomic<T>, BLOCK_T> self_t;
+
+ public:
+ typedef typename InnerMostType<T>::value_t value_t;
+ typedef T default_value_t;
+
+ ParamValue()
+ : mValue(),
+ mValidated(false)
+ {}
+
+ ParamValue(const default_value_t& value)
+ : mValue(value),
+ mValidated(false)
+ {}
+
+ void setValue(const value_t& val)
+ {
+ mValue.setValue(val);
+ }
+
+ const value_t& getValue() const
+ {
+ return mValue.getValue();
+ }
+
+ value_t& getValue()
+ {
+ return mValue.getValue();
+ }
+
+ bool deserializeBlock(Parser& p, Parser::name_stack_range_t& name_stack_range, bool new_name)
+ {
+ if (new_name)
+ {
+ resetToDefault();
+ }
+ return mValue.deserializeBlock(p, name_stack_range, new_name);
+ }
+
+ void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const self_t* diff_block = NULL) const
+ {
+ const BaseBlock* base_block = diff_block
+ ? &(diff_block->mValue)
+ : NULL;
+ mValue.serializeBlock(p, name_stack, base_block);
+ }
+
+ bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const
+ {
+ return mValue.inspectBlock(p, name_stack, min_count, max_count);
+ }
+
+ bool mergeBlockParam(bool source_provided, bool dst_provided, BlockDescriptor& block_data, const self_t& source, bool overwrite)
+ {
+ if ((overwrite && source_provided) // new values coming in on top or...
+ || (!overwrite && !dst_provided)) // values being pushed under with nothing already there
+ {
+ // clear away what is there and take the new stuff as a whole
+ resetToDefault();
+ return mValue.mergeBlock(block_data, source.getValue(), overwrite);
+ }
+
+
+ return mValue.mergeBlock(block_data, source.getValue(), overwrite);
+ }
+
+ bool validateBlock(bool emit_errors = true) const
+ {
+ return mValue.validateBlock(emit_errors);
+ }
+
+ static BlockDescriptor& getBlockDescriptor()
+ {
+ return value_t::getBlockDescriptor();
+ }
+
+
+ mutable bool mValidated; // lazy validation flag
+
+ private:
+ void resetToDefault()
+ {
+ static T default_value;
+ mValue = default_value;
+ }
+
+ T mValue;
+ };
+
+ template<typename T>
+ class ParamValue <BaseBlock::Sequential<T>, IS_A_BLOCK>
+ {
+ typedef ParamValue <BaseBlock::Sequential<T>, IS_A_BLOCK> self_t;
+
+ public:
+ typedef typename InnerMostType<T>::value_t value_t;
+ typedef T default_value_t;
+
+ ParamValue()
+ : mValue(),
+ mValidated(false)
+ {
+ mCurParam = getBlockDescriptor().mAllParams.begin();
+ }
+
+ ParamValue(const default_value_t& value)
+ : mValue(value),
+ mValidated(false)
+ {
+ mCurParam = getBlockDescriptor().mAllParams.begin();
+ }
+
+ void setValue(const value_t& val)
+ {
+ mValue.setValue(val);
+ }
+
+ const value_t& getValue() const
+ {
+ return mValue.getValue();
+ }
+
+ value_t& getValue()
+ {
+ return mValue.getValue();
+ }
+
+ bool deserializeBlock(Parser& p, Parser::name_stack_range_t& name_stack_range, bool new_name)
+ {
+ if (new_name)
+ {
+ mCurParam = getBlockDescriptor().mAllParams.begin();
+ }
+ if (name_stack_range.first == name_stack_range.second
+ && mCurParam != getBlockDescriptor().mAllParams.end())
+ {
+ // deserialize to mCurParam
+ ParamDescriptor& pd = *(*mCurParam);
+ ParamDescriptor::deserialize_func_t deserialize_func = pd.mDeserializeFunc;
+ Param* paramp = mValue.getParamFromHandle(pd.mParamHandle);
+
+ if (deserialize_func
+ && paramp
+ && deserialize_func(*paramp, p, name_stack_range, new_name))
+ {
+ ++mCurParam;
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ else
+ {
+ return mValue.deserializeBlock(p, name_stack_range, new_name);
+ }
+ }
+
+ void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const self_t* diff_block = NULL) const
+ {
+ const BaseBlock* base_block = diff_block
+ ? &(diff_block->mValue)
+ : NULL;
+ mValue.serializeBlock(p, name_stack, base_block);
+ }
+
+ bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const
+ {
+ return mValue.inspectBlock(p, name_stack, min_count, max_count);
+ }
+
+ bool mergeBlockParam(bool source_provided, bool dst_provided, BlockDescriptor& block_data, const self_t& source, bool overwrite)
+ {
+ return mValue.mergeBlock(block_data, source.getValue(), overwrite);
+ }
+
+ bool validateBlock(bool emit_errors = true) const
+ {
+ return mValue.validateBlock(emit_errors);
+ }
+
+ static BlockDescriptor& getBlockDescriptor()
+ {
+ return value_t::getBlockDescriptor();
+ }
+
+ mutable bool mValidated; // lazy validation flag
+
+ private:
+
+ BlockDescriptor::all_params_list_t::iterator mCurParam;
+ T mValue;
+ };
+
+ template<typename T>
+ class ParamValue <BaseBlock::Sequential<T>, NOT_BLOCK>
+ : public T
+ {
+ typedef ParamValue <BaseBlock::Sequential<T>, NOT_BLOCK> self_t;
+
+ public:
+ typedef typename InnerMostType<T>::value_t value_t;
+ typedef T default_value_t;
+
+ ParamValue()
+ : T(),
+ mValidated(false)
+ {}
+
+ ParamValue(const default_value_t& value)
+ : T(value.getValue()),
+ mValidated(false)
+ {}
+
+ mutable bool mValidated; // lazy validation flag
+ };
+
+ template<typename T, typename BLOCK_T>
+ class ParamValue <BaseBlock::Lazy<T, IS_A_BLOCK>, BLOCK_T>
+ {
+ typedef ParamValue <BaseBlock::Lazy<T, IS_A_BLOCK>, BLOCK_T> self_t;
+
+ public:
+ typedef typename InnerMostType<T>::value_t value_t;
+ typedef LazyValue<T> default_value_t;
+
+ ParamValue()
+ : mValue(),
+ mValidated(false)
+ {}
+
+ ParamValue(const default_value_t& other)
+ : mValue(other),
+ mValidated(false)
+ {}
+
+ ParamValue(const T& value)
+ : mValue(value),
+ mValidated(false)
+ {}
+
+ void setValue(const value_t& val)
+ {
+ mValue.set(val);
+ }
+
+ const value_t& getValue() const
+ {
+ return mValue.get().getValue();
+ }
+
+ value_t& getValue()
+ {
+ return mValue.get().getValue();
+ }
+
+ bool deserializeBlock(Parser& p, Parser::name_stack_range_t& name_stack_range, bool new_name)
+ {
+ return mValue.get().deserializeBlock(p, name_stack_range, new_name);
+ }
+
+ void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const self_t* diff_block = NULL) const
+ {
+ if (mValue.empty()) return;
+
+ const BaseBlock* base_block = (diff_block && !diff_block->mValue.empty())
+ ? &(diff_block->mValue.get().getValue())
+ : NULL;
+ mValue.get().serializeBlock(p, name_stack, base_block);
+ }
+
+ bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const
+ {
+ return mValue.get().inspectBlock(p, name_stack, min_count, max_count);
+ }
+
+ bool mergeBlockParam(bool source_provided, bool dst_provided, BlockDescriptor& block_data, const self_t& source, bool overwrite)
+ {
+ return source.mValue.empty() || mValue.get().mergeBlock(block_data, source.getValue(), overwrite);
+ }
+
+ bool validateBlock(bool emit_errors = true) const
+ {
+ return mValue.empty() || mValue.get().validateBlock(emit_errors);
+ }
+
+ static BlockDescriptor& getBlockDescriptor()
+ {
+ return value_t::getBlockDescriptor();
+ }
+
+ mutable bool mValidated; // lazy validation flag
+
+ private:
+ LazyValue<T> mValue;
+ };
+
+ template<typename T, typename BLOCK_T>
+ class ParamValue <BaseBlock::Lazy<T, NOT_BLOCK>, BLOCK_T>
+ {
+ typedef ParamValue <BaseBlock::Lazy<T, NOT_BLOCK>, BLOCK_T> self_t;
+
+ public:
+ typedef typename InnerMostType<T>::value_t value_t;
+ typedef LazyValue<T> default_value_t;
+
+ ParamValue()
+ : mValue(),
+ mValidated(false)
+ {}
+
+ ParamValue(const default_value_t& other)
+ : mValue(other),
+ mValidated(false)
+ {}
+
+ ParamValue(const T& value)
+ : mValue(value),
+ mValidated(false)
+ {}
+
+ void setValue(const value_t& val)
+ {
+ mValue.set(val);
+ }
+
+ const value_t& getValue() const
+ {
+ return mValue.get().getValue();
+ }
+
+ value_t& getValue()
+ {
+ return mValue.get().getValue();
+ }
+
+ mutable bool mValidated; // lazy validation flag
+
+ private:
+ LazyValue<T> mValue;
+ };
+
+ template <>
+ class ParamValue <LLSD, NOT_BLOCK>
+ : public BaseBlock
+ {
+ public:
+ typedef LLSD value_t;
+ typedef LLSD default_value_t;
+
+ ParamValue()
+ : mValidated(false)
+ {}
+
+ ParamValue(const default_value_t& other)
+ : mValue(other),
+ mValidated(false)
+ {}
+
+ void setValue(const value_t& val) { mValue = val; }
+
+ const value_t& getValue() const { return mValue; }
+ LLSD& getValue() { return mValue; }
+
+ // block param interface
+ LL_COMMON_API bool deserializeBlock(Parser& p, Parser::name_stack_range_t& name_stack_range, bool new_name);
+ LL_COMMON_API void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const BaseBlock* diff_block = NULL) const;
+ bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const
+ {
+ //TODO: implement LLSD params as schema type Any
+ return true;
+ }
+
+ protected:
+ mutable bool mValidated; // lazy validation flag
+
+ private:
+ static void serializeElement(Parser& p, const LLSD& sd, Parser::name_stack_t& name_stack);
+
+ LLSD mValue;
+ };
+
+ template<typename T>
+ class CustomParamValue
+ : public Block<ParamValue<T> >
+ {
+ public:
+ typedef enum e_value_age
+ {
+ VALUE_NEEDS_UPDATE, // mValue needs to be refreshed from the block parameters
+ VALUE_AUTHORITATIVE, // mValue holds the authoritative value (which has been replicated to the block parameters via updateBlockFromValue)
+ BLOCK_AUTHORITATIVE // mValue is derived from the block parameters, which are authoritative
+ } EValueAge;
+
+ typedef ParamValue<T> derived_t;
+ typedef CustomParamValue<T> self_t;
+ typedef Block<derived_t> block_t;
+ typedef T default_value_t;
+ typedef T value_t;
+ typedef void baseblock_base_class_t;
+
+
+ CustomParamValue(const default_value_t& value = T())
+ : mValue(value),
+ mValueAge(VALUE_AUTHORITATIVE),
+ mValidated(false)
+ {}
+
+ bool deserializeBlock(Parser& parser, Parser::name_stack_range_t& name_stack_range, bool new_name)
+ {
+ derived_t& typed_param = static_cast<derived_t&>(*this);
+ // try to parse direct value T
+ if (name_stack_range.first == name_stack_range.second)
+ {
+ if(parser.readValue(typed_param.mValue))
+ {
+ typed_param.mValueAge = VALUE_AUTHORITATIVE;
+ typed_param.updateBlockFromValue(false);
+
+ return true;
+ }
+ }
+
+ // fall back on parsing block components for T
+ return typed_param.BaseBlock::deserializeBlock(parser, name_stack_range, new_name);
+ }
+
+ void serializeBlock(Parser& parser, Parser::name_stack_t& name_stack, const BaseBlock* diff_block = NULL) const
+ {
+ const derived_t& typed_param = static_cast<const derived_t&>(*this);
+ const derived_t* diff_param = static_cast<const derived_t*>(diff_block);
+
+ // then try to serialize value directly
+ if (!diff_param || !ParamCompare<T>::equals(typed_param.getValue(), diff_param->getValue()))
+ {
+
+ if (!parser.writeValue(typed_param.getValue(), name_stack))
+ {
+ //RN: *always* serialize provided components of BlockValue (don't pass diff_param on),
+ // since these tend to be viewed as the constructor arguments for the value T. It seems
+ // cleaner to treat the uniqueness of a BlockValue according to the generated value, and
+ // not the individual components. This way <color red="0" green="1" blue="0"/> will not
+ // be exported as <color green="1"/>, since it was probably the intent of the user to
+ // be specific about the RGB color values. This also fixes an issue where we distinguish
+ // between rect.left not being provided and rect.left being explicitly set to 0 (same as default)
+
+ if (typed_param.mValueAge == VALUE_AUTHORITATIVE)
+ {
+ // if the value is authoritative but the parser doesn't accept the value type
+ // go ahead and make a copy, and splat the value out to its component params
+ // and serialize those params
+ derived_t copy(typed_param);
+ copy.updateBlockFromValue(true);
+ copy.block_t::serializeBlock(parser, name_stack, NULL);
+ }
+ else
+ {
+ block_t::serializeBlock(parser, name_stack, NULL);
+ }
+ }
+ }
+ }
+
+ bool validateBlock(bool emit_errors = true) const
+ {
+ if (mValueAge == VALUE_NEEDS_UPDATE)
+ {
+ if (block_t::validateBlock(emit_errors))
+ {
+ // clear stale keyword associated with old value
+ mValueAge = BLOCK_AUTHORITATIVE;
+ static_cast<derived_t*>(const_cast<self_t*>(this))->updateValueFromBlock();
+ return true;
+ }
+ else
+ {
+ //block value incomplete, so not considered provided
+ // will attempt to revalidate on next call to isProvided()
+ return false;
+ }
+ }
+ else
+ {
+ // we have a valid value in hand
+ return true;
+ }
+ }
+
+ // propagate change status up to enclosing block
+ /*virtual*/ void paramChanged(const Param& changed_param, bool user_provided)
+ {
+ BaseBlock::paramChanged(changed_param, user_provided);
+ if (user_provided)
+ {
+ // a parameter changed, so our value is out of date
+ mValueAge = VALUE_NEEDS_UPDATE;
+ }
+ }
+
+ void setValue(const value_t& val)
+ {
+ // set param version number to be up to date, so we ignore block contents
+ mValueAge = VALUE_AUTHORITATIVE;
+ mValue = val;
+ static_cast<derived_t*>(this)->updateBlockFromValue(false);
+ }
+
+ const value_t& getValue() const
+ {
+ validateBlock(true);
+ return mValue;
+ }
+
+ T& getValue()
+ {
+ validateBlock(true);
+ return mValue;
+ }
+
+ protected:
+
+ // use this from within updateValueFromBlock() to set the value without making it authoritative
+ void updateValue(const value_t& value)
+ {
+ mValue = value;
+ }
+
+ bool mergeBlockParam(bool source_provided, bool dst_provided, BlockDescriptor& block_data, const BaseBlock& source, bool overwrite)
+ {
+ bool source_override = source_provided && (overwrite || !dst_provided);
+
+ const derived_t& src_typed_param = static_cast<const derived_t&>(source);
+
+ if (source_override && src_typed_param.mValueAge == VALUE_AUTHORITATIVE)
+ {
+ // copy value over
+ setValue(src_typed_param.getValue());
+ return true;
+ }
+ // merge individual parameters into destination
+ if (mValueAge == VALUE_AUTHORITATIVE)
+ {
+ static_cast<derived_t*>(this)->updateBlockFromValue(dst_provided);
+ }
+ return mergeBlock(block_data, source, overwrite);
+ }
+
+ bool mergeBlock(BlockDescriptor& block_data, const BaseBlock& source, bool overwrite)
+ {
+ return block_t::mergeBlock(block_data, source, overwrite);
+ }
+
+ mutable bool mValidated; // lazy validation flag
+
+ private:
+ mutable T mValue;
+ mutable EValueAge mValueAge;
+ };
+}
+
+
+#endif // LL_LLPARAM_H
diff --git a/indra/llcommon/llinstancetracker.cpp b/indra/llcommon/llinstancetracker.cpp
index 5dc3ea5d7b..64a313b5ff 100644..100755
--- a/indra/llcommon/llinstancetracker.cpp
+++ b/indra/llcommon/llinstancetracker.cpp
@@ -32,18 +32,3 @@
// external library headers
// other Linden headers
-//static
-void * & LLInstanceTrackerBase::getInstances(std::type_info const & info)
-{
- typedef std::map<std::string, void *> InstancesMap;
- static InstancesMap instances;
-
- // std::map::insert() is just what we want here. You attempt to insert a
- // (key, value) pair. If the specified key doesn't yet exist, it inserts
- // the pair and returns a std::pair of (iterator, true). If the specified
- // key DOES exist, insert() simply returns (iterator, false). One lookup
- // handles both cases.
- return instances.insert(InstancesMap::value_type(info.name(),
- InstancesMap::mapped_type()))
- .first->second;
-}
diff --git a/indra/llcommon/llinstancetracker.h b/indra/llcommon/llinstancetracker.h
index 34d841a4e0..55187d8325 100644..100755
--- a/indra/llcommon/llinstancetracker.h
+++ b/indra/llcommon/llinstancetracker.h
@@ -43,24 +43,10 @@
* semantics: one instance per process, rather than one instance per module as
* sometimes happens with data simply declared static.
*/
-class LL_COMMON_API LLInstanceTrackerBase : public boost::noncopyable
+class LL_COMMON_API LLInstanceTrackerBase
{
protected:
- /// Get a process-unique void* pointer slot for the specified type_info
- static void * & getInstances(std::type_info const & info);
- /// Find or create a STATICDATA instance for the specified TRACKED class.
- /// STATICDATA must be default-constructible.
- template<typename STATICDATA, class TRACKED>
- static STATICDATA& getStatic()
- {
- void *& instances = getInstances(typeid(TRACKED));
- if (! instances)
- {
- instances = new STATICDATA;
- }
- return *static_cast<STATICDATA*>(instances);
- }
/// It's not essential to derive your STATICDATA (for use with
/// getStatic()) from StaticBase; it's just that both known
@@ -74,6 +60,8 @@ protected:
};
};
+LL_COMMON_API void assert_main_thread();
+
/// This mix-in class adds support for tracking all instances of the specified class parameter T
/// The (optional) key associates a value of type KEY with a given instance of T, for quick lookup
/// If KEY is not provided, then instances are stored in a simple set
@@ -81,14 +69,18 @@ protected:
template<typename T, typename KEY = T*>
class LLInstanceTracker : public LLInstanceTrackerBase
{
- typedef LLInstanceTracker<T, KEY> MyT;
+ typedef LLInstanceTracker<T, KEY> self_t;
typedef typename std::map<KEY, T*> InstanceMap;
struct StaticData: public StaticBase
{
InstanceMap sMap;
};
- static StaticData& getStatic() { return LLInstanceTrackerBase::getStatic<StaticData, MyT>(); }
- static InstanceMap& getMap_() { return getStatic().sMap; }
+ static StaticData& getStatic() { static StaticData sData; return sData;}
+ static InstanceMap& getMap_()
+ {
+ // assert_main_thread(); fwiw this class is not thread safe, and it used by multiple threads. Bad things happen.
+ return getStatic().sMap;
+ }
public:
class instance_iter : public boost::iterator_facade<instance_iter, T, boost::forward_traversal_tag>
@@ -167,8 +159,9 @@ public:
static T* getInstance(const KEY& k)
{
- typename InstanceMap::const_iterator found = getMap_().find(k);
- return (found == getMap_().end()) ? NULL : found->second;
+ const InstanceMap& map(getMap_());
+ typename InstanceMap::const_iterator found = map.find(k);
+ return (found == map.end()) ? NULL : found->second;
}
static instance_iter beginInstances()
@@ -209,6 +202,9 @@ protected:
virtual const KEY& getKey() const { return mInstanceKey; }
private:
+ LLInstanceTracker( const LLInstanceTracker& );
+ const LLInstanceTracker& operator=( const LLInstanceTracker& );
+
void add_(KEY key)
{
mInstanceKey = key;
@@ -216,7 +212,11 @@ private:
}
void remove_()
{
- getMap_().erase(mInstanceKey);
+ typename InstanceMap::iterator iter = getMap_().find(mInstanceKey);
+ if (iter != getMap_().end())
+ {
+ getMap_().erase(iter);
+ }
}
private:
@@ -228,19 +228,31 @@ private:
template<typename T>
class LLInstanceTracker<T, T*> : public LLInstanceTrackerBase
{
- typedef LLInstanceTracker<T, T*> MyT;
+ typedef LLInstanceTracker<T, T*> self_t;
typedef typename std::set<T*> InstanceSet;
struct StaticData: public StaticBase
{
InstanceSet sSet;
};
- static StaticData& getStatic() { return LLInstanceTrackerBase::getStatic<StaticData, MyT>(); }
+ static StaticData& getStatic() { static StaticData sData; return sData; }
static InstanceSet& getSet_() { return getStatic().sSet; }
public:
- /// for completeness of analogy with the generic implementation
- static T* getInstance(T* k) { return k; }
+ /**
+ * Does a particular instance still exist? Of course, if you already have
+ * a T* in hand, you need not call getInstance() to @em locate the
+ * instance -- unlike the case where getInstance() accepts some kind of
+ * key. Nonetheless this method is still useful to @em validate a
+ * particular T*, since each instance's destructor removes itself from the
+ * underlying set.
+ */
+ static T* getInstance(T* k)
+ {
+ const InstanceSet& set(getSet_());
+ typename InstanceSet::const_iterator found = set.find(k);
+ return (found == set.end())? NULL : *found;
+ }
static S32 instanceCount() { return getSet_().size(); }
class instance_iter : public boost::iterator_facade<instance_iter, T, boost::forward_traversal_tag>
diff --git a/indra/llcommon/llkeythrottle.h b/indra/llcommon/llkeythrottle.h
index 1f576cc19e..1f576cc19e 100644..100755
--- a/indra/llcommon/llkeythrottle.h
+++ b/indra/llcommon/llkeythrottle.h
diff --git a/indra/llcommon/llkeyusetracker.h b/indra/llcommon/llkeyusetracker.h
index 1fb222dd40..1fb222dd40 100644..100755
--- a/indra/llcommon/llkeyusetracker.h
+++ b/indra/llcommon/llkeyusetracker.h
diff --git a/indra/llcommon/lllazy.cpp b/indra/llcommon/lllazy.cpp
index 29fa040387..29fa040387 100644..100755
--- a/indra/llcommon/lllazy.cpp
+++ b/indra/llcommon/lllazy.cpp
diff --git a/indra/llcommon/lllazy.h b/indra/llcommon/lllazy.h
index 5f3bbce79e..5f3bbce79e 100644..100755
--- a/indra/llcommon/lllazy.h
+++ b/indra/llcommon/lllazy.h
diff --git a/indra/llcommon/llleap.cpp b/indra/llcommon/llleap.cpp
new file mode 100755
index 0000000000..0a57ef1c48
--- /dev/null
+++ b/indra/llcommon/llleap.cpp
@@ -0,0 +1,459 @@
+/**
+ * @file llleap.cpp
+ * @author Nat Goodspeed
+ * @date 2012-02-20
+ * @brief Implementation for llleap.
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Copyright (c) 2012, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+// Precompiled header
+#include "linden_common.h"
+// associated header
+#include "llleap.h"
+// STL headers
+#include <sstream>
+#include <algorithm>
+// std headers
+// external library headers
+#include <boost/bind.hpp>
+#include <boost/scoped_ptr.hpp>
+#include <boost/tokenizer.hpp>
+// other Linden headers
+#include "llerror.h"
+#include "llstring.h"
+#include "llprocess.h"
+#include "llevents.h"
+#include "stringize.h"
+#include "llsdutil.h"
+#include "llsdserialize.h"
+#include "llerrorcontrol.h"
+#include "lltimer.h"
+#include "lluuid.h"
+#include "llleaplistener.h"
+
+#if LL_MSVC
+#pragma warning (disable : 4355) // 'this' used in initializer list: yes, intentionally
+#endif
+
+LLLeap::LLLeap() {}
+LLLeap::~LLLeap() {}
+
+class LLLeapImpl: public LLLeap
+{
+ LOG_CLASS(LLLeap);
+public:
+ // Called only by LLLeap::create()
+ LLLeapImpl(const std::string& desc, const std::vector<std::string>& plugin):
+ // We might reassign mDesc in the constructor body if it's empty here.
+ mDesc(desc),
+ // We expect multiple LLLeapImpl instances. Definitely tweak
+ // mDonePump's name for uniqueness.
+ mDonePump("LLLeap", true),
+ // Troubling thought: what if one plugin intentionally messes with
+ // another plugin? LLEventPump names are in a single global namespace.
+ // Try to make that more difficult by generating a UUID for the reply-
+ // pump name -- so it should NOT need tweaking for uniqueness.
+ mReplyPump(LLUUID::generateNewID().asString()),
+ mExpect(0),
+ mPrevFatalFunction(LLError::getFatalFunction()),
+ // Instantiate a distinct LLLeapListener for this plugin. (Every
+ // plugin will want its own collection of managed listeners, etc.)
+ // Pass it a callback to our connect() method, so it can send events
+ // from a particular LLEventPump to the plugin without having to know
+ // this class or method name.
+ mListener(new LLLeapListener(boost::bind(&LLLeapImpl::connect, this, _1, _2)))
+ {
+ // Rule out empty vector
+ if (plugin.empty())
+ {
+ throw Error("no plugin command");
+ }
+
+ // Don't leave desc empty either, but in this case, if we weren't
+ // given one, we'll fake one.
+ if (desc.empty())
+ {
+ mDesc = LLProcess::basename(plugin[0]);
+ // how about a toLower() variant that returns the transformed string?!
+ std::string desclower(mDesc);
+ LLStringUtil::toLower(desclower);
+ // If we're running a Python script, use the script name for the
+ // desc instead of just 'python'. Arguably we should check for
+ // more different interpreters as well, but there's a reason to
+ // notice Python specially: we provide Python LLSD serialization
+ // support, so there's a pretty good reason to implement plugins
+ // in that language.
+ if (plugin.size() >= 2 && (desclower == "python" || desclower == "python.exe"))
+ {
+ mDesc = LLProcess::basename(plugin[1]);
+ }
+ }
+
+ // Listen for child "termination" right away to catch launch errors.
+ mDonePump.listen("LLLeap", boost::bind(&LLLeapImpl::bad_launch, this, _1));
+
+ // Okay, launch child.
+ LLProcess::Params params;
+ params.desc = mDesc;
+ std::vector<std::string>::const_iterator pi(plugin.begin()), pend(plugin.end());
+ params.executable = *pi++;
+ for ( ; pi != pend; ++pi)
+ {
+ params.args.add(*pi);
+ }
+ params.files.add(LLProcess::FileParam("pipe")); // stdin
+ params.files.add(LLProcess::FileParam("pipe")); // stdout
+ params.files.add(LLProcess::FileParam("pipe")); // stderr
+ params.postend = mDonePump.getName();
+ mChild = LLProcess::create(params);
+ // If that didn't work, no point in keeping this LLLeap object.
+ if (! mChild)
+ {
+ throw Error(STRINGIZE("failed to run " << mDesc));
+ }
+
+ // Okay, launch apparently worked. Change our mDonePump listener.
+ mDonePump.stopListening("LLLeap");
+ mDonePump.listen("LLLeap", boost::bind(&LLLeapImpl::done, this, _1));
+
+ // Child might pump large volumes of data through either stdout or
+ // stderr. Don't bother copying all that data into notification event.
+ LLProcess::ReadPipe
+ &childout(mChild->getReadPipe(LLProcess::STDOUT)),
+ &childerr(mChild->getReadPipe(LLProcess::STDERR));
+ childout.setLimit(20);
+ childerr.setLimit(20);
+
+ // Serialize any event received on mReplyPump to our child's stdin.
+ mStdinConnection = connect(mReplyPump, "LLLeap");
+
+ // Listening on stdout is stateful. In general, we're either waiting
+ // for the length prefix or waiting for the specified length of data.
+ // We address that with two different listener methods -- one of which
+ // is blocked at any given time.
+ mStdoutConnection = childout.getPump()
+ .listen("prefix", boost::bind(&LLLeapImpl::rstdout, this, _1));
+ mStdoutDataConnection = childout.getPump()
+ .listen("data", boost::bind(&LLLeapImpl::rstdoutData, this, _1));
+ mBlocker.reset(new LLEventPump::Blocker(mStdoutDataConnection));
+
+ // Log anything sent up through stderr. When a typical program
+ // encounters an error, it writes its error message to stderr and
+ // terminates with nonzero exit code. In particular, the Python
+ // interpreter behaves that way. More generally, though, a plugin
+ // author can log whatever s/he wants to the viewer log using stderr.
+ mStderrConnection = childerr.getPump()
+ .listen("LLLeap", boost::bind(&LLLeapImpl::rstderr, this, _1));
+
+ // For our lifespan, intercept any LL_ERRS so we can notify plugin
+ LLError::setFatalFunction(boost::bind(&LLLeapImpl::fatalFunction, this, _1));
+
+ // Send child a preliminary event reporting our own reply-pump name --
+ // which would otherwise be pretty tricky to guess!
+ wstdin(mReplyPump.getName(),
+ LLSDMap
+ ("command", mListener->getName())
+ // Include LLLeap features -- this may be important for child to
+ // construct (or recognize) current protocol.
+ ("features", LLLeapListener::getFeatures()));
+ }
+
+ // Normally we'd expect to arrive here only via done()
+ virtual ~LLLeapImpl()
+ {
+ LL_DEBUGS("LLLeap") << "destroying LLLeap(\"" << mDesc << "\")" << LL_ENDL;
+ // Restore original FatalFunction
+ LLError::setFatalFunction(mPrevFatalFunction);
+ }
+
+ // Listener for failed launch attempt
+ bool bad_launch(const LLSD& data)
+ {
+ LL_WARNS("LLLeap") << data["string"].asString() << LL_ENDL;
+ return false;
+ }
+
+ // Listener for child-process termination
+ bool done(const LLSD& data)
+ {
+ // Log the termination
+ LL_INFOS("LLLeap") << data["string"].asString() << LL_ENDL;
+
+ // Any leftover data at this moment are because protocol was not
+ // satisfied. Possibly the child was interrupted in the middle of
+ // sending a message, possibly the child didn't flush stdout before
+ // terminating, possibly it's just garbage. Log its existence but
+ // discard it.
+ LLProcess::ReadPipe& childout(mChild->getReadPipe(LLProcess::STDOUT));
+ if (childout.size())
+ {
+ LLProcess::ReadPipe::size_type
+ peeklen((std::min)(LLProcess::ReadPipe::size_type(50), childout.size()));
+ LL_WARNS("LLLeap") << "Discarding final " << childout.size() << " bytes: "
+ << childout.peek(0, peeklen) << "..." << LL_ENDL;
+ }
+
+ // Kill this instance. MUST BE LAST before return!
+ delete this;
+ return false;
+ }
+
+ // Listener for events on mReplyPump: send to child stdin
+ bool wstdin(const std::string& pump, const LLSD& data)
+ {
+ LLSD packet(LLSDMap("pump", pump)("data", data));
+
+ std::ostringstream buffer;
+ buffer << LLSDNotationStreamer(packet);
+
+/*==========================================================================*|
+ // DEBUGGING ONLY: don't copy str() if we can avoid it.
+ std::string strdata(buffer.str());
+ if (std::size_t(buffer.tellp()) != strdata.length())
+ {
+ LL_ERRS("LLLeap") << "tellp() -> " << buffer.tellp() << " != "
+ << "str().length() -> " << strdata.length() << LL_ENDL;
+ }
+ // DEBUGGING ONLY: reading back is terribly inefficient.
+ std::istringstream readback(strdata);
+ LLSD echo;
+ LLPointer<LLSDParser> parser(new LLSDNotationParser());
+ S32 parse_status(parser->parse(readback, echo, strdata.length()));
+ if (parse_status == LLSDParser::PARSE_FAILURE)
+ {
+ LL_ERRS("LLLeap") << "LLSDNotationParser() cannot parse output of "
+ << "LLSDNotationStreamer()" << LL_ENDL;
+ }
+ if (! llsd_equals(echo, packet))
+ {
+ LL_ERRS("LLLeap") << "LLSDNotationParser() produced different LLSD "
+ << "than passed to LLSDNotationStreamer()" << LL_ENDL;
+ }
+|*==========================================================================*/
+
+ LL_DEBUGS("EventHost") << "Sending: " << buffer.tellp() << ':';
+ std::string::size_type truncate(80);
+ if (buffer.tellp() <= truncate)
+ {
+ LL_CONT << buffer.str();
+ }
+ else
+ {
+ LL_CONT << buffer.str().substr(0, truncate) << "...";
+ }
+ LL_CONT << LL_ENDL;
+
+ LLProcess::WritePipe& childin(mChild->getWritePipe(LLProcess::STDIN));
+ childin.get_ostream() << buffer.tellp() << ':' << buffer.str() << std::flush;
+ return false;
+ }
+
+ // Initial state of stateful listening on child stdout: wait for a length
+ // prefix, followed by ':'.
+ bool rstdout(const LLSD& data)
+ {
+ LLProcess::ReadPipe& childout(mChild->getReadPipe(LLProcess::STDOUT));
+ // It's possible we got notified of a couple digit characters without
+ // seeing the ':' -- unlikely, but still. Until we see ':', keep
+ // waiting.
+ if (childout.contains(':'))
+ {
+ std::istream& childstream(childout.get_istream());
+ // Saw ':', read length prefix and store in mExpect.
+ size_t expect;
+ childstream >> expect;
+ int colon(childstream.get());
+ if (colon != ':')
+ {
+ // Protocol failure. Clear out the rest of the pending data in
+ // childout (well, up to a max length) to log what was wrong.
+ LLProcess::ReadPipe::size_type
+ readlen((std::min)(childout.size(), LLProcess::ReadPipe::size_type(80)));
+ bad_protocol(STRINGIZE(expect << char(colon) << childout.read(readlen)));
+ }
+ else
+ {
+ // Saw length prefix, saw colon, life is good. Now wait for
+ // that length of data to arrive.
+ mExpect = expect;
+ LL_DEBUGS("LLLeap") << "got length, waiting for "
+ << mExpect << " bytes of data" << LL_ENDL;
+ // Block calls to this method; resetting mBlocker unblocks
+ // calls to the other method.
+ mBlocker.reset(new LLEventPump::Blocker(mStdoutConnection));
+ // Go check if we've already received all the advertised data.
+ if (childout.size())
+ {
+ LLSD updata(data);
+ updata["len"] = LLSD::Integer(childout.size());
+ rstdoutData(updata);
+ }
+ }
+ }
+ else if (childout.contains('\n'))
+ {
+ // Since this is the initial listening state, this is where we'd
+ // arrive if the child isn't following protocol at all -- say
+ // because the user specified 'ls' or some darn thing.
+ bad_protocol(childout.getline());
+ }
+ return false;
+ }
+
+ // State in which we listen on stdout for the specified length of data to
+ // arrive.
+ bool rstdoutData(const LLSD& data)
+ {
+ LLProcess::ReadPipe& childout(mChild->getReadPipe(LLProcess::STDOUT));
+ // Until we've accumulated the promised length of data, keep waiting.
+ if (childout.size() >= mExpect)
+ {
+ // Ready to rock and roll.
+ LL_DEBUGS("LLLeap") << "needed " << mExpect << " bytes, got "
+ << childout.size() << ", parsing LLSD" << LL_ENDL;
+ LLSD data;
+ LLPointer<LLSDParser> parser(new LLSDNotationParser());
+ S32 parse_status(parser->parse(childout.get_istream(), data, mExpect));
+ if (parse_status == LLSDParser::PARSE_FAILURE)
+ {
+ bad_protocol("unparseable LLSD data");
+ }
+ else if (! (data.isMap() && data["pump"].isString() && data.has("data")))
+ {
+ // we got an LLSD object, but it lacks required keys
+ bad_protocol("missing 'pump' or 'data'");
+ }
+ else
+ {
+ // The LLSD object we got from our stream contains the keys we
+ // need.
+ LLEventPumps::instance().obtain(data["pump"]).post(data["data"]);
+ // Block calls to this method; resetting mBlocker unblocks calls
+ // to the other method.
+ mBlocker.reset(new LLEventPump::Blocker(mStdoutDataConnection));
+ // Go check for any more pending events in the buffer.
+ if (childout.size())
+ {
+ LLSD updata(data);
+ data["len"] = LLSD::Integer(childout.size());
+ rstdout(updata);
+ }
+ }
+ }
+ return false;
+ }
+
+ void bad_protocol(const std::string& data)
+ {
+ LL_WARNS("LLLeap") << mDesc << ": invalid protocol: " << data << LL_ENDL;
+ // No point in continuing to run this child.
+ mChild->kill();
+ }
+
+ // Listen on child stderr and log everything that arrives
+ bool rstderr(const LLSD& data)
+ {
+ LLProcess::ReadPipe& childerr(mChild->getReadPipe(LLProcess::STDERR));
+ // We might have gotten a notification involving only a partial line
+ // -- or multiple lines. Read all complete lines; stop when there's
+ // only a partial line left.
+ while (childerr.contains('\n'))
+ {
+ // DO NOT make calls with side effects in a logging statement! If
+ // that log level is suppressed, your side effects WON'T HAPPEN.
+ std::string line(childerr.getline());
+ // Log the received line. Prefix it with the desc so we know which
+ // plugin it's from. This method name rstderr() is intentionally
+ // chosen to further qualify the log output.
+ LL_INFOS("LLLeap") << mDesc << ": " << line << LL_ENDL;
+ }
+ // What if child writes a final partial line to stderr?
+ if (data["eof"].asBoolean() && childerr.size())
+ {
+ std::string rest(childerr.read(childerr.size()));
+ // Read all remaining bytes and log.
+ LL_INFOS("LLLeap") << mDesc << ": " << rest << LL_ENDL;
+ }
+ return false;
+ }
+
+ void fatalFunction(const std::string& error)
+ {
+ // Notify plugin
+ LLSD event;
+ event["type"] = "error";
+ event["error"] = error;
+ mReplyPump.post(event);
+
+ // All the above really accomplished was to buffer the serialized
+ // event in our WritePipe. Have to pump mainloop a couple times to
+ // really write it out there... but time out in case we can't write.
+ LLProcess::WritePipe& childin(mChild->getWritePipe(LLProcess::STDIN));
+ LLEventPump& mainloop(LLEventPumps::instance().obtain("mainloop"));
+ LLSD nop;
+ F64 until(LLTimer::getElapsedSeconds() + 2);
+ while (childin.size() && LLTimer::getElapsedSeconds() < until)
+ {
+ mainloop.post(nop);
+ }
+
+ // forward the call to the previous FatalFunction
+ mPrevFatalFunction(error);
+ }
+
+private:
+ /// We always want to listen on mReplyPump with wstdin(); under some
+ /// circumstances we'll also echo other LLEventPumps to the plugin.
+ LLBoundListener connect(LLEventPump& pump, const std::string& listener)
+ {
+ // Serialize any event received on the specified LLEventPump to our
+ // child's stdin, suitably enriched with the pump name on which it was
+ // received.
+ return pump.listen(listener,
+ boost::bind(&LLLeapImpl::wstdin, this, pump.getName(), _1));
+ }
+
+ std::string mDesc;
+ LLEventStream mDonePump;
+ LLEventStream mReplyPump;
+ LLProcessPtr mChild;
+ LLTempBoundListener
+ mStdinConnection, mStdoutConnection, mStdoutDataConnection, mStderrConnection;
+ boost::scoped_ptr<LLEventPump::Blocker> mBlocker;
+ LLProcess::ReadPipe::size_type mExpect;
+ LLError::FatalFunction mPrevFatalFunction;
+ boost::scoped_ptr<LLLeapListener> mListener;
+};
+
+// This must follow the declaration of LLLeapImpl, so it may as well be last.
+LLLeap* LLLeap::create(const std::string& desc, const std::vector<std::string>& plugin, bool exc)
+{
+ // If caller is willing to permit exceptions, just instantiate.
+ if (exc)
+ return new LLLeapImpl(desc, plugin);
+
+ // Caller insists on suppressing LLLeap::Error. Very well, catch it.
+ try
+ {
+ return new LLLeapImpl(desc, plugin);
+ }
+ catch (const LLLeap::Error&)
+ {
+ return NULL;
+ }
+}
+
+LLLeap* LLLeap::create(const std::string& desc, const std::string& plugin, bool exc)
+{
+ // Use LLStringUtil::getTokens() to parse the command line
+ return create(desc,
+ LLStringUtil::getTokens(plugin,
+ " \t\r\n", // drop_delims
+ "", // no keep_delims
+ "\"'", // either kind of quotes
+ "\\"), // backslash escape
+ exc);
+}
diff --git a/indra/llcommon/llleap.h b/indra/llcommon/llleap.h
new file mode 100755
index 0000000000..e33f25e530
--- /dev/null
+++ b/indra/llcommon/llleap.h
@@ -0,0 +1,81 @@
+/**
+ * @file llleap.h
+ * @author Nat Goodspeed
+ * @date 2012-02-20
+ * @brief Class that implements "LLSD Event API Plugin"
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Copyright (c) 2012, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+#if ! defined(LL_LLLEAP_H)
+#define LL_LLLEAP_H
+
+#include "llinstancetracker.h"
+#include <string>
+#include <vector>
+#include <stdexcept>
+
+/**
+ * LLSD Event API Plugin class. Because instances are managed by
+ * LLInstanceTracker, you can instantiate LLLeap and forget the instance
+ * unless you need it later. Each instance manages an LLProcess; when the
+ * child process terminates, LLLeap deletes itself. We don't require a unique
+ * LLInstanceTracker key.
+ *
+ * The fact that a given LLLeap instance vanishes when its child process
+ * terminates makes it problematic to store an LLLeap* anywhere. Any stored
+ * LLLeap* pointer should be validated before use by
+ * LLLeap::getInstance(LLLeap*) (see LLInstanceTracker).
+ */
+class LL_COMMON_API LLLeap: public LLInstanceTracker<LLLeap>
+{
+public:
+
+ /**
+ * Pass a brief string description, mostly for logging purposes. The desc
+ * need not be unique, but obviously the clearer we can make it, the
+ * easier these things will be to debug. The strings are the command line
+ * used to launch the desired plugin process.
+ *
+ * Pass exc=false to suppress LLLeap::Error exception. Obviously in that
+ * case the caller cannot discover the nature of the error, merely that an
+ * error of some kind occurred (because create() returned NULL). Either
+ * way, the error is logged.
+ */
+ static LLLeap* create(const std::string& desc, const std::vector<std::string>& plugin,
+ bool exc=true);
+
+ /**
+ * Pass a brief string description, mostly for logging purposes. The desc
+ * need not be unique, but obviously the clearer we can make it, the
+ * easier these things will be to debug. Pass a command-line string
+ * to launch the desired plugin process.
+ *
+ * Pass exc=false to suppress LLLeap::Error exception. Obviously in that
+ * case the caller cannot discover the nature of the error, merely that an
+ * error of some kind occurred (because create() returned NULL). Either
+ * way, the error is logged.
+ */
+ static LLLeap* create(const std::string& desc, const std::string& plugin,
+ bool exc=true);
+
+ /**
+ * Exception thrown for invalid create() arguments, e.g. no plugin
+ * program. This is more resiliant than an LL_ERRS failure, because the
+ * string(s) passed to create() might come from an external source. This
+ * way the caller can catch LLLeap::Error and try to recover.
+ */
+ struct Error: public std::runtime_error
+ {
+ Error(const std::string& what): std::runtime_error(what) {}
+ };
+
+ virtual ~LLLeap();
+
+protected:
+ LLLeap();
+};
+
+#endif /* ! defined(LL_LLLEAP_H) */
diff --git a/indra/llcommon/llleaplistener.cpp b/indra/llcommon/llleaplistener.cpp
new file mode 100755
index 0000000000..fa5730f112
--- /dev/null
+++ b/indra/llcommon/llleaplistener.cpp
@@ -0,0 +1,287 @@
+/**
+ * @file llleaplistener.cpp
+ * @author Nat Goodspeed
+ * @date 2012-03-16
+ * @brief Implementation for llleaplistener.
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Copyright (c) 2012, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+// Precompiled header
+#include "linden_common.h"
+// associated header
+#include "llleaplistener.h"
+// STL headers
+// std headers
+// external library headers
+#include <boost/foreach.hpp>
+// other Linden headers
+#include "lluuid.h"
+#include "llsdutil.h"
+#include "stringize.h"
+
+/*****************************************************************************
+* LEAP FEATURE STRINGS
+*****************************************************************************/
+/**
+ * Implement "getFeatures" command. The LLSD map thus obtained is intended to
+ * be machine-readable (read: easily-parsed, if parsing be necessary) and to
+ * highlight the differences between this version of the LEAP protocol and
+ * the baseline version. A client may thus determine whether or not the
+ * running viewer supports some recent feature of interest.
+ *
+ * This method is defined at the top of this implementation file so it's easy
+ * to find, easy to spot, easy to update as we enhance the LEAP protocol.
+ */
+/*static*/ LLSD LLLeapListener::getFeatures()
+{
+ static LLSD features;
+ if (features.isUndefined())
+ {
+ features = LLSD::emptyMap();
+
+ // This initial implementation IS the baseline LEAP protocol; thus the
+ // set of differences is empty; thus features is initially empty.
+// features["featurename"] = "value";
+ }
+
+ return features;
+}
+
+LLLeapListener::LLLeapListener(const ConnectFunc& connect):
+ // Each LEAP plugin has an instance of this listener. Make the command
+ // pump name difficult for other such plugins to guess.
+ LLEventAPI(LLUUID::generateNewID().asString(),
+ "Operations relating to the LLSD Event API Plugin (LEAP) protocol"),
+ mConnect(connect)
+{
+ LLSD need_name(LLSDMap("name", LLSD()));
+ add("newpump",
+ "Instantiate a new LLEventPump named like [\"name\"] and listen to it.\n"
+ "If [\"type\"] == \"LLEventQueue\", make LLEventQueue, else LLEventStream.\n"
+ "Events sent through new LLEventPump will be decorated with [\"pump\"]=name.\n"
+ "Returns actual name in [\"name\"] (may be different if collision).",
+ &LLLeapListener::newpump,
+ need_name);
+ add("killpump",
+ "Delete LLEventPump [\"name\"] created by \"newpump\".\n"
+ "Returns [\"status\"] boolean indicating whether such a pump existed.",
+ &LLLeapListener::killpump,
+ need_name);
+ LLSD need_source_listener(LLSDMap("source", LLSD())("listener", LLSD()));
+ add("listen",
+ "Listen to an existing LLEventPump named [\"source\"], with listener name\n"
+ "[\"listener\"].\n"
+ "By default, send events on [\"source\"] to the plugin, decorated\n"
+ "with [\"pump\"]=[\"source\"].\n"
+ "If [\"dest\"] specified, send undecorated events on [\"source\"] to the\n"
+ "LLEventPump named [\"dest\"].\n"
+ "Returns [\"status\"] boolean indicating whether the connection was made.",
+ &LLLeapListener::listen,
+ need_source_listener);
+ add("stoplistening",
+ "Disconnect a connection previously established by \"listen\".\n"
+ "Pass same [\"source\"] and [\"listener\"] arguments.\n"
+ "Returns [\"status\"] boolean indicating whether such a listener existed.",
+ &LLLeapListener::stoplistening,
+ need_source_listener);
+ add("ping",
+ "No arguments, just a round-trip sanity check.",
+ &LLLeapListener::ping);
+ add("getAPIs",
+ "Enumerate all LLEventAPI instances by name and description.",
+ &LLLeapListener::getAPIs);
+ add("getAPI",
+ "Get name, description, dispatch key and operations for LLEventAPI [\"api\"].",
+ &LLLeapListener::getAPI,
+ LLSD().with("api", LLSD()));
+ add("getFeatures",
+ "Return an LLSD map of feature strings (deltas from baseline LEAP protocol)",
+ static_cast<void (LLLeapListener::*)(const LLSD&) const>(&LLLeapListener::getFeatures));
+ add("getFeature",
+ "Return the feature value with key [\"feature\"]",
+ &LLLeapListener::getFeature,
+ LLSD().with("feature", LLSD()));
+}
+
+LLLeapListener::~LLLeapListener()
+{
+ // We'd have stored a map of LLTempBoundListener instances, save that the
+ // operation of inserting into a std::map necessarily copies the
+ // value_type, and Bad Things would happen if you copied an
+ // LLTempBoundListener. (Destruction of the original would disconnect the
+ // listener, invalidating every stored connection.)
+ BOOST_FOREACH(ListenersMap::value_type& pair, mListeners)
+ {
+ pair.second.disconnect();
+ }
+}
+
+void LLLeapListener::newpump(const LLSD& request)
+{
+ Response reply(LLSD(), request);
+
+ std::string name = request["name"];
+ LLSD const & type = request["type"];
+
+ LLEventPump * new_pump = NULL;
+ if (type.asString() == "LLEventQueue")
+ {
+ new_pump = new LLEventQueue(name, true); // tweak name for uniqueness
+ }
+ else
+ {
+ if (! (type.isUndefined() || type.asString() == "LLEventStream"))
+ {
+ reply.warn(STRINGIZE("unknown 'type' " << type << ", using LLEventStream"));
+ }
+ new_pump = new LLEventStream(name, true); // tweak name for uniqueness
+ }
+
+ name = new_pump->getName();
+
+ mEventPumps.insert(name, new_pump);
+
+ // Now listen on this new pump with our plugin listener
+ std::string myname("llleap");
+ saveListener(name, myname, mConnect(*new_pump, myname));
+
+ reply["name"] = name;
+}
+
+void LLLeapListener::killpump(const LLSD& request)
+{
+ Response reply(LLSD(), request);
+
+ std::string name = request["name"];
+ // success == (nonzero number of entries were erased)
+ reply["status"] = bool(mEventPumps.erase(name));
+}
+
+void LLLeapListener::listen(const LLSD& request)
+{
+ Response reply(LLSD(), request);
+
+ std::string source_name = request["source"];
+ std::string dest_name = request["dest"];
+ std::string listener_name = request["listener"];
+
+ LLEventPump & source = LLEventPumps::instance().obtain(source_name);
+
+ reply["status"] = false;
+ if (mListeners.find(ListenersMap::key_type(source_name, listener_name)) == mListeners.end())
+ {
+ try
+ {
+ if (request["dest"].isDefined())
+ {
+ // If we're asked to connect the "source" pump to a
+ // specific "dest" pump, find dest pump and connect it.
+ LLEventPump & dest = LLEventPumps::instance().obtain(dest_name);
+ saveListener(source_name, listener_name,
+ source.listen(listener_name,
+ boost::bind(&LLEventPump::post, &dest, _1)));
+ }
+ else
+ {
+ // "dest" unspecified means to direct events on "source"
+ // to our plugin listener.
+ saveListener(source_name, listener_name, mConnect(source, listener_name));
+ }
+ reply["status"] = true;
+ }
+ catch (const LLEventPump::DupListenerName &)
+ {
+ // pass - status already set to false
+ }
+ }
+}
+
+void LLLeapListener::stoplistening(const LLSD& request)
+{
+ Response reply(LLSD(), request);
+
+ std::string source_name = request["source"];
+ std::string listener_name = request["listener"];
+
+ ListenersMap::iterator finder =
+ mListeners.find(ListenersMap::key_type(source_name, listener_name));
+
+ reply["status"] = false;
+ if(finder != mListeners.end())
+ {
+ reply["status"] = true;
+ finder->second.disconnect();
+ mListeners.erase(finder);
+ }
+}
+
+void LLLeapListener::ping(const LLSD& request) const
+{
+ // do nothing, default reply suffices
+ Response(LLSD(), request);
+}
+
+void LLLeapListener::getAPIs(const LLSD& request) const
+{
+ Response reply(LLSD(), request);
+
+ for (LLEventAPI::instance_iter eai(LLEventAPI::beginInstances()),
+ eaend(LLEventAPI::endInstances());
+ eai != eaend; ++eai)
+ {
+ LLSD info;
+ info["desc"] = eai->getDesc();
+ reply[eai->getName()] = info;
+ }
+}
+
+void LLLeapListener::getAPI(const LLSD& request) const
+{
+ Response reply(LLSD(), request);
+
+ LLEventAPI* found = LLEventAPI::getInstance(request["api"]);
+ if (found)
+ {
+ reply["name"] = found->getName();
+ reply["desc"] = found->getDesc();
+ reply["key"] = found->getDispatchKey();
+ LLSD ops;
+ for (LLEventAPI::const_iterator oi(found->begin()), oend(found->end());
+ oi != oend; ++oi)
+ {
+ ops.append(found->getMetadata(oi->first));
+ }
+ reply["ops"] = ops;
+ }
+}
+
+void LLLeapListener::getFeatures(const LLSD& request) const
+{
+ // Merely constructing and destroying a Response object suffices here.
+ // Giving it a name would only produce fatal 'unreferenced variable'
+ // warnings.
+ Response(getFeatures(), request);
+}
+
+void LLLeapListener::getFeature(const LLSD& request) const
+{
+ Response reply(LLSD(), request);
+
+ LLSD::String feature_name(request["feature"]);
+ LLSD features(getFeatures());
+ if (features[feature_name].isDefined())
+ {
+ reply["feature"] = features[feature_name];
+ }
+}
+
+void LLLeapListener::saveListener(const std::string& pump_name,
+ const std::string& listener_name,
+ const LLBoundListener& listener)
+{
+ mListeners.insert(ListenersMap::value_type(ListenersMap::key_type(pump_name, listener_name),
+ listener));
+}
diff --git a/indra/llcommon/llleaplistener.h b/indra/llcommon/llleaplistener.h
new file mode 100755
index 0000000000..2193d81b9e
--- /dev/null
+++ b/indra/llcommon/llleaplistener.h
@@ -0,0 +1,73 @@
+/**
+ * @file llleaplistener.h
+ * @author Nat Goodspeed
+ * @date 2012-03-16
+ * @brief LLEventAPI supporting LEAP plugins
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Copyright (c) 2012, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+#if ! defined(LL_LLLEAPLISTENER_H)
+#define LL_LLLEAPLISTENER_H
+
+#include "lleventapi.h"
+#include <map>
+#include <string>
+#include <boost/function.hpp>
+#include <boost/ptr_container/ptr_map.hpp>
+
+/// Listener class implementing LLLeap query/control operations.
+/// See https://jira.lindenlab.com/jira/browse/DEV-31978.
+class LLLeapListener: public LLEventAPI
+{
+public:
+ /**
+ * Decouple LLLeap by dependency injection. Certain LLLeapListener
+ * operations must be able to cause LLLeap to listen on a specified
+ * LLEventPump with the LLLeap listener that wraps incoming events in an
+ * outer (pump=, data=) map and forwards them to the plugin. Very well,
+ * define the signature for a function that will perform that, and make
+ * our constructor accept such a function.
+ */
+ typedef boost::function<LLBoundListener(LLEventPump&, const std::string& listener)>
+ ConnectFunc;
+ LLLeapListener(const ConnectFunc& connect);
+ ~LLLeapListener();
+
+ static LLSD getFeatures();
+
+private:
+ void newpump(const LLSD&);
+ void killpump(const LLSD&);
+ void listen(const LLSD&);
+ void stoplistening(const LLSD&);
+ void ping(const LLSD&) const;
+ void getAPIs(const LLSD&) const;
+ void getAPI(const LLSD&) const;
+ void getFeatures(const LLSD&) const;
+ void getFeature(const LLSD&) const;
+
+ void saveListener(const std::string& pump_name, const std::string& listener_name,
+ const LLBoundListener& listener);
+
+ ConnectFunc mConnect;
+
+ // In theory, listen() could simply call the relevant LLEventPump's
+ // listen() method, stoplistening() likewise. Lifespan issues make us
+ // capture the LLBoundListener objects: when this object goes away, all
+ // those listeners should be disconnected. But what if the client listens,
+ // stops, listens again on the same LLEventPump with the same listener
+ // name? Merely collecting LLBoundListeners wouldn't adequately track
+ // that. So capture the latest LLBoundListener for this LLEventPump name
+ // and listener name.
+ typedef std::map<std::pair<std::string, std::string>, LLBoundListener> ListenersMap;
+ ListenersMap mListeners;
+ // Similar lifespan reasoning applies to LLEventPumps instantiated by
+ // newpump() operations.
+ typedef boost::ptr_map<std::string, LLEventPump> EventPumpsMap;
+ EventPumpsMap mEventPumps;
+};
+
+#endif /* ! defined(LL_LLLEAPLISTENER_H) */
diff --git a/indra/llcommon/lllinkedqueue.h b/indra/llcommon/lllinkedqueue.h
index 8336608809..8336608809 100644..100755
--- a/indra/llcommon/lllinkedqueue.h
+++ b/indra/llcommon/lllinkedqueue.h
diff --git a/indra/llcommon/lllistenerwrapper.h b/indra/llcommon/lllistenerwrapper.h
index 09d074abca..09d074abca 100644..100755
--- a/indra/llcommon/lllistenerwrapper.h
+++ b/indra/llcommon/lllistenerwrapper.h
diff --git a/indra/llcommon/llliveappconfig.cpp b/indra/llcommon/llliveappconfig.cpp
index 3a3dfa9f28..3a3dfa9f28 100644..100755
--- a/indra/llcommon/llliveappconfig.cpp
+++ b/indra/llcommon/llliveappconfig.cpp
diff --git a/indra/llcommon/llliveappconfig.h b/indra/llcommon/llliveappconfig.h
index 4fd7c26a07..4fd7c26a07 100644..100755
--- a/indra/llcommon/llliveappconfig.h
+++ b/indra/llcommon/llliveappconfig.h
diff --git a/indra/llcommon/lllivefile.cpp b/indra/llcommon/lllivefile.cpp
index c1987baf55..c1987baf55 100644..100755
--- a/indra/llcommon/lllivefile.cpp
+++ b/indra/llcommon/lllivefile.cpp
diff --git a/indra/llcommon/lllivefile.h b/indra/llcommon/lllivefile.h
index 320aa4bc3e..320aa4bc3e 100644..100755
--- a/indra/llcommon/lllivefile.h
+++ b/indra/llcommon/lllivefile.h
diff --git a/indra/llcommon/lllocalidhashmap.h b/indra/llcommon/lllocalidhashmap.h
index 8f4f91a560..8f4f91a560 100644..100755
--- a/indra/llcommon/lllocalidhashmap.h
+++ b/indra/llcommon/lllocalidhashmap.h
diff --git a/indra/llcommon/lllog.cpp b/indra/llcommon/lllog.cpp
index fc4058b5c9..fc4058b5c9 100644..100755
--- a/indra/llcommon/lllog.cpp
+++ b/indra/llcommon/lllog.cpp
diff --git a/indra/llcommon/lllog.h b/indra/llcommon/lllog.h
index 7964412e83..7964412e83 100644..100755
--- a/indra/llcommon/lllog.h
+++ b/indra/llcommon/lllog.h
diff --git a/indra/llcommon/lllslconstants.h b/indra/llcommon/lllslconstants.h
index 9f32598e61..926ce32d75 100644..100755
--- a/indra/llcommon/lllslconstants.h
+++ b/indra/llcommon/lllslconstants.h
@@ -67,6 +67,19 @@ const S32 LSL_PRIM_TEXGEN = 22;
const S32 LSL_PRIM_POINT_LIGHT = 23;
const S32 LSL_PRIM_CAST_SHADOWS = 24;
const S32 LSL_PRIM_GLOW = 25;
+const S32 LSL_PRIM_TEXT = 26;
+const S32 LSL_PRIM_NAME = 27;
+const S32 LSL_PRIM_DESC = 28;
+const S32 LSL_PRIM_ROT_LOCAL = 29;
+const S32 LSL_PRIM_PHYSICS_SHAPE_TYPE = 30;
+const S32 LSL_PRIM_OMEGA = 32;
+const S32 LSL_PRIM_POS_LOCAL = 33;
+const S32 LSL_PRIM_LINK_TARGET = 34;
+const S32 LSL_PRIM_SLICE = 35;
+
+const S32 LSL_PRIM_PHYSICS_SHAPE_PRIM = 0;
+const S32 LSL_PRIM_PHYSICS_SHAPE_NONE = 1;
+const S32 LSL_PRIM_PHYSICS_SHAPE_CONVEX = 2;
const S32 LSL_PRIM_TYPE_BOX = 0;
const S32 LSL_PRIM_TYPE_CYLINDER= 1;
@@ -179,6 +192,22 @@ const S32 OBJECT_VELOCITY = 5;
const S32 OBJECT_OWNER = 6;
const S32 OBJECT_GROUP = 7;
const S32 OBJECT_CREATOR = 8;
+const S32 OBJECT_RUNNING_SCRIPT_COUNT = 9;
+const S32 OBJECT_TOTAL_SCRIPT_COUNT = 10;
+const S32 OBJECT_SCRIPT_MEMORY = 11;
+const S32 OBJECT_SCRIPT_TIME = 12;
+const S32 OBJECT_PRIM_EQUIVALENCE = 13;
+const S32 OBJECT_SERVER_COST = 14;
+const S32 OBJECT_STREAMING_COST = 15;
+const S32 OBJECT_PHYSICS_COST = 16;
+const S32 OBJECT_CHARACTER_TIME = 17;
+const S32 OBJECT_ROOT = 18;
+const S32 OBJECT_ATTACHED_POINT = 19;
+const S32 OBJECT_PATHFINDING_TYPE = 20;
+const S32 OBJECT_PHYSICS = 21;
+const S32 OBJECT_PHANTOM = 22;
+const S32 OBJECT_TEMP_ON_REZ = 23;
+const S32 OBJECT_RENDER_WEIGHT = 24;
// llTextBox() magic token string - yes this is a hack. sue me.
char const* const TEXTBOX_MAGIC_TOKEN = "!!llTextBox!!";
diff --git a/indra/llcommon/llmap.h b/indra/llcommon/llmap.h
index 6294a15d3b..6294a15d3b 100644..100755
--- a/indra/llcommon/llmap.h
+++ b/indra/llcommon/llmap.h
diff --git a/indra/llcommon/llmd5.cpp b/indra/llcommon/llmd5.cpp
index 1409c55d1c..1409c55d1c 100644..100755
--- a/indra/llcommon/llmd5.cpp
+++ b/indra/llcommon/llmd5.cpp
diff --git a/indra/llcommon/llmd5.h b/indra/llcommon/llmd5.h
index 1526e6ac3c..1526e6ac3c 100644..100755
--- a/indra/llcommon/llmd5.h
+++ b/indra/llcommon/llmd5.h
diff --git a/indra/llcommon/llmemory.cpp b/indra/llcommon/llmemory.cpp
index 3b9758f996..70ad10ad55 100644..100755
--- a/indra/llcommon/llmemory.cpp
+++ b/indra/llcommon/llmemory.cpp
@@ -61,6 +61,18 @@ BOOL LLMemory::sEnableMemoryFailurePrevention = FALSE;
LLPrivateMemoryPoolManager::mem_allocation_info_t LLPrivateMemoryPoolManager::sMemAllocationTracker;
#endif
+void ll_assert_aligned_func(uintptr_t ptr,U32 alignment)
+{
+#ifdef SHOW_ASSERT
+ // Redundant, place to set breakpoints.
+ if (ptr%alignment!=0)
+ {
+ llwarns << "alignment check failed" << llendl;
+ }
+ llassert(ptr%alignment==0);
+#endif
+}
+
//static
void LLMemory::initClass()
{
@@ -240,21 +252,6 @@ U32 LLMemory::getAllocatedMemKB()
return sAllocatedMemInKB ;
}
-void* ll_allocate (size_t size)
-{
- if (size == 0)
- {
- llwarns << "Null allocation" << llendl;
- }
- void *p = malloc(size);
- if (p == NULL)
- {
- LLMemory::freeReserve();
- llerrs << "Out of memory Error" << llendl;
- }
- return p;
-}
-
//----------------------------------------------------------------------------
#if defined(LL_WINDOWS)
@@ -1353,7 +1350,7 @@ char* LLPrivateMemoryPool::allocate(U32 size)
//if the asked size larger than MAX_BLOCK_SIZE, fetch from heap directly, the pool does not manage it
if(size >= CHUNK_SIZE)
{
- return (char*)malloc(size) ;
+ return (char*)ll_aligned_malloc_16(size) ;
}
char* p = NULL ;
@@ -1410,7 +1407,7 @@ char* LLPrivateMemoryPool::allocate(U32 size)
to_log = false ;
}
- return (char*)malloc(size) ;
+ return (char*)ll_aligned_malloc_16(size) ;
}
return p ;
@@ -1429,7 +1426,7 @@ void LLPrivateMemoryPool::freeMem(void* addr)
if(!chunk)
{
- free(addr) ; //release from heap
+ ll_aligned_free_16(addr) ; //release from heap
}
else
{
@@ -1553,7 +1550,7 @@ LLPrivateMemoryPool::LLMemoryChunk* LLPrivateMemoryPool::addChunk(S32 chunk_inde
mReservedPoolSize += preferred_size + overhead ;
- char* buffer = (char*)malloc(preferred_size + overhead) ;
+ char* buffer = (char*)ll_aligned_malloc_16(preferred_size + overhead) ;
if(!buffer)
{
return NULL ;
@@ -1621,7 +1618,7 @@ void LLPrivateMemoryPool::removeChunk(LLMemoryChunk* chunk)
mReservedPoolSize -= chunk->getBufferSize() ;
//release memory
- free(chunk->getBuffer()) ;
+ ll_aligned_free_16(chunk->getBuffer()) ;
}
U16 LLPrivateMemoryPool::findHashKey(const char* addr)
@@ -1965,7 +1962,7 @@ char* LLPrivateMemoryPoolManager::allocate(LLPrivateMemoryPool* poolp, U32 size,
if(!poolp)
{
- p = (char*)malloc(size) ;
+ p = (char*)ll_aligned_malloc_16(size) ;
}
else
{
@@ -1994,7 +1991,7 @@ char* LLPrivateMemoryPoolManager::allocate(LLPrivateMemoryPool* poolp, U32 size)
}
else
{
- return (char*)malloc(size) ;
+ return (char*)ll_aligned_malloc_16(size) ;
}
}
#endif
@@ -2019,7 +2016,7 @@ void LLPrivateMemoryPoolManager::freeMem(LLPrivateMemoryPool* poolp, void* addr
{
if(!sPrivatePoolEnabled)
{
- free(addr) ; //private pool is disabled.
+ ll_aligned_free_16(addr) ; //private pool is disabled.
}
else if(!sInstance) //the private memory manager is destroyed, try the dangling list
{
diff --git a/indra/llcommon/llmemory.h b/indra/llcommon/llmemory.h
index bbbdaa6497..61e30f11cc 100644..100755
--- a/indra/llcommon/llmemory.h
+++ b/indra/llcommon/llmemory.h
@@ -26,27 +26,85 @@
#ifndef LLMEMORY_H
#define LLMEMORY_H
-#include "llmemtype.h"
-#if LL_DEBUG
+#include "linden_common.h"
+
+class LLMutex ;
+
+#if LL_WINDOWS && LL_DEBUG
+#define LL_CHECK_MEMORY llassert(_CrtCheckMemory());
+#else
+#define LL_CHECK_MEMORY
+#endif
+
+LL_COMMON_API void ll_assert_aligned_func(uintptr_t ptr,U32 alignment);
+
+#ifdef SHOW_ASSERT
+#define ll_assert_aligned(ptr,alignment) ll_assert_aligned_func(reinterpret_cast<uintptr_t>(ptr),((U32)alignment))
+#else
+#define ll_assert_aligned(ptr,alignment)
+#endif
+
+#include <xmmintrin.h>
+
+template <typename T> T* LL_NEXT_ALIGNED_ADDRESS(T* address)
+{
+ return reinterpret_cast<T*>(
+ (reinterpret_cast<uintptr_t>(address) + 0xF) & ~0xF);
+}
+
+template <typename T> T* LL_NEXT_ALIGNED_ADDRESS_64(T* address)
+{
+ return reinterpret_cast<T*>(
+ (reinterpret_cast<uintptr_t>(address) + 0x3F) & ~0x3F);
+}
+
+#if LL_LINUX || LL_DARWIN
+
+#define LL_ALIGN_PREFIX(x)
+#define LL_ALIGN_POSTFIX(x) __attribute__((aligned(x)))
+
+#elif LL_WINDOWS
+
+#define LL_ALIGN_PREFIX(x) __declspec(align(x))
+#define LL_ALIGN_POSTFIX(x)
+
+#else
+#error "LL_ALIGN_PREFIX and LL_ALIGN_POSTFIX undefined"
+#endif
+
+#define LL_ALIGN_16(var) LL_ALIGN_PREFIX(16) var LL_ALIGN_POSTFIX(16)
+
inline void* ll_aligned_malloc( size_t size, int align )
{
+#if defined(LL_WINDOWS)
+ return _aligned_malloc(size, align);
+#else
void* mem = malloc( size + (align - 1) + sizeof(void*) );
char* aligned = ((char*)mem) + sizeof(void*);
aligned += align - ((uintptr_t)aligned & (align - 1));
((void**)aligned)[-1] = mem;
return aligned;
+#endif
}
inline void ll_aligned_free( void* ptr )
{
- free( ((void**)ptr)[-1] );
+#if defined(LL_WINDOWS)
+ _aligned_free(ptr);
+#else
+ if (ptr)
+ {
+ free( ((void**)ptr)[-1] );
+ }
+#endif
}
+#if !LL_USE_TCMALLOC
inline void* ll_aligned_malloc_16(size_t size) // returned hunk MUST be freed with ll_aligned_free_16().
{
#if defined(LL_WINDOWS)
- return _mm_malloc(size, 16);
+ return _aligned_malloc(size, 16);
#elif defined(LL_DARWIN)
return malloc(size); // default osx malloc is 16 byte aligned.
#else
@@ -61,7 +119,7 @@ inline void* ll_aligned_malloc_16(size_t size) // returned hunk MUST be freed wi
inline void ll_aligned_free_16(void *p)
{
#if defined(LL_WINDOWS)
- _mm_free(p);
+ _aligned_free(p);
#elif defined(LL_DARWIN)
return free(p);
#else
@@ -69,10 +127,39 @@ inline void ll_aligned_free_16(void *p)
#endif
}
+inline void* ll_aligned_realloc_16(void* ptr, size_t size, size_t old_size) // returned hunk MUST be freed with ll_aligned_free_16().
+{
+#if defined(LL_WINDOWS)
+ return _aligned_realloc(ptr, size, 16);
+#elif defined(LL_DARWIN)
+ return realloc(ptr,size); // default osx malloc is 16 byte aligned.
+#else
+ //FIXME: memcpy is SLOW
+ void* ret = ll_aligned_malloc_16(size);
+ if (ptr)
+ {
+ if (ret)
+ {
+ // Only copy the size of the smallest memory block to avoid memory corruption.
+ memcpy(ret, ptr, llmin(old_size, size));
+ }
+ ll_aligned_free_16(ptr);
+ }
+ return ret;
+#endif
+}
+
+#else // USE_TCMALLOC
+// ll_aligned_foo_16 are not needed with tcmalloc
+#define ll_aligned_malloc_16 malloc
+#define ll_aligned_realloc_16(a,b,c) realloc(a,b)
+#define ll_aligned_free_16 free
+#endif // USE_TCMALLOC
+
inline void* ll_aligned_malloc_32(size_t size) // returned hunk MUST be freed with ll_aligned_free_32().
{
#if defined(LL_WINDOWS)
- return _mm_malloc(size, 32);
+ return _aligned_malloc(size, 32);
#elif defined(LL_DARWIN)
return ll_aligned_malloc( size, 32 );
#else
@@ -87,22 +174,85 @@ inline void* ll_aligned_malloc_32(size_t size) // returned hunk MUST be freed wi
inline void ll_aligned_free_32(void *p)
{
#if defined(LL_WINDOWS)
- _mm_free(p);
+ _aligned_free(p);
#elif defined(LL_DARWIN)
ll_aligned_free( p );
#else
free(p); // posix_memalign() is compatible with heap deallocator
#endif
}
-#else // LL_DEBUG
-// ll_aligned_foo are noops now that we use tcmalloc everywhere (tcmalloc aligns automatically at appropriate intervals)
-#define ll_aligned_malloc( size, align ) malloc(size)
-#define ll_aligned_free( ptr ) free(ptr)
-#define ll_aligned_malloc_16 malloc
-#define ll_aligned_free_16 free
-#define ll_aligned_malloc_32 malloc
-#define ll_aligned_free_32 free
-#endif // LL_DEBUG
+
+
+// Copy words 16-byte blocks from src to dst. Source and destination MUST NOT OVERLAP.
+// Source and dest must be 16-byte aligned and size must be multiple of 16.
+//
+inline void ll_memcpy_nonaliased_aligned_16(char* __restrict dst, const char* __restrict src, size_t bytes)
+{
+ assert(src != NULL);
+ assert(dst != NULL);
+ assert(bytes > 0);
+ assert((bytes % sizeof(F32))== 0);
+ ll_assert_aligned(src,16);
+ ll_assert_aligned(dst,16);
+ assert((src < dst) ? ((src + bytes) < dst) : ((dst + bytes) < src));
+ assert(bytes%16==0);
+
+ char* end = dst + bytes;
+
+ if (bytes > 64)
+ {
+
+ // Find start of 64b aligned area within block
+ //
+ void* begin_64 = LL_NEXT_ALIGNED_ADDRESS_64(dst);
+
+ //at least 64 bytes before the end of the destination, switch to 16 byte copies
+ void* end_64 = end-64;
+
+ // Prefetch the head of the 64b area now
+ //
+ _mm_prefetch((char*)begin_64, _MM_HINT_NTA);
+ _mm_prefetch((char*)begin_64 + 64, _MM_HINT_NTA);
+ _mm_prefetch((char*)begin_64 + 128, _MM_HINT_NTA);
+ _mm_prefetch((char*)begin_64 + 192, _MM_HINT_NTA);
+
+ // Copy 16b chunks until we're 64b aligned
+ //
+ while (dst < begin_64)
+ {
+
+ _mm_store_ps((F32*)dst, _mm_load_ps((F32*)src));
+ dst += 16;
+ src += 16;
+ }
+
+ // Copy 64b chunks up to your tail
+ //
+ // might be good to shmoo the 512b prefetch offset
+ // (characterize performance for various values)
+ //
+ while (dst < end_64)
+ {
+ _mm_prefetch((char*)src + 512, _MM_HINT_NTA);
+ _mm_prefetch((char*)dst + 512, _MM_HINT_NTA);
+ _mm_store_ps((F32*)dst, _mm_load_ps((F32*)src));
+ _mm_store_ps((F32*)(dst + 16), _mm_load_ps((F32*)(src + 16)));
+ _mm_store_ps((F32*)(dst + 32), _mm_load_ps((F32*)(src + 32)));
+ _mm_store_ps((F32*)(dst + 48), _mm_load_ps((F32*)(src + 48)));
+ dst += 64;
+ src += 64;
+ }
+ }
+
+ // Copy remainder 16b tail chunks (or ALL 16b chunks for sub-64b copies)
+ //
+ while (dst < end)
+ {
+ _mm_store_ps((F32*)dst, _mm_load_ps((F32*)src));
+ dst += 16;
+ src += 16;
+ }
+}
#ifndef __DEBUG_PRIVATE_MEM__
#define __DEBUG_PRIVATE_MEM__ 0
@@ -512,4 +662,7 @@ void LLPrivateMemoryPoolTester::operator delete[](void* addr)
// LLSingleton moved to llsingleton.h
+
+
+
#endif
diff --git a/indra/llcommon/llmemorystream.cpp b/indra/llcommon/llmemorystream.cpp
index 723d94f025..723d94f025 100644..100755
--- a/indra/llcommon/llmemorystream.cpp
+++ b/indra/llcommon/llmemorystream.cpp
diff --git a/indra/llcommon/llmemorystream.h b/indra/llcommon/llmemorystream.h
index e28f012192..e28f012192 100644..100755
--- a/indra/llcommon/llmemorystream.h
+++ b/indra/llcommon/llmemorystream.h
diff --git a/indra/llcommon/llmemtype.cpp b/indra/llcommon/llmemtype.cpp
deleted file mode 100644
index 6290a7158f..0000000000
--- a/indra/llcommon/llmemtype.cpp
+++ /dev/null
@@ -1,232 +0,0 @@
-/**
- * @file llmemtype.cpp
- * @brief Simple memory allocation/deallocation tracking stuff here
- *
- * $LicenseInfo:firstyear=2002&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 "llmemtype.h"
-#include "llallocator.h"
-
-std::vector<char const *> LLMemType::DeclareMemType::mNameList;
-
-LLMemType::DeclareMemType LLMemType::MTYPE_INIT("Init");
-LLMemType::DeclareMemType LLMemType::MTYPE_STARTUP("Startup");
-LLMemType::DeclareMemType LLMemType::MTYPE_MAIN("Main");
-LLMemType::DeclareMemType LLMemType::MTYPE_FRAME("Frame");
-
-LLMemType::DeclareMemType LLMemType::MTYPE_GATHER_INPUT("GatherInput");
-LLMemType::DeclareMemType LLMemType::MTYPE_JOY_KEY("JoyKey");
-
-LLMemType::DeclareMemType LLMemType::MTYPE_IDLE("Idle");
-LLMemType::DeclareMemType LLMemType::MTYPE_IDLE_PUMP("IdlePump");
-LLMemType::DeclareMemType LLMemType::MTYPE_IDLE_NETWORK("IdleNetwork");
-LLMemType::DeclareMemType LLMemType::MTYPE_IDLE_UPDATE_REGIONS("IdleUpdateRegions");
-LLMemType::DeclareMemType LLMemType::MTYPE_IDLE_UPDATE_VIEWER_REGION("IdleUpdateViewerRegion");
-LLMemType::DeclareMemType LLMemType::MTYPE_IDLE_UPDATE_SURFACE("IdleUpdateSurface");
-LLMemType::DeclareMemType LLMemType::MTYPE_IDLE_UPDATE_PARCEL_OVERLAY("IdleUpdateParcelOverlay");
-LLMemType::DeclareMemType LLMemType::MTYPE_IDLE_AUDIO("IdleAudio");
-
-LLMemType::DeclareMemType LLMemType::MTYPE_CACHE_PROCESS_PENDING("CacheProcessPending");
-LLMemType::DeclareMemType LLMemType::MTYPE_CACHE_PROCESS_PENDING_ASKS("CacheProcessPendingAsks");
-LLMemType::DeclareMemType LLMemType::MTYPE_CACHE_PROCESS_PENDING_REPLIES("CacheProcessPendingReplies");
-
-LLMemType::DeclareMemType LLMemType::MTYPE_MESSAGE_CHECK_ALL("MessageCheckAll");
-LLMemType::DeclareMemType LLMemType::MTYPE_MESSAGE_PROCESS_ACKS("MessageProcessAcks");
-
-LLMemType::DeclareMemType LLMemType::MTYPE_RENDER("Render");
-LLMemType::DeclareMemType LLMemType::MTYPE_SLEEP("Sleep");
-
-LLMemType::DeclareMemType LLMemType::MTYPE_NETWORK("Network");
-LLMemType::DeclareMemType LLMemType::MTYPE_PHYSICS("Physics");
-LLMemType::DeclareMemType LLMemType::MTYPE_INTERESTLIST("InterestList");
-
-LLMemType::DeclareMemType LLMemType::MTYPE_IMAGEBASE("ImageBase");
-LLMemType::DeclareMemType LLMemType::MTYPE_IMAGERAW("ImageRaw");
-LLMemType::DeclareMemType LLMemType::MTYPE_IMAGEFORMATTED("ImageFormatted");
-
-LLMemType::DeclareMemType LLMemType::MTYPE_APPFMTIMAGE("AppFmtImage");
-LLMemType::DeclareMemType LLMemType::MTYPE_APPRAWIMAGE("AppRawImage");
-LLMemType::DeclareMemType LLMemType::MTYPE_APPAUXRAWIMAGE("AppAuxRawImage");
-
-LLMemType::DeclareMemType LLMemType::MTYPE_DRAWABLE("Drawable");
-
-LLMemType::DeclareMemType LLMemType::MTYPE_OBJECT("Object");
-LLMemType::DeclareMemType LLMemType::MTYPE_OBJECT_PROCESS_UPDATE("ObjectProcessUpdate");
-LLMemType::DeclareMemType LLMemType::MTYPE_OBJECT_PROCESS_UPDATE_CORE("ObjectProcessUpdateCore");
-
-LLMemType::DeclareMemType LLMemType::MTYPE_DISPLAY("Display");
-LLMemType::DeclareMemType LLMemType::MTYPE_DISPLAY_UPDATE("DisplayUpdate");
-LLMemType::DeclareMemType LLMemType::MTYPE_DISPLAY_UPDATE_CAMERA("DisplayUpdateCam");
-LLMemType::DeclareMemType LLMemType::MTYPE_DISPLAY_UPDATE_GEOM("DisplayUpdateGeom");
-LLMemType::DeclareMemType LLMemType::MTYPE_DISPLAY_SWAP("DisplaySwap");
-LLMemType::DeclareMemType LLMemType::MTYPE_DISPLAY_UPDATE_HUD("DisplayUpdateHud");
-LLMemType::DeclareMemType LLMemType::MTYPE_DISPLAY_GEN_REFLECTION("DisplayGenRefl");
-LLMemType::DeclareMemType LLMemType::MTYPE_DISPLAY_IMAGE_UPDATE("DisplayImageUpdate");
-LLMemType::DeclareMemType LLMemType::MTYPE_DISPLAY_STATE_SORT("DisplayStateSort");
-LLMemType::DeclareMemType LLMemType::MTYPE_DISPLAY_SKY("DisplaySky");
-LLMemType::DeclareMemType LLMemType::MTYPE_DISPLAY_RENDER_GEOM("DisplayRenderGeom");
-LLMemType::DeclareMemType LLMemType::MTYPE_DISPLAY_RENDER_FLUSH("DisplayRenderFlush");
-LLMemType::DeclareMemType LLMemType::MTYPE_DISPLAY_RENDER_UI("DisplayRenderUI");
-LLMemType::DeclareMemType LLMemType::MTYPE_DISPLAY_RENDER_ATTACHMENTS("DisplayRenderAttach");
-
-LLMemType::DeclareMemType LLMemType::MTYPE_VERTEX_DATA("VertexData");
-LLMemType::DeclareMemType LLMemType::MTYPE_VERTEX_CONSTRUCTOR("VertexConstr");
-LLMemType::DeclareMemType LLMemType::MTYPE_VERTEX_DESTRUCTOR("VertexDestr");
-LLMemType::DeclareMemType LLMemType::MTYPE_VERTEX_CREATE_VERTICES("VertexCreateVerts");
-LLMemType::DeclareMemType LLMemType::MTYPE_VERTEX_CREATE_INDICES("VertexCreateIndices");
-LLMemType::DeclareMemType LLMemType::MTYPE_VERTEX_DESTROY_BUFFER("VertexDestroyBuff");
-LLMemType::DeclareMemType LLMemType::MTYPE_VERTEX_DESTROY_INDICES("VertexDestroyIndices");
-LLMemType::DeclareMemType LLMemType::MTYPE_VERTEX_UPDATE_VERTS("VertexUpdateVerts");
-LLMemType::DeclareMemType LLMemType::MTYPE_VERTEX_UPDATE_INDICES("VertexUpdateIndices");
-LLMemType::DeclareMemType LLMemType::MTYPE_VERTEX_ALLOCATE_BUFFER("VertexAllocateBuffer");
-LLMemType::DeclareMemType LLMemType::MTYPE_VERTEX_RESIZE_BUFFER("VertexResizeBuffer");
-LLMemType::DeclareMemType LLMemType::MTYPE_VERTEX_MAP_BUFFER("VertexMapBuffer");
-LLMemType::DeclareMemType LLMemType::MTYPE_VERTEX_MAP_BUFFER_VERTICES("VertexMapBufferVerts");
-LLMemType::DeclareMemType LLMemType::MTYPE_VERTEX_MAP_BUFFER_INDICES("VertexMapBufferIndices");
-LLMemType::DeclareMemType LLMemType::MTYPE_VERTEX_UNMAP_BUFFER("VertexUnmapBuffer");
-LLMemType::DeclareMemType LLMemType::MTYPE_VERTEX_SET_STRIDE("VertexSetStride");
-LLMemType::DeclareMemType LLMemType::MTYPE_VERTEX_SET_BUFFER("VertexSetBuffer");
-LLMemType::DeclareMemType LLMemType::MTYPE_VERTEX_SETUP_VERTEX_BUFFER("VertexSetupVertBuff");
-LLMemType::DeclareMemType LLMemType::MTYPE_VERTEX_CLEANUP_CLASS("VertexCleanupClass");
-
-LLMemType::DeclareMemType LLMemType::MTYPE_SPACE_PARTITION("SpacePartition");
-
-LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE("Pipeline");
-LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_INIT("PipelineInit");
-LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_CREATE_BUFFERS("PipelineCreateBuffs");
-LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_RESTORE_GL("PipelineRestroGL");
-LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_UNLOAD_SHADERS("PipelineUnloadShaders");
-LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_LIGHTING_DETAIL("PipelineLightingDetail");
-LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_GET_POOL_TYPE("PipelineGetPoolType");
-LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_ADD_POOL("PipelineAddPool");
-LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_ALLOCATE_DRAWABLE("PipelineAllocDrawable");
-LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_ADD_OBJECT("PipelineAddObj");
-LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_CREATE_OBJECTS("PipelineCreateObjs");
-LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_UPDATE_MOVE("PipelineUpdateMove");
-LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_UPDATE_GEOM("PipelineUpdateGeom");
-LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_MARK_VISIBLE("PipelineMarkVisible");
-LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_MARK_MOVED("PipelineMarkMoved");
-LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_MARK_SHIFT("PipelineMarkShift");
-LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_SHIFT_OBJECTS("PipelineShiftObjs");
-LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_MARK_TEXTURED("PipelineMarkTextured");
-LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_MARK_REBUILD("PipelineMarkRebuild");
-LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_UPDATE_CULL("PipelineUpdateCull");
-LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_STATE_SORT("PipelineStateSort");
-LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_POST_SORT("PipelinePostSort");
-
-LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_RENDER_HUD_ELS("PipelineHudEls");
-LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_RENDER_HL("PipelineRenderHL");
-LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_RENDER_GEOM("PipelineRenderGeom");
-LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_RENDER_GEOM_DEFFERRED("PipelineRenderGeomDef");
-LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_RENDER_GEOM_POST_DEF("PipelineRenderGeomPostDef");
-LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_RENDER_GEOM_SHADOW("PipelineRenderGeomShadow");
-LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_RENDER_SELECT("PipelineRenderSelect");
-LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_REBUILD_POOLS("PipelineRebuildPools");
-LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_QUICK_LOOKUP("PipelineQuickLookup");
-LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_RENDER_OBJECTS("PipelineRenderObjs");
-LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_GENERATE_IMPOSTOR("PipelineGenImpostors");
-LLMemType::DeclareMemType LLMemType::MTYPE_PIPELINE_RENDER_BLOOM("PipelineRenderBloom");
-
-LLMemType::DeclareMemType LLMemType::MTYPE_UPKEEP_POOLS("UpkeepPools");
-
-LLMemType::DeclareMemType LLMemType::MTYPE_AVATAR("Avatar");
-LLMemType::DeclareMemType LLMemType::MTYPE_AVATAR_MESH("AvatarMesh");
-LLMemType::DeclareMemType LLMemType::MTYPE_PARTICLES("Particles");
-LLMemType::DeclareMemType LLMemType::MTYPE_REGIONS("Regions");
-
-LLMemType::DeclareMemType LLMemType::MTYPE_INVENTORY("Inventory");
-LLMemType::DeclareMemType LLMemType::MTYPE_INVENTORY_DRAW("InventoryDraw");
-LLMemType::DeclareMemType LLMemType::MTYPE_INVENTORY_BUILD_NEW_VIEWS("InventoryBuildNewViews");
-LLMemType::DeclareMemType LLMemType::MTYPE_INVENTORY_DO_FOLDER("InventoryDoFolder");
-LLMemType::DeclareMemType LLMemType::MTYPE_INVENTORY_POST_BUILD("InventoryPostBuild");
-LLMemType::DeclareMemType LLMemType::MTYPE_INVENTORY_FROM_XML("InventoryFromXML");
-LLMemType::DeclareMemType LLMemType::MTYPE_INVENTORY_CREATE_NEW_ITEM("InventoryCreateNewItem");
-LLMemType::DeclareMemType LLMemType::MTYPE_INVENTORY_VIEW_INIT("InventoryViewInit");
-LLMemType::DeclareMemType LLMemType::MTYPE_INVENTORY_VIEW_SHOW("InventoryViewShow");
-LLMemType::DeclareMemType LLMemType::MTYPE_INVENTORY_VIEW_TOGGLE("InventoryViewToggle");
-
-LLMemType::DeclareMemType LLMemType::MTYPE_ANIMATION("Animation");
-LLMemType::DeclareMemType LLMemType::MTYPE_VOLUME("Volume");
-LLMemType::DeclareMemType LLMemType::MTYPE_PRIMITIVE("Primitive");
-
-LLMemType::DeclareMemType LLMemType::MTYPE_SCRIPT("Script");
-LLMemType::DeclareMemType LLMemType::MTYPE_SCRIPT_RUN("ScriptRun");
-LLMemType::DeclareMemType LLMemType::MTYPE_SCRIPT_BYTECODE("ScriptByteCode");
-
-LLMemType::DeclareMemType LLMemType::MTYPE_IO_PUMP("IoPump");
-LLMemType::DeclareMemType LLMemType::MTYPE_IO_TCP("IoTCP");
-LLMemType::DeclareMemType LLMemType::MTYPE_IO_BUFFER("IoBuffer");
-LLMemType::DeclareMemType LLMemType::MTYPE_IO_HTTP_SERVER("IoHttpServer");
-LLMemType::DeclareMemType LLMemType::MTYPE_IO_SD_SERVER("IoSDServer");
-LLMemType::DeclareMemType LLMemType::MTYPE_IO_SD_CLIENT("IoSDClient");
-LLMemType::DeclareMemType LLMemType::MTYPE_IO_URL_REQUEST("IOUrlRequest");
-
-LLMemType::DeclareMemType LLMemType::MTYPE_DIRECTX_INIT("DirectXInit");
-
-LLMemType::DeclareMemType LLMemType::MTYPE_TEMP1("Temp1");
-LLMemType::DeclareMemType LLMemType::MTYPE_TEMP2("Temp2");
-LLMemType::DeclareMemType LLMemType::MTYPE_TEMP3("Temp3");
-LLMemType::DeclareMemType LLMemType::MTYPE_TEMP4("Temp4");
-LLMemType::DeclareMemType LLMemType::MTYPE_TEMP5("Temp5");
-LLMemType::DeclareMemType LLMemType::MTYPE_TEMP6("Temp6");
-LLMemType::DeclareMemType LLMemType::MTYPE_TEMP7("Temp7");
-LLMemType::DeclareMemType LLMemType::MTYPE_TEMP8("Temp8");
-LLMemType::DeclareMemType LLMemType::MTYPE_TEMP9("Temp9");
-
-LLMemType::DeclareMemType LLMemType::MTYPE_OTHER("Other");
-
-
-LLMemType::DeclareMemType::DeclareMemType(char const * st)
-{
- mID = (S32)mNameList.size();
- mName = st;
-
- mNameList.push_back(mName);
-}
-
-LLMemType::DeclareMemType::~DeclareMemType()
-{
-}
-
-LLMemType::LLMemType(LLMemType::DeclareMemType& dt)
-{
- mTypeIndex = dt.mID;
- LLAllocator::pushMemType(dt.mID);
-}
-
-LLMemType::~LLMemType()
-{
- LLAllocator::popMemType();
-}
-
-char const * LLMemType::getNameFromID(S32 id)
-{
- if (id < 0 || id >= (S32)DeclareMemType::mNameList.size())
- {
- return "INVALID";
- }
-
- return DeclareMemType::mNameList[id];
-}
-
-//--------------------------------------------------------------------------------------------------
diff --git a/indra/llcommon/llmemtype.h b/indra/llcommon/llmemtype.h
deleted file mode 100644
index 4945dbaf60..0000000000
--- a/indra/llcommon/llmemtype.h
+++ /dev/null
@@ -1,242 +0,0 @@
-/**
- * @file llmemtype.h
- * @brief Runtime memory usage debugging utilities.
- *
- * $LicenseInfo:firstyear=2005&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$
- */
-
-#ifndef LL_MEMTYPE_H
-#define LL_MEMTYPE_H
-
-//----------------------------------------------------------------------------
-//----------------------------------------------------------------------------
-
-//----------------------------------------------------------------------------
-
-#include "linden_common.h"
-//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-// WARNING: Never commit with MEM_TRACK_MEM == 1
-//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-#define MEM_TRACK_MEM (0 && LL_WINDOWS)
-
-#include <vector>
-
-#define MEM_TYPE_NEW(T)
-
-class LL_COMMON_API LLMemType
-{
-public:
-
- // class we'll initialize all instances of as
- // static members of MemType. Then use
- // to construct any new mem type.
- class LL_COMMON_API DeclareMemType
- {
- public:
- DeclareMemType(char const * st);
- ~DeclareMemType();
-
- S32 mID;
- char const * mName;
-
- // array so we can map an index ID to Name
- static std::vector<char const *> mNameList;
- };
-
- LLMemType(DeclareMemType& dt);
- ~LLMemType();
-
- static char const * getNameFromID(S32 id);
-
- static DeclareMemType MTYPE_INIT;
- static DeclareMemType MTYPE_STARTUP;
- static DeclareMemType MTYPE_MAIN;
- static DeclareMemType MTYPE_FRAME;
-
- static DeclareMemType MTYPE_GATHER_INPUT;
- static DeclareMemType MTYPE_JOY_KEY;
-
- static DeclareMemType MTYPE_IDLE;
- static DeclareMemType MTYPE_IDLE_PUMP;
- static DeclareMemType MTYPE_IDLE_NETWORK;
- static DeclareMemType MTYPE_IDLE_UPDATE_REGIONS;
- static DeclareMemType MTYPE_IDLE_UPDATE_VIEWER_REGION;
- static DeclareMemType MTYPE_IDLE_UPDATE_SURFACE;
- static DeclareMemType MTYPE_IDLE_UPDATE_PARCEL_OVERLAY;
- static DeclareMemType MTYPE_IDLE_AUDIO;
-
- static DeclareMemType MTYPE_CACHE_PROCESS_PENDING;
- static DeclareMemType MTYPE_CACHE_PROCESS_PENDING_ASKS;
- static DeclareMemType MTYPE_CACHE_PROCESS_PENDING_REPLIES;
-
- static DeclareMemType MTYPE_MESSAGE_CHECK_ALL;
- static DeclareMemType MTYPE_MESSAGE_PROCESS_ACKS;
-
- static DeclareMemType MTYPE_RENDER;
- static DeclareMemType MTYPE_SLEEP;
-
- static DeclareMemType MTYPE_NETWORK;
- static DeclareMemType MTYPE_PHYSICS;
- static DeclareMemType MTYPE_INTERESTLIST;
-
- static DeclareMemType MTYPE_IMAGEBASE;
- static DeclareMemType MTYPE_IMAGERAW;
- static DeclareMemType MTYPE_IMAGEFORMATTED;
-
- static DeclareMemType MTYPE_APPFMTIMAGE;
- static DeclareMemType MTYPE_APPRAWIMAGE;
- static DeclareMemType MTYPE_APPAUXRAWIMAGE;
-
- static DeclareMemType MTYPE_DRAWABLE;
-
- static DeclareMemType MTYPE_OBJECT;
- static DeclareMemType MTYPE_OBJECT_PROCESS_UPDATE;
- static DeclareMemType MTYPE_OBJECT_PROCESS_UPDATE_CORE;
-
- static DeclareMemType MTYPE_DISPLAY;
- static DeclareMemType MTYPE_DISPLAY_UPDATE;
- static DeclareMemType MTYPE_DISPLAY_UPDATE_CAMERA;
- static DeclareMemType MTYPE_DISPLAY_UPDATE_GEOM;
- static DeclareMemType MTYPE_DISPLAY_SWAP;
- static DeclareMemType MTYPE_DISPLAY_UPDATE_HUD;
- static DeclareMemType MTYPE_DISPLAY_GEN_REFLECTION;
- static DeclareMemType MTYPE_DISPLAY_IMAGE_UPDATE;
- static DeclareMemType MTYPE_DISPLAY_STATE_SORT;
- static DeclareMemType MTYPE_DISPLAY_SKY;
- static DeclareMemType MTYPE_DISPLAY_RENDER_GEOM;
- static DeclareMemType MTYPE_DISPLAY_RENDER_FLUSH;
- static DeclareMemType MTYPE_DISPLAY_RENDER_UI;
- static DeclareMemType MTYPE_DISPLAY_RENDER_ATTACHMENTS;
-
- static DeclareMemType MTYPE_VERTEX_DATA;
- static DeclareMemType MTYPE_VERTEX_CONSTRUCTOR;
- static DeclareMemType MTYPE_VERTEX_DESTRUCTOR;
- static DeclareMemType MTYPE_VERTEX_CREATE_VERTICES;
- static DeclareMemType MTYPE_VERTEX_CREATE_INDICES;
- static DeclareMemType MTYPE_VERTEX_DESTROY_BUFFER;
- static DeclareMemType MTYPE_VERTEX_DESTROY_INDICES;
- static DeclareMemType MTYPE_VERTEX_UPDATE_VERTS;
- static DeclareMemType MTYPE_VERTEX_UPDATE_INDICES;
- static DeclareMemType MTYPE_VERTEX_ALLOCATE_BUFFER;
- static DeclareMemType MTYPE_VERTEX_RESIZE_BUFFER;
- static DeclareMemType MTYPE_VERTEX_MAP_BUFFER;
- static DeclareMemType MTYPE_VERTEX_MAP_BUFFER_VERTICES;
- static DeclareMemType MTYPE_VERTEX_MAP_BUFFER_INDICES;
- static DeclareMemType MTYPE_VERTEX_UNMAP_BUFFER;
- static DeclareMemType MTYPE_VERTEX_SET_STRIDE;
- static DeclareMemType MTYPE_VERTEX_SET_BUFFER;
- static DeclareMemType MTYPE_VERTEX_SETUP_VERTEX_BUFFER;
- static DeclareMemType MTYPE_VERTEX_CLEANUP_CLASS;
-
- static DeclareMemType MTYPE_SPACE_PARTITION;
-
- static DeclareMemType MTYPE_PIPELINE;
- static DeclareMemType MTYPE_PIPELINE_INIT;
- static DeclareMemType MTYPE_PIPELINE_CREATE_BUFFERS;
- static DeclareMemType MTYPE_PIPELINE_RESTORE_GL;
- static DeclareMemType MTYPE_PIPELINE_UNLOAD_SHADERS;
- static DeclareMemType MTYPE_PIPELINE_LIGHTING_DETAIL;
- static DeclareMemType MTYPE_PIPELINE_GET_POOL_TYPE;
- static DeclareMemType MTYPE_PIPELINE_ADD_POOL;
- static DeclareMemType MTYPE_PIPELINE_ALLOCATE_DRAWABLE;
- static DeclareMemType MTYPE_PIPELINE_ADD_OBJECT;
- static DeclareMemType MTYPE_PIPELINE_CREATE_OBJECTS;
- static DeclareMemType MTYPE_PIPELINE_UPDATE_MOVE;
- static DeclareMemType MTYPE_PIPELINE_UPDATE_GEOM;
- static DeclareMemType MTYPE_PIPELINE_MARK_VISIBLE;
- static DeclareMemType MTYPE_PIPELINE_MARK_MOVED;
- static DeclareMemType MTYPE_PIPELINE_MARK_SHIFT;
- static DeclareMemType MTYPE_PIPELINE_SHIFT_OBJECTS;
- static DeclareMemType MTYPE_PIPELINE_MARK_TEXTURED;
- static DeclareMemType MTYPE_PIPELINE_MARK_REBUILD;
- static DeclareMemType MTYPE_PIPELINE_UPDATE_CULL;
- static DeclareMemType MTYPE_PIPELINE_STATE_SORT;
- static DeclareMemType MTYPE_PIPELINE_POST_SORT;
-
- static DeclareMemType MTYPE_PIPELINE_RENDER_HUD_ELS;
- static DeclareMemType MTYPE_PIPELINE_RENDER_HL;
- static DeclareMemType MTYPE_PIPELINE_RENDER_GEOM;
- static DeclareMemType MTYPE_PIPELINE_RENDER_GEOM_DEFFERRED;
- static DeclareMemType MTYPE_PIPELINE_RENDER_GEOM_POST_DEF;
- static DeclareMemType MTYPE_PIPELINE_RENDER_GEOM_SHADOW;
- static DeclareMemType MTYPE_PIPELINE_RENDER_SELECT;
- static DeclareMemType MTYPE_PIPELINE_REBUILD_POOLS;
- static DeclareMemType MTYPE_PIPELINE_QUICK_LOOKUP;
- static DeclareMemType MTYPE_PIPELINE_RENDER_OBJECTS;
- static DeclareMemType MTYPE_PIPELINE_GENERATE_IMPOSTOR;
- static DeclareMemType MTYPE_PIPELINE_RENDER_BLOOM;
-
- static DeclareMemType MTYPE_UPKEEP_POOLS;
-
- static DeclareMemType MTYPE_AVATAR;
- static DeclareMemType MTYPE_AVATAR_MESH;
- static DeclareMemType MTYPE_PARTICLES;
- static DeclareMemType MTYPE_REGIONS;
-
- static DeclareMemType MTYPE_INVENTORY;
- static DeclareMemType MTYPE_INVENTORY_DRAW;
- static DeclareMemType MTYPE_INVENTORY_BUILD_NEW_VIEWS;
- static DeclareMemType MTYPE_INVENTORY_DO_FOLDER;
- static DeclareMemType MTYPE_INVENTORY_POST_BUILD;
- static DeclareMemType MTYPE_INVENTORY_FROM_XML;
- static DeclareMemType MTYPE_INVENTORY_CREATE_NEW_ITEM;
- static DeclareMemType MTYPE_INVENTORY_VIEW_INIT;
- static DeclareMemType MTYPE_INVENTORY_VIEW_SHOW;
- static DeclareMemType MTYPE_INVENTORY_VIEW_TOGGLE;
-
- static DeclareMemType MTYPE_ANIMATION;
- static DeclareMemType MTYPE_VOLUME;
- static DeclareMemType MTYPE_PRIMITIVE;
-
- static DeclareMemType MTYPE_SCRIPT;
- static DeclareMemType MTYPE_SCRIPT_RUN;
- static DeclareMemType MTYPE_SCRIPT_BYTECODE;
-
- static DeclareMemType MTYPE_IO_PUMP;
- static DeclareMemType MTYPE_IO_TCP;
- static DeclareMemType MTYPE_IO_BUFFER;
- static DeclareMemType MTYPE_IO_HTTP_SERVER;
- static DeclareMemType MTYPE_IO_SD_SERVER;
- static DeclareMemType MTYPE_IO_SD_CLIENT;
- static DeclareMemType MTYPE_IO_URL_REQUEST;
-
- static DeclareMemType MTYPE_DIRECTX_INIT;
-
- static DeclareMemType MTYPE_TEMP1;
- static DeclareMemType MTYPE_TEMP2;
- static DeclareMemType MTYPE_TEMP3;
- static DeclareMemType MTYPE_TEMP4;
- static DeclareMemType MTYPE_TEMP5;
- static DeclareMemType MTYPE_TEMP6;
- static DeclareMemType MTYPE_TEMP7;
- static DeclareMemType MTYPE_TEMP8;
- static DeclareMemType MTYPE_TEMP9;
-
- static DeclareMemType MTYPE_OTHER; // Special; used by display code
-
- S32 mTypeIndex;
-};
-
-//----------------------------------------------------------------------------
-
-#endif
-
diff --git a/indra/llcommon/llmetricperformancetester.cpp b/indra/llcommon/llmetricperformancetester.cpp
index 41d3eb0bf3..731e58bd20 100644..100755
--- a/indra/llcommon/llmetricperformancetester.cpp
+++ b/indra/llcommon/llmetricperformancetester.cpp
@@ -100,7 +100,7 @@ LLSD LLMetricPerformanceTesterBasic::analyzeMetricPerformanceLog(std::istream& i
LLSD ret;
LLSD cur;
- while (!is.eof() && LLSDSerialize::fromXML(cur, is))
+ while (!is.eof() && LLSDParser::PARSE_FAILURE != LLSDSerialize::fromXML(cur, is))
{
for (LLSD::map_iterator iter = cur.beginMap(); iter != cur.endMap(); ++iter)
{
diff --git a/indra/llcommon/llmetricperformancetester.h b/indra/llcommon/llmetricperformancetester.h
index 1a18cdf36f..1a18cdf36f 100644..100755
--- a/indra/llcommon/llmetricperformancetester.h
+++ b/indra/llcommon/llmetricperformancetester.h
diff --git a/indra/llcommon/llmetrics.cpp b/indra/llcommon/llmetrics.cpp
index 3078139f43..3078139f43 100644..100755
--- a/indra/llcommon/llmetrics.cpp
+++ b/indra/llcommon/llmetrics.cpp
diff --git a/indra/llcommon/llmetrics.h b/indra/llcommon/llmetrics.h
index 4f0ae56338..4f0ae56338 100644..100755
--- a/indra/llcommon/llmetrics.h
+++ b/indra/llcommon/llmetrics.h
diff --git a/indra/llcommon/llmortician.cpp b/indra/llcommon/llmortician.cpp
index 287f096eae..287f096eae 100644..100755
--- a/indra/llcommon/llmortician.cpp
+++ b/indra/llcommon/llmortician.cpp
diff --git a/indra/llcommon/llmortician.h b/indra/llcommon/llmortician.h
index 319955ef93..319955ef93 100644..100755
--- a/indra/llcommon/llmortician.h
+++ b/indra/llcommon/llmortician.h
diff --git a/indra/llcommon/llnametable.h b/indra/llcommon/llnametable.h
index d3283543f3..d3283543f3 100644..100755
--- a/indra/llcommon/llnametable.h
+++ b/indra/llcommon/llnametable.h
diff --git a/indra/llcommon/lloptioninterface.cpp b/indra/llcommon/lloptioninterface.cpp
index 23fae76dc0..23fae76dc0 100644..100755
--- a/indra/llcommon/lloptioninterface.cpp
+++ b/indra/llcommon/lloptioninterface.cpp
diff --git a/indra/llcommon/lloptioninterface.h b/indra/llcommon/lloptioninterface.h
index 93b465db32..93b465db32 100644..100755
--- a/indra/llcommon/lloptioninterface.h
+++ b/indra/llcommon/lloptioninterface.h
diff --git a/indra/llcommon/llpointer.h b/indra/llcommon/llpointer.h
index affa040602..88c09c8dca 100644..100755
--- a/indra/llcommon/llpointer.h
+++ b/indra/llcommon/llpointer.h
@@ -140,6 +140,10 @@ public:
}
protected:
+#ifdef LL_LIBRARY_INCLUDE
+ void ref();
+ void unref();
+#else
void ref()
{
if (mPointer)
@@ -162,7 +166,7 @@ protected:
}
}
}
-
+#endif
protected:
Type* mPointer;
};
diff --git a/indra/llcommon/llpreprocessor.h b/indra/llcommon/llpreprocessor.h
index 7fdb537ab5..7fdb537ab5 100644..100755
--- a/indra/llcommon/llpreprocessor.h
+++ b/indra/llcommon/llpreprocessor.h
diff --git a/indra/llcommon/llpriqueuemap.h b/indra/llcommon/llpriqueuemap.h
index da997c7b04..da997c7b04 100644..100755
--- a/indra/llcommon/llpriqueuemap.h
+++ b/indra/llcommon/llpriqueuemap.h
diff --git a/indra/llcommon/llprocess.cpp b/indra/llcommon/llprocess.cpp
new file mode 100755
index 0000000000..715df36f39
--- /dev/null
+++ b/indra/llcommon/llprocess.cpp
@@ -0,0 +1,1351 @@
+/**
+ * @file llprocess.cpp
+ * @brief Utility class for launching, terminating, and tracking the state of processes.
+ *
+ * $LicenseInfo:firstyear=2008&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 "llprocess.h"
+#include "llsdutil.h"
+#include "llsdserialize.h"
+#include "llsingleton.h"
+#include "llstring.h"
+#include "stringize.h"
+#include "llapr.h"
+#include "apr_signal.h"
+#include "llevents.h"
+
+#include <boost/foreach.hpp>
+#include <boost/bind.hpp>
+#include <boost/asio/streambuf.hpp>
+#include <boost/asio/buffers_iterator.hpp>
+#include <iostream>
+#include <stdexcept>
+#include <limits>
+#include <algorithm>
+#include <vector>
+#include <typeinfo>
+#include <utility>
+
+/*****************************************************************************
+* Helpers
+*****************************************************************************/
+static const char* whichfile_[] = { "stdin", "stdout", "stderr" };
+static std::string empty;
+static LLProcess::Status interpret_status(int status);
+static std::string getDesc(const LLProcess::Params& params);
+
+static std::string whichfile(LLProcess::FILESLOT index)
+{
+ if (index < LL_ARRAY_SIZE(whichfile_))
+ return whichfile_[index];
+ return STRINGIZE("file slot " << index);
+}
+
+/**
+ * Ref-counted "mainloop" listener. As long as there are still outstanding
+ * LLProcess objects, keep listening on "mainloop" so we can keep polling APR
+ * for process status.
+ */
+class LLProcessListener
+{
+ LOG_CLASS(LLProcessListener);
+public:
+ LLProcessListener():
+ mCount(0)
+ {}
+
+ void addPoll(const LLProcess&)
+ {
+ // Unconditionally increment mCount. If it was zero before
+ // incrementing, listen on "mainloop".
+ if (mCount++ == 0)
+ {
+ LL_DEBUGS("LLProcess") << "listening on \"mainloop\"" << LL_ENDL;
+ mConnection = LLEventPumps::instance().obtain("mainloop")
+ .listen("LLProcessListener", boost::bind(&LLProcessListener::tick, this, _1));
+ }
+ }
+
+ void dropPoll(const LLProcess&)
+ {
+ // Unconditionally decrement mCount. If it's zero after decrementing,
+ // stop listening on "mainloop".
+ if (--mCount == 0)
+ {
+ LL_DEBUGS("LLProcess") << "disconnecting from \"mainloop\"" << LL_ENDL;
+ mConnection.disconnect();
+ }
+ }
+
+private:
+ /// called once per frame by the "mainloop" LLEventPump
+ bool tick(const LLSD&)
+ {
+ // Tell APR to sense whether each registered LLProcess is still
+ // running and call handle_status() appropriately. We should be able
+ // to get the same info from an apr_proc_wait(APR_NOWAIT) call; but at
+ // least in APR 1.4.2, testing suggests that even with APR_NOWAIT,
+ // apr_proc_wait() blocks the caller. We can't have that in the
+ // viewer. Hence the callback rigmarole. (Once we update APR, it's
+ // probably worth testing again.) Also -- although there's an
+ // apr_proc_other_child_refresh() call, i.e. get that information for
+ // one specific child, it accepts an 'apr_other_child_rec_t*' that's
+ // mentioned NOWHERE else in the documentation or header files! I
+ // would use the specific call in LLProcess::getStatus() if I knew
+ // how. As it is, each call to apr_proc_other_child_refresh_all() will
+ // call callbacks for ALL still-running child processes. That's why we
+ // centralize such calls, using "mainloop" to ensure it happens once
+ // per frame, and refcounting running LLProcess objects to remain
+ // registered only while needed.
+ LL_DEBUGS("LLProcess") << "calling apr_proc_other_child_refresh_all()" << LL_ENDL;
+ apr_proc_other_child_refresh_all(APR_OC_REASON_RUNNING);
+ return false;
+ }
+
+ /// If this object is destroyed before mCount goes to zero, stop
+ /// listening on "mainloop" anyway.
+ LLTempBoundListener mConnection;
+ unsigned mCount;
+};
+static LLProcessListener sProcessListener;
+
+/*****************************************************************************
+* WritePipe and ReadPipe
+*****************************************************************************/
+LLProcess::BasePipe::~BasePipe() {}
+const LLProcess::BasePipe::size_type
+ // use funky syntax to call max() to avoid blighted max() macros
+ LLProcess::BasePipe::npos((std::numeric_limits<LLProcess::BasePipe::size_type>::max)());
+
+class WritePipeImpl: public LLProcess::WritePipe
+{
+ LOG_CLASS(WritePipeImpl);
+public:
+ WritePipeImpl(const std::string& desc, apr_file_t* pipe):
+ mDesc(desc),
+ mPipe(pipe),
+ // Essential to initialize our std::ostream with our special streambuf!
+ mStream(&mStreambuf)
+ {
+ mConnection = LLEventPumps::instance().obtain("mainloop")
+ .listen(LLEventPump::inventName("WritePipe"),
+ boost::bind(&WritePipeImpl::tick, this, _1));
+
+#if ! LL_WINDOWS
+ // We can't count on every child process reading everything we try to
+ // write to it. And if the child terminates with WritePipe data still
+ // pending, unless we explicitly suppress it, Posix will hit us with
+ // SIGPIPE. That would terminate the viewer, boom. "Ignoring" it means
+ // APR gets the correct errno, passes it back to us, we log it, etc.
+ signal(SIGPIPE, SIG_IGN);
+#endif
+ }
+
+ virtual std::ostream& get_ostream() { return mStream; }
+ virtual size_type size() const { return mStreambuf.size(); }
+
+ bool tick(const LLSD&)
+ {
+ typedef boost::asio::streambuf::const_buffers_type const_buffer_sequence;
+ // If there's anything to send, try to send it.
+ std::size_t total(mStreambuf.size()), consumed(0);
+ if (total)
+ {
+ const_buffer_sequence bufs = mStreambuf.data();
+ // In general, our streambuf might contain a number of different
+ // physical buffers; iterate over those.
+ bool keepwriting = true;
+ for (const_buffer_sequence::const_iterator bufi(bufs.begin()), bufend(bufs.end());
+ bufi != bufend && keepwriting; ++bufi)
+ {
+ // http://www.boost.org/doc/libs/1_49_0_beta1/doc/html/boost_asio/reference/buffer.html#boost_asio.reference.buffer.accessing_buffer_contents
+ // Although apr_file_write() accepts const void*, we
+ // manipulate const char* so we can increment the pointer.
+ const char* remainptr = boost::asio::buffer_cast<const char*>(*bufi);
+ std::size_t remainlen = boost::asio::buffer_size(*bufi);
+ while (remainlen)
+ {
+ // Tackle the current buffer in discrete chunks. On
+ // Windows, we've observed strange failures when trying to
+ // write big lengths (~1 MB) in a single operation. Even a
+ // 32K chunk seems too large. At some point along the way
+ // apr_file_write() returns 11 (Resource temporarily
+ // unavailable, i.e. EAGAIN) and says it wrote 0 bytes --
+ // even though it did write the chunk! Our next write
+ // attempt retries with the same chunk, resulting in the
+ // chunk being duplicated at the child end. Using smaller
+ // chunks is empirically more reliable.
+ std::size_t towrite((std::min)(remainlen, std::size_t(4*1024)));
+ apr_size_t written(towrite);
+ apr_status_t err = apr_file_write(mPipe, remainptr, &written);
+ // EAGAIN is exactly what we want from a nonblocking pipe.
+ // Rather than waiting for data, it should return immediately.
+ if (! (err == APR_SUCCESS || APR_STATUS_IS_EAGAIN(err)))
+ {
+ LL_WARNS("LLProcess") << "apr_file_write(" << towrite << ") on " << mDesc
+ << " got " << err << ":" << LL_ENDL;
+ ll_apr_warn_status(err);
+ }
+
+ // 'written' is modified to reflect the number of bytes actually
+ // written. Make sure we consume those later. (Don't consume them
+ // now, that would invalidate the buffer iterator sequence!)
+ consumed += written;
+ // don't forget to advance to next chunk of current buffer
+ remainptr += written;
+ remainlen -= written;
+
+ char msgbuf[512];
+ LL_DEBUGS("LLProcess") << "wrote " << written << " of " << towrite
+ << " bytes to " << mDesc
+ << " (original " << total << "),"
+ << " code " << err << ": "
+ << apr_strerror(err, msgbuf, sizeof(msgbuf))
+ << LL_ENDL;
+
+ // The parent end of this pipe is nonblocking. If we weren't able
+ // to write everything we wanted, don't keep banging on it -- that
+ // won't change until the child reads some. Wait for next tick().
+ if (written < towrite)
+ {
+ keepwriting = false; // break outer loop over buffers too
+ break;
+ }
+ } // next chunk of current buffer
+ } // next buffer
+ // In all, we managed to write 'consumed' bytes. Remove them from the
+ // streambuf so we don't keep trying to send them. This could be
+ // anywhere from 0 up to mStreambuf.size(); anything we haven't yet
+ // sent, we'll try again later.
+ mStreambuf.consume(consumed);
+ }
+
+ return false;
+ }
+
+private:
+ std::string mDesc;
+ apr_file_t* mPipe;
+ LLTempBoundListener mConnection;
+ boost::asio::streambuf mStreambuf;
+ std::ostream mStream;
+};
+
+class ReadPipeImpl: public LLProcess::ReadPipe
+{
+ LOG_CLASS(ReadPipeImpl);
+public:
+ ReadPipeImpl(const std::string& desc, apr_file_t* pipe, LLProcess::FILESLOT index):
+ mDesc(desc),
+ mPipe(pipe),
+ mIndex(index),
+ // Essential to initialize our std::istream with our special streambuf!
+ mStream(&mStreambuf),
+ mPump("ReadPipe", true), // tweak name as needed to avoid collisions
+ mLimit(0),
+ mEOF(false)
+ {
+ mConnection = LLEventPumps::instance().obtain("mainloop")
+ .listen(LLEventPump::inventName("ReadPipe"),
+ boost::bind(&ReadPipeImpl::tick, this, _1));
+ }
+
+ // Much of the implementation is simply connecting the abstract virtual
+ // methods with implementation data concealed from the base class.
+ virtual std::istream& get_istream() { return mStream; }
+ virtual std::string getline() { return LLProcess::getline(mStream); }
+ virtual LLEventPump& getPump() { return mPump; }
+ virtual void setLimit(size_type limit) { mLimit = limit; }
+ virtual size_type getLimit() const { return mLimit; }
+ virtual size_type size() const { return mStreambuf.size(); }
+
+ virtual std::string read(size_type len)
+ {
+ // Read specified number of bytes into a buffer.
+ size_type readlen((std::min)(size(), len));
+ // Formally, &buffer[0] is invalid for a vector of size() 0. Exit
+ // early in that situation.
+ if (! readlen)
+ return "";
+ // Make a buffer big enough.
+ std::vector<char> buffer(readlen);
+ mStream.read(&buffer[0], readlen);
+ // Since we've already clamped 'readlen', we can think of no reason
+ // why mStream.read() should read fewer than 'readlen' bytes.
+ // Nonetheless, use the actual retrieved length.
+ return std::string(&buffer[0], mStream.gcount());
+ }
+
+ virtual std::string peek(size_type offset=0, size_type len=npos) const
+ {
+ // Constrain caller's offset and len to overlap actual buffer content.
+ std::size_t real_offset = (std::min)(mStreambuf.size(), std::size_t(offset));
+ size_type want_end = (len == npos)? npos : (real_offset + len);
+ std::size_t real_end = (std::min)(mStreambuf.size(), std::size_t(want_end));
+ boost::asio::streambuf::const_buffers_type cbufs = mStreambuf.data();
+ return std::string(boost::asio::buffers_begin(cbufs) + real_offset,
+ boost::asio::buffers_begin(cbufs) + real_end);
+ }
+
+ virtual size_type find(const std::string& seek, size_type offset=0) const
+ {
+ // If we're passing a string of length 1, use find(char), which can
+ // use an O(n) std::find() rather than the O(n^2) std::search().
+ if (seek.length() == 1)
+ {
+ return find(seek[0], offset);
+ }
+
+ // If offset is beyond the whole buffer, can't even construct a valid
+ // iterator range; can't possibly find the string we seek.
+ if (offset > mStreambuf.size())
+ {
+ return npos;
+ }
+
+ boost::asio::streambuf::const_buffers_type cbufs = mStreambuf.data();
+ boost::asio::buffers_iterator<boost::asio::streambuf::const_buffers_type>
+ begin(boost::asio::buffers_begin(cbufs)),
+ end (boost::asio::buffers_end(cbufs)),
+ found(std::search(begin + offset, end, seek.begin(), seek.end()));
+ return (found == end)? npos : (found - begin);
+ }
+
+ virtual size_type find(char seek, size_type offset=0) const
+ {
+ // If offset is beyond the whole buffer, can't even construct a valid
+ // iterator range; can't possibly find the char we seek.
+ if (offset > mStreambuf.size())
+ {
+ return npos;
+ }
+
+ boost::asio::streambuf::const_buffers_type cbufs = mStreambuf.data();
+ boost::asio::buffers_iterator<boost::asio::streambuf::const_buffers_type>
+ begin(boost::asio::buffers_begin(cbufs)),
+ end (boost::asio::buffers_end(cbufs)),
+ found(std::find(begin + offset, end, seek));
+ return (found == end)? npos : (found - begin);
+ }
+
+ bool tick(const LLSD&)
+ {
+ // Once we've hit EOF, skip all the rest of this.
+ if (mEOF)
+ return false;
+
+ typedef boost::asio::streambuf::mutable_buffers_type mutable_buffer_sequence;
+ // Try, every time, to read into our streambuf. In fact, we have no
+ // idea how much data the child might be trying to send: keep trying
+ // until we're convinced we've temporarily exhausted the pipe.
+ enum PipeState { RETRY, EXHAUSTED, CLOSED };
+ PipeState state = RETRY;
+ std::size_t committed(0);
+ do
+ {
+ // attempt to read an arbitrary size
+ mutable_buffer_sequence bufs = mStreambuf.prepare(4096);
+ // In general, the mutable_buffer_sequence returned by prepare() might
+ // contain a number of different physical buffers; iterate over those.
+ std::size_t tocommit(0);
+ for (mutable_buffer_sequence::const_iterator bufi(bufs.begin()), bufend(bufs.end());
+ bufi != bufend; ++bufi)
+ {
+ // http://www.boost.org/doc/libs/1_49_0_beta1/doc/html/boost_asio/reference/buffer.html#boost_asio.reference.buffer.accessing_buffer_contents
+ std::size_t toread(boost::asio::buffer_size(*bufi));
+ apr_size_t gotten(toread);
+ apr_status_t err = apr_file_read(mPipe,
+ boost::asio::buffer_cast<void*>(*bufi),
+ &gotten);
+ // EAGAIN is exactly what we want from a nonblocking pipe.
+ // Rather than waiting for data, it should return immediately.
+ if (! (err == APR_SUCCESS || APR_STATUS_IS_EAGAIN(err)))
+ {
+ // Handle EOF specially: it's part of normal-case processing.
+ if (err == APR_EOF)
+ {
+ LL_DEBUGS("LLProcess") << "EOF on " << mDesc << LL_ENDL;
+ }
+ else
+ {
+ LL_WARNS("LLProcess") << "apr_file_read(" << toread << ") on " << mDesc
+ << " got " << err << ":" << LL_ENDL;
+ ll_apr_warn_status(err);
+ }
+ // Either way, though, we won't need any more tick() calls.
+ mConnection.disconnect();
+ // Ignore any subsequent calls we might get anyway.
+ mEOF = true;
+ state = CLOSED; // also break outer retry loop
+ break;
+ }
+
+ // 'gotten' was modified to reflect the number of bytes actually
+ // received. Make sure we commit those later. (Don't commit them
+ // now, that would invalidate the buffer iterator sequence!)
+ tocommit += gotten;
+ LL_DEBUGS("LLProcess") << "filled " << gotten << " of " << toread
+ << " bytes from " << mDesc << LL_ENDL;
+
+ // The parent end of this pipe is nonblocking. If we weren't even
+ // able to fill this buffer, don't loop to try to fill the next --
+ // that won't change until the child writes more. Wait for next
+ // tick().
+ if (gotten < toread)
+ {
+ // break outer retry loop too
+ state = EXHAUSTED;
+ break;
+ }
+ }
+
+ // Don't forget to "commit" the data!
+ mStreambuf.commit(tocommit);
+ committed += tocommit;
+
+ // state is changed from RETRY when we can't fill any one buffer
+ // of the mutable_buffer_sequence established by the current
+ // prepare() call -- whether due to error or not enough bytes.
+ // That is, if state is still RETRY, we've filled every physical
+ // buffer in the mutable_buffer_sequence. In that case, for all we
+ // know, the child might have still more data pending -- go for it!
+ } while (state == RETRY);
+
+ // Once we recognize that the pipe is closed, make one more call to
+ // listener. The listener might be waiting for a particular substring
+ // to arrive, or a particular length of data or something. The event
+ // with "eof" == true announces that nothing further will arrive, so
+ // use it or lose it.
+ if (committed || state == CLOSED)
+ {
+ // If we actually received new data, publish it on our LLEventPump
+ // as advertised. Constrain it by mLimit. But show listener the
+ // actual accumulated buffer size, regardless of mLimit.
+ size_type datasize((std::min)(mLimit, size_type(mStreambuf.size())));
+ mPump.post(LLSDMap
+ ("data", peek(0, datasize))
+ ("len", LLSD::Integer(mStreambuf.size()))
+ ("slot", LLSD::Integer(mIndex))
+ ("name", whichfile(mIndex))
+ ("desc", mDesc)
+ ("eof", state == CLOSED));
+ }
+
+ return false;
+ }
+
+private:
+ std::string mDesc;
+ apr_file_t* mPipe;
+ LLProcess::FILESLOT mIndex;
+ LLTempBoundListener mConnection;
+ boost::asio::streambuf mStreambuf;
+ std::istream mStream;
+ LLEventStream mPump;
+ size_type mLimit;
+ bool mEOF;
+};
+
+/*****************************************************************************
+* LLProcess itself
+*****************************************************************************/
+/// Need an exception to avoid constructing an invalid LLProcess object, but
+/// internal use only
+struct LLProcessError: public std::runtime_error
+{
+ LLProcessError(const std::string& msg): std::runtime_error(msg) {}
+};
+
+LLProcessPtr LLProcess::create(const LLSDOrParams& params)
+{
+ try
+ {
+ return LLProcessPtr(new LLProcess(params));
+ }
+ catch (const LLProcessError& e)
+ {
+ LL_WARNS("LLProcess") << e.what() << LL_ENDL;
+
+ // If caller is requesting an event on process termination, send one
+ // indicating bad launch. This may prevent someone waiting forever for
+ // a termination post that can't arrive because the child never
+ // started.
+ if (params.postend.isProvided())
+ {
+ LLEventPumps::instance().obtain(params.postend)
+ .post(LLSDMap
+ // no "id"
+ ("desc", getDesc(params))
+ ("state", LLProcess::UNSTARTED)
+ // no "data"
+ ("string", e.what())
+ );
+ }
+
+ return LLProcessPtr();
+ }
+}
+
+/// Call an apr function returning apr_status_t. On failure, log warning and
+/// throw LLProcessError mentioning the function call that produced that
+/// result.
+#define chkapr(func) \
+ if (ll_apr_warn_status(func)) \
+ throw LLProcessError(#func " failed")
+
+LLProcess::LLProcess(const LLSDOrParams& params):
+ mAutokill(params.autokill),
+ mPipes(NSLOTS)
+{
+ // Hmm, when you construct a ptr_vector with a size, it merely reserves
+ // space, it doesn't actually make it that big. Explicitly make it bigger.
+ // Because of ptr_vector's odd semantics, have to push_back(0) the right
+ // number of times! resize() wants to default-construct new BasePipe
+ // instances, which fails because it's pure virtual. But because of the
+ // constructor call, these push_back() calls should require no new
+ // allocation.
+ for (size_t i = 0; i < mPipes.capacity(); ++i)
+ mPipes.push_back(0);
+
+ if (! params.validateBlock(true))
+ {
+ throw LLProcessError(STRINGIZE("not launched: failed parameter validation\n"
+ << LLSDNotationStreamer(params)));
+ }
+
+ mPostend = params.postend;
+
+ apr_procattr_t *procattr = NULL;
+ chkapr(apr_procattr_create(&procattr, gAPRPoolp));
+
+ // IQA-490, CHOP-900: On Windows, ask APR to jump through hoops to
+ // constrain the set of handles passed to the child process. Before we
+ // changed to APR, the Windows implementation of LLProcessLauncher called
+ // CreateProcess(bInheritHandles=FALSE), meaning to pass NO open handles
+ // to the child process. Now that we support pipes, though, we must allow
+ // apr_proc_create() to pass bInheritHandles=TRUE. But without taking
+ // special pains, that causes trouble in a number of ways, due to the fact
+ // that the viewer is constantly opening and closing files -- most of
+ // which CreateProcess() passes to every child process!
+#if ! defined(APR_HAS_PROCATTR_CONSTRAIN_HANDLE_SET)
+ // Our special preprocessor symbol isn't even defined -- wrong APR
+ LL_WARNS("LLProcess") << "This version of APR lacks Linden "
+ << "apr_procattr_constrain_handle_set() extension" << LL_ENDL;
+#else
+ chkapr(apr_procattr_constrain_handle_set(procattr, 1));
+#endif
+
+ // For which of stdin, stdout, stderr should we create a pipe to the
+ // child? In the viewer, there are only a couple viable
+ // apr_procattr_io_set() alternatives: inherit the viewer's own stdxxx
+ // handle (APR_NO_PIPE, e.g. for stdout, stderr), or create a pipe that's
+ // blocking on the child end but nonblocking at the viewer end
+ // (APR_CHILD_BLOCK).
+ // Other major options could include explicitly creating a single APR pipe
+ // and passing it as both stdout and stderr (apr_procattr_child_out_set(),
+ // apr_procattr_child_err_set()), or accepting a filename, opening it and
+ // passing that apr_file_t (simple <, >, 2> redirect emulation).
+ std::vector<apr_int32_t> select;
+ BOOST_FOREACH(const FileParam& fparam, params.files)
+ {
+ // Every iteration, we're going to append an item to 'select'. At the
+ // top of the loop, its size() is, in effect, an index. Use that to
+ // pick a string description for messages.
+ std::string which(whichfile(FILESLOT(select.size())));
+ if (fparam.type().empty()) // inherit our file descriptor
+ {
+ select.push_back(APR_NO_PIPE);
+ }
+ else if (fparam.type() == "pipe") // anonymous pipe
+ {
+ if (! fparam.name().empty())
+ {
+ LL_WARNS("LLProcess") << "For " << params.executable()
+ << ": internal names for reusing pipes ('"
+ << fparam.name() << "' for " << which
+ << ") are not yet supported -- creating distinct pipe"
+ << LL_ENDL;
+ }
+ // The viewer can't block for anything: the parent end MUST be
+ // nonblocking. As the APR documentation itself points out, it
+ // makes very little sense to set nonblocking I/O for the child
+ // end of a pipe: only a specially-written child could deal with
+ // that.
+ select.push_back(APR_CHILD_BLOCK);
+ }
+ else
+ {
+ throw LLProcessError(STRINGIZE("For " << params.executable()
+ << ": unsupported FileParam for " << which
+ << ": type='" << fparam.type()
+ << "', name='" << fparam.name() << "'"));
+ }
+ }
+ // By default, pass APR_NO_PIPE for unspecified slots.
+ while (select.size() < NSLOTS)
+ {
+ select.push_back(APR_NO_PIPE);
+ }
+ chkapr(apr_procattr_io_set(procattr, select[STDIN], select[STDOUT], select[STDERR]));
+
+ // Thumbs down on implicitly invoking the shell to invoke the child. From
+ // our point of view, the other major alternative to APR_PROGRAM_PATH
+ // would be APR_PROGRAM_ENV: still copy environment, but require full
+ // executable pathname. I don't see a downside to searching the PATH,
+ // though: if our caller wants (e.g.) a specific Python interpreter, s/he
+ // can still pass the full pathname.
+ chkapr(apr_procattr_cmdtype_set(procattr, APR_PROGRAM_PATH));
+ // YES, do extra work if necessary to report child exec() failures back to
+ // parent process.
+ chkapr(apr_procattr_error_check_set(procattr, 1));
+ // Do not start a non-autokill child in detached state. On Posix
+ // platforms, this setting attempts to daemonize the new child, closing
+ // std handles and the like, and that's a bit more detachment than we
+ // want. autokill=false just means not to implicitly kill the child when
+ // the parent terminates!
+// chkapr(apr_procattr_detach_set(procattr, params.autokill? 0 : 1));
+
+ if (params.autokill)
+ {
+#if ! defined(APR_HAS_PROCATTR_AUTOKILL_SET)
+ // Our special preprocessor symbol isn't even defined -- wrong APR
+ LL_WARNS("LLProcess") << "This version of APR lacks Linden apr_procattr_autokill_set() extension" << LL_ENDL;
+#elif ! APR_HAS_PROCATTR_AUTOKILL_SET
+ // Symbol is defined, but to 0: expect apr_procattr_autokill_set() to
+ // return APR_ENOTIMPL.
+#else // APR_HAS_PROCATTR_AUTOKILL_SET nonzero
+ ll_apr_warn_status(apr_procattr_autokill_set(procattr, 1));
+#endif
+ }
+
+ // In preparation for calling apr_proc_create(), we collect a number of
+ // const char* pointers obtained from std::string::c_str(). Turns out
+ // LLInitParam::Block's helpers Optional, Mandatory, Multiple et al.
+ // guarantee that converting to the wrapped type (std::string in our
+ // case), e.g. by calling operator(), returns a reference to *the same
+ // instance* of the wrapped type that's stored in our Block subclass.
+ // That's important! We know 'params' persists throughout this method
+ // call; but without that guarantee, we'd have to assume that converting
+ // one of its members to std::string might return a different (temp)
+ // instance. Capturing the c_str() from a temporary std::string is Bad Bad
+ // Bad. But armed with this knowledge, when you see params.cwd().c_str(),
+ // grit your teeth and smile and carry on.
+
+ if (params.cwd.isProvided())
+ {
+ chkapr(apr_procattr_dir_set(procattr, params.cwd().c_str()));
+ }
+
+ // create an argv vector for the child process
+ std::vector<const char*> argv;
+
+ // Add the executable path. See above remarks about c_str().
+ argv.push_back(params.executable().c_str());
+
+ // Add arguments. See above remarks about c_str().
+ BOOST_FOREACH(const std::string& arg, params.args)
+ {
+ argv.push_back(arg.c_str());
+ }
+
+ // terminate with a null pointer
+ argv.push_back(NULL);
+
+ // Launch! The NULL would be the environment block, if we were passing
+ // one. Hand-expand chkapr() macro so we can fill in the actual command
+ // string instead of the variable names.
+ if (ll_apr_warn_status(apr_proc_create(&mProcess, argv[0], &argv[0], NULL, procattr,
+ gAPRPoolp)))
+ {
+ throw LLProcessError(STRINGIZE(params << " failed"));
+ }
+
+ // arrange to call status_callback()
+ apr_proc_other_child_register(&mProcess, &LLProcess::status_callback, this, mProcess.in,
+ gAPRPoolp);
+ // and make sure we poll it once per "mainloop" tick
+ sProcessListener.addPoll(*this);
+ mStatus.mState = RUNNING;
+
+ mDesc = STRINGIZE(getDesc(params) << " (" << mProcess.pid << ')');
+ LL_INFOS("LLProcess") << mDesc << ": launched " << params << LL_ENDL;
+
+ // Unless caller explicitly turned off autokill (child should persist),
+ // take steps to terminate the child. This is all suspenders-and-belt: in
+ // theory our destructor should kill an autokill child, but in practice
+ // that doesn't always work (e.g. VWR-21538).
+ if (params.autokill)
+ {
+/*==========================================================================*|
+ // NO: There may be an APR bug, not sure -- but at least on Mac, when
+ // gAPRPoolp is destroyed, OUR process receives SIGTERM! Apparently
+ // either our own PID is getting into the list of processes to kill()
+ // (unlikely), or somehow one of those PIDs is getting zeroed first,
+ // so that kill() sends SIGTERM to the whole process group -- this
+ // process included. I'd have to build and link with a debug version
+ // of APR to know for sure. It's too bad: this mechanism would be just
+ // right for dealing with static autokill LLProcessPtr variables,
+ // which aren't destroyed until after APR is no longer available.
+
+ // Tie the lifespan of this child process to the lifespan of our APR
+ // pool: on destruction of the pool, forcibly kill the process. Tell
+ // APR to try SIGTERM and wait 3 seconds. If that didn't work, use
+ // SIGKILL.
+ apr_pool_note_subprocess(gAPRPoolp, &mProcess, APR_KILL_AFTER_TIMEOUT);
+|*==========================================================================*/
+
+ // On Windows, associate the new child process with our Job Object.
+ autokill();
+ }
+
+ // Instantiate the proper pipe I/O machinery
+ // want to be able to point to apr_proc_t::in, out, err by index
+ typedef apr_file_t* apr_proc_t::*apr_proc_file_ptr;
+ static apr_proc_file_ptr members[] =
+ { &apr_proc_t::in, &apr_proc_t::out, &apr_proc_t::err };
+ for (size_t i = 0; i < NSLOTS; ++i)
+ {
+ if (select[i] != APR_CHILD_BLOCK)
+ continue;
+ std::string desc(STRINGIZE(mDesc << ' ' << whichfile(FILESLOT(i))));
+ apr_file_t* pipe(mProcess.*(members[i]));
+ if (i == STDIN)
+ {
+ mPipes.replace(i, new WritePipeImpl(desc, pipe));
+ }
+ else
+ {
+ mPipes.replace(i, new ReadPipeImpl(desc, pipe, FILESLOT(i)));
+ }
+ LL_DEBUGS("LLProcess") << "Instantiating " << typeid(mPipes[i]).name()
+ << "('" << desc << "')" << LL_ENDL;
+ }
+}
+
+// Helper to obtain a description string, given a Params block
+static std::string getDesc(const LLProcess::Params& params)
+{
+ // If caller specified a description string, by all means use it.
+ if (params.desc.isProvided())
+ return params.desc;
+
+ // Caller didn't say. Use the executable name -- but use just the filename
+ // part. On Mac, for instance, full pathnames get cumbersome.
+ return LLProcess::basename(params.executable);
+}
+
+//static
+std::string LLProcess::basename(const std::string& path)
+{
+ // If there are Linden utility functions to manipulate pathnames, I
+ // haven't found them -- and for this usage, Boost.Filesystem seems kind
+ // of heavyweight.
+ std::string::size_type delim = path.find_last_of("\\/");
+ // If path contains no pathname delimiters, return the whole thing.
+ if (delim == std::string::npos)
+ return path;
+
+ // Return just the part beyond the last delimiter.
+ return path.substr(delim + 1);
+}
+
+LLProcess::~LLProcess()
+{
+ // In the Linden viewer, there's at least one static LLProcessPtr. Its
+ // destructor will be called *after* ll_cleanup_apr(). In such a case,
+ // unregistering is pointless (and fatal!) -- and kill(), which also
+ // relies on APR, is impossible.
+ if (! gAPRPoolp)
+ return;
+
+ // Only in state RUNNING are we registered for callback. In UNSTARTED we
+ // haven't yet registered. And since receiving the callback is the only
+ // way we detect child termination, we only change from state RUNNING at
+ // the same time we unregister.
+ if (mStatus.mState == RUNNING)
+ {
+ // We're still registered for a callback: unregister. Do it before
+ // we even issue the kill(): even if kill() somehow prompted an
+ // instantaneous callback (unlikely), this object is going away! Any
+ // information updated in this object by such a callback is no longer
+ // available to any consumer anyway.
+ apr_proc_other_child_unregister(this);
+ // One less LLProcess to poll for
+ sProcessListener.dropPoll(*this);
+ }
+
+ if (mAutokill)
+ {
+ kill("destructor");
+ }
+}
+
+bool LLProcess::kill(const std::string& who)
+{
+ if (isRunning())
+ {
+ LL_INFOS("LLProcess") << who << " killing " << mDesc << LL_ENDL;
+
+#if LL_WINDOWS
+ int sig = -1;
+#else // Posix
+ int sig = SIGTERM;
+#endif
+
+ ll_apr_warn_status(apr_proc_kill(&mProcess, sig));
+ }
+
+ return ! isRunning();
+}
+
+//static
+bool LLProcess::kill(const LLProcessPtr& p, const std::string& who)
+{
+ if (! p)
+ return true; // process dead! (was never running)
+ return p->kill(who);
+}
+
+bool LLProcess::isRunning() const
+{
+ return getStatus().mState == RUNNING;
+}
+
+//static
+bool LLProcess::isRunning(const LLProcessPtr& p)
+{
+ if (! p)
+ return false;
+ return p->isRunning();
+}
+
+LLProcess::Status LLProcess::getStatus() const
+{
+ return mStatus;
+}
+
+//static
+LLProcess::Status LLProcess::getStatus(const LLProcessPtr& p)
+{
+ if (! p)
+ {
+ // default-constructed Status has mState == UNSTARTED
+ return Status();
+ }
+ return p->getStatus();
+}
+
+std::string LLProcess::getStatusString() const
+{
+ return getStatusString(getStatus());
+}
+
+std::string LLProcess::getStatusString(const Status& status) const
+{
+ return getStatusString(mDesc, status);
+}
+
+//static
+std::string LLProcess::getStatusString(const std::string& desc, const LLProcessPtr& p)
+{
+ if (! p)
+ {
+ // default-constructed Status has mState == UNSTARTED
+ return getStatusString(desc, Status());
+ }
+ return desc + " " + p->getStatusString();
+}
+
+//static
+std::string LLProcess::getStatusString(const std::string& desc, const Status& status)
+{
+ if (status.mState == UNSTARTED)
+ return desc + " was never launched";
+
+ if (status.mState == RUNNING)
+ return desc + " running";
+
+ if (status.mState == EXITED)
+ return STRINGIZE(desc << " exited with code " << status.mData);
+
+ if (status.mState == KILLED)
+#if LL_WINDOWS
+ return STRINGIZE(desc << " killed with exception " << std::hex << status.mData);
+#else
+ return STRINGIZE(desc << " killed by signal " << status.mData
+ << " (" << apr_signal_description_get(status.mData) << ")");
+#endif
+
+ return STRINGIZE(desc << " in unknown state " << status.mState << " (" << status.mData << ")");
+}
+
+// Classic-C-style APR callback
+void LLProcess::status_callback(int reason, void* data, int status)
+{
+ // Our only role is to bounce this static method call back into object
+ // space.
+ static_cast<LLProcess*>(data)->handle_status(reason, status);
+}
+
+#define tabent(symbol) { symbol, #symbol }
+static struct ReasonCode
+{
+ int code;
+ const char* name;
+} reasons[] =
+{
+ tabent(APR_OC_REASON_DEATH),
+ tabent(APR_OC_REASON_UNWRITABLE),
+ tabent(APR_OC_REASON_RESTART),
+ tabent(APR_OC_REASON_UNREGISTER),
+ tabent(APR_OC_REASON_LOST),
+ tabent(APR_OC_REASON_RUNNING)
+};
+#undef tabent
+
+// Object-oriented callback
+void LLProcess::handle_status(int reason, int status)
+{
+ {
+ // This odd appearance of LL_DEBUGS is just to bracket a lookup that will
+ // only be performed if in fact we're going to produce the log message.
+ LL_DEBUGS("LLProcess") << empty;
+ std::string reason_str;
+ BOOST_FOREACH(const ReasonCode& rcp, reasons)
+ {
+ if (reason == rcp.code)
+ {
+ reason_str = rcp.name;
+ break;
+ }
+ }
+ if (reason_str.empty())
+ {
+ reason_str = STRINGIZE("unknown reason " << reason);
+ }
+ LL_CONT << mDesc << ": handle_status(" << reason_str << ", " << status << ")" << LL_ENDL;
+ }
+
+ if (! (reason == APR_OC_REASON_DEATH || reason == APR_OC_REASON_LOST))
+ {
+ // We're only interested in the call when the child terminates.
+ return;
+ }
+
+ // Somewhat oddly, APR requires that you explicitly unregister even when
+ // it already knows the child has terminated. We must pass the same 'data'
+ // pointer as for the register() call, which was our 'this'.
+ apr_proc_other_child_unregister(this);
+ // don't keep polling for a terminated process
+ sProcessListener.dropPoll(*this);
+ // We overload mStatus.mState to indicate whether the child is registered
+ // for APR callback: only RUNNING means registered. Track that we've
+ // unregistered. We know the child has terminated; might be EXITED or
+ // KILLED; refine below.
+ mStatus.mState = EXITED;
+
+ // Make last-gasp calls for each of the ReadPipes we have on hand. Since
+ // they're listening on "mainloop", we can be sure they'll eventually
+ // collect all pending data from the child. But we want to be able to
+ // guarantee to our consumer that by the time we post on the "postend"
+ // LLEventPump, our ReadPipes are already buffering all the data there
+ // will ever be from the child. That lets the "postend" listener decide
+ // what to do with that final data.
+ for (size_t i = 0; i < mPipes.size(); ++i)
+ {
+ std::string error;
+ ReadPipeImpl* ppipe = getPipePtr<ReadPipeImpl>(error, FILESLOT(i));
+ if (ppipe)
+ {
+ static LLSD trivial;
+ ppipe->tick(trivial);
+ }
+ }
+
+// wi->rv = apr_proc_wait(wi->child, &wi->rc, &wi->why, APR_NOWAIT);
+ // It's just wrong to call apr_proc_wait() here. The only way APR knows to
+ // call us with APR_OC_REASON_DEATH is that it's already reaped this child
+ // process, so calling wait() will only produce "huh?" from the OS. We
+ // must rely on the status param passed in, which unfortunately comes
+ // straight from the OS wait() call, which means we have to decode it by
+ // hand.
+ mStatus = interpret_status(status);
+ LL_INFOS("LLProcess") << getStatusString() << LL_ENDL;
+
+ // If caller requested notification on child termination, send it.
+ if (! mPostend.empty())
+ {
+ LLEventPumps::instance().obtain(mPostend)
+ .post(LLSDMap
+ ("id", getProcessID())
+ ("desc", mDesc)
+ ("state", mStatus.mState)
+ ("data", mStatus.mData)
+ ("string", getStatusString())
+ );
+ }
+}
+
+LLProcess::id LLProcess::getProcessID() const
+{
+ return mProcess.pid;
+}
+
+LLProcess::handle LLProcess::getProcessHandle() const
+{
+#if LL_WINDOWS
+ return mProcess.hproc;
+#else
+ return mProcess.pid;
+#endif
+}
+
+std::string LLProcess::getPipeName(FILESLOT) const
+{
+ // LLProcess::FileParam::type "npipe" is not yet implemented
+ return "";
+}
+
+template<class PIPETYPE>
+PIPETYPE* LLProcess::getPipePtr(std::string& error, FILESLOT slot)
+{
+ if (slot >= NSLOTS)
+ {
+ error = STRINGIZE(mDesc << " has no slot " << slot);
+ return NULL;
+ }
+ if (mPipes.is_null(slot))
+ {
+ error = STRINGIZE(mDesc << ' ' << whichfile(slot) << " not a monitored pipe");
+ return NULL;
+ }
+ // Make sure we dynamic_cast in pointer domain so we can test, rather than
+ // accepting runtime's exception.
+ PIPETYPE* ppipe = dynamic_cast<PIPETYPE*>(&mPipes[slot]);
+ if (! ppipe)
+ {
+ error = STRINGIZE(mDesc << ' ' << whichfile(slot) << " not a " << typeid(PIPETYPE).name());
+ return NULL;
+ }
+
+ error.clear();
+ return ppipe;
+}
+
+template <class PIPETYPE>
+PIPETYPE& LLProcess::getPipe(FILESLOT slot)
+{
+ std::string error;
+ PIPETYPE* wp = getPipePtr<PIPETYPE>(error, slot);
+ if (! wp)
+ {
+ throw NoPipe(error);
+ }
+ return *wp;
+}
+
+template <class PIPETYPE>
+boost::optional<PIPETYPE&> LLProcess::getOptPipe(FILESLOT slot)
+{
+ std::string error;
+ PIPETYPE* wp = getPipePtr<PIPETYPE>(error, slot);
+ if (! wp)
+ {
+ LL_DEBUGS("LLProcess") << error << LL_ENDL;
+ return boost::optional<PIPETYPE&>();
+ }
+ return *wp;
+}
+
+LLProcess::WritePipe& LLProcess::getWritePipe(FILESLOT slot)
+{
+ return getPipe<WritePipe>(slot);
+}
+
+boost::optional<LLProcess::WritePipe&> LLProcess::getOptWritePipe(FILESLOT slot)
+{
+ return getOptPipe<WritePipe>(slot);
+}
+
+LLProcess::ReadPipe& LLProcess::getReadPipe(FILESLOT slot)
+{
+ return getPipe<ReadPipe>(slot);
+}
+
+boost::optional<LLProcess::ReadPipe&> LLProcess::getOptReadPipe(FILESLOT slot)
+{
+ return getOptPipe<ReadPipe>(slot);
+}
+
+//static
+std::string LLProcess::getline(std::istream& in)
+{
+ std::string line;
+ std::getline(in, line);
+ // Blur the distinction between "\r\n" and plain "\n". std::getline() will
+ // have eaten the "\n", but we could still end up with a trailing "\r".
+ std::string::size_type lastpos = line.find_last_not_of("\r");
+ if (lastpos != std::string::npos)
+ {
+ // Found at least one character that's not a trailing '\r'. SKIP OVER
+ // IT and erase the rest of the line.
+ line.erase(lastpos+1);
+ }
+ return line;
+}
+
+std::ostream& operator<<(std::ostream& out, const LLProcess::Params& params)
+{
+ if (params.cwd.isProvided())
+ {
+ out << "cd " << LLStringUtil::quote(params.cwd) << ": ";
+ }
+ out << LLStringUtil::quote(params.executable);
+ BOOST_FOREACH(const std::string& arg, params.args)
+ {
+ out << ' ' << LLStringUtil::quote(arg);
+ }
+ return out;
+}
+
+/*****************************************************************************
+* Windows specific
+*****************************************************************************/
+#if LL_WINDOWS
+
+static std::string WindowsErrorString(const std::string& operation);
+
+void LLProcess::autokill()
+{
+ // hopefully now handled by apr_procattr_autokill_set()
+}
+
+LLProcess::handle LLProcess::isRunning(handle h, const std::string& desc)
+{
+ // This direct Windows implementation is because we have no access to the
+ // apr_proc_t struct: we expect it's been destroyed.
+ if (! h)
+ return 0;
+
+ DWORD waitresult = WaitForSingleObject(h, 0);
+ if(waitresult == WAIT_OBJECT_0)
+ {
+ // the process has completed.
+ if (! desc.empty())
+ {
+ DWORD status = 0;
+ if (! GetExitCodeProcess(h, &status))
+ {
+ LL_WARNS("LLProcess") << desc << " terminated, but "
+ << WindowsErrorString("GetExitCodeProcess()") << LL_ENDL;
+ }
+ {
+ LL_INFOS("LLProcess") << getStatusString(desc, interpret_status(status))
+ << LL_ENDL;
+ }
+ }
+ CloseHandle(h);
+ return 0;
+ }
+
+ return h;
+}
+
+static LLProcess::Status interpret_status(int status)
+{
+ LLProcess::Status result;
+
+ // This bit of code is cribbed from apr/threadproc/win32/proc.c, a
+ // function (unfortunately static) called why_from_exit_code():
+ /* See WinNT.h STATUS_ACCESS_VIOLATION and family for how
+ * this class of failures was determined
+ */
+ if ((status & 0xFFFF0000) == 0xC0000000)
+ {
+ result.mState = LLProcess::KILLED;
+ }
+ else
+ {
+ result.mState = LLProcess::EXITED;
+ }
+ result.mData = status;
+
+ return result;
+}
+
+/// GetLastError()/FormatMessage() boilerplate
+static std::string WindowsErrorString(const std::string& operation)
+{
+ int result = GetLastError();
+
+ LPTSTR error_str = 0;
+ if (FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL,
+ result,
+ 0,
+ (LPTSTR)&error_str,
+ 0,
+ NULL)
+ != 0)
+ {
+ // convert from wide-char string to multi-byte string
+ char message[256];
+ wcstombs(message, error_str, sizeof(message));
+ message[sizeof(message)-1] = 0;
+ LocalFree(error_str);
+ // convert to std::string to trim trailing whitespace
+ std::string mbsstr(message);
+ mbsstr.erase(mbsstr.find_last_not_of(" \t\r\n"));
+ return STRINGIZE(operation << " failed (" << result << "): " << mbsstr);
+ }
+ return STRINGIZE(operation << " failed (" << result
+ << "), but FormatMessage() did not explain");
+}
+
+/*****************************************************************************
+* Posix specific
+*****************************************************************************/
+#else // Mac and linux
+
+#include <signal.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/wait.h>
+
+void LLProcess::autokill()
+{
+ // What we ought to do here is to:
+ // 1. create a unique process group and run all autokill children in that
+ // group (see https://jira.secondlife.com/browse/SWAT-563);
+ // 2. figure out a way to intercept control when the viewer exits --
+ // gracefully or not;
+ // 3. when the viewer exits, kill off the aforementioned process group.
+
+ // It's point 2 that's troublesome. Although I've seen some signal-
+ // handling logic in the Posix viewer code, I haven't yet found any bit of
+ // code that's run no matter how the viewer exits (a try/finally for the
+ // whole process, as it were).
+}
+
+// Attempt to reap a process ID -- returns true if the process has exited and been reaped, false otherwise.
+static bool reap_pid(pid_t pid, LLProcess::Status* pstatus=NULL)
+{
+ LLProcess::Status dummy;
+ if (! pstatus)
+ {
+ // If caller doesn't want to see Status, give us a target anyway so we
+ // don't have to have a bunch of conditionals.
+ pstatus = &dummy;
+ }
+
+ int status = 0;
+ pid_t wait_result = ::waitpid(pid, &status, WNOHANG);
+ if (wait_result == pid)
+ {
+ *pstatus = interpret_status(status);
+ return true;
+ }
+ if (wait_result == 0)
+ {
+ pstatus->mState = LLProcess::RUNNING;
+ pstatus->mData = 0;
+ return false;
+ }
+
+ // Clear caller's Status block; caller must interpret UNSTARTED to mean
+ // "if this PID was ever valid, it no longer is."
+ *pstatus = LLProcess::Status();
+
+ // We've dealt with the success cases: we were able to reap the child
+ // (wait_result == pid) or it's still running (wait_result == 0). It may
+ // be that the child terminated but didn't hang around long enough for us
+ // to reap. In that case we still have no Status to report, but we can at
+ // least state that it's not running.
+ if (wait_result == -1 && errno == ECHILD)
+ {
+ // No such process -- this may mean we're ignoring SIGCHILD.
+ return true;
+ }
+
+ // Uh, should never happen?!
+ LL_WARNS("LLProcess") << "LLProcess::reap_pid(): waitpid(" << pid << ") returned "
+ << wait_result << "; not meaningful?" << LL_ENDL;
+ // If caller is looping until this pid terminates, and if we can't find
+ // out, better to break the loop than to claim it's still running.
+ return true;
+}
+
+LLProcess::id LLProcess::isRunning(id pid, const std::string& desc)
+{
+ // This direct Posix implementation is because we have no access to the
+ // apr_proc_t struct: we expect it's been destroyed.
+ if (! pid)
+ return 0;
+
+ // Check whether the process has exited, and reap it if it has.
+ LLProcess::Status status;
+ if(reap_pid(pid, &status))
+ {
+ // the process has exited.
+ if (! desc.empty())
+ {
+ std::string statstr(desc + " apparently terminated: no status available");
+ // We don't just pass UNSTARTED to getStatusString() because, in
+ // the context of reap_pid(), that state has special meaning.
+ if (status.mState != UNSTARTED)
+ {
+ statstr = getStatusString(desc, status);
+ }
+ LL_INFOS("LLProcess") << statstr << LL_ENDL;
+ }
+ return 0;
+ }
+
+ return pid;
+}
+
+static LLProcess::Status interpret_status(int status)
+{
+ LLProcess::Status result;
+
+ if (WIFEXITED(status))
+ {
+ result.mState = LLProcess::EXITED;
+ result.mData = WEXITSTATUS(status);
+ }
+ else if (WIFSIGNALED(status))
+ {
+ result.mState = LLProcess::KILLED;
+ result.mData = WTERMSIG(status);
+ }
+ else // uh, shouldn't happen?
+ {
+ result.mState = LLProcess::EXITED;
+ result.mData = status; // someone else will have to decode
+ }
+
+ return result;
+}
+
+#endif // Posix
diff --git a/indra/llcommon/llprocess.h b/indra/llcommon/llprocess.h
new file mode 100755
index 0000000000..d711ce2f74
--- /dev/null
+++ b/indra/llcommon/llprocess.h
@@ -0,0 +1,553 @@
+/**
+ * @file llprocess.h
+ * @brief Utility class for launching, terminating, and tracking child processes.
+ *
+ * $LicenseInfo:firstyear=2008&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$
+ */
+
+#ifndef LL_LLPROCESS_H
+#define LL_LLPROCESS_H
+
+#include "llinitparam.h"
+#include "llsdparam.h"
+#include "apr_thread_proc.h"
+#include <boost/shared_ptr.hpp>
+#include <boost/ptr_container/ptr_vector.hpp>
+#include <boost/optional.hpp>
+#include <boost/noncopyable.hpp>
+#include <iosfwd> // std::ostream
+#include <stdexcept>
+
+#if LL_WINDOWS
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h> // HANDLE (eye roll)
+#elif LL_LINUX
+#if defined(Status)
+#undef Status
+#endif
+#endif
+
+class LLEventPump;
+
+class LLProcess;
+/// LLProcess instances are created on the heap by static factory methods and
+/// managed by ref-counted pointers.
+typedef boost::shared_ptr<LLProcess> LLProcessPtr;
+
+/**
+ * LLProcess handles launching an external process with specified command line
+ * arguments. It also keeps track of whether the process is still running, and
+ * can kill it if required.
+ *
+ * In discussing LLProcess, we use the term "parent" to refer to this process
+ * (the process invoking LLProcess), versus "child" to refer to the process
+ * spawned by LLProcess.
+ *
+ * LLProcess relies on periodic post() calls on the "mainloop" LLEventPump: an
+ * LLProcess object's Status won't update until the next "mainloop" tick. For
+ * instance, the Second Life viewer's main loop already posts to an
+ * LLEventPump by that name once per iteration. See
+ * indra/llcommon/tests/llprocess_test.cpp for an example of waiting for
+ * child-process termination in a standalone test context.
+ */
+class LL_COMMON_API LLProcess: public boost::noncopyable
+{
+ LOG_CLASS(LLProcess);
+public:
+ /**
+ * Specify what to pass for each of child stdin, stdout, stderr.
+ * @see LLProcess::Params::files.
+ */
+ struct FileParam: public LLInitParam::Block<FileParam>
+ {
+ /**
+ * type of file handle to pass to child process
+ *
+ * - "" (default): let the child inherit the same file handle used by
+ * this process. For instance, if passed as stdout, child stdout
+ * will be interleaved with stdout from this process. In this case,
+ * @a name is moot and should be left "".
+ *
+ * - "file": open an OS filesystem file with the specified @a name.
+ * <i>Not yet implemented.</i>
+ *
+ * - "pipe" or "tpipe" or "npipe": depends on @a name
+ *
+ * - @a name.empty(): construct an OS pipe used only for this slot
+ * of the forthcoming child process.
+ *
+ * - ! @a name.empty(): in a global registry, find or create (using
+ * the specified @a name) an OS pipe. The point of the (purely
+ * internal) @a name is that passing the same @a name in more than
+ * one slot for a given LLProcess -- or for slots in different
+ * LLProcess instances -- means the same pipe. For example, you
+ * might pass the same @a name value as both stdout and stderr to
+ * make the child process produce both on the same actual pipe. Or
+ * you might pass the same @a name as the stdout for one LLProcess
+ * and the stdin for another to connect the two child processes.
+ * Use LLProcess::getPipeName() to generate a unique name
+ * guaranteed not to already exist in the registry. <i>Not yet
+ * implemented.</i>
+ *
+ * The difference between "pipe", "tpipe" and "npipe" is as follows.
+ *
+ * - "pipe": direct LLProcess to monitor the parent end of the pipe,
+ * pumping nonblocking I/O every frame. The expectation (at least
+ * for stdout or stderr) is that the caller will listen for
+ * incoming data and consume it as it arrives. It's important not
+ * to neglect such a pipe, because it's buffered in memory. If you
+ * suspect the child may produce a great volume of output between
+ * frames, consider directing the child to write to a filesystem
+ * file instead, then read the file later.
+ *
+ * - "tpipe": do not engage LLProcess machinery to monitor the
+ * parent end of the pipe. A "tpipe" is used only to connect
+ * different child processes. As such, it makes little sense to
+ * pass an empty @a name. <i>Not yet implemented.</i>
+ *
+ * - "npipe": like "tpipe", but use an OS named pipe with a
+ * generated name. Note that @a name is the @em internal name of
+ * the pipe in our global registry -- it doesn't necessarily have
+ * anything to do with the pipe's name in the OS filesystem. Use
+ * LLProcess::getPipeName() to obtain the named pipe's OS
+ * filesystem name, e.g. to pass it as the @a name to another
+ * LLProcess instance using @a type "file". This supports usage
+ * like bash's &lt;(subcommand...) or &gt;(subcommand...)
+ * constructs. <i>Not yet implemented.</i>
+ *
+ * In all cases the open mode (read, write) is determined by the child
+ * slot you're filling. Child stdin means select the "read" end of a
+ * pipe, or open a filesystem file for reading; child stdout or stderr
+ * means select the "write" end of a pipe, or open a filesystem file
+ * for writing.
+ *
+ * Confusion such as passing the same pipe as the stdin of two
+ * processes (rather than stdout for one and stdin for the other) is
+ * explicitly permitted: it's up to the caller to construct meaningful
+ * LLProcess pipe graphs.
+ */
+ Optional<std::string> type;
+ Optional<std::string> name;
+
+ FileParam(const std::string& tp="", const std::string& nm=""):
+ type("type"),
+ name("name")
+ {
+ // If caller wants to specify values, use explicit assignment to
+ // set them rather than initialization.
+ if (! tp.empty()) type = tp;
+ if (! nm.empty()) name = nm;
+ }
+ };
+
+ /// Param block definition
+ struct Params: public LLInitParam::Block<Params>
+ {
+ Params():
+ executable("executable"),
+ args("args"),
+ cwd("cwd"),
+ autokill("autokill", true),
+ files("files"),
+ postend("postend"),
+ desc("desc")
+ {}
+
+ /// pathname of executable
+ Mandatory<std::string> executable;
+ /**
+ * zero or more additional command-line arguments. Arguments are
+ * passed through as exactly as we can manage, whitespace and all.
+ * @note On Windows we manage this by implicitly double-quoting each
+ * argument while assembling the command line.
+ */
+ Multiple<std::string> args;
+ /// current working directory, if need it changed
+ Optional<std::string> cwd;
+ /// implicitly kill process on destruction of LLProcess object
+ /// (default true)
+ Optional<bool> autokill;
+ /**
+ * Up to three FileParam items: for child stdin, stdout, stderr.
+ * Passing two FileParam entries means default treatment for stderr,
+ * and so forth.
+ *
+ * @note LLInitParam::Block permits usage like this:
+ * @code
+ * LLProcess::Params params;
+ * ...
+ * params.files
+ * .add(LLProcess::FileParam()) // stdin
+ * .add(LLProcess::FileParam().type("pipe") // stdout
+ * .add(LLProcess::FileParam().type("file").name("error.log"));
+ * @endcode
+ *
+ * @note While it's theoretically plausible to pass additional open
+ * file handles to a child specifically written to expect them, our
+ * underlying implementation doesn't yet support that.
+ */
+ Multiple<FileParam, AtMost<3> > files;
+ /**
+ * On child-process termination, if this LLProcess object still
+ * exists, post LLSD event to LLEventPump with specified name (default
+ * no event). Event contains at least:
+ *
+ * - "id" as obtained from getProcessID()
+ * - "desc" short string description of child (executable + pid)
+ * - "state" @c state enum value, from Status.mState
+ * - "data" if "state" is EXITED, exit code; if KILLED, on Posix,
+ * signal number
+ * - "string" English text describing "state" and "data" (e.g. "exited
+ * with code 0")
+ */
+ Optional<std::string> postend;
+ /**
+ * Description of child process for logging purposes. It need not be
+ * unique; the logged description string will contain the PID as well.
+ * If this is omitted, a description will be derived from the
+ * executable name.
+ */
+ Optional<std::string> desc;
+ };
+ typedef LLSDParamAdapter<Params> LLSDOrParams;
+
+ /**
+ * Factory accepting either plain LLSD::Map or Params block.
+ * MAY RETURN DEFAULT-CONSTRUCTED LLProcessPtr if params invalid!
+ */
+ static LLProcessPtr create(const LLSDOrParams& params);
+ virtual ~LLProcess();
+
+ /// Is child process still running?
+ bool isRunning() const;
+ // static isRunning(LLProcessPtr), getStatus(LLProcessPtr),
+ // getStatusString(LLProcessPtr), kill(LLProcessPtr) handle the case in
+ // which the passed LLProcessPtr might be NULL (default-constructed).
+ static bool isRunning(const LLProcessPtr&);
+
+ /**
+ * State of child process
+ */
+ enum state
+ {
+ UNSTARTED, ///< initial value, invisible to consumer
+ RUNNING, ///< child process launched
+ EXITED, ///< child process terminated voluntarily
+ KILLED ///< child process terminated involuntarily
+ };
+
+ /**
+ * Status info
+ */
+ struct Status
+ {
+ Status():
+ mState(UNSTARTED),
+ mData(0)
+ {}
+
+ state mState; ///< @see state
+ /**
+ * - for mState == EXITED: mData is exit() code
+ * - for mState == KILLED: mData is signal number (Posix)
+ * - otherwise: mData is undefined
+ */
+ int mData;
+ };
+
+ /// Status query
+ Status getStatus() const;
+ static Status getStatus(const LLProcessPtr&);
+ /// English Status string query, for logging etc.
+ std::string getStatusString() const;
+ static std::string getStatusString(const std::string& desc, const LLProcessPtr&);
+ /// English Status string query for previously-captured Status
+ std::string getStatusString(const Status& status) const;
+ /// static English Status string query
+ static std::string getStatusString(const std::string& desc, const Status& status);
+
+ // Attempt to kill the process -- returns true if the process is no longer running when it returns.
+ // Note that even if this returns false, the process may exit some time after it's called.
+ bool kill(const std::string& who="");
+ static bool kill(const LLProcessPtr& p, const std::string& who="");
+
+#if LL_WINDOWS
+ typedef int id; ///< as returned by getProcessID()
+ typedef HANDLE handle; ///< as returned by getProcessHandle()
+#else
+ typedef pid_t id;
+ typedef pid_t handle;
+#endif
+ /**
+ * Get an int-like id value. This is primarily intended for a human reader
+ * to differentiate processes.
+ */
+ id getProcessID() const;
+ /**
+ * Get a "handle" of a kind that you might pass to platform-specific API
+ * functions to engage features not directly supported by LLProcess.
+ */
+ handle getProcessHandle() const;
+
+ /**
+ * Test if a process (@c handle obtained from getProcessHandle()) is still
+ * running. Return same nonzero @c handle value if still running, else
+ * zero, so you can test it like a bool. But if you want to update a
+ * stored variable as a side effect, you can write code like this:
+ * @code
+ * hchild = LLProcess::isRunning(hchild);
+ * @endcode
+ * @note This method is intended as a unit-test hook, not as the first of
+ * a whole set of operations supported on freestanding @c handle values.
+ * New functionality should be added as nonstatic members operating on
+ * the same data as getProcessHandle().
+ *
+ * In particular, if child termination is detected by this static isRunning()
+ * rather than by nonstatic isRunning(), the LLProcess object won't be
+ * aware of the child's changed status and may encounter OS errors trying
+ * to obtain it. This static isRunning() is only intended for after the
+ * launching LLProcess object has been destroyed.
+ */
+ static handle isRunning(handle, const std::string& desc="");
+
+ /// Provide symbolic access to child's file slots
+ enum FILESLOT { STDIN=0, STDOUT=1, STDERR=2, NSLOTS=3 };
+
+ /**
+ * For a pipe constructed with @a type "npipe", obtain the generated OS
+ * filesystem name for the specified pipe. Otherwise returns the empty
+ * string. @see LLProcess::FileParam::type
+ */
+ std::string getPipeName(FILESLOT) const;
+
+ /// base of ReadPipe, WritePipe
+ class LL_COMMON_API BasePipe
+ {
+ public:
+ virtual ~BasePipe() = 0;
+
+ typedef std::size_t size_type;
+ static const size_type npos;
+
+ /**
+ * Get accumulated buffer length.
+ *
+ * For WritePipe, is there still pending data to send to child?
+ *
+ * For ReadPipe, we often need to refrain from actually reading the
+ * std::istream returned by get_istream() until we've accumulated
+ * enough data to make it worthwhile. For instance, if we're expecting
+ * a number from the child, but the child happens to flush "12" before
+ * emitting "3\n", get_istream() >> myint could return 12 rather than
+ * 123!
+ */
+ virtual size_type size() const = 0;
+ };
+
+ /// As returned by getWritePipe() or getOptWritePipe()
+ class WritePipe: public BasePipe
+ {
+ public:
+ /**
+ * Get ostream& on which to write to child's stdin.
+ *
+ * @usage
+ * @code
+ * myProcess->getWritePipe().get_ostream() << "Hello, child!" << std::endl;
+ * @endcode
+ */
+ virtual std::ostream& get_ostream() = 0;
+ };
+
+ /// As returned by getReadPipe() or getOptReadPipe()
+ class ReadPipe: public BasePipe
+ {
+ public:
+ /**
+ * Get istream& on which to read from child's stdout or stderr.
+ *
+ * @usage
+ * @code
+ * std::string stuff;
+ * myProcess->getReadPipe().get_istream() >> stuff;
+ * @endcode
+ *
+ * You should be sure in advance that the ReadPipe in question can
+ * fill the request. @see getPump()
+ */
+ virtual std::istream& get_istream() = 0;
+
+ /**
+ * Like std::getline(get_istream(), line), but trims off trailing '\r'
+ * to make calling code less platform-sensitive.
+ */
+ virtual std::string getline() = 0;
+
+ /**
+ * Like get_istream().read(buffer, n), but returns std::string rather
+ * than requiring caller to construct a buffer, etc.
+ */
+ virtual std::string read(size_type len) = 0;
+
+ /**
+ * Peek at accumulated buffer data without consuming it. Optional
+ * parameters give you substr() functionality.
+ *
+ * @note You can discard buffer data using get_istream().ignore(n).
+ */
+ virtual std::string peek(size_type offset=0, size_type len=npos) const = 0;
+
+ /**
+ * Detect presence of a substring (or char) in accumulated buffer data
+ * without retrieving it. Optional offset allows you to search from
+ * specified position.
+ */
+ template <typename SEEK>
+ bool contains(SEEK seek, size_type offset=0) const
+ { return find(seek, offset) != npos; }
+
+ /**
+ * Search for a substring in accumulated buffer data without
+ * retrieving it. Returns size_type position at which found, or npos
+ * meaning not found. Optional offset allows you to search from
+ * specified position.
+ */
+ virtual size_type find(const std::string& seek, size_type offset=0) const = 0;
+
+ /**
+ * Search for a char in accumulated buffer data without retrieving it.
+ * Returns size_type position at which found, or npos meaning not
+ * found. Optional offset allows you to search from specified
+ * position.
+ */
+ virtual size_type find(char seek, size_type offset=0) const = 0;
+
+ /**
+ * Get LLEventPump& on which to listen for incoming data. The posted
+ * LLSD::Map event will contain:
+ *
+ * - "data" part of pending data; see setLimit()
+ * - "len" entire length of pending data, regardless of setLimit()
+ * - "slot" this ReadPipe's FILESLOT, e.g. LLProcess::STDOUT
+ * - "name" e.g. "stdout"
+ * - "desc" e.g. "SLPlugin (pid) stdout"
+ * - "eof" @c true means there no more data will arrive on this pipe,
+ * therefore no more events on this pump
+ *
+ * If the child sends "abc", and this ReadPipe posts "data"="abc", but
+ * you don't consume it by reading the std::istream returned by
+ * get_istream(), and the child next sends "def", ReadPipe will post
+ * "data"="abcdef".
+ */
+ virtual LLEventPump& getPump() = 0;
+
+ /**
+ * Set maximum length of buffer data that will be posted in the LLSD
+ * announcing arrival of new data from the child. If you call
+ * setLimit(5), and the child sends "abcdef", the LLSD event will
+ * contain "data"="abcde". However, you may still read the entire
+ * "abcdef" from get_istream(): this limit affects only the size of
+ * the data posted with the LLSD event. If you don't call this method,
+ * @em no data will be posted: the default is 0 bytes.
+ */
+ virtual void setLimit(size_type limit) = 0;
+
+ /**
+ * Query the current setLimit() limit.
+ */
+ virtual size_type getLimit() const = 0;
+ };
+
+ /// Exception thrown by getWritePipe(), getReadPipe() if you didn't ask to
+ /// create a pipe at the corresponding FILESLOT.
+ struct NoPipe: public std::runtime_error
+ {
+ NoPipe(const std::string& what): std::runtime_error(what) {}
+ };
+
+ /**
+ * Get a reference to the (only) WritePipe for this LLProcess. @a slot, if
+ * specified, must be STDIN. Throws NoPipe if you did not request a "pipe"
+ * for child stdin. Use this method when you know how you created the
+ * LLProcess in hand.
+ */
+ WritePipe& getWritePipe(FILESLOT slot=STDIN);
+
+ /**
+ * Get a boost::optional<WritePipe&> to the (only) WritePipe for this
+ * LLProcess. @a slot, if specified, must be STDIN. The return value is
+ * empty if you did not request a "pipe" for child stdin. Use this method
+ * for inspecting an LLProcess you did not create.
+ */
+ boost::optional<WritePipe&> getOptWritePipe(FILESLOT slot=STDIN);
+
+ /**
+ * Get a reference to one of the ReadPipes for this LLProcess. @a slot, if
+ * specified, must be STDOUT or STDERR. Throws NoPipe if you did not
+ * request a "pipe" for child stdout or stderr. Use this method when you
+ * know how you created the LLProcess in hand.
+ */
+ ReadPipe& getReadPipe(FILESLOT slot);
+
+ /**
+ * Get a boost::optional<ReadPipe&> to one of the ReadPipes for this
+ * LLProcess. @a slot, if specified, must be STDOUT or STDERR. The return
+ * value is empty if you did not request a "pipe" for child stdout or
+ * stderr. Use this method for inspecting an LLProcess you did not create.
+ */
+ boost::optional<ReadPipe&> getOptReadPipe(FILESLOT slot);
+
+ /// little utilities that really should already be somewhere else in the
+ /// code base
+ static std::string basename(const std::string& path);
+ static std::string getline(std::istream&);
+
+private:
+ /// constructor is private: use create() instead
+ LLProcess(const LLSDOrParams& params);
+ void autokill();
+ // Classic-C-style APR callback
+ static void status_callback(int reason, void* data, int status);
+ // Object-oriented callback
+ void handle_status(int reason, int status);
+ // implementation for get[Opt][Read|Write]Pipe()
+ template <class PIPETYPE>
+ PIPETYPE& getPipe(FILESLOT slot);
+ template <class PIPETYPE>
+ boost::optional<PIPETYPE&> getOptPipe(FILESLOT slot);
+ template <class PIPETYPE>
+ PIPETYPE* getPipePtr(std::string& error, FILESLOT slot);
+
+ std::string mDesc;
+ std::string mPostend;
+ apr_proc_t mProcess;
+ bool mAutokill;
+ Status mStatus;
+ // explicitly want this ptr_vector to be able to store NULLs
+ typedef boost::ptr_vector< boost::nullable<BasePipe> > PipeVector;
+ PipeVector mPipes;
+};
+
+/// for logging
+LL_COMMON_API std::ostream& operator<<(std::ostream&, const LLProcess::Params&);
+
+#endif // LL_LLPROCESS_H
diff --git a/indra/llcommon/llprocesslauncher.cpp b/indra/llcommon/llprocesslauncher.cpp
deleted file mode 100644
index 10950181fd..0000000000
--- a/indra/llcommon/llprocesslauncher.cpp
+++ /dev/null
@@ -1,357 +0,0 @@
-/**
- * @file llprocesslauncher.cpp
- * @brief Utility class for launching, terminating, and tracking the state of processes.
- *
- * $LicenseInfo:firstyear=2008&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 "llprocesslauncher.h"
-
-#include <iostream>
-#if LL_DARWIN || LL_LINUX
-// not required or present on Win32
-#include <sys/wait.h>
-#endif
-
-LLProcessLauncher::LLProcessLauncher()
-{
-#if LL_WINDOWS
- mProcessHandle = 0;
-#else
- mProcessID = 0;
-#endif
-}
-
-LLProcessLauncher::~LLProcessLauncher()
-{
- kill();
-}
-
-void LLProcessLauncher::setExecutable(const std::string &executable)
-{
- mExecutable = executable;
-}
-
-void LLProcessLauncher::setWorkingDirectory(const std::string &dir)
-{
- mWorkingDir = dir;
-}
-
-const std::string& LLProcessLauncher::getExecutable() const
-{
- return mExecutable;
-}
-
-void LLProcessLauncher::clearArguments()
-{
- mLaunchArguments.clear();
-}
-
-void LLProcessLauncher::addArgument(const std::string &arg)
-{
- mLaunchArguments.push_back(arg);
-}
-
-void LLProcessLauncher::addArgument(const char *arg)
-{
- mLaunchArguments.push_back(std::string(arg));
-}
-
-#if LL_WINDOWS
-
-int LLProcessLauncher::launch(void)
-{
- // If there was already a process associated with this object, kill it.
- kill();
- orphan();
-
- int result = 0;
-
- PROCESS_INFORMATION pinfo;
- STARTUPINFOA sinfo;
- memset(&sinfo, 0, sizeof(sinfo));
-
- std::string args = mExecutable;
- for(int i = 0; i < (int)mLaunchArguments.size(); i++)
- {
- args += " ";
- args += mLaunchArguments[i];
- }
-
- // So retarded. Windows requires that the second parameter to CreateProcessA be a writable (non-const) string...
- char *args2 = new char[args.size() + 1];
- strcpy(args2, args.c_str());
-
- const char * working_directory = 0;
- if(!mWorkingDir.empty()) working_directory = mWorkingDir.c_str();
- if( ! CreateProcessA( NULL, args2, NULL, NULL, FALSE, 0, NULL, working_directory, &sinfo, &pinfo ) )
- {
- result = GetLastError();
-
- LPTSTR error_str = 0;
- if(
- FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
- NULL,
- result,
- 0,
- (LPTSTR)&error_str,
- 0,
- NULL)
- != 0)
- {
- char message[256];
- wcstombs(message, error_str, 256);
- message[255] = 0;
- llwarns << "CreateProcessA failed: " << message << llendl;
- LocalFree(error_str);
- }
-
- if(result == 0)
- {
- // Make absolutely certain we return a non-zero value on failure.
- result = -1;
- }
- }
- else
- {
- // foo = pinfo.dwProcessId; // get your pid here if you want to use it later on
- // CloseHandle(pinfo.hProcess); // stops leaks - nothing else
- mProcessHandle = pinfo.hProcess;
- CloseHandle(pinfo.hThread); // stops leaks - nothing else
- }
-
- delete[] args2;
-
- return result;
-}
-
-bool LLProcessLauncher::isRunning(void)
-{
- if(mProcessHandle != 0)
- {
- DWORD waitresult = WaitForSingleObject(mProcessHandle, 0);
- if(waitresult == WAIT_OBJECT_0)
- {
- // the process has completed.
- mProcessHandle = 0;
- }
- }
-
- return (mProcessHandle != 0);
-}
-bool LLProcessLauncher::kill(void)
-{
- bool result = true;
-
- if(mProcessHandle != 0)
- {
- TerminateProcess(mProcessHandle,0);
-
- if(isRunning())
- {
- result = false;
- }
- }
-
- return result;
-}
-
-void LLProcessLauncher::orphan(void)
-{
- // Forget about the process
- mProcessHandle = 0;
-}
-
-// static
-void LLProcessLauncher::reap(void)
-{
- // No actions necessary on Windows.
-}
-
-#else // Mac and linux
-
-#include <signal.h>
-#include <fcntl.h>
-#include <errno.h>
-
-static std::list<pid_t> sZombies;
-
-// Attempt to reap a process ID -- returns true if the process has exited and been reaped, false otherwise.
-static bool reap_pid(pid_t pid)
-{
- bool result = false;
-
- pid_t wait_result = ::waitpid(pid, NULL, WNOHANG);
- if(wait_result == pid)
- {
- result = true;
- }
- else if(wait_result == -1)
- {
- if(errno == ECHILD)
- {
- // No such process -- this may mean we're ignoring SIGCHILD.
- result = true;
- }
- }
-
- return result;
-}
-
-int LLProcessLauncher::launch(void)
-{
- // If there was already a process associated with this object, kill it.
- kill();
- orphan();
-
- int result = 0;
- int current_wd = -1;
-
- // create an argv vector for the child process
- const char ** fake_argv = new const char *[mLaunchArguments.size() + 2]; // 1 for the executable path, 1 for the NULL terminator
-
- int i = 0;
-
- // add the executable path
- fake_argv[i++] = mExecutable.c_str();
-
- // and any arguments
- for(int j=0; j < mLaunchArguments.size(); j++)
- fake_argv[i++] = mLaunchArguments[j].c_str();
-
- // terminate with a null pointer
- fake_argv[i] = NULL;
-
- if(!mWorkingDir.empty())
- {
- // save the current working directory
- current_wd = ::open(".", O_RDONLY);
-
- // and change to the one the child will be executed in
- if (::chdir(mWorkingDir.c_str()))
- {
- // chdir failed
- }
- }
-
- // flush all buffers before the child inherits them
- ::fflush(NULL);
-
- pid_t id = vfork();
- if(id == 0)
- {
- // child process
-
- ::execv(mExecutable.c_str(), (char * const *)fake_argv);
-
- // If we reach this point, the exec failed.
- // Use _exit() instead of exit() per the vfork man page.
- _exit(0);
- }
-
- // parent process
-
- if(current_wd >= 0)
- {
- // restore the previous working directory
- if (::fchdir(current_wd))
- {
- // chdir failed
- }
- ::close(current_wd);
- }
-
- delete[] fake_argv;
-
- mProcessID = id;
-
- return result;
-}
-
-bool LLProcessLauncher::isRunning(void)
-{
- if(mProcessID != 0)
- {
- // Check whether the process has exited, and reap it if it has.
- if(reap_pid(mProcessID))
- {
- // the process has exited.
- mProcessID = 0;
- }
- }
-
- return (mProcessID != 0);
-}
-
-bool LLProcessLauncher::kill(void)
-{
- bool result = true;
-
- if(mProcessID != 0)
- {
- // Try to kill the process. We'll do approximately the same thing whether the kill returns an error or not, so we ignore the result.
- (void)::kill(mProcessID, SIGTERM);
-
- // This will have the side-effect of reaping the zombie if the process has exited.
- if(isRunning())
- {
- result = false;
- }
- }
-
- return result;
-}
-
-void LLProcessLauncher::orphan(void)
-{
- // Disassociate the process from this object
- if(mProcessID != 0)
- {
- // We may still need to reap the process's zombie eventually
- sZombies.push_back(mProcessID);
-
- mProcessID = 0;
- }
-}
-
-// static
-void LLProcessLauncher::reap(void)
-{
- // Attempt to real all saved process ID's.
-
- std::list<pid_t>::iterator iter = sZombies.begin();
- while(iter != sZombies.end())
- {
- if(reap_pid(*iter))
- {
- iter = sZombies.erase(iter);
- }
- else
- {
- iter++;
- }
- }
-}
-
-#endif
diff --git a/indra/llcommon/llprocesslauncher.h b/indra/llcommon/llprocesslauncher.h
deleted file mode 100644
index 954c249147..0000000000
--- a/indra/llcommon/llprocesslauncher.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/**
- * @file llprocesslauncher.h
- * @brief Utility class for launching, terminating, and tracking the state of processes.
- *
- * $LicenseInfo:firstyear=2008&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$
- */
-
-#ifndef LL_LLPROCESSLAUNCHER_H
-#define LL_LLPROCESSLAUNCHER_H
-
-#if LL_WINDOWS
-#include <windows.h>
-#endif
-
-
-/*
- LLProcessLauncher handles launching external processes with specified command line arguments.
- It also keeps track of whether the process is still running, and can kill it if required.
-*/
-
-class LL_COMMON_API LLProcessLauncher
-{
- LOG_CLASS(LLProcessLauncher);
-public:
- LLProcessLauncher();
- virtual ~LLProcessLauncher();
-
- void setExecutable(const std::string &executable);
- void setWorkingDirectory(const std::string &dir);
-
- const std::string& getExecutable() const;
-
- void clearArguments();
- void addArgument(const std::string &arg);
- void addArgument(const char *arg);
-
- int launch(void);
- bool isRunning(void);
-
- // Attempt to kill the process -- returns true if the process is no longer running when it returns.
- // Note that even if this returns false, the process may exit some time after it's called.
- bool kill(void);
-
- // Use this if you want the external process to continue execution after the LLProcessLauncher instance controlling it is deleted.
- // Normally, the destructor will attempt to kill the process and wait for termination.
- // This should only be used if the viewer is about to exit -- otherwise, the child process will become a zombie after it exits.
- void orphan(void);
-
- // This needs to be called periodically on Mac/Linux to clean up zombie processes.
- static void reap(void);
-
- // Accessors for platform-specific process ID
-#if LL_WINDOWS
- HANDLE getProcessHandle() { return mProcessHandle; };
-#else
- pid_t getProcessID() { return mProcessID; };
-#endif
-
-private:
- std::string mExecutable;
- std::string mWorkingDir;
- std::vector<std::string> mLaunchArguments;
-
-#if LL_WINDOWS
- HANDLE mProcessHandle;
-#else
- pid_t mProcessID;
-#endif
-};
-
-#endif // LL_LLPROCESSLAUNCHER_H
diff --git a/indra/llcommon/llprocessor.cpp b/indra/llcommon/llprocessor.cpp
index fd8f603d21..fd8f603d21 100644..100755
--- a/indra/llcommon/llprocessor.cpp
+++ b/indra/llcommon/llprocessor.cpp
diff --git a/indra/llcommon/llprocessor.h b/indra/llcommon/llprocessor.h
index 6364d3c8bb..6364d3c8bb 100644..100755
--- a/indra/llcommon/llprocessor.h
+++ b/indra/llcommon/llprocessor.h
diff --git a/indra/llcommon/llptrskiplist.h b/indra/llcommon/llptrskiplist.h
index 67c7cde352..67c7cde352 100644..100755
--- a/indra/llcommon/llptrskiplist.h
+++ b/indra/llcommon/llptrskiplist.h
diff --git a/indra/llcommon/llptrskipmap.h b/indra/llcommon/llptrskipmap.h
index 94bc71ec55..94bc71ec55 100644..100755
--- a/indra/llcommon/llptrskipmap.h
+++ b/indra/llcommon/llptrskipmap.h
diff --git a/indra/llcommon/llptrto.cpp b/indra/llcommon/llptrto.cpp
index b270291bd6..b270291bd6 100644..100755
--- a/indra/llcommon/llptrto.cpp
+++ b/indra/llcommon/llptrto.cpp
diff --git a/indra/llcommon/llptrto.h b/indra/llcommon/llptrto.h
index 7091d36f6b..7091d36f6b 100644..100755
--- a/indra/llcommon/llptrto.h
+++ b/indra/llcommon/llptrto.h
diff --git a/indra/llcommon/llqueuedthread.cpp b/indra/llcommon/llqueuedthread.cpp
index 1738c16dea..abf47a0f57 100644..100755
--- a/indra/llcommon/llqueuedthread.cpp
+++ b/indra/llcommon/llqueuedthread.cpp
@@ -134,8 +134,8 @@ S32 LLQueuedThread::updateQueue(F32 max_time_ms)
pending = getPending();
if(pending > 0)
{
- unpause();
- }
+ unpause();
+ }
}
else
{
diff --git a/indra/llcommon/llqueuedthread.h b/indra/llcommon/llqueuedthread.h
index d3704b0fe2..d3704b0fe2 100644..100755
--- a/indra/llcommon/llqueuedthread.h
+++ b/indra/llcommon/llqueuedthread.h
diff --git a/indra/llcommon/llrand.cpp b/indra/llcommon/llrand.cpp
index cb28a8f5c3..cb28a8f5c3 100644..100755
--- a/indra/llcommon/llrand.cpp
+++ b/indra/llcommon/llrand.cpp
diff --git a/indra/llcommon/llrand.h b/indra/llcommon/llrand.h
index ad317d5bf7..ad317d5bf7 100644..100755
--- a/indra/llcommon/llrand.h
+++ b/indra/llcommon/llrand.h
diff --git a/indra/llcommon/llrefcount.cpp b/indra/llcommon/llrefcount.cpp
index e1876599fc..e1876599fc 100644..100755
--- a/indra/llcommon/llrefcount.cpp
+++ b/indra/llcommon/llrefcount.cpp
diff --git a/indra/llcommon/llrefcount.h b/indra/llcommon/llrefcount.h
index 8eb5d53f3f..32ae15435a 100644..100755
--- a/indra/llcommon/llrefcount.h
+++ b/indra/llcommon/llrefcount.h
@@ -27,6 +27,7 @@
#define LLREFCOUNT_H
#include <boost/noncopyable.hpp>
+#include <boost/intrusive_ptr.hpp>
#define LL_REF_COUNT_DEBUG 0
#if LL_REF_COUNT_DEBUG
@@ -86,4 +87,22 @@ private:
#endif
};
+/**
+ * intrusive pointer support
+ * this allows you to use boost::intrusive_ptr with any LLRefCount-derived type
+ */
+namespace boost
+{
+ inline void intrusive_ptr_add_ref(LLRefCount* p)
+ {
+ p->ref();
+ }
+
+ inline void intrusive_ptr_release(LLRefCount* p)
+ {
+ p->unref();
+ }
+};
+
+
#endif
diff --git a/indra/llcommon/llregistry.h b/indra/llcommon/llregistry.h
new file mode 100755
index 0000000000..bb0d60247e
--- /dev/null
+++ b/indra/llcommon/llregistry.h
@@ -0,0 +1,360 @@
+/**
+ * @file llregistry.h
+ * @brief template classes for registering name, value pairs in nested scopes, statically, etc.
+ *
+ * $LicenseInfo:firstyear=2001&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$
+ */
+
+#ifndef LL_LLREGISTRY_H
+#define LL_LLREGISTRY_H
+
+#include <list>
+
+#include <boost/type_traits.hpp>
+#include "llsingleton.h"
+#include "llstl.h"
+
+template <typename T>
+struct LLRegistryDefaultComparator
+{
+ bool operator()(const T& lhs, const T& rhs) const
+ {
+ using std::less;
+ return less<T>()(lhs, rhs);
+ }
+};
+
+template <typename KEY, typename VALUE, typename COMPARATOR = LLRegistryDefaultComparator<KEY> >
+class LLRegistry
+{
+public:
+ typedef LLRegistry<KEY, VALUE, COMPARATOR> registry_t;
+ typedef typename boost::add_reference<typename boost::add_const<KEY>::type>::type ref_const_key_t;
+ typedef typename boost::add_reference<typename boost::add_const<VALUE>::type>::type ref_const_value_t;
+ typedef typename boost::add_reference<VALUE>::type ref_value_t;
+ typedef typename boost::add_pointer<typename boost::add_const<VALUE>::type>::type ptr_const_value_t;
+ typedef typename boost::add_pointer<VALUE>::type ptr_value_t;
+
+ class Registrar
+ {
+ friend class LLRegistry<KEY, VALUE, COMPARATOR>;
+ public:
+ typedef std::map<KEY, VALUE, COMPARATOR> registry_map_t;
+
+ bool add(ref_const_key_t key, ref_const_value_t value)
+ {
+ if (mMap.insert(std::make_pair(key, value)).second == false)
+ {
+ llwarns << "Tried to register " << key << " but it was already registered!" << llendl;
+ return false;
+ }
+ return true;
+ }
+
+ void remove(ref_const_key_t key)
+ {
+ mMap.erase(key);
+ }
+
+ void replace(ref_const_key_t key, ref_const_value_t value)
+ {
+ mMap[key] = value;
+ }
+
+ typename registry_map_t::const_iterator beginItems() const
+ {
+ return mMap.begin();
+ }
+
+ typename registry_map_t::const_iterator endItems() const
+ {
+ return mMap.end();
+ }
+
+ protected:
+ ptr_value_t getValue(ref_const_key_t key)
+ {
+ typename registry_map_t::iterator found_it = mMap.find(key);
+ if (found_it != mMap.end())
+ {
+ return &(found_it->second);
+ }
+ return NULL;
+ }
+
+ ptr_const_value_t getValue(ref_const_key_t key) const
+ {
+ typename registry_map_t::const_iterator found_it = mMap.find(key);
+ if (found_it != mMap.end())
+ {
+ return &(found_it->second);
+ }
+ return NULL;
+ }
+
+ // if the registry is used to store pointers, and null values are valid entries
+ // then use this function to check the existence of an entry
+ bool exists(ref_const_key_t key) const
+ {
+ return mMap.find(key) != mMap.end();
+ }
+
+ bool empty() const
+ {
+ return mMap.empty();
+ }
+
+ protected:
+ // use currentRegistrar() or defaultRegistrar()
+ Registrar() {}
+ ~Registrar() {}
+
+ private:
+ registry_map_t mMap;
+ };
+
+ typedef typename std::list<Registrar*> scope_list_t;
+ typedef typename std::list<Registrar*>::iterator scope_list_iterator_t;
+ typedef typename std::list<Registrar*>::const_iterator scope_list_const_iterator_t;
+
+ LLRegistry()
+ {}
+
+ ~LLRegistry() {}
+
+ ptr_value_t getValue(ref_const_key_t key)
+ {
+ for(scope_list_iterator_t it = mActiveScopes.begin();
+ it != mActiveScopes.end();
+ ++it)
+ {
+ ptr_value_t valuep = (*it)->getValue(key);
+ if (valuep != NULL) return valuep;
+ }
+ return mDefaultRegistrar.getValue(key);
+ }
+
+ ptr_const_value_t getValue(ref_const_key_t key) const
+ {
+ for(scope_list_const_iterator_t it = mActiveScopes.begin();
+ it != mActiveScopes.end();
+ ++it)
+ {
+ ptr_value_t valuep = (*it)->getValue(key);
+ if (valuep != NULL) return valuep;
+ }
+ return mDefaultRegistrar.getValue(key);
+ }
+
+ bool exists(ref_const_key_t key) const
+ {
+ for(scope_list_const_iterator_t it = mActiveScopes.begin();
+ it != mActiveScopes.end();
+ ++it)
+ {
+ if ((*it)->exists(key)) return true;
+ }
+
+ return mDefaultRegistrar.exists(key);
+ }
+
+ bool empty() const
+ {
+ for(scope_list_const_iterator_t it = mActiveScopes.begin();
+ it != mActiveScopes.end();
+ ++it)
+ {
+ if (!(*it)->empty()) return false;
+ }
+
+ return mDefaultRegistrar.empty();
+ }
+
+
+ Registrar& defaultRegistrar()
+ {
+ return mDefaultRegistrar;
+ }
+
+ const Registrar& defaultRegistrar() const
+ {
+ return mDefaultRegistrar;
+ }
+
+
+ Registrar& currentRegistrar()
+ {
+ if (!mActiveScopes.empty())
+ {
+ return *mActiveScopes.front();
+ }
+
+ return mDefaultRegistrar;
+ }
+
+ const Registrar& currentRegistrar() const
+ {
+ if (!mActiveScopes.empty())
+ {
+ return *mActiveScopes.front();
+ }
+
+ return mDefaultRegistrar;
+ }
+
+
+protected:
+ void addScope(Registrar* scope)
+ {
+ // newer scopes go up front
+ mActiveScopes.insert(mActiveScopes.begin(), scope);
+ }
+
+ void removeScope(Registrar* scope)
+ {
+ // O(N) but should be near the beggining and N should be small and this is safer than storing iterators
+ scope_list_iterator_t iter = std::find(mActiveScopes.begin(), mActiveScopes.end(), scope);
+ if (iter != mActiveScopes.end())
+ {
+ mActiveScopes.erase(iter);
+ }
+ }
+
+private:
+ scope_list_t mActiveScopes;
+ Registrar mDefaultRegistrar;
+};
+
+template <typename KEY, typename VALUE, typename DERIVED_TYPE, typename COMPARATOR = LLRegistryDefaultComparator<KEY> >
+class LLRegistrySingleton
+ : public LLRegistry<KEY, VALUE, COMPARATOR>,
+ public LLSingleton<DERIVED_TYPE>
+{
+ friend class LLSingleton<DERIVED_TYPE>;
+public:
+ typedef LLRegistry<KEY, VALUE, COMPARATOR> registry_t;
+ typedef const KEY& ref_const_key_t;
+ typedef const VALUE& ref_const_value_t;
+ typedef VALUE* ptr_value_t;
+ typedef const VALUE* ptr_const_value_t;
+ typedef LLSingleton<DERIVED_TYPE> singleton_t;
+
+ class ScopedRegistrar : public registry_t::Registrar
+ {
+ public:
+ ScopedRegistrar(bool push_scope = true)
+ {
+ if (push_scope)
+ {
+ pushScope();
+ }
+ }
+
+ ~ScopedRegistrar()
+ {
+ if (!singleton_t::destroyed())
+ {
+ popScope();
+ }
+ }
+
+ void pushScope()
+ {
+ singleton_t::instance().addScope(this);
+ }
+
+ void popScope()
+ {
+ singleton_t::instance().removeScope(this);
+ }
+
+ ptr_value_t getValueFromScope(ref_const_key_t key)
+ {
+ return getValue(key);
+ }
+
+ ptr_const_value_t getValueFromScope(ref_const_key_t key) const
+ {
+ return getValue(key);
+ }
+
+ private:
+ typename std::list<typename registry_t::Registrar*>::iterator mListIt;
+ };
+
+ class StaticRegistrar : public registry_t::Registrar
+ {
+ public:
+ virtual ~StaticRegistrar() {}
+ StaticRegistrar(ref_const_key_t key, ref_const_value_t value)
+ {
+ if (singleton_t::instance().exists(key))
+ {
+ llerrs << "Duplicate registry entry under key \"" << key << "\"" << llendl;
+ }
+ singleton_t::instance().mStaticScope->add(key, value);
+ }
+ };
+
+ // convenience functions
+ typedef typename LLRegistry<KEY, VALUE, COMPARATOR>::Registrar& ref_registrar_t;
+ static ref_registrar_t currentRegistrar()
+ {
+ return singleton_t::instance().registry_t::currentRegistrar();
+ }
+
+ static ref_registrar_t defaultRegistrar()
+ {
+ return singleton_t::instance().registry_t::defaultRegistrar();
+ }
+
+ static ptr_value_t getValue(ref_const_key_t key)
+ {
+ return singleton_t::instance().registry_t::getValue(key);
+ }
+
+protected:
+ // DERIVED_TYPE needs to derive from LLRegistrySingleton
+ LLRegistrySingleton()
+ : mStaticScope(NULL)
+ {}
+
+ virtual void initSingleton()
+ {
+ mStaticScope = new ScopedRegistrar();
+ }
+
+ virtual ~LLRegistrySingleton()
+ {
+ delete mStaticScope;
+ }
+
+private:
+ ScopedRegistrar* mStaticScope;
+};
+
+// helper macro for doing static registration
+#define GLUED_TOKEN(x, y) x ## y
+#define GLUE_TOKENS(x, y) GLUED_TOKEN(x, y)
+#define LLREGISTER_STATIC(REGISTRY, KEY, VALUE) static REGISTRY::StaticRegistrar GLUE_TOKENS(reg, __LINE__)(KEY, VALUE);
+
+#endif
diff --git a/indra/llcommon/llrun.cpp b/indra/llcommon/llrun.cpp
index f5d3f302fa..f5d3f302fa 100644..100755
--- a/indra/llcommon/llrun.cpp
+++ b/indra/llcommon/llrun.cpp
diff --git a/indra/llcommon/llrun.h b/indra/llcommon/llrun.h
index a117405366..a117405366 100644..100755
--- a/indra/llcommon/llrun.h
+++ b/indra/llcommon/llrun.h
diff --git a/indra/llcommon/llsafehandle.h b/indra/llcommon/llsafehandle.h
index 8d52d9bb15..8d52d9bb15 100644..100755
--- a/indra/llcommon/llsafehandle.h
+++ b/indra/llcommon/llsafehandle.h
diff --git a/indra/llcommon/llsd.cpp b/indra/llcommon/llsd.cpp
index e295e3c621..f962485284 100644..100755
--- a/indra/llcommon/llsd.cpp
+++ b/indra/llcommon/llsd.cpp
@@ -269,6 +269,7 @@ namespace
virtual LLSD::UUID asUUID() const { return LLUUID(mValue); }
virtual LLSD::Date asDate() const { return LLDate(mValue); }
virtual LLSD::URI asURI() const { return LLURI(mValue); }
+ virtual int size() const { return mValue.size(); }
};
LLSD::Integer ImplString::asInteger() const
@@ -505,6 +506,8 @@ namespace
LLSD::array_iterator beginArray() { return mData.begin(); }
LLSD::array_iterator endArray() { return mData.end(); }
+ LLSD::reverse_array_iterator rbeginArray() { return mData.rbegin(); }
+ LLSD::reverse_array_iterator rendArray() { return mData.rend(); }
virtual LLSD::array_const_iterator beginArray() const { return mData.begin(); }
virtual LLSD::array_const_iterator endArray() const { return mData.end(); }
@@ -946,6 +949,9 @@ LLSD::array_iterator LLSD::endArray() { return makeArray(impl).endArray(); }
LLSD::array_const_iterator LLSD::beginArray() const{ return safe(impl).beginArray(); }
LLSD::array_const_iterator LLSD::endArray() const { return safe(impl).endArray(); }
+LLSD::reverse_array_iterator LLSD::rbeginArray() { return makeArray(impl).rbeginArray(); }
+LLSD::reverse_array_iterator LLSD::rendArray() { return makeArray(impl).rendArray(); }
+
namespace llsd
{
diff --git a/indra/llcommon/llsd.h b/indra/llcommon/llsd.h
index 5eb69059ac..a3792c1f9d 100644..100755
--- a/indra/llcommon/llsd.h
+++ b/indra/llcommon/llsd.h
@@ -320,11 +320,15 @@ public:
typedef std::vector<LLSD>::iterator array_iterator;
typedef std::vector<LLSD>::const_iterator array_const_iterator;
-
+ typedef std::vector<LLSD>::reverse_iterator reverse_array_iterator;
+
array_iterator beginArray();
array_iterator endArray();
array_const_iterator beginArray() const;
array_const_iterator endArray() const;
+
+ reverse_array_iterator rbeginArray();
+ reverse_array_iterator rendArray();
//@}
/** @name Type Testing */
diff --git a/indra/llcommon/llsdparam.cpp b/indra/llcommon/llsdparam.cpp
new file mode 100755
index 0000000000..9f4460a988
--- /dev/null
+++ b/indra/llcommon/llsdparam.cpp
@@ -0,0 +1,341 @@
+/**
+ * @file llsdparam.cpp
+ * @brief parameter block abstraction for creating complex objects and
+ * parsing construction parameters from xml and LLSD
+ *
+ * $LicenseInfo:firstyear=2008&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"
+
+// Project includes
+#include "llsdparam.h"
+#include "llsdutil.h"
+
+static LLInitParam::Parser::parser_read_func_map_t sReadFuncs;
+static LLInitParam::Parser::parser_write_func_map_t sWriteFuncs;
+static LLInitParam::Parser::parser_inspect_func_map_t sInspectFuncs;
+static const LLSD NO_VALUE_MARKER;
+
+LLFastTimer::DeclareTimer FTM_SD_PARAM_ADAPTOR("LLSD to LLInitParam conversion");
+
+//
+// LLParamSDParser
+//
+LLParamSDParser::LLParamSDParser()
+: Parser(sReadFuncs, sWriteFuncs, sInspectFuncs)
+{
+ using boost::bind;
+
+ if (sReadFuncs.empty())
+ {
+ registerParserFuncs<LLInitParam::Flag>(readFlag, &LLParamSDParser::writeFlag);
+ registerParserFuncs<S32>(readS32, &LLParamSDParser::writeTypedValue<S32>);
+ registerParserFuncs<U32>(readU32, &LLParamSDParser::writeU32Param);
+ registerParserFuncs<F32>(readF32, &LLParamSDParser::writeTypedValue<F32>);
+ registerParserFuncs<F64>(readF64, &LLParamSDParser::writeTypedValue<F64>);
+ registerParserFuncs<bool>(readBool, &LLParamSDParser::writeTypedValue<bool>);
+ registerParserFuncs<std::string>(readString, &LLParamSDParser::writeTypedValue<std::string>);
+ registerParserFuncs<LLUUID>(readUUID, &LLParamSDParser::writeTypedValue<LLUUID>);
+ registerParserFuncs<LLDate>(readDate, &LLParamSDParser::writeTypedValue<LLDate>);
+ registerParserFuncs<LLURI>(readURI, &LLParamSDParser::writeTypedValue<LLURI>);
+ registerParserFuncs<LLSD>(readSD, &LLParamSDParser::writeTypedValue<LLSD>);
+ }
+}
+
+// special case handling of U32 due to ambiguous LLSD::assign overload
+bool LLParamSDParser::writeU32Param(LLParamSDParser::parser_t& parser, const void* val_ptr, parser_t::name_stack_t& name_stack)
+{
+ LLParamSDParser& sdparser = static_cast<LLParamSDParser&>(parser);
+ if (!sdparser.mWriteRootSD) return false;
+
+ parser_t::name_stack_range_t range(name_stack.begin(), name_stack.end());
+ LLSD& sd_to_write = LLParamSDParserUtilities::getSDWriteNode(*sdparser.mWriteRootSD, range);
+ sd_to_write.assign((S32)*((const U32*)val_ptr));
+
+ return true;
+}
+
+bool LLParamSDParser::writeFlag(LLParamSDParser::parser_t& parser, const void* val_ptr, parser_t::name_stack_t& name_stack)
+{
+ LLParamSDParser& sdparser = static_cast<LLParamSDParser&>(parser);
+ if (!sdparser.mWriteRootSD) return false;
+
+ parser_t::name_stack_range_t range(name_stack.begin(), name_stack.end());
+ LLParamSDParserUtilities::getSDWriteNode(*sdparser.mWriteRootSD, range);
+
+ return true;
+}
+
+void LLParamSDParser::submit(LLInitParam::BaseBlock& block, const LLSD& sd, LLInitParam::Parser::name_stack_t& name_stack)
+{
+ mCurReadSD = &sd;
+ block.submitValue(name_stack, *this);
+}
+
+void LLParamSDParser::readSD(const LLSD& sd, LLInitParam::BaseBlock& block, bool silent)
+{
+ mCurReadSD = NULL;
+ mNameStack.clear();
+ setParseSilently(silent);
+
+ LLParamSDParserUtilities::readSDValues(boost::bind(&LLParamSDParser::submit, this, boost::ref(block), _1, _2), sd, mNameStack);
+ //readSDValues(sd, block);
+}
+
+void LLParamSDParser::writeSD(LLSD& sd, const LLInitParam::BaseBlock& block)
+{
+ mNameStack.clear();
+ mWriteRootSD = &sd;
+
+ name_stack_t name_stack;
+ block.serializeBlock(*this, name_stack);
+}
+
+/*virtual*/ std::string LLParamSDParser::getCurrentElementName()
+{
+ std::string full_name = "sd";
+ for (name_stack_t::iterator it = mNameStack.begin();
+ it != mNameStack.end();
+ ++it)
+ {
+ full_name += llformat("[%s]", it->first.c_str());
+ }
+
+ return full_name;
+}
+
+
+bool LLParamSDParser::readFlag(Parser& parser, void* val_ptr)
+{
+ LLParamSDParser& self = static_cast<LLParamSDParser&>(parser);
+ return self.mCurReadSD == &NO_VALUE_MARKER;
+}
+
+
+bool LLParamSDParser::readS32(Parser& parser, void* val_ptr)
+{
+ LLParamSDParser& self = static_cast<LLParamSDParser&>(parser);
+
+ *((S32*)val_ptr) = self.mCurReadSD->asInteger();
+ return true;
+}
+
+bool LLParamSDParser::readU32(Parser& parser, void* val_ptr)
+{
+ LLParamSDParser& self = static_cast<LLParamSDParser&>(parser);
+
+ *((U32*)val_ptr) = self.mCurReadSD->asInteger();
+ return true;
+}
+
+bool LLParamSDParser::readF32(Parser& parser, void* val_ptr)
+{
+ LLParamSDParser& self = static_cast<LLParamSDParser&>(parser);
+
+ *((F32*)val_ptr) = self.mCurReadSD->asReal();
+ return true;
+}
+
+bool LLParamSDParser::readF64(Parser& parser, void* val_ptr)
+{
+ LLParamSDParser& self = static_cast<LLParamSDParser&>(parser);
+
+ *((F64*)val_ptr) = self.mCurReadSD->asReal();
+ return true;
+}
+
+bool LLParamSDParser::readBool(Parser& parser, void* val_ptr)
+{
+ LLParamSDParser& self = static_cast<LLParamSDParser&>(parser);
+
+ *((bool*)val_ptr) = self.mCurReadSD->asBoolean();
+ return true;
+}
+
+bool LLParamSDParser::readString(Parser& parser, void* val_ptr)
+{
+ LLParamSDParser& self = static_cast<LLParamSDParser&>(parser);
+
+ *((std::string*)val_ptr) = self.mCurReadSD->asString();
+ return true;
+}
+
+bool LLParamSDParser::readUUID(Parser& parser, void* val_ptr)
+{
+ LLParamSDParser& self = static_cast<LLParamSDParser&>(parser);
+
+ *((LLUUID*)val_ptr) = self.mCurReadSD->asUUID();
+ return true;
+}
+
+bool LLParamSDParser::readDate(Parser& parser, void* val_ptr)
+{
+ LLParamSDParser& self = static_cast<LLParamSDParser&>(parser);
+
+ *((LLDate*)val_ptr) = self.mCurReadSD->asDate();
+ return true;
+}
+
+bool LLParamSDParser::readURI(Parser& parser, void* val_ptr)
+{
+ LLParamSDParser& self = static_cast<LLParamSDParser&>(parser);
+
+ *((LLURI*)val_ptr) = self.mCurReadSD->asURI();
+ return true;
+}
+
+bool LLParamSDParser::readSD(Parser& parser, void* val_ptr)
+{
+ LLParamSDParser& self = static_cast<LLParamSDParser&>(parser);
+
+ *((LLSD*)val_ptr) = *self.mCurReadSD;
+ return true;
+}
+
+// static
+LLSD& LLParamSDParserUtilities::getSDWriteNode(LLSD& input, LLInitParam::Parser::name_stack_range_t& name_stack_range)
+{
+ LLSD* sd_to_write = &input;
+
+ for (LLInitParam::Parser::name_stack_t::iterator it = name_stack_range.first;
+ it != name_stack_range.second;
+ ++it)
+ {
+ bool new_traversal = it->second;
+
+ LLSD* child_sd;
+ if (it->first.empty())
+ {
+ child_sd = sd_to_write;
+ if (child_sd->isUndefined())
+ {
+ *child_sd = LLSD::emptyArray();
+ }
+ if (new_traversal)
+ {
+ // write to new element at end
+ sd_to_write = &(*child_sd)[child_sd->size()];
+ }
+ else
+ {
+ // write to last of existing elements, or first element if empty
+ sd_to_write = &(*child_sd)[llmax(0, child_sd->size() - 1)];
+ }
+ }
+ else
+ {
+ sd_to_write = &(*sd_to_write)[it->first];
+ }
+ it->second = false;
+ }
+
+ return *sd_to_write;
+}
+
+//static
+void LLParamSDParserUtilities::readSDValues(read_sd_cb_t cb, const LLSD& sd, LLInitParam::Parser::name_stack_t& stack)
+{
+ if (sd.isMap())
+ {
+ for (LLSD::map_const_iterator it = sd.beginMap();
+ it != sd.endMap();
+ ++it)
+ {
+ stack.push_back(make_pair(it->first, true));
+ readSDValues(cb, it->second, stack);
+ stack.pop_back();
+ }
+ }
+ else if (sd.isArray())
+ {
+ for (LLSD::array_const_iterator it = sd.beginArray();
+ it != sd.endArray();
+ ++it)
+ {
+ stack.push_back(make_pair(std::string(), true));
+ readSDValues(cb, *it, stack);
+ stack.pop_back();
+ }
+ }
+ else if (sd.isUndefined())
+ {
+ if (!cb.empty())
+ {
+ cb(NO_VALUE_MARKER, stack);
+ }
+ }
+ else
+ {
+ if (!cb.empty())
+ {
+ cb(sd, stack);
+ }
+ }
+}
+
+//static
+void LLParamSDParserUtilities::readSDValues(read_sd_cb_t cb, const LLSD& sd)
+{
+ LLInitParam::Parser::name_stack_t stack = LLInitParam::Parser::name_stack_t();
+ readSDValues(cb, sd, stack);
+}
+namespace LLInitParam
+{
+ // LLSD specialization
+ // block param interface
+ bool ParamValue<LLSD, NOT_BLOCK>::deserializeBlock(Parser& p, Parser::name_stack_range_t& name_stack, bool new_name)
+ {
+ if (name_stack.first == name_stack.second
+ && p.readValue<LLSD>(mValue))
+ {
+ return true;
+ }
+
+ LLSD& sd = LLParamSDParserUtilities::getSDWriteNode(mValue, name_stack);
+
+ LLSD::String string;
+
+ if (p.readValue<LLSD::String>(string))
+ {
+ sd = string;
+ return true;
+ }
+ return false;
+ }
+
+ //static
+ void ParamValue<LLSD, NOT_BLOCK>::serializeElement(Parser& p, const LLSD& sd, Parser::name_stack_t& name_stack)
+ {
+ p.writeValue<LLSD::String>(sd.asString(), name_stack);
+ }
+
+ void ParamValue<LLSD, NOT_BLOCK>::serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const BaseBlock* diff_block) const
+ {
+ // attempt to write LLSD out directly
+ if (!p.writeValue<LLSD>(mValue, name_stack))
+ {
+ // otherwise read from LLSD value and serialize out to parser (which could be LLSD, XUI, etc)
+ LLParamSDParserUtilities::readSDValues(boost::bind(&serializeElement, boost::ref(p), _1, _2), mValue, name_stack);
+ }
+ }
+}
diff --git a/indra/llcommon/llsdparam.h b/indra/llcommon/llsdparam.h
new file mode 100755
index 0000000000..6ef5debd7b
--- /dev/null
+++ b/indra/llcommon/llsdparam.h
@@ -0,0 +1,126 @@
+/**
+ * @file llsdparam.h
+ * @brief parameter block abstraction for creating complex objects and
+ * parsing construction parameters from xml and LLSD
+ *
+ * $LicenseInfo:firstyear=2008&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$
+ */
+
+#ifndef LL_LLSDPARAM_H
+#define LL_LLSDPARAM_H
+
+#include "llinitparam.h"
+#include "boost/function.hpp"
+
+struct LL_COMMON_API LLParamSDParserUtilities
+{
+ static LLSD& getSDWriteNode(LLSD& input, LLInitParam::Parser::name_stack_range_t& name_stack_range);
+
+ typedef boost::function<void (const LLSD&, LLInitParam::Parser::name_stack_t&)> read_sd_cb_t;
+ static void readSDValues(read_sd_cb_t cb, const LLSD& sd, LLInitParam::Parser::name_stack_t& stack);
+ static void readSDValues(read_sd_cb_t cb, const LLSD& sd);
+};
+
+class LL_COMMON_API LLParamSDParser
+: public LLInitParam::Parser
+{
+LOG_CLASS(LLParamSDParser);
+
+typedef LLInitParam::Parser parser_t;
+
+public:
+ LLParamSDParser();
+ void readSD(const LLSD& sd, LLInitParam::BaseBlock& block, bool silent = false);
+ void writeSD(LLSD& sd, const LLInitParam::BaseBlock& block);
+
+ /*virtual*/ std::string getCurrentElementName();
+
+private:
+ void submit(LLInitParam::BaseBlock& block, const LLSD& sd, LLInitParam::Parser::name_stack_t& name_stack);
+
+ template<typename T>
+ static bool writeTypedValue(Parser& parser, const void* val_ptr, parser_t::name_stack_t& name_stack)
+ {
+ LLParamSDParser& sdparser = static_cast<LLParamSDParser&>(parser);
+ if (!sdparser.mWriteRootSD) return false;
+
+ LLInitParam::Parser::name_stack_range_t range(name_stack.begin(), name_stack.end());
+ LLSD& sd_to_write = LLParamSDParserUtilities::getSDWriteNode(*sdparser.mWriteRootSD, range);
+
+ sd_to_write.assign(*((const T*)val_ptr));
+ return true;
+ }
+
+ static bool writeU32Param(Parser& parser, const void* value_ptr, parser_t::name_stack_t& name_stack);
+ static bool writeFlag(Parser& parser, const void* value_ptr, parser_t::name_stack_t& name_stack);
+
+ static bool readFlag(Parser& parser, void* val_ptr);
+ static bool readS32(Parser& parser, void* val_ptr);
+ static bool readU32(Parser& parser, void* val_ptr);
+ static bool readF32(Parser& parser, void* val_ptr);
+ static bool readF64(Parser& parser, void* val_ptr);
+ static bool readBool(Parser& parser, void* val_ptr);
+ static bool readString(Parser& parser, void* val_ptr);
+ static bool readUUID(Parser& parser, void* val_ptr);
+ static bool readDate(Parser& parser, void* val_ptr);
+ static bool readURI(Parser& parser, void* val_ptr);
+ static bool readSD(Parser& parser, void* val_ptr);
+
+ Parser::name_stack_t mNameStack;
+ const LLSD* mCurReadSD;
+ LLSD* mWriteRootSD;
+ LLSD* mCurWriteSD;
+};
+
+
+extern LL_COMMON_API LLFastTimer::DeclareTimer FTM_SD_PARAM_ADAPTOR;
+template<typename T>
+class LLSDParamAdapter : public T
+{
+public:
+ LLSDParamAdapter() {}
+ LLSDParamAdapter(const LLSD& sd)
+ {
+ LLFastTimer _(FTM_SD_PARAM_ADAPTOR);
+ LLParamSDParser parser;
+ // don't spam for implicit parsing of LLSD, as we want to allow arbitrary freeform data and ignore most of it
+ bool parse_silently = true;
+ parser.readSD(sd, *this, parse_silently);
+ }
+
+ operator LLSD() const
+ {
+ LLParamSDParser parser;
+ LLSD sd;
+ parser.writeSD(sd, *this);
+ return sd;
+ }
+
+ LLSDParamAdapter(const T& val)
+ : T(val)
+ {
+ T::operator=(val);
+ }
+};
+
+#endif // LL_LLSDPARAM_H
+
diff --git a/indra/llcommon/llsdserialize.cpp b/indra/llcommon/llsdserialize.cpp
index b419101b7e..ad4fce6f35 100644..100755
--- a/indra/llcommon/llsdserialize.cpp
+++ b/indra/llcommon/llsdserialize.cpp
@@ -55,6 +55,10 @@ static const char LEGACY_NON_HEADER[] = "<llsd>";
const std::string LLSD_BINARY_HEADER("LLSD/Binary");
const std::string LLSD_XML_HEADER("LLSD/XML");
+//used to deflate a gzipped asset (currently used for navmeshes)
+#define windowBits 15
+#define ENABLE_ZLIB_GZIP 32
+
/**
* LLSDSerialize
*/
@@ -1447,9 +1451,12 @@ S32 LLSDBinaryFormatter::format(const LLSD& data, std::ostream& ostr, U32 option
}
case LLSD::TypeUUID:
+ {
ostr.put('u');
- ostr.write((const char*)(&(data.asUUID().mData)), UUID_BYTES);
+ LLUUID temp = data.asUUID();
+ ostr.write((const char*)(&(temp.mData)), UUID_BYTES);
break;
+ }
case LLSD::TypeString:
ostr.put('s');
@@ -2096,7 +2103,7 @@ bool unzip_llsd(LLSD& data, std::istream& is, S32 size)
strm.next_in = in;
S32 ret = inflateInit(&strm);
-
+
do
{
strm.avail_out = CHUNK;
@@ -2159,12 +2166,87 @@ bool unzip_llsd(LLSD& data, std::istream& is, S32 size)
llwarns << "Failed to unzip LLSD block" << llendl;
free(result);
return false;
- }
+ }
}
free(result);
return true;
}
+//This unzip function will only work with a gzip header and trailer - while the contents
+//of the actual compressed data is the same for either format (gzip vs zlib ), the headers
+//and trailers are different for the formats.
+U8* unzip_llsdNavMesh( bool& valid, unsigned int& outsize, std::istream& is, S32 size )
+{
+ U8* result = NULL;
+ U32 cur_size = 0;
+ z_stream strm;
+
+ const U32 CHUNK = 0x4000;
+
+ U8 *in = new U8[size];
+ is.read((char*) in, size);
+
+ U8 out[CHUNK];
+
+ strm.zalloc = Z_NULL;
+ strm.zfree = Z_NULL;
+ strm.opaque = Z_NULL;
+ strm.avail_in = size;
+ strm.next_in = in;
+
+ S32 ret = inflateInit2(&strm, windowBits | ENABLE_ZLIB_GZIP );
+ do
+ {
+ strm.avail_out = CHUNK;
+ strm.next_out = out;
+ ret = inflate(&strm, Z_NO_FLUSH);
+ if (ret == Z_STREAM_ERROR)
+ {
+ inflateEnd(&strm);
+ free(result);
+ delete [] in;
+ valid = false;
+ }
+
+ switch (ret)
+ {
+ case Z_NEED_DICT:
+ ret = Z_DATA_ERROR;
+ case Z_DATA_ERROR:
+ case Z_MEM_ERROR:
+ inflateEnd(&strm);
+ free(result);
+ delete [] in;
+ valid = false;
+ break;
+ }
+
+ U32 have = CHUNK-strm.avail_out;
+
+ result = (U8*) realloc(result, cur_size + have);
+ memcpy(result+cur_size, out, have);
+ cur_size += have;
+
+ } while (ret == Z_OK);
+
+ inflateEnd(&strm);
+ delete [] in;
+
+ if (ret != Z_STREAM_END)
+ {
+ free(result);
+ valid = false;
+ return NULL;
+ }
+
+ //result now points to the decompressed LLSD block
+ {
+ outsize= cur_size;
+ valid = true;
+ }
+
+ return result;
+}
diff --git a/indra/llcommon/llsdserialize.h b/indra/llcommon/llsdserialize.h
index 99a3ea3cd4..e7a5507385 100644..100755
--- a/indra/llcommon/llsdserialize.h
+++ b/indra/llcommon/llsdserialize.h
@@ -300,7 +300,7 @@ public:
/**
* @brief Constructor
*/
- LLSDXMLParser();
+ LLSDXMLParser(bool emit_errors=true);
protected:
/**
@@ -747,25 +747,25 @@ public:
return f->format(sd, str, LLSDFormatter::OPTIONS_PRETTY);
}
- static S32 fromXMLEmbedded(LLSD& sd, std::istream& str)
+ static S32 fromXMLEmbedded(LLSD& sd, std::istream& str, bool emit_errors=true)
{
// no need for max_bytes since xml formatting is not
// subvertable by bad sizes.
- LLPointer<LLSDXMLParser> p = new LLSDXMLParser;
+ LLPointer<LLSDXMLParser> p = new LLSDXMLParser(emit_errors);
return p->parse(str, sd, LLSDSerialize::SIZE_UNLIMITED);
}
// Line oriented parser, 30% faster than fromXML(), but can
// only be used when you know you have the complete XML
// document available in the stream.
- static S32 fromXMLDocument(LLSD& sd, std::istream& str)
+ static S32 fromXMLDocument(LLSD& sd, std::istream& str, bool emit_errors=true)
{
- LLPointer<LLSDXMLParser> p = new LLSDXMLParser();
+ LLPointer<LLSDXMLParser> p = new LLSDXMLParser(emit_errors);
return p->parseLines(str, sd);
}
- static S32 fromXML(LLSD& sd, std::istream& str)
+ static S32 fromXML(LLSD& sd, std::istream& str, bool emit_errors=true)
{
- return fromXMLEmbedded(sd, str);
-// return fromXMLDocument(sd, str);
+ return fromXMLEmbedded(sd, str, emit_errors);
+// return fromXMLDocument(sd, str, emit_errors);
}
/*
@@ -793,5 +793,5 @@ public:
//dirty little zip functions -- yell at davep
LL_COMMON_API std::string zip_llsd(LLSD& data);
LL_COMMON_API bool unzip_llsd(LLSD& data, std::istream& is, S32 size);
-
+LL_COMMON_API U8* unzip_llsdNavMesh( bool& valid, unsigned int& outsize,std::istream& is, S32 size);
#endif // LL_LLSDSERIALIZE_H
diff --git a/indra/llcommon/llsdserialize_xml.cpp b/indra/llcommon/llsdserialize_xml.cpp
index 34b3dbb99a..614a2d5636 100644..100755
--- a/indra/llcommon/llsdserialize_xml.cpp
+++ b/indra/llcommon/llsdserialize_xml.cpp
@@ -250,7 +250,7 @@ std::string LLSDXMLFormatter::escapeString(const std::string& in)
class LLSDXMLParser::Impl
{
public:
- Impl();
+ Impl(bool emit_errors);
~Impl();
S32 parse(std::istream& input, LLSD& data);
@@ -294,6 +294,7 @@ private:
static const XML_Char* findAttribute(const XML_Char* name, const XML_Char** pairs);
+ bool mEmitErrors;
XML_Parser mParser;
@@ -315,7 +316,8 @@ private:
};
-LLSDXMLParser::Impl::Impl()
+LLSDXMLParser::Impl::Impl(bool emit_errors)
+ : mEmitErrors(emit_errors)
{
mParser = XML_ParserCreate(NULL);
reset();
@@ -402,7 +404,10 @@ S32 LLSDXMLParser::Impl::parse(std::istream& input, LLSD& data)
{
((char*) buffer)[count ? count - 1 : 0] = '\0';
}
+ if (mEmitErrors)
+ {
llinfos << "LLSDXMLParser::Impl::parse: XML_STATUS_ERROR parsing:" << (char*) buffer << llendl;
+ }
data = LLSD();
return LLSDParser::PARSE_FAILURE;
}
@@ -480,7 +485,10 @@ S32 LLSDXMLParser::Impl::parseLines(std::istream& input, LLSD& data)
if (status == XML_STATUS_ERROR
&& !mGracefullStop)
{
+ if (mEmitErrors)
+ {
llinfos << "LLSDXMLParser::Impl::parseLines: XML_STATUS_ERROR" << llendl;
+ }
return LLSDParser::PARSE_FAILURE;
}
@@ -897,7 +905,7 @@ LLSDXMLParser::Impl::Element LLSDXMLParser::Impl::readElement(const XML_Char* na
/**
* LLSDXMLParser
*/
-LLSDXMLParser::LLSDXMLParser() : impl(* new Impl)
+LLSDXMLParser::LLSDXMLParser(bool emit_errors /* = true */) : impl(* new Impl(emit_errors))
{
}
diff --git a/indra/llcommon/llsdserialize_xml.h b/indra/llcommon/llsdserialize_xml.h
index dcc5f3d3c7..dcc5f3d3c7 100644..100755
--- a/indra/llcommon/llsdserialize_xml.h
+++ b/indra/llcommon/llsdserialize_xml.h
diff --git a/indra/llcommon/llsdutil.cpp b/indra/llcommon/llsdutil.cpp
index 803417d368..803417d368 100644..100755
--- a/indra/llcommon/llsdutil.cpp
+++ b/indra/llcommon/llsdutil.cpp
diff --git a/indra/llcommon/llsdutil.h b/indra/llcommon/llsdutil.h
index 532d3f9341..532d3f9341 100644..100755
--- a/indra/llcommon/llsdutil.h
+++ b/indra/llcommon/llsdutil.h
diff --git a/indra/llcommon/llsecondlifeurls.cpp b/indra/llcommon/llsecondlifeurls.cpp
index 9154e05e43..9154e05e43 100644..100755
--- a/indra/llcommon/llsecondlifeurls.cpp
+++ b/indra/llcommon/llsecondlifeurls.cpp
diff --git a/indra/llcommon/llsecondlifeurls.h b/indra/llcommon/llsecondlifeurls.h
index 62f357ffed..62f357ffed 100644..100755
--- a/indra/llcommon/llsecondlifeurls.h
+++ b/indra/llcommon/llsecondlifeurls.h
diff --git a/indra/llcommon/llsimplehash.h b/indra/llcommon/llsimplehash.h
index 727b4568d8..727b4568d8 100644..100755
--- a/indra/llcommon/llsimplehash.h
+++ b/indra/llcommon/llsimplehash.h
diff --git a/indra/llcommon/llsingleton.cpp b/indra/llcommon/llsingleton.cpp
index eb8e2c9456..9b49e52377 100644..100755
--- a/indra/llcommon/llsingleton.cpp
+++ b/indra/llcommon/llsingleton.cpp
@@ -28,5 +28,4 @@
#include "llsingleton.h"
-std::map<std::string, void *> * LLSingletonRegistry::sSingletonMap = NULL;
diff --git a/indra/llcommon/llsingleton.h b/indra/llcommon/llsingleton.h
index 49d99f2cd0..40002313f1 100644..100755
--- a/indra/llcommon/llsingleton.h
+++ b/indra/llcommon/llsingleton.h
@@ -30,38 +30,6 @@
#include <typeinfo>
#include <boost/noncopyable.hpp>
-/// @brief A global registry of all singletons to prevent duplicate allocations
-/// across shared library boundaries
-class LL_COMMON_API LLSingletonRegistry {
- private:
- typedef std::map<std::string, void *> TypeMap;
- static TypeMap * sSingletonMap;
-
- static void checkInit()
- {
- if(sSingletonMap == NULL)
- {
- sSingletonMap = new TypeMap();
- }
- }
-
- public:
- template<typename T> static void * & get()
- {
- std::string name(typeid(T).name());
-
- checkInit();
-
- // the first entry of the pair returned by insert will be either the existing
- // iterator matching our key, or the newly inserted NULL initialized entry
- // see "Insert element" in http://www.sgi.com/tech/stl/UniqueAssociativeContainer.html
- TypeMap::iterator result =
- sSingletonMap->insert(std::make_pair(name, (void*)NULL)).first;
-
- return result->second;
- }
-};
-
// LLSingleton implements the getInstance() method part of the Singleton
// pattern. It can't make the derived class constructors protected, though, so
// you have to do that yourself.
@@ -101,20 +69,23 @@ private:
} EInitState;
// stores pointer to singleton instance
- // and tracks initialization state of singleton
- struct SingletonInstanceData
+ struct SingletonLifetimeManager
{
- EInitState mInitState;
- DERIVED_TYPE* mSingletonInstance;
-
- SingletonInstanceData()
- : mSingletonInstance(NULL),
- mInitState(UNINITIALIZED)
- {}
-
- ~SingletonInstanceData()
+ SingletonLifetimeManager()
+ {
+ construct();
+ }
+
+ static void construct()
{
- if (mInitState != DELETED)
+ sData.mInitState = CONSTRUCTING;
+ sData.mInstance = new DERIVED_TYPE();
+ sData.mInitState = INITIALIZING;
+ }
+
+ ~SingletonLifetimeManager()
+ {
+ if (sData.mInitState != DELETED)
{
deleteSingleton();
}
@@ -124,9 +95,8 @@ private:
public:
virtual ~LLSingleton()
{
- SingletonInstanceData& data = getData();
- data.mSingletonInstance = NULL;
- data.mInitState = DELETED;
+ sData.mInstance = NULL;
+ sData.mInitState = DELETED;
}
/**
@@ -151,50 +121,46 @@ public:
*/
static void deleteSingleton()
{
- delete getData().mSingletonInstance;
- getData().mSingletonInstance = NULL;
- getData().mInitState = DELETED;
+ delete sData.mInstance;
+ sData.mInstance = NULL;
+ sData.mInitState = DELETED;
}
- static SingletonInstanceData& getData()
- {
- // this is static to cache the lookup results
- static void * & registry = LLSingletonRegistry::get<DERIVED_TYPE>();
-
- // *TODO - look into making this threadsafe
- if(NULL == registry)
- {
- static SingletonInstanceData data;
- registry = &data;
- }
-
- return *static_cast<SingletonInstanceData *>(registry);
- }
static DERIVED_TYPE* getInstance()
{
- SingletonInstanceData& data = getData();
+ static SingletonLifetimeManager sLifeTimeMgr;
- if (data.mInitState == CONSTRUCTING)
+ switch (sData.mInitState)
{
+ case UNINITIALIZED:
+ // should never be uninitialized at this point
+ llassert(false);
+ return NULL;
+ case CONSTRUCTING:
llerrs << "Tried to access singleton " << typeid(DERIVED_TYPE).name() << " from singleton constructor!" << llendl;
- }
-
- if (data.mInitState == DELETED)
- {
+ return NULL;
+ case INITIALIZING:
+ // go ahead and flag ourselves as initialized so we can be reentrant during initialization
+ sData.mInitState = INITIALIZED;
+ sData.mInstance->initSingleton();
+ return sData.mInstance;
+ case INITIALIZED:
+ return sData.mInstance;
+ case DELETED:
llwarns << "Trying to access deleted singleton " << typeid(DERIVED_TYPE).name() << " creating new instance" << llendl;
+ SingletonLifetimeManager::construct();
+ sData.mInitState = INITIALIZED;
+ sData.mInstance->initSingleton();
+ return sData.mInstance;
}
-
- if (!data.mSingletonInstance)
- {
- data.mInitState = CONSTRUCTING;
- data.mSingletonInstance = new DERIVED_TYPE();
- data.mInitState = INITIALIZING;
- data.mSingletonInstance->initSingleton();
- data.mInitState = INITIALIZED;
- }
-
- return data.mSingletonInstance;
+
+ return NULL;
+ }
+
+ static DERIVED_TYPE* getIfExists()
+ {
+ return sData.mInstance;
}
// Reference version of getInstance()
@@ -208,18 +174,29 @@ public:
// Use this to avoid accessing singletons before the can safely be constructed
static bool instanceExists()
{
- return getData().mInitState == INITIALIZED;
+ return sData.mInitState == INITIALIZED;
}
// Has this singleton already been deleted?
// Use this to avoid accessing singletons from a static object's destructor
static bool destroyed()
{
- return getData().mInitState == DELETED;
+ return sData.mInitState == DELETED;
}
private:
+
virtual void initSingleton() {}
+
+ struct SingletonData
+ {
+ EInitState mInitState;
+ DERIVED_TYPE* mInstance;
+ };
+ static SingletonData sData;
};
+template<typename T>
+typename LLSingleton<T>::SingletonData LLSingleton<T>::sData;
+
#endif
diff --git a/indra/llcommon/llskiplist.h b/indra/llcommon/llskiplist.h
index ed132381f9..ed132381f9 100644..100755
--- a/indra/llcommon/llskiplist.h
+++ b/indra/llcommon/llskiplist.h
diff --git a/indra/llcommon/llskipmap.h b/indra/llcommon/llskipmap.h
index 49ff2928d1..49ff2928d1 100644..100755
--- a/indra/llcommon/llskipmap.h
+++ b/indra/llcommon/llskipmap.h
diff --git a/indra/llcommon/llsmoothstep.h b/indra/llcommon/llsmoothstep.h
index 1f97a3ec89..1f97a3ec89 100644..100755
--- a/indra/llcommon/llsmoothstep.h
+++ b/indra/llcommon/llsmoothstep.h
diff --git a/indra/llcommon/llsortedvector.h b/indra/llcommon/llsortedvector.h
new file mode 100755
index 0000000000..391b82ee44
--- /dev/null
+++ b/indra/llcommon/llsortedvector.h
@@ -0,0 +1,152 @@
+/**
+ * @file llsortedvector.h
+ * @author Nat Goodspeed
+ * @date 2012-04-08
+ * @brief LLSortedVector class wraps a vector that we maintain in sorted
+ * order so we can perform binary-search lookups.
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Copyright (c) 2012, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+#if ! defined(LL_LLSORTEDVECTOR_H)
+#define LL_LLSORTEDVECTOR_H
+
+#include <vector>
+#include <algorithm>
+
+/**
+ * LLSortedVector contains a std::vector<std::pair> that we keep sorted on the
+ * first of the pair. This makes insertion somewhat more expensive than simple
+ * std::vector::push_back(), but allows us to use binary search for lookups.
+ * It's intended for small aggregates where lookup is far more performance-
+ * critical than insertion; in such cases a binary search on a small, sorted
+ * std::vector can be more performant than a std::map lookup.
+ */
+template <typename KEY, typename VALUE>
+class LLSortedVector
+{
+public:
+ typedef LLSortedVector<KEY, VALUE> self;
+ typedef KEY key_type;
+ typedef VALUE mapped_type;
+ typedef std::pair<key_type, mapped_type> value_type;
+ typedef std::vector<value_type> PairVector;
+ typedef typename PairVector::iterator iterator;
+ typedef typename PairVector::const_iterator const_iterator;
+
+ /// Empty
+ LLSortedVector() {}
+
+ /// Fixed initial size
+ LLSortedVector(std::size_t size):
+ mVector(size)
+ {}
+
+ /// Bulk load
+ template <typename ITER>
+ LLSortedVector(ITER begin, ITER end):
+ mVector(begin, end)
+ {
+ // Allow caller to dump in a bunch of (pairs convertible to)
+ // value_type if desired, but make sure we sort afterwards.
+ std::sort(mVector.begin(), mVector.end());
+ }
+
+ /// insert(key, value)
+ std::pair<iterator, bool> insert(const key_type& key, const mapped_type& value)
+ {
+ return insert(value_type(key, value));
+ }
+
+ /// insert(value_type)
+ std::pair<iterator, bool> insert(const value_type& pair)
+ {
+ typedef std::pair<iterator, bool> iterbool;
+ iterator found = std::lower_bound(mVector.begin(), mVector.end(), pair,
+ less<value_type>());
+ // have to check for end() before it's even valid to dereference
+ if (found == mVector.end())
+ {
+ std::size_t index(mVector.size());
+ mVector.push_back(pair);
+ // don't forget that push_back() invalidates 'found'
+ return iterbool(mVector.begin() + index, true);
+ }
+ if (found->first == pair.first)
+ {
+ return iterbool(found, false);
+ }
+ // remember that insert() invalidates 'found' -- save index
+ std::size_t index(found - mVector.begin());
+ mVector.insert(found, pair);
+ // okay, convert from index back to iterator
+ return iterbool(mVector.begin() + index, true);
+ }
+
+ iterator begin() { return mVector.begin(); }
+ iterator end() { return mVector.end(); }
+ const_iterator begin() const { return mVector.begin(); }
+ const_iterator end() const { return mVector.end(); }
+
+ bool empty() const { return mVector.empty(); }
+ std::size_t size() const { return mVector.size(); }
+
+ /// find
+ iterator find(const key_type& key)
+ {
+ iterator found = std::lower_bound(mVector.begin(), mVector.end(),
+ value_type(key, mapped_type()),
+ less<value_type>());
+ if (found == mVector.end() || found->first != key)
+ return mVector.end();
+ return found;
+ }
+
+ const_iterator find(const key_type& key) const
+ {
+ return const_cast<self*>(this)->find(key);
+ }
+
+private:
+ // Define our own 'less' comparator so we can specialize without messing
+ // with std::less.
+ template <typename T>
+ struct less: public std::less<T> {};
+
+ // Specialize 'less' for an LLSortedVector::value_type involving
+ // std::type_info*. This is one of LLSortedVector's foremost use cases. We
+ // specialize 'less' rather than just defining a specific comparator
+ // because LLSortedVector should be usable for other key_types as well.
+ template <typename T>
+ struct less< std::pair<std::type_info*, T> >:
+ public std::binary_function<std::pair<std::type_info*, T>,
+ std::pair<std::type_info*, T>,
+ bool>
+ {
+ bool operator()(const std::pair<std::type_info*, T>& lhs,
+ const std::pair<std::type_info*, T>& rhs) const
+ {
+ return lhs.first->before(*rhs.first);
+ }
+ };
+
+ // Same as above, but with const std::type_info*.
+ template <typename T>
+ struct less< std::pair<const std::type_info*, T> >:
+ public std::binary_function<std::pair<const std::type_info*, T>,
+ std::pair<const std::type_info*, T>,
+ bool>
+ {
+ bool operator()(const std::pair<const std::type_info*, T>& lhs,
+ const std::pair<const std::type_info*, T>& rhs) const
+ {
+ return lhs.first->before(*rhs.first);
+ }
+ };
+
+ PairVector mVector;
+};
+
+#endif /* ! defined(LL_LLSORTEDVECTOR_H) */
diff --git a/indra/llcommon/llstack.h b/indra/llcommon/llstack.h
index 315de6ba2d..315de6ba2d 100644..100755
--- a/indra/llcommon/llstack.h
+++ b/indra/llcommon/llstack.h
diff --git a/indra/llcommon/llstacktrace.cpp b/indra/llcommon/llstacktrace.cpp
index ccd7ef91c2..ccd7ef91c2 100644..100755
--- a/indra/llcommon/llstacktrace.cpp
+++ b/indra/llcommon/llstacktrace.cpp
diff --git a/indra/llcommon/llstacktrace.h b/indra/llcommon/llstacktrace.h
index ca72c64c5d..ca72c64c5d 100644..100755
--- a/indra/llcommon/llstacktrace.h
+++ b/indra/llcommon/llstacktrace.h
diff --git a/indra/llcommon/llstat.cpp b/indra/llcommon/llstat.cpp
index 057257057f..3678c8e1c1 100644..100755
--- a/indra/llcommon/llstat.cpp
+++ b/indra/llcommon/llstat.cpp
@@ -37,849 +37,70 @@
// statics
-S32 LLPerfBlock::sStatsFlags = LLPerfBlock::LLSTATS_NO_OPTIONAL_STATS; // Control what is being recorded
-LLPerfBlock::stat_map_t LLPerfBlock::sStatMap; // Map full path string to LLStatTime objects, tracks all active objects
-std::string LLPerfBlock::sCurrentStatPath = ""; // Something like "/total_time/physics/physics step"
-LLStat::stat_map_t LLStat::sStatList;
-
-//------------------------------------------------------------------------
-// Live config file to trigger stats logging
-static const char STATS_CONFIG_FILE_NAME[] = "/dev/shm/simperf/simperf_proc_config.llsd";
-static const F32 STATS_CONFIG_REFRESH_RATE = 5.0; // seconds
-
-class LLStatsConfigFile : public LLLiveFile
-{
-public:
- LLStatsConfigFile()
- : LLLiveFile(filename(), STATS_CONFIG_REFRESH_RATE),
- mChanged(false), mStatsp(NULL) { }
-
- static std::string filename();
-
-protected:
- /* virtual */ bool loadFile();
-
-public:
- void init(LLPerfStats* statsp);
- static LLStatsConfigFile& instance();
- // return the singleton stats config file
-
- bool mChanged;
-
-protected:
- LLPerfStats* mStatsp;
-};
-
-std::string LLStatsConfigFile::filename()
-{
- return STATS_CONFIG_FILE_NAME;
-}
-
-void LLStatsConfigFile::init(LLPerfStats* statsp)
-{
- mStatsp = statsp;
-}
-
-LLStatsConfigFile& LLStatsConfigFile::instance()
-{
- static LLStatsConfigFile the_file;
- return the_file;
-}
-
-
-/* virtual */
-// Load and parse the stats configuration file
-bool LLStatsConfigFile::loadFile()
-{
- if (!mStatsp)
- {
- llwarns << "Tries to load performance configure file without initializing LPerfStats" << llendl;
- return false;
- }
- mChanged = true;
-
- LLSD stats_config;
- {
- llifstream file(filename().c_str());
- if (file.is_open())
- {
- LLSDSerialize::fromXML(stats_config, file);
- if (stats_config.isUndefined())
- {
- llinfos << "Performance statistics configuration file ill-formed, not recording statistics" << llendl;
- mStatsp->setReportPerformanceDuration( 0.f );
- return false;
- }
- }
- else
- { // File went away, turn off stats if it was on
- if ( mStatsp->frameStatsIsRunning() )
- {
- llinfos << "Performance statistics configuration file deleted, not recording statistics" << llendl;
- mStatsp->setReportPerformanceDuration( 0.f );
- }
- return true;
- }
- }
-
- F32 duration = 0.f;
- F32 interval = 0.f;
- S32 flags = LLPerfBlock::LLSTATS_BASIC_STATS;
-
- const char * w = "duration";
- if (stats_config.has(w))
- {
- duration = (F32)stats_config[w].asReal();
- }
- w = "interval";
- if (stats_config.has(w))
- {
- interval = (F32)stats_config[w].asReal();
- }
- w = "flags";
- if (stats_config.has(w))
- {
- flags = (S32)stats_config[w].asInteger();
- if (flags == LLPerfBlock::LLSTATS_NO_OPTIONAL_STATS &&
- duration > 0)
- { // No flags passed in, but have a duration, so reset to basic stats
- flags = LLPerfBlock::LLSTATS_BASIC_STATS;
- }
- }
-
- mStatsp->setReportPerformanceDuration( duration, flags );
- mStatsp->setReportPerformanceInterval( interval );
-
- if ( duration > 0 )
- {
- if ( interval == 0.f )
- {
- llinfos << "Recording performance stats every frame for " << duration << " sec" << llendl;
- }
- else
- {
- llinfos << "Recording performance stats every " << interval << " seconds for " << duration << " seconds" << llendl;
- }
- }
- else
- {
- llinfos << "Performance stats recording turned off" << llendl;
- }
- return true;
-}
-
-
//------------------------------------------------------------------------
-
-LLPerfStats::LLPerfStats(const std::string& process_name, S32 process_pid) :
- mFrameStatsFileFailure(FALSE),
- mSkipFirstFrameStats(FALSE),
- mProcessName(process_name),
- mProcessPID(process_pid),
- mReportPerformanceStatInterval(1.f),
- mReportPerformanceStatEnd(0.0)
-{ }
-
-LLPerfStats::~LLPerfStats()
-{
- LLPerfBlock::clearDynamicStats();
- mFrameStatsFile.close();
-}
-
-void LLPerfStats::init()
-{
- // Initialize the stats config file instance.
- (void) LLStatsConfigFile::instance().init(this);
- (void) LLStatsConfigFile::instance().checkAndReload();
-}
-
-// Open file for statistics
-void LLPerfStats::openPerfStatsFile()
-{
- if ( !mFrameStatsFile
- && !mFrameStatsFileFailure )
- {
- std::string stats_file = llformat("/dev/shm/simperf/%s_proc.%d.llsd", mProcessName.c_str(), mProcessPID);
- mFrameStatsFile.close();
- mFrameStatsFile.clear();
- mFrameStatsFile.open(stats_file, llofstream::out);
- if ( mFrameStatsFile.fail() )
- {
- llinfos << "Error opening statistics log file " << stats_file << llendl;
- mFrameStatsFileFailure = TRUE;
- }
- else
- {
- LLSD process_info = LLSD::emptyMap();
- process_info["name"] = mProcessName;
- process_info["pid"] = (LLSD::Integer) mProcessPID;
- process_info["stat_rate"] = (LLSD::Integer) mReportPerformanceStatInterval;
- // Add process-specific info.
- addProcessHeaderInfo(process_info);
-
- mFrameStatsFile << LLSDNotationStreamer(process_info) << std::endl;
- }
- }
-}
-
-// Dump out performance metrics over some time interval
-void LLPerfStats::dumpIntervalPerformanceStats()
-{
- // Ensure output file is OK
- openPerfStatsFile();
-
- if ( mFrameStatsFile )
- {
- LLSD stats = LLSD::emptyMap();
-
- LLStatAccum::TimeScale scale;
- if ( getReportPerformanceInterval() == 0.f )
- {
- scale = LLStatAccum::SCALE_PER_FRAME;
- }
- else if ( getReportPerformanceInterval() < 0.5f )
- {
- scale = LLStatAccum::SCALE_100MS;
- }
- else
- {
- scale = LLStatAccum::SCALE_SECOND;
- }
-
- // Write LLSD into log
- stats["utc_time"] = (LLSD::String) LLError::utcTime();
- stats["timestamp"] = U64_to_str((totalTime() / 1000) + (gUTCOffset * 1000)); // milliseconds since epoch
- stats["frame_number"] = (LLSD::Integer) LLFrameTimer::getFrameCount();
-
- // Add process-specific frame info.
- addProcessFrameInfo(stats, scale);
- LLPerfBlock::addStatsToLLSDandReset( stats, scale );
-
- mFrameStatsFile << LLSDNotationStreamer(stats) << std::endl;
- }
-}
-
-// Set length of performance stat recording.
-// If turning stats on, caller must provide flags
-void LLPerfStats::setReportPerformanceDuration( F32 seconds, S32 flags /* = LLSTATS_NO_OPTIONAL_STATS */ )
-{
- if ( seconds <= 0.f )
- {
- mReportPerformanceStatEnd = 0.0;
- LLPerfBlock::setStatsFlags(LLPerfBlock::LLSTATS_NO_OPTIONAL_STATS); // Make sure all recording is off
- mFrameStatsFile.close();
- LLPerfBlock::clearDynamicStats();
- }
- else
- {
- mReportPerformanceStatEnd = LLFrameTimer::getElapsedSeconds() + ((F64) seconds);
- // Clear failure flag to try and create the log file once
- mFrameStatsFileFailure = FALSE;
- mSkipFirstFrameStats = TRUE; // Skip the first report (at the end of this frame)
- LLPerfBlock::setStatsFlags(flags);
- }
-}
-
-void LLPerfStats::updatePerFrameStats()
-{
- (void) LLStatsConfigFile::instance().checkAndReload();
- static LLFrameTimer performance_stats_timer;
- if ( frameStatsIsRunning() )
- {
- if ( mReportPerformanceStatInterval == 0 )
- { // Record info every frame
- if ( mSkipFirstFrameStats )
- { // Skip the first time - was started this frame
- mSkipFirstFrameStats = FALSE;
- }
- else
- {
- dumpIntervalPerformanceStats();
- }
- }
- else
- {
- performance_stats_timer.setTimerExpirySec( getReportPerformanceInterval() );
- if (performance_stats_timer.checkExpirationAndReset( mReportPerformanceStatInterval ))
- {
- dumpIntervalPerformanceStats();
- }
- }
-
- if ( LLFrameTimer::getElapsedSeconds() > mReportPerformanceStatEnd )
- { // Reached end of time, clear it to stop reporting
- setReportPerformanceDuration(0.f); // Don't set mReportPerformanceStatEnd directly
- llinfos << "Recording performance stats completed" << llendl;
- }
- }
-}
-
-
-//------------------------------------------------------------------------
-
-U64 LLStatAccum::sScaleTimes[NUM_SCALES] =
-{
- USEC_PER_SEC / 10, // 100 millisec
- USEC_PER_SEC * 1, // seconds
- USEC_PER_SEC * 60, // minutes
-#if ENABLE_LONG_TIME_STATS
- // enable these when more time scales are desired
- USEC_PER_SEC * 60*60, // hours
- USEC_PER_SEC * 24*60*60, // days
- USEC_PER_SEC * 7*24*60*60, // weeks
-#endif
-};
-
-
-
-LLStatAccum::LLStatAccum(bool useFrameTimer)
- : mUseFrameTimer(useFrameTimer),
- mRunning(FALSE),
- mLastTime(0),
- mLastSampleValue(0.0),
- mLastSampleValid(FALSE)
-{
-}
-
-LLStatAccum::~LLStatAccum()
-{
-}
-
-
-
-void LLStatAccum::reset(U64 when)
-{
- mRunning = TRUE;
- mLastTime = when;
-
- for (int i = 0; i < NUM_SCALES; ++i)
- {
- mBuckets[i].accum = 0.0;
- mBuckets[i].endTime = when + sScaleTimes[i];
- mBuckets[i].lastValid = false;
- }
-}
-
-void LLStatAccum::sum(F64 value)
-{
- sum(value, getCurrentUsecs());
-}
-
-void LLStatAccum::sum(F64 value, U64 when)
-{
- if (!mRunning)
- {
- reset(when);
- return;
- }
- if (when < mLastTime)
- {
- // This happens a LOT on some dual core systems.
- lldebugs << "LLStatAccum::sum clock has gone backwards from "
- << mLastTime << " to " << when << ", resetting" << llendl;
-
- reset(when);
- return;
- }
-
- // how long is this value for
- U64 timeSpan = when - mLastTime;
-
- for (int i = 0; i < NUM_SCALES; ++i)
- {
- Bucket& bucket = mBuckets[i];
-
- if (when < bucket.endTime)
- {
- bucket.accum += value;
- }
- else
- {
- U64 timeScale = sScaleTimes[i];
-
- U64 timeLeft = when - bucket.endTime;
- // how much time is left after filling this bucket
-
- if (timeLeft < timeScale)
- {
- F64 valueLeft = value * timeLeft / timeSpan;
-
- bucket.lastValid = true;
- bucket.lastAccum = bucket.accum + (value - valueLeft);
- bucket.accum = valueLeft;
- bucket.endTime += timeScale;
- }
- else
- {
- U64 timeTail = timeLeft % timeScale;
-
- bucket.lastValid = true;
- bucket.lastAccum = value * timeScale / timeSpan;
- bucket.accum = value * timeTail / timeSpan;
- bucket.endTime += (timeLeft - timeTail) + timeScale;
- }
- }
- }
-
- mLastTime = when;
-}
-
-
-F32 LLStatAccum::meanValue(TimeScale scale) const
-{
- if (!mRunning)
- {
- return 0.0;
- }
- if ( scale == SCALE_PER_FRAME )
- { // Per-frame not supported here
- scale = SCALE_100MS;
- }
-
- if (scale < 0 || scale >= NUM_SCALES)
- {
- llwarns << "llStatAccum::meanValue called for unsupported scale: "
- << scale << llendl;
- return 0.0;
- }
-
- const Bucket& bucket = mBuckets[scale];
-
- F64 value = bucket.accum;
- U64 timeLeft = bucket.endTime - mLastTime;
- U64 scaleTime = sScaleTimes[scale];
-
- if (bucket.lastValid)
- {
- value += bucket.lastAccum * timeLeft / scaleTime;
- }
- else if (timeLeft < scaleTime)
- {
- value *= scaleTime / (scaleTime - timeLeft);
- }
- else
- {
- value = 0.0;
- }
-
- return (F32)(value / scaleTime);
-}
-
-
-U64 LLStatAccum::getCurrentUsecs() const
-{
- if (mUseFrameTimer)
- {
- return LLFrameTimer::getTotalTime();
- }
- else
- {
- return totalTime();
- }
-}
-
-
-// ------------------------------------------------------------------------
-
-LLStatRate::LLStatRate(bool use_frame_timer)
- : LLStatAccum(use_frame_timer)
-{
-}
-
-void LLStatRate::count(U32 value)
-{
- sum((F64)value * sScaleTimes[SCALE_SECOND]);
-}
-
-
-void LLStatRate::mark()
- {
- // Effectively the same as count(1), but sets mLastSampleValue
- U64 when = getCurrentUsecs();
-
- if ( mRunning
- && (when > mLastTime) )
- { // Set mLastSampleValue to the time from the last mark()
- F64 duration = ((F64)(when - mLastTime)) / sScaleTimes[SCALE_SECOND];
- if ( duration > 0.0 )
- {
- mLastSampleValue = 1.0 / duration;
- }
- else
- {
- mLastSampleValue = 0.0;
- }
- }
-
- sum( (F64) sScaleTimes[SCALE_SECOND], when);
- }
-
-
-// ------------------------------------------------------------------------
-
-
-LLStatMeasure::LLStatMeasure(bool use_frame_timer)
- : LLStatAccum(use_frame_timer)
-{
-}
-
-void LLStatMeasure::sample(F64 value)
-{
- U64 when = getCurrentUsecs();
-
- if (mLastSampleValid)
- {
- F64 avgValue = (value + mLastSampleValue) / 2.0;
- F64 interval = (F64)(when - mLastTime);
-
- sum(avgValue * interval, when);
- }
- else
- {
- reset(when);
- }
-
- mLastSampleValid = TRUE;
- mLastSampleValue = value;
-}
-
-
-// ------------------------------------------------------------------------
-
-LLStatTime::LLStatTime(const std::string & key)
- : LLStatAccum(false),
- mFrameNumber(LLFrameTimer::getFrameCount()),
- mTotalTimeInFrame(0),
- mKey(key)
-#if LL_DEBUG
- , mRunning(FALSE)
-#endif
-{
-}
-
-void LLStatTime::start()
-{
- // Reset frame accumluation if the frame number has changed
- U32 frame_number = LLFrameTimer::getFrameCount();
- if ( frame_number != mFrameNumber )
- {
- mFrameNumber = frame_number;
- mTotalTimeInFrame = 0;
- }
-
- sum(0.0);
-
-#if LL_DEBUG
- // Shouldn't be running already
- llassert( !mRunning );
- mRunning = TRUE;
-#endif
-}
-
-void LLStatTime::stop()
-{
- U64 end_time = getCurrentUsecs();
- U64 duration = end_time - mLastTime;
- sum(F64(duration), end_time);
- //llinfos << "mTotalTimeInFrame incremented from " << mTotalTimeInFrame << " to " << (mTotalTimeInFrame + duration) << llendl;
- mTotalTimeInFrame += duration;
-
-#if LL_DEBUG
- mRunning = FALSE;
-#endif
-}
-
-/* virtual */ F32 LLStatTime::meanValue(TimeScale scale) const
-{
- if ( LLStatAccum::SCALE_PER_FRAME == scale )
- {
- return (F32)mTotalTimeInFrame;
- }
- else
- {
- return LLStatAccum::meanValue(scale);
- }
-}
-
-
-// ------------------------------------------------------------------------
-
-
-// Use this constructor for pre-defined LLStatTime objects
-LLPerfBlock::LLPerfBlock(LLStatTime* stat ) : mPredefinedStat(stat), mDynamicStat(NULL)
-{
- if (mPredefinedStat)
- {
- // If dynamic stats are turned on, this will create a separate entry in the stat map.
- initDynamicStat(mPredefinedStat->mKey);
-
- // Start predefined stats. These stats are not part of the stat map.
- mPredefinedStat->start();
- }
-}
-
-// Use this constructor for normal, optional LLPerfBlock time slices
-LLPerfBlock::LLPerfBlock( const char* key ) : mPredefinedStat(NULL), mDynamicStat(NULL)
-{
- if ((sStatsFlags & LLSTATS_BASIC_STATS) == 0)
- { // These are off unless the base set is enabled
- return;
- }
-
- initDynamicStat(key);
-}
-
-
-// Use this constructor for dynamically created LLPerfBlock time slices
-// that are only enabled by specific control flags
-LLPerfBlock::LLPerfBlock( const char* key1, const char* key2, S32 flags ) : mPredefinedStat(NULL), mDynamicStat(NULL)
-{
- if ((sStatsFlags & flags) == 0)
- {
- return;
- }
-
- if (NULL == key2 || strlen(key2) == 0)
- {
- initDynamicStat(key1);
- }
- else
- {
- std::ostringstream key;
- key << key1 << "_" << key2;
- initDynamicStat(key.str());
- }
-}
-
-// Set up the result data map if dynamic stats are enabled
-void LLPerfBlock::initDynamicStat(const std::string& key)
-{
- // Early exit if dynamic stats aren't enabled.
- if (sStatsFlags == LLSTATS_NO_OPTIONAL_STATS)
- return;
-
- mLastPath = sCurrentStatPath; // Save and restore current path
- sCurrentStatPath += "/" + key; // Add key to current path
-
- // See if the LLStatTime object already exists
- stat_map_t::iterator iter = sStatMap.find(sCurrentStatPath);
- if ( iter == sStatMap.end() )
- {
- // StatEntry object doesn't exist, so create it
- mDynamicStat = new StatEntry( key );
- sStatMap[ sCurrentStatPath ] = mDynamicStat; // Set the entry for this path
- }
- else
- {
- // Found this path in the map, use the object there
- mDynamicStat = (*iter).second; // Get StatEntry for the current path
- }
-
- if (mDynamicStat)
- {
- mDynamicStat->mStat.start();
- mDynamicStat->mCount++;
- }
- else
- {
- llwarns << "Initialized NULL dynamic stat at '" << sCurrentStatPath << "'" << llendl;
- sCurrentStatPath = mLastPath;
- }
-}
-
-
-// Destructor does the time accounting
-LLPerfBlock::~LLPerfBlock()
-{
- if (mPredefinedStat) mPredefinedStat->stop();
- if (mDynamicStat)
- {
- mDynamicStat->mStat.stop();
- sCurrentStatPath = mLastPath; // Restore the path in case sStatsEnabled changed during this block
- }
-}
-
-
-// Clear the map of any dynamic stats. Static routine
-void LLPerfBlock::clearDynamicStats()
-{
- std::for_each(sStatMap.begin(), sStatMap.end(), DeletePairedPointer());
- sStatMap.clear();
-}
-
-// static - Extract the stat info into LLSD
-void LLPerfBlock::addStatsToLLSDandReset( LLSD & stats,
- LLStatAccum::TimeScale scale )
-{
- // If we aren't in per-frame scale, we need to go from second to microsecond.
- U32 scale_adjustment = 1;
- if (LLStatAccum::SCALE_PER_FRAME != scale)
- {
- scale_adjustment = USEC_PER_SEC;
- }
- stat_map_t::iterator iter = sStatMap.begin();
- for ( ; iter != sStatMap.end(); ++iter )
- { // Put the entry into LLSD "/full/path/to/stat/" = microsecond total time
- const std::string & stats_full_path = (*iter).first;
-
- StatEntry * stat = (*iter).second;
- if (stat)
- {
- if (stat->mCount > 0)
- {
- stats[stats_full_path] = LLSD::emptyMap();
- stats[stats_full_path]["us"] = (LLSD::Integer) (scale_adjustment * stat->mStat.meanValue(scale));
- if (stat->mCount > 1)
- {
- stats[stats_full_path]["count"] = (LLSD::Integer) stat->mCount;
- }
- stat->mCount = 0;
- }
- }
- else
- { // Shouldn't have a NULL pointer in the map.
- llwarns << "Unexpected NULL dynamic stat at '" << stats_full_path << "'" << llendl;
- }
- }
-}
-
-
-// ------------------------------------------------------------------------
-
LLTimer LLStat::sTimer;
LLFrameTimer LLStat::sFrameTimer;
-void LLStat::init()
+void LLStat::reset()
{
- llassert(mNumBins > 0);
mNumValues = 0;
mLastValue = 0.f;
- mLastTime = 0.f;
- mCurBin = (mNumBins-1);
+ delete[] mBins;
+ mBins = new ValueEntry[mNumBins];
+ mCurBin = mNumBins-1;
mNextBin = 0;
- mBins = new F32[mNumBins];
- mBeginTime = new F64[mNumBins];
- mTime = new F64[mNumBins];
- mDT = new F32[mNumBins];
- for (U32 i = 0; i < mNumBins; i++)
- {
- mBins[i] = 0.f;
- mBeginTime[i] = 0.0;
- mTime[i] = 0.0;
- mDT[i] = 0.f;
- }
+}
+
+LLStat::LLStat(std::string name, S32 num_bins, BOOL use_frame_timer)
+: mUseFrameTimer(use_frame_timer),
+ mNumBins(num_bins),
+ mName(name),
+ mBins(NULL)
+{
+ llassert(mNumBins > 0);
+ mLastTime = 0.f;
+
+ reset();
if (!mName.empty())
{
- stat_map_t::iterator iter = sStatList.find(mName);
- if (iter != sStatList.end())
+ stat_map_t::iterator iter = getStatList().find(mName);
+ if (iter != getStatList().end())
llwarns << "LLStat with duplicate name: " << mName << llendl;
- sStatList.insert(std::make_pair(mName, this));
+ getStatList().insert(std::make_pair(mName, this));
}
}
-LLStat::LLStat(const U32 num_bins, const BOOL use_frame_timer)
- : mUseFrameTimer(use_frame_timer),
- mNumBins(num_bins)
+LLStat::stat_map_t& LLStat::getStatList()
{
- init();
+ static LLStat::stat_map_t stat_list;
+ return stat_list;
}
-LLStat::LLStat(std::string name, U32 num_bins, BOOL use_frame_timer)
- : mUseFrameTimer(use_frame_timer),
- mNumBins(num_bins),
- mName(name)
-{
- init();
-}
LLStat::~LLStat()
{
delete[] mBins;
- delete[] mBeginTime;
- delete[] mTime;
- delete[] mDT;
if (!mName.empty())
{
// handle multiple entries with the same name
- stat_map_t::iterator iter = sStatList.find(mName);
- while (iter != sStatList.end() && iter->second != this)
+ stat_map_t::iterator iter = getStatList().find(mName);
+ while (iter != getStatList().end() && iter->second != this)
++iter;
- sStatList.erase(iter);
+ getStatList().erase(iter);
}
}
-void LLStat::reset()
-{
- U32 i;
-
- mNumValues = 0;
- mLastValue = 0.f;
- mCurBin = (mNumBins-1);
- delete[] mBins;
- delete[] mBeginTime;
- delete[] mTime;
- delete[] mDT;
- mBins = new F32[mNumBins];
- mBeginTime = new F64[mNumBins];
- mTime = new F64[mNumBins];
- mDT = new F32[mNumBins];
- for (i = 0; i < mNumBins; i++)
- {
- mBins[i] = 0.f;
- mBeginTime[i] = 0.0;
- mTime[i] = 0.0;
- mDT[i] = 0.f;
- }
-}
-
-void LLStat::setBeginTime(const F64 time)
-{
- mBeginTime[mNextBin] = time;
-}
-
-void LLStat::addValueTime(const F64 time, const F32 value)
-{
- if (mNumValues < mNumBins)
- {
- mNumValues++;
- }
-
- // Increment the bin counters.
- mCurBin++;
- if ((U32)mCurBin == mNumBins)
- {
- mCurBin = 0;
- }
- mNextBin++;
- if ((U32)mNextBin == mNumBins)
- {
- mNextBin = 0;
- }
-
- mBins[mCurBin] = value;
- mTime[mCurBin] = time;
- mDT[mCurBin] = (F32)(mTime[mCurBin] - mBeginTime[mCurBin]);
- //this value is used to prime the min/max calls
- mLastTime = mTime[mCurBin];
- mLastValue = value;
-
- // Set the begin time for the next stat segment.
- mBeginTime[mNextBin] = mTime[mCurBin];
- mTime[mNextBin] = mTime[mCurBin];
- mDT[mNextBin] = 0.f;
-}
-
void LLStat::start()
{
if (mUseFrameTimer)
{
- mBeginTime[mNextBin] = sFrameTimer.getElapsedSeconds();
+ mBins[mNextBin].mBeginTime = sFrameTimer.getElapsedSeconds();
}
else
{
- mBeginTime[mNextBin] = sTimer.getElapsedTimeF64();
+ mBins[mNextBin].mBeginTime = sTimer.getElapsedTimeF64();
}
}
@@ -892,41 +113,41 @@ void LLStat::addValue(const F32 value)
// Increment the bin counters.
mCurBin++;
- if ((U32)mCurBin == mNumBins)
+ if (mCurBin >= mNumBins)
{
mCurBin = 0;
}
mNextBin++;
- if ((U32)mNextBin == mNumBins)
+ if (mNextBin >= mNumBins)
{
mNextBin = 0;
}
- mBins[mCurBin] = value;
+ mBins[mCurBin].mValue = value;
if (mUseFrameTimer)
{
- mTime[mCurBin] = sFrameTimer.getElapsedSeconds();
+ mBins[mCurBin].mTime = sFrameTimer.getElapsedSeconds();
}
else
{
- mTime[mCurBin] = sTimer.getElapsedTimeF64();
+ mBins[mCurBin].mTime = sTimer.getElapsedTimeF64();
}
- mDT[mCurBin] = (F32)(mTime[mCurBin] - mBeginTime[mCurBin]);
+ mBins[mCurBin].mDT = (F32)(mBins[mCurBin].mTime - mBins[mCurBin].mBeginTime);
//this value is used to prime the min/max calls
- mLastTime = mTime[mCurBin];
+ mLastTime = mBins[mCurBin].mTime;
mLastValue = value;
// Set the begin time for the next stat segment.
- mBeginTime[mNextBin] = mTime[mCurBin];
- mTime[mNextBin] = mTime[mCurBin];
- mDT[mNextBin] = 0.f;
+ mBins[mNextBin].mBeginTime = mBins[mCurBin].mTime;
+ mBins[mNextBin].mTime = mBins[mCurBin].mTime;
+ mBins[mNextBin].mDT = 0.f;
}
F32 LLStat::getMax() const
{
- U32 i;
+ S32 i;
F32 current_max = mLastValue;
if (mNumBins == 0)
{
@@ -937,13 +158,13 @@ F32 LLStat::getMax() const
for (i = 0; (i < mNumBins) && (i < mNumValues); i++)
{
// Skip the bin we're currently filling.
- if (i == (U32)mNextBin)
+ if (i == mNextBin)
{
continue;
}
- if (mBins[i] > current_max)
+ if (mBins[i].mValue > current_max)
{
- current_max = mBins[i];
+ current_max = mBins[i].mValue;
}
}
}
@@ -952,17 +173,17 @@ F32 LLStat::getMax() const
F32 LLStat::getMean() const
{
- U32 i;
+ S32 i;
F32 current_mean = 0.f;
- U32 samples = 0;
+ S32 samples = 0;
for (i = 0; (i < mNumBins) && (i < mNumValues); i++)
{
// Skip the bin we're currently filling.
- if (i == (U32)mNextBin)
+ if (i == mNextBin)
{
continue;
}
- current_mean += mBins[i];
+ current_mean += mBins[i].mValue;
samples++;
}
@@ -980,7 +201,7 @@ F32 LLStat::getMean() const
F32 LLStat::getMin() const
{
- U32 i;
+ S32 i;
F32 current_min = mLastValue;
if (mNumBins == 0)
@@ -992,53 +213,19 @@ F32 LLStat::getMin() const
for (i = 0; (i < mNumBins) && (i < mNumValues); i++)
{
// Skip the bin we're currently filling.
- if (i == (U32)mNextBin)
+ if (i == mNextBin)
{
continue;
}
- if (mBins[i] < current_min)
+ if (mBins[i].mValue < current_min)
{
- current_min = mBins[i];
+ current_min = mBins[i].mValue;
}
}
}
return current_min;
}
-F32 LLStat::getSum() const
-{
- U32 i;
- F32 sum = 0.f;
- for (i = 0; (i < mNumBins) && (i < mNumValues); i++)
- {
- // Skip the bin we're currently filling.
- if (i == (U32)mNextBin)
- {
- continue;
- }
- sum += mBins[i];
- }
-
- return sum;
-}
-
-F32 LLStat::getSumDuration() const
-{
- U32 i;
- F32 sum = 0.f;
- for (i = 0; (i < mNumBins) && (i < mNumValues); i++)
- {
- // Skip the bin we're currently filling.
- if (i == (U32)mNextBin)
- {
- continue;
- }
- sum += mDT[i];
- }
-
- return sum;
-}
-
F32 LLStat::getPrev(S32 age) const
{
S32 bin;
@@ -1054,7 +241,7 @@ F32 LLStat::getPrev(S32 age) const
// Bogus for bin we're currently working on.
return 0.f;
}
- return mBins[bin];
+ return mBins[bin].mValue;
}
F32 LLStat::getPrevPerSec(S32 age) const
@@ -1072,107 +259,34 @@ F32 LLStat::getPrevPerSec(S32 age) const
// Bogus for bin we're currently working on.
return 0.f;
}
- return mBins[bin] / mDT[bin];
-}
-
-F64 LLStat::getPrevBeginTime(S32 age) const
-{
- S32 bin;
- bin = mCurBin - age;
-
- while (bin < 0)
- {
- bin += mNumBins;
- }
-
- if (bin == mNextBin)
- {
- // Bogus for bin we're currently working on.
- return 0.f;
- }
-
- return mBeginTime[bin];
-}
-
-F64 LLStat::getPrevTime(S32 age) const
-{
- S32 bin;
- bin = mCurBin - age;
-
- while (bin < 0)
- {
- bin += mNumBins;
- }
-
- if (bin == mNextBin)
- {
- // Bogus for bin we're currently working on.
- return 0.f;
- }
-
- return mTime[bin];
-}
-
-F32 LLStat::getBin(S32 bin) const
-{
- return mBins[bin];
-}
-
-F32 LLStat::getBinPerSec(S32 bin) const
-{
- return mBins[bin] / mDT[bin];
-}
-
-F64 LLStat::getBinBeginTime(S32 bin) const
-{
- return mBeginTime[bin];
-}
-
-F64 LLStat::getBinTime(S32 bin) const
-{
- return mTime[bin];
+ return mBins[bin].mValue / mBins[bin].mDT;
}
F32 LLStat::getCurrent() const
{
- return mBins[mCurBin];
+ return mBins[mCurBin].mValue;
}
F32 LLStat::getCurrentPerSec() const
{
- return mBins[mCurBin] / mDT[mCurBin];
-}
-
-F64 LLStat::getCurrentBeginTime() const
-{
- return mBeginTime[mCurBin];
-}
-
-F64 LLStat::getCurrentTime() const
-{
- return mTime[mCurBin];
-}
-
-F32 LLStat::getCurrentDuration() const
-{
- return mDT[mCurBin];
+ return mBins[mCurBin].mValue / mBins[mCurBin].mDT;
}
F32 LLStat::getMeanPerSec() const
{
- U32 i;
+ S32 i;
F32 value = 0.f;
F32 dt = 0.f;
for (i = 0; (i < mNumBins) && (i < mNumValues); i++)
{
// Skip the bin we're currently filling.
- if (i == (U32)mNextBin)
+ if (i == mNextBin)
{
continue;
}
- value += mBins[i];
- dt += mDT[i];
+ value += mBins[i].mValue;
+ dt += mBins[i].mDT;
}
if (dt > 0.f)
@@ -1188,14 +302,14 @@ F32 LLStat::getMeanPerSec() const
F32 LLStat::getMeanDuration() const
{
F32 dur = 0.0f;
- U32 count = 0;
- for (U32 i=0; (i < mNumBins) && (i < mNumValues); i++)
+ S32 count = 0;
+ for (S32 i=0; (i < mNumBins) && (i < mNumValues); i++)
{
- if (i == (U32)mNextBin)
+ if (i == mNextBin)
{
continue;
}
- dur += mDT[i];
+ dur += mBins[i].mDT;
count++;
}
@@ -1212,46 +326,45 @@ F32 LLStat::getMeanDuration() const
F32 LLStat::getMaxPerSec() const
{
- U32 i;
F32 value;
if (mNextBin != 0)
{
- value = mBins[0]/mDT[0];
+ value = mBins[0].mValue/mBins[0].mDT;
}
else if (mNumValues > 0)
{
- value = mBins[1]/mDT[1];
+ value = mBins[1].mValue/mBins[1].mDT;
}
else
{
value = 0.f;
}
- for (i = 0; (i < mNumBins) && (i < mNumValues); i++)
+ for (S32 i = 0; (i < mNumBins) && (i < mNumValues); i++)
{
// Skip the bin we're currently filling.
- if (i == (U32)mNextBin)
+ if (i == mNextBin)
{
continue;
}
- value = llmax(value, mBins[i]/mDT[i]);
+ value = llmax(value, mBins[i].mValue/mBins[i].mDT);
}
return value;
}
F32 LLStat::getMinPerSec() const
{
- U32 i;
+ S32 i;
F32 value;
if (mNextBin != 0)
{
- value = mBins[0]/mDT[0];
+ value = mBins[0].mValue/mBins[0].mDT;
}
else if (mNumValues > 0)
{
- value = mBins[1]/mDT[1];
+ value = mBins[1].mValue/mBins[0].mDT;
}
else
{
@@ -1261,25 +374,15 @@ F32 LLStat::getMinPerSec() const
for (i = 0; (i < mNumBins) && (i < mNumValues); i++)
{
// Skip the bin we're currently filling.
- if (i == (U32)mNextBin)
+ if (i == mNextBin)
{
continue;
}
- value = llmin(value, mBins[i]/mDT[i]);
+ value = llmin(value, mBins[i].mValue/mBins[i].mDT);
}
return value;
}
-F32 LLStat::getMinDuration() const
-{
- F32 dur = 0.0f;
- for (U32 i=0; (i < mNumBins) && (i < mNumValues); i++)
- {
- dur = llmin(dur, mDT[i]);
- }
- return dur;
-}
-
U32 LLStat::getNumValues() const
{
return mNumValues;
@@ -1290,11 +393,6 @@ S32 LLStat::getNumBins() const
return mNumBins;
}
-S32 LLStat::getCurBin() const
-{
- return mCurBin;
-}
-
S32 LLStat::getNextBin() const
{
return mNextBin;
diff --git a/indra/llcommon/llstat.h b/indra/llcommon/llstat.h
index b877432e86..38377a010b 100644..100755
--- a/indra/llcommon/llstat.h
+++ b/indra/llcommon/llstat.h
@@ -27,294 +27,46 @@
#ifndef LL_LLSTAT_H
#define LL_LLSTAT_H
-#include <deque>
#include <map>
#include "lltimer.h"
#include "llframetimer.h"
-#include "llfile.h"
class LLSD;
-// Set this if longer stats are needed
-#define ENABLE_LONG_TIME_STATS 0
-
-//
-// Accumulates statistics for an arbitrary length of time.
-// Does this by maintaining a chain of accumulators, each one
-// accumulation the results of the parent. Can scale to arbitrary
-// amounts of time with very low memory cost.
-//
-
-class LL_COMMON_API LLStatAccum
-{
-protected:
- LLStatAccum(bool use_frame_timer);
- virtual ~LLStatAccum();
-
-public:
- enum TimeScale {
- SCALE_100MS,
- SCALE_SECOND,
- SCALE_MINUTE,
-#if ENABLE_LONG_TIME_STATS
- SCALE_HOUR,
- SCALE_DAY,
- SCALE_WEEK,
-#endif
- NUM_SCALES, // Use to size storage arrays
- SCALE_PER_FRAME // For latest frame information - should be after NUM_SCALES since this doesn't go into the time buckets
- };
-
- static U64 sScaleTimes[NUM_SCALES];
-
- virtual F32 meanValue(TimeScale scale) const;
- // see the subclasses for the specific meaning of value
-
- F32 meanValueOverLast100ms() const { return meanValue(SCALE_100MS); }
- F32 meanValueOverLastSecond() const { return meanValue(SCALE_SECOND); }
- F32 meanValueOverLastMinute() const { return meanValue(SCALE_MINUTE); }
-
- void reset(U64 when);
-
- void sum(F64 value);
- void sum(F64 value, U64 when);
-
- U64 getCurrentUsecs() const;
- // Get current microseconds based on timer type
-
- BOOL mUseFrameTimer;
- BOOL mRunning;
-
- U64 mLastTime;
-
- struct Bucket
- {
- Bucket() :
- accum(0.0),
- endTime(0),
- lastValid(false),
- lastAccum(0.0)
- {}
-
- F64 accum;
- U64 endTime;
-
- bool lastValid;
- F64 lastAccum;
- };
-
- Bucket mBuckets[NUM_SCALES];
-
- BOOL mLastSampleValid;
- F64 mLastSampleValue;
-};
-
-class LL_COMMON_API LLStatMeasure : public LLStatAccum
- // gathers statistics about things that are measured
- // ex.: tempature, time dilation
-{
-public:
- LLStatMeasure(bool use_frame_timer = true);
-
- void sample(F64);
- void sample(S32 v) { sample((F64)v); }
- void sample(U32 v) { sample((F64)v); }
- void sample(S64 v) { sample((F64)v); }
- void sample(U64 v) { sample((F64)v); }
-};
-
-
-class LL_COMMON_API LLStatRate : public LLStatAccum
- // gathers statistics about things that can be counted over time
- // ex.: LSL instructions executed, messages sent, simulator frames completed
- // renders it in terms of rate of thing per second
-{
-public:
- LLStatRate(bool use_frame_timer = true);
-
- void count(U32);
- // used to note that n items have occured
-
- void mark();
- // used for counting the rate thorugh a point in the code
-};
-
-
-class LL_COMMON_API LLStatTime : public LLStatAccum
- // gathers statistics about time spent in a block of code
- // measure average duration per second in the block
-{
-public:
- LLStatTime( const std::string & key = "undefined" );
-
- U32 mFrameNumber; // Current frame number
- U64 mTotalTimeInFrame; // Total time (microseconds) accumulated during the last frame
-
- void setKey( const std::string & key ) { mKey = key; };
-
- virtual F32 meanValue(TimeScale scale) const;
-
-private:
- void start(); // Start and stop measuring time block
- void stop();
-
- std::string mKey; // Tag representing this time block
-
-#if LL_DEBUG
- BOOL mRunning; // TRUE if start() has been called
-#endif
-
- friend class LLPerfBlock;
-};
-
-// ----------------------------------------------------------------------------
-
-
-// Use this class on the stack to record statistics about an area of code
-class LL_COMMON_API LLPerfBlock
-{
-public:
- struct StatEntry
- {
- StatEntry(const std::string& key) : mStat(LLStatTime(key)), mCount(0) {}
- LLStatTime mStat;
- U32 mCount;
- };
- typedef std::map<std::string, StatEntry*> stat_map_t;
-
- // Use this constructor for pre-defined LLStatTime objects
- LLPerfBlock(LLStatTime* stat);
-
- // Use this constructor for normal, optional LLPerfBlock time slices
- LLPerfBlock( const char* key );
-
- // Use this constructor for dynamically created LLPerfBlock time slices
- // that are only enabled by specific control flags
- LLPerfBlock( const char* key1, const char* key2, S32 flags = LLSTATS_BASIC_STATS );
-
- ~LLPerfBlock();
-
- enum
- { // Stats bitfield flags
- LLSTATS_NO_OPTIONAL_STATS = 0x00, // No optional stats gathering, just pre-defined LLStatTime objects
- LLSTATS_BASIC_STATS = 0x01, // Gather basic optional runtime stats
- LLSTATS_SCRIPT_FUNCTIONS = 0x02, // Include LSL function calls
- };
- static void setStatsFlags( S32 flags ) { sStatsFlags = flags; };
- static S32 getStatsFlags() { return sStatsFlags; };
-
- static void clearDynamicStats(); // Reset maps to clear out dynamic objects
- static void addStatsToLLSDandReset( LLSD & stats, // Get current information and clear time bin
- LLStatAccum::TimeScale scale );
-
-private:
- // Initialize dynamically created LLStatTime objects
- void initDynamicStat(const std::string& key);
-
- std::string mLastPath; // Save sCurrentStatPath when this is called
- LLStatTime * mPredefinedStat; // LLStatTime object to get data
- StatEntry * mDynamicStat; // StatEntryobject to get data
-
- static S32 sStatsFlags; // Control what is being recorded
- static stat_map_t sStatMap; // Map full path string to LLStatTime objects
- static std::string sCurrentStatPath; // Something like "frame/physics/physics step"
-};
-
-// ----------------------------------------------------------------------------
-
-class LL_COMMON_API LLPerfStats
-{
-public:
- LLPerfStats(const std::string& process_name = "unknown", S32 process_pid = 0);
- virtual ~LLPerfStats();
-
- virtual void init(); // Reset and start all stat timers
- virtual void updatePerFrameStats();
- // Override these function to add process-specific information to the performance log header and per-frame logging.
- virtual void addProcessHeaderInfo(LLSD& info) { /* not implemented */ }
- virtual void addProcessFrameInfo(LLSD& info, LLStatAccum::TimeScale scale) { /* not implemented */ }
-
- // High-resolution frame stats
- BOOL frameStatsIsRunning() { return (mReportPerformanceStatEnd > 0.); };
- F32 getReportPerformanceInterval() const { return mReportPerformanceStatInterval; };
- void setReportPerformanceInterval( F32 interval ) { mReportPerformanceStatInterval = interval; };
- void setReportPerformanceDuration( F32 seconds, S32 flags = LLPerfBlock::LLSTATS_NO_OPTIONAL_STATS );
- void setProcessName(const std::string& process_name) { mProcessName = process_name; }
- void setProcessPID(S32 process_pid) { mProcessPID = process_pid; }
-
-protected:
- void openPerfStatsFile(); // Open file for high resolution metrics logging
- void dumpIntervalPerformanceStats();
-
- llofstream mFrameStatsFile; // File for per-frame stats
- BOOL mFrameStatsFileFailure; // Flag to prevent repeat opening attempts
- BOOL mSkipFirstFrameStats; // Flag to skip one (partial) frame report
- std::string mProcessName;
- S32 mProcessPID;
-
-private:
- F32 mReportPerformanceStatInterval; // Seconds between performance stats
- F64 mReportPerformanceStatEnd; // End time (seconds) for performance stats
-};
-
// ----------------------------------------------------------------------------
class LL_COMMON_API LLStat
{
private:
typedef std::multimap<std::string, LLStat*> stat_map_t;
- static stat_map_t sStatList;
- void init();
+ static stat_map_t& getStatList();
public:
- LLStat(U32 num_bins = 32, BOOL use_frame_timer = FALSE);
- LLStat(std::string name, U32 num_bins = 32, BOOL use_frame_timer = FALSE);
+ LLStat(std::string name = std::string(), S32 num_bins = 32, BOOL use_frame_timer = FALSE);
~LLStat();
- void reset();
-
void start(); // Start the timer for the current "frame", otherwise uses the time tracked from
// the last addValue
+ void reset();
void addValue(const F32 value = 1.f); // Adds the current value being tracked, and tracks the DT.
void addValue(const S32 value) { addValue((F32)value); }
void addValue(const U32 value) { addValue((F32)value); }
- void setBeginTime(const F64 time);
- void addValueTime(const F64 time, const F32 value = 1.f);
-
- S32 getCurBin() const;
S32 getNextBin() const;
- F32 getCurrent() const;
- F32 getCurrentPerSec() const;
- F64 getCurrentBeginTime() const;
- F64 getCurrentTime() const;
- F32 getCurrentDuration() const;
-
F32 getPrev(S32 age) const; // Age is how many "addValues" previously - zero is current
F32 getPrevPerSec(S32 age) const; // Age is how many "addValues" previously - zero is current
- F64 getPrevBeginTime(S32 age) const;
- F64 getPrevTime(S32 age) const;
-
- F32 getBin(S32 bin) const;
- F32 getBinPerSec(S32 bin) const;
- F64 getBinBeginTime(S32 bin) const;
- F64 getBinTime(S32 bin) const;
-
- F32 getMax() const;
- F32 getMaxPerSec() const;
+ F32 getCurrent() const;
+ F32 getCurrentPerSec() const;
+ F32 getMin() const;
+ F32 getMinPerSec() const;
F32 getMean() const;
F32 getMeanPerSec() const;
F32 getMeanDuration() const;
-
- F32 getMin() const;
- F32 getMinPerSec() const;
- F32 getMinDuration() const;
-
- F32 getSum() const;
- F32 getSumDuration() const;
+ F32 getMax() const;
+ F32 getMaxPerSec() const;
U32 getNumValues() const;
S32 getNumBins() const;
@@ -326,10 +78,21 @@ private:
U32 mNumBins;
F32 mLastValue;
F64 mLastTime;
- F32 *mBins;
- F64 *mBeginTime;
- F64 *mTime;
- F32 *mDT;
+
+ struct ValueEntry
+ {
+ ValueEntry()
+ : mValue(0.f),
+ mBeginTime(0.0),
+ mTime(0.0),
+ mDT(0.f)
+ {}
+ F32 mValue;
+ F64 mBeginTime;
+ F64 mTime;
+ F32 mDT;
+ };
+ ValueEntry* mBins;
S32 mCurBin;
S32 mNextBin;
@@ -342,8 +105,8 @@ public:
static LLStat* getStat(const std::string& name)
{
// return the first stat that matches 'name'
- stat_map_t::iterator iter = sStatList.find(name);
- if (iter != sStatList.end())
+ stat_map_t::iterator iter = getStatList().find(name);
+ if (iter != getStatList().end())
return iter->second;
else
return NULL;
diff --git a/indra/llcommon/llstatenums.h b/indra/llcommon/llstatenums.h
index 9033d8eb43..81c4085d16 100644..100755
--- a/indra/llcommon/llstatenums.h
+++ b/indra/llcommon/llstatenums.h
@@ -28,41 +28,48 @@
enum
{
- LL_SIM_STAT_TIME_DILATION, // 0
- LL_SIM_STAT_FPS,
- LL_SIM_STAT_PHYSFPS,
- LL_SIM_STAT_AGENTUPS,
- LL_SIM_STAT_FRAMEMS,
- LL_SIM_STAT_NETMS, // 5
- LL_SIM_STAT_SIMOTHERMS,
- LL_SIM_STAT_SIMPHYSICSMS,
- LL_SIM_STAT_AGENTMS,
- LL_SIM_STAT_IMAGESMS,
- LL_SIM_STAT_SCRIPTMS, // 10
- LL_SIM_STAT_NUMTASKS,
- LL_SIM_STAT_NUMTASKSACTIVE,
- LL_SIM_STAT_NUMAGENTMAIN,
- LL_SIM_STAT_NUMAGENTCHILD,
- LL_SIM_STAT_NUMSCRIPTSACTIVE, // 15
- LL_SIM_STAT_LSLIPS,
- LL_SIM_STAT_INPPS,
- LL_SIM_STAT_OUTPPS,
- LL_SIM_STAT_PENDING_DOWNLOADS,
- LL_SIM_STAT_PENDING_UPLOADS, // 20
- LL_SIM_STAT_VIRTUAL_SIZE_KB,
- LL_SIM_STAT_RESIDENT_SIZE_KB,
- LL_SIM_STAT_PENDING_LOCAL_UPLOADS,
- LL_SIM_STAT_TOTAL_UNACKED_BYTES,
- LL_SIM_STAT_PHYSICS_PINNED_TASKS, // 25
- LL_SIM_STAT_PHYSICS_LOD_TASKS,
- LL_SIM_STAT_SIMPHYSICSSTEPMS,
- LL_SIM_STAT_SIMPHYSICSSHAPEMS,
- LL_SIM_STAT_SIMPHYSICSOTHERMS,
- LL_SIM_STAT_SIMPHYSICSMEMORY, // 30
- LL_SIM_STAT_SCRIPT_EPS,
- LL_SIM_STAT_SIMSPARETIME,
- LL_SIM_STAT_SIMSLEEPTIME,
- LL_SIM_STAT_IOPUMPTIME,
+ LL_SIM_STAT_TIME_DILATION = 0,
+ LL_SIM_STAT_FPS = 1,
+ LL_SIM_STAT_PHYSFPS = 2,
+ LL_SIM_STAT_AGENTUPS = 3,
+ LL_SIM_STAT_FRAMEMS = 4,
+ LL_SIM_STAT_NETMS = 5,
+ LL_SIM_STAT_SIMOTHERMS = 6,
+ LL_SIM_STAT_SIMPHYSICSMS = 7,
+ LL_SIM_STAT_AGENTMS = 8,
+ LL_SIM_STAT_IMAGESMS = 9,
+ LL_SIM_STAT_SCRIPTMS = 10,
+ LL_SIM_STAT_NUMTASKS = 11,
+ LL_SIM_STAT_NUMTASKSACTIVE = 12,
+ LL_SIM_STAT_NUMAGENTMAIN = 13,
+ LL_SIM_STAT_NUMAGENTCHILD = 14,
+ LL_SIM_STAT_NUMSCRIPTSACTIVE = 15,
+ LL_SIM_STAT_LSLIPS = 16,
+ LL_SIM_STAT_INPPS = 17,
+ LL_SIM_STAT_OUTPPS = 18,
+ LL_SIM_STAT_PENDING_DOWNLOADS = 19,
+ LL_SIM_STAT_PENDING_UPLOADS = 20,
+ LL_SIM_STAT_VIRTUAL_SIZE_KB = 21,
+ LL_SIM_STAT_RESIDENT_SIZE_KB = 22,
+ LL_SIM_STAT_PENDING_LOCAL_UPLOADS = 23,
+ LL_SIM_STAT_TOTAL_UNACKED_BYTES = 24,
+ LL_SIM_STAT_PHYSICS_PINNED_TASKS = 25,
+ LL_SIM_STAT_PHYSICS_LOD_TASKS = 26,
+ LL_SIM_STAT_SIMPHYSICSSTEPMS = 27,
+ LL_SIM_STAT_SIMPHYSICSSHAPEMS = 28,
+ LL_SIM_STAT_SIMPHYSICSOTHERMS = 29,
+ LL_SIM_STAT_SIMPHYSICSMEMORY = 30,
+ LL_SIM_STAT_SCRIPT_EPS = 31,
+ LL_SIM_STAT_SIMSPARETIME = 32,
+ LL_SIM_STAT_SIMSLEEPTIME = 33,
+ LL_SIM_STAT_IOPUMPTIME = 34,
+ LL_SIM_STAT_PCTSCRIPTSRUN = 35,
+ LL_SIM_STAT_REGION_IDLE = 36, // dataserver only
+ LL_SIM_STAT_REGION_IDLE_POSSIBLE = 37, // dataserver only
+ LL_SIM_STAT_SIMAISTEPTIMEMS = 38,
+ LL_SIM_STAT_SKIPPEDAISILSTEPS_PS = 39,
+ LL_SIM_STAT_PCTSTEPPEDCHARACTERS = 40
+
};
#endif
diff --git a/indra/llcommon/llstaticstringtable.h b/indra/llcommon/llstaticstringtable.h
new file mode 100644
index 0000000000..d7e0e8a08d
--- /dev/null
+++ b/indra/llcommon/llstaticstringtable.h
@@ -0,0 +1,82 @@
+/**
+ * @file llstringtable.h
+ * @brief The LLStringTable class provides a _fast_ method for finding
+ * unique copies of strings.
+ *
+ * $LicenseInfo:firstyear=2001&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$
+ */
+
+#ifndef LL_STATIC_STRING_TABLE_H
+#define LL_STATIC_STRING_TABLE_H
+
+#include "lldefs.h"
+#include <boost/unordered_map.hpp>
+#include "llstl.h"
+
+class LLStaticHashedString
+{
+public:
+
+ LLStaticHashedString(const std::string& s)
+ {
+ string_hash = makehash(s);
+ string = s;
+ }
+
+ const std::string& String() const { return string; }
+ size_t Hash() const { return string_hash; }
+
+ bool operator==(const LLStaticHashedString& b) const { return Hash() == b.Hash(); }
+
+protected:
+
+ size_t makehash(const std::string& s)
+ {
+ size_t len = s.size();
+ const char* c = s.c_str();
+ size_t hashval = 0;
+ for (size_t i=0; i<len; i++)
+ {
+ hashval = ((hashval<<5) + hashval) + *c++;
+ }
+ return hashval;
+ }
+
+ std::string string;
+ size_t string_hash;
+};
+
+struct LLStaticStringHasher
+{
+ enum { bucket_size = 8 };
+ size_t operator()(const LLStaticHashedString& key_value) const { return key_value.Hash(); }
+ bool operator()(const LLStaticHashedString& left, const LLStaticHashedString& right) const { return left.Hash() < right.Hash(); }
+};
+
+template< typename MappedObject >
+class LL_COMMON_API LLStaticStringTable
+ : public boost::unordered_map< LLStaticHashedString, MappedObject, LLStaticStringHasher >
+{
+};
+
+#endif
+
diff --git a/indra/llcommon/llstl.h b/indra/llcommon/llstl.h
index 8ad12c9a03..d3941e1bc9 100644..100755
--- a/indra/llcommon/llstl.h
+++ b/indra/llcommon/llstl.h
@@ -33,6 +33,7 @@
#include <vector>
#include <set>
#include <deque>
+#include <typeinfo>
// Use to compare the first element only of a pair
// e.g. typedef std::set<std::pair<int, Data*>, compare_pair<int, Data*> > some_pair_set_t;
@@ -470,4 +471,54 @@ llbind2nd(const _Operation& __oper, const _Tp& __x)
return llbinder2nd<_Operation>(__oper, _Arg2_type(__x));
}
+/**
+ * Compare std::type_info* pointers a la std::less. We break this out as a
+ * separate function for use in two different std::less specializations.
+ */
+inline
+bool before(const std::type_info* lhs, const std::type_info* rhs)
+{
+#if LL_LINUX && defined(__GNUC__) && ((__GNUC__ < 4) || (__GNUC__ == 4 && __GNUC_MINOR__ < 4))
+ // If we're building on Linux with gcc, and it's either gcc 3.x or
+ // 4.{0,1,2,3}, then we have to use a workaround. Note that we use gcc on
+ // Mac too, and some people build with gcc on Windows (cygwin or mingw).
+ // On Linux, different load modules may produce different type_info*
+ // pointers for the same type. Have to compare name strings to get good
+ // results.
+ return strcmp(lhs->name(), rhs->name()) < 0;
+#else // not Linux, or gcc 4.4+
+ // Just use before(), as we normally would
+ return lhs->before(*rhs);
+#endif
+}
+
+/**
+ * Specialize std::less<std::type_info*> to use std::type_info::before().
+ * See MAINT-1175. It is NEVER a good idea to directly compare std::type_info*
+ * because, on Linux, you might get different std::type_info* pointers for the
+ * same type (from different load modules)!
+ */
+namespace std
+{
+ template <>
+ struct less<const std::type_info*>:
+ public std::binary_function<const std::type_info*, const std::type_info*, bool>
+ {
+ bool operator()(const std::type_info* lhs, const std::type_info* rhs) const
+ {
+ return before(lhs, rhs);
+ }
+ };
+
+ template <>
+ struct less<std::type_info*>:
+ public std::binary_function<std::type_info*, std::type_info*, bool>
+ {
+ bool operator()(std::type_info* lhs, std::type_info* rhs) const
+ {
+ return before(lhs, rhs);
+ }
+ };
+} // std
+
#endif // LL_LLSTL_H
diff --git a/indra/llcommon/llstreamqueue.cpp b/indra/llcommon/llstreamqueue.cpp
new file mode 100755
index 0000000000..1116a2b6a2
--- /dev/null
+++ b/indra/llcommon/llstreamqueue.cpp
@@ -0,0 +1,24 @@
+/**
+ * @file llstreamqueue.cpp
+ * @author Nat Goodspeed
+ * @date 2012-01-05
+ * @brief Implementation for llstreamqueue.
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Copyright (c) 2012, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+// Precompiled header
+#include "linden_common.h"
+// associated header
+#include "llstreamqueue.h"
+// STL headers
+// std headers
+// external library headers
+// other Linden headers
+
+// As of this writing, llstreamqueue.h is entirely template-based, therefore
+// we don't strictly need a corresponding .cpp file. However, our CMake test
+// macro assumes one. Here it is.
+bool llstreamqueue_cpp_ignored = true;
diff --git a/indra/llcommon/llstreamqueue.h b/indra/llcommon/llstreamqueue.h
new file mode 100755
index 0000000000..0726bad175
--- /dev/null
+++ b/indra/llcommon/llstreamqueue.h
@@ -0,0 +1,240 @@
+/**
+ * @file llstreamqueue.h
+ * @author Nat Goodspeed
+ * @date 2012-01-04
+ * @brief Definition of LLStreamQueue
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Copyright (c) 2012, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+#if ! defined(LL_LLSTREAMQUEUE_H)
+#define LL_LLSTREAMQUEUE_H
+
+#include <string>
+#include <list>
+#include <iosfwd> // std::streamsize
+#include <boost/iostreams/categories.hpp>
+
+/**
+ * This class is a growable buffer between a producer and consumer. It serves
+ * as a queue usable with Boost.Iostreams -- hence, a "stream queue."
+ *
+ * This is especially useful for buffering nonblocking I/O. For instance, we
+ * want application logic to be able to serialize LLSD to a std::ostream. We
+ * may write more data than the destination pipe can handle all at once, but
+ * it's imperative NOT to block the application-level serialization call. So
+ * we buffer it instead. Successive frames can try nonblocking writes to the
+ * destination pipe until all buffered data has been sent.
+ *
+ * Similarly, we want application logic be able to deserialize LLSD from a
+ * std::istream. Again, we must not block that deserialize call waiting for
+ * more data to arrive from the input pipe! Instead we build up a buffer over
+ * a number of frames, using successive nonblocking reads, until we have
+ * "enough" data to be able to present it through a std::istream.
+ *
+ * @note The use cases for this class overlap somewhat with those for the
+ * LLIOPipe/LLPumpIO hierarchies, and indeed we considered using those. This
+ * class has two virtues over the older machinery:
+ *
+ * # It's vastly simpler -- way fewer concepts. It's not clear to me whether
+ * there were ever LLIOPipe/etc. use cases that demanded all the fanciness
+ * rolled in, or whether they were simply overdesigned. In any case, no
+ * remaining Lindens will admit to familiarity with those classes -- and
+ * they're sufficiently obtuse that it would take considerable learning
+ * curve to figure out how to use them properly. The bottom line is that
+ * current management is not keen on any more engineers climbing that curve.
+ * # This class is designed around available components such as std::string,
+ * std::list, Boost.Iostreams. There's less proprietary code.
+ */
+template <typename Ch>
+class LLGenericStreamQueue
+{
+public:
+ LLGenericStreamQueue():
+ mSize(0),
+ mClosed(false)
+ {}
+
+ /**
+ * Boost.Iostreams Source Device facade for use with other Boost.Iostreams
+ * functionality. LLGenericStreamQueue doesn't quite fit any of the Boost
+ * 1.48 Iostreams concepts; instead it behaves as both a Sink and a
+ * Source. This is its Source facade.
+ */
+ struct Source
+ {
+ typedef Ch char_type;
+ typedef boost::iostreams::source_tag category;
+
+ /// Bind the underlying LLGenericStreamQueue
+ Source(LLGenericStreamQueue& sq):
+ mStreamQueue(sq)
+ {}
+
+ // Read up to n characters from the underlying data source into the
+ // buffer s, returning the number of characters read; return -1 to
+ // indicate EOF
+ std::streamsize read(Ch* s, std::streamsize n)
+ {
+ return mStreamQueue.read(s, n);
+ }
+
+ LLGenericStreamQueue& mStreamQueue;
+ };
+
+ /**
+ * Boost.Iostreams Sink Device facade for use with other Boost.Iostreams
+ * functionality. LLGenericStreamQueue doesn't quite fit any of the Boost
+ * 1.48 Iostreams concepts; instead it behaves as both a Sink and a
+ * Source. This is its Sink facade.
+ */
+ struct Sink
+ {
+ typedef Ch char_type;
+ typedef boost::iostreams::sink_tag category;
+
+ /// Bind the underlying LLGenericStreamQueue
+ Sink(LLGenericStreamQueue& sq):
+ mStreamQueue(sq)
+ {}
+
+ /// Write up to n characters from the buffer s to the output sequence,
+ /// returning the number of characters written
+ std::streamsize write(const Ch* s, std::streamsize n)
+ {
+ return mStreamQueue.write(s, n);
+ }
+
+ /// Send EOF to consumer
+ void close()
+ {
+ mStreamQueue.close();
+ }
+
+ LLGenericStreamQueue& mStreamQueue;
+ };
+
+ /// Present Boost.Iostreams Source facade
+ Source asSource() { return Source(*this); }
+ /// Present Boost.Iostreams Sink facade
+ Sink asSink() { return Sink(*this); }
+
+ /// append data to buffer
+ std::streamsize write(const Ch* s, std::streamsize n)
+ {
+ // Unclear how often we might be asked to write 0 bytes -- perhaps a
+ // naive caller responding to an unready nonblocking read. But if we
+ // do get such a call, don't add a completely empty BufferList entry.
+ if (n == 0)
+ return n;
+ // We could implement this using a single std::string object, a la
+ // ostringstream. But the trouble with appending to a string is that
+ // you might have to recopy all previous contents to grow its size. If
+ // we want this to scale to large data volumes, better to allocate
+ // individual pieces.
+ mBuffer.push_back(string(s, n));
+ mSize += n;
+ return n;
+ }
+
+ /**
+ * Inform this LLGenericStreamQueue that no further data are forthcoming.
+ * For our purposes, close() is strictly a producer-side operation;
+ * there's little point in closing the consumer side.
+ */
+ void close()
+ {
+ mClosed = true;
+ }
+
+ /// consume data from buffer
+ std::streamsize read(Ch* s, std::streamsize n)
+ {
+ // read() is actually a convenience method for peek() followed by
+ // skip().
+ std::streamsize got(peek(s, n));
+ // We can only skip() as many characters as we can peek(); ignore
+ // skip() return here.
+ skip(n);
+ return got;
+ }
+
+ /// Retrieve data from buffer without consuming. Like read(), return -1 on
+ /// EOF.
+ std::streamsize peek(Ch* s, std::streamsize n) const;
+
+ /// Consume data from buffer without retrieving. Unlike read() and peek(),
+ /// at EOF we simply skip 0 characters.
+ std::streamsize skip(std::streamsize n);
+
+ /// How many characters do we currently have buffered?
+ std::streamsize size() const
+ {
+ return mSize;
+ }
+
+private:
+ typedef std::basic_string<Ch> string;
+ typedef std::list<string> BufferList;
+ BufferList mBuffer;
+ std::streamsize mSize;
+ bool mClosed;
+};
+
+template <typename Ch>
+std::streamsize LLGenericStreamQueue<Ch>::peek(Ch* s, std::streamsize n) const
+{
+ // Here we may have to build up 'n' characters from an arbitrary
+ // number of individual BufferList entries.
+ typename BufferList::const_iterator bli(mBuffer.begin()), blend(mBuffer.end());
+ // Indicate EOF if producer has closed the pipe AND we've exhausted
+ // all previously-buffered data.
+ if (mClosed && bli == blend)
+ {
+ return -1;
+ }
+ // Here either producer hasn't yet closed, or we haven't yet exhausted
+ // remaining data.
+ std::streamsize needed(n), got(0);
+ // Loop until either we run out of BufferList entries or we've
+ // completely satisfied the request.
+ for ( ; bli != blend && needed; ++bli)
+ {
+ std::streamsize chunk(std::min(needed, std::streamsize(bli->length())));
+ std::copy(bli->begin(), bli->begin() + chunk, s);
+ needed -= chunk;
+ s += chunk;
+ got += chunk;
+ }
+ return got;
+}
+
+template <typename Ch>
+std::streamsize LLGenericStreamQueue<Ch>::skip(std::streamsize n)
+{
+ typename BufferList::iterator bli(mBuffer.begin()), blend(mBuffer.end());
+ std::streamsize toskip(n), skipped(0);
+ while (bli != blend && toskip >= bli->length())
+ {
+ std::streamsize chunk(bli->length());
+ typename BufferList::iterator zap(bli++);
+ mBuffer.erase(zap);
+ mSize -= chunk;
+ toskip -= chunk;
+ skipped += chunk;
+ }
+ if (bli != blend && toskip)
+ {
+ bli->erase(bli->begin(), bli->begin() + toskip);
+ mSize -= toskip;
+ skipped += toskip;
+ }
+ return skipped;
+}
+
+typedef LLGenericStreamQueue<char> LLStreamQueue;
+typedef LLGenericStreamQueue<wchar_t> LLWStreamQueue;
+
+#endif /* ! defined(LL_LLSTREAMQUEUE_H) */
diff --git a/indra/llcommon/llstreamtools.cpp b/indra/llcommon/llstreamtools.cpp
index d7a6f47932..d7a6f47932 100644..100755
--- a/indra/llcommon/llstreamtools.cpp
+++ b/indra/llcommon/llstreamtools.cpp
diff --git a/indra/llcommon/llstreamtools.h b/indra/llcommon/llstreamtools.h
index 1b04bf91d7..1b04bf91d7 100644..100755
--- a/indra/llcommon/llstreamtools.h
+++ b/indra/llcommon/llstreamtools.h
diff --git a/indra/llcommon/llstrider.h b/indra/llcommon/llstrider.h
index f4c43bac61..ed9284d2c5 100644..100755
--- a/indra/llcommon/llstrider.h
+++ b/indra/llcommon/llstrider.h
@@ -44,6 +44,15 @@ public:
const LLStrider<Object>& operator = (Object *first) { mObjectp = first; return *this;}
void setStride (S32 skipBytes) { mSkip = (skipBytes ? skipBytes : sizeof(Object));}
+ LLStrider<Object> operator+(const S32& index)
+ {
+ LLStrider<Object> ret;
+ ret.mBytep = mBytep + mSkip*index;
+ ret.mSkip = mSkip;
+
+ return ret;
+ }
+
void skip(const U32 index) { mBytep += mSkip*index;}
U32 getSkip() const { return mSkip; }
Object* get() { return mObjectp; }
@@ -51,6 +60,7 @@ public:
Object& operator *() { return *mObjectp; }
Object* operator ++(int) { Object* old = mObjectp; mBytep += mSkip; return old; }
Object* operator +=(int i) { mBytep += mSkip*i; return mObjectp; }
+
Object& operator[](U32 index) { return *(Object*)(mBytep + (mSkip * index)); }
};
diff --git a/indra/llcommon/llstring.cpp b/indra/llcommon/llstring.cpp
index e7fe656808..22c8681983 100644..100755
--- a/indra/llcommon/llstring.cpp
+++ b/indra/llcommon/llstring.cpp
@@ -47,10 +47,28 @@ std::string ll_safe_string(const char* in)
std::string ll_safe_string(const char* in, S32 maxlen)
{
- if(in) return std::string(in, maxlen);
+ if(in && maxlen > 0 ) return std::string(in, maxlen);
+
return std::string();
}
+bool is_char_hex(char hex)
+{
+ if((hex >= '0') && (hex <= '9'))
+ {
+ return true;
+ }
+ else if((hex >= 'a') && (hex <='f'))
+ {
+ return true;
+ }
+ else if((hex >= 'A') && (hex <='F'))
+ {
+ return true;
+ }
+ return false; // uh - oh, not hex any more...
+}
+
U8 hex_as_nybble(char hex)
{
if((hex >= '0') && (hex <= '9'))
@@ -912,22 +930,24 @@ S32 LLStringUtil::format(std::string& s, const format_map_t& substitutions);
template<>
void LLStringUtil::getTokens(const std::string& instr, std::vector<std::string >& tokens, const std::string& delims)
{
- std::string currToken;
- std::string::size_type begIdx, endIdx;
-
- begIdx = instr.find_first_not_of (delims);
- while (begIdx != std::string::npos)
+ // Starting at offset 0, scan forward for the next non-delimiter. We're
+ // done when the only characters left in 'instr' are delimiters.
+ for (std::string::size_type begIdx, endIdx = 0;
+ (begIdx = instr.find_first_not_of (delims, endIdx)) != std::string::npos; )
{
+ // Found a non-delimiter. After that, find the next delimiter.
endIdx = instr.find_first_of (delims, begIdx);
if (endIdx == std::string::npos)
{
+ // No more delimiters: this token extends to the end of the string.
endIdx = instr.length();
}
- currToken = instr.substr(begIdx, endIdx - begIdx);
+ // extract the token between begIdx and endIdx; substr() needs length
+ std::string currToken(instr.substr(begIdx, endIdx - begIdx));
LLStringUtil::trim (currToken);
tokens.push_back(currToken);
- begIdx = instr.find_first_not_of (delims, endIdx);
+ // next scan past delimiters starts at endIdx
}
}
diff --git a/indra/llcommon/llstring.h b/indra/llcommon/llstring.h
index 7e41e787b5..f9702868c8 100644..100755
--- a/indra/llcommon/llstring.h
+++ b/indra/llcommon/llstring.h
@@ -40,6 +40,7 @@
#endif
#include <string.h>
+#include <boost/scoped_ptr.hpp>
#if LL_SOLARIS
// stricmp and strnicmp do not exist on Solaris:
@@ -182,6 +183,9 @@ public:
static bool isPunct(char a) { return ispunct((unsigned char)a) != 0; }
static bool isPunct(llwchar a) { return iswpunct(a) != 0; }
+ static bool isAlpha(char a) { return isalpha((unsigned char)a) != 0; }
+ static bool isAlpha(llwchar a) { return iswalpha(a) != 0; }
+
static bool isAlnum(char a) { return isalnum((unsigned char)a) != 0; }
static bool isAlnum(llwchar a) { return iswalnum(a) != 0; }
@@ -237,40 +241,77 @@ private:
static std::string sLocale;
public:
- typedef typename std::basic_string<T>::size_type size_type;
+ typedef std::basic_string<T> string_type;
+ typedef typename string_type::size_type size_type;
public:
/////////////////////////////////////////////////////////////////////////////////////////
// Static Utility functions that operate on std::strings
- static const std::basic_string<T> null;
+ static const string_type null;
typedef std::map<LLFormatMapString, LLFormatMapString> format_map_t;
- LL_COMMON_API static void getTokens(const std::basic_string<T>& instr, std::vector<std::basic_string<T> >& tokens, const std::basic_string<T>& delims);
- LL_COMMON_API static void formatNumber(std::basic_string<T>& numStr, std::basic_string<T> decimals);
- LL_COMMON_API static bool formatDatetime(std::basic_string<T>& replacement, std::basic_string<T> token, std::basic_string<T> param, S32 secFromEpoch);
- LL_COMMON_API static S32 format(std::basic_string<T>& s, const format_map_t& substitutions);
- LL_COMMON_API static S32 format(std::basic_string<T>& s, const LLSD& substitutions);
- LL_COMMON_API static bool simpleReplacement(std::basic_string<T>& replacement, std::basic_string<T> token, const format_map_t& substitutions);
- LL_COMMON_API static bool simpleReplacement(std::basic_string<T>& replacement, std::basic_string<T> token, const LLSD& substitutions);
+ /// considers any sequence of delims as a single field separator
+ LL_COMMON_API static void getTokens(const string_type& instr,
+ std::vector<string_type >& tokens,
+ const string_type& delims);
+ /// like simple scan overload, but returns scanned vector
+ static std::vector<string_type> getTokens(const string_type& instr,
+ const string_type& delims);
+ /// add support for keep_delims and quotes (either could be empty string)
+ static void getTokens(const string_type& instr,
+ std::vector<string_type>& tokens,
+ const string_type& drop_delims,
+ const string_type& keep_delims,
+ const string_type& quotes=string_type());
+ /// like keep_delims-and-quotes overload, but returns scanned vector
+ static std::vector<string_type> getTokens(const string_type& instr,
+ const string_type& drop_delims,
+ const string_type& keep_delims,
+ const string_type& quotes=string_type());
+ /// add support for escapes (could be empty string)
+ static void getTokens(const string_type& instr,
+ std::vector<string_type>& tokens,
+ const string_type& drop_delims,
+ const string_type& keep_delims,
+ const string_type& quotes,
+ const string_type& escapes);
+ /// like escapes overload, but returns scanned vector
+ static std::vector<string_type> getTokens(const string_type& instr,
+ const string_type& drop_delims,
+ const string_type& keep_delims,
+ const string_type& quotes,
+ const string_type& escapes);
+
+ LL_COMMON_API static void formatNumber(string_type& numStr, string_type decimals);
+ LL_COMMON_API static bool formatDatetime(string_type& replacement, string_type token, string_type param, S32 secFromEpoch);
+ LL_COMMON_API static S32 format(string_type& s, const format_map_t& substitutions);
+ LL_COMMON_API static S32 format(string_type& s, const LLSD& substitutions);
+ LL_COMMON_API static bool simpleReplacement(string_type& replacement, string_type token, const format_map_t& substitutions);
+ LL_COMMON_API static bool simpleReplacement(string_type& replacement, string_type token, const LLSD& substitutions);
LL_COMMON_API static void setLocale (std::string inLocale);
LL_COMMON_API static std::string getLocale (void);
- static bool isValidIndex(const std::basic_string<T>& string, size_type i)
+ static bool isValidIndex(const string_type& string, size_type i)
{
return !string.empty() && (0 <= i) && (i <= string.size());
}
- static void trimHead(std::basic_string<T>& string);
- static void trimTail(std::basic_string<T>& string);
- static void trim(std::basic_string<T>& string) { trimHead(string); trimTail(string); }
- static void truncate(std::basic_string<T>& string, size_type count);
+ static bool contains(const string_type& string, T c, size_type i=0)
+ {
+ return string.find(c, i) != string_type::npos;
+ }
+
+ static void trimHead(string_type& string);
+ static void trimTail(string_type& string);
+ static void trim(string_type& string) { trimHead(string); trimTail(string); }
+ static void truncate(string_type& string, size_type count);
- static void toUpper(std::basic_string<T>& string);
- static void toLower(std::basic_string<T>& string);
+ static void toUpper(string_type& string);
+ static void toLower(string_type& string);
// True if this is the head of s.
- static BOOL isHead( const std::basic_string<T>& string, const T* s );
+ static BOOL isHead( const string_type& string, const T* s );
/**
* @brief Returns true if string starts with substr
@@ -278,8 +319,8 @@ public:
* If etither string or substr are empty, this method returns false.
*/
static bool startsWith(
- const std::basic_string<T>& string,
- const std::basic_string<T>& substr);
+ const string_type& string,
+ const string_type& substr);
/**
* @brief Returns true if string ends in substr
@@ -287,19 +328,32 @@ public:
* If etither string or substr are empty, this method returns false.
*/
static bool endsWith(
- const std::basic_string<T>& string,
- const std::basic_string<T>& substr);
+ const string_type& string,
+ const string_type& substr);
- static void addCRLF(std::basic_string<T>& string);
- static void removeCRLF(std::basic_string<T>& string);
+ static void addCRLF(string_type& string);
+ static void removeCRLF(string_type& string);
- static void replaceTabsWithSpaces( std::basic_string<T>& string, size_type spaces_per_tab );
- static void replaceNonstandardASCII( std::basic_string<T>& string, T replacement );
- static void replaceChar( std::basic_string<T>& string, T target, T replacement );
- static void replaceString( std::basic_string<T>& string, std::basic_string<T> target, std::basic_string<T> replacement );
+ static void replaceTabsWithSpaces( string_type& string, size_type spaces_per_tab );
+ static void replaceNonstandardASCII( string_type& string, T replacement );
+ static void replaceChar( string_type& string, T target, T replacement );
+ static void replaceString( string_type& string, string_type target, string_type replacement );
- static BOOL containsNonprintable(const std::basic_string<T>& string);
- static void stripNonprintable(std::basic_string<T>& string);
+ static BOOL containsNonprintable(const string_type& string);
+ static void stripNonprintable(string_type& string);
+
+ /**
+ * Double-quote an argument string if needed, unless it's already
+ * double-quoted. Decide whether it's needed based on the presence of any
+ * character in @a triggers (default space or double-quote). If we quote
+ * it, escape any embedded double-quote with the @a escape string (default
+ * backslash).
+ *
+ * Passing triggers="" means always quote, unless it's already double-quoted.
+ */
+ static string_type quote(const string_type& str,
+ const string_type& triggers=" \"",
+ const string_type& escape="\\");
/**
* @brief Unsafe way to make ascii characters. You should probably
@@ -308,18 +362,18 @@ public:
* The 2 and 4 byte std::string probably work, so LLWStringUtil::_makeASCII
* should work.
*/
- static void _makeASCII(std::basic_string<T>& string);
+ static void _makeASCII(string_type& string);
// Conversion to other data types
- static BOOL convertToBOOL(const std::basic_string<T>& string, BOOL& value);
- static BOOL convertToU8(const std::basic_string<T>& string, U8& value);
- static BOOL convertToS8(const std::basic_string<T>& string, S8& value);
- static BOOL convertToS16(const std::basic_string<T>& string, S16& value);
- static BOOL convertToU16(const std::basic_string<T>& string, U16& value);
- static BOOL convertToU32(const std::basic_string<T>& string, U32& value);
- static BOOL convertToS32(const std::basic_string<T>& string, S32& value);
- static BOOL convertToF32(const std::basic_string<T>& string, F32& value);
- static BOOL convertToF64(const std::basic_string<T>& string, F64& value);
+ static BOOL convertToBOOL(const string_type& string, BOOL& value);
+ static BOOL convertToU8(const string_type& string, U8& value);
+ static BOOL convertToS8(const string_type& string, S8& value);
+ static BOOL convertToS16(const string_type& string, S16& value);
+ static BOOL convertToU16(const string_type& string, U16& value);
+ static BOOL convertToU32(const string_type& string, U32& value);
+ static BOOL convertToS32(const string_type& string, S32& value);
+ static BOOL convertToF32(const string_type& string, F32& value);
+ static BOOL convertToF64(const string_type& string, F64& value);
/////////////////////////////////////////////////////////////////////////////////////////
// Utility functions for working with char*'s and strings
@@ -327,24 +381,24 @@ public:
// Like strcmp but also handles empty strings. Uses
// current locale.
static S32 compareStrings(const T* lhs, const T* rhs);
- static S32 compareStrings(const std::basic_string<T>& lhs, const std::basic_string<T>& rhs);
+ static S32 compareStrings(const string_type& lhs, const string_type& rhs);
// case insensitive version of above. Uses current locale on
// Win32, and falls back to a non-locale aware comparison on
// Linux.
static S32 compareInsensitive(const T* lhs, const T* rhs);
- static S32 compareInsensitive(const std::basic_string<T>& lhs, const std::basic_string<T>& rhs);
+ static S32 compareInsensitive(const string_type& lhs, const string_type& rhs);
// Case sensitive comparison with good handling of numbers. Does not use current locale.
// a.k.a. strdictcmp()
- static S32 compareDict(const std::basic_string<T>& a, const std::basic_string<T>& b);
+ static S32 compareDict(const string_type& a, const string_type& b);
// Case *in*sensitive comparison with good handling of numbers. Does not use current locale.
// a.k.a. strdictcmp()
- static S32 compareDictInsensitive(const std::basic_string<T>& a, const std::basic_string<T>& b);
+ static S32 compareDictInsensitive(const string_type& a, const string_type& b);
// Puts compareDict() in a form appropriate for LL container classes to use for sorting.
- static BOOL precedesDict( const std::basic_string<T>& a, const std::basic_string<T>& b );
+ static BOOL precedesDict( const string_type& a, const string_type& b );
// A replacement for strncpy.
// If the dst buffer is dst_size bytes long or more, ensures that dst is null terminated and holds
@@ -352,7 +406,7 @@ public:
static void copy(T* dst, const T* src, size_type dst_size);
// Copies src into dst at a given offset.
- static void copyInto(std::basic_string<T>& dst, const std::basic_string<T>& src, size_type offset);
+ static void copyInto(string_type& dst, const string_type& src, size_type offset);
static bool isPartOfWord(T c) { return (c == (T)'_') || LLStringOps::isAlnum(c); }
@@ -362,7 +416,7 @@ public:
#endif
private:
- LL_COMMON_API static size_type getSubstitution(const std::basic_string<T>& instr, size_type& start, std::vector<std::basic_string<T> >& tokens);
+ LL_COMMON_API static size_type getSubstitution(const string_type& instr, size_type& start, std::vector<string_type >& tokens);
};
template<class T> const std::basic_string<T> LLStringUtilBase<T>::null;
@@ -416,6 +470,7 @@ inline std::string chop_tail_copy(
* @brief This translates a nybble stored as a hex value from 0-f back
* to a nybble in the low order bits of the return byte.
*/
+LL_COMMON_API bool is_char_hex(char hex);
LL_COMMON_API U8 hex_as_nybble(char hex);
/**
@@ -636,10 +691,325 @@ namespace LLStringFn
////////////////////////////////////////////////////////////
// NOTE: LLStringUtil::format, getTokens, and support functions moved to llstring.cpp.
// There is no LLWStringUtil::format implementation currently.
-// Calling thse for anything other than LLStringUtil will produce link errors.
+// Calling these for anything other than LLStringUtil will produce link errors.
////////////////////////////////////////////////////////////
+// static
+template <class T>
+std::vector<typename LLStringUtilBase<T>::string_type>
+LLStringUtilBase<T>::getTokens(const string_type& instr, const string_type& delims)
+{
+ std::vector<string_type> tokens;
+ getTokens(instr, tokens, delims);
+ return tokens;
+}
+
+// static
+template <class T>
+std::vector<typename LLStringUtilBase<T>::string_type>
+LLStringUtilBase<T>::getTokens(const string_type& instr,
+ const string_type& drop_delims,
+ const string_type& keep_delims,
+ const string_type& quotes)
+{
+ std::vector<string_type> tokens;
+ getTokens(instr, tokens, drop_delims, keep_delims, quotes);
+ return tokens;
+}
+
+// static
+template <class T>
+std::vector<typename LLStringUtilBase<T>::string_type>
+LLStringUtilBase<T>::getTokens(const string_type& instr,
+ const string_type& drop_delims,
+ const string_type& keep_delims,
+ const string_type& quotes,
+ const string_type& escapes)
+{
+ std::vector<string_type> tokens;
+ getTokens(instr, tokens, drop_delims, keep_delims, quotes, escapes);
+ return tokens;
+}
+
+namespace LLStringUtilBaseImpl
+{
+
+/**
+ * Input string scanner helper for getTokens(), or really any other
+ * character-parsing routine that may have to deal with escape characters.
+ * This implementation defines the concept (also an interface, should you
+ * choose to implement the concept by subclassing) and provides trivial
+ * implementations for a string @em without escape processing.
+ */
+template <class T>
+struct InString
+{
+ typedef std::basic_string<T> string_type;
+ typedef typename string_type::const_iterator const_iterator;
+
+ InString(const_iterator b, const_iterator e):
+ mIter(b),
+ mEnd(e)
+ {}
+ virtual ~InString() {}
+
+ bool done() const { return mIter == mEnd; }
+ /// Is the current character (*mIter) escaped? This implementation can
+ /// answer trivially because it doesn't support escapes.
+ virtual bool escaped() const { return false; }
+ /// Obtain the current character and advance @c mIter.
+ virtual T next() { return *mIter++; }
+ /// Does the current character match specified character?
+ virtual bool is(T ch) const { return (! done()) && *mIter == ch; }
+ /// Is the current character any one of the specified characters?
+ virtual bool oneof(const string_type& delims) const
+ {
+ return (! done()) && LLStringUtilBase<T>::contains(delims, *mIter);
+ }
+
+ /**
+ * Scan forward from @from until either @a delim or end. This is primarily
+ * useful for processing quoted substrings.
+ *
+ * If we do see @a delim, append everything from @from until (excluding)
+ * @a delim to @a into, advance @c mIter to skip @a delim, and return @c
+ * true.
+ *
+ * If we do not see @a delim, do not alter @a into or @c mIter and return
+ * @c false. Do not pass GO, do not collect $200.
+ *
+ * @note The @c false case described above implements normal getTokens()
+ * treatment of an unmatched open quote: treat the quote character as if
+ * escaped, that is, simply collect it as part of the current token. Other
+ * plausible behaviors directly affect the way getTokens() deals with an
+ * unmatched quote: e.g. throwing an exception to treat it as an error, or
+ * assuming a close quote beyond end of string (in which case return @c
+ * true).
+ */
+ virtual bool collect_until(string_type& into, const_iterator from, T delim)
+ {
+ const_iterator found = std::find(from, mEnd, delim);
+ // If we didn't find delim, change nothing, just tell caller.
+ if (found == mEnd)
+ return false;
+ // Found delim! Append everything between from and found.
+ into.append(from, found);
+ // advance past delim in input
+ mIter = found + 1;
+ return true;
+ }
+
+ const_iterator mIter, mEnd;
+};
+
+/// InString subclass that handles escape characters
+template <class T>
+class InEscString: public InString<T>
+{
+public:
+ typedef InString<T> super;
+ typedef typename super::string_type string_type;
+ typedef typename super::const_iterator const_iterator;
+ using super::done;
+ using super::mIter;
+ using super::mEnd;
+
+ InEscString(const_iterator b, const_iterator e, const string_type& escapes):
+ super(b, e),
+ mEscapes(escapes)
+ {
+ // Even though we've already initialized 'mIter' via our base-class
+ // constructor, set it again to check for initial escape char.
+ setiter(b);
+ }
+
+ /// This implementation uses the answer cached by setiter().
+ virtual bool escaped() const { return mIsEsc; }
+ virtual T next()
+ {
+ // If we're looking at the escape character of an escape sequence,
+ // skip that character. This is the one time we can modify 'mIter'
+ // without using setiter: for this one case we DO NOT CARE if the
+ // escaped character is itself an escape.
+ if (mIsEsc)
+ ++mIter;
+ // If we were looking at an escape character, this is the escaped
+ // character; otherwise it's just the next character.
+ T result(*mIter);
+ // Advance mIter, checking for escape sequence.
+ setiter(mIter + 1);
+ return result;
+ }
+
+ virtual bool is(T ch) const
+ {
+ // Like base-class is(), except that an escaped character matches
+ // nothing.
+ return (! done()) && (! mIsEsc) && *mIter == ch;
+ }
+
+ virtual bool oneof(const string_type& delims) const
+ {
+ // Like base-class oneof(), except that an escaped character matches
+ // nothing.
+ return (! done()) && (! mIsEsc) && LLStringUtilBase<T>::contains(delims, *mIter);
+ }
+
+ virtual bool collect_until(string_type& into, const_iterator from, T delim)
+ {
+ // Deal with escapes in the characters we collect; that is, an escaped
+ // character must become just that character without the preceding
+ // escape. Collect characters in a separate string rather than
+ // directly appending to 'into' in case we do not find delim, in which
+ // case we're supposed to leave 'into' unmodified.
+ string_type collected;
+ // For scanning purposes, we're going to work directly with 'mIter'.
+ // Save its current value in case we fail to see delim.
+ const_iterator save_iter(mIter);
+ // Okay, set 'mIter', checking for escape.
+ setiter(from);
+ while (! done())
+ {
+ // If we see an unescaped delim, stop and report success.
+ if ((! mIsEsc) && *mIter == delim)
+ {
+ // Append collected chars to 'into'.
+ into.append(collected);
+ // Don't forget to advance 'mIter' past delim.
+ setiter(mIter + 1);
+ return true;
+ }
+ // We're not at end, and either we're not looking at delim or it's
+ // escaped. Collect this character and keep going.
+ collected.push_back(next());
+ }
+ // Here we hit 'mEnd' without ever seeing delim. Restore mIter and tell
+ // caller.
+ setiter(save_iter);
+ return false;
+ }
+
+private:
+ void setiter(const_iterator i)
+ {
+ mIter = i;
+
+ // Every time we change 'mIter', set 'mIsEsc' to be able to repetitively
+ // answer escaped() without having to rescan 'mEscapes'. mIsEsc caches
+ // contains(mEscapes, *mIter).
+
+ // We're looking at an escaped char if we're not already at end (that
+ // is, *mIter is even meaningful); if *mIter is in fact one of the
+ // specified escape characters; and if there's one more character
+ // following it. That is, if an escape character is the very last
+ // character of the input string, it loses its special meaning.
+ mIsEsc = (! done()) &&
+ LLStringUtilBase<T>::contains(mEscapes, *mIter) &&
+ (mIter+1) != mEnd;
+ }
+
+ const string_type mEscapes;
+ bool mIsEsc;
+};
+
+/// getTokens() implementation based on InString concept
+template <typename INSTRING, typename string_type>
+void getTokens(INSTRING& instr, std::vector<string_type>& tokens,
+ const string_type& drop_delims, const string_type& keep_delims,
+ const string_type& quotes)
+{
+ // There are times when we want to match either drop_delims or
+ // keep_delims. Concatenate them up front to speed things up.
+ string_type all_delims(drop_delims + keep_delims);
+ // no tokens yet
+ tokens.clear();
+
+ // try for another token
+ while (! instr.done())
+ {
+ // scan past any drop_delims
+ while (instr.oneof(drop_delims))
+ {
+ // skip this drop_delim
+ instr.next();
+ // but if that was the end of the string, done
+ if (instr.done())
+ return;
+ }
+ // found the start of another token: make a slot for it
+ tokens.push_back(string_type());
+ if (instr.oneof(keep_delims))
+ {
+ // *iter is a keep_delim, a token of exactly 1 character. Append
+ // that character to the new token and proceed.
+ tokens.back().push_back(instr.next());
+ continue;
+ }
+ // Here we have a non-delimiter token, which might consist of a mix of
+ // quoted and unquoted parts. Use bash rules for quoting: you can
+ // embed a quoted substring in the midst of an unquoted token (e.g.
+ // ~/"sub dir"/myfile.txt); you can ram two quoted substrings together
+ // to make a single token (e.g. 'He said, "'"Don't."'"'). We diverge
+ // from bash in that bash considers an unmatched quote an error. Our
+ // param signature doesn't allow for errors, so just pretend it's not
+ // a quote and embed it.
+ // At this level, keep scanning until we hit the next delimiter of
+ // either type (drop_delims or keep_delims).
+ while (! instr.oneof(all_delims))
+ {
+ // If we're looking at an open quote, search forward for
+ // a close quote, collecting characters along the way.
+ if (instr.oneof(quotes) &&
+ instr.collect_until(tokens.back(), instr.mIter+1, *instr.mIter))
+ {
+ // collect_until is cleverly designed to do exactly what we
+ // need here. No further action needed if it returns true.
+ }
+ else
+ {
+ // Either *iter isn't a quote, or there's no matching close
+ // quote: in other words, just an ordinary char. Append it to
+ // current token.
+ tokens.back().push_back(instr.next());
+ }
+ // having scanned that segment of this token, if we've reached the
+ // end of the string, we're done
+ if (instr.done())
+ return;
+ }
+ }
+}
+
+} // namespace LLStringUtilBaseImpl
+
+// static
+template <class T>
+void LLStringUtilBase<T>::getTokens(const string_type& string, std::vector<string_type>& tokens,
+ const string_type& drop_delims, const string_type& keep_delims,
+ const string_type& quotes)
+{
+ // Because this overload doesn't support escapes, use simple InString to
+ // manage input range.
+ LLStringUtilBaseImpl::InString<T> instring(string.begin(), string.end());
+ LLStringUtilBaseImpl::getTokens(instring, tokens, drop_delims, keep_delims, quotes);
+}
+
+// static
+template <class T>
+void LLStringUtilBase<T>::getTokens(const string_type& string, std::vector<string_type>& tokens,
+ const string_type& drop_delims, const string_type& keep_delims,
+ const string_type& quotes, const string_type& escapes)
+{
+ // This overload must deal with escapes. Delegate that to InEscString
+ // (unless there ARE no escapes).
+ boost::scoped_ptr< LLStringUtilBaseImpl::InString<T> > instrp;
+ if (escapes.empty())
+ instrp.reset(new LLStringUtilBaseImpl::InString<T>(string.begin(), string.end()));
+ else
+ instrp.reset(new LLStringUtilBaseImpl::InEscString<T>(string.begin(), string.end(), escapes));
+ LLStringUtilBaseImpl::getTokens(*instrp, tokens, drop_delims, keep_delims, quotes);
+}
// static
template<class T>
@@ -669,7 +1039,7 @@ S32 LLStringUtilBase<T>::compareStrings(const T* lhs, const T* rhs)
//static
template<class T>
-S32 LLStringUtilBase<T>::compareStrings(const std::basic_string<T>& lhs, const std::basic_string<T>& rhs)
+S32 LLStringUtilBase<T>::compareStrings(const string_type& lhs, const string_type& rhs)
{
return LLStringOps::collate(lhs.c_str(), rhs.c_str());
}
@@ -695,8 +1065,8 @@ S32 LLStringUtilBase<T>::compareInsensitive(const T* lhs, const T* rhs )
}
else
{
- std::basic_string<T> lhs_string(lhs);
- std::basic_string<T> rhs_string(rhs);
+ string_type lhs_string(lhs);
+ string_type rhs_string(rhs);
LLStringUtilBase<T>::toUpper(lhs_string);
LLStringUtilBase<T>::toUpper(rhs_string);
result = LLStringOps::collate(lhs_string.c_str(), rhs_string.c_str());
@@ -706,10 +1076,10 @@ S32 LLStringUtilBase<T>::compareInsensitive(const T* lhs, const T* rhs )
//static
template<class T>
-S32 LLStringUtilBase<T>::compareInsensitive(const std::basic_string<T>& lhs, const std::basic_string<T>& rhs)
+S32 LLStringUtilBase<T>::compareInsensitive(const string_type& lhs, const string_type& rhs)
{
- std::basic_string<T> lhs_string(lhs);
- std::basic_string<T> rhs_string(rhs);
+ string_type lhs_string(lhs);
+ string_type rhs_string(rhs);
LLStringUtilBase<T>::toUpper(lhs_string);
LLStringUtilBase<T>::toUpper(rhs_string);
return LLStringOps::collate(lhs_string.c_str(), rhs_string.c_str());
@@ -720,7 +1090,7 @@ S32 LLStringUtilBase<T>::compareInsensitive(const std::basic_string<T>& lhs, con
//static
template<class T>
-S32 LLStringUtilBase<T>::compareDict(const std::basic_string<T>& astr, const std::basic_string<T>& bstr)
+S32 LLStringUtilBase<T>::compareDict(const string_type& astr, const string_type& bstr)
{
const T* a = astr.c_str();
const T* b = bstr.c_str();
@@ -761,7 +1131,7 @@ S32 LLStringUtilBase<T>::compareDict(const std::basic_string<T>& astr, const std
// static
template<class T>
-S32 LLStringUtilBase<T>::compareDictInsensitive(const std::basic_string<T>& astr, const std::basic_string<T>& bstr)
+S32 LLStringUtilBase<T>::compareDictInsensitive(const string_type& astr, const string_type& bstr)
{
const T* a = astr.c_str();
const T* b = bstr.c_str();
@@ -796,7 +1166,7 @@ S32 LLStringUtilBase<T>::compareDictInsensitive(const std::basic_string<T>& astr
// Puts compareDict() in a form appropriate for LL container classes to use for sorting.
// static
template<class T>
-BOOL LLStringUtilBase<T>::precedesDict( const std::basic_string<T>& a, const std::basic_string<T>& b )
+BOOL LLStringUtilBase<T>::precedesDict( const string_type& a, const string_type& b )
{
if( a.size() && b.size() )
{
@@ -810,7 +1180,7 @@ BOOL LLStringUtilBase<T>::precedesDict( const std::basic_string<T>& a, const std
//static
template<class T>
-void LLStringUtilBase<T>::toUpper(std::basic_string<T>& string)
+void LLStringUtilBase<T>::toUpper(string_type& string)
{
if( !string.empty() )
{
@@ -824,7 +1194,7 @@ void LLStringUtilBase<T>::toUpper(std::basic_string<T>& string)
//static
template<class T>
-void LLStringUtilBase<T>::toLower(std::basic_string<T>& string)
+void LLStringUtilBase<T>::toLower(string_type& string)
{
if( !string.empty() )
{
@@ -838,7 +1208,7 @@ void LLStringUtilBase<T>::toLower(std::basic_string<T>& string)
//static
template<class T>
-void LLStringUtilBase<T>::trimHead(std::basic_string<T>& string)
+void LLStringUtilBase<T>::trimHead(string_type& string)
{
if( !string.empty() )
{
@@ -853,7 +1223,7 @@ void LLStringUtilBase<T>::trimHead(std::basic_string<T>& string)
//static
template<class T>
-void LLStringUtilBase<T>::trimTail(std::basic_string<T>& string)
+void LLStringUtilBase<T>::trimTail(string_type& string)
{
if( string.size() )
{
@@ -872,7 +1242,7 @@ void LLStringUtilBase<T>::trimTail(std::basic_string<T>& string)
// Replace line feeds with carriage return-line feed pairs.
//static
template<class T>
-void LLStringUtilBase<T>::addCRLF(std::basic_string<T>& string)
+void LLStringUtilBase<T>::addCRLF(string_type& string)
{
const T LF = 10;
const T CR = 13;
@@ -914,7 +1284,7 @@ void LLStringUtilBase<T>::addCRLF(std::basic_string<T>& string)
// Remove all carriage returns
//static
template<class T>
-void LLStringUtilBase<T>::removeCRLF(std::basic_string<T>& string)
+void LLStringUtilBase<T>::removeCRLF(string_type& string)
{
const T CR = 13;
@@ -935,10 +1305,10 @@ void LLStringUtilBase<T>::removeCRLF(std::basic_string<T>& string)
//static
template<class T>
-void LLStringUtilBase<T>::replaceChar( std::basic_string<T>& string, T target, T replacement )
+void LLStringUtilBase<T>::replaceChar( string_type& string, T target, T replacement )
{
size_type found_pos = 0;
- while( (found_pos = string.find(target, found_pos)) != std::basic_string<T>::npos )
+ while( (found_pos = string.find(target, found_pos)) != string_type::npos )
{
string[found_pos] = replacement;
found_pos++; // avoid infinite defeat if target == replacement
@@ -947,10 +1317,10 @@ void LLStringUtilBase<T>::replaceChar( std::basic_string<T>& string, T target, T
//static
template<class T>
-void LLStringUtilBase<T>::replaceString( std::basic_string<T>& string, std::basic_string<T> target, std::basic_string<T> replacement )
+void LLStringUtilBase<T>::replaceString( string_type& string, string_type target, string_type replacement )
{
size_type found_pos = 0;
- while( (found_pos = string.find(target, found_pos)) != std::basic_string<T>::npos )
+ while( (found_pos = string.find(target, found_pos)) != string_type::npos )
{
string.replace( found_pos, target.length(), replacement );
found_pos += replacement.length(); // avoid infinite defeat if replacement contains target
@@ -959,7 +1329,7 @@ void LLStringUtilBase<T>::replaceString( std::basic_string<T>& string, std::basi
//static
template<class T>
-void LLStringUtilBase<T>::replaceNonstandardASCII( std::basic_string<T>& string, T replacement )
+void LLStringUtilBase<T>::replaceNonstandardASCII( string_type& string, T replacement )
{
const char LF = 10;
const S8 MIN = 32;
@@ -979,12 +1349,12 @@ void LLStringUtilBase<T>::replaceNonstandardASCII( std::basic_string<T>& string,
//static
template<class T>
-void LLStringUtilBase<T>::replaceTabsWithSpaces( std::basic_string<T>& str, size_type spaces_per_tab )
+void LLStringUtilBase<T>::replaceTabsWithSpaces( string_type& str, size_type spaces_per_tab )
{
const T TAB = '\t';
const T SPACE = ' ';
- std::basic_string<T> out_str;
+ string_type out_str;
// Replace tabs with spaces
for (size_type i = 0; i < str.length(); i++)
{
@@ -1003,7 +1373,7 @@ void LLStringUtilBase<T>::replaceTabsWithSpaces( std::basic_string<T>& str, size
//static
template<class T>
-BOOL LLStringUtilBase<T>::containsNonprintable(const std::basic_string<T>& string)
+BOOL LLStringUtilBase<T>::containsNonprintable(const string_type& string)
{
const char MIN = 32;
BOOL rv = FALSE;
@@ -1020,7 +1390,7 @@ BOOL LLStringUtilBase<T>::containsNonprintable(const std::basic_string<T>& strin
//static
template<class T>
-void LLStringUtilBase<T>::stripNonprintable(std::basic_string<T>& string)
+void LLStringUtilBase<T>::stripNonprintable(string_type& string)
{
const char MIN = 32;
size_type j = 0;
@@ -1051,8 +1421,43 @@ void LLStringUtilBase<T>::stripNonprintable(std::basic_string<T>& string)
delete []c_string;
}
+template<class T>
+std::basic_string<T> LLStringUtilBase<T>::quote(const string_type& str,
+ const string_type& triggers,
+ const string_type& escape)
+{
+ size_type len(str.length());
+ // If the string is already quoted, assume user knows what s/he's doing.
+ if (len >= 2 && str[0] == '"' && str[len-1] == '"')
+ {
+ return str;
+ }
+
+ // Not already quoted: do we need to? triggers.empty() is a special case
+ // meaning "always quote."
+ if ((! triggers.empty()) && str.find_first_of(triggers) == string_type::npos)
+ {
+ // no trigger characters, don't bother quoting
+ return str;
+ }
+
+ // For whatever reason, we must quote this string.
+ string_type result;
+ result.push_back('"');
+ for (typename string_type::const_iterator ci(str.begin()), cend(str.end()); ci != cend; ++ci)
+ {
+ if (*ci == '"')
+ {
+ result.append(escape);
+ }
+ result.push_back(*ci);
+ }
+ result.push_back('"');
+ return result;
+}
+
template<class T>
-void LLStringUtilBase<T>::_makeASCII(std::basic_string<T>& string)
+void LLStringUtilBase<T>::_makeASCII(string_type& string)
{
// Replace non-ASCII chars with LL_UNKNOWN_CHAR
for (size_type i = 0; i < string.length(); i++)
@@ -1082,7 +1487,7 @@ void LLStringUtilBase<T>::copy( T* dst, const T* src, size_type dst_size )
// static
template<class T>
-void LLStringUtilBase<T>::copyInto(std::basic_string<T>& dst, const std::basic_string<T>& src, size_type offset)
+void LLStringUtilBase<T>::copyInto(string_type& dst, const string_type& src, size_type offset)
{
if ( offset == dst.length() )
{
@@ -1092,7 +1497,7 @@ void LLStringUtilBase<T>::copyInto(std::basic_string<T>& dst, const std::basic_s
}
else
{
- std::basic_string<T> tail = dst.substr(offset);
+ string_type tail = dst.substr(offset);
dst = dst.substr(0, offset);
dst += src;
@@ -1103,7 +1508,7 @@ void LLStringUtilBase<T>::copyInto(std::basic_string<T>& dst, const std::basic_s
// True if this is the head of s.
//static
template<class T>
-BOOL LLStringUtilBase<T>::isHead( const std::basic_string<T>& string, const T* s )
+BOOL LLStringUtilBase<T>::isHead( const string_type& string, const T* s )
{
if( string.empty() )
{
@@ -1119,8 +1524,8 @@ BOOL LLStringUtilBase<T>::isHead( const std::basic_string<T>& string, const T* s
// static
template<class T>
bool LLStringUtilBase<T>::startsWith(
- const std::basic_string<T>& string,
- const std::basic_string<T>& substr)
+ const string_type& string,
+ const string_type& substr)
{
if(string.empty() || (substr.empty())) return false;
if(0 == string.find(substr)) return true;
@@ -1130,8 +1535,8 @@ bool LLStringUtilBase<T>::startsWith(
// static
template<class T>
bool LLStringUtilBase<T>::endsWith(
- const std::basic_string<T>& string,
- const std::basic_string<T>& substr)
+ const string_type& string,
+ const string_type& substr)
{
if(string.empty() || (substr.empty())) return false;
std::string::size_type idx = string.rfind(substr);
@@ -1141,14 +1546,14 @@ bool LLStringUtilBase<T>::endsWith(
template<class T>
-BOOL LLStringUtilBase<T>::convertToBOOL(const std::basic_string<T>& string, BOOL& value)
+BOOL LLStringUtilBase<T>::convertToBOOL(const string_type& string, BOOL& value)
{
if( string.empty() )
{
return FALSE;
}
- std::basic_string<T> temp( string );
+ string_type temp( string );
trim(temp);
if(
(temp == "1") ||
@@ -1178,7 +1583,7 @@ BOOL LLStringUtilBase<T>::convertToBOOL(const std::basic_string<T>& string, BOOL
}
template<class T>
-BOOL LLStringUtilBase<T>::convertToU8(const std::basic_string<T>& string, U8& value)
+BOOL LLStringUtilBase<T>::convertToU8(const string_type& string, U8& value)
{
S32 value32 = 0;
BOOL success = convertToS32(string, value32);
@@ -1191,7 +1596,7 @@ BOOL LLStringUtilBase<T>::convertToU8(const std::basic_string<T>& string, U8& va
}
template<class T>
-BOOL LLStringUtilBase<T>::convertToS8(const std::basic_string<T>& string, S8& value)
+BOOL LLStringUtilBase<T>::convertToS8(const string_type& string, S8& value)
{
S32 value32 = 0;
BOOL success = convertToS32(string, value32);
@@ -1204,7 +1609,7 @@ BOOL LLStringUtilBase<T>::convertToS8(const std::basic_string<T>& string, S8& va
}
template<class T>
-BOOL LLStringUtilBase<T>::convertToS16(const std::basic_string<T>& string, S16& value)
+BOOL LLStringUtilBase<T>::convertToS16(const string_type& string, S16& value)
{
S32 value32 = 0;
BOOL success = convertToS32(string, value32);
@@ -1217,7 +1622,7 @@ BOOL LLStringUtilBase<T>::convertToS16(const std::basic_string<T>& string, S16&
}
template<class T>
-BOOL LLStringUtilBase<T>::convertToU16(const std::basic_string<T>& string, U16& value)
+BOOL LLStringUtilBase<T>::convertToU16(const string_type& string, U16& value)
{
S32 value32 = 0;
BOOL success = convertToS32(string, value32);
@@ -1230,17 +1635,17 @@ BOOL LLStringUtilBase<T>::convertToU16(const std::basic_string<T>& string, U16&
}
template<class T>
-BOOL LLStringUtilBase<T>::convertToU32(const std::basic_string<T>& string, U32& value)
+BOOL LLStringUtilBase<T>::convertToU32(const string_type& string, U32& value)
{
if( string.empty() )
{
return FALSE;
}
- std::basic_string<T> temp( string );
+ string_type temp( string );
trim(temp);
U32 v;
- std::basic_istringstream<T> i_stream((std::basic_string<T>)temp);
+ std::basic_istringstream<T> i_stream((string_type)temp);
if(i_stream >> v)
{
value = v;
@@ -1250,17 +1655,17 @@ BOOL LLStringUtilBase<T>::convertToU32(const std::basic_string<T>& string, U32&
}
template<class T>
-BOOL LLStringUtilBase<T>::convertToS32(const std::basic_string<T>& string, S32& value)
+BOOL LLStringUtilBase<T>::convertToS32(const string_type& string, S32& value)
{
if( string.empty() )
{
return FALSE;
}
- std::basic_string<T> temp( string );
+ string_type temp( string );
trim(temp);
S32 v;
- std::basic_istringstream<T> i_stream((std::basic_string<T>)temp);
+ std::basic_istringstream<T> i_stream((string_type)temp);
if(i_stream >> v)
{
//TODO: figure out overflow and underflow reporting here
@@ -1277,7 +1682,7 @@ BOOL LLStringUtilBase<T>::convertToS32(const std::basic_string<T>& string, S32&
}
template<class T>
-BOOL LLStringUtilBase<T>::convertToF32(const std::basic_string<T>& string, F32& value)
+BOOL LLStringUtilBase<T>::convertToF32(const string_type& string, F32& value)
{
F64 value64 = 0.0;
BOOL success = convertToF64(string, value64);
@@ -1290,17 +1695,17 @@ BOOL LLStringUtilBase<T>::convertToF32(const std::basic_string<T>& string, F32&
}
template<class T>
-BOOL LLStringUtilBase<T>::convertToF64(const std::basic_string<T>& string, F64& value)
+BOOL LLStringUtilBase<T>::convertToF64(const string_type& string, F64& value)
{
if( string.empty() )
{
return FALSE;
}
- std::basic_string<T> temp( string );
+ string_type temp( string );
trim(temp);
F64 v;
- std::basic_istringstream<T> i_stream((std::basic_string<T>)temp);
+ std::basic_istringstream<T> i_stream((string_type)temp);
if(i_stream >> v)
{
//TODO: figure out overflow and underflow reporting here
@@ -1317,7 +1722,7 @@ BOOL LLStringUtilBase<T>::convertToF64(const std::basic_string<T>& string, F64&
}
template<class T>
-void LLStringUtilBase<T>::truncate(std::basic_string<T>& string, size_type count)
+void LLStringUtilBase<T>::truncate(string_type& string, size_type count)
{
size_type cur_size = string.size();
string.resize(count < cur_size ? count : cur_size);
diff --git a/indra/llcommon/llstringtable.cpp b/indra/llcommon/llstringtable.cpp
index 7ad3805351..7ad3805351 100644..100755
--- a/indra/llcommon/llstringtable.cpp
+++ b/indra/llcommon/llstringtable.cpp
diff --git a/indra/llcommon/llstringtable.h b/indra/llcommon/llstringtable.h
index 59d7372ed4..ff09e71677 100644..100755
--- a/indra/llcommon/llstringtable.h
+++ b/indra/llcommon/llstringtable.h
@@ -42,14 +42,6 @@
//# define STRING_TABLE_HASH_MAP 1
#endif
-#if STRING_TABLE_HASH_MAP
-# if LL_WINDOWS
-# include <hash_map>
-# else
-# include <ext/hash_map>
-# endif
-#endif
-
const U32 MAX_STRINGS_LENGTH = 256;
class LL_COMMON_API LLStringTableEntry
diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp
index 6073bcd0a6..bb17725c9c 100644..100755
--- a/indra/llcommon/llsys.cpp
+++ b/indra/llcommon/llsys.cpp
@@ -67,12 +67,18 @@ using namespace llsd;
# include <sys/sysctl.h>
# include <sys/utsname.h>
# include <stdint.h>
-# include <Carbon/Carbon.h>
+# include <CoreServices/CoreServices.h>
# include <stdexcept>
# include <mach/host_info.h>
# include <mach/mach_host.h>
# include <mach/task.h>
# include <mach/task_info.h>
+
+// disable warnings about Gestalt calls being deprecated
+// until Apple get's on the ball and provides an alternative
+//
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+
#elif LL_LINUX
# include <errno.h>
# include <sys/utsname.h>
@@ -80,6 +86,7 @@ using namespace llsd;
# include <sys/sysinfo.h>
# include <stdexcept>
const char MEMINFO_FILE[] = "/proc/meminfo";
+# include <gnu/libc-version.h>
#elif LL_SOLARIS
# include <stdio.h>
# include <unistd.h>
@@ -107,6 +114,9 @@ static const F32 MEM_INFO_THROTTLE = 20;
static const F32 MEM_INFO_WINDOW = 10*60;
#if LL_WINDOWS
+// We cannot trust GetVersionEx function on Win8.1 , we should check this value when creating OS string
+static const U32 WINNT_WINBLUE = 0x0603;
+
#ifndef DLLVERSIONINFO
typedef struct _DllVersionInfo
{
@@ -175,13 +185,67 @@ bool get_shell32_dll_version(DWORD& major, DWORD& minor, DWORD& build_number)
}
#endif // LL_WINDOWS
+// Wrap boost::regex_match() with a function that doesn't throw.
+template <typename S, typename M, typename R>
+static bool regex_match_no_exc(const S& string, M& match, const R& regex)
+{
+ try
+ {
+ return boost::regex_match(string, match, regex);
+ }
+ catch (const std::runtime_error& e)
+ {
+ LL_WARNS("LLMemoryInfo") << "error matching with '" << regex.str() << "': "
+ << e.what() << ":\n'" << string << "'" << LL_ENDL;
+ return false;
+ }
+}
+
+// Wrap boost::regex_search() with a function that doesn't throw.
+template <typename S, typename M, typename R>
+static bool regex_search_no_exc(const S& string, M& match, const R& regex)
+{
+ try
+ {
+ return boost::regex_search(string, match, regex);
+ }
+ catch (const std::runtime_error& e)
+ {
+ LL_WARNS("LLMemoryInfo") << "error searching with '" << regex.str() << "': "
+ << e.what() << ":\n'" << string << "'" << LL_ENDL;
+ return false;
+ }
+}
+
+#if LL_WINDOWS
+// GetVersionEx should not works correct with Windows 8.1 and the later version. We need to check this case
+static bool check_for_version(WORD wMajorVersion, WORD wMinorVersion, WORD wServicePackMajor)
+{
+ OSVERSIONINFOEXW osvi = { sizeof(osvi), 0, 0, 0, 0, {0}, 0, 0 };
+ DWORDLONG const dwlConditionMask = VerSetConditionMask(
+ VerSetConditionMask(
+ VerSetConditionMask(
+ 0, VER_MAJORVERSION, VER_GREATER_EQUAL),
+ VER_MINORVERSION, VER_GREATER_EQUAL),
+ VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);
+
+ osvi.dwMajorVersion = wMajorVersion;
+ osvi.dwMinorVersion = wMinorVersion;
+ osvi.wServicePackMajor = wServicePackMajor;
+
+ return VerifyVersionInfoW(&osvi, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR, dwlConditionMask) != FALSE;
+}
+#endif
+
+
LLOSInfo::LLOSInfo() :
- mMajorVer(0), mMinorVer(0), mBuild(0)
+ mMajorVer(0), mMinorVer(0), mBuild(0), mOSVersionString("")
{
#if LL_WINDOWS
OSVERSIONINFOEX osvi;
BOOL bOsVersionInfoEx;
+ BOOL bShouldUseShellVersion = false;
// Try calling GetVersionEx using the OSVERSIONINFOEX structure.
ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
@@ -244,10 +308,18 @@ LLOSInfo::LLOSInfo() :
}
else if(osvi.dwMinorVersion == 2)
{
- if(osvi.wProductType == VER_NT_WORKSTATION)
- mOSStringSimple = "Microsoft Windows 8 ";
+ if (check_for_version(HIBYTE(WINNT_WINBLUE), LOBYTE(WINNT_WINBLUE), 0))
+ {
+ mOSStringSimple = "Microsoft Windows 8.1 ";
+ bShouldUseShellVersion = true; // GetVersionEx failed, going to use shell version
+ }
else
- mOSStringSimple = "Windows Server 2012 ";
+ {
+ if(osvi.wProductType == VER_NT_WORKSTATION)
+ mOSStringSimple = "Microsoft Windows 8 ";
+ else
+ mOSStringSimple = "Windows Server 2012 ";
+ }
}
///get native system info if available..
@@ -314,9 +386,8 @@ LLOSInfo::LLOSInfo() :
}
else
{
- tmpstr = llformat("%s (Build %d)",
- csdversion.c_str(),
- (osvi.dwBuildNumber & 0xffff));
+ tmpstr = !bShouldUseShellVersion ? llformat("%s (Build %d)", csdversion.c_str(), (osvi.dwBuildNumber & 0xffff)):
+ llformat("%s (Build %d)", csdversion.c_str(), shell32_build);
}
mOSString = mOSStringSimple + tmpstr;
@@ -352,7 +423,7 @@ LLOSInfo::LLOSInfo() :
std::string compatibility_mode;
if(got_shell32_version)
{
- if(osvi.dwMajorVersion != shell32_major || osvi.dwMinorVersion != shell32_minor)
+ if((osvi.dwMajorVersion != shell32_major || osvi.dwMinorVersion != shell32_minor) && !bShouldUseShellVersion)
{
compatibility_mode = llformat(" compatibility mode. real ver: %d.%d (Build %d)",
shell32_major,
@@ -412,6 +483,102 @@ LLOSInfo::LLOSInfo() :
mOSString = mOSStringSimple;
}
+#elif LL_LINUX
+
+ struct utsname un;
+ if(uname(&un) != -1)
+ {
+ mOSStringSimple.append(un.sysname);
+ mOSStringSimple.append(" ");
+ mOSStringSimple.append(un.release);
+
+ mOSString = mOSStringSimple;
+ mOSString.append(" ");
+ mOSString.append(un.version);
+ mOSString.append(" ");
+ mOSString.append(un.machine);
+
+ // Simplify 'Simple'
+ std::string ostype = mOSStringSimple.substr(0, mOSStringSimple.find_first_of(" ", 0));
+ if (ostype == "Linux")
+ {
+ // Only care about major and minor Linux versions, truncate at second '.'
+ std::string::size_type idx1 = mOSStringSimple.find_first_of(".", 0);
+ std::string::size_type idx2 = (idx1 != std::string::npos) ? mOSStringSimple.find_first_of(".", idx1+1) : std::string::npos;
+ std::string simple = mOSStringSimple.substr(0, idx2);
+ if (simple.length() > 0)
+ mOSStringSimple = simple;
+ }
+ }
+ else
+ {
+ mOSStringSimple.append("Unable to collect OS info");
+ mOSString = mOSStringSimple;
+ }
+
+ const char OS_VERSION_MATCH_EXPRESSION[] = "([0-9]+)\\.([0-9]+)(\\.([0-9]+))?";
+ boost::regex os_version_parse(OS_VERSION_MATCH_EXPRESSION);
+ boost::smatch matched;
+
+ std::string glibc_version(gnu_get_libc_version());
+ if ( regex_match_no_exc(glibc_version, matched, os_version_parse) )
+ {
+ LL_INFOS("AppInit") << "Using glibc version '" << glibc_version << "' as OS version" << LL_ENDL;
+
+ std::string version_value;
+
+ if ( matched[1].matched ) // Major version
+ {
+ version_value.assign(matched[1].first, matched[1].second);
+ if (sscanf(version_value.c_str(), "%d", &mMajorVer) != 1)
+ {
+ LL_WARNS("AppInit") << "failed to parse major version '" << version_value << "' as a number" << LL_ENDL;
+ }
+ }
+ else
+ {
+ LL_ERRS("AppInit")
+ << "OS version regex '" << OS_VERSION_MATCH_EXPRESSION
+ << "' returned true, but major version [1] did not match"
+ << LL_ENDL;
+ }
+
+ if ( matched[2].matched ) // Minor version
+ {
+ version_value.assign(matched[2].first, matched[2].second);
+ if (sscanf(version_value.c_str(), "%d", &mMinorVer) != 1)
+ {
+ LL_ERRS("AppInit") << "failed to parse minor version '" << version_value << "' as a number" << LL_ENDL;
+ }
+ }
+ else
+ {
+ LL_ERRS("AppInit")
+ << "OS version regex '" << OS_VERSION_MATCH_EXPRESSION
+ << "' returned true, but minor version [1] did not match"
+ << LL_ENDL;
+ }
+
+ if ( matched[4].matched ) // Build version (optional) - note that [3] includes the '.'
+ {
+ version_value.assign(matched[4].first, matched[4].second);
+ if (sscanf(version_value.c_str(), "%d", &mBuild) != 1)
+ {
+ LL_ERRS("AppInit") << "failed to parse build version '" << version_value << "' as a number" << LL_ENDL;
+ }
+ }
+ else
+ {
+ LL_INFOS("AppInit")
+ << "OS build version not provided; using zero"
+ << LL_ENDL;
+ }
+ }
+ else
+ {
+ LL_WARNS("AppInit") << "glibc version '" << glibc_version << "' cannot be parsed to three numbers; using all zeros" << LL_ENDL;
+ }
+
#else
struct utsname un;
@@ -444,8 +611,13 @@ LLOSInfo::LLOSInfo() :
mOSStringSimple.append("Unable to collect OS info");
mOSString = mOSStringSimple;
}
+
#endif
+ std::stringstream dotted_version_string;
+ dotted_version_string << mMajorVer << "." << mMinorVer << "." << mBuild;
+ mOSVersionString.append(dotted_version_string.str());
+
}
#ifndef LL_WINDOWS
@@ -496,6 +668,11 @@ const std::string& LLOSInfo::getOSStringSimple() const
return mOSStringSimple;
}
+const std::string& LLOSInfo::getOSVersionString() const
+{
+ return mOSVersionString;
+}
+
const S32 STATUS_SIZE = 8192;
//static
@@ -687,38 +864,6 @@ private:
LLSD mStats;
};
-// Wrap boost::regex_match() with a function that doesn't throw.
-template <typename S, typename M, typename R>
-static bool regex_match_no_exc(const S& string, M& match, const R& regex)
-{
- try
- {
- return boost::regex_match(string, match, regex);
- }
- catch (const std::runtime_error& e)
- {
- LL_WARNS("LLMemoryInfo") << "error matching with '" << regex.str() << "': "
- << e.what() << ":\n'" << string << "'" << LL_ENDL;
- return false;
- }
-}
-
-// Wrap boost::regex_search() with a function that doesn't throw.
-template <typename S, typename M, typename R>
-static bool regex_search_no_exc(const S& string, M& match, const R& regex)
-{
- try
- {
- return boost::regex_search(string, match, regex);
- }
- catch (const std::runtime_error& e)
- {
- LL_WARNS("LLMemoryInfo") << "error searching with '" << regex.str() << "': "
- << e.what() << ":\n'" << string << "'" << LL_ENDL;
- return false;
- }
-}
-
LLMemoryInfo::LLMemoryInfo()
{
refresh();
@@ -944,13 +1089,15 @@ LLSD LLMemoryInfo::loadStatsMap()
state.dwLength = sizeof(state);
GlobalMemoryStatusEx(&state);
- stats.add("Percent Memory use", state.dwMemoryLoad);
- stats.add("Total Physical KB", state.ullTotalPhys/1024);
- stats.add("Avail Physical KB", state.ullAvailPhys/1024);
- stats.add("Total page KB", state.ullTotalPageFile/1024);
- stats.add("Avail page KB", state.ullAvailPageFile/1024);
- stats.add("Total Virtual KB", state.ullTotalVirtual/1024);
- stats.add("Avail Virtual KB", state.ullAvailVirtual/1024);
+ DWORDLONG div = 1024;
+
+ stats.add("Percent Memory use", state.dwMemoryLoad/div);
+ stats.add("Total Physical KB", state.ullTotalPhys/div);
+ stats.add("Avail Physical KB", state.ullAvailPhys/div);
+ stats.add("Total page KB", state.ullTotalPageFile/div);
+ stats.add("Avail page KB", state.ullAvailPageFile/div);
+ stats.add("Total Virtual KB", state.ullTotalVirtual/div);
+ stats.add("Avail Virtual KB", state.ullAvailVirtual/div);
PERFORMANCE_INFORMATION perf;
perf.cb = sizeof(perf);
@@ -982,15 +1129,15 @@ LLSD LLMemoryInfo::loadStatsMap()
GetProcessMemoryInfo(GetCurrentProcess(), PPROCESS_MEMORY_COUNTERS(&pmem), sizeof(pmem));
stats.add("Page Fault Count", pmem.PageFaultCount);
- stats.add("PeakWorkingSetSize KB", pmem.PeakWorkingSetSize/1024);
- stats.add("WorkingSetSize KB", pmem.WorkingSetSize/1024);
- stats.add("QutaPeakPagedPoolUsage KB", pmem.QuotaPeakPagedPoolUsage/1024);
- stats.add("QuotaPagedPoolUsage KB", pmem.QuotaPagedPoolUsage/1024);
- stats.add("QuotaPeakNonPagedPoolUsage KB", pmem.QuotaPeakNonPagedPoolUsage/1024);
- stats.add("QuotaNonPagedPoolUsage KB", pmem.QuotaNonPagedPoolUsage/1024);
- stats.add("PagefileUsage KB", pmem.PagefileUsage/1024);
- stats.add("PeakPagefileUsage KB", pmem.PeakPagefileUsage/1024);
- stats.add("PrivateUsage KB", pmem.PrivateUsage/1024);
+ stats.add("PeakWorkingSetSize KB", pmem.PeakWorkingSetSize/div);
+ stats.add("WorkingSetSize KB", pmem.WorkingSetSize/div);
+ stats.add("QutaPeakPagedPoolUsage KB", pmem.QuotaPeakPagedPoolUsage/div);
+ stats.add("QuotaPagedPoolUsage KB", pmem.QuotaPagedPoolUsage/div);
+ stats.add("QuotaPeakNonPagedPoolUsage KB", pmem.QuotaPeakNonPagedPoolUsage/div);
+ stats.add("QuotaNonPagedPoolUsage KB", pmem.QuotaNonPagedPoolUsage/div);
+ stats.add("PagefileUsage KB", pmem.PagefileUsage/div);
+ stats.add("PeakPagefileUsage KB", pmem.PeakPagefileUsage/div);
+ stats.add("PrivateUsage KB", pmem.PrivateUsage/div);
#elif LL_DARWIN
@@ -1392,3 +1539,10 @@ BOOL gzip_file(const std::string& srcfile, const std::string& dstfile)
if (dst != NULL) gzclose(dst);
return retval;
}
+
+#if LL_DARWIN
+// disable warnings about Gestalt calls being deprecated
+// until Apple get's on the ball and provides an alternative
+//
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#endif
diff --git a/indra/llcommon/llsys.h b/indra/llcommon/llsys.h
index 739e795d3a..cfed0fff17 100644..100755
--- a/indra/llcommon/llsys.h
+++ b/indra/llcommon/llsys.h
@@ -49,6 +49,8 @@ public:
const std::string& getOSString() const;
const std::string& getOSStringSimple() const;
+ const std::string& getOSVersionString() const;
+
S32 mMajorVer;
S32 mMinorVer;
S32 mBuild;
@@ -62,6 +64,7 @@ public:
private:
std::string mOSString;
std::string mOSStringSimple;
+ std::string mOSVersionString;
};
diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp
index a6ad6b125c..60adeeaeb7 100644..100755
--- a/indra/llcommon/llthread.cpp
+++ b/indra/llcommon/llthread.cpp
@@ -67,10 +67,18 @@ LL_COMMON_API void assert_main_thread()
static U32 s_thread_id = LLThread::currentID();
if (LLThread::currentID() != s_thread_id)
{
- llerrs << "Illegal execution outside main thread." << llendl;
+ llwarns << "Illegal execution from thread id " << (S32) LLThread::currentID()
+ << " outside main thread " << (S32) s_thread_id << llendl;
}
}
+void LLThread::registerThreadID()
+{
+#if !LL_DARWIN
+ sThreadID = ++sIDIter;
+#endif
+}
+
//
// Handed to the APR thread creation function
//
@@ -114,7 +122,7 @@ LLThread::LLThread(const std::string& name, apr_pool_t *poolp) :
apr_pool_create(&mAPRPoolp, NULL); // Create a subpool for this thread
}
mRunCondition = new LLCondition(mAPRPoolp);
-
+ mDataLock = new LLMutex(mAPRPoolp);
mLocalAPRFilePoolp = NULL ;
}
@@ -173,7 +181,10 @@ void LLThread::shutdown()
}
delete mRunCondition;
- mRunCondition = 0;
+ mRunCondition = NULL;
+
+ delete mDataLock;
+ mDataLock = NULL;
if (mIsLocalPool && mAPRPoolp)
{
@@ -242,28 +253,30 @@ bool LLThread::runCondition(void)
// Stop thread execution if requested until unpaused.
void LLThread::checkPause()
{
- mRunCondition->lock();
+ mDataLock->lock();
// This is in a while loop because the pthread API allows for spurious wakeups.
while(shouldSleep())
{
+ mDataLock->unlock();
mRunCondition->wait(); // unlocks mRunCondition
+ mDataLock->lock();
// mRunCondition is locked when the thread wakes up
}
- mRunCondition->unlock();
+ mDataLock->unlock();
}
//============================================================================
void LLThread::setQuitting()
{
- mRunCondition->lock();
+ mDataLock->lock();
if (mStatus == RUNNING)
{
mStatus = QUITTING;
}
- mRunCondition->unlock();
+ mDataLock->unlock();
wake();
}
@@ -285,12 +298,12 @@ void LLThread::yield()
void LLThread::wake()
{
- mRunCondition->lock();
+ mDataLock->lock();
if(!shouldSleep())
{
mRunCondition->signal();
}
- mRunCondition->unlock();
+ mDataLock->unlock();
}
void LLThread::wakeLocked()
@@ -481,6 +494,11 @@ LLThreadSafeRefCount::LLThreadSafeRefCount() :
{
}
+LLThreadSafeRefCount::LLThreadSafeRefCount(const LLThreadSafeRefCount& src)
+{
+ mRef = 0;
+}
+
LLThreadSafeRefCount::~LLThreadSafeRefCount()
{
if (mRef != 0)
@@ -489,6 +507,7 @@ LLThreadSafeRefCount::~LLThreadSafeRefCount()
}
}
+
//============================================================================
LLResponder::~LLResponder()
diff --git a/indra/llcommon/llthread.h b/indra/llcommon/llthread.h
index b52e70ab2e..f51d985b5f 100644..100755
--- a/indra/llcommon/llthread.h
+++ b/indra/llcommon/llthread.h
@@ -30,6 +30,7 @@
#include "llapp.h"
#include "llapr.h"
#include "apr_thread_cond.h"
+#include "boost/intrusive_ptr.hpp"
class LLThread;
class LLMutex;
@@ -88,6 +89,11 @@ public:
U32 getID() const { return mID; }
+ // Called by threads *not* created via LLThread to register some
+ // internal state used by LLMutex. You must call this once early
+ // in the running thread to prevent collisions with the main thread.
+ static void registerThreadID();
+
private:
BOOL mPaused;
@@ -97,6 +103,7 @@ private:
protected:
std::string mName;
LLCondition* mRunCondition;
+ LLMutex* mDataLock;
apr_thread_t *mAPRThreadp;
apr_pool_t *mAPRPoolp;
@@ -122,15 +129,15 @@ protected:
inline void unlockData();
// This is the predicate that decides whether the thread should sleep.
- // It should only be called with mRunCondition locked, since the virtual runCondition() function may need to access
+ // It should only be called with mDataLock locked, since the virtual runCondition() function may need to access
// data structures that are thread-unsafe.
bool shouldSleep(void) { return (mStatus == RUNNING) && (isPaused() || (!runCondition())); }
// To avoid spurious signals (and the associated context switches) when the condition may or may not have changed, you can do the following:
- // mRunCondition->lock();
+ // mDataLock->lock();
// if(!shouldSleep())
// mRunCondition->signal();
- // mRunCondition->unlock();
+ // mDataLock->unlock();
};
//============================================================================
@@ -205,12 +212,12 @@ private:
void LLThread::lockData()
{
- mRunCondition->lock();
+ mDataLock->lock();
}
void LLThread::unlockData()
{
- mRunCondition->unlock();
+ mDataLock->unlock();
}
@@ -227,45 +234,63 @@ public:
private:
static LLMutex* sMutex;
-private:
- LLThreadSafeRefCount(const LLThreadSafeRefCount&); // not implemented
- LLThreadSafeRefCount&operator=(const LLThreadSafeRefCount&); // not implemented
-
protected:
virtual ~LLThreadSafeRefCount(); // use unref()
public:
LLThreadSafeRefCount();
-
+ LLThreadSafeRefCount(const LLThreadSafeRefCount&);
+ LLThreadSafeRefCount& operator=(const LLThreadSafeRefCount& ref)
+ {
+ mRef = 0;
+ return *this;
+ }
+
void ref()
{
- if (sMutex) sMutex->lock();
mRef++;
- if (sMutex) sMutex->unlock();
}
- S32 unref()
+ void unref()
{
llassert(mRef >= 1);
- if (sMutex) sMutex->lock();
- S32 res = --mRef;
- if (sMutex) sMutex->unlock();
- if (0 == res)
- {
- delete this;
- return 0;
+ if ((--mRef) == 0) // See note in llapr.h on atomic decrement operator return value.
+ {
+ // If we hit zero, the caller should be the only smart pointer owning the object and we can delete it.
+ // It is technically possible for a vanilla pointer to mess this up, or another thread to
+ // jump in, find this object, create another smart pointer and end up dangling, but if
+ // the code is that bad and not thread-safe, it's trouble already.
+ delete this;
}
- return res;
- }
+ }
+
S32 getNumRefs() const
{
- return mRef;
+ const S32 currentVal = mRef.CurrentValue();
+ return currentVal;
}
private:
- S32 mRef;
+ LLAtomic32< S32 > mRef;
};
+
+/**
+ * intrusive pointer support for LLThreadSafeRefCount
+ * this allows you to use boost::intrusive_ptr with any LLThreadSafeRefCount-derived type
+ */
+namespace boost
+{
+ inline void intrusive_ptr_add_ref(LLThreadSafeRefCount* p)
+ {
+ p->ref();
+ }
+
+ inline void intrusive_ptr_release(LLThreadSafeRefCount* p)
+ {
+ p->unref();
+ }
+};
//============================================================================
// Simple responder for self destructing callbacks
@@ -280,4 +305,6 @@ public:
//============================================================================
+extern LL_COMMON_API void assert_main_thread();
+
#endif // LL_LLTHREAD_H
diff --git a/indra/llcommon/llthreadsafequeue.cpp b/indra/llcommon/llthreadsafequeue.cpp
index 8a73e632a9..8a73e632a9 100644..100755
--- a/indra/llcommon/llthreadsafequeue.cpp
+++ b/indra/llcommon/llthreadsafequeue.cpp
diff --git a/indra/llcommon/llthreadsafequeue.h b/indra/llcommon/llthreadsafequeue.h
index 58cac38769..58cac38769 100644..100755
--- a/indra/llcommon/llthreadsafequeue.h
+++ b/indra/llcommon/llthreadsafequeue.h
diff --git a/indra/llcommon/lltimer.cpp b/indra/llcommon/lltimer.cpp
index 9ebc6de7f4..9ebc6de7f4 100644..100755
--- a/indra/llcommon/lltimer.cpp
+++ b/indra/llcommon/lltimer.cpp
diff --git a/indra/llcommon/lltimer.h b/indra/llcommon/lltimer.h
index 513de0605d..513de0605d 100644..100755
--- a/indra/llcommon/lltimer.h
+++ b/indra/llcommon/lltimer.h
diff --git a/indra/llcommon/lltreeiterators.h b/indra/llcommon/lltreeiterators.h
index ba861ae70b..ba861ae70b 100644..100755
--- a/indra/llcommon/lltreeiterators.h
+++ b/indra/llcommon/lltreeiterators.h
diff --git a/indra/llcommon/lltypeinfolookup.h b/indra/llcommon/lltypeinfolookup.h
new file mode 100755
index 0000000000..0b6862444e
--- /dev/null
+++ b/indra/llcommon/lltypeinfolookup.h
@@ -0,0 +1,117 @@
+/**
+ * @file lltypeinfolookup.h
+ * @author Nat Goodspeed
+ * @date 2012-04-08
+ * @brief Template data structure like std::map<std::type_info*, T>
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Copyright (c) 2012, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+#if ! defined(LL_LLTYPEINFOLOOKUP_H)
+#define LL_LLTYPEINFOLOOKUP_H
+
+#include <boost/unordered_map.hpp>
+#include <boost/functional/hash.hpp>
+#include <boost/optional.hpp>
+#include <functional> // std::binary_function
+#include <typeinfo>
+
+/**
+ * The following helper classes are based on the Boost.Unordered documentation:
+ * http://www.boost.org/doc/libs/1_45_0/doc/html/unordered/hash_equality.html
+ */
+
+/**
+ * Compute hash for a string passed as const char*
+ */
+struct const_char_star_hash: public std::unary_function<const char*, std::size_t>
+{
+ std::size_t operator()(const char* str) const
+ {
+ std::size_t seed = 0;
+ for ( ; *str; ++str)
+ {
+ boost::hash_combine(seed, *str);
+ }
+ return seed;
+ }
+};
+
+/**
+ * Compute equality for strings passed as const char*
+ *
+ * I (nat) suspect that this is where the default behavior breaks for the
+ * const char* values returned from std::type_info::name(). If you compare the
+ * two const char* pointer values, as a naive, unspecialized implementation
+ * will surely do, they'll compare unequal.
+ */
+struct const_char_star_equal: public std::binary_function<const char*, const char*, bool>
+{
+ bool operator()(const char* lhs, const char* rhs) const
+ {
+ return strcmp(lhs, rhs) == 0;
+ }
+};
+
+/**
+ * LLTypeInfoLookup is specifically designed for use cases for which you might
+ * consider std::map<std::type_info*, VALUE>. We have several such data
+ * structures in the viewer. The trouble with them is that at least on Linux,
+ * you can't rely on always getting the same std::type_info* for a given type:
+ * different load modules will produce different std::type_info*.
+ * LLTypeInfoLookup contains a workaround to address this issue.
+ *
+ * The API deliberately diverges from std::map in several respects:
+ * * It avoids iterators, not only begin()/end() but also as return values
+ * from insert() and find(). This bypasses transform_iterator overhead.
+ * * Since we literally use compile-time types as keys, the essential insert()
+ * and find() methods accept the key type as a @em template parameter,
+ * accepting and returning value_type as a normal runtime value. This is to
+ * permit future optimization (e.g. compile-time type hashing) without
+ * changing the API.
+ */
+template <typename VALUE>
+class LLTypeInfoLookup
+{
+ // Use this for our underlying implementation: lookup by
+ // std::type_info::name() string. This is one of the rare cases in which I
+ // dare use const char* directly, rather than std::string, because I'm
+ // sure that every value returned by std::type_info::name() is static.
+ // HOWEVER, specify our own hash + equality functors: naively comparing
+ // distinct const char* values won't work.
+ typedef boost::unordered_map<const char*, VALUE,
+ const_char_star_hash, const_char_star_equal> impl_map_type;
+
+public:
+ typedef VALUE value_type;
+
+ LLTypeInfoLookup() {}
+
+ bool empty() const { return mMap.empty(); }
+ std::size_t size() const { return mMap.size(); }
+
+ template <typename KEY>
+ bool insert(const value_type& value)
+ {
+ // Obtain and store the std::type_info::name() string as the key.
+ // Return just the bool from std::map::insert()'s return pair.
+ return mMap.insert(typename impl_map_type::value_type(typeid(KEY).name(), value)).second;
+ }
+
+ template <typename KEY>
+ boost::optional<value_type> find() const
+ {
+ // Use the std::type_info::name() string as the key.
+ typename impl_map_type::const_iterator found = mMap.find(typeid(KEY).name());
+ if (found == mMap.end())
+ return boost::optional<value_type>();
+ return found->second;
+ }
+
+private:
+ impl_map_type mMap;
+};
+
+#endif /* ! defined(LL_LLTYPEINFOLOOKUP_H) */
diff --git a/indra/llcommon/lluri.cpp b/indra/llcommon/lluri.cpp
index b39ea0c6f2..37f5b3d6a3 100644..100755
--- a/indra/llcommon/lluri.cpp
+++ b/indra/llcommon/lluri.cpp
@@ -37,6 +37,8 @@
// system includes
#include <boost/tokenizer.hpp>
+#include <boost/algorithm/string/find_iterator.hpp>
+#include <boost/algorithm/string/finder.hpp>
void encode_character(std::ostream& ostr, std::string::value_type val)
{
@@ -127,11 +129,30 @@ std::string LLURI::unescape(const std::string& str)
{
++it;
if(it == end) break;
- U8 c = hex_as_nybble(*it++);
- c = c << 4;
- if (it == end) break;
- c |= hex_as_nybble(*it);
- ostr.put((char)c);
+
+ if(is_char_hex(*it))
+ {
+ U8 c = hex_as_nybble(*it++);
+
+ c = c << 4;
+ if (it == end) break;
+
+ if(is_char_hex(*it))
+ {
+ c |= hex_as_nybble(*it);
+ ostr.put((char)c);
+ }
+ else
+ {
+ ostr.put((char)c);
+ ostr.put(*it);
+ }
+ }
+ else
+ {
+ ostr.put('%');
+ ostr.put(*it);
+ }
}
else
{
@@ -317,7 +338,7 @@ LLURI LLURI::buildHTTP(const std::string& prefix,
const LLSD& path)
{
LLURI result;
-
+
// TODO: deal with '/' '?' '#' in host_port
if (prefix.find("://") != prefix.npos)
{
@@ -342,15 +363,41 @@ LLURI LLURI::buildHTTP(const std::string& prefix,
result.mEscapedPath += "/" + escapePathComponent(it->asString());
}
}
- else if(path.isString())
+ else if (path.isString())
{
- result.mEscapedPath += "/" + escapePathComponent(path.asString());
+ std::string pathstr(path);
+ // Trailing slash is significant in HTTP land. If caller specified,
+ // make a point of preserving.
+ std::string last_slash;
+ std::string::size_type len(pathstr.length());
+ if (len && pathstr[len-1] == '/')
+ {
+ last_slash = "/";
+ }
+
+ // Escape every individual path component, recombining with slashes.
+ for (boost::split_iterator<std::string::const_iterator>
+ ti(pathstr, boost::first_finder("/")), tend;
+ ti != tend; ++ti)
+ {
+ // Eliminate a leading slash or duplicate slashes anywhere. (Extra
+ // slashes show up here as empty components.) This test also
+ // eliminates a trailing slash, hence last_slash above.
+ if (! ti->empty())
+ {
+ result.mEscapedPath
+ += "/" + escapePathComponent(std::string(ti->begin(), ti->end()));
+ }
+ }
+
+ // Reinstate trailing slash, if any.
+ result.mEscapedPath += last_slash;
}
else if(path.isUndefined())
{
// do nothing
}
- else
+ else
{
llwarns << "Valid path arguments to buildHTTP are array, string, or undef, you passed type"
<< path.type() << llendl;
diff --git a/indra/llcommon/lluri.h b/indra/llcommon/lluri.h
index c82a666e48..c82a666e48 100644..100755
--- a/indra/llcommon/lluri.h
+++ b/indra/llcommon/lluri.h
diff --git a/indra/llcommon/lluuid.cpp b/indra/llcommon/lluuid.cpp
index 5d452ac4e4..0aaa50d231 100644..100755
--- a/indra/llcommon/lluuid.cpp
+++ b/indra/llcommon/lluuid.cpp
@@ -44,10 +44,16 @@
#include "llmd5.h"
#include "llstring.h"
#include "lltimer.h"
+#include "llthread.h"
const LLUUID LLUUID::null;
const LLTransactionID LLTransactionID::tnull;
+// static
+LLMutex * LLUUID::mMutex = NULL;
+
+
+
/*
NOT DONE YET!!!
@@ -734,6 +740,7 @@ void LLUUID::getCurrentTime(uuid_time_t *timestamp)
getSystemTime(&time_last);
uuids_this_tick = uuids_per_tick;
init = TRUE;
+ mMutex = new LLMutex(NULL);
}
uuid_time_t time_now = {0,0};
@@ -785,6 +792,7 @@ void LLUUID::generate()
#endif
if (!has_init)
{
+ has_init = 1;
if (getNodeID(node_id) <= 0)
{
get_random_bytes(node_id, 6);
@@ -806,18 +814,24 @@ void LLUUID::generate()
#else
clock_seq = (U16)ll_rand(65536);
#endif
- has_init = 1;
}
// get current time
getCurrentTime(&timestamp);
+ U16 our_clock_seq = clock_seq;
- // if clock went backward change clockseq
- if (cmpTime(&timestamp, &time_last) == -1) {
+ // if clock hasn't changed or went backward, change clockseq
+ if (cmpTime(&timestamp, &time_last) != 1)
+ {
+ LLMutexLock lock(mMutex);
clock_seq = (clock_seq + 1) & 0x3FFF;
- if (clock_seq == 0) clock_seq++;
+ if (clock_seq == 0)
+ clock_seq++;
+ our_clock_seq = clock_seq; // Ensure we're using a different clock_seq value from previous time
}
+ time_last = timestamp;
+
memcpy(mData+10, node_id, 6); /* Flawfinder: ignore */
U32 tmp;
tmp = timestamp.low;
@@ -839,7 +853,8 @@ void LLUUID::generate()
tmp >>= 8;
mData[6] = (unsigned char) tmp;
- tmp = clock_seq;
+ tmp = our_clock_seq;
+
mData[9] = (unsigned char) tmp;
tmp >>= 8;
mData[8] = (unsigned char) tmp;
@@ -849,8 +864,6 @@ void LLUUID::generate()
md5_uuid.update(mData,16);
md5_uuid.finalize();
md5_uuid.raw_digest(mData);
-
- time_last = timestamp;
}
void LLUUID::generate(const std::string& hash_string)
@@ -864,8 +877,14 @@ U32 LLUUID::getRandomSeed()
static unsigned char seed[16]; /* Flawfinder: ignore */
getNodeID(&seed[0]);
- seed[6]='\0';
- seed[7]='\0';
+
+ // Incorporate the pid into the seed to prevent
+ // processes that start on the same host at the same
+ // time from generating the same seed.
+ pid_t pid = LLApp::getPid();
+
+ seed[6]=(unsigned char)(pid >> 8);
+ seed[7]=(unsigned char)(pid);
getSystemTime((uuid_time_t *)(&seed[8]));
LLMD5 md5_seed;
@@ -922,3 +941,174 @@ LLAssetID LLTransactionID::makeAssetID(const LLUUID& session) const
}
return result;
}
+
+// Construct
+LLUUID::LLUUID()
+{
+ setNull();
+}
+
+
+// Faster than copying from memory
+ void LLUUID::setNull()
+{
+ U32 *word = (U32 *)mData;
+ word[0] = 0;
+ word[1] = 0;
+ word[2] = 0;
+ word[3] = 0;
+}
+
+
+// Compare
+ bool LLUUID::operator==(const LLUUID& rhs) const
+{
+ U32 *tmp = (U32 *)mData;
+ U32 *rhstmp = (U32 *)rhs.mData;
+ // Note: binary & to avoid branching
+ return
+ (tmp[0] == rhstmp[0]) &
+ (tmp[1] == rhstmp[1]) &
+ (tmp[2] == rhstmp[2]) &
+ (tmp[3] == rhstmp[3]);
+}
+
+
+ bool LLUUID::operator!=(const LLUUID& rhs) const
+{
+ U32 *tmp = (U32 *)mData;
+ U32 *rhstmp = (U32 *)rhs.mData;
+ // Note: binary | to avoid branching
+ return
+ (tmp[0] != rhstmp[0]) |
+ (tmp[1] != rhstmp[1]) |
+ (tmp[2] != rhstmp[2]) |
+ (tmp[3] != rhstmp[3]);
+}
+
+/*
+// JC: This is dangerous. It allows UUIDs to be cast automatically
+// to integers, among other things. Use isNull() or notNull().
+ LLUUID::operator bool() const
+{
+ U32 *word = (U32 *)mData;
+ return (word[0] | word[1] | word[2] | word[3]) > 0;
+}
+*/
+
+ BOOL LLUUID::notNull() const
+{
+ U32 *word = (U32 *)mData;
+ return (word[0] | word[1] | word[2] | word[3]) > 0;
+}
+
+// Faster than == LLUUID::null because doesn't require
+// as much memory access.
+ BOOL LLUUID::isNull() const
+{
+ U32 *word = (U32 *)mData;
+ // If all bits are zero, return !0 == TRUE
+ return !(word[0] | word[1] | word[2] | word[3]);
+}
+
+// Copy constructor
+ LLUUID::LLUUID(const LLUUID& rhs)
+{
+ U32 *tmp = (U32 *)mData;
+ U32 *rhstmp = (U32 *)rhs.mData;
+ tmp[0] = rhstmp[0];
+ tmp[1] = rhstmp[1];
+ tmp[2] = rhstmp[2];
+ tmp[3] = rhstmp[3];
+}
+
+ LLUUID::~LLUUID()
+{
+}
+
+// Assignment
+ LLUUID& LLUUID::operator=(const LLUUID& rhs)
+{
+ // No need to check the case where this==&rhs. The branch is slower than the write.
+ U32 *tmp = (U32 *)mData;
+ U32 *rhstmp = (U32 *)rhs.mData;
+ tmp[0] = rhstmp[0];
+ tmp[1] = rhstmp[1];
+ tmp[2] = rhstmp[2];
+ tmp[3] = rhstmp[3];
+
+ return *this;
+}
+
+
+ LLUUID::LLUUID(const char *in_string)
+{
+ if (!in_string || in_string[0] == 0)
+ {
+ setNull();
+ return;
+ }
+
+ set(in_string);
+}
+
+ LLUUID::LLUUID(const std::string& in_string)
+{
+ if (in_string.empty())
+ {
+ setNull();
+ return;
+ }
+
+ set(in_string);
+}
+
+// IW: DON'T "optimize" these w/ U32s or you'll scoogie the sort order
+// IW: this will make me very sad
+ bool LLUUID::operator<(const LLUUID &rhs) const
+{
+ U32 i;
+ for( i = 0; i < (UUID_BYTES - 1); i++ )
+ {
+ if( mData[i] != rhs.mData[i] )
+ {
+ return (mData[i] < rhs.mData[i]);
+ }
+ }
+ return (mData[UUID_BYTES - 1] < rhs.mData[UUID_BYTES - 1]);
+}
+
+ bool LLUUID::operator>(const LLUUID &rhs) const
+{
+ U32 i;
+ for( i = 0; i < (UUID_BYTES - 1); i++ )
+ {
+ if( mData[i] != rhs.mData[i] )
+ {
+ return (mData[i] > rhs.mData[i]);
+ }
+ }
+ return (mData[UUID_BYTES - 1] > rhs.mData[UUID_BYTES - 1]);
+}
+
+ U16 LLUUID::getCRC16() const
+{
+ // A UUID is 16 bytes, or 8 shorts.
+ U16 *short_data = (U16*)mData;
+ U16 out = 0;
+ out += short_data[0];
+ out += short_data[1];
+ out += short_data[2];
+ out += short_data[3];
+ out += short_data[4];
+ out += short_data[5];
+ out += short_data[6];
+ out += short_data[7];
+ return out;
+}
+
+ U32 LLUUID::getCRC32() const
+{
+ U32 *tmp = (U32*)mData;
+ return tmp[0] + tmp[1] + tmp[2] + tmp[3];
+}
diff --git a/indra/llcommon/lluuid.h b/indra/llcommon/lluuid.h
index 726be4a82d..7889828c85 100644..100755
--- a/indra/llcommon/lluuid.h
+++ b/indra/llcommon/lluuid.h
@@ -31,6 +31,8 @@
#include "stdtypes.h"
#include "llpreprocessor.h"
+class LLMutex;
+
const S32 UUID_BYTES = 16;
const S32 UUID_WORDS = 4;
const S32 UUID_STR_LENGTH = 37; // actually wrong, should be 36 and use size below
@@ -118,6 +120,7 @@ public:
static BOOL validate(const std::string& in_string); // Validate that the UUID string is legal.
static const LLUUID null;
+ static LLMutex * mMutex;
static U32 getRandomSeed();
static S32 getNodeID(unsigned char * node_id);
@@ -129,177 +132,6 @@ public:
typedef std::vector<LLUUID> uuid_vec_t;
-// Construct
-inline LLUUID::LLUUID()
-{
- setNull();
-}
-
-
-// Faster than copying from memory
-inline void LLUUID::setNull()
-{
- U32 *word = (U32 *)mData;
- word[0] = 0;
- word[1] = 0;
- word[2] = 0;
- word[3] = 0;
-}
-
-
-// Compare
-inline bool LLUUID::operator==(const LLUUID& rhs) const
-{
- U32 *tmp = (U32 *)mData;
- U32 *rhstmp = (U32 *)rhs.mData;
- // Note: binary & to avoid branching
- return
- (tmp[0] == rhstmp[0]) &
- (tmp[1] == rhstmp[1]) &
- (tmp[2] == rhstmp[2]) &
- (tmp[3] == rhstmp[3]);
-}
-
-
-inline bool LLUUID::operator!=(const LLUUID& rhs) const
-{
- U32 *tmp = (U32 *)mData;
- U32 *rhstmp = (U32 *)rhs.mData;
- // Note: binary | to avoid branching
- return
- (tmp[0] != rhstmp[0]) |
- (tmp[1] != rhstmp[1]) |
- (tmp[2] != rhstmp[2]) |
- (tmp[3] != rhstmp[3]);
-}
-
-/*
-// JC: This is dangerous. It allows UUIDs to be cast automatically
-// to integers, among other things. Use isNull() or notNull().
-inline LLUUID::operator bool() const
-{
- U32 *word = (U32 *)mData;
- return (word[0] | word[1] | word[2] | word[3]) > 0;
-}
-*/
-
-inline BOOL LLUUID::notNull() const
-{
- U32 *word = (U32 *)mData;
- return (word[0] | word[1] | word[2] | word[3]) > 0;
-}
-
-// Faster than == LLUUID::null because doesn't require
-// as much memory access.
-inline BOOL LLUUID::isNull() const
-{
- U32 *word = (U32 *)mData;
- // If all bits are zero, return !0 == TRUE
- return !(word[0] | word[1] | word[2] | word[3]);
-}
-
-// Copy constructor
-inline LLUUID::LLUUID(const LLUUID& rhs)
-{
- U32 *tmp = (U32 *)mData;
- U32 *rhstmp = (U32 *)rhs.mData;
- tmp[0] = rhstmp[0];
- tmp[1] = rhstmp[1];
- tmp[2] = rhstmp[2];
- tmp[3] = rhstmp[3];
-}
-
-inline LLUUID::~LLUUID()
-{
-}
-
-// Assignment
-inline LLUUID& LLUUID::operator=(const LLUUID& rhs)
-{
- // No need to check the case where this==&rhs. The branch is slower than the write.
- U32 *tmp = (U32 *)mData;
- U32 *rhstmp = (U32 *)rhs.mData;
- tmp[0] = rhstmp[0];
- tmp[1] = rhstmp[1];
- tmp[2] = rhstmp[2];
- tmp[3] = rhstmp[3];
-
- return *this;
-}
-
-
-inline LLUUID::LLUUID(const char *in_string)
-{
- if (!in_string || in_string[0] == 0)
- {
- setNull();
- return;
- }
-
- set(in_string);
-}
-
-inline LLUUID::LLUUID(const std::string& in_string)
-{
- if (in_string.empty())
- {
- setNull();
- return;
- }
-
- set(in_string);
-}
-
-// IW: DON'T "optimize" these w/ U32s or you'll scoogie the sort order
-// IW: this will make me very sad
-inline bool LLUUID::operator<(const LLUUID &rhs) const
-{
- U32 i;
- for( i = 0; i < (UUID_BYTES - 1); i++ )
- {
- if( mData[i] != rhs.mData[i] )
- {
- return (mData[i] < rhs.mData[i]);
- }
- }
- return (mData[UUID_BYTES - 1] < rhs.mData[UUID_BYTES - 1]);
-}
-
-inline bool LLUUID::operator>(const LLUUID &rhs) const
-{
- U32 i;
- for( i = 0; i < (UUID_BYTES - 1); i++ )
- {
- if( mData[i] != rhs.mData[i] )
- {
- return (mData[i] > rhs.mData[i]);
- }
- }
- return (mData[UUID_BYTES - 1] > rhs.mData[UUID_BYTES - 1]);
-}
-
-inline U16 LLUUID::getCRC16() const
-{
- // A UUID is 16 bytes, or 8 shorts.
- U16 *short_data = (U16*)mData;
- U16 out = 0;
- out += short_data[0];
- out += short_data[1];
- out += short_data[2];
- out += short_data[3];
- out += short_data[4];
- out += short_data[5];
- out += short_data[6];
- out += short_data[7];
- return out;
-}
-
-inline U32 LLUUID::getCRC32() const
-{
- U32 *tmp = (U32*)mData;
- return tmp[0] + tmp[1] + tmp[2] + tmp[3];
-}
-
// Helper structure for ordering lluuids in stl containers.
// eg: std::map<LLUUID, LLWidget*, lluuid_less> widget_map;
@@ -329,3 +161,5 @@ public:
};
#endif
+
+
diff --git a/indra/llcommon/lluuidhashmap.h b/indra/llcommon/lluuidhashmap.h
index e294670030..e294670030 100644..100755
--- a/indra/llcommon/lluuidhashmap.h
+++ b/indra/llcommon/lluuidhashmap.h
diff --git a/indra/llcommon/llversionserver.h b/indra/llcommon/llversionserver.h
index b19ba3bf74..ef68a0eaf5 100644..100755
--- a/indra/llcommon/llversionserver.h
+++ b/indra/llcommon/llversionserver.h
@@ -30,7 +30,7 @@
const S32 LL_VERSION_MAJOR = 2;
const S32 LL_VERSION_MINOR = 1;
const S32 LL_VERSION_PATCH = 0;
-const S32 LL_VERSION_BUILD = 13828;
+const S32 LL_VERSION_BUILD = 264760;
const char * const LL_CHANNEL = "Second Life Server";
diff --git a/indra/llcommon/llversionviewer.h b/indra/llcommon/llversionviewer.h
deleted file mode 100644
index fafc750690..0000000000
--- a/indra/llcommon/llversionviewer.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/**
- * @file llversionviewer.h
- * @brief
- *
- * $LicenseInfo:firstyear=2002&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$
- */
-
-#ifndef LL_LLVERSIONVIEWER_H
-#define LL_LLVERSIONVIEWER_H
-
-const S32 LL_VERSION_MAJOR = 3;
-const S32 LL_VERSION_MINOR = 3;
-const S32 LL_VERSION_PATCH = 2;
-const S32 LL_VERSION_BUILD = 0;
-
-const char * const LL_CHANNEL = "Second Life Developer";
-
-#if LL_DARWIN
-const char * const LL_VERSION_BUNDLE_ID = "com.secondlife.indra.viewer";
-#endif
-
-#endif
diff --git a/indra/llcommon/llworkerthread.cpp b/indra/llcommon/llworkerthread.cpp
index 3d05a30ac2..3d05a30ac2 100644..100755
--- a/indra/llcommon/llworkerthread.cpp
+++ b/indra/llcommon/llworkerthread.cpp
diff --git a/indra/llcommon/llworkerthread.h b/indra/llcommon/llworkerthread.h
index be46394d6e..be46394d6e 100644..100755
--- a/indra/llcommon/llworkerthread.h
+++ b/indra/llcommon/llworkerthread.h
diff --git a/indra/llcommon/metaclass.cpp b/indra/llcommon/metaclass.cpp
index 5e403511cf..5e403511cf 100644..100755
--- a/indra/llcommon/metaclass.cpp
+++ b/indra/llcommon/metaclass.cpp
diff --git a/indra/llcommon/metaclass.h b/indra/llcommon/metaclass.h
index 626757d58d..626757d58d 100644..100755
--- a/indra/llcommon/metaclass.h
+++ b/indra/llcommon/metaclass.h
diff --git a/indra/llcommon/metaclasst.h b/indra/llcommon/metaclasst.h
index b9a7ae219d..b9a7ae219d 100644..100755
--- a/indra/llcommon/metaclasst.h
+++ b/indra/llcommon/metaclasst.h
diff --git a/indra/llcommon/metaproperty.cpp b/indra/llcommon/metaproperty.cpp
index 98d850bf1e..98d850bf1e 100644..100755
--- a/indra/llcommon/metaproperty.cpp
+++ b/indra/llcommon/metaproperty.cpp
diff --git a/indra/llcommon/metaproperty.h b/indra/llcommon/metaproperty.h
index bd5bb1a30f..bd5bb1a30f 100644..100755
--- a/indra/llcommon/metaproperty.h
+++ b/indra/llcommon/metaproperty.h
diff --git a/indra/llcommon/metapropertyt.h b/indra/llcommon/metapropertyt.h
index 7a36c161da..7a36c161da 100644..100755
--- a/indra/llcommon/metapropertyt.h
+++ b/indra/llcommon/metapropertyt.h
diff --git a/indra/llcommon/reflective.cpp b/indra/llcommon/reflective.cpp
index 2cc0e7e1f2..2cc0e7e1f2 100644..100755
--- a/indra/llcommon/reflective.cpp
+++ b/indra/llcommon/reflective.cpp
diff --git a/indra/llcommon/reflective.h b/indra/llcommon/reflective.h
index da5c5a2630..da5c5a2630 100644..100755
--- a/indra/llcommon/reflective.h
+++ b/indra/llcommon/reflective.h
diff --git a/indra/llcommon/reflectivet.h b/indra/llcommon/reflectivet.h
index 958921f23e..958921f23e 100644..100755
--- a/indra/llcommon/reflectivet.h
+++ b/indra/llcommon/reflectivet.h
diff --git a/indra/llcommon/roles_constants.h b/indra/llcommon/roles_constants.h
index effd15ea72..effd15ea72 100644..100755
--- a/indra/llcommon/roles_constants.h
+++ b/indra/llcommon/roles_constants.h
diff --git a/indra/llcommon/stdenums.h b/indra/llcommon/stdenums.h
index 40b3364b36..efcbe76795 100644..100755
--- a/indra/llcommon/stdenums.h
+++ b/indra/llcommon/stdenums.h
@@ -51,7 +51,8 @@ enum EDragAndDropType
DAD_LINK = 14,
DAD_MESH = 15,
DAD_WIDGET = 16,
- DAD_COUNT = 17, // number of types in this enum
+ DAD_PERSON = 17,
+ DAD_COUNT = 18, // number of types in this enum
};
// Reasons for drags to be denied.
diff --git a/indra/llcommon/stdtypes.h b/indra/llcommon/stdtypes.h
index bf3f3f9ee8..bf3f3f9ee8 100644..100755
--- a/indra/llcommon/stdtypes.h
+++ b/indra/llcommon/stdtypes.h
diff --git a/indra/llcommon/string_table.h b/indra/llcommon/string_table.h
index fe6416fb50..fe6416fb50 100644..100755
--- a/indra/llcommon/string_table.h
+++ b/indra/llcommon/string_table.h
diff --git a/indra/llcommon/stringize.h b/indra/llcommon/stringize.h
index 72f2e58ce1..72f2e58ce1 100644..100755
--- a/indra/llcommon/stringize.h
+++ b/indra/llcommon/stringize.h
diff --git a/indra/llcommon/tests/StringVec.h b/indra/llcommon/tests/StringVec.h
new file mode 100755
index 0000000000..a380b00a05
--- /dev/null
+++ b/indra/llcommon/tests/StringVec.h
@@ -0,0 +1,37 @@
+/**
+ * @file StringVec.h
+ * @author Nat Goodspeed
+ * @date 2012-02-24
+ * @brief Extend TUT ensure_equals() to handle std::vector<std::string>
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Copyright (c) 2012, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+#if ! defined(LL_STRINGVEC_H)
+#define LL_STRINGVEC_H
+
+#include <vector>
+#include <string>
+#include <iostream>
+
+typedef std::vector<std::string> StringVec;
+
+std::ostream& operator<<(std::ostream& out, const StringVec& strings)
+{
+ out << '(';
+ StringVec::const_iterator begin(strings.begin()), end(strings.end());
+ if (begin != end)
+ {
+ out << '"' << *begin << '"';
+ while (++begin != end)
+ {
+ out << ", \"" << *begin << '"';
+ }
+ }
+ out << ')';
+ return out;
+}
+
+#endif /* ! defined(LL_STRINGVEC_H) */
diff --git a/indra/llcommon/tests/bitpack_test.cpp b/indra/llcommon/tests/bitpack_test.cpp
index 05289881d0..afc0c18cd0 100644..100755
--- a/indra/llcommon/tests/bitpack_test.cpp
+++ b/indra/llcommon/tests/bitpack_test.cpp
@@ -71,7 +71,6 @@ namespace tut
U8 packbuffer[255];
U8 unpackbuffer[255];
int pack_bufsize = 0;
- int unpack_bufsize = 0;
LLBitPack bitpack(packbuffer, 255);
@@ -81,19 +80,19 @@ namespace tut
pack_bufsize = bitpack.flushBitPack();
LLBitPack bitunpack(packbuffer, pack_bufsize*8);
- unpack_bufsize = bitunpack.bitUnpack(&unpackbuffer[0], 8);
+ bitunpack.bitUnpack(&unpackbuffer[0], 8);
ensure("bitPack: individual unpack: 0", unpackbuffer[0] == (U8) str[0]);
- unpack_bufsize = bitunpack.bitUnpack(&unpackbuffer[0], 8);
+ bitunpack.bitUnpack(&unpackbuffer[0], 8);
ensure("bitPack: individual unpack: 1", unpackbuffer[0] == (U8) str[1]);
- unpack_bufsize = bitunpack.bitUnpack(&unpackbuffer[0], 8);
+ bitunpack.bitUnpack(&unpackbuffer[0], 8);
ensure("bitPack: individual unpack: 2", unpackbuffer[0] == (U8) str[2]);
- unpack_bufsize = bitunpack.bitUnpack(&unpackbuffer[0], 8);
+ bitunpack.bitUnpack(&unpackbuffer[0], 8);
ensure("bitPack: individual unpack: 3", unpackbuffer[0] == (U8) str[3]);
- unpack_bufsize = bitunpack.bitUnpack(&unpackbuffer[0], 8);
+ bitunpack.bitUnpack(&unpackbuffer[0], 8);
ensure("bitPack: individual unpack: 4", unpackbuffer[0] == (U8) str[4]);
- unpack_bufsize = bitunpack.bitUnpack(&unpackbuffer[0], 8);
+ bitunpack.bitUnpack(&unpackbuffer[0], 8);
ensure("bitPack: individual unpack: 5", unpackbuffer[0] == (U8) str[5]);
- unpack_bufsize = bitunpack.bitUnpack(unpackbuffer, 8*4); // Life
+ bitunpack.bitUnpack(unpackbuffer, 8*4); // Life
ensure_memory_matches("bitPack: 4 bytes unpack:", unpackbuffer, 4, str+6, 4);
}
diff --git a/indra/llcommon/tests/commonmisc_test.cpp b/indra/llcommon/tests/commonmisc_test.cpp
index b115c153c1..b115c153c1 100644..100755
--- a/indra/llcommon/tests/commonmisc_test.cpp
+++ b/indra/llcommon/tests/commonmisc_test.cpp
diff --git a/indra/llcommon/tests/listener.h b/indra/llcommon/tests/listener.h
index dcdb2412be..9c5c18a150 100644..100755
--- a/indra/llcommon/tests/listener.h
+++ b/indra/llcommon/tests/listener.h
@@ -30,6 +30,8 @@
#define LL_LISTENER_H
#include "llsd.h"
+#include "llevents.h"
+#include "tests/StringVec.h"
#include <iostream>
/*****************************************************************************
@@ -133,24 +135,7 @@ struct Collect
return false;
}
void clear() { result.clear(); }
- typedef std::vector<std::string> StringList;
- StringList result;
+ StringVec result;
};
-std::ostream& operator<<(std::ostream& out, const Collect::StringList& strings)
-{
- out << '(';
- Collect::StringList::const_iterator begin(strings.begin()), end(strings.end());
- if (begin != end)
- {
- out << '"' << *begin << '"';
- while (++begin != end)
- {
- out << ", \"" << *begin << '"';
- }
- }
- out << ')';
- return out;
-}
-
#endif /* ! defined(LL_LISTENER_H) */
diff --git a/indra/llcommon/tests/llallocator_heap_profile_test.cpp b/indra/llcommon/tests/llallocator_heap_profile_test.cpp
index 44a9705803..44a9705803 100644..100755
--- a/indra/llcommon/tests/llallocator_heap_profile_test.cpp
+++ b/indra/llcommon/tests/llallocator_heap_profile_test.cpp
diff --git a/indra/llcommon/tests/llallocator_test.cpp b/indra/llcommon/tests/llallocator_test.cpp
index 4e62eaee67..4e62eaee67 100644..100755
--- a/indra/llcommon/tests/llallocator_test.cpp
+++ b/indra/llcommon/tests/llallocator_test.cpp
diff --git a/indra/llcommon/tests/llbase64_test.cpp b/indra/llcommon/tests/llbase64_test.cpp
index d0394150fa..d0394150fa 100644..100755
--- a/indra/llcommon/tests/llbase64_test.cpp
+++ b/indra/llcommon/tests/llbase64_test.cpp
diff --git a/indra/llcommon/tests/lldate_test.cpp b/indra/llcommon/tests/lldate_test.cpp
index 7c95ccb91f..7c95ccb91f 100644..100755
--- a/indra/llcommon/tests/lldate_test.cpp
+++ b/indra/llcommon/tests/lldate_test.cpp
diff --git a/indra/llcommon/tests/lldependencies_test.cpp b/indra/llcommon/tests/lldependencies_test.cpp
index 5395d785b6..5395d785b6 100644..100755
--- a/indra/llcommon/tests/lldependencies_test.cpp
+++ b/indra/llcommon/tests/lldependencies_test.cpp
diff --git a/indra/llcommon/tests/llerror_test.cpp b/indra/llcommon/tests/llerror_test.cpp
index 09a20231de..279a90e51b 100644..100755
--- a/indra/llcommon/tests/llerror_test.cpp
+++ b/indra/llcommon/tests/llerror_test.cpp
@@ -1,4 +1,4 @@
-/**
+/**
* @file llerror_test.cpp
* @date December 2006
* @brief error unit tests
@@ -6,21 +6,21 @@
* $LicenseInfo:firstyear=2006&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$
*/
@@ -49,7 +49,7 @@ namespace
static bool fatalWasCalled;
void fatalCall(const std::string&) { fatalWasCalled = true; }
}
-
+
namespace tut
{
class TestRecorder : public LLError::Recorder
@@ -57,59 +57,65 @@ namespace tut
public:
TestRecorder() : mWantsTime(false) { }
~TestRecorder() { LLError::removeRecorder(this); }
-
+
void recordMessage(LLError::ELevel level,
const std::string& message)
{
mMessages.push_back(message);
}
-
+
int countMessages() { return (int) mMessages.size(); }
void clearMessages() { mMessages.clear(); }
-
+
void setWantsTime(bool t) { mWantsTime = t; }
bool wantsTime() { return mWantsTime; }
-
+
std::string message(int n)
{
std::ostringstream test_name;
test_name << "testing message " << n << ", not enough messages";
-
+
tut::ensure(test_name.str(), n < countMessages());
return mMessages[n];
}
-
+
private:
typedef std::vector<std::string> MessageVector;
MessageVector mMessages;
-
+
bool mWantsTime;
};
struct ErrorTestData
{
- TestRecorder mRecorder;
+ // addRecorder() expects to be able to later delete the passed
+ // Recorder*. Even though removeRecorder() reclaims ownership, passing
+ // a pointer to a data member rather than a heap Recorder subclass
+ // instance would just be Wrong.
+ TestRecorder* mRecorder;
LLError::Settings* mPriorErrorSettings;
-
- ErrorTestData()
+
+ ErrorTestData():
+ mRecorder(new TestRecorder)
{
fatalWasCalled = false;
-
+
mPriorErrorSettings = LLError::saveAndResetSettings();
LLError::setDefaultLevel(LLError::LEVEL_DEBUG);
LLError::setFatalFunction(fatalCall);
- LLError::addRecorder(&mRecorder);
+ LLError::addRecorder(mRecorder);
}
-
+
~ErrorTestData()
{
- LLError::removeRecorder(&mRecorder);
+ LLError::removeRecorder(mRecorder);
+ delete mRecorder;
LLError::restoreSettings(mPriorErrorSettings);
}
-
+
void ensure_message_count(int expectedCount)
{
- ensure_equals("message count", mRecorder.countMessages(), expectedCount);
+ ensure_equals("message count", mRecorder->countMessages(), expectedCount);
}
void ensure_message_contains(int n, const std::string& expectedText)
@@ -117,7 +123,7 @@ namespace tut
std::ostringstream test_name;
test_name << "testing message " << n;
- ensure_contains(test_name.str(), mRecorder.message(n), expectedText);
+ ensure_contains(test_name.str(), mRecorder->message(n), expectedText);
}
void ensure_message_does_not_contain(int n, const std::string& expectedText)
@@ -125,22 +131,22 @@ namespace tut
std::ostringstream test_name;
test_name << "testing message " << n;
- ensure_does_not_contain(test_name.str(), mRecorder.message(n), expectedText);
+ ensure_does_not_contain(test_name.str(), mRecorder->message(n), expectedText);
}
};
-
+
typedef test_group<ErrorTestData> ErrorTestGroup;
typedef ErrorTestGroup::object ErrorTestObject;
-
+
ErrorTestGroup errorTestGroup("error");
-
+
template<> template<>
void ErrorTestObject::test<1>()
// basic test of output
{
llinfos << "test" << llendl;
llinfos << "bob" << llendl;
-
+
ensure_message_contains(0, "test");
ensure_message_contains(1, "bob");
}
@@ -159,7 +165,7 @@ namespace
};
namespace tut
-{
+{
template<> template<>
void ErrorTestObject::test<2>()
// messages are filtered based on default level
@@ -172,7 +178,7 @@ namespace tut
ensure_message_contains(3, "error");
ensure_message_contains(4, "four");
ensure_message_count(5);
-
+
LLError::setDefaultLevel(LLError::LEVEL_INFO);
writeSome();
ensure_message_contains(5, "two");
@@ -180,20 +186,20 @@ namespace tut
ensure_message_contains(7, "error");
ensure_message_contains(8, "four");
ensure_message_count(9);
-
+
LLError::setDefaultLevel(LLError::LEVEL_WARN);
writeSome();
ensure_message_contains(9, "three");
ensure_message_contains(10, "error");
ensure_message_contains(11, "four");
ensure_message_count(12);
-
+
LLError::setDefaultLevel(LLError::LEVEL_ERROR);
writeSome();
ensure_message_contains(12, "error");
ensure_message_contains(13, "four");
ensure_message_count(14);
-
+
LLError::setDefaultLevel(LLError::LEVEL_NONE);
writeSome();
ensure_message_count(14);
@@ -218,14 +224,14 @@ namespace tut
{
std::string thisFile = __FILE__;
std::string abbreviateFile = LLError::abbreviateFile(thisFile);
-
+
ensure_ends_with("file name abbreviation",
abbreviateFile,
"llcommon/tests/llerror_test.cpp"
);
ensure_does_not_contain("file name abbreviation",
abbreviateFile, "indra");
-
+
std::string someFile =
#if LL_WINDOWS
"C:/amy/bob/cam.cpp"
@@ -234,12 +240,12 @@ namespace tut
#endif
;
std::string someAbbreviation = LLError::abbreviateFile(someFile);
-
+
ensure_equals("non-indra file abbreviation",
someAbbreviation, someFile);
}
}
-
+
namespace
{
std::string locationString(int line)
@@ -247,22 +253,22 @@ namespace
std::ostringstream location;
location << LLError::abbreviateFile(__FILE__)
<< "(" << line << ") : ";
-
+
return location.str();
}
-
+
std::string writeReturningLocation()
{
llinfos << "apple" << llendl; int this_line = __LINE__;
return locationString(this_line);
}
-
+
std::string writeReturningLocationAndFunction()
{
llinfos << "apple" << llendl; int this_line = __LINE__;
return locationString(this_line) + __FUNCTION__;
}
-
+
std::string errorReturningLocation()
{
llerrs << "die" << llendl; int this_line = __LINE__;
@@ -271,20 +277,20 @@ namespace
}
namespace tut
-{
+{
template<> template<>
void ErrorTestObject::test<5>()
// file and line information in log messages
{
std::string location = writeReturningLocation();
// expecting default to not print location information
-
+
LLError::setPrintLocation(true);
writeReturningLocation();
-
+
LLError::setPrintLocation(false);
writeReturningLocation();
-
+
ensure_message_does_not_contain(0, location);
ensure_message_contains(1, location);
ensure_message_does_not_contain(2, location);
@@ -297,7 +303,7 @@ namespace tut
existing log messages often do.) The functions all return their C++
name so that test can be substantial mechanized.
*/
-
+
std::string logFromGlobal(bool id)
{
llinfos << (id ? "logFromGlobal: " : "") << "hi" << llendl;
@@ -345,7 +351,7 @@ namespace
return "ClassWithNoLogType::logFromStatic";
}
};
-
+
class ClassWithLogType {
LOG_CLASS(ClassWithLogType);
public:
@@ -360,13 +366,13 @@ namespace
return "ClassWithLogType::logFromStatic";
}
};
-
+
std::string logFromNamespace(bool id) { return Foo::logFromNamespace(id); }
std::string logFromClassWithNoLogTypeMember(bool id) { ClassWithNoLogType c; return c.logFromMember(id); }
std::string logFromClassWithNoLogTypeStatic(bool id) { return ClassWithNoLogType::logFromStatic(id); }
std::string logFromClassWithLogTypeMember(bool id) { ClassWithLogType c; return c.logFromMember(id); }
std::string logFromClassWithLogTypeStatic(bool id) { return ClassWithLogType::logFromStatic(id); }
-
+
void ensure_has(const std::string& message,
const std::string& actual, const std::string& expected)
{
@@ -379,18 +385,18 @@ namespace
throw tut::failure(ss.str().c_str());
}
}
-
+
typedef std::string (*LogFromFunction)(bool);
- void testLogName(tut::TestRecorder& recorder, LogFromFunction f,
+ void testLogName(tut::TestRecorder* recorder, LogFromFunction f,
const std::string& class_name = "")
{
- recorder.clearMessages();
+ recorder->clearMessages();
std::string name = f(false);
f(true);
-
- std::string messageWithoutName = recorder.message(0);
- std::string messageWithName = recorder.message(1);
-
+
+ std::string messageWithoutName = recorder->message(0);
+ std::string messageWithName = recorder->message(1);
+
ensure_has(name + " logged without name",
messageWithoutName, name);
ensure_has(name + " logged with name",
@@ -431,18 +437,18 @@ namespace
llinfos << "inside" << llendl;
return "moo";
}
-
+
std::string outerLogger()
{
llinfos << "outside(" << innerLogger() << ")" << llendl;
return "bar";
}
-
+
void uberLogger()
{
llinfos << "uber(" << outerLogger() << "," << innerLogger() << ")" << llendl;
}
-
+
class LogWhileLogging
{
public:
@@ -461,11 +467,11 @@ namespace
LogWhileLogging l;
llinfos << "meta(" << l << ")" << llendl;
}
-
+
}
namespace tut
-{
+{
template<> template<>
// handle nested logging
void ErrorTestObject::test<7>()
@@ -474,31 +480,31 @@ namespace tut
ensure_message_contains(0, "inside");
ensure_message_contains(1, "outside(moo)");
ensure_message_count(2);
-
+
uberLogger();
ensure_message_contains(2, "inside");
ensure_message_contains(3, "inside");
ensure_message_contains(4, "outside(moo)");
ensure_message_contains(5, "uber(bar,moo)");
ensure_message_count(6);
-
+
metaLogger();
ensure_message_contains(6, "logging");
ensure_message_contains(7, "meta(baz)");
ensure_message_count(8);
}
-
+
template<> template<>
// special handling of llerrs calls
void ErrorTestObject::test<8>()
{
LLError::setPrintLocation(false);
std::string location = errorReturningLocation();
-
+
ensure_message_contains(0, location + "error");
ensure_message_contains(1, "die");
ensure_message_count(2);
-
+
ensure("fatal callback called", fatalWasCalled);
}
}
@@ -509,7 +515,7 @@ namespace
{
return "1947-07-08T03:04:05Z";
}
-
+
void ufoSighting()
{
llinfos << "ufo" << llendl;
@@ -517,35 +523,35 @@ namespace
}
namespace tut
-{
+{
template<> template<>
// time in output (for recorders that need it)
void ErrorTestObject::test<9>()
{
LLError::setTimeFunction(roswell);
- mRecorder.setWantsTime(false);
+ mRecorder->setWantsTime(false);
ufoSighting();
ensure_message_contains(0, "ufo");
ensure_message_does_not_contain(0, roswell());
-
- mRecorder.setWantsTime(true);
+
+ mRecorder->setWantsTime(true);
ufoSighting();
ensure_message_contains(1, "ufo");
ensure_message_contains(1, roswell());
}
-
+
template<> template<>
// output order
void ErrorTestObject::test<10>()
{
LLError::setPrintLocation(true);
LLError::setTimeFunction(roswell);
- mRecorder.setWantsTime(true);
+ mRecorder->setWantsTime(true);
std::string locationAndFunction = writeReturningLocationAndFunction();
-
+
ensure_equals("order is time type location function message",
- mRecorder.message(0),
+ mRecorder->message(0),
roswell() + " INFO: " + locationAndFunction + ": apple");
}
@@ -553,30 +559,30 @@ namespace tut
// multiple recorders
void ErrorTestObject::test<11>()
{
- TestRecorder altRecorder;
- LLError::addRecorder(&altRecorder);
-
+ TestRecorder* altRecorder(new TestRecorder);
+ LLError::addRecorder(altRecorder);
+
llinfos << "boo" << llendl;
ensure_message_contains(0, "boo");
- ensure_equals("alt recorder count", altRecorder.countMessages(), 1);
- ensure_contains("alt recorder message 0", altRecorder.message(0), "boo");
-
+ ensure_equals("alt recorder count", altRecorder->countMessages(), 1);
+ ensure_contains("alt recorder message 0", altRecorder->message(0), "boo");
+
LLError::setTimeFunction(roswell);
- TestRecorder anotherRecorder;
- anotherRecorder.setWantsTime(true);
- LLError::addRecorder(&anotherRecorder);
-
+ TestRecorder* anotherRecorder(new TestRecorder);
+ anotherRecorder->setWantsTime(true);
+ LLError::addRecorder(anotherRecorder);
+
llinfos << "baz" << llendl;
std::string when = roswell();
-
+
ensure_message_does_not_contain(1, when);
- ensure_equals("alt recorder count", altRecorder.countMessages(), 2);
- ensure_does_not_contain("alt recorder message 1", altRecorder.message(1), when);
- ensure_equals("another recorder count", anotherRecorder.countMessages(), 1);
- ensure_contains("another recorder message 0", anotherRecorder.message(0), when);
+ ensure_equals("alt recorder count", altRecorder->countMessages(), 2);
+ ensure_does_not_contain("alt recorder message 1", altRecorder->message(1), when);
+ ensure_equals("another recorder count", anotherRecorder->countMessages(), 1);
+ ensure_contains("another recorder message 0", anotherRecorder->message(0), when);
}
}
@@ -610,10 +616,10 @@ namespace tut
{
LLError::setDefaultLevel(LLError::LEVEL_WARN);
LLError::setClassLevel("TestBeta", LLError::LEVEL_INFO);
-
+
TestAlpha::doAll();
TestBeta::doAll();
-
+
ensure_message_contains(0, "aim west");
ensure_message_contains(1, "error");
ensure_message_contains(2, "ate eels");
@@ -623,7 +629,7 @@ namespace tut
ensure_message_contains(6, "big easy");
ensure_message_count(7);
}
-
+
template<> template<>
// filtering by function, and that it will override class filtering
void ErrorTestObject::test<13>()
@@ -632,13 +638,13 @@ namespace tut
LLError::setClassLevel("TestBeta", LLError::LEVEL_WARN);
LLError::setFunctionLevel("TestBeta::doInfo", LLError::LEVEL_DEBUG);
LLError::setFunctionLevel("TestBeta::doError", LLError::LEVEL_NONE);
-
+
TestBeta::doAll();
ensure_message_contains(0, "buy iron");
ensure_message_contains(1, "bad word");
ensure_message_count(2);
}
-
+
template<> template<>
// filtering by file
// and that it is overridden by both class and function filtering
@@ -652,7 +658,7 @@ namespace tut
LLError::LEVEL_NONE);
LLError::setFunctionLevel("TestBeta::doError",
LLError::LEVEL_NONE);
-
+
TestAlpha::doAll();
TestBeta::doAll();
ensure_message_contains(0, "any idea");
@@ -660,7 +666,7 @@ namespace tut
ensure_message_contains(2, "bad word");
ensure_message_count(3);
}
-
+
template<> template<>
// proper cached, efficient lookup of filtering
void ErrorTestObject::test<15>()
@@ -690,7 +696,7 @@ namespace tut
ensure_message_count(2);
ensure_equals("sixth check", LLError::shouldLogCallCount(), 3);
}
-
+
template<> template<>
// configuration from LLSD
void ErrorTestObject::test<16>()
@@ -699,26 +705,26 @@ namespace tut
LLSD config;
config["print-location"] = true;
config["default-level"] = "DEBUG";
-
+
LLSD set1;
set1["level"] = "WARN";
set1["files"][0] = this_file;
-
+
LLSD set2;
set2["level"] = "INFO";
set2["classes"][0] = "TestAlpha";
-
+
LLSD set3;
set3["level"] = "NONE";
set3["functions"][0] = "TestAlpha::doError";
set3["functions"][1] = "TestBeta::doError";
-
+
config["settings"][0] = set1;
config["settings"][1] = set2;
config["settings"][2] = set3;
-
+
LLError::configure(config);
-
+
TestAlpha::doAll();
TestBeta::doAll();
ensure_message_contains(0, "any idea");
@@ -726,13 +732,13 @@ namespace tut
ensure_message_contains(1, "aim west");
ensure_message_contains(2, "bad word");
ensure_message_count(3);
-
+
// make sure reconfiguring works
LLSD config2;
config2["default-level"] = "WARN";
-
+
LLError::configure(config2);
-
+
TestAlpha::doAll();
TestBeta::doAll();
ensure_message_contains(3, "aim west");
@@ -744,13 +750,13 @@ namespace tut
ensure_message_contains(8, "big easy");
ensure_message_count(9);
}
-}
+}
/* Tests left:
handling of classes without LOG_CLASS
- live update of filtering from file
-
+ live update of filtering from file
+
syslog recorder
file recorder
cerr/stderr recorder
diff --git a/indra/llcommon/tests/lleventcoro_test.cpp b/indra/llcommon/tests/lleventcoro_test.cpp
index 901ba35b2f..5ebde1a31d 100644..100755
--- a/indra/llcommon/tests/lleventcoro_test.cpp
+++ b/indra/llcommon/tests/lleventcoro_test.cpp
@@ -64,10 +64,10 @@
// Boost.Coroutine #include is the *first* #include of the platform header.
// That means that client code must generally #include Boost.Coroutine headers
// before anything else.
-#include <boost/coroutine/coroutine.hpp>
+#include <boost/dcoroutine/coroutine.hpp>
// Normally, lleventcoro.h obviates future.hpp. We only include this because
// we implement a "by hand" test of future functionality.
-#include <boost/coroutine/future.hpp>
+#include <boost/dcoroutine/future.hpp>
#include <boost/bind.hpp>
#include <boost/range.hpp>
@@ -78,6 +78,7 @@
#include "../test/lltut.h"
#include "llsd.h"
+#include "llsdutil.h"
#include "llevents.h"
#include "tests/wrapllerrs.h"
#include "stringize.h"
@@ -87,7 +88,7 @@
/*****************************************************************************
* from the banana.cpp example program borrowed for test<1>()
*****************************************************************************/
-namespace coroutines = boost::coroutines;
+namespace coroutines = boost::dcoroutines;
using coroutines::coroutine;
template<typename Iter>
@@ -108,7 +109,7 @@ match_substring(BidirectionalIterator begin,
BidirectionalIterator end,
std::string xmatch,
BOOST_DEDUCED_TYPENAME coroutine<BidirectionalIterator(void)>::self& self) {
- BidirectionalIterator begin_ = begin;
+//BidirectionalIterator begin_ = begin;
for(; begin != end; ++begin)
if(match(begin, end, xmatch)) {
self.yield(begin);
@@ -122,7 +123,7 @@ typedef coroutine<std::string::iterator(void)> match_coroutine_type;
* Test helpers
*****************************************************************************/
// I suspect this will be typical of coroutines used in Linden software
-typedef boost::coroutines::coroutine<void()> coroutine_type;
+typedef boost::dcoroutines::coroutine<void()> coroutine_type;
/// Simulate an event API whose response is immediate: sent on receipt of the
/// initial request, rather than after some delay. This is the case that
@@ -173,10 +174,10 @@ namespace tut
// ... do whatever preliminary stuff must happen ...
// declare the future
- boost::coroutines::future<LLSD> future(self);
+ boost::dcoroutines::future<LLSD> future(self);
// tell the future what to wait for
LLTempBoundListener connection(
- LLEventPumps::instance().obtain("source").listen("coro", voidlistener(boost::coroutines::make_callback(future))));
+ LLEventPumps::instance().obtain("source").listen("coro", voidlistener(boost::dcoroutines::make_callback(future))));
ensure("Not yet", ! future);
// attempting to dereference ("resolve") the future causes the calling
// coroutine to wait for it
@@ -213,7 +214,7 @@ namespace tut
BEGIN
{
result = postAndWait(self,
- LLSD().insert("value", 17), // request event
+ LLSDMap("value", 17), // request event
immediateAPI.getPump(), // requestPump
"reply1", // replyPump
"reply"); // request["reply"] = name
@@ -226,7 +227,7 @@ namespace tut
BEGIN
{
LLEventWithID pair = ::postAndWait2(self,
- LLSD().insert("value", 18),
+ LLSDMap("value", 18),
immediateAPI.getPump(),
"reply2",
"error2",
@@ -244,7 +245,7 @@ namespace tut
BEGIN
{
LLEventWithID pair = ::postAndWait2(self,
- LLSD().insert("value", 18).insert("fail", LLSD()),
+ LLSDMap("value", 18)("fail", LLSD()),
immediateAPI.getPump(),
"reply2",
"error2",
@@ -273,7 +274,7 @@ namespace tut
BEGIN
{
LLCoroEventPump waiter;
- result = waiter.postAndWait(self, LLSD().insert("value", 17),
+ result = waiter.postAndWait(self, LLSDMap("value", 17),
immediateAPI.getPump(), "reply");
}
END
@@ -365,7 +366,7 @@ namespace tut
BEGIN
{
LLCoroEventPumps waiter;
- LLEventWithID pair(waiter.postAndWait(self, LLSD().insert("value", 23),
+ LLEventWithID pair(waiter.postAndWait(self, LLSDMap("value", 23),
immediateAPI.getPump(), "reply", "error"));
result = pair.first;
which = pair.second;
@@ -379,7 +380,7 @@ namespace tut
{
LLCoroEventPumps waiter;
LLEventWithID pair(
- waiter.postAndWait(self, LLSD().insert("value", 23).insert("fail", LLSD()),
+ waiter.postAndWait(self, LLSDMap("value", 23)("fail", LLSD()),
immediateAPI.getPump(), "reply", "error"));
result = pair.first;
which = pair.second;
@@ -392,7 +393,7 @@ namespace tut
BEGIN
{
LLCoroEventPumps waiter;
- result = waiter.postAndWaitWithException(self, LLSD().insert("value", 8),
+ result = waiter.postAndWaitWithException(self, LLSDMap("value", 8),
immediateAPI.getPump(), "reply", "error");
}
END
@@ -406,7 +407,7 @@ namespace tut
try
{
result = waiter.postAndWaitWithException(self,
- LLSD().insert("value", 9).insert("fail", LLSD()),
+ LLSDMap("value", 9)("fail", LLSD()),
immediateAPI.getPump(), "reply", "error");
debug("no exception");
}
@@ -424,7 +425,7 @@ namespace tut
BEGIN
{
LLCoroEventPumps waiter;
- result = waiter.postAndWaitWithLog(self, LLSD().insert("value", 30),
+ result = waiter.postAndWaitWithLog(self, LLSDMap("value", 30),
immediateAPI.getPump(), "reply", "error");
}
END
@@ -439,7 +440,7 @@ namespace tut
try
{
result = waiter.postAndWaitWithLog(self,
- LLSD().insert("value", 31).insert("fail", LLSD()),
+ LLSDMap("value", 31)("fail", LLSD()),
immediateAPI.getPump(), "reply", "error");
debug("no exception");
}
@@ -796,4 +797,18 @@ namespace tut
ensure("no result", result.isUndefined());
ensure_contains("got error", threw, "32");
}
+}
+
+/*==========================================================================*|
+#include <boost/context/guarded_stack_allocator.hpp>
+
+namespace tut
+{
+ template<> template<>
+ void object::test<23>()
+ {
+ set_test_name("stacksize");
+ std::cout << "default_stacksize: " << boost::context::guarded_stack_allocator::default_stacksize() << '\n';
+ }
} // namespace tut
+|*==========================================================================*/
diff --git a/indra/llcommon/tests/lleventdispatcher_test.cpp b/indra/llcommon/tests/lleventdispatcher_test.cpp
index 263c9b171f..263c9b171f 100644..100755
--- a/indra/llcommon/tests/lleventdispatcher_test.cpp
+++ b/indra/llcommon/tests/lleventdispatcher_test.cpp
diff --git a/indra/llcommon/tests/lleventfilter_test.cpp b/indra/llcommon/tests/lleventfilter_test.cpp
index ca05ef62a9..ca05ef62a9 100644..100755
--- a/indra/llcommon/tests/lleventfilter_test.cpp
+++ b/indra/llcommon/tests/lleventfilter_test.cpp
diff --git a/indra/llcommon/tests/llframetimer_test.cpp b/indra/llcommon/tests/llframetimer_test.cpp
index 8ac1c91a3a..8ac1c91a3a 100644..100755
--- a/indra/llcommon/tests/llframetimer_test.cpp
+++ b/indra/llcommon/tests/llframetimer_test.cpp
diff --git a/indra/llcommon/tests/llinstancetracker_test.cpp b/indra/llcommon/tests/llinstancetracker_test.cpp
index b34d1c5fd3..e769c3e22c 100644..100755
--- a/indra/llcommon/tests/llinstancetracker_test.cpp
+++ b/indra/llcommon/tests/llinstancetracker_test.cpp
@@ -35,6 +35,7 @@
#include <vector>
#include <set>
#include <algorithm> // std::sort()
+#include <stdexcept>
// std headers
// external library headers
#include <boost/scoped_ptr.hpp>
@@ -42,6 +43,11 @@
#include "../test/lltut.h"
#include "wrapllerrs.h"
+struct Badness: public std::runtime_error
+{
+ Badness(const std::string& what): std::runtime_error(what) {}
+};
+
struct Keyed: public LLInstanceTracker<Keyed, std::string>
{
Keyed(const std::string& name):
@@ -53,6 +59,17 @@ struct Keyed: public LLInstanceTracker<Keyed, std::string>
struct Unkeyed: public LLInstanceTracker<Unkeyed>
{
+ Unkeyed(const std::string& thrw="")
+ {
+ // LLInstanceTracker should respond appropriately if a subclass
+ // constructor throws an exception. Specifically, it should run
+ // LLInstanceTracker's destructor and remove itself from the
+ // underlying container.
+ if (! thrw.empty())
+ {
+ throw Badness(thrw);
+ }
+ }
};
/*****************************************************************************
@@ -95,6 +112,7 @@ namespace tut
void object::test<2>()
{
ensure_equals(Unkeyed::instanceCount(), 0);
+ Unkeyed* dangling = NULL;
{
Unkeyed one;
ensure_equals(Unkeyed::instanceCount(), 1);
@@ -107,7 +125,11 @@ namespace tut
ensure_equals(found, two.get());
}
ensure_equals(Unkeyed::instanceCount(), 1);
- }
+ // store an unwise pointer to a temp Unkeyed instance
+ dangling = &one;
+ } // make that instance vanish
+ // check the now-invalid pointer to the destroyed instance
+ ensure("getInstance(T*) failed to track destruction", ! Unkeyed::getInstance(dangling));
ensure_equals(Unkeyed::instanceCount(), 0);
}
@@ -229,4 +251,48 @@ namespace tut
}
ensure(! what.empty());
}
+
+ template<> template<>
+ void object::test<8>()
+ {
+ set_test_name("exception in subclass ctor");
+ typedef std::set<Unkeyed*> InstanceSet;
+ InstanceSet existing;
+ // We can't use the iterator-range InstanceSet constructor because
+ // beginInstances() returns an iterator that dereferences to an
+ // Unkeyed&, not an Unkeyed*.
+ for (Unkeyed::instance_iter uki(Unkeyed::beginInstances()),
+ ukend(Unkeyed::endInstances());
+ uki != ukend; ++uki)
+ {
+ existing.insert(&*uki);
+ }
+ try
+ {
+ // We don't expect the assignment to take place because we expect
+ // Unkeyed to respond to the non-empty string param by throwing.
+ // We know the LLInstanceTracker base-class constructor will have
+ // run before Unkeyed's constructor, therefore the new instance
+ // will have added itself to the underlying set. The whole
+ // question is, when Unkeyed's constructor throws, will
+ // LLInstanceTracker's destructor remove it from the set? I
+ // realize we're testing the C++ implementation more than
+ // Unkeyed's implementation, but this seems an important point to
+ // nail down.
+ new Unkeyed("throw");
+ }
+ catch (const Badness&)
+ {
+ }
+ // Ensure that every member of the new, updated set of Unkeyed
+ // instances was also present in the original set. If that's not true,
+ // it's because our new Unkeyed ended up in the updated set despite
+ // its constructor exception.
+ for (Unkeyed::instance_iter uki(Unkeyed::beginInstances()),
+ ukend(Unkeyed::endInstances());
+ uki != ukend; ++uki)
+ {
+ ensure("failed to remove instance", existing.find(&*uki) != existing.end());
+ }
+ }
} // namespace tut
diff --git a/indra/llcommon/tests/lllazy_test.cpp b/indra/llcommon/tests/lllazy_test.cpp
index 32a717f4fc..32a717f4fc 100644..100755
--- a/indra/llcommon/tests/lllazy_test.cpp
+++ b/indra/llcommon/tests/lllazy_test.cpp
diff --git a/indra/llcommon/tests/llleap_test.cpp b/indra/llcommon/tests/llleap_test.cpp
new file mode 100755
index 0000000000..29060d4ef5
--- /dev/null
+++ b/indra/llcommon/tests/llleap_test.cpp
@@ -0,0 +1,691 @@
+/**
+ * @file llleap_test.cpp
+ * @author Nat Goodspeed
+ * @date 2012-02-21
+ * @brief Test for llleap.
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Copyright (c) 2012, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+// Precompiled header
+#include "linden_common.h"
+// associated header
+#include "llleap.h"
+// STL headers
+// std headers
+// external library headers
+#include <boost/assign/list_of.hpp>
+#include <boost/lambda/lambda.hpp>
+#include <boost/foreach.hpp>
+// other Linden headers
+#include "../test/lltut.h"
+#include "../test/namedtempfile.h"
+#include "../test/manageapr.h"
+#include "../test/catch_and_store_what_in.h"
+#include "wrapllerrs.h"
+#include "llevents.h"
+#include "llprocess.h"
+#include "stringize.h"
+#include "StringVec.h"
+#include <functional>
+
+using boost::assign::list_of;
+
+static ManageAPR manager;
+
+StringVec sv(const StringVec& listof) { return listof; }
+
+#if defined(LL_WINDOWS)
+#define sleep(secs) _sleep((secs) * 1000)
+#endif
+
+#if ! LL_WINDOWS
+const size_t BUFFERED_LENGTH = 1023*1024; // try wrangling just under a megabyte of data
+#else
+// "Then there's Windows... sigh." The "very large message" test is flaky in a
+// way that seems to point to either the OS (nonblocking writes to pipes) or
+// possibly the apr_file_write() function. Poring over log messages reveals
+// that at some point along the way apr_file_write() returns 11 (Resource
+// temporarily unavailable, i.e. EAGAIN) and says it wrote 0 bytes -- even
+// though it did write the chunk! Our next write attempt retries the same
+// chunk, resulting in the chunk being duplicated at the child end, corrupting
+// the data stream. Much as I would love to be able to fix it for real, such a
+// fix would appear to require distinguishing bogus EAGAIN returns from real
+// ones -- how?? Empirically this behavior is only observed when writing a
+// "very large message". To be able to move forward at all, try to bypass this
+// particular failure by adjusting the size of a "very large message" on
+// Windows.
+const size_t BUFFERED_LENGTH = 65336;
+#endif // LL_WINDOWS
+
+void waitfor(const std::vector<LLLeap*>& instances, int timeout=60)
+{
+ int i;
+ for (i = 0; i < timeout; ++i)
+ {
+ // Every iteration, test whether any of the passed LLLeap instances
+ // still exist (are still running).
+ std::vector<LLLeap*>::const_iterator vli(instances.begin()), vlend(instances.end());
+ for ( ; vli != vlend; ++vli)
+ {
+ // getInstance() returns NULL if it's terminated/gone, non-NULL if
+ // it's still running
+ if (LLLeap::getInstance(*vli))
+ break;
+ }
+ // If we made it through all of 'instances' without finding one that's
+ // still running, we're done.
+ if (vli == vlend)
+ {
+/*==========================================================================*|
+ std::cout << instances.size() << " LLLeap instances terminated in "
+ << i << " seconds, proceeding" << std::endl;
+|*==========================================================================*/
+ return;
+ }
+ // Found an instance that's still running. Wait and pump LLProcess.
+ sleep(1);
+ LLEventPumps::instance().obtain("mainloop").post(LLSD());
+ }
+ tut::ensure(STRINGIZE("at least 1 of " << instances.size()
+ << " LLLeap instances timed out ("
+ << timeout << " seconds) without terminating"),
+ i < timeout);
+}
+
+void waitfor(LLLeap* instance, int timeout=60)
+{
+ std::vector<LLLeap*> instances;
+ instances.push_back(instance);
+ waitfor(instances, timeout);
+}
+
+/*****************************************************************************
+* TUT
+*****************************************************************************/
+namespace tut
+{
+ struct llleap_data
+ {
+ llleap_data():
+ reader(".py",
+ // This logic is adapted from vita.viewerclient.receiveEvent()
+ boost::lambda::_1 <<
+ "import re\n"
+ "import os\n"
+ "import sys\n"
+ "\n"
+ // Don't forget that this Python script is written to some
+ // temp directory somewhere! Its __file__ is useless in
+ // finding indra/lib/python. Use our __FILE__, with
+ // raw-string syntax to deal with Windows pathnames.
+ "mydir = os.path.dirname(r'" << __FILE__ << "')\n"
+ // We expect mydir to be .../indra/llcommon/tests.
+ "sys.path.insert(0,\n"
+ " os.path.join(mydir, os.pardir, os.pardir, 'lib', 'python'))\n"
+ "from indra.base import llsd\n"
+ "\n"
+ "class ProtocolError(Exception):\n"
+ " def __init__(self, msg, data):\n"
+ " Exception.__init__(self, msg)\n"
+ " self.data = data\n"
+ "\n"
+ "class ParseError(ProtocolError):\n"
+ " pass\n"
+ "\n"
+ "def get():\n"
+ " hdr = ''\n"
+ " while ':' not in hdr and len(hdr) < 20:\n"
+ " hdr += sys.stdin.read(1)\n"
+ " if not hdr:\n"
+ " sys.exit(0)\n"
+ " if not hdr.endswith(':'):\n"
+ " raise ProtocolError('Expected len:data, got %r' % hdr, hdr)\n"
+ " try:\n"
+ " length = int(hdr[:-1])\n"
+ " except ValueError:\n"
+ " raise ProtocolError('Non-numeric len %r' % hdr[:-1], hdr[:-1])\n"
+ " parts = []\n"
+ " received = 0\n"
+ " while received < length:\n"
+ " parts.append(sys.stdin.read(length - received))\n"
+ " received += len(parts[-1])\n"
+ " data = ''.join(parts)\n"
+ " assert len(data) == length\n"
+ " try:\n"
+ " return llsd.parse(data)\n"
+ // Seems the old indra.base.llsd module didn't properly
+ // convert IndexError (from running off end of string) to
+ // LLSDParseError.
+ " except (IndexError, llsd.LLSDParseError), e:\n"
+ " msg = 'Bad received packet (%s)' % e\n"
+ " print >>sys.stderr, '%s, %s bytes:' % (msg, len(data))\n"
+ " showmax = 40\n"
+ // We've observed failures with very large packets;
+ // dumping the entire packet wastes time and space.
+ // But if the error states a particular byte offset,
+ // truncate to (near) that offset when dumping data.
+ " location = re.search(r' at (byte|index) ([0-9]+)', str(e))\n"
+ " if not location:\n"
+ " # didn't find offset, dump whole thing, no ellipsis\n"
+ " ellipsis = ''\n"
+ " else:\n"
+ " # found offset within error message\n"
+ " trunc = int(location.group(2)) + showmax\n"
+ " data = data[:trunc]\n"
+ " ellipsis = '... (%s more)' % (length - trunc)\n"
+ " offset = -showmax\n"
+ " for offset in xrange(0, len(data)-showmax, showmax):\n"
+ " print >>sys.stderr, '%04d: %r +' % \\\n"
+ " (offset, data[offset:offset+showmax])\n"
+ " offset += showmax\n"
+ " print >>sys.stderr, '%04d: %r%s' % \\\n"
+ " (offset, data[offset:], ellipsis)\n"
+ " raise ParseError(msg, data)\n"
+ "\n"
+ "# deal with initial stdin message\n"
+ // this will throw if the initial write to stdin doesn't
+ // follow len:data protocol, or if we couldn't find 'pump'
+ // in the dict
+ "_reply = get()['pump']\n"
+ "\n"
+ "def replypump():\n"
+ " return _reply\n"
+ "\n"
+ "def put(req):\n"
+ " sys.stdout.write(':'.join((str(len(req)), req)))\n"
+ " sys.stdout.flush()\n"
+ "\n"
+ "def send(pump, data):\n"
+ " put(llsd.format_notation(dict(pump=pump, data=data)))\n"
+ "\n"
+ "def request(pump, data):\n"
+ " # we expect 'data' is a dict\n"
+ " data['reply'] = _reply\n"
+ " send(pump, data)\n"),
+ // Get the actual pathname of the NamedExtTempFile and trim off
+ // the ".py" extension. (We could cache reader.getName() in a
+ // separate member variable, but I happen to know getName() just
+ // returns a NamedExtTempFile member rather than performing any
+ // computation, so I don't mind calling it twice.) Then take the
+ // basename.
+ reader_module(LLProcess::basename(
+ reader.getName().substr(0, reader.getName().length()-3))),
+ pPYTHON(getenv("PYTHON")),
+ PYTHON(pPYTHON? pPYTHON : "")
+ {
+ ensure("Set PYTHON to interpreter pathname", pPYTHON);
+ }
+ NamedExtTempFile reader;
+ const std::string reader_module;
+ const char* pPYTHON;
+ const std::string PYTHON;
+ };
+ typedef test_group<llleap_data> llleap_group;
+ typedef llleap_group::object object;
+ llleap_group llleapgrp("llleap");
+
+ template<> template<>
+ void object::test<1>()
+ {
+ set_test_name("multiple LLLeap instances");
+ NamedTempFile script("py",
+ "import time\n"
+ "time.sleep(1)\n");
+ std::vector<LLLeap*> instances;
+ instances.push_back(LLLeap::create(get_test_name(),
+ sv(list_of(PYTHON)(script.getName()))));
+ instances.push_back(LLLeap::create(get_test_name(),
+ sv(list_of(PYTHON)(script.getName()))));
+ // In this case we're simply establishing that two LLLeap instances
+ // can coexist without throwing exceptions or bombing in any other
+ // way. Wait for them to terminate.
+ waitfor(instances);
+ }
+
+ template<> template<>
+ void object::test<2>()
+ {
+ set_test_name("stderr to log");
+ NamedTempFile script("py",
+ "import sys\n"
+ "sys.stderr.write('''Hello from Python!\n"
+ "note partial line''')\n");
+ CaptureLog log(LLError::LEVEL_INFO);
+ waitfor(LLLeap::create(get_test_name(),
+ sv(list_of(PYTHON)(script.getName()))));
+ log.messageWith("Hello from Python!");
+ log.messageWith("note partial line");
+ }
+
+ template<> template<>
+ void object::test<3>()
+ {
+ set_test_name("bad stdout protocol");
+ NamedTempFile script("py",
+ "print 'Hello from Python!'\n");
+ CaptureLog log(LLError::LEVEL_WARN);
+ waitfor(LLLeap::create(get_test_name(),
+ sv(list_of(PYTHON)(script.getName()))));
+ ensure_contains("error log line",
+ log.messageWith("invalid protocol"), "Hello from Python!");
+ }
+
+ template<> template<>
+ void object::test<4>()
+ {
+ set_test_name("leftover stdout");
+ NamedTempFile script("py",
+ "import sys\n"
+ // note lack of newline
+ "sys.stdout.write('Hello from Python!')\n");
+ CaptureLog log(LLError::LEVEL_WARN);
+ waitfor(LLLeap::create(get_test_name(),
+ sv(list_of(PYTHON)(script.getName()))));
+ ensure_contains("error log line",
+ log.messageWith("Discarding"), "Hello from Python!");
+ }
+
+ template<> template<>
+ void object::test<5>()
+ {
+ set_test_name("bad stdout len prefix");
+ NamedTempFile script("py",
+ "import sys\n"
+ "sys.stdout.write('5a2:something')\n");
+ CaptureLog log(LLError::LEVEL_WARN);
+ waitfor(LLLeap::create(get_test_name(),
+ sv(list_of(PYTHON)(script.getName()))));
+ ensure_contains("error log line",
+ log.messageWith("invalid protocol"), "5a2:");
+ }
+
+ template<> template<>
+ void object::test<6>()
+ {
+ set_test_name("empty plugin vector");
+ std::string threw;
+ try
+ {
+ LLLeap::create("empty", StringVec());
+ }
+ CATCH_AND_STORE_WHAT_IN(threw, LLLeap::Error)
+ ensure_contains("LLLeap::Error", threw, "no plugin");
+ // try the suppress-exception variant
+ ensure("bad launch returned non-NULL", ! LLLeap::create("empty", StringVec(), false));
+ }
+
+ template<> template<>
+ void object::test<7>()
+ {
+ set_test_name("bad launch");
+ // Synthesize bogus executable name
+ std::string BADPYTHON(PYTHON.substr(0, PYTHON.length()-1) + "x");
+ CaptureLog log;
+ std::string threw;
+ try
+ {
+ LLLeap::create("bad exe", BADPYTHON);
+ }
+ CATCH_AND_STORE_WHAT_IN(threw, LLLeap::Error)
+ ensure_contains("LLLeap::create() didn't throw", threw, "failed");
+ log.messageWith("failed");
+ log.messageWith(BADPYTHON);
+ // try the suppress-exception variant
+ ensure("bad launch returned non-NULL", ! LLLeap::create("bad exe", BADPYTHON, false));
+ }
+
+ // Generic self-contained listener: derive from this and override its
+ // call() method, then tell somebody to post on the pump named getName().
+ // Control will reach your call() override.
+ struct ListenerBase
+ {
+ // Pass the pump name you want; will tweak for uniqueness.
+ ListenerBase(const std::string& name):
+ mPump(name, true)
+ {
+ mPump.listen(name, boost::bind(&ListenerBase::call, this, _1));
+ }
+
+ virtual ~ListenerBase() {} // pacify MSVC
+
+ virtual bool call(const LLSD& request)
+ {
+ return false;
+ }
+
+ LLEventPump& getPump() { return mPump; }
+ const LLEventPump& getPump() const { return mPump; }
+
+ std::string getName() const { return mPump.getName(); }
+ void post(const LLSD& data) { mPump.post(data); }
+
+ LLEventStream mPump;
+ };
+
+ // Mimic a dummy little LLEventAPI that merely sends a reply back to its
+ // requester on the "reply" pump.
+ struct AckAPI: public ListenerBase
+ {
+ AckAPI(): ListenerBase("AckAPI") {}
+
+ virtual bool call(const LLSD& request)
+ {
+ LLEventPumps::instance().obtain(request["reply"]).post("ack");
+ return false;
+ }
+ };
+
+ // Give LLLeap script a way to post success/failure.
+ struct Result: public ListenerBase
+ {
+ Result(): ListenerBase("Result") {}
+
+ virtual bool call(const LLSD& request)
+ {
+ mData = request;
+ return false;
+ }
+
+ void ensure() const
+ {
+ tut::ensure(std::string("never posted to ") + getName(), mData.isDefined());
+ // Post an empty string for success, non-empty string is failure message.
+ tut::ensure(mData, mData.asString().empty());
+ }
+
+ LLSD mData;
+ };
+
+ template<> template<>
+ void object::test<8>()
+ {
+ set_test_name("round trip");
+ AckAPI api;
+ Result result;
+ NamedTempFile script("py",
+ boost::lambda::_1 <<
+ "from " << reader_module << " import *\n"
+ // make a request on our little API
+ "request(pump='" << api.getName() << "', data={})\n"
+ // wait for its response
+ "resp = get()\n"
+ "result = '' if resp == dict(pump=replypump(), data='ack')\\\n"
+ " else 'bad: ' + str(resp)\n"
+ "send(pump='" << result.getName() << "', data=result)\n");
+ waitfor(LLLeap::create(get_test_name(), sv(list_of(PYTHON)(script.getName()))));
+ result.ensure();
+ }
+
+ struct ReqIDAPI: public ListenerBase
+ {
+ ReqIDAPI(): ListenerBase("ReqIDAPI") {}
+
+ virtual bool call(const LLSD& request)
+ {
+ // free function from llevents.h
+ sendReply(LLSD(), request);
+ return false;
+ }
+ };
+
+ template<> template<>
+ void object::test<9>()
+ {
+ set_test_name("many small messages");
+ // It's not clear to me whether there's value in iterating many times
+ // over a send/receive loop -- I don't think that will exercise any
+ // interesting corner cases. This test first sends a large number of
+ // messages, then receives all the responses. The intent is to ensure
+ // that some of that data stream crosses buffer boundaries, loop
+ // iterations etc. in OS pipes and the LLLeap/LLProcess implementation.
+ ReqIDAPI api;
+ Result result;
+ NamedTempFile script("py",
+ boost::lambda::_1 <<
+ "import sys\n"
+ "from " << reader_module << " import *\n"
+ // Note that since reader imports llsd, this
+ // 'import *' gets us llsd too.
+ "sample = llsd.format_notation(dict(pump='" <<
+ api.getName() << "', data=dict(reqid=999999, reply=replypump())))\n"
+ // The whole packet has length prefix too: "len:data"
+ "samplen = len(str(len(sample))) + 1 + len(sample)\n"
+ // guess how many messages it will take to
+ // accumulate BUFFERED_LENGTH
+ "count = int(" << BUFFERED_LENGTH << "/samplen)\n"
+ "print >>sys.stderr, 'Sending %s requests' % count\n"
+ "for i in xrange(count):\n"
+ " request('" << api.getName() << "', dict(reqid=i))\n"
+ // The assumption in this specific test that
+ // replies will arrive in the same order as
+ // requests is ONLY valid because the API we're
+ // invoking sends replies instantly. If the API
+ // had to wait for some external event before
+ // sending its reply, replies could arrive in
+ // arbitrary order, and we'd have to tick them
+ // off from a set.
+ "result = ''\n"
+ "for i in xrange(count):\n"
+ " resp = get()\n"
+ " if resp['data']['reqid'] != i:\n"
+ " result = 'expected reqid=%s in %s' % (i, resp)\n"
+ " break\n"
+ "send(pump='" << result.getName() << "', data=result)\n");
+ waitfor(LLLeap::create(get_test_name(), sv(list_of(PYTHON)(script.getName()))),
+ 300); // needs more realtime than most tests
+ result.ensure();
+ }
+
+ // This is the body of test<10>, extracted so we can run it over a number
+ // of large-message sizes.
+ void test_large_message(const std::string& PYTHON, const std::string& reader_module,
+ const std::string& test_name, size_t size)
+ {
+ ReqIDAPI api;
+ Result result;
+ NamedTempFile script("py",
+ boost::lambda::_1 <<
+ "import sys\n"
+ "from " << reader_module << " import *\n"
+ // Generate a very large string value.
+ "desired = int(sys.argv[1])\n"
+ // 7 chars per item: 6 digits, 1 comma
+ "count = int((desired - 50)/7)\n"
+ "large = ''.join('%06d,' % i for i in xrange(count))\n"
+ // Pass 'large' as reqid because we know the API
+ // will echo reqid, and we want to receive it back.
+ "request('" << api.getName() << "', dict(reqid=large))\n"
+ "try:\n"
+ " resp = get()\n"
+ "except ParseError, e:\n"
+ " # try to find where e.data diverges from expectation\n"
+ // Normally we'd expect a 'pump' key in there,
+ // too, with value replypump(). But Python
+ // serializes keys in a different order than C++,
+ // so incoming data start with 'data'.
+ // Truthfully, though, if we get as far as 'pump'
+ // before we find a difference, something's very
+ // strange.
+ " expect = llsd.format_notation(dict(data=dict(reqid=large)))\n"
+ " chunk = 40\n"
+ " for offset in xrange(0, max(len(e.data), len(expect)), chunk):\n"
+ " if e.data[offset:offset+chunk] != \\\n"
+ " expect[offset:offset+chunk]:\n"
+ " print >>sys.stderr, 'Offset %06d: expect %r,\\n'\\\n"
+ " ' get %r' %\\\n"
+ " (offset,\n"
+ " expect[offset:offset+chunk],\n"
+ " e.data[offset:offset+chunk])\n"
+ " break\n"
+ " else:\n"
+ " print >>sys.stderr, 'incoming data matches expect?!'\n"
+ " send('" << result.getName() << "', '%s: %s' % (e.__class__.__name__, e))\n"
+ " sys.exit(1)\n"
+ "\n"
+ "echoed = resp['data']['reqid']\n"
+ "if echoed == large:\n"
+ " send('" << result.getName() << "', '')\n"
+ " sys.exit(0)\n"
+ // Here we know echoed did NOT match; try to find where
+ "for i in xrange(count):\n"
+ " start = 7*i\n"
+ " end = 7*(i+1)\n"
+ " if end > len(echoed)\\\n"
+ " or echoed[start:end] != large[start:end]:\n"
+ " send('" << result.getName() << "',\n"
+ " 'at offset %s, expected %r but got %r' %\n"
+ " (start, large[start:end], echoed[start:end]))\n"
+ "sys.exit(1)\n");
+ waitfor(LLLeap::create(test_name,
+ sv(list_of
+ (PYTHON)
+ (script.getName())
+ (stringize(size)))),
+ 180); // try a longer timeout
+ result.ensure();
+ }
+
+ struct TestLargeMessage: public std::binary_function<size_t, size_t, bool>
+ {
+ TestLargeMessage(const std::string& PYTHON_, const std::string& reader_module_,
+ const std::string& test_name_):
+ PYTHON(PYTHON_),
+ reader_module(reader_module_),
+ test_name(test_name_)
+ {}
+
+ bool operator()(size_t left, size_t right) const
+ {
+ // We don't know whether upper_bound is going to pass the "sought
+ // value" as the left or the right operand. We pass 0 as the
+ // "sought value" so we can distinguish it. Of course that means
+ // the sequence we're searching must not itself contain 0!
+ size_t size;
+ bool success;
+ if (left)
+ {
+ size = left;
+ // Consider our return value carefully. Normal binary_search
+ // (or, in our case, upper_bound) expects a container sorted
+ // in ascending order, and defaults to the std::less
+ // comparator. Our container is in fact in ascending order, so
+ // return consistently with std::less. Here we were called as
+ // compare(item, sought). If std::less were called that way,
+ // 'true' would mean to move right (to higher numbers) within
+ // the sequence: the item being considered is less than the
+ // sought value. For us, that means that test_large_message()
+ // success should return 'true'.
+ success = true;
+ }
+ else
+ {
+ size = right;
+ // Here we were called as compare(sought, item). If std::less
+ // were called that way, 'true' would mean to move left (to
+ // lower numbers) within the sequence: the sought value is
+ // less than the item being considered. For us, that means
+ // test_large_message() FAILURE should return 'true', hence
+ // test_large_message() success should return 'false'.
+ success = false;
+ }
+
+ try
+ {
+ test_large_message(PYTHON, reader_module, test_name, size);
+ std::cout << "test_large_message(" << size << ") succeeded" << std::endl;
+ return success;
+ }
+ catch (const failure& e)
+ {
+ std::cout << "test_large_message(" << size << ") failed: " << e.what() << std::endl;
+ return ! success;
+ }
+ }
+
+ const std::string PYTHON, reader_module, test_name;
+ };
+
+ // The point of this function is to try to find a size at which
+ // test_large_message() can succeed. We still want the overall test to
+ // fail; otherwise we won't get the coder's attention -- but if
+ // test_large_message() fails, try to find a plausible size at which it
+ // DOES work.
+ void test_or_split(const std::string& PYTHON, const std::string& reader_module,
+ const std::string& test_name, size_t size)
+ {
+ try
+ {
+ test_large_message(PYTHON, reader_module, test_name, size);
+ }
+ catch (const failure& e)
+ {
+ std::cout << "test_large_message(" << size << ") failed: " << e.what() << std::endl;
+ // If it still fails below 4K, give up: subdividing any further is
+ // pointless.
+ if (size >= 4096)
+ {
+ try
+ {
+ // Recur with half the size
+ size_t smaller(size/2);
+ test_or_split(PYTHON, reader_module, test_name, smaller);
+ // Recursive call will throw if test_large_message()
+ // failed, therefore we only reach the line below if it
+ // succeeded.
+ std::cout << "but test_large_message(" << smaller << ") succeeded" << std::endl;
+
+ // Binary search for largest size that works. But since
+ // std::binary_search() only returns bool, actually use
+ // std::upper_bound(), consistent with our desire to find
+ // the LARGEST size that works. First generate a sorted
+ // container of all the sizes we intend to try, from
+ // 'smaller' (known to work) to 'size' (known to fail). We
+ // could whomp up magic iterators to do this dynamically,
+ // without actually instantiating a vector, but for a test
+ // program this will do. At least preallocate the vector.
+ // Per TestLargeMessage comments, it's important that this
+ // vector not contain 0.
+ std::vector<size_t> sizes;
+ sizes.reserve((size - smaller)/4096 + 1);
+ for (size_t sz(smaller), szend(size); sz < szend; sz += 4096)
+ sizes.push_back(sz);
+ // our comparator
+ TestLargeMessage tester(PYTHON, reader_module, test_name);
+ // Per TestLargeMessage comments, pass 0 as the sought value.
+ std::vector<size_t>::const_iterator found =
+ std::upper_bound(sizes.begin(), sizes.end(), 0, tester);
+ if (found != sizes.end() && found != sizes.begin())
+ {
+ std::cout << "test_large_message(" << *(found - 1)
+ << ") is largest that succeeds" << std::endl;
+ }
+ else
+ {
+ std::cout << "cannot determine largest test_large_message(size) "
+ << "that succeeds" << std::endl;
+ }
+ }
+ catch (const failure&)
+ {
+ // The recursive test_or_split() call above has already
+ // handled the exception. We don't want our caller to see
+ // innermost exception; propagate outermost (below).
+ }
+ }
+ // In any case, because we reached here through failure of
+ // our original test_large_message(size) call, ensure failure
+ // propagates.
+ throw e;
+ }
+ }
+
+ template<> template<>
+ void object::test<10>()
+ {
+ set_test_name("very large message");
+ test_or_split(PYTHON, reader_module, get_test_name(), BUFFERED_LENGTH);
+ }
+} // namespace tut
diff --git a/indra/llcommon/tests/llmemtype_test.cpp b/indra/llcommon/tests/llmemtype_test.cpp
index 1f050d6dc7..1f050d6dc7 100644..100755
--- a/indra/llcommon/tests/llmemtype_test.cpp
+++ b/indra/llcommon/tests/llmemtype_test.cpp
diff --git a/indra/llcommon/tests/llprocess_test.cpp b/indra/llcommon/tests/llprocess_test.cpp
new file mode 100755
index 0000000000..3e68ef068e
--- /dev/null
+++ b/indra/llcommon/tests/llprocess_test.cpp
@@ -0,0 +1,1259 @@
+/**
+ * @file llprocess_test.cpp
+ * @author Nat Goodspeed
+ * @date 2011-12-19
+ * @brief Test for llprocess.
+ *
+ * $LicenseInfo:firstyear=2011&license=viewerlgpl$
+ * Copyright (c) 2011, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+// Precompiled header
+#include "linden_common.h"
+// associated header
+#include "llprocess.h"
+// STL headers
+#include <vector>
+#include <list>
+// std headers
+#include <fstream>
+// external library headers
+#include "llapr.h"
+#include "apr_thread_proc.h"
+#include <boost/foreach.hpp>
+#include <boost/function.hpp>
+#include <boost/algorithm/string/find_iterator.hpp>
+#include <boost/algorithm/string/finder.hpp>
+//#include <boost/lambda/lambda.hpp>
+//#include <boost/lambda/bind.hpp>
+// other Linden headers
+#include "../test/lltut.h"
+#include "../test/manageapr.h"
+#include "../test/namedtempfile.h"
+#include "../test/catch_and_store_what_in.h"
+#include "stringize.h"
+#include "llsdutil.h"
+#include "llevents.h"
+#include "wrapllerrs.h"
+
+#if defined(LL_WINDOWS)
+#define sleep(secs) _sleep((secs) * 1000)
+#define EOL "\r\n"
+#else
+#define EOL "\n"
+#include <sys/wait.h>
+#endif
+
+//namespace lambda = boost::lambda;
+
+// static instance of this manages APR init/cleanup
+static ManageAPR manager;
+
+/*****************************************************************************
+* Helpers
+*****************************************************************************/
+
+#define ensure_equals_(left, right) \
+ ensure_equals(STRINGIZE(#left << " != " << #right), (left), (right))
+
+#define aprchk(expr) aprchk_(#expr, (expr))
+static void aprchk_(const char* call, apr_status_t rv, apr_status_t expected=APR_SUCCESS)
+{
+ tut::ensure_equals(STRINGIZE(call << " => " << rv << ": " << manager.strerror(rv)),
+ rv, expected);
+}
+
+/**
+ * Read specified file using std::getline(). It is assumed to be an error if
+ * the file is empty: don't use this function if that's an acceptable case.
+ * Last line will not end with '\n'; this is to facilitate the usual case of
+ * string compares with a single line of output.
+ * @param pathname The file to read.
+ * @param desc Optional description of the file for error message;
+ * defaults to "in <pathname>"
+ */
+static std::string readfile(const std::string& pathname, const std::string& desc="")
+{
+ std::string use_desc(desc);
+ if (use_desc.empty())
+ {
+ use_desc = STRINGIZE("in " << pathname);
+ }
+ std::ifstream inf(pathname.c_str());
+ std::string output;
+ tut::ensure(STRINGIZE("No output " << use_desc), std::getline(inf, output));
+ std::string more;
+ while (std::getline(inf, more))
+ {
+ output += '\n' + more;
+ }
+ return output;
+}
+
+/// Looping on LLProcess::isRunning() must now be accompanied by pumping
+/// "mainloop" -- otherwise the status won't update and you get an infinite
+/// loop.
+void yield(int seconds=1)
+{
+ // This function simulates waiting for another viewer frame
+ sleep(seconds);
+ LLEventPumps::instance().obtain("mainloop").post(LLSD());
+}
+
+void waitfor(LLProcess& proc, int timeout=60)
+{
+ int i = 0;
+ for ( ; i < timeout && proc.isRunning(); ++i)
+ {
+ yield();
+ }
+ tut::ensure(STRINGIZE("process took longer than " << timeout << " seconds to terminate"),
+ i < timeout);
+}
+
+void waitfor(LLProcess::handle h, const std::string& desc, int timeout=60)
+{
+ int i = 0;
+ for ( ; i < timeout && LLProcess::isRunning(h, desc); ++i)
+ {
+ yield();
+ }
+ tut::ensure(STRINGIZE("process took longer than " << timeout << " seconds to terminate"),
+ i < timeout);
+}
+
+/**
+ * Construct an LLProcess to run a Python script.
+ */
+struct PythonProcessLauncher
+{
+ /**
+ * @param desc Arbitrary description for error messages
+ * @param script Python script, any form acceptable to NamedTempFile,
+ * typically either a std::string or an expression of the form
+ * (lambda::_1 << "script content with " << variable_data)
+ */
+ template <typename CONTENT>
+ PythonProcessLauncher(const std::string& desc, const CONTENT& script):
+ mDesc(desc),
+ mScript("py", script)
+ {
+ const char* PYTHON(getenv("PYTHON"));
+ tut::ensure("Set $PYTHON to the Python interpreter", PYTHON);
+
+ mParams.desc = desc + " script";
+ mParams.executable = PYTHON;
+ mParams.args.add(mScript.getName());
+ }
+
+ /// Launch Python script; verify that it launched
+ void launch()
+ {
+ mPy = LLProcess::create(mParams);
+ tut::ensure(STRINGIZE("Couldn't launch " << mDesc << " script"), mPy);
+ }
+
+ /// Run Python script and wait for it to complete.
+ void run()
+ {
+ launch();
+ // One of the irritating things about LLProcess is that
+ // there's no API to wait for the child to terminate -- but given
+ // its use in our graphics-intensive interactive viewer, it's
+ // understandable.
+ waitfor(*mPy);
+ }
+
+ /**
+ * Run a Python script using LLProcess, expecting that it will
+ * write to the file passed as its sys.argv[1]. Retrieve that output.
+ *
+ * Until January 2012, LLProcess provided distressingly few
+ * mechanisms for a child process to communicate back to its caller --
+ * not even its return code. We've introduced a convention by which we
+ * create an empty temp file, pass the name of that file to our child
+ * as sys.argv[1] and expect the script to write its output to that
+ * file. This function implements the C++ (parent process) side of
+ * that convention.
+ */
+ std::string run_read()
+ {
+ NamedTempFile out("out", ""); // placeholder
+ // pass name of this temporary file to the script
+ mParams.args.add(out.getName());
+ run();
+ // assuming the script wrote to that file, read it
+ return readfile(out.getName(), STRINGIZE("from " << mDesc << " script"));
+ }
+
+ LLProcess::Params mParams;
+ LLProcessPtr mPy;
+ std::string mDesc;
+ NamedTempFile mScript;
+};
+
+/// convenience function for PythonProcessLauncher::run()
+template <typename CONTENT>
+static void python(const std::string& desc, const CONTENT& script)
+{
+ PythonProcessLauncher py(desc, script);
+ py.run();
+}
+
+/// convenience function for PythonProcessLauncher::run_read()
+template <typename CONTENT>
+static std::string python_out(const std::string& desc, const CONTENT& script)
+{
+ PythonProcessLauncher py(desc, script);
+ return py.run_read();
+}
+
+/// Create a temporary directory and clean it up later.
+class NamedTempDir: public boost::noncopyable
+{
+public:
+ // Use python() function to create a temp directory: I've found
+ // nothing in either Boost.Filesystem or APR quite like Python's
+ // tempfile.mkdtemp().
+ // Special extra bonus: on Mac, mkdtemp() reports a pathname
+ // starting with /var/folders/something, whereas that's really a
+ // symlink to /private/var/folders/something. Have to use
+ // realpath() to compare properly.
+ NamedTempDir():
+ mPath(python_out("mkdtemp()",
+ "from __future__ import with_statement\n"
+ "import os.path, sys, tempfile\n"
+ "with open(sys.argv[1], 'w') as f:\n"
+ " f.write(os.path.normcase(os.path.normpath(os.path.realpath(tempfile.mkdtemp()))))\n"))
+ {}
+
+ ~NamedTempDir()
+ {
+ aprchk(apr_dir_remove(mPath.c_str(), gAPRPoolp));
+ }
+
+ std::string getName() const { return mPath; }
+
+private:
+ std::string mPath;
+};
+
+/*****************************************************************************
+* TUT
+*****************************************************************************/
+namespace tut
+{
+ struct llprocess_data
+ {
+ LLAPRPool pool;
+ };
+ typedef test_group<llprocess_data> llprocess_group;
+ typedef llprocess_group::object object;
+ llprocess_group llprocessgrp("llprocess");
+
+ struct Item
+ {
+ Item(): tries(0) {}
+ unsigned tries;
+ std::string which;
+ std::string what;
+ };
+
+/*==========================================================================*|
+#define tabent(symbol) { symbol, #symbol }
+ static struct ReasonCode
+ {
+ int code;
+ const char* name;
+ } reasons[] =
+ {
+ tabent(APR_OC_REASON_DEATH),
+ tabent(APR_OC_REASON_UNWRITABLE),
+ tabent(APR_OC_REASON_RESTART),
+ tabent(APR_OC_REASON_UNREGISTER),
+ tabent(APR_OC_REASON_LOST),
+ tabent(APR_OC_REASON_RUNNING)
+ };
+#undef tabent
+|*==========================================================================*/
+
+ struct WaitInfo
+ {
+ WaitInfo(apr_proc_t* child_):
+ child(child_),
+ rv(-1), // we haven't yet called apr_proc_wait()
+ rc(0),
+ why(apr_exit_why_e(0))
+ {}
+ apr_proc_t* child; // which subprocess
+ apr_status_t rv; // return from apr_proc_wait()
+ int rc; // child's exit code
+ apr_exit_why_e why; // APR_PROC_EXIT, APR_PROC_SIGNAL, APR_PROC_SIGNAL_CORE
+ };
+
+ void child_status_callback(int reason, void* data, int status)
+ {
+/*==========================================================================*|
+ std::string reason_str;
+ BOOST_FOREACH(const ReasonCode& rcp, reasons)
+ {
+ if (reason == rcp.code)
+ {
+ reason_str = rcp.name;
+ break;
+ }
+ }
+ if (reason_str.empty())
+ {
+ reason_str = STRINGIZE("unknown reason " << reason);
+ }
+ std::cout << "child_status_callback(" << reason_str << ")\n";
+|*==========================================================================*/
+
+ if (reason == APR_OC_REASON_DEATH || reason == APR_OC_REASON_LOST)
+ {
+ // Somewhat oddly, APR requires that you explicitly unregister
+ // even when it already knows the child has terminated.
+ apr_proc_other_child_unregister(data);
+
+ WaitInfo* wi(static_cast<WaitInfo*>(data));
+ // It's just wrong to call apr_proc_wait() here. The only way APR
+ // knows to call us with APR_OC_REASON_DEATH is that it's already
+ // reaped this child process, so calling wait() will only produce
+ // "huh?" from the OS. We must rely on the status param passed in,
+ // which unfortunately comes straight from the OS wait() call.
+// wi->rv = apr_proc_wait(wi->child, &wi->rc, &wi->why, APR_NOWAIT);
+ wi->rv = APR_CHILD_DONE; // fake apr_proc_wait() results
+#if defined(LL_WINDOWS)
+ wi->why = APR_PROC_EXIT;
+ wi->rc = status; // no encoding on Windows (no signals)
+#else // Posix
+ if (WIFEXITED(status))
+ {
+ wi->why = APR_PROC_EXIT;
+ wi->rc = WEXITSTATUS(status);
+ }
+ else if (WIFSIGNALED(status))
+ {
+ wi->why = APR_PROC_SIGNAL;
+ wi->rc = WTERMSIG(status);
+ }
+ else // uh, shouldn't happen?
+ {
+ wi->why = APR_PROC_EXIT;
+ wi->rc = status; // someone else will have to decode
+ }
+#endif // Posix
+ }
+ }
+
+ template<> template<>
+ void object::test<1>()
+ {
+ set_test_name("raw APR nonblocking I/O");
+
+ // Create a script file in a temporary place.
+ NamedTempFile script("py",
+ "import sys" EOL
+ "import time" EOL
+ EOL
+ "time.sleep(2)" EOL
+ "print >>sys.stdout, 'stdout after wait'" EOL
+ "sys.stdout.flush()" EOL
+ "time.sleep(2)" EOL
+ "print >>sys.stderr, 'stderr after wait'" EOL
+ "sys.stderr.flush()" EOL
+ );
+
+ // Arrange to track the history of our interaction with child: what we
+ // fetched, which pipe it came from, how many tries it took before we
+ // got it.
+ std::vector<Item> history;
+ history.push_back(Item());
+
+ // Run the child process.
+ apr_procattr_t *procattr = NULL;
+ aprchk(apr_procattr_create(&procattr, pool.getAPRPool()));
+ aprchk(apr_procattr_io_set(procattr, APR_CHILD_BLOCK, APR_CHILD_BLOCK, APR_CHILD_BLOCK));
+ aprchk(apr_procattr_cmdtype_set(procattr, APR_PROGRAM_PATH));
+
+ std::vector<const char*> argv;
+ apr_proc_t child;
+ argv.push_back("python");
+ // Have to have a named copy of this std::string so its c_str() value
+ // will persist.
+ std::string scriptname(script.getName());
+ argv.push_back(scriptname.c_str());
+ argv.push_back(NULL);
+
+ aprchk(apr_proc_create(&child, argv[0],
+ &argv[0],
+ NULL, // if we wanted to pass explicit environment
+ procattr,
+ pool.getAPRPool()));
+
+ // We do not want this child process to outlive our APR pool. On
+ // destruction of the pool, forcibly kill the process. Tell APR to try
+ // SIGTERM and wait 3 seconds. If that didn't work, use SIGKILL.
+ apr_pool_note_subprocess(pool.getAPRPool(), &child, APR_KILL_AFTER_TIMEOUT);
+
+ // arrange to call child_status_callback()
+ WaitInfo wi(&child);
+ apr_proc_other_child_register(&child, child_status_callback, &wi, child.in, pool.getAPRPool());
+
+ // TODO:
+ // Stuff child.in until it (would) block to verify EWOULDBLOCK/EAGAIN.
+ // Have child script clear it later, then write one more line to prove
+ // that it gets through.
+
+ // Monitor two different output pipes. Because one will be closed
+ // before the other, keep them in a list so we can drop whichever of
+ // them is closed first.
+ typedef std::pair<std::string, apr_file_t*> DescFile;
+ typedef std::list<DescFile> DescFileList;
+ DescFileList outfiles;
+ outfiles.push_back(DescFile("out", child.out));
+ outfiles.push_back(DescFile("err", child.err));
+
+ while (! outfiles.empty())
+ {
+ // This peculiar for loop is designed to let us erase(dfli). With
+ // a list, that invalidates only dfli itself -- but even so, we
+ // lose the ability to increment it for the next item. So at the
+ // top of every loop, while dfli is still valid, increment
+ // dflnext. Then before the next iteration, set dfli to dflnext.
+ for (DescFileList::iterator
+ dfli(outfiles.begin()), dflnext(outfiles.begin()), dflend(outfiles.end());
+ dfli != dflend; dfli = dflnext)
+ {
+ // Only valid to increment dflnext once we're sure it's not
+ // already at dflend.
+ ++dflnext;
+
+ char buf[4096];
+
+ apr_status_t rv = apr_file_gets(buf, sizeof(buf), dfli->second);
+ if (APR_STATUS_IS_EOF(rv))
+ {
+// std::cout << "(EOF on " << dfli->first << ")\n";
+// history.back().which = dfli->first;
+// history.back().what = "*eof*";
+// history.push_back(Item());
+ outfiles.erase(dfli);
+ continue;
+ }
+ if (rv == EWOULDBLOCK || rv == EAGAIN)
+ {
+// std::cout << "(waiting; apr_file_gets(" << dfli->first << ") => " << rv << ": " << manager.strerror(rv) << ")\n";
+ ++history.back().tries;
+ continue;
+ }
+ aprchk_("apr_file_gets(buf, sizeof(buf), dfli->second)", rv);
+ // Is it even possible to get APR_SUCCESS but read 0 bytes?
+ // Hope not, but defend against that anyway.
+ if (buf[0])
+ {
+// std::cout << dfli->first << ": " << buf;
+ history.back().which = dfli->first;
+ history.back().what.append(buf);
+ if (buf[strlen(buf) - 1] == '\n')
+ history.push_back(Item());
+ else
+ {
+ // Just for pretty output... if we only read a partial
+ // line, terminate it.
+// std::cout << "...\n";
+ }
+ }
+ }
+ // Do this once per tick, as we expect the viewer will
+ apr_proc_other_child_refresh_all(APR_OC_REASON_RUNNING);
+ sleep(1);
+ }
+ apr_file_close(child.in);
+ apr_file_close(child.out);
+ apr_file_close(child.err);
+
+ // Okay, we've broken the loop because our pipes are all closed. If we
+ // haven't yet called wait, give the callback one more chance. This
+ // models the fact that unlike this small test program, the viewer
+ // will still be running.
+ if (wi.rv == -1)
+ {
+ std::cout << "last gasp apr_proc_other_child_refresh_all()\n";
+ apr_proc_other_child_refresh_all(APR_OC_REASON_RUNNING);
+ }
+
+ if (wi.rv == -1)
+ {
+ std::cout << "child_status_callback(APR_OC_REASON_DEATH) wasn't called" << std::endl;
+ wi.rv = apr_proc_wait(wi.child, &wi.rc, &wi.why, APR_NOWAIT);
+ }
+// std::cout << "child done: rv = " << rv << " (" << manager.strerror(rv) << "), why = " << why << ", rc = " << rc << '\n';
+ aprchk_("apr_proc_wait(wi->child, &wi->rc, &wi->why, APR_NOWAIT)", wi.rv, APR_CHILD_DONE);
+ ensure_equals_(wi.why, APR_PROC_EXIT);
+ ensure_equals_(wi.rc, 0);
+
+ // Beyond merely executing all the above successfully, verify that we
+ // obtained expected output -- and that we duly got control while
+ // waiting, proving the non-blocking nature of these pipes.
+ try
+ {
+ unsigned i = 0;
+ ensure("blocking I/O on child pipe (0)", history[i].tries);
+ ensure_equals_(history[i].which, "out");
+ ensure_equals_(history[i].what, "stdout after wait" EOL);
+// ++i;
+// ensure_equals_(history[i].which, "out");
+// ensure_equals_(history[i].what, "*eof*");
+ ++i;
+ ensure("blocking I/O on child pipe (1)", history[i].tries);
+ ensure_equals_(history[i].which, "err");
+ ensure_equals_(history[i].what, "stderr after wait" EOL);
+// ++i;
+// ensure_equals_(history[i].which, "err");
+// ensure_equals_(history[i].what, "*eof*");
+ }
+ catch (const failure&)
+ {
+ std::cout << "History:\n";
+ BOOST_FOREACH(const Item& item, history)
+ {
+ std::string what(item.what);
+ if ((! what.empty()) && what[what.length() - 1] == '\n')
+ {
+ what.erase(what.length() - 1);
+ if ((! what.empty()) && what[what.length() - 1] == '\r')
+ {
+ what.erase(what.length() - 1);
+ what.append("\\r");
+ }
+ what.append("\\n");
+ }
+ std::cout << " " << item.which << ": '" << what << "' ("
+ << item.tries << " tries)\n";
+ }
+ std::cout << std::flush;
+ // re-raise same error; just want to enrich the output
+ throw;
+ }
+ }
+
+ template<> template<>
+ void object::test<2>()
+ {
+ set_test_name("setWorkingDirectory()");
+ // We want to test setWorkingDirectory(). But what directory is
+ // guaranteed to exist on every machine, under every OS? Have to
+ // create one. Naturally, ensure we clean it up when done.
+ NamedTempDir tempdir;
+ PythonProcessLauncher py(get_test_name(),
+ "from __future__ import with_statement\n"
+ "import os, sys\n"
+ "with open(sys.argv[1], 'w') as f:\n"
+ " f.write(os.path.normcase(os.path.normpath(os.getcwd())))\n");
+ // Before running, call setWorkingDirectory()
+ py.mParams.cwd = tempdir.getName();
+ ensure_equals("os.getcwd()", py.run_read(), tempdir.getName());
+ }
+
+ template<> template<>
+ void object::test<3>()
+ {
+ set_test_name("arguments");
+ PythonProcessLauncher py(get_test_name(),
+ "from __future__ import with_statement\n"
+ "import sys\n"
+ // note nonstandard output-file arg!
+ "with open(sys.argv[3], 'w') as f:\n"
+ " for arg in sys.argv[1:]:\n"
+ " print >>f, arg\n");
+ // We expect that PythonProcessLauncher has already appended
+ // its own NamedTempFile to mParams.args (sys.argv[0]).
+ py.mParams.args.add("first arg"); // sys.argv[1]
+ py.mParams.args.add("second arg"); // sys.argv[2]
+ // run_read() appends() one more argument, hence [3]
+ std::string output(py.run_read());
+ boost::split_iterator<std::string::const_iterator>
+ li(output, boost::first_finder("\n")), lend;
+ ensure("didn't get first arg", li != lend);
+ std::string arg(li->begin(), li->end());
+ ensure_equals(arg, "first arg");
+ ++li;
+ ensure("didn't get second arg", li != lend);
+ arg.assign(li->begin(), li->end());
+ ensure_equals(arg, "second arg");
+ ++li;
+ ensure("didn't get output filename?!", li != lend);
+ arg.assign(li->begin(), li->end());
+ ensure("output filename empty?!", ! arg.empty());
+ ++li;
+ ensure("too many args", li == lend);
+ }
+
+ template<> template<>
+ void object::test<4>()
+ {
+ set_test_name("exit(0)");
+ PythonProcessLauncher py(get_test_name(),
+ "import sys\n"
+ "sys.exit(0)\n");
+ py.run();
+ ensure_equals("Status.mState", py.mPy->getStatus().mState, LLProcess::EXITED);
+ ensure_equals("Status.mData", py.mPy->getStatus().mData, 0);
+ }
+
+ template<> template<>
+ void object::test<5>()
+ {
+ set_test_name("exit(2)");
+ PythonProcessLauncher py(get_test_name(),
+ "import sys\n"
+ "sys.exit(2)\n");
+ py.run();
+ ensure_equals("Status.mState", py.mPy->getStatus().mState, LLProcess::EXITED);
+ ensure_equals("Status.mData", py.mPy->getStatus().mData, 2);
+ }
+
+ template<> template<>
+ void object::test<6>()
+ {
+ set_test_name("syntax_error");
+ PythonProcessLauncher py(get_test_name(),
+ "syntax_error:\n");
+ py.mParams.files.add(LLProcess::FileParam()); // inherit stdin
+ py.mParams.files.add(LLProcess::FileParam()); // inherit stdout
+ py.mParams.files.add(LLProcess::FileParam().type("pipe")); // pipe for stderr
+ py.run();
+ ensure_equals("Status.mState", py.mPy->getStatus().mState, LLProcess::EXITED);
+ ensure_equals("Status.mData", py.mPy->getStatus().mData, 1);
+ std::istream& rpipe(py.mPy->getReadPipe(LLProcess::STDERR).get_istream());
+ std::vector<char> buffer(4096);
+ rpipe.read(&buffer[0], buffer.size());
+ std::streamsize got(rpipe.gcount());
+ ensure("Nothing read from stderr pipe", got);
+ std::string data(&buffer[0], got);
+ ensure("Didn't find 'SyntaxError:'", data.find("\nSyntaxError:") != std::string::npos);
+ }
+
+ template<> template<>
+ void object::test<7>()
+ {
+ set_test_name("explicit kill()");
+ PythonProcessLauncher py(get_test_name(),
+ "from __future__ import with_statement\n"
+ "import sys, time\n"
+ "with open(sys.argv[1], 'w') as f:\n"
+ " f.write('ok')\n"
+ "# now sleep; expect caller to kill\n"
+ "time.sleep(120)\n"
+ "# if caller hasn't managed to kill by now, bad\n"
+ "with open(sys.argv[1], 'w') as f:\n"
+ " f.write('bad')\n");
+ NamedTempFile out("out", "not started");
+ py.mParams.args.add(out.getName());
+ py.launch();
+ // Wait for the script to wake up and do its first write
+ int i = 0, timeout = 60;
+ for ( ; i < timeout; ++i)
+ {
+ yield();
+ if (readfile(out.getName(), "from kill() script") == "ok")
+ break;
+ }
+ // If we broke this loop because of the counter, something's wrong
+ ensure("script never started", i < timeout);
+ // script has performed its first write and should now be sleeping.
+ py.mPy->kill();
+ // wait for the script to terminate... one way or another.
+ waitfor(*py.mPy);
+#if LL_WINDOWS
+ ensure_equals("Status.mState", py.mPy->getStatus().mState, LLProcess::EXITED);
+ ensure_equals("Status.mData", py.mPy->getStatus().mData, -1);
+#else
+ ensure_equals("Status.mState", py.mPy->getStatus().mState, LLProcess::KILLED);
+ ensure_equals("Status.mData", py.mPy->getStatus().mData, SIGTERM);
+#endif
+ // If kill() failed, the script would have woken up on its own and
+ // overwritten the file with 'bad'. But if kill() succeeded, it should
+ // not have had that chance.
+ ensure_equals(get_test_name() + " script output", readfile(out.getName()), "ok");
+ }
+
+ template<> template<>
+ void object::test<8>()
+ {
+ set_test_name("implicit kill()");
+ NamedTempFile out("out", "not started");
+ LLProcess::handle phandle(0);
+ {
+ PythonProcessLauncher py(get_test_name(),
+ "from __future__ import with_statement\n"
+ "import sys, time\n"
+ "with open(sys.argv[1], 'w') as f:\n"
+ " f.write('ok')\n"
+ "# now sleep; expect caller to kill\n"
+ "time.sleep(120)\n"
+ "# if caller hasn't managed to kill by now, bad\n"
+ "with open(sys.argv[1], 'w') as f:\n"
+ " f.write('bad')\n");
+ py.mParams.args.add(out.getName());
+ py.launch();
+ // Capture handle for later
+ phandle = py.mPy->getProcessHandle();
+ // Wait for the script to wake up and do its first write
+ int i = 0, timeout = 60;
+ for ( ; i < timeout; ++i)
+ {
+ yield();
+ if (readfile(out.getName(), "from kill() script") == "ok")
+ break;
+ }
+ // If we broke this loop because of the counter, something's wrong
+ ensure("script never started", i < timeout);
+ // Script has performed its first write and should now be sleeping.
+ // Destroy the LLProcess, which should kill the child.
+ }
+ // wait for the script to terminate... one way or another.
+ waitfor(phandle, "kill() script");
+ // If kill() failed, the script would have woken up on its own and
+ // overwritten the file with 'bad'. But if kill() succeeded, it should
+ // not have had that chance.
+ ensure_equals(get_test_name() + " script output", readfile(out.getName()), "ok");
+ }
+
+ template<> template<>
+ void object::test<9>()
+ {
+ set_test_name("autokill=false");
+ NamedTempFile from("from", "not started");
+ NamedTempFile to("to", "");
+ LLProcess::handle phandle(0);
+ {
+ PythonProcessLauncher py(get_test_name(),
+ "from __future__ import with_statement\n"
+ "import sys, time\n"
+ "with open(sys.argv[1], 'w') as f:\n"
+ " f.write('ok')\n"
+ "# wait for 'go' from test program\n"
+ "for i in xrange(60):\n"
+ " time.sleep(1)\n"
+ " with open(sys.argv[2]) as f:\n"
+ " go = f.read()\n"
+ " if go == 'go':\n"
+ " break\n"
+ "else:\n"
+ " with open(sys.argv[1], 'w') as f:\n"
+ " f.write('never saw go')\n"
+ " sys.exit(1)\n"
+ "# okay, saw 'go', write 'ack'\n"
+ "with open(sys.argv[1], 'w') as f:\n"
+ " f.write('ack')\n");
+ py.mParams.args.add(from.getName());
+ py.mParams.args.add(to.getName());
+ py.mParams.autokill = false;
+ py.launch();
+ // Capture handle for later
+ phandle = py.mPy->getProcessHandle();
+ // Wait for the script to wake up and do its first write
+ int i = 0, timeout = 60;
+ for ( ; i < timeout; ++i)
+ {
+ yield();
+ if (readfile(from.getName(), "from autokill script") == "ok")
+ break;
+ }
+ // If we broke this loop because of the counter, something's wrong
+ ensure("script never started", i < timeout);
+ // Now destroy the LLProcess, which should NOT kill the child!
+ }
+ // If the destructor killed the child anyway, give it time to die
+ yield(2);
+ // How do we know it's not terminated? By making it respond to
+ // a specific stimulus in a specific way.
+ {
+ std::ofstream outf(to.getName().c_str());
+ outf << "go";
+ } // flush and close.
+ // now wait for the script to terminate... one way or another.
+ waitfor(phandle, "autokill script");
+ // If the LLProcess destructor implicitly called kill(), the
+ // script could not have written 'ack' as we expect.
+ ensure_equals(get_test_name() + " script output", readfile(from.getName()), "ack");
+ }
+
+ template<> template<>
+ void object::test<10>()
+ {
+ set_test_name("'bogus' test");
+ CaptureLog recorder;
+ PythonProcessLauncher py(get_test_name(),
+ "print 'Hello world'\n");
+ py.mParams.files.add(LLProcess::FileParam("bogus"));
+ py.mPy = LLProcess::create(py.mParams);
+ ensure("should have rejected 'bogus'", ! py.mPy);
+ std::string message(recorder.messageWith("bogus"));
+ ensure_contains("did not name 'stdin'", message, "stdin");
+ }
+
+ template<> template<>
+ void object::test<11>()
+ {
+ set_test_name("'file' test");
+ // Replace this test with one or more real 'file' tests when we
+ // implement 'file' support
+ PythonProcessLauncher py(get_test_name(),
+ "print 'Hello world'\n");
+ py.mParams.files.add(LLProcess::FileParam());
+ py.mParams.files.add(LLProcess::FileParam("file"));
+ py.mPy = LLProcess::create(py.mParams);
+ ensure("should have rejected 'file'", ! py.mPy);
+ }
+
+ template<> template<>
+ void object::test<12>()
+ {
+ set_test_name("'tpipe' test");
+ // Replace this test with one or more real 'tpipe' tests when we
+ // implement 'tpipe' support
+ CaptureLog recorder;
+ PythonProcessLauncher py(get_test_name(),
+ "print 'Hello world'\n");
+ py.mParams.files.add(LLProcess::FileParam());
+ py.mParams.files.add(LLProcess::FileParam("tpipe"));
+ py.mPy = LLProcess::create(py.mParams);
+ ensure("should have rejected 'tpipe'", ! py.mPy);
+ std::string message(recorder.messageWith("tpipe"));
+ ensure_contains("did not name 'stdout'", message, "stdout");
+ }
+
+ template<> template<>
+ void object::test<13>()
+ {
+ set_test_name("'npipe' test");
+ // Replace this test with one or more real 'npipe' tests when we
+ // implement 'npipe' support
+ CaptureLog recorder;
+ PythonProcessLauncher py(get_test_name(),
+ "print 'Hello world'\n");
+ py.mParams.files.add(LLProcess::FileParam());
+ py.mParams.files.add(LLProcess::FileParam());
+ py.mParams.files.add(LLProcess::FileParam("npipe"));
+ py.mPy = LLProcess::create(py.mParams);
+ ensure("should have rejected 'npipe'", ! py.mPy);
+ std::string message(recorder.messageWith("npipe"));
+ ensure_contains("did not name 'stderr'", message, "stderr");
+ }
+
+ template<> template<>
+ void object::test<14>()
+ {
+ set_test_name("internal pipe name warning");
+ CaptureLog recorder;
+ PythonProcessLauncher py(get_test_name(),
+ "import sys\n"
+ "sys.exit(7)\n");
+ py.mParams.files.add(LLProcess::FileParam("pipe", "somename"));
+ py.run(); // verify that it did launch anyway
+ ensure_equals("Status.mState", py.mPy->getStatus().mState, LLProcess::EXITED);
+ ensure_equals("Status.mData", py.mPy->getStatus().mData, 7);
+ std::string message(recorder.messageWith("not yet supported"));
+ ensure_contains("log message did not mention internal pipe name",
+ message, "somename");
+ }
+
+ /*-------------- support for "get*Pipe() validation" test --------------*/
+#define TEST_getPipe(PROCESS, GETPIPE, GETOPTPIPE, VALID, NOPIPE, BADPIPE) \
+ do \
+ { \
+ std::string threw; \
+ /* Both the following calls should work. */ \
+ (PROCESS).GETPIPE(VALID); \
+ ensure(#GETOPTPIPE "(" #VALID ") failed", (PROCESS).GETOPTPIPE(VALID)); \
+ /* pass obviously bogus PIPESLOT */ \
+ CATCH_IN(threw, LLProcess::NoPipe, (PROCESS).GETPIPE(LLProcess::FILESLOT(4))); \
+ ensure_contains("didn't reject bad slot", threw, "no slot"); \
+ ensure_contains("didn't mention bad slot num", threw, "4"); \
+ EXPECT_FAIL_WITH_LOG(threw, (PROCESS).GETOPTPIPE(LLProcess::FILESLOT(4))); \
+ /* pass NOPIPE */ \
+ CATCH_IN(threw, LLProcess::NoPipe, (PROCESS).GETPIPE(NOPIPE)); \
+ ensure_contains("didn't reject non-pipe", threw, "not a monitored"); \
+ EXPECT_FAIL_WITH_LOG(threw, (PROCESS).GETOPTPIPE(NOPIPE)); \
+ /* pass BADPIPE: FILESLOT isn't empty but wrong direction */ \
+ CATCH_IN(threw, LLProcess::NoPipe, (PROCESS).GETPIPE(BADPIPE)); \
+ /* sneaky: GETPIPE is getReadPipe or getWritePipe */ \
+ /* so skip "get" to obtain ReadPipe or WritePipe :-P */ \
+ ensure_contains("didn't reject wrong pipe", threw, (#GETPIPE)+3); \
+ EXPECT_FAIL_WITH_LOG(threw, (PROCESS).GETOPTPIPE(BADPIPE)); \
+ } while (0)
+
+/// For expecting exceptions. Execute CODE, catch EXCEPTION, store its what()
+/// in std::string THREW, ensure it's not empty (i.e. EXCEPTION did happen).
+#define CATCH_IN(THREW, EXCEPTION, CODE) \
+ do \
+ { \
+ (THREW).clear(); \
+ try \
+ { \
+ CODE; \
+ } \
+ CATCH_AND_STORE_WHAT_IN(THREW, EXCEPTION) \
+ ensure("failed to throw " #EXCEPTION ": " #CODE, ! (THREW).empty()); \
+ } while (0)
+
+#define EXPECT_FAIL_WITH_LOG(EXPECT, CODE) \
+ do \
+ { \
+ CaptureLog recorder; \
+ ensure(#CODE " succeeded", ! (CODE)); \
+ recorder.messageWith(EXPECT); \
+ } while (0)
+
+ template<> template<>
+ void object::test<15>()
+ {
+ set_test_name("get*Pipe() validation");
+ PythonProcessLauncher py(get_test_name(),
+ "print 'this output is expected'\n");
+ py.mParams.files.add(LLProcess::FileParam("pipe")); // pipe for stdin
+ py.mParams.files.add(LLProcess::FileParam()); // inherit stdout
+ py.mParams.files.add(LLProcess::FileParam("pipe")); // pipe for stderr
+ py.run();
+ TEST_getPipe(*py.mPy, getWritePipe, getOptWritePipe,
+ LLProcess::STDIN, // VALID
+ LLProcess::STDOUT, // NOPIPE
+ LLProcess::STDERR); // BADPIPE
+ TEST_getPipe(*py.mPy, getReadPipe, getOptReadPipe,
+ LLProcess::STDERR, // VALID
+ LLProcess::STDOUT, // NOPIPE
+ LLProcess::STDIN); // BADPIPE
+ }
+
+ template<> template<>
+ void object::test<16>()
+ {
+ set_test_name("talk to stdin/stdout");
+ PythonProcessLauncher py(get_test_name(),
+ "import sys, time\n"
+ "print 'ok'\n"
+ "sys.stdout.flush()\n"
+ "# wait for 'go' from test program\n"
+ "go = sys.stdin.readline()\n"
+ "if go != 'go\\n':\n"
+ " sys.exit('expected \"go\", saw %r' % go)\n"
+ "print 'ack'\n");
+ py.mParams.files.add(LLProcess::FileParam("pipe")); // stdin
+ py.mParams.files.add(LLProcess::FileParam("pipe")); // stdout
+ py.launch();
+ LLProcess::ReadPipe& childout(py.mPy->getReadPipe(LLProcess::STDOUT));
+ int i, timeout = 60;
+ for (i = 0; i < timeout && py.mPy->isRunning() && childout.size() < 3; ++i)
+ {
+ yield();
+ }
+ ensure("script never started", i < timeout);
+ ensure_equals("bad wakeup from stdin/stdout script",
+ childout.getline(), "ok");
+ // important to get the implicit flush from std::endl
+ py.mPy->getWritePipe().get_ostream() << "go" << std::endl;
+ waitfor(*py.mPy);
+ ensure("script never replied", childout.contains("\n"));
+ ensure_equals("child didn't ack", childout.getline(), "ack");
+ ensure_equals("bad child termination", py.mPy->getStatus().mState, LLProcess::EXITED);
+ ensure_equals("bad child exit code", py.mPy->getStatus().mData, 0);
+ }
+
+ struct EventListener: public boost::noncopyable
+ {
+ EventListener(LLEventPump& pump)
+ {
+ mConnection =
+ pump.listen("EventListener", boost::bind(&EventListener::tick, this, _1));
+ }
+
+ bool tick(const LLSD& data)
+ {
+ mHistory.push_back(data);
+ return false;
+ }
+
+ std::list<LLSD> mHistory;
+ LLTempBoundListener mConnection;
+ };
+
+ static bool ack(std::ostream& out, const LLSD& data)
+ {
+ out << "continue" << std::endl;
+ return false;
+ }
+
+ template<> template<>
+ void object::test<17>()
+ {
+ set_test_name("listen for ReadPipe events");
+ PythonProcessLauncher py(get_test_name(),
+ "import sys\n"
+ "sys.stdout.write('abc')\n"
+ "sys.stdout.flush()\n"
+ "sys.stdin.readline()\n"
+ "sys.stdout.write('def')\n"
+ "sys.stdout.flush()\n"
+ "sys.stdin.readline()\n"
+ "sys.stdout.write('ghi\\n')\n"
+ "sys.stdout.flush()\n"
+ "sys.stdin.readline()\n"
+ "sys.stdout.write('second line\\n')\n");
+ py.mParams.files.add(LLProcess::FileParam("pipe")); // stdin
+ py.mParams.files.add(LLProcess::FileParam("pipe")); // stdout
+ py.launch();
+ std::ostream& childin(py.mPy->getWritePipe(LLProcess::STDIN).get_ostream());
+ LLProcess::ReadPipe& childout(py.mPy->getReadPipe(LLProcess::STDOUT));
+ // lift the default limit; allow event to carry (some of) the actual data
+ childout.setLimit(20);
+ // listen for incoming data on childout
+ EventListener listener(childout.getPump());
+ // also listen with a function that prompts the child to continue
+ // every time we see output
+ LLTempBoundListener connection(
+ childout.getPump().listen("ack", boost::bind(ack, boost::ref(childin), _1)));
+ int i, timeout = 60;
+ // wait through stuttering first line
+ for (i = 0; i < timeout && py.mPy->isRunning() && ! childout.contains("\n"); ++i)
+ {
+ yield();
+ }
+ ensure("couldn't get first line", i < timeout);
+ // disconnect from listener
+ listener.mConnection.disconnect();
+ // finish out the run
+ waitfor(*py.mPy);
+ // now verify history
+ std::list<LLSD>::const_iterator li(listener.mHistory.begin()),
+ lend(listener.mHistory.end());
+ ensure("no events", li != lend);
+ ensure_equals("history[0]", (*li)["data"].asString(), "abc");
+ ensure_equals("history[0] len", (*li)["len"].asInteger(), 3);
+ ++li;
+ ensure("only 1 event", li != lend);
+ ensure_equals("history[1]", (*li)["data"].asString(), "abcdef");
+ ensure_equals("history[0] len", (*li)["len"].asInteger(), 6);
+ ++li;
+ ensure("only 2 events", li != lend);
+ ensure_equals("history[2]", (*li)["data"].asString(), "abcdefghi" EOL);
+ ensure_equals("history[0] len", (*li)["len"].asInteger(), 9 + sizeof(EOL) - 1);
+ ++li;
+ // We DO NOT expect a whole new event for the second line because we
+ // disconnected.
+ ensure("more than 3 events", li == lend);
+ }
+
+ template<> template<>
+ void object::test<18>()
+ {
+ set_test_name("ReadPipe \"eof\" event");
+ PythonProcessLauncher py(get_test_name(),
+ "print 'Hello from Python!'\n");
+ py.mParams.files.add(LLProcess::FileParam()); // stdin
+ py.mParams.files.add(LLProcess::FileParam("pipe")); // stdout
+ py.launch();
+ LLProcess::ReadPipe& childout(py.mPy->getReadPipe(LLProcess::STDOUT));
+ EventListener listener(childout.getPump());
+ waitfor(*py.mPy);
+ // We can't be positive there will only be a single event, if the OS
+ // (or any other intervening layer) does crazy buffering. What we want
+ // to ensure is that there was exactly ONE event with "eof" true, and
+ // that it was the LAST event.
+ std::list<LLSD>::const_reverse_iterator rli(listener.mHistory.rbegin()),
+ rlend(listener.mHistory.rend());
+ ensure("no events", rli != rlend);
+ ensure("last event not \"eof\"", (*rli)["eof"].asBoolean());
+ while (++rli != rlend)
+ {
+ ensure("\"eof\" event not last", ! (*rli)["eof"].asBoolean());
+ }
+ }
+
+ template<> template<>
+ void object::test<19>()
+ {
+ set_test_name("setLimit()");
+ PythonProcessLauncher py(get_test_name(),
+ "import sys\n"
+ "sys.stdout.write(sys.argv[1])\n");
+ std::string abc("abcdefghijklmnopqrstuvwxyz");
+ py.mParams.args.add(abc);
+ py.mParams.files.add(LLProcess::FileParam()); // stdin
+ py.mParams.files.add(LLProcess::FileParam("pipe")); // stdout
+ py.launch();
+ LLProcess::ReadPipe& childout(py.mPy->getReadPipe(LLProcess::STDOUT));
+ // listen for incoming data on childout
+ EventListener listener(childout.getPump());
+ // but set limit
+ childout.setLimit(10);
+ ensure_equals("getLimit() after setlimit(10)", childout.getLimit(), 10);
+ // okay, pump I/O to pick up output from child
+ waitfor(*py.mPy);
+ ensure("no events", ! listener.mHistory.empty());
+ // For all we know, that data could have arrived in several different
+ // bursts... probably not, but anyway, only check the last one.
+ ensure_equals("event[\"len\"]",
+ listener.mHistory.back()["len"].asInteger(), abc.length());
+ ensure_equals("length of setLimit(10) data",
+ listener.mHistory.back()["data"].asString().length(), 10);
+ }
+
+ template<> template<>
+ void object::test<20>()
+ {
+ set_test_name("peek() ReadPipe data");
+ PythonProcessLauncher py(get_test_name(),
+ "import sys\n"
+ "sys.stdout.write(sys.argv[1])\n");
+ std::string abc("abcdefghijklmnopqrstuvwxyz");
+ py.mParams.args.add(abc);
+ py.mParams.files.add(LLProcess::FileParam()); // stdin
+ py.mParams.files.add(LLProcess::FileParam("pipe")); // stdout
+ py.launch();
+ LLProcess::ReadPipe& childout(py.mPy->getReadPipe(LLProcess::STDOUT));
+ // okay, pump I/O to pick up output from child
+ waitfor(*py.mPy);
+ // peek() with substr args
+ ensure_equals("peek()", childout.peek(), abc);
+ ensure_equals("peek(23)", childout.peek(23), abc.substr(23));
+ ensure_equals("peek(5, 3)", childout.peek(5, 3), abc.substr(5, 3));
+ ensure_equals("peek(27, 2)", childout.peek(27, 2), "");
+ ensure_equals("peek(23, 5)", childout.peek(23, 5), "xyz");
+ // contains() -- we don't exercise as thoroughly as find() because the
+ // contains() implementation is trivially (and visibly) based on find()
+ ensure("contains(\":\")", ! childout.contains(":"));
+ ensure("contains(':')", ! childout.contains(':'));
+ ensure("contains(\"d\")", childout.contains("d"));
+ ensure("contains('d')", childout.contains('d'));
+ ensure("contains(\"klm\")", childout.contains("klm"));
+ ensure("contains(\"klx\")", ! childout.contains("klx"));
+ // find()
+ ensure("find(\":\")", childout.find(":") == LLProcess::ReadPipe::npos);
+ ensure("find(':')", childout.find(':') == LLProcess::ReadPipe::npos);
+ ensure_equals("find(\"d\")", childout.find("d"), 3);
+ ensure_equals("find('d')", childout.find('d'), 3);
+ ensure_equals("find(\"d\", 3)", childout.find("d", 3), 3);
+ ensure_equals("find('d', 3)", childout.find('d', 3), 3);
+ ensure("find(\"d\", 4)", childout.find("d", 4) == LLProcess::ReadPipe::npos);
+ ensure("find('d', 4)", childout.find('d', 4) == LLProcess::ReadPipe::npos);
+ // The case of offset == end and offset > end are different. In the
+ // first case, we can form a valid (albeit empty) iterator range and
+ // search that. In the second, guard logic in the implementation must
+ // realize we can't form a valid iterator range.
+ ensure("find(\"d\", 26)", childout.find("d", 26) == LLProcess::ReadPipe::npos);
+ ensure("find('d', 26)", childout.find('d', 26) == LLProcess::ReadPipe::npos);
+ ensure("find(\"d\", 27)", childout.find("d", 27) == LLProcess::ReadPipe::npos);
+ ensure("find('d', 27)", childout.find('d', 27) == LLProcess::ReadPipe::npos);
+ ensure_equals("find(\"ghi\")", childout.find("ghi"), 6);
+ ensure_equals("find(\"ghi\", 6)", childout.find("ghi"), 6);
+ ensure("find(\"ghi\", 7)", childout.find("ghi", 7) == LLProcess::ReadPipe::npos);
+ ensure("find(\"ghi\", 26)", childout.find("ghi", 26) == LLProcess::ReadPipe::npos);
+ ensure("find(\"ghi\", 27)", childout.find("ghi", 27) == LLProcess::ReadPipe::npos);
+ }
+
+ template<> template<>
+ void object::test<21>()
+ {
+ set_test_name("bad postend");
+ std::string pumpname("postend");
+ EventListener listener(LLEventPumps::instance().obtain(pumpname));
+ LLProcess::Params params;
+ params.desc = get_test_name();
+ params.postend = pumpname;
+ LLProcessPtr child = LLProcess::create(params);
+ ensure("shouldn't have launched", ! child);
+ ensure_equals("number of postend events", listener.mHistory.size(), 1);
+ LLSD postend(listener.mHistory.front());
+ ensure("has id", ! postend.has("id"));
+ ensure_equals("desc", postend["desc"].asString(), std::string(params.desc));
+ ensure_equals("state", postend["state"].asInteger(), LLProcess::UNSTARTED);
+ ensure("has data", ! postend.has("data"));
+ std::string error(postend["string"]);
+ // All we get from canned parameter validation is a bool, so the
+ // "validation failed" message we ourselves generate can't mention
+ // "executable" by name. Just check that it's nonempty.
+ //ensure_contains("error", error, "executable");
+ ensure("string", ! error.empty());
+ }
+
+ template<> template<>
+ void object::test<22>()
+ {
+ set_test_name("good postend");
+ PythonProcessLauncher py(get_test_name(),
+ "import sys\n"
+ "sys.exit(35)\n");
+ std::string pumpname("postend");
+ EventListener listener(LLEventPumps::instance().obtain(pumpname));
+ py.mParams.postend = pumpname;
+ py.launch();
+ LLProcess::id childid(py.mPy->getProcessID());
+ // Don't use waitfor(), which calls isRunning(); instead wait for an
+ // event on pumpname.
+ int i, timeout = 60;
+ for (i = 0; i < timeout && listener.mHistory.empty(); ++i)
+ {
+ yield();
+ }
+ ensure("no postend event", i < timeout);
+ ensure_equals("number of postend events", listener.mHistory.size(), 1);
+ LLSD postend(listener.mHistory.front());
+ ensure_equals("id", postend["id"].asInteger(), childid);
+ ensure("desc empty", ! postend["desc"].asString().empty());
+ ensure_equals("state", postend["state"].asInteger(), LLProcess::EXITED);
+ ensure_equals("data", postend["data"].asInteger(), 35);
+ std::string str(postend["string"]);
+ ensure_contains("string", str, "exited");
+ ensure_contains("string", str, "35");
+ }
+
+ struct PostendListener
+ {
+ PostendListener(LLProcess::ReadPipe& rpipe,
+ const std::string& pumpname,
+ const std::string& expect):
+ mReadPipe(rpipe),
+ mExpect(expect),
+ mTriggered(false)
+ {
+ LLEventPumps::instance().obtain(pumpname)
+ .listen("PostendListener", boost::bind(&PostendListener::postend, this, _1));
+ }
+
+ bool postend(const LLSD&)
+ {
+ mTriggered = true;
+ ensure_equals("postend listener", mReadPipe.read(mReadPipe.size()), mExpect);
+ return false;
+ }
+
+ LLProcess::ReadPipe& mReadPipe;
+ std::string mExpect;
+ bool mTriggered;
+ };
+
+ template<> template<>
+ void object::test<23>()
+ {
+ set_test_name("all data visible at postend");
+ PythonProcessLauncher py(get_test_name(),
+ "import sys\n"
+ // note, no '\n' in written data
+ "sys.stdout.write('partial line')\n");
+ std::string pumpname("postend");
+ py.mParams.files.add(LLProcess::FileParam()); // stdin
+ py.mParams.files.add(LLProcess::FileParam("pipe")); // stdout
+ py.mParams.postend = pumpname;
+ py.launch();
+ PostendListener listener(py.mPy->getReadPipe(LLProcess::STDOUT),
+ pumpname,
+ "partial line");
+ waitfor(*py.mPy);
+ ensure("postend never triggered", listener.mTriggered);
+ }
+} // namespace tut
diff --git a/indra/llcommon/tests/llprocessor_test.cpp b/indra/llcommon/tests/llprocessor_test.cpp
index 884e1b5e5b..884e1b5e5b 100644..100755
--- a/indra/llcommon/tests/llprocessor_test.cpp
+++ b/indra/llcommon/tests/llprocessor_test.cpp
diff --git a/indra/llcommon/tests/llrand_test.cpp b/indra/llcommon/tests/llrand_test.cpp
index 383e6f9e0a..383e6f9e0a 100644..100755
--- a/indra/llcommon/tests/llrand_test.cpp
+++ b/indra/llcommon/tests/llrand_test.cpp
diff --git a/indra/llcommon/tests/llsdserialize_test.cpp b/indra/llcommon/tests/llsdserialize_test.cpp
index 72322c3b72..4d436e8897 100644..100755
--- a/indra/llcommon/tests/llsdserialize_test.cpp
+++ b/indra/llcommon/tests/llsdserialize_test.cpp
@@ -40,41 +40,15 @@ typedef U32 uint32_t;
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/wait.h>
-#include "llprocesslauncher.h"
+#include "llprocess.h"
#endif
-#include <sstream>
-
-/*==========================================================================*|
-// Whoops, seems Linden's Boost package and the viewer are built with
-// different settings of VC's /Zc:wchar_t switch! Using Boost.Filesystem
-// pathname operations produces Windows link errors:
-// unresolved external symbol "private: static class std::codecvt<unsigned short,
-// char,int> const * & __cdecl boost::filesystem3::path::wchar_t_codecvt_facet()"
-// unresolved external symbol "void __cdecl boost::filesystem3::path_traits::convert()"
-// See:
-// http://boost.2283326.n4.nabble.com/filesystem-v3-unicode-and-std-codecvt-linker-error-td3455549.html
-// which points to:
-// http://msdn.microsoft.com/en-us/library/dh8che7s%28v=VS.100%29.aspx
-
-// As we're not trying to preserve compatibility with old Boost.Filesystem
-// code, but rather writing brand-new code, use the newest available
-// Filesystem API.
-#define BOOST_FILESYSTEM_VERSION 3
-#include "boost/filesystem.hpp"
-#include "boost/filesystem/v3/fstream.hpp"
-|*==========================================================================*/
#include "boost/range.hpp"
#include "boost/foreach.hpp"
#include "boost/function.hpp"
#include "boost/lambda/lambda.hpp"
#include "boost/lambda/bind.hpp"
namespace lambda = boost::lambda;
-/*==========================================================================*|
-// Aaaarrgh, Linden's Boost package doesn't even include Boost.Iostreams!
-#include "boost/iostreams/stream.hpp"
-#include "boost/iostreams/device/file_descriptor.hpp"
-|*==========================================================================*/
#include "../llsd.h"
#include "../llsdserialize.h"
@@ -82,236 +56,17 @@ namespace lambda = boost::lambda;
#include "../llformat.h"
#include "../test/lltut.h"
+#include "../test/manageapr.h"
+#include "../test/namedtempfile.h"
#include "stringize.h"
+static ManageAPR manager;
+
std::vector<U8> string_to_vector(const std::string& str)
{
return std::vector<U8>(str.begin(), str.end());
}
-#if ! LL_WINDOWS
-// We want to call strerror_r(), but alarmingly, there are two different
-// variants. The one that returns int always populates the passed buffer
-// (except in case of error), whereas the other one always returns a valid
-// char* but might or might not populate the passed buffer. How do we know
-// which one we're getting? Define adapters for each and let the compiler
-// select the applicable adapter.
-
-// strerror_r() returns char*
-std::string message_from(int /*orig_errno*/, const char* /*buffer*/, const char* strerror_ret)
-{
- return strerror_ret;
-}
-
-// strerror_r() returns int
-std::string message_from(int orig_errno, const char* buffer, int strerror_ret)
-{
- if (strerror_ret == 0)
- {
- return buffer;
- }
- // Here strerror_r() has set errno. Since strerror_r() has already failed,
- // seems like a poor bet to call it again to diagnose its own error...
- int stre_errno = errno;
- if (stre_errno == ERANGE)
- {
- return STRINGIZE("strerror_r() can't explain errno " << orig_errno
- << " (buffer too small)");
- }
- if (stre_errno == EINVAL)
- {
- return STRINGIZE("unknown errno " << orig_errno);
- }
- // Here we don't even understand the errno from strerror_r()!
- return STRINGIZE("strerror_r() can't explain errno " << orig_errno
- << " (error " << stre_errno << ')');
-}
-#endif // ! LL_WINDOWS
-
-// boost::filesystem::temp_directory_path() isn't yet in Boost 1.45! :-(
-std::string temp_directory_path()
-{
-#if LL_WINDOWS
- char buffer[4096];
- GetTempPathA(sizeof(buffer), buffer);
- return buffer;
-
-#else // LL_DARWIN, LL_LINUX
- static const char* vars[] = { "TMPDIR", "TMP", "TEMP", "TEMPDIR" };
- BOOST_FOREACH(const char* var, vars)
- {
- const char* found = getenv(var);
- if (found)
- return found;
- }
- return "/tmp";
-#endif // LL_DARWIN, LL_LINUX
-}
-
-// Windows presents a kinda sorta compatibility layer. Code to the yucky
-// Windows names because they're less likely than the Posix names to collide
-// with any other names in this source.
-#if LL_WINDOWS
-#define _remove DeleteFileA
-#else // ! LL_WINDOWS
-#define _open open
-#define _write write
-#define _close close
-#define _remove remove
-#endif // ! LL_WINDOWS
-
-// Create a text file with specified content "somewhere in the
-// filesystem," cleaning up when it goes out of scope.
-class NamedTempFile
-{
-public:
- // Function that accepts an ostream ref and (presumably) writes stuff to
- // it, e.g.:
- // (lambda::_1 << "the value is " << 17 << '\n')
- typedef boost::function<void(std::ostream&)> Streamer;
-
- NamedTempFile(const std::string& ext, const std::string& content):
- mPath(temp_directory_path())
- {
- createFile(ext, lambda::_1 << content);
- }
-
- // Disambiguate when passing string literal
- NamedTempFile(const std::string& ext, const char* content):
- mPath(temp_directory_path())
- {
- createFile(ext, lambda::_1 << content);
- }
-
- NamedTempFile(const std::string& ext, const Streamer& func):
- mPath(temp_directory_path())
- {
- createFile(ext, func);
- }
-
- ~NamedTempFile()
- {
- _remove(mPath.c_str());
- }
-
- std::string getName() const { return mPath; }
-
-private:
- void createFile(const std::string& ext, const Streamer& func)
- {
- // Silly maybe, but use 'ext' as the name prefix. Strip off a leading
- // '.' if present.
- int pfx_offset = ((! ext.empty()) && ext[0] == '.')? 1 : 0;
-
-#if ! LL_WINDOWS
- // Make sure mPath ends with a directory separator, if it doesn't already.
- if (mPath.empty() ||
- ! (mPath[mPath.length() - 1] == '\\' || mPath[mPath.length() - 1] == '/'))
- {
- mPath.append("/");
- }
-
- // mkstemp() accepts and modifies a char* template string. Generate
- // the template string, then copy to modifiable storage.
- // mkstemp() requires its template string to end in six X's.
- mPath += ext.substr(pfx_offset) + "XXXXXX";
- // Copy to vector<char>
- std::vector<char> pathtemplate(mPath.begin(), mPath.end());
- // append a nul byte for classic-C semantics
- pathtemplate.push_back('\0');
- // std::vector promises that a pointer to the 0th element is the same
- // as a pointer to a contiguous classic-C array
- int fd(mkstemp(&pathtemplate[0]));
- if (fd == -1)
- {
- // The documented errno values (http://linux.die.net/man/3/mkstemp)
- // are used in a somewhat unusual way, so provide context-specific
- // errors.
- if (errno == EEXIST)
- {
- LL_ERRS("NamedTempFile") << "mkstemp(\"" << mPath
- << "\") could not create unique file " << LL_ENDL;
- }
- if (errno == EINVAL)
- {
- LL_ERRS("NamedTempFile") << "bad mkstemp() file path template '"
- << mPath << "'" << LL_ENDL;
- }
- // Shrug, something else
- int mkst_errno = errno;
- char buffer[256];
- LL_ERRS("NamedTempFile") << "mkstemp(\"" << mPath << "\") failed: "
- << message_from(mkst_errno, buffer,
- strerror_r(mkst_errno, buffer, sizeof(buffer)))
- << LL_ENDL;
- }
- // mkstemp() seems to have worked! Capture the modified filename.
- // Avoid the nul byte we appended.
- mPath.assign(pathtemplate.begin(), (pathtemplate.end()-1));
-
-/*==========================================================================*|
- // Define an ostream on the open fd. Tell it to close fd on destruction.
- boost::iostreams::stream<boost::iostreams::file_descriptor_sink>
- out(fd, boost::iostreams::close_handle);
-|*==========================================================================*/
-
- // Write desired content.
- std::ostringstream out;
- // Stream stuff to it.
- func(out);
-
- std::string data(out.str());
- int written(_write(fd, data.c_str(), data.length()));
- int closed(_close(fd));
- llassert_always(written == data.length() && closed == 0);
-
-#else // LL_WINDOWS
- // GetTempFileName() is documented to require a MAX_PATH buffer.
- char tempname[MAX_PATH];
- // Use 'ext' as filename prefix, but skip leading '.' if any.
- // The 0 param is very important: requests iterating until we get a
- // unique name.
- if (0 == GetTempFileNameA(mPath.c_str(), ext.c_str() + pfx_offset, 0, tempname))
- {
- // I always have to look up this call... :-P
- LPSTR msgptr;
- FormatMessageA(
- FORMAT_MESSAGE_ALLOCATE_BUFFER |
- FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL,
- GetLastError(),
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
- LPSTR(&msgptr), // have to cast (char**) to (char*)
- 0, NULL );
- LL_ERRS("NamedTempFile") << "GetTempFileName(\"" << mPath << "\", \""
- << (ext.c_str() + pfx_offset) << "\") failed: "
- << msgptr << LL_ENDL;
- LocalFree(msgptr);
- }
- // GetTempFileName() appears to have worked! Capture the actual
- // filename.
- mPath = tempname;
- // Open the file and stream content to it. Destructor will close.
- std::ofstream out(tempname);
- func(out);
-
-#endif // LL_WINDOWS
- }
-
- void peep()
- {
- std::cout << "File '" << mPath << "' contains:\n";
- std::ifstream reader(mPath.c_str());
- std::string line;
- while (std::getline(reader, line))
- std::cout << line << '\n';
- std::cout << "---\n";
- }
-
- std::string mPath;
-};
-
namespace tut
{
struct sd_xml_data
@@ -1768,10 +1523,7 @@ namespace tut
"sys.path.insert(0,\n"
" os.path.join(os.path.dirname(r'" __FILE__ "'),\n"
" os.pardir, os.pardir, 'lib', 'python'))\n"
- "try:\n"
- " from llbase import llsd\n"
- "except ImportError:\n"
- " from indra.base import llsd\n")
+ "from indra.base import llsd\n")
{}
~TestPythonCompatible() {}
@@ -1783,7 +1535,7 @@ namespace tut
const char* PYTHON(getenv("PYTHON"));
ensure("Set $PYTHON to the Python interpreter", PYTHON);
- NamedTempFile scriptfile(".py", script);
+ NamedTempFile scriptfile("py", script);
#if LL_WINDOWS
std::string q("\"");
@@ -1802,14 +1554,15 @@ namespace tut
}
#else // LL_DARWIN, LL_LINUX
- LLProcessLauncher py;
- py.setExecutable(PYTHON);
- py.addArgument(scriptfile.getName());
- ensure_equals(STRINGIZE("Couldn't launch " << desc << " script"), py.launch(), 0);
+ LLProcess::Params params;
+ params.executable = PYTHON;
+ params.args.add(scriptfile.getName());
+ LLProcessPtr py(LLProcess::create(params));
+ ensure(STRINGIZE("Couldn't launch " << desc << " script"), py);
// Implementing timeout would mean messing with alarm() and
// catching SIGALRM... later maybe...
int status(0);
- if (waitpid(py.getProcessID(), &status, 0) == -1)
+ if (waitpid(py->getProcessID(), &status, 0) == -1)
{
int waitpid_errno(errno);
ensure_equals(STRINGIZE("Couldn't retrieve rc from " << desc << " script: "
@@ -1888,12 +1641,12 @@ namespace tut
" else:\n"
" assert False, 'Too many data items'\n";
- // Create a something.llsd file containing 'data' serialized to
+ // Create an llsdXXXXXX file containing 'data' serialized to
// notation. It's important to separate with newlines because Python's
// llsd module doesn't support parsing from a file stream, only from a
// string, so we have to know how much of the file to read into a
// string.
- NamedTempFile file(".llsd",
+ NamedTempFile file("llsd",
// NamedTempFile's boost::function constructor
// takes a callable. To this callable it passes the
// std::ostream with which it's writing the
@@ -1926,7 +1679,7 @@ namespace tut
// Create an empty data file. This is just a placeholder for our
// script to write into. Create it to establish a unique name that
// we know.
- NamedTempFile file(".llsd", "");
+ NamedTempFile file("llsd", "");
python("write Python notation",
lambda::_1 <<
diff --git a/indra/llcommon/tests/llsingleton_test.cpp b/indra/llcommon/tests/llsingleton_test.cpp
index 385289aefe..385289aefe 100644..100755
--- a/indra/llcommon/tests/llsingleton_test.cpp
+++ b/indra/llcommon/tests/llsingleton_test.cpp
diff --git a/indra/llcommon/tests/llstreamqueue_test.cpp b/indra/llcommon/tests/llstreamqueue_test.cpp
new file mode 100755
index 0000000000..050ad5c5bf
--- /dev/null
+++ b/indra/llcommon/tests/llstreamqueue_test.cpp
@@ -0,0 +1,197 @@
+/**
+ * @file llstreamqueue_test.cpp
+ * @author Nat Goodspeed
+ * @date 2012-01-05
+ * @brief Test for llstreamqueue.
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Copyright (c) 2012, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+// Precompiled header
+#include "linden_common.h"
+// associated header
+#include "llstreamqueue.h"
+// STL headers
+#include <vector>
+// std headers
+// external library headers
+#include <boost/foreach.hpp>
+// other Linden headers
+#include "../test/lltut.h"
+#include "stringize.h"
+
+/*****************************************************************************
+* TUT
+*****************************************************************************/
+namespace tut
+{
+ struct llstreamqueue_data
+ {
+ llstreamqueue_data():
+ // we want a buffer with actual bytes in it, not an empty vector
+ buffer(10)
+ {}
+ // As LLStreamQueue is merely a typedef for
+ // LLGenericStreamQueue<char>, and no logic in LLGenericStreamQueue is
+ // specific to the <char> instantiation, we're comfortable for now
+ // testing only the narrow-char version.
+ LLStreamQueue strq;
+ // buffer for use in multiple tests
+ std::vector<char> buffer;
+ };
+ typedef test_group<llstreamqueue_data> llstreamqueue_group;
+ typedef llstreamqueue_group::object object;
+ llstreamqueue_group llstreamqueuegrp("llstreamqueue");
+
+ template<> template<>
+ void object::test<1>()
+ {
+ set_test_name("empty LLStreamQueue");
+ ensure_equals("brand-new LLStreamQueue isn't empty",
+ strq.size(), 0);
+ ensure_equals("brand-new LLStreamQueue returns data",
+ strq.asSource().read(&buffer[0], buffer.size()), 0);
+ strq.asSink().close();
+ ensure_equals("closed empty LLStreamQueue not at EOF",
+ strq.asSource().read(&buffer[0], buffer.size()), -1);
+ }
+
+ template<> template<>
+ void object::test<2>()
+ {
+ set_test_name("one internal block, one buffer");
+ LLStreamQueue::Sink sink(strq.asSink());
+ ensure_equals("write(\"\")", sink.write("", 0), 0);
+ ensure_equals("0 write should leave LLStreamQueue empty (size())",
+ strq.size(), 0);
+ ensure_equals("0 write should leave LLStreamQueue empty (peek())",
+ strq.peek(&buffer[0], buffer.size()), 0);
+ // The meaning of "atomic" is that it must be smaller than our buffer.
+ std::string atomic("atomic");
+ ensure("test data exceeds buffer", atomic.length() < buffer.size());
+ ensure_equals(STRINGIZE("write(\"" << atomic << "\")"),
+ sink.write(&atomic[0], atomic.length()), atomic.length());
+ ensure_equals("size() after write()", strq.size(), atomic.length());
+ size_t peeklen(strq.peek(&buffer[0], buffer.size()));
+ ensure_equals(STRINGIZE("peek(\"" << atomic << "\")"),
+ peeklen, atomic.length());
+ ensure_equals(STRINGIZE("peek(\"" << atomic << "\") result"),
+ std::string(buffer.begin(), buffer.begin() + peeklen), atomic);
+ ensure_equals("size() after peek()", strq.size(), atomic.length());
+ // peek() should not consume. Use a different buffer to prove it isn't
+ // just leftover data from the first peek().
+ std::vector<char> again(buffer.size());
+ peeklen = size_t(strq.peek(&again[0], again.size()));
+ ensure_equals(STRINGIZE("peek(\"" << atomic << "\") again"),
+ peeklen, atomic.length());
+ ensure_equals(STRINGIZE("peek(\"" << atomic << "\") again result"),
+ std::string(again.begin(), again.begin() + peeklen), atomic);
+ // now consume.
+ std::vector<char> third(buffer.size());
+ size_t readlen(strq.read(&third[0], third.size()));
+ ensure_equals(STRINGIZE("read(\"" << atomic << "\")"),
+ readlen, atomic.length());
+ ensure_equals(STRINGIZE("read(\"" << atomic << "\") result"),
+ std::string(third.begin(), third.begin() + readlen), atomic);
+ ensure_equals("peek() after read()", strq.peek(&buffer[0], buffer.size()), 0);
+ ensure_equals("size() after read()", strq.size(), 0);
+ }
+
+ template<> template<>
+ void object::test<3>()
+ {
+ set_test_name("basic skip()");
+ std::string lovecraft("lovecraft");
+ ensure("test data exceeds buffer", lovecraft.length() < buffer.size());
+ ensure_equals(STRINGIZE("write(\"" << lovecraft << "\")"),
+ strq.write(&lovecraft[0], lovecraft.length()), lovecraft.length());
+ size_t peeklen(strq.peek(&buffer[0], buffer.size()));
+ ensure_equals(STRINGIZE("peek(\"" << lovecraft << "\")"),
+ peeklen, lovecraft.length());
+ ensure_equals(STRINGIZE("peek(\"" << lovecraft << "\") result"),
+ std::string(buffer.begin(), buffer.begin() + peeklen), lovecraft);
+ std::streamsize skip1(4);
+ ensure_equals(STRINGIZE("skip(" << skip1 << ")"), strq.skip(skip1), skip1);
+ ensure_equals("size() after skip()", strq.size(), lovecraft.length() - skip1);
+ size_t readlen(strq.read(&buffer[0], buffer.size()));
+ ensure_equals(STRINGIZE("read(\"" << lovecraft.substr(skip1) << "\")"),
+ readlen, lovecraft.length() - skip1);
+ ensure_equals(STRINGIZE("read(\"" << lovecraft.substr(skip1) << "\") result"),
+ std::string(buffer.begin(), buffer.begin() + readlen),
+ lovecraft.substr(skip1));
+ ensure_equals("unconsumed", strq.read(&buffer[0], buffer.size()), 0);
+ }
+
+ template<> template<>
+ void object::test<4>()
+ {
+ set_test_name("skip() multiple blocks");
+ std::string blocks[] = { "books of ", "H.P. ", "Lovecraft" };
+ std::streamsize total(blocks[0].length() + blocks[1].length() + blocks[2].length());
+ std::streamsize leave(5); // len("craft") above
+ std::streamsize skip(total - leave);
+ std::streamsize written(0);
+ BOOST_FOREACH(const std::string& block, blocks)
+ {
+ written += strq.write(&block[0], block.length());
+ ensure_equals("size() after write()", strq.size(), written);
+ }
+ std::streamsize skiplen(strq.skip(skip));
+ ensure_equals(STRINGIZE("skip(" << skip << ")"), skiplen, skip);
+ ensure_equals("size() after skip()", strq.size(), leave);
+ size_t readlen(strq.read(&buffer[0], buffer.size()));
+ ensure_equals("read(\"craft\")", readlen, leave);
+ ensure_equals("read(\"craft\") result",
+ std::string(buffer.begin(), buffer.begin() + readlen), "craft");
+ }
+
+ template<> template<>
+ void object::test<5>()
+ {
+ set_test_name("concatenate blocks");
+ std::string blocks[] = { "abcd", "efghij", "klmnopqrs" };
+ BOOST_FOREACH(const std::string& block, blocks)
+ {
+ strq.write(&block[0], block.length());
+ }
+ std::vector<char> longbuffer(30);
+ std::streamsize readlen(strq.read(&longbuffer[0], longbuffer.size()));
+ ensure_equals("read() multiple blocks",
+ readlen, blocks[0].length() + blocks[1].length() + blocks[2].length());
+ ensure_equals("read() multiple blocks result",
+ std::string(longbuffer.begin(), longbuffer.begin() + readlen),
+ blocks[0] + blocks[1] + blocks[2]);
+ }
+
+ template<> template<>
+ void object::test<6>()
+ {
+ set_test_name("split blocks");
+ std::string blocks[] = { "abcdefghijklm", "nopqrstuvwxyz" };
+ BOOST_FOREACH(const std::string& block, blocks)
+ {
+ strq.write(&block[0], block.length());
+ }
+ strq.close();
+ // We've already verified what strq.size() should be at this point;
+ // see above test named "skip() multiple blocks"
+ std::streamsize chksize(strq.size());
+ std::streamsize readlen(strq.read(&buffer[0], buffer.size()));
+ ensure_equals("read() 0", readlen, buffer.size());
+ ensure_equals("read() 0 result", std::string(buffer.begin(), buffer.end()), "abcdefghij");
+ chksize -= readlen;
+ ensure_equals("size() after read() 0", strq.size(), chksize);
+ readlen = strq.read(&buffer[0], buffer.size());
+ ensure_equals("read() 1", readlen, buffer.size());
+ ensure_equals("read() 1 result", std::string(buffer.begin(), buffer.end()), "klmnopqrst");
+ chksize -= readlen;
+ ensure_equals("size() after read() 1", strq.size(), chksize);
+ readlen = strq.read(&buffer[0], buffer.size());
+ ensure_equals("read() 2", readlen, chksize);
+ ensure_equals("read() 2 result",
+ std::string(buffer.begin(), buffer.begin() + readlen), "uvwxyz");
+ ensure_equals("read() 3", strq.read(&buffer[0], buffer.size()), -1);
+ }
+} // namespace tut
diff --git a/indra/llcommon/tests/llstring_test.cpp b/indra/llcommon/tests/llstring_test.cpp
index 6a1cbf652a..93d3968dbf 100644..100755
--- a/indra/llcommon/tests/llstring_test.cpp
+++ b/indra/llcommon/tests/llstring_test.cpp
@@ -29,7 +29,11 @@
#include "linden_common.h"
#include "../test/lltut.h"
+#include <boost/assign/list_of.hpp>
#include "../llstring.h"
+#include "StringVec.h"
+
+using boost::assign::list_of;
namespace tut
{
@@ -750,4 +754,118 @@ namespace tut
ensure("empty substr.", !LLStringUtil::endsWith(empty, value));
ensure("empty everything.", !LLStringUtil::endsWith(empty, empty));
}
+
+ template<> template<>
+ void string_index_object_t::test<41>()
+ {
+ set_test_name("getTokens(\"delims\")");
+ ensure_equals("empty string", LLStringUtil::getTokens("", " "), StringVec());
+ ensure_equals("only delims",
+ LLStringUtil::getTokens(" \r\n ", " \r\n"), StringVec());
+ ensure_equals("sequence of delims",
+ LLStringUtil::getTokens(",,, one ,,,", ","), list_of("one"));
+ // nat considers this a dubious implementation side effect, but I'd
+ // hate to change it now...
+ ensure_equals("noncontiguous tokens",
+ LLStringUtil::getTokens(", ,, , one ,,,", ","), list_of("")("")("one"));
+ ensure_equals("space-padded tokens",
+ LLStringUtil::getTokens(", one , two ,", ","), list_of("one")("two"));
+ ensure_equals("no delims", LLStringUtil::getTokens("one", ","), list_of("one"));
+ }
+
+ // Shorthand for verifying that getTokens() behaves the same when you
+ // don't pass a string of escape characters, when you pass an empty string
+ // (different overloads), and when you pass a string of characters that
+ // aren't actually present.
+ void ensure_getTokens(const std::string& desc,
+ const std::string& string,
+ const std::string& drop_delims,
+ const std::string& keep_delims,
+ const std::string& quotes,
+ const std::vector<std::string>& expect)
+ {
+ ensure_equals(desc + " - no esc",
+ LLStringUtil::getTokens(string, drop_delims, keep_delims, quotes),
+ expect);
+ ensure_equals(desc + " - empty esc",
+ LLStringUtil::getTokens(string, drop_delims, keep_delims, quotes, ""),
+ expect);
+ ensure_equals(desc + " - unused esc",
+ LLStringUtil::getTokens(string, drop_delims, keep_delims, quotes, "!"),
+ expect);
+ }
+
+ void ensure_getTokens(const std::string& desc,
+ const std::string& string,
+ const std::string& drop_delims,
+ const std::string& keep_delims,
+ const std::vector<std::string>& expect)
+ {
+ ensure_getTokens(desc, string, drop_delims, keep_delims, "", expect);
+ }
+
+ template<> template<>
+ void string_index_object_t::test<42>()
+ {
+ set_test_name("getTokens(\"delims\", etc.)");
+ // Signatures to test in this method:
+ // getTokens(string, drop_delims, keep_delims [, quotes [, escapes]])
+ // If you omit keep_delims, you get the older function (test above).
+
+ // cases like the getTokens(string, delims) tests above
+ ensure_getTokens("empty string", "", " ", "", StringVec());
+ ensure_getTokens("only delims",
+ " \r\n ", " \r\n", "", StringVec());
+ ensure_getTokens("sequence of delims",
+ ",,, one ,,,", ", ", "", list_of("one"));
+ // Note contrast with the case in the previous method
+ ensure_getTokens("noncontiguous tokens",
+ ", ,, , one ,,,", ", ", "", list_of("one"));
+ ensure_getTokens("space-padded tokens",
+ ", one , two ,", ", ", "",
+ list_of("one")("two"));
+ ensure_getTokens("no delims", "one", ",", "", list_of("one"));
+
+ // drop_delims vs. keep_delims
+ ensure_getTokens("arithmetic",
+ " ab+def / xx* yy ", " ", "+-*/",
+ list_of("ab")("+")("def")("/")("xx")("*")("yy"));
+
+ // quotes
+ ensure_getTokens("no quotes",
+ "She said, \"Don't go.\"", " ", ",", "",
+ list_of("She")("said")(",")("\"Don't")("go.\""));
+ ensure_getTokens("quotes",
+ "She said, \"Don't go.\"", " ", ",", "\"",
+ list_of("She")("said")(",")("Don't go."));
+ ensure_getTokens("quotes and delims",
+ "run c:/'Documents and Settings'/someone", " ", "", "'",
+ list_of("run")("c:/Documents and Settings/someone"));
+ ensure_getTokens("unmatched quote",
+ "baby don't leave", " ", "", "'",
+ list_of("baby")("don't")("leave"));
+ ensure_getTokens("adjacent quoted",
+ "abc'def \"ghi'\"jkl' mno\"pqr", " ", "", "\"'",
+ list_of("abcdef \"ghijkl' mnopqr"));
+ ensure_getTokens("quoted empty string",
+ "--set SomeVar ''", " ", "", "'",
+ list_of("--set")("SomeVar")(""));
+
+ // escapes
+ // Don't use backslash as an escape for these tests -- you'll go nuts
+ // between the C++ string scanner and getTokens() escapes. Test with
+ // something else!
+ ensure_equals("escaped delims",
+ LLStringUtil::getTokens("^ a - dog^-gone^ phrase", " ", "-", "", "^"),
+ list_of(" a")("-")("dog-gone phrase"));
+ ensure_equals("escaped quotes",
+ LLStringUtil::getTokens("say: 'this isn^'t w^orking'.", " ", "", "'", "^"),
+ list_of("say:")("this isn't working."));
+ ensure_equals("escaped escape",
+ LLStringUtil::getTokens("want x^^2", " ", "", "", "^"),
+ list_of("want")("x^2"));
+ ensure_equals("escape at end",
+ LLStringUtil::getTokens("it's^ up there^", " ", "", "'", "^"),
+ list_of("it's up")("there^"));
+ }
}
diff --git a/indra/llcommon/tests/lltreeiterators_test.cpp b/indra/llcommon/tests/lltreeiterators_test.cpp
index 1d619867d4..1d619867d4 100644..100755
--- a/indra/llcommon/tests/lltreeiterators_test.cpp
+++ b/indra/llcommon/tests/lltreeiterators_test.cpp
diff --git a/indra/llcommon/tests/lluri_test.cpp b/indra/llcommon/tests/lluri_test.cpp
index f6d4221256..4c64f15ca7 100644..100755
--- a/indra/llcommon/tests/lluri_test.cpp
+++ b/indra/llcommon/tests/lluri_test.cpp
@@ -58,12 +58,12 @@ namespace tut
ensure_equals("escape/unescape escaped", uri_esc_2, uri_esc_1);
}
};
-
+
typedef test_group<URITestData> URITestGroup;
typedef URITestGroup::object URITestObject;
URITestGroup uriTestGroup("LLURI");
-
+
template<> template<>
void URITestObject::test<1>()
{
@@ -89,14 +89,14 @@ namespace tut
template<> template<>
void URITestObject::test<2>()
{
- // empty string
+ set_test_name("empty string");
checkParts(LLURI(""), "", "", "", "");
}
-
+
template<> template<>
void URITestObject::test<3>()
{
- // no scheme
+ set_test_name("no scheme");
checkParts(LLURI("foo"), "", "foo", "", "");
checkParts(LLURI("foo%3A"), "", "foo:", "", "");
}
@@ -104,7 +104,7 @@ namespace tut
template<> template<>
void URITestObject::test<4>()
{
- // scheme w/o paths
+ set_test_name("scheme w/o paths");
checkParts(LLURI("mailto:zero@ll.com"),
"mailto", "zero@ll.com", "", "");
checkParts(LLURI("silly://abc/def?foo"),
@@ -114,16 +114,16 @@ namespace tut
template<> template<>
void URITestObject::test<5>()
{
- // authority section
+ set_test_name("authority section");
checkParts(LLURI("http:///"),
"http", "///", "", "/");
-
+
checkParts(LLURI("http://abc"),
"http", "//abc", "abc", "");
-
+
checkParts(LLURI("http://a%2Fb/cd"),
"http", "//a/b/cd", "a/b", "/cd");
-
+
checkParts(LLURI("http://host?"),
"http", "//host?", "host", "");
}
@@ -131,13 +131,13 @@ namespace tut
template<> template<>
void URITestObject::test<6>()
{
- // path section
+ set_test_name("path section");
checkParts(LLURI("http://host/a/b/"),
"http", "//host/a/b/", "host", "/a/b/");
-
+
checkParts(LLURI("http://host/a%3Fb/"),
"http", "//host/a?b/", "host", "/a?b/");
-
+
checkParts(LLURI("http://host/a:b/"),
"http", "//host/a:b/", "host", "/a:b/");
}
@@ -145,16 +145,16 @@ namespace tut
template<> template<>
void URITestObject::test<7>()
{
- // query string
+ set_test_name("query string");
checkParts(LLURI("http://host/?"),
"http", "//host/?", "host", "/", "");
-
+
checkParts(LLURI("http://host/?x"),
"http", "//host/?x", "host", "/", "x");
-
+
checkParts(LLURI("http://host/??"),
"http", "//host/??", "host", "/", "?");
-
+
checkParts(LLURI("http://host/?%3F"),
"http", "//host/??", "host", "/", "?");
}
@@ -167,19 +167,44 @@ namespace tut
path.append("123");
checkParts(LLURI::buildHTTP("host", path),
"http", "//host/x/123", "host", "/x/123");
-
+
LLSD query;
query["123"] = "12";
query["abcd"] = "abc";
checkParts(LLURI::buildHTTP("host", path, query),
"http", "//host/x/123?123=12&abcd=abc",
"host", "/x/123", "123=12&abcd=abc");
+
+ ensure_equals(LLURI::buildHTTP("host", "").asString(),
+ "http://host");
+ ensure_equals(LLURI::buildHTTP("host", "/").asString(),
+ "http://host/");
+ ensure_equals(LLURI::buildHTTP("host", "//").asString(),
+ "http://host/");
+ ensure_equals(LLURI::buildHTTP("host", "dir name").asString(),
+ "http://host/dir%20name");
+ ensure_equals(LLURI::buildHTTP("host", "dir name/").asString(),
+ "http://host/dir%20name/");
+ ensure_equals(LLURI::buildHTTP("host", "/dir name").asString(),
+ "http://host/dir%20name");
+ ensure_equals(LLURI::buildHTTP("host", "/dir name/").asString(),
+ "http://host/dir%20name/");
+ ensure_equals(LLURI::buildHTTP("host", "dir name/subdir name").asString(),
+ "http://host/dir%20name/subdir%20name");
+ ensure_equals(LLURI::buildHTTP("host", "dir name/subdir name/").asString(),
+ "http://host/dir%20name/subdir%20name/");
+ ensure_equals(LLURI::buildHTTP("host", "/dir name/subdir name").asString(),
+ "http://host/dir%20name/subdir%20name");
+ ensure_equals(LLURI::buildHTTP("host", "/dir name/subdir name/").asString(),
+ "http://host/dir%20name/subdir%20name/");
+ ensure_equals(LLURI::buildHTTP("host", "//dir name//subdir name//").asString(),
+ "http://host/dir%20name/subdir%20name/");
}
template<> template<>
void URITestObject::test<9>()
{
- // test unescaped path components
+ set_test_name("test unescaped path components");
LLSD path;
path.append("x@*//*$&^");
path.append("123");
@@ -190,7 +215,7 @@ namespace tut
template<> template<>
void URITestObject::test<10>()
{
- // test unescaped query components
+ set_test_name("test unescaped query components");
LLSD path;
path.append("x");
path.append("123");
@@ -205,7 +230,7 @@ namespace tut
template<> template<>
void URITestObject::test<11>()
{
- // test unescaped host components
+ set_test_name("test unescaped host components");
LLSD path;
path.append("x");
path.append("123");
@@ -216,16 +241,16 @@ namespace tut
"http", "//hi123*33--}{:portstuffs/x/123?123=12&abcd=abc",
"hi123*33--}{:portstuffs", "/x/123", "123=12&abcd=abc");
}
-
+
template<> template<>
void URITestObject::test<12>()
{
- // test funky host_port values that are actually prefixes
-
+ set_test_name("test funky host_port values that are actually prefixes");
+
checkParts(LLURI::buildHTTP("http://example.com:8080", LLSD()),
"http", "//example.com:8080",
"example.com:8080", "");
-
+
checkParts(LLURI::buildHTTP("http://example.com:8080/", LLSD()),
"http", "//example.com:8080/",
"example.com:8080", "/");
@@ -242,7 +267,7 @@ namespace tut
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
"0123456789"
"-._~";
- // test escape
+ set_test_name("test escape");
ensure_equals("escaping", LLURI::escape("abcdefg", "abcdef"), "abcdef%67");
ensure_equals("escaping", LLURI::escape("|/&\\+-_!@", ""), "%7C%2F%26%5C%2B%2D%5F%21%40");
ensure_equals("escaping as query variable",
@@ -259,13 +284,12 @@ namespace tut
cedilla.push_back( (char)0xA7 );
ensure_equals("escape UTF8", LLURI::escape( cedilla, unreserved), "%C3%A7");
}
-
+
template<> template<>
void URITestObject::test<14>()
{
- // make sure escape and unescape of empty strings return empty
- // strings.
+ set_test_name("make sure escape and unescape of empty strings return empty strings.");
std::string uri_esc(LLURI::escape(""));
ensure("escape string empty", uri_esc.empty());
std::string uri_raw(LLURI::unescape(""));
@@ -275,7 +299,7 @@ namespace tut
template<> template<>
void URITestObject::test<15>()
{
- // do some round-trip tests
+ set_test_name("do some round-trip tests");
escapeRoundTrip("http://secondlife.com");
escapeRoundTrip("http://secondlife.com/url with spaces");
escapeRoundTrip("http://bad[domain]name.com/");
@@ -286,7 +310,7 @@ namespace tut
template<> template<>
void URITestObject::test<16>()
{
- // Test the default escaping
+ set_test_name("Test the default escaping");
// yes -- this mangles the url. This is expected behavior
std::string simple("http://secondlife.com");
ensure_equals(
@@ -302,7 +326,7 @@ namespace tut
template<> template<>
void URITestObject::test<17>()
{
- // do some round-trip tests with very long strings.
+ set_test_name("do some round-trip tests with very long strings.");
escapeRoundTrip("Welcome to Second Life.We hope you'll have a richly rewarding experience, filled with creativity, self expression and fun.The goals of the Community Standards are simple: treat each other with respect and without harassment, adhere to local standards as indicated by simulator ratings, and refrain from any hate activity which slurs a real-world individual or real-world community. Behavioral Guidelines - The Big Six");
escapeRoundTrip(
"'asset_data':b(12100){'task_id':ucc706f2d-0b68-68f8-11a4-f1043ff35ca0}\n{\n\tname\tObject|\n\tpermissions 0\n\t{\n\t\tbase_mask\t7fffffff\n\t\towner_mask\t7fffffff\n\t\tgroup_mask\t00000000\n\t\teveryone_mask\t00000000\n\t\tnext_owner_mask\t7fffffff\n\t\tcreator_id\t13fd9595-a47b-4d64-a5fb-6da645f038e0\n\t\towner_id\t3c115e51-04f4-523c-9fa6-98aff1034730\n\t\tlast_owner_id\t3c115e51-04f4-523c-9fa6-98aff1034730\n\t\tgroup_id\t00000000-0000-0000-0000-000000000000\n\t}\n\tlocal_id\t217444921\n\ttotal_crc\t323\n\ttype\t2\n\ttask_valid\t2\n\ttravel_access\t13\n\tdisplayopts\t2\n\tdisplaytype\tv\n\tpos\t-0.368634403\t0.00781063363\t-0.569040775\n\toldpos\t150.117996\t25.8658009\t8.19664001\n\trotation\t-0.06293071806430816650390625\t-0.6995697021484375\t-0.7002241611480712890625\t0.1277817934751510620117188\n\tchildpos\t-0.00499999989\t-0.0359999985\t0.307999998\n\tchildrot\t-0.515492737293243408203125\t-0.46601200103759765625\t0.529055416584014892578125\t0.4870323240756988525390625\n\tscale"
@@ -322,7 +346,7 @@ namespace tut
"D STRING RW SV 20f36c3a-b44b-9bc7-87f3-018bfdfc8cda\n\tscratchpad\t0\n\t{\n\t\n\t}\n\tsale_info\t0\n\t{\n\t\tsale_type\tnot\n\t\tsale_price\t10\n\t}\n\torig_asset_id\t8747acbc-d391-1e59-69f1-41d06830e6c0\n\torig_item_id\t20f36c3a-b44b-9bc7-87f3-018bfdfc8cda\n\tfrom_task_id\t3c115e51-04f4-523c-9fa6-98aff1034730\n\tcorrect_family_id\t00000000-0000-0000-0000-000000000000\n\thas_rezzed\t0\n\tpre_link_base_mask\t7fffffff\n\tlinked \tlinked\n\tdefault_pay_price\t-2\t1\t5\t10\t20\n}\n");
}
-
+
template<> template<>
void URITestObject::test<18>()
{
@@ -335,7 +359,7 @@ namespace tut
ensure_equals("pathmap", u.pathArray()[1].asString(), "login");
ensure_equals("query", u.query(), "first_name=Testert4&last_name=Tester&web_login_key=test");
ensure_equals("query map element", u.queryMap()["last_name"].asString(), "Tester");
-
+
u = LLURI("secondlife://Da Boom/128/128/128");
// if secondlife is the scheme, LLURI should parse /128/128/128 as path, with Da Boom as authority
ensure_equals("scheme", u.scheme(), "secondlife");
@@ -350,7 +374,7 @@ namespace tut
template<> template<>
void URITestObject::test<19>()
{
- // Parse about: schemes
+ set_test_name("Parse about: schemes");
LLURI u("about:blank?redirect-http-hack=secondlife%3A%2F%2F%2Fapp%2Flogin%3Ffirst_name%3DCallum%26last_name%3DLinden%26location%3Dspecify%26grid%3Dvaak%26region%3D%2FMorris%2F128%2F128%26web_login_key%3Defaa4795-c2aa-4c58-8966-763c27931e78");
ensure_equals("scheme", u.scheme(), "about");
ensure_equals("authority", u.authority(), "");
diff --git a/indra/llcommon/tests/reflection_test.cpp b/indra/llcommon/tests/reflection_test.cpp
index 59491cd1fe..8980ebb1f1 100644..100755
--- a/indra/llcommon/tests/reflection_test.cpp
+++ b/indra/llcommon/tests/reflection_test.cpp
@@ -207,7 +207,7 @@ namespace tut
const LLReflective* reflective = property->get(aggregated_data); // Wrong reflective type, should throw exception.
// useless op to get rid of compiler warning.
- reflective = NULL;
+ reflective = reflective;
}
catch(...)
{
diff --git a/indra/llcommon/tests/setpython.py b/indra/llcommon/tests/setpython.py
deleted file mode 100644
index df7b90428e..0000000000
--- a/indra/llcommon/tests/setpython.py
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/usr/bin/python
-"""\
-@file setpython.py
-@author Nat Goodspeed
-@date 2011-07-13
-@brief Set PYTHON environment variable for tests that care.
-
-$LicenseInfo:firstyear=2011&license=viewerlgpl$
-Copyright (c) 2011, Linden Research, Inc.
-$/LicenseInfo$
-"""
-
-import os
-import sys
-import subprocess
-
-if __name__ == "__main__":
- os.environ["PYTHON"] = sys.executable
- sys.exit(subprocess.call(sys.argv[1:]))
diff --git a/indra/llcommon/tests/stringize_test.cpp b/indra/llcommon/tests/stringize_test.cpp
index 3d34f23998..3d34f23998 100644..100755
--- a/indra/llcommon/tests/stringize_test.cpp
+++ b/indra/llcommon/tests/stringize_test.cpp
diff --git a/indra/llcommon/tests/wrapllerrs.h b/indra/llcommon/tests/wrapllerrs.h
index ffda84729b..a4d3a4e026 100644..100755
--- a/indra/llcommon/tests/wrapllerrs.h
+++ b/indra/llcommon/tests/wrapllerrs.h
@@ -29,7 +29,22 @@
#if ! defined(LL_WRAPLLERRS_H)
#define LL_WRAPLLERRS_H
+#if LL_WINDOWS
+#pragma warning (disable : 4355) // 'this' used in initializer list: yes, intentionally
+#endif
+
+#include <tut/tut.hpp>
#include "llerrorcontrol.h"
+#include "stringize.h"
+#include <boost/bind.hpp>
+#include <boost/noncopyable.hpp>
+#include <list>
+#include <string>
+#include <stdexcept>
+
+// statically reference the function in test.cpp... it's short, we could
+// replicate, but better to reuse
+extern void wouldHaveCrashed(const std::string& message);
struct WrapLL_ERRS
{
@@ -70,4 +85,118 @@ struct WrapLL_ERRS
LLError::FatalFunction mPriorFatal;
};
+/**
+ * LLError::addRecorder() accepts ownership of the passed Recorder* -- it
+ * expects to be able to delete it later. CaptureLog isa Recorder whose
+ * pointer we want to be able to pass without any ownership implications.
+ * For such cases, instantiate a new RecorderProxy(yourRecorder) and pass
+ * that. Your heap RecorderProxy might later be deleted, but not yourRecorder.
+ */
+class RecorderProxy: public LLError::Recorder
+{
+public:
+ RecorderProxy(LLError::Recorder* recorder):
+ mRecorder(recorder)
+ {}
+
+ virtual void recordMessage(LLError::ELevel level, const std::string& message)
+ {
+ mRecorder->recordMessage(level, message);
+ }
+
+ virtual bool wantsTime()
+ {
+ return mRecorder->wantsTime();
+ }
+
+private:
+ LLError::Recorder* mRecorder;
+};
+
+/**
+ * Capture log messages. This is adapted (simplified) from the one in
+ * llerror_test.cpp.
+ */
+class CaptureLog : public LLError::Recorder, public boost::noncopyable
+{
+public:
+ CaptureLog(LLError::ELevel level=LLError::LEVEL_DEBUG):
+ // Mostly what we're trying to accomplish by saving and resetting
+ // LLError::Settings is to bypass the default RecordToStderr and
+ // RecordToWinDebug Recorders. As these are visible only inside
+ // llerror.cpp, we can't just call LLError::removeRecorder() with
+ // each. For certain tests we need to produce, capture and examine
+ // DEBUG log messages -- but we don't want to spam the user's console
+ // with that output. If it turns out that saveAndResetSettings() has
+ // some bad effect, give up and just let the DEBUG level log messages
+ // display.
+ mOldSettings(LLError::saveAndResetSettings()),
+ mProxy(new RecorderProxy(this))
+ {
+ LLError::setFatalFunction(wouldHaveCrashed);
+ LLError::setDefaultLevel(level);
+ LLError::addRecorder(mProxy);
+ }
+
+ ~CaptureLog()
+ {
+ LLError::removeRecorder(mProxy);
+ delete mProxy;
+ LLError::restoreSettings(mOldSettings);
+ }
+
+ void recordMessage(LLError::ELevel level,
+ const std::string& message)
+ {
+ mMessages.push_back(message);
+ }
+
+ /// Don't assume the message we want is necessarily the LAST log message
+ /// emitted by the underlying code; search backwards through all messages
+ /// for the sought string.
+ std::string messageWith(const std::string& search, bool required=true)
+ {
+ for (MessageList::const_reverse_iterator rmi(mMessages.rbegin()), rmend(mMessages.rend());
+ rmi != rmend; ++rmi)
+ {
+ if (rmi->find(search) != std::string::npos)
+ return *rmi;
+ }
+ // failed to find any such message
+ if (! required)
+ return std::string();
+
+ throw tut::failure(STRINGIZE("failed to find '" << search
+ << "' in captured log messages:\n"
+ << boost::ref(*this)));
+ }
+
+ std::ostream& streamto(std::ostream& out) const
+ {
+ MessageList::const_iterator mi(mMessages.begin()), mend(mMessages.end());
+ if (mi != mend)
+ {
+ // handle first message separately: it doesn't get a newline
+ out << *mi++;
+ for ( ; mi != mend; ++mi)
+ {
+ // every subsequent message gets a newline
+ out << '\n' << *mi;
+ }
+ }
+ return out;
+ }
+
+ typedef std::list<std::string> MessageList;
+ MessageList mMessages;
+ LLError::Settings* mOldSettings;
+ LLError::Recorder* mProxy;
+};
+
+inline
+std::ostream& operator<<(std::ostream& out, const CaptureLog& log)
+{
+ return log.streamto(out);
+}
+
#endif /* ! defined(LL_WRAPLLERRS_H) */
diff --git a/indra/llcommon/timer.h b/indra/llcommon/timer.h
index 82d19c2d32..82d19c2d32 100644..100755
--- a/indra/llcommon/timer.h
+++ b/indra/llcommon/timer.h
diff --git a/indra/llcommon/timing.cpp b/indra/llcommon/timing.cpp
index c2dc695ef3..c2dc695ef3 100644..100755
--- a/indra/llcommon/timing.cpp
+++ b/indra/llcommon/timing.cpp
diff --git a/indra/llcommon/timing.h b/indra/llcommon/timing.h
index c408d4c446..c408d4c446 100644..100755
--- a/indra/llcommon/timing.h
+++ b/indra/llcommon/timing.h
diff --git a/indra/llcommon/u64.cpp b/indra/llcommon/u64.cpp
index eea16c5036..eea16c5036 100644..100755
--- a/indra/llcommon/u64.cpp
+++ b/indra/llcommon/u64.cpp
diff --git a/indra/llcommon/u64.h b/indra/llcommon/u64.h
index 75c8a59136..75c8a59136 100644..100755
--- a/indra/llcommon/u64.h
+++ b/indra/llcommon/u64.h
diff --git a/indra/llcorehttp/CMakeLists.txt b/indra/llcorehttp/CMakeLists.txt
new file mode 100755
index 0000000000..9adfd0ed62
--- /dev/null
+++ b/indra/llcorehttp/CMakeLists.txt
@@ -0,0 +1,186 @@
+# -*- cmake -*-
+
+project(llcorehttp)
+
+include(00-Common)
+include(GoogleMock)
+include(CURL)
+include(CARes)
+include(OpenSSL)
+include(ZLIB)
+include(LLCoreHttp)
+include(LLAddBuildTest)
+include(LLMessage)
+include(LLCommon)
+include(Tut)
+
+include_directories (${CMAKE_CURRENT_SOURCE_DIR})
+
+include_directories(
+ ${LLMESSAGE_INCLUDE_DIRS}
+ ${LLCOMMON_INCLUDE_DIRS}
+ ${LLCOREHTTP_INCLUDE_DIRS}
+ )
+
+set(llcorehttp_SOURCE_FILES
+ bufferarray.cpp
+ bufferstream.cpp
+ httpcommon.cpp
+ httpheaders.cpp
+ httpoptions.cpp
+ httprequest.cpp
+ httpresponse.cpp
+ _httplibcurl.cpp
+ _httpopcancel.cpp
+ _httpoperation.cpp
+ _httpoprequest.cpp
+ _httpopsetget.cpp
+ _httpopsetpriority.cpp
+ _httppolicy.cpp
+ _httppolicyclass.cpp
+ _httppolicyglobal.cpp
+ _httpreplyqueue.cpp
+ _httprequestqueue.cpp
+ _httpservice.cpp
+ _refcounted.cpp
+ )
+
+set(llcorehttp_HEADER_FILES
+ CMakeLists.txt
+
+ bufferarray.h
+ bufferstream.h
+ httpcommon.h
+ httphandler.h
+ httpheaders.h
+ httpoptions.h
+ httprequest.h
+ httpresponse.h
+ _httpinternal.h
+ _httplibcurl.h
+ _httpopcancel.h
+ _httpoperation.h
+ _httpoprequest.h
+ _httpopsetget.h
+ _httpopsetpriority.h
+ _httppolicy.h
+ _httppolicyclass.h
+ _httppolicyglobal.h
+ _httpreadyqueue.h
+ _httpreplyqueue.h
+ _httprequestqueue.h
+ _httpservice.h
+ _mutex.h
+ _refcounted.h
+ _thread.h
+ )
+
+set_source_files_properties(${llcorehttp_HEADER_FILES}
+ PROPERTIES HEADER_FILE_ONLY TRUE)
+if (DARWIN OR LINUX)
+ # Boost headers define unused members in condition_variable so...
+ set_source_files_properties(${llcorehttp_SOURCE_FILES}
+ PROPERTIES COMPILE_FLAGS -Wno-unused-variable)
+endif (DARWIN OR LINUX)
+
+list(APPEND llcorehttp_SOURCE_FILES ${llcorehttp_HEADER_FILES})
+
+add_library (llcorehttp ${llcorehttp_SOURCE_FILES})
+target_link_libraries(
+ llcorehttp
+ ${CURL_LIBRARIES}
+ ${CARES_LIBRARIES}
+ ${OPENSSL_LIBRARIES}
+ ${CRYPTO_LIBRARIES}
+ ${BOOST_THREAD_LIBRARY}
+ )
+
+# tests
+if (LL_TESTS)
+ SET(llcorehttp_TEST_SOURCE_FILES
+ tests/test_allocator.cpp
+ )
+
+ set(llcorehttp_TEST_HEADER_FILS
+ tests/test_httpstatus.hpp
+ tests/test_refcounted.hpp
+ tests/test_httpoperation.hpp
+ tests/test_httprequest.hpp
+ tests/test_httprequestqueue.hpp
+ tests/test_httpheaders.hpp
+ tests/test_bufferarray.hpp
+ tests/test_bufferstream.hpp
+ )
+
+ set_source_files_properties(${llcorehttp_TEST_HEADER_FILES}
+ PROPERTIES HEADER_FILE_ONLY TRUE)
+
+ list(APPEND llcorehttp_TEST_SOURCE_FILES ${llcorehttp_TEST_HEADER_FILES})
+
+ # LL_ADD_PROJECT_UNIT_TESTS(llcorehttp "${llcorehttp_TEST_SOURCE_FILES}")
+
+ # set(TEST_DEBUG on)
+ set(test_libs
+ ${LLCOREHTTP_LIBRARIES}
+ ${WINDOWS_LIBRARIES}
+ ${LLMESSAGE_LIBRARIES}
+ ${LLCOMMON_LIBRARIES}
+ ${GOOGLEMOCK_LIBRARIES}
+ ${CURL_LIBRARIES}
+ ${CARES_LIBRARIES}
+ ${OPENSSL_LIBRARIES}
+ ${CRYPTO_LIBRARIES}
+ ${BOOST_SYSTEM_LIBRARY}
+ ${BOOST_THREAD_LIBRARY}
+ )
+
+ LL_ADD_INTEGRATION_TEST(llcorehttp
+ "${llcorehttp_TEST_SOURCE_FILES}"
+ "${test_libs}"
+ ${PYTHON_EXECUTABLE}
+ "${CMAKE_CURRENT_SOURCE_DIR}/tests/test_llcorehttp_peer.py"
+ )
+
+ #
+ # Example Programs
+ #
+ SET(llcorehttp_EXAMPLE_SOURCE_FILES
+ examples/http_texture_load.cpp
+ )
+
+ set(example_libs
+ ${LLCOREHTTP_LIBRARIES}
+ ${WINDOWS_LIBRARIES}
+ ${LLMESSAGE_LIBRARIES}
+ ${LLCOMMON_LIBRARIES}
+ ${GOOGLEMOCK_LIBRARIES}
+ ${CURL_LIBRARIES}
+ ${CARES_LIBRARIES}
+ ${OPENSSL_LIBRARIES}
+ ${CRYPTO_LIBRARIES}
+ ${BOOST_SYSTEM_LIBRARY}
+ ${BOOST_THREAD_LIBRARY}
+ )
+
+ add_executable(http_texture_load
+ ${llcorehttp_EXAMPLE_SOURCE_FILES}
+ )
+ set_target_properties(http_texture_load
+ PROPERTIES
+ RUNTIME_OUTPUT_DIRECTORY "${EXE_STAGING_DIR}"
+ )
+
+ if (WINDOWS)
+ # The following come from LLAddBuildTest.cmake's INTEGRATION_TEST_xxxx target.
+ set_target_properties(http_texture_load
+ PROPERTIES
+ LINK_FLAGS "/debug /NODEFAULTLIB:LIBCMT /SUBSYSTEM:WINDOWS ${TCMALLOC_LINK_FLAGS}"
+ LINK_FLAGS_DEBUG "/NODEFAULTLIB:\"LIBCMT;LIBCMTD;MSVCRT\" /INCREMENTAL:NO"
+ LINK_FLAGS_RELEASE ""
+ )
+ endif (WINDOWS)
+
+ target_link_libraries(http_texture_load ${example_libs})
+
+endif (LL_TESTS)
+
diff --git a/indra/llcorehttp/_httpinternal.h b/indra/llcorehttp/_httpinternal.h
new file mode 100755
index 0000000000..008e4fd95c
--- /dev/null
+++ b/indra/llcorehttp/_httpinternal.h
@@ -0,0 +1,151 @@
+/**
+ * @file _httpinternal.h
+ * @brief Implementation constants and magic numbers
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 _LLCORE_HTTP_INTERNAL_H_
+#define _LLCORE_HTTP_INTERNAL_H_
+
+
+// If you find this included in a public interface header,
+// something wrong is probably happening.
+
+
+// --------------------------------------------------------------------
+// General library to-do list
+//
+// - Implement policy classes. Structure is mostly there just didn't
+// need it for the first consumer.
+// - Consider Removing 'priority' from the request interface. Its use
+// in an always active class can lead to starvation of low-priority
+// requests. Requires coodination of priority values across all
+// components that share a class. Changing priority across threads
+// is slightly expensive (relative to gain) and hasn't been completely
+// implemented. And the major user of priority, texture fetches,
+// may not really need it.
+// - Set/get for global policy and policy classes is clumsy. Rework
+// it heading in a direction that allows for more dynamic behavior.
+// - Move HttpOpRequest::prepareRequest() to HttpLibcurl for the
+// pedantic.
+// - Update downloader and other long-duration services are going to
+// need a progress notification. Initial idea is to introduce a
+// 'repeating request' which can piggyback on another request and
+// persist until canceled or carrier completes. Current queue
+// structures allow an HttpOperation object to be enqueued
+// repeatedly, so...
+// - Investigate making c-ares' re-implementation of a resolver library
+// more resilient or more intelligent on Mac. Part of the DNS failure
+// lies in here. The mechanism also looks a little less dynamic
+// than needed in an environments where networking is changing.
+// - Global optimizations: 'borrowing' connections from other classes,
+// HTTP pipelining.
+// - Dynamic/control system stuff: detect problems and self-adjust.
+// This won't help in the face of the router problems we've looked
+// at, however. Detect starvation due to UDP activity and provide
+// feedback to it.
+//
+// Integration to-do list
+// - LLTextureFetch still needs a major refactor. The use of
+// LLQueuedThread makes it hard to inspect workers and do the
+// resource waiting we're now doing. Rebuild along simpler lines
+// some of which are suggested in new commentary at the top of
+// the main source file.
+// - Expand areas of usage eventually leading to the removal of LLCurl.
+// Rough order of expansion:
+// . Mesh fetch
+// . Avatar names
+// . Group membership lists
+// . Caps access in general
+// . 'The rest'
+// - Adapt texture cache, image decode and other image consumers to
+// the BufferArray model to reduce data copying. Alternatively,
+// adapt this library to something else.
+//
+// --------------------------------------------------------------------
+
+
+// If '1', internal ready queues will not order ready
+// requests by priority, instead it's first-come-first-served.
+// Reprioritization requests have the side-effect of then
+// putting the modified request at the back of the ready queue.
+
+#define LLCORE_HTTP_READY_QUEUE_IGNORES_PRIORITY 1
+
+
+namespace LLCore
+{
+
+// Maxium number of policy classes that can be defined.
+// *TODO: Currently limited to the default class, extend.
+const int HTTP_POLICY_CLASS_LIMIT = 1;
+
+// Debug/informational tracing. Used both
+// as a global option and in per-request traces.
+const int HTTP_TRACE_OFF = 0;
+const int HTTP_TRACE_LOW = 1;
+const int HTTP_TRACE_CURL_HEADERS = 2;
+const int HTTP_TRACE_CURL_BODIES = 3;
+
+const int HTTP_TRACE_MIN = HTTP_TRACE_OFF;
+const int HTTP_TRACE_MAX = HTTP_TRACE_CURL_BODIES;
+
+// Request retry limits
+//
+// At a minimum, retries need to extend past any throttling
+// window we're expecting from central services. In the case
+// of Linden services running through the caps routers, there's
+// a five-second or so window for throttling with some spillover.
+// We want to span a few windows to allow transport to slow
+// after onset of the throttles and then recover without a final
+// failure. Other systems may need other constants.
+const int HTTP_RETRY_COUNT_DEFAULT = 8;
+const int HTTP_RETRY_COUNT_MIN = 0;
+const int HTTP_RETRY_COUNT_MAX = 100;
+
+const int HTTP_REDIRECTS_DEFAULT = 10;
+
+// Timeout value used for both connect and protocol exchange.
+// Retries and time-on-queue are not included and aren't
+// accounted for.
+const long HTTP_REQUEST_TIMEOUT_DEFAULT = 30L;
+const long HTTP_REQUEST_TIMEOUT_MIN = 0L;
+const long HTTP_REQUEST_TIMEOUT_MAX = 3600L;
+
+// Limits on connection counts
+const int HTTP_CONNECTION_LIMIT_DEFAULT = 8;
+const int HTTP_CONNECTION_LIMIT_MIN = 1;
+const int HTTP_CONNECTION_LIMIT_MAX = 256;
+
+// Tuning parameters
+
+// Time worker thread sleeps after a pass through the
+// request, ready and active queues.
+const int HTTP_SERVICE_LOOP_SLEEP_NORMAL_MS = 2;
+
+// Block allocation size (a tuning parameter) is found
+// in bufferarray.h.
+
+} // end namespace LLCore
+
+#endif // _LLCORE_HTTP_INTERNAL_H_
diff --git a/indra/llcorehttp/_httplibcurl.cpp b/indra/llcorehttp/_httplibcurl.cpp
new file mode 100755
index 0000000000..6fe0bfc7d1
--- /dev/null
+++ b/indra/llcorehttp/_httplibcurl.cpp
@@ -0,0 +1,373 @@
+/**
+ * @file _httplibcurl.cpp
+ * @brief Internal definitions of the Http libcurl thread
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 "_httplibcurl.h"
+
+#include "httpheaders.h"
+#include "bufferarray.h"
+#include "_httpoprequest.h"
+#include "_httppolicy.h"
+
+#include "llhttpstatuscodes.h"
+
+
+namespace LLCore
+{
+
+
+HttpLibcurl::HttpLibcurl(HttpService * service)
+ : mService(service),
+ mPolicyCount(0),
+ mMultiHandles(NULL)
+{}
+
+
+HttpLibcurl::~HttpLibcurl()
+{
+ shutdown();
+
+ mService = NULL;
+}
+
+
+void HttpLibcurl::shutdown()
+{
+ while (! mActiveOps.empty())
+ {
+ HttpOpRequest * op(* mActiveOps.begin());
+ mActiveOps.erase(mActiveOps.begin());
+
+ cancelRequest(op);
+ op->release();
+ }
+
+ if (mMultiHandles)
+ {
+ for (int policy_class(0); policy_class < mPolicyCount; ++policy_class)
+ {
+ if (mMultiHandles[policy_class])
+ {
+ curl_multi_cleanup(mMultiHandles[policy_class]);
+ mMultiHandles[policy_class] = 0;
+ }
+ }
+
+ delete [] mMultiHandles;
+ mMultiHandles = NULL;
+ }
+
+ mPolicyCount = 0;
+}
+
+
+void HttpLibcurl::start(int policy_count)
+{
+ llassert_always(policy_count <= HTTP_POLICY_CLASS_LIMIT);
+ llassert_always(! mMultiHandles); // One-time call only
+
+ mPolicyCount = policy_count;
+ mMultiHandles = new CURLM * [mPolicyCount];
+ for (int policy_class(0); policy_class < mPolicyCount; ++policy_class)
+ {
+ mMultiHandles[policy_class] = curl_multi_init();
+ }
+}
+
+
+// Give libcurl some cycles, invoke it's callbacks, process
+// completed requests finalizing or issuing retries as needed.
+//
+// If active list goes empty *and* we didn't queue any
+// requests for retry, we return a request for a hard
+// sleep otherwise ask for a normal polling interval.
+HttpService::ELoopSpeed HttpLibcurl::processTransport()
+{
+ HttpService::ELoopSpeed ret(HttpService::REQUEST_SLEEP);
+
+ // Give libcurl some cycles to do I/O & callbacks
+ for (int policy_class(0); policy_class < mPolicyCount; ++policy_class)
+ {
+ if (! mMultiHandles[policy_class])
+ continue;
+
+ int running(0);
+ CURLMcode status(CURLM_CALL_MULTI_PERFORM);
+ do
+ {
+ running = 0;
+ status = curl_multi_perform(mMultiHandles[policy_class], &running);
+ }
+ while (0 != running && CURLM_CALL_MULTI_PERFORM == status);
+
+ // Run completion on anything done
+ CURLMsg * msg(NULL);
+ int msgs_in_queue(0);
+ while ((msg = curl_multi_info_read(mMultiHandles[policy_class], &msgs_in_queue)))
+ {
+ if (CURLMSG_DONE == msg->msg)
+ {
+ CURL * handle(msg->easy_handle);
+ CURLcode result(msg->data.result);
+
+ if (completeRequest(mMultiHandles[policy_class], handle, result))
+ {
+ // Request is still active, don't get too sleepy
+ ret = HttpService::NORMAL;
+ }
+ handle = NULL; // No longer valid on return
+ }
+ else if (CURLMSG_NONE == msg->msg)
+ {
+ // Ignore this... it shouldn't mean anything.
+ ;
+ }
+ else
+ {
+ LL_WARNS_ONCE("CoreHttp") << "Unexpected message from libcurl. Msg code: "
+ << msg->msg
+ << LL_ENDL;
+ }
+ msgs_in_queue = 0;
+ }
+ }
+
+ if (! mActiveOps.empty())
+ {
+ ret = HttpService::NORMAL;
+ }
+ return ret;
+}
+
+
+// Caller has provided us with a ref count on op.
+void HttpLibcurl::addOp(HttpOpRequest * op)
+{
+ llassert_always(op->mReqPolicy < mPolicyCount);
+ llassert_always(mMultiHandles[op->mReqPolicy] != NULL);
+
+ // Create standard handle
+ if (! op->prepareRequest(mService))
+ {
+ // Couldn't issue request, fail with notification
+ // *TODO: Need failure path
+ return;
+ }
+
+ // Make the request live
+ curl_multi_add_handle(mMultiHandles[op->mReqPolicy], op->mCurlHandle);
+ op->mCurlActive = true;
+
+ if (op->mTracing > HTTP_TRACE_OFF)
+ {
+ HttpPolicy & policy(mService->getPolicy());
+
+ LL_INFOS("CoreHttp") << "TRACE, ToActiveQueue, Handle: "
+ << static_cast<HttpHandle>(op)
+ << ", Actives: " << mActiveOps.size()
+ << ", Readies: " << policy.getReadyCount(op->mReqPolicy)
+ << LL_ENDL;
+ }
+
+ // On success, make operation active
+ mActiveOps.insert(op);
+}
+
+
+// Implements the transport part of any cancel operation.
+// See if the handle is an active operation and if so,
+// use the more complicated transport-based cancelation
+// method to kill the request.
+bool HttpLibcurl::cancel(HttpHandle handle)
+{
+ HttpOpRequest * op(static_cast<HttpOpRequest *>(handle));
+ active_set_t::iterator it(mActiveOps.find(op));
+ if (mActiveOps.end() == it)
+ {
+ return false;
+ }
+
+ // Cancel request
+ cancelRequest(op);
+
+ // Drop references
+ mActiveOps.erase(it);
+ op->release();
+
+ return true;
+}
+
+
+// *NOTE: cancelRequest logic parallels completeRequest logic.
+// Keep them synchronized as necessary. Caller is expected to
+// remove the op from the active list and release the op *after*
+// calling this method. It must be called first to deliver the
+// op to the reply queue with refcount intact.
+void HttpLibcurl::cancelRequest(HttpOpRequest * op)
+{
+ // Deactivate request
+ op->mCurlActive = false;
+
+ // Detach from multi and recycle handle
+ curl_multi_remove_handle(mMultiHandles[op->mReqPolicy], op->mCurlHandle);
+ curl_easy_cleanup(op->mCurlHandle);
+ op->mCurlHandle = NULL;
+
+ // Tracing
+ if (op->mTracing > HTTP_TRACE_OFF)
+ {
+ LL_INFOS("CoreHttp") << "TRACE, RequestCanceled, Handle: "
+ << static_cast<HttpHandle>(op)
+ << ", Status: " << op->mStatus.toHex()
+ << LL_ENDL;
+ }
+
+ // Cancel op and deliver for notification
+ op->cancel();
+}
+
+
+// *NOTE: cancelRequest logic parallels completeRequest logic.
+// Keep them synchronized as necessary.
+bool HttpLibcurl::completeRequest(CURLM * multi_handle, CURL * handle, CURLcode status)
+{
+ HttpOpRequest * op(NULL);
+ curl_easy_getinfo(handle, CURLINFO_PRIVATE, &op);
+
+ if (handle != op->mCurlHandle || ! op->mCurlActive)
+ {
+ LL_WARNS("CoreHttp") << "libcurl handle and HttpOpRequest handle in disagreement or inactive request."
+ << " Handle: " << static_cast<HttpHandle>(handle)
+ << LL_ENDL;
+ return false;
+ }
+
+ active_set_t::iterator it(mActiveOps.find(op));
+ if (mActiveOps.end() == it)
+ {
+ LL_WARNS("CoreHttp") << "libcurl completion for request not on active list. Continuing."
+ << " Handle: " << static_cast<HttpHandle>(handle)
+ << LL_ENDL;
+ return false;
+ }
+
+ // Deactivate request
+ mActiveOps.erase(it);
+ op->mCurlActive = false;
+
+ // Set final status of request if it hasn't failed by other mechanisms yet
+ if (op->mStatus)
+ {
+ op->mStatus = HttpStatus(HttpStatus::EXT_CURL_EASY, status);
+ }
+ if (op->mStatus)
+ {
+ int http_status(HTTP_OK);
+
+ curl_easy_getinfo(handle, CURLINFO_RESPONSE_CODE, &http_status);
+ if (http_status >= 100 && http_status <= 999)
+ {
+ char * cont_type(NULL);
+ curl_easy_getinfo(handle, CURLINFO_CONTENT_TYPE, &cont_type);
+ if (cont_type)
+ {
+ op->mReplyConType = cont_type;
+ }
+ op->mStatus = HttpStatus(http_status);
+ }
+ else
+ {
+ LL_WARNS("CoreHttp") << "Invalid HTTP response code ("
+ << http_status << ") received from server."
+ << LL_ENDL;
+ op->mStatus = HttpStatus(HttpStatus::LLCORE, HE_INVALID_HTTP_STATUS);
+ }
+ }
+
+ // Detach from multi and recycle handle
+ curl_multi_remove_handle(multi_handle, handle);
+ curl_easy_cleanup(handle);
+ op->mCurlHandle = NULL;
+
+ // Tracing
+ if (op->mTracing > HTTP_TRACE_OFF)
+ {
+ LL_INFOS("CoreHttp") << "TRACE, RequestComplete, Handle: "
+ << static_cast<HttpHandle>(op)
+ << ", Status: " << op->mStatus.toHex()
+ << LL_ENDL;
+ }
+
+ // Dispatch to next stage
+ HttpPolicy & policy(mService->getPolicy());
+ bool still_active(policy.stageAfterCompletion(op));
+
+ return still_active;
+}
+
+
+int HttpLibcurl::getActiveCount() const
+{
+ return mActiveOps.size();
+}
+
+
+int HttpLibcurl::getActiveCountInClass(int policy_class) const
+{
+ int count(0);
+
+ for (active_set_t::const_iterator iter(mActiveOps.begin());
+ mActiveOps.end() != iter;
+ ++iter)
+ {
+ if ((*iter)->mReqPolicy == policy_class)
+ {
+ ++count;
+ }
+ }
+
+ return count;
+}
+
+
+// ---------------------------------------
+// Free functions
+// ---------------------------------------
+
+
+struct curl_slist * append_headers_to_slist(const HttpHeaders * headers, struct curl_slist * slist)
+{
+ for (HttpHeaders::container_t::const_iterator it(headers->mHeaders.begin());
+
+ headers->mHeaders.end() != it;
+ ++it)
+ {
+ slist = curl_slist_append(slist, (*it).c_str());
+ }
+ return slist;
+}
+
+
+} // end namespace LLCore
diff --git a/indra/llcorehttp/_httplibcurl.h b/indra/llcorehttp/_httplibcurl.h
new file mode 100755
index 0000000000..611f029ef5
--- /dev/null
+++ b/indra/llcorehttp/_httplibcurl.h
@@ -0,0 +1,129 @@
+/**
+ * @file _httplibcurl.h
+ * @brief Declarations for internal class providing libcurl transport.
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 _LLCORE_HTTP_LIBCURL_H_
+#define _LLCORE_HTTP_LIBCURL_H_
+
+#include "linden_common.h" // Modifies curl/curl.h interfaces
+
+#include <curl/curl.h>
+#include <curl/multi.h>
+
+#include <set>
+
+#include "httprequest.h"
+#include "_httpservice.h"
+#include "_httpinternal.h"
+
+
+namespace LLCore
+{
+
+
+class HttpPolicy;
+class HttpOpRequest;
+class HttpHeaders;
+
+
+/// Implements libcurl-based transport for an HttpService instance.
+///
+/// Threading: Single-threaded. Other than for construction/destruction,
+/// all methods are expected to be invoked in a single thread, typically
+/// a worker thread of some sort.
+
+class HttpLibcurl
+{
+public:
+ HttpLibcurl(HttpService * service);
+ virtual ~HttpLibcurl();
+
+private:
+ HttpLibcurl(const HttpLibcurl &); // Not defined
+ void operator=(const HttpLibcurl &); // Not defined
+
+public:
+ /// Give cycles to libcurl to run active requests. Completed
+ /// operations (successful or failed) will be retried or handed
+ /// over to the reply queue as final responses.
+ ///
+ /// @return Indication of how long this method is
+ /// willing to wait for next service call.
+ HttpService::ELoopSpeed processTransport();
+
+ /// Add request to the active list. Caller is expected to have
+ /// provided us with a reference count on the op to hold the
+ /// request. (No additional references will be added.)
+ void addOp(HttpOpRequest * op);
+
+ /// One-time call to set the number of policy classes to be
+ /// serviced and to create the resources for each. Value
+ /// must agree with HttpPolicy::setPolicies() call.
+ void start(int policy_count);
+
+ /// Synchronously stop libcurl operations. All active requests
+ /// are canceled and removed from libcurl's handling. Easy
+ /// handles are detached from their multi handles and released.
+ /// Multi handles are also released. Canceled requests are
+ /// completed with canceled status and made available on their
+ /// respective reply queues.
+ ///
+ /// Can be restarted with a start() call.
+ void shutdown();
+
+ /// Return global and per-class counts of active requests.
+ int getActiveCount() const;
+ int getActiveCountInClass(int policy_class) const;
+
+ /// Attempt to cancel a request identified by handle.
+ ///
+ /// Interface shadows HttpService's method.
+ ///
+ /// @return True if handle was found and operation canceled.
+ ///
+ bool cancel(HttpHandle handle);
+
+protected:
+ /// Invoked when libcurl has indicated a request has been processed
+ /// to completion and we need to move the request to a new state.
+ bool completeRequest(CURLM * multi_handle, CURL * handle, CURLcode status);
+
+ /// Invoked to cancel an active request, mainly during shutdown
+ /// and destroy.
+ void cancelRequest(HttpOpRequest * op);
+
+protected:
+ typedef std::set<HttpOpRequest *> active_set_t;
+
+protected:
+ HttpService * mService; // Simple reference, not owner
+ active_set_t mActiveOps;
+ int mPolicyCount;
+ CURLM ** mMultiHandles;
+}; // end class HttpLibcurl
+
+} // end namespace LLCore
+
+#endif // _LLCORE_HTTP_LIBCURL_H_
diff --git a/indra/llcorehttp/_httpopcancel.cpp b/indra/llcorehttp/_httpopcancel.cpp
new file mode 100755
index 0000000000..c1912eb3db
--- /dev/null
+++ b/indra/llcorehttp/_httpopcancel.cpp
@@ -0,0 +1,73 @@
+/**
+ * @file _httpopcancel.cpp
+ * @brief Definitions for internal class HttpOpCancel
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 "_httpopcancel.h"
+
+#include "httpcommon.h"
+#include "httphandler.h"
+#include "httpresponse.h"
+
+#include "_httpservice.h"
+
+
+namespace LLCore
+{
+
+
+// ==================================
+// HttpOpCancel
+// ==================================
+
+
+HttpOpCancel::HttpOpCancel(HttpHandle handle)
+ : HttpOperation(),
+ mHandle(handle)
+{}
+
+
+HttpOpCancel::~HttpOpCancel()
+{}
+
+
+// Immediately search for the request on various queues
+// and cancel operations if found. Return the status of
+// the search and cancel as the status of this request.
+// The canceled request will return a canceled status to
+// its handler.
+void HttpOpCancel::stageFromRequest(HttpService * service)
+{
+ if (! service->cancel(mHandle))
+ {
+ mStatus = HttpStatus(HttpStatus::LLCORE, HE_HANDLE_NOT_FOUND);
+ }
+
+ addAsReply();
+}
+
+
+} // end namespace LLCore
+
+
diff --git a/indra/llcorehttp/_httpopcancel.h b/indra/llcorehttp/_httpopcancel.h
new file mode 100755
index 0000000000..336dfdc573
--- /dev/null
+++ b/indra/llcorehttp/_httpopcancel.h
@@ -0,0 +1,78 @@
+/**
+ * @file _httpopcancel.h
+ * @brief Internal declarations for the HttpOpCancel subclass
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 _LLCORE_HTTP_OPCANCEL_H_
+#define _LLCORE_HTTP_OPCANCEL_H_
+
+
+#include "linden_common.h" // Modifies curl/curl.h interfaces
+
+#include "httpcommon.h"
+
+#include <curl/curl.h>
+
+#include "_httpoperation.h"
+#include "_refcounted.h"
+
+
+namespace LLCore
+{
+
+
+/// HttpOpCancel requests that a previously issued request
+/// be canceled, if possible. This includes active requests
+/// that may be in the middle of an HTTP transaction. Any
+/// completed request will not be canceled and will return
+/// its final status unchanged and *this* request will complete
+/// with an HE_HANDLE_NOT_FOUND error status.
+
+class HttpOpCancel : public HttpOperation
+{
+public:
+ /// @param handle Handle of previously-issued request to
+ /// be canceled.
+ HttpOpCancel(HttpHandle handle);
+
+protected:
+ virtual ~HttpOpCancel(); // Use release()
+
+private:
+ HttpOpCancel(const HttpOpCancel &); // Not defined
+ void operator=(const HttpOpCancel &); // Not defined
+
+public:
+ virtual void stageFromRequest(HttpService *);
+
+public:
+ // Request data
+ HttpHandle mHandle;
+}; // end class HttpOpCancel
+
+
+} // end namespace LLCore
+
+#endif // _LLCORE_HTTP_OPCANCEL_H_
+
diff --git a/indra/llcorehttp/_httpoperation.cpp b/indra/llcorehttp/_httpoperation.cpp
new file mode 100755
index 0000000000..5cf5bc5930
--- /dev/null
+++ b/indra/llcorehttp/_httpoperation.cpp
@@ -0,0 +1,248 @@
+/**
+ * @file _httpoperation.cpp
+ * @brief Definitions for internal classes based on HttpOperation
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 "_httpoperation.h"
+
+#include "httphandler.h"
+#include "httpresponse.h"
+#include "httprequest.h"
+
+#include "_httprequestqueue.h"
+#include "_httpreplyqueue.h"
+#include "_httpservice.h"
+#include "_httpinternal.h"
+
+#include "lltimer.h"
+
+
+namespace LLCore
+{
+
+
+// ==================================
+// HttpOperation
+// ==================================
+
+
+HttpOperation::HttpOperation()
+ : LLCoreInt::RefCounted(true),
+ mReplyQueue(NULL),
+ mUserHandler(NULL),
+ mReqPolicy(HttpRequest::DEFAULT_POLICY_ID),
+ mReqPriority(0U),
+ mTracing(0)
+{
+ mMetricCreated = totalTime();
+}
+
+
+HttpOperation::~HttpOperation()
+{
+ setReplyPath(NULL, NULL);
+}
+
+
+void HttpOperation::setReplyPath(HttpReplyQueue * reply_queue,
+ HttpHandler * user_handler)
+{
+ if (reply_queue != mReplyQueue)
+ {
+ if (mReplyQueue)
+ {
+ mReplyQueue->release();
+ }
+
+ if (reply_queue)
+ {
+ reply_queue->addRef();
+ }
+
+ mReplyQueue = reply_queue;
+ }
+
+ // Not refcounted
+ mUserHandler = user_handler;
+}
+
+
+
+void HttpOperation::stageFromRequest(HttpService *)
+{
+ // Default implementation should never be called. This
+ // indicates an operation making a transition that isn't
+ // defined.
+ LL_ERRS("HttpCore") << "Default stageFromRequest method may not be called."
+ << LL_ENDL;
+}
+
+
+void HttpOperation::stageFromReady(HttpService *)
+{
+ // Default implementation should never be called. This
+ // indicates an operation making a transition that isn't
+ // defined.
+ LL_ERRS("HttpCore") << "Default stageFromReady method may not be called."
+ << LL_ENDL;
+}
+
+
+void HttpOperation::stageFromActive(HttpService *)
+{
+ // Default implementation should never be called. This
+ // indicates an operation making a transition that isn't
+ // defined.
+ LL_ERRS("HttpCore") << "Default stageFromActive method may not be called."
+ << LL_ENDL;
+}
+
+
+void HttpOperation::visitNotifier(HttpRequest *)
+{
+ if (mUserHandler)
+ {
+ HttpResponse * response = new HttpResponse();
+
+ response->setStatus(mStatus);
+ mUserHandler->onCompleted(static_cast<HttpHandle>(this), response);
+
+ response->release();
+ }
+}
+
+
+HttpStatus HttpOperation::cancel()
+{
+ HttpStatus status;
+
+ return status;
+}
+
+
+void HttpOperation::addAsReply()
+{
+ if (mTracing > HTTP_TRACE_OFF)
+ {
+ LL_INFOS("CoreHttp") << "TRACE, ToReplyQueue, Handle: "
+ << static_cast<HttpHandle>(this)
+ << LL_ENDL;
+ }
+
+ if (mReplyQueue)
+ {
+ addRef();
+ mReplyQueue->addOp(this);
+ }
+}
+
+
+// ==================================
+// HttpOpStop
+// ==================================
+
+
+HttpOpStop::HttpOpStop()
+ : HttpOperation()
+{}
+
+
+HttpOpStop::~HttpOpStop()
+{}
+
+
+void HttpOpStop::stageFromRequest(HttpService * service)
+{
+ // Do operations
+ service->stopRequested();
+
+ // Prepare response if needed
+ addAsReply();
+}
+
+
+// ==================================
+// HttpOpNull
+// ==================================
+
+
+HttpOpNull::HttpOpNull()
+ : HttpOperation()
+{}
+
+
+HttpOpNull::~HttpOpNull()
+{}
+
+
+void HttpOpNull::stageFromRequest(HttpService * service)
+{
+ // Perform op
+ // Nothing to perform. This doesn't fall into the libcurl
+ // ready/active queues, it just bounces over to the reply
+ // queue directly.
+
+ // Prepare response if needed
+ addAsReply();
+}
+
+
+// ==================================
+// HttpOpSpin
+// ==================================
+
+
+HttpOpSpin::HttpOpSpin(int mode)
+ : HttpOperation(),
+ mMode(mode)
+{}
+
+
+HttpOpSpin::~HttpOpSpin()
+{}
+
+
+void HttpOpSpin::stageFromRequest(HttpService * service)
+{
+ if (0 == mMode)
+ {
+ // Spin forever
+ while (true)
+ {
+ ms_sleep(100);
+ }
+ }
+ else
+ {
+ ms_sleep(1); // backoff interlock plumbing a bit
+ this->addRef();
+ if (! service->getRequestQueue().addOp(this))
+ {
+ this->release();
+ }
+ }
+}
+
+
+} // end namespace LLCore
diff --git a/indra/llcorehttp/_httpoperation.h b/indra/llcorehttp/_httpoperation.h
new file mode 100755
index 0000000000..914627fad0
--- /dev/null
+++ b/indra/llcorehttp/_httpoperation.h
@@ -0,0 +1,262 @@
+/**
+ * @file _httpoperation.h
+ * @brief Internal declarations for HttpOperation and sub-classes
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 _LLCORE_HTTP_OPERATION_H_
+#define _LLCORE_HTTP_OPERATION_H_
+
+
+#include "httpcommon.h"
+#include "httprequest.h"
+#include "_refcounted.h"
+
+
+namespace LLCore
+{
+
+class HttpReplyQueue;
+class HttpHandler;
+class HttpService;
+
+/// HttpOperation is the base class for all request/reply
+/// pairs.
+///
+/// Operations are expected to be of two types: immediate
+/// and queued. Immediate requests go to the singleton
+/// request queue and when picked up by the worker thread
+/// are executed immediately and there results placed on
+/// the supplied reply queue. Queued requests (namely for
+/// HTTP operations), go to the request queue, are picked
+/// up and moved to a ready queue where they're ordered by
+/// priority and managed by the policy component, are
+/// then activated issuing HTTP requests and moved to an
+/// active list managed by the transport (libcurl) component
+/// and eventually finalized when a response is available
+/// and status and data return via reply queue.
+///
+/// To manage these transitions, derived classes implement
+/// three methods: stageFromRequest, stageFromReady and
+/// stageFromActive. Immediate requests will only override
+/// stageFromRequest which will perform the operation and
+/// return the result by invoking addAsReply() to put the
+/// request on a reply queue. Queued requests will involve
+/// all three stage methods.
+///
+/// Threading: not thread-safe. Base and derived classes
+/// provide no locking. Instances move across threads
+/// via queue-like interfaces that are thread compatible
+/// and those interfaces establish the access rules.
+
+class HttpOperation : public LLCoreInt::RefCounted
+{
+public:
+ /// Threading: called by a consumer/application thread.
+ HttpOperation();
+
+protected:
+ /// Threading: called by any thread.
+ virtual ~HttpOperation(); // Use release()
+
+private:
+ HttpOperation(const HttpOperation &); // Not defined
+ void operator=(const HttpOperation &); // Not defined
+
+public:
+ /// Register a reply queue and a handler for completion notifications.
+ ///
+ /// Invokers of operations that want to receive notification that an
+ /// operation has been completed do so by binding a reply queue and
+ /// a handler object to the request.
+ ///
+ /// @param reply_queue Pointer to the reply queue where completion
+ /// notifications are to be queued (typically
+ /// by addAsReply()). This will typically be
+ /// the reply queue referenced by the request
+ /// object. This method will increment the
+ /// refcount on the queue holding the queue
+ /// until delivery is complete. Using a reply_queue
+ /// even if the handler is NULL has some benefits
+ /// for memory deallocation by keeping it in the
+ /// originating thread.
+ ///
+ /// @param handler Possibly NULL pointer to a non-refcounted
+ //// handler object to be invoked (onCompleted)
+ /// when the operation is finished. Note that
+ /// the handler object is never dereferenced
+ /// by the worker thread. This is passible data
+ /// until notification is performed.
+ ///
+ /// Threading: called by application thread.
+ ///
+ void setReplyPath(HttpReplyQueue * reply_queue,
+ HttpHandler * handler);
+
+ /// The three possible staging steps in an operation's lifecycle.
+ /// Asynchronous requests like HTTP operations move from the
+ /// request queue to the ready queue via stageFromRequest. Then
+ /// from the ready queue to the active queue by stageFromReady. And
+ /// when complete, to the reply queue via stageFromActive and the
+ /// addAsReply utility.
+ ///
+ /// Immediate mode operations (everything else) move from the
+ /// request queue to the reply queue directly via stageFromRequest
+ /// and addAsReply with no existence on the ready or active queues.
+ ///
+ /// These methods will take out a reference count on the request,
+ /// caller only needs to dispose of its reference when done with
+ /// the request.
+ ///
+ /// Threading: called by worker thread.
+ ///
+ virtual void stageFromRequest(HttpService *);
+ virtual void stageFromReady(HttpService *);
+ virtual void stageFromActive(HttpService *);
+
+ /// Delivers a notification to a handler object on completion.
+ ///
+ /// Once a request is complete and it has been removed from its
+ /// reply queue, a handler notification may be delivered by a
+ /// call to HttpRequest::update(). This method does the necessary
+ /// dispatching.
+ ///
+ /// Threading: called by application thread.
+ ///
+ virtual void visitNotifier(HttpRequest *);
+
+ /// Cancels the operation whether queued or active.
+ /// Final status of the request becomes canceled (an error) and
+ /// that will be delivered to caller via notification scheme.
+ ///
+ /// Threading: called by worker thread.
+ ///
+ virtual HttpStatus cancel();
+
+protected:
+ /// Delivers request to reply queue on completion. After this
+ /// call, worker thread no longer accesses the object and it
+ /// is owned by the reply queue.
+ ///
+ /// Threading: called by worker thread.
+ ///
+ void addAsReply();
+
+protected:
+ HttpReplyQueue * mReplyQueue; // Have refcount
+ HttpHandler * mUserHandler; // Naked pointer
+
+public:
+ // Request Data
+ HttpRequest::policy_t mReqPolicy;
+ HttpRequest::priority_t mReqPriority;
+
+ // Reply Data
+ HttpStatus mStatus;
+
+ // Tracing, debug and metrics
+ HttpTime mMetricCreated;
+ int mTracing;
+}; // end class HttpOperation
+
+
+/// HttpOpStop requests the servicing thread to shutdown
+/// operations, cease pulling requests from the request
+/// queue and release shared resources (particularly
+/// those shared via reference count). The servicing
+/// thread will then exit. The underlying thread object
+/// remains so that another thread can join on the
+/// servicing thread prior to final cleanup. The
+/// request *does* generate a reply on the response
+/// queue, if requested.
+
+class HttpOpStop : public HttpOperation
+{
+public:
+ HttpOpStop();
+
+protected:
+ virtual ~HttpOpStop();
+
+private:
+ HttpOpStop(const HttpOpStop &); // Not defined
+ void operator=(const HttpOpStop &); // Not defined
+
+public:
+ virtual void stageFromRequest(HttpService *);
+
+}; // end class HttpOpStop
+
+
+/// HttpOpNull is a do-nothing operation used for testing via
+/// a basic loopback pattern. It's executed immediately by
+/// the servicing thread which bounces a reply back to the
+/// caller without any further delay.
+
+class HttpOpNull : public HttpOperation
+{
+public:
+ HttpOpNull();
+
+protected:
+ virtual ~HttpOpNull();
+
+private:
+ HttpOpNull(const HttpOpNull &); // Not defined
+ void operator=(const HttpOpNull &); // Not defined
+
+public:
+ virtual void stageFromRequest(HttpService *);
+
+}; // end class HttpOpNull
+
+
+/// HttpOpSpin is a test-only request that puts the worker
+/// thread into a cpu spin. Used for unit tests and cleanup
+/// evaluation. You do not want to use this in production.
+class HttpOpSpin : public HttpOperation
+{
+public:
+ // 0 does a hard spin in the operation
+ // 1 does a soft spin continuously requeuing itself
+ HttpOpSpin(int mode);
+
+protected:
+ virtual ~HttpOpSpin();
+
+private:
+ HttpOpSpin(const HttpOpSpin &); // Not defined
+ void operator=(const HttpOpSpin &); // Not defined
+
+public:
+ virtual void stageFromRequest(HttpService *);
+
+protected:
+ int mMode;
+}; // end class HttpOpSpin
+
+
+} // end namespace LLCore
+
+#endif // _LLCORE_HTTP_OPERATION_H_
+
diff --git a/indra/llcorehttp/_httpoprequest.cpp b/indra/llcorehttp/_httpoprequest.cpp
new file mode 100755
index 0000000000..207ed8e1e4
--- /dev/null
+++ b/indra/llcorehttp/_httpoprequest.cpp
@@ -0,0 +1,886 @@
+/**
+ * @file _httpoprequest.cpp
+ * @brief Definitions for internal class HttpOpRequest
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012-2013, 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 "_httpoprequest.h"
+
+#include <cstdio>
+#include <algorithm>
+
+#include "httpcommon.h"
+#include "httphandler.h"
+#include "httpresponse.h"
+#include "bufferarray.h"
+#include "httpheaders.h"
+#include "httpoptions.h"
+
+#include "_httprequestqueue.h"
+#include "_httpreplyqueue.h"
+#include "_httpservice.h"
+#include "_httppolicy.h"
+#include "_httppolicyglobal.h"
+#include "_httplibcurl.h"
+#include "_httpinternal.h"
+
+#include "llhttpstatuscodes.h"
+#include "llproxy.h"
+
+namespace
+{
+
+// Attempts to parse a 'Content-Range:' header. Caller must already
+// have verified that the header tag is present. The 'buffer' argument
+// will be processed by strtok_r calls which will modify the buffer.
+//
+// @return -1 if invalid and response should be dropped, 0 if valid an
+// correct, 1 if couldn't be parsed. If 0, the first, last,
+// and length arguments are also written. 'length' may be
+// 0 if the length wasn't available to the server.
+//
+int parse_content_range_header(char * buffer,
+ unsigned int * first,
+ unsigned int * last,
+ unsigned int * length);
+
+
+// Take data from libcurl's CURLOPT_DEBUGFUNCTION callback and
+// escape and format it for a tracing line in logging. Absolutely
+// anything including NULs can be in the data. If @scrub is true,
+// non-printing or non-ascii characters are replaced with spaces
+// otherwise a %XX form of escaping is used.
+void escape_libcurl_debug_data(char * buffer, size_t len, bool scrub,
+ std::string & safe_line);
+
+
+// OS-neutral string comparisons of various types
+int os_strncasecmp(const char *s1, const char *s2, size_t n);
+int os_strcasecmp(const char *s1, const char *s2);
+char * os_strtok_r(char *str, const char *delim, char **saveptr);
+
+
+static const char * const hdr_whitespace(" \t");
+static const char * const hdr_separator(": \t");
+
+} // end anonymous namespace
+
+
+namespace LLCore
+{
+
+
+HttpOpRequest::HttpOpRequest()
+ : HttpOperation(),
+ mProcFlags(0U),
+ mReqMethod(HOR_GET),
+ mReqBody(NULL),
+ mReqOffset(0),
+ mReqLength(0),
+ mReqHeaders(NULL),
+ mReqOptions(NULL),
+ mCurlActive(false),
+ mCurlHandle(NULL),
+ mCurlService(NULL),
+ mCurlHeaders(NULL),
+ mCurlBodyPos(0),
+ mReplyBody(NULL),
+ mReplyOffset(0),
+ mReplyLength(0),
+ mReplyFullLength(0),
+ mReplyHeaders(NULL),
+ mPolicyRetries(0),
+ mPolicyRetryAt(HttpTime(0)),
+ mPolicyRetryLimit(HTTP_RETRY_COUNT_DEFAULT)
+{
+ // *NOTE: As members are added, retry initialization/cleanup
+ // may need to be extended in @see prepareRequest().
+}
+
+
+
+HttpOpRequest::~HttpOpRequest()
+{
+ if (mReqBody)
+ {
+ mReqBody->release();
+ mReqBody = NULL;
+ }
+
+ if (mReqOptions)
+ {
+ mReqOptions->release();
+ mReqOptions = NULL;
+ }
+
+ if (mReqHeaders)
+ {
+ mReqHeaders->release();
+ mReqHeaders = NULL;
+ }
+
+ if (mCurlHandle)
+ {
+ curl_easy_cleanup(mCurlHandle);
+ mCurlHandle = NULL;
+ }
+
+ mCurlService = NULL;
+
+ if (mCurlHeaders)
+ {
+ curl_slist_free_all(mCurlHeaders);
+ mCurlHeaders = NULL;
+ }
+
+ if (mReplyBody)
+ {
+ mReplyBody->release();
+ mReplyBody = NULL;
+ }
+
+ if (mReplyHeaders)
+ {
+ mReplyHeaders->release();
+ mReplyHeaders = NULL;
+ }
+}
+
+
+void HttpOpRequest::stageFromRequest(HttpService * service)
+{
+ addRef();
+ service->getPolicy().addOp(this); // transfers refcount
+}
+
+
+void HttpOpRequest::stageFromReady(HttpService * service)
+{
+ addRef();
+ service->getTransport().addOp(this); // transfers refcount
+}
+
+
+void HttpOpRequest::stageFromActive(HttpService * service)
+{
+ if (mReplyLength)
+ {
+ // If non-zero, we received and processed a Content-Range
+ // header with the response. If there is received data
+ // (and there may not be due to protocol violations,
+ // HEAD requests, etc., see BUG-2295) Verify that what it
+ // says is consistent with the received data.
+ if (mReplyBody && mReplyBody->size() && mReplyLength != mReplyBody->size())
+ {
+ // Not as expected, fail the request
+ mStatus = HttpStatus(HttpStatus::LLCORE, HE_INV_CONTENT_RANGE_HDR);
+ }
+ }
+
+ if (mCurlHeaders)
+ {
+ // We take these headers out of the request now as they were
+ // allocated originally in this thread and the notifier doesn't
+ // need them. This eliminates one source of heap moving across
+ // threads.
+
+ curl_slist_free_all(mCurlHeaders);
+ mCurlHeaders = NULL;
+ }
+
+ addAsReply();
+}
+
+
+void HttpOpRequest::visitNotifier(HttpRequest * request)
+{
+ if (mUserHandler)
+ {
+ HttpResponse * response = new HttpResponse();
+ response->setStatus(mStatus);
+ response->setBody(mReplyBody);
+ response->setHeaders(mReplyHeaders);
+ if (mReplyOffset || mReplyLength)
+ {
+ // Got an explicit offset/length in response
+ response->setRange(mReplyOffset, mReplyLength, mReplyFullLength);
+ }
+ response->setContentType(mReplyConType);
+
+ mUserHandler->onCompleted(static_cast<HttpHandle>(this), response);
+
+ response->release();
+ }
+}
+
+
+HttpStatus HttpOpRequest::cancel()
+{
+ mStatus = HttpStatus(HttpStatus::LLCORE, HE_OP_CANCELED);
+
+ addAsReply();
+
+ return HttpStatus();
+}
+
+
+HttpStatus HttpOpRequest::setupGet(HttpRequest::policy_t policy_id,
+ HttpRequest::priority_t priority,
+ const std::string & url,
+ HttpOptions * options,
+ HttpHeaders * headers)
+{
+ setupCommon(policy_id, priority, url, NULL, options, headers);
+ mReqMethod = HOR_GET;
+
+ return HttpStatus();
+}
+
+
+HttpStatus HttpOpRequest::setupGetByteRange(HttpRequest::policy_t policy_id,
+ HttpRequest::priority_t priority,
+ const std::string & url,
+ size_t offset,
+ size_t len,
+ HttpOptions * options,
+ HttpHeaders * headers)
+{
+ setupCommon(policy_id, priority, url, NULL, options, headers);
+ mReqMethod = HOR_GET;
+ mReqOffset = offset;
+ mReqLength = len;
+ if (offset || len)
+ {
+ mProcFlags |= PF_SCAN_RANGE_HEADER;
+ }
+
+ return HttpStatus();
+}
+
+
+HttpStatus HttpOpRequest::setupPost(HttpRequest::policy_t policy_id,
+ HttpRequest::priority_t priority,
+ const std::string & url,
+ BufferArray * body,
+ HttpOptions * options,
+ HttpHeaders * headers)
+{
+ setupCommon(policy_id, priority, url, body, options, headers);
+ mReqMethod = HOR_POST;
+
+ return HttpStatus();
+}
+
+
+HttpStatus HttpOpRequest::setupPut(HttpRequest::policy_t policy_id,
+ HttpRequest::priority_t priority,
+ const std::string & url,
+ BufferArray * body,
+ HttpOptions * options,
+ HttpHeaders * headers)
+{
+ setupCommon(policy_id, priority, url, body, options, headers);
+ mReqMethod = HOR_PUT;
+
+ return HttpStatus();
+}
+
+
+void HttpOpRequest::setupCommon(HttpRequest::policy_t policy_id,
+ HttpRequest::priority_t priority,
+ const std::string & url,
+ BufferArray * body,
+ HttpOptions * options,
+ HttpHeaders * headers)
+{
+ mProcFlags = 0U;
+ mReqPolicy = policy_id;
+ mReqPriority = priority;
+ mReqURL = url;
+ if (body)
+ {
+ body->addRef();
+ mReqBody = body;
+ }
+ if (headers && ! mReqHeaders)
+ {
+ headers->addRef();
+ mReqHeaders = headers;
+ }
+ if (options && ! mReqOptions)
+ {
+ options->addRef();
+ mReqOptions = options;
+ if (options->getWantHeaders())
+ {
+ mProcFlags |= PF_SAVE_HEADERS;
+ }
+ mPolicyRetryLimit = options->getRetries();
+ mPolicyRetryLimit = llclamp(mPolicyRetryLimit, HTTP_RETRY_COUNT_MIN, HTTP_RETRY_COUNT_MAX);
+ mTracing = (std::max)(mTracing, llclamp(options->getTrace(), HTTP_TRACE_MIN, HTTP_TRACE_MAX));
+ }
+}
+
+// Sets all libcurl options and data for a request.
+//
+// Used both for initial requests and to 'reload' for
+// a retry, generally with a different CURL handle.
+// Junk may be left around from a failed request and that
+// needs to be cleaned out.
+//
+HttpStatus HttpOpRequest::prepareRequest(HttpService * service)
+{
+ // Scrub transport and result data for retried op case
+ mCurlActive = false;
+ mCurlHandle = NULL;
+ mCurlService = NULL;
+ if (mCurlHeaders)
+ {
+ curl_slist_free_all(mCurlHeaders);
+ mCurlHeaders = NULL;
+ }
+ mCurlBodyPos = 0;
+
+ if (mReplyBody)
+ {
+ mReplyBody->release();
+ mReplyBody = NULL;
+ }
+ mReplyOffset = 0;
+ mReplyLength = 0;
+ mReplyFullLength = 0;
+ if (mReplyHeaders)
+ {
+ mReplyHeaders->release();
+ mReplyHeaders = NULL;
+ }
+ mReplyConType.clear();
+
+ // *FIXME: better error handling later
+ HttpStatus status;
+
+ // Get policy options
+ HttpPolicyGlobal & policy(service->getPolicy().getGlobalOptions());
+
+ mCurlHandle = LLCurl::createStandardCurlHandle();
+
+ curl_easy_setopt(mCurlHandle, CURLOPT_WRITEFUNCTION, writeCallback);
+ curl_easy_setopt(mCurlHandle, CURLOPT_READFUNCTION, readCallback);
+ curl_easy_setopt(mCurlHandle, CURLOPT_READDATA, this);
+ curl_easy_setopt(mCurlHandle, CURLOPT_WRITEDATA, this);
+ curl_easy_setopt(mCurlHandle, CURLOPT_URL, mReqURL.c_str());
+ curl_easy_setopt(mCurlHandle, CURLOPT_PRIVATE, this);
+ curl_easy_setopt(mCurlHandle, CURLOPT_MAXREDIRS, HTTP_REDIRECTS_DEFAULT);
+
+ const std::string * opt_value(NULL);
+ long opt_long(0L);
+ policy.get(HttpRequest::GP_LLPROXY, &opt_long);
+ if (opt_long)
+ {
+ // Use the viewer-based thread-safe API which has a
+ // fast/safe check for proxy enable. Would like to
+ // encapsulate this someway...
+ LLProxy::getInstance()->applyProxySettings(mCurlHandle);
+ }
+ else if (policy.get(HttpRequest::GP_HTTP_PROXY, &opt_value))
+ {
+ // *TODO: This is fine for now but get fuller socks5/
+ // authentication thing going later....
+ curl_easy_setopt(mCurlHandle, CURLOPT_PROXY, opt_value->c_str());
+ curl_easy_setopt(mCurlHandle, CURLOPT_PROXYTYPE, CURLPROXY_HTTP);
+ }
+ if (policy.get(HttpRequest::GP_CA_PATH, &opt_value))
+ {
+ curl_easy_setopt(mCurlHandle, CURLOPT_CAPATH, opt_value->c_str());
+ }
+ if (policy.get(HttpRequest::GP_CA_FILE, &opt_value))
+ {
+ curl_easy_setopt(mCurlHandle, CURLOPT_CAINFO, opt_value->c_str());
+ }
+
+ switch (mReqMethod)
+ {
+ case HOR_GET:
+ curl_easy_setopt(mCurlHandle, CURLOPT_HTTPGET, 1);
+ mCurlHeaders = curl_slist_append(mCurlHeaders, "Connection: keep-alive");
+ mCurlHeaders = curl_slist_append(mCurlHeaders, "Keep-alive: 300");
+ break;
+
+ case HOR_POST:
+ {
+ curl_easy_setopt(mCurlHandle, CURLOPT_POST, 1);
+ curl_easy_setopt(mCurlHandle, CURLOPT_ENCODING, "");
+ long data_size(0);
+ if (mReqBody)
+ {
+ data_size = mReqBody->size();
+ }
+ curl_easy_setopt(mCurlHandle, CURLOPT_POSTFIELDS, static_cast<void *>(NULL));
+ curl_easy_setopt(mCurlHandle, CURLOPT_POSTFIELDSIZE, data_size);
+ mCurlHeaders = curl_slist_append(mCurlHeaders, "Expect:");
+ mCurlHeaders = curl_slist_append(mCurlHeaders, "Connection: keep-alive");
+ mCurlHeaders = curl_slist_append(mCurlHeaders, "Keep-alive: 300");
+ }
+ break;
+
+ case HOR_PUT:
+ {
+ curl_easy_setopt(mCurlHandle, CURLOPT_UPLOAD, 1);
+ long data_size(0);
+ if (mReqBody)
+ {
+ data_size = mReqBody->size();
+ }
+ curl_easy_setopt(mCurlHandle, CURLOPT_INFILESIZE, data_size);
+ curl_easy_setopt(mCurlHandle, CURLOPT_POSTFIELDS, (void *) NULL);
+ mCurlHeaders = curl_slist_append(mCurlHeaders, "Expect:");
+ mCurlHeaders = curl_slist_append(mCurlHeaders, "Connection: keep-alive");
+ mCurlHeaders = curl_slist_append(mCurlHeaders, "Keep-alive: 300");
+ }
+ break;
+
+ default:
+ LL_ERRS("CoreHttp") << "Invalid HTTP method in request: "
+ << int(mReqMethod) << ". Can't recover."
+ << LL_ENDL;
+ break;
+ }
+
+ // Tracing
+ if (mTracing >= HTTP_TRACE_CURL_HEADERS)
+ {
+ curl_easy_setopt(mCurlHandle, CURLOPT_VERBOSE, 1);
+ curl_easy_setopt(mCurlHandle, CURLOPT_DEBUGDATA, this);
+ curl_easy_setopt(mCurlHandle, CURLOPT_DEBUGFUNCTION, debugCallback);
+ }
+
+ // There's a CURLOPT for this now...
+ if ((mReqOffset || mReqLength) && HOR_GET == mReqMethod)
+ {
+ static const char * const fmt1("Range: bytes=%lu-%lu");
+ static const char * const fmt2("Range: bytes=%lu-");
+
+ char range_line[64];
+
+#if LL_WINDOWS
+ _snprintf_s(range_line, sizeof(range_line), sizeof(range_line) - 1,
+ (mReqLength ? fmt1 : fmt2),
+ (unsigned long) mReqOffset, (unsigned long) (mReqOffset + mReqLength - 1));
+#else
+ snprintf(range_line, sizeof(range_line),
+ (mReqLength ? fmt1 : fmt2),
+ (unsigned long) mReqOffset, (unsigned long) (mReqOffset + mReqLength - 1));
+#endif // LL_WINDOWS
+ range_line[sizeof(range_line) - 1] = '\0';
+ mCurlHeaders = curl_slist_append(mCurlHeaders, range_line);
+ }
+
+ mCurlHeaders = curl_slist_append(mCurlHeaders, "Pragma:");
+
+ // Request options
+ long timeout(HTTP_REQUEST_TIMEOUT_DEFAULT);
+ if (mReqOptions)
+ {
+ timeout = mReqOptions->getTimeout();
+ timeout = llclamp(timeout, HTTP_REQUEST_TIMEOUT_MIN, HTTP_REQUEST_TIMEOUT_MAX);
+ }
+ curl_easy_setopt(mCurlHandle, CURLOPT_TIMEOUT, timeout);
+ curl_easy_setopt(mCurlHandle, CURLOPT_CONNECTTIMEOUT, timeout);
+
+ // Request headers
+ if (mReqHeaders)
+ {
+ // Caller's headers last to override
+ mCurlHeaders = append_headers_to_slist(mReqHeaders, mCurlHeaders);
+ }
+ curl_easy_setopt(mCurlHandle, CURLOPT_HTTPHEADER, mCurlHeaders);
+
+ if (mProcFlags & (PF_SCAN_RANGE_HEADER | PF_SAVE_HEADERS))
+ {
+ curl_easy_setopt(mCurlHandle, CURLOPT_HEADERFUNCTION, headerCallback);
+ curl_easy_setopt(mCurlHandle, CURLOPT_HEADERDATA, this);
+ }
+
+ if (status)
+ {
+ mCurlService = service;
+ }
+ return status;
+}
+
+
+size_t HttpOpRequest::writeCallback(void * data, size_t size, size_t nmemb, void * userdata)
+{
+ HttpOpRequest * op(static_cast<HttpOpRequest *>(userdata));
+
+ if (! op->mReplyBody)
+ {
+ op->mReplyBody = new BufferArray();
+ }
+ const size_t req_size(size * nmemb);
+ const size_t write_size(op->mReplyBody->append(static_cast<char *>(data), req_size));
+ return write_size;
+}
+
+
+size_t HttpOpRequest::readCallback(void * data, size_t size, size_t nmemb, void * userdata)
+{
+ HttpOpRequest * op(static_cast<HttpOpRequest *>(userdata));
+
+ if (! op->mReqBody)
+ {
+ return 0;
+ }
+ const size_t req_size(size * nmemb);
+ const size_t body_size(op->mReqBody->size());
+ if (body_size <= op->mCurlBodyPos)
+ {
+ if (body_size < op->mCurlBodyPos)
+ {
+ // Warn but continue if the read position moves beyond end-of-body
+ // for some reason.
+ LL_WARNS("HttpCore") << "Request body position beyond body size. Truncating request body."
+ << LL_ENDL;
+ }
+ return 0;
+ }
+
+ const size_t do_size((std::min)(req_size, body_size - op->mCurlBodyPos));
+ const size_t read_size(op->mReqBody->read(op->mCurlBodyPos, static_cast<char *>(data), do_size));
+ op->mCurlBodyPos += read_size;
+ return read_size;
+}
+
+
+size_t HttpOpRequest::headerCallback(void * data, size_t size, size_t nmemb, void * userdata)
+{
+ static const char status_line[] = "HTTP/";
+ static const size_t status_line_len = sizeof(status_line) - 1;
+
+ static const char con_ran_line[] = "content-range:";
+ static const size_t con_ran_line_len = sizeof(con_ran_line) - 1;
+
+ HttpOpRequest * op(static_cast<HttpOpRequest *>(userdata));
+
+ const size_t hdr_size(size * nmemb);
+ const char * hdr_data(static_cast<const char *>(data)); // Not null terminated
+
+ if (hdr_size >= status_line_len && ! strncmp(status_line, hdr_data, status_line_len))
+ {
+ // One of possibly several status lines. Reset what we know and start over
+ // taking results from the last header stanza we receive.
+ op->mReplyOffset = 0;
+ op->mReplyLength = 0;
+ op->mReplyFullLength = 0;
+ op->mStatus = HttpStatus();
+ if (op->mReplyHeaders)
+ {
+ op->mReplyHeaders->mHeaders.clear();
+ }
+ }
+
+ // Nothing in here wants a final CR/LF combination. Remove
+ // it as much as possible.
+ size_t wanted_hdr_size(hdr_size);
+ if (wanted_hdr_size && '\n' == hdr_data[wanted_hdr_size - 1])
+ {
+ if (--wanted_hdr_size && '\r' == hdr_data[wanted_hdr_size - 1])
+ {
+ --wanted_hdr_size;
+ }
+ }
+
+ // Save header if caller wants them in the response
+ if (op->mProcFlags & PF_SAVE_HEADERS)
+ {
+ // Save headers in response
+ if (! op->mReplyHeaders)
+ {
+ op->mReplyHeaders = new HttpHeaders;
+ }
+ op->mReplyHeaders->mHeaders.push_back(std::string(hdr_data, wanted_hdr_size));
+ }
+
+ // Detect and parse 'Content-Range' headers
+ if (op->mProcFlags & PF_SCAN_RANGE_HEADER)
+ {
+ char hdr_buffer[128]; // Enough for a reasonable header
+ size_t frag_size((std::min)(wanted_hdr_size, sizeof(hdr_buffer) - 1));
+
+ memcpy(hdr_buffer, hdr_data, frag_size);
+ hdr_buffer[frag_size] = '\0';
+ if (frag_size > con_ran_line_len &&
+ ! os_strncasecmp(hdr_buffer, con_ran_line, con_ran_line_len))
+ {
+ unsigned int first(0), last(0), length(0);
+ int status;
+
+ if (! (status = parse_content_range_header(hdr_buffer, &first, &last, &length)))
+ {
+ // Success, record the fragment position
+ op->mReplyOffset = first;
+ op->mReplyLength = last - first + 1;
+ op->mReplyFullLength = length;
+ }
+ else if (-1 == status)
+ {
+ // Response is badly formed and shouldn't be accepted
+ op->mStatus = HttpStatus(HttpStatus::LLCORE, HE_INV_CONTENT_RANGE_HDR);
+ }
+ else
+ {
+ // Ignore the unparsable.
+ LL_INFOS_ONCE("CoreHttp") << "Problem parsing odd Content-Range header: '"
+ << std::string(hdr_data, frag_size)
+ << "'. Ignoring."
+ << LL_ENDL;
+ }
+ }
+ }
+
+ return hdr_size;
+}
+
+
+int HttpOpRequest::debugCallback(CURL * handle, curl_infotype info, char * buffer, size_t len, void * userdata)
+{
+ HttpOpRequest * op(static_cast<HttpOpRequest *>(userdata));
+
+ std::string safe_line;
+ std::string tag;
+ bool logit(false);
+ const size_t log_len((std::min)(len, size_t(256))); // Keep things reasonable in all cases
+
+ switch (info)
+ {
+ case CURLINFO_TEXT:
+ if (op->mTracing >= HTTP_TRACE_CURL_HEADERS)
+ {
+ tag = "TEXT";
+ escape_libcurl_debug_data(buffer, log_len, true, safe_line);
+ logit = true;
+ }
+ break;
+
+ case CURLINFO_HEADER_IN:
+ if (op->mTracing >= HTTP_TRACE_CURL_HEADERS)
+ {
+ tag = "HEADERIN";
+ escape_libcurl_debug_data(buffer, log_len, true, safe_line);
+ logit = true;
+ }
+ break;
+
+ case CURLINFO_HEADER_OUT:
+ if (op->mTracing >= HTTP_TRACE_CURL_HEADERS)
+ {
+ tag = "HEADEROUT";
+ escape_libcurl_debug_data(buffer, log_len, true, safe_line); // Goes out as one line unlike header_in
+ logit = true;
+ }
+ break;
+
+ case CURLINFO_DATA_IN:
+ if (op->mTracing >= HTTP_TRACE_CURL_HEADERS)
+ {
+ tag = "DATAIN";
+ logit = true;
+ if (op->mTracing >= HTTP_TRACE_CURL_BODIES)
+ {
+ escape_libcurl_debug_data(buffer, log_len, false, safe_line);
+ }
+ else
+ {
+ std::ostringstream out;
+ out << len << " Bytes";
+ safe_line = out.str();
+ }
+ }
+ break;
+
+ case CURLINFO_DATA_OUT:
+ if (op->mTracing >= HTTP_TRACE_CURL_HEADERS)
+ {
+ tag = "DATAOUT";
+ logit = true;
+ if (op->mTracing >= HTTP_TRACE_CURL_BODIES)
+ {
+ escape_libcurl_debug_data(buffer, log_len, false, safe_line);
+ }
+ else
+ {
+ std::ostringstream out;
+ out << len << " Bytes";
+ safe_line = out.str();
+ }
+ }
+ break;
+
+ default:
+ logit = false;
+ break;
+ }
+
+ if (logit)
+ {
+ LL_INFOS("CoreHttp") << "TRACE, LibcurlDebug, Handle: "
+ << static_cast<HttpHandle>(op)
+ << ", Type: " << tag
+ << ", Data: " << safe_line
+ << LL_ENDL;
+ }
+
+ return 0;
+}
+
+
+} // end namespace LLCore
+
+
+// =======================================
+// Anonymous Namespace
+// =======================================
+
+namespace
+{
+
+int parse_content_range_header(char * buffer,
+ unsigned int * first,
+ unsigned int * last,
+ unsigned int * length)
+{
+ char * tok_state(NULL), * tok(NULL);
+ bool match(true);
+
+ if (! os_strtok_r(buffer, hdr_separator, &tok_state))
+ match = false;
+ if (match && (tok = os_strtok_r(NULL, hdr_whitespace, &tok_state)))
+ match = 0 == os_strcasecmp("bytes", tok);
+ if (match && ! (tok = os_strtok_r(NULL, " \t", &tok_state)))
+ match = false;
+ if (match)
+ {
+ unsigned int lcl_first(0), lcl_last(0), lcl_len(0);
+
+#if LL_WINDOWS
+ if (3 == sscanf_s(tok, "%u-%u/%u", &lcl_first, &lcl_last, &lcl_len))
+#else
+ if (3 == sscanf(tok, "%u-%u/%u", &lcl_first, &lcl_last, &lcl_len))
+#endif // LL_WINDOWS
+ {
+ if (lcl_first > lcl_last || lcl_last >= lcl_len)
+ return -1;
+ *first = lcl_first;
+ *last = lcl_last;
+ *length = lcl_len;
+ return 0;
+ }
+#if LL_WINDOWS
+ if (2 == sscanf_s(tok, "%u-%u/*", &lcl_first, &lcl_last))
+#else
+ if (2 == sscanf(tok, "%u-%u/*", &lcl_first, &lcl_last))
+#endif // LL_WINDOWS
+ {
+ if (lcl_first > lcl_last)
+ return -1;
+ *first = lcl_first;
+ *last = lcl_last;
+ *length = 0;
+ return 0;
+ }
+ }
+
+ // Header is there but badly/unexpectedly formed, try to ignore it.
+ return 1;
+}
+
+
+void escape_libcurl_debug_data(char * buffer, size_t len, bool scrub, std::string & safe_line)
+{
+ std::string out;
+ len = (std::min)(len, size_t(200));
+ out.reserve(3 * len);
+ for (int i(0); i < len; ++i)
+ {
+ unsigned char uc(static_cast<unsigned char>(buffer[i]));
+
+ if (uc < 32 || uc > 126)
+ {
+ if (scrub)
+ {
+ out.append(1, ' ');
+ }
+ else
+ {
+ static const char hex[] = "0123456789ABCDEF";
+ char convert[4];
+
+ convert[0] = '%';
+ convert[1] = hex[(uc >> 4) % 16];
+ convert[2] = hex[uc % 16];
+ convert[3] = '\0';
+ out.append(convert);
+ }
+ }
+ else
+ {
+ out.append(1, buffer[i]);
+ }
+ }
+ safe_line.swap(out);
+}
+
+
+int os_strncasecmp(const char *s1, const char *s2, size_t n)
+{
+#if LL_WINDOWS
+ return _strnicmp(s1, s2, n);
+#else
+ return strncasecmp(s1, s2, n);
+#endif // LL_WINDOWS
+}
+
+
+int os_strcasecmp(const char *s1, const char *s2)
+{
+#if LL_WINDOWS
+ return _stricmp(s1, s2);
+#else
+ return strcasecmp(s1, s2);
+#endif // LL_WINDOWS
+}
+
+
+char * os_strtok_r(char *str, const char *delim, char ** savestate)
+{
+#if LL_WINDOWS
+ return strtok_s(str, delim, savestate);
+#else
+ return strtok_r(str, delim, savestate);
+#endif
+}
+
+
+} // end anonymous namespace
+
+
diff --git a/indra/llcorehttp/_httpoprequest.h b/indra/llcorehttp/_httpoprequest.h
new file mode 100755
index 0000000000..74a349b0bf
--- /dev/null
+++ b/indra/llcorehttp/_httpoprequest.h
@@ -0,0 +1,218 @@
+/**
+ * @file _httpoprequest.h
+ * @brief Internal declarations for the HttpOpRequest subclass
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 _LLCORE_HTTP_OPREQUEST_H_
+#define _LLCORE_HTTP_OPREQUEST_H_
+
+
+#include "linden_common.h" // Modifies curl/curl.h interfaces
+
+#include <string>
+#include <curl/curl.h>
+
+#include "httpcommon.h"
+#include "httprequest.h"
+#include "_httpoperation.h"
+#include "_refcounted.h"
+
+
+namespace LLCore
+{
+
+
+class BufferArray;
+class HttpHeaders;
+class HttpOptions;
+
+
+/// HttpOpRequest requests a supported HTTP method invocation with
+/// option and header overrides.
+///
+/// Essentially an RPC to get an HTTP GET, POST or PUT executed
+/// asynchronously with options to override behaviors and HTTP
+/// headers.
+///
+/// Constructor creates a raw object incapable of useful work.
+/// A subsequent call to one of the setupXXX() methods provides
+/// the information needed to make a working request which can
+/// then be enqueued to a request queue.
+///
+class HttpOpRequest : public HttpOperation
+{
+public:
+ HttpOpRequest();
+
+protected:
+ virtual ~HttpOpRequest(); // Use release()
+
+private:
+ HttpOpRequest(const HttpOpRequest &); // Not defined
+ void operator=(const HttpOpRequest &); // Not defined
+
+public:
+ enum EMethod
+ {
+ HOR_GET,
+ HOR_POST,
+ HOR_PUT
+ };
+
+ virtual void stageFromRequest(HttpService *);
+ virtual void stageFromReady(HttpService *);
+ virtual void stageFromActive(HttpService *);
+
+ virtual void visitNotifier(HttpRequest * request);
+
+public:
+ /// Setup Methods
+ ///
+ /// Basically an RPC setup for each type of HTTP method
+ /// invocation with one per method type. These are
+ /// generally invoked right after construction.
+ ///
+ /// Threading: called by application thread
+ ///
+ HttpStatus setupGet(HttpRequest::policy_t policy_id,
+ HttpRequest::priority_t priority,
+ const std::string & url,
+ HttpOptions * options,
+ HttpHeaders * headers);
+
+ HttpStatus setupGetByteRange(HttpRequest::policy_t policy_id,
+ HttpRequest::priority_t priority,
+ const std::string & url,
+ size_t offset,
+ size_t len,
+ HttpOptions * options,
+ HttpHeaders * headers);
+
+ HttpStatus setupPost(HttpRequest::policy_t policy_id,
+ HttpRequest::priority_t priority,
+ const std::string & url,
+ BufferArray * body,
+ HttpOptions * options,
+ HttpHeaders * headers);
+
+ HttpStatus setupPut(HttpRequest::policy_t policy_id,
+ HttpRequest::priority_t priority,
+ const std::string & url,
+ BufferArray * body,
+ HttpOptions * options,
+ HttpHeaders * headers);
+
+ // Internal method used to setup the libcurl options for a request.
+ // Does all the libcurl handle setup in one place.
+ //
+ // Threading: called by worker thread
+ //
+ HttpStatus prepareRequest(HttpService * service);
+
+ virtual HttpStatus cancel();
+
+protected:
+ // Common setup for all the request methods.
+ //
+ // Threading: called by application thread
+ //
+ void setupCommon(HttpRequest::policy_t policy_id,
+ HttpRequest::priority_t priority,
+ const std::string & url,
+ BufferArray * body,
+ HttpOptions * options,
+ HttpHeaders * headers);
+
+ // libcurl operational callbacks
+ //
+ // Threading: called by worker thread
+ //
+ static size_t writeCallback(void * data, size_t size, size_t nmemb, void * userdata);
+ static size_t readCallback(void * data, size_t size, size_t nmemb, void * userdata);
+ static size_t headerCallback(void * data, size_t size, size_t nmemb, void * userdata);
+ static int debugCallback(CURL *, curl_infotype info, char * buffer, size_t len, void * userdata);
+
+protected:
+ unsigned int mProcFlags;
+ static const unsigned int PF_SCAN_RANGE_HEADER = 0x00000001U;
+ static const unsigned int PF_SAVE_HEADERS = 0x00000002U;
+
+public:
+ // Request data
+ EMethod mReqMethod;
+ std::string mReqURL;
+ BufferArray * mReqBody;
+ off_t mReqOffset;
+ size_t mReqLength;
+ HttpHeaders * mReqHeaders;
+ HttpOptions * mReqOptions;
+
+ // Transport data
+ bool mCurlActive;
+ CURL * mCurlHandle;
+ HttpService * mCurlService;
+ curl_slist * mCurlHeaders;
+ size_t mCurlBodyPos;
+
+ // Result data
+ HttpStatus mStatus;
+ BufferArray * mReplyBody;
+ off_t mReplyOffset;
+ size_t mReplyLength;
+ size_t mReplyFullLength;
+ HttpHeaders * mReplyHeaders;
+ std::string mReplyConType;
+
+ // Policy data
+ int mPolicyRetries;
+ HttpTime mPolicyRetryAt;
+ int mPolicyRetryLimit;
+}; // end class HttpOpRequest
+
+
+/// HttpOpRequestCompare isn't an operation but a uniform comparison
+/// functor for STL containers that order by priority. Mainly
+/// used for the ready queue container but defined here.
+class HttpOpRequestCompare
+{
+public:
+ bool operator()(const HttpOpRequest * lhs, const HttpOpRequest * rhs)
+ {
+ return lhs->mReqPriority > rhs->mReqPriority;
+ }
+}; // end class HttpOpRequestCompare
+
+
+// ---------------------------------------
+// Free functions
+// ---------------------------------------
+
+// Internal function to append the contents of an HttpHeaders
+// instance to a curl_slist object.
+curl_slist * append_headers_to_slist(const HttpHeaders *, curl_slist * slist);
+
+} // end namespace LLCore
+
+#endif // _LLCORE_HTTP_OPREQUEST_H_
+
diff --git a/indra/llcorehttp/_httpopsetget.cpp b/indra/llcorehttp/_httpopsetget.cpp
new file mode 100755
index 0000000000..8198528a9b
--- /dev/null
+++ b/indra/llcorehttp/_httpopsetget.cpp
@@ -0,0 +1,97 @@
+/**
+ * @file _httpopsetget.cpp
+ * @brief Definitions for internal class HttpOpSetGet
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 "_httpopsetget.h"
+
+#include "httpcommon.h"
+
+#include "_httpservice.h"
+#include "_httppolicy.h"
+
+
+namespace LLCore
+{
+
+
+// ==================================
+// HttpOpSetget
+// ==================================
+
+
+HttpOpSetGet::HttpOpSetGet()
+ : HttpOperation(),
+ mIsGlobal(false),
+ mDoSet(false),
+ mSetting(-1), // Nothing requested
+ mLongValue(0L)
+{}
+
+
+HttpOpSetGet::~HttpOpSetGet()
+{}
+
+
+void HttpOpSetGet::setupGet(HttpRequest::EGlobalPolicy setting)
+{
+ mIsGlobal = true;
+ mSetting = setting;
+}
+
+
+void HttpOpSetGet::setupSet(HttpRequest::EGlobalPolicy setting, const std::string & value)
+{
+ mIsGlobal = true;
+ mDoSet = true;
+ mSetting = setting;
+ mStrValue = value;
+}
+
+
+void HttpOpSetGet::stageFromRequest(HttpService * service)
+{
+ HttpPolicyGlobal & pol_opt(service->getPolicy().getGlobalOptions());
+ HttpRequest::EGlobalPolicy setting(static_cast<HttpRequest::EGlobalPolicy>(mSetting));
+
+ if (mDoSet)
+ {
+ mStatus = pol_opt.set(setting, mStrValue);
+ }
+ if (mStatus)
+ {
+ const std::string * value(NULL);
+ if ((mStatus = pol_opt.get(setting, &value)))
+ {
+ mStrValue = *value;
+ }
+ }
+
+ addAsReply();
+}
+
+
+} // end namespace LLCore
+
+
diff --git a/indra/llcorehttp/_httpopsetget.h b/indra/llcorehttp/_httpopsetget.h
new file mode 100755
index 0000000000..6966b9d94e
--- /dev/null
+++ b/indra/llcorehttp/_httpopsetget.h
@@ -0,0 +1,83 @@
+/**
+ * @file _httpopsetget.h
+ * @brief Internal declarations for the HttpOpSetGet subclass
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 _LLCORE_HTTP_OPSETGET_H_
+#define _LLCORE_HTTP_OPSETGET_H_
+
+
+#include "linden_common.h" // Modifies curl/curl.h interfaces
+
+#include "httpcommon.h"
+
+#include <curl/curl.h>
+
+#include "_httpoperation.h"
+#include "_refcounted.h"
+
+
+namespace LLCore
+{
+
+
+/// HttpOpSetGet requests dynamic changes to policy and
+/// configuration settings.
+///
+/// *NOTE: Expect this to change. Don't really like it yet.
+
+class HttpOpSetGet : public HttpOperation
+{
+public:
+ HttpOpSetGet();
+
+protected:
+ virtual ~HttpOpSetGet(); // Use release()
+
+private:
+ HttpOpSetGet(const HttpOpSetGet &); // Not defined
+ void operator=(const HttpOpSetGet &); // Not defined
+
+public:
+ /// Threading: called by application thread
+ void setupGet(HttpRequest::EGlobalPolicy setting);
+ void setupSet(HttpRequest::EGlobalPolicy setting, const std::string & value);
+
+ virtual void stageFromRequest(HttpService *);
+
+public:
+ // Request data
+ bool mIsGlobal;
+ bool mDoSet;
+ int mSetting;
+ long mLongValue;
+ std::string mStrValue;
+
+}; // end class HttpOpSetGet
+
+
+} // end namespace LLCore
+
+#endif // _LLCORE_HTTP_OPSETGET_H_
+
diff --git a/indra/llcorehttp/_httpopsetpriority.cpp b/indra/llcorehttp/_httpopsetpriority.cpp
new file mode 100755
index 0000000000..d48c7a0b7d
--- /dev/null
+++ b/indra/llcorehttp/_httpopsetpriority.cpp
@@ -0,0 +1,63 @@
+/**
+ * @file _httpopsetpriority.cpp
+ * @brief Definitions for internal classes based on HttpOpSetPriority
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 "_httpopsetpriority.h"
+
+#include "httpresponse.h"
+#include "httphandler.h"
+#include "_httpservice.h"
+
+
+namespace LLCore
+{
+
+
+HttpOpSetPriority::HttpOpSetPriority(HttpHandle handle, HttpRequest::priority_t priority)
+ : HttpOperation(),
+ mHandle(handle),
+ mPriority(priority)
+{}
+
+
+HttpOpSetPriority::~HttpOpSetPriority()
+{}
+
+
+void HttpOpSetPriority::stageFromRequest(HttpService * service)
+{
+ // Do operations
+ if (! service->changePriority(mHandle, mPriority))
+ {
+ // Request not found, fail the final status
+ mStatus = HttpStatus(HttpStatus::LLCORE, HE_HANDLE_NOT_FOUND);
+ }
+
+ // Move directly to response queue
+ addAsReply();
+}
+
+
+} // end namespace LLCore
diff --git a/indra/llcorehttp/_httpopsetpriority.h b/indra/llcorehttp/_httpopsetpriority.h
new file mode 100755
index 0000000000..31706b737c
--- /dev/null
+++ b/indra/llcorehttp/_httpopsetpriority.h
@@ -0,0 +1,73 @@
+/**
+ * @file _httpsetpriority.h
+ * @brief Internal declarations for HttpSetPriority
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 _LLCORE_HTTP_SETPRIORITY_H_
+#define _LLCORE_HTTP_SETPRIORITY_H_
+
+
+#include "httpcommon.h"
+#include "httprequest.h"
+#include "_httpoperation.h"
+#include "_refcounted.h"
+
+
+namespace LLCore
+{
+
+
+/// HttpOpSetPriority is an immediate request that
+/// searches the various queues looking for a given
+/// request handle and changing it's priority if
+/// found.
+///
+/// *NOTE: This will very likely be removed in the near future
+/// when priority is removed from the library.
+
+class HttpOpSetPriority : public HttpOperation
+{
+public:
+ HttpOpSetPriority(HttpHandle handle, HttpRequest::priority_t priority);
+
+protected:
+ virtual ~HttpOpSetPriority();
+
+private:
+ HttpOpSetPriority(const HttpOpSetPriority &); // Not defined
+ void operator=(const HttpOpSetPriority &); // Not defined
+
+public:
+ virtual void stageFromRequest(HttpService *);
+
+protected:
+ // Request Data
+ HttpHandle mHandle;
+ HttpRequest::priority_t mPriority;
+}; // end class HttpOpSetPriority
+
+} // end namespace LLCore
+
+#endif // _LLCORE_HTTP_SETPRIORITY_H_
+
diff --git a/indra/llcorehttp/_httppolicy.cpp b/indra/llcorehttp/_httppolicy.cpp
new file mode 100755
index 0000000000..014bd37e2e
--- /dev/null
+++ b/indra/llcorehttp/_httppolicy.cpp
@@ -0,0 +1,367 @@
+/**
+ * @file _httppolicy.cpp
+ * @brief Internal definitions of the Http policy thread
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012-2013, 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 "_httppolicy.h"
+
+#include "_httpoprequest.h"
+#include "_httpservice.h"
+#include "_httplibcurl.h"
+#include "_httppolicyclass.h"
+
+#include "lltimer.h"
+
+
+namespace LLCore
+{
+
+
+// Per-policy-class data for a running system.
+// Collection of queues, parameters, history, metrics, etc.
+// for a single policy class.
+//
+// Threading: accessed only by worker thread
+struct HttpPolicy::State
+{
+public:
+ State()
+ : mConnMax(HTTP_CONNECTION_LIMIT_DEFAULT),
+ mConnAt(HTTP_CONNECTION_LIMIT_DEFAULT),
+ mConnMin(1),
+ mNextSample(0),
+ mErrorCount(0),
+ mErrorFactor(0)
+ {}
+
+ HttpReadyQueue mReadyQueue;
+ HttpRetryQueue mRetryQueue;
+
+ HttpPolicyClass mOptions;
+
+ long mConnMax;
+ long mConnAt;
+ long mConnMin;
+
+ HttpTime mNextSample;
+ unsigned long mErrorCount;
+ unsigned long mErrorFactor;
+};
+
+
+HttpPolicy::HttpPolicy(HttpService * service)
+ : mActiveClasses(0),
+ mState(NULL),
+ mService(service)
+{}
+
+
+HttpPolicy::~HttpPolicy()
+{
+ shutdown();
+
+ mService = NULL;
+}
+
+
+void HttpPolicy::shutdown()
+{
+ for (int policy_class(0); policy_class < mActiveClasses; ++policy_class)
+ {
+ HttpRetryQueue & retryq(mState[policy_class].mRetryQueue);
+ while (! retryq.empty())
+ {
+ HttpOpRequest * op(retryq.top());
+ retryq.pop();
+
+ op->cancel();
+ op->release();
+ }
+
+ HttpReadyQueue & readyq(mState[policy_class].mReadyQueue);
+ while (! readyq.empty())
+ {
+ HttpOpRequest * op(readyq.top());
+ readyq.pop();
+
+ op->cancel();
+ op->release();
+ }
+ }
+ delete [] mState;
+ mState = NULL;
+ mActiveClasses = 0;
+}
+
+
+void HttpPolicy::start(const HttpPolicyGlobal & global,
+ const std::vector<HttpPolicyClass> & classes)
+{
+ llassert_always(! mState);
+
+ mGlobalOptions = global;
+ mActiveClasses = classes.size();
+ mState = new State [mActiveClasses];
+ for (int i(0); i < mActiveClasses; ++i)
+ {
+ mState[i].mOptions = classes[i];
+ mState[i].mConnMax = classes[i].mConnectionLimit;
+ mState[i].mConnAt = mState[i].mConnMax;
+ mState[i].mConnMin = 2;
+ }
+}
+
+
+void HttpPolicy::addOp(HttpOpRequest * op)
+{
+ const int policy_class(op->mReqPolicy);
+
+ op->mPolicyRetries = 0;
+ mState[policy_class].mReadyQueue.push(op);
+}
+
+
+void HttpPolicy::retryOp(HttpOpRequest * op)
+{
+ static const HttpTime retry_deltas[] =
+ {
+ 250000, // 1st retry in 0.25 S, etc...
+ 500000,
+ 1000000,
+ 2000000,
+ 5000000 // ... to every 5.0 S.
+ };
+ static const int delta_max(int(LL_ARRAY_SIZE(retry_deltas)) - 1);
+
+ const HttpTime now(totalTime());
+ const int policy_class(op->mReqPolicy);
+
+ const HttpTime delta(retry_deltas[llclamp(op->mPolicyRetries, 0, delta_max)]);
+ op->mPolicyRetryAt = now + delta;
+ ++op->mPolicyRetries;
+ LL_WARNS("CoreHttp") << "HTTP request " << static_cast<HttpHandle>(op)
+ << " retry " << op->mPolicyRetries
+ << " scheduled for +" << (delta / HttpTime(1000))
+ << " mS. Status: " << op->mStatus.toHex()
+ << LL_ENDL;
+ if (op->mTracing > 0)
+ {
+ LL_INFOS("CoreHttp") << "TRACE, ToRetryQueue, Handle: "
+ << static_cast<HttpHandle>(op)
+ << LL_ENDL;
+ }
+ mState[policy_class].mRetryQueue.push(op);
+}
+
+
+// Attempt to deliver requests to the transport layer.
+//
+// Tries to find HTTP requests for each policy class with
+// available capacity. Starts with the retry queue first
+// looking for requests that have waited long enough then
+// moves on to the ready queue.
+//
+// If all queues are empty, will return an indication that
+// the worker thread may sleep hard otherwise will ask for
+// normal polling frequency.
+//
+HttpService::ELoopSpeed HttpPolicy::processReadyQueue()
+{
+ const HttpTime now(totalTime());
+ HttpService::ELoopSpeed result(HttpService::REQUEST_SLEEP);
+ HttpLibcurl & transport(mService->getTransport());
+
+ for (int policy_class(0); policy_class < mActiveClasses; ++policy_class)
+ {
+ State & state(mState[policy_class]);
+ int active(transport.getActiveCountInClass(policy_class));
+ int needed(state.mConnAt - active); // Expect negatives here
+
+ HttpRetryQueue & retryq(state.mRetryQueue);
+ HttpReadyQueue & readyq(state.mReadyQueue);
+
+ if (needed > 0)
+ {
+ // First see if we have any retries...
+ while (needed > 0 && ! retryq.empty())
+ {
+ HttpOpRequest * op(retryq.top());
+ if (op->mPolicyRetryAt > now)
+ break;
+
+ retryq.pop();
+
+ op->stageFromReady(mService);
+ op->release();
+
+ --needed;
+ }
+
+ // Now go on to the new requests...
+ while (needed > 0 && ! readyq.empty())
+ {
+ HttpOpRequest * op(readyq.top());
+ readyq.pop();
+
+ op->stageFromReady(mService);
+ op->release();
+
+ --needed;
+ }
+ }
+
+ if (! readyq.empty() || ! retryq.empty())
+ {
+ // If anything is ready, continue looping...
+ result = HttpService::NORMAL;
+ }
+ } // end foreach policy_class
+
+ return result;
+}
+
+
+bool HttpPolicy::changePriority(HttpHandle handle, HttpRequest::priority_t priority)
+{
+ for (int policy_class(0); policy_class < mActiveClasses; ++policy_class)
+ {
+ State & state(mState[policy_class]);
+ // We don't scan retry queue because a priority change there
+ // is meaningless. The request will be issued based on retry
+ // intervals not priority value, which is now moot.
+
+ // Scan ready queue for requests that match policy
+ HttpReadyQueue::container_type & c(state.mReadyQueue.get_container());
+ for (HttpReadyQueue::container_type::iterator iter(c.begin()); c.end() != iter;)
+ {
+ HttpReadyQueue::container_type::iterator cur(iter++);
+
+ if (static_cast<HttpHandle>(*cur) == handle)
+ {
+ HttpOpRequest * op(*cur);
+ c.erase(cur); // All iterators are now invalidated
+ op->mReqPriority = priority;
+ state.mReadyQueue.push(op); // Re-insert using adapter class
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+
+bool HttpPolicy::cancel(HttpHandle handle)
+{
+ for (int policy_class(0); policy_class < mActiveClasses; ++policy_class)
+ {
+ State & state(mState[policy_class]);
+
+ // Scan retry queue
+ HttpRetryQueue::container_type & c1(state.mRetryQueue.get_container());
+ for (HttpRetryQueue::container_type::iterator iter(c1.begin()); c1.end() != iter;)
+ {
+ HttpRetryQueue::container_type::iterator cur(iter++);
+
+ if (static_cast<HttpHandle>(*cur) == handle)
+ {
+ HttpOpRequest * op(*cur);
+ c1.erase(cur); // All iterators are now invalidated
+ op->cancel();
+ op->release();
+ return true;
+ }
+ }
+
+ // Scan ready queue
+ HttpReadyQueue::container_type & c2(state.mReadyQueue.get_container());
+ for (HttpReadyQueue::container_type::iterator iter(c2.begin()); c2.end() != iter;)
+ {
+ HttpReadyQueue::container_type::iterator cur(iter++);
+
+ if (static_cast<HttpHandle>(*cur) == handle)
+ {
+ HttpOpRequest * op(*cur);
+ c2.erase(cur); // All iterators are now invalidated
+ op->cancel();
+ op->release();
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+
+bool HttpPolicy::stageAfterCompletion(HttpOpRequest * op)
+{
+ // Retry or finalize
+ if (! op->mStatus)
+ {
+ // If this failed, we might want to retry.
+ if (op->mPolicyRetries < op->mPolicyRetryLimit && op->mStatus.isRetryable())
+ {
+ // Okay, worth a retry.
+ retryOp(op);
+ return true; // still active/ready
+ }
+ }
+
+ // This op is done, finalize it delivering it to the reply queue...
+ if (! op->mStatus)
+ {
+ LL_WARNS("CoreHttp") << "HTTP request " << static_cast<HttpHandle>(op)
+ << " failed after " << op->mPolicyRetries
+ << " retries. Reason: " << op->mStatus.toString()
+ << " (" << op->mStatus.toHex() << ")"
+ << LL_ENDL;
+ }
+ else if (op->mPolicyRetries)
+ {
+ LL_WARNS("CoreHttp") << "HTTP request " << static_cast<HttpHandle>(op)
+ << " succeeded on retry " << op->mPolicyRetries << "."
+ << LL_ENDL;
+ }
+
+ op->stageFromActive(mService);
+ op->release();
+ return false; // not active
+}
+
+
+int HttpPolicy::getReadyCount(HttpRequest::policy_t policy_class) const
+{
+ if (policy_class < mActiveClasses)
+ {
+ return (mState[policy_class].mReadyQueue.size()
+ + mState[policy_class].mRetryQueue.size());
+ }
+ return 0;
+}
+
+
+} // end namespace LLCore
diff --git a/indra/llcorehttp/_httppolicy.h b/indra/llcorehttp/_httppolicy.h
new file mode 100755
index 0000000000..03d92c0b8e
--- /dev/null
+++ b/indra/llcorehttp/_httppolicy.h
@@ -0,0 +1,161 @@
+/**
+ * @file _httppolicy.h
+ * @brief Declarations for internal class enforcing policy decisions.
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 _LLCORE_HTTP_POLICY_H_
+#define _LLCORE_HTTP_POLICY_H_
+
+
+#include "httprequest.h"
+#include "_httpservice.h"
+#include "_httpreadyqueue.h"
+#include "_httpretryqueue.h"
+#include "_httppolicyglobal.h"
+#include "_httppolicyclass.h"
+#include "_httpinternal.h"
+
+
+namespace LLCore
+{
+
+class HttpReadyQueue;
+class HttpOpRequest;
+
+
+/// Implements class-based queuing policies for an HttpService instance.
+///
+/// Threading: Single-threaded. Other than for construction/destruction,
+/// all methods are expected to be invoked in a single thread, typically
+/// a worker thread of some sort.
+class HttpPolicy
+{
+public:
+ HttpPolicy(HttpService *);
+ virtual ~HttpPolicy();
+
+private:
+ HttpPolicy(const HttpPolicy &); // Not defined
+ void operator=(const HttpPolicy &); // Not defined
+
+public:
+ /// Cancel all ready and retry requests sending them to
+ /// their notification queues. Release state resources
+ /// making further request handling impossible.
+ ///
+ /// Threading: called by worker thread
+ void shutdown();
+
+ /// Deliver policy definitions and enable handling of
+ /// requests. One-time call invoked before starting
+ /// the worker thread.
+ ///
+ /// Threading: called by application thread
+ void start(const HttpPolicyGlobal & global,
+ const std::vector<HttpPolicyClass> & classes);
+
+ /// Give the policy layer some cycles to scan the ready
+ /// queue promoting higher-priority requests to active
+ /// as permited.
+ ///
+ /// @return Indication of how soon this method
+ /// should be called again.
+ ///
+ /// Threading: called by worker thread
+ HttpService::ELoopSpeed processReadyQueue();
+
+ /// Add request to a ready queue. Caller is expected to have
+ /// provided us with a reference count to hold the request. (No
+ /// additional references will be added.)
+ ///
+ /// OpRequest is owned by the request queue after this call
+ /// and should not be modified by anyone until retrieved
+ /// from queue.
+ ///
+ /// Threading: called by any thread
+ void addOp(HttpOpRequest *);
+
+ /// Similar to addOp, used when a caller wants to retry a
+ /// request that has failed. It's placed on a special retry
+ /// queue but ordered by retry time not priority. Otherwise,
+ /// handling is the same and retried operations are considered
+ /// before new ones but that doesn't guarantee completion
+ /// order.
+ ///
+ /// Threading: called by worker thread
+ void retryOp(HttpOpRequest *);
+
+ /// Attempt to change the priority of an earlier request.
+ /// Request that Shadows HttpService's method
+ ///
+ /// Threading: called by worker thread
+ bool changePriority(HttpHandle handle, HttpRequest::priority_t priority);
+
+ /// Attempt to cancel a previous request.
+ /// Shadows HttpService's method as well
+ ///
+ /// Threading: called by worker thread
+ bool cancel(HttpHandle handle);
+
+ /// When transport is finished with an op and takes it off the
+ /// active queue, it is delivered here for dispatch. Policy
+ /// may send it back to the ready/retry queues if it needs another
+ /// go or we may finalize it and send it on to the reply queue.
+ ///
+ /// @return Returns true of the request is still active
+ /// or ready after staging, false if has been
+ /// sent on to the reply queue.
+ ///
+ /// Threading: called by worker thread
+ bool stageAfterCompletion(HttpOpRequest * op);
+
+ // Get pointer to global policy options. Caller is expected
+ // to do context checks like no setting once running.
+ ///
+ /// Threading: called by any thread *but* the object may
+ /// only be modified by the worker thread once running.
+ ///
+ HttpPolicyGlobal & getGlobalOptions()
+ {
+ return mGlobalOptions;
+ }
+
+ /// Get ready counts for a particular policy class
+ ///
+ /// Threading: called by worker thread
+ int getReadyCount(HttpRequest::policy_t policy_class) const;
+
+protected:
+ struct State;
+
+ int mActiveClasses;
+ State * mState;
+ HttpService * mService; // Naked pointer, not refcounted, not owner
+ HttpPolicyGlobal mGlobalOptions;
+
+}; // end class HttpPolicy
+
+} // end namespace LLCore
+
+#endif // _LLCORE_HTTP_POLICY_H_
diff --git a/indra/llcorehttp/_httppolicyclass.cpp b/indra/llcorehttp/_httppolicyclass.cpp
new file mode 100755
index 0000000000..a23b81322c
--- /dev/null
+++ b/indra/llcorehttp/_httppolicyclass.cpp
@@ -0,0 +1,125 @@
+/**
+ * @file _httppolicyclass.cpp
+ * @brief Definitions for internal class defining class policy option.
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 "_httppolicyclass.h"
+
+#include "_httpinternal.h"
+
+
+namespace LLCore
+{
+
+
+HttpPolicyClass::HttpPolicyClass()
+ : mSetMask(0UL),
+ mConnectionLimit(HTTP_CONNECTION_LIMIT_DEFAULT),
+ mPerHostConnectionLimit(HTTP_CONNECTION_LIMIT_DEFAULT),
+ mPipelining(0)
+{}
+
+
+HttpPolicyClass::~HttpPolicyClass()
+{}
+
+
+HttpPolicyClass & HttpPolicyClass::operator=(const HttpPolicyClass & other)
+{
+ if (this != &other)
+ {
+ mSetMask = other.mSetMask;
+ mConnectionLimit = other.mConnectionLimit;
+ mPerHostConnectionLimit = other.mPerHostConnectionLimit;
+ mPipelining = other.mPipelining;
+ }
+ return *this;
+}
+
+
+HttpPolicyClass::HttpPolicyClass(const HttpPolicyClass & other)
+ : mSetMask(other.mSetMask),
+ mConnectionLimit(other.mConnectionLimit),
+ mPerHostConnectionLimit(other.mPerHostConnectionLimit),
+ mPipelining(other.mPipelining)
+{}
+
+
+HttpStatus HttpPolicyClass::set(HttpRequest::EClassPolicy opt, long value)
+{
+ switch (opt)
+ {
+ case HttpRequest::CP_CONNECTION_LIMIT:
+ mConnectionLimit = llclamp(value, long(HTTP_CONNECTION_LIMIT_MIN), long(HTTP_CONNECTION_LIMIT_MAX));
+ break;
+
+ case HttpRequest::CP_PER_HOST_CONNECTION_LIMIT:
+ mPerHostConnectionLimit = llclamp(value, long(HTTP_CONNECTION_LIMIT_MIN), mConnectionLimit);
+ break;
+
+ case HttpRequest::CP_ENABLE_PIPELINING:
+ mPipelining = llclamp(value, 0L, 1L);
+ break;
+
+ default:
+ return HttpStatus(HttpStatus::LLCORE, HE_INVALID_ARG);
+ }
+
+ mSetMask |= 1UL << int(opt);
+ return HttpStatus();
+}
+
+
+HttpStatus HttpPolicyClass::get(HttpRequest::EClassPolicy opt, long * value)
+{
+ static const HttpStatus not_set(HttpStatus::LLCORE, HE_OPT_NOT_SET);
+ long * src(NULL);
+
+ switch (opt)
+ {
+ case HttpRequest::CP_CONNECTION_LIMIT:
+ src = &mConnectionLimit;
+ break;
+
+ case HttpRequest::CP_PER_HOST_CONNECTION_LIMIT:
+ src = &mPerHostConnectionLimit;
+ break;
+
+ case HttpRequest::CP_ENABLE_PIPELINING:
+ src = &mPipelining;
+ break;
+
+ default:
+ return HttpStatus(HttpStatus::LLCORE, HE_INVALID_ARG);
+ }
+
+ if (! (mSetMask & (1UL << int(opt))))
+ return not_set;
+
+ *value = *src;
+ return HttpStatus();
+}
+
+
+} // end namespace LLCore
diff --git a/indra/llcorehttp/_httppolicyclass.h b/indra/llcorehttp/_httppolicyclass.h
new file mode 100755
index 0000000000..d175413cbd
--- /dev/null
+++ b/indra/llcorehttp/_httppolicyclass.h
@@ -0,0 +1,59 @@
+/**
+ * @file _httppolicyclass.h
+ * @brief Declarations for internal class defining policy class options.
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 _LLCORE_HTTP_POLICY_CLASS_H_
+#define _LLCORE_HTTP_POLICY_CLASS_H_
+
+
+#include "httprequest.h"
+
+
+namespace LLCore
+{
+
+class HttpPolicyClass
+{
+public:
+ HttpPolicyClass();
+ ~HttpPolicyClass();
+
+ HttpPolicyClass & operator=(const HttpPolicyClass &);
+ HttpPolicyClass(const HttpPolicyClass &); // Not defined
+
+public:
+ HttpStatus set(HttpRequest::EClassPolicy opt, long value);
+ HttpStatus get(HttpRequest::EClassPolicy opt, long * value);
+
+public:
+ unsigned long mSetMask;
+ long mConnectionLimit;
+ long mPerHostConnectionLimit;
+ long mPipelining;
+}; // end class HttpPolicyClass
+
+} // end namespace LLCore
+
+#endif // _LLCORE_HTTP_POLICY_CLASS_H_
diff --git a/indra/llcorehttp/_httppolicyglobal.cpp b/indra/llcorehttp/_httppolicyglobal.cpp
new file mode 100755
index 0000000000..72f409d3b1
--- /dev/null
+++ b/indra/llcorehttp/_httppolicyglobal.cpp
@@ -0,0 +1,175 @@
+/**
+ * @file _httppolicyglobal.cpp
+ * @brief Definitions for internal class defining global policy option.
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 "_httppolicyglobal.h"
+
+#include "_httpinternal.h"
+
+
+namespace LLCore
+{
+
+
+HttpPolicyGlobal::HttpPolicyGlobal()
+ : mSetMask(0UL),
+ mConnectionLimit(HTTP_CONNECTION_LIMIT_DEFAULT),
+ mTrace(HTTP_TRACE_OFF),
+ mUseLLProxy(0)
+{}
+
+
+HttpPolicyGlobal::~HttpPolicyGlobal()
+{}
+
+
+HttpPolicyGlobal & HttpPolicyGlobal::operator=(const HttpPolicyGlobal & other)
+{
+ if (this != &other)
+ {
+ mSetMask = other.mSetMask;
+ mConnectionLimit = other.mConnectionLimit;
+ mCAPath = other.mCAPath;
+ mCAFile = other.mCAFile;
+ mHttpProxy = other.mHttpProxy;
+ mTrace = other.mTrace;
+ mUseLLProxy = other.mUseLLProxy;
+ }
+ return *this;
+}
+
+
+HttpStatus HttpPolicyGlobal::set(HttpRequest::EGlobalPolicy opt, long value)
+{
+ switch (opt)
+ {
+ case HttpRequest::GP_CONNECTION_LIMIT:
+ mConnectionLimit = llclamp(value, long(HTTP_CONNECTION_LIMIT_MIN), long(HTTP_CONNECTION_LIMIT_MAX));
+ break;
+
+ case HttpRequest::GP_TRACE:
+ mTrace = llclamp(value, long(HTTP_TRACE_MIN), long(HTTP_TRACE_MAX));
+ break;
+
+ case HttpRequest::GP_LLPROXY:
+ mUseLLProxy = llclamp(value, 0L, 1L);
+ break;
+
+ default:
+ return HttpStatus(HttpStatus::LLCORE, HE_INVALID_ARG);
+ }
+
+ mSetMask |= 1UL << int(opt);
+ return HttpStatus();
+}
+
+
+HttpStatus HttpPolicyGlobal::set(HttpRequest::EGlobalPolicy opt, const std::string & value)
+{
+ switch (opt)
+ {
+ case HttpRequest::GP_CA_PATH:
+ mCAPath = value;
+ break;
+
+ case HttpRequest::GP_CA_FILE:
+ mCAFile = value;
+ break;
+
+ case HttpRequest::GP_HTTP_PROXY:
+ mCAFile = value;
+ break;
+
+ default:
+ return HttpStatus(HttpStatus::LLCORE, HE_INVALID_ARG);
+ }
+
+ mSetMask |= 1UL << int(opt);
+ return HttpStatus();
+}
+
+
+HttpStatus HttpPolicyGlobal::get(HttpRequest::EGlobalPolicy opt, long * value)
+{
+ static const HttpStatus not_set(HttpStatus::LLCORE, HE_OPT_NOT_SET);
+ long * src(NULL);
+
+ switch (opt)
+ {
+ case HttpRequest::GP_CONNECTION_LIMIT:
+ src = &mConnectionLimit;
+ break;
+
+ case HttpRequest::GP_TRACE:
+ src = &mTrace;
+ break;
+
+ case HttpRequest::GP_LLPROXY:
+ src = &mUseLLProxy;
+ break;
+
+ default:
+ return HttpStatus(HttpStatus::LLCORE, HE_INVALID_ARG);
+ }
+
+ if (! (mSetMask & (1UL << int(opt))))
+ return not_set;
+
+ *value = *src;
+ return HttpStatus();
+}
+
+
+HttpStatus HttpPolicyGlobal::get(HttpRequest::EGlobalPolicy opt, const std::string ** value)
+{
+ static const HttpStatus not_set(HttpStatus::LLCORE, HE_OPT_NOT_SET);
+ const std::string * src(NULL);
+
+ switch (opt)
+ {
+ case HttpRequest::GP_CA_PATH:
+ src = &mCAPath;
+ break;
+
+ case HttpRequest::GP_CA_FILE:
+ src = &mCAFile;
+ break;
+
+ case HttpRequest::GP_HTTP_PROXY:
+ src = &mHttpProxy;
+ break;
+
+ default:
+ return HttpStatus(HttpStatus::LLCORE, HE_INVALID_ARG);
+ }
+
+ if (! (mSetMask & (1UL << int(opt))))
+ return not_set;
+
+ *value = src;
+ return HttpStatus();
+}
+
+} // end namespace LLCore
diff --git a/indra/llcorehttp/_httppolicyglobal.h b/indra/llcorehttp/_httppolicyglobal.h
new file mode 100755
index 0000000000..a50d0e4188
--- /dev/null
+++ b/indra/llcorehttp/_httppolicyglobal.h
@@ -0,0 +1,66 @@
+/**
+ * @file _httppolicyglobal.h
+ * @brief Declarations for internal class defining global policy option.
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 _LLCORE_HTTP_POLICY_GLOBAL_H_
+#define _LLCORE_HTTP_POLICY_GLOBAL_H_
+
+
+#include "httprequest.h"
+
+
+namespace LLCore
+{
+
+class HttpPolicyGlobal
+{
+public:
+ HttpPolicyGlobal();
+ ~HttpPolicyGlobal();
+
+ HttpPolicyGlobal & operator=(const HttpPolicyGlobal &);
+
+private:
+ HttpPolicyGlobal(const HttpPolicyGlobal &); // Not defined
+
+public:
+ HttpStatus set(HttpRequest::EGlobalPolicy opt, long value);
+ HttpStatus set(HttpRequest::EGlobalPolicy opt, const std::string & value);
+ HttpStatus get(HttpRequest::EGlobalPolicy opt, long * value);
+ HttpStatus get(HttpRequest::EGlobalPolicy opt, const std::string ** value);
+
+public:
+ unsigned long mSetMask;
+ long mConnectionLimit;
+ std::string mCAPath;
+ std::string mCAFile;
+ std::string mHttpProxy;
+ long mTrace;
+ long mUseLLProxy;
+}; // end class HttpPolicyGlobal
+
+} // end namespace LLCore
+
+#endif // _LLCORE_HTTP_POLICY_GLOBAL_H_
diff --git a/indra/llcorehttp/_httpreadyqueue.h b/indra/llcorehttp/_httpreadyqueue.h
new file mode 100755
index 0000000000..5f19a9c5f9
--- /dev/null
+++ b/indra/llcorehttp/_httpreadyqueue.h
@@ -0,0 +1,124 @@
+/**
+ * @file _httpreadyqueue.h
+ * @brief Internal declaration for the operation ready queue
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 _LLCORE_HTTP_READY_QUEUE_H_
+#define _LLCORE_HTTP_READY_QUEUE_H_
+
+
+#include <queue>
+
+#include "_httpinternal.h"
+#include "_httpoprequest.h"
+
+
+namespace LLCore
+{
+
+/// HttpReadyQueue provides a simple priority queue for HttpOpRequest objects.
+///
+/// This uses the priority_queue adaptor class to provide the queue
+/// as well as the ordering scheme while allowing us access to the
+/// raw container if we follow a few simple rules. One of the more
+/// important of those rules is that any iterator becomes invalid
+/// on element erasure. So pay attention.
+///
+/// If LLCORE_HTTP_READY_QUEUE_IGNORES_PRIORITY tests true, the class
+/// implements a std::priority_queue interface but on std::deque
+/// behavior to eliminate sensitivity to priority. In the future,
+/// this will likely become the only behavior or it may become
+/// a run-time election.
+///
+/// Threading: not thread-safe. Expected to be used entirely by
+/// a single thread, typically a worker thread of some sort.
+
+#if LLCORE_HTTP_READY_QUEUE_IGNORES_PRIORITY
+
+typedef std::deque<HttpOpRequest *> HttpReadyQueueBase;
+
+#else
+
+typedef std::priority_queue<HttpOpRequest *,
+ std::deque<HttpOpRequest *>,
+ LLCore::HttpOpRequestCompare> HttpReadyQueueBase;
+
+#endif // LLCORE_HTTP_READY_QUEUE_IGNORES_PRIORITY
+
+class HttpReadyQueue : public HttpReadyQueueBase
+{
+public:
+ HttpReadyQueue()
+ : HttpReadyQueueBase()
+ {}
+
+ ~HttpReadyQueue()
+ {}
+
+protected:
+ HttpReadyQueue(const HttpReadyQueue &); // Not defined
+ void operator=(const HttpReadyQueue &); // Not defined
+
+public:
+
+#if LLCORE_HTTP_READY_QUEUE_IGNORES_PRIORITY
+ // Types and methods needed to make a std::deque look
+ // more like a std::priority_queue, at least for our
+ // purposes.
+ typedef HttpReadyQueueBase container_type;
+
+ const_reference top() const
+ {
+ return front();
+ }
+
+ void pop()
+ {
+ pop_front();
+ }
+
+ void push(const value_type & v)
+ {
+ push_back(v);
+ }
+
+#endif // LLCORE_HTTP_READY_QUEUE_IGNORES_PRIORITY
+
+ const container_type & get_container() const
+ {
+ return *this;
+ }
+
+ container_type & get_container()
+ {
+ return *this;
+ }
+
+}; // end class HttpReadyQueue
+
+
+} // end namespace LLCore
+
+
+#endif // _LLCORE_HTTP_READY_QUEUE_H_
diff --git a/indra/llcorehttp/_httpreplyqueue.cpp b/indra/llcorehttp/_httpreplyqueue.cpp
new file mode 100755
index 0000000000..558b7bdee9
--- /dev/null
+++ b/indra/llcorehttp/_httpreplyqueue.cpp
@@ -0,0 +1,107 @@
+/**
+ * @file _httpreplyqueue.cpp
+ * @brief Internal definitions for the operation reply queue
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 "_httpreplyqueue.h"
+
+
+#include "_mutex.h"
+#include "_thread.h"
+#include "_httpoperation.h"
+
+using namespace LLCoreInt;
+
+
+namespace LLCore
+{
+
+
+HttpReplyQueue::HttpReplyQueue()
+ : RefCounted(true)
+{
+}
+
+
+HttpReplyQueue::~HttpReplyQueue()
+{
+ while (! mQueue.empty())
+ {
+ HttpOperation * op = mQueue.back();
+ mQueue.pop_back();
+ op->release();
+ }
+}
+
+
+void HttpReplyQueue::addOp(HttpOperation * op)
+{
+ {
+ HttpScopedLock lock(mQueueMutex);
+
+ mQueue.push_back(op);
+ }
+ mQueueCV.notify_all();
+}
+
+
+HttpOperation * HttpReplyQueue::fetchOp()
+{
+ HttpOperation * result(NULL);
+
+ {
+ HttpScopedLock lock(mQueueMutex);
+
+ if (mQueue.empty())
+ return NULL;
+
+ result = mQueue.front();
+ mQueue.erase(mQueue.begin());
+ }
+
+ // Caller also acquires the reference count
+ return result;
+}
+
+
+void HttpReplyQueue::fetchAll(OpContainer & ops)
+{
+ // Not valid putting something back on the queue...
+ llassert_always(ops.empty());
+
+ {
+ HttpScopedLock lock(mQueueMutex);
+
+ if (! mQueue.empty())
+ {
+ mQueue.swap(ops);
+ }
+ }
+
+ // Caller also acquires the reference counts on each op.
+ return;
+}
+
+
+} // end namespace LLCore
diff --git a/indra/llcorehttp/_httpreplyqueue.h b/indra/llcorehttp/_httpreplyqueue.h
new file mode 100755
index 0000000000..4220a09a3b
--- /dev/null
+++ b/indra/llcorehttp/_httpreplyqueue.h
@@ -0,0 +1,108 @@
+/**
+ * @file _httpreplyqueue.h
+ * @brief Internal declarations for the operation reply queue.
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 _LLCORE_HTTP_REPLY_QUEUE_H_
+#define _LLCORE_HTTP_REPLY_QUEUE_H_
+
+
+#include "_refcounted.h"
+#include "_mutex.h"
+
+
+namespace LLCore
+{
+
+
+class HttpOperation;
+
+
+/// Almost identical to the HttpRequestQueue class but
+/// whereas that class is a singleton and is known to the
+/// HttpService object, this queue is 1:1 with HttpRequest
+/// instances and isn't explicitly referenced by the
+/// service object. Instead, HttpOperation objects that
+/// want to generate replies back to their creators also
+/// keep references to the corresponding HttpReplyQueue.
+/// The HttpService plumbing then simply delivers replies
+/// to the requested reply queue.
+///
+/// One result of that is that the fetch operations do
+/// not have a wait forever option. The service object
+/// doesn't keep handles on everything it would need to
+/// notify so it can't wake up sleepers should it need to
+/// shutdown. So only non-blocking or timed-blocking modes
+/// are anticipated. These are how most application consumers
+/// will be coded anyway so it shouldn't be too much of a
+/// burden.
+
+class HttpReplyQueue : public LLCoreInt::RefCounted
+{
+public:
+ /// Caller acquires a Refcount on construction
+ HttpReplyQueue();
+
+protected:
+ virtual ~HttpReplyQueue(); // Use release()
+
+private:
+ HttpReplyQueue(const HttpReplyQueue &); // Not defined
+ void operator=(const HttpReplyQueue &); // Not defined
+
+public:
+ typedef std::vector<HttpOperation *> OpContainer;
+
+ /// Insert an object at the back of the reply queue.
+ ///
+ /// Library also takes possession of one reference count to pass
+ /// through the queue.
+ ///
+ /// Threading: callable by any thread.
+ void addOp(HttpOperation * op);
+
+ /// Fetch an operation from the head of the queue. Returns
+ /// NULL if none exists.
+ ///
+ /// Caller acquires reference count on returned operation.
+ ///
+ /// Threading: callable by any thread.
+ HttpOperation * fetchOp();
+
+ /// Caller acquires reference count on each returned operation
+ ///
+ /// Threading: callable by any thread.
+ void fetchAll(OpContainer & ops);
+
+protected:
+ OpContainer mQueue;
+ LLCoreInt::HttpMutex mQueueMutex;
+ LLCoreInt::HttpConditionVariable mQueueCV;
+
+}; // end class HttpReplyQueue
+
+} // end namespace LLCore
+
+
+#endif // _LLCORE_HTTP_REPLY_QUEUE_H_
diff --git a/indra/llcorehttp/_httprequestqueue.cpp b/indra/llcorehttp/_httprequestqueue.cpp
new file mode 100755
index 0000000000..c16966d078
--- /dev/null
+++ b/indra/llcorehttp/_httprequestqueue.cpp
@@ -0,0 +1,161 @@
+/**
+ * @file _httprequestqueue.cpp
+ * @brief
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 "_httprequestqueue.h"
+
+#include "_httpoperation.h"
+#include "_mutex.h"
+
+
+using namespace LLCoreInt;
+
+namespace LLCore
+{
+
+HttpRequestQueue * HttpRequestQueue::sInstance(NULL);
+
+
+HttpRequestQueue::HttpRequestQueue()
+ : RefCounted(true),
+ mQueueStopped(false)
+{
+}
+
+
+HttpRequestQueue::~HttpRequestQueue()
+{
+ while (! mQueue.empty())
+ {
+ HttpOperation * op = mQueue.back();
+ mQueue.pop_back();
+ op->release();
+ }
+}
+
+
+void HttpRequestQueue::init()
+{
+ llassert_always(! sInstance);
+ sInstance = new HttpRequestQueue();
+}
+
+
+void HttpRequestQueue::term()
+{
+ if (sInstance)
+ {
+ sInstance->release();
+ sInstance = NULL;
+ }
+}
+
+
+HttpStatus HttpRequestQueue::addOp(HttpOperation * op)
+{
+ bool wake(false);
+ {
+ HttpScopedLock lock(mQueueMutex);
+
+ if (mQueueStopped)
+ {
+ // Return op and error to caller
+ return HttpStatus(HttpStatus::LLCORE, HE_SHUTTING_DOWN);
+ }
+ wake = mQueue.empty();
+ mQueue.push_back(op);
+ }
+ if (wake)
+ {
+ mQueueCV.notify_all();
+ }
+ return HttpStatus();
+}
+
+
+HttpOperation * HttpRequestQueue::fetchOp(bool wait)
+{
+ HttpOperation * result(NULL);
+
+ {
+ HttpScopedLock lock(mQueueMutex);
+
+ while (mQueue.empty())
+ {
+ if (! wait || mQueueStopped)
+ return NULL;
+ mQueueCV.wait(lock);
+ }
+
+ result = mQueue.front();
+ mQueue.erase(mQueue.begin());
+ }
+
+ // Caller also acquires the reference count
+ return result;
+}
+
+
+void HttpRequestQueue::fetchAll(bool wait, OpContainer & ops)
+{
+ // Not valid putting something back on the queue...
+ llassert_always(ops.empty());
+
+ {
+ HttpScopedLock lock(mQueueMutex);
+
+ while (mQueue.empty())
+ {
+ if (! wait || mQueueStopped)
+ return;
+ mQueueCV.wait(lock);
+ }
+
+ mQueue.swap(ops);
+ }
+
+ // Caller also acquires the reference counts on each op.
+ return;
+}
+
+
+void HttpRequestQueue::wakeAll()
+{
+ mQueueCV.notify_all();
+}
+
+
+void HttpRequestQueue::stopQueue()
+{
+ {
+ HttpScopedLock lock(mQueueMutex);
+
+ mQueueStopped = true;
+ wakeAll();
+ }
+}
+
+
+} // end namespace LLCore
diff --git a/indra/llcorehttp/_httprequestqueue.h b/indra/llcorehttp/_httprequestqueue.h
new file mode 100755
index 0000000000..c9c52b7233
--- /dev/null
+++ b/indra/llcorehttp/_httprequestqueue.h
@@ -0,0 +1,141 @@
+/**
+ * @file _httprequestqueue.h
+ * @brief Internal declaration for the operation request queue
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 _LLCORE_HTTP_REQUEST_QUEUE_H_
+#define _LLCORE_HTTP_REQUEST_QUEUE_H_
+
+
+#include <vector>
+
+#include "httpcommon.h"
+#include "_refcounted.h"
+#include "_mutex.h"
+
+
+namespace LLCore
+{
+
+
+class HttpOperation;
+
+
+/// Thread-safe queue of HttpOperation objects. Just
+/// a simple queue that handles the transfer of operation
+/// requests from all HttpRequest instances into the
+/// singleton HttpService instance.
+
+class HttpRequestQueue : public LLCoreInt::RefCounted
+{
+protected:
+ /// Caller acquires a Refcount on construction
+ HttpRequestQueue();
+
+protected:
+ virtual ~HttpRequestQueue(); // Use release()
+
+private:
+ HttpRequestQueue(const HttpRequestQueue &); // Not defined
+ void operator=(const HttpRequestQueue &); // Not defined
+
+public:
+ static void init();
+ static void term();
+
+ /// Threading: callable by any thread once inited.
+ inline static HttpRequestQueue * instanceOf()
+ {
+ return sInstance;
+ }
+
+public:
+ typedef std::vector<HttpOperation *> OpContainer;
+
+ /// Insert an object at the back of the request queue.
+ ///
+ /// Caller must provide one refcount to the queue which takes
+ /// possession of the count on success.
+ ///
+ /// @return Standard status. On failure, caller
+ /// must dispose of the operation with
+ /// an explicit release() call.
+ ///
+ /// Threading: callable by any thread.
+ HttpStatus addOp(HttpOperation * op);
+
+ /// Return the operation on the front of the queue. If
+ /// the queue is empty and @wait is false, call returns
+ /// immediately and a NULL pointer is returned. If true,
+ /// caller will sleep until explicitly woken. Wakeups
+ /// can be spurious and callers must expect NULL pointers
+ /// even if waiting is indicated.
+ ///
+ /// Caller acquires reference count any returned operation
+ ///
+ /// Threading: callable by any thread.
+ HttpOperation * fetchOp(bool wait);
+
+ /// Return all queued requests to caller. The @ops argument
+ /// should be empty when called and will be swap()'d with
+ /// current contents. Handling of the @wait argument is
+ /// identical to @fetchOp.
+ ///
+ /// Caller acquires reference count on each returned operation
+ ///
+ /// Threading: callable by any thread.
+ void fetchAll(bool wait, OpContainer & ops);
+
+ /// Wake any sleeping threads. Normal queuing operations
+ /// won't require this but it may be necessary for termination
+ /// requests.
+ ///
+ /// Threading: callable by any thread.
+ void wakeAll();
+
+ /// Disallow further request queuing. Callers to @addOp will
+ /// get a failure status (LLCORE, HE_SHUTTING_DOWN). Callers
+ /// to @fetchAll or @fetchOp will get requests that are on the
+ /// queue but the calls will no longer wait. Instead they'll
+ /// return immediately. Also wakes up all sleepers to send
+ /// them on their way.
+ ///
+ /// Threading: callable by any thread.
+ void stopQueue();
+
+protected:
+ static HttpRequestQueue * sInstance;
+
+protected:
+ OpContainer mQueue;
+ LLCoreInt::HttpMutex mQueueMutex;
+ LLCoreInt::HttpConditionVariable mQueueCV;
+ bool mQueueStopped;
+
+}; // end class HttpRequestQueue
+
+} // end namespace LLCore
+
+
+#endif // _LLCORE_HTTP_REQUEST_QUEUE_H_
diff --git a/indra/llcorehttp/_httpretryqueue.h b/indra/llcorehttp/_httpretryqueue.h
new file mode 100755
index 0000000000..745adec09d
--- /dev/null
+++ b/indra/llcorehttp/_httpretryqueue.h
@@ -0,0 +1,94 @@
+/**
+ * @file _httpretryqueue.h
+ * @brief Internal declaration for the operation retry queue
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 _LLCORE_HTTP_RETRY_QUEUE_H_
+#define _LLCORE_HTTP_RETRY_QUEUE_H_
+
+
+#include <queue>
+
+#include "_httpoprequest.h"
+
+
+namespace LLCore
+{
+
+/// HttpRetryQueue provides a simple priority queue for HttpOpRequest objects.
+///
+/// This uses the priority_queue adaptor class to provide the queue
+/// as well as the ordering scheme while allowing us access to the
+/// raw container if we follow a few simple rules. One of the more
+/// important of those rules is that any iterator becomes invalid
+/// on element erasure. So pay attention.
+///
+/// Threading: not thread-safe. Expected to be used entirely by
+/// a single thread, typically a worker thread of some sort.
+
+struct HttpOpRetryCompare
+{
+ bool operator()(const HttpOpRequest * lhs, const HttpOpRequest * rhs)
+ {
+ return lhs->mPolicyRetryAt < rhs->mPolicyRetryAt;
+ }
+};
+
+
+typedef std::priority_queue<HttpOpRequest *,
+ std::deque<HttpOpRequest *>,
+ LLCore::HttpOpRetryCompare> HttpRetryQueueBase;
+
+class HttpRetryQueue : public HttpRetryQueueBase
+{
+public:
+ HttpRetryQueue()
+ : HttpRetryQueueBase()
+ {}
+
+ ~HttpRetryQueue()
+ {}
+
+protected:
+ HttpRetryQueue(const HttpRetryQueue &); // Not defined
+ void operator=(const HttpRetryQueue &); // Not defined
+
+public:
+ const container_type & get_container() const
+ {
+ return c;
+ }
+
+ container_type & get_container()
+ {
+ return c;
+ }
+
+}; // end class HttpRetryQueue
+
+
+} // end namespace LLCore
+
+
+#endif // _LLCORE_HTTP_RETRY_QUEUE_H_
diff --git a/indra/llcorehttp/_httpservice.cpp b/indra/llcorehttp/_httpservice.cpp
new file mode 100755
index 0000000000..0825888d0f
--- /dev/null
+++ b/indra/llcorehttp/_httpservice.cpp
@@ -0,0 +1,348 @@
+/**
+ * @file _httpservice.cpp
+ * @brief Internal definitions of the Http service thread
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 "_httpservice.h"
+
+#include <boost/bind.hpp>
+#include <boost/function.hpp>
+
+#include "_httpoperation.h"
+#include "_httprequestqueue.h"
+#include "_httppolicy.h"
+#include "_httplibcurl.h"
+#include "_thread.h"
+#include "_httpinternal.h"
+
+#include "lltimer.h"
+#include "llthread.h"
+
+
+namespace LLCore
+{
+
+HttpService * HttpService::sInstance(NULL);
+volatile HttpService::EState HttpService::sState(NOT_INITIALIZED);
+
+HttpService::HttpService()
+ : mRequestQueue(NULL),
+ mExitRequested(0U),
+ mThread(NULL),
+ mPolicy(NULL),
+ mTransport(NULL)
+{
+ // Create the default policy class
+ HttpPolicyClass pol_class;
+ pol_class.set(HttpRequest::CP_CONNECTION_LIMIT, HTTP_CONNECTION_LIMIT_DEFAULT);
+ pol_class.set(HttpRequest::CP_PER_HOST_CONNECTION_LIMIT, HTTP_CONNECTION_LIMIT_DEFAULT);
+ pol_class.set(HttpRequest::CP_ENABLE_PIPELINING, 0L);
+ mPolicyClasses.push_back(pol_class);
+}
+
+
+HttpService::~HttpService()
+{
+ mExitRequested = 1U;
+ if (RUNNING == sState)
+ {
+ // Trying to kill the service object with a running thread
+ // is a bit tricky.
+ if (mRequestQueue)
+ {
+ mRequestQueue->stopQueue();
+ }
+
+ if (mThread)
+ {
+ if (! mThread->timedJoin(250))
+ {
+ // Failed to join, expect problems ahead so do a hard termination.
+ mThread->cancel();
+
+ LL_WARNS("CoreHttp") << "Destroying HttpService with running thread. Expect problems."
+ << LL_ENDL;
+ }
+ }
+ }
+
+ if (mRequestQueue)
+ {
+ mRequestQueue->release();
+ mRequestQueue = NULL;
+ }
+
+ delete mTransport;
+ mTransport = NULL;
+
+ delete mPolicy;
+ mPolicy = NULL;
+
+ if (mThread)
+ {
+ mThread->release();
+ mThread = NULL;
+ }
+}
+
+
+void HttpService::init(HttpRequestQueue * queue)
+{
+ llassert_always(! sInstance);
+ llassert_always(NOT_INITIALIZED == sState);
+ sInstance = new HttpService();
+
+ queue->addRef();
+ sInstance->mRequestQueue = queue;
+ sInstance->mPolicy = new HttpPolicy(sInstance);
+ sInstance->mTransport = new HttpLibcurl(sInstance);
+ sState = INITIALIZED;
+}
+
+
+void HttpService::term()
+{
+ if (sInstance)
+ {
+ if (RUNNING == sState && sInstance->mThread)
+ {
+ // Unclean termination. Thread appears to be running. We'll
+ // try to give the worker thread a chance to cancel using the
+ // exit flag...
+ sInstance->mExitRequested = 1U;
+ sInstance->mRequestQueue->stopQueue();
+
+ // And a little sleep
+ for (int i(0); i < 10 && RUNNING == sState; ++i)
+ {
+ ms_sleep(100);
+ }
+ }
+
+ delete sInstance;
+ sInstance = NULL;
+ }
+ sState = NOT_INITIALIZED;
+}
+
+
+HttpRequest::policy_t HttpService::createPolicyClass()
+{
+ const HttpRequest::policy_t policy_class(mPolicyClasses.size());
+ if (policy_class >= HTTP_POLICY_CLASS_LIMIT)
+ {
+ return 0;
+ }
+ mPolicyClasses.push_back(HttpPolicyClass());
+ return policy_class;
+}
+
+
+bool HttpService::isStopped()
+{
+ // What is really wanted here is something like:
+ //
+ // HttpService * service = instanceOf();
+ // return STOPPED == sState && (! service || ! service->mThread || ! service->mThread->joinable());
+ //
+ // But boost::thread is not giving me a consistent story on joinability
+ // of a thread after it returns. Debug and non-debug builds are showing
+ // different behavior on Linux/Etch so we do a weaker test that may
+ // not be globally correct (i.e. thread *is* stopping, may not have
+ // stopped but will very soon):
+
+ return STOPPED == sState;
+}
+
+
+/// Threading: callable by consumer thread *once*.
+void HttpService::startThread()
+{
+ llassert_always(! mThread || STOPPED == sState);
+ llassert_always(INITIALIZED == sState || STOPPED == sState);
+
+ if (mThread)
+ {
+ mThread->release();
+ }
+
+ // Push current policy definitions, enable policy & transport components
+ mPolicy->start(mPolicyGlobal, mPolicyClasses);
+ mTransport->start(mPolicyClasses.size());
+
+ mThread = new LLCoreInt::HttpThread(boost::bind(&HttpService::threadRun, this, _1));
+ sState = RUNNING;
+}
+
+
+/// Threading: callable by worker thread.
+void HttpService::stopRequested()
+{
+ mExitRequested = 1U;
+}
+
+
+/// Threading: callable by worker thread.
+bool HttpService::changePriority(HttpHandle handle, HttpRequest::priority_t priority)
+{
+ bool found(false);
+
+ // Skip the request queue as we currently don't leave earlier
+ // requests sitting there. Start with the ready queue...
+ found = mPolicy->changePriority(handle, priority);
+
+ // If not there, we could try the transport/active queue but priority
+ // doesn't really have much effect there so we don't waste cycles.
+
+ return found;
+}
+
+
+/// Try to find the given request handle on any of the request
+/// queues and cancel the operation.
+///
+/// @return True if the request was canceled.
+///
+/// Threading: callable by worker thread.
+bool HttpService::cancel(HttpHandle handle)
+{
+ bool canceled(false);
+
+ // Request can't be on request queue so skip that.
+
+ // Check the policy component's queues first
+ canceled = mPolicy->cancel(handle);
+
+ if (! canceled)
+ {
+ // If that didn't work, check transport's.
+ canceled = mTransport->cancel(handle);
+ }
+
+ return canceled;
+}
+
+
+/// Threading: callable by worker thread.
+void HttpService::shutdown()
+{
+ // Disallow future enqueue of requests
+ mRequestQueue->stopQueue();
+
+ // Cancel requests already on the request queue
+ HttpRequestQueue::OpContainer ops;
+ mRequestQueue->fetchAll(false, ops);
+ while (! ops.empty())
+ {
+ HttpOperation * op(ops.front());
+ ops.erase(ops.begin());
+
+ op->cancel();
+ op->release();
+ }
+
+ // Shutdown transport canceling requests, freeing resources
+ mTransport->shutdown();
+
+ // And now policy
+ mPolicy->shutdown();
+}
+
+
+// Working thread loop-forever method. Gives time to
+// each of the request queue, policy layer and transport
+// layer pieces and then either sleeps for a small time
+// or waits for a request to come in. Repeats until
+// requested to stop.
+void HttpService::threadRun(LLCoreInt::HttpThread * thread)
+{
+ boost::this_thread::disable_interruption di;
+
+ LLThread::registerThreadID();
+
+ ELoopSpeed loop(REQUEST_SLEEP);
+ while (! mExitRequested)
+ {
+ loop = processRequestQueue(loop);
+
+ // Process ready queue issuing new requests as needed
+ ELoopSpeed new_loop = mPolicy->processReadyQueue();
+ loop = (std::min)(loop, new_loop);
+
+ // Give libcurl some cycles
+ new_loop = mTransport->processTransport();
+ loop = (std::min)(loop, new_loop);
+
+ // Determine whether to spin, sleep briefly or sleep for next request
+ if (REQUEST_SLEEP != loop)
+ {
+ ms_sleep(HTTP_SERVICE_LOOP_SLEEP_NORMAL_MS);
+ }
+ }
+
+ shutdown();
+ sState = STOPPED;
+}
+
+
+HttpService::ELoopSpeed HttpService::processRequestQueue(ELoopSpeed loop)
+{
+ HttpRequestQueue::OpContainer ops;
+ const bool wait_for_req(REQUEST_SLEEP == loop);
+
+ mRequestQueue->fetchAll(wait_for_req, ops);
+ while (! ops.empty())
+ {
+ HttpOperation * op(ops.front());
+ ops.erase(ops.begin());
+
+ // Process operation
+ if (! mExitRequested)
+ {
+ // Setup for subsequent tracing
+ long tracing(HTTP_TRACE_OFF);
+ mPolicy->getGlobalOptions().get(HttpRequest::GP_TRACE, &tracing);
+ op->mTracing = (std::max)(op->mTracing, int(tracing));
+
+ if (op->mTracing > HTTP_TRACE_OFF)
+ {
+ LL_INFOS("CoreHttp") << "TRACE, FromRequestQueue, Handle: "
+ << static_cast<HttpHandle>(op)
+ << LL_ENDL;
+ }
+
+ // Stage
+ op->stageFromRequest(this);
+ }
+
+ // Done with operation
+ op->release();
+ }
+
+ // Queue emptied, allow polling loop to sleep
+ return REQUEST_SLEEP;
+}
+
+
+} // end namespace LLCore
diff --git a/indra/llcorehttp/_httpservice.h b/indra/llcorehttp/_httpservice.h
new file mode 100755
index 0000000000..ffe0349d4d
--- /dev/null
+++ b/indra/llcorehttp/_httpservice.h
@@ -0,0 +1,224 @@
+/**
+ * @file _httpservice.h
+ * @brief Declarations for internal class providing HTTP service.
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 _LLCORE_HTTP_SERVICE_H_
+#define _LLCORE_HTTP_SERVICE_H_
+
+
+#include <vector>
+
+#include "linden_common.h"
+#include "llapr.h"
+#include "httpcommon.h"
+#include "httprequest.h"
+#include "_httppolicyglobal.h"
+#include "_httppolicyclass.h"
+
+
+namespace LLCoreInt
+{
+
+class HttpThread;
+
+}
+
+
+namespace LLCore
+{
+
+
+class HttpRequestQueue;
+class HttpPolicy;
+class HttpLibcurl;
+
+
+/// The HttpService class does the work behind the request queue. It
+/// oversees the HTTP workflow carrying out a number of tasks:
+/// - Pulling requests from the global request queue
+/// - Executing 'immediate' requests directly
+/// - Prioritizing and re-queuing on internal queues the slower requests
+/// - Providing cpu cycles to the libcurl plumbing
+/// - Overseeing retry operations
+///
+/// Note that the service object doesn't have a pointer to any
+/// reply queue. These are kept by HttpRequest and HttpOperation
+/// only.
+///
+/// Service, Policy and Transport
+///
+/// HttpService could have been a monolithic class combining a request
+/// queue servicer, request policy manager and network transport.
+/// Instead, to prevent monolithic growth and allow for easier
+/// replacement, it was developed as three separate classes: HttpService,
+/// HttpPolicy and HttpLibcurl (transport). These always exist in a
+/// 1:1:1 relationship with HttpService managing instances of the other
+/// two. So, these classes do not use reference counting to refer
+/// to one another, their lifecycles are always managed together.
+
+class HttpService
+{
+protected:
+ HttpService();
+ virtual ~HttpService();
+
+private:
+ HttpService(const HttpService &); // Not defined
+ void operator=(const HttpService &); // Not defined
+
+public:
+ enum EState
+ {
+ NOT_INITIALIZED = -1,
+ INITIALIZED, ///< init() has been called
+ RUNNING, ///< thread created and running
+ STOPPED ///< thread has committed to exiting
+ };
+
+ // Ordered enumeration of idling strategies available to
+ // threadRun's loop. Ordered so that std::min on values
+ // produces the most conservative result of multiple
+ // requests.
+ enum ELoopSpeed
+ {
+ NORMAL, ///< continuous polling of request, ready, active queues
+ REQUEST_SLEEP ///< can sleep indefinitely waiting for request queue write
+ };
+
+ static void init(HttpRequestQueue *);
+ static void term();
+
+ /// Threading: callable by any thread once inited.
+ inline static HttpService * instanceOf()
+ {
+ return sInstance;
+ }
+
+ /// Return the state of the worker thread. Note that the
+ /// transition from RUNNING to STOPPED is performed by the
+ /// worker thread itself. This has two weaknesses:
+ /// - race where the thread hasn't really stopped but will
+ /// - data ordering between threads where a non-worker thread
+ /// may see a stale RUNNING status.
+ ///
+ /// This transition is generally of interest only to unit tests
+ /// and these weaknesses shouldn't be any real burden.
+ ///
+ /// Threading: callable by any thread with above exceptions.
+ static EState getState()
+ {
+ return sState;
+ }
+
+ /// Threading: callable by any thread but uses @see getState() and
+ /// acquires its weaknesses.
+ static bool isStopped();
+
+ /// Threading: callable by consumer thread *once*.
+ void startThread();
+
+ /// Threading: callable by worker thread.
+ void stopRequested();
+
+ /// Threading: callable by worker thread.
+ void shutdown();
+
+ /// Try to find the given request handle on any of the request
+ /// queues and reset the priority (and queue position) of the
+ /// request if found.
+ ///
+ /// @return True if the request was found somewhere.
+ ///
+ /// Threading: callable by worker thread.
+ bool changePriority(HttpHandle handle, HttpRequest::priority_t priority);
+
+ /// Try to find the given request handle on any of the request
+ /// queues and cancel the operation.
+ ///
+ /// @return True if the request was found and canceled.
+ ///
+ /// Threading: callable by worker thread.
+ bool cancel(HttpHandle handle);
+
+ /// Threading: callable by worker thread.
+ HttpPolicy & getPolicy()
+ {
+ return *mPolicy;
+ }
+
+ /// Threading: callable by worker thread.
+ HttpLibcurl & getTransport()
+ {
+ return *mTransport;
+ }
+
+ /// Threading: callable by worker thread.
+ HttpRequestQueue & getRequestQueue()
+ {
+ return *mRequestQueue;
+ }
+
+ /// Threading: callable by consumer thread.
+ HttpPolicyGlobal & getGlobalOptions()
+ {
+ return mPolicyGlobal;
+ }
+
+ /// Threading: callable by consumer thread.
+ HttpRequest::policy_t createPolicyClass();
+
+ /// Threading: callable by consumer thread.
+ HttpPolicyClass & getClassOptions(HttpRequest::policy_t policy_class)
+ {
+ llassert(policy_class >= 0 && policy_class < mPolicyClasses.size());
+ return mPolicyClasses[policy_class];
+ }
+
+protected:
+ void threadRun(LLCoreInt::HttpThread * thread);
+
+ ELoopSpeed processRequestQueue(ELoopSpeed loop);
+
+protected:
+ static HttpService * sInstance;
+
+ // === shared data ===
+ static volatile EState sState;
+ HttpRequestQueue * mRequestQueue; // Refcounted
+ LLAtomicU32 mExitRequested;
+ LLCoreInt::HttpThread * mThread;
+
+ // === consumer-thread-only data ===
+ HttpPolicyGlobal mPolicyGlobal;
+ std::vector<HttpPolicyClass> mPolicyClasses;
+
+ // === working-thread-only data ===
+ HttpPolicy * mPolicy; // Simple pointer, has ownership
+ HttpLibcurl * mTransport; // Simple pointer, has ownership
+}; // end class HttpService
+
+} // end namespace LLCore
+
+#endif // _LLCORE_HTTP_SERVICE_H_
diff --git a/indra/llcorehttp/_mutex.h b/indra/llcorehttp/_mutex.h
new file mode 100755
index 0000000000..4be4d016d4
--- /dev/null
+++ b/indra/llcorehttp/_mutex.h
@@ -0,0 +1,55 @@
+/**
+ * @file _mutex.hpp
+ * @brief mutex type abstraction
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 LLCOREINT_MUTEX_H_
+#define LLCOREINT_MUTEX_H_
+
+
+#include <boost/thread.hpp>
+
+
+namespace LLCoreInt
+{
+
+// MUTEX TYPES
+
+// unique mutex type
+typedef boost::mutex HttpMutex;
+
+// CONDITION VARIABLES
+
+// standard condition variable
+typedef boost::condition_variable HttpConditionVariable;
+
+// LOCKS AND FENCES
+
+// scoped unique lock
+typedef boost::unique_lock<HttpMutex> HttpScopedLock;
+
+}
+
+#endif // LLCOREINT_MUTEX_H
+
diff --git a/indra/llcorehttp/_refcounted.cpp b/indra/llcorehttp/_refcounted.cpp
new file mode 100755
index 0000000000..e7d0b72741
--- /dev/null
+++ b/indra/llcorehttp/_refcounted.cpp
@@ -0,0 +1,45 @@
+/**
+ * @file _refcounted.cpp
+ * @brief Atomic, thread-safe ref counting and destruction mixin class
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 "_refcounted.h"
+
+
+namespace LLCoreInt
+{
+
+#if ! LL_WINDOWS
+
+const S32 RefCounted::NOT_REF_COUNTED;
+
+#endif // ! LL_WINDOWS
+
+RefCounted::~RefCounted()
+{}
+
+
+} // end namespace LLCoreInt
+
+
diff --git a/indra/llcorehttp/_refcounted.h b/indra/llcorehttp/_refcounted.h
new file mode 100755
index 0000000000..21a916b13b
--- /dev/null
+++ b/indra/llcorehttp/_refcounted.h
@@ -0,0 +1,126 @@
+/**
+ * @file _refcounted.h
+ * @brief Atomic, thread-safe ref counting and destruction mixin class
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 LLCOREINT__REFCOUNTED_H_
+#define LLCOREINT__REFCOUNTED_H_
+
+
+#include "linden_common.h"
+
+#include "fix_macros.h"
+#include <boost/thread.hpp>
+
+#include "llapr.h"
+
+
+namespace LLCoreInt
+{
+
+
+class RefCounted
+{
+private:
+ RefCounted(); // Not defined - may not be default constructed
+ void operator=(const RefCounted &); // Not defined
+
+public:
+ explicit RefCounted(bool const implicit)
+ : mRefCount(implicit)
+ {}
+
+ // ref-count interface
+ void addRef() const;
+ void release() const;
+ bool isLastRef() const;
+ S32 getRefCount() const;
+ void noRef() const;
+
+ static const S32 NOT_REF_COUNTED = -1;
+
+protected:
+ virtual ~RefCounted();
+ virtual void destroySelf();
+
+private:
+ mutable LLAtomicS32 mRefCount;
+
+}; // end class RefCounted
+
+
+inline void RefCounted::addRef() const
+{
+ S32 count(mRefCount++);
+ llassert_always(count >= 0);
+}
+
+
+inline void RefCounted::release() const
+{
+ S32 count(mRefCount);
+ llassert_always(count != NOT_REF_COUNTED);
+ llassert_always(count > 0);
+ count = mRefCount--;
+
+ // clean ourselves up if that was the last reference
+ if (0 == count)
+ {
+ const_cast<RefCounted *>(this)->destroySelf();
+ }
+}
+
+
+inline bool RefCounted::isLastRef() const
+{
+ const S32 count(mRefCount);
+ llassert_always(count != NOT_REF_COUNTED);
+ llassert_always(count >= 1);
+ return (1 == count);
+}
+
+
+inline S32 RefCounted::getRefCount() const
+{
+ const S32 result(mRefCount);
+ return result;
+}
+
+
+inline void RefCounted::noRef() const
+{
+ llassert_always(mRefCount <= 1);
+ mRefCount = NOT_REF_COUNTED;
+}
+
+
+inline void RefCounted::destroySelf()
+{
+ delete this;
+}
+
+} // end namespace LLCoreInt
+
+#endif // LLCOREINT__REFCOUNTED_H_
+
diff --git a/indra/llcorehttp/_thread.h b/indra/llcorehttp/_thread.h
new file mode 100755
index 0000000000..e058d660e5
--- /dev/null
+++ b/indra/llcorehttp/_thread.h
@@ -0,0 +1,123 @@
+/**
+ * @file _thread.h
+ * @brief thread type abstraction
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 LLCOREINT_THREAD_H_
+#define LLCOREINT_THREAD_H_
+
+#include "linden_common.h"
+
+#include <boost/thread.hpp>
+#include <boost/function.hpp>
+#include <boost/date_time/posix_time/posix_time_types.hpp>
+
+#include "_refcounted.h"
+
+namespace LLCoreInt
+{
+
+class HttpThread : public RefCounted
+{
+private:
+ HttpThread(); // Not defined
+ void operator=(const HttpThread &); // Not defined
+
+ void at_exit()
+ {
+ // the thread function has exited so we need to release our reference
+ // to ourself so that we will be automagically cleaned up.
+ release();
+ }
+
+ void run()
+ { // THREAD CONTEXT
+
+ // Take out additional reference for the at_exit handler
+ addRef();
+ boost::this_thread::at_thread_exit(boost::bind(&HttpThread::at_exit, this));
+
+ // run the thread function
+ mThreadFunc(this);
+
+ } // THREAD CONTEXT
+
+protected:
+ virtual ~HttpThread()
+ {
+ delete mThread;
+ }
+
+public:
+ /// Constructs a thread object for concurrent execution but does
+ /// not start running. Caller receives on refcount on the thread
+ /// instance. If the thread is started, another will be taken
+ /// out for the exit handler.
+ explicit HttpThread(boost::function<void (HttpThread *)> threadFunc)
+ : RefCounted(true), // implicit reference
+ mThreadFunc(threadFunc)
+ {
+ // this creates a boost thread that will call HttpThread::run on this instance
+ // and pass it the threadfunc callable...
+ boost::function<void()> f = boost::bind(&HttpThread::run, this);
+
+ mThread = new boost::thread(f);
+ }
+
+ inline void join()
+ {
+ mThread->join();
+ }
+
+ inline bool timedJoin(S32 millis)
+ {
+ return mThread->timed_join(boost::posix_time::milliseconds(millis));
+ }
+
+ inline bool joinable() const
+ {
+ return mThread->joinable();
+ }
+
+ // A very hostile method to force a thread to quit
+ inline void cancel()
+ {
+ boost::thread::native_handle_type thread(mThread->native_handle());
+#if LL_WINDOWS
+ TerminateThread(thread, 0);
+#else
+ pthread_cancel(thread);
+#endif
+ }
+
+private:
+ boost::function<void(HttpThread *)> mThreadFunc;
+ boost::thread * mThread;
+}; // end class HttpThread
+
+} // end namespace LLCoreInt
+
+#endif // LLCOREINT_THREAD_H_
+
+
diff --git a/indra/llcorehttp/bufferarray.cpp b/indra/llcorehttp/bufferarray.cpp
new file mode 100755
index 0000000000..8eaaeed710
--- /dev/null
+++ b/indra/llcorehttp/bufferarray.cpp
@@ -0,0 +1,352 @@
+/**
+ * @file bufferarray.cpp
+ * @brief Implements the BufferArray scatter/gather buffer
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 "bufferarray.h"
+
+
+// BufferArray is a list of chunks, each a BufferArray::Block, of contiguous
+// data presented as a single array. Chunks are at least BufferArray::BLOCK_ALLOC_SIZE
+// in length and can be larger. Any chunk may be partially filled or even
+// empty.
+//
+// The BufferArray itself is sharable as a RefCounted entity. As shared
+// reads don't work with the concept of a current position/seek value,
+// none is kept with the object. Instead, the read and write operations
+// all take position arguments. Single write/shared read isn't supported
+// directly and any such attempts have to be serialized outside of this
+// implementation.
+
+namespace LLCore
+{
+
+
+// ==================================
+// BufferArray::Block Declaration
+// ==================================
+
+class BufferArray::Block
+{
+public:
+ ~Block();
+
+ void operator delete(void *);
+ void operator delete(void *, size_t len);
+
+protected:
+ Block(size_t len);
+
+ Block(const Block &); // Not defined
+ void operator=(const Block &); // Not defined
+
+ // Allocate the block with the additional space for the
+ // buffered data at the end of the object.
+ void * operator new(size_t len, size_t addl_len);
+
+public:
+ // Only public entry to get a block.
+ static Block * alloc(size_t len);
+
+public:
+ size_t mUsed;
+ size_t mAlloced;
+
+ // *NOTE: Must be last member of the object. We'll
+ // overallocate as requested via operator new and index
+ // into the array at will.
+ char mData[1];
+};
+
+
+// ==================================
+// BufferArray Definitions
+// ==================================
+
+
+#if ! LL_WINDOWS
+const size_t BufferArray::BLOCK_ALLOC_SIZE;
+#endif // ! LL_WINDOWS
+
+BufferArray::BufferArray()
+ : LLCoreInt::RefCounted(true),
+ mLen(0)
+{}
+
+
+BufferArray::~BufferArray()
+{
+ for (container_t::iterator it(mBlocks.begin());
+ it != mBlocks.end();
+ ++it)
+ {
+ delete *it;
+ *it = NULL;
+ }
+ mBlocks.clear();
+}
+
+
+size_t BufferArray::append(const void * src, size_t len)
+{
+ const size_t ret(len);
+ const char * c_src(static_cast<const char *>(src));
+
+ // First, try to copy into the last block
+ if (len && ! mBlocks.empty())
+ {
+ Block & last(*mBlocks.back());
+ if (last.mUsed < last.mAlloced)
+ {
+ // Some will fit...
+ const size_t copy_len((std::min)(len, (last.mAlloced - last.mUsed)));
+
+ memcpy(&last.mData[last.mUsed], c_src, copy_len);
+ last.mUsed += copy_len;
+ llassert_always(last.mUsed <= last.mAlloced);
+ mLen += copy_len;
+ c_src += copy_len;
+ len -= copy_len;
+ }
+ }
+
+ // Then get new blocks as needed
+ while (len)
+ {
+ const size_t copy_len((std::min)(len, BLOCK_ALLOC_SIZE));
+
+ if (mBlocks.size() >= mBlocks.capacity())
+ {
+ mBlocks.reserve(mBlocks.size() + 5);
+ }
+ Block * block = Block::alloc(BLOCK_ALLOC_SIZE);
+ memcpy(block->mData, c_src, copy_len);
+ block->mUsed = copy_len;
+ llassert_always(block->mUsed <= block->mAlloced);
+ mBlocks.push_back(block);
+ mLen += copy_len;
+ c_src += copy_len;
+ len -= copy_len;
+ }
+ return ret;
+}
+
+
+void * BufferArray::appendBufferAlloc(size_t len)
+{
+ // If someone asks for zero-length, we give them a valid pointer.
+ if (mBlocks.size() >= mBlocks.capacity())
+ {
+ mBlocks.reserve(mBlocks.size() + 5);
+ }
+ Block * block = Block::alloc((std::max)(BLOCK_ALLOC_SIZE, len));
+ block->mUsed = len;
+ mBlocks.push_back(block);
+ mLen += len;
+ return block->mData;
+}
+
+
+size_t BufferArray::read(size_t pos, void * dst, size_t len)
+{
+ char * c_dst(static_cast<char *>(dst));
+
+ if (pos >= mLen)
+ return 0;
+ size_t len_limit(mLen - pos);
+ len = (std::min)(len, len_limit);
+ if (0 == len)
+ return 0;
+
+ size_t result(0), offset(0);
+ const int block_limit(mBlocks.size());
+ int block_start(findBlock(pos, &offset));
+ if (block_start < 0)
+ return 0;
+
+ do
+ {
+ Block & block(*mBlocks[block_start]);
+ size_t block_limit(block.mUsed - offset);
+ size_t block_len((std::min)(block_limit, len));
+
+ memcpy(c_dst, &block.mData[offset], block_len);
+ result += block_len;
+ len -= block_len;
+ c_dst += block_len;
+ offset = 0;
+ ++block_start;
+ }
+ while (len && block_start < block_limit);
+
+ return result;
+}
+
+
+size_t BufferArray::write(size_t pos, const void * src, size_t len)
+{
+ const char * c_src(static_cast<const char *>(src));
+
+ if (pos > mLen || 0 == len)
+ return 0;
+
+ size_t result(0), offset(0);
+ const int block_limit(mBlocks.size());
+ int block_start(findBlock(pos, &offset));
+
+ if (block_start >= 0)
+ {
+ // Some or all of the write will be on top of
+ // existing data.
+ do
+ {
+ Block & block(*mBlocks[block_start]);
+ size_t block_limit(block.mUsed - offset);
+ size_t block_len((std::min)(block_limit, len));
+
+ memcpy(&block.mData[offset], c_src, block_len);
+ result += block_len;
+ c_src += block_len;
+ len -= block_len;
+ offset = 0;
+ ++block_start;
+ }
+ while (len && block_start < block_limit);
+ }
+
+ // Something left, see if it will fit in the free
+ // space of the last block.
+ if (len && ! mBlocks.empty())
+ {
+ Block & last(*mBlocks.back());
+ if (last.mUsed < last.mAlloced)
+ {
+ // Some will fit...
+ const size_t copy_len((std::min)(len, (last.mAlloced - last.mUsed)));
+
+ memcpy(&last.mData[last.mUsed], c_src, copy_len);
+ last.mUsed += copy_len;
+ result += copy_len;
+ llassert_always(last.mUsed <= last.mAlloced);
+ mLen += copy_len;
+ c_src += copy_len;
+ len -= copy_len;
+ }
+ }
+
+ if (len)
+ {
+ // Some or all of the remaining write data will
+ // be an append.
+ result += append(c_src, len);
+ }
+
+ return result;
+}
+
+
+int BufferArray::findBlock(size_t pos, size_t * ret_offset)
+{
+ *ret_offset = 0;
+ if (pos >= mLen)
+ return -1; // Doesn't exist
+
+ const int block_limit(mBlocks.size());
+ for (int i(0); i < block_limit; ++i)
+ {
+ if (pos < mBlocks[i]->mUsed)
+ {
+ *ret_offset = pos;
+ return i;
+ }
+ pos -= mBlocks[i]->mUsed;
+ }
+
+ // Shouldn't get here but...
+ return -1;
+}
+
+
+bool BufferArray::getBlockStartEnd(int block, const char ** start, const char ** end)
+{
+ if (block < 0 || block >= mBlocks.size())
+ {
+ return false;
+ }
+
+ const Block & b(*mBlocks[block]);
+ *start = &b.mData[0];
+ *end = &b.mData[b.mUsed];
+ return true;
+}
+
+
+// ==================================
+// BufferArray::Block Definitions
+// ==================================
+
+
+BufferArray::Block::Block(size_t len)
+ : mUsed(0),
+ mAlloced(len)
+{
+ memset(mData, 0, len);
+}
+
+
+BufferArray::Block::~Block()
+{
+ mUsed = 0;
+ mAlloced = 0;
+}
+
+
+void * BufferArray::Block::operator new(size_t len, size_t addl_len)
+{
+ void * mem = new char[len + addl_len + sizeof(void *)];
+ return mem;
+}
+
+
+void BufferArray::Block::operator delete(void * mem)
+{
+ char * cmem = static_cast<char *>(mem);
+ delete [] cmem;
+}
+
+
+void BufferArray::Block::operator delete(void * mem, size_t)
+{
+ operator delete(mem);
+}
+
+
+BufferArray::Block * BufferArray::Block::alloc(size_t len)
+{
+ Block * block = new (len) Block(len);
+ return block;
+}
+
+
+} // end namespace LLCore
diff --git a/indra/llcorehttp/bufferarray.h b/indra/llcorehttp/bufferarray.h
new file mode 100755
index 0000000000..1094a435b4
--- /dev/null
+++ b/indra/llcorehttp/bufferarray.h
@@ -0,0 +1,137 @@
+/**
+ * @file bufferarray.h
+ * @brief Public-facing declaration for the BufferArray scatter/gather class
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 _LLCORE_BUFFER_ARRAY_H_
+#define _LLCORE_BUFFER_ARRAY_H_
+
+
+#include <cstdlib>
+#include <vector>
+
+#include "_refcounted.h"
+
+
+namespace LLCore
+{
+
+class BufferArrayStreamBuf;
+
+/// A very simple scatter/gather type map for bulk data. The motivation
+/// for this class is the writedata callback used by libcurl. Response
+/// bodies are delivered to the caller in a sequence of sequential write
+/// operations and this class captures them without having to reallocate
+/// and move data.
+///
+/// The interface looks a little like a unix file descriptor but only
+/// just. There is a notion of a current position, starting from 0,
+/// which is used as the position in the data when performing read and
+/// write operations. The position also moves after various operations:
+/// - seek(...)
+/// - read(...)
+/// - write(...)
+/// - append(...)
+/// - appendBufferAlloc(...)
+/// The object also keeps a total length value which is updated after
+/// write and append operations and beyond which the current position
+/// cannot be set.
+///
+/// Threading: not thread-safe
+///
+/// Allocation: Refcounted, heap only. Caller of the constructor
+/// is given a single refcount.
+///
+class BufferArray : public LLCoreInt::RefCounted
+{
+public:
+ // BufferArrayStreamBuf has intimate knowledge of this
+ // implementation to implement a buffer-free adapter.
+ // Changes here will likely need to be reflected there.
+ friend class BufferArrayStreamBuf;
+
+ BufferArray();
+
+protected:
+ virtual ~BufferArray(); // Use release()
+
+private:
+ BufferArray(const BufferArray &); // Not defined
+ void operator=(const BufferArray &); // Not defined
+
+public:
+ // Internal magic number, may be used by unit tests.
+ static const size_t BLOCK_ALLOC_SIZE = 65540;
+
+ /// Appends the indicated data to the BufferArray
+ /// modifying current position and total size. New
+ /// position is one beyond the final byte of the buffer.
+ ///
+ /// @return Count of bytes copied to BufferArray
+ size_t append(const void * src, size_t len);
+
+ /// Similar to @see append(), this call guarantees a
+ /// contiguous block of memory of requested size placed
+ /// at the current end of the BufferArray. On return,
+ /// the data in the memory is considered valid whether
+ /// the caller writes to it or not.
+ ///
+ /// @return Pointer to contiguous region at end
+ /// of BufferArray of 'len' size.
+ void * appendBufferAlloc(size_t len);
+
+ /// Current count of bytes in BufferArray instance.
+ size_t size() const
+ {
+ return mLen;
+ }
+
+ /// Copies data from the given position in the instance
+ /// to the caller's buffer. Will return a short count of
+ /// bytes copied if the 'len' extends beyond the data.
+ size_t read(size_t pos, void * dst, size_t len);
+
+ /// Copies data from the caller's buffer to the instance
+ /// at the current position. May overwrite existing data,
+ /// append data when current position is equal to the
+ /// size of the instance or do a mix of both.
+ size_t write(size_t pos, const void * src, size_t len);
+
+protected:
+ int findBlock(size_t pos, size_t * ret_offset);
+
+ bool getBlockStartEnd(int block, const char ** start, const char ** end);
+
+protected:
+ class Block;
+ typedef std::vector<Block *> container_t;
+
+ container_t mBlocks;
+ size_t mLen;
+}; // end class BufferArray
+
+
+} // end namespace LLCore
+
+#endif // _LLCORE_BUFFER_ARRAY_H_
diff --git a/indra/llcorehttp/bufferstream.cpp b/indra/llcorehttp/bufferstream.cpp
new file mode 100755
index 0000000000..6553900eef
--- /dev/null
+++ b/indra/llcorehttp/bufferstream.cpp
@@ -0,0 +1,285 @@
+/**
+ * @file bufferstream.cpp
+ * @brief Implements the BufferStream adapter class
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 "bufferstream.h"
+
+#include "bufferarray.h"
+
+
+namespace LLCore
+{
+
+BufferArrayStreamBuf::BufferArrayStreamBuf(BufferArray * array)
+ : mBufferArray(array),
+ mReadCurPos(0),
+ mReadCurBlock(-1),
+ mReadBegin(NULL),
+ mReadCur(NULL),
+ mReadEnd(NULL),
+ mWriteCurPos(0)
+{
+ if (array)
+ {
+ array->addRef();
+ mWriteCurPos = array->mLen;
+ }
+}
+
+
+BufferArrayStreamBuf::~BufferArrayStreamBuf()
+{
+ if (mBufferArray)
+ {
+ mBufferArray->release();
+ mBufferArray = NULL;
+ }
+}
+
+
+BufferArrayStreamBuf::int_type BufferArrayStreamBuf::underflow()
+{
+ if (! mBufferArray)
+ {
+ return traits_type::eof();
+ }
+
+ if (mReadCur == mReadEnd)
+ {
+ // Find the next block with actual data or leave
+ // mCurBlock/mCur/mEnd unchanged if we're at the end
+ // of any block chain.
+ const char * new_begin(NULL), * new_end(NULL);
+ int new_cur_block(mReadCurBlock + 1);
+
+ while (mBufferArray->getBlockStartEnd(new_cur_block, &new_begin, &new_end))
+ {
+ if (new_begin != new_end)
+ {
+ break;
+ }
+ ++new_cur_block;
+ }
+ if (new_begin == new_end)
+ {
+ return traits_type::eof();
+ }
+
+ mReadCurBlock = new_cur_block;
+ mReadBegin = mReadCur = new_begin;
+ mReadEnd = new_end;
+ }
+
+ return traits_type::to_int_type(*mReadCur);
+}
+
+
+BufferArrayStreamBuf::int_type BufferArrayStreamBuf::uflow()
+{
+ const int_type ret(underflow());
+
+ if (traits_type::eof() != ret)
+ {
+ ++mReadCur;
+ ++mReadCurPos;
+ }
+ return ret;
+}
+
+
+BufferArrayStreamBuf::int_type BufferArrayStreamBuf::pbackfail(int_type ch)
+{
+ if (! mBufferArray)
+ {
+ return traits_type::eof();
+ }
+
+ if (mReadCur == mReadBegin)
+ {
+ // Find the previous block with actual data or leave
+ // mCurBlock/mBegin/mCur/mEnd unchanged if we're at the
+ // beginning of any block chain.
+ const char * new_begin(NULL), * new_end(NULL);
+ int new_cur_block(mReadCurBlock - 1);
+
+ while (mBufferArray->getBlockStartEnd(new_cur_block, &new_begin, &new_end))
+ {
+ if (new_begin != new_end)
+ {
+ break;
+ }
+ --new_cur_block;
+ }
+ if (new_begin == new_end)
+ {
+ return traits_type::eof();
+ }
+
+ mReadCurBlock = new_cur_block;
+ mReadBegin = new_begin;
+ mReadEnd = mReadCur = new_end;
+ }
+
+ if (traits_type::eof() != ch && mReadCur[-1] != ch)
+ {
+ return traits_type::eof();
+ }
+ --mReadCurPos;
+ return traits_type::to_int_type(*--mReadCur);
+}
+
+
+std::streamsize BufferArrayStreamBuf::showmanyc()
+{
+ if (! mBufferArray)
+ {
+ return -1;
+ }
+ return mBufferArray->mLen - mReadCurPos;
+}
+
+
+BufferArrayStreamBuf::int_type BufferArrayStreamBuf::overflow(int c)
+{
+ if (! mBufferArray || mWriteCurPos > mBufferArray->mLen)
+ {
+ return traits_type::eof();
+ }
+ const size_t wrote(mBufferArray->write(mWriteCurPos, &c, 1));
+ mWriteCurPos += wrote;
+ return wrote ? c : traits_type::eof();
+}
+
+
+std::streamsize BufferArrayStreamBuf::xsputn(const char * src, std::streamsize count)
+{
+ if (! mBufferArray || mWriteCurPos > mBufferArray->mLen)
+ {
+ return 0;
+ }
+ const size_t wrote(mBufferArray->write(mWriteCurPos, src, count));
+ mWriteCurPos += wrote;
+ return wrote;
+}
+
+
+std::streampos BufferArrayStreamBuf::seekoff(std::streamoff off,
+ std::ios_base::seekdir way,
+ std::ios_base::openmode which)
+{
+ std::streampos ret(-1);
+
+ if (! mBufferArray)
+ {
+ return ret;
+ }
+
+ if (std::ios_base::in == which)
+ {
+ size_t pos(0);
+
+ switch (way)
+ {
+ case std::ios_base::beg:
+ pos = off;
+ break;
+
+ case std::ios_base::cur:
+ pos = mReadCurPos += off;
+ break;
+
+ case std::ios_base::end:
+ pos = mBufferArray->mLen - off;
+ break;
+
+ default:
+ return ret;
+ }
+
+ if (pos >= mBufferArray->size())
+ {
+ pos = (std::max)(size_t(0), mBufferArray->size() - 1);
+ }
+ size_t ba_offset(0);
+ int block(mBufferArray->findBlock(pos, &ba_offset));
+ if (block < 0)
+ return ret;
+ const char * start(NULL), * end(NULL);
+ if (! mBufferArray->getBlockStartEnd(block, &start, &end))
+ return ret;
+ mReadCurBlock = block;
+ mReadBegin = start;
+ mReadCur = start + ba_offset;
+ mReadEnd = end;
+ ret = mReadCurPos = pos;
+ }
+ else if (std::ios_base::out == which)
+ {
+ size_t pos(0);
+
+ switch (way)
+ {
+ case std::ios_base::beg:
+ pos = off;
+ break;
+
+ case std::ios_base::cur:
+ pos = mWriteCurPos += off;
+ break;
+
+ case std::ios_base::end:
+ pos = mBufferArray->mLen - off;
+ break;
+
+ default:
+ return ret;
+ }
+
+ if (pos < 0)
+ return ret;
+ if (pos > mBufferArray->size())
+ {
+ pos = mBufferArray->size();
+ }
+ ret = mWriteCurPos = pos;
+ }
+
+ return ret;
+}
+
+
+BufferArrayStream::BufferArrayStream(BufferArray * ba)
+ : std::iostream(&mStreamBuf),
+ mStreamBuf(ba)
+{}
+
+
+BufferArrayStream::~BufferArrayStream()
+{}
+
+
+} // end namespace LLCore
+
+
diff --git a/indra/llcorehttp/bufferstream.h b/indra/llcorehttp/bufferstream.h
new file mode 100755
index 0000000000..9327a798aa
--- /dev/null
+++ b/indra/llcorehttp/bufferstream.h
@@ -0,0 +1,153 @@
+/**
+ * @file bufferstream.h
+ * @brief Public-facing declaration for the BufferStream adapter class
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 _LLCORE_BUFFER_STREAM_H_
+#define _LLCORE_BUFFER_STREAM_H_
+
+
+#include <sstream>
+#include <cstdlib>
+
+#include "bufferarray.h"
+
+
+/// @file bufferstream.h
+///
+/// std::streambuf and std::iostream adapters for BufferArray
+/// objects.
+///
+/// BufferArrayStreamBuf inherits std::streambuf and implements
+/// an unbuffered interface for streambuf. This may or may not
+/// be the most time efficient implementation and it is a little
+/// challenging.
+///
+/// BufferArrayStream inherits std::iostream and will be the
+/// adapter object most callers will be interested in (though
+/// it uses BufferArrayStreamBuf internally). Instances allow
+/// for the usual streaming operators ('<<', '>>') and serialization
+/// methods.
+///
+/// Example of LLSD serialization to a BufferArray:
+///
+/// BufferArray * ba = new BufferArray;
+/// BufferArrayStream bas(ba);
+/// LLSDSerialize::toXML(llsd, bas);
+/// operationOnBufferArray(ba);
+/// ba->release();
+/// ba = NULL;
+/// // operationOnBufferArray and bas are each holding
+/// // references to the ba instance at this point.
+///
+
+namespace LLCore
+{
+
+
+// =====================================================
+// BufferArrayStreamBuf
+// =====================================================
+
+/// Adapter class to put a std::streambuf interface on a BufferArray
+///
+/// Application developers will rarely be interested in anything
+/// other than the constructor and even that will rarely be used
+/// except indirectly via the @BufferArrayStream class. The
+/// choice of interfaces implemented yields a bufferless adapter
+/// that doesn't used either the input or output pointer triplets
+/// of the more common buffered implementations. This may or may
+/// not be faster and that question could stand to be looked at
+/// sometime.
+///
+
+class BufferArrayStreamBuf : public std::streambuf
+{
+public:
+ /// Constructor increments the reference count on the
+ /// BufferArray argument and calls release() on destruction.
+ BufferArrayStreamBuf(BufferArray * array);
+ virtual ~BufferArrayStreamBuf();
+
+private:
+ BufferArrayStreamBuf(const BufferArrayStreamBuf &); // Not defined
+ void operator=(const BufferArrayStreamBuf &); // Not defined
+
+public:
+ // Input interfaces from std::streambuf
+ int_type underflow();
+ int_type uflow();
+ int_type pbackfail(int_type ch);
+ std::streamsize showmanyc();
+
+ // Output interfaces from std::streambuf
+ int_type overflow(int c);
+ std::streamsize xsputn(const char * src, std::streamsize count);
+
+ // Common/misc interfaces from std::streambuf
+ std::streampos seekoff(std::streamoff off, std::ios_base::seekdir way, std::ios_base::openmode which);
+
+protected:
+ BufferArray * mBufferArray; // Ref counted
+ size_t mReadCurPos;
+ int mReadCurBlock;
+ const char * mReadBegin;
+ const char * mReadCur;
+ const char * mReadEnd;
+ size_t mWriteCurPos;
+
+}; // end class BufferArrayStreamBuf
+
+
+// =====================================================
+// BufferArrayStream
+// =====================================================
+
+/// Adapter class that supplies streaming operators to BufferArray
+///
+/// Provides a streaming adapter to an existing BufferArray
+/// instance so that the convenient '<<' and '>>' conversions
+/// can be applied to a BufferArray. Very convenient for LLSD
+/// serialization and parsing as well.
+
+class BufferArrayStream : public std::iostream
+{
+public:
+ /// Constructor increments the reference count on the
+ /// BufferArray argument and calls release() on destruction.
+ BufferArrayStream(BufferArray * ba);
+ ~BufferArrayStream();
+
+protected:
+ BufferArrayStream(const BufferArrayStream &);
+ void operator=(const BufferArrayStream &);
+
+protected:
+ BufferArrayStreamBuf mStreamBuf;
+}; // end class BufferArrayStream
+
+
+} // end namespace LLCore
+
+#endif // _LLCORE_BUFFER_STREAM_H_
diff --git a/indra/llcorehttp/examples/http_texture_load.cpp b/indra/llcorehttp/examples/http_texture_load.cpp
new file mode 100755
index 0000000000..40ad4f047d
--- /dev/null
+++ b/indra/llcorehttp/examples/http_texture_load.cpp
@@ -0,0 +1,947 @@
+/**
+ * @file http_texture_load.cpp
+ * @brief Texture download example for core-http library
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 <iostream>
+#include <cstdio>
+#include <cstdlib>
+#include <set>
+#include <map>
+#if !defined(WIN32)
+#include <pthread.h>
+#endif
+
+#include "linden_common.h"
+
+#include "httpcommon.h"
+#include "httprequest.h"
+#include "httphandler.h"
+#include "httpresponse.h"
+#include "httpheaders.h"
+#include "bufferarray.h"
+#include "_mutex.h"
+
+#include <curl/curl.h>
+#include <openssl/crypto.h>
+
+#include "lltimer.h"
+
+
+void init_curl();
+void term_curl();
+unsigned long ssl_thread_id_callback(void);
+void ssl_locking_callback(int mode, int type, const char * file, int line);
+void usage(std::ostream & out);
+
+// Default command line settings
+static int concurrency_limit(40);
+static char url_format[1024] = "http://example.com/some/path?texture_id=%s.texture";
+
+#if defined(WIN32)
+
+#define strncpy(_a, _b, _c) strncpy_s(_a, _b, _c)
+#define strtok_r(_a, _b, _c) strtok_s(_a, _b, _c)
+
+int getopt(int argc, char * const argv[], const char *optstring);
+char *optarg(NULL);
+int optind(1);
+
+#endif
+
+
+// Mostly just a container for the texture IDs and fetch
+// parameters....
+class WorkingSet : public LLCore::HttpHandler
+{
+public:
+ WorkingSet();
+ ~WorkingSet();
+
+ bool reload(LLCore::HttpRequest *);
+
+ virtual void onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response);
+
+ void loadTextureUuids(FILE * in);
+
+public:
+ struct Spec
+ {
+ std::string mUuid;
+ int mOffset;
+ int mLength;
+ };
+ typedef std::set<LLCore::HttpHandle> handle_set_t;
+ typedef std::vector<Spec> texture_list_t;
+
+public:
+ bool mVerbose;
+ bool mRandomRange;
+ int mMaxConcurrency;
+ handle_set_t mHandles;
+ int mRemaining;
+ int mLimit;
+ int mAt;
+ std::string mUrl;
+ texture_list_t mTextures;
+ int mErrorsApi;
+ int mErrorsHttp;
+ int mErrorsHttp404;
+ int mErrorsHttp416;
+ int mErrorsHttp500;
+ int mErrorsHttp503;
+ int mSuccesses;
+ long mByteCount;
+ LLCore::HttpHeaders * mHeaders;
+};
+
+
+// Gather process information while we run. Process
+// size, cpu consumed, wallclock time.
+
+class Metrics
+{
+public:
+ class MetricsImpl;
+
+public:
+ Metrics();
+ ~Metrics();
+
+ void init();
+ void sample();
+ void term();
+
+protected:
+ MetricsImpl * mImpl;
+
+public:
+ U64 mMaxVSZ;
+ U64 mMinVSZ;
+ U64 mStartWallTime;
+ U64 mEndWallTime;
+ U64 mStartUTime;
+ U64 mEndUTime;
+ U64 mStartSTime;
+ U64 mEndSTime;
+};
+
+
+//
+//
+//
+int main(int argc, char** argv)
+{
+ LLCore::HttpStatus status;
+ bool do_random(false);
+ bool do_verbose(false);
+
+ int option(-1);
+ while (-1 != (option = getopt(argc, argv, "u:c:h?Rv")))
+ {
+ switch (option)
+ {
+ case 'u':
+ strncpy(url_format, optarg, sizeof(url_format));
+ url_format[sizeof(url_format) - 1] = '\0';
+ break;
+
+ case 'c':
+ {
+ unsigned long value;
+ char * end;
+
+ value = strtoul(optarg, &end, 10);
+ if (value < 1 || value > 100 || *end != '\0')
+ {
+ usage(std::cerr);
+ return 1;
+ }
+ concurrency_limit = value;
+ }
+ break;
+
+ case 'R':
+ do_random = true;
+ break;
+
+ case 'v':
+ do_verbose = true;
+ break;
+
+ case 'h':
+ case '?':
+ usage(std::cout);
+ return 0;
+ }
+ }
+
+ if ((optind + 1) != argc)
+ {
+ usage(std::cerr);
+ return 1;
+ }
+
+ FILE * uuids(fopen(argv[optind], "r"));
+ if (! uuids)
+ {
+ const char * errstr(strerror(errno));
+
+ std::cerr << "Couldn't open UUID file '" << argv[optind] << "'. Reason: "
+ << errstr << std::endl;
+ return 1;
+ }
+
+ // Initialization
+ init_curl();
+ LLCore::HttpRequest::createService();
+ LLCore::HttpRequest::setPolicyClassOption(LLCore::HttpRequest::DEFAULT_POLICY_ID,
+ LLCore::HttpRequest::CP_CONNECTION_LIMIT,
+ concurrency_limit);
+ LLCore::HttpRequest::startThread();
+
+ // Get service point
+ LLCore::HttpRequest * hr = new LLCore::HttpRequest();
+
+ // Get a handler/working set
+ WorkingSet ws;
+
+ // Fill the working set with work
+ ws.mUrl = url_format;
+ ws.loadTextureUuids(uuids);
+ ws.mRandomRange = do_random;
+ ws.mVerbose = do_verbose;
+ ws.mMaxConcurrency = 100;
+
+ if (! ws.mTextures.size())
+ {
+ std::cerr << "No UUIDs found in file '" << argv[optind] << "'." << std::endl;
+ return 1;
+ }
+
+ // Setup metrics
+ Metrics metrics;
+ metrics.init();
+
+ // Run it
+ int passes(0);
+ while (! ws.reload(hr))
+ {
+ hr->update(5000000);
+ ms_sleep(2);
+ if (0 == (++passes % 200))
+ {
+ metrics.sample();
+ }
+ }
+ metrics.sample();
+ metrics.term();
+
+ // Report
+ std::cout << "HTTP errors: " << ws.mErrorsHttp << " API errors: " << ws.mErrorsApi
+ << " Successes: " << ws.mSuccesses << " Byte count: " << ws.mByteCount
+ << std::endl;
+ std::cout << "HTTP 404 errors: " << ws.mErrorsHttp404 << " HTTP 416 errors: " << ws.mErrorsHttp416
+ << " HTTP 500 errors: " << ws.mErrorsHttp500 << " HTTP 503 errors: " << ws.mErrorsHttp503
+ << std::endl;
+ std::cout << "User CPU: " << (metrics.mEndUTime - metrics.mStartUTime)
+ << " uS System CPU: " << (metrics.mEndSTime - metrics.mStartSTime)
+ << " uS Wall Time: " << (metrics.mEndWallTime - metrics.mStartWallTime)
+ << " uS Maximum VSZ: " << metrics.mMaxVSZ
+ << " Bytes Minimum VSZ: " << metrics.mMinVSZ << " Bytes"
+ << std::endl;
+
+ // Clean up
+ hr->requestStopThread(NULL);
+ ms_sleep(1000);
+ delete hr;
+ LLCore::HttpRequest::destroyService();
+ term_curl();
+
+ return 0;
+}
+
+
+void usage(std::ostream & out)
+{
+ out << "\n"
+ "usage:\thttp_texture_load [options] uuid_file\n"
+ "\n"
+ "This is a standalone program to drive the New Platform HTTP Library.\n"
+ "The program is supplied with a file of texture UUIDs, one per line\n"
+ "These are fetched sequentially using a pool of concurrent connection\n"
+ "until all are fetched. The default URL format is only useful from\n"
+ "within Linden Lab but this can be overriden with a printf-style\n"
+ "URL formatting string on the command line.\n"
+ "\n"
+ "Options:\n"
+ "\n"
+ " -u <url_format> printf-style format string for URL generation\n"
+ " Default: " << url_format << "\n"
+ " -R Issue GETs with random Range: headers\n"
+ " -c <limit> Maximum request concurrency. Range: [1..100]\n"
+ " Default: " << concurrency_limit << "\n"
+ " -v Verbose mode. Issue some chatter while running\n"
+ " -h print this help\n"
+ "\n"
+ << std::endl;
+}
+
+
+WorkingSet::WorkingSet()
+ : LLCore::HttpHandler(),
+ mVerbose(false),
+ mRandomRange(false),
+ mRemaining(200),
+ mLimit(200),
+ mAt(0),
+ mErrorsApi(0),
+ mErrorsHttp(0),
+ mErrorsHttp404(0),
+ mErrorsHttp416(0),
+ mErrorsHttp500(0),
+ mErrorsHttp503(0),
+ mSuccesses(0),
+ mByteCount(0L)
+{
+ mTextures.reserve(30000);
+
+ mHeaders = new LLCore::HttpHeaders;
+ mHeaders->mHeaders.push_back("Accept: image/x-j2c");
+}
+
+
+WorkingSet::~WorkingSet()
+{
+ if (mHeaders)
+ {
+ mHeaders->release();
+ mHeaders = NULL;
+ }
+}
+
+
+bool WorkingSet::reload(LLCore::HttpRequest * hr)
+{
+ int to_do((std::min)(mRemaining, mMaxConcurrency - int(mHandles.size())));
+
+ for (int i(0); i < to_do; ++i)
+ {
+ char buffer[1024];
+#if defined(WIN32)
+ _snprintf_s(buffer, sizeof(buffer), sizeof(buffer) - 1, mUrl.c_str(), mTextures[mAt].mUuid.c_str());
+#else
+ snprintf(buffer, sizeof(buffer), mUrl.c_str(), mTextures[mAt].mUuid.c_str());
+#endif
+ int offset(mRandomRange ? ((unsigned long) rand()) % 1000000UL : mTextures[mAt].mOffset);
+ int length(mRandomRange ? ((unsigned long) rand()) % 1000000UL : mTextures[mAt].mLength);
+
+ LLCore::HttpHandle handle;
+ if (offset || length)
+ {
+ handle = hr->requestGetByteRange(0, 0, buffer, offset, length, NULL, mHeaders, this);
+ }
+ else
+ {
+ handle = hr->requestGet(0, 0, buffer, NULL, mHeaders, this);
+ }
+ if (! handle)
+ {
+ // Fatal. Couldn't queue up something.
+ std::cerr << "Failed to queue work to HTTP Service. Reason: "
+ << hr->getStatus().toString() << std::endl;
+ exit(1);
+ }
+ else
+ {
+ mHandles.insert(handle);
+ }
+ mAt++;
+ mRemaining--;
+
+ if (mVerbose)
+ {
+ static int count(0);
+ ++count;
+ if (0 == (count %5))
+ std::cout << "Queued " << count << std::endl;
+ }
+ }
+
+ // Are we done?
+ return (! mRemaining) && mHandles.empty();
+}
+
+
+void WorkingSet::onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response)
+{
+ handle_set_t::iterator it(mHandles.find(handle));
+ if (mHandles.end() == it)
+ {
+ // Wha?
+ std::cerr << "Failed to find handle in request list. Fatal." << std::endl;
+ exit(1);
+ }
+ else
+ {
+ LLCore::HttpStatus status(response->getStatus());
+ if (status)
+ {
+ // More success
+ LLCore::BufferArray * data(response->getBody());
+ mByteCount += data->size();
+ ++mSuccesses;
+ }
+ else
+ {
+ // Something in this library or libcurl
+ if (status.isHttpStatus())
+ {
+ static const LLCore::HttpStatus hs404(404);
+ static const LLCore::HttpStatus hs416(416);
+ static const LLCore::HttpStatus hs500(500);
+ static const LLCore::HttpStatus hs503(503);
+
+ ++mErrorsHttp;
+ if (hs404 == status)
+ {
+ ++mErrorsHttp404;
+ }
+ else if (hs416 == status)
+ {
+ ++mErrorsHttp416;
+ }
+ else if (hs500 == status)
+ {
+ ++mErrorsHttp500;
+ }
+ else if (hs503 == status)
+ {
+ ++mErrorsHttp503;
+ }
+ }
+ else
+ {
+ ++mErrorsApi;
+ }
+ }
+ mHandles.erase(it);
+ }
+
+ if (mVerbose)
+ {
+ static int count(0);
+ ++count;
+ if (0 == (count %5))
+ std::cout << "Handled " << count << std::endl;
+ }
+}
+
+
+void WorkingSet::loadTextureUuids(FILE * in)
+{
+ char buffer[1024];
+
+ while (fgets(buffer, sizeof(buffer), in))
+ {
+ WorkingSet::Spec texture;
+ char * state(NULL);
+ char * token = strtok_r(buffer, " \t\n,", &state);
+ if (token && 36 == strlen(token))
+ {
+ // Close enough for this function
+ texture.mUuid = token;
+ texture.mOffset = 0;
+ texture.mLength = 0;
+ token = strtok_r(buffer, " \t\n,", &state);
+ if (token)
+ {
+ int offset(atoi(token));
+ token = strtok_r(buffer, " \t\n,", &state);
+ if (token)
+ {
+ int length(atoi(token));
+ texture.mOffset = offset;
+ texture.mLength = length;
+ }
+ }
+ mTextures.push_back(texture);
+ }
+ }
+ mRemaining = mLimit = mTextures.size();
+}
+
+
+int ssl_mutex_count(0);
+LLCoreInt::HttpMutex ** ssl_mutex_list = NULL;
+
+void init_curl()
+{
+ curl_global_init(CURL_GLOBAL_ALL);
+
+ ssl_mutex_count = CRYPTO_num_locks();
+ if (ssl_mutex_count > 0)
+ {
+ ssl_mutex_list = new LLCoreInt::HttpMutex * [ssl_mutex_count];
+
+ for (int i(0); i < ssl_mutex_count; ++i)
+ {
+ ssl_mutex_list[i] = new LLCoreInt::HttpMutex;
+ }
+
+ CRYPTO_set_locking_callback(ssl_locking_callback);
+ CRYPTO_set_id_callback(ssl_thread_id_callback);
+ }
+}
+
+
+void term_curl()
+{
+ CRYPTO_set_locking_callback(NULL);
+ for (int i(0); i < ssl_mutex_count; ++i)
+ {
+ delete ssl_mutex_list[i];
+ }
+ delete [] ssl_mutex_list;
+}
+
+
+unsigned long ssl_thread_id_callback(void)
+{
+#if defined(WIN32)
+ return (unsigned long) GetCurrentThread();
+#else
+ return (unsigned long) pthread_self();
+#endif
+}
+
+
+void ssl_locking_callback(int mode, int type, const char * /* file */, int /* line */)
+{
+ if (type >= 0 && type < ssl_mutex_count)
+ {
+ if (mode & CRYPTO_LOCK)
+ {
+ ssl_mutex_list[type]->lock();
+ }
+ else
+ {
+ ssl_mutex_list[type]->unlock();
+ }
+ }
+}
+
+
+#if defined(WIN32)
+
+// Very much a subset of posix functionality. Don't push
+// it too hard...
+int getopt(int argc, char * const argv[], const char *optstring)
+{
+ static int pos(0);
+ while (optind < argc)
+ {
+ if (pos == 0)
+ {
+ if (argv[optind][0] != '-')
+ return -1;
+ pos = 1;
+ }
+ if (! argv[optind][pos])
+ {
+ ++optind;
+ pos = 0;
+ continue;
+ }
+ const char * thing(strchr(optstring, argv[optind][pos]));
+ if (! thing)
+ {
+ ++optind;
+ return -1;
+ }
+ if (thing[1] == ':')
+ {
+ optarg = argv[++optind];
+ ++optind;
+ pos = 0;
+ }
+ else
+ {
+ optarg = NULL;
+ ++pos;
+ }
+ return *thing;
+ }
+ return -1;
+}
+
+#endif
+
+
+
+#if LL_WINDOWS
+
+#define PSAPI_VERSION 1
+#include "windows.h"
+#include "psapi.h"
+
+class Metrics::MetricsImpl
+{
+public:
+ MetricsImpl()
+ {}
+
+ ~MetricsImpl()
+ {}
+
+ void init(Metrics * metrics)
+ {
+ HANDLE self(GetCurrentProcess()); // Does not have to be closed
+ FILETIME ft_dummy, ft_system, ft_user;
+ GetProcessTimes(self, &ft_dummy, &ft_dummy, &ft_system, &ft_user);
+ ULARGE_INTEGER uli;
+ uli.u.LowPart = ft_system.dwLowDateTime;
+ uli.u.HighPart = ft_system.dwHighDateTime;
+ metrics->mStartSTime = uli.QuadPart / U64L(10); // Convert to uS
+ uli.u.LowPart = ft_user.dwLowDateTime;
+ uli.u.HighPart = ft_user.dwHighDateTime;
+ metrics->mStartUTime = uli.QuadPart / U64L(10);
+ metrics->mStartWallTime = totalTime();
+ }
+
+ void sample(Metrics * metrics)
+ {
+ PROCESS_MEMORY_COUNTERS_EX counters;
+
+ GetProcessMemoryInfo(GetCurrentProcess(),
+ (PROCESS_MEMORY_COUNTERS *) &counters,
+ sizeof(counters));
+ // Okay, PrivateUsage isn't truly VSZ but it will be
+ // a good tracker for leaks and fragmentation. Work on
+ // a better estimator later...
+ SIZE_T vsz(counters.PrivateUsage);
+ metrics->mMaxVSZ = (std::max)(metrics->mMaxVSZ, U64(vsz));
+ metrics->mMinVSZ = (std::min)(metrics->mMinVSZ, U64(vsz));
+ }
+
+ void term(Metrics * metrics)
+ {
+ HANDLE self(GetCurrentProcess()); // Does not have to be closed
+ FILETIME ft_dummy, ft_system, ft_user;
+ GetProcessTimes(self, &ft_dummy, &ft_dummy, &ft_system, &ft_user);
+ ULARGE_INTEGER uli;
+ uli.u.LowPart = ft_system.dwLowDateTime;
+ uli.u.HighPart = ft_system.dwHighDateTime;
+ metrics->mEndSTime = uli.QuadPart / U64L(10);
+ uli.u.LowPart = ft_user.dwLowDateTime;
+ uli.u.HighPart = ft_user.dwHighDateTime;
+ metrics->mEndUTime = uli.QuadPart / U64L(10);
+ metrics->mEndWallTime = totalTime();
+ }
+
+protected:
+};
+
+#elif LL_DARWIN
+
+#include <sys/resource.h>
+#include <mach/mach.h>
+
+class Metrics::MetricsImpl
+{
+public:
+ MetricsImpl()
+ {}
+
+ ~MetricsImpl()
+ {}
+
+ void init(Metrics * metrics)
+ {
+ U64 utime, stime;
+
+ if (getTimes(&utime, &stime))
+ {
+ metrics->mStartSTime = stime;
+ metrics->mStartUTime = utime;
+ }
+ metrics->mStartWallTime = totalTime();
+ sample(metrics);
+ }
+
+ void sample(Metrics * metrics)
+ {
+ U64 vsz;
+
+ if (getVM(&vsz))
+ {
+ metrics->mMaxVSZ = (std::max)(metrics->mMaxVSZ, vsz);
+ metrics->mMinVSZ = (std::min)(metrics->mMinVSZ, vsz);
+ }
+ }
+
+ void term(Metrics * metrics)
+ {
+ U64 utime, stime;
+
+ if (getTimes(&utime, &stime))
+ {
+ metrics->mEndSTime = stime;
+ metrics->mEndUTime = utime;
+ }
+ metrics->mEndWallTime = totalTime();
+ }
+
+protected:
+ bool getVM(U64 * vsz)
+ {
+ task_basic_info task_info_block;
+ mach_msg_type_number_t task_info_count(TASK_BASIC_INFO_COUNT);
+
+ if (KERN_SUCCESS != task_info(mach_task_self(),
+ TASK_BASIC_INFO,
+ (task_info_t) &task_info_block,
+ &task_info_count))
+ {
+ return false;
+ }
+ * vsz = task_info_block.virtual_size;
+ return true;
+ }
+
+ bool getTimes(U64 * utime, U64 * stime)
+ {
+ struct rusage usage;
+
+ if (getrusage(RUSAGE_SELF, &usage))
+ {
+ return false;
+ }
+ * utime = U64(usage.ru_utime.tv_sec) * U64L(1000000) + usage.ru_utime.tv_usec;
+ * stime = U64(usage.ru_stime.tv_sec) * U64L(1000000) + usage.ru_stime.tv_usec;
+ return true;
+ }
+
+};
+
+#else
+
+class Metrics::MetricsImpl
+{
+public:
+ MetricsImpl()
+ : mProcFS(NULL),
+ mUsecsPerTick(U64L(0))
+ {}
+
+
+ ~MetricsImpl()
+ {
+ if (mProcFS)
+ {
+ fclose(mProcFS);
+ mProcFS = NULL;
+ }
+ }
+
+ void init(Metrics * metrics)
+ {
+ if (! mProcFS)
+ {
+ mProcFS = fopen("/proc/self/stat", "r");
+ if (! mProcFS)
+ {
+ const int errnum(errno);
+ LL_ERRS("Main") << "Error opening proc fs: " << strerror(errnum) << LL_ENDL;
+ }
+ }
+
+ long ticks_per_sec(sysconf(_SC_CLK_TCK));
+ mUsecsPerTick = U64L(1000000) / ticks_per_sec;
+ U64 usecs_per_sec(mUsecsPerTick * ticks_per_sec);
+ if (900000 > usecs_per_sec || 1100000 < usecs_per_sec)
+ {
+ LL_ERRS("Main") << "Resolution problems using uSecs for ticks" << LL_ENDL;
+ }
+
+ U64 utime, stime;
+ if (scanProcFS(&utime, &stime, NULL))
+ {
+ metrics->mStartSTime = stime;
+ metrics->mStartUTime = utime;
+ }
+ metrics->mStartWallTime = totalTime();
+
+ sample(metrics);
+ }
+
+
+ void sample(Metrics * metrics)
+ {
+ U64 vsz;
+ if (scanProcFS(NULL, NULL, &vsz))
+ {
+ metrics->mMaxVSZ = (std::max)(metrics->mMaxVSZ, vsz);
+ metrics->mMinVSZ = (std::min)(metrics->mMinVSZ, vsz);
+ }
+ }
+
+
+ void term(Metrics * metrics)
+ {
+ U64 utime, stime;
+ if (scanProcFS(&utime, &stime, NULL))
+ {
+ metrics->mEndSTime = stime;
+ metrics->mEndUTime = utime;
+ }
+ metrics->mEndWallTime = totalTime();
+
+ sample(metrics);
+
+ if (mProcFS)
+ {
+ fclose(mProcFS);
+ mProcFS = NULL;
+ }
+ }
+
+protected:
+ bool scanProcFS(U64 * utime, U64 * stime, U64 * vsz)
+ {
+ if (mProcFS)
+ {
+ int i_dummy;
+ unsigned int ui_dummy;
+ unsigned long ul_dummy, user_ticks, sys_ticks, vsize;
+ long l_dummy, rss;
+ unsigned long long ull_dummy;
+ char c_dummy;
+
+ char buffer[256];
+
+ static const char * format("%d %*s %c %d %d %d %d %d %u %lu %lu %lu %lu %lu %lu %ld %ld %ld %ld %ld %ld %llu %lu %ld");
+
+ fseek(mProcFS, 0L, SEEK_SET);
+ size_t len = fread(buffer, 1, sizeof(buffer) - 1, mProcFS);
+ if (! len)
+ {
+ return false;
+ }
+ buffer[len] = '\0';
+ if (23 == sscanf(buffer, format,
+ &i_dummy, // pid
+ // &s_dummy, // command name
+ &c_dummy, // state
+ &i_dummy, // ppid
+ &i_dummy, // pgrp
+ &i_dummy, // session
+ &i_dummy, // terminal
+ &i_dummy, // terminal group id
+ &ui_dummy, // flags
+ &ul_dummy, // minor faults
+ &ul_dummy, // minor faults in children
+ &ul_dummy, // major faults
+ &ul_dummy, // major faults in children
+ &user_ticks,
+ &sys_ticks,
+ &l_dummy, // cutime
+ &l_dummy, // cstime
+ &l_dummy, // process priority
+ &l_dummy, // nice value
+ &l_dummy, // thread count
+ &l_dummy, // time to SIGALRM
+ &ull_dummy, // start time
+ &vsize,
+ &rss))
+ {
+ // Looks like we understand the line
+ if (utime)
+ {
+ *utime = user_ticks * mUsecsPerTick;
+ }
+
+ if (stime)
+ {
+ *stime = sys_ticks * mUsecsPerTick;
+ }
+
+ if (vsz)
+ {
+ *vsz = vsize;
+ }
+ return true;
+ }
+ }
+ return false;
+ }
+
+protected:
+ FILE * mProcFS;
+ U64 mUsecsPerTick;
+
+};
+
+
+#endif // LL_WINDOWS
+
+Metrics::Metrics()
+ : mMaxVSZ(U64(0)),
+ mMinVSZ(U64L(0xffffffffffffffff)),
+ mStartWallTime(U64(0)),
+ mEndWallTime(U64(0)),
+ mStartUTime(U64(0)),
+ mEndUTime(U64(0)),
+ mStartSTime(U64(0)),
+ mEndSTime(U64(0))
+{
+ mImpl = new MetricsImpl();
+}
+
+
+Metrics::~Metrics()
+{
+ delete mImpl;
+ mImpl = NULL;
+}
+
+
+void Metrics::init()
+{
+ mImpl->init(this);
+}
+
+
+void Metrics::sample()
+{
+ mImpl->sample(this);
+}
+
+
+void Metrics::term()
+{
+ mImpl->term(this);
+}
+
+
diff --git a/indra/llcorehttp/httpcommon.cpp b/indra/llcorehttp/httpcommon.cpp
new file mode 100755
index 0000000000..0738760763
--- /dev/null
+++ b/indra/llcorehttp/httpcommon.cpp
@@ -0,0 +1,211 @@
+/**
+ * @file httpcommon.cpp
+ * @brief
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012-2013, 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 "httpcommon.h"
+
+#include <curl/curl.h>
+#include <string>
+#include <sstream>
+
+
+namespace LLCore
+{
+
+HttpStatus::type_enum_t EXT_CURL_EASY;
+HttpStatus::type_enum_t EXT_CURL_MULTI;
+HttpStatus::type_enum_t LLCORE;
+
+HttpStatus::operator unsigned long() const
+{
+ static const int shift(sizeof(unsigned long) * 4);
+
+ unsigned long result(((unsigned long) mType) << shift | (unsigned long) (int) mStatus);
+ return result;
+}
+
+
+std::string HttpStatus::toHex() const
+{
+ std::ostringstream result;
+ result.width(8);
+ result.fill('0');
+ result << std::hex << operator unsigned long();
+ return result.str();
+}
+
+
+std::string HttpStatus::toString() const
+{
+ static const char * llcore_errors[] =
+ {
+ "",
+ "HTTP error reply status",
+ "Services shutting down",
+ "Operation canceled",
+ "Invalid Content-Range header encountered",
+ "Request handle not found",
+ "Invalid datatype for argument or option",
+ "Option has not been explicitly set",
+ "Option is not dynamic and must be set early",
+ "Invalid HTTP status code received from server"
+ };
+ static const int llcore_errors_count(sizeof(llcore_errors) / sizeof(llcore_errors[0]));
+
+ static const struct
+ {
+ type_enum_t mCode;
+ const char * mText;
+ }
+ http_errors[] =
+ {
+ // Keep sorted by mCode, we binary search this list.
+ { 100, "Continue" },
+ { 101, "Switching Protocols" },
+ { 200, "OK" },
+ { 201, "Created" },
+ { 202, "Accepted" },
+ { 203, "Non-Authoritative Information" },
+ { 204, "No Content" },
+ { 205, "Reset Content" },
+ { 206, "Partial Content" },
+ { 300, "Multiple Choices" },
+ { 301, "Moved Permanently" },
+ { 302, "Found" },
+ { 303, "See Other" },
+ { 304, "Not Modified" },
+ { 305, "Use Proxy" },
+ { 307, "Temporary Redirect" },
+ { 400, "Bad Request" },
+ { 401, "Unauthorized" },
+ { 402, "Payment Required" },
+ { 403, "Forbidden" },
+ { 404, "Not Found" },
+ { 405, "Method Not Allowed" },
+ { 406, "Not Acceptable" },
+ { 407, "Proxy Authentication Required" },
+ { 408, "Request Time-out" },
+ { 409, "Conflict" },
+ { 410, "Gone" },
+ { 411, "Length Required" },
+ { 412, "Precondition Failed" },
+ { 413, "Request Entity Too Large" },
+ { 414, "Request-URI Too Large" },
+ { 415, "Unsupported Media Type" },
+ { 416, "Requested range not satisfiable" },
+ { 417, "Expectation Failed" },
+ { 499, "Linden Catch-All" },
+ { 500, "Internal Server Error" },
+ { 501, "Not Implemented" },
+ { 502, "Bad Gateway" },
+ { 503, "Service Unavailable" },
+ { 504, "Gateway Time-out" },
+ { 505, "HTTP Version not supported" }
+ };
+ static const int http_errors_count(sizeof(http_errors) / sizeof(http_errors[0]));
+
+ if (*this)
+ {
+ return std::string("");
+ }
+ switch (mType)
+ {
+ case EXT_CURL_EASY:
+ return std::string(curl_easy_strerror(CURLcode(mStatus)));
+
+ case EXT_CURL_MULTI:
+ return std::string(curl_multi_strerror(CURLMcode(mStatus)));
+
+ case LLCORE:
+ if (mStatus >= 0 && mStatus < llcore_errors_count)
+ {
+ return std::string(llcore_errors[mStatus]);
+ }
+ break;
+
+ default:
+ if (isHttpStatus())
+ {
+ // Binary search for the error code and string
+ int bottom(0), top(http_errors_count);
+ while (true)
+ {
+ int at((bottom + top) / 2);
+ if (mType == http_errors[at].mCode)
+ {
+ return std::string(http_errors[at].mText);
+ }
+ if (at == bottom)
+ {
+ break;
+ }
+ else if (mType < http_errors[at].mCode)
+ {
+ top = at;
+ }
+ else
+ {
+ bottom = at;
+ }
+ }
+ }
+ break;
+ }
+ return std::string("Unknown error");
+}
+
+
+// Pass true on statuses that might actually be cleared by a
+// retry. Library failures, calling problems, etc. aren't
+// going to be fixed by squirting bits all over the Net.
+bool HttpStatus::isRetryable() const
+{
+ static const HttpStatus cant_connect(HttpStatus::EXT_CURL_EASY, CURLE_COULDNT_CONNECT);
+ static const HttpStatus cant_res_proxy(HttpStatus::EXT_CURL_EASY, CURLE_COULDNT_RESOLVE_PROXY);
+ static const HttpStatus cant_res_host(HttpStatus::EXT_CURL_EASY, CURLE_COULDNT_RESOLVE_HOST);
+ static const HttpStatus send_error(HttpStatus::EXT_CURL_EASY, CURLE_SEND_ERROR);
+ static const HttpStatus recv_error(HttpStatus::EXT_CURL_EASY, CURLE_RECV_ERROR);
+ static const HttpStatus upload_failed(HttpStatus::EXT_CURL_EASY, CURLE_UPLOAD_FAILED);
+ static const HttpStatus op_timedout(HttpStatus::EXT_CURL_EASY, CURLE_OPERATION_TIMEDOUT);
+ static const HttpStatus post_error(HttpStatus::EXT_CURL_EASY, CURLE_HTTP_POST_ERROR);
+ static const HttpStatus partial_file(HttpStatus::EXT_CURL_EASY, CURLE_PARTIAL_FILE);
+ static const HttpStatus inv_cont_range(HttpStatus::LLCORE, HE_INV_CONTENT_RANGE_HDR);
+
+ return ((isHttpStatus() && mType >= 499 && mType <= 599) || // Include special 499 in retryables
+ *this == cant_connect || // Connection reset/endpoint problems
+ *this == cant_res_proxy || // DNS problems
+ *this == cant_res_host || // DNS problems
+ *this == send_error || // General socket problems
+ *this == recv_error || // General socket problems
+ *this == upload_failed || // Transport problem
+ *this == op_timedout || // Timer expired
+ *this == post_error || // Transport problem
+ *this == partial_file || // Data inconsistency in response
+ *this == inv_cont_range); // Short data read disagrees with content-range
+}
+
+
+} // end namespace LLCore
+
diff --git a/indra/llcorehttp/httpcommon.h b/indra/llcorehttp/httpcommon.h
new file mode 100755
index 0000000000..41fb5164cf
--- /dev/null
+++ b/indra/llcorehttp/httpcommon.h
@@ -0,0 +1,317 @@
+/**
+ * @file httpcommon.h
+ * @brief Public-facing declarations and definitions of common types
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012-2013, 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 _LLCORE_HTTP_COMMON_H_
+#define _LLCORE_HTTP_COMMON_H_
+
+/// @package LLCore::HTTP
+///
+/// This library implements a high-level, Indra-code-free client interface to
+/// HTTP services based on actual patterns found in the viewer and simulator.
+/// Interfaces are similar to those supplied by the legacy classes
+/// LLCurlRequest and LLHTTPClient. To that is added a policy scheme that
+/// allows an application to specify connection behaviors: limits on
+/// connections, HTTP keepalive, HTTP pipelining, retry-on-error limits, etc.
+///
+/// Features of the library include:
+/// - Single, private working thread where all transport and processing occurs.
+/// - Support for multiple consumers running in multiple threads.
+/// - Scatter/gather (a.k.a. buffer array) model for bulk data movement.
+/// - Reference counting used for many object instance lifetimes.
+/// - Minimal data sharing across threads for correctness and low latency.
+///
+/// The public interface is declared in a few key header files:
+/// - "llcorehttp/bufferarray.h"
+/// - "llcorehttp/httpcommon.h"
+/// - "llcorehttp/httphandler.h"
+/// - "llcorehttp/httpheaders.h"
+/// - "llcorehttp/httpoptions.h"
+/// - "llcorehttp/httprequest.h"
+/// - "llcorehttp/httpresponse.h"
+///
+/// The library is still under early development and particular users
+/// may need access to internal implementation details that are found
+/// in the _*.h header files. But this is a crutch to be avoided if at
+/// all possible and probably indicates some interface work is neeeded.
+///
+/// Using the library is fairly easy. Global setup needs a few
+/// steps:
+///
+/// - libcurl initialization including thread-safely callbacks for SSL:
+/// . curl_global_init(...)
+/// . CRYPTO_set_locking_callback(...)
+/// . CRYPTO_set_id_callback(...)
+/// - HttpRequest::createService() called to instantiate singletons
+/// and support objects.
+///
+/// An HTTP consumer in an application, and an application may have many
+/// consumers, does a few things:
+///
+/// - Instantiate and retain an object based on HttpRequest. This
+/// object becomes the portal into runtime services for the consumer.
+/// - Derive or mixin the HttpHandler class if you want notification
+/// when requests succeed or fail. This object's onCompleted()
+/// method is invoked and an instance can be shared across
+/// requests.
+///
+/// Issuing a request is straightforward:
+/// - Construct a suitable URL.
+/// - Configure HTTP options for the request. (optional)
+/// - Build a list of additional headers. (optional)
+/// - Invoke one of the requestXXXX() methods (requestGetByteRange,
+/// requestPost, etc.) on the HttpRequest instance supplying the
+/// above along with a policy class, a priority and an optional
+/// pointer to an HttpHandler instance. Work is then queued to
+/// the worker thread and occurs asynchronously.
+/// - Periodically invoke the update() method on the HttpRequest
+/// instance which performs completion notification to HttpHandler
+/// objects.
+/// - Do completion processing in your onCompletion() method.
+///
+/// Code fragments:
+/// Rather than a poorly-maintained example in comments, look in the
+/// example subdirectory which is a minimal yet functional tool to do
+/// GET request performance testing. With four calls:
+///
+/// init_curl();
+/// LLCore::HttpRequest::createService();
+/// LLCore::HttpRequest::startThread();
+/// LLCore::HttpRequest * hr = new LLCore::HttpRequest();
+///
+/// the program is basically ready to issue requests.
+///
+
+
+#include "linden_common.h" // Modifies curl/curl.h interfaces
+
+#include <string>
+
+
+namespace LLCore
+{
+
+
+/// All queued requests are represented by an HttpHandle value.
+/// The invalid value is returned when a request failed to queue.
+/// The actual status for these failures is then fetched with
+/// HttpRequest::getStatus().
+///
+/// The handle is valid only for the life of a request. On
+/// return from any HttpHandler notification, the handle immediately
+/// becomes invalid and may be recycled for other queued requests.
+
+typedef void * HttpHandle;
+#define LLCORE_HTTP_HANDLE_INVALID (NULL)
+
+/// For internal scheduling and metrics, we use a microsecond
+/// timebase compatible with the environment.
+typedef U64 HttpTime;
+
+/// Error codes defined by the library itself as distinct from
+/// libcurl (or any other transport provider).
+enum HttpError
+{
+ // Successful value compatible with the libcurl codes.
+ HE_SUCCESS = 0,
+
+ // Intended for HTTP reply codes 100-999, indicates that
+ // the reply should be considered an error by the application.
+ HE_REPLY_ERROR = 1,
+
+ // Service is shutting down and requested operation will
+ // not be queued or performed.
+ HE_SHUTTING_DOWN = 2,
+
+ // Operation was canceled by request.
+ HE_OP_CANCELED = 3,
+
+ // Invalid content range header received.
+ HE_INV_CONTENT_RANGE_HDR = 4,
+
+ // Request handle not found
+ HE_HANDLE_NOT_FOUND = 5,
+
+ // Invalid datatype for option/setting
+ HE_INVALID_ARG = 6,
+
+ // Option hasn't been explicitly set
+ HE_OPT_NOT_SET = 7,
+
+ // Option not dynamic, must be set during init phase
+ HE_OPT_NOT_DYNAMIC = 8,
+
+ // Invalid HTTP status code returned by server
+ HE_INVALID_HTTP_STATUS = 9
+
+}; // end enum HttpError
+
+
+/// HttpStatus encapsulates errors from libcurl (easy, multi), HTTP
+/// reply status codes and internal errors as well. The encapsulation
+/// isn't expected to completely isolate the caller from libcurl but
+/// basic operational tests (success or failure) are provided.
+///
+/// Non-HTTP status are encoded as (type, status) with type being
+/// one of: EXT_CURL_EASY, EXT_CURL_MULTI or LLCORE and status
+/// being the success/error code from that domain. HTTP status
+/// is encoded as (status, error_flag). Status should be in the
+/// range [100, 999] and error_flag is either HE_SUCCESS or
+/// HE_REPLY_ERROR to indicate whether this should be treated as
+/// a successful status or an error. The application is responsible
+/// for making that determination and a range like [200, 299] isn't
+/// automatically assumed to be definitive.
+///
+/// Examples:
+///
+/// 1. Construct a default, successful status code:
+/// HttpStatus();
+///
+/// 2. Construct a successful, HTTP 200 status code:
+/// HttpStatus(200);
+///
+/// 3. Construct a failed, HTTP 404 not-found status code:
+/// HttpStatus(404);
+///
+/// 4. Construct a failed libcurl couldn't connect status code:
+/// HttpStatus(HttpStatus::EXT_CURL_EASY, CURLE_COULDNT_CONNECT);
+///
+/// 5. Construct an HTTP 301 status code to be treated as success:
+/// HttpStatus(301, HE_SUCCESS);
+///
+
+struct HttpStatus
+{
+ typedef unsigned short type_enum_t;
+
+ HttpStatus()
+ : mType(LLCORE),
+ mStatus(HE_SUCCESS)
+ {}
+
+ HttpStatus(type_enum_t type, short status)
+ : mType(type),
+ mStatus(status)
+ {}
+
+ HttpStatus(int http_status)
+ : mType(http_status),
+ mStatus(http_status >= 200 && http_status <= 299
+ ? HE_SUCCESS
+ : HE_REPLY_ERROR)
+ {
+ llassert(http_status >= 100 && http_status <= 999);
+ }
+
+ HttpStatus(const HttpStatus & rhs)
+ : mType(rhs.mType),
+ mStatus(rhs.mStatus)
+ {}
+
+ HttpStatus & operator=(const HttpStatus & rhs)
+ {
+ // Don't care if lhs & rhs are the same object
+
+ mType = rhs.mType;
+ mStatus = rhs.mStatus;
+ return *this;
+ }
+
+ static const type_enum_t EXT_CURL_EASY = 0;
+ static const type_enum_t EXT_CURL_MULTI = 1;
+ static const type_enum_t LLCORE = 2;
+
+ type_enum_t mType;
+ short mStatus;
+
+ /// Test for successful status in the code regardless
+ /// of error source (internal, libcurl).
+ ///
+ /// @return 'true' when status is successful.
+ ///
+ operator bool() const
+ {
+ return 0 == mStatus;
+ }
+
+ /// Inverse of previous operator.
+ ///
+ /// @return 'true' on any error condition
+ bool operator !() const
+ {
+ return 0 != mStatus;
+ }
+
+ /// Equality and inequality tests to bypass bool conversion
+ /// which will do the wrong thing in conditional expressions.
+ bool operator==(const HttpStatus & rhs) const
+ {
+ return mType == rhs.mType && mStatus == rhs.mStatus;
+ }
+
+ bool operator!=(const HttpStatus & rhs) const
+ {
+ return ! operator==(rhs);
+ }
+
+ /// Convert to single numeric representation. Mainly
+ /// for logging or other informal purposes. Also
+ /// creates an ambiguous second path to integer conversion
+ /// which tends to find programming errors such as formatting
+ /// the status to a stream (operator<<).
+ operator unsigned long() const;
+ unsigned long toULong() const
+ {
+ return operator unsigned long();
+ }
+
+ /// And to convert to a hex string.
+ std::string toHex() const;
+
+ /// Convert status to a string representation. For
+ /// success, returns an empty string. For failure
+ /// statuses, a string as appropriate for the source of
+ /// the error code (libcurl easy, libcurl multi, or
+ /// LLCore itself).
+ std::string toString() const;
+
+ /// Returns true if the status value represents an
+ /// HTTP response status (100 - 999).
+ bool isHttpStatus() const
+ {
+ return mType >= type_enum_t(100) && mType <= type_enum_t(999);
+ }
+
+ /// Returns true if the status is one that will be retried
+ /// internally. Provided for external consumption for cases
+ /// where that logic needs to be replicated. Only applies
+ /// to failed statuses, successful statuses will return false.
+ bool isRetryable() const;
+
+}; // end struct HttpStatus
+
+} // end namespace LLCore
+
+#endif // _LLCORE_HTTP_COMMON_H_
diff --git a/indra/llcorehttp/httphandler.h b/indra/llcorehttp/httphandler.h
new file mode 100755
index 0000000000..9171e4e7b9
--- /dev/null
+++ b/indra/llcorehttp/httphandler.h
@@ -0,0 +1,88 @@
+/**
+ * @file httphandler.h
+ * @brief Public-facing declarations for the HttpHandler class
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 _LLCORE_HTTP_HANDLER_H_
+#define _LLCORE_HTTP_HANDLER_H_
+
+
+#include "httpcommon.h"
+
+
+namespace LLCore
+{
+
+class HttpResponse;
+
+
+/// HttpHandler defines an interface used by the library to
+/// notify library callers of significant events, currently
+/// request completion. Callers must derive or mixin this class
+/// then provide an implementation of the @see onCompleted
+/// method to receive such notifications. An instance may
+/// be shared by any number of requests and across instances
+/// of HttpRequest running in the same thread.
+///
+/// Threading: HttpHandler itself is pure interface and is
+/// tread-compatible. Most derivations, however, will have
+/// different constraints.
+///
+/// Allocation: Not refcounted, may be stack allocated though
+/// that is rarely a good idea. Queued requests and replies keep
+/// a naked pointer to the handler and this can result in a
+/// dangling pointer if lifetimes aren't managed correctly.
+
+class HttpHandler
+{
+public:
+ virtual ~HttpHandler()
+ {}
+
+ /// Method invoked during calls to @see update(). Each invocation
+ /// represents the completion of some requested operation. Caller
+ /// can identify the request from the handle and interrogate the
+ /// response argument for success/failure, data and other information.
+ ///
+ /// @param handle Identifier of the request generating
+ /// the notification.
+ /// @param response Supplies detailed information about
+ /// the request including status codes
+ /// (both programming and HTTP), HTTP body
+ /// data and encodings, headers, etc.
+ /// The response object is refcounted and
+ /// the called code may retain the object
+ /// by invoking @see addRef() on it. The
+ /// library itself drops all references to
+ /// to object on return and never touches
+ /// it again.
+ ///
+ virtual void onCompleted(HttpHandle handle, HttpResponse * response) = 0;
+
+}; // end class HttpHandler
+
+
+} // end namespace LLCore
+
+#endif // _LLCORE_HTTP_HANDLER_H_
diff --git a/indra/llcorehttp/httpheaders.cpp b/indra/llcorehttp/httpheaders.cpp
new file mode 100755
index 0000000000..2832696271
--- /dev/null
+++ b/indra/llcorehttp/httpheaders.cpp
@@ -0,0 +1,44 @@
+/**
+ * @file httpheaders.cpp
+ * @brief Implementation of the HTTPHeaders class
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 "httpheaders.h"
+
+
+namespace LLCore
+{
+
+
+HttpHeaders::HttpHeaders()
+ : RefCounted(true)
+{}
+
+
+HttpHeaders::~HttpHeaders()
+{}
+
+
+} // end namespace LLCore
+
diff --git a/indra/llcorehttp/httpheaders.h b/indra/llcorehttp/httpheaders.h
new file mode 100755
index 0000000000..3449daa3a1
--- /dev/null
+++ b/indra/llcorehttp/httpheaders.h
@@ -0,0 +1,87 @@
+/**
+ * @file httpheaders.h
+ * @brief Public-facing declarations for the HttpHeaders class
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 _LLCORE_HTTP_HEADERS_H_
+#define _LLCORE_HTTP_HEADERS_H_
+
+
+#include <string>
+
+#include "_refcounted.h"
+
+
+namespace LLCore
+{
+
+///
+/// Maintains an ordered list of name/value pairs representing
+/// HTTP header lines. This is used both to provide additional
+/// headers when making HTTP requests and in responses when the
+/// caller has asked that headers be returned (not the default
+/// option).
+///
+/// @note
+/// This is a minimally-functional placeholder at the moment
+/// to fill out the class hierarchy. The final class will be
+/// something else, probably more pair-oriented. It's also
+/// an area where shared values are desirable so refcounting is
+/// already specced and a copy-on-write scheme imagined.
+/// Expect changes here.
+///
+/// Threading: Not intrinsically thread-safe. It *is* expected
+/// that callers will build these objects and then share them
+/// via reference counting with the worker thread. The implication
+/// is that once an HttpHeader instance is handed to a request,
+/// the object must be treated as read-only.
+///
+/// Allocation: Refcounted, heap only. Caller of the
+/// constructor is given a refcount.
+///
+
+class HttpHeaders : public LLCoreInt::RefCounted
+{
+public:
+ /// @post In addition to the instance, caller has a refcount
+ /// to the instance. A call to @see release() will destroy
+ /// the instance.
+ HttpHeaders();
+
+protected:
+ virtual ~HttpHeaders(); // Use release()
+
+ HttpHeaders(const HttpHeaders &); // Not defined
+ void operator=(const HttpHeaders &); // Not defined
+
+public:
+ typedef std::vector<std::string> container_t;
+ container_t mHeaders;
+
+}; // end class HttpHeaders
+
+} // end namespace LLCore
+
+
+#endif // _LLCORE_HTTP_HEADERS_H_
diff --git a/indra/llcorehttp/httpoptions.cpp b/indra/llcorehttp/httpoptions.cpp
new file mode 100755
index 0000000000..1699d19f8d
--- /dev/null
+++ b/indra/llcorehttp/httpoptions.cpp
@@ -0,0 +1,73 @@
+/**
+ * @file httpoptions.cpp
+ * @brief Implementation of the HTTPOptions class
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 "httpoptions.h"
+
+#include "_httpinternal.h"
+
+
+namespace LLCore
+{
+
+
+HttpOptions::HttpOptions()
+ : RefCounted(true),
+ mWantHeaders(false),
+ mTracing(HTTP_TRACE_OFF),
+ mTimeout(HTTP_REQUEST_TIMEOUT_DEFAULT),
+ mRetries(HTTP_RETRY_COUNT_DEFAULT)
+{}
+
+
+HttpOptions::~HttpOptions()
+{}
+
+
+void HttpOptions::setWantHeaders(bool wanted)
+{
+ mWantHeaders = wanted;
+}
+
+
+void HttpOptions::setTrace(long level)
+{
+ mTracing = int(level);
+}
+
+
+void HttpOptions::setTimeout(unsigned int timeout)
+{
+ mTimeout = timeout;
+}
+
+
+void HttpOptions::setRetries(unsigned int retries)
+{
+ mRetries = retries;
+}
+
+
+} // end namespace LLCore
diff --git a/indra/llcorehttp/httpoptions.h b/indra/llcorehttp/httpoptions.h
new file mode 100755
index 0000000000..97e46a8cd3
--- /dev/null
+++ b/indra/llcorehttp/httpoptions.h
@@ -0,0 +1,106 @@
+/**
+ * @file httpoptions.h
+ * @brief Public-facing declarations for the HTTPOptions class
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 _LLCORE_HTTP_OPTIONS_H_
+#define _LLCORE_HTTP_OPTIONS_H_
+
+
+#include "httpcommon.h"
+
+#include "_refcounted.h"
+
+
+namespace LLCore
+{
+
+
+/// Really a struct in spirit, it provides options that
+/// modify HTTP requests.
+///
+/// Sharing instances across requests. It's intended that
+/// these be shared across requests: caller can create one
+/// of these, set it up as needed and then reference it
+/// repeatedly in HTTP operations. But see the Threading
+/// note about references.
+///
+/// Threading: While this class does nothing to ensure thread
+/// safety, it *is* intended to be shared between the application
+/// thread and the worker thread. This means that once an instance
+/// is delivered to the library in request operations, the
+/// option data must not be written until all such requests
+/// complete and relinquish their references.
+///
+/// Allocation: Refcounted, heap only. Caller of the constructor
+/// is given a refcount.
+///
+class HttpOptions : public LLCoreInt::RefCounted
+{
+public:
+ HttpOptions();
+
+protected:
+ virtual ~HttpOptions(); // Use release()
+
+ HttpOptions(const HttpOptions &); // Not defined
+ void operator=(const HttpOptions &); // Not defined
+
+public:
+ void setWantHeaders(bool wanted);
+ bool getWantHeaders() const
+ {
+ return mWantHeaders;
+ }
+
+ void setTrace(int long);
+ int getTrace() const
+ {
+ return mTracing;
+ }
+
+ void setTimeout(unsigned int timeout);
+ unsigned int getTimeout() const
+ {
+ return mTimeout;
+ }
+
+ void setRetries(unsigned int retries);
+ unsigned int getRetries() const
+ {
+ return mRetries;
+ }
+
+protected:
+ bool mWantHeaders;
+ int mTracing;
+ unsigned int mTimeout;
+ unsigned int mRetries;
+
+}; // end class HttpOptions
+
+
+} // end namespace HttpOptions
+
+#endif // _LLCORE_HTTP_OPTIONS_H_
diff --git a/indra/llcorehttp/httprequest.cpp b/indra/llcorehttp/httprequest.cpp
new file mode 100755
index 0000000000..9b739a8825
--- /dev/null
+++ b/indra/llcorehttp/httprequest.cpp
@@ -0,0 +1,504 @@
+/**
+ * @file httprequest.cpp
+ * @brief Implementation of the HTTPRequest class
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 "httprequest.h"
+
+#include "_httprequestqueue.h"
+#include "_httpreplyqueue.h"
+#include "_httpservice.h"
+#include "_httppolicy.h"
+#include "_httpoperation.h"
+#include "_httpoprequest.h"
+#include "_httpopsetpriority.h"
+#include "_httpopcancel.h"
+#include "_httpopsetget.h"
+
+#include "lltimer.h"
+
+
+namespace
+{
+
+bool has_inited(false);
+
+}
+
+namespace LLCore
+{
+
+// ====================================
+// HttpRequest Implementation
+// ====================================
+
+
+HttpRequest::policy_t HttpRequest::sNextPolicyID(1);
+
+
+HttpRequest::HttpRequest()
+ : //HttpHandler(),
+ mReplyQueue(NULL),
+ mRequestQueue(NULL)
+{
+ mRequestQueue = HttpRequestQueue::instanceOf();
+ mRequestQueue->addRef();
+
+ mReplyQueue = new HttpReplyQueue();
+}
+
+
+HttpRequest::~HttpRequest()
+{
+ if (mRequestQueue)
+ {
+ mRequestQueue->release();
+ mRequestQueue = NULL;
+ }
+
+ if (mReplyQueue)
+ {
+ mReplyQueue->release();
+ mReplyQueue = NULL;
+ }
+}
+
+
+// ====================================
+// Policy Methods
+// ====================================
+
+
+HttpStatus HttpRequest::setPolicyGlobalOption(EGlobalPolicy opt, long value)
+{
+ if (HttpService::RUNNING == HttpService::instanceOf()->getState())
+ {
+ return HttpStatus(HttpStatus::LLCORE, HE_OPT_NOT_DYNAMIC);
+ }
+ return HttpService::instanceOf()->getGlobalOptions().set(opt, value);
+}
+
+
+HttpStatus HttpRequest::setPolicyGlobalOption(EGlobalPolicy opt, const std::string & value)
+{
+ if (HttpService::RUNNING == HttpService::instanceOf()->getState())
+ {
+ return HttpStatus(HttpStatus::LLCORE, HE_OPT_NOT_DYNAMIC);
+ }
+ return HttpService::instanceOf()->getGlobalOptions().set(opt, value);
+}
+
+
+HttpRequest::policy_t HttpRequest::createPolicyClass()
+{
+ if (HttpService::RUNNING == HttpService::instanceOf()->getState())
+ {
+ return 0;
+ }
+ return HttpService::instanceOf()->createPolicyClass();
+}
+
+
+HttpStatus HttpRequest::setPolicyClassOption(policy_t policy_id,
+ EClassPolicy opt,
+ long value)
+{
+ if (HttpService::RUNNING == HttpService::instanceOf()->getState())
+ {
+ return HttpStatus(HttpStatus::LLCORE, HE_OPT_NOT_DYNAMIC);
+ }
+ return HttpService::instanceOf()->getClassOptions(policy_id).set(opt, value);
+}
+
+
+// ====================================
+// Request Methods
+// ====================================
+
+
+HttpStatus HttpRequest::getStatus() const
+{
+ return mLastReqStatus;
+}
+
+
+HttpHandle HttpRequest::requestGet(policy_t policy_id,
+ priority_t priority,
+ const std::string & url,
+ HttpOptions * options,
+ HttpHeaders * headers,
+ HttpHandler * user_handler)
+{
+ HttpStatus status;
+ HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID);
+
+ HttpOpRequest * op = new HttpOpRequest();
+ if (! (status = op->setupGet(policy_id, priority, url, options, headers)))
+ {
+ op->release();
+ mLastReqStatus = status;
+ return handle;
+ }
+ op->setReplyPath(mReplyQueue, user_handler);
+ if (! (status = mRequestQueue->addOp(op))) // transfers refcount
+ {
+ op->release();
+ mLastReqStatus = status;
+ return handle;
+ }
+
+ mLastReqStatus = status;
+ handle = static_cast<HttpHandle>(op);
+
+ return handle;
+}
+
+
+HttpHandle HttpRequest::requestGetByteRange(policy_t policy_id,
+ priority_t priority,
+ const std::string & url,
+ size_t offset,
+ size_t len,
+ HttpOptions * options,
+ HttpHeaders * headers,
+ HttpHandler * user_handler)
+{
+ HttpStatus status;
+ HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID);
+
+ HttpOpRequest * op = new HttpOpRequest();
+ if (! (status = op->setupGetByteRange(policy_id, priority, url, offset, len, options, headers)))
+ {
+ op->release();
+ mLastReqStatus = status;
+ return handle;
+ }
+ op->setReplyPath(mReplyQueue, user_handler);
+ if (! (status = mRequestQueue->addOp(op))) // transfers refcount
+ {
+ op->release();
+ mLastReqStatus = status;
+ return handle;
+ }
+
+ mLastReqStatus = status;
+ handle = static_cast<HttpHandle>(op);
+
+ return handle;
+}
+
+
+HttpHandle HttpRequest::requestPost(policy_t policy_id,
+ priority_t priority,
+ const std::string & url,
+ BufferArray * body,
+ HttpOptions * options,
+ HttpHeaders * headers,
+ HttpHandler * user_handler)
+{
+ HttpStatus status;
+ HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID);
+
+ HttpOpRequest * op = new HttpOpRequest();
+ if (! (status = op->setupPost(policy_id, priority, url, body, options, headers)))
+ {
+ op->release();
+ mLastReqStatus = status;
+ return handle;
+ }
+ op->setReplyPath(mReplyQueue, user_handler);
+ if (! (status = mRequestQueue->addOp(op))) // transfers refcount
+ {
+ op->release();
+ mLastReqStatus = status;
+ return handle;
+ }
+
+ mLastReqStatus = status;
+ handle = static_cast<HttpHandle>(op);
+
+ return handle;
+}
+
+
+HttpHandle HttpRequest::requestPut(policy_t policy_id,
+ priority_t priority,
+ const std::string & url,
+ BufferArray * body,
+ HttpOptions * options,
+ HttpHeaders * headers,
+ HttpHandler * user_handler)
+{
+ HttpStatus status;
+ HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID);
+
+ HttpOpRequest * op = new HttpOpRequest();
+ if (! (status = op->setupPut(policy_id, priority, url, body, options, headers)))
+ {
+ op->release();
+ mLastReqStatus = status;
+ return handle;
+ }
+ op->setReplyPath(mReplyQueue, user_handler);
+ if (! (status = mRequestQueue->addOp(op))) // transfers refcount
+ {
+ op->release();
+ mLastReqStatus = status;
+ return handle;
+ }
+
+ mLastReqStatus = status;
+ handle = static_cast<HttpHandle>(op);
+
+ return handle;
+}
+
+
+HttpHandle HttpRequest::requestNoOp(HttpHandler * user_handler)
+{
+ HttpStatus status;
+ HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID);
+
+ HttpOpNull * op = new HttpOpNull();
+ op->setReplyPath(mReplyQueue, user_handler);
+ if (! (status = mRequestQueue->addOp(op))) // transfers refcount
+ {
+ op->release();
+ mLastReqStatus = status;
+ return handle;
+ }
+
+ mLastReqStatus = status;
+ handle = static_cast<HttpHandle>(op);
+
+ return handle;
+}
+
+
+HttpStatus HttpRequest::update(long usecs)
+{
+ HttpOperation * op(NULL);
+
+ if (usecs)
+ {
+ const HttpTime limit(totalTime() + HttpTime(usecs));
+ while (limit >= totalTime() && (op = mReplyQueue->fetchOp()))
+ {
+ // Process operation
+ op->visitNotifier(this);
+
+ // We're done with the operation
+ op->release();
+ }
+ }
+ else
+ {
+ // Same as above, just no time limit
+ HttpReplyQueue::OpContainer replies;
+ mReplyQueue->fetchAll(replies);
+ if (! replies.empty())
+ {
+ for (HttpReplyQueue::OpContainer::iterator iter(replies.begin());
+ replies.end() != iter;
+ ++iter)
+ {
+ // Swap op pointer for NULL;
+ op = *iter; *iter = NULL;
+
+ // Process operation
+ op->visitNotifier(this);
+
+ // We're done with the operation
+ op->release();
+ }
+ }
+ }
+
+ return HttpStatus();
+}
+
+
+
+
+// ====================================
+// Request Management Methods
+// ====================================
+
+HttpHandle HttpRequest::requestCancel(HttpHandle request, HttpHandler * user_handler)
+{
+ HttpStatus status;
+ HttpHandle ret_handle(LLCORE_HTTP_HANDLE_INVALID);
+
+ HttpOpCancel * op = new HttpOpCancel(request);
+ op->setReplyPath(mReplyQueue, user_handler);
+ if (! (status = mRequestQueue->addOp(op))) // transfers refcount
+ {
+ op->release();
+ mLastReqStatus = status;
+ return ret_handle;
+ }
+
+ mLastReqStatus = status;
+ ret_handle = static_cast<HttpHandle>(op);
+
+ return ret_handle;
+}
+
+
+HttpHandle HttpRequest::requestSetPriority(HttpHandle request, priority_t priority,
+ HttpHandler * handler)
+{
+ HttpStatus status;
+ HttpHandle ret_handle(LLCORE_HTTP_HANDLE_INVALID);
+
+ HttpOpSetPriority * op = new HttpOpSetPriority(request, priority);
+ op->setReplyPath(mReplyQueue, handler);
+ if (! (status = mRequestQueue->addOp(op))) // transfers refcount
+ {
+ op->release();
+ mLastReqStatus = status;
+ return ret_handle;
+ }
+
+ mLastReqStatus = status;
+ ret_handle = static_cast<HttpHandle>(op);
+
+ return ret_handle;
+}
+
+
+// ====================================
+// Utility Methods
+// ====================================
+
+HttpStatus HttpRequest::createService()
+{
+ HttpStatus status;
+
+ if (! has_inited)
+ {
+ HttpRequestQueue::init();
+ HttpRequestQueue * rq = HttpRequestQueue::instanceOf();
+ HttpService::init(rq);
+ has_inited = true;
+ }
+
+ return status;
+}
+
+
+HttpStatus HttpRequest::destroyService()
+{
+ HttpStatus status;
+
+ if (has_inited)
+ {
+ HttpService::term();
+ HttpRequestQueue::term();
+ has_inited = false;
+ }
+
+ return status;
+}
+
+
+HttpStatus HttpRequest::startThread()
+{
+ HttpStatus status;
+
+ HttpService::instanceOf()->startThread();
+
+ return status;
+}
+
+
+HttpHandle HttpRequest::requestStopThread(HttpHandler * user_handler)
+{
+ HttpStatus status;
+ HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID);
+
+ HttpOpStop * op = new HttpOpStop();
+ op->setReplyPath(mReplyQueue, user_handler);
+ if (! (status = mRequestQueue->addOp(op))) // transfers refcount
+ {
+ op->release();
+ mLastReqStatus = status;
+ return handle;
+ }
+
+ mLastReqStatus = status;
+ handle = static_cast<HttpHandle>(op);
+
+ return handle;
+}
+
+
+HttpHandle HttpRequest::requestSpin(int mode)
+{
+ HttpStatus status;
+ HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID);
+
+ HttpOpSpin * op = new HttpOpSpin(mode);
+ op->setReplyPath(mReplyQueue, NULL);
+ if (! (status = mRequestQueue->addOp(op))) // transfers refcount
+ {
+ op->release();
+ mLastReqStatus = status;
+ return handle;
+ }
+
+ mLastReqStatus = status;
+ handle = static_cast<HttpHandle>(op);
+
+ return handle;
+}
+
+// ====================================
+// Dynamic Policy Methods
+// ====================================
+
+HttpHandle HttpRequest::requestSetHttpProxy(const std::string & proxy, HttpHandler * handler)
+{
+ HttpStatus status;
+ HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID);
+
+ HttpOpSetGet * op = new HttpOpSetGet();
+ op->setupSet(GP_HTTP_PROXY, proxy);
+ op->setReplyPath(mReplyQueue, handler);
+ if (! (status = mRequestQueue->addOp(op))) // transfers refcount
+ {
+ op->release();
+ mLastReqStatus = status;
+ return handle;
+ }
+
+ mLastReqStatus = status;
+ handle = static_cast<HttpHandle>(op);
+
+ return handle;
+}
+
+
+} // end namespace LLCore
+
diff --git a/indra/llcorehttp/httprequest.h b/indra/llcorehttp/httprequest.h
new file mode 100755
index 0000000000..ab2f302d34
--- /dev/null
+++ b/indra/llcorehttp/httprequest.h
@@ -0,0 +1,535 @@
+/**
+ * @file httprequest.h
+ * @brief Public-facing declarations for HttpRequest class
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 _LLCORE_HTTP_REQUEST_H_
+#define _LLCORE_HTTP_REQUEST_H_
+
+
+#include "httpcommon.h"
+#include "httphandler.h"
+
+
+namespace LLCore
+{
+
+class HttpRequestQueue;
+class HttpReplyQueue;
+class HttpService;
+class HttpOptions;
+class HttpHeaders;
+class HttpOperation;
+class BufferArray;
+
+/// HttpRequest supplies the entry into the HTTP transport
+/// services in the LLCore libraries. Services provided include:
+///
+/// - Some, but not all, global initialization of libcurl.
+/// - Starting asynchronous, threaded HTTP requests.
+/// - Definition of policy classes affect request handling.
+/// - Utilities to control request options and headers
+///
+/// Requests
+///
+/// The class supports the current HTTP request operations:
+///
+/// - requestGetByteRange: GET with Range header for a single range of bytes
+///
+/// Policy Classes
+///
+/// <TBD>
+///
+/// Usage
+///
+/// <TBD>
+///
+/// Threading: An instance may only be used by one application/
+/// consumer thread. But a thread may have as many instances of
+/// this as it likes.
+///
+/// Allocation: Not refcounted, may be stack allocated though that
+/// hasn't been tested. Queued requests can still run and any
+/// queued replies will keep refcounts to the reply queue leading
+/// to memory leaks.
+///
+/// @pre Before using this class (static or instances), some global
+/// initialization is required. See @see httpcommon.h for more information.
+///
+/// @nosubgrouping
+///
+
+class HttpRequest
+{
+public:
+ HttpRequest();
+ virtual ~HttpRequest();
+
+private:
+ HttpRequest(const HttpRequest &); // Disallowed
+ void operator=(const HttpRequest &); // Disallowed
+
+public:
+ typedef unsigned int policy_t;
+ typedef unsigned int priority_t;
+
+public:
+ /// @name PolicyMethods
+ /// @{
+
+ /// Represents a default, catch-all policy class that guarantees
+ /// eventual service for any HTTP request.
+ static const int DEFAULT_POLICY_ID = 0;
+
+ enum EGlobalPolicy
+ {
+ /// Maximum number of connections the library will use to
+ /// perform operations. This is somewhat soft as the underlying
+ /// transport will cache some connections (up to 5).
+
+ /// A long value setting the maximum number of connections
+ /// allowed over all policy classes. Note that this will be
+ /// a somewhat soft value. There may be an additional five
+ /// connections per policy class depending upon runtime
+ /// behavior.
+ GP_CONNECTION_LIMIT,
+
+ /// String containing a system-appropriate directory name
+ /// where SSL certs are stored.
+ GP_CA_PATH,
+
+ /// String giving a full path to a file containing SSL certs.
+ GP_CA_FILE,
+
+ /// String of host/port to use as simple HTTP proxy. This is
+ /// going to change in the future into something more elaborate
+ /// that may support richer schemes.
+ GP_HTTP_PROXY,
+
+ /// Long value that if non-zero enables the use of the
+ /// traditional LLProxy code for http/socks5 support. If
+ /// enabled, has priority over GP_HTTP_PROXY.
+ GP_LLPROXY,
+
+ /// Long value setting the logging trace level for the
+ /// library. Possible values are:
+ /// 0 - No tracing (default)
+ /// 1 - Basic tracing of request start, stop and major events.
+ /// 2 - Connection, header and payload size information from
+ /// HTTP transactions.
+ /// 3 - Partial logging of payload itself.
+ ///
+ /// These values are also used in the trace modes for
+ /// individual requests in HttpOptions. Also be aware that
+ /// tracing tends to impact performance of the viewer.
+ GP_TRACE
+ };
+
+ /// Set a parameter on a global policy option. Calls
+ /// made after the start of the servicing thread are
+ /// not honored and return an error status.
+ ///
+ /// @param opt Enum of option to be set.
+ /// @param value Desired value of option.
+ /// @return Standard status code.
+ static HttpStatus setPolicyGlobalOption(EGlobalPolicy opt, long value);
+ static HttpStatus setPolicyGlobalOption(EGlobalPolicy opt, const std::string & value);
+
+ /// Create a new policy class into which requests can be made.
+ ///
+ /// @return If positive, the policy_id used to reference
+ /// the class in other methods. If 0, an error
+ /// occurred and @see getStatus() may provide more
+ /// detail on the reason.
+ static policy_t createPolicyClass();
+
+ enum EClassPolicy
+ {
+ /// Limits the number of connections used for the class.
+ CP_CONNECTION_LIMIT,
+
+ /// Limits the number of connections used for a single
+ /// literal address/port pair within the class.
+ CP_PER_HOST_CONNECTION_LIMIT,
+
+ /// Suitable requests are allowed to pipeline on their
+ /// connections when they ask for it.
+ CP_ENABLE_PIPELINING
+ };
+
+ /// Set a parameter on a class-based policy option. Calls
+ /// made after the start of the servicing thread are
+ /// not honored and return an error status.
+ ///
+ /// @param policy_id ID of class as returned by @see createPolicyClass().
+ /// @param opt Enum of option to be set.
+ /// @param value Desired value of option.
+ /// @return Standard status code.
+ static HttpStatus setPolicyClassOption(policy_t policy_id, EClassPolicy opt, long value);
+
+ /// @}
+
+ /// @name RequestMethods
+ ///
+ /// @{
+
+ /// Some calls expect to succeed as the normal part of operation and so
+ /// return a useful value rather than a status. When they do fail, the
+ /// status is saved and can be fetched with this method.
+ ///
+ /// @return Status of the failing method invocation. If the
+ /// preceding call succeeded or other HttpStatus
+ /// returning calls immediately preceded this method,
+ /// the returned value may not be reliable.
+ ///
+ HttpStatus getStatus() const;
+
+ /// Queue a full HTTP GET request to be issued for entire entity.
+ /// The request is queued and serviced by the working thread and
+ /// notification of completion delivered to the optional HttpHandler
+ /// argument during @see update() calls.
+ ///
+ /// With a valid handle returned, it can be used to reference the
+ /// request in other requests (like cancellation) and will be an
+ /// argument when any HttpHandler object is invoked.
+ ///
+ /// Headers supplied by default:
+ /// - Connection: keep-alive
+ /// - Accept: */*
+ /// - Accept-Encoding: deflate, gzip
+ /// - Keep-alive: 300
+ /// - Host: <stuff>
+ ///
+ /// Some headers excluded by default:
+ /// - Pragma:
+ /// - Cache-control:
+ /// - Range:
+ /// - Transfer-Encoding:
+ /// - Referer:
+ ///
+ /// @param policy_id Default or user-defined policy class under
+ /// which this request is to be serviced.
+ /// @param priority Standard priority scheme inherited from
+ /// Indra code base (U32-type scheme).
+ /// @param url URL with any encoded query parameters to
+ /// be accessed.
+ /// @param options Optional instance of an HttpOptions object
+ /// to provide additional controls over the request
+ /// function for this request only. Any such
+ /// object then becomes shared-read across threads
+ /// and no code should modify the HttpOptions
+ /// instance.
+ /// @param headers Optional instance of an HttpHeaders object
+ /// to provide additional and/or overridden
+ /// headers for the request. As with options,
+ /// the instance becomes shared-read across threads
+ /// and no code should modify the HttpHeaders
+ /// instance.
+ /// @param handler Optional pointer to an HttpHandler instance
+ /// whose onCompleted() method will be invoked
+ /// during calls to update(). This is a non-
+ /// reference-counted object which would be a
+ /// problem for shutdown and other edge cases but
+ /// the pointer is only dereferenced during
+ /// calls to update().
+ ///
+ /// @return The handle of the request if successfully
+ /// queued or LLCORE_HTTP_HANDLE_INVALID if the
+ /// request could not be queued. In the latter
+ /// case, @see getStatus() will return more info.
+ ///
+ HttpHandle requestGet(policy_t policy_id,
+ priority_t priority,
+ const std::string & url,
+ HttpOptions * options,
+ HttpHeaders * headers,
+ HttpHandler * handler);
+
+
+ /// Queue a full HTTP GET request to be issued with a 'Range' header.
+ /// The request is queued and serviced by the working thread and
+ /// notification of completion delivered to the optional HttpHandler
+ /// argument during @see update() calls.
+ ///
+ /// With a valid handle returned, it can be used to reference the
+ /// request in other requests (like cancellation) and will be an
+ /// argument when any HttpHandler object is invoked.
+ ///
+ /// Headers supplied by default:
+ /// - Connection: keep-alive
+ /// - Accept: */*
+ /// - Accept-Encoding: deflate, gzip
+ /// - Keep-alive: 300
+ /// - Host: <stuff>
+ /// - Range: <stuff> (will be omitted if offset == 0 and len == 0)
+ ///
+ /// Some headers excluded by default:
+ /// - Pragma:
+ /// - Cache-control:
+ /// - Transfer-Encoding:
+ /// - Referer:
+ ///
+ /// @param policy_id @see requestGet()
+ /// @param priority "
+ /// @param url "
+ /// @param offset Offset of first byte into resource to be returned.
+ /// @param len Count of bytes to be returned
+ /// @param options @see requestGet()
+ /// @param headers "
+ /// @param handler "
+ /// @return "
+ ///
+ HttpHandle requestGetByteRange(policy_t policy_id,
+ priority_t priority,
+ const std::string & url,
+ size_t offset,
+ size_t len,
+ HttpOptions * options,
+ HttpHeaders * headers,
+ HttpHandler * handler);
+
+
+ /// Queue a full HTTP POST. Query arguments and body may
+ /// be provided. Caller is responsible for escaping and
+ /// encoding and communicating the content types.
+ ///
+ /// Headers supplied by default:
+ /// - Connection: keep-alive
+ /// - Accept: */*
+ /// - Accept-Encoding: deflate, gzip
+ /// - Keep-Alive: 300
+ /// - Host: <stuff>
+ /// - Content-Length: <digits>
+ /// - Content-Type: application/x-www-form-urlencoded
+ ///
+ /// Some headers excluded by default:
+ /// - Pragma:
+ /// - Cache-Control:
+ /// - Transfer-Encoding: ... chunked ...
+ /// - Referer:
+ /// - Content-Encoding:
+ /// - Expect:
+ ///
+ /// @param policy_id @see requestGet()
+ /// @param priority "
+ /// @param url "
+ /// @param body Byte stream to be sent as the body. No
+ /// further encoding or escaping will be done
+ /// to the content.
+ /// @param options @see requestGet()K(optional)
+ /// @param headers "
+ /// @param handler "
+ /// @return "
+ ///
+ HttpHandle requestPost(policy_t policy_id,
+ priority_t priority,
+ const std::string & url,
+ BufferArray * body,
+ HttpOptions * options,
+ HttpHeaders * headers,
+ HttpHandler * handler);
+
+
+ /// Queue a full HTTP PUT. Query arguments and body may
+ /// be provided. Caller is responsible for escaping and
+ /// encoding and communicating the content types.
+ ///
+ /// Headers supplied by default:
+ /// - Connection: keep-alive
+ /// - Accept: */*
+ /// - Accept-Encoding: deflate, gzip
+ /// - Keep-Alive: 300
+ /// - Host: <stuff>
+ /// - Content-Length: <digits>
+ ///
+ /// Some headers excluded by default:
+ /// - Pragma:
+ /// - Cache-Control:
+ /// - Transfer-Encoding: ... chunked ...
+ /// - Referer:
+ /// - Content-Encoding:
+ /// - Expect:
+ /// - Content-Type:
+ ///
+ /// @param policy_id @see requestGet()
+ /// @param priority "
+ /// @param url "
+ /// @param body Byte stream to be sent as the body. No
+ /// further encoding or escaping will be done
+ /// to the content.
+ /// @param options @see requestGet()K(optional)
+ /// @param headers "
+ /// @param handler "
+ /// @return "
+ ///
+ HttpHandle requestPut(policy_t policy_id,
+ priority_t priority,
+ const std::string & url,
+ BufferArray * body,
+ HttpOptions * options,
+ HttpHeaders * headers,
+ HttpHandler * handler);
+
+
+ /// Queue a NoOp request.
+ /// The request is queued and serviced by the working thread which
+ /// immediately processes it and returns the request to the reply
+ /// queue.
+ ///
+ /// @param handler @see requestGet()
+ /// @return "
+ ///
+ HttpHandle requestNoOp(HttpHandler * handler);
+
+ /// While all the heavy work is done by the worker thread, notifications
+ /// must be performed in the context of the application thread. These
+ /// are done synchronously during calls to this method which gives the
+ /// library control so notification can be performed. Application handlers
+ /// are expected to return 'quickly' and do any significant processing
+ /// outside of the notification callback to onCompleted().
+ ///
+ /// @param usecs Maximum number of wallclock microseconds to
+ /// spend in the call. As hinted at above, this
+ /// is partly a function of application code so it's
+ /// a soft limit. A '0' value will run without
+ /// time limit until everything queued has been
+ /// delivered.
+ ///
+ /// @return Standard status code.
+ HttpStatus update(long usecs);
+
+ /// @}
+
+ /// @name RequestMgmtMethods
+ ///
+ /// @{
+
+ HttpHandle requestCancel(HttpHandle request, HttpHandler *);
+
+ /// Request that a previously-issued request be reprioritized.
+ /// The status of whether the change itself succeeded arrives
+ /// via notification.
+ ///
+ /// @param request Handle of previously-issued request to
+ /// be changed.
+ /// @param priority New priority value.
+ /// @param handler @see requestGet()
+ /// @return "
+ ///
+ HttpHandle requestSetPriority(HttpHandle request, priority_t priority, HttpHandler * handler);
+
+ /// @}
+
+ /// @name UtilityMethods
+ ///
+ /// @{
+
+ /// Initialization method that needs to be called before queueing any
+ /// requests. Doesn't start the worker thread and may be called befoer
+ /// or after policy setup.
+ static HttpStatus createService();
+
+ /// Mostly clean shutdown of services prior to exit. Caller is expected
+ /// to have stopped a running worker thread before calling this.
+ static HttpStatus destroyService();
+
+ /// Called once after @see createService() to start the worker thread.
+ /// Stopping the thread is achieved by requesting it via @see requestStopThread().
+ /// May be called before or after requests are issued.
+ static HttpStatus startThread();
+
+ /// Queues a request to the worker thread to have it stop processing
+ /// and exit (without exiting the program). When the operation is
+ /// picked up by the worker thread, it immediately processes it and
+ /// begins detaching from refcounted resources like request and
+ /// reply queues and then returns to the host OS. It *does* queue a
+ /// reply to give the calling application thread a notification that
+ /// the operation has been performed.
+ ///
+ /// @param handler (optional)
+ /// @return The handle of the request if successfully
+ /// queued or LLCORE_HTTP_HANDLE_INVALID if the
+ /// request could not be queued. In the latter
+ /// case, @see getStatus() will return more info.
+ /// As the request cannot be cancelled, the handle
+ /// is generally not useful.
+ ///
+ HttpHandle requestStopThread(HttpHandler * handler);
+
+ /// Queue a Spin request.
+ /// DEBUG/TESTING ONLY. This puts the worker into a CPU spin for
+ /// test purposes.
+ ///
+ /// @param mode 0 for hard spin, 1 for soft spin
+ /// @return Standard handle return cases.
+ ///
+ HttpHandle requestSpin(int mode);
+
+ /// @}
+
+ /// @name DynamicPolicyMethods
+ ///
+ /// @{
+
+ /// Request that a running transport pick up a new proxy setting.
+ /// An empty string will indicate no proxy is to be used.
+ HttpHandle requestSetHttpProxy(const std::string & proxy, HttpHandler * handler);
+
+ /// @}
+
+protected:
+ void generateNotification(HttpOperation * op);
+
+private:
+ /// @name InstanceData
+ ///
+ /// @{
+ HttpStatus mLastReqStatus;
+ HttpReplyQueue * mReplyQueue;
+ HttpRequestQueue * mRequestQueue;
+
+ /// @}
+
+ // ====================================
+ /// @name GlobalState
+ ///
+ /// @{
+ ///
+ /// Must be established before any threading is allowed to
+ /// start.
+ ///
+ static policy_t sNextPolicyID;
+
+ /// @}
+ // End Global State
+ // ====================================
+
+}; // end class HttpRequest
+
+
+} // end namespace LLCore
+
+
+
+#endif // _LLCORE_HTTP_REQUEST_H_
diff --git a/indra/llcorehttp/httpresponse.cpp b/indra/llcorehttp/httpresponse.cpp
new file mode 100755
index 0000000000..a552e48a1b
--- /dev/null
+++ b/indra/llcorehttp/httpresponse.cpp
@@ -0,0 +1,91 @@
+/**
+ * @file httpresponse.cpp
+ * @brief
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 "httpresponse.h"
+#include "bufferarray.h"
+#include "httpheaders.h"
+
+
+namespace LLCore
+{
+
+
+HttpResponse::HttpResponse()
+ : LLCoreInt::RefCounted(true),
+ mReplyOffset(0U),
+ mReplyLength(0U),
+ mReplyFullLength(0U),
+ mBufferArray(NULL),
+ mHeaders(NULL)
+{}
+
+
+HttpResponse::~HttpResponse()
+{
+ setBody(NULL);
+ setHeaders(NULL);
+}
+
+
+void HttpResponse::setBody(BufferArray * ba)
+{
+ if (mBufferArray == ba)
+ return;
+
+ if (mBufferArray)
+ {
+ mBufferArray->release();
+ }
+
+ if (ba)
+ {
+ ba->addRef();
+ }
+
+ mBufferArray = ba;
+}
+
+
+void HttpResponse::setHeaders(HttpHeaders * headers)
+{
+ if (mHeaders == headers)
+ return;
+
+ if (mHeaders)
+ {
+ mHeaders->release();
+ }
+
+ if (headers)
+ {
+ headers->addRef();
+ }
+
+ mHeaders = headers;
+}
+
+
+} // end namespace LLCore
diff --git a/indra/llcorehttp/httpresponse.h b/indra/llcorehttp/httpresponse.h
new file mode 100755
index 0000000000..f19b521fbf
--- /dev/null
+++ b/indra/llcorehttp/httpresponse.h
@@ -0,0 +1,166 @@
+/**
+ * @file httpresponse.h
+ * @brief Public-facing declarations for the HttpResponse class
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 _LLCORE_HTTP_RESPONSE_H_
+#define _LLCORE_HTTP_RESPONSE_H_
+
+
+#include <string>
+
+#include "httpcommon.h"
+
+#include "_refcounted.h"
+
+
+namespace LLCore
+{
+
+class BufferArray;
+class HttpHeaders;
+
+/// HttpResponse is instantiated by the library and handed to
+/// the caller during callbacks to the handler. It supplies
+/// all the status, header and HTTP body data the caller is
+/// interested in. Methods provide simple getters to return
+/// individual pieces of the response.
+///
+/// Typical usage will have the caller interrogate the object
+/// during the handler callback and then simply returning.
+/// But instances are refcounted and and callers can add a
+/// reference and hold onto the object after the callback.
+///
+/// Threading: Not intrinsically thread-safe.
+///
+/// Allocation: Refcounted, heap only. Caller of the constructor
+/// is given a refcount.
+///
+class HttpResponse : public LLCoreInt::RefCounted
+{
+public:
+ HttpResponse();
+
+protected:
+ virtual ~HttpResponse(); // Use release()
+
+ HttpResponse(const HttpResponse &); // Not defined
+ void operator=(const HttpResponse &); // Not defined
+
+public:
+ /// Returns the final status of the requested operation.
+ ///
+ HttpStatus getStatus() const
+ {
+ return mStatus;
+ }
+
+ void setStatus(const HttpStatus & status)
+ {
+ mStatus = status;
+ }
+
+ /// Simple getter for the response body returned as a scatter/gather
+ /// buffer. If the operation doesn't produce data (such as the Null
+ /// or StopThread operations), this may be NULL.
+ ///
+ /// Caller can hold onto the response by incrementing the reference
+ /// count of the returned object.
+ BufferArray * getBody() const
+ {
+ return mBufferArray;
+ }
+
+ /// Set the response data in the instance. Will drop the reference
+ /// count to any existing data and increment the count of that passed
+ /// in. It is legal to set the data to NULL.
+ void setBody(BufferArray * ba);
+
+ /// And a getter for the headers. And as with @see getResponse(),
+ /// if headers aren't available because the operation doesn't produce
+ /// any or delivery of headers wasn't requested in the options, this
+ /// will be NULL.
+ ///
+ /// Caller can hold onto the headers by incrementing the reference
+ /// count of the returned object.
+ HttpHeaders * getHeaders() const
+ {
+ return mHeaders;
+ }
+
+ /// Behaves like @see setResponse() but for header data.
+ void setHeaders(HttpHeaders * headers);
+
+ /// If a 'Range:' header was used, these methods are involved
+ /// in setting and returning data about the actual response.
+ /// If both @offset and @length are returned as 0, we probably
+ /// didn't get a Content-Range header in the response. This
+ /// occurs with various Capabilities-based services and the
+ /// caller is going to have to make assumptions on receipt of
+ /// a 206 status. The @full value may also be zero in cases of
+ /// parsing problems or a wild-carded length response.
+ ///
+ /// These values will not necessarily agree with the data in
+ /// the body itself (if present). The BufferArray object
+ /// is authoritative for actual data length.
+ void getRange(unsigned int * offset, unsigned int * length, unsigned int * full) const
+ {
+ *offset = mReplyOffset;
+ *length = mReplyLength;
+ *full = mReplyFullLength;
+ }
+
+ void setRange(unsigned int offset, unsigned int length, unsigned int full_length)
+ {
+ mReplyOffset = offset;
+ mReplyLength = length;
+ mReplyFullLength = full_length;
+ }
+
+ ///
+ const std::string & getContentType() const
+ {
+ return mContentType;
+ }
+
+ void setContentType(const std::string & con_type)
+ {
+ mContentType = con_type;
+ }
+
+protected:
+ // Response data here
+ HttpStatus mStatus;
+ unsigned int mReplyOffset;
+ unsigned int mReplyLength;
+ unsigned int mReplyFullLength;
+ BufferArray * mBufferArray;
+ HttpHeaders * mHeaders;
+ std::string mContentType;
+};
+
+
+} // end namespace LLCore
+
+#endif // _LLCORE_HTTP_RESPONSE_H_
diff --git a/indra/llcorehttp/tests/llcorehttp_test.cpp b/indra/llcorehttp/tests/llcorehttp_test.cpp
new file mode 100755
index 0000000000..e863ddd13f
--- /dev/null
+++ b/indra/llcorehttp/tests/llcorehttp_test.cpp
@@ -0,0 +1,175 @@
+/**
+ * @file llcorehttp_test
+ * @brief Main test runner
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 "llcorehttp_test.h"
+
+#include <iostream>
+#include <sstream>
+
+// These are not the right way in viewer for some reason:
+// #include <tut/tut.hpp>
+// #include <tut/tut_reporter.hpp>
+// This works:
+#include "../test/lltut.h"
+
+// Pull in each of the test sets
+#include "test_bufferarray.hpp"
+#include "test_bufferstream.hpp"
+#include "test_httpstatus.hpp"
+#include "test_refcounted.hpp"
+#include "test_httpoperation.hpp"
+#include "test_httprequest.hpp"
+#include "test_httpheaders.hpp"
+#include "test_httprequestqueue.hpp"
+
+#include "llproxy.h"
+
+unsigned long ssl_thread_id_callback(void);
+void ssl_locking_callback(int mode, int type, const char * file, int line);
+
+#if 0 // lltut provides main and runner
+
+namespace tut
+{
+ test_runner_singleton runner;
+}
+
+int main()
+{
+ curl_global_init(CURL_GLOBAL_ALL);
+
+ // *FIXME: Need threaded/SSL curl setup here.
+
+ tut::reporter reporter;
+
+ tut::runner.get().set_callback(&reporter);
+ tut::runner.get().run_tests();
+ return !reporter.all_ok();
+
+ curl_global_cleanup();
+}
+
+#endif // 0
+
+int ssl_mutex_count(0);
+LLCoreInt::HttpMutex ** ssl_mutex_list = NULL;
+
+void init_curl()
+{
+ curl_global_init(CURL_GLOBAL_ALL);
+
+ ssl_mutex_count = CRYPTO_num_locks();
+ if (ssl_mutex_count > 0)
+ {
+ ssl_mutex_list = new LLCoreInt::HttpMutex * [ssl_mutex_count];
+
+ for (int i(0); i < ssl_mutex_count; ++i)
+ {
+ ssl_mutex_list[i] = new LLCoreInt::HttpMutex;
+ }
+
+ CRYPTO_set_locking_callback(ssl_locking_callback);
+ CRYPTO_set_id_callback(ssl_thread_id_callback);
+ }
+
+ LLProxy::getInstance();
+}
+
+
+void term_curl()
+{
+ LLProxy::cleanupClass();
+
+ CRYPTO_set_locking_callback(NULL);
+ for (int i(0); i < ssl_mutex_count; ++i)
+ {
+ delete ssl_mutex_list[i];
+ }
+ delete [] ssl_mutex_list;
+}
+
+
+unsigned long ssl_thread_id_callback(void)
+{
+#if defined(WIN32)
+ return (unsigned long) GetCurrentThread();
+#else
+ return (unsigned long) pthread_self();
+#endif
+}
+
+
+void ssl_locking_callback(int mode, int type, const char * /* file */, int /* line */)
+{
+ if (type >= 0 && type < ssl_mutex_count)
+ {
+ if (mode & CRYPTO_LOCK)
+ {
+ ssl_mutex_list[type]->lock();
+ }
+ else
+ {
+ ssl_mutex_list[type]->unlock();
+ }
+ }
+}
+
+
+std::string get_base_url()
+{
+ const char * env(getenv("LL_TEST_PORT"));
+
+ if (! env)
+ {
+ std::cerr << "LL_TEST_PORT environment variable missing." << std::endl;
+ std::cerr << "Test expects to run in test_llcorehttp_peer.py script." << std::endl;
+ tut::ensure("LL_TEST_PORT set in environment", NULL != env);
+ }
+
+ int port(atoi(env));
+ std::ostringstream out;
+ out << "http://localhost:" << port << "/";
+ return out.str();
+}
+
+
+void stop_thread(LLCore::HttpRequest * req)
+{
+ if (req)
+ {
+ req->requestStopThread(NULL);
+
+ int count = 0;
+ int limit = 10;
+ while (count++ < limit && ! HttpService::isStopped())
+ {
+ req->update(1000);
+ usleep(100000);
+ }
+ }
+}
+
+
diff --git a/indra/llcorehttp/tests/llcorehttp_test.h b/indra/llcorehttp/tests/llcorehttp_test.h
new file mode 100755
index 0000000000..a9567435ce
--- /dev/null
+++ b/indra/llcorehttp/tests/llcorehttp_test.h
@@ -0,0 +1,64 @@
+/**
+ * @file llcorehttp_test.h
+ * @brief Main test runner
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 _LLCOREHTTP_TEST_H_
+#define _LLCOREHTTP_TEST_H_
+
+#include "linden_common.h" // Modifies curl interfaces
+
+#include <curl/curl.h>
+#include <openssl/crypto.h>
+#include <string>
+
+#include "httprequest.h"
+
+// Initialization and cleanup for libcurl. Mainly provides
+// a mutex callback for SSL and a thread ID hash for libcurl.
+// If you don't use these (or equivalent) and do use libcurl,
+// you'll see stalls and other anomalies when performing curl
+// operations.
+extern void init_curl();
+extern void term_curl();
+extern std::string get_base_url();
+extern void stop_thread(LLCore::HttpRequest * req);
+
+class ScopedCurlInit
+{
+public:
+ ScopedCurlInit()
+ {
+ init_curl();
+ }
+
+ ~ScopedCurlInit()
+ {
+ term_curl();
+ }
+};
+
+
+#endif // _LLCOREHTTP_TEST_H_
diff --git a/indra/llcorehttp/tests/test_allocator.cpp b/indra/llcorehttp/tests/test_allocator.cpp
new file mode 100755
index 0000000000..ea12dc58eb
--- /dev/null
+++ b/indra/llcorehttp/tests/test_allocator.cpp
@@ -0,0 +1,184 @@
+/**
+ * @file test_allocator.cpp
+ * @brief quick and dirty allocator for tracking memory allocations
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 "test_allocator.h"
+
+#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1050
+#include <libkern/OSAtomic.h>
+#elif defined(_MSC_VER)
+#include <Windows.h>
+#elif (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__ ) > 40100
+// atomic extensions are built into GCC on posix platforms
+#endif
+
+#include <cassert>
+#include <cstdlib>
+#include <cstring>
+#include <vector>
+#include <iostream>
+#include <new>
+
+#include <boost/thread.hpp>
+
+
+#if defined(WIN32)
+#define THROW_BAD_ALLOC() _THROW1(std::bad_alloc)
+#define THROW_NOTHING() _THROW0()
+#else
+#define THROW_BAD_ALLOC() throw(std::bad_alloc)
+#define THROW_NOTHING() throw()
+#endif
+
+
+struct BlockHeader
+{
+ struct Block * next;
+ std::size_t size;
+ bool in_use;
+};
+
+struct Block
+{
+ BlockHeader hdr;
+ unsigned char data[1];
+};
+
+#define TRACE_MSG(val) std::cout << __FUNCTION__ << "(" << val << ") [" << __FILE__ << ":" << __LINE__ << "]" << std::endl;
+
+static unsigned char MemBuf[ 4096 * 1024 ];
+Block * pNext = static_cast<Block *>(static_cast<void *>(MemBuf));
+volatile std::size_t MemTotal = 0;
+
+// cross-platform compare and swap operation
+static bool CAS(void * volatile * ptr, void * expected, void * new_value)
+{
+#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1050
+ return OSAtomicCompareAndSwapPtr( expected, new_value, ptr );
+#elif defined(_MSC_VER)
+ return expected == InterlockedCompareExchangePointer( ptr, new_value, expected );
+#elif (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__ ) > 40100
+ return __sync_bool_compare_and_swap( ptr, expected, new_value );
+#endif
+}
+
+static void * GetMem(std::size_t size)
+{
+ // TRACE_MSG(size);
+ volatile Block * pBlock = NULL;
+ volatile Block * pNewNext = NULL;
+
+ // do a lock-free update of the global next pointer
+ do
+ {
+ pBlock = pNext;
+ pNewNext = (volatile Block *)(pBlock->data + size);
+
+ } while(! CAS((void * volatile *) &pNext, (void *) pBlock, (void *) pNewNext));
+
+ // if we get here, we safely carved out a block of memory in the
+ // memory pool...
+
+ // initialize our block
+ pBlock->hdr.next = (Block *)(pBlock->data + size);
+ pBlock->hdr.size = size;
+ pBlock->hdr.in_use = true;
+ memset((void *) pBlock->data, 0, pBlock->hdr.size);
+
+ // do a lock-free update of the global memory total
+ volatile size_t total = 0;
+ volatile size_t new_total = 0;
+ do
+ {
+ total = MemTotal;
+ new_total = total + size;
+
+ } while (! CAS((void * volatile *) &MemTotal, (void *) total, (void *) new_total));
+
+ return (void *) pBlock->data;
+}
+
+
+static void FreeMem(void * p)
+{
+ // get the pointer to the block record
+ Block * pBlock = (Block *)((unsigned char *) p - sizeof(BlockHeader));
+
+ // TRACE_MSG(pBlock->hdr.size);
+ bool * cur_in_use = &(pBlock->hdr.in_use);
+ volatile bool in_use = false;
+ bool new_in_use = false;
+ do
+ {
+ in_use = pBlock->hdr.in_use;
+ } while (! CAS((void * volatile *) cur_in_use, (void *) in_use, (void *) new_in_use));
+
+ // do a lock-free update of the global memory total
+ volatile size_t total = 0;
+ volatile size_t new_total = 0;
+ do
+ {
+ total = MemTotal;
+ new_total = total - pBlock->hdr.size;
+ } while (! CAS((void * volatile *)&MemTotal, (void *) total, (void *) new_total));
+}
+
+
+std::size_t GetMemTotal()
+{
+ return MemTotal;
+}
+
+
+void * operator new(std::size_t size) THROW_BAD_ALLOC()
+{
+ return GetMem( size );
+}
+
+
+void * operator new[](std::size_t size) THROW_BAD_ALLOC()
+{
+ return GetMem( size );
+}
+
+
+void operator delete(void * p) THROW_NOTHING()
+{
+ if (p)
+ {
+ FreeMem( p );
+ }
+}
+
+
+void operator delete[](void * p) THROW_NOTHING()
+{
+ if (p)
+ {
+ FreeMem( p );
+ }
+}
+
+
diff --git a/indra/llcorehttp/tests/test_allocator.h b/indra/llcorehttp/tests/test_allocator.h
new file mode 100755
index 0000000000..3572bbc5c5
--- /dev/null
+++ b/indra/llcorehttp/tests/test_allocator.h
@@ -0,0 +1,47 @@
+/**
+ * @file test_allocator.h
+ * @brief quick and dirty allocator for tracking memory allocations
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 TEST_ALLOCATOR_H
+#define TEST_ALLOCATOR_H
+
+#include <cstdlib>
+#include <new>
+
+size_t GetMemTotal();
+#if defined(WIN32)
+void * operator new(std::size_t size) _THROW1(std::bad_alloc);
+void * operator new[](std::size_t size) _THROW1(std::bad_alloc);
+void operator delete(void * p) _THROW0();
+void operator delete[](void * p) _THROW0();
+#else
+void * operator new(std::size_t size) throw (std::bad_alloc);
+void * operator new[](std::size_t size) throw (std::bad_alloc);
+void operator delete(void * p) throw ();
+void operator delete[](void * p) throw ();
+#endif
+
+#endif // TEST_ALLOCATOR_H
+
diff --git a/indra/llcorehttp/tests/test_bufferarray.hpp b/indra/llcorehttp/tests/test_bufferarray.hpp
new file mode 100755
index 0000000000..8a2a64d970
--- /dev/null
+++ b/indra/llcorehttp/tests/test_bufferarray.hpp
@@ -0,0 +1,432 @@
+/**
+ * @file test_bufferarray.hpp
+ * @brief unit tests for the LLCore::BufferArray class
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 TEST_LLCORE_BUFFER_ARRAY_H_
+#define TEST_LLCORE_BUFFER_ARRAY_H_
+
+#include "bufferarray.h"
+
+#include <iostream>
+
+#include "test_allocator.h"
+
+
+using namespace LLCore;
+
+
+
+namespace tut
+{
+
+struct BufferArrayTestData
+{
+ // the test objects inherit from this so the member functions and variables
+ // can be referenced directly inside of the test functions.
+ size_t mMemTotal;
+};
+
+typedef test_group<BufferArrayTestData> BufferArrayTestGroupType;
+typedef BufferArrayTestGroupType::object BufferArrayTestObjectType;
+BufferArrayTestGroupType BufferArrayTestGroup("BufferArray Tests");
+
+template <> template <>
+void BufferArrayTestObjectType::test<1>()
+{
+ set_test_name("BufferArray construction");
+
+ // record the total amount of dynamically allocated memory
+ mMemTotal = GetMemTotal();
+
+ // create a new ref counted object with an implicit reference
+ BufferArray * ba = new BufferArray();
+ ensure("One ref on construction of BufferArray", ba->getRefCount() == 1);
+ ensure("Memory being used", mMemTotal < GetMemTotal());
+ ensure("Nothing in BA", 0 == ba->size());
+
+ // Try to read
+ char buffer[20];
+ size_t read_len(ba->read(0, buffer, sizeof(buffer)));
+ ensure("Read returns empty", 0 == read_len);
+
+ // release the implicit reference, causing the object to be released
+ ba->release();
+
+ // make sure we didn't leak any memory
+ ensure(mMemTotal == GetMemTotal());
+}
+
+template <> template <>
+void BufferArrayTestObjectType::test<2>()
+{
+ set_test_name("BufferArray single write");
+
+ // record the total amount of dynamically allocated memory
+ mMemTotal = GetMemTotal();
+
+ // create a new ref counted object with an implicit reference
+ BufferArray * ba = new BufferArray();
+
+ // write some data to the buffer
+ char str1[] = "abcdefghij";
+ char buffer[256];
+
+ size_t len = ba->write(0, str1, strlen(str1));
+ ensure("Wrote length correct", strlen(str1) == len);
+ ensure("Recorded size correct", strlen(str1) == ba->size());
+
+ // read some data back
+ memset(buffer, 'X', sizeof(buffer));
+ len = ba->read(2, buffer, 2);
+ ensure("Read length correct", 2 == len);
+ ensure("Read content correct", 'c' == buffer[0] && 'd' == buffer[1]);
+ ensure("Read didn't overwrite", 'X' == buffer[2]);
+
+ // release the implicit reference, causing the object to be released
+ ba->release();
+
+ // make sure we didn't leak any memory
+ ensure(mMemTotal == GetMemTotal());
+}
+
+
+template <> template <>
+void BufferArrayTestObjectType::test<3>()
+{
+ set_test_name("BufferArray multiple writes");
+
+ // record the total amount of dynamically allocated memory
+ mMemTotal = GetMemTotal();
+
+ // create a new ref counted object with an implicit reference
+ BufferArray * ba = new BufferArray();
+
+ // write some data to the buffer
+ char str1[] = "abcdefghij";
+ size_t str1_len(strlen(str1));
+ char buffer[256];
+
+ size_t len = ba->write(0, str1, str1_len);
+ ensure("Wrote length correct", str1_len == len);
+ ensure("Recorded size correct", str1_len == ba->size());
+
+ // again...
+ len = ba->write(str1_len, str1, strlen(str1));
+ ensure("Wrote length correct", str1_len == len);
+ ensure("Recorded size correct", (2 * str1_len) == ba->size());
+
+ // read some data back
+ memset(buffer, 'X', sizeof(buffer));
+ len = ba->read(8, buffer, 4);
+ ensure("Read length correct", 4 == len);
+ ensure("Read content correct", 'i' == buffer[0] && 'j' == buffer[1]);
+ ensure("Read content correct", 'a' == buffer[2] && 'b' == buffer[3]);
+ ensure("Read didn't overwrite", 'X' == buffer[4]);
+
+ // Read whole thing
+ memset(buffer, 'X', sizeof(buffer));
+ len = ba->read(0, buffer, sizeof(buffer));
+ ensure("Read length correct", (2 * str1_len) == len);
+ ensure("Read content correct (3)", 0 == strncmp(buffer, str1, str1_len));
+ ensure("Read content correct (4)", 0 == strncmp(&buffer[str1_len], str1, str1_len));
+ ensure("Read didn't overwrite (5)", 'X' == buffer[2 * str1_len]);
+
+ // release the implicit reference, causing the object to be released
+ ba->release();
+
+ // make sure we didn't leak any memory
+ ensure(mMemTotal == GetMemTotal());
+}
+
+template <> template <>
+void BufferArrayTestObjectType::test<4>()
+{
+ set_test_name("BufferArray overwriting");
+
+ // record the total amount of dynamically allocated memory
+ mMemTotal = GetMemTotal();
+
+ // create a new ref counted object with an implicit reference
+ BufferArray * ba = new BufferArray();
+
+ // write some data to the buffer
+ char str1[] = "abcdefghij";
+ size_t str1_len(strlen(str1));
+ char str2[] = "ABCDEFGHIJ";
+ char buffer[256];
+
+ size_t len = ba->write(0, str1, str1_len);
+ ensure("Wrote length correct", str1_len == len);
+ ensure("Recorded size correct", str1_len == ba->size());
+
+ // again...
+ len = ba->write(str1_len, str1, strlen(str1));
+ ensure("Wrote length correct", str1_len == len);
+ ensure("Recorded size correct", (2 * str1_len) == ba->size());
+
+ // reposition and overwrite
+ len = ba->write(8, str2, 4);
+ ensure("Overwrite length correct", 4 == len);
+
+ // Leave position and read verifying content (stale really from seek() days)
+ memset(buffer, 'X', sizeof(buffer));
+ len = ba->read(12, buffer, 4);
+ ensure("Read length correct", 4 == len);
+ ensure("Read content correct", 'c' == buffer[0] && 'd' == buffer[1]);
+ ensure("Read content correct.2", 'e' == buffer[2] && 'f' == buffer[3]);
+ ensure("Read didn't overwrite", 'X' == buffer[4]);
+
+ // reposition and check
+ len = ba->read(6, buffer, 8);
+ ensure("Read length correct.2", 8 == len);
+ ensure("Read content correct.3", 'g' == buffer[0] && 'h' == buffer[1]);
+ ensure("Read content correct.4", 'A' == buffer[2] && 'B' == buffer[3]);
+ ensure("Read content correct.5", 'C' == buffer[4] && 'D' == buffer[5]);
+ ensure("Read content correct.6", 'c' == buffer[6] && 'd' == buffer[7]);
+ ensure("Read didn't overwrite.7", 'X' == buffer[8]);
+
+ // release the implicit reference, causing the object to be released
+ ba->release();
+
+ // make sure we didn't leak any memory
+ ensure(mMemTotal == GetMemTotal());
+}
+
+template <> template <>
+void BufferArrayTestObjectType::test<5>()
+{
+ set_test_name("BufferArray multiple writes - sequential reads");
+
+ // record the total amount of dynamically allocated memory
+ mMemTotal = GetMemTotal();
+
+ // create a new ref counted object with an implicit reference
+ BufferArray * ba = new BufferArray();
+
+ // write some data to the buffer
+ char str1[] = "abcdefghij";
+ size_t str1_len(strlen(str1));
+ char buffer[256];
+
+ size_t len = ba->write(0, str1, str1_len);
+ ensure("Wrote length correct", str1_len == len);
+ ensure("Recorded size correct", str1_len == ba->size());
+
+ // again...
+ len = ba->write(str1_len, str1, str1_len);
+ ensure("Wrote length correct", str1_len == len);
+ ensure("Recorded size correct", (2 * str1_len) == ba->size());
+
+ // read some data back
+ memset(buffer, 'X', sizeof(buffer));
+ len = ba->read(8, buffer, 4);
+ ensure("Read length correct", 4 == len);
+ ensure("Read content correct", 'i' == buffer[0] && 'j' == buffer[1]);
+ ensure("Read content correct.2", 'a' == buffer[2] && 'b' == buffer[3]);
+ ensure("Read didn't overwrite", 'X' == buffer[4]);
+
+ // Read some more without repositioning
+ memset(buffer, 'X', sizeof(buffer));
+ len = ba->read(12, buffer, sizeof(buffer));
+ ensure("Read length correct", (str1_len - 2) == len);
+ ensure("Read content correct.3", 0 == strncmp(buffer, str1+2, str1_len-2));
+ ensure("Read didn't overwrite.2", 'X' == buffer[str1_len-1]);
+
+ // release the implicit reference, causing the object to be released
+ ba->release();
+
+ // make sure we didn't leak any memory
+ ensure(mMemTotal == GetMemTotal());
+}
+
+template <> template <>
+void BufferArrayTestObjectType::test<6>()
+{
+ set_test_name("BufferArray overwrite spanning blocks and appending");
+
+ // record the total amount of dynamically allocated memory
+ mMemTotal = GetMemTotal();
+
+ // create a new ref counted object with an implicit reference
+ BufferArray * ba = new BufferArray();
+
+ // write some data to the buffer
+ char str1[] = "abcdefghij";
+ size_t str1_len(strlen(str1));
+ char str2[] = "ABCDEFGHIJKLMNOPQRST";
+ size_t str2_len(strlen(str2));
+ char buffer[256];
+
+ size_t len = ba->write(0, str1, str1_len);
+ ensure("Wrote length correct", str1_len == len);
+ ensure("Recorded size correct", str1_len == ba->size());
+
+ // again...
+ len = ba->write(str1_len, str1, strlen(str1));
+ ensure("Wrote length correct", str1_len == len);
+ ensure("Recorded size correct", (2 * str1_len) == ba->size());
+
+ // reposition and overwrite
+ len = ba->write(8, str2, str2_len);
+ ensure("Overwrite length correct", str2_len == len);
+
+ // Leave position and read verifying content
+ memset(buffer, 'X', sizeof(buffer));
+ len = ba->read(8 + str2_len, buffer, 0);
+ ensure("Read length correct", 0 == len);
+ ensure("Read didn't overwrite", 'X' == buffer[0]);
+
+ // reposition and check
+ len = ba->read(0, buffer, sizeof(buffer));
+ ensure("Read length correct.2", (str1_len + str2_len - 2) == len);
+ ensure("Read content correct", 0 == strncmp(buffer, str1, str1_len-2));
+ ensure("Read content correct.2", 0 == strncmp(buffer+str1_len-2, str2, str2_len));
+ ensure("Read didn't overwrite.2", 'X' == buffer[str1_len + str2_len - 2]);
+
+ // release the implicit reference, causing the object to be released
+ ba->release();
+
+ // make sure we didn't leak any memory
+ ensure("All memory released", mMemTotal == GetMemTotal());
+}
+
+template <> template <>
+void BufferArrayTestObjectType::test<7>()
+{
+ set_test_name("BufferArray overwrite spanning blocks and sequential writes");
+
+ // record the total amount of dynamically allocated memory
+ mMemTotal = GetMemTotal();
+
+ // create a new ref counted object with an implicit reference
+ BufferArray * ba = new BufferArray();
+
+ // write some data to the buffer
+ char str1[] = "abcdefghij";
+ size_t str1_len(strlen(str1));
+ char str2[] = "ABCDEFGHIJKLMNOPQRST";
+ size_t str2_len(strlen(str2));
+ char buffer[256];
+
+ // 2x str1
+ size_t len = ba->write(0, str1, str1_len);
+ len = ba->write(str1_len, str1, str1_len);
+
+ // reposition and overwrite
+ len = ba->write(6, str2, 2);
+ ensure("Overwrite length correct", 2 == len);
+
+ len = ba->write(8, str2, 2);
+ ensure("Overwrite length correct.2", 2 == len);
+
+ len = ba->write(10, str2, 2);
+ ensure("Overwrite length correct.3", 2 == len);
+
+ // append some data
+ len = ba->append(str2, str2_len);
+ ensure("Append length correct", str2_len == len);
+
+ // append some more
+ void * out_buf(ba->appendBufferAlloc(str1_len));
+ memcpy(out_buf, str1, str1_len);
+
+ // And some final writes
+ len = ba->write(3 * str1_len + str2_len, str2, 2);
+ ensure("Write length correct.2", 2 == len);
+
+ // Check contents
+ memset(buffer, 'X', sizeof(buffer));
+ len = ba->read(0, buffer, sizeof(buffer));
+ ensure("Final buffer length correct", (3 * str1_len + str2_len + 2) == len);
+ ensure("Read content correct", 0 == strncmp(buffer, str1, 6));
+ ensure("Read content correct.2", 0 == strncmp(buffer + 6, str2, 2));
+ ensure("Read content correct.3", 0 == strncmp(buffer + 8, str2, 2));
+ ensure("Read content correct.4", 0 == strncmp(buffer + 10, str2, 2));
+ ensure("Read content correct.5", 0 == strncmp(buffer + str1_len + 2, str1 + 2, str1_len - 2));
+ ensure("Read content correct.6", 0 == strncmp(buffer + str1_len + str1_len, str2, str2_len));
+ ensure("Read content correct.7", 0 == strncmp(buffer + str1_len + str1_len + str2_len, str1, str1_len));
+ ensure("Read content correct.8", 0 == strncmp(buffer + str1_len + str1_len + str2_len + str1_len, str2, 2));
+ ensure("Read didn't overwrite", 'X' == buffer[str1_len + str1_len + str2_len + str1_len + 2]);
+
+ // release the implicit reference, causing the object to be released
+ ba->release();
+
+ // make sure we didn't leak any memory
+ ensure("All memory released", mMemTotal == GetMemTotal());
+}
+
+template <> template <>
+void BufferArrayTestObjectType::test<8>()
+{
+ set_test_name("BufferArray zero-length appendBufferAlloc");
+
+ // record the total amount of dynamically allocated memory
+ mMemTotal = GetMemTotal();
+
+ // create a new ref counted object with an implicit reference
+ BufferArray * ba = new BufferArray();
+
+ // write some data to the buffer
+ char str1[] = "abcdefghij";
+ size_t str1_len(strlen(str1));
+ char str2[] = "ABCDEFGHIJKLMNOPQRST";
+ size_t str2_len(strlen(str2));
+ char buffer[256];
+
+ // 2x str1
+ size_t len = ba->write(0, str1, str1_len);
+ len = ba->write(str1_len, str1, str1_len);
+
+ // zero-length allocate (we allow this with a valid pointer returned)
+ void * out_buf(ba->appendBufferAlloc(0));
+ ensure("Buffer from zero-length appendBufferAlloc non-NULL", NULL != out_buf);
+
+ // Do it again
+ void * out_buf2(ba->appendBufferAlloc(0));
+ ensure("Buffer from zero-length appendBufferAlloc non-NULL.2", NULL != out_buf2);
+ ensure("Two zero-length appendBufferAlloc buffers distinct", out_buf != out_buf2);
+
+ // And some final writes
+ len = ba->write(2 * str1_len, str2, str2_len);
+
+ // Check contents
+ memset(buffer, 'X', sizeof(buffer));
+ len = ba->read(0, buffer, sizeof(buffer));
+ ensure("Final buffer length correct", (2 * str1_len + str2_len) == len);
+ ensure("Read content correct.1", 0 == strncmp(buffer, str1, str1_len));
+ ensure("Read content correct.2", 0 == strncmp(buffer + str1_len, str1, str1_len));
+ ensure("Read content correct.3", 0 == strncmp(buffer + str1_len + str1_len, str2, str2_len));
+ ensure("Read didn't overwrite", 'X' == buffer[str1_len + str1_len + str2_len]);
+
+ // release the implicit reference, causing the object to be released
+ ba->release();
+
+ // make sure we didn't leak any memory
+ ensure("All memory released", mMemTotal == GetMemTotal());
+}
+
+} // end namespace tut
+
+
+#endif // TEST_LLCORE_BUFFER_ARRAY_H_
diff --git a/indra/llcorehttp/tests/test_bufferstream.hpp b/indra/llcorehttp/tests/test_bufferstream.hpp
new file mode 100755
index 0000000000..831c901b9d
--- /dev/null
+++ b/indra/llcorehttp/tests/test_bufferstream.hpp
@@ -0,0 +1,304 @@
+/**
+ * @file test_bufferstream.hpp
+ * @brief unit tests for the LLCore::BufferArrayStreamBuf/BufferArrayStream classes
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 TEST_LLCORE_BUFFER_STREAM_H_
+#define TEST_LLCORE_BUFFER_STREAM_H_
+
+#include "bufferstream.h"
+
+#include <iostream>
+
+#include "test_allocator.h"
+#include "llsd.h"
+#include "llsdserialize.h"
+
+
+using namespace LLCore;
+
+
+namespace tut
+{
+
+struct BufferStreamTestData
+{
+ // the test objects inherit from this so the member functions and variables
+ // can be referenced directly inside of the test functions.
+ size_t mMemTotal;
+};
+
+typedef test_group<BufferStreamTestData> BufferStreamTestGroupType;
+typedef BufferStreamTestGroupType::object BufferStreamTestObjectType;
+BufferStreamTestGroupType BufferStreamTestGroup("BufferStream Tests");
+typedef BufferArrayStreamBuf::traits_type tst_traits_t;
+
+
+template <> template <>
+void BufferStreamTestObjectType::test<1>()
+{
+ set_test_name("BufferArrayStreamBuf construction with NULL BufferArray");
+
+ // record the total amount of dynamically allocated memory
+ mMemTotal = GetMemTotal();
+
+ // create a new ref counted object with an implicit reference
+ BufferArrayStreamBuf * bsb = new BufferArrayStreamBuf(NULL);
+ ensure("Memory being used", mMemTotal < GetMemTotal());
+
+ // Not much will work with a NULL
+ ensure("underflow() on NULL fails", tst_traits_t::eof() == bsb->underflow());
+ ensure("uflow() on NULL fails", tst_traits_t::eof() == bsb->uflow());
+ ensure("pbackfail() on NULL fails", tst_traits_t::eof() == bsb->pbackfail('c'));
+ ensure("showmanyc() on NULL fails", bsb->showmanyc() == -1);
+ ensure("overflow() on NULL fails", tst_traits_t::eof() == bsb->overflow('c'));
+ ensure("xsputn() on NULL fails", bsb->xsputn("blah", 4) == 0);
+ ensure("seekoff() on NULL fails", bsb->seekoff(0, std::ios_base::beg, std::ios_base::in) == std::streampos(-1));
+
+ // release the implicit reference, causing the object to be released
+ delete bsb;
+ bsb = NULL;
+
+ // make sure we didn't leak any memory
+ ensure("Allocated memory returned", mMemTotal == GetMemTotal());
+}
+
+
+template <> template <>
+void BufferStreamTestObjectType::test<2>()
+{
+ set_test_name("BufferArrayStream construction with NULL BufferArray");
+
+ // record the total amount of dynamically allocated memory
+ mMemTotal = GetMemTotal();
+
+ // create a new ref counted object with an implicit reference
+ BufferArrayStream * bas = new BufferArrayStream(NULL);
+ ensure("Memory being used", mMemTotal < GetMemTotal());
+
+ // Not much will work with a NULL here
+ ensure("eof() is false on NULL", ! bas->eof());
+ ensure("fail() is false on NULL", ! bas->fail());
+ ensure("good() on NULL", bas->good());
+
+ // release the implicit reference, causing the object to be released
+ delete bas;
+ bas = NULL;
+
+ // make sure we didn't leak any memory
+ ensure("Allocated memory returned", mMemTotal == GetMemTotal());
+}
+
+
+template <> template <>
+void BufferStreamTestObjectType::test<3>()
+{
+ set_test_name("BufferArrayStreamBuf construction with empty BufferArray");
+
+ // record the total amount of dynamically allocated memory
+ mMemTotal = GetMemTotal();
+
+ // create a new ref counted BufferArray with implicit reference
+ BufferArray * ba = new BufferArray;
+ BufferArrayStreamBuf * bsb = new BufferArrayStreamBuf(ba);
+ ensure("Memory being used", mMemTotal < GetMemTotal());
+
+ // I can release my ref on the BA
+ ba->release();
+ ba = NULL;
+
+ // release the implicit reference, causing the object to be released
+ delete bsb;
+ bsb = NULL;
+
+ // make sure we didn't leak any memory
+ ensure("Allocated memory returned", mMemTotal == GetMemTotal());
+}
+
+
+template <> template <>
+void BufferStreamTestObjectType::test<4>()
+{
+ set_test_name("BufferArrayStream construction with empty BufferArray");
+
+ // record the total amount of dynamically allocated memory
+ mMemTotal = GetMemTotal();
+
+ // create a new ref counted BufferArray with implicit reference
+ BufferArray * ba = new BufferArray;
+
+ {
+ // create a new ref counted object with an implicit reference
+ BufferArrayStream bas(ba);
+ ensure("Memory being used", mMemTotal < GetMemTotal());
+ }
+
+ // release the implicit reference, causing the object to be released
+ ba->release();
+ ba = NULL;
+
+ // make sure we didn't leak any memory
+ ensure("Allocated memory returned", mMemTotal == GetMemTotal());
+}
+
+
+template <> template <>
+void BufferStreamTestObjectType::test<5>()
+{
+ set_test_name("BufferArrayStreamBuf construction with real BufferArray");
+
+ // record the total amount of dynamically allocated memory
+ mMemTotal = GetMemTotal();
+
+ // create a new ref counted BufferArray with implicit reference
+ BufferArray * ba = new BufferArray;
+ const char * content("This is a string. A fragment.");
+ const size_t c_len(strlen(content));
+ ba->append(content, c_len);
+
+ // Creat an adapter for the BufferArray
+ BufferArrayStreamBuf * bsb = new BufferArrayStreamBuf(ba);
+ ensure("Memory being used", mMemTotal < GetMemTotal());
+
+ // I can release my ref on the BA
+ ba->release();
+ ba = NULL;
+
+ // Various static state
+ ensure("underflow() returns 'T'", bsb->underflow() == 'T');
+ ensure("underflow() returns 'T' again", bsb->underflow() == 'T');
+ ensure("uflow() returns 'T'", bsb->uflow() == 'T');
+ ensure("uflow() returns 'h'", bsb->uflow() == 'h');
+ ensure("pbackfail('i') fails", tst_traits_t::eof() == bsb->pbackfail('i'));
+ ensure("pbackfail('T') fails", tst_traits_t::eof() == bsb->pbackfail('T'));
+ ensure("pbackfail('h') succeeds", bsb->pbackfail('h') == 'h');
+ ensure("showmanyc() is everything but the 'T'", bsb->showmanyc() == (c_len - 1));
+ ensure("overflow() appends", bsb->overflow('c') == 'c');
+ ensure("showmanyc() reflects append", bsb->showmanyc() == (c_len - 1 + 1));
+ ensure("xsputn() appends some more", bsb->xsputn("bla!", 4) == 4);
+ ensure("showmanyc() reflects 2nd append", bsb->showmanyc() == (c_len - 1 + 5));
+ ensure("seekoff() succeeds", bsb->seekoff(0, std::ios_base::beg, std::ios_base::in) == std::streampos(0));
+ ensure("seekoff() succeeds 2", bsb->seekoff(4, std::ios_base::cur, std::ios_base::in) == std::streampos(4));
+ ensure("showmanyc() picks up seekoff", bsb->showmanyc() == (c_len + 5 - 4));
+ ensure("seekoff() succeeds 3", bsb->seekoff(0, std::ios_base::end, std::ios_base::in) == std::streampos(c_len + 4));
+ ensure("pbackfail('!') succeeds", tst_traits_t::eof() == bsb->pbackfail('!'));
+
+ // release the implicit reference, causing the object to be released
+ delete bsb;
+ bsb = NULL;
+
+ // make sure we didn't leak any memory
+ ensure("Allocated memory returned", mMemTotal == GetMemTotal());
+}
+
+
+template <> template <>
+void BufferStreamTestObjectType::test<6>()
+{
+ set_test_name("BufferArrayStream construction with real BufferArray");
+
+ // record the total amount of dynamically allocated memory
+ mMemTotal = GetMemTotal();
+
+ // create a new ref counted BufferArray with implicit reference
+ BufferArray * ba = new BufferArray;
+ //const char * content("This is a string. A fragment.");
+ //const size_t c_len(strlen(content));
+ //ba->append(content, strlen(content));
+
+ {
+ // Creat an adapter for the BufferArray
+ BufferArrayStream bas(ba);
+ ensure("Memory being used", mMemTotal < GetMemTotal());
+
+ // Basic operations
+ bas << "Hello" << 27 << ".";
+ ensure("BA length 8", ba->size() == 8);
+
+ std::string str;
+ bas >> str;
+ ensure("reads correctly", str == "Hello27.");
+ }
+
+ // release the implicit reference, causing the object to be released
+ ba->release();
+ ba = NULL;
+
+ // make sure we didn't leak any memory
+ // ensure("Allocated memory returned", mMemTotal == GetMemTotal());
+ // static U64 mem = GetMemTotal();
+}
+
+
+template <> template <>
+void BufferStreamTestObjectType::test<7>()
+{
+ set_test_name("BufferArrayStream with LLSD serialization");
+
+ // record the total amount of dynamically allocated memory
+ mMemTotal = GetMemTotal();
+
+ // create a new ref counted BufferArray with implicit reference
+ BufferArray * ba = new BufferArray;
+
+ {
+ // Creat an adapter for the BufferArray
+ BufferArrayStream bas(ba);
+ ensure("Memory being used", mMemTotal < GetMemTotal());
+
+ // LLSD
+ LLSD llsd = LLSD::emptyMap();
+
+ llsd["int"] = LLSD::Integer(3);
+ llsd["float"] = LLSD::Real(923289.28992);
+ llsd["string"] = LLSD::String("aksjdl;ajsdgfjgfal;sdgjakl;sdfjkl;ajsdfkl;ajsdfkl;jaskl;dfj");
+
+ LLSD llsd_map = LLSD::emptyMap();
+ llsd_map["int"] = LLSD::Integer(-2889);
+ llsd_map["float"] = LLSD::Real(2.37829e32);
+ llsd_map["string"] = LLSD::String("OHIGODHSPDGHOSDHGOPSHDGP");
+
+ llsd["map"] = llsd_map;
+
+ // Serialize it
+ LLSDSerialize::toXML(llsd, bas);
+
+ std::string str;
+ bas >> str;
+ // std::cout << "SERIALIZED LLSD: " << str << std::endl;
+ ensure("Extracted string has reasonable length", str.size() > 60);
+ }
+
+ // release the implicit reference, causing the object to be released
+ ba->release();
+ ba = NULL;
+
+ // make sure we didn't leak any memory
+ // ensure("Allocated memory returned", mMemTotal == GetMemTotal());
+}
+
+
+} // end namespace tut
+
+
+#endif // TEST_LLCORE_BUFFER_STREAM_H_
diff --git a/indra/llcorehttp/tests/test_httpheaders.hpp b/indra/llcorehttp/tests/test_httpheaders.hpp
new file mode 100755
index 0000000000..ce0d19b058
--- /dev/null
+++ b/indra/llcorehttp/tests/test_httpheaders.hpp
@@ -0,0 +1,108 @@
+/**
+ * @file test_httpheaders.hpp
+ * @brief unit tests for the LLCore::HttpHeaders class
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 TEST_LLCORE_HTTP_HEADERS_H_
+#define TEST_LLCORE_HTTP_HEADERS_H_
+
+#include "httpheaders.h"
+
+#include <iostream>
+
+#include "test_allocator.h"
+
+
+using namespace LLCoreInt;
+
+
+
+namespace tut
+{
+
+struct HttpHeadersTestData
+{
+ // the test objects inherit from this so the member functions and variables
+ // can be referenced directly inside of the test functions.
+ size_t mMemTotal;
+};
+
+typedef test_group<HttpHeadersTestData> HttpHeadersTestGroupType;
+typedef HttpHeadersTestGroupType::object HttpHeadersTestObjectType;
+HttpHeadersTestGroupType HttpHeadersTestGroup("HttpHeaders Tests");
+
+template <> template <>
+void HttpHeadersTestObjectType::test<1>()
+{
+ set_test_name("HttpHeaders construction");
+
+ // record the total amount of dynamically allocated memory
+ mMemTotal = GetMemTotal();
+
+ // create a new ref counted object with an implicit reference
+ HttpHeaders * headers = new HttpHeaders();
+ ensure("One ref on construction of HttpHeaders", headers->getRefCount() == 1);
+ ensure("Memory being used", mMemTotal < GetMemTotal());
+ ensure("Nothing in headers", 0 == headers->mHeaders.size());
+
+ // release the implicit reference, causing the object to be released
+ headers->release();
+
+ // make sure we didn't leak any memory
+ ensure(mMemTotal == GetMemTotal());
+}
+
+template <> template <>
+void HttpHeadersTestObjectType::test<2>()
+{
+ set_test_name("HttpHeaders construction");
+
+ // record the total amount of dynamically allocated memory
+ mMemTotal = GetMemTotal();
+
+ // create a new ref counted object with an implicit reference
+ HttpHeaders * headers = new HttpHeaders();
+
+ {
+ // Append a few strings
+ std::string str1("Pragma:");
+ headers->mHeaders.push_back(str1);
+ std::string str2("Accept: application/json");
+ headers->mHeaders.push_back(str2);
+
+ ensure("Headers retained", 2 == headers->mHeaders.size());
+ ensure("First is first", headers->mHeaders[0] == str1);
+ ensure("Second is second", headers->mHeaders[1] == str2);
+ }
+
+ // release the implicit reference, causing the object to be released
+ headers->release();
+
+ // make sure we didn't leak any memory
+ ensure(mMemTotal == GetMemTotal());
+}
+
+} // end namespace tut
+
+
+#endif // TEST_LLCORE_HTTP_HEADERS_H_
diff --git a/indra/llcorehttp/tests/test_httpoperation.hpp b/indra/llcorehttp/tests/test_httpoperation.hpp
new file mode 100755
index 0000000000..17b1a96878
--- /dev/null
+++ b/indra/llcorehttp/tests/test_httpoperation.hpp
@@ -0,0 +1,125 @@
+/**
+ * @file test_httpoperation.hpp
+ * @brief unit tests for the LLCore::HttpOperation-derived classes
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 TEST_LLCORE_HTTP_OPERATION_H_
+#define TEST_LLCORE_HTTP_OPERATION_H_
+
+#include "_httpoperation.h"
+#include "httphandler.h"
+
+#include <iostream>
+
+#include "test_allocator.h"
+
+
+using namespace LLCoreInt;
+
+
+namespace
+{
+
+class TestHandler : public LLCore::HttpHandler
+{
+public:
+ virtual void onCompleted(HttpHandle, HttpResponse *)
+ {
+ std::cout << "TestHandler::onCompleted() invoked" << std::endl;
+ }
+
+};
+
+
+} // end namespace anonymous
+
+
+namespace tut
+{
+ struct HttpOperationTestData
+ {
+ // the test objects inherit from this so the member functions and variables
+ // can be referenced directly inside of the test functions.
+ size_t mMemTotal;
+ };
+
+ typedef test_group<HttpOperationTestData> HttpOperationTestGroupType;
+ typedef HttpOperationTestGroupType::object HttpOperationTestObjectType;
+ HttpOperationTestGroupType HttpOperationTestGroup("HttpOperation Tests");
+
+ template <> template <>
+ void HttpOperationTestObjectType::test<1>()
+ {
+ set_test_name("HttpOpNull construction");
+
+ // record the total amount of dynamically allocated memory
+ mMemTotal = GetMemTotal();
+
+ // create a new ref counted object with an implicit reference
+ HttpOpNull * op = new HttpOpNull();
+ ensure(op->getRefCount() == 1);
+ ensure(mMemTotal < GetMemTotal());
+
+ // release the implicit reference, causing the object to be released
+ op->release();
+
+ // make sure we didn't leak any memory
+ ensure(mMemTotal == GetMemTotal());
+ }
+
+ template <> template <>
+ void HttpOperationTestObjectType::test<2>()
+ {
+ set_test_name("HttpOpNull construction with handlers");
+
+ // record the total amount of dynamically allocated memory
+ mMemTotal = GetMemTotal();
+
+ // Get some handlers
+ TestHandler * h1 = new TestHandler();
+
+ // create a new ref counted object with an implicit reference
+ HttpOpNull * op = new HttpOpNull();
+
+ // Add the handlers
+ op->setReplyPath(NULL, h1);
+
+ // Check ref count
+ ensure(op->getRefCount() == 1);
+
+ // release the reference, releasing the operation but
+ // not the handlers.
+ op->release();
+ op = NULL;
+ ensure(mMemTotal != GetMemTotal());
+
+ // release the handlers
+ delete h1;
+ h1 = NULL;
+
+ ensure(mMemTotal == GetMemTotal());
+ }
+
+}
+
+#endif // TEST_LLCORE_HTTP_OPERATION_H_
diff --git a/indra/llcorehttp/tests/test_httprequest.hpp b/indra/llcorehttp/tests/test_httprequest.hpp
new file mode 100755
index 0000000000..900a699887
--- /dev/null
+++ b/indra/llcorehttp/tests/test_httprequest.hpp
@@ -0,0 +1,2873 @@
+/**
+ * @file test_httprequest.hpp
+ * @brief unit tests for the LLCore::HttpRequest class
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012-2013, 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 TEST_LLCORE_HTTP_REQUEST_H_
+#define TEST_LLCORE_HTTP_REQUEST_H_
+
+#include "httprequest.h"
+#include "bufferarray.h"
+#include "httphandler.h"
+#include "httpheaders.h"
+#include "httpresponse.h"
+#include "httpoptions.h"
+#include "_httpservice.h"
+#include "_httprequestqueue.h"
+
+#include <curl/curl.h>
+#include <boost/regex.hpp>
+#include <sstream>
+
+#include "test_allocator.h"
+#include "llcorehttp_test.h"
+
+
+using namespace LLCoreInt;
+
+// spin/sleep waiting times for client/server exchange tests
+//
+// These are now fairly generous to try to get around timeout
+// ('reasonable time') failures during execution on a heavily-
+// loaded system where the unit test is in competition with
+// other programs.
+static const int LOOP_SLEEP_INTERVAL(10000);
+static const int LOOP_COUNT_SHORT(500); // 5-second dwell time
+static const int LOOP_COUNT_LONG(3000); // 30-second dwell time
+
+namespace
+{
+
+#if defined(WIN32)
+
+void usleep(unsigned long usec);
+
+#endif
+
+}
+
+namespace tut
+{
+
+struct HttpRequestTestData
+{
+ // the test objects inherit from this so the member functions and variables
+ // can be referenced directly inside of the test functions.
+ size_t mMemTotal;
+ int mHandlerCalls;
+ HttpStatus mStatus;
+};
+
+class TestHandler2 : public LLCore::HttpHandler
+{
+public:
+ TestHandler2(HttpRequestTestData * state,
+ const std::string & name)
+ : mState(state),
+ mName(name),
+ mExpectHandle(LLCORE_HTTP_HANDLE_INVALID)
+ {}
+
+ virtual void onCompleted(HttpHandle handle, HttpResponse * response)
+ {
+ if (LLCORE_HTTP_HANDLE_INVALID != mExpectHandle)
+ {
+ ensure("Expected handle received in handler", mExpectHandle == handle);
+ }
+ ensure("Handler got a response", NULL != response);
+ if (response && mState)
+ {
+ const HttpStatus actual_status(response->getStatus());
+ std::ostringstream test;
+ test << "Expected HttpStatus received in response. Wanted: "
+ << mState->mStatus.toHex() << " Received: " << actual_status.toHex();
+ ensure(test.str().c_str(), actual_status == mState->mStatus);
+ }
+ if (mState)
+ {
+ mState->mHandlerCalls++;
+ }
+ if (! mHeadersRequired.empty() || ! mHeadersDisallowed.empty())
+ {
+ ensure("Response required with header check", response != NULL);
+ HttpHeaders * header(response->getHeaders()); // Will not hold onto this
+ ensure("Some quantity of headers returned", header != NULL);
+
+ if (! mHeadersRequired.empty())
+ {
+ for (int i(0); i < mHeadersRequired.size(); ++i)
+ {
+ bool found = false;
+ for (HttpHeaders::container_t::const_iterator iter(header->mHeaders.begin());
+ header->mHeaders.end() != iter;
+ ++iter)
+ {
+ if (boost::regex_match(*iter, mHeadersRequired[i]))
+ {
+ found = true;
+ break;
+ }
+ }
+ std::ostringstream str;
+ str << "Required header # " << i << " found in response";
+ ensure(str.str(), found);
+ }
+ }
+
+ if (! mHeadersDisallowed.empty())
+ {
+ for (int i(0); i < mHeadersDisallowed.size(); ++i)
+ {
+ for (HttpHeaders::container_t::const_iterator iter(header->mHeaders.begin());
+ header->mHeaders.end() != iter;
+ ++iter)
+ {
+ if (boost::regex_match(*iter, mHeadersDisallowed[i]))
+ {
+ std::ostringstream str;
+ str << "Disallowed header # " << i << " not found in response";
+ ensure(str.str(), false);
+ }
+ }
+ }
+ }
+ }
+
+ if (! mCheckContentType.empty())
+ {
+ ensure("Response required with content type check", response != NULL);
+ std::string con_type(response->getContentType());
+ ensure("Content-Type as expected (" + mCheckContentType + ")",
+ mCheckContentType == con_type);
+ }
+
+ // std::cout << "TestHandler2::onCompleted() invoked" << std::endl;
+ }
+
+ HttpRequestTestData * mState;
+ std::string mName;
+ HttpHandle mExpectHandle;
+ std::string mCheckContentType;
+ std::vector<boost::regex> mHeadersRequired;
+ std::vector<boost::regex> mHeadersDisallowed;
+};
+
+typedef test_group<HttpRequestTestData> HttpRequestTestGroupType;
+typedef HttpRequestTestGroupType::object HttpRequestTestObjectType;
+HttpRequestTestGroupType HttpRequestTestGroup("HttpRequest Tests");
+
+template <> template <>
+void HttpRequestTestObjectType::test<1>()
+{
+ ScopedCurlInit ready;
+
+ set_test_name("HttpRequest construction");
+
+ HttpRequest * req = NULL;
+
+ // record the total amount of dynamically allocated memory
+ mMemTotal = GetMemTotal();
+
+ try
+ {
+ // Get singletons created
+ HttpRequest::createService();
+
+ // create a new ref counted object with an implicit reference
+ req = new HttpRequest();
+ ensure("Memory being used", mMemTotal < GetMemTotal());
+
+ // release the request object
+ delete req;
+ req = NULL;
+
+ HttpRequest::destroyService();
+
+ // make sure we didn't leak any memory
+ ensure("Memory returned", mMemTotal == GetMemTotal());
+ }
+ catch (...)
+ {
+ delete req;
+ HttpRequest::destroyService();
+ throw;
+ }
+}
+
+template <> template <>
+void HttpRequestTestObjectType::test<2>()
+{
+ ScopedCurlInit ready;
+
+ set_test_name("HttpRequest and Null Op queued");
+
+ HttpRequest * req = NULL;
+
+ // record the total amount of dynamically allocated memory
+ mMemTotal = GetMemTotal();
+
+ try
+ {
+ // Get singletons created
+ HttpRequest::createService();
+
+ // create a new ref counted object with an implicit reference
+ req = new HttpRequest();
+ ensure("Memory being used", mMemTotal < GetMemTotal());
+
+ // Issue a NoOp
+ HttpHandle handle = req->requestNoOp(NULL);
+ ensure("Request issued", handle != LLCORE_HTTP_HANDLE_INVALID);
+
+ // release the request object
+ delete req;
+ req = NULL;
+
+ // We're still holding onto the operation which is
+ // sitting, unserviced, on the request queue so...
+ ensure("Memory being used 2", mMemTotal < GetMemTotal());
+
+ // Request queue should have two references: global singleton & service object
+ ensure("Two references to request queue", 2 == HttpRequestQueue::instanceOf()->getRefCount());
+
+ // Okay, tear it down
+ HttpRequest::destroyService();
+ // printf("Old mem: %d, New mem: %d\n", mMemTotal, GetMemTotal());
+ ensure("Memory returned", mMemTotal == GetMemTotal());
+ }
+ catch (...)
+ {
+ stop_thread(req);
+ delete req;
+ HttpRequest::destroyService();
+ throw;
+ }
+}
+
+
+template <> template <>
+void HttpRequestTestObjectType::test<3>()
+{
+ ScopedCurlInit ready;
+
+ set_test_name("HttpRequest NoOp + Stop execution");
+
+ // Handler can be stack-allocated *if* there are no dangling
+ // references to it after completion of this method.
+ // Create before memory record as the string copy will bump numbers.
+ TestHandler2 handler(this, "handler");
+
+ // record the total amount of dynamically allocated memory
+ mMemTotal = GetMemTotal();
+ mHandlerCalls = 0;
+
+ HttpRequest * req = NULL;
+
+ try
+ {
+
+ // Get singletons created
+ HttpRequest::createService();
+
+ // Start threading early so that thread memory is invariant
+ // over the test.
+ HttpRequest::startThread();
+
+ // create a new ref counted object with an implicit reference
+ req = new HttpRequest();
+ ensure("Memory allocated on construction", mMemTotal < GetMemTotal());
+
+ // Issue a NoOp
+ HttpHandle handle = req->requestNoOp(&handler);
+ ensure("Valid handle returned for first request", handle != LLCORE_HTTP_HANDLE_INVALID);
+
+ // Run the notification pump.
+ int count(0);
+ int limit(LOOP_COUNT_SHORT);
+ while (count++ < limit && mHandlerCalls < 1)
+ {
+ req->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Request executed in reasonable time", count < limit);
+ ensure("One handler invocation for request", mHandlerCalls == 1);
+
+ // Okay, request a shutdown of the servicing thread
+ handle = req->requestStopThread(&handler);
+ ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID);
+
+ // Run the notification pump again
+ count = 0;
+ limit = LOOP_COUNT_LONG;
+ while (count++ < limit && mHandlerCalls < 2)
+ {
+ req->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Second request executed in reasonable time", count < limit);
+ ensure("Second handler invocation", mHandlerCalls == 2);
+
+ // See that we actually shutdown the thread
+ count = 0;
+ limit = LOOP_COUNT_SHORT;
+ while (count++ < limit && ! HttpService::isStopped())
+ {
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Thread actually stopped running", HttpService::isStopped());
+
+ // release the request object
+ delete req;
+ req = NULL;
+
+ // Shut down service
+ HttpRequest::destroyService();
+
+ ensure("Two handler calls on the way out", 2 == mHandlerCalls);
+ // printf("Old mem: %d, New mem: %d\n", mMemTotal, GetMemTotal());
+ ensure("Memory usage back to that at entry", mMemTotal == GetMemTotal());
+ }
+ catch (...)
+ {
+ stop_thread(req);
+ delete req;
+ HttpRequest::destroyService();
+ throw;
+ }
+}
+
+template <> template <>
+void HttpRequestTestObjectType::test<4>()
+{
+ ScopedCurlInit ready;
+
+ set_test_name("2 HttpRequest instances, one thread");
+
+ // Handler can be stack-allocated *if* there are no dangling
+ // references to it after completion of this method.
+ TestHandler2 handler1(this, "handler1");
+ TestHandler2 handler2(this, "handler2");
+
+ // record the total amount of dynamically allocated memory
+ mMemTotal = GetMemTotal();
+ mHandlerCalls = 0;
+
+ HttpRequest * req1 = NULL;
+ HttpRequest * req2 = NULL;
+
+ try
+ {
+
+ // Get singletons created
+ HttpRequest::createService();
+
+ // Start threading early so that thread memory is invariant
+ // over the test.
+ HttpRequest::startThread();
+
+ // create a new ref counted object with an implicit reference
+ req1 = new HttpRequest();
+ req2 = new HttpRequest();
+ ensure("Memory allocated on construction", mMemTotal < GetMemTotal());
+
+ // Issue some NoOps
+ HttpHandle handle = req1->requestNoOp(&handler1);
+ ensure("Valid handle returned for first request", handle != LLCORE_HTTP_HANDLE_INVALID);
+ handler1.mExpectHandle = handle;
+
+ handle = req2->requestNoOp(&handler2);
+ ensure("Valid handle returned for first request", handle != LLCORE_HTTP_HANDLE_INVALID);
+ handler2.mExpectHandle = handle;
+
+ // Run the notification pump.
+ int count(0);
+ int limit(LOOP_COUNT_LONG);
+ while (count++ < limit && mHandlerCalls < 2)
+ {
+ req1->update(1000000);
+ req2->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Request executed in reasonable time", count < limit);
+ ensure("One handler invocation for request", mHandlerCalls == 2);
+
+ // Okay, request a shutdown of the servicing thread
+ handle = req2->requestStopThread(&handler2);
+ ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID);
+ handler2.mExpectHandle = handle;
+
+ // Run the notification pump again
+ count = 0;
+ limit = LOOP_COUNT_LONG;
+ while (count++ < limit && mHandlerCalls < 3)
+ {
+ req1->update(1000000);
+ req2->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Second request executed in reasonable time", count < limit);
+ ensure("Second handler invocation", mHandlerCalls == 3);
+
+ // See that we actually shutdown the thread
+ count = 0;
+ limit = LOOP_COUNT_SHORT;
+ while (count++ < limit && ! HttpService::isStopped())
+ {
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Thread actually stopped running", HttpService::isStopped());
+
+ // release the request object
+ delete req1;
+ req1 = NULL;
+ delete req2;
+ req2 = NULL;
+
+ // Shut down service
+ HttpRequest::destroyService();
+
+ ensure("Two handler calls on the way out", 3 == mHandlerCalls);
+ // printf("Old mem: %d, New mem: %d\n", mMemTotal, GetMemTotal());
+ ensure("Memory usage back to that at entry", mMemTotal == GetMemTotal());
+ }
+ catch (...)
+ {
+ stop_thread(req1);
+ delete req1;
+ delete req2;
+ HttpRequest::destroyService();
+ throw;
+ }
+}
+
+template <> template <>
+void HttpRequestTestObjectType::test<5>()
+{
+ ScopedCurlInit ready;
+
+ set_test_name("HttpRequest Spin (soft) + NoOp + hard termination");
+
+ // Handler can be stack-allocated *if* there are no dangling
+ // references to it after completion of this method.
+ // Create before memory record as the string copy will bump numbers.
+ TestHandler2 handler(this, "handler");
+
+ // record the total amount of dynamically allocated memory
+ mMemTotal = GetMemTotal();
+ mHandlerCalls = 0;
+
+ HttpRequest * req = NULL;
+
+ try
+ {
+
+ // Get singletons created
+ HttpRequest::createService();
+
+ // Start threading early so that thread memory is invariant
+ // over the test.
+ HttpRequest::startThread();
+
+ // create a new ref counted object with an implicit reference
+ req = new HttpRequest();
+ ensure("Memory allocated on construction", mMemTotal < GetMemTotal());
+
+ // Issue a Spin
+ HttpHandle handle = req->requestSpin(1);
+ ensure("Valid handle returned for spin request", handle != LLCORE_HTTP_HANDLE_INVALID);
+
+ // Issue a NoOp
+ handle = req->requestNoOp(&handler);
+ ensure("Valid handle returned for no-op request", handle != LLCORE_HTTP_HANDLE_INVALID);
+
+ // Run the notification pump.
+ int count(0);
+ int limit(LOOP_COUNT_SHORT);
+ while (count++ < limit && mHandlerCalls < 1)
+ {
+ req->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("NoOp notification received", mHandlerCalls == 1);
+
+ // release the request object
+ delete req;
+ req = NULL;
+
+ // Shut down service
+ HttpRequest::destroyService();
+
+ // Check memory usage
+ // printf("Old mem: %d, New mem: %d\n", mMemTotal, GetMemTotal());
+ ensure("Memory usage back to that at entry", mMemTotal == GetMemTotal());
+ // This memory test should work but could give problems as it
+ // relies on the worker thread picking up a friendly request
+ // to shutdown. Doing so, it drops references to things and
+ // we should go back to where we started. If it gives you
+ // problems, look into the code before commenting things out.
+ }
+ catch (...)
+ {
+ stop_thread(req);
+ delete req;
+ HttpRequest::destroyService();
+ throw;
+ }
+}
+
+
+template <> template <>
+void HttpRequestTestObjectType::test<6>()
+{
+ ScopedCurlInit ready;
+
+ set_test_name("HttpRequest Spin + NoOp + hard termination");
+
+ // Handler can be stack-allocated *if* there are no dangling
+ // references to it after completion of this method.
+ // Create before memory record as the string copy will bump numbers.
+ TestHandler2 handler(this, "handler");
+
+ // record the total amount of dynamically allocated memory
+ mMemTotal = GetMemTotal();
+ mHandlerCalls = 0;
+
+ HttpRequest * req = NULL;
+
+ try
+ {
+
+ // Get singletons created
+ HttpRequest::createService();
+
+ // Start threading early so that thread memory is invariant
+ // over the test.
+ HttpRequest::startThread();
+
+ // create a new ref counted object with an implicit reference
+ req = new HttpRequest();
+ ensure("Memory allocated on construction", mMemTotal < GetMemTotal());
+
+ // Issue a Spin
+ HttpHandle handle = req->requestSpin(0); // Hard spin
+ ensure("Valid handle returned for spin request", handle != LLCORE_HTTP_HANDLE_INVALID);
+
+ // Issue a NoOp
+ handle = req->requestNoOp(&handler);
+ ensure("Valid handle returned for no-op request", handle != LLCORE_HTTP_HANDLE_INVALID);
+
+ // Run the notification pump.
+ int count(0);
+ int limit(LOOP_COUNT_SHORT);
+ while (count++ < limit && mHandlerCalls < 1)
+ {
+ req->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("No notifications received", mHandlerCalls == 0);
+
+ // release the request object
+ delete req;
+ req = NULL;
+
+ // Shut down service
+ HttpRequest::destroyService();
+
+ // Check memory usage
+ // printf("Old mem: %d, New mem: %d\n", mMemTotal, GetMemTotal());
+ // ensure("Memory usage back to that at entry", mMemTotal == GetMemTotal());
+ // This memory test won't work because we're killing the thread
+ // hard with the hard spinner. There's no opportunity to join
+ // nicely so many things leak or get destroyed unilaterally.
+ }
+ catch (...)
+ {
+ stop_thread(req);
+ delete req;
+ HttpRequest::destroyService();
+ throw;
+ }
+}
+
+
+template <> template <>
+void HttpRequestTestObjectType::test<7>()
+{
+ ScopedCurlInit ready;
+
+ set_test_name("HttpRequest GET to dead port + Stop execution");
+
+ // Handler can be stack-allocated *if* there are no dangling
+ // references to it after completion of this method.
+ // Create before memory record as the string copy will bump numbers.
+ TestHandler2 handler(this, "handler");
+
+ // record the total amount of dynamically allocated memory
+ mMemTotal = GetMemTotal();
+ mHandlerCalls = 0;
+
+ HttpRequest * req = NULL;
+ HttpOptions * opts = NULL;
+
+ try
+ {
+ // Get singletons created
+ HttpRequest::createService();
+
+ // Start threading early so that thread memory is invariant
+ // over the test.
+ HttpRequest::startThread();
+
+ // create a new ref counted object with an implicit reference
+ req = new HttpRequest();
+ ensure("Memory allocated on construction", mMemTotal < GetMemTotal());
+
+ opts = new HttpOptions();
+ opts->setRetries(1); // Don't try for too long - default retries take about 18S
+
+ // Issue a GET that can't connect
+ mStatus = HttpStatus(HttpStatus::EXT_CURL_EASY, CURLE_COULDNT_CONNECT);
+ HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID,
+ 0U,
+ "http://127.0.0.1:2/nothing/here",
+ 0,
+ 0,
+ opts,
+ NULL,
+ &handler);
+ ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID);
+
+ // Run the notification pump.
+ int count(0);
+ int limit(LOOP_COUNT_LONG);
+ while (count++ < limit && mHandlerCalls < 1)
+ {
+ req->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Request executed in reasonable time", count < limit);
+ ensure("One handler invocation for request", mHandlerCalls == 1);
+
+ // Okay, request a shutdown of the servicing thread
+ mStatus = HttpStatus();
+ handle = req->requestStopThread(&handler);
+ ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID);
+
+ // Run the notification pump again
+ count = 0;
+ limit = LOOP_COUNT_LONG;
+ while (count++ < limit && mHandlerCalls < 2)
+ {
+ req->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Second request executed in reasonable time", count < limit);
+ ensure("Second handler invocation", mHandlerCalls == 2);
+
+ // See that we actually shutdown the thread
+ count = 0;
+ limit = LOOP_COUNT_SHORT;
+ while (count++ < limit && ! HttpService::isStopped())
+ {
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Thread actually stopped running", HttpService::isStopped());
+
+ // release options
+ opts->release();
+ opts = NULL;
+
+ // release the request object
+ delete req;
+ req = NULL;
+
+ // Shut down service
+ HttpRequest::destroyService();
+
+ ensure("Two handler calls on the way out", 2 == mHandlerCalls);
+
+#if 0 // defined(WIN32)
+ // Can't do this on any platform anymore, the LL logging system holds
+ // on to memory and produces what looks like memory leaks...
+
+ // printf("Old mem: %d, New mem: %d\n", mMemTotal, GetMemTotal());
+ ensure("Memory usage back to that at entry", mMemTotal == GetMemTotal());
+#endif
+ }
+ catch (...)
+ {
+ stop_thread(req);
+ if (opts)
+ {
+ opts->release();
+ opts = NULL;
+ }
+ delete req;
+ HttpRequest::destroyService();
+ throw;
+ }
+}
+
+
+template <> template <>
+void HttpRequestTestObjectType::test<8>()
+{
+ ScopedCurlInit ready;
+
+ std::string url_base(get_base_url());
+ // std::cerr << "Base: " << url_base << std::endl;
+
+ set_test_name("HttpRequest GET to real service");
+
+ // Handler can be stack-allocated *if* there are no dangling
+ // references to it after completion of this method.
+ // Create before memory record as the string copy will bump numbers.
+ TestHandler2 handler(this, "handler");
+
+ // record the total amount of dynamically allocated memory
+ mMemTotal = GetMemTotal();
+ mHandlerCalls = 0;
+
+ HttpRequest * req = NULL;
+
+ try
+ {
+ // Get singletons created
+ HttpRequest::createService();
+
+ // Start threading early so that thread memory is invariant
+ // over the test.
+ HttpRequest::startThread();
+
+ // create a new ref counted object with an implicit reference
+ req = new HttpRequest();
+ ensure("Memory allocated on construction", mMemTotal < GetMemTotal());
+
+ // Issue a GET that *can* connect
+ mStatus = HttpStatus(200);
+ HttpHandle handle = req->requestGet(HttpRequest::DEFAULT_POLICY_ID,
+ 0U,
+ url_base,
+ NULL,
+ NULL,
+ &handler);
+ ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID);
+
+ // Run the notification pump.
+ int count(0);
+ int limit(LOOP_COUNT_LONG);
+ while (count++ < limit && mHandlerCalls < 1)
+ {
+ req->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Request executed in reasonable time", count < limit);
+ ensure("One handler invocation for request", mHandlerCalls == 1);
+
+ // Okay, request a shutdown of the servicing thread
+ mStatus = HttpStatus();
+ handle = req->requestStopThread(&handler);
+ ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID);
+
+ // Run the notification pump again
+ count = 0;
+ limit = LOOP_COUNT_LONG;
+ while (count++ < limit && mHandlerCalls < 2)
+ {
+ req->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Second request executed in reasonable time", count < limit);
+ ensure("Second handler invocation", mHandlerCalls == 2);
+
+ // See that we actually shutdown the thread
+ count = 0;
+ limit = LOOP_COUNT_SHORT;
+ while (count++ < limit && ! HttpService::isStopped())
+ {
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Thread actually stopped running", HttpService::isStopped());
+
+ // release the request object
+ delete req;
+ req = NULL;
+
+ // Shut down service
+ HttpRequest::destroyService();
+
+ ensure("Two handler calls on the way out", 2 == mHandlerCalls);
+
+#if defined(WIN32)
+ // Can only do this memory test on Windows. On other platforms,
+ // the LL logging system holds on to memory and produces what looks
+ // like memory leaks...
+
+ // printf("Old mem: %d, New mem: %d\n", mMemTotal, GetMemTotal());
+ ensure("Memory usage back to that at entry", mMemTotal == GetMemTotal());
+#endif
+ }
+ catch (...)
+ {
+ stop_thread(req);
+ delete req;
+ HttpRequest::destroyService();
+ throw;
+ }
+}
+
+
+template <> template <>
+void HttpRequestTestObjectType::test<9>()
+{
+ ScopedCurlInit ready;
+
+ std::string url_base(get_base_url());
+ // std::cerr << "Base: " << url_base << std::endl;
+
+ set_test_name("HttpRequest GET with Range: header to real service");
+
+ // Handler can be stack-allocated *if* there are no dangling
+ // references to it after completion of this method.
+ // Create before memory record as the string copy will bump numbers.
+ TestHandler2 handler(this, "handler");
+
+ // record the total amount of dynamically allocated memory
+ mMemTotal = GetMemTotal();
+ mHandlerCalls = 0;
+
+ HttpRequest * req = NULL;
+
+ try
+ {
+ // Get singletons created
+ HttpRequest::createService();
+
+ // Start threading early so that thread memory is invariant
+ // over the test.
+ HttpRequest::startThread();
+
+ // create a new ref counted object with an implicit reference
+ req = new HttpRequest();
+ ensure("Memory allocated on construction", mMemTotal < GetMemTotal());
+
+ // Issue a GET that *can* connect
+ mStatus = HttpStatus(200);
+ HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID,
+ 0U,
+ url_base,
+ 0,
+ 0,
+ NULL,
+ NULL,
+ &handler);
+ ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID);
+
+ // Run the notification pump.
+ int count(0);
+ int limit(LOOP_COUNT_LONG);
+ while (count++ < limit && mHandlerCalls < 1)
+ {
+ req->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Request executed in reasonable time", count < limit);
+ ensure("One handler invocation for request", mHandlerCalls == 1);
+
+ // Okay, request a shutdown of the servicing thread
+ mStatus = HttpStatus();
+ handle = req->requestStopThread(&handler);
+ ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID);
+
+ // Run the notification pump again
+ count = 0;
+ limit = LOOP_COUNT_LONG;
+ while (count++ < limit && mHandlerCalls < 2)
+ {
+ req->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Second request executed in reasonable time", count < limit);
+ ensure("Second handler invocation", mHandlerCalls == 2);
+
+ // See that we actually shutdown the thread
+ count = 0;
+ limit = LOOP_COUNT_SHORT;
+ while (count++ < limit && ! HttpService::isStopped())
+ {
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Thread actually stopped running", HttpService::isStopped());
+
+ // release the request object
+ delete req;
+ req = NULL;
+
+ // Shut down service
+ HttpRequest::destroyService();
+
+ ensure("Two handler calls on the way out", 2 == mHandlerCalls);
+
+#if defined(WIN32)
+ // Can only do this memory test on Windows. On other platforms,
+ // the LL logging system holds on to memory and produces what looks
+ // like memory leaks...
+
+ // printf("Old mem: %d, New mem: %d\n", mMemTotal, GetMemTotal());
+ ensure("Memory usage back to that at entry", mMemTotal == GetMemTotal());
+#endif
+ }
+ catch (...)
+ {
+ stop_thread(req);
+ delete req;
+ HttpRequest::destroyService();
+ throw;
+ }
+}
+
+
+template <> template <>
+void HttpRequestTestObjectType::test<10>()
+{
+ ScopedCurlInit ready;
+
+ std::string url_base(get_base_url());
+ // std::cerr << "Base: " << url_base << std::endl;
+
+ set_test_name("HttpRequest PUT to real service");
+
+ // Handler can be stack-allocated *if* there are no dangling
+ // references to it after completion of this method.
+ // Create before memory record as the string copy will bump numbers.
+ TestHandler2 handler(this, "handler");
+
+ // record the total amount of dynamically allocated memory
+ mMemTotal = GetMemTotal();
+ mHandlerCalls = 0;
+
+ HttpRequest * req = NULL;
+ BufferArray * body = new BufferArray;
+
+ try
+ {
+ // Get singletons created
+ HttpRequest::createService();
+
+ // Start threading early so that thread memory is invariant
+ // over the test.
+ HttpRequest::startThread();
+
+ // create a new ref counted object with an implicit reference
+ req = new HttpRequest();
+ ensure("Memory allocated on construction", mMemTotal < GetMemTotal());
+
+ // Issue a GET that *can* connect
+ static const char * body_text("Now is the time for all good men...");
+ body->append(body_text, strlen(body_text));
+ mStatus = HttpStatus(200);
+ HttpHandle handle = req->requestPut(HttpRequest::DEFAULT_POLICY_ID,
+ 0U,
+ url_base,
+ body,
+ NULL,
+ NULL,
+ &handler);
+ ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID);
+
+ // Run the notification pump.
+ int count(0);
+ int limit(LOOP_COUNT_LONG);
+ while (count++ < limit && mHandlerCalls < 1)
+ {
+ req->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Request executed in reasonable time", count < limit);
+ ensure("One handler invocation for request", mHandlerCalls == 1);
+
+ // Okay, request a shutdown of the servicing thread
+ mStatus = HttpStatus();
+ handle = req->requestStopThread(&handler);
+ ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID);
+
+ // Run the notification pump again
+ count = 0;
+ limit = LOOP_COUNT_LONG;
+ while (count++ < limit && mHandlerCalls < 2)
+ {
+ req->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Second request executed in reasonable time", count < limit);
+ ensure("Second handler invocation", mHandlerCalls == 2);
+
+ // See that we actually shutdown the thread
+ count = 0;
+ limit = LOOP_COUNT_SHORT;
+ while (count++ < limit && ! HttpService::isStopped())
+ {
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Thread actually stopped running", HttpService::isStopped());
+
+ // Lose the request body
+ body->release();
+ body = NULL;
+
+ // release the request object
+ delete req;
+ req = NULL;
+
+ // Shut down service
+ HttpRequest::destroyService();
+
+ ensure("Two handler calls on the way out", 2 == mHandlerCalls);
+
+#if 0 // defined(WIN32)
+ // Can't do this on any platform anymore, the LL logging system holds
+ // on to memory and produces what looks like memory leaks...
+
+ // printf("Old mem: %d, New mem: %d\n", mMemTotal, GetMemTotal());
+ ensure("Memory usage back to that at entry", mMemTotal == GetMemTotal());
+#endif
+ }
+ catch (...)
+ {
+ if (body)
+ {
+ body->release();
+ }
+ stop_thread(req);
+ delete req;
+ HttpRequest::destroyService();
+ throw;
+ }
+}
+
+template <> template <>
+void HttpRequestTestObjectType::test<11>()
+{
+ ScopedCurlInit ready;
+
+ std::string url_base(get_base_url());
+ // std::cerr << "Base: " << url_base << std::endl;
+
+ set_test_name("HttpRequest POST to real service");
+
+ // Handler can be stack-allocated *if* there are no dangling
+ // references to it after completion of this method.
+ // Create before memory record as the string copy will bump numbers.
+ TestHandler2 handler(this, "handler");
+
+ // record the total amount of dynamically allocated memory
+ mMemTotal = GetMemTotal();
+ mHandlerCalls = 0;
+
+ HttpRequest * req = NULL;
+ BufferArray * body = new BufferArray;
+
+ try
+ {
+ // Get singletons created
+ HttpRequest::createService();
+
+ // Start threading early so that thread memory is invariant
+ // over the test.
+ HttpRequest::startThread();
+
+ // create a new ref counted object with an implicit reference
+ req = new HttpRequest();
+ ensure("Memory allocated on construction", mMemTotal < GetMemTotal());
+
+ // Issue a GET that *can* connect
+ static const char * body_text("Now is the time for all good men...");
+ body->append(body_text, strlen(body_text));
+ mStatus = HttpStatus(200);
+ HttpHandle handle = req->requestPost(HttpRequest::DEFAULT_POLICY_ID,
+ 0U,
+ url_base,
+ body,
+ NULL,
+ NULL,
+ &handler);
+ ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID);
+
+ // Run the notification pump.
+ int count(0);
+ int limit(LOOP_COUNT_LONG);
+ while (count++ < limit && mHandlerCalls < 1)
+ {
+ req->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Request executed in reasonable time", count < limit);
+ ensure("One handler invocation for request", mHandlerCalls == 1);
+
+ // Okay, request a shutdown of the servicing thread
+ mStatus = HttpStatus();
+ handle = req->requestStopThread(&handler);
+ ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID);
+
+ // Run the notification pump again
+ count = 0;
+ limit = LOOP_COUNT_LONG;
+ while (count++ < limit && mHandlerCalls < 2)
+ {
+ req->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Second request executed in reasonable time", count < limit);
+ ensure("Second handler invocation", mHandlerCalls == 2);
+
+ // See that we actually shutdown the thread
+ count = 0;
+ limit = LOOP_COUNT_SHORT;
+ while (count++ < limit && ! HttpService::isStopped())
+ {
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Thread actually stopped running", HttpService::isStopped());
+
+ // Lose the request body
+ body->release();
+ body = NULL;
+
+ // release the request object
+ delete req;
+ req = NULL;
+
+ // Shut down service
+ HttpRequest::destroyService();
+
+ ensure("Two handler calls on the way out", 2 == mHandlerCalls);
+
+#if defined(WIN32)
+ // Can only do this memory test on Windows. On other platforms,
+ // the LL logging system holds on to memory and produces what looks
+ // like memory leaks...
+
+ // printf("Old mem: %d, New mem: %d\n", mMemTotal, GetMemTotal());
+ ensure("Memory usage back to that at entry", mMemTotal == GetMemTotal());
+#endif
+ }
+ catch (...)
+ {
+ if (body)
+ {
+ body->release();
+ }
+ stop_thread(req);
+ delete req;
+ HttpRequest::destroyService();
+ throw;
+ }
+}
+
+template <> template <>
+void HttpRequestTestObjectType::test<12>()
+{
+ ScopedCurlInit ready;
+
+ std::string url_base(get_base_url());
+ // std::cerr << "Base: " << url_base << std::endl;
+
+ set_test_name("HttpRequest GET with some tracing");
+
+ // Handler can be stack-allocated *if* there are no dangling
+ // references to it after completion of this method.
+ // Create before memory record as the string copy will bump numbers.
+ TestHandler2 handler(this, "handler");
+
+ // record the total amount of dynamically allocated memory
+ mMemTotal = GetMemTotal();
+ mHandlerCalls = 0;
+
+ HttpRequest * req = NULL;
+
+ try
+ {
+ // Get singletons created
+ HttpRequest::createService();
+
+ // Enable tracing
+ HttpRequest::setPolicyGlobalOption(LLCore::HttpRequest::GP_TRACE, 2);
+
+ // Start threading early so that thread memory is invariant
+ // over the test.
+ HttpRequest::startThread();
+
+ // create a new ref counted object with an implicit reference
+ req = new HttpRequest();
+ ensure("Memory allocated on construction", mMemTotal < GetMemTotal());
+
+ // Issue a GET that *can* connect
+ mStatus = HttpStatus(200);
+ HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID,
+ 0U,
+ url_base,
+ 0,
+ 0,
+ NULL,
+ NULL,
+ &handler);
+ ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID);
+
+ // Run the notification pump.
+ int count(0);
+ int limit(LOOP_COUNT_LONG);
+ while (count++ < limit && mHandlerCalls < 1)
+ {
+ req->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Request executed in reasonable time", count < limit);
+ ensure("One handler invocation for request", mHandlerCalls == 1);
+
+ // Okay, request a shutdown of the servicing thread
+ mStatus = HttpStatus();
+ handle = req->requestStopThread(&handler);
+ ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID);
+
+ // Run the notification pump again
+ count = 0;
+ limit = LOOP_COUNT_LONG;
+ while (count++ < limit && mHandlerCalls < 2)
+ {
+ req->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Second request executed in reasonable time", count < limit);
+ ensure("Second handler invocation", mHandlerCalls == 2);
+
+ // See that we actually shutdown the thread
+ count = 0;
+ limit = LOOP_COUNT_SHORT;
+ while (count++ < limit && ! HttpService::isStopped())
+ {
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Thread actually stopped running", HttpService::isStopped());
+
+ // release the request object
+ delete req;
+ req = NULL;
+
+ // Shut down service
+ HttpRequest::destroyService();
+
+ ensure("Two handler calls on the way out", 2 == mHandlerCalls);
+
+#if 0 // defined(WIN32)
+ // Can't do this on any platform anymore, the LL logging system holds
+ // on to memory and produces what looks like memory leaks...
+
+ // printf("Old mem: %d, New mem: %d\n", mMemTotal, GetMemTotal());
+ ensure("Memory usage back to that at entry", mMemTotal == GetMemTotal());
+#endif
+ }
+ catch (...)
+ {
+ stop_thread(req);
+ delete req;
+ HttpRequest::destroyService();
+ throw;
+ }
+}
+
+
+template <> template <>
+void HttpRequestTestObjectType::test<13>()
+{
+ ScopedCurlInit ready;
+
+ // Warmup boost::regex to pre-alloc memory for memory size tests
+ boost::regex warmup("askldjflasdj;f", boost::regex::icase);
+ boost::regex_match("akl;sjflajfk;ajsk", warmup);
+
+ std::string url_base(get_base_url());
+ // std::cerr << "Base: " << url_base << std::endl;
+
+ set_test_name("HttpRequest GET with returned headers");
+
+ // Handler can be stack-allocated *if* there are no dangling
+ // references to it after completion of this method.
+ // Create before memory record as the string copy will bump numbers.
+ TestHandler2 handler(this, "handler");
+ handler.mHeadersRequired.reserve(20); // Avoid memory leak test failure
+
+ // record the total amount of dynamically allocated memory
+ mMemTotal = GetMemTotal();
+ mHandlerCalls = 0;
+
+ HttpRequest * req = NULL;
+ HttpOptions * opts = NULL;
+
+ try
+ {
+ // Get singletons created
+ HttpRequest::createService();
+
+ // Enable tracing
+ HttpRequest::setPolicyGlobalOption(LLCore::HttpRequest::GP_TRACE, 2);
+
+ // Start threading early so that thread memory is invariant
+ // over the test.
+ HttpRequest::startThread();
+
+ // create a new ref counted object with an implicit reference
+ req = new HttpRequest();
+ ensure("Memory allocated on construction", mMemTotal < GetMemTotal());
+
+ opts = new HttpOptions();
+ opts->setWantHeaders(true);
+
+ // Issue a GET that succeeds
+ mStatus = HttpStatus(200);
+ handler.mHeadersRequired.push_back(boost::regex("\\W*X-LL-Special:.*", boost::regex::icase));
+ HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID,
+ 0U,
+ url_base,
+ 0,
+ 0,
+ opts,
+ NULL,
+ &handler);
+ ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID);
+
+ // release options
+ opts->release();
+ opts = NULL;
+
+ // Run the notification pump.
+ int count(0);
+ int limit(LOOP_COUNT_LONG);
+ while (count++ < limit && mHandlerCalls < 1)
+ {
+ req->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Request executed in reasonable time", count < limit);
+ ensure("One handler invocation for request", mHandlerCalls == 1);
+
+ // Okay, request a shutdown of the servicing thread
+ mStatus = HttpStatus();
+ handler.mHeadersRequired.clear();
+ handle = req->requestStopThread(&handler);
+ ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID);
+
+ // Run the notification pump again
+ count = 0;
+ limit = LOOP_COUNT_LONG;
+ while (count++ < limit && mHandlerCalls < 2)
+ {
+ req->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Second request executed in reasonable time", count < limit);
+ ensure("Second handler invocation", mHandlerCalls == 2);
+
+ // See that we actually shutdown the thread
+ count = 0;
+ limit = LOOP_COUNT_SHORT;
+ while (count++ < limit && ! HttpService::isStopped())
+ {
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Thread actually stopped running", HttpService::isStopped());
+
+ // release the request object
+ delete req;
+ req = NULL;
+
+ // Shut down service
+ HttpRequest::destroyService();
+
+ ensure("Two handler calls on the way out", 2 == mHandlerCalls);
+
+#if defined(WIN32)
+ // Can only do this memory test on Windows. On other platforms,
+ // the LL logging system holds on to memory and produces what looks
+ // like memory leaks...
+
+ // printf("Old mem: %d, New mem: %d\n", mMemTotal, GetMemTotal());
+ ensure("Memory usage back to that at entry", mMemTotal == GetMemTotal());
+#endif
+ }
+ catch (...)
+ {
+ stop_thread(req);
+ if (opts)
+ {
+ opts->release();
+ opts = NULL;
+ }
+ delete req;
+ HttpRequest::destroyService();
+ throw;
+ }
+}
+
+
+template <> template <>
+void HttpRequestTestObjectType::test<14>()
+{
+ ScopedCurlInit ready;
+
+ set_test_name("HttpRequest GET timeout");
+
+ // Handler can be stack-allocated *if* there are no dangling
+ // references to it after completion of this method.
+ // Create before memory record as the string copy will bump numbers.
+ TestHandler2 handler(this, "handler");
+ std::string url_base(get_base_url() + "/sleep/"); // path to a 30-second sleep
+
+ // record the total amount of dynamically allocated memory
+ mMemTotal = GetMemTotal();
+ mHandlerCalls = 0;
+
+ HttpRequest * req = NULL;
+ HttpOptions * opts = NULL;
+
+ try
+ {
+ // Get singletons created
+ HttpRequest::createService();
+
+ // Start threading early so that thread memory is invariant
+ // over the test.
+ HttpRequest::startThread();
+
+ // create a new ref counted object with an implicit reference
+ req = new HttpRequest();
+ ensure("Memory allocated on construction", mMemTotal < GetMemTotal());
+
+ opts = new HttpOptions();
+ opts->setRetries(0); // Don't retry
+ opts->setTimeout(2);
+
+ // Issue a GET that sleeps
+ mStatus = HttpStatus(HttpStatus::EXT_CURL_EASY, CURLE_OPERATION_TIMEDOUT);
+ HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID,
+ 0U,
+ url_base,
+ 0,
+ 0,
+ opts,
+ NULL,
+ &handler);
+ ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID);
+
+ // Run the notification pump.
+ int count(0);
+ int limit(LOOP_COUNT_LONG);
+ while (count++ < limit && mHandlerCalls < 1)
+ {
+ req->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Request executed in reasonable time", count < limit);
+ ensure("One handler invocation for request", mHandlerCalls == 1);
+
+ // Okay, request a shutdown of the servicing thread
+ mStatus = HttpStatus();
+ handle = req->requestStopThread(&handler);
+ ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID);
+
+ // Run the notification pump again
+ count = 0;
+ limit = LOOP_COUNT_LONG;
+ while (count++ < limit && mHandlerCalls < 2)
+ {
+ req->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Second request executed in reasonable time", count < limit);
+ ensure("Second handler invocation", mHandlerCalls == 2);
+
+ // See that we actually shutdown the thread
+ count = 0;
+ limit = LOOP_COUNT_SHORT;
+ while (count++ < limit && ! HttpService::isStopped())
+ {
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Thread actually stopped running", HttpService::isStopped());
+
+ // release options
+ opts->release();
+ opts = NULL;
+
+ // release the request object
+ delete req;
+ req = NULL;
+
+ // Shut down service
+ HttpRequest::destroyService();
+
+ ensure("Two handler calls on the way out", 2 == mHandlerCalls);
+
+#if defined(WIN32)
+ // Can only do this memory test on Windows. On other platforms,
+ // the LL logging system holds on to memory and produces what looks
+ // like memory leaks...
+
+ // printf("Old mem: %d, New mem: %d\n", mMemTotal, GetMemTotal());
+ ensure("Memory usage back to that at entry", mMemTotal == GetMemTotal());
+#endif
+ }
+ catch (...)
+ {
+ stop_thread(req);
+ if (opts)
+ {
+ opts->release();
+ opts = NULL;
+ }
+ delete req;
+ HttpRequest::destroyService();
+ throw;
+ }
+}
+
+// Test retrieval of Content-Type/Content-Encoding headers
+template <> template <>
+void HttpRequestTestObjectType::test<15>()
+{
+ ScopedCurlInit ready;
+
+ std::string url_base(get_base_url());
+ // std::cerr << "Base: " << url_base << std::endl;
+
+ set_test_name("HttpRequest GET with Content-Type");
+
+ // Handler can be stack-allocated *if* there are no dangling
+ // references to it after completion of this method.
+ // Create before memory record as the string copy will bump numbers.
+ TestHandler2 handler(this, "handler");
+
+ // Load and clear the string setting to preload std::string object
+ // for memory return tests.
+ handler.mCheckContentType = "application/llsd+xml";
+ handler.mCheckContentType.clear();
+
+ // record the total amount of dynamically allocated memory
+ mMemTotal = GetMemTotal();
+ mHandlerCalls = 0;
+
+ HttpRequest * req = NULL;
+
+ try
+ {
+ // Get singletons created
+ HttpRequest::createService();
+
+ // Start threading early so that thread memory is invariant
+ // over the test.
+ HttpRequest::startThread();
+
+ // create a new ref counted object with an implicit reference
+ req = new HttpRequest();
+ ensure("Memory allocated on construction", mMemTotal < GetMemTotal());
+
+ // Issue a GET that *can* connect
+ mStatus = HttpStatus(200);
+ handler.mCheckContentType = "application/llsd+xml";
+ HttpHandle handle = req->requestGet(HttpRequest::DEFAULT_POLICY_ID,
+ 0U,
+ url_base,
+ NULL,
+ NULL,
+ &handler);
+ ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID);
+
+ // Run the notification pump.
+ int count(0);
+ int limit(LOOP_COUNT_LONG);
+ while (count++ < limit && mHandlerCalls < 1)
+ {
+ req->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Request executed in reasonable time", count < limit);
+ ensure("One handler invocation for request", mHandlerCalls == 1);
+
+ // Okay, request a shutdown of the servicing thread
+ mStatus = HttpStatus();
+ handler.mCheckContentType.clear();
+ handle = req->requestStopThread(&handler);
+ ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID);
+
+ // Run the notification pump again
+ count = 0;
+ limit = LOOP_COUNT_LONG;
+ while (count++ < limit && mHandlerCalls < 2)
+ {
+ req->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Second request executed in reasonable time", count < limit);
+ ensure("Second handler invocation", mHandlerCalls == 2);
+
+ // See that we actually shutdown the thread
+ count = 0;
+ limit = LOOP_COUNT_SHORT;
+ while (count++ < limit && ! HttpService::isStopped())
+ {
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Thread actually stopped running", HttpService::isStopped());
+
+ // release the request object
+ delete req;
+ req = NULL;
+
+ // Shut down service
+ HttpRequest::destroyService();
+
+ ensure("Two handler calls on the way out", 2 == mHandlerCalls);
+
+#if defined(WIN32)
+ // Can only do this memory test on Windows. On other platforms,
+ // the LL logging system holds on to memory and produces what looks
+ // like memory leaks...
+
+ // printf("Old mem: %d, New mem: %d\n", mMemTotal, GetMemTotal());
+ ensure("Memory usage back to that at entry", mMemTotal == GetMemTotal());
+#endif
+ }
+ catch (...)
+ {
+ stop_thread(req);
+ delete req;
+ HttpRequest::destroyService();
+ throw;
+ }
+}
+
+
+// Test header generation on GET requests
+template <> template <>
+void HttpRequestTestObjectType::test<16>()
+{
+ ScopedCurlInit ready;
+
+ // Warmup boost::regex to pre-alloc memory for memory size tests
+ boost::regex warmup("askldjflasdj;f", boost::regex::icase);
+ boost::regex_match("akl;sjflajfk;ajsk", warmup);
+
+ std::string url_base(get_base_url());
+
+ set_test_name("Header generation for HttpRequest GET");
+
+ // Handler can be stack-allocated *if* there are no dangling
+ // references to it after completion of this method.
+ // Create before memory record as the string copy will bump numbers.
+ TestHandler2 handler(this, "handler");
+
+ // record the total amount of dynamically allocated memory
+ mMemTotal = GetMemTotal();
+ mHandlerCalls = 0;
+
+ HttpRequest * req = NULL;
+ HttpOptions * options = NULL;
+ HttpHeaders * headers = NULL;
+
+ try
+ {
+ // Get singletons created
+ HttpRequest::createService();
+
+ // Start threading early so that thread memory is invariant
+ // over the test.
+ HttpRequest::startThread();
+
+ // create a new ref counted object with an implicit reference
+ req = new HttpRequest();
+
+ // options set
+ options = new HttpOptions();
+ options->setWantHeaders(true);
+
+ // Issue a GET that *can* connect
+ mStatus = HttpStatus(200);
+ handler.mHeadersRequired.push_back(boost::regex("X-Reflect-connection:\\s*keep-alive", boost::regex::icase));
+ handler.mHeadersRequired.push_back(boost::regex("X-Reflect-accept:\\s*\\*/\\*", boost::regex::icase));
+ handler.mHeadersRequired.push_back(boost::regex("X-Reflect-accept-encoding:\\s*((gzip|deflate),\\s*)+(gzip|deflate)", boost::regex::icase)); // close enough
+ handler.mHeadersRequired.push_back(boost::regex("X-Reflect-keep-alive:\\s*\\d+", boost::regex::icase));
+ handler.mHeadersRequired.push_back(boost::regex("X-Reflect-host:\\s*.*", boost::regex::icase));
+ handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-cache-control:.*", boost::regex::icase));
+ handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-pragma:.*", boost::regex::icase));
+ handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-range:.*", boost::regex::icase));
+ handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-transfer-encoding:.*", boost::regex::icase));
+ handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-referer:.*", boost::regex::icase));
+ handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-content-type:.*", boost::regex::icase));
+ handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-content-encoding:.*", boost::regex::icase));
+ HttpHandle handle = req->requestGet(HttpRequest::DEFAULT_POLICY_ID,
+ 0U,
+ url_base + "reflect/",
+ options,
+ NULL,
+ &handler);
+ ensure("Valid handle returned for get request", handle != LLCORE_HTTP_HANDLE_INVALID);
+
+ // Run the notification pump.
+ int count(0);
+ int limit(LOOP_COUNT_LONG);
+ while (count++ < limit && mHandlerCalls < 1)
+ {
+ req->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Request executed in reasonable time", count < limit);
+ ensure("One handler invocation for request", mHandlerCalls == 1);
+
+ // Do a texture-style fetch
+ headers = new HttpHeaders;
+ headers->mHeaders.push_back("Accept: image/x-j2c");
+
+ mStatus = HttpStatus(200);
+ handler.mHeadersRequired.clear();
+ handler.mHeadersDisallowed.clear();
+ handler.mHeadersRequired.push_back(boost::regex("X-Reflect-connection:\\s*keep-alive", boost::regex::icase));
+ handler.mHeadersRequired.push_back(boost::regex("X-Reflect-accept:\\s*image/x-j2c", boost::regex::icase));
+ handler.mHeadersRequired.push_back(boost::regex("X-Reflect-accept-encoding:\\s*((gzip|deflate),\\s*)+(gzip|deflate)", boost::regex::icase)); // close enough
+ handler.mHeadersRequired.push_back(boost::regex("X-Reflect-keep-alive:\\s*\\d+", boost::regex::icase));
+ handler.mHeadersRequired.push_back(boost::regex("X-Reflect-host:\\s*.*", boost::regex::icase));
+ handler.mHeadersRequired.push_back(boost::regex("\\W*X-Reflect-range:.*", boost::regex::icase));
+ handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-cache-control:.*", boost::regex::icase));
+ handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-pragma:.*", boost::regex::icase));
+ handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-transfer-encoding:.*", boost::regex::icase));
+ handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-referer:.*", boost::regex::icase));
+ handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-content-type:.*", boost::regex::icase));
+ handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-content-encoding:.*", boost::regex::icase));
+ handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID,
+ 0U,
+ url_base + "reflect/",
+ 0,
+ 47,
+ options,
+ headers,
+ &handler);
+ ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID);
+
+ // Run the notification pump.
+ count = 0;
+ limit = LOOP_COUNT_LONG;
+ while (count++ < limit && mHandlerCalls < 2)
+ {
+ req->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Request executed in reasonable time", count < limit);
+ ensure("One handler invocation for request", mHandlerCalls == 2);
+
+
+ // Okay, request a shutdown of the servicing thread
+ mStatus = HttpStatus();
+ handler.mHeadersRequired.clear();
+ handler.mHeadersDisallowed.clear();
+ handle = req->requestStopThread(&handler);
+ ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID);
+
+ // Run the notification pump again
+ count = 0;
+ limit = LOOP_COUNT_LONG;
+ while (count++ < limit && mHandlerCalls < 3)
+ {
+ req->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Second request executed in reasonable time", count < limit);
+ ensure("Second handler invocation", mHandlerCalls == 3);
+
+ // See that we actually shutdown the thread
+ count = 0;
+ limit = LOOP_COUNT_SHORT;
+ while (count++ < limit && ! HttpService::isStopped())
+ {
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Thread actually stopped running", HttpService::isStopped());
+
+ // release options & headers
+ if (options)
+ {
+ options->release();
+ }
+ options = NULL;
+
+ if (headers)
+ {
+ headers->release();
+ }
+ headers = NULL;
+
+ // release the request object
+ delete req;
+ req = NULL;
+
+ // Shut down service
+ HttpRequest::destroyService();
+ }
+ catch (...)
+ {
+ stop_thread(req);
+ if (options)
+ {
+ options->release();
+ options = NULL;
+ }
+ if (headers)
+ {
+ headers->release();
+ headers = NULL;
+ }
+ delete req;
+ HttpRequest::destroyService();
+ throw;
+ }
+}
+
+
+// Test header generation on POST requests
+template <> template <>
+void HttpRequestTestObjectType::test<17>()
+{
+ ScopedCurlInit ready;
+
+ // Warmup boost::regex to pre-alloc memory for memory size tests
+ boost::regex warmup("askldjflasdj;f", boost::regex::icase);
+ boost::regex_match("akl;sjflajfk;ajsk", warmup);
+
+ std::string url_base(get_base_url());
+
+ set_test_name("Header generation for HttpRequest POST");
+
+ // Handler can be stack-allocated *if* there are no dangling
+ // references to it after completion of this method.
+ // Create before memory record as the string copy will bump numbers.
+ TestHandler2 handler(this, "handler");
+
+ // record the total amount of dynamically allocated memory
+ mMemTotal = GetMemTotal();
+ mHandlerCalls = 0;
+
+ HttpRequest * req = NULL;
+ HttpOptions * options = NULL;
+ HttpHeaders * headers = NULL;
+ BufferArray * ba = NULL;
+
+ try
+ {
+ // Get singletons created
+ HttpRequest::createService();
+
+ // Start threading early so that thread memory is invariant
+ // over the test.
+ HttpRequest::startThread();
+
+ // create a new ref counted object with an implicit reference
+ req = new HttpRequest();
+
+ // options set
+ options = new HttpOptions();
+ options->setWantHeaders(true);
+
+ // And a buffer array
+ const char * msg("It was the best of times, it was the worst of times.");
+ ba = new BufferArray;
+ ba->append(msg, strlen(msg));
+
+ // Issue a default POST
+ mStatus = HttpStatus(200);
+ handler.mHeadersRequired.push_back(boost::regex("X-Reflect-connection:\\s*keep-alive", boost::regex::icase));
+ handler.mHeadersRequired.push_back(boost::regex("X-Reflect-accept:\\s*\\*/\\*", boost::regex::icase));
+ handler.mHeadersRequired.push_back(boost::regex("X-Reflect-accept-encoding:\\s*((gzip|deflate),\\s*)+(gzip|deflate)", boost::regex::icase)); // close enough
+ handler.mHeadersRequired.push_back(boost::regex("X-Reflect-keep-alive:\\s*\\d+", boost::regex::icase));
+ handler.mHeadersRequired.push_back(boost::regex("X-Reflect-host:\\s*.*", boost::regex::icase));
+ handler.mHeadersRequired.push_back(boost::regex("X-Reflect-content-length:\\s*\\d+", boost::regex::icase));
+ handler.mHeadersRequired.push_back(boost::regex("X-Reflect-content-type:\\s*application/x-www-form-urlencoded", boost::regex::icase));
+ handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-cache-control:.*", boost::regex::icase));
+ handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-pragma:.*", boost::regex::icase));
+ handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-range:.*", boost::regex::icase));
+ handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-referer:.*", boost::regex::icase));
+ handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-content-encoding:.*", boost::regex::icase));
+ handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-expect:.*", boost::regex::icase));
+ handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-transfer-encoding:\\s*.*chunked.*", boost::regex::icase));
+ HttpHandle handle = req->requestPost(HttpRequest::DEFAULT_POLICY_ID,
+ 0U,
+ url_base + "reflect/",
+ ba,
+ options,
+ NULL,
+ &handler);
+ ensure("Valid handle returned for get request", handle != LLCORE_HTTP_HANDLE_INVALID);
+ ba->release();
+ ba = NULL;
+
+ // Run the notification pump.
+ int count(0);
+ int limit(LOOP_COUNT_LONG);
+ while (count++ < limit && mHandlerCalls < 1)
+ {
+ req->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Request executed in reasonable time", count < limit);
+ ensure("One handler invocation for request", mHandlerCalls == 1);
+
+
+ // Okay, request a shutdown of the servicing thread
+ mStatus = HttpStatus();
+ handler.mHeadersRequired.clear();
+ handler.mHeadersDisallowed.clear();
+ handle = req->requestStopThread(&handler);
+ ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID);
+
+ // Run the notification pump again
+ count = 0;
+ limit = LOOP_COUNT_LONG;
+ while (count++ < limit && mHandlerCalls < 2)
+ {
+ req->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Second request executed in reasonable time", count < limit);
+ ensure("Second handler invocation", mHandlerCalls == 2);
+
+ // See that we actually shutdown the thread
+ count = 0;
+ limit = LOOP_COUNT_SHORT;
+ while (count++ < limit && ! HttpService::isStopped())
+ {
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Thread actually stopped running", HttpService::isStopped());
+
+ // release options & headers
+ if (options)
+ {
+ options->release();
+ }
+ options = NULL;
+
+ if (headers)
+ {
+ headers->release();
+ }
+ headers = NULL;
+
+ // release the request object
+ delete req;
+ req = NULL;
+
+ // Shut down service
+ HttpRequest::destroyService();
+ }
+ catch (...)
+ {
+ stop_thread(req);
+ if (ba)
+ {
+ ba->release();
+ ba = NULL;
+ }
+ if (options)
+ {
+ options->release();
+ options = NULL;
+ }
+ if (headers)
+ {
+ headers->release();
+ headers = NULL;
+ }
+ delete req;
+ HttpRequest::destroyService();
+ throw;
+ }
+}
+
+
+// Test header generation on PUT requests
+template <> template <>
+void HttpRequestTestObjectType::test<18>()
+{
+ ScopedCurlInit ready;
+
+ // Warmup boost::regex to pre-alloc memory for memory size tests
+ boost::regex warmup("askldjflasdj;f", boost::regex::icase);
+ boost::regex_match("akl;sjflajfk;ajsk", warmup);
+
+ std::string url_base(get_base_url());
+
+ set_test_name("Header generation for HttpRequest PUT");
+
+ // Handler can be stack-allocated *if* there are no dangling
+ // references to it after completion of this method.
+ // Create before memory record as the string copy will bump numbers.
+ TestHandler2 handler(this, "handler");
+
+ // record the total amount of dynamically allocated memory
+ mMemTotal = GetMemTotal();
+ mHandlerCalls = 0;
+
+ HttpRequest * req = NULL;
+ HttpOptions * options = NULL;
+ HttpHeaders * headers = NULL;
+ BufferArray * ba = NULL;
+
+ try
+ {
+ // Get singletons created
+ HttpRequest::createService();
+
+ // Start threading early so that thread memory is invariant
+ // over the test.
+ HttpRequest::startThread();
+
+ // create a new ref counted object with an implicit reference
+ req = new HttpRequest();
+
+ // options set
+ options = new HttpOptions();
+ options->setWantHeaders(true);
+
+ // And a buffer array
+ const char * msg("It was the best of times, it was the worst of times.");
+ ba = new BufferArray;
+ ba->append(msg, strlen(msg));
+
+ // Issue a default PUT
+ mStatus = HttpStatus(200);
+ handler.mHeadersRequired.push_back(boost::regex("X-Reflect-connection:\\s*keep-alive", boost::regex::icase));
+ handler.mHeadersRequired.push_back(boost::regex("X-Reflect-accept:\\s*\\*/\\*", boost::regex::icase));
+ handler.mHeadersRequired.push_back(boost::regex("X-Reflect-accept-encoding:\\s*((gzip|deflate),\\s*)+(gzip|deflate)", boost::regex::icase)); // close enough
+ handler.mHeadersRequired.push_back(boost::regex("X-Reflect-keep-alive:\\s*\\d+", boost::regex::icase));
+ handler.mHeadersRequired.push_back(boost::regex("X-Reflect-host:\\s*.*", boost::regex::icase));
+ handler.mHeadersRequired.push_back(boost::regex("X-Reflect-content-length:\\s*\\d+", boost::regex::icase));
+ handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-cache-control:.*", boost::regex::icase));
+ handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-pragma:.*", boost::regex::icase));
+ handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-range:.*", boost::regex::icase));
+ handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-referer:.*", boost::regex::icase));
+ handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-content-encoding:.*", boost::regex::icase));
+ handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-expect:.*", boost::regex::icase));
+ handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-transfer-encoding:\\s*.*chunked.*", boost::regex::icase));
+ handler.mHeadersDisallowed.push_back(boost::regex("X-Reflect-content-type:.*", boost::regex::icase));
+ HttpHandle handle = req->requestPut(HttpRequest::DEFAULT_POLICY_ID,
+ 0U,
+ url_base + "reflect/",
+ ba,
+ options,
+ NULL,
+ &handler);
+ ensure("Valid handle returned for get request", handle != LLCORE_HTTP_HANDLE_INVALID);
+ ba->release();
+ ba = NULL;
+
+ // Run the notification pump.
+ int count(0);
+ int limit(LOOP_COUNT_LONG);
+ while (count++ < limit && mHandlerCalls < 1)
+ {
+ req->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Request executed in reasonable time", count < limit);
+ ensure("One handler invocation for request", mHandlerCalls == 1);
+
+
+ // Okay, request a shutdown of the servicing thread
+ mStatus = HttpStatus();
+ handler.mHeadersRequired.clear();
+ handler.mHeadersDisallowed.clear();
+ handle = req->requestStopThread(&handler);
+ ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID);
+
+ // Run the notification pump again
+ count = 0;
+ limit = LOOP_COUNT_LONG;
+ while (count++ < limit && mHandlerCalls < 2)
+ {
+ req->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Second request executed in reasonable time", count < limit);
+ ensure("Second handler invocation", mHandlerCalls == 2);
+
+ // See that we actually shutdown the thread
+ count = 0;
+ limit = LOOP_COUNT_SHORT;
+ while (count++ < limit && ! HttpService::isStopped())
+ {
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Thread actually stopped running", HttpService::isStopped());
+
+ // release options & headers
+ if (options)
+ {
+ options->release();
+ }
+ options = NULL;
+
+ if (headers)
+ {
+ headers->release();
+ }
+ headers = NULL;
+
+ // release the request object
+ delete req;
+ req = NULL;
+
+ // Shut down service
+ HttpRequest::destroyService();
+ }
+ catch (...)
+ {
+ stop_thread(req);
+ if (ba)
+ {
+ ba->release();
+ ba = NULL;
+ }
+ if (options)
+ {
+ options->release();
+ options = NULL;
+ }
+ if (headers)
+ {
+ headers->release();
+ headers = NULL;
+ }
+ delete req;
+ HttpRequest::destroyService();
+ throw;
+ }
+}
+
+
+// Test header generation on GET requests with overrides
+template <> template <>
+void HttpRequestTestObjectType::test<19>()
+{
+ ScopedCurlInit ready;
+
+ // Warmup boost::regex to pre-alloc memory for memory size tests
+ boost::regex warmup("askldjflasdj;f", boost::regex::icase);
+ boost::regex_match("akl;sjflajfk;ajsk", warmup);
+
+ std::string url_base(get_base_url());
+
+ set_test_name("Header generation for HttpRequest GET with header overrides");
+
+ // Handler can be stack-allocated *if* there are no dangling
+ // references to it after completion of this method.
+ // Create before memory record as the string copy will bump numbers.
+ TestHandler2 handler(this, "handler");
+
+ // record the total amount of dynamically allocated memory
+ mMemTotal = GetMemTotal();
+ mHandlerCalls = 0;
+
+ HttpRequest * req = NULL;
+ HttpOptions * options = NULL;
+ HttpHeaders * headers = NULL;
+
+ try
+ {
+ // Get singletons created
+ HttpRequest::createService();
+
+ // Start threading early so that thread memory is invariant
+ // over the test.
+ HttpRequest::startThread();
+
+ // create a new ref counted object with an implicit reference
+ req = new HttpRequest();
+
+ // options set
+ options = new HttpOptions();
+ options->setWantHeaders(true);
+
+ // headers
+ headers = new HttpHeaders;
+ headers->mHeaders.push_back("Keep-Alive: 120");
+ headers->mHeaders.push_back("Accept-encoding: deflate");
+ headers->mHeaders.push_back("Accept: text/plain");
+
+ // Issue a GET with modified headers
+ mStatus = HttpStatus(200);
+ handler.mHeadersRequired.push_back(boost::regex("X-Reflect-connection:\\s*keep-alive", boost::regex::icase));
+ handler.mHeadersRequired.push_back(boost::regex("X-Reflect-accept:\\s*text/plain", boost::regex::icase));
+ handler.mHeadersRequired.push_back(boost::regex("X-Reflect-accept-encoding:\\s*deflate", boost::regex::icase)); // close enough
+ handler.mHeadersRequired.push_back(boost::regex("X-Reflect-keep-alive:\\s*120", boost::regex::icase));
+ handler.mHeadersRequired.push_back(boost::regex("X-Reflect-host:\\s*.*", boost::regex::icase));
+ handler.mHeadersDisallowed.push_back(boost::regex("X-Reflect-accept-encoding:\\s*((gzip|deflate),\\s*)+(gzip|deflate)", boost::regex::icase)); // close enough
+ handler.mHeadersDisallowed.push_back(boost::regex("X-Reflect-keep-alive:\\s*300", boost::regex::icase));
+ handler.mHeadersDisallowed.push_back(boost::regex("X-Reflect-accept:\\s*\\*/\\*", boost::regex::icase));
+ handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-cache-control:.*", boost::regex::icase));
+ handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-pragma:.*", boost::regex::icase));
+ handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-range:.*", boost::regex::icase));
+ handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-transfer-encoding:.*", boost::regex::icase));
+ handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-referer:.*", boost::regex::icase));
+ handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-content-type:.*", boost::regex::icase));
+ handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-content-encoding:.*", boost::regex::icase));
+ HttpHandle handle = req->requestGet(HttpRequest::DEFAULT_POLICY_ID,
+ 0U,
+ url_base + "reflect/",
+ options,
+ headers,
+ &handler);
+ ensure("Valid handle returned for get request", handle != LLCORE_HTTP_HANDLE_INVALID);
+
+ // Run the notification pump.
+ int count(0);
+ int limit(LOOP_COUNT_LONG);
+ while (count++ < limit && mHandlerCalls < 1)
+ {
+ req->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Request executed in reasonable time", count < limit);
+ ensure("One handler invocation for request", mHandlerCalls == 1);
+
+ // Okay, request a shutdown of the servicing thread
+ mStatus = HttpStatus();
+ handler.mHeadersRequired.clear();
+ handler.mHeadersDisallowed.clear();
+ handle = req->requestStopThread(&handler);
+ ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID);
+
+ // Run the notification pump again
+ count = 0;
+ limit = LOOP_COUNT_LONG;
+ while (count++ < limit && mHandlerCalls < 2)
+ {
+ req->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Second request executed in reasonable time", count < limit);
+ ensure("Second handler invocation", mHandlerCalls == 2);
+
+ // See that we actually shutdown the thread
+ count = 0;
+ limit = LOOP_COUNT_SHORT;
+ while (count++ < limit && ! HttpService::isStopped())
+ {
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Thread actually stopped running", HttpService::isStopped());
+
+ // release options & headers
+ if (options)
+ {
+ options->release();
+ }
+ options = NULL;
+
+ if (headers)
+ {
+ headers->release();
+ }
+ headers = NULL;
+
+ // release the request object
+ delete req;
+ req = NULL;
+
+ // Shut down service
+ HttpRequest::destroyService();
+ }
+ catch (...)
+ {
+ stop_thread(req);
+ if (options)
+ {
+ options->release();
+ options = NULL;
+ }
+ if (headers)
+ {
+ headers->release();
+ headers = NULL;
+ }
+ delete req;
+ HttpRequest::destroyService();
+ throw;
+ }
+}
+
+
+// Test header generation on POST requests with overrides
+template <> template <>
+void HttpRequestTestObjectType::test<20>()
+{
+ ScopedCurlInit ready;
+
+ // Warmup boost::regex to pre-alloc memory for memory size tests
+ boost::regex warmup("askldjflasdj;f", boost::regex::icase);
+ boost::regex_match("akl;sjflajfk;ajsk", warmup);
+
+ std::string url_base(get_base_url());
+
+ set_test_name("Header generation for HttpRequest POST with header overrides");
+
+ // Handler can be stack-allocated *if* there are no dangling
+ // references to it after completion of this method.
+ // Create before memory record as the string copy will bump numbers.
+ TestHandler2 handler(this, "handler");
+
+ // record the total amount of dynamically allocated memory
+ mMemTotal = GetMemTotal();
+ mHandlerCalls = 0;
+
+ HttpRequest * req = NULL;
+ HttpOptions * options = NULL;
+ HttpHeaders * headers = NULL;
+ BufferArray * ba = NULL;
+
+ try
+ {
+ // Get singletons created
+ HttpRequest::createService();
+
+ // Start threading early so that thread memory is invariant
+ // over the test.
+ HttpRequest::startThread();
+
+ // create a new ref counted object with an implicit reference
+ req = new HttpRequest();
+
+ // options set
+ options = new HttpOptions();
+ options->setWantHeaders(true);
+
+ // headers
+ headers = new HttpHeaders();
+ headers->mHeaders.push_back("keep-Alive: 120");
+ headers->mHeaders.push_back("Accept: text/html");
+ headers->mHeaders.push_back("content-type: application/llsd+xml");
+ headers->mHeaders.push_back("cache-control: no-store");
+
+ // And a buffer array
+ const char * msg("<xml><llsd><string>It was the best of times, it was the worst of times.</string></llsd></xml>");
+ ba = new BufferArray;
+ ba->append(msg, strlen(msg));
+
+ // Issue a default POST
+ mStatus = HttpStatus(200);
+ handler.mHeadersRequired.push_back(boost::regex("X-Reflect-connection:\\s*keep-alive", boost::regex::icase));
+ handler.mHeadersRequired.push_back(boost::regex("X-Reflect-accept:\\s*text/html", boost::regex::icase));
+ handler.mHeadersRequired.push_back(boost::regex("X-Reflect-accept-encoding:\\s*((gzip|deflate),\\s*)+(gzip|deflate)", boost::regex::icase)); // close enough
+ handler.mHeadersRequired.push_back(boost::regex("X-Reflect-keep-alive:\\s*120", boost::regex::icase));
+ handler.mHeadersRequired.push_back(boost::regex("X-Reflect-host:\\s*.*", boost::regex::icase));
+ handler.mHeadersRequired.push_back(boost::regex("X-Reflect-content-length:\\s*\\d+", boost::regex::icase));
+ handler.mHeadersRequired.push_back(boost::regex("X-Reflect-content-type:\\s*application/llsd\\+xml", boost::regex::icase));
+ handler.mHeadersRequired.push_back(boost::regex("\\s*X-Reflect-cache-control:\\s*no-store", boost::regex::icase));
+ handler.mHeadersDisallowed.push_back(boost::regex("X-Reflect-content-type:\\s*application/x-www-form-urlencoded", boost::regex::icase));
+ handler.mHeadersDisallowed.push_back(boost::regex("X-Reflect-accept:\\s*\\*/\\*", boost::regex::icase));
+ handler.mHeadersDisallowed.push_back(boost::regex("X-Reflect-keep-alive:\\s*300", boost::regex::icase));
+ handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-pragma:.*", boost::regex::icase));
+ handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-range:.*", boost::regex::icase));
+ handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-referer:.*", boost::regex::icase));
+ handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-content-encoding:.*", boost::regex::icase));
+ handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-expect:.*", boost::regex::icase));
+ handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-transfer-encoding:\\s*.*chunked.*", boost::regex::icase));
+ HttpHandle handle = req->requestPost(HttpRequest::DEFAULT_POLICY_ID,
+ 0U,
+ url_base + "reflect/",
+ ba,
+ options,
+ headers,
+ &handler);
+ ensure("Valid handle returned for get request", handle != LLCORE_HTTP_HANDLE_INVALID);
+ ba->release();
+ ba = NULL;
+
+ // Run the notification pump.
+ int count(0);
+ int limit(LOOP_COUNT_LONG);
+ while (count++ < limit && mHandlerCalls < 1)
+ {
+ req->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Request executed in reasonable time", count < limit);
+ ensure("One handler invocation for request", mHandlerCalls == 1);
+
+
+ // Okay, request a shutdown of the servicing thread
+ mStatus = HttpStatus();
+ handler.mHeadersRequired.clear();
+ handler.mHeadersDisallowed.clear();
+ handle = req->requestStopThread(&handler);
+ ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID);
+
+ // Run the notification pump again
+ count = 0;
+ limit = LOOP_COUNT_LONG;
+ while (count++ < limit && mHandlerCalls < 2)
+ {
+ req->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Second request executed in reasonable time", count < limit);
+ ensure("Second handler invocation", mHandlerCalls == 2);
+
+ // See that we actually shutdown the thread
+ count = 0;
+ limit = LOOP_COUNT_SHORT;
+ while (count++ < limit && ! HttpService::isStopped())
+ {
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Thread actually stopped running", HttpService::isStopped());
+
+ // release options & headers
+ if (options)
+ {
+ options->release();
+ }
+ options = NULL;
+
+ if (headers)
+ {
+ headers->release();
+ }
+ headers = NULL;
+
+ // release the request object
+ delete req;
+ req = NULL;
+
+ // Shut down service
+ HttpRequest::destroyService();
+ }
+ catch (...)
+ {
+ stop_thread(req);
+ if (ba)
+ {
+ ba->release();
+ ba = NULL;
+ }
+ if (options)
+ {
+ options->release();
+ options = NULL;
+ }
+ if (headers)
+ {
+ headers->release();
+ headers = NULL;
+ }
+ delete req;
+ HttpRequest::destroyService();
+ throw;
+ }
+}
+
+
+// Test header generation on PUT requests with overrides
+template <> template <>
+void HttpRequestTestObjectType::test<21>()
+{
+ ScopedCurlInit ready;
+
+ // Warmup boost::regex to pre-alloc memory for memory size tests
+ boost::regex warmup("askldjflasdj;f", boost::regex::icase);
+ boost::regex_match("akl;sjflajfk;ajsk", warmup);
+
+ std::string url_base(get_base_url());
+
+ set_test_name("Header generation for HttpRequest PUT with header overrides");
+
+ // Handler can be stack-allocated *if* there are no dangling
+ // references to it after completion of this method.
+ // Create before memory record as the string copy will bump numbers.
+ TestHandler2 handler(this, "handler");
+
+ // record the total amount of dynamically allocated memory
+ mMemTotal = GetMemTotal();
+ mHandlerCalls = 0;
+
+ HttpRequest * req = NULL;
+ HttpOptions * options = NULL;
+ HttpHeaders * headers = NULL;
+ BufferArray * ba = NULL;
+
+ try
+ {
+ // Get singletons created
+ HttpRequest::createService();
+
+ // Start threading early so that thread memory is invariant
+ // over the test.
+ HttpRequest::startThread();
+
+ // create a new ref counted object with an implicit reference
+ req = new HttpRequest();
+
+ // options set
+ options = new HttpOptions();
+ options->setWantHeaders(true);
+
+ // headers
+ headers = new HttpHeaders;
+ headers->mHeaders.push_back("content-type: text/plain");
+ headers->mHeaders.push_back("content-type: text/html");
+ headers->mHeaders.push_back("content-type: application/llsd+xml");
+
+ // And a buffer array
+ const char * msg("<xml><llsd><string>It was the best of times, it was the worst of times.</string></llsd></xml>");
+ ba = new BufferArray;
+ ba->append(msg, strlen(msg));
+
+ // Issue a default PUT
+ mStatus = HttpStatus(200);
+ handler.mHeadersRequired.push_back(boost::regex("X-Reflect-connection:\\s*keep-alive", boost::regex::icase));
+ handler.mHeadersRequired.push_back(boost::regex("X-Reflect-accept:\\s*\\*/\\*", boost::regex::icase));
+ handler.mHeadersRequired.push_back(boost::regex("X-Reflect-accept-encoding:\\s*((gzip|deflate),\\s*)+(gzip|deflate)", boost::regex::icase)); // close enough
+ handler.mHeadersRequired.push_back(boost::regex("X-Reflect-keep-alive:\\s*\\d+", boost::regex::icase));
+ handler.mHeadersRequired.push_back(boost::regex("X-Reflect-host:\\s*.*", boost::regex::icase));
+ handler.mHeadersRequired.push_back(boost::regex("X-Reflect-content-length:\\s*\\d+", boost::regex::icase));
+ handler.mHeadersRequired.push_back(boost::regex("X-Reflect-content-type:\\s*application/llsd\\+xml", boost::regex::icase));
+ handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-cache-control:.*", boost::regex::icase));
+ handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-pragma:.*", boost::regex::icase));
+ handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-range:.*", boost::regex::icase));
+ handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-referer:.*", boost::regex::icase));
+ handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-content-encoding:.*", boost::regex::icase));
+ handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-expect:.*", boost::regex::icase));
+ handler.mHeadersDisallowed.push_back(boost::regex("\\s*X-Reflect-transfer-encoding:\\s*.*chunked.*", boost::regex::icase));
+ handler.mHeadersDisallowed.push_back(boost::regex("X-Reflect-content-type:\\s*text/plain", boost::regex::icase));
+ handler.mHeadersDisallowed.push_back(boost::regex("X-Reflect-content-type:\\s*text/html", boost::regex::icase));
+ HttpHandle handle = req->requestPut(HttpRequest::DEFAULT_POLICY_ID,
+ 0U,
+ url_base + "reflect/",
+ ba,
+ options,
+ headers,
+ &handler);
+ ensure("Valid handle returned for get request", handle != LLCORE_HTTP_HANDLE_INVALID);
+ ba->release();
+ ba = NULL;
+
+ // Run the notification pump.
+ int count(0);
+ int limit(LOOP_COUNT_LONG);
+ while (count++ < limit && mHandlerCalls < 1)
+ {
+ req->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Request executed in reasonable time", count < limit);
+ ensure("One handler invocation for request", mHandlerCalls == 1);
+
+
+ // Okay, request a shutdown of the servicing thread
+ mStatus = HttpStatus();
+ handler.mHeadersRequired.clear();
+ handler.mHeadersDisallowed.clear();
+ handle = req->requestStopThread(&handler);
+ ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID);
+
+ // Run the notification pump again
+ count = 0;
+ limit = LOOP_COUNT_LONG;
+ while (count++ < limit && mHandlerCalls < 2)
+ {
+ req->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Second request executed in reasonable time", count < limit);
+ ensure("Second handler invocation", mHandlerCalls == 2);
+
+ // See that we actually shutdown the thread
+ count = 0;
+ limit = LOOP_COUNT_SHORT;
+ while (count++ < limit && ! HttpService::isStopped())
+ {
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Thread actually stopped running", HttpService::isStopped());
+
+ // release options & headers
+ if (options)
+ {
+ options->release();
+ }
+ options = NULL;
+
+ if (headers)
+ {
+ headers->release();
+ }
+ headers = NULL;
+
+ // release the request object
+ delete req;
+ req = NULL;
+
+ // Shut down service
+ HttpRequest::destroyService();
+ }
+ catch (...)
+ {
+ stop_thread(req);
+ if (ba)
+ {
+ ba->release();
+ ba = NULL;
+ }
+ if (options)
+ {
+ options->release();
+ options = NULL;
+ }
+ if (headers)
+ {
+ headers->release();
+ headers = NULL;
+ }
+ delete req;
+ HttpRequest::destroyService();
+ throw;
+ }
+}
+
+// BUG-2295 Tests - Content-Range header received but no body
+template <> template <>
+void HttpRequestTestObjectType::test<22>()
+{
+ ScopedCurlInit ready;
+
+ std::string url_base(get_base_url());
+ // std::cerr << "Base: " << url_base << std::endl;
+
+ set_test_name("BUG-2295");
+
+ // Handler can be stack-allocated *if* there are no dangling
+ // references to it after completion of this method.
+ // Create before memory record as the string copy will bump numbers.
+ TestHandler2 handler(this, "handler");
+
+ // record the total amount of dynamically allocated memory
+ mMemTotal = GetMemTotal();
+ mHandlerCalls = 0;
+
+ HttpOptions * options = NULL;
+ HttpRequest * req = NULL;
+
+ try
+ {
+ // options set
+ options = new HttpOptions();
+ options->setRetries(1); // Partial_File is retryable and can timeout in here
+
+ // Get singletons created
+ HttpRequest::createService();
+
+ // Start threading early so that thread memory is invariant
+ // over the test.
+ HttpRequest::startThread();
+
+ // create a new ref counted object with an implicit reference
+ req = new HttpRequest();
+ ensure("Memory allocated on construction", mMemTotal < GetMemTotal());
+
+ // ======================================
+ // Issue bug2295 GETs that will get a 206
+ // ======================================
+ mStatus = HttpStatus(206);
+ static const int test_count(3);
+ for (int i(0); i < test_count; ++i)
+ {
+ char buffer[128];
+ sprintf(buffer, "/bug2295/%d/", i);
+ HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID,
+ 0U,
+ url_base + buffer,
+ 0,
+ 25,
+ options,
+ NULL,
+ &handler);
+ ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID);
+ }
+
+ // Run the notification pump.
+ int count(0);
+ int limit(LOOP_COUNT_LONG);
+ while (count++ < limit && mHandlerCalls < test_count)
+ {
+ req->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Request executed in reasonable time - ms1", count < limit);
+ ensure("One handler invocation for each request - ms1", mHandlerCalls == test_count);
+
+ // ======================================
+ // Issue bug2295 GETs that will get a libcurl 18 (PARTIAL_FILE)
+ // ======================================
+ mHandlerCalls = 0;
+ mStatus = HttpStatus(HttpStatus::EXT_CURL_EASY, CURLE_PARTIAL_FILE);
+ static const int test2_count(1);
+ for (int i(0); i < test2_count; ++i)
+ {
+ char buffer[128];
+ sprintf(buffer, "/bug2295/00000012/%d/", i);
+ HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID,
+ 0U,
+ url_base + buffer,
+ 0,
+ 25,
+ options,
+ NULL,
+ &handler);
+ ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID);
+ }
+
+ // Run the notification pump.
+ count = 0;
+ limit = LOOP_COUNT_LONG;
+ while (count++ < limit && mHandlerCalls < test2_count)
+ {
+ req->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Request executed in reasonable time - ms2", count < limit);
+ ensure("One handler invocation for each request - ms2", mHandlerCalls == test2_count);
+
+ // ======================================
+ // Issue bug2295 GETs that will get an llcorehttp HE_INV_CONTENT_RANGE_HDR status
+ // ======================================
+ mHandlerCalls = 0;
+ mStatus = HttpStatus(HttpStatus::LLCORE, HE_INV_CONTENT_RANGE_HDR);
+ static const int test3_count(1);
+ for (int i(0); i < test3_count; ++i)
+ {
+ char buffer[128];
+ sprintf(buffer, "/bug2295/inv_cont_range/%d/", i);
+ HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID,
+ 0U,
+ url_base + buffer,
+ 0,
+ 25,
+ options,
+ NULL,
+ &handler);
+ ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID);
+ }
+
+ // Run the notification pump.
+ count = 0;
+ limit = LOOP_COUNT_LONG;
+ while (count++ < limit && mHandlerCalls < test3_count)
+ {
+ req->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Request executed in reasonable time - ms3", count < limit);
+ ensure("One handler invocation for each request - ms3", mHandlerCalls == test3_count);
+
+ // ======================================
+ // Okay, request a shutdown of the servicing thread
+ // ======================================
+ mStatus = HttpStatus();
+ mHandlerCalls = 0;
+ HttpHandle handle = req->requestStopThread(&handler);
+ ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID);
+
+ // Run the notification pump again
+ count = 0;
+ limit = LOOP_COUNT_LONG;
+ while (count++ < limit && mHandlerCalls < 1)
+ {
+ req->update(1000000);
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Shutdown request executed in reasonable time", count < limit);
+ ensure("Shutdown handler invocation", mHandlerCalls == 1);
+
+ // See that we actually shutdown the thread
+ count = 0;
+ limit = LOOP_COUNT_SHORT;
+ while (count++ < limit && ! HttpService::isStopped())
+ {
+ usleep(LOOP_SLEEP_INTERVAL);
+ }
+ ensure("Thread actually stopped running", HttpService::isStopped());
+
+ // release options
+ if (options)
+ {
+ options->release();
+ options = NULL;
+ }
+
+ // release the request object
+ delete req;
+ req = NULL;
+
+ // Shut down service
+ HttpRequest::destroyService();
+
+#if defined(WIN32)
+ // Can only do this memory test on Windows. On other platforms,
+ // the LL logging system holds on to memory and produces what looks
+ // like memory leaks...
+
+ // printf("Old mem: %d, New mem: %d\n", mMemTotal, GetMemTotal());
+ ensure("Memory usage back to that at entry", mMemTotal == GetMemTotal());
+#endif
+ }
+ catch (...)
+ {
+ stop_thread(req);
+ delete req;
+ HttpRequest::destroyService();
+ throw;
+ }
+}
+
+} // end namespace tut
+
+namespace
+{
+
+#if defined(WIN32)
+
+void usleep(unsigned long usec)
+{
+ Sleep((DWORD) (usec / 1000UL));
+}
+
+#endif
+
+}
+
+#endif // TEST_LLCORE_HTTP_REQUEST_H_
diff --git a/indra/llcorehttp/tests/test_httprequestqueue.hpp b/indra/llcorehttp/tests/test_httprequestqueue.hpp
new file mode 100755
index 0000000000..1de2d8f9ab
--- /dev/null
+++ b/indra/llcorehttp/tests/test_httprequestqueue.hpp
@@ -0,0 +1,186 @@
+/**
+ * @file test_httprequestqueue.hpp
+ * @brief unit tests for the LLCore::HttpRequestQueue class
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 TEST_LLCORE_HTTP_REQUESTQUEUE_H_
+#define TEST_LLCORE_HTTP_REQUESTQUEUE_H_
+
+#include "_httprequestqueue.h"
+
+#include <iostream>
+
+#include "test_allocator.h"
+#include "_httpoperation.h"
+
+
+using namespace LLCoreInt;
+
+
+
+namespace tut
+{
+
+struct HttpRequestqueueTestData
+{
+ // the test objects inherit from this so the member functions and variables
+ // can be referenced directly inside of the test functions.
+ size_t mMemTotal;
+};
+
+typedef test_group<HttpRequestqueueTestData> HttpRequestqueueTestGroupType;
+typedef HttpRequestqueueTestGroupType::object HttpRequestqueueTestObjectType;
+HttpRequestqueueTestGroupType HttpRequestqueueTestGroup("HttpRequestqueue Tests");
+
+template <> template <>
+void HttpRequestqueueTestObjectType::test<1>()
+{
+ set_test_name("HttpRequestQueue construction");
+
+ // record the total amount of dynamically allocated memory
+ mMemTotal = GetMemTotal();
+
+ // create a new ref counted object with an implicit reference
+ HttpRequestQueue::init();
+
+ ensure("One ref on construction of HttpRequestQueue", HttpRequestQueue::instanceOf()->getRefCount() == 1);
+ ensure("Memory being used", mMemTotal < GetMemTotal());
+
+ // release the implicit reference, causing the object to be released
+ HttpRequestQueue::term();
+
+ // make sure we didn't leak any memory
+ ensure(mMemTotal == GetMemTotal());
+}
+
+template <> template <>
+void HttpRequestqueueTestObjectType::test<2>()
+{
+ set_test_name("HttpRequestQueue refcount works");
+
+ // record the total amount of dynamically allocated memory
+ mMemTotal = GetMemTotal();
+
+ // create a new ref counted object with an implicit reference
+ HttpRequestQueue::init();
+
+ HttpRequestQueue * rq = HttpRequestQueue::instanceOf();
+ rq->addRef();
+
+ // release the singleton, hold on to the object
+ HttpRequestQueue::term();
+
+ ensure("One ref after term() called", rq->getRefCount() == 1);
+ ensure("Memory being used", mMemTotal < GetMemTotal());
+
+ // Drop ref
+ rq->release();
+
+ // make sure we didn't leak any memory
+ ensure(mMemTotal == GetMemTotal());
+}
+
+template <> template <>
+void HttpRequestqueueTestObjectType::test<3>()
+{
+ set_test_name("HttpRequestQueue addOp/fetchOp work");
+
+ // record the total amount of dynamically allocated memory
+ mMemTotal = GetMemTotal();
+
+ // create a new ref counted object with an implicit reference
+ HttpRequestQueue::init();
+
+ HttpRequestQueue * rq = HttpRequestQueue::instanceOf();
+
+ HttpOperation * op = new HttpOpNull();
+
+ rq->addOp(op); // transfer my refcount
+
+ op = rq->fetchOp(true); // Potentially hangs the test on failure
+ ensure("One goes in, one comes out", NULL != op);
+ op->release();
+
+ op = rq->fetchOp(false);
+ ensure("Better not be two of them", NULL == op);
+
+ // release the singleton, hold on to the object
+ HttpRequestQueue::term();
+
+ // make sure we didn't leak any memory
+ ensure(mMemTotal == GetMemTotal());
+}
+
+template <> template <>
+void HttpRequestqueueTestObjectType::test<4>()
+{
+ set_test_name("HttpRequestQueue addOp/fetchAll work");
+
+ // record the total amount of dynamically allocated memory
+ mMemTotal = GetMemTotal();
+
+ // create a new ref counted object with an implicit reference
+ HttpRequestQueue::init();
+
+ HttpRequestQueue * rq = HttpRequestQueue::instanceOf();
+
+ HttpOperation * op = new HttpOpNull();
+ rq->addOp(op); // transfer my refcount
+
+ op = new HttpOpNull();
+ rq->addOp(op); // transfer my refcount
+
+ op = new HttpOpNull();
+ rq->addOp(op); // transfer my refcount
+
+ {
+ HttpRequestQueue::OpContainer ops;
+ rq->fetchAll(true, ops); // Potentially hangs the test on failure
+ ensure("Three go in, three come out", 3 == ops.size());
+
+ op = rq->fetchOp(false);
+ ensure("Better not be any more of them", NULL == op);
+
+ // release the singleton, hold on to the object
+ HttpRequestQueue::term();
+
+ // We're still holding onto the ops.
+ ensure(mMemTotal < GetMemTotal());
+
+ // Release them
+ while (! ops.empty())
+ {
+ HttpOperation * op = ops.front();
+ ops.erase(ops.begin());
+ op->release();
+ }
+ }
+
+ // Should be clean
+ ensure("All memory returned", mMemTotal == GetMemTotal());
+}
+
+} // end namespace tut
+
+
+#endif // TEST_LLCORE_HTTP_REQUESTQUEUE_H_
diff --git a/indra/llcorehttp/tests/test_httpstatus.hpp b/indra/llcorehttp/tests/test_httpstatus.hpp
new file mode 100755
index 0000000000..b5538528c5
--- /dev/null
+++ b/indra/llcorehttp/tests/test_httpstatus.hpp
@@ -0,0 +1,265 @@
+/**
+ * @file test_llrefcounted
+ * @brief unit tests for HttpStatus struct
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012-2013, 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 TEST_HTTP_STATUS_H_
+#define TEST_HTTP_STATUS_H_
+
+#include "httpcommon.h"
+
+#include <curl/curl.h>
+#include <curl/multi.h>
+
+using namespace LLCore;
+
+namespace tut
+{
+
+struct HttpStatusTestData
+{
+ HttpStatusTestData()
+ {}
+};
+
+typedef test_group<HttpStatusTestData> HttpStatusTestGroupType;
+typedef HttpStatusTestGroupType::object HttpStatusTestObjectType;
+
+HttpStatusTestGroupType HttpStatusTestGroup("HttpStatus Tests");
+
+template <> template <>
+void HttpStatusTestObjectType::test<1>()
+{
+ set_test_name("HttpStatus construction");
+
+ // auto allocation fine for this
+ HttpStatus status;
+ status.mType = HttpStatus::EXT_CURL_EASY;
+ status.mStatus = 0;
+
+ ensure(bool(status));
+ ensure(false == !(status));
+
+ status.mType = HttpStatus::EXT_CURL_MULTI;
+ status.mStatus = 0;
+
+ ensure(bool(status));
+ ensure(false == !(status));
+
+ status.mType = HttpStatus::LLCORE;
+ status.mStatus = HE_SUCCESS;
+
+ ensure(bool(status));
+ ensure(false == !(status));
+
+ status.mType = HttpStatus::EXT_CURL_MULTI;
+ status.mStatus = -1;
+
+ ensure(false == bool(status));
+ ensure(!(status));
+
+ status.mType = HttpStatus::EXT_CURL_EASY;
+ status.mStatus = CURLE_BAD_DOWNLOAD_RESUME;
+
+ ensure(false == bool(status));
+ ensure(!(status));
+}
+
+
+template <> template <>
+void HttpStatusTestObjectType::test<2>()
+{
+ set_test_name("HttpStatus memory structure");
+
+ // Require that an HttpStatus object can be trivially
+ // returned as a function return value in registers.
+ // One should fit in an int on all platforms.
+
+ ensure(sizeof(HttpStatus) <= sizeof(int));
+}
+
+
+template <> template <>
+void HttpStatusTestObjectType::test<3>()
+{
+ set_test_name("HttpStatus valid status string conversion");
+
+ HttpStatus status;
+ status.mType = HttpStatus::EXT_CURL_EASY;
+ status.mStatus = 0;
+ std::string msg = status.toString();
+ // std::cout << "Result: " << msg << std::endl;
+ ensure(msg.empty());
+
+ status.mType = HttpStatus::EXT_CURL_EASY;
+ status.mStatus = CURLE_BAD_FUNCTION_ARGUMENT;
+ msg = status.toString();
+ // std::cout << "Result: " << msg << std::endl;
+ ensure(! msg.empty());
+
+ status.mType = HttpStatus::EXT_CURL_MULTI;
+ status.mStatus = CURLM_OUT_OF_MEMORY;
+ msg = status.toString();
+ // std::cout << "Result: " << msg << std::endl;
+ ensure(! msg.empty());
+
+ status.mType = HttpStatus::LLCORE;
+ status.mStatus = HE_SHUTTING_DOWN;
+ msg = status.toString();
+ // std::cout << "Result: " << msg << std::endl;
+ ensure(! msg.empty());
+}
+
+
+template <> template <>
+void HttpStatusTestObjectType::test<4>()
+{
+ set_test_name("HttpStatus invalid status string conversion");
+
+ HttpStatus status;
+ status.mType = HttpStatus::EXT_CURL_EASY;
+ status.mStatus = 32726;
+ std::string msg = status.toString();
+ // std::cout << "Result: " << msg << std::endl;
+ ensure(! msg.empty());
+
+ status.mType = HttpStatus::EXT_CURL_MULTI;
+ status.mStatus = -470;
+ msg = status.toString();
+ // std::cout << "Result: " << msg << std::endl;
+ ensure(! msg.empty());
+
+ status.mType = HttpStatus::LLCORE;
+ status.mStatus = 923;
+ msg = status.toString();
+ // std::cout << "Result: " << msg << std::endl;
+ ensure(! msg.empty());
+}
+
+template <> template <>
+void HttpStatusTestObjectType::test<5>()
+{
+ set_test_name("HttpStatus equality/inequality testing");
+
+ // Make certain equality/inequality tests do not pass
+ // through the bool conversion. Distinct successful
+ // and error statuses should compare unequal.
+
+ HttpStatus status1(HttpStatus::LLCORE, HE_SUCCESS);
+ HttpStatus status2(HttpStatus::EXT_CURL_EASY, HE_SUCCESS);
+ ensure(status1 != status2);
+
+ status1.mType = HttpStatus::LLCORE;
+ status1.mStatus = HE_REPLY_ERROR;
+ status2.mType = HttpStatus::LLCORE;
+ status2.mStatus= HE_SHUTTING_DOWN;
+ ensure(status1 != status2);
+}
+
+template <> template <>
+void HttpStatusTestObjectType::test<6>()
+{
+ set_test_name("HttpStatus basic HTTP status encoding");
+
+ HttpStatus status;
+ status.mType = 200;
+ status.mStatus = HE_SUCCESS;
+ std::string msg = status.toString();
+ ensure(msg.empty());
+ ensure(bool(status));
+
+ // Normally a success but application says error
+ status.mStatus = HE_REPLY_ERROR;
+ msg = status.toString();
+ ensure(! msg.empty());
+ ensure(! bool(status));
+ ensure(status.toULong() > 1UL); // Biggish number, not a bool-to-ulong
+
+ // Same statuses with distinct success/fail are distinct
+ status.mType = 200;
+ status.mStatus = HE_SUCCESS;
+ HttpStatus status2(200, HE_REPLY_ERROR);
+ ensure(status != status2);
+
+ // Normally an error but application says okay
+ status.mType = 406;
+ status.mStatus = HE_SUCCESS;
+ msg = status.toString();
+ ensure(msg.empty());
+ ensure(bool(status));
+
+ // Different statuses but both successful are distinct
+ status.mType = 200;
+ status.mStatus = HE_SUCCESS;
+ status2.mType = 201;
+ status2.mStatus = HE_SUCCESS;
+ ensure(status != status2);
+
+ // Different statuses but both failed are distinct
+ status.mType = 200;
+ status.mStatus = HE_REPLY_ERROR;
+ status2.mType = 201;
+ status2.mStatus = HE_REPLY_ERROR;
+ ensure(status != status2);
+}
+
+template <> template <>
+void HttpStatusTestObjectType::test<7>()
+{
+ set_test_name("HttpStatus HTTP status text strings");
+
+ HttpStatus status(100, HE_REPLY_ERROR);
+ std::string msg(status.toString());
+ ensure(! msg.empty()); // Should be something
+ ensure(msg == "Continue");
+
+ status.mStatus = HE_SUCCESS;
+ msg = status.toString();
+ ensure(msg.empty()); // Success is empty
+
+ status.mType = 199;
+ status.mStatus = HE_REPLY_ERROR;
+ msg = status.toString();
+ ensure(msg == "Unknown error");
+
+ status.mType = 505; // Last defined string
+ status.mStatus = HE_REPLY_ERROR;
+ msg = status.toString();
+ ensure(msg == "HTTP Version not supported");
+
+ status.mType = 506; // One beyond
+ status.mStatus = HE_REPLY_ERROR;
+ msg = status.toString();
+ ensure(msg == "Unknown error");
+
+ status.mType = 999; // Last HTTP status
+ status.mStatus = HE_REPLY_ERROR;
+ msg = status.toString();
+ ensure(msg == "Unknown error");
+}
+
+} // end namespace tut
+
+#endif // TEST_HTTP_STATUS_H
+
diff --git a/indra/llcorehttp/tests/test_llcorehttp_peer.py b/indra/llcorehttp/tests/test_llcorehttp_peer.py
new file mode 100755
index 0000000000..3c3af8dc75
--- /dev/null
+++ b/indra/llcorehttp/tests/test_llcorehttp_peer.py
@@ -0,0 +1,274 @@
+#!/usr/bin/env python
+"""\
+@file test_llsdmessage_peer.py
+@author Nat Goodspeed
+@date 2008-10-09
+@brief This script asynchronously runs the executable (with args) specified on
+ the command line, returning its result code. While that executable is
+ running, we provide dummy local services for use by C++ tests.
+
+$LicenseInfo:firstyear=2008&license=viewerlgpl$
+Second Life Viewer Source Code
+Copyright (C) 2012-2013, Linden Research, Inc.
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation;
+version 2.1 of the License only.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+$/LicenseInfo$
+"""
+
+import os
+import sys
+import time
+import select
+import getopt
+from threading import Thread
+try:
+ from cStringIO import StringIO
+except ImportError:
+ from StringIO import StringIO
+from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
+from SocketServer import ThreadingMixIn
+
+mydir = os.path.dirname(__file__) # expected to be .../indra/llcorehttp/tests/
+sys.path.insert(0, os.path.join(mydir, os.pardir, os.pardir, "lib", "python"))
+from indra.util.fastest_elementtree import parse as xml_parse
+from indra.base import llsd
+from testrunner import freeport, run, debug, VERBOSE
+
+class TestHTTPRequestHandler(BaseHTTPRequestHandler):
+ """This subclass of BaseHTTPRequestHandler is to receive and echo
+ LLSD-flavored messages sent by the C++ LLHTTPClient.
+
+ Target URLs are fairly free-form and are assembled by
+ concatinating fragments. Currently defined fragments
+ are:
+ - '/reflect/' Request headers are bounced back to caller
+ after prefixing with 'X-Reflect-'
+ - '/fail/' Body of request can contain LLSD with
+ 'reason' string and 'status' integer
+ which will become response header.
+ - '/bug2295/' 206 response, no data in body:
+ -- '/bug2295/0/' "Content-Range: bytes 0-75/2983"
+ -- '/bug2295/1/' "Content-Range: bytes 0-75/*"
+ -- '/bug2295/2/' "Content-Range: bytes 0-75/2983",
+ "Content-Length: 0"
+ -- '/bug2295/00000018/0/' Generates PARTIAL_FILE (18) error in libcurl.
+ "Content-Range: bytes 0-75/2983",
+ "Content-Length: 76"
+ -- '/bug2295/inv_cont_range/0/' Generates HE_INVALID_CONTENT_RANGE error in llcorehttp.
+
+ Some combinations make no sense, there's no effort to protect
+ you from that.
+ """
+ ignore_exceptions = (Exception,)
+
+ def read(self):
+ # The following logic is adapted from the library module
+ # SimpleXMLRPCServer.py.
+ # Get arguments by reading body of request.
+ # We read this in chunks to avoid straining
+ # socket.read(); around the 10 or 15Mb mark, some platforms
+ # begin to have problems (bug #792570).
+ try:
+ size_remaining = int(self.headers["content-length"])
+ except (KeyError, ValueError):
+ return ""
+ max_chunk_size = 10*1024*1024
+ L = []
+ while size_remaining:
+ chunk_size = min(size_remaining, max_chunk_size)
+ chunk = self.rfile.read(chunk_size)
+ L.append(chunk)
+ size_remaining -= len(chunk)
+ return ''.join(L)
+ # end of swiped read() logic
+
+ def read_xml(self):
+ # This approach reads the entire POST data into memory first
+ return llsd.parse(self.read())
+## # This approach attempts to stream in the LLSD XML from self.rfile,
+## # assuming that the underlying XML parser reads its input file
+## # incrementally. Unfortunately I haven't been able to make it work.
+## tree = xml_parse(self.rfile)
+## debug("Finished raw parse")
+## debug("parsed XML tree %s", tree)
+## debug("parsed root node %s", tree.getroot())
+## debug("root node tag %s", tree.getroot().tag)
+## return llsd.to_python(tree.getroot())
+
+ def do_HEAD(self):
+ self.do_GET(withdata=False)
+
+ def do_GET(self, withdata=True):
+ # Of course, don't attempt to read data.
+ try:
+ self.answer(dict(reply="success", status=200,
+ reason="Your GET operation worked"))
+ except self.ignore_exceptions, e:
+ print >> sys.stderr, "Exception during GET (ignoring): %s" % str(e)
+
+ def do_POST(self):
+ # Read the provided POST data.
+ # self.answer(self.read())
+ try:
+ self.answer(dict(reply="success", status=200,
+ reason=self.read()))
+ except self.ignore_exceptions, e:
+ print >> sys.stderr, "Exception during POST (ignoring): %s" % str(e)
+
+ def do_PUT(self):
+ # Read the provided PUT data.
+ # self.answer(self.read())
+ try:
+ self.answer(dict(reply="success", status=200,
+ reason=self.read()))
+ except self.ignore_exceptions, e:
+ print >> sys.stderr, "Exception during PUT (ignoring): %s" % str(e)
+
+ def answer(self, data, withdata=True):
+ debug("%s.answer(%s): self.path = %r", self.__class__.__name__, data, self.path)
+ if "/sleep/" in self.path:
+ time.sleep(30)
+
+ if "fail" in self.path:
+ status = data.get("status", 500)
+ # self.responses maps an int status to a (short, long) pair of
+ # strings. We want the longer string. That's why we pass a string
+ # pair to get(): the [1] will select the second string, whether it
+ # came from self.responses or from our default pair.
+ reason = data.get("reason",
+ self.responses.get(status,
+ ("fail requested",
+ "Your request specified failure status %s "
+ "without providing a reason" % status))[1])
+ debug("fail requested: %s: %r", status, reason)
+ self.send_error(status, reason)
+ if "/reflect/" in self.path:
+ self.reflect_headers()
+ self.end_headers()
+ elif "/bug2295/" in self.path:
+ # Test for https://jira.secondlife.com/browse/BUG-2295
+ #
+ # Client can receive a header indicating data should
+ # appear in the body without actually getting the body.
+ # Library needs to defend against this case.
+ #
+ body = None
+ if "/bug2295/0/" in self.path:
+ self.send_response(206)
+ self.send_header("Content-Range", "bytes 0-75/2983")
+ elif "/bug2295/1/" in self.path:
+ self.send_response(206)
+ self.send_header("Content-Range", "bytes 0-75/*")
+ elif "/bug2295/2/" in self.path:
+ self.send_response(206)
+ self.send_header("Content-Range", "bytes 0-75/2983")
+ self.send_header("Content-Length", "0")
+ elif "/bug2295/00000012/0/" in self.path:
+ self.send_response(206)
+ self.send_header("Content-Range", "bytes 0-75/2983")
+ self.send_header("Content-Length", "76")
+ elif "/bug2295/inv_cont_range/0/" in self.path:
+ self.send_response(206)
+ self.send_header("Content-Range", "bytes 0-75/2983")
+ body = "Some text, but not enough."
+ else:
+ # Unknown request
+ self.send_response(400)
+ if "/reflect/" in self.path:
+ self.reflect_headers()
+ self.send_header("Content-type", "text/plain")
+ self.end_headers()
+ if body:
+ self.wfile.write(body)
+ else:
+ # Normal response path
+ data = data.copy() # we're going to modify
+ # Ensure there's a "reply" key in data, even if there wasn't before
+ data["reply"] = data.get("reply", llsd.LLSD("success"))
+ response = llsd.format_xml(data)
+ debug("success: %s", response)
+ self.send_response(200)
+ if "/reflect/" in self.path:
+ self.reflect_headers()
+ self.send_header("Content-type", "application/llsd+xml")
+ self.send_header("Content-Length", str(len(response)))
+ self.send_header("X-LL-Special", "Mememememe");
+ self.end_headers()
+ if withdata:
+ self.wfile.write(response)
+
+ def reflect_headers(self):
+ for name in self.headers.keys():
+ # print "Header: %s: %s" % (name, self.headers[name])
+ self.send_header("X-Reflect-" + name, self.headers[name])
+
+ if not VERBOSE:
+ # When VERBOSE is set, skip both these overrides because they exist to
+ # suppress output.
+
+ def log_request(self, code, size=None):
+ # For present purposes, we don't want the request splattered onto
+ # stderr, as it would upset devs watching the test run
+ pass
+
+ def log_error(self, format, *args):
+ # Suppress error output as well
+ pass
+
+class Server(ThreadingMixIn, HTTPServer):
+ # This pernicious flag is on by default in HTTPServer. But proper
+ # operation of freeport() absolutely depends on it being off.
+ allow_reuse_address = False
+
+ # Override of BaseServer.handle_error(). Not too interested
+ # in errors and the default handler emits a scary traceback
+ # to stderr which annoys some. Disable this override to get
+ # default behavior which *shouldn't* cause the program to return
+ # a failure status.
+ def handle_error(self, request, client_address):
+ print '-'*40
+ print 'Ignoring exception during processing of request from',
+ print client_address
+ print '-'*40
+
+if __name__ == "__main__":
+ do_valgrind = False
+ path_search = False
+ options, args = getopt.getopt(sys.argv[1:], "V", ["valgrind"])
+ for option, value in options:
+ if option == "-V" or option == "--valgrind":
+ do_valgrind = True
+
+ # Instantiate a Server(TestHTTPRequestHandler) on the first free port
+ # in the specified port range. Doing this inline is better than in a
+ # daemon thread: if it blows up here, we'll get a traceback. If it blew up
+ # in some other thread, the traceback would get eaten and we'd run the
+ # subject test program anyway.
+ httpd, port = freeport(xrange(8000, 8020),
+ lambda port: Server(('127.0.0.1', port), TestHTTPRequestHandler))
+
+ # Pass the selected port number to the subject test program via the
+ # environment. We don't want to impose requirements on the test program's
+ # command-line parsing -- and anyway, for C++ integration tests, that's
+ # performed in TUT code rather than our own.
+ os.environ["LL_TEST_PORT"] = str(port)
+ debug("$LL_TEST_PORT = %s", port)
+ if do_valgrind:
+ args = ["valgrind", "--log-file=./valgrind.log"] + args
+ path_search = True
+ sys.exit(run(server=Thread(name="httpd", target=httpd.serve_forever), use_path=path_search, *args))
+
diff --git a/indra/llcorehttp/tests/test_refcounted.hpp b/indra/llcorehttp/tests/test_refcounted.hpp
new file mode 100755
index 0000000000..cb4b50287a
--- /dev/null
+++ b/indra/llcorehttp/tests/test_refcounted.hpp
@@ -0,0 +1,156 @@
+/**
+ * @file test_refcounted.hpp
+ * @brief unit tests for the LLCoreInt::RefCounted class
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 TEST_LLCOREINT_REF_COUNTED_H_
+#define TEST_LLCOREINT_REF_COUNTED_H_
+
+#include "_refcounted.h"
+
+#include "test_allocator.h"
+
+using namespace LLCoreInt;
+
+namespace tut
+{
+ struct RefCountedTestData
+ {
+ // the test objects inherit from this so the member functions and variables
+ // can be referenced directly inside of the test functions.
+ size_t mMemTotal;
+ };
+
+ typedef test_group<RefCountedTestData> RefCountedTestGroupType;
+ typedef RefCountedTestGroupType::object RefCountedTestObjectType;
+ RefCountedTestGroupType RefCountedTestGroup("RefCounted Tests");
+
+ template <> template <>
+ void RefCountedTestObjectType::test<1>()
+ {
+ set_test_name("RefCounted construction with implicit count");
+
+ // record the total amount of dynamically allocated memory
+ mMemTotal = GetMemTotal();
+
+ // create a new ref counted object with an implicit reference
+ RefCounted * rc = new RefCounted(true);
+ ensure(rc->getRefCount() == 1);
+
+ // release the implicit reference, causing the object to be released
+ rc->release();
+
+ // make sure we didn't leak any memory
+ ensure(mMemTotal == GetMemTotal());
+ }
+
+ template <> template <>
+ void RefCountedTestObjectType::test<2>()
+ {
+ set_test_name("RefCounted construction without implicit count");
+
+ // record the total amount of dynamically allocated memory
+ mMemTotal = GetMemTotal();
+
+ // create a new ref counted object with an implicit reference
+ RefCounted * rc = new RefCounted(false);
+ ensure(rc->getRefCount() == 0);
+
+ // add a reference
+ rc->addRef();
+ ensure(rc->getRefCount() == 1);
+
+ // release the implicit reference, causing the object to be released
+ rc->release();
+
+ ensure(mMemTotal == GetMemTotal());
+ }
+
+ template <> template <>
+ void RefCountedTestObjectType::test<3>()
+ {
+ set_test_name("RefCounted addRef and release");
+
+ // record the total amount of dynamically allocated memory
+ mMemTotal = GetMemTotal();
+
+ RefCounted * rc = new RefCounted(false);
+
+ for (int i = 0; i < 1024; ++i)
+ {
+ rc->addRef();
+ }
+
+ ensure(rc->getRefCount() == 1024);
+
+ for (int i = 0; i < 1024; ++i)
+ {
+ rc->release();
+ }
+
+ // make sure we didn't leak any memory
+ ensure(mMemTotal == GetMemTotal());
+ }
+
+ template <> template <>
+ void RefCountedTestObjectType::test<4>()
+ {
+ set_test_name("RefCounted isLastRef check");
+
+ // record the total amount of dynamically allocated memory
+ mMemTotal = GetMemTotal();
+
+ RefCounted * rc = new RefCounted(true);
+
+ // with only one reference, isLastRef should be true
+ ensure(rc->isLastRef());
+
+ // release it to clean up memory
+ rc->release();
+
+ // make sure we didn't leak any memory
+ ensure(mMemTotal == GetMemTotal());
+ }
+
+ template <> template <>
+ void RefCountedTestObjectType::test<5>()
+ {
+ set_test_name("RefCounted noRef check");
+
+ // record the total amount of dynamically allocated memory
+ mMemTotal = GetMemTotal();
+
+ RefCounted * rc = new RefCounted(false);
+
+ // set the noRef
+ rc->noRef();
+
+ // with only one reference, isLastRef should be true
+ ensure(rc->getRefCount() == RefCounted::NOT_REF_COUNTED);
+
+ // allow this memory leak, but check that we're leaking a known amount
+ ensure(mMemTotal == (GetMemTotal() - sizeof(RefCounted)));
+ }
+}
+
+#endif // TEST_LLCOREINT_REF_COUNTED_H_
diff --git a/indra/llcorehttp/tests/testrunner.py b/indra/llcorehttp/tests/testrunner.py
new file mode 100755
index 0000000000..9a2de71142
--- /dev/null
+++ b/indra/llcorehttp/tests/testrunner.py
@@ -0,0 +1,265 @@
+#!/usr/bin/env python
+"""\
+@file testrunner.py
+@author Nat Goodspeed
+@date 2009-03-20
+@brief Utilities for writing wrapper scripts for ADD_COMM_BUILD_TEST unit tests
+
+$LicenseInfo:firstyear=2009&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$
+"""
+
+from __future__ import with_statement
+
+import os
+import sys
+import re
+import errno
+import socket
+
+VERBOSE = os.environ.get("INTEGRATION_TEST_VERBOSE", "0") # default to quiet
+# Support usage such as INTEGRATION_TEST_VERBOSE=off -- distressing to user if
+# that construct actually turns on verbosity...
+VERBOSE = not re.match(r"(0|off|false|quiet)$", VERBOSE, re.IGNORECASE)
+
+if VERBOSE:
+ def debug(fmt, *args):
+ print fmt % args
+ sys.stdout.flush()
+else:
+ debug = lambda *args: None
+
+def freeport(portlist, expr):
+ """
+ Find a free server port to use. Specifically, evaluate 'expr' (a
+ callable(port)) until it stops raising EADDRINUSE exception.
+
+ Pass:
+
+ portlist: an iterable (e.g. xrange()) of ports to try. If you exhaust the
+ range, freeport() lets the socket.error exception propagate. If you want
+ unbounded, you could pass itertools.count(baseport), though of course in
+ practice the ceiling is 2^16-1 anyway. But it seems prudent to constrain
+ the range much more sharply: if we're iterating an absurd number of times,
+ probably something else is wrong.
+
+ expr: a callable accepting a port number, specifically one of the items
+ from portlist. If calling that callable raises socket.error with
+ EADDRINUSE, freeport() retrieves the next item from portlist and retries.
+
+ Returns: (expr(port), port)
+
+ port: the value from portlist for which expr(port) succeeded
+
+ Raises:
+
+ Any exception raised by expr(port) other than EADDRINUSE.
+
+ socket.error if, for every item from portlist, expr(port) raises
+ socket.error. The exception you see is the one from the last item in
+ portlist.
+
+ StopIteration if portlist is completely empty.
+
+ Example:
+
+ class Server(HTTPServer):
+ # If you use BaseHTTPServer.HTTPServer, turning off this flag is
+ # essential for proper operation of freeport()!
+ allow_reuse_address = False
+ # ...
+ server, port = freeport(xrange(8000, 8010),
+ lambda port: Server(("localhost", port),
+ MyRequestHandler))
+ # pass 'port' to client code
+ # call server.serve_forever()
+ """
+ try:
+ # If portlist is completely empty, let StopIteration propagate: that's an
+ # error because we can't return meaningful values. We have no 'port',
+ # therefore no 'expr(port)'.
+ portiter = iter(portlist)
+ port = portiter.next()
+
+ while True:
+ try:
+ # If this value of port works, return as promised.
+ value = expr(port)
+
+ except socket.error, err:
+ # Anything other than 'Address already in use', propagate
+ if err.args[0] != errno.EADDRINUSE:
+ raise
+
+ # Here we want the next port from portiter. But on StopIteration,
+ # we want to raise the original exception rather than
+ # StopIteration. So save the original exc_info().
+ type, value, tb = sys.exc_info()
+ try:
+ try:
+ port = portiter.next()
+ except StopIteration:
+ raise type, value, tb
+ finally:
+ # Clean up local traceback, see docs for sys.exc_info()
+ del tb
+
+ else:
+ debug("freeport() returning %s on port %s", value, port)
+ return value, port
+
+ # Recap of the control flow above:
+ # If expr(port) doesn't raise, return as promised.
+ # If expr(port) raises anything but EADDRINUSE, propagate that
+ # exception.
+ # If portiter.next() raises StopIteration -- that is, if the port
+ # value we just passed to expr(port) was the last available -- reraise
+ # the EADDRINUSE exception.
+ # If we've actually arrived at this point, portiter.next() delivered a
+ # new port value. Loop back to pass that to expr(port).
+
+ except Exception, err:
+ debug("*** freeport() raising %s: %s", err.__class__.__name__, err)
+ raise
+
+def run(*args, **kwds):
+ """All positional arguments collectively form a command line, executed as
+ a synchronous child process.
+ In addition, pass server=new_thread_instance as an explicit keyword (to
+ differentiate it from an additional command-line argument).
+ new_thread_instance should be an instantiated but not yet started Thread
+ subclass instance, e.g.:
+ run("python", "-c", 'print "Hello, world!"', server=TestHTTPServer(name="httpd"))
+ """
+ # If there's no server= keyword arg, don't start a server thread: simply
+ # run a child process.
+ try:
+ thread = kwds.pop("server")
+ except KeyError:
+ pass
+ else:
+ # Start server thread. Note that this and all other comm server
+ # threads should be daemon threads: we'll let them run "forever,"
+ # confident that the whole process will terminate when the main thread
+ # terminates, which will be when the child process terminates.
+ thread.setDaemon(True)
+ thread.start()
+ # choice of os.spawnv():
+ # - [v vs. l] pass a list of args vs. individual arguments,
+ # - [no p] don't use the PATH because we specifically want to invoke the
+ # executable passed as our first arg,
+ # - [no e] child should inherit this process's environment.
+ debug("Running %s...", " ".join(args))
+ if kwds.get("use_path", False):
+ rc = os.spawnvp(os.P_WAIT, args[0], args)
+ else:
+ rc = os.spawnv(os.P_WAIT, args[0], args)
+ debug("%s returned %s", args[0], rc)
+ return rc
+
+# ****************************************************************************
+# test code -- manual at this point, see SWAT-564
+# ****************************************************************************
+def test_freeport():
+ # ------------------------------- Helpers --------------------------------
+ from contextlib import contextmanager
+ # helper Context Manager for expecting an exception
+ # with exc(SomeError):
+ # raise SomeError()
+ # raises AssertionError otherwise.
+ @contextmanager
+ def exc(exception_class, *args):
+ try:
+ yield
+ except exception_class, err:
+ for i, expected_arg in enumerate(args):
+ assert expected_arg == err.args[i], \
+ "Raised %s, but args[%s] is %r instead of %r" % \
+ (err.__class__.__name__, i, err.args[i], expected_arg)
+ print "Caught expected exception %s(%s)" % \
+ (err.__class__.__name__, ', '.join(repr(arg) for arg in err.args))
+ else:
+ assert False, "Failed to raise " + exception_class.__class__.__name__
+
+ # helper to raise specified exception
+ def raiser(exception):
+ raise exception
+
+ # the usual
+ def assert_equals(a, b):
+ assert a == b, "%r != %r" % (a, b)
+
+ # ------------------------ Sanity check the above ------------------------
+ class SomeError(Exception): pass
+ # Without extra args, accept any err.args value
+ with exc(SomeError):
+ raiser(SomeError("abc"))
+ # With extra args, accept only the specified value
+ with exc(SomeError, "abc"):
+ raiser(SomeError("abc"))
+ with exc(AssertionError):
+ with exc(SomeError, "abc"):
+ raiser(SomeError("def"))
+ with exc(AssertionError):
+ with exc(socket.error, errno.EADDRINUSE):
+ raiser(socket.error(errno.ECONNREFUSED, 'Connection refused'))
+
+ # ----------- freeport() without engaging socket functionality -----------
+ # If portlist is empty, freeport() raises StopIteration.
+ with exc(StopIteration):
+ freeport([], None)
+
+ assert_equals(freeport([17], str), ("17", 17))
+
+ # This is the magic exception that should prompt us to retry
+ inuse = socket.error(errno.EADDRINUSE, 'Address already in use')
+ # Get the iterator to our ports list so we can check later if we've used all
+ ports = iter(xrange(5))
+ with exc(socket.error, errno.EADDRINUSE):
+ freeport(ports, lambda port: raiser(inuse))
+ # did we entirely exhaust 'ports'?
+ with exc(StopIteration):
+ ports.next()
+
+ ports = iter(xrange(2))
+ # Any exception but EADDRINUSE should quit immediately
+ with exc(SomeError):
+ freeport(ports, lambda port: raiser(SomeError()))
+ assert_equals(ports.next(), 1)
+
+ # ----------- freeport() with platform-dependent socket stuff ------------
+ # This is what we should've had unit tests to begin with (see CHOP-661).
+ def newbind(port):
+ sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ sock.bind(('127.0.0.1', port))
+ return sock
+
+ bound0, port0 = freeport(xrange(7777, 7780), newbind)
+ assert_equals(port0, 7777)
+ bound1, port1 = freeport(xrange(7777, 7780), newbind)
+ assert_equals(port1, 7778)
+ bound2, port2 = freeport(xrange(7777, 7780), newbind)
+ assert_equals(port2, 7779)
+ with exc(socket.error, errno.EADDRINUSE):
+ bound3, port3 = freeport(xrange(7777, 7780), newbind)
+
+if __name__ == "__main__":
+ test_freeport()
diff --git a/indra/llcrashlogger/CMakeLists.txt b/indra/llcrashlogger/CMakeLists.txt
index b2639aec30..12986de8b2 100644..100755
--- a/indra/llcrashlogger/CMakeLists.txt
+++ b/indra/llcrashlogger/CMakeLists.txt
@@ -16,6 +16,10 @@ include_directories(
${LLVFS_INCLUDE_DIRS}
${LLXML_INCLUDE_DIRS}
)
+include_directories(SYSTEM
+ ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+ ${LLXML_SYSTEM_INCLUDE_DIRS}
+ )
set(llcrashlogger_SOURCE_FILES
llcrashlogger.cpp
diff --git a/indra/llcrashlogger/llcrashlogger.cpp b/indra/llcrashlogger/llcrashlogger.cpp
index d6dcde4b9f..fb2d43e3b0 100644..100755
--- a/indra/llcrashlogger/llcrashlogger.cpp
+++ b/indra/llcrashlogger/llcrashlogger.cpp
@@ -147,7 +147,7 @@ void LLCrashLogger::gatherFiles()
// Look for it in the debug_info.log file
if (debug_log_file.is_open())
- {
+ {
LLSDSerialize::fromXML(mDebugLog, debug_log_file);
mCrashInPreviousExec = mDebugLog["CrashNotHandled"].asBoolean();
@@ -366,7 +366,7 @@ bool LLCrashLogger::sendCrashLogs()
{
sent = runCrashLogPost(mAltCrashHost, post_data, std::string("Sending to alternate server"), 3, 5);
}
-
+
mSentCrashLogs = sent;
return true;
diff --git a/indra/llcrashlogger/llcrashlogger.h b/indra/llcrashlogger/llcrashlogger.h
index 1510d7e0b3..1510d7e0b3 100644..100755
--- a/indra/llcrashlogger/llcrashlogger.h
+++ b/indra/llcrashlogger/llcrashlogger.h
diff --git a/indra/llimage/CMakeLists.txt b/indra/llimage/CMakeLists.txt
index ea8c1a1107..e837b0cac2 100644..100755
--- a/indra/llimage/CMakeLists.txt
+++ b/indra/llimage/CMakeLists.txt
@@ -7,12 +7,15 @@ include(LLCommon)
include(LLImage)
include(LLMath)
include(LLVFS)
+include(LLKDU)
+include(LLImageJ2COJ)
include(ZLIB)
include(LLAddBuildTest)
include(Tut)
include_directories(
${LLCOMMON_INCLUDE_DIRS}
+ ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
${LLMATH_INCLUDE_DIRS}
${LLVFS_INCLUDE_DIRS}
${PNG_INCLUDE_DIRS}
@@ -56,8 +59,16 @@ list(APPEND llimage_SOURCE_FILES ${llimage_HEADER_FILES})
add_library (llimage ${llimage_SOURCE_FILES})
# Libraries on which this library depends, needed for Linux builds
# Sort by high-level to low-level
+if (USE_KDU)
+ target_link_libraries(llimage ${LLKDU_LIBRARIES})
+else (USE_KDU)
+ target_link_libraries(llimage ${LLIMAGEJ2COJ_LIBRARIES})
+endif (USE_KDU)
+
target_link_libraries(llimage
- llcommon
+ ${LLVFS_LIBRARIES}
+ ${LLMATH_LIBRARIES}
+ ${LLCOMMON_LIBRARIES}
${JPEG_LIBRARIES}
${PNG_LIBRARIES}
${ZLIB_LIBRARIES}
diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp
index 56e01ac851..c8a05e1fae 100644..100755
--- a/indra/llimage/llimage.cpp
+++ b/indra/llimage/llimage.cpp
@@ -30,7 +30,6 @@
#include "llmath.h"
#include "v4coloru.h"
-#include "llmemtype.h"
#include "llimagebmp.h"
#include "llimagetga.h"
@@ -48,11 +47,15 @@
//static
std::string LLImage::sLastErrorMessage;
LLMutex* LLImage::sMutex = NULL;
+bool LLImage::sUseNewByteRange = false;
+S32 LLImage::sMinimalReverseByteRangePercent = 75;
LLPrivateMemoryPool* LLImageBase::sPrivatePoolp = NULL ;
//static
-void LLImage::initClass()
+void LLImage::initClass(bool use_new_byte_range, S32 minimal_reverse_byte_range_percent)
{
+ sUseNewByteRange = use_new_byte_range;
+ sMinimalReverseByteRangePercent = minimal_reverse_byte_range_percent;
sMutex = new LLMutex(NULL);
LLImageBase::createPrivatePool() ;
@@ -92,8 +95,7 @@ LLImageBase::LLImageBase()
mHeight(0),
mComponents(0),
mBadBufferAllocation(false),
- mAllowOverSize(false),
- mMemType(LLMemType::MTYPE_IMAGEBASE)
+ mAllowOverSize(false)
{
}
@@ -163,8 +165,6 @@ void LLImageBase::deleteData()
// virtual
U8* LLImageBase::allocateData(S32 size)
{
- LLMemType mt1(mMemType);
-
if (size < 0)
{
size = mWidth * mHeight * mComponents;
@@ -209,7 +209,6 @@ U8* LLImageBase::allocateData(S32 size)
// virtual
U8* LLImageBase::reallocateData(S32 size)
{
- LLMemType mt1(mMemType);
U8 *new_datap = (U8*)ALLOCATE_MEM(sPrivatePoolp, size);
if (!new_datap)
{
@@ -275,24 +274,26 @@ S32 LLImageRaw::sRawImageCount = 0;
LLImageRaw::LLImageRaw()
: LLImageBase()
{
- mMemType = LLMemType::MTYPE_IMAGERAW;
++sRawImageCount;
}
LLImageRaw::LLImageRaw(U16 width, U16 height, S8 components)
: LLImageBase()
{
- mMemType = LLMemType::MTYPE_IMAGERAW;
//llassert( S32(width) * S32(height) * S32(components) <= MAX_IMAGE_DATA_SIZE );
allocateDataSize(width, height, components);
++sRawImageCount;
}
-LLImageRaw::LLImageRaw(U8 *data, U16 width, U16 height, S8 components)
+LLImageRaw::LLImageRaw(U8 *data, U16 width, U16 height, S8 components, bool no_copy)
: LLImageBase()
{
- mMemType = LLMemType::MTYPE_IMAGERAW;
- if(allocateDataSize(width, height, components))
+
+ if(no_copy)
+ {
+ setDataAndSize(data, width, height, components);
+ }
+ else if(allocateDataSize(width, height, components))
{
memcpy(getData(), data, width*height*components);
}
@@ -366,29 +367,6 @@ BOOL LLImageRaw::resize(U16 width, U16 height, S8 components)
return TRUE;
}
-#if 0
-U8 * LLImageRaw::getSubImage(U32 x_pos, U32 y_pos, U32 width, U32 height) const
-{
- LLMemType mt1(mMemType);
- U8 *data = new U8[width*height*getComponents()];
-
- // Should do some simple bounds checking
- if (!data)
- {
- llerrs << "Out of memory in LLImageRaw::getSubImage" << llendl;
- return NULL;
- }
-
- U32 i;
- for (i = y_pos; i < y_pos+height; i++)
- {
- memcpy(data + i*width*getComponents(), /* Flawfinder: ignore */
- getData() + ((y_pos + i)*getWidth() + x_pos)*getComponents(), getComponents()*width);
- }
- return data;
-}
-#endif
-
BOOL LLImageRaw::setSubImage(U32 x_pos, U32 y_pos, U32 width, U32 height,
const U8 *data, U32 stride, BOOL reverse_y)
{
@@ -453,7 +431,6 @@ void LLImageRaw::clear(U8 r, U8 g, U8 b, U8 a)
// Reverses the order of the rows in the image
void LLImageRaw::verticalFlip()
{
- LLMemType mt1(mMemType);
S32 row_bytes = getWidth() * getComponents();
llassert(row_bytes > 0);
std::vector<U8> line_buffer(row_bytes);
@@ -586,7 +563,6 @@ void LLImageRaw::composite( LLImageRaw* src )
// Src and dst can be any size. Src has 4 components. Dst has 3 components.
void LLImageRaw::compositeScaled4onto3(LLImageRaw* src)
{
- LLMemType mt1(mMemType);
llinfos << "compositeScaled4onto3" << llendl;
LLImageRaw* dst = this; // Just for clarity.
@@ -664,6 +640,29 @@ void LLImageRaw::compositeUnscaled4onto3( LLImageRaw* src )
}
}
+void LLImageRaw::copyUnscaledAlphaMask( LLImageRaw* src, const LLColor4U& fill)
+{
+ LLImageRaw* dst = this; // Just for clarity.
+
+ llassert( 1 == src->getComponents() );
+ llassert( 4 == dst->getComponents() );
+ llassert( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) );
+
+ S32 pixels = getWidth() * getHeight();
+ U8* src_data = src->getData();
+ U8* dst_data = dst->getData();
+ for ( S32 i = 0; i < pixels; i++ )
+ {
+ dst_data[0] = fill.mV[0];
+ dst_data[1] = fill.mV[1];
+ dst_data[2] = fill.mV[2];
+ dst_data[3] = src_data[0];
+ src_data += 1;
+ dst_data += 4;
+ }
+}
+
+
// Fill the buffer with a constant color
void LLImageRaw::fill( const LLColor4U& color )
{
@@ -690,8 +689,17 @@ void LLImageRaw::fill( const LLColor4U& color )
}
}
+LLPointer<LLImageRaw> LLImageRaw::duplicate()
+{
+ if(getNumRefs() < 2)
+ {
+ return this; //nobody else refences to this image, no need to duplicate.
+ }
-
+ //make a duplicate
+ LLPointer<LLImageRaw> dup = new LLImageRaw(getData(), getWidth(), getHeight(), getComponents());
+ return dup;
+}
// Src and dst can be any size. Src and dst can each have 3 or 4 components.
void LLImageRaw::copy(LLImageRaw* src)
@@ -828,7 +836,6 @@ void LLImageRaw::copyUnscaled3onto4( LLImageRaw* src )
// Src and dst can be any size. Src and dst have same number of components.
void LLImageRaw::copyScaled( LLImageRaw* src )
{
- LLMemType mt1(mMemType);
LLImageRaw* dst = this; // Just for clarity.
llassert_always( (1 == src->getComponents()) || (3 == src->getComponents()) || (4 == src->getComponents()) );
@@ -857,57 +864,9 @@ void LLImageRaw::copyScaled( LLImageRaw* src )
}
}
-#if 0
-//scale down image by not blending a pixel with its neighbors.
-BOOL LLImageRaw::scaleDownWithoutBlending( S32 new_width, S32 new_height)
-{
- LLMemType mt1(mMemType);
-
- S8 c = getComponents() ;
- llassert((1 == c) || (3 == c) || (4 == c) );
-
- S32 old_width = getWidth();
- S32 old_height = getHeight();
-
- S32 new_data_size = old_width * new_height * c ;
- llassert_always(new_data_size > 0);
-
- F32 ratio_x = (F32)old_width / new_width ;
- F32 ratio_y = (F32)old_height / new_height ;
- if( ratio_x < 1.0f || ratio_y < 1.0f )
- {
- return TRUE; // Nothing to do.
- }
- ratio_x -= 1.0f ;
- ratio_y -= 1.0f ;
-
- U8* new_data = allocateMemory(new_data_size) ;
- llassert_always(new_data != NULL) ;
-
- U8* old_data = getData() ;
- S32 i, j, k, s, t;
- for(i = 0, s = 0, t = 0 ; i < new_height ; i++)
- {
- for(j = 0 ; j < new_width ; j++)
- {
- for(k = 0 ; k < c ; k++)
- {
- new_data[s++] = old_data[t++] ;
- }
- t += (S32)(ratio_x * c + 0.1f) ;
- }
- t += (S32)(ratio_y * old_width * c + 0.1f) ;
- }
-
- setDataAndSize(new_data, new_width, new_height, c) ;
-
- return TRUE ;
-}
-#endif
BOOL LLImageRaw::scale( S32 new_width, S32 new_height, BOOL scale_image_data )
{
- LLMemType mt1(mMemType);
llassert((1 == getComponents()) || (3 == getComponents()) || (4 == getComponents()) );
S32 old_width = getWidth();
@@ -1334,9 +1293,9 @@ LLImageFormatted::LLImageFormatted(S8 codec)
mCodec(codec),
mDecoding(0),
mDecoded(0),
- mDiscardLevel(-1)
+ mDiscardLevel(-1),
+ mLevels(0)
{
- mMemType = LLMemType::MTYPE_IMAGEFORMATTED;
}
// virtual
@@ -1561,7 +1520,7 @@ void LLImageFormatted::appendData(U8 *data, S32 size)
//----------------------------------------------------------------------------
-BOOL LLImageFormatted::load(const std::string &filename)
+BOOL LLImageFormatted::load(const std::string &filename, int load_size)
{
resetLastError();
@@ -1580,14 +1539,19 @@ BOOL LLImageFormatted::load(const std::string &filename)
return FALSE;
}
+ // Constrain the load size to acceptable values
+ if ((load_size == 0) || (load_size > file_size))
+ {
+ load_size = file_size;
+ }
BOOL res;
- U8 *data = allocateData(file_size);
- apr_size_t bytes_read = file_size;
+ U8 *data = allocateData(load_size);
+ apr_size_t bytes_read = load_size;
apr_status_t s = apr_file_read(apr_file, data, &bytes_read); // modifies bytes_read
- if (s != APR_SUCCESS || (S32) bytes_read != file_size)
+ if (s != APR_SUCCESS || (S32) bytes_read != load_size)
{
deleteData();
- setLastError("Unable to read entire file",filename);
+ setLastError("Unable to read file",filename);
res = FALSE;
}
else
@@ -1650,6 +1614,12 @@ static void avg4_colors2(const U8* a, const U8* b, const U8* c, const U8* d, U8*
dst[1] = (U8)(((U32)(a[1]) + b[1] + c[1] + d[1])>>2);
}
+void LLImageBase::setDataAndSize(U8 *data, S32 size)
+{
+ ll_assert_aligned(data, 16);
+ mData = data; mDataSize = size;
+}
+
//static
void LLImageBase::generateMip(const U8* indata, U8* mipdata, S32 width, S32 height, S32 nchannels)
{
diff --git a/indra/llimage/llimage.h b/indra/llimage/llimage.h
index 4469c9e860..2277afc585 100644..100755
--- a/indra/llimage/llimage.h
+++ b/indra/llimage/llimage.h
@@ -30,7 +30,7 @@
#include "lluuid.h"
#include "llstring.h"
#include "llthread.h"
-#include "llmemtype.h"
+#include "llpointer.h"
const S32 MIN_IMAGE_MIP = 2; // 4x4, only used for expand/contract power of 2
const S32 MAX_IMAGE_MIP = 11; // 2048x2048
@@ -48,6 +48,8 @@ const S32 MAX_PRECINCT_SIZE = 2048; // No reason to be bigger than MAX_IMAGE_S
const S32 MIN_PRECINCT_SIZE = 4; // Can't be smaller than MIN_BLOCK_SIZE
const S32 MAX_BLOCK_SIZE = 64; // Max total block size is 4096, hence 64x64 when using square blocks
const S32 MIN_BLOCK_SIZE = 4; // Min block dim is 4 according to jpeg2000 spec
+const S32 MIN_LAYER_SIZE = 2000; // Size of the first quality layer (after header). Must be > to FIRST_PACKET_SIZE!!
+const S32 MAX_NB_LAYERS = 64; // Max number of layers we'll entertain in SL (practical limit)
const S32 MIN_IMAGE_SIZE = (1<<MIN_IMAGE_MIP); // 4, only used for expand/contract power of 2
const S32 MAX_IMAGE_SIZE = (1<<MAX_IMAGE_MIP); // 2048
@@ -60,6 +62,7 @@ const S32 MAX_IMAGE_DATA_SIZE = MAX_IMAGE_AREA * MAX_IMAGE_COMPONENTS; //2048 *
// *TODO: change both to 1024 when SIM texture fetching is deprecated
const S32 FIRST_PACKET_SIZE = 600;
const S32 MAX_IMG_PACKET_SIZE = 1000;
+const S32 HTTP_PACKET_SIZE = 1496;
// Base classes for images.
// There are two major parts for the image:
@@ -89,15 +92,20 @@ typedef enum e_image_codec
class LLImage
{
public:
- static void initClass();
+ static void initClass(bool use_new_byte_range = false, S32 minimal_reverse_byte_range_percent = 75);
static void cleanupClass();
static const std::string& getLastError();
static void setLastError(const std::string& message);
+ static bool useNewByteRange() { return sUseNewByteRange; }
+ static S32 getReverseByteRangePercent() { return sMinimalReverseByteRangePercent; }
+
protected:
static LLMutex* sMutex;
static std::string sLastErrorMessage;
+ static bool sUseNewByteRange;
+ static S32 sMinimalReverseByteRangePercent;
};
//============================================================================
@@ -140,7 +148,7 @@ public:
protected:
// special accessor to allow direct setting of mData and mDataSize by LLImageFormatted
- void setDataAndSize(U8 *data, S32 size) { mData = data; mDataSize = size; }
+ void setDataAndSize(U8 *data, S32 size);
public:
static void generateMip(const U8 *indata, U8* mipdata, int width, int height, S32 nchannels);
@@ -168,8 +176,6 @@ private:
bool mAllowOverSize ;
static LLPrivateMemoryPool* sPrivatePoolp ;
-public:
- LLMemType::DeclareMemType& mMemType; // debug
};
// Raw representation of an image (used for textures, and other uncompressed formats
@@ -181,7 +187,7 @@ protected:
public:
LLImageRaw();
LLImageRaw(U16 width, U16 height, S8 components);
- LLImageRaw(U8 *data, U16 width, U16 height, S8 components);
+ LLImageRaw(U8 *data, U16 width, U16 height, S8 components, bool no_copy = false);
// Construct using createFromFile (used by tools)
//LLImageRaw(const std::string& filename, bool j2c_lowest_mip_only = false);
@@ -203,13 +209,15 @@ public:
void contractToPowerOfTwo(S32 max_dim = MAX_IMAGE_SIZE, BOOL scale_image = TRUE);
void biasedScaleToPowerOfTwo(S32 max_dim = MAX_IMAGE_SIZE);
BOOL scale( S32 new_width, S32 new_height, BOOL scale_image = TRUE );
- //BOOL scaleDownWithoutBlending( S32 new_width, S32 new_height) ;
-
+
// Fill the buffer with a constant color
void fill( const LLColor4U& color );
// Copy operations
+ //duplicate this raw image if refCount > 1.
+ LLPointer<LLImageRaw> duplicate();
+
// Src and dst can be any size. Src and dst can each have 3 or 4 components.
void copy( LLImageRaw* src );
@@ -222,6 +230,11 @@ public:
// Src and dst are same size. Src has 3 components. Dst has 4 components.
void copyUnscaled3onto4( LLImageRaw* src );
+ // Src and dst are same size. Src has 1 component. Dst has 4 components.
+ // Alpha component is set to source alpha mask component.
+ // RGB components are set to fill color.
+ void copyUnscaledAlphaMask( LLImageRaw* src, const LLColor4U& fill);
+
// Src and dst can be any size. Src and dst have same number of components.
void copyScaled( LLImageRaw* src );
@@ -294,7 +307,7 @@ public:
// getRawDiscardLevel() by default returns mDiscardLevel, but may be overridden (LLImageJ2C)
virtual S8 getRawDiscardLevel() { return mDiscardLevel; }
- BOOL load(const std::string& filename);
+ BOOL load(const std::string& filename, int load_size = 0);
BOOL save(const std::string& filename);
virtual BOOL updateData() = 0; // pure virtual
@@ -313,6 +326,8 @@ public:
BOOL isDecoded() const { return mDecoded ? TRUE : FALSE; }
void setDiscardLevel(S8 discard_level) { mDiscardLevel = discard_level; }
S8 getDiscardLevel() const { return mDiscardLevel; }
+ S8 getLevels() const { return mLevels; }
+ void setLevels(S8 nlevels) { mLevels = nlevels; }
// setLastError needs to be deferred for J2C images since it may be called from a DLL
virtual void resetLastError();
@@ -325,7 +340,8 @@ protected:
S8 mCodec;
S8 mDecoding;
S8 mDecoded; // unused, but changing LLImage layout requires recompiling static Mac/Linux libs. 2009-01-30 JC
- S8 mDiscardLevel;
+ S8 mDiscardLevel; // Current resolution level worked on. 0 = full res, 1 = half res, 2 = quarter res, etc...
+ S8 mLevels; // Number of resolution levels in that image. Min is 1. 0 means unknown.
public:
static S32 sGlobalFormattedMemory;
diff --git a/indra/llimage/llimagebmp.cpp b/indra/llimage/llimagebmp.cpp
index 60b1c628d7..60b1c628d7 100644..100755
--- a/indra/llimage/llimagebmp.cpp
+++ b/indra/llimage/llimagebmp.cpp
diff --git a/indra/llimage/llimagebmp.h b/indra/llimage/llimagebmp.h
index db0b45def0..db0b45def0 100644..100755
--- a/indra/llimage/llimagebmp.h
+++ b/indra/llimage/llimagebmp.h
diff --git a/indra/llimage/llimagedimensionsinfo.cpp b/indra/llimage/llimagedimensionsinfo.cpp
index c6bfa50b40..c6bfa50b40 100644..100755
--- a/indra/llimage/llimagedimensionsinfo.cpp
+++ b/indra/llimage/llimagedimensionsinfo.cpp
diff --git a/indra/llimage/llimagedimensionsinfo.h b/indra/llimage/llimagedimensionsinfo.h
index 382fdb2a0e..382fdb2a0e 100644..100755
--- a/indra/llimage/llimagedimensionsinfo.h
+++ b/indra/llimage/llimagedimensionsinfo.h
diff --git a/indra/llimage/llimagedxt.cpp b/indra/llimage/llimagedxt.cpp
index 34c6793522..34c6793522 100644..100755
--- a/indra/llimage/llimagedxt.cpp
+++ b/indra/llimage/llimagedxt.cpp
diff --git a/indra/llimage/llimagedxt.h b/indra/llimage/llimagedxt.h
index a8756ba8ed..a8756ba8ed 100644..100755
--- a/indra/llimage/llimagedxt.h
+++ b/indra/llimage/llimagedxt.h
diff --git a/indra/llimage/llimagej2c.cpp b/indra/llimage/llimagej2c.cpp
index 8241746a74..5412f98ee5 100644..100755
--- a/indra/llimage/llimagej2c.cpp
+++ b/indra/llimage/llimagej2c.cpp
@@ -26,7 +26,6 @@
#include "lldir.h"
#include "llimagej2c.h"
-#include "llmemtype.h"
#include "lltimer.h"
#include "llmath.h"
#include "llmemory.h"
@@ -56,7 +55,7 @@ std::string LLImageJ2C::getEngineInfo()
LLImageJ2C::LLImageJ2C() : LLImageFormatted(IMG_CODEC_J2C),
mMaxBytes(0),
mRawDiscardLevel(-1),
- mRate(0.0f),
+ mRate(DEFAULT_COMPRESSION_RATE),
mReversible(FALSE),
mAreaUsedForDataSizeCalcs(0)
{
@@ -142,6 +141,7 @@ BOOL LLImageJ2C::updateData()
BOOL LLImageJ2C::initDecode(LLImageRaw &raw_image, int discard_level, int* region)
{
+ setDiscardLevel(discard_level != -1 ? discard_level : 0);
return mImpl->initDecode(*this,raw_image,discard_level,region);
}
@@ -160,7 +160,6 @@ BOOL LLImageJ2C::decode(LLImageRaw *raw_imagep, F32 decode_time)
BOOL LLImageJ2C::decodeChannels(LLImageRaw *raw_imagep, F32 decode_time, S32 first_channel, S32 max_channel_count )
{
LLTimer elapsed;
- LLMemType mt1(mMemType);
BOOL res = TRUE;
@@ -226,7 +225,6 @@ BOOL LLImageJ2C::encode(const LLImageRaw *raw_imagep, F32 encode_time)
BOOL LLImageJ2C::encode(const LLImageRaw *raw_imagep, const char* comment_text, F32 encode_time)
{
LLTimer elapsed;
- LLMemType mt1(mMemType);
resetLastError();
BOOL res = mImpl->encodeImpl(*this, *raw_imagep, comment_text, encode_time, mReversible);
if (!mLastError.empty())
@@ -261,19 +259,34 @@ S32 LLImageJ2C::calcHeaderSizeJ2C()
//static
S32 LLImageJ2C::calcDataSizeJ2C(S32 w, S32 h, S32 comp, S32 discard_level, F32 rate)
{
- // Note: this only provides an *estimate* of the size in bytes of an image level
- // *TODO: find a way to read the true size (when available) and convey the fact
- // that the result is an estimate in the other cases
- if (rate <= 0.f) rate = .125f;
- while (discard_level > 0)
+ // Note: This provides an estimation for the first to last quality layer of a given discard level
+ // This is however an efficient approximation, as the true discard level boundary would be
+ // in general too big for fast fetching.
+ // For details about the equation used here, see https://wiki.lindenlab.com/wiki/THX1138_KDU_Improvements#Byte_Range_Study
+
+ // Estimate the number of layers. This is consistent with what's done for j2c encoding in LLImageJ2CKDU::encodeImpl().
+ S32 nb_layers = 1;
+ S32 surface = w*h;
+ S32 s = 64*64;
+ while (surface > s)
{
- if (w < 1 || h < 1)
- break;
- w >>= 1;
- h >>= 1;
- discard_level--;
+ nb_layers++;
+ s *= 4;
}
- S32 bytes = (S32)((F32)(w*h*comp)*rate);
+ F32 layer_factor = 3.0f * (7 - llclamp(nb_layers,1,6));
+
+ // Compute w/pow(2,discard_level) and h/pow(2,discard_level)
+ w >>= discard_level;
+ h >>= discard_level;
+ w = llmax(w, 1);
+ h = llmax(h, 1);
+
+ // Temporary: compute both new and old range and pick one according to the settings TextureNewByteRange
+ // *TODO: Take the old code out once we have enough tests done
+ S32 bytes;
+ S32 new_bytes = (S32) (sqrt((F32)(w*h))*(F32)(comp)*rate*1000.f/layer_factor);
+ S32 old_bytes = (S32)((F32)(w*h*comp)*rate);
+ bytes = (LLImage::useNewByteRange() && (new_bytes < old_bytes) ? new_bytes : old_bytes);
bytes = llmax(bytes, calcHeaderSizeJ2C());
return bytes;
}
@@ -283,15 +296,12 @@ S32 LLImageJ2C::calcHeaderSize()
return calcHeaderSizeJ2C();
}
-
-// calcDataSize() returns how many bytes to read
-// to load discard_level (including header and higher discard levels)
+// calcDataSize() returns how many bytes to read to load discard_level (including header)
S32 LLImageJ2C::calcDataSize(S32 discard_level)
{
discard_level = llclamp(discard_level, 0, MAX_DISCARD_LEVEL);
-
if ( mAreaUsedForDataSizeCalcs != (getHeight() * getWidth())
- || mDataSizes[0] == 0)
+ || (mDataSizes[0] == 0))
{
mAreaUsedForDataSizeCalcs = getHeight() * getWidth();
@@ -301,25 +311,6 @@ S32 LLImageJ2C::calcDataSize(S32 discard_level)
mDataSizes[level] = calcDataSizeJ2C(getWidth(), getHeight(), getComponents(), level, mRate);
level--;
}
-
- /* This is technically a more correct way to calculate the size required
- for each discard level, since they should include the size needed for
- lower levels. Unfortunately, this doesn't work well and will lead to
- download stalls. The true correct way is to parse the header. This will
- all go away with http textures at some point.
-
- // Calculate the size for each discard level. Lower levels (higher quality)
- // contain the cumulative size of higher levels
- S32 total_size = calcHeaderSizeJ2C();
-
- S32 level = MAX_DISCARD_LEVEL; // Start at the highest discard
- while ( level >= 0 )
- { // Add in this discard level and all before it
- total_size += calcDataSizeJ2C(getWidth(), getHeight(), getComponents(), level, mRate);
- mDataSizes[level] = total_size;
- level--;
- }
- */
}
return mDataSizes[discard_level];
}
@@ -334,8 +325,9 @@ S32 LLImageJ2C::calcDiscardLevelBytes(S32 bytes)
}
while (1)
{
- S32 bytes_needed = calcDataSize(discard_level); // virtual
- if (bytes >= bytes_needed - (bytes_needed>>2)) // For J2c, up the res at 75% of the optimal number of bytes
+ S32 bytes_needed = calcDataSize(discard_level);
+ // Use TextureReverseByteRange percent (see settings.xml) of the optimal size to qualify as correct rendering for the given discard level
+ if (bytes >= (bytes_needed*LLImage::getReverseByteRangePercent()/100))
{
break;
}
@@ -348,11 +340,6 @@ S32 LLImageJ2C::calcDiscardLevelBytes(S32 bytes)
return discard_level;
}
-void LLImageJ2C::setRate(F32 rate)
-{
- mRate = rate;
-}
-
void LLImageJ2C::setMaxBytes(S32 max_bytes)
{
mMaxBytes = max_bytes;
@@ -414,7 +401,6 @@ BOOL LLImageJ2C::loadAndValidate(const std::string &filename)
BOOL LLImageJ2C::validate(U8 *data, U32 file_size)
{
- LLMemType mt1(mMemType);
resetLastError();
@@ -474,6 +460,7 @@ LLImageCompressionTester::LLImageCompressionTester() : LLMetricPerformanceTester
addMetric("Perf Compression (kB/s)");
mRunBytesInDecompression = 0;
+ mRunBytesOutDecompression = 0;
mRunBytesInCompression = 0;
mTotalBytesInDecompression = 0;
@@ -483,6 +470,7 @@ LLImageCompressionTester::LLImageCompressionTester() : LLMetricPerformanceTester
mTotalTimeDecompression = 0.0f;
mTotalTimeCompression = 0.0f;
+ mRunTimeDecompression = 0.0f;
}
LLImageCompressionTester::~LLImageCompressionTester()
@@ -565,12 +553,17 @@ void LLImageCompressionTester::updateDecompressionStats(const S32 bytesIn, const
mTotalBytesInDecompression += bytesIn;
mRunBytesInDecompression += bytesIn;
mTotalBytesOutDecompression += bytesOut;
- if (mRunBytesInDecompression > (1000000))
+ mRunBytesOutDecompression += bytesOut;
+ //if (mRunBytesInDecompression > (1000000))
+ if (mRunBytesOutDecompression > (10000000))
+ //if ((mTotalTimeDecompression - mRunTimeDecompression) >= (5.0f))
{
// Output everything
outputTestResults();
// Reset the decompression data of the run
mRunBytesInDecompression = 0;
+ mRunBytesOutDecompression = 0;
+ mRunTimeDecompression = mTotalTimeDecompression;
}
}
diff --git a/indra/llimage/llimagej2c.h b/indra/llimage/llimagej2c.h
index 914174fc57..ce8195940d 100644..100755
--- a/indra/llimage/llimagej2c.h
+++ b/indra/llimage/llimagej2c.h
@@ -31,6 +31,9 @@
#include "llassettype.h"
#include "llmetricperformancetester.h"
+// JPEG2000 : compression rate used in j2c conversion.
+const F32 DEFAULT_COMPRESSION_RATE = 1.f/8.f;
+
class LLImageJ2CImpl;
class LLImageCompressionTester ;
@@ -67,12 +70,11 @@ public:
// Encode accessors
void setReversible(const BOOL reversible); // Use non-lossy?
- void setRate(F32 rate);
void setMaxBytes(S32 max_bytes);
S32 getMaxBytes() const { return mMaxBytes; }
static S32 calcHeaderSizeJ2C();
- static S32 calcDataSizeJ2C(S32 w, S32 h, S32 comp, S32 discard_level, F32 rate = 0.f);
+ static S32 calcDataSizeJ2C(S32 w, S32 h, S32 comp, S32 discard_level, F32 rate = DEFAULT_COMPRESSION_RATE);
static std::string getEngineInfo();
@@ -154,13 +156,15 @@ class LLImageCompressionTester : public LLMetricPerformanceTesterBasic
U32 mTotalBytesOutDecompression; // Total bytes produced by decompressor
U32 mTotalBytesInCompression; // Total bytes fed to compressor
U32 mTotalBytesOutCompression; // Total bytes produced by compressor
- U32 mRunBytesInDecompression; // Bytes fed to decompressor in this run
+ U32 mRunBytesInDecompression; // Bytes fed to decompressor in this run
+ U32 mRunBytesOutDecompression; // Bytes produced by the decompressor in this run
U32 mRunBytesInCompression; // Bytes fed to compressor in this run
//
// Time
//
F32 mTotalTimeDecompression; // Total time spent in computing decompression
F32 mTotalTimeCompression; // Total time spent in computing compression
+ F32 mRunTimeDecompression; // Time in this run (we output every 5 sec in decompress)
};
#endif
diff --git a/indra/llimage/llimagejpeg.cpp b/indra/llimage/llimagejpeg.cpp
index b70f84efc8..b70f84efc8 100644..100755
--- a/indra/llimage/llimagejpeg.cpp
+++ b/indra/llimage/llimagejpeg.cpp
diff --git a/indra/llimage/llimagejpeg.h b/indra/llimage/llimagejpeg.h
index 7ac7f5d2e0..7ac7f5d2e0 100644..100755
--- a/indra/llimage/llimagejpeg.h
+++ b/indra/llimage/llimagejpeg.h
diff --git a/indra/llimage/llimagepng.cpp b/indra/llimage/llimagepng.cpp
index 294f68b122..294f68b122 100644..100755
--- a/indra/llimage/llimagepng.cpp
+++ b/indra/llimage/llimagepng.cpp
diff --git a/indra/llimage/llimagepng.h b/indra/llimage/llimagepng.h
index 1fbd850a2e..1fbd850a2e 100644..100755
--- a/indra/llimage/llimagepng.h
+++ b/indra/llimage/llimagepng.h
diff --git a/indra/llimage/llimagetga.cpp b/indra/llimage/llimagetga.cpp
index 58426d31fa..920ae2891f 100644..100755
--- a/indra/llimage/llimagetga.cpp
+++ b/indra/llimage/llimagetga.cpp
@@ -132,12 +132,12 @@ BOOL LLImageTGA::updateData()
** FIELD 2 : COLOR MAP TYPE (1 BYTES)
** FIELD 3 : IMAGE TYPE CODE (1 BYTES)
** = 0 NO IMAGE DATA INCLUDED
- ** = 1 UNCOMPRESSED, COLOR-MAPPED IMAGE
- ** = 2 UNCOMPRESSED, TRUE-COLOR IMAGE
- ** = 3 UNCOMPRESSED, BLACK AND WHITE IMAGE
- ** = 9 RUN-LENGTH ENCODED COLOR-MAPPED IMAGE
- ** = 10 RUN-LENGTH ENCODED TRUE-COLOR IMAGE
- ** = 11 RUN-LENGTH ENCODED BLACK AND WHITE IMAGE
+ ** = (0001) 1 UNCOMPRESSED, COLOR-MAPPED IMAGE
+ ** = (0010) 2 UNCOMPRESSED, TRUE-COLOR IMAGE
+ ** = (0011) 3 UNCOMPRESSED, BLACK AND WHITE IMAGE
+ ** = (1001) 9 RUN-LENGTH ENCODED COLOR-MAPPED IMAGE
+ ** = (1010) 10 RUN-LENGTH ENCODED TRUE-COLOR IMAGE
+ ** = (1011) 11 RUN-LENGTH ENCODED BLACK AND WHITE IMAGE
** FIELD 4 : COLOR MAP SPECIFICATION (5 BYTES)
** 4.1 : COLOR MAP ORIGIN (2 BYTES)
** 4.2 : COLOR MAP LENGTH (2 BYTES)
diff --git a/indra/llimage/llimagetga.h b/indra/llimage/llimagetga.h
index 5da3525149..5da3525149 100644..100755
--- a/indra/llimage/llimagetga.h
+++ b/indra/llimage/llimagetga.h
diff --git a/indra/llimage/llimageworker.cpp b/indra/llimage/llimageworker.cpp
index ad2eb0f69c..ad2eb0f69c 100644..100755
--- a/indra/llimage/llimageworker.cpp
+++ b/indra/llimage/llimageworker.cpp
diff --git a/indra/llimage/llimageworker.h b/indra/llimage/llimageworker.h
index 1bfb0ddfd3..1bfb0ddfd3 100644..100755
--- a/indra/llimage/llimageworker.h
+++ b/indra/llimage/llimageworker.h
diff --git a/indra/llimage/llmapimagetype.h b/indra/llimage/llmapimagetype.h
index 0a040d3db9..0a040d3db9 100644..100755
--- a/indra/llimage/llmapimagetype.h
+++ b/indra/llimage/llmapimagetype.h
diff --git a/indra/llimage/llpngwrapper.cpp b/indra/llimage/llpngwrapper.cpp
index 2cc7d3c460..2cc7d3c460 100644..100755
--- a/indra/llimage/llpngwrapper.cpp
+++ b/indra/llimage/llpngwrapper.cpp
diff --git a/indra/llimage/llpngwrapper.h b/indra/llimage/llpngwrapper.h
index 739f435996..739f435996 100644..100755
--- a/indra/llimage/llpngwrapper.h
+++ b/indra/llimage/llpngwrapper.h
diff --git a/indra/llimage/tests/llimageworker_test.cpp b/indra/llimage/tests/llimageworker_test.cpp
index 08476fb72c..e255d65b43 100644..100755
--- a/indra/llimage/tests/llimageworker_test.cpp
+++ b/indra/llimage/tests/llimageworker_test.cpp
@@ -49,8 +49,7 @@ mWidth(0),
mHeight(0),
mComponents(0),
mBadBufferAllocation(false),
-mAllowOverSize(false),
-mMemType(LLMemType::MTYPE_IMAGEBASE)
+mAllowOverSize(false)
{
}
LLImageBase::~LLImageBase() {}
diff --git a/indra/llimagej2coj/CMakeLists.txt b/indra/llimagej2coj/CMakeLists.txt
index 97d22cf86a..97d22cf86a 100644..100755
--- a/indra/llimagej2coj/CMakeLists.txt
+++ b/indra/llimagej2coj/CMakeLists.txt
diff --git a/indra/llimagej2coj/llimagej2coj.cpp b/indra/llimagej2coj/llimagej2coj.cpp
index d15824ce5a..d15824ce5a 100644..100755
--- a/indra/llimagej2coj/llimagej2coj.cpp
+++ b/indra/llimagej2coj/llimagej2coj.cpp
diff --git a/indra/llimagej2coj/llimagej2coj.h b/indra/llimagej2coj/llimagej2coj.h
index 40ad4edb00..40ad4edb00 100644..100755
--- a/indra/llimagej2coj/llimagej2coj.h
+++ b/indra/llimagej2coj/llimagej2coj.h
diff --git a/indra/llinventory/CMakeLists.txt b/indra/llinventory/CMakeLists.txt
index e45c809e7e..e45c809e7e 100644..100755
--- a/indra/llinventory/CMakeLists.txt
+++ b/indra/llinventory/CMakeLists.txt
diff --git a/indra/llinventory/llcategory.cpp b/indra/llinventory/llcategory.cpp
index 97a496845b..97a496845b 100644..100755
--- a/indra/llinventory/llcategory.cpp
+++ b/indra/llinventory/llcategory.cpp
diff --git a/indra/llinventory/llcategory.h b/indra/llinventory/llcategory.h
index 19ce8fa89b..19ce8fa89b 100644..100755
--- a/indra/llinventory/llcategory.h
+++ b/indra/llinventory/llcategory.h
diff --git a/indra/llinventory/lleconomy.cpp b/indra/llinventory/lleconomy.cpp
index d643ea6ed9..d643ea6ed9 100644..100755
--- a/indra/llinventory/lleconomy.cpp
+++ b/indra/llinventory/lleconomy.cpp
diff --git a/indra/llinventory/lleconomy.h b/indra/llinventory/lleconomy.h
index eb2ecf71ba..eb2ecf71ba 100644..100755
--- a/indra/llinventory/lleconomy.h
+++ b/indra/llinventory/lleconomy.h
diff --git a/indra/llinventory/llinventory.cpp b/indra/llinventory/llinventory.cpp
index fbf23bc3f0..41d58c6deb 100644..100755
--- a/indra/llinventory/llinventory.cpp
+++ b/indra/llinventory/llinventory.cpp
@@ -75,13 +75,15 @@ LLInventoryObject::LLInventoryObject(const LLUUID& uuid,
mUUID(uuid),
mParentUUID(parent_uuid),
mType(type),
- mName(name)
+ mName(name),
+ mCreationDate(0)
{
correctInventoryName(mName);
}
LLInventoryObject::LLInventoryObject() :
- mType(LLAssetType::AT_NONE)
+ mType(LLAssetType::AT_NONE),
+ mCreationDate(0)
{
}
@@ -275,6 +277,26 @@ void LLInventoryObject::correctInventoryName(std::string& name)
LLStringUtil::truncate(name, DB_INV_ITEM_NAME_STR_LEN);
}
+time_t LLInventoryObject::getCreationDate() const
+{
+ return mCreationDate;
+}
+
+void LLInventoryObject::setCreationDate(time_t creation_date_utc)
+{
+ mCreationDate = creation_date_utc;
+}
+
+
+const std::string& LLInventoryItem::getDescription() const
+{
+ return mDescription;
+}
+
+const std::string& LLInventoryItem::getActualDescription() const
+{
+ return mDescription;
+}
///----------------------------------------------------------------------------
/// Class LLInventoryItem
@@ -297,9 +319,10 @@ LLInventoryItem::LLInventoryItem(const LLUUID& uuid,
mDescription(desc),
mSaleInfo(sale_info),
mInventoryType(inv_type),
- mFlags(flags),
- mCreationDate(creation_date_utc)
+ mFlags(flags)
{
+ mCreationDate = creation_date_utc;
+
LLStringUtil::replaceNonstandardASCII(mDescription, ' ');
LLStringUtil::replaceChar(mDescription, '|', ' ');
mPermissions.initMasks(inv_type);
@@ -312,9 +335,9 @@ LLInventoryItem::LLInventoryItem() :
mDescription(),
mSaleInfo(),
mInventoryType(LLInventoryType::IT_NONE),
- mFlags(0),
- mCreationDate(0)
+ mFlags(0)
{
+ mCreationDate = 0;
}
LLInventoryItem::LLInventoryItem(const LLInventoryItem* other) :
@@ -374,16 +397,6 @@ void LLInventoryItem::setAssetUUID(const LLUUID& asset_id)
}
-const std::string& LLInventoryItem::getDescription() const
-{
- return mDescription;
-}
-
-time_t LLInventoryItem::getCreationDate() const
-{
- return mCreationDate;
-}
-
U32 LLInventoryItem::getCRC32() const
{
// *FIX: Not a real crc - more of a checksum.
@@ -440,11 +453,6 @@ void LLInventoryItem::setFlags(U32 flags)
mFlags = flags;
}
-void LLInventoryItem::setCreationDate(time_t creation_date_utc)
-{
- mCreationDate = creation_date_utc;
-}
-
// Currently only used in the Viewer to handle calling cards
// where the creator is actually used to store the target.
void LLInventoryItem::setCreator(const LLUUID& creator)
@@ -506,6 +514,12 @@ U32 LLInventoryItem::getFlags() const
return mFlags;
}
+time_t LLInventoryItem::getCreationDate() const
+{
+ return mCreationDate;
+}
+
+
// virtual
void LLInventoryItem::packMessage(LLMessageSystem* msg) const
{
diff --git a/indra/llinventory/llinventory.h b/indra/llinventory/llinventory.h
index a5cfe59bda..99716ed7be 100644..100755
--- a/indra/llinventory/llinventory.h
+++ b/indra/llinventory/llinventory.h
@@ -30,7 +30,6 @@
#include "lldarray.h"
#include "llfoldertype.h"
#include "llinventorytype.h"
-#include "llmemtype.h"
#include "llpermissions.h"
#include "llrefcount.h"
#include "llsaleinfo.h"
@@ -54,7 +53,6 @@ public:
// Initialization
//--------------------------------------------------------------------
public:
- MEM_TYPE_NEW(LLMemType::MTYPE_INVENTORY);
LLInventoryObject();
LLInventoryObject(const LLUUID& uuid,
const LLUUID& parent_uuid,
@@ -75,6 +73,7 @@ public:
virtual LLAssetType::EType getType() const;
LLAssetType::EType getActualType() const; // bypasses indirection for linked items
BOOL getIsLinkType() const;
+ virtual time_t getCreationDate() const;
//--------------------------------------------------------------------
// Mutators
@@ -85,6 +84,7 @@ public:
virtual void rename(const std::string& new_name);
void setParent(const LLUUID& new_parent);
void setType(LLAssetType::EType type);
+ virtual void setCreationDate(time_t creation_date_utc); // only stored for items
private:
// in place correction for inventory name string
@@ -113,6 +113,7 @@ protected:
LLUUID mParentUUID; // Parent category. Root categories have LLUUID::NULL.
LLAssetType::EType mType;
std::string mName;
+ time_t mCreationDate; // seconds from 1/1/1970, UTC
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -129,7 +130,6 @@ public:
// Initialization
//--------------------------------------------------------------------
public:
- MEM_TYPE_NEW(LLMemType::MTYPE_INVENTORY);
LLInventoryItem(const LLUUID& uuid,
const LLUUID& parent_uuid,
const LLPermissions& permissions,
@@ -160,6 +160,7 @@ public:
virtual const LLUUID& getCreatorUUID() const;
virtual const LLUUID& getAssetUUID() const;
virtual const std::string& getDescription() const;
+ virtual const std::string& getActualDescription() const; // Does not follow links
virtual const LLSaleInfo& getSaleInfo() const;
virtual LLInventoryType::EType getInventoryType() const;
virtual U32 getFlags() const;
@@ -178,7 +179,6 @@ public:
void setPermissions(const LLPermissions& perm);
void setInventoryType(LLInventoryType::EType inv_type);
void setFlags(U32 flags);
- void setCreationDate(time_t creation_date_utc);
void setCreator(const LLUUID& creator); // only used for calling cards
// Check for changes in permissions masks and sale info
@@ -224,7 +224,6 @@ protected:
LLSaleInfo mSaleInfo;
LLInventoryType::EType mInventoryType;
U32 mFlags;
- time_t mCreationDate; // seconds from 1/1/1970, UTC
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -242,7 +241,6 @@ public:
// Initialization
//--------------------------------------------------------------------
public:
- MEM_TYPE_NEW(LLMemType::MTYPE_INVENTORY);
LLInventoryCategory(const LLUUID& uuid, const LLUUID& parent_uuid,
LLFolderType::EType preferred_type,
const std::string& name);
diff --git a/indra/llinventory/llinventorydefines.cpp b/indra/llinventory/llinventorydefines.cpp
index 575331a263..575331a263 100644..100755
--- a/indra/llinventory/llinventorydefines.cpp
+++ b/indra/llinventory/llinventorydefines.cpp
diff --git a/indra/llinventory/llinventorydefines.h b/indra/llinventory/llinventorydefines.h
index 3881fb1fd7..3881fb1fd7 100644..100755
--- a/indra/llinventory/llinventorydefines.h
+++ b/indra/llinventory/llinventorydefines.h
diff --git a/indra/llinventory/llinventorytype.cpp b/indra/llinventory/llinventorytype.cpp
index 8282d79b67..8807b36117 100644..100755
--- a/indra/llinventory/llinventorytype.cpp
+++ b/indra/llinventory/llinventorytype.cpp
@@ -85,6 +85,7 @@ LLInventoryDictionary::LLInventoryDictionary()
addEntry(LLInventoryType::IT_GESTURE, new InventoryEntry("gesture", "gesture", 1, LLAssetType::AT_GESTURE));
addEntry(LLInventoryType::IT_MESH, new InventoryEntry("mesh", "mesh", 1, LLAssetType::AT_MESH));
addEntry(LLInventoryType::IT_WIDGET, new InventoryEntry("widget", "widget", 1, LLAssetType::AT_WIDGET));
+ addEntry(LLInventoryType::IT_PERSON, new InventoryEntry("person", "person", 1, LLAssetType::AT_PERSON));
}
@@ -140,7 +141,7 @@ DEFAULT_ASSET_FOR_INV_TYPE[LLAssetType::AT_COUNT] =
LLInventoryType::IT_NONE, // 42 AT_NONE
LLInventoryType::IT_NONE, // 43 AT_NONE
LLInventoryType::IT_NONE, // 44 AT_NONE
- LLInventoryType::IT_NONE, // 45 AT_NONE
+ LLInventoryType::IT_PERSON, // 45 AT_PERSON
LLInventoryType::IT_NONE, // 46 AT_NONE
LLInventoryType::IT_NONE, // 47 AT_NONE
LLInventoryType::IT_NONE, // 48 AT_NONE
diff --git a/indra/llinventory/llinventorytype.h b/indra/llinventory/llinventorytype.h
index 4d1e0db040..fc3c78cf50 100644..100755
--- a/indra/llinventory/llinventorytype.h
+++ b/indra/llinventory/llinventorytype.h
@@ -63,11 +63,59 @@ public:
IT_GESTURE = 20,
IT_MESH = 22,
IT_WIDGET = 23,
- IT_COUNT = 24,
+ IT_PERSON = 24,
+ IT_COUNT = 25,
IT_NONE = -1
};
+ enum EIconName
+ {
+ ICONNAME_TEXTURE,
+ ICONNAME_SOUND,
+ ICONNAME_CALLINGCARD_ONLINE,
+ ICONNAME_CALLINGCARD_OFFLINE,
+ ICONNAME_LANDMARK,
+ ICONNAME_LANDMARK_VISITED,
+ ICONNAME_SCRIPT,
+ ICONNAME_CLOTHING,
+ ICONNAME_OBJECT,
+ ICONNAME_OBJECT_MULTI,
+ ICONNAME_NOTECARD,
+ ICONNAME_BODYPART,
+ ICONNAME_SNAPSHOT,
+
+ ICONNAME_BODYPART_SHAPE,
+ ICONNAME_BODYPART_SKIN,
+ ICONNAME_BODYPART_HAIR,
+ ICONNAME_BODYPART_EYES,
+ ICONNAME_CLOTHING_SHIRT,
+ ICONNAME_CLOTHING_PANTS,
+ ICONNAME_CLOTHING_SHOES,
+ ICONNAME_CLOTHING_SOCKS,
+ ICONNAME_CLOTHING_JACKET,
+ ICONNAME_CLOTHING_GLOVES,
+ ICONNAME_CLOTHING_UNDERSHIRT,
+ ICONNAME_CLOTHING_UNDERPANTS,
+ ICONNAME_CLOTHING_SKIRT,
+ ICONNAME_CLOTHING_ALPHA,
+ ICONNAME_CLOTHING_TATTOO,
+
+ ICONNAME_ANIMATION,
+ ICONNAME_GESTURE,
+
+ ICONNAME_CLOTHING_PHYSICS,
+
+ ICONNAME_LINKITEM,
+ ICONNAME_LINKFOLDER,
+ ICONNAME_MESH,
+
+ ICONNAME_INVALID,
+ ICONNAME_COUNT,
+ ICONNAME_NONE = -1
+ };
+
+
// machine transation between type and strings
static EType lookup(const std::string& name);
static const std::string &lookup(EType type);
diff --git a/indra/llinventory/lllandmark.cpp b/indra/llinventory/lllandmark.cpp
index 493909cf9c..493909cf9c 100644..100755
--- a/indra/llinventory/lllandmark.cpp
+++ b/indra/llinventory/lllandmark.cpp
diff --git a/indra/llinventory/lllandmark.h b/indra/llinventory/lllandmark.h
index 92923ea6fb..92923ea6fb 100644..100755
--- a/indra/llinventory/lllandmark.h
+++ b/indra/llinventory/lllandmark.h
diff --git a/indra/llinventory/llnotecard.cpp b/indra/llinventory/llnotecard.cpp
index 69152cefe0..69152cefe0 100644..100755
--- a/indra/llinventory/llnotecard.cpp
+++ b/indra/llinventory/llnotecard.cpp
diff --git a/indra/llinventory/llnotecard.h b/indra/llinventory/llnotecard.h
index d64a821b78..d64a821b78 100644..100755
--- a/indra/llinventory/llnotecard.h
+++ b/indra/llinventory/llnotecard.h
diff --git a/indra/llinventory/llparcel.cpp b/indra/llinventory/llparcel.cpp
index 433076c7a9..5eb5fb442d 100644..100755
--- a/indra/llinventory/llparcel.cpp
+++ b/indra/llinventory/llparcel.cpp
@@ -193,8 +193,6 @@ void LLParcel::init(const LLUUID &owner_id,
mMediaWidth = 0;
mMediaHeight = 0;
setMediaCurrentURL(LLStringUtil::null);
- mMediaURLFilterEnable = FALSE;
- mMediaURLFilterList = LLSD::emptyArray();
mMediaAllowNavigate = TRUE;
mMediaURLTimeout = 0.0f;
mMediaPreventCameraZoom = FALSE;
@@ -207,7 +205,7 @@ void LLParcel::init(const LLUUID &owner_id,
mAABBMin.setVec(SOME_BIG_NUMBER, SOME_BIG_NUMBER, SOME_BIG_NUMBER);
mAABBMax.setVec(SOME_BIG_NEG_NUMBER, SOME_BIG_NEG_NUMBER, SOME_BIG_NEG_NUMBER);
- mLocalID = 0;
+ mLocalID = INVALID_PARCEL_ID;
//mSimWidePrimCorrection = 0;
setMaxPrimCapacity((S32)(sim_object_limit * area / (F32)(REGION_WIDTH_METERS * REGION_WIDTH_METERS)));
@@ -336,38 +334,6 @@ void LLParcel::setMediaURLResetTimer(F32 time)
mMediaResetTimer.setTimerExpirySec(time);
}
-void LLParcel::setMediaURLFilterList(LLSD list)
-{
- // sanity check LLSD
- // must be array of strings
- if (!list.isArray())
- {
- return;
- }
-
- for (S32 i = 0; i < list.size(); i++)
- {
- if (!list[i].isString())
- return;
- }
-
- // can't be too big
- const S32 MAX_SIZE = 50;
- if (list.size() > MAX_SIZE)
- {
- LLSD new_list = LLSD::emptyArray();
-
- for (S32 i = 0; i < llmin(list.size(), MAX_SIZE); i++)
- {
- new_list.append(list[i]);
- }
-
- list = new_list;
- }
-
- mMediaURLFilterList = list;
-}
-
// virtual
void LLParcel::setLocalID(S32 local_id)
{
@@ -448,117 +414,6 @@ BOOL LLParcel::allowTerraformBy(const LLUUID &agent_id) const
}
-bool LLParcel::isAgentBlockedFromParcel(LLParcel* parcelp,
- const LLUUID& agent_id,
- const uuid_vec_t& group_ids,
- const BOOL is_agent_identified,
- const BOOL is_agent_transacted,
- const BOOL is_agent_ageverified)
-{
- S32 current_group_access = parcelp->blockAccess(agent_id, LLUUID::null, is_agent_identified, is_agent_transacted, is_agent_ageverified);
- S32 count;
- bool is_allowed = (current_group_access == BA_ALLOWED) ? true: false;
- LLUUID group_id;
-
- count = group_ids.size();
- for (int i = 0; i < count && !is_allowed; i++)
- {
- group_id = group_ids[i];
- current_group_access = parcelp->blockAccess(agent_id, group_id, is_agent_identified, is_agent_transacted, is_agent_ageverified);
-
- if (current_group_access == BA_ALLOWED) is_allowed = true;
- }
-
- return !is_allowed;
-}
-
-BOOL LLParcel::isAgentBanned(const LLUUID& agent_id) const
-{
- // Test ban list
- if (mBanList.find(agent_id) != mBanList.end())
- {
- return TRUE;
- }
-
- return FALSE;
-}
-
-S32 LLParcel::blockAccess(const LLUUID& agent_id, const LLUUID& group_id,
- const BOOL is_agent_identified,
- const BOOL is_agent_transacted,
- const BOOL is_agent_ageverified) const
-{
- // Test ban list
- if (isAgentBanned(agent_id))
- {
- return BA_BANNED;
- }
-
- // Always allow owner on (unless he banned himself, useful for
- // testing). We will also allow estate owners/managers in if they
- // are not explicitly banned.
- if (agent_id == mOwnerID)
- {
- return BA_ALLOWED;
- }
-
- // Special case when using pass list where group access is being restricted but not
- // using access list. In this case group members are allowed only if they buy a pass.
- // We return BA_NOT_IN_LIST if not in list
- BOOL passWithGroup = getParcelFlag(PF_USE_PASS_LIST) && !getParcelFlag(PF_USE_ACCESS_LIST)
- && getParcelFlag(PF_USE_ACCESS_GROUP) && !mGroupID.isNull() && group_id == mGroupID;
-
-
- // Test group list
- if (getParcelFlag(PF_USE_ACCESS_GROUP)
- && !mGroupID.isNull()
- && group_id == mGroupID
- && !passWithGroup)
- {
- return BA_ALLOWED;
- }
-
- // Test access list
- if (getParcelFlag(PF_USE_ACCESS_LIST) || passWithGroup )
- {
- if (mAccessList.find(agent_id) != mAccessList.end())
- {
- return BA_ALLOWED;
- }
-
- return BA_NOT_ON_LIST;
- }
-
- // If we're not doing any other limitations, all users
- // can enter, unless
- if ( !getParcelFlag(PF_USE_ACCESS_GROUP)
- && !getParcelFlag(PF_USE_ACCESS_LIST))
- {
- //If the land is group owned, and you are in the group, bypass these checks
- if(getIsGroupOwned() && group_id == mGroupID)
- {
- return BA_ALLOWED;
- }
-
- // Test for "payment" access levels
- // Anonymous - No Payment Info on File
- if(getParcelFlag(PF_DENY_ANONYMOUS) && !is_agent_identified && !is_agent_transacted)
- {
- return BA_NO_ACCESS_LEVEL;
- }
- // AgeUnverified - Not Age Verified
- if(getParcelFlag(PF_DENY_AGEUNVERIFIED) && !is_agent_ageverified)
- {
- return BA_NOT_AGE_VERIFIED;
- }
-
- return BA_ALLOWED;
- }
-
- return BA_NOT_IN_GROUP;
-
-}
-
void LLParcel::setArea(S32 area, S32 sim_object_limit)
{
@@ -622,34 +477,6 @@ BOOL LLParcel::importAccessEntry(std::istream& input_stream, LLAccessEntry* entr
return input_stream.good();
}
-BOOL LLParcel::importMediaURLFilter(std::istream& input_stream, std::string& url)
-{
- skip_to_end_of_next_keyword("{", input_stream);
-
- while(input_stream.good())
- {
- skip_comments_and_emptyspace(input_stream);
- std::string line, keyword, value;
- get_line(line, input_stream, MAX_STRING);
- get_keyword_and_value(keyword, value, line);
-
- if ("}" == keyword)
- {
- break;
- }
- else if ("url" == keyword)
- {
- url = value;
- }
- else
- {
- llwarns << "Unknown keyword in parcel media url filter section: <"
- << keyword << ">" << llendl;
- }
- }
- return input_stream.good();
-}
-
// Assumes we are in a block "ParcelData"
void LLParcel::packMessage(LLMessageSystem* msg)
{
@@ -696,8 +523,6 @@ void LLParcel::packMessage(LLSD& msg)
msg["media_allow_navigate"] = getMediaAllowNavigate();
msg["media_prevent_camera_zoom"] = getMediaPreventCameraZoom();
msg["media_url_timeout"] = getMediaURLTimeout();
- msg["media_url_filter_enable"] = getMediaURLFilterEnable();
- msg["media_url_filter_list"] = getMediaURLFilterList();
msg["group_id"] = getGroupID();
msg["pass_price"] = mPassPrice;
msg["pass_hours"] = mPassHours;
@@ -789,7 +614,6 @@ void LLParcel::unpackMessage(LLMessageSystem* msg)
msg->getString("MediaLinkSharing", "MediaCurrentURL", buffer);
setMediaCurrentURL(buffer);
msg->getU8 ( "MediaLinkSharing", "MediaAllowNavigate", mMediaAllowNavigate );
- msg->getU8 ( "MediaLinkSharing", "MediaURLFilterEnable", mMediaURLFilterEnable );
msg->getU8 ( "MediaLinkSharing", "MediaPreventCameraZoom", mMediaPreventCameraZoom );
msg->getF32( "MediaLinkSharing", "MediaURLTimeout", mMediaURLTimeout);
}
@@ -1250,8 +1074,6 @@ void LLParcel::clearParcel()
mMediaWidth = 0;
mMediaHeight = 0;
setMediaCurrentURL(LLStringUtil::null);
- setMediaURLFilterList(LLSD::emptyArray());
- setMediaURLFilterEnable(FALSE);
setMediaAllowNavigate(TRUE);
setMediaPreventCameraZoom(FALSE);
setMediaURLTimeout(0.0f);
diff --git a/indra/llinventory/llparcel.h b/indra/llinventory/llparcel.h
index e36d0b20d2..c4363a48df 100644..100755
--- a/indra/llinventory/llparcel.h
+++ b/indra/llinventory/llparcel.h
@@ -45,7 +45,7 @@ const S32 PARCEL_UNIT_AREA = 16;
const F32 PARCEL_HEIGHT = 50.f;
//Height above ground which parcel boundries exist for explicitly banned avatars
-const F32 BAN_HEIGHT = 768.f;
+const F32 BAN_HEIGHT = 5000.f;
// Maximum number of entries in an access list
const S32 PARCEL_MAX_ACCESS_LIST = 300;
@@ -97,6 +97,7 @@ const U32 RT_OTHER = 0x1 << 3;
const U32 RT_LIST = 0x1 << 4;
const U32 RT_SELL = 0x1 << 5;
+const S32 INVALID_PARCEL_ID = -1;
// Timeouts for parcels
// default is 21 days * 24h/d * 60m/h * 60s/m *1000000 usec/s = 1814400000000
@@ -247,8 +248,6 @@ public:
void setMediaWidth(S32 width);
void setMediaHeight(S32 height);
void setMediaCurrentURL(const std::string& url);
- void setMediaURLFilterEnable(U8 enable) { mMediaURLFilterEnable = enable; }
- void setMediaURLFilterList(LLSD list);
void setMediaAllowNavigate(U8 enable) { mMediaAllowNavigate = enable; }
void setMediaURLTimeout(F32 timeout) { mMediaURLTimeout = timeout; }
void setMediaPreventCameraZoom(U8 enable) { mMediaPreventCameraZoom = enable; }
@@ -310,7 +309,6 @@ public:
// BOOL importStream(std::istream& input_stream);
BOOL importAccessEntry(std::istream& input_stream, LLAccessEntry* entry);
- BOOL importMediaURLFilter(std::istream& input_stream, std::string& url);
// BOOL exportStream(std::ostream& output_stream);
void packMessage(LLMessageSystem* msg);
@@ -354,8 +352,6 @@ public:
U8 getMediaAutoScale() const { return mMediaAutoScale; }
U8 getMediaLoop() const { return mMediaLoop; }
const std::string& getMediaCurrentURL() const { return mMediaCurrentURL; }
- U8 getMediaURLFilterEnable() const { return mMediaURLFilterEnable; }
- LLSD getMediaURLFilterList() const { return mMediaURLFilterList; }
U8 getMediaAllowNavigate() const { return mMediaAllowNavigate; }
F32 getMediaURLTimeout() const { return mMediaURLTimeout; }
U8 getMediaPreventCameraZoom() const { return mMediaPreventCameraZoom; }
@@ -531,23 +527,6 @@ public:
// Can this agent change the shape of the land?
BOOL allowTerraformBy(const LLUUID &agent_id) const;
- // Returns 0 if access is OK, otherwise a BA_ return code above.
- S32 blockAccess(const LLUUID& agent_id,
- const LLUUID& group_id,
- const BOOL is_agent_identified,
- const BOOL is_agent_transacted,
- const BOOL is_agent_ageverified) const;
-
- // Only checks if the agent is explicitly banned from this parcel
- BOOL isAgentBanned(const LLUUID& agent_id) const;
-
- static bool isAgentBlockedFromParcel(LLParcel* parcelp,
- const LLUUID& agent_id,
- const uuid_vec_t& group_ids,
- const BOOL is_agent_identified,
- const BOOL is_agent_transacted,
- const BOOL is_agent_ageverified);
-
bool operator==(const LLParcel &rhs) const;
// Calculate rent - area * rent * discount rate
@@ -651,8 +630,6 @@ protected:
U8 mMediaLoop;
std::string mMediaCurrentURL;
LLUUID mMediaID;
- U8 mMediaURLFilterEnable;
- LLSD mMediaURLFilterList;
U8 mMediaAllowNavigate;
U8 mMediaPreventCameraZoom;
F32 mMediaURLTimeout;
diff --git a/indra/llinventory/llparcelflags.h b/indra/llinventory/llparcelflags.h
index b1a917df73..b1a917df73 100644..100755
--- a/indra/llinventory/llparcelflags.h
+++ b/indra/llinventory/llparcelflags.h
diff --git a/indra/llinventory/llpermissions.cpp b/indra/llinventory/llpermissions.cpp
index 7e013de11a..7e013de11a 100644..100755
--- a/indra/llinventory/llpermissions.cpp
+++ b/indra/llinventory/llpermissions.cpp
diff --git a/indra/llinventory/llpermissions.h b/indra/llinventory/llpermissions.h
index 3ecc922370..3ecc922370 100644..100755
--- a/indra/llinventory/llpermissions.h
+++ b/indra/llinventory/llpermissions.h
diff --git a/indra/llinventory/llpermissionsflags.h b/indra/llinventory/llpermissionsflags.h
index 9ecf465c8c..9ecf465c8c 100644..100755
--- a/indra/llinventory/llpermissionsflags.h
+++ b/indra/llinventory/llpermissionsflags.h
diff --git a/indra/llinventory/llsaleinfo.cpp b/indra/llinventory/llsaleinfo.cpp
index dd408a8efe..dd408a8efe 100644..100755
--- a/indra/llinventory/llsaleinfo.cpp
+++ b/indra/llinventory/llsaleinfo.cpp
diff --git a/indra/llinventory/llsaleinfo.h b/indra/llinventory/llsaleinfo.h
index 4e98ccf6ff..4e98ccf6ff 100644..100755
--- a/indra/llinventory/llsaleinfo.h
+++ b/indra/llinventory/llsaleinfo.h
diff --git a/indra/llinventory/lltransactionflags.cpp b/indra/llinventory/lltransactionflags.cpp
index ee0e6ae26c..ee0e6ae26c 100644..100755
--- a/indra/llinventory/lltransactionflags.cpp
+++ b/indra/llinventory/lltransactionflags.cpp
diff --git a/indra/llinventory/lltransactionflags.h b/indra/llinventory/lltransactionflags.h
index 8227f3bcc2..8227f3bcc2 100644..100755
--- a/indra/llinventory/lltransactionflags.h
+++ b/indra/llinventory/lltransactionflags.h
diff --git a/indra/llinventory/lltransactiontypes.h b/indra/llinventory/lltransactiontypes.h
index 6f8d005f1b..6f8d005f1b 100644..100755
--- a/indra/llinventory/lltransactiontypes.h
+++ b/indra/llinventory/lltransactiontypes.h
diff --git a/indra/llinventory/lluserrelations.cpp b/indra/llinventory/lluserrelations.cpp
index b938dfeb7b..b938dfeb7b 100644..100755
--- a/indra/llinventory/lluserrelations.cpp
+++ b/indra/llinventory/lluserrelations.cpp
diff --git a/indra/llinventory/lluserrelations.h b/indra/llinventory/lluserrelations.h
index 9fbf36f0e2..9fbf36f0e2 100644..100755
--- a/indra/llinventory/lluserrelations.h
+++ b/indra/llinventory/lluserrelations.h
diff --git a/indra/llinventory/tests/inventorymisc_test.cpp b/indra/llinventory/tests/inventorymisc_test.cpp
index c9af7c4eac..c9af7c4eac 100644..100755
--- a/indra/llinventory/tests/inventorymisc_test.cpp
+++ b/indra/llinventory/tests/inventorymisc_test.cpp
diff --git a/indra/llinventory/tests/llparcel_test.cpp b/indra/llinventory/tests/llparcel_test.cpp
index f2e4b03ff7..f2e4b03ff7 100644..100755
--- a/indra/llinventory/tests/llparcel_test.cpp
+++ b/indra/llinventory/tests/llparcel_test.cpp
diff --git a/indra/llkdu/CMakeLists.txt b/indra/llkdu/CMakeLists.txt
index bdac2eded7..b8f8b420c3 100644..100755
--- a/indra/llkdu/CMakeLists.txt
+++ b/indra/llkdu/CMakeLists.txt
@@ -41,7 +41,10 @@ set_source_files_properties(${llkdu_HEADER_FILES}
list(APPEND llkdu_SOURCE_FILES ${llkdu_HEADER_FILES})
if (USE_KDU)
- add_library (${LLKDU_LIBRARIES} ${llkdu_SOURCE_FILES})
+ add_library (llkdu ${llkdu_SOURCE_FILES})
+
+ target_link_libraries(llkdu
+ ${KDU_LIBRARY})
# Add tests
if (LL_TESTS)
diff --git a/indra/llkdu/llimagej2ckdu.cpp b/indra/llkdu/llimagej2ckdu.cpp
index c156ed0cef..0c0a844b73 100644..100755
--- a/indra/llkdu/llimagej2ckdu.cpp
+++ b/indra/llkdu/llimagej2ckdu.cpp
@@ -32,6 +32,7 @@
#include "llmath.h"
#include "llkdumem.h"
+#include "kdu_block_coding.h"
class kdc_flow_control {
@@ -244,7 +245,9 @@ void LLImageJ2CKDU::setupCodeStream(LLImageJ2C &base, BOOL keep_codestream, ECod
mCodeStreamp->create(mInputp);
// Set the maximum number of bytes to use from the codestream
- mCodeStreamp->set_max_bytes(max_bytes);
+ // *TODO: This seems to be wrong. The base class should have no idea of how j2c compression works so no
+ // good way of computing what's the byte range to be used.
+ mCodeStreamp->set_max_bytes(max_bytes,true);
// If you want to flip or rotate the image for some reason, change
// the resolution, or identify a restricted region of interest, this is
@@ -291,8 +294,13 @@ void LLImageJ2CKDU::setupCodeStream(LLImageJ2C &base, BOOL keep_codestream, ECod
}
}
+ // Get the number of resolution levels in that image
+ mLevels = mCodeStreamp->get_min_dwt_levels();
+
+ // Set the base dimensions
base.setSize(dims.size.x, dims.size.y, components);
-
+ base.setLevels(mLevels);
+
if (!keep_codestream)
{
mCodeStreamp->destroy();
@@ -351,7 +359,8 @@ BOOL LLImageJ2CKDU::initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int bloc
mLevels = levels;
if (mLevels != 0)
{
- mLevels = llclamp(mLevels,MIN_DECOMPOSITION_LEVELS,MIN_DECOMPOSITION_LEVELS);
+ mLevels = llclamp(mLevels,MIN_DECOMPOSITION_LEVELS,MAX_DECOMPOSITION_LEVELS);
+ base.setLevels(mLevels);
}
return TRUE;
}
@@ -364,6 +373,9 @@ BOOL LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco
// To regain control, we throw an exception, and catch it here.
try
{
+ // Merov : Test!! DO NOT COMMIT!!
+ //findDiscardLevelsBoundaries(base);
+
base.updateRawDiscardLevel();
setupCodeStream(base, TRUE, mode);
@@ -381,7 +393,7 @@ BOOL LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco
region_kdu->size.y = region[3] - region[1];
}
int discard = (discard_level != -1 ? discard_level : base.getRawDiscardLevel());
-
+ //llinfos << "Merov debug : initDecode, discard used = " << discard << ", asked = " << discard_level << llendl;
// Apply loading restrictions
mCodeStreamp->apply_input_restrictions( first_channel, max_channel_count, discard, 0, region_kdu);
@@ -394,12 +406,9 @@ BOOL LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco
// Resize raw_image according to the image to be decoded
kdu_dims dims; mCodeStreamp->get_dims(0,dims);
- // *TODO: Use the real number of levels read from the file throughout the code instead of relying on an infered value from dimensions
- //S32 levels = mCodeStreamp->get_min_dwt_levels();
S32 channels = base.getComponents() - first_channel;
channels = llmin(channels,max_channel_count);
raw_image.resize(dims.size.x, dims.size.y, channels);
- //llinfos << "j2c image dimension: width = " << dims.size.x << ", height = " << dims.size.y << ", channels = " << channels << ", levels = " << levels << llendl;
if (!mTileIndicesp)
{
@@ -583,12 +592,6 @@ BOOL LLImageJ2CKDU::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, co
comment.put_text(comment_text);
}
- // Set codestream options
- int num_layer_specs = 0;
-
- kdu_long layer_bytes[64];
- U32 max_bytes = 0;
-
if (num_components >= 3)
{
// Note that we always use YCC and not YUV
@@ -596,66 +599,51 @@ BOOL LLImageJ2CKDU::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, co
set_default_colour_weights(codestream.access_siz());
}
- if (reversible)
+ // Set codestream options
+ int nb_layers = 0;
+ kdu_long layer_bytes[MAX_NB_LAYERS];
+ U32 max_bytes = (U32)(base.getWidth() * base.getHeight() * base.getComponents());
+
+ // Rate is the argument passed into the LLImageJ2C which specifies the target compression rate. The default is 8:1.
+ // *TODO: mRate is actually always 8:1 in the viewer. Test different values.
+ llassert (base.mRate > 0.f);
+ max_bytes = (U32)((F32)(max_bytes) * base.mRate);
+
+ // This code is where we specify the target number of bytes for each quality layer.
+ // We're using a logarithmic spacing rule that fits with our way of fetching texture data.
+ // Note: For more info on this layers business, read kdu_codestream::flush() doc in kdu_compressed.h
+ layer_bytes[nb_layers++] = FIRST_PACKET_SIZE;
+ U32 i = MIN_LAYER_SIZE;
+ while ((i < max_bytes) && (nb_layers < (MAX_NB_LAYERS-1)))
{
- codestream.access_siz()->parse_string("Creversible=yes");
- // *TODO: we should use yuv in reversible mode and one level since those images are small.
- // Don't turn this on now though as both create problems on decoding for the moment
- //codestream.access_siz()->parse_string("Clevels=1");
- //codestream.access_siz()->parse_string("Cycc=no");
- // If we're doing reversible (i.e. lossless compression), assumes we're not using quality layers.
- // *TODO: this is incorrect and unecessary. Try using the regular layer setting.
- codestream.access_siz()->parse_string("Clayers=1");
- num_layer_specs = 1;
- layer_bytes[0] = 0;
+ layer_bytes[nb_layers++] = i;
+ i *= 4;
}
- else
+ // Note: for small images, we can have (max_bytes < FIRST_PACKET_SIZE), hence the test
+ if (layer_bytes[nb_layers-1] < max_bytes)
{
- // Rate is the argument passed into the LLImageJ2C which
- // specifies the target compression rate. The default is 8:1.
- // Possibly if max_bytes < 500, we should just use the default setting?
- // *TODO: mRate is actually always 8:1 in the viewer. Test different values. Also force to reversible for small (< 500 bytes) textures.
- if (base.mRate != 0.f)
- {
- max_bytes = (U32)(base.mRate*base.getWidth()*base.getHeight()*base.getComponents());
- }
- else
- {
- max_bytes = (U32)(base.getWidth()*base.getHeight()*base.getComponents()*0.125);
- }
-
- const U32 min_bytes = FIRST_PACKET_SIZE;
- if (max_bytes > min_bytes)
- {
- U32 i;
- // This code is where we specify the target number of bytes for
- // each layer. Not sure if we should do this for small images
- // or not. The goal is to have this roughly align with
- // different quality levels that we decode at.
- for (i = min_bytes; i < max_bytes; i*=4)
- {
- if (i == min_bytes * 4)
- {
- i = 2000;
- }
- layer_bytes[num_layer_specs] = i;
- num_layer_specs++;
- }
- layer_bytes[num_layer_specs] = max_bytes;
- num_layer_specs++;
+ // Set the last quality layer so to fit the preset compression ratio
+ layer_bytes[nb_layers++] = max_bytes;
+ }
- std::string layer_string = llformat("Clayers=%d",num_layer_specs);
- codestream.access_siz()->parse_string(layer_string.c_str());
- }
- else
+ if (reversible)
+ {
+ // Use 0 for a last quality layer for reversible images so all remaining code blocks will be flushed
+ // Hack: KDU encoding for reversible images has a bug for small images that leads to j2c images that
+ // cannot be open or are very blurry. Avoiding that last layer prevents the problem to happen.
+ if ((base.getWidth() >= 32) || (base.getHeight() >= 32))
{
- layer_bytes[0] = min_bytes;
- num_layer_specs = 1;
- std::string layer_string = llformat("Clayers=%d",num_layer_specs);
- codestream.access_siz()->parse_string(layer_string.c_str());
+ layer_bytes[nb_layers++] = 0;
}
+ codestream.access_siz()->parse_string("Creversible=yes");
+ // *TODO: we should use yuv in reversible mode
+ // Don't turn this on now though as it creates problems on decoding for the moment
+ //codestream.access_siz()->parse_string("Cycc=no");
}
+ std::string layer_string = llformat("Clayers=%d",nb_layers);
+ codestream.access_siz()->parse_string(layer_string.c_str());
+
// Set up data ordering, markers, etc... if precincts or blocks specified
if ((mBlocksSize != -1) || (mPrecinctsSize != -1))
{
@@ -669,23 +657,26 @@ BOOL LLImageJ2CKDU::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, co
std::string blocks_string = llformat("Cblk={%d,%d}",mBlocksSize,mBlocksSize);
codestream.access_siz()->parse_string(blocks_string.c_str());
}
- std::string ordering_string = llformat("Corder=RPCL");
+ std::string ordering_string = llformat("Corder=LRCP");
codestream.access_siz()->parse_string(ordering_string.c_str());
std::string PLT_string = llformat("ORGgen_plt=yes");
codestream.access_siz()->parse_string(PLT_string.c_str());
std::string Parts_string = llformat("ORGtparts=R");
codestream.access_siz()->parse_string(Parts_string.c_str());
}
+
+ // Set the number of wavelets subresolutions (aka levels)
if (mLevels != 0)
{
std::string levels_string = llformat("Clevels=%d",mLevels);
codestream.access_siz()->parse_string(levels_string.c_str());
}
+ // Complete the encode settings
codestream.access_siz()->finalize_all();
codestream.change_appearance(transpose,vflip,hflip);
- // Now we are ready for sample data processing.
+ // Now we are ready for sample data processing
kdc_flow_control *tile = new kdc_flow_control(&mem_in,codestream);
bool done = false;
while (!done)
@@ -702,7 +693,7 @@ BOOL LLImageJ2CKDU::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, co
}
// Produce the compressed output
- codestream.flush(layer_bytes,num_layer_specs);
+ codestream.flush(layer_bytes,nb_layers);
// Cleanup
delete tile;
@@ -750,6 +741,207 @@ BOOL LLImageJ2CKDU::getMetadata(LLImageJ2C &base)
}
}
+/*****************************************************************************/
+/* STATIC copy_block */
+/*****************************************************************************/
+
+static void copy_block(kdu_block *in, kdu_block *out)
+{
+ if (in->K_max_prime != out->K_max_prime)
+ {
+ std::cout << "Cannot copy blocks belonging to subbands with different quantization parameters." << std::endl;
+ return;
+ }
+ if ((in->size.x != out->size.x) || (in->size.y != out->size.y))
+ {
+ std::cout << "Cannot copy code-blocks with different dimensions." << std::endl;
+ return;
+ }
+ out->missing_msbs = in->missing_msbs;
+ if (out->max_passes < (in->num_passes+2)) // Gives us enough to round up
+ out->set_max_passes(in->num_passes+2,false); // to the next whole bit-plane
+ out->num_passes = in->num_passes;
+ int num_bytes = 0;
+ for (int z=0; z < in->num_passes; z++)
+ {
+ num_bytes += (out->pass_lengths[z] = in->pass_lengths[z]);
+ out->pass_slopes[z] = in->pass_slopes[z];
+ }
+
+ // Just copy compressed code-bytes. Block transcoding not supported.
+ if (out->max_bytes < num_bytes)
+ out->set_max_bytes(num_bytes,false);
+ memcpy(out->byte_buffer,in->byte_buffer,(size_t) num_bytes);
+}
+
+/*****************************************************************************/
+/* STATIC copy_tile */
+/*****************************************************************************/
+
+static void
+copy_tile(kdu_tile tile_in, kdu_tile tile_out, int tnum_in, int tnum_out,
+ kdu_params *siz_in, kdu_params *siz_out, int skip_components,
+ int &num_blocks)
+{
+ int num_components = tile_out.get_num_components();
+ int new_tpart=0, next_tpart = 1;
+
+ for (int c=0; c < num_components; c++)
+ {
+ kdu_tile_comp comp_in, comp_out;
+ comp_in = tile_in.access_component(c);
+ comp_out = tile_out.access_component(c);
+ int num_resolutions = comp_out.get_num_resolutions();
+ //std::cout << " Copying tile : num_resolutions = " << num_resolutions << std::endl;
+ for (int r=0; r < num_resolutions; r++)
+ {
+ kdu_resolution res_in; res_in = comp_in.access_resolution(r);
+ kdu_resolution res_out; res_out = comp_out.access_resolution(r);
+ int b, min_band;
+ int num_bands = res_in.get_valid_band_indices(min_band);
+ std::cout << " Copying tile : num_bands = " << num_bands << std::endl;
+ for (b=min_band; num_bands > 0; num_bands--, b++)
+ {
+ kdu_subband band_in; band_in = res_in.access_subband(b);
+ kdu_subband band_out; band_out = res_out.access_subband(b);
+ kdu_dims blocks_in; band_in.get_valid_blocks(blocks_in);
+ kdu_dims blocks_out; band_out.get_valid_blocks(blocks_out);
+ if ((blocks_in.size.x != blocks_out.size.x) ||
+ (blocks_in.size.y != blocks_out.size.y))
+ {
+ std::cout << "Transcoding operation cannot proceed: Code-block partitions for the input and output code-streams do not agree." << std::endl;
+ return;
+ }
+ kdu_coords idx;
+ //std::cout << " Copying tile : block indices, x = " << blocks_out.size.x << " and y = " << blocks_out.size.y << std::endl;
+ for (idx.y=0; idx.y < blocks_out.size.y; idx.y++)
+ {
+ for (idx.x=0; idx.x < blocks_out.size.x; idx.x++)
+ {
+ kdu_block *in =
+ band_in.open_block(idx+blocks_in.pos,&new_tpart);
+ for (; next_tpart <= new_tpart; next_tpart++)
+ siz_out->copy_from(siz_in,tnum_in,tnum_out,next_tpart,
+ skip_components);
+ kdu_block *out = band_out.open_block(idx+blocks_out.pos);
+ copy_block(in,out);
+ band_in.close_block(in);
+ band_out.close_block(out);
+ num_blocks++;
+ }
+ }
+ }
+ }
+ }
+}
+
+// Find the block boundary for each discard level in the input image.
+// We parse the input blocks and copy them in a temporary output stream.
+// For the moment, we do nothing more that parsing the raw list of blocks and outputing result.
+void LLImageJ2CKDU::findDiscardLevelsBoundaries(LLImageJ2C &base)
+{
+ // We need the number of levels in that image before starting.
+ getMetadata(base);
+
+ for (int discard_level = 0; discard_level < mLevels; discard_level++)
+ {
+ //std::cout << "Parsing discard level = " << discard_level << std::endl;
+ // Create the input codestream object.
+ setupCodeStream(base, TRUE, MODE_FAST);
+ mCodeStreamp->apply_input_restrictions(0, 4, discard_level, 0, NULL);
+ mCodeStreamp->set_max_bytes(KDU_LONG_MAX,true);
+ siz_params *siz_in = mCodeStreamp->access_siz();
+
+ // Create the output codestream object.
+ siz_params siz;
+ siz.copy_from(siz_in,-1,-1,-1,0,discard_level,false,false,false);
+ siz.set(Scomponents,0,0,mCodeStreamp->get_num_components());
+
+ U32 max_output_size = base.getWidth()*base.getHeight()*base.getComponents();
+ max_output_size = (max_output_size < 1000 ? 1000 : max_output_size);
+ U8 *output_buffer = new U8[max_output_size];
+ U32 output_size = 0; // Address updated by LLKDUMemTarget to give the final compressed buffer size
+ LLKDUMemTarget output(output_buffer, output_size, max_output_size);
+ kdu_codestream codestream_out;
+ codestream_out.create(&siz,&output);
+ //codestream_out.share_buffering(*mCodeStreamp);
+ siz_params *siz_out = codestream_out.access_siz();
+ siz_out->copy_from(siz_in,-1,-1,-1,0,discard_level,false,false,false);
+ codestream_out.access_siz()->finalize_all(-1);
+
+ // Set up rate control variables
+ kdu_long max_bytes = KDU_LONG_MAX;
+ kdu_params *cod = siz_out->access_cluster(COD_params);
+ int total_layers; cod->get(Clayers,0,0,total_layers);
+ kdu_long *layer_bytes = new kdu_long[total_layers];
+ int nel, non_empty_layers = 0;
+
+ // Now ready to perform the transfer of compressed data between streams
+ int flush_counter = INT_MAX;
+ kdu_dims tile_indices_in;
+ mCodeStreamp->get_valid_tiles(tile_indices_in);
+ kdu_dims tile_indices_out;
+ codestream_out.get_valid_tiles(tile_indices_out);
+ assert((tile_indices_in.size.x == tile_indices_out.size.x) &&
+ (tile_indices_in.size.y == tile_indices_out.size.y));
+ int num_blocks=0;
+
+ kdu_coords idx;
+ //std::cout << "Parsing tiles : x = " << tile_indices_out.size.x << " to y = " << tile_indices_out.size.y << std::endl;
+ for (idx.y=0; idx.y < tile_indices_out.size.y; idx.y++)
+ {
+ for (idx.x=0; idx.x < tile_indices_out.size.x; idx.x++)
+ {
+ kdu_tile tile_in = mCodeStreamp->open_tile(idx+tile_indices_in.pos);
+ int tnum_in = tile_in.get_tnum();
+ int tnum_out = idx.x + idx.y*tile_indices_out.size.x;
+ siz_out->copy_from(siz_in,tnum_in,tnum_out,0,0,discard_level,false,false,false);
+ siz_out->finalize_all(tnum_out);
+ // Note: do not open the output tile without first copying any tile-specific code-stream parameters
+ kdu_tile tile_out = codestream_out.open_tile(idx+tile_indices_out.pos);
+ assert(tnum_out == tile_out.get_tnum());
+ copy_tile(tile_in,tile_out,tnum_in,tnum_out,siz_in,siz_out,0,num_blocks);
+ tile_in.close();
+ tile_out.close();
+ flush_counter--;
+ if ((flush_counter <= 0) && codestream_out.ready_for_flush())
+ {
+ flush_counter = INT_MAX;
+ nel = codestream_out.trans_out(max_bytes,layer_bytes,total_layers);
+ non_empty_layers = (nel > non_empty_layers)?nel:non_empty_layers;
+ }
+ }
+ }
+
+ // Generate the output code-stream
+ if (codestream_out.ready_for_flush())
+ {
+ nel = codestream_out.trans_out(max_bytes,layer_bytes,total_layers);
+ non_empty_layers = (nel > non_empty_layers)?nel:non_empty_layers;
+ }
+ if (non_empty_layers > total_layers)
+ non_empty_layers = total_layers; // Can happen if a tile has more layers
+
+ // Print out stats
+ std::cout << "Code stream parsing for discard level = " << discard_level << std::endl;
+ std::cout << " Total compressed memory in = " << mCodeStreamp->get_compressed_data_memory() << " bytes" << std::endl;
+ std::cout << " Total compressed memory out = " << codestream_out.get_compressed_data_memory() << " bytes" << std::endl;
+ //std::cout << " Output contains " << total_layers << " quality layers" << std::endl;
+ std::cout << " Transferred " << num_blocks << " code-blocks from in to out" << std::endl;
+ //std::cout << " Read " << mCodeStreamp->get_num_tparts() << " tile-part(s) from a total of " << (int) tile_indices_in.area() << " tile(s)" << std::endl;
+ std::cout << " Total bytes read = " << mCodeStreamp->get_total_bytes() << std::endl;
+ //std::cout << " Wrote " << codestream_out.get_num_tparts() << " tile-part(s) in a total of " << (int) tile_indices_out.area() << " tile(s)" << std::endl;
+ std::cout << " Total bytes written = " << codestream_out.get_total_bytes() << std::endl;
+ std::cout << "-------------" << std::endl;
+
+ // Clean-up
+ cleanupCodeStream();
+ codestream_out.destroy();
+ delete[] output_buffer;
+ }
+ return;
+}
+
void set_default_colour_weights(kdu_params *siz)
{
kdu_params *cod = siz->access_cluster(COD_params);
@@ -987,7 +1179,7 @@ LLKDUDecodeState::LLKDUDecodeState(kdu_tile tile, kdu_byte *buf, S32 row_gap)
llassert(mDims == comp_dims); // Safety check; the caller has ensured this
}
bool use_shorts = (mComps[c].get_bit_depth(true) <= 16);
- mLines[c].pre_create(&mAllocator,mDims.size.x,mReversible[c],use_shorts);
+ mLines[c].pre_create(&mAllocator,mDims.size.x,mReversible[c],use_shorts,0,0);
if (res.which() == 0) // No DWT levels used
{
mEngines[c] = kdu_decoder(res.access_subband(LL_BAND),&mAllocator,use_shorts);
@@ -1031,7 +1223,7 @@ separation between consecutive rows in the real buffer. */
{
for (c = 0; c < mNumComponents; c++)
{
- mEngines[c].pull(mLines[c],true);
+ mEngines[c].pull(mLines[c]);
}
if ((mNumComponents >= 3) && mUseYCC)
{
diff --git a/indra/llkdu/llimagej2ckdu.h b/indra/llkdu/llimagej2ckdu.h
index 1489dbf704..fb1f6535ba 100644..100755
--- a/indra/llkdu/llimagej2ckdu.h
+++ b/indra/llkdu/llimagej2ckdu.h
@@ -32,6 +32,7 @@
//
// KDU core header files
//
+#define KDU_NO_THREADS
#include "kdu_elementary.h"
#include "kdu_messaging.h"
#include "kdu_params.h"
@@ -60,6 +61,7 @@ protected:
BOOL reversible=FALSE);
/*virtual*/ BOOL initDecode(LLImageJ2C &base, LLImageRaw &raw_image, int discard_level = -1, int* region = NULL);
/*virtual*/ BOOL initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int blocks_size = -1, int precincts_size = -1, int levels = 0);
+ void findDiscardLevelsBoundaries(LLImageJ2C &base);
private:
BOOL initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, ECodeStreamMode mode, S32 first_channel, S32 max_channel_count, int discard_level = -1, int* region = NULL);
diff --git a/indra/llkdu/llkdumem.cpp b/indra/llkdu/llkdumem.cpp
index 0347475559..0347475559 100644..100755
--- a/indra/llkdu/llkdumem.cpp
+++ b/indra/llkdu/llkdumem.cpp
diff --git a/indra/llkdu/llkdumem.h b/indra/llkdu/llkdumem.h
index 9d923fc367..dbdf88b2d9 100644..100755
--- a/indra/llkdu/llkdumem.h
+++ b/indra/llkdu/llkdumem.h
@@ -28,6 +28,7 @@
#define LL_LLKDUMEM_H
// Support classes for reading and writing from memory buffers in KDU
+#define KDU_NO_THREADS
#include "kdu_image.h"
#include "kdu_elementary.h"
#include "kdu_messaging.h"
diff --git a/indra/llkdu/tests/llimagej2ckdu_test.cpp b/indra/llkdu/tests/llimagej2ckdu_test.cpp
index ab60ab6d50..62c245f125 100644..100755
--- a/indra/llkdu/tests/llimagej2ckdu_test.cpp
+++ b/indra/llkdu/tests/llimagej2ckdu_test.cpp
@@ -29,6 +29,7 @@
// Class to test
#include "llimagej2ckdu.h"
#include "llkdumem.h"
+#include "kdu_block_coding.h"
// Tut header
#include "lltut.h"
@@ -57,8 +58,7 @@ mWidth(0),
mHeight(0),
mComponents(0),
mBadBufferAllocation(false),
-mAllowOverSize(false),
-mMemType(LLMemType::MTYPE_IMAGEBASE)
+mAllowOverSize(false)
{ }
LLImageBase::~LLImageBase() { }
U8* LLImageBase::allocateData(S32 ) { return NULL; }
@@ -86,7 +86,7 @@ void LLImageFormatted::resetLastError() { }
void LLImageFormatted::sanityCheck() { }
void LLImageFormatted::setLastError(const std::string& , const std::string& ) { }
-LLImageJ2C::LLImageJ2C() : LLImageFormatted(IMG_CODEC_J2C) { }
+LLImageJ2C::LLImageJ2C() : LLImageFormatted(IMG_CODEC_J2C), mRate(DEFAULT_COMPRESSION_RATE) { }
LLImageJ2C::~LLImageJ2C() { }
S32 LLImageJ2C::calcDataSize(S32 ) { return 0; }
S32 LLImageJ2C::calcDiscardLevelBytes(S32 ) { return 0; }
@@ -107,23 +107,32 @@ bool LLKDUMemIn::get(int, kdu_line_buf&, int) { return false; }
// Stub Kakadu Library calls
kdu_tile_comp kdu_tile::access_component(int ) { kdu_tile_comp a; return a; }
+kdu_block_encoder::kdu_block_encoder() { }
+kdu_block_decoder::kdu_block_decoder() { }
+void kdu_block::set_max_passes(int , bool ) { }
+void kdu_block::set_max_bytes(int , bool ) { }
+void kdu_block::set_max_samples(int ) { }
void kdu_tile::close(kdu_thread_env* ) { }
int kdu_tile::get_num_components() { return 0; }
bool kdu_tile::get_ycc() { return false; }
void kdu_tile::set_components_of_interest(int , const int* ) { }
+int kdu_tile::get_tnum() { return 0; }
kdu_resolution kdu_tile_comp::access_resolution() { kdu_resolution a; return a; }
+kdu_resolution kdu_tile_comp::access_resolution(int ) { kdu_resolution a; return a; }
int kdu_tile_comp::get_bit_depth(bool ) { return 8; }
bool kdu_tile_comp::get_reversible() { return false; }
+int kdu_tile_comp::get_num_resolutions() { return 1; }
kdu_subband kdu_resolution::access_subband(int ) { kdu_subband a; return a; }
void kdu_resolution::get_dims(kdu_dims& ) { }
int kdu_resolution::which() { return 0; }
-kdu_decoder::kdu_decoder(kdu_subband , kdu_sample_allocator*, bool , float, int, kdu_thread_env*, kdu_thread_queue*) { }
+int kdu_resolution::get_valid_band_indices(int &) { return 1; }
kdu_synthesis::kdu_synthesis(kdu_resolution, kdu_sample_allocator*, bool, float, kdu_thread_env*, kdu_thread_queue*) { }
kdu_params::kdu_params(const char*, bool, bool, bool, bool, bool) { }
kdu_params::~kdu_params() { }
void kdu_params::set(const char* , int , int , bool ) { }
void kdu_params::set(const char* , int , int , int ) { }
void kdu_params::finalize_all(bool ) { }
+void kdu_params::finalize_all(int, bool ) { }
void kdu_params::copy_from(kdu_params*, int, int, int, int, int, bool, bool, bool) { }
bool kdu_params::parse_string(const char*) { return false; }
bool kdu_params::get(const char*, int, int, bool&, bool, bool, bool) { return false; }
@@ -135,26 +144,35 @@ void kdu_codestream::set_fast() { }
void kdu_codestream::set_fussy() { }
void kdu_codestream::get_dims(int, kdu_dims&, bool ) { }
int kdu_codestream::get_min_dwt_levels() { return 5; }
+int kdu_codestream::get_max_tile_layers() { return 1; }
void kdu_codestream::change_appearance(bool, bool, bool) { }
void kdu_codestream::get_tile_dims(kdu_coords, int, kdu_dims&, bool ) { }
void kdu_codestream::destroy() { }
void kdu_codestream::collect_timing_stats(int ) { }
void kdu_codestream::set_max_bytes(kdu_long, bool, bool ) { }
void kdu_codestream::get_valid_tiles(kdu_dims& ) { }
-void kdu_codestream::create(siz_params*, kdu_compressed_target*, kdu_dims*, int, kdu_long ) { }
void kdu_codestream::create(kdu_compressed_source*, kdu_thread_env*) { }
void kdu_codestream::apply_input_restrictions( int, int, int, int, kdu_dims*, kdu_component_access_mode ) { }
void kdu_codestream::get_subsampling(int , kdu_coords&, bool ) { }
void kdu_codestream::flush(kdu_long *, int , kdu_uint16 *, bool, bool, double, kdu_thread_env*) { }
void kdu_codestream::set_resilient(bool ) { }
int kdu_codestream::get_num_components(bool ) { return 0; }
+kdu_long kdu_codestream::get_total_bytes(bool ) { return 0; }
+kdu_long kdu_codestream::get_compressed_data_memory(bool ) {return 0; }
+void kdu_codestream::share_buffering(kdu_codestream ) { }
+int kdu_codestream::get_num_tparts() { return 0; }
+int kdu_codestream::trans_out(kdu_long, kdu_long*, int, bool, kdu_thread_env* ) { return 0; }
+bool kdu_codestream::ready_for_flush(kdu_thread_env*) { return false; }
siz_params* kdu_codestream::access_siz() { return NULL; }
kdu_tile kdu_codestream::open_tile(kdu_coords , kdu_thread_env* ) { kdu_tile a; return a; }
kdu_codestream_comment kdu_codestream::add_comment() { kdu_codestream_comment a; return a; }
+void kdu_subband::close_block(kdu_block*, kdu_thread_env*) { }
+void kdu_subband::get_valid_blocks(kdu_dims &indices) { }
+kdu_block* kdu_subband::open_block(kdu_coords, int*, kdu_thread_env*) { return NULL; }
bool kdu_codestream_comment::put_text(const char*) { return false; }
void kdu_customize_warnings(kdu_message*) { }
void kdu_customize_errors(kdu_message*) { }
-void kdu_convert_ycc_to_rgb(kdu_line_buf&, kdu_line_buf&, kdu_line_buf&, int) { }
+
kdu_long kdu_multi_analysis::create(kdu_codestream, kdu_tile, bool, kdu_roi_image*, bool, int, kdu_thread_env*, kdu_thread_queue*, bool ) { kdu_long a = 0; return a; }
siz_params::siz_params() : kdu_params(NULL, false, false, false, false, false) { }
void siz_params::finalize(bool ) { }
@@ -163,6 +181,21 @@ int siz_params::write_marker_segment(kdu_output*, kdu_params*, int) { return 0;
bool siz_params::check_marker_segment(kdu_uint16, int, kdu_byte a[], int&) { return false; }
bool siz_params::read_marker_segment(kdu_uint16, int, kdu_byte a[], int) { return false; }
+#ifdef LL_LINUX
+// Linux use the old pre KDU v7.0.0
+// *TODO: Supress this legacy stubbs once Linux migrates to v7.0.0
+kdu_decoder::kdu_decoder(kdu_subband , kdu_sample_allocator*, bool , float, int, kdu_thread_env*, kdu_thread_queue*) { }
+void kdu_codestream::create(siz_params*, kdu_compressed_target*, kdu_dims*, int, kdu_long ) { }
+void kdu_convert_ycc_to_rgb(kdu_line_buf&, kdu_line_buf&, kdu_line_buf&, int) { }
+#else
+kdu_decoder::kdu_decoder(kdu_subband , kdu_sample_allocator*, bool , float, int, kdu_thread_env*, kdu_thread_queue*, int) { }
+void kdu_codestream::create(siz_params*, kdu_compressed_target*, kdu_dims*, int, kdu_long, kdu_thread_env* ) { }
+void (*kdu_convert_ycc_to_rgb_rev16)(kdu_int16*,kdu_int16*,kdu_int16*,int);
+void (*kdu_convert_ycc_to_rgb_irrev16)(kdu_int16*,kdu_int16*,kdu_int16*,int);
+void (*kdu_convert_ycc_to_rgb_rev32)(kdu_int32*,kdu_int32*,kdu_int32*,int);
+void (*kdu_convert_ycc_to_rgb_irrev32)(float*,float*,float*,int);
+#endif
+
// -------------------------------------------------------------------------------------------
// TUT
// -------------------------------------------------------------------------------------------
diff --git a/indra/llmath/CMakeLists.txt b/indra/llmath/CMakeLists.txt
index b5e59c1ca3..0614fd92ef 100644..100755
--- a/indra/llmath/CMakeLists.txt
+++ b/indra/llmath/CMakeLists.txt
@@ -7,6 +7,7 @@ include(LLCommon)
include_directories(
${LLCOMMON_INCLUDE_DIRS}
+ ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
)
set(llmath_SOURCE_FILES
@@ -99,6 +100,10 @@ list(APPEND llmath_SOURCE_FILES ${llmath_HEADER_FILES})
add_library (llmath ${llmath_SOURCE_FILES})
+target_link_libraries(llmath
+ ${LLCOMMON_LIBRARIES}
+ )
+
# Add tests
if (LL_TESTS)
include(LLAddBuildTest)
@@ -117,6 +122,7 @@ if (LL_TESTS)
# INTEGRATION TESTS
set(test_libs llmath llcommon ${LLCOMMON_LIBRARIES} ${WINDOWS_LIBRARIES})
# TODO: Some of these need refactoring to be proper Unit tests rather than Integration tests.
+ LL_ADD_INTEGRATION_TEST(alignment "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llbbox llbbox.cpp "${test_libs}")
LL_ADD_INTEGRATION_TEST(llquaternion llquaternion.cpp "${test_libs}")
LL_ADD_INTEGRATION_TEST(mathmisc "" "${test_libs}")
diff --git a/indra/llmath/camera.h b/indra/llmath/camera.h
index 26f3c3d19f..26f3c3d19f 100644..100755
--- a/indra/llmath/camera.h
+++ b/indra/llmath/camera.h
diff --git a/indra/llmath/coordframe.h b/indra/llmath/coordframe.h
index 271bcb433c..271bcb433c 100644..100755
--- a/indra/llmath/coordframe.h
+++ b/indra/llmath/coordframe.h
diff --git a/indra/llmath/llbbox.cpp b/indra/llmath/llbbox.cpp
index 3e2c05a6e6..3e2c05a6e6 100644..100755
--- a/indra/llmath/llbbox.cpp
+++ b/indra/llmath/llbbox.cpp
diff --git a/indra/llmath/llbbox.h b/indra/llmath/llbbox.h
index 28e69b75e1..28e69b75e1 100644..100755
--- a/indra/llmath/llbbox.h
+++ b/indra/llmath/llbbox.h
diff --git a/indra/llmath/llbboxlocal.cpp b/indra/llmath/llbboxlocal.cpp
index bf0c1a7b93..bf0c1a7b93 100644..100755
--- a/indra/llmath/llbboxlocal.cpp
+++ b/indra/llmath/llbboxlocal.cpp
diff --git a/indra/llmath/llbboxlocal.h b/indra/llmath/llbboxlocal.h
index defb899248..defb899248 100644..100755
--- a/indra/llmath/llbboxlocal.h
+++ b/indra/llmath/llbboxlocal.h
diff --git a/indra/llmath/llcalc.cpp b/indra/llmath/llcalc.cpp
index 1b2d609b67..1b2d609b67 100644..100755
--- a/indra/llmath/llcalc.cpp
+++ b/indra/llmath/llcalc.cpp
diff --git a/indra/llmath/llcalc.h b/indra/llmath/llcalc.h
index ceb9dce585..ceb9dce585 100644..100755
--- a/indra/llmath/llcalc.h
+++ b/indra/llmath/llcalc.h
diff --git a/indra/llmath/llcalcparser.cpp b/indra/llmath/llcalcparser.cpp
index b4ca320659..b4ca320659 100644..100755
--- a/indra/llmath/llcalcparser.cpp
+++ b/indra/llmath/llcalcparser.cpp
diff --git a/indra/llmath/llcalcparser.h b/indra/llmath/llcalcparser.h
index e0ad270266..e0ad270266 100644..100755
--- a/indra/llmath/llcalcparser.h
+++ b/indra/llmath/llcalcparser.h
diff --git a/indra/llmath/llcamera.cpp b/indra/llmath/llcamera.cpp
index 22ba26f99b..33cf185196 100644..100755
--- a/indra/llmath/llcamera.cpp
+++ b/indra/llmath/llcamera.cpp
@@ -42,6 +42,11 @@ LLCamera::LLCamera() :
mPlaneCount(6),
mFrustumCornerDist(0.f)
{
+ for (U32 i = 0; i < PLANE_MASK_NUM; i++)
+ {
+ mPlaneMask[i] = PLANE_MASK_NONE;
+ }
+
calculateFrustumPlanes();
}
@@ -52,6 +57,11 @@ LLCamera::LLCamera(F32 vertical_fov_rads, F32 aspect_ratio, S32 view_height_in_p
mPlaneCount(6),
mFrustumCornerDist(0.f)
{
+ for (U32 i = 0; i < PLANE_MASK_NUM; i++)
+ {
+ mPlaneMask[i] = PLANE_MASK_NONE;
+ }
+
mAspect = llclamp(aspect_ratio, MIN_ASPECT_RATIO, MAX_ASPECT_RATIO);
mNearPlane = llclamp(near_plane, MIN_NEAR_PLANE, MAX_NEAR_PLANE);
if(far_plane < 0) far_plane = DEFAULT_FAR_PLANE;
@@ -87,14 +97,14 @@ F32 LLCamera::getMaxView() const
void LLCamera::setUserClipPlane(LLPlane& plane)
{
- mPlaneCount = 7;
- mAgentPlanes[6] = plane;
- mPlaneMask[6] = plane.calcPlaneMask();
+ mPlaneCount = AGENT_PLANE_USER_CLIP_NUM;
+ mAgentPlanes[AGENT_PLANE_USER_CLIP] = plane;
+ mPlaneMask[AGENT_PLANE_USER_CLIP] = plane.calcPlaneMask();
}
void LLCamera::disableUserClipPlane()
{
- mPlaneCount = 6;
+ mPlaneCount = AGENT_PLANE_NO_USER_CLIP_NUM;
}
void LLCamera::setView(F32 vertical_fov_rads)
@@ -161,31 +171,33 @@ size_t LLCamera::readFrustumFromBuffer(const char *buffer)
// ---------------- test methods ----------------
-S32 LLCamera::AABBInFrustum(const LLVector4a &center, const LLVector4a& radius)
+static const LLVector4a sFrustumScaler[] =
{
- static const LLVector4a scaler[] = {
- LLVector4a(-1,-1,-1),
- LLVector4a( 1,-1,-1),
- LLVector4a(-1, 1,-1),
- LLVector4a( 1, 1,-1),
- LLVector4a(-1,-1, 1),
- LLVector4a( 1,-1, 1),
- LLVector4a(-1, 1, 1),
- LLVector4a( 1, 1, 1)
- };
+ LLVector4a(-1,-1,-1),
+ LLVector4a( 1,-1,-1),
+ LLVector4a(-1, 1,-1),
+ LLVector4a( 1, 1,-1),
+ LLVector4a(-1,-1, 1),
+ LLVector4a( 1,-1, 1),
+ LLVector4a(-1, 1, 1),
+ LLVector4a( 1, 1, 1) // 8 entries
+};
+S32 LLCamera::AABBInFrustum(const LLVector4a &center, const LLVector4a& radius)
+{
U8 mask = 0;
bool result = false;
LLVector4a rscale, maxp, minp;
LLSimdScalar d;
- for (U32 i = 0; i < mPlaneCount; i++)
+ U32 max_planes = llmin(mPlaneCount, (U32) AGENT_PLANE_USER_CLIP_NUM); // mAgentPlanes[] size is 7
+ for (U32 i = 0; i < max_planes; i++)
{
mask = mPlaneMask[i];
- if (mask != 0xff)
+ if (mask < PLANE_MASK_NUM)
{
const LLPlane& p(mAgentPlanes[i]);
p.getAt<3>(d);
- rscale.setMul(radius, scaler[mask]);
+ rscale.setMul(radius, sFrustumScaler[mask]);
minp.setSub(center, rscale);
d = -d;
if (p.dot3(minp).getF32() > d)
@@ -207,29 +219,19 @@ S32 LLCamera::AABBInFrustum(const LLVector4a &center, const LLVector4a& radius)
S32 LLCamera::AABBInFrustumNoFarClip(const LLVector4a& center, const LLVector4a& radius)
{
- static const LLVector4a scaler[] = {
- LLVector4a(-1,-1,-1),
- LLVector4a( 1,-1,-1),
- LLVector4a(-1, 1,-1),
- LLVector4a( 1, 1,-1),
- LLVector4a(-1,-1, 1),
- LLVector4a( 1,-1, 1),
- LLVector4a(-1, 1, 1),
- LLVector4a( 1, 1, 1)
- };
-
U8 mask = 0;
bool result = false;
LLVector4a rscale, maxp, minp;
LLSimdScalar d;
- for (U32 i = 0; i < mPlaneCount; i++)
+ U32 max_planes = llmin(mPlaneCount, (U32) AGENT_PLANE_USER_CLIP_NUM); // mAgentPlanes[] size is 7
+ for (U32 i = 0; i < max_planes; i++)
{
mask = mPlaneMask[i];
- if ((i != 5) && (mask != 0xff))
+ if ((i != 5) && (mask < PLANE_MASK_NUM))
{
const LLPlane& p(mAgentPlanes[i]);
p.getAt<3>(d);
- rscale.setMul(radius, scaler[mask]);
+ rscale.setMul(radius, sFrustumScaler[mask]);
minp.setSub(center, rscale);
d = -d;
if (p.dot3(minp).getF32() > d)
@@ -369,7 +371,7 @@ int LLCamera::sphereInFrustum(const LLVector3 &sphere_center, const F32 radius)
bool res = false;
for (int i = 0; i < 6; i++)
{
- if (mPlaneMask[i] != 0xff)
+ if (mPlaneMask[i] != PLANE_MASK_NONE)
{
float d = mAgentPlanes[i].dist(sphere_center);
@@ -541,14 +543,14 @@ void LLCamera::ignoreAgentFrustumPlane(S32 idx)
return;
}
- mPlaneMask[idx] = 0xff;
+ mPlaneMask[idx] = PLANE_MASK_NONE;
mAgentPlanes[idx].clear();
}
void LLCamera::calcAgentFrustumPlanes(LLVector3* frust)
{
- for (int i = 0; i < 8; i++)
+ for (int i = 0; i < AGENT_FRUSTRUM_NUM; i++)
{
mAgentFrustum[i] = frust[i];
}
@@ -560,22 +562,22 @@ void LLCamera::calcAgentFrustumPlanes(LLVector3* frust)
//order of planes is important, keep most likely to fail in the front of the list
//near - frust[0], frust[1], frust[2]
- mAgentPlanes[2] = planeFromPoints(frust[0], frust[1], frust[2]);
+ mAgentPlanes[AGENT_PLANE_NEAR] = planeFromPoints(frust[0], frust[1], frust[2]);
//far
- mAgentPlanes[5] = planeFromPoints(frust[5], frust[4], frust[6]);
+ mAgentPlanes[AGENT_PLANE_FAR] = planeFromPoints(frust[5], frust[4], frust[6]);
//left
- mAgentPlanes[0] = planeFromPoints(frust[4], frust[0], frust[7]);
+ mAgentPlanes[AGENT_PLANE_LEFT] = planeFromPoints(frust[4], frust[0], frust[7]);
//right
- mAgentPlanes[1] = planeFromPoints(frust[1], frust[5], frust[6]);
+ mAgentPlanes[AGENT_PLANE_RIGHT] = planeFromPoints(frust[1], frust[5], frust[6]);
//top
- mAgentPlanes[4] = planeFromPoints(frust[3], frust[2], frust[6]);
+ mAgentPlanes[AGENT_PLANE_TOP] = planeFromPoints(frust[3], frust[2], frust[6]);
//bottom
- mAgentPlanes[3] = planeFromPoints(frust[1], frust[0], frust[4]);
+ mAgentPlanes[AGENT_PLANE_BOTTOM] = planeFromPoints(frust[1], frust[0], frust[4]);
//cache plane octant facing mask for use in AABBInFrustum
for (U32 i = 0; i < mPlaneCount; i++)
@@ -635,7 +637,7 @@ void LLCamera::calculateWorldFrustumPlanes()
LLVector3 center = mOrigin - mXAxis*mNearPlane;
mWorldPlanePos = center;
LLVector3 pnorm;
- for (int p=0; p<4; p++)
+ for (int p = 0; p < PLANE_NUM; p++)
{
mLocalPlanes[p].getVector3(pnorm);
LLVector3 norm = rotateToAbsolute(pnorm);
diff --git a/indra/llmath/llcamera.h b/indra/llmath/llcamera.h
index ec67b91d05..1283cfb16b 100644..100755
--- a/indra/llmath/llcamera.h
+++ b/indra/llmath/llcamera.h
@@ -60,7 +60,7 @@ static const F32 MAX_FIELD_OF_VIEW = 175.f * DEG_TO_RAD;
// roll(), pitch(), yaw()
// etc...
-
+LL_ALIGN_PREFIX(16)
class LLCamera
: public LLCoordFrame
{
@@ -76,26 +76,39 @@ public:
PLANE_RIGHT = 1,
PLANE_BOTTOM = 2,
PLANE_TOP = 3,
- PLANE_NUM = 4
+ PLANE_NUM = 4,
+ PLANE_MASK_NONE = 0xff // Disable this plane
};
enum {
PLANE_LEFT_MASK = (1<<PLANE_LEFT),
PLANE_RIGHT_MASK = (1<<PLANE_RIGHT),
PLANE_BOTTOM_MASK = (1<<PLANE_BOTTOM),
PLANE_TOP_MASK = (1<<PLANE_TOP),
- PLANE_ALL_MASK = 0xf
+ PLANE_ALL_MASK = 0xf,
};
enum
- {
+ { // Indexes to mAgentPlanes[] and mPlaneMask[]
AGENT_PLANE_LEFT = 0,
- AGENT_PLANE_RIGHT,
- AGENT_PLANE_NEAR,
- AGENT_PLANE_BOTTOM,
- AGENT_PLANE_TOP,
- AGENT_PLANE_FAR,
+ AGENT_PLANE_RIGHT = 1,
+ AGENT_PLANE_NEAR = 2,
+ AGENT_PLANE_BOTTOM = 3,
+ AGENT_PLANE_TOP = 4,
+ AGENT_PLANE_FAR = 5,
+ AGENT_PLANE_USER_CLIP = 6
+ };
+ enum
+ { // Sizes for mAgentPlanes[]. 7th entry is special case for user clip
+ AGENT_PLANE_NO_USER_CLIP_NUM = 6,
+ AGENT_PLANE_USER_CLIP_NUM = 7,
+ PLANE_MASK_NUM = 8 // 7 actually used, 8 is for alignment
};
+ enum
+ {
+ AGENT_FRUSTRUM_NUM = 8
+ };
+
enum {
HORIZ_PLANE_LEFT = 0,
HORIZ_PLANE_RIGHT = 1,
@@ -108,27 +121,27 @@ public:
};
private:
- LLPlane mAgentPlanes[7]; //frustum planes in agent space a la gluUnproject (I'm a bastard, I know) - DaveP
- U8 mPlaneMask[8]; // 8 for alignment
+ LL_ALIGN_16(LLPlane mAgentPlanes[AGENT_PLANE_USER_CLIP_NUM]); //frustum planes in agent space a la gluUnproject (I'm a bastard, I know) - DaveP
+ U8 mPlaneMask[PLANE_MASK_NUM]; // 8 for alignment
F32 mView; // angle between top and bottom frustum planes in radians.
F32 mAspect; // width/height
S32 mViewHeightInPixels; // for ViewHeightInPixels() only
F32 mNearPlane;
F32 mFarPlane;
- LLPlane mLocalPlanes[4];
+ LL_ALIGN_16(LLPlane mLocalPlanes[PLANE_NUM]);
F32 mFixedDistance; // Always return this distance, unless < 0
LLVector3 mFrustCenter; // center of frustum and radius squared for ultra-quick exclusion test
F32 mFrustRadiusSquared;
- LLPlane mWorldPlanes[PLANE_NUM];
- LLPlane mHorizPlanes[HORIZ_PLANE_NUM];
+ LL_ALIGN_16(LLPlane mWorldPlanes[PLANE_NUM]);
+ LL_ALIGN_16(LLPlane mHorizPlanes[HORIZ_PLANE_NUM]);
U32 mPlaneCount; //defaults to 6, if setUserClipPlane is called, uses user supplied clip plane in
LLVector3 mWorldPlanePos; // Position of World Planes (may be offset from camera)
public:
- LLVector3 mAgentFrustum[8]; //8 corners of 6-plane frustum
+ LLVector3 mAgentFrustum[AGENT_FRUSTRUM_NUM]; //8 corners of 6-plane frustum
F32 mFrustumCornerDist; //distance to corner of frustum against far clip plane
LLPlane& getAgentPlane(U32 idx) { return mAgentPlanes[idx]; }
@@ -208,7 +221,7 @@ protected:
void calculateFrustumPlanes(F32 left, F32 right, F32 top, F32 bottom);
void calculateFrustumPlanesFromWindow(F32 x1, F32 y1, F32 x2, F32 y2);
void calculateWorldFrustumPlanes();
-};
+} LL_ALIGN_POSTFIX(16);
#endif
diff --git a/indra/llmath/llcoord.h b/indra/llmath/llcoord.h
index 9b76268afd..9b76268afd 100644..100755
--- a/indra/llmath/llcoord.h
+++ b/indra/llmath/llcoord.h
diff --git a/indra/llmath/llcoordframe.cpp b/indra/llmath/llcoordframe.cpp
index 7dd8e43185..7dd8e43185 100644..100755
--- a/indra/llmath/llcoordframe.cpp
+++ b/indra/llmath/llcoordframe.cpp
diff --git a/indra/llmath/llcoordframe.h b/indra/llmath/llcoordframe.h
index 909adf260c..909adf260c 100644..100755
--- a/indra/llmath/llcoordframe.h
+++ b/indra/llmath/llcoordframe.h
diff --git a/indra/llmath/llinterp.h b/indra/llmath/llinterp.h
index 5187646179..5187646179 100644..100755
--- a/indra/llmath/llinterp.h
+++ b/indra/llmath/llinterp.h
diff --git a/indra/llmath/llline.cpp b/indra/llmath/llline.cpp
index ef10d1e7fa..ef10d1e7fa 100644..100755
--- a/indra/llmath/llline.cpp
+++ b/indra/llmath/llline.cpp
diff --git a/indra/llmath/llline.h b/indra/llmath/llline.h
index e1cbc1323e..e1cbc1323e 100644..100755
--- a/indra/llmath/llline.h
+++ b/indra/llmath/llline.h
diff --git a/indra/llmath/llmath.h b/indra/llmath/llmath.h
index 9297bcbac2..b93f89d674 100644..100755
--- a/indra/llmath/llmath.h
+++ b/indra/llmath/llmath.h
@@ -85,7 +85,7 @@ const F32 F_ALMOST_ONE = 1.0f - F_ALMOST_ZERO;
const F32 FP_MAG_THRESHOLD = 0.0000001f;
// TODO: Replace with logic like is_approx_equal
-inline BOOL is_approx_zero( F32 f ) { return (-F_APPROXIMATELY_ZERO < f) && (f < F_APPROXIMATELY_ZERO); }
+inline bool is_approx_zero( F32 f ) { return (-F_APPROXIMATELY_ZERO < f) && (f < F_APPROXIMATELY_ZERO); }
// These functions work by interpreting sign+exp+mantissa as an unsigned
// integer.
@@ -111,13 +111,13 @@ inline BOOL is_approx_zero( F32 f ) { return (-F_APPROXIMATELY_ZERO < f) && (f <
// WARNING: Infinity is comparable with F32_MAX and negative
// infinity is comparable with F32_MIN
-inline BOOL is_approx_equal(F32 x, F32 y)
+inline bool is_approx_equal(F32 x, F32 y)
{
const S32 COMPARE_MANTISSA_UP_TO_BIT = 0x02;
return (std::abs((S32) ((U32&)x - (U32&)y) ) < COMPARE_MANTISSA_UP_TO_BIT);
}
-inline BOOL is_approx_equal(F64 x, F64 y)
+inline bool is_approx_equal(F64 x, F64 y)
{
const S64 COMPARE_MANTISSA_UP_TO_BIT = 0x02;
return (std::abs((S32) ((U64&)x - (U64&)y) ) < COMPARE_MANTISSA_UP_TO_BIT);
diff --git a/indra/llmath/llmatrix3a.cpp b/indra/llmath/llmatrix3a.cpp
index ab077abcb0..ab077abcb0 100644..100755
--- a/indra/llmath/llmatrix3a.cpp
+++ b/indra/llmath/llmatrix3a.cpp
diff --git a/indra/llmath/llmatrix3a.h b/indra/llmath/llmatrix3a.h
index adb7e3389d..9916cfd2da 100644..100755
--- a/indra/llmath/llmatrix3a.h
+++ b/indra/llmath/llmatrix3a.h
@@ -111,7 +111,7 @@ public:
protected:
- LLVector4a mColumns[3];
+ LL_ALIGN_16(LLVector4a mColumns[3]);
};
diff --git a/indra/llmath/llmatrix3a.inl b/indra/llmath/llmatrix3a.inl
index 37819fea3c..37819fea3c 100644..100755
--- a/indra/llmath/llmatrix3a.inl
+++ b/indra/llmath/llmatrix3a.inl
diff --git a/indra/llmath/llmatrix4a.h b/indra/llmath/llmatrix4a.h
index 27cf5b79f6..d141298f69 100644..100755
--- a/indra/llmath/llmatrix4a.h
+++ b/indra/llmath/llmatrix4a.h
@@ -34,7 +34,7 @@
class LLMatrix4a
{
public:
- LLVector4a mMatrix[4];
+ LL_ALIGN_16(LLVector4a mMatrix[4]);
inline void clear()
{
@@ -107,15 +107,14 @@ public:
inline void rotate(const LLVector4a& v, LLVector4a& res)
{
+ LLVector4a y,z;
+
res = _mm_shuffle_ps(v, v, _MM_SHUFFLE(0, 0, 0, 0));
- res.mul(mMatrix[0]);
-
- LLVector4a y;
y = _mm_shuffle_ps(v, v, _MM_SHUFFLE(1, 1, 1, 1));
- y.mul(mMatrix[1]);
-
- LLVector4a z;
z = _mm_shuffle_ps(v, v, _MM_SHUFFLE(2, 2, 2, 2));
+
+ res.mul(mMatrix[0]);
+ y.mul(mMatrix[1]);
z.mul(mMatrix[2]);
res.add(y);
diff --git a/indra/llmath/llmodularmath.cpp b/indra/llmath/llmodularmath.cpp
index cdc20028bf..cdc20028bf 100644..100755
--- a/indra/llmath/llmodularmath.cpp
+++ b/indra/llmath/llmodularmath.cpp
diff --git a/indra/llmath/llmodularmath.h b/indra/llmath/llmodularmath.h
index 0d4d28fadc..0d4d28fadc 100644..100755
--- a/indra/llmath/llmodularmath.h
+++ b/indra/llmath/llmodularmath.h
diff --git a/indra/llmath/lloctree.h b/indra/llmath/lloctree.h
index 1b11e83b4a..7348904c61 100644..100755
--- a/indra/llmath/lloctree.h
+++ b/indra/llmath/lloctree.h
@@ -31,7 +31,6 @@
#include "v3math.h"
#include "llvector4a.h"
#include <vector>
-#include <set>
#define OCT_ERRS LL_WARNS("OctreeErrors")
@@ -79,16 +78,18 @@ public:
typedef LLOctreeTraveler<T> oct_traveler;
typedef LLTreeTraveler<T> tree_traveler;
- typedef typename std::set<LLPointer<T> > element_list;
- typedef typename element_list::iterator element_iter;
- typedef typename element_list::const_iterator const_element_iter;
+ typedef std::vector< LLPointer<T> > element_list; // note: don't remove the whitespace between "> >"
+ typedef LLPointer<T>* element_iter;
+ typedef const LLPointer<T>* const_element_iter;
typedef typename std::vector<LLTreeListener<T>*>::iterator tree_listener_iter;
- typedef typename std::vector<LLOctreeNode<T>* > child_list;
+ typedef LLOctreeNode<T>** child_list;
+ typedef LLOctreeNode<T>** child_iter;
+
typedef LLTreeNode<T> BaseType;
typedef LLOctreeNode<T> oct_node;
typedef LLOctreeListener<T> oct_listener;
- /*void* operator new(size_t size)
+ void* operator new(size_t size)
{
return ll_aligned_malloc_16(size);
}
@@ -96,7 +97,7 @@ public:
void operator delete(void* ptr)
{
ll_aligned_free_16(ptr);
- }*/
+ }
LLOctreeNode( const LLVector4a& center,
const LLVector4a& size,
@@ -105,6 +106,10 @@ public:
: mParent((oct_node*)parent),
mOctant(octant)
{
+ //always keep a NULL terminated list to avoid out of bounds exceptions in debug builds
+ mData.push_back(NULL);
+ mDataEnd = &mData[0];
+
mCenter = center;
mSize = size;
@@ -123,6 +128,16 @@ public:
{
BaseType::destroyListeners();
+ for (U32 i = 0; i < mElementCount; ++i)
+ {
+ mData[i]->setBinIndex(-1);
+ mData[i] = NULL;
+ }
+
+ mData.clear();
+ mData.push_back(NULL);
+ mDataEnd = &mData[0];
+
for (U32 i = 0; i < getChildCount(); i++)
{
delete getChild(i);
@@ -219,12 +234,17 @@ public:
}
void accept(oct_traveler* visitor) { visitor->visit(this); }
- virtual bool isLeaf() const { return mChild.empty(); }
+ virtual bool isLeaf() const { return mChildCount == 0; }
U32 getElementCount() const { return mElementCount; }
+ bool isEmpty() const { return mElementCount == 0; }
element_list& getData() { return mData; }
const element_list& getData() const { return mData; }
-
+ element_iter getDataBegin() { return &mData[0]; }
+ element_iter getDataEnd() { return mDataEnd; }
+ const_element_iter getDataBegin() const { return &mData[0]; }
+ const_element_iter getDataEnd() const { return mDataEnd; }
+
U32 getChildCount() const { return mChildCount; }
oct_node* getChild(U32 index) { return mChild[index]; }
const oct_node* getChild(U32 index) const { return mChild[index]; }
@@ -289,7 +309,7 @@ public:
virtual bool insert(T* data)
{
- if (data == NULL)
+ if (data == NULL || data->getBinIndex() != -1)
{
OCT_ERRS << "!!! INVALID ELEMENT ADDED TO OCTREE BRANCH !!!" << llendl;
return false;
@@ -302,13 +322,12 @@ public:
if ((getElementCount() < gOctreeMaxCapacity && contains(data->getBinRadius()) ||
(data->getBinRadius() > getSize()[0] && parent && parent->getElementCount() >= gOctreeMaxCapacity)))
{ //it belongs here
- //if this is a redundant insertion, error out (should never happen)
- llassert(mData.find(data) == mData.end());
-
- mData.insert(data);
+ mData.push_back(NULL);
+ mData[mElementCount] = data;
+ mElementCount++;
+ mDataEnd = &mData[mElementCount];
+ data->setBinIndex(mElementCount-1);
BaseType::insert(data);
-
- mElementCount = mData.size();
return true;
}
else
@@ -342,10 +361,12 @@ public:
if( lt == 0x7 )
{
- mData.insert(data);
+ mData.push_back(NULL);
+ mData[mElementCount] = data;
+ mElementCount++;
+ mDataEnd = &mData[mElementCount];
+ data->setBinIndex(mElementCount-1);
BaseType::insert(data);
-
- mElementCount = mData.size();
return true;
}
@@ -394,23 +415,58 @@ public:
return false;
}
+ void _remove(T* data, S32 i)
+ { //precondition -- mElementCount > 0, idx is in range [0, mElementCount)
+
+ mElementCount--;
+ data->setBinIndex(-1);
+
+ if (mElementCount > 0)
+ {
+ if (mElementCount != i)
+ {
+ mData[i] = mData[mElementCount]; //might unref data, do not access data after this point
+ mData[i]->setBinIndex(i);
+ }
+
+ mData[mElementCount] = NULL;
+ mData.pop_back();
+ mDataEnd = &mData[mElementCount];
+ }
+ else
+ {
+ mData.clear();
+ mData.push_back(NULL);
+ mDataEnd = &mData[0];
+ }
+
+ notifyRemoval(data);
+ checkAlive();
+ }
+
bool remove(T* data)
{
- if (mData.find(data) != mData.end())
- { //we have data
- mData.erase(data);
- mElementCount = mData.size();
- notifyRemoval(data);
- checkAlive();
- return true;
- }
- else if (isInside(data))
+ S32 i = data->getBinIndex();
+
+ if (i >= 0 && i < mElementCount)
+ {
+ if (mData[i] == data)
+ { //found it
+ _remove(data, i);
+ llassert(data->getBinIndex() == -1);
+ return true;
+ }
+ }
+
+ if (isInside(data))
{
oct_node* dest = getNodeAt(data);
if (dest != this)
{
- return dest->remove(data);
+ bool ret = dest->remove(data);
+ llassert(data->getBinIndex() == -1);
+ return ret;
}
}
@@ -427,21 +483,22 @@ public:
}
//node is now root
- llwarns << "!!! OCTREE REMOVING FACE BY ADDRESS, SEVERE PERFORMANCE PENALTY |||" << llendl;
+ llwarns << "!!! OCTREE REMOVING ELEMENT BY ADDRESS, SEVERE PERFORMANCE PENALTY |||" << llendl;
node->removeByAddress(data);
+ llassert(data->getBinIndex() == -1);
return true;
}
void removeByAddress(T* data)
{
- if (mData.find(data) != mData.end())
+ for (U32 i = 0; i < mElementCount; ++i)
{
- mData.erase(data);
- mElementCount = mData.size();
- notifyRemoval(data);
- llwarns << "FOUND!" << llendl;
- checkAlive();
- return;
+ if (mData[i] == data)
+ { //we have data
+ _remove(data, i);
+ llwarns << "FOUND!" << llendl;
+ return;
+ }
}
for (U32 i = 0; i < getChildCount(); i++)
@@ -453,8 +510,8 @@ public:
void clearChildren()
{
- mChild.clear();
mChildCount = 0;
+
U32* foo = (U32*) mChildMap;
foo[0] = foo[1] = 0xFFFFFFFF;
}
@@ -516,7 +573,7 @@ public:
mChildMap[child->getOctant()] = mChildCount;
- mChild.push_back(child);
+ mChild[mChildCount] = child;
++mChildCount;
child->setParent(this);
@@ -543,9 +600,12 @@ public:
mChild[index]->destroy();
delete mChild[index];
}
- mChild.erase(mChild.begin() + index);
+
--mChildCount;
+ mChild[index] = mChild[mChildCount];
+
+
//rebuild child map
U32* foo = (U32*) mChildMap;
foo[0] = foo[1] = 0xFFFFFFFF;
@@ -601,11 +661,12 @@ protected:
oct_node* mParent;
U8 mOctant;
- child_list mChild;
+ LLOctreeNode<T>* mChild[8];
U8 mChildMap[8];
U32 mChildCount;
element_list mData;
+ element_iter mDataEnd;
U32 mElementCount;
};
diff --git a/indra/llmath/llperlin.cpp b/indra/llmath/llperlin.cpp
index e1da2bf92b..e1da2bf92b 100644..100755
--- a/indra/llmath/llperlin.cpp
+++ b/indra/llmath/llperlin.cpp
diff --git a/indra/llmath/llperlin.h b/indra/llmath/llperlin.h
index 40cf19d1ec..40cf19d1ec 100644..100755
--- a/indra/llmath/llperlin.h
+++ b/indra/llmath/llperlin.h
diff --git a/indra/llmath/llplane.h b/indra/llmath/llplane.h
index a611894721..3c32441b11 100644..100755
--- a/indra/llmath/llplane.h
+++ b/indra/llmath/llplane.h
@@ -36,6 +36,8 @@
// The plane normal = [A, B, C]
// The closest approach = D / sqrt(A*A + B*B + C*C)
+
+LL_ALIGN_PREFIX(16)
class LLPlane
{
public:
@@ -94,7 +96,7 @@ public:
private:
LLVector4a mV;
-};
+} LL_ALIGN_POSTFIX(16);
diff --git a/indra/llmath/llquantize.h b/indra/llmath/llquantize.h
index 1595dbecf8..1595dbecf8 100644..100755
--- a/indra/llmath/llquantize.h
+++ b/indra/llmath/llquantize.h
diff --git a/indra/llmath/llquaternion.cpp b/indra/llmath/llquaternion.cpp
index 7381d5eb99..7381d5eb99 100644..100755
--- a/indra/llmath/llquaternion.cpp
+++ b/indra/llmath/llquaternion.cpp
diff --git a/indra/llmath/llquaternion.h b/indra/llmath/llquaternion.h
index ca0dfe206b..ca0dfe206b 100644..100755
--- a/indra/llmath/llquaternion.h
+++ b/indra/llmath/llquaternion.h
diff --git a/indra/llmath/llquaternion2.h b/indra/llmath/llquaternion2.h
index fd9c0cf3ab..fd9c0cf3ab 100644..100755
--- a/indra/llmath/llquaternion2.h
+++ b/indra/llmath/llquaternion2.h
diff --git a/indra/llmath/llquaternion2.inl b/indra/llmath/llquaternion2.inl
index 2a6987552d..2a6987552d 100644..100755
--- a/indra/llmath/llquaternion2.inl
+++ b/indra/llmath/llquaternion2.inl
diff --git a/indra/llmath/llrect.cpp b/indra/llmath/llrect.cpp
index 4083c99768..4083c99768 100644..100755
--- a/indra/llmath/llrect.cpp
+++ b/indra/llmath/llrect.cpp
diff --git a/indra/llmath/llrect.h b/indra/llmath/llrect.h
index c51e0e0ae6..c51e0e0ae6 100644..100755
--- a/indra/llmath/llrect.h
+++ b/indra/llmath/llrect.h
diff --git a/indra/llmath/llsdutil_math.cpp b/indra/llmath/llsdutil_math.cpp
index 591f7fde36..591f7fde36 100644..100755
--- a/indra/llmath/llsdutil_math.cpp
+++ b/indra/llmath/llsdutil_math.cpp
diff --git a/indra/llmath/llsdutil_math.h b/indra/llmath/llsdutil_math.h
index 0ea78cd231..0ea78cd231 100644..100755
--- a/indra/llmath/llsdutil_math.h
+++ b/indra/llmath/llsdutil_math.h
diff --git a/indra/llmath/llsimdmath.h b/indra/llmath/llsimdmath.h
index c7cdf7b32c..cebd2ace7d 100644..100755
--- a/indra/llmath/llsimdmath.h
+++ b/indra/llmath/llsimdmath.h
@@ -39,39 +39,10 @@
#include <stdint.h>
#endif
-template <typename T> T* LL_NEXT_ALIGNED_ADDRESS(T* address)
-{
- return reinterpret_cast<T*>(
- (reinterpret_cast<uintptr_t>(address) + 0xF) & ~0xF);
-}
-
-template <typename T> T* LL_NEXT_ALIGNED_ADDRESS_64(T* address)
-{
- return reinterpret_cast<T*>(
- (reinterpret_cast<uintptr_t>(address) + 0x3F) & ~0x3F);
-}
-
-#if LL_LINUX || LL_DARWIN
-
-#define LL_ALIGN_PREFIX(x)
-#define LL_ALIGN_POSTFIX(x) __attribute__((aligned(x)))
-
-#elif LL_WINDOWS
-
-#define LL_ALIGN_PREFIX(x) __declspec(align(x))
-#define LL_ALIGN_POSTFIX(x)
-
-#else
-#error "LL_ALIGN_PREFIX and LL_ALIGN_POSTFIX undefined"
-#endif
-
-#define LL_ALIGN_16(var) LL_ALIGN_PREFIX(16) var LL_ALIGN_POSTFIX(16)
-
-
-
#include <xmmintrin.h>
#include <emmintrin.h>
+#include "llmemory.h"
#include "llsimdtypes.h"
#include "llsimdtypes.inl"
diff --git a/indra/llmath/llsimdtypes.h b/indra/llmath/llsimdtypes.h
index bd991d0e71..bd991d0e71 100644..100755
--- a/indra/llmath/llsimdtypes.h
+++ b/indra/llmath/llsimdtypes.h
diff --git a/indra/llmath/llsimdtypes.inl b/indra/llmath/llsimdtypes.inl
index 712239e425..e905c84954 100644..100755
--- a/indra/llmath/llsimdtypes.inl
+++ b/indra/llmath/llsimdtypes.inl
@@ -62,6 +62,7 @@ inline LLSimdScalar operator/(const LLSimdScalar& a, const LLSimdScalar& b)
inline LLSimdScalar operator-(const LLSimdScalar& a)
{
static LL_ALIGN_16(const U32 signMask[4]) = {0x80000000, 0x80000000, 0x80000000, 0x80000000 };
+ ll_assert_aligned(signMask,16);
return _mm_xor_ps(*reinterpret_cast<const LLQuad*>(signMask), a);
}
@@ -146,6 +147,7 @@ inline LLSimdScalar& LLSimdScalar::operator/=(const LLSimdScalar& rhs)
inline LLSimdScalar LLSimdScalar::getAbs() const
{
static const LL_ALIGN_16(U32 F_ABS_MASK_4A[4]) = { 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF };
+ ll_assert_aligned(F_ABS_MASK_4A,16);
return _mm_and_ps( mQ, *reinterpret_cast<const LLQuad*>(F_ABS_MASK_4A));
}
diff --git a/indra/llmath/llsphere.cpp b/indra/llmath/llsphere.cpp
index 740047b93a..740047b93a 100644..100755
--- a/indra/llmath/llsphere.cpp
+++ b/indra/llmath/llsphere.cpp
diff --git a/indra/llmath/llsphere.h b/indra/llmath/llsphere.h
index 7c60a11406..7c60a11406 100644..100755
--- a/indra/llmath/llsphere.h
+++ b/indra/llmath/llsphere.h
diff --git a/indra/llmath/lltreenode.h b/indra/llmath/lltreenode.h
index c66bc26176..c66bc26176 100644..100755
--- a/indra/llmath/lltreenode.h
+++ b/indra/llmath/lltreenode.h
diff --git a/indra/llmath/llvector4a.cpp b/indra/llmath/llvector4a.cpp
index b66b7a7076..570fa41a43 100644..100755
--- a/indra/llmath/llvector4a.cpp
+++ b/indra/llmath/llvector4a.cpp
@@ -24,6 +24,7 @@
* $/LicenseInfo$
*/
+#include "llmemory.h"
#include "llmath.h"
#include "llquantize.h"
@@ -40,52 +41,7 @@ extern const LLVector4a LL_V4A_EPSILON = reinterpret_cast<const LLVector4a&> ( F
/*static */void LLVector4a::memcpyNonAliased16(F32* __restrict dst, const F32* __restrict src, size_t bytes)
{
- assert(src != NULL);
- assert(dst != NULL);
- assert(bytes > 0);
- assert((bytes % sizeof(F32))== 0);
-
- F32* end = dst + (bytes / sizeof(F32) );
-
- if (bytes > 64)
- {
- F32* begin_64 = LL_NEXT_ALIGNED_ADDRESS_64(dst);
-
- //at least 64 (16*4) bytes before the end of the destination, switch to 16 byte copies
- F32* end_64 = end-16;
-
- _mm_prefetch((char*)begin_64, _MM_HINT_NTA);
- _mm_prefetch((char*)begin_64 + 64, _MM_HINT_NTA);
- _mm_prefetch((char*)begin_64 + 128, _MM_HINT_NTA);
- _mm_prefetch((char*)begin_64 + 192, _MM_HINT_NTA);
-
- while (dst < begin_64)
- {
- copy4a(dst, src);
- dst += 4;
- src += 4;
- }
-
- while (dst < end_64)
- {
- _mm_prefetch((char*)src + 512, _MM_HINT_NTA);
- _mm_prefetch((char*)dst + 512, _MM_HINT_NTA);
- copy4a(dst, src);
- copy4a(dst+4, src+4);
- copy4a(dst+8, src+8);
- copy4a(dst+12, src+12);
-
- dst += 16;
- src += 16;
- }
- }
-
- while (dst < end)
- {
- copy4a(dst, src);
- dst += 4;
- src += 4;
- }
+ ll_memcpy_nonaliased_aligned_16((char*)dst, (char*)src, bytes);
}
void LLVector4a::setRotated( const LLRotation& rot, const LLVector4a& vec )
@@ -189,6 +145,8 @@ void LLVector4a::quantize16( const LLVector4a& low, const LLVector4a& high )
LLVector4a oneOverDelta;
{
static LL_ALIGN_16( const F32 F_TWO_4A[4] ) = { 2.f, 2.f, 2.f, 2.f };
+ ll_assert_aligned(F_TWO_4A,16);
+
LLVector4a two; two.load4a( F_TWO_4A );
// Here we use _mm_rcp_ps plus one round of newton-raphson
diff --git a/indra/llmath/llvector4a.h b/indra/llmath/llvector4a.h
index 596082509d..79d0a44551 100644..100755
--- a/indra/llmath/llvector4a.h
+++ b/indra/llmath/llvector4a.h
@@ -32,6 +32,7 @@ class LLRotation;
#include <assert.h>
#include "llpreprocessor.h"
+#include "llmemory.h"
///////////////////////////////////
// FIRST TIME USERS PLEASE READ
@@ -45,7 +46,9 @@ class LLRotation;
// of this writing, July 08, 2010) about getting it implemented before you resort to
// LLVector3/LLVector4.
/////////////////////////////////
+class LLVector4a;
+LL_ALIGN_PREFIX(16)
class LLVector4a
{
public:
@@ -82,6 +85,7 @@ public:
}
// Copy words 16-byte blocks from src to dst. Source and destination must not overlap.
+ // Source and dest must be 16-byte aligned and size must be multiple of 16.
static void memcpyNonAliased16(F32* __restrict dst, const F32* __restrict src, size_t bytes);
////////////////////////////////////
@@ -90,6 +94,7 @@ public:
LLVector4a()
{ //DO NOT INITIALIZE -- The overhead is completely unnecessary
+ ll_assert_aligned(this,16);
}
LLVector4a(F32 x, F32 y, F32 z, F32 w = 0.f)
@@ -232,6 +237,11 @@ public:
// Note that this does not consider zero length vectors!
inline void normalize3fast();
+ // Normalize this vector with respect to the x, y, and z components only. Accurate only to 10-12 bits of precision. W component is destroyed
+ // Same as above except substitutes default vector contents if the vector is non-finite or degenerate due to zero length.
+ //
+ inline void normalize3fast_checked(LLVector4a* d = 0);
+
// Return true if this vector is normalized with respect to x,y,z up to tolerance
inline LLBool32 isNormalized3( F32 tolerance = 1e-3 ) const;
@@ -313,7 +323,7 @@ public:
private:
LLQuad mQ;
-};
+} LL_ALIGN_POSTFIX(16);
inline void update_min_max(LLVector4a& min, LLVector4a& max, const LLVector4a& p)
{
diff --git a/indra/llmath/llvector4a.inl b/indra/llmath/llvector4a.inl
index 7ad22a5631..69d3d01efe 100644..100755
--- a/indra/llmath/llvector4a.inl
+++ b/indra/llmath/llvector4a.inl
@@ -409,6 +409,26 @@ inline void LLVector4a::normalize3fast()
mQ = _mm_mul_ps( mQ, approxRsqrt );
}
+inline void LLVector4a::normalize3fast_checked(LLVector4a* d)
+{
+ if (!isFinite3())
+ {
+ *this = d ? *d : LLVector4a(0,1,0,1);
+ return;
+ }
+
+ LLVector4a lenSqrd; lenSqrd.setAllDot3( *this, *this );
+
+ if (lenSqrd.getF32ptr()[0] <= FLT_EPSILON)
+ {
+ *this = d ? *d : LLVector4a(0,1,0,1);
+ return;
+ }
+
+ const LLQuad approxRsqrt = _mm_rsqrt_ps(lenSqrd.mQ);
+ mQ = _mm_mul_ps( mQ, approxRsqrt );
+}
+
// Return true if this vector is normalized with respect to x,y,z up to tolerance
inline LLBool32 LLVector4a::isNormalized3( F32 tolerance ) const
{
@@ -460,21 +480,19 @@ inline void LLVector4a::setMax(const LLVector4a& lhs, const LLVector4a& rhs)
mQ = _mm_max_ps(lhs.mQ, rhs.mQ);
}
-// Set this to (c * lhs) + rhs * ( 1 - c)
+// Set this to lhs + (rhs-lhs)*c
inline void LLVector4a::setLerp(const LLVector4a& lhs, const LLVector4a& rhs, F32 c)
{
- LLVector4a a = lhs;
- a.mul(c);
-
- LLVector4a b = rhs;
- b.mul(1.f-c);
-
- setAdd(a, b);
+ LLVector4a t;
+ t.setSub(rhs,lhs);
+ t.mul(c);
+ setAdd(lhs, t);
}
inline LLBool32 LLVector4a::isFinite3() const
{
static LL_ALIGN_16(const U32 nanOrInfMask[4]) = { 0x7f800000, 0x7f800000, 0x7f800000, 0x7f800000 };
+ ll_assert_aligned(nanOrInfMask,16);
const __m128i nanOrInfMaskV = *reinterpret_cast<const __m128i*> (nanOrInfMask);
const __m128i maskResult = _mm_and_si128( _mm_castps_si128(mQ), nanOrInfMaskV );
const LLVector4Logical equalityCheck = _mm_castsi128_ps(_mm_cmpeq_epi32( maskResult, nanOrInfMaskV ));
diff --git a/indra/llmath/llvector4logical.h b/indra/llmath/llvector4logical.h
index dd66b09d43..c5698f7cea 100644..100755
--- a/indra/llmath/llvector4logical.h
+++ b/indra/llmath/llvector4logical.h
@@ -27,6 +27,7 @@
#ifndef LL_VECTOR4LOGICAL_H
#define LL_VECTOR4LOGICAL_H
+#include "llmemory.h"
////////////////////////////
// LLVector4Logical
@@ -77,6 +78,7 @@ public:
inline LLVector4Logical& invert()
{
static const LL_ALIGN_16(U32 allOnes[4]) = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
+ ll_assert_aligned(allOnes,16);
mQ = _mm_andnot_ps( mQ, *(LLQuad*)(allOnes) );
return *this;
}
diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp
index cc9744756f..f74c934b21 100644..100755
--- a/indra/llmath/llvolume.cpp
+++ b/indra/llmath/llvolume.cpp
@@ -35,7 +35,6 @@
#include <cmath>
#include "llerror.h"
-#include "llmemtype.h"
#include "llvolumemgr.h"
#include "v2math.h"
@@ -95,17 +94,6 @@ const S32 SCULPT_MIN_AREA_DETAIL = 1;
extern BOOL gDebugGL;
-void assert_aligned(void* ptr, uintptr_t alignment)
-{
-#if 0
- uintptr_t t = (uintptr_t) ptr;
- if (t%alignment != 0)
- {
- llerrs << "Alignment check failed." << llendl;
- }
-#endif
-}
-
BOOL check_same_clock_dir( const LLVector3& pt1, const LLVector3& pt2, const LLVector3& pt3, const LLVector3& norm)
{
LLVector3 test = (pt2-pt1)%(pt3-pt2);
@@ -148,6 +136,83 @@ BOOL LLLineSegmentBoxIntersect(const F32* start, const F32* end, const F32* cent
return true;
}
+// Finds tangent vec based on three vertices with texture coordinates.
+// Fills in dummy values if the triangle has degenerate texture coordinates.
+void calc_tangent_from_triangle(
+ LLVector4a& normal,
+ LLVector4a& tangent_out,
+ const LLVector4a& v1,
+ const LLVector2& w1,
+ const LLVector4a& v2,
+ const LLVector2& w2,
+ const LLVector4a& v3,
+ const LLVector2& w3)
+{
+ const F32* v1ptr = v1.getF32ptr();
+ const F32* v2ptr = v2.getF32ptr();
+ const F32* v3ptr = v3.getF32ptr();
+
+ float x1 = v2ptr[0] - v1ptr[0];
+ float x2 = v3ptr[0] - v1ptr[0];
+ float y1 = v2ptr[1] - v1ptr[1];
+ float y2 = v3ptr[1] - v1ptr[1];
+ float z1 = v2ptr[2] - v1ptr[2];
+ float z2 = v3ptr[2] - v1ptr[2];
+
+ float s1 = w2.mV[0] - w1.mV[0];
+ float s2 = w3.mV[0] - w1.mV[0];
+ float t1 = w2.mV[1] - w1.mV[1];
+ float t2 = w3.mV[1] - w1.mV[1];
+
+ F32 rd = s1*t2-s2*t1;
+
+ float r = ((rd*rd) > FLT_EPSILON) ? (1.0f / rd)
+ : ((rd > 0.0f) ? 1024.f : -1024.f); //some made up large ratio for division by zero
+
+ llassert(llfinite(r));
+ llassert(!llisnan(r));
+
+ LLVector4a sdir(
+ (t2 * x1 - t1 * x2) * r,
+ (t2 * y1 - t1 * y2) * r,
+ (t2 * z1 - t1 * z2) * r);
+
+ LLVector4a tdir(
+ (s1 * x2 - s2 * x1) * r,
+ (s1 * y2 - s2 * y1) * r,
+ (s1 * z2 - s2 * z1) * r);
+
+ LLVector4a n = normal;
+ LLVector4a t = sdir;
+
+ LLVector4a ncrosst;
+ ncrosst.setCross3(n,t);
+
+ // Gram-Schmidt orthogonalize
+ n.mul(n.dot3(t).getF32());
+
+ LLVector4a tsubn;
+ tsubn.setSub(t,n);
+
+ if (tsubn.dot3(tsubn).getF32() > F_APPROXIMATELY_ZERO)
+ {
+ tsubn.normalize3fast_checked();
+
+ // Calculate handedness
+ F32 handedness = ncrosst.dot3(tdir).getF32() < 0.f ? -1.f : 1.f;
+
+ tsubn.getF32ptr()[3] = handedness;
+
+ tangent_out = tsubn;
+ }
+ else
+ {
+ // degenerate, make up a value
+ //
+ tangent_out.set(0,0,1,1);
+ }
+
+}
// intersect test between triangle vert0, vert1, vert2 and a ray from orig in direction dir.
@@ -328,16 +393,16 @@ public:
LLVector4a& min = node->mExtents[0];
LLVector4a& max = node->mExtents[1];
- if (!branch->getData().empty())
+ if (!branch->isEmpty())
{ //node has data, find AABB that binds data set
- const LLVolumeTriangle* tri = *(branch->getData().begin());
+ const LLVolumeTriangle* tri = *(branch->getDataBegin());
//initialize min/max to first available vertex
min = *(tri->mV[0]);
max = *(tri->mV[0]);
for (LLOctreeNode<LLVolumeTriangle>::const_element_iter iter =
- branch->getData().begin(); iter != branch->getData().end(); ++iter)
+ branch->getDataBegin(); iter != branch->getDataEnd(); ++iter)
{ //for each triangle in node
//stretch by triangles in node
@@ -352,7 +417,7 @@ public:
max.setMax(max, *tri->mV[2]);
}
}
- else if (!branch->getChildren().empty())
+ else if (!branch->isLeaf())
{ //no data, but child nodes exist
LLVolumeOctreeListener* child = (LLVolumeOctreeListener*) branch->getChild(0)->getListener(0);
@@ -389,8 +454,6 @@ public:
LLProfile::Face* LLProfile::addCap(S16 faceID)
{
- LLMemType m1(LLMemType::MTYPE_VOLUME);
-
Face *face = vector_append(mFaces, 1);
face->mIndex = 0;
@@ -403,8 +466,6 @@ LLProfile::Face* LLProfile::addCap(S16 faceID)
LLProfile::Face* LLProfile::addFace(S32 i, S32 count, F32 scaleU, S16 faceID, BOOL flat)
{
- LLMemType m1(LLMemType::MTYPE_VOLUME);
-
Face *face = vector_append(mFaces, 1);
face->mIndex = i;
@@ -420,7 +481,6 @@ LLProfile::Face* LLProfile::addFace(S32 i, S32 count, F32 scaleU, S16 faceID, BO
//static
S32 LLProfile::getNumNGonPoints(const LLProfileParams& params, S32 sides, F32 offset, F32 bevel, F32 ang_scale, S32 split)
{ // this is basically LLProfile::genNGon stripped down to only the operations that influence the number of points
- LLMemType m1(LLMemType::MTYPE_VOLUME);
S32 np = 0;
// Generate an n-sided "circular" path.
@@ -486,14 +546,12 @@ S32 LLProfile::getNumNGonPoints(const LLProfileParams& params, S32 sides, F32 of
// filleted and chamfered corners
void LLProfile::genNGon(const LLProfileParams& params, S32 sides, F32 offset, F32 bevel, F32 ang_scale, S32 split)
{
- LLMemType m1(LLMemType::MTYPE_VOLUME);
-
// Generate an n-sided "circular" path.
// 0 is (1,0), and we go counter-clockwise along a circular path from there.
const F32 tableScale[] = { 1, 1, 1, 0.5f, 0.707107f, 0.53f, 0.525f, 0.5f };
F32 scale = 0.5f;
F32 t, t_step, t_first, t_fraction, ang, ang_step;
- LLVector3 pt1,pt2;
+ LLVector4a pt1,pt2;
F32 begin = params.getBegin();
F32 end = params.getEnd();
@@ -516,20 +574,21 @@ void LLProfile::genNGon(const LLProfileParams& params, S32 sides, F32 offset, F3
// Starting t and ang values for the first face
t = t_first;
ang = 2.0f*F_PI*(t*ang_scale + offset);
- pt1.setVec(cos(ang)*scale,sin(ang)*scale, t);
+ pt1.set(cos(ang)*scale,sin(ang)*scale, t);
// Increment to the next point.
// pt2 is the end point on the fractional face
t += t_step;
ang += ang_step;
- pt2.setVec(cos(ang)*scale,sin(ang)*scale,t);
+ pt2.set(cos(ang)*scale,sin(ang)*scale,t);
t_fraction = (begin - t_first)*sides;
// Only use if it's not almost exactly on an edge.
if (t_fraction < 0.9999f)
{
- LLVector3 new_pt = lerp(pt1, pt2, t_fraction);
+ LLVector4a new_pt;
+ new_pt.setLerp(pt1, pt2, t_fraction);
mProfile.push_back(new_pt);
}
@@ -537,12 +596,17 @@ void LLProfile::genNGon(const LLProfileParams& params, S32 sides, F32 offset, F3
while (t < end)
{
// Iterate through all the integer steps of t.
- pt1.setVec(cos(ang)*scale,sin(ang)*scale,t);
+ pt1.set(cos(ang)*scale,sin(ang)*scale,t);
if (mProfile.size() > 0) {
- LLVector3 p = mProfile[mProfile.size()-1];
+ LLVector4a p = mProfile[mProfile.size()-1];
for (S32 i = 0; i < split && mProfile.size() > 0; i++) {
- mProfile.push_back(p+(pt1-p) * 1.0f/(float)(split+1) * (float)(i+1));
+ //mProfile.push_back(p+(pt1-p) * 1.0f/(float)(split+1) * (float)(i+1));
+ LLVector4a new_pt;
+ new_pt.setSub(pt1, p);
+ new_pt.mul(1.0f/(float)(split+1) * (float)(i+1));
+ new_pt.add(p);
+ mProfile.push_back(new_pt);
}
}
mProfile.push_back(pt1);
@@ -555,18 +619,25 @@ void LLProfile::genNGon(const LLProfileParams& params, S32 sides, F32 offset, F3
// pt1 is the first point on the fractional face
// pt2 is the end point on the fractional face
- pt2.setVec(cos(ang)*scale,sin(ang)*scale,t);
+ pt2.set(cos(ang)*scale,sin(ang)*scale,t);
// Find the fraction that we need to add to the end point.
t_fraction = (end - (t - t_step))*sides;
if (t_fraction > 0.0001f)
{
- LLVector3 new_pt = lerp(pt1, pt2, t_fraction);
+ LLVector4a new_pt;
+ new_pt.setLerp(pt1, pt2, t_fraction);
if (mProfile.size() > 0) {
- LLVector3 p = mProfile[mProfile.size()-1];
+ LLVector4a p = mProfile[mProfile.size()-1];
for (S32 i = 0; i < split && mProfile.size() > 0; i++) {
- mProfile.push_back(p+(new_pt-p) * 1.0f/(float)(split+1) * (float)(i+1));
+ //mProfile.push_back(p+(new_pt-p) * 1.0f/(float)(split+1) * (float)(i+1));
+
+ LLVector4a pt1;
+ pt1.setSub(new_pt, p);
+ pt1.mul(1.0f/(float)(split+1) * (float)(i+1));
+ pt1.add(p);
+ mProfile.push_back(pt1);
}
}
mProfile.push_back(new_pt);
@@ -587,7 +658,7 @@ void LLProfile::genNGon(const LLProfileParams& params, S32 sides, F32 offset, F3
if (params.getHollow() <= 0)
{
// put center point if not hollow.
- mProfile.push_back(LLVector3(0,0,0));
+ mProfile.push_back(LLVector4a(0,0,0));
}
}
else
@@ -600,103 +671,6 @@ void LLProfile::genNGon(const LLProfileParams& params, S32 sides, F32 offset, F3
mTotal = mProfile.size();
}
-void LLProfile::genNormals(const LLProfileParams& params)
-{
- S32 count = mProfile.size();
-
- S32 outer_count;
- if (mTotalOut)
- {
- outer_count = mTotalOut;
- }
- else
- {
- outer_count = mTotal / 2;
- }
-
- mEdgeNormals.resize(count * 2);
- mEdgeCenters.resize(count * 2);
- mNormals.resize(count);
-
- LLVector2 pt0,pt1;
-
- BOOL hollow = (params.getHollow() > 0);
-
- S32 i0, i1, i2, i3, i4;
-
- // Parametrically generate normal
- for (i2 = 0; i2 < count; i2++)
- {
- mNormals[i2].mV[0] = mProfile[i2].mV[0];
- mNormals[i2].mV[1] = mProfile[i2].mV[1];
- if (hollow && (i2 >= outer_count))
- {
- mNormals[i2] *= -1.f;
- }
- if (mNormals[i2].magVec() < 0.001)
- {
- // Special case for point at center, get adjacent points.
- i1 = (i2 - 1) >= 0 ? i2 - 1 : count - 1;
- i0 = (i1 - 1) >= 0 ? i1 - 1 : count - 1;
- i3 = (i2 + 1) < count ? i2 + 1 : 0;
- i4 = (i3 + 1) < count ? i3 + 1 : 0;
-
- pt0.setVec(mProfile[i1].mV[VX] + mProfile[i1].mV[VX] - mProfile[i0].mV[VX],
- mProfile[i1].mV[VY] + mProfile[i1].mV[VY] - mProfile[i0].mV[VY]);
- pt1.setVec(mProfile[i3].mV[VX] + mProfile[i3].mV[VX] - mProfile[i4].mV[VX],
- mProfile[i3].mV[VY] + mProfile[i3].mV[VY] - mProfile[i4].mV[VY]);
-
- mNormals[i2] = pt0 + pt1;
- mNormals[i2] *= 0.5f;
- }
- mNormals[i2].normVec();
- }
-
- S32 num_normal_sets = isConcave() ? 2 : 1;
- for (S32 normal_set = 0; normal_set < num_normal_sets; normal_set++)
- {
- S32 point_num;
- for (point_num = 0; point_num < mTotal; point_num++)
- {
- LLVector3 point_1 = mProfile[point_num];
- point_1.mV[VZ] = 0.f;
-
- LLVector3 point_2;
-
- if (isConcave() && normal_set == 0 && point_num == (mTotal - 1) / 2)
- {
- point_2 = mProfile[mTotal - 1];
- }
- else if (isConcave() && normal_set == 1 && point_num == mTotal - 1)
- {
- point_2 = mProfile[(mTotal - 1) / 2];
- }
- else
- {
- LLVector3 delta_pos;
- S32 neighbor_point = (point_num + 1) % mTotal;
- while(delta_pos.magVecSquared() < 0.01f * 0.01f)
- {
- point_2 = mProfile[neighbor_point];
- delta_pos = point_2 - point_1;
- neighbor_point = (neighbor_point + 1) % mTotal;
- if (neighbor_point == point_num)
- {
- break;
- }
- }
- }
-
- point_2.mV[VZ] = 0.f;
- LLVector3 face_normal = (point_2 - point_1) % LLVector3::z_axis;
- face_normal.normVec();
- mEdgeNormals[normal_set * count + point_num] = face_normal;
- mEdgeCenters[normal_set * count + point_num] = lerp(point_1, point_2, 0.5f);
- }
- }
-}
-
-
// Hollow is percent of the original bounding box, not of this particular
// profile's geometry. Thus, a swept triangle needs lower hollow values than
// a swept square.
@@ -712,12 +686,13 @@ LLProfile::Face* LLProfile::addHole(const LLProfileParams& params, BOOL flat, F3
Face *face = addFace(mTotalOut, mTotal-mTotalOut,0,LL_FACE_INNER_SIDE, flat);
- std::vector<LLVector3> pt;
+ static LLAlignedArray<LLVector4a,64> pt;
pt.resize(mTotal) ;
for (S32 i=mTotalOut;i<mTotal;i++)
{
- pt[i] = mProfile[i] * box_hollow;
+ pt[i] = mProfile[i];
+ pt[i].mul(box_hollow);
}
S32 j=mTotal-1;
@@ -741,8 +716,6 @@ LLProfile::Face* LLProfile::addHole(const LLProfileParams& params, BOOL flat, F3
S32 LLProfile::getNumPoints(const LLProfileParams& params, BOOL path_open,F32 detail, S32 split,
BOOL is_sculpted, S32 sculpt_size)
{ // this is basically LLProfile::generate stripped down to only operations that influence the number of points
- LLMemType m1(LLMemType::MTYPE_VOLUME);
-
if (detail < MIN_LOD)
{
detail = MIN_LOD;
@@ -853,8 +826,6 @@ S32 LLProfile::getNumPoints(const LLProfileParams& params, BOOL path_open,F32 de
BOOL LLProfile::generate(const LLProfileParams& params, BOOL path_open,F32 detail, S32 split,
BOOL is_sculpted, S32 sculpt_size)
{
- LLMemType m1(LLMemType::MTYPE_VOLUME);
-
if ((!mDirty) && (!is_sculpted))
{
return FALSE;
@@ -867,8 +838,8 @@ BOOL LLProfile::generate(const LLProfileParams& params, BOOL path_open,F32 detai
detail = MIN_LOD;
}
- mProfile.clear();
- mFaces.clear();
+ mProfile.resize(0);
+ mFaces.resize(0);
// Generate the face data
S32 i;
@@ -900,10 +871,13 @@ BOOL LLProfile::generate(const LLProfileParams& params, BOOL path_open,F32 detai
addFace((face_num++) * (split +1), split+2, 1, LL_FACE_OUTER_SIDE_0 << i, TRUE);
}
+ LLVector4a scale(1,1,4,1);
+
for (i = 0; i <(S32) mProfile.size(); i++)
{
// Scale by 4 to generate proper tex coords.
- mProfile[i].mV[2] *= 4.f;
+ mProfile[i].mul(scale);
+ llassert(mProfile[i].isFinite3());
}
if (hollow)
@@ -936,10 +910,12 @@ BOOL LLProfile::generate(const LLProfileParams& params, BOOL path_open,F32 detai
case LL_PCODE_PROFILE_EQUALTRI:
{
genNGon(params, 3,0, 0, 1, split);
+ LLVector4a scale(1,1,3,1);
for (i = 0; i <(S32) mProfile.size(); i++)
{
// Scale by 3 to generate proper tex coords.
- mProfile[i].mV[2] *= 3.f;
+ mProfile[i].mul(scale);
+ llassert(mProfile[i].isFinite3());
}
if (path_open)
@@ -1118,8 +1094,6 @@ BOOL LLProfile::generate(const LLProfileParams& params, BOOL path_open,F32 detai
}
}
- //genNormals(params);
-
return TRUE;
}
@@ -1127,8 +1101,6 @@ BOOL LLProfile::generate(const LLProfileParams& params, BOOL path_open,F32 detai
BOOL LLProfileParams::importFile(LLFILE *fp)
{
- LLMemType m1(LLMemType::MTYPE_VOLUME);
-
const S32 BUFSIZE = 16384;
char buffer[BUFSIZE]; /* Flawfinder: ignore */
// *NOTE: changing the size or type of these buffers will require
@@ -1204,8 +1176,6 @@ BOOL LLProfileParams::exportFile(LLFILE *fp) const
BOOL LLProfileParams::importLegacyStream(std::istream& input_stream)
{
- LLMemType m1(LLMemType::MTYPE_VOLUME);
-
const S32 BUFSIZE = 16384;
char buffer[BUFSIZE]; /* Flawfinder: ignore */
// *NOTE: changing the size or type of these buffers will require
@@ -1297,7 +1267,6 @@ bool LLProfileParams::fromLLSD(LLSD& sd)
void LLProfileParams::copyParams(const LLProfileParams &params)
{
- LLMemType m1(LLMemType::MTYPE_VOLUME);
setCurveType(params.getCurveType());
setBegin(params.getBegin());
setEnd(params.getEnd());
@@ -1407,25 +1376,29 @@ void LLPath::genNGon(const LLPathParams& params, S32 sides, F32 startOff, F32 en
// the path begins at the correct cut.
F32 step= 1.0f / sides;
F32 t = params.getBegin();
- pt = vector_append(mPath, 1);
+ pt = mPath.append(1);
ang = 2.0f*F_PI*revolutions * t;
s = sin(ang)*lerp(radius_start, radius_end, t);
c = cos(ang)*lerp(radius_start, radius_end, t);
- pt->mPos.setVec(0 + lerp(0,params.getShear().mV[0],s)
+ pt->mPos.set(0 + lerp(0,params.getShear().mV[0],s)
+ lerp(-skew ,skew, t) * 0.5f,
c + lerp(0,params.getShear().mV[1],s),
s);
- pt->mScale.mV[VX] = hole_x * lerp(taper_x_begin, taper_x_end, t);
- pt->mScale.mV[VY] = hole_y * lerp(taper_y_begin, taper_y_end, t);
+ pt->mScale.set(hole_x * lerp(taper_x_begin, taper_x_end, t),
+ hole_y * lerp(taper_y_begin, taper_y_end, t),
+ 0,1);
pt->mTexT = t;
-
+
// Twist rotates the path along the x,y plane (I think) - DJS 04/05/02
twist.setQuat (lerp(twist_begin,twist_end,t) * 2.f * F_PI - F_PI,0,0,1);
// Rotate the point around the circle's center.
qang.setQuat (ang,path_axis);
- pt->mRot = twist * qang;
+
+ LLMatrix3 rot(twist * qang);
+
+ pt->mRot.loadu(rot);
t+=step;
@@ -1436,50 +1409,54 @@ void LLPath::genNGon(const LLPathParams& params, S32 sides, F32 startOff, F32 en
// Run through the non-cut dependent points.
while (t < params.getEnd())
{
- pt = vector_append(mPath, 1);
+ pt = mPath.append(1);
ang = 2.0f*F_PI*revolutions * t;
c = cos(ang)*lerp(radius_start, radius_end, t);
s = sin(ang)*lerp(radius_start, radius_end, t);
- pt->mPos.setVec(0 + lerp(0,params.getShear().mV[0],s)
+ pt->mPos.set(0 + lerp(0,params.getShear().mV[0],s)
+ lerp(-skew ,skew, t) * 0.5f,
c + lerp(0,params.getShear().mV[1],s),
s);
- pt->mScale.mV[VX] = hole_x * lerp(taper_x_begin, taper_x_end, t);
- pt->mScale.mV[VY] = hole_y * lerp(taper_y_begin, taper_y_end, t);
+ pt->mScale.set(hole_x * lerp(taper_x_begin, taper_x_end, t),
+ hole_y * lerp(taper_y_begin, taper_y_end, t),
+ 0,1);
pt->mTexT = t;
// Twist rotates the path along the x,y plane (I think) - DJS 04/05/02
twist.setQuat (lerp(twist_begin,twist_end,t) * 2.f * F_PI - F_PI,0,0,1);
// Rotate the point around the circle's center.
qang.setQuat (ang,path_axis);
- pt->mRot = twist * qang;
+ LLMatrix3 tmp(twist*qang);
+ pt->mRot.loadu(tmp);
t+=step;
}
// Make one final pass for the end cut.
t = params.getEnd();
- pt = vector_append(mPath, 1);
+ pt = mPath.append(1);
ang = 2.0f*F_PI*revolutions * t;
c = cos(ang)*lerp(radius_start, radius_end, t);
s = sin(ang)*lerp(radius_start, radius_end, t);
- pt->mPos.setVec(0 + lerp(0,params.getShear().mV[0],s)
+ pt->mPos.set(0 + lerp(0,params.getShear().mV[0],s)
+ lerp(-skew ,skew, t) * 0.5f,
c + lerp(0,params.getShear().mV[1],s),
s);
- pt->mScale.mV[VX] = hole_x * lerp(taper_x_begin, taper_x_end, t);
- pt->mScale.mV[VY] = hole_y * lerp(taper_y_begin, taper_y_end, t);
+ pt->mScale.set(hole_x * lerp(taper_x_begin, taper_x_end, t),
+ hole_y * lerp(taper_y_begin, taper_y_end, t),
+ 0,1);
pt->mTexT = t;
-
+
// Twist rotates the path along the x,y plane (I think) - DJS 04/05/02
twist.setQuat (lerp(twist_begin,twist_end,t) * 2.f * F_PI - F_PI,0,0,1);
// Rotate the point around the circle's center.
qang.setQuat (ang,path_axis);
- pt->mRot = twist * qang;
+ LLMatrix3 tmp(twist*qang);
+ pt->mRot.loadu(tmp);
mTotal = mPath.size();
}
@@ -1514,8 +1491,6 @@ const LLVector2 LLPathParams::getEndScale() const
S32 LLPath::getNumPoints(const LLPathParams& params, F32 detail)
{ // this is basically LLPath::generate stripped down to only the operations that influence the number of points
- LLMemType m1(LLMemType::MTYPE_VOLUME);
-
if (detail < MIN_LOD)
{
detail = MIN_LOD;
@@ -1565,8 +1540,6 @@ S32 LLPath::getNumPoints(const LLPathParams& params, F32 detail)
BOOL LLPath::generate(const LLPathParams& params, F32 detail, S32 split,
BOOL is_sculpted, S32 sculpt_size)
{
- LLMemType m1(LLMemType::MTYPE_VOLUME);
-
if ((!mDirty) && (!is_sculpted))
{
return FALSE;
@@ -1581,7 +1554,7 @@ BOOL LLPath::generate(const LLPathParams& params, F32 detail, S32 split,
mDirty = FALSE;
S32 np = 2; // hardcode for line
- mPath.clear();
+ mPath.resize(0);
mOpen = TRUE;
// Is this 0xf0 mask really necessary? DK 03/02/05
@@ -1607,12 +1580,16 @@ BOOL LLPath::generate(const LLPathParams& params, F32 detail, S32 split,
for (S32 i=0;i<np;i++)
{
F32 t = lerp(params.getBegin(),params.getEnd(),(F32)i * mStep);
- mPath[i].mPos.setVec(lerp(0,params.getShear().mV[0],t),
+ mPath[i].mPos.set(lerp(0,params.getShear().mV[0],t),
lerp(0,params.getShear().mV[1],t),
t - 0.5f);
- mPath[i].mRot.setQuat(lerp(F_PI * params.getTwistBegin(),F_PI * params.getTwist(),t),0,0,1);
- mPath[i].mScale.mV[0] = lerp(start_scale.mV[0],end_scale.mV[0],t);
- mPath[i].mScale.mV[1] = lerp(start_scale.mV[1],end_scale.mV[1],t);
+ LLQuaternion quat;
+ quat.setQuat(lerp(F_PI * params.getTwistBegin(),F_PI * params.getTwist(),t),0,0,1);
+ LLMatrix3 tmp(quat);
+ mPath[i].mRot.loadu(tmp);
+ mPath[i].mScale.set(lerp(start_scale.mV[0],end_scale.mV[0],t),
+ lerp(start_scale.mV[1],end_scale.mV[1],t),
+ 0,1);
mPath[i].mTexT = t;
}
}
@@ -1626,7 +1603,7 @@ BOOL LLPath::generate(const LLPathParams& params, F32 detail, S32 split,
S32 sides = (S32)llfloor(llfloor((MIN_DETAIL_FACES * detail + twist_mag * 3.5f * (detail-0.5f))) * params.getRevolutions());
if (is_sculpted)
- sides = sculpt_size;
+ sides = llmax(sculpt_size, 1);
genNGon(params, sides);
}
@@ -1649,7 +1626,7 @@ BOOL LLPath::generate(const LLPathParams& params, F32 detail, S32 split,
F32 toggle = 0.5f;
for (S32 i=0;i<(S32)mPath.size();i++)
{
- mPath[i].mPos.mV[0] = toggle;
+ mPath[i].mPos.getF32ptr()[0] = toggle;
if (toggle == 0.5f)
toggle = -0.5f;
else
@@ -1670,13 +1647,16 @@ BOOL LLPath::generate(const LLPathParams& params, F32 detail, S32 split,
for (S32 i=0;i<np;i++)
{
F32 t = (F32)i * mStep;
- mPath[i].mPos.setVec(0,
+ mPath[i].mPos.set(0,
lerp(0, -sin(F_PI*params.getTwist()*t)*0.5f,t),
lerp(-0.5, cos(F_PI*params.getTwist()*t)*0.5f,t));
- mPath[i].mScale.mV[0] = lerp(1,params.getScale().mV[0],t);
- mPath[i].mScale.mV[1] = lerp(1,params.getScale().mV[1],t);
+ mPath[i].mScale.set(lerp(1,params.getScale().mV[0],t),
+ lerp(1,params.getScale().mV[1],t), 0,1);
mPath[i].mTexT = t;
- mPath[i].mRot.setQuat(F_PI * params.getTwist() * t,1,0,0);
+ LLQuaternion quat;
+ quat.setQuat(F_PI * params.getTwist() * t,1,0,0);
+ LLMatrix3 tmp(quat);
+ mPath[i].mRot.loadu(tmp);
}
break;
@@ -1694,19 +1674,21 @@ BOOL LLPath::generate(const LLPathParams& params, F32 detail, S32 split,
BOOL LLDynamicPath::generate(const LLPathParams& params, F32 detail, S32 split,
BOOL is_sculpted, S32 sculpt_size)
{
- LLMemType m1(LLMemType::MTYPE_VOLUME);
-
mOpen = TRUE; // Draw end caps
if (getPathLength() == 0)
{
// Path hasn't been generated yet.
// Some algorithms later assume at least TWO path points.
resizePath(2);
+ LLQuaternion quat;
+ quat.setQuat(0,0,0);
+ LLMatrix3 tmp(quat);
+
for (U32 i = 0; i < 2; i++)
{
- mPath[i].mPos.setVec(0, 0, 0);
- mPath[i].mRot.setQuat(0, 0, 0);
- mPath[i].mScale.setVec(1, 1);
+ mPath[i].mPos.set(0, 0, 0);
+ mPath[i].mRot.loadu(tmp);
+ mPath[i].mScale.set(1, 1, 0, 1);
mPath[i].mTexT = 0;
}
}
@@ -1717,8 +1699,6 @@ BOOL LLDynamicPath::generate(const LLPathParams& params, F32 detail, S32 split,
BOOL LLPathParams::importFile(LLFILE *fp)
{
- LLMemType m1(LLMemType::MTYPE_VOLUME);
-
const S32 BUFSIZE = 16384;
char buffer[BUFSIZE]; /* Flawfinder: ignore */
// *NOTE: changing the size or type of these buffers will require
@@ -1863,8 +1843,6 @@ BOOL LLPathParams::exportFile(LLFILE *fp) const
BOOL LLPathParams::importLegacyStream(std::istream& input_stream)
{
- LLMemType m1(LLMemType::MTYPE_VOLUME);
-
const S32 BUFSIZE = 16384;
char buffer[BUFSIZE]; /* Flawfinder: ignore */
// *NOTE: changing the size or type of these buffers will require
@@ -2072,8 +2050,6 @@ S32 LLVolume::sNumMeshPoints = 0;
LLVolume::LLVolume(const LLVolumeParams &params, const F32 detail, const BOOL generate_single_face, const BOOL is_unique)
: mParams(params)
{
- LLMemType m1(LLMemType::MTYPE_VOLUME);
-
mUnique = is_unique;
mFaceMask = 0x0;
mDetail = detail;
@@ -2119,9 +2095,9 @@ void LLVolume::regen()
createVolumeFaces();
}
-void LLVolume::genBinormals(S32 face)
+void LLVolume::genTangents(S32 face)
{
- mVolumeFaces[face].createBinormals();
+ mVolumeFaces[face].createTangents();
}
LLVolume::~LLVolume()
@@ -2145,7 +2121,7 @@ LLVolume::~LLVolume()
BOOL LLVolume::generate()
{
- LLMemType m1(LLMemType::MTYPE_VOLUME);
+ LL_CHECK_MEMORY
llassert_always(mProfilep);
//Added 10.03.05 Dave Parks
@@ -2182,20 +2158,6 @@ BOOL LLVolume::generate()
mLODScaleBias.setVec(0.6f, 0.6f, 0.6f);
}
- //********************************************************************
- //debug info, to be removed
- if((U32)(mPathp->mPath.size() * mProfilep->mProfile.size()) > (1u << 20))
- {
- llinfos << "sizeS: " << mPathp->mPath.size() << " sizeT: " << mProfilep->mProfile.size() << llendl ;
- llinfos << "path_detail : " << path_detail << " split: " << split << " profile_detail: " << profile_detail << llendl ;
- llinfos << mParams << llendl ;
- llinfos << "more info to check if mProfilep is deleted or not." << llendl ;
- llinfos << mProfilep->mNormals.size() << " : " << mProfilep->mFaces.size() << " : " << mProfilep->mEdgeNormals.size() << " : " << mProfilep->mEdgeCenters.size() << llendl ;
-
- llerrs << "LLVolume corrupted!" << llendl ;
- }
- //********************************************************************
-
BOOL regenPath = mPathp->generate(mParams.getPathParams(), path_detail, split);
BOOL regenProf = mProfilep->generate(mParams.getProfileParams(), mPathp->isOpen(),profile_detail, split);
@@ -2204,21 +2166,6 @@ BOOL LLVolume::generate()
S32 sizeS = mPathp->mPath.size();
S32 sizeT = mProfilep->mProfile.size();
- //********************************************************************
- //debug info, to be removed
- if((U32)(sizeS * sizeT) > (1u << 20))
- {
- llinfos << "regenPath: " << (S32)regenPath << " regenProf: " << (S32)regenProf << llendl ;
- llinfos << "sizeS: " << sizeS << " sizeT: " << sizeT << llendl ;
- llinfos << "path_detail : " << path_detail << " split: " << split << " profile_detail: " << profile_detail << llendl ;
- llinfos << mParams << llendl ;
- llinfos << "more info to check if mProfilep is deleted or not." << llendl ;
- llinfos << mProfilep->mNormals.size() << " : " << mProfilep->mFaces.size() << " : " << mProfilep->mEdgeNormals.size() << " : " << mProfilep->mEdgeCenters.size() << llendl ;
-
- llerrs << "LLVolume corrupted!" << llendl ;
- }
- //********************************************************************
-
sNumMeshPoints -= mMesh.size();
mMesh.resize(sizeT * sizeS);
sNumMeshPoints += mMesh.size();
@@ -2226,22 +2173,39 @@ BOOL LLVolume::generate()
//generate vertex positions
// Run along the path.
+ LLVector4a* dst = mMesh.mArray;
+
for (S32 s = 0; s < sizeS; ++s)
{
- LLVector2 scale = mPathp->mPath[s].mScale;
- LLQuaternion rot = mPathp->mPath[s].mRot;
+ F32* scale = mPathp->mPath[s].mScale.getF32ptr();
+
+ F32 sc [] =
+ { scale[0], 0, 0, 0,
+ 0, scale[1], 0, 0,
+ 0, 0, scale[2], 0,
+ 0, 0, 0, 1 };
+
+ LLMatrix4 rot((F32*) mPathp->mPath[s].mRot.mMatrix);
+ LLMatrix4 scale_mat(sc);
+
+ scale_mat *= rot;
+
+ LLMatrix4a rot_mat;
+ rot_mat.loadu(scale_mat);
+
+ LLVector4a* profile = mProfilep->mProfile.mArray;
+ LLVector4a* end_profile = profile+sizeT;
+ LLVector4a offset = mPathp->mPath[s].mPos;
+
+ LLVector4a tmp;
// Run along the profile.
- for (S32 t = 0; t < sizeT; ++t)
+ while (profile < end_profile)
{
- S32 m = s*sizeT + t;
- Point& pt = mMesh[m];
-
- pt.mPos.mV[0] = mProfilep->mProfile[t].mV[0] * scale.mV[0];
- pt.mPos.mV[1] = mProfilep->mProfile[t].mV[1] * scale.mV[1];
- pt.mPos.mV[2] = 0.0f;
- pt.mPos = pt.mPos * rot;
- pt.mPos += mPathp->mPath[s].mPos;
+ rot_mat.rotate(*profile++, tmp);
+ dst->setAdd(tmp,offset);
+ llassert(dst->isFinite3());
+ ++dst;
}
}
@@ -2251,9 +2215,11 @@ BOOL LLVolume::generate()
LLFaceID id = iter->mFaceID;
mFaceMask |= id;
}
-
+ LL_CHECK_MEMORY
return TRUE;
}
+
+ LL_CHECK_MEMORY
return FALSE;
}
@@ -2483,6 +2449,7 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)
LLVector4a pos_range;
pos_range.setSub(max_pos, min_pos);
LLVector2 tc_range2 = max_tc - min_tc;
+
LLVector4a tc_range;
tc_range.set(tc_range2[0], tc_range2[1], tc_range2[0], tc_range2[1]);
LLVector4a min_tc4(min_tc[0], min_tc[1], min_tc[0], min_tc[1]);
@@ -2741,8 +2708,6 @@ S32 LLVolume::getNumFaces() const
void LLVolume::createVolumeFaces()
{
- LLMemType m1(LLMemType::MTYPE_VOLUME);
-
if (mGenerateSingleFace)
{
// do nothing
@@ -2833,13 +2798,15 @@ void LLVolume::createVolumeFaces()
}
-inline LLVector3 sculpt_rgb_to_vector(U8 r, U8 g, U8 b)
+inline LLVector4a sculpt_rgb_to_vector(U8 r, U8 g, U8 b)
{
// maps RGB values to vector values [0..255] -> [-0.5..0.5]
- LLVector3 value;
- value.mV[VX] = r / 255.f - 0.5f;
- value.mV[VY] = g / 255.f - 0.5f;
- value.mV[VZ] = b / 255.f - 0.5f;
+ LLVector4a value;
+ LLVector4a sub(0.5f, 0.5f, 0.5f);
+
+ value.set(r,g,b);
+ value.mul(1.f/255.f);
+ value.sub(sub);
return value;
}
@@ -2860,21 +2827,21 @@ inline U32 sculpt_st_to_index(S32 s, S32 t, S32 size_s, S32 size_t, U16 sculpt_w
}
-inline LLVector3 sculpt_index_to_vector(U32 index, const U8* sculpt_data)
+inline LLVector4a sculpt_index_to_vector(U32 index, const U8* sculpt_data)
{
- LLVector3 v = sculpt_rgb_to_vector(sculpt_data[index], sculpt_data[index+1], sculpt_data[index+2]);
+ LLVector4a v = sculpt_rgb_to_vector(sculpt_data[index], sculpt_data[index+1], sculpt_data[index+2]);
return v;
}
-inline LLVector3 sculpt_st_to_vector(S32 s, S32 t, S32 size_s, S32 size_t, U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data)
+inline LLVector4a sculpt_st_to_vector(S32 s, S32 t, S32 size_s, S32 size_t, U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data)
{
U32 index = sculpt_st_to_index(s, t, size_s, size_t, sculpt_width, sculpt_height, sculpt_components);
return sculpt_index_to_vector(index, sculpt_data);
}
-inline LLVector3 sculpt_xy_to_vector(U32 x, U32 y, U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data)
+inline LLVector4a sculpt_xy_to_vector(U32 x, U32 y, U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data)
{
U32 index = sculpt_xy_to_index(x, y, sculpt_width, sculpt_height, sculpt_components);
@@ -2896,15 +2863,26 @@ F32 LLVolume::sculptGetSurfaceArea()
for (S32 t = 0; t < sizeT-1; t++)
{
// get four corners of quad
- LLVector3 p1 = mMesh[(s )*sizeT + (t )].mPos;
- LLVector3 p2 = mMesh[(s+1)*sizeT + (t )].mPos;
- LLVector3 p3 = mMesh[(s )*sizeT + (t+1)].mPos;
- LLVector3 p4 = mMesh[(s+1)*sizeT + (t+1)].mPos;
+ LLVector4a& p1 = mMesh[(s )*sizeT + (t )];
+ LLVector4a& p2 = mMesh[(s+1)*sizeT + (t )];
+ LLVector4a& p3 = mMesh[(s )*sizeT + (t+1)];
+ LLVector4a& p4 = mMesh[(s+1)*sizeT + (t+1)];
// compute the area of the quad by taking the length of the cross product of the two triangles
- LLVector3 cross1 = (p1 - p2) % (p1 - p3);
- LLVector3 cross2 = (p4 - p2) % (p4 - p3);
- area += (cross1.magVec() + cross2.magVec()) / 2.f;
+ LLVector4a v0,v1,v2,v3;
+ v0.setSub(p1,p2);
+ v1.setSub(p1,p3);
+ v2.setSub(p4,p2);
+ v3.setSub(p4,p3);
+
+ LLVector4a cross1, cross2;
+ cross1.setCross3(v0,v1);
+ cross2.setCross3(v2,v3);
+
+ //LLVector3 cross1 = (p1 - p2) % (p1 - p3);
+ //LLVector3 cross2 = (p4 - p2) % (p4 - p3);
+
+ area += (cross1.getLength3() + cross2.getLength3()).getF32() / 2.f;
}
}
@@ -2914,8 +2892,6 @@ F32 LLVolume::sculptGetSurfaceArea()
// create placeholder shape
void LLVolume::sculptGeneratePlaceholder()
{
- LLMemType m1(LLMemType::MTYPE_VOLUME);
-
S32 sizeS = mPathp->mPath.size();
S32 sizeT = mProfilep->mProfile.size();
@@ -2927,7 +2903,7 @@ void LLVolume::sculptGeneratePlaceholder()
for (S32 t = 0; t < sizeT; t++)
{
S32 i = t + line;
- Point& pt = mMesh[i];
+ LLVector4a& pt = mMesh[i];
F32 u = (F32)s/(sizeS-1);
@@ -2935,9 +2911,13 @@ void LLVolume::sculptGeneratePlaceholder()
const F32 RADIUS = (F32) 0.3;
- pt.mPos.mV[0] = (F32)(sin(F_PI * v) * cos(2.0 * F_PI * u) * RADIUS);
- pt.mPos.mV[1] = (F32)(sin(F_PI * v) * sin(2.0 * F_PI * u) * RADIUS);
- pt.mPos.mV[2] = (F32)(cos(F_PI * v) * RADIUS);
+ F32* p = pt.getF32ptr();
+
+ p[0] = (F32)(sin(F_PI * v) * cos(2.0 * F_PI * u) * RADIUS);
+ p[1] = (F32)(sin(F_PI * v) * sin(2.0 * F_PI * u) * RADIUS);
+ p[2] = (F32)(cos(F_PI * v) * RADIUS);
+
+ llassert(pt.isFinite3());
}
line += sizeT;
@@ -2952,9 +2932,6 @@ void LLVolume::sculptGenerateMapVertices(U16 sculpt_width, U16 sculpt_height, S8
BOOL sculpt_mirror = sculpt_type & LL_SCULPT_FLAG_MIRROR;
BOOL reverse_horizontal = (sculpt_invert ? !sculpt_mirror : sculpt_mirror); // XOR
-
- LLMemType m1(LLMemType::MTYPE_VOLUME);
-
S32 sizeS = mPathp->mPath.size();
S32 sizeT = mProfilep->mProfile.size();
@@ -2965,7 +2942,7 @@ void LLVolume::sculptGenerateMapVertices(U16 sculpt_width, U16 sculpt_height, S8
for (S32 t = 0; t < sizeT; t++)
{
S32 i = t + line;
- Point& pt = mMesh[i];
+ LLVector4a& pt = mMesh[i];
S32 reversed_t = t;
@@ -3022,12 +2999,15 @@ void LLVolume::sculptGenerateMapVertices(U16 sculpt_width, U16 sculpt_height, S8
}
}
- pt.mPos = sculpt_xy_to_vector(x, y, sculpt_width, sculpt_height, sculpt_components, sculpt_data);
+ pt = sculpt_xy_to_vector(x, y, sculpt_width, sculpt_height, sculpt_components, sculpt_data);
if (sculpt_mirror)
{
- pt.mPos.mV[VX] *= -1.f;
+ LLVector4a scale(-1.f,1,1,1);
+ pt.mul(scale);
}
+
+ llassert(pt.isFinite3());
}
line += sizeT;
@@ -3103,7 +3083,6 @@ void sculpt_calc_mesh_resolution(U16 width, U16 height, U8 type, F32 detail, S32
// sculpt replaces generate() for sculpted surfaces
void LLVolume::sculpt(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data, S32 sculpt_level)
{
- LLMemType m1(LLMemType::MTYPE_VOLUME);
U8 sculpt_type = mParams.getSculptType();
BOOL data_is_empty = FALSE;
@@ -3240,7 +3219,6 @@ bool LLVolumeParams::operator<(const LLVolumeParams &params) const
void LLVolumeParams::copyParams(const LLVolumeParams &params)
{
- LLMemType m1(LLMemType::MTYPE_VOLUME);
mProfileParams.copyParams(params.mProfileParams);
mPathParams.copyParams(params.mPathParams);
mSculptID = params.getSculptID();
@@ -3610,629 +3588,6 @@ bool LLVolumeParams::validate(U8 prof_curve, F32 prof_begin, F32 prof_end, F32 h
return true;
}
-S32 *LLVolume::getTriangleIndices(U32 &num_indices) const
-{
- LLMemType m1(LLMemType::MTYPE_VOLUME);
-
- S32 expected_num_triangle_indices = getNumTriangleIndices();
- if (expected_num_triangle_indices > MAX_VOLUME_TRIANGLE_INDICES)
- {
- // we don't allow LLVolumes with this many vertices
- llwarns << "Couldn't allocate triangle indices" << llendl;
- num_indices = 0;
- return NULL;
- }
-
- S32* index = new S32[expected_num_triangle_indices];
- S32 count = 0;
-
- // Let's do this totally diffently, as we don't care about faces...
- // Counter-clockwise triangles are forward facing...
-
- BOOL open = getProfile().isOpen();
- BOOL hollow = (mParams.getProfileParams().getHollow() > 0);
- BOOL path_open = getPath().isOpen();
- S32 size_s, size_s_out, size_t;
- S32 s, t, i;
- size_s = getProfile().getTotal();
- size_s_out = getProfile().getTotalOut();
- size_t = getPath().mPath.size();
-
- // NOTE -- if the construction of the triangles below ever changes
- // then getNumTriangleIndices() method may also have to be updated.
-
- if (open) /* Flawfinder: ignore */
- {
- if (hollow)
- {
- // Open hollow -- much like the closed solid, except we
- // we need to stitch up the gap between s=0 and s=size_s-1
-
- for (t = 0; t < size_t - 1; t++)
- {
- // The outer face, first cut, and inner face
- for (s = 0; s < size_s - 1; s++)
- {
- i = s + t*size_s;
- index[count++] = i; // x,y
- index[count++] = i + 1; // x+1,y
- index[count++] = i + size_s; // x,y+1
-
- index[count++] = i + size_s; // x,y+1
- index[count++] = i + 1; // x+1,y
- index[count++] = i + size_s + 1; // x+1,y+1
- }
-
- // The other cut face
- index[count++] = s + t*size_s; // x,y
- index[count++] = 0 + t*size_s; // x+1,y
- index[count++] = s + (t+1)*size_s; // x,y+1
-
- index[count++] = s + (t+1)*size_s; // x,y+1
- index[count++] = 0 + t*size_s; // x+1,y
- index[count++] = 0 + (t+1)*size_s; // x+1,y+1
- }
-
- // Do the top and bottom caps, if necessary
- if (path_open)
- {
- // Top cap
- S32 pt1 = 0;
- S32 pt2 = size_s-1;
- S32 i = (size_t - 1)*size_s;
-
- while (pt2 - pt1 > 1)
- {
- // Use the profile points instead of the mesh, since you want
- // the un-transformed profile distances.
- LLVector3 p1 = getProfile().mProfile[pt1];
- LLVector3 p2 = getProfile().mProfile[pt2];
- LLVector3 pa = getProfile().mProfile[pt1+1];
- LLVector3 pb = getProfile().mProfile[pt2-1];
-
- p1.mV[VZ] = 0.f;
- p2.mV[VZ] = 0.f;
- pa.mV[VZ] = 0.f;
- pb.mV[VZ] = 0.f;
-
- // Use area of triangle to determine backfacing
- F32 area_1a2, area_1ba, area_21b, area_2ab;
- area_1a2 = (p1.mV[0]*pa.mV[1] - pa.mV[0]*p1.mV[1]) +
- (pa.mV[0]*p2.mV[1] - p2.mV[0]*pa.mV[1]) +
- (p2.mV[0]*p1.mV[1] - p1.mV[0]*p2.mV[1]);
-
- area_1ba = (p1.mV[0]*pb.mV[1] - pb.mV[0]*p1.mV[1]) +
- (pb.mV[0]*pa.mV[1] - pa.mV[0]*pb.mV[1]) +
- (pa.mV[0]*p1.mV[1] - p1.mV[0]*pa.mV[1]);
-
- area_21b = (p2.mV[0]*p1.mV[1] - p1.mV[0]*p2.mV[1]) +
- (p1.mV[0]*pb.mV[1] - pb.mV[0]*p1.mV[1]) +
- (pb.mV[0]*p2.mV[1] - p2.mV[0]*pb.mV[1]);
-
- area_2ab = (p2.mV[0]*pa.mV[1] - pa.mV[0]*p2.mV[1]) +
- (pa.mV[0]*pb.mV[1] - pb.mV[0]*pa.mV[1]) +
- (pb.mV[0]*p2.mV[1] - p2.mV[0]*pb.mV[1]);
-
- BOOL use_tri1a2 = TRUE;
- BOOL tri_1a2 = TRUE;
- BOOL tri_21b = TRUE;
-
- if (area_1a2 < 0)
- {
- tri_1a2 = FALSE;
- }
- if (area_2ab < 0)
- {
- // Can't use, because it contains point b
- tri_1a2 = FALSE;
- }
- if (area_21b < 0)
- {
- tri_21b = FALSE;
- }
- if (area_1ba < 0)
- {
- // Can't use, because it contains point b
- tri_21b = FALSE;
- }
-
- if (!tri_1a2)
- {
- use_tri1a2 = FALSE;
- }
- else if (!tri_21b)
- {
- use_tri1a2 = TRUE;
- }
- else
- {
- LLVector3 d1 = p1 - pa;
- LLVector3 d2 = p2 - pb;
-
- if (d1.magVecSquared() < d2.magVecSquared())
- {
- use_tri1a2 = TRUE;
- }
- else
- {
- use_tri1a2 = FALSE;
- }
- }
-
- if (use_tri1a2)
- {
- index[count++] = pt1 + i;
- index[count++] = pt1 + 1 + i;
- index[count++] = pt2 + i;
- pt1++;
- }
- else
- {
- index[count++] = pt1 + i;
- index[count++] = pt2 - 1 + i;
- index[count++] = pt2 + i;
- pt2--;
- }
- }
-
- // Bottom cap
- pt1 = 0;
- pt2 = size_s-1;
- while (pt2 - pt1 > 1)
- {
- // Use the profile points instead of the mesh, since you want
- // the un-transformed profile distances.
- LLVector3 p1 = getProfile().mProfile[pt1];
- LLVector3 p2 = getProfile().mProfile[pt2];
- LLVector3 pa = getProfile().mProfile[pt1+1];
- LLVector3 pb = getProfile().mProfile[pt2-1];
-
- p1.mV[VZ] = 0.f;
- p2.mV[VZ] = 0.f;
- pa.mV[VZ] = 0.f;
- pb.mV[VZ] = 0.f;
-
- // Use area of triangle to determine backfacing
- F32 area_1a2, area_1ba, area_21b, area_2ab;
- area_1a2 = (p1.mV[0]*pa.mV[1] - pa.mV[0]*p1.mV[1]) +
- (pa.mV[0]*p2.mV[1] - p2.mV[0]*pa.mV[1]) +
- (p2.mV[0]*p1.mV[1] - p1.mV[0]*p2.mV[1]);
-
- area_1ba = (p1.mV[0]*pb.mV[1] - pb.mV[0]*p1.mV[1]) +
- (pb.mV[0]*pa.mV[1] - pa.mV[0]*pb.mV[1]) +
- (pa.mV[0]*p1.mV[1] - p1.mV[0]*pa.mV[1]);
-
- area_21b = (p2.mV[0]*p1.mV[1] - p1.mV[0]*p2.mV[1]) +
- (p1.mV[0]*pb.mV[1] - pb.mV[0]*p1.mV[1]) +
- (pb.mV[0]*p2.mV[1] - p2.mV[0]*pb.mV[1]);
-
- area_2ab = (p2.mV[0]*pa.mV[1] - pa.mV[0]*p2.mV[1]) +
- (pa.mV[0]*pb.mV[1] - pb.mV[0]*pa.mV[1]) +
- (pb.mV[0]*p2.mV[1] - p2.mV[0]*pb.mV[1]);
-
- BOOL use_tri1a2 = TRUE;
- BOOL tri_1a2 = TRUE;
- BOOL tri_21b = TRUE;
-
- if (area_1a2 < 0)
- {
- tri_1a2 = FALSE;
- }
- if (area_2ab < 0)
- {
- // Can't use, because it contains point b
- tri_1a2 = FALSE;
- }
- if (area_21b < 0)
- {
- tri_21b = FALSE;
- }
- if (area_1ba < 0)
- {
- // Can't use, because it contains point b
- tri_21b = FALSE;
- }
-
- if (!tri_1a2)
- {
- use_tri1a2 = FALSE;
- }
- else if (!tri_21b)
- {
- use_tri1a2 = TRUE;
- }
- else
- {
- LLVector3 d1 = p1 - pa;
- LLVector3 d2 = p2 - pb;
-
- if (d1.magVecSquared() < d2.magVecSquared())
- {
- use_tri1a2 = TRUE;
- }
- else
- {
- use_tri1a2 = FALSE;
- }
- }
-
- if (use_tri1a2)
- {
- index[count++] = pt1;
- index[count++] = pt2;
- index[count++] = pt1 + 1;
- pt1++;
- }
- else
- {
- index[count++] = pt1;
- index[count++] = pt2;
- index[count++] = pt2 - 1;
- pt2--;
- }
- }
- }
- }
- else
- {
- // Open solid
-
- for (t = 0; t < size_t - 1; t++)
- {
- // Outer face + 1 cut face
- for (s = 0; s < size_s - 1; s++)
- {
- i = s + t*size_s;
-
- index[count++] = i; // x,y
- index[count++] = i + 1; // x+1,y
- index[count++] = i + size_s; // x,y+1
-
- index[count++] = i + size_s; // x,y+1
- index[count++] = i + 1; // x+1,y
- index[count++] = i + size_s + 1; // x+1,y+1
- }
-
- // The other cut face
- index[count++] = (size_s - 1) + (t*size_s); // x,y
- index[count++] = 0 + t*size_s; // x+1,y
- index[count++] = (size_s - 1) + (t+1)*size_s; // x,y+1
-
- index[count++] = (size_s - 1) + (t+1)*size_s; // x,y+1
- index[count++] = 0 + (t*size_s); // x+1,y
- index[count++] = 0 + (t+1)*size_s; // x+1,y+1
- }
-
- // Do the top and bottom caps, if necessary
- if (path_open)
- {
- for (s = 0; s < size_s - 2; s++)
- {
- index[count++] = s+1;
- index[count++] = s;
- index[count++] = size_s - 1;
- }
-
- // We've got a top cap
- S32 offset = (size_t - 1)*size_s;
- for (s = 0; s < size_s - 2; s++)
- {
- // Inverted ordering from bottom cap.
- index[count++] = offset + size_s - 1;
- index[count++] = offset + s;
- index[count++] = offset + s + 1;
- }
- }
- }
- }
- else if (hollow)
- {
- // Closed hollow
- // Outer face
-
- for (t = 0; t < size_t - 1; t++)
- {
- for (s = 0; s < size_s_out - 1; s++)
- {
- i = s + t*size_s;
-
- index[count++] = i; // x,y
- index[count++] = i + 1; // x+1,y
- index[count++] = i + size_s; // x,y+1
-
- index[count++] = i + size_s; // x,y+1
- index[count++] = i + 1; // x+1,y
- index[count++] = i + 1 + size_s; // x+1,y+1
- }
- }
-
- // Inner face
- // Invert facing from outer face
- for (t = 0; t < size_t - 1; t++)
- {
- for (s = size_s_out; s < size_s - 1; s++)
- {
- i = s + t*size_s;
-
- index[count++] = i; // x,y
- index[count++] = i + 1; // x+1,y
- index[count++] = i + size_s; // x,y+1
-
- index[count++] = i + size_s; // x,y+1
- index[count++] = i + 1; // x+1,y
- index[count++] = i + 1 + size_s; // x+1,y+1
- }
- }
-
- // Do the top and bottom caps, if necessary
- if (path_open)
- {
- // Top cap
- S32 pt1 = 0;
- S32 pt2 = size_s-1;
- S32 i = (size_t - 1)*size_s;
-
- while (pt2 - pt1 > 1)
- {
- // Use the profile points instead of the mesh, since you want
- // the un-transformed profile distances.
- LLVector3 p1 = getProfile().mProfile[pt1];
- LLVector3 p2 = getProfile().mProfile[pt2];
- LLVector3 pa = getProfile().mProfile[pt1+1];
- LLVector3 pb = getProfile().mProfile[pt2-1];
-
- p1.mV[VZ] = 0.f;
- p2.mV[VZ] = 0.f;
- pa.mV[VZ] = 0.f;
- pb.mV[VZ] = 0.f;
-
- // Use area of triangle to determine backfacing
- F32 area_1a2, area_1ba, area_21b, area_2ab;
- area_1a2 = (p1.mV[0]*pa.mV[1] - pa.mV[0]*p1.mV[1]) +
- (pa.mV[0]*p2.mV[1] - p2.mV[0]*pa.mV[1]) +
- (p2.mV[0]*p1.mV[1] - p1.mV[0]*p2.mV[1]);
-
- area_1ba = (p1.mV[0]*pb.mV[1] - pb.mV[0]*p1.mV[1]) +
- (pb.mV[0]*pa.mV[1] - pa.mV[0]*pb.mV[1]) +
- (pa.mV[0]*p1.mV[1] - p1.mV[0]*pa.mV[1]);
-
- area_21b = (p2.mV[0]*p1.mV[1] - p1.mV[0]*p2.mV[1]) +
- (p1.mV[0]*pb.mV[1] - pb.mV[0]*p1.mV[1]) +
- (pb.mV[0]*p2.mV[1] - p2.mV[0]*pb.mV[1]);
-
- area_2ab = (p2.mV[0]*pa.mV[1] - pa.mV[0]*p2.mV[1]) +
- (pa.mV[0]*pb.mV[1] - pb.mV[0]*pa.mV[1]) +
- (pb.mV[0]*p2.mV[1] - p2.mV[0]*pb.mV[1]);
-
- BOOL use_tri1a2 = TRUE;
- BOOL tri_1a2 = TRUE;
- BOOL tri_21b = TRUE;
-
- if (area_1a2 < 0)
- {
- tri_1a2 = FALSE;
- }
- if (area_2ab < 0)
- {
- // Can't use, because it contains point b
- tri_1a2 = FALSE;
- }
- if (area_21b < 0)
- {
- tri_21b = FALSE;
- }
- if (area_1ba < 0)
- {
- // Can't use, because it contains point b
- tri_21b = FALSE;
- }
-
- if (!tri_1a2)
- {
- use_tri1a2 = FALSE;
- }
- else if (!tri_21b)
- {
- use_tri1a2 = TRUE;
- }
- else
- {
- LLVector3 d1 = p1 - pa;
- LLVector3 d2 = p2 - pb;
-
- if (d1.magVecSquared() < d2.magVecSquared())
- {
- use_tri1a2 = TRUE;
- }
- else
- {
- use_tri1a2 = FALSE;
- }
- }
-
- if (use_tri1a2)
- {
- index[count++] = pt1 + i;
- index[count++] = pt1 + 1 + i;
- index[count++] = pt2 + i;
- pt1++;
- }
- else
- {
- index[count++] = pt1 + i;
- index[count++] = pt2 - 1 + i;
- index[count++] = pt2 + i;
- pt2--;
- }
- }
-
- // Bottom cap
- pt1 = 0;
- pt2 = size_s-1;
- while (pt2 - pt1 > 1)
- {
- // Use the profile points instead of the mesh, since you want
- // the un-transformed profile distances.
- LLVector3 p1 = getProfile().mProfile[pt1];
- LLVector3 p2 = getProfile().mProfile[pt2];
- LLVector3 pa = getProfile().mProfile[pt1+1];
- LLVector3 pb = getProfile().mProfile[pt2-1];
-
- p1.mV[VZ] = 0.f;
- p2.mV[VZ] = 0.f;
- pa.mV[VZ] = 0.f;
- pb.mV[VZ] = 0.f;
-
- // Use area of triangle to determine backfacing
- F32 area_1a2, area_1ba, area_21b, area_2ab;
- area_1a2 = (p1.mV[0]*pa.mV[1] - pa.mV[0]*p1.mV[1]) +
- (pa.mV[0]*p2.mV[1] - p2.mV[0]*pa.mV[1]) +
- (p2.mV[0]*p1.mV[1] - p1.mV[0]*p2.mV[1]);
-
- area_1ba = (p1.mV[0]*pb.mV[1] - pb.mV[0]*p1.mV[1]) +
- (pb.mV[0]*pa.mV[1] - pa.mV[0]*pb.mV[1]) +
- (pa.mV[0]*p1.mV[1] - p1.mV[0]*pa.mV[1]);
-
- area_21b = (p2.mV[0]*p1.mV[1] - p1.mV[0]*p2.mV[1]) +
- (p1.mV[0]*pb.mV[1] - pb.mV[0]*p1.mV[1]) +
- (pb.mV[0]*p2.mV[1] - p2.mV[0]*pb.mV[1]);
-
- area_2ab = (p2.mV[0]*pa.mV[1] - pa.mV[0]*p2.mV[1]) +
- (pa.mV[0]*pb.mV[1] - pb.mV[0]*pa.mV[1]) +
- (pb.mV[0]*p2.mV[1] - p2.mV[0]*pb.mV[1]);
-
- BOOL use_tri1a2 = TRUE;
- BOOL tri_1a2 = TRUE;
- BOOL tri_21b = TRUE;
-
- if (area_1a2 < 0)
- {
- tri_1a2 = FALSE;
- }
- if (area_2ab < 0)
- {
- // Can't use, because it contains point b
- tri_1a2 = FALSE;
- }
- if (area_21b < 0)
- {
- tri_21b = FALSE;
- }
- if (area_1ba < 0)
- {
- // Can't use, because it contains point b
- tri_21b = FALSE;
- }
-
- if (!tri_1a2)
- {
- use_tri1a2 = FALSE;
- }
- else if (!tri_21b)
- {
- use_tri1a2 = TRUE;
- }
- else
- {
- LLVector3 d1 = p1 - pa;
- LLVector3 d2 = p2 - pb;
-
- if (d1.magVecSquared() < d2.magVecSquared())
- {
- use_tri1a2 = TRUE;
- }
- else
- {
- use_tri1a2 = FALSE;
- }
- }
-
- if (use_tri1a2)
- {
- index[count++] = pt1;
- index[count++] = pt2;
- index[count++] = pt1 + 1;
- pt1++;
- }
- else
- {
- index[count++] = pt1;
- index[count++] = pt2;
- index[count++] = pt2 - 1;
- pt2--;
- }
- }
- }
- }
- else
- {
- // Closed solid. Easy case.
- for (t = 0; t < size_t - 1; t++)
- {
- for (s = 0; s < size_s - 1; s++)
- {
- // Should wrap properly, but for now...
- i = s + t*size_s;
-
- index[count++] = i; // x,y
- index[count++] = i + 1; // x+1,y
- index[count++] = i + size_s; // x,y+1
-
- index[count++] = i + size_s; // x,y+1
- index[count++] = i + 1; // x+1,y
- index[count++] = i + size_s + 1; // x+1,y+1
- }
- }
-
- // Do the top and bottom caps, if necessary
- if (path_open)
- {
- // bottom cap
- for (s = 1; s < size_s - 2; s++)
- {
- index[count++] = s+1;
- index[count++] = s;
- index[count++] = 0;
- }
-
- // top cap
- S32 offset = (size_t - 1)*size_s;
- for (s = 1; s < size_s - 2; s++)
- {
- // Inverted ordering from bottom cap.
- index[count++] = offset;
- index[count++] = offset + s;
- index[count++] = offset + s + 1;
- }
- }
- }
-
-#ifdef LL_DEBUG
- // assert that we computed the correct number of indices
- if (count != expected_num_triangle_indices )
- {
- llerrs << "bad index count prediciton:"
- << " expected=" << expected_num_triangle_indices
- << " actual=" << count << llendl;
- }
-#endif
-
-#if 0
- // verify that each index does not point beyond the size of the mesh
- S32 num_vertices = mMesh.size();
- for (i = 0; i < count; i+=3)
- {
- llinfos << index[i] << ":" << index[i+1] << ":" << index[i+2] << llendl;
- llassert(index[i] < num_vertices);
- llassert(index[i+1] < num_vertices);
- llassert(index[i+2] < num_vertices);
- }
-#endif
-
- num_indices = count;
- return index;
-}
-
void LLVolume::getLoDTriangleCounts(const LLVolumeParams& params, S32* counts)
{ //attempt to approximate the number of triangles that will result from generating a volume LoD set for the
//supplied LLVolumeParams -- inaccurate, but a close enough approximation for determining streaming cost
@@ -4250,63 +3605,6 @@ void LLVolume::getLoDTriangleCounts(const LLVolumeParams& params, S32* counts)
}
}
-S32 LLVolume::getNumTriangleIndices() const
-{
- BOOL profile_open = getProfile().isOpen();
- BOOL hollow = (mParams.getProfileParams().getHollow() > 0);
- BOOL path_open = getPath().isOpen();
-
- S32 size_s, size_s_out, size_t;
- size_s = getProfile().getTotal();
- size_s_out = getProfile().getTotalOut();
- size_t = getPath().mPath.size();
-
- S32 count = 0;
- if (profile_open) /* Flawfinder: ignore */
- {
- if (hollow)
- {
- // Open hollow -- much like the closed solid, except we
- // we need to stitch up the gap between s=0 and s=size_s-1
- count = (size_t - 1) * (((size_s -1) * 6) + 6);
- }
- else
- {
- count = (size_t - 1) * (((size_s -1) * 6) + 6);
- }
- }
- else if (hollow)
- {
- // Closed hollow
- // Outer face
- count = (size_t - 1) * (size_s_out - 1) * 6;
-
- // Inner face
- count += (size_t - 1) * ((size_s - 1) - size_s_out) * 6;
- }
- else
- {
- // Closed solid. Easy case.
- count = (size_t - 1) * (size_s - 1) * 6;
- }
-
- if (path_open)
- {
- S32 cap_triangle_count = size_s - 3;
- if ( profile_open
- || hollow )
- {
- cap_triangle_count = size_s - 2;
- }
- if ( cap_triangle_count > 0 )
- {
- // top and bottom caps
- count += cap_triangle_count * 2 * 3;
- }
- }
- return count;
-}
-
S32 LLVolume::getNumTriangles(S32* vcount) const
{
@@ -4341,8 +3639,6 @@ void LLVolume::generateSilhouetteVertices(std::vector<LLVector3> &vertices,
const LLMatrix3& norm_mat_in,
S32 face_mask)
{
- LLMemType m1(LLMemType::MTYPE_VOLUME);
-
LLMatrix4a mat;
mat.loadu(mat_in);
@@ -4446,7 +3742,7 @@ void LLVolume::generateSilhouetteVertices(std::vector<LLVector3> &vertices,
segments.push_back(vertices.size());
#if DEBUG_SILHOUETTE_BINORMALS
vertices.push_back(face.mVertices[j].getPosition());
- vertices.push_back(face.mVertices[j].getPosition() + face.mVertices[j].mBinormal*0.1f);
+ vertices.push_back(face.mVertices[j].getPosition() + face.mVertices[j].mTangent*0.1f);
normals.push_back(LLVector3(0,0,1));
normals.push_back(LLVector3(0,0,1));
segments.push_back(vertices.size());
@@ -4562,22 +3858,9 @@ void LLVolume::generateSilhouetteVertices(std::vector<LLVector3> &vertices,
}
}
-S32 LLVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& end,
- S32 face,
- LLVector3* intersection,LLVector2* tex_coord, LLVector3* normal, LLVector3* bi_normal)
-{
- LLVector4a starta, enda;
- starta.load3(start.mV);
- enda.load3(end.mV);
-
- return lineSegmentIntersect(starta, enda, face, intersection, tex_coord, normal, bi_normal);
-
-}
-
-
S32 LLVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
S32 face,
- LLVector3* intersection,LLVector2* tex_coord, LLVector3* normal, LLVector3* bi_normal)
+ LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent_out)
{
S32 hit_face = -1;
@@ -4615,9 +3898,9 @@ S32 LLVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& en
if (LLLineSegmentBoxIntersect(start, end, box_center, box_size))
{
- if (bi_normal != NULL) // if the caller wants binormals, we may need to generate them
+ if (tangent_out != NULL) // if the caller wants tangents, we may need to generate them
{
- genBinormals(i);
+ genTangents(i);
}
if (isUnique())
@@ -4651,7 +3934,7 @@ S32 LLVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& en
LLVector4a intersect = dir;
intersect.mul(closest_t);
intersect.add(start);
- intersection->set(intersect.getF32ptr());
+ *intersection = intersect;
}
@@ -4666,19 +3949,42 @@ S32 LLVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& en
if (normal!= NULL)
{
- LLVector4* norm = (LLVector4*) face.mNormals;
-
- *normal = ((1.f - a - b) * LLVector3(norm[idx0]) +
- a * LLVector3(norm[idx1]) +
- b * LLVector3(norm[idx2]));
+ LLVector4a* norm = face.mNormals;
+
+ LLVector4a n1,n2,n3;
+ n1 = norm[idx0];
+ n1.mul(1.f-a-b);
+
+ n2 = norm[idx1];
+ n2.mul(a);
+
+ n3 = norm[idx2];
+ n3.mul(b);
+
+ n1.add(n2);
+ n1.add(n3);
+
+ *normal = n1;
}
- if (bi_normal != NULL)
+ if (tangent_out != NULL)
{
- LLVector4* binormal = (LLVector4*) face.mBinormals;
- *bi_normal = ((1.f - a - b) * LLVector3(binormal[idx0]) +
- a * LLVector3(binormal[idx1]) +
- b * LLVector3(binormal[idx2]));
+ LLVector4a* tangents = face.mTangents;
+
+ LLVector4a t1,t2,t3;
+ t1 = tangents[idx0];
+ t1.mul(1.f-a-b);
+
+ t2 = tangents[idx1];
+ t2.mul(a);
+
+ t3 = tangents[idx2];
+ t3.mul(b);
+
+ t1.add(t2);
+ t1.add(t3);
+
+ *tangent_out = t1;
}
}
}
@@ -4691,7 +3997,7 @@ S32 LLVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& en
face.createOctree();
}
- LLOctreeTriangleRayIntersect intersect(start, dir, &face, &closest_t, intersection, tex_coord, normal, bi_normal);
+ LLOctreeTriangleRayIntersect intersect(start, dir, &face, &closest_t, intersection, tex_coord, normal, tangent_out);
intersect.traverse(face.mOctree);
if (intersect.mHitFace)
{
@@ -4804,241 +4110,8 @@ BOOL equalTriangle(const S32 *a, const S32 *b)
return FALSE;
}
-BOOL LLVolume::cleanupTriangleData( const S32 num_input_vertices,
- const std::vector<Point>& input_vertices,
- const S32 num_input_triangles,
- S32 *input_triangles,
- S32 &num_output_vertices,
- LLVector3 **output_vertices,
- S32 &num_output_triangles,
- S32 **output_triangles)
-{
- LLMemType m1(LLMemType::MTYPE_VOLUME);
-
- /* Testing: avoid any cleanup
- static BOOL skip_cleanup = TRUE;
- if ( skip_cleanup )
- {
- num_output_vertices = num_input_vertices;
- num_output_triangles = num_input_triangles;
-
- *output_vertices = new LLVector3[num_input_vertices];
- for (S32 index = 0; index < num_input_vertices; index++)
- {
- (*output_vertices)[index] = input_vertices[index].mPos;
- }
-
- *output_triangles = new S32[num_input_triangles*3];
- memcpy(*output_triangles, input_triangles, 3*num_input_triangles*sizeof(S32)); // Flawfinder: ignore
- return TRUE;
- }
- */
-
- // Here's how we do this:
- // Create a structure which contains the original vertex index and the
- // LLVector3 data.
- // "Sort" the data by the vectors
- // Create an array the size of the old vertex list, with a mapping of
- // old indices to new indices.
- // Go through triangles, shift so the lowest index is first
- // Sort triangles by first index
- // Remove duplicate triangles
- // Allocate and pack new triangle data.
-
- //LLTimer cleanupTimer;
- //llinfos << "In vertices: " << num_input_vertices << llendl;
- //llinfos << "In triangles: " << num_input_triangles << llendl;
-
- S32 i;
- typedef std::multiset<LLVertexIndexPair*, lessVertex> vertex_set_t;
- vertex_set_t vertex_list;
-
- LLVertexIndexPair *pairp = NULL;
- for (i = 0; i < num_input_vertices; i++)
- {
- LLVertexIndexPair *new_pairp = new LLVertexIndexPair(input_vertices[i].mPos, i);
- vertex_list.insert(new_pairp);
- }
-
- // Generate the vertex mapping and the list of vertices without
- // duplicates. This will crash if there are no vertices.
- llassert(num_input_vertices > 0); // check for no vertices!
- S32 *vertex_mapping = new S32[num_input_vertices];
- LLVector3 *new_vertices = new LLVector3[num_input_vertices];
- LLVertexIndexPair *prev_pairp = NULL;
-
- S32 new_num_vertices;
-
- new_num_vertices = 0;
- for (vertex_set_t::iterator iter = vertex_list.begin(),
- end = vertex_list.end();
- iter != end; iter++)
- {
- pairp = *iter;
- if (!prev_pairp || ((pairp->mVertex - prev_pairp->mVertex).magVecSquared() >= VERTEX_SLOP_SQRD))
- {
- new_vertices[new_num_vertices] = pairp->mVertex;
- //llinfos << "Added vertex " << new_num_vertices << " : " << pairp->mVertex << llendl;
- new_num_vertices++;
- // Update the previous
- prev_pairp = pairp;
- }
- else
- {
- //llinfos << "Removed duplicate vertex " << pairp->mVertex << ", distance magVecSquared() is " << (pairp->mVertex - prev_pairp->mVertex).magVecSquared() << llendl;
- }
- vertex_mapping[pairp->mIndex] = new_num_vertices - 1;
- }
-
- // Iterate through triangles and remove degenerates, re-ordering vertices
- // along the way.
- S32 *new_triangles = new S32[num_input_triangles * 3];
- S32 new_num_triangles = 0;
-
- for (i = 0; i < num_input_triangles; i++)
- {
- S32 v1 = i*3;
- S32 v2 = v1 + 1;
- S32 v3 = v1 + 2;
-
- //llinfos << "Checking triangle " << input_triangles[v1] << ":" << input_triangles[v2] << ":" << input_triangles[v3] << llendl;
- input_triangles[v1] = vertex_mapping[input_triangles[v1]];
- input_triangles[v2] = vertex_mapping[input_triangles[v2]];
- input_triangles[v3] = vertex_mapping[input_triangles[v3]];
-
- if ((input_triangles[v1] == input_triangles[v2])
- || (input_triangles[v1] == input_triangles[v3])
- || (input_triangles[v2] == input_triangles[v3]))
- {
- //llinfos << "Removing degenerate triangle " << input_triangles[v1] << ":" << input_triangles[v2] << ":" << input_triangles[v3] << llendl;
- // Degenerate triangle, skip
- continue;
- }
-
- if (input_triangles[v1] < input_triangles[v2])
- {
- if (input_triangles[v1] < input_triangles[v3])
- {
- // (0 < 1) && (0 < 2)
- new_triangles[new_num_triangles*3] = input_triangles[v1];
- new_triangles[new_num_triangles*3+1] = input_triangles[v2];
- new_triangles[new_num_triangles*3+2] = input_triangles[v3];
- }
- else
- {
- // (0 < 1) && (2 < 0)
- new_triangles[new_num_triangles*3] = input_triangles[v3];
- new_triangles[new_num_triangles*3+1] = input_triangles[v1];
- new_triangles[new_num_triangles*3+2] = input_triangles[v2];
- }
- }
- else if (input_triangles[v2] < input_triangles[v3])
- {
- // (1 < 0) && (1 < 2)
- new_triangles[new_num_triangles*3] = input_triangles[v2];
- new_triangles[new_num_triangles*3+1] = input_triangles[v3];
- new_triangles[new_num_triangles*3+2] = input_triangles[v1];
- }
- else
- {
- // (1 < 0) && (2 < 1)
- new_triangles[new_num_triangles*3] = input_triangles[v3];
- new_triangles[new_num_triangles*3+1] = input_triangles[v1];
- new_triangles[new_num_triangles*3+2] = input_triangles[v2];
- }
- new_num_triangles++;
- }
-
- if (new_num_triangles == 0)
- {
- llwarns << "Created volume object with 0 faces." << llendl;
- delete[] new_triangles;
- delete[] vertex_mapping;
- delete[] new_vertices;
- return FALSE;
- }
-
- typedef std::set<S32*, lessTriangle> triangle_set_t;
- triangle_set_t triangle_list;
-
- for (i = 0; i < new_num_triangles; i++)
- {
- triangle_list.insert(&new_triangles[i*3]);
- }
-
- // Sort through the triangle list, and delete duplicates
-
- S32 *prevp = NULL;
- S32 *curp = NULL;
-
- S32 *sorted_tris = new S32[new_num_triangles*3];
- S32 cur_tri = 0;
- for (triangle_set_t::iterator iter = triangle_list.begin(),
- end = triangle_list.end();
- iter != end; iter++)
- {
- curp = *iter;
- if (!prevp || !equalTriangle(prevp, curp))
- {
- //llinfos << "Added triangle " << *curp << ":" << *(curp+1) << ":" << *(curp+2) << llendl;
- sorted_tris[cur_tri*3] = *curp;
- sorted_tris[cur_tri*3+1] = *(curp+1);
- sorted_tris[cur_tri*3+2] = *(curp+2);
- cur_tri++;
- prevp = curp;
- }
- else
- {
- //llinfos << "Skipped triangle " << *curp << ":" << *(curp+1) << ":" << *(curp+2) << llendl;
- }
- }
-
- *output_vertices = new LLVector3[new_num_vertices];
- num_output_vertices = new_num_vertices;
- for (i = 0; i < new_num_vertices; i++)
- {
- (*output_vertices)[i] = new_vertices[i];
- }
-
- *output_triangles = new S32[cur_tri*3];
- num_output_triangles = cur_tri;
- memcpy(*output_triangles, sorted_tris, 3*cur_tri*sizeof(S32)); /* Flawfinder: ignore */
-
- /*
- llinfos << "Out vertices: " << num_output_vertices << llendl;
- llinfos << "Out triangles: " << num_output_triangles << llendl;
- for (i = 0; i < num_output_vertices; i++)
- {
- llinfos << i << ":" << (*output_vertices)[i] << llendl;
- }
- for (i = 0; i < num_output_triangles; i++)
- {
- llinfos << i << ":" << (*output_triangles)[i*3] << ":" << (*output_triangles)[i*3+1] << ":" << (*output_triangles)[i*3+2] << llendl;
- }
- */
-
- //llinfos << "Out vertices: " << num_output_vertices << llendl;
- //llinfos << "Out triangles: " << num_output_triangles << llendl;
- delete[] vertex_mapping;
- vertex_mapping = NULL;
- delete[] new_vertices;
- new_vertices = NULL;
- delete[] new_triangles;
- new_triangles = NULL;
- delete[] sorted_tris;
- sorted_tris = NULL;
- triangle_list.clear();
- std::for_each(vertex_list.begin(), vertex_list.end(), DeletePointer());
- vertex_list.clear();
-
- return TRUE;
-}
-
-
BOOL LLVolumeParams::importFile(LLFILE *fp)
{
- LLMemType m1(LLMemType::MTYPE_VOLUME);
-
//llinfos << "importing volume" << llendl;
const S32 BUFSIZE = 16384;
char buffer[BUFSIZE]; /* Flawfinder: ignore */
@@ -5093,8 +4166,6 @@ BOOL LLVolumeParams::exportFile(LLFILE *fp) const
BOOL LLVolumeParams::importLegacyStream(std::istream& input_stream)
{
- LLMemType m1(LLMemType::MTYPE_VOLUME);
-
//llinfos << "importing volume" << llendl;
const S32 BUFSIZE = 16384;
// *NOTE: changing the size or type of this buffer will require
@@ -5134,8 +4205,6 @@ BOOL LLVolumeParams::importLegacyStream(std::istream& input_stream)
BOOL LLVolumeParams::exportLegacyStream(std::ostream& output_stream) const
{
- LLMemType m1(LLMemType::MTYPE_VOLUME);
-
output_stream <<"\tshape 0\n";
output_stream <<"\t{\n";
mPathParams.exportLegacyStream(output_stream);
@@ -5471,14 +4540,16 @@ LLVolumeFace::LLVolumeFace() :
mNumS(0),
mNumT(0),
mNumVertices(0),
+ mNumAllocatedVertices(0),
mNumIndices(0),
mPositions(NULL),
mNormals(NULL),
- mBinormals(NULL),
+ mTangents(NULL),
mTexCoords(NULL),
mIndices(NULL),
mWeights(NULL),
- mOctree(NULL)
+ mOctree(NULL),
+ mOptimized(FALSE)
{
mExtents = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*3);
mExtents[0].splat(-0.5f);
@@ -5494,10 +4565,11 @@ LLVolumeFace::LLVolumeFace(const LLVolumeFace& src)
mNumS(0),
mNumT(0),
mNumVertices(0),
+ mNumAllocatedVertices(0),
mNumIndices(0),
mPositions(NULL),
mNormals(NULL),
- mBinormals(NULL),
+ mTangents(NULL),
mTexCoords(NULL),
mIndices(NULL),
mWeights(NULL),
@@ -5531,8 +4603,6 @@ LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src)
freeData();
- LLVector4a::memcpyNonAliased16((F32*) mExtents, (F32*) src.mExtents, 3*sizeof(LLVector4a));
-
resizeVertices(src.mNumVertices);
resizeIndices(src.mNumIndices);
@@ -5542,28 +4612,26 @@ LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src)
S32 tc_size = (mNumVertices*sizeof(LLVector2)+0xF) & ~0xF;
LLVector4a::memcpyNonAliased16((F32*) mPositions, (F32*) src.mPositions, vert_size);
+
+ if (src.mNormals)
+ {
LLVector4a::memcpyNonAliased16((F32*) mNormals, (F32*) src.mNormals, vert_size);
+ }
if(src.mTexCoords)
{
LLVector4a::memcpyNonAliased16((F32*) mTexCoords, (F32*) src.mTexCoords, tc_size);
}
- else
- {
- ll_aligned_free_16(mTexCoords) ;
- mTexCoords = NULL ;
- }
-
- if (src.mBinormals)
+ if (src.mTangents)
{
- allocateBinormals(src.mNumVertices);
- LLVector4a::memcpyNonAliased16((F32*) mBinormals, (F32*) src.mBinormals, vert_size);
+ allocateTangents(src.mNumVertices);
+ LLVector4a::memcpyNonAliased16((F32*) mTangents, (F32*) src.mTangents, vert_size);
}
else
{
- ll_aligned_free_16(mBinormals);
- mBinormals = NULL;
+ ll_aligned_free_16(mTangents);
+ mTangents = NULL;
}
if (src.mWeights)
@@ -5585,6 +4653,8 @@ LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src)
LLVector4a::memcpyNonAliased16((F32*) mIndices, (F32*) src.mIndices, idx_size);
}
+ mOptimized = src.mOptimized;
+
//delete
return *this;
}
@@ -5599,16 +4669,17 @@ LLVolumeFace::~LLVolumeFace()
void LLVolumeFace::freeData()
{
- ll_aligned_free_16(mPositions);
+ ll_aligned_free(mPositions);
mPositions = NULL;
- ll_aligned_free_16( mNormals);
+
+ //normals and texture coordinates are part of the same buffer as mPositions, do not free them separately
mNormals = NULL;
- ll_aligned_free_16(mTexCoords);
mTexCoords = NULL;
+
ll_aligned_free_16(mIndices);
mIndices = NULL;
- ll_aligned_free_16(mBinormals);
- mBinormals = NULL;
+ ll_aligned_free_16(mTangents);
+ mTangents = NULL;
ll_aligned_free_16(mWeights);
mWeights = NULL;
@@ -5622,52 +4693,23 @@ BOOL LLVolumeFace::create(LLVolume* volume, BOOL partial_build)
delete mOctree;
mOctree = NULL;
+ LL_CHECK_MEMORY
BOOL ret = FALSE ;
if (mTypeMask & CAP_MASK)
{
ret = createCap(volume, partial_build);
+ LL_CHECK_MEMORY
}
else if ((mTypeMask & END_MASK) || (mTypeMask & SIDE_MASK))
{
ret = createSide(volume, partial_build);
+ LL_CHECK_MEMORY
}
else
{
llerrs << "Unknown/uninitialized face type!" << llendl;
}
- //update the range of the texture coordinates
- if(ret)
- {
- mTexCoordExtents[0].setVec(1.f, 1.f) ;
- mTexCoordExtents[1].setVec(0.f, 0.f) ;
-
- for(U32 i = 0 ; i < mNumVertices ; i++)
- {
- if(mTexCoordExtents[0].mV[0] > mTexCoords[i].mV[0])
- {
- mTexCoordExtents[0].mV[0] = mTexCoords[i].mV[0] ;
- }
- if(mTexCoordExtents[1].mV[0] < mTexCoords[i].mV[0])
- {
- mTexCoordExtents[1].mV[0] = mTexCoords[i].mV[0] ;
- }
-
- if(mTexCoordExtents[0].mV[1] > mTexCoords[i].mV[1])
- {
- mTexCoordExtents[0].mV[1] = mTexCoords[i].mV[1] ;
- }
- if(mTexCoordExtents[1].mV[1] < mTexCoords[i].mV[1])
- {
- mTexCoordExtents[1].mV[1] = mTexCoords[i].mV[1] ;
- }
- }
- mTexCoordExtents[0].mV[0] = llmax(0.f, mTexCoordExtents[0].mV[0]) ;
- mTexCoordExtents[0].mV[1] = llmax(0.f, mTexCoordExtents[0].mV[1]) ;
- mTexCoordExtents[1].mV[0] = llmin(1.f, mTexCoordExtents[1].mV[0]) ;
- mTexCoordExtents[1].mV[1] = llmin(1.f, mTexCoordExtents[1].mV[1]) ;
- }
-
return ret ;
}
@@ -5783,22 +4825,29 @@ void LLVolumeFace::optimize(F32 angle_cutoff)
}
}
- llassert(new_face.mNumIndices == mNumIndices);
- llassert(new_face.mNumVertices <= mNumVertices);
if (angle_cutoff > 1.f && !mNormals)
{
- ll_aligned_free_16(new_face.mNormals);
+ // Now alloc'd with positions
+ //ll_aligned_free_16(new_face.mNormals);
new_face.mNormals = NULL;
}
if (!mTexCoords)
{
- ll_aligned_free_16(new_face.mTexCoords);
+ // Now alloc'd with positions
+ //ll_aligned_free_16(new_face.mTexCoords);
new_face.mTexCoords = NULL;
}
- swapData(new_face);
+ // Only swap data if we've actually optimized the mesh
+ //
+ if (new_face.mNumVertices <= mNumVertices)
+ {
+ llassert(new_face.mNumIndices == mNumIndices);
+ swapData(new_face);
+ }
+
}
class LLVCacheTriangleData;
@@ -5808,14 +4857,14 @@ class LLVCacheVertexData
public:
S32 mIdx;
S32 mCacheTag;
- F32 mScore;
+ F64 mScore;
U32 mActiveTriangles;
std::vector<LLVCacheTriangleData*> mTriangles;
LLVCacheVertexData()
{
mCacheTag = -1;
- mScore = 0.f;
+ mScore = 0.0;
mActiveTriangles = 0;
mIdx = -1;
}
@@ -5825,13 +4874,13 @@ class LLVCacheTriangleData
{
public:
bool mActive;
- F32 mScore;
+ F64 mScore;
LLVCacheVertexData* mVertex[3];
LLVCacheTriangleData()
{
mActive = true;
- mScore = 0.f;
+ mScore = 0.0;
mVertex[0] = mVertex[1] = mVertex[2] = NULL;
}
@@ -5842,7 +4891,7 @@ public:
{
if (mVertex[i])
{
- llassert_always(mVertex[i]->mActiveTriangles > 0);
+ llassert(mVertex[i]->mActiveTriangles > 0);
mVertex[i]->mActiveTriangles--;
}
}
@@ -5854,20 +4903,20 @@ public:
}
};
-const F32 FindVertexScore_CacheDecayPower = 1.5f;
-const F32 FindVertexScore_LastTriScore = 0.75f;
-const F32 FindVertexScore_ValenceBoostScale = 2.0f;
-const F32 FindVertexScore_ValenceBoostPower = 0.5f;
+const F64 FindVertexScore_CacheDecayPower = 1.5;
+const F64 FindVertexScore_LastTriScore = 0.75;
+const F64 FindVertexScore_ValenceBoostScale = 2.0;
+const F64 FindVertexScore_ValenceBoostPower = 0.5;
const U32 MaxSizeVertexCache = 32;
+const F64 FindVertexScore_Scaler = 1.0/(MaxSizeVertexCache-3);
-F32 find_vertex_score(LLVCacheVertexData& data)
+F64 find_vertex_score(LLVCacheVertexData& data)
{
- if (data.mActiveTriangles == 0)
- { //no triangle references this vertex
- return -1.f;
- }
+ F64 score = -1.0;
- F32 score = 0.f;
+ if (data.mActiveTriangles >= 0)
+ {
+ score = 0.0;
S32 cache_idx = data.mCacheTag;
@@ -5883,15 +4932,15 @@ F32 find_vertex_score(LLVCacheVertexData& data)
}
else
{ //more points for being higher in the cache
- F32 scaler = 1.f/(MaxSizeVertexCache-3);
- score = 1.f-((cache_idx-3)*scaler);
- score = powf(score, FindVertexScore_CacheDecayPower);
+ score = 1.0-((cache_idx-3)*FindVertexScore_Scaler);
+ score = pow(score, FindVertexScore_CacheDecayPower);
}
}
//bonus points for having low valence
- F32 valence_boost = powf((F32)data.mActiveTriangles, -FindVertexScore_ValenceBoostPower);
+ F64 valence_boost = pow((F64)data.mActiveTriangles, -FindVertexScore_ValenceBoostPower);
score += FindVertexScore_ValenceBoostScale * valence_boost;
+ }
return score;
}
@@ -5998,32 +5047,44 @@ public:
void updateScores()
{
- for (U32 i = MaxSizeVertexCache; i < MaxSizeVertexCache+3; ++i)
- { //trailing 3 vertices aren't actually in the cache for scoring purposes
- if (mCache[i])
+ LLVCacheVertexData** data_iter = mCache+MaxSizeVertexCache;
+ LLVCacheVertexData** end_data = mCache+MaxSizeVertexCache+3;
+
+ while(data_iter != end_data)
+ {
+ LLVCacheVertexData* data = *data_iter++;
+ //trailing 3 vertices aren't actually in the cache for scoring purposes
+ if (data)
{
- mCache[i]->mCacheTag = -1;
+ data->mCacheTag = -1;
}
}
- for (U32 i = 0; i < MaxSizeVertexCache; ++i)
+ data_iter = mCache;
+ end_data = mCache+MaxSizeVertexCache;
+
+ while (data_iter != end_data)
{ //update scores of vertices in cache
- if (mCache[i])
+ LLVCacheVertexData* data = *data_iter++;
+ if (data)
{
- mCache[i]->mScore = find_vertex_score(*(mCache[i]));
- llassert_always(mCache[i]->mCacheTag == i);
+ data->mScore = find_vertex_score(*data);
}
}
mBestTriangle = NULL;
//update triangle scores
- for (U32 i = 0; i < MaxSizeVertexCache+3; ++i)
+ data_iter = mCache;
+ end_data = mCache+MaxSizeVertexCache+3;
+
+ while (data_iter != end_data)
{
- if (mCache[i])
+ LLVCacheVertexData* data = *data_iter++;
+ if (data)
{
- for (U32 j = 0; j < mCache[i]->mTriangles.size(); ++j)
+ for (std::vector<LLVCacheTriangleData*>::iterator iter = data->mTriangles.begin(), end_iter = data->mTriangles.end(); iter != end_iter; ++iter)
{
- LLVCacheTriangleData* tri = mCache[i]->mTriangles[j];
+ LLVCacheTriangleData* tri = *iter;
if (tri->mActive)
{
tri->mScore = tri->mVertex[0]->mScore;
@@ -6040,13 +5101,17 @@ public:
}
//knock trailing 3 vertices off the cache
- for (U32 i = MaxSizeVertexCache; i < MaxSizeVertexCache+3; ++i)
+ data_iter = mCache+MaxSizeVertexCache;
+ end_data = mCache+MaxSizeVertexCache+3;
+ while (data_iter != end_data)
{
- if (mCache[i])
+ LLVCacheVertexData* data = *data_iter;
+ if (data)
{
- llassert_always(mCache[i]->mCacheTag == -1);
- mCache[i] = NULL;
+ llassert(data->mCacheTag == -1);
+ *data_iter = NULL;
}
+ ++data_iter;
}
}
};
@@ -6056,6 +5121,9 @@ void LLVolumeFace::cacheOptimize()
{ //optimize for vertex cache according to Forsyth method:
// http://home.comcast.net/~tom_forsyth/papers/fast_vert_cache_opt.html
+ llassert(!mOptimized);
+ mOptimized = TRUE;
+
LLVCacheLRU cache;
if (mNumVertices < 3)
@@ -6101,12 +5169,14 @@ void LLVolumeFace::cacheOptimize()
for (U32 i = 0; i < mNumVertices; i++)
{ //initialize score values (no cache -- might try a fifo cache here)
- vertex_data[i].mScore = find_vertex_score(vertex_data[i]);
- vertex_data[i].mActiveTriangles = vertex_data[i].mTriangles.size();
+ LLVCacheVertexData& data = vertex_data[i];
+
+ data.mScore = find_vertex_score(data);
+ data.mActiveTriangles = data.mTriangles.size();
- for (U32 j = 0; j < vertex_data[i].mTriangles.size(); ++j)
+ for (U32 j = 0; j < data.mActiveTriangles; ++j)
{
- vertex_data[i].mTriangles[j]->mScore += vertex_data[i].mScore;
+ data.mTriangles[j]->mScore += data.mScore;
}
}
@@ -6176,10 +5246,10 @@ void LLVolumeFace::cacheOptimize()
//allocate space for new buffer
S32 num_verts = mNumVertices;
- LLVector4a* pos = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts);
- LLVector4a* norm = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts);
S32 size = ((num_verts*sizeof(LLVector2)) + 0xF) & ~0xF;
- LLVector2* tc = (LLVector2*) ll_aligned_malloc_16(size);
+ LLVector4a* pos = (LLVector4a*) ll_aligned_malloc(sizeof(LLVector4a)*2*num_verts+size, 64);
+ LLVector4a* norm = pos + num_verts;
+ LLVector2* tc = (LLVector2*) (norm + num_verts);
LLVector4a* wght = NULL;
if (mWeights)
@@ -6188,7 +5258,7 @@ void LLVolumeFace::cacheOptimize()
}
LLVector4a* binorm = NULL;
- if (mBinormals)
+ if (mTangents)
{
binorm = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts);
}
@@ -6213,9 +5283,9 @@ void LLVolumeFace::cacheOptimize()
{
wght[cur_idx] = mWeights[idx];
}
- if (mBinormals)
+ if (mTangents)
{
- binorm[cur_idx] = mBinormals[idx];
+ binorm[cur_idx] = mTangents[idx];
}
cur_idx++;
@@ -6227,17 +5297,16 @@ void LLVolumeFace::cacheOptimize()
mIndices[i] = new_idx[mIndices[i]];
}
- ll_aligned_free_16(mPositions);
- ll_aligned_free_16(mNormals);
- ll_aligned_free_16(mTexCoords);
+ ll_aligned_free(mPositions);
+ // DO NOT free mNormals and mTexCoords as they are part of mPositions buffer
ll_aligned_free_16(mWeights);
- ll_aligned_free_16(mBinormals);
+ ll_aligned_free_16(mTangents);
mPositions = pos;
mNormals = norm;
mTexCoords = tc;
mWeights = wght;
- mBinormals = binorm;
+ mTangents = binorm;
//std::string result = llformat("ACMR pre/post: %.3f/%.3f -- %d triangles %d breaks", pre_acmr, post_acmr, mNumIndices/3, breaks);
//llinfos << result << llendl;
@@ -6318,7 +5387,7 @@ void LLVolumeFace::swapData(LLVolumeFace& rhs)
{
llswap(rhs.mPositions, mPositions);
llswap(rhs.mNormals, mNormals);
- llswap(rhs.mBinormals, mBinormals);
+ llswap(rhs.mTangents, mTangents);
llswap(rhs.mTexCoords, mTexCoords);
llswap(rhs.mIndices,mIndices);
llswap(rhs.mNumVertices, mNumVertices);
@@ -6351,20 +5420,15 @@ void LerpPlanarVertex(LLVolumeFace::VertexData& v0,
BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build)
{
- LLMemType m1(LLMemType::MTYPE_VOLUME);
-
- const std::vector<LLVolume::Point>& mesh = volume->getMesh();
- const std::vector<LLVector3>& profile = volume->getProfile().mProfile;
+ LL_CHECK_MEMORY
+
+ const LLAlignedArray<LLVector4a,64>& mesh = volume->getMesh();
+ const LLAlignedArray<LLVector4a,64>& profile = volume->getProfile().mProfile;
S32 max_s = volume->getProfile().getTotal();
S32 max_t = volume->getPath().mPath.size();
// S32 i;
- S32 num_vertices = 0, num_indices = 0;
S32 grid_size = (profile.size()-1)/4;
- S32 quad_count = (grid_size * grid_size);
-
- num_vertices = (grid_size+1)*(grid_size+1);
- num_indices = quad_count * 4;
LLVector4a& min = mExtents[0];
LLVector4a& max = mExtents[1];
@@ -6384,9 +5448,9 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build)
VertexData baseVert;
for(S32 t = 0; t < 4; t++)
{
- corners[t].getPosition().load3( mesh[offset + (grid_size*t)].mPos.mV);
- corners[t].mTexCoord.mV[0] = profile[grid_size*t].mV[0]+0.5f;
- corners[t].mTexCoord.mV[1] = 0.5f - profile[grid_size*t].mV[1];
+ corners[t].getPosition().load4a(mesh[offset + (grid_size*t)].getF32ptr());
+ corners[t].mTexCoord.mV[0] = profile[grid_size*t][0]+0.5f;
+ corners[t].mTexCoord.mV[1] = 0.5f - profile[grid_size*t][1];
}
{
@@ -6414,22 +5478,11 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build)
corners[2].mTexCoord=swap;
}
- LLVector4a binormal;
-
- calc_binormal_from_triangle( binormal,
- corners[0].getPosition(), corners[0].mTexCoord,
- corners[1].getPosition(), corners[1].mTexCoord,
- corners[2].getPosition(), corners[2].mTexCoord);
-
- binormal.normalize3fast();
-
S32 size = (grid_size+1)*(grid_size+1);
resizeVertices(size);
- allocateBinormals(size);
-
+
LLVector4a* pos = (LLVector4a*) mPositions;
LLVector4a* norm = (LLVector4a*) mNormals;
- LLVector4a* binorm = (LLVector4a*) mBinormals;
LLVector2* tc = (LLVector2*) mTexCoords;
for(int gx = 0;gx<grid_size+1;gx++)
@@ -6448,8 +5501,7 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build)
*pos++ = newVert.getPosition();
*norm++ = baseVert.getNormal();
*tc++ = newVert.mTexCoord;
- *binorm++ = binormal;
-
+
if (gx == 0 && gy == 0)
{
min = newVert.getPosition();
@@ -6497,14 +5549,13 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build)
}
}
+ LL_CHECK_MEMORY
return TRUE;
}
BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)
{
- LLMemType m1(LLMemType::MTYPE_VOLUME);
-
if (!(mTypeMask & HOLLOW_MASK) &&
!(mTypeMask & OPEN_MASK) &&
((volume->getParams().getPathParams().getBegin()==0.0f)&&
@@ -6517,8 +5568,8 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)
S32 num_vertices = 0, num_indices = 0;
- const std::vector<LLVolume::Point>& mesh = volume->getMesh();
- const std::vector<LLVector3>& profile = volume->getProfile().mProfile;
+ const LLAlignedArray<LLVector4a,64>& mesh = volume->getMesh();
+ const LLAlignedArray<LLVector4a,64>& profile = volume->getProfile().mProfile;
// All types of caps have the same number of vertices and indices
num_vertices = profile.size();
@@ -6527,8 +5578,7 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)
if (!(mTypeMask & HOLLOW_MASK) && !(mTypeMask & OPEN_MASK))
{
resizeVertices(num_vertices+1);
- allocateBinormals(num_vertices+1);
-
+
if (!partial_build)
{
resizeIndices(num_indices+3);
@@ -6537,14 +5587,14 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)
else
{
resizeVertices(num_vertices);
- allocateBinormals(num_vertices);
-
if (!partial_build)
{
resizeIndices(num_indices);
}
}
+ LL_CHECK_MEMORY;
+
S32 max_s = volume->getProfile().getTotal();
S32 max_t = volume->getPath().mPath.size();
@@ -6572,67 +5622,79 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)
LLVector2* tc = (LLVector2*) mTexCoords;
LLVector4a* pos = (LLVector4a*) mPositions;
LLVector4a* norm = (LLVector4a*) mNormals;
- LLVector4a* binorm = (LLVector4a*) mBinormals;
-
+
// Copy the vertices into the array
- for (S32 i = 0; i < num_vertices; i++)
+
+ const LLVector4a* src = mesh.mArray+offset;
+ const LLVector4a* end = src+num_vertices;
+
+ min = *src;
+ max = min;
+
+
+ const LLVector4a* p = profile.mArray;
+
+ if (mTypeMask & TOP_MASK)
{
- if (mTypeMask & TOP_MASK)
+ min_uv.set((*p)[0]+0.5f,
+ (*p)[1]+0.5f);
+
+ max_uv = min_uv;
+
+ while(src < end)
{
- tc[i].mV[0] = profile[i].mV[0]+0.5f;
- tc[i].mV[1] = profile[i].mV[1]+0.5f;
+ tc->mV[0] = (*p)[0]+0.5f;
+ tc->mV[1] = (*p)[1]+0.5f;
+
+ llassert(src->isFinite3());
+ update_min_max(min,max,*src);
+ update_min_max(min_uv, max_uv, *tc);
+
+ *pos = *src;
+
+ llassert(pos->isFinite3());
+
+ ++p;
+ ++tc;
+ ++src;
+ ++pos;
+ }
}
else
{
+
+ min_uv.set((*p)[0]+0.5f,
+ 0.5f - (*p)[1]);
+ max_uv = min_uv;
+
+ while(src < end)
+ {
// Mirror for underside.
- tc[i].mV[0] = profile[i].mV[0]+0.5f;
- tc[i].mV[1] = 0.5f - profile[i].mV[1];
- }
+ tc->mV[0] = (*p)[0]+0.5f;
+ tc->mV[1] = 0.5f - (*p)[1];
+
+ llassert(src->isFinite3());
+ update_min_max(min,max,*src);
+ update_min_max(min_uv, max_uv, *tc);
- pos[i].load3(mesh[i + offset].mPos.mV);
+ *pos = *src;
- if (i == 0)
- {
- max = pos[i];
- min = max;
- min_uv = max_uv = tc[i];
- }
- else
- {
- update_min_max(min,max,pos[i]);
- update_min_max(min_uv, max_uv, tc[i]);
+ llassert(pos->isFinite3());
+
+ ++p;
+ ++tc;
+ ++src;
+ ++pos;
}
}
+ LL_CHECK_MEMORY
+
mCenter->setAdd(min, max);
mCenter->mul(0.5f);
cuv = (min_uv + max_uv)*0.5f;
- LLVector4a binormal;
- calc_binormal_from_triangle(binormal,
- *mCenter, cuv,
- pos[0], tc[0],
- pos[1], tc[1]);
- binormal.normalize3fast();
-
- LLVector4a normal;
- LLVector4a d0, d1;
-
-
- d0.setSub(*mCenter, pos[0]);
- d1.setSub(*mCenter, pos[1]);
-
- if (mTypeMask & TOP_MASK)
- {
- normal.setCross3(d0, d1);
- }
- else
- {
- normal.setCross3(d1, d0);
- }
-
- normal.normalize3fast();
VertexData vd;
vd.setPosition(*mCenter);
@@ -6640,17 +5702,13 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)
if (!(mTypeMask & HOLLOW_MASK) && !(mTypeMask & OPEN_MASK))
{
- pos[num_vertices] = *mCenter;
- tc[num_vertices] = cuv;
+ *pos++ = *mCenter;
+ *tc++ = cuv;
num_vertices++;
}
- for (S32 i = 0; i < num_vertices; i++)
- {
- binorm[i].load4a(binormal.getF32ptr());
- norm[i].load4a(normal.getF32ptr());
- }
-
+ LL_CHECK_MEMORY
+
if (partial_build)
{
return TRUE;
@@ -6669,33 +5727,38 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)
{
// Use the profile points instead of the mesh, since you want
// the un-transformed profile distances.
- LLVector3 p1 = profile[pt1];
- LLVector3 p2 = profile[pt2];
- LLVector3 pa = profile[pt1+1];
- LLVector3 pb = profile[pt2-1];
+ const LLVector4a& p1 = profile[pt1];
+ const LLVector4a& p2 = profile[pt2];
+ const LLVector4a& pa = profile[pt1+1];
+ const LLVector4a& pb = profile[pt2-1];
+
+ const F32* p1V = p1.getF32ptr();
+ const F32* p2V = p2.getF32ptr();
+ const F32* paV = pa.getF32ptr();
+ const F32* pbV = pb.getF32ptr();
- p1.mV[VZ] = 0.f;
- p2.mV[VZ] = 0.f;
- pa.mV[VZ] = 0.f;
- pb.mV[VZ] = 0.f;
+ //p1.mV[VZ] = 0.f;
+ //p2.mV[VZ] = 0.f;
+ //pa.mV[VZ] = 0.f;
+ //pb.mV[VZ] = 0.f;
// Use area of triangle to determine backfacing
F32 area_1a2, area_1ba, area_21b, area_2ab;
- area_1a2 = (p1.mV[0]*pa.mV[1] - pa.mV[0]*p1.mV[1]) +
- (pa.mV[0]*p2.mV[1] - p2.mV[0]*pa.mV[1]) +
- (p2.mV[0]*p1.mV[1] - p1.mV[0]*p2.mV[1]);
+ area_1a2 = (p1V[0]*paV[1] - paV[0]*p1V[1]) +
+ (paV[0]*p2V[1] - p2V[0]*paV[1]) +
+ (p2V[0]*p1V[1] - p1V[0]*p2V[1]);
- area_1ba = (p1.mV[0]*pb.mV[1] - pb.mV[0]*p1.mV[1]) +
- (pb.mV[0]*pa.mV[1] - pa.mV[0]*pb.mV[1]) +
- (pa.mV[0]*p1.mV[1] - p1.mV[0]*pa.mV[1]);
+ area_1ba = (p1V[0]*pbV[1] - pbV[0]*p1V[1]) +
+ (pbV[0]*paV[1] - paV[0]*pbV[1]) +
+ (paV[0]*p1V[1] - p1V[0]*paV[1]);
- area_21b = (p2.mV[0]*p1.mV[1] - p1.mV[0]*p2.mV[1]) +
- (p1.mV[0]*pb.mV[1] - pb.mV[0]*p1.mV[1]) +
- (pb.mV[0]*p2.mV[1] - p2.mV[0]*pb.mV[1]);
+ area_21b = (p2V[0]*p1V[1] - p1V[0]*p2V[1]) +
+ (p1V[0]*pbV[1] - pbV[0]*p1V[1]) +
+ (pbV[0]*p2V[1] - p2V[0]*pbV[1]);
- area_2ab = (p2.mV[0]*pa.mV[1] - pa.mV[0]*p2.mV[1]) +
- (pa.mV[0]*pb.mV[1] - pb.mV[0]*pa.mV[1]) +
- (pb.mV[0]*p2.mV[1] - p2.mV[0]*pb.mV[1]);
+ area_2ab = (p2V[0]*paV[1] - paV[0]*p2V[1]) +
+ (paV[0]*pbV[1] - pbV[0]*paV[1]) +
+ (pbV[0]*p2V[1] - p2V[0]*pbV[1]);
BOOL use_tri1a2 = TRUE;
BOOL tri_1a2 = TRUE;
@@ -6730,10 +5793,13 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)
}
else
{
- LLVector3 d1 = p1 - pa;
- LLVector3 d2 = p2 - pb;
+ LLVector4a d1;
+ d1.setSub(p1, pa);
+
+ LLVector4a d2;
+ d2.setSub(p2, pb);
- if (d1.magVecSquared() < d2.magVecSquared())
+ if (d1.dot3(d1) < d2.dot3(d2))
{
use_tri1a2 = TRUE;
}
@@ -6772,33 +5838,33 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)
{
// Use the profile points instead of the mesh, since you want
// the un-transformed profile distances.
- LLVector3 p1 = profile[pt1];
- LLVector3 p2 = profile[pt2];
- LLVector3 pa = profile[pt1+1];
- LLVector3 pb = profile[pt2-1];
+ const LLVector4a& p1 = profile[pt1];
+ const LLVector4a& p2 = profile[pt2];
+ const LLVector4a& pa = profile[pt1+1];
+ const LLVector4a& pb = profile[pt2-1];
- p1.mV[VZ] = 0.f;
- p2.mV[VZ] = 0.f;
- pa.mV[VZ] = 0.f;
- pb.mV[VZ] = 0.f;
+ const F32* p1V = p1.getF32ptr();
+ const F32* p2V = p2.getF32ptr();
+ const F32* paV = pa.getF32ptr();
+ const F32* pbV = pb.getF32ptr();
// Use area of triangle to determine backfacing
F32 area_1a2, area_1ba, area_21b, area_2ab;
- area_1a2 = (p1.mV[0]*pa.mV[1] - pa.mV[0]*p1.mV[1]) +
- (pa.mV[0]*p2.mV[1] - p2.mV[0]*pa.mV[1]) +
- (p2.mV[0]*p1.mV[1] - p1.mV[0]*p2.mV[1]);
+ area_1a2 = (p1V[0]*paV[1] - paV[0]*p1V[1]) +
+ (paV[0]*p2V[1] - p2V[0]*paV[1]) +
+ (p2V[0]*p1V[1] - p1V[0]*p2V[1]);
- area_1ba = (p1.mV[0]*pb.mV[1] - pb.mV[0]*p1.mV[1]) +
- (pb.mV[0]*pa.mV[1] - pa.mV[0]*pb.mV[1]) +
- (pa.mV[0]*p1.mV[1] - p1.mV[0]*pa.mV[1]);
+ area_1ba = (p1V[0]*pbV[1] - pbV[0]*p1V[1]) +
+ (pbV[0]*paV[1] - paV[0]*pbV[1]) +
+ (paV[0]*p1V[1] - p1V[0]*paV[1]);
- area_21b = (p2.mV[0]*p1.mV[1] - p1.mV[0]*p2.mV[1]) +
- (p1.mV[0]*pb.mV[1] - pb.mV[0]*p1.mV[1]) +
- (pb.mV[0]*p2.mV[1] - p2.mV[0]*pb.mV[1]);
+ area_21b = (p2V[0]*p1V[1] - p1V[0]*p2V[1]) +
+ (p1V[0]*pbV[1] - pbV[0]*p1V[1]) +
+ (pbV[0]*p2V[1] - p2V[0]*pbV[1]);
- area_2ab = (p2.mV[0]*pa.mV[1] - pa.mV[0]*p2.mV[1]) +
- (pa.mV[0]*pb.mV[1] - pb.mV[0]*pa.mV[1]) +
- (pb.mV[0]*p2.mV[1] - p2.mV[0]*pb.mV[1]);
+ area_2ab = (p2V[0]*paV[1] - paV[0]*p2V[1]) +
+ (paV[0]*pbV[1] - pbV[0]*paV[1]) +
+ (pbV[0]*p2V[1] - p2V[0]*pbV[1]);
BOOL use_tri1a2 = TRUE;
BOOL tri_1a2 = TRUE;
@@ -6833,10 +5899,12 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)
}
else
{
- LLVector3 d1 = p1 - pa;
- LLVector3 d2 = p2 - pb;
+ LLVector4a d1;
+ d1.setSub(p1,pa);
+ LLVector4a d2;
+ d2.setSub(p2,pb);
- if (d1.magVecSquared() < d2.magVecSquared())
+ if (d1.dot3(d1) < d2.dot3(d2))
{
use_tri1a2 = TRUE;
}
@@ -6885,65 +5953,70 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)
}
+
+ LLVector4a d0,d1;
+ LL_CHECK_MEMORY
+
+ d0.setSub(mPositions[mIndices[1]], mPositions[mIndices[0]]);
+ d1.setSub(mPositions[mIndices[2]], mPositions[mIndices[0]]);
+
+ LLVector4a normal;
+ normal.setCross3(d0,d1);
+
+ if (normal.dot3(normal).getF32() > F_APPROXIMATELY_ZERO)
+ {
+ normal.normalize3fast();
+ }
+ else
+ { //degenerate, make up a value
+ normal.set(0,0,1);
+ }
+
+ llassert(llfinite(normal.getF32ptr()[0]));
+ llassert(llfinite(normal.getF32ptr()[1]));
+ llassert(llfinite(normal.getF32ptr()[2]));
+
+ llassert(!llisnan(normal.getF32ptr()[0]));
+ llassert(!llisnan(normal.getF32ptr()[1]));
+ llassert(!llisnan(normal.getF32ptr()[2]));
+
+ for (S32 i = 0; i < num_vertices; i++)
+ {
+ norm[i].load4a(normal.getF32ptr());
+ }
+
return TRUE;
}
-void LLVolumeFace::createBinormals()
+void CalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVector4a *normal,
+ const LLVector2 *texcoord, U32 triangleCount, const U16* index_array, LLVector4a *tangent);
+
+void LLVolumeFace::createTangents()
{
- LLMemType m1(LLMemType::MTYPE_VOLUME);
-
- if (!mBinormals)
+ if (!mTangents)
{
- allocateBinormals(mNumVertices);
+ allocateTangents(mNumVertices);
- //generate binormals
- LLVector4a* pos = mPositions;
- LLVector2* tc = (LLVector2*) mTexCoords;
- LLVector4a* binorm = (LLVector4a*) mBinormals;
+ //generate tangents
+ //LLVector4a* pos = mPositions;
+ //LLVector2* tc = (LLVector2*) mTexCoords;
+ LLVector4a* binorm = (LLVector4a*) mTangents;
- LLVector4a* end = mBinormals+mNumVertices;
+ LLVector4a* end = mTangents+mNumVertices;
while (binorm < end)
{
(*binorm++).clear();
}
- binorm = mBinormals;
+ binorm = mTangents;
- for (U32 i = 0; i < mNumIndices/3; i++)
- { //for each triangle
- const U16& i0 = mIndices[i*3+0];
- const U16& i1 = mIndices[i*3+1];
- const U16& i2 = mIndices[i*3+2];
-
- //calculate binormal
- LLVector4a binormal;
- calc_binormal_from_triangle(binormal,
- pos[i0], tc[i0],
- pos[i1], tc[i1],
- pos[i2], tc[i2]);
-
-
- //add triangle normal to vertices
- binorm[i0].add(binormal);
- binorm[i1].add(binormal);
- binorm[i2].add(binormal);
-
- //even out quad contributions
- if (i % 2 == 0)
- {
- binorm[i2].add(binormal);
- }
- else
- {
- binorm[i1].add(binormal);
- }
- }
+ CalculateTangentArray(mNumVertices, mPositions, mNormals, mTexCoords, mNumIndices/3, mIndices, mTangents);
- //normalize binormals
+ //normalize tangents
for (U32 i = 0; i < mNumVertices; i++)
{
- binorm[i].normalize3fast();
+ //binorm[i].normalize3fast();
//bump map/planar projection code requires normals to be normalized
mNormals[i].normalize3fast();
}
@@ -6952,24 +6025,22 @@ void LLVolumeFace::createBinormals()
void LLVolumeFace::resizeVertices(S32 num_verts)
{
- ll_aligned_free_16(mPositions);
- ll_aligned_free_16(mNormals);
- ll_aligned_free_16(mBinormals);
- ll_aligned_free_16(mTexCoords);
+ ll_aligned_free(mPositions);
+ //DO NOT free mNormals and mTexCoords as they are part of mPositions buffer
+ ll_aligned_free_16(mTangents);
- mBinormals = NULL;
+ mTangents = NULL;
if (num_verts)
{
- mPositions = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts);
- assert_aligned(mPositions, 16);
- mNormals = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts);
- assert_aligned(mNormals, 16);
-
//pad texture coordinate block end to allow for QWORD reads
S32 size = ((num_verts*sizeof(LLVector2)) + 0xF) & ~0xF;
- mTexCoords = (LLVector2*) ll_aligned_malloc_16(size);
- assert_aligned(mTexCoords, 16);
+
+ mPositions = (LLVector4a*) ll_aligned_malloc(sizeof(LLVector4a)*2*num_verts+size, 64);
+ mNormals = mPositions+num_verts;
+ mTexCoords = (LLVector2*) (mNormals+num_verts);
+
+ ll_assert_aligned(mPositions, 64);
}
else
{
@@ -6979,6 +6050,7 @@ void LLVolumeFace::resizeVertices(S32 num_verts)
}
mNumVertices = num_verts;
+ mNumAllocatedVertices = num_verts;
}
void LLVolumeFace::pushVertex(const LLVolumeFace::VertexData& cv)
@@ -6989,23 +6061,42 @@ void LLVolumeFace::pushVertex(const LLVolumeFace::VertexData& cv)
void LLVolumeFace::pushVertex(const LLVector4a& pos, const LLVector4a& norm, const LLVector2& tc)
{
S32 new_verts = mNumVertices+1;
- S32 new_size = new_verts*16;
-// S32 old_size = mNumVertices*16;
+
+ if (new_verts > mNumAllocatedVertices)
+ {
+ //double buffer size on expansion
+ new_verts *= 2;
+
+ S32 new_tc_size = ((new_verts*8)+0xF) & ~0xF;
+ S32 old_tc_size = ((mNumVertices*8)+0xF) & ~0xF;
+
+ S32 old_vsize = mNumVertices*16;
+
+ S32 new_size = new_verts*16*2+new_tc_size;
+
+ LLVector4a* old_buf = mPositions;
+
+ mPositions = (LLVector4a*) ll_aligned_malloc(new_size, 64);
+ mNormals = mPositions+new_verts;
+ mTexCoords = (LLVector2*) (mNormals+new_verts);
//positions
- mPositions = (LLVector4a*) realloc(mPositions, new_size);
+ LLVector4a::memcpyNonAliased16((F32*) mPositions, (F32*) old_buf, old_vsize);
//normals
- mNormals = (LLVector4a*) realloc(mNormals, new_size);
-
+ LLVector4a::memcpyNonAliased16((F32*) mNormals, (F32*) (old_buf+mNumVertices), old_vsize);
+
//tex coords
- new_size = ((new_verts*8)+0xF) & ~0xF;
- mTexCoords = (LLVector2*) realloc(mTexCoords, new_size);
-
+ LLVector4a::memcpyNonAliased16((F32*) mTexCoords, (F32*) (old_buf+mNumVertices*2), old_tc_size);
- //just clear binormals
- ll_aligned_free_16(mBinormals);
- mBinormals = NULL;
+ //just clear tangents
+ ll_aligned_free_16(mTangents);
+ mTangents = NULL;
+ ll_aligned_free(old_buf);
+
+ mNumAllocatedVertices = new_verts;
+
+ }
mPositions[mNumVertices] = pos;
mNormals[mNumVertices] = norm;
@@ -7014,10 +6105,10 @@ void LLVolumeFace::pushVertex(const LLVector4a& pos, const LLVector4a& norm, con
mNumVertices++;
}
-void LLVolumeFace::allocateBinormals(S32 num_verts)
+void LLVolumeFace::allocateTangents(S32 num_verts)
{
- ll_aligned_free_16(mBinormals);
- mBinormals = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts);
+ ll_aligned_free_16(mTangents);
+ mTangents = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts);
}
void LLVolumeFace::allocateWeights(S32 num_verts)
@@ -7053,7 +6144,8 @@ void LLVolumeFace::pushIndex(const U16& idx)
S32 old_size = ((mNumIndices*2)+0xF) & ~0xF;
if (new_size != old_size)
{
- mIndices = (U16*) realloc(mIndices, new_size);
+ mIndices = (U16*) ll_aligned_realloc_16(mIndices, new_size, old_size);
+ ll_assert_aligned(mIndices,16);
}
mIndices[mNumIndices++] = idx;
@@ -7093,13 +6185,23 @@ void LLVolumeFace::appendFace(const LLVolumeFace& face, LLMatrix4& mat_in, LLMat
llerrs << "Cannot append empty face." << llendl;
}
+ U32 old_vsize = mNumVertices*16;
+ U32 new_vsize = new_count * 16;
+ U32 old_tcsize = (mNumVertices*sizeof(LLVector2)+0xF) & ~0xF;
+ U32 new_tcsize = (new_count*sizeof(LLVector2)+0xF) & ~0xF;
+ U32 new_size = new_vsize * 2 + new_tcsize;
+
//allocate new buffer space
- mPositions = (LLVector4a*) realloc(mPositions, new_count*sizeof(LLVector4a));
- assert_aligned(mPositions, 16);
- mNormals = (LLVector4a*) realloc(mNormals, new_count*sizeof(LLVector4a));
- assert_aligned(mNormals, 16);
- mTexCoords = (LLVector2*) realloc(mTexCoords, (new_count*sizeof(LLVector2)+0xF) & ~0xF);
- assert_aligned(mTexCoords, 16);
+ LLVector4a* old_buf = mPositions;
+ mPositions = (LLVector4a*) ll_aligned_malloc(new_size, 64);
+ mNormals = mPositions + new_count;
+ mTexCoords = (LLVector2*) (mNormals+new_count);
+
+ mNumAllocatedVertices = new_count;
+
+ LLVector4a::memcpyNonAliased16((F32*) mPositions, (F32*) old_buf, old_vsize);
+ LLVector4a::memcpyNonAliased16((F32*) mNormals, (F32*) (old_buf+mNumVertices), old_vsize);
+ LLVector4a::memcpyNonAliased16((F32*) mTexCoords, (F32*) (old_buf+mNumVertices*2), old_tcsize);
mNumVertices = new_count;
@@ -7145,7 +6247,7 @@ void LLVolumeFace::appendFace(const LLVolumeFace& face, LLMatrix4& mat_in, LLMat
new_count = mNumIndices + face.mNumIndices;
//allocate new index buffer
- mIndices = (U16*) realloc(mIndices, (new_count*sizeof(U16)+0xF) & ~0xF);
+ mIndices = (U16*) ll_aligned_realloc_16(mIndices, (new_count*sizeof(U16)+0xF) & ~0xF, (mNumIndices*sizeof(U16)+0xF) & ~0xF);
//get destination address into new index buffer
U16* dst_idx = mIndices+mNumIndices;
@@ -7159,8 +6261,7 @@ void LLVolumeFace::appendFace(const LLVolumeFace& face, LLMatrix4& mat_in, LLMat
BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)
{
- LLMemType m1(LLMemType::MTYPE_VOLUME);
-
+ LL_CHECK_MEMORY
BOOL flat = mTypeMask & FLAT_MASK;
U8 sculpt_type = volume->getParams().getSculptType();
@@ -7171,9 +6272,9 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)
S32 num_vertices, num_indices;
- const std::vector<LLVolume::Point>& mesh = volume->getMesh();
- const std::vector<LLVector3>& profile = volume->getProfile().mProfile;
- const std::vector<LLPath::PathPt>& path_data = volume->getPath().mPath;
+ const LLAlignedArray<LLVector4a,64>& mesh = volume->getMesh();
+ const LLAlignedArray<LLVector4a,64>& profile = volume->getProfile().mProfile;
+ const LLAlignedArray<LLPath::PathPt,64>& path_data = volume->getPath().mPath;
S32 max_s = volume->getProfile().getTotal();
@@ -7194,15 +6295,19 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)
}
}
+ LL_CHECK_MEMORY
+
LLVector4a* pos = (LLVector4a*) mPositions;
- LLVector4a* norm = (LLVector4a*) mNormals;
LLVector2* tc = (LLVector2*) mTexCoords;
- S32 begin_stex = llfloor( profile[mBeginS].mV[2] );
+ F32 begin_stex = floorf(profile[mBeginS][2]);
S32 num_s = ((mTypeMask & INNER_MASK) && (mTypeMask & FLAT_MASK) && mNumS > 2) ? mNumS/2 : mNumS;
S32 cur_vertex = 0;
+ S32 end_t = mBeginT+mNumT;
+ bool test = (mTypeMask & INNER_MASK) && (mTypeMask & FLAT_MASK) && mNumS > 2;
+
// Copy the vertices into the array
- for (t = mBeginT; t < mBeginT + mNumT; t++)
+ for (t = mBeginT; t < end_t; t++)
{
tt = path_data[t].mTexT;
for (s = 0; s < num_s; s++)
@@ -7223,11 +6328,11 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)
// Get s value for tex-coord.
if (!flat)
{
- ss = profile[mBeginS + s].mV[2];
+ ss = profile[mBeginS + s][2];
}
else
{
- ss = profile[mBeginS + s].mV[2] - begin_stex;
+ ss = profile[mBeginS + s][2] - begin_stex;
}
}
@@ -7247,20 +6352,15 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)
i = mBeginS + s + max_s*t;
}
- pos[cur_vertex].load3(mesh[i].mPos.mV);
- tc[cur_vertex] = LLVector2(ss,tt);
+ mesh[i].store4a((F32*)(pos+cur_vertex));
+ tc[cur_vertex].set(ss,tt);
- norm[cur_vertex].clear();
cur_vertex++;
- if ((mTypeMask & INNER_MASK) && (mTypeMask & FLAT_MASK) && mNumS > 2 && s > 0)
+ if (test && s > 0)
{
-
- pos[cur_vertex].load3(mesh[i].mPos.mV);
- tc[cur_vertex] = LLVector2(ss,tt);
-
- norm[cur_vertex].clear();
-
+ mesh[i].store4a((F32*)(pos+cur_vertex));
+ tc[cur_vertex].set(ss,tt);
cur_vertex++;
}
}
@@ -7277,28 +6377,63 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)
}
i = mBeginS + s + max_s*t;
- ss = profile[mBeginS + s].mV[2] - begin_stex;
- pos[cur_vertex].load3(mesh[i].mPos.mV);
- tc[cur_vertex] = LLVector2(ss,tt);
- norm[cur_vertex].clear();
+ ss = profile[mBeginS + s][2] - begin_stex;
+
+ mesh[i].store4a((F32*)(pos+cur_vertex));
+ tc[cur_vertex].set(ss,tt);
cur_vertex++;
}
- }
+ }
+ LL_CHECK_MEMORY
+ mCenter->clear();
+
+ LLVector4a* cur_pos = pos;
+ LLVector4a* end_pos = pos + mNumVertices;
//get bounding box for this side
- LLVector4a& face_min = mExtents[0];
- LLVector4a& face_max = mExtents[1];
- mCenter->clear();
+ LLVector4a face_min;
+ LLVector4a face_max;
+
+ face_min = face_max = *cur_pos++;
+
+ while (cur_pos < end_pos)
+ {
+ update_min_max(face_min, face_max, *cur_pos++);
+ }
+
+ mExtents[0] = face_min;
+ mExtents[1] = face_max;
+
+ U32 tc_count = mNumVertices;
+ if (tc_count%2 == 1)
+ { //odd number of texture coordinates, duplicate last entry to padded end of array
+ tc_count++;
+ mTexCoords[mNumVertices] = mTexCoords[mNumVertices-1];
+ }
- face_min = face_max = pos[0];
+ LLVector4a* cur_tc = (LLVector4a*) mTexCoords;
+ LLVector4a* end_tc = (LLVector4a*) (mTexCoords+tc_count);
- for (U32 i = 1; i < mNumVertices; ++i)
+ LLVector4a tc_min;
+ LLVector4a tc_max;
+
+ tc_min = tc_max = *cur_tc++;
+
+ while (cur_tc < end_tc)
{
- update_min_max(face_min, face_max, pos[i]);
+ update_min_max(tc_min, tc_max, *cur_tc++);
}
+ F32* minp = tc_min.getF32ptr();
+ F32* maxp = tc_max.getF32ptr();
+
+ mTexCoordExtents[0].mV[0] = llmin(minp[0], minp[2]);
+ mTexCoordExtents[0].mV[1] = llmin(minp[1], minp[3]);
+ mTexCoordExtents[1].mV[0] = llmax(maxp[0], maxp[2]);
+ mTexCoordExtents[1].mV[1] = llmax(maxp[1], maxp[3]);
+
mCenter->setAdd(face_min, face_max);
mCenter->mul(0.5f);
@@ -7363,39 +6498,119 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)
}
}
+ LL_CHECK_MEMORY
+
//clear normals
- for (U32 i = 0; i < mNumVertices; i++)
+ F32* dst = (F32*) mNormals;
+ F32* end = (F32*) (mNormals+mNumVertices);
+ LLVector4a zero = LLVector4a::getZero();
+
+ while (dst < end)
{
- mNormals[i].clear();
+ zero.store4a(dst);
+ dst += 4;
}
+ LL_CHECK_MEMORY
+
//generate normals
- for (U32 i = 0; i < mNumIndices/3; i++) //for each triangle
+ U32 count = mNumIndices/3;
+
+ LLVector4a* norm = mNormals;
+
+ static LLAlignedArray<LLVector4a, 64> triangle_normals;
+ triangle_normals.resize(count);
+ LLVector4a* output = triangle_normals.mArray;
+ LLVector4a* end_output = output+count;
+
+ U16* idx = mIndices;
+
+ while (output < end_output)
{
- const U16* idx = &(mIndices[i*3]);
+ LLVector4a b,v1,v2;
+ b.load4a((F32*) (pos+idx[0]));
+ v1.load4a((F32*) (pos+idx[1]));
+ v2.load4a((F32*) (pos+idx[2]));
+ //calculate triangle normal
+ LLVector4a a;
+
+ a.setSub(b, v1);
+ b.sub(v2);
+
- LLVector4a* v[] =
- { pos+idx[0], pos+idx[1], pos+idx[2] };
+ LLQuad& vector1 = *((LLQuad*) &v1);
+ LLQuad& vector2 = *((LLQuad*) &v2);
- LLVector4a* n[] =
- { norm+idx[0], norm+idx[1], norm+idx[2] };
+ LLQuad& amQ = *((LLQuad*) &a);
+ LLQuad& bmQ = *((LLQuad*) &b);
+
+ //v1.setCross3(t,v0);
+ //setCross3(const LLVector4a& a, const LLVector4a& b)
+ // Vectors are stored in memory in w, z, y, x order from high to low
+ // Set vector1 = { a[W], a[X], a[Z], a[Y] }
+ vector1 = _mm_shuffle_ps( amQ, amQ, _MM_SHUFFLE( 3, 0, 2, 1 ));
+ // Set vector2 = { b[W], b[Y], b[X], b[Z] }
+ vector2 = _mm_shuffle_ps( bmQ, bmQ, _MM_SHUFFLE( 3, 1, 0, 2 ));
+ // mQ = { a[W]*b[W], a[X]*b[Y], a[Z]*b[X], a[Y]*b[Z] }
+ vector2 = _mm_mul_ps( vector1, vector2 );
+ // vector3 = { a[W], a[Y], a[X], a[Z] }
+ amQ = _mm_shuffle_ps( amQ, amQ, _MM_SHUFFLE( 3, 1, 0, 2 ));
+ // vector4 = { b[W], b[X], b[Z], b[Y] }
+ bmQ = _mm_shuffle_ps( bmQ, bmQ, _MM_SHUFFLE( 3, 0, 2, 1 ));
+ // mQ = { 0, a[X]*b[Y] - a[Y]*b[X], a[Z]*b[X] - a[X]*b[Z], a[Y]*b[Z] - a[Z]*b[Y] }
+ vector1 = _mm_sub_ps( vector2, _mm_mul_ps( amQ, bmQ ));
+
+ llassert(v1.isFinite3());
+
+ v1.store4a((F32*) output);
- //calculate triangle normal
- LLVector4a a, b, c;
- a.setSub(*v[0], *v[1]);
- b.setSub(*v[0], *v[2]);
- c.setCross3(a,b);
+ output++;
+ idx += 3;
+ }
+
+ idx = mIndices;
+
+ LLVector4a* src = triangle_normals.mArray;
+
+ for (U32 i = 0; i < count; i++) //for each triangle
+ {
+ LLVector4a c;
+ c.load4a((F32*) (src++));
+
+ LLVector4a* n0p = norm+idx[0];
+ LLVector4a* n1p = norm+idx[1];
+ LLVector4a* n2p = norm+idx[2];
+
+ idx += 3;
- n[0]->add(c);
- n[1]->add(c);
- n[2]->add(c);
+ LLVector4a n0,n1,n2;
+ n0.load4a((F32*) n0p);
+ n1.load4a((F32*) n1p);
+ n2.load4a((F32*) n2p);
+ n0.add(c);
+ n1.add(c);
+ n2.add(c);
+
+ llassert(c.isFinite3());
+
//even out quad contributions
- n[i%2+1]->add(c);
+ switch (i%2+1)
+ {
+ case 0: n0.add(c); break;
+ case 1: n1.add(c); break;
+ case 2: n2.add(c); break;
+ };
+
+ n0.store4a((F32*) n0p);
+ n1.store4a((F32*) n1p);
+ n2.store4a((F32*) n2p);
}
+ LL_CHECK_MEMORY
+
// adjust normals based on wrapping and stitching
LLVector4a top;
@@ -7527,56 +6742,107 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)
}
+ LL_CHECK_MEMORY
+
return TRUE;
}
-// Finds binormal based on three vertices with texture coordinates.
-// Fills in dummy values if the triangle has degenerate texture coordinates.
-void calc_binormal_from_triangle(LLVector4a& binormal,
-
- const LLVector4a& pos0,
- const LLVector2& tex0,
- const LLVector4a& pos1,
- const LLVector2& tex1,
- const LLVector4a& pos2,
- const LLVector2& tex2)
-{
- LLVector4a rx0( pos0[VX], tex0.mV[VX], tex0.mV[VY] );
- LLVector4a rx1( pos1[VX], tex1.mV[VX], tex1.mV[VY] );
- LLVector4a rx2( pos2[VX], tex2.mV[VX], tex2.mV[VY] );
-
- LLVector4a ry0( pos0[VY], tex0.mV[VX], tex0.mV[VY] );
- LLVector4a ry1( pos1[VY], tex1.mV[VX], tex1.mV[VY] );
- LLVector4a ry2( pos2[VY], tex2.mV[VX], tex2.mV[VY] );
-
- LLVector4a rz0( pos0[VZ], tex0.mV[VX], tex0.mV[VY] );
- LLVector4a rz1( pos1[VZ], tex1.mV[VX], tex1.mV[VY] );
- LLVector4a rz2( pos2[VZ], tex2.mV[VX], tex2.mV[VY] );
-
- LLVector4a lhs, rhs;
-
- LLVector4a r0;
- lhs.setSub(rx0, rx1); rhs.setSub(rx0, rx2);
- r0.setCross3(lhs, rhs);
+//adapted from Lengyel, Eric. “Computing Tangent Space Basis Vectors for an Arbitrary Mesh”. Terathon Software 3D Graphics Library, 2001. http://www.terathon.com/code/tangent.html
+void CalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVector4a *normal,
+ const LLVector2 *texcoord, U32 triangleCount, const U16* index_array, LLVector4a *tangent)
+{
+ //LLVector4a *tan1 = new LLVector4a[vertexCount * 2];
+ LLVector4a* tan1 = (LLVector4a*) ll_aligned_malloc_16(vertexCount*2*sizeof(LLVector4a));
+
+ LLVector4a* tan2 = tan1 + vertexCount;
+
+ memset(tan1, 0, vertexCount*2*sizeof(LLVector4a));
+
+ for (U32 a = 0; a < triangleCount; a++)
+ {
+ U32 i1 = *index_array++;
+ U32 i2 = *index_array++;
+ U32 i3 = *index_array++;
+
+ const LLVector4a& v1 = vertex[i1];
+ const LLVector4a& v2 = vertex[i2];
+ const LLVector4a& v3 = vertex[i3];
+
+ const LLVector2& w1 = texcoord[i1];
+ const LLVector2& w2 = texcoord[i2];
+ const LLVector2& w3 = texcoord[i3];
+
+ const F32* v1ptr = v1.getF32ptr();
+ const F32* v2ptr = v2.getF32ptr();
+ const F32* v3ptr = v3.getF32ptr();
- LLVector4a r1;
- lhs.setSub(ry0, ry1); rhs.setSub(ry0, ry2);
- r1.setCross3(lhs, rhs);
-
- LLVector4a r2;
- lhs.setSub(rz0, rz1); rhs.setSub(rz0, rz2);
- r2.setCross3(lhs, rhs);
+ float x1 = v2ptr[0] - v1ptr[0];
+ float x2 = v3ptr[0] - v1ptr[0];
+ float y1 = v2ptr[1] - v1ptr[1];
+ float y2 = v3ptr[1] - v1ptr[1];
+ float z1 = v2ptr[2] - v1ptr[2];
+ float z2 = v3ptr[2] - v1ptr[2];
+
+ float s1 = w2.mV[0] - w1.mV[0];
+ float s2 = w3.mV[0] - w1.mV[0];
+ float t1 = w2.mV[1] - w1.mV[1];
+ float t2 = w3.mV[1] - w1.mV[1];
+
+ F32 rd = s1*t2-s2*t1;
+
+ float r = ((rd*rd) > FLT_EPSILON) ? (1.0f / rd)
+ : ((rd > 0.0f) ? 1024.f : -1024.f); //some made up large ratio for division by zero
+
+ llassert(llfinite(r));
+ llassert(!llisnan(r));
+
+ LLVector4a sdir((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r,
+ (t2 * z1 - t1 * z2) * r);
+ LLVector4a tdir((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r,
+ (s1 * z2 - s2 * z1) * r);
+
+ tan1[i1].add(sdir);
+ tan1[i2].add(sdir);
+ tan1[i3].add(sdir);
+
+ tan2[i1].add(tdir);
+ tan2[i2].add(tdir);
+ tan2[i3].add(tdir);
+ }
+
+ for (U32 a = 0; a < vertexCount; a++)
+ {
+ LLVector4a n = normal[a];
+
+ const LLVector4a& t = tan1[a];
+
+ LLVector4a ncrosst;
+ ncrosst.setCross3(n,t);
+
+ // Gram-Schmidt orthogonalize
+ n.mul(n.dot3(t).getF32());
+
+ LLVector4a tsubn;
+ tsubn.setSub(t,n);
+
+ if (tsubn.dot3(tsubn).getF32() > F_APPROXIMATELY_ZERO)
+ {
+ tsubn.normalize3fast();
+
+ // Calculate handedness
+ F32 handedness = ncrosst.dot3(tan2[a]).getF32() < 0.f ? -1.f : 1.f;
+
+ tsubn.getF32ptr()[3] = handedness;
- if( r0[VX] && r1[VX] && r2[VX] )
- {
- binormal.set(
- -r0[VZ] / r0[VX],
- -r1[VZ] / r1[VX],
- -r2[VZ] / r2[VX]);
- // binormal.normVec();
- }
- else
- {
- binormal.set( 0, 1 , 0 );
- }
+ tangent[a] = tsubn;
+ }
+ else
+ { //degenerate, make up a value
+ tangent[a].set(0,0,1,1);
+ }
+ }
+
+ ll_aligned_free_16(tan1);
}
+
+
diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h
index 76cf9de613..975227ea58 100644..100755
--- a/indra/llmath/llvolume.h
+++ b/indra/llmath/llvolume.h
@@ -37,7 +37,6 @@ class LLPath;
template <class T> class LLOctreeNode;
-class LLVector4a;
class LLVolumeFace;
class LLVolume;
class LLVolumeTriangle;
@@ -50,11 +49,15 @@ class LLVolumeTriangle;
#include "v3math.h"
#include "v3dmath.h"
#include "v4math.h"
+#include "llvector4a.h"
+#include "llmatrix4a.h"
#include "llquaternion.h"
#include "llstrider.h"
#include "v4coloru.h"
#include "llrefcount.h"
+#include "llpointer.h"
#include "llfile.h"
+#include "llalignedarray.h"
//============================================================================
@@ -707,16 +710,16 @@ public:
LLFaceID mFaceID;
};
- std::vector<LLVector3> mProfile;
- std::vector<LLVector2> mNormals;
+ LLAlignedArray<LLVector4a, 64> mProfile;
+ //LLAlignedArray<LLVector4a, 64> mNormals;
std::vector<Face> mFaces;
- std::vector<LLVector3> mEdgeNormals;
- std::vector<LLVector3> mEdgeCenters;
+
+ //LLAlignedArray<LLVector4a, 64> mEdgeNormals;
+ //LLAlignedArray<LLVector4a, 64> mEdgeCenters;
friend std::ostream& operator<<(std::ostream &s, const LLProfile &profile);
protected:
- void genNormals(const LLProfileParams& params);
static S32 getNumNGonPoints(const LLProfileParams& params, S32 sides, F32 offset=0.0f, F32 bevel = 0.0f, F32 ang_scale = 1.f, S32 split = 0);
void genNGon(const LLProfileParams& params, S32 sides, F32 offset=0.0f, F32 bevel = 0.0f, F32 ang_scale = 1.f, S32 split = 0);
@@ -740,13 +743,29 @@ protected:
class LLPath
{
public:
- struct PathPt
+ class PathPt
{
- LLVector3 mPos;
- LLVector2 mScale;
- LLQuaternion mRot;
+ public:
+ LLMatrix4a mRot;
+ LLVector4a mPos;
+
+ LLVector4a mScale;
F32 mTexT;
- PathPt() { mPos.setVec(0,0,0); mTexT = 0; mScale.setVec(0,0); mRot.loadIdentity(); }
+ F32 pad[3]; //for alignment
+ PathPt()
+ {
+ mPos.clear();
+ mTexT = 0;
+ mScale.clear();
+ mRot.setRows(LLVector4a(1,0,0,0),
+ LLVector4a(0,1,0,0),
+ LLVector4a(0,0,1,0));
+
+ //distinguished data in the pad for debugging
+ pad[0] = 3.14159f;
+ pad[1] = -3.14159f;
+ pad[2] = 0.585f;
+ }
};
public:
@@ -778,7 +797,7 @@ public:
friend std::ostream& operator<<(std::ostream &s, const LLPath &path);
public:
- std::vector<PathPt> mPath;
+ LLAlignedArray<PathPt, 64> mPath;
protected:
BOOL mOpen;
@@ -843,12 +862,12 @@ private:
public:
BOOL create(LLVolume* volume, BOOL partial_build = FALSE);
- void createBinormals();
+ void createTangents();
void appendFace(const LLVolumeFace& face, LLMatrix4& transform, LLMatrix4& normal_tranform);
void resizeVertices(S32 num_verts);
- void allocateBinormals(S32 num_verts);
+ void allocateTangents(S32 num_verts);
void allocateWeights(S32 num_verts);
void resizeIndices(S32 num_indices);
void fillFromLegacyData(std::vector<LLVolumeFace::VertexData>& v, std::vector<U16>& idx);
@@ -911,14 +930,19 @@ public:
LLVector2 mTexCoordExtents[2]; //minimum and maximum of texture coordinates of the face.
S32 mNumVertices;
+ S32 mNumAllocatedVertices;
S32 mNumIndices;
LLVector4a* mPositions;
LLVector4a* mNormals;
- LLVector4a* mBinormals;
+ LLVector4a* mTangents;
LLVector2* mTexCoords;
U16* mIndices;
+ //vertex buffer filled in by LLFace to cache this volume face geometry in vram
+ // (declared as a LLPointer to LLRefCount to avoid dependency on LLVertexBuffer)
+ mutable LLPointer<LLRefCount> mVertexBuffer;
+
std::vector<S32> mEdge;
//list of skin weights for rigged volumes
@@ -928,6 +952,9 @@ public:
LLOctreeNode<LLVolumeTriangle>* mOctree;
+ //whether or not face has been cache optimized
+ BOOL mOptimized;
+
private:
BOOL createUnCutCubeCap(LLVolume* volume, BOOL partial_build = FALSE);
BOOL createCap(LLVolume* volume, BOOL partial_build = FALSE);
@@ -942,11 +969,7 @@ protected:
~LLVolume(); // use unref
public:
- struct Point
- {
- LLVector3 mPos;
- };
-
+
struct FaceParams
{
LLFaceID mFaceID;
@@ -969,13 +992,13 @@ public:
const LLProfile& getProfile() const { return *mProfilep; }
LLPath& getPath() const { return *mPathp; }
void resizePath(S32 length);
- const std::vector<Point>& getMesh() const { return mMesh; }
- const LLVector3& getMeshPt(const U32 i) const { return mMesh[i].mPos; }
+ const LLAlignedArray<LLVector4a,64>& getMesh() const { return mMesh; }
+ const LLVector4a& getMeshPt(const U32 i) const { return mMesh[i]; }
void setDirty() { mPathp->setDirty(); mProfilep->setDirty(); }
void regen();
- void genBinormals(S32 face);
+ void genTangents(S32 face);
BOOL isConvex() const;
BOOL isCap(S32 face);
@@ -985,10 +1008,7 @@ public:
S32 getSculptLevel() const { return mSculptLevel; }
void setSculptLevel(S32 level) { mSculptLevel = level; }
- S32 *getTriangleIndices(U32 &num_indices) const;
-
- // returns number of triangle indeces required for path/profile mesh
- S32 getNumTriangleIndices() const;
+
static void getLoDTriangleCounts(const LLVolumeParams& params, S32* counts);
S32 getNumTriangles(S32* vcount = NULL) const;
@@ -1003,32 +1023,14 @@ public:
//get the face index of the face that intersects with the given line segment at the point
//closest to start. Moves end to the point of intersection. Returns -1 if no intersection.
//Line segment must be in volume space.
- S32 lineSegmentIntersect(const LLVector3& start, const LLVector3& end,
+ S32 lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
S32 face = -1, // which face to check, -1 = ALL_SIDES
- LLVector3* intersection = NULL, // return the intersection point
+ LLVector4a* intersection = NULL, // return the intersection point
LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
- LLVector3* normal = NULL, // return the surface normal at the intersection point
- LLVector3* bi_normal = NULL // return the surface bi-normal at the intersection point
+ LLVector4a* normal = NULL, // return the surface normal at the intersection point
+ LLVector4a* tangent = NULL // return the surface tangent at the intersection point
);
- S32 lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
- S32 face = 1,
- LLVector3* intersection = NULL,
- LLVector2* tex_coord = NULL,
- LLVector3* normal = NULL,
- LLVector3* bi_normal = NULL);
-
- // The following cleans up vertices and triangles,
- // getting rid of degenerate triangles and duplicate vertices,
- // and allocates new arrays with the clean data.
- static BOOL cleanupTriangleData( const S32 num_input_vertices,
- const std::vector<Point> &input_vertices,
- const S32 num_input_triangles,
- S32 *input_triangles,
- S32 &num_output_vertices,
- LLVector3 **output_vertices,
- S32 &num_output_triangles,
- S32 **output_triangles);
LLFaceID generateFaceMask();
BOOL isFaceMaskValid(LLFaceID face_mask);
@@ -1072,7 +1074,8 @@ public:
LLVolumeParams mParams;
LLPath *mPathp;
LLProfile *mProfilep;
- std::vector<Point> mMesh;
+ LLAlignedArray<LLVector4a,64> mMesh;
+
BOOL mGenerateSingleFace;
typedef std::vector<LLVolumeFace> face_list_t;
@@ -1087,21 +1090,12 @@ public:
std::ostream& operator<<(std::ostream &s, const LLVolumeParams &volume_params);
-void calc_binormal_from_triangle(
- LLVector4a& binormal,
- const LLVector4a& pos0,
- const LLVector2& tex0,
- const LLVector4a& pos1,
- const LLVector2& tex1,
- const LLVector4a& pos2,
- const LLVector2& tex2);
-
BOOL LLLineSegmentBoxIntersect(const F32* start, const F32* end, const F32* center, const F32* size);
BOOL LLLineSegmentBoxIntersect(const LLVector3& start, const LLVector3& end, const LLVector3& center, const LLVector3& size);
BOOL LLLineSegmentBoxIntersect(const LLVector4a& start, const LLVector4a& end, const LLVector4a& center, const LLVector4a& size);
-BOOL LLTriangleRayIntersect(const LLVector3& vert0, const LLVector3& vert1, const LLVector3& vert2, const LLVector3& orig, const LLVector3& dir,
- F32& intersection_a, F32& intersection_b, F32& intersection_t, BOOL two_sided);
+//BOOL LLTriangleRayIntersect(const LLVector3& vert0, const LLVector3& vert1, const LLVector3& vert2, const LLVector3& orig, const LLVector3& dir,
+// F32& intersection_a, F32& intersection_b, F32& intersection_t, BOOL two_sided);
BOOL LLTriangleRayIntersect(const LLVector4a& vert0, const LLVector4a& vert1, const LLVector4a& vert2, const LLVector4a& orig, const LLVector4a& dir,
F32& intersection_a, F32& intersection_b, F32& intersection_t);
diff --git a/indra/llmath/llvolumemgr.cpp b/indra/llmath/llvolumemgr.cpp
index c60b750088..9083273ee5 100644..100755
--- a/indra/llmath/llvolumemgr.cpp
+++ b/indra/llmath/llvolumemgr.cpp
@@ -26,7 +26,6 @@
#include "linden_common.h"
#include "llvolumemgr.h"
-#include "llmemtype.h"
#include "llvolume.h"
@@ -182,7 +181,6 @@ void LLVolumeMgr::insertGroup(LLVolumeLODGroup* volgroup)
// protected
LLVolumeLODGroup* LLVolumeMgr::createNewGroup(const LLVolumeParams& volume_params)
{
- LLMemType m1(LLMemType::MTYPE_VOLUME);
LLVolumeLODGroup* volgroup = new LLVolumeLODGroup(volume_params);
insertGroup(volgroup);
return volgroup;
@@ -297,7 +295,6 @@ LLVolume* LLVolumeLODGroup::refLOD(const S32 detail)
mRefs++;
if (mVolumeLODs[detail].isNull())
{
- LLMemType m1(LLMemType::MTYPE_VOLUME);
mVolumeLODs[detail] = new LLVolume(mVolumeParams, mDetailScales[detail]);
}
mLODRefs[detail]++;
diff --git a/indra/llmath/llvolumemgr.h b/indra/llmath/llvolumemgr.h
index c75906f675..c75906f675 100644..100755
--- a/indra/llmath/llvolumemgr.h
+++ b/indra/llmath/llvolumemgr.h
diff --git a/indra/llmath/llvolumeoctree.cpp b/indra/llmath/llvolumeoctree.cpp
index b5a935c2b5..0728b49c1f 100644..100755
--- a/indra/llmath/llvolumeoctree.cpp
+++ b/indra/llmath/llvolumeoctree.cpp
@@ -94,14 +94,14 @@ void LLVolumeOctreeListener::handleChildAddition(const LLOctreeNode<LLVolumeTria
LLOctreeTriangleRayIntersect::LLOctreeTriangleRayIntersect(const LLVector4a& start, const LLVector4a& dir,
const LLVolumeFace* face, F32* closest_t,
- LLVector3* intersection,LLVector2* tex_coord, LLVector3* normal, LLVector3* bi_normal)
+ LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent)
: mFace(face),
mStart(start),
mDir(dir),
mIntersection(intersection),
mTexCoord(tex_coord),
mNormal(normal),
- mBinormal(bi_normal),
+ mTangent(tangent),
mClosestT(closest_t),
mHitFace(false)
{
@@ -112,13 +112,7 @@ void LLOctreeTriangleRayIntersect::traverse(const LLOctreeNode<LLVolumeTriangle>
{
LLVolumeOctreeListener* vl = (LLVolumeOctreeListener*) node->getListener(0);
- /*const F32* start = mStart.getF32();
- const F32* end = mEnd.getF32();
- const F32* center = vl->mBounds[0].getF32();
- const F32* size = vl->mBounds[1].getF32();*/
-
- //if (LLLineSegmentBoxIntersect(mStart, mEnd, vl->mBounds[0], vl->mBounds[1]))
- if (LLLineSegmentBoxIntersect(mStart.getF32ptr(), mEnd.getF32ptr(), vl->mBounds[0].getF32ptr(), vl->mBounds[1].getF32ptr()))
+ if (LLLineSegmentBoxIntersect(mStart, mEnd, vl->mBounds[0], vl->mBounds[1]))
{
node->accept(this);
for (S32 i = 0; i < node->getChildCount(); ++i)
@@ -131,7 +125,7 @@ void LLOctreeTriangleRayIntersect::traverse(const LLOctreeNode<LLVolumeTriangle>
void LLOctreeTriangleRayIntersect::visit(const LLOctreeNode<LLVolumeTriangle>* node)
{
for (LLOctreeNode<LLVolumeTriangle>::const_element_iter iter =
- node->getData().begin(); iter != node->getData().end(); ++iter)
+ node->getDataBegin(); iter != node->getDataEnd(); ++iter)
{
const LLVolumeTriangle* tri = *iter;
@@ -152,34 +146,60 @@ void LLOctreeTriangleRayIntersect::visit(const LLOctreeNode<LLVolumeTriangle>* n
LLVector4a intersect = mDir;
intersect.mul(*mClosestT);
intersect.add(mStart);
- mIntersection->set(intersect.getF32ptr());
+ *mIntersection = intersect;
}
+ U32 idx0 = tri->mIndex[0];
+ U32 idx1 = tri->mIndex[1];
+ U32 idx2 = tri->mIndex[2];
if (mTexCoord != NULL)
{
LLVector2* tc = (LLVector2*) mFace->mTexCoords;
- *mTexCoord = ((1.f - a - b) * tc[tri->mIndex[0]] +
- a * tc[tri->mIndex[1]] +
- b * tc[tri->mIndex[2]]);
+ *mTexCoord = ((1.f - a - b) * tc[idx0] +
+ a * tc[idx1] +
+ b * tc[idx2]);
}
if (mNormal != NULL)
{
- LLVector4* norm = (LLVector4*) mFace->mNormals;
-
- *mNormal = ((1.f - a - b) * LLVector3(norm[tri->mIndex[0]]) +
- a * LLVector3(norm[tri->mIndex[1]]) +
- b * LLVector3(norm[tri->mIndex[2]]));
+ LLVector4a* norm = mFace->mNormals;
+
+ LLVector4a n1,n2,n3;
+ n1 = norm[idx0];
+ n1.mul(1.f-a-b);
+
+ n2 = norm[idx1];
+ n2.mul(a);
+
+ n3 = norm[idx2];
+ n3.mul(b);
+
+ n1.add(n2);
+ n1.add(n3);
+
+ *mNormal = n1;
}
- if (mBinormal != NULL)
+ if (mTangent != NULL)
{
- LLVector4* binormal = (LLVector4*) mFace->mBinormals;
- *mBinormal = ((1.f - a - b) * LLVector3(binormal[tri->mIndex[0]]) +
- a * LLVector3(binormal[tri->mIndex[1]]) +
- b * LLVector3(binormal[tri->mIndex[2]]));
+ LLVector4a* tangents = mFace->mTangents;
+
+ LLVector4a t1,t2,t3;
+ t1 = tangents[idx0];
+ t1.mul(1.f-a-b);
+
+ t2 = tangents[idx1];
+ t2.mul(a);
+
+ t3 = tangents[idx2];
+ t3.mul(b);
+
+ t1.add(t2);
+ t1.add(t3);
+
+ *mTangent = t1;
}
}
}
@@ -236,8 +256,8 @@ void LLVolumeOctreeValidate::visit(const LLOctreeNode<LLVolumeTriangle>* branch)
}
//children fit, check data
- for (LLOctreeNode<LLVolumeTriangle>::const_element_iter iter = branch->getData().begin();
- iter != branch->getData().end(); ++iter)
+ for (LLOctreeNode<LLVolumeTriangle>::const_element_iter iter = branch->getDataBegin();
+ iter != branch->getDataEnd(); ++iter)
{
const LLVolumeTriangle* tri = *iter;
diff --git a/indra/llmath/llvolumeoctree.h b/indra/llmath/llvolumeoctree.h
index 688d91dc40..80d6ced36d 100644..100755
--- a/indra/llmath/llvolumeoctree.h
+++ b/indra/llmath/llvolumeoctree.h
@@ -37,9 +37,19 @@
class LLVolumeTriangle : public LLRefCount
{
public:
+ void* operator new(size_t size)
+ {
+ return ll_aligned_malloc_16(size);
+ }
+
+ void operator delete(void* ptr)
+ {
+ ll_aligned_free_16(ptr);
+ }
+
LLVolumeTriangle()
{
-
+ mBinIndex = -1;
}
LLVolumeTriangle(const LLVolumeTriangle& rhs)
@@ -58,21 +68,38 @@ public:
}
- LLVector4a mPositionGroup;
+ LL_ALIGN_16(LLVector4a mPositionGroup);
const LLVector4a* mV[3];
U16 mIndex[3];
F32 mRadius;
+ mutable S32 mBinIndex;
+
virtual const LLVector4a& getPositionGroup() const;
virtual const F32& getBinRadius() const;
+
+ S32 getBinIndex() const { return mBinIndex; }
+ void setBinIndex(S32 idx) const { mBinIndex = idx; }
+
+
};
class LLVolumeOctreeListener : public LLOctreeListener<LLVolumeTriangle>
{
public:
+ void* operator new(size_t size)
+ {
+ return ll_aligned_malloc_16(size);
+ }
+
+ void operator delete(void* ptr)
+ {
+ ll_aligned_free_16(ptr);
+ }
+
LLVolumeOctreeListener(LLOctreeNode<LLVolumeTriangle>* node);
~LLVolumeOctreeListener();
@@ -99,8 +126,8 @@ public:
public:
- LLVector4a mBounds[2]; // bounding box (center, size) of this node and all its children (tight fit to objects)
- LLVector4a mExtents[2]; // extents (min, max) of this node and all its children
+ LL_ALIGN_16(LLVector4a mBounds[2]); // bounding box (center, size) of this node and all its children (tight fit to objects)
+ LL_ALIGN_16(LLVector4a mExtents[2]); // extents (min, max) of this node and all its children
};
class LLOctreeTriangleRayIntersect : public LLOctreeTraveler<LLVolumeTriangle>
@@ -110,16 +137,16 @@ public:
LLVector4a mStart;
LLVector4a mDir;
LLVector4a mEnd;
- LLVector3* mIntersection;
+ LLVector4a* mIntersection;
LLVector2* mTexCoord;
- LLVector3* mNormal;
- LLVector3* mBinormal;
+ LLVector4a* mNormal;
+ LLVector4a* mTangent;
F32* mClosestT;
bool mHitFace;
LLOctreeTriangleRayIntersect(const LLVector4a& start, const LLVector4a& dir,
const LLVolumeFace* face, F32* closest_t,
- LLVector3* intersection,LLVector2* tex_coord, LLVector3* normal, LLVector3* bi_normal);
+ LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent);
void traverse(const LLOctreeNode<LLVolumeTriangle>* node);
diff --git a/indra/llmath/m3math.cpp b/indra/llmath/m3math.cpp
index 802ddb9e57..802ddb9e57 100644..100755
--- a/indra/llmath/m3math.cpp
+++ b/indra/llmath/m3math.cpp
diff --git a/indra/llmath/m3math.h b/indra/llmath/m3math.h
index 2be5452f8d..2be5452f8d 100644..100755
--- a/indra/llmath/m3math.h
+++ b/indra/llmath/m3math.h
diff --git a/indra/llmath/m4math.cpp b/indra/llmath/m4math.cpp
index 6a1b4143cf..6a1b4143cf 100644..100755
--- a/indra/llmath/m4math.cpp
+++ b/indra/llmath/m4math.cpp
diff --git a/indra/llmath/m4math.h b/indra/llmath/m4math.h
index a7dce10397..a7dce10397 100644..100755
--- a/indra/llmath/m4math.h
+++ b/indra/llmath/m4math.h
diff --git a/indra/llmath/raytrace.cpp b/indra/llmath/raytrace.cpp
index f38fe49bcb..f38fe49bcb 100644..100755
--- a/indra/llmath/raytrace.cpp
+++ b/indra/llmath/raytrace.cpp
diff --git a/indra/llmath/raytrace.h b/indra/llmath/raytrace.h
index 2d32af0c86..2d32af0c86 100644..100755
--- a/indra/llmath/raytrace.h
+++ b/indra/llmath/raytrace.h
diff --git a/indra/llmath/tests/alignment_test.cpp b/indra/llmath/tests/alignment_test.cpp
new file mode 100755
index 0000000000..5ee3c45502
--- /dev/null
+++ b/indra/llmath/tests/alignment_test.cpp
@@ -0,0 +1,141 @@
+/**
+ * @file v3dmath_test.cpp
+ * @author Vir
+ * @date 2011-12
+ * @brief v3dmath test cases.
+ *
+ * $LicenseInfo:firstyear=2011&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+// Tests related to allocating objects with alignment constraints, particularly for SSE support.
+
+#include "linden_common.h"
+#include "../test/lltut.h"
+#include "../llmath.h"
+#include "../llsimdmath.h"
+#include "../llvector4a.h"
+
+namespace tut
+{
+
+#define is_aligned(ptr,alignment) ((reinterpret_cast<uintptr_t>(ptr))%(alignment)==0)
+#define is_aligned_relative(ptr,base_ptr,alignment) ((reinterpret_cast<uintptr_t>(ptr)-reinterpret_cast<uintptr_t>(base_ptr))%(alignment)==0)
+
+struct alignment_test {};
+
+typedef test_group<alignment_test> alignment_test_t;
+typedef alignment_test_t::object alignment_test_object_t;
+tut::alignment_test_t tut_alignment_test("LLAlignment");
+
+LL_ALIGN_PREFIX(16)
+class MyVector4a
+{
+public:
+ void* operator new(size_t size)
+ {
+ return ll_aligned_malloc_16(size);
+ }
+
+ void operator delete(void *p)
+ {
+ ll_aligned_free_16(p);
+ }
+
+ void* operator new[](size_t count)
+ { // try to allocate count bytes for an array
+ return ll_aligned_malloc_16(count);
+ }
+
+ void operator delete[](void *p)
+ {
+ ll_aligned_free_16(p);
+ }
+
+ LLQuad mQ;
+} LL_ALIGN_POSTFIX(16);
+
+
+// Verify that aligned allocators perform as advertised.
+template<> template<>
+void alignment_test_object_t::test<1>()
+{
+# ifdef LL_DEBUG
+// skip("This test fails on Windows when compiled in debug mode.");
+# endif
+
+ const int num_tests = 7;
+ void *align_ptr;
+ for (int i=0; i<num_tests; i++)
+ {
+ align_ptr = ll_aligned_malloc_16(sizeof(MyVector4a));
+ ensure("ll_aligned_malloc_16 failed", is_aligned(align_ptr,16));
+
+ align_ptr = ll_aligned_realloc_16(align_ptr,2*sizeof(MyVector4a), sizeof(MyVector4a));
+ ensure("ll_aligned_realloc_16 failed", is_aligned(align_ptr,16));
+
+ ll_aligned_free_16(align_ptr);
+
+ align_ptr = ll_aligned_malloc_32(sizeof(MyVector4a));
+ ensure("ll_aligned_malloc_32 failed", is_aligned(align_ptr,32));
+ ll_aligned_free_32(align_ptr);
+ }
+}
+
+// In-place allocation of objects and arrays.
+template<> template<>
+void alignment_test_object_t::test<2>()
+{
+ MyVector4a vec1;
+ ensure("LLAlignment vec1 unaligned", is_aligned(&vec1,16));
+
+ MyVector4a veca[12];
+ ensure("LLAlignment veca unaligned", is_aligned(veca,16));
+}
+
+// Heap allocation of objects and arrays.
+template<> template<>
+void alignment_test_object_t::test<3>()
+{
+# ifdef LL_DEBUG
+// skip("This test fails on Windows when compiled in debug mode.");
+# endif
+
+ const int ARR_SIZE = 7;
+ for(int i=0; i<ARR_SIZE; i++)
+ {
+ MyVector4a *vecp = new MyVector4a;
+ ensure("LLAlignment vecp unaligned", is_aligned(vecp,16));
+ delete vecp;
+ }
+
+ MyVector4a *veca = new MyVector4a[ARR_SIZE];
+ //std::cout << "veca base is " << (S32) veca << std::endl;
+ ensure("LLAligment veca base", is_aligned(veca,16));
+ for(int i=0; i<ARR_SIZE; i++)
+ {
+ std::cout << "veca[" << i << "]" << std::endl;
+ ensure("LLAlignment veca member unaligned", is_aligned(&veca[i],16));
+ }
+ delete [] veca;
+}
+
+}
diff --git a/indra/llmath/tests/llbbox_test.cpp b/indra/llmath/tests/llbbox_test.cpp
index fd0dbb58fc..fd0dbb58fc 100644..100755
--- a/indra/llmath/tests/llbbox_test.cpp
+++ b/indra/llmath/tests/llbbox_test.cpp
diff --git a/indra/llmath/tests/llbboxlocal_test.cpp b/indra/llmath/tests/llbboxlocal_test.cpp
index f31e4126c4..f31e4126c4 100644..100755
--- a/indra/llmath/tests/llbboxlocal_test.cpp
+++ b/indra/llmath/tests/llbboxlocal_test.cpp
diff --git a/indra/llmath/tests/llmodularmath_test.cpp b/indra/llmath/tests/llmodularmath_test.cpp
index 063d3ef79f..063d3ef79f 100644..100755
--- a/indra/llmath/tests/llmodularmath_test.cpp
+++ b/indra/llmath/tests/llmodularmath_test.cpp
diff --git a/indra/llmath/tests/llquaternion_test.cpp b/indra/llmath/tests/llquaternion_test.cpp
index e69010b2d6..e69010b2d6 100644..100755
--- a/indra/llmath/tests/llquaternion_test.cpp
+++ b/indra/llmath/tests/llquaternion_test.cpp
diff --git a/indra/llmath/tests/llrect_test.cpp b/indra/llmath/tests/llrect_test.cpp
index d740173e69..d740173e69 100644..100755
--- a/indra/llmath/tests/llrect_test.cpp
+++ b/indra/llmath/tests/llrect_test.cpp
diff --git a/indra/llmath/tests/m3math_test.cpp b/indra/llmath/tests/m3math_test.cpp
index 1ca2b005d9..1ca2b005d9 100644..100755
--- a/indra/llmath/tests/m3math_test.cpp
+++ b/indra/llmath/tests/m3math_test.cpp
diff --git a/indra/llmath/tests/mathmisc_test.cpp b/indra/llmath/tests/mathmisc_test.cpp
index 91a2e6c009..91a2e6c009 100644..100755
--- a/indra/llmath/tests/mathmisc_test.cpp
+++ b/indra/llmath/tests/mathmisc_test.cpp
diff --git a/indra/llmath/tests/v2math_test.cpp b/indra/llmath/tests/v2math_test.cpp
index 4d6a2eca93..4d6a2eca93 100644..100755
--- a/indra/llmath/tests/v2math_test.cpp
+++ b/indra/llmath/tests/v2math_test.cpp
diff --git a/indra/llmath/tests/v3color_test.cpp b/indra/llmath/tests/v3color_test.cpp
index 29d1c483ab..29d1c483ab 100644..100755
--- a/indra/llmath/tests/v3color_test.cpp
+++ b/indra/llmath/tests/v3color_test.cpp
diff --git a/indra/llmath/tests/v3dmath_test.cpp b/indra/llmath/tests/v3dmath_test.cpp
index 20b26faa12..20b26faa12 100644..100755
--- a/indra/llmath/tests/v3dmath_test.cpp
+++ b/indra/llmath/tests/v3dmath_test.cpp
diff --git a/indra/llmath/tests/v3math_test.cpp b/indra/llmath/tests/v3math_test.cpp
index e4ae1c10ef..e4ae1c10ef 100644..100755
--- a/indra/llmath/tests/v3math_test.cpp
+++ b/indra/llmath/tests/v3math_test.cpp
diff --git a/indra/llmath/tests/v4color_test.cpp b/indra/llmath/tests/v4color_test.cpp
index d7eec3c87f..d7eec3c87f 100644..100755
--- a/indra/llmath/tests/v4color_test.cpp
+++ b/indra/llmath/tests/v4color_test.cpp
diff --git a/indra/llmath/tests/v4coloru_test.cpp b/indra/llmath/tests/v4coloru_test.cpp
index 128f6f3564..128f6f3564 100644..100755
--- a/indra/llmath/tests/v4coloru_test.cpp
+++ b/indra/llmath/tests/v4coloru_test.cpp
diff --git a/indra/llmath/tests/v4math_test.cpp b/indra/llmath/tests/v4math_test.cpp
index 191ac864df..191ac864df 100644..100755
--- a/indra/llmath/tests/v4math_test.cpp
+++ b/indra/llmath/tests/v4math_test.cpp
diff --git a/indra/llmath/tests/xform_test.cpp b/indra/llmath/tests/xform_test.cpp
index 49870eef3c..49870eef3c 100644..100755
--- a/indra/llmath/tests/xform_test.cpp
+++ b/indra/llmath/tests/xform_test.cpp
diff --git a/indra/llmath/v2math.cpp b/indra/llmath/v2math.cpp
index a0cd642853..a0cd642853 100644..100755
--- a/indra/llmath/v2math.cpp
+++ b/indra/llmath/v2math.cpp
diff --git a/indra/llmath/v2math.h b/indra/llmath/v2math.h
index 8d5db96f5e..8d5db96f5e 100644..100755
--- a/indra/llmath/v2math.h
+++ b/indra/llmath/v2math.h
diff --git a/indra/llmath/v3color.cpp b/indra/llmath/v3color.cpp
index d38f48b11e..d38f48b11e 100644..100755
--- a/indra/llmath/v3color.cpp
+++ b/indra/llmath/v3color.cpp
diff --git a/indra/llmath/v3color.h b/indra/llmath/v3color.h
index 56cb2ae73e..daf3a6857b 100644..100755
--- a/indra/llmath/v3color.h
+++ b/indra/llmath/v3color.h
@@ -33,6 +33,7 @@ class LLVector4;
#include "llerror.h"
#include "llmath.h"
#include "llsd.h"
+#include <string.h>
// LLColor3 = |r g b|
diff --git a/indra/llmath/v3dmath.cpp b/indra/llmath/v3dmath.cpp
index a50cb3c6ca..a50cb3c6ca 100644..100755
--- a/indra/llmath/v3dmath.cpp
+++ b/indra/llmath/v3dmath.cpp
diff --git a/indra/llmath/v3dmath.h b/indra/llmath/v3dmath.h
index 578dcdc8ea..578dcdc8ea 100644..100755
--- a/indra/llmath/v3dmath.h
+++ b/indra/llmath/v3dmath.h
diff --git a/indra/llmath/v3math.cpp b/indra/llmath/v3math.cpp
index e7107dee16..e7107dee16 100644..100755
--- a/indra/llmath/v3math.cpp
+++ b/indra/llmath/v3math.cpp
diff --git a/indra/llmath/v3math.h b/indra/llmath/v3math.h
index 0432aeba4c..0432aeba4c 100644..100755
--- a/indra/llmath/v3math.h
+++ b/indra/llmath/v3math.h
diff --git a/indra/llmath/v4color.cpp b/indra/llmath/v4color.cpp
index 81ac62be56..81ac62be56 100644..100755
--- a/indra/llmath/v4color.cpp
+++ b/indra/llmath/v4color.cpp
diff --git a/indra/llmath/v4color.h b/indra/llmath/v4color.h
index b047f86e6e..8c8c315808 100644..100755
--- a/indra/llmath/v4color.h
+++ b/indra/llmath/v4color.h
@@ -50,7 +50,7 @@ class LLColor4
LLColor4(F32 r, F32 g, F32 b); // Initializes LLColor4 to (r, g, b, 1)
LLColor4(F32 r, F32 g, F32 b, F32 a); // Initializes LLColor4 to (r. g, b, a)
LLColor4(U32 clr); // Initializes LLColor4 to (r=clr>>24, etc))
- LLColor4(const F32 *vec); // Initializes LLColor4 to (vec[0]. vec[1], vec[2], 1)
+ LLColor4(const F32 *vec); // Initializes LLColor4 to (vec[0]. vec[1], vec[2], vec[3])
LLColor4(const LLColor3 &vec, F32 a = 1.f); // Initializes LLColor4 to (vec, a)
explicit LLColor4(const LLSD& sd);
explicit LLColor4(const LLColor4U& color4u); // "explicit" to avoid automatic conversion
diff --git a/indra/llmath/v4coloru.cpp b/indra/llmath/v4coloru.cpp
index f1a2518cf3..f1a2518cf3 100644..100755
--- a/indra/llmath/v4coloru.cpp
+++ b/indra/llmath/v4coloru.cpp
diff --git a/indra/llmath/v4coloru.h b/indra/llmath/v4coloru.h
index 12da7e2dd7..12da7e2dd7 100644..100755
--- a/indra/llmath/v4coloru.h
+++ b/indra/llmath/v4coloru.h
diff --git a/indra/llmath/v4math.cpp b/indra/llmath/v4math.cpp
index 2782cf2966..2782cf2966 100644..100755
--- a/indra/llmath/v4math.cpp
+++ b/indra/llmath/v4math.cpp
diff --git a/indra/llmath/v4math.h b/indra/llmath/v4math.h
index 623c8b2003..623c8b2003 100644..100755
--- a/indra/llmath/v4math.h
+++ b/indra/llmath/v4math.h
diff --git a/indra/llmath/xform.cpp b/indra/llmath/xform.cpp
index b75aec6a27..b75aec6a27 100644..100755
--- a/indra/llmath/xform.cpp
+++ b/indra/llmath/xform.cpp
diff --git a/indra/llmath/xform.h b/indra/llmath/xform.h
index 1b50749b3e..1b50749b3e 100644..100755
--- a/indra/llmath/xform.h
+++ b/indra/llmath/xform.h
diff --git a/indra/llmessage/CMakeLists.txt b/indra/llmessage/CMakeLists.txt
index d98781e9e6..d193e367eb 100644..100755
--- a/indra/llmessage/CMakeLists.txt
+++ b/indra/llmessage/CMakeLists.txt
@@ -218,6 +218,9 @@ add_library (llmessage ${llmessage_SOURCE_FILES})
target_link_libraries(
llmessage
${CURL_LIBRARIES}
+ ${LLCOMMON_LIBRARIES}
+ ${LLVFS_LIBRARES}
+ ${LLMATH_LIBRARIES}
${CARES_LIBRARIES}
${OPENSSL_LIBRARIES}
${CRYPTO_LIBRARIES}
diff --git a/indra/llmessage/llares.cpp b/indra/llmessage/llares.cpp
index 5a67035ed1..7f74247a13 100644..100755
--- a/indra/llmessage/llares.cpp
+++ b/indra/llmessage/llares.cpp
@@ -99,8 +99,7 @@ void LLAres::QueryResponder::queryError(int code)
LLAres::LLAres() :
chan_(NULL),
- mInitSuccess(false),
- mListener(new LLAresListener(this))
+ mInitSuccess(false)
{
if (ares_library_init( ARES_LIB_INIT_ALL ) != ARES_SUCCESS ||
ares_init(&chan_) != ARES_SUCCESS)
@@ -109,6 +108,8 @@ LLAres::LLAres() :
return;
}
+ mListener = boost::shared_ptr< LLAresListener >(new LLAresListener(this));
+
mInitSuccess = true;
}
@@ -161,12 +162,26 @@ void LLAres::getSrvRecords(const std::string &name, SrvResponder *resp)
}
void LLAres::rewriteURI(const std::string &uri, UriRewriteResponder *resp)
-{
- llinfos << "Rewriting " << uri << llendl;
+{
+ if (resp && uri.size())
+ {
+ LLURI* pURI = new LLURI(uri);
+
+ resp->mUri = *pURI;
+
+ delete pURI;
+
+ if (!resp->mUri.scheme().size() || !resp->mUri.hostName().size())
+ {
+ return;
+ }
+
+ //llinfos << "LLAres::rewriteURI (" << uri << ") search: '" << "_" + resp->mUri.scheme() + "._tcp." + resp->mUri.hostName() << "'" << llendl;
- resp->mUri = LLURI(uri);
- search("_" + resp->mUri.scheme() + "._tcp." + resp->mUri.hostName(),
- RES_SRV, resp);
+ search("_" + resp->mUri.scheme() + "._tcp." + resp->mUri.hostName(), RES_SRV, resp);
+
+
+ }
}
LLQueryResponder::LLQueryResponder()
diff --git a/indra/llmessage/llares.h b/indra/llmessage/llares.h
index 800781ee88..800781ee88 100644..100755
--- a/indra/llmessage/llares.h
+++ b/indra/llmessage/llares.h
diff --git a/indra/llmessage/llareslistener.cpp b/indra/llmessage/llareslistener.cpp
index 58b8a05a9e..0a4effac19 100644..100755
--- a/indra/llmessage/llareslistener.cpp
+++ b/indra/llmessage/llareslistener.cpp
@@ -93,5 +93,12 @@ private:
void LLAresListener::rewriteURI(const LLSD& data)
{
- mAres->rewriteURI(data["uri"], new UriRewriteResponder(data));
+ if (mAres)
+ {
+ mAres->rewriteURI(data["uri"], new UriRewriteResponder(data));
+ }
+ else
+ {
+ llinfos << "LLAresListener::rewriteURI requested without Ares present. Ignoring: " << data << llendl;
+ }
}
diff --git a/indra/llmessage/llareslistener.h b/indra/llmessage/llareslistener.h
index 780dcdd9c5..780dcdd9c5 100644..100755
--- a/indra/llmessage/llareslistener.h
+++ b/indra/llmessage/llareslistener.h
diff --git a/indra/llmessage/llassetstorage.cpp b/indra/llmessage/llassetstorage.cpp
index 9b86daebe5..9b86daebe5 100644..100755
--- a/indra/llmessage/llassetstorage.cpp
+++ b/indra/llmessage/llassetstorage.cpp
diff --git a/indra/llmessage/llassetstorage.h b/indra/llmessage/llassetstorage.h
index 563ff9e077..563ff9e077 100644..100755
--- a/indra/llmessage/llassetstorage.h
+++ b/indra/llmessage/llassetstorage.h
diff --git a/indra/llmessage/llavatarnamecache.cpp b/indra/llmessage/llavatarnamecache.cpp
index 97f2792686..9a68093427 100644..100755
--- a/indra/llmessage/llavatarnamecache.cpp
+++ b/indra/llmessage/llavatarnamecache.cpp
@@ -43,26 +43,26 @@ namespace LLAvatarNameCache
{
use_display_name_signal_t mUseDisplayNamesSignal;
- // Manual override for display names - can disable even if the region
- // supports it.
- bool sUseDisplayNames = true;
-
// Cache starts in a paused state until we can determine if the
// current region supports display names.
bool sRunning = false;
+ // Use the People API (modern) for fetching name if true. Use the old legacy protocol if false.
+ // For testing, there's a UsePeopleAPI setting that can be flipped (must restart viewer).
+ bool sUsePeopleAPI = true;
+
// Base lookup URL for name service.
// On simulator, loaded from indra.xml
// On viewer, usually a simulator capability (at People API team's request)
// Includes the trailing slash, like "http://pdp60.lindenlab.com:8000/agents/"
std::string sNameLookupURL;
- // accumulated agent IDs for next query against service
+ // Accumulated agent IDs for next query against service
typedef std::set<LLUUID> ask_queue_t;
ask_queue_t sAskQueue;
- // agent IDs that have been requested, but with no reply
- // maps agent ID to frame time request was made
+ // Agent IDs that have been requested, but with no reply.
+ // Maps agent ID to frame time request was made.
typedef std::map<LLUUID, F64> pending_queue_t;
pending_queue_t sPendingQueue;
@@ -73,45 +73,43 @@ namespace LLAvatarNameCache
typedef std::map<LLUUID, callback_signal_t*> signal_map_t;
signal_map_t sSignalMap;
- // names we know about
+ // The cache at last, i.e. avatar names we know about.
typedef std::map<LLUUID, LLAvatarName> cache_t;
cache_t sCache;
- // Send bulk lookup requests a few times a second at most
- // only need per-frame timing resolution
+ // Send bulk lookup requests a few times a second at most.
+ // Only need per-frame timing resolution.
LLFrameTimer sRequestTimer;
- /// Maximum time an unrefreshed cache entry is allowed
+ // Maximum time an unrefreshed cache entry is allowed.
const F64 MAX_UNREFRESHED_TIME = 20.0 * 60.0;
- /// Time when unrefreshed cached names were checked last
+ // Time when unrefreshed cached names were checked last.
static F64 sLastExpireCheck;
+ // Time-to-live for a temp cache entry.
+ const F64 TEMP_CACHE_ENTRY_LIFETIME = 60.0;
+
//-----------------------------------------------------------------------
// Internal methods
//-----------------------------------------------------------------------
// Handle name response off network.
- // Optionally skip adding to cache, used when this is a fallback to the
- // legacy name system.
void processName(const LLUUID& agent_id,
- const LLAvatarName& av_name,
- bool add_to_cache);
+ const LLAvatarName& av_name);
void requestNamesViaCapability();
- // Legacy name system callback
+ // Legacy name system callbacks
void legacyNameCallback(const LLUUID& agent_id,
const std::string& full_name,
- bool is_group
- );
-
+ bool is_group);
+ void legacyNameFetch(const LLUUID& agent_id,
+ const std::string& full_name,
+ bool is_group);
+
void requestNamesViaLegacy();
- // Fill in an LLAvatarName with the legacy name data
- void buildLegacyName(const std::string& full_name,
- LLAvatarName* av_name);
-
// Do a single callback to a given slot
void fireSignal(const LLUUID& agent_id,
const callback_slot_t& slot,
@@ -206,20 +204,11 @@ public:
// Use expiration time from header
av_name.mExpires = expires;
- // Some avatars don't have explicit display names set
- if (av_name.mDisplayName.empty())
- {
- av_name.mDisplayName = av_name.mUsername;
- }
-
- LL_DEBUGS("AvNameCache") << "LLAvatarNameResponder::result for " << agent_id << " "
- << "user '" << av_name.mUsername << "' "
- << "display '" << av_name.mDisplayName << "' "
- << "expires in " << expires - now << " seconds"
- << LL_ENDL;
+ LL_DEBUGS("AvNameCache") << "LLAvatarNameResponder::result for " << agent_id << LL_ENDL;
+ av_name.dump();
// cache it and fire signals
- LLAvatarNameCache::processName(agent_id, av_name, true);
+ LLAvatarNameCache::processName(agent_id, av_name);
}
// Same logic as error response case
@@ -274,41 +263,36 @@ void LLAvatarNameCache::handleAgentError(const LLUUID& agent_id)
{
// there is no existing cache entry, so make a temporary name from legacy
LL_WARNS("AvNameCache") << "LLAvatarNameCache get legacy for agent "
- << agent_id << LL_ENDL;
+ << agent_id << LL_ENDL;
gCacheName->get(agent_id, false, // legacy compatibility
- boost::bind(&LLAvatarNameCache::legacyNameCallback,
- _1, _2, _3));
+ boost::bind(&LLAvatarNameCache::legacyNameFetch, _1, _2, _3));
}
else
{
- // we have a chached (but probably expired) entry - since that would have
+ // we have a cached (but probably expired) entry - since that would have
// been returned by the get method, there is no need to signal anyone
// Clear this agent from the pending list
LLAvatarNameCache::sPendingQueue.erase(agent_id);
- const LLAvatarName& av_name = existing->second;
- LL_DEBUGS("AvNameCache") << "LLAvatarNameCache use cache for agent "
- << agent_id
- << "user '" << av_name.mUsername << "' "
- << "display '" << av_name.mDisplayName << "' "
- << "expires in " << av_name.mExpires - LLFrameTimer::getTotalSeconds() << " seconds"
- << LL_ENDL;
+ LLAvatarName& av_name = existing->second;
+ LL_DEBUGS("AvNameCache") << "LLAvatarNameCache use cache for agent " << agent_id << LL_ENDL;
+ av_name.dump();
+
+ // Reset expiry time so we don't constantly rerequest.
+ av_name.setExpires(TEMP_CACHE_ENTRY_LIFETIME);
}
}
-void LLAvatarNameCache::processName(const LLUUID& agent_id,
- const LLAvatarName& av_name,
- bool add_to_cache)
+void LLAvatarNameCache::processName(const LLUUID& agent_id, const LLAvatarName& av_name)
{
- if (add_to_cache)
- {
- sCache[agent_id] = av_name;
- }
+ // Add to the cache
+ sCache[agent_id] = av_name;
+ // Suppress request from the queue
sPendingQueue.erase(agent_id);
- // signal everyone waiting on this name
+ // Signal everyone waiting on this name
signal_map_t::iterator sig_it = sSignalMap.find(agent_id);
if (sig_it != sSignalMap.end())
{
@@ -330,8 +314,9 @@ void LLAvatarNameCache::requestNamesViaCapability()
// http://pdp60.lindenlab.com:8000/agents/?ids=3941037e-78ab-45f0-b421-bd6e77c1804d&ids=0012809d-7d2d-4c24-9609-af1230a37715&ids=0019aaba-24af-4f0a-aa72-6457953cf7f0
//
// Apache can handle URLs of 4096 chars, but let's be conservative
- const U32 NAME_URL_MAX = 4096;
- const U32 NAME_URL_SEND_THRESHOLD = 3000;
+ static const U32 NAME_URL_MAX = 4096;
+ static const U32 NAME_URL_SEND_THRESHOLD = 3500;
+
std::string url;
url.reserve(NAME_URL_MAX);
@@ -339,10 +324,12 @@ void LLAvatarNameCache::requestNamesViaCapability()
agent_ids.reserve(128);
U32 ids = 0;
- ask_queue_t::const_iterator it = sAskQueue.begin();
- for ( ; it != sAskQueue.end(); ++it)
+ ask_queue_t::const_iterator it;
+ while(!sAskQueue.empty())
{
- const LLUUID& agent_id = *it;
+ it = sAskQueue.begin();
+ LLUUID agent_id = *it;
+ sAskQueue.erase(it);
if (url.empty())
{
@@ -365,57 +352,63 @@ void LLAvatarNameCache::requestNamesViaCapability()
if (url.size() > NAME_URL_SEND_THRESHOLD)
{
- LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::requestNamesViaCapability first "
- << ids << " ids"
- << LL_ENDL;
- LLHTTPClient::get(url, new LLAvatarNameResponder(agent_ids));
- url.clear();
- agent_ids.clear();
+ break;
}
}
if (!url.empty())
{
- LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::requestNamesViaCapability all "
+ LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::requestNamesViaCapability requested "
<< ids << " ids"
<< LL_ENDL;
LLHTTPClient::get(url, new LLAvatarNameResponder(agent_ids));
- url.clear();
- agent_ids.clear();
}
-
- // We've moved all asks to the pending request queue
- sAskQueue.clear();
}
void LLAvatarNameCache::legacyNameCallback(const LLUUID& agent_id,
const std::string& full_name,
bool is_group)
{
- // Construct a dummy record for this name. By convention, SLID is blank
- // Never expires, but not written to disk, so lasts until end of session.
- LLAvatarName av_name;
- LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::legacyNameCallback "
- << "agent " << agent_id << " "
+ // Put the received data in the cache
+ legacyNameFetch(agent_id, full_name, is_group);
+
+ // Retrieve the name and set it to never (or almost never...) expire: when we are using the legacy
+ // protocol, we do not get an expiration date for each name and there's no reason to ask the
+ // data again and again so we set the expiration time to the largest value admissible.
+ std::map<LLUUID,LLAvatarName>::iterator av_record = sCache.find(agent_id);
+ LLAvatarName& av_name = av_record->second;
+ av_name.setExpires(MAX_UNREFRESHED_TIME);
+}
+
+void LLAvatarNameCache::legacyNameFetch(const LLUUID& agent_id,
+ const std::string& full_name,
+ bool is_group)
+{
+ LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::legacyNameFetch "
+ << "agent " << agent_id << " "
<< "full name '" << full_name << "'"
- << ( is_group ? " [group]" : "" )
- << LL_ENDL;
- buildLegacyName(full_name, &av_name);
-
- // Don't add to cache, the data already exists in the legacy name system
- // cache and we don't want or need duplicate storage, because keeping the
- // two copies in sync is complex.
- processName(agent_id, av_name, false);
+ << ( is_group ? " [group]" : "" )
+ << LL_ENDL;
+
+ // Construct an av_name record from this name.
+ LLAvatarName av_name;
+ av_name.fromString(full_name);
+
+ // Add to cache: we're still using the new cache even if we're using the old (legacy) protocol.
+ processName(agent_id, av_name);
}
void LLAvatarNameCache::requestNamesViaLegacy()
{
+ static const S32 MAX_REQUESTS = 100;
F64 now = LLFrameTimer::getTotalSeconds();
std::string full_name;
- ask_queue_t::const_iterator it = sAskQueue.begin();
- for (; it != sAskQueue.end(); ++it)
+ ask_queue_t::const_iterator it;
+ for (S32 requests = 0; !sAskQueue.empty() && requests < MAX_REQUESTS; ++requests)
{
- const LLUUID& agent_id = *it;
+ it = sAskQueue.begin();
+ LLUUID agent_id = *it;
+ sAskQueue.erase(it);
// Mark as pending first, just in case the callback is immediately
// invoked below. This should never happen in practice.
@@ -424,29 +417,28 @@ void LLAvatarNameCache::requestNamesViaLegacy()
LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::requestNamesViaLegacy agent " << agent_id << LL_ENDL;
gCacheName->get(agent_id, false, // legacy compatibility
- boost::bind(&LLAvatarNameCache::legacyNameCallback,
- _1, _2, _3));
+ boost::bind(&LLAvatarNameCache::legacyNameCallback, _1, _2, _3));
}
-
- // We've either answered immediately or moved all asks to the
- // pending queue
- sAskQueue.clear();
}
-void LLAvatarNameCache::initClass(bool running)
+void LLAvatarNameCache::initClass(bool running, bool usePeopleAPI)
{
sRunning = running;
+ sUsePeopleAPI = usePeopleAPI;
}
void LLAvatarNameCache::cleanupClass()
{
+ sCache.clear();
}
void LLAvatarNameCache::importFile(std::istream& istr)
{
LLSD data;
- S32 parse_count = LLSDSerialize::fromXMLDocument(data, istr);
- if (parse_count < 1) return;
+ if (LLSDParser::PARSE_FAILURE == LLSDSerialize::fromXMLDocument(data, istr))
+ {
+ return;
+ }
// by convention LLSD storage is a map
// we only store one entry in the map
@@ -478,7 +470,7 @@ void LLAvatarNameCache::exportFile(std::ostream& ostr)
const LLUUID& agent_id = it->first;
const LLAvatarName& av_name = it->second;
// Do not write temporary or expired entries to the stored cache
- if (!av_name.mIsTemporaryName && av_name.mExpires >= max_unrefreshed)
+ if (av_name.isValidName(max_unrefreshed))
{
// key must be a string
agents[agent_id.asString()] = av_name.asLLSD();
@@ -499,6 +491,11 @@ bool LLAvatarNameCache::hasNameLookupURL()
return !sNameLookupURL.empty();
}
+bool LLAvatarNameCache::usePeopleAPI()
+{
+ return hasNameLookupURL() && sUsePeopleAPI;
+}
+
void LLAvatarNameCache::idle()
{
// By convention, start running at first idle() call
@@ -507,25 +504,30 @@ void LLAvatarNameCache::idle()
// *TODO: Possibly re-enabled this based on People API load measurements
// 100 ms is the threshold for "user speed" operations, so we can
// stall for about that long to batch up requests.
- //const F32 SECS_BETWEEN_REQUESTS = 0.1f;
- //if (!sRequestTimer.checkExpirationAndReset(SECS_BETWEEN_REQUESTS))
- //{
- // return;
- //}
+ const F32 SECS_BETWEEN_REQUESTS = 0.1f;
+ if (!sRequestTimer.hasExpired())
+ {
+ return;
+ }
if (!sAskQueue.empty())
{
- if (useDisplayNames())
+ if (usePeopleAPI())
{
requestNamesViaCapability();
}
else
{
- // ...fall back to legacy name cache system
requestNamesViaLegacy();
}
}
+ if (sAskQueue.empty())
+ {
+ // cleared the list, reset the request timer.
+ sRequestTimer.resetWithExpiry(SECS_BETWEEN_REQUESTS);
+ }
+
// erase anything that has not been refreshed for more than MAX_UNREFRESHED_TIME
eraseUnrefreshed();
}
@@ -559,9 +561,8 @@ void LLAvatarNameCache::eraseUnrefreshed()
const LLAvatarName& av_name = it->second;
if (av_name.mExpires < max_unrefreshed)
{
- const LLUUID& agent_id = it->first;
- LL_DEBUGS("AvNameCache") << agent_id
- << " user '" << av_name.mUsername << "' "
+ LL_DEBUGS("AvNameCache") << it->first
+ << " user '" << av_name.getAccountName() << "' "
<< "expired " << now - av_name.mExpires << " secs ago"
<< LL_ENDL;
sCache.erase(it++);
@@ -575,20 +576,6 @@ void LLAvatarNameCache::eraseUnrefreshed()
}
}
-void LLAvatarNameCache::buildLegacyName(const std::string& full_name,
- LLAvatarName* av_name)
-{
- llassert(av_name);
- av_name->mUsername = "";
- av_name->mDisplayName = full_name;
- av_name->mIsDisplayNameDefault = true;
- av_name->mIsTemporaryName = true;
- av_name->mExpires = F64_MAX; // not used because these are not cached
- LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::buildLegacyName "
- << full_name
- << LL_ENDL;
-}
-
// fills in av_name if it has it in the cache, even if expired (can check expiry time)
// returns bool specifying if av_name was filled, false otherwise
bool LLAvatarNameCache::get(const LLUUID& agent_id, LLAvatarName *av_name)
@@ -596,38 +583,24 @@ bool LLAvatarNameCache::get(const LLUUID& agent_id, LLAvatarName *av_name)
if (sRunning)
{
// ...only do immediate lookups when cache is running
- if (useDisplayNames())
+ std::map<LLUUID,LLAvatarName>::iterator it = sCache.find(agent_id);
+ if (it != sCache.end())
{
- // ...use display names cache
- std::map<LLUUID,LLAvatarName>::iterator it = sCache.find(agent_id);
- if (it != sCache.end())
- {
- *av_name = it->second;
+ *av_name = it->second;
- // re-request name if entry is expired
- if (av_name->mExpires < LLFrameTimer::getTotalSeconds())
+ // re-request name if entry is expired
+ if (av_name->mExpires < LLFrameTimer::getTotalSeconds())
+ {
+ if (!isRequestPending(agent_id))
{
- if (!isRequestPending(agent_id))
- {
- LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::get "
- << "refresh agent " << agent_id
- << LL_ENDL;
- sAskQueue.insert(agent_id);
- }
+ LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::get "
+ << "refresh agent " << agent_id
+ << LL_ENDL;
+ sAskQueue.insert(agent_id);
}
-
- return true;
- }
- }
- else
- {
- // ...use legacy names cache
- std::string full_name;
- if (gCacheName->getFullName(agent_id, full_name))
- {
- buildLegacyName(full_name, av_name);
- return true;
}
+
+ return true;
}
}
@@ -651,37 +624,23 @@ void LLAvatarNameCache::fireSignal(const LLUUID& agent_id,
signal(agent_id, av_name);
}
-void LLAvatarNameCache::get(const LLUUID& agent_id, callback_slot_t slot)
+LLAvatarNameCache::callback_connection_t LLAvatarNameCache::get(const LLUUID& agent_id, callback_slot_t slot)
{
+ callback_connection_t connection;
+
if (sRunning)
{
// ...only do immediate lookups when cache is running
- if (useDisplayNames())
+ std::map<LLUUID,LLAvatarName>::iterator it = sCache.find(agent_id);
+ if (it != sCache.end())
{
- // ...use new cache
- std::map<LLUUID,LLAvatarName>::iterator it = sCache.find(agent_id);
- if (it != sCache.end())
- {
- const LLAvatarName& av_name = it->second;
-
- if (av_name.mExpires > LLFrameTimer::getTotalSeconds())
- {
- // ...name already exists in cache, fire callback now
- fireSignal(agent_id, slot, av_name);
- return;
- }
- }
- }
- else
- {
- // ...use old name system
- std::string full_name;
- if (gCacheName->getFullName(agent_id, full_name))
+ const LLAvatarName& av_name = it->second;
+
+ if (av_name.mExpires > LLFrameTimer::getTotalSeconds())
{
- LLAvatarName av_name;
- buildLegacyName(full_name, &av_name);
+ // ...name already exists in cache, fire callback now
fireSignal(agent_id, slot, av_name);
- return;
+ return connection;
}
}
}
@@ -698,47 +657,34 @@ void LLAvatarNameCache::get(const LLUUID& agent_id, callback_slot_t slot)
{
// ...new callback for this id
callback_signal_t* signal = new callback_signal_t();
- signal->connect(slot);
+ connection = signal->connect(slot);
sSignalMap[agent_id] = signal;
}
else
{
// ...existing callback, bind additional slot
callback_signal_t* signal = sig_it->second;
- signal->connect(slot);
+ connection = signal->connect(slot);
}
+
+ return connection;
}
void LLAvatarNameCache::setUseDisplayNames(bool use)
{
- if (use != sUseDisplayNames)
+ if (use != LLAvatarName::useDisplayNames())
{
- sUseDisplayNames = use;
- // flush our cache
- sCache.clear();
-
+ LLAvatarName::setUseDisplayNames(use);
mUseDisplayNamesSignal();
}
}
-bool LLAvatarNameCache::useDisplayNames()
-{
- // Must be both manually set on and able to look up names.
- return sUseDisplayNames && !sNameLookupURL.empty();
-}
-
void LLAvatarNameCache::erase(const LLUUID& agent_id)
{
sCache.erase(agent_id);
}
-void LLAvatarNameCache::fetch(const LLUUID& agent_id)
-{
- // re-request, even if request is already pending
- sAskQueue.insert(agent_id);
-}
-
void LLAvatarNameCache::insert(const LLUUID& agent_id, const LLAvatarName& av_name)
{
// *TODO: update timestamp if zero?
diff --git a/indra/llmessage/llavatarnamecache.h b/indra/llmessage/llavatarnamecache.h
index 59c1329ffa..2a8eb46187 100644..100755
--- a/indra/llmessage/llavatarnamecache.h
+++ b/indra/llmessage/llavatarnamecache.h
@@ -37,33 +37,33 @@ class LLUUID;
namespace LLAvatarNameCache
{
-
typedef boost::signals2::signal<void (void)> use_display_name_signal_t;
// Until the cache is set running, immediate lookups will fail and
// async lookups will be queued. This allows us to block requests
// until we know if the first region supports display names.
- void initClass(bool running);
+ void initClass(bool running, bool usePeopleAPI);
void cleanupClass();
+ // Import/export the name cache to file.
void importFile(std::istream& istr);
void exportFile(std::ostream& ostr);
- // On the viewer, usually a simulator capabilitity
- // If empty, name cache will fall back to using legacy name
- // lookup system
+ // On the viewer, usually a simulator capabilitity.
+ // If empty, name cache will fall back to using legacy name lookup system.
void setNameLookupURL(const std::string& name_lookup_url);
- // Do we have a valid lookup URL, hence are we trying to use the
- // new display name lookup system?
+ // Do we have a valid lookup URL, i.e. are we trying to use the
+ // more recent display name lookup system?
bool hasNameLookupURL();
+ bool usePeopleAPI();
// Periodically makes a batch request for display names not already in
- // cache. Call once per frame.
+ // cache. Called once per frame.
void idle();
// If name is in cache, returns true and fills in provided LLAvatarName
- // otherwise returns false
+ // otherwise returns false.
bool get(const LLUUID& agent_id, LLAvatarName *av_name);
// Callback types for get() below
@@ -71,26 +71,21 @@ namespace LLAvatarNameCache
void (const LLUUID& agent_id, const LLAvatarName& av_name)>
callback_signal_t;
typedef callback_signal_t::slot_type callback_slot_t;
+ typedef boost::signals2::connection callback_connection_t;
- // Fetches name information and calls callback.
- // If name information is in cache, callback will be called immediately.
- void get(const LLUUID& agent_id, callback_slot_t slot);
+ // Fetches name information and calls callbacks.
+ // If name information is in cache, callbacks will be called immediately.
+ callback_connection_t get(const LLUUID& agent_id, callback_slot_t slot);
- // Allow display names to be explicitly disabled for testing.
+ // Set display name: flips the switch and triggers the callbacks.
void setUseDisplayNames(bool use);
- bool useDisplayNames();
-
+
+ void insert(const LLUUID& agent_id, const LLAvatarName& av_name);
void erase(const LLUUID& agent_id);
- /// Provide some fallback for agents that return errors
+ /// Provide some fallback for agents that return errors.
void handleAgentError(const LLUUID& agent_id);
- // Force a re-fetch of the most recent data, but keep the current
- // data in cache
- void fetch(const LLUUID& agent_id);
-
- void insert(const LLUUID& agent_id, const LLAvatarName& av_name);
-
// Compute name expiration time from HTTP Cache-Control header,
// or return default value, in seconds from epoch.
F64 nameExpirationFromHeaders(LLSD headers);
diff --git a/indra/llmessage/llblowfishcipher.cpp b/indra/llmessage/llblowfishcipher.cpp
index 88aaf7c52a..88aaf7c52a 100644..100755
--- a/indra/llmessage/llblowfishcipher.cpp
+++ b/indra/llmessage/llblowfishcipher.cpp
diff --git a/indra/llmessage/llblowfishcipher.h b/indra/llmessage/llblowfishcipher.h
index e2e54526e8..e2e54526e8 100644..100755
--- a/indra/llmessage/llblowfishcipher.h
+++ b/indra/llmessage/llblowfishcipher.h
diff --git a/indra/llmessage/llbuffer.cpp b/indra/llmessage/llbuffer.cpp
index 250cace6e9..01da20f060 100644..100755
--- a/indra/llmessage/llbuffer.cpp
+++ b/indra/llmessage/llbuffer.cpp
@@ -30,7 +30,6 @@
#include "llbuffer.h"
#include "llmath.h"
-#include "llmemtype.h"
#include "llstl.h"
#include "llthread.h"
@@ -44,7 +43,6 @@ LLSegment::LLSegment() :
mData(NULL),
mSize(0)
{
- LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
}
LLSegment::LLSegment(S32 channel, U8* data, S32 data_len) :
@@ -52,12 +50,10 @@ LLSegment::LLSegment(S32 channel, U8* data, S32 data_len) :
mData(data),
mSize(data_len)
{
- LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
}
LLSegment::~LLSegment()
{
- LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
}
bool LLSegment::isOnChannel(S32 channel) const
@@ -104,7 +100,6 @@ LLHeapBuffer::LLHeapBuffer() :
mNextFree(NULL),
mReclaimedBytes(0)
{
- LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
const S32 DEFAULT_HEAP_BUFFER_SIZE = 16384;
allocate(DEFAULT_HEAP_BUFFER_SIZE);
}
@@ -115,7 +110,6 @@ LLHeapBuffer::LLHeapBuffer(S32 size) :
mNextFree(NULL),
mReclaimedBytes(0)
{
- LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
allocate(size);
}
@@ -125,7 +119,6 @@ LLHeapBuffer::LLHeapBuffer(const U8* src, S32 len) :
mNextFree(NULL),
mReclaimedBytes(0)
{
- LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
if((len > 0) && src)
{
allocate(len);
@@ -139,7 +132,6 @@ LLHeapBuffer::LLHeapBuffer(const U8* src, S32 len) :
// virtual
LLHeapBuffer::~LLHeapBuffer()
{
- LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
delete[] mBuffer;
mBuffer = NULL;
mSize = 0;
@@ -157,7 +149,6 @@ bool LLHeapBuffer::createSegment(
S32 size,
LLSegment& segment)
{
- LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
// get actual size of the segment.
S32 actual_size = llmin(size, (mSize - S32(mNextFree - mBuffer)));
@@ -212,7 +203,6 @@ bool LLHeapBuffer::containsSegment(const LLSegment& segment) const
void LLHeapBuffer::allocate(S32 size)
{
- LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
mReclaimedBytes = 0;
mBuffer = new U8[size];
if(mBuffer)
@@ -230,12 +220,10 @@ LLBufferArray::LLBufferArray() :
mNextBaseChannel(0),
mMutexp(NULL)
{
- LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
}
LLBufferArray::~LLBufferArray()
{
- LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
std::for_each(mBuffers.begin(), mBuffers.end(), DeletePointer());
delete mMutexp;
@@ -314,7 +302,6 @@ bool LLBufferArray::append(S32 channel, const U8* src, S32 len)
{
LLMutexLock lock(mMutexp) ;
- LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
std::vector<LLSegment> segments;
if(copyIntoBuffers(channel, src, len, segments))
{
@@ -329,7 +316,6 @@ bool LLBufferArray::prepend(S32 channel, const U8* src, S32 len)
{
ASSERT_LLBUFFERARRAY_MUTEX_LOCKED
- LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
std::vector<LLSegment> segments;
if(copyIntoBuffers(channel, src, len, segments))
{
@@ -345,7 +331,6 @@ bool LLBufferArray::insertAfter(
const U8* src,
S32 len)
{
- LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
std::vector<LLSegment> segments;
LLMutexLock lock(mMutexp) ;
@@ -366,7 +351,6 @@ LLBufferArray::segment_iterator_t LLBufferArray::splitAfter(U8* address)
{
ASSERT_LLBUFFERARRAY_MUTEX_LOCKED
- LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
segment_iterator_t end = mSegments.end();
segment_iterator_t it = getSegment(address);
if(it == end)
@@ -414,7 +398,6 @@ LLBufferArray::segment_iterator_t LLBufferArray::constructSegmentAfter(
LLSegment& segment)
{
ASSERT_LLBUFFERARRAY_MUTEX_LOCKED
- LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
segment_iterator_t rv = mSegments.begin();
segment_iterator_t end = mSegments.end();
if(!address)
@@ -578,7 +561,6 @@ U8* LLBufferArray::readAfter(
U8* dest,
S32& len) const
{
- LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
U8* rv = start;
if(!dest || len <= 0)
{
@@ -642,7 +624,6 @@ U8* LLBufferArray::seek(
S32 delta) const
{
ASSERT_LLBUFFERARRAY_MUTEX_LOCKED
- LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
const_segment_iterator_t it;
const_segment_iterator_t end = mSegments.end();
U8* rv = start;
@@ -786,8 +767,6 @@ U8* LLBufferArray::seek(
//test use only
bool LLBufferArray::takeContents(LLBufferArray& source)
{
- LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
-
LLMutexLock lock(mMutexp);
source.lock();
@@ -813,7 +792,6 @@ LLBufferArray::segment_iterator_t LLBufferArray::makeSegment(
S32 len)
{
ASSERT_LLBUFFERARRAY_MUTEX_LOCKED
- LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
// start at the end of the buffers, because it is the most likely
// to have free space.
LLSegment segment;
@@ -852,7 +830,6 @@ LLBufferArray::segment_iterator_t LLBufferArray::makeSegment(
bool LLBufferArray::eraseSegment(const segment_iterator_t& erase_iter)
{
ASSERT_LLBUFFERARRAY_MUTEX_LOCKED
- LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
// Find out which buffer contains the segment, and if it is found,
// ask it to reclaim the memory.
@@ -885,7 +862,6 @@ bool LLBufferArray::copyIntoBuffers(
std::vector<LLSegment>& segments)
{
ASSERT_LLBUFFERARRAY_MUTEX_LOCKED
- LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
if(!src || !len) return false;
S32 copied = 0;
LLSegment segment;
diff --git a/indra/llmessage/llbuffer.h b/indra/llmessage/llbuffer.h
index ccdb9fa7ee..ccdb9fa7ee 100644..100755
--- a/indra/llmessage/llbuffer.h
+++ b/indra/llmessage/llbuffer.h
diff --git a/indra/llmessage/llbufferstream.cpp b/indra/llmessage/llbufferstream.cpp
index 8d8ad05ad5..a51a48edc3 100644..100755
--- a/indra/llmessage/llbufferstream.cpp
+++ b/indra/llmessage/llbufferstream.cpp
@@ -30,7 +30,6 @@
#include "llbufferstream.h"
#include "llbuffer.h"
-#include "llmemtype.h"
#include "llthread.h"
static const S32 DEFAULT_OUTPUT_SEGMENT_SIZE = 1024 * 4;
@@ -44,19 +43,16 @@ LLBufferStreamBuf::LLBufferStreamBuf(
mChannels(channels),
mBuffer(buffer)
{
- LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
}
LLBufferStreamBuf::~LLBufferStreamBuf()
{
- LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
sync();
}
// virtual
int LLBufferStreamBuf::underflow()
{
- LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
//lldebugs << "LLBufferStreamBuf::underflow()" << llendl;
if(!mBuffer)
{
@@ -129,7 +125,6 @@ int LLBufferStreamBuf::underflow()
// virtual
int LLBufferStreamBuf::overflow(int c)
{
- LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
if(!mBuffer)
{
return EOF;
@@ -169,7 +164,6 @@ int LLBufferStreamBuf::overflow(int c)
// virtual
int LLBufferStreamBuf::sync()
{
- LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
int return_value = -1;
if(!mBuffer)
{
@@ -251,7 +245,6 @@ streampos LLBufferStreamBuf::seekoff(
std::ios::openmode which)
#endif
{
- LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
if(!mBuffer
|| ((way == std::ios::beg) && (off < 0))
|| ((way == std::ios::end) && (off > 0)))
@@ -343,10 +336,8 @@ LLBufferStream::LLBufferStream(
std::iostream(&mStreamBuf),
mStreamBuf(channels, buffer)
{
- LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
}
LLBufferStream::~LLBufferStream()
{
- LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
}
diff --git a/indra/llmessage/llbufferstream.h b/indra/llmessage/llbufferstream.h
index 19749612f3..19749612f3 100644..100755
--- a/indra/llmessage/llbufferstream.h
+++ b/indra/llmessage/llbufferstream.h
diff --git a/indra/llmessage/llcachename.cpp b/indra/llmessage/llcachename.cpp
index 479efabb5f..267c48e1d2 100644..100755
--- a/indra/llmessage/llcachename.cpp
+++ b/indra/llmessage/llcachename.cpp
@@ -36,7 +36,6 @@
#include "llsdserialize.h"
#include "lluuid.h"
#include "message.h"
-#include "llmemtype.h"
#include <boost/regex.hpp>
@@ -309,8 +308,10 @@ boost::signals2::connection LLCacheName::addObserver(const LLCacheNameCallback&
bool LLCacheName::importFile(std::istream& istr)
{
LLSD data;
- if(LLSDSerialize::fromXMLDocument(data, istr) < 1)
+ if(LLSDParser::PARSE_FAILURE == LLSDSerialize::fromXMLDocument(data, istr))
+ {
return false;
+ }
// We'll expire entries more than a week old
U32 now = (U32)time(NULL);
@@ -524,6 +525,7 @@ std::string LLCacheName::cleanFullName(const std::string& full_name)
}
//static
+// Transform hard-coded name provided by server to a more legible username
std::string LLCacheName::buildUsername(const std::string& full_name)
{
// rare, but handle hard-coded error names returned from server
@@ -549,8 +551,9 @@ std::string LLCacheName::buildUsername(const std::string& full_name)
return username;
}
- // if the input wasn't a correctly formatted legacy name just return it unchanged
- return full_name;
+ // if the input wasn't a correctly formatted legacy name, just return it
+ // cleaned up from a potential terminal "Resident"
+ return cleanFullName(full_name);
}
//static
@@ -663,7 +666,6 @@ boost::signals2::connection LLCacheName::get(const LLUUID& id, bool is_group, ol
void LLCacheName::processPending()
{
- LLMemType mt_pp(LLMemType::MTYPE_CACHE_PROCESS_PENDING);
const F32 SECS_BETWEEN_PROCESS = 0.1f;
if(!impl.mProcessTimer.checkExpirationAndReset(SECS_BETWEEN_PROCESS))
{
@@ -769,7 +771,6 @@ std::string LLCacheName::getDefaultLastName()
void LLCacheName::Impl::processPendingAsks()
{
- LLMemType mt_ppa(LLMemType::MTYPE_CACHE_PROCESS_PENDING_ASKS);
sendRequest(_PREHASH_UUIDNameRequest, mAskNameQueue);
sendRequest(_PREHASH_UUIDGroupNameRequest, mAskGroupQueue);
mAskNameQueue.clear();
@@ -778,7 +779,6 @@ void LLCacheName::Impl::processPendingAsks()
void LLCacheName::Impl::processPendingReplies()
{
- LLMemType mt_ppr(LLMemType::MTYPE_CACHE_PROCESS_PENDING_REPLIES);
// First call all the callbacks, because they might send messages.
for(ReplyQueue::iterator it = mReplyQueue.begin(); it != mReplyQueue.end(); ++it)
{
diff --git a/indra/llmessage/llcachename.h b/indra/llmessage/llcachename.h
index b108e37157..d238c3a247 100644..100755
--- a/indra/llmessage/llcachename.h
+++ b/indra/llmessage/llcachename.h
@@ -40,7 +40,7 @@ typedef boost::signals2::signal<void (const LLUUID& id,
bool is_group)> LLCacheNameSignal;
typedef LLCacheNameSignal::slot_type LLCacheNameCallback;
-// Old callback with user data for compatability
+// Old callback with user data for compatibility
typedef void (*old_callback_t)(const LLUUID&, const std::string&, bool, void*);
// Here's the theory:
diff --git a/indra/llmessage/llchainio.cpp b/indra/llmessage/llchainio.cpp
index bcda6746a1..bcda6746a1 100644..100755
--- a/indra/llmessage/llchainio.cpp
+++ b/indra/llmessage/llchainio.cpp
diff --git a/indra/llmessage/llchainio.h b/indra/llmessage/llchainio.h
index 6e4d6c2013..6e4d6c2013 100644..100755
--- a/indra/llmessage/llchainio.h
+++ b/indra/llmessage/llchainio.h
diff --git a/indra/llmessage/llcipher.h b/indra/llmessage/llcipher.h
index 76e3a7a5a3..76e3a7a5a3 100644..100755
--- a/indra/llmessage/llcipher.h
+++ b/indra/llmessage/llcipher.h
diff --git a/indra/llmessage/llcircuit.cpp b/indra/llmessage/llcircuit.cpp
index e0410906fb..0c2d4b823d 100644..100755
--- a/indra/llmessage/llcircuit.cpp
+++ b/indra/llmessage/llcircuit.cpp
@@ -679,7 +679,6 @@ void LLCircuitData::checkPacketInID(TPACKETID id, BOOL receive_resent)
setPacketInID((id + 1) % LL_MAX_OUT_PACKET_ID);
mLastPacketGap = 0;
- mOutOfOrderRate.count(0);
return;
}
@@ -775,7 +774,6 @@ void LLCircuitData::checkPacketInID(TPACKETID id, BOOL receive_resent)
}
}
- mOutOfOrderRate.count(gap);
mLastPacketGap = gap;
}
diff --git a/indra/llmessage/llcircuit.h b/indra/llmessage/llcircuit.h
index d1c400c6a2..430d6358f7 100644..100755
--- a/indra/llmessage/llcircuit.h
+++ b/indra/llmessage/llcircuit.h
@@ -40,7 +40,6 @@
#include "llpacketack.h"
#include "lluuid.h"
#include "llthrottle.h"
-#include "llstat.h"
//
// Constants
@@ -126,8 +125,6 @@ public:
S32 getUnackedPacketCount() const { return mUnackedPacketCount; }
S32 getUnackedPacketBytes() const { return mUnackedPacketBytes; }
F64 getNextPingSendTime() const { return mNextPingSendTime; }
- F32 getOutOfOrderRate(LLStatAccum::TimeScale scale = LLStatAccum::SCALE_MINUTE)
- { return mOutOfOrderRate.meanValue(scale); }
U32 getLastPacketGap() const { return mLastPacketGap; }
LLHost getHost() const { return mHost; }
F64 getLastPacketInTime() const { return mLastPacketInTime; }
@@ -275,7 +272,6 @@ protected:
LLTimer mExistenceTimer; // initialized when circuit created, used to track bandwidth numbers
S32 mCurrentResendCount; // Number of resent packets since last spam
- LLStatRate mOutOfOrderRate; // Rate of out of order packets coming in.
U32 mLastPacketGap; // Gap in sequence number of last packet.
const F32 mHeartbeatInterval;
diff --git a/indra/llmessage/llclassifiedflags.cpp b/indra/llmessage/llclassifiedflags.cpp
index f6084d4a60..f6084d4a60 100644..100755
--- a/indra/llmessage/llclassifiedflags.cpp
+++ b/indra/llmessage/llclassifiedflags.cpp
diff --git a/indra/llmessage/llclassifiedflags.h b/indra/llmessage/llclassifiedflags.h
index 17fc867453..17fc867453 100644..100755
--- a/indra/llmessage/llclassifiedflags.h
+++ b/indra/llmessage/llclassifiedflags.h
diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp
index b93d429feb..081f070866 100644..100755
--- a/indra/llmessage/llcurl.cpp
+++ b/indra/llmessage/llcurl.cpp
@@ -72,7 +72,8 @@
static const U32 EASY_HANDLE_POOL_SIZE = 5;
static const S32 MULTI_PERFORM_CALL_REPEAT = 5;
-static const S32 CURL_REQUEST_TIMEOUT = 30; // seconds per operation
+static const S32 CURL_REQUEST_TIMEOUT = 120; // seconds per operation
+static const S32 CURL_CONNECT_TIMEOUT = 30; //seconds to wait for a connection
static const S32 MAX_ACTIVE_REQUEST_COUNT = 100;
// DEBUG //
@@ -91,6 +92,7 @@ S32 LLCurl::sTotalHandles = 0 ;
bool LLCurl::sNotQuitting = true;
F32 LLCurl::sCurlRequestTimeOut = 120.f; //seonds
S32 LLCurl::sMaxHandles = 256; //max number of handles, (multi handles and easy handles combined).
+CURL* LLCurl::sCurlTemplateStandardHandle = NULL;
void check_curl_code(CURLcode code)
{
@@ -133,12 +135,12 @@ std::string LLCurl::getVersionString()
//////////////////////////////////////////////////////////////////////////////
LLCurl::Responder::Responder()
- : mReferenceCount(0)
{
}
LLCurl::Responder::~Responder()
{
+ LL_CHECK_MEMORY
}
// virtual
@@ -175,9 +177,11 @@ void LLCurl::Responder::completedRaw(
{
LLSD content;
LLBufferStream istr(channels, buffer.get());
- if (!LLSDSerialize::fromXML(content, istr))
+ const bool emit_errors = false;
+ if (LLSDParser::PARSE_FAILURE == LLSDSerialize::fromXML(content, istr, emit_errors))
{
llinfos << "Failed to deserialize LLSD. " << mURL << " [" << status << "]: " << reason << llendl;
+ content["reason"] = reason;
}
completed(status, reason, content);
@@ -202,23 +206,6 @@ void LLCurl::Responder::completedHeader(U32 status, const std::string& reason, c
}
-namespace boost
-{
- void intrusive_ptr_add_ref(LLCurl::Responder* p)
- {
- ++p->mReferenceCount;
- }
-
- void intrusive_ptr_release(LLCurl::Responder* p)
- {
- if (p && 0 == --p->mReferenceCount)
- {
- delete p;
- }
- }
-};
-
-
//////////////////////////////////////////////////////////////////////////////
std::set<CURL*> LLCurl::Easy::sFreeHandles;
@@ -267,15 +254,18 @@ void LLCurl::Easy::releaseEasyHandle(CURL* handle)
LLMutexLock lock(sHandleMutexp) ;
if (sActiveHandles.find(handle) != sActiveHandles.end())
{
+ LL_CHECK_MEMORY
sActiveHandles.erase(handle);
-
+ LL_CHECK_MEMORY
if(sFreeHandles.size() < MAX_NUM_FREE_HANDLES)
{
- sFreeHandles.insert(handle);
- }
- else
- {
+ sFreeHandles.insert(handle);
+ LL_CHECK_MEMORY
+ }
+ else
+ {
LLCurl::deleteEasyHandle(handle) ;
+ LL_CHECK_MEMORY
}
}
else
@@ -308,6 +298,8 @@ LLCurl::Easy* LLCurl::Easy::getEasy()
// multi handles cache if they are added to one.
CURLcode result = curl_easy_setopt(easy->mCurlEasyHandle, CURLOPT_DNS_CACHE_TIMEOUT, 0);
check_curl_code(result);
+ result = curl_easy_setopt(easy->mCurlEasyHandle, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
+ check_curl_code(result);
++gCurlEasyCount;
return easy;
@@ -318,13 +310,15 @@ LLCurl::Easy::~Easy()
releaseEasyHandle(mCurlEasyHandle);
--gCurlEasyCount;
curl_slist_free_all(mHeaders);
+ LL_CHECK_MEMORY
for_each(mStrings.begin(), mStrings.end(), DeletePointerArray());
-
+ LL_CHECK_MEMORY
if (mResponder && LLCurl::sNotQuitting) //aborted
{
std::string reason("Request timeout, aborted.") ;
mResponder->completedRaw(408, //HTTP_REQUEST_TIME_OUT, timeout, abort
reason, mChannels, mOutput);
+ LL_CHECK_MEMORY
}
mResponder = NULL;
}
@@ -494,7 +488,8 @@ void LLCurl::Easy::prepRequest(const std::string& url,
//setopt(CURLOPT_VERBOSE, 1); // useful for debugging
setopt(CURLOPT_NOSIGNAL, 1);
-
+ setopt(CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
+
// Set the CURL options for either Socks or HTTP proxy
LLProxy::getInstance()->applyProxySettings(this);
@@ -524,6 +519,7 @@ void LLCurl::Easy::prepRequest(const std::string& url,
//don't verify host name so urls with scrubbed host names will work (improves DNS performance)
setopt(CURLOPT_SSL_VERIFYHOST, 0);
setopt(CURLOPT_TIMEOUT, llmax(time_out, CURL_REQUEST_TIMEOUT));
+ setopt(CURLOPT_CONNECTTIMEOUT, CURL_CONNECT_TIMEOUT);
setoptString(CURLOPT_URL, url);
@@ -548,6 +544,7 @@ LLCurl::Multi::Multi(F32 idle_time_out)
mErrorCount(0),
mState(STATE_READY),
mDead(FALSE),
+ mValid(TRUE),
mMutexp(NULL),
mDeletionMutexp(NULL),
mEasyMutexp(NULL)
@@ -583,41 +580,65 @@ LLCurl::Multi::Multi(F32 idle_time_out)
LLCurl::Multi::~Multi()
{
- cleanup() ;
+ cleanup(true) ;
+
+ delete mDeletionMutexp ;
+ mDeletionMutexp = NULL ;
}
-void LLCurl::Multi::cleanup()
+void LLCurl::Multi::cleanup(bool deleted)
{
if(!mCurlMultiHandle)
{
return ; //nothing to clean.
}
+ llassert_always(deleted || !mValid) ;
+
+ LLMutexLock lock(mDeletionMutexp);
+
// Clean up active
for(easy_active_list_t::iterator iter = mEasyActiveList.begin();
iter != mEasyActiveList.end(); ++iter)
{
Easy* easy = *iter;
+ LL_CHECK_MEMORY
check_curl_multi_code(curl_multi_remove_handle(mCurlMultiHandle, easy->getCurlHandle()));
+ LL_CHECK_MEMORY
+ if(deleted)
+ {
+ easy->mResponder = NULL ; //avoid triggering mResponder.
+ LL_CHECK_MEMORY
+ }
delete easy;
+ LL_CHECK_MEMORY
}
mEasyActiveList.clear();
mEasyActiveMap.clear();
- // Clean up freed
+ LL_CHECK_MEMORY
+
+ // Clean up freed
for_each(mEasyFreeList.begin(), mEasyFreeList.end(), DeletePointer());
mEasyFreeList.clear();
-
+
+ LL_CHECK_MEMORY
+
check_curl_multi_code(LLCurl::deleteMultiHandle(mCurlMultiHandle));
mCurlMultiHandle = NULL ;
+ LL_CHECK_MEMORY
+
delete mMutexp ;
mMutexp = NULL ;
- delete mDeletionMutexp ;
- mDeletionMutexp = NULL ;
+
+ LL_CHECK_MEMORY
+
delete mEasyMutexp ;
mEasyMutexp = NULL ;
+ LL_CHECK_MEMORY
+
mQueued = 0 ;
mState = STATE_COMPLETED;
@@ -644,10 +665,20 @@ void LLCurl::Multi::unlock()
void LLCurl::Multi::markDead()
{
- LLMutexLock lock(mDeletionMutexp) ;
+ {
+ LLMutexLock lock(mDeletionMutexp) ;
- mDead = TRUE ;
- LLCurl::getCurlThread()->setPriority(mHandle, LLQueuedThread::PRIORITY_URGENT) ;
+ if(mCurlMultiHandle != NULL)
+ {
+ mDead = TRUE ;
+ LLCurl::getCurlThread()->setPriority(mHandle, LLQueuedThread::PRIORITY_URGENT) ;
+
+ return;
+ }
+ }
+
+ //not valid, delete it.
+ delete this;
}
void LLCurl::Multi::setState(LLCurl::Multi::ePerformState state)
@@ -741,10 +772,14 @@ bool LLCurl::Multi::doPerform()
setState(STATE_COMPLETED) ;
mIdleTimer.reset() ;
}
- else if(mIdleTimer.getElapsedTimeF32() > mIdleTimeOut) //idle for too long, remove it.
+ else if(!mValid && mIdleTimer.getElapsedTimeF32() > mIdleTimeOut) //idle for too long, remove it.
{
dead = true ;
}
+ else if(mValid && mIdleTimer.getElapsedTimeF32() > mIdleTimeOut - 1.f) //idle for too long, mark it invalid.
+ {
+ mValid = FALSE ;
+ }
return dead ;
}
@@ -911,8 +946,8 @@ bool LLCurlThread::CurlRequest::processRequest()
if(!completed)
{
- setPriority(LLQueuedThread::PRIORITY_LOW) ;
- }
+ setPriority(LLQueuedThread::PRIORITY_LOW) ;
+ }
}
return completed ;
@@ -922,7 +957,7 @@ void LLCurlThread::CurlRequest::finishRequest(bool completed)
{
if(mMulti->isDead())
{
- mCurlThread->deleteMulti(mMulti) ;
+ mCurlThread->deleteMulti(mMulti) ;
}
else
{
@@ -966,15 +1001,9 @@ void LLCurlThread::killMulti(LLCurl::Multi* multi)
return ;
}
- if(multi->isValid())
- {
+
multi->markDead() ;
}
- else
- {
- deleteMulti(multi) ;
- }
-}
//private
bool LLCurlThread::doMultiPerform(LLCurl::Multi* multi)
@@ -992,6 +1021,10 @@ void LLCurlThread::deleteMulti(LLCurl::Multi* multi)
void LLCurlThread::cleanupMulti(LLCurl::Multi* multi)
{
multi->cleanup() ;
+ if(multi->isDead()) //check if marked dead during cleaning up.
+ {
+ deleteMulti(multi) ;
+ }
}
//------------------------------------------------------------
@@ -1074,12 +1107,15 @@ void LLCurlRequest::get(const std::string& url, LLCurl::ResponderPtr responder)
{
getByteRange(url, headers_t(), 0, -1, responder);
}
-
+
+// Note: (length==0) is interpreted as "the rest of the file", i.e. the whole file if (offset==0) or
+// the remainder of the file if not.
bool LLCurlRequest::getByteRange(const std::string& url,
const headers_t& headers,
S32 offset, S32 length,
LLCurl::ResponderPtr responder)
{
+ llassert(LLCurl::sNotQuitting);
LLCurl::Easy* easy = allocEasy();
if (!easy)
{
@@ -1092,6 +1128,11 @@ bool LLCurlRequest::getByteRange(const std::string& url,
std::string range = llformat("Range: bytes=%d-%d", offset,offset+length-1);
easy->slist_append(range.c_str());
}
+ else if (offset > 0)
+ {
+ std::string range = llformat("Range: bytes=%d-", offset);
+ easy->slist_append(range.c_str());
+ }
easy->setHeaders();
bool res = addEasy(easy);
return res;
@@ -1102,6 +1143,7 @@ bool LLCurlRequest::post(const std::string& url,
const LLSD& data,
LLCurl::ResponderPtr responder, S32 time_out)
{
+ llassert(LLCurl::sNotQuitting);
LLCurl::Easy* easy = allocEasy();
if (!easy)
{
@@ -1129,6 +1171,7 @@ bool LLCurlRequest::post(const std::string& url,
const std::string& data,
LLCurl::ResponderPtr responder, S32 time_out)
{
+ llassert(LLCurl::sNotQuitting);
LLCurl::Easy* easy = allocEasy();
if (!easy)
{
@@ -1217,6 +1260,208 @@ S32 LLCurlRequest::getQueued()
return queued;
}
+LLCurlTextureRequest::LLCurlTextureRequest(S32 concurrency) :
+ LLCurlRequest(),
+ mConcurrency(concurrency),
+ mInQueue(0),
+ mMutex(NULL),
+ mHandleCounter(1),
+ mTotalIssuedRequests(0),
+ mTotalReceivedBits(0)
+{
+ mGlobalTimer.reset();
+}
+
+LLCurlTextureRequest::~LLCurlTextureRequest()
+{
+ mRequestMap.clear();
+
+ for(req_queue_t::iterator iter = mCachedRequests.begin(); iter != mCachedRequests.end(); ++iter)
+ {
+ delete *iter;
+ }
+ mCachedRequests.clear();
+}
+
+//return 0: success
+// > 0: cached handle
+U32 LLCurlTextureRequest::getByteRange(const std::string& url,
+ const headers_t& headers,
+ S32 offset, S32 length, U32 pri,
+ LLCurl::ResponderPtr responder, F32 delay_time)
+{
+ U32 ret_val = 0;
+ bool success = false;
+
+ if(mInQueue < mConcurrency && delay_time < 0.f)
+ {
+ success = LLCurlRequest::getByteRange(url, headers, offset, length, responder);
+ }
+
+ LLMutexLock lock(&mMutex);
+
+ if(success)
+ {
+ mInQueue++;
+ mTotalIssuedRequests++;
+ }
+ else
+ {
+ request_t* request = new request_t(mHandleCounter, url, headers, offset, length, pri, responder);
+ if(delay_time > 0.f)
+ {
+ request->mStartTime = mGlobalTimer.getElapsedTimeF32() + delay_time;
+ }
+
+ mCachedRequests.insert(request);
+ mRequestMap[mHandleCounter] = request;
+ ret_val = mHandleCounter;
+ mHandleCounter++;
+
+ if(!mHandleCounter)
+ {
+ mHandleCounter = 1;
+ }
+ }
+
+ return ret_val;
+}
+
+void LLCurlTextureRequest::completeRequest(S32 received_bytes)
+{
+ LLMutexLock lock(&mMutex);
+
+ llassert_always(mInQueue > 0);
+
+ mInQueue--;
+ mTotalReceivedBits += received_bytes * 8;
+}
+
+void LLCurlTextureRequest::nextRequests()
+{
+ if(mCachedRequests.empty() || mInQueue >= mConcurrency)
+ {
+ return;
+ }
+
+ F32 cur_time = mGlobalTimer.getElapsedTimeF32();
+
+ req_queue_t::iterator iter;
+ {
+ LLMutexLock lock(&mMutex);
+ iter = mCachedRequests.begin();
+ }
+ while(1)
+ {
+ request_t* request = *iter;
+ if(request->mStartTime < cur_time)
+ {
+ if(!LLCurlRequest::getByteRange(request->mUrl, request->mHeaders, request->mOffset, request->mLength, request->mResponder))
+ {
+ break;
+ }
+
+ LLMutexLock lock(&mMutex);
+ ++iter;
+ mInQueue++;
+ mTotalIssuedRequests++;
+ mCachedRequests.erase(request);
+ mRequestMap.erase(request->mHandle);
+ delete request;
+
+ if(iter == mCachedRequests.end() || mInQueue >= mConcurrency)
+ {
+ break;
+ }
+ }
+ else
+ {
+ LLMutexLock lock(&mMutex);
+ ++iter;
+ if(iter == mCachedRequests.end() || mInQueue >= mConcurrency)
+ {
+ break;
+ }
+ }
+ }
+
+ return;
+}
+
+void LLCurlTextureRequest::updatePriority(U32 handle, U32 pri)
+{
+ if(!handle)
+ {
+ return;
+ }
+
+ LLMutexLock lock(&mMutex);
+
+ std::map<S32, request_t*>::iterator iter = mRequestMap.find(handle);
+ if(iter != mRequestMap.end())
+ {
+ request_t* req = iter->second;
+
+ if(req->mPriority != pri)
+ {
+ mCachedRequests.erase(req);
+ req->mPriority = pri;
+ mCachedRequests.insert(req);
+ }
+ }
+}
+
+void LLCurlTextureRequest::removeRequest(U32 handle)
+{
+ if(!handle)
+ {
+ return;
+ }
+
+ LLMutexLock lock(&mMutex);
+
+ std::map<S32, request_t*>::iterator iter = mRequestMap.find(handle);
+ if(iter != mRequestMap.end())
+ {
+ request_t* req = iter->second;
+ mRequestMap.erase(iter);
+ mCachedRequests.erase(req);
+ delete req;
+ }
+}
+
+bool LLCurlTextureRequest::isWaiting(U32 handle)
+{
+ if(!handle)
+ {
+ return false;
+ }
+
+ LLMutexLock lock(&mMutex);
+ return mRequestMap.find(handle) != mRequestMap.end();
+}
+
+U32 LLCurlTextureRequest::getTotalReceivedBits()
+{
+ LLMutexLock lock(&mMutex);
+
+ U32 bits = mTotalReceivedBits;
+ mTotalReceivedBits = 0;
+ return bits;
+}
+
+U32 LLCurlTextureRequest::getTotalIssuedRequests()
+{
+ LLMutexLock lock(&mMutex);
+ return mTotalIssuedRequests;
+}
+
+S32 LLCurlTextureRequest::getNumRequests()
+{
+ LLMutexLock lock(&mMutex);
+ return mInQueue;
+}
+
////////////////////////////////////////////////////////////////////////////
// For generating one easy request
// associated with a single multi request
@@ -1483,35 +1728,51 @@ void LLCurl::cleanupClass()
break ;
}
}
+ LL_CHECK_MEMORY
sCurlThread->shutdown() ;
+ LL_CHECK_MEMORY
delete sCurlThread ;
sCurlThread = NULL ;
+ LL_CHECK_MEMORY
#if SAFE_SSL
CRYPTO_set_locking_callback(NULL);
for_each(sSSLMutex.begin(), sSSLMutex.end(), DeletePointer());
#endif
+
+ LL_CHECK_MEMORY
for (std::set<CURL*>::iterator iter = Easy::sFreeHandles.begin(); iter != Easy::sFreeHandles.end(); ++iter)
{
CURL* curl = *iter;
LLCurl::deleteEasyHandle(curl);
}
+
+ LL_CHECK_MEMORY
Easy::sFreeHandles.clear();
+ LL_CHECK_MEMORY
+
delete Easy::sHandleMutexp ;
Easy::sHandleMutexp = NULL ;
+ LL_CHECK_MEMORY
+
delete sHandleMutexp ;
sHandleMutexp = NULL ;
- llassert(Easy::sActiveHandles.empty());
+ LL_CHECK_MEMORY
+
+ // removed as per https://jira.secondlife.com/browse/SH-3115
+ //llassert(Easy::sActiveHandles.empty());
}
//static
CURLM* LLCurl::newMultiHandle()
{
+ llassert(sNotQuitting);
+
LLMutexLock lock(sHandleMutexp) ;
if(sTotalHandles + 1 > sMaxHandles)
@@ -1545,6 +1806,7 @@ CURLMcode LLCurl::deleteMultiHandle(CURLM* handle)
//static
CURL* LLCurl::newEasyHandle()
{
+ llassert(sNotQuitting);
LLMutexLock lock(sHandleMutexp) ;
if(sTotalHandles + 1 > sMaxHandles)
@@ -1554,10 +1816,10 @@ CURL* LLCurl::newEasyHandle()
}
sTotalHandles++;
- CURL* ret = curl_easy_init() ;
+ CURL* ret = createStandardCurlHandle();
if(!ret)
{
- llwarns << "curl_easy_init failed." << llendl ;
+ llwarns << "failed to create curl handle." << llendl ;
}
return ret ;
@@ -1569,7 +1831,9 @@ void LLCurl::deleteEasyHandle(CURL* handle)
if(handle)
{
LLMutexLock lock(sHandleMutexp) ;
+ LL_CHECK_MEMORY
curl_easy_cleanup(handle) ;
+ LL_CHECK_MEMORY
sTotalHandles-- ;
}
}
@@ -1585,3 +1849,47 @@ void LLCurlFF::check_multi_code(CURLMcode code)
{
check_curl_multi_code(code);
}
+
+
+// Static
+CURL* LLCurl::createStandardCurlHandle()
+{
+ if (sCurlTemplateStandardHandle == NULL)
+ { // Late creation of the template curl handle
+ sCurlTemplateStandardHandle = curl_easy_init();
+ if (sCurlTemplateStandardHandle == NULL)
+ {
+ llwarns << "curl error calling curl_easy_init()" << llendl;
+ }
+ else
+ {
+ CURLcode result = curl_easy_setopt(sCurlTemplateStandardHandle, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
+ check_curl_code(result);
+ result = curl_easy_setopt(sCurlTemplateStandardHandle, CURLOPT_NOSIGNAL, 1);
+ check_curl_code(result);
+ result = curl_easy_setopt(sCurlTemplateStandardHandle, CURLOPT_NOPROGRESS, 1);
+ check_curl_code(result);
+ result = curl_easy_setopt(sCurlTemplateStandardHandle, CURLOPT_ENCODING, "");
+ check_curl_code(result);
+ result = curl_easy_setopt(sCurlTemplateStandardHandle, CURLOPT_AUTOREFERER, 1);
+ check_curl_code(result);
+ result = curl_easy_setopt(sCurlTemplateStandardHandle, CURLOPT_FOLLOWLOCATION, 1);
+ check_curl_code(result);
+ result = curl_easy_setopt(sCurlTemplateStandardHandle, CURLOPT_SSL_VERIFYPEER, 1);
+ check_curl_code(result);
+ result = curl_easy_setopt(sCurlTemplateStandardHandle, CURLOPT_SSL_VERIFYHOST, 0);
+ check_curl_code(result);
+
+ // The Linksys WRT54G V5 router has an issue with frequent
+ // DNS lookups from LAN machines. If they happen too often,
+ // like for every HTTP request, the router gets annoyed after
+ // about 700 or so requests and starts issuing TCP RSTs to
+ // new connections. Reuse the DNS lookups for even a few
+ // seconds and no RSTs.
+ result = curl_easy_setopt(sCurlTemplateStandardHandle, CURLOPT_DNS_CACHE_TIMEOUT, 15);
+ check_curl_code(result);
+ }
+ }
+
+ return curl_easy_duphandle(sCurlTemplateStandardHandle);
+}
diff --git a/indra/llmessage/llcurl.h b/indra/llmessage/llcurl.h
index fd664c0fa1..90b3f2815d 100644..100755
--- a/indra/llmessage/llcurl.h
+++ b/indra/llmessage/llcurl.h
@@ -44,6 +44,8 @@
#include "llthread.h"
#include "llqueuedthread.h"
#include "llframetimer.h"
+#include "llpointer.h"
+#include "llsingleton.h"
class LLMutex;
class LLCurlThread;
@@ -67,7 +69,7 @@ public:
F64 mSpeedDownload;
};
- class Responder
+ class Responder : public LLThreadSafeRefCount
{
//LOG_CLASS(Responder);
public:
@@ -126,13 +128,10 @@ public:
return false;
}
- public: /* but not really -- don't touch this */
- U32 mReferenceCount;
-
private:
std::string mURL;
};
- typedef boost::intrusive_ptr<Responder> ResponderPtr;
+ typedef LLPointer<Responder> ResponderPtr;
/**
@@ -189,6 +188,8 @@ public:
static CURL* newEasyHandle() ;
static void deleteEasyHandle(CURL* handle) ;
+ static CURL* createStandardCurlHandle();
+
private:
static std::string sCAPath;
static std::string sCAFile;
@@ -198,6 +199,7 @@ private:
static LLMutex* sHandleMutexp ;
static S32 sTotalHandles ;
static S32 sMaxHandles;
+ static CURL* sCurlTemplateStandardHandle;
public:
static bool sNotQuitting;
static F32 sCurlRequestTimeOut;
@@ -304,7 +306,7 @@ public:
ePerformState getState() ;
bool isCompleted() ;
- bool isValid() {return mCurlMultiHandle != NULL ;}
+ bool isValid() {return mCurlMultiHandle != NULL && mValid;}
bool isDead() {return mDead;}
bool waitToComplete() ;
@@ -318,7 +320,7 @@ public:
private:
void easyFree(LLCurl::Easy*);
- void cleanup() ;
+ void cleanup(bool deleted = false) ;
CURLM* mCurlMultiHandle;
@@ -333,6 +335,7 @@ private:
ePerformState mState;
BOOL mDead ;
+ BOOL mValid ;
LLMutex* mMutexp ;
LLMutex* mDeletionMutexp ;
LLMutex* mEasyMutexp ;
@@ -377,12 +380,6 @@ private:
void cleanupMulti(LLCurl::Multi* multi) ;
} ;
-namespace boost
-{
- void intrusive_ptr_add_ref(LLCurl::Responder* p);
- void intrusive_ptr_release(LLCurl::Responder* p);
-};
-
class LLCurlRequest
{
@@ -413,6 +410,71 @@ private:
BOOL mProcessing;
};
+//for texture fetch only
+class LLCurlTextureRequest : public LLCurlRequest
+{
+public:
+ LLCurlTextureRequest(S32 concurrency);
+ ~LLCurlTextureRequest();
+
+ U32 getByteRange(const std::string& url, const headers_t& headers, S32 offset, S32 length, U32 pri, LLCurl::ResponderPtr responder, F32 delay_time = -1.f);
+ void nextRequests();
+ void completeRequest(S32 received_bytes);
+
+ void updatePriority(U32 handle, U32 pri);
+ void removeRequest(U32 handle);
+
+ U32 getTotalReceivedBits();
+ U32 getTotalIssuedRequests();
+ S32 getNumRequests();
+ bool isWaiting(U32 handle);
+
+private:
+ LLMutex mMutex;
+ S32 mConcurrency;
+ S32 mInQueue; //request currently in queue.
+ U32 mHandleCounter;
+ U32 mTotalIssuedRequests;
+ U32 mTotalReceivedBits;
+
+ typedef struct _request_t
+ {
+ _request_t(U32 handle, const std::string& url, const headers_t& headers, S32 offset, S32 length, U32 pri, LLCurl::ResponderPtr responder) :
+ mHandle(handle), mUrl(url), mHeaders(headers), mOffset(offset), mLength(length), mPriority(pri), mResponder(responder), mStartTime(0.f)
+ {}
+
+ U32 mHandle;
+ std::string mUrl;
+ LLCurlRequest::headers_t mHeaders;
+ S32 mOffset;
+ S32 mLength;
+ LLCurl::ResponderPtr mResponder;
+ U32 mPriority;
+ F32 mStartTime; //start time to issue this request
+ } request_t;
+
+ struct request_compare
+ {
+ bool operator()(const request_t* lhs, const request_t* rhs) const
+ {
+ if(lhs->mPriority != rhs->mPriority)
+ {
+ return lhs->mPriority > rhs->mPriority; // higher priority in front of queue (set)
+ }
+ else
+ {
+ return (U32)lhs < (U32)rhs;
+ }
+ }
+ };
+
+ typedef std::set<request_t*, request_compare> req_queue_t;
+ req_queue_t mCachedRequests;
+ std::map<S32, request_t*> mRequestMap;
+
+ LLFrameTimer mGlobalTimer;
+};
+
class LLCurlEasyRequest
{
public:
diff --git a/indra/llmessage/lldatapacker.cpp b/indra/llmessage/lldatapacker.cpp
index 3385d7c2e2..3385d7c2e2 100644..100755
--- a/indra/llmessage/lldatapacker.cpp
+++ b/indra/llmessage/lldatapacker.cpp
diff --git a/indra/llmessage/lldatapacker.h b/indra/llmessage/lldatapacker.h
index b0a638c16e..b0a638c16e 100644..100755
--- a/indra/llmessage/lldatapacker.h
+++ b/indra/llmessage/lldatapacker.h
diff --git a/indra/llmessage/lldbstrings.h b/indra/llmessage/lldbstrings.h
index 9bf1b3eda4..e23d17d5b6 100644..100755
--- a/indra/llmessage/lldbstrings.h
+++ b/indra/llmessage/lldbstrings.h
@@ -156,18 +156,6 @@ const S32 DB_USER_SKILLS_BUF_SIZE = 255;
const S32 DB_NV_NAME_STR_LEN = 128;
const S32 DB_NV_NAME_BUF_SIZE = 129;
-// votes.vote_text varchar(254)
-const S32 DB_VOTE_TEXT_STR_LEN = 254;
-const S32 DB_VOTE_TEXT_BUF_SIZE = 255;
-
-// vpte type text varchar(9)
-const S32 DB_VOTE_TYPE_STR_LEN = 9;
-const S32 DB_VOTE_TYPE_BUF_SIZE = 10;
-
-// vote result text
-const S32 DB_VOTE_RESULT_BUF_LEN = 8;
-const S32 DB_VOTE_RESULT_BUF_SIZE = 9;
-
// user_start_location.location_name varchar(254)
const S32 DB_START_LOCATION_STR_LEN = 254;
const S32 DB_START_LOCATION_BUF_SIZE = 255;
diff --git a/indra/llmessage/lldispatcher.cpp b/indra/llmessage/lldispatcher.cpp
index b2dc414a68..b2dc414a68 100644..100755
--- a/indra/llmessage/lldispatcher.cpp
+++ b/indra/llmessage/lldispatcher.cpp
diff --git a/indra/llmessage/lldispatcher.h b/indra/llmessage/lldispatcher.h
index 9d1751f588..9d1751f588 100644..100755
--- a/indra/llmessage/lldispatcher.h
+++ b/indra/llmessage/lldispatcher.h
diff --git a/indra/llmessage/lleventflags.h b/indra/llmessage/lleventflags.h
index 75d79071b1..75d79071b1 100644..100755
--- a/indra/llmessage/lleventflags.h
+++ b/indra/llmessage/lleventflags.h
diff --git a/indra/llmessage/llfiltersd2xmlrpc.cpp b/indra/llmessage/llfiltersd2xmlrpc.cpp
index e0ca056a5f..e0ca056a5f 100644..100755
--- a/indra/llmessage/llfiltersd2xmlrpc.cpp
+++ b/indra/llmessage/llfiltersd2xmlrpc.cpp
diff --git a/indra/llmessage/llfiltersd2xmlrpc.h b/indra/llmessage/llfiltersd2xmlrpc.h
index 0c9a0dc95b..0c9a0dc95b 100644..100755
--- a/indra/llmessage/llfiltersd2xmlrpc.h
+++ b/indra/llmessage/llfiltersd2xmlrpc.h
diff --git a/indra/llmessage/llfollowcamparams.h b/indra/llmessage/llfollowcamparams.h
index 25208031db..25208031db 100644..100755
--- a/indra/llmessage/llfollowcamparams.h
+++ b/indra/llmessage/llfollowcamparams.h
diff --git a/indra/llmessage/llhost.cpp b/indra/llmessage/llhost.cpp
index 61a84de8e3..61a84de8e3 100644..100755
--- a/indra/llmessage/llhost.cpp
+++ b/indra/llmessage/llhost.cpp
diff --git a/indra/llmessage/llhost.h b/indra/llmessage/llhost.h
index 0cf52a4151..0cf52a4151 100644..100755
--- a/indra/llmessage/llhost.h
+++ b/indra/llmessage/llhost.h
diff --git a/indra/llmessage/llhttpassetstorage.cpp b/indra/llmessage/llhttpassetstorage.cpp
index 612d765969..7dcf160c9b 100644..100755
--- a/indra/llmessage/llhttpassetstorage.cpp
+++ b/indra/llmessage/llhttpassetstorage.cpp
@@ -747,7 +747,7 @@ LLAssetRequest* LLHTTPAssetStorage::findNextRequest(LLAssetStorage::request_list
request_list_t::iterator running_end = running.end();
request_list_t::iterator pending_iter = pending.begin();
- request_list_t::iterator pending_end = pending.end();
+
// Loop over all pending requests until we miss finding it in the running list.
for (; pending_iter != pending.end(); ++pending_iter)
{
diff --git a/indra/llmessage/llhttpassetstorage.h b/indra/llmessage/llhttpassetstorage.h
index f743ccf0ac..f743ccf0ac 100644..100755
--- a/indra/llmessage/llhttpassetstorage.h
+++ b/indra/llmessage/llhttpassetstorage.h
diff --git a/indra/llmessage/llhttpclient.cpp b/indra/llmessage/llhttpclient.cpp
index 0c325a68aa..11648717ad 100644..100755
--- a/indra/llmessage/llhttpclient.cpp
+++ b/indra/llmessage/llhttpclient.cpp
@@ -217,20 +217,30 @@ static void request(
Injector* body_injector,
LLCurl::ResponderPtr responder,
const F32 timeout = HTTP_REQUEST_EXPIRY_SECS,
- const LLSD& headers = LLSD()
+ const LLSD& headers = LLSD(),
+ bool follow_redirects = true
)
{
if (!LLHTTPClient::hasPump())
{
+ if (responder)
+ {
responder->completed(U32_MAX, "No pump", LLSD());
+ }
+ delete body_injector;
return;
}
LLPumpIO::chain_t chain;
- LLURLRequest* req = new LLURLRequest(method, url);
+ LLURLRequest* req = new LLURLRequest(method, url, follow_redirects);
if(!req->isValid())//failed
{
+ if (responder)
+ {
+ responder->completed(498, "Internal Error - curl failure", LLSD());
+ }
delete req ;
+ delete body_injector;
return ;
}
@@ -325,7 +335,8 @@ void LLHTTPClient::getByteRange(
S32 bytes,
ResponderPtr responder,
const LLSD& hdrs,
- const F32 timeout)
+ const F32 timeout,
+ bool follow_redirects /* = true */)
{
LLSD headers = hdrs;
if(offset > 0 || bytes > 0)
@@ -333,37 +344,42 @@ void LLHTTPClient::getByteRange(
std::string range = llformat("bytes=%d-%d", offset, offset+bytes-1);
headers["Range"] = range;
}
- request(url,LLURLRequest::HTTP_GET, NULL, responder, timeout, headers);
+ request(url,LLURLRequest::HTTP_GET, NULL, responder, timeout, headers, follow_redirects);
}
void LLHTTPClient::head(
const std::string& url,
ResponderPtr responder,
const LLSD& headers,
- const F32 timeout)
+ const F32 timeout,
+ bool follow_redirects /* = true */)
{
- request(url, LLURLRequest::HTTP_HEAD, NULL, responder, timeout, headers);
+ request(url, LLURLRequest::HTTP_HEAD, NULL, responder, timeout, headers, follow_redirects);
}
-void LLHTTPClient::get(const std::string& url, ResponderPtr responder, const LLSD& headers, const F32 timeout)
+void LLHTTPClient::get(const std::string& url, ResponderPtr responder, const LLSD& headers, const F32 timeout,
+ bool follow_redirects /* = true */)
{
- request(url, LLURLRequest::HTTP_GET, NULL, responder, timeout, headers);
+ request(url, LLURLRequest::HTTP_GET, NULL, responder, timeout, headers, follow_redirects);
}
-void LLHTTPClient::getHeaderOnly(const std::string& url, ResponderPtr responder, const LLSD& headers, const F32 timeout)
+void LLHTTPClient::getHeaderOnly(const std::string& url, ResponderPtr responder, const LLSD& headers,
+ const F32 timeout, bool follow_redirects /* = true */)
{
- request(url, LLURLRequest::HTTP_HEAD, NULL, responder, timeout, headers);
+ request(url, LLURLRequest::HTTP_HEAD, NULL, responder, timeout, headers, follow_redirects);
}
-void LLHTTPClient::getHeaderOnly(const std::string& url, ResponderPtr responder, const F32 timeout)
+void LLHTTPClient::getHeaderOnly(const std::string& url, ResponderPtr responder, const F32 timeout,
+ bool follow_redirects /* = true */)
{
- getHeaderOnly(url, responder, LLSD(), timeout);
+ getHeaderOnly(url, responder, LLSD(), timeout, follow_redirects);
}
-void LLHTTPClient::get(const std::string& url, const LLSD& query, ResponderPtr responder, const LLSD& headers, const F32 timeout)
+void LLHTTPClient::get(const std::string& url, const LLSD& query, ResponderPtr responder, const LLSD& headers,
+ const F32 timeout, bool follow_redirects /* = true */)
{
LLURI uri;
uri = LLURI::buildHTTP(url, LLSD::emptyArray(), query);
- get(uri.asString(), responder, headers, timeout);
+ get(uri.asString(), responder, headers, timeout, follow_redirects);
}
// A simple class for managing data returned from a curl http request.
diff --git a/indra/llmessage/llhttpclient.h b/indra/llmessage/llhttpclient.h
index a7236ba169..5de257a4f6 100644..100755
--- a/indra/llmessage/llhttpclient.h
+++ b/indra/llmessage/llhttpclient.h
@@ -63,10 +63,15 @@ public:
const std::string& url,
ResponderPtr,
const LLSD& headers = LLSD(),
- const F32 timeout=HTTP_REQUEST_EXPIRY_SECS);
- static void getByteRange(const std::string& url, S32 offset, S32 bytes, ResponderPtr, const LLSD& headers=LLSD(), const F32 timeout=HTTP_REQUEST_EXPIRY_SECS);
- static void get(const std::string& url, ResponderPtr, const LLSD& headers = LLSD(), const F32 timeout=HTTP_REQUEST_EXPIRY_SECS);
- static void get(const std::string& url, const LLSD& query, ResponderPtr, const LLSD& headers = LLSD(), const F32 timeout=HTTP_REQUEST_EXPIRY_SECS);
+ const F32 timeout=HTTP_REQUEST_EXPIRY_SECS,
+ bool follow_redirects = true);
+ static void getByteRange(const std::string& url, S32 offset, S32 bytes, ResponderPtr,
+ const LLSD& headers=LLSD(), const F32 timeout=HTTP_REQUEST_EXPIRY_SECS,
+ bool follow_redirects = true);
+ static void get(const std::string& url, ResponderPtr, const LLSD& headers = LLSD(),
+ const F32 timeout=HTTP_REQUEST_EXPIRY_SECS, bool follow_redirects = true);
+ static void get(const std::string& url, const LLSD& query, ResponderPtr, const LLSD& headers = LLSD(),
+ const F32 timeout=HTTP_REQUEST_EXPIRY_SECS, bool follow_redirects = true);
static void put(
const std::string& url,
@@ -74,8 +79,10 @@ public:
ResponderPtr,
const LLSD& headers = LLSD(),
const F32 timeout=HTTP_REQUEST_EXPIRY_SECS);
- static void getHeaderOnly(const std::string& url, ResponderPtr, const F32 timeout=HTTP_REQUEST_EXPIRY_SECS);
- static void getHeaderOnly(const std::string& url, ResponderPtr, const LLSD& headers, const F32 timeout=HTTP_REQUEST_EXPIRY_SECS);
+ static void getHeaderOnly(const std::string& url, ResponderPtr, const F32 timeout=HTTP_REQUEST_EXPIRY_SECS,
+ bool follow_redirects = true);
+ static void getHeaderOnly(const std::string& url, ResponderPtr, const LLSD& headers,
+ const F32 timeout=HTTP_REQUEST_EXPIRY_SECS, bool follow_redirects = true);
static void post(
const std::string& url,
diff --git a/indra/llmessage/llhttpclientadapter.cpp b/indra/llmessage/llhttpclientadapter.cpp
index f5d7a9abb6..dcd2d79d67 100644..100755
--- a/indra/llmessage/llhttpclientadapter.cpp
+++ b/indra/llmessage/llhttpclientadapter.cpp
@@ -43,8 +43,11 @@ void LLHTTPClientAdapter::get(const std::string& url, LLCurl::ResponderPtr respo
void LLHTTPClientAdapter::get(const std::string& url, LLCurl::ResponderPtr responder, const LLSD& headers)
{
LLSD empty_pragma_header = headers;
+ if (!empty_pragma_header.has("Pragma"))
+ {
// as above
empty_pragma_header["Pragma"] = " ";
+ }
LLHTTPClient::get(url, responder, empty_pragma_header);
}
diff --git a/indra/llmessage/llhttpclientadapter.h b/indra/llmessage/llhttpclientadapter.h
index aae6426a59..aae6426a59 100644..100755
--- a/indra/llmessage/llhttpclientadapter.h
+++ b/indra/llmessage/llhttpclientadapter.h
diff --git a/indra/llmessage/llhttpclientinterface.h b/indra/llmessage/llhttpclientinterface.h
index 12a3857a61..12a3857a61 100644..100755
--- a/indra/llmessage/llhttpclientinterface.h
+++ b/indra/llmessage/llhttpclientinterface.h
diff --git a/indra/llmessage/llhttpnode.cpp b/indra/llmessage/llhttpnode.cpp
index 5c2f73eccb..5c2f73eccb 100644..100755
--- a/indra/llmessage/llhttpnode.cpp
+++ b/indra/llmessage/llhttpnode.cpp
diff --git a/indra/llmessage/llhttpnode.h b/indra/llmessage/llhttpnode.h
index 148647ddde..148647ddde 100644..100755
--- a/indra/llmessage/llhttpnode.h
+++ b/indra/llmessage/llhttpnode.h
diff --git a/indra/llmessage/llhttpnodeadapter.h b/indra/llmessage/llhttpnodeadapter.h
index 22984c4478..22984c4478 100644..100755
--- a/indra/llmessage/llhttpnodeadapter.h
+++ b/indra/llmessage/llhttpnodeadapter.h
diff --git a/indra/llmessage/llhttpsender.cpp b/indra/llmessage/llhttpsender.cpp
index c48cbc42a6..c48cbc42a6 100644..100755
--- a/indra/llmessage/llhttpsender.cpp
+++ b/indra/llmessage/llhttpsender.cpp
diff --git a/indra/llmessage/llhttpsender.h b/indra/llmessage/llhttpsender.h
index 88920db24d..88920db24d 100644..100755
--- a/indra/llmessage/llhttpsender.h
+++ b/indra/llmessage/llhttpsender.h
diff --git a/indra/llmessage/llinstantmessage.cpp b/indra/llmessage/llinstantmessage.cpp
index d68e0c423e..b0275c161b 100644..100755
--- a/indra/llmessage/llinstantmessage.cpp
+++ b/indra/llmessage/llinstantmessage.cpp
@@ -43,14 +43,6 @@
const U8 IM_ONLINE = 0;
const U8 IM_OFFLINE = 1;
-const S32 VOTE_YES = 1;
-const S32 VOTE_NO = 0;
-const S32 VOTE_ABSTAIN = -1;
-
-const S32 VOTE_MAJORITY = 0;
-const S32 VOTE_SUPER_MAJORITY = 1;
-const S32 VOTE_UNANIMOUS = 2;
-
const char EMPTY_BINARY_BUCKET[] = "";
const S32 EMPTY_BINARY_BUCKET_SIZE = 1;
const U32 NO_TIMESTAMP = 0;
@@ -69,7 +61,6 @@ LLIMInfo::LLIMInfo() :
mViewerThinksToIsOnline(false),
mIMType(IM_NOTHING_SPECIAL),
mTimeStamp(0),
- mSource(IM_FROM_SIM),
mTTL(IM_TTL)
{
}
@@ -88,7 +79,6 @@ LLIMInfo::LLIMInfo(
LLSD data,
U8 offline,
U32 timestamp,
- EIMSource source,
S32 ttl) :
mFromID(from_id),
mFromGroup(from_group),
@@ -104,14 +94,12 @@ LLIMInfo::LLIMInfo(
mName(name),
mMessage(message),
mData(data),
- mSource(source),
mTTL(ttl)
{
}
-LLIMInfo::LLIMInfo(LLMessageSystem* msg, EIMSource source, S32 ttl) :
+LLIMInfo::LLIMInfo(LLMessageSystem* msg, S32 ttl) :
mViewerThinksToIsOnline(false),
- mSource(source),
mTTL(ttl)
{
unpackMessageBlock(msg);
@@ -326,7 +314,6 @@ LLSD im_info_to_llsd(LLPointer<LLIMInfo> im_info)
param_message["region_id"] = im_info->mRegionID;
param_message["position"] = ll_sd_from_vector3(im_info->mPosition);
param_message["data"] = im_info->mData;
- param_message["source"]= im_info->mSource;
param_message["ttl"] = im_info->mTTL;
LLSD param_agent;
@@ -359,7 +346,6 @@ LLPointer<LLIMInfo> llsd_to_im_info(const LLSD& im_info_sd)
param_message["data"],
(U8) param_message["offline"].asInteger(),
(U32) param_message["timestamp"].asInteger(),
- (EIMSource)param_message["source"].asInteger(),
param_message["ttl"].asInteger());
return im_info;
@@ -381,7 +367,6 @@ LLPointer<LLIMInfo> LLIMInfo::clone()
mData,
mOffline,
mTimeStamp,
- mSource,
mTTL);
}
diff --git a/indra/llmessage/llinstantmessage.h b/indra/llmessage/llinstantmessage.h
index e0dae376b4..f7118f8ccf 100644..100755
--- a/indra/llmessage/llinstantmessage.h
+++ b/indra/llmessage/llinstantmessage.h
@@ -115,8 +115,8 @@ enum EInstantMessage
// viewer, since you can't IM an object yet.
IM_FROM_TASK = 19,
- // sent an IM to a busy user, this is the auto response
- IM_BUSY_AUTO_RESPONSE = 20,
+ // sent an IM to a do not disturb user, this is the auto response
+ IM_DO_NOT_DISTURB_AUTO_RESPONSE = 20,
// Shows the message in the console and chat history
IM_CONSOLE_AND_CHAT_HISTORY = 21,
@@ -126,7 +126,7 @@ enum EInstantMessage
IM_LURE_ACCEPTED = 23,
IM_LURE_DECLINED = 24,
IM_GODLIKE_LURE_USER = 25,
- IM_YET_TO_BE_USED = 26,
+ IM_TELEPORT_REQUEST = 26,
// IM that notifie of a new group election.
// Name is name of person who called vote.
@@ -164,57 +164,9 @@ enum EInstantMessage
};
-// Hooks for quickly hacking in experimental admin debug messages
-// without needing to recompile the viewer
-// *NOTE: This functionality has been moved to be a string based
-// operation so that we don't even have to do a full recompile. This
-// enumeration will be phased out soon.
-enum EGodlikeRequest
-{
- GOD_WANTS_NOTHING,
-
- // for requesting physics information about an object
- GOD_WANTS_PHYSICS_INFO,
-
- // two unused requests that can be appropriated for debug
- // purposes (no viewer recompile necessary)
- GOD_WANTS_FOO,
- GOD_WANTS_BAR,
-
- // to dump simulator terrain data to terrain.raw file
- GOD_WANTS_TERRAIN_SAVE,
- // to load simulator terrain data from terrain.raw file
- GOD_WANTS_TERRAIN_LOAD,
-
- GOD_WANTS_TOGGLE_AVATAR_GEOMETRY, // HACK for testing new avatar geom
-
- // real-time telehub operations
- GOD_WANTS_TELEHUB_INFO,
- GOD_WANTS_CONNECT_TELEHUB,
- GOD_WANTS_DELETE_TELEHUB,
- GOD_WANTS_ADD_TELEHUB_SPAWNPOINT,
- GOD_WANTS_REMOVE_TELEHUB_SPAWNPOINT,
-
-};
-
-enum EIMSource
-{
- IM_FROM_VIEWER,
- IM_FROM_DATASERVER,
- IM_FROM_SIM
-};
-
extern const U8 IM_ONLINE;
extern const U8 IM_OFFLINE;
-extern const S32 VOTE_YES;
-extern const S32 VOTE_NO;
-extern const S32 VOTE_ABSTAIN;
-
-extern const S32 VOTE_MAJORITY;
-extern const S32 VOTE_SUPER_MAJORITY;
-extern const S32 VOTE_UNANIMOUS;
-
extern const char EMPTY_BINARY_BUCKET[];
extern const S32 EMPTY_BINARY_BUCKET_SIZE;
@@ -234,7 +186,6 @@ protected:
public:
LLIMInfo(LLMessageSystem* msg,
- EIMSource source = IM_FROM_SIM,
S32 ttl = IM_TTL);
LLIMInfo(
@@ -251,7 +202,6 @@ public:
LLSD data,
U8 offline,
U32 timestamp,
- EIMSource source,
S32 ttl = IM_TTL);
void packInstantMessage(LLMessageSystem* msg) const;
@@ -274,7 +224,6 @@ public:
std::string mMessage;
LLSD mData;
- EIMSource mSource;
S32 mTTL;
};
diff --git a/indra/llmessage/llinvite.h b/indra/llmessage/llinvite.h
index e5d573c1e3..e5d573c1e3 100644..100755
--- a/indra/llmessage/llinvite.h
+++ b/indra/llmessage/llinvite.h
diff --git a/indra/llmessage/lliobuffer.cpp b/indra/llmessage/lliobuffer.cpp
index ed00e230ac..ed00e230ac 100644..100755
--- a/indra/llmessage/lliobuffer.cpp
+++ b/indra/llmessage/lliobuffer.cpp
diff --git a/indra/llmessage/lliobuffer.h b/indra/llmessage/lliobuffer.h
index 3349848947..3349848947 100644..100755
--- a/indra/llmessage/lliobuffer.h
+++ b/indra/llmessage/lliobuffer.h
diff --git a/indra/llmessage/lliohttpserver.cpp b/indra/llmessage/lliohttpserver.cpp
index 987f386aa3..1236fc8b71 100644..100755
--- a/indra/llmessage/lliohttpserver.cpp
+++ b/indra/llmessage/lliohttpserver.cpp
@@ -37,12 +37,10 @@
#include "lliopipe.h"
#include "lliosocket.h"
#include "llioutil.h"
-#include "llmemtype.h"
#include "llmemorystream.h"
#include "llpumpio.h"
#include "llsd.h"
#include "llsdserialize_xml.h"
-#include "llstat.h"
#include "llstl.h"
#include "lltimer.h"
@@ -141,6 +139,11 @@ private:
};
static LLFastTimer::DeclareTimer FTM_PROCESS_HTTP_PIPE("HTTP Pipe");
+static LLFastTimer::DeclareTimer FTM_PROCESS_HTTP_GET("HTTP Get");
+static LLFastTimer::DeclareTimer FTM_PROCESS_HTTP_PUT("HTTP Put");
+static LLFastTimer::DeclareTimer FTM_PROCESS_HTTP_POST("HTTP Post");
+static LLFastTimer::DeclareTimer FTM_PROCESS_HTTP_DELETE("HTTP Delete");
+
LLIOPipe::EStatus LLHTTPPipe::process_impl(
const LLChannelDescriptors& channels,
buffer_ptr_t& buffer,
@@ -177,12 +180,12 @@ LLIOPipe::EStatus LLHTTPPipe::process_impl(
std::string verb = context[CONTEXT_REQUEST][CONTEXT_VERB];
if(verb == HTTP_VERB_GET)
{
- LLPerfBlock getblock("http_get");
+ LLFastTimer _(FTM_PROCESS_HTTP_GET);
mNode.get(LLHTTPNode::ResponsePtr(mResponse), context);
}
else if(verb == HTTP_VERB_PUT)
{
- LLPerfBlock putblock("http_put");
+ LLFastTimer _(FTM_PROCESS_HTTP_PUT);
LLSD input;
if (mNode.getContentType() == LLHTTPNode::CONTENT_TYPE_LLSD)
{
@@ -198,7 +201,7 @@ LLIOPipe::EStatus LLHTTPPipe::process_impl(
}
else if(verb == HTTP_VERB_POST)
{
- LLPerfBlock postblock("http_post");
+ LLFastTimer _(FTM_PROCESS_HTTP_POST);
LLSD input;
if (mNode.getContentType() == LLHTTPNode::CONTENT_TYPE_LLSD)
{
@@ -214,7 +217,7 @@ LLIOPipe::EStatus LLHTTPPipe::process_impl(
}
else if(verb == HTTP_VERB_DELETE)
{
- LLPerfBlock delblock("http_delete");
+ LLFastTimer _(FTM_PROCESS_HTTP_DELETE);
mNode.del(LLHTTPNode::ResponsePtr(mResponse), context);
}
else if(verb == HTTP_VERB_OPTIONS)
@@ -443,7 +446,6 @@ LLIOPipe::EStatus LLHTTPResponseHeader::process_impl(
{
LLFastTimer t(FTM_PROCESS_HTTP_HEADER);
PUMP_DEBUG;
- LLMemType m1(LLMemType::MTYPE_IO_HTTP_SERVER);
if(eos)
{
PUMP_DEBUG;
@@ -587,13 +589,11 @@ LLHTTPResponder::LLHTTPResponder(const LLHTTPNode& tree, const LLSD& ctx) :
mContentLength(0),
mRootNode(tree)
{
- LLMemType m1(LLMemType::MTYPE_IO_HTTP_SERVER);
}
// virtual
LLHTTPResponder::~LLHTTPResponder()
{
- LLMemType m1(LLMemType::MTYPE_IO_HTTP_SERVER);
//lldebugs << "destroying LLHTTPResponder" << llendl;
}
@@ -603,7 +603,6 @@ bool LLHTTPResponder::readHeaderLine(
U8* dest,
S32& len)
{
- LLMemType m1(LLMemType::MTYPE_IO_HTTP_SERVER);
--len;
U8* last = buffer->readAfter(channels.in(), mLastRead, dest, len);
dest[len] = '\0';
@@ -628,7 +627,6 @@ void LLHTTPResponder::markBad(
const LLChannelDescriptors& channels,
buffer_ptr_t buffer)
{
- LLMemType m1(LLMemType::MTYPE_IO_HTTP_SERVER);
mState = STATE_SHORT_CIRCUIT;
LLBufferStream out(channels, buffer.get());
out << HTTP_VERSION_STR << " 400 Bad Request\r\n\r\n<html>\n"
@@ -648,7 +646,6 @@ LLIOPipe::EStatus LLHTTPResponder::process_impl(
{
LLFastTimer t(FTM_PROCESS_HTTP_RESPONDER);
PUMP_DEBUG;
- LLMemType m1(LLMemType::MTYPE_IO_HTTP_SERVER);
LLIOPipe::EStatus status = STATUS_OK;
// parsing headers
diff --git a/indra/llmessage/lliohttpserver.h b/indra/llmessage/lliohttpserver.h
index 5c1b0531ff..5c1b0531ff 100644..100755
--- a/indra/llmessage/lliohttpserver.h
+++ b/indra/llmessage/lliohttpserver.h
diff --git a/indra/llmessage/lliopipe.cpp b/indra/llmessage/lliopipe.cpp
index 8f827f7a30..8f827f7a30 100644..100755
--- a/indra/llmessage/lliopipe.cpp
+++ b/indra/llmessage/lliopipe.cpp
diff --git a/indra/llmessage/lliopipe.h b/indra/llmessage/lliopipe.h
index cbd17b5a3d..cbd17b5a3d 100644..100755
--- a/indra/llmessage/lliopipe.h
+++ b/indra/llmessage/lliopipe.h
diff --git a/indra/llmessage/lliosocket.cpp b/indra/llmessage/lliosocket.cpp
index d5b4d45821..2043bae5e7 100644..100755
--- a/indra/llmessage/lliosocket.cpp
+++ b/indra/llmessage/lliosocket.cpp
@@ -33,7 +33,6 @@
#include "llbuffer.h"
#include "llhost.h"
-#include "llmemtype.h"
#include "llpumpio.h"
//
@@ -100,7 +99,6 @@ void ll_debug_socket(const char* msg, apr_socket_t* apr_sock)
// static
LLSocket::ptr_t LLSocket::create(apr_pool_t* pool, EType type, U16 port)
{
- LLMemType m1(LLMemType::MTYPE_IO_TCP);
LLSocket::ptr_t rv;
apr_socket_t* socket = NULL;
apr_pool_t* new_pool = NULL;
@@ -198,7 +196,6 @@ LLSocket::ptr_t LLSocket::create(apr_pool_t* pool, EType type, U16 port)
// static
LLSocket::ptr_t LLSocket::create(apr_socket_t* socket, apr_pool_t* pool)
{
- LLMemType m1(LLMemType::MTYPE_IO_TCP);
LLSocket::ptr_t rv;
if(!socket)
{
@@ -240,12 +237,10 @@ LLSocket::LLSocket(apr_socket_t* socket, apr_pool_t* pool) :
mPort(PORT_INVALID)
{
ll_debug_socket("Constructing wholely formed socket", mSocket);
- LLMemType m1(LLMemType::MTYPE_IO_TCP);
}
LLSocket::~LLSocket()
{
- LLMemType m1(LLMemType::MTYPE_IO_TCP);
// *FIX: clean up memory we are holding.
if(mSocket)
{
@@ -265,7 +260,6 @@ LLSocket::~LLSocket()
void LLSocket::setBlocking(S32 timeout)
{
- LLMemType m1(LLMemType::MTYPE_IO_TCP);
// set up the socket options
ll_apr_warn_status(apr_socket_timeout_set(mSocket, timeout));
ll_apr_warn_status(apr_socket_opt_set(mSocket, APR_SO_NONBLOCK, 0));
@@ -276,7 +270,6 @@ void LLSocket::setBlocking(S32 timeout)
void LLSocket::setNonBlocking()
{
- LLMemType m1(LLMemType::MTYPE_IO_TCP);
// set up the socket options
ll_apr_warn_status(apr_socket_timeout_set(mSocket, 0));
ll_apr_warn_status(apr_socket_opt_set(mSocket, APR_SO_NONBLOCK, 1));
@@ -293,12 +286,10 @@ LLIOSocketReader::LLIOSocketReader(LLSocket::ptr_t socket) :
mSource(socket),
mInitialized(false)
{
- LLMemType m1(LLMemType::MTYPE_IO_TCP);
}
LLIOSocketReader::~LLIOSocketReader()
{
- LLMemType m1(LLMemType::MTYPE_IO_TCP);
//lldebugs << "Destroying LLIOSocketReader" << llendl;
}
@@ -314,7 +305,6 @@ LLIOPipe::EStatus LLIOSocketReader::process_impl(
{
LLFastTimer t(FTM_PROCESS_SOCKET_READER);
PUMP_DEBUG;
- LLMemType m1(LLMemType::MTYPE_IO_TCP);
if(!mSource) return STATUS_PRECONDITION_NOT_MET;
if(!mInitialized)
{
@@ -396,12 +386,10 @@ LLIOSocketWriter::LLIOSocketWriter(LLSocket::ptr_t socket) :
mLastWritten(NULL),
mInitialized(false)
{
- LLMemType m1(LLMemType::MTYPE_IO_TCP);
}
LLIOSocketWriter::~LLIOSocketWriter()
{
- LLMemType m1(LLMemType::MTYPE_IO_TCP);
//lldebugs << "Destroying LLIOSocketWriter" << llendl;
}
@@ -416,7 +404,6 @@ LLIOPipe::EStatus LLIOSocketWriter::process_impl(
{
LLFastTimer t(FTM_PROCESS_SOCKET_WRITER);
PUMP_DEBUG;
- LLMemType m1(LLMemType::MTYPE_IO_TCP);
if(!mDestination) return STATUS_PRECONDITION_NOT_MET;
if(!mInitialized)
{
@@ -550,12 +537,10 @@ LLIOServerSocket::LLIOServerSocket(
mInitialized(false),
mResponseTimeout(DEFAULT_CHAIN_EXPIRY_SECS)
{
- LLMemType m1(LLMemType::MTYPE_IO_TCP);
}
LLIOServerSocket::~LLIOServerSocket()
{
- LLMemType m1(LLMemType::MTYPE_IO_TCP);
//lldebugs << "Destroying LLIOServerSocket" << llendl;
}
@@ -575,7 +560,6 @@ LLIOPipe::EStatus LLIOServerSocket::process_impl(
{
LLFastTimer t(FTM_PROCESS_SERVER_SOCKET);
PUMP_DEBUG;
- LLMemType m1(LLMemType::MTYPE_IO_TCP);
if(!pump)
{
llwarns << "Need a pump for server socket." << llendl;
@@ -608,6 +592,15 @@ LLIOPipe::EStatus LLIOServerSocket::process_impl(
PUMP_DEBUG;
apr_pool_t* new_pool = NULL;
apr_status_t status = apr_pool_create(&new_pool, mPool);
+ if(ll_apr_warn_status(status))
+ {
+ if(new_pool)
+ {
+ apr_pool_destroy(new_pool);
+ }
+ return STATUS_ERROR;
+ }
+
apr_socket_t* socket = NULL;
status = apr_socket_accept(
&socket,
diff --git a/indra/llmessage/lliosocket.h b/indra/llmessage/lliosocket.h
index be0f7dfcc6..be0f7dfcc6 100644..100755
--- a/indra/llmessage/lliosocket.h
+++ b/indra/llmessage/lliosocket.h
diff --git a/indra/llmessage/llioutil.cpp b/indra/llmessage/llioutil.cpp
index 8c50fd5069..8c50fd5069 100644..100755
--- a/indra/llmessage/llioutil.cpp
+++ b/indra/llmessage/llioutil.cpp
diff --git a/indra/llmessage/llioutil.h b/indra/llmessage/llioutil.h
index e8d245f530..e8d245f530 100644..100755
--- a/indra/llmessage/llioutil.h
+++ b/indra/llmessage/llioutil.h
diff --git a/indra/llmessage/llloginflags.h b/indra/llmessage/llloginflags.h
index 45833fc914..45833fc914 100644..100755
--- a/indra/llmessage/llloginflags.h
+++ b/indra/llmessage/llloginflags.h
diff --git a/indra/llmessage/llmail.cpp b/indra/llmessage/llmail.cpp
index 08b31e9c7a..08b31e9c7a 100644..100755
--- a/indra/llmessage/llmail.cpp
+++ b/indra/llmessage/llmail.cpp
diff --git a/indra/llmessage/llmail.h b/indra/llmessage/llmail.h
index 3791714363..3791714363 100644..100755
--- a/indra/llmessage/llmail.h
+++ b/indra/llmessage/llmail.h
diff --git a/indra/llmessage/llmessagebuilder.cpp b/indra/llmessage/llmessagebuilder.cpp
index e2ed968a57..e2ed968a57 100644..100755
--- a/indra/llmessage/llmessagebuilder.cpp
+++ b/indra/llmessage/llmessagebuilder.cpp
diff --git a/indra/llmessage/llmessagebuilder.h b/indra/llmessage/llmessagebuilder.h
index bf5be929f2..bf5be929f2 100644..100755
--- a/indra/llmessage/llmessagebuilder.h
+++ b/indra/llmessage/llmessagebuilder.h
diff --git a/indra/llmessage/llmessageconfig.cpp b/indra/llmessage/llmessageconfig.cpp
index 539efc65f8..539efc65f8 100644..100755
--- a/indra/llmessage/llmessageconfig.cpp
+++ b/indra/llmessage/llmessageconfig.cpp
diff --git a/indra/llmessage/llmessageconfig.h b/indra/llmessage/llmessageconfig.h
index 1b39c386ca..1b39c386ca 100644..100755
--- a/indra/llmessage/llmessageconfig.h
+++ b/indra/llmessage/llmessageconfig.h
diff --git a/indra/llmessage/llmessagereader.cpp b/indra/llmessage/llmessagereader.cpp
index 1d1bee7f59..1d1bee7f59 100644..100755
--- a/indra/llmessage/llmessagereader.cpp
+++ b/indra/llmessage/llmessagereader.cpp
diff --git a/indra/llmessage/llmessagereader.h b/indra/llmessage/llmessagereader.h
index 3b77a6bfe4..3b77a6bfe4 100644..100755
--- a/indra/llmessage/llmessagereader.h
+++ b/indra/llmessage/llmessagereader.h
diff --git a/indra/llmessage/llmessagesenderinterface.h b/indra/llmessage/llmessagesenderinterface.h
index ac0f9f7edb..ac0f9f7edb 100644..100755
--- a/indra/llmessage/llmessagesenderinterface.h
+++ b/indra/llmessage/llmessagesenderinterface.h
diff --git a/indra/llmessage/llmessagetemplate.cpp b/indra/llmessage/llmessagetemplate.cpp
index d64123ad62..d64123ad62 100644..100755
--- a/indra/llmessage/llmessagetemplate.cpp
+++ b/indra/llmessage/llmessagetemplate.cpp
diff --git a/indra/llmessage/llmessagetemplate.h b/indra/llmessage/llmessagetemplate.h
index 16d825d33b..ae8e0087c1 100644..100755
--- a/indra/llmessage/llmessagetemplate.h
+++ b/indra/llmessage/llmessagetemplate.h
@@ -29,7 +29,6 @@
#include "lldarray.h"
#include "message.h" // TODO: babbage: Remove...
-#include "llstat.h"
#include "llstl.h"
class LLMsgVarData
@@ -263,6 +262,7 @@ enum EMsgDeprecation
MD_DEPRECATED
};
+
class LLMessageTemplate
{
public:
@@ -364,7 +364,6 @@ public:
{
if (mHandlerFunc)
{
- LLPerfBlock msg_cb_time("msg_cb", mName);
mHandlerFunc(msgsystem, mUserData);
return TRUE;
}
diff --git a/indra/llmessage/llmessagetemplateparser.cpp b/indra/llmessage/llmessagetemplateparser.cpp
index b0f19df47c..b0f19df47c 100644..100755
--- a/indra/llmessage/llmessagetemplateparser.cpp
+++ b/indra/llmessage/llmessagetemplateparser.cpp
diff --git a/indra/llmessage/llmessagetemplateparser.h b/indra/llmessage/llmessagetemplateparser.h
index 372a2b292d..372a2b292d 100644..100755
--- a/indra/llmessage/llmessagetemplateparser.h
+++ b/indra/llmessage/llmessagetemplateparser.h
diff --git a/indra/llmessage/llmessagethrottle.cpp b/indra/llmessage/llmessagethrottle.cpp
index 579d6d7187..579d6d7187 100644..100755
--- a/indra/llmessage/llmessagethrottle.cpp
+++ b/indra/llmessage/llmessagethrottle.cpp
diff --git a/indra/llmessage/llmessagethrottle.h b/indra/llmessage/llmessagethrottle.h
index 4ea84f712a..4ea84f712a 100644..100755
--- a/indra/llmessage/llmessagethrottle.h
+++ b/indra/llmessage/llmessagethrottle.h
diff --git a/indra/llmessage/llmime.cpp b/indra/llmessage/llmime.cpp
index 9d9c4ebd68..9d9c4ebd68 100644..100755
--- a/indra/llmessage/llmime.cpp
+++ b/indra/llmessage/llmime.cpp
diff --git a/indra/llmessage/llmime.h b/indra/llmessage/llmime.h
index e6617fb503..e6617fb503 100644..100755
--- a/indra/llmessage/llmime.h
+++ b/indra/llmessage/llmime.h
diff --git a/indra/llmessage/llmsgvariabletype.h b/indra/llmessage/llmsgvariabletype.h
index c4de822b46..c4de822b46 100644..100755
--- a/indra/llmessage/llmsgvariabletype.h
+++ b/indra/llmessage/llmsgvariabletype.h
diff --git a/indra/llmessage/llnamevalue.cpp b/indra/llmessage/llnamevalue.cpp
index d799403029..d799403029 100644..100755
--- a/indra/llmessage/llnamevalue.cpp
+++ b/indra/llmessage/llnamevalue.cpp
diff --git a/indra/llmessage/llnamevalue.h b/indra/llmessage/llnamevalue.h
index 273de475f8..273de475f8 100644..100755
--- a/indra/llmessage/llnamevalue.h
+++ b/indra/llmessage/llnamevalue.h
diff --git a/indra/llmessage/llnullcipher.cpp b/indra/llmessage/llnullcipher.cpp
index b32e7e6fa6..b32e7e6fa6 100644..100755
--- a/indra/llmessage/llnullcipher.cpp
+++ b/indra/llmessage/llnullcipher.cpp
diff --git a/indra/llmessage/llnullcipher.h b/indra/llmessage/llnullcipher.h
index a9f9a1ce03..a9f9a1ce03 100644..100755
--- a/indra/llmessage/llnullcipher.h
+++ b/indra/llmessage/llnullcipher.h
diff --git a/indra/llmessage/llpacketack.cpp b/indra/llmessage/llpacketack.cpp
index f08d3404ea..f08d3404ea 100644..100755
--- a/indra/llmessage/llpacketack.cpp
+++ b/indra/llmessage/llpacketack.cpp
diff --git a/indra/llmessage/llpacketack.h b/indra/llmessage/llpacketack.h
index 2ef3c48e44..2ef3c48e44 100644..100755
--- a/indra/llmessage/llpacketack.h
+++ b/indra/llmessage/llpacketack.h
diff --git a/indra/llmessage/llpacketbuffer.cpp b/indra/llmessage/llpacketbuffer.cpp
index e69631eb3b..e69631eb3b 100644..100755
--- a/indra/llmessage/llpacketbuffer.cpp
+++ b/indra/llmessage/llpacketbuffer.cpp
diff --git a/indra/llmessage/llpacketbuffer.h b/indra/llmessage/llpacketbuffer.h
index 14b6f9d5d2..14b6f9d5d2 100644..100755
--- a/indra/llmessage/llpacketbuffer.h
+++ b/indra/llmessage/llpacketbuffer.h
diff --git a/indra/llmessage/llpacketring.cpp b/indra/llmessage/llpacketring.cpp
index fc6e9c5193..fc6e9c5193 100644..100755
--- a/indra/llmessage/llpacketring.cpp
+++ b/indra/llmessage/llpacketring.cpp
diff --git a/indra/llmessage/llpacketring.h b/indra/llmessage/llpacketring.h
index b214271e78..b214271e78 100644..100755
--- a/indra/llmessage/llpacketring.h
+++ b/indra/llmessage/llpacketring.h
diff --git a/indra/llmessage/llpartdata.cpp b/indra/llmessage/llpartdata.cpp
index 26cafa025f..41a0310ce0 100644..100755
--- a/indra/llmessage/llpartdata.cpp
+++ b/indra/llmessage/llpartdata.cpp
@@ -37,53 +37,46 @@
-const S32 PS_PART_DATA_BLOCK_SIZE = 4 + 2 + 4 + 4 + 2 + 2; // 18
-const S32 PS_DATA_BLOCK_SIZE = 68 + PS_PART_DATA_BLOCK_SIZE; // 68 + 18 = 86
+const S32 PS_PART_DATA_GLOW_SIZE = 2;
+const S32 PS_PART_DATA_BLEND_SIZE = 2;
+const S32 PS_LEGACY_PART_DATA_BLOCK_SIZE = 4 + 2 + 4 + 4 + 2 + 2; //18
+const S32 PS_SYS_DATA_BLOCK_SIZE = 68;
+const S32 PS_MAX_DATA_BLOCK_SIZE = PS_SYS_DATA_BLOCK_SIZE+
+ PS_LEGACY_PART_DATA_BLOCK_SIZE +
+ PS_PART_DATA_BLEND_SIZE +
+ PS_PART_DATA_GLOW_SIZE+
+ 8; //two S32 size fields
+
+const S32 PS_LEGACY_DATA_BLOCK_SIZE = PS_SYS_DATA_BLOCK_SIZE + PS_LEGACY_PART_DATA_BLOCK_SIZE;
+
+
+const U32 PART_DATA_MASK = LLPartData::LL_PART_DATA_GLOW | LLPartData::LL_PART_DATA_BLEND;
+
const F32 MAX_PART_SCALE = 4.f;
-BOOL LLPartData::pack(LLDataPacker &dp)
+bool LLPartData::hasGlow() const
{
- LLColor4U coloru;
- dp.packU32(mFlags, "pdflags");
- dp.packFixed(mMaxAge, "pdmaxage", FALSE, 8, 8);
- coloru.setVec(mStartColor);
- dp.packColor4U(coloru, "pdstartcolor");
- coloru.setVec(mEndColor);
- dp.packColor4U(coloru, "pdendcolor");
- dp.packFixed(mStartScale.mV[0], "pdstartscalex", FALSE, 3, 5);
- dp.packFixed(mStartScale.mV[1], "pdstartscaley", FALSE, 3, 5);
- dp.packFixed(mEndScale.mV[0], "pdendscalex", FALSE, 3, 5);
- dp.packFixed(mEndScale.mV[1], "pdendscaley", FALSE, 3, 5);
- return TRUE;
+ return mStartGlow > 0.f || mEndGlow > 0.f;
}
-LLSD LLPartData::asLLSD() const
+bool LLPartData::hasBlendFunc() const
{
- LLSD sd = LLSD();
- sd["pdflags"] = ll_sd_from_U32(mFlags);
- sd["pdmaxage"] = mMaxAge;
- sd["pdstartcolor"] = ll_sd_from_color4(mStartColor);
- sd["pdendcolor"] = ll_sd_from_color4(mEndColor);
- sd["pdstartscale"] = ll_sd_from_vector2(mStartScale);
- sd["pdendscale"] = ll_sd_from_vector2(mEndScale);
- return sd;
+ return mBlendFuncSource != LLPartData::LL_PART_BF_SOURCE_ALPHA || mBlendFuncDest != LLPartData::LL_PART_BF_ONE_MINUS_SOURCE_ALPHA;
}
-bool LLPartData::fromLLSD(LLSD& sd)
+S32 LLPartData::getSize() const
{
- mFlags = ll_U32_from_sd(sd["pdflags"]);
- mMaxAge = (F32)sd["pdmaxage"].asReal();
- mStartColor = ll_color4_from_sd(sd["pdstartcolor"]);
- mEndColor = ll_color4_from_sd(sd["pdendcolor"]);
- mStartScale = ll_vector2_from_sd(sd["pdstartscale"]);
- mEndScale = ll_vector2_from_sd(sd["pdendscale"]);
- return true;
+ S32 size = PS_LEGACY_PART_DATA_BLOCK_SIZE;
+ if (hasGlow()) size += PS_PART_DATA_GLOW_SIZE;
+ if (hasBlendFunc()) size += PS_PART_DATA_BLEND_SIZE;
+
+ return size;
}
-BOOL LLPartData::unpack(LLDataPacker &dp)
+BOOL LLPartData::unpackLegacy(LLDataPacker &dp)
{
LLColor4U coloru;
@@ -98,9 +91,70 @@ BOOL LLPartData::unpack(LLDataPacker &dp)
dp.unpackFixed(mStartScale.mV[1], "pdstartscaley", FALSE, 3, 5);
dp.unpackFixed(mEndScale.mV[0], "pdendscalex", FALSE, 3, 5);
dp.unpackFixed(mEndScale.mV[1], "pdendscaley", FALSE, 3, 5);
+
+ mStartGlow = 0.f;
+ mEndGlow = 0.f;
+ mBlendFuncSource = LLPartData::LL_PART_BF_SOURCE_ALPHA;
+ mBlendFuncDest = LLPartData::LL_PART_BF_ONE_MINUS_SOURCE_ALPHA;
+
return TRUE;
}
+BOOL LLPartData::unpack(LLDataPacker &dp)
+{
+ S32 size = 0;
+ dp.unpackS32(size, "partsize");
+
+ unpackLegacy(dp);
+ size -= PS_LEGACY_PART_DATA_BLOCK_SIZE;
+
+ if (mFlags & LL_PART_DATA_GLOW)
+ {
+ if (size < PS_PART_DATA_GLOW_SIZE) return FALSE;
+
+ U8 tmp_glow = 0;
+ dp.unpackU8(tmp_glow,"pdstartglow");
+ mStartGlow = tmp_glow / 255.f;
+ dp.unpackU8(tmp_glow,"pdendglow");
+ mEndGlow = tmp_glow / 255.f;
+
+ size -= PS_PART_DATA_GLOW_SIZE;
+ }
+ else
+ {
+ mStartGlow = 0.f;
+ mEndGlow = 0.f;
+ }
+
+ if (mFlags & LL_PART_DATA_BLEND)
+ {
+ if (size < PS_PART_DATA_BLEND_SIZE) return FALSE;
+ dp.unpackU8(mBlendFuncSource,"pdblendsource");
+ dp.unpackU8(mBlendFuncDest,"pdblenddest");
+ size -= PS_PART_DATA_BLEND_SIZE;
+ }
+ else
+ {
+ mBlendFuncSource = LLPartData::LL_PART_BF_SOURCE_ALPHA;
+ mBlendFuncDest = LLPartData::LL_PART_BF_ONE_MINUS_SOURCE_ALPHA;
+ }
+
+ if (size > 0)
+ { //leftover bytes, unrecognized parameters
+ U8 feh = 0;
+ while (size > 0)
+ { //read remaining bytes in block
+ dp.unpackU8(feh, "whippang");
+ size--;
+ }
+
+ //this particle system won't display properly, better to not show anything
+ return FALSE;
+ }
+
+
+ return TRUE;
+}
void LLPartData::setFlags(const U32 flags)
{
@@ -148,6 +202,18 @@ void LLPartData::setEndAlpha(const F32 alpha)
mEndColor.mV[3] = alpha;
}
+// static
+bool LLPartData::validBlendFunc(S32 func)
+{
+ if (func >= 0
+ && func < LL_PART_BF_COUNT
+ && func != UNSUPPORTED_DEST_ALPHA
+ && func != UNSUPPORTED_ONE_MINUS_DEST_ALPHA)
+ {
+ return true;
+ }
+ return false;
+}
LLPartSysData::LLPartSysData()
{
@@ -160,6 +226,10 @@ LLPartSysData::LLPartSysData()
mPartData.mStartScale = LLVector2(1.f, 1.f);
mPartData.mEndScale = LLVector2(1.f, 1.f);
mPartData.mMaxAge = 10.0;
+ mPartData.mBlendFuncSource = LLPartData::LL_PART_BF_SOURCE_ALPHA;
+ mPartData.mBlendFuncDest = LLPartData::LL_PART_BF_ONE_MINUS_SOURCE_ALPHA;
+ mPartData.mStartGlow = 0.f;
+ mPartData.mEndGlow = 0.f;
mMaxAge = 0.0;
mStartAge = 0.0;
@@ -175,38 +245,7 @@ LLPartSysData::LLPartSysData()
mNumParticles = 0;
}
-
-BOOL LLPartSysData::pack(LLDataPacker &dp)
-{
- dp.packU32(mCRC, "pscrc");
- dp.packU32(mFlags, "psflags");
- dp.packU8(mPattern, "pspattern");
- dp.packFixed(mMaxAge, "psmaxage", FALSE, 8, 8);
- dp.packFixed(mStartAge, "psstartage", FALSE, 8, 8);
- dp.packFixed(mInnerAngle, "psinnerangle", FALSE, 3, 5);
- dp.packFixed(mOuterAngle, "psouterangle", FALSE, 3, 5);
- dp.packFixed(mBurstRate, "psburstrate", FALSE, 8, 8);
- dp.packFixed(mBurstRadius, "psburstradius", FALSE, 8, 8);
- dp.packFixed(mBurstSpeedMin, "psburstspeedmin", FALSE, 8, 8);
- dp.packFixed(mBurstSpeedMax, "psburstspeedmax", FALSE, 8, 8);
- dp.packU8(mBurstPartCount, "psburstpartcount");
-
- dp.packFixed(mAngularVelocity.mV[0], "psangvelx", TRUE, 8, 7);
- dp.packFixed(mAngularVelocity.mV[1], "psangvely", TRUE, 8, 7);
- dp.packFixed(mAngularVelocity.mV[2], "psangvelz", TRUE, 8, 7);
-
- dp.packFixed(mPartAccel.mV[0], "psaccelx", TRUE, 8, 7);
- dp.packFixed(mPartAccel.mV[1], "psaccely", TRUE, 8, 7);
- dp.packFixed(mPartAccel.mV[2], "psaccelz", TRUE, 8, 7);
-
- dp.packUUID(mPartImageID, "psuuid");
- dp.packUUID(mTargetUUID, "pstargetuuid");
- mPartData.pack(dp);
- return TRUE;
-}
-
-
-BOOL LLPartSysData::unpack(LLDataPacker &dp)
+BOOL LLPartSysData::unpackSystem(LLDataPacker &dp)
{
dp.unpackU32(mCRC, "pscrc");
dp.unpackU32(mFlags, "psflags");
@@ -232,10 +271,48 @@ BOOL LLPartSysData::unpack(LLDataPacker &dp)
dp.unpackUUID(mPartImageID, "psuuid");
dp.unpackUUID(mTargetUUID, "pstargetuuid");
- mPartData.unpack(dp);
return TRUE;
}
+BOOL LLPartSysData::unpackLegacy(LLDataPacker &dp)
+{
+ unpackSystem(dp);
+ mPartData.unpackLegacy(dp);
+
+ return TRUE;
+}
+
+BOOL LLPartSysData::unpack(LLDataPacker &dp)
+{
+ // syssize is currently unused. Adding now when modifying the 'version to make extensible in the future
+ S32 size = 0;
+ dp.unpackS32(size, "syssize");
+
+ if (size != PS_SYS_DATA_BLOCK_SIZE)
+ { //unexpected size, this viewer doesn't know how to parse this particle system
+
+ //skip to LLPartData block
+ U8 feh = 0;
+
+ for (U32 i = 0; i < size; ++i)
+ {
+ dp.unpackU8(feh, "whippang");
+ }
+
+ dp.unpackS32(size, "partsize");
+ //skip LLPartData block
+ for (U32 i = 0; i < size; ++i)
+ {
+ dp.unpackU8(feh, "whippang");
+ }
+ return FALSE;
+ }
+
+ unpackSystem(dp);
+
+ return mPartData.unpack(dp);
+}
+
std::ostream& operator<<(std::ostream& s, const LLPartSysData &data)
{
s << "Flags: " << std::hex << data.mFlags;
@@ -253,7 +330,7 @@ std::ostream& operator<<(std::ostream& s, const LLPartSysData &data)
BOOL LLPartSysData::isNullPS(const S32 block_num)
{
- U8 ps_data_block[PS_DATA_BLOCK_SIZE];
+ U8 ps_data_block[PS_MAX_DATA_BLOCK_SIZE];
U32 crc;
S32 size;
@@ -264,14 +341,28 @@ BOOL LLPartSysData::isNullPS(const S32 block_num)
{
return TRUE;
}
- else if (size != PS_DATA_BLOCK_SIZE)
+
+ if (size > PS_MAX_DATA_BLOCK_SIZE)
{
- llwarns << "PSBlock is wrong size for particle system data - got " << size << ", expecting " << PS_DATA_BLOCK_SIZE << llendl;
+ //size is too big, newer particle version unsupported
return TRUE;
}
- gMessageSystem->getBinaryData("ObjectData", "PSBlock", ps_data_block, PS_DATA_BLOCK_SIZE, block_num, PS_DATA_BLOCK_SIZE);
- LLDataPackerBinaryBuffer dp(ps_data_block, PS_DATA_BLOCK_SIZE);
+ gMessageSystem->getBinaryData("ObjectData", "PSBlock", ps_data_block, size, block_num, PS_MAX_DATA_BLOCK_SIZE);
+
+ LLDataPackerBinaryBuffer dp(ps_data_block, size);
+ if (size > PS_LEGACY_DATA_BLOCK_SIZE)
+ {
+ // non legacy systems pack a size before the CRC
+ S32 tmp = 0;
+ dp.unpackS32(tmp, "syssize");
+
+ if (tmp > PS_SYS_DATA_BLOCK_SIZE)
+ { //unknown system data block size, don't know how to parse it, treat as NULL
+ return TRUE;
+ }
+ }
+
dp.unpackU32(crc, "crc");
if (crc == 0)
@@ -281,50 +372,37 @@ BOOL LLPartSysData::isNullPS(const S32 block_num)
return FALSE;
}
-
-//static
-BOOL LLPartSysData::packNull()
-{
- U8 ps_data_block[PS_DATA_BLOCK_SIZE];
- gMessageSystem->addBinaryData("PSBlock", ps_data_block, 0);
- return TRUE;
-}
-
-
-BOOL LLPartSysData::packBlock()
-{
- U8 ps_data_block[PS_DATA_BLOCK_SIZE];
-
- LLDataPackerBinaryBuffer dp(ps_data_block, PS_DATA_BLOCK_SIZE);
- pack(dp);
-
- // Add to message
- gMessageSystem->addBinaryData("PSBlock", ps_data_block, PS_DATA_BLOCK_SIZE);
-
- return TRUE;
-}
-
-
BOOL LLPartSysData::unpackBlock(const S32 block_num)
{
- U8 ps_data_block[PS_DATA_BLOCK_SIZE];
+ U8 ps_data_block[PS_MAX_DATA_BLOCK_SIZE];
// Check size of block
S32 size = gMessageSystem->getSize("ObjectData", block_num, "PSBlock");
- if (size != PS_DATA_BLOCK_SIZE)
+ if (size > PS_MAX_DATA_BLOCK_SIZE)
{
- llwarns << "PSBlock is wrong size for particle system data - got " << size << ", expecting " << PS_DATA_BLOCK_SIZE << llendl;
+ // Larger packets are newer and unsupported
return FALSE;
}
// Get from message
- gMessageSystem->getBinaryData("ObjectData", "PSBlock", ps_data_block, PS_DATA_BLOCK_SIZE, block_num, PS_DATA_BLOCK_SIZE);
+ gMessageSystem->getBinaryData("ObjectData", "PSBlock", ps_data_block, size, block_num, PS_MAX_DATA_BLOCK_SIZE);
- LLDataPackerBinaryBuffer dp(ps_data_block, PS_DATA_BLOCK_SIZE);
- unpack(dp);
+ LLDataPackerBinaryBuffer dp(ps_data_block, size);
- return TRUE;
+ if (size == PS_LEGACY_DATA_BLOCK_SIZE)
+ {
+ return unpackLegacy(dp);
+ }
+ else
+ {
+ return unpack(dp);
+ }
+}
+
+bool LLPartSysData::isLegacyCompatible() const
+{
+ return !mPartData.hasGlow() && !mPartData.hasBlendFunc();
}
void LLPartSysData::clampSourceParticleRate()
diff --git a/indra/llmessage/llpartdata.h b/indra/llmessage/llpartdata.h
index a4ef058b30..ed5c1a6ac7 100644..100755
--- a/indra/llmessage/llpartdata.h
+++ b/indra/llmessage/llpartdata.h
@@ -70,7 +70,12 @@ enum LLPSScriptFlags
LLPS_SRC_TARGET_UUID,
LLPS_SRC_OMEGA,
LLPS_SRC_ANGLE_BEGIN,
- LLPS_SRC_ANGLE_END
+ LLPS_SRC_ANGLE_END,
+
+ LLPS_PART_BLEND_FUNC_SOURCE,
+ LLPS_PART_BLEND_FUNC_DEST,
+ LLPS_PART_START_GLOW,
+ LLPS_PART_END_GLOW
};
@@ -83,11 +88,13 @@ public:
mParameter(0.f)
{
}
+ BOOL unpackLegacy(LLDataPacker &dp);
BOOL unpack(LLDataPacker &dp);
+
BOOL pack(LLDataPacker &dp);
- LLSD asLLSD() const;
- operator LLSD() const {return asLLSD(); }
- bool fromLLSD(LLSD& sd);
+
+ bool hasGlow() const;
+ bool hasBlendFunc() const;
// Masks for the different particle flags
enum
@@ -102,17 +109,39 @@ public:
LL_PART_TARGET_LINEAR_MASK = 0x80, // Particle uses a direct linear interpolation
LL_PART_EMISSIVE_MASK = 0x100, // Particle is "emissive", instead of being lit
LL_PART_BEAM_MASK = 0x200, // Particle is a "beam" connecting source and target
+ LL_PART_RIBBON_MASK = 0x400, // Particles are joined together into one continuous triangle strip
// Not implemented yet!
//LL_PART_RANDOM_ACCEL_MASK = 0x100, // Particles have random acceleration
//LL_PART_RANDOM_VEL_MASK = 0x200, // Particles have random velocity shifts"
//LL_PART_TRAIL_MASK = 0x400, // Particles have historical "trails"
+ //sYSTEM SET FLAGS
+ LL_PART_DATA_GLOW = 0x10000,
+ LL_PART_DATA_BLEND = 0x20000,
+
// Viewer side use only!
LL_PART_HUD = 0x40000000,
LL_PART_DEAD_MASK = 0x80000000,
};
+ enum
+ {
+ LL_PART_BF_ONE = 0,
+ LL_PART_BF_ZERO = 1,
+ LL_PART_BF_DEST_COLOR = 2,
+ LL_PART_BF_SOURCE_COLOR = 3,
+ LL_PART_BF_ONE_MINUS_DEST_COLOR = 4,
+ LL_PART_BF_ONE_MINUS_SOURCE_COLOR = 5,
+ UNSUPPORTED_DEST_ALPHA = 6,
+ LL_PART_BF_SOURCE_ALPHA = 7,
+ UNSUPPORTED_ONE_MINUS_DEST_ALPHA = 8,
+ LL_PART_BF_ONE_MINUS_SOURCE_ALPHA = 9,
+ LL_PART_BF_COUNT = 10
+ };
+
+ static bool validBlendFunc(S32 func);
+
void setFlags(const U32 flags);
void setMaxAge(const F32 max_age);
void setStartScale(const F32 xs, F32 ys);
@@ -126,6 +155,9 @@ public:
friend class LLPartSysData;
friend class LLViewerPartSourceScript;
+private:
+ S32 getSize() const;
+
// These are public because I'm really lazy...
public:
U32 mFlags; // Particle state/interpolators in effect
@@ -137,6 +169,12 @@ public:
LLVector3 mPosOffset; // Offset from source if using FOLLOW_SOURCE
F32 mParameter; // A single floating point parameter
+
+ F32 mStartGlow;
+ F32 mEndGlow;
+
+ U8 mBlendFuncSource;
+ U8 mBlendFuncDest;
};
@@ -146,15 +184,13 @@ public:
LLPartSysData();
BOOL unpack(LLDataPacker &dp);
- BOOL pack(LLDataPacker &dp);
-
-
+ BOOL unpackLegacy(LLDataPacker &dp);
BOOL unpackBlock(const S32 block_num);
- BOOL packBlock();
-
- static BOOL packNull();
+
static BOOL isNullPS(const S32 block_num); // Returns FALSE if this is a "NULL" particle system (i.e. no system)
+ bool isLegacyCompatible() const;
+
// Different masks for effects on the source
enum
{
@@ -187,7 +223,12 @@ public:
void clampSourceParticleRate();
friend std::ostream& operator<<(std::ostream& s, const LLPartSysData &data); // Stream a
+
+ S32 getdataBlockSize() const;
+private:
+ BOOL unpackSystem(LLDataPacker &dp);
+
public:
// Public because I'm lazy....
diff --git a/indra/llmessage/llproxy.cpp b/indra/llmessage/llproxy.cpp
index 9988fcd9c0..9988fcd9c0 100644..100755
--- a/indra/llmessage/llproxy.cpp
+++ b/indra/llmessage/llproxy.cpp
diff --git a/indra/llmessage/llproxy.h b/indra/llmessage/llproxy.h
index a919370540..a919370540 100644..100755
--- a/indra/llmessage/llproxy.h
+++ b/indra/llmessage/llproxy.h
diff --git a/indra/llmessage/llpumpio.cpp b/indra/llmessage/llpumpio.cpp
index f3ef4f2684..0623e99f0a 100644..100755
--- a/indra/llmessage/llpumpio.cpp
+++ b/indra/llmessage/llpumpio.cpp
@@ -34,9 +34,7 @@
#include "apr_poll.h"
#include "llapr.h"
-#include "llmemtype.h"
#include "llstl.h"
-#include "llstat.h"
// These should not be enabled in production, but they can be
// intensely useful during development for finding certain kinds of
@@ -153,7 +151,6 @@ struct ll_delete_apr_pollset_fd_client_data
typedef std::pair<LLIOPipe::ptr_t, apr_pollfd_t> pipe_conditional_t;
void operator()(const pipe_conditional_t& conditional)
{
- LLMemType m1(LLMemType::MTYPE_IO_PUMP);
S32* client_id = (S32*)conditional.second.client_data;
delete client_id;
}
@@ -177,19 +174,16 @@ LLPumpIO::LLPumpIO(apr_pool_t* pool) :
{
mCurrentChain = mRunningChains.end();
- LLMemType m1(LLMemType::MTYPE_IO_PUMP);
initialize(pool);
}
LLPumpIO::~LLPumpIO()
{
- LLMemType m1(LLMemType::MTYPE_IO_PUMP);
cleanup();
}
bool LLPumpIO::prime(apr_pool_t* pool)
{
- LLMemType m1(LLMemType::MTYPE_IO_PUMP);
cleanup();
initialize(pool);
return ((pool == NULL) ? false : true);
@@ -197,7 +191,6 @@ bool LLPumpIO::prime(apr_pool_t* pool)
bool LLPumpIO::addChain(const chain_t& chain, F32 timeout, bool has_curl_request)
{
- LLMemType m1(LLMemType::MTYPE_IO_PUMP);
if(chain.empty()) return false;
#if LL_THREADS_APR
@@ -233,7 +226,6 @@ bool LLPumpIO::addChain(
LLSD context,
F32 timeout)
{
- LLMemType m1(LLMemType::MTYPE_IO_PUMP);
// remember that if the caller is providing a full link
// description, we need to have that description matched to a
@@ -311,7 +303,6 @@ static std::string events_2_string(apr_int16_t events)
bool LLPumpIO::setConditional(LLIOPipe* pipe, const apr_pollfd_t* poll)
{
- LLMemType m1(LLMemType::MTYPE_IO_PUMP);
if(!pipe) return false;
ll_debug_poll_fd("Set conditional", poll);
@@ -423,7 +414,6 @@ bool LLPumpIO::sleepChain(F64 seconds)
bool LLPumpIO::copyCurrentLinkInfo(links_t& links) const
{
- LLMemType m1(LLMemType::MTYPE_IO_PUMP);
if(mRunningChains.end() == mCurrentChain)
{
return false;
@@ -441,6 +431,7 @@ void LLPumpIO::pump()
}
static LLFastTimer::DeclareTimer FTM_PUMP_IO("Pump IO");
+static LLFastTimer::DeclareTimer FTM_PUMP_POLL("Pump Poll");
LLPumpIO::current_chain_t LLPumpIO::removeRunningChain(LLPumpIO::current_chain_t& run_chain)
{
@@ -454,7 +445,6 @@ LLPumpIO::current_chain_t LLPumpIO::removeRunningChain(LLPumpIO::current_chain_t
//timeout is in microseconds
void LLPumpIO::pump(const S32& poll_timeout)
{
- LLMemType m1(LLMemType::MTYPE_IO_PUMP);
LLFastTimer t1(FTM_PUMP_IO);
//llinfos << "LLPumpIO::pump()" << llendl;
@@ -536,7 +526,7 @@ void LLPumpIO::pump(const S32& poll_timeout)
S32 count = 0;
S32 client_id = 0;
{
- LLPerfBlock polltime("pump_poll");
+ LLFastTimer _(FTM_PUMP_POLL);
apr_pollset_poll(mPollset, poll_timeout, &count, &poll_fd);
}
PUMP_DEBUG;
@@ -747,7 +737,6 @@ void LLPumpIO::pump(const S32& poll_timeout)
bool LLPumpIO::respond(LLIOPipe* pipe)
{
- LLMemType m1(LLMemType::MTYPE_IO_PUMP);
if(NULL == pipe) return false;
#if LL_THREADS_APR
@@ -766,7 +755,6 @@ bool LLPumpIO::respond(
LLIOPipe::buffer_ptr_t data,
LLSD context)
{
- LLMemType m1(LLMemType::MTYPE_IO_PUMP);
// if the caller is providing a full link description, we need to
// have that description matched to a particular buffer.
if(!data) return false;
@@ -789,7 +777,6 @@ static LLFastTimer::DeclareTimer FTM_PUMP_CALLBACK_CHAIN("Chain");
void LLPumpIO::callback()
{
- LLMemType m1(LLMemType::MTYPE_IO_PUMP);
//llinfos << "LLPumpIO::callback()" << llendl;
if(true)
{
@@ -840,7 +827,6 @@ void LLPumpIO::control(LLPumpIO::EControl op)
void LLPumpIO::initialize(apr_pool_t* pool)
{
- LLMemType m1(LLMemType::MTYPE_IO_PUMP);
if(!pool) return;
#if LL_THREADS_APR
// SJB: Windows defaults to NESTED and OSX defaults to UNNESTED, so use UNNESTED explicitly.
@@ -852,7 +838,6 @@ void LLPumpIO::initialize(apr_pool_t* pool)
void LLPumpIO::cleanup()
{
- LLMemType m1(LLMemType::MTYPE_IO_PUMP);
#if LL_THREADS_APR
if(mChainsMutex) apr_thread_mutex_destroy(mChainsMutex);
if(mCallbackMutex) apr_thread_mutex_destroy(mCallbackMutex);
@@ -875,7 +860,6 @@ void LLPumpIO::cleanup()
void LLPumpIO::rebuildPollset()
{
- LLMemType m1(LLMemType::MTYPE_IO_PUMP);
// lldebugs << "LLPumpIO::rebuildPollset()" << llendl;
if(mPollset)
{
@@ -928,7 +912,6 @@ void LLPumpIO::rebuildPollset()
void LLPumpIO::processChain(LLChainInfo& chain)
{
PUMP_DEBUG;
- LLMemType m1(LLMemType::MTYPE_IO_PUMP);
LLIOPipe::EStatus status = LLIOPipe::STATUS_OK;
links_t::iterator it = chain.mHead;
links_t::iterator end = chain.mChainLinks.end();
@@ -1130,7 +1113,6 @@ bool LLPumpIO::handleChainError(
LLChainInfo& chain,
LLIOPipe::EStatus error)
{
- LLMemType m1(LLMemType::MTYPE_IO_PUMP);
links_t::reverse_iterator rit;
if(chain.mHead == chain.mChainLinks.end())
{
@@ -1194,13 +1176,11 @@ LLPumpIO::LLChainInfo::LLChainInfo() :
mEOS(false),
mHasCurlRequest(false)
{
- LLMemType m1(LLMemType::MTYPE_IO_PUMP);
mTimer.setTimerExpirySec(DEFAULT_CHAIN_EXPIRY_SECS);
}
void LLPumpIO::LLChainInfo::setTimeoutSeconds(F32 timeout)
{
- LLMemType m1(LLMemType::MTYPE_IO_PUMP);
if(timeout > 0.0f)
{
mTimer.start();
@@ -1215,7 +1195,6 @@ void LLPumpIO::LLChainInfo::setTimeoutSeconds(F32 timeout)
void LLPumpIO::LLChainInfo::adjustTimeoutSeconds(F32 delta)
{
- LLMemType m1(LLMemType::MTYPE_IO_PUMP);
if(mTimer.getStarted())
{
F64 expiry = mTimer.expiresAt();
diff --git a/indra/llmessage/llpumpio.h b/indra/llmessage/llpumpio.h
index d2c5d37571..d2c5d37571 100644..100755
--- a/indra/llmessage/llpumpio.h
+++ b/indra/llmessage/llpumpio.h
diff --git a/indra/llmessage/llqueryflags.h b/indra/llmessage/llqueryflags.h
index 14a62de04f..14a62de04f 100644..100755
--- a/indra/llmessage/llqueryflags.h
+++ b/indra/llmessage/llqueryflags.h
diff --git a/indra/llmessage/llregionflags.h b/indra/llmessage/llregionflags.h
index 7b796a0fa8..1cf940918b 100644..100755
--- a/indra/llmessage/llregionflags.h
+++ b/indra/llmessage/llregionflags.h
@@ -28,95 +28,98 @@
#define LL_LLREGIONFLAGS_H
// Can you be hurt here? Should health be on?
-const U32 REGION_FLAGS_ALLOW_DAMAGE = (1 << 0);
+const U64 REGION_FLAGS_ALLOW_DAMAGE = (1 << 0);
// Can you make landmarks here?
-const U32 REGION_FLAGS_ALLOW_LANDMARK = (1 << 1);
+const U64 REGION_FLAGS_ALLOW_LANDMARK = (1 << 1);
// Do we reset the home position when someone teleports away from here?
-const U32 REGION_FLAGS_ALLOW_SET_HOME = (1 << 2);
+const U64 REGION_FLAGS_ALLOW_SET_HOME = (1 << 2);
// Do we reset the home position when someone teleports away from here?
-const U32 REGION_FLAGS_RESET_HOME_ON_TELEPORT = (1 << 3);
+const U64 REGION_FLAGS_RESET_HOME_ON_TELEPORT = (1 << 3);
// Does the sun move?
-const U32 REGION_FLAGS_SUN_FIXED = (1 << 4);
+const U64 REGION_FLAGS_SUN_FIXED = (1 << 4);
// Can't change the terrain heightfield, even on owned parcels,
// but can plant trees and grass.
-const U32 REGION_FLAGS_BLOCK_TERRAFORM = (1 << 6);
+const U64 REGION_FLAGS_BLOCK_TERRAFORM = (1 << 6);
// Can't release, sell, or buy land.
-const U32 REGION_FLAGS_BLOCK_LAND_RESELL = (1 << 7);
+const U64 REGION_FLAGS_BLOCK_LAND_RESELL = (1 << 7);
// All content wiped once per night
-const U32 REGION_FLAGS_SANDBOX = (1 << 8);
-const U32 REGION_FLAGS_SKIP_COLLISIONS = (1 << 12); // Pin all non agent rigid bodies
-const U32 REGION_FLAGS_SKIP_SCRIPTS = (1 << 13);
-const U32 REGION_FLAGS_SKIP_PHYSICS = (1 << 14); // Skip all physics
-const U32 REGION_FLAGS_EXTERNALLY_VISIBLE = (1 << 15);
-const U32 REGION_FLAGS_ALLOW_RETURN_ENCROACHING_OBJECT = (1 << 16);
-const U32 REGION_FLAGS_ALLOW_RETURN_ENCROACHING_ESTATE_OBJECT = (1 << 17);
-const U32 REGION_FLAGS_BLOCK_DWELL = (1 << 18);
+const U64 REGION_FLAGS_SANDBOX = (1 << 8);
+const U64 REGION_FLAGS_SKIP_COLLISIONS = (1 << 12); // Pin all non agent rigid bodies
+const U64 REGION_FLAGS_SKIP_SCRIPTS = (1 << 13);
+const U64 REGION_FLAGS_SKIP_PHYSICS = (1 << 14); // Skip all physics
+const U64 REGION_FLAGS_EXTERNALLY_VISIBLE = (1 << 15);
+const U64 REGION_FLAGS_ALLOW_RETURN_ENCROACHING_OBJECT = (1 << 16);
+const U64 REGION_FLAGS_ALLOW_RETURN_ENCROACHING_ESTATE_OBJECT = (1 << 17);
+const U64 REGION_FLAGS_BLOCK_DWELL = (1 << 18);
// Is flight allowed?
-const U32 REGION_FLAGS_BLOCK_FLY = (1 << 19);
+const U64 REGION_FLAGS_BLOCK_FLY = (1 << 19);
// Is direct teleport (p2p) allowed?
-const U32 REGION_FLAGS_ALLOW_DIRECT_TELEPORT = (1 << 20);
+const U64 REGION_FLAGS_ALLOW_DIRECT_TELEPORT = (1 << 20);
// Is there an administrative override on scripts in the region at the
// moment. This is the similar skip scripts, except this flag is
// presisted in the database on an estate level.
-const U32 REGION_FLAGS_ESTATE_SKIP_SCRIPTS = (1 << 21);
+const U64 REGION_FLAGS_ESTATE_SKIP_SCRIPTS = (1 << 21);
-const U32 REGION_FLAGS_RESTRICT_PUSHOBJECT = (1 << 22);
+const U64 REGION_FLAGS_RESTRICT_PUSHOBJECT = (1 << 22);
-const U32 REGION_FLAGS_DENY_ANONYMOUS = (1 << 23);
+const U64 REGION_FLAGS_DENY_ANONYMOUS = (1 << 23);
-const U32 REGION_FLAGS_ALLOW_PARCEL_CHANGES = (1 << 26);
+const U64 REGION_FLAGS_ALLOW_PARCEL_CHANGES = (1 << 26);
-const U32 REGION_FLAGS_ALLOW_VOICE = (1 << 28);
+const U64 REGION_FLAGS_ALLOW_VOICE = (1 << 28);
-const U32 REGION_FLAGS_BLOCK_PARCEL_SEARCH = (1 << 29);
-const U32 REGION_FLAGS_DENY_AGEUNVERIFIED = (1 << 30);
+const U64 REGION_FLAGS_BLOCK_PARCEL_SEARCH = (1 << 29);
+const U64 REGION_FLAGS_DENY_AGEUNVERIFIED = (1 << 30);
-const U32 REGION_FLAGS_DEFAULT = REGION_FLAGS_ALLOW_LANDMARK |
+const U64 REGION_FLAGS_DEFAULT = REGION_FLAGS_ALLOW_LANDMARK |
REGION_FLAGS_ALLOW_SET_HOME |
REGION_FLAGS_ALLOW_PARCEL_CHANGES |
REGION_FLAGS_ALLOW_VOICE;
-const U32 REGION_FLAGS_PRELUDE_SET = REGION_FLAGS_RESET_HOME_ON_TELEPORT;
-const U32 REGION_FLAGS_PRELUDE_UNSET = REGION_FLAGS_ALLOW_LANDMARK
+const U64 REGION_FLAGS_PRELUDE_SET = REGION_FLAGS_RESET_HOME_ON_TELEPORT;
+const U64 REGION_FLAGS_PRELUDE_UNSET = REGION_FLAGS_ALLOW_LANDMARK
| REGION_FLAGS_ALLOW_SET_HOME;
-const U32 REGION_FLAGS_ESTATE_MASK = REGION_FLAGS_EXTERNALLY_VISIBLE
+const U64 REGION_FLAGS_ESTATE_MASK = REGION_FLAGS_EXTERNALLY_VISIBLE
| REGION_FLAGS_SUN_FIXED
| REGION_FLAGS_DENY_ANONYMOUS
| REGION_FLAGS_DENY_AGEUNVERIFIED;
-inline BOOL is_prelude( U32 flags )
+inline BOOL is_prelude( U64 flags )
{
// definition of prelude does not depend on fixed-sun
return 0 == (flags & REGION_FLAGS_PRELUDE_UNSET)
&& 0 != (flags & REGION_FLAGS_PRELUDE_SET);
}
-inline U32 set_prelude_flags(U32 flags)
+inline U64 set_prelude_flags(U64 flags)
{
// also set the sun-fixed flag
return ((flags & ~REGION_FLAGS_PRELUDE_UNSET)
| (REGION_FLAGS_PRELUDE_SET | REGION_FLAGS_SUN_FIXED));
}
-inline U32 unset_prelude_flags(U32 flags)
+inline U64 unset_prelude_flags(U64 flags)
{
// also unset the fixed-sun flag
return ((flags | REGION_FLAGS_PRELUDE_UNSET)
& ~(REGION_FLAGS_PRELUDE_SET | REGION_FLAGS_SUN_FIXED));
}
+// Region protocols
+const U64 REGION_PROTOCOLS_AGENT_APPEARANCE_SERVICE = (1 << 0);
+
// estate constants. Need to match first few etries in indra.estate table.
const U32 ESTATE_ALL = 0; // will not match in db, reserved key for logic
const U32 ESTATE_MAINLAND = 1;
diff --git a/indra/llmessage/llregionhandle.h b/indra/llmessage/llregionhandle.h
index c77794e4b8..c77794e4b8 100644..100755
--- a/indra/llmessage/llregionhandle.h
+++ b/indra/llmessage/llregionhandle.h
diff --git a/indra/llmessage/llregionpresenceverifier.cpp b/indra/llmessage/llregionpresenceverifier.cpp
index 932cbf375e..932cbf375e 100644..100755
--- a/indra/llmessage/llregionpresenceverifier.cpp
+++ b/indra/llmessage/llregionpresenceverifier.cpp
diff --git a/indra/llmessage/llregionpresenceverifier.h b/indra/llmessage/llregionpresenceverifier.h
index 5e8251e519..5e8251e519 100644..100755
--- a/indra/llmessage/llregionpresenceverifier.h
+++ b/indra/llmessage/llregionpresenceverifier.h
diff --git a/indra/llmessage/llsdappservices.cpp b/indra/llmessage/llsdappservices.cpp
index 8bab91b0c0..8bab91b0c0 100644..100755
--- a/indra/llmessage/llsdappservices.cpp
+++ b/indra/llmessage/llsdappservices.cpp
diff --git a/indra/llmessage/llsdappservices.h b/indra/llmessage/llsdappservices.h
index e76e20cea9..e76e20cea9 100644..100755
--- a/indra/llmessage/llsdappservices.h
+++ b/indra/llmessage/llsdappservices.h
diff --git a/indra/llmessage/llsdhttpserver.cpp b/indra/llmessage/llsdhttpserver.cpp
index 5c8fc7b2bb..5c8fc7b2bb 100644..100755
--- a/indra/llmessage/llsdhttpserver.cpp
+++ b/indra/llmessage/llsdhttpserver.cpp
diff --git a/indra/llmessage/llsdhttpserver.h b/indra/llmessage/llsdhttpserver.h
index 39f9204604..39f9204604 100644..100755
--- a/indra/llmessage/llsdhttpserver.h
+++ b/indra/llmessage/llsdhttpserver.h
diff --git a/indra/llmessage/llsdmessage.cpp b/indra/llmessage/llsdmessage.cpp
index 1c93c12d99..1c93c12d99 100644..100755
--- a/indra/llmessage/llsdmessage.cpp
+++ b/indra/llmessage/llsdmessage.cpp
diff --git a/indra/llmessage/llsdmessage.h b/indra/llmessage/llsdmessage.h
index 0d34847ff2..0d34847ff2 100644..100755
--- a/indra/llmessage/llsdmessage.h
+++ b/indra/llmessage/llsdmessage.h
diff --git a/indra/llmessage/llsdmessagebuilder.cpp b/indra/llmessage/llsdmessagebuilder.cpp
index 615221e0ad..615221e0ad 100644..100755
--- a/indra/llmessage/llsdmessagebuilder.cpp
+++ b/indra/llmessage/llsdmessagebuilder.cpp
diff --git a/indra/llmessage/llsdmessagebuilder.h b/indra/llmessage/llsdmessagebuilder.h
index 9c7c1bfde3..9c7c1bfde3 100644..100755
--- a/indra/llmessage/llsdmessagebuilder.h
+++ b/indra/llmessage/llsdmessagebuilder.h
diff --git a/indra/llmessage/llsdmessagereader.cpp b/indra/llmessage/llsdmessagereader.cpp
index 3d8ca2ad9f..a6fccd2a56 100644..100755
--- a/indra/llmessage/llsdmessagereader.cpp
+++ b/indra/llmessage/llsdmessagereader.cpp
@@ -276,7 +276,7 @@ S32 getElementSize(const LLSD& llsd)
case LLSD::TypeReal:
return sizeof(F64);
case LLSD::TypeString:
- return llsd.asString().size();
+ return llsd.size();
case LLSD::TypeUUID:
return sizeof(LLUUID);
case LLSD::TypeDate:
diff --git a/indra/llmessage/llsdmessagereader.h b/indra/llmessage/llsdmessagereader.h
index 3b3d7fbfbe..3b3d7fbfbe 100644..100755
--- a/indra/llmessage/llsdmessagereader.h
+++ b/indra/llmessage/llsdmessagereader.h
diff --git a/indra/llmessage/llsdrpcclient.cpp b/indra/llmessage/llsdrpcclient.cpp
index 91fd070f07..fcda0e81a3 100644..100755
--- a/indra/llmessage/llsdrpcclient.cpp
+++ b/indra/llmessage/llsdrpcclient.cpp
@@ -31,7 +31,6 @@
#include "llbufferstream.h"
#include "llfiltersd2xmlrpc.h"
-#include "llmemtype.h"
#include "llpumpio.h"
#include "llsd.h"
#include "llsdserialize.h"
@@ -50,18 +49,15 @@ LLSDRPCResponse::LLSDRPCResponse() :
mIsError(false),
mIsFault(false)
{
- LLMemType m1(LLMemType::MTYPE_IO_SD_CLIENT);
}
// virtual
LLSDRPCResponse::~LLSDRPCResponse()
{
- LLMemType m1(LLMemType::MTYPE_IO_SD_CLIENT);
}
bool LLSDRPCResponse::extractResponse(const LLSD& sd)
{
- LLMemType m1(LLMemType::MTYPE_IO_SD_CLIENT);
bool rv = true;
if(sd.has(LLSDRPC_RESPONSE_NAME))
{
@@ -94,7 +90,6 @@ LLIOPipe::EStatus LLSDRPCResponse::process_impl(
{
LLFastTimer t(FTM_SDRPC_RESPONSE);
PUMP_DEBUG;
- LLMemType m1(LLMemType::MTYPE_IO_SD_CLIENT);
if(mIsError)
{
error(pump);
@@ -119,13 +114,11 @@ LLSDRPCClient::LLSDRPCClient() :
mState(STATE_NONE),
mQueue(EPBQ_PROCESS)
{
- LLMemType m1(LLMemType::MTYPE_IO_SD_CLIENT);
}
// virtual
LLSDRPCClient::~LLSDRPCClient()
{
- LLMemType m1(LLMemType::MTYPE_IO_SD_CLIENT);
}
bool LLSDRPCClient::call(
@@ -135,7 +128,6 @@ bool LLSDRPCClient::call(
LLSDRPCResponse* response,
EPassBackQueue queue)
{
- LLMemType m1(LLMemType::MTYPE_IO_SD_CLIENT);
//llinfos << "RPC: " << uri << "." << method << "(" << *parameter << ")"
// << llendl;
if(method.empty() || !response)
@@ -162,7 +154,6 @@ bool LLSDRPCClient::call(
LLSDRPCResponse* response,
EPassBackQueue queue)
{
- LLMemType m1(LLMemType::MTYPE_IO_SD_CLIENT);
//llinfos << "RPC: " << uri << "." << method << "(" << parameter << ")"
// << llendl;
if(method.empty() || parameter.empty() || !response)
@@ -193,7 +184,6 @@ LLIOPipe::EStatus LLSDRPCClient::process_impl(
{
LLFastTimer t(FTM_PROCESS_SDRPC_CLIENT);
PUMP_DEBUG;
- LLMemType m1(LLMemType::MTYPE_IO_SD_CLIENT);
if((STATE_NONE == mState) || (!pump))
{
// You should have called the call() method already.
diff --git a/indra/llmessage/llsdrpcclient.h b/indra/llmessage/llsdrpcclient.h
index 0cecf4f688..0cecf4f688 100644..100755
--- a/indra/llmessage/llsdrpcclient.h
+++ b/indra/llmessage/llsdrpcclient.h
diff --git a/indra/llmessage/llsdrpcserver.cpp b/indra/llmessage/llsdrpcserver.cpp
index 9f776aca72..f26ee52f71 100644..100755
--- a/indra/llmessage/llsdrpcserver.cpp
+++ b/indra/llmessage/llsdrpcserver.cpp
@@ -31,7 +31,6 @@
#include "llbuffer.h"
#include "llbufferstream.h"
-#include "llmemtype.h"
#include "llpumpio.h"
#include "llsdserialize.h"
#include "llstl.h"
@@ -58,12 +57,10 @@ LLSDRPCServer::LLSDRPCServer() :
mPump(NULL),
mLock(0)
{
- LLMemType m1(LLMemType::MTYPE_IO_SD_SERVER);
}
LLSDRPCServer::~LLSDRPCServer()
{
- LLMemType m1(LLMemType::MTYPE_IO_SD_SERVER);
std::for_each(
mMethods.begin(),
mMethods.end(),
@@ -109,7 +106,6 @@ LLIOPipe::EStatus LLSDRPCServer::process_impl(
{
LLFastTimer t(FTM_PROCESS_SDRPC_SERVER);
PUMP_DEBUG;
- LLMemType m1(LLMemType::MTYPE_IO_SD_SERVER);
// lldebugs << "LLSDRPCServer::process_impl" << llendl;
// Once we have all the data, We need to read the sd on
// the the in channel, and respond on the out channel
@@ -253,7 +249,6 @@ ESDRPCSStatus LLSDRPCServer::callMethod(
const LLChannelDescriptors& channels,
LLBufferArray* response)
{
- LLMemType m1(LLMemType::MTYPE_IO_SD_SERVER);
// Try to find the method in the method table.
ESDRPCSStatus rv = ESDRPCS_DONE;
method_map_t::iterator it = mMethods.find(method);
@@ -292,7 +287,6 @@ ESDRPCSStatus LLSDRPCServer::callbackMethod(
const LLChannelDescriptors& channels,
LLBufferArray* response)
{
- LLMemType m1(LLMemType::MTYPE_IO_SD_SERVER);
// Try to find the method in the callback method table.
ESDRPCSStatus rv = ESDRPCS_DONE;
method_map_t::iterator it = mCallbackMethods.find(method);
@@ -320,7 +314,6 @@ void LLSDRPCServer::buildFault(
S32 code,
const std::string& msg)
{
- LLMemType m1(LLMemType::MTYPE_IO_SD_SERVER);
LLBufferStream ostr(channels, data);
ostr << FAULT_PART_1 << code << FAULT_PART_2 << msg << FAULT_PART_3;
llinfos << "LLSDRPCServer::buildFault: " << code << ", " << msg << llendl;
@@ -332,7 +325,6 @@ void LLSDRPCServer::buildResponse(
LLBufferArray* data,
const LLSD& response)
{
- LLMemType m1(LLMemType::MTYPE_IO_SD_SERVER);
LLBufferStream ostr(channels, data);
ostr << RESPONSE_PART_1;
LLSDSerialize::toNotation(response, ostr);
diff --git a/indra/llmessage/llsdrpcserver.h b/indra/llmessage/llsdrpcserver.h
index 9e56e4ea46..9e56e4ea46 100644..100755
--- a/indra/llmessage/llsdrpcserver.h
+++ b/indra/llmessage/llsdrpcserver.h
diff --git a/indra/llmessage/llservice.cpp b/indra/llmessage/llservice.cpp
index dbec92c221..dbec92c221 100644..100755
--- a/indra/llmessage/llservice.cpp
+++ b/indra/llmessage/llservice.cpp
diff --git a/indra/llmessage/llservice.h b/indra/llmessage/llservice.h
index 9c09aeb44c..9c09aeb44c 100644..100755
--- a/indra/llmessage/llservice.h
+++ b/indra/llmessage/llservice.h
diff --git a/indra/llmessage/llservicebuilder.cpp b/indra/llmessage/llservicebuilder.cpp
index b9aef3d0ba..b9aef3d0ba 100644..100755
--- a/indra/llmessage/llservicebuilder.cpp
+++ b/indra/llmessage/llservicebuilder.cpp
diff --git a/indra/llmessage/llservicebuilder.h b/indra/llmessage/llservicebuilder.h
index 968995edf2..968995edf2 100644..100755
--- a/indra/llmessage/llservicebuilder.h
+++ b/indra/llmessage/llservicebuilder.h
diff --git a/indra/llmessage/llstoredmessage.cpp b/indra/llmessage/llstoredmessage.cpp
index 9f2f2bcda7..9f2f2bcda7 100644..100755
--- a/indra/llmessage/llstoredmessage.cpp
+++ b/indra/llmessage/llstoredmessage.cpp
diff --git a/indra/llmessage/llstoredmessage.h b/indra/llmessage/llstoredmessage.h
index 9c98e2c558..9c98e2c558 100644..100755
--- a/indra/llmessage/llstoredmessage.h
+++ b/indra/llmessage/llstoredmessage.h
diff --git a/indra/llmessage/lltaskname.h b/indra/llmessage/lltaskname.h
index 5dbd9c6223..5dbd9c6223 100644..100755
--- a/indra/llmessage/lltaskname.h
+++ b/indra/llmessage/lltaskname.h
diff --git a/indra/llmessage/llteleportflags.h b/indra/llmessage/llteleportflags.h
index b3fcad036e..b3fcad036e 100644..100755
--- a/indra/llmessage/llteleportflags.h
+++ b/indra/llmessage/llteleportflags.h
diff --git a/indra/llmessage/lltemplatemessagebuilder.cpp b/indra/llmessage/lltemplatemessagebuilder.cpp
index 9e8eb48460..9e8eb48460 100644..100755
--- a/indra/llmessage/lltemplatemessagebuilder.cpp
+++ b/indra/llmessage/lltemplatemessagebuilder.cpp
diff --git a/indra/llmessage/lltemplatemessagebuilder.h b/indra/llmessage/lltemplatemessagebuilder.h
index 4f614a4657..4f614a4657 100644..100755
--- a/indra/llmessage/lltemplatemessagebuilder.h
+++ b/indra/llmessage/lltemplatemessagebuilder.h
diff --git a/indra/llmessage/lltemplatemessagedispatcher.cpp b/indra/llmessage/lltemplatemessagedispatcher.cpp
index ee7a4e7e71..ee7a4e7e71 100644..100755
--- a/indra/llmessage/lltemplatemessagedispatcher.cpp
+++ b/indra/llmessage/lltemplatemessagedispatcher.cpp
diff --git a/indra/llmessage/lltemplatemessagedispatcher.h b/indra/llmessage/lltemplatemessagedispatcher.h
index fe77f92074..fe77f92074 100644..100755
--- a/indra/llmessage/lltemplatemessagedispatcher.h
+++ b/indra/llmessage/lltemplatemessagedispatcher.h
diff --git a/indra/llmessage/lltemplatemessagereader.cpp b/indra/llmessage/lltemplatemessagereader.cpp
index ab91f74abe..ab91f74abe 100644..100755
--- a/indra/llmessage/lltemplatemessagereader.cpp
+++ b/indra/llmessage/lltemplatemessagereader.cpp
diff --git a/indra/llmessage/lltemplatemessagereader.h b/indra/llmessage/lltemplatemessagereader.h
index fcf8f92fa6..fcf8f92fa6 100644..100755
--- a/indra/llmessage/lltemplatemessagereader.h
+++ b/indra/llmessage/lltemplatemessagereader.h
diff --git a/indra/llmessage/llthrottle.cpp b/indra/llmessage/llthrottle.cpp
index 64ebd51fec..64ebd51fec 100644..100755
--- a/indra/llmessage/llthrottle.cpp
+++ b/indra/llmessage/llthrottle.cpp
diff --git a/indra/llmessage/llthrottle.h b/indra/llmessage/llthrottle.h
index ed0aeb4602..ed0aeb4602 100644..100755
--- a/indra/llmessage/llthrottle.h
+++ b/indra/llmessage/llthrottle.h
diff --git a/indra/llmessage/lltransfermanager.cpp b/indra/llmessage/lltransfermanager.cpp
index 034680caf8..38b743fb75 100644..100755
--- a/indra/llmessage/lltransfermanager.cpp
+++ b/indra/llmessage/lltransfermanager.cpp
@@ -606,16 +606,21 @@ void LLTransferManager::processTransferAbort(LLMessageSystem *msgp, void **)
void LLTransferManager::reliablePacketCallback(void **user_data, S32 result)
{
LLUUID *transfer_idp = (LLUUID *)user_data;
- if (result)
+ if (result &&
+ transfer_idp != NULL)
{
- llwarns << "Aborting reliable transfer " << *transfer_idp << " due to failed reliable resends!" << llendl;
LLTransferSource *tsp = gTransferManager.findTransferSource(*transfer_idp);
if (tsp)
{
+ llwarns << "Aborting reliable transfer " << *transfer_idp << " due to failed reliable resends!" << llendl;
LLTransferSourceChannel *tscp = tsp->mChannelp;
tsp->abortTransfer();
tscp->deleteTransfer(tsp);
}
+ else
+ {
+ llwarns << "Aborting reliable transfer " << *transfer_idp << " but can't find the LLTransferSource object" << llendl;
+ }
}
delete transfer_idp;
}
@@ -892,22 +897,26 @@ LLTransferSource *LLTransferSourceChannel::findTransferSource(const LLUUID &tran
}
-BOOL LLTransferSourceChannel::deleteTransfer(LLTransferSource *tsp)
+void LLTransferSourceChannel::deleteTransfer(LLTransferSource *tsp)
{
-
- LLPriQueueMap<LLTransferSource *>::pqm_iter iter;
- for (iter = mTransferSources.mMap.begin(); iter != mTransferSources.mMap.end(); iter++)
+ if (tsp)
{
- if (iter->second == tsp)
+ LLPriQueueMap<LLTransferSource *>::pqm_iter iter;
+ for (iter = mTransferSources.mMap.begin(); iter != mTransferSources.mMap.end(); iter++)
{
- delete tsp;
- mTransferSources.mMap.erase(iter);
- return TRUE;
+ if (iter->second == tsp)
+ {
+ delete tsp;
+ mTransferSources.mMap.erase(iter);
+ return;
+ }
}
- }
- llerrs << "Unable to find transfer source to delete!" << llendl;
- return FALSE;
+ llwarns << "Unable to find transfer source id "
+ << tsp->getID()
+ << " to delete!"
+ << llendl;
+ }
}
@@ -1008,21 +1017,26 @@ LLTransferTarget *LLTransferTargetChannel::findTransferTarget(const LLUUID &tran
}
-BOOL LLTransferTargetChannel::deleteTransfer(LLTransferTarget *ttp)
+void LLTransferTargetChannel::deleteTransfer(LLTransferTarget *ttp)
{
- tt_iter iter;
- for (iter = mTransferTargets.begin(); iter != mTransferTargets.end(); iter++)
+ if (ttp)
{
- if (*iter == ttp)
+ tt_iter iter;
+ for (iter = mTransferTargets.begin(); iter != mTransferTargets.end(); iter++)
{
- delete ttp;
- mTransferTargets.erase(iter);
- return TRUE;
+ if (*iter == ttp)
+ {
+ delete ttp;
+ mTransferTargets.erase(iter);
+ return;
+ }
}
- }
- llerrs << "Unable to find transfer target to delete!" << llendl;
- return FALSE;
+ llwarns << "Unable to find transfer target id "
+ << ttp->getID()
+ << " to delete!"
+ << llendl;
+ }
}
diff --git a/indra/llmessage/lltransfermanager.h b/indra/llmessage/lltransfermanager.h
index 252e05d1d1..6aad153c24 100644..100755
--- a/indra/llmessage/lltransfermanager.h
+++ b/indra/llmessage/lltransfermanager.h
@@ -199,7 +199,7 @@ public:
void addTransferSource(LLTransferSource *sourcep);
LLTransferSource *findTransferSource(const LLUUID &transfer_id);
- BOOL deleteTransfer(LLTransferSource *tsp);
+ void deleteTransfer(LLTransferSource *tsp);
void setThrottleID(const S32 throttle_id) { mThrottleID = throttle_id; }
@@ -232,7 +232,7 @@ public:
const F32 priority);
LLTransferTarget *findTransferTarget(const LLUUID &transfer_id);
- BOOL deleteTransfer(LLTransferTarget *ttp);
+ void deleteTransfer(LLTransferTarget *ttp);
LLTransferChannelType getChannelType() const { return mChannelType; }
diff --git a/indra/llmessage/lltransfersourceasset.cpp b/indra/llmessage/lltransfersourceasset.cpp
index 8537773a3f..8537773a3f 100644..100755
--- a/indra/llmessage/lltransfersourceasset.cpp
+++ b/indra/llmessage/lltransfersourceasset.cpp
diff --git a/indra/llmessage/lltransfersourceasset.h b/indra/llmessage/lltransfersourceasset.h
index 3abda83cf8..3abda83cf8 100644..100755
--- a/indra/llmessage/lltransfersourceasset.h
+++ b/indra/llmessage/lltransfersourceasset.h
diff --git a/indra/llmessage/lltransfersourcefile.cpp b/indra/llmessage/lltransfersourcefile.cpp
index 43c9448fba..43c9448fba 100644..100755
--- a/indra/llmessage/lltransfersourcefile.cpp
+++ b/indra/llmessage/lltransfersourcefile.cpp
diff --git a/indra/llmessage/lltransfersourcefile.h b/indra/llmessage/lltransfersourcefile.h
index 985042417e..985042417e 100644..100755
--- a/indra/llmessage/lltransfersourcefile.h
+++ b/indra/llmessage/lltransfersourcefile.h
diff --git a/indra/llmessage/lltransfertargetfile.cpp b/indra/llmessage/lltransfertargetfile.cpp
index 560fc8b6e4..560fc8b6e4 100644..100755
--- a/indra/llmessage/lltransfertargetfile.cpp
+++ b/indra/llmessage/lltransfertargetfile.cpp
diff --git a/indra/llmessage/lltransfertargetfile.h b/indra/llmessage/lltransfertargetfile.h
index 6d03ff2d2e..6d03ff2d2e 100644..100755
--- a/indra/llmessage/lltransfertargetfile.h
+++ b/indra/llmessage/lltransfertargetfile.h
diff --git a/indra/llmessage/lltransfertargetvfile.cpp b/indra/llmessage/lltransfertargetvfile.cpp
index c78d9288b6..c78d9288b6 100644..100755
--- a/indra/llmessage/lltransfertargetvfile.cpp
+++ b/indra/llmessage/lltransfertargetvfile.cpp
diff --git a/indra/llmessage/lltransfertargetvfile.h b/indra/llmessage/lltransfertargetvfile.h
index 23a65e4bb2..23a65e4bb2 100644..100755
--- a/indra/llmessage/lltransfertargetvfile.h
+++ b/indra/llmessage/lltransfertargetvfile.h
diff --git a/indra/llmessage/lltrustedmessageservice.cpp b/indra/llmessage/lltrustedmessageservice.cpp
index fea7fc72c4..fea7fc72c4 100644..100755
--- a/indra/llmessage/lltrustedmessageservice.cpp
+++ b/indra/llmessage/lltrustedmessageservice.cpp
diff --git a/indra/llmessage/lltrustedmessageservice.h b/indra/llmessage/lltrustedmessageservice.h
index 688937ac2c..688937ac2c 100644..100755
--- a/indra/llmessage/lltrustedmessageservice.h
+++ b/indra/llmessage/lltrustedmessageservice.h
diff --git a/indra/llmessage/llurlrequest.cpp b/indra/llmessage/llurlrequest.cpp
index a16f5c7bf0..683065357d 100644..100755
--- a/indra/llmessage/llurlrequest.cpp
+++ b/indra/llmessage/llurlrequest.cpp
@@ -34,7 +34,6 @@
#include <openssl/ssl.h>
#include "llcurl.h"
#include "llioutil.h"
-#include "llmemtype.h"
#include "llproxy.h"
#include "llpumpio.h"
#include "llsd.h"
@@ -81,7 +80,6 @@ LLURLRequestDetail::LLURLRequestDetail() :
mIsBodyLimitSet(false),
mSSLVerifyCallback(NULL)
{
- LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST);
mCurlRequest = new LLCurlEasyRequest();
if(!mCurlRequest->isValid()) //failed.
@@ -93,7 +91,6 @@ LLURLRequestDetail::LLURLRequestDetail() :
LLURLRequestDetail::~LLURLRequestDetail()
{
- LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST);
delete mCurlRequest;
mLastRead = NULL;
}
@@ -153,34 +150,37 @@ std::string LLURLRequest::actionAsVerb(LLURLRequest::ERequestAction action)
return VERBS[action];
}
-LLURLRequest::LLURLRequest(LLURLRequest::ERequestAction action) :
- mAction(action)
+LLURLRequest::LLURLRequest(LLURLRequest::ERequestAction action, bool follow_redirects /* = true */) :
+ mAction(action),
+ mFollowRedirects(follow_redirects)
{
- LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST);
initialize();
}
LLURLRequest::LLURLRequest(
LLURLRequest::ERequestAction action,
- const std::string& url) :
- mAction(action)
+ const std::string& url,
+ bool follow_redirects /* = true */) :
+ mAction(action),
+ mFollowRedirects(follow_redirects)
{
- LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST);
initialize();
setURL(url);
}
LLURLRequest::~LLURLRequest()
{
- LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST);
delete mDetail;
mDetail = NULL ;
}
void LLURLRequest::setURL(const std::string& url)
{
- LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST);
mDetail->mURL = url;
+ if (url.empty())
+ {
+ llwarns << "empty URL specified" << llendl;
+ }
}
std::string LLURLRequest::getURL() const
@@ -190,7 +190,6 @@ std::string LLURLRequest::getURL() const
void LLURLRequest::addHeader(const char* header)
{
- LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST);
mDetail->mCurlRequest->slist_append(header);
}
@@ -202,7 +201,6 @@ void LLURLRequest::setBodyLimit(U32 size)
void LLURLRequest::setCallback(LLURLRequestComplete* callback)
{
- LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST);
mCompletionCallback = callback;
mDetail->mCurlRequest->setHeaderCallback(&headerCallback, (void*)callback);
}
@@ -267,8 +265,6 @@ LLIOPipe::EStatus LLURLRequest::handleError(
LLIOPipe::EStatus status,
LLPumpIO* pump)
{
- LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST);
-
if(!isValid())
{
return STATUS_EXPIRED ;
@@ -289,6 +285,8 @@ LLIOPipe::EStatus LLURLRequest::handleError(
}
static LLFastTimer::DeclareTimer FTM_PROCESS_URL_REQUEST("URL Request");
+static LLFastTimer::DeclareTimer FTM_PROCESS_URL_REQUEST_GET_RESULT("Get Result");
+static LLFastTimer::DeclareTimer FTM_URL_PERFORM("Perform");
// virtual
LLIOPipe::EStatus LLURLRequest::process_impl(
@@ -300,7 +298,6 @@ LLIOPipe::EStatus LLURLRequest::process_impl(
{
LLFastTimer t(FTM_PROCESS_URL_REQUEST);
PUMP_DEBUG;
- LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST);
//llinfos << "LLURLRequest::process_impl()" << llendl;
if (!buffer) return STATUS_ERROR;
@@ -320,11 +317,11 @@ LLIOPipe::EStatus LLURLRequest::process_impl(
const F32 TIMEOUT_ADJUSTMENT = 2.0f;
mDetail->mByteAccumulator = 0;
pump->adjustTimeoutSeconds(TIMEOUT_ADJUSTMENT);
- lldebugs << "LLURLRequest adjustTimeoutSeconds for request: " << mDetail->mURL << llendl;
- if (mState == STATE_INITIALIZED)
- {
- llinfos << "LLURLRequest adjustTimeoutSeconds called during upload" << llendl;
- }
+ lldebugs << "LLURLRequest adjustTimeoutSeconds for request: " << mDetail->mURL << llendl;
+ if (mState == STATE_INITIALIZED)
+ {
+ llinfos << "LLURLRequest adjustTimeoutSeconds called during upload" << llendl;
+ }
}
switch(mState)
@@ -358,7 +355,6 @@ LLIOPipe::EStatus LLURLRequest::process_impl(
{
PUMP_DEBUG;
LLIOPipe::EStatus status = STATUS_BREAK;
- static LLFastTimer::DeclareTimer FTM_URL_PERFORM("Perform");
{
LLFastTimer t(FTM_URL_PERFORM);
if(!mDetail->mCurlRequest->wait())
@@ -367,12 +363,11 @@ LLIOPipe::EStatus LLURLRequest::process_impl(
}
}
- while(1)
+ bool keep_looping = true;
+ while(keep_looping)
{
CURLcode result;
- static LLFastTimer::DeclareTimer FTM_PROCESS_URL_REQUEST_GET_RESULT("Get Result");
-
bool newmsg = false;
{
LLFastTimer t(FTM_PROCESS_URL_REQUEST_GET_RESULT);
@@ -421,8 +416,9 @@ LLIOPipe::EStatus LLURLRequest::process_impl(
case CURLE_FAILED_INIT:
case CURLE_COULDNT_CONNECT:
status = STATUS_NO_CONNECTION;
+ keep_looping = false;
break;
- default:
+ default: // CURLE_URL_MALFORMAT
llwarns << "URLRequest Error: " << result
<< ", "
<< LLCurl::strerror(result)
@@ -430,6 +426,7 @@ LLIOPipe::EStatus LLURLRequest::process_impl(
<< (mDetail->mURL.empty() ? "<EMPTY URL>" : mDetail->mURL)
<< llendl;
status = STATUS_ERROR;
+ keep_looping = false;
break;
}
}
@@ -456,7 +453,6 @@ LLIOPipe::EStatus LLURLRequest::process_impl(
void LLURLRequest::initialize()
{
- LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST);
mState = STATE_INITIALIZED;
mDetail = new LLURLRequestDetail;
@@ -477,7 +473,6 @@ bool LLURLRequest::configure()
{
LLFastTimer t(FTM_URL_REQUEST_CONFIGURE);
- LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST);
bool rv = false;
S32 bytes = mDetail->mResponseBuffer->countAfter(
mDetail->mChannels.in(),
@@ -487,12 +482,18 @@ bool LLURLRequest::configure()
case HTTP_HEAD:
mDetail->mCurlRequest->setopt(CURLOPT_HEADER, 1);
mDetail->mCurlRequest->setopt(CURLOPT_NOBODY, 1);
- mDetail->mCurlRequest->setopt(CURLOPT_FOLLOWLOCATION, 1);
+ if (mFollowRedirects)
+ {
+ mDetail->mCurlRequest->setopt(CURLOPT_FOLLOWLOCATION, 1);
+ }
rv = true;
break;
case HTTP_GET:
mDetail->mCurlRequest->setopt(CURLOPT_HTTPGET, 1);
- mDetail->mCurlRequest->setopt(CURLOPT_FOLLOWLOCATION, 1);
+ if (mFollowRedirects)
+ {
+ mDetail->mCurlRequest->setopt(CURLOPT_FOLLOWLOCATION, 1);
+ }
// Set Accept-Encoding to allow response compression
mDetail->mCurlRequest->setoptString(CURLOPT_ENCODING, "");
@@ -557,7 +558,6 @@ size_t LLURLRequest::downCallback(
size_t nmemb,
void* user)
{
- LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST);
LLURLRequest* req = (LLURLRequest*)user;
if(STATE_WAITING_FOR_RESPONSE == req->mState)
{
@@ -593,7 +593,6 @@ size_t LLURLRequest::upCallback(
size_t nmemb,
void* user)
{
- LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST);
LLURLRequest* req = (LLURLRequest*)user;
S32 bytes = llmin(
(S32)(size * nmemb),
@@ -691,7 +690,6 @@ LLIOPipe::EStatus LLContextURLExtractor::process_impl(
{
LLFastTimer t(FTM_PROCESS_URL_EXTRACTOR);
PUMP_DEBUG;
- LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST);
// The destination host is in the context.
if(context.isUndefined() || !mRequest)
{
@@ -719,13 +717,11 @@ LLIOPipe::EStatus LLContextURLExtractor::process_impl(
LLURLRequestComplete::LLURLRequestComplete() :
mRequestStatus(LLIOPipe::STATUS_ERROR)
{
- LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST);
}
// virtual
LLURLRequestComplete::~LLURLRequestComplete()
{
- LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST);
}
//virtual
@@ -764,7 +760,6 @@ void LLURLRequestComplete::noResponse()
void LLURLRequestComplete::responseStatus(LLIOPipe::EStatus status)
{
- LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST);
mRequestStatus = status;
}
diff --git a/indra/llmessage/llurlrequest.h b/indra/llmessage/llurlrequest.h
index 44d358d906..20d6e30d17 100644..100755
--- a/indra/llmessage/llurlrequest.h
+++ b/indra/llmessage/llurlrequest.h
@@ -95,7 +95,7 @@ public:
*
* @param action One of the ERequestAction enumerations.
*/
- LLURLRequest(ERequestAction action);
+ LLURLRequest(ERequestAction action, bool follow_redirects = true);
/**
* @brief Constructor.
@@ -103,7 +103,7 @@ public:
* @param action One of the ERequestAction enumerations.
* @param url The url of the request. It should already be encoded.
*/
- LLURLRequest(ERequestAction action, const std::string& url);
+ LLURLRequest(ERequestAction action, const std::string& url, bool follow_redirects = true);
/**
* @brief Destructor.
@@ -219,10 +219,11 @@ protected:
};
EState mState;
ERequestAction mAction;
+ bool mFollowRedirects;
LLURLRequestDetail* mDetail;
LLIOPipe::ptr_t mCompletionCallback;
- S32 mRequestTransferedBytes;
- S32 mResponseTransferedBytes;
+ S32 mRequestTransferedBytes;
+ S32 mResponseTransferedBytes;
static CURLcode _sslCtxCallback(CURL * curl, void *sslctx, void *param);
diff --git a/indra/llmessage/lluseroperation.cpp b/indra/llmessage/lluseroperation.cpp
index a4a68d0c81..a4a68d0c81 100644..100755
--- a/indra/llmessage/lluseroperation.cpp
+++ b/indra/llmessage/lluseroperation.cpp
diff --git a/indra/llmessage/lluseroperation.h b/indra/llmessage/lluseroperation.h
index 7db5f0b27f..7db5f0b27f 100644..100755
--- a/indra/llmessage/lluseroperation.h
+++ b/indra/llmessage/lluseroperation.h
diff --git a/indra/llmessage/llvehicleparams.h b/indra/llmessage/llvehicleparams.h
index f34df7744e..f34df7744e 100644..100755
--- a/indra/llmessage/llvehicleparams.h
+++ b/indra/llmessage/llvehicleparams.h
diff --git a/indra/llmessage/llxfer.cpp b/indra/llmessage/llxfer.cpp
index f8c55d52ad..f8c55d52ad 100644..100755
--- a/indra/llmessage/llxfer.cpp
+++ b/indra/llmessage/llxfer.cpp
diff --git a/indra/llmessage/llxfer.h b/indra/llmessage/llxfer.h
index f9348eb11f..f9348eb11f 100644..100755
--- a/indra/llmessage/llxfer.h
+++ b/indra/llmessage/llxfer.h
diff --git a/indra/llmessage/llxfer_file.cpp b/indra/llmessage/llxfer_file.cpp
index 9e02af2c3e..9e02af2c3e 100644..100755
--- a/indra/llmessage/llxfer_file.cpp
+++ b/indra/llmessage/llxfer_file.cpp
diff --git a/indra/llmessage/llxfer_file.h b/indra/llmessage/llxfer_file.h
index a37dda6732..a37dda6732 100644..100755
--- a/indra/llmessage/llxfer_file.h
+++ b/indra/llmessage/llxfer_file.h
diff --git a/indra/llmessage/llxfer_mem.cpp b/indra/llmessage/llxfer_mem.cpp
index 4c7e83c33d..4c7e83c33d 100644..100755
--- a/indra/llmessage/llxfer_mem.cpp
+++ b/indra/llmessage/llxfer_mem.cpp
diff --git a/indra/llmessage/llxfer_mem.h b/indra/llmessage/llxfer_mem.h
index b5adf837df..b5adf837df 100644..100755
--- a/indra/llmessage/llxfer_mem.h
+++ b/indra/llmessage/llxfer_mem.h
diff --git a/indra/llmessage/llxfer_vfile.cpp b/indra/llmessage/llxfer_vfile.cpp
index 751a69518c..751a69518c 100644..100755
--- a/indra/llmessage/llxfer_vfile.cpp
+++ b/indra/llmessage/llxfer_vfile.cpp
diff --git a/indra/llmessage/llxfer_vfile.h b/indra/llmessage/llxfer_vfile.h
index 048bf49dcc..048bf49dcc 100644..100755
--- a/indra/llmessage/llxfer_vfile.h
+++ b/indra/llmessage/llxfer_vfile.h
diff --git a/indra/llmessage/llxfermanager.cpp b/indra/llmessage/llxfermanager.cpp
index b9cddc8e45..00b9d81611 100644..100755
--- a/indra/llmessage/llxfermanager.cpp
+++ b/indra/llmessage/llxfermanager.cpp
@@ -886,8 +886,17 @@ void LLXferManager::processFileRequest (LLMessageSystem *mesgsys, void ** /*user
return;
}
-
- std::string expanded_filename = gDirUtilp->getExpandedFilename( local_path, local_filename );
+ // If we want to use a special path (e.g. LL_PATH_CACHE), we want to make sure we create the
+ // proper expanded filename.
+ std::string expanded_filename;
+ if (local_path != LL_PATH_NONE)
+ {
+ expanded_filename = gDirUtilp->getExpandedFilename( local_path, local_filename );
+ }
+ else
+ {
+ expanded_filename = local_filename;
+ }
llinfos << "starting file transfer: " << expanded_filename << " to " << mesgsys->getSender() << llendl;
BOOL delete_local_on_completion = FALSE;
diff --git a/indra/llmessage/llxfermanager.h b/indra/llmessage/llxfermanager.h
index b84bccb5b7..b84bccb5b7 100644..100755
--- a/indra/llmessage/llxfermanager.h
+++ b/indra/llmessage/llxfermanager.h
diff --git a/indra/llmessage/llxorcipher.cpp b/indra/llmessage/llxorcipher.cpp
index 9053e1b2f1..9053e1b2f1 100644..100755
--- a/indra/llmessage/llxorcipher.cpp
+++ b/indra/llmessage/llxorcipher.cpp
diff --git a/indra/llmessage/llxorcipher.h b/indra/llmessage/llxorcipher.h
index c5b0700f0d..c5b0700f0d 100644..100755
--- a/indra/llmessage/llxorcipher.h
+++ b/indra/llmessage/llxorcipher.h
diff --git a/indra/llmessage/machine.cpp b/indra/llmessage/machine.cpp
index 8d2f512037..8d2f512037 100644..100755
--- a/indra/llmessage/machine.cpp
+++ b/indra/llmessage/machine.cpp
diff --git a/indra/llmessage/machine.h b/indra/llmessage/machine.h
index 07aadd47d2..07aadd47d2 100644..100755
--- a/indra/llmessage/machine.h
+++ b/indra/llmessage/machine.h
diff --git a/indra/llmessage/mean_collision_data.h b/indra/llmessage/mean_collision_data.h
index 29de091603..29de091603 100644..100755
--- a/indra/llmessage/mean_collision_data.h
+++ b/indra/llmessage/mean_collision_data.h
diff --git a/indra/llmessage/message.cpp b/indra/llmessage/message.cpp
index 6a425cfe98..ae95087377 100644..100755
--- a/indra/llmessage/message.cpp
+++ b/indra/llmessage/message.cpp
@@ -80,7 +80,6 @@
#include "v3math.h"
#include "v4math.h"
#include "lltransfertargetvfile.h"
-#include "llmemtype.h"
// Constants
//const char* MESSAGE_LOG_FILENAME = "message.log";
@@ -793,7 +792,6 @@ S32 LLMessageSystem::getReceiveBytes() const
void LLMessageSystem::processAcks()
{
- LLMemType mt_pa(LLMemType::MTYPE_MESSAGE_PROCESS_ACKS);
F64 mt_sec = getMessageTimeSeconds();
{
gTransferManager.updateTransfers();
@@ -4020,7 +4018,6 @@ void LLMessageSystem::setTimeDecodesSpamThreshold( F32 seconds )
// TODO: babbage: move gServicePump in to LLMessageSystem?
bool LLMessageSystem::checkAllMessages(S64 frame_count, LLPumpIO* http_pump)
{
- LLMemType mt_cam(LLMemType::MTYPE_MESSAGE_CHECK_ALL);
if(checkMessages(frame_count))
{
return true;
diff --git a/indra/llmessage/message.h b/indra/llmessage/message.h
index 1589ea29c1..1589ea29c1 100644..100755
--- a/indra/llmessage/message.h
+++ b/indra/llmessage/message.h
diff --git a/indra/llmessage/message_prehash.cpp b/indra/llmessage/message_prehash.cpp
index e71fb96540..39cfb6019e 100644..100755
--- a/indra/llmessage/message_prehash.cpp
+++ b/indra/llmessage/message_prehash.cpp
@@ -279,6 +279,8 @@ char const* const _PREHASH_GrabOffset = LLMessageStringTable::getInstance()->get
char const* const _PREHASH_SimPort = LLMessageStringTable::getInstance()->getString("SimPort");
char const* const _PREHASH_PricePerMeter = LLMessageStringTable::getInstance()->getString("PricePerMeter");
char const* const _PREHASH_RegionFlags = LLMessageStringTable::getInstance()->getString("RegionFlags");
+char const* const _PREHASH_RegionFlagsExtended = LLMessageStringTable::getInstance()->getString("RegionFlagsExtended");
+char const* const _PREHASH_RegionProtocols = LLMessageStringTable::getInstance()->getString("RegionProtocols");
char const* const _PREHASH_VoteResult = LLMessageStringTable::getInstance()->getString("VoteResult");
char const* const _PREHASH_ParcelDirFeeEstimate = LLMessageStringTable::getInstance()->getString("ParcelDirFeeEstimate");
char const* const _PREHASH_ModifyBlock = LLMessageStringTable::getInstance()->getString("ModifyBlock");
@@ -305,6 +307,8 @@ char const* const _PREHASH_ViewerStartAuction = LLMessageStringTable::getInstanc
char const* const _PREHASH_StartAuction = LLMessageStringTable::getInstance()->getString("StartAuction");
char const* const _PREHASH_DuplicateFlags = LLMessageStringTable::getInstance()->getString("DuplicateFlags");
char const* const _PREHASH_RegionInfo2 = LLMessageStringTable::getInstance()->getString("RegionInfo2");
+char const* const _PREHASH_RegionInfo3 = LLMessageStringTable::getInstance()->getString("RegionInfo3");
+char const* const _PREHASH_RegionInfo4 = LLMessageStringTable::getInstance()->getString("RegionInfo4");
char const* const _PREHASH_TextColor = LLMessageStringTable::getInstance()->getString("TextColor");
char const* const _PREHASH_SlaveID = LLMessageStringTable::getInstance()->getString("SlaveID");
char const* const _PREHASH_Charter = LLMessageStringTable::getInstance()->getString("Charter");
@@ -943,7 +947,6 @@ char const* const _PREHASH_SysGPU = LLMessageStringTable::getInstance()->getStri
char const* const _PREHASH_AvatarInterestsReply = LLMessageStringTable::getInstance()->getString("AvatarInterestsReply");
char const* const _PREHASH_StartLure = LLMessageStringTable::getInstance()->getString("StartLure");
char const* const _PREHASH_SysRAM = LLMessageStringTable::getInstance()->getString("SysRAM");
-char const* const _PREHASH_ObjectPosition = LLMessageStringTable::getInstance()->getString("ObjectPosition");
char const* const _PREHASH_SitPosition = LLMessageStringTable::getInstance()->getString("SitPosition");
char const* const _PREHASH_StartTime = LLMessageStringTable::getInstance()->getString("StartTime");
char const* const _PREHASH_BornOn = LLMessageStringTable::getInstance()->getString("BornOn");
@@ -999,7 +1002,6 @@ char const* const _PREHASH_SnapshotID = LLMessageStringTable::getInstance()->get
char const* const _PREHASH_Aspect = LLMessageStringTable::getInstance()->getString("Aspect");
char const* const _PREHASH_ParamSize = LLMessageStringTable::getInstance()->getString("ParamSize");
char const* const _PREHASH_VoteCast = LLMessageStringTable::getInstance()->getString("VoteCast");
-char const* const _PREHASH_CastsShadows = LLMessageStringTable::getInstance()->getString("CastsShadows");
char const* const _PREHASH_EveryoneMask = LLMessageStringTable::getInstance()->getString("EveryoneMask");
char const* const _PREHASH_ObjectSpinUpdate = LLMessageStringTable::getInstance()->getString("ObjectSpinUpdate");
char const* const _PREHASH_MaturePublish = LLMessageStringTable::getInstance()->getString("MaturePublish");
@@ -1048,7 +1050,6 @@ char const* const _PREHASH_SimIP = LLMessageStringTable::getInstance()->getStrin
char const* const _PREHASH_GodID = LLMessageStringTable::getInstance()->getString("GodID");
char const* const _PREHASH_TeleportMinPrice = LLMessageStringTable::getInstance()->getString("TeleportMinPrice");
char const* const _PREHASH_VoteItem = LLMessageStringTable::getInstance()->getString("VoteItem");
-char const* const _PREHASH_ObjectRotation = LLMessageStringTable::getInstance()->getString("ObjectRotation");
char const* const _PREHASH_SitRotation = LLMessageStringTable::getInstance()->getString("SitRotation");
char const* const _PREHASH_SnapSelection = LLMessageStringTable::getInstance()->getString("SnapSelection");
char const* const _PREHASH_SoundTrigger = LLMessageStringTable::getInstance()->getString("SoundTrigger");
@@ -1379,3 +1380,6 @@ char const* const _PREHASH_ProductSKU = LLMessageStringTable::getInstance()->get
char const* const _PREHASH_SeeAVs = LLMessageStringTable::getInstance()->getString("SeeAVs");
char const* const _PREHASH_AnyAVSounds = LLMessageStringTable::getInstance()->getString("AnyAVSounds");
char const* const _PREHASH_GroupAVSounds = LLMessageStringTable::getInstance()->getString("GroupAVSounds");
+char const* const _PREHASH_AppearanceData = LLMessageStringTable::getInstance()->getString("AppearanceData");
+char const* const _PREHASH_AppearanceVersion = LLMessageStringTable::getInstance()->getString("AppearanceVersion");
+char const* const _PREHASH_CofVersion = LLMessageStringTable::getInstance()->getString("CofVersion");
diff --git a/indra/llmessage/message_prehash.h b/indra/llmessage/message_prehash.h
index dd2c2dbd64..573e10dc0b 100644..100755
--- a/indra/llmessage/message_prehash.h
+++ b/indra/llmessage/message_prehash.h
@@ -279,6 +279,8 @@ extern char const* const _PREHASH_GrabOffset;
extern char const* const _PREHASH_SimPort;
extern char const* const _PREHASH_PricePerMeter;
extern char const* const _PREHASH_RegionFlags;
+extern char const* const _PREHASH_RegionFlagsExtended;
+extern char const* const _PREHASH_RegionProtocols;
extern char const* const _PREHASH_VoteResult;
extern char const* const _PREHASH_ParcelDirFeeEstimate;
extern char const* const _PREHASH_ModifyBlock;
@@ -305,6 +307,8 @@ extern char const* const _PREHASH_ViewerStartAuction;
extern char const* const _PREHASH_StartAuction;
extern char const* const _PREHASH_DuplicateFlags;
extern char const* const _PREHASH_RegionInfo2;
+extern char const* const _PREHASH_RegionInfo3;
+extern char const* const _PREHASH_RegionInfo4;
extern char const* const _PREHASH_TextColor;
extern char const* const _PREHASH_SlaveID;
extern char const* const _PREHASH_Charter;
@@ -943,7 +947,6 @@ extern char const* const _PREHASH_SysGPU;
extern char const* const _PREHASH_AvatarInterestsReply;
extern char const* const _PREHASH_StartLure;
extern char const* const _PREHASH_SysRAM;
-extern char const* const _PREHASH_ObjectPosition;
extern char const* const _PREHASH_SitPosition;
extern char const* const _PREHASH_StartTime;
extern char const* const _PREHASH_BornOn;
@@ -999,7 +1002,6 @@ extern char const* const _PREHASH_SnapshotID;
extern char const* const _PREHASH_Aspect;
extern char const* const _PREHASH_ParamSize;
extern char const* const _PREHASH_VoteCast;
-extern char const* const _PREHASH_CastsShadows;
extern char const* const _PREHASH_EveryoneMask;
extern char const* const _PREHASH_ObjectSpinUpdate;
extern char const* const _PREHASH_MaturePublish;
@@ -1048,7 +1050,6 @@ extern char const* const _PREHASH_SimIP;
extern char const* const _PREHASH_GodID;
extern char const* const _PREHASH_TeleportMinPrice;
extern char const* const _PREHASH_VoteItem;
-extern char const* const _PREHASH_ObjectRotation;
extern char const* const _PREHASH_SitRotation;
extern char const* const _PREHASH_SnapSelection;
extern char const* const _PREHASH_SoundTrigger;
@@ -1379,4 +1380,7 @@ extern char const* const _PREHASH_ProductSKU;
extern char const* const _PREHASH_SeeAVs;
extern char const* const _PREHASH_AnyAVSounds;
extern char const* const _PREHASH_GroupAVSounds;
+extern char const* const _PREHASH_AppearanceData;
+extern char const* const _PREHASH_AppearanceVersion;
+extern char const* const _PREHASH_CofVersion;
#endif
diff --git a/indra/llmessage/message_string_table.cpp b/indra/llmessage/message_string_table.cpp
index dd063fcb83..dd063fcb83 100644..100755
--- a/indra/llmessage/message_string_table.cpp
+++ b/indra/llmessage/message_string_table.cpp
diff --git a/indra/llmessage/net.cpp b/indra/llmessage/net.cpp
index 85aef5da00..85aef5da00 100644..100755
--- a/indra/llmessage/net.cpp
+++ b/indra/llmessage/net.cpp
diff --git a/indra/llmessage/net.h b/indra/llmessage/net.h
index 0f2437479d..0f2437479d 100644..100755
--- a/indra/llmessage/net.h
+++ b/indra/llmessage/net.h
diff --git a/indra/llmessage/partsyspacket.cpp b/indra/llmessage/partsyspacket.cpp
index ad21614258..ad21614258 100644..100755
--- a/indra/llmessage/partsyspacket.cpp
+++ b/indra/llmessage/partsyspacket.cpp
diff --git a/indra/llmessage/partsyspacket.h b/indra/llmessage/partsyspacket.h
index d9abecea3f..d9abecea3f 100644..100755
--- a/indra/llmessage/partsyspacket.h
+++ b/indra/llmessage/partsyspacket.h
diff --git a/indra/llmessage/patch_code.cpp b/indra/llmessage/patch_code.cpp
index e5d7f19448..e5d7f19448 100644..100755
--- a/indra/llmessage/patch_code.cpp
+++ b/indra/llmessage/patch_code.cpp
diff --git a/indra/llmessage/patch_code.h b/indra/llmessage/patch_code.h
index 4c87c9808a..4c87c9808a 100644..100755
--- a/indra/llmessage/patch_code.h
+++ b/indra/llmessage/patch_code.h
diff --git a/indra/llmessage/patch_dct.cpp b/indra/llmessage/patch_dct.cpp
index b5518b61ea..b5518b61ea 100644..100755
--- a/indra/llmessage/patch_dct.cpp
+++ b/indra/llmessage/patch_dct.cpp
diff --git a/indra/llmessage/patch_dct.h b/indra/llmessage/patch_dct.h
index 101231ec84..101231ec84 100644..100755
--- a/indra/llmessage/patch_dct.h
+++ b/indra/llmessage/patch_dct.h
diff --git a/indra/llmessage/patch_idct.cpp b/indra/llmessage/patch_idct.cpp
index 9ce35df284..9ce35df284 100644..100755
--- a/indra/llmessage/patch_idct.cpp
+++ b/indra/llmessage/patch_idct.cpp
diff --git a/indra/llmessage/sound_ids.cpp b/indra/llmessage/sound_ids.cpp
index 2b8a0807c6..2b8a0807c6 100644..100755
--- a/indra/llmessage/sound_ids.cpp
+++ b/indra/llmessage/sound_ids.cpp
diff --git a/indra/llmessage/sound_ids.h b/indra/llmessage/sound_ids.h
index 6a2e343ad3..6a2e343ad3 100644..100755
--- a/indra/llmessage/sound_ids.h
+++ b/indra/llmessage/sound_ids.h
diff --git a/indra/llmessage/tests/commtest.h b/indra/llmessage/tests/commtest.h
index 0d149b5258..0d149b5258 100644..100755
--- a/indra/llmessage/tests/commtest.h
+++ b/indra/llmessage/tests/commtest.h
diff --git a/indra/llmessage/tests/llareslistener_test.cpp b/indra/llmessage/tests/llareslistener_test.cpp
index 60c91e12cf..60c91e12cf 100644..100755
--- a/indra/llmessage/tests/llareslistener_test.cpp
+++ b/indra/llmessage/tests/llareslistener_test.cpp
diff --git a/indra/llmessage/tests/llavatarnamecache_test.cpp b/indra/llmessage/tests/llavatarnamecache_test.cpp
index ec6b65d483..ec6b65d483 100644..100755
--- a/indra/llmessage/tests/llavatarnamecache_test.cpp
+++ b/indra/llmessage/tests/llavatarnamecache_test.cpp
diff --git a/indra/llmessage/tests/llcurl_stub.cpp b/indra/llmessage/tests/llcurl_stub.cpp
index d84fe0a49f..9b298d0c04 100644..100755
--- a/indra/llmessage/tests/llcurl_stub.cpp
+++ b/indra/llmessage/tests/llcurl_stub.cpp
@@ -28,7 +28,6 @@
#include "llcurl.h"
LLCurl::Responder::Responder()
- : mReferenceCount(0)
{
}
@@ -77,19 +76,3 @@ void LLCurl::Responder::result(LLSD const&)
{
}
-namespace boost
-{
- void intrusive_ptr_add_ref(LLCurl::Responder* p)
- {
- ++p->mReferenceCount;
- }
-
- void intrusive_ptr_release(LLCurl::Responder* p)
- {
- if(p && 0 == --p->mReferenceCount)
- {
- delete p;
- }
- }
-};
-
diff --git a/indra/llmessage/tests/llhost_test.cpp b/indra/llmessage/tests/llhost_test.cpp
index eadf83c428..eadf83c428 100644..100755
--- a/indra/llmessage/tests/llhost_test.cpp
+++ b/indra/llmessage/tests/llhost_test.cpp
diff --git a/indra/llmessage/tests/llhttpclient_test.cpp b/indra/llmessage/tests/llhttpclient_test.cpp
index 843c3bcc4b..559001d079 100644..100755
--- a/indra/llmessage/tests/llhttpclient_test.cpp
+++ b/indra/llmessage/tests/llhttpclient_test.cpp
@@ -47,67 +47,31 @@
namespace tut
{
- LLSD storage;
-
- class LLSDStorageNode : public LLHTTPNode
- {
- public:
- LLSD simpleGet() const { return storage; }
- LLSD simplePut(const LLSD& value) const { storage = value; return LLSD(); }
- };
-
- class ErrorNode : public LLHTTPNode
- {
- public:
- void get(ResponsePtr r, const LLSD& context) const
- { r->status(599, "Intentional error"); }
- void post(ResponsePtr r, const LLSD& context, const LLSD& input) const
- { r->status(input["status"], input["reason"]); }
- };
-
- class TimeOutNode : public LLHTTPNode
- {
- public:
- void get(ResponsePtr r, const LLSD& context) const
- {
- /* do nothing, the request will eventually time out */
- }
- };
-
- LLHTTPRegistration<LLSDStorageNode> gStorageNode("/test/storage");
- LLHTTPRegistration<ErrorNode> gErrorNode("/test/error");
- LLHTTPRegistration<TimeOutNode> gTimeOutNode("/test/timeout");
-
struct HTTPClientTestData
{
public:
HTTPClientTestData():
- local_server(STRINGIZE("http://127.0.0.1:" << getenv("PORT") << "/"))
+ PORT(getenv("PORT")),
+ // Turning NULL PORT into empty string doesn't make things work;
+ // that's just to keep this initializer from blowing up. We test
+ // PORT separately in the constructor body.
+ local_server(STRINGIZE("http://127.0.0.1:" << (PORT? PORT : "") << "/"))
{
+ ensure("Set environment variable PORT to local test server port", PORT);
apr_pool_create(&mPool, NULL);
LLCurl::initClass(false);
- mServerPump = new LLPumpIO(mPool);
mClientPump = new LLPumpIO(mPool);
LLHTTPClient::setPump(*mClientPump);
}
-
+
~HTTPClientTestData()
{
- delete mServerPump;
delete mClientPump;
LLProxy::cleanupClass();
apr_pool_destroy(mPool);
}
- void setupTheServer()
- {
- LLHTTPNode& root = LLIOHTTPServer::create(mPool, *mServerPump, 8888);
-
- LLHTTPStandardServices::useServices();
- LLHTTPRegistrar::buildAllServices(root);
- }
-
void runThePump(float timeout = 100.0f)
{
LLTimer timer;
@@ -115,11 +79,7 @@ namespace tut
while(!mSawCompleted && !mSawCompletedHeader && !timer.hasExpired())
{
- if (mServerPump)
- {
- mServerPump->pump();
- mServerPump->callback();
- }
+ LLFrameTimer::updateFrameTime();
if (mClientPump)
{
mClientPump->pump();
@@ -128,17 +88,11 @@ namespace tut
}
}
- void killServer()
- {
- delete mServerPump;
- mServerPump = NULL;
- }
-
+ const char* const PORT;
const std::string local_server;
private:
apr_pool_t* mPool;
- LLPumpIO* mServerPump;
LLPumpIO* mClientPump;
protected:
@@ -148,11 +102,11 @@ namespace tut
{
std::string msg =
llformat("error() called when not expected, status %d",
- mStatus);
+ mStatus);
fail(msg);
}
}
-
+
void ensureStatusError()
{
if (!mSawError)
@@ -160,7 +114,7 @@ namespace tut
fail("error() wasn't called");
}
}
-
+
LLSD getResult()
{
return mResult;
@@ -169,7 +123,7 @@ namespace tut
{
return mHeader;
}
-
+
protected:
bool mSawError;
U32 mStatus;
@@ -187,18 +141,18 @@ namespace tut
: mClient(client)
{
}
-
+
public:
- static boost::intrusive_ptr<Result> build(HTTPClientTestData& client)
+ static Result* build(HTTPClientTestData& client)
{
- return boost::intrusive_ptr<Result>(new Result(client));
+ return new Result(client);
}
-
+
~Result()
{
mClient.mResultDeleted = true;
}
-
+
virtual void error(U32 status, const std::string& reason)
{
mClient.mSawError = true;
@@ -216,7 +170,7 @@ namespace tut
const LLSD& content)
{
LLHTTPClient::Responder::completed(status, reason, content);
-
+
mClient.mSawCompleted = true;
}
@@ -244,12 +198,12 @@ namespace tut
mResult.clear();
mHeader.clear();
mResultDeleted = false;
-
+
return Result::build(*this);
}
};
-
-
+
+
typedef test_group<HTTPClientTestData> HTTPClientTestGroup;
typedef HTTPClientTestGroup::object HTTPClientTestObject;
HTTPClientTestGroup httpClientTestGroup("http_client");
@@ -282,9 +236,7 @@ namespace tut
sd["list"][1]["three"] = 3;
sd["list"][1]["four"] = 4;
- setupTheServer();
-
- LLHTTPClient::post("http://localhost:8888/web/echo", sd, newResult());
+ LLHTTPClient::post(local_server + "web/echo", sd, newResult());
runThePump();
ensureStatusOK();
ensure_equals("echoed result matches", getResult(), sd);
@@ -297,12 +249,11 @@ namespace tut
sd["message"] = "This is my test message.";
- setupTheServer();
- LLHTTPClient::put("http://localhost:8888/test/storage", sd, newResult());
+ LLHTTPClient::put(local_server + "test/storage", sd, newResult());
runThePump();
ensureStatusOK();
- LLHTTPClient::get("http://localhost:8888/test/storage", newResult());
+ LLHTTPClient::get(local_server + "test/storage", newResult());
runThePump();
ensureStatusOK();
ensure_equals("echoed result matches", getResult(), sd);
@@ -316,9 +267,7 @@ namespace tut
sd["status"] = 543;
sd["reason"] = "error for testing";
- setupTheServer();
-
- LLHTTPClient::post("http://localhost:8888/test/error", sd, newResult());
+ LLHTTPClient::post(local_server + "test/error", sd, newResult());
runThePump();
ensureStatusError();
ensure_contains("reason", mReason, sd["reason"]);
@@ -327,23 +276,16 @@ namespace tut
template<> template<>
void HTTPClientTestObject::test<6>()
{
- setupTheServer();
-
- LLHTTPClient::get("http://localhost:8888/test/timeout", newResult());
- runThePump(1.0f);
- killServer();
- runThePump();
+ const F32 timeout = 1.0f;
+ LLHTTPClient::get(local_server + "test/timeout", newResult(), LLSD(), timeout);
+ runThePump(timeout * 5.0f);
ensureStatusError();
- ensure_equals("reason", mReason, "STATUS_ERROR");
+ ensure_equals("reason", mReason, "STATUS_EXPIRED");
}
template<> template<>
void HTTPClientTestObject::test<7>()
{
- // Can not use the little mini server. The blocking request
- // won't ever let it run. Instead get from a known LLSD
- // source and compare results with the non-blocking get which
- // is tested against the mini server earlier.
LLHTTPClient::get(local_server, newResult());
runThePump();
ensureStatusOK();
diff --git a/indra/llmessage/tests/llhttpclientadapter_test.cpp b/indra/llmessage/tests/llhttpclientadapter_test.cpp
index 13ce0a0edd..13ce0a0edd 100644..100755
--- a/indra/llmessage/tests/llhttpclientadapter_test.cpp
+++ b/indra/llmessage/tests/llhttpclientadapter_test.cpp
diff --git a/indra/llmessage/tests/llmime_test.cpp b/indra/llmessage/tests/llmime_test.cpp
index aed5c4589c..aed5c4589c 100644..100755
--- a/indra/llmessage/tests/llmime_test.cpp
+++ b/indra/llmessage/tests/llmime_test.cpp
diff --git a/indra/llmessage/tests/llmockhttpclient.h b/indra/llmessage/tests/llmockhttpclient.h
index af26bf8803..af26bf8803 100644..100755
--- a/indra/llmessage/tests/llmockhttpclient.h
+++ b/indra/llmessage/tests/llmockhttpclient.h
diff --git a/indra/llmessage/tests/llnamevalue_test.cpp b/indra/llmessage/tests/llnamevalue_test.cpp
index 8902fdd2e8..8902fdd2e8 100644..100755
--- a/indra/llmessage/tests/llnamevalue_test.cpp
+++ b/indra/llmessage/tests/llnamevalue_test.cpp
diff --git a/indra/llmessage/tests/llpartdata_test.cpp b/indra/llmessage/tests/llpartdata_test.cpp
index 9123bd06c7..de81e0bbb2 100644..100755
--- a/indra/llmessage/tests/llpartdata_test.cpp
+++ b/indra/llmessage/tests/llpartdata_test.cpp
@@ -38,10 +38,34 @@
namespace tut
{
+
+ //bunch of sniffed data that *should* be a valid particle system
+ static U8 msg[] = {
+ 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0x00, 0x80, 0x00, 0x80,
+ 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x5e, 0x12, 0x0b, 0xa1, 0x58, 0x05, 0xdc, 0x57, 0x66,
+ 0xb7, 0xf5, 0xac, 0x4b, 0xd1, 0x8f, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x02, 0x05, 0x02, 0x00, 0x00, 0x0a, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x20, 0x20, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x7e, 0xc6, 0x81, 0xdc, 0x7e, 0xc6, 0x81, 0xdc, 0x77, 0xcf, 0xef, 0xd4, 0xce, 0x64, 0x1a, 0x7e,
+ 0x26, 0x87, 0x55, 0x7f, 0xdd, 0x65, 0x22, 0x7f, 0xdd, 0x65, 0x22, 0x7f, 0x77, 0xcf, 0x98, 0xa3, 0xab,
+ 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd1, 0xf2,
+ 0xf1, 0x65, 0x32, 0x1b, 0xef, 0x18, 0x70, 0x66, 0xba, 0x30, 0xa0, 0x11, 0xaa, 0x2f, 0xb0, 0xab, 0xd0,
+ 0x30, 0x7d, 0xbd, 0x01, 0x00, 0xf8, 0x0d, 0xb8, 0x30, 0x01, 0x00, 0x00, 0x00, 0xce, 0xc6, 0x81, 0xdc,
+ 0xce, 0xc6, 0x81, 0xdc, 0xc7, 0xcf, 0xef, 0xd4, 0x75, 0x65, 0x1a, 0x7f, 0x62, 0x6f, 0x55, 0x7f, 0x6d,
+ 0x65, 0x22, 0x7f, 0x6d, 0x65, 0x22, 0x7f, 0xc7, 0xcf, 0x98, 0xa3, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
+ 0xab, 0xab, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0xf2, 0xf1, 0x62, 0x12, 0x1b, 0xef,
+ 0x18, 0x7e, 0xbd, 0x01, 0x00, 0x16, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x7c, 0xac, 0x28, 0x03, 0x80, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x48,
+ 0xe0, 0xb9, 0x30, 0x03, 0xe1, 0xb9, 0x30, 0xbb, 0x00, 0x00, 0x00, 0x48, 0xe0, 0xb9, 0x30, 0x36, 0xd9,
+ 0x81, 0xdc, 0x36, 0xd9, 0x81, 0xdc, 0x3f, 0xd0, 0xef, 0xd4, 0xa5, 0x7a, 0x72, 0x7f, 0x26, 0x30, 0x55,
+ 0x7f, 0x95, 0x7a, 0x22, 0x7f, 0x95, 0x7a, 0x22, 0x7f, 0x3f, 0xd0, 0x98, 0xa3, 0xab, 0xab, 0xab, 0xab,
+ 0xab, 0xab, 0xab, 0xab, 0x00, 0x00, 0x00, 0x00, 0x00 };
struct partdata_test
{
};
+
typedef test_group<partdata_test> partdata_test_t;
typedef partdata_test_t::object partdata_test_object_t;
tut::partdata_test_t tut_partdata_test("LLPartData");
@@ -49,168 +73,82 @@ namespace tut
template<> template<>
void partdata_test_object_t::test<1>()
{
- LLPartData llpdata,llpdata1;
- U8 pkbuf[128];
-
- llpdata.setFlags(LLPartData::LL_PART_INTERP_COLOR_MASK | LLPartData::LL_PART_INTERP_SCALE_MASK |
- LLPartData::LL_PART_BOUNCE_MASK | LLPartData::LL_PART_WIND_MASK | LLPartData::LL_PART_FOLLOW_SRC_MASK |
- LLPartData::LL_PART_FOLLOW_VELOCITY_MASK | LLPartData::LL_PART_TARGET_POS_MASK | LLPartData::LL_PART_TARGET_LINEAR_MASK |
- LLPartData::LL_PART_EMISSIVE_MASK | LLPartData::LL_PART_BEAM_MASK | LLPartData::LL_PART_DEAD_MASK);
-
- llpdata.setMaxAge(29.3f);
-
- LLVector3 llvec1(1.0f, .5f, .25f);
- llpdata.setStartColor(llvec1);
- llpdata.setStartAlpha(.7f);
-
- LLVector3 llvec2(.2f, .3f, 1.0f);
- llpdata.setEndColor(llvec2);
- llpdata.setEndAlpha(1.0f);
+ LLPartSysData llpsysdata;
+ LLDataPackerBinaryBuffer dp1(msg, sizeof(msg));
- llpdata.setStartScale(3.23f, 4.0f);
- llpdata.setEndScale(2.4678f, 1.0f);
+ ensure("LLPartSysData::unpack failed.", llpsysdata.unpack(dp1));
- LLDataPackerBinaryBuffer dp((U8*)pkbuf, 128);
- llpdata.pack(dp);
- S32 cur_size = dp.getCurrentSize();
-
- LLDataPackerBinaryBuffer dp1((U8*)pkbuf, cur_size);
- llpdata1.unpack(dp1);
-
- ensure("1.mFlags values are different after unpacking", llpdata1.mFlags == llpdata.mFlags);
- ensure_approximately_equals("2.mMaxAge values are different after unpacking", llpdata1.mMaxAge, llpdata.mMaxAge, 8);
-
- ensure_approximately_equals("3.mStartColor[0] values are different after unpacking", llpdata1.mStartColor.mV[0], llpdata.mStartColor.mV[0], 8);
- ensure_approximately_equals("4.mStartColor[1] values are different after unpacking", llpdata1.mStartColor.mV[1], llpdata.mStartColor.mV[1], 8);
- ensure_approximately_equals("5.mStartColor[2] values are different after unpacking", llpdata1.mStartColor.mV[2], llpdata.mStartColor.mV[2], 8);
- ensure_approximately_equals("6.mStartColor[3] values are different after unpacking", llpdata1.mStartColor.mV[3], llpdata.mStartColor.mV[3], 8);
-
- ensure_approximately_equals("7.mEndColor[0] values are different after unpacking", llpdata1.mEndColor.mV[0], llpdata.mEndColor.mV[0], 8);
- ensure_approximately_equals("8.mEndColor[1] values are different after unpacking", llpdata1.mEndColor.mV[1], llpdata.mEndColor.mV[1], 8);
- ensure_approximately_equals("9.mEndColor[2] values are different after unpacking", llpdata1.mEndColor.mV[2], llpdata.mEndColor.mV[2], 8);
- ensure_approximately_equals("10.mEndColor[2] values are different after unpacking", llpdata1.mEndColor.mV[3], llpdata.mEndColor.mV[3], 8);
-
- ensure_approximately_equals("11.mStartScale[0] values are different after unpacking", llpdata1.mStartScale.mV[0], llpdata.mStartScale.mV[0], 5);
- ensure_approximately_equals("12.mStartScale[1] values are different after unpacking", llpdata1.mStartScale.mV[1], llpdata.mStartScale.mV[1], 5);
-
- ensure_approximately_equals("13.mEndScale[0] values are different after unpacking", llpdata1.mEndScale.mV[0], llpdata.mEndScale.mV[0], 5);
- ensure_approximately_equals("14.mEndScale[1] values are different after unpacking", llpdata1.mEndScale.mV[1], llpdata.mEndScale.mV[1], 5);
- }
-
-
- template<> template<>
- void partdata_test_object_t::test<2>()
- {
- LLPartData llpdata,llpdata1;
-
- llpdata.setFlags(LLPartData::LL_PART_INTERP_COLOR_MASK | LLPartData::LL_PART_INTERP_SCALE_MASK |
- LLPartData::LL_PART_BOUNCE_MASK | LLPartData::LL_PART_WIND_MASK | LLPartData::LL_PART_FOLLOW_SRC_MASK |
- LLPartData::LL_PART_FOLLOW_VELOCITY_MASK | LLPartData::LL_PART_TARGET_POS_MASK | LLPartData::LL_PART_TARGET_LINEAR_MASK |
- LLPartData::LL_PART_EMISSIVE_MASK | LLPartData::LL_PART_BEAM_MASK | LLPartData::LL_PART_DEAD_MASK);
-
- llpdata.setMaxAge(29.3f);
-
- LLVector3 llvec1(1.0f, .5f, .25f);
- llpdata.setStartColor(llvec1);
- llpdata.setStartAlpha(.7f);
-
- LLVector3 llvec2(.2f, .3f, 1.0f);
- llpdata.setEndColor(llvec2);
- llpdata.setEndAlpha(1.0f);
-
- llpdata.setStartScale(3.23f, 4.0f);
- llpdata.setEndScale(2.4678f, 1.0f);
-
- LLSD llsd = llpdata.asLLSD();
-
- llpdata1.fromLLSD(llsd);
-
- ensure("1.mFlags values are different after unpacking", llpdata1.mFlags == llpdata.mFlags);
- ensure_approximately_equals("2.mMaxAge values are different after unpacking", llpdata1.mMaxAge, llpdata.mMaxAge, 8);
-
- ensure_approximately_equals("3.mStartColor[0] values are different after unpacking", llpdata1.mStartColor.mV[0], llpdata.mStartColor.mV[0], 8);
- ensure_approximately_equals("4.mStartColor[1] values are different after unpacking", llpdata1.mStartColor.mV[1], llpdata.mStartColor.mV[1], 8);
- ensure_approximately_equals("5.mStartColor[2] values are different after unpacking", llpdata1.mStartColor.mV[2], llpdata.mStartColor.mV[2], 8);
- ensure_approximately_equals("6.mStartColor[3] values are different after unpacking", llpdata1.mStartColor.mV[3], llpdata.mStartColor.mV[3], 8);
-
- ensure_approximately_equals("7.mEndColor[0] values are different after unpacking", llpdata1.mEndColor.mV[0], llpdata.mEndColor.mV[0], 8);
- ensure_approximately_equals("8.mEndColor[1] values are different after unpacking", llpdata1.mEndColor.mV[1], llpdata.mEndColor.mV[1], 8);
- ensure_approximately_equals("9.mEndColor[2] values are different after unpacking", llpdata1.mEndColor.mV[2], llpdata.mEndColor.mV[2], 8);
- ensure_approximately_equals("10.mEndColor[2] values are different after unpacking", llpdata1.mEndColor.mV[3], llpdata.mEndColor.mV[3], 8);
-
- ensure_approximately_equals("11.mStartScale[0] values are different after unpacking", llpdata1.mStartScale.mV[0], llpdata.mStartScale.mV[0], 5);
- ensure_approximately_equals("12.mStartScale[1] values are different after unpacking", llpdata1.mStartScale.mV[1], llpdata.mStartScale.mV[1], 5);
-
- ensure_approximately_equals("13.mEndScale[0] values are different after unpacking", llpdata1.mEndScale.mV[0], llpdata.mEndScale.mV[0], 5);
- ensure_approximately_equals("14.mEndScale[1] values are different after unpacking", llpdata1.mEndScale.mV[1], llpdata.mEndScale.mV[1], 5);
- }
-
-
-//*********llpartsysdata***********
-
- template<> template<>
- void partdata_test_object_t::test<3>()
- {
- LLPartSysData llpsysdata, llpsysdata1;
- U8 pkbuf[256];
- llpsysdata.setBurstSpeedMin(33.33f);
- ensure("1.mBurstSpeedMin coudnt be set", 33.33f == llpsysdata.mBurstSpeedMin);
-
- llpsysdata.setBurstSpeedMax(44.44f);
- ensure("2.mBurstSpeedMax coudnt be set", 44.44f == llpsysdata.mBurstSpeedMax);
-
- llpsysdata.setBurstRadius(45.55f);
- ensure("3.mBurstRadius coudnt be set", 45.55f == llpsysdata.mBurstRadius);
-
- LLVector3 llvec(44.44f, 111.11f, -40.4f);
- llpsysdata.setPartAccel(llvec);
-
- llpsysdata.mCRC = 0xFFFFFFFF;
- llpsysdata.mFlags = 0x20;
-
- llpsysdata.mPattern = LLPartSysData::LL_PART_SRC_PATTERN_ANGLE_CONE_EMPTY;
-
- llpsysdata.mMaxAge = 99.99f;
- llpsysdata.mStartAge = 18.5f;
- llpsysdata.mInnerAngle = 4.234f;
- llpsysdata.mOuterAngle = 7.123f;
- llpsysdata.mBurstRate = 245.53f;
- llpsysdata.mBurstPartCount = 0xFF;
- llpsysdata.mAngularVelocity = llvec;
-
- llpsysdata.mPartImageID.generate();
- llpsysdata.mTargetUUID.generate();
+ //mCRC 1 unsigned int
+ ensure("mCRC different after unpacking", llpsysdata.mCRC == (U32) 1);
+ //mFlags 0 unsigned int
+ ensure ("mFlags different after unpacking", llpsysdata.mFlags == (U32) 0);
+ //mPattern 1 '' unsigned char
+ ensure ("mPattern different after unpacking", llpsysdata.mPattern == (U8) 1);
+ //mInnerAngle 0.00000000 float
+ ensure_approximately_equals("mInnerAngle different after unpacking", llpsysdata.mInnerAngle, 0.f, 8);
+ //mOuterAngle 0.00000000 float
+ ensure_approximately_equals("mOuterAngle different after unpacking", llpsysdata.mOuterAngle, 0.f, 8);
+ //mAngularVelocity 0,0,0
+ ensure_approximately_equals("mAngularVelocity.mV[0] different after unpacking", llpsysdata.mAngularVelocity.mV[0], 0.f, 8);
+ ensure_approximately_equals("mAngularVelocity.mV[0] different after unpacking", llpsysdata.mAngularVelocity.mV[1], 0.f, 8);
+ ensure_approximately_equals("mAngularVelocity.mV[0] different after unpacking", llpsysdata.mAngularVelocity.mV[2], 0.f, 8);
+ //mBurstRate 0.097656250 float
+ ensure_approximately_equals("mBurstRate different after unpacking", llpsysdata.mBurstRate, 0.097656250f, 8);
+ //mBurstPartCount 1 '' unsigned char
+ ensure("mBurstPartCount different after unpacking", llpsysdata.mBurstPartCount == (U8) 1);
+ //mBurstRadius 0.00000000 float
+ ensure_approximately_equals("mBurstRadius different after unpacking", llpsysdata.mBurstRadius, 0.f, 8);
+ //mBurstSpeedMin 1.0000000 float
+ ensure_approximately_equals("mBurstSpeedMin different after unpacking", llpsysdata.mBurstSpeedMin, 1.f, 8);
+ //mBurstSpeedMax 1.0000000 float
+ ensure_approximately_equals("mBurstSpeedMax different after unpacking", llpsysdata.mBurstSpeedMax, 1.f, 8);
+ //mMaxAge 0.00000000 float
+ ensure_approximately_equals("mMaxAge different after unpacking", llpsysdata.mMaxAge, 0.f, 8);
+ //mStartAge 0.00000000 float
+ ensure_approximately_equals("mStartAge different after unpacking", llpsysdata.mStartAge, 0.f, 8);
+ //mPartAccel <0,0,0>
+ ensure_approximately_equals("mPartAccel.mV[0] different after unpacking", llpsysdata.mPartAccel.mV[0], 0.f, 7);
+ ensure_approximately_equals("mPartAccel.mV[1] different after unpacking", llpsysdata.mPartAccel.mV[1], 0.f, 7);
+ ensure_approximately_equals("mPartAccel.mV[2] different after unpacking", llpsysdata.mPartAccel.mV[2], 0.f, 7);
+
+ //mPartData
+ LLPartData& data = llpsysdata.mPartData;
+
+ //mFlags 132354 unsigned int
+ ensure ("mPartData.mFlags different after unpacking", data.mFlags == (U32) 132354);
+ //mMaxAge 10.000000 float
+ ensure_approximately_equals("mPartData.mMaxAge different after unpacking", data.mMaxAge, 10.f, 8);
+ //mStartColor <1,1,1,1>
+ ensure_approximately_equals("mPartData.mStartColor.mV[0] different after unpacking", data.mStartColor.mV[0], 1.f, 8);
+ ensure_approximately_equals("mPartData.mStartColor.mV[1] different after unpacking", data.mStartColor.mV[1], 1.f, 8);
+ ensure_approximately_equals("mPartData.mStartColor.mV[2] different after unpacking", data.mStartColor.mV[2], 1.f, 8);
+ ensure_approximately_equals("mPartData.mStartColor.mV[3] different after unpacking", data.mStartColor.mV[3], 1.f, 8);
+ //mEndColor <1,1,0,0>
+ ensure_approximately_equals("mPartData.mEndColor.mV[0] different after unpacking", data.mEndColor.mV[0], 1.f, 8);
+ ensure_approximately_equals("mPartData.mEndColor.mV[1] different after unpacking", data.mEndColor.mV[1], 1.f, 8);
+ ensure_approximately_equals("mPartData.mEndColor.mV[2] different after unpacking", data.mEndColor.mV[2], 0.f, 8);
+ ensure_approximately_equals("mPartData.mEndColor.mV[3] different after unpacking", data.mEndColor.mV[3], 0.f, 8);
+ //mStartScale <1,1>
+ ensure_approximately_equals("mPartData.mStartScale.mV[0] different after unpacking", data.mStartScale.mV[0], 1.f, 8);
+ ensure_approximately_equals("mPartData.mStartScale.mV[1] different after unpacking", data.mStartScale.mV[1], 1.f, 8);
+ //mEndScale <0,0>
+ ensure_approximately_equals("mPartData.mEndScale.mV[0] different after unpacking", data.mEndScale.mV[0], 0.f, 8);
+ ensure_approximately_equals("mPartData.mEndScale.mV[1] different after unpacking", data.mEndScale.mV[1], 0.f, 8);
+ //mPosOffset <0,0,0>
+ ensure_approximately_equals("mPartData.mPosOffset.mV[0] different after unpacking", data.mPosOffset.mV[0], 0.f, 8);
+ ensure_approximately_equals("mPartData.mPosOffset.mV[1] different after unpacking", data.mPosOffset.mV[1], 0.f, 8);
+ ensure_approximately_equals("mPartData.mPosOffset.mV[2] different after unpacking", data.mPosOffset.mV[2], 0.f, 8);
+ //mParameter 0.00000000 float
+ ensure_approximately_equals("mPartData.mParameter different after unpacking", data.mParameter, 0.f, 8);
- LLDataPackerBinaryBuffer dp((U8*)pkbuf, 256);
- llpsysdata.pack(dp);
- S32 cur_size = dp.getCurrentSize();
- LLDataPackerBinaryBuffer dp1((U8*)pkbuf, cur_size);
- llpsysdata1.unpack(dp1);
-
- ensure("1.mCRC's not equal", llpsysdata.mCRC == llpsysdata1.mCRC);
- ensure("2.mFlags's not equal", llpsysdata.mFlags == llpsysdata1.mFlags);
- ensure("3.mPattern's not equal", llpsysdata.mPattern == llpsysdata1.mPattern);
- ensure_approximately_equals("4.mMaxAge's not equal", llpsysdata.mMaxAge , llpsysdata1.mMaxAge, 8);
- ensure_approximately_equals("5.mStartAge's not equal", llpsysdata.mStartAge, llpsysdata1.mStartAge, 8);
- ensure_approximately_equals("6.mOuterAngle's not equal", llpsysdata.mOuterAngle, llpsysdata1.mOuterAngle, 5);
- ensure_approximately_equals("7.mInnerAngles's not equal", llpsysdata.mInnerAngle, llpsysdata1.mInnerAngle, 5);
- ensure_approximately_equals("8.mBurstRate's not equal", llpsysdata.mBurstRate, llpsysdata1.mBurstRate, 8);
- ensure("9.mBurstPartCount's not equal", llpsysdata.mBurstPartCount == llpsysdata1.mBurstPartCount);
-
- ensure_approximately_equals("10.mBurstSpeedMin's not equal", llpsysdata.mBurstSpeedMin, llpsysdata1.mBurstSpeedMin, 8);
- ensure_approximately_equals("11.mBurstSpeedMax's not equal", llpsysdata.mBurstSpeedMax, llpsysdata1.mBurstSpeedMax, 8);
-
- ensure_approximately_equals("12.mAngularVelocity's not equal", llpsysdata.mAngularVelocity.mV[0], llpsysdata1.mAngularVelocity.mV[0], 7);
- ensure_approximately_equals("13.mAngularVelocity's not equal", llpsysdata.mAngularVelocity.mV[1], llpsysdata1.mAngularVelocity.mV[1], 7);
- ensure_approximately_equals("14.mAngularVelocity's not equal", llpsysdata.mAngularVelocity.mV[2], llpsysdata1.mAngularVelocity.mV[2], 7);
-
- ensure_approximately_equals("15.mPartAccel's not equal", llpsysdata.mPartAccel.mV[0], llpsysdata1.mPartAccel.mV[0], 7);
- ensure_approximately_equals("16.mPartAccel's not equal", llpsysdata.mPartAccel.mV[1], llpsysdata1.mPartAccel.mV[1], 7);
- ensure_approximately_equals("17.mPartAccel's not equal", llpsysdata.mPartAccel.mV[2], llpsysdata1.mPartAccel.mV[2], 7);
-
- ensure("18.mPartImageID's not equal", llpsysdata.mPartImageID == llpsysdata1.mPartImageID);
- ensure("19.mTargetUUID's not equal", llpsysdata.mTargetUUID == llpsysdata1.mTargetUUID);
- ensure_approximately_equals("20.mBurstRadius's not equal", llpsysdata.mBurstRadius, llpsysdata1.mBurstRadius, 8);
+ //mStartGlow 0.00000000 float
+ ensure_approximately_equals("mPartData.mStartGlow different after unpacking", data.mStartGlow, 0.f, 8);
+ //mEndGlow 0.00000000 float
+ ensure_approximately_equals("mPartData.mEndGlow different after unpacking", data.mEndGlow, 0.f, 8);
+ //mBlendFuncSource 2 '' unsigned char
+ ensure("mPartData.mBlendFuncSource different after unpacking", data.mBlendFuncSource == (U8) 2);
+ //mBlendFuncDest 1 '' unsigned char
+ ensure("mPartData.mBlendFuncDest different after unpacking", data.mBlendFuncDest == (U8) 1);
}
}
diff --git a/indra/llmessage/tests/llregionpresenceverifier_test.cpp b/indra/llmessage/tests/llregionpresenceverifier_test.cpp
index 5b89f2a8c6..5b89f2a8c6 100644..100755
--- a/indra/llmessage/tests/llregionpresenceverifier_test.cpp
+++ b/indra/llmessage/tests/llregionpresenceverifier_test.cpp
diff --git a/indra/llmessage/tests/llsdmessage_test.cpp b/indra/llmessage/tests/llsdmessage_test.cpp
index 31a791e4b4..44b024a83f 100644..100755
--- a/indra/llmessage/tests/llsdmessage_test.cpp
+++ b/indra/llmessage/tests/llsdmessage_test.cpp
@@ -42,6 +42,7 @@
// external library headers
// other Linden headers
#include "../test/lltut.h"
+#include "../test/catch_and_store_what_in.h"
#include "llsdserialize.h"
#include "llevents.h"
#include "stringize.h"
@@ -72,43 +73,14 @@ namespace tut
template<> template<>
void llsdmessage_object::test<1>()
{
- bool threw = false;
+ std::string threw;
// This should fail...
try
{
LLSDMessage localListener;
}
- catch (const LLEventPump::DupPumpName&)
- {
- threw = true;
- }
- catch (const std::runtime_error& ex)
- {
- // This clause is because on Linux, on the viewer side, for this
- // one test program (though not others!), the
- // LLEventPump::DupPumpName exception isn't caught by the clause
- // above. Warn the user...
- std::cerr << "Failed to catch " << typeid(ex).name() << std::endl;
- // But if the expected exception was thrown, allow the test to
- // succeed anyway. Not sure how else to handle this odd case.
- if (std::string(typeid(ex).name()) == typeid(LLEventPump::DupPumpName).name())
- {
- threw = true;
- }
- else
- {
- // We don't even recognize this exception. Let it propagate
- // out to TUT to fail the test.
- throw;
- }
- }
- catch (...)
- {
- std::cerr << "Utterly failed to catch expected exception!" << std::endl;
- // This case is full of fail. We HAVE to address it.
- throw;
- }
- ensure("second LLSDMessage should throw", threw);
+ CATCH_AND_STORE_WHAT_IN(threw, LLEventPump::DupPumpName)
+ ensure("second LLSDMessage should throw", ! threw.empty());
}
template<> template<>
diff --git a/indra/llmessage/tests/lltemplatemessagedispatcher_test.cpp b/indra/llmessage/tests/lltemplatemessagedispatcher_test.cpp
index 3b04530c1a..3b04530c1a 100644..100755
--- a/indra/llmessage/tests/lltemplatemessagedispatcher_test.cpp
+++ b/indra/llmessage/tests/lltemplatemessagedispatcher_test.cpp
diff --git a/indra/llmessage/tests/lltesthttpclientadapter.cpp b/indra/llmessage/tests/lltesthttpclientadapter.cpp
index 4539e4a540..4539e4a540 100644..100755
--- a/indra/llmessage/tests/lltesthttpclientadapter.cpp
+++ b/indra/llmessage/tests/lltesthttpclientadapter.cpp
diff --git a/indra/llmessage/tests/lltesthttpclientadapter.h b/indra/llmessage/tests/lltesthttpclientadapter.h
index c29cbb3a2a..c29cbb3a2a 100644..100755
--- a/indra/llmessage/tests/lltesthttpclientadapter.h
+++ b/indra/llmessage/tests/lltesthttpclientadapter.h
diff --git a/indra/llmessage/tests/lltestmessagesender.cpp b/indra/llmessage/tests/lltestmessagesender.cpp
index ee40e0249e..ee40e0249e 100644..100755
--- a/indra/llmessage/tests/lltestmessagesender.cpp
+++ b/indra/llmessage/tests/lltestmessagesender.cpp
diff --git a/indra/llmessage/tests/lltestmessagesender.h b/indra/llmessage/tests/lltestmessagesender.h
index bb89289585..bb89289585 100644..100755
--- a/indra/llmessage/tests/lltestmessagesender.h
+++ b/indra/llmessage/tests/lltestmessagesender.h
diff --git a/indra/llmessage/tests/lltrustedmessageservice_test.cpp b/indra/llmessage/tests/lltrustedmessageservice_test.cpp
index b287a29841..b287a29841 100644..100755
--- a/indra/llmessage/tests/lltrustedmessageservice_test.cpp
+++ b/indra/llmessage/tests/lltrustedmessageservice_test.cpp
diff --git a/indra/llmessage/tests/llxfer_file_test.cpp b/indra/llmessage/tests/llxfer_file_test.cpp
index a8c1adf9b4..a8c1adf9b4 100644..100755
--- a/indra/llmessage/tests/llxfer_file_test.cpp
+++ b/indra/llmessage/tests/llxfer_file_test.cpp
diff --git a/indra/llmessage/tests/networkio.h b/indra/llmessage/tests/networkio.h
index 2aff90ca1e..2aff90ca1e 100644..100755
--- a/indra/llmessage/tests/networkio.h
+++ b/indra/llmessage/tests/networkio.h
diff --git a/indra/llmessage/tests/test_llsdmessage_peer.py b/indra/llmessage/tests/test_llsdmessage_peer.py
index fe4f3a8c01..e45249b1cb 100644..100755
--- a/indra/llmessage/tests/test_llsdmessage_peer.py
+++ b/indra/llmessage/tests/test_llsdmessage_peer.py
@@ -39,6 +39,9 @@ sys.path.insert(0, os.path.join(mydir, os.pardir, os.pardir, "lib", "python"))
from indra.util.fastest_elementtree import parse as xml_parse
from indra.base import llsd
from testrunner import freeport, run, debug, VERBOSE
+import time
+
+_storage=None
class TestHTTPRequestHandler(BaseHTTPRequestHandler):
"""This subclass of BaseHTTPRequestHandler is to receive and echo
@@ -90,21 +93,14 @@ class TestHTTPRequestHandler(BaseHTTPRequestHandler):
# Read the provided POST data.
self.answer(self.read_xml())
+ def do_PUT(self):
+ # Read the provided PUT data.
+ self.answer(self.read_xml())
+
def answer(self, data, withdata=True):
+ global _storage
debug("%s.answer(%s): self.path = %r", self.__class__.__name__, data, self.path)
- if "fail" not in self.path:
- data = data.copy() # we're going to modify
- # Ensure there's a "reply" key in data, even if there wasn't before
- data["reply"] = data.get("reply", llsd.LLSD("success"))
- response = llsd.format_xml(data)
- debug("success: %s", response)
- self.send_response(200)
- self.send_header("Content-type", "application/llsd+xml")
- self.send_header("Content-Length", str(len(response)))
- self.end_headers()
- if withdata:
- self.wfile.write(response)
- else: # fail requested
+ if "fail" in self.path or "test/error" in self.path: # fail requested
status = data.get("status", 500)
# self.responses maps an int status to a (short, long) pair of
# strings. We want the longer string. That's why we pass a string
@@ -117,6 +113,30 @@ class TestHTTPRequestHandler(BaseHTTPRequestHandler):
"without providing a reason" % status))[1])
debug("fail requested: %s: %r", status, reason)
self.send_error(status, reason)
+ else:
+ if "web/echo" in self.path:
+ pass
+ elif "test/timeout" in self.path:
+ time.sleep(5.0)
+ return
+ elif "test/storage" in self.path:
+ if "GET" == self.command:
+ data = _storage
+ else:
+ _storage = data
+ data = "ok"
+ else:
+ data = data.copy() # we're going to modify
+ # Ensure there's a "reply" key in data, even if there wasn't before
+ data["reply"] = data.get("reply", llsd.LLSD("success"))
+ response = llsd.format_xml(data)
+ debug("success: %s", response)
+ self.send_response(200)
+ self.send_header("Content-type", "application/llsd+xml")
+ self.send_header("Content-Length", str(len(response)))
+ self.end_headers()
+ if withdata:
+ self.wfile.write(response)
if not VERBOSE:
# When VERBOSE is set, skip both these overrides because they exist to
diff --git a/indra/llmessage/tests/testrunner.py b/indra/llmessage/tests/testrunner.py
index 5b9beb359b..5b9beb359b 100644..100755
--- a/indra/llmessage/tests/testrunner.py
+++ b/indra/llmessage/tests/testrunner.py
diff --git a/indra/llplugin/CMakeLists.txt b/indra/llplugin/CMakeLists.txt
index 1353b7a458..75d89aac78 100644..100755
--- a/indra/llplugin/CMakeLists.txt
+++ b/indra/llplugin/CMakeLists.txt
@@ -22,6 +22,10 @@ include_directories(
${LLWINDOW_INCLUDE_DIRS}
${LLQTWEBKIT_INCLUDE_DIR}
)
+include_directories(SYSTEM
+ ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+ ${LLXML_SYSTEM_INCLUDE_DIRS}
+ )
set(llplugin_SOURCE_FILES
llpluginclassmedia.cpp
diff --git a/indra/llplugin/llpluginclassmedia.cpp b/indra/llplugin/llpluginclassmedia.cpp
index dbd96673a1..0644d2638c 100644..100755
--- a/indra/llplugin/llpluginclassmedia.cpp
+++ b/indra/llplugin/llpluginclassmedia.cpp
@@ -1074,7 +1074,7 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
mAuthURL = message.getValue("url");
mAuthRealm = message.getValue("realm");
mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_AUTH_REQUEST);
- }
+ }
else if(message_name == "debug_message")
{
mDebugMessageText = message.getValue("message_text");
diff --git a/indra/llplugin/llpluginclassmedia.h b/indra/llplugin/llpluginclassmedia.h
index 5fe8254331..5fe8254331 100644..100755
--- a/indra/llplugin/llpluginclassmedia.h
+++ b/indra/llplugin/llpluginclassmedia.h
diff --git a/indra/llplugin/llpluginclassmediaowner.h b/indra/llplugin/llpluginclassmediaowner.h
index 2f3edba7f3..2f3edba7f3 100644..100755
--- a/indra/llplugin/llpluginclassmediaowner.h
+++ b/indra/llplugin/llpluginclassmediaowner.h
diff --git a/indra/llplugin/llplugincookiestore.cpp b/indra/llplugin/llplugincookiestore.cpp
index 82017ab3fa..9f4d65e723 100644..100755
--- a/indra/llplugin/llplugincookiestore.cpp
+++ b/indra/llplugin/llplugincookiestore.cpp
@@ -87,6 +87,16 @@ std::string LLPluginCookieStore::Cookie::getKey() const
return result;
}
+std::string LLPluginCookieStore::Cookie::getDomain() const
+{
+ std::string result;
+ if(mDomainEnd > mDomainStart)
+ {
+ result += mCookie.substr(mDomainStart, mDomainEnd - mDomainStart);
+ }
+ return result;
+}
+
bool LLPluginCookieStore::Cookie::parse(const std::string &host)
{
bool first_field = true;
@@ -662,3 +672,21 @@ void LLPluginCookieStore::removeCookie(const std::string &key)
}
}
+void LLPluginCookieStore::removeCookiesByDomain(const std::string &domain)
+{
+ cookie_map_t::iterator iter = mCookies.begin();
+ while(iter != mCookies.end())
+ {
+ if(iter->second->getDomain() == domain)
+ {
+ cookie_map_t::iterator doErase = iter;
+ iter++;
+ delete doErase->second;
+ mCookies.erase(doErase);
+ }
+ else
+ {
+ iter++;
+ }
+ }
+}
diff --git a/indra/llplugin/llplugincookiestore.h b/indra/llplugin/llplugincookiestore.h
index 91289d38a5..a2fdeab647 100644..100755
--- a/indra/llplugin/llplugincookiestore.h
+++ b/indra/llplugin/llplugincookiestore.h
@@ -67,6 +67,8 @@ public:
// quote or unquote a string as per the definition of 'quoted-string' in rfc2616
static std::string quoteString(const std::string &s);
static std::string unquoteString(const std::string &s);
+
+ void removeCookiesByDomain(const std::string &domain);
private:
@@ -79,6 +81,7 @@ private:
// Construct a string from the cookie that uniquely represents it, to be used as a key in a std::map.
std::string getKey() const;
+ std::string getDomain() const;
const std::string &getCookie() const { return mCookie; };
bool isSessionCookie() const { return mDate.isNull(); };
diff --git a/indra/llplugin/llplugininstance.cpp b/indra/llplugin/llplugininstance.cpp
index 7cde82a20e..7cde82a20e 100644..100755
--- a/indra/llplugin/llplugininstance.cpp
+++ b/indra/llplugin/llplugininstance.cpp
diff --git a/indra/llplugin/llplugininstance.h b/indra/llplugin/llplugininstance.h
index e6926c3e37..e6926c3e37 100644..100755
--- a/indra/llplugin/llplugininstance.h
+++ b/indra/llplugin/llplugininstance.h
diff --git a/indra/llplugin/llpluginmessage.cpp b/indra/llplugin/llpluginmessage.cpp
index b39e951155..b39e951155 100644..100755
--- a/indra/llplugin/llpluginmessage.cpp
+++ b/indra/llplugin/llpluginmessage.cpp
diff --git a/indra/llplugin/llpluginmessage.h b/indra/llplugin/llpluginmessage.h
index f86b68d16e..f86b68d16e 100644..100755
--- a/indra/llplugin/llpluginmessage.h
+++ b/indra/llplugin/llpluginmessage.h
diff --git a/indra/llplugin/llpluginmessageclasses.h b/indra/llplugin/llpluginmessageclasses.h
index 65fc8cb5ff..65fc8cb5ff 100644..100755
--- a/indra/llplugin/llpluginmessageclasses.h
+++ b/indra/llplugin/llpluginmessageclasses.h
diff --git a/indra/llplugin/llpluginmessagepipe.cpp b/indra/llplugin/llpluginmessagepipe.cpp
index 091e93ea4b..091e93ea4b 100644..100755
--- a/indra/llplugin/llpluginmessagepipe.cpp
+++ b/indra/llplugin/llpluginmessagepipe.cpp
diff --git a/indra/llplugin/llpluginmessagepipe.h b/indra/llplugin/llpluginmessagepipe.h
index c3498beac0..c3498beac0 100644..100755
--- a/indra/llplugin/llpluginmessagepipe.h
+++ b/indra/llplugin/llpluginmessagepipe.h
diff --git a/indra/llplugin/llpluginprocesschild.cpp b/indra/llplugin/llpluginprocesschild.cpp
index f8a282184e..f8a282184e 100644..100755
--- a/indra/llplugin/llpluginprocesschild.cpp
+++ b/indra/llplugin/llpluginprocesschild.cpp
diff --git a/indra/llplugin/llpluginprocesschild.h b/indra/llplugin/llpluginprocesschild.h
index a9d6794e40..a9d6794e40 100644..100755
--- a/indra/llplugin/llpluginprocesschild.h
+++ b/indra/llplugin/llpluginprocesschild.h
diff --git a/indra/llplugin/llpluginprocessparent.cpp b/indra/llplugin/llpluginprocessparent.cpp
index 110fac0f23..a4da7674d5 100644..100755
--- a/indra/llplugin/llpluginprocessparent.cpp
+++ b/indra/llplugin/llpluginprocessparent.cpp
@@ -31,6 +31,8 @@
#include "llpluginprocessparent.h"
#include "llpluginmessagepipe.h"
#include "llpluginmessageclasses.h"
+#include "llsdserialize.h"
+#include "stringize.h"
#include "llapr.h"
@@ -133,8 +135,8 @@ LLPluginProcessParent::~LLPluginProcessParent()
// and remove it from our map
mSharedMemoryRegions.erase(iter);
}
-
- mProcess.kill();
+
+ LLProcess::kill(mProcess);
killSockets();
}
@@ -159,8 +161,8 @@ void LLPluginProcessParent::errorState(void)
void LLPluginProcessParent::init(const std::string &launcher_filename, const std::string &plugin_dir, const std::string &plugin_filename, bool debug)
{
- mProcess.setExecutable(launcher_filename);
- mProcess.setWorkingDirectory(plugin_dir);
+ mProcessParams.executable = launcher_filename;
+ mProcessParams.cwd = plugin_dir;
mPluginFile = plugin_filename;
mPluginDir = plugin_dir;
mCPUUsage = 0.0f;
@@ -371,10 +373,8 @@ void LLPluginProcessParent::idle(void)
// Launch the plugin process.
// Only argument to the launcher is the port number we're listening on
- std::stringstream stream;
- stream << mBoundPort;
- mProcess.addArgument(stream.str());
- if(mProcess.launch() != 0)
+ mProcessParams.args.add(stringize(mBoundPort));
+ if (! (mProcess = LLProcess::create(mProcessParams)))
{
errorState();
}
@@ -388,19 +388,18 @@ void LLPluginProcessParent::idle(void)
// The command we're constructing would look like this on the command line:
// osascript -e 'tell application "Terminal"' -e 'set win to do script "gdb -pid 12345"' -e 'do script "continue" in win' -e 'end tell'
- std::stringstream cmd;
-
- mDebugger.setExecutable("/usr/bin/osascript");
- mDebugger.addArgument("-e");
- mDebugger.addArgument("tell application \"Terminal\"");
- mDebugger.addArgument("-e");
- cmd << "set win to do script \"gdb -pid " << mProcess.getProcessID() << "\"";
- mDebugger.addArgument(cmd.str());
- mDebugger.addArgument("-e");
- mDebugger.addArgument("do script \"continue\" in win");
- mDebugger.addArgument("-e");
- mDebugger.addArgument("end tell");
- mDebugger.launch();
+ LLProcess::Params params;
+ params.executable = "/usr/bin/osascript";
+ params.args.add("-e");
+ params.args.add("tell application \"Terminal\"");
+ params.args.add("-e");
+ params.args.add(STRINGIZE("set win to do script \"gdb -pid "
+ << mProcess->getProcessID() << "\""));
+ params.args.add("-e");
+ params.args.add("do script \"continue\" in win");
+ params.args.add("-e");
+ params.args.add("end tell");
+ mDebugger = LLProcess::create(params);
#endif
}
@@ -470,7 +469,7 @@ void LLPluginProcessParent::idle(void)
break;
case STATE_EXITING:
- if(!mProcess.isRunning())
+ if (! LLProcess::isRunning(mProcess))
{
setState(STATE_CLEANUP);
}
@@ -498,7 +497,7 @@ void LLPluginProcessParent::idle(void)
break;
case STATE_CLEANUP:
- mProcess.kill();
+ LLProcess::kill(mProcess);
killSockets();
setState(STATE_DONE);
break;
@@ -838,7 +837,7 @@ void LLPluginProcessParent::receiveMessageRaw(const std::string &message)
LL_DEBUGS("Plugin") << "Received: " << message << LL_ENDL;
LLPluginMessage parsed;
- if(parsed.parse(message) != -1)
+ if(LLSDParser::PARSE_FAILURE != parsed.parse(message))
{
if(parsed.hasValue("blocking_request"))
{
@@ -1077,7 +1076,7 @@ bool LLPluginProcessParent::pluginLockedUpOrQuit()
{
bool result = false;
- if(!mProcess.isRunning())
+ if (! LLProcess::isRunning(mProcess))
{
LL_WARNS("Plugin") << "child exited" << LL_ENDL;
result = true;
diff --git a/indra/llplugin/llpluginprocessparent.h b/indra/llplugin/llpluginprocessparent.h
index c66723f175..990fc5cbae 100644..100755
--- a/indra/llplugin/llpluginprocessparent.h
+++ b/indra/llplugin/llpluginprocessparent.h
@@ -30,13 +30,14 @@
#define LL_LLPLUGINPROCESSPARENT_H
#include "llapr.h"
-#include "llprocesslauncher.h"
+#include "llprocess.h"
#include "llpluginmessage.h"
#include "llpluginmessagepipe.h"
#include "llpluginsharedmemory.h"
#include "lliosocket.h"
#include "llthread.h"
+#include "llsd.h"
class LLPluginProcessParentOwner
{
@@ -139,26 +140,27 @@ private:
};
EState mState;
void setState(EState state);
-
+
bool pluginLockedUp();
bool pluginLockedUpOrQuit();
bool accept();
-
+
LLSocket::ptr_t mListenSocket;
LLSocket::ptr_t mSocket;
U32 mBoundPort;
-
- LLProcessLauncher mProcess;
-
+
+ LLProcess::Params mProcessParams;
+ LLProcessPtr mProcess;
+
std::string mPluginFile;
std::string mPluginDir;
LLPluginProcessParentOwner *mOwner;
-
+
typedef std::map<std::string, LLPluginSharedMemory*> sharedMemoryRegionsType;
sharedMemoryRegionsType mSharedMemoryRegions;
-
+
LLSD mMessageClassVersions;
std::string mPluginVersionString;
@@ -171,7 +173,7 @@ private:
bool mBlocked;
bool mPolledInput;
- LLProcessLauncher mDebugger;
+ LLProcessPtr mDebugger;
F32 mPluginLaunchTimeout; // Somewhat longer timeout for initial launch.
F32 mPluginLockupTimeout; // If we don't receive a heartbeat in this many seconds, we declare the plugin locked up.
diff --git a/indra/llplugin/llpluginsharedmemory.cpp b/indra/llplugin/llpluginsharedmemory.cpp
index 63ff5085c6..63ff5085c6 100644..100755
--- a/indra/llplugin/llpluginsharedmemory.cpp
+++ b/indra/llplugin/llpluginsharedmemory.cpp
diff --git a/indra/llplugin/llpluginsharedmemory.h b/indra/llplugin/llpluginsharedmemory.h
index c6cd49cabb..c6cd49cabb 100644..100755
--- a/indra/llplugin/llpluginsharedmemory.h
+++ b/indra/llplugin/llpluginsharedmemory.h
diff --git a/indra/llplugin/slplugin/CMakeLists.txt b/indra/llplugin/slplugin/CMakeLists.txt
index 3fc54573a7..6e7fefeb21 100644..100755
--- a/indra/llplugin/slplugin/CMakeLists.txt
+++ b/indra/llplugin/slplugin/CMakeLists.txt
@@ -12,10 +12,12 @@ include_directories(
${LLMESSAGE_INCLUDE_DIRS}
${LLCOMMON_INCLUDE_DIRS}
)
+include_directories(SYSTEM
+ ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+ )
if (DARWIN)
include(CMakeFindFrameworks)
- find_library(CARBON_LIBRARY Carbon)
find_library(COCOA_LIBRARY Cocoa)
endif (DARWIN)
@@ -48,10 +50,17 @@ add_executable(SLPlugin
${SLPlugin_SOURCE_FILES}
)
+if (WINDOWS)
+set_target_properties(SLPlugin
+ PROPERTIES
+ LINK_FLAGS_DEBUG "/NODEFAULTLIB:\"LIBCMTD\""
+ )
+else ()
set_target_properties(SLPlugin
PROPERTIES
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/slplugin_info.plist
)
+endif ()
target_link_libraries(SLPlugin
${LLPLUGIN_LIBRARIES}
@@ -68,7 +77,7 @@ add_dependencies(SLPlugin
if (DARWIN)
# Mac version needs to link against Carbon
- target_link_libraries(SLPlugin ${CARBON_LIBRARY} ${COCOA_LIBRARY})
+ target_link_libraries(SLPlugin ${COCOA_LIBRARY})
# Make sure the app bundle has a Resources directory (it will get populated by viewer-manifest.py later)
add_custom_command(
TARGET SLPlugin POST_BUILD
diff --git a/indra/llplugin/slplugin/slplugin-objc.h b/indra/llplugin/slplugin/slplugin-objc.h
index 602d848f7e..f2c2b3239c 100644..100755
--- a/indra/llplugin/slplugin/slplugin-objc.h
+++ b/indra/llplugin/slplugin/slplugin-objc.h
@@ -28,8 +28,26 @@
* @endcond
*/
+//Protos for ObjectiveC classes (cannot import cocoa here due to BOOL conflict)
+class NSWindow;
/* Defined in slplugin-objc.mm: */
-void setupCocoa();
-void createAutoReleasePool();
-void deleteAutoReleasePool();
+
+class LLCocoaPlugin
+{
+public:
+ LLCocoaPlugin();
+ void setupCocoa();
+ void createAutoReleasePool();
+ void deleteAutoReleasePool();
+ void setupGroup();
+ void updateWindows();
+ void processEvents();
+public:
+ //EventTargetRef mEventTarget;
+ NSWindow* mFrontWindow;
+ NSWindow* mPluginWindow;
+ int mHackState;
+};
+
+
diff --git a/indra/llplugin/slplugin/slplugin-objc.mm b/indra/llplugin/slplugin/slplugin-objc.mm
index 646416b9d2..a5ab1d95c8 100644..100755
--- a/indra/llplugin/slplugin/slplugin-objc.mm
+++ b/indra/llplugin/slplugin/slplugin-objc.mm
@@ -30,11 +30,13 @@
#include <AppKit/AppKit.h>
+#import <Cocoa/Cocoa.h>
#include "slplugin-objc.h"
+//Note: NSApp is a global defined by cocoa which is an id to the application.
-void setupCocoa()
+void LLCocoaPlugin::setupCocoa()
{
static bool inited = false;
@@ -56,6 +58,8 @@ void setupCocoa()
// Must first call [[[NSWindow alloc] init] release] to get the NSWindow machinery set up so that NSCursor can use a window to cache the cursor image
[[[NSWindow alloc] init] release];
+ mPluginWindow = [NSApp mainWindow];
+
deleteAutoReleasePool();
inited = true;
@@ -64,7 +68,7 @@ void setupCocoa()
static NSAutoreleasePool *sPool = NULL;
-void createAutoReleasePool()
+void LLCocoaPlugin::createAutoReleasePool()
{
if(!sPool)
{
@@ -72,7 +76,7 @@ void createAutoReleasePool()
}
}
-void deleteAutoReleasePool()
+void LLCocoaPlugin::deleteAutoReleasePool()
{
if(sPool)
{
@@ -80,3 +84,94 @@ void deleteAutoReleasePool()
sPool = NULL;
}
}
+
+LLCocoaPlugin::LLCocoaPlugin():mHackState(0)
+{
+ NSArray* window_list = [NSApp orderedWindows];
+ mFrontWindow = [window_list objectAtIndex:0];
+}
+
+void LLCocoaPlugin::processEvents()
+{
+ // Some plugins (webkit at least) will want an event loop. This qualifies.
+ NSEvent * event;
+ event = [NSApp nextEventMatchingMask:NSAnyEventMask untilDate:[NSDate distantPast] inMode:NSDefaultRunLoopMode dequeue:YES];
+ [NSApp sendEvent: event];
+}
+
+
+//Turns out the window ordering stuff never gets hit with any of the current plugins.
+//Leaving the following code here 'just in case' for the time being.
+
+void LLCocoaPlugin::setupGroup()
+{
+ // CreateWindowGroup(kWindowGroupAttrFixedLevel, &layer_group);
+ // if(layer_group)
+ // {
+ // // Start out with a window layer that's way out in front (fixes the problem with the menubar not getting hidden on first switch to fullscreen youtube)
+ // SetWindowGroupName(layer_group, CFSTR("SLPlugin Layer"));
+ // SetWindowGroupLevel(layer_group, kCGOverlayWindowLevel);
+ // }
+
+}
+
+void LLCocoaPlugin::updateWindows()
+{
+// NSArray* window_list = [NSApp orderedWindows];
+// NSWindow* current_window = [window_list objectAtIndex:0];
+// NSWindow* parent_window = [ current_window parentWindow ];
+// bool this_is_front_process = false;
+// bool parent_is_front_process = false;
+//
+//
+// // Check for a change in this process's frontmost window.
+// if ( current_window != mFrontWindow )
+// {
+// // and figure out whether this process or its parent are currently frontmost
+// if ( current_window == parent_window ) parent_is_front_process = true;
+// if ( current_window == mPluginWindow ) this_is_front_process = true;
+//
+// if (current_window != NULL && mFrontWindow == NULL)
+// {
+// // Opening the first window
+//
+// if(mHackState == 0)
+// {
+// // Next time through the event loop, lower the window group layer
+// mHackState = 1;
+// }
+//
+// if(parent_is_front_process)
+// {
+// // Bring this process's windows to the front.
+// [mPluginWindow makeKeyAndOrderFront:NSApp];
+// [mPluginWindow setOrderedIndex:0];
+// }
+//
+// [NSApp activateIgnoringOtherApps:YES];
+// }
+//
+// else if (( current_window == NULL) && (mFrontWindow != NULL))
+// {
+// // Closing the last window
+//
+// if(this_is_front_process)
+// {
+// // Try to bring this process's parent to the front
+// [parent_window makeKeyAndOrderFront:NSApp];
+// [parent_window setOrderedIndex:0];
+// }
+// }
+// else if(mHackState == 1)
+// {
+//// if(layer_group)
+//// {
+//// // Set the window group level back to something less extreme
+//// SetWindowGroupLevel(layer_group, kCGNormalWindowLevel);
+//// }
+// mHackState = 2;
+// }
+//
+// mFrontWindow = [window_list objectAtIndex:0];
+// }
+ }
diff --git a/indra/llplugin/slplugin/slplugin.cpp b/indra/llplugin/slplugin/slplugin.cpp
index 516a58db88..6c9ba0ae52 100644..100755
--- a/indra/llplugin/slplugin/slplugin.cpp
+++ b/indra/llplugin/slplugin/slplugin.cpp
@@ -37,8 +37,12 @@
#include "llapr.h"
#include "llstring.h"
+#include <iostream>
+#include <fstream>
+using namespace std;
+
+
#if LL_DARWIN
- #include <Carbon/Carbon.h>
#include "slplugin-objc.h"
#endif
@@ -176,6 +180,7 @@ int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdL
int main(int argc, char **argv)
#endif
{
+
ll_init_apr();
// Set up llerror logging
@@ -216,26 +221,25 @@ int main(int argc, char **argv)
// Catch signals that most kinds of crashes will generate, and exit cleanly so the system crash dialog isn't shown.
signal(SIGILL, &crash_handler); // illegal instruction
-# if LL_DARWIN
- signal(SIGEMT, &crash_handler); // emulate instruction executed
-# endif // LL_DARWIN
signal(SIGFPE, &crash_handler); // floating-point exception
signal(SIGBUS, &crash_handler); // bus error
signal(SIGSEGV, &crash_handler); // segmentation violation
signal(SIGSYS, &crash_handler); // non-existent system call invoked
#endif
+# if LL_DARWIN
+ signal(SIGEMT, &crash_handler); // emulate instruction executed
-#if LL_DARWIN
- setupCocoa();
- createAutoReleasePool();
-#endif
+ LLCocoaPlugin cocoa_interface;
+ cocoa_interface.setupCocoa();
+ cocoa_interface.createAutoReleasePool();
+#endif //LL_DARWIN
LLPluginProcessChild *plugin = new LLPluginProcessChild();
plugin->init(port);
#if LL_DARWIN
- deleteAutoReleasePool();
+ cocoa_interface.deleteAutoReleasePool();
#endif
LLTimer timer;
@@ -246,114 +250,22 @@ int main(int argc, char **argv)
#endif
#if LL_DARWIN
+
// If the plugin opens a new window (such as the Flash plugin's fullscreen player), we may need to bring this plugin process to the foreground.
// Use this to track the current frontmost window and bring this process to the front if it changes.
- WindowRef front_window = NULL;
- WindowGroupRef layer_group = NULL;
- int window_hack_state = 0;
- CreateWindowGroup(kWindowGroupAttrFixedLevel, &layer_group);
- if(layer_group)
- {
- // Start out with a window layer that's way out in front (fixes the problem with the menubar not getting hidden on first switch to fullscreen youtube)
- SetWindowGroupName(layer_group, CFSTR("SLPlugin Layer"));
- SetWindowGroupLevel(layer_group, kCGOverlayWindowLevel);
- }
-#endif
-
-#if LL_DARWIN
- EventTargetRef event_target = GetEventDispatcherTarget();
+ // cocoa_interface.mEventTarget = GetEventDispatcherTarget();
#endif
while(!plugin->isDone())
{
#if LL_DARWIN
- createAutoReleasePool();
+ cocoa_interface.createAutoReleasePool();
#endif
timer.reset();
plugin->idle();
#if LL_DARWIN
{
- // Some plugins (webkit at least) will want an event loop. This qualifies.
- EventRef event;
- if(ReceiveNextEvent(0, 0, kEventDurationNoWait, true, &event) == noErr)
- {
- SendEventToEventTarget (event, event_target);
- ReleaseEvent(event);
- }
-
- // Check for a change in this process's frontmost window.
- if(GetFrontWindowOfClass(kAllWindowClasses, true) != front_window)
- {
- ProcessSerialNumber self = { 0, kCurrentProcess };
- ProcessSerialNumber parent = { 0, kNoProcess };
- ProcessSerialNumber front = { 0, kNoProcess };
- Boolean this_is_front_process = false;
- Boolean parent_is_front_process = false;
- {
- // Get this process's parent
- ProcessInfoRec info;
- info.processInfoLength = sizeof(ProcessInfoRec);
- info.processName = NULL;
- info.processAppSpec = NULL;
- if(GetProcessInformation( &self, &info ) == noErr)
- {
- parent = info.processLauncher;
- }
-
- // and figure out whether this process or its parent are currently frontmost
- if(GetFrontProcess(&front) == noErr)
- {
- (void) SameProcess(&self, &front, &this_is_front_process);
- (void) SameProcess(&parent, &front, &parent_is_front_process);
- }
- }
-
- if((GetFrontWindowOfClass(kAllWindowClasses, true) != NULL) && (front_window == NULL))
- {
- // Opening the first window
-
- if(window_hack_state == 0)
- {
- // Next time through the event loop, lower the window group layer
- window_hack_state = 1;
- }
-
- if(layer_group)
- {
- SetWindowGroup(GetFrontWindowOfClass(kAllWindowClasses, true), layer_group);
- }
-
- if(parent_is_front_process)
- {
- // Bring this process's windows to the front.
- (void) SetFrontProcess( &self );
- }
-
- ActivateWindow(GetFrontWindowOfClass(kAllWindowClasses, true), true);
- }
- else if((GetFrontWindowOfClass(kAllWindowClasses, true) == NULL) && (front_window != NULL))
- {
- // Closing the last window
-
- if(this_is_front_process)
- {
- // Try to bring this process's parent to the front
- (void) SetFrontProcess(&parent);
- }
- }
- else if(window_hack_state == 1)
- {
- if(layer_group)
- {
- // Set the window group level back to something less extreme
- SetWindowGroupLevel(layer_group, kCGNormalWindowLevel);
- }
- window_hack_state = 2;
- }
-
- front_window = GetFrontWindowOfClass(kAllWindowClasses, true);
-
- }
- }
+ cocoa_interface.processEvents();
+ }
#endif
F64 elapsed = timer.getElapsedTimeF64();
F64 remaining = plugin->getSleepTime() - elapsed;
@@ -377,7 +289,8 @@ int main(int argc, char **argv)
// LL_INFOS("slplugin") << "slept for "<< timer.getElapsedTimeF64() * 1000.0f << " ms" << LL_ENDL;
}
-
+
+
#if LL_WINDOWS
// More agressive checking of interfering exception handlers.
// Doesn't appear to be required so far - even for plugins
@@ -387,14 +300,14 @@ int main(int argc, char **argv)
#endif
#if LL_DARWIN
- deleteAutoReleasePool();
+ cocoa_interface.deleteAutoReleasePool();
#endif
}
-
delete plugin;
ll_cleanup_apr();
+
return 0;
}
diff --git a/indra/llplugin/slplugin/slplugin_info.plist b/indra/llplugin/slplugin/slplugin_info.plist
index c4597380e0..c4597380e0 100644..100755
--- a/indra/llplugin/slplugin/slplugin_info.plist
+++ b/indra/llplugin/slplugin/slplugin_info.plist
diff --git a/indra/llplugin/tests/llplugincookiestore_test.cpp b/indra/llplugin/tests/llplugincookiestore_test.cpp
index aefa1ca144..aefa1ca144 100644..100755
--- a/indra/llplugin/tests/llplugincookiestore_test.cpp
+++ b/indra/llplugin/tests/llplugincookiestore_test.cpp
diff --git a/indra/llprimitive/CMakeLists.txt b/indra/llprimitive/CMakeLists.txt
index 7d0e313ff3..0dd13916bf 100644..100755
--- a/indra/llprimitive/CMakeLists.txt
+++ b/indra/llprimitive/CMakeLists.txt
@@ -7,6 +7,7 @@ include(LLCommon)
include(LLMath)
include(LLMessage)
include(LLXML)
+include(LLPhysicsExtensions)
include_directories(
${LLCOMMON_INCLUDE_DIRS}
@@ -16,8 +17,15 @@ include_directories(
${LIBS_PREBUILT_DIR}/include/collada
${LIBS_PREBUILT_DIR}/include/collada/1.4
)
+include_directories(SYSTEM
+ ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+ ${LLXML_SYSTEM_INCLUDE_DIRS}
+ ${LLPHYSICSEXTENSIONS_INCLUDE_DIRS}
+ )
set(llprimitive_SOURCE_FILES
+ llmaterialid.cpp
+ llmaterial.cpp
llmaterialtable.cpp
llmediaentry.cpp
llmodel.cpp
@@ -35,6 +43,8 @@ set(llprimitive_HEADER_FILES
CMakeLists.txt
legacy_object_types.h
+ llmaterial.h
+ llmaterialid.h
llmaterialtable.h
llmediaentry.h
llmodel.h
@@ -57,6 +67,15 @@ list(APPEND llprimitive_SOURCE_FILES ${llprimitive_HEADER_FILES})
add_library (llprimitive ${llprimitive_SOURCE_FILES})
+target_link_libraries(llprimitive
+ ${LLCOMMON_LIBRARIES}
+ ${LLMATH_LIBRARIES}
+ ${LLMESSAGE_LIBRARIES}
+ ${LLXML_LIBRARIES}
+ ${LLPHYSICSEXTENSIONS_LIBRARIES}
+ )
+
+
#add unit tests
if (LL_TESTS)
INCLUDE(LLAddBuildTest)
diff --git a/indra/llprimitive/legacy_object_types.h b/indra/llprimitive/legacy_object_types.h
index 697ad584a5..697ad584a5 100644..100755
--- a/indra/llprimitive/legacy_object_types.h
+++ b/indra/llprimitive/legacy_object_types.h
diff --git a/indra/llprimitive/llmaterial.cpp b/indra/llprimitive/llmaterial.cpp
new file mode 100644
index 0000000000..cf4c645cfd
--- /dev/null
+++ b/indra/llprimitive/llmaterial.cpp
@@ -0,0 +1,227 @@
+/**
+ * @file llmaterial.cpp
+ * @brief Material definition
+ *
+ * $LicenseInfo:firstyear=2006&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 "llmaterial.h"
+
+/**
+ * Materials cap parameters
+ */
+#define MATERIALS_CAP_NORMAL_MAP_FIELD "NormMap"
+#define MATERIALS_CAP_NORMAL_MAP_OFFSET_X_FIELD "NormOffsetX"
+#define MATERIALS_CAP_NORMAL_MAP_OFFSET_Y_FIELD "NormOffsetY"
+#define MATERIALS_CAP_NORMAL_MAP_REPEAT_X_FIELD "NormRepeatX"
+#define MATERIALS_CAP_NORMAL_MAP_REPEAT_Y_FIELD "NormRepeatY"
+#define MATERIALS_CAP_NORMAL_MAP_ROTATION_FIELD "NormRotation"
+
+#define MATERIALS_CAP_SPECULAR_MAP_FIELD "SpecMap"
+#define MATERIALS_CAP_SPECULAR_MAP_OFFSET_X_FIELD "SpecOffsetX"
+#define MATERIALS_CAP_SPECULAR_MAP_OFFSET_Y_FIELD "SpecOffsetY"
+#define MATERIALS_CAP_SPECULAR_MAP_REPEAT_X_FIELD "SpecRepeatX"
+#define MATERIALS_CAP_SPECULAR_MAP_REPEAT_Y_FIELD "SpecRepeatY"
+#define MATERIALS_CAP_SPECULAR_MAP_ROTATION_FIELD "SpecRotation"
+
+#define MATERIALS_CAP_SPECULAR_COLOR_FIELD "SpecColor"
+#define MATERIALS_CAP_SPECULAR_EXP_FIELD "SpecExp"
+#define MATERIALS_CAP_ENV_INTENSITY_FIELD "EnvIntensity"
+#define MATERIALS_CAP_ALPHA_MASK_CUTOFF_FIELD "AlphaMaskCutoff"
+#define MATERIALS_CAP_DIFFUSE_ALPHA_MODE_FIELD "DiffuseAlphaMode"
+
+const LLColor4U LLMaterial::DEFAULT_SPECULAR_LIGHT_COLOR(255,255,255,255);
+
+/**
+ * Materials constants
+ */
+
+const F32 MATERIALS_MULTIPLIER = 10000.f;
+
+/**
+ * Helper functions
+ */
+
+template<typename T> T getMaterialField(const LLSD& data, const std::string& field, const LLSD::Type field_type)
+{
+ if ( (data.has(field)) && (field_type == data[field].type()) )
+ {
+ return (T)data[field];
+ }
+ llerrs << "Missing or mistyped field '" << field << "' in material definition" << llendl;
+ return (T)LLSD();
+}
+
+// GCC didn't like the generic form above for some reason
+template<> LLUUID getMaterialField(const LLSD& data, const std::string& field, const LLSD::Type field_type)
+{
+ if ( (data.has(field)) && (field_type == data[field].type()) )
+ {
+ return data[field].asUUID();
+ }
+ llerrs << "Missing or mistyped field '" << field << "' in material definition" << llendl;
+ return LLUUID::null;
+}
+
+/**
+ * LLMaterial class
+ */
+
+const LLMaterial LLMaterial::null;
+
+LLMaterial::LLMaterial()
+ : mNormalOffsetX(0.0f)
+ , mNormalOffsetY(0.0f)
+ , mNormalRepeatX(1.0f)
+ , mNormalRepeatY(1.0f)
+ , mNormalRotation(0.0f)
+ , mSpecularOffsetX(0.0f)
+ , mSpecularOffsetY(0.0f)
+ , mSpecularRepeatX(1.0f)
+ , mSpecularRepeatY(1.0f)
+ , mSpecularRotation(0.0f)
+ , mSpecularLightColor(LLMaterial::DEFAULT_SPECULAR_LIGHT_COLOR)
+ , mSpecularLightExponent(LLMaterial::DEFAULT_SPECULAR_LIGHT_EXPONENT)
+ , mEnvironmentIntensity(LLMaterial::DEFAULT_ENV_INTENSITY)
+ , mDiffuseAlphaMode(LLMaterial::DIFFUSE_ALPHA_MODE_BLEND)
+ , mAlphaMaskCutoff(0)
+{
+}
+
+LLMaterial::LLMaterial(const LLSD& material_data)
+{
+ fromLLSD(material_data);
+}
+
+LLSD LLMaterial::asLLSD() const
+{
+ LLSD material_data;
+
+ material_data[MATERIALS_CAP_NORMAL_MAP_FIELD] = mNormalID;
+ material_data[MATERIALS_CAP_NORMAL_MAP_OFFSET_X_FIELD] = llround(mNormalOffsetX * MATERIALS_MULTIPLIER);
+ material_data[MATERIALS_CAP_NORMAL_MAP_OFFSET_Y_FIELD] = llround(mNormalOffsetY * MATERIALS_MULTIPLIER);
+ material_data[MATERIALS_CAP_NORMAL_MAP_REPEAT_X_FIELD] = llround(mNormalRepeatX * MATERIALS_MULTIPLIER);
+ material_data[MATERIALS_CAP_NORMAL_MAP_REPEAT_Y_FIELD] = llround(mNormalRepeatY * MATERIALS_MULTIPLIER);
+ material_data[MATERIALS_CAP_NORMAL_MAP_ROTATION_FIELD] = llround(mNormalRotation * MATERIALS_MULTIPLIER);
+
+ material_data[MATERIALS_CAP_SPECULAR_MAP_FIELD] = mSpecularID;
+ material_data[MATERIALS_CAP_SPECULAR_MAP_OFFSET_X_FIELD] = llround(mSpecularOffsetX * MATERIALS_MULTIPLIER);
+ material_data[MATERIALS_CAP_SPECULAR_MAP_OFFSET_Y_FIELD] = llround(mSpecularOffsetY * MATERIALS_MULTIPLIER);
+ material_data[MATERIALS_CAP_SPECULAR_MAP_REPEAT_X_FIELD] = llround(mSpecularRepeatX * MATERIALS_MULTIPLIER);
+ material_data[MATERIALS_CAP_SPECULAR_MAP_REPEAT_Y_FIELD] = llround(mSpecularRepeatY * MATERIALS_MULTIPLIER);
+ material_data[MATERIALS_CAP_SPECULAR_MAP_ROTATION_FIELD] = llround(mSpecularRotation * MATERIALS_MULTIPLIER);
+
+ material_data[MATERIALS_CAP_SPECULAR_COLOR_FIELD] = mSpecularLightColor.getValue();
+ material_data[MATERIALS_CAP_SPECULAR_EXP_FIELD] = mSpecularLightExponent;
+ material_data[MATERIALS_CAP_ENV_INTENSITY_FIELD] = mEnvironmentIntensity;
+ material_data[MATERIALS_CAP_DIFFUSE_ALPHA_MODE_FIELD] = mDiffuseAlphaMode;
+ material_data[MATERIALS_CAP_ALPHA_MASK_CUTOFF_FIELD] = mAlphaMaskCutoff;
+
+ return material_data;
+}
+
+void LLMaterial::fromLLSD(const LLSD& material_data)
+{
+ mNormalID = getMaterialField<LLSD::UUID>(material_data, MATERIALS_CAP_NORMAL_MAP_FIELD, LLSD::TypeUUID);
+ mNormalOffsetX = (F32)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_NORMAL_MAP_OFFSET_X_FIELD, LLSD::TypeInteger) / MATERIALS_MULTIPLIER;
+ mNormalOffsetY = (F32)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_NORMAL_MAP_OFFSET_Y_FIELD, LLSD::TypeInteger) / MATERIALS_MULTIPLIER;
+ mNormalRepeatX = (F32)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_NORMAL_MAP_REPEAT_X_FIELD, LLSD::TypeInteger) / MATERIALS_MULTIPLIER;
+ mNormalRepeatY = (F32)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_NORMAL_MAP_REPEAT_Y_FIELD, LLSD::TypeInteger) / MATERIALS_MULTIPLIER;
+ mNormalRotation = (F32)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_NORMAL_MAP_ROTATION_FIELD, LLSD::TypeInteger) / MATERIALS_MULTIPLIER;
+
+ mSpecularID = getMaterialField<LLSD::UUID>(material_data, MATERIALS_CAP_SPECULAR_MAP_FIELD, LLSD::TypeUUID);
+ mSpecularOffsetX = (F32)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_SPECULAR_MAP_OFFSET_X_FIELD, LLSD::TypeInteger) / MATERIALS_MULTIPLIER;
+ mSpecularOffsetY = (F32)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_SPECULAR_MAP_OFFSET_Y_FIELD, LLSD::TypeInteger) / MATERIALS_MULTIPLIER;
+ mSpecularRepeatX = (F32)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_SPECULAR_MAP_REPEAT_X_FIELD, LLSD::TypeInteger) / MATERIALS_MULTIPLIER;
+ mSpecularRepeatY = (F32)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_SPECULAR_MAP_REPEAT_Y_FIELD, LLSD::TypeInteger) / MATERIALS_MULTIPLIER;
+ mSpecularRotation = (F32)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_SPECULAR_MAP_ROTATION_FIELD, LLSD::TypeInteger) / MATERIALS_MULTIPLIER;
+
+ mSpecularLightColor.setValue(getMaterialField<LLSD>(material_data, MATERIALS_CAP_SPECULAR_COLOR_FIELD, LLSD::TypeArray));
+ mSpecularLightExponent = (U8)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_SPECULAR_EXP_FIELD, LLSD::TypeInteger);
+ mEnvironmentIntensity = (U8)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_ENV_INTENSITY_FIELD, LLSD::TypeInteger);
+ mDiffuseAlphaMode = (U8)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_DIFFUSE_ALPHA_MODE_FIELD, LLSD::TypeInteger);
+ mAlphaMaskCutoff = (U8)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_ALPHA_MASK_CUTOFF_FIELD, LLSD::TypeInteger);
+}
+
+bool LLMaterial::isNull() const
+{
+ return (*this == null);
+}
+
+bool LLMaterial::operator == (const LLMaterial& rhs) const
+{
+ return
+ (mNormalID == rhs.mNormalID) && (mNormalOffsetX == rhs.mNormalOffsetX) && (mNormalOffsetY == rhs.mNormalOffsetY) &&
+ (mNormalRepeatX == rhs.mNormalRepeatX) && (mNormalRepeatY == rhs.mNormalRepeatY) && (mNormalRotation == rhs.mNormalRotation) &&
+ (mSpecularID == rhs.mSpecularID) && (mSpecularOffsetX == rhs.mSpecularOffsetX) && (mSpecularOffsetY == rhs.mSpecularOffsetY) &&
+ (mSpecularRepeatX == rhs.mSpecularRepeatX) && (mSpecularRepeatY == rhs.mSpecularRepeatY) && (mSpecularRotation == rhs.mSpecularRotation) &&
+ (mSpecularLightColor == rhs.mSpecularLightColor) && (mSpecularLightExponent == rhs.mSpecularLightExponent) &&
+ (mEnvironmentIntensity == rhs.mEnvironmentIntensity) && (mDiffuseAlphaMode == rhs.mDiffuseAlphaMode) && (mAlphaMaskCutoff == rhs.mAlphaMaskCutoff);
+}
+
+bool LLMaterial::operator != (const LLMaterial& rhs) const
+{
+ return !(*this == rhs);
+}
+
+
+U32 LLMaterial::getShaderMask(U32 alpha_mode)
+{ //NEVER incorporate this value into the message system -- this function will vary depending on viewer implementation
+ U32 ret = 0;
+
+ //two least significant bits are "diffuse alpha mode"
+ if (alpha_mode != DIFFUSE_ALPHA_MODE_DEFAULT)
+ {
+ ret = alpha_mode;
+ }
+ else
+ {
+ ret = getDiffuseAlphaMode();
+ }
+
+ llassert(ret < SHADER_COUNT);
+
+ //next bit is whether or not specular map is present
+ const U32 SPEC_BIT = 0x4;
+
+ if (getSpecularID().notNull())
+ {
+ ret |= SPEC_BIT;
+ }
+
+ llassert(ret < SHADER_COUNT);
+
+ //next bit is whether or not normal map is present
+ const U32 NORM_BIT = 0x8;
+ if (getNormalID().notNull())
+ {
+ ret |= NORM_BIT;
+ }
+
+ llassert(ret < SHADER_COUNT);
+
+ return ret;
+}
+
+
diff --git a/indra/llprimitive/llmaterial.h b/indra/llprimitive/llmaterial.h
new file mode 100644
index 0000000000..9f52a3f6c1
--- /dev/null
+++ b/indra/llprimitive/llmaterial.h
@@ -0,0 +1,155 @@
+/**
+ * @file llmaterial.h
+ * @brief Material definition
+ *
+ * $LicenseInfo:firstyear=2006&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$
+ */
+
+#ifndef LL_LLMATERIAL_H
+#define LL_LLMATERIAL_H
+
+#include <boost/shared_ptr.hpp>
+
+#include "llmaterialid.h"
+#include "llsd.h"
+#include "v4coloru.h"
+#include "llpointer.h"
+#include "llrefcount.h"
+
+class LLMaterial : public LLRefCount
+{
+public:
+
+ typedef enum
+ {
+ DIFFUSE_ALPHA_MODE_NONE = 0,
+ DIFFUSE_ALPHA_MODE_BLEND = 1,
+ DIFFUSE_ALPHA_MODE_MASK = 2,
+ DIFFUSE_ALPHA_MODE_EMISSIVE = 3,
+ DIFFUSE_ALPHA_MODE_DEFAULT = 4,
+ } eDiffuseAlphaMode;
+
+ typedef enum
+ {
+ SHADER_COUNT = 16,
+ ALPHA_SHADER_COUNT = 4
+ } eShaderCount;
+
+
+
+ static const U8 DEFAULT_SPECULAR_LIGHT_EXPONENT = ((U8)(0.2f * 255));
+ static const LLColor4U DEFAULT_SPECULAR_LIGHT_COLOR;
+ static const U8 DEFAULT_ENV_INTENSITY = 0;
+
+ LLMaterial();
+ LLMaterial(const LLSD& material_data);
+
+ LLSD asLLSD() const;
+ void fromLLSD(const LLSD& material_data);
+
+ const LLUUID& getNormalID() const { return mNormalID; }
+ void setNormalID(const LLUUID& normal_id) { mNormalID = normal_id; }
+ void getNormalOffset(F32& offset_x, F32& offset_y) const { offset_x = mNormalOffsetX; offset_y = mNormalOffsetY; }
+ F32 getNormalOffsetX() const { return mNormalOffsetX; }
+ F32 getNormalOffsetY() const { return mNormalOffsetY; }
+
+ void setNormalOffset(F32 offset_x, F32 offset_y) { mNormalOffsetX = offset_x; mNormalOffsetY = offset_y; }
+ void setNormalOffsetX(F32 offset_x) { mNormalOffsetX = offset_x; }
+ void setNormalOffsetY(F32 offset_y) { mNormalOffsetY = offset_y; }
+
+ void getNormalRepeat(F32& repeat_x, F32& repeat_y) const { repeat_x = mNormalRepeatX; repeat_y = mNormalRepeatY; }
+ F32 getNormalRepeatX() const { return mNormalRepeatX; }
+ F32 getNormalRepeatY() const { return mNormalRepeatY; }
+
+ void setNormalRepeat(F32 repeat_x, F32 repeat_y) { mNormalRepeatX = repeat_x; mNormalRepeatY = repeat_y; }
+ void setNormalRepeatX(F32 repeat_x) { mNormalRepeatX = repeat_x; }
+ void setNormalRepeatY(F32 repeat_y) { mNormalRepeatY = repeat_y; }
+
+ F32 getNormalRotation() const { return mNormalRotation; }
+ void setNormalRotation(F32 rot) { mNormalRotation = rot; }
+
+ const LLUUID& getSpecularID() const { return mSpecularID; }
+ void setSpecularID(const LLUUID& specular_id) { mSpecularID = specular_id; }
+ void getSpecularOffset(F32& offset_x, F32& offset_y) const { offset_x = mSpecularOffsetX; offset_y = mSpecularOffsetY; }
+ F32 getSpecularOffsetX() const { return mSpecularOffsetX; }
+ F32 getSpecularOffsetY() const { return mSpecularOffsetY; }
+
+ void setSpecularOffset(F32 offset_x, F32 offset_y) { mSpecularOffsetX = offset_x; mSpecularOffsetY = offset_y; }
+ void setSpecularOffsetX(F32 offset_x) { mSpecularOffsetX = offset_x; }
+ void setSpecularOffsetY(F32 offset_y) { mSpecularOffsetY = offset_y; }
+
+ void getSpecularRepeat(F32& repeat_x, F32& repeat_y) const { repeat_x = mSpecularRepeatX; repeat_y = mSpecularRepeatY; }
+ F32 getSpecularRepeatX() const { return mSpecularRepeatX; }
+ F32 getSpecularRepeatY() const { return mSpecularRepeatY; }
+
+ void setSpecularRepeat(F32 repeat_x, F32 repeat_y) { mSpecularRepeatX = repeat_x; mSpecularRepeatY = repeat_y; }
+ void setSpecularRepeatX(F32 repeat_x) { mSpecularRepeatX = repeat_x; }
+ void setSpecularRepeatY(F32 repeat_y) { mSpecularRepeatY = repeat_y; }
+
+ F32 getSpecularRotation() const { return mSpecularRotation; }
+ void setSpecularRotation(F32 rot) { mSpecularRotation = rot; }
+
+ const LLColor4U getSpecularLightColor() const { return mSpecularLightColor; }
+ void setSpecularLightColor(const LLColor4U& color) { mSpecularLightColor = color; }
+ U8 getSpecularLightExponent() const { return mSpecularLightExponent; }
+ void setSpecularLightExponent(U8 exponent) { mSpecularLightExponent = exponent; }
+ U8 getEnvironmentIntensity() const { return mEnvironmentIntensity; }
+ void setEnvironmentIntensity(U8 intensity) { mEnvironmentIntensity = intensity; }
+ U8 getDiffuseAlphaMode() const { return mDiffuseAlphaMode; }
+ void setDiffuseAlphaMode(U8 alpha_mode) { mDiffuseAlphaMode = alpha_mode; }
+ U8 getAlphaMaskCutoff() const { return mAlphaMaskCutoff; }
+ void setAlphaMaskCutoff(U8 cutoff) { mAlphaMaskCutoff = cutoff; }
+
+ bool isNull() const;
+ static const LLMaterial null;
+
+ bool operator == (const LLMaterial& rhs) const;
+ bool operator != (const LLMaterial& rhs) const;
+
+ U32 getShaderMask(U32 alpha_mode = DIFFUSE_ALPHA_MODE_DEFAULT);
+
+protected:
+ LLUUID mNormalID;
+ F32 mNormalOffsetX;
+ F32 mNormalOffsetY;
+ F32 mNormalRepeatX;
+ F32 mNormalRepeatY;
+ F32 mNormalRotation;
+
+ LLUUID mSpecularID;
+ F32 mSpecularOffsetX;
+ F32 mSpecularOffsetY;
+ F32 mSpecularRepeatX;
+ F32 mSpecularRepeatY;
+ F32 mSpecularRotation;
+
+ LLColor4U mSpecularLightColor;
+ U8 mSpecularLightExponent;
+ U8 mEnvironmentIntensity;
+ U8 mDiffuseAlphaMode;
+ U8 mAlphaMaskCutoff;
+};
+
+typedef LLPointer<LLMaterial> LLMaterialPtr;
+
+#endif // LL_LLMATERIAL_H
+
diff --git a/indra/llprimitive/llmaterialid.cpp b/indra/llprimitive/llmaterialid.cpp
new file mode 100644
index 0000000000..820f62c43c
--- /dev/null
+++ b/indra/llprimitive/llmaterialid.cpp
@@ -0,0 +1,183 @@
+/**
+* @file llmaterialid.cpp
+* @brief Implementation of llmaterialid
+* @author Stinson@lindenlab.com
+*
+* $LicenseInfo:firstyear=2012&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2012, 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 "llmaterialid.h"
+
+#include <string>
+
+#include "llformat.h"
+
+const LLMaterialID LLMaterialID::null;
+
+LLMaterialID::LLMaterialID()
+{
+ clear();
+}
+
+LLMaterialID::LLMaterialID(const LLSD& pMaterialID)
+{
+ llassert(pMaterialID.isBinary());
+ parseFromBinary(pMaterialID.asBinary());
+}
+
+LLMaterialID::LLMaterialID(const LLSD::Binary& pMaterialID)
+{
+ parseFromBinary(pMaterialID);
+}
+
+LLMaterialID::LLMaterialID(const void* pMemory)
+{
+ set(pMemory);
+}
+
+LLMaterialID::LLMaterialID(const LLMaterialID& pOtherMaterialID)
+{
+ copyFromOtherMaterialID(pOtherMaterialID);
+}
+
+LLMaterialID::~LLMaterialID()
+{
+}
+
+bool LLMaterialID::operator == (const LLMaterialID& pOtherMaterialID) const
+{
+ return (compareToOtherMaterialID(pOtherMaterialID) == 0);
+}
+
+bool LLMaterialID::operator != (const LLMaterialID& pOtherMaterialID) const
+{
+ return (compareToOtherMaterialID(pOtherMaterialID) != 0);
+}
+
+bool LLMaterialID::operator < (const LLMaterialID& pOtherMaterialID) const
+{
+ return (compareToOtherMaterialID(pOtherMaterialID) < 0);
+}
+
+bool LLMaterialID::operator <= (const LLMaterialID& pOtherMaterialID) const
+{
+ return (compareToOtherMaterialID(pOtherMaterialID) <= 0);
+}
+
+bool LLMaterialID::operator > (const LLMaterialID& pOtherMaterialID) const
+{
+ return (compareToOtherMaterialID(pOtherMaterialID) > 0);
+}
+
+bool LLMaterialID::operator >= (const LLMaterialID& pOtherMaterialID) const
+{
+ return (compareToOtherMaterialID(pOtherMaterialID) >= 0);
+}
+
+LLMaterialID& LLMaterialID::operator = (const LLMaterialID& pOtherMaterialID)
+{
+ copyFromOtherMaterialID(pOtherMaterialID);
+ return (*this);
+}
+
+bool LLMaterialID::isNull() const
+{
+ return (compareToOtherMaterialID(LLMaterialID::null) == 0);
+}
+
+const U8* LLMaterialID::get() const
+{
+ return mID;
+}
+
+void LLMaterialID::set(const void* pMemory)
+{
+ llassert(pMemory != NULL);
+
+ // assumes that the required size of memory is available
+ memcpy(mID, pMemory, MATERIAL_ID_SIZE * sizeof(U8));
+}
+
+void LLMaterialID::clear()
+{
+ memset(mID, 0, MATERIAL_ID_SIZE * sizeof(U8));
+}
+
+LLSD LLMaterialID::asLLSD() const
+{
+ LLSD::Binary materialIDBinary;
+
+ materialIDBinary.resize(MATERIAL_ID_SIZE * sizeof(U8));
+ memcpy(materialIDBinary.data(), mID, MATERIAL_ID_SIZE * sizeof(U8));
+
+ LLSD materialID = materialIDBinary;
+ return materialID;
+}
+
+std::string LLMaterialID::asString() const
+{
+ std::string materialIDString;
+ for (unsigned int i = 0U; i < static_cast<unsigned int>(MATERIAL_ID_SIZE / sizeof(U32)); ++i)
+ {
+ if (i != 0U)
+ {
+ materialIDString += "-";
+ }
+ const U32 *value = reinterpret_cast<const U32*>(&get()[i * sizeof(U32)]);
+ materialIDString += llformat("%08x", *value);
+ }
+ return materialIDString;
+}
+
+std::ostream& operator<<(std::ostream& s, const LLMaterialID &material_id)
+{
+ s << material_id.asString();
+ return s;
+}
+
+
+void LLMaterialID::parseFromBinary (const LLSD::Binary& pMaterialID)
+{
+ llassert(pMaterialID.size() == (MATERIAL_ID_SIZE * sizeof(U8)));
+ memcpy(mID, &pMaterialID[0], MATERIAL_ID_SIZE * sizeof(U8));
+}
+
+void LLMaterialID::copyFromOtherMaterialID(const LLMaterialID& pOtherMaterialID)
+{
+ memcpy(mID, pOtherMaterialID.get(), MATERIAL_ID_SIZE * sizeof(U8));
+}
+
+int LLMaterialID::compareToOtherMaterialID(const LLMaterialID& pOtherMaterialID) const
+{
+ int retVal = 0;
+
+ for (unsigned int i = 0U; (retVal == 0) && (i < static_cast<unsigned int>(MATERIAL_ID_SIZE / sizeof(U32))); ++i)
+ {
+ const U32 *thisValue = reinterpret_cast<const U32*>(&get()[i * sizeof(U32)]);
+ const U32 *otherValue = reinterpret_cast<const U32*>(&pOtherMaterialID.get()[i * sizeof(U32)]);
+ retVal = ((*thisValue < *otherValue) ? -1 : ((*thisValue > *otherValue) ? 1 : 0));
+ }
+
+ return retVal;
+}
diff --git a/indra/llprimitive/llmaterialid.h b/indra/llprimitive/llmaterialid.h
new file mode 100644
index 0000000000..0a95204085
--- /dev/null
+++ b/indra/llprimitive/llmaterialid.h
@@ -0,0 +1,76 @@
+/**
+* @file llmaterialid.h
+* @brief Header file for llmaterialid
+* @author Stinson@lindenlab.com
+*
+* $LicenseInfo:firstyear=2012&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2012, 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_LLMATERIALID_H
+#define LL_LLMATERIALID_H
+
+#define MATERIAL_ID_SIZE 16
+
+#include <string>
+
+class LLMaterialID
+{
+public:
+ LLMaterialID();
+ LLMaterialID(const LLSD& pMaterialID);
+ LLMaterialID(const LLSD::Binary& pMaterialID);
+ LLMaterialID(const void* pMemory);
+ LLMaterialID(const LLMaterialID& pOtherMaterialID);
+ ~LLMaterialID();
+
+ bool operator == (const LLMaterialID& pOtherMaterialID) const;
+ bool operator != (const LLMaterialID& pOtherMaterialID) const;
+
+ bool operator < (const LLMaterialID& pOtherMaterialID) const;
+ bool operator <= (const LLMaterialID& pOtherMaterialID) const;
+ bool operator > (const LLMaterialID& pOtherMaterialID) const;
+ bool operator >= (const LLMaterialID& pOtherMaterialID) const;
+
+ LLMaterialID& operator = (const LLMaterialID& pOtherMaterialID);
+
+ bool isNull() const;
+
+ const U8* get() const;
+ void set(const void* pMemory);
+ void clear();
+
+ LLSD asLLSD() const;
+ std::string asString() const;
+
+ friend std::ostream& operator<<(std::ostream& s, const LLMaterialID &material_id);
+
+ static const LLMaterialID null;
+
+private:
+ void parseFromBinary(const LLSD::Binary& pMaterialID);
+ void copyFromOtherMaterialID(const LLMaterialID& pOtherMaterialID);
+ int compareToOtherMaterialID(const LLMaterialID& pOtherMaterialID) const;
+
+ U8 mID[MATERIAL_ID_SIZE];
+} ;
+
+#endif // LL_LLMATERIALID_H
+
diff --git a/indra/llprimitive/llmaterialtable.cpp b/indra/llprimitive/llmaterialtable.cpp
index b4539ebee9..b4539ebee9 100644..100755
--- a/indra/llprimitive/llmaterialtable.cpp
+++ b/indra/llprimitive/llmaterialtable.cpp
diff --git a/indra/llprimitive/llmaterialtable.h b/indra/llprimitive/llmaterialtable.h
index a17e0103ff..a17e0103ff 100644..100755
--- a/indra/llprimitive/llmaterialtable.h
+++ b/indra/llprimitive/llmaterialtable.h
diff --git a/indra/llprimitive/llmediaentry.cpp b/indra/llprimitive/llmediaentry.cpp
index 02aba2bd83..02aba2bd83 100644..100755
--- a/indra/llprimitive/llmediaentry.cpp
+++ b/indra/llprimitive/llmediaentry.cpp
diff --git a/indra/llprimitive/llmediaentry.h b/indra/llprimitive/llmediaentry.h
index 33855b3fb2..33855b3fb2 100644..100755
--- a/indra/llprimitive/llmediaentry.h
+++ b/indra/llprimitive/llmediaentry.h
diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp
index cb32a510b8..34e0483a83 100644..100755
--- a/indra/llprimitive/llmodel.cpp
+++ b/indra/llprimitive/llmodel.cpp
@@ -166,6 +166,7 @@ LLModel::EModelStatus load_face_from_dom_triangles(std::vector<LLVolumeFace>& fa
if ( !get_dom_sources(inputs, pos_offset, tc_offset, norm_offset, idx_stride, pos_source, tc_source, norm_source) || !pos_source )
{
+ llwarns << "Could not find dom sources for basic geo data; invalid model." << llendl;
return LLModel::BAD_ELEMENT;
}
@@ -186,27 +187,78 @@ LLModel::EModelStatus load_face_from_dom_triangles(std::vector<LLVolumeFace>& fa
LLVolumeFace::VertexMapData::PointMap point_map;
- for (U32 i = 0; i < idx.getCount(); i += idx_stride)
+ U32 index_count = idx.getCount();
+ U32 vertex_count = pos_source ? v.getCount() : 0;
+ U32 tc_count = tc_source ? tc.getCount() : 0;
+ U32 norm_count = norm_source ? n.getCount() : 0;
+
+ for (U32 i = 0; i < index_count; i += idx_stride)
{
LLVolumeFace::VertexData cv;
if (pos_source)
{
+ // guard against model data specifiying out of range indices or verts
+ //
+ if (((i + pos_offset) > index_count)
+ || ((idx[i+pos_offset]*3+2) > vertex_count))
+ {
+ llwarns << "Out of range index data; invalid model." << llendl;
+ return LLModel::BAD_ELEMENT;
+ }
+
cv.setPosition(LLVector4a(v[idx[i+pos_offset]*3+0],
v[idx[i+pos_offset]*3+1],
v[idx[i+pos_offset]*3+2]));
+
+ if (!cv.getPosition().isFinite3())
+ {
+ llwarns << "Nan positional data, invalid model." << llendl;
+ return LLModel::BAD_ELEMENT;
+ }
}
if (tc_source)
{
+ // guard against model data specifiying out of range indices or tcs
+ //
+
+ if (((i + tc_offset) > index_count)
+ || ((idx[i+tc_offset]*2+1) > tc_count))
+ {
+ llwarns << "Out of range TC indices." << llendl;
+ return LLModel::BAD_ELEMENT;
+ }
+
cv.mTexCoord.setVec(tc[idx[i+tc_offset]*2+0],
tc[idx[i+tc_offset]*2+1]);
+
+ if (!cv.mTexCoord.isFinite())
+ {
+ llwarns << "Found NaN while loading tex coords from DAE-Model, invalid model." << llendl;
+ return LLModel::BAD_ELEMENT;
+ }
}
if (norm_source)
{
+ // guard against model data specifiying out of range indices or norms
+ //
+ if (((i + norm_offset) > index_count)
+ || ((idx[i+norm_offset]*3+2) > norm_count))
+ {
+ llwarns << "Found out of range norm indices, invalid model." << llendl;
+ return LLModel::BAD_ELEMENT;
+ }
+
cv.setNormal(LLVector4a(n[idx[i+norm_offset]*3+0],
n[idx[i+norm_offset]*3+1],
n[idx[i+norm_offset]*3+2]));
+
+ if (!cv.getNormal().isFinite3())
+ {
+ llwarns << "Found NaN while loading normals from DAE-Model, invalid model." << llendl;
+ return LLModel::BAD_ELEMENT;
+ }
}
BOOL found = FALSE;
@@ -261,13 +313,13 @@ LLModel::EModelStatus load_face_from_dom_triangles(std::vector<LLVolumeFace>& fa
LLVolumeFace& new_face = *face_list.rbegin();
if (!norm_source)
{
- ll_aligned_free_16(new_face.mNormals);
+ //ll_aligned_free_16(new_face.mNormals);
new_face.mNormals = NULL;
}
if (!tc_source)
{
- ll_aligned_free_16(new_face.mTexCoords);
+ //ll_aligned_free_16(new_face.mTexCoords);
new_face.mTexCoords = NULL;
}
@@ -292,13 +344,13 @@ LLModel::EModelStatus load_face_from_dom_triangles(std::vector<LLVolumeFace>& fa
LLVolumeFace& new_face = *face_list.rbegin();
if (!norm_source)
{
- ll_aligned_free_16(new_face.mNormals);
+ //ll_aligned_free_16(new_face.mNormals);
new_face.mNormals = NULL;
}
if (!tc_source)
{
- ll_aligned_free_16(new_face.mTexCoords);
+ //ll_aligned_free_16(new_face.mTexCoords);
new_face.mTexCoords = NULL;
}
}
@@ -333,6 +385,7 @@ LLModel::EModelStatus load_face_from_dom_polylist(std::vector<LLVolumeFace>& fac
if (!get_dom_sources(inputs, pos_offset, tc_offset, norm_offset, idx_stride, pos_source, tc_source, norm_source))
{
+ llwarns << "Could not get DOM sources for basic geo data, invalid model." << llendl;
return LLModel::BAD_ELEMENT;
}
@@ -364,6 +417,11 @@ LLModel::EModelStatus load_face_from_dom_polylist(std::vector<LLVolumeFace>& fac
LLVolumeFace::VertexMapData::PointMap point_map;
+ U32 index_count = idx.getCount();
+ U32 vertex_count = pos_source ? v.getCount() : 0;
+ U32 tc_count = tc_source ? tc.getCount() : 0;
+ U32 norm_count = norm_source ? n.getCount() : 0;
+
U32 cur_idx = 0;
for (U32 i = 0; i < vcount.getCount(); ++i)
{ //for each polygon
@@ -376,22 +434,68 @@ LLModel::EModelStatus load_face_from_dom_polylist(std::vector<LLVolumeFace>& fac
if (pos_source)
{
+ // guard against model data specifiying out of range indices or verts
+ //
+ if (((cur_idx + pos_offset) > index_count)
+ || ((idx[cur_idx+pos_offset]*3+2) > vertex_count))
+ {
+ llwarns << "Out of range position indices, invalid model." << llendl;
+ return LLModel::BAD_ELEMENT;
+ }
+
cv.getPosition().set(v[idx[cur_idx+pos_offset]*3+0],
v[idx[cur_idx+pos_offset]*3+1],
v[idx[cur_idx+pos_offset]*3+2]);
+
+ if (!cv.getPosition().isFinite3())
+ {
+ llwarns << "Found NaN while loading positions from DAE-Model, invalid model." << llendl;
+ return LLModel::BAD_ELEMENT;
+ }
+
}
if (tc_source)
{
+ // guard against model data specifiying out of range indices or tcs
+ //
+ if (((cur_idx + tc_offset) > index_count)
+ || ((idx[cur_idx+tc_offset]*2+1) > tc_count))
+ {
+ llwarns << "Out of range TC indices, invalid model." << llendl;
+ return LLModel::BAD_ELEMENT;
+ }
+
cv.mTexCoord.setVec(tc[idx[cur_idx+tc_offset]*2+0],
tc[idx[cur_idx+tc_offset]*2+1]);
+
+ if (!cv.mTexCoord.isFinite())
+ {
+ llwarns << "Found NaN while loading tex coords from DAE-Model, invalid model." << llendl;
+ return LLModel::BAD_ELEMENT;
+ }
}
if (norm_source)
{
+ // guard against model data specifiying out of range indices or norms
+ //
+ if (((cur_idx + norm_offset) > index_count)
+ || ((idx[cur_idx+norm_offset]*3+2) > norm_count))
+ {
+ llwarns << "Out of range norm indices, invalid model." << llendl;
+ return LLModel::BAD_ELEMENT;
+ }
+
cv.getNormal().set(n[idx[cur_idx+norm_offset]*3+0],
n[idx[cur_idx+norm_offset]*3+1],
n[idx[cur_idx+norm_offset]*3+2]);
+
+ if (!cv.getNormal().isFinite3())
+ {
+ llwarns << "Found NaN while loading normals from DAE-Model, invalid model." << llendl;
+ return LLModel::BAD_ELEMENT;
+ }
}
cur_idx += idx_stride;
@@ -480,13 +584,13 @@ LLModel::EModelStatus load_face_from_dom_polylist(std::vector<LLVolumeFace>& fac
LLVolumeFace& new_face = *face_list.rbegin();
if (!norm_source)
{
- ll_aligned_free_16(new_face.mNormals);
+ //ll_aligned_free_16(new_face.mNormals);
new_face.mNormals = NULL;
}
if (!tc_source)
{
- ll_aligned_free_16(new_face.mTexCoords);
+ //ll_aligned_free_16(new_face.mTexCoords);
new_face.mTexCoords = NULL;
}
@@ -514,13 +618,13 @@ LLModel::EModelStatus load_face_from_dom_polylist(std::vector<LLVolumeFace>& fac
LLVolumeFace& new_face = *face_list.rbegin();
if (!norm_source)
{
- ll_aligned_free_16(new_face.mNormals);
+ //ll_aligned_free_16(new_face.mNormals);
new_face.mNormals = NULL;
}
if (!tc_source)
{
- ll_aligned_free_16(new_face.mTexCoords);
+ //ll_aligned_free_16(new_face.mTexCoords);
new_face.mTexCoords = NULL;
}
}
@@ -558,6 +662,7 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector<LLVolumeFace>& fac
domVertices* vertices = (domVertices*) elem.cast();
if (!vertices)
{
+ llwarns << "Could not find vertex source, invalid model." << llendl;
return LLModel::BAD_ELEMENT;
}
domInputLocal_Array& v_inp = vertices->getInput_array();
@@ -571,6 +676,7 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector<LLVolumeFace>& fac
domSource* src = (domSource*) elem.cast();
if (!src)
{
+ llwarns << "Could not find DOM source, invalid model." << llendl;
return LLModel::BAD_ELEMENT;
}
v = &(src->getFloat_array()->getValue());
@@ -586,6 +692,7 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector<LLVolumeFace>& fac
domSource* src = (domSource*) elem.cast();
if (!src)
{
+ llwarns << "Could not find DOM source, invalid model." << llendl;
return LLModel::BAD_ELEMENT;
}
n = &(src->getFloat_array()->getValue());
@@ -598,6 +705,7 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector<LLVolumeFace>& fac
domSource* src = (domSource*) elem.cast();
if (!src)
{
+ llwarns << "Could not find DOM source, invalid model." << llendl;
return LLModel::BAD_ELEMENT;
}
t = &(src->getFloat_array()->getValue());
@@ -628,25 +736,59 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector<LLVolumeFace>& fac
if (v)
{
U32 v_idx = idx[j*stride+v_offset]*3;
+ v_idx = llclamp(v_idx, (U32) 0, (U32) v->getCount());
vert.getPosition().set(v->get(v_idx),
v->get(v_idx+1),
v->get(v_idx+2));
+
+ if (!vert.getPosition().isFinite3())
+ {
+ llwarns << "Found NaN while loading position data from DAE-Model, invalid model." << llendl;
+ return LLModel::BAD_ELEMENT;
+ }
}
- if (n)
+ //bounds check n and t lookups because some FBX to DAE converters
+ //use negative indices and empty arrays to indicate data does not exist
+ //for a particular channel
+ if (n && n->getCount() > 0)
{
U32 n_idx = idx[j*stride+n_offset]*3;
+ n_idx = llclamp(n_idx, (U32) 0, (U32) n->getCount());
vert.getNormal().set(n->get(n_idx),
n->get(n_idx+1),
n->get(n_idx+2));
+
+ if (!vert.getNormal().isFinite3())
+ {
+ llwarns << "Found NaN while loading normals from DAE-Model, invalid model." << llendl;
+ return LLModel::BAD_ELEMENT;
+ }
+ }
+ else
+ {
+ vert.getNormal().clear();
}
+
- if (t)
+ if (t && t->getCount() > 0)
{
U32 t_idx = idx[j*stride+t_offset]*2;
+ t_idx = llclamp(t_idx, (U32) 0, (U32) t->getCount());
vert.mTexCoord.setVec(t->get(t_idx),
t->get(t_idx+1));
+
+ if (!vert.mTexCoord.isFinite())
+ {
+ llwarns << "Found NaN while loading tex coords from DAE-Model, invalid model." << llendl;
+ return LLModel::BAD_ELEMENT;
+ }
}
+ else
+ {
+ vert.mTexCoord.clear();
+ }
+
verts.push_back(vert);
}
@@ -714,13 +856,13 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector<LLVolumeFace>& fac
LLVolumeFace& new_face = *face_list.rbegin();
if (!n)
{
- ll_aligned_free_16(new_face.mNormals);
+ //ll_aligned_free_16(new_face.mNormals);
new_face.mNormals = NULL;
}
if (!t)
{
- ll_aligned_free_16(new_face.mTexCoords);
+ //ll_aligned_free_16(new_face.mTexCoords);
new_face.mTexCoords = NULL;
}
}
@@ -994,6 +1136,43 @@ void LLModel::getNormalizedScaleTranslation(LLVector3& scale_out, LLVector3& tra
translation_out = mNormalizedTranslation;
}
+LLVector3 LLModel::getTransformedCenter(const LLMatrix4& mat)
+{
+ LLVector3 ret;
+
+ if (!mVolumeFaces.empty())
+ {
+ LLMatrix4a m;
+ m.loadu(mat);
+
+ LLVector4a minv,maxv;
+
+ LLVector4a t;
+ m.affineTransform(mVolumeFaces[0].mPositions[0], t);
+ minv = maxv = t;
+
+ for (S32 i = 0; i < mVolumeFaces.size(); ++i)
+ {
+ LLVolumeFace& face = mVolumeFaces[i];
+
+ for (U32 j = 0; j < face.mNumVertices; ++j)
+ {
+ m.affineTransform(face.mPositions[j],t);
+ update_min_max(minv, maxv, t);
+ }
+ }
+
+ minv.add(maxv);
+ minv.mul(0.5f);
+
+ ret.set(minv.getF32ptr());
+ }
+
+ return ret;
+}
+
+
+
void LLModel::setNumVolumeFaces(S32 count)
{
mVolumeFaces.resize(count);
@@ -1020,17 +1199,18 @@ void LLModel::setVolumeFaceData(
}
else
{
- ll_aligned_free_16(face.mNormals);
+ //ll_aligned_free_16(face.mNormals);
face.mNormals = NULL;
}
if (tc.get())
{
- LLVector4a::memcpyNonAliased16((F32*) face.mTexCoords, (F32*) tc.get(), num_verts*2*sizeof(F32));
+ U32 tex_size = (num_verts*2*sizeof(F32)+0xF)&~0xF;
+ LLVector4a::memcpyNonAliased16((F32*) face.mTexCoords, (F32*) tc.get(), tex_size);
}
else
{
- ll_aligned_free_16(face.mTexCoords);
+ //ll_aligned_free_16(face.mTexCoords);
face.mTexCoords = NULL;
}
@@ -1229,7 +1409,7 @@ void LLModel::generateNormals(F32 angle_cutoff)
}
else
{
- ll_aligned_free_16(new_face.mTexCoords);
+ //ll_aligned_free_16(new_face.mTexCoords);
new_face.mTexCoords = NULL;
}
diff --git a/indra/llprimitive/llmodel.h b/indra/llprimitive/llmodel.h
index 1cf528fd9f..aaafc55258 100644..100755
--- a/indra/llprimitive/llmodel.h
+++ b/indra/llprimitive/llmodel.h
@@ -173,13 +173,15 @@ public:
void optimizeVolumeFaces();
void offsetMesh( const LLVector3& pivotPoint );
void getNormalizedScaleTranslation(LLVector3& scale_out, LLVector3& translation_out);
-
+ LLVector3 getTransformedCenter(const LLMatrix4& mat);
+
//reorder face list based on mMaterialList in this and reference so
//order matches that of reference (material ordering touchup)
bool matchMaterialOrder(LLModel* ref, int& refFaceCnt, int& modelFaceCnt );
bool isMaterialListSubset( LLModel* ref );
bool needToAddFaces( LLModel* ref, int& refFaceCnt, int& modelFaceCnt );
+
std::vector<std::string> mMaterialList;
//data used for skin weights
diff --git a/indra/llprimitive/llprimitive.cpp b/indra/llprimitive/llprimitive.cpp
index 30532247ac..2fa77177f5 100644..100755
--- a/indra/llprimitive/llprimitive.cpp
+++ b/indra/llprimitive/llprimitive.cpp
@@ -27,7 +27,6 @@
#include "linden_common.h"
#include "material_codes.h"
-#include "llmemtype.h"
#include "llerror.h"
#include "message.h"
#include "llprimitive.h"
@@ -39,6 +38,8 @@
#include "lldatapacker.h"
#include "llsdutil_math.h"
#include "llprimtexturelist.h"
+#include "imageids.h"
+#include "llmaterialid.h"
/**
* exported constants
@@ -149,7 +150,8 @@ bool LLPrimitive::cleanupVolumeManager()
LLPrimitive::LLPrimitive()
: mTextureList(),
mNumTEs(0),
- mMiscFlags(0)
+ mMiscFlags(0),
+ mNumBumpmapTEs(0)
{
mPrimitiveCode = 0;
@@ -188,7 +190,6 @@ void LLPrimitive::clearTextureList()
// static
LLPrimitive *LLPrimitive::createPrimitive(LLPCode p_code)
{
- LLMemType m1(LLMemType::MTYPE_PRIMITIVE);
LLPrimitive *retval = new LLPrimitive();
if (retval)
@@ -206,7 +207,6 @@ LLPrimitive *LLPrimitive::createPrimitive(LLPCode p_code)
//===============================================================
void LLPrimitive::init_primitive(LLPCode p_code)
{
- LLMemType m1(LLMemType::MTYPE_PRIMITIVE);
clearTextureList();
mPrimitiveCode = p_code;
}
@@ -237,7 +237,10 @@ void LLPrimitive::setAllTETextures(const LLUUID &tex_id)
//===============================================================
void LLPrimitive::setTE(const U8 index, const LLTextureEntry& te)
{
- mTextureList.copyTexture(index, te);
+ if(mTextureList.copyTexture(index, te) != TEM_CHANGE_NONE && te.getBumpmap() > 0)
+ {
+ mNumBumpmapTEs++;
+ }
}
S32 LLPrimitive::setTETexture(const U8 index, const LLUUID &id)
@@ -312,10 +315,20 @@ S32 LLPrimitive::setTERotation(const U8 index, const F32 r)
return mTextureList.setRotation(index, r);
}
+S32 LLPrimitive::setTEMaterialID(const U8 index, const LLMaterialID& pMaterialID)
+{
+ return mTextureList.setMaterialID(index, pMaterialID);
+}
+
+S32 LLPrimitive::setTEMaterialParams(const U8 index, const LLMaterialPtr pMaterialParams)
+{
+ return mTextureList.setMaterialParams(index, pMaterialParams);
+}
//===============================================================
S32 LLPrimitive::setTEBumpShinyFullbright(const U8 index, const U8 bump)
{
+ updateNumBumpmap(index, bump);
return mTextureList.setBumpShinyFullbright(index, bump);
}
@@ -326,11 +339,13 @@ S32 LLPrimitive::setTEMediaTexGen(const U8 index, const U8 media)
S32 LLPrimitive::setTEBumpmap(const U8 index, const U8 bump)
{
+ updateNumBumpmap(index, bump);
return mTextureList.setBumpMap(index, bump);
}
S32 LLPrimitive::setTEBumpShiny(const U8 index, const U8 bump_shiny)
{
+ updateNumBumpmap(index, bump_shiny);
return mTextureList.setBumpShiny(index, bump_shiny);
}
@@ -359,6 +374,23 @@ S32 LLPrimitive::setTEGlow(const U8 index, const F32 glow)
return mTextureList.setGlow(index, glow);
}
+void LLPrimitive::setAllTESelected(bool sel)
+{
+ for (int i = 0, cnt = getNumTEs(); i < cnt; i++)
+ {
+ setTESelected(i, sel);
+ }
+}
+
+void LLPrimitive::setTESelected(const U8 te, bool sel)
+{
+ LLTextureEntry* tep = getTE(te);
+ if ( (tep) && (tep->setSelected(sel)) && (!sel) && (tep->hasPendingMaterialUpdate()) )
+ {
+ LLMaterialID material_id = tep->getMaterialID();
+ setTEMaterialID(te, material_id);
+ }
+}
LLPCode LLPrimitive::legacyToPCode(const U8 legacy)
{
@@ -698,7 +730,6 @@ S32 face_index_from_id(LLFaceID face_ID, const std::vector<LLProfile::Face>& fac
BOOL LLPrimitive::setVolume(const LLVolumeParams &volume_params, const S32 detail, bool unique_volume)
{
- LLMemType m1(LLMemType::MTYPE_VOLUME);
LLVolume *volumep;
if (unique_volume)
{
@@ -1040,7 +1071,7 @@ S32 LLPrimitive::unpackTEField(U8 *cur_ptr, U8 *buffer_end, U8 *data_ptr, U8 dat
while ((cur_ptr < buffer_end) && (*cur_ptr != 0))
{
-// llinfos << "TE exception" << llendl;
+ LL_DEBUGS("TEFieldDecode") << "TE exception" << LL_ENDL;
i = 0;
while (*cur_ptr & 0x80)
{
@@ -1055,14 +1086,16 @@ S32 LLPrimitive::unpackTEField(U8 *cur_ptr, U8 *buffer_end, U8 *data_ptr, U8 dat
if (i & 0x01)
{
htonmemcpy(data_ptr+(j*data_size),cur_ptr,type,data_size);
-// char foo[64];
-// sprintf(foo,"%x %x",*(data_ptr+(j*data_size)), *(data_ptr+(j*data_size)+1));
-// llinfos << "Assigning " << foo << " to face " << j << llendl;
+ LL_DEBUGS("TEFieldDecode") << "Assigning " ;
+ char foo[64];
+ sprintf(foo,"%x %x",*(data_ptr+(j*data_size)), *(data_ptr+(j*data_size)+1));
+ LL_CONT << foo << " to face " << j << LL_ENDL;
}
i = i >> 1;
}
cur_ptr += data_size;
}
+ llassert(cur_ptr <= buffer_end); // buffer underrun
return (S32)(cur_ptr - start_loc);
}
@@ -1084,6 +1117,7 @@ BOOL LLPrimitive::packTEMessage(LLMessageSystem *mesgsys) const
U8 bump[MAX_TES];
U8 media_flags[MAX_TES];
U8 glow[MAX_TES];
+ U8 material_data[MAX_TES*16];
const U32 MAX_TE_BUFFER = 4096;
U8 packed_buffer[MAX_TE_BUFFER];
@@ -1121,6 +1155,9 @@ BOOL LLPrimitive::packTEMessage(LLMessageSystem *mesgsys) const
bump[face_index] = te->getBumpShinyFullbright();
media_flags[face_index] = te->getMediaTexGen();
glow[face_index] = (U8) llround((llclamp(te->getGlow(), 0.0f, 1.0f) * (F32)0xFF));
+
+ // Directly sending material_ids is not safe!
+ memcpy(&material_data[face_index*16],getTE(face_index)->getMaterialID().get(),16); /* Flawfinder: ignore */
}
cur_ptr += packTEField(cur_ptr, (U8 *)image_ids, sizeof(LLUUID),last_face_index, MVT_LLUUID);
@@ -1142,6 +1179,8 @@ BOOL LLPrimitive::packTEMessage(LLMessageSystem *mesgsys) const
cur_ptr += packTEField(cur_ptr, (U8 *)media_flags, 1 ,last_face_index, MVT_U8);
*cur_ptr++ = 0;
cur_ptr += packTEField(cur_ptr, (U8 *)glow, 1 ,last_face_index, MVT_U8);
+ *cur_ptr++ = 0;
+ cur_ptr += packTEField(cur_ptr, (U8 *)material_data, 16, last_face_index, MVT_LLUUID);
}
mesgsys->addBinaryDataFast(_PREHASH_TextureEntry, packed_buffer, (S32)(cur_ptr - packed_buffer));
@@ -1163,6 +1202,7 @@ BOOL LLPrimitive::packTEMessage(LLDataPacker &dp) const
U8 bump[MAX_TES];
U8 media_flags[MAX_TES];
U8 glow[MAX_TES];
+ U8 material_data[MAX_TES*16];
const U32 MAX_TE_BUFFER = 4096;
U8 packed_buffer[MAX_TE_BUFFER];
@@ -1200,6 +1240,9 @@ BOOL LLPrimitive::packTEMessage(LLDataPacker &dp) const
bump[face_index] = te->getBumpShinyFullbright();
media_flags[face_index] = te->getMediaTexGen();
glow[face_index] = (U8) llround((llclamp(te->getGlow(), 0.0f, 1.0f) * (F32)0xFF));
+
+ // Directly sending material_ids is not safe!
+ memcpy(&material_data[face_index*16],getTE(face_index)->getMaterialID().get(),16); /* Flawfinder: ignore */
}
cur_ptr += packTEField(cur_ptr, (U8 *)image_ids, sizeof(LLUUID),last_face_index, MVT_LLUUID);
@@ -1221,100 +1264,107 @@ BOOL LLPrimitive::packTEMessage(LLDataPacker &dp) const
cur_ptr += packTEField(cur_ptr, (U8 *)media_flags, 1 ,last_face_index, MVT_U8);
*cur_ptr++ = 0;
cur_ptr += packTEField(cur_ptr, (U8 *)glow, 1 ,last_face_index, MVT_U8);
+ *cur_ptr++ = 0;
+ cur_ptr += packTEField(cur_ptr, (U8 *)material_data, 16, last_face_index, MVT_LLUUID);
}
dp.packBinaryData(packed_buffer, (S32)(cur_ptr - packed_buffer), "TextureEntry");
return FALSE;
}
-S32 LLPrimitive::unpackTEMessage(LLMessageSystem* mesgsys, char const* block_name)
-{
- return(unpackTEMessage(mesgsys,block_name,-1));
-}
-
-S32 LLPrimitive::unpackTEMessage(LLMessageSystem* mesgsys, char const* block_name, const S32 block_num)
+S32 LLPrimitive::parseTEMessage(LLMessageSystem* mesgsys, char const* block_name, const S32 block_num, LLTEContents& tec)
{
- // use a negative block_num to indicate a single-block read (a non-variable block)
S32 retval = 0;
- const U32 MAX_TES = 32;
-
- // Avoid construction of 32 UUIDs per call. JC
-
- U8 image_data[MAX_TES*16];
- U8 colors[MAX_TES*4];
- F32 scale_s[MAX_TES];
- F32 scale_t[MAX_TES];
- S16 offset_s[MAX_TES];
- S16 offset_t[MAX_TES];
- S16 image_rot[MAX_TES];
- U8 bump[MAX_TES];
- U8 media_flags[MAX_TES];
- U8 glow[MAX_TES];
-
- const U32 MAX_TE_BUFFER = 4096;
- U8 packed_buffer[MAX_TE_BUFFER];
- U8 *cur_ptr = packed_buffer;
-
- U32 size;
- U32 face_count = 0;
+ // temp buffer for material ID processing
+ // data will end up in tec.material_id[]
+ U8 material_data[LLTEContents::MAX_TES*16];
if (block_num < 0)
{
- size = mesgsys->getSizeFast(block_name, _PREHASH_TextureEntry);
+ tec.size = mesgsys->getSizeFast(block_name, _PREHASH_TextureEntry);
}
else
{
- size = mesgsys->getSizeFast(block_name, block_num, _PREHASH_TextureEntry);
+ tec.size = mesgsys->getSizeFast(block_name, block_num, _PREHASH_TextureEntry);
}
- if (size == 0)
+ if (tec.size == 0)
{
+ tec.face_count = 0;
return retval;
}
if (block_num < 0)
{
- mesgsys->getBinaryDataFast(block_name, _PREHASH_TextureEntry, packed_buffer, 0, 0, MAX_TE_BUFFER);
+ mesgsys->getBinaryDataFast(block_name, _PREHASH_TextureEntry, tec.packed_buffer, 0, 0, LLTEContents::MAX_TE_BUFFER);
}
else
{
- mesgsys->getBinaryDataFast(block_name, _PREHASH_TextureEntry, packed_buffer, 0, block_num, MAX_TE_BUFFER);
+ mesgsys->getBinaryDataFast(block_name, _PREHASH_TextureEntry, tec.packed_buffer, 0, block_num, LLTEContents::MAX_TE_BUFFER);
}
- face_count = getNumTEs();
+ tec.face_count = llmin((U32)getNumTEs(),(U32)LLTEContents::MAX_TES);
- cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)image_data, 16, face_count, MVT_LLUUID);
+ U8 *cur_ptr = tec.packed_buffer;
+ cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.image_data, 16, tec.face_count, MVT_LLUUID);
cur_ptr++;
- cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)colors, 4, face_count, MVT_U8);
+ cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.colors, 4, tec.face_count, MVT_U8);
cur_ptr++;
- cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)scale_s, 4, face_count, MVT_F32);
+ cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.scale_s, 4, tec.face_count, MVT_F32);
cur_ptr++;
- cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)scale_t, 4, face_count, MVT_F32);
+ cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.scale_t, 4, tec.face_count, MVT_F32);
cur_ptr++;
- cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)offset_s, 2, face_count, MVT_S16Array);
+ cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.offset_s, 2, tec.face_count, MVT_S16Array);
cur_ptr++;
- cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)offset_t, 2, face_count, MVT_S16Array);
+ cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.offset_t, 2, tec.face_count, MVT_S16Array);
cur_ptr++;
- cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)image_rot, 2, face_count, MVT_S16Array);
+ cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.image_rot, 2, tec.face_count, MVT_S16Array);
cur_ptr++;
- cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)bump, 1, face_count, MVT_U8);
+ cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.bump, 1, tec.face_count, MVT_U8);
cur_ptr++;
- cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)media_flags, 1, face_count, MVT_U8);
+ cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.media_flags, 1, tec.face_count, MVT_U8);
cur_ptr++;
- cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)glow, 1, face_count, MVT_U8);
+ cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.glow, 1, tec.face_count, MVT_U8);
+
+ if (cur_ptr < tec.packed_buffer + tec.size)
+ {
+ cur_ptr++;
+ cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)material_data, 16, tec.face_count, MVT_LLUUID);
+ }
+ else
+ {
+ memset(material_data, 0, sizeof(material_data));
+ }
+
+ for (U32 i = 0; i < tec.face_count; i++)
+ {
+ tec.material_ids[i].set(&material_data[i * 16]);
+ }
+
+ retval = 1;
+ return retval;
+ }
+
+S32 LLPrimitive::applyParsedTEMessage(LLTEContents& tec)
+{
+ S32 retval = 0;
LLColor4 color;
LLColor4U coloru;
- for (U32 i = 0; i < face_count; i++)
- {
- retval |= setTETexture(i, ((LLUUID*)image_data)[i]);
- retval |= setTEScale(i, scale_s[i], scale_t[i]);
- retval |= setTEOffset(i, (F32)offset_s[i] / (F32)0x7FFF, (F32) offset_t[i] / (F32) 0x7FFF);
- retval |= setTERotation(i, ((F32)image_rot[i] / TEXTURE_ROTATION_PACK_FACTOR) * F_TWO_PI);
- retval |= setTEBumpShinyFullbright(i, bump[i]);
- retval |= setTEMediaTexGen(i, media_flags[i]);
- retval |= setTEGlow(i, (F32)glow[i] / (F32)0xFF);
- coloru = LLColor4U(colors + 4*i);
+ for (U32 i = 0; i < tec.face_count; i++)
+ {
+ LLUUID& req_id = ((LLUUID*)tec.image_data)[i];
+ retval |= setTETexture(i, req_id);
+ retval |= setTEScale(i, tec.scale_s[i], tec.scale_t[i]);
+ retval |= setTEOffset(i, (F32)tec.offset_s[i] / (F32)0x7FFF, (F32) tec.offset_t[i] / (F32) 0x7FFF);
+ retval |= setTERotation(i, ((F32)tec.image_rot[i] / TEXTURE_ROTATION_PACK_FACTOR) * F_TWO_PI);
+ retval |= setTEBumpShinyFullbright(i, tec.bump[i]);
+ retval |= setTEMediaTexGen(i, tec.media_flags[i]);
+ retval |= setTEGlow(i, (F32)tec.glow[i] / (F32)0xFF);
+
+ retval |= setTEMaterialID(i, tec.material_ids[i]);
+
+ coloru = LLColor4U(tec.colors + 4*i);
// Note: This is an optimization to send common colors (1.f, 1.f, 1.f, 1.f)
// as all zeros. However, the subtraction and addition must be done in unsigned
@@ -1331,6 +1381,15 @@ S32 LLPrimitive::unpackTEMessage(LLMessageSystem* mesgsys, char const* block_nam
return retval;
}
+S32 LLPrimitive::unpackTEMessage(LLMessageSystem* mesgsys, char const* block_name, const S32 block_num)
+{
+ LLTEContents tec;
+ S32 retval = parseTEMessage(mesgsys, block_name, block_num, tec);
+ if (!retval)
+ return retval;
+ return applyParsedTEMessage(tec);
+}
+
S32 LLPrimitive::unpackTEMessage(LLDataPacker &dp)
{
// use a negative block_num to indicate a single-block read (a non-variable block)
@@ -1339,6 +1398,7 @@ S32 LLPrimitive::unpackTEMessage(LLDataPacker &dp)
// Avoid construction of 32 UUIDs per call
static LLUUID image_ids[MAX_TES];
+ static LLMaterialID material_ids[MAX_TES];
U8 image_data[MAX_TES*16];
U8 colors[MAX_TES*4];
@@ -1350,6 +1410,7 @@ S32 LLPrimitive::unpackTEMessage(LLDataPacker &dp)
U8 bump[MAX_TES];
U8 media_flags[MAX_TES];
U8 glow[MAX_TES];
+ U8 material_data[MAX_TES*16];
const U32 MAX_TE_BUFFER = 4096;
U8 packed_buffer[MAX_TE_BUFFER];
@@ -1392,10 +1453,20 @@ S32 LLPrimitive::unpackTEMessage(LLDataPacker &dp)
cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)media_flags, 1, face_count, MVT_U8);
cur_ptr++;
cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)glow, 1, face_count, MVT_U8);
+ if (cur_ptr < packed_buffer + size)
+ {
+ cur_ptr++;
+ cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)material_data, 16, face_count, MVT_LLUUID);
+ }
+ else
+ {
+ memset(material_data, 0, sizeof(material_data));
+ }
for (i = 0; i < face_count; i++)
{
memcpy(image_ids[i].mData,&image_data[i*16],16); /* Flawfinder: ignore */
+ material_ids[i].set(&material_data[i * 16]);
}
LLColor4 color;
@@ -1409,6 +1480,7 @@ S32 LLPrimitive::unpackTEMessage(LLDataPacker &dp)
retval |= setTEBumpShinyFullbright(i, bump[i]);
retval |= setTEMediaTexGen(i, media_flags[i]);
retval |= setTEGlow(i, (F32)glow[i] / (F32)0xFF);
+ retval |= setTEMaterialID(i, material_ids[i]);
coloru = LLColor4U(colors + 4*i);
// Note: This is an optimization to send common colors (1.f, 1.f, 1.f, 1.f)
@@ -1445,6 +1517,26 @@ void LLPrimitive::takeTextureList(LLPrimTextureList& other_list)
mTextureList.take(other_list);
}
+void LLPrimitive::updateNumBumpmap(const U8 index, const U8 bump)
+{
+ LLTextureEntry* te = getTE(index);
+ if(!te)
+ {
+ return;
+ }
+
+ U8 old_bump = te->getBumpmap();
+ if(old_bump > 0)
+ {
+ mNumBumpmapTEs--;
+ }
+ if((bump & TEM_BUMP_MASK) > 0)
+ {
+ mNumBumpmapTEs++;
+ }
+
+ return;
+}
//============================================================================
// Moved from llselectmgr.cpp
diff --git a/indra/llprimitive/llprimitive.h b/indra/llprimitive/llprimitive.h
index 998016f8f6..47a21beaaf 100644..100755
--- a/indra/llprimitive/llprimitive.h
+++ b/indra/llprimitive/llprimitive.h
@@ -42,6 +42,7 @@ class LLMessageSystem;
class LLVolumeParams;
class LLColor4;
class LLColor3;
+class LLMaterialID;
class LLTextureEntry;
class LLDataPacker;
class LLVolumeMgr;
@@ -289,6 +290,35 @@ public:
};
+// This code is not naming-standards compliant. Leaving it like this for
+// now to make the connection to code in
+// BOOL packTEMessage(LLDataPacker &dp) const;
+// more obvious. This should be refactored to remove the duplication, at which
+// point we can fix the names as well.
+// - Vir
+struct LLTEContents
+{
+ static const U32 MAX_TES = 32;
+
+ U8 image_data[MAX_TES*16];
+ U8 colors[MAX_TES*4];
+ F32 scale_s[MAX_TES];
+ F32 scale_t[MAX_TES];
+ S16 offset_s[MAX_TES];
+ S16 offset_t[MAX_TES];
+ S16 image_rot[MAX_TES];
+ U8 bump[MAX_TES];
+ U8 media_flags[MAX_TES];
+ U8 glow[MAX_TES];
+ LLMaterialID material_ids[MAX_TES];
+
+ static const U32 MAX_TE_BUFFER = 4096;
+ U8 packed_buffer[MAX_TE_BUFFER];
+
+ U32 size;
+ U32 face_count;
+};
+
class LLPrimitive : public LLXform
{
public:
@@ -331,6 +361,7 @@ public:
LLTextureEntry* getTE(const U8 te_num) const;
virtual void setNumTEs(const U8 num_tes);
+ virtual void setAllTESelected(bool sel);
virtual void setAllTETextures(const LLUUID &tex_id);
virtual void setTE(const U8 index, const LLTextureEntry& te);
virtual S32 setTEColor(const U8 te, const LLColor4 &color);
@@ -353,16 +384,20 @@ public:
virtual S32 setTEFullbright(const U8 te, const U8 fullbright);
virtual S32 setTEMediaFlags(const U8 te, const U8 flags);
virtual S32 setTEGlow(const U8 te, const F32 glow);
+ virtual S32 setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID);
+ virtual S32 setTEMaterialParams(const U8 index, const LLMaterialPtr pMaterialParams);
virtual BOOL setMaterial(const U8 material); // returns TRUE if material changed
+ virtual void setTESelected(const U8 te, bool sel);
void copyTEs(const LLPrimitive *primitive);
S32 packTEField(U8 *cur_ptr, U8 *data_ptr, U8 data_size, U8 last_face_index, EMsgVariableType type) const;
S32 unpackTEField(U8 *cur_ptr, U8 *buffer_end, U8 *data_ptr, U8 data_size, U8 face_count, EMsgVariableType type);
BOOL packTEMessage(LLMessageSystem *mesgsys) const;
BOOL packTEMessage(LLDataPacker &dp) const;
- S32 unpackTEMessage(LLMessageSystem* mesgsys, char const* block_name);
S32 unpackTEMessage(LLMessageSystem* mesgsys, char const* block_name, const S32 block_num); // Variable num of blocks
BOOL unpackTEMessage(LLDataPacker &dp);
+ S32 parseTEMessage(LLMessageSystem* mesgsys, char const* block_name, const S32 block_num, LLTEContents& tec);
+ S32 applyParsedTEMessage(LLTEContents& tec);
#ifdef CHECK_FOR_FINITE
inline void setPosition(const LLVector3& pos);
@@ -421,7 +456,8 @@ public:
inline BOOL isAvatar() const;
inline BOOL isSittingAvatar() const;
inline BOOL isSittingAvatarOnGround() const;
-
+ inline bool hasBumpmap() const { return mNumBumpmapTEs > 0;}
+
void setFlags(U32 flags) { mMiscFlags = flags; }
void addFlags(U32 flags) { mMiscFlags |= flags; }
void removeFlags(U32 flags) { mMiscFlags &= ~flags; }
@@ -435,6 +471,9 @@ public:
inline static BOOL isPrimitive(const LLPCode pcode);
inline static BOOL isApp(const LLPCode pcode);
+private:
+ void updateNumBumpmap(const U8 index, const U8 bump);
+
protected:
LLPCode mPrimitiveCode; // Primitive code
LLVector3 mVelocity; // how fast are we moving?
@@ -444,6 +483,7 @@ protected:
LLPrimTextureList mTextureList; // list of texture GUIDs, scales, offsets
U8 mMaterial; // Material code
U8 mNumTEs; // # of faces on the primitve
+ U8 mNumBumpmapTEs; // number of bumpmap TEs.
U32 mMiscFlags; // home for misc bools
public:
diff --git a/indra/llprimitive/llprimlinkinfo.h b/indra/llprimitive/llprimlinkinfo.h
index 82c50cfe2f..82c50cfe2f 100644..100755
--- a/indra/llprimitive/llprimlinkinfo.h
+++ b/indra/llprimitive/llprimlinkinfo.h
diff --git a/indra/llprimitive/llprimtexturelist.cpp b/indra/llprimitive/llprimtexturelist.cpp
index 36e04df7b7..537e7a6695 100644..100755
--- a/indra/llprimitive/llprimtexturelist.cpp
+++ b/indra/llprimitive/llprimtexturelist.cpp
@@ -27,8 +27,8 @@
#include "linden_common.h"
#include "llprimtexturelist.h"
+#include "llmaterialid.h"
#include "lltextureentry.h"
-#include "llmemtype.h"
// static
//int (TMyClass::*pt2Member)(float, char, char) = NULL; // C++
@@ -359,6 +359,24 @@ S32 LLPrimTextureList::setGlow(const U8 index, const F32 glow)
return TEM_CHANGE_NONE;
}
+S32 LLPrimTextureList::setMaterialID(const U8 index, const LLMaterialID& pMaterialID)
+{
+ if (index < mEntryList.size())
+ {
+ return mEntryList[index]->setMaterialID(pMaterialID);
+ }
+ return TEM_CHANGE_NONE;
+}
+
+S32 LLPrimTextureList::setMaterialParams(const U8 index, const LLMaterialPtr pMaterialParams)
+{
+ if (index < mEntryList.size())
+ {
+ return mEntryList[index]->setMaterialParams(pMaterialParams);
+ }
+ return TEM_CHANGE_NONE;
+}
+
S32 LLPrimTextureList::size() const
{
return mEntryList.size();
@@ -367,7 +385,6 @@ S32 LLPrimTextureList::size() const
// sets the size of the mEntryList container
void LLPrimTextureList::setSize(S32 new_size)
{
- LLMemType m1(LLMemType::MTYPE_PRIMITIVE);
if (new_size < 0)
{
new_size = 0;
diff --git a/indra/llprimitive/llprimtexturelist.h b/indra/llprimitive/llprimtexturelist.h
index 3cfa52f1d5..d7fabbbb79 100644..100755
--- a/indra/llprimitive/llprimtexturelist.h
+++ b/indra/llprimitive/llprimtexturelist.h
@@ -31,9 +31,11 @@
#include "lluuid.h"
#include "v3color.h"
#include "v4color.h"
+#include "llmaterial.h"
class LLTextureEntry;
+class LLMaterialID;
// this is a list of LLTextureEntry*'s because in practice the list's elements
// are of some derived class: LLFooTextureEntry
@@ -102,6 +104,8 @@ public:
S32 setFullbright(const U8 index, const U8 t);
S32 setMediaFlags(const U8 index, const U8 media_flags);
S32 setGlow(const U8 index, const F32 glow);
+ S32 setMaterialID(const U8 index, const LLMaterialID& pMaterialID);
+ S32 setMaterialParams(const U8 index, const LLMaterialPtr pMaterialParams);
S32 size() const;
diff --git a/indra/llprimitive/lltextureanim.cpp b/indra/llprimitive/lltextureanim.cpp
index 185a3f69c0..185a3f69c0 100644..100755
--- a/indra/llprimitive/lltextureanim.cpp
+++ b/indra/llprimitive/lltextureanim.cpp
diff --git a/indra/llprimitive/lltextureanim.h b/indra/llprimitive/lltextureanim.h
index f0d9f9df5c..f0d9f9df5c 100644..100755
--- a/indra/llprimitive/lltextureanim.h
+++ b/indra/llprimitive/lltextureanim.h
diff --git a/indra/llprimitive/lltextureentry.cpp b/indra/llprimitive/lltextureentry.cpp
index 34eff17519..0db75a0e82 100644..100755
--- a/indra/llprimitive/lltextureentry.cpp
+++ b/indra/llprimitive/lltextureentry.cpp
@@ -29,6 +29,7 @@
#include "lluuid.h"
#include "llmediaentry.h"
#include "lltextureentry.h"
+#include "llmaterialid.h"
#include "llsdutil_math.h"
#include "v4color.h"
@@ -60,18 +61,24 @@ LLTextureEntry* LLTextureEntry::newTextureEntry()
//===============================================================
LLTextureEntry::LLTextureEntry()
: mMediaEntry(NULL)
+ , mSelected(false)
+ , mMaterialUpdatePending(false)
{
init(LLUUID::null,1.f,1.f,0.f,0.f,0.f,DEFAULT_BUMP_CODE);
}
LLTextureEntry::LLTextureEntry(const LLUUID& tex_id)
: mMediaEntry(NULL)
+ , mSelected(false)
+ , mMaterialUpdatePending(false)
{
init(tex_id,1.f,1.f,0.f,0.f,0.f,DEFAULT_BUMP_CODE);
}
LLTextureEntry::LLTextureEntry(const LLTextureEntry &rhs)
: mMediaEntry(NULL)
+ , mSelected(false)
+ , mMaterialUpdatePending(false)
{
mID = rhs.mID;
mScaleS = rhs.mScaleS;
@@ -83,6 +90,8 @@ LLTextureEntry::LLTextureEntry(const LLTextureEntry &rhs)
mBump = rhs.mBump;
mMediaFlags = rhs.mMediaFlags;
mGlow = rhs.mGlow;
+ mMaterialID = rhs.mMaterialID;
+ mMaterial = rhs.mMaterial;
if (rhs.mMediaEntry != NULL) {
// Make a copy
mMediaEntry = new LLMediaEntry(*rhs.mMediaEntry);
@@ -103,6 +112,8 @@ LLTextureEntry &LLTextureEntry::operator=(const LLTextureEntry &rhs)
mBump = rhs.mBump;
mMediaFlags = rhs.mMediaFlags;
mGlow = rhs.mGlow;
+ mMaterialID = rhs.mMaterialID;
+ mMaterial = rhs.mMaterial;
if (mMediaEntry != NULL) {
delete mMediaEntry;
}
@@ -130,6 +141,7 @@ void LLTextureEntry::init(const LLUUID& tex_id, F32 scale_s, F32 scale_t, F32 of
mBump = bump;
mMediaFlags = 0x0;
mGlow = 0;
+ mMaterialID.clear();
setColor(LLColor4(1.f, 1.f, 1.f, 1.f));
if (mMediaEntry != NULL) {
@@ -159,6 +171,7 @@ bool LLTextureEntry::operator!=(const LLTextureEntry &rhs) const
if (mBump != rhs.mBump) return (true);
if (mMediaFlags != rhs.mMediaFlags) return (true);
if (mGlow != rhs.mGlow) return (true);
+ if (mMaterialID != rhs.mMaterialID) return (true);
return(false);
}
@@ -174,6 +187,7 @@ bool LLTextureEntry::operator==(const LLTextureEntry &rhs) const
if (mBump != rhs.mBump) return (false);
if (mMediaFlags != rhs.mMediaFlags) return false;
if (mGlow != rhs.mGlow) return false;
+ if (mMaterialID != rhs.mMaterialID) return (false);
return(true);
}
@@ -523,6 +537,34 @@ S32 LLTextureEntry::setGlow(F32 glow)
return TEM_CHANGE_NONE;
}
+S32 LLTextureEntry::setMaterialID(const LLMaterialID& pMaterialID)
+{
+ if ( (mMaterialID != pMaterialID) || (mMaterialUpdatePending && !mSelected) )
+ {
+ if (mSelected)
+ {
+ mMaterialUpdatePending = true;
+ mMaterialID = pMaterialID;
+ return TEM_CHANGE_TEXTURE;
+ }
+
+ mMaterialUpdatePending = false;
+ mMaterialID = pMaterialID;
+ return TEM_CHANGE_TEXTURE;
+ }
+ return TEM_CHANGE_NONE;
+}
+
+S32 LLTextureEntry::setMaterialParams(const LLMaterialPtr pMaterialParams)
+{
+ if (mSelected)
+ {
+ mMaterialUpdatePending = true;
+ }
+ mMaterial = pMaterialParams;
+ return TEM_CHANGE_TEXTURE;
+}
+
void LLTextureEntry::setMediaData(const LLMediaEntry &media_entry)
{
mMediaFlags |= MF_HAS_MEDIA;
diff --git a/indra/llprimitive/lltextureentry.h b/indra/llprimitive/lltextureentry.h
index 437b85e03f..19edcaa27d 100644..100755
--- a/indra/llprimitive/lltextureentry.h
+++ b/indra/llprimitive/lltextureentry.h
@@ -30,6 +30,8 @@
#include "lluuid.h"
#include "v4color.h"
#include "llsd.h"
+#include "llmaterialid.h"
+#include "llmaterial.h"
// These bits are used while unpacking TEM messages to tell which aspects of
// the texture entry changed.
@@ -98,6 +100,10 @@ public:
void init(const LLUUID& tex_id, F32 scale_s, F32 scale_t, F32 offset_s, F32 offset_t, F32 rotation, U8 bump);
+ bool hasPendingMaterialUpdate() const { return mMaterialUpdatePending; }
+ bool isSelected() const { return mSelected; }
+ bool setSelected(bool sel) { bool prev_sel = mSelected; mSelected = sel; return prev_sel; }
+
// These return a TEM_ flag from above to indicate if something changed.
S32 setID (const LLUUID &tex_id);
S32 setColor(const LLColor4 &color);
@@ -121,11 +127,19 @@ public:
S32 setTexGen(U8 texGen);
S32 setMediaTexGen(U8 media);
S32 setGlow(F32 glow);
+ S32 setMaterialID(const LLMaterialID& pMaterialID);
+ S32 setMaterialParams(const LLMaterialPtr pMaterialParams);
virtual const LLUUID &getID() const { return mID; }
const LLColor4 &getColor() const { return mColor; }
void getScale(F32 *s, F32 *t) const { *s = mScaleS; *t = mScaleT; }
+ F32 getScaleS() const { return mScaleS; }
+ F32 getScaleT() const { return mScaleT; }
+
void getOffset(F32 *s, F32 *t) const { *s = mOffsetS; *t = mOffsetT; }
+ F32 getOffsetS() const { return mOffsetS; }
+ F32 getOffsetT() const { return mOffsetT; }
+
F32 getRotation() const { return mRotation; }
void getRotation(F32 *theta) const { *theta = mRotation; }
@@ -136,9 +150,11 @@ public:
U8 getBumpShinyFullbright() const { return mBump; }
U8 getMediaFlags() const { return mMediaFlags & TEM_MEDIA_MASK; }
- U8 getTexGen() const { return mMediaFlags & TEM_TEX_GEN_MASK; }
+ LLTextureEntry::e_texgen getTexGen() const { return LLTextureEntry::e_texgen(mMediaFlags & TEM_TEX_GEN_MASK); }
U8 getMediaTexGen() const { return mMediaFlags; }
F32 getGlow() const { return mGlow; }
+ const LLMaterialID& getMaterialID() const { return mMaterialID; };
+ const LLMaterialPtr getMaterialParams() const { return mMaterial; };
// *NOTE: it is possible for hasMedia() to return true, but getMediaData() to return NULL.
// CONVERSELY, it is also possible for hasMedia() to return false, but getMediaData()
@@ -188,11 +204,15 @@ public:
static const char* TEXTURE_MEDIA_DATA_KEY;
protected:
+ bool mSelected;
LLUUID mID; // Texture GUID
LLColor4 mColor;
U8 mBump; // Bump map, shiny, and fullbright
U8 mMediaFlags; // replace with web page, movie, etc.
F32 mGlow;
+ bool mMaterialUpdatePending;
+ LLMaterialID mMaterialID;
+ LLMaterialPtr mMaterial;
// Note the media data is not sent via the same message structure as the rest of the TE
LLMediaEntry* mMediaEntry; // The media data for the face
diff --git a/indra/llprimitive/lltree_common.h b/indra/llprimitive/lltree_common.h
index df00ff1591..df00ff1591 100644..100755
--- a/indra/llprimitive/lltree_common.h
+++ b/indra/llprimitive/lltree_common.h
diff --git a/indra/llprimitive/lltreeparams.cpp b/indra/llprimitive/lltreeparams.cpp
index 842d848217..842d848217 100644..100755
--- a/indra/llprimitive/lltreeparams.cpp
+++ b/indra/llprimitive/lltreeparams.cpp
diff --git a/indra/llprimitive/lltreeparams.h b/indra/llprimitive/lltreeparams.h
index 6e2b47c0e9..6e2b47c0e9 100644..100755
--- a/indra/llprimitive/lltreeparams.h
+++ b/indra/llprimitive/lltreeparams.h
diff --git a/indra/llprimitive/llvolumemessage.cpp b/indra/llprimitive/llvolumemessage.cpp
index 58b23bebd2..58b23bebd2 100644..100755
--- a/indra/llprimitive/llvolumemessage.cpp
+++ b/indra/llprimitive/llvolumemessage.cpp
diff --git a/indra/llprimitive/llvolumemessage.h b/indra/llprimitive/llvolumemessage.h
index f59ee79c60..f59ee79c60 100644..100755
--- a/indra/llprimitive/llvolumemessage.h
+++ b/indra/llprimitive/llvolumemessage.h
diff --git a/indra/llprimitive/llvolumexml.cpp b/indra/llprimitive/llvolumexml.cpp
index bf2297a029..bf2297a029 100644..100755
--- a/indra/llprimitive/llvolumexml.cpp
+++ b/indra/llprimitive/llvolumexml.cpp
diff --git a/indra/llprimitive/llvolumexml.h b/indra/llprimitive/llvolumexml.h
index 9d4d989475..9d4d989475 100644..100755
--- a/indra/llprimitive/llvolumexml.h
+++ b/indra/llprimitive/llvolumexml.h
diff --git a/indra/llprimitive/material_codes.cpp b/indra/llprimitive/material_codes.cpp
index 2ea47eec36..2ea47eec36 100644..100755
--- a/indra/llprimitive/material_codes.cpp
+++ b/indra/llprimitive/material_codes.cpp
diff --git a/indra/llprimitive/material_codes.h b/indra/llprimitive/material_codes.h
index 84a6f2edd2..84a6f2edd2 100644..100755
--- a/indra/llprimitive/material_codes.h
+++ b/indra/llprimitive/material_codes.h
diff --git a/indra/llprimitive/object_flags.h b/indra/llprimitive/object_flags.h
index 94c559d757..31dbd15ae0 100644..100755
--- a/indra/llprimitive/object_flags.h
+++ b/indra/llprimitive/object_flags.h
@@ -28,43 +28,47 @@
#define LL_OBJECT_FLAGS_H
// downstream flags from sim->viewer
-const U32 FLAGS_USE_PHYSICS = 0x00000001;
-const U32 FLAGS_CREATE_SELECTED = 0x00000002;
-const U32 FLAGS_OBJECT_MODIFY = 0x00000004;
-const U32 FLAGS_OBJECT_COPY = 0x00000008;
-const U32 FLAGS_OBJECT_ANY_OWNER = 0x00000010;
-const U32 FLAGS_OBJECT_YOU_OWNER = 0x00000020;
-const U32 FLAGS_SCRIPTED = 0x00000040;
-const U32 FLAGS_HANDLE_TOUCH = 0x00000080;
-const U32 FLAGS_OBJECT_MOVE = 0x00000100;
-const U32 FLAGS_TAKES_MONEY = 0x00000200;
-const U32 FLAGS_PHANTOM = 0x00000400;
-const U32 FLAGS_INVENTORY_EMPTY = 0x00000800;
+const U32 FLAGS_USE_PHYSICS = (1U << 0);
+const U32 FLAGS_CREATE_SELECTED = (1U << 1);
+const U32 FLAGS_OBJECT_MODIFY = (1U << 2);
+const U32 FLAGS_OBJECT_COPY = (1U << 3);
+const U32 FLAGS_OBJECT_ANY_OWNER = (1U << 4);
+const U32 FLAGS_OBJECT_YOU_OWNER = (1U << 5);
+const U32 FLAGS_SCRIPTED = (1U << 6);
+const U32 FLAGS_HANDLE_TOUCH = (1U << 7);
+const U32 FLAGS_OBJECT_MOVE = (1U << 8);
+const U32 FLAGS_TAKES_MONEY = (1U << 9);
+const U32 FLAGS_PHANTOM = (1U << 10);
+const U32 FLAGS_INVENTORY_EMPTY = (1U << 11);
-const U32 FLAGS_JOINT_HINGE = 0x00001000;
-const U32 FLAGS_JOINT_P2P = 0x00002000;
-const U32 FLAGS_JOINT_LP2P = 0x00004000;
-// const U32 FLAGS_JOINT_WHEEL = 0x00008000;
-const U32 FLAGS_INCLUDE_IN_SEARCH = 0x00008000;
+const U32 FLAGS_AFFECTS_NAVMESH = (1U << 12);
+const U32 FLAGS_CHARACTER = (1U << 13);
+const U32 FLAGS_VOLUME_DETECT = (1U << 14);
+const U32 FLAGS_INCLUDE_IN_SEARCH = (1U << 15);
-const U32 FLAGS_ALLOW_INVENTORY_DROP = 0x00010000;
-const U32 FLAGS_OBJECT_TRANSFER = 0x00020000;
-const U32 FLAGS_OBJECT_GROUP_OWNED = 0x00040000;
-//const U32 FLAGS_OBJECT_YOU_OFFICER = 0x00080000;
+const U32 FLAGS_ALLOW_INVENTORY_DROP = (1U << 16);
+const U32 FLAGS_OBJECT_TRANSFER = (1U << 17);
+const U32 FLAGS_OBJECT_GROUP_OWNED = (1U << 18);
+//const U32 FLAGS_UNUSED_000 = (1U << 19); // was FLAGS_OBJECT_YOU_OFFICER
-const U32 FLAGS_CAMERA_DECOUPLED = 0x00100000;
-const U32 FLAGS_ANIM_SOURCE = 0x00200000;
-const U32 FLAGS_CAMERA_SOURCE = 0x00400000;
+const U32 FLAGS_CAMERA_DECOUPLED = (1U << 20);
+const U32 FLAGS_ANIM_SOURCE = (1U << 21);
+const U32 FLAGS_CAMERA_SOURCE = (1U << 22);
-const U32 FLAGS_CAST_SHADOWS = 0x00800000;
+//const U32 FLAGS_UNUSED_001 = (1U << 23); // was FLAGS_CAST_SHADOWS
-const U32 FLAGS_OBJECT_OWNER_MODIFY = 0x10000000;
+//const U32 FLAGS_UNUSED_002 = (1U << 24);
+//const U32 FLAGS_UNUSED_003 = (1U << 25);
+//const U32 FLAGS_UNUSED_004 = (1U << 26);
+//const U32 FLAGS_UNUSED_005 = (1U << 27);
-const U32 FLAGS_TEMPORARY_ON_REZ = 0x20000000;
-const U32 FLAGS_TEMPORARY = 0x40000000;
-const U32 FLAGS_ZLIB_COMPRESSED = 0x80000000;
+const U32 FLAGS_OBJECT_OWNER_MODIFY = (1U << 28);
-const U32 FLAGS_LOCAL = FLAGS_ANIM_SOURCE | FLAGS_CAMERA_SOURCE;
+const U32 FLAGS_TEMPORARY_ON_REZ = (1U << 29);
+//const U32 FLAGS_UNUSED_006 = (1U << 30); // was FLAGS_TEMPORARY
+//const U32 FLAGS_UNUSED_007 = (1U << 31); // was FLAGS_ZLIB_COMPRESSED
+
+const U32 FLAGS_LOCAL = FLAGS_ANIM_SOURCE | FLAGS_CAMERA_SOURCE;
typedef enum e_havok_joint_type
{
@@ -77,4 +81,3 @@ typedef enum e_havok_joint_type
} EHavokJointType;
#endif
-
diff --git a/indra/llprimitive/tests/llmediaentry_test.cpp b/indra/llprimitive/tests/llmediaentry_test.cpp
index 16e5f894e2..16e5f894e2 100644..100755
--- a/indra/llprimitive/tests/llmediaentry_test.cpp
+++ b/indra/llprimitive/tests/llmediaentry_test.cpp
diff --git a/indra/llprimitive/tests/llmessagesystem_stub.cpp b/indra/llprimitive/tests/llmessagesystem_stub.cpp
index 04e70945c4..04e70945c4 100644..100755
--- a/indra/llprimitive/tests/llmessagesystem_stub.cpp
+++ b/indra/llprimitive/tests/llmessagesystem_stub.cpp
diff --git a/indra/llprimitive/tests/llprimitive_test.cpp b/indra/llprimitive/tests/llprimitive_test.cpp
index 0d60c7cd15..0d60c7cd15 100644..100755
--- a/indra/llprimitive/tests/llprimitive_test.cpp
+++ b/indra/llprimitive/tests/llprimitive_test.cpp
diff --git a/indra/llrender/CMakeLists.txt b/indra/llrender/CMakeLists.txt
index 5c13df9f81..dba12d048e 100644..100755
--- a/indra/llrender/CMakeLists.txt
+++ b/indra/llrender/CMakeLists.txt
@@ -3,7 +3,7 @@
project(llrender)
include(00-Common)
-include(FindOpenGL)
+include(OpenGL)
include(FreeType)
include(LLCommon)
include(LLImage)
@@ -25,20 +25,31 @@ include_directories(
${LLXML_INCLUDE_DIRS}
${LLVFS_INCLUDE_DIRS}
)
+include_directories(SYSTEM
+ ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+ ${LLXML_SYSTEM_INCLUDE_DIRS}
+ )
set(llrender_SOURCE_FILES
llcubemap.cpp
+ llfontbitmapcache.cpp
llfontfreetype.cpp
llfontgl.cpp
- llfontbitmapcache.cpp
llfontregistry.cpp
+ llgl.cpp
llgldbg.cpp
llglslshader.cpp
+ llgltexture.cpp
llimagegl.cpp
llpostprocess.cpp
+ llrender.cpp
+ llrender2dutils.cpp
+ llrendernavprim.cpp
llrendersphere.cpp
+ llrendertarget.cpp
llshadermgr.cpp
lltexture.cpp
+ lluiimage.cpp
llvertexbuffer.cpp
)
@@ -55,13 +66,17 @@ set(llrender_HEADER_FILES
llglheaders.h
llglslshader.h
llglstates.h
+ llgltexture.h
llgltypes.h
llimagegl.h
llpostprocess.h
llrender.h
+ llrender2dutils.h
+ llrendernavprim.h
llrendersphere.h
llshadermgr.h
lltexture.h
+ lluiimage.h
llvertexbuffer.h
)
@@ -70,33 +85,47 @@ set_source_files_properties(${llrender_HEADER_FILES}
list(APPEND llrender_SOURCE_FILES ${llrender_HEADER_FILES})
-if (SERVER AND NOT WINDOWS AND NOT DARWIN)
- copy_server_sources(
- llgl
- llrender
- )
-
-
- set_source_files_properties(
- ${server_SOURCE_FILES}
- PROPERTIES
- COMPILE_FLAGS "-DLL_MESA=1 -DLL_MESA_HEADLESS=1"
- )
+if (BUILD_HEADLESS)
add_library (llrenderheadless
${llrender_SOURCE_FILES}
- ${server_SOURCE_FILES}
)
-else (SERVER AND NOT WINDOWS AND NOT DARWIN)
- list(APPEND llrender_SOURCE_FILES
- llgl.cpp
- llrender.cpp
- llrendertarget.cpp
+
+ set_property(TARGET llrenderheadless
+ PROPERTY COMPILE_DEFINITIONS LL_MESA=1 LL_MESA_HEADLESS=1
)
-endif (SERVER AND NOT WINDOWS AND NOT DARWIN)
+
+ target_link_libraries(llrenderheadless
+ ${LLCOMMON_LIBRARIES}
+ ${LLIMAGE_LIBRARIES}
+ ${LLMATH_LIBRARIES}
+ ${LLRENDER_HEADLESS_LIBRARIES}
+ ${LLVFS_LIBRARIES}
+ ${LLXML_LIBRARIES}
+ ${LLVFS_LIBRARIES}
+ ${LLWINDOW_HEADLESS_LIBRARIES}
+ ${OPENGL_HEADLESS_LIBRARIES})
+
+endif (BUILD_HEADLESS)
+
add_library (llrender ${llrender_SOURCE_FILES})
+
+if (SDL_FOUND)
+ set_property(TARGET llrender
+ PROPERTY COMPILE_DEFINITIONS LL_SDL=1
+ )
+endif (SDL_FOUND)
+
# Libraries on which this library depends, needed for Linux builds
# Sort by high-level to low-level
target_link_libraries(llrender
- llimage
+ ${LLCOMMON_LIBRARIES}
+ ${LLIMAGE_LIBRARIES}
+ ${LLMATH_LIBRARIES}
+ ${LLRENDER_LIBRARIES}
+ ${LLVFS_LIBRARIES}
+ ${LLXML_LIBRARIES}
+ ${LLVFS_LIBRARIES}
+ ${LLWINDOW_LIBRARIES}
${FREETYPE_LIBRARIES}
${OPENGL_LIBRARIES})
+
diff --git a/indra/llrender/llcubemap.cpp b/indra/llrender/llcubemap.cpp
index 45a3b18179..45a3b18179 100644..100755
--- a/indra/llrender/llcubemap.cpp
+++ b/indra/llrender/llcubemap.cpp
diff --git a/indra/llrender/llcubemap.h b/indra/llrender/llcubemap.h
index ee2c41e026..ee2c41e026 100644..100755
--- a/indra/llrender/llcubemap.h
+++ b/indra/llrender/llcubemap.h
diff --git a/indra/llrender/llfontbitmapcache.cpp b/indra/llrender/llfontbitmapcache.cpp
index c985f6b959..c985f6b959 100644..100755
--- a/indra/llrender/llfontbitmapcache.cpp
+++ b/indra/llrender/llfontbitmapcache.cpp
diff --git a/indra/llrender/llfontbitmapcache.h b/indra/llrender/llfontbitmapcache.h
index c93b0c7320..c93b0c7320 100644..100755
--- a/indra/llrender/llfontbitmapcache.h
+++ b/indra/llrender/llfontbitmapcache.h
diff --git a/indra/llrender/llfontfreetype.cpp b/indra/llrender/llfontfreetype.cpp
index 66d4ad2d87..058bef43a5 100644..100755
--- a/indra/llrender/llfontfreetype.cpp
+++ b/indra/llrender/llfontfreetype.cpp
@@ -485,14 +485,11 @@ void LLFontFreetype::renderGlyph(U32 glyph_index) const
if (mFTFace == NULL)
return;
- int error = FT_Load_Glyph(mFTFace, glyph_index, FT_LOAD_FORCE_AUTOHINT );
- llassert(!error);
+ llassert_always(! FT_Load_Glyph(mFTFace, glyph_index, FT_LOAD_FORCE_AUTOHINT) );
- error = FT_Render_Glyph(mFTFace->glyph, gFontRenderMode);
+ llassert_always(! FT_Render_Glyph(mFTFace->glyph, gFontRenderMode) );
mRenderGlyphCount++;
-
- llassert(!error);
}
void LLFontFreetype::reset(F32 vert_dpi, F32 horz_dpi)
diff --git a/indra/llrender/llfontfreetype.h b/indra/llrender/llfontfreetype.h
index f1b23f22d5..f1b23f22d5 100644..100755
--- a/indra/llrender/llfontfreetype.h
+++ b/indra/llrender/llfontfreetype.h
diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp
index fccbf37a8d..c4f36cabd0 100644..100755
--- a/indra/llrender/llfontgl.cpp
+++ b/indra/llrender/llfontgl.cpp
@@ -422,6 +422,16 @@ S32 LLFontGL::renderUTF8(const std::string &text, S32 begin_offset, S32 x, S32 y
}
// font metrics - override for LLFontFreetype that returns units of virtual pixels
+F32 LLFontGL::getAscenderHeight() const
+{
+ return mFontFreetype->getAscenderHeight() / sScaleY;
+}
+
+F32 LLFontGL::getDescenderHeight() const
+{
+ return mFontFreetype->getDescenderHeight() / sScaleY;
+}
+
S32 LLFontGL::getLineHeight() const
{
return llceil(mFontFreetype->getAscenderHeight() / sScaleY) + llceil(mFontFreetype->getDescenderHeight() / sScaleY);
@@ -531,7 +541,6 @@ S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_ch
BOOL clip = FALSE;
F32 cur_x = 0;
- F32 drawn_x = 0;
S32 start_of_last_word = 0;
BOOL in_word = FALSE;
@@ -589,6 +598,11 @@ S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_ch
if(!fgi)
{
fgi = mFontFreetype->getGlyphInfo(wch);
+
+ if (NULL == fgi)
+ {
+ return 0;
+ }
}
// account for glyphs that run beyond the starting point for the next glyphs
@@ -614,7 +628,6 @@ S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_ch
// Round after kerning.
cur_x = (F32)llround(cur_x);
- drawn_x = cur_x;
}
if( clip )
@@ -779,7 +792,7 @@ const LLFontDescriptor& LLFontGL::getFontDesc() const
}
// static
-void LLFontGL::initClass(F32 screen_dpi, F32 x_scale, F32 y_scale, const std::string& app_dir, const std::vector<std::string>& xui_paths, bool create_gl_textures)
+void LLFontGL::initClass(F32 screen_dpi, F32 x_scale, F32 y_scale, const std::string& app_dir, bool create_gl_textures)
{
sVertDPI = (F32)llfloor(screen_dpi * y_scale);
sHorizDPI = (F32)llfloor(screen_dpi * x_scale);
@@ -790,7 +803,7 @@ void LLFontGL::initClass(F32 screen_dpi, F32 x_scale, F32 y_scale, const std::st
// Font registry init
if (!sFontRegistry)
{
- sFontRegistry = new LLFontRegistry(xui_paths, create_gl_textures);
+ sFontRegistry = new LLFontRegistry(create_gl_textures);
sFontRegistry->parseFontInfo("fonts.xml");
}
else
diff --git a/indra/llrender/llfontgl.h b/indra/llrender/llfontgl.h
index 74bdbb43e7..0988e99deb 100644..100755
--- a/indra/llrender/llfontgl.h
+++ b/indra/llrender/llfontgl.h
@@ -115,6 +115,8 @@ public:
S32 renderUTF8(const std::string &text, S32 begin_offset, S32 x, S32 y, const LLColor4 &color, HAlign halign, VAlign valign, U8 style = NORMAL, ShadowType shadow = NO_SHADOW) const;
// font metrics - override for LLFontFreetype that returns units of virtual pixels
+ F32 getAscenderHeight() const;
+ F32 getDescenderHeight() const;
S32 getLineHeight() const;
S32 getWidth(const std::string& utf8text) const;
@@ -148,7 +150,7 @@ public:
const LLFontDescriptor& getFontDesc() const;
- static void initClass(F32 screen_dpi, F32 x_scale, F32 y_scale, const std::string& app_dir, const std::vector<std::string>& xui_paths, bool create_gl_textures = true);
+ static void initClass(F32 screen_dpi, F32 x_scale, F32 y_scale, const std::string& app_dir, bool create_gl_textures = true);
// Load sans-serif, sans-serif-small, etc.
// Slow, requires multiple seconds to load fonts.
diff --git a/indra/llrender/llfontregistry.cpp b/indra/llrender/llfontregistry.cpp
index 4d22eba3d9..f5ca8d5b04 100644..100755
--- a/indra/llrender/llfontregistry.cpp
+++ b/indra/llrender/llfontregistry.cpp
@@ -163,14 +163,9 @@ LLFontDescriptor LLFontDescriptor::normalize() const
return LLFontDescriptor(new_name,new_size,new_style,getFileNames());
}
-LLFontRegistry::LLFontRegistry(const string_vec_t& xui_paths,
- bool create_gl_textures)
+LLFontRegistry::LLFontRegistry(bool create_gl_textures)
: mCreateGLTextures(create_gl_textures)
{
- // Propagate this down from LLUICtrlFactory so LLRender doesn't
- // need an upstream dependency on LLUI.
- mXUIPaths = xui_paths;
-
// This is potentially a slow directory traversal, so we want to
// cache the result.
mUltimateFallbackList = LLWindow::getDynamicFallbackFontList();
@@ -183,27 +178,30 @@ LLFontRegistry::~LLFontRegistry()
bool LLFontRegistry::parseFontInfo(const std::string& xml_filename)
{
- bool success = false; // Succeed if we find at least one XUI file
- const string_vec_t& xml_paths = mXUIPaths;
+ bool success = false; // Succeed if we find and read at least one XUI file
+ const string_vec_t xml_paths = gDirUtilp->findSkinnedFilenames(LLDir::XUI, xml_filename);
+ if (xml_paths.empty())
+ {
+ // We didn't even find one single XUI file
+ return false;
+ }
+
for (string_vec_t::const_iterator path_it = xml_paths.begin();
path_it != xml_paths.end();
++path_it)
{
-
LLXMLNodePtr root;
- std::string full_filename = gDirUtilp->findSkinnedFilename(*path_it, xml_filename);
- bool parsed_file = LLXMLNode::parseFile(full_filename, root, NULL);
+ bool parsed_file = LLXMLNode::parseFile(*path_it, root, NULL);
if (!parsed_file)
continue;
-
+
if ( root.isNull() || ! root->hasName( "fonts" ) )
{
- llwarns << "Bad font info file: "
- << full_filename << llendl;
+ llwarns << "Bad font info file: " << *path_it << llendl;
continue;
}
-
+
std::string root_name;
root->getAttributeString("name",root_name);
if (root->hasName("fonts"))
@@ -215,7 +213,7 @@ bool LLFontRegistry::parseFontInfo(const std::string& xml_filename)
}
//if (success)
// dump();
-
+
return success;
}
@@ -225,7 +223,7 @@ std::string currentOsName()
return "Windows";
#elif LL_DARWIN
return "Mac";
-#elif LL_SDL
+#elif LL_SDL || LL_MESA_HEADLESS
return "Linux";
#else
return "";
diff --git a/indra/llrender/llfontregistry.h b/indra/llrender/llfontregistry.h
index 8b06191c56..059248fbbd 100644..100755
--- a/indra/llrender/llfontregistry.h
+++ b/indra/llrender/llfontregistry.h
@@ -67,8 +67,7 @@ class LLFontRegistry
public:
// create_gl_textures - set to false for test apps with no OpenGL window,
// such as llui_libtest
- LLFontRegistry(const string_vec_t& xui_paths,
- bool create_gl_textures);
+ LLFontRegistry(bool create_gl_textures);
~LLFontRegistry();
// Load standard font info from XML file(s).
@@ -105,7 +104,6 @@ private:
font_size_map_t mFontSizes;
string_vec_t mUltimateFallbackList;
- string_vec_t mXUIPaths;
bool mCreateGLTextures;
};
diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp
index 197bc2b422..acfb3c085a 100644..100755
--- a/indra/llrender/llgl.cpp
+++ b/indra/llrender/llgl.cpp
@@ -44,7 +44,6 @@
#include "llmath.h"
#include "m4math.h"
#include "llstring.h"
-#include "llmemtype.h"
#include "llstacktrace.h"
#include "llglheaders.h"
@@ -60,6 +59,7 @@ BOOL gDebugGL = FALSE;
BOOL gClothRipple = FALSE;
BOOL gHeadlessClient = FALSE;
BOOL gGLActive = FALSE;
+BOOL gGLDebugLoggingEnabled = TRUE;
static const std::string HEADLESS_VENDOR_STRING("Linden Lab");
static const std::string HEADLESS_RENDERER_STRING("Headless");
@@ -81,6 +81,8 @@ void APIENTRY gl_debug_callback(GLenum source,
const GLchar* message,
GLvoid* userParam)
{
+ if (gGLDebugLoggingEnabled)
+ {
if (severity == GL_DEBUG_SEVERITY_HIGH_ARB)
{
llwarns << "----- GL ERROR --------" << llendl;
@@ -94,6 +96,11 @@ void APIENTRY gl_debug_callback(GLenum source,
llwarns << "Severity: " << std::hex << severity << llendl;
llwarns << "Message: " << message << llendl;
llwarns << "-----------------------" << llendl;
+ if (severity == GL_DEBUG_SEVERITY_HIGH_ARB)
+ {
+ llerrs << "Halting on GL Error" << llendl;
+ }
+}
}
#endif
@@ -213,6 +220,11 @@ PFNGLGETQUERYIVARBPROC glGetQueryivARB = NULL;
PFNGLGETQUERYOBJECTIVARBPROC glGetQueryObjectivARB = NULL;
PFNGLGETQUERYOBJECTUIVARBPROC glGetQueryObjectuivARB = NULL;
+// GL_ARB_timer_query
+PFNGLQUERYCOUNTERPROC glQueryCounter = NULL;
+PFNGLGETQUERYOBJECTI64VPROC glGetQueryObjecti64v = NULL;
+PFNGLGETQUERYOBJECTUI64VPROC glGetQueryObjectui64v = NULL;
+
// GL_ARB_point_parameters
PFNGLPOINTPARAMETERFARBPROC glPointParameterfARB = NULL;
PFNGLPOINTPARAMETERFVARBPROC glPointParameterfvARB = NULL;
@@ -245,6 +257,13 @@ PFNGLTEXIMAGE3DMULTISAMPLEPROC glTexImage3DMultisample = NULL;
PFNGLGETMULTISAMPLEFVPROC glGetMultisamplefv = NULL;
PFNGLSAMPLEMASKIPROC glSampleMaski = NULL;
+//transform feedback (4.0 core)
+PFNGLBEGINTRANSFORMFEEDBACKPROC glBeginTransformFeedback = NULL;
+PFNGLENDTRANSFORMFEEDBACKPROC glEndTransformFeedback = NULL;
+PFNGLTRANSFORMFEEDBACKVARYINGSPROC glTransformFeedbackVaryings = NULL;
+PFNGLBINDBUFFERRANGEPROC glBindBufferRange = NULL;
+PFNGLBINDBUFFERBASEPROC glBindBufferBase = NULL;
+
//GL_ARB_debug_output
PFNGLDEBUGMESSAGECONTROLARBPROC glDebugMessageControlARB = NULL;
PFNGLDEBUGMESSAGEINSERTARBPROC glDebugMessageInsertARB = NULL;
@@ -412,11 +431,13 @@ LLGLManager::LLGLManager() :
mHasFragmentShader(FALSE),
mNumTextureImageUnits(0),
mHasOcclusionQuery(FALSE),
+ mHasTimerQuery(FALSE),
mHasOcclusionQuery2(FALSE),
mHasPointParameters(FALSE),
mHasDrawBuffers(FALSE),
mHasTextureRectangle(FALSE),
mHasTextureMultisample(FALSE),
+ mHasTransformFeedback(FALSE),
mMaxSampleMaskWords(0),
mMaxColorTextureSamples(0),
mMaxDepthTextureSamples(0),
@@ -435,7 +456,9 @@ LLGLManager::LLGLManager() :
mIsGFFX(FALSE),
mATIOffsetVerticalLines(FALSE),
mATIOldDriver(FALSE),
-
+#if LL_DARWIN
+ mIsMobileGF(FALSE),
+#endif
mHasRequirements(TRUE),
mHasSeparateSpecularColor(FALSE),
@@ -554,7 +577,8 @@ bool LLGLManager::initGL()
parse_gl_version( &mDriverVersionMajor,
&mDriverVersionMinor,
&mDriverVersionRelease,
- &mDriverVersionVendorString );
+ &mDriverVersionVendorString,
+ &mGLVersionString);
mGLVersion = mDriverVersionMajor + mDriverVersionMinor * .1f;
@@ -572,16 +596,20 @@ bool LLGLManager::initGL()
#endif
}
+ if (mGLVersion >= 2.1f && LLImageGL::sCompressTextures)
+ { //use texture compression
+ glHint(GL_TEXTURE_COMPRESSION_HINT, GL_NICEST);
+ }
+ else
+ { //GL version is < 3.0, always disable texture compression
+ LLImageGL::sCompressTextures = false;
+ }
+
// Trailing space necessary to keep "nVidia Corpor_ati_on" cards
// from being recognized as ATI.
if (mGLVendor.substr(0,4) == "ATI ")
{
mGLVendorShort = "ATI";
- BOOL mobile = FALSE;
- if (mGLRenderer.find("MOBILITY") != std::string::npos)
- {
- mobile = TRUE;
- }
mIsATI = TRUE;
#if LL_WINDOWS && !LL_MESA_HEADLESS
@@ -592,11 +620,8 @@ bool LLGLManager::initGL()
#endif // LL_WINDOWS
#if (LL_WINDOWS || LL_LINUX) && !LL_MESA_HEADLESS
- // release 7277 is a point at which we verify that ATI OpenGL
- // drivers get pretty stable with SL, ~Catalyst 8.2,
- // for both Win32 and Linux.
- if (mDriverVersionRelease < 7277 &&
- mDriverVersionRelease != 0) // 0 == Undetectable driver version - these get to pretend to be new ATI drivers, though that decision may be revisited.
+ // count any pre OpenGL 3.0 implementation as an old driver
+ if (mGLVersion < 3.f)
{
mATIOldDriver = TRUE;
}
@@ -625,6 +650,14 @@ bool LLGLManager::initGL()
{
mIsGF3 = TRUE;
}
+#if LL_DARWIN
+ else if ((mGLRenderer.find("9400M") != std::string::npos)
+ || (mGLRenderer.find("9600M") != std::string::npos)
+ || (mGLRenderer.find("9800M") != std::string::npos))
+ {
+ mIsMobileGF = TRUE;
+ }
+#endif
}
else if (mGLVendor.find("INTEL") != std::string::npos
@@ -733,6 +766,12 @@ bool LLGLManager::initGL()
{ //using multisample textures on ATI results in black screen for some reason
mHasTextureMultisample = FALSE;
}
+
+
+ if (mIsIntel && mGLVersion <= 3.f)
+ { //never try to use framebuffer objects on older intel drivers (crashy)
+ mHasFramebufferObject = FALSE;
+ }
#endif
if (mHasFramebufferObject)
@@ -923,7 +962,6 @@ void LLGLManager::initExtensions()
mHasMultitexture = glh_init_extensions("GL_ARB_multitexture");
mHasATIMemInfo = ExtensionExists("GL_ATI_meminfo", gGLHExts.mSysExts);
mHasNVXMemInfo = ExtensionExists("GL_NVX_gpu_memory_info", gGLHExts.mSysExts);
- mHasMipMapGeneration = glh_init_extensions("GL_SGIS_generate_mipmap");
mHasSeparateSpecularColor = glh_init_extensions("GL_EXT_separate_specular_color");
mHasAnisotropic = glh_init_extensions("GL_EXT_texture_filter_anisotropic");
glh_init_extensions("GL_ARB_texture_cube_map");
@@ -931,13 +969,15 @@ void LLGLManager::initExtensions()
mHasARBEnvCombine = ExtensionExists("GL_ARB_texture_env_combine", gGLHExts.mSysExts);
mHasCompressedTextures = glh_init_extensions("GL_ARB_texture_compression");
mHasOcclusionQuery = ExtensionExists("GL_ARB_occlusion_query", gGLHExts.mSysExts);
+ mHasTimerQuery = ExtensionExists("GL_ARB_timer_query", gGLHExts.mSysExts);
mHasOcclusionQuery2 = ExtensionExists("GL_ARB_occlusion_query2", gGLHExts.mSysExts);
mHasVertexBufferObject = ExtensionExists("GL_ARB_vertex_buffer_object", gGLHExts.mSysExts);
mHasVertexArrayObject = ExtensionExists("GL_ARB_vertex_array_object", gGLHExts.mSysExts);
mHasSync = ExtensionExists("GL_ARB_sync", gGLHExts.mSysExts);
mHasMapBufferRange = ExtensionExists("GL_ARB_map_buffer_range", gGLHExts.mSysExts);
mHasFlushBufferRange = ExtensionExists("GL_APPLE_flush_buffer_range", gGLHExts.mSysExts);
- mHasDepthClamp = ExtensionExists("GL_ARB_depth_clamp", gGLHExts.mSysExts) || ExtensionExists("GL_NV_depth_clamp", gGLHExts.mSysExts);
+ //mHasDepthClamp = ExtensionExists("GL_ARB_depth_clamp", gGLHExts.mSysExts) || ExtensionExists("GL_NV_depth_clamp", gGLHExts.mSysExts);
+ mHasDepthClamp = FALSE;
// mask out FBO support when packed_depth_stencil isn't there 'cause we need it for LLRenderTarget -Brad
#ifdef GL_ARB_framebuffer_object
mHasFramebufferObject = ExtensionExists("GL_ARB_framebuffer_object", gGLHExts.mSysExts);
@@ -947,12 +987,24 @@ void LLGLManager::initExtensions()
ExtensionExists("GL_EXT_framebuffer_multisample", gGLHExts.mSysExts) &&
ExtensionExists("GL_EXT_packed_depth_stencil", gGLHExts.mSysExts);
#endif
+#ifdef GL_EXT_texture_sRGB
+ mHassRGBTexture = ExtensionExists("GL_EXT_texture_sRGB", gGLHExts.mSysExts);
+#endif
+#ifdef GL_ARB_framebuffer_sRGB
+ mHassRGBFramebuffer = ExtensionExists("GL_ARB_framebuffer_sRGB", gGLHExts.mSysExts);
+#else
+ mHassRGBFramebuffer = ExtensionExists("GL_EXT_framebuffer_sRGB", gGLHExts.mSysExts);
+#endif
+
+ mHasMipMapGeneration = mHasFramebufferObject || mGLVersion >= 1.4f;
+
mHasDrawBuffers = ExtensionExists("GL_ARB_draw_buffers", gGLHExts.mSysExts);
mHasBlendFuncSeparate = ExtensionExists("GL_EXT_blend_func_separate", gGLHExts.mSysExts);
mHasTextureRectangle = ExtensionExists("GL_ARB_texture_rectangle", gGLHExts.mSysExts);
mHasTextureMultisample = ExtensionExists("GL_ARB_texture_multisample", gGLHExts.mSysExts);
mHasDebugOutput = ExtensionExists("GL_ARB_debug_output", gGLHExts.mSysExts);
+ mHasTransformFeedback = mGLVersion >= 4.f ? TRUE : FALSE;
#if !LL_DARWIN
mHasPointParameters = !mIsATI && ExtensionExists("GL_ARB_point_parameters", gGLHExts.mSysExts);
#endif
@@ -1108,7 +1160,8 @@ void LLGLManager::initExtensions()
// Misc
glGetIntegerv(GL_MAX_ELEMENTS_VERTICES, (GLint*) &mGLMaxVertexRange);
glGetIntegerv(GL_MAX_ELEMENTS_INDICES, (GLint*) &mGLMaxIndexRange);
-
+ glGetIntegerv(GL_MAX_TEXTURE_SIZE, (GLint*) &mGLMaxTextureSize);
+
#if (LL_WINDOWS || LL_LINUX || LL_SOLARIS) && !LL_MESA_HEADLESS
LL_DEBUGS("RenderInit") << "GL Probe: Getting symbols" << LL_ENDL;
if (mHasVertexBufferObject)
@@ -1192,7 +1245,15 @@ void LLGLManager::initExtensions()
glTexImage3DMultisample = (PFNGLTEXIMAGE3DMULTISAMPLEPROC) GLH_EXT_GET_PROC_ADDRESS("glTexImage3DMultisample");
glGetMultisamplefv = (PFNGLGETMULTISAMPLEFVPROC) GLH_EXT_GET_PROC_ADDRESS("glGetMultisamplefv");
glSampleMaski = (PFNGLSAMPLEMASKIPROC) GLH_EXT_GET_PROC_ADDRESS("glSampleMaski");
- }
+ }
+ if (mHasTransformFeedback)
+ {
+ glBeginTransformFeedback = (PFNGLBEGINTRANSFORMFEEDBACKPROC) GLH_EXT_GET_PROC_ADDRESS("glBeginTransformFeedback");
+ glEndTransformFeedback = (PFNGLENDTRANSFORMFEEDBACKPROC) GLH_EXT_GET_PROC_ADDRESS("glEndTransformFeedback");
+ glTransformFeedbackVaryings = (PFNGLTRANSFORMFEEDBACKVARYINGSPROC) GLH_EXT_GET_PROC_ADDRESS("glTransformFeedbackVaryings");
+ glBindBufferRange = (PFNGLBINDBUFFERRANGEPROC) GLH_EXT_GET_PROC_ADDRESS("glBindBufferRange");
+ glBindBufferBase = (PFNGLBINDBUFFERBASEPROC) GLH_EXT_GET_PROC_ADDRESS("glBindBufferBase");
+ }
if (mHasDebugOutput)
{
glDebugMessageControlARB = (PFNGLDEBUGMESSAGECONTROLARBPROC) GLH_EXT_GET_PROC_ADDRESS("glDebugMessageControlARB");
@@ -1227,6 +1288,13 @@ void LLGLManager::initExtensions()
glGetQueryObjectivARB = (PFNGLGETQUERYOBJECTIVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glGetQueryObjectivARB");
glGetQueryObjectuivARB = (PFNGLGETQUERYOBJECTUIVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glGetQueryObjectuivARB");
}
+ if (mHasTimerQuery)
+ {
+ llinfos << "initExtensions() TimerQuery-related procs..." << llendl;
+ glQueryCounter = (PFNGLQUERYCOUNTERPROC) GLH_EXT_GET_PROC_ADDRESS("glQueryCounter");
+ glGetQueryObjecti64v = (PFNGLGETQUERYOBJECTI64VPROC) GLH_EXT_GET_PROC_ADDRESS("glGetQueryObjecti64v");
+ glGetQueryObjectui64v = (PFNGLGETQUERYOBJECTUI64VPROC) GLH_EXT_GET_PROC_ADDRESS("glGetQueryObjectui64v");
+ }
if (mHasPointParameters)
{
llinfos << "initExtensions() PointParameters-related procs..." << llendl;
@@ -1439,7 +1507,7 @@ void do_assert_glerror()
void assert_glerror()
{
- if (!gGLActive)
+/* if (!gGLActive)
{
//llwarns << "GL used while not active!" << llendl;
@@ -1448,8 +1516,13 @@ void assert_glerror()
//ll_fail("GL used while not active");
}
}
+*/
- if (gDebugGL)
+ if (!gDebugGL)
+ {
+ //funny looking if for branch prediction -- gDebugGL is almost always false and assert_glerror is called often
+ }
+ else
{
do_assert_glerror();
}
@@ -1458,9 +1531,8 @@ void assert_glerror()
void clear_glerror()
{
- // Create or update texture to be used with this data
- GLenum error;
- error = glGetError();
+ glGetError();
+ glGetError();
}
///////////////////////////////////////////////////////////////
@@ -1897,7 +1969,7 @@ void LLGLState::checkClientArrays(const std::string& msg, U32 data_mask)
glClientActiveTextureARB(GL_TEXTURE0_ARB);
gGL.getTexUnit(0)->activate();
- if (gGLManager.mHasVertexShader)
+ if (gGLManager.mHasVertexShader && LLGLSLShader::sNoFixedFunction)
{ //make sure vertex attribs are all disabled
GLint count;
glGetIntegerv(GL_MAX_VERTEX_ATTRIBS_ARB, &count);
@@ -1949,6 +2021,7 @@ LLGLState::LLGLState(LLGLenum state, S32 enabled) :
case GL_COLOR_MATERIAL:
case GL_FOG:
case GL_LINE_STIPPLE:
+ case GL_POLYGON_STIPPLE:
mState = 0;
break;
}
@@ -2037,7 +2110,7 @@ void LLGLManager::initGLStates()
////////////////////////////////////////////////////////////////////////////////
-void parse_gl_version( S32* major, S32* minor, S32* release, std::string* vendor_specific )
+void parse_gl_version( S32* major, S32* minor, S32* release, std::string* vendor_specific, std::string* version_string )
{
// GL_VERSION returns a null-terminated string with the format:
// <major>.<minor>[.<release>] [<vendor specific>]
@@ -2053,6 +2126,8 @@ void parse_gl_version( S32* major, S32* minor, S32* release, std::string* vendor
return;
}
+ version_string->assign(version);
+
std::string ver_copy( version );
S32 len = (S32)strlen( version ); /* Flawfinder: ignore */
S32 i = 0;
@@ -2288,7 +2363,6 @@ void LLGLNamePool::release(GLuint name)
//static
void LLGLNamePool::upkeepPools()
{
- LLMemType mt(LLMemType::MTYPE_UPKEEP_POOLS);
for (tracker_t::instance_iter iter = beginInstances(); iter != endInstances(); ++iter)
{
LLGLNamePool & pool = *iter;
@@ -2414,3 +2488,65 @@ LLGLSquashToFarClip::~LLGLSquashToFarClip()
gGL.matrixMode(LLRender::MM_MODELVIEW);
}
+
+
+LLGLSyncFence::LLGLSyncFence()
+{
+#ifdef GL_ARB_sync
+ mSync = 0;
+#endif
+}
+
+LLGLSyncFence::~LLGLSyncFence()
+{
+#ifdef GL_ARB_sync
+ if (mSync)
+ {
+ glDeleteSync(mSync);
+ }
+#endif
+}
+
+void LLGLSyncFence::placeFence()
+{
+#ifdef GL_ARB_sync
+ if (mSync)
+ {
+ glDeleteSync(mSync);
+ }
+ mSync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
+#endif
+}
+
+bool LLGLSyncFence::isCompleted()
+{
+ bool ret = true;
+#ifdef GL_ARB_sync
+ if (mSync)
+ {
+ GLenum status = glClientWaitSync(mSync, 0, 1);
+ if (status == GL_TIMEOUT_EXPIRED)
+ {
+ ret = false;
+ }
+ }
+#endif
+ return ret;
+}
+
+void LLGLSyncFence::wait()
+{
+#ifdef GL_ARB_sync
+ if (mSync)
+ {
+ while (glClientWaitSync(mSync, 0, FENCE_WAIT_TIME_NANOSECONDS) == GL_TIMEOUT_EXPIRED)
+ { //track the number of times we've waited here
+ static S32 waits = 0;
+ waits++;
+ }
+ }
+#endif
+}
+
+
+
diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h
index 5a33c98708..75e5fe86ec 100644..100755
--- a/indra/llrender/llgl.h
+++ b/indra/llrender/llgl.h
@@ -98,12 +98,14 @@ public:
BOOL mHasFragmentShader;
S32 mNumTextureImageUnits;
BOOL mHasOcclusionQuery;
+ BOOL mHasTimerQuery;
BOOL mHasOcclusionQuery2;
BOOL mHasPointParameters;
BOOL mHasDrawBuffers;
BOOL mHasDepthClamp;
BOOL mHasTextureRectangle;
BOOL mHasTextureMultisample;
+ BOOL mHasTransformFeedback;
S32 mMaxSampleMaskWords;
S32 mMaxColorTextureSamples;
S32 mMaxDepthTextureSamples;
@@ -114,6 +116,8 @@ public:
BOOL mHasARBEnvCombine;
BOOL mHasCubeMap;
BOOL mHasDebugOutput;
+ BOOL mHassRGBTexture;
+ BOOL mHassRGBFramebuffer;
// Vendor-specific extensions
BOOL mIsATI;
@@ -125,6 +129,11 @@ public:
BOOL mATIOffsetVerticalLines;
BOOL mATIOldDriver;
+#if LL_DARWIN
+ // Needed to distinguish problem cards on older Macs that break with Materials
+ BOOL mIsMobileGF;
+#endif
+
// Whether this version of GL is good enough for SL to use
BOOL mHasRequirements;
@@ -141,10 +150,12 @@ public:
S32 mGLSLVersionMajor;
S32 mGLSLVersionMinor;
std::string mDriverVersionVendorString;
+ std::string mGLVersionString;
S32 mVRAM; // VRAM in MB
S32 mGLMaxVertexRange;
S32 mGLMaxIndexRange;
+ S32 mGLMaxTextureSize;
void getPixelFormat(); // Get the best pixel format
@@ -417,13 +428,42 @@ public:
virtual void updateGL() = 0;
};
+const U32 FENCE_WAIT_TIME_NANOSECONDS = 1000; //1 ms
+
+class LLGLFence
+{
+public:
+ virtual ~LLGLFence()
+ {
+ }
+
+ virtual void placeFence() = 0;
+ virtual bool isCompleted() = 0;
+ virtual void wait() = 0;
+};
+
+class LLGLSyncFence : public LLGLFence
+{
+public:
+#ifdef GL_ARB_sync
+ GLsync mSync;
+#endif
+
+ LLGLSyncFence();
+ virtual ~LLGLSyncFence();
+
+ void placeFence();
+ bool isCompleted();
+ void wait();
+};
+
extern LLMatrix4 gGLObliqueProjectionInverse;
#include "llglstates.h"
void init_glstates();
-void parse_gl_version( S32* major, S32* minor, S32* release, std::string* vendor_specific );
+void parse_gl_version( S32* major, S32* minor, S32* release, std::string* vendor_specific, std::string* version_string );
extern BOOL gClothRipple;
extern BOOL gHeadlessClient;
diff --git a/indra/llrender/llgldbg.cpp b/indra/llrender/llgldbg.cpp
index 4b68194db3..4b68194db3 100644..100755
--- a/indra/llrender/llgldbg.cpp
+++ b/indra/llrender/llgldbg.cpp
diff --git a/indra/llrender/llgldbg.h b/indra/llrender/llgldbg.h
index 963579cb82..963579cb82 100644..100755
--- a/indra/llrender/llgldbg.h
+++ b/indra/llrender/llgldbg.h
diff --git a/indra/llrender/llglheaders.h b/indra/llrender/llglheaders.h
index d61ec707f0..5a80a8faa4 100644..100755
--- a/indra/llrender/llglheaders.h
+++ b/indra/llrender/llglheaders.h
@@ -116,6 +116,11 @@ extern PFNGLGETQUERYIVARBPROC glGetQueryivARB;
extern PFNGLGETQUERYOBJECTIVARBPROC glGetQueryObjectivARB;
extern PFNGLGETQUERYOBJECTUIVARBPROC glGetQueryObjectuivARB;
+// GL_ARB_timer_query
+extern PFNGLQUERYCOUNTERPROC glQueryCounter;
+extern PFNGLGETQUERYOBJECTI64VPROC glGetQueryObjecti64v;
+extern PFNGLGETQUERYOBJECTUI64VPROC glGetQueryObjectui64v;
+
// GL_ARB_point_parameters
extern PFNGLPOINTPARAMETERFARBPROC glPointParameterfARB;
extern PFNGLPOINTPARAMETERFVARBPROC glPointParameterfvARB;
@@ -378,6 +383,11 @@ extern PFNGLGETQUERYIVARBPROC glGetQueryivARB;
extern PFNGLGETQUERYOBJECTIVARBPROC glGetQueryObjectivARB;
extern PFNGLGETQUERYOBJECTUIVARBPROC glGetQueryObjectuivARB;
+// GL_ARB_timer_query
+extern PFNGLQUERYCOUNTERPROC glQueryCounter;
+extern PFNGLGETQUERYOBJECTI64VPROC glGetQueryObjecti64v;
+extern PFNGLGETQUERYOBJECTUI64VPROC glGetQueryObjectui64v;
+
// GL_ARB_point_parameters
extern PFNGLPOINTPARAMETERFARBPROC glPointParameterfARB;
extern PFNGLPOINTPARAMETERFVARBPROC glPointParameterfvARB;
@@ -528,6 +538,14 @@ extern PFNGLTEXIMAGE3DMULTISAMPLEPROC glTexImage3DMultisample;
extern PFNGLGETMULTISAMPLEFVPROC glGetMultisamplefv;
extern PFNGLSAMPLEMASKIPROC glSampleMaski;
+//transform feedback (4.0 core)
+extern PFNGLBEGINTRANSFORMFEEDBACKPROC glBeginTransformFeedback;
+extern PFNGLENDTRANSFORMFEEDBACKPROC glEndTransformFeedback;
+extern PFNGLTRANSFORMFEEDBACKVARYINGSPROC glTransformFeedbackVaryings;
+extern PFNGLBINDBUFFERRANGEPROC glBindBufferRange;
+extern PFNGLBINDBUFFERBASEPROC glBindBufferBase;
+
+
#elif LL_WINDOWS
//----------------------------------------------------------------------------
// LL_WINDOWS
@@ -612,6 +630,12 @@ extern PFNGLGETQUERYIVARBPROC glGetQueryivARB;
extern PFNGLGETQUERYOBJECTIVARBPROC glGetQueryObjectivARB;
extern PFNGLGETQUERYOBJECTUIVARBPROC glGetQueryObjectuivARB;
+// GL_ARB_timer_query
+extern PFNGLQUERYCOUNTERPROC glQueryCounter;
+extern PFNGLGETQUERYOBJECTI64VPROC glGetQueryObjecti64v;
+extern PFNGLGETQUERYOBJECTUI64VPROC glGetQueryObjectui64v;
+
+
// GL_ARB_point_parameters
extern PFNGLPOINTPARAMETERFARBPROC glPointParameterfARB;
extern PFNGLPOINTPARAMETERFVARBPROC glPointParameterfvARB;
@@ -759,6 +783,13 @@ extern PFNGLTEXIMAGE3DMULTISAMPLEPROC glTexImage3DMultisample;
extern PFNGLGETMULTISAMPLEFVPROC glGetMultisamplefv;
extern PFNGLSAMPLEMASKIPROC glSampleMaski;
+//transform feedback (4.0 core)
+extern PFNGLBEGINTRANSFORMFEEDBACKPROC glBeginTransformFeedback;
+extern PFNGLENDTRANSFORMFEEDBACKPROC glEndTransformFeedback;
+extern PFNGLTRANSFORMFEEDBACKVARYINGSPROC glTransformFeedbackVaryings;
+extern PFNGLBINDBUFFERRANGEPROC glBindBufferRange;
+extern PFNGLBINDBUFFERBASEPROC glBindBufferBase;
+
//GL_ARB_debug_output
extern PFNGLDEBUGMESSAGECONTROLARBPROC glDebugMessageControlARB;
extern PFNGLDEBUGMESSAGEINSERTARBPROC glDebugMessageInsertARB;
@@ -980,7 +1011,7 @@ extern void glGetBufferPointervARB (GLenum, GLenum, GLvoid* *);
}
#endif
-#include <AGL/gl.h>
+#include <OpenGL/gl.h>
#endif // LL_MESA / LL_WINDOWS / LL_DARWIN
diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp
index 4b7e639aed..35620bb656 100644..100755
--- a/indra/llrender/llglslshader.cpp
+++ b/indra/llrender/llglslshader.cpp
@@ -53,6 +53,12 @@ GLhandleARB LLGLSLShader::sCurBoundShader = 0;
LLGLSLShader* LLGLSLShader::sCurBoundShaderPtr = NULL;
S32 LLGLSLShader::sIndexedTextureChannels = 0;
bool LLGLSLShader::sNoFixedFunction = false;
+bool LLGLSLShader::sProfileEnabled = false;
+std::set<LLGLSLShader*> LLGLSLShader::sInstances;
+U64 LLGLSLShader::sTotalTimeElapsed = 0;
+U32 LLGLSLShader::sTotalTrianglesDrawn = 0;
+U64 LLGLSLShader::sTotalSamplesDrawn = 0;
+U32 LLGLSLShader::sTotalDrawCalls = 0;
//UI shader -- declared here so llui_libtest will link properly
LLGLSLShader gUIProgram;
@@ -87,19 +93,240 @@ LLShaderFeatures::LLShaderFeatures()
//===============================
// LLGLSL Shader implementation
//===============================
+
+//static
+void LLGLSLShader::initProfile()
+{
+ sProfileEnabled = true;
+ sTotalTimeElapsed = 0;
+ sTotalTrianglesDrawn = 0;
+ sTotalSamplesDrawn = 0;
+ sTotalDrawCalls = 0;
+
+ for (std::set<LLGLSLShader*>::iterator iter = sInstances.begin(); iter != sInstances.end(); ++iter)
+ {
+ (*iter)->clearStats();
+ }
+}
+
+
+struct LLGLSLShaderCompareTimeElapsed
+{
+ bool operator()(const LLGLSLShader* const& lhs, const LLGLSLShader* const& rhs)
+ {
+ return lhs->mTimeElapsed < rhs->mTimeElapsed;
+ }
+};
+
+//static
+void LLGLSLShader::finishProfile()
+{
+ sProfileEnabled = false;
+
+ std::vector<LLGLSLShader*> sorted;
+
+ for (std::set<LLGLSLShader*>::iterator iter = sInstances.begin(); iter != sInstances.end(); ++iter)
+ {
+ sorted.push_back(*iter);
+ }
+
+ std::sort(sorted.begin(), sorted.end(), LLGLSLShaderCompareTimeElapsed());
+
+ for (std::vector<LLGLSLShader*>::iterator iter = sorted.begin(); iter != sorted.end(); ++iter)
+ {
+ (*iter)->dumpStats();
+ }
+
+ llinfos << "-----------------------------------" << llendl;
+ llinfos << "Total rendering time: " << llformat("%.4f ms", sTotalTimeElapsed/1000000.f) << llendl;
+ llinfos << "Total samples drawn: " << llformat("%.4f million", sTotalSamplesDrawn/1000000.f) << llendl;
+ llinfos << "Total triangles drawn: " << llformat("%.3f million", sTotalTrianglesDrawn/1000000.f) << llendl;
+}
+
+void LLGLSLShader::clearStats()
+{
+ mTrianglesDrawn = 0;
+ mTimeElapsed = 0;
+ mSamplesDrawn = 0;
+ mDrawCalls = 0;
+ mTextureStateFetched = false;
+ mTextureMagFilter.clear();
+ mTextureMinFilter.clear();
+}
+
+void LLGLSLShader::dumpStats()
+{
+ if (mDrawCalls > 0)
+ {
+ llinfos << "=============================================" << llendl;
+ llinfos << mName << llendl;
+ for (U32 i = 0; i < mShaderFiles.size(); ++i)
+ {
+ llinfos << mShaderFiles[i].first << llendl;
+ }
+ for (U32 i = 0; i < mTexture.size(); ++i)
+ {
+ GLint idx = mTexture[i];
+
+ if (idx >= 0)
+ {
+ GLint uniform_idx = getUniformLocation(i);
+ llinfos << mUniformNameMap[uniform_idx] << " - " << std::hex << mTextureMagFilter[i] << "/" << mTextureMinFilter[i] << std::dec << llendl;
+ }
+ }
+ llinfos << "=============================================" << llendl;
+
+ F32 ms = mTimeElapsed/1000000.f;
+ F32 seconds = ms/1000.f;
+
+ F32 pct_tris = (F32) mTrianglesDrawn/(F32)sTotalTrianglesDrawn*100.f;
+ F32 tris_sec = (F32) (mTrianglesDrawn/1000000.0);
+ tris_sec /= seconds;
+
+ F32 pct_samples = (F32) ((F64)mSamplesDrawn/(F64)sTotalSamplesDrawn)*100.f;
+ F32 samples_sec = (F32) mSamplesDrawn/1000000000.0;
+ samples_sec /= seconds;
+
+ F32 pct_calls = (F32) mDrawCalls/(F32)sTotalDrawCalls*100.f;
+ U32 avg_batch = mTrianglesDrawn/mDrawCalls;
+
+ llinfos << "Triangles Drawn: " << mTrianglesDrawn << " " << llformat("(%.2f pct of total, %.3f million/sec)", pct_tris, tris_sec ) << llendl;
+ llinfos << "Draw Calls: " << mDrawCalls << " " << llformat("(%.2f pct of total, avg %d tris/call)", pct_calls, avg_batch) << llendl;
+ llinfos << "SamplesDrawn: " << mSamplesDrawn << " " << llformat("(%.2f pct of total, %.3f billion/sec)", pct_samples, samples_sec) << llendl;
+ llinfos << "Time Elapsed: " << mTimeElapsed << " " << llformat("(%.2f pct of total, %.5f ms)\n", (F32) ((F64)mTimeElapsed/(F64)sTotalTimeElapsed)*100.f, ms) << llendl;
+ }
+}
+
+//static
+void LLGLSLShader::startProfile()
+{
+ if (sProfileEnabled && sCurBoundShaderPtr)
+ {
+ sCurBoundShaderPtr->placeProfileQuery();
+ }
+
+}
+
+//static
+void LLGLSLShader::stopProfile(U32 count, U32 mode)
+{
+ if (sProfileEnabled)
+ {
+ sCurBoundShaderPtr->readProfileQuery(count, mode);
+ }
+}
+
+void LLGLSLShader::placeProfileQuery()
+{
+#if !LL_DARWIN
+ if (mTimerQuery == 0)
+ {
+ glGenQueriesARB(1, &mTimerQuery);
+ }
+
+ if (!mTextureStateFetched)
+ {
+ mTextureStateFetched = true;
+ mTextureMagFilter.resize(mTexture.size());
+ mTextureMinFilter.resize(mTexture.size());
+
+ U32 cur_active = gGL.getCurrentTexUnitIndex();
+
+ for (U32 i = 0; i < mTexture.size(); ++i)
+ {
+ GLint idx = mTexture[i];
+
+ if (idx >= 0)
+ {
+ gGL.getTexUnit(idx)->activate();
+
+ U32 mag = 0xFFFFFFFF;
+ U32 min = 0xFFFFFFFF;
+
+ U32 type = LLTexUnit::getInternalType(gGL.getTexUnit(idx)->getCurrType());
+
+ glGetTexParameteriv(type, GL_TEXTURE_MAG_FILTER, (GLint*) &mag);
+ glGetTexParameteriv(type, GL_TEXTURE_MIN_FILTER, (GLint*) &min);
+
+ mTextureMagFilter[i] = mag;
+ mTextureMinFilter[i] = min;
+ }
+ }
+
+ gGL.getTexUnit(cur_active)->activate();
+ }
+
+
+ glBeginQueryARB(GL_SAMPLES_PASSED, 1);
+ glBeginQueryARB(GL_TIME_ELAPSED, mTimerQuery);
+#endif
+}
+
+void LLGLSLShader::readProfileQuery(U32 count, U32 mode)
+{
+#if !LL_DARWIN
+ glEndQueryARB(GL_TIME_ELAPSED);
+ glEndQueryARB(GL_SAMPLES_PASSED);
+
+ U64 time_elapsed = 0;
+ glGetQueryObjectui64v(mTimerQuery, GL_QUERY_RESULT, &time_elapsed);
+
+ U64 samples_passed = 0;
+ glGetQueryObjectui64v(1, GL_QUERY_RESULT, &samples_passed);
+
+ sTotalTimeElapsed += time_elapsed;
+ mTimeElapsed += time_elapsed;
+
+ sTotalSamplesDrawn += samples_passed;
+ mSamplesDrawn += samples_passed;
+
+ U32 tri_count = 0;
+ switch (mode)
+ {
+ case LLRender::TRIANGLES: tri_count = count/3; break;
+ case LLRender::TRIANGLE_FAN: tri_count = count-2; break;
+ case LLRender::TRIANGLE_STRIP: tri_count = count-2; break;
+ default: tri_count = count; break; //points lines etc just use primitive count
+ }
+
+ mTrianglesDrawn += tri_count;
+ sTotalTrianglesDrawn += tri_count;
+
+ sTotalDrawCalls++;
+ mDrawCalls++;
+#endif
+}
+
+
+
LLGLSLShader::LLGLSLShader()
- : mProgramObject(0), mActiveTextureChannels(0), mShaderLevel(0), mShaderGroup(SG_DEFAULT), mUniformsDirty(FALSE)
+ : mProgramObject(0),
+ mAttributeMask(0),
+ mTotalUniformSize(0),
+ mActiveTextureChannels(0),
+ mShaderLevel(0),
+ mShaderGroup(SG_DEFAULT),
+ mUniformsDirty(FALSE),
+ mTimerQuery(0)
{
+
+}
+LLGLSLShader::~LLGLSLShader()
+{
+
}
void LLGLSLShader::unload()
{
+ sInstances.erase(this);
+
stop_glerror();
mAttribute.clear();
mTexture.clear();
mUniform.clear();
mShaderFiles.clear();
+ mDefines.clear();
if (mProgramObject)
{
@@ -128,9 +355,13 @@ void LLGLSLShader::unload()
stop_glerror();
}
-BOOL LLGLSLShader::createShader(vector<string> * attributes,
- vector<string> * uniforms)
+BOOL LLGLSLShader::createShader(std::vector<LLStaticHashedString> * attributes,
+ std::vector<LLStaticHashedString> * uniforms,
+ U32 varying_count,
+ const char** varyings)
{
+ sInstances.insert(this);
+
//reloading, reset matrix hash values
for (U32 i = 0; i < LLRender::NUM_MATRIX_MODES; ++i)
{
@@ -144,11 +375,16 @@ BOOL LLGLSLShader::createShader(vector<string> * attributes,
// Create program
mProgramObject = glCreateProgramObjectARB();
+#if LL_DARWIN
+ // work-around missing mix(vec3,vec3,bvec3)
+ mDefines["OLD_SELECT"] = "1";
+#endif
+
//compile new source
vector< pair<string,GLenum> >::iterator fileIter = mShaderFiles.begin();
for ( ; fileIter != mShaderFiles.end(); fileIter++ )
{
- GLhandleARB shaderhandle = LLShaderMgr::instance()->loadShaderFile((*fileIter).first, mShaderLevel, (*fileIter).second, mFeatures.mIndexedTextureChannels);
+ GLhandleARB shaderhandle = LLShaderMgr::instance()->loadShaderFile((*fileIter).first, mShaderLevel, (*fileIter).second, &mDefines, mFeatures.mIndexedTextureChannels);
LL_DEBUGS("ShaderLoading") << "SHADER FILE: " << (*fileIter).first << " mShaderLevel=" << mShaderLevel << LL_ENDL;
if (shaderhandle > 0)
{
@@ -172,6 +408,13 @@ BOOL LLGLSLShader::createShader(vector<string> * attributes,
mFeatures.mIndexedTextureChannels = llmin(mFeatures.mIndexedTextureChannels, 1);
}
+#ifdef GL_INTERLEAVED_ATTRIBS
+ if (varying_count > 0 && varyings)
+ {
+ glTransformFeedbackVaryings(mProgramObject, varying_count, varyings, GL_INTERLEAVED_ATTRIBS);
+ }
+#endif
+
// Map attributes and uniforms
if (success)
{
@@ -200,7 +443,8 @@ BOOL LLGLSLShader::createShader(vector<string> * attributes,
for (S32 i = 0; i < channel_count; i++)
{
- uniform1i(llformat("tex%d", i), i);
+ LLStaticHashedString uniName(llformat("tex%d", i));
+ uniform1i(uniName, i);
}
S32 cur_tex = channel_count; //adjust any texture channels that might have been overwritten
@@ -257,7 +501,7 @@ void LLGLSLShader::attachObjects(GLhandleARB* objects, S32 count)
}
}
-BOOL LLGLSLShader::mapAttributes(const vector<string> * attributes)
+BOOL LLGLSLShader::mapAttributes(const std::vector<LLStaticHashedString> * attributes)
{
//before linking, make sure reserved attributes always have consistent locations
for (U32 i = 0; i < LLShaderMgr::instance()->mReservedAttribs.size(); i++)
@@ -276,6 +520,8 @@ BOOL LLGLSLShader::mapAttributes(const vector<string> * attributes)
if (res)
{ //read back channel locations
+ mAttributeMask = 0;
+
//read back reserved channels first
for (U32 i = 0; i < LLShaderMgr::instance()->mReservedAttribs.size(); i++)
{
@@ -284,6 +530,7 @@ BOOL LLGLSLShader::mapAttributes(const vector<string> * attributes)
if (index != -1)
{
mAttribute[i] = index;
+ mAttributeMask |= 1 << i;
LL_DEBUGS("ShaderLoading") << "Attribute " << name << " assigned to channel " << index << LL_ENDL;
}
}
@@ -291,7 +538,7 @@ BOOL LLGLSLShader::mapAttributes(const vector<string> * attributes)
{
for (U32 i = 0; i < numAttributes; i++)
{
- const char* name = (*attributes)[i].c_str();
+ const char* name = (*attributes)[i].String().c_str();
S32 index = glGetAttribLocationARB(mProgramObject, name);
if (index != -1)
{
@@ -307,7 +554,7 @@ BOOL LLGLSLShader::mapAttributes(const vector<string> * attributes)
return FALSE;
}
-void LLGLSLShader::mapUniform(GLint index, const vector<string> * uniforms)
+void LLGLSLShader::mapUniform(GLint index, const vector<LLStaticHashedString> * uniforms)
{
if (index == -1)
{
@@ -316,11 +563,56 @@ void LLGLSLShader::mapUniform(GLint index, const vector<string> * uniforms)
GLenum type;
GLsizei length;
- GLint size;
+ GLint size = -1;
char name[1024]; /* Flawfinder: ignore */
name[0] = 0;
+
glGetActiveUniformARB(mProgramObject, index, 1024, &length, &size, &type, (GLcharARB *)name);
+#if !LL_DARWIN
+ if (size > 0)
+ {
+ switch(type)
+ {
+ case GL_FLOAT_VEC2: size *= 2; break;
+ case GL_FLOAT_VEC3: size *= 3; break;
+ case GL_FLOAT_VEC4: size *= 4; break;
+ case GL_DOUBLE: size *= 2; break;
+ case GL_DOUBLE_VEC2: size *= 2; break;
+ case GL_DOUBLE_VEC3: size *= 6; break;
+ case GL_DOUBLE_VEC4: size *= 8; break;
+ case GL_INT_VEC2: size *= 2; break;
+ case GL_INT_VEC3: size *= 3; break;
+ case GL_INT_VEC4: size *= 4; break;
+ case GL_UNSIGNED_INT_VEC2: size *= 2; break;
+ case GL_UNSIGNED_INT_VEC3: size *= 3; break;
+ case GL_UNSIGNED_INT_VEC4: size *= 4; break;
+ case GL_BOOL_VEC2: size *= 2; break;
+ case GL_BOOL_VEC3: size *= 3; break;
+ case GL_BOOL_VEC4: size *= 4; break;
+ case GL_FLOAT_MAT2: size *= 4; break;
+ case GL_FLOAT_MAT3: size *= 9; break;
+ case GL_FLOAT_MAT4: size *= 16; break;
+ case GL_FLOAT_MAT2x3: size *= 6; break;
+ case GL_FLOAT_MAT2x4: size *= 8; break;
+ case GL_FLOAT_MAT3x2: size *= 6; break;
+ case GL_FLOAT_MAT3x4: size *= 12; break;
+ case GL_FLOAT_MAT4x2: size *= 8; break;
+ case GL_FLOAT_MAT4x3: size *= 12; break;
+ case GL_DOUBLE_MAT2: size *= 8; break;
+ case GL_DOUBLE_MAT3: size *= 18; break;
+ case GL_DOUBLE_MAT4: size *= 32; break;
+ case GL_DOUBLE_MAT2x3: size *= 12; break;
+ case GL_DOUBLE_MAT2x4: size *= 16; break;
+ case GL_DOUBLE_MAT3x2: size *= 12; break;
+ case GL_DOUBLE_MAT3x4: size *= 24; break;
+ case GL_DOUBLE_MAT4x2: size *= 16; break;
+ case GL_DOUBLE_MAT4x3: size *= 24; break;
+ }
+ mTotalUniformSize += size;
+ }
+#endif
+
S32 location = glGetUniformLocationARB(mProgramObject, name);
if (location != -1)
{
@@ -332,7 +624,10 @@ void LLGLSLShader::mapUniform(GLint index, const vector<string> * uniforms)
is_array[0] = 0;
}
- mUniformMap[name] = location;
+ LLStaticHashedString hashedName(name);
+ mUniformNameMap[location] = name;
+ mUniformMap[hashedName] = location;
+
LL_DEBUGS("ShaderLoading") << "Uniform " << name << " is at location " << location << LL_ENDL;
//find the index of this uniform
@@ -353,7 +648,7 @@ void LLGLSLShader::mapUniform(GLint index, const vector<string> * uniforms)
for (U32 i = 0; i < uniforms->size(); i++)
{
if ( (mUniform[i+LLShaderMgr::instance()->mReservedUniforms.size()] == -1)
- && ((*uniforms)[i] == name))
+ && ((*uniforms)[i].String() == name))
{
//found it
mUniform[i+LLShaderMgr::instance()->mReservedUniforms.size()] = location;
@@ -363,11 +658,21 @@ void LLGLSLShader::mapUniform(GLint index, const vector<string> * uniforms)
}
}
}
- }
+}
+
+void LLGLSLShader::addPermutation(std::string name, std::string value)
+{
+ mDefines[name] = value;
+}
+
+void LLGLSLShader::removePermutation(std::string name)
+{
+ mDefines[name].erase();
+}
GLint LLGLSLShader::mapUniformTextureChannel(GLint location, GLenum type)
{
- if (type >= GL_SAMPLER_1D_ARB && type <= GL_SAMPLER_2D_RECT_SHADOW_ARB ||
+ if ((type >= GL_SAMPLER_1D_ARB && type <= GL_SAMPLER_2D_RECT_SHADOW_ARB) ||
type == GL_SAMPLER_2D_MULTISAMPLE)
{ //this here is a texture
glUniform1iARB(location, mActiveTextureChannels);
@@ -377,13 +682,15 @@ GLint LLGLSLShader::mapUniformTextureChannel(GLint location, GLenum type)
return -1;
}
-BOOL LLGLSLShader::mapUniforms(const vector<string> * uniforms)
+BOOL LLGLSLShader::mapUniforms(const vector<LLStaticHashedString> * uniforms)
{
BOOL res = TRUE;
+ mTotalUniformSize = 0;
mActiveTextureChannels = 0;
mUniform.clear();
mUniformMap.clear();
+ mUniformNameMap.clear();
mTexture.clear();
mValue.clear();
//initialize arrays
@@ -404,6 +711,7 @@ BOOL LLGLSLShader::mapUniforms(const vector<string> * uniforms)
unbind();
+ LL_DEBUGS("ShaderLoading") << "Total Uniform Size: " << mTotalUniformSize << llendl;
return res;
}
@@ -462,6 +770,58 @@ void LLGLSLShader::bindNoShader(void)
}
}
+S32 LLGLSLShader::bindTexture(const std::string &uniform, LLTexture *texture, LLTexUnit::eTextureType mode)
+{
+ S32 channel = 0;
+ channel = getUniformLocation(uniform);
+
+ return bindTexture(channel, texture, mode);
+}
+
+S32 LLGLSLShader::bindTexture(S32 uniform, LLTexture *texture, LLTexUnit::eTextureType mode)
+{
+ if (uniform < 0 || uniform >= (S32)mTexture.size())
+ {
+ UNIFORM_ERRS << "Uniform out of range: " << uniform << LL_ENDL;
+ return -1;
+ }
+
+ uniform = mTexture[uniform];
+
+ if (uniform > -1)
+ {
+ gGL.getTexUnit(uniform)->bind(texture, mode);
+ }
+
+ return uniform;
+}
+
+S32 LLGLSLShader::unbindTexture(const std::string &uniform, LLTexUnit::eTextureType mode)
+{
+ S32 channel = 0;
+ channel = getUniformLocation(uniform);
+
+ return unbindTexture(channel);
+}
+
+S32 LLGLSLShader::unbindTexture(S32 uniform, LLTexUnit::eTextureType mode)
+{
+ if (uniform < 0 || uniform >= (S32)mTexture.size())
+ {
+ UNIFORM_ERRS << "Uniform out of range: " << uniform << LL_ENDL;
+ return -1;
+ }
+
+ uniform = mTexture[uniform];
+
+ if (uniform > -1)
+ {
+ gGL.getTexUnit(uniform)->unbind(mode);
+ }
+
+ return uniform;
+}
+
S32 LLGLSLShader::enableTexture(S32 uniform, LLTexUnit::eTextureType mode)
{
if (uniform < 0 || uniform >= (S32)mTexture.size())
@@ -784,18 +1144,18 @@ void LLGLSLShader::uniformMatrix4fv(U32 index, U32 count, GLboolean transpose, c
}
}
-GLint LLGLSLShader::getUniformLocation(const string& uniform)
+GLint LLGLSLShader::getUniformLocation(const LLStaticHashedString& uniform)
{
GLint ret = -1;
if (mProgramObject > 0)
{
- std::map<string, GLint>::iterator iter = mUniformMap.find(uniform);
+ LLStaticStringTable<GLint>::iterator iter = mUniformMap.find(uniform);
if (iter != mUniformMap.end())
{
if (gDebugGL)
{
stop_glerror();
- if (iter->second != glGetUniformLocationARB(mProgramObject, uniform.c_str()))
+ if (iter->second != glGetUniformLocationARB(mProgramObject, uniform.String().c_str()))
{
llerrs << "Uniform does not match." << llendl;
}
@@ -832,7 +1192,7 @@ GLint LLGLSLShader::getAttribLocation(U32 attrib)
}
}
-void LLGLSLShader::uniform1i(const string& uniform, GLint v)
+void LLGLSLShader::uniform1i(const LLStaticHashedString& uniform, GLint v)
{
GLint location = getUniformLocation(uniform);
@@ -848,72 +1208,73 @@ void LLGLSLShader::uniform1i(const string& uniform, GLint v)
}
}
-void LLGLSLShader::uniform1f(const string& uniform, GLfloat v)
+void LLGLSLShader::uniform2i(const LLStaticHashedString& uniform, GLint i, GLint j)
{
GLint location = getUniformLocation(uniform);
if (location >= 0)
{
std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
- LLVector4 vec(v,0.f,0.f,0.f);
+ LLVector4 vec(i,j,0.f,0.f);
if (iter == mValue.end() || shouldChange(iter->second,vec))
{
- glUniform1fARB(location, v);
+ glUniform2iARB(location, i, j);
mValue[location] = vec;
}
}
}
-void LLGLSLShader::uniform2f(const string& uniform, GLfloat x, GLfloat y)
+
+void LLGLSLShader::uniform1f(const LLStaticHashedString& uniform, GLfloat v)
{
GLint location = getUniformLocation(uniform);
if (location >= 0)
{
std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
- LLVector4 vec(x,y,0.f,0.f);
+ LLVector4 vec(v,0.f,0.f,0.f);
if (iter == mValue.end() || shouldChange(iter->second,vec))
{
- glUniform2fARB(location, x,y);
+ glUniform1fARB(location, v);
mValue[location] = vec;
}
}
-
}
-void LLGLSLShader::uniform3f(const string& uniform, GLfloat x, GLfloat y, GLfloat z)
+void LLGLSLShader::uniform2f(const LLStaticHashedString& uniform, GLfloat x, GLfloat y)
{
GLint location = getUniformLocation(uniform);
if (location >= 0)
{
std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
- LLVector4 vec(x,y,z,0.f);
+ LLVector4 vec(x,y,0.f,0.f);
if (iter == mValue.end() || shouldChange(iter->second,vec))
{
- glUniform3fARB(location, x,y,z);
+ glUniform2fARB(location, x,y);
mValue[location] = vec;
}
}
+
}
-void LLGLSLShader::uniform4f(const string& uniform, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+void LLGLSLShader::uniform3f(const LLStaticHashedString& uniform, GLfloat x, GLfloat y, GLfloat z)
{
GLint location = getUniformLocation(uniform);
-
+
if (location >= 0)
{
std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
- LLVector4 vec(x,y,z,w);
+ LLVector4 vec(x,y,z,0.f);
if (iter == mValue.end() || shouldChange(iter->second,vec))
{
- glUniform4fARB(location, x,y,z,w);
+ glUniform3fARB(location, x,y,z);
mValue[location] = vec;
}
}
}
-void LLGLSLShader::uniform1fv(const string& uniform, U32 count, const GLfloat* v)
+void LLGLSLShader::uniform1fv(const LLStaticHashedString& uniform, U32 count, const GLfloat* v)
{
GLint location = getUniformLocation(uniform);
@@ -929,7 +1290,7 @@ void LLGLSLShader::uniform1fv(const string& uniform, U32 count, const GLfloat* v
}
}
-void LLGLSLShader::uniform2fv(const string& uniform, U32 count, const GLfloat* v)
+void LLGLSLShader::uniform2fv(const LLStaticHashedString& uniform, U32 count, const GLfloat* v)
{
GLint location = getUniformLocation(uniform);
@@ -945,7 +1306,7 @@ void LLGLSLShader::uniform2fv(const string& uniform, U32 count, const GLfloat* v
}
}
-void LLGLSLShader::uniform3fv(const string& uniform, U32 count, const GLfloat* v)
+void LLGLSLShader::uniform3fv(const LLStaticHashedString& uniform, U32 count, const GLfloat* v)
{
GLint location = getUniformLocation(uniform);
@@ -961,7 +1322,7 @@ void LLGLSLShader::uniform3fv(const string& uniform, U32 count, const GLfloat* v
}
}
-void LLGLSLShader::uniform4fv(const string& uniform, U32 count, const GLfloat* v)
+void LLGLSLShader::uniform4fv(const LLStaticHashedString& uniform, U32 count, const GLfloat* v)
{
GLint location = getUniformLocation(uniform);
@@ -979,27 +1340,7 @@ void LLGLSLShader::uniform4fv(const string& uniform, U32 count, const GLfloat* v
}
}
-void LLGLSLShader::uniformMatrix2fv(const string& uniform, U32 count, GLboolean transpose, const GLfloat* v)
-{
- GLint location = getUniformLocation(uniform);
-
- if (location >= 0)
- {
- glUniformMatrix2fvARB(location, count, transpose, v);
- }
-}
-
-void LLGLSLShader::uniformMatrix3fv(const string& uniform, U32 count, GLboolean transpose, const GLfloat* v)
-{
- GLint location = getUniformLocation(uniform);
-
- if (location >= 0)
- {
- glUniformMatrix3fvARB(location, count, transpose, v);
- }
-}
-
-void LLGLSLShader::uniformMatrix4fv(const string& uniform, U32 count, GLboolean transpose, const GLfloat* v)
+void LLGLSLShader::uniformMatrix4fv(const LLStaticHashedString& uniform, U32 count, GLboolean transpose, const GLfloat* v)
{
GLint location = getUniformLocation(uniform);
diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h
index 7873fe3c4e..7b2f5f04c2 100644..100755
--- a/indra/llrender/llglslshader.h
+++ b/indra/llrender/llglslshader.h
@@ -29,6 +29,7 @@
#include "llgl.h"
#include "llrender.h"
+#include "llstaticstringtable.h"
class LLShaderFeatures
{
@@ -67,22 +68,39 @@ public:
SG_WATER
};
+ static std::set<LLGLSLShader*> sInstances;
+ static bool sProfileEnabled;
+
LLGLSLShader();
+ ~LLGLSLShader();
static GLhandleARB sCurBoundShader;
static LLGLSLShader* sCurBoundShaderPtr;
static S32 sIndexedTextureChannels;
static bool sNoFixedFunction;
+ static void initProfile();
+ static void finishProfile();
+
+ static void startProfile();
+ static void stopProfile(U32 count, U32 mode);
+
void unload();
- BOOL createShader(std::vector<std::string> * attributes,
- std::vector<std::string> * uniforms);
+ void clearStats();
+ void dumpStats();
+ void placeProfileQuery();
+ void readProfileQuery(U32 count, U32 mode);
+
+ BOOL createShader(std::vector<LLStaticHashedString> * attributes,
+ std::vector<LLStaticHashedString> * uniforms,
+ U32 varying_count = 0,
+ const char** varyings = NULL);
BOOL attachObject(std::string object);
void attachObject(GLhandleARB object);
void attachObjects(GLhandleARB* objects = NULL, S32 count = 0);
- BOOL mapAttributes(const std::vector<std::string> * attributes);
- BOOL mapUniforms(const std::vector<std::string> * uniforms);
- void mapUniform(GLint index, const std::vector<std::string> * uniforms);
+ BOOL mapAttributes(const std::vector<LLStaticHashedString> * attributes);
+ BOOL mapUniforms(const std::vector<LLStaticHashedString> *);
+ void mapUniform(GLint index, const std::vector<LLStaticHashedString> *);
void uniform1i(U32 index, GLint i);
void uniform1f(U32 index, GLfloat v);
void uniform2f(U32 index, GLfloat x, GLfloat y);
@@ -93,40 +111,48 @@ public:
void uniform2fv(U32 index, U32 count, const GLfloat* v);
void uniform3fv(U32 index, U32 count, const GLfloat* v);
void uniform4fv(U32 index, U32 count, const GLfloat* v);
- void uniform1i(const std::string& uniform, GLint i);
- void uniform1f(const std::string& uniform, GLfloat v);
- void uniform2f(const std::string& uniform, GLfloat x, GLfloat y);
- void uniform3f(const std::string& uniform, GLfloat x, GLfloat y, GLfloat z);
- void uniform4f(const std::string& uniform, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
- void uniform1iv(const std::string& uniform, U32 count, const GLint* i);
- void uniform1fv(const std::string& uniform, U32 count, const GLfloat* v);
- void uniform2fv(const std::string& uniform, U32 count, const GLfloat* v);
- void uniform3fv(const std::string& uniform, U32 count, const GLfloat* v);
- void uniform4fv(const std::string& uniform, U32 count, const GLfloat* v);
+ void uniform2i(const LLStaticHashedString& uniform, GLint i, GLint j);
void uniformMatrix2fv(U32 index, U32 count, GLboolean transpose, const GLfloat *v);
void uniformMatrix3fv(U32 index, U32 count, GLboolean transpose, const GLfloat *v);
void uniformMatrix4fv(U32 index, U32 count, GLboolean transpose, const GLfloat *v);
- void uniformMatrix2fv(const std::string& uniform, U32 count, GLboolean transpose, const GLfloat *v);
- void uniformMatrix3fv(const std::string& uniform, U32 count, GLboolean transpose, const GLfloat *v);
- void uniformMatrix4fv(const std::string& uniform, U32 count, GLboolean transpose, const GLfloat *v);
+ void uniform1i(const LLStaticHashedString& uniform, GLint i);
+ void uniform1f(const LLStaticHashedString& uniform, GLfloat v);
+ void uniform2f(const LLStaticHashedString& uniform, GLfloat x, GLfloat y);
+ void uniform3f(const LLStaticHashedString& uniform, GLfloat x, GLfloat y, GLfloat z);
+ void uniform1fv(const LLStaticHashedString& uniform, U32 count, const GLfloat* v);
+ void uniform2fv(const LLStaticHashedString& uniform, U32 count, const GLfloat* v);
+ void uniform3fv(const LLStaticHashedString& uniform, U32 count, const GLfloat* v);
+ void uniform4fv(const LLStaticHashedString& uniform, U32 count, const GLfloat* v);
+ void uniformMatrix4fv(const LLStaticHashedString& uniform, U32 count, GLboolean transpose, const GLfloat *v);
void setMinimumAlpha(F32 minimum);
void vertexAttrib4f(U32 index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
void vertexAttrib4fv(U32 index, GLfloat* v);
- GLint getUniformLocation(const std::string& uniform);
+ //GLint getUniformLocation(const std::string& uniform);
+ GLint getUniformLocation(const LLStaticHashedString& uniform);
GLint getUniformLocation(U32 index);
GLint getAttribLocation(U32 attrib);
GLint mapUniformTextureChannel(GLint location, GLenum type);
+ void addPermutation(std::string name, std::string value);
+ void removePermutation(std::string name);
+
//enable/disable texture channel for specified uniform
//if given texture uniform is active in the shader,
//the corresponding channel will be active upon return
//returns channel texture is enabled in from [0-MAX)
S32 enableTexture(S32 uniform, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE);
- S32 disableTexture(S32 uniform, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE);
+ S32 disableTexture(S32 uniform, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE);
+
+ // bindTexture returns the texture unit we've bound the texture to.
+ // You can reuse the return value to unbind a texture when required.
+ S32 bindTexture(const std::string& uniform, LLTexture *texture, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE);
+ S32 bindTexture(S32 uniform, LLTexture *texture, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE);
+ S32 unbindTexture(const std::string& uniform, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE);
+ S32 unbindTexture(S32 uniform, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE);
BOOL link(BOOL suppress_errors = FALSE);
void bind();
@@ -140,10 +166,13 @@ public:
GLhandleARB mProgramObject;
std::vector<GLint> mAttribute; //lookup table of attribute enum to attribute channel
+ U32 mAttributeMask; //mask of which reserved attributes are set (lines up with LLVertexBuffer::getTypeMask())
std::vector<GLint> mUniform; //lookup table of uniform enum to uniform location
- std::map<std::string, GLint> mUniformMap; //lookup map of uniform name to uniform location
+ LLStaticStringTable<GLint> mUniformMap; //lookup map of uniform name to uniform location
+ std::map<GLint, std::string> mUniformNameMap; //lookup map of uniform location to uniform name
std::map<GLint, LLVector4> mValue; //lookup map of uniform location to last known value
std::vector<GLint> mTexture;
+ S32 mTotalUniformSize;
S32 mActiveTextureChannels;
S32 mShaderLevel;
S32 mShaderGroup;
@@ -151,12 +180,31 @@ public:
LLShaderFeatures mFeatures;
std::vector< std::pair< std::string, GLenum > > mShaderFiles;
std::string mName;
+ boost::unordered_map<std::string, std::string> mDefines;
+
+ //statistcis for profiling shader performance
+ U32 mTimerQuery;
+ U64 mTimeElapsed;
+ static U64 sTotalTimeElapsed;
+ U32 mTrianglesDrawn;
+ static U32 sTotalTrianglesDrawn;
+ U64 mSamplesDrawn;
+ static U64 sTotalSamplesDrawn;
+ U32 mDrawCalls;
+ static U32 sTotalDrawCalls;
+
+ bool mTextureStateFetched;
+ std::vector<U32> mTextureMagFilter;
+ std::vector<U32> mTextureMinFilter;
+
};
//UI shader (declared here so llui_libtest will link properly)
extern LLGLSLShader gUIProgram;
//output vec4(color.rgb,color.a*tex0[tc0].a)
extern LLGLSLShader gSolidColorProgram;
+//Alpha mask shader (declared here so llappearance can access properly)
+extern LLGLSLShader gAlphaMaskProgram;
#endif
diff --git a/indra/llrender/llglstates.h b/indra/llrender/llglstates.h
index e26aead676..0e2c3bcb44 100644..100755
--- a/indra/llrender/llglstates.h
+++ b/indra/llrender/llglstates.h
@@ -59,7 +59,6 @@ protected:
LLGLEnable mColorMaterial;
LLGLDisable mAlphaTest, mBlend, mCullFace, mDither, mFog,
mLineSmooth, mLineStipple, mNormalize, mPolygonSmooth,
- mTextureGenQ, mTextureGenR, mTextureGenS, mTextureGenT,
mGLMultisample;
public:
LLGLSDefault()
@@ -76,10 +75,6 @@ public:
mLineStipple(GL_LINE_STIPPLE),
mNormalize(GL_NORMALIZE),
mPolygonSmooth(GL_POLYGON_SMOOTH),
- mTextureGenQ(GL_TEXTURE_GEN_Q),
- mTextureGenR(GL_TEXTURE_GEN_R),
- mTextureGenS(GL_TEXTURE_GEN_S),
- mTextureGenT(GL_TEXTURE_GEN_T),
mGLMultisample(GL_MULTISAMPLE_ARB)
{ }
};
diff --git a/indra/llrender/llgltexture.cpp b/indra/llrender/llgltexture.cpp
new file mode 100644
index 0000000000..d06ed5e57b
--- /dev/null
+++ b/indra/llrender/llgltexture.cpp
@@ -0,0 +1,396 @@
+/**
+ * @file llgltexture.cpp
+ * @brief Opengl texture implementation
+ *
+ * $LicenseInfo:firstyear=2000&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+#include "linden_common.h"
+#include "llgltexture.h"
+
+
+// static
+S32 LLGLTexture::getTotalNumOfCategories()
+{
+ return MAX_GL_IMAGE_CATEGORY - (BOOST_HIGH - BOOST_SCULPTED) + 2 ;
+}
+
+// static
+//index starts from zero.
+S32 LLGLTexture::getIndexFromCategory(S32 category)
+{
+ return (category < BOOST_HIGH) ? category : category - (BOOST_HIGH - BOOST_SCULPTED) + 1 ;
+}
+
+//static
+S32 LLGLTexture::getCategoryFromIndex(S32 index)
+{
+ return (index < BOOST_HIGH) ? index : index + (BOOST_HIGH - BOOST_SCULPTED) - 1 ;
+}
+
+LLGLTexture::LLGLTexture(BOOL usemipmaps)
+{
+ init();
+ mUseMipMaps = usemipmaps;
+}
+
+LLGLTexture::LLGLTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps)
+{
+ init();
+ mFullWidth = width ;
+ mFullHeight = height ;
+ mUseMipMaps = usemipmaps;
+ mComponents = components ;
+ setTexelsPerImage();
+}
+
+LLGLTexture::LLGLTexture(const LLImageRaw* raw, BOOL usemipmaps)
+{
+ init();
+ mUseMipMaps = usemipmaps ;
+ // Create an empty image of the specified size and width
+ mGLTexturep = new LLImageGL(raw, usemipmaps) ;
+}
+
+LLGLTexture::~LLGLTexture()
+{
+ cleanup();
+}
+
+void LLGLTexture::init()
+{
+ mBoostLevel = LLGLTexture::BOOST_NONE;
+
+ mFullWidth = 0;
+ mFullHeight = 0;
+ mTexelsPerImage = 0 ;
+ mUseMipMaps = FALSE ;
+ mComponents = 0 ;
+
+ mTextureState = NO_DELETE ;
+ mDontDiscard = FALSE;
+ mNeedsGLTexture = FALSE ;
+}
+
+void LLGLTexture::cleanup()
+{
+ if(mGLTexturep)
+ {
+ mGLTexturep->cleanup();
+ }
+}
+
+// virtual
+void LLGLTexture::dump()
+{
+ if(mGLTexturep)
+ {
+ mGLTexturep->dump();
+ }
+}
+
+void LLGLTexture::setBoostLevel(S32 level)
+{
+ if(mBoostLevel != level)
+ {
+ mBoostLevel = level ;
+ if(mBoostLevel != LLGLTexture::BOOST_NONE)
+ {
+ setNoDelete() ;
+ }
+ }
+}
+
+void LLGLTexture::forceActive()
+{
+ mTextureState = ACTIVE ;
+}
+
+void LLGLTexture::setActive()
+{
+ if(mTextureState != NO_DELETE)
+ {
+ mTextureState = ACTIVE ;
+ }
+}
+
+//set the texture to stay in memory
+void LLGLTexture::setNoDelete()
+{
+ mTextureState = NO_DELETE ;
+}
+
+void LLGLTexture::generateGLTexture()
+{
+ if(mGLTexturep.isNull())
+ {
+ mGLTexturep = new LLImageGL(mFullWidth, mFullHeight, mComponents, mUseMipMaps) ;
+ }
+}
+
+LLImageGL* LLGLTexture::getGLTexture() const
+{
+ llassert(mGLTexturep.notNull()) ;
+
+ return mGLTexturep ;
+}
+
+BOOL LLGLTexture::createGLTexture()
+{
+ if(mGLTexturep.isNull())
+ {
+ generateGLTexture() ;
+ }
+
+ return mGLTexturep->createGLTexture() ;
+}
+
+BOOL LLGLTexture::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename, BOOL to_create, S32 category)
+{
+ llassert(mGLTexturep.notNull()) ;
+
+ BOOL ret = mGLTexturep->createGLTexture(discard_level, imageraw, usename, to_create, category) ;
+
+ if(ret)
+ {
+ mFullWidth = mGLTexturep->getCurrentWidth() ;
+ mFullHeight = mGLTexturep->getCurrentHeight() ;
+ mComponents = mGLTexturep->getComponents() ;
+ setTexelsPerImage();
+ }
+
+ return ret ;
+}
+
+void LLGLTexture::setExplicitFormat(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format, BOOL swap_bytes)
+{
+ llassert(mGLTexturep.notNull()) ;
+
+ mGLTexturep->setExplicitFormat(internal_format, primary_format, type_format, swap_bytes) ;
+}
+void LLGLTexture::setAddressMode(LLTexUnit::eTextureAddressMode mode)
+{
+ llassert(mGLTexturep.notNull()) ;
+ mGLTexturep->setAddressMode(mode) ;
+}
+void LLGLTexture::setFilteringOption(LLTexUnit::eTextureFilterOptions option)
+{
+ llassert(mGLTexturep.notNull()) ;
+ mGLTexturep->setFilteringOption(option) ;
+}
+
+//virtual
+S32 LLGLTexture::getWidth(S32 discard_level) const
+{
+ llassert(mGLTexturep.notNull()) ;
+ return mGLTexturep->getWidth(discard_level) ;
+}
+
+//virtual
+S32 LLGLTexture::getHeight(S32 discard_level) const
+{
+ llassert(mGLTexturep.notNull()) ;
+ return mGLTexturep->getHeight(discard_level) ;
+}
+
+S32 LLGLTexture::getMaxDiscardLevel() const
+{
+ llassert(mGLTexturep.notNull()) ;
+ return mGLTexturep->getMaxDiscardLevel() ;
+}
+S32 LLGLTexture::getDiscardLevel() const
+{
+ llassert(mGLTexturep.notNull()) ;
+ return mGLTexturep->getDiscardLevel() ;
+}
+S8 LLGLTexture::getComponents() const
+{
+ llassert(mGLTexturep.notNull()) ;
+
+ return mGLTexturep->getComponents() ;
+}
+
+LLGLuint LLGLTexture::getTexName() const
+{
+ llassert(mGLTexturep.notNull()) ;
+
+ return mGLTexturep->getTexName() ;
+}
+
+BOOL LLGLTexture::hasGLTexture() const
+{
+ if(mGLTexturep.notNull())
+ {
+ return mGLTexturep->getHasGLTexture() ;
+ }
+ return FALSE ;
+}
+
+BOOL LLGLTexture::getBoundRecently() const
+{
+ if(mGLTexturep.notNull())
+ {
+ return mGLTexturep->getBoundRecently() ;
+ }
+ return FALSE ;
+}
+
+LLTexUnit::eTextureType LLGLTexture::getTarget(void) const
+{
+ llassert(mGLTexturep.notNull()) ;
+ return mGLTexturep->getTarget() ;
+}
+
+BOOL LLGLTexture::setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height)
+{
+ llassert(mGLTexturep.notNull()) ;
+
+ return mGLTexturep->setSubImage(imageraw, x_pos, y_pos, width, height) ;
+}
+
+BOOL LLGLTexture::setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height)
+{
+ llassert(mGLTexturep.notNull()) ;
+
+ return mGLTexturep->setSubImage(datap, data_width, data_height, x_pos, y_pos, width, height) ;
+}
+
+void LLGLTexture::setGLTextureCreated (bool initialized)
+{
+ llassert(mGLTexturep.notNull()) ;
+
+ mGLTexturep->setGLTextureCreated (initialized) ;
+}
+
+void LLGLTexture::setCategory(S32 category)
+{
+ llassert(mGLTexturep.notNull()) ;
+
+ mGLTexturep->setCategory(category) ;
+}
+
+LLTexUnit::eTextureAddressMode LLGLTexture::getAddressMode(void) const
+{
+ llassert(mGLTexturep.notNull()) ;
+
+ return mGLTexturep->getAddressMode() ;
+}
+
+S32 LLGLTexture::getTextureMemory() const
+{
+ llassert(mGLTexturep.notNull()) ;
+
+ return mGLTexturep->mTextureMemory ;
+}
+
+LLGLenum LLGLTexture::getPrimaryFormat() const
+{
+ llassert(mGLTexturep.notNull()) ;
+
+ return mGLTexturep->getPrimaryFormat() ;
+}
+
+BOOL LLGLTexture::getIsAlphaMask() const
+{
+ llassert(mGLTexturep.notNull()) ;
+
+ return mGLTexturep->getIsAlphaMask() ;
+}
+
+BOOL LLGLTexture::getMask(const LLVector2 &tc)
+{
+ llassert(mGLTexturep.notNull()) ;
+
+ return mGLTexturep->getMask(tc) ;
+}
+
+F32 LLGLTexture::getTimePassedSinceLastBound()
+{
+ llassert(mGLTexturep.notNull()) ;
+
+ return mGLTexturep->getTimePassedSinceLastBound() ;
+}
+BOOL LLGLTexture::getMissed() const
+{
+ llassert(mGLTexturep.notNull()) ;
+
+ return mGLTexturep->getMissed() ;
+}
+
+BOOL LLGLTexture::isJustBound() const
+{
+ llassert(mGLTexturep.notNull()) ;
+
+ return mGLTexturep->isJustBound() ;
+}
+
+void LLGLTexture::forceUpdateBindStats(void) const
+{
+ llassert(mGLTexturep.notNull()) ;
+
+ return mGLTexturep->forceUpdateBindStats() ;
+}
+
+U32 LLGLTexture::getTexelsInAtlas() const
+{
+ llassert(mGLTexturep.notNull()) ;
+
+ return mGLTexturep->getTexelsInAtlas() ;
+}
+
+U32 LLGLTexture::getTexelsInGLTexture() const
+{
+ llassert(mGLTexturep.notNull()) ;
+
+ return mGLTexturep->getTexelsInGLTexture() ;
+}
+
+BOOL LLGLTexture::isGLTextureCreated() const
+{
+ llassert(mGLTexturep.notNull()) ;
+
+ return mGLTexturep->isGLTextureCreated() ;
+}
+
+S32 LLGLTexture::getDiscardLevelInAtlas() const
+{
+ llassert(mGLTexturep.notNull()) ;
+
+ return mGLTexturep->getDiscardLevelInAtlas() ;
+}
+
+void LLGLTexture::destroyGLTexture()
+{
+ if(mGLTexturep.notNull() && mGLTexturep->getHasGLTexture())
+ {
+ mGLTexturep->destroyGLTexture() ;
+ mTextureState = DELETED ;
+ }
+}
+
+void LLGLTexture::setTexelsPerImage()
+{
+ S32 fullwidth = llmin(mFullWidth,(S32)MAX_IMAGE_SIZE_DEFAULT);
+ S32 fullheight = llmin(mFullHeight,(S32)MAX_IMAGE_SIZE_DEFAULT);
+ mTexelsPerImage = (F32)fullwidth * fullheight;
+}
+
+
diff --git a/indra/llrender/llgltexture.h b/indra/llrender/llgltexture.h
new file mode 100644
index 0000000000..e69b322d60
--- /dev/null
+++ b/indra/llrender/llgltexture.h
@@ -0,0 +1,199 @@
+/**
+ * @file llglviewertexture.h
+ * @brief Object for managing opengl textures
+ *
+ * $LicenseInfo:firstyear=2012&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$
+ */
+
+
+#ifndef LL_GL_TEXTURE_H
+#define LL_GL_TEXTURE_H
+
+#include "lltexture.h"
+#include "llgl.h"
+
+class LLImageRaw;
+
+//
+//this the parent for the class LLViewerTexture
+//through the following virtual functions, the class LLViewerTexture can be reached from /llrender.
+//
+class LLGLTexture : public LLTexture
+{
+public:
+ enum
+ {
+ MAX_IMAGE_SIZE_DEFAULT = 1024,
+ INVALID_DISCARD_LEVEL = 0x7fff
+ };
+
+ enum EBoostLevel
+ {
+ BOOST_NONE = 0,
+ BOOST_AVATAR_BAKED ,
+ BOOST_AVATAR ,
+ BOOST_CLOUDS ,
+ BOOST_SCULPTED ,
+
+ BOOST_HIGH = 10,
+ BOOST_BUMP ,
+ BOOST_TERRAIN , // has to be high priority for minimap / low detail
+ BOOST_SELECTED ,
+ BOOST_AVATAR_BAKED_SELF ,
+ BOOST_AVATAR_SELF , // needed for baking avatar
+ BOOST_SUPER_HIGH , //textures higher than this need to be downloaded at the required resolution without delay.
+ BOOST_HUD ,
+ BOOST_ICON ,
+ BOOST_UI ,
+ BOOST_PREVIEW ,
+ BOOST_MAP ,
+ BOOST_MAP_VISIBLE ,
+ BOOST_MAX_LEVEL,
+
+ //other texture Categories
+ LOCAL = BOOST_MAX_LEVEL,
+ AVATAR_SCRATCH_TEX,
+ DYNAMIC_TEX,
+ MEDIA,
+ ATLAS,
+ OTHER,
+ MAX_GL_IMAGE_CATEGORY
+ };
+
+ typedef enum
+ {
+ DELETED = 0, //removed from memory
+ DELETION_CANDIDATE, //ready to be removed from memory
+ INACTIVE, //not be used for the last certain period (i.e., 30 seconds).
+ ACTIVE, //just being used, can become inactive if not being used for a certain time (10 seconds).
+ NO_DELETE = 99 //stay in memory, can not be removed.
+ } LLGLTextureState;
+
+ static S32 getTotalNumOfCategories() ;
+ static S32 getIndexFromCategory(S32 category) ;
+ static S32 getCategoryFromIndex(S32 index) ;
+
+protected:
+ virtual ~LLGLTexture();
+ LOG_CLASS(LLGLTexture);
+
+public:
+ LLGLTexture(BOOL usemipmaps = TRUE);
+ LLGLTexture(const LLImageRaw* raw, BOOL usemipmaps) ;
+ LLGLTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps) ;
+
+ virtual void dump(); // debug info to llinfos
+
+ virtual const LLUUID& getID() const = 0;
+
+ void setBoostLevel(S32 level);
+ S32 getBoostLevel() { return mBoostLevel; }
+
+ S32 getFullWidth() const { return mFullWidth; }
+ S32 getFullHeight() const { return mFullHeight; }
+
+ void generateGLTexture() ;
+ void destroyGLTexture() ;
+
+ //---------------------------------------------------------------------------------------------
+ //functions to access LLImageGL
+ //---------------------------------------------------------------------------------------------
+ /*virtual*/S32 getWidth(S32 discard_level = -1) const;
+ /*virtual*/S32 getHeight(S32 discard_level = -1) const;
+
+ BOOL hasGLTexture() const ;
+ LLGLuint getTexName() const ;
+ BOOL createGLTexture() ;
+ BOOL createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename = 0, BOOL to_create = TRUE, S32 category = LLGLTexture::OTHER);
+
+ void setFilteringOption(LLTexUnit::eTextureFilterOptions option);
+ void setExplicitFormat(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format = 0, BOOL swap_bytes = FALSE);
+ void setAddressMode(LLTexUnit::eTextureAddressMode mode);
+ BOOL setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height);
+ BOOL setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height);
+ void setGLTextureCreated (bool initialized);
+ void setCategory(S32 category) ;
+
+ LLTexUnit::eTextureAddressMode getAddressMode(void) const ;
+ S32 getMaxDiscardLevel() const;
+ S32 getDiscardLevel() const;
+ S8 getComponents() const;
+ BOOL getBoundRecently() const;
+ S32 getTextureMemory() const ;
+ LLGLenum getPrimaryFormat() const;
+ BOOL getIsAlphaMask() const ;
+ LLTexUnit::eTextureType getTarget(void) const ;
+ BOOL getMask(const LLVector2 &tc);
+ F32 getTimePassedSinceLastBound();
+ BOOL getMissed() const ;
+ BOOL isJustBound()const ;
+ void forceUpdateBindStats(void) const;
+
+ U32 getTexelsInAtlas() const ;
+ U32 getTexelsInGLTexture() const ;
+ BOOL isGLTextureCreated() const ;
+ S32 getDiscardLevelInAtlas() const ;
+ LLGLTextureState getTextureState() const { return mTextureState; }
+
+ //---------------------------------------------------------------------------------------------
+ //end of functions to access LLImageGL
+ //---------------------------------------------------------------------------------------------
+
+ //-----------------
+ /*virtual*/ void setActive() ;
+ void forceActive() ;
+ void setNoDelete() ;
+ void dontDiscard() { mDontDiscard = 1; mTextureState = NO_DELETE; }
+ BOOL getDontDiscard() const { return mDontDiscard; }
+ //-----------------
+
+private:
+ void cleanup();
+ void init();
+
+protected:
+ void setTexelsPerImage();
+
+ //note: do not make this function public.
+ /*virtual*/ LLImageGL* getGLTexture() const ;
+
+protected:
+ S32 mBoostLevel; // enum describing priority level
+ S32 mFullWidth;
+ S32 mFullHeight;
+ BOOL mUseMipMaps;
+ S8 mComponents;
+ F32 mTexelsPerImage; // Texels per image.
+ mutable S8 mNeedsGLTexture;
+
+ //GL texture
+ LLPointer<LLImageGL> mGLTexturep ;
+ S8 mDontDiscard; // Keep full res version of this image (for UI, etc)
+
+protected:
+ LLGLTextureState mTextureState ;
+
+
+};
+
+#endif // LL_GL_TEXTURE_H
+
diff --git a/indra/llrender/llgltypes.h b/indra/llrender/llgltypes.h
index 6c217ef727..6c217ef727 100644..100755
--- a/indra/llrender/llgltypes.h
+++ b/indra/llrender/llgltypes.h
diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp
index 78591ddd38..ab875141c5 100644..100755
--- a/indra/llrender/llimagegl.cpp
+++ b/indra/llrender/llimagegl.cpp
@@ -42,8 +42,11 @@
//----------------------------------------------------------------------------
const F32 MIN_TEXTURE_LIFETIME = 10.f;
+//which power of 2 is i?
+//assumes i is a power of 2 > 0
+U32 wpo2(U32 i);
+
//statics
-LLGLuint LLImageGL::sCurrentBoundTextures[MAX_GL_TEXTURE_UNITS] = { 0 };
U32 LLImageGL::sUniqueCount = 0;
U32 LLImageGL::sBindCount = 0;
@@ -51,12 +54,12 @@ S32 LLImageGL::sGlobalTextureMemoryInBytes = 0;
S32 LLImageGL::sBoundTextureMemoryInBytes = 0;
S32 LLImageGL::sCurBoundTextureMemory = 0;
S32 LLImageGL::sCount = 0;
-std::list<U32> LLImageGL::sDeadTextureList;
BOOL LLImageGL::sGlobalUseAnisotropic = FALSE;
F32 LLImageGL::sLastFrameTime = 0.f;
BOOL LLImageGL::sAllowReadBackRaw = FALSE ;
LLImageGL* LLImageGL::sDefaultGLTexture = NULL ;
+bool LLImageGL::sCompressTextures = false;
std::set<LLImageGL*> LLImageGL::sImageList;
@@ -65,19 +68,13 @@ std::set<LLImageGL*> LLImageGL::sImageList;
//****************************************************************************************************
//-----------------------
//debug use
-BOOL gAuditTexture = FALSE ;
-#define MAX_TEXTURE_LOG_SIZE 22 //2048 * 2048
-std::vector<S32> LLImageGL::sTextureLoadedCounter(MAX_TEXTURE_LOG_SIZE + 1) ;
-std::vector<S32> LLImageGL::sTextureBoundCounter(MAX_TEXTURE_LOG_SIZE + 1) ;
-std::vector<S32> LLImageGL::sTextureCurBoundCounter(MAX_TEXTURE_LOG_SIZE + 1) ;
S32 LLImageGL::sCurTexSizeBar = -1 ;
S32 LLImageGL::sCurTexPickSize = -1 ;
-LLPointer<LLImageGL> LLImageGL::sHighlightTexturep = NULL;
-S32 LLImageGL::sMaxCatagories = 1 ;
+S32 LLImageGL::sMaxCategories = 1 ;
+
+//optimization for when we don't need to calculate mIsMask
+BOOL LLImageGL::sSkipAnalyzeAlpha;
-std::vector<S32> LLImageGL::sTextureMemByCategory;
-std::vector<S32> LLImageGL::sTextureMemByCategoryBound ;
-std::vector<S32> LLImageGL::sTextureCurMemByCategoryBound ;
//------------------------
//****************************************************************************************************
//End for texture auditing use only
@@ -173,51 +170,14 @@ BOOL is_little_endian()
return (*c == 0x78) ;
}
//static
-void LLImageGL::initClass(S32 num_catagories)
+void LLImageGL::initClass(S32 num_catagories, BOOL skip_analyze_alpha /* = false */)
{
- sMaxCatagories = num_catagories ;
-
- sTextureMemByCategory.resize(sMaxCatagories);
- sTextureMemByCategoryBound.resize(sMaxCatagories) ;
- sTextureCurMemByCategoryBound.resize(sMaxCatagories) ;
+ sSkipAnalyzeAlpha = skip_analyze_alpha;
}
//static
void LLImageGL::cleanupClass()
{
- sTextureMemByCategory.clear() ;
- sTextureMemByCategoryBound.clear() ;
- sTextureCurMemByCategoryBound.clear() ;
-}
-
-//static
-void LLImageGL::setHighlightTexture(S32 category)
-{
- const S32 dim = 128;
- sHighlightTexturep = new LLImageGL() ;
- LLPointer<LLImageRaw> image_raw = new LLImageRaw(dim,dim,3);
- U8* data = image_raw->getData();
- for (S32 i = 0; i<dim; i++)
- {
- for (S32 j = 0; j<dim; j++)
- {
- const S32 border = 2;
- if (i<border || j<border || i>=(dim-border) || j>=(dim-border))
- {
- *data++ = 0xff;
- *data++ = 0xff;
- *data++ = 0xff;
- }
- else
- {
- *data++ = 0xff;
- *data++ = 0xff;
- *data++ = 0x00;
- }
- }
- }
- sHighlightTexturep->createGLTexture(0, image_raw, 0, TRUE, category);
- image_raw = NULL;
}
//static
@@ -279,37 +239,19 @@ S32 LLImageGL::dataFormatComponents(S32 dataformat)
//----------------------------------------------------------------------------
+static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE_STATS("Image Stats");
// static
void LLImageGL::updateStats(F32 current_time)
{
+ LLFastTimer t(FTM_IMAGE_UPDATE_STATS);
sLastFrameTime = current_time;
sBoundTextureMemoryInBytes = sCurBoundTextureMemory;
sCurBoundTextureMemory = 0;
-
- if(gAuditTexture)
- {
- for(U32 i = 0 ; i < sTextureCurBoundCounter.size() ; i++)
- {
- sTextureBoundCounter[i] = sTextureCurBoundCounter[i] ;
- sTextureCurBoundCounter[i] = 0 ;
- }
- for(U32 i = 0 ; i < sTextureCurMemByCategoryBound.size() ; i++)
- {
- sTextureMemByCategoryBound[i] = sTextureCurMemByCategoryBound[i] ;
- sTextureCurMemByCategoryBound[i] = 0 ;
- }
- }
}
//static
S32 LLImageGL::updateBoundTexMem(const S32 mem, const S32 ncomponents, S32 category)
{
- if(gAuditTexture && ncomponents > 0 && category > -1)
- {
- sTextureCurBoundCounter[getTextureCounterIndex(mem / ncomponents)]++ ;
- sTextureCurMemByCategoryBound[category] += mem ;
- }
-
LLImageGL::sCurBoundTextureMemory += mem ;
return LLImageGL::sCurBoundTextureMemory;
}
@@ -477,10 +419,13 @@ void LLImageGL::init(BOOL usemipmaps)
mDiscardLevelInAtlas = -1 ;
mTexelsInAtlas = 0 ;
mTexelsInGLTexture = 0 ;
+
+ mAllowCompression = true;
mTarget = GL_TEXTURE_2D;
mBindTarget = LLTexUnit::TT_TEXTURE;
mHasMipMaps = false;
+ mMipLevels = -1;
mIsResident = 0;
@@ -535,7 +480,7 @@ bool LLImageGL::checkSize(S32 width, S32 height)
return check_power_of_two(width) && check_power_of_two(height);
}
-void LLImageGL::setSize(S32 width, S32 height, S32 ncomponents)
+void LLImageGL::setSize(S32 width, S32 height, S32 ncomponents, S32 discard_level)
{
if (width != mWidth || height != mHeight || ncomponents != mComponents)
{
@@ -568,6 +513,11 @@ void LLImageGL::setSize(S32 width, S32 height, S32 ncomponents)
width >>= 1;
height >>= 1;
}
+
+ if(discard_level > 0)
+ {
+ mMaxDiscardLevel = llmax(mMaxDiscardLevel, (S8)discard_level);
+ }
}
else
{
@@ -663,16 +613,34 @@ void LLImageGL::setImage(const LLImageRaw* imageraw)
setImage(rawdata, FALSE);
}
+static LLFastTimer::DeclareTimer FTM_SET_IMAGE("setImage");
void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
{
+ LLFastTimer t(FTM_SET_IMAGE);
bool is_compressed = false;
if (mFormatPrimary >= GL_COMPRESSED_RGBA_S3TC_DXT1_EXT && mFormatPrimary <= GL_COMPRESSED_RGBA_S3TC_DXT5_EXT)
{
is_compressed = true;
}
-
+
+
+
+ if (mUseMipMaps)
+ {
+ //set has mip maps to true before binding image so tex parameters get set properly
+ gGL.getTexUnit(0)->unbind(mBindTarget);
+ mHasMipMaps = true;
+ mTexOptionsDirty = true;
+ setFilteringOption(LLTexUnit::TFO_ANISOTROPIC);
+ }
+ else
+ {
+ mHasMipMaps = false;
+ }
+
llverify(gGL.getTexUnit(0)->bind(this));
+
if (mUseMipMaps)
{
if (data_hasmips)
@@ -685,6 +653,9 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
S32 w = getWidth(d);
S32 h = getHeight(d);
S32 gl_level = d-mCurrentDiscardLevel;
+
+ mMipLevels = llmax(mMipLevels, gl_level);
+
if (d > mCurrentDiscardLevel)
{
data_in -= dataFormatBytes(mFormatPrimary, w, h); // see above comment
@@ -705,7 +676,7 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
stop_glerror();
}
- LLImageGL::setManualImage(mTarget, gl_level, mFormatInternal, w, h, mFormatPrimary, GL_UNSIGNED_BYTE, (GLvoid*)data_in);
+ LLImageGL::setManualImage(mTarget, gl_level, mFormatInternal, w, h, mFormatPrimary, GL_UNSIGNED_BYTE, (GLvoid*)data_in, mAllowCompression);
if (gl_level == 0)
{
analyzeAlpha(data_in, w, h);
@@ -727,10 +698,6 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
{
if (mAutoGenMips)
{
- if (!gGLManager.mHasFramebufferObject)
- {
- glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_GENERATE_MIPMAP_SGIS, TRUE);
- }
stop_glerror();
{
// LLFastTimer t2(FTM_TEMP4);
@@ -744,10 +711,20 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
S32 w = getWidth(mCurrentDiscardLevel);
S32 h = getHeight(mCurrentDiscardLevel);
+ mMipLevels = wpo2(llmax(w, h));
+
+ //use legacy mipmap generation mode (note: making this condional can cause rendering issues)
+ // -- but making it not conditional triggers deprecation warnings when core profile is enabled
+ // (some rendering issues while core profile is enabled are acceptable at this point in time)
+ if (!LLRender::sGLCoreProfile)
+ {
+ glTexParameteri(mTarget, GL_GENERATE_MIPMAP, GL_TRUE);
+ }
+
LLImageGL::setManualImage(mTarget, 0, mFormatInternal,
w, h,
mFormatPrimary, mFormatType,
- data_in);
+ data_in, mAllowCompression);
analyzeAlpha(data_in, w, h);
stop_glerror();
@@ -758,45 +735,67 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
glPixelStorei(GL_UNPACK_SWAP_BYTES, 0);
stop_glerror();
}
- }
- if (gGLManager.mHasFramebufferObject)
- {
- glGenerateMipmap(LLTexUnit::getInternalType(mBindTarget));
+ if (LLRender::sGLCoreProfile)
+ {
+ glGenerateMipmap(mTarget);
+ }
+ stop_glerror();
}
}
else
{
// Create mips by hand
- // about 30% faster than autogen on ATI 9800, 50% slower on nVidia 4800
// ~4x faster than gluBuild2DMipmaps
S32 width = getWidth(mCurrentDiscardLevel);
S32 height = getHeight(mCurrentDiscardLevel);
S32 nummips = mMaxDiscardLevel - mCurrentDiscardLevel + 1;
S32 w = width, h = height;
+
+
+ const U8* new_data = 0;
+ (void)new_data;
+
const U8* prev_mip_data = 0;
const U8* cur_mip_data = 0;
- S32 prev_mip_size = 0;
+#ifdef SHOW_ASSERT
S32 cur_mip_size = 0;
+#endif
+ mMipLevels = nummips;
+
for (int m=0; m<nummips; m++)
{
if (m==0)
{
cur_mip_data = data_in;
+#ifdef SHOW_ASSERT
cur_mip_size = width * height * mComponents;
+#endif
}
else
{
S32 bytes = w * h * mComponents;
+#ifdef SHOW_ASSERT
llassert(prev_mip_data);
- llassert(prev_mip_size == bytes*4);
+ llassert(cur_mip_size == bytes*4);
+#endif
U8* new_data = new U8[bytes];
+
+#ifdef SHOW_ASSERT
+ llassert(prev_mip_data);
+ llassert(cur_mip_size == bytes*4);
llassert_always(new_data);
+#endif
+
LLImageBase::generateMip(prev_mip_data, new_data, w, h, mComponents);
cur_mip_data = new_data;
+#ifdef SHOW_ASSERT
cur_mip_size = bytes;
+#endif
+
}
llassert(w > 0 && h > 0 && cur_mip_data);
+ (void)cur_mip_data;
{
// LLFastTimer t1(FTM_TEMP4);
if(mFormatSwapBytes)
@@ -805,7 +804,7 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
stop_glerror();
}
- LLImageGL::setManualImage(mTarget, m, mFormatInternal, w, h, mFormatPrimary, mFormatType, cur_mip_data);
+ LLImageGL::setManualImage(mTarget, m, mFormatInternal, w, h, mFormatPrimary, mFormatType, cur_mip_data, mAllowCompression);
if (m == 0)
{
analyzeAlpha(data_in, w, h);
@@ -827,7 +826,6 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
delete[] prev_mip_data;
}
prev_mip_data = cur_mip_data;
- prev_mip_size = cur_mip_size;
w >>= 1;
h >>= 1;
}
@@ -842,10 +840,10 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
{
llerrs << "Compressed Image has mipmaps but data does not (can not auto generate compressed mips)" << llendl;
}
- mHasMipMaps = true;
}
else
{
+ mMipLevels = 0;
S32 w = getWidth();
S32 h = getHeight();
if (is_compressed)
@@ -863,7 +861,7 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
}
LLImageGL::setManualImage(mTarget, 0, mFormatInternal, w, h,
- mFormatPrimary, mFormatType, (GLvoid *)data_in);
+ mFormatPrimary, mFormatType, (GLvoid *)data_in, mAllowCompression);
analyzeAlpha(data_in, w, h);
updatePickMask(w, h, data_in);
@@ -877,7 +875,6 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
}
}
- mHasMipMaps = false;
}
stop_glerror();
mGLTextureCreated = true;
@@ -901,14 +898,13 @@ BOOL LLImageGL::preAddToAtlas(S32 discard_level, const LLImageRaw* raw_image)
llassert(mCurrentDiscardLevel >= 0);
discard_level = mCurrentDiscardLevel;
}
- discard_level = llclamp(discard_level, 0, (S32)mMaxDiscardLevel);
-
+
// Actual image width/height = raw image width/height * 2^discard_level
S32 w = raw_image->getWidth() << discard_level;
S32 h = raw_image->getHeight() << discard_level;
// setSize may call destroyGLTexture if the size does not match
- setSize(w, h, raw_image->getComponents());
+ setSize(w, h, raw_image->getComponents(), discard_level);
if( !mHasExplicitFormat )
{
@@ -1090,28 +1086,27 @@ BOOL LLImageGL::setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_
}
// static
+static LLFastTimer::DeclareTimer FTM_GENERATE_TEXTURES("generate textures");
void LLImageGL::generateTextures(S32 numTextures, U32 *textures)
{
- glGenTextures(numTextures, (GLuint*)textures);
+ LLFastTimer t(FTM_GENERATE_TEXTURES);
+ glGenTextures(numTextures, textures);
}
// static
-void LLImageGL::deleteTextures(S32 numTextures, U32 *textures, bool immediate)
+void LLImageGL::deleteTextures(S32 numTextures, U32 *textures)
{
- for (S32 i = 0; i < numTextures; i++)
+ if (gGLManager.mInited)
{
- sDeadTextureList.push_back(textures[i]);
- }
-
- if (immediate)
- {
- LLImageGL::deleteDeadTextures();
+ glDeleteTextures(numTextures, textures);
}
}
// static
-void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 width, S32 height, U32 pixformat, U32 pixtype, const void *pixels)
+static LLFastTimer::DeclareTimer FTM_SET_MANUAL_IMAGE("setManualImage");
+void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 width, S32 height, U32 pixformat, U32 pixtype, const void *pixels, bool allow_compression)
{
+ LLFastTimer t(FTM_SET_MANUAL_IMAGE);
bool use_scratch = false;
U32* scratch = NULL;
if (LLRender::sGLCoreProfile)
@@ -1173,6 +1168,36 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt
}
}
+ if (LLImageGL::sCompressTextures && allow_compression)
+ {
+ switch (intformat)
+ {
+ case GL_RGB:
+ case GL_RGB8:
+ intformat = GL_COMPRESSED_RGB;
+ break;
+ case GL_RGBA:
+ case GL_RGBA8:
+ intformat = GL_COMPRESSED_RGBA;
+ break;
+ case GL_LUMINANCE:
+ case GL_LUMINANCE8:
+ intformat = GL_COMPRESSED_LUMINANCE;
+ break;
+ case GL_LUMINANCE_ALPHA:
+ case GL_LUMINANCE8_ALPHA8:
+ intformat = GL_COMPRESSED_LUMINANCE_ALPHA;
+ break;
+ case GL_ALPHA:
+ case GL_ALPHA8:
+ intformat = GL_COMPRESSED_ALPHA;
+ break;
+ default:
+ llwarns << "Could not compress format: " << std::hex << intformat << llendl;
+ break;
+ }
+ }
+
stop_glerror();
glTexImage2D(target, miplevel, intformat, width, height, 0, pixformat, pixtype, use_scratch ? scratch : pixels);
stop_glerror();
@@ -1185,9 +1210,10 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt
//create an empty GL texture: just create a texture name
//the texture is assiciate with some image by calling glTexImage outside LLImageGL
+static LLFastTimer::DeclareTimer FTM_CREATE_GL_TEXTURE1("createGLTexture()");
BOOL LLImageGL::createGLTexture()
{
- if (gHeadlessClient) return FALSE;
+ LLFastTimer t(FTM_CREATE_GL_TEXTURE1);
if (gGLManager.mIsDisabled)
{
llwarns << "Trying to create a texture while GL is disabled!" << llendl;
@@ -1201,10 +1227,11 @@ BOOL LLImageGL::createGLTexture()
if(mTexName)
{
- glDeleteTextures(1, (reinterpret_cast<GLuint*>(&mTexName))) ;
+ LLImageGL::deleteTextures(1, (reinterpret_cast<GLuint*>(&mTexName))) ;
}
- glGenTextures(1, (GLuint*)&mTexName);
+
+ LLImageGL::generateTextures(1, &mTexName);
stop_glerror();
if (!mTexName)
{
@@ -1214,9 +1241,10 @@ BOOL LLImageGL::createGLTexture()
return TRUE ;
}
+static LLFastTimer::DeclareTimer FTM_CREATE_GL_TEXTURE2("createGLTexture(raw)");
BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename/*=0*/, BOOL to_create, S32 category)
{
- if (gHeadlessClient) return FALSE;
+ LLFastTimer t(FTM_CREATE_GL_TEXTURE2);
if (gGLManager.mIsDisabled)
{
llwarns << "Trying to create a texture while GL is disabled!" << llendl;
@@ -1232,8 +1260,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S
llassert(mCurrentDiscardLevel >= 0);
discard_level = mCurrentDiscardLevel;
}
- discard_level = llclamp(discard_level, 0, (S32)mMaxDiscardLevel);
-
+
// Actual image width/height = raw image width/height * 2^discard_level
S32 raw_w = imageraw->getWidth() ;
S32 raw_h = imageraw->getHeight() ;
@@ -1241,7 +1268,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S
S32 h = raw_h << discard_level;
// setSize may call destroyGLTexture if the size does not match
- setSize(w, h, imageraw->getComponents());
+ setSize(w, h, imageraw->getComponents(), discard_level);
if( !mHasExplicitFormat )
{
@@ -1284,13 +1311,15 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S
return TRUE ;
}
- setCategory(category) ;
+ setCategory(category);
const U8* rawdata = imageraw->getData();
return createGLTexture(discard_level, rawdata, FALSE, usename);
}
+static LLFastTimer::DeclareTimer FTM_CREATE_GL_TEXTURE3("createGLTexture3(data)");
BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_hasmips, S32 usename)
{
+ LLFastTimer t(FTM_CREATE_GL_TEXTURE3);
llassert(data_in);
stop_glerror();
@@ -1362,11 +1391,6 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_
{
sGlobalTextureMemoryInBytes -= mTextureMemory;
- if(gAuditTexture)
- {
- decTextureCounter(mTextureMemory, mComponents, mCategory) ;
- }
-
LLImageGL::deleteTextures(1, &old_name);
stop_glerror();
@@ -1376,10 +1400,6 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_
sGlobalTextureMemoryInBytes += mTextureMemory;
mTexelsInGLTexture = getWidth() * getHeight() ;
- if(gAuditTexture)
- {
- incTextureCounter(mTextureMemory, mComponents, mCategory) ;
- }
// mark this as bound at this point, so we don't throw it out immediately
mLastBindTime = sLastFrameTime;
return TRUE;
@@ -1500,30 +1520,6 @@ void LLImageGL::deleteDeadTextures()
{
bool reset = false;
- while (!sDeadTextureList.empty())
- {
- GLuint tex = sDeadTextureList.front();
- sDeadTextureList.pop_front();
- for (int i = 0; i < gGLManager.mNumTextureImageUnits; i++)
- {
- LLTexUnit* tex_unit = gGL.getTexUnit(i);
-
- if (tex_unit && tex_unit->getCurrTexture() == tex)
- {
- tex_unit->unbind(tex_unit->getCurrType());
- stop_glerror();
-
- if (i > 0)
- {
- reset = true;
- }
- }
- }
-
- glDeleteTextures(1, &tex);
- stop_glerror();
- }
-
if (reset)
{
gGL.getTexUnit(0)->activate();
@@ -1536,22 +1532,29 @@ void LLImageGL::destroyGLTexture()
{
if(mTextureMemory)
{
- if(gAuditTexture)
- {
- decTextureCounter(mTextureMemory, mComponents, mCategory) ;
- }
sGlobalTextureMemoryInBytes -= mTextureMemory;
mTextureMemory = 0;
}
LLImageGL::deleteTextures(1, &mTexName);
- mTexName = 0;
mCurrentDiscardLevel = -1 ; //invalidate mCurrentDiscardLevel.
+ mTexName = 0;
mGLTextureCreated = FALSE ;
- }
+ }
}
-
+//force to invalidate the gl texture, most likely a sculpty texture
+void LLImageGL::forceToInvalidateGLTexture()
+{
+ if (mTexName != 0)
+ {
+ destroyGLTexture();
+ }
+ else
+ {
+ mCurrentDiscardLevel = -1 ; //invalidate mCurrentDiscardLevel.
+ }
+}
//----------------------------------------------------------------------------
@@ -1669,6 +1672,12 @@ BOOL LLImageGL::getBoundRecently() const
return (BOOL)(sLastFrameTime - mLastBindTime < MIN_TEXTURE_LIFETIME);
}
+BOOL LLImageGL::getIsAlphaMask() const
+{
+ llassert_always(!sSkipAnalyzeAlpha);
+ return mIsMask;
+}
+
void LLImageGL::setTarget(const LLGLenum target, const LLTexUnit::eTextureType bind_target)
{
mTarget = target;
@@ -1766,7 +1775,7 @@ void LLImageGL::calcAlphaChannelOffsetAndStride()
void LLImageGL::analyzeAlpha(const void* data_in, U32 w, U32 h)
{
- if(!mNeedsAlphaAndPickMask)
+ if(sSkipAnalyzeAlpha || !mNeedsAlphaAndPickMask)
{
return ;
}
@@ -1969,70 +1978,6 @@ BOOL LLImageGL::getMask(const LLVector2 &tc)
return res;
}
-void LLImageGL::setCategory(S32 category)
-{
-#if 0 //turn this off temporarily because it is not in use now.
- if(!gAuditTexture)
- {
- return ;
- }
- if(mCategory != category)
- {
- if(mCategory > -1)
- {
- sTextureMemByCategory[mCategory] -= mTextureMemory ;
- }
- if(category > -1 && category < sMaxCatagories)
- {
- sTextureMemByCategory[category] += mTextureMemory ;
- mCategory = category;
- }
- else
- {
- mCategory = -1 ;
- }
- }
-#endif
-}
-
-//for debug use
-//val is a "power of two" number
-S32 LLImageGL::getTextureCounterIndex(U32 val)
-{
- //index range is [0, MAX_TEXTURE_LOG_SIZE].
- if(val < 2)
- {
- return 0 ;
- }
- else if(val >= (1 << MAX_TEXTURE_LOG_SIZE))
- {
- return MAX_TEXTURE_LOG_SIZE ;
- }
- else
- {
- S32 ret = 0 ;
- while(val >>= 1)
- {
- ++ret;
- }
- return ret ;
- }
-}
-
-//static
-void LLImageGL::incTextureCounter(U32 val, S32 ncomponents, S32 category)
-{
- sTextureLoadedCounter[getTextureCounterIndex(val)]++ ;
- sTextureMemByCategory[category] += (S32)val * ncomponents ;
-}
-
-//static
-void LLImageGL::decTextureCounter(U32 val, S32 ncomponents, S32 category)
-{
- sTextureLoadedCounter[getTextureCounterIndex(val)]-- ;
- sTextureMemByCategory[category] += (S32)val * ncomponents ;
-}
-
void LLImageGL::setCurTexSizebar(S32 index, BOOL set_pick_size)
{
sCurTexSizeBar = index ;
diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h
index 2cfb15b0d9..0c62dd0d33 100644..100755
--- a/indra/llrender/llimagegl.h
+++ b/indra/llrender/llimagegl.h
@@ -45,8 +45,9 @@ class LLImageGL : public LLRefCount
{
friend class LLTexUnit;
public:
- static std::list<U32> sDeadTextureList;
-
+ // These 2 functions replace glGenTextures() and glDeleteTextures()
+ static void generateTextures(S32 numTextures, U32 *textures);
+ static void deleteTextures(S32 numTextures, U32 *textures);
static void deleteDeadTextures();
// Size calculation
@@ -92,18 +93,15 @@ protected:
public:
virtual void dump(); // debugging info to llinfos
- void setSize(S32 width, S32 height, S32 ncomponents);
+ void setSize(S32 width, S32 height, S32 ncomponents, S32 discard_level = -1);
void setComponents(S32 ncomponents) { mComponents = (S8)ncomponents ;}
+ void setAllowCompression(bool allow) { mAllowCompression = allow; }
- // These 3 functions currently wrap glGenTextures(), glDeleteTextures(), and glTexImage2D()
- // for tracking purposes and will be deprecated in the future
- static void generateTextures(S32 numTextures, U32 *textures);
- static void deleteTextures(S32 numTextures, U32 *textures, bool immediate = false);
- static void setManualImage(U32 target, S32 miplevel, S32 intformat, S32 width, S32 height, U32 pixformat, U32 pixtype, const void *pixels);
+ static void setManualImage(U32 target, S32 miplevel, S32 intformat, S32 width, S32 height, U32 pixformat, U32 pixtype, const void *pixels, bool allow_compression = true);
BOOL createGLTexture() ;
- BOOL createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename = 0, BOOL to_create = TRUE,
- S32 category = sMaxCatagories - 1);
+ BOOL createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename = 0, BOOL to_create = TRUE,
+ S32 category = sMaxCategories-1);
BOOL createGLTexture(S32 discard_level, const U8* data, BOOL data_hasmips = FALSE, S32 usename = 0);
void setImage(const LLImageRaw* imageraw);
void setImage(const U8* data_in, BOOL data_hasmips = FALSE);
@@ -114,6 +112,7 @@ public:
// Read back a raw image for this discard level, if it exists
BOOL readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compressed_ok) const;
void destroyGLTexture();
+ void forceToInvalidateGLTexture();
void setExplicitFormat(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format = 0, BOOL swap_bytes = FALSE);
void setComponents(S8 ncomponents) { mComponents = ncomponents; }
@@ -136,7 +135,7 @@ public:
BOOL getHasGLTexture() const { return mTexName != 0; }
LLGLuint getTexName() const { return mTexName; }
- BOOL getIsAlphaMask() const { return mIsMask; }
+ BOOL getIsAlphaMask() const;
BOOL getIsResident(BOOL test_now = FALSE); // not const
@@ -209,11 +208,14 @@ private:
U32 mTexelsInAtlas ;
U32 mTexelsInGLTexture;
+ bool mAllowCompression;
+
protected:
LLGLenum mTarget; // Normally GL_TEXTURE2D, sometimes something else (ex. cube maps)
LLTexUnit::eTextureType mBindTarget; // Normally TT_TEXTURE, sometimes something else (ex. cube maps)
bool mHasMipMaps;
-
+ S32 mMipLevels;
+
LLGLboolean mIsResident;
S8 mComponents;
@@ -234,8 +236,6 @@ public:
static S32 sCount;
static F32 sLastFrameTime;
-
- static LLGLuint sCurrentBoundTextures[MAX_GL_TEXTURE_UNITS]; // Currently bound texture ID
// Global memory statistics
static S32 sGlobalTextureMemoryInBytes; // Tracks main memory texmem
@@ -246,7 +246,7 @@ public:
static BOOL sGlobalUseAnisotropic;
static LLImageGL* sDefaultGLTexture ;
static BOOL sAutomatedTest;
-
+ static bool sCompressTextures; //use GL texture compression
#if DEBUG_MISS
BOOL mMissed; // Missed on last bind?
BOOL getMissed() const { return mMissed; };
@@ -255,11 +255,13 @@ public:
#endif
public:
- static void initClass(S32 num_catagories) ;
+ static void initClass(S32 num_catagories, BOOL skip_analyze_alpha = false);
static void cleanupClass() ;
-private:
- static S32 sMaxCatagories ;
+private:
+ static S32 sMaxCategories;
+ static BOOL sSkipAnalyzeAlpha;
+
//the flag to allow to call readBackRaw(...).
//can be removed if we do not use that function at all.
static BOOL sAllowReadBackRaw ;
@@ -269,39 +271,22 @@ private:
//****************************************************************************************************
private:
S32 mCategory ;
-public:
- void setCategory(S32 category) ;
- S32 getCategory()const {return mCategory ;}
-
+public:
+ void setCategory(S32 category) {mCategory = category;}
+ S32 getCategory()const {return mCategory;}
+
//for debug use: show texture size distribution
//----------------------------------------
- static LLPointer<LLImageGL> sHighlightTexturep; //default texture to replace normal textures
- static std::vector<S32> sTextureLoadedCounter ;
- static std::vector<S32> sTextureBoundCounter ;
- static std::vector<S32> sTextureCurBoundCounter ;
static S32 sCurTexSizeBar ;
static S32 sCurTexPickSize ;
- static void setHighlightTexture(S32 category) ;
- static S32 getTextureCounterIndex(U32 val) ;
- static void incTextureCounter(U32 val, S32 ncomponents, S32 category) ;
- static void decTextureCounter(U32 val, S32 ncomponents, S32 category) ;
static void setCurTexSizebar(S32 index, BOOL set_pick_size = TRUE) ;
static void resetCurTexSizebar();
- //----------------------------------------
- //for debug use: show texture category distribution
- //----------------------------------------
-
- static std::vector<S32> sTextureMemByCategory;
- static std::vector<S32> sTextureMemByCategoryBound ;
- static std::vector<S32> sTextureCurMemByCategoryBound ;
- //----------------------------------------
//****************************************************************************************************
//End of definitions for texture auditing use only
//****************************************************************************************************
};
-extern BOOL gAuditTexture;
#endif // LL_LLIMAGEGL_H
diff --git a/indra/llrender/llpostprocess.cpp b/indra/llrender/llpostprocess.cpp
index c0045c8044..4c36185b08 100644..100755
--- a/indra/llrender/llpostprocess.cpp
+++ b/indra/llrender/llpostprocess.cpp
@@ -31,6 +31,21 @@
#include "llsdserialize.h"
#include "llrender.h"
+static LLStaticHashedString sRenderTexture("RenderTexture");
+static LLStaticHashedString sBrightness("brightness");
+static LLStaticHashedString sContrast("contrast");
+static LLStaticHashedString sContrastBase("contrastBase");
+static LLStaticHashedString sSaturation("saturation");
+static LLStaticHashedString sLumWeights("lumWeights");
+static LLStaticHashedString sNoiseTexture("NoiseTexture");
+static LLStaticHashedString sBrightMult("brightMult");
+static LLStaticHashedString sNoiseStrength("noiseStrength");
+static LLStaticHashedString sExtractLow("extractLow");
+static LLStaticHashedString sExtractHigh("extractHigh");
+static LLStaticHashedString sBloomStrength("bloomStrength");
+static LLStaticHashedString sTexelSize("texelSize");
+static LLStaticHashedString sBlurDirection("blurDirection");
+static LLStaticHashedString sBlurWidth("blurWidth");
LLPostProcess * gPostProcess = NULL;
@@ -258,12 +273,12 @@ void LLPostProcess::applyColorFilterShader(void)
void LLPostProcess::createColorFilterShader(void)
{
/// Define uniform names
- colorFilterUniforms["RenderTexture"] = 0;
- colorFilterUniforms["brightness"] = 0;
- colorFilterUniforms["contrast"] = 0;
- colorFilterUniforms["contrastBase"] = 0;
- colorFilterUniforms["saturation"] = 0;
- colorFilterUniforms["lumWeights"] = 0;
+ colorFilterUniforms[sRenderTexture] = 0;
+ colorFilterUniforms[sBrightness] = 0;
+ colorFilterUniforms[sContrast] = 0;
+ colorFilterUniforms[sContrastBase] = 0;
+ colorFilterUniforms[sSaturation] = 0;
+ colorFilterUniforms[sLumWeights] = 0;
}
void LLPostProcess::applyNightVisionShader(void)
@@ -307,11 +322,11 @@ void LLPostProcess::applyNightVisionShader(void)
void LLPostProcess::createNightVisionShader(void)
{
/// Define uniform names
- nightVisionUniforms["RenderTexture"] = 0;
- nightVisionUniforms["NoiseTexture"] = 0;
- nightVisionUniforms["brightMult"] = 0;
- nightVisionUniforms["noiseStrength"] = 0;
- nightVisionUniforms["lumWeights"] = 0;
+ nightVisionUniforms[sRenderTexture] = 0;
+ nightVisionUniforms[sNoiseTexture] = 0;
+ nightVisionUniforms[sBrightMult] = 0;
+ nightVisionUniforms[sNoiseStrength] = 0;
+ nightVisionUniforms[sLumWeights] = 0;
createNoiseTexture(mNoiseTexture);
}
@@ -326,25 +341,25 @@ void LLPostProcess::createBloomShader(void)
createTexture(mTempBloomTexture, unsigned(screenW * 0.5), unsigned(screenH * 0.5));
/// Create Bloom Extract Shader
- bloomExtractUniforms["RenderTexture"] = 0;
- bloomExtractUniforms["extractLow"] = 0;
- bloomExtractUniforms["extractHigh"] = 0;
- bloomExtractUniforms["lumWeights"] = 0;
+ bloomExtractUniforms[sRenderTexture] = 0;
+ bloomExtractUniforms[sExtractLow] = 0;
+ bloomExtractUniforms[sExtractHigh] = 0;
+ bloomExtractUniforms[sLumWeights] = 0;
/// Create Bloom Blur Shader
- bloomBlurUniforms["RenderTexture"] = 0;
- bloomBlurUniforms["bloomStrength"] = 0;
- bloomBlurUniforms["texelSize"] = 0;
- bloomBlurUniforms["blurDirection"] = 0;
- bloomBlurUniforms["blurWidth"] = 0;
+ bloomBlurUniforms[sRenderTexture] = 0;
+ bloomBlurUniforms[sBloomStrength] = 0;
+ bloomBlurUniforms[sTexelSize] = 0;
+ bloomBlurUniforms[sBlurDirection] = 0;
+ bloomBlurUniforms[sBlurWidth] = 0;
}
void LLPostProcess::getShaderUniforms(glslUniforms & uniforms, GLhandleARB & prog)
{
/// Find uniform locations and insert into map
- std::map<const char *, GLuint>::iterator i;
+ glslUniforms::iterator i;
for (i = uniforms.begin(); i != uniforms.end(); ++i){
- i->second = glGetUniformLocationARB(prog, i->first);
+ i->second = glGetUniformLocationARB(prog, i->first.String().c_str());
}
}
diff --git a/indra/llrender/llpostprocess.h b/indra/llrender/llpostprocess.h
index e19de44c60..ce17b6693d 100644..100755
--- a/indra/llrender/llpostprocess.h
+++ b/indra/llrender/llpostprocess.h
@@ -31,6 +31,7 @@
#include <fstream>
#include "llgl.h"
#include "llglheaders.h"
+#include "llstaticstringtable.h"
class LLPostProcess
{
@@ -44,7 +45,7 @@ public:
} QuadType;
/// GLSL Shader Encapsulation Struct
- typedef std::map<const char *, GLuint> glslUniforms;
+ typedef LLStaticStringTable<GLuint> glslUniforms;
struct PostProcessTweaks : public LLSD {
inline PostProcessTweaks() : LLSD(LLSD::emptyMap())
diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp
index b0ddacbb05..0ac30b4d63 100644..100755
--- a/indra/llrender/llrender.cpp
+++ b/indra/llrender/llrender.cpp
@@ -225,35 +225,16 @@ void LLTexUnit::disable(void)
bool LLTexUnit::bind(LLTexture* texture, bool for_rendering, bool forceBind)
{
stop_glerror();
- if (mIndex < 0) return false;
-
+ if (mIndex >= 0)
+ {
gGL.flush();
LLImageGL* gl_tex = NULL ;
- if (texture == NULL || !(gl_tex = texture->getGLTexture()))
+ if (texture != NULL && (gl_tex = texture->getGLTexture()))
{
- llwarns << "NULL LLTexUnit::bind texture" << llendl;
- return false;
- }
-
- if (!gl_tex->getTexName()) //if texture does not exist
+ if (gl_tex->getTexName()) //if texture exists
{
- //if deleted, will re-generate it immediately
- texture->forceImmediateUpdate() ;
-
- gl_tex->forceUpdateBindStats() ;
- return texture->bindDefaultImage(mIndex);
- }
-
//in audit, replace the selected texture by the default one.
- if(gAuditTexture && for_rendering && LLImageGL::sCurTexPickSize > 0)
- {
- if(texture->getWidth() * texture->getHeight() == LLImageGL::sCurTexPickSize)
- {
- gl_tex->updateBindStats(gl_tex->mTextureMemory);
- return bind(LLImageGL::sHighlightTexturep.get());
- }
- }
if ((mCurrTexture != gl_tex->getTexName()) || forceBind)
{
activate();
@@ -273,6 +254,27 @@ bool LLTexUnit::bind(LLTexture* texture, bool for_rendering, bool forceBind)
setTextureFilteringOption(gl_tex->mFilterOption);
}
}
+ }
+ else
+ {
+ //if deleted, will re-generate it immediately
+ texture->forceImmediateUpdate() ;
+
+ gl_tex->forceUpdateBindStats() ;
+ return texture->bindDefaultImage(mIndex);
+ }
+ }
+ else
+ {
+ llwarns << "NULL LLTexUnit::bind texture" << llendl;
+ return false;
+ }
+ }
+ else
+ { // mIndex < 0
+ return false;
+ }
+
return true;
}
@@ -365,7 +367,6 @@ bool LLTexUnit::bind(LLCubeMap* cubeMap)
}
// LLRenderTarget is unavailible on the mapserver since it uses FBOs.
-#if !LL_MESA_HEADLESS
bool LLTexUnit::bind(LLRenderTarget* renderTarget, bool bindDepth)
{
if (mIndex < 0) return false;
@@ -388,7 +389,6 @@ bool LLTexUnit::bind(LLRenderTarget* renderTarget, bool bindDepth)
return true;
}
-#endif // LL_MESA_HEADLESS
bool LLTexUnit::bindManual(eTextureType type, U32 texture, bool hasMips)
{
@@ -416,12 +416,14 @@ void LLTexUnit::unbind(eTextureType type)
if (mIndex < 0) return;
+ //always flush and activate for consistency
+ // some code paths assume unbind always flushes and sets the active texture
+ gGL.flush();
+ activate();
+
// Disabled caching of binding state.
if (mCurrTexType == type)
{
- gGL.flush();
-
- activate();
mCurrTexture = 0;
if (LLGLSLShader::sNoFixedFunction && type == LLTexUnit::TT_TEXTURE)
{
@@ -472,11 +474,25 @@ void LLTexUnit::setTextureFilteringOption(LLTexUnit::eTextureFilterOptions optio
}
else if (option >= TFO_BILINEAR)
{
- glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ if (mHasMipMaps)
+ {
+ glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
+ }
+ else
+ {
+ glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ }
}
else
{
- glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ if (mHasMipMaps)
+ {
+ glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
+ }
+ else
+ {
+ glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ }
}
if (gGLManager.mHasAnisotropic)
@@ -640,7 +656,7 @@ void LLTexUnit::setTextureCombiner(eTextureBlendOp op, eTextureBlendSrc src1, eT
gGL.flush();
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
}
-
+
// We want an early out, because this function does a LOT of stuff.
if ( ( (isAlpha && (mCurrAlphaOp == op) && (mCurrAlphaSrc1 == src1) && (mCurrAlphaSrc2 == src2))
|| (!isAlpha && (mCurrColorOp == op) && (mCurrColorSrc1 == src1) && (mCurrColorSrc2 == src2)) ) && !gGL.mDirty)
@@ -1052,6 +1068,16 @@ LLRender::~LLRender()
void LLRender::init()
{
+ if (sGLCoreProfile && !LLVertexBuffer::sUseVAO)
+ { //bind a dummy vertex array object so we're core profile compliant
+#ifdef GL_ARB_vertex_array_object
+ U32 ret;
+ glGenVertexArrays(1, &ret);
+ glBindVertexArray(ret);
+#endif
+ }
+
+
llassert_always(mBuffer.isNull()) ;
stop_glerror();
mBuffer = new LLVertexBuffer(immediate_mask, 0);
@@ -1429,6 +1455,17 @@ void LLRender::matrixMode(U32 mode)
mMatrixMode = mode;
}
+U32 LLRender::getMatrixMode()
+{
+ if (mMatrixMode >= MM_TEXTURE0 && mMatrixMode <= MM_TEXTURE3)
+ { //always return MM_TEXTURE if current matrix mode points at any texture matrix
+ return MM_TEXTURE;
+ }
+
+ return mMatrixMode;
+}
+
+
void LLRender::loadIdentity()
{
flush();
@@ -1832,13 +1869,15 @@ void LLRender::flush()
sUIVerts += mCount;
}
- if (gDebugGL)
- {
+ //store mCount in a local variable to avoid re-entrance (drawArrays may call flush)
+ U32 count = mCount;
+
if (mMode == LLRender::QUADS && !sGLCoreProfile)
{
if (mCount%4 != 0)
{
- llerrs << "Incomplete quad rendered." << llendl;
+ count -= (mCount % 4);
+ llwarns << "Incomplete quad requested." << llendl;
}
}
@@ -1846,7 +1885,8 @@ void LLRender::flush()
{
if (mCount%3 != 0)
{
- llerrs << "Incomplete triangle rendered." << llendl;
+ count -= (mCount % 3);
+ llwarns << "Incomplete triangle requested." << llendl;
}
}
@@ -1854,13 +1894,11 @@ void LLRender::flush()
{
if (mCount%2 != 0)
{
- llerrs << "Incomplete line rendered." << llendl;
- }
+ count -= (mCount % 2);
+ llwarns << "Incomplete line requested." << llendl;
}
}
- //store mCount in a local variable to avoid re-entrance (drawArrays may call flush)
- U32 count = mCount;
mCount = 0;
if (mBuffer->useVBOs() && !mBuffer->isLocked())
@@ -2263,6 +2301,22 @@ void LLRender::diffuseColor4ubv(const U8* c)
}
}
+void LLRender::diffuseColor4ub(U8 r, U8 g, U8 b, U8 a)
+{
+ LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
+ llassert(!LLGLSLShader::sNoFixedFunction || shader != NULL);
+
+ if (shader)
+ {
+ shader->uniform4f(LLShaderMgr::DIFFUSE_COLOR, r/255.f, g/255.f, b/255.f, a/255.f);
+ }
+ else
+ {
+ glColor4ub(r,g,b,a);
+ }
+}
+
+
void LLRender::debugTexUnits(void)
{
LL_INFOS("TextureUnit") << "Active TexUnit: " << mCurrTextureUnitIndex << LL_ENDL;
diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h
index fa5f7f311d..42b02a8159 100644..100755
--- a/indra/llrender/llrender.h
+++ b/indra/llrender/llrender.h
@@ -262,6 +262,14 @@ class LLRender
friend class LLTexUnit;
public:
+ enum eTexIndex
+ {
+ DIFFUSE_MAP = 0,
+ NORMAL_MAP,
+ SPECULAR_MAP,
+ NUM_TEXTURE_CHANNELS,
+ };
+
typedef enum {
TRIANGLES = 0,
TRIANGLE_STRIP,
@@ -346,6 +354,7 @@ public:
void loadIdentity();
void multMatrix(const GLfloat* m);
void matrixMode(U32 mode);
+ U32 getMatrixMode();
const glh::matrix4f& getModelviewMatrix();
const glh::matrix4f& getProjectionMatrix();
@@ -387,6 +396,7 @@ public:
void diffuseColor4f(F32 r, F32 g, F32 b, F32 a);
void diffuseColor4fv(const F32* c);
void diffuseColor4ubv(const U8* c);
+ void diffuseColor4ub(U8 r, U8 g, U8 b, U8 a);
void vertexBatchPreTransformed(LLVector3* verts, S32 vert_count);
void vertexBatchPreTransformed(LLVector3* verts, LLVector2* uvs, S32 vert_count);
diff --git a/indra/llrender/llrender2dutils.cpp b/indra/llrender/llrender2dutils.cpp
new file mode 100644
index 0000000000..d3cfbaf03a
--- /dev/null
+++ b/indra/llrender/llrender2dutils.cpp
@@ -0,0 +1,1608 @@
+/**
+ * @file llrender2dutils.cpp
+ * @brief GL function implementations for immediate-mode gl drawing.
+ *
+ * $LicenseInfo:firstyear=2001&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"
+
+// Linden library includes
+#include "v2math.h"
+#include "m3math.h"
+#include "v4color.h"
+#include "llfontgl.h"
+#include "llrender.h"
+#include "llrect.h"
+#include "llgl.h"
+#include "lltexture.h"
+
+// Project includes
+#include "llrender2dutils.h"
+#include "lluiimage.h"
+
+
+//
+// Globals
+//
+const LLColor4 UI_VERTEX_COLOR(1.f, 1.f, 1.f, 1.f);
+/*static*/ LLVector2 LLRender2D::sGLScaleFactor(1.f, 1.f);
+/*static*/ LLImageProviderInterface* LLRender2D::sImageProvider = NULL;
+
+//
+// Functions
+//
+
+BOOL ui_point_in_rect(S32 x, S32 y, S32 left, S32 top, S32 right, S32 bottom)
+{
+ if (x < left || right < x) return FALSE;
+ if (y < bottom || top < y) return FALSE;
+ return TRUE;
+}
+
+
+// Puts GL into 2D drawing mode by turning off lighting, setting to an
+// orthographic projection, etc.
+void gl_state_for_2d(S32 width, S32 height)
+{
+ stop_glerror();
+ F32 window_width = (F32) width;//gViewerWindow->getWindowWidth();
+ F32 window_height = (F32) height;//gViewerWindow->getWindowHeight();
+
+ gGL.matrixMode(LLRender::MM_PROJECTION);
+ gGL.loadIdentity();
+ gGL.ortho(0.0f, llmax(window_width, 1.f), 0.0f, llmax(window_height,1.f), -1.0f, 1.0f);
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.loadIdentity();
+ stop_glerror();
+}
+
+
+void gl_draw_x(const LLRect& rect, const LLColor4& color)
+{
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+ gGL.color4fv( color.mV );
+
+ gGL.begin( LLRender::LINES );
+ gGL.vertex2i( rect.mLeft, rect.mTop );
+ gGL.vertex2i( rect.mRight, rect.mBottom );
+ gGL.vertex2i( rect.mLeft, rect.mBottom );
+ gGL.vertex2i( rect.mRight, rect.mTop );
+ gGL.end();
+}
+
+
+void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &color, S32 pixel_offset, BOOL filled)
+{
+ gGL.color4fv(color.mV);
+ gl_rect_2d_offset_local(left, top, right, bottom, pixel_offset, filled);
+}
+
+void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, S32 pixel_offset, BOOL filled)
+{
+ gGL.pushUIMatrix();
+ left += LLFontGL::sCurOrigin.mX;
+ right += LLFontGL::sCurOrigin.mX;
+ bottom += LLFontGL::sCurOrigin.mY;
+ top += LLFontGL::sCurOrigin.mY;
+
+ gGL.loadUIIdentity();
+ gl_rect_2d(llfloor((F32)left * LLRender2D::sGLScaleFactor.mV[VX]) - pixel_offset,
+ llfloor((F32)top * LLRender2D::sGLScaleFactor.mV[VY]) + pixel_offset,
+ llfloor((F32)right * LLRender2D::sGLScaleFactor.mV[VX]) + pixel_offset,
+ llfloor((F32)bottom * LLRender2D::sGLScaleFactor.mV[VY]) - pixel_offset,
+ filled);
+ gGL.popUIMatrix();
+}
+
+
+void gl_rect_2d(S32 left, S32 top, S32 right, S32 bottom, BOOL filled )
+{
+ stop_glerror();
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+ // Counterclockwise quad will face the viewer
+ if( filled )
+ {
+ gGL.begin( LLRender::QUADS );
+ gGL.vertex2i(left, top);
+ gGL.vertex2i(left, bottom);
+ gGL.vertex2i(right, bottom);
+ gGL.vertex2i(right, top);
+ gGL.end();
+ }
+ else
+ {
+ if( gGLManager.mATIOffsetVerticalLines )
+ {
+ // Work around bug in ATI driver: vertical lines are offset by (-1,-1)
+ gGL.begin( LLRender::LINES );
+
+ // Verticals
+ gGL.vertex2i(left + 1, top);
+ gGL.vertex2i(left + 1, bottom);
+
+ gGL.vertex2i(right, bottom);
+ gGL.vertex2i(right, top);
+
+ // Horizontals
+ top--;
+ right--;
+ gGL.vertex2i(left, bottom);
+ gGL.vertex2i(right, bottom);
+
+ gGL.vertex2i(left, top);
+ gGL.vertex2i(right, top);
+ gGL.end();
+ }
+ else
+ {
+ top--;
+ right--;
+ gGL.begin( LLRender::LINE_STRIP );
+ gGL.vertex2i(left, top);
+ gGL.vertex2i(left, bottom);
+ gGL.vertex2i(right, bottom);
+ gGL.vertex2i(right, top);
+ gGL.vertex2i(left, top);
+ gGL.end();
+ }
+ }
+ stop_glerror();
+}
+
+void gl_rect_2d(S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &color, BOOL filled )
+{
+ gGL.color4fv( color.mV );
+ gl_rect_2d( left, top, right, bottom, filled );
+}
+
+
+void gl_rect_2d( const LLRect& rect, const LLColor4& color, BOOL filled )
+{
+ gGL.color4fv( color.mV );
+ gl_rect_2d( rect.mLeft, rect.mTop, rect.mRight, rect.mBottom, filled );
+}
+
+// Given a rectangle on the screen, draws a drop shadow _outside_
+// the right and bottom edges of it. Along the right it has width "lines"
+// and along the bottom it has height "lines".
+void gl_drop_shadow(S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &start_color, S32 lines)
+{
+ stop_glerror();
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+ // HACK: Overlap with the rectangle by a single pixel.
+ right--;
+ bottom++;
+ lines++;
+
+ LLColor4 end_color = start_color;
+ end_color.mV[VALPHA] = 0.f;
+
+ gGL.begin(LLRender::QUADS);
+
+ // Right edge, CCW faces screen
+ gGL.color4fv(start_color.mV);
+ gGL.vertex2i(right, top-lines);
+ gGL.vertex2i(right, bottom);
+ gGL.color4fv(end_color.mV);
+ gGL.vertex2i(right+lines, bottom);
+ gGL.vertex2i(right+lines, top-lines);
+
+ // Bottom edge, CCW faces screen
+ gGL.color4fv(start_color.mV);
+ gGL.vertex2i(right, bottom);
+ gGL.vertex2i(left+lines, bottom);
+ gGL.color4fv(end_color.mV);
+ gGL.vertex2i(left+lines, bottom-lines);
+ gGL.vertex2i(right, bottom-lines);
+
+ // bottom left Corner
+ gGL.color4fv(start_color.mV);
+ gGL.vertex2i(left+lines, bottom);
+ gGL.color4fv(end_color.mV);
+ gGL.vertex2i(left, bottom);
+ // make the bottom left corner not sharp
+ gGL.vertex2i(left+1, bottom-lines+1);
+ gGL.vertex2i(left+lines, bottom-lines);
+
+ // bottom right corner
+ gGL.color4fv(start_color.mV);
+ gGL.vertex2i(right, bottom);
+ gGL.color4fv(end_color.mV);
+ gGL.vertex2i(right, bottom-lines);
+ // make the rightmost corner not sharp
+ gGL.vertex2i(right+lines-1, bottom-lines+1);
+ gGL.vertex2i(right+lines, bottom);
+
+ // top right corner
+ gGL.color4fv(start_color.mV);
+ gGL.vertex2i( right, top-lines );
+ gGL.color4fv(end_color.mV);
+ gGL.vertex2i( right+lines, top-lines );
+ // make the corner not sharp
+ gGL.vertex2i( right+lines-1, top-1 );
+ gGL.vertex2i( right, top );
+
+ gGL.end();
+ stop_glerror();
+}
+
+void gl_line_2d(S32 x1, S32 y1, S32 x2, S32 y2 )
+{
+ // Work around bug in ATI driver: vertical lines are offset by (-1,-1)
+ if( (x1 == x2) && gGLManager.mATIOffsetVerticalLines )
+ {
+ x1++;
+ x2++;
+ y1++;
+ y2++;
+ }
+
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+ gGL.begin(LLRender::LINES);
+ gGL.vertex2i(x1, y1);
+ gGL.vertex2i(x2, y2);
+ gGL.end();
+}
+
+void gl_line_2d(S32 x1, S32 y1, S32 x2, S32 y2, const LLColor4 &color )
+{
+ // Work around bug in ATI driver: vertical lines are offset by (-1,-1)
+ if( (x1 == x2) && gGLManager.mATIOffsetVerticalLines )
+ {
+ x1++;
+ x2++;
+ y1++;
+ y2++;
+ }
+
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+ gGL.color4fv( color.mV );
+
+ gGL.begin(LLRender::LINES);
+ gGL.vertex2i(x1, y1);
+ gGL.vertex2i(x2, y2);
+ gGL.end();
+}
+
+void gl_triangle_2d(S32 x1, S32 y1, S32 x2, S32 y2, S32 x3, S32 y3, const LLColor4& color, BOOL filled)
+{
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+ gGL.color4fv(color.mV);
+
+ if (filled)
+ {
+ gGL.begin(LLRender::TRIANGLES);
+ }
+ else
+ {
+ gGL.begin(LLRender::LINE_LOOP);
+ }
+ gGL.vertex2i(x1, y1);
+ gGL.vertex2i(x2, y2);
+ gGL.vertex2i(x3, y3);
+ gGL.end();
+}
+
+void gl_corners_2d(S32 left, S32 top, S32 right, S32 bottom, S32 length, F32 max_frac)
+{
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+ length = llmin((S32)(max_frac*(right - left)), length);
+ length = llmin((S32)(max_frac*(top - bottom)), length);
+ gGL.begin(LLRender::LINES);
+ gGL.vertex2i(left, top);
+ gGL.vertex2i(left + length, top);
+
+ gGL.vertex2i(left, top);
+ gGL.vertex2i(left, top - length);
+
+ gGL.vertex2i(left, bottom);
+ gGL.vertex2i(left + length, bottom);
+
+ gGL.vertex2i(left, bottom);
+ gGL.vertex2i(left, bottom + length);
+
+ gGL.vertex2i(right, top);
+ gGL.vertex2i(right - length, top);
+
+ gGL.vertex2i(right, top);
+ gGL.vertex2i(right, top - length);
+
+ gGL.vertex2i(right, bottom);
+ gGL.vertex2i(right - length, bottom);
+
+ gGL.vertex2i(right, bottom);
+ gGL.vertex2i(right, bottom + length);
+ gGL.end();
+}
+
+
+void gl_draw_image( S32 x, S32 y, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect )
+{
+ if (NULL == image)
+ {
+ llwarns << "image == NULL; aborting function" << llendl;
+ return;
+ }
+ gl_draw_scaled_rotated_image( x, y, image->getWidth(0), image->getHeight(0), 0.f, image, color, uv_rect );
+}
+
+void gl_draw_scaled_image(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect)
+{
+ if (NULL == image)
+ {
+ llwarns << "image == NULL; aborting function" << llendl;
+ return;
+ }
+ gl_draw_scaled_rotated_image( x, y, width, height, 0.f, image, color, uv_rect );
+}
+
+void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 border_width, S32 border_height, S32 width, S32 height, LLTexture* image, const LLColor4& color, BOOL solid_color, const LLRectf& uv_rect)
+{
+ if (NULL == image)
+ {
+ llwarns << "image == NULL; aborting function" << llendl;
+ return;
+ }
+
+ // scale screen size of borders down
+ F32 border_width_fraction = (F32)border_width / (F32)image->getWidth(0);
+ F32 border_height_fraction = (F32)border_height / (F32)image->getHeight(0);
+
+ LLRectf scale_rect(border_width_fraction, 1.f - border_height_fraction, 1.f - border_width_fraction, border_height_fraction);
+ gl_draw_scaled_image_with_border(x, y, width, height, image, color, solid_color, uv_rect, scale_rect);
+}
+
+void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color, BOOL solid_color, const LLRectf& uv_outer_rect, const LLRectf& center_rect)
+{
+ stop_glerror();
+
+ if (NULL == image)
+ {
+ llwarns << "image == NULL; aborting function" << llendl;
+ return;
+ }
+
+ // add in offset of current image to current UI translation
+ const LLVector3 ui_scale = gGL.getUIScale();
+ const LLVector3 ui_translation = (gGL.getUITranslation() + LLVector3(x, y, 0.f)).scaledVec(ui_scale);
+
+ F32 uv_width = uv_outer_rect.getWidth();
+ F32 uv_height = uv_outer_rect.getHeight();
+
+ // shrink scaling region to be proportional to clipped image region
+ LLRectf uv_center_rect(
+ uv_outer_rect.mLeft + (center_rect.mLeft * uv_width),
+ uv_outer_rect.mBottom + (center_rect.mTop * uv_height),
+ uv_outer_rect.mLeft + (center_rect.mRight * uv_width),
+ uv_outer_rect.mBottom + (center_rect.mBottom * uv_height));
+
+ F32 image_width = image->getWidth(0);
+ F32 image_height = image->getHeight(0);
+
+ S32 image_natural_width = llround(image_width * uv_width);
+ S32 image_natural_height = llround(image_height * uv_height);
+
+ LLRectf draw_center_rect( uv_center_rect.mLeft * image_width,
+ uv_center_rect.mTop * image_height,
+ uv_center_rect.mRight * image_width,
+ uv_center_rect.mBottom * image_height);
+
+ { // scale fixed region of image to drawn region
+ draw_center_rect.mRight += width - image_natural_width;
+ draw_center_rect.mTop += height - image_natural_height;
+
+ F32 border_shrink_width = llmax(0.f, draw_center_rect.mLeft - draw_center_rect.mRight);
+ F32 border_shrink_height = llmax(0.f, draw_center_rect.mBottom - draw_center_rect.mTop);
+
+ F32 shrink_width_ratio = center_rect.getWidth() == 1.f ? 0.f : border_shrink_width / ((F32)image_natural_width * (1.f - center_rect.getWidth()));
+ F32 shrink_height_ratio = center_rect.getHeight() == 1.f ? 0.f : border_shrink_height / ((F32)image_natural_height * (1.f - center_rect.getHeight()));
+
+ F32 shrink_scale = 1.f - llmax(shrink_width_ratio, shrink_height_ratio);
+
+ draw_center_rect.mLeft = llround(ui_translation.mV[VX] + (F32)draw_center_rect.mLeft * shrink_scale * ui_scale.mV[VX]);
+ draw_center_rect.mTop = llround(ui_translation.mV[VY] + lerp((F32)height, (F32)draw_center_rect.mTop, shrink_scale) * ui_scale.mV[VY]);
+ draw_center_rect.mRight = llround(ui_translation.mV[VX] + lerp((F32)width, (F32)draw_center_rect.mRight, shrink_scale) * ui_scale.mV[VX]);
+ draw_center_rect.mBottom = llround(ui_translation.mV[VY] + (F32)draw_center_rect.mBottom * shrink_scale * ui_scale.mV[VY]);
+ }
+
+ LLRectf draw_outer_rect(ui_translation.mV[VX],
+ ui_translation.mV[VY] + height * ui_scale.mV[VY],
+ ui_translation.mV[VX] + width * ui_scale.mV[VX],
+ ui_translation.mV[VY]);
+
+ LLGLSUIDefault gls_ui;
+
+ if (solid_color)
+ {
+ if (LLGLSLShader::sNoFixedFunction)
+ {
+ gSolidColorProgram.bind();
+ }
+ else
+ {
+ gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_PREV_COLOR);
+ gGL.getTexUnit(0)->setTextureAlphaBlend(LLTexUnit::TBO_MULT, LLTexUnit::TBS_TEX_ALPHA, LLTexUnit::TBS_VERT_ALPHA);
+ }
+ }
+
+ gGL.getTexUnit(0)->bind(image, true);
+
+ gGL.color4fv(color.mV);
+
+ const S32 NUM_VERTICES = 9 * 4; // 9 quads
+ LLVector2 uv[NUM_VERTICES];
+ LLVector3 pos[NUM_VERTICES];
+
+ S32 index = 0;
+
+ gGL.begin(LLRender::QUADS);
+ {
+ // draw bottom left
+ uv[index] = LLVector2(uv_outer_rect.mLeft, uv_outer_rect.mBottom);
+ pos[index] = LLVector3(draw_outer_rect.mLeft, draw_outer_rect.mBottom, 0.f);
+ index++;
+
+ uv[index] = LLVector2(uv_center_rect.mLeft, uv_outer_rect.mBottom);
+ pos[index] = LLVector3(draw_center_rect.mLeft, draw_outer_rect.mBottom, 0.f);
+ index++;
+
+ uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mBottom);
+ pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f);
+ index++;
+
+ uv[index] = LLVector2(uv_outer_rect.mLeft, uv_center_rect.mBottom);
+ pos[index] = LLVector3(draw_outer_rect.mLeft, draw_center_rect.mBottom, 0.f);
+ index++;
+
+ // draw bottom middle
+ uv[index] = LLVector2(uv_center_rect.mLeft, uv_outer_rect.mBottom);
+ pos[index] = LLVector3(draw_center_rect.mLeft, draw_outer_rect.mBottom, 0.f);
+ index++;
+
+ uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mBottom);
+ pos[index] = LLVector3(draw_center_rect.mRight, draw_outer_rect.mBottom, 0.f);
+ index++;
+
+ uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mBottom);
+ pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f);
+ index++;
+
+ uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mBottom);
+ pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f);
+ index++;
+
+ // draw bottom right
+ uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mBottom);
+ pos[index] = LLVector3(draw_center_rect.mRight, draw_outer_rect.mBottom, 0.f);
+ index++;
+
+ uv[index] = LLVector2(uv_outer_rect.mRight, uv_outer_rect.mBottom);
+ pos[index] = LLVector3(draw_outer_rect.mRight, draw_outer_rect.mBottom, 0.f);
+ index++;
+
+ uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mBottom);
+ pos[index] = LLVector3(draw_outer_rect.mRight, draw_center_rect.mBottom, 0.f);
+ index++;
+
+ uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mBottom);
+ pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f);
+ index++;
+
+ // draw left
+ uv[index] = LLVector2(uv_outer_rect.mLeft, uv_center_rect.mBottom);
+ pos[index] = LLVector3(draw_outer_rect.mLeft, draw_center_rect.mBottom, 0.f);
+ index++;
+
+ uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mBottom);
+ pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f);
+ index++;
+
+ uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mTop);
+ pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f);
+ index++;
+
+ uv[index] = LLVector2(uv_outer_rect.mLeft, uv_center_rect.mTop);
+ pos[index] = LLVector3(draw_outer_rect.mLeft, draw_center_rect.mTop, 0.f);
+ index++;
+
+ // draw middle
+ uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mBottom);
+ pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f);
+ index++;
+
+ uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mBottom);
+ pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f);
+ index++;
+
+ uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mTop);
+ pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mTop, 0.f);
+ index++;
+
+ uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mTop);
+ pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f);
+ index++;
+
+ // draw right
+ uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mBottom);
+ pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f);
+ index++;
+
+ uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mBottom);
+ pos[index] = LLVector3(draw_outer_rect.mRight, draw_center_rect.mBottom, 0.f);
+ index++;
+
+ uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mTop);
+ pos[index] = LLVector3(draw_outer_rect.mRight, draw_center_rect.mTop, 0.f);
+ index++;
+
+ uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mTop);
+ pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mTop, 0.f);
+ index++;
+
+ // draw top left
+ uv[index] = LLVector2(uv_outer_rect.mLeft, uv_center_rect.mTop);
+ pos[index] = LLVector3(draw_outer_rect.mLeft, draw_center_rect.mTop, 0.f);
+ index++;
+
+ uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mTop);
+ pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f);
+ index++;
+
+ uv[index] = LLVector2(uv_center_rect.mLeft, uv_outer_rect.mTop);
+ pos[index] = LLVector3(draw_center_rect.mLeft, draw_outer_rect.mTop, 0.f);
+ index++;
+
+ uv[index] = LLVector2(uv_outer_rect.mLeft, uv_outer_rect.mTop);
+ pos[index] = LLVector3(draw_outer_rect.mLeft, draw_outer_rect.mTop, 0.f);
+ index++;
+
+ // draw top middle
+ uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mTop);
+ pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f);
+ index++;
+
+ uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mTop);
+ pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mTop, 0.f);
+ index++;
+
+ uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mTop);
+ pos[index] = LLVector3(draw_center_rect.mRight, draw_outer_rect.mTop, 0.f);
+ index++;
+
+ uv[index] = LLVector2(uv_center_rect.mLeft, uv_outer_rect.mTop);
+ pos[index] = LLVector3(draw_center_rect.mLeft, draw_outer_rect.mTop, 0.f);
+ index++;
+
+ // draw top right
+ uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mTop);
+ pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mTop, 0.f);
+ index++;
+
+ uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mTop);
+ pos[index] = LLVector3(draw_outer_rect.mRight, draw_center_rect.mTop, 0.f);
+ index++;
+
+ uv[index] = LLVector2(uv_outer_rect.mRight, uv_outer_rect.mTop);
+ pos[index] = LLVector3(draw_outer_rect.mRight, draw_outer_rect.mTop, 0.f);
+ index++;
+
+ uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mTop);
+ pos[index] = LLVector3(draw_center_rect.mRight, draw_outer_rect.mTop, 0.f);
+ index++;
+
+ gGL.vertexBatchPreTransformed(pos, uv, NUM_VERTICES);
+ }
+ gGL.end();
+
+ if (solid_color)
+ {
+ if (LLGLSLShader::sNoFixedFunction)
+ {
+ gUIProgram.bind();
+ }
+ else
+ {
+ gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
+ }
+ }
+}
+
+void gl_draw_rotated_image(S32 x, S32 y, F32 degrees, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect)
+{
+ gl_draw_scaled_rotated_image( x, y, image->getWidth(0), image->getHeight(0), degrees, image, color, uv_rect );
+}
+
+void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degrees, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect)
+{
+ if (NULL == image)
+ {
+ llwarns << "image == NULL; aborting function" << llendl;
+ return;
+ }
+
+ LLGLSUIDefault gls_ui;
+
+
+ gGL.getTexUnit(0)->bind(image, true);
+
+ gGL.color4fv(color.mV);
+
+ if (degrees == 0.f)
+ {
+ const S32 NUM_VERTICES = 4; // 9 quads
+ LLVector2 uv[NUM_VERTICES];
+ LLVector3 pos[NUM_VERTICES];
+
+ gGL.begin(LLRender::QUADS);
+ {
+ LLVector3 ui_scale = gGL.getUIScale();
+ LLVector3 ui_translation = gGL.getUITranslation();
+ ui_translation.mV[VX] += x;
+ ui_translation.mV[VY] += y;
+ ui_translation.scaleVec(ui_scale);
+ S32 index = 0;
+ S32 scaled_width = llround(width * ui_scale.mV[VX]);
+ S32 scaled_height = llround(height * ui_scale.mV[VY]);
+
+ uv[index] = LLVector2(uv_rect.mRight, uv_rect.mTop);
+ pos[index] = LLVector3(ui_translation.mV[VX] + scaled_width, ui_translation.mV[VY] + scaled_height, 0.f);
+ index++;
+
+ uv[index] = LLVector2(uv_rect.mLeft, uv_rect.mTop);
+ pos[index] = LLVector3(ui_translation.mV[VX], ui_translation.mV[VY] + scaled_height, 0.f);
+ index++;
+
+ uv[index] = LLVector2(uv_rect.mLeft, uv_rect.mBottom);
+ pos[index] = LLVector3(ui_translation.mV[VX], ui_translation.mV[VY], 0.f);
+ index++;
+
+ uv[index] = LLVector2(uv_rect.mRight, uv_rect.mBottom);
+ pos[index] = LLVector3(ui_translation.mV[VX] + scaled_width, ui_translation.mV[VY], 0.f);
+ index++;
+
+ gGL.vertexBatchPreTransformed(pos, uv, NUM_VERTICES);
+ }
+ gGL.end();
+ }
+ else
+ {
+ gGL.pushUIMatrix();
+ gGL.translateUI((F32)x, (F32)y, 0.f);
+
+ F32 offset_x = F32(width/2);
+ F32 offset_y = F32(height/2);
+
+ gGL.translateUI(offset_x, offset_y, 0.f);
+
+ LLMatrix3 quat(0.f, 0.f, degrees*DEG_TO_RAD);
+
+ gGL.getTexUnit(0)->bind(image, true);
+
+ gGL.color4fv(color.mV);
+
+ gGL.begin(LLRender::QUADS);
+ {
+ LLVector3 v;
+
+ v = LLVector3(offset_x, offset_y, 0.f) * quat;
+ gGL.texCoord2f(uv_rect.mRight, uv_rect.mTop);
+ gGL.vertex2f(v.mV[0], v.mV[1] );
+
+ v = LLVector3(-offset_x, offset_y, 0.f) * quat;
+ gGL.texCoord2f(uv_rect.mLeft, uv_rect.mTop);
+ gGL.vertex2f(v.mV[0], v.mV[1] );
+
+ v = LLVector3(-offset_x, -offset_y, 0.f) * quat;
+ gGL.texCoord2f(uv_rect.mLeft, uv_rect.mBottom);
+ gGL.vertex2f(v.mV[0], v.mV[1] );
+
+ v = LLVector3(offset_x, -offset_y, 0.f) * quat;
+ gGL.texCoord2f(uv_rect.mRight, uv_rect.mBottom);
+ gGL.vertex2f(v.mV[0], v.mV[1] );
+ }
+ gGL.end();
+ gGL.popUIMatrix();
+ }
+}
+
+
+void gl_stippled_line_3d( const LLVector3& start, const LLVector3& end, const LLColor4& color, F32 phase )
+{
+ phase = fmod(phase, 1.f);
+
+ S32 shift = S32(phase * 4.f) % 4;
+
+ // Stippled line
+ LLGLEnable stipple(GL_LINE_STIPPLE);
+
+ gGL.color4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], color.mV[VALPHA]);
+
+ gGL.flush();
+ glLineWidth(2.5f);
+
+ if (!LLGLSLShader::sNoFixedFunction)
+ {
+ glLineStipple(2, 0x3333 << shift);
+ }
+
+ gGL.begin(LLRender::LINES);
+ {
+ gGL.vertex3fv( start.mV );
+ gGL.vertex3fv( end.mV );
+ }
+ gGL.end();
+
+ LLRender2D::setLineWidth(1.f);
+}
+
+void gl_arc_2d(F32 center_x, F32 center_y, F32 radius, S32 steps, BOOL filled, F32 start_angle, F32 end_angle)
+{
+ if (end_angle < start_angle)
+ {
+ end_angle += F_TWO_PI;
+ }
+
+ gGL.pushUIMatrix();
+ {
+ gGL.translateUI(center_x, center_y, 0.f);
+
+ // Inexact, but reasonably fast.
+ F32 delta = (end_angle - start_angle) / steps;
+ F32 sin_delta = sin( delta );
+ F32 cos_delta = cos( delta );
+ F32 x = cosf(start_angle) * radius;
+ F32 y = sinf(start_angle) * radius;
+
+ if (filled)
+ {
+ gGL.begin(LLRender::TRIANGLE_FAN);
+ gGL.vertex2f(0.f, 0.f);
+ // make sure circle is complete
+ steps += 1;
+ }
+ else
+ {
+ gGL.begin(LLRender::LINE_STRIP);
+ }
+
+ while( steps-- )
+ {
+ // Successive rotations
+ gGL.vertex2f( x, y );
+ F32 x_new = x * cos_delta - y * sin_delta;
+ y = x * sin_delta + y * cos_delta;
+ x = x_new;
+ }
+ gGL.end();
+ }
+ gGL.popUIMatrix();
+}
+
+void gl_circle_2d(F32 center_x, F32 center_y, F32 radius, S32 steps, BOOL filled)
+{
+ gGL.pushUIMatrix();
+ {
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.translateUI(center_x, center_y, 0.f);
+
+ // Inexact, but reasonably fast.
+ F32 delta = F_TWO_PI / steps;
+ F32 sin_delta = sin( delta );
+ F32 cos_delta = cos( delta );
+ F32 x = radius;
+ F32 y = 0.f;
+
+ if (filled)
+ {
+ gGL.begin(LLRender::TRIANGLE_FAN);
+ gGL.vertex2f(0.f, 0.f);
+ // make sure circle is complete
+ steps += 1;
+ }
+ else
+ {
+ gGL.begin(LLRender::LINE_LOOP);
+ }
+
+ while( steps-- )
+ {
+ // Successive rotations
+ gGL.vertex2f( x, y );
+ F32 x_new = x * cos_delta - y * sin_delta;
+ y = x * sin_delta + y * cos_delta;
+ x = x_new;
+ }
+ gGL.end();
+ }
+ gGL.popUIMatrix();
+}
+
+// Renders a ring with sides (tube shape)
+void gl_deep_circle( F32 radius, F32 depth, S32 steps )
+{
+ F32 x = radius;
+ F32 y = 0.f;
+ F32 angle_delta = F_TWO_PI / (F32)steps;
+ gGL.begin( LLRender::TRIANGLE_STRIP );
+ {
+ S32 step = steps + 1; // An extra step to close the circle.
+ while( step-- )
+ {
+ gGL.vertex3f( x, y, depth );
+ gGL.vertex3f( x, y, 0.f );
+
+ F32 x_new = x * cosf(angle_delta) - y * sinf(angle_delta);
+ y = x * sinf(angle_delta) + y * cosf(angle_delta);
+ x = x_new;
+ }
+ }
+ gGL.end();
+}
+
+void gl_ring( F32 radius, F32 width, const LLColor4& center_color, const LLColor4& side_color, S32 steps, BOOL render_center )
+{
+ gGL.pushUIMatrix();
+ {
+ gGL.translateUI(0.f, 0.f, -width / 2);
+ if( render_center )
+ {
+ gGL.color4fv(center_color.mV);
+ gGL.diffuseColor4fv(center_color.mV);
+ gl_deep_circle( radius, width, steps );
+ }
+ else
+ {
+ gGL.diffuseColor4fv(side_color.mV);
+ gl_washer_2d(radius, radius - width, steps, side_color, side_color);
+ gGL.translateUI(0.f, 0.f, width);
+ gl_washer_2d(radius - width, radius, steps, side_color, side_color);
+ }
+ }
+ gGL.popUIMatrix();
+}
+
+// Draw gray and white checkerboard with black border
+void gl_rect_2d_checkerboard(const LLRect& rect, GLfloat alpha)
+{
+ if (!LLGLSLShader::sNoFixedFunction)
+ {
+ // Initialize the first time this is called.
+ const S32 PIXELS = 32;
+ static GLubyte checkerboard[PIXELS * PIXELS];
+ static BOOL first = TRUE;
+ if( first )
+ {
+ for( S32 i = 0; i < PIXELS; i++ )
+ {
+ for( S32 j = 0; j < PIXELS; j++ )
+ {
+ checkerboard[i * PIXELS + j] = ((i & 1) ^ (j & 1)) * 0xFF;
+ }
+ }
+ first = FALSE;
+ }
+
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+ // ...white squares
+ gGL.color4f( 1.f, 1.f, 1.f, alpha );
+ gl_rect_2d(rect);
+
+ // ...gray squares
+ gGL.color4f( .7f, .7f, .7f, alpha );
+ gGL.flush();
+
+ glPolygonStipple( checkerboard );
+
+ LLGLEnable polygon_stipple(GL_POLYGON_STIPPLE);
+ gl_rect_2d(rect);
+ }
+ else
+ { //polygon stipple is deprecated, use "Checker" texture
+ LLPointer<LLUIImage> img = LLRender2D::getUIImage("Checker");
+ gGL.getTexUnit(0)->bind(img->getImage());
+ gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_WRAP);
+ gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
+
+ LLColor4 color(1.f, 1.f, 1.f, alpha);
+ LLRectf uv_rect(0, 0, rect.getWidth()/32.f, rect.getHeight()/32.f);
+
+ gl_draw_scaled_image(rect.mLeft, rect.mBottom, rect.getWidth(), rect.getHeight(),
+ img->getImage(), color, uv_rect);
+ }
+
+ gGL.flush();
+}
+
+
+// Draws the area between two concentric circles, like
+// a doughnut or washer.
+void gl_washer_2d(F32 outer_radius, F32 inner_radius, S32 steps, const LLColor4& inner_color, const LLColor4& outer_color)
+{
+ const F32 DELTA = F_TWO_PI / steps;
+ const F32 SIN_DELTA = sin( DELTA );
+ const F32 COS_DELTA = cos( DELTA );
+
+ F32 x1 = outer_radius;
+ F32 y1 = 0.f;
+ F32 x2 = inner_radius;
+ F32 y2 = 0.f;
+
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+ gGL.begin( LLRender::TRIANGLE_STRIP );
+ {
+ steps += 1; // An extra step to close the circle.
+ while( steps-- )
+ {
+ gGL.color4fv(outer_color.mV);
+ gGL.vertex2f( x1, y1 );
+ gGL.color4fv(inner_color.mV);
+ gGL.vertex2f( x2, y2 );
+
+ F32 x1_new = x1 * COS_DELTA - y1 * SIN_DELTA;
+ y1 = x1 * SIN_DELTA + y1 * COS_DELTA;
+ x1 = x1_new;
+
+ F32 x2_new = x2 * COS_DELTA - y2 * SIN_DELTA;
+ y2 = x2 * SIN_DELTA + y2 * COS_DELTA;
+ x2 = x2_new;
+ }
+ }
+ gGL.end();
+}
+
+// Draws the area between two concentric circles, like
+// a doughnut or washer.
+void gl_washer_segment_2d(F32 outer_radius, F32 inner_radius, F32 start_radians, F32 end_radians, S32 steps, const LLColor4& inner_color, const LLColor4& outer_color)
+{
+ const F32 DELTA = (end_radians - start_radians) / steps;
+ const F32 SIN_DELTA = sin( DELTA );
+ const F32 COS_DELTA = cos( DELTA );
+
+ F32 x1 = outer_radius * cos( start_radians );
+ F32 y1 = outer_radius * sin( start_radians );
+ F32 x2 = inner_radius * cos( start_radians );
+ F32 y2 = inner_radius * sin( start_radians );
+
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.begin( LLRender::TRIANGLE_STRIP );
+ {
+ steps += 1; // An extra step to close the circle.
+ while( steps-- )
+ {
+ gGL.color4fv(outer_color.mV);
+ gGL.vertex2f( x1, y1 );
+ gGL.color4fv(inner_color.mV);
+ gGL.vertex2f( x2, y2 );
+
+ F32 x1_new = x1 * COS_DELTA - y1 * SIN_DELTA;
+ y1 = x1 * SIN_DELTA + y1 * COS_DELTA;
+ x1 = x1_new;
+
+ F32 x2_new = x2 * COS_DELTA - y2 * SIN_DELTA;
+ y2 = x2 * SIN_DELTA + y2 * COS_DELTA;
+ x2 = x2_new;
+ }
+ }
+ gGL.end();
+}
+
+void gl_rect_2d_simple_tex( S32 width, S32 height )
+{
+ gGL.begin( LLRender::QUADS );
+
+ gGL.texCoord2f(1.f, 1.f);
+ gGL.vertex2i(width, height);
+
+ gGL.texCoord2f(0.f, 1.f);
+ gGL.vertex2i(0, height);
+
+ gGL.texCoord2f(0.f, 0.f);
+ gGL.vertex2i(0, 0);
+
+ gGL.texCoord2f(1.f, 0.f);
+ gGL.vertex2i(width, 0);
+
+ gGL.end();
+}
+
+void gl_rect_2d_simple( S32 width, S32 height )
+{
+ gGL.begin( LLRender::QUADS );
+ gGL.vertex2i(width, height);
+ gGL.vertex2i(0, height);
+ gGL.vertex2i(0, 0);
+ gGL.vertex2i(width, 0);
+ gGL.end();
+}
+
+void gl_segmented_rect_2d_tex(const S32 left,
+ const S32 top,
+ const S32 right,
+ const S32 bottom,
+ const S32 texture_width,
+ const S32 texture_height,
+ const S32 border_size,
+ const U32 edges)
+{
+ S32 width = llabs(right - left);
+ S32 height = llabs(top - bottom);
+
+ gGL.pushUIMatrix();
+
+ gGL.translateUI((F32)left, (F32)bottom, 0.f);
+ LLVector2 border_uv_scale((F32)border_size / (F32)texture_width, (F32)border_size / (F32)texture_height);
+
+ if (border_uv_scale.mV[VX] > 0.5f)
+ {
+ border_uv_scale *= 0.5f / border_uv_scale.mV[VX];
+ }
+ if (border_uv_scale.mV[VY] > 0.5f)
+ {
+ border_uv_scale *= 0.5f / border_uv_scale.mV[VY];
+ }
+
+ F32 border_scale = llmin((F32)border_size, (F32)width * 0.5f, (F32)height * 0.5f);
+ LLVector2 border_width_left = ((edges & (~(U32)ROUNDED_RECT_RIGHT)) != 0) ? LLVector2(border_scale, 0.f) : LLVector2::zero;
+ LLVector2 border_width_right = ((edges & (~(U32)ROUNDED_RECT_LEFT)) != 0) ? LLVector2(border_scale, 0.f) : LLVector2::zero;
+ LLVector2 border_height_bottom = ((edges & (~(U32)ROUNDED_RECT_TOP)) != 0) ? LLVector2(0.f, border_scale) : LLVector2::zero;
+ LLVector2 border_height_top = ((edges & (~(U32)ROUNDED_RECT_BOTTOM)) != 0) ? LLVector2(0.f, border_scale) : LLVector2::zero;
+ LLVector2 width_vec((F32)width, 0.f);
+ LLVector2 height_vec(0.f, (F32)height);
+
+ gGL.begin(LLRender::QUADS);
+ {
+ // draw bottom left
+ gGL.texCoord2f(0.f, 0.f);
+ gGL.vertex2f(0.f, 0.f);
+
+ gGL.texCoord2f(border_uv_scale.mV[VX], 0.f);
+ gGL.vertex2fv(border_width_left.mV);
+
+ gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
+ gGL.vertex2fv((border_width_left + border_height_bottom).mV);
+
+ gGL.texCoord2f(0.f, border_uv_scale.mV[VY]);
+ gGL.vertex2fv(border_height_bottom.mV);
+
+ // draw bottom middle
+ gGL.texCoord2f(border_uv_scale.mV[VX], 0.f);
+ gGL.vertex2fv(border_width_left.mV);
+
+ gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 0.f);
+ gGL.vertex2fv((width_vec - border_width_right).mV);
+
+ gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
+ gGL.vertex2fv((width_vec - border_width_right + border_height_bottom).mV);
+
+ gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
+ gGL.vertex2fv((border_width_left + border_height_bottom).mV);
+
+ // draw bottom right
+ gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 0.f);
+ gGL.vertex2fv((width_vec - border_width_right).mV);
+
+ gGL.texCoord2f(1.f, 0.f);
+ gGL.vertex2fv(width_vec.mV);
+
+ gGL.texCoord2f(1.f, border_uv_scale.mV[VY]);
+ gGL.vertex2fv((width_vec + border_height_bottom).mV);
+
+ gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
+ gGL.vertex2fv((width_vec - border_width_right + border_height_bottom).mV);
+
+ // draw left
+ gGL.texCoord2f(0.f, border_uv_scale.mV[VY]);
+ gGL.vertex2fv(border_height_bottom.mV);
+
+ gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
+ gGL.vertex2fv((border_width_left + border_height_bottom).mV);
+
+ gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
+ gGL.vertex2fv((border_width_left + height_vec - border_height_top).mV);
+
+ gGL.texCoord2f(0.f, 1.f - border_uv_scale.mV[VY]);
+ gGL.vertex2fv((height_vec - border_height_top).mV);
+
+ // draw middle
+ gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
+ gGL.vertex2fv((border_width_left + border_height_bottom).mV);
+
+ gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
+ gGL.vertex2fv((width_vec - border_width_right + border_height_bottom).mV);
+
+ gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
+ gGL.vertex2fv((width_vec - border_width_right + height_vec - border_height_top).mV);
+
+ gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
+ gGL.vertex2fv((border_width_left + height_vec - border_height_top).mV);
+
+ // draw right
+ gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
+ gGL.vertex2fv((width_vec - border_width_right + border_height_bottom).mV);
+
+ gGL.texCoord2f(1.f, border_uv_scale.mV[VY]);
+ gGL.vertex2fv((width_vec + border_height_bottom).mV);
+
+ gGL.texCoord2f(1.f, 1.f - border_uv_scale.mV[VY]);
+ gGL.vertex2fv((width_vec + height_vec - border_height_top).mV);
+
+ gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
+ gGL.vertex2fv((width_vec - border_width_right + height_vec - border_height_top).mV);
+
+ // draw top left
+ gGL.texCoord2f(0.f, 1.f - border_uv_scale.mV[VY]);
+ gGL.vertex2fv((height_vec - border_height_top).mV);
+
+ gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
+ gGL.vertex2fv((border_width_left + height_vec - border_height_top).mV);
+
+ gGL.texCoord2f(border_uv_scale.mV[VX], 1.f);
+ gGL.vertex2fv((border_width_left + height_vec).mV);
+
+ gGL.texCoord2f(0.f, 1.f);
+ gGL.vertex2fv((height_vec).mV);
+
+ // draw top middle
+ gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
+ gGL.vertex2fv((border_width_left + height_vec - border_height_top).mV);
+
+ gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
+ gGL.vertex2fv((width_vec - border_width_right + height_vec - border_height_top).mV);
+
+ gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f);
+ gGL.vertex2fv((width_vec - border_width_right + height_vec).mV);
+
+ gGL.texCoord2f(border_uv_scale.mV[VX], 1.f);
+ gGL.vertex2fv((border_width_left + height_vec).mV);
+
+ // draw top right
+ gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
+ gGL.vertex2fv((width_vec - border_width_right + height_vec - border_height_top).mV);
+
+ gGL.texCoord2f(1.f, 1.f - border_uv_scale.mV[VY]);
+ gGL.vertex2fv((width_vec + height_vec - border_height_top).mV);
+
+ gGL.texCoord2f(1.f, 1.f);
+ gGL.vertex2fv((width_vec + height_vec).mV);
+
+ gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f);
+ gGL.vertex2fv((width_vec - border_width_right + height_vec).mV);
+ }
+ gGL.end();
+
+ gGL.popUIMatrix();
+}
+
+//FIXME: rewrite to use scissor?
+void gl_segmented_rect_2d_fragment_tex(const S32 left,
+ const S32 top,
+ const S32 right,
+ const S32 bottom,
+ const S32 texture_width,
+ const S32 texture_height,
+ const S32 border_size,
+ const F32 start_fragment,
+ const F32 end_fragment,
+ const U32 edges)
+{
+ S32 width = llabs(right - left);
+ S32 height = llabs(top - bottom);
+
+ gGL.pushUIMatrix();
+
+ gGL.translateUI((F32)left, (F32)bottom, 0.f);
+ LLVector2 border_uv_scale((F32)border_size / (F32)texture_width, (F32)border_size / (F32)texture_height);
+
+ if (border_uv_scale.mV[VX] > 0.5f)
+ {
+ border_uv_scale *= 0.5f / border_uv_scale.mV[VX];
+ }
+ if (border_uv_scale.mV[VY] > 0.5f)
+ {
+ border_uv_scale *= 0.5f / border_uv_scale.mV[VY];
+ }
+
+ F32 border_scale = llmin((F32)border_size, (F32)width * 0.5f, (F32)height * 0.5f);
+ LLVector2 border_width_left = ((edges & (~(U32)ROUNDED_RECT_RIGHT)) != 0) ? LLVector2(border_scale, 0.f) : LLVector2::zero;
+ LLVector2 border_width_right = ((edges & (~(U32)ROUNDED_RECT_LEFT)) != 0) ? LLVector2(border_scale, 0.f) : LLVector2::zero;
+ LLVector2 border_height_bottom = ((edges & (~(U32)ROUNDED_RECT_TOP)) != 0) ? LLVector2(0.f, border_scale) : LLVector2::zero;
+ LLVector2 border_height_top = ((edges & (~(U32)ROUNDED_RECT_BOTTOM)) != 0) ? LLVector2(0.f, border_scale) : LLVector2::zero;
+ LLVector2 width_vec((F32)width, 0.f);
+ LLVector2 height_vec(0.f, (F32)height);
+
+ F32 middle_start = border_scale / (F32)width;
+ F32 middle_end = 1.f - middle_start;
+
+ F32 u_min;
+ F32 u_max;
+ LLVector2 x_min;
+ LLVector2 x_max;
+
+ gGL.begin(LLRender::QUADS);
+ {
+ if (start_fragment < middle_start)
+ {
+ u_min = (start_fragment / middle_start) * border_uv_scale.mV[VX];
+ u_max = llmin(end_fragment / middle_start, 1.f) * border_uv_scale.mV[VX];
+ x_min = (start_fragment / middle_start) * border_width_left;
+ x_max = llmin(end_fragment / middle_start, 1.f) * border_width_left;
+
+ // draw bottom left
+ gGL.texCoord2f(u_min, 0.f);
+ gGL.vertex2fv(x_min.mV);
+
+ gGL.texCoord2f(border_uv_scale.mV[VX], 0.f);
+ gGL.vertex2fv(x_max.mV);
+
+ gGL.texCoord2f(u_max, border_uv_scale.mV[VY]);
+ gGL.vertex2fv((x_max + border_height_bottom).mV);
+
+ gGL.texCoord2f(u_min, border_uv_scale.mV[VY]);
+ gGL.vertex2fv((x_min + border_height_bottom).mV);
+
+ // draw left
+ gGL.texCoord2f(u_min, border_uv_scale.mV[VY]);
+ gGL.vertex2fv((x_min + border_height_bottom).mV);
+
+ gGL.texCoord2f(u_max, border_uv_scale.mV[VY]);
+ gGL.vertex2fv((x_max + border_height_bottom).mV);
+
+ gGL.texCoord2f(u_max, 1.f - border_uv_scale.mV[VY]);
+ gGL.vertex2fv((x_max + height_vec - border_height_top).mV);
+
+ gGL.texCoord2f(u_min, 1.f - border_uv_scale.mV[VY]);
+ gGL.vertex2fv((x_min + height_vec - border_height_top).mV);
+
+ // draw top left
+ gGL.texCoord2f(u_min, 1.f - border_uv_scale.mV[VY]);
+ gGL.vertex2fv((x_min + height_vec - border_height_top).mV);
+
+ gGL.texCoord2f(u_max, 1.f - border_uv_scale.mV[VY]);
+ gGL.vertex2fv((x_max + height_vec - border_height_top).mV);
+
+ gGL.texCoord2f(u_max, 1.f);
+ gGL.vertex2fv((x_max + height_vec).mV);
+
+ gGL.texCoord2f(u_min, 1.f);
+ gGL.vertex2fv((x_min + height_vec).mV);
+ }
+
+ if (end_fragment > middle_start || start_fragment < middle_end)
+ {
+ x_min = border_width_left + ((llclamp(start_fragment, middle_start, middle_end) - middle_start)) * width_vec;
+ x_max = border_width_left + ((llclamp(end_fragment, middle_start, middle_end) - middle_start)) * width_vec;
+
+ // draw bottom middle
+ gGL.texCoord2f(border_uv_scale.mV[VX], 0.f);
+ gGL.vertex2fv(x_min.mV);
+
+ gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 0.f);
+ gGL.vertex2fv((x_max).mV);
+
+ gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
+ gGL.vertex2fv((x_max + border_height_bottom).mV);
+
+ gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
+ gGL.vertex2fv((x_min + border_height_bottom).mV);
+
+ // draw middle
+ gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
+ gGL.vertex2fv((x_min + border_height_bottom).mV);
+
+ gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
+ gGL.vertex2fv((x_max + border_height_bottom).mV);
+
+ gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
+ gGL.vertex2fv((x_max + height_vec - border_height_top).mV);
+
+ gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
+ gGL.vertex2fv((x_min + height_vec - border_height_top).mV);
+
+ // draw top middle
+ gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
+ gGL.vertex2fv((x_min + height_vec - border_height_top).mV);
+
+ gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
+ gGL.vertex2fv((x_max + height_vec - border_height_top).mV);
+
+ gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f);
+ gGL.vertex2fv((x_max + height_vec).mV);
+
+ gGL.texCoord2f(border_uv_scale.mV[VX], 1.f);
+ gGL.vertex2fv((x_min + height_vec).mV);
+ }
+
+ if (end_fragment > middle_end)
+ {
+ u_min = (1.f - llmax(0.f, ((start_fragment - middle_end) / middle_start))) * border_uv_scale.mV[VX];
+ u_max = (1.f - ((end_fragment - middle_end) / middle_start)) * border_uv_scale.mV[VX];
+ x_min = width_vec - ((1.f - llmax(0.f, ((start_fragment - middle_end) / middle_start))) * border_width_right);
+ x_max = width_vec - ((1.f - ((end_fragment - middle_end) / middle_start)) * border_width_right);
+
+ // draw bottom right
+ gGL.texCoord2f(u_min, 0.f);
+ gGL.vertex2fv((x_min).mV);
+
+ gGL.texCoord2f(u_max, 0.f);
+ gGL.vertex2fv(x_max.mV);
+
+ gGL.texCoord2f(u_max, border_uv_scale.mV[VY]);
+ gGL.vertex2fv((x_max + border_height_bottom).mV);
+
+ gGL.texCoord2f(u_min, border_uv_scale.mV[VY]);
+ gGL.vertex2fv((x_min + border_height_bottom).mV);
+
+ // draw right
+ gGL.texCoord2f(u_min, border_uv_scale.mV[VY]);
+ gGL.vertex2fv((x_min + border_height_bottom).mV);
+
+ gGL.texCoord2f(u_max, border_uv_scale.mV[VY]);
+ gGL.vertex2fv((x_max + border_height_bottom).mV);
+
+ gGL.texCoord2f(u_max, 1.f - border_uv_scale.mV[VY]);
+ gGL.vertex2fv((x_max + height_vec - border_height_top).mV);
+
+ gGL.texCoord2f(u_min, 1.f - border_uv_scale.mV[VY]);
+ gGL.vertex2fv((x_min + height_vec - border_height_top).mV);
+
+ // draw top right
+ gGL.texCoord2f(u_min, 1.f - border_uv_scale.mV[VY]);
+ gGL.vertex2fv((x_min + height_vec - border_height_top).mV);
+
+ gGL.texCoord2f(u_max, 1.f - border_uv_scale.mV[VY]);
+ gGL.vertex2fv((x_max + height_vec - border_height_top).mV);
+
+ gGL.texCoord2f(u_max, 1.f);
+ gGL.vertex2fv((x_max + height_vec).mV);
+
+ gGL.texCoord2f(u_min, 1.f);
+ gGL.vertex2fv((x_min + height_vec).mV);
+ }
+ }
+ gGL.end();
+
+ gGL.popUIMatrix();
+}
+
+void gl_segmented_rect_3d_tex(const LLRectf& clip_rect, const LLRectf& center_uv_rect, const LLRectf& center_draw_rect,
+ const LLVector3& width_vec, const LLVector3& height_vec)
+{
+ gGL.begin(LLRender::QUADS);
+ {
+ // draw bottom left
+ gGL.texCoord2f(clip_rect.mLeft, clip_rect.mBottom);
+ gGL.vertex3f(0.f, 0.f, 0.f);
+
+ gGL.texCoord2f(center_uv_rect.mLeft, clip_rect.mBottom);
+ gGL.vertex3fv((center_draw_rect.mLeft * width_vec).mV);
+
+ gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mBottom);
+ gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mBottom * height_vec).mV);
+
+ gGL.texCoord2f(clip_rect.mLeft, center_uv_rect.mBottom);
+ gGL.vertex3fv((center_draw_rect.mBottom * height_vec).mV);
+
+ // draw bottom middle
+ gGL.texCoord2f(center_uv_rect.mLeft, clip_rect.mBottom);
+ gGL.vertex3fv((center_draw_rect.mLeft * width_vec).mV);
+
+ gGL.texCoord2f(center_uv_rect.mRight, clip_rect.mBottom);
+ gGL.vertex3fv((center_draw_rect.mRight * width_vec).mV);
+
+ gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mBottom);
+ gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mBottom * height_vec).mV);
+
+ gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mBottom);
+ gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mBottom * height_vec).mV);
+
+ // draw bottom right
+ gGL.texCoord2f(center_uv_rect.mRight, clip_rect.mBottom);
+ gGL.vertex3fv((center_draw_rect.mRight * width_vec).mV);
+
+ gGL.texCoord2f(clip_rect.mRight, clip_rect.mBottom);
+ gGL.vertex3fv(width_vec.mV);
+
+ gGL.texCoord2f(clip_rect.mRight, center_uv_rect.mBottom);
+ gGL.vertex3fv((width_vec + center_draw_rect.mBottom * height_vec).mV);
+
+ gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mBottom);
+ gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mBottom * height_vec).mV);
+
+ // draw left
+ gGL.texCoord2f(clip_rect.mLeft, center_uv_rect.mBottom);
+ gGL.vertex3fv((center_draw_rect.mBottom * height_vec).mV);
+
+ gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mBottom);
+ gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mBottom * height_vec).mV);
+
+ gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mTop);
+ gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mTop * height_vec).mV);
+
+ gGL.texCoord2f(clip_rect.mLeft, center_uv_rect.mTop);
+ gGL.vertex3fv((center_draw_rect.mTop * height_vec).mV);
+
+ // draw middle
+ gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mBottom);
+ gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mBottom * height_vec).mV);
+
+ gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mBottom);
+ gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mBottom * height_vec).mV);
+
+ gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mTop);
+ gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mTop * height_vec).mV);
+
+ gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mTop);
+ gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mTop * height_vec).mV);
+
+ // draw right
+ gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mBottom);
+ gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mBottom * height_vec).mV);
+
+ gGL.texCoord2f(clip_rect.mRight, center_uv_rect.mBottom);
+ gGL.vertex3fv((width_vec + center_draw_rect.mBottom * height_vec).mV);
+
+ gGL.texCoord2f(clip_rect.mRight, center_uv_rect.mTop);
+ gGL.vertex3fv((width_vec + center_draw_rect.mTop * height_vec).mV);
+
+ gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mTop);
+ gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mTop * height_vec).mV);
+
+ // draw top left
+ gGL.texCoord2f(clip_rect.mLeft, center_uv_rect.mTop);
+ gGL.vertex3fv((center_draw_rect.mTop * height_vec).mV);
+
+ gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mTop);
+ gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mTop * height_vec).mV);
+
+ gGL.texCoord2f(center_uv_rect.mLeft, clip_rect.mTop);
+ gGL.vertex3fv((center_draw_rect.mLeft * width_vec + height_vec).mV);
+
+ gGL.texCoord2f(clip_rect.mLeft, clip_rect.mTop);
+ gGL.vertex3fv((height_vec).mV);
+
+ // draw top middle
+ gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mTop);
+ gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mTop * height_vec).mV);
+
+ gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mTop);
+ gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mTop * height_vec).mV);
+
+ gGL.texCoord2f(center_uv_rect.mRight, clip_rect.mTop);
+ gGL.vertex3fv((center_draw_rect.mRight * width_vec + height_vec).mV);
+
+ gGL.texCoord2f(center_uv_rect.mLeft, clip_rect.mTop);
+ gGL.vertex3fv((center_draw_rect.mLeft * width_vec + height_vec).mV);
+
+ // draw top right
+ gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mTop);
+ gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mTop * height_vec).mV);
+
+ gGL.texCoord2f(clip_rect.mRight, center_uv_rect.mTop);
+ gGL.vertex3fv((width_vec + center_draw_rect.mTop * height_vec).mV);
+
+ gGL.texCoord2f(clip_rect.mRight, clip_rect.mTop);
+ gGL.vertex3fv((width_vec + height_vec).mV);
+
+ gGL.texCoord2f(center_uv_rect.mRight, clip_rect.mTop);
+ gGL.vertex3fv((center_draw_rect.mRight * width_vec + height_vec).mV);
+ }
+ gGL.end();
+
+}
+
+// static
+void LLRender2D::initClass(LLImageProviderInterface* image_provider,
+ const LLVector2* scale_factor)
+{
+ sGLScaleFactor = (scale_factor == NULL) ? LLVector2(1.f, 1.f) : *scale_factor;
+ sImageProvider = image_provider;
+}
+
+// static
+void LLRender2D::cleanupClass()
+{
+ if(sImageProvider)
+ {
+ sImageProvider->cleanUp();
+ }
+}
+
+
+//static
+void LLRender2D::translate(F32 x, F32 y, F32 z)
+{
+ gGL.translateUI(x,y,z);
+ LLFontGL::sCurOrigin.mX += (S32) x;
+ LLFontGL::sCurOrigin.mY += (S32) y;
+ LLFontGL::sCurDepth += z;
+}
+
+//static
+void LLRender2D::pushMatrix()
+{
+ gGL.pushUIMatrix();
+ LLFontGL::sOriginStack.push_back(std::make_pair(LLFontGL::sCurOrigin, LLFontGL::sCurDepth));
+}
+
+//static
+void LLRender2D::popMatrix()
+{
+ gGL.popUIMatrix();
+ LLFontGL::sCurOrigin = LLFontGL::sOriginStack.back().first;
+ LLFontGL::sCurDepth = LLFontGL::sOriginStack.back().second;
+ LLFontGL::sOriginStack.pop_back();
+}
+
+//static
+void LLRender2D::loadIdentity()
+{
+ gGL.loadUIIdentity();
+ LLFontGL::sCurOrigin.mX = 0;
+ LLFontGL::sCurOrigin.mY = 0;
+ LLFontGL::sCurDepth = 0.f;
+}
+
+//static
+void LLRender2D::setScaleFactor(const LLVector2 &scale_factor)
+{
+ sGLScaleFactor = scale_factor;
+}
+
+//static
+void LLRender2D::setLineWidth(F32 width)
+{
+ gGL.flush();
+ glLineWidth(width * lerp(sGLScaleFactor.mV[VX], sGLScaleFactor.mV[VY], 0.5f));
+}
+
+//static
+LLPointer<LLUIImage> LLRender2D::getUIImageByID(const LLUUID& image_id, S32 priority)
+{
+ if (sImageProvider)
+ {
+ return sImageProvider->getUIImageByID(image_id, priority);
+ }
+ else
+ {
+ return NULL;
+ }
+}
+
+//static
+LLPointer<LLUIImage> LLRender2D::getUIImage(const std::string& name, S32 priority)
+{
+ if (!name.empty() && sImageProvider)
+ return sImageProvider->getUIImage(name, priority);
+ else
+ return NULL;
+}
+
diff --git a/indra/llrender/llrender2dutils.h b/indra/llrender/llrender2dutils.h
new file mode 100644
index 0000000000..4884422c58
--- /dev/null
+++ b/indra/llrender/llrender2dutils.h
@@ -0,0 +1,163 @@
+/**
+ * @file llrender2dutils.h
+ * @brief GL function declarations for immediate-mode gl drawing.
+ *
+ * $LicenseInfo:firstyear=2012&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$
+ */
+
+// All immediate-mode gl drawing should happen here.
+
+
+#ifndef LL_RENDER2DUTILS_H
+#define LL_RENDER2DUTILS_H
+
+#include "llpointer.h" // LLPointer<>
+#include "llrect.h"
+#include "llglslshader.h"
+
+class LLColor4;
+class LLVector3;
+class LLVector2;
+class LLUIImage;
+class LLUUID;
+
+extern const LLColor4 UI_VERTEX_COLOR;
+
+BOOL ui_point_in_rect(S32 x, S32 y, S32 left, S32 top, S32 right, S32 bottom);
+void gl_state_for_2d(S32 width, S32 height);
+
+void gl_line_2d(S32 x1, S32 y1, S32 x2, S32 y2);
+void gl_line_2d(S32 x1, S32 y1, S32 x2, S32 y2, const LLColor4 &color );
+void gl_triangle_2d(S32 x1, S32 y1, S32 x2, S32 y2, S32 x3, S32 y3, const LLColor4& color, BOOL filled);
+void gl_rect_2d_simple( S32 width, S32 height );
+
+void gl_draw_x(const LLRect& rect, const LLColor4& color);
+
+void gl_rect_2d(S32 left, S32 top, S32 right, S32 bottom, BOOL filled = TRUE );
+void gl_rect_2d(S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &color, BOOL filled = TRUE );
+void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &color, S32 pixel_offset = 0, BOOL filled = TRUE );
+void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, S32 pixel_offset = 0, BOOL filled = TRUE );
+void gl_rect_2d(const LLRect& rect, BOOL filled = TRUE );
+void gl_rect_2d(const LLRect& rect, const LLColor4& color, BOOL filled = TRUE );
+void gl_rect_2d_checkerboard(const LLRect& rect, GLfloat alpha = 1.0f);
+
+void gl_drop_shadow(S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &start_color, S32 lines);
+
+void gl_circle_2d(F32 x, F32 y, F32 radius, S32 steps, BOOL filled);
+void gl_arc_2d(F32 center_x, F32 center_y, F32 radius, S32 steps, BOOL filled, F32 start_angle, F32 end_angle);
+void gl_deep_circle( F32 radius, F32 depth );
+void gl_ring( F32 radius, F32 width, const LLColor4& center_color, const LLColor4& side_color, S32 steps, BOOL render_center );
+void gl_corners_2d(S32 left, S32 top, S32 right, S32 bottom, S32 length, F32 max_frac);
+void gl_washer_2d(F32 outer_radius, F32 inner_radius, S32 steps, const LLColor4& inner_color, const LLColor4& outer_color);
+void gl_washer_segment_2d(F32 outer_radius, F32 inner_radius, F32 start_radians, F32 end_radians, S32 steps, const LLColor4& inner_color, const LLColor4& outer_color);
+
+void gl_draw_image(S32 x, S32 y, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
+void gl_draw_scaled_image(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
+void gl_draw_rotated_image(S32 x, S32 y, F32 degrees, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
+void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degrees,LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
+void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 border_width, S32 border_height, S32 width, S32 height, LLTexture* image, const LLColor4 &color, BOOL solid_color = FALSE, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
+void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4 &color, BOOL solid_color = FALSE, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f), const LLRectf& scale_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
+
+void gl_stippled_line_3d( const LLVector3& start, const LLVector3& end, const LLColor4& color, F32 phase = 0.f );
+
+void gl_rect_2d_simple_tex( S32 width, S32 height );
+
+// segmented rectangles
+
+/*
+ TL |______TOP_________| TR
+ /| |\
+ _/_|__________________|_\_
+ L| | MIDDLE | |R
+ _|_|__________________|_|_
+ \ | BOTTOM | /
+ BL\|__________________|/ BR
+ | |
+*/
+
+typedef enum e_rounded_edge
+{
+ ROUNDED_RECT_LEFT = 0x1,
+ ROUNDED_RECT_TOP = 0x2,
+ ROUNDED_RECT_RIGHT = 0x4,
+ ROUNDED_RECT_BOTTOM = 0x8,
+ ROUNDED_RECT_ALL = 0xf
+}ERoundedEdge;
+
+
+void gl_segmented_rect_2d_tex(const S32 left, const S32 top, const S32 right, const S32 bottom, const S32 texture_width, const S32 texture_height, const S32 border_size, const U32 edges = ROUNDED_RECT_ALL);
+void gl_segmented_rect_2d_fragment_tex(const S32 left, const S32 top, const S32 right, const S32 bottom, const S32 texture_width, const S32 texture_height, const S32 border_size, const F32 start_fragment, const F32 end_fragment, const U32 edges = ROUNDED_RECT_ALL);
+void gl_segmented_rect_3d_tex(const LLRectf& clip_rect, const LLRectf& center_uv_rect, const LLRectf& center_draw_rect, const LLVector3& width_vec, const LLVector3& height_vec);
+
+inline void gl_rect_2d( const LLRect& rect, BOOL filled )
+{
+ gl_rect_2d( rect.mLeft, rect.mTop, rect.mRight, rect.mBottom, filled );
+}
+
+inline void gl_rect_2d_offset_local( const LLRect& rect, S32 pixel_offset, BOOL filled)
+{
+ gl_rect_2d_offset_local( rect.mLeft, rect.mTop, rect.mRight, rect.mBottom, pixel_offset, filled );
+}
+
+class LLImageProviderInterface;
+
+class LLRender2D
+{
+ LOG_CLASS(LLRender2D);
+public:
+ static void initClass(LLImageProviderInterface* image_provider,
+ const LLVector2* scale_factor);
+ static void cleanupClass();
+
+ static void pushMatrix();
+ static void popMatrix();
+ static void loadIdentity();
+ static void translate(F32 x, F32 y, F32 z = 0.0f);
+
+ static void setLineWidth(F32 width);
+ static void setScaleFactor(const LLVector2& scale_factor);
+
+ static LLPointer<LLUIImage> getUIImageByID(const LLUUID& image_id, S32 priority = 0);
+ static LLPointer<LLUIImage> getUIImage(const std::string& name, S32 priority = 0);
+
+ static LLVector2 sGLScaleFactor;
+private:
+ static LLImageProviderInterface* sImageProvider;
+};
+
+class LLImageProviderInterface
+{
+protected:
+ LLImageProviderInterface() {};
+ virtual ~LLImageProviderInterface() {};
+public:
+ virtual LLPointer<LLUIImage> getUIImage(const std::string& name, S32 priority) = 0;
+ virtual LLPointer<LLUIImage> getUIImageByID(const LLUUID& id, S32 priority) = 0;
+ virtual void cleanUp() = 0;
+};
+
+
+extern LLGLSLShader gSolidColorProgram;
+extern LLGLSLShader gUIProgram;
+
+#endif // LL_RENDER2DUTILS_H
+
diff --git a/indra/llrender/llrendernavprim.cpp b/indra/llrender/llrendernavprim.cpp
new file mode 100755
index 0000000000..ca72964832
--- /dev/null
+++ b/indra/llrender/llrendernavprim.cpp
@@ -0,0 +1,59 @@
+/**
+* @file llrendernavprim.cpp
+* @brief Implementation of llrendernavprim
+* @author Prep@lindenlab.com
+*
+* $LicenseInfo:firstyear=2012&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2012, 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 "llrendernavprim.h"
+
+#include "llrender.h"
+#include "llvertexbuffer.h"
+#include "v4coloru.h"
+#include "v3math.h"
+
+//=============================================================================
+LLRenderNavPrim gRenderNav;
+//=============================================================================
+void LLRenderNavPrim::renderLLTri( const LLVector3& a, const LLVector3& b, const LLVector3& c, const LLColor4U& color ) const
+{
+ LLColor4 cV(color);
+ gGL.color4fv( cV.mV );
+ gGL.begin(LLRender::TRIANGLES);
+ {
+ gGL.vertex3fv( a.mV );
+ gGL.vertex3fv( b.mV );
+ gGL.vertex3fv( c.mV );
+ }
+ gGL.end();
+}
+//=============================================================================
+void LLRenderNavPrim::renderNavMeshVB( U32 mode, LLVertexBuffer* pVBO, int vertCnt )
+{
+ pVBO->setBuffer( LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_NORMAL );
+ pVBO->drawArrays( mode, 0, vertCnt );
+}
+//=============================================================================
diff --git a/indra/llrender/llrendernavprim.h b/indra/llrender/llrendernavprim.h
new file mode 100755
index 0000000000..a3a5dfec3a
--- /dev/null
+++ b/indra/llrender/llrendernavprim.h
@@ -0,0 +1,49 @@
+/**
+* @file llrendernavprim.h
+* @brief Header file for llrendernavprim
+* @author Prep@lindenlab.com
+*
+* $LicenseInfo:firstyear=2012&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2012, 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_LLRENDERNAVPRIM_H
+#define LL_LLRENDERNAVPRIM_H
+
+#include "stdtypes.h"
+
+class LLColor4U;
+class LLVector3;
+class LLVertexBuffer;
+
+
+class LLRenderNavPrim
+{
+public:
+ //Draw simple tri
+ void renderLLTri( const LLVector3& a, const LLVector3& b, const LLVector3& c, const LLColor4U& color ) const;
+ //Draw the contents of vertex buffer
+ void renderNavMeshVB( U32 mode, LLVertexBuffer* pVBO, int vertCnt );
+private:
+};
+
+extern LLRenderNavPrim gRenderNav;
+
+#endif // LL_LLRENDERNAVPRIM_H
diff --git a/indra/llrender/llrendersphere.cpp b/indra/llrender/llrendersphere.cpp
index 26bfe036e8..26bfe036e8 100644..100755
--- a/indra/llrender/llrendersphere.cpp
+++ b/indra/llrender/llrendersphere.cpp
diff --git a/indra/llrender/llrendersphere.h b/indra/llrender/llrendersphere.h
index f8e9e86e7f..f8e9e86e7f 100644..100755
--- a/indra/llrender/llrendersphere.h
+++ b/indra/llrender/llrendersphere.h
diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp
index ef2a7395da..fe8110904d 100644..100755
--- a/indra/llrender/llrendertarget.cpp
+++ b/indra/llrender/llrendertarget.cpp
@@ -51,12 +51,21 @@ void check_framebuffer_status()
}
bool LLRenderTarget::sUseFBO = false;
+U32 LLRenderTarget::sCurFBO = 0;
+
+
+extern S32 gGLViewport[4];
+
+U32 LLRenderTarget::sCurResX = 0;
+U32 LLRenderTarget::sCurResY = 0;
LLRenderTarget::LLRenderTarget() :
mResX(0),
mResY(0),
- mTex(0),
mFBO(0),
+ mPreviousFBO(0),
+ mPreviousResX(0),
+ mPreviousResY(0),
mDepth(0),
mStencil(0),
mUseDepth(false),
@@ -70,8 +79,49 @@ LLRenderTarget::~LLRenderTarget()
release();
}
+void LLRenderTarget::resize(U32 resx, U32 resy)
+{
+ //for accounting, get the number of pixels added/subtracted
+ S32 pix_diff = (resx*resy)-(mResX*mResY);
+
+ mResX = resx;
+ mResY = resy;
+
+ llassert(mInternalFormat.size() == mTex.size());
+
+ for (U32 i = 0; i < mTex.size(); ++i)
+ { //resize color attachments
+ gGL.getTexUnit(0)->bindManual(mUsage, mTex[i]);
+ LLImageGL::setManualImage(LLTexUnit::getInternalType(mUsage), 0, mInternalFormat[i], mResX, mResY, GL_RGBA, GL_UNSIGNED_BYTE, NULL, false);
+ sBytesAllocated += pix_diff*4;
+ }
+
+ if (mDepth)
+ { //resize depth attachment
+ if (mStencil)
+ {
+ //use render buffers where stencil buffers are in play
+ glBindRenderbuffer(GL_RENDERBUFFER, mDepth);
+ glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, mResX, mResY);
+ glBindRenderbuffer(GL_RENDERBUFFER, 0);
+ }
+ else
+ {
+ gGL.getTexUnit(0)->bindManual(mUsage, mDepth);
+ U32 internal_type = LLTexUnit::getInternalType(mUsage);
+ LLImageGL::setManualImage(internal_type, 0, GL_DEPTH_COMPONENT24, mResX, mResY, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL, false);
+ }
+
+ sBytesAllocated += pix_diff*4;
+ }
+}
+
+
bool LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage, bool use_fbo, S32 samples)
{
+ resx = llmin(resx, (U32) gGLManager.mGLMaxTextureSize);
+ resy = llmin(resy, (U32) gGLManager.mGLMaxTextureSize);
+
stop_glerror();
release();
stop_glerror();
@@ -111,7 +161,7 @@ bool LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, boo
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, LLTexUnit::getInternalType(mUsage), mDepth, 0);
stop_glerror();
}
- glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO);
}
stop_glerror();
@@ -128,10 +178,19 @@ bool LLRenderTarget::addColorAttachment(U32 color_fmt)
}
U32 offset = mTex.size();
- if (offset >= 4 ||
- (offset > 0 && (mFBO == 0 || !gGLManager.mHasDrawBuffers)))
+
+ if( offset >= 4 )
{
- llerrs << "Too many color attachments!" << llendl;
+ llwarns << "Too many color attachments" << llendl;
+ llassert( offset < 4 );
+ return false;
+ }
+ if( offset > 0 && (mFBO == 0 || !gGLManager.mHasDrawBuffers) )
+ {
+ llwarns << "FBO not used or no drawbuffers available; mFBO=" << (U32)mFBO << " gGLManager.mHasDrawBuffers=" << (U32)gGLManager.mHasDrawBuffers << llendl;
+ llassert( mFBO != 0 );
+ llassert( gGLManager.mHasDrawBuffers );
+ return false;
}
U32 tex;
@@ -143,7 +202,7 @@ bool LLRenderTarget::addColorAttachment(U32 color_fmt)
{
clear_glerror();
- LLImageGL::setManualImage(LLTexUnit::getInternalType(mUsage), 0, color_fmt, mResX, mResY, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+ LLImageGL::setManualImage(LLTexUnit::getInternalType(mUsage), 0, color_fmt, mResX, mResY, GL_RGBA, GL_UNSIGNED_BYTE, NULL, false);
if (glGetError() != GL_NO_ERROR)
{
llwarns << "Could not allocate color buffer for render target." << llendl;
@@ -189,17 +248,21 @@ bool LLRenderTarget::addColorAttachment(U32 color_fmt)
check_framebuffer_status();
- glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO);
}
mTex.push_back(tex);
+ mInternalFormat.push_back(color_fmt);
+#if !LL_DARWIN
if (gDebugGL)
{ //bind and unbind to validate target
bindTarget();
flush();
}
-
+#endif
+
+
return true;
}
@@ -223,7 +286,7 @@ bool LLRenderTarget::allocateDepth()
U32 internal_type = LLTexUnit::getInternalType(mUsage);
stop_glerror();
clear_glerror();
- LLImageGL::setManualImage(internal_type, 0, GL_DEPTH_COMPONENT24, mResX, mResY, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL);
+ LLImageGL::setManualImage(internal_type, 0, GL_DEPTH_COMPONENT24, mResX, mResY, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL, false);
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
}
@@ -277,7 +340,7 @@ void LLRenderTarget::shareDepthBuffer(LLRenderTarget& target)
check_framebuffer_status();
- glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO);
target.mUseDepth = true;
}
@@ -294,41 +357,62 @@ void LLRenderTarget::release()
}
else
{
- LLImageGL::deleteTextures(1, &mDepth, true);
+ LLImageGL::deleteTextures(1, &mDepth);
stop_glerror();
}
mDepth = 0;
sBytesAllocated -= mResX*mResY*4;
}
- else if (mUseDepth && mFBO)
- { //detach shared depth buffer
+ else if (mFBO)
+ {
glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
- if (mStencil)
- { //attached as a renderbuffer
- glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
- glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
- mStencil = false;
+
+ if (mUseDepth)
+ { //detach shared depth buffer
+ if (mStencil)
+ { //attached as a renderbuffer
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
+ mStencil = false;
+ }
+ else
+ { //attached as a texture
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, LLTexUnit::getInternalType(mUsage), 0, 0);
+ }
+ mUseDepth = false;
}
- else
- { //attached as a texture
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, LLTexUnit::getInternalType(mUsage), 0, 0);
+ }
+
+ // Detach any extra color buffers (e.g. SRGB spec buffers)
+ //
+ if (mFBO && (mTex.size() > 1))
+ {
+ S32 z;
+ for (z = mTex.size() - 1; z >= 1; z--)
+ {
+ sBytesAllocated -= mResX*mResY*4;
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0+z, LLTexUnit::getInternalType(mUsage), 0, 0);
+ stop_glerror();
+ LLImageGL::deleteTextures(1, &mTex[z]);
}
- mUseDepth = false;
}
if (mFBO)
{
glDeleteFramebuffers(1, (GLuint *) &mFBO);
+ stop_glerror();
mFBO = 0;
}
if (mTex.size() > 0)
{
- sBytesAllocated -= mResX*mResY*4*mTex.size();
- LLImageGL::deleteTextures(mTex.size(), &mTex[0], true);
- mTex.clear();
+ sBytesAllocated -= mResX*mResY*4;
+ LLImageGL::deleteTextures(1, &mTex[0]);
}
+
+ mTex.clear();
+ mInternalFormat.clear();
mResX = mResY = 0;
@@ -341,7 +425,10 @@ void LLRenderTarget::bindTarget()
{
stop_glerror();
+ mPreviousFBO = sCurFBO;
glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
+ sCurFBO = mFBO;
+
stop_glerror();
if (gGLManager.mHasDrawBuffers)
{ //setup multiple render targets
@@ -363,18 +450,13 @@ void LLRenderTarget::bindTarget()
stop_glerror();
}
+ mPreviousResX = sCurResX;
+ mPreviousResY = sCurResY;
glViewport(0, 0, mResX, mResY);
- sBoundTarget = this;
-}
+ sCurResX = mResX;
+ sCurResY = mResY;
-// static
-void LLRenderTarget::unbindTarget()
-{
- if (gGLManager.mHasFramebufferObject)
- {
- glBindFramebuffer(GL_FRAMEBUFFER, 0);
- }
- sBoundTarget = NULL;
+ sBoundTarget = this;
}
void LLRenderTarget::clear(U32 mask_in)
@@ -413,6 +495,12 @@ U32 LLRenderTarget::getTexture(U32 attachment) const
return mTex[attachment];
}
+U32 LLRenderTarget::getNumTextures() const
+{
+ return mTex.size();
+}
+
+
void LLRenderTarget::bindTexture(U32 index, S32 channel)
{
gGL.getTexUnit(channel)->bindManual(mUsage, getTexture(index));
@@ -442,7 +530,22 @@ void LLRenderTarget::flush(bool fetch_depth)
else
{
stop_glerror();
- glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ glBindFramebuffer(GL_FRAMEBUFFER, mPreviousFBO);
+ sCurFBO = mPreviousFBO;
+
+ if (mPreviousFBO)
+ {
+ glViewport(0, 0, mPreviousResX, mPreviousResY);
+ sCurResX = mPreviousResX;
+ sCurResY = mPreviousResY;
+ }
+ else
+ {
+ glViewport(gGLViewport[0],gGLViewport[1],gGLViewport[2],gGLViewport[3]);
+ sCurResX = gGLViewport[2];
+ sCurResY = gGLViewport[3];
+ }
+
stop_glerror();
}
}
@@ -472,7 +575,7 @@ void LLRenderTarget::copyContents(LLRenderTarget& source, S32 srcX0, S32 srcY0,
stop_glerror();
glCopyTexSubImage2D(LLTexUnit::getInternalType(mUsage), 0, srcX0, srcY0, dstX0, dstY0, dstX1, dstY1);
stop_glerror();
- glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO);
stop_glerror();
}
else
@@ -489,7 +592,7 @@ void LLRenderTarget::copyContents(LLRenderTarget& source, S32 srcX0, S32 srcY0,
stop_glerror();
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
stop_glerror();
- glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO);
stop_glerror();
}
}
@@ -500,8 +603,10 @@ void LLRenderTarget::copyContentsToFramebuffer(LLRenderTarget& source, S32 srcX0
{
if (!source.mFBO)
{
- llerrs << "Cannot copy framebuffer contents for non FBO render targets." << llendl;
+ llwarns << "Cannot copy framebuffer contents for non FBO render targets." << llendl;
+ return;
}
+
{
GLboolean write_depth = mask & GL_DEPTH_BUFFER_BIT ? TRUE : FALSE;
@@ -515,7 +620,7 @@ void LLRenderTarget::copyContentsToFramebuffer(LLRenderTarget& source, S32 srcX0
stop_glerror();
glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
stop_glerror();
- glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO);
stop_glerror();
}
}
@@ -533,3 +638,5 @@ void LLRenderTarget::getViewport(S32* viewport)
viewport[3] = mResY;
}
+
+
diff --git a/indra/llrender/llrendertarget.h b/indra/llrender/llrendertarget.h
index 2735ab21c5..6dc84d978d 100644..100755
--- a/indra/llrender/llrendertarget.h
+++ b/indra/llrender/llrendertarget.h
@@ -28,7 +28,6 @@
#define LL_LLRENDERTARGET_H
// LLRenderTarget is unavailible on the mapserver since it uses FBOs.
-#if !LL_MESA_HEADLESS
#include "llgl.h"
#include "llrender.h"
@@ -57,14 +56,16 @@
*/
-class LLMultisampleBuffer;
-
class LLRenderTarget
{
public:
//whether or not to use FBO implementation
static bool sUseFBO;
static U32 sBytesAllocated;
+ static U32 sCurFBO;
+ static U32 sCurResX;
+ static U32 sCurResY;
+
LLRenderTarget();
~LLRenderTarget();
@@ -74,6 +75,12 @@ public:
//multiple calls will release previously allocated resources
bool allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage = LLTexUnit::TT_TEXTURE, bool use_fbo = false, S32 samples = 0);
+ //resize existing attachments to use new resolution and color format
+ // CAUTION: if the GL runs out of memory attempting to resize, this render target will be undefined
+ // DO NOT use for screen space buffers or for scratch space for an image that might be uploaded
+ // DO use for render targets that resize often and aren't likely to ruin someone's day if they break
+ void resize(U32 resx, U32 resy);
+
//add color buffer attachment
//limit of 4 color attachments per render target
bool addColorAttachment(U32 color_fmt);
@@ -92,9 +99,6 @@ public:
//applies appropriate viewport
void bindTarget();
- //unbind target for rendering
- static void unbindTarget();
-
//clear render targer, clears depth buffer if present,
//uses scissor rect if in copy-to-texture mode
void clear(U32 mask = 0xFFFFFFFF);
@@ -111,6 +115,7 @@ public:
LLTexUnit::eTextureType getUsage(void) const { return mUsage; }
U32 getTexture(U32 attachment = 0) const;
+ U32 getNumTextures() const;
U32 getDepth(void) const { return mDepth; }
bool hasStencil() const { return mStencil; }
@@ -142,7 +147,12 @@ protected:
U32 mResX;
U32 mResY;
std::vector<U32> mTex;
+ std::vector<U32> mInternalFormat;
U32 mFBO;
+ U32 mPreviousFBO;
+ U32 mPreviousResX;
+ U32 mPreviousResY;
+
U32 mDepth;
bool mStencil;
bool mUseDepth;
@@ -152,7 +162,5 @@ protected:
static LLRenderTarget* sBoundTarget;
};
-#endif //!LL_MESA_HEADLESS
-
#endif
diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp
index 7d384450e6..d230574752 100644..100755
--- a/indra/llrender/llshadermgr.cpp
+++ b/indra/llrender/llshadermgr.cpp
@@ -521,7 +521,7 @@ void LLShaderMgr::dumpObjectLog(GLhandleARB ret, BOOL warns)
}
}
-GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type, S32 texture_index_channels)
+GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type, boost::unordered_map<std::string, std::string>* defines, S32 texture_index_channels)
{
GLenum error = GL_NO_ERROR;
if (gDebugGL)
@@ -643,20 +643,22 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
text[count++] = strdup("#define textureCube texture\n");
text[count++] = strdup("#define texture2DLod textureLod\n");
text[count++] = strdup("#define shadow2D(a,b) vec2(texture(a,b))\n");
-
+
if (major_version > 1 || minor_version >= 40)
{ //GLSL 1.40 replaces texture2DRect et al with texture
text[count++] = strdup("#define texture2DRect texture\n");
text[count++] = strdup("#define shadow2DRect(a,b) vec2(texture(a,b))\n");
}
}
-
- //copy preprocessor definitions into buffer
- for (std::map<std::string,std::string>::iterator iter = mDefinitions.begin(); iter != mDefinitions.end(); ++iter)
+
+ if (defines)
+ {
+ for (boost::unordered_map<std::string,std::string>::iterator iter = defines->begin(); iter != defines->end(); ++iter)
{
std::string define = "#define " + iter->first + " " + iter->second + "\n";
text[count++] = (GLcharARB *) strdup(define.c_str());
}
+ }
if (texture_index_channels > 0 && type == GL_FRAGMENT_SHADER_ARB)
{
@@ -693,6 +695,8 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
}
*/
+ text[count++] = strdup("#define HAS_DIFFUSE_LOOKUP 1\n");
+
//uniform declartion
for (S32 i = 0; i < texture_index_channels; ++i)
{
@@ -702,7 +706,7 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
if (texture_index_channels > 1)
{
- text[count++] = strdup("VARYING_FLAT ivec4 vary_texture_index;\n");
+ text[count++] = strdup("VARYING_FLAT int vary_texture_index;\n");
}
text[count++] = strdup("vec4 diffuseLookup(vec2 texcoord)\n");
@@ -716,20 +720,33 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
}
else if (major_version > 1 || minor_version >= 30)
{ //switches are supported in GLSL 1.30 and later
- text[count++] = strdup("\tvec4 ret = vec4(1,0,1,1);\n");
- text[count++] = strdup("\tswitch (vary_texture_index.r)\n");
- text[count++] = strdup("\t{\n");
-
- //switch body
- for (S32 i = 0; i < texture_index_channels; ++i)
- {
- std::string case_str = llformat("\t\tcase %d: ret = texture2D(tex%d, texcoord); break;\n", i, i);
- text[count++] = strdup(case_str.c_str());
+ if (gGLManager.mIsNVIDIA)
+ { //switches are unreliable on some NVIDIA drivers
+ for (U32 i = 0; i < texture_index_channels; ++i)
+ {
+ std::string if_string = llformat("\t%sif (vary_texture_index == %d) { return texture2D(tex%d, texcoord); }\n", i > 0 ? "else " : "", i, i);
+ text[count++] = strdup(if_string.c_str());
+ }
+ text[count++] = strdup("\treturn vec4(1,0,1,1);\n");
+ text[count++] = strdup("}\n");
}
+ else
+ {
+ text[count++] = strdup("\tvec4 ret = vec4(1,0,1,1);\n");
+ text[count++] = strdup("\tswitch (vary_texture_index)\n");
+ text[count++] = strdup("\t{\n");
+
+ //switch body
+ for (S32 i = 0; i < texture_index_channels; ++i)
+ {
+ std::string case_str = llformat("\t\tcase %d: return texture2D(tex%d, texcoord);\n", i, i);
+ text[count++] = strdup(case_str.c_str());
+ }
- text[count++] = strdup("\t}\n");
- text[count++] = strdup("\treturn ret;\n");
- text[count++] = strdup("}\n");
+ text[count++] = strdup("\t}\n");
+ text[count++] = strdup("\treturn ret;\n");
+ text[count++] = strdup("}\n");
+ }
}
else
{ //should never get here. Indexed texture rendering requires GLSL 1.30 or later
@@ -737,6 +754,10 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
llerrs << "Indexed texture rendering requires GLSL 1.30 or later." << llendl;
}
}
+ else
+ {
+ text[count++] = strdup("#define HAS_DIFFUSE_LOOKUP 0\n");
+ }
//copy file into memory
while( fgets((char *)buff, 1024, file) != NULL && count < LL_ARRAY_SIZE(text) )
@@ -793,7 +814,6 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
//an error occured, print log
LL_WARNS("ShaderLoading") << "GLSL Compilation Error: (" << error << ") in " << filename << LL_ENDL;
dumpObjectLog(ret);
-
#if LL_WINDOWS
std::stringstream ostr;
//dump shader source for debugging
@@ -811,8 +831,20 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
}
LL_WARNS("ShaderLoading") << "\n" << ostr.str() << llendl;
-#endif // LL_WINDOWS
-
+#else
+ std::string str;
+
+ for (GLuint i = 0; i < count; i++) {
+ str.append(text[i]);
+
+ if (i % 128 == 0)
+ {
+ LL_WARNS("ShaderLoading") << str << llendl;
+ str = "";
+ }
+ }
+#endif
+
ret = 0;
}
}
@@ -841,7 +873,7 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
if (shader_level > 1)
{
shader_level--;
- return loadShaderFile(filename,shader_level,type,texture_index_channels);
+ return loadShaderFile(filename,shader_level,type, defines, texture_index_channels);
}
LL_WARNS("ShaderLoading") << "Failed to load " << filename << LL_ENDL;
}
@@ -945,7 +977,7 @@ void LLShaderMgr::initAttribsAndUniforms()
mReservedAttribs.push_back("texcoord3");
mReservedAttribs.push_back("diffuse_color");
mReservedAttribs.push_back("emissive");
- mReservedAttribs.push_back("binormal");
+ mReservedAttribs.push_back("tangent");
mReservedAttribs.push_back("weight");
mReservedAttribs.push_back("weight4");
mReservedAttribs.push_back("clothing");
@@ -961,7 +993,9 @@ void LLShaderMgr::initAttribsAndUniforms()
mReservedUniforms.push_back("texture_matrix1");
mReservedUniforms.push_back("texture_matrix2");
mReservedUniforms.push_back("texture_matrix3");
- llassert(mReservedUniforms.size() == LLShaderMgr::TEXTURE_MATRIX3+1);
+ mReservedUniforms.push_back("object_plane_s");
+ mReservedUniforms.push_back("object_plane_t");
+ llassert(mReservedUniforms.size() == LLShaderMgr::OBJECT_PLANE_T+1);
mReservedUniforms.push_back("viewport");
@@ -1026,6 +1060,9 @@ void LLShaderMgr::initAttribsAndUniforms()
mReservedUniforms.push_back("size");
mReservedUniforms.push_back("falloff");
+ mReservedUniforms.push_back("box_center");
+ mReservedUniforms.push_back("box_size");
+
mReservedUniforms.push_back("minLuminance");
mReservedUniforms.push_back("maxExtractAlpha");
@@ -1039,6 +1076,7 @@ void LLShaderMgr::initAttribsAndUniforms()
mReservedUniforms.push_back("minimum_alpha");
+ mReservedUniforms.push_back("emissive_brightness");
mReservedUniforms.push_back("shadow_matrix");
mReservedUniforms.push_back("env_mat");
@@ -1062,8 +1100,9 @@ void LLShaderMgr::initAttribsAndUniforms()
mReservedUniforms.push_back("proj_shadow_res");
mReservedUniforms.push_back("depth_cutoff");
mReservedUniforms.push_back("norm_cutoff");
+ mReservedUniforms.push_back("shadow_target_width");
- llassert(mReservedUniforms.size() == LLShaderMgr::DEFERRED_NORM_CUTOFF+1);
+ llassert(mReservedUniforms.size() == LLShaderMgr::DEFERRED_SHADOW_TARGET_WIDTH+1);
mReservedUniforms.push_back("tc_scale");
mReservedUniforms.push_back("rcp_screen_res");
@@ -1098,7 +1137,54 @@ void LLShaderMgr::initAttribsAndUniforms()
mReservedUniforms.push_back("lightMap");
mReservedUniforms.push_back("bloomMap");
mReservedUniforms.push_back("projectionMap");
+ mReservedUniforms.push_back("norm_mat");
+
+ mReservedUniforms.push_back("global_gamma");
+ mReservedUniforms.push_back("texture_gamma");
+
+ mReservedUniforms.push_back("specular_color");
+ mReservedUniforms.push_back("env_intensity");
+
+ mReservedUniforms.push_back("matrixPalette");
+
+ mReservedUniforms.push_back("screenTex");
+ mReservedUniforms.push_back("screenDepth");
+ mReservedUniforms.push_back("refTex");
+ mReservedUniforms.push_back("eyeVec");
+ mReservedUniforms.push_back("time");
+ mReservedUniforms.push_back("d1");
+ mReservedUniforms.push_back("d2");
+ mReservedUniforms.push_back("lightDir");
+ mReservedUniforms.push_back("specular");
+ mReservedUniforms.push_back("lightExp");
+ mReservedUniforms.push_back("waterFogColor");
+ mReservedUniforms.push_back("waterFogDensity");
+ mReservedUniforms.push_back("waterFogKS");
+ mReservedUniforms.push_back("refScale");
+ mReservedUniforms.push_back("waterHeight");
+ mReservedUniforms.push_back("waterPlane");
+ mReservedUniforms.push_back("normScale");
+ mReservedUniforms.push_back("fresnelScale");
+ mReservedUniforms.push_back("fresnelOffset");
+ mReservedUniforms.push_back("blurMultiplier");
+ mReservedUniforms.push_back("sunAngle");
+ mReservedUniforms.push_back("scaledAngle");
+ mReservedUniforms.push_back("sunAngle2");
+
+ mReservedUniforms.push_back("camPosLocal");
+
+ mReservedUniforms.push_back("gWindDir");
+ mReservedUniforms.push_back("gSinWaveParams");
+ mReservedUniforms.push_back("gGravity");
+
+ mReservedUniforms.push_back("detail_0");
+ mReservedUniforms.push_back("detail_1");
+ mReservedUniforms.push_back("detail_2");
+ mReservedUniforms.push_back("detail_3");
+ mReservedUniforms.push_back("alpha_ramp");
+ mReservedUniforms.push_back("origin");
+ mReservedUniforms.push_back("display_gamma");
llassert(mReservedUniforms.size() == END_RESERVED_UNIFORMS);
std::set<std::string> dupe_check;
diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h
index e28bda6de2..51c27fc8b6 100644..100755
--- a/indra/llrender/llshadermgr.h
+++ b/indra/llrender/llshadermgr.h
@@ -47,6 +47,8 @@ public:
TEXTURE_MATRIX1,
TEXTURE_MATRIX2,
TEXTURE_MATRIX3,
+ OBJECT_PLANE_S,
+ OBJECT_PLANE_T,
VIEWPORT,
LIGHT_POSITION,
LIGHT_DIRECTION,
@@ -97,6 +99,8 @@ public:
LIGHT_CENTER,
LIGHT_SIZE,
LIGHT_FALLOFF,
+ BOX_CENTER,
+ BOX_SIZE,
GLOW_MIN_LUMINANCE,
GLOW_MAX_EXTRACT_ALPHA,
@@ -107,6 +111,7 @@ public:
GLOW_DELTA,
MINIMUM_ALPHA,
+ EMISSIVE_BRIGHTNESS,
DEFERRED_SHADOW_MATRIX,
DEFERRED_ENV_MAT,
@@ -130,6 +135,7 @@ public:
DEFERRED_PROJ_SHADOW_RES,
DEFERRED_DEPTH_CUTOFF,
DEFERRED_NORM_CUTOFF,
+ DEFERRED_SHADOW_TARGET_WIDTH,
FXAA_TC_SCALE,
FXAA_RCP_SCREEN_RES,
@@ -161,6 +167,54 @@ public:
DEFERRED_LIGHT,
DEFERRED_BLOOM,
DEFERRED_PROJECTION,
+ DEFERRED_NORM_MATRIX,
+
+ GLOBAL_GAMMA,
+ TEXTURE_GAMMA,
+
+ SPECULAR_COLOR,
+ ENVIRONMENT_INTENSITY,
+
+ AVATAR_MATRIX,
+
+ WATER_SCREENTEX,
+ WATER_SCREENDEPTH,
+ WATER_REFTEX,
+ WATER_EYEVEC,
+ WATER_TIME,
+ WATER_WAVE_DIR1,
+ WATER_WAVE_DIR2,
+ WATER_LIGHT_DIR,
+ WATER_SPECULAR,
+ WATER_SPECULAR_EXP,
+ WATER_FOGCOLOR,
+ WATER_FOGDENSITY,
+ WATER_FOGKS,
+ WATER_REFSCALE,
+ WATER_WATERHEIGHT,
+ WATER_WATERPLANE,
+ WATER_NORM_SCALE,
+ WATER_FRESNEL_SCALE,
+ WATER_FRESNEL_OFFSET,
+ WATER_BLUR_MULTIPLIER,
+ WATER_SUN_ANGLE,
+ WATER_SCALED_ANGLE,
+ WATER_SUN_ANGLE2,
+
+ WL_CAMPOSLOCAL,
+
+ AVATAR_WIND,
+ AVATAR_SINWAVE,
+ AVATAR_GRAVITY,
+
+ TERRAIN_DETAIL0,
+ TERRAIN_DETAIL1,
+ TERRAIN_DETAIL2,
+ TERRAIN_DETAIL3,
+ TERRAIN_ALPHARAMP,
+
+ SHINY_ORIGIN,
+DISPLAY_GAMMA,
END_RESERVED_UNIFORMS
} eGLSLReservedUniforms;
@@ -173,7 +227,7 @@ public:
void dumpObjectLog(GLhandleARB ret, BOOL warns = TRUE);
BOOL linkProgramObject(GLhandleARB obj, BOOL suppress_errors = FALSE);
BOOL validateProgramObject(GLhandleARB obj);
- GLhandleARB loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type, S32 texture_index_channels = -1);
+ GLhandleARB loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type, boost::unordered_map<std::string, std::string>* defines = NULL, S32 texture_index_channels = -1);
// Implemented in the application to actually point to the shader directory.
virtual std::string getShaderDirPrefix(void) = 0; // Pure Virtual
diff --git a/indra/llrender/lltexture.cpp b/indra/llrender/lltexture.cpp
index 90fbcec2be..90fbcec2be 100644..100755
--- a/indra/llrender/lltexture.cpp
+++ b/indra/llrender/lltexture.cpp
diff --git a/indra/llrender/lltexture.h b/indra/llrender/lltexture.h
index 569a65c2e0..093bac20d1 100644..100755
--- a/indra/llrender/lltexture.h
+++ b/indra/llrender/lltexture.h
@@ -38,10 +38,9 @@ class LLTexUnit ;
class LLFontGL ;
//
-//this is an abstract class as the parent for the class LLViewerTexture
-//through the following virtual functions, the class LLViewerTexture can be reached from /llrender.
+//this is an abstract class as the parent for the class LLGLTexture
//
-class LLTexture : public LLRefCount
+class LLTexture : public virtual LLRefCount
{
friend class LLTexUnit ;
friend class LLFontGL ;
@@ -53,7 +52,7 @@ public:
LLTexture(){}
//
- //interfaces to access LLViewerTexture
+ //interfaces to access LLGLTexture
//
virtual S8 getType() const = 0 ;
virtual void setKnownDrawSize(S32 width, S32 height) = 0 ;
diff --git a/indra/llrender/lluiimage.cpp b/indra/llrender/lluiimage.cpp
new file mode 100644
index 0000000000..b954b66350
--- /dev/null
+++ b/indra/llrender/lluiimage.cpp
@@ -0,0 +1,243 @@
+/**
+ * @file lluiimage.cpp
+ * @brief UI implementation
+ *
+ * $LicenseInfo:firstyear=2007&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$
+ */
+
+// Utilities functions the user interface needs
+
+//#include "llviewerprecompiledheaders.h"
+#include "linden_common.h"
+
+// Project includes
+#include "lluiimage.h"
+#include "llrender2dutils.h"
+
+LLUIImage::LLUIImage(const std::string& name, LLPointer<LLTexture> image)
+: mName(name),
+ mImage(image),
+ mScaleRegion(0.f, 1.f, 1.f, 0.f),
+ mClipRegion(0.f, 1.f, 1.f, 0.f),
+ mUniformScaling(TRUE),
+ mNoClip(TRUE),
+ mImageLoaded(NULL)
+{
+}
+
+LLUIImage::~LLUIImage()
+{
+ delete mImageLoaded;
+}
+
+void LLUIImage::setClipRegion(const LLRectf& region)
+{
+ mClipRegion = region;
+ mNoClip = mClipRegion.mLeft == 0.f
+ && mClipRegion.mRight == 1.f
+ && mClipRegion.mBottom == 0.f
+ && mClipRegion.mTop == 1.f;
+}
+
+void LLUIImage::setScaleRegion(const LLRectf& region)
+{
+ mScaleRegion = region;
+ mUniformScaling = mScaleRegion.mLeft == 0.f
+ && mScaleRegion.mRight == 1.f
+ && mScaleRegion.mBottom == 0.f
+ && mScaleRegion.mTop == 1.f;
+}
+
+//TODO: move drawing implementation inside class
+void LLUIImage::draw(S32 x, S32 y, const LLColor4& color) const
+{
+ gl_draw_scaled_image(x, y, getWidth(), getHeight(), mImage, color, mClipRegion);
+}
+
+void LLUIImage::draw(S32 x, S32 y, S32 width, S32 height, const LLColor4& color) const
+{
+ if (mUniformScaling)
+ {
+ gl_draw_scaled_image(x, y, width, height, mImage, color, mClipRegion);
+ }
+ else
+ {
+ gl_draw_scaled_image_with_border(
+ x, y,
+ width, height,
+ mImage,
+ color,
+ FALSE,
+ mClipRegion,
+ mScaleRegion);
+ }
+}
+
+void LLUIImage::drawSolid(S32 x, S32 y, S32 width, S32 height, const LLColor4& color) const
+{
+ gl_draw_scaled_image_with_border(
+ x, y,
+ width, height,
+ mImage,
+ color,
+ TRUE,
+ mClipRegion,
+ mScaleRegion);
+}
+
+void LLUIImage::drawBorder(S32 x, S32 y, S32 width, S32 height, const LLColor4& color, S32 border_width) const
+{
+ LLRect border_rect;
+ border_rect.setOriginAndSize(x, y, width, height);
+ border_rect.stretch(border_width, border_width);
+ drawSolid(border_rect, color);
+}
+
+void LLUIImage::draw3D(const LLVector3& origin_agent, const LLVector3& x_axis, const LLVector3& y_axis,
+ const LLRect& rect, const LLColor4& color)
+{
+ F32 border_scale = 1.f;
+ F32 border_height = (1.f - mScaleRegion.getHeight()) * getHeight();
+ F32 border_width = (1.f - mScaleRegion.getWidth()) * getWidth();
+ if (rect.getHeight() < border_height || rect.getWidth() < border_width)
+ {
+ if(border_height - rect.getHeight() > border_width - rect.getWidth())
+ {
+ border_scale = (F32)rect.getHeight() / border_height;
+ }
+ else
+ {
+ border_scale = (F32)rect.getWidth() / border_width;
+ }
+ }
+
+ LLRender2D::pushMatrix();
+ {
+ LLVector3 rect_origin = origin_agent + (rect.mLeft * x_axis) + (rect.mBottom * y_axis);
+ LLRender2D::translate(rect_origin.mV[VX],
+ rect_origin.mV[VY],
+ rect_origin.mV[VZ]);
+ gGL.getTexUnit(0)->bind(getImage());
+ gGL.color4fv(color.mV);
+
+ LLRectf center_uv_rect(mClipRegion.mLeft + mScaleRegion.mLeft * mClipRegion.getWidth(),
+ mClipRegion.mBottom + mScaleRegion.mTop * mClipRegion.getHeight(),
+ mClipRegion.mLeft + mScaleRegion.mRight * mClipRegion.getWidth(),
+ mClipRegion.mBottom + mScaleRegion.mBottom * mClipRegion.getHeight());
+ gl_segmented_rect_3d_tex(mClipRegion,
+ center_uv_rect,
+ LLRectf(border_width * border_scale * 0.5f / (F32)rect.getWidth(),
+ (rect.getHeight() - (border_height * border_scale * 0.5f)) / (F32)rect.getHeight(),
+ (rect.getWidth() - (border_width * border_scale * 0.5f)) / (F32)rect.getWidth(),
+ (border_height * border_scale * 0.5f) / (F32)rect.getHeight()),
+ rect.getWidth() * x_axis,
+ rect.getHeight() * y_axis);
+
+ } LLRender2D::popMatrix();
+}
+
+
+S32 LLUIImage::getWidth() const
+{
+ // return clipped dimensions of actual image area
+ return llround((F32)mImage->getWidth(0) * mClipRegion.getWidth());
+}
+
+S32 LLUIImage::getHeight() const
+{
+ // return clipped dimensions of actual image area
+ return llround((F32)mImage->getHeight(0) * mClipRegion.getHeight());
+}
+
+S32 LLUIImage::getTextureWidth() const
+{
+ return mImage->getWidth(0);
+}
+
+S32 LLUIImage::getTextureHeight() const
+{
+ return mImage->getHeight(0);
+}
+
+boost::signals2::connection LLUIImage::addLoadedCallback( const image_loaded_signal_t::slot_type& cb )
+{
+ if (!mImageLoaded)
+ {
+ mImageLoaded = new image_loaded_signal_t();
+ }
+ return mImageLoaded->connect(cb);
+}
+
+
+void LLUIImage::onImageLoaded()
+{
+ if (mImageLoaded)
+ {
+ (*mImageLoaded)();
+ }
+}
+
+
+namespace LLInitParam
+{
+ void ParamValue<LLUIImage*>::updateValueFromBlock()
+ {
+ // The keyword "none" is specifically requesting a null image
+ // do not default to current value. Used to overwrite template images.
+ if (name() == "none")
+ {
+ updateValue(NULL);
+ return;
+ }
+
+ LLUIImage* imagep = LLRender2D::getUIImage(name());
+ if (imagep)
+ {
+ updateValue(imagep);
+ }
+ }
+
+ void ParamValue<LLUIImage*>::updateBlockFromValue(bool make_block_authoritative)
+ {
+ if (getValue() == NULL)
+ {
+ name.set("none", make_block_authoritative);
+ }
+ else
+ {
+ name.set(getValue()->getName(), make_block_authoritative);
+ }
+ }
+
+
+ bool ParamCompare<LLUIImage*, false>::equals(
+ LLUIImage* const &a,
+ LLUIImage* const &b)
+ {
+ // force all LLUIImages for XML UI export to be "non-default"
+ if (!a && !b)
+ return false;
+ else
+ return (a == b);
+ }
+}
+
diff --git a/indra/llrender/lluiimage.h b/indra/llrender/lluiimage.h
new file mode 100644
index 0000000000..7817ba1c7b
--- /dev/null
+++ b/indra/llrender/lluiimage.h
@@ -0,0 +1,126 @@
+/**
+ * @file lluiimage.h
+ * @brief wrapper for images used in the UI that handles smart scaling, etc.
+ *
+ * $LicenseInfo:firstyear=2007&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$
+ */
+
+#ifndef LL_LLUIIMAGE_H
+#define LL_LLUIIMAGE_H
+
+#include "v4color.h"
+#include "llpointer.h"
+#include "llrefcount.h"
+#include "llrefcount.h"
+#include "llrect.h"
+#include <boost/function.hpp>
+#include <boost/signals2.hpp>
+#include "llinitparam.h"
+#include "lltexture.h"
+
+extern const LLColor4 UI_VERTEX_COLOR;
+
+class LLUIImage : public LLRefCount
+{
+public:
+ typedef boost::signals2::signal<void (void)> image_loaded_signal_t;
+
+ LLUIImage(const std::string& name, LLPointer<LLTexture> image);
+ virtual ~LLUIImage();
+
+ void setClipRegion(const LLRectf& region);
+ void setScaleRegion(const LLRectf& region);
+
+ LLPointer<LLTexture> getImage() { return mImage; }
+ const LLPointer<LLTexture>& getImage() const { return mImage; }
+
+ void draw(S32 x, S32 y, S32 width, S32 height, const LLColor4& color = UI_VERTEX_COLOR) const;
+ void draw(S32 x, S32 y, const LLColor4& color = UI_VERTEX_COLOR) const;
+ void draw(const LLRect& rect, const LLColor4& color = UI_VERTEX_COLOR) const { draw(rect.mLeft, rect.mBottom, rect.getWidth(), rect.getHeight(), color); }
+
+ void drawSolid(S32 x, S32 y, S32 width, S32 height, const LLColor4& color) const;
+ void drawSolid(const LLRect& rect, const LLColor4& color) const { drawSolid(rect.mLeft, rect.mBottom, rect.getWidth(), rect.getHeight(), color); }
+ void drawSolid(S32 x, S32 y, const LLColor4& color) const { drawSolid(x, y, getWidth(), getHeight(), color); }
+
+ void drawBorder(S32 x, S32 y, S32 width, S32 height, const LLColor4& color, S32 border_width) const;
+ void drawBorder(const LLRect& rect, const LLColor4& color, S32 border_width) const { drawBorder(rect.mLeft, rect.mBottom, rect.getWidth(), rect.getHeight(), color, border_width); }
+ void drawBorder(S32 x, S32 y, const LLColor4& color, S32 border_width) const { drawBorder(x, y, getWidth(), getHeight(), color, border_width); }
+
+ void draw3D(const LLVector3& origin_agent, const LLVector3& x_axis, const LLVector3& y_axis, const LLRect& rect, const LLColor4& color);
+
+ const std::string& getName() const { return mName; }
+
+ virtual S32 getWidth() const;
+ virtual S32 getHeight() const;
+
+ // returns dimensions of underlying textures, which might not be equal to ui image portion
+ S32 getTextureWidth() const;
+ S32 getTextureHeight() const;
+
+ boost::signals2::connection addLoadedCallback( const image_loaded_signal_t::slot_type& cb );
+
+ void onImageLoaded();
+
+protected:
+ image_loaded_signal_t* mImageLoaded;
+
+ std::string mName;
+ LLRectf mScaleRegion;
+ LLRectf mClipRegion;
+ LLPointer<LLTexture> mImage;
+ BOOL mUniformScaling;
+ BOOL mNoClip;
+};
+
+namespace LLInitParam
+{
+ template<>
+ class ParamValue<LLUIImage*>
+ : public CustomParamValue<LLUIImage*>
+ {
+ typedef boost::add_reference<boost::add_const<LLUIImage*>::type>::type T_const_ref;
+ typedef CustomParamValue<LLUIImage*> super_t;
+ public:
+ Optional<std::string> name;
+
+ ParamValue(LLUIImage* const& image = NULL)
+ : super_t(image)
+ {
+ updateBlockFromValue(false);
+ addSynonym(name, "name");
+ }
+
+ void updateValueFromBlock();
+ void updateBlockFromValue(bool make_block_authoritative);
+ };
+
+ // Need custom comparison function for our test app, which only loads
+ // LLUIImage* as NULL.
+ template<>
+ struct ParamCompare<LLUIImage*, false>
+ {
+ static bool equals(LLUIImage* const &a, LLUIImage* const &b);
+ };
+}
+
+typedef LLPointer<LLUIImage> LLUIImagePtr;
+#endif
diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index 8b5503229f..e6f20cd40e 100644..100755
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -31,7 +31,6 @@
#include "llvertexbuffer.h"
// #include "llrender.h"
#include "llglheaders.h"
-#include "llmemtype.h"
#include "llrender.h"
#include "llvector4a.h"
#include "llshadermgr.h"
@@ -49,15 +48,55 @@ U32 nhpo2(U32 v)
return r;
}
+//which power of 2 is i?
+//assumes i is a power of 2 > 0
+U32 wpo2(U32 i)
+{
+ llassert(i > 0);
+ llassert(nhpo2(i) == i);
+
+ U32 r = 0;
+
+ while (i >>= 1) ++r;
+
+ return r;
+}
+
+
+const U32 LL_VBO_BLOCK_SIZE = 2048;
+const U32 LL_VBO_POOL_MAX_SEED_SIZE = 256*1024;
+
+U32 vbo_block_size(U32 size)
+{ //what block size will fit size?
+ U32 mod = size % LL_VBO_BLOCK_SIZE;
+ return mod == 0 ? size : size + (LL_VBO_BLOCK_SIZE-mod);
+}
+
+U32 vbo_block_index(U32 size)
+{
+ return vbo_block_size(size)/LL_VBO_BLOCK_SIZE;
+}
+
+const U32 LL_VBO_POOL_SEED_COUNT = vbo_block_index(LL_VBO_POOL_MAX_SEED_SIZE);
+
//============================================================================
//static
LLVBOPool LLVertexBuffer::sStreamVBOPool(GL_STREAM_DRAW_ARB, GL_ARRAY_BUFFER_ARB);
LLVBOPool LLVertexBuffer::sDynamicVBOPool(GL_DYNAMIC_DRAW_ARB, GL_ARRAY_BUFFER_ARB);
+LLVBOPool LLVertexBuffer::sDynamicCopyVBOPool(GL_DYNAMIC_COPY_ARB, GL_ARRAY_BUFFER_ARB);
LLVBOPool LLVertexBuffer::sStreamIBOPool(GL_STREAM_DRAW_ARB, GL_ELEMENT_ARRAY_BUFFER_ARB);
LLVBOPool LLVertexBuffer::sDynamicIBOPool(GL_DYNAMIC_DRAW_ARB, GL_ELEMENT_ARRAY_BUFFER_ARB);
+
U32 LLVBOPool::sBytesPooled = 0;
+U32 LLVBOPool::sIndexBytesPooled = 0;
+
+std::list<U32> LLVertexBuffer::sAvailableVAOName;
+U32 LLVertexBuffer::sCurVAOName = 1;
+
+U32 LLVertexBuffer::sAllocatedIndexBytes = 0;
+U32 LLVertexBuffer::sIndexCount = 0;
LLPrivateMemoryPool* LLVertexBuffer::sPrivatePoolp = NULL;
U32 LLVertexBuffer::sBindCount = 0;
@@ -74,104 +113,85 @@ U32 LLVertexBuffer::sLastMask = 0;
bool LLVertexBuffer::sVBOActive = false;
bool LLVertexBuffer::sIBOActive = false;
U32 LLVertexBuffer::sAllocatedBytes = 0;
+U32 LLVertexBuffer::sVertexCount = 0;
bool LLVertexBuffer::sMapped = false;
bool LLVertexBuffer::sUseStreamDraw = true;
bool LLVertexBuffer::sUseVAO = false;
bool LLVertexBuffer::sPreferStreamDraw = false;
-const U32 FENCE_WAIT_TIME_NANOSECONDS = 10000; //1 ms
-class LLGLSyncFence : public LLGLFence
+U32 LLVBOPool::genBuffer()
{
-public:
-#ifdef GL_ARB_sync
- GLsync mSync;
-#endif
+ U32 ret = 0;
+
+ glGenBuffersARB(1, &ret);
- LLGLSyncFence()
- {
-#ifdef GL_ARB_sync
- mSync = 0;
-#endif
- }
+ return ret;
+}
- virtual ~LLGLSyncFence()
+void LLVBOPool::deleteBuffer(U32 name)
+{
+ if (gGLManager.mInited)
{
-#ifdef GL_ARB_sync
- if (mSync)
- {
- glDeleteSync(mSync);
- }
-#endif
- }
+ LLVertexBuffer::unbind();
- void placeFence()
- {
-#ifdef GL_ARB_sync
- if (mSync)
- {
- glDeleteSync(mSync);
- }
- mSync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
-#endif
- }
+ glBindBufferARB(mType, name);
+ glBufferDataARB(mType, 0, NULL, mUsage);
+ glBindBufferARB(mType, 0);
- void wait()
- {
-#ifdef GL_ARB_sync
- if (mSync)
- {
- while (glClientWaitSync(mSync, 0, FENCE_WAIT_TIME_NANOSECONDS) == GL_TIMEOUT_EXPIRED)
- { //track the number of times we've waited here
- static S32 waits = 0;
- waits++;
- }
- }
-#endif
+ glDeleteBuffersARB(1, &name);
}
+}
-};
-
-
-//which power of 2 is i?
-//assumes i is a power of 2 > 0
-U32 wpo2(U32 i)
+LLVBOPool::LLVBOPool(U32 vboUsage, U32 vboType)
+: mUsage(vboUsage), mType(vboType)
{
- llassert(i > 0);
- llassert(nhpo2(i) == i);
-
- U32 r = 0;
-
- while (i >>= 1) ++r;
-
- return r;
+ mMissCount.resize(LL_VBO_POOL_SEED_COUNT);
+ std::fill(mMissCount.begin(), mMissCount.end(), 0);
}
-volatile U8* LLVBOPool::allocate(U32& name, U32 size)
+volatile U8* LLVBOPool::allocate(U32& name, U32 size, bool for_seed)
{
- llassert(nhpo2(size) == size);
+ llassert(vbo_block_size(size) == size);
+
+ volatile U8* ret = NULL;
- U32 i = wpo2(size);
+ U32 i = vbo_block_index(size);
if (mFreeList.size() <= i)
{
mFreeList.resize(i+1);
}
- volatile U8* ret = NULL;
-
- if (mFreeList[i].empty())
+ if (mFreeList[i].empty() || for_seed)
{
//make a new buffer
- glGenBuffersARB(1, &name);
+ name = genBuffer();
+
glBindBufferARB(mType, name);
- LLVertexBuffer::sAllocatedBytes += size;
+
+ if (!for_seed && i < LL_VBO_POOL_SEED_COUNT)
+ { //record this miss
+ mMissCount[i]++;
+ }
+
+ if (mType == GL_ARRAY_BUFFER_ARB)
+ {
+ LLVertexBuffer::sAllocatedBytes += size;
+ }
+ else
+ {
+ LLVertexBuffer::sAllocatedIndexBytes += size;
+ }
if (LLVertexBuffer::sDisableVBOMapping || mUsage != GL_DYNAMIC_DRAW_ARB)
{
glBufferDataARB(mType, size, 0, mUsage);
- ret = (U8*) ll_aligned_malloc_16(size);
+ if (mUsage != GL_DYNAMIC_COPY_ARB)
+ { //data will be provided by application
+ ret = (U8*) ll_aligned_malloc(size, 64);
+ }
}
else
{ //always use a true hint of static draw when allocating non-client-backed buffers
@@ -179,13 +199,39 @@ volatile U8* LLVBOPool::allocate(U32& name, U32 size)
}
glBindBufferARB(mType, 0);
+
+ if (for_seed)
+ { //put into pool for future use
+ llassert(mFreeList.size() > i);
+
+ Record rec;
+ rec.mGLName = name;
+ rec.mClientData = ret;
+
+ if (mType == GL_ARRAY_BUFFER_ARB)
+ {
+ sBytesPooled += size;
+ }
+ else
+ {
+ sIndexBytesPooled += size;
+ }
+ mFreeList[i].push_back(rec);
+ }
}
else
{
name = mFreeList[i].front().mGLName;
ret = mFreeList[i].front().mClientData;
- sBytesPooled -= size;
+ if (mType == GL_ARRAY_BUFFER_ARB)
+ {
+ sBytesPooled -= size;
+ }
+ else
+ {
+ sIndexBytesPooled -= size;
+ }
mFreeList[i].pop_front();
}
@@ -195,30 +241,50 @@ volatile U8* LLVBOPool::allocate(U32& name, U32 size)
void LLVBOPool::release(U32 name, volatile U8* buffer, U32 size)
{
- llassert(nhpo2(size) == size);
+ llassert(vbo_block_size(size) == size);
- U32 i = wpo2(size);
+ deleteBuffer(name);
+ ll_aligned_free((U8*) buffer);
- llassert(mFreeList.size() > i);
-
- Record rec;
- rec.mGLName = name;
- rec.mClientData = buffer;
-
- if (buffer == NULL)
+ if (mType == GL_ARRAY_BUFFER_ARB)
{
- glDeleteBuffersARB(1, &rec.mGLName);
+ LLVertexBuffer::sAllocatedBytes -= size;
}
else
{
- sBytesPooled += size;
- mFreeList[i].push_back(rec);
+ LLVertexBuffer::sAllocatedIndexBytes -= size;
+ }
+}
+
+void LLVBOPool::seedPool()
+{
+ U32 dummy_name = 0;
+
+ if (mFreeList.size() < LL_VBO_POOL_SEED_COUNT)
+ {
+ mFreeList.resize(LL_VBO_POOL_SEED_COUNT);
+ }
+
+ for (U32 i = 0; i < LL_VBO_POOL_SEED_COUNT; i++)
+ {
+ if (mMissCount[i] > mFreeList[i].size())
+ {
+ U32 size = i*LL_VBO_BLOCK_SIZE;
+
+ S32 count = mMissCount[i] - mFreeList[i].size();
+ for (U32 j = 0; j < count; ++j)
+ {
+ allocate(dummy_name, size, true);
+ }
+ }
}
}
+
+
void LLVBOPool::cleanup()
{
- U32 size = 1;
+ U32 size = LL_VBO_BLOCK_SIZE;
for (U32 i = 0; i < mFreeList.size(); ++i)
{
@@ -228,21 +294,32 @@ void LLVBOPool::cleanup()
{
Record& r = l.front();
- glDeleteBuffersARB(1, &r.mGLName);
-
+ deleteBuffer(r.mGLName);
+
if (r.mClientData)
{
- ll_aligned_free_16((void*) r.mClientData);
+ ll_aligned_free((void*) r.mClientData);
}
l.pop_front();
- LLVertexBuffer::sAllocatedBytes -= size;
- sBytesPooled -= size;
+ if (mType == GL_ARRAY_BUFFER_ARB)
+ {
+ sBytesPooled -= size;
+ LLVertexBuffer::sAllocatedBytes -= size;
+ }
+ else
+ {
+ sIndexBytesPooled -= size;
+ LLVertexBuffer::sAllocatedIndexBytes -= size;
+ }
}
- size *= 2;
+ size += LL_VBO_BLOCK_SIZE;
}
+
+ //reset miss counts
+ std::fill(mMissCount.begin(), mMissCount.end(), 0);
}
@@ -257,13 +334,32 @@ S32 LLVertexBuffer::sTypeSize[LLVertexBuffer::TYPE_MAX] =
sizeof(LLVector2), // TYPE_TEXCOORD3,
sizeof(LLColor4U), // TYPE_COLOR,
sizeof(LLColor4U), // TYPE_EMISSIVE, only alpha is used currently
- sizeof(LLVector4), // TYPE_BINORMAL,
+ sizeof(LLVector4), // TYPE_TANGENT,
sizeof(F32), // TYPE_WEIGHT,
sizeof(LLVector4), // TYPE_WEIGHT4,
sizeof(LLVector4), // TYPE_CLOTHWEIGHT,
sizeof(LLVector4), // TYPE_TEXTURE_INDEX (actually exists as position.w), no extra data, but stride is 16 bytes
};
+static std::string vb_type_name[] =
+{
+ "TYPE_VERTEX",
+ "TYPE_NORMAL",
+ "TYPE_TEXCOORD0",
+ "TYPE_TEXCOORD1",
+ "TYPE_TEXCOORD2",
+ "TYPE_TEXCOORD3",
+ "TYPE_COLOR",
+ "TYPE_EMISSIVE",
+ "TYPE_TANGENT",
+ "TYPE_WEIGHT",
+ "TYPE_WEIGHT4",
+ "TYPE_CLOTHWEIGHT",
+ "TYPE_TEXTURE_INDEX",
+ "TYPE_MAX",
+ "TYPE_INDEX",
+};
+
U32 LLVertexBuffer::sGLMode[LLRender::NUM_MODES] =
{
GL_TRIANGLES,
@@ -276,13 +372,48 @@ U32 LLVertexBuffer::sGLMode[LLRender::NUM_MODES] =
GL_LINE_LOOP,
};
+//static
+U32 LLVertexBuffer::getVAOName()
+{
+ U32 ret = 0;
+
+ if (!sAvailableVAOName.empty())
+ {
+ ret = sAvailableVAOName.front();
+ sAvailableVAOName.pop_front();
+ }
+ else
+ {
+#ifdef GL_ARB_vertex_array_object
+ glGenVertexArrays(1, &ret);
+#endif
+ }
+
+ return ret;
+}
+
+//static
+void LLVertexBuffer::releaseVAOName(U32 name)
+{
+ sAvailableVAOName.push_back(name);
+}
+
+
+//static
+void LLVertexBuffer::seedPools()
+{
+ sStreamVBOPool.seedPool();
+ sDynamicVBOPool.seedPool();
+ sDynamicCopyVBOPool.seedPool();
+ sStreamIBOPool.seedPool();
+ sDynamicIBOPool.seedPool();
+}
//static
void LLVertexBuffer::setupClientArrays(U32 data_mask)
{
if (sLastMask != data_mask)
{
- bool error = false;
if (gGLManager.mGLSLVersionMajor < 2 && gGLManager.mGLSLVersionMinor < 30)
{
@@ -349,7 +480,6 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)
{
if (gDebugSession)
{
- error = true;
gFailLog << "Bad client state! " << array[i] << " disabled." << std::endl;
}
else
@@ -369,7 +499,6 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)
{ //needs to be disabled, make sure it was (DEBUG TEMPORARY)
if (gDebugSession)
{
- error = true;
gFailLog << "Bad client state! " << array[i] << " enabled." << std::endl;
}
else
@@ -406,16 +535,16 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)
}
}
- if (sLastMask & MAP_BINORMAL)
+ if (sLastMask & MAP_TANGENT)
{
- if (!(data_mask & MAP_BINORMAL))
+ if (!(data_mask & MAP_TANGENT))
{
glClientActiveTextureARB(GL_TEXTURE2_ARB);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glClientActiveTextureARB(GL_TEXTURE0_ARB);
}
}
- else if (data_mask & MAP_BINORMAL)
+ else if (data_mask & MAP_TANGENT)
{
glClientActiveTextureARB(GL_TEXTURE2_ARB);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
@@ -428,14 +557,29 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)
}
//static
+static LLFastTimer::DeclareTimer FTM_VB_DRAW_ARRAYS("drawArrays");
void LLVertexBuffer::drawArrays(U32 mode, const std::vector<LLVector3>& pos, const std::vector<LLVector3>& norm)
{
+ LLFastTimer t(FTM_VB_DRAW_ARRAYS);
llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL);
gGL.syncMatrices();
U32 count = pos.size();
- llassert_always(norm.size() >= pos.size());
- llassert_always(count > 0);
+
+ llassert(norm.size() >= pos.size());
+ llassert(count > 0);
+
+ if( count == 0 )
+ {
+ llwarns << "Called drawArrays with 0 vertices" << llendl;
+ return;
+ }
+
+ if( norm.size() < pos.size() )
+ {
+ llwarns << "Called drawArrays with #" << norm.size() << " normals and #" << pos.size() << " vertices" << llendl;
+ return;
+ }
unbind();
@@ -461,8 +605,9 @@ void LLVertexBuffer::drawArrays(U32 mode, const std::vector<LLVector3>& pos, con
glVertexPointer(3, GL_FLOAT, 0, pos[0].mV);
glNormalPointer(GL_FLOAT, 0, norm[0].mV);
}
-
+ LLGLSLShader::startProfile();
glDrawArrays(sGLMode[mode], 0, count);
+ LLGLSLShader::stopProfile(count, mode);
}
//static
@@ -499,7 +644,9 @@ void LLVertexBuffer::drawElements(U32 mode, const LLVector4a* pos, const LLVecto
glVertexPointer(3, GL_FLOAT, 16, pos);
}
+ LLGLSLShader::startProfile();
glDrawElements(sGLMode[mode], num_indices, GL_UNSIGNED_SHORT, indicesp);
+ LLGLSLShader::stopProfile(num_indices, mode);
}
void LLVertexBuffer::validateRange(U32 start, U32 end, U32 count, U32 indices_offset) const
@@ -599,9 +746,14 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi
U16* idx = ((U16*) getIndicesPointer())+indices_offset;
stop_glerror();
+ LLGLSLShader::startProfile();
glDrawRangeElements(sGLMode[mode], start, end, count, GL_UNSIGNED_SHORT,
idx);
+ LLGLSLShader::stopProfile(count, mode);
stop_glerror();
+
+
+
placeFence();
}
@@ -645,12 +797,15 @@ void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const
}
stop_glerror();
+ LLGLSLShader::startProfile();
glDrawElements(sGLMode[mode], count, GL_UNSIGNED_SHORT,
((U16*) getIndicesPointer()) + indices_offset);
+ LLGLSLShader::stopProfile(count, mode);
stop_glerror();
placeFence();
}
+static LLFastTimer::DeclareTimer FTM_GL_DRAW_ARRAYS("GL draw arrays");
void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const
{
llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL);
@@ -685,8 +840,14 @@ void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const
return;
}
+ {
+ LLFastTimer t2(FTM_GL_DRAW_ARRAYS);
stop_glerror();
+ LLGLSLShader::startProfile();
glDrawArrays(sGLMode[mode], first, count);
+ LLGLSLShader::stopProfile(count, mode);
+ }
+
stop_glerror();
placeFence();
}
@@ -736,13 +897,13 @@ void LLVertexBuffer::unbind()
//static
void LLVertexBuffer::cleanupClass()
{
- LLMemType mt2(LLMemType::MTYPE_VERTEX_CLEANUP_CLASS);
unbind();
sStreamIBOPool.cleanup();
sDynamicIBOPool.cleanup();
sStreamVBOPool.cleanup();
sDynamicVBOPool.cleanup();
+ sDynamicCopyVBOPool.cleanup();
if(sPrivatePoolp)
{
@@ -779,6 +940,8 @@ S32 LLVertexBuffer::determineUsage(S32 usage)
if (ret_usage && ret_usage != GL_STREAM_DRAW_ARB)
{ //only stream_draw and dynamic_draw are supported when using VBOs, dynamic draw is the default
+ if (ret_usage != GL_DYNAMIC_COPY_ARB)
+ {
if (sDisableVBOMapping)
{ //always use stream draw if VBO mapping is disabled
ret_usage = GL_STREAM_DRAW_ARB;
@@ -788,6 +951,7 @@ S32 LLVertexBuffer::determineUsage(S32 usage)
ret_usage = GL_DYNAMIC_DRAW_ARB;
}
}
+ }
return ret_usage;
}
@@ -817,8 +981,6 @@ LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) :
mMappable(false),
mFence(NULL)
{
- LLMemType mt2(LLMemType::MTYPE_VERTEX_CONSTRUCTOR);
-
mMappable = (mUsage == GL_DYNAMIC_DRAW_ARB && !sDisableVBOMapping);
//zero out offsets
@@ -878,14 +1040,13 @@ S32 LLVertexBuffer::getSize() const
//virtual
LLVertexBuffer::~LLVertexBuffer()
{
- LLMemType mt2(LLMemType::MTYPE_VERTEX_DESTRUCTOR);
destroyGLBuffer();
destroyGLIndices();
if (mGLArray)
{
#if GL_ARB_vertex_array_object
- glDeleteVertexArrays(1, &mGLArray);
+ releaseVAOName(mGLArray);
#endif
}
@@ -898,6 +1059,9 @@ LLVertexBuffer::~LLVertexBuffer()
mFence = NULL;
+ sVertexCount -= mNumVerts;
+ sIndexCount -= mNumIndices;
+
llassert_always(!mMappedData && !mMappedIndexData);
};
@@ -929,23 +1093,28 @@ void LLVertexBuffer::waitFence() const
void LLVertexBuffer::genBuffer(U32 size)
{
- mSize = nhpo2(size);
+ mSize = vbo_block_size(size);
if (mUsage == GL_STREAM_DRAW_ARB)
{
mMappedData = sStreamVBOPool.allocate(mGLBuffer, mSize);
}
- else
+ else if (mUsage == GL_DYNAMIC_DRAW_ARB)
{
mMappedData = sDynamicVBOPool.allocate(mGLBuffer, mSize);
}
+ else
+ {
+ mMappedData = sDynamicCopyVBOPool.allocate(mGLBuffer, mSize);
+ }
+
sGLCount++;
}
void LLVertexBuffer::genIndices(U32 size)
{
- mIndicesSize = nhpo2(size);
+ mIndicesSize = vbo_block_size(size);
if (mUsage == GL_STREAM_DRAW_ARB)
{
@@ -995,8 +1164,6 @@ void LLVertexBuffer::releaseIndices()
void LLVertexBuffer::createGLBuffer(U32 size)
{
- LLMemType mt2(LLMemType::MTYPE_VERTEX_CREATE_VERTICES);
-
if (mGLBuffer)
{
destroyGLBuffer();
@@ -1026,8 +1193,6 @@ void LLVertexBuffer::createGLBuffer(U32 size)
void LLVertexBuffer::createGLIndices(U32 size)
{
- LLMemType mt2(LLMemType::MTYPE_VERTEX_CREATE_INDICES);
-
if (mGLIndices)
{
destroyGLIndices();
@@ -1062,7 +1227,6 @@ void LLVertexBuffer::createGLIndices(U32 size)
void LLVertexBuffer::destroyGLBuffer()
{
- LLMemType mt2(LLMemType::MTYPE_VERTEX_DESTROY_BUFFER);
if (mGLBuffer)
{
if (mMappedDataUsingVBOs)
@@ -1083,7 +1247,6 @@ void LLVertexBuffer::destroyGLBuffer()
void LLVertexBuffer::destroyGLIndices()
{
- LLMemType mt2(LLMemType::MTYPE_VERTEX_DESTROY_INDICES);
if (mGLIndices)
{
if (mMappedIndexDataUsingVBOs)
@@ -1104,14 +1267,12 @@ void LLVertexBuffer::destroyGLIndices()
void LLVertexBuffer::updateNumVerts(S32 nverts)
{
- LLMemType mt2(LLMemType::MTYPE_VERTEX_UPDATE_VERTS);
-
llassert(nverts >= 0);
- if (nverts >= 65535)
+ if (nverts > 65536)
{
llwarns << "Vertex buffer overflow!" << llendl;
- nverts = 65535;
+ nverts = 65536;
}
U32 needed_size = calcOffsets(mTypeMask, mOffsets, nverts);
@@ -1121,13 +1282,13 @@ void LLVertexBuffer::updateNumVerts(S32 nverts)
createGLBuffer(needed_size);
}
+ sVertexCount -= mNumVerts;
mNumVerts = nverts;
+ sVertexCount += mNumVerts;
}
void LLVertexBuffer::updateNumIndices(S32 nindices)
{
- LLMemType mt2(LLMemType::MTYPE_VERTEX_UPDATE_INDICES);
-
llassert(nindices >= 0);
U32 needed_size = sizeof(U16) * nindices;
@@ -1137,13 +1298,13 @@ void LLVertexBuffer::updateNumIndices(S32 nindices)
createGLIndices(needed_size);
}
+ sIndexCount -= mNumIndices;
mNumIndices = nindices;
+ sIndexCount += mNumIndices;
}
void LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create)
{
- LLMemType mt2(LLMemType::MTYPE_VERTEX_ALLOCATE_BUFFER);
-
stop_glerror();
if (nverts < 0 || nindices < 0 ||
@@ -1160,10 +1321,10 @@ void LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create)
//actually allocate space for the vertex buffer if using VBO mapping
flush();
- if (gGLManager.mHasVertexArrayObject && useVBOs() && (LLRender::sGLCoreProfile || sUseVAO))
+ if (gGLManager.mHasVertexArrayObject && useVBOs() && sUseVAO)
{
#if GL_ARB_vertex_array_object
- glGenVertexArrays(1, &mGLArray);
+ mGLArray = getVAOName();
#endif
setupVertexArray();
}
@@ -1195,11 +1356,11 @@ void LLVertexBuffer::setupVertexArray()
2, //TYPE_TEXCOORD3,
4, //TYPE_COLOR,
4, //TYPE_EMISSIVE,
- 3, //TYPE_BINORMAL,
+ 4, //TYPE_TANGENT,
1, //TYPE_WEIGHT,
4, //TYPE_WEIGHT4,
4, //TYPE_CLOTHWEIGHT,
- 4, //TYPE_TEXTURE_INDEX
+ 1, //TYPE_TEXTURE_INDEX
};
U32 attrib_type[] =
@@ -1212,11 +1373,11 @@ void LLVertexBuffer::setupVertexArray()
GL_FLOAT, //TYPE_TEXCOORD3,
GL_UNSIGNED_BYTE, //TYPE_COLOR,
GL_UNSIGNED_BYTE, //TYPE_EMISSIVE,
- GL_FLOAT, //TYPE_BINORMAL,
+ GL_FLOAT, //TYPE_TANGENT,
GL_FLOAT, //TYPE_WEIGHT,
GL_FLOAT, //TYPE_WEIGHT4,
GL_FLOAT, //TYPE_CLOTHWEIGHT,
- GL_UNSIGNED_BYTE, //TYPE_TEXTURE_INDEX
+ GL_UNSIGNED_INT, //TYPE_TEXTURE_INDEX
};
bool attrib_integer[] =
@@ -1229,7 +1390,7 @@ void LLVertexBuffer::setupVertexArray()
false, //TYPE_TEXCOORD3,
false, //TYPE_COLOR,
false, //TYPE_EMISSIVE,
- false, //TYPE_BINORMAL,
+ false, //TYPE_TANGENT,
false, //TYPE_WEIGHT,
false, //TYPE_WEIGHT4,
false, //TYPE_CLOTHWEIGHT,
@@ -1246,7 +1407,7 @@ void LLVertexBuffer::setupVertexArray()
GL_FALSE, //TYPE_TEXCOORD3,
GL_TRUE, //TYPE_COLOR,
GL_TRUE, //TYPE_EMISSIVE,
- GL_FALSE, //TYPE_BINORMAL,
+ GL_FALSE, //TYPE_TANGENT,
GL_FALSE, //TYPE_WEIGHT,
GL_FALSE, //TYPE_WEIGHT4,
GL_FALSE, //TYPE_CLOTHWEIGHT,
@@ -1294,8 +1455,6 @@ void LLVertexBuffer::resizeBuffer(S32 newnverts, S32 newnindices)
llassert(newnverts >= 0);
llassert(newnindices >= 0);
- LLMemType mt2(LLMemType::MTYPE_VERTEX_RESIZE_BUFFER);
-
updateNumVerts(newnverts);
updateNumIndices(newnindices);
@@ -1343,7 +1502,6 @@ static LLFastTimer::DeclareTimer FTM_VBO_MAP_BUFFER("VBO Map");
volatile U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_range)
{
bindGLBuffer(true);
- LLMemType mt2(LLMemType::MTYPE_VERTEX_MAP_BUFFER);
if (mFinal)
{
llerrs << "LLVertexBuffer::mapVeretxBuffer() called on a finalized buffer." << llendl;
@@ -1392,7 +1550,6 @@ volatile U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, boo
if (!mVertexLocked)
{
- LLMemType mt_v(LLMemType::MTYPE_VERTEX_MAP_BUFFER_VERTICES);
mVertexLocked = true;
sMappedCount++;
stop_glerror();
@@ -1445,8 +1602,10 @@ volatile U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, boo
{
if (map_range)
{
+#ifndef LL_MESA_HEADLESS
glBufferParameteriAPPLE(GL_ARRAY_BUFFER_ARB, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_FALSE);
glBufferParameteriAPPLE(GL_ARRAY_BUFFER_ARB, GL_BUFFER_FLUSHING_UNMAP_APPLE, GL_FALSE);
+#endif
src = (U8*) glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
}
else
@@ -1523,7 +1682,6 @@ static LLFastTimer::DeclareTimer FTM_VBO_MAP_INDEX("IBO Map");
volatile U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range)
{
- LLMemType mt2(LLMemType::MTYPE_VERTEX_MAP_BUFFER);
bindGLIndices(true);
if (mFinal)
{
@@ -1570,8 +1728,6 @@ volatile U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range
if (!mIndexLocked)
{
- LLMemType mt_v(LLMemType::MTYPE_VERTEX_MAP_BUFFER_INDICES);
-
mIndexLocked = true;
sMappedCount++;
stop_glerror();
@@ -1623,8 +1779,10 @@ volatile U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range
{
if (map_range)
{
+#ifndef LL_MESA_HEADLESS
glBufferParameteriAPPLE(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_FALSE);
glBufferParameteriAPPLE(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_BUFFER_FLUSHING_UNMAP_APPLE, GL_FALSE);
+#endif
src = (U8*) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
}
else
@@ -1694,7 +1852,6 @@ static LLFastTimer::DeclareTimer FTM_IBO_FLUSH_RANGE("Flush IBO Range");
void LLVertexBuffer::unmapBuffer()
{
- LLMemType mt2(LLMemType::MTYPE_VERTEX_UNMAP_BUFFER);
if (!useVBOs())
{
return; //nothing to unmap
@@ -1752,7 +1909,9 @@ void LLVertexBuffer::unmapBuffer()
}
else if (gGLManager.mHasFlushBufferRange)
{
+#ifndef LL_MESA_HEADLESS
glFlushMappedBufferRangeAPPLE(GL_ARRAY_BUFFER_ARB, offset, length);
+#endif
}
stop_glerror();
}
@@ -1818,8 +1977,10 @@ void LLVertexBuffer::unmapBuffer()
else if (gGLManager.mHasFlushBufferRange)
{
#ifdef GL_APPLE_flush_buffer_range
+#ifndef LL_MESA_HEADLESS
glFlushMappedBufferRangeAPPLE(GL_ELEMENT_ARRAY_BUFFER_ARB, offset, length);
#endif
+#endif
}
stop_glerror();
}
@@ -1911,14 +2072,21 @@ bool LLVertexBuffer::getTexCoord1Strider(LLStrider<LLVector2>& strider, S32 inde
{
return VertexBufferStrider<LLVector2,TYPE_TEXCOORD1>::get(*this, strider, index, count, map_range);
}
-
+bool LLVertexBuffer::getTexCoord2Strider(LLStrider<LLVector2>& strider, S32 index, S32 count, bool map_range)
+{
+ return VertexBufferStrider<LLVector2,TYPE_TEXCOORD2>::get(*this, strider, index, count, map_range);
+}
bool LLVertexBuffer::getNormalStrider(LLStrider<LLVector3>& strider, S32 index, S32 count, bool map_range)
{
return VertexBufferStrider<LLVector3,TYPE_NORMAL>::get(*this, strider, index, count, map_range);
}
-bool LLVertexBuffer::getBinormalStrider(LLStrider<LLVector3>& strider, S32 index, S32 count, bool map_range)
+bool LLVertexBuffer::getTangentStrider(LLStrider<LLVector3>& strider, S32 index, S32 count, bool map_range)
+{
+ return VertexBufferStrider<LLVector3,TYPE_TANGENT>::get(*this, strider, index, count, map_range);
+}
+bool LLVertexBuffer::getTangentStrider(LLStrider<LLVector4a>& strider, S32 index, S32 count, bool map_range)
{
- return VertexBufferStrider<LLVector3,TYPE_BINORMAL>::get(*this, strider, index, count, map_range);
+ return VertexBufferStrider<LLVector4a,TYPE_TANGENT>::get(*this, strider, index, count, map_range);
}
bool LLVertexBuffer::getColorStrider(LLStrider<LLColor4U>& strider, S32 index, S32 count, bool map_range)
{
@@ -1978,21 +2146,14 @@ bool LLVertexBuffer::bindGLBuffer(bool force_bind)
if (useVBOs() && (force_bind || (mGLBuffer && (mGLBuffer != sGLRenderBuffer || !sVBOActive))))
{
- LLFastTimer t(FTM_BIND_GL_BUFFER);
- /*if (sMapped)
- {
- llerrs << "VBO bound while another VBO mapped!" << llendl;
- }*/
+ //LLFastTimer t(FTM_BIND_GL_BUFFER); <-- this timer is showing up as a hotspot (irony)
+
glBindBufferARB(GL_ARRAY_BUFFER_ARB, mGLBuffer);
sGLRenderBuffer = mGLBuffer;
sBindCount++;
sVBOActive = true;
- if (mGLArray)
- {
- llassert(sGLRenderArray == mGLArray);
- //mCachedRenderBuffer = mGLBuffer;
- }
+ llassert(!mGLArray || sGLRenderArray == mGLArray);
ret = true;
}
@@ -2033,12 +2194,21 @@ void LLVertexBuffer::flush()
}
}
+// bind for transform feedback (quick 'n dirty)
+void LLVertexBuffer::bindForFeedback(U32 channel, U32 type, U32 index, U32 count)
+{
+#ifdef GL_TRANSFORM_FEEDBACK_BUFFER
+ U32 offset = mOffsets[type] + sTypeSize[type]*index;
+ U32 size= (sTypeSize[type]*count);
+ glBindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, channel, mGLBuffer, offset, size);
+#endif
+}
+
// Set for rendering
void LLVertexBuffer::setBuffer(U32 data_mask)
{
flush();
- LLMemType mt2(LLMemType::MTYPE_VERTEX_SET_BUFFER);
//set up pointers if the data mask is different ...
bool setup = (sLastMask != data_mask);
@@ -2064,6 +2234,37 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
if ((data_mask & required_mask) != required_mask)
{
+
+ U32 unsatisfied_mask = (required_mask & ~data_mask);
+ U32 i = 0;
+
+ while (i < TYPE_MAX)
+ {
+ U32 unsatisfied_flag = unsatisfied_mask & (1 << i);
+ switch (unsatisfied_flag)
+ {
+ case MAP_VERTEX: llinfos << "Missing vert pos" << llendl; break;
+ case MAP_NORMAL: llinfos << "Missing normals" << llendl; break;
+ case MAP_TEXCOORD0: llinfos << "Missing TC 0" << llendl; break;
+ case MAP_TEXCOORD1: llinfos << "Missing TC 1" << llendl; break;
+ case MAP_TEXCOORD2: llinfos << "Missing TC 2" << llendl; break;
+ case MAP_TEXCOORD3: llinfos << "Missing TC 3" << llendl; break;
+ case MAP_COLOR: llinfos << "Missing vert color" << llendl; break;
+ case MAP_EMISSIVE: llinfos << "Missing emissive" << llendl; break;
+ case MAP_TANGENT: llinfos << "Missing tangent" << llendl; break;
+ case MAP_WEIGHT: llinfos << "Missing weight" << llendl; break;
+ case MAP_WEIGHT4: llinfos << "Missing weightx4" << llendl; break;
+ case MAP_CLOTHWEIGHT: llinfos << "Missing clothweight" << llendl; break;
+ case MAP_TEXTURE_INDEX: llinfos << "Missing tex index" << llendl; break;
+ default: llinfos << "Missing who effin knows: " << unsatisfied_flag << llendl;
+ }
+ }
+
+ if (unsatisfied_mask & (1 << TYPE_INDEX))
+ {
+ llinfos << "Missing indices" << llendl;
+ }
+
llerrs << "Shader consumption mismatches data provision." << llendl;
}
}
@@ -2084,7 +2285,6 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
setup = setup || bindBuffer || bindIndices;
}
- bool error = false;
if (gDebugGL && !mGLArray)
{
GLint buff;
@@ -2093,7 +2293,6 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
{
if (gDebugSession)
{
- error = true;
gFailLog << "Invalid GL vertex buffer bound: " << buff << std::endl;
}
else
@@ -2109,7 +2308,6 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
{
if (gDebugSession)
{
- error = true;
gFailLog << "Invalid GL index buffer bound: " << buff << std::endl;
}
else
@@ -2180,14 +2378,21 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
// virtual (default)
void LLVertexBuffer::setupVertexBuffer(U32 data_mask)
{
- LLMemType mt2(LLMemType::MTYPE_VERTEX_SETUP_VERTEX_BUFFER);
stop_glerror();
volatile U8* base = useVBOs() ? (U8*) mAlignedOffset : mMappedData;
- /*if ((data_mask & mTypeMask) != data_mask)
+ if (gDebugGL && ((data_mask & mTypeMask) != data_mask))
{
+ for (U32 i = 0; i < LLVertexBuffer::TYPE_MAX; ++i)
+ {
+ U32 mask = 1 << i;
+ if (mask & data_mask && !(mask & mTypeMask))
+ { //bit set in data_mask, but not set in mTypeMask
+ llwarns << "Missing required component " << vb_type_name[i] << llendl;
+ }
+ }
llerrs << "LLVertexBuffer::setupVertexBuffer missing required components for supplied data mask." << llendl;
- }*/
+ }
if (LLGLSLShader::sNoFixedFunction)
{
@@ -2215,11 +2420,11 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask)
void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD1]);
glVertexAttribPointerARB(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], ptr);
}
- if (data_mask & MAP_BINORMAL)
+ if (data_mask & MAP_TANGENT)
{
- S32 loc = TYPE_BINORMAL;
- void* ptr = (void*)(base + mOffsets[TYPE_BINORMAL]);
- glVertexAttribPointerARB(loc, 3,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_BINORMAL], ptr);
+ S32 loc = TYPE_TANGENT;
+ void* ptr = (void*)(base + mOffsets[TYPE_TANGENT]);
+ glVertexAttribPointerARB(loc, 4,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TANGENT], ptr);
}
if (data_mask & MAP_TEXCOORD0)
{
@@ -2230,7 +2435,8 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask)
if (data_mask & MAP_COLOR)
{
S32 loc = TYPE_COLOR;
- void* ptr = (void*)(base + mOffsets[TYPE_COLOR]);
+ //bind emissive instead of color pointer if emissive is present
+ void* ptr = (data_mask & MAP_EMISSIVE) ? (void*)(base + mOffsets[TYPE_EMISSIVE]) : (void*)(base + mOffsets[TYPE_COLOR]);
glVertexAttribPointerARB(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_COLOR], ptr);
}
if (data_mask & MAP_EMISSIVE)
@@ -2238,6 +2444,12 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask)
S32 loc = TYPE_EMISSIVE;
void* ptr = (void*)(base + mOffsets[TYPE_EMISSIVE]);
glVertexAttribPointerARB(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_EMISSIVE], ptr);
+
+ if (!(data_mask & MAP_COLOR))
+ { //map emissive to color channel when color is not also being bound to avoid unnecessary shader swaps
+ loc = TYPE_COLOR;
+ glVertexAttribPointerARB(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_EMISSIVE], ptr);
+ }
}
if (data_mask & MAP_WEIGHT)
{
@@ -2263,7 +2475,7 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask)
#if !LL_DARWIN
S32 loc = TYPE_TEXTURE_INDEX;
void *ptr = (void*) (base + mOffsets[TYPE_VERTEX] + 12);
- glVertexAttribIPointer(loc, 4, GL_UNSIGNED_BYTE, LLVertexBuffer::sTypeSize[TYPE_VERTEX], ptr);
+ glVertexAttribIPointer(loc, 1, GL_UNSIGNED_INT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], ptr);
#endif
}
if (data_mask & MAP_VERTEX)
@@ -2297,10 +2509,10 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask)
glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], (void*)(base + mOffsets[TYPE_TEXCOORD1]));
glClientActiveTextureARB(GL_TEXTURE0_ARB);
}
- if (data_mask & MAP_BINORMAL)
+ if (data_mask & MAP_TANGENT)
{
glClientActiveTextureARB(GL_TEXTURE2_ARB);
- glTexCoordPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_BINORMAL], (void*)(base + mOffsets[TYPE_BINORMAL]));
+ glTexCoordPointer(4,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TANGENT], (void*)(base + mOffsets[TYPE_TANGENT]));
glClientActiveTextureARB(GL_TEXTURE0_ARB);
}
if (data_mask & MAP_TEXCOORD0)
@@ -2323,8 +2535,7 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask)
LLVertexBuffer::MappedRegion::MappedRegion(S32 type, S32 index, S32 count)
: mType(type), mIndex(index), mCount(count)
{
- llassert(mType == LLVertexBuffer::TYPE_INDEX ||
- mType < LLVertexBuffer::TYPE_TEXTURE_INDEX);
+ mEnd = mIndex+mCount;
}
diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h
index d859199663..619a0cec46 100644..100755
--- a/indra/llrender/llvertexbuffer.h
+++ b/indra/llrender/llvertexbuffer.h
@@ -55,24 +55,28 @@ class LLVBOPool
{
public:
static U32 sBytesPooled;
+ static U32 sIndexBytesPooled;
- LLVBOPool(U32 vboUsage, U32 vboType)
- : mUsage(vboUsage)
- , mType(vboType)
- {}
-
+ LLVBOPool(U32 vboUsage, U32 vboType);
+
const U32 mUsage;
const U32 mType;
//size MUST be a power of 2
- volatile U8* allocate(U32& name, U32 size);
+ volatile U8* allocate(U32& name, U32 size, bool for_seed = false);
//size MUST be the size provided to allocate that returned the given name
void release(U32 name, volatile U8* buffer, U32 size);
+ //batch allocate buffers to be provided to the application on demand
+ void seedPool();
+
//destroy all records in mFreeList
void cleanup();
+ U32 genBuffer();
+ void deleteBuffer(U32 name);
+
class Record
{
public:
@@ -82,15 +86,11 @@ public:
typedef std::list<Record> record_list_t;
std::vector<record_list_t> mFreeList;
-};
+ std::vector<U32> mMissCount;
-class LLGLFence
-{
-public:
- virtual void placeFence() = 0;
- virtual void wait() = 0;
};
+
//============================================================================
// base class
class LLPrivateMemoryPool;
@@ -103,6 +103,7 @@ public:
S32 mType;
S32 mIndex;
S32 mCount;
+ S32 mEnd;
MappedRegion(S32 type, S32 index, S32 count);
};
@@ -121,16 +122,26 @@ public:
static LLVBOPool sStreamVBOPool;
static LLVBOPool sDynamicVBOPool;
+ static LLVBOPool sDynamicCopyVBOPool;
static LLVBOPool sStreamIBOPool;
static LLVBOPool sDynamicIBOPool;
+
+ static std::list<U32> sAvailableVAOName;
+ static U32 sCurVAOName;
static bool sUseStreamDraw;
static bool sUseVAO;
static bool sPreferStreamDraw;
+ static void seedPools();
+
+ static U32 getVAOName();
+ static void releaseVAOName(U32 name);
+
static void initClass(bool use_vbo, bool no_vbo_mapping);
static void cleanupClass();
static void setupClientArrays(U32 data_mask);
+ static void pushPositions(U32 mode, const LLVector4a* pos, U32 count);
static void drawArrays(U32 mode, const std::vector<LLVector3>& pos, const std::vector<LLVector3>& norm);
static void drawElements(U32 mode, const LLVector4a* pos, const LLVector2* tc, S32 num_indices, const U16* indicesp);
@@ -161,7 +172,7 @@ public:
TYPE_TEXCOORD3,
TYPE_COLOR,
TYPE_EMISSIVE,
- TYPE_BINORMAL,
+ TYPE_TANGENT,
TYPE_WEIGHT,
TYPE_WEIGHT4,
TYPE_CLOTHWEIGHT,
@@ -179,7 +190,7 @@ public:
MAP_COLOR = (1<<TYPE_COLOR),
MAP_EMISSIVE = (1<<TYPE_EMISSIVE),
// These use VertexAttribPointer and should possibly be made generic
- MAP_BINORMAL = (1<<TYPE_BINORMAL),
+ MAP_TANGENT = (1<<TYPE_TANGENT),
MAP_WEIGHT = (1<<TYPE_WEIGHT),
MAP_WEIGHT4 = (1<<TYPE_WEIGHT4),
MAP_CLOTHWEIGHT = (1<<TYPE_CLOTHWEIGHT),
@@ -207,7 +218,6 @@ protected:
void destroyGLIndices();
void updateNumVerts(S32 nverts);
void updateNumIndices(S32 nindices);
- bool useVBOs() const;
void unmapBuffer();
public:
@@ -217,6 +227,8 @@ public:
volatile U8* mapVertexBuffer(S32 type, S32 index, S32 count, bool map_range);
volatile U8* mapIndexBuffer(S32 index, S32 count, bool map_range);
+ void bindForFeedback(U32 channel, U32 type, U32 index, U32 count);
+
// set for rendering
virtual void setBuffer(U32 data_mask); // calls setupVertexBuffer() if data_mask is not 0
void flush(); //flush pending data to GL memory
@@ -236,15 +248,19 @@ public:
bool getIndexStrider(LLStrider<U16>& strider, S32 index=0, S32 count = -1, bool map_range = false);
bool getTexCoord0Strider(LLStrider<LLVector2>& strider, S32 index=0, S32 count = -1, bool map_range = false);
bool getTexCoord1Strider(LLStrider<LLVector2>& strider, S32 index=0, S32 count = -1, bool map_range = false);
+ bool getTexCoord2Strider(LLStrider<LLVector2>& strider, S32 index=0, S32 count = -1, bool map_range = false);
bool getNormalStrider(LLStrider<LLVector3>& strider, S32 index=0, S32 count = -1, bool map_range = false);
- bool getBinormalStrider(LLStrider<LLVector3>& strider, S32 index=0, S32 count = -1, bool map_range = false);
+ bool getTangentStrider(LLStrider<LLVector3>& strider, S32 index=0, S32 count = -1, bool map_range = false);
+ bool getTangentStrider(LLStrider<LLVector4a>& strider, S32 index=0, S32 count = -1, bool map_range = false);
bool getColorStrider(LLStrider<LLColor4U>& strider, S32 index=0, S32 count = -1, bool map_range = false);
+ bool getTextureIndexStrider(LLStrider<LLColor4U>& strider, S32 index=0, S32 count = -1, bool map_range = false);
bool getEmissiveStrider(LLStrider<LLColor4U>& strider, S32 index=0, S32 count = -1, bool map_range = false);
bool getWeightStrider(LLStrider<F32>& strider, S32 index=0, S32 count = -1, bool map_range = false);
bool getWeight4Strider(LLStrider<LLVector4>& strider, S32 index=0, S32 count = -1, bool map_range = false);
bool getClothWeightStrider(LLStrider<LLVector4>& strider, S32 index=0, S32 count = -1, bool map_range = false);
+ bool useVBOs() const;
bool isEmpty() const { return mEmpty; }
bool isLocked() const { return mVertexLocked || mIndexLocked; }
S32 getNumVerts() const { return mNumVerts; }
@@ -332,6 +348,9 @@ public:
static bool sIBOActive;
static U32 sLastMask;
static U32 sAllocatedBytes;
+ static U32 sAllocatedIndexBytes;
+ static U32 sVertexCount;
+ static U32 sIndexCount;
static U32 sBindCount;
static U32 sSetCount;
};
diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt
index 772f173f17..589ceac501 100644..100755
--- a/indra/llui/CMakeLists.txt
+++ b/indra/llui/CMakeLists.txt
@@ -12,7 +12,6 @@ include(LLRender)
include(LLWindow)
include(LLVFS)
include(LLXML)
-include(LLXUIXML)
include_directories(
${LLCOMMON_INCLUDE_DIRS}
@@ -24,7 +23,11 @@ include_directories(
${LLWINDOW_INCLUDE_DIRS}
${LLVFS_INCLUDE_DIRS}
${LLXML_INCLUDE_DIRS}
- ${LLXUIXML_INCLUDE_DIRS}
+ ${LIBS_PREBUILD_DIR}/include/hunspell
+ )
+include_directories(SYSTEM
+ ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+ ${LLXML_SYSTEM_INCLUDE_DIRS}
)
set(llui_SOURCE_FILES
@@ -34,6 +37,7 @@ set(llui_SOURCE_FILES
llbadgeholder.cpp
llbadgeowner.cpp
llbutton.cpp
+ llchatentry.cpp
llcheckboxctrl.cpp
llclipboard.cpp
llcombobox.cpp
@@ -47,12 +51,16 @@ set(llui_SOURCE_FILES
lleditmenuhandler.cpp
llf32uictrl.cpp
llfiltereditor.cpp
+ llflashtimer.cpp
llflatlistview.cpp
llfloater.cpp
llfloaterreg.cpp
llfloaterreglistener.cpp
llflyoutbutton.cpp
llfocusmgr.cpp
+ llfolderview.cpp
+ llfolderviewitem.cpp
+ llfolderviewmodel.cpp
llfunctorregistry.cpp
lliconctrl.cpp
llkeywords.cpp
@@ -83,10 +91,10 @@ set(llui_SOURCE_FILES
llscrolllistcolumn.cpp
llscrolllistctrl.cpp
llscrolllistitem.cpp
- llsdparam.cpp
llsearcheditor.cpp
llslider.cpp
llsliderctrl.cpp
+ llspellcheck.cpp
llspinctrl.cpp
llstatbar.cpp
llstatgraph.cpp
@@ -100,15 +108,16 @@ set(llui_SOURCE_FILES
lltextutil.cpp
lltextvalidate.cpp
lltimectrl.cpp
+ lltrans.cpp
lltransutil.cpp
lltoggleablemenu.cpp
lltoolbar.cpp
lltooltip.cpp
llui.cpp
+ lluicolor.cpp
lluicolortable.cpp
lluictrl.cpp
lluictrlfactory.cpp
- lluiimage.cpp
lluistring.cpp
llundo.cpp
llurlaction.cpp
@@ -120,7 +129,9 @@ set(llui_SOURCE_FILES
llviewmodel.cpp
llview.cpp
llviewquery.cpp
+ llviewereventrecorder.cpp
llwindowshade.cpp
+ llxuiparser.cpp
)
set(llui_HEADER_FILES
@@ -133,6 +144,7 @@ set(llui_HEADER_FILES
llbadgeowner.h
llbutton.h
llcallbackmap.h
+ llchatentry.h
llcheckboxctrl.h
llclipboard.h
llcombobox.h
@@ -146,14 +158,17 @@ set(llui_HEADER_FILES
lleditmenuhandler.h
llf32uictrl.h
llfiltereditor.h
+ llflashtimer.h
llflatlistview.h
llfloater.h
llfloaterreg.h
llfloaterreglistener.h
llflyoutbutton.h
llfocusmgr.h
+ llfolderview.h
+ llfolderviewitem.h
+ llfolderviewmodel.h
llfunctorregistry.h
- llhandle.h
llhelp.h
lliconctrl.h
llkeywords.h
@@ -189,9 +204,10 @@ set(llui_HEADER_FILES
llscrolllistcolumn.h
llscrolllistctrl.h
llscrolllistitem.h
- llsdparam.h
llsliderctrl.h
llslider.h
+ llspellcheck.h
+ llspellcheckmenuhandler.h
llspinctrl.h
llstatbar.h
llstatgraph.h
@@ -208,6 +224,7 @@ set(llui_HEADER_FILES
lltoggleablemenu.h
lltoolbar.h
lltooltip.h
+ lltrans.h
lltransutil.h
lluicolortable.h
lluiconstants.h
@@ -215,7 +232,7 @@ set(llui_HEADER_FILES
lluictrl.h
lluifwd.h
llui.h
- lluiimage.h
+ lluicolor.h
lluistring.h
llundo.h
llurlaction.h
@@ -226,8 +243,10 @@ set(llui_HEADER_FILES
llviewinject.h
llviewmodel.h
llview.h
+ llviewereventrecorder.h
llviewquery.h
llwindowshade.h
+ llxuiparser.h
)
set_source_files_properties(${llui_HEADER_FILES}
@@ -258,6 +277,7 @@ target_link_libraries(llui
${LLXUIXML_LIBRARIES}
${LLXML_LIBRARIES}
${LLMATH_LIBRARIES}
+ ${HUNSPELL_LIBRARY}
${LLCOMMON_LIBRARIES} # must be after llimage, llwindow, llrender
)
diff --git a/indra/llui/llaccordionctrl.cpp b/indra/llui/llaccordionctrl.cpp
index d636161baf..d636161baf 100644..100755
--- a/indra/llui/llaccordionctrl.cpp
+++ b/indra/llui/llaccordionctrl.cpp
diff --git a/indra/llui/llaccordionctrl.h b/indra/llui/llaccordionctrl.h
index 1fe64c472e..1fe64c472e 100644..100755
--- a/indra/llui/llaccordionctrl.h
+++ b/indra/llui/llaccordionctrl.h
diff --git a/indra/llui/llaccordionctrltab.cpp b/indra/llui/llaccordionctrltab.cpp
index c025cd7939..43462bd244 100644..100755
--- a/indra/llui/llaccordionctrltab.cpp
+++ b/indra/llui/llaccordionctrltab.cpp
@@ -184,7 +184,7 @@ void LLAccordionCtrlTab::LLAccordionCtrlTabHeader::setTitleFontStyle(std::string
if (mHeaderTextbox)
{
std::string text = mHeaderTextbox->getText();
- mStyleParams.font(mHeaderTextbox->getDefaultFont());
+ mStyleParams.font(mHeaderTextbox->getFont());
mStyleParams.font.style(style);
mHeaderTextbox->setText(text, mStyleParams);
}
diff --git a/indra/llui/llaccordionctrltab.h b/indra/llui/llaccordionctrltab.h
index dddaa581e6..dddaa581e6 100644..100755
--- a/indra/llui/llaccordionctrltab.h
+++ b/indra/llui/llaccordionctrltab.h
diff --git a/indra/llui/llbadge.cpp b/indra/llui/llbadge.cpp
index 8ede4e3468..8ede4e3468 100644..100755
--- a/indra/llui/llbadge.cpp
+++ b/indra/llui/llbadge.cpp
diff --git a/indra/llui/llbadge.h b/indra/llui/llbadge.h
index 4b21a71aaa..4b21a71aaa 100644..100755
--- a/indra/llui/llbadge.h
+++ b/indra/llui/llbadge.h
diff --git a/indra/llui/llbadgeholder.cpp b/indra/llui/llbadgeholder.cpp
index 1f786f36ae..1f786f36ae 100644..100755
--- a/indra/llui/llbadgeholder.cpp
+++ b/indra/llui/llbadgeholder.cpp
diff --git a/indra/llui/llbadgeholder.h b/indra/llui/llbadgeholder.h
index 2538eaae91..2538eaae91 100644..100755
--- a/indra/llui/llbadgeholder.h
+++ b/indra/llui/llbadgeholder.h
diff --git a/indra/llui/llbadgeowner.cpp b/indra/llui/llbadgeowner.cpp
index 1860a05edd..1860a05edd 100644..100755
--- a/indra/llui/llbadgeowner.cpp
+++ b/indra/llui/llbadgeowner.cpp
diff --git a/indra/llui/llbadgeowner.h b/indra/llui/llbadgeowner.h
index 8d03e30645..8d03e30645 100644..100755
--- a/indra/llui/llbadgeowner.h
+++ b/indra/llui/llbadgeowner.h
diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp
index 705fe16559..50ac511d18 100644..100755
--- a/indra/llui/llbutton.cpp
+++ b/indra/llui/llbutton.cpp
@@ -49,6 +49,7 @@
#include "lluictrlfactory.h"
#include "llhelp.h"
#include "lldockablefloater.h"
+#include "llviewereventrecorder.h"
static LLDefaultChildRegistry::Register<LLButton> r("button");
@@ -105,6 +106,7 @@ LLButton::Params::Params()
badge("badge"),
handle_right_mouse("handle_right_mouse"),
held_down_delay("held_down_delay"),
+ button_flash_enable("button_flash_enable", false),
button_flash_count("button_flash_count"),
button_flash_rate("button_flash_rate")
{
@@ -171,9 +173,24 @@ LLButton::LLButton(const LLButton::Params& p)
mHeldDownSignal(NULL),
mUseDrawContextAlpha(p.use_draw_context_alpha),
mHandleRightMouse(p.handle_right_mouse),
- mButtonFlashCount(p.button_flash_count),
- mButtonFlashRate(p.button_flash_rate)
+ mFlashingTimer(NULL)
{
+ if (p.button_flash_enable)
+ {
+ // If optional parameter "p.button_flash_count" is not provided, LLFlashTimer will be
+ // used instead it a "default" value from gSavedSettings.getS32("FlashCount")).
+ // Likewise, missing "p.button_flash_rate" is replaced by gSavedSettings.getF32("FlashPeriod").
+ // Note: flashing should be allowed in settings.xml (boolean key "EnableButtonFlashing").
+ S32 flash_count = p.button_flash_count.isProvided()? p.button_flash_count : 0;
+ F32 flash_rate = p.button_flash_rate.isProvided()? p.button_flash_rate : 0.0;
+ mFlashingTimer = new LLFlashTimer ((LLFlashTimer::callback_t)NULL, flash_count, flash_rate);
+ }
+ else
+ {
+ mButtonFlashCount = p.button_flash_count;
+ mButtonFlashRate = p.button_flash_rate;
+ }
+
static LLUICachedControl<S32> llbutton_orig_h_pad ("UIButtonOrigHPad", 0);
static Params default_params(LLUICtrlFactory::getDefaultParams<LLButton>());
@@ -267,6 +284,11 @@ LLButton::~LLButton()
delete mMouseDownSignal;
delete mMouseUpSignal;
delete mHeldDownSignal;
+
+ if (mFlashingTimer)
+ {
+ mFlashingTimer->unset();
+ }
}
// HACK: Committing a button is the same as instantly clicking it.
@@ -422,6 +444,8 @@ BOOL LLButton::handleMouseDown(S32 x, S32 y, MASK mask)
*/
LLUICtrl::handleMouseDown(x, y, mask);
+ LLViewerEventRecorder::instance().updateMouseEventInfo(x,y,-55,-55,getPathname());
+
if(mMouseDownSignal) (*mMouseDownSignal)(this, LLSD());
mMouseDownTimer.start();
@@ -452,6 +476,7 @@ BOOL LLButton::handleMouseUp(S32 x, S32 y, MASK mask)
* by calling LLUICtrl::mMouseUpSignal(x, y, mask);
*/
LLUICtrl::handleMouseUp(x, y, mask);
+ LLViewerEventRecorder::instance().updateMouseEventInfo(x,y,-55,-55,getPathname());
// Regardless of where mouseup occurs, handle callback
if(mMouseUpSignal) (*mMouseUpSignal)(this, LLSD());
@@ -591,22 +616,6 @@ void LLButton::draw()
{
static LLCachedControl<bool> sEnableButtonFlashing(*LLUI::sSettingGroups["config"], "EnableButtonFlashing", true);
F32 alpha = mUseDrawContextAlpha ? getDrawContext().mAlpha : getCurrentTransparency();
- bool flash = FALSE;
-
- if( mFlashing)
- {
- if ( sEnableButtonFlashing)
- {
- F32 elapsed = mFlashingTimer.getElapsedTimeF32();
- S32 flash_count = S32(elapsed * mButtonFlashRate * 2.f);
- // flash on or off?
- flash = (flash_count % 2 == 0) || flash_count > S32((F32)mButtonFlashCount * 2.f);
- }
- else
- { // otherwise just highlight button in flash color
- flash = true;
- }
- }
bool pressed_by_keyboard = FALSE;
if (hasFocus())
@@ -631,9 +640,21 @@ void LLButton::draw()
bool selected = getToggleState();
bool use_glow_effect = FALSE;
- LLColor4 glow_color = LLColor4::white;
+ LLColor4 highlighting_color = LLColor4::white;
+ LLColor4 glow_color;
LLRender::eBlendType glow_type = LLRender::BT_ADD_WITH_ALPHA;
LLUIImage* imagep = NULL;
+
+ // Cancel sticking of color, if the button is pressed,
+ // or when a flashing of the previously selected button is ended
+ if (mFlashingTimer
+ && ((selected && !mFlashingTimer->isFlashingInProgress() && !mForceFlashing) || pressed))
+ {
+ mFlashing = false;
+ }
+
+ bool flash = mFlashing && sEnableButtonFlashing;
+
if (pressed && mDisplayPressedState)
{
imagep = selected ? mImagePressedSelected : mImagePressed;
@@ -699,15 +720,20 @@ void LLButton::draw()
imagep = mImageFlash;
}
// else use usual flashing via flash_color
- else
+ else if (mFlashingTimer)
{
LLColor4 flash_color = mFlashBgColor.get();
use_glow_effect = TRUE;
glow_type = LLRender::BT_ALPHA; // blend the glow
- if (mNeedsHighlight) // highlighted AND flashing
- glow_color = (glow_color*0.5f + flash_color*0.5f) % 2.0f; // average between flash and highlight colour, with sum of the opacity
- else
+
+ if (mFlashingTimer->isCurrentlyHighlighted() || !mFlashingTimer->isFlashingInProgress())
+ {
glow_color = flash_color;
+ }
+ else if (mNeedsHighlight)
+ {
+ glow_color = highlighting_color;
+ }
}
}
@@ -756,8 +782,7 @@ void LLButton::draw()
if (use_glow_effect)
{
mCurGlowStrength = lerp(mCurGlowStrength,
- mFlashing ? (flash? 1.0 : 0.0)
- : mHoverGlowStrength,
+ mFlashing ? (mFlashingTimer->isCurrentlyHighlighted() || !mFlashingTimer->isFlashingInProgress() || mNeedsHighlight? 1.0 : 0.0) : mHoverGlowStrength,
LLCriticalDamp::getInterpolant(0.05f));
}
else
@@ -944,21 +969,27 @@ void LLButton::setToggleState(BOOL b)
{
setControlValue(b); // will fire LLControlVariable callbacks (if any)
setValue(b); // may or may not be redundant
+ setFlashing(false); // stop flash state whenever the selected/unselected state if reset
// Unselected label assignments
autoResize();
}
}
-void LLButton::setFlashing( BOOL b )
+void LLButton::setFlashing(bool b, bool force_flashing/* = false */)
{
- if ((bool)b != mFlashing)
+ mForceFlashing = force_flashing;
+ if (mFlashingTimer)
{
mFlashing = b;
- mFlashingTimer.reset();
+ (b ? mFlashingTimer->startFlashing() : mFlashingTimer->stopFlashing());
+ }
+ else if (b != mFlashing)
+ {
+ mFlashing = b;
+ mFrameTimer.reset();
}
}
-
BOOL LLButton::toggleState()
{
bool flipped = ! getToggleState();
diff --git a/indra/llui/llbutton.h b/indra/llui/llbutton.h
index deaa0823c6..7b4719866d 100644..100755
--- a/indra/llui/llbutton.h
+++ b/indra/llui/llbutton.h
@@ -30,6 +30,7 @@
#include "lluuid.h"
#include "llbadgeowner.h"
#include "llcontrol.h"
+#include "llflashtimer.h"
#include "lluictrl.h"
#include "v4color.h"
#include "llframetimer.h"
@@ -133,6 +134,7 @@ public:
Optional<bool> handle_right_mouse;
+ Optional<bool> button_flash_enable;
Optional<S32> button_flash_count;
Optional<F32> button_flash_rate;
@@ -199,8 +201,9 @@ public:
void setToggleState(BOOL b);
void setHighlight(bool b);
- void setFlashing( BOOL b );
+ void setFlashing( bool b, bool force_flashing = false );
BOOL getFlashing() const { return mFlashing; }
+ LLFlashTimer* getFlashTimer() {return mFlashingTimer;}
void setHAlign( LLFontGL::HAlign align ) { mHAlign = align; }
LLFontGL::HAlign getHAlign() const { return mHAlign; }
@@ -373,8 +376,9 @@ protected:
bool mForcePressedState;
bool mDisplayPressedState;
- LLFrameTimer mFlashingTimer;
-
+ LLFrameTimer mFrameTimer;
+ LLFlashTimer * mFlashingTimer;
+ bool mForceFlashing; // Stick flashing color even if button is pressed
bool mHandleRightMouse;
};
diff --git a/indra/llui/llcallbackmap.h b/indra/llui/llcallbackmap.h
index 0a10877c09..0a10877c09 100644..100755
--- a/indra/llui/llcallbackmap.h
+++ b/indra/llui/llcallbackmap.h
diff --git a/indra/llui/llchatentry.cpp b/indra/llui/llchatentry.cpp
new file mode 100755
index 0000000000..c04b70eb64
--- /dev/null
+++ b/indra/llui/llchatentry.cpp
@@ -0,0 +1,259 @@
+/**
+ * @file llchatentry.cpp
+ * @brief LLChatEntry implementation
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 "llscrollcontainer.h"
+
+#include "llchatentry.h"
+
+static LLDefaultChildRegistry::Register<LLChatEntry> r("chat_editor");
+
+LLChatEntry::Params::Params()
+: has_history("has_history", true),
+ is_expandable("is_expandable", false),
+ expand_lines_count("expand_lines_count", 1)
+{}
+
+LLChatEntry::LLChatEntry(const Params& p)
+: LLTextEditor(p),
+ mTextExpandedSignal(NULL),
+ mHasHistory(p.has_history),
+ mIsExpandable(p.is_expandable),
+ mExpandLinesCount(p.expand_lines_count),
+ mPrevLinesCount(0),
+ mSingleLineMode(false),
+ mPrevExpandedLineCount(S32_MAX)
+{
+ // Initialize current history line iterator
+ mCurrentHistoryLine = mLineHistory.begin();
+
+ mAutoIndent = false;
+}
+
+LLChatEntry::~LLChatEntry()
+{
+ delete mTextExpandedSignal;
+}
+
+void LLChatEntry::draw()
+{
+ if(mIsExpandable)
+ {
+ reflow();
+ expandText();
+ }
+ LLTextEditor::draw();
+}
+
+void LLChatEntry::onCommit()
+{
+ updateHistory();
+ LLTextEditor::onCommit();
+}
+
+boost::signals2::connection LLChatEntry::setTextExpandedCallback(const commit_signal_t::slot_type& cb)
+{
+ if (!mTextExpandedSignal)
+ {
+ mTextExpandedSignal = new commit_signal_t();
+ }
+ return mTextExpandedSignal->connect(cb);
+}
+
+void LLChatEntry::expandText()
+{
+ S32 line_count = mSingleLineMode ? 1 : mExpandLinesCount;
+
+ int visible_lines_count = llabs(getVisibleLines(true).first - getVisibleLines(true).second);
+ bool can_changed = getLineCount() <= line_count || line_count < mPrevExpandedLineCount ;
+ mPrevExpandedLineCount = line_count;
+
+ // true if pasted text has more lines than expand height limit and expand limit is not reached yet
+ bool text_pasted = (getLineCount() > line_count) && (visible_lines_count < line_count);
+
+ if (mIsExpandable && (can_changed || text_pasted || mSingleLineMode) && getLineCount() != mPrevLinesCount)
+ {
+ int lines_height = 0;
+ if (text_pasted)
+ {
+ // text is pasted and now mLineInfoList.size() > mExpandLineCounts and mLineInfoList is not empty,
+ // so lines_height is the sum of the last 'expanded_line_count' lines height
+ lines_height = (mLineInfoList.end() - line_count)->mRect.mTop - mLineInfoList.back().mRect.mBottom;
+ }
+ else
+ {
+ lines_height = mLineInfoList.begin()->mRect.mTop - mLineInfoList.back().mRect.mBottom;
+ }
+
+ int height = mVPad * 2 + lines_height;
+
+ LLRect doc_rect = getRect();
+ doc_rect.setOriginAndSize(doc_rect.mLeft, doc_rect.mBottom, doc_rect.getWidth(), height);
+ setShape(doc_rect);
+
+ mPrevLinesCount = getLineCount();
+
+ if (mTextExpandedSignal)
+ {
+ (*mTextExpandedSignal)(this, LLSD() );
+ }
+
+ needsReflow();
+ }
+}
+
+// line history support
+void LLChatEntry::updateHistory()
+{
+ // On history enabled, remember committed line and
+ // reset current history line number.
+ // Be sure only to remember lines that are not empty and that are
+ // different from the last on the list.
+ if (mHasHistory && getLength())
+ {
+ // Add text to history, ignoring duplicates
+ if (mLineHistory.empty() || getText() != mLineHistory.back())
+ {
+ mLineHistory.push_back(getText());
+ }
+
+ mCurrentHistoryLine = mLineHistory.end();
+ }
+}
+
+void LLChatEntry::beforeValueChange()
+{
+ if(this->getLength() == 0 && !mLabel.empty())
+ {
+ this->clearSegments();
+ }
+}
+
+void LLChatEntry::onValueChange(S32 start, S32 end)
+{
+ //Internally resetLabel() must meet a condition before it can reset the label
+ resetLabel();
+}
+
+bool LLChatEntry::useLabel() const
+{
+ return !getLength() && !mLabel.empty();
+}
+
+void LLChatEntry::onFocusReceived()
+{
+ LLUICtrl::onFocusReceived();
+ updateAllowingLanguageInput();
+}
+
+void LLChatEntry::onFocusLost()
+{
+ LLTextEditor::focusLostHelper();
+ LLUICtrl::onFocusLost();
+}
+
+BOOL LLChatEntry::handleSpecialKey(const KEY key, const MASK mask)
+{
+ BOOL handled = FALSE;
+
+ // In the case of a chat entry, pressing RETURN when something is selected
+ // should NOT erase the selection (unlike a notecard, for example)
+ if (key == KEY_RETURN)
+ {
+ endOfDoc();
+ startSelection();
+ endSelection();
+ }
+
+ LLTextEditor::handleSpecialKey(key, mask);
+
+ switch(key)
+ {
+ case KEY_RETURN:
+ if (MASK_NONE == mask)
+ {
+ needsReflow();
+ }
+ break;
+
+ case KEY_UP:
+ if (mHasHistory && MASK_CONTROL == mask)
+ {
+ if (!mLineHistory.empty() && mCurrentHistoryLine > mLineHistory.begin())
+ {
+ setText(*(--mCurrentHistoryLine));
+ endOfDoc();
+ }
+ else
+ {
+ LLUI::reportBadKeystroke();
+ }
+ handled = TRUE;
+ }
+ break;
+
+ case KEY_DOWN:
+ if (mHasHistory && MASK_CONTROL == mask)
+ {
+ if (!mLineHistory.empty() && mCurrentHistoryLine < (mLineHistory.end() - 1) )
+ {
+ setText(*(++mCurrentHistoryLine));
+ endOfDoc();
+ }
+ else if (!mLineHistory.empty() && mCurrentHistoryLine == (mLineHistory.end() - 1) )
+ {
+ mCurrentHistoryLine++;
+ std::string empty("");
+ setText(empty);
+ needsReflow();
+ endOfDoc();
+ }
+ else
+ {
+ LLUI::reportBadKeystroke();
+ }
+ handled = TRUE;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return handled;
+}
+
+void LLChatEntry::enableSingleLineMode(bool single_line_mode)
+{
+ if (mScroller)
+ {
+ mScroller->setSize(single_line_mode ? 0 : -1);
+ }
+
+ mSingleLineMode = single_line_mode;
+ mPrevLinesCount = -1;
+ setWordWrap(!single_line_mode);
+}
diff --git a/indra/llui/llchatentry.h b/indra/llui/llchatentry.h
new file mode 100755
index 0000000000..3f13691a30
--- /dev/null
+++ b/indra/llui/llchatentry.h
@@ -0,0 +1,106 @@
+/**
+ * @file llchatentry.h
+ * @author Paul Guslisty
+ * @brief Text editor widget which is used for user input
+ *
+ * Features:
+ * Optional line history so previous entries can be recalled by CTRL UP/DOWN
+ * Optional auto-resize behavior on input chat field
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 LLCHATENTRY_H_
+#define LLCHATENTRY_H_
+
+#include "lltexteditor.h"
+
+class LLChatEntry : public LLTextEditor
+{
+public:
+
+ struct Params : public LLInitParam::Block<Params, LLTextEditor::Params>
+ {
+ Optional<bool> has_history,
+ is_expandable;
+
+ Optional<int> expand_lines_count;
+
+ Params();
+ };
+
+ virtual ~LLChatEntry();
+
+protected:
+
+ friend class LLUICtrlFactory;
+ LLChatEntry(const Params& p);
+ /*virtual*/ void beforeValueChange();
+ /*virtual*/ void onValueChange(S32 start, S32 end);
+ /*virtual*/ bool useLabel() const;
+
+public:
+
+ virtual void draw();
+ virtual void onCommit();
+ /*virtual*/ void onFocusReceived();
+ /*virtual*/ void onFocusLost();
+
+ void enableSingleLineMode(bool single_line_mode);
+ boost::signals2::connection setTextExpandedCallback(const commit_signal_t::slot_type& cb);
+
+private:
+
+ /**
+ * Implements auto-resize behavior.
+ * When user's typing reaches the right edge of the chat field
+ * the chat field expands vertically by one line. The bottom of
+ * the chat field remains bottom-justified. The chat field does
+ * not expand beyond mExpandLinesCount.
+ */
+ void expandText();
+
+ /**
+ * Implements line history so previous entries can be recalled by CTRL UP/DOWN
+ */
+ void updateHistory();
+
+ BOOL handleSpecialKey(const KEY key, const MASK mask);
+
+
+ // Fired when text height expanded to mExpandLinesCount
+ commit_signal_t* mTextExpandedSignal;
+
+ // line history support:
+ typedef std::vector<std::string> line_history_t;
+ line_history_t::iterator mCurrentHistoryLine; // currently browsed history line
+ line_history_t mLineHistory; // line history storage
+ bool mHasHistory; // flag for enabled/disabled line history
+ bool mIsExpandable;
+ bool mSingleLineMode;
+
+ S32 mExpandLinesCount;
+ S32 mPrevLinesCount;
+ S32 mPrevExpandedLineCount;
+};
+
+#endif /* LLCHATENTRY_H_ */
diff --git a/indra/llui/llcheckboxctrl.cpp b/indra/llui/llcheckboxctrl.cpp
index 4fe444c1a4..5525520d78 100644..100755
--- a/indra/llui/llcheckboxctrl.cpp
+++ b/indra/llui/llcheckboxctrl.cpp
@@ -107,7 +107,7 @@ LLCheckBoxCtrl::LLCheckBoxCtrl(const LLCheckBoxCtrl::Params& p)
LLButton::Params params = p.check_button;
params.rect(btn_rect);
//params.control_name(p.control_name);
- params.click_callback.function(boost::bind(&LLCheckBoxCtrl::onButtonPress, this, _2));
+ params.click_callback.function(boost::bind(&LLCheckBoxCtrl::onCommit, this));
params.commit_on_return(false);
// Checkboxes only allow boolean initial values, but buttons can
// take any LLSD.
@@ -123,18 +123,6 @@ LLCheckBoxCtrl::~LLCheckBoxCtrl()
// Children all cleaned up by default view destructor.
}
-
-// static
-void LLCheckBoxCtrl::onButtonPress( const LLSD& data )
-{
- //if (mRadioStyle)
- //{
- // setValue(TRUE);
- //}
-
- onCommit();
-}
-
void LLCheckBoxCtrl::onCommit()
{
if( getEnabled() )
diff --git a/indra/llui/llcheckboxctrl.h b/indra/llui/llcheckboxctrl.h
index 67d8091a97..5ce45b2135 100644..100755
--- a/indra/llui/llcheckboxctrl.h
+++ b/indra/llui/llcheckboxctrl.h
@@ -103,8 +103,6 @@ public:
virtual void setControlName(const std::string& control_name, LLView* context);
- void onButtonPress(const LLSD& data);
-
virtual BOOL isDirty() const; // Returns TRUE if the user has modified this control.
virtual void resetDirty(); // Clear dirty state
diff --git a/indra/llui/llclipboard.cpp b/indra/llui/llclipboard.cpp
index 14173fdbb0..14173fdbb0 100644..100755
--- a/indra/llui/llclipboard.cpp
+++ b/indra/llui/llclipboard.cpp
diff --git a/indra/llui/llclipboard.h b/indra/llui/llclipboard.h
index fd2e7610df..fd2e7610df 100644..100755
--- a/indra/llui/llclipboard.h
+++ b/indra/llui/llclipboard.h
diff --git a/indra/llui/llcombobox.cpp b/indra/llui/llcombobox.cpp
index 806d2ef3f6..56be52f69a 100644..100755
--- a/indra/llui/llcombobox.cpp
+++ b/indra/llui/llcombobox.cpp
@@ -534,6 +534,13 @@ void LLComboBox::createLineEditor(const LLComboBox::Params& p)
}
}
+void LLComboBox::setLeftTextPadding(S32 pad)
+{
+ S32 left_pad, right_pad;
+ mTextEntry->getTextPadding(&left_pad, &right_pad);
+ mTextEntry->setTextPadding(pad, right_pad);
+}
+
void* LLComboBox::getCurrentUserdata()
{
LLScrollListItem* item = mList->getFirstSelected();
@@ -551,7 +558,7 @@ void LLComboBox::showList()
LLCoordWindow window_size;
getWindow()->getSize(&window_size);
//HACK: shouldn't have to know about scale here
- mList->fitContents( 192, llfloor((F32)window_size.mY / LLUI::sGLScaleFactor.mV[VY]) - 50 );
+ mList->fitContents( 192, llfloor((F32)window_size.mY / LLUI::getScaleFactor().mV[VY]) - 50 );
// Make sure that we can see the whole list
LLRect root_view_local;
@@ -563,8 +570,7 @@ void LLComboBox::showList()
S32 min_width = getRect().getWidth();
S32 max_width = llmax(min_width, MAX_COMBO_WIDTH);
// make sure we have up to date content width metrics
- mList->calcColumnWidths();
- S32 list_width = llclamp(mList->getMaxContentWidth(), min_width, max_width);
+ S32 list_width = llclamp(mList->calcMaxContentWidth(), min_width, max_width);
if (mListPosition == BELOW)
{
diff --git a/indra/llui/llcombobox.h b/indra/llui/llcombobox.h
index 64dbaea306..1e04fb0866 100644..100755
--- a/indra/llui/llcombobox.h
+++ b/indra/llui/llcombobox.h
@@ -190,6 +190,8 @@ public:
virtual BOOL operateOnAll(EOperation op);
//========================================================================
+
+ void setLeftTextPadding(S32 pad);
void* getCurrentUserdata();
diff --git a/indra/llui/llcommandmanager.cpp b/indra/llui/llcommandmanager.cpp
index 0e2f3f1961..49cfb2255e 100644..100755
--- a/indra/llui/llcommandmanager.cpp
+++ b/indra/llui/llcommandmanager.cpp
@@ -50,6 +50,8 @@ const LLCommandId LLCommandId::null = LLCommandId("null command");
LLCommand::Params::Params()
: available_in_toybox("available_in_toybox", false)
, icon("icon")
+ , hover_icon_unselected("hover_icon_unselected")
+ , hover_icon_selected("hover_icon_selected")
, label_ref("label_ref")
, name("name")
, tooltip_ref("tooltip_ref")
@@ -63,6 +65,7 @@ LLCommand::Params::Params()
, is_running_parameters("is_running_parameters")
, is_starting_function("is_starting_function")
, is_starting_parameters("is_starting_parameters")
+ , is_flashing_allowed("is_flashing_allowed", false)
{
}
@@ -70,6 +73,8 @@ LLCommand::LLCommand(const LLCommand::Params& p)
: mIdentifier(p.name)
, mAvailableInToybox(p.available_in_toybox)
, mIcon(p.icon)
+ , mHoverIconUnselected(p.hover_icon_unselected)
+ , mHoverIconSelected(p.hover_icon_selected)
, mLabelRef(p.label_ref)
, mName(p.name)
, mTooltipRef(p.tooltip_ref)
@@ -83,6 +88,7 @@ LLCommand::LLCommand(const LLCommand::Params& p)
, mIsRunningParameters(p.is_running_parameters)
, mIsStartingFunction(p.is_starting_function)
, mIsStartingParameters(p.is_starting_parameters)
+ , mIsFlashingAllowed(p.is_flashing_allowed)
{
}
diff --git a/indra/llui/llcommandmanager.h b/indra/llui/llcommandmanager.h
index a7276a48aa..9f276f712d 100644..100755
--- a/indra/llui/llcommandmanager.h
+++ b/indra/llui/llcommandmanager.h
@@ -96,6 +96,9 @@ public:
Mandatory<std::string> name;
Mandatory<std::string> tooltip_ref;
+ Optional<std::string> hover_icon_selected;
+ Optional<std::string> hover_icon_unselected;
+
Mandatory<std::string> execute_function;
Optional<LLSD> execute_parameters;
@@ -111,6 +114,8 @@ public:
Optional<std::string> is_starting_function;
Optional<LLSD> is_starting_parameters;
+ Optional<bool> is_flashing_allowed;
+
Params();
};
@@ -122,6 +127,8 @@ public:
const std::string& labelRef() const { return mLabelRef; }
const std::string& name() const { return mName; }
const std::string& tooltipRef() const { return mTooltipRef; }
+ const std::string& hoverIconUnselected() const {return mHoverIconUnselected; }
+ const std::string& hoverIconSelected() const {return mHoverIconSelected; }
const std::string& executeFunctionName() const { return mExecuteFunction; }
const LLSD& executeParameters() const { return mExecuteParameters; }
@@ -138,6 +145,8 @@ public:
const std::string& isStartingFunctionName() const { return mIsStartingFunction; }
const LLSD& isStartingParameters() const { return mIsStartingParameters; }
+ bool isFlashingAllowed() const { return mIsFlashingAllowed; }
+
private:
LLCommandId mIdentifier;
@@ -146,6 +155,8 @@ private:
std::string mLabelRef;
std::string mName;
std::string mTooltipRef;
+ std::string mHoverIconUnselected;
+ std::string mHoverIconSelected;
std::string mExecuteFunction;
LLSD mExecuteParameters;
@@ -161,6 +172,8 @@ private:
std::string mIsStartingFunction;
LLSD mIsStartingParameters;
+
+ bool mIsFlashingAllowed;
};
diff --git a/indra/llui/llconsole.cpp b/indra/llui/llconsole.cpp
index 161496b1f5..fdfaf284de 100644..100755
--- a/indra/llui/llconsole.cpp
+++ b/indra/llui/llconsole.cpp
@@ -243,8 +243,6 @@ void LLConsole::draw()
void LLConsole::Paragraph::makeParagraphColorSegments (const LLColor4 &color)
{
LLSD paragraph_color_segments;
- LLColor4 lcolor=color;
-
paragraph_color_segments[0]["text"] =wstring_to_utf8str(mParagraphText);
LLSD color_sd = color.getValue();
paragraph_color_segments[0]["color"]=color_sd;
diff --git a/indra/llui/llconsole.h b/indra/llui/llconsole.h
index f32f1dd74c..5ff05698b0 100644..100755
--- a/indra/llui/llconsole.h
+++ b/indra/llui/llconsole.h
@@ -37,6 +37,7 @@ class LLSD;
class LLConsole : public LLFixedBuffer, public LLUICtrl, public LLInstanceTracker<LLConsole>
{
public:
+
typedef enum e_font_size
{
MONOSPACE = -1,
diff --git a/indra/llui/llcontainerview.cpp b/indra/llui/llcontainerview.cpp
index e01e331acf..e08ccb0b78 100644..100755
--- a/indra/llui/llcontainerview.cpp
+++ b/indra/llui/llcontainerview.cpp
@@ -196,24 +196,24 @@ void LLContainerView::arrange(S32 width, S32 height, BOOL called_from_parent)
if (total_height < height)
total_height = height;
+ LLRect my_rect = getRect();
if (followsTop())
{
- // HACK: casting away const. Should use setRect or some helper function instead.
- const_cast<LLRect&>(getRect()).mBottom = getRect().mTop - total_height;
+ my_rect.mBottom = my_rect.mTop - total_height;
}
else
{
- // HACK: casting away const. Should use setRect or some helper function instead.
- const_cast<LLRect&>(getRect()).mTop = getRect().mBottom + total_height;
+ my_rect.mTop = my_rect.mBottom + total_height;
}
- // HACK: casting away const. Should use setRect or some helper function instead.
- const_cast<LLRect&>(getRect()).mRight = getRect().mLeft + width;
+
+ my_rect.mRight = my_rect.mLeft + width;
+ setRect(my_rect);
top = total_height;
if (mShowLabel)
- {
- top -= 20;
- }
+ {
+ top -= 20;
+ }
bottom = top;
diff --git a/indra/llui/llcontainerview.h b/indra/llui/llcontainerview.h
index e81600fd6c..e81600fd6c 100644..100755
--- a/indra/llui/llcontainerview.h
+++ b/indra/llui/llcontainerview.h
diff --git a/indra/llui/llctrlselectioninterface.cpp b/indra/llui/llctrlselectioninterface.cpp
index 7e886aff48..7e886aff48 100644..100755
--- a/indra/llui/llctrlselectioninterface.cpp
+++ b/indra/llui/llctrlselectioninterface.cpp
diff --git a/indra/llui/llctrlselectioninterface.h b/indra/llui/llctrlselectioninterface.h
index 2cdcbd88fe..2cdcbd88fe 100644..100755
--- a/indra/llui/llctrlselectioninterface.h
+++ b/indra/llui/llctrlselectioninterface.h
diff --git a/indra/llui/lldockablefloater.cpp b/indra/llui/lldockablefloater.cpp
index 3396213f1c..3396213f1c 100644..100755
--- a/indra/llui/lldockablefloater.cpp
+++ b/indra/llui/lldockablefloater.cpp
diff --git a/indra/llui/lldockablefloater.h b/indra/llui/lldockablefloater.h
index 89c9852f4a..89c9852f4a 100644..100755
--- a/indra/llui/lldockablefloater.h
+++ b/indra/llui/lldockablefloater.h
diff --git a/indra/llui/lldockcontrol.cpp b/indra/llui/lldockcontrol.cpp
index af39e41fa6..bd42497cb6 100644..100755
--- a/indra/llui/lldockcontrol.cpp
+++ b/indra/llui/lldockcontrol.cpp
@@ -31,7 +31,6 @@
LLDockControl::LLDockControl(LLView* dockWidget, LLFloater* dockableFloater,
const LLUIImagePtr& dockTongue, DocAt dockAt, get_allowed_rect_callback_t get_allowed_rect_callback) :
- mDockWidget(dockWidget),
mDockableFloater(dockableFloater),
mDockTongue(dockTongue),
mDockTongueX(0),
@@ -39,6 +38,11 @@ LLDockControl::LLDockControl(LLView* dockWidget, LLFloater* dockableFloater,
{
mDockAt = dockAt;
+ if (dockWidget != NULL)
+ {
+ mDockWidgetHandle = dockWidget->getHandle();
+ }
+
if (dockableFloater->isDocked())
{
on();
@@ -62,7 +66,7 @@ LLDockControl::LLDockControl(LLView* dockWidget, LLFloater* dockableFloater,
repositionDockable();
}
- if (mDockWidget != NULL)
+ if (getDock() != NULL)
{
mDockWidgetVisible = isDockVisible();
}
@@ -78,14 +82,15 @@ LLDockControl::~LLDockControl()
void LLDockControl::setDock(LLView* dockWidget)
{
- mDockWidget = dockWidget;
- if (mDockWidget != NULL)
+ if (dockWidget != NULL)
{
+ mDockWidgetHandle = dockWidget->getHandle();
repositionDockable();
mDockWidgetVisible = isDockVisible();
}
else
{
+ mDockWidgetHandle = LLHandle<LLView>();
mDockWidgetVisible = false;
}
}
@@ -97,8 +102,8 @@ void LLDockControl::getAllowedRect(LLRect& rect)
void LLDockControl::repositionDockable()
{
- if (!mDockWidget) return;
- LLRect dockRect = mDockWidget->calcScreenRect();
+ if (!getDock()) return;
+ LLRect dockRect = getDock()->calcScreenRect();
LLRect rootRect;
LLRect floater_rect = mDockableFloater->calcScreenRect();
mGetAllowedRectCallback(rootRect);
@@ -150,13 +155,13 @@ bool LLDockControl::isDockVisible()
{
bool res = true;
- if (mDockWidget != NULL)
+ if (getDock() != NULL)
{
//we should check all hierarchy
- res = mDockWidget->isInVisibleChain();
+ res = getDock()->isInVisibleChain();
if (res)
{
- LLRect dockRect = mDockWidget->calcScreenRect();
+ LLRect dockRect = getDock()->calcScreenRect();
switch (mDockAt)
{
@@ -169,7 +174,7 @@ bool LLDockControl::isDockVisible()
// assume that parent for all dockable floaters
// is the root view
LLRect dockParentRect =
- mDockWidget->getRootView()->calcScreenRect();
+ getDock()->getRootView()->calcScreenRect();
if (dockRect.mRight <= dockParentRect.mLeft
|| dockRect.mLeft >= dockParentRect.mRight)
{
@@ -189,7 +194,7 @@ bool LLDockControl::isDockVisible()
void LLDockControl::moveDockable()
{
// calculate new dockable position
- LLRect dockRect = mDockWidget->calcScreenRect();
+ LLRect dockRect = getDock()->calcScreenRect();
LLRect rootRect;
mGetAllowedRectCallback(rootRect);
@@ -263,7 +268,7 @@ void LLDockControl::moveDockable()
// calculate dock tongue position
- dockParentRect = mDockWidget->getParent()->calcScreenRect();
+ dockParentRect = getDock()->getParent()->calcScreenRect();
if (dockRect.getCenterX() < dockParentRect.mLeft)
{
mDockTongueX = dockParentRect.mLeft - mDockTongue->getWidth() / 2;
@@ -299,7 +304,7 @@ void LLDockControl::moveDockable()
}
// calculate dock tongue position
- dockParentRect = mDockWidget->getParent()->calcScreenRect();
+ dockParentRect = getDock()->getParent()->calcScreenRect();
if (dockRect.getCenterX() < dockParentRect.mLeft)
{
mDockTongueX = dockParentRect.mLeft - mDockTongue->getWidth() / 2;
diff --git a/indra/llui/lldockcontrol.h b/indra/llui/lldockcontrol.h
index c9602011f6..98a9c7236d 100644..100755
--- a/indra/llui/lldockcontrol.h
+++ b/indra/llui/lldockcontrol.h
@@ -63,7 +63,7 @@ public:
void setDock(LLView* dockWidget);
LLView* getDock()
{
- return mDockWidget;
+ return mDockWidgetHandle.get();
}
void repositionDockable();
void drawToungue();
@@ -83,7 +83,7 @@ private:
bool mRecalculateDockablePosition;
bool mDockWidgetVisible;
DocAt mDockAt;
- LLView* mDockWidget;
+ LLHandle<LLView> mDockWidgetHandle;
LLRect mPrevDockRect;
LLRect mRootRect;
LLRect mFloaterRect;
diff --git a/indra/llui/lldraghandle.cpp b/indra/llui/lldraghandle.cpp
index 5f69c6af31..5f69c6af31 100644..100755
--- a/indra/llui/lldraghandle.cpp
+++ b/indra/llui/lldraghandle.cpp
diff --git a/indra/llui/lldraghandle.h b/indra/llui/lldraghandle.h
index e095e577b1..e095e577b1 100644..100755
--- a/indra/llui/lldraghandle.h
+++ b/indra/llui/lldraghandle.h
diff --git a/indra/llui/lleditmenuhandler.cpp b/indra/llui/lleditmenuhandler.cpp
index d48237e377..d48237e377 100644..100755
--- a/indra/llui/lleditmenuhandler.cpp
+++ b/indra/llui/lleditmenuhandler.cpp
diff --git a/indra/llui/lleditmenuhandler.h b/indra/llui/lleditmenuhandler.h
index 0932f094ef..0932f094ef 100644..100755
--- a/indra/llui/lleditmenuhandler.h
+++ b/indra/llui/lleditmenuhandler.h
diff --git a/indra/llui/llf32uictrl.cpp b/indra/llui/llf32uictrl.cpp
index d186f085b4..d186f085b4 100644..100755
--- a/indra/llui/llf32uictrl.cpp
+++ b/indra/llui/llf32uictrl.cpp
diff --git a/indra/llui/llf32uictrl.h b/indra/llui/llf32uictrl.h
index 6e648f9102..6e648f9102 100644..100755
--- a/indra/llui/llf32uictrl.h
+++ b/indra/llui/llf32uictrl.h
diff --git a/indra/llui/llfiltereditor.cpp b/indra/llui/llfiltereditor.cpp
index d62874d793..d62874d793 100644..100755
--- a/indra/llui/llfiltereditor.cpp
+++ b/indra/llui/llfiltereditor.cpp
diff --git a/indra/llui/llfiltereditor.h b/indra/llui/llfiltereditor.h
index 3a05bc05a1..3a05bc05a1 100644..100755
--- a/indra/llui/llfiltereditor.h
+++ b/indra/llui/llfiltereditor.h
diff --git a/indra/llui/llflashtimer.cpp b/indra/llui/llflashtimer.cpp
new file mode 100755
index 0000000000..e49628acd5
--- /dev/null
+++ b/indra/llui/llflashtimer.cpp
@@ -0,0 +1,100 @@
+/**
+ * @file llflashtimer.cpp
+ * @brief LLFlashTimer class implementation
+ *
+ * $LicenseInfo:firstyear=2002&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 "../newview/llviewerprecompiledheaders.h"
+
+#include "llflashtimer.h"
+#include "../newview/llviewercontrol.h"
+#include "lleventtimer.h"
+
+LLFlashTimer::LLFlashTimer(callback_t cb, S32 count, F32 period)
+ : LLEventTimer(period)
+ , mCallback(cb)
+ , mCurrentTickCount(0)
+ , mIsFlashingInProgress(false)
+ , mIsCurrentlyHighlighted(false)
+ , mUnset(false)
+{
+ mEventTimer.stop();
+
+ // By default use settings from settings.xml to be able change them via Debug settings. See EXT-5973.
+ // Due to Timer is implemented as derived class from EventTimer it is impossible to change period
+ // in runtime. So, both settings are made as required restart.
+ mFlashCount = 2 * ((count > 0) ? count : gSavedSettings.getS32("FlashCount"));
+ if (mPeriod <= 0)
+ {
+ mPeriod = gSavedSettings.getF32("FlashPeriod");
+ }
+}
+
+void LLFlashTimer::unset()
+{
+ mUnset = true;
+ mCallback = NULL;
+}
+
+BOOL LLFlashTimer::tick()
+{
+ mIsCurrentlyHighlighted = !mIsCurrentlyHighlighted;
+
+ if (mCallback)
+ {
+ mCallback(mIsCurrentlyHighlighted);
+ }
+
+ if (++mCurrentTickCount >= mFlashCount)
+ {
+ stopFlashing();
+ }
+
+ return mUnset;
+}
+
+void LLFlashTimer::startFlashing()
+{
+ mIsFlashingInProgress = true;
+ mIsCurrentlyHighlighted = true;
+ mEventTimer.start();
+}
+
+void LLFlashTimer::stopFlashing()
+{
+ mEventTimer.stop();
+ mIsFlashingInProgress = false;
+ mIsCurrentlyHighlighted = false;
+ mCurrentTickCount = 0;
+}
+
+bool LLFlashTimer::isFlashingInProgress()
+{
+ return mIsFlashingInProgress;
+}
+
+bool LLFlashTimer::isCurrentlyHighlighted()
+{
+ return mIsCurrentlyHighlighted;
+}
+
+
diff --git a/indra/llui/llflashtimer.h b/indra/llui/llflashtimer.h
new file mode 100755
index 0000000000..c60f99a8ea
--- /dev/null
+++ b/indra/llui/llflashtimer.h
@@ -0,0 +1,73 @@
+/**
+ * @file llflashtimer.h
+ * @brief LLFlashTimer class implementation
+ *
+ * $LicenseInfo:firstyear=2002&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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_FLASHTIMER_H
+#define LL_FLASHTIMER_H
+
+#include "lleventtimer.h"
+
+class LLFlashTimer : public LLEventTimer
+{
+public:
+
+ typedef boost::function<void (bool)> callback_t;
+
+ /**
+ * Constructor.
+ *
+ * @param count - how many times callback should be called (twice to not change original state)
+ * @param period - how frequently callback should be called
+ * @param cb - callback to be called each tick
+ */
+ LLFlashTimer(callback_t cb = NULL, S32 count = 0, F32 period = 0.0);
+ ~LLFlashTimer() {};
+
+ /*virtual*/ BOOL tick();
+
+ void startFlashing();
+ void stopFlashing();
+
+ bool isFlashingInProgress();
+ bool isCurrentlyHighlighted();
+ /*
+ * Use this instead of deleting this object.
+ * The next call to tick() will return true and that will destroy this object.
+ */
+ void unset();
+
+private:
+ callback_t mCallback;
+ /**
+ * How many times parent will blink.
+ */
+ S32 mFlashCount;
+ S32 mCurrentTickCount;
+ bool mIsCurrentlyHighlighted;
+ bool mIsFlashingInProgress;
+ bool mUnset;
+};
+
+#endif /* LL_FLASHTIMER_H */
diff --git a/indra/llui/llflatlistview.cpp b/indra/llui/llflatlistview.cpp
index 97a52fada4..97a52fada4 100644..100755
--- a/indra/llui/llflatlistview.cpp
+++ b/indra/llui/llflatlistview.cpp
diff --git a/indra/llui/llflatlistview.h b/indra/llui/llflatlistview.h
index 92bf429031..92bf429031 100644..100755
--- a/indra/llui/llflatlistview.h
+++ b/indra/llui/llflatlistview.h
diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index 8ca1e685a9..6e6bcd6ab5 100644..100755
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -29,7 +29,7 @@
// mini-map floater, etc.
#include "linden_common.h"
-
+#include "llviewereventrecorder.h"
#include "llfloater.h"
#include "llfocusmgr.h"
@@ -64,6 +64,8 @@
// use this to control "jumping" behavior when Ctrl-Tabbing
const S32 TABBED_FLOATER_OFFSET = 0;
+extern LLControlGroup gSavedSettings;
+
namespace LLInitParam
{
void TypeValues<LLFloaterEnums::EOpenPositioning>::declareValues()
@@ -505,22 +507,11 @@ LLFloater::~LLFloater()
{
LLFloaterReg::removeInstance(mInstanceName, mKey);
-// delete mNotificationContext;
-// mNotificationContext = NULL;
-
- //// am I not hosted by another floater?
- //if (mHostHandle.isDead())
- //{
- // LLFloaterView* parent = (LLFloaterView*) getParent();
-
- // if( parent )
- // {
- // parent->removeChild( this );
- // }
- //}
-
+ if( gFocusMgr.childHasKeyboardFocus(this))
+ {
// Just in case we might still have focus here, release it.
releaseFocus();
+ }
// This is important so that floaters with persistent rects (i.e., those
// created with rect control rather than an LLRect) are restored in their
@@ -627,6 +618,17 @@ void LLFloater::setVisible( BOOL visible )
storeVisibilityControl();
}
+
+void LLFloater::setIsSingleInstance(BOOL is_single_instance)
+{
+ mSingleInstance = is_single_instance;
+ if (!mIsReuseInitialized)
+ {
+ mReuseInstance = is_single_instance; // reuse single-instance floaters by default
+ }
+}
+
+
// virtual
void LLFloater::handleVisibilityChange ( BOOL new_visibility )
{
@@ -640,16 +642,25 @@ void LLFloater::handleVisibilityChange ( BOOL new_visibility )
void LLFloater::openFloater(const LLSD& key)
{
- llinfos << "Opening floater " << getName() << llendl;
+ llinfos << "Opening floater " << getName() << " full path: " << getPathname() << llendl;
+
+ LLViewerEventRecorder::instance().logVisibilityChange( getPathname(), getName(), true,"floater"); // Last param is event subtype or empty string
+
mKey = key; // in case we need to open ourselves again
-
+
if (getSoundFlags() != SILENT
// don't play open sound for hosted (tabbed) windows
&& !getHost()
&& !getFloaterHost()
&& (!getVisible() || isMinimized()))
{
- make_ui_sound("UISndWindowOpen");
+ //Don't play a sound for incoming voice call based upon chat preference setting
+ bool playSound = !(getName() == "incoming call" && gSavedSettings.getBOOL("PlaySoundIncomingVoiceCall") == FALSE);
+
+ if(playSound)
+ {
+ make_ui_sound("UISndWindowOpen");
+ }
}
//RN: for now, we don't allow rehosting from one multifloater to another
@@ -688,6 +699,7 @@ void LLFloater::openFloater(const LLSD& key)
void LLFloater::closeFloater(bool app_quitting)
{
llinfos << "Closing floater " << getName() << llendl;
+ LLViewerEventRecorder::instance().logVisibilityChange( getPathname(), getName(), false,"floater"); // Last param is event subtype or empty string
if (app_quitting)
{
LLFloater::sQuitting = true;
@@ -713,6 +725,33 @@ void LLFloater::closeFloater(bool app_quitting)
make_ui_sound("UISndWindowClose");
}
+ gFocusMgr.clearLastFocusForGroup(this);
+
+ if (hasFocus())
+ {
+ // Do this early, so UI controls will commit before the
+ // window is taken down.
+ releaseFocus();
+
+ // give focus to dependee floater if it exists, and we had focus first
+ if (isDependent())
+ {
+ LLFloater* dependee = mDependeeHandle.get();
+ if (dependee && !dependee->isDead())
+ {
+ dependee->setFocus(TRUE);
+ }
+ }
+ }
+
+
+ //If floater is a dependent, remove it from parent (dependee)
+ LLFloater* dependee = mDependeeHandle.get();
+ if (dependee)
+ {
+ dependee->removeDependentFloater(this);
+ }
+
// now close dependent floater
for(handle_set_iter_t dependent_it = mDependents.begin();
dependent_it != mDependents.end(); )
@@ -731,24 +770,6 @@ void LLFloater::closeFloater(bool app_quitting)
}
cleanupHandles();
- gFocusMgr.clearLastFocusForGroup(this);
-
- if (hasFocus())
- {
- // Do this early, so UI controls will commit before the
- // window is taken down.
- releaseFocus();
-
- // give focus to dependee floater if it exists, and we had focus first
- if (isDependent())
- {
- LLFloater* dependee = mDependeeHandle.get();
- if (dependee && !dependee->isDead())
- {
- dependee->setFocus(TRUE);
- }
- }
- }
dirtyRect();
@@ -785,6 +806,20 @@ void LLFloater::closeFloater(bool app_quitting)
}
/*virtual*/
+void LLFloater::closeHostedFloater()
+{
+ // When toggling *visibility*, close the host instead of the floater when hosted
+ if (getHost())
+ {
+ getHost()->closeFloater();
+ }
+ else
+ {
+ closeFloater();
+ }
+}
+
+/*virtual*/
void LLFloater::reshape(S32 width, S32 height, BOOL called_from_parent)
{
LLPanel::reshape(width, height, called_from_parent);
@@ -1101,17 +1136,26 @@ void LLFloater::handleReshape(const LLRect& new_rect, bool by_user)
const LLRect old_rect = getRect();
LLView::handleReshape(new_rect, by_user);
- if (by_user && !isMinimized())
+ if (by_user && !getHost())
{
- storeRectControl();
- mPositioning = LLFloaterEnums::POSITIONING_RELATIVE;
- LLRect screen_rect = calcScreenRect();
- mPosition = LLCoordGL(screen_rect.getCenterX(), screen_rect.getCenterY()).convert();
+ static_cast<LLFloaterView*>(getParent())->adjustToFitScreen(this, !isMinimized());
}
// if not minimized, adjust all snapped dependents to new shape
if (!isMinimized())
{
+ if (by_user)
+ {
+ if (isDocked())
+ {
+ setDocked( false, false);
+ }
+ storeRectControl();
+ mPositioning = LLFloaterEnums::POSITIONING_RELATIVE;
+ LLRect screen_rect = calcScreenRect();
+ mPosition = LLCoordGL(screen_rect.getCenterX(), screen_rect.getCenterY()).convert();
+ }
+
// gather all snapped dependents
for(handle_set_iter_t dependent_it = mDependents.begin();
dependent_it != mDependents.end(); ++dependent_it)
@@ -1175,7 +1219,6 @@ void LLFloater::setMinimized(BOOL minimize)
{
// minimized flag should be turned on before release focus
mMinimized = TRUE;
-
mExpandedRect = getRect();
// If the floater has been dragged while minimized in the
@@ -1248,7 +1291,6 @@ void LLFloater::setMinimized(BOOL minimize)
}
setOrigin( mExpandedRect.mLeft, mExpandedRect.mBottom );
-
if (mButtonsEnabled[BUTTON_RESTORE])
{
mButtonsEnabled[BUTTON_MINIMIZE] = TRUE;
@@ -1284,7 +1326,6 @@ void LLFloater::setMinimized(BOOL minimize)
// Reshape *after* setting mMinimized
reshape( mExpandedRect.getWidth(), mExpandedRect.getHeight(), TRUE );
- applyPositioning(NULL, false);
}
make_ui_sound("UISndWindowClose");
@@ -1298,7 +1339,7 @@ void LLFloater::setFocus( BOOL b )
{
return;
}
- LLUICtrl* last_focus = gFocusMgr.getLastFocusForGroup(this);
+ LLView* last_focus = gFocusMgr.getLastFocusForGroup(this);
// a descendent already has focus
BOOL child_had_focus = hasFocus();
@@ -1406,7 +1447,6 @@ void LLFloater::setHost(LLMultiFloater* host)
mButtonScale = 1.f;
//mButtonsEnabled[BUTTON_TEAR_OFF] = FALSE;
}
- updateTitleButtons();
if (host)
{
mHostHandle = host->getHandle();
@@ -1416,6 +1456,8 @@ void LLFloater::setHost(LLMultiFloater* host)
{
mHostHandle.markDead();
}
+
+ updateTitleButtons();
}
void LLFloater::moveResizeHandlesToFront()
@@ -1437,6 +1479,7 @@ void LLFloater::moveResizeHandlesToFront()
}
}
+/*virtual*/
BOOL LLFloater::isFrontmost()
{
LLFloaterView* floater_view = getParentByType<LLFloaterView>();
@@ -1455,7 +1498,7 @@ void LLFloater::addDependentFloater(LLFloater* floaterp, BOOL reposition)
floaterp->setRect(gFloaterView->findNeighboringPosition(this, floaterp));
floaterp->setSnapTarget(getHandle());
}
- gFloaterView->adjustToFitScreen(floaterp, FALSE);
+ gFloaterView->adjustToFitScreen(floaterp, FALSE, TRUE);
if (floaterp->isFrontmost())
{
// make sure to bring self and sibling floaters to front
@@ -1504,6 +1547,17 @@ BOOL LLFloater::handleScrollWheel(S32 x, S32 y, S32 clicks)
}
// virtual
+BOOL LLFloater::handleMouseUp(S32 x, S32 y, MASK mask)
+{
+ lldebugs << "LLFloater::handleMouseUp calling LLPanel (really LLView)'s handleMouseUp (first initialized xui to: " << getPathname() << " )" << llendl;
+ BOOL handled = LLPanel::handleMouseUp(x,y,mask); // Not implemented in LLPanel so this actually calls LLView
+ if (handled) {
+ LLViewerEventRecorder::instance().updateMouseEventInfo(x,y,-55,-55,getPathname());
+ }
+ return handled;
+}
+
+// virtual
BOOL LLFloater::handleMouseDown(S32 x, S32 y, MASK mask)
{
if( mMinimized )
@@ -1523,7 +1577,11 @@ BOOL LLFloater::handleMouseDown(S32 x, S32 y, MASK mask)
else
{
bringToFront( x, y );
- return LLPanel::handleMouseDown( x, y, mask );
+ BOOL handled = LLPanel::handleMouseDown( x, y, mask );
+ if (handled) {
+ LLViewerEventRecorder::instance().updateMouseEventInfo(x,y,-55,-55,getPathname());
+ }
+ return handled;
}
}
@@ -1572,10 +1630,19 @@ void LLFloater::bringToFront( S32 x, S32 y )
// virtual
-void LLFloater::setVisibleAndFrontmost(BOOL take_focus)
+void LLFloater::setVisibleAndFrontmost(BOOL take_focus, const LLSD& key)
{
- setVisible(TRUE);
- setFrontmost(take_focus);
+ LLMultiFloater* hostp = getHost();
+ if (hostp)
+ {
+ hostp->setVisible(TRUE);
+ hostp->setFrontmost(take_focus);
+ }
+ else
+ {
+ setVisible(TRUE);
+ setFrontmost(take_focus);
+ }
}
void LLFloater::setFrontmost(BOOL take_focus)
@@ -1657,10 +1724,12 @@ void LLFloater::onClickTearOff(LLFloater* self)
gFloaterView->addChild(self);
self->openFloater(self->getKey());
-
- // only force position for floaters that don't have that data saved
- if (self->mRectControl.empty())
+ if (self->mSaveRect && !self->mRectControl.empty())
{
+ self->applyRectControl();
+ }
+ else
+ { // only force position for floaters that don't have that data saved
new_rect.setLeftTopAndSize(host_floater->getRect().mLeft + 5, host_floater->getRect().mTop - floater_header_size - 5, self->getRect().getWidth(), self->getRect().getHeight());
self->setRect(new_rect);
}
@@ -1674,6 +1743,10 @@ void LLFloater::onClickTearOff(LLFloater* self)
LLMultiFloater* new_host = (LLMultiFloater*)self->mLastHostHandle.get();
if (new_host)
{
+ if (self->mSaveRect)
+ {
+ self->storeRectControl();
+ }
self->setMinimized(FALSE); // to reenable minimize button if it was minimized
new_host->showFloater(self);
// make sure host is visible
@@ -1682,6 +1755,7 @@ void LLFloater::onClickTearOff(LLFloater* self)
self->setTornOff(false);
}
self->updateTitleButtons();
+ self->setOpenPositioning(LLFloaterEnums::POSITIONING_RELATIVE);
}
// static
@@ -1707,56 +1781,22 @@ void LLFloater::onClickHelp( LLFloater* self )
}
}
-// static
-LLFloater* LLFloater::getClosableFloaterFromFocus()
+void LLFloater::initRectControl()
{
- LLFloater* focused_floater = NULL;
- LLInstanceTracker<LLFloater>::instance_iter it = beginInstances();
- LLInstanceTracker<LLFloater>::instance_iter end_it = endInstances();
- for (; it != end_it; ++it)
- {
- if (it->hasFocus())
- {
- LLFloater& floater = *it;
- focused_floater = &floater;
- break;
- }
- }
-
- if (it == endInstances())
+ // save_rect and save_visibility only apply to registered floaters
+ if (mSaveRect)
{
- // nothing found, return
- return NULL;
- }
-
- // The focused floater may not be closable,
- // Find and close a parental floater that is closeable, if any.
- LLFloater* prev_floater = NULL;
- for(LLFloater* floater_to_close = focused_floater;
- NULL != floater_to_close;
- floater_to_close = gFloaterView->getParentFloater(floater_to_close))
- {
- if(floater_to_close->isCloseable())
- {
- return floater_to_close;
- }
-
- // If floater has as parent root view
- // gFloaterView->getParentFloater(floater_to_close) returns
- // the same floater_to_close, so we need to check this.
- if (prev_floater == floater_to_close) {
- break;
- }
- prev_floater = floater_to_close;
+ std::string ctrl_name = getControlName(mInstanceName, mKey);
+ mRectControl = LLFloaterReg::declareRectControl(ctrl_name);
+ mPosXControl = LLFloaterReg::declarePosXControl(ctrl_name);
+ mPosYControl = LLFloaterReg::declarePosYControl(ctrl_name);
}
-
- return NULL;
}
// static
-void LLFloater::closeFocusedFloater()
+void LLFloater::closeFrontmostFloater()
{
- LLFloater* floater_to_close = LLFloater::getClosableFloaterFromFocus();
+ LLFloater* floater_to_close = gFloaterView->getFrontmostClosableFloater();
if(floater_to_close)
{
floater_to_close->closeFloater();
@@ -1781,7 +1821,7 @@ void LLFloater::onClickClose( LLFloater* self )
self->onClickCloseBtn();
}
-void LLFloater::onClickCloseBtn()
+void LLFloater::onClickCloseBtn(bool app_quitting)
{
closeFloater(false);
}
@@ -2197,7 +2237,8 @@ LLFloaterView::LLFloaterView (const Params& p)
mFocusCycleMode(FALSE),
mMinimizePositionVOffset(0),
mSnapOffsetBottom(0),
- mSnapOffsetRight(0)
+ mSnapOffsetRight(0),
+ mFrontChild(NULL)
{
mSnapView = getHandle();
}
@@ -2346,6 +2387,17 @@ LLRect LLFloaterView::findNeighboringPosition( LLFloater* reference_floater, LLF
void LLFloaterView::bringToFront(LLFloater* child, BOOL give_focus)
{
+ if (mFrontChild == child)
+ {
+ if (give_focus && !gFocusMgr.childHasKeyboardFocus(child))
+ {
+ child->setFocus(TRUE);
+ }
+ return;
+ }
+
+ mFrontChild = child;
+
// *TODO: make this respect floater's mAutoFocus value, instead of
// using parameter
if (child->getHost())
@@ -2353,15 +2405,14 @@ void LLFloaterView::bringToFront(LLFloater* child, BOOL give_focus)
// this floater is hosted elsewhere and hence not one of our children, abort
return;
}
- std::vector<LLView*> floaters_to_move;
+ std::vector<LLFloater*> floaters_to_move;
// Look at all floaters...tab
- for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it)
+ for (child_list_const_iter_t child_it = beginChild(); child_it != endChild(); ++child_it)
{
- LLView* viewp = *child_it;
- LLFloater *floater = (LLFloater *)viewp;
+ LLFloater* floater = dynamic_cast<LLFloater*>(*child_it);
// ...but if I'm a dependent floater...
- if (child->isDependent())
+ if (floater && child->isDependent())
{
// ...look for floaters that have me as a dependent...
LLFloater::handle_set_iter_t found_dependent = floater->mDependents.find(child->getHandle());
@@ -2369,15 +2420,14 @@ void LLFloaterView::bringToFront(LLFloater* child, BOOL give_focus)
if (found_dependent != floater->mDependents.end())
{
// ...and make sure all children of that floater (including me) are brought to front...
- for(LLFloater::handle_set_iter_t dependent_it = floater->mDependents.begin();
- dependent_it != floater->mDependents.end(); )
+ for (LLFloater::handle_set_iter_t dependent_it = floater->mDependents.begin();
+ dependent_it != floater->mDependents.end(); ++dependent_it)
{
LLFloater* sibling = dependent_it->get();
if (sibling)
{
floaters_to_move.push_back(sibling);
}
- ++dependent_it;
}
//...before bringing my parent to the front...
floaters_to_move.push_back(floater);
@@ -2385,10 +2435,10 @@ void LLFloaterView::bringToFront(LLFloater* child, BOOL give_focus)
}
}
- std::vector<LLView*>::iterator view_it;
- for(view_it = floaters_to_move.begin(); view_it != floaters_to_move.end(); ++view_it)
+ std::vector<LLFloater*>::iterator floater_it;
+ for(floater_it = floaters_to_move.begin(); floater_it != floaters_to_move.end(); ++floater_it)
{
- LLFloater* floaterp = (LLFloater*)(*view_it);
+ LLFloater* floaterp = *floater_it;
sendChildToFront(floaterp);
// always unminimize dependee, but allow dependents to stay minimized
@@ -2400,23 +2450,19 @@ void LLFloaterView::bringToFront(LLFloater* child, BOOL give_focus)
floaters_to_move.clear();
// ...then bringing my own dependents to the front...
- for(LLFloater::handle_set_iter_t dependent_it = child->mDependents.begin();
- dependent_it != child->mDependents.end(); )
+ for (LLFloater::handle_set_iter_t dependent_it = child->mDependents.begin();
+ dependent_it != child->mDependents.end(); ++dependent_it)
{
LLFloater* dependent = dependent_it->get();
if (dependent)
{
sendChildToFront(dependent);
- //don't un-minimize dependent windows automatically
- // respect user's wishes
- //dependent->setMinimized(FALSE);
}
- ++dependent_it;
}
// ...and finally bringing myself to front
// (do this last, so that I'm left in front at end of this call)
- if( *getChildList()->begin() != child )
+ if (*beginChild() != child)
{
sendChildToFront(child);
}
@@ -2474,6 +2520,24 @@ void LLFloaterView::highlightFocusedFloater()
}
}
+LLFloater* LLFloaterView::getFrontmostClosableFloater()
+{
+ child_list_const_iter_t child_it;
+ LLFloater* frontmost_floater = NULL;
+
+ for ( child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it)
+ {
+ frontmost_floater = (LLFloater *)(*child_it);
+
+ if (frontmost_floater->isInVisibleChain() && frontmost_floater->isCloseable())
+ {
+ return frontmost_floater;
+ }
+ }
+
+ return NULL;
+}
+
void LLFloaterView::unhighlightFocusedFloater()
{
for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it)
@@ -2680,7 +2744,7 @@ void LLFloaterView::refresh()
const S32 FLOATER_MIN_VISIBLE_PIXELS = 16;
-void LLFloaterView::adjustToFitScreen(LLFloater* floater, BOOL allow_partial_outside)
+void LLFloaterView::adjustToFitScreen(LLFloater* floater, BOOL allow_partial_outside, BOOL snap_in_toolbars/* = false*/)
{
if (floater->getParent() != this)
{
@@ -2733,7 +2797,7 @@ void LLFloaterView::adjustToFitScreen(LLFloater* floater, BOOL allow_partial_out
}
// move window fully onscreen
- if (floater->translateIntoRect( getSnapRect(), allow_partial_outside ? FLOATER_MIN_VISIBLE_PIXELS : S32_MAX ))
+ if (floater->translateIntoRect( snap_in_toolbars ? getSnapRect() : gFloaterView->getRect(), allow_partial_outside ? FLOATER_MIN_VISIBLE_PIXELS : S32_MAX ))
{
floater->clearSnapTarget();
}
@@ -2938,21 +3002,14 @@ void LLFloaterView::popVisibleAll(const skip_list_t& skip_list)
void LLFloater::setInstanceName(const std::string& name)
{
- if (name == mInstanceName)
- return;
+ if (name != mInstanceName)
+ {
llassert_always(mInstanceName.empty());
mInstanceName = name;
if (!mInstanceName.empty())
{
std::string ctrl_name = getControlName(mInstanceName, mKey);
-
- // save_rect and save_visibility only apply to registered floaters
- if (mSaveRect)
- {
- mRectControl = LLFloaterReg::declareRectControl(ctrl_name);
- mPosXControl = LLFloaterReg::declarePosXControl(ctrl_name);
- mPosYControl = LLFloaterReg::declarePosYControl(ctrl_name);
- }
+ initRectControl();
if (!mVisibilityControl.empty())
{
mVisibilityControl = LLFloaterReg::declareVisibilityControl(ctrl_name);
@@ -2963,6 +3020,7 @@ void LLFloater::setInstanceName(const std::string& name)
}
}
}
+}
void LLFloater::setKey(const LLSD& newkey)
{
@@ -3209,6 +3267,11 @@ bool LLFloater::isShown() const
return ! isMinimized() && isInVisibleChain();
}
+bool LLFloater::isDetachedAndNotMinimized()
+{
+ return !getHost() && !isMinimized();
+}
+
/* static */
bool LLFloater::isShown(const LLFloater* floater)
{
@@ -3229,24 +3292,14 @@ bool LLFloater::isVisible(const LLFloater* floater)
static LLFastTimer::DeclareTimer FTM_BUILD_FLOATERS("Build Floaters");
-bool LLFloater::buildFromFile(const std::string& filename, LLXMLNodePtr output_node)
+bool LLFloater::buildFromFile(const std::string& filename)
{
LLFastTimer timer(FTM_BUILD_FLOATERS);
LLXMLNodePtr root;
- //if exporting, only load the language being exported,
- //instead of layering localized version on top of english
- if (output_node)
- {
- if (!LLUICtrlFactory::getLocalizedXMLNode(filename, root))
- {
- llwarns << "Couldn't parse floater from: " << LLUI::getLocalizedSkinPath() + gDirUtilp->getDirDelimiter() + filename << llendl;
- return false;
- }
- }
- else if (!LLUICtrlFactory::getLayeredXMLNode(filename, root))
+ if (!LLUICtrlFactory::getLayeredXMLNode(filename, root))
{
- llwarns << "Couldn't parse floater from: " << LLUI::getSkinPath() + gDirUtilp->getDirDelimiter() + filename << llendl;
+ llwarns << "Couldn't find (or parse) floater from: " << filename << llendl;
return false;
}
@@ -3271,7 +3324,7 @@ bool LLFloater::buildFromFile(const std::string& filename, LLXMLNodePtr output_n
getCommitCallbackRegistrar().pushScope();
getEnableCallbackRegistrar().pushScope();
- res = initFloaterXML(root, getParent(), filename, output_node);
+ res = initFloaterXML(root, getParent(), filename, NULL);
setXMLFilename(filename);
diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h
index 64d6dcea04..75715ef296 100644..100755
--- a/indra/llui/llfloater.h
+++ b/indra/llui/llfloater.h
@@ -112,6 +112,8 @@ struct LLCoordFloater : LLCoord<LL_COORD_FLOATER>
bool operator!=(const LLCoordFloater& other) const { return !(*this == other); }
void setFloater(LLFloater& floater);
+
+
};
class LLFloater : public LLPanel, public LLInstanceTracker<LLFloater>
@@ -121,6 +123,7 @@ class LLFloater : public LLPanel, public LLInstanceTracker<LLFloater>
friend class LLMultiFloater;
public:
+
struct KeyCompare
{
// static bool compare(const LLSD& a, const LLSD& b);
@@ -202,7 +205,7 @@ public:
// Don't export top/left for rect, only height/width
static void setupParamsForExport(Params& p, LLView* parent);
- bool buildFromFile(const std::string &filename, LLXMLNodePtr output_node = NULL);
+ bool buildFromFile(const std::string &filename);
boost::signals2::connection setMinimizeCallback( const commit_signal_t::slot_type& cb );
boost::signals2::connection setOpenCallback( const commit_signal_t::slot_type& cb );
@@ -217,13 +220,17 @@ public:
/*virtual*/ void setFocus( BOOL b );
/*virtual*/ void setIsChrome(BOOL is_chrome);
/*virtual*/ void setRect(const LLRect &rect);
+ void setIsSingleInstance(BOOL is_single_instance);
void initFloater(const Params& p);
void openFloater(const LLSD& key = LLSD());
// If allowed, close the floater cleanly, releasing focus.
- void closeFloater(bool app_quitting = false);
+ virtual void closeFloater(bool app_quitting = false);
+
+ // Close the floater or its host. Use when hidding or toggling a floater instance.
+ virtual void closeHostedFloater();
/*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
@@ -234,6 +241,7 @@ public:
void center();
LLMultiFloater* getHost();
+ bool isDetachedAndNotMinimized();
void applyTitle();
std::string getCurrentTitle() const;
@@ -257,7 +265,7 @@ public:
static bool isVisible(const LLFloater* floater);
static bool isMinimized(const LLFloater* floater);
BOOL isFirstLook() { return mFirstLook; } // EXT-2653: This function is necessary to prevent overlapping for secondary showed toasts
- BOOL isFrontmost();
+ virtual BOOL isFrontmost();
BOOL isDependent() { return !mDependeeHandle.isDead(); }
void setCanMinimize(BOOL can_minimize);
void setCanClose(BOOL can_close);
@@ -281,6 +289,7 @@ public:
S32 getHeaderHeight() const { return mHeaderHeight; }
virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
+ virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask);
virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
virtual BOOL handleDoubleClick(S32 x, S32 y, MASK mask);
virtual BOOL handleMiddleMouseDown(S32 x, S32 y, MASK mask);
@@ -301,6 +310,7 @@ public:
/*virtual*/ void handleVisibilityChange ( BOOL new_visibility ); // do not override
void setFrontmost(BOOL take_focus = TRUE);
+ virtual void setVisibleAndFrontmost(BOOL take_focus=TRUE, const LLSD& key = LLSD());
// Defaults to false.
virtual BOOL canSaveAs() const { return FALSE; }
@@ -324,13 +334,13 @@ public:
virtual void setDocked(bool docked, bool pop_on_undock = true);
virtual void setTornOff(bool torn_off) { mTornOff = torn_off; }
+ bool isTornOff() {return mTornOff;}
+ void setOpenPositioning(LLFloaterEnums::EOpenPositioning pos) {mPositioning = pos;}
- // Return a closeable floater, if any, given the current focus.
- static LLFloater* getClosableFloaterFromFocus();
- // Close the floater returned by getClosableFloaterFromFocus() and
+ // Close the floater returned by getFrontmostClosableFloater() and
// handle refocusing.
- static void closeFocusedFloater();
+ static void closeFrontmostFloater();
// LLNotification::Params contextualNotification(const std::string& name)
// {
@@ -356,6 +366,7 @@ protected:
void stackWith(LLFloater& other);
+ virtual void initRectControl();
virtual bool applyRectControl();
bool applyDockState();
void applyPositioning(LLFloater* other, bool on_open);
@@ -369,7 +380,6 @@ protected:
void setInstanceName(const std::string& name);
virtual void bringToFront(S32 x, S32 y);
- virtual void setVisibleAndFrontmost(BOOL take_focus=TRUE);
void setExpandedRect(const LLRect& rect) { mExpandedRect = rect; } // size when not minimized
const LLRect& getExpandedRect() const { return mExpandedRect; }
@@ -380,7 +390,7 @@ protected:
void destroy(); // Don't call this directly. You probably want to call closeFloater()
- virtual void onClickCloseBtn();
+ virtual void onClickCloseBtn(bool app_quitting = false);
virtual void updateTitleButtons();
@@ -443,9 +453,10 @@ private:
LLUIString mTitle;
LLUIString mShortTitle;
- BOOL mSingleInstance; // TRUE if there is only ever one instance of the floater
- bool mReuseInstance; // true if we want to hide the floater when we close it instead of destroying it
- std::string mInstanceName; // Store the instance name so we can remove ourselves from the list
+ BOOL mSingleInstance; // TRUE if there is only ever one instance of the floater
+ bool mReuseInstance; // true if we want to hide the floater when we close it instead of destroying it
+ bool mIsReuseInitialized; // true if mReuseInstance already set from parameters
+ std::string mInstanceName; // Store the instance name so we can remove ourselves from the list
BOOL mCanTearOff;
BOOL mCanMinimize;
@@ -522,7 +533,7 @@ public:
LLRect findNeighboringPosition( LLFloater* reference_floater, LLFloater* neighbor );
// Given a child of gFloaterView, make sure this view can fit entirely onscreen.
- void adjustToFitScreen(LLFloater* floater, BOOL allow_partial_outside);
+ void adjustToFitScreen(LLFloater* floater, BOOL allow_partial_outside, BOOL snap_in_toolbars = false);
void setMinimizePositionVerticalOffset(S32 offset) { mMinimizePositionVOffset = offset; }
void getMinimizePosition( S32 *left, S32 *bottom);
@@ -559,6 +570,7 @@ public:
S32 getZOrder(LLFloater* child);
void setFloaterSnapView(LLHandle<LLView> snap_view) {mSnapView = snap_view; }
+ LLFloater* getFrontmostClosableFloater();
private:
void hiddenFloaterClosed(LLFloater* floater);
@@ -571,6 +583,7 @@ private:
S32 mMinimizePositionVOffset;
typedef std::vector<std::pair<LLHandle<LLFloater>, boost::signals2::connection> > hidden_floaters_t;
hidden_floaters_t mHiddenFloaters;
+ LLFloater * mFrontChild;
};
//
diff --git a/indra/llui/llfloaterreg.cpp b/indra/llui/llfloaterreg.cpp
index 9115eb7174..b1b75776a7 100644..100755
--- a/indra/llui/llfloaterreg.cpp
+++ b/indra/llui/llfloaterreg.cpp
@@ -154,7 +154,7 @@ LLFloater* LLFloaterReg::getInstance(const std::string& name, const LLSD& key)
llwarns << "Failed to build floater type: '" << name << "'." << llendl;
return NULL;
}
- bool success = res->buildFromFile(xui_file, NULL);
+ bool success = res->buildFromFile(xui_file);
if (!success)
{
llwarns << "Failed to build floater type: '" << name << "'." << llendl;
@@ -264,17 +264,9 @@ bool LLFloaterReg::hideInstance(const std::string& name, const LLSD& key)
LLFloater* instance = findInstance(name, key);
if (instance)
{
- // When toggling *visibility*, close the host instead of the floater when hosted
- if (instance->getHost())
- instance->getHost()->closeFloater();
- else
- instance->closeFloater();
- return true;
- }
- else
- {
- return false;
+ instance->closeHostedFloater();
}
+ return (instance != NULL);
}
//static
@@ -284,11 +276,7 @@ bool LLFloaterReg::toggleInstance(const std::string& name, const LLSD& key)
LLFloater* instance = findInstance(name, key);
if (LLFloater::isShown(instance))
{
- // When toggling *visibility*, close the host instead of the floater when hosted
- if (instance->getHost())
- instance->getHost()->closeFloater();
- else
- instance->closeFloater();
+ instance->closeHostedFloater();
return false;
}
else
@@ -368,8 +356,8 @@ std::string LLFloaterReg::declareRectControl(const std::string& name)
{
std::string controlname = getRectControlName(name);
LLFloater::getControlGroup()->declareRect(controlname, LLRect(),
- llformat("Window Size for %s", name.c_str()),
- TRUE);
+ llformat("Window Size for %s", name.c_str()),
+ LLControlVariable::PERSIST_NONDFT);
return controlname;
}
@@ -379,7 +367,7 @@ std::string LLFloaterReg::declarePosXControl(const std::string& name)
LLFloater::getControlGroup()->declareF32(controlname,
10.f,
llformat("Window X Position for %s", name.c_str()),
- TRUE);
+ LLControlVariable::PERSIST_NONDFT);
return controlname;
}
@@ -389,7 +377,7 @@ std::string LLFloaterReg::declarePosYControl(const std::string& name)
LLFloater::getControlGroup()->declareF32(controlname,
10.f,
llformat("Window Y Position for %s", name.c_str()),
- TRUE);
+ LLControlVariable::PERSIST_NONDFT);
return controlname;
}
@@ -416,7 +404,7 @@ std::string LLFloaterReg::declareVisibilityControl(const std::string& name)
std::string controlname = getVisibilityControlName(name);
LLFloater::getControlGroup()->declareBOOL(controlname, FALSE,
llformat("Window Visibility for %s", name.c_str()),
- TRUE);
+ LLControlVariable::PERSIST_NONDFT);
return controlname;
}
@@ -426,7 +414,7 @@ std::string LLFloaterReg::declareDockStateControl(const std::string& name)
std::string controlname = getDockStateControlName(name);
LLFloater::getControlGroup()->declareBOOL(controlname, TRUE,
llformat("Window Docking state for %s", name.c_str()),
- TRUE);
+ LLControlVariable::PERSIST_NONDFT);
return controlname;
}
@@ -481,31 +469,58 @@ void LLFloaterReg::toggleInstanceOrBringToFront(const LLSD& sdname, const LLSD&
// * Also, if it is not on top, bring it forward when focus is given.
// * Else the target floater is open, close it.
//
-
std::string name = sdname.asString();
LLFloater* instance = getInstance(name, key);
+
if (!instance)
{
lldebugs << "Unable to get instance of floater '" << name << "'" << llendl;
+ return;
}
- else if (instance->isMinimized())
+
+ // If hosted, we need to take that into account
+ LLFloater* host = instance->getHost();
+
+ if (host)
{
- instance->setMinimized(FALSE);
- instance->setVisibleAndFrontmost();
- }
- else if (!instance->isShown())
- {
- instance->openFloater(key);
- instance->setVisibleAndFrontmost();
- }
- else if (!instance->isFrontmost())
- {
- instance->setVisibleAndFrontmost();
+ if (host->isMinimized() || !host->isShown() || !host->isFrontmost())
+ {
+ host->setMinimized(FALSE);
+ instance->openFloater(key);
+ instance->setVisibleAndFrontmost(true, key);
+ }
+ else if (!instance->getVisible())
+ {
+ instance->openFloater(key);
+ instance->setVisibleAndFrontmost(true, key);
+ instance->setFocus(TRUE);
+ }
+ else
+ {
+ instance->closeHostedFloater();
+ }
}
else
{
- instance->closeFloater();
+ if (instance->isMinimized())
+ {
+ instance->setMinimized(FALSE);
+ instance->setVisibleAndFrontmost(true, key);
+ }
+ else if (!instance->isShown())
+ {
+ instance->openFloater(key);
+ instance->setVisibleAndFrontmost(true, key);
+ }
+ else if (!instance->isFrontmost())
+ {
+ instance->setVisibleAndFrontmost(true, key);
+ }
+ else
+ {
+ instance->closeHostedFloater();
+ }
}
}
diff --git a/indra/llui/llfloaterreg.h b/indra/llui/llfloaterreg.h
index a1e1f8a988..a1e1f8a988 100644..100755
--- a/indra/llui/llfloaterreg.h
+++ b/indra/llui/llfloaterreg.h
diff --git a/indra/llui/llfloaterreglistener.cpp b/indra/llui/llfloaterreglistener.cpp
index 7525b8cab3..7525b8cab3 100644..100755
--- a/indra/llui/llfloaterreglistener.cpp
+++ b/indra/llui/llfloaterreglistener.cpp
diff --git a/indra/llui/llfloaterreglistener.h b/indra/llui/llfloaterreglistener.h
index 24311a2dfa..24311a2dfa 100644..100755
--- a/indra/llui/llfloaterreglistener.h
+++ b/indra/llui/llfloaterreglistener.h
diff --git a/indra/llui/llflyoutbutton.cpp b/indra/llui/llflyoutbutton.cpp
index 4b3a0a5d21..4b3a0a5d21 100644..100755
--- a/indra/llui/llflyoutbutton.cpp
+++ b/indra/llui/llflyoutbutton.cpp
diff --git a/indra/llui/llflyoutbutton.h b/indra/llui/llflyoutbutton.h
index 36998eba2e..36998eba2e 100644..100755
--- a/indra/llui/llflyoutbutton.h
+++ b/indra/llui/llflyoutbutton.h
diff --git a/indra/llui/llfocusmgr.cpp b/indra/llui/llfocusmgr.cpp
index 724d190307..f03c8d444b 100644..100755
--- a/indra/llui/llfocusmgr.cpp
+++ b/indra/llui/llfocusmgr.cpp
@@ -469,7 +469,7 @@ void LLFocusMgr::setAppHasFocus(BOOL focus)
mAppHasFocus = focus;
}
-LLUICtrl* LLFocusMgr::getLastFocusForGroup(LLView* subtree_root) const
+LLView* LLFocusMgr::getLastFocusForGroup(LLView* subtree_root) const
{
if (subtree_root)
{
@@ -477,7 +477,7 @@ LLUICtrl* LLFocusMgr::getLastFocusForGroup(LLView* subtree_root) const
if (found_it != mImpl->mFocusHistory.end())
{
// found last focus for this subtree
- return static_cast<LLUICtrl*>(found_it->second.get());
+ return found_it->second.get();
}
}
return NULL;
diff --git a/indra/llui/llfocusmgr.h b/indra/llui/llfocusmgr.h
index 25ae1d2579..1c7326260c 100644..100755
--- a/indra/llui/llfocusmgr.h
+++ b/indra/llui/llfocusmgr.h
@@ -97,7 +97,7 @@ public:
void triggerFocusFlash();
BOOL getAppHasFocus() const { return mAppHasFocus; }
void setAppHasFocus(BOOL focus);
- LLUICtrl* getLastFocusForGroup(LLView* subtree_root) const;
+ LLView* getLastFocusForGroup(LLView* subtree_root) const;
void clearLastFocusForGroup(LLView* subtree_root);
// If setKeyboardFocus(NULL) is called, and there is a non-NULL default
diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp
new file mode 100755
index 0000000000..f32a52e6c6
--- /dev/null
+++ b/indra/llui/llfolderview.cpp
@@ -0,0 +1,1954 @@
+/**
+ * @file llfolderview.cpp
+ * @brief Implementation of the folder view collection of classes.
+ *
+ * $LicenseInfo:firstyear=2001&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 "llfolderview.h"
+#include "llfolderviewmodel.h"
+#include "llclipboard.h" // *TODO: remove this once hack below gone.
+#include "llkeyboard.h"
+#include "lllineeditor.h"
+#include "llmenugl.h"
+#include "llpanel.h"
+#include "llscrollcontainer.h" // hack to allow scrolling
+#include "lltextbox.h"
+#include "lltrans.h"
+#include "llui.h"
+#include "lluictrlfactory.h"
+
+// Linden library includes
+#include "lldbstrings.h"
+#include "llfocusmgr.h"
+#include "llfontgl.h"
+#include "llgl.h"
+#include "llrender.h"
+
+// Third-party library includes
+#include <algorithm>
+
+///----------------------------------------------------------------------------
+/// Local function declarations, constants, enums, and typedefs
+///----------------------------------------------------------------------------
+
+const S32 RENAME_WIDTH_PAD = 4;
+const S32 RENAME_HEIGHT_PAD = 1;
+const S32 AUTO_OPEN_STACK_DEPTH = 16;
+
+const S32 MINIMUM_RENAMER_WIDTH = 80;
+
+// *TODO: move in params in xml if necessary. Requires modification of LLFolderView & LLInventoryPanel Params.
+const S32 STATUS_TEXT_HPAD = 6;
+const S32 STATUS_TEXT_VPAD = 8;
+
+enum {
+ SIGNAL_NO_KEYBOARD_FOCUS = 1,
+ SIGNAL_KEYBOARD_FOCUS = 2
+};
+
+F32 LLFolderView::sAutoOpenTime = 1.f;
+
+//---------------------------------------------------------------------------
+
+// Tells all folders in a folderview to close themselves
+// For efficiency, calls setOpenArrangeRecursively().
+// The calling function must then call:
+// LLFolderView* root = getRoot();
+// if( root )
+// {
+// root->arrange( NULL, NULL );
+// root->scrollToShowSelection();
+// }
+// to patch things up.
+class LLCloseAllFoldersFunctor : public LLFolderViewFunctor
+{
+public:
+ LLCloseAllFoldersFunctor(BOOL close) { mOpen = !close; }
+ virtual ~LLCloseAllFoldersFunctor() {}
+ virtual void doFolder(LLFolderViewFolder* folder);
+ virtual void doItem(LLFolderViewItem* item);
+
+ BOOL mOpen;
+};
+
+
+void LLCloseAllFoldersFunctor::doFolder(LLFolderViewFolder* folder)
+{
+ folder->setOpenArrangeRecursively(mOpen);
+}
+
+// Do nothing.
+void LLCloseAllFoldersFunctor::doItem(LLFolderViewItem* item)
+{ }
+
+///----------------------------------------------------------------------------
+/// Class LLFolderViewScrollContainer
+///----------------------------------------------------------------------------
+
+// virtual
+const LLRect LLFolderViewScrollContainer::getScrolledViewRect() const
+{
+ LLRect rect = LLRect::null;
+ if (mScrolledView)
+ {
+ LLFolderView* folder_view = dynamic_cast<LLFolderView*>(mScrolledView);
+ if (folder_view)
+ {
+ S32 height = folder_view->getRect().getHeight();
+
+ rect = mScrolledView->getRect();
+ rect.setLeftTopAndSize(rect.mLeft, rect.mTop, rect.getWidth(), height);
+ }
+ }
+
+ return rect;
+}
+
+LLFolderViewScrollContainer::LLFolderViewScrollContainer(const LLScrollContainer::Params& p)
+: LLScrollContainer(p)
+{}
+
+///----------------------------------------------------------------------------
+/// Class LLFolderView
+///----------------------------------------------------------------------------
+LLFolderView::Params::Params()
+: title("title"),
+ use_label_suffix("use_label_suffix"),
+ allow_multiselect("allow_multiselect", true),
+ show_empty_message("show_empty_message", true),
+ use_ellipses("use_ellipses", false),
+ options_menu("options_menu", "")
+{
+ folder_indentation = -4;
+}
+
+
+// Default constructor
+LLFolderView::LLFolderView(const Params& p)
+: LLFolderViewFolder(p),
+ mScrollContainer( NULL ),
+ mPopupMenuHandle(),
+ mAllowMultiSelect(p.allow_multiselect),
+ mShowEmptyMessage(p.show_empty_message),
+ mShowFolderHierarchy(FALSE),
+ mRenameItem( NULL ),
+ mNeedsScroll( FALSE ),
+ mUseLabelSuffix(p.use_label_suffix),
+ mPinningSelectedItem(FALSE),
+ mNeedsAutoSelect( FALSE ),
+ mAutoSelectOverride(FALSE),
+ mNeedsAutoRename(FALSE),
+ mShowSelectionContext(FALSE),
+ mShowSingleSelection(FALSE),
+ mArrangeGeneration(0),
+ mSignalSelectCallback(0),
+ mMinWidth(0),
+ mDragAndDropThisFrame(FALSE),
+ mCallbackRegistrar(NULL),
+ mParentPanel(p.parent_panel),
+ mUseEllipses(p.use_ellipses),
+ mDraggingOverItem(NULL),
+ mStatusTextBox(NULL),
+ mShowItemLinkOverlays(p.show_item_link_overlays),
+ mViewModel(p.view_model)
+{
+ mViewModel->setFolderView(this);
+ mRoot = this;
+
+ LLRect rect = p.rect;
+ LLRect new_rect(rect.mLeft, rect.mBottom + getRect().getHeight(), rect.mLeft + getRect().getWidth(), rect.mBottom);
+ setRect( rect );
+ reshape(rect.getWidth(), rect.getHeight());
+ mAutoOpenItems.setDepth(AUTO_OPEN_STACK_DEPTH);
+ mAutoOpenCandidate = NULL;
+ mAutoOpenTimer.stop();
+ mKeyboardSelection = FALSE;
+ mIndentation = getParentFolder() ? getParentFolder()->getIndentation() + mLocalIndentation : 0;
+
+ //clear label
+ // go ahead and render root folder as usual
+ // just make sure the label ("Inventory Folder") never shows up
+ mLabel = LLStringUtil::null;
+
+ // Escape is handled by reverting the rename, not commiting it (default behavior)
+ LLLineEditor::Params params;
+ params.name("ren");
+ params.rect(rect);
+ params.font(getLabelFontForStyle(LLFontGL::NORMAL));
+ params.max_length.bytes(DB_INV_ITEM_NAME_STR_LEN);
+ params.commit_callback.function(boost::bind(&LLFolderView::commitRename, this, _2));
+ params.prevalidate_callback(&LLTextValidate::validateASCIIPrintableNoPipe);
+ params.commit_on_focus_lost(true);
+ params.visible(false);
+ mRenamer = LLUICtrlFactory::create<LLLineEditor> (params);
+ addChild(mRenamer);
+
+ // Textbox
+ LLTextBox::Params text_p;
+ LLFontGL* font = getLabelFontForStyle(mLabelStyle);
+ //mIconPad, mTextPad are set in folder_view_item.xml
+ LLRect new_r = LLRect(rect.mLeft + mIconPad,
+ rect.mTop - mTextPad,
+ rect.mRight,
+ rect.mTop - mTextPad - font->getLineHeight());
+ text_p.rect(new_r);
+ text_p.name(std::string(p.name));
+ text_p.font(font);
+ text_p.visible(false);
+ text_p.parse_urls(true);
+ text_p.wrap(true); // allow multiline text. See EXT-7564, EXT-7047
+ // set text padding the same as in People panel. EXT-7047, EXT-4837
+ text_p.h_pad(STATUS_TEXT_HPAD);
+ text_p.v_pad(STATUS_TEXT_VPAD);
+ mStatusTextBox = LLUICtrlFactory::create<LLTextBox> (text_p);
+ mStatusTextBox->setFollowsLeft();
+ mStatusTextBox->setFollowsTop();
+ //addChild(mStatusTextBox);
+
+
+ // make the popup menu available
+ LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>(p.options_menu, LLMenuGL::sMenuContainer, LLMenuHolderGL::child_registry_t::instance());
+ if (!menu)
+ {
+ menu = LLUICtrlFactory::getDefaultWidget<LLMenuGL>("inventory_menu");
+ }
+ menu->setBackgroundColor(LLUIColorTable::instance().getColor("MenuPopupBgColor"));
+ mPopupMenuHandle = menu->getHandle();
+
+ mViewModelItem->openItem();
+}
+
+// Destroys the object
+LLFolderView::~LLFolderView( void )
+{
+ closeRenamer();
+
+ // The release focus call can potentially call the
+ // scrollcontainer, which can potentially be called with a partly
+ // destroyed scollcontainer. Just null it out here, and no worries
+ // about calling into the invalid scroll container.
+ // Same with the renamer.
+ mScrollContainer = NULL;
+ mRenameItem = NULL;
+ mRenamer = NULL;
+ mStatusTextBox = NULL;
+
+ mAutoOpenItems.removeAllNodes();
+
+ if (mPopupMenuHandle.get()) mPopupMenuHandle.get()->die();
+
+ mAutoOpenItems.removeAllNodes();
+ clearSelection();
+ mItems.clear();
+ mFolders.clear();
+
+ mViewModel = NULL;
+}
+
+BOOL LLFolderView::canFocusChildren() const
+{
+ return FALSE;
+}
+
+void LLFolderView::addFolder( LLFolderViewFolder* folder)
+{
+ LLFolderViewFolder::addFolder(folder);
+}
+
+void LLFolderView::closeAllFolders()
+{
+ // Close all the folders
+ setOpenArrangeRecursively(FALSE, LLFolderViewFolder::RECURSE_DOWN);
+ arrangeAll();
+}
+
+void LLFolderView::openTopLevelFolders()
+{
+ for (folders_t::iterator iter = mFolders.begin();
+ iter != mFolders.end();)
+ {
+ folders_t::iterator fit = iter++;
+ (*fit)->setOpen(TRUE);
+ }
+}
+
+// This view grows and shrinks to enclose all of its children items and folders.
+// *width should be 0
+// conform show folder state works
+S32 LLFolderView::arrange( S32* unused_width, S32* unused_height )
+ {
+ mMinWidth = 0;
+ S32 target_height;
+
+ LLFolderViewFolder::arrange(&mMinWidth, &target_height);
+
+ LLRect scroll_rect = (mScrollContainer ? mScrollContainer->getContentWindowRect() : LLRect());
+ reshape( llmax(scroll_rect.getWidth(), mMinWidth), llround(mCurHeight) );
+
+ LLRect new_scroll_rect = (mScrollContainer ? mScrollContainer->getContentWindowRect() : LLRect());
+ if (new_scroll_rect.getWidth() != scroll_rect.getWidth())
+ {
+ reshape( llmax(scroll_rect.getWidth(), mMinWidth), llround(mCurHeight) );
+ }
+
+ // move item renamer text field to item's new position
+ updateRenamerPosition();
+
+ return llround(mTargetHeight);
+}
+
+static LLFastTimer::DeclareTimer FTM_FILTER("Filter Folder View");
+
+void LLFolderView::filter( LLFolderViewFilter& filter )
+{
+ // Entry point of inventory filtering (CHUI-849)
+ LLFastTimer t2(FTM_FILTER);
+ filter.resetTime(llclamp(LLUI::sSettingGroups["config"]->getS32(mParentPanel->getVisible() ? "FilterItemsMaxTimePerFrameVisible" : "FilterItemsMaxTimePerFrameUnvisible"), 1, 100));
+
+ // Note: we filter the model, not the view
+ getViewModelItem()->filter(filter);
+}
+
+void LLFolderView::reshape(S32 width, S32 height, BOOL called_from_parent)
+{
+ LLRect scroll_rect;
+ if (mScrollContainer)
+ {
+ LLView::reshape(width, height, called_from_parent);
+ scroll_rect = mScrollContainer->getContentWindowRect();
+ }
+ width = llmax(mMinWidth, scroll_rect.getWidth());
+ height = llmax(llround(mCurHeight), scroll_rect.getHeight());
+
+ // Restrict width within scroll container's width
+ if (mUseEllipses && mScrollContainer)
+ {
+ width = scroll_rect.getWidth();
+ }
+ LLView::reshape(width, height, called_from_parent);
+ mReshapeSignal(mSelectedItems, FALSE);
+}
+
+void LLFolderView::addToSelectionList(LLFolderViewItem* item)
+{
+ if (item->isSelected())
+ {
+ removeFromSelectionList(item);
+ }
+ if (mSelectedItems.size())
+ {
+ mSelectedItems.back()->setIsCurSelection(FALSE);
+ }
+ item->setIsCurSelection(TRUE);
+ mSelectedItems.push_back(item);
+}
+
+void LLFolderView::removeFromSelectionList(LLFolderViewItem* item)
+{
+ if (mSelectedItems.size())
+ {
+ mSelectedItems.back()->setIsCurSelection(FALSE);
+ }
+
+ selected_items_t::iterator item_iter;
+ for (item_iter = mSelectedItems.begin(); item_iter != mSelectedItems.end();)
+ {
+ if (*item_iter == item)
+ {
+ item_iter = mSelectedItems.erase(item_iter);
+ }
+ else
+ {
+ ++item_iter;
+ }
+ }
+ if (mSelectedItems.size())
+ {
+ mSelectedItems.back()->setIsCurSelection(TRUE);
+ }
+}
+
+LLFolderViewItem* LLFolderView::getCurSelectedItem( void )
+{
+ if(mSelectedItems.size())
+ {
+ LLFolderViewItem* itemp = mSelectedItems.back();
+ llassert(itemp->getIsCurSelection());
+ return itemp;
+ }
+ return NULL;
+}
+
+LLFolderView::selected_items_t& LLFolderView::getSelectedItems( void )
+{
+ return mSelectedItems;
+}
+
+// Record the selected item and pass it down the hierachy.
+BOOL LLFolderView::setSelection(LLFolderViewItem* selection, BOOL openitem,
+ BOOL take_keyboard_focus)
+{
+ mSignalSelectCallback = take_keyboard_focus ? SIGNAL_KEYBOARD_FOCUS : SIGNAL_NO_KEYBOARD_FOCUS;
+
+ if( selection == this )
+ {
+ return FALSE;
+ }
+
+ if( selection && take_keyboard_focus)
+ {
+ mParentPanel->setFocus(TRUE);
+ }
+
+ // clear selection down here because change of keyboard focus can potentially
+ // affect selection
+ clearSelection();
+
+ if(selection)
+ {
+ addToSelectionList(selection);
+ }
+
+ BOOL rv = LLFolderViewFolder::setSelection(selection, openitem, take_keyboard_focus);
+ if(openitem && selection)
+ {
+ selection->getParentFolder()->requestArrange();
+ }
+
+ llassert(mSelectedItems.size() <= 1);
+
+ return rv;
+}
+
+BOOL LLFolderView::changeSelection(LLFolderViewItem* selection, BOOL selected)
+{
+ BOOL rv = FALSE;
+
+ // can't select root folder
+ if(!selection || selection == this)
+ {
+ return FALSE;
+ }
+
+ if (!mAllowMultiSelect)
+ {
+ clearSelection();
+ }
+
+ selected_items_t::iterator item_iter;
+ for (item_iter = mSelectedItems.begin(); item_iter != mSelectedItems.end(); ++item_iter)
+ {
+ if (*item_iter == selection)
+ {
+ break;
+ }
+ }
+
+ BOOL on_list = (item_iter != mSelectedItems.end());
+
+ if(selected && !on_list)
+ {
+ addToSelectionList(selection);
+ }
+ if(!selected && on_list)
+ {
+ removeFromSelectionList(selection);
+ }
+
+ rv = LLFolderViewFolder::changeSelection(selection, selected);
+
+ mSignalSelectCallback = SIGNAL_KEYBOARD_FOCUS;
+
+ return rv;
+}
+
+static LLFastTimer::DeclareTimer FTM_SANITIZE_SELECTION("Sanitize Selection");
+void LLFolderView::sanitizeSelection()
+{
+ LLFastTimer _(FTM_SANITIZE_SELECTION);
+ // store off current item in case it is automatically deselected
+ // and we want to preserve context
+ LLFolderViewItem* original_selected_item = getCurSelectedItem();
+
+ std::vector<LLFolderViewItem*> items_to_remove;
+ selected_items_t::iterator item_iter;
+ for (item_iter = mSelectedItems.begin(); item_iter != mSelectedItems.end(); ++item_iter)
+ {
+ LLFolderViewItem* item = *item_iter;
+
+ // ensure that each ancestor is open and potentially passes filtering
+ BOOL visible = false;
+ if(item->getViewModelItem() != NULL)
+ {
+ visible = item->getViewModelItem()->potentiallyVisible(); // initialize from filter state for this item
+ }
+ // modify with parent open and filters states
+ LLFolderViewFolder* parent_folder = item->getParentFolder();
+ // Move up through parent folders and see what's visible
+ while(parent_folder)
+ {
+ visible = visible && parent_folder->isOpen() && parent_folder->getViewModelItem()->potentiallyVisible();
+ parent_folder = parent_folder->getParentFolder();
+ }
+
+ // deselect item if any ancestor is closed or didn't pass filter requirements.
+ if (!visible)
+ {
+ items_to_remove.push_back(item);
+ }
+
+ // disallow nested selections (i.e. folder items plus one or more ancestors)
+ // could check cached mum selections count and only iterate if there are any
+ // but that may be a premature optimization.
+ selected_items_t::iterator other_item_iter;
+ for (other_item_iter = mSelectedItems.begin(); other_item_iter != mSelectedItems.end(); ++other_item_iter)
+ {
+ LLFolderViewItem* other_item = *other_item_iter;
+ for( parent_folder = other_item->getParentFolder(); parent_folder; parent_folder = parent_folder->getParentFolder())
+ {
+ if (parent_folder == item)
+ {
+ // this is a descendent of the current folder, remove from list
+ items_to_remove.push_back(other_item);
+ break;
+ }
+ }
+ }
+
+ // Don't allow invisible items (such as root folders) to be selected.
+ if (item == getRoot())
+ {
+ items_to_remove.push_back(item);
+ }
+ }
+
+ std::vector<LLFolderViewItem*>::iterator item_it;
+ for (item_it = items_to_remove.begin(); item_it != items_to_remove.end(); ++item_it )
+ {
+ changeSelection(*item_it, FALSE); // toggle selection (also removes from list)
+ }
+
+ // if nothing selected after prior constraints...
+ if (mSelectedItems.empty())
+ {
+ // ...select first available parent of original selection
+ LLFolderViewItem* new_selection = NULL;
+ if (original_selected_item)
+ {
+ for(LLFolderViewFolder* parent_folder = original_selected_item->getParentFolder();
+ parent_folder;
+ parent_folder = parent_folder->getParentFolder())
+ {
+ if (parent_folder->getViewModelItem() && parent_folder->getViewModelItem()->potentiallyVisible())
+ {
+ // give initial selection to first ancestor folder that potentially passes the filter
+ if (!new_selection)
+ {
+ new_selection = parent_folder;
+ }
+
+ // if any ancestor folder of original item is closed, move the selection up
+ // to the highest closed
+ if (!parent_folder->isOpen())
+ {
+ new_selection = parent_folder;
+ }
+ }
+ }
+ }
+ else
+ {
+ new_selection = NULL;
+ }
+
+ if (new_selection)
+ {
+ setSelection(new_selection, FALSE, FALSE);
+ }
+ }
+}
+
+void LLFolderView::clearSelection()
+{
+ for (selected_items_t::const_iterator item_it = mSelectedItems.begin();
+ item_it != mSelectedItems.end();
+ ++item_it)
+ {
+ (*item_it)->setUnselected();
+ }
+
+ mSelectedItems.clear();
+}
+
+std::set<LLFolderViewItem*> LLFolderView::getSelectionList() const
+{
+ std::set<LLFolderViewItem*> selection;
+ std::copy(mSelectedItems.begin(), mSelectedItems.end(), std::inserter(selection, selection.begin()));
+ return selection;
+}
+
+bool LLFolderView::startDrag()
+{
+ std::vector<LLFolderViewModelItem*> selected_items;
+ selected_items_t::iterator item_it;
+
+ if (!mSelectedItems.empty())
+ {
+ for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it)
+ {
+ selected_items.push_back((*item_it)->getViewModelItem());
+ }
+
+ return getFolderViewModel()->startDrag(selected_items);
+ }
+ return false;
+}
+
+void LLFolderView::commitRename( const LLSD& data )
+{
+ finishRenamingItem();
+}
+
+void LLFolderView::draw()
+{
+ //LLFontGL* font = getLabelFontForStyle(mLabelStyle);
+
+ // if cursor has moved off of me during drag and drop
+ // close all auto opened folders
+ if (!mDragAndDropThisFrame)
+ {
+ closeAutoOpenedFolders();
+ }
+
+ if (mSearchTimer.getElapsedTimeF32() > LLUI::sSettingGroups["config"]->getF32("TypeAheadTimeout") || !mSearchString.size())
+ {
+ mSearchString.clear();
+ }
+
+ if (hasVisibleChildren())
+ {
+ mStatusTextBox->setVisible( FALSE );
+ }
+ else if (mShowEmptyMessage)
+ {
+ mStatusTextBox->setValue(getFolderViewModel()->getStatusText());
+ mStatusTextBox->setVisible( TRUE );
+
+ // firstly reshape message textbox with current size. This is necessary to
+ // LLTextBox::getTextPixelHeight works properly
+ const LLRect local_rect = getLocalRect();
+ mStatusTextBox->setShape(local_rect);
+
+ // get preferable text height...
+ S32 pixel_height = mStatusTextBox->getTextPixelHeight();
+ bool height_changed = (local_rect.getHeight() < pixel_height);
+ if (height_changed)
+ {
+ // ... if it does not match current height, lets rearrange current view.
+ // This will indirectly call ::arrange and reshape of the status textbox.
+ // We should call this method to also notify parent about required rect.
+ // See EXT-7564, EXT-7047.
+ S32 height = 0;
+ S32 width = 0;
+ S32 total_height = arrange( &width, &height );
+ notifyParent(LLSD().with("action", "size_changes").with("height", total_height));
+
+ LLUI::popMatrix();
+ LLUI::pushMatrix();
+ LLUI::translate((F32)getRect().mLeft, (F32)getRect().mBottom);
+ }
+ }
+
+ // skip over LLFolderViewFolder::draw since we don't want the folder icon, label,
+ // and arrow for the root folder
+ LLView::draw();
+
+ mDragAndDropThisFrame = FALSE;
+}
+
+void LLFolderView::finishRenamingItem( void )
+{
+ if(!mRenamer)
+ {
+ return;
+ }
+ if( mRenameItem )
+ {
+ mRenameItem->rename( mRenamer->getText() );
+ }
+
+ closeRenamer();
+
+ // List is re-sorted alphabetically, so scroll to make sure the selected item is visible.
+ scrollToShowSelection();
+}
+
+void LLFolderView::closeRenamer( void )
+{
+ if (mRenamer && mRenamer->getVisible())
+ {
+ // Triggers onRenamerLost() that actually closes the renamer.
+ LLUI::removePopup(mRenamer);
+ }
+}
+
+void LLFolderView::removeSelectedItems()
+{
+ if(getVisible() && getEnabled())
+ {
+ // just in case we're removing the renaming item.
+ mRenameItem = NULL;
+
+ // create a temporary structure which we will use to remove
+ // items, since the removal will futz with internal data
+ // structures.
+ std::vector<LLFolderViewItem*> items;
+ S32 count = mSelectedItems.size();
+ if(count == 0) return;
+ LLFolderViewItem* item = NULL;
+ selected_items_t::iterator item_it;
+ for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it)
+ {
+ item = *item_it;
+ if (item && item->isRemovable())
+ {
+ items.push_back(item);
+ }
+ else
+ {
+ llinfos << "Cannot delete " << item->getName() << llendl;
+ return;
+ }
+ }
+
+ // iterate through the new container.
+ count = items.size();
+ LLUUID new_selection_id;
+ LLFolderViewItem* item_to_select = getNextUnselectedItem();
+
+ if(count == 1)
+ {
+ LLFolderViewItem* item_to_delete = items[0];
+ LLFolderViewFolder* parent = item_to_delete->getParentFolder();
+ if(parent)
+ {
+ if (item_to_delete->remove())
+ {
+ // change selection on successful delete
+ setSelection(item_to_select, item_to_select ? item_to_select->isOpen() : false, mParentPanel->hasFocus());
+ }
+ }
+ arrangeAll();
+ }
+ else if (count > 1)
+ {
+ LLDynamicArray<LLFolderViewModelItem*> listeners;
+ LLFolderViewModelItem* listener;
+
+ setSelection(item_to_select, item_to_select ? item_to_select->isOpen() : false, mParentPanel->hasFocus());
+
+ for(S32 i = 0; i < count; ++i)
+ {
+ listener = items[i]->getViewModelItem();
+ if(listener && (listeners.find(listener) == LLDynamicArray<LLFolderViewModelItem*>::FAIL))
+ {
+ listeners.put(listener);
+ }
+ }
+ listener = static_cast<LLFolderViewModelItem*>(listeners.get(0));
+ if(listener)
+ {
+ listener->removeBatch(listeners);
+ }
+ }
+ arrangeAll();
+ scrollToShowSelection();
+ }
+}
+
+void LLFolderView::autoOpenItem( LLFolderViewFolder* item )
+{
+ if ((mAutoOpenItems.check() == item) ||
+ (mAutoOpenItems.getDepth() >= (U32)AUTO_OPEN_STACK_DEPTH) ||
+ item->isOpen())
+ {
+ return;
+ }
+
+ // close auto-opened folders
+ LLFolderViewFolder* close_item = mAutoOpenItems.check();
+ while (close_item && close_item != item->getParentFolder())
+ {
+ mAutoOpenItems.pop();
+ close_item->setOpenArrangeRecursively(FALSE);
+ close_item = mAutoOpenItems.check();
+ }
+
+ item->requestArrange();
+
+ mAutoOpenItems.push(item);
+
+ item->setOpen(TRUE);
+ LLRect content_rect = (mScrollContainer ? mScrollContainer->getContentWindowRect() : LLRect());
+ LLRect constraint_rect(0,content_rect.getHeight(), content_rect.getWidth(), 0);
+ scrollToShowItem(item, constraint_rect);
+}
+
+void LLFolderView::closeAutoOpenedFolders()
+{
+ while (mAutoOpenItems.check())
+ {
+ LLFolderViewFolder* close_item = mAutoOpenItems.pop();
+ close_item->setOpen(FALSE);
+ }
+
+ if (mAutoOpenCandidate)
+ {
+ mAutoOpenCandidate->setAutoOpenCountdown(0.f);
+ }
+ mAutoOpenCandidate = NULL;
+ mAutoOpenTimer.stop();
+}
+
+BOOL LLFolderView::autoOpenTest(LLFolderViewFolder* folder)
+{
+ if (folder && mAutoOpenCandidate == folder)
+ {
+ if (mAutoOpenTimer.getStarted())
+ {
+ if (!mAutoOpenCandidate->isOpen())
+ {
+ mAutoOpenCandidate->setAutoOpenCountdown(clamp_rescale(mAutoOpenTimer.getElapsedTimeF32(), 0.f, sAutoOpenTime, 0.f, 1.f));
+ }
+ if (mAutoOpenTimer.getElapsedTimeF32() > sAutoOpenTime)
+ {
+ autoOpenItem(folder);
+ mAutoOpenTimer.stop();
+ return TRUE;
+ }
+ }
+ return FALSE;
+ }
+
+ // otherwise new candidate, restart timer
+ if (mAutoOpenCandidate)
+ {
+ mAutoOpenCandidate->setAutoOpenCountdown(0.f);
+ }
+ mAutoOpenCandidate = folder;
+ mAutoOpenTimer.start();
+ return FALSE;
+}
+
+BOOL LLFolderView::canCopy() const
+{
+ if (!(getVisible() && getEnabled() && (mSelectedItems.size() > 0)))
+ {
+ return FALSE;
+ }
+
+ for (selected_items_t::const_iterator selected_it = mSelectedItems.begin(); selected_it != mSelectedItems.end(); ++selected_it)
+ {
+ const LLFolderViewItem* item = *selected_it;
+ if (!item->getViewModelItem()->isItemCopyable())
+ {
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+// copy selected item
+void LLFolderView::copy()
+{
+ // *NOTE: total hack to clear the inventory clipboard
+ LLClipboard::instance().reset();
+ S32 count = mSelectedItems.size();
+ if(getVisible() && getEnabled() && (count > 0))
+ {
+ LLFolderViewModelItem* listener = NULL;
+ selected_items_t::iterator item_it;
+ for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it)
+ {
+ listener = (*item_it)->getViewModelItem();
+ if(listener)
+ {
+ listener->copyToClipboard();
+ }
+ }
+ }
+ mSearchString.clear();
+}
+
+BOOL LLFolderView::canCut() const
+{
+ if (!(getVisible() && getEnabled() && (mSelectedItems.size() > 0)))
+ {
+ return FALSE;
+ }
+
+ for (selected_items_t::const_iterator selected_it = mSelectedItems.begin(); selected_it != mSelectedItems.end(); ++selected_it)
+ {
+ const LLFolderViewItem* item = *selected_it;
+ const LLFolderViewModelItem* listener = item->getViewModelItem();
+
+ if (!listener || !listener->isItemRemovable())
+ {
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+void LLFolderView::cut()
+{
+ // clear the inventory clipboard
+ LLClipboard::instance().reset();
+ if(getVisible() && getEnabled() && (mSelectedItems.size() > 0))
+ {
+ // Find out which item will be selected once the selection will be cut
+ LLFolderViewItem* item_to_select = getNextUnselectedItem();
+
+ // Get the selection: removeItem() modified mSelectedItems and makes iterating on it unwise
+ std::set<LLFolderViewItem*> inventory_selected = getSelectionList();
+
+ // Move each item to the clipboard and out of their folder
+ for (std::set<LLFolderViewItem*>::iterator item_it = inventory_selected.begin(); item_it != inventory_selected.end(); ++item_it)
+ {
+ LLFolderViewItem* item_to_cut = *item_it;
+ LLFolderViewModelItem* listener = item_to_cut->getViewModelItem();
+ if (listener)
+ {
+ listener->cutToClipboard();
+ listener->removeItem();
+ }
+ }
+
+ // Update the selection
+ setSelection(item_to_select, item_to_select ? item_to_select->isOpen() : false, mParentPanel->hasFocus());
+ }
+ mSearchString.clear();
+}
+
+BOOL LLFolderView::canPaste() const
+{
+ if (mSelectedItems.empty())
+ {
+ return FALSE;
+ }
+
+ if(getVisible() && getEnabled())
+ {
+ for (selected_items_t::const_iterator item_it = mSelectedItems.begin();
+ item_it != mSelectedItems.end(); ++item_it)
+ {
+ // *TODO: only check folders and parent folders of items
+ const LLFolderViewItem* item = (*item_it);
+ const LLFolderViewModelItem* listener = item->getViewModelItem();
+ if(!listener || !listener->isClipboardPasteable())
+ {
+ const LLFolderViewFolder* folderp = item->getParentFolder();
+ listener = folderp->getViewModelItem();
+ if (!listener || !listener->isClipboardPasteable())
+ {
+ return FALSE;
+ }
+ }
+ }
+ return TRUE;
+ }
+ return FALSE;
+}
+
+// paste selected item
+void LLFolderView::paste()
+{
+ if(getVisible() && getEnabled())
+ {
+ // find set of unique folders to paste into
+ std::set<LLFolderViewFolder*> folder_set;
+
+ selected_items_t::iterator selected_it;
+ for (selected_it = mSelectedItems.begin(); selected_it != mSelectedItems.end(); ++selected_it)
+ {
+ LLFolderViewItem* item = *selected_it;
+ LLFolderViewFolder* folder = dynamic_cast<LLFolderViewFolder*>(item);
+ if (folder == NULL)
+ {
+ folder = item->getParentFolder();
+ }
+ folder_set.insert(folder);
+ }
+
+ std::set<LLFolderViewFolder*>::iterator set_iter;
+ for(set_iter = folder_set.begin(); set_iter != folder_set.end(); ++set_iter)
+ {
+ LLFolderViewModelItem* listener = (*set_iter)->getViewModelItem();
+ if(listener && listener->isClipboardPasteable())
+ {
+ listener->pasteFromClipboard();
+ }
+ }
+ }
+ mSearchString.clear();
+}
+
+// public rename functionality - can only start the process
+void LLFolderView::startRenamingSelectedItem( void )
+{
+ // make sure selection is visible
+ scrollToShowSelection();
+
+ S32 count = mSelectedItems.size();
+ LLFolderViewItem* item = NULL;
+ if(count > 0)
+ {
+ item = mSelectedItems.front();
+ }
+ if(getVisible() && getEnabled() && (count == 1) && item && item->getViewModelItem() &&
+ item->getViewModelItem()->isItemRenameable())
+ {
+ mRenameItem = item;
+
+ updateRenamerPosition();
+
+
+ mRenamer->setText(item->getName());
+ mRenamer->selectAll();
+ mRenamer->setVisible( TRUE );
+ // set focus will fail unless item is visible
+ mRenamer->setFocus( TRUE );
+ mRenamer->setTopLostCallback(boost::bind(&LLFolderView::onRenamerLost, this));
+ LLUI::addPopup(mRenamer);
+ }
+}
+
+BOOL LLFolderView::handleKeyHere( KEY key, MASK mask )
+{
+ BOOL handled = FALSE;
+
+ // SL-51858: Key presses are not being passed to the Popup menu.
+ // A proper fix is non-trivial so instead just close the menu.
+ LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get();
+ if (menu && menu->isOpen())
+ {
+ LLMenuGL::sMenuContainer->hideMenus();
+ }
+
+ switch( key )
+ {
+ case KEY_F2:
+ mSearchString.clear();
+ startRenamingSelectedItem();
+ handled = TRUE;
+ break;
+
+ case KEY_RETURN:
+ if (mask == MASK_NONE)
+ {
+ if( mRenameItem && mRenamer->getVisible() )
+ {
+ finishRenamingItem();
+ mSearchString.clear();
+ handled = TRUE;
+ }
+ }
+ break;
+
+ case KEY_ESCAPE:
+ if( mRenameItem && mRenamer->getVisible() )
+ {
+ closeRenamer();
+ handled = TRUE;
+ }
+ mSearchString.clear();
+ break;
+
+ case KEY_PAGE_UP:
+ mSearchString.clear();
+ if (mScrollContainer)
+ {
+ mScrollContainer->pageUp(30);
+ }
+ handled = TRUE;
+ break;
+
+ case KEY_PAGE_DOWN:
+ mSearchString.clear();
+ if (mScrollContainer)
+ {
+ mScrollContainer->pageDown(30);
+ }
+ handled = TRUE;
+ break;
+
+ case KEY_HOME:
+ mSearchString.clear();
+ if (mScrollContainer)
+ {
+ mScrollContainer->goToTop();
+ }
+ handled = TRUE;
+ break;
+
+ case KEY_END:
+ mSearchString.clear();
+ if (mScrollContainer)
+ {
+ mScrollContainer->goToBottom();
+ }
+ break;
+
+ case KEY_DOWN:
+ if((mSelectedItems.size() > 0) && mScrollContainer)
+ {
+ LLFolderViewItem* last_selected = getCurSelectedItem();
+
+ if (!mKeyboardSelection)
+ {
+ setSelection(last_selected, FALSE, TRUE);
+ mKeyboardSelection = TRUE;
+ }
+
+ LLFolderViewItem* next = NULL;
+ if (mask & MASK_SHIFT)
+ {
+ // don't shift select down to children of folders (they are implicitly selected through parent)
+ next = last_selected->getNextOpenNode(FALSE);
+ if (next)
+ {
+ if (next->isSelected())
+ {
+ // shrink selection
+ changeSelection(last_selected, FALSE);
+ }
+ else if (last_selected->getParentFolder() == next->getParentFolder())
+ {
+ // grow selection
+ changeSelection(next, TRUE);
+ }
+ }
+ }
+ else
+ {
+ next = last_selected->getNextOpenNode();
+ if( next )
+ {
+ if (next == last_selected)
+ {
+ //special case for LLAccordionCtrl
+ if(notifyParent(LLSD().with("action","select_next")) > 0 )//message was processed
+ {
+ clearSelection();
+ return TRUE;
+ }
+ return FALSE;
+ }
+ setSelection( next, FALSE, TRUE );
+ }
+ else
+ {
+ //special case for LLAccordionCtrl
+ if(notifyParent(LLSD().with("action","select_next")) > 0 )//message was processed
+ {
+ clearSelection();
+ return TRUE;
+ }
+ return FALSE;
+ }
+ }
+ scrollToShowSelection();
+ mSearchString.clear();
+ handled = TRUE;
+ }
+ break;
+
+ case KEY_UP:
+ if((mSelectedItems.size() > 0) && mScrollContainer)
+ {
+ LLFolderViewItem* last_selected = mSelectedItems.back();
+
+ if (!mKeyboardSelection)
+ {
+ setSelection(last_selected, FALSE, TRUE);
+ mKeyboardSelection = TRUE;
+ }
+
+ LLFolderViewItem* prev = NULL;
+ if (mask & MASK_SHIFT)
+ {
+ // don't shift select down to children of folders (they are implicitly selected through parent)
+ prev = last_selected->getPreviousOpenNode(FALSE);
+ if (prev)
+ {
+ if (prev->isSelected())
+ {
+ // shrink selection
+ changeSelection(last_selected, FALSE);
+ }
+ else if (last_selected->getParentFolder() == prev->getParentFolder())
+ {
+ // grow selection
+ changeSelection(prev, TRUE);
+ }
+ }
+ }
+ else
+ {
+ prev = last_selected->getPreviousOpenNode();
+ if( prev )
+ {
+ if (prev == this)
+ {
+ // If case we are in accordion tab notify parent to go to the previous accordion
+ if(notifyParent(LLSD().with("action","select_prev")) > 0 )//message was processed
+ {
+ clearSelection();
+ return TRUE;
+ }
+
+ return FALSE;
+ }
+ setSelection( prev, FALSE, TRUE );
+ }
+ }
+ scrollToShowSelection();
+ mSearchString.clear();
+
+ handled = TRUE;
+ }
+ break;
+
+ case KEY_RIGHT:
+ if(mSelectedItems.size())
+ {
+ LLFolderViewItem* last_selected = getCurSelectedItem();
+ last_selected->setOpen( TRUE );
+ mSearchString.clear();
+ handled = TRUE;
+ }
+ break;
+
+ case KEY_LEFT:
+ if(mSelectedItems.size())
+ {
+ LLFolderViewItem* last_selected = getCurSelectedItem();
+ LLFolderViewItem* parent_folder = last_selected->getParentFolder();
+ if (!last_selected->isOpen() && parent_folder && parent_folder->getParentFolder())
+ {
+ setSelection(parent_folder, FALSE, TRUE);
+ }
+ else
+ {
+ last_selected->setOpen( FALSE );
+ }
+ mSearchString.clear();
+ scrollToShowSelection();
+ handled = TRUE;
+ }
+ break;
+ }
+
+ return handled;
+}
+
+
+BOOL LLFolderView::handleUnicodeCharHere(llwchar uni_char)
+{
+ if ((uni_char < 0x20) || (uni_char == 0x7F)) // Control character or DEL
+ {
+ return FALSE;
+ }
+
+ if (uni_char > 0x7f)
+ {
+ llwarns << "LLFolderView::handleUnicodeCharHere - Don't handle non-ascii yet, aborting" << llendl;
+ return FALSE;
+ }
+
+ BOOL handled = FALSE;
+ if (mParentPanel->hasFocus())
+ {
+ // SL-51858: Key presses are not being passed to the Popup menu.
+ // A proper fix is non-trivial so instead just close the menu.
+ LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get();
+ if (menu && menu->isOpen())
+ {
+ LLMenuGL::sMenuContainer->hideMenus();
+ }
+
+ //do text search
+ if (mSearchTimer.getElapsedTimeF32() > LLUI::sSettingGroups["config"]->getF32("TypeAheadTimeout"))
+ {
+ mSearchString.clear();
+ }
+ mSearchTimer.reset();
+ if (mSearchString.size() < 128)
+ {
+ mSearchString += uni_char;
+ }
+ search(getCurSelectedItem(), mSearchString, FALSE);
+
+ handled = TRUE;
+ }
+
+ return handled;
+}
+
+
+BOOL LLFolderView::handleMouseDown( S32 x, S32 y, MASK mask )
+{
+ mKeyboardSelection = FALSE;
+ mSearchString.clear();
+
+ mParentPanel->setFocus(TRUE);
+
+ LLEditMenuHandler::gEditMenuHandler = this;
+
+ return LLView::handleMouseDown( x, y, mask );
+}
+
+BOOL LLFolderView::search(LLFolderViewItem* first_item, const std::string &search_string, BOOL backward)
+{
+ // get first selected item
+ LLFolderViewItem* search_item = first_item;
+
+ // make sure search string is upper case
+ std::string upper_case_string = search_string;
+ LLStringUtil::toUpper(upper_case_string);
+
+ // if nothing selected, select first item in folder
+ if (!search_item)
+ {
+ // start from first item
+ search_item = getNextFromChild(NULL);
+ }
+
+ // search over all open nodes for first substring match (with wrapping)
+ BOOL found = FALSE;
+ LLFolderViewItem* original_search_item = search_item;
+ do
+ {
+ // wrap at end
+ if (!search_item)
+ {
+ if (backward)
+ {
+ search_item = getPreviousFromChild(NULL);
+ }
+ else
+ {
+ search_item = getNextFromChild(NULL);
+ }
+ if (!search_item || search_item == original_search_item)
+ {
+ break;
+ }
+ }
+
+ const std::string current_item_label(search_item->getViewModelItem()->getSearchableName());
+ S32 search_string_length = llmin(upper_case_string.size(), current_item_label.size());
+ if (!current_item_label.compare(0, search_string_length, upper_case_string))
+ {
+ found = TRUE;
+ break;
+ }
+ if (backward)
+ {
+ search_item = search_item->getPreviousOpenNode();
+ }
+ else
+ {
+ search_item = search_item->getNextOpenNode();
+ }
+
+ } while(search_item != original_search_item);
+
+
+ if (found)
+ {
+ setSelection(search_item, FALSE, TRUE);
+ scrollToShowSelection();
+ }
+
+ return found;
+}
+
+BOOL LLFolderView::handleDoubleClick( S32 x, S32 y, MASK mask )
+{
+ // skip LLFolderViewFolder::handleDoubleClick()
+ return LLView::handleDoubleClick( x, y, mask );
+}
+
+BOOL LLFolderView::handleRightMouseDown( S32 x, S32 y, MASK mask )
+{
+ // all user operations move keyboard focus to inventory
+ // this way, we know when to stop auto-updating a search
+ mParentPanel->setFocus(TRUE);
+
+ BOOL handled = childrenHandleRightMouseDown(x, y, mask) != NULL;
+ S32 count = mSelectedItems.size();
+ LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get();
+ if ( handled
+ && ( count > 0 && (hasVisibleChildren()) ) // show menu only if selected items are visible
+ && menu )
+ {
+ if (mCallbackRegistrar)
+ {
+ mCallbackRegistrar->pushScope();
+ }
+
+ updateMenuOptions(menu);
+
+ menu->updateParent(LLMenuGL::sMenuContainer);
+ LLMenuGL::showPopup(this, menu, x, y);
+ if (mCallbackRegistrar)
+ {
+ mCallbackRegistrar->popScope();
+ }
+ }
+ else
+ {
+ if (menu && menu->getVisible())
+ {
+ menu->setVisible(FALSE);
+ }
+ setSelection(NULL, FALSE, TRUE);
+ }
+ return handled;
+}
+
+// Add "--no options--" if the menu is completely blank.
+BOOL LLFolderView::addNoOptions(LLMenuGL* menu) const
+{
+ const std::string nooptions_str = "--no options--";
+ LLView *nooptions_item = NULL;
+
+ const LLView::child_list_t *list = menu->getChildList();
+ for (LLView::child_list_t::const_iterator itor = list->begin();
+ itor != list->end();
+ ++itor)
+ {
+ LLView *menu_item = (*itor);
+ if (menu_item->getVisible())
+ {
+ return FALSE;
+ }
+ std::string name = menu_item->getName();
+ if (menu_item->getName() == nooptions_str)
+ {
+ nooptions_item = menu_item;
+ }
+ }
+ if (nooptions_item)
+ {
+ nooptions_item->setVisible(TRUE);
+ nooptions_item->setEnabled(FALSE);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+BOOL LLFolderView::handleHover( S32 x, S32 y, MASK mask )
+{
+ return LLView::handleHover( x, y, mask );
+}
+
+BOOL LLFolderView::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
+ EDragAndDropType cargo_type,
+ void* cargo_data,
+ EAcceptance* accept,
+ std::string& tooltip_msg)
+{
+ mDragAndDropThisFrame = TRUE;
+ // have children handle it first
+ BOOL handled = LLView::handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data,
+ accept, tooltip_msg);
+
+ // when drop is not handled by child, it should be handled
+ // by the folder which is the hierarchy root.
+ if (!handled)
+ {
+ handled = LLFolderViewFolder::handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
+ }
+
+ return handled;
+}
+
+void LLFolderView::deleteAllChildren()
+{
+ closeRenamer();
+ if (mPopupMenuHandle.get()) mPopupMenuHandle.get()->die();
+ mPopupMenuHandle = LLHandle<LLView>();
+ mScrollContainer = NULL;
+ mRenameItem = NULL;
+ mRenamer = NULL;
+ mStatusTextBox = NULL;
+
+ clearSelection();
+ LLView::deleteAllChildren();
+}
+
+void LLFolderView::scrollToShowSelection()
+{
+ if ( mSelectedItems.size() )
+ {
+ mNeedsScroll = TRUE;
+ }
+}
+
+// If the parent is scroll container, scroll it to make the selection
+// is maximally visible.
+void LLFolderView::scrollToShowItem(LLFolderViewItem* item, const LLRect& constraint_rect)
+{
+ if (!mScrollContainer) return;
+
+ // don't scroll to items when mouse is being used to scroll/drag and drop
+ if (gFocusMgr.childHasMouseCapture(mScrollContainer))
+ {
+ mNeedsScroll = FALSE;
+ return;
+ }
+
+ // if item exists and is in visible portion of parent folder...
+ if(item)
+ {
+ LLRect local_rect = item->getLocalRect();
+ S32 icon_height = mIcon.isNull() ? 0 : mIcon->getHeight();
+ S32 label_height = getLabelFontForStyle(mLabelStyle)->getLineHeight();
+ // when navigating with keyboard, only move top of opened folder on screen, otherwise show whole folder
+ S32 max_height_to_show = item->isOpen() && mScrollContainer->hasFocus() ? (llmax( icon_height, label_height ) + item->getIconPad()) : local_rect.getHeight();
+
+ // get portion of item that we want to see...
+ LLRect item_local_rect = LLRect(item->getIndentation(),
+ local_rect.getHeight(),
+ //+40 is supposed to include few first characters
+ llmin(item->getLabelXPos() - item->getIndentation() + 40, local_rect.getWidth()),
+ llmax(0, local_rect.getHeight() - max_height_to_show));
+
+ LLRect item_doc_rect;
+
+ item->localRectToOtherView(item_local_rect, &item_doc_rect, this);
+
+ mScrollContainer->scrollToShowRect( item_doc_rect, constraint_rect );
+
+ }
+}
+
+LLRect LLFolderView::getVisibleRect()
+{
+ S32 visible_height = (mScrollContainer ? mScrollContainer->getRect().getHeight() : 0);
+ S32 visible_width = (mScrollContainer ? mScrollContainer->getRect().getWidth() : 0);
+ LLRect visible_rect;
+ visible_rect.setLeftTopAndSize(-getRect().mLeft, visible_height - getRect().mBottom, visible_width, visible_height);
+ return visible_rect;
+}
+
+BOOL LLFolderView::getShowSelectionContext()
+{
+ if (mShowSelectionContext)
+ {
+ return TRUE;
+ }
+ LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get();
+ if (menu && menu->getVisible())
+ {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void LLFolderView::setShowSingleSelection(BOOL show)
+{
+ if (show != mShowSingleSelection)
+ {
+ mMultiSelectionFadeTimer.reset();
+ mShowSingleSelection = show;
+ }
+}
+
+static LLFastTimer::DeclareTimer FTM_AUTO_SELECT("Open and Select");
+static LLFastTimer::DeclareTimer FTM_INVENTORY("Inventory");
+
+// Main idle routine
+void LLFolderView::update()
+{
+ // If this is associated with the user's inventory, don't do anything
+ // until that inventory is loaded up.
+ LLFastTimer t2(FTM_INVENTORY);
+
+ if (getFolderViewModel()->getFilter().isModified() && getFolderViewModel()->getFilter().isNotDefault())
+ {
+ mNeedsAutoSelect = TRUE;
+ }
+
+ // Filter to determine visibility before arranging
+ filter(getFolderViewModel()->getFilter());
+
+ // Clear the modified setting on the filter only if the filter finished after running the filter process
+ // Note: if the filter count has timed out, that means the filter halted before completing the entire set of items
+ if (getFolderViewModel()->getFilter().isModified() && (!getFolderViewModel()->getFilter().isTimedOut()))
+ {
+ getFolderViewModel()->getFilter().clearModified();
+ }
+
+ // automatically show matching items, and select first one if we had a selection
+ if (mNeedsAutoSelect)
+ {
+ LLFastTimer t3(FTM_AUTO_SELECT);
+ // select new item only if a filtered item not currently selected
+ LLFolderViewItem* selected_itemp = mSelectedItems.empty() ? NULL : mSelectedItems.back();
+ if (!mAutoSelectOverride && (!selected_itemp || !selected_itemp->getViewModelItem()->potentiallyVisible()))
+ {
+ // these are named variables to get around gcc not binding non-const references to rvalues
+ // and functor application is inherently non-const to allow for stateful functors
+ LLSelectFirstFilteredItem functor;
+ applyFunctorRecursively(functor);
+ }
+
+ // Open filtered folders for folder views with mAutoSelectOverride=TRUE.
+ // Used by LLPlacesFolderView.
+ if (getFolderViewModel()->getFilter().showAllResults())
+ {
+ // these are named variables to get around gcc not binding non-const references to rvalues
+ // and functor application is inherently non-const to allow for stateful functors
+ LLOpenFilteredFolders functor;
+ applyFunctorRecursively(functor);
+ }
+
+ scrollToShowSelection();
+ }
+
+ BOOL filter_finished = getViewModelItem()->passedFilter()
+ && mViewModel->contentsReady();
+ if (filter_finished
+ || gFocusMgr.childHasKeyboardFocus(mParentPanel)
+ || gFocusMgr.childHasMouseCapture(mParentPanel))
+ {
+ // finishing the filter process, giving focus to the folder view, or dragging the scrollbar all stop the auto select process
+ mNeedsAutoSelect = FALSE;
+ }
+
+ BOOL is_visible = isInVisibleChain();
+
+ //Puts folders/items in proper positions
+ // arrange() takes the model filter flag into account and call sort() if necessary (CHUI-849)
+ // It also handles the open/close folder animation
+ if ( is_visible )
+ {
+ sanitizeSelection();
+ if( needsArrange() )
+ {
+ S32 height = 0;
+ S32 width = 0;
+ S32 total_height = arrange( &width, &height );
+ notifyParent(LLSD().with("action", "size_changes").with("height", total_height));
+ }
+ }
+
+ // during filtering process, try to pin selected item's location on screen
+ // this will happen when searching your inventory and when new items arrive
+ if (!filter_finished)
+ {
+ // calculate rectangle to pin item to at start of animated rearrange
+ if (!mPinningSelectedItem && !mSelectedItems.empty())
+ {
+ // lets pin it!
+ mPinningSelectedItem = TRUE;
+
+ //Computes visible area
+ const LLRect visible_content_rect = (mScrollContainer ? mScrollContainer->getVisibleContentRect() : LLRect());
+ LLFolderViewItem* selected_item = mSelectedItems.back();
+
+ //Computes location of selected content, content outside visible area will be scrolled to using below code
+ LLRect item_rect;
+ selected_item->localRectToOtherView(selected_item->getLocalRect(), &item_rect, this);
+
+ //Computes intersected region of the selected content and visible area
+ LLRect overlap_rect(item_rect);
+ overlap_rect.intersectWith(visible_content_rect);
+
+ //Don't scroll when the selected content exists within the visible area
+ if (overlap_rect.getHeight() >= selected_item->getItemHeight())
+ {
+ // then attempt to keep it in same place on screen
+ mScrollConstraintRect = item_rect;
+ mScrollConstraintRect.translate(-visible_content_rect.mLeft, -visible_content_rect.mBottom);
+ }
+ //Scroll because the selected content is outside the visible area
+ else
+ {
+ // otherwise we just want it onscreen somewhere
+ LLRect content_rect = (mScrollContainer ? mScrollContainer->getContentWindowRect() : LLRect());
+ mScrollConstraintRect.setOriginAndSize(0, 0, content_rect.getWidth(), content_rect.getHeight());
+ }
+ }
+ }
+ else
+ {
+ // stop pinning selected item after folders stop rearranging
+ if (!needsArrange())
+ {
+ mPinningSelectedItem = FALSE;
+ }
+ }
+
+ LLRect constraint_rect;
+ if (mPinningSelectedItem)
+ {
+ // use last known constraint rect for pinned item
+ constraint_rect = mScrollConstraintRect;
+ }
+ else
+ {
+ // during normal use (page up/page down, etc), just try to fit item on screen
+ LLRect content_rect = (mScrollContainer ? mScrollContainer->getContentWindowRect() : LLRect());
+ constraint_rect.setOriginAndSize(0, 0, content_rect.getWidth(), content_rect.getHeight());
+ }
+
+ if (mSelectedItems.size() && mNeedsScroll)
+ {
+ scrollToShowItem(mSelectedItems.back(), constraint_rect);
+ // continue scrolling until animated layout change is done
+ if (filter_finished
+ && (!needsArrange() || !is_visible))
+ {
+ mNeedsScroll = FALSE;
+ }
+ }
+
+ if (mSignalSelectCallback)
+ {
+ //RN: we use keyboard focus as a proxy for user-explicit actions
+ BOOL take_keyboard_focus = (mSignalSelectCallback == SIGNAL_KEYBOARD_FOCUS);
+ mSelectSignal(mSelectedItems, take_keyboard_focus);
+ }
+ mSignalSelectCallback = FALSE;
+}
+
+void LLFolderView::dumpSelectionInformation()
+{
+ llinfos << "LLFolderView::dumpSelectionInformation()" << llendl;
+ llinfos << "****************************************" << llendl;
+ selected_items_t::iterator item_it;
+ for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it)
+ {
+ llinfos << " " << (*item_it)->getName() << llendl;
+ }
+ llinfos << "****************************************" << llendl;
+}
+
+void LLFolderView::updateRenamerPosition()
+{
+ if(mRenameItem)
+ {
+ // See also LLFolderViewItem::draw()
+ S32 x = mRenameItem->getLabelXPos();
+ S32 y = mRenameItem->getRect().getHeight() - mRenameItem->getItemHeight() - RENAME_HEIGHT_PAD;
+ mRenameItem->localPointToScreen( x, y, &x, &y );
+ screenPointToLocal( x, y, &x, &y );
+ mRenamer->setOrigin( x, y );
+
+ LLRect scroller_rect(0, 0, (S32)LLUI::getWindowSize().mV[VX], 0);
+ if (mScrollContainer)
+ {
+ scroller_rect = mScrollContainer->getContentWindowRect();
+ }
+
+ S32 width = llmax(llmin(mRenameItem->getRect().getWidth() - x, scroller_rect.getWidth() - x - getRect().mLeft), MINIMUM_RENAMER_WIDTH);
+ S32 height = mRenameItem->getItemHeight() - RENAME_HEIGHT_PAD;
+ mRenamer->reshape( width, height, TRUE );
+ }
+}
+
+// Update visibility and availability (i.e. enabled/disabled) of context menu items.
+void LLFolderView::updateMenuOptions(LLMenuGL* menu)
+{
+ const LLView::child_list_t *list = menu->getChildList();
+
+ LLView::child_list_t::const_iterator menu_itor;
+ for (menu_itor = list->begin(); menu_itor != list->end(); ++menu_itor)
+ {
+ (*menu_itor)->setVisible(FALSE);
+ (*menu_itor)->pushVisible(TRUE);
+ (*menu_itor)->setEnabled(TRUE);
+ }
+
+ // Successively filter out invalid options
+
+ U32 multi_select_flag = (mSelectedItems.size() > 1 ? ITEM_IN_MULTI_SELECTION : 0x0);
+ U32 flags = multi_select_flag | FIRST_SELECTED_ITEM;
+ for (selected_items_t::iterator item_itor = mSelectedItems.begin();
+ item_itor != mSelectedItems.end();
+ ++item_itor)
+ {
+ LLFolderViewItem* selected_item = (*item_itor);
+ selected_item->buildContextMenu(*menu, flags);
+ flags = multi_select_flag;
+ }
+
+ addNoOptions(menu);
+}
+
+// Refresh the context menu (that is already shown).
+void LLFolderView::updateMenu()
+{
+ LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get();
+ if (menu && menu->getVisible())
+ {
+ updateMenuOptions(menu);
+ menu->needsArrange(); // update menu height if needed
+ }
+}
+
+bool LLFolderView::selectFirstItem()
+{
+ for (folders_t::iterator iter = mFolders.begin();
+ iter != mFolders.end();++iter)
+ {
+ LLFolderViewFolder* folder = (*iter );
+ if (folder->getVisible())
+ {
+ LLFolderViewItem* itemp = folder->getNextFromChild(0,true);
+ if(itemp)
+ setSelection(itemp,FALSE,TRUE);
+ return true;
+ }
+
+ }
+ for(items_t::iterator iit = mItems.begin();
+ iit != mItems.end(); ++iit)
+ {
+ LLFolderViewItem* itemp = (*iit);
+ if (itemp->getVisible())
+ {
+ setSelection(itemp,FALSE,TRUE);
+ return true;
+ }
+ }
+ return false;
+}
+bool LLFolderView::selectLastItem()
+{
+ for(items_t::reverse_iterator iit = mItems.rbegin();
+ iit != mItems.rend(); ++iit)
+ {
+ LLFolderViewItem* itemp = (*iit);
+ if (itemp->getVisible())
+ {
+ setSelection(itemp,FALSE,TRUE);
+ return true;
+ }
+ }
+ for (folders_t::reverse_iterator iter = mFolders.rbegin();
+ iter != mFolders.rend();++iter)
+ {
+ LLFolderViewFolder* folder = (*iter);
+ if (folder->getVisible())
+ {
+ LLFolderViewItem* itemp = folder->getPreviousFromChild(0,true);
+ if(itemp)
+ setSelection(itemp,FALSE,TRUE);
+ return true;
+ }
+ }
+ return false;
+}
+
+
+S32 LLFolderView::notify(const LLSD& info)
+{
+ if(info.has("action"))
+ {
+ std::string str_action = info["action"];
+ if(str_action == "select_first")
+ {
+ setFocus(true);
+ selectFirstItem();
+ scrollToShowSelection();
+ return 1;
+
+ }
+ else if(str_action == "select_last")
+ {
+ setFocus(true);
+ selectLastItem();
+ scrollToShowSelection();
+ return 1;
+ }
+ }
+ return 0;
+}
+
+
+///----------------------------------------------------------------------------
+/// Local function definitions
+///----------------------------------------------------------------------------
+
+void LLFolderView::onRenamerLost()
+{
+ if (mRenamer && mRenamer->getVisible())
+ {
+ mRenamer->setVisible(FALSE);
+
+ // will commit current name (which could be same as original name)
+ mRenamer->setFocus(FALSE);
+ }
+
+ if( mRenameItem )
+ {
+ setSelection( mRenameItem, TRUE );
+ mRenameItem = NULL;
+ }
+}
+
+LLFolderViewItem* LLFolderView::getNextUnselectedItem()
+{
+ LLFolderViewItem* last_item = *mSelectedItems.rbegin();
+ LLFolderViewItem* new_selection = last_item->getNextOpenNode(FALSE);
+ while(new_selection && new_selection->isSelected())
+ {
+ new_selection = new_selection->getNextOpenNode(FALSE);
+ }
+ if (!new_selection)
+ {
+ new_selection = last_item->getPreviousOpenNode(FALSE);
+ while (new_selection && (new_selection->isInSelection()))
+ {
+ new_selection = new_selection->getPreviousOpenNode(FALSE);
+ }
+ }
+ return new_selection;
+}
+
+S32 LLFolderView::getItemHeight()
+{
+ if(!hasVisibleChildren())
+{
+ //We need to display status textbox, let's reserve some place for it
+ return llmax(0, mStatusTextBox->getTextPixelHeight());
+}
+ return 0;
+}
diff --git a/indra/llui/llfolderview.h b/indra/llui/llfolderview.h
new file mode 100755
index 0000000000..11fccdace4
--- /dev/null
+++ b/indra/llui/llfolderview.h
@@ -0,0 +1,399 @@
+/**
+ * @file llfolderview.h
+ * @brief Definition of the folder view collection of classes.
+ *
+ * $LicenseInfo:firstyear=2001&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$
+ */
+
+/**
+ *
+ * The folder view collection of classes provides an interface for
+ * making a 'folder view' similar to the way the a single pane file
+ * folder interface works.
+ *
+ */
+
+#ifndef LL_LLFOLDERVIEW_H
+#define LL_LLFOLDERVIEW_H
+
+#include "llfolderviewitem.h" // because LLFolderView is-a LLFolderViewFolder
+
+#include "lluictrl.h"
+#include "v4color.h"
+#include "stdenums.h"
+#include "lldepthstack.h"
+#include "lleditmenuhandler.h"
+#include "llfontgl.h"
+#include "llscrollcontainer.h"
+
+class LLFolderViewModelInterface;
+class LLFolderViewFolder;
+class LLFolderViewItem;
+class LLFolderViewFilter;
+class LLPanel;
+class LLLineEditor;
+class LLMenuGL;
+class LLUICtrl;
+class LLTextBox;
+
+/**
+ * Class LLFolderViewScrollContainer
+ *
+ * A scroll container which provides the information about the height
+ * of currently displayed folder view contents.
+ * Used for updating vertical scroll bar visibility in inventory panel.
+ * See LLScrollContainer::calcVisibleSize().
+ */
+class LLFolderViewScrollContainer : public LLScrollContainer
+{
+public:
+ /*virtual*/ ~LLFolderViewScrollContainer() {};
+ /*virtual*/ const LLRect getScrolledViewRect() const;
+
+protected:
+ LLFolderViewScrollContainer(const LLScrollContainer::Params& p);
+ friend class LLUICtrlFactory;
+};
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Class LLFolderView
+//
+// The LLFolderView represents the root level folder view object.
+// It manages the screen region of the folder view.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+class LLFolderView : public LLFolderViewFolder, public LLEditMenuHandler
+{
+public:
+ struct Params : public LLInitParam::Block<Params, LLFolderViewFolder::Params>
+ {
+ Mandatory<LLPanel*> parent_panel;
+ Optional<std::string> title;
+ Optional<bool> use_label_suffix,
+ allow_multiselect,
+ show_empty_message,
+ use_ellipses,
+ show_item_link_overlays;
+ Mandatory<LLFolderViewModelInterface*> view_model;
+ Mandatory<std::string> options_menu;
+
+
+ Params();
+ };
+
+ friend class LLFolderViewScrollContainer;
+ typedef std::deque<LLFolderViewItem*> selected_items_t;
+
+ LLFolderView(const Params&);
+ virtual ~LLFolderView( void );
+
+ virtual BOOL canFocusChildren() const;
+
+ virtual const LLFolderView* getRoot() const { return this; }
+ virtual LLFolderView* getRoot() { return this; }
+
+ LLFolderViewModelInterface* getFolderViewModel() { return mViewModel; }
+ const LLFolderViewModelInterface* getFolderViewModel() const { return mViewModel; }
+
+ typedef boost::signals2::signal<void (const std::deque<LLFolderViewItem*>& items, BOOL user_action)> signal_t;
+ void setSelectCallback(const signal_t::slot_type& cb) { mSelectSignal.connect(cb); }
+ void setReshapeCallback(const signal_t::slot_type& cb) { mReshapeSignal.connect(cb); }
+
+ bool getAllowMultiSelect() { return mAllowMultiSelect; }
+
+ // Close all folders in the view
+ void closeAllFolders();
+ void openTopLevelFolders();
+
+ virtual void addFolder( LLFolderViewFolder* folder);
+
+ // Find width and height of this object and its children. Also
+ // makes sure that this view and its children are the right size.
+ virtual S32 arrange( S32* width, S32* height );
+ virtual S32 getItemHeight();
+
+ void arrangeAll() { mArrangeGeneration++; }
+ S32 getArrangeGeneration() { return mArrangeGeneration; }
+
+ // applies filters to control visibility of items
+ virtual void filter( LLFolderViewFilter& filter);
+
+ // Get the last selected item
+ virtual LLFolderViewItem* getCurSelectedItem( void );
+ selected_items_t& getSelectedItems( void );
+
+ // Record the selected item and pass it down the hierarchy.
+ virtual BOOL setSelection(LLFolderViewItem* selection, BOOL openitem,
+ BOOL take_keyboard_focus = TRUE);
+
+ // This method is used to toggle the selection of an item. Walks
+ // children, and keeps track of selected objects.
+ virtual BOOL changeSelection(LLFolderViewItem* selection, BOOL selected);
+
+ virtual std::set<LLFolderViewItem*> getSelectionList() const;
+
+ // Make sure if ancestor is selected, descendants are not
+ void sanitizeSelection();
+ virtual void clearSelection();
+ void addToSelectionList(LLFolderViewItem* item);
+ void removeFromSelectionList(LLFolderViewItem* item);
+
+ bool startDrag();
+ void setDragAndDropThisFrame() { mDragAndDropThisFrame = TRUE; }
+ void setDraggingOverItem(LLFolderViewItem* item) { mDraggingOverItem = item; }
+ LLFolderViewItem* getDraggingOverItem() { return mDraggingOverItem; }
+
+ // Deletion functionality
+ void removeSelectedItems();
+
+ void autoOpenItem(LLFolderViewFolder* item);
+ void closeAutoOpenedFolders();
+ BOOL autoOpenTest(LLFolderViewFolder* item);
+ BOOL isOpen() const { return TRUE; } // root folder always open
+
+ // Copy & paste
+ virtual BOOL canCopy() const;
+ virtual void copy();
+
+ virtual BOOL canCut() const;
+ virtual void cut();
+
+ virtual BOOL canPaste() const;
+ virtual void paste();
+
+ LLFolderViewItem* getNextUnselectedItem();
+
+ // Public rename functionality - can only start the process
+ void startRenamingSelectedItem( void );
+
+ // LLView functionality
+ ///*virtual*/ BOOL handleKey( KEY key, MASK mask, BOOL called_from_parent );
+ /*virtual*/ BOOL handleKeyHere( KEY key, MASK mask );
+ /*virtual*/ BOOL handleUnicodeCharHere(llwchar uni_char);
+ /*virtual*/ BOOL handleMouseDown( S32 x, S32 y, MASK mask );
+ /*virtual*/ BOOL handleDoubleClick( S32 x, S32 y, MASK mask );
+ /*virtual*/ BOOL handleRightMouseDown( S32 x, S32 y, MASK mask );
+ /*virtual*/ BOOL handleHover( S32 x, S32 y, MASK mask );
+ /*virtual*/ BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
+ EDragAndDropType cargo_type,
+ void* cargo_data,
+ EAcceptance* accept,
+ std::string& tooltip_msg);
+ /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
+ /*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask) { setShowSelectionContext(FALSE); }
+ virtual void draw();
+ virtual void deleteAllChildren();
+
+ void scrollToShowSelection();
+ void scrollToShowItem(LLFolderViewItem* item, const LLRect& constraint_rect);
+ void setScrollContainer( LLScrollContainer* parent ) { mScrollContainer = parent; }
+ LLRect getVisibleRect();
+
+ BOOL search(LLFolderViewItem* first_item, const std::string &search_string, BOOL backward);
+ void setShowSelectionContext(BOOL show) { mShowSelectionContext = show; }
+ BOOL getShowSelectionContext();
+ void setShowSingleSelection(BOOL show);
+ BOOL getShowSingleSelection() { return mShowSingleSelection; }
+ F32 getSelectionFadeElapsedTime() { return mMultiSelectionFadeTimer.getElapsedTimeF32(); }
+ bool getUseEllipses() { return mUseEllipses; }
+ S32 getSelectedCount() { return (S32)mSelectedItems.size(); }
+
+ void update(); // needs to be called periodically (e.g. once per frame)
+
+ BOOL needsAutoSelect() { return mNeedsAutoSelect && !mAutoSelectOverride; }
+ BOOL needsAutoRename() { return mNeedsAutoRename; }
+ void setNeedsAutoRename(BOOL val) { mNeedsAutoRename = val; }
+ void setPinningSelectedItem(BOOL val) { mPinningSelectedItem = val; }
+ void setAutoSelectOverride(BOOL val) { mAutoSelectOverride = val; }
+
+ bool showItemLinkOverlays() { return mShowItemLinkOverlays; }
+
+ void setCallbackRegistrar(LLUICtrl::CommitCallbackRegistry::ScopedRegistrar* registrar) { mCallbackRegistrar = registrar; }
+
+ LLPanel* getParentPanel() { return mParentPanel; }
+ // DEBUG only
+ void dumpSelectionInformation();
+
+ virtual S32 notify(const LLSD& info) ;
+
+ bool useLabelSuffix() { return mUseLabelSuffix; }
+ void updateMenu();
+
+private:
+ void updateMenuOptions(LLMenuGL* menu);
+ void updateRenamerPosition();
+
+protected:
+ LLScrollContainer* mScrollContainer; // NULL if this is not a child of a scroll container.
+
+ void commitRename( const LLSD& data );
+ void onRenamerLost();
+
+ void finishRenamingItem( void );
+ void closeRenamer( void );
+
+ bool selectFirstItem();
+ bool selectLastItem();
+
+ BOOL addNoOptions(LLMenuGL* menu) const;
+
+
+protected:
+ LLHandle<LLView> mPopupMenuHandle;
+
+ selected_items_t mSelectedItems;
+ BOOL mKeyboardSelection;
+ BOOL mAllowMultiSelect;
+ BOOL mShowEmptyMessage;
+ BOOL mShowFolderHierarchy;
+
+ // Renaming variables and methods
+ LLFolderViewItem* mRenameItem; // The item currently being renamed
+ LLLineEditor* mRenamer;
+
+ BOOL mNeedsScroll;
+ BOOL mPinningSelectedItem;
+ LLRect mScrollConstraintRect;
+ BOOL mNeedsAutoSelect;
+ BOOL mAutoSelectOverride;
+ BOOL mNeedsAutoRename;
+ bool mUseLabelSuffix;
+ bool mShowItemLinkOverlays;
+
+ LLDepthStack<LLFolderViewFolder> mAutoOpenItems;
+ LLFolderViewFolder* mAutoOpenCandidate;
+ LLFrameTimer mAutoOpenTimer;
+ LLFrameTimer mSearchTimer;
+ std::string mSearchString;
+ BOOL mShowSelectionContext;
+ BOOL mShowSingleSelection;
+ LLFrameTimer mMultiSelectionFadeTimer;
+ S32 mArrangeGeneration;
+
+ signal_t mSelectSignal;
+ signal_t mReshapeSignal;
+ S32 mSignalSelectCallback;
+ S32 mMinWidth;
+ BOOL mDragAndDropThisFrame;
+
+ LLPanel* mParentPanel;
+
+ LLFolderViewModelInterface* mViewModel;
+
+ /**
+ * Is used to determine if we need to cut text In LLFolderViewItem to avoid horizontal scroll.
+ * NOTE: For now it's used only to cut LLFolderViewItem::mLabel text for Landmarks in Places Panel.
+ */
+ bool mUseEllipses; // See EXT-719
+
+ /**
+ * Contains item under mouse pointer while dragging
+ */
+ LLFolderViewItem* mDraggingOverItem; // See EXT-719
+
+ LLUICtrl::CommitCallbackRegistry::ScopedRegistrar* mCallbackRegistrar;
+
+public:
+ static F32 sAutoOpenTime;
+ LLTextBox* mStatusTextBox;
+
+};
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Class LLFolderViewFunctor
+//
+// Simple abstract base class for applying a functor to folders and
+// items in a folder view hierarchy. This is suboptimal for algorithms
+// that only work folders or only work on items, but I'll worry about
+// that later when it's determined to be too slow.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+class LLFolderViewFunctor
+{
+public:
+ virtual ~LLFolderViewFunctor() {}
+ virtual void doFolder(LLFolderViewFolder* folder) = 0;
+ virtual void doItem(LLFolderViewItem* item) = 0;
+};
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Class LLSelectFirstFilteredItem
+//
+// This will select the first *item* found in the hierarchy. If no item can be
+// selected, the first matching folder will.
+// Since doFolder() is done first but we prioritize item selection, we let the
+// first filtered folder set the selection and raise a folder flag.
+// The selection might be overridden by the first filtered item in doItem()
+// which checks an item flag. Since doFolder() checks the item flag too, the first
+// item will still be selected if items were to be done first and folders second.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+class LLSelectFirstFilteredItem : public LLFolderViewFunctor
+{
+public:
+ LLSelectFirstFilteredItem() : mItemSelected(FALSE), mFolderSelected(FALSE) {}
+ virtual ~LLSelectFirstFilteredItem() {}
+ virtual void doFolder(LLFolderViewFolder* folder);
+ virtual void doItem(LLFolderViewItem* item);
+ BOOL wasItemSelected() { return mItemSelected || mFolderSelected; }
+protected:
+ BOOL mItemSelected;
+ BOOL mFolderSelected;
+};
+
+class LLOpenFilteredFolders : public LLFolderViewFunctor
+{
+public:
+ LLOpenFilteredFolders() {}
+ virtual ~LLOpenFilteredFolders() {}
+ virtual void doFolder(LLFolderViewFolder* folder);
+ virtual void doItem(LLFolderViewItem* item);
+};
+
+class LLSaveFolderState : public LLFolderViewFunctor
+{
+public:
+ LLSaveFolderState() : mApply(FALSE) {}
+ virtual ~LLSaveFolderState() {}
+ virtual void doFolder(LLFolderViewFolder* folder);
+ virtual void doItem(LLFolderViewItem* item) {}
+ void setApply(BOOL apply);
+ void clearOpenFolders() { mOpenFolders.clear(); }
+protected:
+ std::set<LLUUID> mOpenFolders;
+ BOOL mApply;
+};
+
+class LLOpenFoldersWithSelection : public LLFolderViewFunctor
+{
+public:
+ LLOpenFoldersWithSelection() {}
+ virtual ~LLOpenFoldersWithSelection() {}
+ virtual void doFolder(LLFolderViewFolder* folder);
+ virtual void doItem(LLFolderViewItem* item);
+};
+
+// Flags for buildContextMenu()
+const U32 SUPPRESS_OPEN_ITEM = 0x1;
+const U32 FIRST_SELECTED_ITEM = 0x2;
+const U32 ITEM_IN_MULTI_SELECTION = 0x4;
+
+#endif // LL_LLFOLDERVIEW_H
diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp
new file mode 100644
index 0000000000..aa2343226c
--- /dev/null
+++ b/indra/llui/llfolderviewitem.cpp
@@ -0,0 +1,2109 @@
+/**
+* @file llfolderviewitem.cpp
+* @brief Items and folders that can appear in a hierarchical folder view
+*
+* $LicenseInfo:firstyear=2001&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 "../newview/llviewerprecompiledheaders.h"
+
+#include "llflashtimer.h"
+
+#include "linden_common.h"
+#include "llfolderviewitem.h"
+#include "llfolderview.h"
+#include "llfolderviewmodel.h"
+#include "llpanel.h"
+#include "llcriticaldamp.h"
+#include "llclipboard.h"
+#include "llfocusmgr.h" // gFocusMgr
+#include "lltrans.h"
+#include "llwindow.h"
+
+///----------------------------------------------------------------------------
+/// Class LLFolderViewItem
+///----------------------------------------------------------------------------
+
+static LLDefaultChildRegistry::Register<LLFolderViewItem> r("folder_view_item");
+
+// statics
+std::map<U8, LLFontGL*> LLFolderViewItem::sFonts; // map of styles to fonts
+
+bool LLFolderViewItem::sColorSetInitialized = false;
+LLUIColor LLFolderViewItem::sFgColor;
+LLUIColor LLFolderViewItem::sHighlightBgColor;
+LLUIColor LLFolderViewItem::sFlashBgColor;
+LLUIColor LLFolderViewItem::sFocusOutlineColor;
+LLUIColor LLFolderViewItem::sMouseOverColor;
+LLUIColor LLFolderViewItem::sFilterBGColor;
+LLUIColor LLFolderViewItem::sFilterTextColor;
+LLUIColor LLFolderViewItem::sSuffixColor;
+LLUIColor LLFolderViewItem::sSearchStatusColor;
+
+// only integers can be initialized in header
+const F32 LLFolderViewItem::FOLDER_CLOSE_TIME_CONSTANT = 0.02f;
+const F32 LLFolderViewItem::FOLDER_OPEN_TIME_CONSTANT = 0.03f;
+
+const LLColor4U DEFAULT_WHITE(255, 255, 255);
+
+
+//static
+LLFontGL* LLFolderViewItem::getLabelFontForStyle(U8 style)
+{
+ LLFontGL* rtn = sFonts[style];
+ if (!rtn) // grab label font with this style, lazily
+ {
+ LLFontDescriptor labelfontdesc("SansSerif", "Small", style);
+ rtn = LLFontGL::getFont(labelfontdesc);
+ if (!rtn)
+ {
+ rtn = LLFontGL::getFontDefault();
+ }
+ sFonts[style] = rtn;
+ }
+ return rtn;
+}
+
+//static
+void LLFolderViewItem::initClass()
+{
+}
+
+//static
+void LLFolderViewItem::cleanupClass()
+{
+ sFonts.clear();
+}
+
+
+// NOTE: Optimize this, we call it a *lot* when opening a large inventory
+LLFolderViewItem::Params::Params()
+: root(),
+ listener(),
+ folder_arrow_image("folder_arrow_image"),
+ folder_indentation("folder_indentation"),
+ selection_image("selection_image"),
+ item_height("item_height"),
+ item_top_pad("item_top_pad"),
+ creation_date(),
+ allow_open("allow_open", true),
+ font_color("font_color"),
+ font_highlight_color("font_highlight_color"),
+ left_pad("left_pad", 0),
+ icon_pad("icon_pad", 0),
+ icon_width("icon_width", 0),
+ text_pad("text_pad", 0),
+ text_pad_right("text_pad_right", 0),
+ arrow_size("arrow_size", 0),
+ max_folder_item_overlap("max_folder_item_overlap", 0)
+{ }
+
+// Default constructor
+LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p)
+: LLView(p),
+ mLabelWidth(0),
+ mLabelWidthDirty(false),
+ mLabelPaddingRight(DEFAULT_LABEL_PADDING_RIGHT),
+ mParentFolder( NULL ),
+ mIsSelected( FALSE ),
+ mIsCurSelection( FALSE ),
+ mSelectPending(FALSE),
+ mLabelStyle( LLFontGL::NORMAL ),
+ mHasVisibleChildren(FALSE),
+ mLocalIndentation(p.folder_indentation),
+ mIndentation(0),
+ mItemHeight(p.item_height),
+ mControlLabelRotation(0.f),
+ mDragAndDropTarget(FALSE),
+ mLabel(p.name),
+ mRoot(p.root),
+ mViewModelItem(p.listener),
+ mIsMouseOverTitle(false),
+ mAllowOpen(p.allow_open),
+ mFontColor(p.font_color),
+ mFontHighlightColor(p.font_highlight_color),
+ mLeftPad(p.left_pad),
+ mIconPad(p.icon_pad),
+ mIconWidth(p.icon_width),
+ mTextPad(p.text_pad),
+ mTextPadRight(p.text_pad_right),
+ mArrowSize(p.arrow_size),
+ mMaxFolderItemOverlap(p.max_folder_item_overlap)
+{
+ if (!sColorSetInitialized)
+ {
+ sFgColor = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE);
+ sHighlightBgColor = LLUIColorTable::instance().getColor("MenuItemHighlightBgColor", DEFAULT_WHITE);
+ sFlashBgColor = LLUIColorTable::instance().getColor("MenuItemFlashBgColor", DEFAULT_WHITE);
+ sFocusOutlineColor = LLUIColorTable::instance().getColor("InventoryFocusOutlineColor", DEFAULT_WHITE);
+ sMouseOverColor = LLUIColorTable::instance().getColor("InventoryMouseOverColor", DEFAULT_WHITE);
+ sFilterBGColor = LLUIColorTable::instance().getColor("FilterBackgroundColor", DEFAULT_WHITE);
+ sFilterTextColor = LLUIColorTable::instance().getColor("FilterTextColor", DEFAULT_WHITE);
+ sSuffixColor = LLUIColorTable::instance().getColor("InventoryItemColor", DEFAULT_WHITE);
+ sSearchStatusColor = LLUIColorTable::instance().getColor("InventorySearchStatusColor", DEFAULT_WHITE);
+ sColorSetInitialized = true;
+ }
+
+ if (mViewModelItem)
+ {
+ mViewModelItem->setFolderViewItem(this);
+ }
+}
+
+// Destroys the object
+LLFolderViewItem::~LLFolderViewItem()
+{
+ mViewModelItem = NULL;
+}
+
+BOOL LLFolderViewItem::postBuild()
+{
+ refresh();
+ return TRUE;
+}
+
+
+LLFolderView* LLFolderViewItem::getRoot()
+{
+ return mRoot;
+}
+
+const LLFolderView* LLFolderViewItem::getRoot() const
+{
+ return mRoot;
+}
+// Returns true if this object is a child (or grandchild, etc.) of potential_ancestor.
+BOOL LLFolderViewItem::isDescendantOf( const LLFolderViewFolder* potential_ancestor )
+{
+ LLFolderViewItem* root = this;
+ while( root->mParentFolder )
+ {
+ if( root->mParentFolder == potential_ancestor )
+ {
+ return TRUE;
+ }
+ root = root->mParentFolder;
+ }
+ return FALSE;
+}
+
+LLFolderViewItem* LLFolderViewItem::getNextOpenNode(BOOL include_children)
+{
+ if (!mParentFolder)
+ {
+ return NULL;
+ }
+
+ LLFolderViewItem* itemp = mParentFolder->getNextFromChild( this, include_children );
+ while(itemp && !itemp->getVisible())
+ {
+ LLFolderViewItem* next_itemp = itemp->mParentFolder->getNextFromChild( itemp, include_children );
+ if (itemp == next_itemp)
+ {
+ // hit last item
+ return itemp->getVisible() ? itemp : this;
+ }
+ itemp = next_itemp;
+ }
+
+ return itemp;
+}
+
+LLFolderViewItem* LLFolderViewItem::getPreviousOpenNode(BOOL include_children)
+{
+ if (!mParentFolder)
+ {
+ return NULL;
+ }
+
+ LLFolderViewItem* itemp = mParentFolder->getPreviousFromChild( this, include_children );
+
+ // Skip over items that are invisible or are hidden from the UI.
+ while(itemp && !itemp->getVisible())
+ {
+ LLFolderViewItem* next_itemp = itemp->mParentFolder->getPreviousFromChild( itemp, include_children );
+ if (itemp == next_itemp)
+ {
+ // hit first item
+ return itemp->getVisible() ? itemp : this;
+ }
+ itemp = next_itemp;
+ }
+
+ return itemp;
+}
+
+BOOL LLFolderViewItem::passedFilter(S32 filter_generation)
+{
+ return getViewModelItem()->passedFilter(filter_generation);
+}
+
+void LLFolderViewItem::refresh()
+{
+ LLFolderViewModelItem& vmi = *getViewModelItem();
+
+ mLabel = vmi.getDisplayName();
+
+ setToolTip(vmi.getName());
+ mIcon = vmi.getIcon();
+ mIconOpen = vmi.getIconOpen();
+ mIconOverlay = vmi.getIconOverlay();
+
+ if (mRoot->useLabelSuffix())
+ {
+ mLabelStyle = vmi.getLabelStyle();
+ mLabelSuffix = vmi.getLabelSuffix();
+ }
+
+ mLabelWidthDirty = true;
+ // Dirty the filter flag of the model from the view (CHUI-849)
+ vmi.dirtyFilter();
+}
+
+// Utility function for LLFolderView
+void LLFolderViewItem::arrangeAndSet(BOOL set_selection,
+ BOOL take_keyboard_focus)
+{
+ LLFolderView* root = getRoot();
+ if (getParentFolder())
+ {
+ getParentFolder()->requestArrange();
+ }
+ if(set_selection)
+ {
+ getRoot()->setSelection(this, TRUE, take_keyboard_focus);
+ if(root)
+ {
+ root->scrollToShowSelection();
+ }
+ }
+}
+
+
+std::set<LLFolderViewItem*> LLFolderViewItem::getSelectionList() const
+{
+ std::set<LLFolderViewItem*> selection;
+ return selection;
+}
+
+// addToFolder() returns TRUE if it succeeds. FALSE otherwise
+void LLFolderViewItem::addToFolder(LLFolderViewFolder* folder)
+{
+ folder->addItem(this);
+
+ // Compute indentation since parent folder changed
+ mIndentation = (getParentFolder())
+ ? getParentFolder()->getIndentation() + mLocalIndentation
+ : 0;
+}
+
+
+// Finds width and height of this object and its children. Also
+// makes sure that this view and its children are the right size.
+S32 LLFolderViewItem::arrange( S32* width, S32* height )
+{
+ // Only indent deeper items in hierarchy
+ mIndentation = (getParentFolder())
+ ? getParentFolder()->getIndentation() + mLocalIndentation
+ : 0;
+ if (mLabelWidthDirty)
+ {
+ mLabelWidth = getLabelXPos() + getLabelFontForStyle(mLabelStyle)->getWidth(mLabel) + getLabelFontForStyle(mLabelStyle)->getWidth(mLabelSuffix) + mLabelPaddingRight;
+ mLabelWidthDirty = false;
+ }
+
+ *width = llmax(*width, mLabelWidth);
+
+ // determine if we need to use ellipses to avoid horizontal scroll. EXT-719
+ bool use_ellipses = getRoot()->getUseEllipses();
+ if (use_ellipses)
+ {
+ // limit to set rect to avoid horizontal scrollbar
+ *width = llmin(*width, getRoot()->getRect().getWidth());
+ }
+ *height = getItemHeight();
+ return *height;
+}
+
+S32 LLFolderViewItem::getItemHeight()
+{
+ return mItemHeight;
+}
+
+S32 LLFolderViewItem::getLabelXPos()
+{
+ return getIndentation() + mArrowSize + mTextPad + mIconWidth + mIconPad;
+}
+
+S32 LLFolderViewItem::getIconPad()
+{
+ return mIconPad;
+}
+
+S32 LLFolderViewItem::getTextPad()
+{
+ return mTextPad;
+}
+
+// *TODO: This can be optimized a lot by simply recording that it is
+// selected in the appropriate places, and assuming that set selection
+// means 'deselect' for a leaf item. Do this optimization after
+// multiple selection is implemented to make sure it all plays nice
+// together.
+BOOL LLFolderViewItem::setSelection(LLFolderViewItem* selection, BOOL openitem, BOOL take_keyboard_focus)
+{
+ if (selection == this && !mIsSelected)
+ {
+ selectItem();
+ }
+ else if (mIsSelected) // Deselect everything else.
+ {
+ deselectItem();
+ }
+ return mIsSelected;
+}
+
+BOOL LLFolderViewItem::changeSelection(LLFolderViewItem* selection, BOOL selected)
+{
+ if (selection == this)
+ {
+ if (mIsSelected)
+ {
+ deselectItem();
+ }
+ else
+ {
+ selectItem();
+ }
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void LLFolderViewItem::deselectItem(void)
+{
+ mIsSelected = FALSE;
+}
+
+void LLFolderViewItem::selectItem(void)
+{
+ if (mIsSelected == FALSE)
+ {
+ mIsSelected = TRUE;
+ getViewModelItem()->selectItem();
+ }
+}
+
+BOOL LLFolderViewItem::isMovable()
+{
+ return getViewModelItem()->isItemMovable();
+}
+
+BOOL LLFolderViewItem::isRemovable()
+{
+ return getViewModelItem()->isItemRemovable();
+}
+
+void LLFolderViewItem::destroyView()
+{
+ getRoot()->removeFromSelectionList(this);
+
+ if (mParentFolder)
+ {
+ // removeView deletes me
+ mParentFolder->extractItem(this);
+ }
+ delete this;
+}
+
+// Call through to the viewed object and return true if it can be
+// removed.
+//BOOL LLFolderViewItem::removeRecursively(BOOL single_item)
+BOOL LLFolderViewItem::remove()
+{
+ if(!isRemovable())
+ {
+ return FALSE;
+ }
+ return getViewModelItem()->removeItem();
+}
+
+// Build an appropriate context menu for the item.
+void LLFolderViewItem::buildContextMenu(LLMenuGL& menu, U32 flags)
+{
+ getViewModelItem()->buildContextMenu(menu, flags);
+}
+
+void LLFolderViewItem::openItem( void )
+{
+ if (mAllowOpen)
+ {
+ getViewModelItem()->openItem();
+ }
+}
+
+void LLFolderViewItem::rename(const std::string& new_name)
+{
+ if( !new_name.empty() )
+ {
+ getViewModelItem()->renameItem(new_name);
+ }
+}
+
+const std::string& LLFolderViewItem::getName( void ) const
+{
+ static const std::string noName("");
+ return getViewModelItem() ? getViewModelItem()->getName() : noName;
+}
+
+// LLView functionality
+BOOL LLFolderViewItem::handleRightMouseDown( S32 x, S32 y, MASK mask )
+{
+ if(!mIsSelected)
+ {
+ getRoot()->setSelection(this, FALSE);
+ }
+ make_ui_sound("UISndClick");
+ return TRUE;
+}
+
+BOOL LLFolderViewItem::handleMouseDown( S32 x, S32 y, MASK mask )
+{
+ if (LLView::childrenHandleMouseDown(x, y, mask))
+ {
+ return TRUE;
+ }
+
+ // No handler needed for focus lost since this class has no
+ // state that depends on it.
+ gFocusMgr.setMouseCapture( this );
+
+ if (!mIsSelected)
+ {
+ if(mask & MASK_CONTROL)
+ {
+ getRoot()->changeSelection(this, !mIsSelected);
+ }
+ else if (mask & MASK_SHIFT)
+ {
+ getParentFolder()->extendSelectionTo(this);
+ }
+ else
+ {
+ getRoot()->setSelection(this, FALSE);
+ }
+ make_ui_sound("UISndClick");
+ }
+ else
+ {
+ // If selected, we reserve the decision of deselecting/reselecting to the mouse up moment.
+ // This is necessary so we maintain selection consistent when starting a drag.
+ mSelectPending = TRUE;
+ }
+
+ mDragStartX = x;
+ mDragStartY = y;
+ return TRUE;
+}
+
+BOOL LLFolderViewItem::handleHover( S32 x, S32 y, MASK mask )
+{
+ static LLCachedControl<S32> drag_and_drop_threshold(*LLUI::sSettingGroups["config"],"DragAndDropDistanceThreshold", 3);
+
+ mIsMouseOverTitle = (y > (getRect().getHeight() - mItemHeight));
+
+ if( hasMouseCapture() && isMovable() )
+ {
+ LLFolderView* root = getRoot();
+
+ if( (x - mDragStartX) * (x - mDragStartX) + (y - mDragStartY) * (y - mDragStartY) > drag_and_drop_threshold() * drag_and_drop_threshold()
+ && root->getCurSelectedItem()
+ && root->startDrag())
+ {
+ // RN: when starting drag and drop, clear out last auto-open
+ root->autoOpenTest(NULL);
+ root->setShowSelectionContext(TRUE);
+
+ // Release keyboard focus, so that if stuff is dropped into the
+ // world, pressing the delete key won't blow away the inventory
+ // item.
+ gFocusMgr.setKeyboardFocus(NULL);
+
+ getWindow()->setCursor(UI_CURSOR_ARROW);
+ }
+ else if (x != mDragStartX || y != mDragStartY)
+ {
+ getWindow()->setCursor(UI_CURSOR_NOLOCKED);
+ }
+
+ return TRUE;
+ }
+ else
+ {
+ getRoot()->setShowSelectionContext(FALSE);
+ getWindow()->setCursor(UI_CURSOR_ARROW);
+ // let parent handle this then...
+ return FALSE;
+ }
+}
+
+
+BOOL LLFolderViewItem::handleDoubleClick( S32 x, S32 y, MASK mask )
+{
+ openItem();
+ return TRUE;
+}
+
+BOOL LLFolderViewItem::handleMouseUp( S32 x, S32 y, MASK mask )
+{
+ if (LLView::childrenHandleMouseUp(x, y, mask))
+ {
+ return TRUE;
+ }
+
+ // if mouse hasn't moved since mouse down...
+ if ( pointInView(x, y) && mSelectPending )
+ {
+ //...then select
+ if(mask & MASK_CONTROL)
+ {
+ getRoot()->changeSelection(this, !mIsSelected);
+ }
+ else if (mask & MASK_SHIFT)
+ {
+ getParentFolder()->extendSelectionTo(this);
+ }
+ else
+ {
+ getRoot()->setSelection(this, FALSE);
+ }
+ }
+
+ mSelectPending = FALSE;
+
+ if( hasMouseCapture() )
+ {
+ if (getRoot())
+ {
+ getRoot()->setShowSelectionContext(FALSE);
+ }
+ gFocusMgr.setMouseCapture( NULL );
+ }
+ return TRUE;
+}
+
+void LLFolderViewItem::onMouseLeave(S32 x, S32 y, MASK mask)
+{
+ mIsMouseOverTitle = false;
+}
+
+BOOL LLFolderViewItem::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
+ EDragAndDropType cargo_type,
+ void* cargo_data,
+ EAcceptance* accept,
+ std::string& tooltip_msg)
+{
+ BOOL handled = FALSE;
+ BOOL accepted = getViewModelItem()->dragOrDrop(mask,drop,cargo_type,cargo_data, tooltip_msg);
+ handled = accepted;
+ if (accepted)
+ {
+ mDragAndDropTarget = TRUE;
+ *accept = ACCEPT_YES_MULTI;
+ }
+ else
+ {
+ *accept = ACCEPT_NO;
+ }
+ if(mParentFolder && !handled)
+ {
+ // store this item to get it in LLFolderBridge::dragItemIntoFolder on drop event.
+ mRoot->setDraggingOverItem(this);
+ handled = mParentFolder->handleDragAndDropFromChild(mask,drop,cargo_type,cargo_data,accept,tooltip_msg);
+ mRoot->setDraggingOverItem(NULL);
+ }
+ if (handled)
+ {
+ lldebugst(LLERR_USER_INPUT) << "dragAndDrop handled by LLFolderViewItem" << llendl;
+ }
+
+ return handled;
+}
+
+void LLFolderViewItem::drawOpenFolderArrow(const Params& default_params, const LLUIColor& fg_color)
+{
+ //--------------------------------------------------------------------------------//
+ // Draw open folder arrow
+ //
+ const S32 TOP_PAD = default_params.item_top_pad;
+
+ if (hasVisibleChildren() || getViewModelItem()->hasChildren())
+ {
+ LLUIImage* arrow_image = default_params.folder_arrow_image;
+ gl_draw_scaled_rotated_image(
+ mIndentation, getRect().getHeight() - mArrowSize - mTextPad - TOP_PAD,
+ mArrowSize, mArrowSize, mControlLabelRotation, arrow_image->getImage(), fg_color);
+ }
+}
+
+/*virtual*/ bool LLFolderViewItem::isHighlightAllowed()
+{
+ return mIsSelected;
+}
+
+/*virtual*/ bool LLFolderViewItem::isHighlightActive()
+{
+ return mIsCurSelection;
+}
+
+void LLFolderViewItem::drawHighlight(const BOOL showContent, const BOOL hasKeyboardFocus, const LLUIColor &selectColor, const LLUIColor &flashColor,
+ const LLUIColor &focusOutlineColor, const LLUIColor &mouseOverColor)
+{
+ const S32 focus_top = getRect().getHeight();
+ const S32 focus_bottom = getRect().getHeight() - mItemHeight;
+ const bool folder_open = (getRect().getHeight() > mItemHeight + 4);
+ const S32 FOCUS_LEFT = 1;
+
+ // Determine which background color to use for highlighting
+ LLUIColor bgColor = (isFlashing() ? flashColor : selectColor);
+
+ //--------------------------------------------------------------------------------//
+ // Draw highlight for selected items
+ // Note: Always render "current" item or flashing item, only render other selected
+ // items if mShowSingleSelection is FALSE.
+ //
+ if (isHighlightAllowed())
+
+ {
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+ // Highlight for selected but not current items
+ if (!isHighlightActive() && !isFlashing())
+ {
+ LLColor4 bg_color = bgColor;
+ // do time-based fade of extra objects
+ F32 fade_time = (getRoot() ? getRoot()->getSelectionFadeElapsedTime() : 0.0f);
+ if (getRoot() && getRoot()->getShowSingleSelection())
+ {
+ // fading out
+ bg_color.mV[VALPHA] = clamp_rescale(fade_time, 0.f, 0.4f, bg_color.mV[VALPHA], 0.f);
+ }
+ else
+ {
+ // fading in
+ bg_color.mV[VALPHA] = clamp_rescale(fade_time, 0.f, 0.4f, 0.f, bg_color.mV[VALPHA]);
+ }
+ gl_rect_2d(FOCUS_LEFT,
+ focus_top,
+ getRect().getWidth() - 2,
+ focus_bottom,
+ bg_color, hasKeyboardFocus);
+ }
+
+ // Highlight for currently selected or flashing item
+ if (isHighlightActive())
+ {
+ // Background
+ gl_rect_2d(FOCUS_LEFT,
+ focus_top,
+ getRect().getWidth() - 2,
+ focus_bottom,
+ bgColor, hasKeyboardFocus);
+ // Outline
+ gl_rect_2d(FOCUS_LEFT,
+ focus_top,
+ getRect().getWidth() - 2,
+ focus_bottom,
+ focusOutlineColor, FALSE);
+ }
+
+ if (folder_open)
+ {
+ gl_rect_2d(FOCUS_LEFT,
+ focus_bottom + 1, // overlap with bottom edge of above rect
+ getRect().getWidth() - 2,
+ 0,
+ focusOutlineColor, FALSE);
+ if (showContent && !isFlashing())
+ {
+ gl_rect_2d(FOCUS_LEFT,
+ focus_bottom + 1,
+ getRect().getWidth() - 2,
+ 0,
+ bgColor, TRUE);
+ }
+ }
+ }
+ else if (mIsMouseOverTitle)
+ {
+ gl_rect_2d(FOCUS_LEFT,
+ focus_top,
+ getRect().getWidth() - 2,
+ focus_bottom,
+ mouseOverColor, FALSE);
+ }
+
+ //--------------------------------------------------------------------------------//
+ // Draw DragNDrop highlight
+ //
+ if (mDragAndDropTarget)
+ {
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ gl_rect_2d(FOCUS_LEFT,
+ focus_top,
+ getRect().getWidth() - 2,
+ focus_bottom,
+ bgColor, FALSE);
+ if (folder_open)
+ {
+ gl_rect_2d(FOCUS_LEFT,
+ focus_bottom + 1, // overlap with bottom edge of above rect
+ getRect().getWidth() - 2,
+ 0,
+ bgColor, FALSE);
+ }
+ mDragAndDropTarget = FALSE;
+ }
+}
+
+void LLFolderViewItem::drawLabel(const LLFontGL * font, const F32 x, const F32 y, const LLColor4& color, F32 &right_x)
+{
+ //--------------------------------------------------------------------------------//
+ // Draw the actual label text
+ //
+ font->renderUTF8(mLabel, 0, x, y, color,
+ LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
+ S32_MAX, getRect().getWidth() - (S32) x - mLabelPaddingRight, &right_x, TRUE);
+}
+
+void LLFolderViewItem::draw()
+{
+ const BOOL show_context = (getRoot() ? getRoot()->getShowSelectionContext() : FALSE);
+ const BOOL filled = show_context || (getRoot() ? getRoot()->getParentPanel()->hasFocus() : FALSE); // If we have keyboard focus, draw selection filled
+
+ const Params& default_params = LLUICtrlFactory::getDefaultParams<LLFolderViewItem>();
+ const S32 TOP_PAD = default_params.item_top_pad;
+
+ const LLFontGL* font = getLabelFontForStyle(mLabelStyle);
+
+ getViewModelItem()->update();
+
+ drawOpenFolderArrow(default_params, sFgColor);
+
+ drawHighlight(show_context, filled, sHighlightBgColor, sFlashBgColor, sFocusOutlineColor, sMouseOverColor);
+
+ //--------------------------------------------------------------------------------//
+ // Draw open icon
+ //
+ const S32 icon_x = mIndentation + mArrowSize + mTextPad;
+ if (!mIconOpen.isNull() && (llabs(mControlLabelRotation) > 80)) // For open folders
+ {
+ mIconOpen->draw(icon_x, getRect().getHeight() - mIconOpen->getHeight() - TOP_PAD + 1);
+ }
+ else if (mIcon)
+ {
+ mIcon->draw(icon_x, getRect().getHeight() - mIcon->getHeight() - TOP_PAD + 1);
+ }
+
+ if (mIconOverlay && getRoot()->showItemLinkOverlays())
+ {
+ mIconOverlay->draw(icon_x, getRect().getHeight() - mIcon->getHeight() - TOP_PAD + 1);
+ }
+
+ //--------------------------------------------------------------------------------//
+ // Exit if no label to draw
+ //
+ if (mLabel.empty())
+ {
+ return;
+ }
+
+ std::string::size_type filter_string_length = mViewModelItem->hasFilterStringMatch() ? mViewModelItem->getFilterStringSize() : 0;
+ F32 right_x = 0;
+ F32 y = (F32)getRect().getHeight() - font->getLineHeight() - (F32)mTextPad - (F32)TOP_PAD;
+ F32 text_left = (F32)getLabelXPos();
+ std::string combined_string = mLabel + mLabelSuffix;
+
+ if (filter_string_length > 0)
+ {
+ S32 left = llround(text_left) + font->getWidth(combined_string, 0, mViewModelItem->getFilterStringOffset()) - 2;
+ S32 right = left + font->getWidth(combined_string, mViewModelItem->getFilterStringOffset(), filter_string_length) + 2;
+ S32 bottom = llfloor(getRect().getHeight() - font->getLineHeight() - 3 - TOP_PAD);
+ S32 top = getRect().getHeight() - TOP_PAD;
+
+ LLUIImage* box_image = default_params.selection_image;
+ LLRect box_rect(left, top, right, bottom);
+ box_image->draw(box_rect, sFilterBGColor);
+ }
+
+ LLColor4 color = (mIsSelected && filled) ? mFontHighlightColor : mFontColor;
+ drawLabel(font, text_left, y, color, right_x);
+
+ //--------------------------------------------------------------------------------//
+ // Draw label suffix
+ //
+ if (!mLabelSuffix.empty())
+ {
+ font->renderUTF8( mLabelSuffix, 0, right_x, y, sSuffixColor,
+ LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
+ S32_MAX, S32_MAX, &right_x, FALSE );
+ }
+
+ //--------------------------------------------------------------------------------//
+ // Highlight string match
+ //
+ if (filter_string_length > 0)
+ {
+ F32 match_string_left = text_left + font->getWidthF32(combined_string, 0, mViewModelItem->getFilterStringOffset());
+ F32 yy = (F32)getRect().getHeight() - font->getLineHeight() - (F32)mTextPad - (F32)TOP_PAD;
+ font->renderUTF8( combined_string, mViewModelItem->getFilterStringOffset(), match_string_left, yy,
+ sFilterTextColor, LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
+ filter_string_length, S32_MAX, &right_x, FALSE );
+ }
+
+ //Gilbert Linden 9-20-2012: Although this should be legal, removing it because it causes the mLabelSuffix rendering to
+ //be distorted...oddly. I initially added this in but didn't need it after all. So removing to prevent unnecessary bug.
+ //LLView::draw();
+}
+
+const LLFolderViewModelInterface* LLFolderViewItem::getFolderViewModel( void ) const
+{
+ return getRoot()->getFolderViewModel();
+}
+
+LLFolderViewModelInterface* LLFolderViewItem::getFolderViewModel( void )
+{
+ return getRoot()->getFolderViewModel();
+}
+
+bool LLFolderViewItem::isInSelection() const
+{
+ return mIsSelected || (mParentFolder && mParentFolder->isInSelection());
+}
+
+
+
+///----------------------------------------------------------------------------
+/// Class LLFolderViewFolder
+///----------------------------------------------------------------------------
+
+LLFolderViewFolder::LLFolderViewFolder( const LLFolderViewItem::Params& p ):
+ LLFolderViewItem( p ),
+ mIsOpen(FALSE),
+ mExpanderHighlighted(FALSE),
+ mCurHeight(0.f),
+ mTargetHeight(0.f),
+ mAutoOpenCountdown(0.f),
+ mLastArrangeGeneration( -1 ),
+ mLastCalculatedWidth(0)
+{
+}
+
+void LLFolderViewFolder::updateLabelRotation()
+{
+ if (mAutoOpenCountdown != 0.f)
+ {
+ mControlLabelRotation = mAutoOpenCountdown * -90.f;
+ }
+ else if (isOpen())
+ {
+ mControlLabelRotation = lerp(mControlLabelRotation, -90.f, LLCriticalDamp::getInterpolant(0.04f));
+ }
+ else
+ {
+ mControlLabelRotation = lerp(mControlLabelRotation, 0.f, LLCriticalDamp::getInterpolant(0.025f));
+ }
+}
+
+// Destroys the object
+LLFolderViewFolder::~LLFolderViewFolder( void )
+{
+ // The LLView base class takes care of object destruction. make sure that we
+ // don't have mouse or keyboard focus
+ gFocusMgr.releaseFocusIfNeeded( this ); // calls onCommit()
+}
+
+// addToFolder() returns TRUE if it succeeds. FALSE otherwise
+void LLFolderViewFolder::addToFolder(LLFolderViewFolder* folder)
+{
+ folder->addFolder(this);
+
+ // Compute indentation since parent folder changed
+ mIndentation = (getParentFolder())
+ ? getParentFolder()->getIndentation() + mLocalIndentation
+ : 0;
+}
+
+static LLFastTimer::DeclareTimer FTM_ARRANGE("Arrange");
+
+// Make everything right and in the right place ready for drawing (CHUI-849)
+// * Sort everything correctly if necessary
+// * Turn widgets visible/invisible according to their model filtering state
+// * Takes animation state into account for opening/closing of folders (this makes widgets visible/invisible)
+// * Reposition visible widgets so that they line up correctly with no gap
+// * Compute the width and height of the current folder and its children
+// * Makes sure that this view and its children are the right size
+S32 LLFolderViewFolder::arrange( S32* width, S32* height )
+{
+ // Sort before laying out contents
+ // Note that we sort from the root (CHUI-849)
+ getRoot()->getFolderViewModel()->sort(this);
+
+ LLFastTimer t2(FTM_ARRANGE);
+
+ // evaluate mHasVisibleChildren
+ mHasVisibleChildren = false;
+ if (getViewModelItem()->descendantsPassedFilter())
+ {
+ // We have to verify that there's at least one child that's not filtered out
+ bool found = false;
+ // Try the items first
+ for (items_t::iterator iit = mItems.begin(); iit != mItems.end(); ++iit)
+ {
+ LLFolderViewItem* itemp = (*iit);
+ found = itemp->passedFilter();
+ if (found)
+ break;
+ }
+ if (!found)
+ {
+ // If no item found, try the folders
+ for (folders_t::iterator fit = mFolders.begin(); fit != mFolders.end(); ++fit)
+ {
+ LLFolderViewFolder* folderp = (*fit);
+ found = folderp->passedFilter();
+ if (found)
+ break;
+ }
+ }
+
+ mHasVisibleChildren = found;
+ }
+
+ // calculate height as a single item (without any children), and reshapes rectangle to match
+ LLFolderViewItem::arrange( width, height );
+
+ // clamp existing animated height so as to never get smaller than a single item
+ mCurHeight = llmax((F32)*height, mCurHeight);
+
+ // initialize running height value as height of single item in case we have no children
+ F32 running_height = (F32)*height;
+ F32 target_height = (F32)*height;
+
+ // are my children visible?
+ if (needsArrange())
+ {
+ // set last arrange generation first, in case children are animating
+ // and need to be arranged again
+ mLastArrangeGeneration = getRoot()->getArrangeGeneration();
+ if (isOpen())
+ {
+ // Add sizes of children
+ S32 parent_item_height = getRect().getHeight();
+
+ for(folders_t::iterator fit = mFolders.begin(); fit != mFolders.end(); ++fit)
+ {
+ LLFolderViewFolder* folderp = (*fit);
+ folderp->setVisible(folderp->passedFilter()); // passed filter or has descendants that passed filter
+
+ if (folderp->getVisible())
+ {
+ S32 child_width = *width;
+ S32 child_height = 0;
+ S32 child_top = parent_item_height - llround(running_height);
+
+ target_height += folderp->arrange( &child_width, &child_height );
+
+ running_height += (F32)child_height;
+ *width = llmax(*width, child_width);
+ folderp->setOrigin( 0, child_top - folderp->getRect().getHeight() );
+ }
+ }
+ for(items_t::iterator iit = mItems.begin();
+ iit != mItems.end(); ++iit)
+ {
+ LLFolderViewItem* itemp = (*iit);
+ itemp->setVisible(itemp->passedFilter());
+
+ if (itemp->getVisible())
+ {
+ S32 child_width = *width;
+ S32 child_height = 0;
+ S32 child_top = parent_item_height - llround(running_height);
+
+ target_height += itemp->arrange( &child_width, &child_height );
+ // don't change width, as this item is as wide as its parent folder by construction
+ itemp->reshape( itemp->getRect().getWidth(), child_height);
+
+ running_height += (F32)child_height;
+ *width = llmax(*width, child_width);
+ itemp->setOrigin( 0, child_top - itemp->getRect().getHeight() );
+ }
+ }
+ }
+
+ mTargetHeight = target_height;
+ // cache this width so next time we can just return it
+ mLastCalculatedWidth = *width;
+ }
+ else
+ {
+ // just use existing width
+ *width = mLastCalculatedWidth;
+ }
+
+ // animate current height towards target height
+ if (llabs(mCurHeight - mTargetHeight) > 1.f)
+ {
+ mCurHeight = lerp(mCurHeight, mTargetHeight, LLCriticalDamp::getInterpolant(isOpen() ? FOLDER_OPEN_TIME_CONSTANT : FOLDER_CLOSE_TIME_CONSTANT));
+
+ requestArrange();
+
+ // hide child elements that fall out of current animated height
+ for (folders_t::iterator iter = mFolders.begin();
+ iter != mFolders.end();)
+ {
+ folders_t::iterator fit = iter++;
+ // number of pixels that bottom of folder label is from top of parent folder
+ if (getRect().getHeight() - (*fit)->getRect().mTop + (*fit)->getItemHeight()
+ > llround(mCurHeight) + mMaxFolderItemOverlap)
+ {
+ // hide if beyond current folder height
+ (*fit)->setVisible(FALSE);
+ }
+ }
+
+ for (items_t::iterator iter = mItems.begin();
+ iter != mItems.end();)
+ {
+ items_t::iterator iit = iter++;
+ // number of pixels that bottom of item label is from top of parent folder
+ if (getRect().getHeight() - (*iit)->getRect().mBottom
+ > llround(mCurHeight) + mMaxFolderItemOverlap)
+ {
+ (*iit)->setVisible(FALSE);
+ }
+ }
+ }
+ else
+ {
+ mCurHeight = mTargetHeight;
+ }
+
+ // don't change width as this item is already as wide as its parent folder
+ reshape(getRect().getWidth(),llround(mCurHeight));
+
+ // pass current height value back to parent
+ *height = llround(mCurHeight);
+
+ return llround(mTargetHeight);
+}
+
+BOOL LLFolderViewFolder::needsArrange()
+{
+ return mLastArrangeGeneration < getRoot()->getArrangeGeneration();
+}
+
+// Passes selection information on to children and record selection
+// information if necessary.
+BOOL LLFolderViewFolder::setSelection(LLFolderViewItem* selection, BOOL openitem,
+ BOOL take_keyboard_focus)
+{
+ BOOL rv = FALSE;
+ if (selection == this)
+ {
+ if (!isSelected())
+ {
+ selectItem();
+ }
+ rv = TRUE;
+ }
+ else
+ {
+ if (isSelected())
+ {
+ deselectItem();
+ }
+ rv = FALSE;
+ }
+ BOOL child_selected = FALSE;
+
+ for (folders_t::iterator iter = mFolders.begin();
+ iter != mFolders.end();)
+ {
+ folders_t::iterator fit = iter++;
+ if((*fit)->setSelection(selection, openitem, take_keyboard_focus))
+ {
+ rv = TRUE;
+ child_selected = TRUE;
+ }
+ }
+ for (items_t::iterator iter = mItems.begin();
+ iter != mItems.end();)
+ {
+ items_t::iterator iit = iter++;
+ if((*iit)->setSelection(selection, openitem, take_keyboard_focus))
+ {
+ rv = TRUE;
+ child_selected = TRUE;
+ }
+ }
+ if(openitem && child_selected)
+ {
+ setOpenArrangeRecursively(TRUE);
+ }
+ return rv;
+}
+
+// This method is used to change the selection of an item.
+// Recursively traverse all children; if 'selection' is 'this' then change
+// the select status if necessary.
+// Returns TRUE if the selection state of this folder, or of a child, was changed.
+BOOL LLFolderViewFolder::changeSelection(LLFolderViewItem* selection, BOOL selected)
+{
+ BOOL rv = FALSE;
+ if(selection == this)
+ {
+ if (isSelected() != selected)
+ {
+ rv = TRUE;
+ if (selected)
+ {
+ selectItem();
+ }
+ else
+ {
+ deselectItem();
+ }
+ }
+ }
+
+ for (folders_t::iterator iter = mFolders.begin();
+ iter != mFolders.end();)
+ {
+ folders_t::iterator fit = iter++;
+ if((*fit)->changeSelection(selection, selected))
+ {
+ rv = TRUE;
+ }
+ }
+ for (items_t::iterator iter = mItems.begin();
+ iter != mItems.end();)
+ {
+ items_t::iterator iit = iter++;
+ if((*iit)->changeSelection(selection, selected))
+ {
+ rv = TRUE;
+ }
+ }
+ return rv;
+}
+
+LLFolderViewFolder* LLFolderViewFolder::getCommonAncestor(LLFolderViewItem* item_a, LLFolderViewItem* item_b, bool& reverse)
+{
+ if (!item_a->getParentFolder() || !item_b->getParentFolder()) return NULL;
+
+ std::deque<LLFolderViewFolder*> item_a_ancestors;
+
+ LLFolderViewFolder* parent = item_a->getParentFolder();
+ while(parent)
+ {
+ item_a_ancestors.push_back(parent);
+ parent = parent->getParentFolder();
+ }
+
+ std::deque<LLFolderViewFolder*> item_b_ancestors;
+
+ parent = item_b->getParentFolder();
+ while(parent)
+ {
+ item_b_ancestors.push_back(parent);
+ parent = parent->getParentFolder();
+ }
+
+ LLFolderViewFolder* common_ancestor = item_a->getRoot();
+
+ while(item_a_ancestors.size() > item_b_ancestors.size())
+ {
+ item_a = item_a_ancestors.front();
+ item_a_ancestors.pop_front();
+ }
+
+ while(item_b_ancestors.size() > item_a_ancestors.size())
+ {
+ item_b = item_b_ancestors.front();
+ item_b_ancestors.pop_front();
+ }
+
+ while(item_a_ancestors.size())
+ {
+ common_ancestor = item_a_ancestors.front();
+
+ if (item_a_ancestors.front() == item_b_ancestors.front())
+ {
+ // which came first, sibling a or sibling b?
+ for (folders_t::iterator it = common_ancestor->mFolders.begin(), end_it = common_ancestor->mFolders.end();
+ it != end_it;
+ ++it)
+ {
+ LLFolderViewItem* item = *it;
+
+ if (item == item_a)
+ {
+ reverse = false;
+ return common_ancestor;
+ }
+ if (item == item_b)
+ {
+ reverse = true;
+ return common_ancestor;
+ }
+ }
+
+ for (items_t::iterator it = common_ancestor->mItems.begin(), end_it = common_ancestor->mItems.end();
+ it != end_it;
+ ++it)
+ {
+ LLFolderViewItem* item = *it;
+
+ if (item == item_a)
+ {
+ reverse = false;
+ return common_ancestor;
+ }
+ if (item == item_b)
+ {
+ reverse = true;
+ return common_ancestor;
+ }
+ }
+ break;
+ }
+
+ item_a = item_a_ancestors.front();
+ item_a_ancestors.pop_front();
+ item_b = item_b_ancestors.front();
+ item_b_ancestors.pop_front();
+ }
+
+ return NULL;
+}
+
+void LLFolderViewFolder::gatherChildRangeExclusive(LLFolderViewItem* start, LLFolderViewItem* end, bool reverse, std::vector<LLFolderViewItem*>& items)
+{
+ bool selecting = start == NULL;
+ if (reverse)
+ {
+ for (items_t::reverse_iterator it = mItems.rbegin(), end_it = mItems.rend();
+ it != end_it;
+ ++it)
+ {
+ if (*it == end)
+ {
+ return;
+ }
+ if (selecting)
+ {
+ items.push_back(*it);
+ }
+
+ if (*it == start)
+ {
+ selecting = true;
+ }
+ }
+ for (folders_t::reverse_iterator it = mFolders.rbegin(), end_it = mFolders.rend();
+ it != end_it;
+ ++it)
+ {
+ if (*it == end)
+ {
+ return;
+ }
+
+ if (selecting)
+ {
+ items.push_back(*it);
+ }
+
+ if (*it == start)
+ {
+ selecting = true;
+ }
+ }
+ }
+ else
+ {
+ for (folders_t::iterator it = mFolders.begin(), end_it = mFolders.end();
+ it != end_it;
+ ++it)
+ {
+ if (*it == end)
+ {
+ return;
+ }
+
+ if (selecting)
+ {
+ items.push_back(*it);
+ }
+
+ if (*it == start)
+ {
+ selecting = true;
+ }
+ }
+ for (items_t::iterator it = mItems.begin(), end_it = mItems.end();
+ it != end_it;
+ ++it)
+ {
+ if (*it == end)
+ {
+ return;
+ }
+
+ if (selecting)
+ {
+ items.push_back(*it);
+ }
+
+ if (*it == start)
+ {
+ selecting = true;
+ }
+ }
+ }
+}
+
+void LLFolderViewFolder::extendSelectionTo(LLFolderViewItem* new_selection)
+{
+ if (getRoot()->getAllowMultiSelect() == FALSE) return;
+
+ LLFolderViewItem* cur_selected_item = getRoot()->getCurSelectedItem();
+ if (cur_selected_item == NULL)
+ {
+ cur_selected_item = new_selection;
+ }
+
+
+ bool reverse = false;
+ LLFolderViewFolder* common_ancestor = getCommonAncestor(cur_selected_item, new_selection, reverse);
+ if (!common_ancestor) return;
+
+ LLFolderViewItem* last_selected_item_from_cur = cur_selected_item;
+ LLFolderViewFolder* cur_folder = cur_selected_item->getParentFolder();
+
+ std::vector<LLFolderViewItem*> items_to_select_forward;
+
+ while(cur_folder != common_ancestor)
+ {
+ cur_folder->gatherChildRangeExclusive(last_selected_item_from_cur, NULL, reverse, items_to_select_forward);
+
+ last_selected_item_from_cur = cur_folder;
+ cur_folder = cur_folder->getParentFolder();
+ }
+
+ std::vector<LLFolderViewItem*> items_to_select_reverse;
+
+ LLFolderViewItem* last_selected_item_from_new = new_selection;
+ cur_folder = new_selection->getParentFolder();
+ while(cur_folder != common_ancestor)
+ {
+ cur_folder->gatherChildRangeExclusive(last_selected_item_from_new, NULL, !reverse, items_to_select_reverse);
+
+ last_selected_item_from_new = cur_folder;
+ cur_folder = cur_folder->getParentFolder();
+ }
+
+ common_ancestor->gatherChildRangeExclusive(last_selected_item_from_cur, last_selected_item_from_new, reverse, items_to_select_forward);
+
+ for (std::vector<LLFolderViewItem*>::reverse_iterator it = items_to_select_reverse.rbegin(), end_it = items_to_select_reverse.rend();
+ it != end_it;
+ ++it)
+ {
+ items_to_select_forward.push_back(*it);
+ }
+
+ LLFolderView* root = getRoot();
+
+ for (std::vector<LLFolderViewItem*>::iterator it = items_to_select_forward.begin(), end_it = items_to_select_forward.end();
+ it != end_it;
+ ++it)
+ {
+ LLFolderViewItem* item = *it;
+ if (item->isSelected())
+ {
+ root->removeFromSelectionList(item);
+ }
+ else
+ {
+ item->selectItem();
+ }
+ root->addToSelectionList(item);
+ }
+
+ if (new_selection->isSelected())
+ {
+ root->removeFromSelectionList(new_selection);
+ }
+ else
+ {
+ new_selection->selectItem();
+ }
+ root->addToSelectionList(new_selection);
+}
+
+
+void LLFolderViewFolder::destroyView()
+{
+ while (!mItems.empty())
+ {
+ LLFolderViewItem *itemp = mItems.back();
+ itemp->destroyView(); // LLFolderViewItem::destroyView() removes entry from mItems
+ }
+
+ while (!mFolders.empty())
+ {
+ LLFolderViewFolder *folderp = mFolders.back();
+ folderp->destroyView(); // LLFolderVievFolder::destroyView() removes entry from mFolders
+ }
+
+ LLFolderViewItem::destroyView();
+}
+
+// extractItem() removes the specified item from the folder, but
+// doesn't delete it.
+void LLFolderViewFolder::extractItem( LLFolderViewItem* item )
+{
+ if (item->isSelected())
+ getRoot()->clearSelection();
+ items_t::iterator it = std::find(mItems.begin(), mItems.end(), item);
+ if(it == mItems.end())
+ {
+ // This is an evil downcast. However, it's only doing
+ // pointer comparison to find if (which it should be ) the
+ // item is in the container, so it's pretty safe.
+ LLFolderViewFolder* f = static_cast<LLFolderViewFolder*>(item);
+ folders_t::iterator ft;
+ ft = std::find(mFolders.begin(), mFolders.end(), f);
+ if (ft != mFolders.end())
+ {
+ mFolders.erase(ft);
+ }
+ }
+ else
+ {
+ mItems.erase(it);
+ }
+ //item has been removed, need to update filter
+ getViewModelItem()->removeChild(item->getViewModelItem());
+ //because an item is going away regardless of filter status, force rearrange
+ requestArrange();
+ removeChild(item);
+}
+
+BOOL LLFolderViewFolder::isMovable()
+{
+ if( !(getViewModelItem()->isItemMovable()) )
+ {
+ return FALSE;
+ }
+
+ for (items_t::iterator iter = mItems.begin();
+ iter != mItems.end();)
+ {
+ items_t::iterator iit = iter++;
+ if(!(*iit)->isMovable())
+ {
+ return FALSE;
+ }
+ }
+
+ for (folders_t::iterator iter = mFolders.begin();
+ iter != mFolders.end();)
+ {
+ folders_t::iterator fit = iter++;
+ if(!(*fit)->isMovable())
+ {
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+
+BOOL LLFolderViewFolder::isRemovable()
+{
+ if( !(getViewModelItem()->isItemRemovable()) )
+ {
+ return FALSE;
+ }
+
+ for (items_t::iterator iter = mItems.begin();
+ iter != mItems.end();)
+ {
+ items_t::iterator iit = iter++;
+ if(!(*iit)->isRemovable())
+ {
+ return FALSE;
+ }
+ }
+
+ for (folders_t::iterator iter = mFolders.begin();
+ iter != mFolders.end();)
+ {
+ folders_t::iterator fit = iter++;
+ if(!(*fit)->isRemovable())
+ {
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+// this is an internal method used for adding items to folders.
+void LLFolderViewFolder::addItem(LLFolderViewItem* item)
+{
+ if (item->getParentFolder())
+ {
+ item->getParentFolder()->extractItem(item);
+ }
+ item->setParentFolder(this);
+
+ mItems.push_back(item);
+
+ item->setRect(LLRect(0, 0, getRect().getWidth(), 0));
+ item->setVisible(FALSE);
+
+ addChild(item);
+
+ // When the model is already hooked into a hierarchy (i.e. has a parent), do not reparent it
+ // Note: this happens when models are created before views or shared between views
+ if (!item->getViewModelItem()->hasParent())
+ {
+ getViewModelItem()->addChild(item->getViewModelItem());
+ }
+}
+
+// this is an internal method used for adding items to folders.
+void LLFolderViewFolder::addFolder(LLFolderViewFolder* folder)
+{
+ if (folder->mParentFolder)
+ {
+ folder->mParentFolder->extractItem(folder);
+ }
+ folder->mParentFolder = this;
+ mFolders.push_back(folder);
+ folder->setOrigin(0, 0);
+ folder->reshape(getRect().getWidth(), 0);
+ folder->setVisible(FALSE);
+ // rearrange all descendants too, as our indentation level might have changed
+ //folder->requestArrange();
+ //requestSort();
+
+ addChild(folder);
+
+ // When the model is already hooked into a hierarchy (i.e. has a parent), do not reparent it
+ // Note: this happens when models are created before views or shared between views
+ if (!folder->getViewModelItem()->hasParent())
+ {
+ getViewModelItem()->addChild(folder->getViewModelItem());
+ }
+}
+
+void LLFolderViewFolder::requestArrange()
+{
+ mLastArrangeGeneration = -1;
+ // flag all items up to root
+ if (mParentFolder)
+ {
+ mParentFolder->requestArrange();
+ }
+}
+
+void LLFolderViewFolder::toggleOpen()
+{
+ setOpen(!isOpen());
+}
+
+// Force a folder open or closed
+void LLFolderViewFolder::setOpen(BOOL openitem)
+{
+ setOpenArrangeRecursively(openitem);
+}
+
+void LLFolderViewFolder::setOpenArrangeRecursively(BOOL openitem, ERecurseType recurse)
+{
+ BOOL was_open = isOpen();
+ mIsOpen = openitem;
+ if(!was_open && openitem)
+ {
+ getViewModelItem()->openItem();
+ }
+ else if(was_open && !openitem)
+ {
+ getViewModelItem()->closeItem();
+ }
+
+ if (recurse == RECURSE_DOWN || recurse == RECURSE_UP_DOWN)
+ {
+ for (folders_t::iterator iter = mFolders.begin();
+ iter != mFolders.end();)
+ {
+ folders_t::iterator fit = iter++;
+ (*fit)->setOpenArrangeRecursively(openitem, RECURSE_DOWN); /* Flawfinder: ignore */
+ }
+ }
+ if (mParentFolder
+ && (recurse == RECURSE_UP
+ || recurse == RECURSE_UP_DOWN))
+ {
+ mParentFolder->setOpenArrangeRecursively(openitem, RECURSE_UP);
+ }
+
+ if (was_open != isOpen())
+ {
+ requestArrange();
+ }
+}
+
+BOOL LLFolderViewFolder::handleDragAndDropFromChild(MASK mask,
+ BOOL drop,
+ EDragAndDropType c_type,
+ void* cargo_data,
+ EAcceptance* accept,
+ std::string& tooltip_msg)
+{
+ BOOL accepted = mViewModelItem->dragOrDrop(mask,drop,c_type,cargo_data, tooltip_msg);
+ if (accepted)
+ {
+ mDragAndDropTarget = TRUE;
+ *accept = ACCEPT_YES_MULTI;
+ }
+ else
+ {
+ *accept = ACCEPT_NO;
+ }
+
+ // drag and drop to child item, so clear pending auto-opens
+ getRoot()->autoOpenTest(NULL);
+
+ return TRUE;
+}
+
+void LLFolderViewFolder::openItem( void )
+{
+ toggleOpen();
+}
+
+void LLFolderViewFolder::applyFunctorToChildren(LLFolderViewFunctor& functor)
+{
+ for (folders_t::iterator iter = mFolders.begin();
+ iter != mFolders.end();)
+ {
+ folders_t::iterator fit = iter++;
+ functor.doItem((*fit));
+ }
+ for (items_t::iterator iter = mItems.begin();
+ iter != mItems.end();)
+ {
+ items_t::iterator iit = iter++;
+ functor.doItem((*iit));
+ }
+}
+
+void LLFolderViewFolder::applyFunctorRecursively(LLFolderViewFunctor& functor)
+{
+ functor.doFolder(this);
+
+ for (folders_t::iterator iter = mFolders.begin();
+ iter != mFolders.end();)
+ {
+ folders_t::iterator fit = iter++;
+ (*fit)->applyFunctorRecursively(functor);
+ }
+ for (items_t::iterator iter = mItems.begin();
+ iter != mItems.end();)
+ {
+ items_t::iterator iit = iter++;
+ functor.doItem((*iit));
+ }
+}
+
+// LLView functionality
+BOOL LLFolderViewFolder::handleDragAndDrop(S32 x, S32 y, MASK mask,
+ BOOL drop,
+ EDragAndDropType cargo_type,
+ void* cargo_data,
+ EAcceptance* accept,
+ std::string& tooltip_msg)
+{
+ BOOL handled = FALSE;
+
+ if (isOpen())
+ {
+ handled = (childrenHandleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg) != NULL);
+ }
+
+ if (!handled)
+ {
+ handleDragAndDropToThisFolder(mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
+
+ lldebugst(LLERR_USER_INPUT) << "dragAndDrop handled by LLFolderViewFolder" << llendl;
+ }
+
+ return TRUE;
+}
+
+BOOL LLFolderViewFolder::handleDragAndDropToThisFolder(MASK mask,
+ BOOL drop,
+ EDragAndDropType cargo_type,
+ void* cargo_data,
+ EAcceptance* accept,
+ std::string& tooltip_msg)
+{
+ BOOL accepted = getViewModelItem()->dragOrDrop(mask,drop,cargo_type,cargo_data, tooltip_msg);
+
+ if (accepted)
+ {
+ mDragAndDropTarget = TRUE;
+ *accept = ACCEPT_YES_MULTI;
+ }
+ else
+ {
+ *accept = ACCEPT_NO;
+ }
+
+ if (!drop && accepted)
+ {
+ getRoot()->autoOpenTest(this);
+ }
+
+ return TRUE;
+}
+
+
+BOOL LLFolderViewFolder::handleRightMouseDown( S32 x, S32 y, MASK mask )
+{
+ BOOL handled = FALSE;
+
+ if( isOpen() )
+ {
+ handled = childrenHandleRightMouseDown( x, y, mask ) != NULL;
+ }
+ if (!handled)
+ {
+ handled = LLFolderViewItem::handleRightMouseDown( x, y, mask );
+ }
+ return handled;
+}
+
+
+BOOL LLFolderViewFolder::handleHover(S32 x, S32 y, MASK mask)
+{
+ mIsMouseOverTitle = (y > (getRect().getHeight() - mItemHeight));
+
+ BOOL handled = LLView::handleHover(x, y, mask);
+
+ if (!handled)
+ {
+ // this doesn't do child processing
+ handled = LLFolderViewItem::handleHover(x, y, mask);
+ }
+
+ return handled;
+}
+
+BOOL LLFolderViewFolder::handleMouseDown( S32 x, S32 y, MASK mask )
+{
+ BOOL handled = FALSE;
+ if( isOpen() )
+ {
+ handled = childrenHandleMouseDown(x,y,mask) != NULL;
+ }
+ if( !handled )
+ {
+ if(mIndentation < x && x < mIndentation + (isCollapsed() ? 0 : mArrowSize) + mTextPad)
+ {
+ toggleOpen();
+ handled = TRUE;
+ }
+ else
+ {
+ // do normal selection logic
+ handled = LLFolderViewItem::handleMouseDown(x, y, mask);
+ }
+ }
+
+ return handled;
+}
+
+BOOL LLFolderViewFolder::handleDoubleClick( S32 x, S32 y, MASK mask )
+{
+ BOOL handled = FALSE;
+ if( isOpen() )
+ {
+ handled = childrenHandleDoubleClick( x, y, mask ) != NULL;
+ }
+ if( !handled )
+ {
+ if(mIndentation < x && x < mIndentation + (isCollapsed() ? 0 : mArrowSize) + mTextPad)
+ {
+ // don't select when user double-clicks plus sign
+ // so as not to contradict single-click behavior
+ toggleOpen();
+ }
+ else
+ {
+ getRoot()->setSelection(this, FALSE);
+ toggleOpen();
+ }
+ handled = TRUE;
+ }
+ return handled;
+}
+
+void LLFolderViewFolder::draw()
+{
+ updateLabelRotation();
+
+ LLFolderViewItem::draw();
+
+ // draw children if root folder, or any other folder that is open or animating to closed state
+ if( getRoot() == this || (isOpen() || mCurHeight != mTargetHeight ))
+ {
+ LLView::draw();
+ }
+
+ mExpanderHighlighted = FALSE;
+}
+
+// this does prefix traversal, as folders are listed above their contents
+LLFolderViewItem* LLFolderViewFolder::getNextFromChild( LLFolderViewItem* item, BOOL include_children )
+{
+ BOOL found_item = FALSE;
+
+ LLFolderViewItem* result = NULL;
+ // when not starting from a given item, start at beginning
+ if(item == NULL)
+ {
+ found_item = TRUE;
+ }
+
+ // find current item among children
+ folders_t::iterator fit = mFolders.begin();
+ folders_t::iterator fend = mFolders.end();
+
+ items_t::iterator iit = mItems.begin();
+ items_t::iterator iend = mItems.end();
+
+ // if not trivially starting at the beginning, we have to find the current item
+ if (!found_item)
+ {
+ // first, look among folders, since they are always above items
+ for(; fit != fend; ++fit)
+ {
+ if(item == (*fit))
+ {
+ found_item = TRUE;
+ // if we are on downwards traversal
+ if (include_children && (*fit)->isOpen())
+ {
+ // look for first descendant
+ return (*fit)->getNextFromChild(NULL, TRUE);
+ }
+ // otherwise advance to next folder
+ ++fit;
+ include_children = TRUE;
+ break;
+ }
+ }
+
+ // didn't find in folders? Check items...
+ if (!found_item)
+ {
+ for(; iit != iend; ++iit)
+ {
+ if(item == (*iit))
+ {
+ found_item = TRUE;
+ // point to next item
+ ++iit;
+ break;
+ }
+ }
+ }
+ }
+
+ if (!found_item)
+ {
+ // you should never call this method with an item that isn't a child
+ // so we should always find something
+ llassert(FALSE);
+ return NULL;
+ }
+
+ // at this point, either iit or fit point to a candidate "next" item
+ // if both are out of range, we need to punt up to our parent
+
+ // now, starting from found folder, continue through folders
+ // searching for next visible folder
+ while(fit != fend && !(*fit)->getVisible())
+ {
+ // turn on downwards traversal for next folder
+ ++fit;
+ }
+
+ if (fit != fend)
+ {
+ result = (*fit);
+ }
+ else
+ {
+ // otherwise, scan for next visible item
+ while(iit != iend && !(*iit)->getVisible())
+ {
+ ++iit;
+ }
+
+ // check to see if we have a valid item
+ if (iit != iend)
+ {
+ result = (*iit);
+ }
+ }
+
+ if( !result && mParentFolder )
+ {
+ // If there are no siblings or children to go to, recurse up one level in the tree
+ // and skip children for this folder, as we've already discounted them
+ result = mParentFolder->getNextFromChild(this, FALSE);
+ }
+
+ return result;
+}
+
+// this does postfix traversal, as folders are listed above their contents
+LLFolderViewItem* LLFolderViewFolder::getPreviousFromChild( LLFolderViewItem* item, BOOL include_children )
+{
+ BOOL found_item = FALSE;
+
+ LLFolderViewItem* result = NULL;
+ // when not starting from a given item, start at end
+ if(item == NULL)
+ {
+ found_item = TRUE;
+ }
+
+ // find current item among children
+ folders_t::reverse_iterator fit = mFolders.rbegin();
+ folders_t::reverse_iterator fend = mFolders.rend();
+
+ items_t::reverse_iterator iit = mItems.rbegin();
+ items_t::reverse_iterator iend = mItems.rend();
+
+ // if not trivially starting at the end, we have to find the current item
+ if (!found_item)
+ {
+ // first, look among items, since they are always below the folders
+ for(; iit != iend; ++iit)
+ {
+ if(item == (*iit))
+ {
+ found_item = TRUE;
+ // point to next item
+ ++iit;
+ break;
+ }
+ }
+
+ // didn't find in items? Check folders...
+ if (!found_item)
+ {
+ for(; fit != fend; ++fit)
+ {
+ if(item == (*fit))
+ {
+ found_item = TRUE;
+ // point to next folder
+ ++fit;
+ break;
+ }
+ }
+ }
+ }
+
+ if (!found_item)
+ {
+ // you should never call this method with an item that isn't a child
+ // so we should always find something
+ llassert(FALSE);
+ return NULL;
+ }
+
+ // at this point, either iit or fit point to a candidate "next" item
+ // if both are out of range, we need to punt up to our parent
+
+ // now, starting from found item, continue through items
+ // searching for next visible item
+ while(iit != iend && !(*iit)->getVisible())
+ {
+ ++iit;
+ }
+
+ if (iit != iend)
+ {
+ // we found an appropriate item
+ result = (*iit);
+ }
+ else
+ {
+ // otherwise, scan for next visible folder
+ while(fit != fend && !(*fit)->getVisible())
+ {
+ ++fit;
+ }
+
+ // check to see if we have a valid folder
+ if (fit != fend)
+ {
+ // try selecting child element of this folder
+ if ((*fit)->isOpen() && include_children)
+ {
+ result = (*fit)->getPreviousFromChild(NULL);
+ }
+ else
+ {
+ result = (*fit);
+ }
+ }
+ }
+
+ if( !result )
+ {
+ // If there are no siblings or children to go to, recurse up one level in the tree
+ // which gets back to this folder, which will only be visited if it is a valid, visible item
+ result = this;
+ }
+
+ return result;
+}
+
diff --git a/indra/llui/llfolderviewitem.h b/indra/llui/llfolderviewitem.h
new file mode 100644
index 0000000000..a9b0201236
--- /dev/null
+++ b/indra/llui/llfolderviewitem.h
@@ -0,0 +1,457 @@
+/**
+* @file llfolderviewitem.h
+* @brief Items and folders that can appear in a hierarchical folder view
+*
+* $LicenseInfo:firstyear=2001&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$
+*/
+#ifndef LLFOLDERVIEWITEM_H
+#define LLFOLDERVIEWITEM_H
+
+#include "llflashtimer.h"
+#include "llview.h"
+#include "lluiimage.h"
+
+class LLFolderView;
+class LLFolderViewModelItem;
+class LLFolderViewFolder;
+class LLFolderViewFunctor;
+class LLFolderViewFilter;
+class LLFolderViewModelInterface;
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Class LLFolderViewItem
+//
+// An instance of this class represents a single item in a folder view
+// such as an inventory item or a file.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+class LLFolderViewItem : public LLView
+{
+public:
+ struct Params : public LLInitParam::Block<Params, LLView::Params>
+ {
+ Optional<LLUIImage*> folder_arrow_image,
+ selection_image;
+ Mandatory<LLFolderView*> root;
+ Mandatory<LLFolderViewModelItem*> listener;
+
+ Optional<S32> folder_indentation, // pixels
+ item_height,
+ item_top_pad;
+
+ Optional<time_t> creation_date;
+ Optional<bool> allow_open;
+
+ Optional<LLUIColor> font_color;
+ Optional<LLUIColor> font_highlight_color;
+
+ Optional<S32> left_pad,
+ icon_pad,
+ icon_width,
+ text_pad,
+ text_pad_right,
+ arrow_size,
+ max_folder_item_overlap;
+ Params();
+ };
+
+
+ static const S32 DEFAULT_LABEL_PADDING_RIGHT = 4;
+ // animation parameters
+ static const F32 FOLDER_CLOSE_TIME_CONSTANT,
+ FOLDER_OPEN_TIME_CONSTANT;
+
+protected:
+ friend class LLUICtrlFactory;
+ friend class LLFolderViewModelItem;
+
+ LLFolderViewItem(const Params& p);
+
+ std::string mLabel;
+ S32 mLabelWidth;
+ bool mLabelWidthDirty;
+ S32 mLabelPaddingRight;
+ LLFolderViewFolder* mParentFolder;
+ LLPointer<LLFolderViewModelItem> mViewModelItem;
+ LLFontGL::StyleFlags mLabelStyle;
+ std::string mLabelSuffix;
+ LLUIImagePtr mIcon,
+ mIconOpen,
+ mIconOverlay;
+ S32 mLocalIndentation;
+ S32 mIndentation;
+ S32 mItemHeight;
+ S32 mDragStartX,
+ mDragStartY;
+
+ S32 mLeftPad,
+ mIconPad,
+ mIconWidth,
+ mTextPad,
+ mTextPadRight,
+ mArrowSize,
+ mMaxFolderItemOverlap;
+
+ F32 mControlLabelRotation;
+ LLFolderView* mRoot;
+ bool mHasVisibleChildren,
+ mIsCurSelection,
+ mDragAndDropTarget,
+ mIsMouseOverTitle,
+ mAllowOpen,
+ mSelectPending;
+
+ LLUIColor mFontColor;
+ LLUIColor mFontHighlightColor;
+
+ // For now assuming all colors are the same in derived classes.
+ static bool sColorSetInitialized;
+ static LLUIColor sFgColor;
+ static LLUIColor sFgDisabledColor;
+ static LLUIColor sHighlightBgColor;
+ static LLUIColor sFlashBgColor;
+ static LLUIColor sFocusOutlineColor;
+ static LLUIColor sMouseOverColor;
+ static LLUIColor sFilterBGColor;
+ static LLUIColor sFilterTextColor;
+ static LLUIColor sSuffixColor;
+ static LLUIColor sSearchStatusColor;
+
+ // this is an internal method used for adding items to folders. A
+ // no-op at this level, but reimplemented in derived classes.
+ virtual void addItem(LLFolderViewItem*) { }
+ virtual void addFolder(LLFolderViewFolder*) { }
+ virtual bool isHighlightAllowed();
+ virtual bool isHighlightActive();
+ virtual bool isFlashing() { return false; }
+ virtual void setFlashState(bool) { }
+
+ static LLFontGL* getLabelFontForStyle(U8 style);
+
+ BOOL mIsSelected;
+
+public:
+ static void initClass();
+ static void cleanupClass();
+
+ BOOL postBuild();
+
+ virtual void openItem( void );
+
+ void arrangeAndSet(BOOL set_selection, BOOL take_keyboard_focus);
+
+ virtual ~LLFolderViewItem( void );
+
+ // addToFolder() returns TRUE if it succeeds. FALSE otherwise
+ virtual void addToFolder(LLFolderViewFolder* folder);
+
+ // Finds width and height of this object and it's children. Also
+ // makes sure that this view and it's children are the right size.
+ virtual S32 arrange( S32* width, S32* height );
+ virtual S32 getItemHeight();
+ virtual S32 getLabelXPos();
+ S32 getIconPad();
+ S32 getTextPad();
+
+ // If 'selection' is 'this' then note that otherwise ignore.
+ // Returns TRUE if this item ends up being selected.
+ virtual BOOL setSelection(LLFolderViewItem* selection, BOOL openitem, BOOL take_keyboard_focus);
+
+ // This method is used to set the selection state of an item.
+ // If 'selection' is 'this' then note selection.
+ // Returns TRUE if the selection state of this item was changed.
+ virtual BOOL changeSelection(LLFolderViewItem* selection, BOOL selected);
+
+ // this method is used to deselect this element
+ void deselectItem();
+
+ // this method is used to select this element
+ virtual void selectItem();
+
+ // gets multiple-element selection
+ virtual std::set<LLFolderViewItem*> getSelectionList() const;
+
+ // Returns true is this object and all of its children can be removed (deleted by user)
+ virtual BOOL isRemovable();
+
+ // Returns true is this object and all of its children can be moved
+ virtual BOOL isMovable();
+
+ // destroys this item recursively
+ virtual void destroyView();
+
+ BOOL isSelected() const { return mIsSelected; }
+ bool isInSelection() const;
+
+ void setUnselected() { mIsSelected = FALSE; }
+
+ void setIsCurSelection(BOOL select) { mIsCurSelection = select; }
+
+ BOOL getIsCurSelection() { return mIsCurSelection; }
+
+ BOOL hasVisibleChildren() { return mHasVisibleChildren; }
+
+ // Call through to the viewed object and return true if it can be
+ // removed. Returns true if it's removed.
+ //virtual BOOL removeRecursively(BOOL single_item);
+ BOOL remove();
+
+ // Build an appropriate context menu for the item. Flags unused.
+ void buildContextMenu(class LLMenuGL& menu, U32 flags);
+
+ // This method returns the actual name of the thing being
+ // viewed. This method will ask the viewed object itself.
+ const std::string& getName( void ) const;
+
+ // This method returns the label displayed on the view. This
+ // method was primarily added to allow sorting on the folder
+ // contents possible before the entire view has been constructed.
+ const std::string& getLabel() const { return mLabel; }
+
+ LLFolderViewFolder* getParentFolder( void ) { return mParentFolder; }
+ const LLFolderViewFolder* getParentFolder( void ) const { return mParentFolder; }
+
+ void setParentFolder(LLFolderViewFolder* parent) { mParentFolder = parent; }
+
+ LLFolderViewItem* getNextOpenNode( BOOL include_children = TRUE );
+ LLFolderViewItem* getPreviousOpenNode( BOOL include_children = TRUE );
+
+ const LLFolderViewModelItem* getViewModelItem( void ) const { return mViewModelItem; }
+ LLFolderViewModelItem* getViewModelItem( void ) { return mViewModelItem; }
+
+ const LLFolderViewModelInterface* getFolderViewModel( void ) const;
+ LLFolderViewModelInterface* getFolderViewModel( void );
+
+ // just rename the object.
+ void rename(const std::string& new_name);
+
+ // Show children
+ virtual void setOpen(BOOL open = TRUE) {};
+ virtual BOOL isOpen() const { return FALSE; }
+
+ virtual LLFolderView* getRoot();
+ virtual const LLFolderView* getRoot() const;
+ BOOL isDescendantOf( const LLFolderViewFolder* potential_ancestor );
+ S32 getIndentation() { return mIndentation; }
+
+ virtual BOOL passedFilter(S32 filter_generation = -1);
+
+ // refresh information from the object being viewed.
+ virtual void refresh();
+
+ // LLView functionality
+ virtual BOOL handleRightMouseDown( S32 x, S32 y, MASK mask );
+ virtual BOOL handleMouseDown( S32 x, S32 y, MASK mask );
+ virtual BOOL handleHover( S32 x, S32 y, MASK mask );
+ virtual BOOL handleMouseUp( S32 x, S32 y, MASK mask );
+ virtual BOOL handleDoubleClick( S32 x, S32 y, MASK mask );
+
+ virtual void onMouseLeave(S32 x, S32 y, MASK mask);
+
+ //virtual LLView* findChildView(const std::string& name, BOOL recurse) const { return LLView::findChildView(name, recurse); }
+
+ // virtual void handleDropped();
+ virtual void draw();
+ void drawOpenFolderArrow(const Params& default_params, const LLUIColor& fg_color);
+ void drawHighlight(const BOOL showContent, const BOOL hasKeyboardFocus, const LLUIColor &selectColor, const LLUIColor &flashColor, const LLUIColor &outlineColor, const LLUIColor &mouseOverColor);
+ void drawLabel(const LLFontGL * font, const F32 x, const F32 y, const LLColor4& color, F32 &right_x);
+ virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
+ EDragAndDropType cargo_type,
+ void* cargo_data,
+ EAcceptance* accept,
+ std::string& tooltip_msg);
+
+private:
+ static std::map<U8, LLFontGL*> sFonts; // map of styles to fonts
+};
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Class LLFolderViewFolder
+//
+// An instance of an LLFolderViewFolder represents a collection of
+// more folders and items. This is used to build the hierarchy of
+// items found in the folder view.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+class LLFolderViewFolder : public LLFolderViewItem
+{
+protected:
+ LLFolderViewFolder( const LLFolderViewItem::Params& );
+ friend class LLUICtrlFactory;
+
+ void updateLabelRotation();
+ virtual bool isCollapsed() { return FALSE; }
+
+public:
+ typedef std::list<LLFolderViewItem*> items_t;
+ typedef std::list<LLFolderViewFolder*> folders_t;
+
+protected:
+ items_t mItems;
+ folders_t mFolders;
+
+ BOOL mIsOpen;
+ BOOL mExpanderHighlighted;
+ F32 mCurHeight;
+ F32 mTargetHeight;
+ F32 mAutoOpenCountdown;
+ S32 mLastArrangeGeneration;
+ S32 mLastCalculatedWidth;
+ bool mNeedsSort;
+
+public:
+ typedef enum e_recurse_type
+ {
+ RECURSE_NO,
+ RECURSE_UP,
+ RECURSE_DOWN,
+ RECURSE_UP_DOWN
+ } ERecurseType;
+
+
+ virtual ~LLFolderViewFolder( void );
+
+ LLFolderViewItem* getNextFromChild( LLFolderViewItem*, BOOL include_children = TRUE );
+ LLFolderViewItem* getPreviousFromChild( LLFolderViewItem*, BOOL include_children = TRUE );
+
+ // addToFolder() returns TRUE if it succeeds. FALSE otherwise
+ virtual void addToFolder(LLFolderViewFolder* folder);
+
+ // Finds width and height of this object and it's children. Also
+ // makes sure that this view and it's children are the right size.
+ virtual S32 arrange( S32* width, S32* height );
+
+ BOOL needsArrange();
+
+ bool descendantsPassedFilter(S32 filter_generation = -1);
+
+ // Passes selection information on to children and record
+ // selection information if necessary.
+ // Returns TRUE if this object (or a child) ends up being selected.
+ // If 'openitem' is TRUE then folders are opened up along the way to the selection.
+ virtual BOOL setSelection(LLFolderViewItem* selection, BOOL openitem, BOOL take_keyboard_focus = TRUE);
+
+ // This method is used to change the selection of an item.
+ // Recursively traverse all children; if 'selection' is 'this' then change
+ // the select status if necessary.
+ // Returns TRUE if the selection state of this folder, or of a child, was changed.
+ virtual BOOL changeSelection(LLFolderViewItem* selection, BOOL selected);
+
+ // this method is used to group select items
+ void extendSelectionTo(LLFolderViewItem* selection);
+
+ // Returns true is this object and all of its children can be removed.
+ virtual BOOL isRemovable();
+
+ // Returns true is this object and all of its children can be moved
+ virtual BOOL isMovable();
+
+ // destroys this folder, and all children
+ virtual void destroyView();
+
+ // extractItem() removes the specified item from the folder, but
+ // doesn't delete it.
+ virtual void extractItem( LLFolderViewItem* item );
+
+ // This function is called by a child that needs to be resorted.
+ void resort(LLFolderViewItem* item);
+
+ void setAutoOpenCountdown(F32 countdown) { mAutoOpenCountdown = countdown; }
+
+ // folders can be opened. This will usually be called by internal
+ // methods.
+ virtual void toggleOpen();
+
+ // Force a folder open or closed
+ virtual void setOpen(BOOL openitem = TRUE);
+
+ // Called when a child is refreshed.
+ virtual void requestArrange();
+
+ // internal method which doesn't update the entire view. This
+ // method was written because the list iterators destroy the state
+ // of other iterations, thus, we can't arrange while iterating
+ // through the children (such as when setting which is selected.
+ virtual void setOpenArrangeRecursively(BOOL openitem, ERecurseType recurse = RECURSE_NO);
+
+ // Get the current state of the folder.
+ virtual BOOL isOpen() const { return mIsOpen; }
+
+ // special case if an object is dropped on the child.
+ BOOL handleDragAndDropFromChild(MASK mask,
+ BOOL drop,
+ EDragAndDropType cargo_type,
+ void* cargo_data,
+ EAcceptance* accept,
+ std::string& tooltip_msg);
+
+
+ // Just apply this functor to the folder's immediate children.
+ void applyFunctorToChildren(LLFolderViewFunctor& functor);
+ // apply this functor to the folder's descendants.
+ void applyFunctorRecursively(LLFolderViewFunctor& functor);
+
+ virtual void openItem( void );
+
+ // LLView functionality
+ virtual BOOL handleHover(S32 x, S32 y, MASK mask);
+ virtual BOOL handleRightMouseDown( S32 x, S32 y, MASK mask );
+ virtual BOOL handleMouseDown( S32 x, S32 y, MASK mask );
+ virtual BOOL handleDoubleClick( S32 x, S32 y, MASK mask );
+ virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask,
+ BOOL drop,
+ EDragAndDropType cargo_type,
+ void* cargo_data,
+ EAcceptance* accept,
+ std::string& tooltip_msg);
+ BOOL handleDragAndDropToThisFolder(MASK mask,
+ BOOL drop,
+ EDragAndDropType cargo_type,
+ void* cargo_data,
+ EAcceptance* accept,
+ std::string& tooltip_msg);
+ virtual void draw();
+
+ folders_t::iterator getFoldersBegin() { return mFolders.begin(); }
+ folders_t::iterator getFoldersEnd() { return mFolders.end(); }
+ folders_t::size_type getFoldersCount() const { return mFolders.size(); }
+
+ items_t::const_iterator getItemsBegin() const { return mItems.begin(); }
+ items_t::const_iterator getItemsEnd() const { return mItems.end(); }
+ items_t::size_type getItemsCount() const { return mItems.size(); }
+
+ LLFolderViewFolder* getCommonAncestor(LLFolderViewItem* item_a, LLFolderViewItem* item_b, bool& reverse);
+ void gatherChildRangeExclusive(LLFolderViewItem* start, LLFolderViewItem* end, bool reverse, std::vector<LLFolderViewItem*>& items);
+
+ // internal functions for tracking folders and items separately
+ // use addToFolder() virtual method to ensure folders are always added to mFolders
+ // and not mItems
+ void addItem(LLFolderViewItem* item);
+ void addFolder( LLFolderViewFolder* folder);
+
+ //WARNING: do not call directly...use the appropriate LLFolderViewModel-derived class instead
+ template<typename SORT_FUNC> void sortFolders(const SORT_FUNC& func) { mFolders.sort(func); }
+ template<typename SORT_FUNC> void sortItems(const SORT_FUNC& func) { mItems.sort(func); }
+};
+
+
+#endif // LLFOLDERVIEWITEM_H
diff --git a/indra/llui/llfolderviewmodel.cpp b/indra/llui/llfolderviewmodel.cpp
new file mode 100755
index 0000000000..3363dc5316
--- /dev/null
+++ b/indra/llui/llfolderviewmodel.cpp
@@ -0,0 +1,68 @@
+/**
+ * @file llfolderviewmodel.cpp
+ * @brief Implementation of the view model collection of classes.
+ *
+ * $LicenseInfo:firstyear=2001&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 "llfolderviewmodel.h"
+#include "lltrans.h"
+
+bool LLFolderViewModelCommon::needsSort(LLFolderViewModelItem* item)
+{
+ return item->getSortVersion() < mTargetSortVersion;
+}
+
+std::string LLFolderViewModelCommon::getStatusText()
+{
+ if (!contentsReady() || mFolderView->getViewModelItem()->getLastFilterGeneration() < getFilter().getCurrentGeneration())
+ {
+ return LLTrans::getString("Searching");
+ }
+ else
+ {
+ return getFilter().getEmptyLookupMessage();
+ }
+}
+
+void LLFolderViewModelCommon::filter()
+{
+ getFilter().resetTime(llclamp(LLUI::sSettingGroups["config"]->getS32("FilterItemsMaxTimePerFrameVisible"), 1, 100));
+ mFolderView->getViewModelItem()->filter(getFilter());
+}
+
+bool LLFolderViewModelItemCommon::hasFilterStringMatch()
+{
+ return mStringMatchOffsetFilter != std::string::npos;
+}
+
+std::string::size_type LLFolderViewModelItemCommon::getFilterStringOffset()
+{
+ return mStringMatchOffsetFilter;
+}
+
+std::string::size_type LLFolderViewModelItemCommon::getFilterStringSize()
+{
+ return mRootViewModel.getFilter().getFilterStringSize();
+}
diff --git a/indra/llui/llfolderviewmodel.h b/indra/llui/llfolderviewmodel.h
new file mode 100755
index 0000000000..b1bcc8bbb4
--- /dev/null
+++ b/indra/llui/llfolderviewmodel.h
@@ -0,0 +1,445 @@
+/**
+ * @file llfolderviewmodel.h
+ *
+ * $LicenseInfo:firstyear=2001&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$
+ */
+#ifndef LLFOLDERVIEWMODEL_H
+#define LLFOLDERVIEWMODEL_H
+
+#include "llfontgl.h" // just for StyleFlags enum
+#include "llfolderview.h"
+
+// These are grouping of inventory types.
+// Order matters when sorting system folders to the top.
+enum EInventorySortGroup
+{
+ SG_SYSTEM_FOLDER,
+ SG_TRASH_FOLDER,
+ SG_NORMAL_FOLDER,
+ SG_ITEM
+};
+
+class LLFontGL;
+class LLInventoryModel;
+class LLMenuGL;
+class LLUIImage;
+class LLUUID;
+class LLFolderViewItem;
+class LLFolderViewFolder;
+
+class LLFolderViewFilter
+{
+public:
+ enum EFilterModified
+ {
+ FILTER_NONE, // nothing to do, already filtered
+ FILTER_RESTART, // restart filtering from scratch
+ FILTER_LESS_RESTRICTIVE, // existing filtered items will certainly pass this filter
+ FILTER_MORE_RESTRICTIVE // if you didn't pass the previous filter, you definitely won't pass this one
+ };
+
+public:
+
+ LLFolderViewFilter() {}
+ virtual ~LLFolderViewFilter() {}
+
+ // +-------------------------------------------------------------------+
+ // + Execution And Results
+ // +-------------------------------------------------------------------+
+ virtual bool check(const LLFolderViewModelItem* item) = 0;
+ virtual bool checkFolder(const LLFolderViewModelItem* folder) const = 0;
+
+ virtual void setEmptyLookupMessage(const std::string& message) = 0;
+ virtual std::string getEmptyLookupMessage() const = 0;
+
+ virtual bool showAllResults() const = 0;
+
+ virtual std::string::size_type getStringMatchOffset(LLFolderViewModelItem* item) const = 0;
+ virtual std::string::size_type getFilterStringSize() const = 0;
+ // +-------------------------------------------------------------------+
+ // + Status
+ // +-------------------------------------------------------------------+
+ virtual bool isActive() const = 0;
+ virtual bool isModified() const = 0;
+ virtual void clearModified() = 0;
+ virtual const std::string& getName() const = 0;
+ virtual const std::string& getFilterText() = 0;
+ //RN: this is public to allow system to externally force a global refilter
+ virtual void setModified(EFilterModified behavior = FILTER_RESTART) = 0;
+
+ // +-------------------------------------------------------------------+
+ // + Time
+ // +-------------------------------------------------------------------+
+ virtual void resetTime(S32 timeout) = 0;
+ virtual bool isTimedOut() = 0;
+
+ // +-------------------------------------------------------------------+
+ // + Default
+ // +-------------------------------------------------------------------+
+ virtual bool isDefault() const = 0;
+ virtual bool isNotDefault() const = 0;
+ virtual void markDefault() = 0;
+ virtual void resetDefault() = 0;
+
+ // +-------------------------------------------------------------------+
+ // + Generation
+ // +-------------------------------------------------------------------+
+ virtual S32 getCurrentGeneration() const = 0;
+ virtual S32 getFirstSuccessGeneration() const = 0;
+ virtual S32 getFirstRequiredGeneration() const = 0;
+};
+
+class LLFolderViewModelInterface
+{
+public:
+ virtual ~LLFolderViewModelInterface() {}
+ virtual void requestSortAll() = 0;
+
+ virtual void sort(class LLFolderViewFolder*) = 0;
+ virtual void filter() = 0;
+
+ virtual bool contentsReady() = 0;
+ virtual void setFolderView(LLFolderView* folder_view) = 0;
+ virtual LLFolderViewFilter& getFilter() = 0;
+ virtual const LLFolderViewFilter& getFilter() const = 0;
+ virtual std::string getStatusText() = 0;
+
+ virtual bool startDrag(std::vector<LLFolderViewModelItem*>& items) = 0;
+};
+
+// This is an abstract base class that users of the folderview classes
+// would use to bridge the folder view with the underlying data
+class LLFolderViewModelItem : public LLRefCount
+{
+public:
+ LLFolderViewModelItem() { }
+ virtual ~LLFolderViewModelItem() { }
+
+ virtual void update() {} //called when drawing
+ virtual const std::string& getName() const = 0;
+ virtual const std::string& getDisplayName() const = 0;
+ virtual const std::string& getSearchableName() const = 0;
+
+ virtual LLPointer<LLUIImage> getIcon() const = 0;
+ virtual LLPointer<LLUIImage> getIconOpen() const { return getIcon(); }
+ virtual LLPointer<LLUIImage> getIconOverlay() const { return NULL; }
+
+ virtual LLFontGL::StyleFlags getLabelStyle() const = 0;
+ virtual std::string getLabelSuffix() const = 0;
+
+ virtual void openItem( void ) = 0;
+ virtual void closeItem( void ) = 0;
+ virtual void selectItem(void) = 0;
+
+ virtual BOOL isItemRenameable() const = 0;
+ virtual BOOL renameItem(const std::string& new_name) = 0;
+
+ virtual BOOL isItemMovable( void ) const = 0; // Can be moved to another folder
+ virtual void move( LLFolderViewModelItem* parent_listener ) = 0;
+
+ virtual BOOL isItemRemovable( void ) const = 0; // Can be destroyed
+ virtual BOOL removeItem() = 0;
+ virtual void removeBatch(std::vector<LLFolderViewModelItem*>& batch) = 0;
+
+ virtual BOOL isItemCopyable() const = 0;
+ virtual BOOL copyToClipboard() const = 0;
+ virtual BOOL cutToClipboard() const = 0;
+
+ virtual BOOL isClipboardPasteable() const = 0;
+ virtual void pasteFromClipboard() = 0;
+ virtual void pasteLinkFromClipboard() = 0;
+
+ virtual void buildContextMenu(LLMenuGL& menu, U32 flags) = 0;
+
+ virtual bool potentiallyVisible() = 0; // is the item definitely visible or we haven't made up our minds yet?
+
+ virtual bool filter( LLFolderViewFilter& filter) = 0;
+ virtual bool passedFilter(S32 filter_generation = -1) = 0;
+ virtual bool descendantsPassedFilter(S32 filter_generation = -1) = 0;
+ virtual void setPassedFilter(bool passed, S32 filter_generation, std::string::size_type string_offset = std::string::npos, std::string::size_type string_size = 0) = 0;
+ virtual void setPassedFolderFilter(bool passed, S32 filter_generation) = 0;
+ virtual void dirtyFilter() = 0;
+ virtual bool hasFilterStringMatch() = 0;
+ virtual std::string::size_type getFilterStringOffset() = 0;
+ virtual std::string::size_type getFilterStringSize() = 0;
+
+ virtual S32 getLastFilterGeneration() const = 0;
+
+ virtual bool hasChildren() const = 0;
+ virtual void addChild(LLFolderViewModelItem* child) = 0;
+ virtual void removeChild(LLFolderViewModelItem* child) = 0;
+
+ // This method will be called to determine if a drop can be
+ // performed, and will set drop to TRUE if a drop is
+ // requested. Returns TRUE if a drop is possible/happened,
+ // otherwise FALSE.
+ virtual BOOL dragOrDrop(MASK mask, BOOL drop,
+ EDragAndDropType cargo_type,
+ void* cargo_data,
+ std::string& tooltip_msg) = 0;
+
+ virtual void requestSort() = 0;
+ virtual S32 getSortVersion() = 0;
+ virtual void setSortVersion(S32 version) = 0;
+ virtual void setParent(LLFolderViewModelItem* parent) = 0;
+ virtual bool hasParent() = 0;
+
+protected:
+
+ friend class LLFolderViewItem;
+ virtual void setFolderViewItem(LLFolderViewItem* folder_view_item) = 0;
+
+};
+
+
+class LLFolderViewModelItemCommon : public LLFolderViewModelItem
+{
+public:
+ LLFolderViewModelItemCommon(LLFolderViewModelInterface& root_view_model)
+ : mSortVersion(-1),
+ mPassedFilter(true),
+ mPassedFolderFilter(true),
+ mStringMatchOffsetFilter(std::string::npos),
+ mStringFilterSize(0),
+ mFolderViewItem(NULL),
+ mLastFilterGeneration(-1),
+ mLastFolderFilterGeneration(-1),
+ mMostFilteredDescendantGeneration(-1),
+ mParent(NULL),
+ mRootViewModel(root_view_model)
+ {
+ mChildren.clear();
+ }
+
+ void requestSort() { mSortVersion = -1; }
+ S32 getSortVersion() { return mSortVersion; }
+ void setSortVersion(S32 version) { mSortVersion = version;}
+
+ S32 getLastFilterGeneration() const { return mLastFilterGeneration; }
+ S32 getLastFolderFilterGeneration() const { return mLastFolderFilterGeneration; }
+ void dirtyFilter()
+ {
+ mLastFilterGeneration = -1;
+ mLastFolderFilterGeneration = -1;
+
+ // bubble up dirty flag all the way to root
+ if (mParent)
+ {
+ mParent->dirtyFilter();
+ }
+ }
+ bool hasFilterStringMatch();
+ std::string::size_type getFilterStringOffset();
+ std::string::size_type getFilterStringSize();
+
+ typedef std::list<LLFolderViewModelItem*> child_list_t;
+
+ virtual void addChild(LLFolderViewModelItem* child)
+ {
+ // Avoid duplicates: bail out if that child is already present in the list
+ // Note: this happens when models are created before views
+ child_list_t::const_iterator iter;
+ for (iter = mChildren.begin(); iter != mChildren.end(); iter++)
+ {
+ if (child == *iter)
+ {
+ return;
+ }
+ }
+ mChildren.push_back(child);
+ child->setParent(this);
+ dirtyFilter();
+ requestSort();
+ }
+ virtual void removeChild(LLFolderViewModelItem* child)
+ {
+ mChildren.remove(child);
+ child->setParent(NULL);
+ dirtyFilter();
+ }
+
+ virtual void clearChildren()
+ {
+ // As this is cleaning the whole list of children wholesale, we do need to delete the pointed objects
+ // This is different and not equivalent to calling removeChild() on each child
+ std::for_each(mChildren.begin(), mChildren.end(), DeletePointer());
+ mChildren.clear();
+ dirtyFilter();
+ }
+
+ child_list_t::const_iterator getChildrenBegin() const { return mChildren.begin(); }
+ child_list_t::const_iterator getChildrenEnd() const { return mChildren.end(); }
+ child_list_t::size_type getChildrenCount() const { return mChildren.size(); }
+
+ void setPassedFilter(bool passed, S32 filter_generation, std::string::size_type string_offset = std::string::npos, std::string::size_type string_size = 0)
+ {
+ mPassedFilter = passed;
+ mLastFilterGeneration = filter_generation;
+ mStringMatchOffsetFilter = string_offset;
+ mStringFilterSize = string_size;
+ }
+
+ void setPassedFolderFilter(bool passed, S32 filter_generation)
+ {
+ mPassedFolderFilter = passed;
+ mLastFolderFilterGeneration = filter_generation;
+ }
+
+ virtual bool potentiallyVisible()
+ {
+ return passedFilter() // we've passed the filter
+ || (getLastFilterGeneration() < mRootViewModel.getFilter().getFirstSuccessGeneration()) // or we don't know yet
+ || descendantsPassedFilter();
+ }
+
+ virtual bool passedFilter(S32 filter_generation = -1)
+ {
+ if (filter_generation < 0)
+ {
+ filter_generation = mRootViewModel.getFilter().getFirstSuccessGeneration();
+ }
+ bool passed_folder_filter = mPassedFolderFilter && (mLastFolderFilterGeneration >= filter_generation);
+ bool passed_filter = mPassedFilter && (mLastFilterGeneration >= filter_generation);
+ return passed_folder_filter && (passed_filter || descendantsPassedFilter(filter_generation));
+ }
+
+ virtual bool descendantsPassedFilter(S32 filter_generation = -1)
+ {
+ if (filter_generation < 0)
+ {
+ filter_generation = mRootViewModel.getFilter().getFirstSuccessGeneration();
+ }
+ return mMostFilteredDescendantGeneration >= filter_generation;
+ }
+
+
+protected:
+ virtual void setParent(LLFolderViewModelItem* parent) { mParent = parent; }
+ virtual bool hasParent() { return mParent != NULL; }
+
+ S32 mSortVersion;
+ bool mPassedFilter;
+ bool mPassedFolderFilter;
+ std::string::size_type mStringMatchOffsetFilter;
+ std::string::size_type mStringFilterSize;
+
+ S32 mLastFilterGeneration;
+ S32 mLastFolderFilterGeneration;
+ S32 mMostFilteredDescendantGeneration;
+
+ child_list_t mChildren;
+ LLFolderViewModelItem* mParent;
+ LLFolderViewModelInterface& mRootViewModel;
+
+ void setFolderViewItem(LLFolderViewItem* folder_view_item) { mFolderViewItem = folder_view_item;}
+ LLFolderViewItem* mFolderViewItem;
+};
+
+
+
+class LLFolderViewModelCommon : public LLFolderViewModelInterface
+{
+public:
+ LLFolderViewModelCommon()
+ : mTargetSortVersion(0),
+ mFolderView(NULL)
+ {}
+
+ virtual void requestSortAll()
+ {
+ // sort everything
+ mTargetSortVersion++;
+ }
+ virtual std::string getStatusText();
+ virtual void filter();
+
+ void setFolderView(LLFolderView* folder_view) { mFolderView = folder_view;}
+
+protected:
+ bool needsSort(class LLFolderViewModelItem* item);
+
+ S32 mTargetSortVersion;
+ LLFolderView* mFolderView;
+
+};
+
+template <typename SORT_TYPE, typename ITEM_TYPE, typename FOLDER_TYPE, typename FILTER_TYPE>
+class LLFolderViewModel : public LLFolderViewModelCommon
+{
+public:
+ LLFolderViewModel(){}
+ virtual ~LLFolderViewModel() {}
+
+ typedef SORT_TYPE SortType;
+ typedef ITEM_TYPE ItemType;
+ typedef FOLDER_TYPE FolderType;
+ typedef FILTER_TYPE FilterType;
+
+ virtual SortType& getSorter() { return mSorter; }
+ virtual const SortType& getSorter() const { return mSorter; }
+ virtual void setSorter(const SortType& sorter) { mSorter = sorter; requestSortAll(); }
+
+ virtual FilterType& getFilter() { return mFilter; }
+ virtual const FilterType& getFilter() const { return mFilter; }
+ virtual void setFilter(const FilterType& filter) { mFilter = filter; }
+
+ // By default, we assume the content is available. If a network fetch mechanism is implemented for the model,
+ // this method needs to be overloaded and return the relevant fetch status.
+ virtual bool contentsReady() { return true; }
+
+
+ struct ViewModelCompare
+ {
+ ViewModelCompare(const SortType& sorter)
+ : mSorter(sorter)
+ {}
+
+ bool operator () (const LLFolderViewItem* a, const LLFolderViewItem* b) const
+ {
+ return mSorter(static_cast<const ItemType*>(a->getViewModelItem()), static_cast<const ItemType*>(b->getViewModelItem()));
+ }
+
+ bool operator () (const LLFolderViewFolder* a, const LLFolderViewFolder* b) const
+ {
+ return mSorter(static_cast<const ItemType*>(a->getViewModelItem()), static_cast<const ItemType*>(b->getViewModelItem()));
+ }
+
+ const SortType& mSorter;
+ };
+
+ void sort(LLFolderViewFolder* folder)
+ {
+ if (needsSort(folder->getViewModelItem()))
+ {
+ folder->sortFolders(ViewModelCompare(getSorter()));
+ folder->sortItems(ViewModelCompare(getSorter()));
+ folder->getViewModelItem()->setSortVersion(mTargetSortVersion);
+ folder->requestArrange();
+ }
+ }
+
+protected:
+ SortType mSorter;
+ FilterType mFilter;
+};
+
+#endif // LLFOLDERVIEWMODEL_H
diff --git a/indra/llui/llfunctorregistry.cpp b/indra/llui/llfunctorregistry.cpp
index 8003324973..8003324973 100644..100755
--- a/indra/llui/llfunctorregistry.cpp
+++ b/indra/llui/llfunctorregistry.cpp
diff --git a/indra/llui/llfunctorregistry.h b/indra/llui/llfunctorregistry.h
index 899cc3a326..beac212441 100644..100755
--- a/indra/llui/llfunctorregistry.h
+++ b/indra/llui/llfunctorregistry.h
@@ -69,7 +69,6 @@ public:
bool registerFunctor(const std::string& name, ResponseFunctor f)
{
bool retval = true;
- typename FunctorMap::iterator it = mMap.find(name);
if (mMap.count(name) == 0)
{
mMap[name] = f;
@@ -96,7 +95,6 @@ public:
FUNCTOR_TYPE getFunctor(const std::string& name)
{
- typename FunctorMap::iterator it = mMap.find(name);
if (mMap.count(name) != 0)
{
return mMap[name];
diff --git a/indra/llui/llhandle.h b/indra/llui/llhandle.h
deleted file mode 100644
index 37c657dd92..0000000000
--- a/indra/llui/llhandle.h
+++ /dev/null
@@ -1,181 +0,0 @@
-/**
-* @file llhandle.h
-* @brief "Handle" to an object (usually a floater) whose lifetime you don't
-* control.
-*
-* $LicenseInfo:firstyear=2001&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$
-*/
-#ifndef LLHANDLE_H
-#define LLHANDLE_H
-
-#include "llpointer.h"
-#include <boost/type_traits/is_convertible.hpp>
-#include <boost/utility/enable_if.hpp>
-
-class LLTombStone : public LLRefCount
-{
-public:
- LLTombStone(void* target = NULL) : mTarget(target) {}
-
- void setTarget(void* target) { mTarget = target; }
- void* getTarget() const { return mTarget; }
-private:
- mutable void* mTarget;
-};
-
-// LLHandles are used to refer to objects whose lifetime you do not control or influence.
-// Calling get() on a handle will return a pointer to the referenced object or NULL,
-// if the object no longer exists. Note that during the lifetime of the returned pointer,
-// you are assuming that the object will not be deleted by any action you perform,
-// or any other thread, as normal when using pointers, so avoid using that pointer outside of
-// the local code block.
-//
-// https://wiki.lindenlab.com/mediawiki/index.php?title=LLHandle&oldid=79669
-
-template <typename T>
-class LLHandle
-{
- template <typename U> friend class LLHandle;
- template <typename U> friend class LLHandleProvider;
-public:
- LLHandle() : mTombStone(getDefaultTombStone()) {}
-
- template<typename U>
- LLHandle(const LLHandle<U>& other, typename boost::enable_if< typename boost::is_convertible<U*, T*> >::type* dummy = 0)
- : mTombStone(other.mTombStone)
- {}
-
- bool isDead() const
- {
- return mTombStone->getTarget() == NULL;
- }
-
- void markDead()
- {
- mTombStone = getDefaultTombStone();
- }
-
- T* get() const
- {
- return reinterpret_cast<T*>(mTombStone->getTarget());
- }
-
- friend bool operator== (const LLHandle<T>& lhs, const LLHandle<T>& rhs)
- {
- return lhs.mTombStone == rhs.mTombStone;
- }
- friend bool operator!= (const LLHandle<T>& lhs, const LLHandle<T>& rhs)
- {
- return !(lhs == rhs);
- }
- friend bool operator< (const LLHandle<T>& lhs, const LLHandle<T>& rhs)
- {
- return lhs.mTombStone < rhs.mTombStone;
- }
- friend bool operator> (const LLHandle<T>& lhs, const LLHandle<T>& rhs)
- {
- return lhs.mTombStone > rhs.mTombStone;
- }
-
-protected:
- LLPointer<LLTombStone> mTombStone;
-
-private:
- typedef T* pointer_t;
- static LLPointer<LLTombStone>& getDefaultTombStone()
- {
- static LLPointer<LLTombStone> sDefaultTombStone = new LLTombStone;
- return sDefaultTombStone;
- }
-};
-
-template <typename T>
-class LLRootHandle : public LLHandle<T>
-{
-public:
- typedef LLRootHandle<T> self_t;
- typedef LLHandle<T> base_t;
-
- LLRootHandle(T* object) { bind(object); }
- LLRootHandle() {};
- ~LLRootHandle() { unbind(); }
-
- // this is redundant, since an LLRootHandle *is* an LLHandle
- //LLHandle<T> getHandle() { return LLHandle<T>(*this); }
-
- void bind(T* object)
- {
- // unbind existing tombstone
- if (LLHandle<T>::mTombStone.notNull())
- {
- if (LLHandle<T>::mTombStone->getTarget() == (void*)object) return;
- LLHandle<T>::mTombStone->setTarget(NULL);
- }
- // tombstone reference counted, so no paired delete
- LLHandle<T>::mTombStone = new LLTombStone((void*)object);
- }
-
- void unbind()
- {
- LLHandle<T>::mTombStone->setTarget(NULL);
- }
-
- //don't allow copying of root handles, since there should only be one
-private:
- LLRootHandle(const LLRootHandle& other) {};
-};
-
-// Use this as a mixin for simple classes that need handles and when you don't
-// want handles at multiple points of the inheritance hierarchy
-template <typename T>
-class LLHandleProvider
-{
-public:
- LLHandle<T> getHandle() const
- {
- // perform lazy binding to avoid small tombstone allocations for handle
- // providers whose handles are never referenced
- mHandle.bind(static_cast<T*>(const_cast<LLHandleProvider<T>* >(this)));
- return mHandle;
- }
-
-protected:
- typedef LLHandle<T> handle_type_t;
- LLHandleProvider()
- {
- // provided here to enforce T deriving from LLHandleProvider<T>
- }
-
- template <typename U>
- LLHandle<U> getDerivedHandle(typename boost::enable_if< typename boost::is_convertible<U*, T*> >::type* dummy = 0) const
- {
- LLHandle<U> downcast_handle;
- downcast_handle.mTombStone = getHandle().mTombStone;
- return downcast_handle;
- }
-
-
-private:
- mutable LLRootHandle<T> mHandle;
-};
-
-#endif
diff --git a/indra/llui/llhelp.h b/indra/llui/llhelp.h
index 1726347a78..1726347a78 100644..100755
--- a/indra/llui/llhelp.h
+++ b/indra/llui/llhelp.h
diff --git a/indra/llui/lliconctrl.cpp b/indra/llui/lliconctrl.cpp
index 30b79b4d20..30b79b4d20 100644..100755
--- a/indra/llui/lliconctrl.cpp
+++ b/indra/llui/lliconctrl.cpp
diff --git a/indra/llui/lliconctrl.h b/indra/llui/lliconctrl.h
index efa0925a4a..efa0925a4a 100644..100755
--- a/indra/llui/lliconctrl.h
+++ b/indra/llui/lliconctrl.h
diff --git a/indra/llui/llkeywords.cpp b/indra/llui/llkeywords.cpp
index c1cd04186b..26d27d1f34 100644..100755
--- a/indra/llui/llkeywords.cpp
+++ b/indra/llui/llkeywords.cpp
@@ -367,8 +367,6 @@ void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLW
const llwchar* base = wtext.c_str();
const llwchar* cur = base;
- const llwchar* line = NULL;
-
while( *cur )
{
if( *cur == '\n' || cur == base )
@@ -385,9 +383,6 @@ void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLW
}
}
- // Start of a new line
- line = cur;
-
// Skip white space
while( *cur && isspace(*cur) && (*cur != '\n') )
{
diff --git a/indra/llui/llkeywords.h b/indra/llui/llkeywords.h
index ac34015393..ac34015393 100644..100755
--- a/indra/llui/llkeywords.h
+++ b/indra/llui/llkeywords.h
diff --git a/indra/llui/lllayoutstack.cpp b/indra/llui/lllayoutstack.cpp
index 4c730286da..c89c0203b4 100644..100755
--- a/indra/llui/lllayoutstack.cpp
+++ b/indra/llui/lllayoutstack.cpp
@@ -32,11 +32,10 @@
#include "lllocalcliprect.h"
#include "llpanel.h"
-#include "llresizebar.h"
#include "llcriticaldamp.h"
#include "boost/foreach.hpp"
-static const F32 MIN_FRACTIONAL_SIZE = 0.0f;
+static const F32 MIN_FRACTIONAL_SIZE = 0.00001f;
static const F32 MAX_FRACTIONAL_SIZE = 1.f;
static LLDefaultChildRegistry::Register<LLLayoutStack> register_layout_stack("layout_stack");
@@ -71,7 +70,7 @@ LLLayoutPanel::LLLayoutPanel(const Params& p)
mCollapseAmt(0.f),
mVisibleAmt(1.f), // default to fully visible
mResizeBar(NULL),
- mFractionalSize(MIN_FRACTIONAL_SIZE),
+ mFractionalSize(0.f),
mTargetDim(0),
mIgnoreReshape(false),
mOrientation(LLLayoutStack::HORIZONTAL)
@@ -215,8 +214,15 @@ LLLayoutStack::Params::Params()
open_time_constant("open_time_constant", 0.02f),
close_time_constant("close_time_constant", 0.03f),
resize_bar_overlap("resize_bar_overlap", 1),
- border_size("border_size", LLCachedControl<S32>(*LLUI::sSettingGroups["config"], "UIResizeBarHeight", 0))
-{}
+ border_size("border_size", LLCachedControl<S32>(*LLUI::sSettingGroups["config"], "UIResizeBarHeight", 0)),
+ show_drag_handle("show_drag_handle", false),
+ drag_handle_first_indent("drag_handle_first_indent", 0),
+ drag_handle_second_indent("drag_handle_second_indent", 0),
+ drag_handle_thickness("drag_handle_thickness", 5),
+ drag_handle_shift("drag_handle_shift", 2)
+{
+ addSynonym(border_size, "drag_handle_gap");
+}
LLLayoutStack::LLLayoutStack(const LLLayoutStack::Params& p)
: LLView(p),
@@ -228,8 +234,14 @@ LLLayoutStack::LLLayoutStack(const LLLayoutStack::Params& p)
mClip(p.clip),
mOpenTimeConstant(p.open_time_constant),
mCloseTimeConstant(p.close_time_constant),
- mResizeBarOverlap(p.resize_bar_overlap)
-{}
+ mResizeBarOverlap(p.resize_bar_overlap),
+ mShowDragHandle(p.show_drag_handle),
+ mDragHandleFirstIndent(p.drag_handle_first_indent),
+ mDragHandleSecondIndent(p.drag_handle_second_indent),
+ mDragHandleThickness(p.drag_handle_thickness),
+ mDragHandleShift(p.drag_handle_shift)
+{
+}
LLLayoutStack::~LLLayoutStack()
{
@@ -263,6 +275,26 @@ void LLLayoutStack::draw()
drawChild(panelp, 0, 0, !clip_rect.isEmpty());
}
}
+
+ const LLView::child_list_t * child_listp = getChildList();
+ BOOST_FOREACH(LLView * childp, * child_listp)
+ {
+ LLResizeBar * resize_barp = dynamic_cast<LLResizeBar*>(childp);
+ if (resize_barp && resize_barp->isShowDragHandle() && resize_barp->getVisible() && resize_barp->getRect().isValid())
+ {
+ LLRect screen_rect = resize_barp->calcScreenRect();
+ if (LLUI::getRootView()->getLocalRect().overlaps(screen_rect) && LLUI::sDirtyRect.overlaps(screen_rect))
+ {
+ LLUI::pushMatrix();
+ {
+ const LLRect& rb_rect(resize_barp->getRect());
+ LLUI::translate(rb_rect.mLeft, rb_rect.mBottom);
+ resize_barp->draw();
+ }
+ LLUI::popMatrix();
+ }
+ }
+ }
}
void LLLayoutStack::removeChild(LLView* view)
@@ -391,7 +423,6 @@ void LLLayoutStack::updateLayout()
BOOST_FOREACH(LLLayoutPanel* panelp, mPanels)
{
F32 panel_dim = llmax(panelp->getExpandedMinDim(), panelp->mTargetDim);
- F32 panel_visible_dim = panelp->getVisibleDim();
LLRect panel_rect;
if (mOrientation == HORIZONTAL)
@@ -408,27 +439,61 @@ void LLLayoutStack::updateLayout()
getRect().getWidth(),
llround(panel_dim));
}
- panelp->setIgnoreReshape(true);
- panelp->setShape(panel_rect);
- panelp->setIgnoreReshape(false);
LLRect resize_bar_rect(panel_rect);
-
+ LLResizeBar * resize_barp = panelp->getResizeBar();
+ bool show_drag_handle = resize_barp->isShowDragHandle();
F32 panel_spacing = (F32)mPanelSpacing * panelp->getVisibleAmount();
+ F32 panel_visible_dim = panelp->getVisibleDim();
+ S32 panel_spacing_round = (S32)(llround(panel_spacing));
+
if (mOrientation == HORIZONTAL)
{
- resize_bar_rect.mLeft = panel_rect.mRight - mResizeBarOverlap;
- resize_bar_rect.mRight = panel_rect.mRight + (S32)(llround(panel_spacing)) + mResizeBarOverlap;
-
cur_pos += panel_visible_dim + panel_spacing;
+
+ if (show_drag_handle && panel_spacing_round > mDragHandleThickness)
+ {
+ resize_bar_rect.mLeft = panel_rect.mRight + mDragHandleShift;
+ resize_bar_rect.mRight = resize_bar_rect.mLeft + mDragHandleThickness;
+ }
+ else
+ {
+ resize_bar_rect.mLeft = panel_rect.mRight - mResizeBarOverlap;
+ resize_bar_rect.mRight = panel_rect.mRight + panel_spacing_round + mResizeBarOverlap;
+ }
+
+ if (show_drag_handle)
+ {
+ resize_bar_rect.mBottom += mDragHandleSecondIndent;
+ resize_bar_rect.mTop -= mDragHandleFirstIndent;
+ }
+
}
else //VERTICAL
{
- resize_bar_rect.mTop = panel_rect.mBottom + mResizeBarOverlap;
- resize_bar_rect.mBottom = panel_rect.mBottom - (S32)(llround(panel_spacing)) - mResizeBarOverlap;
-
cur_pos -= panel_visible_dim + panel_spacing;
+
+ if (show_drag_handle && panel_spacing_round > mDragHandleThickness)
+ {
+ resize_bar_rect.mTop = panel_rect.mBottom - mDragHandleShift;
+ resize_bar_rect.mBottom = resize_bar_rect.mTop - mDragHandleThickness;
+ }
+ else
+ {
+ resize_bar_rect.mTop = panel_rect.mBottom + mResizeBarOverlap;
+ resize_bar_rect.mBottom = panel_rect.mBottom - panel_spacing_round - mResizeBarOverlap;
+ }
+
+ if (show_drag_handle)
+ {
+ resize_bar_rect.mLeft += mDragHandleFirstIndent;
+ resize_bar_rect.mRight -= mDragHandleSecondIndent;
+ }
}
+
+ panelp->setIgnoreReshape(true);
+ panelp->setShape(panel_rect);
+ panelp->setIgnoreReshape(false);
panelp->mResizeBar->setShape(resize_bar_rect);
}
@@ -476,15 +541,13 @@ void LLLayoutStack::createResizeBar(LLLayoutPanel* panelp)
{
if (lp->mResizeBar == NULL)
{
- LLResizeBar::Side side = (mOrientation == HORIZONTAL) ? LLResizeBar::RIGHT : LLResizeBar::BOTTOM;
- LLRect resize_bar_rect = getRect();
-
LLResizeBar::Params resize_params;
resize_params.name("resize");
resize_params.resizing_view(lp);
resize_params.min_size(lp->getRelevantMinDim());
- resize_params.side(side);
+ resize_params.side((mOrientation == HORIZONTAL) ? LLResizeBar::RIGHT : LLResizeBar::BOTTOM);
resize_params.snapping_enabled(false);
+ resize_params.show_drag_handle(mShowDragHandle);
LLResizeBar* resize_bar = LLUICtrlFactory::create<LLResizeBar>(resize_params);
lp->mResizeBar = resize_bar;
LLView::addChild(resize_bar, 0);
@@ -521,7 +584,7 @@ void LLLayoutStack::updateFractionalSizes()
{
if (panelp->mAutoResize)
{
- total_resizable_dim += llmax(0, panelp->getLayoutDim() - panelp->getRelevantMinDim());
+ total_resizable_dim += llmax(MIN_FRACTIONAL_SIZE, (F32)(panelp->getLayoutDim() - panelp->getRelevantMinDim()));
}
}
@@ -672,12 +735,12 @@ void LLLayoutStack::updatePanelRect( LLLayoutPanel* resized_panel, const LLRect&
S32 new_dim = (mOrientation == HORIZONTAL)
? new_rect.getWidth()
: new_rect.getHeight();
- S32 delta_dim = new_dim - resized_panel->getVisibleDim();
- if (delta_dim == 0) return;
+ S32 delta_panel_dim = new_dim - resized_panel->getVisibleDim();
+ if (delta_panel_dim == 0) return;
F32 total_visible_fraction = 0.f;
F32 delta_auto_resize_headroom = 0.f;
- F32 original_auto_resize_headroom = 0.f;
+ F32 old_auto_resize_headroom = 0.f;
LLLayoutPanel* other_resize_panel = NULL;
LLLayoutPanel* following_panel = NULL;
@@ -686,7 +749,7 @@ void LLLayoutStack::updatePanelRect( LLLayoutPanel* resized_panel, const LLRect&
{
if (panelp->mAutoResize)
{
- original_auto_resize_headroom += (F32)(panelp->mTargetDim - panelp->getRelevantMinDim());
+ old_auto_resize_headroom += (F32)(panelp->mTargetDim - panelp->getRelevantMinDim());
if (panelp->getVisible() && !panelp->mCollapsed)
{
total_visible_fraction += panelp->mFractionalSize;
@@ -704,25 +767,24 @@ void LLLayoutStack::updatePanelRect( LLLayoutPanel* resized_panel, const LLRect&
}
}
-
if (resized_panel->mAutoResize)
{
if (!other_resize_panel || !other_resize_panel->mAutoResize)
{
- delta_auto_resize_headroom += delta_dim;
+ delta_auto_resize_headroom += delta_panel_dim;
}
}
else
{
if (!other_resize_panel || other_resize_panel->mAutoResize)
{
- delta_auto_resize_headroom -= delta_dim;
+ delta_auto_resize_headroom -= delta_panel_dim;
}
}
F32 fraction_given_up = 0.f;
F32 fraction_remaining = 1.f;
- F32 updated_auto_resize_headroom = original_auto_resize_headroom + delta_auto_resize_headroom;
+ F32 new_auto_resize_headroom = old_auto_resize_headroom + delta_auto_resize_headroom;
enum
{
@@ -734,7 +796,14 @@ void LLLayoutStack::updatePanelRect( LLLayoutPanel* resized_panel, const LLRect&
BOOST_FOREACH(LLLayoutPanel* panelp, mPanels)
{
- if (!panelp->getVisible() || panelp->mCollapsed) continue;
+ if (!panelp->getVisible() || panelp->mCollapsed)
+ {
+ if (panelp->mAutoResize)
+ {
+ fraction_remaining -= panelp->mFractionalSize;
+ }
+ continue;
+ }
if (panelp == resized_panel)
{
@@ -746,9 +815,9 @@ void LLLayoutStack::updatePanelRect( LLLayoutPanel* resized_panel, const LLRect&
case BEFORE_RESIZED_PANEL:
if (panelp->mAutoResize)
{ // freeze current size as fraction of overall auto_resize space
- F32 fractional_adjustment_factor = updated_auto_resize_headroom == 0.f
+ F32 fractional_adjustment_factor = new_auto_resize_headroom == 0.f
? 1.f
- : original_auto_resize_headroom / updated_auto_resize_headroom;
+ : old_auto_resize_headroom / new_auto_resize_headroom;
F32 new_fractional_size = llclamp(panelp->mFractionalSize * fractional_adjustment_factor,
MIN_FRACTIONAL_SIZE,
MAX_FRACTIONAL_SIZE);
@@ -765,9 +834,9 @@ void LLLayoutStack::updatePanelRect( LLLayoutPanel* resized_panel, const LLRect&
case RESIZED_PANEL:
if (panelp->mAutoResize)
{ // freeze new size as fraction
- F32 new_fractional_size = (updated_auto_resize_headroom == 0.f)
+ F32 new_fractional_size = (new_auto_resize_headroom == 0.f)
? MAX_FRACTIONAL_SIZE
- : llclamp(total_visible_fraction * (F32)(new_dim - panelp->getRelevantMinDim()) / updated_auto_resize_headroom, MIN_FRACTIONAL_SIZE, MAX_FRACTIONAL_SIZE);
+ : llclamp(total_visible_fraction * (F32)(new_dim - panelp->getRelevantMinDim()) / new_auto_resize_headroom, MIN_FRACTIONAL_SIZE, MAX_FRACTIONAL_SIZE);
fraction_given_up -= new_fractional_size - panelp->mFractionalSize;
fraction_remaining -= panelp->mFractionalSize;
panelp->mFractionalSize = new_fractional_size;
@@ -790,8 +859,13 @@ void LLLayoutStack::updatePanelRect( LLLayoutPanel* resized_panel, const LLRect&
}
else
{
+ if (new_auto_resize_headroom < 1.f)
+ {
+ new_auto_resize_headroom = 1.f;
+ }
+
F32 new_fractional_size = llclamp(total_visible_fraction * (F32)(panelp->mTargetDim - panelp->getRelevantMinDim() + delta_auto_resize_headroom)
- / updated_auto_resize_headroom,
+ / new_auto_resize_headroom,
MIN_FRACTIONAL_SIZE,
MAX_FRACTIONAL_SIZE);
fraction_given_up -= new_fractional_size - panelp->mFractionalSize;
@@ -800,7 +874,7 @@ void LLLayoutStack::updatePanelRect( LLLayoutPanel* resized_panel, const LLRect&
}
else
{
- panelp->mTargetDim -= delta_dim;
+ panelp->mTargetDim -= delta_panel_dim;
}
which_panel = AFTER_RESIZED_PANEL;
break;
@@ -816,7 +890,7 @@ void LLLayoutStack::updatePanelRect( LLLayoutPanel* resized_panel, const LLRect&
}
}
updateLayout();
- normalizeFractionalSizes();
+ //normalizeFractionalSizes();
}
void LLLayoutStack::reshape(S32 width, S32 height, BOOL called_from_parent)
@@ -855,3 +929,4 @@ void LLLayoutStack::updateResizeBarLimits()
previous_visible_panelp = visible_panelp;
}
}
+
diff --git a/indra/llui/lllayoutstack.h b/indra/llui/lllayoutstack.h
index 648cd5fdce..add43fa741 100644..100755
--- a/indra/llui/lllayoutstack.h
+++ b/indra/llui/lllayoutstack.h
@@ -29,6 +29,7 @@
#define LL_LLLAYOUTSTACK_H
#include "llpanel.h"
+#include "llresizebar.h"
class LLLayoutPanel;
@@ -37,6 +38,7 @@ class LLLayoutPanel;
class LLLayoutStack : public LLView, public LLInstanceTracker<LLLayoutStack>
{
public:
+
typedef enum e_layout_orientation
{
HORIZONTAL,
@@ -61,6 +63,11 @@ public:
Optional<F32> open_time_constant,
close_time_constant;
Optional<S32> resize_bar_overlap;
+ Optional<bool> show_drag_handle;
+ Optional<S32> drag_handle_first_indent;
+ Optional<S32> drag_handle_second_indent;
+ Optional<S32> drag_handle_thickness;
+ Optional<S32> drag_handle_shift;
Params();
};
@@ -125,6 +132,11 @@ private:
F32 mCloseTimeConstant;
bool mNeedsLayout;
S32 mResizeBarOverlap;
+ bool mShowDragHandle;
+ S32 mDragHandleFirstIndent;
+ S32 mDragHandleSecondIndent;
+ S32 mDragHandleThickness;
+ S32 mDragHandleShift;
}; // end class LLLayoutStack
@@ -178,6 +190,9 @@ public:
F32 getAutoResizeFactor() const;
F32 getVisibleAmount() const;
S32 getVisibleDim() const;
+ LLResizeBar* getResizeBar() { return mResizeBar; }
+
+ bool isCollapsed() const { return mCollapsed;}
void setOrientation(LLLayoutStack::ELayoutOrientation orientation);
void storeOriginalDim();
diff --git a/indra/llui/lllazyvalue.h b/indra/llui/lllazyvalue.h
index 0fc95d9efa..0fc95d9efa 100644..100755
--- a/indra/llui/lllazyvalue.h
+++ b/indra/llui/lllazyvalue.h
diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp
index d0fbf4b913..5478e85e13 100644..100755
--- a/indra/llui/lllineeditor.cpp
+++ b/indra/llui/lllineeditor.cpp
@@ -45,6 +45,7 @@
#include "llkeyboard.h"
#include "llrect.h"
#include "llresmgr.h"
+#include "llspellcheck.h"
#include "llstring.h"
#include "llwindow.h"
#include "llui.h"
@@ -65,6 +66,7 @@ const S32 SCROLL_INCREMENT_ADD = 0; // make space for typing
const S32 SCROLL_INCREMENT_DEL = 4; // make space for baskspacing
const F32 AUTO_SCROLL_TIME = 0.05f;
const F32 TRIPLE_CLICK_INTERVAL = 0.3f; // delay between double and triple click. *TODO: make this equal to the double click interval?
+const F32 SPELLCHECK_DELAY = 0.5f; // delay between the last keypress and spell checking the word the cursor is on
const std::string PASSWORD_ASTERISK( "\xE2\x80\xA2" ); // U+2022 BULLET
@@ -88,6 +90,7 @@ LLLineEditor::Params::Params()
background_image_focused("background_image_focused"),
select_on_focus("select_on_focus", false),
revert_on_esc("revert_on_esc", true),
+ spellcheck("spellcheck", false),
commit_on_focus_lost("commit_on_focus_lost", true),
ignore_tab("ignore_tab", true),
is_password("is_password", false),
@@ -134,6 +137,9 @@ LLLineEditor::LLLineEditor(const LLLineEditor::Params& p)
mIgnoreArrowKeys( FALSE ),
mIgnoreTab( p.ignore_tab ),
mDrawAsterixes( p.is_password ),
+ mSpellCheck( p.spellcheck ),
+ mSpellCheckStart(-1),
+ mSpellCheckEnd(-1),
mSelectAllonFocusReceived( p.select_on_focus ),
mSelectAllonCommit( TRUE ),
mPassDelete(FALSE),
@@ -177,6 +183,12 @@ LLLineEditor::LLLineEditor(const LLLineEditor::Params& p)
updateTextPadding();
setCursor(mText.length());
+ if (mSpellCheck)
+ {
+ LLSpellChecker::setSettingsChangeCallback(boost::bind(&LLLineEditor::onSpellCheckSettingsChange, this));
+ }
+ mSpellCheckTimer.reset();
+
setPrevalidateInput(p.prevalidate_input_callback());
setPrevalidate(p.prevalidate_callback());
@@ -190,12 +202,19 @@ LLLineEditor::LLLineEditor(const LLLineEditor::Params& p)
LLLineEditor::~LLLineEditor()
{
mCommitOnFocusLost = FALSE;
+
+ // Make sure no context menu linger around once the widget is deleted
+ LLContextMenu* menu = static_cast<LLContextMenu*>(mContextMenuHandle.get());
+ if (menu)
+ {
+ menu->hide();
+ }
+ setContextMenu(NULL);
// calls onCommit() while LLLineEditor still valid
gFocusMgr.releaseFocusIfNeeded( this );
}
-
void LLLineEditor::onFocusReceived()
{
gEditMenuHandler = this;
@@ -519,6 +538,99 @@ void LLLineEditor::selectAll()
updatePrimary();
}
+bool LLLineEditor::getSpellCheck() const
+{
+ return (LLSpellChecker::getUseSpellCheck()) && (!mReadOnly) && (mSpellCheck);
+}
+
+const std::string& LLLineEditor::getSuggestion(U32 index) const
+{
+ return (index < mSuggestionList.size()) ? mSuggestionList[index] : LLStringUtil::null;
+}
+
+U32 LLLineEditor::getSuggestionCount() const
+{
+ return mSuggestionList.size();
+}
+
+void LLLineEditor::replaceWithSuggestion(U32 index)
+{
+ for (std::list<std::pair<U32, U32> >::const_iterator it = mMisspellRanges.begin(); it != mMisspellRanges.end(); ++it)
+ {
+ if ( (it->first <= (U32)mCursorPos) && (it->second >= (U32)mCursorPos) )
+ {
+ deselect();
+
+ // Delete the misspelled word
+ mText.erase(it->first, it->second - it->first);
+
+ // Insert the suggestion in its place
+ LLWString suggestion = utf8str_to_wstring(mSuggestionList[index]);
+ mText.insert(it->first, suggestion);
+ setCursor(it->first + (S32)suggestion.length());
+
+ break;
+ }
+ }
+ mSpellCheckStart = mSpellCheckEnd = -1;
+}
+
+void LLLineEditor::addToDictionary()
+{
+ if (canAddToDictionary())
+ {
+ LLSpellChecker::instance().addToCustomDictionary(getMisspelledWord(mCursorPos));
+ }
+}
+
+bool LLLineEditor::canAddToDictionary() const
+{
+ return (getSpellCheck()) && (isMisspelledWord(mCursorPos));
+}
+
+void LLLineEditor::addToIgnore()
+{
+ if (canAddToIgnore())
+ {
+ LLSpellChecker::instance().addToIgnoreList(getMisspelledWord(mCursorPos));
+ }
+}
+
+bool LLLineEditor::canAddToIgnore() const
+{
+ return (getSpellCheck()) && (isMisspelledWord(mCursorPos));
+}
+
+std::string LLLineEditor::getMisspelledWord(U32 pos) const
+{
+ for (std::list<std::pair<U32, U32> >::const_iterator it = mMisspellRanges.begin(); it != mMisspellRanges.end(); ++it)
+ {
+ if ( (it->first <= pos) && (it->second >= pos) )
+ {
+ return wstring_to_utf8str(mText.getWString().substr(it->first, it->second - it->first));
+ }
+ }
+ return LLStringUtil::null;
+}
+
+bool LLLineEditor::isMisspelledWord(U32 pos) const
+{
+ for (std::list<std::pair<U32, U32> >::const_iterator it = mMisspellRanges.begin(); it != mMisspellRanges.end(); ++it)
+ {
+ if ( (it->first <= pos) && (it->second >= pos) )
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+void LLLineEditor::onSpellCheckSettingsChange()
+{
+ // Recheck the spelling on every change
+ mMisspellRanges.clear();
+ mSpellCheckStart = mSpellCheckEnd = -1;
+}
BOOL LLLineEditor::handleDoubleClick(S32 x, S32 y, MASK mask)
{
@@ -1058,9 +1170,8 @@ void LLLineEditor::cut()
LLUI::reportBadKeystroke();
}
else
- if( mKeystrokeCallback )
{
- mKeystrokeCallback( this );
+ onKeystroke();
}
}
}
@@ -1187,9 +1298,8 @@ void LLLineEditor::pasteHelper(bool is_primary)
LLUI::reportBadKeystroke();
}
else
- if( mKeystrokeCallback )
{
- mKeystrokeCallback( this );
+ onKeystroke();
}
}
}
@@ -1442,9 +1552,10 @@ BOOL LLLineEditor::handleKeyHere(KEY key, MASK mask )
// Notify owner if requested
if (!need_to_rollback && handled)
{
- if (mKeystrokeCallback)
+ onKeystroke();
+ if ( (!selection_modified) && (KEY_BACKSPACE == key) )
{
- mKeystrokeCallback(this);
+ mSpellCheckTimer.setTimerExpirySec(SPELLCHECK_DELAY);
}
}
}
@@ -1497,12 +1608,11 @@ BOOL LLLineEditor::handleUnicodeCharHere(llwchar uni_char)
// Notify owner if requested
if( !need_to_rollback && handled )
{
- if( mKeystrokeCallback )
- {
- // HACK! The only usage of this callback doesn't do anything with the character.
- // We'll have to do something about this if something ever changes! - Doug
- mKeystrokeCallback( this );
- }
+ // HACK! The only usage of this callback doesn't do anything with the character.
+ // We'll have to do something about this if something ever changes! - Doug
+ onKeystroke();
+
+ mSpellCheckTimer.setTimerExpirySec(SPELLCHECK_DELAY);
}
}
return handled;
@@ -1531,9 +1641,7 @@ void LLLineEditor::doDelete()
if (!prevalidateInput(text_to_delete))
{
- if( mKeystrokeCallback )
- mKeystrokeCallback( this );
-
+ onKeystroke();
return;
}
setCursor(getCursor() + 1);
@@ -1549,10 +1657,9 @@ void LLLineEditor::doDelete()
}
else
{
- if( mKeystrokeCallback )
- {
- mKeystrokeCallback( this );
- }
+ onKeystroke();
+
+ mSpellCheckTimer.setTimerExpirySec(SPELLCHECK_DELAY);
}
}
}
@@ -1624,6 +1731,10 @@ void LLLineEditor::draw()
background.stretch( -mBorderThickness );
S32 lineeditor_v_pad = (background.getHeight() - mGLFont->getLineHeight()) / 2;
+ if (mSpellCheck)
+ {
+ lineeditor_v_pad += 1;
+ }
drawBackground();
@@ -1698,14 +1809,14 @@ void LLLineEditor::draw()
{
S32 select_left;
S32 select_right;
- if( mSelectionStart < getCursor() )
+ if (mSelectionStart < mSelectionEnd)
{
select_left = mSelectionStart;
- select_right = getCursor();
+ select_right = mSelectionEnd;
}
else
{
- select_left = getCursor();
+ select_left = mSelectionEnd;
select_right = mSelectionStart;
}
@@ -1749,7 +1860,7 @@ void LLLineEditor::draw()
if( (rendered_pixels_right < (F32)mTextRightEdge) && (rendered_text < text_len) )
{
// unselected, right side
- mGLFont->render(
+ rendered_text += mGLFont->render(
mText, mScrollHPos + rendered_text,
rendered_pixels_right, text_bottom,
text_color,
@@ -1763,7 +1874,7 @@ void LLLineEditor::draw()
}
else
{
- mGLFont->render(
+ rendered_text = mGLFont->render(
mText, mScrollHPos,
rendered_pixels_right, text_bottom,
text_color,
@@ -1778,6 +1889,101 @@ void LLLineEditor::draw()
mBorder->setVisible(FALSE); // no more programmatic art.
#endif
+ if ( (getSpellCheck()) && (mText.length() > 2) )
+ {
+ // Calculate start and end indices for the first and last visible word
+ U32 start = prevWordPos(mScrollHPos), end = nextWordPos(mScrollHPos + rendered_text);
+
+ if ( (mSpellCheckStart != start) || (mSpellCheckEnd != end) )
+ {
+ const LLWString& text = mText.getWString().substr(start, end);
+
+ // Find the start of the first word
+ U32 word_start = 0, word_end = 0;
+ while ( (word_start < text.length()) && (!LLStringOps::isAlpha(text[word_start])) )
+ {
+ word_start++;
+ }
+
+ // Iterate over all words in the text block and check them one by one
+ mMisspellRanges.clear();
+ while (word_start < text.length())
+ {
+ // Find the end of the current word (special case handling for "'" when it's used as a contraction)
+ word_end = word_start + 1;
+ while ( (word_end < text.length()) &&
+ ((LLWStringUtil::isPartOfWord(text[word_end])) ||
+ ((L'\'' == text[word_end]) && (word_end + 1 < text.length()) &&
+ (LLStringOps::isAlnum(text[word_end - 1])) && (LLStringOps::isAlnum(text[word_end + 1])))) )
+ {
+ word_end++;
+ }
+ if (word_end > text.length())
+ {
+ break;
+ }
+
+ // Don't process words shorter than 3 characters
+ std::string word = wstring_to_utf8str(text.substr(word_start, word_end - word_start));
+ if ( (word.length() >= 3) && (!LLSpellChecker::instance().checkSpelling(word)) )
+ {
+ mMisspellRanges.push_back(std::pair<U32, U32>(start + word_start, start + word_end));
+ }
+
+ // Find the start of the next word
+ word_start = word_end + 1;
+ while ( (word_start < text.length()) && (!LLWStringUtil::isPartOfWord(text[word_start])) )
+ {
+ word_start++;
+ }
+ }
+
+ mSpellCheckStart = start;
+ mSpellCheckEnd = end;
+ }
+
+ // Draw squiggly lines under any (visible) misspelled words
+ for (std::list<std::pair<U32, U32> >::const_iterator it = mMisspellRanges.begin(); it != mMisspellRanges.end(); ++it)
+ {
+ // Skip over words that aren't (partially) visible
+ if ( ((it->first < start) && (it->second < start)) || (it->first > end) )
+ {
+ continue;
+ }
+
+ // Skip the current word if the user is still busy editing it
+ if ( (!mSpellCheckTimer.hasExpired()) && (it->first <= (U32)mCursorPos) && (it->second >= (U32)mCursorPos) )
+ {
+ continue;
+ }
+
+ S32 pxWidth = getRect().getWidth();
+ S32 pxStart = findPixelNearestPos(it->first - getCursor());
+ if (pxStart > pxWidth)
+ {
+ continue;
+ }
+ S32 pxEnd = findPixelNearestPos(it->second - getCursor());
+ if (pxEnd > pxWidth)
+ {
+ pxEnd = pxWidth;
+ }
+
+ S32 pxBottom = (S32)(text_bottom + mGLFont->getDescenderHeight());
+
+ gGL.color4ub(255, 0, 0, 200);
+ while (pxStart + 1 < pxEnd)
+ {
+ gl_line_2d(pxStart, pxBottom, pxStart + 2, pxBottom - 2);
+ if (pxStart + 3 < pxEnd)
+ {
+ gl_line_2d(pxStart + 2, pxBottom - 3, pxStart + 4, pxBottom - 1);
+ }
+ pxStart += 4;
+ }
+ }
+ }
+
// If we're editing...
if( hasFocus())
{
@@ -1817,8 +2023,8 @@ void LLLineEditor::draw()
LLRect screen_pos = calcScreenRect();
LLCoordGL ime_pos( screen_pos.mLeft + pixels_after_scroll, screen_pos.mTop - lineeditor_v_pad );
- ime_pos.mX = (S32) (ime_pos.mX * LLUI::sGLScaleFactor.mV[VX]);
- ime_pos.mY = (S32) (ime_pos.mY * LLUI::sGLScaleFactor.mV[VY]);
+ ime_pos.mX = (S32) (ime_pos.mX * LLUI::getScaleFactor().mV[VX]);
+ ime_pos.mY = (S32) (ime_pos.mY * LLUI::getScaleFactor().mV[VY]);
getWindow()->setLanguageTextInput( ime_pos );
}
}
@@ -2109,6 +2315,15 @@ void LLLineEditor::setSelectAllonFocusReceived(BOOL b)
mSelectAllonFocusReceived = b;
}
+void LLLineEditor::onKeystroke()
+{
+ if (mKeystrokeCallback)
+ {
+ mKeystrokeCallback(this);
+ }
+
+ mSpellCheckStart = mSpellCheckEnd = -1;
+}
void LLLineEditor::setKeystrokeCallback(callback_t callback, void* user_data)
{
@@ -2231,10 +2446,9 @@ void LLLineEditor::updatePreedit(const LLWString &preedit_string,
// Update of the preedit should be caused by some key strokes.
mKeystrokeTimer.reset();
- if( mKeystrokeCallback )
- {
- mKeystrokeCallback( this );
- }
+ onKeystroke();
+
+ mSpellCheckTimer.setTimerExpirySec(SPELLCHECK_DELAY);
}
BOOL LLLineEditor::getPreeditLocation(S32 query_offset, LLCoordGL *coord, LLRect *bounds, LLRect *control) const
@@ -2357,7 +2571,7 @@ void LLLineEditor::markAsPreedit(S32 position, S32 length)
S32 LLLineEditor::getPreeditFontSize() const
{
- return llround(mGLFont->getLineHeight() * LLUI::sGLScaleFactor.mV[VY]);
+ return llround(mGLFont->getLineHeight() * LLUI::getScaleFactor().mV[VY]);
}
void LLLineEditor::setReplaceNewlinesWithSpaces(BOOL replace)
@@ -2386,7 +2600,38 @@ void LLLineEditor::showContextMenu(S32 x, S32 y)
S32 screen_x, screen_y;
localPointToScreen(x, y, &screen_x, &screen_y);
- menu->show(screen_x, screen_y);
+
+ setCursorAtLocalPos(x);
+ if (hasSelection())
+ {
+ if ( (mCursorPos < llmin(mSelectionStart, mSelectionEnd)) || (mCursorPos > llmax(mSelectionStart, mSelectionEnd)) )
+ {
+ deselect();
+ }
+ else
+ {
+ setCursor(llmax(mSelectionStart, mSelectionEnd));
+ }
+ }
+
+ bool use_spellcheck = getSpellCheck(), is_misspelled = false;
+ if (use_spellcheck)
+ {
+ mSuggestionList.clear();
+
+ // If the cursor is on a misspelled word, retrieve suggestions for it
+ std::string misspelled_word = getMisspelledWord(mCursorPos);
+ if ((is_misspelled = !misspelled_word.empty()) == true)
+ {
+ LLSpellChecker::instance().getSuggestions(misspelled_word, mSuggestionList);
+ }
+ }
+
+ menu->setItemVisible("Suggestion Separator", (use_spellcheck) && (!mSuggestionList.empty()));
+ menu->setItemVisible("Add to Dictionary", (use_spellcheck) && (is_misspelled));
+ menu->setItemVisible("Add to Ignore", (use_spellcheck) && (is_misspelled));
+ menu->setItemVisible("Spellcheck Separator", (use_spellcheck) && (is_misspelled));
+ menu->show(screen_x, screen_y, this);
}
}
diff --git a/indra/llui/lllineeditor.h b/indra/llui/lllineeditor.h
index 2518dbe3c7..40f931ecc1 100644..100755
--- a/indra/llui/lllineeditor.h
+++ b/indra/llui/lllineeditor.h
@@ -40,6 +40,7 @@
#include "llframetimer.h"
#include "lleditmenuhandler.h"
+#include "llspellcheckmenuhandler.h"
#include "lluictrl.h"
#include "lluiimage.h"
#include "lluistring.h"
@@ -54,7 +55,7 @@ class LLButton;
class LLContextMenu;
class LLLineEditor
-: public LLUICtrl, public LLEditMenuHandler, protected LLPreeditor
+: public LLUICtrl, public LLEditMenuHandler, protected LLPreeditor, public LLSpellCheckMenuHandler
{
public:
@@ -86,6 +87,7 @@ public:
Optional<bool> select_on_focus,
revert_on_esc,
+ spellcheck,
commit_on_focus_lost,
ignore_tab,
is_password;
@@ -146,6 +148,24 @@ public:
virtual void deselect();
virtual BOOL canDeselect() const;
+ // LLSpellCheckMenuHandler overrides
+ /*virtual*/ bool getSpellCheck() const;
+
+ /*virtual*/ const std::string& getSuggestion(U32 index) const;
+ /*virtual*/ U32 getSuggestionCount() const;
+ /*virtual*/ void replaceWithSuggestion(U32 index);
+
+ /*virtual*/ void addToDictionary();
+ /*virtual*/ bool canAddToDictionary() const;
+
+ /*virtual*/ void addToIgnore();
+ /*virtual*/ bool canAddToIgnore() const;
+
+ // Spell checking helper functions
+ std::string getMisspelledWord(U32 pos) const;
+ bool isMisspelledWord(U32 pos) const;
+ void onSpellCheckSettingsChange();
+
// view overrides
virtual void draw();
virtual void reshape(S32 width,S32 height,BOOL called_from_parent=TRUE);
@@ -223,6 +243,7 @@ public:
void setSelectAllonFocusReceived(BOOL b);
void setSelectAllonCommit(BOOL b) { mSelectAllonCommit = b; }
+ void onKeystroke();
typedef boost::function<void (LLLineEditor* caller, void* user_data)> callback_t;
void setKeystrokeCallback(callback_t callback, void* user_data);
@@ -322,6 +343,13 @@ protected:
S32 mLastSelectionStart;
S32 mLastSelectionEnd;
+ bool mSpellCheck;
+ S32 mSpellCheckStart;
+ S32 mSpellCheckEnd;
+ LLTimer mSpellCheckTimer;
+ std::list<std::pair<U32, U32> > mMisspellRanges;
+ std::vector<std::string> mSuggestionList;
+
LLTextValidate::validate_func_t mPrevalidateFunc;
LLTextValidate::validate_func_t mPrevalidateInputFunc;
diff --git a/indra/llui/llloadingindicator.cpp b/indra/llui/llloadingindicator.cpp
index 6ac38f5ad4..1ede5b706f 100644..100755
--- a/indra/llui/llloadingindicator.cpp
+++ b/indra/llui/llloadingindicator.cpp
@@ -52,7 +52,7 @@ LLLoadingIndicator::LLLoadingIndicator(const Params& p)
void LLLoadingIndicator::initFromParams(const Params& p)
{
- BOOST_FOREACH(LLUIImage* image, p.images.image)
+ BOOST_FOREACH(LLUIImage* image, p.images().image)
{
mImages.push_back(image);
}
diff --git a/indra/llui/llloadingindicator.h b/indra/llui/llloadingindicator.h
index c1f979c111..ffcb329f42 100644..100755
--- a/indra/llui/llloadingindicator.h
+++ b/indra/llui/llloadingindicator.h
@@ -51,7 +51,7 @@ class LLLoadingIndicator
LOG_CLASS(LLLoadingIndicator);
public:
- struct Images : public LLInitParam::BatchBlock<Images>
+ struct Images : public LLInitParam::Block<Images>
{
Multiple<LLUIImage*> image;
@@ -62,8 +62,8 @@ public:
struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
{
- Optional<F32> images_per_sec;
- Optional<Images> images;
+ Optional<F32> images_per_sec;
+ Optional<Atomic<Images> > images;
Params()
: images_per_sec("images_per_sec", 1.0f),
diff --git a/indra/llui/lllocalcliprect.cpp b/indra/llui/lllocalcliprect.cpp
index 6841301219..f3a526faeb 100644..100755
--- a/indra/llui/lllocalcliprect.cpp
+++ b/indra/llui/lllocalcliprect.cpp
@@ -88,10 +88,10 @@ void LLScreenClipRect::updateScissorRegion()
LLRect rect = sClipRectStack.top();
stop_glerror();
S32 x,y,w,h;
- x = llfloor(rect.mLeft * LLUI::sGLScaleFactor.mV[VX]);
- y = llfloor(rect.mBottom * LLUI::sGLScaleFactor.mV[VY]);
- w = llmax(0, llceil(rect.getWidth() * LLUI::sGLScaleFactor.mV[VX])) + 1;
- h = llmax(0, llceil(rect.getHeight() * LLUI::sGLScaleFactor.mV[VY])) + 1;
+ x = llfloor(rect.mLeft * LLUI::getScaleFactor().mV[VX]);
+ y = llfloor(rect.mBottom * LLUI::getScaleFactor().mV[VY]);
+ w = llmax(0, llceil(rect.getWidth() * LLUI::getScaleFactor().mV[VX])) + 1;
+ h = llmax(0, llceil(rect.getHeight() * LLUI::getScaleFactor().mV[VY])) + 1;
glScissor( x,y,w,h );
stop_glerror();
}
diff --git a/indra/llui/lllocalcliprect.h b/indra/llui/lllocalcliprect.h
index eeeaf2adb6..eeeaf2adb6 100644..100755
--- a/indra/llui/lllocalcliprect.h
+++ b/indra/llui/lllocalcliprect.h
diff --git a/indra/llui/llmenubutton.cpp b/indra/llui/llmenubutton.cpp
index 50d59f79f4..746ade4648 100644..100755
--- a/indra/llui/llmenubutton.cpp
+++ b/indra/llui/llmenubutton.cpp
@@ -44,33 +44,27 @@ void LLMenuButton::MenuPositions::declareValues()
LLMenuButton::Params::Params()
: menu_filename("menu_filename"),
- position("position", MP_BOTTOM_LEFT)
+ position("menu_position", MP_BOTTOM_LEFT)
{
+ addSynonym(position, "position");
}
LLMenuButton::LLMenuButton(const LLMenuButton::Params& p)
: LLButton(p),
mIsMenuShown(false),
- mMenuPosition(p.position)
+ mMenuPosition(p.position),
+ mOwnMenu(false)
{
std::string menu_filename = p.menu_filename;
- if (!menu_filename.empty())
- {
- LLToggleableMenu* menu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>(menu_filename, LLMenuGL::sMenuContainer, LLMenuHolderGL::child_registry_t::instance());
- if (!menu)
- {
- llwarns << "Error loading menu_button menu" << llendl;
- return;
- }
-
- menu->setVisibilityChangeCallback(boost::bind(&LLMenuButton::onMenuVisibilityChange, this, _2));
-
- mMenuHandle = menu->getHandle();
+ setMenu(menu_filename, mMenuPosition);
+ updateMenuOrigin();
+}
- updateMenuOrigin();
- }
+LLMenuButton::~LLMenuButton()
+{
+ cleanup();
}
boost::signals2::connection LLMenuButton::setMouseDownCallback( const mouse_signal_t::slot_type& cb )
@@ -80,9 +74,7 @@ boost::signals2::connection LLMenuButton::setMouseDownCallback( const mouse_sign
void LLMenuButton::hideMenu()
{
- if(mMenuHandle.isDead()) return;
-
- LLToggleableMenu* menu = dynamic_cast<LLToggleableMenu*>(mMenuHandle.get());
+ LLToggleableMenu* menu = getMenu();
if (menu)
{
menu->setVisible(FALSE);
@@ -94,19 +86,39 @@ LLToggleableMenu* LLMenuButton::getMenu()
return dynamic_cast<LLToggleableMenu*>(mMenuHandle.get());
}
-void LLMenuButton::setMenu(LLToggleableMenu* menu, EMenuPosition position /*MP_TOP_LEFT*/)
+void LLMenuButton::setMenu(const std::string& menu_filename, EMenuPosition position /*MP_TOP_LEFT*/)
+{
+ if (menu_filename.empty())
+ {
+ return;
+ }
+
+ LLToggleableMenu* menu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>(menu_filename, LLMenuGL::sMenuContainer, LLMenuHolderGL::child_registry_t::instance());
+ if (!menu)
+ {
+ llwarns << "Error loading menu_button menu" << llendl;
+ return;
+ }
+
+ setMenu(menu, position, true);
+}
+
+void LLMenuButton::setMenu(LLToggleableMenu* menu, EMenuPosition position /*MP_TOP_LEFT*/, bool take_ownership /*false*/)
{
if (!menu) return;
+ cleanup(); // destroy the previous memnu if we own it
+
mMenuHandle = menu->getHandle();
mMenuPosition = position;
+ mOwnMenu = take_ownership;
menu->setVisibilityChangeCallback(boost::bind(&LLMenuButton::onMenuVisibilityChange, this, _2));
}
BOOL LLMenuButton::handleKeyHere(KEY key, MASK mask )
{
- if (mMenuHandle.isDead()) return FALSE;
+ if (!getMenu()) return FALSE;
if( KEY_RETURN == key && mask == MASK_NONE && !gKeyboard->getKeyRepeated(key))
{
@@ -118,7 +130,7 @@ BOOL LLMenuButton::handleKeyHere(KEY key, MASK mask )
return TRUE;
}
- LLToggleableMenu* menu = dynamic_cast<LLToggleableMenu*>(mMenuHandle.get());
+ LLToggleableMenu* menu = getMenu();
if (menu && menu->getVisible() && key == KEY_ESCAPE && mask == MASK_NONE)
{
menu->setVisible(FALSE);
@@ -139,9 +151,12 @@ BOOL LLMenuButton::handleMouseDown(S32 x, S32 y, MASK mask)
void LLMenuButton::toggleMenu()
{
- if(mMenuHandle.isDead()) return;
+ if (mValidateSignal && !(*mValidateSignal)(this, LLSD()))
+ {
+ return;
+ }
- LLToggleableMenu* menu = dynamic_cast<LLToggleableMenu*>(mMenuHandle.get());
+ LLToggleableMenu* menu = getMenu();
if (!menu) return;
// Store the button rectangle to toggle menu visibility if a mouse event
@@ -170,7 +185,8 @@ void LLMenuButton::toggleMenu()
void LLMenuButton::updateMenuOrigin()
{
- if (mMenuHandle.isDead()) return;
+ LLToggleableMenu* menu = getMenu();
+ if (!menu) return;
LLRect rect = getRect();
@@ -179,12 +195,12 @@ void LLMenuButton::updateMenuOrigin()
case MP_TOP_LEFT:
{
mX = rect.mLeft;
- mY = rect.mTop + mMenuHandle.get()->getRect().getHeight();
+ mY = rect.mTop + menu->getRect().getHeight();
break;
}
case MP_TOP_RIGHT:
{
- const LLRect& menu_rect = mMenuHandle.get()->getRect();
+ const LLRect& menu_rect = menu->getRect();
mX = rect.mRight - menu_rect.getWidth();
mY = rect.mTop + menu_rect.getHeight();
break;
@@ -211,3 +227,11 @@ void LLMenuButton::onMenuVisibilityChange(const LLSD& param)
mIsMenuShown = false;
}
}
+
+void LLMenuButton::cleanup()
+{
+ if (mMenuHandle.get() && mOwnMenu)
+ {
+ mMenuHandle.get()->die();
+ }
+}
diff --git a/indra/llui/llmenubutton.h b/indra/llui/llmenubutton.h
index e2396e7fb2..67ec1983b3 100644..100755
--- a/indra/llui/llmenubutton.h
+++ b/indra/llui/llmenubutton.h
@@ -34,6 +34,8 @@ class LLToggleableMenu;
class LLMenuButton
: public LLButton
{
+ LOG_CLASS(LLMenuButton);
+
public:
typedef enum e_menu_position
{
@@ -53,7 +55,7 @@ public:
{
// filename for it's toggleable menu
Optional<std::string> menu_filename;
- Optional<EMenuPosition> position;
+ Optional<EMenuPosition, MenuPositions> position;
Params();
};
@@ -68,13 +70,15 @@ public:
void hideMenu();
LLToggleableMenu* getMenu();
- void setMenu(LLToggleableMenu* menu, EMenuPosition position = MP_TOP_LEFT);
+ void setMenu(const std::string& menu_filename, EMenuPosition position = MP_TOP_LEFT);
+ void setMenu(LLToggleableMenu* menu, EMenuPosition position = MP_TOP_LEFT, bool take_ownership = false);
void setMenuPosition(EMenuPosition position) { mMenuPosition = position; }
protected:
friend class LLUICtrlFactory;
LLMenuButton(const Params&);
+ ~LLMenuButton();
void toggleMenu();
void updateMenuOrigin();
@@ -82,11 +86,14 @@ protected:
void onMenuVisibilityChange(const LLSD& param);
private:
+ void cleanup();
+
LLHandle<LLView> mMenuHandle;
bool mIsMenuShown;
EMenuPosition mMenuPosition;
S32 mX;
S32 mY;
+ bool mOwnMenu; // true if we manage the menu lifetime
};
diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp
index ff6928ffda..f854e1785d 100644..100755
--- a/indra/llui/llmenugl.cpp
+++ b/indra/llui/llmenugl.cpp
@@ -593,12 +593,12 @@ BOOL LLMenuItemSeparatorGL::handleMouseDown(S32 x, S32 y, MASK mask)
{
// the menu items are in the child list in bottom up order
LLView* prev_menu_item = parent_menu->findNextSibling(this);
- return prev_menu_item ? prev_menu_item->handleMouseDown(x, prev_menu_item->getRect().getHeight(), mask) : FALSE;
+ return (prev_menu_item && prev_menu_item->getVisible() && prev_menu_item->getEnabled()) ? prev_menu_item->handleMouseDown(x, prev_menu_item->getRect().getHeight(), mask) : FALSE;
}
else
{
LLView* next_menu_item = parent_menu->findPrevSibling(this);
- return next_menu_item ? next_menu_item->handleMouseDown(x, 0, mask) : FALSE;
+ return (next_menu_item && next_menu_item->getVisible() && next_menu_item->getEnabled()) ? next_menu_item->handleMouseDown(x, 0, mask) : FALSE;
}
}
@@ -608,12 +608,12 @@ BOOL LLMenuItemSeparatorGL::handleMouseUp(S32 x, S32 y, MASK mask)
if (y > getRect().getHeight() / 2)
{
LLView* prev_menu_item = parent_menu->findNextSibling(this);
- return prev_menu_item ? prev_menu_item->handleMouseUp(x, prev_menu_item->getRect().getHeight(), mask) : FALSE;
+ return (prev_menu_item && prev_menu_item->getVisible() && prev_menu_item->getEnabled()) ? prev_menu_item->handleMouseUp(x, prev_menu_item->getRect().getHeight(), mask) : FALSE;
}
else
{
LLView* next_menu_item = parent_menu->findPrevSibling(this);
- return next_menu_item ? next_menu_item->handleMouseUp(x, 0, mask) : FALSE;
+ return (next_menu_item && next_menu_item->getVisible() && next_menu_item->getEnabled()) ? next_menu_item->handleMouseUp(x, 0, mask) : FALSE;
}
}
@@ -1751,16 +1751,50 @@ void LLMenuGL::setCanTearOff(BOOL tear_off)
bool LLMenuGL::addChild(LLView* view, S32 tab_group)
{
- if (LLMenuGL* menup = dynamic_cast<LLMenuGL*>(view))
+ LLMenuGL* menup = dynamic_cast<LLMenuGL*>(view);
+ if (menup)
{
- appendMenu(menup);
- return true;
+ return appendMenu(menup);
}
- else if (LLMenuItemGL* itemp = dynamic_cast<LLMenuItemGL*>(view))
+
+ LLMenuItemGL* itemp = dynamic_cast<LLMenuItemGL*>(view);
+ if (itemp)
{
- append(itemp);
- return true;
+ return append(itemp);
}
+
+ return false;
+}
+
+// Used in LLContextMenu and in LLTogleableMenu
+
+// Add an item to the context menu branch
+bool LLMenuGL::addContextChild(LLView* view, S32 tab_group)
+{
+ LLContextMenu* context = dynamic_cast<LLContextMenu*>(view);
+ if (context)
+ {
+ return appendContextSubMenu(context);
+ }
+
+ LLMenuItemSeparatorGL* separator = dynamic_cast<LLMenuItemSeparatorGL*>(view);
+ if (separator)
+ {
+ return append(separator);
+ }
+
+ LLMenuItemGL* item = dynamic_cast<LLMenuItemGL*>(view);
+ if (item)
+ {
+ return append(item);
+ }
+
+ LLMenuGL* menup = dynamic_cast<LLMenuGL*>(view);
+ if (menup)
+ {
+ return appendMenu(menup);
+ }
+
return false;
}
@@ -2427,6 +2461,56 @@ void LLMenuGL::empty( void )
deleteAllChildren();
}
+// erase group of items from menu
+void LLMenuGL::erase( S32 begin, S32 end, bool arrange/* = true*/)
+{
+ S32 items = mItems.size();
+
+ if ( items == 0 || begin >= end || begin < 0 || end > items )
+ {
+ return;
+ }
+
+ item_list_t::iterator start_position = mItems.begin();
+ std::advance(start_position, begin);
+
+ item_list_t::iterator end_position = mItems.begin();
+ std::advance(end_position, end);
+
+ for (item_list_t::iterator position_iter = start_position; position_iter != end_position; position_iter++)
+ {
+ LLUICtrl::removeChild(*position_iter);
+ }
+
+ mItems.erase(start_position, end_position);
+
+ if (arrange)
+ {
+ needsArrange();
+ }
+}
+
+// add new item at position
+void LLMenuGL::insert( S32 position, LLView * ctrl, bool arrange /*= true*/ )
+{
+ LLMenuItemGL * item = dynamic_cast<LLMenuItemGL *>(ctrl);
+
+ if (NULL == item || position < 0 || position >= mItems.size())
+ {
+ return;
+ }
+
+ item_list_t::iterator position_iter = mItems.begin();
+ std::advance(position_iter, position);
+ mItems.insert(position_iter, item);
+ LLUICtrl::addChild(item);
+
+ if (arrange)
+ {
+ needsArrange();
+ }
+}
+
// Adjust rectangle of the menu
void LLMenuGL::setLeftAndBottom(S32 left, S32 bottom)
{
@@ -2468,7 +2552,8 @@ BOOL LLMenuGL::append( LLMenuItemGL* item )
// add a separator to this menu
BOOL LLMenuGL::addSeparator()
{
- LLMenuItemGL* separator = new LLMenuItemSeparatorGL();
+ LLMenuItemSeparatorGL::Params p;
+ LLMenuItemGL* separator = LLUICtrlFactory::create<LLMenuItemSeparatorGL>(p);
return addChild(separator);
}
@@ -2501,6 +2586,30 @@ BOOL LLMenuGL::appendMenu( LLMenuGL* menu )
return success;
}
+// add a context menu branch
+BOOL LLMenuGL::appendContextSubMenu(LLMenuGL *menu)
+{
+ if (menu == this)
+ {
+ llerrs << "Can't attach a context menu to itself" << llendl;
+ }
+
+ LLContextMenuBranch *item;
+ LLContextMenuBranch::Params p;
+ p.name = menu->getName();
+ p.label = menu->getLabel();
+ p.branch = (LLContextMenu *)menu;
+ p.enabled_color=LLUIColorTable::instance().getColor("MenuItemEnabledColor");
+ p.disabled_color=LLUIColorTable::instance().getColor("MenuItemDisabledColor");
+ p.highlight_bg_color=LLUIColorTable::instance().getColor("MenuItemHighlightBgColor");
+ p.highlight_fg_color=LLUIColorTable::instance().getColor("MenuItemHighlightFgColor");
+
+ item = LLUICtrlFactory::create<LLContextMenuBranch>(p);
+ LLMenuGL::sMenuContainer->addChild(item->getBranch());
+
+ return append( item );
+}
+
void LLMenuGL::setEnabledSubMenus(BOOL enable)
{
setEnabled(enable);
@@ -3037,11 +3146,29 @@ void LLMenuGL::showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y)
const S32 CURSOR_HEIGHT = 22; // Approximate "normal" cursor size
const S32 CURSOR_WIDTH = 12;
- if(menu->getChildList()->empty())
+ if (menu->getChildList()->empty())
{
return;
}
+ menu->setVisible( TRUE );
+
+ //Do not show menu if all menu items are disabled
+ BOOL item_enabled = false;
+ for (LLView::child_list_t::const_iterator itor = menu->getChildList()->begin();
+ itor != menu->getChildList()->end();
+ ++itor)
+ {
+ LLView *menu_item = (*itor);
+ item_enabled = item_enabled || menu_item->getEnabled();
+ }
+
+ if(!item_enabled)
+ {
+ menu->setVisible( FALSE );
+ return;
+ }
+
// Save click point for detecting cursor moves before mouse-up.
// Must be in local coords to compare with mouseUp events.
// If the mouse doesn't move, the menu will stay open ala the Mac.
@@ -3054,8 +3181,6 @@ void LLMenuGL::showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y)
menu->mFirstVisibleItem = NULL;
}
- menu->setVisible( TRUE );
-
// Fix menu rect if needed.
menu->needsArrange();
menu->arrangeAndClear();
@@ -3725,39 +3850,6 @@ void LLTearOffMenu::closeTearOff()
mMenu->setDropShadowed(TRUE);
}
-
-//-----------------------------------------------------------------------------
-// class LLContextMenuBranch
-// A branch to another context menu
-//-----------------------------------------------------------------------------
-class LLContextMenuBranch : public LLMenuItemGL
-{
-public:
- struct Params : public LLInitParam::Block<Params, LLMenuItemGL::Params>
- {
- Mandatory<LLContextMenu*> branch;
- };
-
- LLContextMenuBranch(const Params&);
-
- virtual ~LLContextMenuBranch()
- {}
-
- // called to rebuild the draw label
- virtual void buildDrawLabel( void );
-
- // onCommit() - do the primary funcationality of the menu item.
- virtual void onCommit( void );
-
- LLContextMenu* getBranch() { return mBranch.get(); }
- void setHighlight( BOOL highlight );
-
-protected:
- void showSubMenu();
-
- LLHandle<LLContextMenu> mBranch;
-};
-
LLContextMenuBranch::LLContextMenuBranch(const LLContextMenuBranch::Params& p)
: LLMenuItemGL(p),
mBranch( p.branch()->getHandle() )
@@ -3854,7 +3946,7 @@ void LLContextMenu::setVisible(BOOL visible)
}
// Takes cursor position in screen space?
-void LLContextMenu::show(S32 x, S32 y)
+void LLContextMenu::show(S32 x, S32 y, LLView* spawning_view)
{
if (getChildList()->empty())
{
@@ -3908,6 +4000,14 @@ void LLContextMenu::show(S32 x, S32 y)
setRect(rect);
arrange();
+ if (spawning_view)
+ {
+ mSpawningViewHandle = spawning_view->getHandle();
+ }
+ else
+ {
+ mSpawningViewHandle.markDead();
+ }
LLView::setVisible(TRUE);
}
@@ -4021,49 +4121,8 @@ BOOL LLContextMenu::handleRightMouseUp( S32 x, S32 y, MASK mask )
return result;
}
-void LLContextMenu::draw()
-{
- LLMenuGL::draw();
-}
-
-BOOL LLContextMenu::appendContextSubMenu(LLContextMenu *menu)
-{
-
- if (menu == this)
- {
- llerrs << "Can't attach a context menu to itself" << llendl;
- }
-
- LLContextMenuBranch *item;
- LLContextMenuBranch::Params p;
- p.name = menu->getName();
- p.label = menu->getLabel();
- p.branch = menu;
- p.enabled_color=LLUIColorTable::instance().getColor("MenuItemEnabledColor");
- p.disabled_color=LLUIColorTable::instance().getColor("MenuItemDisabledColor");
- p.highlight_bg_color=LLUIColorTable::instance().getColor("MenuItemHighlightBgColor");
- p.highlight_fg_color=LLUIColorTable::instance().getColor("MenuItemHighlightFgColor");
-
- item = LLUICtrlFactory::create<LLContextMenuBranch>(p);
- LLMenuGL::sMenuContainer->addChild(item->getBranch());
-
- return append( item );
-}
-
bool LLContextMenu::addChild(LLView* view, S32 tab_group)
{
- LLContextMenu* context = dynamic_cast<LLContextMenu*>(view);
- if (context)
- return appendContextSubMenu(context);
-
- LLMenuItemSeparatorGL* separator = dynamic_cast<LLMenuItemSeparatorGL*>(view);
- if (separator)
- return append(separator);
-
- LLMenuItemGL* item = dynamic_cast<LLMenuItemGL*>(view);
- if (item)
- return append(item);
-
- return false;
+ return addContextChild(view, tab_group);
}
diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h
index 36f3ba34b9..51df5df1f8 100644..100755
--- a/indra/llui/llmenugl.h
+++ b/indra/llui/llmenugl.h
@@ -478,6 +478,12 @@ public:
// remove all items on the menu
void empty( void );
+ // erase group of items from menu
+ void erase( S32 begin, S32 end, bool arrange = true );
+
+ // add new item at position
+ void insert( S32 begin, LLView * ctrl, bool arrange = true );
+
void setItemLastSelected(LLMenuItemGL* item); // must be in menu
U32 getItemCount(); // number of menu items
LLMenuItemGL* getItem(S32 number); // 0 = first item
@@ -519,6 +525,9 @@ public:
void resetScrollPositionOnShow(bool reset_scroll_pos) { mResetScrollPositionOnShow = reset_scroll_pos; }
bool isScrollPositionOnShowReset() { return mResetScrollPositionOnShow; }
+ // add a context menu branch
+ BOOL appendContextSubMenu(LLMenuGL *menu);
+
protected:
void createSpilloverBranch();
void cleanupSpilloverBranch();
@@ -528,6 +537,10 @@ protected:
// add a menu - this will create a cascading menu
virtual BOOL appendMenu( LLMenuGL* menu );
+ // Used in LLContextMenu and in LLTogleableMenu
+ // to add an item of context menu branch
+ bool addContextChild(LLView* view, S32 tab_group);
+
// TODO: create accessor methods for these?
typedef std::list< LLMenuItemGL* > item_list_t;
item_list_t mItems;
@@ -668,9 +681,7 @@ public:
// can't set visibility directly, must call show or hide
virtual void setVisible (BOOL visible);
- virtual void draw ();
-
- virtual void show (S32 x, S32 y);
+ virtual void show (S32 x, S32 y, LLView* spawning_view = NULL);
virtual void hide ();
virtual BOOL handleHover ( S32 x, S32 y, MASK mask );
@@ -679,16 +690,49 @@ public:
virtual bool addChild (LLView* view, S32 tab_group = 0);
- BOOL appendContextSubMenu(LLContextMenu *menu);
-
LLHandle<LLContextMenu> getHandle() { return getDerivedHandle<LLContextMenu>(); }
+ LLView* getSpawningView() const { return mSpawningViewHandle.get(); }
+ void setSpawningView(LLHandle<LLView> spawning_view) { mSpawningViewHandle = spawning_view; }
+
protected:
BOOL mHoveredAnyItem;
LLMenuItemGL* mHoverItem;
LLRootHandle<LLContextMenu> mHandle;
+ LLHandle<LLView> mSpawningViewHandle;
};
+//-----------------------------------------------------------------------------
+// class LLContextMenuBranch
+// A branch to another context menu
+//-----------------------------------------------------------------------------
+class LLContextMenuBranch : public LLMenuItemGL
+{
+public:
+ struct Params : public LLInitParam::Block<Params, LLMenuItemGL::Params>
+ {
+ Mandatory<LLContextMenu*> branch;
+ };
+
+ LLContextMenuBranch(const Params&);
+
+ virtual ~LLContextMenuBranch()
+ {}
+
+ // called to rebuild the draw label
+ virtual void buildDrawLabel( void );
+
+ // onCommit() - do the primary funcationality of the menu item.
+ virtual void onCommit( void );
+
+ LLContextMenu* getBranch() { return mBranch.get(); }
+ void setHighlight( BOOL highlight );
+
+protected:
+ void showSubMenu();
+
+ LLHandle<LLContextMenu> mBranch;
+};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/indra/llui/llmodaldialog.cpp b/indra/llui/llmodaldialog.cpp
index 8c2be44904..ff85b0ad09 100644..100755
--- a/indra/llui/llmodaldialog.cpp
+++ b/indra/llui/llmodaldialog.cpp
@@ -34,7 +34,7 @@
#include "llui.h"
#include "llwindow.h"
#include "llkeyboard.h"
-
+#include "llmenugl.h"
// static
std::list<LLModalDialog*> LLModalDialog::sModalStack;
@@ -161,6 +161,18 @@ void LLModalDialog::setVisible( BOOL visible )
BOOL LLModalDialog::handleMouseDown(S32 x, S32 y, MASK mask)
{
+ LLView* popup_menu = LLMenuGL::sMenuContainer->getVisibleMenu();
+ if (popup_menu != NULL)
+ {
+ S32 mx, my;
+ LLUI::getMousePositionScreen(&mx, &my);
+ LLRect menu_screen_rc = popup_menu->calcScreenRect();
+ if(!menu_screen_rc.pointInRect(mx, my))
+ {
+ LLMenuGL::sMenuContainer->hideMenus();
+ }
+ }
+
if (mModal)
{
if (!LLFloater::handleMouseDown(x, y, mask))
@@ -173,16 +185,34 @@ BOOL LLModalDialog::handleMouseDown(S32 x, S32 y, MASK mask)
{
LLFloater::handleMouseDown(x, y, mask);
}
+
+
return TRUE;
}
BOOL LLModalDialog::handleHover(S32 x, S32 y, MASK mask)
-{
+{
if( childrenHandleHover(x, y, mask) == NULL )
{
getWindow()->setCursor(UI_CURSOR_ARROW);
- lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << llendl;
+ lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << llendl;
}
+
+ LLView* popup_menu = LLMenuGL::sMenuContainer->getVisibleMenu();
+ if (popup_menu != NULL)
+ {
+ S32 mx, my;
+ LLUI::getMousePositionScreen(&mx, &my);
+ LLRect menu_screen_rc = popup_menu->calcScreenRect();
+ if(menu_screen_rc.pointInRect(mx, my))
+ {
+ S32 local_x = mx - popup_menu->getRect().mLeft;
+ S32 local_y = my - popup_menu->getRect().mBottom;
+ popup_menu->handleHover(local_x, local_y, mask);
+ gFocusMgr.setMouseCapture(NULL);
+ }
+ }
+
return TRUE;
}
@@ -210,6 +240,7 @@ BOOL LLModalDialog::handleDoubleClick(S32 x, S32 y, MASK mask)
BOOL LLModalDialog::handleRightMouseDown(S32 x, S32 y, MASK mask)
{
+ LLMenuGL::sMenuContainer->hideMenus();
childrenHandleRightMouseDown(x, y, mask);
return TRUE;
}
diff --git a/indra/llui/llmodaldialog.h b/indra/llui/llmodaldialog.h
index 4e09d11d77..f81273b96a 100644..100755
--- a/indra/llui/llmodaldialog.h
+++ b/indra/llui/llmodaldialog.h
@@ -40,7 +40,7 @@ class LLModalDialog : public LLFloater
{
public:
LLModalDialog( const LLSD& key, BOOL modal = true );
- /*virtual*/ ~LLModalDialog();
+ virtual ~LLModalDialog();
/*virtual*/ BOOL postBuild();
diff --git a/indra/llui/llmultifloater.cpp b/indra/llui/llmultifloater.cpp
index f3a48835b1..179b251cdb 100644..100755
--- a/indra/llui/llmultifloater.cpp
+++ b/indra/llui/llmultifloater.cpp
@@ -41,8 +41,8 @@ LLMultiFloater::LLMultiFloater(const LLSD& key, const LLFloater::Params& params)
mTabContainer(NULL),
mTabPos(LLTabContainer::TOP),
mAutoResize(TRUE),
- mOrigMinWidth(0),
- mOrigMinHeight(0)
+ mOrigMinWidth(params.min_width),
+ mOrigMinHeight(params.min_height)
{
}
@@ -173,7 +173,7 @@ void LLMultiFloater::addFloater(LLFloater* floaterp, BOOL select_added_floater,
else if (floaterp->getHost())
{
// floaterp is hosted by somebody else and
- // this is adding it, so remove it from it's old host
+ // this is adding it, so remove it from its old host
floaterp->getHost()->removeFloater(floaterp);
}
else if (floaterp->getParent() == gFloaterView)
@@ -188,11 +188,13 @@ void LLMultiFloater::addFloater(LLFloater* floaterp, BOOL select_added_floater,
floater_data.mHeight = floaterp->getRect().getHeight();
floater_data.mCanMinimize = floaterp->isMinimizeable();
floater_data.mCanResize = floaterp->isResizable();
+ floater_data.mSaveRect = floaterp->mSaveRect;
// remove minimize and close buttons
floaterp->setCanMinimize(FALSE);
floaterp->setCanResize(FALSE);
floaterp->setCanDrag(FALSE);
+ floaterp->mSaveRect = FALSE;
floaterp->storeRectControl();
// avoid double rendering of floater background (makes it more opaque)
floaterp->setBackgroundVisible(FALSE);
@@ -291,6 +293,7 @@ void LLMultiFloater::removeFloater(LLFloater* floaterp)
{
LLFloaterData& floater_data = found_data_it->second;
floaterp->setCanMinimize(floater_data.mCanMinimize);
+ floaterp->mSaveRect = floater_data.mSaveRect;
if (!floater_data.mCanResize)
{
// restore original size
@@ -349,7 +352,7 @@ void LLMultiFloater::setVisible(BOOL visible)
BOOL LLMultiFloater::handleKeyHere(KEY key, MASK mask)
{
- if (key == 'W' && mask == (MASK_CONTROL|MASK_SHIFT))
+ if (key == 'W' && mask == MASK_CONTROL)
{
LLFloater* floater = getActiveFloater();
// is user closeable and is system closeable
@@ -468,23 +471,12 @@ BOOL LLMultiFloater::postBuild()
void LLMultiFloater::updateResizeLimits()
{
- static LLUICachedControl<S32> tabcntr_close_btn_size ("UITabCntrCloseBtnSize", 0);
- const LLFloater::Params& default_params = LLFloater::getDefaultParams();
- S32 floater_header_size = default_params.header_height;
- S32 tabcntr_header_height = LLPANEL_BORDER_WIDTH + tabcntr_close_btn_size;
// initialize minimum size constraint to the original xml values.
S32 new_min_width = mOrigMinWidth;
S32 new_min_height = mOrigMinHeight;
- // possibly increase minimum size constraint due to children's minimums.
- for (S32 tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx)
- {
- LLFloater* floaterp = (LLFloater*)mTabContainer->getPanelByIndex(tab_idx);
- if (floaterp)
- {
- new_min_width = llmax(new_min_width, floaterp->getMinWidth() + LLPANEL_BORDER_WIDTH * 2);
- new_min_height = llmax(new_min_height, floaterp->getMinHeight() + floater_header_size + tabcntr_header_height);
- }
- }
+
+ computeResizeLimits(new_min_width, new_min_height);
+
setResizeLimits(new_min_width, new_min_height);
S32 cur_height = getRect().getHeight();
@@ -510,3 +502,22 @@ void LLMultiFloater::updateResizeLimits()
gFloaterView->adjustToFitScreen(this, TRUE);
}
}
+
+void LLMultiFloater::computeResizeLimits(S32& new_min_width, S32& new_min_height)
+{
+ static LLUICachedControl<S32> tabcntr_close_btn_size ("UITabCntrCloseBtnSize", 0);
+ const LLFloater::Params& default_params = LLFloater::getDefaultParams();
+ S32 floater_header_size = default_params.header_height;
+ S32 tabcntr_header_height = LLPANEL_BORDER_WIDTH + tabcntr_close_btn_size;
+
+ // possibly increase minimum size constraint due to children's minimums.
+ for (S32 tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx)
+ {
+ LLFloater* floaterp = (LLFloater*)mTabContainer->getPanelByIndex(tab_idx);
+ if (floaterp)
+ {
+ new_min_width = llmax(new_min_width, floaterp->getMinWidth() + LLPANEL_BORDER_WIDTH * 2);
+ new_min_height = llmax(new_min_height, floaterp->getMinHeight() + floater_header_size + tabcntr_header_height);
+ }
+ }
+}
diff --git a/indra/llui/llmultifloater.h b/indra/llui/llmultifloater.h
index 9fa917eca1..d992212650 100644..100755
--- a/indra/llui/llmultifloater.h
+++ b/indra/llui/llmultifloater.h
@@ -45,8 +45,8 @@ public:
virtual BOOL postBuild();
/*virtual*/ void onOpen(const LLSD& key);
- /*virtual*/ void draw();
- /*virtual*/ void setVisible(BOOL visible);
+ virtual void draw();
+ virtual void setVisible(BOOL visible);
/*virtual*/ BOOL handleKeyHere(KEY key, MASK mask);
/*virtual*/ bool addChild(LLView* view, S32 tab_group = 0);
@@ -79,10 +79,11 @@ public:
protected:
struct LLFloaterData
{
- S32 mWidth;
- S32 mHeight;
- BOOL mCanMinimize;
- BOOL mCanResize;
+ S32 mWidth;
+ S32 mHeight;
+ BOOL mCanMinimize;
+ BOOL mCanResize;
+ BOOL mSaveRect;
};
LLTabContainer* mTabContainer;
@@ -93,6 +94,9 @@ protected:
LLTabContainer::TabPosition mTabPos;
BOOL mAutoResize;
S32 mOrigMinWidth, mOrigMinHeight; // logically const but initialized late
+
+private:
+ virtual void computeResizeLimits(S32& new_min_width, S32& new_min_height);
};
#endif // LL_MULTI_FLOATER_H
diff --git a/indra/llui/llmultislider.cpp b/indra/llui/llmultislider.cpp
index 70bcfb5b4f..70bcfb5b4f 100644..100755
--- a/indra/llui/llmultislider.cpp
+++ b/indra/llui/llmultislider.cpp
diff --git a/indra/llui/llmultislider.h b/indra/llui/llmultislider.h
index 2b422e89c9..2b422e89c9 100644..100755
--- a/indra/llui/llmultislider.h
+++ b/indra/llui/llmultislider.h
diff --git a/indra/llui/llmultisliderctrl.cpp b/indra/llui/llmultisliderctrl.cpp
index 91e5b6b9de..91e5b6b9de 100644..100755
--- a/indra/llui/llmultisliderctrl.cpp
+++ b/indra/llui/llmultisliderctrl.cpp
diff --git a/indra/llui/llmultisliderctrl.h b/indra/llui/llmultisliderctrl.h
index b6a3542376..b6a3542376 100644..100755
--- a/indra/llui/llmultisliderctrl.h
+++ b/indra/llui/llmultisliderctrl.h
diff --git a/indra/llui/llnotificationptr.h b/indra/llui/llnotificationptr.h
index acc047527f..acc047527f 100644..100755
--- a/indra/llui/llnotificationptr.h
+++ b/indra/llui/llnotificationptr.h
diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp
index 8aa548b974..5c288c3f03 100644..100755
--- a/indra/llui/llnotifications.cpp
+++ b/indra/llui/llnotifications.cpp
@@ -39,7 +39,6 @@
#include "lldir.h"
#include "llsdserialize.h"
#include "lltrans.h"
-#include "llnotificationslistener.h"
#include "llstring.h"
#include "llsdparam.h"
#include "llsdutil.h"
@@ -60,7 +59,8 @@ void NotificationPriorityValues::declareValues()
}
LLNotificationForm::FormElementBase::FormElementBase()
-: name("name")
+: name("name"),
+ enabled("enabled", true)
{}
LLNotificationForm::FormIgnore::FormIgnore()
@@ -104,39 +104,7 @@ LLNotificationForm::Params::Params()
form_elements("")
{}
-// Local channel for persistent notifications
-// Stores only persistent notifications.
-// Class users can use connectChanged() to process persistent notifications
-// (see LLNotificationStorage for example).
-class LLPersistentNotificationChannel : public LLNotificationChannel
-{
- LOG_CLASS(LLPersistentNotificationChannel);
-public:
- LLPersistentNotificationChannel() :
- LLNotificationChannel("Persistent", "Visible", &notificationFilter, LLNotificationComparators::orderByUUID())
- {
- }
-
-private:
-
- // The channel gets all persistent notifications except those that have been canceled
- static bool notificationFilter(LLNotificationPtr pNotification)
- {
- bool handle_notification = false;
-
- handle_notification = pNotification->isPersistent()
- && !pNotification->isCancelled();
-
- return handle_notification;
- }
- void onDelete(LLNotificationPtr pNotification)
- {
- // we want to keep deleted notifications in our log, otherwise some
- // notifications will be lost on exit.
- mItems.insert(pNotification);
- }
-};
bool filterIgnoredNotifications(LLNotificationPtr notification)
{
@@ -210,6 +178,14 @@ LLNotificationForm::LLNotificationForm()
{
}
+LLNotificationForm::LLNotificationForm( const LLNotificationForm& other )
+{
+ mFormData = other.mFormData;
+ mIgnore = other.mIgnore;
+ mIgnoreMsg = other.mIgnoreMsg;
+ mIgnoreSetting = other.mIgnoreSetting;
+ mInvertSetting = other.mInvertSetting;
+}
LLNotificationForm::LLNotificationForm(const std::string& name, const LLNotificationForm::Params& p)
: mIgnore(IGNORE_NO),
@@ -238,7 +214,7 @@ LLNotificationForm::LLNotificationForm(const std::string& name, const LLNotifica
}
else
{
- LLUI::sSettingGroups["ignores"]->declareBOOL(name, show_notification, "Show notification with this name", TRUE);
+ LLUI::sSettingGroups["ignores"]->declareBOOL(name, show_notification, "Show notification with this name", LLControlVariable::PERSIST_NONDFT);
mIgnoreSetting = LLUI::sSettingGroups["ignores"]->getControl(name);
}
}
@@ -246,14 +222,6 @@ LLNotificationForm::LLNotificationForm(const std::string& name, const LLNotifica
LLParamSDParser parser;
parser.writeSD(mFormData, p.form_elements);
- if (!mFormData.isArray())
- {
- // change existing contents to a one element array
- LLSD new_llsd_array = LLSD::emptyArray();
- new_llsd_array.append(mFormData);
- mFormData = new_llsd_array;
- }
-
for (LLSD::array_iterator it = mFormData.beginArray(), end_it = mFormData.endArray();
it != end_it;
++it)
@@ -300,7 +268,7 @@ LLSD LLNotificationForm::getElement(const std::string& element_name)
}
-bool LLNotificationForm::hasElement(const std::string& element_name)
+bool LLNotificationForm::hasElement(const std::string& element_name) const
{
for (LLSD::array_const_iterator it = mFormData.beginArray();
it != mFormData.endArray();
@@ -311,7 +279,48 @@ bool LLNotificationForm::hasElement(const std::string& element_name)
return false;
}
-void LLNotificationForm::addElement(const std::string& type, const std::string& name, const LLSD& value)
+void LLNotificationForm::getElements(LLSD& elements, S32 offset)
+{
+ //Finds elements that the template did not add
+ LLSD::array_const_iterator it = mFormData.beginArray() + offset;
+
+ //Keeps track of only the dynamic elements
+ for(; it != mFormData.endArray(); ++it)
+ {
+ elements.append(*it);
+ }
+}
+
+bool LLNotificationForm::getElementEnabled(const std::string& element_name) const
+{
+ for (LLSD::array_const_iterator it = mFormData.beginArray();
+ it != mFormData.endArray();
+ ++it)
+ {
+ if ((*it)["name"].asString() == element_name)
+ {
+ return (*it)["enabled"].asBoolean();
+ }
+ }
+
+ return false;
+}
+
+void LLNotificationForm::setElementEnabled(const std::string& element_name, bool enabled)
+{
+ for (LLSD::array_iterator it = mFormData.beginArray();
+ it != mFormData.endArray();
+ ++it)
+ {
+ if ((*it)["name"].asString() == element_name)
+ {
+ (*it)["enabled"] = enabled;
+ }
+ }
+}
+
+
+void LLNotificationForm::addElement(const std::string& type, const std::string& name, const LLSD& value, bool enabled)
{
LLSD element;
element["type"] = type;
@@ -319,6 +328,7 @@ void LLNotificationForm::addElement(const std::string& type, const std::string&
element["text"] = name;
element["value"] = value;
element["index"] = mFormData.size();
+ element["enabled"] = enabled;
mFormData.append(element);
}
@@ -399,6 +409,7 @@ LLNotificationTemplate::LLNotificationTemplate(const LLNotificationTemplate::Par
: mName(p.name),
mType(p.type),
mMessage(p.value),
+ mFooter(p.footer.value),
mLabel(p.label),
mIcon(p.icon),
mURL(p.url.value),
@@ -407,14 +418,19 @@ LLNotificationTemplate::LLNotificationTemplate(const LLNotificationTemplate::Par
mURLOption(p.url.option),
mURLTarget(p.url.target),
mUnique(p.unique.isProvided()),
+ mCombineBehavior(p.unique.combine),
mPriority(p.priority),
mPersist(p.persist),
- mDefaultFunctor(p.functor.isProvided() ? p.functor() : p.name())
+ mDefaultFunctor(p.functor.isProvided() ? p.functor() : p.name()),
+ mLogToChat(p.log_to_chat),
+ mLogToIM(p.log_to_im),
+ mShowToast(p.show_toast),
+ mSoundName("")
{
if (p.sound.isProvided()
&& LLUI::sSettingGroups["config"]->controlExists(p.sound))
{
- mSoundEffect = LLUUID(LLUI::sSettingGroups["config"]->getString(p.sound));
+ mSoundName = p.sound;
}
BOOST_FOREACH(const LLNotificationTemplate::UniquenessContext& context, p.unique.contexts)
@@ -459,18 +475,20 @@ LLNotificationVisibilityRule::LLNotificationVisibilityRule(const LLNotificationV
}
}
-LLNotification::LLNotification(const LLNotification::Params& p) :
+LLNotification::LLNotification(const LLSDParamAdapter<Params>& p) :
mTimestamp(p.time_stamp),
mSubstitutions(p.substitutions),
mPayload(p.payload),
- mExpiresAt(0),
+ mExpiresAt(p.expiry),
mTemporaryResponder(false),
mRespondedTo(false),
mPriority(p.priority),
mCancelled(false),
mIgnored(false),
mResponderObj(NULL),
- mIsReusable(false)
+ mId(p.id.isProvided() ? p.id : LLUUID::generateNewID()),
+ mOfferFromAgent(p.offer_from_agent),
+ mIsDND(p.is_dnd)
{
if (p.functor.name.isChosen())
{
@@ -493,52 +511,52 @@ LLNotification::LLNotification(const LLNotification::Params& p) :
mResponderObj = p.responder;
}
- mId.generate();
init(p.name, p.form_elements);
}
-LLNotification::LLNotification(const LLSD& sd) :
- mTemporaryResponder(false),
- mRespondedTo(false),
- mCancelled(false),
- mIgnored(false),
- mResponderObj(NULL),
- mIsReusable(false)
-{
- mId.generate();
- mSubstitutions = sd["substitutions"];
- mPayload = sd["payload"];
- mTimestamp = sd["time"];
- mExpiresAt = sd["expiry"];
- mPriority = (ENotificationPriority)sd["priority"].asInteger();
- mResponseFunctorName = sd["responseFunctor"].asString();
- std::string templatename = sd["name"].asString();
- init(templatename, LLSD());
- // replace form with serialized version
- mForm = LLNotificationFormPtr(new LLNotificationForm(sd["form"]));
-}
-
-
-LLSD LLNotification::asLLSD()
+LLSD LLNotification::asLLSD(bool excludeTemplateElements)
{
- LLSD output;
- output["id"] = mId;
- output["name"] = mTemplatep->mName;
- output["form"] = getForm()->asLLSD();
- output["substitutions"] = mSubstitutions;
- output["payload"] = mPayload;
- output["time"] = mTimestamp;
- output["expiry"] = mExpiresAt;
- output["priority"] = (S32)mPriority;
- output["responseFunctor"] = mResponseFunctorName;
- output["reusable"] = mIsReusable;
+ LLParamSDParser parser;
- if(mResponder)
- {
- output["responder"] = mResponder->asLLSD();
+ Params p;
+ p.id = mId;
+ p.name = mTemplatep->mName;
+ p.substitutions = mSubstitutions;
+ p.payload = mPayload;
+ p.time_stamp = mTimestamp;
+ p.expiry = mExpiresAt;
+ p.priority = mPriority;
+
+ LLNotificationFormPtr templateForm = mTemplatep->mForm;
+ LLSD formElements = mForm->asLLSD();
+
+ //All form elements (dynamic or not)
+ if(!excludeTemplateElements)
+ {
+ p.form_elements = formElements;
+ }
+ //Only dynamic form elements (exclude template elements)
+ else if(templateForm->getNumElements() < formElements.size())
+ {
+ LLSD dynamicElements;
+ //Offset to dynamic elements and store them
+ mForm->getElements(dynamicElements, templateForm->getNumElements());
+ p.form_elements = dynamicElements;
+ }
+
+ if(mResponder)
+ {
+ p.functor.responder_sd = mResponder->asLLSD();
+ }
+
+ if(!mResponseFunctorName.empty())
+ {
+ p.functor.name = mResponseFunctorName;
}
+ LLSD output;
+ parser.writeSD(output, p);
return output;
}
@@ -568,7 +586,6 @@ void LLNotification::updateFrom(LLNotificationPtr other)
mRespondedTo = other->mRespondedTo;
mResponse = other->mResponse;
mTemporaryResponder = other->mTemporaryResponder;
- mIsReusable = other->isReusable();
update();
}
@@ -667,7 +684,7 @@ void LLNotification::respond(const LLSD& response)
return;
}
- if (mTemporaryResponder && !isReusable())
+ if (mTemporaryResponder)
{
LLNotificationFunctorRegistry::instance().unregisterFunctor(mResponseFunctorName);
mResponseFunctorName = "";
@@ -828,7 +845,7 @@ void LLNotification::init(const std::string& template_name, const LLSD& form_ele
//mSubstitutions["_ARGS"] = get_all_arguments_as_text(mSubstitutions);
mForm = LLNotificationFormPtr(new LLNotificationForm(*mTemplatep->mForm));
- mForm->append(form_elements);
+ mForm->append(form_elements);
// apply substitution to form labels
mForm->formatElements(mSubstitutions);
@@ -870,6 +887,16 @@ std::string LLNotification::getMessage() const
return message;
}
+std::string LLNotification::getFooter() const
+{
+ if (!mTemplatep)
+ return std::string();
+
+ std::string footer = mTemplatep->mFooter;
+ LLStringUtil::format(footer, mSubstitutions);
+ return footer;
+}
+
std::string LLNotification::getLabel() const
{
std::string label = mTemplatep->mLabel;
@@ -886,6 +913,49 @@ std::string LLNotification::getURL() const
return (mTemplatep ? url : "");
}
+bool LLNotification::canLogToChat() const
+{
+ return mTemplatep->mLogToChat;
+}
+
+bool LLNotification::canLogToIM() const
+{
+ return mTemplatep->mLogToIM;
+}
+
+bool LLNotification::canShowToast() const
+{
+ return mTemplatep->mShowToast;
+}
+
+bool LLNotification::hasFormElements() const
+{
+ return mTemplatep->mForm->getNumElements() != 0;
+}
+
+void LLNotification::playSound()
+{
+ make_ui_sound(mTemplatep->mSoundName.c_str());
+}
+
+LLNotification::ECombineBehavior LLNotification::getCombineBehavior() const
+{
+ return mTemplatep->mCombineBehavior;
+}
+
+void LLNotification::updateForm( const LLNotificationFormPtr& form )
+{
+ mForm = form;
+}
+
+void LLNotification::repost()
+{
+ mRespondedTo = false;
+ LLNotifications::instance().update(shared_from_this());
+}
+
+
+
// =========================================================
// LLNotificationChannel implementation
// ---
@@ -946,7 +1016,7 @@ bool LLNotificationChannelBase::updateItem(const LLSD& payload, LLNotificationPt
std::string cmd = payload["sigtype"];
LLNotificationSet::iterator foundItem = mItems.find(pNotification);
bool wasFound = (foundItem != mItems.end());
- bool passesFilter = mFilter(pNotification);
+ bool passesFilter = mFilter ? mFilter(pNotification) : true;
// first, we offer the result of the filter test to the simple
// signals for pass/fail. One of these is guaranteed to be called.
@@ -955,10 +1025,12 @@ bool LLNotificationChannelBase::updateItem(const LLSD& payload, LLNotificationPt
bool abortProcessing = false;
if (passesFilter)
{
+ onFilterPass(pNotification);
abortProcessing = mPassedFilter(payload);
}
else
{
+ onFilterFail(pNotification);
abortProcessing = mFailedFilter(payload);
}
@@ -976,8 +1048,8 @@ bool LLNotificationChannelBase::updateItem(const LLSD& payload, LLNotificationPt
{
// not in our list, add it and say so
mItems.insert(pNotification);
- abortProcessing = mChanged(payload);
onLoad(pNotification);
+ abortProcessing = mChanged(payload);
}
}
else if (cmd == "change")
@@ -992,18 +1064,18 @@ bool LLNotificationChannelBase::updateItem(const LLSD& payload, LLNotificationPt
{
// it already existed, so this is a change
// since it changed in place, all we have to do is resend the signal
- abortProcessing = mChanged(payload);
onChange(pNotification);
+ abortProcessing = mChanged(payload);
}
else
{
// not in our list, add it and say so
mItems.insert(pNotification);
+ onChange(pNotification);
// our payload is const, so make a copy before changing it
LLSD newpayload = payload;
newpayload["sigtype"] = "add";
abortProcessing = mChanged(newpayload);
- onChange(pNotification);
}
}
else
@@ -1012,11 +1084,11 @@ bool LLNotificationChannelBase::updateItem(const LLSD& payload, LLNotificationPt
{
// it already existed, so this is a delete
mItems.erase(pNotification);
+ onChange(pNotification);
// our payload is const, so make a copy before changing it
LLSD newpayload = payload;
newpayload["sigtype"] = "delete";
abortProcessing = mChanged(newpayload);
- onChange(pNotification);
}
// didn't pass, not on our list, do nothing
}
@@ -1030,8 +1102,8 @@ bool LLNotificationChannelBase::updateItem(const LLSD& payload, LLNotificationPt
{
// not in our list, add it and say so
mItems.insert(pNotification);
- abortProcessing = mChanged(payload);
onAdd(pNotification);
+ abortProcessing = mChanged(payload);
}
}
else if (cmd == "delete")
@@ -1039,65 +1111,35 @@ bool LLNotificationChannelBase::updateItem(const LLSD& payload, LLNotificationPt
// if we have it in our list, pass on the delete, then delete it, else do nothing
if (wasFound)
{
+ onDelete(pNotification);
abortProcessing = mChanged(payload);
- // do not delete the notification to make LLChatHistory::appendMessage add notification panel to IM window
- if( ! pNotification->isReusable() )
- {
- mItems.erase(pNotification);
- onDelete(pNotification);
- }
+ mItems.erase(pNotification);
}
}
return abortProcessing;
}
-/* static */
-LLNotificationChannelPtr LLNotificationChannel::buildChannel(const std::string& name,
- const std::string& parent,
- LLNotificationFilter filter,
- LLNotificationComparator comparator)
+LLNotificationChannel::LLNotificationChannel(const Params& p)
+: LLNotificationChannelBase(p.filter()),
+ LLInstanceTracker<LLNotificationChannel, std::string>(p.name.isProvided() ? p.name : LLUUID::generateNewID().asString()),
+ mName(p.name.isProvided() ? p.name : LLUUID::generateNewID().asString())
{
- // note: this is not a leak; notifications are self-registering.
- // This factory helps to prevent excess deletions by making sure all smart
- // pointers to notification channels come from the same source
- new LLNotificationChannel(name, parent, filter, comparator);
- return LLNotifications::instance().getChannel(name);
+ BOOST_FOREACH(const std::string& source, p.sources)
+ {
+ connectToChannel(source);
+ }
}
LLNotificationChannel::LLNotificationChannel(const std::string& name,
const std::string& parent,
- LLNotificationFilter filter,
- LLNotificationComparator comparator) :
-LLNotificationChannelBase(filter, comparator),
-mName(name),
-mParent(parent)
-{
- // store myself in the channel map
- LLNotifications::instance().addChannel(LLNotificationChannelPtr(this));
+ LLNotificationFilter filter)
+: LLNotificationChannelBase(filter),
+ LLInstanceTracker<LLNotificationChannel, std::string>(name),
+ mName(name)
+{
// bind to notification broadcast
- if (parent.empty())
- {
- LLNotifications::instance().connectChanged(
- boost::bind(&LLNotificationChannelBase::updateItem, this, _1));
- }
- else
- {
- LLNotificationChannelPtr p = LLNotifications::instance().getChannel(parent);
- p->connectChanged(boost::bind(&LLNotificationChannelBase::updateItem, this, _1));
- }
-}
-
-
-void LLNotificationChannel::setComparator(LLNotificationComparator comparator)
-{
- mComparator = comparator;
- LLNotificationSet s2(mComparator);
- s2.insert(mItems.begin(), mItems.end());
- mItems.swap(s2);
-
- // notify clients that we've been resorted
- mChanged(LLSD().with("sigtype", "sort"));
+ connectToChannel(parent);
}
bool LLNotificationChannel::isEmpty() const
@@ -1105,6 +1147,11 @@ bool LLNotificationChannel::isEmpty() const
return mItems.empty();
}
+S32 LLNotificationChannel::size() const
+{
+ return mItems.size();
+}
+
LLNotificationChannel::Iterator LLNotificationChannel::begin()
{
return mItems.begin();
@@ -1115,6 +1162,11 @@ LLNotificationChannel::Iterator LLNotificationChannel::end()
return mItems.end();
}
+size_t LLNotificationChannel::size()
+{
+ return mItems.size();
+}
+
std::string LLNotificationChannel::summarize()
{
std::string s("Channel '");
@@ -1128,24 +1180,40 @@ std::string LLNotificationChannel::summarize()
return s;
}
+void LLNotificationChannel::connectToChannel( const std::string& channel_name )
+{
+ if (channel_name.empty())
+ {
+ LLNotifications::instance().connectChanged(
+ boost::bind(&LLNotificationChannelBase::updateItem, this, _1));
+ }
+ else
+ {
+ LLNotificationChannelPtr p = LLNotifications::instance().getChannel(channel_name);
+ p->connectChanged(boost::bind(&LLNotificationChannelBase::updateItem, this, _1));
+ }
+}
// ---
// END OF LLNotificationChannel implementation
// =========================================================
-// =========================================================
+// ============================================== ===========
// LLNotifications implementation
// ---
-LLNotifications::LLNotifications() : LLNotificationChannelBase(LLNotificationFilters::includeEverything,
- LLNotificationComparators::orderByUUID()),
- mIgnoreAllNotifications(false)
+LLNotifications::LLNotifications()
+: LLNotificationChannelBase(LLNotificationFilters::includeEverything),
+ mIgnoreAllNotifications(false)
{
+ mListener.reset(new LLNotificationsListener(*this));
LLUICtrl::CommitCallbackRegistry::currentRegistrar().add("Notification.Show", boost::bind(&LLNotifications::addFromCallback, this, _2));
-
- mListener.reset(new LLNotificationsListener(*this));
}
+void LLNotifications::clear()
+{
+ mDefaultChannels.clear();
+}
// The expiration channel gets all notifications that are cancelled
bool LLNotifications::expirationFilter(LLNotificationPtr pNotification)
@@ -1180,7 +1248,15 @@ bool LLNotifications::uniqueFilter(LLNotificationPtr pNotif)
if (pNotif != existing_notification
&& pNotif->isEquivalentTo(existing_notification))
{
- return false;
+ if (pNotif->getCombineBehavior() == LLNotification::CANCEL_OLD)
+ {
+ cancel(existing_notification);
+ return true;
+ }
+ else
+ {
+ return false;
+ }
}
}
@@ -1220,43 +1296,43 @@ bool LLNotifications::failedUniquenessTest(const LLSD& payload)
return false;
}
- // Update the existing unique notification with the data from this particular instance...
- // This guarantees that duplicate notifications will be collapsed to the one
- // most recently triggered
- for (LLNotificationMap::iterator existing_it = mUniqueNotifications.find(pNotif->getName());
- existing_it != mUniqueNotifications.end();
- ++existing_it)
+ switch(pNotif->getCombineBehavior())
{
- LLNotificationPtr existing_notification = existing_it->second;
- if (pNotif != existing_notification
- && pNotif->isEquivalentTo(existing_notification))
+ case LLNotification::REPLACE_WITH_NEW:
+ // Update the existing unique notification with the data from this particular instance...
+ // This guarantees that duplicate notifications will be collapsed to the one
+ // most recently triggered
+ for (LLNotificationMap::iterator existing_it = mUniqueNotifications.find(pNotif->getName());
+ existing_it != mUniqueNotifications.end();
+ ++existing_it)
{
- // copy notification instance data over to oldest instance
- // of this unique notification and update it
- existing_notification->updateFrom(pNotif);
- // then delete the new one
- cancel(pNotif);
+ LLNotificationPtr existing_notification = existing_it->second;
+ if (pNotif != existing_notification
+ && pNotif->isEquivalentTo(existing_notification))
+ {
+ // copy notification instance data over to oldest instance
+ // of this unique notification and update it
+ existing_notification->updateFrom(pNotif);
+ // then delete the new one
+ cancel(pNotif);
+ }
}
+ break;
+ case LLNotification::KEEP_OLD:
+ break;
+ case LLNotification::CANCEL_OLD:
+ // already handled by filter logic
+ break;
+ default:
+ break;
}
return false;
}
-
-void LLNotifications::addChannel(LLNotificationChannelPtr pChan)
-{
- mChannels[pChan->getName()] = pChan;
-}
-
LLNotificationChannelPtr LLNotifications::getChannel(const std::string& channelName)
{
- ChannelMap::iterator p = mChannels.find(channelName);
- if(p == mChannels.end())
- {
- llerrs << "Did not find channel named " << channelName << llendl;
- return LLNotificationChannelPtr();
- }
- return p->second;
+ return LLNotificationChannelPtr(LLNotificationChannel::getInstance(channelName));
}
@@ -1272,24 +1348,21 @@ void LLNotifications::createDefaultChannels()
{
// now construct the various channels AFTER loading the notifications,
// because the history channel is going to rewrite the stored notifications file
- LLNotificationChannel::buildChannel("Enabled", "",
- !boost::bind(&LLNotifications::getIgnoreAllNotifications, this));
- LLNotificationChannel::buildChannel("Expiration", "Enabled",
- boost::bind(&LLNotifications::expirationFilter, this, _1));
- LLNotificationChannel::buildChannel("Unexpired", "Enabled",
- !boost::bind(&LLNotifications::expirationFilter, this, _1)); // use negated bind
- LLNotificationChannel::buildChannel("Unique", "Unexpired",
- boost::bind(&LLNotifications::uniqueFilter, this, _1));
- LLNotificationChannel::buildChannel("Ignore", "Unique",
- filterIgnoredNotifications);
- LLNotificationChannel::buildChannel("VisibilityRules", "Ignore",
- boost::bind(&LLNotifications::isVisibleByRules, this, _1));
- LLNotificationChannel::buildChannel("Visible", "VisibilityRules",
- &LLNotificationFilters::includeEverything);
-
- // create special persistent notification channel
- // this isn't a leak, don't worry about the empty "new"
- new LLPersistentNotificationChannel();
+ mDefaultChannels.push_back(new LLNotificationChannel("Enabled", "",
+ !boost::bind(&LLNotifications::getIgnoreAllNotifications, this)));
+ mDefaultChannels.push_back(new LLNotificationChannel("Expiration", "Enabled",
+ boost::bind(&LLNotifications::expirationFilter, this, _1)));
+ mDefaultChannels.push_back(new LLNotificationChannel("Unexpired", "Enabled",
+ !boost::bind(&LLNotifications::expirationFilter, this, _1))); // use negated bind
+ mDefaultChannels.push_back(new LLNotificationChannel("Unique", "Unexpired",
+ boost::bind(&LLNotifications::uniqueFilter, this, _1)));
+ mDefaultChannels.push_back(new LLNotificationChannel("Ignore", "Unique",
+ filterIgnoredNotifications));
+ mDefaultChannels.push_back(new LLNotificationChannel("VisibilityRules", "Ignore",
+ boost::bind(&LLNotifications::isVisibleByRules, this, _1)));
+ mDefaultChannels.push_back(new LLNotificationChannel("Visible", "VisibilityRules",
+ &LLNotificationFilters::includeEverything));
+ mDefaultChannels.push_back(new LLPersistentNotificationChannel());
// connect action methods to these channels
LLNotifications::instance().getChannel("Enabled")->
@@ -1413,25 +1486,19 @@ void addPathIfExists(const std::string& new_path, std::vector<std::string>& path
bool LLNotifications::loadTemplates()
{
llinfos << "Reading notifications template" << llendl;
- std::vector<std::string> search_paths;
-
- std::string skin_relative_path = gDirUtilp->getDirDelimiter() + LLUI::getSkinPath() + gDirUtilp->getDirDelimiter() + "notifications.xml";
- std::string localized_skin_relative_path = gDirUtilp->getDirDelimiter() + LLUI::getLocalizedSkinPath() + gDirUtilp->getDirDelimiter() + "notifications.xml";
-
- addPathIfExists(gDirUtilp->getDefaultSkinDir() + skin_relative_path, search_paths);
- addPathIfExists(gDirUtilp->getDefaultSkinDir() + localized_skin_relative_path, search_paths);
- addPathIfExists(gDirUtilp->getSkinDir() + skin_relative_path, search_paths);
- addPathIfExists(gDirUtilp->getSkinDir() + localized_skin_relative_path, search_paths);
- addPathIfExists(gDirUtilp->getUserSkinDir() + skin_relative_path, search_paths);
- addPathIfExists(gDirUtilp->getUserSkinDir() + localized_skin_relative_path, search_paths);
+ // Passing findSkinnedFilenames(constraint=LLDir::ALL_SKINS) makes it
+ // output all relevant pathnames instead of just the ones from the most
+ // specific skin.
+ std::vector<std::string> search_paths =
+ gDirUtilp->findSkinnedFilenames(LLDir::XUI, "notifications.xml", LLDir::ALL_SKINS);
std::string base_filename = search_paths.front();
LLXMLNodePtr root;
BOOL success = LLXMLNode::getLayeredXMLNode(root, search_paths);
-
+
if (!success || root.isNull() || !root->hasName( "notifications" ))
{
- llerrs << "Problem reading UI Notifications file: " << base_filename << llendl;
+ llerrs << "Problem reading XML from UI Notifications file: " << base_filename << llendl;
return false;
}
@@ -1441,7 +1508,7 @@ bool LLNotifications::loadTemplates()
if(!params.validateBlock())
{
- llerrs << "Problem reading UI Notifications file: " << base_filename << llendl;
+ llerrs << "Problem reading XUI from UI Notifications file: " << base_filename << llendl;
return false;
}
@@ -1477,6 +1544,10 @@ bool LLNotifications::loadTemplates()
{
replaceFormText(notification.form_ref.form, "$canceltext", notification.form_ref.form_template.cancel_text);
}
+ if(notification.form_ref.form_template.help_text.isProvided())
+ {
+ replaceFormText(notification.form_ref.form, "$helptext", notification.form_ref.form_template.help_text);
+ }
if(notification.form_ref.form_template.ignore_text.isProvided())
{
replaceFormText(notification.form_ref.form, "$ignoretext", notification.form_ref.form_template.ignore_text);
@@ -1493,7 +1564,9 @@ bool LLNotifications::loadTemplates()
bool LLNotifications::loadVisibilityRules()
{
const std::string xml_filename = "notification_visibility.xml";
- std::string full_filename = gDirUtilp->findSkinnedFilename(LLUI::getXUIPaths().front(), xml_filename);
+ // Note that here we're looking for the "en" version, the default
+ // language, rather than the most localized version of this file.
+ std::string full_filename = gDirUtilp->findSkinnedFilenameBaseLang(LLDir::XUI, xml_filename);
LLNotificationVisibilityRule::Rules params;
LLSimpleXUIParser parser;
@@ -1521,34 +1594,32 @@ void LLNotifications::addFromCallback(const LLSD& name)
add(name.asString(), LLSD(), LLSD());
}
-LLNotificationPtr LLNotifications::add(const std::string& name,
- const LLSD& substitutions,
- const LLSD& payload)
+LLNotificationPtr LLNotifications::add(const std::string& name, const LLSD& substitutions, const LLSD& payload)
{
LLNotification::Params::Functor functor_p;
functor_p.name = name;
return add(LLNotification::Params().name(name).substitutions(substitutions).payload(payload).functor(functor_p));
}
-LLNotificationPtr LLNotifications::add(const std::string& name,
- const LLSD& substitutions,
- const LLSD& payload,
- const std::string& functor_name)
+LLNotificationPtr LLNotifications::add(const std::string& name, const LLSD& substitutions, const LLSD& payload, const std::string& functor_name)
{
LLNotification::Params::Functor functor_p;
functor_p.name = functor_name;
- return add(LLNotification::Params().name(name).substitutions(substitutions).payload(payload).functor(functor_p));
+ return add(LLNotification::Params().name(name)
+ .substitutions(substitutions)
+ .payload(payload)
+ .functor(functor_p));
}
//virtual
-LLNotificationPtr LLNotifications::add(const std::string& name,
- const LLSD& substitutions,
- const LLSD& payload,
- LLNotificationFunctorRegistry::ResponseFunctor functor)
+LLNotificationPtr LLNotifications::add(const std::string& name, const LLSD& substitutions, const LLSD& payload, LLNotificationFunctorRegistry::ResponseFunctor functor)
{
LLNotification::Params::Functor functor_p;
functor_p.function = functor;
- return add(LLNotification::Params().name(name).substitutions(substitutions).payload(payload).functor(functor_p));
+ return add(LLNotification::Params().name(name)
+ .substitutions(substitutions)
+ .payload(payload)
+ .functor(functor_p));
}
// generalized add function that takes a parameter block object for more complex instantiations
@@ -1579,12 +1650,11 @@ void LLNotifications::cancel(LLNotificationPtr pNotif)
if (pNotif == NULL || pNotif->isCancelled()) return;
LLNotificationSet::iterator it=mItems.find(pNotif);
- if (it == mItems.end())
+ if (it != mItems.end())
{
- llerrs << "Attempted to delete nonexistent notification " << pNotif->getName() << llendl;
+ pNotif->cancel();
+ updateItem(LLSD().with("sigtype", "delete").with("id", pNotif->id()), pNotif);
}
- pNotif->cancel();
- updateItem(LLSD().with("sigtype", "delete").with("id", pNotif->id()), pNotif);
}
void LLNotifications::cancelByName(const std::string& name)
@@ -1623,7 +1693,7 @@ void LLNotifications::update(const LLNotificationPtr pNotif)
LLNotificationPtr LLNotifications::find(LLUUID uuid)
{
- LLNotificationPtr target = LLNotificationPtr(new LLNotification(uuid));
+ LLNotificationPtr target = LLNotificationPtr(new LLNotification(LLNotification::Params().id(uuid)));
LLNotificationSet::iterator it=mItems.find(target);
if (it == mItems.end())
{
@@ -1762,22 +1832,18 @@ std::ostream& operator<<(std::ostream& s, const LLNotification& notification)
return s;
}
-//static
-void LLPostponedNotification::lookupName(LLPostponedNotification* thiz,
- const LLUUID& id,
+void LLPostponedNotification::lookupName(const LLUUID& id,
bool is_group)
{
if (is_group)
{
gCacheName->getGroup(id,
boost::bind(&LLPostponedNotification::onGroupNameCache,
- thiz, _1, _2, _3));
+ this, _1, _2, _3));
}
else
{
- LLAvatarNameCache::get(id,
- boost::bind(&LLPostponedNotification::onAvatarNameCache,
- thiz, _1, _2));
+ fetchAvatarName(id);
}
}
@@ -1788,9 +1854,24 @@ void LLPostponedNotification::onGroupNameCache(const LLUUID& id,
finalizeName(full_name);
}
+void LLPostponedNotification::fetchAvatarName(const LLUUID& id)
+{
+ if (id.notNull())
+ {
+ if (mAvatarNameCacheConnection.connected())
+ {
+ mAvatarNameCacheConnection.disconnect();
+ }
+
+ mAvatarNameCacheConnection = LLAvatarNameCache::get(id, boost::bind(&LLPostponedNotification::onAvatarNameCache, this, _1, _2));
+ }
+}
+
void LLPostponedNotification::onAvatarNameCache(const LLUUID& agent_id,
const LLAvatarName& av_name)
{
+ mAvatarNameCacheConnection.disconnect();
+
std::string name = av_name.getCompleteName();
// from PE merge - we should figure out if this is the right thing to do
diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h
index 3df2efcac3..6ac4a98806 100644..100755
--- a/indra/llui/llnotifications.h
+++ b/indra/llui/llnotifications.h
@@ -87,17 +87,18 @@
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/type_traits.hpp>
+#include <boost/signals2.hpp>
-// we want to minimize external dependencies, but this one is important
-#include "llsd.h"
-
-// and we need this to manage the notification callbacks
#include "llevents.h"
#include "llfunctorregistry.h"
-#include "llpointer.h"
#include "llinitparam.h"
-#include "llnotificationslistener.h"
+#include "llmortician.h"
#include "llnotificationptr.h"
+#include "llpointer.h"
+#include "llrefcount.h"
+#include "llsdparam.h"
+
+#include "llnotificationslistener.h"
class LLAvatarName;
typedef enum e_notification_priority
@@ -139,6 +140,7 @@ typedef LLFunctorRegistration<LLNotificationResponder> LLNotificationFunctorRegi
class LLNotificationContext : public LLInstanceTracker<LLNotificationContext, LLUUID>
{
public:
+
LLNotificationContext() : LLInstanceTracker<LLNotificationContext, LLUUID>(LLUUID::generateNewID())
{
}
@@ -164,6 +166,7 @@ public:
struct FormElementBase : public LLInitParam::Block<FormElementBase>
{
Optional<std::string> name;
+ Optional<bool> enabled;
FormElementBase();
};
@@ -233,16 +236,21 @@ public:
} EIgnoreType;
LLNotificationForm();
+ LLNotificationForm(const LLNotificationForm&);
LLNotificationForm(const LLSD& sd);
LLNotificationForm(const std::string& name, const Params& p);
+ void fromLLSD(const LLSD& sd);
LLSD asLLSD() const;
S32 getNumElements() { return mFormData.size(); }
LLSD getElement(S32 index) { return mFormData.get(index); }
LLSD getElement(const std::string& element_name);
- bool hasElement(const std::string& element_name);
- void addElement(const std::string& type, const std::string& name, const LLSD& value = LLSD());
+ void getElements(LLSD& elements, S32 offset = 0);
+ bool hasElement(const std::string& element_name) const;
+ bool getElementEnabled(const std::string& element_name) const;
+ void setElementEnabled(const std::string& element_name, bool enabled);
+ void addElement(const std::string& type, const std::string& name, const LLSD& value = LLSD(), bool enabled = true);
void formatElements(const LLSD& substitutions);
// appends form elements from another form serialized as LLSD
void append(const LLSD& sub_form);
@@ -296,42 +304,52 @@ LOG_CLASS(LLNotification);
friend class LLNotifications;
public:
+
// parameter object used to instantiate a new notification
struct Params : public LLInitParam::Block<Params>
{
friend class LLNotification;
Mandatory<std::string> name;
-
- // optional
- Optional<LLSD> substitutions;
- Optional<LLSD> payload;
+ Optional<LLUUID> id;
+ Optional<LLSD> substitutions,
+ form_elements,
+ payload;
Optional<ENotificationPriority, NotificationPriorityValues> priority;
- Optional<LLSD> form_elements;
- Optional<LLDate> time_stamp;
+ Optional<LLDate> time_stamp,
+ expiry;
Optional<LLNotificationContext*> context;
Optional<void*> responder;
+ Optional<bool> offer_from_agent;
+ Optional<bool> is_dnd;
struct Functor : public LLInitParam::ChoiceBlock<Functor>
{
Alternative<std::string> name;
Alternative<LLNotificationFunctorRegistry::ResponseFunctor> function;
Alternative<LLNotificationResponderPtr> responder;
+ Alternative<LLSD> responder_sd;
Functor()
- : name("functor_name"),
+ : name("responseFunctor"),
function("functor"),
- responder("responder")
+ responder("responder"),
+ responder_sd("responder_sd")
{}
};
Optional<Functor> functor;
Params()
: name("name"),
+ id("id"),
priority("priority", NOTIFICATION_PRIORITY_UNSPECIFIED),
- time_stamp("time_stamp"),
+ time_stamp("time"),
payload("payload"),
- form_elements("form_elements")
+ form_elements("form"),
+ substitutions("substitutions"),
+ expiry("expiry"),
+ offer_from_agent("offer_from_agent", false),
+ is_dnd("is_dnd", false)
{
time_stamp = LLDate::now();
responder = NULL;
@@ -340,9 +358,13 @@ public:
Params(const std::string& _name)
: name("name"),
priority("priority", NOTIFICATION_PRIORITY_UNSPECIFIED),
- time_stamp("time_stamp"),
+ time_stamp("time"),
payload("payload"),
- form_elements("form_elements")
+ form_elements("form"),
+ substitutions("substitutions"),
+ expiry("expiry"),
+ offer_from_agent("offer_from_agent", false),
+ is_dnd("is_dnd", false)
{
functor.name = _name;
name = _name;
@@ -355,7 +377,7 @@ public:
private:
- LLUUID mId;
+ const LLUUID mId;
LLSD mPayload;
LLSD mSubstitutions;
LLDate mTimestamp;
@@ -367,8 +389,9 @@ private:
ENotificationPriority mPriority;
LLNotificationFormPtr mForm;
void* mResponderObj; // TODO - refactor/remove this field
- bool mIsReusable;
LLNotificationResponderPtr mResponder;
+ bool mOfferFromAgent;
+ bool mIsDND;
// a reference to the template
LLNotificationTemplatePtr mTemplatep;
@@ -392,18 +415,10 @@ private:
void init(const std::string& template_name, const LLSD& form_elements);
- LLNotification(const Params& p);
-
- // this is just for making it easy to look things up in a set organized by UUID -- DON'T USE IT
- // for anything real!
- LLNotification(LLUUID uuid) : mId(uuid), mCancelled(false), mRespondedTo(false), mIgnored(false), mPriority(NOTIFICATION_PRIORITY_UNSPECIFIED), mTemporaryResponder(false) {}
-
void cancel();
public:
-
- // constructor from a saved notification
- LLNotification(const LLSD& sd);
+ LLNotification(const LLSDParamAdapter<Params>& p);
void setResponseFunctor(std::string const &responseFunctorName);
@@ -446,7 +461,12 @@ public:
// ["time"] = time at which notification was generated;
// ["expiry"] = time at which notification expires;
// ["responseFunctor"] = name of registered functor that handles responses to notification;
- LLSD asLLSD();
+ LLSD asLLSD(bool excludeTemplateElements = false);
+
+ const LLNotificationFormPtr getForm();
+ void updateForm(const LLNotificationFormPtr& form);
+
+ void repost();
void respond(const LLSD& sd);
void respondWithDefault();
@@ -507,14 +527,43 @@ public:
return mTimestamp;
}
+ bool getOfferFromAgent() const
+ {
+ return mOfferFromAgent;
+ }
+
+ bool isDND() const
+ {
+ return mIsDND;
+ }
+
+ void setDND(const bool flag)
+ {
+ mIsDND = flag;
+ }
+
std::string getType() const;
std::string getMessage() const;
+ std::string getFooter() const;
std::string getLabel() const;
std::string getURL() const;
S32 getURLOption() const;
S32 getURLOpenExternally() const;
+ bool canLogToChat() const;
+ bool canLogToIM() const;
+ bool canShowToast() const;
+ bool hasFormElements() const;
+ void playSound();
+
+ typedef enum e_combine_behavior
+ {
+ REPLACE_WITH_NEW,
+ KEEP_OLD,
+ CANCEL_OLD
+
+ } ECombineBehavior;
- const LLNotificationFormPtr getForm();
+ ECombineBehavior getCombineBehavior() const;
const LLDate getExpiration() const
{
@@ -531,10 +580,6 @@ public:
return mId;
}
- bool isReusable() { return mIsReusable; }
-
- void setReusable(bool reusable) { mIsReusable = reusable; }
-
// comparing two notifications normally means comparing them by UUID (so we can look them
// up quickly this way)
bool operator<(const LLNotification& rhs) const
@@ -646,44 +691,17 @@ namespace LLNotificationFilters
namespace LLNotificationComparators
{
- typedef enum e_direction { ORDER_DECREASING, ORDER_INCREASING } EDirection;
-
- // generic order functor that takes method or member variable reference
- template<typename T>
- struct orderBy
+ struct orderByUUID
{
- typedef boost::function<T (LLNotificationPtr)> field_t;
- orderBy(field_t field, EDirection direction = ORDER_INCREASING) : mField(field), mDirection(direction) {}
bool operator()(LLNotificationPtr lhs, LLNotificationPtr rhs)
{
- if (mDirection == ORDER_DECREASING)
- {
- return mField(lhs) > mField(rhs);
- }
- else
- {
- return mField(lhs) < mField(rhs);
- }
+ return lhs->id() < rhs->id();
}
-
- field_t mField;
- EDirection mDirection;
- };
-
- struct orderByUUID : public orderBy<const LLUUID&>
- {
- orderByUUID(EDirection direction = ORDER_INCREASING) : orderBy<const LLUUID&>(&LLNotification::id, direction) {}
- };
-
- struct orderByDate : public orderBy<const LLDate&>
- {
- orderByDate(EDirection direction = ORDER_INCREASING) : orderBy<const LLDate&>(&LLNotification::getDate, direction) {}
};
};
typedef boost::function<bool (LLNotificationPtr)> LLNotificationFilter;
-typedef boost::function<bool (LLNotificationPtr, LLNotificationPtr)> LLNotificationComparator;
-typedef std::set<LLNotificationPtr, LLNotificationComparator> LLNotificationSet;
+typedef std::set<LLNotificationPtr, LLNotificationComparators::orderByUUID> LLNotificationSet;
typedef std::multimap<std::string, LLNotificationPtr> LLNotificationMap;
// ========================================================
@@ -704,12 +722,14 @@ typedef std::multimap<std::string, LLNotificationPtr> LLNotificationMap;
// all of the built-in tests should attach to the "Visible" channel
//
class LLNotificationChannelBase :
- public LLEventTrackable
+ public LLEventTrackable,
+ public LLRefCount
{
LOG_CLASS(LLNotificationChannelBase);
public:
- LLNotificationChannelBase(LLNotificationFilter filter, LLNotificationComparator comp) :
- mFilter(filter), mItems(comp)
+ LLNotificationChannelBase(LLNotificationFilter filter)
+ : mFilter(filter),
+ mItems()
{}
virtual ~LLNotificationChannelBase() {}
// you can also connect to a Channel, so you can be notified of
@@ -775,6 +795,9 @@ protected:
virtual void onDelete(LLNotificationPtr p) {}
virtual void onChange(LLNotificationPtr p) {}
+ virtual void onFilterPass(LLNotificationPtr p) {}
+ virtual void onFilterFail(LLNotificationPtr p) {}
+
bool updateItem(const LLSD& payload, LLNotificationPtr pNotification);
LLNotificationFilter mFilter;
};
@@ -784,63 +807,53 @@ protected:
// destroy it, but if it becomes necessary to do so, the shared_ptr model
// will ensure that we don't leak resources.
class LLNotificationChannel;
-typedef boost::shared_ptr<LLNotificationChannel> LLNotificationChannelPtr;
+typedef boost::intrusive_ptr<LLNotificationChannel> LLNotificationChannelPtr;
// manages a list of notifications
// Note that if this is ever copied around, we might find ourselves with multiple copies
// of a queue with notifications being added to different nonequivalent copies. So we
-// make it inherit from boost::noncopyable, and then create a map of shared_ptr to manage it.
-//
-// NOTE: LLNotificationChannel is self-registering. The *correct* way to create one is to
-// do something like:
-// LLNotificationChannel::buildChannel("name", "parent"...);
-// This returns an LLNotificationChannelPtr, which you can store, or
-// you can then retrieve the channel by using the registry:
-// LLNotifications::instance().getChannel("name")...
+// make it inherit from boost::noncopyable, and then create a map of LLPointer to manage it.
//
class LLNotificationChannel :
boost::noncopyable,
- public LLNotificationChannelBase
+ public LLNotificationChannelBase,
+ public LLInstanceTracker<LLNotificationChannel, std::string>
{
LOG_CLASS(LLNotificationChannel);
public:
+ // Notification Channels have a filter, which determines which notifications
+ // will be added to this channel.
+ // Channel filters cannot change.
+ struct Params : public LLInitParam::Block<Params>
+ {
+ Mandatory<std::string> name;
+ Optional<LLNotificationFilter> filter;
+ Multiple<std::string> sources;
+ };
+
+ LLNotificationChannel(const Params& p = Params());
+ LLNotificationChannel(const std::string& name, const std::string& parent, LLNotificationFilter filter);
+
virtual ~LLNotificationChannel() {}
typedef LLNotificationSet::iterator Iterator;
std::string getName() const { return mName; }
- std::string getParentChannelName() { return mParent; }
+
+ void connectToChannel(const std::string& channel_name);
bool isEmpty() const;
+ S32 size() const;
Iterator begin();
Iterator end();
+ size_t size();
- // Channels have a comparator to control sort order;
- // the default sorts by arrival date
- void setComparator(LLNotificationComparator comparator);
-
std::string summarize();
- // factory method for constructing these channels; since they're self-registering,
- // we want to make sure that you can't use new to make them
- static LLNotificationChannelPtr buildChannel(const std::string& name, const std::string& parent,
- LLNotificationFilter filter=LLNotificationFilters::includeEverything,
- LLNotificationComparator comparator=LLNotificationComparators::orderByUUID());
-
-protected:
- // Notification Channels have a filter, which determines which notifications
- // will be added to this channel.
- // Channel filters cannot change.
- // Channels have a protected constructor so you can't make smart pointers that don't
- // come from our internal reference; call NotificationChannel::build(args)
- LLNotificationChannel(const std::string& name, const std::string& parent,
- LLNotificationFilter filter, LLNotificationComparator comparator);
-
private:
std::string mName;
std::string mParent;
- LLNotificationComparator mComparator;
};
// An interface class to provide a clean linker seam to the LLNotifications class.
@@ -863,6 +876,13 @@ class LLNotifications :
friend class LLSingleton<LLNotifications>;
public:
+
+ // Needed to clear up RefCounted things prior to actual destruction
+ // as the singleton nature of the class makes them do "bad things"
+ // on at least Mac, if not all 3 platforms
+ //
+ void clear();
+
// load all notification descriptions from file
// calling more than once will overwrite existing templates
// but never delete a template
@@ -923,10 +943,6 @@ public:
void createDefaultChannels();
- typedef std::map<std::string, LLNotificationChannelPtr> ChannelMap;
- ChannelMap mChannels;
-
- void addChannel(LLNotificationChannelPtr pChan);
LLNotificationChannelPtr getChannel(const std::string& channelName);
std::string getGlobalString(const std::string& key) const;
@@ -964,7 +980,9 @@ private:
bool mIgnoreAllNotifications;
- boost::scoped_ptr<LLNotificationsListener> mListener;
+ boost::scoped_ptr<LLNotificationsListener> mListener;
+
+ std::vector<LLNotificationChannelPtr> mDefaultChannels;
};
/**
@@ -977,7 +995,7 @@ private:
* 1 create class derived from LLPostponedNotification;
* 2 call LLPostponedNotification::add method;
*/
-class LLPostponedNotification
+class LLPostponedNotification : public LLMortician
{
public:
/**
@@ -995,26 +1013,38 @@ public:
thiz->mParams = params;
// Avoid header file dependency on llcachename.h
- lookupName(thiz, id, is_group);
+ thiz->lookupName(id, is_group);
}
private:
- static void lookupName(LLPostponedNotification* thiz, const LLUUID& id, bool is_group);
+ void lookupName(const LLUUID& id, bool is_group);
// only used for groups
void onGroupNameCache(const LLUUID& id, const std::string& full_name, bool is_group);
// only used for avatars
+ void fetchAvatarName(const LLUUID& id);
void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name);
// used for both group and avatar names
void finalizeName(const std::string& name);
void cleanup()
{
- delete this;
+ die();
}
protected:
- LLPostponedNotification() {}
- virtual ~LLPostponedNotification() {}
+ LLPostponedNotification()
+ : mParams(),
+ mName(),
+ mAvatarNameCacheConnection()
+ {}
+
+ virtual ~LLPostponedNotification()
+ {
+ if (mAvatarNameCacheConnection.connected())
+ {
+ mAvatarNameCacheConnection.disconnect();
+ }
+ }
/**
* Abstract method provides possibility to modify notification parameters and
@@ -1025,6 +1055,58 @@ protected:
LLNotification::Params mParams;
std::string mName;
+ boost::signals2::connection mAvatarNameCacheConnection;
+};
+
+// Stores only persistent notifications.
+// Class users can use connectChanged() to process persistent notifications
+// (see LLPersistentNotificationStorage for example).
+class LLPersistentNotificationChannel : public LLNotificationChannel
+{
+ LOG_CLASS(LLPersistentNotificationChannel);
+public:
+ LLPersistentNotificationChannel()
+ : LLNotificationChannel("Persistent", "Visible", &notificationFilter)
+ {
+ }
+
+ typedef std::vector<LLNotificationPtr> history_list_t;
+ history_list_t::iterator beginHistory() { sortHistory(); return mHistory.begin(); }
+ history_list_t::iterator endHistory() { return mHistory.end(); }
+
+private:
+
+ struct sortByTime
+ {
+ S32 operator ()(const LLNotificationPtr& a, const LLNotificationPtr& b)
+ {
+ return a->getDate() < b->getDate();
+ }
+ };
+
+ void sortHistory()
+ {
+ std::sort(mHistory.begin(), mHistory.end(), sortByTime());
+ }
+
+
+ // The channel gets all persistent notifications except those that have been canceled
+ static bool notificationFilter(LLNotificationPtr pNotification)
+ {
+ bool handle_notification = false;
+
+ handle_notification = pNotification->isPersistent()
+ && !pNotification->isCancelled();
+
+ return handle_notification;
+ }
+
+ void onAdd(LLNotificationPtr p)
+ {
+ mHistory.push_back(p);
+ }
+
+ std::vector<LLNotificationPtr> mHistory;
};
#endif//LL_LLNOTIFICATIONS_H
diff --git a/indra/llui/llnotificationslistener.cpp b/indra/llui/llnotificationslistener.cpp
index 3bbeb3a778..9e8e943ee6 100644
--- a/indra/llui/llnotificationslistener.cpp
+++ b/indra/llui/llnotificationslistener.cpp
@@ -42,10 +42,11 @@ LLNotificationsListener::LLNotificationsListener(LLNotifications & notifications
"Add a notification with specified [\"name\"], [\"substitutions\"] and [\"payload\"].\n"
"If optional [\"reply\"] specified, arrange to send user response on that LLEventPump.",
&LLNotificationsListener::requestAdd);
- add("listChannels",
+ /* add("listChannels",
"Post to [\"reply\"] a map of info on existing channels",
&LLNotificationsListener::listChannels,
LLSD().with("reply", LLSD()));
+ */
add("listChannelNotifications",
"Post to [\"reply\"] an array of info on notifications in channel [\"channel\"]",
&LLNotificationsListener::listChannelNotifications,
@@ -116,11 +117,15 @@ void LLNotificationsListener::NotificationResponder(const std::string& reply_pum
reponse_event["response"] = response;
LLEventPumps::getInstance()->obtain(reply_pump).post(reponse_event);
}
-
+/*
void LLNotificationsListener::listChannels(const LLSD& params) const
{
LLReqID reqID(params);
LLSD response(reqID.makeResponse());
+ for (LLNotifications::
+
+
+
for (LLNotifications::ChannelMap::const_iterator cmi(mNotifications.mChannels.begin()),
cmend(mNotifications.mChannels.end());
cmi != cmend; ++cmi)
@@ -131,7 +136,7 @@ void LLNotificationsListener::listChannels(const LLSD& params) const
}
LLEventPumps::instance().obtain(params["reply"]).post(response);
}
-
+*/
void LLNotificationsListener::listChannelNotifications(const LLSD& params) const
{
LLReqID reqID(params);
diff --git a/indra/llui/llnotificationsutil.cpp b/indra/llui/llnotificationsutil.cpp
index cc791c26d1..cc791c26d1 100644..100755
--- a/indra/llui/llnotificationsutil.cpp
+++ b/indra/llui/llnotificationsutil.cpp
diff --git a/indra/llui/llnotificationsutil.h b/indra/llui/llnotificationsutil.h
index 4093324d0c..4093324d0c 100644..100755
--- a/indra/llui/llnotificationsutil.h
+++ b/indra/llui/llnotificationsutil.h
diff --git a/indra/llui/llnotificationtemplate.h b/indra/llui/llnotificationtemplate.h
index fb50c9c123..18a82190b5 100644..100755
--- a/indra/llui/llnotificationtemplate.h
+++ b/indra/llui/llnotificationtemplate.h
@@ -49,7 +49,6 @@
//#include "llfunctorregistry.h"
//#include "llpointer.h"
#include "llinitparam.h"
-//#include "llnotificationslistener.h"
//#include "llnotificationptr.h"
//#include "llcachename.h"
#include "llnotifications.h"
@@ -61,6 +60,18 @@ typedef boost::shared_ptr<LLNotificationForm> LLNotificationFormPtr;
// from the appropriate local language directory).
struct LLNotificationTemplate
{
+ struct CombineBehaviorNames
+ : public LLInitParam::TypeValuesHelper<LLNotification::ECombineBehavior, CombineBehaviorNames>
+ {
+ static void declareValues()
+ {
+ declare("replace_with_new", LLNotification::REPLACE_WITH_NEW);
+ declare("keep_old", LLNotification::KEEP_OLD);
+ declare("cancel_old", LLNotification::CANCEL_OLD);
+ }
+ };
+
+
struct GlobalString : public LLInitParam::Block<GlobalString>
{
Mandatory<std::string> name,
@@ -94,9 +105,11 @@ struct LLNotificationTemplate
Optional<LLInitParam::Flag> dummy_val;
public:
Multiple<UniquenessContext> contexts;
+ Optional<LLNotification::ECombineBehavior, CombineBehaviorNames> combine;
UniquenessConstraint()
: contexts("context"),
+ combine("combine", LLNotification::REPLACE_WITH_NEW),
dummy_val("")
{}
};
@@ -121,6 +134,7 @@ struct LLNotificationTemplate
Optional<std::string> yes_text,
no_text,
cancel_text,
+ help_text,
ignore_text;
TemplateRef()
@@ -128,6 +142,7 @@ struct LLNotificationTemplate
yes_text("yestext"),
no_text("notext"),
cancel_text("canceltext"),
+ help_text("helptext"),
ignore_text("ignoretext")
{}
};
@@ -167,10 +182,24 @@ struct LLNotificationTemplate
{}
};
+ struct Footer : public LLInitParam::Block<Footer>
+ {
+ Mandatory<std::string> value;
+
+ Footer()
+ : value("value")
+ {
+ addSynonym(value, "");
+ }
+ };
+
struct Params : public LLInitParam::Block<Params>
{
Mandatory<std::string> name;
- Optional<bool> persist;
+ Optional<bool> persist,
+ log_to_im,
+ show_toast,
+ log_to_chat;
Optional<std::string> functor,
icon,
label,
@@ -184,12 +213,16 @@ struct LLNotificationTemplate
Optional<FormRef> form_ref;
Optional<ENotificationPriority,
NotificationPriorityValues> priority;
- Multiple<Tag> tags;
+ Multiple<Tag> tags;
+ Optional<Footer> footer;
Params()
: name("name"),
persist("persist", false),
+ log_to_im("log_to_im", false),
+ show_toast("show_toast", true),
+ log_to_chat("log_to_chat", true),
functor("functor"),
icon("icon"),
label("label"),
@@ -202,7 +235,8 @@ struct LLNotificationTemplate
url("url"),
unique("unique"),
form_ref(""),
- tags("tag")
+ tags("tag"),
+ footer("footer")
{}
};
@@ -231,6 +265,8 @@ struct LLNotificationTemplate
// The text used to display the notification. Replaceable parameters
// are enclosed in square brackets like this [].
std::string mMessage;
+ // The text used to display the notification, but under the form.
+ std::string mFooter;
// The label for the notification; used for
// certain classes of notification (those with a window and a window title).
// Also used when a notification pops up underneath the current one.
@@ -245,6 +281,7 @@ struct LLNotificationTemplate
// (used for things like progress indications, or repeating warnings
// like "the grid is going down in N minutes")
bool mUnique;
+ LLNotification::ECombineBehavior mCombineBehavior;
// if we want to be unique only if a certain part of the payload or substitutions args
// are constant specify the field names for the payload. The notification will only be
// combined if all of the fields named in the context are identical in the
@@ -285,12 +322,15 @@ struct LLNotificationTemplate
LLNotificationFormPtr mForm;
// default priority for notifications of this type
ENotificationPriority mPriority;
- // UUID of the audio file to be played when this notification arrives
- // this is loaded as a name, but looked up to get the UUID upon template load.
- // If null, it wasn't specified.
- LLUUID mSoundEffect;
+ // Stores the sound name which can then be used to play the sound using make_ui_sound
+ std::string mSoundName;
// List of tags that rules can match against.
std::list<std::string> mTags;
+
+ // inject these notifications into chat/IM streams
+ bool mLogToChat;
+ bool mLogToIM;
+ bool mShowToast;
};
#endif //LL_LLNOTIFICATION_TEMPLATE_H
diff --git a/indra/llui/llnotificationvisibilityrule.h b/indra/llui/llnotificationvisibilityrule.h
index 78788a275c..78788a275c 100644..100755
--- a/indra/llui/llnotificationvisibilityrule.h
+++ b/indra/llui/llnotificationvisibilityrule.h
diff --git a/indra/llui/llpanel.cpp b/indra/llui/llpanel.cpp
index 00318cec6b..67472ad166 100644..100755
--- a/indra/llui/llpanel.cpp
+++ b/indra/llui/llpanel.cpp
@@ -968,25 +968,15 @@ static LLFastTimer::DeclareTimer FTM_BUILD_PANELS("Build Panels");
//-----------------------------------------------------------------------------
// buildPanel()
//-----------------------------------------------------------------------------
-BOOL LLPanel::buildFromFile(const std::string& filename, LLXMLNodePtr output_node, const LLPanel::Params& default_params)
+BOOL LLPanel::buildFromFile(const std::string& filename, const LLPanel::Params& default_params)
{
LLFastTimer timer(FTM_BUILD_PANELS);
BOOL didPost = FALSE;
LLXMLNodePtr root;
- //if exporting, only load the language being exported,
- //instead of layering localized version on top of english
- if (output_node)
- {
- if (!LLUICtrlFactory::getLocalizedXMLNode(filename, root))
- {
- llwarns << "Couldn't parse panel from: " << LLUI::getLocalizedSkinPath() + gDirUtilp->getDirDelimiter() + filename << llendl;
- return didPost;
- }
- }
- else if (!LLUICtrlFactory::getLayeredXMLNode(filename, root))
+ if (!LLUICtrlFactory::getLayeredXMLNode(filename, root))
{
- llwarns << "Couldn't parse panel from: " << LLUI::getSkinPath() + gDirUtilp->getDirDelimiter() + filename << llendl;
+ llwarns << "Couldn't parse panel from: " << filename << llendl;
return didPost;
}
@@ -1010,7 +1000,7 @@ BOOL LLPanel::buildFromFile(const std::string& filename, LLXMLNodePtr output_nod
getCommitCallbackRegistrar().pushScope();
getEnableCallbackRegistrar().pushScope();
- didPost = initPanelXML(root, NULL, output_node, default_params);
+ didPost = initPanelXML(root, NULL, NULL, default_params);
getCommitCallbackRegistrar().popScope();
getEnableCallbackRegistrar().popScope();
diff --git a/indra/llui/llpanel.h b/indra/llui/llpanel.h
index f620201020..e63b41f97c 100644..100755
--- a/indra/llui/llpanel.h
+++ b/indra/llui/llpanel.h
@@ -105,7 +105,7 @@ protected:
LLPanel(const LLPanel::Params& params = getDefaultParams());
public:
- BOOL buildFromFile(const std::string &filename, LLXMLNodePtr output_node = NULL, const LLPanel::Params&default_params = getDefaultParams());
+ BOOL buildFromFile(const std::string &filename, const LLPanel::Params& default_params = getDefaultParams());
static LLPanel* createFactoryPanel(const std::string& name);
diff --git a/indra/llui/llprogressbar.cpp b/indra/llui/llprogressbar.cpp
index 84a890edfa..84a890edfa 100644..100755
--- a/indra/llui/llprogressbar.cpp
+++ b/indra/llui/llprogressbar.cpp
diff --git a/indra/llui/llprogressbar.h b/indra/llui/llprogressbar.h
index a8ec83ea00..a8ec83ea00 100644..100755
--- a/indra/llui/llprogressbar.h
+++ b/indra/llui/llprogressbar.h
diff --git a/indra/llui/llradiogroup.cpp b/indra/llui/llradiogroup.cpp
index 95a7d09382..95a7d09382 100644..100755
--- a/indra/llui/llradiogroup.cpp
+++ b/indra/llui/llradiogroup.cpp
diff --git a/indra/llui/llradiogroup.h b/indra/llui/llradiogroup.h
index 8bd5698538..8bd5698538 100644..100755
--- a/indra/llui/llradiogroup.h
+++ b/indra/llui/llradiogroup.h
diff --git a/indra/llui/llresizebar.cpp b/indra/llui/llresizebar.cpp
index 87aeb4d7a7..e67b22c977 100644..100755
--- a/indra/llui/llresizebar.cpp
+++ b/indra/llui/llresizebar.cpp
@@ -28,14 +28,53 @@
#include "llresizebar.h"
+#include "lllocalcliprect.h"
#include "llmath.h"
#include "llui.h"
#include "llmenugl.h"
#include "llfocusmgr.h"
#include "llwindow.h"
+class LLImagePanel : public LLPanel
+{
+public:
+ struct Params : public LLInitParam::Block<Params, LLPanel::Params>
+ {
+ Optional<bool> horizontal;
+ Params() : horizontal("horizontal", false) {}
+ };
+ LLImagePanel(const Params& p) : LLPanel(p), mHorizontal(p.horizontal) {}
+ virtual ~LLImagePanel() {}
+
+ void draw()
+ {
+ const LLRect& parent_rect = getParent()->getRect();
+ const LLRect& rect = getRect();
+ LLRect clip_rect( -rect.mLeft, parent_rect.getHeight() - rect.mBottom - 2
+ , parent_rect.getWidth() - rect.mLeft - (mHorizontal ? 2 : 0), -rect.mBottom);
+ LLLocalClipRect clip(clip_rect);
+ LLPanel::draw();
+ }
+
+private:
+ bool mHorizontal;
+};
+
+static LLDefaultChildRegistry::Register<LLImagePanel> t1("resize_bar_image_panel");
+
+LLResizeBar::Params::Params()
+: max_size("max_size", S32_MAX),
+ snapping_enabled("snapping_enabled", true),
+ resizing_view("resizing_view"),
+ side("side"),
+ allow_double_click_snapping("allow_double_click_snapping", true),
+ show_drag_handle("show_drag_handle", false)
+{
+ name = "resize_bar";
+}
+
LLResizeBar::LLResizeBar(const LLResizeBar::Params& p)
-: LLView(p),
+: LLPanel(p),
mDragLastScreenX( 0 ),
mDragLastScreenY( 0 ),
mLastMouseScreenX( 0 ),
@@ -45,7 +84,10 @@ LLResizeBar::LLResizeBar(const LLResizeBar::Params& p)
mSide( p.side ),
mSnappingEnabled(p.snapping_enabled),
mAllowDoubleClickSnapping(p.allow_double_click_snapping),
- mResizingView(p.resizing_view)
+ mResizingView(p.resizing_view),
+ mResizeListener(NULL),
+ mShowDragHandle(p.show_drag_handle),
+ mImagePanel(NULL)
{
setFollowsNone();
// set up some generically good follow code.
@@ -74,8 +116,37 @@ LLResizeBar::LLResizeBar(const LLResizeBar::Params& p)
default:
break;
}
+
+ if (mShowDragHandle)
+ {
+ LLViewBorder::Params border_params;
+ border_params.border_thickness = 1;
+ border_params.highlight_light_color = LLUIColorTable::instance().getColor("ResizebarBorderLight");
+ border_params.shadow_dark_color = LLUIColorTable::instance().getColor("ResizebarBorderDark");
+
+ addBorder(border_params);
+ setBorderVisible(TRUE);
+
+ LLImagePanel::Params image_panel;
+ mDragHandleImage = LLUI::getUIImage(LLResizeBar::RIGHT == mSide ? "Vertical Drag Handle" : "Horizontal Drag Handle");
+ image_panel.bg_alpha_image = mDragHandleImage;
+ image_panel.background_visible = true;
+ image_panel.horizontal = (LLResizeBar::BOTTOM == mSide);
+ mImagePanel = LLUICtrlFactory::create<LLImagePanel>(image_panel);
+ setImagePanel(mImagePanel);
+ }
}
+BOOL LLResizeBar::postBuild()
+{
+ if (mShowDragHandle)
+ {
+ setBackgroundVisible(TRUE);
+ setTransparentColor(LLUIColorTable::instance().getColor("ResizebarBody"));
+ }
+
+ return LLPanel::postBuild();
+}
BOOL LLResizeBar::handleMouseDown(S32 x, S32 y, MASK mask)
{
@@ -139,13 +210,6 @@ BOOL LLResizeBar::handleHover(S32 x, S32 y, MASK mask)
if( valid_rect.localPointInRect( screen_x, screen_y ) && mResizingView )
{
- // undock floater when user resize it
- LLFloater* parent = dynamic_cast<LLFloater*>( getParent());
- if (parent && parent->isDocked())
- {
- parent->setDocked( false, false);
- }
-
// Resize the parent
LLRect orig_rect = mResizingView->getRect();
LLRect scaled_rect = orig_rect;
@@ -219,20 +283,66 @@ BOOL LLResizeBar::handleHover(S32 x, S32 y, MASK mask)
// update last valid mouse cursor position based on resized view's actual size
LLRect new_rect = mResizingView->getRect();
+
switch(mSide)
{
case LEFT:
- mDragLastScreenX += new_rect.mLeft - orig_rect.mLeft;
+ {
+ S32 actual_delta_x = new_rect.mLeft - orig_rect.mLeft;
+ if (actual_delta_x != delta_x)
+ {
+ // restore everything by left
+ new_rect.mBottom = orig_rect.mBottom;
+ new_rect.mTop = orig_rect.mTop;
+ new_rect.mRight = orig_rect.mRight;
+ mResizingView->setShape(new_rect, true);
+ }
+ mDragLastScreenX += actual_delta_x;
+
break;
+ }
case RIGHT:
+ {
+ S32 actual_delta_x = new_rect.mRight - orig_rect.mRight;
+ if (actual_delta_x != delta_x)
+ {
+ // restore everything by left
+ new_rect.mBottom = orig_rect.mBottom;
+ new_rect.mTop = orig_rect.mTop;
+ new_rect.mLeft = orig_rect.mLeft;
+ mResizingView->setShape(new_rect, true);
+ }
mDragLastScreenX += new_rect.mRight - orig_rect.mRight;
break;
+ }
case TOP:
+ {
+ S32 actual_delta_y = new_rect.mTop - orig_rect.mTop;
+ if (actual_delta_y != delta_y)
+ {
+ // restore everything by left
+ new_rect.mBottom = orig_rect.mBottom;
+ new_rect.mLeft = orig_rect.mLeft;
+ new_rect.mRight = orig_rect.mRight;
+ mResizingView->setShape(new_rect, true);
+ }
mDragLastScreenY += new_rect.mTop - orig_rect.mTop;
break;
+ }
case BOTTOM:
+ {
+ S32 actual_delta_y = new_rect.mBottom - orig_rect.mBottom;
+ if (actual_delta_y != delta_y)
+ {
+ // restore everything by left
+ new_rect.mTop = orig_rect.mTop;
+ new_rect.mLeft = orig_rect.mLeft;
+ new_rect.mRight = orig_rect.mRight;
+ mResizingView->setShape(new_rect, true);
+ }
mDragLastScreenY += new_rect.mBottom- orig_rect.mBottom;
break;
+ }
default:
break;
}
@@ -261,6 +371,11 @@ BOOL LLResizeBar::handleHover(S32 x, S32 y, MASK mask)
}
}
+ if (mResizeListener)
+ {
+ mResizeListener(NULL);
+ }
+
return handled;
} // end LLResizeBar::handleHover
@@ -297,3 +412,39 @@ BOOL LLResizeBar::handleDoubleClick(S32 x, S32 y, MASK mask)
return TRUE;
}
+void LLResizeBar::setImagePanel(LLPanel * panelp)
+{
+ const LLView::child_list_t * children = getChildList();
+ if (getChildCount() == 2)
+ {
+ LLPanel * image_panelp = dynamic_cast<LLPanel*>(children->back());
+ if (image_panelp)
+ {
+ removeChild(image_panelp);
+ delete image_panelp;
+ }
+ }
+
+ addChild(panelp);
+ sendChildToBack(panelp);
+}
+
+LLPanel * LLResizeBar::getImagePanel() const
+{
+ return getChildCount() > 0 ? (LLPanel *)getChildList()->back() : NULL;
+}
+
+void LLResizeBar::draw()
+{
+ if (mShowDragHandle)
+ {
+ S32 image_width = mDragHandleImage->getTextureWidth();
+ S32 image_height = mDragHandleImage->getTextureHeight();
+ const LLRect& panel_rect = getRect();
+ S32 image_left = (panel_rect.getWidth() - image_width) / 2 - 1;
+ S32 image_bottom = (panel_rect.getHeight() - image_height) / 2;
+ mImagePanel->setRect(LLRect(image_left, image_bottom + image_height, image_left + image_width, image_bottom));
+ }
+
+ LLPanel::draw();
+}
diff --git a/indra/llui/llresizebar.h b/indra/llui/llresizebar.h
index 6daf191918..bcf8ea0b40 100644..100755
--- a/indra/llui/llresizebar.h
+++ b/indra/llui/llresizebar.h
@@ -27,15 +27,14 @@
#ifndef LL_RESIZEBAR_H
#define LL_RESIZEBAR_H
-#include "llview.h"
-#include "llcoord.h"
+#include "llpanel.h"
-class LLResizeBar : public LLView
+class LLResizeBar : public LLPanel
{
public:
enum Side { LEFT, TOP, RIGHT, BOTTOM };
- struct Params : public LLInitParam::Block<Params, LLView::Params>
+ struct Params : public LLInitParam::Block<Params, LLPanel::Params>
{
Mandatory<LLView*> resizing_view;
Mandatory<Side> side;
@@ -44,24 +43,19 @@ public:
Optional<S32> max_size;
Optional<bool> snapping_enabled;
Optional<bool> allow_double_click_snapping;
+ Optional<bool> show_drag_handle;
- Params()
- : max_size("max_size", S32_MAX),
- snapping_enabled("snapping_enabled", true),
- resizing_view("resizing_view"),
- side("side"),
- allow_double_click_snapping("allow_double_click_snapping", true)
- {
- name = "resize_bar";
- }
+ Params();
};
protected:
LLResizeBar(const LLResizeBar::Params& p);
friend class LLUICtrlFactory;
+
+ /*virtual*/ BOOL postBuild();
public:
-// virtual void draw(); No appearance
+ virtual void draw();
virtual BOOL handleHover(S32 x, S32 y, MASK mask);
virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask);
@@ -71,19 +65,27 @@ public:
void setEnableSnapping(BOOL enable) { mSnappingEnabled = enable; }
void setAllowDoubleClickSnapping(BOOL allow) { mAllowDoubleClickSnapping = allow; }
bool canResize() { return getEnabled() && mMaxSize > mMinSize; }
+ void setResizeListener(boost::function<void(void*)> listener) {mResizeListener = listener;}
+ BOOL isShowDragHandle() const { return mShowDragHandle; }
+ void setImagePanel(LLPanel * panelp);
+ LLPanel * getImagePanel() const;
private:
- S32 mDragLastScreenX;
- S32 mDragLastScreenY;
- S32 mLastMouseScreenX;
- S32 mLastMouseScreenY;
- LLCoordGL mLastMouseDir;
- S32 mMinSize;
- S32 mMaxSize;
- const Side mSide;
- BOOL mSnappingEnabled;
- BOOL mAllowDoubleClickSnapping;
- LLView* mResizingView;
+ S32 mDragLastScreenX;
+ S32 mDragLastScreenY;
+ S32 mLastMouseScreenX;
+ S32 mLastMouseScreenY;
+ LLCoordGL mLastMouseDir;
+ S32 mMinSize;
+ S32 mMaxSize;
+ const Side mSide;
+ BOOL mSnappingEnabled;
+ BOOL mAllowDoubleClickSnapping;
+ BOOL mShowDragHandle;
+ LLView* mResizingView;
+ boost::function<void(void*)> mResizeListener;
+ LLPointer<LLUIImage> mDragHandleImage;
+ LLPanel * mImagePanel;
};
#endif // LL_RESIZEBAR_H
diff --git a/indra/llui/llresizehandle.cpp b/indra/llui/llresizehandle.cpp
index c3a51c36c9..24794305ac 100644..100755
--- a/indra/llui/llresizehandle.cpp
+++ b/indra/llui/llresizehandle.cpp
@@ -257,23 +257,65 @@ BOOL LLResizeHandle::handleHover(S32 x, S32 y, MASK mask)
// update last valid mouse cursor position based on resized view's actual size
LLRect new_rect = resizing_view->getRect();
+ S32 actual_delta_x = 0;
+ S32 actual_delta_y = 0;
switch(mCorner)
{
case LEFT_TOP:
- mDragLastScreenX += new_rect.mLeft - orig_rect.mLeft;
- mDragLastScreenY += new_rect.mTop - orig_rect.mTop;
+ actual_delta_x = new_rect.mLeft - orig_rect.mLeft;
+ actual_delta_y = new_rect.mTop - orig_rect.mTop;
+ if (actual_delta_x != delta_x
+ || actual_delta_y != delta_y)
+ {
+ new_rect.mRight = orig_rect.mRight;
+ new_rect.mBottom = orig_rect.mBottom;
+ resizing_view->setShape(new_rect, true);
+ }
+
+ mDragLastScreenX += actual_delta_x;
+ mDragLastScreenY += actual_delta_y;
break;
case LEFT_BOTTOM:
- mDragLastScreenX += new_rect.mLeft - orig_rect.mLeft;
- mDragLastScreenY += new_rect.mBottom- orig_rect.mBottom;
+ actual_delta_x = new_rect.mLeft - orig_rect.mLeft;
+ actual_delta_y = new_rect.mBottom - orig_rect.mBottom;
+ if (actual_delta_x != delta_x
+ || actual_delta_y != delta_y)
+ {
+ new_rect.mRight = orig_rect.mRight;
+ new_rect.mTop = orig_rect.mTop;
+ resizing_view->setShape(new_rect, true);
+ }
+
+ mDragLastScreenX += actual_delta_x;
+ mDragLastScreenY += actual_delta_y;
break;
case RIGHT_TOP:
- mDragLastScreenX += new_rect.mRight - orig_rect.mRight;
- mDragLastScreenY += new_rect.mTop - orig_rect.mTop;
+ actual_delta_x = new_rect.mRight - orig_rect.mRight;
+ actual_delta_y = new_rect.mTop - orig_rect.mTop;
+ if (actual_delta_x != delta_x
+ || actual_delta_y != delta_y)
+ {
+ new_rect.mLeft = orig_rect.mLeft;
+ new_rect.mBottom = orig_rect.mBottom;
+ resizing_view->setShape(new_rect, true);
+ }
+
+ mDragLastScreenX += actual_delta_x;
+ mDragLastScreenY += actual_delta_y;
break;
case RIGHT_BOTTOM:
- mDragLastScreenX += new_rect.mRight - orig_rect.mRight;
- mDragLastScreenY += new_rect.mBottom- orig_rect.mBottom;
+ actual_delta_x = new_rect.mRight - orig_rect.mRight;
+ actual_delta_y = new_rect.mBottom - orig_rect.mBottom;
+ if (actual_delta_x != delta_x
+ || actual_delta_y != delta_y)
+ {
+ new_rect.mLeft = orig_rect.mLeft;
+ new_rect.mTop = orig_rect.mTop;
+ resizing_view->setShape(new_rect, true);
+ }
+
+ mDragLastScreenX += actual_delta_x;
+ mDragLastScreenY += actual_delta_y;
break;
default:
break;
diff --git a/indra/llui/llresizehandle.h b/indra/llui/llresizehandle.h
index 7541b9e6c0..7541b9e6c0 100644..100755
--- a/indra/llui/llresizehandle.h
+++ b/indra/llui/llresizehandle.h
diff --git a/indra/llui/llresmgr.cpp b/indra/llui/llresmgr.cpp
index 820e7cb26a..820e7cb26a 100644..100755
--- a/indra/llui/llresmgr.cpp
+++ b/indra/llui/llresmgr.cpp
diff --git a/indra/llui/llresmgr.h b/indra/llui/llresmgr.h
index a652dcd2c0..a652dcd2c0 100644..100755
--- a/indra/llui/llresmgr.h
+++ b/indra/llui/llresmgr.h
diff --git a/indra/llui/llrngwriter.cpp b/indra/llui/llrngwriter.cpp
index 5e6840d7df..5e6840d7df 100644..100755
--- a/indra/llui/llrngwriter.cpp
+++ b/indra/llui/llrngwriter.cpp
diff --git a/indra/llui/llrngwriter.h b/indra/llui/llrngwriter.h
index c33aa28613..c33aa28613 100644..100755
--- a/indra/llui/llrngwriter.h
+++ b/indra/llui/llrngwriter.h
diff --git a/indra/llui/llscrollbar.cpp b/indra/llui/llscrollbar.cpp
index 5d3bf7a670..13887cbe73 100644..100755
--- a/indra/llui/llscrollbar.cpp
+++ b/indra/llui/llscrollbar.cpp
@@ -642,3 +642,8 @@ void LLScrollbar::onLineDownBtnPressed( const LLSD& data )
{
changeLine( mStepSize, TRUE );
}
+
+void LLScrollbar::setThickness(S32 thickness)
+{
+ mThickness = thickness < 0 ? LLUI::sSettingGroups["config"]->getS32("UIScrollbarSize") : thickness;
+}
diff --git a/indra/llui/llscrollbar.h b/indra/llui/llscrollbar.h
index ff74f753b9..21fd2d631e 100644..100755
--- a/indra/llui/llscrollbar.h
+++ b/indra/llui/llscrollbar.h
@@ -124,6 +124,9 @@ public:
void onLineUpBtnPressed(const LLSD& data);
void onLineDownBtnPressed(const LLSD& data);
+
+ S32 getThickness() const { return mThickness; }
+ void setThickness(S32 thickness);
private:
void updateThumbRect();
diff --git a/indra/llui/llscrollcontainer.cpp b/indra/llui/llscrollcontainer.cpp
index 9b7e30bb04..238eae21c2 100644..100755
--- a/indra/llui/llscrollcontainer.cpp
+++ b/indra/llui/llscrollcontainer.cpp
@@ -73,7 +73,8 @@ LLScrollContainer::Params::Params()
hide_scrollbar("hide_scrollbar"),
min_auto_scroll_rate("min_auto_scroll_rate", 100),
max_auto_scroll_rate("max_auto_scroll_rate", 1000),
- reserve_scroll_corner("reserve_scroll_corner", false)
+ reserve_scroll_corner("reserve_scroll_corner", false),
+ size("size", -1)
{}
@@ -88,9 +89,12 @@ LLScrollContainer::LLScrollContainer(const LLScrollContainer::Params& p)
mReserveScrollCorner(p.reserve_scroll_corner),
mMinAutoScrollRate(p.min_auto_scroll_rate),
mMaxAutoScrollRate(p.max_auto_scroll_rate),
- mScrolledView(NULL)
+ mScrolledView(NULL),
+ mSize(p.size)
{
- static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
+ static LLUICachedControl<S32> scrollbar_size_control ("UIScrollbarSize", 0);
+ S32 scrollbar_size = (mSize == -1 ? scrollbar_size_control : mSize);
+
LLRect border_rect( 0, getRect().getHeight(), getRect().getWidth(), 0 );
LLViewBorder::Params params;
params.name("scroll border");
@@ -276,7 +280,6 @@ BOOL LLScrollContainer::handleDragAndDrop(S32 x, S32 y, MASK mask,
EAcceptance* accept,
std::string& tooltip_msg)
{
- static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
// Scroll folder view if needed. Never accepts a drag or drop.
*accept = ACCEPT_NO;
BOOL handled = autoScroll(x, y);
@@ -292,7 +295,8 @@ BOOL LLScrollContainer::handleDragAndDrop(S32 x, S32 y, MASK mask,
bool LLScrollContainer::autoScroll(S32 x, S32 y)
{
- static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
+ static LLUICachedControl<S32> scrollbar_size_control ("UIScrollbarSize", 0);
+ S32 scrollbar_size = (mSize == -1 ? scrollbar_size_control : mSize);
bool scrolling = false;
if( mScrollbar[HORIZONTAL]->getVisible() || mScrollbar[VERTICAL]->getVisible() )
@@ -365,7 +369,9 @@ bool LLScrollContainer::autoScroll(S32 x, S32 y)
void LLScrollContainer::calcVisibleSize( S32 *visible_width, S32 *visible_height, BOOL* show_h_scrollbar, BOOL* show_v_scrollbar ) const
{
const LLRect& doc_rect = getScrolledViewRect();
- static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
+ static LLUICachedControl<S32> scrollbar_size_control ("UIScrollbarSize", 0);
+ S32 scrollbar_size = (mSize == -1 ? scrollbar_size_control : mSize);
+
S32 doc_width = doc_rect.getWidth();
S32 doc_height = doc_rect.getHeight();
@@ -389,12 +395,11 @@ void LLScrollContainer::calcVisibleSize( S32 *visible_width, S32 *visible_height
{
*show_h_scrollbar = TRUE;
*visible_height -= scrollbar_size;
-
+ // Note: Do *not* recompute *show_v_scrollbar here because with
// The view inside the scroll container should not be extended
// to container's full height to ensure the correct computation
// of *show_v_scrollbar after subtracting horizontal scrollbar_size.
- // Must retest now that visible_height has changed
if( !*show_v_scrollbar && ((doc_height - *visible_height) > 1) )
{
*show_v_scrollbar = TRUE;
@@ -407,7 +412,9 @@ void LLScrollContainer::calcVisibleSize( S32 *visible_width, S32 *visible_height
void LLScrollContainer::draw()
{
- static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
+ static LLUICachedControl<S32> scrollbar_size_control ("UIScrollbarSize", 0);
+ S32 scrollbar_size = (mSize == -1 ? scrollbar_size_control : mSize);
+
if (mAutoScrolling)
{
// add acceleration to autoscroll
@@ -512,11 +519,13 @@ bool LLScrollContainer::addChild(LLView* view, S32 tab_group)
void LLScrollContainer::updateScroll()
{
- if (!mScrolledView)
+ if (!getVisible() || !mScrolledView)
{
return;
}
- static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
+ static LLUICachedControl<S32> scrollbar_size_control ("UIScrollbarSize", 0);
+ S32 scrollbar_size = (mSize == -1 ? scrollbar_size_control : mSize);
+
LLRect doc_rect = mScrolledView->getRect();
S32 doc_width = doc_rect.getWidth();
S32 doc_height = doc_rect.getHeight();
@@ -717,3 +726,9 @@ S32 LLScrollContainer::getBorderWidth() const
return 0;
}
+void LLScrollContainer::setSize(S32 size)
+{
+ mSize = size;
+ mScrollbar[VERTICAL]->setThickness(size);
+ mScrollbar[HORIZONTAL]->setThickness(size);
+}
diff --git a/indra/llui/llscrollcontainer.h b/indra/llui/llscrollcontainer.h
index d87c95b3d7..4eb43539b8 100644..100755
--- a/indra/llui/llscrollcontainer.h
+++ b/indra/llui/llscrollcontainer.h
@@ -68,6 +68,7 @@ public:
max_auto_scroll_rate;
Optional<LLUIColor> bg_color;
Optional<LLScrollbar::callback_t> scroll_callback;
+ Optional<S32> size;
Params();
};
@@ -116,6 +117,9 @@ public:
bool autoScroll(S32 x, S32 y);
+ S32 getSize() const { return mSize; }
+ void setSize(S32 thickness);
+
protected:
LLView* mScrolledView;
diff --git a/indra/llui/llscrollingpanellist.cpp b/indra/llui/llscrollingpanellist.cpp
index 9b65c2b79d..9b65c2b79d 100644..100755
--- a/indra/llui/llscrollingpanellist.cpp
+++ b/indra/llui/llscrollingpanellist.cpp
diff --git a/indra/llui/llscrollingpanellist.h b/indra/llui/llscrollingpanellist.h
index e8df176ec3..e8df176ec3 100644..100755
--- a/indra/llui/llscrollingpanellist.h
+++ b/indra/llui/llscrollingpanellist.h
diff --git a/indra/llui/llscrolllistcell.cpp b/indra/llui/llscrolllistcell.cpp
index 8000efad0e..8000efad0e 100644..100755
--- a/indra/llui/llscrolllistcell.cpp
+++ b/indra/llui/llscrolllistcell.cpp
diff --git a/indra/llui/llscrolllistcell.h b/indra/llui/llscrolllistcell.h
index d625ebddcc..d625ebddcc 100644..100755
--- a/indra/llui/llscrolllistcell.h
+++ b/indra/llui/llscrolllistcell.h
diff --git a/indra/llui/llscrolllistcolumn.cpp b/indra/llui/llscrolllistcolumn.cpp
index 07a6dfaa10..cc9ff7a487 100644..100755
--- a/indra/llui/llscrolllistcolumn.cpp
+++ b/indra/llui/llscrolllistcolumn.cpp
@@ -98,6 +98,7 @@ BOOL LLScrollColumnHeader::handleDoubleClick(S32 x, S32 y, MASK mask)
if (canResize() && mResizeBar->getRect().pointInRect(x, y))
{
// reshape column to max content width
+ mColumn->mParentCtrl->calcMaxContentWidth();
LLRect column_rect = getRect();
column_rect.mRight = column_rect.mLeft + mColumn->mMaxContentWidth;
setShape(column_rect, true);
@@ -127,6 +128,8 @@ LLView* LLScrollColumnHeader::findSnapEdge(S32& new_edge_val, const LLCoordGL& m
LLRect snap_rect = getSnapRect();
+ mColumn->mParentCtrl->calcMaxContentWidth();
+
S32 snap_delta = mColumn->mMaxContentWidth - snap_rect.getWidth();
// x coord growing means column growing, so same signs mean we're going in right direction
@@ -233,7 +236,8 @@ void LLScrollColumnHeader::handleReshape(const LLRect& new_rect, bool by_user)
// tell scroll list to layout columns again
// do immediate update to get proper feedback to resize handle
// which needs to know how far the resize actually went
- mColumn->mParentCtrl->updateColumns();
+ const bool force_update = true;
+ mColumn->mParentCtrl->updateColumns(force_update);
}
}
diff --git a/indra/llui/llscrolllistcolumn.h b/indra/llui/llscrolllistcolumn.h
index b4d4a6d05e..b4d4a6d05e 100644..100755
--- a/indra/llui/llscrolllistcolumn.h
+++ b/indra/llui/llscrolllistcolumn.h
diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp
index b3e1b63db5..6e03f604a2 100644..100755
--- a/indra/llui/llscrolllistctrl.cpp
+++ b/indra/llui/llscrolllistctrl.cpp
@@ -35,6 +35,7 @@
#include "llboost.h"
//#include "indra_constants.h"
+#include "llavatarnamecache.h"
#include "llcheckboxctrl.h"
#include "llclipboard.h"
#include "llfocusmgr.h"
@@ -158,15 +159,14 @@ LLScrollListCtrl::LLScrollListCtrl(const LLScrollListCtrl::Params& p)
mMouseWheelOpaque(p.mouse_wheel_opaque),
mPageLines(p.page_lines),
mMaxSelectable(0),
- mAllowKeyboardMovement(TRUE),
+ mAllowKeyboardMovement(true),
mCommitOnKeyboardMovement(p.commit_on_keyboard_movement),
- mCommitOnSelectionChange(FALSE),
- mSelectionChanged(FALSE),
- mNeedsScroll(FALSE),
- mCanSelect(TRUE),
- mColumnsDirty(FALSE),
+ mCommitOnSelectionChange(false),
+ mSelectionChanged(false),
+ mNeedsScroll(false),
+ mCanSelect(true),
+ mColumnsDirty(false),
mMaxItemCount(INT_MAX),
- mMaxContentWidth(0),
mBorderThickness( 2 ),
mOnDoubleClickCallback( NULL ),
mOnMaximumSelectCallback( NULL ),
@@ -180,7 +180,7 @@ LLScrollListCtrl::LLScrollListCtrl(const LLScrollListCtrl::Params& p)
mTotalStaticColumnWidth(0),
mTotalColumnPadding(0),
mSorted(false),
- mDirty(FALSE),
+ mDirty(false),
mOriginalSelection(-1),
mLastSelected(NULL),
mHeadingHeight(p.heading_height),
@@ -356,7 +356,7 @@ void LLScrollListCtrl::clearRows()
mScrollLines = 0;
mLastSelected = NULL;
updateLayout();
- mDirty = FALSE;
+ mDirty = false;
}
@@ -389,6 +389,22 @@ std::vector<LLScrollListItem*> LLScrollListCtrl::getAllSelected() const
return ret;
}
+S32 LLScrollListCtrl::getNumSelected() const
+{
+ S32 numSelected = 0;
+
+ for(item_list::const_iterator iter = mItemList.begin(); iter != mItemList.end(); ++iter)
+ {
+ LLScrollListItem* item = *iter;
+ if (item->getSelected())
+ {
+ ++numSelected;
+ }
+ }
+
+ return numSelected;
+}
+
S32 LLScrollListCtrl::getFirstSelectedIndex() const
{
S32 CurSelectedIndex = 0;
@@ -564,6 +580,15 @@ BOOL LLScrollListCtrl::addItem( LLScrollListItem* item, EAddPosition pos, BOOL r
addColumn(col_params);
}
+ S32 num_cols = item->getNumColumns();
+ S32 i = 0;
+ for (LLScrollListCell* cell = item->getColumn(i); i < num_cols; cell = item->getColumn(++i))
+ {
+ if (i >= (S32)mColumnsIndexed.size()) break;
+
+ cell->setWidth(mColumnsIndexed[i]->getWidth());
+ }
+
updateLineHeightInsert(item);
updateLayout();
@@ -575,13 +600,11 @@ BOOL LLScrollListCtrl::addItem( LLScrollListItem* item, EAddPosition pos, BOOL r
// NOTE: This is *very* expensive for large lists, especially when we are dirtying the list every frame
// while receiving a long list of names.
// *TODO: Use bookkeeping to make this an incramental cost with item additions
-void LLScrollListCtrl::calcColumnWidths()
+S32 LLScrollListCtrl::calcMaxContentWidth()
{
const S32 HEADING_TEXT_PADDING = 25;
const S32 COLUMN_TEXT_PADDING = 10;
- mMaxContentWidth = 0;
-
S32 max_item_width = 0;
ordered_columns_t::iterator column_itor;
@@ -590,8 +613,37 @@ void LLScrollListCtrl::calcColumnWidths()
LLScrollListColumn* column = *column_itor;
if (!column) continue;
+ if (mColumnWidthsDirty)
+ {
+ // update max content width for this column, by looking at all items
+ column->mMaxContentWidth = column->mHeader ? LLFontGL::getFontSansSerifSmall()->getWidth(column->mLabel) + mColumnPadding + HEADING_TEXT_PADDING : 0;
+ item_list::iterator iter;
+ for (iter = mItemList.begin(); iter != mItemList.end(); iter++)
+ {
+ LLScrollListCell* cellp = (*iter)->getColumn(column->mIndex);
+ if (!cellp) continue;
+
+ column->mMaxContentWidth = llmax(LLFontGL::getFontSansSerifSmall()->getWidth(cellp->getValue().asString()) + mColumnPadding + COLUMN_TEXT_PADDING, column->mMaxContentWidth);
+ }
+ }
+ max_item_width += column->mMaxContentWidth;
+ }
+ mColumnWidthsDirty = false;
+
+ return max_item_width;
+}
+
+bool LLScrollListCtrl::updateColumnWidths()
+{
+ bool width_changed = false;
+ ordered_columns_t::iterator column_itor;
+ for (column_itor = mColumnsIndexed.begin(); column_itor != mColumnsIndexed.end(); ++column_itor)
+ {
+ LLScrollListColumn* column = *column_itor;
+ if (!column) continue;
+
// update column width
- S32 new_width = column->getWidth();
+ S32 new_width = 0;
if (column->mRelWidth >= 0)
{
new_width = (S32)llround(column->mRelWidth*mItemListRect.getWidth());
@@ -600,24 +652,18 @@ void LLScrollListCtrl::calcColumnWidths()
{
new_width = (mItemListRect.getWidth() - mTotalStaticColumnWidth - mTotalColumnPadding) / mNumDynamicWidthColumns;
}
-
- column->setWidth(new_width);
-
- // update max content width for this column, by looking at all items
- column->mMaxContentWidth = column->mHeader ? LLFontGL::getFontSansSerifSmall()->getWidth(column->mLabel) + mColumnPadding + HEADING_TEXT_PADDING : 0;
- item_list::iterator iter;
- for (iter = mItemList.begin(); iter != mItemList.end(); iter++)
+ else
{
- LLScrollListCell* cellp = (*iter)->getColumn(column->mIndex);
- if (!cellp) continue;
-
- column->mMaxContentWidth = llmax(LLFontGL::getFontSansSerifSmall()->getWidth(cellp->getValue().asString()) + mColumnPadding + COLUMN_TEXT_PADDING, column->mMaxContentWidth);
+ new_width = column->getWidth();
}
- max_item_width += column->mMaxContentWidth;
+ if (column->getWidth() != new_width)
+ {
+ column->setWidth(new_width);
+ width_changed = true;
+ }
}
-
- mMaxContentWidth = max_item_width;
+ return width_changed;
}
const S32 SCROLL_LIST_ROW_PAD = 2;
@@ -651,9 +697,14 @@ void LLScrollListCtrl::updateLineHeightInsert(LLScrollListItem* itemp)
}
-void LLScrollListCtrl::updateColumns()
+void LLScrollListCtrl::updateColumns(bool force_update)
{
- calcColumnWidths();
+ if (!mColumnsDirty && !force_update)
+ return;
+
+ mColumnsDirty = false;
+
+ bool columns_changed_width = updateColumnWidths();
// update column headers
std::vector<LLScrollListColumn*>::iterator column_ordered_it;
@@ -702,20 +753,22 @@ void LLScrollListCtrl::updateColumns()
}
// propagate column widths to individual cells
- item_list::iterator iter;
- for (iter = mItemList.begin(); iter != mItemList.end(); iter++)
+ if (columns_changed_width || force_update)
{
- LLScrollListItem *itemp = *iter;
- S32 num_cols = itemp->getNumColumns();
- S32 i = 0;
- for (LLScrollListCell* cell = itemp->getColumn(i); i < num_cols; cell = itemp->getColumn(++i))
+ item_list::iterator iter;
+ for (iter = mItemList.begin(); iter != mItemList.end(); iter++)
{
- if (i >= (S32)mColumnsIndexed.size()) break;
+ LLScrollListItem *itemp = *iter;
+ S32 num_cols = itemp->getNumColumns();
+ S32 i = 0;
+ for (LLScrollListCell* cell = itemp->getColumn(i); i < num_cols; cell = itemp->getColumn(++i))
+ {
+ if (i >= (S32)mColumnsIndexed.size()) break;
- cell->setWidth(mColumnsIndexed[i]->getWidth());
+ cell->setWidth(mColumnsIndexed[i]->getWidth());
+ }
}
}
-
}
void LLScrollListCtrl::setHeadingHeight(S32 heading_height)
@@ -756,7 +809,7 @@ BOOL LLScrollListCtrl::selectFirstItem()
{
deselectItem(itemp);
}
- first_item = FALSE;
+ first_item = false;
}
if (mCommitOnSelectionChange)
{
@@ -1130,10 +1183,10 @@ LLScrollListItem* LLScrollListCtrl::addSeparator(EAddPosition pos)
// Selects first enabled item of the given name.
// Returns false if item not found.
// Calls getItemByLabel in order to combine functionality
-BOOL LLScrollListCtrl::selectItemByLabel(const std::string& label, BOOL case_sensitive)
+BOOL LLScrollListCtrl::selectItemByLabel(const std::string& label, BOOL case_sensitive, S32 column/* = 0*/)
{
deselectAllItems(TRUE); // ensure that no stale items are selected, even if we don't find a match
- LLScrollListItem* item = getItemByLabel(label, case_sensitive);
+ LLScrollListItem* item = getItemByLabel(label, case_sensitive, column);
bool found = NULL != item;
if(found)
@@ -1390,17 +1443,23 @@ void LLScrollListCtrl::drawItems()
S32 cur_y = y;
- S32 line = 0;
S32 max_columns = 0;
LLColor4 highlight_color = LLColor4::white;
static LLUICachedControl<F32> type_ahead_timeout ("TypeAheadTimeout", 0);
highlight_color.mV[VALPHA] = clamp_rescale(mSearchTimer.getElapsedTimeF32(), type_ahead_timeout * 0.7f, type_ahead_timeout, 0.4f, 0.f);
+ S32 first_line = mScrollLines;
+ S32 last_line = llmin((S32)mItemList.size() - 1, mScrollLines + getLinesPerPage());
+
+ if (first_line >= mItemList.size())
+ {
+ return;
+ }
item_list::iterator iter;
- for (iter = mItemList.begin(); iter != mItemList.end(); iter++)
+ for (S32 line = first_line; line <= last_line; line++)
{
- LLScrollListItem* item = *iter;
+ LLScrollListItem* item = mItemList[line];
item_rect.setOriginAndSize(
x,
@@ -1464,7 +1523,6 @@ void LLScrollListCtrl::drawItems()
cur_y -= mLineHeight;
}
- line++;
}
}
}
@@ -1480,7 +1538,7 @@ void LLScrollListCtrl::draw()
if (mNeedsScroll)
{
scrollToShowSelected();
- mNeedsScroll = FALSE;
+ mNeedsScroll = false;
}
LLRect background(0, getRect().getHeight(), getRect().getWidth(), 0);
// Draw background
@@ -1491,11 +1549,7 @@ void LLScrollListCtrl::draw()
gl_rect_2d(background, getEnabled() ? mBgWriteableColor.get() % alpha : mBgReadOnlyColor.get() % alpha );
}
- if (mColumnsDirty)
- {
- updateColumns();
- mColumnsDirty = FALSE;
- }
+ updateColumns();
getChildView("comment_text")->setVisible(mItemList.empty());
@@ -1703,7 +1757,7 @@ BOOL LLScrollListCtrl::handleMouseDown(S32 x, S32 y, MASK mask)
setFocus(TRUE);
// clear selection changed flag because user is starting a selection operation
- mSelectionChanged = FALSE;
+ mSelectionChanged = false;
handleClick(x, y, mask);
}
@@ -1721,15 +1775,15 @@ BOOL LLScrollListCtrl::handleMouseUp(S32 x, S32 y, MASK mask)
if(mask == MASK_NONE)
{
selectItemAt(x, y, mask);
- mNeedsScroll = TRUE;
+ mNeedsScroll = true;
}
}
// always commit when mouse operation is completed inside list
if (mItemListRect.pointInRect(x,y))
{
- mDirty |= mSelectionChanged;
- mSelectionChanged = FALSE;
+ mDirty = mDirty || mSelectionChanged;
+ mSelectionChanged = false;
onCommit();
}
@@ -1751,6 +1805,9 @@ BOOL LLScrollListCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask)
// (N.B. callbacks don't take const refs as id is local scope)
bool is_group = (mContextMenuType == MENU_GROUP);
LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
+ registrar.add("Url.ShowProfile", boost::bind(&LLScrollListCtrl::showProfile, id, is_group));
+ registrar.add("Url.SendIM", boost::bind(&LLScrollListCtrl::sendIM, id));
+ registrar.add("Url.AddFriend", boost::bind(&LLScrollListCtrl::addFriend, id));
registrar.add("Url.Execute", boost::bind(&LLScrollListCtrl::showNameDetails, id, is_group));
registrar.add("Url.CopyLabel", boost::bind(&LLScrollListCtrl::copyNameToClipboard, id, is_group));
registrar.add("Url.CopyUrl", boost::bind(&LLScrollListCtrl::copySLURLToClipboard, id, is_group));
@@ -1771,11 +1828,33 @@ BOOL LLScrollListCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask)
return FALSE;
}
-void LLScrollListCtrl::showNameDetails(std::string id, bool is_group)
+void LLScrollListCtrl::showProfile(std::string id, bool is_group)
{
// show the resident's profile or the group profile
std::string sltype = is_group ? "group" : "agent";
std::string slurl = "secondlife:///app/" + sltype + "/" + id + "/about";
+ LLUrlAction::showProfile(slurl);
+}
+
+void LLScrollListCtrl::sendIM(std::string id)
+{
+ // send im to the resident
+ std::string slurl = "secondlife:///app/agent/" + id + "/about";
+ LLUrlAction::sendIM(slurl);
+}
+
+void LLScrollListCtrl::addFriend(std::string id)
+{
+ // add resident to friends list
+ std::string slurl = "secondlife:///app/agent/" + id + "/about";
+ LLUrlAction::addFriend(slurl);
+}
+
+void LLScrollListCtrl::showNameDetails(std::string id, bool is_group)
+{
+ // open the resident's details or the group details
+ std::string sltype = is_group ? "group" : "agent";
+ std::string slurl = "secondlife:///app/" + sltype + "/" + id + "/about";
LLUrlAction::clickAction(slurl);
}
@@ -1789,7 +1868,9 @@ void LLScrollListCtrl::copyNameToClipboard(std::string id, bool is_group)
}
else
{
- gCacheName->getFullName(LLUUID(id), name);
+ LLAvatarName av_name;
+ LLAvatarNameCache::get(LLUUID(id), &av_name);
+ name = av_name.getAccountName();
}
LLUrlAction::copyURLToClipboard(name);
}
@@ -1843,7 +1924,7 @@ BOOL LLScrollListCtrl::handleClick(S32 x, S32 y, MASK mask)
{
selectItemAt(x, y, mask);
gFocusMgr.setMouseCapture(this);
- mNeedsScroll = TRUE;
+ mNeedsScroll = true;
}
// propagate state of cell to rest of selected column
@@ -1872,7 +1953,7 @@ BOOL LLScrollListCtrl::handleClick(S32 x, S32 y, MASK mask)
// treat this as a normal single item selection
selectItemAt(x, y, mask);
gFocusMgr.setMouseCapture(this);
- mNeedsScroll = TRUE;
+ mNeedsScroll = true;
// do not eat click (allow double click callback)
return FALSE;
}
@@ -1978,7 +2059,7 @@ BOOL LLScrollListCtrl::handleHover(S32 x,S32 y,MASK mask)
if(mask == MASK_NONE)
{
selectItemAt(x, y, mask);
- mNeedsScroll = TRUE;
+ mNeedsScroll = true;
}
}
else
@@ -2025,7 +2106,7 @@ BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask )
{
// commit implicit in call
selectPrevItem(FALSE);
- mNeedsScroll = TRUE;
+ mNeedsScroll = true;
handled = TRUE;
}
break;
@@ -2034,7 +2115,7 @@ BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask )
{
// commit implicit in call
selectNextItem(FALSE);
- mNeedsScroll = TRUE;
+ mNeedsScroll = true;
handled = TRUE;
}
break;
@@ -2042,7 +2123,7 @@ BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask )
if (mAllowKeyboardMovement || hasFocus())
{
selectNthItem(getFirstSelectedIndex() - (mScrollbar->getPageSize() - 1));
- mNeedsScroll = TRUE;
+ mNeedsScroll = true;
if (mCommitOnKeyboardMovement
&& !mCommitOnSelectionChange)
{
@@ -2055,7 +2136,7 @@ BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask )
if (mAllowKeyboardMovement || hasFocus())
{
selectNthItem(getFirstSelectedIndex() + (mScrollbar->getPageSize() - 1));
- mNeedsScroll = TRUE;
+ mNeedsScroll = true;
if (mCommitOnKeyboardMovement
&& !mCommitOnSelectionChange)
{
@@ -2068,7 +2149,7 @@ BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask )
if (mAllowKeyboardMovement || hasFocus())
{
selectFirstItem();
- mNeedsScroll = TRUE;
+ mNeedsScroll = true;
if (mCommitOnKeyboardMovement
&& !mCommitOnSelectionChange)
{
@@ -2081,7 +2162,7 @@ BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask )
if (mAllowKeyboardMovement || hasFocus())
{
selectNthItem(getItemCount() - 1);
- mNeedsScroll = TRUE;
+ mNeedsScroll = true;
if (mCommitOnKeyboardMovement
&& !mCommitOnSelectionChange)
{
@@ -2120,7 +2201,7 @@ BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask )
}
else if (selectItemByPrefix(wstring_to_utf8str(mSearchString), FALSE))
{
- mNeedsScroll = TRUE;
+ mNeedsScroll = true;
// update search string only on successful match
mSearchTimer.reset();
@@ -2161,7 +2242,7 @@ BOOL LLScrollListCtrl::handleUnicodeCharHere(llwchar uni_char)
if (selectItemByPrefix(wstring_to_utf8str(mSearchString + (llwchar)uni_char), FALSE))
{
// update search string only on successful match
- mNeedsScroll = TRUE;
+ mNeedsScroll = true;
mSearchString += uni_char;
mSearchTimer.reset();
@@ -2207,7 +2288,7 @@ BOOL LLScrollListCtrl::handleUnicodeCharHere(llwchar uni_char)
if (item->getEnabled() && LLStringOps::toLower(item_label[0]) == uni_char)
{
selectItem(item);
- mNeedsScroll = TRUE;
+ mNeedsScroll = true;
cellp->highlightText(0, 1);
mSearchTimer.reset();
@@ -2278,7 +2359,7 @@ void LLScrollListCtrl::selectItem(LLScrollListItem* itemp, BOOL select_single_it
}
itemp->setSelected(TRUE);
mLastSelected = itemp;
- mSelectionChanged = TRUE;
+ mSelectionChanged = true;
}
}
@@ -2299,7 +2380,7 @@ void LLScrollListCtrl::deselectItem(LLScrollListItem* itemp)
{
cellp->highlightText(0, 0);
}
- mSelectionChanged = TRUE;
+ mSelectionChanged = true;
}
}
@@ -2307,7 +2388,7 @@ void LLScrollListCtrl::commitIfChanged()
{
if (mSelectionChanged)
{
- mDirty = TRUE;
+ mDirty = true;
mSelectionChanged = FALSE;
onCommit();
}
@@ -2418,7 +2499,8 @@ void LLScrollListCtrl::sortOnce(S32 column, BOOL ascending)
void LLScrollListCtrl::dirtyColumns()
{
- mColumnsDirty = TRUE;
+ mColumnsDirty = true;
+ mColumnWidthsDirty = true;
// need to keep mColumnsIndexed up to date
// just in case someone indexes into it immediately
@@ -2704,6 +2786,11 @@ BOOL LLScrollListCtrl::hasSortOrder() const
return !mSortColumns.empty();
}
+void LLScrollListCtrl::clearSortOrder()
+{
+ mSortColumns.clear();
+}
+
void LLScrollListCtrl::clearColumns()
{
column_map_t::iterator itor;
@@ -2982,7 +3069,7 @@ void LLScrollListCtrl::resetDirty()
void LLScrollListCtrl::onFocusReceived()
{
// forget latent selection changes when getting focus
- mSelectionChanged = FALSE;
+ mSelectionChanged = false;
LLUICtrl::onFocusReceived();
}
diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h
index ae8aea9245..c61e281a31 100644..100755
--- a/indra/llui/llscrolllistctrl.h
+++ b/indra/llui/llscrolllistctrl.h
@@ -241,7 +241,7 @@ public:
// one of which can be selected at a time.
virtual LLScrollListItem* addSimpleElement(const std::string& value, EAddPosition pos = ADD_BOTTOM, const LLSD& id = LLSD());
- BOOL selectItemByLabel( const std::string& item, BOOL case_sensitive = TRUE ); // FALSE if item not found
+ BOOL selectItemByLabel( const std::string& item, BOOL case_sensitive = TRUE, S32 column = 0 ); // FALSE if item not found
BOOL selectItemByPrefix(const std::string& target, BOOL case_sensitive = TRUE);
BOOL selectItemByPrefix(const LLWString& target, BOOL case_sensitive = TRUE);
LLScrollListItem* getItemByLabel( const std::string& item, BOOL case_sensitive = TRUE, S32 column = 0 );
@@ -257,6 +257,7 @@ public:
LLScrollListItem* getFirstSelected() const;
virtual S32 getFirstSelectedIndex() const;
std::vector<LLScrollListItem*> getAllSelected() const;
+ S32 getNumSelected() const;
LLScrollListItem* getLastSelectedItem() const { return mLastSelected; }
// iterate over all items
@@ -341,9 +342,9 @@ public:
static void onClickColumn(void *userdata);
- virtual void updateColumns();
- void calcColumnWidths();
- S32 getMaxContentWidth() { return mMaxContentWidth; }
+ virtual void updateColumns(bool force_update = false);
+ S32 calcMaxContentWidth();
+ bool updateColumnWidths();
void setHeadingHeight(S32 heading_height);
/**
@@ -373,6 +374,7 @@ public:
std::string getSortColumnName();
BOOL getSortAscending() { return mSortColumns.empty() ? TRUE : mSortColumns.back().second; }
BOOL hasSortOrder() const;
+ void clearSortOrder();
S32 selectMultiple( uuid_vec_t ids );
// conceptually const, but mutates mItemList
@@ -428,6 +430,9 @@ private:
BOOL setSort(S32 column, BOOL ascending);
S32 getLinesPerPage();
+ static void showProfile(std::string id, bool is_group);
+ static void sendIM(std::string id);
+ static void addFriend(std::string id);
static void showNameDetails(std::string id, bool is_group);
static void copyNameToClipboard(std::string id, bool is_group);
static void copySLURLToClipboard(std::string id, bool is_group);
@@ -438,16 +443,17 @@ private:
S32 mHeadingHeight; // the height of the column header buttons, if visible
U32 mMaxSelectable;
LLScrollbar* mScrollbar;
- BOOL mAllowMultipleSelection;
- BOOL mAllowKeyboardMovement;
- BOOL mCommitOnKeyboardMovement;
- BOOL mCommitOnSelectionChange;
- BOOL mSelectionChanged;
- BOOL mNeedsScroll;
- BOOL mMouseWheelOpaque;
- BOOL mCanSelect;
- const BOOL mDisplayColumnHeaders;
- BOOL mColumnsDirty;
+ bool mAllowMultipleSelection;
+ bool mAllowKeyboardMovement;
+ bool mCommitOnKeyboardMovement;
+ bool mCommitOnSelectionChange;
+ bool mSelectionChanged;
+ bool mNeedsScroll;
+ bool mMouseWheelOpaque;
+ bool mCanSelect;
+ bool mDisplayColumnHeaders;
+ bool mColumnsDirty;
+ bool mColumnWidthsDirty;
mutable item_list mItemList;
@@ -456,7 +462,6 @@ private:
S32 mMaxItemCount;
LLRect mItemListRect;
- S32 mMaxContentWidth;
S32 mColumnPadding;
BOOL mBackgroundVisible;
@@ -496,7 +501,7 @@ private:
typedef std::map<std::string, LLScrollListColumn*> column_map_t;
column_map_t mColumns;
- BOOL mDirty;
+ bool mDirty;
S32 mOriginalSelection;
ContextMenuType mContextMenuType;
diff --git a/indra/llui/llscrolllistitem.cpp b/indra/llui/llscrolllistitem.cpp
index 5a1e96ab03..5a1e96ab03 100644..100755
--- a/indra/llui/llscrolllistitem.cpp
+++ b/indra/llui/llscrolllistitem.cpp
diff --git a/indra/llui/llscrolllistitem.h b/indra/llui/llscrolllistitem.h
index 13655b5873..13655b5873 100644..100755
--- a/indra/llui/llscrolllistitem.h
+++ b/indra/llui/llscrolllistitem.h
diff --git a/indra/llui/llsdparam.cpp b/indra/llui/llsdparam.cpp
deleted file mode 100644
index 0e29873bb0..0000000000
--- a/indra/llui/llsdparam.cpp
+++ /dev/null
@@ -1,342 +0,0 @@
-/**
- * @file llsdparam.cpp
- * @brief parameter block abstraction for creating complex objects and
- * parsing construction parameters from xml and LLSD
- *
- * $LicenseInfo:firstyear=2008&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"
-
-// Project includes
-#include "llsdparam.h"
-#include "llsdutil.h"
-
-static LLInitParam::Parser::parser_read_func_map_t sReadFuncs;
-static LLInitParam::Parser::parser_write_func_map_t sWriteFuncs;
-static LLInitParam::Parser::parser_inspect_func_map_t sInspectFuncs;
-static const LLSD NO_VALUE_MARKER;
-
-LLFastTimer::DeclareTimer FTM_SD_PARAM_ADAPTOR("LLSD to LLInitParam conversion");
-
-//
-// LLParamSDParser
-//
-LLParamSDParser::LLParamSDParser()
-: Parser(sReadFuncs, sWriteFuncs, sInspectFuncs)
-{
- using boost::bind;
-
- if (sReadFuncs.empty())
- {
- registerParserFuncs<LLInitParam::Flag>(readFlag, &LLParamSDParser::writeFlag);
- registerParserFuncs<S32>(readS32, &LLParamSDParser::writeTypedValue<S32>);
- registerParserFuncs<U32>(readU32, &LLParamSDParser::writeU32Param);
- registerParserFuncs<F32>(readF32, &LLParamSDParser::writeTypedValue<F32>);
- registerParserFuncs<F64>(readF64, &LLParamSDParser::writeTypedValue<F64>);
- registerParserFuncs<bool>(readBool, &LLParamSDParser::writeTypedValue<bool>);
- registerParserFuncs<std::string>(readString, &LLParamSDParser::writeTypedValue<std::string>);
- registerParserFuncs<LLUUID>(readUUID, &LLParamSDParser::writeTypedValue<LLUUID>);
- registerParserFuncs<LLDate>(readDate, &LLParamSDParser::writeTypedValue<LLDate>);
- registerParserFuncs<LLURI>(readURI, &LLParamSDParser::writeTypedValue<LLURI>);
- registerParserFuncs<LLSD>(readSD, &LLParamSDParser::writeTypedValue<LLSD>);
- }
-}
-
-// special case handling of U32 due to ambiguous LLSD::assign overload
-bool LLParamSDParser::writeU32Param(LLParamSDParser::parser_t& parser, const void* val_ptr, parser_t::name_stack_t& name_stack)
-{
- LLParamSDParser& sdparser = static_cast<LLParamSDParser&>(parser);
- if (!sdparser.mWriteRootSD) return false;
-
- parser_t::name_stack_range_t range(name_stack.begin(), name_stack.end());
- LLSD& sd_to_write = LLParamSDParserUtilities::getSDWriteNode(*sdparser.mWriteRootSD, range);
- sd_to_write.assign((S32)*((const U32*)val_ptr));
-
- return true;
-}
-
-bool LLParamSDParser::writeFlag(LLParamSDParser::parser_t& parser, const void* val_ptr, parser_t::name_stack_t& name_stack)
-{
- LLParamSDParser& sdparser = static_cast<LLParamSDParser&>(parser);
- if (!sdparser.mWriteRootSD) return false;
-
- parser_t::name_stack_range_t range(name_stack.begin(), name_stack.end());
- LLParamSDParserUtilities::getSDWriteNode(*sdparser.mWriteRootSD, range);
-
- return true;
-}
-
-void LLParamSDParser::submit(LLInitParam::BaseBlock& block, const LLSD& sd, LLInitParam::Parser::name_stack_t& name_stack)
-{
- mCurReadSD = &sd;
- block.submitValue(name_stack, *this);
-}
-
-void LLParamSDParser::readSD(const LLSD& sd, LLInitParam::BaseBlock& block, bool silent)
-{
- mCurReadSD = NULL;
- mNameStack.clear();
- setParseSilently(silent);
-
- LLParamSDParserUtilities::readSDValues(boost::bind(&LLParamSDParser::submit, this, boost::ref(block), _1, _2), sd, mNameStack);
- //readSDValues(sd, block);
-}
-
-void LLParamSDParser::writeSD(LLSD& sd, const LLInitParam::BaseBlock& block)
-{
- mNameStack.clear();
- mWriteRootSD = &sd;
-
- name_stack_t name_stack;
- block.serializeBlock(*this, name_stack);
-}
-
-/*virtual*/ std::string LLParamSDParser::getCurrentElementName()
-{
- std::string full_name = "sd";
- for (name_stack_t::iterator it = mNameStack.begin();
- it != mNameStack.end();
- ++it)
- {
- full_name += llformat("[%s]", it->first.c_str());
- }
-
- return full_name;
-}
-
-
-bool LLParamSDParser::readFlag(Parser& parser, void* val_ptr)
-{
- LLParamSDParser& self = static_cast<LLParamSDParser&>(parser);
- return self.mCurReadSD == &NO_VALUE_MARKER;
-}
-
-
-bool LLParamSDParser::readS32(Parser& parser, void* val_ptr)
-{
- LLParamSDParser& self = static_cast<LLParamSDParser&>(parser);
-
- *((S32*)val_ptr) = self.mCurReadSD->asInteger();
- return true;
-}
-
-bool LLParamSDParser::readU32(Parser& parser, void* val_ptr)
-{
- LLParamSDParser& self = static_cast<LLParamSDParser&>(parser);
-
- *((U32*)val_ptr) = self.mCurReadSD->asInteger();
- return true;
-}
-
-bool LLParamSDParser::readF32(Parser& parser, void* val_ptr)
-{
- LLParamSDParser& self = static_cast<LLParamSDParser&>(parser);
-
- *((F32*)val_ptr) = self.mCurReadSD->asReal();
- return true;
-}
-
-bool LLParamSDParser::readF64(Parser& parser, void* val_ptr)
-{
- LLParamSDParser& self = static_cast<LLParamSDParser&>(parser);
-
- *((F64*)val_ptr) = self.mCurReadSD->asReal();
- return true;
-}
-
-bool LLParamSDParser::readBool(Parser& parser, void* val_ptr)
-{
- LLParamSDParser& self = static_cast<LLParamSDParser&>(parser);
-
- *((bool*)val_ptr) = self.mCurReadSD->asBoolean();
- return true;
-}
-
-bool LLParamSDParser::readString(Parser& parser, void* val_ptr)
-{
- LLParamSDParser& self = static_cast<LLParamSDParser&>(parser);
-
- *((std::string*)val_ptr) = self.mCurReadSD->asString();
- return true;
-}
-
-bool LLParamSDParser::readUUID(Parser& parser, void* val_ptr)
-{
- LLParamSDParser& self = static_cast<LLParamSDParser&>(parser);
-
- *((LLUUID*)val_ptr) = self.mCurReadSD->asUUID();
- return true;
-}
-
-bool LLParamSDParser::readDate(Parser& parser, void* val_ptr)
-{
- LLParamSDParser& self = static_cast<LLParamSDParser&>(parser);
-
- *((LLDate*)val_ptr) = self.mCurReadSD->asDate();
- return true;
-}
-
-bool LLParamSDParser::readURI(Parser& parser, void* val_ptr)
-{
- LLParamSDParser& self = static_cast<LLParamSDParser&>(parser);
-
- *((LLURI*)val_ptr) = self.mCurReadSD->asURI();
- return true;
-}
-
-bool LLParamSDParser::readSD(Parser& parser, void* val_ptr)
-{
- LLParamSDParser& self = static_cast<LLParamSDParser&>(parser);
-
- *((LLSD*)val_ptr) = *self.mCurReadSD;
- return true;
-}
-
-// static
-LLSD& LLParamSDParserUtilities::getSDWriteNode(LLSD& input, LLInitParam::Parser::name_stack_range_t& name_stack_range)
-{
- LLSD* sd_to_write = &input;
-
- for (LLInitParam::Parser::name_stack_t::iterator it = name_stack_range.first;
- it != name_stack_range.second;
- ++it)
- {
- bool new_traversal = it->second;
-
- LLSD* child_sd = it->first.empty() ? sd_to_write : &(*sd_to_write)[it->first];
-
- if (child_sd->isArray())
- {
- if (new_traversal)
- {
- // write to new element at end
- sd_to_write = &(*child_sd)[child_sd->size()];
- }
- else
- {
- // write to last of existing elements, or first element if empty
- sd_to_write = &(*child_sd)[llmax(0, child_sd->size() - 1)];
- }
- }
- else
- {
- if (new_traversal
- && child_sd->isDefined()
- && !child_sd->isArray())
- {
- // copy child contents into first element of an array
- LLSD new_array = LLSD::emptyArray();
- new_array.append(*child_sd);
- // assign array to slot that previously held the single value
- *child_sd = new_array;
- // return next element in that array
- sd_to_write = &((*child_sd)[1]);
- }
- else
- {
- sd_to_write = child_sd;
- }
- }
- it->second = false;
- }
-
- return *sd_to_write;
-}
-
-//static
-void LLParamSDParserUtilities::readSDValues(read_sd_cb_t cb, const LLSD& sd, LLInitParam::Parser::name_stack_t& stack)
-{
- if (sd.isMap())
- {
- for (LLSD::map_const_iterator it = sd.beginMap();
- it != sd.endMap();
- ++it)
- {
- stack.push_back(make_pair(it->first, true));
- readSDValues(cb, it->second, stack);
- stack.pop_back();
- }
- }
- else if (sd.isArray())
- {
- for (LLSD::array_const_iterator it = sd.beginArray();
- it != sd.endArray();
- ++it)
- {
- stack.back().second = true;
- readSDValues(cb, *it, stack);
- }
- }
- else if (sd.isUndefined())
- {
- if (!cb.empty())
- {
- cb(NO_VALUE_MARKER, stack);
- }
- }
- else
- {
- if (!cb.empty())
- {
- cb(sd, stack);
- }
- }
-}
-
-//static
-void LLParamSDParserUtilities::readSDValues(read_sd_cb_t cb, const LLSD& sd)
-{
- LLInitParam::Parser::name_stack_t stack = LLInitParam::Parser::name_stack_t();
- readSDValues(cb, sd, stack);
-}
-namespace LLInitParam
-{
- // LLSD specialization
- // block param interface
- bool ParamValue<LLSD, TypeValues<LLSD>, false>::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack, bool new_name)
- {
- LLSD& sd = LLParamSDParserUtilities::getSDWriteNode(mValue, name_stack);
-
- LLSD::String string;
-
- if (p.readValue<LLSD::String>(string))
- {
- sd = string;
- return true;
- }
- return false;
- }
-
- //static
- void ParamValue<LLSD, TypeValues<LLSD>, false>::serializeElement(Parser& p, const LLSD& sd, Parser::name_stack_t& name_stack)
- {
- p.writeValue<LLSD::String>(sd.asString(), name_stack);
- }
-
- void ParamValue<LLSD, TypeValues<LLSD>, false>::serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const BaseBlock* diff_block) const
- {
- // read from LLSD value and serialize out to parser (which could be LLSD, XUI, etc)
- Parser::name_stack_t stack;
- LLParamSDParserUtilities::readSDValues(boost::bind(&serializeElement, boost::ref(p), _1, _2), mValue, stack);
- }
-}
diff --git a/indra/llui/llsdparam.h b/indra/llui/llsdparam.h
deleted file mode 100644
index 3dfc6d020e..0000000000
--- a/indra/llui/llsdparam.h
+++ /dev/null
@@ -1,126 +0,0 @@
-/**
- * @file llsdparam.h
- * @brief parameter block abstraction for creating complex objects and
- * parsing construction parameters from xml and LLSD
- *
- * $LicenseInfo:firstyear=2008&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$
- */
-
-#ifndef LL_LLSDPARAM_H
-#define LL_LLSDPARAM_H
-
-#include "llinitparam.h"
-#include "boost/function.hpp"
-
-struct LLParamSDParserUtilities
-{
- static LLSD& getSDWriteNode(LLSD& input, LLInitParam::Parser::name_stack_range_t& name_stack_range);
-
- typedef boost::function<void (const LLSD&, LLInitParam::Parser::name_stack_t&)> read_sd_cb_t;
- static void readSDValues(read_sd_cb_t cb, const LLSD& sd, LLInitParam::Parser::name_stack_t& stack);
- static void readSDValues(read_sd_cb_t cb, const LLSD& sd);
-};
-
-class LLParamSDParser
-: public LLInitParam::Parser
-{
-LOG_CLASS(LLParamSDParser);
-
-typedef LLInitParam::Parser parser_t;
-
-public:
- LLParamSDParser();
- void readSD(const LLSD& sd, LLInitParam::BaseBlock& block, bool silent = false);
- void writeSD(LLSD& sd, const LLInitParam::BaseBlock& block);
-
- /*virtual*/ std::string getCurrentElementName();
-
-private:
- void submit(LLInitParam::BaseBlock& block, const LLSD& sd, LLInitParam::Parser::name_stack_t& name_stack);
-
- template<typename T>
- static bool writeTypedValue(Parser& parser, const void* val_ptr, parser_t::name_stack_t& name_stack)
- {
- LLParamSDParser& sdparser = static_cast<LLParamSDParser&>(parser);
- if (!sdparser.mWriteRootSD) return false;
-
- LLInitParam::Parser::name_stack_range_t range(name_stack.begin(), name_stack.end());
- LLSD& sd_to_write = LLParamSDParserUtilities::getSDWriteNode(*sdparser.mWriteRootSD, range);
-
- sd_to_write.assign(*((const T*)val_ptr));
- return true;
- }
-
- static bool writeU32Param(Parser& parser, const void* value_ptr, parser_t::name_stack_t& name_stack);
- static bool writeFlag(Parser& parser, const void* value_ptr, parser_t::name_stack_t& name_stack);
-
- static bool readFlag(Parser& parser, void* val_ptr);
- static bool readS32(Parser& parser, void* val_ptr);
- static bool readU32(Parser& parser, void* val_ptr);
- static bool readF32(Parser& parser, void* val_ptr);
- static bool readF64(Parser& parser, void* val_ptr);
- static bool readBool(Parser& parser, void* val_ptr);
- static bool readString(Parser& parser, void* val_ptr);
- static bool readUUID(Parser& parser, void* val_ptr);
- static bool readDate(Parser& parser, void* val_ptr);
- static bool readURI(Parser& parser, void* val_ptr);
- static bool readSD(Parser& parser, void* val_ptr);
-
- Parser::name_stack_t mNameStack;
- const LLSD* mCurReadSD;
- LLSD* mWriteRootSD;
- LLSD* mCurWriteSD;
-};
-
-
-extern LLFastTimer::DeclareTimer FTM_SD_PARAM_ADAPTOR;
-template<typename T>
-class LLSDParamAdapter : public T
-{
-public:
- LLSDParamAdapter() {}
- LLSDParamAdapter(const LLSD& sd)
- {
- LLFastTimer _(FTM_SD_PARAM_ADAPTOR);
- LLParamSDParser parser;
- // don't spam for implicit parsing of LLSD, as we want to allow arbitrary freeform data and ignore most of it
- bool parse_silently = true;
- parser.readSD(sd, *this, parse_silently);
- }
-
- operator LLSD() const
- {
- LLParamSDParser parser;
- LLSD sd;
- parser.writeSD(sd, *this);
- return sd;
- }
-
- LLSDParamAdapter(const T& val)
- : T(val)
- {
- T::operator=(val);
- }
-};
-
-#endif // LL_LLSDPARAM_H
-
diff --git a/indra/llui/llsearcheditor.cpp b/indra/llui/llsearcheditor.cpp
index ea96fc573d..ea96fc573d 100644..100755
--- a/indra/llui/llsearcheditor.cpp
+++ b/indra/llui/llsearcheditor.cpp
diff --git a/indra/llui/llsearcheditor.h b/indra/llui/llsearcheditor.h
index c2d7916938..c2d7916938 100644..100755
--- a/indra/llui/llsearcheditor.h
+++ b/indra/llui/llsearcheditor.h
diff --git a/indra/llui/llslider.cpp b/indra/llui/llslider.cpp
index db72234f94..db72234f94 100644..100755
--- a/indra/llui/llslider.cpp
+++ b/indra/llui/llslider.cpp
diff --git a/indra/llui/llslider.h b/indra/llui/llslider.h
index 700c17ea3e..700c17ea3e 100644..100755
--- a/indra/llui/llslider.h
+++ b/indra/llui/llslider.h
diff --git a/indra/llui/llsliderctrl.cpp b/indra/llui/llsliderctrl.cpp
index 583ed1ed2e..583ed1ed2e 100644..100755
--- a/indra/llui/llsliderctrl.cpp
+++ b/indra/llui/llsliderctrl.cpp
diff --git a/indra/llui/llsliderctrl.h b/indra/llui/llsliderctrl.h
index 5153e33f49..5153e33f49 100644..100755
--- a/indra/llui/llsliderctrl.h
+++ b/indra/llui/llsliderctrl.h
diff --git a/indra/llui/llspellcheck.cpp b/indra/llui/llspellcheck.cpp
new file mode 100755
index 0000000000..250372da5b
--- /dev/null
+++ b/indra/llui/llspellcheck.cpp
@@ -0,0 +1,509 @@
+/**
+ * @file llspellcheck.cpp
+ * @brief Spell checking functionality
+ *
+ * $LicenseInfo:firstyear=2001&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 "lldir.h"
+#include "llsdserialize.h"
+
+#include "llspellcheck.h"
+#if LL_WINDOWS
+ #include <hunspell/hunspelldll.h>
+ #pragma comment(lib, "libhunspell.lib")
+#else
+ #include <hunspell/hunspell.hxx>
+#endif
+
+static const std::string DICT_DIR = "dictionaries";
+static const std::string DICT_FILE_CUSTOM = "user_custom.dic";
+static const std::string DICT_FILE_IGNORE = "user_ignore.dic";
+
+static const std::string DICT_FILE_MAIN = "dictionaries.xml";
+static const std::string DICT_FILE_USER = "user_dictionaries.xml";
+
+LLSD LLSpellChecker::sDictMap;
+LLSpellChecker::settings_change_signal_t LLSpellChecker::sSettingsChangeSignal;
+
+LLSpellChecker::LLSpellChecker()
+ : mHunspell(NULL)
+{
+ // Load initial dictionary information
+ refreshDictionaryMap();
+}
+
+LLSpellChecker::~LLSpellChecker()
+{
+ delete mHunspell;
+}
+
+bool LLSpellChecker::checkSpelling(const std::string& word) const
+{
+ if ( (!mHunspell) || (word.length() < 3) || (0 != mHunspell->spell(word.c_str())) )
+ {
+ return true;
+ }
+ if (mIgnoreList.size() > 0)
+ {
+ std::string word_lower(word);
+ LLStringUtil::toLower(word_lower);
+ return (mIgnoreList.end() != std::find(mIgnoreList.begin(), mIgnoreList.end(), word_lower));
+ }
+ return false;
+}
+
+S32 LLSpellChecker::getSuggestions(const std::string& word, std::vector<std::string>& suggestions) const
+{
+ suggestions.clear();
+ if ( (!mHunspell) || (word.length() < 3) )
+ {
+ return 0;
+ }
+
+ char** suggestion_list; int suggestion_cnt = 0;
+ if ( (suggestion_cnt = mHunspell->suggest(&suggestion_list, word.c_str())) != 0 )
+ {
+ for (int suggestion_index = 0; suggestion_index < suggestion_cnt; suggestion_index++)
+ {
+ suggestions.push_back(suggestion_list[suggestion_index]);
+ }
+ mHunspell->free_list(&suggestion_list, suggestion_cnt);
+ }
+ return suggestions.size();
+}
+
+// static
+const LLSD LLSpellChecker::getDictionaryData(const std::string& dict_language)
+{
+ for (LLSD::array_const_iterator it = sDictMap.beginArray(); it != sDictMap.endArray(); ++it)
+ {
+ const LLSD& dict_entry = *it;
+ if (dict_language == dict_entry["language"].asString())
+ {
+ return dict_entry;
+ }
+ }
+ return LLSD();
+}
+
+// static
+bool LLSpellChecker::hasDictionary(const std::string& dict_language, bool check_installed)
+{
+ const LLSD dict_info = getDictionaryData(dict_language);
+ return dict_info.has("language") && ( (!check_installed) || (dict_info["installed"].asBoolean()) );
+}
+
+// static
+void LLSpellChecker::setDictionaryData(const LLSD& dict_info)
+{
+ const std::string dict_language = dict_info["language"].asString();
+ if (dict_language.empty())
+ {
+ return;
+ }
+
+ for (LLSD::array_iterator it = sDictMap.beginArray(); it != sDictMap.endArray(); ++it)
+ {
+ LLSD& dict_entry = *it;
+ if (dict_language == dict_entry["language"].asString())
+ {
+ dict_entry = dict_info;
+ return;
+ }
+ }
+ sDictMap.append(dict_info);
+ return;
+}
+
+// static
+void LLSpellChecker::refreshDictionaryMap()
+{
+ const std::string app_path = getDictionaryAppPath();
+ const std::string user_path = getDictionaryUserPath();
+
+ // Load dictionary information (file name, friendly name, ...)
+ llifstream user_file(user_path + DICT_FILE_MAIN, std::ios::binary);
+ if ( (!user_file.is_open())
+ || (LLSDParser::PARSE_FAILURE == LLSDSerialize::fromXMLDocument(sDictMap, user_file))
+ || (0 == sDictMap.size()) )
+ {
+ llifstream app_file(app_path + DICT_FILE_MAIN, std::ios::binary);
+ if ( (!app_file.is_open())
+ || (LLSDParser::PARSE_FAILURE == LLSDSerialize::fromXMLDocument(sDictMap, app_file))
+ || (0 == sDictMap.size()) )
+ {
+ return;
+ }
+ }
+
+ // Load user installed dictionary information
+ llifstream custom_file(user_path + DICT_FILE_USER, std::ios::binary);
+ if (custom_file.is_open())
+ {
+ LLSD custom_dict_map;
+ LLSDSerialize::fromXMLDocument(custom_dict_map, custom_file);
+ for (LLSD::array_iterator it = custom_dict_map.beginArray(); it != custom_dict_map.endArray(); ++it)
+ {
+ LLSD& dict_info = *it;
+ dict_info["user_installed"] = true;
+ setDictionaryData(dict_info);
+ }
+ custom_file.close();
+ }
+
+ // Look for installed dictionaries
+ std::string tmp_app_path, tmp_user_path;
+ for (LLSD::array_iterator it = sDictMap.beginArray(); it != sDictMap.endArray(); ++it)
+ {
+ LLSD& sdDict = *it;
+ tmp_app_path = (sdDict.has("name")) ? app_path + sdDict["name"].asString() : LLStringUtil::null;
+ tmp_user_path = (sdDict.has("name")) ? user_path + sdDict["name"].asString() : LLStringUtil::null;
+ sdDict["installed"] =
+ (!tmp_app_path.empty()) && ((gDirUtilp->fileExists(tmp_user_path + ".dic")) || (gDirUtilp->fileExists(tmp_app_path + ".dic")));
+ }
+
+ sSettingsChangeSignal();
+}
+
+void LLSpellChecker::addToCustomDictionary(const std::string& word)
+{
+ if (mHunspell)
+ {
+ mHunspell->add(word.c_str());
+ }
+ addToDictFile(getDictionaryUserPath() + DICT_FILE_CUSTOM, word);
+ sSettingsChangeSignal();
+}
+
+void LLSpellChecker::addToIgnoreList(const std::string& word)
+{
+ std::string word_lower(word);
+ LLStringUtil::toLower(word_lower);
+ if (mIgnoreList.end() == std::find(mIgnoreList.begin(), mIgnoreList.end(), word_lower))
+ {
+ mIgnoreList.push_back(word_lower);
+ addToDictFile(getDictionaryUserPath() + DICT_FILE_IGNORE, word_lower);
+ sSettingsChangeSignal();
+ }
+}
+
+void LLSpellChecker::addToDictFile(const std::string& dict_path, const std::string& word)
+{
+ std::vector<std::string> word_list;
+
+ if (gDirUtilp->fileExists(dict_path))
+ {
+ llifstream file_in(dict_path, std::ios::in);
+ if (file_in.is_open())
+ {
+ std::string word; int line_num = 0;
+ while (getline(file_in, word))
+ {
+ // Skip over the first line since that's just a line count
+ if (0 != line_num)
+ {
+ word_list.push_back(word);
+ }
+ line_num++;
+ }
+ }
+ else
+ {
+ // TODO: show error message?
+ return;
+ }
+ }
+
+ word_list.push_back(word);
+
+ llofstream file_out(dict_path, std::ios::out | std::ios::trunc);
+ if (file_out.is_open())
+ {
+ file_out << word_list.size() << std::endl;
+ for (std::vector<std::string>::const_iterator itWord = word_list.begin(); itWord != word_list.end(); ++itWord)
+ {
+ file_out << *itWord << std::endl;
+ }
+ file_out.close();
+ }
+}
+
+bool LLSpellChecker::isActiveDictionary(const std::string& dict_language) const
+{
+ return
+ (mDictLanguage == dict_language) ||
+ (mDictSecondary.end() != std::find(mDictSecondary.begin(), mDictSecondary.end(), dict_language));
+}
+
+void LLSpellChecker::setSecondaryDictionaries(dict_list_t dict_list)
+{
+ if (!getUseSpellCheck())
+ {
+ return;
+ }
+
+ // Check if we're only adding secondary dictionaries, or removing them
+ dict_list_t dict_add(llmax(dict_list.size(), mDictSecondary.size())), dict_rem(llmax(dict_list.size(), mDictSecondary.size()));
+ dict_list.sort();
+ mDictSecondary.sort();
+ dict_list_t::iterator end_added = std::set_difference(dict_list.begin(), dict_list.end(), mDictSecondary.begin(), mDictSecondary.end(), dict_add.begin());
+ dict_list_t::iterator end_removed = std::set_difference(mDictSecondary.begin(), mDictSecondary.end(), dict_list.begin(), dict_list.end(), dict_rem.begin());
+
+ if (end_removed != dict_rem.begin()) // We can't remove secondary dictionaries so we need to recreate the Hunspell instance
+ {
+ mDictSecondary = dict_list;
+
+ std::string dict_language = mDictLanguage;
+ initHunspell(dict_language);
+ }
+ else if (end_added != dict_add.begin()) // Add the new secondary dictionaries one by one
+ {
+ const std::string app_path = getDictionaryAppPath();
+ const std::string user_path = getDictionaryUserPath();
+ for (dict_list_t::const_iterator it_added = dict_add.begin(); it_added != end_added; ++it_added)
+ {
+ const LLSD dict_entry = getDictionaryData(*it_added);
+ if ( (!dict_entry.isDefined()) || (!dict_entry["installed"].asBoolean()) )
+ {
+ continue;
+ }
+
+ const std::string strFileDic = dict_entry["name"].asString() + ".dic";
+ if (gDirUtilp->fileExists(user_path + strFileDic))
+ {
+ mHunspell->add_dic((user_path + strFileDic).c_str());
+ }
+ else if (gDirUtilp->fileExists(app_path + strFileDic))
+ {
+ mHunspell->add_dic((app_path + strFileDic).c_str());
+ }
+ }
+ mDictSecondary = dict_list;
+ sSettingsChangeSignal();
+ }
+}
+
+void LLSpellChecker::initHunspell(const std::string& dict_language)
+{
+ if (mHunspell)
+ {
+ delete mHunspell;
+ mHunspell = NULL;
+ mDictLanguage.clear();
+ mDictFile.clear();
+ mIgnoreList.clear();
+ }
+
+ const LLSD dict_entry = (!dict_language.empty()) ? getDictionaryData(dict_language) : LLSD();
+ if ( (!dict_entry.isDefined()) || (!dict_entry["installed"].asBoolean()) || (!dict_entry["is_primary"].asBoolean()))
+ {
+ sSettingsChangeSignal();
+ return;
+ }
+
+ const std::string app_path = getDictionaryAppPath();
+ const std::string user_path = getDictionaryUserPath();
+ if (dict_entry.has("name"))
+ {
+ const std::string filename_aff = dict_entry["name"].asString() + ".aff";
+ const std::string filename_dic = dict_entry["name"].asString() + ".dic";
+ if ( (gDirUtilp->fileExists(user_path + filename_aff)) && (gDirUtilp->fileExists(user_path + filename_dic)) )
+ {
+ mHunspell = new Hunspell((user_path + filename_aff).c_str(), (user_path + filename_dic).c_str());
+ }
+ else if ( (gDirUtilp->fileExists(app_path + filename_aff)) && (gDirUtilp->fileExists(app_path + filename_dic)) )
+ {
+ mHunspell = new Hunspell((app_path + filename_aff).c_str(), (app_path + filename_dic).c_str());
+ }
+ if (!mHunspell)
+ {
+ return;
+ }
+
+ mDictLanguage = dict_language;
+ mDictFile = dict_entry["name"].asString();
+
+ if (gDirUtilp->fileExists(user_path + DICT_FILE_CUSTOM))
+ {
+ mHunspell->add_dic((user_path + DICT_FILE_CUSTOM).c_str());
+ }
+
+ if (gDirUtilp->fileExists(user_path + DICT_FILE_IGNORE))
+ {
+ llifstream file_in(user_path + DICT_FILE_IGNORE, std::ios::in);
+ if (file_in.is_open())
+ {
+ std::string word; int idxLine = 0;
+ while (getline(file_in, word))
+ {
+ // Skip over the first line since that's just a line count
+ if (0 != idxLine)
+ {
+ LLStringUtil::toLower(word);
+ mIgnoreList.push_back(word);
+ }
+ idxLine++;
+ }
+ }
+ }
+
+ for (dict_list_t::const_iterator it = mDictSecondary.begin(); it != mDictSecondary.end(); ++it)
+ {
+ const LLSD dict_entry = getDictionaryData(*it);
+ if ( (!dict_entry.isDefined()) || (!dict_entry["installed"].asBoolean()) )
+ {
+ continue;
+ }
+
+ const std::string filename_dic = dict_entry["name"].asString() + ".dic";
+ if (gDirUtilp->fileExists(user_path + filename_dic))
+ {
+ mHunspell->add_dic((user_path + filename_dic).c_str());
+ }
+ else if (gDirUtilp->fileExists(app_path + filename_dic))
+ {
+ mHunspell->add_dic((app_path + filename_dic).c_str());
+ }
+ }
+ }
+
+ sSettingsChangeSignal();
+}
+
+// static
+const std::string LLSpellChecker::getDictionaryAppPath()
+{
+ std::string dict_path = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, DICT_DIR, "");
+ return dict_path;
+}
+
+// static
+const std::string LLSpellChecker::getDictionaryUserPath()
+{
+ std::string dict_path = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, DICT_DIR, "");
+ if (!gDirUtilp->fileExists(dict_path))
+ {
+ LLFile::mkdir(dict_path);
+ }
+ return dict_path;
+}
+
+// static
+bool LLSpellChecker::getUseSpellCheck()
+{
+ return (LLSpellChecker::instanceExists()) && (LLSpellChecker::instance().mHunspell);
+}
+
+// static
+bool LLSpellChecker::canRemoveDictionary(const std::string& dict_language)
+{
+ // Only user-installed inactive dictionaries can be removed
+ const LLSD dict_info = getDictionaryData(dict_language);
+ return
+ (dict_info["user_installed"].asBoolean()) &&
+ ( (!getUseSpellCheck()) || (!LLSpellChecker::instance().isActiveDictionary(dict_language)) );
+}
+
+// static
+void LLSpellChecker::removeDictionary(const std::string& dict_language)
+{
+ if (!canRemoveDictionary(dict_language))
+ {
+ return;
+ }
+
+ LLSD dict_map = loadUserDictionaryMap();
+ for (LLSD::array_const_iterator it = dict_map.beginArray(); it != dict_map.endArray(); ++it)
+ {
+ const LLSD& dict_info = *it;
+ if (dict_info["language"].asString() == dict_language)
+ {
+ const std::string dict_dic = getDictionaryUserPath() + dict_info["name"].asString() + ".dic";
+ if (gDirUtilp->fileExists(dict_dic))
+ {
+ LLFile::remove(dict_dic);
+ }
+ const std::string dict_aff = getDictionaryUserPath() + dict_info["name"].asString() + ".aff";
+ if (gDirUtilp->fileExists(dict_aff))
+ {
+ LLFile::remove(dict_aff);
+ }
+ dict_map.erase(it - dict_map.beginArray());
+ break;
+ }
+ }
+ saveUserDictionaryMap(dict_map);
+
+ refreshDictionaryMap();
+}
+
+// static
+LLSD LLSpellChecker::loadUserDictionaryMap()
+{
+ LLSD dict_map;
+ llifstream dict_file(getDictionaryUserPath() + DICT_FILE_USER, std::ios::binary);
+ if (dict_file.is_open())
+ {
+ LLSDSerialize::fromXMLDocument(dict_map, dict_file);
+ dict_file.close();
+ }
+ return dict_map;
+}
+
+// static
+void LLSpellChecker::saveUserDictionaryMap(const LLSD& dict_map)
+{
+ llofstream dict_file(getDictionaryUserPath() + DICT_FILE_USER, std::ios::trunc);
+ if (dict_file.is_open())
+ {
+ LLSDSerialize::toPrettyXML(dict_map, dict_file);
+ dict_file.close();
+ }
+}
+
+// static
+boost::signals2::connection LLSpellChecker::setSettingsChangeCallback(const settings_change_signal_t::slot_type& cb)
+{
+ return sSettingsChangeSignal.connect(cb);
+}
+
+// static
+void LLSpellChecker::setUseSpellCheck(const std::string& dict_language)
+{
+ if ( (((dict_language.empty()) && (getUseSpellCheck())) || (!dict_language.empty())) &&
+ (LLSpellChecker::instance().mDictLanguage != dict_language) )
+ {
+ LLSpellChecker::instance().initHunspell(dict_language);
+ }
+}
+
+// static
+void LLSpellChecker::initClass()
+{
+ if (sDictMap.isUndefined())
+ {
+ refreshDictionaryMap();
+ }
+}
diff --git a/indra/llui/llspellcheck.h b/indra/llui/llspellcheck.h
new file mode 100755
index 0000000000..4ab80195ea
--- /dev/null
+++ b/indra/llui/llspellcheck.h
@@ -0,0 +1,93 @@
+/**
+ * @file llspellcheck.h
+ * @brief Spell checking functionality
+ *
+ * $LicenseInfo:firstyear=2001&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$
+ */
+
+#ifndef LLSPELLCHECK_H
+#define LLSPELLCHECK_H
+
+#include "llsingleton.h"
+#include "llui.h"
+#include <boost/signals2.hpp>
+
+class Hunspell;
+
+class LLSpellChecker : public LLSingleton<LLSpellChecker>, public LLInitClass<LLSpellChecker>
+{
+ friend class LLSingleton<LLSpellChecker>;
+ friend class LLInitClass<LLSpellChecker>;
+protected:
+ LLSpellChecker();
+ ~LLSpellChecker();
+
+public:
+ void addToCustomDictionary(const std::string& word);
+ void addToIgnoreList(const std::string& word);
+ bool checkSpelling(const std::string& word) const;
+ S32 getSuggestions(const std::string& word, std::vector<std::string>& suggestions) const;
+protected:
+ void addToDictFile(const std::string& dict_path, const std::string& word);
+ void initHunspell(const std::string& dict_language);
+
+public:
+ typedef std::list<std::string> dict_list_t;
+
+ const std::string& getPrimaryDictionary() const { return mDictLanguage; }
+ const dict_list_t& getSecondaryDictionaries() const { return mDictSecondary; }
+ bool isActiveDictionary(const std::string& dict_language) const;
+ void setSecondaryDictionaries(dict_list_t dict_list);
+
+ static bool canRemoveDictionary(const std::string& dict_language);
+ static const std::string getDictionaryAppPath();
+ static const std::string getDictionaryUserPath();
+ static const LLSD getDictionaryData(const std::string& dict_language);
+ static const LLSD& getDictionaryMap() { return sDictMap; }
+ static bool getUseSpellCheck();
+ static bool hasDictionary(const std::string& dict_language, bool check_installed = false);
+ static void refreshDictionaryMap();
+ static void removeDictionary(const std::string& dict_language);
+ static void setUseSpellCheck(const std::string& dict_language);
+protected:
+ static LLSD loadUserDictionaryMap();
+ static void setDictionaryData(const LLSD& dict_info);
+ static void saveUserDictionaryMap(const LLSD& dict_map);
+
+public:
+ typedef boost::signals2::signal<void()> settings_change_signal_t;
+ static boost::signals2::connection setSettingsChangeCallback(const settings_change_signal_t::slot_type& cb);
+protected:
+ static void initClass();
+
+protected:
+ Hunspell* mHunspell;
+ std::string mDictLanguage;
+ std::string mDictFile;
+ dict_list_t mDictSecondary;
+ std::vector<std::string> mIgnoreList;
+
+ static LLSD sDictMap;
+ static settings_change_signal_t sSettingsChangeSignal;
+};
+
+#endif // LLSPELLCHECK_H
diff --git a/indra/llui/llspellcheckmenuhandler.h b/indra/llui/llspellcheckmenuhandler.h
new file mode 100755
index 0000000000..d5c95bad39
--- /dev/null
+++ b/indra/llui/llspellcheckmenuhandler.h
@@ -0,0 +1,46 @@
+/**
+ * @file llspellcheckmenuhandler.h
+ * @brief Interface used by spell check menu handling
+ *
+ * $LicenseInfo:firstyear=2001&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$
+ */
+
+#ifndef LLSPELLCHECKMENUHANDLER_H
+#define LLSPELLCHECKMENUHANDLER_H
+
+class LLSpellCheckMenuHandler
+{
+public:
+ virtual bool getSpellCheck() const { return false; }
+
+ virtual const std::string& getSuggestion(U32 index) const { return LLStringUtil::null; }
+ virtual U32 getSuggestionCount() const { return 0; }
+ virtual void replaceWithSuggestion(U32 index){}
+
+ virtual void addToDictionary() {}
+ virtual bool canAddToDictionary() const { return false; }
+
+ virtual void addToIgnore() {}
+ virtual bool canAddToIgnore() const { return false; }
+};
+
+#endif // LLSPELLCHECKMENUHANDLER_H
diff --git a/indra/llui/llspinctrl.cpp b/indra/llui/llspinctrl.cpp
index 934879cdfd..8a728df2e7 100644..100755
--- a/indra/llui/llspinctrl.cpp
+++ b/indra/llui/llspinctrl.cpp
@@ -52,6 +52,7 @@ LLSpinCtrl::Params::Params()
: label_width("label_width"),
decimal_digits("decimal_digits"),
allow_text_entry("allow_text_entry", true),
+ allow_digits_only("allow_digits_only", false),
label_wrap("label_wrap", false),
text_enabled_color("text_enabled_color"),
text_disabled_color("text_disabled_color"),
@@ -129,6 +130,10 @@ LLSpinCtrl::LLSpinCtrl(const LLSpinCtrl::Params& p)
params.follows.flags(FOLLOWS_LEFT | FOLLOWS_BOTTOM);
mEditor = LLUICtrlFactory::create<LLLineEditor> (params);
mEditor->setFocusReceivedCallback( boost::bind(&LLSpinCtrl::onEditorGainFocus, _1, this ));
+ if (p.allow_digits_only)
+ {
+ mEditor->setPrevalidateInput(LLTextValidate::validateNonNegativeS32NoSpace);
+ }
//RN: this seems to be a BAD IDEA, as it makes the editor behavior different when it has focus
// than when it doesn't. Instead, if you always have to double click to select all the text,
// it's easier to understand
diff --git a/indra/llui/llspinctrl.h b/indra/llui/llspinctrl.h
index 87814f838e..e34add879d 100644..100755
--- a/indra/llui/llspinctrl.h
+++ b/indra/llui/llspinctrl.h
@@ -44,6 +44,7 @@ public:
Optional<S32> label_width;
Optional<U32> decimal_digits;
Optional<bool> allow_text_entry;
+ Optional<bool> allow_digits_only;
Optional<bool> label_wrap;
Optional<LLUIColor> text_enabled_color;
diff --git a/indra/llui/llstatbar.cpp b/indra/llui/llstatbar.cpp
index ec4db14790..04cce7878e 100644..100755
--- a/indra/llui/llstatbar.cpp
+++ b/indra/llui/llstatbar.cpp
@@ -272,7 +272,7 @@ LLRect LLStatBar::getRequiredRect()
{
if (mDisplayHistory)
{
- rect.mTop = 67;
+ rect.mTop = 35 + mStatp->getNumBins();
}
else
{
diff --git a/indra/llui/llstatbar.h b/indra/llui/llstatbar.h
index 513fff3234..513fff3234 100644..100755
--- a/indra/llui/llstatbar.h
+++ b/indra/llui/llstatbar.h
diff --git a/indra/llui/llstatgraph.cpp b/indra/llui/llstatgraph.cpp
index e44887ebf0..e44887ebf0 100644..100755
--- a/indra/llui/llstatgraph.cpp
+++ b/indra/llui/llstatgraph.cpp
diff --git a/indra/llui/llstatgraph.h b/indra/llui/llstatgraph.h
index 757525e232..757525e232 100644..100755
--- a/indra/llui/llstatgraph.h
+++ b/indra/llui/llstatgraph.h
diff --git a/indra/llui/llstatview.cpp b/indra/llui/llstatview.cpp
index eda2d6047f..eda2d6047f 100644..100755
--- a/indra/llui/llstatview.cpp
+++ b/indra/llui/llstatview.cpp
diff --git a/indra/llui/llstatview.h b/indra/llui/llstatview.h
index 5abdc42448..5abdc42448 100644..100755
--- a/indra/llui/llstatview.h
+++ b/indra/llui/llstatview.h
diff --git a/indra/llui/llstyle.cpp b/indra/llui/llstyle.cpp
index bb731f4f7e..bb731f4f7e 100644..100755
--- a/indra/llui/llstyle.cpp
+++ b/indra/llui/llstyle.cpp
diff --git a/indra/llui/llstyle.h b/indra/llui/llstyle.h
index 9f1eba79d8..9f1eba79d8 100644..100755
--- a/indra/llui/llstyle.h
+++ b/indra/llui/llstyle.h
diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp
index 5fc2cc350d..6fd2bb1b36 100644..100755
--- a/indra/llui/lltabcontainer.cpp
+++ b/indra/llui/lltabcontainer.cpp
@@ -27,7 +27,7 @@
#include "linden_common.h"
#include "lltabcontainer.h"
-
+#include "llviewereventrecorder.h"
#include "llfocusmgr.h"
#include "lllocalcliprect.h"
#include "llrect.h"
@@ -193,12 +193,15 @@ LLTabContainer::TabParams::TabParams()
: tab_top_image_unselected("tab_top_image_unselected"),
tab_top_image_selected("tab_top_image_selected"),
tab_top_image_flash("tab_top_image_flash"),
+ tab_top_image_hovered("tab_top_image_hovered"),
tab_bottom_image_unselected("tab_bottom_image_unselected"),
tab_bottom_image_selected("tab_bottom_image_selected"),
tab_bottom_image_flash("tab_bottom_image_flash"),
+ tab_bottom_image_hovered("tab_bottom_image_hovered"),
tab_left_image_unselected("tab_left_image_unselected"),
tab_left_image_selected("tab_left_image_selected"),
- tab_left_image_flash("tab_left_image_flash")
+ tab_left_image_flash("tab_left_image_flash"),
+ tab_left_image_hovered("tab_left_image_hovered")
{}
LLTabContainer::Params::Params()
@@ -218,7 +221,8 @@ LLTabContainer::Params::Params()
open_tabs_on_drag_and_drop("open_tabs_on_drag_and_drop", false),
tab_icon_ctrl_pad("tab_icon_ctrl_pad", 0),
use_ellipses("use_ellipses"),
- font_halign("halign")
+ font_halign("halign"),
+ use_highlighting_on_hover("use_highlighting_on_hover",false)
{}
LLTabContainer::LLTabContainer(const LLTabContainer::Params& p)
@@ -254,7 +258,8 @@ LLTabContainer::LLTabContainer(const LLTabContainer::Params& p)
mCustomIconCtrlUsed(p.use_custom_icon_ctrl),
mOpenTabsOnDragAndDrop(p.open_tabs_on_drag_and_drop),
mTabIconCtrlPad(p.tab_icon_ctrl_pad),
- mUseTabEllipses(p.use_ellipses)
+ mUseTabEllipses(p.use_ellipses),
+ mUseHighlightingOnHover(p.use_highlighting_on_hover)
{
static LLUICachedControl<S32> tabcntr_vert_tab_min_width ("UITabCntrVertTabMinWidth", 0);
@@ -506,8 +511,8 @@ void LLTabContainer::draw()
}
}
- mPrevArrowBtn->setFlashing(FALSE);
- mNextArrowBtn->setFlashing(FALSE);
+ mPrevArrowBtn->setFlashing(false);
+ mNextArrowBtn->setFlashing(false);
}
@@ -578,6 +583,11 @@ BOOL LLTabContainer::handleMouseDown( S32 x, S32 y, MASK mask )
tab_button->setFocus(TRUE);
}
}
+ if (handled) {
+ // Note: May need to also capture local coords right here ?
+ LLViewerEventRecorder::instance().update_xui(getPathname( ));
+ }
+
return handled;
}
@@ -629,30 +639,33 @@ BOOL LLTabContainer::handleMouseUp( S32 x, S32 y, MASK mask )
BOOL handled = FALSE;
BOOL has_scroll_arrows = (getMaxScrollPos() > 0) && !getTabsHidden();
+ S32 local_x = x - getRect().mLeft;
+ S32 local_y = y - getRect().mBottom;
+
if (has_scroll_arrows)
{
if (mJumpPrevArrowBtn && mJumpPrevArrowBtn->getRect().pointInRect(x, y))
{
- S32 local_x = x - mJumpPrevArrowBtn->getRect().mLeft;
- S32 local_y = y - mJumpPrevArrowBtn->getRect().mBottom;
+ local_x = x - mJumpPrevArrowBtn->getRect().mLeft;
+ local_y = y - mJumpPrevArrowBtn->getRect().mBottom;
handled = mJumpPrevArrowBtn->handleMouseUp(local_x, local_y, mask);
}
else if (mJumpNextArrowBtn && mJumpNextArrowBtn->getRect().pointInRect(x, y))
{
- S32 local_x = x - mJumpNextArrowBtn->getRect().mLeft;
- S32 local_y = y - mJumpNextArrowBtn->getRect().mBottom;
+ local_x = x - mJumpNextArrowBtn->getRect().mLeft;
+ local_y = y - mJumpNextArrowBtn->getRect().mBottom;
handled = mJumpNextArrowBtn->handleMouseUp(local_x, local_y, mask);
}
else if (mPrevArrowBtn && mPrevArrowBtn->getRect().pointInRect(x, y))
{
- S32 local_x = x - mPrevArrowBtn->getRect().mLeft;
- S32 local_y = y - mPrevArrowBtn->getRect().mBottom;
+ local_x = x - mPrevArrowBtn->getRect().mLeft;
+ local_y = y - mPrevArrowBtn->getRect().mBottom;
handled = mPrevArrowBtn->handleMouseUp(local_x, local_y, mask);
}
else if (mNextArrowBtn && mNextArrowBtn->getRect().pointInRect(x, y))
{
- S32 local_x = x - mNextArrowBtn->getRect().mLeft;
- S32 local_y = y - mNextArrowBtn->getRect().mBottom;
+ local_x = x - mNextArrowBtn->getRect().mLeft;
+ local_y = y - mNextArrowBtn->getRect().mBottom;
handled = mNextArrowBtn->handleMouseUp(local_x, local_y, mask);
}
}
@@ -676,6 +689,10 @@ BOOL LLTabContainer::handleMouseUp( S32 x, S32 y, MASK mask )
}
gFocusMgr.setMouseCapture(NULL);
}
+ if (handled) {
+ // Note: may need to capture local coords here
+ LLViewerEventRecorder::instance().update_xui(getPathname( ));
+ }
return handled;
}
@@ -891,18 +908,30 @@ void LLTabContainer::update_images(LLTabTuple* tuple, TabParams params, LLTabCon
tuple->mButton->setImageUnselected(static_cast<LLUIImage*>(params.tab_top_image_unselected));
tuple->mButton->setImageSelected(static_cast<LLUIImage*>(params.tab_top_image_selected));
tuple->mButton->setImageFlash(static_cast<LLUIImage*>(params.tab_top_image_flash));
+ if(mUseHighlightingOnHover)
+ {
+ tuple->mButton->setImageHoverUnselected(static_cast<LLUIImage*>(params.tab_top_image_hovered));
+ }
}
else if (pos == LLTabContainer::BOTTOM)
{
tuple->mButton->setImageUnselected(static_cast<LLUIImage*>(params.tab_bottom_image_unselected));
tuple->mButton->setImageSelected(static_cast<LLUIImage*>(params.tab_bottom_image_selected));
tuple->mButton->setImageFlash(static_cast<LLUIImage*>(params.tab_bottom_image_flash));
+ if(mUseHighlightingOnHover)
+ {
+ tuple->mButton->setImageHoverUnselected(static_cast<LLUIImage*>(params.tab_bottom_image_hovered));
+ }
}
else if (pos == LLTabContainer::LEFT)
{
tuple->mButton->setImageUnselected(static_cast<LLUIImage*>(params.tab_left_image_unselected));
tuple->mButton->setImageSelected(static_cast<LLUIImage*>(params.tab_left_image_selected));
tuple->mButton->setImageFlash(static_cast<LLUIImage*>(params.tab_left_image_flash));
+ if(mUseHighlightingOnHover)
+ {
+ tuple->mButton->setImageHoverUnselected(static_cast<LLUIImage*>(params.tab_left_image_hovered));
+ }
}
}
}
@@ -1059,21 +1088,21 @@ void LLTabContainer::addTabPanel(const TabPanelParams& panel)
if (mIsVertical)
{
- p.name(std::string("vert tab button"));
- p.image_unselected(mMiddleTabParams.tab_left_image_unselected);
- p.image_selected(mMiddleTabParams.tab_left_image_selected);
- p.follows.flags = p.follows.flags() | FOLLOWS_TOP;
+ p.name("vtab_"+std::string(child->getName()));
+ p.image_unselected(mMiddleTabParams.tab_left_image_unselected);
+ p.image_selected(mMiddleTabParams.tab_left_image_selected);
+ p.follows.flags = p.follows.flags() | FOLLOWS_TOP;
}
else
- {
- p.name(std::string(child->getName()) + " tab");
- p.visible(false);
- p.image_unselected(tab_img);
- p.image_selected(tab_selected_img);
- p.follows.flags = p.follows.flags() | (getTabPosition() == TOP ? FOLLOWS_TOP : FOLLOWS_BOTTOM);
- // Try to squeeze in a bit more text
- p.pad_left( mLabelPadLeft );
- p.pad_right(2);
+ {
+ p.name("htab_"+std::string(child->getName()));
+ p.visible(false);
+ p.image_unselected(tab_img);
+ p.image_selected(tab_selected_img);
+ p.follows.flags = p.follows.flags() | (getTabPosition() == TOP ? FOLLOWS_TOP : FOLLOWS_BOTTOM);
+ // Try to squeeze in a bit more text
+ p.pad_left( mLabelPadLeft );
+ p.pad_right(2);
}
// *TODO : It seems wrong not to use p in both cases considering the way p is initialized
@@ -1209,11 +1238,17 @@ void LLTabContainer::removeTabPanel(LLPanel* child)
update_images(mTabList[mTabList.size()-2], mLastTabParams, getTabPosition());
}
- removeChild( tuple->mButton );
+ if (!getTabsHidden())
+ {
+ // We need to remove tab buttons only if the tabs are not hidden.
+ removeChild( tuple->mButton );
+ }
delete tuple->mButton;
+ tuple->mButton = NULL;
removeChild( tuple->mTabPanel );
// delete tuple->mTabPanel;
+ tuple->mTabPanel = NULL;
mTabList.erase( iter );
delete tuple;
@@ -1275,9 +1310,11 @@ void LLTabContainer::deleteAllTabs()
removeChild( tuple->mButton );
delete tuple->mButton;
+ tuple->mButton = NULL;
removeChild( tuple->mTabPanel );
// delete tuple->mTabPanel;
+ tuple->mTabPanel = NULL;
}
// Actually delete the tuples themselves
@@ -1480,13 +1517,20 @@ BOOL LLTabContainer::setTab(S32 which)
{
LLTabTuple* tuple = *iter;
BOOL is_selected = ( tuple == selected_tuple );
- tuple->mButton->setUseEllipses(mUseTabEllipses);
- tuple->mButton->setHAlign(mFontHalign);
- tuple->mTabPanel->setVisible( is_selected );
-// tuple->mTabPanel->setFocus(is_selected); // not clear that we want to do this here.
- tuple->mButton->setToggleState( is_selected );
- // RN: this limits tab-stops to active button only, which would require arrow keys to switch tabs
- tuple->mButton->setTabStop( is_selected );
+ // Although the selected tab must be complete, we may have hollow LLTabTuple tucked in the list
+ if (tuple && tuple->mButton)
+ {
+ tuple->mButton->setUseEllipses(mUseTabEllipses);
+ tuple->mButton->setHAlign(mFontHalign);
+ tuple->mButton->setToggleState( is_selected );
+ // RN: this limits tab-stops to active button only, which would require arrow keys to switch tabs
+ tuple->mButton->setTabStop( is_selected );
+ }
+ if (tuple && tuple->mTabPanel)
+ {
+ tuple->mTabPanel->setVisible( is_selected );
+ //tuple->mTabPanel->setFocus(is_selected); // not clear that we want to do this here.
+ }
if (is_selected)
{
@@ -1513,7 +1557,7 @@ BOOL LLTabContainer::setTab(S32 which)
else
{
S32 available_width_with_arrows = getRect().getWidth() - mRightTabBtnOffset - 2 * (LLPANEL_BORDER_WIDTH + tabcntr_arrow_btn_size + tabcntr_arrow_btn_size + 1);
- S32 running_tab_width = tuple->mButton->getRect().getWidth();
+ S32 running_tab_width = (tuple && tuple->mButton ? tuple->mButton->getRect().getWidth() : 0);
S32 j = i - 1;
S32 min_scroll_pos = i;
if (running_tab_width < available_width_with_arrows)
@@ -1521,7 +1565,7 @@ BOOL LLTabContainer::setTab(S32 which)
while (j >= 0)
{
LLTabTuple* other_tuple = getTab(j);
- running_tab_width += other_tuple->mButton->getRect().getWidth();
+ running_tab_width += (other_tuple && other_tuple->mButton ? other_tuple->mButton->getRect().getWidth() : 0);
if (running_tab_width > available_width_with_arrows)
{
break;
@@ -1557,8 +1601,7 @@ BOOL LLTabContainer::selectTabByName(const std::string& name)
LLPanel* panel = getPanelByName(name);
if (!panel)
{
- llwarns << "LLTabContainer::selectTabByName("
- << name << ") failed" << llendl;
+ llwarns << "LLTabContainer::selectTabByName(" << name << ") failed" << llendl;
return FALSE;
}
diff --git a/indra/llui/lltabcontainer.h b/indra/llui/lltabcontainer.h
index cebace2ceb..7e7d4ac6e6 100644..100755
--- a/indra/llui/lltabcontainer.h
+++ b/indra/llui/lltabcontainer.h
@@ -62,12 +62,15 @@ public:
Optional<LLUIImage*> tab_top_image_unselected,
tab_top_image_selected,
tab_top_image_flash,
+ tab_top_image_hovered,
tab_bottom_image_unselected,
tab_bottom_image_selected,
tab_bottom_image_flash,
+ tab_bottom_image_hovered,
tab_left_image_unselected,
tab_left_image_selected,
- tab_left_image_flash;
+ tab_left_image_flash,
+ tab_left_image_hovered;
TabParams();
};
@@ -114,6 +117,11 @@ public:
*/
Optional<S32> tab_icon_ctrl_pad;
+ /**
+ * This variable is used to found out should we highlight tab button on hover
+ */
+ Optional<bool> use_highlighting_on_hover;
+
Params();
};
@@ -188,10 +196,11 @@ public:
void selectFirstTab();
void selectLastTab();
void selectNextTab();
- void selectPrevTab();
+ void selectPrevTab();
BOOL selectTabPanel( LLPanel* child );
BOOL selectTab(S32 which);
BOOL selectTabByName(const std::string& title);
+ void setCurrentPanelIndex(S32 index) { mCurrentTabIdx = index; }
BOOL getTabPanelFlashing(LLPanel* child);
void setTabPanelFlashing(LLPanel* child, BOOL state);
@@ -242,8 +251,6 @@ private:
void setTabsHidden(BOOL hidden) { mTabsHidden = hidden; }
BOOL getTabsHidden() const { return mTabsHidden; }
-
- void setCurrentPanelIndex(S32 index) { mCurrentTabIdx = index; }
void scrollPrev() { mScrollPos = llmax(0, mScrollPos-1); } // No wrap
void scrollNext() { mScrollPos = llmin(mScrollPos+1, mMaxScrollPos); } // No wrap
@@ -308,6 +315,7 @@ private:
bool mOpenTabsOnDragAndDrop;
S32 mTabIconCtrlPad;
bool mUseTabEllipses;
+ bool mUseHighlightingOnHover;
};
#endif // LL_TABCONTAINER_H
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index 7aeeae298f..5ec4cf4fe5 100644..100755
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -32,6 +32,7 @@
#include "lllocalcliprect.h"
#include "llmenugl.h"
#include "llscrollcontainer.h"
+#include "llspellcheck.h"
#include "llstl.h"
#include "lltextparser.h"
#include "lltextutil.h"
@@ -45,6 +46,7 @@
const F32 CURSOR_FLASH_DELAY = 1.0f; // in seconds
const S32 CURSOR_THICKNESS = 2;
+const F32 TRIPLE_CLICK_INTERVAL = 0.3f; // delay between double and triple click.
LLTextBase::line_info::line_info(S32 index_start, S32 index_end, LLRect rect, S32 line_num)
: mDocIndexStart(index_start),
@@ -144,6 +146,7 @@ LLTextBase::Params::Params()
: cursor_color("cursor_color"),
text_color("text_color"),
text_readonly_color("text_readonly_color"),
+ text_tentative_color("text_tentative_color"),
bg_visible("bg_visible", false),
border_visible("border_visible", false),
bg_readonly_color("bg_readonly_color"),
@@ -155,6 +158,7 @@ LLTextBase::Params::Params()
plain_text("plain_text",false),
track_end("track_end", false),
read_only("read_only", false),
+ spellcheck("spellcheck", false),
v_pad("v_pad", 0),
h_pad("h_pad", 0),
clip("clip", true),
@@ -176,15 +180,20 @@ LLTextBase::Params::Params()
LLTextBase::LLTextBase(const LLTextBase::Params &p)
: LLUICtrl(p, LLTextViewModelPtr(new LLTextViewModel)),
mURLClickSignal(NULL),
+ mIsFriendSignal(NULL),
mMaxTextByteLength( p.max_text_length ),
- mDefaultFont(p.font),
+ mFont(p.font),
mFontShadow(p.font_shadow),
mPopupMenu(NULL),
mReadOnly(p.read_only),
+ mSpellCheck(p.spellcheck),
+ mSpellCheckStart(-1),
+ mSpellCheckEnd(-1),
mCursorColor(p.cursor_color),
mFgColor(p.text_color),
mBorderVisible( p.border_visible ),
mReadOnlyFgColor(p.text_readonly_color),
+ mTentativeFgColor(p.text_tentative_color()),
mWriteableBgColor(p.bg_writeable_color),
mReadOnlyBgColor(p.bg_readonly_color),
mFocusBgColor(p.bg_focus_color),
@@ -246,6 +255,12 @@ LLTextBase::LLTextBase(const LLTextBase::Params &p)
addChild(mDocumentView);
}
+ if (mSpellCheck)
+ {
+ LLSpellChecker::setSettingsChangeCallback(boost::bind(&LLTextBase::onSpellCheckSettingsChange, this));
+ }
+ mSpellCheckTimer.reset();
+
createDefaultSegment();
updateRects();
@@ -280,12 +295,23 @@ bool LLTextBase::truncate()
if (getLength() >= S32(mMaxTextByteLength / 4))
{
// Have to check actual byte size
- LLWString text(getWText());
- S32 utf8_byte_size = wstring_utf8_length(text);
+ S32 utf8_byte_size = 0;
+ LLSD value = getViewModel()->getValue();
+ if (value.type() == LLSD::TypeString)
+ {
+ // save a copy for strings.
+ utf8_byte_size = value.size();
+ }
+ else
+ {
+ // non string LLSDs need explicit conversion to string
+ utf8_byte_size = value.asString().size();
+ }
+
if ( utf8_byte_size > mMaxTextByteLength )
{
// Truncate safely in UTF-8
- std::string temp_utf8_text = wstring_to_utf8str(text);
+ std::string temp_utf8_text = value.asString();
temp_utf8_text = utf8str_truncate( temp_utf8_text, mMaxTextByteLength );
LLWString text = utf8str_to_wstring( temp_utf8_text );
// remove extra bit of current string, to preserve formatting, etc.
@@ -297,21 +323,26 @@ bool LLTextBase::truncate()
return did_truncate;
}
-const LLStyle::Params& LLTextBase::getDefaultStyleParams()
+const LLStyle::Params& LLTextBase::getStyleParams()
{
//FIXME: convert mDefaultStyle to a flyweight http://www.boost.org/doc/libs/1_40_0/libs/flyweight/doc/index.html
//and eliminate color member values
if (mStyleDirty)
{
- mDefaultStyle
+ mStyle
.color(LLUIColor(&mFgColor)) // pass linked color instead of copy of mFGColor
.readonly_color(LLUIColor(&mReadOnlyFgColor))
.selected_color(LLUIColor(&mTextSelectedColor))
- .font(mDefaultFont)
+ .font(mFont)
.drop_shadow(mFontShadow);
mStyleDirty = false;
}
- return mDefaultStyle;
+ return mStyle;
+}
+
+void LLTextBase::beforeValueChange()
+{
+
}
void LLTextBase::onValueChange(S32 start, S32 end)
@@ -329,7 +360,6 @@ void LLTextBase::drawSelectionBackground()
S32 selection_left = llmin( mSelectionStart, mSelectionEnd );
S32 selection_right = llmax( mSelectionStart, mSelectionEnd );
- LLRect selection_rect = mVisibleTextRect;
// Skip through the lines we aren't drawing.
LLRect content_display_rect = getVisibleDocumentRect();
@@ -414,6 +444,7 @@ void LLTextBase::drawSelectionBackground()
++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);
}
@@ -491,8 +522,8 @@ void LLTextBase::drawCursor()
LLRect screen_pos = calcScreenRect();
LLCoordGL ime_pos( screen_pos.mLeft + llfloor(cursor_rect.mLeft), screen_pos.mBottom + llfloor(cursor_rect.mTop) );
- ime_pos.mX = (S32) (ime_pos.mX * LLUI::sGLScaleFactor.mV[VX]);
- ime_pos.mY = (S32) (ime_pos.mY * LLUI::sGLScaleFactor.mV[VY]);
+ ime_pos.mX = (S32) (ime_pos.mX * LLUI::getScaleFactor().mV[VX]);
+ ime_pos.mY = (S32) (ime_pos.mY * LLUI::getScaleFactor().mV[VY]);
getWindow()->setLanguageTextInput( ime_pos );
}
}
@@ -500,11 +531,17 @@ void LLTextBase::drawCursor()
void LLTextBase::drawText()
{
- const S32 text_len = getLength();
- if( text_len <= 0 )
+ S32 text_len = getLength();
+
+ if (text_len <= 0 && mLabel.empty())
{
return;
}
+ else if (useLabel())
+ {
+ text_len = mLabel.getWString().length();
+ }
+
S32 selection_left = -1;
S32 selection_right = -1;
// Draw selection even if we don't have keyboard focus for search/replace
@@ -530,8 +567,101 @@ void LLTextBase::drawText()
return;
}
+ // Perform spell check if needed
+ if ( (getSpellCheck()) && (getWText().length() > 2) )
+ {
+ // Calculate start and end indices for the spell checking range
+ S32 start = line_start, end = getLineEnd(last_line);
+
+ if ( (mSpellCheckStart != start) || (mSpellCheckEnd != end) )
+ {
+ const LLWString& wstrText = getWText();
+ mMisspellRanges.clear();
+
+ segment_set_t::const_iterator seg_it = getSegIterContaining(start);
+ while (mSegments.end() != seg_it)
+ {
+ LLTextSegmentPtr text_segment = *seg_it;
+ if ( (text_segment.isNull()) || (text_segment->getStart() >= end) )
+ {
+ break;
+ }
+
+ if (!text_segment->canEdit())
+ {
+ ++seg_it;
+ continue;
+ }
+
+ // Combine adjoining text segments into one
+ U32 seg_start = text_segment->getStart(), seg_end = llmin(text_segment->getEnd(), end);
+ while (mSegments.end() != ++seg_it)
+ {
+ text_segment = *seg_it;
+ if ( (text_segment.isNull()) || (!text_segment->canEdit()) || (text_segment->getStart() >= end) )
+ {
+ break;
+ }
+ seg_end = llmin(text_segment->getEnd(), end);
+ }
+
+ // Find the start of the first word
+ U32 word_start = seg_start, word_end = -1;
+ U32 text_length = wstrText.length();
+ while ( (word_start < text_length) && (!LLStringOps::isAlpha(wstrText[word_start])) )
+ {
+ word_start++;
+ }
+
+ // Iterate over all words in the text block and check them one by one
+ while (word_start < seg_end)
+ {
+ // Find the end of the current word (special case handling for "'" when it's used as a contraction)
+ word_end = word_start + 1;
+ while ( (word_end < seg_end) &&
+ ((LLWStringUtil::isPartOfWord(wstrText[word_end])) ||
+ ((L'\'' == wstrText[word_end]) &&
+ (LLStringOps::isAlnum(wstrText[word_end - 1])) && (LLStringOps::isAlnum(wstrText[word_end + 1])))) )
+ {
+ word_end++;
+ }
+ if (word_end > seg_end)
+ {
+ break;
+ }
+
+ if (word_start < text_length && word_end <= text_length && word_end > word_start)
+ {
+ std::string word = wstring_to_utf8str(wstrText.substr(word_start, word_end - word_start));
+
+ // Don't process words shorter than 3 characters
+ if ( (word.length() >= 3) && (!LLSpellChecker::instance().checkSpelling(word)) )
+ {
+ mMisspellRanges.push_back(std::pair<U32, U32>(word_start, word_end));
+ }
+ }
+
+ // Find the start of the next word
+ word_start = word_end + 1;
+ while ( (word_start < seg_end) && (!LLWStringUtil::isPartOfWord(wstrText[word_start])) )
+ {
+ word_start++;
+ }
+ }
+ }
+
+ mSpellCheckStart = start;
+ mSpellCheckEnd = end;
+ }
+ }
+ else
+ {
+ mMisspellRanges.clear();
+ }
+
LLTextSegmentPtr cur_segment = *seg_iter;
+ std::list<std::pair<U32, U32> >::const_iterator misspell_it = std::lower_bound(mMisspellRanges.begin(), mMisspellRanges.end(), std::pair<U32, U32>(line_start, 0));
for (S32 cur_line = first_line; cur_line < last_line; cur_line++)
{
S32 next_line = cur_line + 1;
@@ -566,7 +696,8 @@ void LLTextBase::drawText()
cur_segment = *seg_iter;
}
- S32 clipped_end = llmin( line_end, cur_segment->getEnd() ) - cur_segment->getStart();
+ S32 seg_end = llmin(line_end, cur_segment->getEnd());
+ S32 clipped_end = seg_end - cur_segment->getStart();
if (mUseEllipses // using ellipses
&& clipped_end == line_end // last segment on line
@@ -578,6 +709,46 @@ void LLTextBase::drawText()
text_rect.mRight -= 2;
}
+ // Draw squiggly lines under any visible misspelled words
+ while ( (mMisspellRanges.end() != misspell_it) && (misspell_it->first < seg_end) && (misspell_it->second > seg_start) )
+ {
+ // Skip the current word if the user is still busy editing it
+ if ( (!mSpellCheckTimer.hasExpired()) && (misspell_it->first <= (U32)mCursorPos) && (misspell_it->second >= (U32)mCursorPos) )
+ {
+ ++misspell_it;
+ continue;
+ }
+
+ U32 misspell_start = llmax<U32>(misspell_it->first, seg_start), misspell_end = llmin<U32>(misspell_it->second, seg_end);
+ S32 squiggle_start = 0, squiggle_end = 0, pony = 0;
+ cur_segment->getDimensions(seg_start - cur_segment->getStart(), misspell_start - seg_start, squiggle_start, pony);
+ cur_segment->getDimensions(misspell_start - cur_segment->getStart(), misspell_end - misspell_start, squiggle_end, pony);
+ squiggle_start += text_rect.mLeft;
+
+ pony = (squiggle_end + 3) / 6;
+ squiggle_start += squiggle_end / 2 - pony * 3;
+ squiggle_end = squiggle_start + pony * 6;
+
+ S32 squiggle_bottom = text_rect.mBottom + (S32)cur_segment->getStyle()->getFont()->getDescenderHeight();
+
+ gGL.color4ub(255, 0, 0, 200);
+ while (squiggle_start + 1 < squiggle_end)
+ {
+ gl_line_2d(squiggle_start, squiggle_bottom, squiggle_start + 2, squiggle_bottom - 2);
+ if (squiggle_start + 3 < squiggle_end)
+ {
+ gl_line_2d(squiggle_start + 2, squiggle_bottom - 3, squiggle_start + 4, squiggle_bottom - 1);
+ }
+ squiggle_start += 4;
+ }
+
+ if (misspell_it->second > seg_end)
+ {
+ break;
+ }
+ ++misspell_it;
+ }
+
text_rect.mLeft = (S32)(cur_segment->draw(seg_start - cur_segment->getStart(), clipped_end, selection_left, selection_right, text_rect));
seg_start = clipped_end + cur_segment->getStart();
@@ -592,8 +763,9 @@ void LLTextBase::drawText()
S32 LLTextBase::insertStringNoUndo(S32 pos, const LLWString &wstr, LLTextBase::segment_vec_t* segments )
{
- LLWString text(getWText());
- S32 old_len = text.length(); // length() returns character length
+ beforeValueChange();
+
+ S32 old_len = getLength(); // length() returns character length
S32 insert_len = wstr.length();
pos = getEditableIndex(pos, true);
@@ -624,7 +796,7 @@ S32 LLTextBase::insertStringNoUndo(S32 pos, const LLWString &wstr, LLTextBase::s
else
{
// create default editable segment to hold new text
- LLStyleConstSP sp(new LLStyle(getDefaultStyleParams()));
+ LLStyleConstSP sp(new LLStyle(getStyleParams()));
default_segment = new LLNormalTextSegment( sp, pos, pos + insert_len, *this);
}
@@ -653,8 +825,7 @@ S32 LLTextBase::insertStringNoUndo(S32 pos, const LLWString &wstr, LLTextBase::s
}
}
- text.insert(pos, wstr);
- getViewModel()->setDisplay(text);
+ getViewModel()->getEditableDisplay().insert(pos, wstr);
if ( truncate() )
{
@@ -669,7 +840,8 @@ S32 LLTextBase::insertStringNoUndo(S32 pos, const LLWString &wstr, LLTextBase::s
S32 LLTextBase::removeStringNoUndo(S32 pos, S32 length)
{
- LLWString text(getWText());
+
+ beforeValueChange();
segment_set_t::iterator seg_iter = getSegIterContaining(pos);
while(seg_iter != mSegments.end())
{
@@ -715,8 +887,7 @@ S32 LLTextBase::removeStringNoUndo(S32 pos, S32 length)
++seg_iter;
}
- text.erase(pos, length);
- getViewModel()->setDisplay(text);
+ getViewModel()->getEditableDisplay().erase(pos, length);
// recreate default segment in case we erased everything
createDefaultSegment();
@@ -729,13 +900,13 @@ S32 LLTextBase::removeStringNoUndo(S32 pos, S32 length)
S32 LLTextBase::overwriteCharNoUndo(S32 pos, llwchar wc)
{
+ beforeValueChange();
+
if (pos > (S32)getLength())
{
return 0;
}
- LLWString text(getWText());
- text[pos] = wc;
- getViewModel()->setDisplay(text);
+ getViewModel()->getEditableDisplay()[pos] = wc;
onValueChange(pos, pos + 1);
needsReflow(pos);
@@ -749,7 +920,7 @@ void LLTextBase::createDefaultSegment()
// ensures that there is always at least one segment
if (mSegments.empty())
{
- LLStyleConstSP sp(new LLStyle(getDefaultStyleParams()));
+ LLStyleConstSP sp(new LLStyle(getStyleParams()));
LLTextSegmentPtr default_segment = new LLNormalTextSegment( sp, 0, getLength() + 1, *this);
mSegments.insert(default_segment);
default_segment->linkToDocument(this);
@@ -839,6 +1010,13 @@ void LLTextBase::insertSegment(LLTextSegmentPtr segment_to_insert)
BOOL LLTextBase::handleMouseDown(S32 x, S32 y, MASK mask)
{
+ // handle triple click
+ if (!mTripleClickTimer.hasExpired())
+ {
+ selectAll();
+ return TRUE;
+ }
+
LLTextSegmentPtr cur_segment = getSegmentAtLocalPos(x, y);
if (cur_segment && cur_segment->handleMouseDown(x, y, mask))
{
@@ -851,7 +1029,7 @@ BOOL LLTextBase::handleMouseDown(S32 x, S32 y, MASK mask)
BOOL LLTextBase::handleMouseUp(S32 x, S32 y, MASK mask)
{
LLTextSegmentPtr cur_segment = getSegmentAtLocalPos(x, y);
- if (cur_segment && cur_segment->handleMouseUp(x, y, mask))
+ if (hasMouseCapture() && cur_segment && cur_segment->handleMouseUp(x, y, mask))
{
// Did we just click on a link?
if (mURLClickSignal
@@ -913,6 +1091,14 @@ BOOL LLTextBase::handleRightMouseUp(S32 x, S32 y, MASK mask)
BOOL LLTextBase::handleDoubleClick(S32 x, S32 y, MASK mask)
{
+ //Don't start triple click timer if user have clicked on scrollbar
+ mVisibleTextRect = mScroller ? mScroller->getContentWindowRect() : getLocalRect();
+ if (x >= mVisibleTextRect.mLeft && x <= mVisibleTextRect.mRight
+ && y >= mVisibleTextRect.mBottom && y <= mVisibleTextRect.mTop)
+ {
+ mTripleClickTimer.setTimerExpirySec(TRIPLE_CLICK_INTERVAL);
+ }
+
LLTextSegmentPtr cur_segment = getSegmentAtLocalPos(x, y);
if (cur_segment && cur_segment->handleDoubleClick(x, y, mask))
{
@@ -1103,6 +1289,118 @@ void LLTextBase::deselect()
mIsSelecting = FALSE;
}
+bool LLTextBase::getSpellCheck() const
+{
+ return (LLSpellChecker::getUseSpellCheck()) && (!mReadOnly) && (mSpellCheck);
+}
+
+const std::string& LLTextBase::getSuggestion(U32 index) const
+{
+ return (index < mSuggestionList.size()) ? mSuggestionList[index] : LLStringUtil::null;
+}
+
+U32 LLTextBase::getSuggestionCount() const
+{
+ return mSuggestionList.size();
+}
+
+void LLTextBase::replaceWithSuggestion(U32 index)
+{
+ for (std::list<std::pair<U32, U32> >::const_iterator it = mMisspellRanges.begin(); it != mMisspellRanges.end(); ++it)
+ {
+ if ( (it->first <= (U32)mCursorPos) && (it->second >= (U32)mCursorPos) )
+ {
+ deselect();
+
+ // Delete the misspelled word
+ removeStringNoUndo(it->first, it->second - it->first);
+
+ // Insert the suggestion in its place
+ LLWString suggestion = utf8str_to_wstring(mSuggestionList[index]);
+ insertStringNoUndo(it->first, utf8str_to_wstring(mSuggestionList[index]));
+ setCursorPos(it->first + (S32)suggestion.length());
+
+ break;
+ }
+ }
+ mSpellCheckStart = mSpellCheckEnd = -1;
+}
+
+void LLTextBase::addToDictionary()
+{
+ if (canAddToDictionary())
+ {
+ LLSpellChecker::instance().addToCustomDictionary(getMisspelledWord(mCursorPos));
+ }
+}
+
+bool LLTextBase::canAddToDictionary() const
+{
+ return (getSpellCheck()) && (isMisspelledWord(mCursorPos));
+}
+
+void LLTextBase::addToIgnore()
+{
+ if (canAddToIgnore())
+ {
+ LLSpellChecker::instance().addToIgnoreList(getMisspelledWord(mCursorPos));
+ }
+}
+
+bool LLTextBase::canAddToIgnore() const
+{
+ return (getSpellCheck()) && (isMisspelledWord(mCursorPos));
+}
+
+std::string LLTextBase::getMisspelledWord(U32 pos) const
+{
+ for (std::list<std::pair<U32, U32> >::const_iterator it = mMisspellRanges.begin(); it != mMisspellRanges.end(); ++it)
+ {
+ if ( (it->first <= pos) && (it->second >= pos) )
+ {
+ return wstring_to_utf8str(getWText().substr(it->first, it->second - it->first));
+ }
+ }
+ return LLStringUtil::null;
+}
+
+bool LLTextBase::isMisspelledWord(U32 pos) const
+{
+ for (std::list<std::pair<U32, U32> >::const_iterator it = mMisspellRanges.begin(); it != mMisspellRanges.end(); ++it)
+ {
+ if ( (it->first <= pos) && (it->second >= pos) )
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+void LLTextBase::onSpellCheckSettingsChange()
+{
+ // Recheck the spelling on every change
+ mMisspellRanges.clear();
+ mSpellCheckStart = mSpellCheckEnd = -1;
+}
+
+void LLTextBase::onFocusReceived()
+{
+ LLUICtrl::onFocusReceived();
+ if (!getLength() && !mLabel.empty())
+ {
+ // delete label which is LLLabelTextSegment
+ clearSegments();
+ }
+}
+
+void LLTextBase::onFocusLost()
+{
+ LLUICtrl::onFocusLost();
+ if (!getLength() && !mLabel.empty())
+ {
+ resetLabel();
+ }
+}
// Sets the scrollbar from the cursor position
void LLTextBase::updateScrollFromCursor()
@@ -1557,7 +1855,17 @@ LLTextBase::segment_set_t::iterator LLTextBase::getSegIterContaining(S32 index)
static LLPointer<LLIndexSegment> index_segment = new LLIndexSegment();
- if (index > getLength()) { return mSegments.end(); }
+ S32 text_len = 0;
+ if (!useLabel())
+ {
+ text_len = getLength();
+ }
+ else
+ {
+ text_len = mLabel.getWString().length();
+ }
+
+ if (index > text_len) { return mSegments.end(); }
// when there are no segments, we return the end iterator, which must be checked by caller
if (mSegments.size() <= 1) { return mSegments.begin(); }
@@ -1573,7 +1881,17 @@ LLTextBase::segment_set_t::const_iterator LLTextBase::getSegIterContaining(S32 i
{
static LLPointer<LLIndexSegment> index_segment = new LLIndexSegment();
- if (index > getLength()) { return mSegments.end(); }
+ S32 text_len = 0;
+ if (!useLabel())
+ {
+ text_len = getLength();
+ }
+ else
+ {
+ text_len = mLabel.getWString().length();
+ }
+
+ if (index > text_len) { return mSegments.end(); }
// when there are no segments, we return the end iterator, which must be checked by caller
if (mSegments.size() <= 1) { return mSegments.begin(); }
@@ -1623,8 +1941,12 @@ void LLTextBase::createUrlContextMenu(S32 x, S32 y, const std::string &in_url)
registrar.add("Url.OpenInternal", boost::bind(&LLUrlAction::openURLInternal, url));
registrar.add("Url.OpenExternal", boost::bind(&LLUrlAction::openURLExternal, url));
registrar.add("Url.Execute", boost::bind(&LLUrlAction::executeSLURL, url));
+ registrar.add("Url.Block", boost::bind(&LLUrlAction::blockObject, url));
registrar.add("Url.Teleport", boost::bind(&LLUrlAction::teleportToLocation, url));
registrar.add("Url.ShowProfile", boost::bind(&LLUrlAction::showProfile, url));
+ registrar.add("Url.AddFriend", boost::bind(&LLUrlAction::addFriend, url));
+ registrar.add("Url.RemoveFriend", boost::bind(&LLUrlAction::removeFriend, url));
+ registrar.add("Url.SendIM", boost::bind(&LLUrlAction::sendIM, url));
registrar.add("Url.ShowOnMap", boost::bind(&LLUrlAction::showLocationOnMap, url));
registrar.add("Url.CopyLabel", boost::bind(&LLUrlAction::copyLabelToClipboard, url));
registrar.add("Url.CopyUrl", boost::bind(&LLUrlAction::copyURLToClipboard, url));
@@ -1633,6 +1955,19 @@ void LLTextBase::createUrlContextMenu(S32 x, S32 y, const std::string &in_url)
delete mPopupMenu;
mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>(xui_file, LLMenuGL::sMenuContainer,
LLMenuHolderGL::child_registry_t::instance());
+ if (mIsFriendSignal)
+ {
+ bool isFriend = *(*mIsFriendSignal)(LLUUID(LLUrlAction::getUserID(url)));
+ LLView* addFriendButton = mPopupMenu->getChild<LLView>("add_friend");
+ LLView* removeFriendButton = mPopupMenu->getChild<LLView>("remove_friend");
+
+ if (addFriendButton && removeFriendButton)
+ {
+ addFriendButton->setEnabled(!isFriend);
+ removeFriendButton->setEnabled(isFriend);
+ }
+ }
+
if (mPopupMenu)
{
mPopupMenu->show(x, y);
@@ -1685,23 +2020,23 @@ static LLUIImagePtr image_from_icon_name(const std::string& icon_name)
}
}
+static LLFastTimer::DeclareTimer FTM_PARSE_HTML("Parse HTML");
+
void LLTextBase::appendTextImpl(const std::string &new_text, const LLStyle::Params& input_params)
{
LLStyle::Params style_params(input_params);
- style_params.fillFrom(getDefaultStyleParams());
+ style_params.fillFrom(getStyleParams());
S32 part = (S32)LLTextParser::WHOLE;
if (mParseHTML && !style_params.is_link) // Don't search for URLs inside a link segment (STORM-358).
{
+ LLFastTimer _(FTM_PARSE_HTML);
S32 start=0,end=0;
LLUrlMatch match;
std::string text = new_text;
while ( LLUrlRegistry::instance().findUrl(text, match,
boost::bind(&LLTextBase::replaceUrl, this, _1, _2, _3)) )
{
-
- LLTextUtil::processUrlMatch(&match,this);
-
start = match.getStart();
end = match.getEnd()+1;
@@ -1737,6 +2072,8 @@ void LLTextBase::appendTextImpl(const std::string &new_text, const LLStyle::Para
}
}
+ LLTextUtil::processUrlMatch(&match,this);
+
// move on to the rest of the text after the Url
if (end < (S32)text.length())
{
@@ -1760,8 +2097,11 @@ void LLTextBase::appendTextImpl(const std::string &new_text, const LLStyle::Para
}
}
+static LLFastTimer::DeclareTimer FTM_APPEND_TEXT("Append Text");
+
void LLTextBase::appendText(const std::string &new_text, bool prepend_newline, const LLStyle::Params& input_params)
{
+ LLFastTimer _(FTM_APPEND_TEXT);
if (new_text.empty())
return;
@@ -1770,6 +2110,44 @@ void LLTextBase::appendText(const std::string &new_text, bool prepend_newline, c
appendTextImpl(new_text,input_params);
}
+void LLTextBase::setLabel(const LLStringExplicit& label)
+{
+ mLabel = label;
+ resetLabel();
+}
+
+BOOL LLTextBase::setLabelArg(const std::string& key, const LLStringExplicit& text )
+{
+ mLabel.setArg(key, text);
+ return TRUE;
+}
+
+void LLTextBase::resetLabel()
+{
+ if (useLabel())
+ {
+ clearSegments();
+
+ LLStyle* style = new LLStyle(getStyleParams());
+ style->setColor(mTentativeFgColor);
+ LLStyleConstSP sp(style);
+
+ LLTextSegmentPtr label = new LLLabelTextSegment(sp, 0, mLabel.getWString().length() + 1, *this);
+ insertSegment(label);
+ }
+}
+
+bool LLTextBase::useLabel() const
+{
+ return !getLength() && !mLabel.empty() && !hasFocus();
+}
+
+void LLTextBase::setFont(const LLFontGL* font)
+{
+ mFont = font;
+ mStyleDirty = true;
+}
+
void LLTextBase::needsReflow(S32 index)
{
lldebugs << "reflow on object " << (void*)this << " index = " << mReflowIndex << ", new index = " << index << llendl;
@@ -2000,9 +2378,7 @@ const LLWString& LLTextBase::getWText() const
S32 LLTextBase::getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round, bool hit_past_end_of_line) const
{
// Figure out which line we're nearest to.
- LLRect visible_region = getVisibleDocumentRect();
LLRect doc_rect = mDocumentView->getRect();
-
S32 doc_y = local_y - doc_rect.mBottom;
// binary search for line that starts before local_y
@@ -2160,7 +2536,7 @@ LLRect LLTextBase::getLocalRectFromDocIndex(S32 pos) const
{
// return default height rect in upper left
local_rect = content_window_rect;
- local_rect.mBottom = local_rect.mTop - mDefaultFont->getLineHeight();
+ local_rect.mBottom = local_rect.mTop - mFont->getLineHeight();
return local_rect;
}
@@ -2266,21 +2642,18 @@ void LLTextBase::setCursorAtLocalPos( S32 local_x, S32 local_y, bool round, bool
void LLTextBase::changeLine( S32 delta )
{
S32 line = getLineNumFromDocIndex(mCursorPos);
+ S32 max_line_nb = getLineCount() - 1;
+ max_line_nb = (max_line_nb < 0 ? 0 : max_line_nb);
+
+ S32 new_line = llclamp(line + delta, 0, max_line_nb);
- S32 new_line = line;
- if( (delta < 0) && (line > 0 ) )
- {
- new_line = line - 1;
- }
- else if( (delta > 0) && (line < (getLineCount() - 1)) )
- {
- new_line = line + 1;
- }
-
- LLRect visible_region = getVisibleDocumentRect();
-
- S32 new_cursor_pos = getDocIndexFromLocalCoord(mDesiredXPixel, mLineInfoList[new_line].mRect.mBottom + mVisibleTextRect.mBottom - visible_region.mBottom, TRUE);
- setCursorPos(new_cursor_pos, true);
+ if (new_line != line)
+ {
+ LLRect visible_region = getVisibleDocumentRect();
+ S32 new_cursor_pos = getDocIndexFromLocalCoord(mDesiredXPixel,
+ mLineInfoList[new_line].mRect.mBottom + mVisibleTextRect.mBottom - visible_region.mBottom, TRUE);
+ setCursorPos(new_cursor_pos, true);
+ }
}
bool LLTextBase::scrolledToStart()
@@ -2574,6 +2947,15 @@ boost::signals2::connection LLTextBase::setURLClickedCallback(const commit_signa
return mURLClickSignal->connect(cb);
}
+boost::signals2::connection LLTextBase::setIsFriendCallback(const is_friend_signal_t::slot_type& cb)
+{
+ if (!mIsFriendSignal)
+ {
+ mIsFriendSignal = new is_friend_signal_t();
+ }
+ return mIsFriendSignal->connect(cb);
+}
+
//
// LLTextSegment
//
@@ -2665,7 +3047,7 @@ F32 LLNormalTextSegment::drawClippedSegment(S32 seg_start, S32 seg_end, S32 sele
{
F32 alpha = LLViewDrawContext::getCurrentContext().mAlpha;
- const LLWString &text = mEditor.getWText();
+ const LLWString &text = getWText();
F32 right_x = rect.mLeft;
if (!mStyle->isVisible())
@@ -2828,7 +3210,7 @@ bool LLNormalTextSegment::getDimensions(S32 first_char, S32 num_chars, S32& widt
if (num_chars > 0)
{
height = mFontHeight;
- const LLWString &text = mEditor.getWText();
+ const LLWString &text = getWText();
// if last character is a newline, then return true, forcing line break
width = mStyle->getFont()->getWidth(text.c_str(), mStart + first_char, num_chars);
}
@@ -2837,7 +3219,7 @@ bool LLNormalTextSegment::getDimensions(S32 first_char, S32 num_chars, S32& widt
S32 LLNormalTextSegment::getOffset(S32 segment_local_x_coord, S32 start_offset, S32 num_chars, bool round) const
{
- const LLWString &text = mEditor.getWText();
+ const LLWString &text = getWText();
return mStyle->getFont()->charFromPixelOffset(text.c_str(), mStart + start_offset,
(F32)segment_local_x_coord,
F32_MAX,
@@ -2847,7 +3229,7 @@ S32 LLNormalTextSegment::getOffset(S32 segment_local_x_coord, S32 start_offset,
S32 LLNormalTextSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const
{
- const LLWString &text = mEditor.getWText();
+ const LLWString &text = getWText();
LLUIImagePtr image = mStyle->getImage();
if( image.notNull())
@@ -2865,7 +3247,23 @@ S32 LLNormalTextSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 lin
LLFontGL::EWordWrapStyle word_wrap_style = (line_offset == 0)
? LLFontGL::WORD_BOUNDARY_IF_POSSIBLE
: LLFontGL::ONLY_WORD_BOUNDARIES;
- S32 num_chars = mStyle->getFont()->maxDrawableChars(text.c_str() + segment_offset + mStart,
+
+
+ S32 offsetLength = text.length() - (segment_offset + mStart);
+
+ if(getLength() < segment_offset + mStart)
+ {
+ llinfos << "getLength() < segment_offset + mStart\t getLength()\t" << getLength() << "\tsegment_offset:\t"
+ << segment_offset << "\tmStart:\t" << mStart << "\tsegments\t" << mEditor.mSegments.size() << "\tmax_chars\t" << max_chars << llendl;
+ }
+
+ if( (offsetLength + 1) < max_chars)
+ {
+ llinfos << "offsetString.length() + 1 < max_chars\t max_chars:\t" << max_chars << "\toffsetLength:\t" << offsetLength << " getLength() : "
+ << getLength() << "\tsegment_offset:\t" << segment_offset << "\tmStart:\t" << mStart << "\tsegments\t" << mEditor.mSegments.size() << llendl;
+ }
+
+ S32 num_chars = mStyle->getFont()->maxDrawableChars( text.c_str() + (segment_offset + mStart),
(F32)num_pixels,
max_chars,
word_wrap_style);
@@ -2883,7 +3281,7 @@ S32 LLNormalTextSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 lin
S32 last_char_in_run = mStart + segment_offset + num_chars;
// check length first to avoid indexing off end of string
if (last_char_in_run < mEnd
- && (last_char_in_run >= mEditor.getLength() ))
+ && (last_char_in_run >= getLength()))
{
num_chars++;
}
@@ -2901,6 +3299,39 @@ void LLNormalTextSegment::dump() const
llendl;
}
+/*virtual*/
+const LLWString& LLNormalTextSegment::getWText() const
+{
+ return mEditor.getWText();
+}
+
+/*virtual*/
+const S32 LLNormalTextSegment::getLength() const
+{
+ return mEditor.getLength();
+}
+
+LLLabelTextSegment::LLLabelTextSegment( LLStyleConstSP style, S32 start, S32 end, LLTextBase& editor )
+: LLNormalTextSegment(style, start, end, editor)
+{
+}
+
+LLLabelTextSegment::LLLabelTextSegment( const LLColor4& color, S32 start, S32 end, LLTextBase& editor, BOOL is_visible)
+: LLNormalTextSegment(color, start, end, editor, is_visible)
+{
+}
+
+/*virtual*/
+const LLWString& LLLabelTextSegment::getWText() const
+{
+ return mEditor.getWlabel();
+}
+/*virtual*/
+const S32 LLLabelTextSegment::getLength() const
+{
+ return mEditor.getWlabel().length();
+}
+
//
// LLOnHoverChangeableTextSegment
//
@@ -3105,3 +3536,7 @@ F32 LLImageTextSegment::draw(S32 start, S32 end, S32 selection_start, S32 select
return 0.0;
}
+void LLTextBase::setWordWrap(bool wrap)
+{
+ mWordWrap = wrap;
+}
diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h
index 0549141b72..a74e97cac8 100644..100755
--- a/indra/llui/lltextbase.h
+++ b/indra/llui/lltextbase.h
@@ -30,6 +30,7 @@
#include "v4color.h"
#include "lleditmenuhandler.h"
+#include "llspellcheckmenuhandler.h"
#include "llstyle.h"
#include "llkeywords.h"
#include "llpanel.h"
@@ -40,6 +41,7 @@
#include <boost/signals2.hpp>
+class LLScrollContainer;
class LLContextMenu;
class LLUrlMatch;
@@ -105,7 +107,7 @@ class LLNormalTextSegment : public LLTextSegment
public:
LLNormalTextSegment( LLStyleConstSP style, S32 start, S32 end, LLTextBase& editor );
LLNormalTextSegment( const LLColor4& color, S32 start, S32 end, LLTextBase& editor, BOOL is_visible = TRUE);
- ~LLNormalTextSegment();
+ virtual ~LLNormalTextSegment();
/*virtual*/ bool getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const;
/*virtual*/ S32 getOffset(S32 segment_local_x_coord, S32 start_offset, S32 num_chars, bool round) const;
@@ -130,6 +132,9 @@ public:
protected:
F32 drawClippedSegment(S32 seg_start, S32 seg_end, S32 selection_start, S32 selection_end, LLRect rect);
+ virtual const LLWString& getWText() const;
+ virtual const S32 getLength() const;
+
protected:
class LLTextBase& mEditor;
LLStyleConstSP mStyle;
@@ -139,6 +144,21 @@ protected:
boost::signals2::connection mImageLoadedConnection;
};
+// This text segment is the same as LLNormalTextSegment, the only difference
+// is that LLNormalTextSegment draws value of LLTextBase (LLTextBase::getWText()),
+// but LLLabelTextSegment draws label of the LLTextBase (LLTextBase::mLabel)
+class LLLabelTextSegment : public LLNormalTextSegment
+{
+public:
+ LLLabelTextSegment( LLStyleConstSP style, S32 start, S32 end, LLTextBase& editor );
+ LLLabelTextSegment( const LLColor4& color, S32 start, S32 end, LLTextBase& editor, BOOL is_visible = TRUE);
+
+protected:
+
+ /*virtual*/ const LLWString& getWText() const;
+ /*virtual*/ const S32 getLength() const;
+};
+
// Text segment that changes it's style depending of mouse pointer position ( is it inside or outside segment)
class LLOnHoverChangeableTextSegment : public LLNormalTextSegment
{
@@ -230,13 +250,16 @@ typedef LLPointer<LLTextSegment> LLTextSegmentPtr;
///
class LLTextBase
: public LLUICtrl,
- protected LLEditMenuHandler
+ protected LLEditMenuHandler,
+ public LLSpellCheckMenuHandler
{
public:
friend class LLTextSegment;
friend class LLNormalTextSegment;
friend class LLUICtrlFactory;
+ typedef boost::signals2::signal<bool (const LLUUID& user_id)> is_friend_signal_t;
+
struct LineSpacingParams : public LLInitParam::ChoiceBlock<LineSpacingParams>
{
Alternative<F32> multiple;
@@ -249,6 +272,7 @@ public:
Optional<LLUIColor> cursor_color,
text_color,
text_readonly_color,
+ text_tentative_color,
bg_readonly_color,
bg_writeable_color,
bg_focus_color,
@@ -259,6 +283,7 @@ public:
border_visible,
track_end,
read_only,
+ spellcheck,
allow_scroll,
plain_text,
wrap,
@@ -311,6 +336,27 @@ public:
/*virtual*/ BOOL canDeselect() const;
/*virtual*/ void deselect();
+ virtual void onFocusReceived();
+ virtual void onFocusLost();
+
+ // LLSpellCheckMenuHandler overrides
+ /*virtual*/ bool getSpellCheck() const;
+
+ /*virtual*/ const std::string& getSuggestion(U32 index) const;
+ /*virtual*/ U32 getSuggestionCount() const;
+ /*virtual*/ void replaceWithSuggestion(U32 index);
+
+ /*virtual*/ void addToDictionary();
+ /*virtual*/ bool canAddToDictionary() const;
+
+ /*virtual*/ void addToIgnore();
+ /*virtual*/ bool canAddToIgnore() const;
+
+ // Spell checking helper functions
+ std::string getMisspelledWord(U32 pos) const;
+ bool isMisspelledWord(U32 pos) const;
+ void onSpellCheckSettingsChange();
+
// used by LLTextSegment layout code
bool getWordWrap() { return mWordWrap; }
bool getUseEllipses() { return mUseEllipses; }
@@ -330,6 +376,21 @@ public:
const LLWString& getWText() const;
void appendText(const std::string &new_text, bool prepend_newline, const LLStyle::Params& input_params = LLStyle::Params());
+
+ void setLabel(const LLStringExplicit& label);
+ virtual BOOL setLabelArg(const std::string& key, const LLStringExplicit& text );
+
+ const std::string& getLabel() { return mLabel.getString(); }
+ const LLWString& getWlabel() { return mLabel.getWString();}
+
+ /**
+ * If label is set, draws text label (which is LLLabelTextSegment)
+ * that is visible when no user text provided
+ */
+ void resetLabel();
+
+ void setFont(const LLFontGL* font);
+
// force reflow of text
void needsReflow(S32 index = 0);
@@ -369,12 +430,16 @@ public:
bool scrolledToStart();
bool scrolledToEnd();
- const LLFontGL* getDefaultFont() const { return mDefaultFont; }
+ const LLFontGL* getFont() const { return mFont; }
virtual void appendLineBreakSegment(const LLStyle::Params& style_params);
virtual void appendImageSegment(const LLStyle::Params& style_params);
virtual void appendWidget(const LLInlineViewSegment::Params& params, const std::string& text, bool allow_undo);
boost::signals2::connection setURLClickedCallback(const commit_signal_t::slot_type& cb);
+ boost::signals2::connection setIsFriendCallback(const is_friend_signal_t::slot_type& cb);
+
+ void setWordWrap(bool wrap);
+ LLScrollContainer* getScrollContainer() const { return mScroller; }
protected:
// helper structs
@@ -443,7 +508,9 @@ protected:
LLTextBase(const Params &p);
virtual ~LLTextBase();
void initFromParams(const Params& p);
+ virtual void beforeValueChange();
virtual void onValueChange(S32 start, S32 end);
+ virtual bool useLabel() const;
// draw methods
void drawSelectionBackground(); // draws the black box behind the selected text
@@ -469,7 +536,7 @@ protected:
void createDefaultSegment();
virtual void updateSegments();
void insertSegment(LLTextSegmentPtr segment_to_insert);
- const LLStyle::Params& getDefaultStyleParams();
+ const LLStyle::Params& getStyleParams();
// manage lines
S32 getLineStart( S32 line ) const;
@@ -514,15 +581,16 @@ protected:
LLRect mTextBoundingRect;
// default text style
- LLStyle::Params mDefaultStyle;
+ LLStyle::Params mStyle;
bool mStyleDirty;
- const LLFontGL* const mDefaultFont; // font that is used when none specified, can only be set by constructor
- const LLFontGL::ShadowType mFontShadow; // shadow style, can only be set by constructor
+ const LLFontGL* mFont;
+ const LLFontGL::ShadowType mFontShadow;
// colors
LLUIColor mCursorColor;
LLUIColor mFgColor;
LLUIColor mReadOnlyFgColor;
+ LLUIColor mTentativeFgColor;
LLUIColor mWriteableBgColor;
LLUIColor mReadOnlyBgColor;
LLUIColor mFocusBgColor;
@@ -537,9 +605,18 @@ protected:
// selection
S32 mSelectionStart;
S32 mSelectionEnd;
-
+ LLTimer mTripleClickTimer;
+
BOOL mIsSelecting; // Are we in the middle of a drag-select?
+ // spell checking
+ bool mSpellCheck;
+ S32 mSpellCheckStart;
+ S32 mSpellCheckEnd;
+ LLTimer mSpellCheckTimer;
+ std::list<std::pair<U32, U32> > mMisspellRanges;
+ std::vector<std::string> mSuggestionList;
+
// configuration
S32 mHPad; // padding on left of text
S32 mVPad; // padding above text
@@ -558,12 +635,13 @@ protected:
bool mClip; // clip text to widget rect
bool mClipPartial; // false if we show lines that are partially inside bounding rect
bool mPlainText; // didn't use Image or Icon segments
+ bool mAutoIndent;
S32 mMaxTextByteLength; // Maximum length mText is allowed to be in bytes
// support widgets
LLContextMenu* mPopupMenu;
LLView* mDocumentView;
- class LLScrollContainer* mScroller;
+ LLScrollContainer* mScroller;
// transient state
S32 mReflowIndex; // index at which to start reflow. S32_MAX indicates no reflow needed.
@@ -573,6 +651,10 @@ protected:
// Fired when a URL link is clicked
commit_signal_t* mURLClickSignal;
+ // Used to check if user with given ID is avatar's friend
+ is_friend_signal_t* mIsFriendSignal;
+
+ LLUIString mLabel; // text label that is visible when no user text provided
};
#endif
diff --git a/indra/llui/lltextbox.cpp b/indra/llui/lltextbox.cpp
index 6a905b7ec0..d175204e6d 100644..100755
--- a/indra/llui/lltextbox.cpp
+++ b/indra/llui/lltextbox.cpp
@@ -60,10 +60,13 @@ BOOL LLTextBox::handleMouseDown(S32 x, S32 y, MASK mask)
if (!handled && mClickedCallback)
{
+ handled = TRUE;
+ }
+
+ if (handled)
+ {
// Route future Mouse messages here preemptively. (Release on mouse up.)
gFocusMgr.setMouseCapture( this );
-
- handled = TRUE;
}
return handled;
@@ -71,7 +74,7 @@ BOOL LLTextBox::handleMouseDown(S32 x, S32 y, MASK mask)
BOOL LLTextBox::handleMouseUp(S32 x, S32 y, MASK mask)
{
- BOOL handled = FALSE;
+ BOOL handled = LLTextBase::handleMouseUp(x, y, mask);
if (getSoundFlags() & MOUSE_UP)
{
@@ -93,10 +96,6 @@ BOOL LLTextBox::handleMouseUp(S32 x, S32 y, MASK mask)
handled = TRUE;
}
}
- else
- {
- handled = LLTextBase::handleMouseUp(x, y, mask);
- }
return handled;
}
@@ -150,7 +149,7 @@ S32 LLTextBox::getTextPixelHeight()
LLSD LLTextBox::getValue() const
{
- return LLSD(getText());
+ return getViewModel()->getValue();
}
BOOL LLTextBox::setTextArg( const std::string& key, const LLStringExplicit& text )
diff --git a/indra/llui/lltextbox.h b/indra/llui/lltextbox.h
index 071e18c638..071e18c638 100644..100755
--- a/indra/llui/lltextbox.h
+++ b/indra/llui/lltextbox.h
diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp
index 9720dded6c..62140dd9d6 100644..100755
--- a/indra/llui/lltexteditor.cpp
+++ b/indra/llui/lltexteditor.cpp
@@ -54,6 +54,7 @@
#include "llwindow.h"
#include "lltextparser.h"
#include "llscrollcontainer.h"
+#include "llspellcheck.h"
#include "llpanel.h"
#include "llurlregistry.h"
#include "lltooltip.h"
@@ -77,6 +78,7 @@ template class LLTextEditor* LLView::getChild<class LLTextEditor>(
const S32 UI_TEXTEDITOR_LINE_NUMBER_MARGIN = 32;
const S32 UI_TEXTEDITOR_LINE_NUMBER_DIGITS = 4;
const S32 SPACES_PER_TAB = 4;
+const F32 SPELLCHECK_DELAY = 0.5f; // delay between the last keypress and spell checking the word the cursor is on
///////////////////////////////////////////////////////////////////
@@ -235,20 +237,24 @@ LLTextEditor::Params::Params()
embedded_items("embedded_items", false),
ignore_tab("ignore_tab", true),
show_line_numbers("show_line_numbers", false),
+ auto_indent("auto_indent", true),
default_color("default_color"),
commit_on_focus_lost("commit_on_focus_lost", false),
- show_context_menu("show_context_menu")
+ show_context_menu("show_context_menu"),
+ enable_tooltip_paste("enable_tooltip_paste")
{
addSynonym(prevalidate_callback, "text_type");
}
LLTextEditor::LLTextEditor(const LLTextEditor::Params& p) :
LLTextBase(p),
+ mAutoreplaceCallback(),
mBaseDocIsPristine(TRUE),
mPristineCmd( NULL ),
mLastCmd( NULL ),
mDefaultColor( p.default_color() ),
mShowLineNumbers ( p.show_line_numbers ),
+ mAutoIndent(p.auto_indent),
mCommitOnFocusLost( p.commit_on_focus_lost),
mAllowEmbeddedItems( p.embedded_items ),
mMouseDownX(0),
@@ -256,7 +262,9 @@ LLTextEditor::LLTextEditor(const LLTextEditor::Params& p) :
mTabsToNextField(p.ignore_tab),
mPrevalidateFunc(p.prevalidate_callback()),
mContextMenu(NULL),
- mShowContextMenu(p.show_context_menu)
+ mShowContextMenu(p.show_context_menu),
+ mEnableTooltipPaste(p.enable_tooltip_paste),
+ mPassDelete(FALSE)
{
mSourceID.generate();
@@ -658,6 +666,14 @@ void LLTextEditor::selectAll()
updatePrimary();
}
+void LLTextEditor::selectByCursorPosition(S32 prev_cursor_pos, S32 next_cursor_pos)
+{
+ setCursorPos(prev_cursor_pos);
+ startSelection();
+ setCursorPos(next_cursor_pos);
+ endSelection();
+}
+
BOOL LLTextEditor::handleMouseDown(S32 x, S32 y, MASK mask)
{
BOOL handled = FALSE;
@@ -705,7 +721,6 @@ BOOL LLTextEditor::handleMouseDown(S32 x, S32 y, MASK mask)
setCursorAtLocalPos( x, y, true );
startSelection();
}
- gFocusMgr.setMouseCapture( this );
}
handled = TRUE;
@@ -714,6 +729,10 @@ BOOL LLTextEditor::handleMouseDown(S32 x, S32 y, MASK mask)
// Delay cursor flashing
resetCursorBlink();
+ if (handled && !gFocusMgr.getMouseCapture())
+ {
+ gFocusMgr.setMouseCapture( this );
+ }
return handled;
}
@@ -948,12 +967,18 @@ S32 LLTextEditor::insert(S32 pos, const LLWString &wstr, bool group_with_next_op
S32 LLTextEditor::remove(S32 pos, S32 length, bool group_with_next_op)
{
S32 end_pos = getEditableIndex(pos + length, true);
+ BOOL removedChar = FALSE;
segment_vec_t segments_to_remove;
// store text segments
getSegmentsInRange(segments_to_remove, pos, pos + length, false);
+
+ if(pos <= end_pos)
+ {
+ removedChar = execute( new TextCmdRemove( pos, group_with_next_op, end_pos - pos, segments_to_remove ) );
+ }
- return execute( new TextCmdRemove( pos, group_with_next_op, end_pos - pos, segments_to_remove ) );
+ return removedChar;
}
S32 LLTextEditor::overwriteChar(S32 pos, llwchar wc)
@@ -1092,8 +1117,27 @@ void LLTextEditor::addChar(llwchar wc)
}
setCursorPos(mCursorPos + addChar( mCursorPos, wc ));
+
+ if (!mReadOnly && mAutoreplaceCallback != NULL)
+ {
+ // autoreplace the text, if necessary
+ S32 replacement_start;
+ S32 replacement_length;
+ LLWString replacement_string;
+ S32 new_cursor_pos = mCursorPos;
+ mAutoreplaceCallback(replacement_start, replacement_length, replacement_string, new_cursor_pos, getWText());
+
+ if (replacement_length > 0 || !replacement_string.empty())
+ {
+ remove(replacement_start, replacement_length, true);
+ insert(replacement_start, replacement_string, false, LLTextSegmentPtr());
+ setCursorPos(new_cursor_pos);
+ }
+ }
}
-void LLTextEditor::addLineBreakChar()
+
+
+void LLTextEditor::addLineBreakChar(BOOL group_together)
{
if( !getEnabled() )
{
@@ -1111,7 +1155,7 @@ void LLTextEditor::addLineBreakChar()
LLStyleConstSP sp(new LLStyle(LLStyle::Params()));
LLTextSegmentPtr segment = new LLLineBreakTextSegment(sp, mCursorPos);
- S32 pos = execute(new TextCmdAddChar(mCursorPos, FALSE, '\n', segment));
+ S32 pos = execute(new TextCmdAddChar(mCursorPos, group_together, '\n', segment));
setCursorPos(mCursorPos + pos);
}
@@ -1409,6 +1453,23 @@ void LLTextEditor::pasteHelper(bool is_primary)
// Clean up string (replace tabs and remove characters that our fonts don't support).
LLWString clean_string(paste);
+ cleanStringForPaste(clean_string);
+
+ // Insert the new text into the existing text.
+
+ //paste text with linebreaks.
+ pasteTextWithLinebreaks(clean_string);
+
+ deselect();
+
+ onKeyStroke();
+ mParseOnTheFly = TRUE;
+}
+
+
+// Clean up string (replace tabs and remove characters that our fonts don't support).
+void LLTextEditor::cleanStringForPaste(LLWString & clean_string)
+{
LLWStringUtil::replaceTabsWithSpaces(clean_string, SPACES_PER_TAB);
if( mAllowEmbeddedItems )
{
@@ -1427,37 +1488,38 @@ void LLTextEditor::pasteHelper(bool is_primary)
}
}
}
+}
- // Insert the new text into the existing text.
- //paste text with linebreaks.
+void LLTextEditor::pasteTextWithLinebreaks(LLWString & clean_string)
+{
std::basic_string<llwchar>::size_type start = 0;
std::basic_string<llwchar>::size_type pos = clean_string.find('\n',start);
- while(pos!=-1)
+ while((pos != -1) && (pos != clean_string.length() -1))
{
if(pos!=start)
{
std::basic_string<llwchar> str = std::basic_string<llwchar>(clean_string,start,pos-start);
- setCursorPos(mCursorPos + insert(mCursorPos, str, FALSE, LLTextSegmentPtr()));
+ setCursorPos(mCursorPos + insert(mCursorPos, str, TRUE, LLTextSegmentPtr()));
}
- addLineBreakChar();
-
+ addLineBreakChar(TRUE); // Add a line break and group with the next addition.
+
start = pos+1;
pos = clean_string.find('\n',start);
}
- std::basic_string<llwchar> str = std::basic_string<llwchar>(clean_string,start,clean_string.length()-start);
- setCursorPos(mCursorPos + insert(mCursorPos, str, FALSE, LLTextSegmentPtr()));
-
- deselect();
-
- onKeyStroke();
- mParseOnTheFly = TRUE;
+ if (pos != start)
+ {
+ std::basic_string<llwchar> str = std::basic_string<llwchar>(clean_string,start,clean_string.length()-start);
+ setCursorPos(mCursorPos + insert(mCursorPos, str, FALSE, LLTextSegmentPtr()));
+ }
+ else
+ {
+ addLineBreakChar(FALSE); // Add a line break and end the grouping.
+ }
}
-
-
// copy selection to primary
void LLTextEditor::copyPrimary()
{
@@ -1606,7 +1668,10 @@ BOOL LLTextEditor::handleSpecialKey(const KEY key, const MASK mask)
{
deleteSelection(FALSE);
}
- autoIndent(); // TODO: make this optional
+ if (mAutoIndent)
+ {
+ autoIndent();
+ }
}
else
{
@@ -1678,19 +1743,50 @@ BOOL LLTextEditor::handleKeyHere(KEY key, MASK mask )
{
return FALSE;
}
-
+
if (mReadOnly && mScroller)
{
handled = (mScroller && mScroller->handleKeyHere( key, mask ))
|| handleSelectionKey(key, mask)
|| handleControlKey(key, mask);
+ }
+ else
+ {
+ if (mEnableTooltipPaste &&
+ LLToolTipMgr::instance().toolTipVisible() &&
+ KEY_TAB == key)
+ { // Paste the first line of a tooltip into the editor
+ std::string message;
+ LLToolTipMgr::instance().getToolTipMessage(message);
+ LLWString tool_tip_text(utf8str_to_wstring(message));
+
+ if (tool_tip_text.size() > 0)
+ {
+ // Delete any selected characters (the tooltip text replaces them)
+ if(hasSelection())
+ {
+ deleteSelection(TRUE);
+ }
+
+ std::basic_string<llwchar>::size_type pos = tool_tip_text.find('\n',0);
+ if (pos != -1)
+ { // Extract the first line of the tooltip
+ tool_tip_text = std::basic_string<llwchar>(tool_tip_text, 0, pos);
+ }
+
+ // Add the text
+ cleanStringForPaste(tool_tip_text);
+ pasteTextWithLinebreaks(tool_tip_text);
+ handled = TRUE;
+ }
+ }
+ else
+ { // Normal key handling
+ handled = handleNavigationKey( key, mask )
+ || handleSelectionKey(key, mask)
+ || handleControlKey(key, mask)
+ || handleSpecialKey(key, mask);
}
- else
- {
- handled = handleNavigationKey( key, mask )
- || handleSelectionKey(key, mask)
- || handleControlKey(key, mask)
- || handleSpecialKey(key, mask);
}
if( handled )
@@ -1746,7 +1842,7 @@ BOOL LLTextEditor::handleUnicodeCharHere(llwchar uni_char)
// virtual
BOOL LLTextEditor::canDoDelete() const
{
- return !mReadOnly && ( hasSelection() || (mCursorPos < getLength()) );
+ return !mReadOnly && ( !mPassDelete || ( hasSelection() || (mCursorPos < getLength())) );
}
void LLTextEditor::doDelete()
@@ -1887,8 +1983,7 @@ void LLTextEditor::onFocusReceived()
updateAllowingLanguageInput();
}
-// virtual, from LLView
-void LLTextEditor::onFocusLost()
+void LLTextEditor::focusLostHelper()
{
updateAllowingLanguageInput();
@@ -1905,7 +2000,11 @@ void LLTextEditor::onFocusLost()
// Make sure cursor is shown again
getWindow()->showCursorFromMouseMove();
+}
+void LLTextEditor::onFocusLost()
+{
+ focusLostHelper();
LLTextBase::onFocusLost();
}
@@ -1953,7 +2052,38 @@ void LLTextEditor::showContextMenu(S32 x, S32 y)
S32 screen_x, screen_y;
localPointToScreen(x, y, &screen_x, &screen_y);
- mContextMenu->show(screen_x, screen_y);
+
+ setCursorAtLocalPos(x, y, false);
+ if (hasSelection())
+ {
+ if ( (mCursorPos < llmin(mSelectionStart, mSelectionEnd)) || (mCursorPos > llmax(mSelectionStart, mSelectionEnd)) )
+ {
+ deselect();
+ }
+ else
+ {
+ setCursorPos(llmax(mSelectionStart, mSelectionEnd));
+ }
+ }
+
+ bool use_spellcheck = getSpellCheck(), is_misspelled = false;
+ if (use_spellcheck)
+ {
+ mSuggestionList.clear();
+
+ // If the cursor is on a misspelled word, retrieve suggestions for it
+ std::string misspelled_word = getMisspelledWord(mCursorPos);
+ if ((is_misspelled = !misspelled_word.empty()) == true)
+ {
+ LLSpellChecker::instance().getSuggestions(misspelled_word, mSuggestionList);
+ }
+ }
+
+ mContextMenu->setItemVisible("Suggestion Separator", (use_spellcheck) && (!mSuggestionList.empty()));
+ mContextMenu->setItemVisible("Add to Dictionary", (use_spellcheck) && (is_misspelled));
+ mContextMenu->setItemVisible("Add to Ignore", (use_spellcheck) && (is_misspelled));
+ mContextMenu->setItemVisible("Spellcheck Separator", (use_spellcheck) && (is_misspelled));
+ mContextMenu->show(screen_x, screen_y, this);
}
@@ -1984,7 +2114,7 @@ void LLTextEditor::drawPreeditMarker()
return;
}
- const S32 line_height = mDefaultFont->getLineHeight();
+ const S32 line_height = mFont->getLineHeight();
S32 line_start = getLineStart(cur_line);
S32 line_y = mVisibleTextRect.mTop - line_height;
@@ -2020,36 +2150,41 @@ void LLTextEditor::drawPreeditMarker()
continue;
}
- S32 preedit_left = mVisibleTextRect.mLeft;
+ line_info& line = mLineInfoList[cur_line];
+ LLRect text_rect(line.mRect);
+ text_rect.mRight = mDocumentView->getRect().getWidth(); // clamp right edge to document extents
+ text_rect.translate(mDocumentView->getRect().mLeft, mDocumentView->getRect().mBottom); // adjust by scroll position
+
+ S32 preedit_left = text_rect.mLeft;
if (left > line_start)
{
- preedit_left += mDefaultFont->getWidth(text, line_start, left - line_start);
+ preedit_left += mFont->getWidth(text, line_start, left - line_start);
}
- S32 preedit_right = mVisibleTextRect.mLeft;
+ S32 preedit_right = text_rect.mLeft;
if (right < line_end)
{
- preedit_right += mDefaultFont->getWidth(text, line_start, right - line_start);
+ preedit_right += mFont->getWidth(text, line_start, right - line_start);
}
else
{
- preedit_right += mDefaultFont->getWidth(text, line_start, line_end - line_start);
+ preedit_right += mFont->getWidth(text, line_start, line_end - line_start);
}
if (mPreeditStandouts[i])
{
gl_rect_2d(preedit_left + preedit_standout_gap,
- line_y + preedit_standout_position,
- preedit_right - preedit_standout_gap - 1,
- line_y + preedit_standout_position - preedit_standout_thickness,
- (mCursorColor.get() * preedit_standout_brightness + mWriteableBgColor.get() * (1 - preedit_standout_brightness)).setAlpha(1.0f));
+ text_rect.mBottom + mFont->getDescenderHeight() - 1,
+ preedit_right - preedit_standout_gap - 1,
+ text_rect.mBottom + mFont->getDescenderHeight() - 1 - preedit_standout_thickness,
+ (mCursorColor.get() * preedit_standout_brightness + mWriteableBgColor.get() * (1 - preedit_standout_brightness)).setAlpha(1.0f));
}
else
{
gl_rect_2d(preedit_left + preedit_marker_gap,
- line_y + preedit_marker_position,
- preedit_right - preedit_marker_gap - 1,
- line_y + preedit_marker_position - preedit_marker_thickness,
- (mCursorColor.get() * preedit_marker_brightness + mWriteableBgColor.get() * (1 - preedit_marker_brightness)).setAlpha(1.0f));
+ text_rect.mBottom + mFont->getDescenderHeight() - 1,
+ preedit_right - preedit_marker_gap - 1,
+ text_rect.mBottom + mFont->getDescenderHeight() - 1 - preedit_marker_thickness,
+ (mCursorColor.get() * preedit_marker_brightness + mWriteableBgColor.get() * (1 - preedit_marker_brightness)).setAlpha(1.0f));
}
}
}
@@ -2132,12 +2267,13 @@ void LLTextEditor::draw()
LLRect clip_rect(mVisibleTextRect);
clip_rect.stretch(1);
LLLocalClipRect clip(clip_rect);
- drawPreeditMarker();
}
LLTextBase::draw();
drawLineNumbers();
+ drawPreeditMarker();
+
//RN: the decision was made to always show the orange border for keyboard focus but do not put an insertion caret
// when in readonly mode
mBorder->setKeyboardFocusHighlight( hasFocus() );// && !mReadOnly);
@@ -2413,7 +2549,6 @@ void LLTextEditor::updateSegments()
mKeywords.findSegments(&segment_list, getWText(), mDefaultColor.get(), *this);
clearSegments();
- segment_set_t::iterator insert_it = mSegments.begin();
for (segment_vec_t::iterator list_it = segment_list.begin(); list_it != segment_list.end(); ++list_it)
{
insertSegment(*list_it);
@@ -2588,14 +2723,20 @@ BOOL LLTextEditor::hasPreeditString() const
void LLTextEditor::resetPreedit()
{
+ if (hasSelection())
+ {
+ if (hasPreeditString())
+ {
+ llwarns << "Preedit and selection!" << llendl;
+ deselect();
+ }
+ else
+ {
+ deleteSelection(TRUE);
+ }
+ }
if (hasPreeditString())
{
- if (hasSelection())
- {
- llwarns << "Preedit and selection!" << llendl;
- deselect();
- }
-
setCursorPos(mPreeditPositions.front());
removeStringNoUndo(mCursorPos, mPreeditPositions.back() - mCursorPos);
insertStringNoUndo(mCursorPos, mPreeditOverwrittenWString);
@@ -2643,7 +2784,10 @@ void LLTextEditor::updatePreedit(const LLWString &preedit_string,
{
mPreeditOverwrittenWString.clear();
}
- insertStringNoUndo(insert_preedit_at, mPreeditWString);
+
+ segment_vec_t segments;
+ //pass empty segments to let "insertStringNoUndo" make new LLNormalTextSegment and insert it, if needed.
+ insertStringNoUndo(insert_preedit_at, mPreeditWString, &segments);
mPreeditStandouts = preedit_standouts;
@@ -2707,11 +2851,11 @@ BOOL LLTextEditor::getPreeditLocation(S32 query_offset, LLCoordGL *coord, LLRect
const LLWString textString(getWText());
const llwchar * const text = textString.c_str();
- const S32 line_height = mDefaultFont->getLineHeight();
+ const S32 line_height = mFont->getLineHeight();
if (coord)
{
- const S32 query_x = mVisibleTextRect.mLeft + mDefaultFont->getWidth(text, current_line_start, query - current_line_start);
+ const S32 query_x = mVisibleTextRect.mLeft + mFont->getWidth(text, current_line_start, query - current_line_start);
const S32 query_y = mVisibleTextRect.mTop - (current_line - first_visible_line) * line_height - line_height / 2;
S32 query_screen_x, query_screen_y;
localPointToScreen(query_x, query_y, &query_screen_x, &query_screen_y);
@@ -2723,17 +2867,17 @@ BOOL LLTextEditor::getPreeditLocation(S32 query_offset, LLCoordGL *coord, LLRect
S32 preedit_left = mVisibleTextRect.mLeft;
if (preedit_left_position > current_line_start)
{
- preedit_left += mDefaultFont->getWidth(text, current_line_start, preedit_left_position - current_line_start);
+ preedit_left += mFont->getWidth(text, current_line_start, preedit_left_position - current_line_start);
}
S32 preedit_right = mVisibleTextRect.mLeft;
if (preedit_right_position < current_line_end)
{
- preedit_right += mDefaultFont->getWidth(text, current_line_start, preedit_right_position - current_line_start);
+ preedit_right += mFont->getWidth(text, current_line_start, preedit_right_position - current_line_start);
}
else
{
- preedit_right += mDefaultFont->getWidth(text, current_line_start, current_line_end - current_line_start);
+ preedit_right += mFont->getWidth(text, current_line_start, current_line_end - current_line_start);
}
const S32 preedit_top = mVisibleTextRect.mTop - (current_line - first_visible_line) * line_height;
@@ -2810,7 +2954,7 @@ void LLTextEditor::markAsPreedit(S32 position, S32 length)
S32 LLTextEditor::getPreeditFontSize() const
{
- return llround((F32)mDefaultFont->getLineHeight() * LLUI::sGLScaleFactor.mV[VY]);
+ return llround((F32)mFont->getLineHeight() * LLUI::getScaleFactor().mV[VY]);
}
BOOL LLTextEditor::isDirty() const
@@ -2838,6 +2982,9 @@ void LLTextEditor::setKeystrokeCallback(const keystroke_signal_t::slot_type& cal
void LLTextEditor::onKeyStroke()
{
mKeystrokeSignal(this);
+
+ mSpellCheckStart = mSpellCheckEnd = -1;
+ mSpellCheckTimer.setTimerExpirySec(SPELLCHECK_DELAY);
}
//virtual
diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h
index 40821ae9fb..d3b7bc0eb7 100644..100755
--- a/indra/llui/lltexteditor.h
+++ b/indra/llui/lltexteditor.h
@@ -64,7 +64,9 @@ public:
ignore_tab,
show_line_numbers,
commit_on_focus_lost,
- show_context_menu;
+ show_context_menu,
+ enable_tooltip_paste,
+ auto_indent;
//colors
Optional<LLUIColor> default_color;
@@ -142,6 +144,8 @@ public:
virtual void selectAll();
virtual BOOL canSelectAll() const;
+ void selectByCursorPosition(S32 prev_cursor_pos, S32 next_cursor_pos);
+
virtual bool canLoadOrSaveToFile();
void selectNext(const std::string& search_text_in, BOOL case_insensitive, BOOL wrap = TRUE);
@@ -156,6 +160,11 @@ public:
BOOL isPristine() const;
BOOL allowsEmbeddedItems() const { return mAllowEmbeddedItems; }
+ // Autoreplace (formerly part of LLLineEditor)
+ typedef boost::function<void(S32&, S32&, LLWString&, S32&, const LLWString&)> autoreplace_callback_t;
+ autoreplace_callback_t mAutoreplaceCallback;
+ void setAutoreplaceCallback(autoreplace_callback_t cb) { mAutoreplaceCallback = cb; }
+
//
// Text manipulation
//
@@ -202,6 +211,8 @@ public:
void setShowContextMenu(bool show) { mShowContextMenu = show; }
bool getShowContextMenu() const { return mShowContextMenu; }
+ void setPassDelete(BOOL b) { mPassDelete = b; }
+
protected:
void showContextMenu(S32 x, S32 y);
void drawPreeditMarker();
@@ -214,8 +225,8 @@ protected:
S32 indentLine( S32 pos, S32 spaces );
void unindentLineBeforeCloseBrace();
+ virtual BOOL handleSpecialKey(const KEY key, const MASK mask);
BOOL handleNavigationKey(const KEY key, const MASK mask);
- BOOL handleSpecialKey(const KEY key, const MASK mask);
BOOL handleSelectionKey(const KEY key, const MASK mask);
BOOL handleControlKey(const KEY key, const MASK mask);
@@ -239,13 +250,14 @@ protected:
// Undoable operations
void addChar(llwchar c); // at mCursorPos
S32 addChar(S32 pos, llwchar wc);
- void addLineBreakChar();
+ void addLineBreakChar(BOOL group_together = FALSE);
S32 overwriteChar(S32 pos, llwchar wc);
void removeChar();
S32 removeChar(S32 pos);
S32 insert(S32 pos, const LLWString &wstr, bool group_with_next_op, LLTextSegmentPtr segment);
S32 remove(S32 pos, S32 length, bool group_with_next_op);
+ void focusLostHelper();
void updateAllowingLanguageInput();
BOOL hasPreeditString() const;
@@ -279,6 +291,7 @@ protected:
LLUIColor mDefaultColor;
BOOL mShowLineNumbers;
+ bool mAutoIndent;
/*virtual*/ void updateSegments();
void updateLinkSegments();
@@ -288,6 +301,8 @@ private:
// Methods
//
void pasteHelper(bool is_primary);
+ void cleanStringForPaste(LLWString & clean_string);
+ void pasteTextWithLinebreaks(LLWString & clean_string);
void drawLineNumbers();
@@ -321,6 +336,8 @@ private:
BOOL mAllowEmbeddedItems;
bool mShowContextMenu;
bool mParseOnTheFly;
+ bool mEnableTooltipPaste;
+ bool mPassDelete;
LLUUID mSourceID;
diff --git a/indra/llui/lltextparser.cpp b/indra/llui/lltextparser.cpp
index 8a85f99e0c..8a85f99e0c 100644..100755
--- a/indra/llui/lltextparser.cpp
+++ b/indra/llui/lltextparser.cpp
diff --git a/indra/llui/lltextparser.h b/indra/llui/lltextparser.h
index 400aeeb8be..400aeeb8be 100644..100755
--- a/indra/llui/lltextparser.h
+++ b/indra/llui/lltextparser.h
diff --git a/indra/llui/lltextutil.cpp b/indra/llui/lltextutil.cpp
index 4df2c3363f..4df2c3363f 100644..100755
--- a/indra/llui/lltextutil.cpp
+++ b/indra/llui/lltextutil.cpp
diff --git a/indra/llui/lltextutil.h b/indra/llui/lltextutil.h
index bf7dbb58ce..bf7dbb58ce 100644..100755
--- a/indra/llui/lltextutil.h
+++ b/indra/llui/lltextutil.h
diff --git a/indra/llui/lltextvalidate.cpp b/indra/llui/lltextvalidate.cpp
index 234e600ccd..234e600ccd 100644..100755
--- a/indra/llui/lltextvalidate.cpp
+++ b/indra/llui/lltextvalidate.cpp
diff --git a/indra/llui/lltextvalidate.h b/indra/llui/lltextvalidate.h
index 5c830d7db3..5c830d7db3 100644..100755
--- a/indra/llui/lltextvalidate.h
+++ b/indra/llui/lltextvalidate.h
diff --git a/indra/llui/lltimectrl.cpp b/indra/llui/lltimectrl.cpp
index 9ea1e8815e..9ea1e8815e 100644..100755
--- a/indra/llui/lltimectrl.cpp
+++ b/indra/llui/lltimectrl.cpp
diff --git a/indra/llui/lltimectrl.h b/indra/llui/lltimectrl.h
index b5f268c76a..b5f268c76a 100644..100755
--- a/indra/llui/lltimectrl.h
+++ b/indra/llui/lltimectrl.h
diff --git a/indra/llui/lltoggleablemenu.cpp b/indra/llui/lltoggleablemenu.cpp
index d29260750f..00d52fe10d 100644..100755
--- a/indra/llui/lltoggleablemenu.cpp
+++ b/indra/llui/lltoggleablemenu.cpp
@@ -57,7 +57,9 @@ void LLToggleableMenu::handleVisibilityChange (BOOL curVisibilityIn)
S32 x,y;
LLUI::getMousePositionLocal(LLUI::getRootView(), &x, &y);
- if (!curVisibilityIn && mButtonRect.pointInRect(x, y))
+ // STORM-1879: also check MouseCapture to see if the button was really
+ // clicked (otherwise the VisibilityChange was triggered via keyboard shortcut)
+ if (!curVisibilityIn && mButtonRect.pointInRect(x, y) && gFocusMgr.getMouseCapture())
{
mClosedByButtonClick = true;
}
@@ -99,3 +101,8 @@ bool LLToggleableMenu::toggleVisibility()
return true;
}
+
+bool LLToggleableMenu::addChild(LLView* view, S32 tab_group)
+{
+ return addContextChild(view, tab_group);
+}
diff --git a/indra/llui/lltoggleablemenu.h b/indra/llui/lltoggleablemenu.h
index 2094bd776f..dfe70cbf54 100644..100755
--- a/indra/llui/lltoggleablemenu.h
+++ b/indra/llui/lltoggleablemenu.h
@@ -47,6 +47,8 @@ public:
virtual void handleVisibilityChange (BOOL curVisibilityIn);
+ virtual bool addChild (LLView* view, S32 tab_group = 0);
+
const LLRect& getButtonRect() const { return mButtonRect; }
// Converts the given local button rect to a screen rect
@@ -58,6 +60,8 @@ public:
// its visibility off.
bool toggleVisibility();
+ LLHandle<LLToggleableMenu> getHandle() { return getDerivedHandle<LLToggleableMenu>(); }
+
protected:
bool mClosedByButtonClick;
LLRect mButtonRect;
diff --git a/indra/llui/lltoolbar.cpp b/indra/llui/lltoolbar.cpp
index 81ea0ebf0c..6bfe113933 100644..100755
--- a/indra/llui/lltoolbar.cpp
+++ b/indra/llui/lltoolbar.cpp
@@ -117,7 +117,8 @@ LLToolBar::LLToolBar(const LLToolBar::Params& p)
mButtonEnterSignal(NULL),
mButtonLeaveSignal(NULL),
mButtonRemoveSignal(NULL),
- mDragAndDropTarget(false)
+ mDragAndDropTarget(false),
+ mCaretIcon(NULL)
{
mButtonParams[LLToolBarEnums::BTNTYPE_ICONS_WITH_TEXT] = p.button_icon_and_text;
mButtonParams[LLToolBarEnums::BTNTYPE_ICONS_ONLY] = p.button_icon;
@@ -380,7 +381,7 @@ bool LLToolBar::stopCommandInProgress(const LLCommandId& commandId)
return (command_button != NULL);
}
-bool LLToolBar::flashCommand(const LLCommandId& commandId, bool flash)
+bool LLToolBar::flashCommand(const LLCommandId& commandId, bool flash, bool force_flashing/* = false */)
{
LLButton * command_button = NULL;
@@ -390,7 +391,7 @@ bool LLToolBar::flashCommand(const LLCommandId& commandId, bool flash)
if (it != mButtonMap.end())
{
command_button = it->second;
- command_button->setFlashing(flash ? TRUE : FALSE);
+ command_button->setFlashing((BOOL)(flash),(BOOL)(force_flashing));
}
}
@@ -652,7 +653,6 @@ void LLToolBar::updateLayoutAsNeeded()
S32 max_row_length = 0;
S32 max_length;
- S32 max_total_girth;
S32 cur_start;
S32 cur_row ;
S32 row_pad_start;
@@ -663,7 +663,6 @@ void LLToolBar::updateLayoutAsNeeded()
if (orientation == LLLayoutStack::HORIZONTAL)
{
max_length = getRect().getWidth() - mPadLeft - mPadRight;
- max_total_girth = getRect().getHeight() - mPadTop - mPadBottom;
row_pad_start = mPadLeft;
row_pad_end = mPadRight;
cur_row = mPadTop;
@@ -672,7 +671,6 @@ void LLToolBar::updateLayoutAsNeeded()
else // VERTICAL
{
max_length = getRect().getHeight() - mPadTop - mPadBottom;
- max_total_girth = getRect().getWidth() - mPadLeft - mPadRight;
row_pad_start = mPadTop;
row_pad_end = mPadBottom;
cur_row = mPadLeft;
@@ -830,12 +828,16 @@ void LLToolBar::draw()
LLUI::translate((F32)getRect().mLeft, (F32)getRect().mBottom);
// Position the caret
- LLIconCtrl* caret = getChild<LLIconCtrl>("caret");
+ if (!mCaretIcon)
+ {
+ mCaretIcon = getChild<LLIconCtrl>("caret");
+ }
+
+ LLIconCtrl* caret = mCaretIcon;
caret->setVisible(FALSE);
if (mDragAndDropTarget && !mButtonCommands.empty())
{
LLRect caret_rect = caret->getRect();
- LLRect toolbar_rect = getRect();
if (getOrientation(mSideType) == LLLayoutStack::HORIZONTAL)
{
caret->setRect(LLRect(mDragx-caret_rect.getWidth()/2+1,
@@ -866,8 +868,15 @@ void LLToolBar::reshape(S32 width, S32 height, BOOL called_from_parent)
void LLToolBar::createButtons()
{
+ std::set<LLUUID> set_flashing;
+
BOOST_FOREACH(LLToolBarButton* button, mButtons)
{
+ if (button->getFlashTimer() && button->getFlashTimer()->isFlashingInProgress())
+ {
+ set_flashing.insert(button->getCommandId().uuid());
+ }
+
if (mButtonRemoveSignal)
{
(*mButtonRemoveSignal)(button);
@@ -890,6 +899,11 @@ void LLToolBar::createButtons()
{
(*mButtonAddSignal)(button);
}
+
+ if (set_flashing.find(button->getCommandId().uuid()) != set_flashing.end())
+ {
+ button->setFlashing(true);
+ }
}
mNeedsLayout = true;
}
@@ -914,6 +928,9 @@ LLToolBarButton* LLToolBar::createButton(const LLCommandId& id)
button_p.label = LLTrans::getString(commandp->labelRef());
button_p.tool_tip = LLTrans::getString(commandp->tooltipRef());
button_p.image_overlay = LLUI::getUIImage(commandp->icon());
+ button_p.image_hover_unselected = LLUI::getUIImage(commandp->hoverIconUnselected());
+ button_p.image_hover_selected = LLUI::getUIImage(commandp->hoverIconSelected());
+ button_p.button_flash_enable = commandp->isFlashingAllowed();
button_p.overwriteFrom(mButtonParams[mButtonType]);
LLToolBarButton* button = LLUICtrlFactory::create<LLToolBarButton>(button_p);
@@ -1040,10 +1057,9 @@ BOOL LLToolBar::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
// Convert drag position into insert position and rank
if (!isReadOnly() && handled && !drop)
{
- LLInventoryItem* inv_item = (LLInventoryItem*)cargo_data;
- LLAssetType::EType type = inv_item->getType();
- if (type == LLAssetType::AT_WIDGET)
+ if (cargo_type == DAD_WIDGET)
{
+ LLInventoryItem* inv_item = (LLInventoryItem*)cargo_data;
LLCommandId dragged_command(inv_item->getUUID());
int orig_rank = getRankFromPosition(dragged_command);
mDragRank = getRankFromPosition(x, y);
diff --git a/indra/llui/lltoolbar.h b/indra/llui/lltoolbar.h
index a50c60282c..743951a41f 100644..100755
--- a/indra/llui/lltoolbar.h
+++ b/indra/llui/lltoolbar.h
@@ -37,6 +37,7 @@
class LLToolBar;
class LLToolBarButton;
+class LLIconCtrl;
typedef boost::function<void (S32 x, S32 y, LLToolBarButton* button)> tool_startdrag_callback_t;
typedef boost::function<BOOL (S32 x, S32 y, const LLUUID& uuid, LLAssetType::EType type)> tool_handledrag_callback_t;
@@ -191,7 +192,7 @@ public:
bool hasCommand(const LLCommandId& commandId) const; // is this command bound to a button in this toolbar
bool enableCommand(const LLCommandId& commandId, bool enabled); // enable/disable button bound to the specified command, if it exists in this toolbar
bool stopCommandInProgress(const LLCommandId& commandId); // stop command if it is currently active
- bool flashCommand(const LLCommandId& commandId, bool flash); // flash button associated with given command, if in this toolbar
+ bool flashCommand(const LLCommandId& commandId, bool flash, bool force_flashing = false); // flash button associated with given command, if in this toolbar
void setStartDragCallback(tool_startdrag_callback_t cb) { mStartDragItemCallback = cb; } // connects drag and drop behavior to external logic
void setHandleDragCallback(tool_handledrag_callback_t cb) { mHandleDragItemCallback = cb; }
@@ -284,6 +285,8 @@ private:
button_signal_t* mButtonRemoveSignal;
std::string mButtonTooltipSuffix;
+
+ LLIconCtrl* mCaretIcon;
};
diff --git a/indra/llui/lltooltip.cpp b/indra/llui/lltooltip.cpp
index f737d48abf..f52a3b3323 100644..100755
--- a/indra/llui/lltooltip.cpp
+++ b/indra/llui/lltooltip.cpp
@@ -288,7 +288,7 @@ void LLToolTip::initFromParams(const LLToolTip::Params& p)
mTextBox->setText(p.message());
}
- S32 text_width = llmin(p.max_width(), mTextBox->getTextPixelWidth());
+ S32 text_width = llmin(p.max_width(), mTextBox->getTextPixelWidth() + 1);
S32 text_height = mTextBox->getTextPixelHeight();
mTextBox->reshape(text_width, text_height);
if (mInfoButton)
@@ -390,6 +390,15 @@ bool LLToolTip::hasClickCallback()
return mHasClickCallback;
}
+void LLToolTip::getToolTipMessage(std::string & message)
+{
+ if (mTextBox)
+ {
+ message = mTextBox->getText();
+ }
+}
+
+
//
// LLToolTipMgr
@@ -594,5 +603,14 @@ void LLToolTipMgr::updateToolTipVisibility()
}
+// Return the current tooltip text
+void LLToolTipMgr::getToolTipMessage(std::string & message)
+{
+ if (toolTipVisible())
+ {
+ mToolTip->getToolTipMessage(message);
+ }
+}
+
// EOF
diff --git a/indra/llui/lltooltip.h b/indra/llui/lltooltip.h
index d71a944c3d..fad127fc4c 100644..100755
--- a/indra/llui/lltooltip.h
+++ b/indra/llui/lltooltip.h
@@ -105,6 +105,8 @@ public:
LLToolTip(const Params& p);
void initFromParams(const LLToolTip::Params& params);
+ void getToolTipMessage(std::string & message);
+
private:
class LLTextBox* mTextBox;
class LLButton* mInfoButton;
@@ -142,6 +144,8 @@ public:
LLRect getMouseNearRect();
void updateToolTipVisibility();
+ void getToolTipMessage(std::string & message);
+
private:
void createToolTip(const LLToolTip::Params& params);
diff --git a/indra/llxuixml/lltrans.cpp b/indra/llui/lltrans.cpp
index 5388069c24..5388069c24 100644..100755
--- a/indra/llxuixml/lltrans.cpp
+++ b/indra/llui/lltrans.cpp
diff --git a/indra/llxuixml/lltrans.h b/indra/llui/lltrans.h
index 128b51d383..128b51d383 100644..100755
--- a/indra/llxuixml/lltrans.h
+++ b/indra/llui/lltrans.h
diff --git a/indra/llui/lltransutil.cpp b/indra/llui/lltransutil.cpp
index 58fa8a0828..80d079cbc8 100644..100755
--- a/indra/llui/lltransutil.cpp
+++ b/indra/llui/lltransutil.cpp
@@ -31,15 +31,20 @@
#include "lltrans.h"
#include "lluictrlfactory.h"
#include "llxmlnode.h"
-
+#include "lldir.h"
bool LLTransUtil::parseStrings(const std::string& xml_filename, const std::set<std::string>& default_args)
{
LLXMLNodePtr root;
- BOOL success = LLUICtrlFactory::getLayeredXMLNode(xml_filename, root);
+ // Pass LLDir::ALL_SKINS to load a composite of all the individual string
+ // definitions in the default skin and the current skin. This means an
+ // individual skin can provide an xml_filename that overrides only a
+ // subset of the available string definitions; any string definition not
+ // overridden by that skin will be sought in the default skin.
+ bool success = LLUICtrlFactory::getLayeredXMLNode(xml_filename, root, LLDir::ALL_SKINS);
if (!success)
{
- llerrs << "Couldn't load string table" << llendl;
+ llerrs << "Couldn't load string table " << xml_filename << llendl;
return false;
}
@@ -54,7 +59,7 @@ bool LLTransUtil::parseLanguageStrings(const std::string& xml_filename)
if (!success)
{
- llerrs << "Couldn't load string table " << xml_filename << llendl;
+ llerrs << "Couldn't load localization table " << xml_filename << llendl;
return false;
}
diff --git a/indra/llui/lltransutil.h b/indra/llui/lltransutil.h
index 9c7cee3f6f..9c7cee3f6f 100644..100755
--- a/indra/llui/lltransutil.h
+++ b/indra/llui/lltransutil.h
diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp
index b5e27616b7..0ddb149738 100644..100755
--- a/indra/llui/llui.cpp
+++ b/indra/llui/llui.cpp
@@ -39,6 +39,7 @@
#include "llrect.h"
#include "lldir.h"
#include "llgl.h"
+#include "llsd.h"
// Project includes
#include "llcommandmanager.h"
@@ -69,15 +70,13 @@
//
// Globals
//
-const LLColor4 UI_VERTEX_COLOR(1.f, 1.f, 1.f, 1.f);
// Language for UI construction
std::map<std::string, std::string> gTranslation;
std::list<std::string> gUntranslated;
/*static*/ LLUI::settings_map_t LLUI::sSettingGroups;
-/*static*/ LLImageProviderInterface* LLUI::sImageProvider = NULL;
/*static*/ LLUIAudioCallback LLUI::sAudioCallback = NULL;
-/*static*/ LLVector2 LLUI::sGLScaleFactor(1.f, 1.f);
+/*static*/ LLUIAudioCallback LLUI::sDeferredAudioCallback = NULL;
/*static*/ LLWindow* LLUI::sWindow = NULL;
/*static*/ LLView* LLUI::sRootView = NULL;
/*static*/ BOOL LLUI::sDirty = FALSE;
@@ -101,16 +100,18 @@ static LLDefaultChildRegistry::Register<LLToolBar> register_toolbar("toolbar");
//
// Functions
//
-void make_ui_sound(const char* namep)
+
+LLUUID find_ui_sound(const char * namep)
{
std::string name = ll_safe_string(namep);
+ LLUUID uuid = LLUUID(NULL);
if (!LLUI::sSettingGroups["config"]->controlExists(name))
{
llwarns << "tried to make UI sound for unknown sound name: " << name << llendl;
}
else
{
- LLUUID uuid(LLUI::sSettingGroups["config"]->getString(name));
+ uuid = LLUUID(LLUI::sSettingGroups["config"]->getString(name));
if (uuid.isNull())
{
if (LLUI::sSettingGroups["config"]->getString(name) == LLUUID::null.asString())
@@ -124,7 +125,6 @@ void make_ui_sound(const char* namep)
{
llwarns << "UI sound named: " << name << " does not translate to a valid uuid" << llendl;
}
-
}
else if (LLUI::sAudioCallback != NULL)
{
@@ -132,1493 +132,38 @@ void make_ui_sound(const char* namep)
{
llinfos << "UI sound name: " << name << llendl;
}
- LLUI::sAudioCallback(uuid);
- }
- }
-}
-
-BOOL ui_point_in_rect(S32 x, S32 y, S32 left, S32 top, S32 right, S32 bottom)
-{
- if (x < left || right < x) return FALSE;
- if (y < bottom || top < y) return FALSE;
- return TRUE;
-}
-
-
-// Puts GL into 2D drawing mode by turning off lighting, setting to an
-// orthographic projection, etc.
-void gl_state_for_2d(S32 width, S32 height)
-{
- stop_glerror();
- F32 window_width = (F32) width;//gViewerWindow->getWindowWidth();
- F32 window_height = (F32) height;//gViewerWindow->getWindowHeight();
-
- gGL.matrixMode(LLRender::MM_PROJECTION);
- gGL.loadIdentity();
- gGL.ortho(0.0f, llmax(window_width, 1.f), 0.0f, llmax(window_height,1.f), -1.0f, 1.0f);
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.loadIdentity();
- stop_glerror();
-}
-
-
-void gl_draw_x(const LLRect& rect, const LLColor4& color)
-{
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
- gGL.color4fv( color.mV );
-
- gGL.begin( LLRender::LINES );
- gGL.vertex2i( rect.mLeft, rect.mTop );
- gGL.vertex2i( rect.mRight, rect.mBottom );
- gGL.vertex2i( rect.mLeft, rect.mBottom );
- gGL.vertex2i( rect.mRight, rect.mTop );
- gGL.end();
-}
-
-
-void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &color, S32 pixel_offset, BOOL filled)
-{
- gGL.color4fv(color.mV);
- gl_rect_2d_offset_local(left, top, right, bottom, pixel_offset, filled);
-}
-
-void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, S32 pixel_offset, BOOL filled)
-{
- gGL.pushUIMatrix();
- left += LLFontGL::sCurOrigin.mX;
- right += LLFontGL::sCurOrigin.mX;
- bottom += LLFontGL::sCurOrigin.mY;
- top += LLFontGL::sCurOrigin.mY;
-
- gGL.loadUIIdentity();
- gl_rect_2d(llfloor((F32)left * LLUI::sGLScaleFactor.mV[VX]) - pixel_offset,
- llfloor((F32)top * LLUI::sGLScaleFactor.mV[VY]) + pixel_offset,
- llfloor((F32)right * LLUI::sGLScaleFactor.mV[VX]) + pixel_offset,
- llfloor((F32)bottom * LLUI::sGLScaleFactor.mV[VY]) - pixel_offset,
- filled);
- gGL.popUIMatrix();
-}
-
-
-void gl_rect_2d(S32 left, S32 top, S32 right, S32 bottom, BOOL filled )
-{
- stop_glerror();
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
- // Counterclockwise quad will face the viewer
- if( filled )
- {
- gGL.begin( LLRender::QUADS );
- gGL.vertex2i(left, top);
- gGL.vertex2i(left, bottom);
- gGL.vertex2i(right, bottom);
- gGL.vertex2i(right, top);
- gGL.end();
- }
- else
- {
- if( gGLManager.mATIOffsetVerticalLines )
- {
- // Work around bug in ATI driver: vertical lines are offset by (-1,-1)
- gGL.begin( LLRender::LINES );
-
- // Verticals
- gGL.vertex2i(left + 1, top);
- gGL.vertex2i(left + 1, bottom);
-
- gGL.vertex2i(right, bottom);
- gGL.vertex2i(right, top);
-
- // Horizontals
- top--;
- right--;
- gGL.vertex2i(left, bottom);
- gGL.vertex2i(right, bottom);
-
- gGL.vertex2i(left, top);
- gGL.vertex2i(right, top);
- gGL.end();
- }
- else
- {
- top--;
- right--;
- gGL.begin( LLRender::LINE_STRIP );
- gGL.vertex2i(left, top);
- gGL.vertex2i(left, bottom);
- gGL.vertex2i(right, bottom);
- gGL.vertex2i(right, top);
- gGL.vertex2i(left, top);
- gGL.end();
}
}
- stop_glerror();
-}
-
-void gl_rect_2d(S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &color, BOOL filled )
-{
- gGL.color4fv( color.mV );
- gl_rect_2d( left, top, right, bottom, filled );
-}
-
-
-void gl_rect_2d( const LLRect& rect, const LLColor4& color, BOOL filled )
-{
- gGL.color4fv( color.mV );
- gl_rect_2d( rect.mLeft, rect.mTop, rect.mRight, rect.mBottom, filled );
-}
-
-// Given a rectangle on the screen, draws a drop shadow _outside_
-// the right and bottom edges of it. Along the right it has width "lines"
-// and along the bottom it has height "lines".
-void gl_drop_shadow(S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &start_color, S32 lines)
-{
- stop_glerror();
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
- // HACK: Overlap with the rectangle by a single pixel.
- right--;
- bottom++;
- lines++;
-
- LLColor4 end_color = start_color;
- end_color.mV[VALPHA] = 0.f;
-
- gGL.begin(LLRender::QUADS);
-
- // Right edge, CCW faces screen
- gGL.color4fv(start_color.mV);
- gGL.vertex2i(right, top-lines);
- gGL.vertex2i(right, bottom);
- gGL.color4fv(end_color.mV);
- gGL.vertex2i(right+lines, bottom);
- gGL.vertex2i(right+lines, top-lines);
-
- // Bottom edge, CCW faces screen
- gGL.color4fv(start_color.mV);
- gGL.vertex2i(right, bottom);
- gGL.vertex2i(left+lines, bottom);
- gGL.color4fv(end_color.mV);
- gGL.vertex2i(left+lines, bottom-lines);
- gGL.vertex2i(right, bottom-lines);
-
- // bottom left Corner
- gGL.color4fv(start_color.mV);
- gGL.vertex2i(left+lines, bottom);
- gGL.color4fv(end_color.mV);
- gGL.vertex2i(left, bottom);
- // make the bottom left corner not sharp
- gGL.vertex2i(left+1, bottom-lines+1);
- gGL.vertex2i(left+lines, bottom-lines);
-
- // bottom right corner
- gGL.color4fv(start_color.mV);
- gGL.vertex2i(right, bottom);
- gGL.color4fv(end_color.mV);
- gGL.vertex2i(right, bottom-lines);
- // make the rightmost corner not sharp
- gGL.vertex2i(right+lines-1, bottom-lines+1);
- gGL.vertex2i(right+lines, bottom);
-
- // top right corner
- gGL.color4fv(start_color.mV);
- gGL.vertex2i( right, top-lines );
- gGL.color4fv(end_color.mV);
- gGL.vertex2i( right+lines, top-lines );
- // make the corner not sharp
- gGL.vertex2i( right+lines-1, top-1 );
- gGL.vertex2i( right, top );
-
- gGL.end();
- stop_glerror();
-}
-
-void gl_line_2d(S32 x1, S32 y1, S32 x2, S32 y2 )
-{
- // Work around bug in ATI driver: vertical lines are offset by (-1,-1)
- if( (x1 == x2) && gGLManager.mATIOffsetVerticalLines )
- {
- x1++;
- x2++;
- y1++;
- y2++;
- }
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
- gGL.begin(LLRender::LINES);
- gGL.vertex2i(x1, y1);
- gGL.vertex2i(x2, y2);
- gGL.end();
+ return uuid;
}
-void gl_line_2d(S32 x1, S32 y1, S32 x2, S32 y2, const LLColor4 &color )
-{
- // Work around bug in ATI driver: vertical lines are offset by (-1,-1)
- if( (x1 == x2) && gGLManager.mATIOffsetVerticalLines )
- {
- x1++;
- x2++;
- y1++;
- y2++;
- }
-
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
- gGL.color4fv( color.mV );
-
- gGL.begin(LLRender::LINES);
- gGL.vertex2i(x1, y1);
- gGL.vertex2i(x2, y2);
- gGL.end();
-}
-
-void gl_triangle_2d(S32 x1, S32 y1, S32 x2, S32 y2, S32 x3, S32 y3, const LLColor4& color, BOOL filled)
-{
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
- gGL.color4fv(color.mV);
-
- if (filled)
- {
- gGL.begin(LLRender::TRIANGLES);
- }
- else
- {
- gGL.begin(LLRender::LINE_LOOP);
- }
- gGL.vertex2i(x1, y1);
- gGL.vertex2i(x2, y2);
- gGL.vertex2i(x3, y3);
- gGL.end();
-}
-
-void gl_corners_2d(S32 left, S32 top, S32 right, S32 bottom, S32 length, F32 max_frac)
-{
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
- length = llmin((S32)(max_frac*(right - left)), length);
- length = llmin((S32)(max_frac*(top - bottom)), length);
- gGL.begin(LLRender::LINES);
- gGL.vertex2i(left, top);
- gGL.vertex2i(left + length, top);
-
- gGL.vertex2i(left, top);
- gGL.vertex2i(left, top - length);
-
- gGL.vertex2i(left, bottom);
- gGL.vertex2i(left + length, bottom);
-
- gGL.vertex2i(left, bottom);
- gGL.vertex2i(left, bottom + length);
-
- gGL.vertex2i(right, top);
- gGL.vertex2i(right - length, top);
-
- gGL.vertex2i(right, top);
- gGL.vertex2i(right, top - length);
-
- gGL.vertex2i(right, bottom);
- gGL.vertex2i(right - length, bottom);
-
- gGL.vertex2i(right, bottom);
- gGL.vertex2i(right, bottom + length);
- gGL.end();
-}
-
-
-void gl_draw_image( S32 x, S32 y, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect )
-{
- if (NULL == image)
- {
- llwarns << "image == NULL; aborting function" << llendl;
- return;
- }
- gl_draw_scaled_rotated_image( x, y, image->getWidth(0), image->getHeight(0), 0.f, image, color, uv_rect );
-}
-
-void gl_draw_scaled_image(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect)
-{
- if (NULL == image)
- {
- llwarns << "image == NULL; aborting function" << llendl;
- return;
- }
- gl_draw_scaled_rotated_image( x, y, width, height, 0.f, image, color, uv_rect );
-}
-
-void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 border_width, S32 border_height, S32 width, S32 height, LLTexture* image, const LLColor4& color, BOOL solid_color, const LLRectf& uv_rect)
-{
- if (NULL == image)
- {
- llwarns << "image == NULL; aborting function" << llendl;
- return;
- }
-
- // scale screen size of borders down
- F32 border_width_fraction = (F32)border_width / (F32)image->getWidth(0);
- F32 border_height_fraction = (F32)border_height / (F32)image->getHeight(0);
-
- LLRectf scale_rect(border_width_fraction, 1.f - border_height_fraction, 1.f - border_width_fraction, border_height_fraction);
- gl_draw_scaled_image_with_border(x, y, width, height, image, color, solid_color, uv_rect, scale_rect);
-}
-
-void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color, BOOL solid_color, const LLRectf& uv_outer_rect, const LLRectf& center_rect)
-{
- stop_glerror();
-
- if (NULL == image)
- {
- llwarns << "image == NULL; aborting function" << llendl;
- return;
- }
-
- // add in offset of current image to current UI translation
- const LLVector3 ui_scale = gGL.getUIScale();
- const LLVector3 ui_translation = (gGL.getUITranslation() + LLVector3(x, y, 0.f)).scaledVec(ui_scale);
-
- F32 uv_width = uv_outer_rect.getWidth();
- F32 uv_height = uv_outer_rect.getHeight();
-
- // shrink scaling region to be proportional to clipped image region
- LLRectf uv_center_rect(
- uv_outer_rect.mLeft + (center_rect.mLeft * uv_width),
- uv_outer_rect.mBottom + (center_rect.mTop * uv_height),
- uv_outer_rect.mLeft + (center_rect.mRight * uv_width),
- uv_outer_rect.mBottom + (center_rect.mBottom * uv_height));
-
- F32 image_width = image->getWidth(0);
- F32 image_height = image->getHeight(0);
-
- S32 image_natural_width = llround(image_width * uv_width);
- S32 image_natural_height = llround(image_height * uv_height);
-
- LLRectf draw_center_rect( uv_center_rect.mLeft * image_width,
- uv_center_rect.mTop * image_height,
- uv_center_rect.mRight * image_width,
- uv_center_rect.mBottom * image_height);
-
- { // scale fixed region of image to drawn region
- draw_center_rect.mRight += width - image_natural_width;
- draw_center_rect.mTop += height - image_natural_height;
-
- F32 border_shrink_width = llmax(0.f, draw_center_rect.mLeft - draw_center_rect.mRight);
- F32 border_shrink_height = llmax(0.f, draw_center_rect.mBottom - draw_center_rect.mTop);
-
- F32 shrink_width_ratio = center_rect.getWidth() == 1.f ? 0.f : border_shrink_width / ((F32)image_natural_width * (1.f - center_rect.getWidth()));
- F32 shrink_height_ratio = center_rect.getHeight() == 1.f ? 0.f : border_shrink_height / ((F32)image_natural_height * (1.f - center_rect.getHeight()));
-
- F32 shrink_scale = 1.f - llmax(shrink_width_ratio, shrink_height_ratio);
-
- draw_center_rect.mLeft = llround(ui_translation.mV[VX] + (F32)draw_center_rect.mLeft * shrink_scale * ui_scale.mV[VX]);
- draw_center_rect.mTop = llround(ui_translation.mV[VY] + lerp((F32)height, (F32)draw_center_rect.mTop, shrink_scale) * ui_scale.mV[VY]);
- draw_center_rect.mRight = llround(ui_translation.mV[VX] + lerp((F32)width, (F32)draw_center_rect.mRight, shrink_scale) * ui_scale.mV[VX]);
- draw_center_rect.mBottom = llround(ui_translation.mV[VY] + (F32)draw_center_rect.mBottom * shrink_scale * ui_scale.mV[VY]);
- }
-
- LLRectf draw_outer_rect(ui_translation.mV[VX],
- ui_translation.mV[VY] + height * ui_scale.mV[VY],
- ui_translation.mV[VX] + width * ui_scale.mV[VX],
- ui_translation.mV[VY]);
-
- LLGLSUIDefault gls_ui;
-
- if (solid_color)
- {
- if (LLGLSLShader::sNoFixedFunction)
- {
- gSolidColorProgram.bind();
- }
- else
- {
- gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_PREV_COLOR);
- gGL.getTexUnit(0)->setTextureAlphaBlend(LLTexUnit::TBO_MULT, LLTexUnit::TBS_TEX_ALPHA, LLTexUnit::TBS_VERT_ALPHA);
- }
- }
-
- gGL.getTexUnit(0)->bind(image, true);
-
- gGL.color4fv(color.mV);
-
- const S32 NUM_VERTICES = 9 * 4; // 9 quads
- LLVector2 uv[NUM_VERTICES];
- LLVector3 pos[NUM_VERTICES];
-
- S32 index = 0;
-
- gGL.begin(LLRender::QUADS);
- {
- // draw bottom left
- uv[index] = LLVector2(uv_outer_rect.mLeft, uv_outer_rect.mBottom);
- pos[index] = LLVector3(draw_outer_rect.mLeft, draw_outer_rect.mBottom, 0.f);
- index++;
-
- uv[index] = LLVector2(uv_center_rect.mLeft, uv_outer_rect.mBottom);
- pos[index] = LLVector3(draw_center_rect.mLeft, draw_outer_rect.mBottom, 0.f);
- index++;
-
- uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mBottom);
- pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f);
- index++;
-
- uv[index] = LLVector2(uv_outer_rect.mLeft, uv_center_rect.mBottom);
- pos[index] = LLVector3(draw_outer_rect.mLeft, draw_center_rect.mBottom, 0.f);
- index++;
-
- // draw bottom middle
- uv[index] = LLVector2(uv_center_rect.mLeft, uv_outer_rect.mBottom);
- pos[index] = LLVector3(draw_center_rect.mLeft, draw_outer_rect.mBottom, 0.f);
- index++;
-
- uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mBottom);
- pos[index] = LLVector3(draw_center_rect.mRight, draw_outer_rect.mBottom, 0.f);
- index++;
-
- uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mBottom);
- pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f);
- index++;
-
- uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mBottom);
- pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f);
- index++;
-
- // draw bottom right
- uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mBottom);
- pos[index] = LLVector3(draw_center_rect.mRight, draw_outer_rect.mBottom, 0.f);
- index++;
-
- uv[index] = LLVector2(uv_outer_rect.mRight, uv_outer_rect.mBottom);
- pos[index] = LLVector3(draw_outer_rect.mRight, draw_outer_rect.mBottom, 0.f);
- index++;
-
- uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mBottom);
- pos[index] = LLVector3(draw_outer_rect.mRight, draw_center_rect.mBottom, 0.f);
- index++;
-
- uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mBottom);
- pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f);
- index++;
-
- // draw left
- uv[index] = LLVector2(uv_outer_rect.mLeft, uv_center_rect.mBottom);
- pos[index] = LLVector3(draw_outer_rect.mLeft, draw_center_rect.mBottom, 0.f);
- index++;
-
- uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mBottom);
- pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f);
- index++;
-
- uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mTop);
- pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f);
- index++;
-
- uv[index] = LLVector2(uv_outer_rect.mLeft, uv_center_rect.mTop);
- pos[index] = LLVector3(draw_outer_rect.mLeft, draw_center_rect.mTop, 0.f);
- index++;
-
- // draw middle
- uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mBottom);
- pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f);
- index++;
-
- uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mBottom);
- pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f);
- index++;
-
- uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mTop);
- pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mTop, 0.f);
- index++;
-
- uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mTop);
- pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f);
- index++;
-
- // draw right
- uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mBottom);
- pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f);
- index++;
-
- uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mBottom);
- pos[index] = LLVector3(draw_outer_rect.mRight, draw_center_rect.mBottom, 0.f);
- index++;
-
- uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mTop);
- pos[index] = LLVector3(draw_outer_rect.mRight, draw_center_rect.mTop, 0.f);
- index++;
-
- uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mTop);
- pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mTop, 0.f);
- index++;
-
- // draw top left
- uv[index] = LLVector2(uv_outer_rect.mLeft, uv_center_rect.mTop);
- pos[index] = LLVector3(draw_outer_rect.mLeft, draw_center_rect.mTop, 0.f);
- index++;
-
- uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mTop);
- pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f);
- index++;
-
- uv[index] = LLVector2(uv_center_rect.mLeft, uv_outer_rect.mTop);
- pos[index] = LLVector3(draw_center_rect.mLeft, draw_outer_rect.mTop, 0.f);
- index++;
-
- uv[index] = LLVector2(uv_outer_rect.mLeft, uv_outer_rect.mTop);
- pos[index] = LLVector3(draw_outer_rect.mLeft, draw_outer_rect.mTop, 0.f);
- index++;
-
- // draw top middle
- uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mTop);
- pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f);
- index++;
-
- uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mTop);
- pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mTop, 0.f);
- index++;
-
- uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mTop);
- pos[index] = LLVector3(draw_center_rect.mRight, draw_outer_rect.mTop, 0.f);
- index++;
-
- uv[index] = LLVector2(uv_center_rect.mLeft, uv_outer_rect.mTop);
- pos[index] = LLVector3(draw_center_rect.mLeft, draw_outer_rect.mTop, 0.f);
- index++;
-
- // draw top right
- uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mTop);
- pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mTop, 0.f);
- index++;
-
- uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mTop);
- pos[index] = LLVector3(draw_outer_rect.mRight, draw_center_rect.mTop, 0.f);
- index++;
-
- uv[index] = LLVector2(uv_outer_rect.mRight, uv_outer_rect.mTop);
- pos[index] = LLVector3(draw_outer_rect.mRight, draw_outer_rect.mTop, 0.f);
- index++;
-
- uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mTop);
- pos[index] = LLVector3(draw_center_rect.mRight, draw_outer_rect.mTop, 0.f);
- index++;
-
- gGL.vertexBatchPreTransformed(pos, uv, NUM_VERTICES);
- }
- gGL.end();
-
- if (solid_color)
- {
- if (LLGLSLShader::sNoFixedFunction)
- {
- gUIProgram.bind();
- }
- else
- {
- gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
- }
- }
-}
-
-void gl_draw_rotated_image(S32 x, S32 y, F32 degrees, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect)
-{
- gl_draw_scaled_rotated_image( x, y, image->getWidth(0), image->getHeight(0), degrees, image, color, uv_rect );
-}
-
-void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degrees, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect)
-{
- if (NULL == image)
- {
- llwarns << "image == NULL; aborting function" << llendl;
- return;
- }
-
- LLGLSUIDefault gls_ui;
-
-
- gGL.getTexUnit(0)->bind(image, true);
-
- gGL.color4fv(color.mV);
-
- if (degrees == 0.f)
- {
- const S32 NUM_VERTICES = 4; // 9 quads
- LLVector2 uv[NUM_VERTICES];
- LLVector3 pos[NUM_VERTICES];
-
- gGL.begin(LLRender::QUADS);
- {
- LLVector3 ui_scale = gGL.getUIScale();
- LLVector3 ui_translation = gGL.getUITranslation();
- ui_translation.mV[VX] += x;
- ui_translation.mV[VY] += y;
- ui_translation.scaleVec(ui_scale);
- S32 index = 0;
- S32 scaled_width = llround(width * ui_scale.mV[VX]);
- S32 scaled_height = llround(height * ui_scale.mV[VY]);
-
- uv[index] = LLVector2(uv_rect.mRight, uv_rect.mTop);
- pos[index] = LLVector3(ui_translation.mV[VX] + scaled_width, ui_translation.mV[VY] + scaled_height, 0.f);
- index++;
-
- uv[index] = LLVector2(uv_rect.mLeft, uv_rect.mTop);
- pos[index] = LLVector3(ui_translation.mV[VX], ui_translation.mV[VY] + scaled_height, 0.f);
- index++;
-
- uv[index] = LLVector2(uv_rect.mLeft, uv_rect.mBottom);
- pos[index] = LLVector3(ui_translation.mV[VX], ui_translation.mV[VY], 0.f);
- index++;
-
- uv[index] = LLVector2(uv_rect.mRight, uv_rect.mBottom);
- pos[index] = LLVector3(ui_translation.mV[VX] + scaled_width, ui_translation.mV[VY], 0.f);
- index++;
-
- gGL.vertexBatchPreTransformed(pos, uv, NUM_VERTICES);
- }
- gGL.end();
- }
- else
- {
- gGL.pushUIMatrix();
- gGL.translateUI((F32)x, (F32)y, 0.f);
-
- F32 offset_x = F32(width/2);
- F32 offset_y = F32(height/2);
-
- gGL.translateUI(offset_x, offset_y, 0.f);
-
- LLMatrix3 quat(0.f, 0.f, degrees*DEG_TO_RAD);
-
- gGL.getTexUnit(0)->bind(image, true);
-
- gGL.color4fv(color.mV);
-
- gGL.begin(LLRender::QUADS);
- {
- LLVector3 v;
-
- v = LLVector3(offset_x, offset_y, 0.f) * quat;
- gGL.texCoord2f(uv_rect.mRight, uv_rect.mTop);
- gGL.vertex2f(v.mV[0], v.mV[1] );
-
- v = LLVector3(-offset_x, offset_y, 0.f) * quat;
- gGL.texCoord2f(uv_rect.mLeft, uv_rect.mTop);
- gGL.vertex2f(v.mV[0], v.mV[1] );
-
- v = LLVector3(-offset_x, -offset_y, 0.f) * quat;
- gGL.texCoord2f(uv_rect.mLeft, uv_rect.mBottom);
- gGL.vertex2f(v.mV[0], v.mV[1] );
-
- v = LLVector3(offset_x, -offset_y, 0.f) * quat;
- gGL.texCoord2f(uv_rect.mRight, uv_rect.mBottom);
- gGL.vertex2f(v.mV[0], v.mV[1] );
- }
- gGL.end();
- gGL.popUIMatrix();
- }
-}
-
-
-void gl_stippled_line_3d( const LLVector3& start, const LLVector3& end, const LLColor4& color, F32 phase )
-{
- phase = fmod(phase, 1.f);
-
- S32 shift = S32(phase * 4.f) % 4;
-
- // Stippled line
- LLGLEnable stipple(GL_LINE_STIPPLE);
-
- gGL.color4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], color.mV[VALPHA]);
-
- gGL.flush();
- glLineWidth(2.5f);
- glLineStipple(2, 0x3333 << shift);
-
- gGL.begin(LLRender::LINES);
- {
- gGL.vertex3fv( start.mV );
- gGL.vertex3fv( end.mV );
- }
- gGL.end();
-
- LLUI::setLineWidth(1.f);
-}
-
-void gl_arc_2d(F32 center_x, F32 center_y, F32 radius, S32 steps, BOOL filled, F32 start_angle, F32 end_angle)
-{
- if (end_angle < start_angle)
- {
- end_angle += F_TWO_PI;
- }
-
- gGL.pushUIMatrix();
- {
- gGL.translateUI(center_x, center_y, 0.f);
-
- // Inexact, but reasonably fast.
- F32 delta = (end_angle - start_angle) / steps;
- F32 sin_delta = sin( delta );
- F32 cos_delta = cos( delta );
- F32 x = cosf(start_angle) * radius;
- F32 y = sinf(start_angle) * radius;
-
- if (filled)
- {
- gGL.begin(LLRender::TRIANGLE_FAN);
- gGL.vertex2f(0.f, 0.f);
- // make sure circle is complete
- steps += 1;
- }
- else
- {
- gGL.begin(LLRender::LINE_STRIP);
- }
-
- while( steps-- )
- {
- // Successive rotations
- gGL.vertex2f( x, y );
- F32 x_new = x * cos_delta - y * sin_delta;
- y = x * sin_delta + y * cos_delta;
- x = x_new;
- }
- gGL.end();
- }
- gGL.popUIMatrix();
-}
-
-void gl_circle_2d(F32 center_x, F32 center_y, F32 radius, S32 steps, BOOL filled)
-{
- gGL.pushUIMatrix();
- {
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.translateUI(center_x, center_y, 0.f);
-
- // Inexact, but reasonably fast.
- F32 delta = F_TWO_PI / steps;
- F32 sin_delta = sin( delta );
- F32 cos_delta = cos( delta );
- F32 x = radius;
- F32 y = 0.f;
-
- if (filled)
- {
- gGL.begin(LLRender::TRIANGLE_FAN);
- gGL.vertex2f(0.f, 0.f);
- // make sure circle is complete
- steps += 1;
- }
- else
- {
- gGL.begin(LLRender::LINE_LOOP);
- }
-
- while( steps-- )
- {
- // Successive rotations
- gGL.vertex2f( x, y );
- F32 x_new = x * cos_delta - y * sin_delta;
- y = x * sin_delta + y * cos_delta;
- x = x_new;
- }
- gGL.end();
- }
- gGL.popUIMatrix();
-}
-
-// Renders a ring with sides (tube shape)
-void gl_deep_circle( F32 radius, F32 depth, S32 steps )
-{
- F32 x = radius;
- F32 y = 0.f;
- F32 angle_delta = F_TWO_PI / (F32)steps;
- gGL.begin( LLRender::TRIANGLE_STRIP );
- {
- S32 step = steps + 1; // An extra step to close the circle.
- while( step-- )
- {
- gGL.vertex3f( x, y, depth );
- gGL.vertex3f( x, y, 0.f );
-
- F32 x_new = x * cosf(angle_delta) - y * sinf(angle_delta);
- y = x * sinf(angle_delta) + y * cosf(angle_delta);
- x = x_new;
- }
- }
- gGL.end();
-}
-
-void gl_ring( F32 radius, F32 width, const LLColor4& center_color, const LLColor4& side_color, S32 steps, BOOL render_center )
-{
- gGL.pushUIMatrix();
- {
- gGL.translateUI(0.f, 0.f, -width / 2);
- if( render_center )
- {
- gGL.color4fv(center_color.mV);
- gGL.diffuseColor4fv(center_color.mV);
- gl_deep_circle( radius, width, steps );
- }
- else
- {
- gGL.diffuseColor4fv(side_color.mV);
- gl_washer_2d(radius, radius - width, steps, side_color, side_color);
- gGL.translateUI(0.f, 0.f, width);
- gl_washer_2d(radius - width, radius, steps, side_color, side_color);
- }
- }
- gGL.popUIMatrix();
-}
-
-// Draw gray and white checkerboard with black border
-void gl_rect_2d_checkerboard(const LLRect& rect, GLfloat alpha)
-{
- if (!LLGLSLShader::sNoFixedFunction)
- {
- // Initialize the first time this is called.
- const S32 PIXELS = 32;
- static GLubyte checkerboard[PIXELS * PIXELS];
- static BOOL first = TRUE;
- if( first )
- {
- for( S32 i = 0; i < PIXELS; i++ )
- {
- for( S32 j = 0; j < PIXELS; j++ )
- {
- checkerboard[i * PIXELS + j] = ((i & 1) ^ (j & 1)) * 0xFF;
- }
- }
- first = FALSE;
- }
-
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
- // ...white squares
- gGL.color4f( 1.f, 1.f, 1.f, alpha );
- gl_rect_2d(rect);
-
- // ...gray squares
- gGL.color4f( .7f, .7f, .7f, alpha );
- gGL.flush();
-
- glPolygonStipple( checkerboard );
-
- LLGLEnable polygon_stipple(GL_POLYGON_STIPPLE);
- gl_rect_2d(rect);
- }
- else
- { //polygon stipple is deprecated, use "Checker" texture
- LLPointer<LLUIImage> img = LLUI::getUIImage("Checker");
- gGL.getTexUnit(0)->bind(img->getImage());
- gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_WRAP);
- gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
-
- LLColor4 color(1.f, 1.f, 1.f, alpha);
- LLRectf uv_rect(0, 0, rect.getWidth()/32.f, rect.getHeight()/32.f);
-
- gl_draw_scaled_image(rect.mLeft, rect.mBottom, rect.getWidth(), rect.getHeight(),
- img->getImage(), color, uv_rect);
- }
-
- gGL.flush();
-}
-
-
-// Draws the area between two concentric circles, like
-// a doughnut or washer.
-void gl_washer_2d(F32 outer_radius, F32 inner_radius, S32 steps, const LLColor4& inner_color, const LLColor4& outer_color)
-{
- const F32 DELTA = F_TWO_PI / steps;
- const F32 SIN_DELTA = sin( DELTA );
- const F32 COS_DELTA = cos( DELTA );
-
- F32 x1 = outer_radius;
- F32 y1 = 0.f;
- F32 x2 = inner_radius;
- F32 y2 = 0.f;
-
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
- gGL.begin( LLRender::TRIANGLE_STRIP );
- {
- steps += 1; // An extra step to close the circle.
- while( steps-- )
- {
- gGL.color4fv(outer_color.mV);
- gGL.vertex2f( x1, y1 );
- gGL.color4fv(inner_color.mV);
- gGL.vertex2f( x2, y2 );
-
- F32 x1_new = x1 * COS_DELTA - y1 * SIN_DELTA;
- y1 = x1 * SIN_DELTA + y1 * COS_DELTA;
- x1 = x1_new;
-
- F32 x2_new = x2 * COS_DELTA - y2 * SIN_DELTA;
- y2 = x2 * SIN_DELTA + y2 * COS_DELTA;
- x2 = x2_new;
- }
- }
- gGL.end();
-}
-
-// Draws the area between two concentric circles, like
-// a doughnut or washer.
-void gl_washer_segment_2d(F32 outer_radius, F32 inner_radius, F32 start_radians, F32 end_radians, S32 steps, const LLColor4& inner_color, const LLColor4& outer_color)
-{
- const F32 DELTA = (end_radians - start_radians) / steps;
- const F32 SIN_DELTA = sin( DELTA );
- const F32 COS_DELTA = cos( DELTA );
-
- F32 x1 = outer_radius * cos( start_radians );
- F32 y1 = outer_radius * sin( start_radians );
- F32 x2 = inner_radius * cos( start_radians );
- F32 y2 = inner_radius * sin( start_radians );
-
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.begin( LLRender::TRIANGLE_STRIP );
- {
- steps += 1; // An extra step to close the circle.
- while( steps-- )
- {
- gGL.color4fv(outer_color.mV);
- gGL.vertex2f( x1, y1 );
- gGL.color4fv(inner_color.mV);
- gGL.vertex2f( x2, y2 );
-
- F32 x1_new = x1 * COS_DELTA - y1 * SIN_DELTA;
- y1 = x1 * SIN_DELTA + y1 * COS_DELTA;
- x1 = x1_new;
-
- F32 x2_new = x2 * COS_DELTA - y2 * SIN_DELTA;
- y2 = x2 * SIN_DELTA + y2 * COS_DELTA;
- x2 = x2_new;
- }
- }
- gGL.end();
-}
-
-void gl_rect_2d_simple_tex( S32 width, S32 height )
-{
- gGL.begin( LLRender::QUADS );
-
- gGL.texCoord2f(1.f, 1.f);
- gGL.vertex2i(width, height);
-
- gGL.texCoord2f(0.f, 1.f);
- gGL.vertex2i(0, height);
-
- gGL.texCoord2f(0.f, 0.f);
- gGL.vertex2i(0, 0);
-
- gGL.texCoord2f(1.f, 0.f);
- gGL.vertex2i(width, 0);
-
- gGL.end();
-}
-
-void gl_rect_2d_simple( S32 width, S32 height )
-{
- gGL.begin( LLRender::QUADS );
- gGL.vertex2i(width, height);
- gGL.vertex2i(0, height);
- gGL.vertex2i(0, 0);
- gGL.vertex2i(width, 0);
- gGL.end();
-}
-
-void gl_segmented_rect_2d_tex(const S32 left,
- const S32 top,
- const S32 right,
- const S32 bottom,
- const S32 texture_width,
- const S32 texture_height,
- const S32 border_size,
- const U32 edges)
-{
- S32 width = llabs(right - left);
- S32 height = llabs(top - bottom);
-
- gGL.pushUIMatrix();
-
- gGL.translateUI((F32)left, (F32)bottom, 0.f);
- LLVector2 border_uv_scale((F32)border_size / (F32)texture_width, (F32)border_size / (F32)texture_height);
-
- if (border_uv_scale.mV[VX] > 0.5f)
- {
- border_uv_scale *= 0.5f / border_uv_scale.mV[VX];
- }
- if (border_uv_scale.mV[VY] > 0.5f)
- {
- border_uv_scale *= 0.5f / border_uv_scale.mV[VY];
- }
-
- F32 border_scale = llmin((F32)border_size, (F32)width * 0.5f, (F32)height * 0.5f);
- LLVector2 border_width_left = ((edges & (~(U32)ROUNDED_RECT_RIGHT)) != 0) ? LLVector2(border_scale, 0.f) : LLVector2::zero;
- LLVector2 border_width_right = ((edges & (~(U32)ROUNDED_RECT_LEFT)) != 0) ? LLVector2(border_scale, 0.f) : LLVector2::zero;
- LLVector2 border_height_bottom = ((edges & (~(U32)ROUNDED_RECT_TOP)) != 0) ? LLVector2(0.f, border_scale) : LLVector2::zero;
- LLVector2 border_height_top = ((edges & (~(U32)ROUNDED_RECT_BOTTOM)) != 0) ? LLVector2(0.f, border_scale) : LLVector2::zero;
- LLVector2 width_vec((F32)width, 0.f);
- LLVector2 height_vec(0.f, (F32)height);
-
- gGL.begin(LLRender::QUADS);
- {
- // draw bottom left
- gGL.texCoord2f(0.f, 0.f);
- gGL.vertex2f(0.f, 0.f);
-
- gGL.texCoord2f(border_uv_scale.mV[VX], 0.f);
- gGL.vertex2fv(border_width_left.mV);
-
- gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
- gGL.vertex2fv((border_width_left + border_height_bottom).mV);
-
- gGL.texCoord2f(0.f, border_uv_scale.mV[VY]);
- gGL.vertex2fv(border_height_bottom.mV);
-
- // draw bottom middle
- gGL.texCoord2f(border_uv_scale.mV[VX], 0.f);
- gGL.vertex2fv(border_width_left.mV);
-
- gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 0.f);
- gGL.vertex2fv((width_vec - border_width_right).mV);
-
- gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
- gGL.vertex2fv((width_vec - border_width_right + border_height_bottom).mV);
-
- gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
- gGL.vertex2fv((border_width_left + border_height_bottom).mV);
-
- // draw bottom right
- gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 0.f);
- gGL.vertex2fv((width_vec - border_width_right).mV);
-
- gGL.texCoord2f(1.f, 0.f);
- gGL.vertex2fv(width_vec.mV);
-
- gGL.texCoord2f(1.f, border_uv_scale.mV[VY]);
- gGL.vertex2fv((width_vec + border_height_bottom).mV);
-
- gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
- gGL.vertex2fv((width_vec - border_width_right + border_height_bottom).mV);
-
- // draw left
- gGL.texCoord2f(0.f, border_uv_scale.mV[VY]);
- gGL.vertex2fv(border_height_bottom.mV);
-
- gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
- gGL.vertex2fv((border_width_left + border_height_bottom).mV);
-
- gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
- gGL.vertex2fv((border_width_left + height_vec - border_height_top).mV);
-
- gGL.texCoord2f(0.f, 1.f - border_uv_scale.mV[VY]);
- gGL.vertex2fv((height_vec - border_height_top).mV);
-
- // draw middle
- gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
- gGL.vertex2fv((border_width_left + border_height_bottom).mV);
-
- gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
- gGL.vertex2fv((width_vec - border_width_right + border_height_bottom).mV);
-
- gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
- gGL.vertex2fv((width_vec - border_width_right + height_vec - border_height_top).mV);
-
- gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
- gGL.vertex2fv((border_width_left + height_vec - border_height_top).mV);
-
- // draw right
- gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
- gGL.vertex2fv((width_vec - border_width_right + border_height_bottom).mV);
-
- gGL.texCoord2f(1.f, border_uv_scale.mV[VY]);
- gGL.vertex2fv((width_vec + border_height_bottom).mV);
-
- gGL.texCoord2f(1.f, 1.f - border_uv_scale.mV[VY]);
- gGL.vertex2fv((width_vec + height_vec - border_height_top).mV);
-
- gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
- gGL.vertex2fv((width_vec - border_width_right + height_vec - border_height_top).mV);
-
- // draw top left
- gGL.texCoord2f(0.f, 1.f - border_uv_scale.mV[VY]);
- gGL.vertex2fv((height_vec - border_height_top).mV);
-
- gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
- gGL.vertex2fv((border_width_left + height_vec - border_height_top).mV);
-
- gGL.texCoord2f(border_uv_scale.mV[VX], 1.f);
- gGL.vertex2fv((border_width_left + height_vec).mV);
-
- gGL.texCoord2f(0.f, 1.f);
- gGL.vertex2fv((height_vec).mV);
-
- // draw top middle
- gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
- gGL.vertex2fv((border_width_left + height_vec - border_height_top).mV);
-
- gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
- gGL.vertex2fv((width_vec - border_width_right + height_vec - border_height_top).mV);
-
- gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f);
- gGL.vertex2fv((width_vec - border_width_right + height_vec).mV);
-
- gGL.texCoord2f(border_uv_scale.mV[VX], 1.f);
- gGL.vertex2fv((border_width_left + height_vec).mV);
-
- // draw top right
- gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
- gGL.vertex2fv((width_vec - border_width_right + height_vec - border_height_top).mV);
-
- gGL.texCoord2f(1.f, 1.f - border_uv_scale.mV[VY]);
- gGL.vertex2fv((width_vec + height_vec - border_height_top).mV);
-
- gGL.texCoord2f(1.f, 1.f);
- gGL.vertex2fv((width_vec + height_vec).mV);
-
- gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f);
- gGL.vertex2fv((width_vec - border_width_right + height_vec).mV);
- }
- gGL.end();
-
- gGL.popUIMatrix();
-}
-
-//FIXME: rewrite to use scissor?
-void gl_segmented_rect_2d_fragment_tex(const S32 left,
- const S32 top,
- const S32 right,
- const S32 bottom,
- const S32 texture_width,
- const S32 texture_height,
- const S32 border_size,
- const F32 start_fragment,
- const F32 end_fragment,
- const U32 edges)
+void make_ui_sound(const char* namep)
{
- S32 width = llabs(right - left);
- S32 height = llabs(top - bottom);
-
- gGL.pushUIMatrix();
-
- gGL.translateUI((F32)left, (F32)bottom, 0.f);
- LLVector2 border_uv_scale((F32)border_size / (F32)texture_width, (F32)border_size / (F32)texture_height);
-
- if (border_uv_scale.mV[VX] > 0.5f)
- {
- border_uv_scale *= 0.5f / border_uv_scale.mV[VX];
- }
- if (border_uv_scale.mV[VY] > 0.5f)
+ LLUUID soundUUID = find_ui_sound(namep);
+ if(soundUUID.notNull())
{
- border_uv_scale *= 0.5f / border_uv_scale.mV[VY];
- }
-
- F32 border_scale = llmin((F32)border_size, (F32)width * 0.5f, (F32)height * 0.5f);
- LLVector2 border_width_left = ((edges & (~(U32)ROUNDED_RECT_RIGHT)) != 0) ? LLVector2(border_scale, 0.f) : LLVector2::zero;
- LLVector2 border_width_right = ((edges & (~(U32)ROUNDED_RECT_LEFT)) != 0) ? LLVector2(border_scale, 0.f) : LLVector2::zero;
- LLVector2 border_height_bottom = ((edges & (~(U32)ROUNDED_RECT_TOP)) != 0) ? LLVector2(0.f, border_scale) : LLVector2::zero;
- LLVector2 border_height_top = ((edges & (~(U32)ROUNDED_RECT_BOTTOM)) != 0) ? LLVector2(0.f, border_scale) : LLVector2::zero;
- LLVector2 width_vec((F32)width, 0.f);
- LLVector2 height_vec(0.f, (F32)height);
-
- F32 middle_start = border_scale / (F32)width;
- F32 middle_end = 1.f - middle_start;
-
- F32 u_min;
- F32 u_max;
- LLVector2 x_min;
- LLVector2 x_max;
-
- gGL.begin(LLRender::QUADS);
- {
- if (start_fragment < middle_start)
- {
- u_min = (start_fragment / middle_start) * border_uv_scale.mV[VX];
- u_max = llmin(end_fragment / middle_start, 1.f) * border_uv_scale.mV[VX];
- x_min = (start_fragment / middle_start) * border_width_left;
- x_max = llmin(end_fragment / middle_start, 1.f) * border_width_left;
-
- // draw bottom left
- gGL.texCoord2f(u_min, 0.f);
- gGL.vertex2fv(x_min.mV);
-
- gGL.texCoord2f(border_uv_scale.mV[VX], 0.f);
- gGL.vertex2fv(x_max.mV);
-
- gGL.texCoord2f(u_max, border_uv_scale.mV[VY]);
- gGL.vertex2fv((x_max + border_height_bottom).mV);
-
- gGL.texCoord2f(u_min, border_uv_scale.mV[VY]);
- gGL.vertex2fv((x_min + border_height_bottom).mV);
-
- // draw left
- gGL.texCoord2f(u_min, border_uv_scale.mV[VY]);
- gGL.vertex2fv((x_min + border_height_bottom).mV);
-
- gGL.texCoord2f(u_max, border_uv_scale.mV[VY]);
- gGL.vertex2fv((x_max + border_height_bottom).mV);
-
- gGL.texCoord2f(u_max, 1.f - border_uv_scale.mV[VY]);
- gGL.vertex2fv((x_max + height_vec - border_height_top).mV);
-
- gGL.texCoord2f(u_min, 1.f - border_uv_scale.mV[VY]);
- gGL.vertex2fv((x_min + height_vec - border_height_top).mV);
-
- // draw top left
- gGL.texCoord2f(u_min, 1.f - border_uv_scale.mV[VY]);
- gGL.vertex2fv((x_min + height_vec - border_height_top).mV);
-
- gGL.texCoord2f(u_max, 1.f - border_uv_scale.mV[VY]);
- gGL.vertex2fv((x_max + height_vec - border_height_top).mV);
-
- gGL.texCoord2f(u_max, 1.f);
- gGL.vertex2fv((x_max + height_vec).mV);
-
- gGL.texCoord2f(u_min, 1.f);
- gGL.vertex2fv((x_min + height_vec).mV);
- }
-
- if (end_fragment > middle_start || start_fragment < middle_end)
- {
- x_min = border_width_left + ((llclamp(start_fragment, middle_start, middle_end) - middle_start)) * width_vec;
- x_max = border_width_left + ((llclamp(end_fragment, middle_start, middle_end) - middle_start)) * width_vec;
-
- // draw bottom middle
- gGL.texCoord2f(border_uv_scale.mV[VX], 0.f);
- gGL.vertex2fv(x_min.mV);
-
- gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 0.f);
- gGL.vertex2fv((x_max).mV);
-
- gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
- gGL.vertex2fv((x_max + border_height_bottom).mV);
-
- gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
- gGL.vertex2fv((x_min + border_height_bottom).mV);
-
- // draw middle
- gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
- gGL.vertex2fv((x_min + border_height_bottom).mV);
-
- gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
- gGL.vertex2fv((x_max + border_height_bottom).mV);
-
- gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
- gGL.vertex2fv((x_max + height_vec - border_height_top).mV);
-
- gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
- gGL.vertex2fv((x_min + height_vec - border_height_top).mV);
-
- // draw top middle
- gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
- gGL.vertex2fv((x_min + height_vec - border_height_top).mV);
-
- gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
- gGL.vertex2fv((x_max + height_vec - border_height_top).mV);
-
- gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f);
- gGL.vertex2fv((x_max + height_vec).mV);
-
- gGL.texCoord2f(border_uv_scale.mV[VX], 1.f);
- gGL.vertex2fv((x_min + height_vec).mV);
- }
-
- if (end_fragment > middle_end)
- {
- u_min = (1.f - llmax(0.f, ((start_fragment - middle_end) / middle_start))) * border_uv_scale.mV[VX];
- u_max = (1.f - ((end_fragment - middle_end) / middle_start)) * border_uv_scale.mV[VX];
- x_min = width_vec - ((1.f - llmax(0.f, ((start_fragment - middle_end) / middle_start))) * border_width_right);
- x_max = width_vec - ((1.f - ((end_fragment - middle_end) / middle_start)) * border_width_right);
-
- // draw bottom right
- gGL.texCoord2f(u_min, 0.f);
- gGL.vertex2fv((x_min).mV);
-
- gGL.texCoord2f(u_max, 0.f);
- gGL.vertex2fv(x_max.mV);
-
- gGL.texCoord2f(u_max, border_uv_scale.mV[VY]);
- gGL.vertex2fv((x_max + border_height_bottom).mV);
-
- gGL.texCoord2f(u_min, border_uv_scale.mV[VY]);
- gGL.vertex2fv((x_min + border_height_bottom).mV);
-
- // draw right
- gGL.texCoord2f(u_min, border_uv_scale.mV[VY]);
- gGL.vertex2fv((x_min + border_height_bottom).mV);
-
- gGL.texCoord2f(u_max, border_uv_scale.mV[VY]);
- gGL.vertex2fv((x_max + border_height_bottom).mV);
-
- gGL.texCoord2f(u_max, 1.f - border_uv_scale.mV[VY]);
- gGL.vertex2fv((x_max + height_vec - border_height_top).mV);
-
- gGL.texCoord2f(u_min, 1.f - border_uv_scale.mV[VY]);
- gGL.vertex2fv((x_min + height_vec - border_height_top).mV);
-
- // draw top right
- gGL.texCoord2f(u_min, 1.f - border_uv_scale.mV[VY]);
- gGL.vertex2fv((x_min + height_vec - border_height_top).mV);
-
- gGL.texCoord2f(u_max, 1.f - border_uv_scale.mV[VY]);
- gGL.vertex2fv((x_max + height_vec - border_height_top).mV);
-
- gGL.texCoord2f(u_max, 1.f);
- gGL.vertex2fv((x_max + height_vec).mV);
-
- gGL.texCoord2f(u_min, 1.f);
- gGL.vertex2fv((x_min + height_vec).mV);
- }
+ LLUI::sAudioCallback(soundUUID);
}
- gGL.end();
-
- gGL.popUIMatrix();
}
-void gl_segmented_rect_3d_tex(const LLVector2& border_scale, const LLVector3& border_width,
- const LLVector3& border_height, const LLVector3& width_vec, const LLVector3& height_vec,
- const U32 edges)
+void make_ui_sound_deferred(const char* namep)
{
- LLVector3 left_border_width = ((edges & (~(U32)ROUNDED_RECT_RIGHT)) != 0) ? border_width : LLVector3::zero;
- LLVector3 right_border_width = ((edges & (~(U32)ROUNDED_RECT_LEFT)) != 0) ? border_width : LLVector3::zero;
-
- LLVector3 top_border_height = ((edges & (~(U32)ROUNDED_RECT_BOTTOM)) != 0) ? border_height : LLVector3::zero;
- LLVector3 bottom_border_height = ((edges & (~(U32)ROUNDED_RECT_TOP)) != 0) ? border_height : LLVector3::zero;
-
-
- gGL.begin(LLRender::QUADS);
+ LLUUID soundUUID = find_ui_sound(namep);
+ if(soundUUID.notNull())
{
- // draw bottom left
- gGL.texCoord2f(0.f, 0.f);
- gGL.vertex3f(0.f, 0.f, 0.f);
-
- gGL.texCoord2f(border_scale.mV[VX], 0.f);
- gGL.vertex3fv(left_border_width.mV);
-
- gGL.texCoord2f(border_scale.mV[VX], border_scale.mV[VY]);
- gGL.vertex3fv((left_border_width + bottom_border_height).mV);
-
- gGL.texCoord2f(0.f, border_scale.mV[VY]);
- gGL.vertex3fv(bottom_border_height.mV);
-
- // draw bottom middle
- gGL.texCoord2f(border_scale.mV[VX], 0.f);
- gGL.vertex3fv(left_border_width.mV);
-
- gGL.texCoord2f(1.f - border_scale.mV[VX], 0.f);
- gGL.vertex3fv((width_vec - right_border_width).mV);
-
- gGL.texCoord2f(1.f - border_scale.mV[VX], border_scale.mV[VY]);
- gGL.vertex3fv((width_vec - right_border_width + bottom_border_height).mV);
-
- gGL.texCoord2f(border_scale.mV[VX], border_scale.mV[VY]);
- gGL.vertex3fv((left_border_width + bottom_border_height).mV);
-
- // draw bottom right
- gGL.texCoord2f(1.f - border_scale.mV[VX], 0.f);
- gGL.vertex3fv((width_vec - right_border_width).mV);
-
- gGL.texCoord2f(1.f, 0.f);
- gGL.vertex3fv(width_vec.mV);
-
- gGL.texCoord2f(1.f, border_scale.mV[VY]);
- gGL.vertex3fv((width_vec + bottom_border_height).mV);
-
- gGL.texCoord2f(1.f - border_scale.mV[VX], border_scale.mV[VY]);
- gGL.vertex3fv((width_vec - right_border_width + bottom_border_height).mV);
-
- // draw left
- gGL.texCoord2f(0.f, border_scale.mV[VY]);
- gGL.vertex3fv(bottom_border_height.mV);
-
- gGL.texCoord2f(border_scale.mV[VX], border_scale.mV[VY]);
- gGL.vertex3fv((left_border_width + bottom_border_height).mV);
-
- gGL.texCoord2f(border_scale.mV[VX], 1.f - border_scale.mV[VY]);
- gGL.vertex3fv((left_border_width + height_vec - top_border_height).mV);
-
- gGL.texCoord2f(0.f, 1.f - border_scale.mV[VY]);
- gGL.vertex3fv((height_vec - top_border_height).mV);
-
- // draw middle
- gGL.texCoord2f(border_scale.mV[VX], border_scale.mV[VY]);
- gGL.vertex3fv((left_border_width + bottom_border_height).mV);
-
- gGL.texCoord2f(1.f - border_scale.mV[VX], border_scale.mV[VY]);
- gGL.vertex3fv((width_vec - right_border_width + bottom_border_height).mV);
-
- gGL.texCoord2f(1.f - border_scale.mV[VX], 1.f - border_scale.mV[VY]);
- gGL.vertex3fv((width_vec - right_border_width + height_vec - top_border_height).mV);
-
- gGL.texCoord2f(border_scale.mV[VX], 1.f - border_scale.mV[VY]);
- gGL.vertex3fv((left_border_width + height_vec - top_border_height).mV);
-
- // draw right
- gGL.texCoord2f(1.f - border_scale.mV[VX], border_scale.mV[VY]);
- gGL.vertex3fv((width_vec - right_border_width + bottom_border_height).mV);
-
- gGL.texCoord2f(1.f, border_scale.mV[VY]);
- gGL.vertex3fv((width_vec + bottom_border_height).mV);
-
- gGL.texCoord2f(1.f, 1.f - border_scale.mV[VY]);
- gGL.vertex3fv((width_vec + height_vec - top_border_height).mV);
-
- gGL.texCoord2f(1.f - border_scale.mV[VX], 1.f - border_scale.mV[VY]);
- gGL.vertex3fv((width_vec - right_border_width + height_vec - top_border_height).mV);
-
- // draw top left
- gGL.texCoord2f(0.f, 1.f - border_scale.mV[VY]);
- gGL.vertex3fv((height_vec - top_border_height).mV);
-
- gGL.texCoord2f(border_scale.mV[VX], 1.f - border_scale.mV[VY]);
- gGL.vertex3fv((left_border_width + height_vec - top_border_height).mV);
-
- gGL.texCoord2f(border_scale.mV[VX], 1.f);
- gGL.vertex3fv((left_border_width + height_vec).mV);
-
- gGL.texCoord2f(0.f, 1.f);
- gGL.vertex3fv((height_vec).mV);
-
- // draw top middle
- gGL.texCoord2f(border_scale.mV[VX], 1.f - border_scale.mV[VY]);
- gGL.vertex3fv((left_border_width + height_vec - top_border_height).mV);
-
- gGL.texCoord2f(1.f - border_scale.mV[VX], 1.f - border_scale.mV[VY]);
- gGL.vertex3fv((width_vec - right_border_width + height_vec - top_border_height).mV);
-
- gGL.texCoord2f(1.f - border_scale.mV[VX], 1.f);
- gGL.vertex3fv((width_vec - right_border_width + height_vec).mV);
-
- gGL.texCoord2f(border_scale.mV[VX], 1.f);
- gGL.vertex3fv((left_border_width + height_vec).mV);
-
- // draw top right
- gGL.texCoord2f(1.f - border_scale.mV[VX], 1.f - border_scale.mV[VY]);
- gGL.vertex3fv((width_vec - right_border_width + height_vec - top_border_height).mV);
-
- gGL.texCoord2f(1.f, 1.f - border_scale.mV[VY]);
- gGL.vertex3fv((width_vec + height_vec - top_border_height).mV);
-
- gGL.texCoord2f(1.f, 1.f);
- gGL.vertex3fv((width_vec + height_vec).mV);
-
- gGL.texCoord2f(1.f - border_scale.mV[VX], 1.f);
- gGL.vertex3fv((width_vec - right_border_width + height_vec).mV);
+ LLUI::sDeferredAudioCallback(soundUUID);
}
- gGL.end();
-
-}
-
-void gl_segmented_rect_3d_tex_top(const LLVector2& border_scale, const LLVector3& border_width, const LLVector3& border_height, const LLVector3& width_vec, const LLVector3& height_vec)
-{
- gl_segmented_rect_3d_tex(border_scale, border_width, border_height, width_vec, height_vec, ROUNDED_RECT_TOP);
}
void LLUI::initClass(const settings_map_t& settings,
LLImageProviderInterface* image_provider,
LLUIAudioCallback audio_callback,
+ LLUIAudioCallback deferred_audio_callback,
const LLVector2* scale_factor,
const std::string& language)
{
+ LLRender2D::initClass(image_provider,scale_factor);
sSettingGroups = settings;
if ((get_ptr_in_map(sSettingGroups, std::string("config")) == NULL) ||
@@ -1628,9 +173,8 @@ void LLUI::initClass(const settings_map_t& settings,
llerrs << "Failure to initialize configuration groups" << llendl;
}
- sImageProvider = image_provider;
sAudioCallback = audio_callback;
- sGLScaleFactor = (scale_factor == NULL) ? LLVector2(1.f, 1.f) : *scale_factor;
+ sDeferredAudioCallback = deferred_audio_callback;
sWindow = NULL; // set later in startup
LLFontGL::sShadowColor = LLUIColorTable::instance().getColor("ColorDropShadow");
@@ -1664,10 +208,7 @@ void LLUI::initClass(const settings_map_t& settings,
void LLUI::cleanupClass()
{
- if(sImageProvider)
- {
- sImageProvider->cleanUp();
-}
+ LLRender2D::cleanupClass();
}
void LLUI::setPopupFuncs(const add_popup_t& add_popup, const remove_popup_t& remove_popup, const clear_popups_t& clear_popups)
@@ -1691,60 +232,12 @@ void LLUI::dirtyRect(LLRect rect)
}
}
-
-//static
-void LLUI::translate(F32 x, F32 y, F32 z)
-{
- gGL.translateUI(x,y,z);
- LLFontGL::sCurOrigin.mX += (S32) x;
- LLFontGL::sCurOrigin.mY += (S32) y;
- LLFontGL::sCurDepth += z;
-}
-
-//static
-void LLUI::pushMatrix()
-{
- gGL.pushUIMatrix();
- LLFontGL::sOriginStack.push_back(std::make_pair(LLFontGL::sCurOrigin, LLFontGL::sCurDepth));
-}
-
-//static
-void LLUI::popMatrix()
-{
- gGL.popUIMatrix();
- LLFontGL::sCurOrigin = LLFontGL::sOriginStack.back().first;
- LLFontGL::sCurDepth = LLFontGL::sOriginStack.back().second;
- LLFontGL::sOriginStack.pop_back();
-}
-
-//static
-void LLUI::loadIdentity()
-{
- gGL.loadUIIdentity();
- LLFontGL::sCurOrigin.mX = 0;
- LLFontGL::sCurOrigin.mY = 0;
- LLFontGL::sCurDepth = 0.f;
-}
-
-//static
-void LLUI::setScaleFactor(const LLVector2 &scale_factor)
-{
- sGLScaleFactor = scale_factor;
-}
-
-//static
-void LLUI::setLineWidth(F32 width)
-{
- gGL.flush();
- glLineWidth(width * lerp(sGLScaleFactor.mV[VX], sGLScaleFactor.mV[VY], 0.5f));
-}
-
//static
void LLUI::setMousePositionScreen(S32 x, S32 y)
{
S32 screen_x, screen_y;
- screen_x = llround((F32)x * sGLScaleFactor.mV[VX]);
- screen_y = llround((F32)y * sGLScaleFactor.mV[VY]);
+ screen_x = llround((F32)x * getScaleFactor().mV[VX]);
+ screen_y = llround((F32)y * getScaleFactor().mV[VY]);
LLView::getWindow()->setCursorPosition(LLCoordGL(screen_x, screen_y).convert());
}
@@ -1755,8 +248,8 @@ void LLUI::getMousePositionScreen(S32 *x, S32 *y)
LLCoordWindow cursor_pos_window;
getWindow()->getCursorPosition(&cursor_pos_window);
LLCoordGL cursor_pos_gl(cursor_pos_window.convert());
- *x = llround((F32)cursor_pos_gl.mX / sGLScaleFactor.mV[VX]);
- *y = llround((F32)cursor_pos_gl.mY / sGLScaleFactor.mV[VX]);
+ *x = llround((F32)cursor_pos_gl.mX / getScaleFactor().mV[VX]);
+ *y = llround((F32)cursor_pos_gl.mY / getScaleFactor().mV[VX]);
}
//static
@@ -1832,88 +325,37 @@ struct Paths : public LLInitParam::Block<Paths>
{}
};
-//static
-void LLUI::setupPaths()
-{
- std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_SKINS, "paths.xml");
-
- LLXMLNodePtr root;
- BOOL success = LLXMLNode::parseFile(filename, root, NULL);
- Paths paths;
-
- if(success)
- {
- LLXUIParser parser;
- parser.readXUI(root, paths, filename);
- }
- sXUIPaths.clear();
-
- if (success && paths.validateBlock())
- {
- LLStringUtil::format_map_t path_args;
- path_args["[LANGUAGE]"] = LLUI::getLanguage();
-
- for (LLInitParam::ParamIterator<Directory>::const_iterator it = paths.directories.begin(),
- end_it = paths.directories.end();
- it != end_it;
- ++it)
- {
- std::string path_val_ui;
- for (LLInitParam::ParamIterator<SubDir>::const_iterator subdir_it = it->subdirs.begin(),
- subdir_end_it = it->subdirs.end();
- subdir_it != subdir_end_it;)
- {
- path_val_ui += subdir_it->value();
- if (++subdir_it != subdir_end_it)
- path_val_ui += gDirUtilp->getDirDelimiter();
- }
- LLStringUtil::format(path_val_ui, path_args);
- if (std::find(sXUIPaths.begin(), sXUIPaths.end(), path_val_ui) == sXUIPaths.end())
- {
- sXUIPaths.push_back(path_val_ui);
- }
-
- }
- }
- else // parsing failed
- {
- std::string slash = gDirUtilp->getDirDelimiter();
- std::string dir = "xui" + slash + "en";
- llwarns << "XUI::config file unable to open: " << filename << llendl;
- sXUIPaths.push_back(dir);
- }
-}
-
//static
std::string LLUI::locateSkin(const std::string& filename)
{
- std::string slash = gDirUtilp->getDirDelimiter();
std::string found_file = filename;
- if (!gDirUtilp->fileExists(found_file))
+ if (gDirUtilp->fileExists(found_file))
{
- found_file = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, filename); // Should be CUSTOM_SKINS?
+ return found_file;
}
- if (sSettingGroups["config"] && sSettingGroups["config"]->controlExists("Language"))
+
+ found_file = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, filename); // Should be CUSTOM_SKINS?
+ if (gDirUtilp->fileExists(found_file))
{
- if (!gDirUtilp->fileExists(found_file))
- {
- std::string localization = getLanguage();
- std::string local_skin = "xui" + slash + localization + slash + filename;
- found_file = gDirUtilp->findSkinnedFilename(local_skin);
- }
+ return found_file;
}
- if (!gDirUtilp->fileExists(found_file))
+
+ found_file = gDirUtilp->findSkinnedFilename(LLDir::XUI, filename);
+ if (! found_file.empty())
{
- std::string local_skin = "xui" + slash + "en" + slash + filename;
- found_file = gDirUtilp->findSkinnedFilename(local_skin);
+ return found_file;
}
- if (!gDirUtilp->fileExists(found_file))
+
+ found_file = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, filename);
+ if (gDirUtilp->fileExists(found_file))
{
- found_file = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, filename);
+ return found_file;
}
- return found_file;
-}
+ LL_WARNS("LLUI") << "Can't find '" << filename
+ << "' in user settings, any skin directory or app_settings" << LL_ENDL;
+ return "";
+}
//static
LLVector2 LLUI::getWindowSize()
@@ -1921,21 +363,21 @@ LLVector2 LLUI::getWindowSize()
LLCoordWindow window_rect;
sWindow->getSize(&window_rect);
- return LLVector2(window_rect.mX / sGLScaleFactor.mV[VX], window_rect.mY / sGLScaleFactor.mV[VY]);
+ return LLVector2(window_rect.mX / getScaleFactor().mV[VX], window_rect.mY / getScaleFactor().mV[VY]);
}
//static
void LLUI::screenPointToGL(S32 screen_x, S32 screen_y, S32 *gl_x, S32 *gl_y)
{
- *gl_x = llround((F32)screen_x * sGLScaleFactor.mV[VX]);
- *gl_y = llround((F32)screen_y * sGLScaleFactor.mV[VY]);
+ *gl_x = llround((F32)screen_x * getScaleFactor().mV[VX]);
+ *gl_y = llround((F32)screen_y * getScaleFactor().mV[VY]);
}
//static
void LLUI::glPointToScreen(S32 gl_x, S32 gl_y, S32 *screen_x, S32 *screen_y)
{
- *screen_x = llround((F32)gl_x / sGLScaleFactor.mV[VX]);
- *screen_y = llround((F32)gl_y / sGLScaleFactor.mV[VY]);
+ *screen_x = llround((F32)gl_x / getScaleFactor().mV[VX]);
+ *screen_y = llround((F32)gl_y / getScaleFactor().mV[VY]);
}
//static
@@ -1952,27 +394,6 @@ void LLUI::glRectToScreen(const LLRect& gl, LLRect *screen)
glPointToScreen(gl.mRight, gl.mBottom, &screen->mRight, &screen->mBottom);
}
-//static
-LLPointer<LLUIImage> LLUI::getUIImageByID(const LLUUID& image_id, S32 priority)
-{
- if (sImageProvider)
- {
- return sImageProvider->getUIImageByID(image_id, priority);
- }
- else
- {
- return NULL;
- }
-}
-
-//static
-LLPointer<LLUIImage> LLUI::getUIImage(const std::string& name, S32 priority)
-{
- if (!name.empty() && sImageProvider)
- return sImageProvider->getUIImage(name, priority);
- else
- return NULL;
-}
LLControlGroup& LLUI::getControlControlGroup (const std::string& controlname)
{
@@ -2114,7 +535,7 @@ const LLView* LLUI::resolvePath(const LLView* context, const std::string& path)
namespace LLInitParam
{
- ParamValue<LLUIColor, TypeValues<LLUIColor> >::ParamValue(const LLUIColor& color)
+ ParamValue<LLUIColor>::ParamValue(const LLUIColor& color)
: super_t(color),
red("red"),
green("green"),
@@ -2125,7 +546,7 @@ namespace LLInitParam
updateBlockFromValue(false);
}
- void ParamValue<LLUIColor, TypeValues<LLUIColor> >::updateValueFromBlock()
+ void ParamValue<LLUIColor>::updateValueFromBlock()
{
if (control.isProvided() && !control().empty())
{
@@ -2137,7 +558,7 @@ namespace LLInitParam
}
}
- void ParamValue<LLUIColor, TypeValues<LLUIColor> >::updateBlockFromValue(bool make_block_authoritative)
+ void ParamValue<LLUIColor>::updateBlockFromValue(bool make_block_authoritative)
{
LLColor4 color = getValue();
red.set(color.mV[VRED], make_block_authoritative);
@@ -2153,7 +574,7 @@ namespace LLInitParam
&& !(b->getFontDesc() < a->getFontDesc());
}
- ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::ParamValue(const LLFontGL* fontp)
+ ParamValue<const LLFontGL*>::ParamValue(const LLFontGL* fontp)
: super_t(fontp),
name("name"),
size("size"),
@@ -2167,7 +588,7 @@ namespace LLInitParam
updateBlockFromValue(false);
}
- void ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::updateValueFromBlock()
+ void ParamValue<const LLFontGL*>::updateValueFromBlock()
{
const LLFontGL* res_fontp = LLFontGL::getFontByName(name);
if (res_fontp)
@@ -2190,7 +611,7 @@ namespace LLInitParam
}
}
- void ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::updateBlockFromValue(bool make_block_authoritative)
+ void ParamValue<const LLFontGL*>::updateBlockFromValue(bool make_block_authoritative)
{
if (getValue())
{
@@ -2200,7 +621,7 @@ namespace LLInitParam
}
}
- ParamValue<LLRect, TypeValues<LLRect> >::ParamValue(const LLRect& rect)
+ ParamValue<LLRect>::ParamValue(const LLRect& rect)
: super_t(rect),
left("left"),
top("top"),
@@ -2212,7 +633,7 @@ namespace LLInitParam
updateBlockFromValue(false);
}
- void ParamValue<LLRect, TypeValues<LLRect> >::updateValueFromBlock()
+ void ParamValue<LLRect>::updateValueFromBlock()
{
LLRect rect;
@@ -2276,7 +697,7 @@ namespace LLInitParam
updateValue(rect);
}
- void ParamValue<LLRect, TypeValues<LLRect> >::updateBlockFromValue(bool make_block_authoritative)
+ void ParamValue<LLRect>::updateBlockFromValue(bool make_block_authoritative)
{
// because of the ambiguity in specifying a rect by position and/or dimensions
// we use the lowest priority pairing so that any valid pairing in xui
@@ -2293,7 +714,7 @@ namespace LLInitParam
height.set(value.getHeight(), make_block_authoritative);
}
- ParamValue<LLCoordGL, TypeValues<LLCoordGL> >::ParamValue(const LLCoordGL& coord)
+ ParamValue<LLCoordGL>::ParamValue(const LLCoordGL& coord)
: super_t(coord),
x("x"),
y("y")
@@ -2301,12 +722,12 @@ namespace LLInitParam
updateBlockFromValue(false);
}
- void ParamValue<LLCoordGL, TypeValues<LLCoordGL> >::updateValueFromBlock()
+ void ParamValue<LLCoordGL>::updateValueFromBlock()
{
updateValue(LLCoordGL(x, y));
}
- void ParamValue<LLCoordGL, TypeValues<LLCoordGL> >::updateBlockFromValue(bool make_block_authoritative)
+ void ParamValue<LLCoordGL>::updateBlockFromValue(bool make_block_authoritative)
{
x.set(getValue().mX, make_block_authoritative);
y.set(getValue().mY, make_block_authoritative);
diff --git a/indra/llui/llui.h b/indra/llui/llui.h
index 28e84fa444..0bc4424a8c 100644..100755
--- a/indra/llui/llui.h
+++ b/indra/llui/llui.h
@@ -1,6 +1,6 @@
/**
* @file llui.h
- * @brief GL function declarations and other general static UI services.
+ * @brief General static UI services.
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -24,121 +24,37 @@
* $/LicenseInfo$
*/
-// All immediate-mode gl drawing should happen here.
#ifndef LL_LLUI_H
#define LL_LLUI_H
-#include "llpointer.h" // LLPointer<>
#include "llrect.h"
#include "llcontrol.h"
#include "llcoord.h"
-#include "llglslshader.h"
+#include "v2math.h"
#include "llinitparam.h"
#include "llregistry.h"
+#include "llrender2dutils.h"
+#include "llpointer.h"
#include "lluicolor.h"
#include "lluicolortable.h"
+#include "lluiimage.h"
#include <boost/signals2.hpp>
#include "lllazyvalue.h"
#include "llframetimer.h"
#include <limits>
-// LLUIFactory
-#include "llsd.h"
-
// for initparam specialization
#include "llfontgl.h"
-class LLColor4;
-class LLVector3;
-class LLVector2;
-class LLUIImage;
class LLUUID;
class LLWindow;
class LLView;
class LLHelp;
-// UI colors
-extern const LLColor4 UI_VERTEX_COLOR;
void make_ui_sound(const char* name);
-
-BOOL ui_point_in_rect(S32 x, S32 y, S32 left, S32 top, S32 right, S32 bottom);
-void gl_state_for_2d(S32 width, S32 height);
-
-void gl_line_2d(S32 x1, S32 y1, S32 x2, S32 y2);
-void gl_line_2d(S32 x1, S32 y1, S32 x2, S32 y2, const LLColor4 &color );
-void gl_triangle_2d(S32 x1, S32 y1, S32 x2, S32 y2, S32 x3, S32 y3, const LLColor4& color, BOOL filled);
-void gl_rect_2d_simple( S32 width, S32 height );
-
-void gl_draw_x(const LLRect& rect, const LLColor4& color);
-
-void gl_rect_2d(S32 left, S32 top, S32 right, S32 bottom, BOOL filled = TRUE );
-void gl_rect_2d(S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &color, BOOL filled = TRUE );
-void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &color, S32 pixel_offset = 0, BOOL filled = TRUE );
-void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, S32 pixel_offset = 0, BOOL filled = TRUE );
-void gl_rect_2d(const LLRect& rect, BOOL filled = TRUE );
-void gl_rect_2d(const LLRect& rect, const LLColor4& color, BOOL filled = TRUE );
-void gl_rect_2d_checkerboard(const LLRect& rect, GLfloat alpha = 1.0f);
-
-void gl_drop_shadow(S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &start_color, S32 lines);
-
-void gl_circle_2d(F32 x, F32 y, F32 radius, S32 steps, BOOL filled);
-void gl_arc_2d(F32 center_x, F32 center_y, F32 radius, S32 steps, BOOL filled, F32 start_angle, F32 end_angle);
-void gl_deep_circle( F32 radius, F32 depth );
-void gl_ring( F32 radius, F32 width, const LLColor4& center_color, const LLColor4& side_color, S32 steps, BOOL render_center );
-void gl_corners_2d(S32 left, S32 top, S32 right, S32 bottom, S32 length, F32 max_frac);
-void gl_washer_2d(F32 outer_radius, F32 inner_radius, S32 steps, const LLColor4& inner_color, const LLColor4& outer_color);
-void gl_washer_segment_2d(F32 outer_radius, F32 inner_radius, F32 start_radians, F32 end_radians, S32 steps, const LLColor4& inner_color, const LLColor4& outer_color);
-
-void gl_draw_image(S32 x, S32 y, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
-void gl_draw_scaled_image(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
-void gl_draw_rotated_image(S32 x, S32 y, F32 degrees, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
-void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degrees,LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
-void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 border_width, S32 border_height, S32 width, S32 height, LLTexture* image, const LLColor4 &color, BOOL solid_color = FALSE, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
-void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4 &color, BOOL solid_color = FALSE, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f), const LLRectf& scale_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
-
-void gl_stippled_line_3d( const LLVector3& start, const LLVector3& end, const LLColor4& color, F32 phase = 0.f );
-
-void gl_rect_2d_simple_tex( S32 width, S32 height );
-
-// segmented rectangles
-
-/*
- TL |______TOP_________| TR
- /| |\
- _/_|__________________|_\_
- L| | MIDDLE | |R
- _|_|__________________|_|_
- \ | BOTTOM | /
- BL\|__________________|/ BR
- | |
-*/
-
-typedef enum e_rounded_edge
-{
- ROUNDED_RECT_LEFT = 0x1,
- ROUNDED_RECT_TOP = 0x2,
- ROUNDED_RECT_RIGHT = 0x4,
- ROUNDED_RECT_BOTTOM = 0x8,
- ROUNDED_RECT_ALL = 0xf
-}ERoundedEdge;
-
-
-void gl_segmented_rect_2d_tex(const S32 left, const S32 top, const S32 right, const S32 bottom, const S32 texture_width, const S32 texture_height, const S32 border_size, const U32 edges = ROUNDED_RECT_ALL);
-void gl_segmented_rect_2d_fragment_tex(const S32 left, const S32 top, const S32 right, const S32 bottom, const S32 texture_width, const S32 texture_height, const S32 border_size, const F32 start_fragment, const F32 end_fragment, const U32 edges = ROUNDED_RECT_ALL);
-void gl_segmented_rect_3d_tex(const LLVector2& border_scale, const LLVector3& border_width, const LLVector3& border_height, const LLVector3& width_vec, const LLVector3& height_vec, U32 edges = ROUNDED_RECT_ALL);
-void gl_segmented_rect_3d_tex_top(const LLVector2& border_scale, const LLVector3& border_width, const LLVector3& border_height, const LLVector3& width_vec, const LLVector3& height_vec);
-
-inline void gl_rect_2d( const LLRect& rect, BOOL filled )
-{
- gl_rect_2d( rect.mLeft, rect.mTop, rect.mRight, rect.mBottom, filled );
-}
-
-inline void gl_rect_2d_offset_local( const LLRect& rect, S32 pixel_offset, BOOL filled)
-{
- gl_rect_2d_offset_local( rect.mLeft, rect.mTop, rect.mRight, rect.mBottom, pixel_offset, filled );
-}
+void make_ui_sound_deferred(const char * name);
class LLImageProviderInterface;
@@ -275,15 +191,16 @@ public:
static void initClass(const settings_map_t& settings,
LLImageProviderInterface* image_provider,
LLUIAudioCallback audio_callback = NULL,
+ LLUIAudioCallback deferred_audio_callback = NULL,
const LLVector2 *scale_factor = NULL,
const std::string& language = LLStringUtil::null);
static void cleanupClass();
static void setPopupFuncs(const add_popup_t& add_popup, const remove_popup_t&, const clear_popups_t& );
- static void pushMatrix();
- static void popMatrix();
- static void loadIdentity();
- static void translate(F32 x, F32 y, F32 z = 0.0f);
+ static void pushMatrix() { LLRender2D::pushMatrix(); }
+ static void popMatrix() { LLRender2D::popMatrix(); }
+ static void loadIdentity() { LLRender2D::loadIdentity(); }
+ static void translate(F32 x, F32 y, F32 z = 0.0f) { LLRender2D::translate(x, y, z); }
static LLRect sDirtyRect;
static BOOL sDirty;
@@ -292,11 +209,6 @@ public:
// Return the ISO639 language name ("en", "ko", etc.) for the viewer UI.
// http://www.loc.gov/standards/iso639-2/php/code_list.php
static std::string getLanguage();
-
- static void setupPaths();
- static const std::vector<std::string>& getXUIPaths() { return sXUIPaths; }
- static std::string getSkinPath() { return sXUIPaths.front(); }
- static std::string getLocalizedSkinPath() { return sXUIPaths.back(); } //all files may not exist at the localized path
//helper functions (should probably move free standing rendering helper functions here)
static LLView* getRootView() { return sRootView; }
@@ -333,10 +245,13 @@ public:
static void getMousePositionScreen(S32 *x, S32 *y);
static void setMousePositionLocal(const LLView* viewp, S32 x, S32 y);
static void getMousePositionLocal(const LLView* viewp, S32 *x, S32 *y);
- static void setScaleFactor(const LLVector2& scale_factor);
- static void setLineWidth(F32 width);
- static LLPointer<LLUIImage> getUIImageByID(const LLUUID& image_id, S32 priority = 0);
- static LLPointer<LLUIImage> getUIImage(const std::string& name, S32 priority = 0);
+ static LLVector2& getScaleFactor() { return LLRender2D::sGLScaleFactor; }
+ static void setScaleFactor(const LLVector2& scale_factor) { LLRender2D::setScaleFactor(scale_factor); }
+ static void setLineWidth(F32 width) { LLRender2D::setLineWidth(width); }
+ static LLPointer<LLUIImage> getUIImageByID(const LLUUID& image_id, S32 priority = 0)
+ { return LLRender2D::getUIImageByID(image_id, priority); }
+ static LLPointer<LLUIImage> getUIImage(const std::string& name, S32 priority = 0)
+ { return LLRender2D::getUIImage(name, priority); }
static LLVector2 getWindowSize();
static void screenPointToGL(S32 screen_x, S32 screen_y, S32 *gl_x, S32 *gl_y);
static void glPointToScreen(S32 gl_x, S32 gl_y, S32 *screen_x, S32 *screen_y);
@@ -365,12 +280,11 @@ public:
//
static settings_map_t sSettingGroups;
static LLUIAudioCallback sAudioCallback;
- static LLVector2 sGLScaleFactor;
+ static LLUIAudioCallback sDeferredAudioCallback;
static LLWindow* sWindow;
static LLView* sRootView;
static LLHelp* sHelpImpl;
private:
- static LLImageProviderInterface* sImageProvider;
static std::vector<std::string> sXUIPaths;
static LLFrameTimer sMouseIdleTimer;
static add_popup_t sAddPopupFunc;
@@ -381,18 +295,6 @@ private:
// Moved LLLocalClipRect to lllocalcliprect.h
-//RN: maybe this needs to moved elsewhere?
-class LLImageProviderInterface
-{
-protected:
- LLImageProviderInterface() {};
- virtual ~LLImageProviderInterface() {};
-public:
- virtual LLPointer<LLUIImage> getUIImage(const std::string& name, S32 priority) = 0;
- virtual LLPointer<LLUIImage> getUIImageByID(const LLUUID& id, S32 priority) = 0;
- virtual void cleanUp() = 0;
-};
-
class LLCallbackRegistry
{
public:
@@ -441,10 +343,11 @@ public:
// this avoids a MSVC bug where non-referenced static members are "optimized" away
// even if their constructors have side effects
- void reference()
+ S32 reference()
{
S32 dummy;
dummy = 0;
+ return dummy;
}
};
@@ -502,17 +405,12 @@ public:
const std::string& comment = "Declared In Code")
: LLCachedControl<T>(LLUI::getControlControlGroup(name), name, default_value, comment)
{}
-
- // This constructor will signal an error if the control doesn't exist in the control group
- LLUICachedControl(const std::string& name)
- : LLCachedControl<T>(LLUI::getControlControlGroup(name), name)
- {}
};
namespace LLInitParam
{
template<>
- class ParamValue<LLRect, TypeValues<LLRect> >
+ class ParamValue<LLRect>
: public CustomParamValue<LLRect>
{
typedef CustomParamValue<LLRect> super_t;
@@ -531,7 +429,7 @@ namespace LLInitParam
};
template<>
- class ParamValue<LLUIColor, TypeValues<LLUIColor> >
+ class ParamValue<LLUIColor>
: public CustomParamValue<LLUIColor>
{
typedef CustomParamValue<LLUIColor> super_t;
@@ -549,7 +447,7 @@ namespace LLInitParam
};
template<>
- class ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >
+ class ParamValue<const LLFontGL*>
: public CustomParamValue<const LLFontGL* >
{
typedef CustomParamValue<const LLFontGL*> super_t;
@@ -589,7 +487,7 @@ namespace LLInitParam
template<>
- class ParamValue<LLCoordGL, TypeValues<LLCoordGL> >
+ class ParamValue<LLCoordGL>
: public CustomParamValue<LLCoordGL>
{
typedef CustomParamValue<LLCoordGL> super_t;
@@ -603,7 +501,4 @@ namespace LLInitParam
};
}
-extern LLGLSLShader gSolidColorProgram;
-extern LLGLSLShader gUIProgram;
-
#endif
diff --git a/indra/llxuixml/lluicolor.cpp b/indra/llui/lluicolor.cpp
index f9bb80f8c5..f9bb80f8c5 100644..100755
--- a/indra/llxuixml/lluicolor.cpp
+++ b/indra/llui/lluicolor.cpp
diff --git a/indra/llxuixml/lluicolor.h b/indra/llui/lluicolor.h
index 97ebea854a..97ebea854a 100644..100755
--- a/indra/llxuixml/lluicolor.h
+++ b/indra/llui/lluicolor.h
diff --git a/indra/llui/lluicolortable.cpp b/indra/llui/lluicolortable.cpp
index 9455d09cc0..ffeff15968 100644..100755
--- a/indra/llui/lluicolortable.cpp
+++ b/indra/llui/lluicolortable.cpp
@@ -32,6 +32,7 @@
#include "llui.h"
#include "lluicolortable.h"
#include "lluictrlfactory.h"
+#include <boost/foreach.hpp>
LLUIColorTable::ColorParams::ColorParams()
: value("value"),
@@ -206,19 +207,12 @@ bool LLUIColorTable::loadFromSettings()
{
bool result = false;
- std::string default_filename = gDirUtilp->getExpandedFilename(LL_PATH_DEFAULT_SKIN, "colors.xml");
- result |= loadFromFilename(default_filename, mLoadedColors);
-
- std::string current_filename = gDirUtilp->getExpandedFilename(LL_PATH_TOP_SKIN, "colors.xml");
- if(current_filename != default_filename)
- {
- result |= loadFromFilename(current_filename, mLoadedColors);
- }
-
- current_filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SKIN, "colors.xml");
- if(current_filename != default_filename)
+ // pass constraint=LLDir::ALL_SKINS because we want colors.xml from every
+ // skin dir
+ BOOST_FOREACH(std::string colors_path,
+ gDirUtilp->findSkinnedFilenames(LLDir::SKINBASE, "colors.xml", LLDir::ALL_SKINS))
{
- result |= loadFromFilename(current_filename, mLoadedColors);
+ result |= loadFromFilename(colors_path, mLoadedColors);
}
std::string user_filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "colors.xml");
diff --git a/indra/llui/lluicolortable.h b/indra/llui/lluicolortable.h
index 6a7a681d57..6a7a681d57 100644..100755
--- a/indra/llui/lluicolortable.h
+++ b/indra/llui/lluicolortable.h
diff --git a/indra/llui/lluiconstants.h b/indra/llui/lluiconstants.h
index 1479e58c43..1479e58c43 100644..100755
--- a/indra/llui/lluiconstants.h
+++ b/indra/llui/lluiconstants.h
diff --git a/indra/llui/lluictrl.cpp b/indra/llui/lluictrl.cpp
index b9c843e931..1722bf27bd 100644..100755
--- a/indra/llui/lluictrl.cpp
+++ b/indra/llui/lluictrl.cpp
@@ -29,7 +29,7 @@
#define LLUICTRL_CPP
#include "lluictrl.h"
-
+#include "llviewereventrecorder.h"
#include "llfocusmgr.h"
#include "llpanel.h"
#include "lluictrlfactory.h"
@@ -308,22 +308,40 @@ void LLUICtrl::onMouseLeave(S32 x, S32 y, MASK mask)
//virtual
BOOL LLUICtrl::handleMouseDown(S32 x, S32 y, MASK mask)
{
+
+ lldebugs << "LLUICtrl::handleMouseDown calling LLView)'s handleMouseUp (first initialized xui to: " << getPathname() << " )" << llendl;
+
BOOL handled = LLView::handleMouseDown(x,y,mask);
+
if (mMouseDownSignal)
{
(*mMouseDownSignal)(this,x,y,mask);
}
+ lldebugs << "LLUICtrl::handleMousedown - handled is returning as: " << handled << " " << llendl;
+
+ if (handled) {
+ LLViewerEventRecorder::instance().updateMouseEventInfo(x,y,-56,-56,getPathname());
+ }
return handled;
}
//virtual
BOOL LLUICtrl::handleMouseUp(S32 x, S32 y, MASK mask)
{
+
+ lldebugs << "LLUICtrl::handleMouseUp calling LLView)'s handleMouseUp (first initialized xui to: " << getPathname() << " )" << llendl;
+
BOOL handled = LLView::handleMouseUp(x,y,mask);
+ if (handled) {
+ LLViewerEventRecorder::instance().updateMouseEventInfo(x,y,-56,-56,getPathname());
+ }
if (mMouseUpSignal)
{
(*mMouseUpSignal)(this,x,y,mask);
}
+
+ lldebugs << "LLUICtrl::handleMouseUp - handled for xui " << getPathname() << " - is returning as: " << handled << " " << llendl;
+
return handled;
}
diff --git a/indra/llui/lluictrl.h b/indra/llui/lluictrl.h
index fb2196bb16..fb2196bb16 100644..100755
--- a/indra/llui/lluictrl.h
+++ b/indra/llui/lluictrl.h
diff --git a/indra/llui/lluictrlfactory.cpp b/indra/llui/lluictrlfactory.cpp
index 25e7a31e90..60fee47ae0 100644..100755
--- a/indra/llui/lluictrlfactory.cpp
+++ b/indra/llui/lluictrlfactory.cpp
@@ -90,10 +90,12 @@ LLUICtrlFactory::~LLUICtrlFactory()
void LLUICtrlFactory::loadWidgetTemplate(const std::string& widget_tag, LLInitParam::BaseBlock& block)
{
- std::string filename = std::string("widgets") + gDirUtilp->getDirDelimiter() + widget_tag + ".xml";
+ std::string filename = gDirUtilp->add("widgets", widget_tag + ".xml");
LLXMLNodePtr root_node;
- std::string full_filename = gDirUtilp->findSkinnedFilename(LLUI::getXUIPaths().front(), filename);
+ // Here we're looking for the "en" version, the default-language version
+ // of the file, rather than the localized version.
+ std::string full_filename = gDirUtilp->findSkinnedFilenameBaseLang(LLDir::XUI, filename);
if (!full_filename.empty())
{
LLUICtrlFactory::instance().pushFileName(full_filename);
@@ -149,22 +151,12 @@ static LLFastTimer::DeclareTimer FTM_XML_PARSE("XML Reading/Parsing");
//-----------------------------------------------------------------------------
// getLayeredXMLNode()
//-----------------------------------------------------------------------------
-bool LLUICtrlFactory::getLayeredXMLNode(const std::string &xui_filename, LLXMLNodePtr& root)
+bool LLUICtrlFactory::getLayeredXMLNode(const std::string &xui_filename, LLXMLNodePtr& root,
+ LLDir::ESkinConstraint constraint)
{
LLFastTimer timer(FTM_XML_PARSE);
-
- std::vector<std::string> paths;
- std::string path = gDirUtilp->findSkinnedFilename(LLUI::getSkinPath(), xui_filename);
- if (!path.empty())
- {
- paths.push_back(path);
- }
-
- std::string localize_path = gDirUtilp->findSkinnedFilename(LLUI::getLocalizedSkinPath(), xui_filename);
- if (!localize_path.empty() && localize_path != path)
- {
- paths.push_back(localize_path);
- }
+ std::vector<std::string> paths =
+ gDirUtilp->findSkinnedFilenames(LLDir::XUI, xui_filename, constraint);
if (paths.empty())
{
@@ -177,23 +169,6 @@ bool LLUICtrlFactory::getLayeredXMLNode(const std::string &xui_filename, LLXMLNo
//-----------------------------------------------------------------------------
-// getLocalizedXMLNode()
-//-----------------------------------------------------------------------------
-bool LLUICtrlFactory::getLocalizedXMLNode(const std::string &xui_filename, LLXMLNodePtr& root)
-{
- LLFastTimer timer(FTM_XML_PARSE);
- std::string full_filename = gDirUtilp->findSkinnedFilename(LLUI::getLocalizedSkinPath(), xui_filename);
- if (!LLXMLNode::parseFile(full_filename, root, NULL))
- {
- return false;
- }
- else
- {
- return true;
- }
-}
-
-//-----------------------------------------------------------------------------
// saveToXML()
//-----------------------------------------------------------------------------
S32 LLUICtrlFactory::saveToXML(LLView* viewp, const std::string& filename)
@@ -239,8 +214,10 @@ std::string LLUICtrlFactory::getCurFileName()
void LLUICtrlFactory::pushFileName(const std::string& name)
-{
- mFileNames.push_back(gDirUtilp->findSkinnedFilename(LLUI::getSkinPath(), name));
+{
+ // Here we seem to be looking for the default language file ("en") rather
+ // than the localized one, if any.
+ mFileNames.push_back(gDirUtilp->findSkinnedFilenameBaseLang(LLDir::XUI, name));
}
void LLUICtrlFactory::popFileName()
@@ -255,14 +232,6 @@ void LLUICtrlFactory::setCtrlParent(LLView* view, LLView* parent, S32 tab_group)
parent->addChild(view, tab_group);
}
-
-// Avoid directly using LLUI and LLDir in the template code
-//static
-std::string LLUICtrlFactory::findSkinnedFilename(const std::string& filename)
-{
- return gDirUtilp->findSkinnedFilename(LLUI::getSkinPath(), filename);
-}
-
//static
void LLUICtrlFactory::copyName(LLXMLNodePtr src, LLXMLNodePtr dest)
{
@@ -278,13 +247,13 @@ const LLInitParam::BaseBlock& get_empty_param_block()
// adds a widget and its param block to various registries
//static
-void LLUICtrlFactory::registerWidget(const std::type_info* widget_type, const std::type_info* param_block_type, const std::string& tag)
+void LLUICtrlFactory::registerWidget(const std::type_info* widget_type, const std::type_info* param_block_type, const std::string& name)
{
// associate parameter block type with template .xml file
- std::string* existing_tag = LLWidgetNameRegistry::instance().getValue(param_block_type);
- if (existing_tag != NULL)
+ std::string* existing_name = LLWidgetNameRegistry::instance().getValue(param_block_type);
+ if (existing_name != NULL)
{
- if(*existing_tag != tag)
+ if(*existing_name != name)
{
std::cerr << "Duplicate entry for T::Params, try creating empty param block in derived classes that inherit T::Params" << std::endl;
// forcing crash here
@@ -293,19 +262,15 @@ void LLUICtrlFactory::registerWidget(const std::type_info* widget_type, const st
}
else
{
- // widget already registered
+ // widget already registered this name
return;
}
}
- LLWidgetNameRegistry::instance().defaultRegistrar().add(param_block_type, tag);
+
+ LLWidgetNameRegistry::instance().defaultRegistrar().add(param_block_type, name);
//FIXME: comment this in when working on schema generation
//LLWidgetTypeRegistry::instance().defaultRegistrar().add(tag, widget_type);
//LLDefaultParamBlockRegistry::instance().defaultRegistrar().add(widget_type, &get_empty_param_block<T>);
}
-//static
-const std::string* LLUICtrlFactory::getWidgetTag(const std::type_info* widget_type)
-{
- return LLWidgetNameRegistry::instance().getValue(widget_type);
-}
diff --git a/indra/llui/lluictrlfactory.h b/indra/llui/lluictrlfactory.h
index d612ad5005..876bb5ef46 100644..100755
--- a/indra/llui/lluictrlfactory.h
+++ b/indra/llui/lluictrlfactory.h
@@ -31,18 +31,11 @@
#include "llinitparam.h"
#include "llregistry.h"
#include "llxuiparser.h"
+#include "llstl.h"
+#include "lldir.h"
class LLView;
-// sort functor for typeid maps
-struct LLCompareTypeID
-{
- bool operator()(const std::type_info* lhs, const std::type_info* rhs) const
- {
- return lhs->before(*rhs);
- }
-};
-
// lookup widget constructor funcs by widget name
template <typename DERIVED_TYPE>
class LLChildRegistry : public LLRegistrySingleton<std::string, LLWidgetCreatorFunc, DERIVED_TYPE>
@@ -71,14 +64,14 @@ protected:
// lookup widget name by type
class LLWidgetNameRegistry
-: public LLRegistrySingleton<const std::type_info*, std::string, LLWidgetNameRegistry , LLCompareTypeID>
+: public LLRegistrySingleton<const std::type_info*, std::string, LLWidgetNameRegistry>
{};
// lookup function for generating empty param block by widget type
// this is used for schema generation
//typedef const LLInitParam::BaseBlock& (*empty_param_block_func_t)();
//class LLDefaultParamBlockRegistry
-//: public LLRegistrySingleton<const std::type_info*, empty_param_block_func_t, LLDefaultParamBlockRegistry, LLCompareTypeID>
+//: public LLRegistrySingleton<const std::type_info*, empty_param_block_func_t, LLDefaultParamBlockRegistry>
//{};
extern LLFastTimer::DeclareTimer FTM_WIDGET_SETUP;
@@ -105,7 +98,7 @@ private:
ParamDefaults()
{
// look up template file for this param block...
- const std::string* param_block_tag = getWidgetTag(&typeid(PARAM_BLOCK));
+ const std::string* param_block_tag = LLWidgetNameRegistry::instance().getValue(&typeid(PARAM_BLOCK));
if (param_block_tag)
{ // ...and if it exists, back fill values using the most specific template first
PARAM_BLOCK params;
@@ -139,7 +132,6 @@ public:
template<typename T>
static const typename T::Params& getDefaultParams()
{
- //#pragma message("Generating ParamDefaults")
return ParamDefaults<typename T::Params, 0>::instance().get();
}
@@ -169,32 +161,21 @@ public:
LLView* createFromXML(LLXMLNodePtr node, LLView* parent, const std::string& filename, const widget_registry_t&, LLXMLNodePtr output_node );
template<typename T>
- static T* createFromFile(const std::string &filename, LLView *parent, const widget_registry_t& registry, LLXMLNodePtr output_node = NULL)
+ static T* createFromFile(const std::string &filename, LLView *parent, const widget_registry_t& registry)
{
T* widget = NULL;
-
- std::string skinned_filename = findSkinnedFilename(filename);
+
instance().pushFileName(filename);
{
LLXMLNodePtr root_node;
- //if exporting, only load the language being exported,
- //instead of layering localized version on top of english
- if (output_node)
- {
- if (!LLUICtrlFactory::getLocalizedXMLNode(filename, root_node))
- {
- llwarns << "Couldn't parse XUI file: " << filename << llendl;
- goto fail;
- }
- }
- else if (!LLUICtrlFactory::getLayeredXMLNode(filename, root_node))
+ if (!LLUICtrlFactory::getLayeredXMLNode(filename, root_node))
{
- llwarns << "Couldn't parse XUI file: " << skinned_filename << llendl;
+ llwarns << "Couldn't parse XUI file: " << instance().getCurFileName() << llendl;
goto fail;
}
-
- LLView* view = getInstance()->createFromXML(root_node, parent, filename, registry, output_node);
+
+ LLView* view = getInstance()->createFromXML(root_node, parent, filename, registry, NULL);
if (view)
{
widget = dynamic_cast<T*>(view);
@@ -222,8 +203,8 @@ fail:
static void createChildren(LLView* viewp, LLXMLNodePtr node, const widget_registry_t&, LLXMLNodePtr output_node = NULL);
- static bool getLayeredXMLNode(const std::string &filename, LLXMLNodePtr& root);
- static bool getLocalizedXMLNode(const std::string &xui_filename, LLXMLNodePtr& root);
+ static bool getLayeredXMLNode(const std::string &filename, LLXMLNodePtr& root,
+ LLDir::ESkinConstraint constraint=LLDir::CURRENT_SKIN);
private:
//NOTE: both friend declarations are necessary to keep both gcc and msvc happy
@@ -303,14 +284,9 @@ private:
}
- static const std::string* getWidgetTag(const std::type_info* widget_type);
-
// this exists to get around dependency on llview
static void setCtrlParent(LLView* view, LLView* parent, S32 tab_group);
- // Avoid directly using LLUI and LLDir in the template code
- static std::string findSkinnedFilename(const std::string& filename);
-
class LLPanel* mDummyPanel;
std::vector<std::string> mFileNames;
};
diff --git a/indra/llui/lluifwd.h b/indra/llui/lluifwd.h
index a68629a091..a68629a091 100644..100755
--- a/indra/llui/lluifwd.h
+++ b/indra/llui/lluifwd.h
diff --git a/indra/llui/lluiimage.cpp b/indra/llui/lluiimage.cpp
deleted file mode 100644
index 1d9ce29ba9..0000000000
--- a/indra/llui/lluiimage.cpp
+++ /dev/null
@@ -1,199 +0,0 @@
-/**
- * @file lluiimage.cpp
- * @brief UI implementation
- *
- * $LicenseInfo:firstyear=2007&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$
- */
-
-// Utilities functions the user interface needs
-
-//#include "llviewerprecompiledheaders.h"
-#include "linden_common.h"
-
-// Project includes
-#include "lluiimage.h"
-#include "llui.h"
-
-LLUIImage::LLUIImage(const std::string& name, LLPointer<LLTexture> image)
-: mName(name),
- mImage(image),
- mScaleRegion(0.f, 1.f, 1.f, 0.f),
- mClipRegion(0.f, 1.f, 1.f, 0.f),
- mUniformScaling(TRUE),
- mNoClip(TRUE),
- mImageLoaded(NULL)
-{
-}
-
-LLUIImage::~LLUIImage()
-{
- delete mImageLoaded;
-}
-
-void LLUIImage::setClipRegion(const LLRectf& region)
-{
- mClipRegion = region;
- mNoClip = mClipRegion.mLeft == 0.f
- && mClipRegion.mRight == 1.f
- && mClipRegion.mBottom == 0.f
- && mClipRegion.mTop == 1.f;
-}
-
-void LLUIImage::setScaleRegion(const LLRectf& region)
-{
- mScaleRegion = region;
- mUniformScaling = mScaleRegion.mLeft == 0.f
- && mScaleRegion.mRight == 1.f
- && mScaleRegion.mBottom == 0.f
- && mScaleRegion.mTop == 1.f;
-}
-
-//TODO: move drawing implementation inside class
-void LLUIImage::draw(S32 x, S32 y, const LLColor4& color) const
-{
- gl_draw_scaled_image(x, y, getWidth(), getHeight(), mImage, color, mClipRegion);
-}
-
-void LLUIImage::draw(S32 x, S32 y, S32 width, S32 height, const LLColor4& color) const
-{
- if (mUniformScaling)
- {
- gl_draw_scaled_image(x, y, width, height, mImage, color, mClipRegion);
- }
- else
- {
- gl_draw_scaled_image_with_border(
- x, y,
- width, height,
- mImage,
- color,
- FALSE,
- mClipRegion,
- mScaleRegion);
- }
-}
-
-void LLUIImage::drawSolid(S32 x, S32 y, S32 width, S32 height, const LLColor4& color) const
-{
- gl_draw_scaled_image_with_border(
- x, y,
- width, height,
- mImage,
- color,
- TRUE,
- mClipRegion,
- mScaleRegion);
-}
-
-void LLUIImage::drawBorder(S32 x, S32 y, S32 width, S32 height, const LLColor4& color, S32 border_width) const
-{
- LLRect border_rect;
- border_rect.setOriginAndSize(x, y, width, height);
- border_rect.stretch(border_width, border_width);
- drawSolid(border_rect, color);
-}
-
-S32 LLUIImage::getWidth() const
-{
- // return clipped dimensions of actual image area
- return llround((F32)mImage->getWidth(0) * mClipRegion.getWidth());
-}
-
-S32 LLUIImage::getHeight() const
-{
- // return clipped dimensions of actual image area
- return llround((F32)mImage->getHeight(0) * mClipRegion.getHeight());
-}
-
-S32 LLUIImage::getTextureWidth() const
-{
- return mImage->getWidth(0);
-}
-
-S32 LLUIImage::getTextureHeight() const
-{
- return mImage->getHeight(0);
-}
-
-boost::signals2::connection LLUIImage::addLoadedCallback( const image_loaded_signal_t::slot_type& cb )
-{
- if (!mImageLoaded)
- {
- mImageLoaded = new image_loaded_signal_t();
- }
- return mImageLoaded->connect(cb);
-}
-
-
-void LLUIImage::onImageLoaded()
-{
- if (mImageLoaded)
- {
- (*mImageLoaded)();
- }
-}
-
-
-namespace LLInitParam
-{
- void ParamValue<LLUIImage*, TypeValues<LLUIImage*> >::updateValueFromBlock()
- {
- // The keyword "none" is specifically requesting a null image
- // do not default to current value. Used to overwrite template images.
- if (name() == "none")
- {
- updateValue(NULL);
- return;
- }
-
- LLUIImage* imagep = LLUI::getUIImage(name());
- if (imagep)
- {
- updateValue(imagep);
- }
- }
-
- void ParamValue<LLUIImage*, TypeValues<LLUIImage*> >::updateBlockFromValue(bool make_block_authoritative)
- {
- if (getValue() == NULL)
- {
- name.set("none", make_block_authoritative);
- }
- else
- {
- name.set(getValue()->getName(), make_block_authoritative);
- }
- }
-
-
- bool ParamCompare<LLUIImage*, false>::equals(
- LLUIImage* const &a,
- LLUIImage* const &b)
- {
- // force all LLUIImages for XML UI export to be "non-default"
- if (!a && !b)
- return false;
- else
- return (a == b);
- }
-}
-
diff --git a/indra/llui/lluiimage.h b/indra/llui/lluiimage.h
deleted file mode 100644
index f07e8fa746..0000000000
--- a/indra/llui/lluiimage.h
+++ /dev/null
@@ -1,124 +0,0 @@
-/**
- * @file lluiimage.h
- * @brief wrapper for images used in the UI that handles smart scaling, etc.
- *
- * $LicenseInfo:firstyear=2007&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$
- */
-
-#ifndef LL_LLUIIMAGE_H
-#define LL_LLUIIMAGE_H
-
-#include "v4color.h"
-#include "llpointer.h"
-#include "llrefcount.h"
-#include "llrefcount.h"
-#include "llrect.h"
-#include <boost/function.hpp>
-#include <boost/signals2.hpp>
-#include "llinitparam.h"
-#include "lltexture.h"
-
-extern const LLColor4 UI_VERTEX_COLOR;
-
-class LLUIImage : public LLRefCount
-{
-public:
- typedef boost::signals2::signal<void (void)> image_loaded_signal_t;
-
- LLUIImage(const std::string& name, LLPointer<LLTexture> image);
- virtual ~LLUIImage();
-
- void setClipRegion(const LLRectf& region);
- void setScaleRegion(const LLRectf& region);
-
- LLPointer<LLTexture> getImage() { return mImage; }
- const LLPointer<LLTexture>& getImage() const { return mImage; }
-
- void draw(S32 x, S32 y, S32 width, S32 height, const LLColor4& color = UI_VERTEX_COLOR) const;
- void draw(S32 x, S32 y, const LLColor4& color = UI_VERTEX_COLOR) const;
- void draw(const LLRect& rect, const LLColor4& color = UI_VERTEX_COLOR) const { draw(rect.mLeft, rect.mBottom, rect.getWidth(), rect.getHeight(), color); }
-
- void drawSolid(S32 x, S32 y, S32 width, S32 height, const LLColor4& color) const;
- void drawSolid(const LLRect& rect, const LLColor4& color) const { drawSolid(rect.mLeft, rect.mBottom, rect.getWidth(), rect.getHeight(), color); }
- void drawSolid(S32 x, S32 y, const LLColor4& color) const { drawSolid(x, y, getWidth(), getHeight(), color); }
-
- void drawBorder(S32 x, S32 y, S32 width, S32 height, const LLColor4& color, S32 border_width) const;
- void drawBorder(const LLRect& rect, const LLColor4& color, S32 border_width) const { drawBorder(rect.mLeft, rect.mBottom, rect.getWidth(), rect.getHeight(), color, border_width); }
- void drawBorder(S32 x, S32 y, const LLColor4& color, S32 border_width) const { drawBorder(x, y, getWidth(), getHeight(), color, border_width); }
-
- const std::string& getName() const { return mName; }
-
- virtual S32 getWidth() const;
- virtual S32 getHeight() const;
-
- // returns dimensions of underlying textures, which might not be equal to ui image portion
- S32 getTextureWidth() const;
- S32 getTextureHeight() const;
-
- boost::signals2::connection addLoadedCallback( const image_loaded_signal_t::slot_type& cb );
-
- void onImageLoaded();
-
-protected:
- image_loaded_signal_t* mImageLoaded;
-
- std::string mName;
- LLRectf mScaleRegion;
- LLRectf mClipRegion;
- LLPointer<LLTexture> mImage;
- BOOL mUniformScaling;
- BOOL mNoClip;
-};
-
-namespace LLInitParam
-{
- template<>
- class ParamValue<LLUIImage*, TypeValues<LLUIImage*> >
- : public CustomParamValue<LLUIImage*>
- {
- typedef boost::add_reference<boost::add_const<LLUIImage*>::type>::type T_const_ref;
- typedef CustomParamValue<LLUIImage*> super_t;
- public:
- Optional<std::string> name;
-
- ParamValue(LLUIImage* const& image)
- : super_t(image)
- {
- updateBlockFromValue(false);
- addSynonym(name, "name");
- }
-
- void updateValueFromBlock();
- void updateBlockFromValue(bool make_block_authoritative);
- };
-
- // Need custom comparison function for our test app, which only loads
- // LLUIImage* as NULL.
- template<>
- struct ParamCompare<LLUIImage*, false>
- {
- static bool equals(LLUIImage* const &a, LLUIImage* const &b);
- };
-}
-
-typedef LLPointer<LLUIImage> LLUIImagePtr;
-#endif
diff --git a/indra/llui/lluistring.cpp b/indra/llui/lluistring.cpp
index c4e073ccdb..c4e073ccdb 100644..100755
--- a/indra/llui/lluistring.cpp
+++ b/indra/llui/lluistring.cpp
diff --git a/indra/llui/lluistring.h b/indra/llui/lluistring.h
index cb40c85582..cb40c85582 100644..100755
--- a/indra/llui/lluistring.h
+++ b/indra/llui/lluistring.h
diff --git a/indra/llui/llundo.cpp b/indra/llui/llundo.cpp
index 06b0514223..06b0514223 100644..100755
--- a/indra/llui/llundo.cpp
+++ b/indra/llui/llundo.cpp
diff --git a/indra/llui/llundo.h b/indra/llui/llundo.h
index a6da550126..a6da550126 100644..100755
--- a/indra/llui/llundo.h
+++ b/indra/llui/llundo.h
diff --git a/indra/llui/llurlaction.cpp b/indra/llui/llurlaction.cpp
index fd9b3d9a6d..23e574cb74 100644..100755
--- a/indra/llui/llurlaction.cpp
+++ b/indra/llui/llurlaction.cpp
@@ -24,7 +24,6 @@
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-
#include "linden_common.h"
#include "llurlaction.h"
@@ -32,6 +31,7 @@
#include "llwindow.h"
#include "llurlregistry.h"
+
// global state for the callback functions
LLUrlAction::url_callback_t LLUrlAction::sOpenURLCallback;
LLUrlAction::url_callback_t LLUrlAction::sOpenURLInternalCallback;
@@ -157,3 +157,76 @@ void LLUrlAction::showProfile(std::string url)
}
}
}
+
+std::string LLUrlAction::getUserID(std::string url)
+{
+ LLURI uri(url);
+ LLSD path_array = uri.pathArray();
+ std::string id_str;
+ if (path_array.size() == 4)
+ {
+ id_str = path_array.get(2).asString();
+ }
+ return id_str;
+}
+
+std::string LLUrlAction::getObjectId(std::string url)
+{
+ LLURI uri(url);
+ LLSD path_array = uri.pathArray();
+ std::string id_str;
+ if (path_array.size() >= 3)
+ {
+ id_str = path_array.get(2).asString();
+ }
+ return id_str;
+}
+
+std::string LLUrlAction::getObjectName(std::string url)
+{
+ LLURI uri(url);
+ LLSD query_map = uri.queryMap();
+ std::string name;
+ if (query_map.has("name"))
+ {
+ name = query_map["name"].asString();
+ }
+ return name;
+}
+
+void LLUrlAction::sendIM(std::string url)
+{
+ std::string id_str = getUserID(url);
+ if (LLUUID::validate(id_str))
+ {
+ executeSLURL("secondlife:///app/agent/" + id_str + "/im");
+ }
+}
+
+void LLUrlAction::addFriend(std::string url)
+{
+ std::string id_str = getUserID(url);
+ if (LLUUID::validate(id_str))
+ {
+ executeSLURL("secondlife:///app/agent/" + id_str + "/requestfriend");
+ }
+}
+
+void LLUrlAction::removeFriend(std::string url)
+{
+ std::string id_str = getUserID(url);
+ if (LLUUID::validate(id_str))
+ {
+ executeSLURL("secondlife:///app/agent/" + id_str + "/removefriend");
+ }
+}
+
+void LLUrlAction::blockObject(std::string url)
+{
+ std::string object_id = getObjectId(url);
+ std::string object_name = getObjectName(url);
+ if (LLUUID::validate(object_id))
+ {
+ executeSLURL("secondlife:///app/agent/" + object_id + "/block/" + object_name);
+ }
+}
diff --git a/indra/llui/llurlaction.h b/indra/llui/llurlaction.h
index c34960b826..e731376b95 100644..100755
--- a/indra/llui/llurlaction.h
+++ b/indra/llui/llurlaction.h
@@ -76,6 +76,13 @@ public:
/// if the Url specifies an SL command in the form like 'app/{cmd}/{id}/*', show its profile
static void showProfile(std::string url);
+ static std::string getUserID(std::string url);
+ static std::string getObjectName(std::string url);
+ static std::string getObjectId(std::string url);
+ static void sendIM(std::string url);
+ static void addFriend(std::string url);
+ static void removeFriend(std::string url);
+ static void blockObject(std::string url);
/// specify the callbacks to enable this class's functionality
typedef boost::function<void (const std::string&)> url_callback_t;
diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp
index a9e8fbb4e4..b1cc502c4b 100644..100755
--- a/indra/llui/llurlentry.cpp
+++ b/indra/llui/llurlentry.cpp
@@ -340,7 +340,8 @@ std::string LLUrlEntrySLURL::getLocation(const std::string &url) const
// secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about
// x-grid-location-info://lincoln.lindenlab.com/app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about
//
-LLUrlEntryAgent::LLUrlEntryAgent()
+LLUrlEntryAgent::LLUrlEntryAgent() :
+ mAvatarNameCacheConnection()
{
mPattern = boost::regex(APP_HEADER_REGEX "/agent/[\\da-f-]+/\\w+",
boost::regex::perl|boost::regex::icase);
@@ -371,7 +372,9 @@ void LLUrlEntryAgent::callObservers(const std::string &id,
void LLUrlEntryAgent::onAvatarNameCache(const LLUUID& id,
const LLAvatarName& av_name)
{
- std::string label = av_name.getCompleteName();
+ mAvatarNameCacheConnection.disconnect();
+
+ std::string label = av_name.getCompleteName();
// received the agent name from the server - tell our observers
callObservers(id.asString(), label, mIcon);
@@ -456,9 +459,11 @@ std::string LLUrlEntryAgent::getLabel(const std::string &url, const LLUrlLabelCa
}
else
{
- LLAvatarNameCache::get(agent_id,
- boost::bind(&LLUrlEntryAgent::onAvatarNameCache,
- this, _1, _2));
+ if (mAvatarNameCacheConnection.connected())
+ {
+ mAvatarNameCacheConnection.disconnect();
+ }
+ mAvatarNameCacheConnection = LLAvatarNameCache::get(agent_id, boost::bind(&LLUrlEntryAgent::onAvatarNameCache, this, _1, _2));
addObserver(agent_id_string, url, cb);
return LLTrans::getString("LoadingData");
}
@@ -499,6 +504,10 @@ std::string localize_slapp_label(const std::string& url, const std::string& full
{
return LLTrans::getString("SLappAgentRequestFriend") + " " + full_name;
}
+ if (LLStringUtil::endsWith(url, "/removefriend"))
+ {
+ return LLTrans::getString("SLappAgentRemoveFriend") + " " + full_name;
+ }
return full_name;
}
@@ -515,12 +524,15 @@ std::string LLUrlEntryAgent::getIcon(const std::string &url)
// secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/(completename|displayname|username)
// x-grid-location-info://lincoln.lindenlab.com/app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/(completename|displayname|username)
//
-LLUrlEntryAgentName::LLUrlEntryAgentName()
+LLUrlEntryAgentName::LLUrlEntryAgentName() :
+ mAvatarNameCacheConnection()
{}
void LLUrlEntryAgentName::onAvatarNameCache(const LLUUID& id,
const LLAvatarName& av_name)
{
+ mAvatarNameCacheConnection.disconnect();
+
std::string label = getName(av_name);
// received the agent name from the server - tell our observers
callObservers(id.asString(), label, mIcon);
@@ -554,9 +566,11 @@ std::string LLUrlEntryAgentName::getLabel(const std::string &url, const LLUrlLab
}
else
{
- LLAvatarNameCache::get(agent_id,
- boost::bind(&LLUrlEntryAgentCompleteName::onAvatarNameCache,
- this, _1, _2));
+ if (mAvatarNameCacheConnection.connected())
+ {
+ mAvatarNameCacheConnection.disconnect();
+ }
+ mAvatarNameCacheConnection = LLAvatarNameCache::get(agent_id, boost::bind(&LLUrlEntryAgentName::onAvatarNameCache, this, _1, _2));
addObserver(agent_id_string, url, cb);
return LLTrans::getString("LoadingData");
}
@@ -597,7 +611,7 @@ LLUrlEntryAgentDisplayName::LLUrlEntryAgentDisplayName()
std::string LLUrlEntryAgentDisplayName::getName(const LLAvatarName& avatar_name)
{
- return avatar_name.mDisplayName;
+ return avatar_name.getDisplayName();
}
//
@@ -613,7 +627,7 @@ LLUrlEntryAgentUserName::LLUrlEntryAgentUserName()
std::string LLUrlEntryAgentUserName::getName(const LLAvatarName& avatar_name)
{
- return avatar_name.mUsername.empty() ? avatar_name.getLegacyName() : avatar_name.mUsername;
+ return avatar_name.getAccountName();
}
//
diff --git a/indra/llui/llurlentry.h b/indra/llui/llurlentry.h
index 5f82721c0f..8c6c32178a 100644..100755
--- a/indra/llui/llurlentry.h
+++ b/indra/llui/llurlentry.h
@@ -171,6 +171,13 @@ class LLUrlEntryAgent : public LLUrlEntryBase
{
public:
LLUrlEntryAgent();
+ ~LLUrlEntryAgent()
+ {
+ if (mAvatarNameCacheConnection.connected())
+ {
+ mAvatarNameCacheConnection.disconnect();
+ }
+ }
/*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
/*virtual*/ std::string getIcon(const std::string &url);
/*virtual*/ std::string getTooltip(const std::string &string) const;
@@ -181,6 +188,7 @@ protected:
/*virtual*/ void callObservers(const std::string &id, const std::string &label, const std::string& icon);
private:
void onAvatarNameCache(const LLUUID& id, const LLAvatarName& av_name);
+ boost::signals2::connection mAvatarNameCacheConnection;
};
///
@@ -192,6 +200,13 @@ class LLUrlEntryAgentName : public LLUrlEntryBase, public boost::signals2::track
{
public:
LLUrlEntryAgentName();
+ ~LLUrlEntryAgentName()
+ {
+ if (mAvatarNameCacheConnection.connected())
+ {
+ mAvatarNameCacheConnection.disconnect();
+ }
+ }
/*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
/*virtual*/ LLStyle::Params getStyle() const;
protected:
@@ -199,6 +214,7 @@ protected:
virtual std::string getName(const LLAvatarName& avatar_name) = 0;
private:
void onAvatarNameCache(const LLUUID& id, const LLAvatarName& av_name);
+ boost::signals2::connection mAvatarNameCacheConnection;
};
diff --git a/indra/llui/llurlmatch.cpp b/indra/llui/llurlmatch.cpp
index c1f1382a9f..c1f1382a9f 100644..100755
--- a/indra/llui/llurlmatch.cpp
+++ b/indra/llui/llurlmatch.cpp
diff --git a/indra/llui/llurlmatch.h b/indra/llui/llurlmatch.h
index 2818f45207..2818f45207 100644..100755
--- a/indra/llui/llurlmatch.h
+++ b/indra/llui/llurlmatch.h
diff --git a/indra/llui/llurlregistry.cpp b/indra/llui/llurlregistry.cpp
index 523ee5d78c..523ee5d78c 100644..100755
--- a/indra/llui/llurlregistry.cpp
+++ b/indra/llui/llurlregistry.cpp
diff --git a/indra/llui/llurlregistry.h b/indra/llui/llurlregistry.h
index da16171a97..da16171a97 100644..100755
--- a/indra/llui/llurlregistry.h
+++ b/indra/llui/llurlregistry.h
diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp
index 54843227b7..20015dca1a 100644..100755
--- a/indra/llui/llview.cpp
+++ b/indra/llui/llview.cpp
@@ -48,13 +48,17 @@
#include "lluictrlfactory.h"
#include "lltooltip.h"
#include "llsdutil.h"
-
+#include "llsdserialize.h"
+#include "llviewereventrecorder.h"
+#include "llkeyboard.h"
// for ui edit hack
#include "llbutton.h"
#include "lllineeditor.h"
#include "lltexteditor.h"
#include "lltextbox.h"
+static const S32 LINE_HEIGHT = 15;
+
S32 LLView::sDepth = 0;
bool LLView::sDebugRects = false;
bool LLView::sDebugRectsShowNames = true;
@@ -349,7 +353,7 @@ void LLView::removeChild(LLView* child)
}
else
{
- llwarns << child->getName() << "is not a child of " << getName() << llendl;
+ llwarns << "\"" << child->getName() << "\" is not a child of " << getName() << llendl;
}
updateBoundingRect();
}
@@ -640,13 +644,27 @@ void LLView::setVisible(BOOL visible)
// virtual
void LLView::handleVisibilityChange ( BOOL new_visibility )
{
+ BOOL old_visibility;
BOOST_FOREACH(LLView* viewp, mChildList)
{
// only views that are themselves visible will have their overall visibility affected by their ancestors
- if (viewp->getVisible())
+ old_visibility=viewp->getVisible();
+
+ if (old_visibility!=new_visibility)
+ {
+ LLViewerEventRecorder::instance().logVisibilityChange( viewp->getPathname(), viewp->getName(), new_visibility,"widget");
+ }
+
+ if (old_visibility)
{
viewp->handleVisibilityChange ( new_visibility );
}
+
+ // Consider changing returns to confirm success and know which widget grabbed it
+ // For now assume success and log at highest xui possible
+ // NOTE we log actual state - which may differ if it somehow failed to set visibility
+ lldebugs << "LLView::handleVisibilityChange - now: " << getVisible() << " xui: " << viewp->getPathname() << " name: " << viewp->getName() << llendl;
+
}
}
@@ -695,6 +713,7 @@ bool LLView::visibleEnabledAndContains(S32 local_x, S32 local_y)
&& getEnabled();
}
+// This is NOT event recording related
void LLView::logMouseEvent()
{
if (sDebugMouseHandling)
@@ -741,7 +760,14 @@ LLView* LLView::childrenHandleMouseEvent(const METHOD& method, S32 x, S32 y, XDA
if ((viewp->*method)( local_x, local_y, extra )
|| (allow_mouse_block && viewp->blockMouseEvent( local_x, local_y )))
{
+ lldebugs << "LLView::childrenHandleMouseEvent calling updatemouseeventinfo - local_x|global x "<< local_x << " " << x << "local/global y " << local_y << " " << y << llendl;
+ lldebugs << "LLView::childrenHandleMouseEvent getPathname for viewp result: " << viewp->getPathname() << "for this view: " << getPathname() << llendl;
+
+ LLViewerEventRecorder::instance().updateMouseEventInfo(x,y,-55,-55,getPathname());
+
+ // This is NOT event recording related
viewp->logMouseEvent();
+
return viewp;
}
}
@@ -764,6 +790,7 @@ LLView* LLView::childrenHandleToolTip(S32 x, S32 y, MASK mask)
if (viewp->handleToolTip(local_x, local_y, mask)
|| viewp->blockMouseEvent(local_x, local_y))
{
+ // This is NOT event recording related
viewp->logMouseEvent();
return viewp;
}
@@ -822,6 +849,7 @@ LLView* LLView::childrenHandleHover(S32 x, S32 y, MASK mask)
if (viewp->handleHover(local_x, local_y, mask)
|| viewp->blockMouseEvent(local_x, local_y))
{
+ // This is NOT event recording related
viewp->logMouseEvent();
return viewp;
}
@@ -873,13 +901,12 @@ BOOL LLView::handleToolTip(S32 x, S32 y, MASK mask)
// allow "scrubbing" over ui by showing next tooltip immediately
// if previous one was still visible
F32 timeout = LLToolTipMgr::instance().toolTipVisible()
- ? LLUI::sSettingGroups["config"]->getF32( "ToolTipFastDelay" )
- : LLUI::sSettingGroups["config"]->getF32( "ToolTipDelay" );
+ ? LLUI::sSettingGroups["config"]->getF32( "ToolTipFastDelay" )
+ : LLUI::sSettingGroups["config"]->getF32( "ToolTipDelay" );
LLToolTipMgr::instance().show(LLToolTip::Params()
- .message(tooltip)
- .sticky_rect(calcScreenRect())
- .delay_time(timeout));
-
+ .message(tooltip)
+ .sticky_rect(calcScreenRect())
+ .delay_time(timeout));
handled = TRUE;
}
@@ -906,10 +933,12 @@ BOOL LLView::handleKey(KEY key, MASK mask, BOOL called_from_parent)
if (!handled)
{
+ // For event logging we don't care which widget handles it
+ // So we capture the key at the end of this function once we know if it was handled
handled = handleKeyHere( key, mask );
- if (handled && LLView::sDebugKeys)
+ if (handled)
{
- llinfos << "Key handled by " << getName() << llendl;
+ llwarns << "Key handled by " << getName() << llendl;
}
}
}
@@ -957,6 +986,11 @@ BOOL LLView::handleUnicodeChar(llwchar uni_char, BOOL called_from_parent)
handled = mParentView->handleUnicodeChar(uni_char, FALSE);
}
+ if (handled)
+ {
+ LLViewerEventRecorder::instance().logKeyUnicodeEvent(uni_char);
+ }
+
return handled;
}
@@ -986,12 +1020,16 @@ BOOL LLView::hasMouseCapture()
BOOL LLView::handleMouseUp(S32 x, S32 y, MASK mask)
{
- return childrenHandleMouseUp( x, y, mask ) != NULL;
+ LLView* r = childrenHandleMouseUp( x, y, mask );
+
+ return (r!=NULL);
}
BOOL LLView::handleMouseDown(S32 x, S32 y, MASK mask)
{
- return childrenHandleMouseDown( x, y, mask ) != NULL;
+ LLView* r= childrenHandleMouseDown(x, y, mask );
+
+ return (r!=NULL);
}
BOOL LLView::handleDoubleClick(S32 x, S32 y, MASK mask)
@@ -1064,7 +1102,7 @@ LLView* LLView::childrenHandleDoubleClick(S32 x, S32 y, MASK mask)
LLView* LLView::childrenHandleMouseUp(S32 x, S32 y, MASK mask)
{
- return childrenHandleMouseEvent(&LLView::handleMouseUp, x, y, mask);
+ return childrenHandleMouseEvent(&LLView::handleMouseUp, x, y, mask);
}
LLView* LLView::childrenHandleRightMouseUp(S32 x, S32 y, MASK mask)
@@ -1204,11 +1242,24 @@ void LLView::drawDebugRect()
&& preview_iter == sPreviewHighlightedElements.end()
&& sDebugRectsShowNames)
{
- //char temp[256];
S32 x, y;
gGL.color4fv( border_color.mV );
- x = debug_rect.getWidth()/2;
- y = debug_rect.getHeight()/2;
+
+ x = debug_rect.getWidth() / 2;
+
+ S32 rect_height = debug_rect.getHeight();
+ S32 lines = rect_height / LINE_HEIGHT + 1;
+
+ S32 depth = 0;
+ LLView * viewp = this;
+ while (NULL != viewp)
+ {
+ viewp = viewp->getParent();
+ depth++;
+ }
+
+ y = rect_height - LINE_HEIGHT * (depth % lines + 1);
+
std::string debug_text = llformat("%s (%d x %d)", getName().c_str(),
debug_rect.getWidth(), debug_rect.getHeight());
LLFontGL::getFontSansSerifSmall()->renderUTF8(debug_text, 0, (F32)x, (F32)y, border_color,
@@ -1549,16 +1600,18 @@ void LLView::screenPointToLocal(S32 screen_x, S32 screen_y, S32* local_x, S32* l
void LLView::localPointToScreen(S32 local_x, S32 local_y, S32* screen_x, S32* screen_y) const
{
- *screen_x = local_x + getRect().mLeft;
- *screen_y = local_y + getRect().mBottom;
+ *screen_x = local_x;
+ *screen_y = local_y;
const LLView* cur = this;
- while( cur->mParentView )
+ do
{
+ LLRect cur_rect = cur->getRect();
+ *screen_x += cur_rect.mLeft;
+ *screen_y += cur_rect.mBottom;
cur = cur->mParentView;
- *screen_x += cur->getRect().mLeft;
- *screen_y += cur->getRect().mBottom;
}
+ while( cur );
}
void LLView::screenRectToLocal(const LLRect& screen, LLRect* local) const
diff --git a/indra/llui/llview.h b/indra/llui/llview.h
index 1c35349510..15b85a6418 100644..100755
--- a/indra/llui/llview.h
+++ b/indra/llui/llview.h
@@ -67,7 +67,6 @@ const BOOL NOT_MOUSE_OPAQUE = FALSE;
const U32 GL_NAME_UI_RESERVED = 2;
-
// maintains render state during traversal of UI tree
class LLViewDrawContext
{
diff --git a/indra/llui/llviewborder.cpp b/indra/llui/llviewborder.cpp
index 919267dcc6..919267dcc6 100644..100755
--- a/indra/llui/llviewborder.cpp
+++ b/indra/llui/llviewborder.cpp
diff --git a/indra/llui/llviewborder.h b/indra/llui/llviewborder.h
index 413ce39744..413ce39744 100644..100755
--- a/indra/llui/llviewborder.h
+++ b/indra/llui/llviewborder.h
diff --git a/indra/llui/llviewereventrecorder.cpp b/indra/llui/llviewereventrecorder.cpp
new file mode 100644
index 0000000000..a352f621eb
--- /dev/null
+++ b/indra/llui/llviewereventrecorder.cpp
@@ -0,0 +1,296 @@
+/**
+ * @file llviewereventrecorder.cpp
+ * @brief Viewer event recording and playback support for mouse and keyboard events
+ *
+ * $LicenseInfo:firstyear=2013&license=viewerlgpl$
+ *
+ * Copyright (c) 2013, 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 "llviewereventrecorder.h"
+#include "llui.h"
+#include "llleap.h"
+
+LLViewerEventRecorder::LLViewerEventRecorder() {
+
+ clear(UNDEFINED);
+
+ // Remove any previous event log file
+ std::string old_log_ui_events_to_llsd_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SecondLife_Events_log.old");
+ LLFile::remove(old_log_ui_events_to_llsd_file);
+
+
+ mLogFilename = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SecondLife_Events_log.llsd");
+ LLFile::rename(mLogFilename, old_log_ui_events_to_llsd_file);
+
+}
+
+
+bool LLViewerEventRecorder::displayViewerEventRecorderMenuItems() {
+ return LLUI::sSettingGroups["config"]->getBOOL("ShowEventRecorderMenuItems");
+}
+
+
+void LLViewerEventRecorder::setEventLoggingOn() {
+ if (! mLog.is_open()) {
+ mLog.open(mLogFilename, llofstream::out);
+ }
+ logEvents=true;
+ lldebugs << "LLViewerEventRecorder::setEventLoggingOn event logging turned on" << llendl;
+}
+
+void LLViewerEventRecorder::setEventLoggingOff() {
+ logEvents=false;
+ mLog.flush();
+ mLog.close();
+ lldebugs << "LLViewerEventRecorder::setEventLoggingOff event logging turned off" << llendl;
+}
+
+
+ LLViewerEventRecorder::~LLViewerEventRecorder() {
+ if (mLog.is_open()) {
+ mLog.close();
+ }
+}
+
+void LLViewerEventRecorder::clear_xui() {
+ xui.clear();
+}
+
+void LLViewerEventRecorder::clear(S32 r) {
+
+ xui.clear();
+
+ local_x=r;
+ local_y=r;
+
+ global_x=r;
+ global_y=r;
+
+
+}
+
+void LLViewerEventRecorder::setMouseLocalCoords(S32 x, S32 y) {
+ local_x=x;
+ local_y=y;
+}
+
+void LLViewerEventRecorder::setMouseGlobalCoords(S32 x, S32 y) {
+ global_x=x;
+ global_y=y;
+}
+
+void LLViewerEventRecorder::updateMouseEventInfo(S32 local_x, S32 local_y, S32 global_x, S32 global_y, std::string mName) {
+
+ LLView * target_view = LLUI::resolvePath(LLUI::getRootView(), xui);
+ if (! target_view) {
+ lldebugs << "LLViewerEventRecorder::updateMouseEventInfo - xui path on file at moment is NOT valid - so DO NOT record these local coords" << llendl;
+ return;
+ }
+ lldebugs << "LLViewerEventRecorder::updateMouseEventInfo b4 updatemouseeventinfo - local_x|global x "<< this->local_x << " " << this->global_x << "local/global y " << this->local_y << " " << this->global_y << " mname: " << mName << " xui: " << xui << llendl;
+
+
+ if (this->local_x < 1 && this->local_y<1 && local_x && local_y) {
+ this->local_x=local_x;
+ this->local_y=local_y;
+ }
+ this->global_x=global_x;
+ this->global_y=global_y;
+
+ // ONLY record deepest xui path for hierarchy searches - or first/only xui for floaters/panels reached via mouse captor - and llmousehandler
+ if (mName!="" && mName!="/" && xui=="") {
+ // xui=std::string("/")+mName+xui;
+ //xui=mName+xui;
+ xui = mName; // TODO review confirm we never call with partial path - also cAN REMOVE CHECK FOR "" - ON OTHER HAND IT'S PRETTY HARMLESS
+ }
+
+ lldebugs << "LLViewerEventRecorder::updateMouseEventInfo after updatemouseeventinfo - local_x|global x "<< this->local_x << " " << this->global_x << "local/global y " << this->local_y << " " << this->global_y << " mname: " << mName << " xui: " << xui << llendl;
+}
+
+void LLViewerEventRecorder::logVisibilityChange(std::string xui, std::string name, BOOL visibility, std::string event_subtype) {
+
+ LLSD event=LLSD::emptyMap();
+
+ event.insert("event",LLSD(std::string("visibility")));
+
+ if (visibility) {
+ event.insert("visibility",LLSD(true));
+ } else {
+ event.insert("visibility",LLSD(false));
+ }
+
+ if (event_subtype!="") {
+ event.insert("event_subtype", LLSD(event_subtype));
+ }
+
+ if(name!="") {
+ event.insert("name",LLSD(name));
+ }
+
+ if (xui!="") {
+ event.insert("path",LLSD(xui));
+ }
+
+ event.insert("timestamp",LLSD(LLDate::now().asString()));
+ recordEvent(event);
+}
+
+
+std::string LLViewerEventRecorder::get_xui() {
+ return xui;
+}
+void LLViewerEventRecorder::update_xui(std::string xui) {
+ if (xui!="" && this->xui=="" ) {
+ lldebugs << "LLViewerEventRecorder::update_xui to " << xui << llendl;
+ this->xui=xui;
+ } else {
+ lldebugs << "LLViewerEventRecorder::update_xui called with empty string" << llendl;
+ }
+}
+
+void LLViewerEventRecorder::logKeyEvent(KEY key, MASK mask) {
+
+ // NOTE: Event recording only logs keydown events - the viewer itself hides keyup events at a fairly low level in the code and does not appear to care about them anywhere
+
+ LLSD event = LLSD::emptyMap();
+
+ event.insert("event",LLSD("type"));
+
+ // keysym ...or
+ // keycode...or
+ // char
+ event.insert("keysym",LLSD(LLKeyboard::stringFromKey(key)));
+
+ // path (optional) - for now we are not recording path for key events during record - should not be needed for full record and playback of recorded steps
+ // as a vita script - it does become useful if you edit the resulting vita script and wish to remove some steps leading to a key event - that sort of edit might
+ // break the test script and it would be useful to have more context to make these sorts of edits safer
+
+ // TODO replace this with a call which extracts to an array of names of masks (just like vita expects during playback)
+ // This is looking more and more like an object is a good idea, for this part a handy method call to setMask(mask) would be nice :-)
+ // call the func - llkeyboard::llsdStringarrayFromMask
+
+ LLSD key_mask=LLSD::emptyArray();
+
+ if (mask & MASK_CONTROL) { key_mask.append(LLSD("CTL")); } // Mac command key - has code of 0x1 in llcommon/indra_contstants
+ if (mask & MASK_ALT) { key_mask.append(LLSD("ALT")); }
+ if (mask & MASK_SHIFT) { key_mask.append(LLSD("SHIFT")); }
+ if (mask & MASK_MAC_CONTROL) { key_mask.append(LLSD("MAC_CONTROL")); }
+
+ event.insert("mask",key_mask);
+ event.insert("timestamp",LLSD(LLDate::now().asString()));
+
+ // Although vita has keyDown and keyUp requests it does not have type as a high-level concept
+ // (maybe it should) - instead it has a convenience method that generates the keydown and keyup events
+ // Here we will use "type" as our event type
+
+ lldebugs << "LLVIewerEventRecorder::logKeyEvent Serialized LLSD for event " << event.asString() << "\n" << llendl;
+
+
+ //lldebugs << "[VITA] key_name: " << LLKeyboard::stringFromKey(key) << "mask: "<< mask << "handled by " << getName() << llendl;
+ lldebugs << "LLVIewerEventRecorder::logKeyEvent key_name: " << LLKeyboard::stringFromKey(key) << "mask: "<< mask << llendl;
+
+
+ recordEvent(event);
+
+}
+
+void LLViewerEventRecorder::playbackRecording() {
+
+ LLSD LeapCommand;
+
+ // ivita sets this on startup, it also sends commands to the viewer to make start, stop, and playback menu items visible in viewer
+ LeapCommand =LLUI::sSettingGroups["config"]->getLLSD("LeapPlaybackEventsCommand");
+
+ lldebugs << "[VITA] launching playback - leap command is: " << LLSDXMLStreamer(LeapCommand) << llendl;
+ LLLeap::create("", LeapCommand, false); // exception=false
+
+}
+
+
+void LLViewerEventRecorder::recordEvent(LLSD event) {
+ lldebugs << "LLViewerEventRecorder::recordEvent event written to log: " << LLSDXMLStreamer(event) << llendl;
+ mLog << event << std::endl;
+
+}
+void LLViewerEventRecorder::logKeyUnicodeEvent(llwchar uni_char) {
+ if (! logEvents) return;
+
+ // Note: keyUp is not captured since the viewer seems to not care about keyUp events
+
+ LLSD event=LLSD::emptyMap();
+
+ event.insert("timestamp",LLSD(LLDate::now().asString()));
+
+
+ // keysym ...or
+ // keycode...or
+ // char
+
+ lldebugs << "Wrapped in conversion to wstring " << wstring_to_utf8str(LLWString( 1, uni_char)) << "\n" << llendl;
+
+ event.insert("char",
+ LLSD( wstring_to_utf8str(LLWString( 1,uni_char)) )
+ );
+
+ // path (optional) - for now we are not recording path for key events during record - should not be needed for full record and playback of recorded steps
+ // as a vita script - it does become useful if you edit the resulting vita script and wish to remove some steps leading to a key event - that sort of edit might
+ // break the test script and it would be useful to have more context to make these sorts of edits safer
+
+ // TODO need to consider mask keys too? Doesn't seem possible - at least not easily at this point
+
+ event.insert("event",LLSD("keyDown"));
+
+ lldebugs << "[VITA] unicode key: " << uni_char << llendl;
+ lldebugs << "[VITA] dumpxml " << LLSDXMLStreamer(event) << "\n" << llendl;
+
+
+ recordEvent(event);
+
+}
+
+void LLViewerEventRecorder::logMouseEvent(std::string button_state,std::string button_name)
+{
+ if (! logEvents) return;
+
+ LLSD event=LLSD::emptyMap();
+
+ event.insert("event",LLSD(std::string("mouse"+ button_state)));
+ event.insert("button",LLSD(button_name));
+ if (xui!="") {
+ event.insert("path",LLSD(xui));
+ }
+
+ if (local_x>0 && local_y>0) {
+ event.insert("local_x",LLSD(local_x));
+ event.insert("local_y",LLSD(local_y));
+ }
+
+ if (global_x>0 && global_y>0) {
+ event.insert("global_x",LLSD(global_x));
+ event.insert("global_y",LLSD(global_y));
+ }
+ event.insert("timestamp",LLSD(LLDate::now().asString()));
+ recordEvent(event);
+
+
+ clear(UNDEFINED);
+
+
+}
diff --git a/indra/llui/llviewereventrecorder.h b/indra/llui/llviewereventrecorder.h
new file mode 100644
index 0000000000..72ca643ced
--- /dev/null
+++ b/indra/llui/llviewereventrecorder.h
@@ -0,0 +1,103 @@
+/**
+ * @file llviewereventrecorder.h
+ * @brief Viewer event recording and playback support for mouse and keyboard events
+ *
+ * $LicenseInfo:firstyear=2013&license=viewerlgpl$
+ *
+ * Copyright (c) 2013, 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_VIEWER_EVENT_RECORDER
+#define LL_VIEWER_EVENT_RECORDER
+
+
+#include "linden_common.h"
+
+#include "lldir.h"
+#include "llsd.h"
+#include "llfile.h"
+#include "llvfile.h"
+#include "lldate.h"
+#include "llsdserialize.h"
+#include "llkeyboard.h"
+#include "llstring.h"
+
+#include <sstream>
+
+#include "llsingleton.h" // includes llerror which we need here so we can skip the include here
+
+class LLViewerEventRecorder : public LLSingleton<LLViewerEventRecorder>
+{
+
+ public:
+
+ LLViewerEventRecorder(); // TODO Protect constructor better if we can (not happy in private section) - could add a factory... - we are singleton
+ ~LLViewerEventRecorder();
+
+
+ void updateMouseEventInfo(S32 local_x,S32 local_y, S32 global_x, S32 global_y, std::string mName);
+ void setMouseLocalCoords(S32 x,S32 y);
+ void setMouseGlobalCoords(S32 x,S32 y);
+
+ void logMouseEvent(std::string button_state, std::string button_name );
+ void logKeyEvent(KEY key, MASK mask);
+ void logKeyUnicodeEvent(llwchar uni_char);
+
+ void logVisibilityChange(std::string xui, std::string name, BOOL visibility, std::string event_subtype);
+
+ void clear_xui();
+ std::string get_xui();
+ void update_xui(std::string xui);
+
+ bool getLoggingStatus();
+ void setEventLoggingOn();
+ void setEventLoggingOff();
+
+ void playbackRecording();
+
+ bool displayViewerEventRecorderMenuItems();
+
+
+ protected:
+ // On if we wish to log events at the moment - toggle via Develop/Recorder submenu
+ bool logEvents;
+
+ std::string mLogFilename;
+ llofstream mLog;
+
+
+ private:
+
+ // Mouse event info
+ S32 global_x;
+ S32 global_y;
+ S32 local_x;
+ S32 local_y;
+
+ // XUI path of UI element
+ std::string xui;
+
+ // Actually write the event out to llsd log file
+ void recordEvent(LLSD event);
+
+ void clear(S32 r);
+
+ static const S32 UNDEFINED=-1;
+};
+#endif
diff --git a/indra/llui/llviewinject.cpp b/indra/llui/llviewinject.cpp
index 46c5839f8e..46c5839f8e 100644..100755
--- a/indra/llui/llviewinject.cpp
+++ b/indra/llui/llviewinject.cpp
diff --git a/indra/llui/llviewinject.h b/indra/llui/llviewinject.h
index 0de3d155c4..0de3d155c4 100644..100755
--- a/indra/llui/llviewinject.h
+++ b/indra/llui/llviewinject.h
diff --git a/indra/llui/llviewmodel.cpp b/indra/llui/llviewmodel.cpp
index a9f8acc440..a9f8acc440 100644..100755
--- a/indra/llui/llviewmodel.cpp
+++ b/indra/llui/llviewmodel.cpp
diff --git a/indra/llui/llviewmodel.h b/indra/llui/llviewmodel.h
index 763af5d8a2..ef2e314799 100644..100755
--- a/indra/llui/llviewmodel.h
+++ b/indra/llui/llviewmodel.h
@@ -102,6 +102,7 @@ public:
// New functions
/// Get the stored value in string form
const LLWString& getDisplay() const { return mDisplay; }
+ LLWString& getEditableDisplay() { mDirty = true; mUpdateFromDisplay = true; return mDisplay; }
/**
* Set the display string directly (see LLTextEditor). What the user is
diff --git a/indra/llui/llviewquery.cpp b/indra/llui/llviewquery.cpp
index d0b78ba186..d0b78ba186 100644..100755
--- a/indra/llui/llviewquery.cpp
+++ b/indra/llui/llviewquery.cpp
diff --git a/indra/llui/llviewquery.h b/indra/llui/llviewquery.h
index 210f95162a..210f95162a 100644..100755
--- a/indra/llui/llviewquery.h
+++ b/indra/llui/llviewquery.h
diff --git a/indra/llui/llwindowshade.cpp b/indra/llui/llwindowshade.cpp
index f5c463c961..f5c463c961 100644..100755
--- a/indra/llui/llwindowshade.cpp
+++ b/indra/llui/llwindowshade.cpp
diff --git a/indra/llui/llwindowshade.h b/indra/llui/llwindowshade.h
index 6d753d1161..6d753d1161 100644..100755
--- a/indra/llui/llwindowshade.h
+++ b/indra/llui/llwindowshade.h
diff --git a/indra/llui/llxuiparser.cpp b/indra/llui/llxuiparser.cpp
new file mode 100755
index 0000000000..6322da9123
--- /dev/null
+++ b/indra/llui/llxuiparser.cpp
@@ -0,0 +1,1780 @@
+/**
+ * @file llxuiparser.cpp
+ * @brief Utility functions for handling XUI structures in XML
+ *
+ * $LicenseInfo:firstyear=2003&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 "llxuiparser.h"
+
+#include "llxmlnode.h"
+
+#ifdef LL_STANDALONE
+#include <expat.h>
+#else
+#include "expat/expat.h"
+#endif
+
+#include <fstream>
+#include <boost/tokenizer.hpp>
+//#include <boost/spirit/include/qi.hpp>
+#include <boost/spirit/include/classic_core.hpp>
+
+#include "lluicolor.h"
+#include "v3math.h"
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+const S32 MAX_STRING_ATTRIBUTE_SIZE = 40;
+
+static LLInitParam::Parser::parser_read_func_map_t sXSDReadFuncs;
+static LLInitParam::Parser::parser_write_func_map_t sXSDWriteFuncs;
+static LLInitParam::Parser::parser_inspect_func_map_t sXSDInspectFuncs;
+
+static LLInitParam::Parser::parser_read_func_map_t sSimpleXUIReadFuncs;
+static LLInitParam::Parser::parser_write_func_map_t sSimpleXUIWriteFuncs;
+static LLInitParam::Parser::parser_inspect_func_map_t sSimpleXUIInspectFuncs;
+
+const char* NO_VALUE_MARKER = "no_value";
+
+const S32 LINE_NUMBER_HERE = 0;
+
+struct MaxOccursValues : public LLInitParam::TypeValuesHelper<U32, MaxOccursValues>
+{
+ static void declareValues()
+ {
+ declare("unbounded", U32_MAX);
+ }
+};
+
+struct Occurs : public LLInitParam::Block<Occurs>
+{
+ Optional<U32> minOccurs;
+ Optional<U32, MaxOccursValues> maxOccurs;
+
+ Occurs()
+ : minOccurs("minOccurs", 0),
+ maxOccurs("maxOccurs", U32_MAX)
+
+ {}
+};
+
+typedef enum
+{
+ USE_REQUIRED,
+ USE_OPTIONAL
+} EUse;
+
+namespace LLInitParam
+{
+ template<>
+ struct TypeValues<EUse> : public TypeValuesHelper<EUse>
+ {
+ static void declareValues()
+ {
+ declare("required", USE_REQUIRED);
+ declare("optional", USE_OPTIONAL);
+ }
+ };
+}
+
+struct Element;
+struct Group;
+struct Sequence;
+
+struct All : public LLInitParam::Block<All, Occurs>
+{
+ Multiple< Lazy<Element, IS_A_BLOCK> > elements;
+
+ All()
+ : elements("element")
+ {
+ maxOccurs = 1;
+ }
+};
+
+struct Attribute : public LLInitParam::Block<Attribute>
+{
+ Mandatory<std::string> name,
+ type;
+ Mandatory<EUse> use;
+
+ Attribute()
+ : name("name"),
+ type("type"),
+ use("use")
+ {}
+};
+
+struct Any : public LLInitParam::Block<Any, Occurs>
+{
+ Optional<std::string> _namespace;
+
+ Any()
+ : _namespace("namespace")
+ {}
+};
+
+struct Choice : public LLInitParam::ChoiceBlock<Choice, Occurs>
+{
+ Alternative< Lazy<Element, IS_A_BLOCK> > element;
+ Alternative< Lazy<Group, IS_A_BLOCK> > group;
+ Alternative< Lazy<Choice, IS_A_BLOCK> > choice;
+ Alternative< Lazy<Sequence, IS_A_BLOCK> > sequence;
+ Alternative< Lazy<Any> > any;
+
+ Choice()
+ : element("element"),
+ group("group"),
+ choice("choice"),
+ sequence("sequence"),
+ any("any")
+ {}
+
+};
+
+struct Sequence : public LLInitParam::ChoiceBlock<Sequence, Occurs>
+{
+ Alternative< Lazy<Element, IS_A_BLOCK> > element;
+ Alternative< Lazy<Group, IS_A_BLOCK> > group;
+ Alternative< Lazy<Choice> > choice;
+ Alternative< Lazy<Sequence, IS_A_BLOCK> > sequence;
+ Alternative< Lazy<Any> > any;
+};
+
+struct GroupContents : public LLInitParam::ChoiceBlock<GroupContents, Occurs>
+{
+ Alternative<All> all;
+ Alternative<Choice> choice;
+ Alternative<Sequence> sequence;
+
+ GroupContents()
+ : all("all"),
+ choice("choice"),
+ sequence("sequence")
+ {}
+};
+
+struct Group : public LLInitParam::Block<Group, GroupContents>
+{
+ Optional<std::string> name,
+ ref;
+
+ Group()
+ : name("name"),
+ ref("ref")
+ {}
+};
+
+struct Restriction : public LLInitParam::Block<Restriction>
+{
+};
+
+struct Extension : public LLInitParam::Block<Extension>
+{
+};
+
+struct SimpleContent : public LLInitParam::ChoiceBlock<SimpleContent>
+{
+ Alternative<Restriction> restriction;
+ Alternative<Extension> extension;
+
+ SimpleContent()
+ : restriction("restriction"),
+ extension("extension")
+ {}
+};
+
+struct SimpleType : public LLInitParam::Block<SimpleType>
+{
+ // TODO
+};
+
+struct ComplexContent : public LLInitParam::Block<ComplexContent, SimpleContent>
+{
+ Optional<bool> mixed;
+
+ ComplexContent()
+ : mixed("mixed", true)
+ {}
+};
+
+struct ComplexTypeContents : public LLInitParam::ChoiceBlock<ComplexTypeContents>
+{
+ Alternative<SimpleContent> simple_content;
+ Alternative<ComplexContent> complex_content;
+ Alternative<Group> group;
+ Alternative<All> all;
+ Alternative<Choice> choice;
+ Alternative<Sequence> sequence;
+
+ ComplexTypeContents()
+ : simple_content("simpleContent"),
+ complex_content("complexContent"),
+ group("group"),
+ all("all"),
+ choice("choice"),
+ sequence("sequence")
+ {}
+};
+
+struct ComplexType : public LLInitParam::Block<ComplexType, ComplexTypeContents>
+{
+ Optional<std::string> name;
+ Optional<bool> mixed;
+
+ Multiple<Attribute> attribute;
+ Multiple< Lazy<Element, IS_A_BLOCK > > elements;
+
+ ComplexType()
+ : name("name"),
+ attribute("xs:attribute"),
+ elements("xs:element"),
+ mixed("mixed")
+ {
+ }
+};
+
+struct ElementContents : public LLInitParam::ChoiceBlock<ElementContents, Occurs>
+{
+ Alternative<SimpleType> simpleType;
+ Alternative<ComplexType> complexType;
+
+ ElementContents()
+ : simpleType("simpleType"),
+ complexType("complexType")
+ {}
+};
+
+struct Element : public LLInitParam::Block<Element, ElementContents>
+{
+ Optional<std::string> name,
+ ref,
+ type;
+
+ Element()
+ : name("xs:name"),
+ ref("xs:ref"),
+ type("xs:type")
+ {}
+};
+
+struct Schema : public LLInitParam::Block<Schema>
+{
+private:
+ Mandatory<std::string> targetNamespace,
+ xmlns,
+ xs;
+
+public:
+ Optional<std::string> attributeFormDefault,
+ elementFormDefault;
+
+ Mandatory<Element> root_element;
+
+ void setNameSpace(const std::string& ns) {targetNamespace = ns; xmlns = ns;}
+
+ Schema(const std::string& ns = LLStringUtil::null)
+ : attributeFormDefault("attributeFormDefault"),
+ elementFormDefault("elementFormDefault"),
+ xs("xmlns:xs"),
+ targetNamespace("targetNamespace"),
+ xmlns("xmlns"),
+ root_element("xs:element")
+ {
+ attributeFormDefault = "unqualified";
+ elementFormDefault = "qualified";
+ xs = "http://www.w3.org/2001/XMLSchema";
+ if (!ns.empty())
+ {
+ setNameSpace(ns);
+ };
+ }
+};
+
+//
+// LLXSDWriter
+//
+LLXSDWriter::LLXSDWriter()
+: Parser(sXSDReadFuncs, sXSDWriteFuncs, sXSDInspectFuncs)
+{
+ registerInspectFunc<bool>(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:boolean", _1, _2, _3, _4));
+ registerInspectFunc<std::string>(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:string", _1, _2, _3, _4));
+ registerInspectFunc<U8>(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:unsignedByte", _1, _2, _3, _4));
+ registerInspectFunc<S8>(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:signedByte", _1, _2, _3, _4));
+ registerInspectFunc<U16>(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:unsignedShort", _1, _2, _3, _4));
+ registerInspectFunc<S16>(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:signedShort", _1, _2, _3, _4));
+ registerInspectFunc<U32>(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:unsignedInt", _1, _2, _3, _4));
+ registerInspectFunc<S32>(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:integer", _1, _2, _3, _4));
+ registerInspectFunc<F32>(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:float", _1, _2, _3, _4));
+ registerInspectFunc<F64>(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:double", _1, _2, _3, _4));
+ registerInspectFunc<LLColor4>(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:string", _1, _2, _3, _4));
+ registerInspectFunc<LLUIColor>(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:string", _1, _2, _3, _4));
+ registerInspectFunc<LLUUID>(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:string", _1, _2, _3, _4));
+ registerInspectFunc<LLSD>(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:string", _1, _2, _3, _4));
+}
+
+void LLXSDWriter::writeXSD(const std::string& type_name, LLXMLNodePtr node, const LLInitParam::BaseBlock& block, const std::string& xml_namespace)
+{
+ Schema schema(xml_namespace);
+
+ schema.root_element.name = type_name;
+ Choice& choice = schema.root_element.complexType.choice;
+
+ choice.minOccurs = 0;
+ choice.maxOccurs = "unbounded";
+
+ mSchemaNode = node;
+ //node->setName("xs:schema");
+ //node->createChild("attributeFormDefault", true)->setStringValue("unqualified");
+ //node->createChild("elementFormDefault", true)->setStringValue("qualified");
+ //node->createChild("targetNamespace", true)->setStringValue(xml_namespace);
+ //node->createChild("xmlns:xs", true)->setStringValue("http://www.w3.org/2001/XMLSchema");
+ //node->createChild("xmlns", true)->setStringValue(xml_namespace);
+
+ //node = node->createChild("xs:complexType", false);
+ //node->createChild("name", true)->setStringValue(type_name);
+ //node->createChild("mixed", true)->setStringValue("true");
+
+ //mAttributeNode = node;
+ //mElementNode = node->createChild("xs:choice", false);
+ //mElementNode->createChild("minOccurs", true)->setStringValue("0");
+ //mElementNode->createChild("maxOccurs", true)->setStringValue("unbounded");
+ block.inspectBlock(*this);
+
+ // duplicate element choices
+ LLXMLNodeList children;
+ mElementNode->getChildren("xs:element", children, FALSE);
+ for (LLXMLNodeList::iterator child_it = children.begin(); child_it != children.end(); ++child_it)
+ {
+ LLXMLNodePtr child_copy = child_it->second->deepCopy();
+ std::string child_name;
+ child_copy->getAttributeString("name", child_name);
+ child_copy->setAttributeString("name", type_name + "." + child_name);
+ mElementNode->addChild(child_copy);
+ }
+
+ LLXMLNodePtr element_declaration_node = mSchemaNode->createChild("xs:element", false);
+ element_declaration_node->createChild("name", true)->setStringValue(type_name);
+ element_declaration_node->createChild("type", true)->setStringValue(type_name);
+}
+
+void LLXSDWriter::writeAttribute(const std::string& type, const Parser::name_stack_t& stack, S32 min_count, S32 max_count, const std::vector<std::string>* possible_values)
+{
+ name_stack_t non_empty_names;
+ std::string attribute_name;
+ for (name_stack_t::const_iterator it = stack.begin();
+ it != stack.end();
+ ++it)
+ {
+ const std::string& name = it->first;
+ if (!name.empty())
+ {
+ non_empty_names.push_back(*it);
+ }
+ }
+
+ for (name_stack_t::const_iterator it = non_empty_names.begin();
+ it != non_empty_names.end();
+ ++it)
+ {
+ if (!attribute_name.empty())
+ {
+ attribute_name += ".";
+ }
+ attribute_name += it->first;
+ }
+
+ // only flag non-nested attributes as mandatory, nested attributes have variant syntax
+ // that can't be properly constrained in XSD
+ // e.g. <foo mandatory.value="bar"/> vs <foo><mandatory value="bar"/></foo>
+ bool attribute_mandatory = min_count == 1 && max_count == 1 && non_empty_names.size() == 1;
+
+ // don't bother supporting "Multiple" params as xml attributes
+ if (max_count <= 1)
+ {
+ // add compound attribute to root node
+ addAttributeToSchema(mAttributeNode, attribute_name, type, attribute_mandatory, possible_values);
+ }
+
+ // now generated nested elements for compound attributes
+ if (non_empty_names.size() > 1 && !attribute_mandatory)
+ {
+ std::string element_name;
+
+ // traverse all but last element, leaving that as an attribute name
+ name_stack_t::const_iterator end_it = non_empty_names.end();
+ end_it--;
+
+ for (name_stack_t::const_iterator it = non_empty_names.begin();
+ it != end_it;
+ ++it)
+ {
+ if (it != non_empty_names.begin())
+ {
+ element_name += ".";
+ }
+ element_name += it->first;
+ }
+
+ std::string short_attribute_name = non_empty_names.back().first;
+
+ LLXMLNodePtr complex_type_node;
+
+ // find existing element node here, starting at tail of child list
+ if (mElementNode->mChildren.notNull())
+ {
+ for(LLXMLNodePtr element = mElementNode->mChildren->tail;
+ element.notNull();
+ element = element->mPrev)
+ {
+ std::string name;
+ if(element->getAttributeString("name", name) && name == element_name)
+ {
+ complex_type_node = element->mChildren->head;
+ break;
+ }
+ }
+ }
+ //create complex_type node
+ //
+ //<xs:element
+ // maxOccurs="1"
+ // minOccurs="0"
+ // name="name">
+ // <xs:complexType>
+ // </xs:complexType>
+ //</xs:element>
+ if(complex_type_node.isNull())
+ {
+ complex_type_node = mElementNode->createChild("xs:element", false);
+
+ complex_type_node->createChild("minOccurs", true)->setIntValue(min_count);
+ complex_type_node->createChild("maxOccurs", true)->setIntValue(max_count);
+ complex_type_node->createChild("name", true)->setStringValue(element_name);
+ complex_type_node = complex_type_node->createChild("xs:complexType", false);
+ }
+
+ addAttributeToSchema(complex_type_node, short_attribute_name, type, false, possible_values);
+ }
+}
+
+void LLXSDWriter::addAttributeToSchema(LLXMLNodePtr type_declaration_node, const std::string& attribute_name, const std::string& type, bool mandatory, const std::vector<std::string>* possible_values)
+{
+ if (!attribute_name.empty())
+ {
+ LLXMLNodePtr new_enum_type_node;
+ if (possible_values != NULL)
+ {
+ // custom attribute type, for example
+ //<xs:simpleType>
+ // <xs:restriction
+ // base="xs:string">
+ // <xs:enumeration
+ // value="a" />
+ // <xs:enumeration
+ // value="b" />
+ // </xs:restriction>
+ // </xs:simpleType>
+ new_enum_type_node = new LLXMLNode("xs:simpleType", false);
+
+ LLXMLNodePtr restriction_node = new_enum_type_node->createChild("xs:restriction", false);
+ restriction_node->createChild("base", true)->setStringValue("xs:string");
+
+ for (std::vector<std::string>::const_iterator it = possible_values->begin();
+ it != possible_values->end();
+ ++it)
+ {
+ LLXMLNodePtr enum_node = restriction_node->createChild("xs:enumeration", false);
+ enum_node->createChild("value", true)->setStringValue(*it);
+ }
+ }
+
+ string_set_t& attributes_written = mAttributesWritten[type_declaration_node];
+
+ string_set_t::iterator found_it = attributes_written.lower_bound(attribute_name);
+
+ // attribute not yet declared
+ if (found_it == attributes_written.end() || attributes_written.key_comp()(attribute_name, *found_it))
+ {
+ attributes_written.insert(found_it, attribute_name);
+
+ LLXMLNodePtr attribute_node = type_declaration_node->createChild("xs:attribute", false);
+
+ // attribute name
+ attribute_node->createChild("name", true)->setStringValue(attribute_name);
+
+ if (new_enum_type_node.notNull())
+ {
+ attribute_node->addChild(new_enum_type_node);
+ }
+ else
+ {
+ // simple attribute type
+ attribute_node->createChild("type", true)->setStringValue(type);
+ }
+
+ // required or optional
+ attribute_node->createChild("use", true)->setStringValue(mandatory ? "required" : "optional");
+ }
+ // attribute exists...handle collision of same name attributes with potentially different types
+ else
+ {
+ LLXMLNodePtr attribute_declaration;
+ if (type_declaration_node.notNull())
+ {
+ for(LLXMLNodePtr node = type_declaration_node->mChildren->tail;
+ node.notNull();
+ node = node->mPrev)
+ {
+ std::string name;
+ if (node->getAttributeString("name", name) && name == attribute_name)
+ {
+ attribute_declaration = node;
+ break;
+ }
+ }
+ }
+
+ bool new_type_is_enum = new_enum_type_node.notNull();
+ bool existing_type_is_enum = !attribute_declaration->hasAttribute("type");
+
+ // either type is enum, revert to string in collision
+ // don't bother to check for enum equivalence
+ if (new_type_is_enum || existing_type_is_enum)
+ {
+ if (attribute_declaration->hasAttribute("type"))
+ {
+ attribute_declaration->setAttributeString("type", "xs:string");
+ }
+ else
+ {
+ attribute_declaration->createChild("type", true)->setStringValue("xs:string");
+ }
+ attribute_declaration->deleteChildren("xs:simpleType");
+ }
+ else
+ {
+ // check for collision of different standard types
+ std::string existing_type;
+ attribute_declaration->getAttributeString("type", existing_type);
+ // if current type is not the same as the new type, revert to strnig
+ if (existing_type != type)
+ {
+ // ...than use most general type, string
+ attribute_declaration->setAttributeString("type", "string");
+ }
+ }
+ }
+ }
+}
+
+//
+// LLXUIXSDWriter
+//
+void LLXUIXSDWriter::writeXSD(const std::string& type_name, const std::string& path, const LLInitParam::BaseBlock& block)
+{
+ std::string file_name(path);
+ file_name += type_name + ".xsd";
+ LLXMLNodePtr root_nodep = new LLXMLNode();
+
+ LLXSDWriter::writeXSD(type_name, root_nodep, block, "http://www.lindenlab.com/xui");
+
+ // add includes for all possible children
+ const std::type_info* type = *LLWidgetTypeRegistry::instance().getValue(type_name);
+ const widget_registry_t* widget_registryp = LLChildRegistryRegistry::instance().getValue(type);
+
+ // add choices for valid children
+ if (widget_registryp)
+ {
+ // add include declarations for all valid children
+ for (widget_registry_t::Registrar::registry_map_t::const_iterator it = widget_registryp->currentRegistrar().beginItems();
+ it != widget_registryp->currentRegistrar().endItems();
+ ++it)
+ {
+ std::string widget_name = it->first;
+ if (widget_name == type_name)
+ {
+ continue;
+ }
+ LLXMLNodePtr nodep = new LLXMLNode("xs:include", false);
+ nodep->createChild("schemaLocation", true)->setStringValue(widget_name + ".xsd");
+
+ // add to front of schema
+ mSchemaNode->addChild(nodep);
+ }
+
+ for (widget_registry_t::Registrar::registry_map_t::const_iterator it = widget_registryp->currentRegistrar().beginItems();
+ it != widget_registryp->currentRegistrar().endItems();
+ ++it)
+ {
+ std::string widget_name = it->first;
+ //<xs:element name="widget_name" type="widget_name">
+ LLXMLNodePtr widget_node = mElementNode->createChild("xs:element", false);
+ widget_node->createChild("name", true)->setStringValue(widget_name);
+ widget_node->createChild("type", true)->setStringValue(widget_name);
+ }
+ }
+
+ LLFILE* xsd_file = LLFile::fopen(file_name.c_str(), "w");
+ LLXMLNode::writeHeaderToFile(xsd_file);
+ root_nodep->writeToFile(xsd_file);
+ fclose(xsd_file);
+}
+
+static LLInitParam::Parser::parser_read_func_map_t sXUIReadFuncs;
+static LLInitParam::Parser::parser_write_func_map_t sXUIWriteFuncs;
+static LLInitParam::Parser::parser_inspect_func_map_t sXUIInspectFuncs;
+
+//
+// LLXUIParser
+//
+LLXUIParser::LLXUIParser()
+: Parser(sXUIReadFuncs, sXUIWriteFuncs, sXUIInspectFuncs),
+ mCurReadDepth(0)
+{
+ if (sXUIReadFuncs.empty())
+ {
+ registerParserFuncs<LLInitParam::Flag>(readFlag, writeFlag);
+ registerParserFuncs<bool>(readBoolValue, writeBoolValue);
+ registerParserFuncs<std::string>(readStringValue, writeStringValue);
+ registerParserFuncs<U8>(readU8Value, writeU8Value);
+ registerParserFuncs<S8>(readS8Value, writeS8Value);
+ registerParserFuncs<U16>(readU16Value, writeU16Value);
+ registerParserFuncs<S16>(readS16Value, writeS16Value);
+ registerParserFuncs<U32>(readU32Value, writeU32Value);
+ registerParserFuncs<S32>(readS32Value, writeS32Value);
+ registerParserFuncs<F32>(readF32Value, writeF32Value);
+ registerParserFuncs<F64>(readF64Value, writeF64Value);
+ registerParserFuncs<LLVector3>(readVector3Value, writeVector3Value);
+ registerParserFuncs<LLColor4>(readColor4Value, writeColor4Value);
+ registerParserFuncs<LLUIColor>(readUIColorValue, writeUIColorValue);
+ registerParserFuncs<LLUUID>(readUUIDValue, writeUUIDValue);
+ registerParserFuncs<LLSD>(readSDValue, writeSDValue);
+ }
+}
+
+static LLFastTimer::DeclareTimer FTM_PARSE_XUI("XUI Parsing");
+const LLXMLNodePtr DUMMY_NODE = new LLXMLNode();
+
+void LLXUIParser::readXUI(LLXMLNodePtr node, LLInitParam::BaseBlock& block, const std::string& filename, bool silent)
+{
+ LLFastTimer timer(FTM_PARSE_XUI);
+ mNameStack.clear();
+ mRootNodeName = node->getName()->mString;
+ mCurFileName = filename;
+ mCurReadDepth = 0;
+ setParseSilently(silent);
+
+ if (node.isNull())
+ {
+ parserWarning("Invalid node");
+ }
+ else
+ {
+ readXUIImpl(node, block);
+ }
+}
+
+bool LLXUIParser::readXUIImpl(LLXMLNodePtr nodep, LLInitParam::BaseBlock& block)
+{
+ typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
+ boost::char_separator<char> sep(".");
+
+ bool values_parsed = false;
+ bool silent = mCurReadDepth > 0;
+
+ if (nodep->getFirstChild().isNull()
+ && nodep->mAttributes.empty()
+ && nodep->getSanitizedValue().empty())
+ {
+ // empty node, just parse as flag
+ mCurReadNode = DUMMY_NODE;
+ return block.submitValue(mNameStack, *this, silent);
+ }
+
+ // submit attributes for current node
+ values_parsed |= readAttributes(nodep, block);
+
+ // treat text contents of xml node as "value" parameter
+ std::string text_contents = nodep->getSanitizedValue();
+ if (!text_contents.empty())
+ {
+ mCurReadNode = nodep;
+ mNameStack.push_back(std::make_pair(std::string("value"), true));
+ // child nodes are not necessarily valid parameters (could be a child widget)
+ // so don't complain once we've recursed
+ if (!block.submitValue(mNameStack, *this, true))
+ {
+ mNameStack.pop_back();
+ block.submitValue(mNameStack, *this, silent);
+ }
+ else
+ {
+ mNameStack.pop_back();
+ }
+ }
+
+ // then traverse children
+ // child node must start with last name of parent node (our "scope")
+ // for example: "<button><button.param nested_param1="foo"><param.nested_param2 nested_param3="bar"/></button.param></button>"
+ // which equates to the following nesting:
+ // button
+ // param
+ // nested_param1
+ // nested_param2
+ // nested_param3
+ mCurReadDepth++;
+ for(LLXMLNodePtr childp = nodep->getFirstChild(); childp.notNull();)
+ {
+ std::string child_name(childp->getName()->mString);
+ S32 num_tokens_pushed = 0;
+
+ // for non "dotted" child nodes check to see if child node maps to another widget type
+ // and if not, treat as a child element of the current node
+ // e.g. <button><rect left="10"/></button> will interpret <rect> as "button.rect"
+ // since there is no widget named "rect"
+ if (child_name.find(".") == std::string::npos)
+ {
+ mNameStack.push_back(std::make_pair(child_name, true));
+ num_tokens_pushed++;
+ }
+ else
+ {
+ // parse out "dotted" name into individual tokens
+ tokenizer name_tokens(child_name, sep);
+
+ tokenizer::iterator name_token_it = name_tokens.begin();
+ if(name_token_it == name_tokens.end())
+ {
+ childp = childp->getNextSibling();
+ continue;
+ }
+
+ // check for proper nesting
+ if (mNameStack.empty())
+ {
+ if (*name_token_it != mRootNodeName)
+ {
+ childp = childp->getNextSibling();
+ continue;
+ }
+ }
+ else if(mNameStack.back().first != *name_token_it)
+ {
+ childp = childp->getNextSibling();
+ continue;
+ }
+
+ // now ignore first token
+ ++name_token_it;
+
+ // copy remaining tokens on to our running token list
+ for(tokenizer::iterator token_to_push = name_token_it; token_to_push != name_tokens.end(); ++token_to_push)
+ {
+ mNameStack.push_back(std::make_pair(*token_to_push, true));
+ num_tokens_pushed++;
+ }
+ }
+
+ // recurse and visit children XML nodes
+ if(readXUIImpl(childp, block))
+ {
+ // child node successfully parsed, remove from DOM
+
+ values_parsed = true;
+ LLXMLNodePtr node_to_remove = childp;
+ childp = childp->getNextSibling();
+
+ nodep->deleteChild(node_to_remove);
+ }
+ else
+ {
+ childp = childp->getNextSibling();
+ }
+
+ while(num_tokens_pushed-- > 0)
+ {
+ mNameStack.pop_back();
+ }
+ }
+ mCurReadDepth--;
+ return values_parsed;
+}
+
+bool LLXUIParser::readAttributes(LLXMLNodePtr nodep, LLInitParam::BaseBlock& block)
+{
+ typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
+ boost::char_separator<char> sep(".");
+
+ bool any_parsed = false;
+ bool silent = mCurReadDepth > 0;
+
+ for(LLXMLAttribList::const_iterator attribute_it = nodep->mAttributes.begin();
+ attribute_it != nodep->mAttributes.end();
+ ++attribute_it)
+ {
+ S32 num_tokens_pushed = 0;
+ std::string attribute_name(attribute_it->first->mString);
+ mCurReadNode = attribute_it->second;
+
+ tokenizer name_tokens(attribute_name, sep);
+ // copy remaining tokens on to our running token list
+ for(tokenizer::iterator token_to_push = name_tokens.begin(); token_to_push != name_tokens.end(); ++token_to_push)
+ {
+ mNameStack.push_back(std::make_pair(*token_to_push, true));
+ num_tokens_pushed++;
+ }
+
+ // child nodes are not necessarily valid attributes, so don't complain once we've recursed
+ any_parsed |= block.submitValue(mNameStack, *this, silent);
+
+ while(num_tokens_pushed-- > 0)
+ {
+ mNameStack.pop_back();
+ }
+ }
+
+ return any_parsed;
+}
+
+void LLXUIParser::writeXUI(LLXMLNodePtr node, const LLInitParam::BaseBlock &block, const LLInitParam::BaseBlock* diff_block)
+{
+ mWriteRootNode = node;
+ name_stack_t name_stack = Parser::name_stack_t();
+ block.serializeBlock(*this, name_stack, diff_block);
+ mOutNodes.clear();
+}
+
+// go from a stack of names to a specific XML node
+LLXMLNodePtr LLXUIParser::getNode(name_stack_t& stack)
+{
+ LLXMLNodePtr out_node = mWriteRootNode;
+
+ name_stack_t::iterator next_it = stack.begin();
+ for (name_stack_t::iterator it = stack.begin();
+ it != stack.end();
+ it = next_it)
+ {
+ ++next_it;
+ bool force_new_node = false;
+
+ if (it->first.empty())
+ {
+ it->second = false;
+ continue;
+ }
+
+ if (next_it != stack.end() && next_it->first.empty() && next_it->second)
+ {
+ force_new_node = true;
+ }
+
+
+ out_nodes_t::iterator found_it = mOutNodes.find(it->first);
+
+ // node with this name not yet written
+ if (found_it == mOutNodes.end() || it->second || force_new_node)
+ {
+ // make an attribute if we are the last element on the name stack
+ bool is_attribute = next_it == stack.end();
+ LLXMLNodePtr new_node = new LLXMLNode(it->first.c_str(), is_attribute);
+ out_node->addChild(new_node);
+ mOutNodes[it->first] = new_node;
+ out_node = new_node;
+ it->second = false;
+ }
+ else
+ {
+ out_node = found_it->second;
+ }
+ }
+
+ return (out_node == mWriteRootNode ? LLXMLNodePtr(NULL) : out_node);
+}
+
+bool LLXUIParser::readFlag(Parser& parser, void* val_ptr)
+{
+ LLXUIParser& self = static_cast<LLXUIParser&>(parser);
+ return self.mCurReadNode == DUMMY_NODE;
+}
+
+bool LLXUIParser::writeFlag(Parser& parser, const void* val_ptr, name_stack_t& stack)
+{
+ // just create node
+ LLXUIParser& self = static_cast<LLXUIParser&>(parser);
+ LLXMLNodePtr node = self.getNode(stack);
+ return node.notNull();
+}
+
+bool LLXUIParser::readBoolValue(Parser& parser, void* val_ptr)
+{
+ S32 value;
+ LLXUIParser& self = static_cast<LLXUIParser&>(parser);
+ bool success = self.mCurReadNode->getBoolValue(1, &value);
+ *((bool*)val_ptr) = (value != FALSE);
+ return success;
+}
+
+bool LLXUIParser::writeBoolValue(Parser& parser, const void* val_ptr, name_stack_t& stack)
+{
+ LLXUIParser& self = static_cast<LLXUIParser&>(parser);
+ LLXMLNodePtr node = self.getNode(stack);
+ if (node.notNull())
+ {
+ node->setBoolValue(*((bool*)val_ptr));
+ return true;
+ }
+ return false;
+}
+
+bool LLXUIParser::readStringValue(Parser& parser, void* val_ptr)
+{
+ LLXUIParser& self = static_cast<LLXUIParser&>(parser);
+ *((std::string*)val_ptr) = self.mCurReadNode->getSanitizedValue();
+ return true;
+}
+
+bool LLXUIParser::writeStringValue(Parser& parser, const void* val_ptr, name_stack_t& stack)
+{
+ LLXUIParser& self = static_cast<LLXUIParser&>(parser);
+ LLXMLNodePtr node = self.getNode(stack);
+ if (node.notNull())
+ {
+ const std::string* string_val = reinterpret_cast<const std::string*>(val_ptr);
+ if (string_val->find('\n') != std::string::npos
+ || string_val->size() > MAX_STRING_ATTRIBUTE_SIZE)
+ {
+ // don't write strings with newlines into attributes
+ std::string attribute_name = node->getName()->mString;
+ LLXMLNodePtr parent_node = node->mParent;
+ parent_node->deleteChild(node);
+ // write results in text contents of node
+ if (attribute_name == "value")
+ {
+ // "value" is implicit, just write to parent
+ node = parent_node;
+ }
+ else
+ {
+ // create a child that is not an attribute, but with same name
+ node = parent_node->createChild(attribute_name.c_str(), false);
+ }
+ }
+ node->setStringValue(*string_val);
+ return true;
+ }
+ return false;
+}
+
+bool LLXUIParser::readU8Value(Parser& parser, void* val_ptr)
+{
+ LLXUIParser& self = static_cast<LLXUIParser&>(parser);
+ return self.mCurReadNode->getByteValue(1, (U8*)val_ptr);
+}
+
+bool LLXUIParser::writeU8Value(Parser& parser, const void* val_ptr, name_stack_t& stack)
+{
+ LLXUIParser& self = static_cast<LLXUIParser&>(parser);
+ LLXMLNodePtr node = self.getNode(stack);
+ if (node.notNull())
+ {
+ node->setUnsignedValue(*((U8*)val_ptr));
+ return true;
+ }
+ return false;
+}
+
+bool LLXUIParser::readS8Value(Parser& parser, void* val_ptr)
+{
+ LLXUIParser& self = static_cast<LLXUIParser&>(parser);
+ S32 value;
+ if(self.mCurReadNode->getIntValue(1, &value))
+ {
+ *((S8*)val_ptr) = value;
+ return true;
+ }
+ return false;
+}
+
+bool LLXUIParser::writeS8Value(Parser& parser, const void* val_ptr, name_stack_t& stack)
+{
+ LLXUIParser& self = static_cast<LLXUIParser&>(parser);
+ LLXMLNodePtr node = self.getNode(stack);
+ if (node.notNull())
+ {
+ node->setIntValue(*((S8*)val_ptr));
+ return true;
+ }
+ return false;
+}
+
+bool LLXUIParser::readU16Value(Parser& parser, void* val_ptr)
+{
+ LLXUIParser& self = static_cast<LLXUIParser&>(parser);
+ U32 value;
+ if(self.mCurReadNode->getUnsignedValue(1, &value))
+ {
+ *((U16*)val_ptr) = value;
+ return true;
+ }
+ return false;
+}
+
+bool LLXUIParser::writeU16Value(Parser& parser, const void* val_ptr, name_stack_t& stack)
+{
+ LLXUIParser& self = static_cast<LLXUIParser&>(parser);
+ LLXMLNodePtr node = self.getNode(stack);
+ if (node.notNull())
+ {
+ node->setUnsignedValue(*((U16*)val_ptr));
+ return true;
+ }
+ return false;
+}
+
+bool LLXUIParser::readS16Value(Parser& parser, void* val_ptr)
+{
+ LLXUIParser& self = static_cast<LLXUIParser&>(parser);
+ S32 value;
+ if(self.mCurReadNode->getIntValue(1, &value))
+ {
+ *((S16*)val_ptr) = value;
+ return true;
+ }
+ return false;
+}
+
+bool LLXUIParser::writeS16Value(Parser& parser, const void* val_ptr, name_stack_t& stack)
+{
+ LLXUIParser& self = static_cast<LLXUIParser&>(parser);
+ LLXMLNodePtr node = self.getNode(stack);
+ if (node.notNull())
+ {
+ node->setIntValue(*((S16*)val_ptr));
+ return true;
+ }
+ return false;
+}
+
+bool LLXUIParser::readU32Value(Parser& parser, void* val_ptr)
+{
+ LLXUIParser& self = static_cast<LLXUIParser&>(parser);
+ return self.mCurReadNode->getUnsignedValue(1, (U32*)val_ptr);
+}
+
+bool LLXUIParser::writeU32Value(Parser& parser, const void* val_ptr, name_stack_t& stack)
+{
+ LLXUIParser& self = static_cast<LLXUIParser&>(parser);
+ LLXMLNodePtr node = self.getNode(stack);
+ if (node.notNull())
+ {
+ node->setUnsignedValue(*((U32*)val_ptr));
+ return true;
+ }
+ return false;
+}
+
+bool LLXUIParser::readS32Value(Parser& parser, void* val_ptr)
+{
+ LLXUIParser& self = static_cast<LLXUIParser&>(parser);
+ return self.mCurReadNode->getIntValue(1, (S32*)val_ptr);
+}
+
+bool LLXUIParser::writeS32Value(Parser& parser, const void* val_ptr, name_stack_t& stack)
+{
+ LLXUIParser& self = static_cast<LLXUIParser&>(parser);
+ LLXMLNodePtr node = self.getNode(stack);
+ if (node.notNull())
+ {
+ node->setIntValue(*((S32*)val_ptr));
+ return true;
+ }
+ return false;
+}
+
+bool LLXUIParser::readF32Value(Parser& parser, void* val_ptr)
+{
+ LLXUIParser& self = static_cast<LLXUIParser&>(parser);
+ return self.mCurReadNode->getFloatValue(1, (F32*)val_ptr);
+}
+
+bool LLXUIParser::writeF32Value(Parser& parser, const void* val_ptr, name_stack_t& stack)
+{
+ LLXUIParser& self = static_cast<LLXUIParser&>(parser);
+ LLXMLNodePtr node = self.getNode(stack);
+ if (node.notNull())
+ {
+ node->setFloatValue(*((F32*)val_ptr));
+ return true;
+ }
+ return false;
+}
+
+bool LLXUIParser::readF64Value(Parser& parser, void* val_ptr)
+{
+ LLXUIParser& self = static_cast<LLXUIParser&>(parser);
+ return self.mCurReadNode->getDoubleValue(1, (F64*)val_ptr);
+}
+
+bool LLXUIParser::writeF64Value(Parser& parser, const void* val_ptr, name_stack_t& stack)
+{
+ LLXUIParser& self = static_cast<LLXUIParser&>(parser);
+ LLXMLNodePtr node = self.getNode(stack);
+ if (node.notNull())
+ {
+ node->setDoubleValue(*((F64*)val_ptr));
+ return true;
+ }
+ return false;
+}
+
+bool LLXUIParser::readVector3Value(Parser& parser, void* val_ptr)
+{
+ LLXUIParser& self = static_cast<LLXUIParser&>(parser);
+ LLVector3* vecp = (LLVector3*)val_ptr;
+ if(self.mCurReadNode->getFloatValue(3, vecp->mV) >= 3)
+ {
+ return true;
+ }
+
+ return false;
+}
+
+bool LLXUIParser::writeVector3Value(Parser& parser, const void* val_ptr, name_stack_t& stack)
+{
+ LLXUIParser& self = static_cast<LLXUIParser&>(parser);
+ LLXMLNodePtr node = self.getNode(stack);
+ if (node.notNull())
+ {
+ LLVector3 vector = *((LLVector3*)val_ptr);
+ node->setFloatValue(3, vector.mV);
+ return true;
+ }
+ return false;
+}
+
+bool LLXUIParser::readColor4Value(Parser& parser, void* val_ptr)
+{
+ LLXUIParser& self = static_cast<LLXUIParser&>(parser);
+ LLColor4* colorp = (LLColor4*)val_ptr;
+ if(self.mCurReadNode->getFloatValue(4, colorp->mV) >= 3)
+ {
+ return true;
+ }
+
+ return false;
+}
+
+bool LLXUIParser::writeColor4Value(Parser& parser, const void* val_ptr, name_stack_t& stack)
+{
+ LLXUIParser& self = static_cast<LLXUIParser&>(parser);
+ LLXMLNodePtr node = self.getNode(stack);
+ if (node.notNull())
+ {
+ LLColor4 color = *((LLColor4*)val_ptr);
+ node->setFloatValue(4, color.mV);
+ return true;
+ }
+ return false;
+}
+
+bool LLXUIParser::readUIColorValue(Parser& parser, void* val_ptr)
+{
+ LLXUIParser& self = static_cast<LLXUIParser&>(parser);
+ LLUIColor* param = (LLUIColor*)val_ptr;
+ LLColor4 color;
+ bool success = self.mCurReadNode->getFloatValue(4, color.mV) >= 3;
+ if (success)
+ {
+ param->set(color);
+ return true;
+ }
+ return false;
+}
+
+bool LLXUIParser::writeUIColorValue(Parser& parser, const void* val_ptr, name_stack_t& stack)
+{
+ LLXUIParser& self = static_cast<LLXUIParser&>(parser);
+ LLXMLNodePtr node = self.getNode(stack);
+ if (node.notNull())
+ {
+ LLUIColor color = *((LLUIColor*)val_ptr);
+ //RN: don't write out the color that is represented by a function
+ // rely on param block exporting to get the reference to the color settings
+ if (color.isReference()) return false;
+ node->setFloatValue(4, color.get().mV);
+ return true;
+ }
+ return false;
+}
+
+bool LLXUIParser::readUUIDValue(Parser& parser, void* val_ptr)
+{
+ LLXUIParser& self = static_cast<LLXUIParser&>(parser);
+ LLUUID temp_id;
+ // LLUUID::set is destructive, so use temporary value
+ if (temp_id.set(self.mCurReadNode->getSanitizedValue()))
+ {
+ *(LLUUID*)(val_ptr) = temp_id;
+ return true;
+ }
+ return false;
+}
+
+bool LLXUIParser::writeUUIDValue(Parser& parser, const void* val_ptr, name_stack_t& stack)
+{
+ LLXUIParser& self = static_cast<LLXUIParser&>(parser);
+ LLXMLNodePtr node = self.getNode(stack);
+ if (node.notNull())
+ {
+ node->setStringValue(((LLUUID*)val_ptr)->asString());
+ return true;
+ }
+ return false;
+}
+
+bool LLXUIParser::readSDValue(Parser& parser, void* val_ptr)
+{
+ LLXUIParser& self = static_cast<LLXUIParser&>(parser);
+ *((LLSD*)val_ptr) = LLSD(self.mCurReadNode->getSanitizedValue());
+ return true;
+}
+
+bool LLXUIParser::writeSDValue(Parser& parser, const void* val_ptr, name_stack_t& stack)
+{
+ LLXUIParser& self = static_cast<LLXUIParser&>(parser);
+
+ LLXMLNodePtr node = self.getNode(stack);
+ if (node.notNull())
+ {
+ std::string string_val = ((LLSD*)val_ptr)->asString();
+ if (string_val.find('\n') != std::string::npos || string_val.size() > MAX_STRING_ATTRIBUTE_SIZE)
+ {
+ // don't write strings with newlines into attributes
+ std::string attribute_name = node->getName()->mString;
+ LLXMLNodePtr parent_node = node->mParent;
+ parent_node->deleteChild(node);
+ // write results in text contents of node
+ if (attribute_name == "value")
+ {
+ // "value" is implicit, just write to parent
+ node = parent_node;
+ }
+ else
+ {
+ node = parent_node->createChild(attribute_name.c_str(), false);
+ }
+ }
+
+ node->setStringValue(string_val);
+ return true;
+ }
+ return false;
+}
+
+/*virtual*/ std::string LLXUIParser::getCurrentElementName()
+{
+ std::string full_name;
+ for (name_stack_t::iterator it = mNameStack.begin();
+ it != mNameStack.end();
+ ++it)
+ {
+ full_name += it->first + "."; // build up dotted names: "button.param.nestedparam."
+ }
+
+ return full_name;
+}
+
+void LLXUIParser::parserWarning(const std::string& message)
+{
+#ifdef LL_WINDOWS
+ // use Visual Studio friendly formatting of output message for easy access to originating xml
+ LL_WINDOWS_OUTPUT_DEBUG(llformat("%s(%d):\t%s", mCurFileName.c_str(), mCurReadNode->getLineNumber(), message.c_str()));
+#else
+ Parser::parserWarning(message);
+#endif
+}
+
+void LLXUIParser::parserError(const std::string& message)
+{
+#ifdef LL_WINDOWS
+ // use Visual Studio friendly formatting of output message for easy access to originating xml
+ LL_WINDOWS_OUTPUT_DEBUG(llformat("%s(%d):\t%s", mCurFileName.c_str(), mCurReadNode->getLineNumber(), message.c_str()));
+#else
+ Parser::parserError(message);
+#endif
+}
+
+
+//
+// LLSimpleXUIParser
+//
+
+struct ScopedFile
+{
+ ScopedFile( const std::string& filename, const char* accessmode )
+ {
+ mFile = LLFile::fopen(filename, accessmode);
+ }
+
+ ~ScopedFile()
+ {
+ fclose(mFile);
+ mFile = NULL;
+ }
+
+ S32 getRemainingBytes()
+ {
+ if (!isOpen()) return 0;
+
+ S32 cur_pos = ftell(mFile);
+ fseek(mFile, 0L, SEEK_END);
+ S32 file_size = ftell(mFile);
+ fseek(mFile, cur_pos, SEEK_SET);
+ return file_size - cur_pos;
+ }
+
+ bool isOpen() { return mFile != NULL; }
+
+ LLFILE* mFile;
+};
+LLSimpleXUIParser::LLSimpleXUIParser(LLSimpleXUIParser::element_start_callback_t element_cb)
+: Parser(sSimpleXUIReadFuncs, sSimpleXUIWriteFuncs, sSimpleXUIInspectFuncs),
+ mCurReadDepth(0),
+ mElementCB(element_cb)
+{
+ if (sSimpleXUIReadFuncs.empty())
+ {
+ registerParserFuncs<LLInitParam::Flag>(readFlag);
+ registerParserFuncs<bool>(readBoolValue);
+ registerParserFuncs<std::string>(readStringValue);
+ registerParserFuncs<U8>(readU8Value);
+ registerParserFuncs<S8>(readS8Value);
+ registerParserFuncs<U16>(readU16Value);
+ registerParserFuncs<S16>(readS16Value);
+ registerParserFuncs<U32>(readU32Value);
+ registerParserFuncs<S32>(readS32Value);
+ registerParserFuncs<F32>(readF32Value);
+ registerParserFuncs<F64>(readF64Value);
+ registerParserFuncs<LLColor4>(readColor4Value);
+ registerParserFuncs<LLUIColor>(readUIColorValue);
+ registerParserFuncs<LLUUID>(readUUIDValue);
+ registerParserFuncs<LLSD>(readSDValue);
+ }
+}
+
+LLSimpleXUIParser::~LLSimpleXUIParser()
+{
+}
+
+
+bool LLSimpleXUIParser::readXUI(const std::string& filename, LLInitParam::BaseBlock& block, bool silent)
+{
+ LLFastTimer timer(FTM_PARSE_XUI);
+
+ mParser = XML_ParserCreate(NULL);
+ XML_SetUserData(mParser, this);
+ XML_SetElementHandler( mParser, startElementHandler, endElementHandler);
+ XML_SetCharacterDataHandler( mParser, characterDataHandler);
+
+ mOutputStack.push_back(std::make_pair(&block, 0));
+ mNameStack.clear();
+ mCurFileName = filename;
+ mCurReadDepth = 0;
+ setParseSilently(silent);
+
+ ScopedFile file(filename, "rb");
+ if( !file.isOpen() )
+ {
+ LL_WARNS("ReadXUI") << "Unable to open file " << filename << LL_ENDL;
+ XML_ParserFree( mParser );
+ return false;
+ }
+
+ S32 bytes_read = 0;
+
+ S32 buffer_size = file.getRemainingBytes();
+ void* buffer = XML_GetBuffer(mParser, buffer_size);
+ if( !buffer )
+ {
+ LL_WARNS("ReadXUI") << "Unable to allocate XML buffer while reading file " << filename << LL_ENDL;
+ XML_ParserFree( mParser );
+ return false;
+ }
+
+ bytes_read = (S32)fread(buffer, 1, buffer_size, file.mFile);
+ if( bytes_read <= 0 )
+ {
+ LL_WARNS("ReadXUI") << "Error while reading file " << filename << LL_ENDL;
+ XML_ParserFree( mParser );
+ return false;
+ }
+
+ mEmptyLeafNode.push_back(false);
+
+ if( !XML_ParseBuffer(mParser, bytes_read, TRUE ) )
+ {
+ LL_WARNS("ReadXUI") << "Error while parsing file " << filename << LL_ENDL;
+ XML_ParserFree( mParser );
+ return false;
+ }
+
+ mEmptyLeafNode.pop_back();
+
+ XML_ParserFree( mParser );
+ return true;
+}
+
+void LLSimpleXUIParser::startElementHandler(void *userData, const char *name, const char **atts)
+{
+ LLSimpleXUIParser* self = reinterpret_cast<LLSimpleXUIParser*>(userData);
+ self->startElement(name, atts);
+}
+
+void LLSimpleXUIParser::endElementHandler(void *userData, const char *name)
+{
+ LLSimpleXUIParser* self = reinterpret_cast<LLSimpleXUIParser*>(userData);
+ self->endElement(name);
+}
+
+void LLSimpleXUIParser::characterDataHandler(void *userData, const char *s, int len)
+{
+ LLSimpleXUIParser* self = reinterpret_cast<LLSimpleXUIParser*>(userData);
+ self->characterData(s, len);
+}
+
+void LLSimpleXUIParser::characterData(const char *s, int len)
+{
+ mTextContents += std::string(s, len);
+}
+
+void LLSimpleXUIParser::startElement(const char *name, const char **atts)
+{
+ processText();
+
+ typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
+ boost::char_separator<char> sep(".");
+
+ if (mElementCB)
+ {
+ LLInitParam::BaseBlock* blockp = mElementCB(*this, name);
+ if (blockp)
+ {
+ mOutputStack.push_back(std::make_pair(blockp, 0));
+ }
+ }
+
+ mOutputStack.back().second++;
+ S32 num_tokens_pushed = 0;
+ std::string child_name(name);
+
+ if (mOutputStack.back().second == 1)
+ { // root node for this block
+ mScope.push_back(child_name);
+ }
+ else
+ { // compound attribute
+ if (child_name.find(".") == std::string::npos)
+ {
+ mNameStack.push_back(std::make_pair(child_name, true));
+ num_tokens_pushed++;
+ mScope.push_back(child_name);
+ }
+ else
+ {
+ // parse out "dotted" name into individual tokens
+ tokenizer name_tokens(child_name, sep);
+
+ tokenizer::iterator name_token_it = name_tokens.begin();
+ if(name_token_it == name_tokens.end())
+ {
+ return;
+ }
+
+ // check for proper nesting
+ if(!mScope.empty() && *name_token_it != mScope.back())
+ {
+ return;
+ }
+
+ // now ignore first token
+ ++name_token_it;
+
+ // copy remaining tokens on to our running token list
+ for(tokenizer::iterator token_to_push = name_token_it; token_to_push != name_tokens.end(); ++token_to_push)
+ {
+ mNameStack.push_back(std::make_pair(*token_to_push, true));
+ num_tokens_pushed++;
+ }
+ mScope.push_back(mNameStack.back().first);
+ }
+ }
+
+ // parent node is not empty
+ mEmptyLeafNode.back() = false;
+ // we are empty if we have no attributes
+ mEmptyLeafNode.push_back(atts[0] == NULL);
+
+ mTokenSizeStack.push_back(num_tokens_pushed);
+ readAttributes(atts);
+
+}
+
+void LLSimpleXUIParser::endElement(const char *name)
+{
+ bool has_text = processText();
+
+ // no text, attributes, or children
+ if (!has_text && mEmptyLeafNode.back())
+ {
+ // submit this as a valueless name (even though there might be text contents we haven't seen yet)
+ mCurAttributeValueBegin = NO_VALUE_MARKER;
+ mOutputStack.back().first->submitValue(mNameStack, *this, mParseSilently);
+ }
+
+ if (--mOutputStack.back().second == 0)
+ {
+ if (mOutputStack.empty())
+ {
+ LL_ERRS("ReadXUI") << "Parameter block output stack popped while empty." << LL_ENDL;
+ }
+ mOutputStack.pop_back();
+ }
+
+ S32 num_tokens_to_pop = mTokenSizeStack.back();
+ mTokenSizeStack.pop_back();
+ while(num_tokens_to_pop-- > 0)
+ {
+ mNameStack.pop_back();
+ }
+ mScope.pop_back();
+ mEmptyLeafNode.pop_back();
+}
+
+bool LLSimpleXUIParser::readAttributes(const char **atts)
+{
+ typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
+ boost::char_separator<char> sep(".");
+
+ bool any_parsed = false;
+ for(S32 i = 0; atts[i] && atts[i+1]; i += 2 )
+ {
+ std::string attribute_name(atts[i]);
+ mCurAttributeValueBegin = atts[i+1];
+
+ S32 num_tokens_pushed = 0;
+ tokenizer name_tokens(attribute_name, sep);
+ // copy remaining tokens on to our running token list
+ for(tokenizer::iterator token_to_push = name_tokens.begin(); token_to_push != name_tokens.end(); ++token_to_push)
+ {
+ mNameStack.push_back(std::make_pair(*token_to_push, true));
+ num_tokens_pushed++;
+ }
+
+ // child nodes are not necessarily valid attributes, so don't complain once we've recursed
+ any_parsed |= mOutputStack.back().first->submitValue(mNameStack, *this, mParseSilently);
+
+ while(num_tokens_pushed-- > 0)
+ {
+ mNameStack.pop_back();
+ }
+ }
+ return any_parsed;
+}
+
+bool LLSimpleXUIParser::processText()
+{
+ if (!mTextContents.empty())
+ {
+ LLStringUtil::trim(mTextContents);
+ if (!mTextContents.empty())
+ {
+ mNameStack.push_back(std::make_pair(std::string("value"), true));
+ mCurAttributeValueBegin = mTextContents.c_str();
+ mOutputStack.back().first->submitValue(mNameStack, *this, mParseSilently);
+ mNameStack.pop_back();
+ }
+ mTextContents.clear();
+ return true;
+ }
+ return false;
+}
+
+/*virtual*/ std::string LLSimpleXUIParser::getCurrentElementName()
+{
+ std::string full_name;
+ for (name_stack_t::iterator it = mNameStack.begin();
+ it != mNameStack.end();
+ ++it)
+ {
+ full_name += it->first + "."; // build up dotted names: "button.param.nestedparam."
+ }
+
+ return full_name;
+}
+
+void LLSimpleXUIParser::parserWarning(const std::string& message)
+{
+#ifdef LL_WINDOWS
+ // use Visual Studio friendly formatting of output message for easy access to originating xml
+ LL_WINDOWS_OUTPUT_DEBUG(llformat("%s(%d):\t%s", mCurFileName.c_str(), LINE_NUMBER_HERE, message.c_str()));
+#else
+ Parser::parserWarning(message);
+#endif
+}
+
+void LLSimpleXUIParser::parserError(const std::string& message)
+{
+#ifdef LL_WINDOWS
+ // use Visual Studio friendly formatting of output message for easy access to originating xml
+ LL_WINDOWS_OUTPUT_DEBUG(llformat("%s(%d):\t%s", mCurFileName.c_str(), LINE_NUMBER_HERE, message.c_str()));
+#else
+ Parser::parserError(message);
+#endif
+}
+
+bool LLSimpleXUIParser::readFlag(Parser& parser, void* val_ptr)
+{
+ LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser);
+ return self.mCurAttributeValueBegin == NO_VALUE_MARKER;
+}
+
+bool LLSimpleXUIParser::readBoolValue(Parser& parser, void* val_ptr)
+{
+ LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser);
+ if (!strcmp(self.mCurAttributeValueBegin, "true"))
+ {
+ *((bool*)val_ptr) = true;
+ return true;
+ }
+ else if (!strcmp(self.mCurAttributeValueBegin, "false"))
+ {
+ *((bool*)val_ptr) = false;
+ return true;
+ }
+
+ return false;
+}
+
+bool LLSimpleXUIParser::readStringValue(Parser& parser, void* val_ptr)
+{
+ LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser);
+ *((std::string*)val_ptr) = self.mCurAttributeValueBegin;
+ return true;
+}
+
+bool LLSimpleXUIParser::readU8Value(Parser& parser, void* val_ptr)
+{
+ LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser);
+ return parse(self.mCurAttributeValueBegin, uint_p[assign_a(*(U8*)val_ptr)]).full;
+}
+
+bool LLSimpleXUIParser::readS8Value(Parser& parser, void* val_ptr)
+{
+ LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser);
+ return parse(self.mCurAttributeValueBegin, int_p[assign_a(*(S8*)val_ptr)]).full;
+}
+
+bool LLSimpleXUIParser::readU16Value(Parser& parser, void* val_ptr)
+{
+ LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser);
+ return parse(self.mCurAttributeValueBegin, uint_p[assign_a(*(U16*)val_ptr)]).full;
+}
+
+bool LLSimpleXUIParser::readS16Value(Parser& parser, void* val_ptr)
+{
+ LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser);
+ return parse(self.mCurAttributeValueBegin, int_p[assign_a(*(S16*)val_ptr)]).full;
+}
+
+bool LLSimpleXUIParser::readU32Value(Parser& parser, void* val_ptr)
+{
+ LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser);
+ return parse(self.mCurAttributeValueBegin, uint_p[assign_a(*(U32*)val_ptr)]).full;
+}
+
+bool LLSimpleXUIParser::readS32Value(Parser& parser, void* val_ptr)
+{
+ LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser);
+ return parse(self.mCurAttributeValueBegin, int_p[assign_a(*(S32*)val_ptr)]).full;
+}
+
+bool LLSimpleXUIParser::readF32Value(Parser& parser, void* val_ptr)
+{
+ LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser);
+ return parse(self.mCurAttributeValueBegin, real_p[assign_a(*(F32*)val_ptr)]).full;
+}
+
+bool LLSimpleXUIParser::readF64Value(Parser& parser, void* val_ptr)
+{
+ LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser);
+ return parse(self.mCurAttributeValueBegin, real_p[assign_a(*(F64*)val_ptr)]).full;
+}
+
+bool LLSimpleXUIParser::readColor4Value(Parser& parser, void* val_ptr)
+{
+ LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser);
+ LLColor4 value;
+
+ if (parse(self.mCurAttributeValueBegin, real_p[assign_a(value.mV[0])] >> real_p[assign_a(value.mV[1])] >> real_p[assign_a(value.mV[2])] >> real_p[assign_a(value.mV[3])], space_p).full)
+ {
+ *(LLColor4*)(val_ptr) = value;
+ return true;
+ }
+ return false;
+}
+
+bool LLSimpleXUIParser::readUIColorValue(Parser& parser, void* val_ptr)
+{
+ LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser);
+ LLColor4 value;
+ LLUIColor* colorp = (LLUIColor*)val_ptr;
+
+ if (parse(self.mCurAttributeValueBegin, real_p[assign_a(value.mV[0])] >> real_p[assign_a(value.mV[1])] >> real_p[assign_a(value.mV[2])] >> real_p[assign_a(value.mV[3])], space_p).full)
+ {
+ colorp->set(value);
+ return true;
+ }
+ return false;
+}
+
+bool LLSimpleXUIParser::readUUIDValue(Parser& parser, void* val_ptr)
+{
+ LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser);
+ LLUUID temp_id;
+ // LLUUID::set is destructive, so use temporary value
+ if (temp_id.set(std::string(self.mCurAttributeValueBegin)))
+ {
+ *(LLUUID*)(val_ptr) = temp_id;
+ return true;
+ }
+ return false;
+}
+
+bool LLSimpleXUIParser::readSDValue(Parser& parser, void* val_ptr)
+{
+ LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser);
+ *((LLSD*)val_ptr) = LLSD(self.mCurAttributeValueBegin);
+ return true;
+}
diff --git a/indra/llui/llxuiparser.h b/indra/llui/llxuiparser.h
new file mode 100755
index 0000000000..e48663e5cc
--- /dev/null
+++ b/indra/llui/llxuiparser.h
@@ -0,0 +1,244 @@
+/**
+ * @file llxuiparser.h
+ * @brief Utility functions for handling XUI structures in XML
+ *
+ * $LicenseInfo:firstyear=2003&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$
+ */
+
+#ifndef LLXUIPARSER_H
+#define LLXUIPARSER_H
+
+#include "llinitparam.h"
+#include "llregistry.h"
+#include "llpointer.h"
+
+#include <boost/function.hpp>
+#include <iosfwd>
+#include <stack>
+#include <set>
+
+
+
+class LLView;
+
+
+typedef LLPointer<class LLXMLNode> LLXMLNodePtr;
+
+
+// lookup widget type by name
+class LLWidgetTypeRegistry
+: public LLRegistrySingleton<std::string, const std::type_info*, LLWidgetTypeRegistry>
+{};
+
+
+// global static instance for registering all widget types
+typedef boost::function<LLView* (LLXMLNodePtr node, LLView *parent, LLXMLNodePtr output_node)> LLWidgetCreatorFunc;
+
+typedef LLRegistry<std::string, LLWidgetCreatorFunc> widget_registry_t;
+
+class LLChildRegistryRegistry
+: public LLRegistrySingleton<const std::type_info*, widget_registry_t, LLChildRegistryRegistry>
+{};
+
+
+
+class LLXSDWriter : public LLInitParam::Parser
+{
+ LOG_CLASS(LLXSDWriter);
+public:
+ void writeXSD(const std::string& name, LLXMLNodePtr node, const LLInitParam::BaseBlock& block, const std::string& xml_namespace);
+
+ /*virtual*/ std::string getCurrentElementName() { return LLStringUtil::null; }
+
+ LLXSDWriter();
+
+protected:
+ void writeAttribute(const std::string& type, const Parser::name_stack_t&, S32 min_count, S32 max_count, const std::vector<std::string>* possible_values);
+ void addAttributeToSchema(LLXMLNodePtr nodep, const std::string& attribute_name, const std::string& type, bool mandatory, const std::vector<std::string>* possible_values);
+ LLXMLNodePtr mAttributeNode;
+ LLXMLNodePtr mElementNode;
+ LLXMLNodePtr mSchemaNode;
+
+ typedef std::set<std::string> string_set_t;
+ typedef std::map<LLXMLNodePtr, string_set_t> attributes_map_t;
+ attributes_map_t mAttributesWritten;
+};
+
+
+
+// NOTE: DOES NOT WORK YET
+// should support child widgets for XUI
+class LLXUIXSDWriter : public LLXSDWriter
+{
+public:
+ void writeXSD(const std::string& name, const std::string& path, const LLInitParam::BaseBlock& block);
+};
+
+
+class LLXUIParserImpl;
+
+class LLXUIParser : public LLInitParam::Parser
+{
+LOG_CLASS(LLXUIParser);
+
+public:
+ LLXUIParser();
+ typedef LLInitParam::Parser::name_stack_t name_stack_t;
+
+ /*virtual*/ std::string getCurrentElementName();
+ /*virtual*/ void parserWarning(const std::string& message);
+ /*virtual*/ void parserError(const std::string& message);
+
+ void readXUI(LLXMLNodePtr node, LLInitParam::BaseBlock& block, const std::string& filename = LLStringUtil::null, bool silent=false);
+ void writeXUI(LLXMLNodePtr node, const LLInitParam::BaseBlock& block, const LLInitParam::BaseBlock* diff_block = NULL);
+
+private:
+ bool readXUIImpl(LLXMLNodePtr node, LLInitParam::BaseBlock& block);
+ bool readAttributes(LLXMLNodePtr nodep, LLInitParam::BaseBlock& block);
+
+ //reader helper functions
+ static bool readFlag(Parser& parser, void* val_ptr);
+ static bool readBoolValue(Parser& parser, void* val_ptr);
+ static bool readStringValue(Parser& parser, void* val_ptr);
+ static bool readU8Value(Parser& parser, void* val_ptr);
+ static bool readS8Value(Parser& parser, void* val_ptr);
+ static bool readU16Value(Parser& parser, void* val_ptr);
+ static bool readS16Value(Parser& parser, void* val_ptr);
+ static bool readU32Value(Parser& parser, void* val_ptr);
+ static bool readS32Value(Parser& parser, void* val_ptr);
+ static bool readF32Value(Parser& parser, void* val_ptr);
+ static bool readF64Value(Parser& parser, void* val_ptr);
+ static bool readVector3Value(Parser& parser, void* val_ptr);
+ static bool readColor4Value(Parser& parser, void* val_ptr);
+ static bool readUIColorValue(Parser& parser, void* val_ptr);
+ static bool readUUIDValue(Parser& parser, void* val_ptr);
+ static bool readSDValue(Parser& parser, void* val_ptr);
+
+ //writer helper functions
+ static bool writeFlag(Parser& parser, const void* val_ptr, name_stack_t&);
+ static bool writeBoolValue(Parser& parser, const void* val_ptr, name_stack_t&);
+ static bool writeStringValue(Parser& parser, const void* val_ptr, name_stack_t&);
+ static bool writeU8Value(Parser& parser, const void* val_ptr, name_stack_t&);
+ static bool writeS8Value(Parser& parser, const void* val_ptr, name_stack_t&);
+ static bool writeU16Value(Parser& parser, const void* val_ptr, name_stack_t&);
+ static bool writeS16Value(Parser& parser, const void* val_ptr, name_stack_t&);
+ static bool writeU32Value(Parser& parser, const void* val_ptr, name_stack_t&);
+ static bool writeS32Value(Parser& parser, const void* val_ptr, name_stack_t&);
+ static bool writeF32Value(Parser& parser, const void* val_ptr, name_stack_t&);
+ static bool writeF64Value(Parser& parser, const void* val_ptr, name_stack_t&);
+ static bool writeVector3Value(Parser& parser, const void* val_ptr, name_stack_t&);
+ static bool writeColor4Value(Parser& parser, const void* val_ptr, name_stack_t&);
+ static bool writeUIColorValue(Parser& parser, const void* val_ptr, name_stack_t&);
+ static bool writeUUIDValue(Parser& parser, const void* val_ptr, name_stack_t&);
+ static bool writeSDValue(Parser& parser, const void* val_ptr, name_stack_t&);
+
+ LLXMLNodePtr getNode(name_stack_t& stack);
+
+private:
+ Parser::name_stack_t mNameStack;
+ LLXMLNodePtr mCurReadNode;
+ // Root of the widget XML sub-tree, for example, "line_editor"
+ LLXMLNodePtr mWriteRootNode;
+
+ typedef std::map<std::string, LLXMLNodePtr> out_nodes_t;
+ out_nodes_t mOutNodes;
+ LLXMLNodePtr mLastWrittenChild;
+ S32 mCurReadDepth;
+ std::string mCurFileName;
+ std::string mRootNodeName;
+};
+
+// LLSimpleXUIParser is a streamlined SAX-based XUI parser that does not support localization
+// or parsing of a tree of independent param blocks, such as child widgets.
+// Use this for reading non-localized files that only need a single param block as a result.
+//
+// NOTE: In order to support nested block parsing, we need callbacks for start element that
+// push new blocks contexts on the mScope stack.
+// NOTE: To support localization without building a DOM, we need to enforce consistent
+// ordering of child elements from base file to localized diff file. Then we can use a pair
+// of coroutines to perform matching of xml nodes during parsing. Not sure if the overhead
+// of coroutines would offset the gain from SAX parsing
+class LLSimpleXUIParserImpl;
+
+class LLSimpleXUIParser : public LLInitParam::Parser
+{
+LOG_CLASS(LLSimpleXUIParser);
+public:
+ typedef LLInitParam::Parser::name_stack_t name_stack_t;
+ typedef LLInitParam::BaseBlock* (*element_start_callback_t)(LLSimpleXUIParser&, const char* block_name);
+
+ LLSimpleXUIParser(element_start_callback_t element_cb = NULL);
+ virtual ~LLSimpleXUIParser();
+
+ /*virtual*/ std::string getCurrentElementName();
+ /*virtual*/ void parserWarning(const std::string& message);
+ /*virtual*/ void parserError(const std::string& message);
+
+ bool readXUI(const std::string& filename, LLInitParam::BaseBlock& block, bool silent=false);
+
+
+private:
+ //reader helper functions
+ static bool readFlag(Parser&, void* val_ptr);
+ static bool readBoolValue(Parser&, void* val_ptr);
+ static bool readStringValue(Parser&, void* val_ptr);
+ static bool readU8Value(Parser&, void* val_ptr);
+ static bool readS8Value(Parser&, void* val_ptr);
+ static bool readU16Value(Parser&, void* val_ptr);
+ static bool readS16Value(Parser&, void* val_ptr);
+ static bool readU32Value(Parser&, void* val_ptr);
+ static bool readS32Value(Parser&, void* val_ptr);
+ static bool readF32Value(Parser&, void* val_ptr);
+ static bool readF64Value(Parser&, void* val_ptr);
+ static bool readColor4Value(Parser&, void* val_ptr);
+ static bool readUIColorValue(Parser&, void* val_ptr);
+ static bool readUUIDValue(Parser&, void* val_ptr);
+ static bool readSDValue(Parser&, void* val_ptr);
+
+private:
+ static void startElementHandler(void *userData, const char *name, const char **atts);
+ static void endElementHandler(void *userData, const char *name);
+ static void characterDataHandler(void *userData, const char *s, int len);
+
+ void startElement(const char *name, const char **atts);
+ void endElement(const char *name);
+ void characterData(const char *s, int len);
+ bool readAttributes(const char **atts);
+ bool processText();
+
+ Parser::name_stack_t mNameStack;
+ struct XML_ParserStruct* mParser;
+ LLXMLNodePtr mLastWrittenChild;
+ S32 mCurReadDepth;
+ std::string mCurFileName;
+ std::string mTextContents;
+ const char* mCurAttributeValueBegin;
+ std::vector<S32> mTokenSizeStack;
+ std::vector<std::string> mScope;
+ std::vector<bool> mEmptyLeafNode;
+ element_start_callback_t mElementCB;
+
+ std::vector<std::pair<LLInitParam::BaseBlock*, S32> > mOutputStack;
+};
+
+
+#endif //LLXUIPARSER_H
diff --git a/indra/llui/tests/llurlentry_stub.cpp b/indra/llui/tests/llurlentry_stub.cpp
index c75df86891..5d3f9ac327 100644..100755
--- a/indra/llui/tests/llurlentry_stub.cpp
+++ b/indra/llui/tests/llurlentry_stub.cpp
@@ -40,14 +40,10 @@ bool LLAvatarNameCache::get(const LLUUID& agent_id, LLAvatarName *av_name)
return false;
}
-void LLAvatarNameCache::get(const LLUUID& agent_id, callback_slot_t slot)
+LLAvatarNameCache::callback_connection_t LLAvatarNameCache::get(const LLUUID& agent_id, callback_slot_t slot)
{
- return;
-}
-
-bool LLAvatarNameCache::useDisplayNames()
-{
- return false;
+ callback_connection_t connection;
+ return connection;
}
//
@@ -105,36 +101,14 @@ LLStyle::Params::Params()
namespace LLInitParam
{
- Param::Param(BaseBlock* enclosing_block)
- : mIsProvided(false)
- {
- const U8* my_addr = reinterpret_cast<const U8*>(this);
- const U8* block_addr = reinterpret_cast<const U8*>(enclosing_block);
- mEnclosingBlockOffset = (U16)(my_addr - block_addr);
- }
-
- void BaseBlock::addParam(BlockDescriptor& block_data, const ParamDescriptorPtr in_param, const char* char_name){}
- void BaseBlock::addSynonym(Param& param, const std::string& synonym) {}
- param_handle_t BaseBlock::getHandleFromParam(const Param* param) const {return 0;}
-
- void BaseBlock::init(BlockDescriptor& descriptor, BlockDescriptor& base_descriptor, size_t block_size)
- {
- descriptor.mCurrentBlockPtr = this;
- }
- bool BaseBlock::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack, bool new_name){ return true; }
- void BaseBlock::serializeBlock(Parser& parser, Parser::name_stack_t& name_stack, const LLInitParam::BaseBlock* diff_block) const {}
- bool BaseBlock::inspectBlock(Parser& parser, Parser::name_stack_t name_stack, S32 min_value, S32 max_value) const { return true; }
- bool BaseBlock::mergeBlock(BlockDescriptor& block_data, const BaseBlock& other, bool overwrite) { return true; }
- bool BaseBlock::validateBlock(bool emit_errors) const { return true; }
-
- ParamValue<LLUIColor, TypeValues<LLUIColor> >::ParamValue(const LLUIColor& color)
+ ParamValue<LLUIColor>::ParamValue(const LLUIColor& color)
: super_t(color)
{}
- void ParamValue<LLUIColor, TypeValues<LLUIColor> >::updateValueFromBlock()
+ void ParamValue<LLUIColor>::updateValueFromBlock()
{}
- void ParamValue<LLUIColor, TypeValues<LLUIColor> >::updateBlockFromValue(bool)
+ void ParamValue<LLUIColor>::updateBlockFromValue(bool)
{}
bool ParamCompare<const LLFontGL*, false>::equals(const LLFontGL* a, const LLFontGL* b)
@@ -142,14 +116,14 @@ namespace LLInitParam
return false;
}
- ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::ParamValue(const LLFontGL* fontp)
+ ParamValue<const LLFontGL*>::ParamValue(const LLFontGL* fontp)
: super_t(fontp)
{}
- void ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::updateValueFromBlock()
+ void ParamValue<const LLFontGL*>::updateValueFromBlock()
{}
- void ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::updateBlockFromValue(bool)
+ void ParamValue<const LLFontGL*>::updateBlockFromValue(bool)
{}
void TypeValues<LLFontGL::HAlign>::declareValues()
@@ -161,10 +135,10 @@ namespace LLInitParam
void TypeValues<LLFontGL::ShadowType>::declareValues()
{}
- void ParamValue<LLUIImage*, TypeValues<LLUIImage*> >::updateValueFromBlock()
+ void ParamValue<LLUIImage*>::updateValueFromBlock()
{}
- void ParamValue<LLUIImage*, TypeValues<LLUIImage*> >::updateBlockFromValue(bool)
+ void ParamValue<LLUIImage*>::updateBlockFromValue(bool)
{}
diff --git a/indra/llui/tests/llurlentry_test.cpp b/indra/llui/tests/llurlentry_test.cpp
index c1fb050206..c3f0e92cb0 100644..100755
--- a/indra/llui/tests/llurlentry_test.cpp
+++ b/indra/llui/tests/llurlentry_test.cpp
@@ -31,7 +31,7 @@
#include "llurlentry_stub.cpp"
#include "lltut.h"
#include "../lluicolortable.h"
-#include "../lluiimage.h"
+#include "../llrender/lluiimage.h"
#include <boost/regex.hpp>
@@ -70,21 +70,6 @@ S32 LLUIImage::getHeight() const
return 0;
}
-namespace LLInitParam
-{
- BlockDescriptor::BlockDescriptor() {}
- ParamDescriptor::ParamDescriptor(param_handle_t p,
- merge_func_t merge_func,
- deserialize_func_t deserialize_func,
- serialize_func_t serialize_func,
- validation_func_t validation_func,
- inspect_func_t inspect_func,
- S32 min_count,
- S32 max_count){}
- ParamDescriptor::~ParamDescriptor() {}
-
-}
-
namespace tut
{
struct LLUrlEntryData
diff --git a/indra/llui/tests/llurlmatch_test.cpp b/indra/llui/tests/llurlmatch_test.cpp
index 7183413463..55c1efefef 100644..100755
--- a/indra/llui/tests/llurlmatch_test.cpp
+++ b/indra/llui/tests/llurlmatch_test.cpp
@@ -28,7 +28,7 @@
#include "linden_common.h"
#include "../llurlmatch.h"
-#include "../lluiimage.h"
+#include "../llrender/lluiimage.h"
#include "lltut.h"
// link seams
@@ -63,48 +63,14 @@ S32 LLUIImage::getHeight() const
namespace LLInitParam
{
- BlockDescriptor::BlockDescriptor() {}
- ParamDescriptor::ParamDescriptor(param_handle_t p,
- merge_func_t merge_func,
- deserialize_func_t deserialize_func,
- serialize_func_t serialize_func,
- validation_func_t validation_func,
- inspect_func_t inspect_func,
- S32 min_count,
- S32 max_count){}
- ParamDescriptor::~ParamDescriptor() {}
-
- void BaseBlock::addParam(BlockDescriptor& block_data, const ParamDescriptorPtr in_param, const char* char_name){}
- param_handle_t BaseBlock::getHandleFromParam(const Param* param) const {return 0;}
- void BaseBlock::addSynonym(Param& param, const std::string& synonym) {}
-
- void BaseBlock::init(BlockDescriptor& descriptor, BlockDescriptor& base_descriptor, size_t block_size)
- {
- descriptor.mCurrentBlockPtr = this;
- }
-
- Param::Param(BaseBlock* enclosing_block)
- : mIsProvided(false)
- {
- const U8* my_addr = reinterpret_cast<const U8*>(this);
- const U8* block_addr = reinterpret_cast<const U8*>(enclosing_block);
- mEnclosingBlockOffset = 0x7FFFffff & ((U32)(my_addr - block_addr));
- }
-
- bool BaseBlock::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack, bool new_name){ return true; }
- void BaseBlock::serializeBlock(Parser& parser, Parser::name_stack_t& name_stack, const LLInitParam::BaseBlock* diff_block) const {}
- bool BaseBlock::inspectBlock(Parser& parser, Parser::name_stack_t name_stack, S32 min_count, S32 max_count) const { return true; }
- bool BaseBlock::mergeBlock(BlockDescriptor& block_data, const BaseBlock& other, bool overwrite) { return true; }
- bool BaseBlock::validateBlock(bool emit_errors) const { return true; }
-
- ParamValue<LLUIColor, TypeValues<LLUIColor> >::ParamValue(const LLUIColor& color)
+ ParamValue<LLUIColor>::ParamValue(const LLUIColor& color)
: super_t(color)
{}
- void ParamValue<LLUIColor, TypeValues<LLUIColor> >::updateValueFromBlock()
+ void ParamValue<LLUIColor>::updateValueFromBlock()
{}
- void ParamValue<LLUIColor, TypeValues<LLUIColor> >::updateBlockFromValue(bool)
+ void ParamValue<LLUIColor>::updateBlockFromValue(bool)
{}
bool ParamCompare<const LLFontGL*, false>::equals(const LLFontGL* a, const LLFontGL* b)
@@ -113,14 +79,14 @@ namespace LLInitParam
}
- ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::ParamValue(const LLFontGL* fontp)
+ ParamValue<const LLFontGL*>::ParamValue(const LLFontGL* fontp)
: super_t(fontp)
{}
- void ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::updateValueFromBlock()
+ void ParamValue<const LLFontGL*>::updateValueFromBlock()
{}
- void ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::updateBlockFromValue(bool)
+ void ParamValue<const LLFontGL*>::updateBlockFromValue(bool)
{}
void TypeValues<LLFontGL::HAlign>::declareValues()
@@ -132,10 +98,10 @@ namespace LLInitParam
void TypeValues<LLFontGL::ShadowType>::declareValues()
{}
- void ParamValue<LLUIImage*, TypeValues<LLUIImage*> >::updateValueFromBlock()
+ void ParamValue<LLUIImage*>::updateValueFromBlock()
{}
- void ParamValue<LLUIImage*, TypeValues<LLUIImage*> >::updateBlockFromValue(bool)
+ void ParamValue<LLUIImage*>::updateBlockFromValue(bool)
{}
bool ParamCompare<LLUIImage*, false>::equals(
diff --git a/indra/llvfs/CMakeLists.txt b/indra/llvfs/CMakeLists.txt
index a819d12861..67dce8c073 100644..100755
--- a/indra/llvfs/CMakeLists.txt
+++ b/indra/llvfs/CMakeLists.txt
@@ -8,6 +8,7 @@ include(UnixInstall)
include_directories(
${LLCOMMON_INCLUDE_DIRS}
+ ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
)
set(llvfs_SOURCE_FILES
@@ -36,18 +37,20 @@ set(llvfs_HEADER_FILES
if (DARWIN)
LIST(APPEND llvfs_SOURCE_FILES lldir_mac.cpp)
LIST(APPEND llvfs_HEADER_FILES lldir_mac.h)
+ LIST(APPEND llvfs_SOURCE_FILES llvfs_objc.mm)
+ LIST(APPEND llvfs_HEADER_FILES llvfs_objc.h)
endif (DARWIN)
if (LINUX)
LIST(APPEND llvfs_SOURCE_FILES lldir_linux.cpp)
LIST(APPEND llvfs_HEADER_FILES lldir_linux.h)
- if (VIEWER AND INSTALL)
+ if (INSTALL)
set_source_files_properties(lldir_linux.cpp
PROPERTIES COMPILE_FLAGS
"-DAPP_RO_DATA_DIR=\\\"${APP_SHARE_DIR}\\\""
)
- endif (VIEWER AND INSTALL)
+ endif (INSTALL)
endif (LINUX)
if (WINDOWS)
@@ -68,13 +71,14 @@ set(vfs_BOOST_LIBRARIES
)
target_link_libraries(llvfs
+ ${LLCOMMON_LIBRARIES}
${vfs_BOOST_LIBRARIES}
)
if (DARWIN)
include(CMakeFindFrameworks)
- find_library(CARBON_LIBRARY Carbon)
- target_link_libraries(llvfs ${CARBON_LIBRARY})
+ find_library(COCOA_LIBRARY Cocoa)
+ target_link_libraries(llvfs ${COCOA_LIBRARY})
endif (DARWIN)
diff --git a/indra/llvfs/lldir.cpp b/indra/llvfs/lldir.cpp
index f3ac17d612..6899e9a44a 100644..100755
--- a/indra/llvfs/lldir.cpp
+++ b/indra/llvfs/lldir.cpp
@@ -41,6 +41,17 @@
#include "lluuid.h"
#include "lldiriterator.h"
+#include "stringize.h"
+#include <boost/foreach.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/assign/list_of.hpp>
+#include <boost/bind.hpp>
+#include <boost/ref.hpp>
+#include <algorithm>
+
+using boost::assign::list_of;
+using boost::assign::map_list_of;
#if LL_WINDOWS
#include "lldir_win32.h"
@@ -58,6 +69,14 @@ LLDir_Linux gDirUtil;
LLDir *gDirUtilp = (LLDir *)&gDirUtil;
+/// Values for findSkinnedFilenames(subdir) parameter
+const char
+ *LLDir::XUI = "xui",
+ *LLDir::TEXTURES = "textures",
+ *LLDir::SKINBASE = "";
+
+static const char* const empty = "";
+
LLDir::LLDir()
: mAppName(""),
mExecutablePathAndName(""),
@@ -70,7 +89,9 @@ LLDir::LLDir()
mOSCacheDir(""),
mCAFile(""),
mTempDir(""),
- mDirDelimiter("/") // fallback to forward slash if not overridden
+ mDirDelimiter("/"), // fallback to forward slash if not overridden
+ mLanguage("en"),
+ mUserName("undefined")
{
}
@@ -86,12 +107,17 @@ S32 LLDir::deleteFilesInDir(const std::string &dirname, const std::string &mask)
std::string fullpath;
S32 result;
+ // File masks starting with "/" will match nothing, so we consider them invalid.
+ if (LLStringUtil::startsWith(mask, getDirDelimiter()))
+ {
+ llwarns << "Invalid file mask: " << mask << llendl;
+ llassert(!"Invalid file mask");
+ }
+
LLDirIterator iter(dirname, mask);
while (iter.next(filename))
{
- fullpath = dirname;
- fullpath += getDirDelimiter();
- fullpath += filename;
+ fullpath = add(dirname, filename);
if(LLFile::isdir(fullpath))
{
@@ -263,12 +289,12 @@ std::string LLDir::buildSLOSCacheDir() const
}
else
{
- res = getOSUserAppDir() + mDirDelimiter + "cache";
+ res = add(getOSUserAppDir(), "cache");
}
}
else
{
- res = getOSCacheDir() + mDirDelimiter + "SecondLife";
+ res = add(getOSCacheDir(), "SecondLife");
}
return res;
}
@@ -291,19 +317,24 @@ const std::string &LLDir::getDirDelimiter() const
return mDirDelimiter;
}
+const std::string& LLDir::getDefaultSkinDir() const
+{
+ return mDefaultSkinDir;
+}
+
const std::string &LLDir::getSkinDir() const
{
return mSkinDir;
}
-const std::string &LLDir::getUserSkinDir() const
+const std::string &LLDir::getUserDefaultSkinDir() const
{
- return mUserSkinDir;
+ return mUserDefaultSkinDir;
}
-const std::string& LLDir::getDefaultSkinDir() const
+const std::string &LLDir::getUserSkinDir() const
{
- return mDefaultSkinDir;
+ return mUserSkinDir;
}
const std::string LLDir::getSkinBaseDir() const
@@ -316,6 +347,44 @@ const std::string &LLDir::getLLPluginDir() const
return mLLPluginDir;
}
+const std::string &LLDir::getUserName() const
+{
+ return mUserName;
+}
+
+static std::string ELLPathToString(ELLPath location)
+{
+ typedef std::map<ELLPath, const char*> ELLPathMap;
+#define ENT(symbol) (symbol, #symbol)
+ static const ELLPathMap sMap = map_list_of
+ ENT(LL_PATH_NONE)
+ ENT(LL_PATH_USER_SETTINGS)
+ ENT(LL_PATH_APP_SETTINGS)
+ ENT(LL_PATH_PER_SL_ACCOUNT) // returns/expands to blank string if we don't know the account name yet
+ ENT(LL_PATH_CACHE)
+ ENT(LL_PATH_CHARACTER)
+ ENT(LL_PATH_HELP)
+ ENT(LL_PATH_LOGS)
+ ENT(LL_PATH_TEMP)
+ ENT(LL_PATH_SKINS)
+ ENT(LL_PATH_TOP_SKIN)
+ ENT(LL_PATH_CHAT_LOGS)
+ ENT(LL_PATH_PER_ACCOUNT_CHAT_LOGS)
+ ENT(LL_PATH_USER_SKIN)
+ ENT(LL_PATH_LOCAL_ASSETS)
+ ENT(LL_PATH_EXECUTABLE)
+ ENT(LL_PATH_DEFAULT_SKIN)
+ ENT(LL_PATH_FONTS)
+ ENT(LL_PATH_LAST)
+ ;
+#undef ENT
+
+ ELLPathMap::const_iterator found = sMap.find(location);
+ if (found != sMap.end())
+ return found->second;
+ return STRINGIZE("Invalid ELLPath value " << location);
+}
+
std::string LLDir::getExpandedFilename(ELLPath location, const std::string& filename) const
{
return getExpandedFilename(location, "", filename);
@@ -336,15 +405,11 @@ std::string LLDir::getExpandedFilename(ELLPath location, const std::string& subd
break;
case LL_PATH_APP_SETTINGS:
- prefix = getAppRODataDir();
- prefix += mDirDelimiter;
- prefix += "app_settings";
+ prefix = add(getAppRODataDir(), "app_settings");
break;
case LL_PATH_CHARACTER:
- prefix = getAppRODataDir();
- prefix += mDirDelimiter;
- prefix += "character";
+ prefix = add(getAppRODataDir(), "character");
break;
case LL_PATH_HELP:
@@ -356,16 +421,22 @@ std::string LLDir::getExpandedFilename(ELLPath location, const std::string& subd
break;
case LL_PATH_USER_SETTINGS:
- prefix = getOSUserAppDir();
- prefix += mDirDelimiter;
- prefix += "user_settings";
+ prefix = add(getOSUserAppDir(), "user_settings");
break;
case LL_PATH_PER_SL_ACCOUNT:
prefix = getLindenUserDir();
if (prefix.empty())
{
- // if we're asking for the per-SL-account directory but we haven't logged in yet (or otherwise don't know the account name from which to build this string), then intentionally return a blank string to the caller and skip the below warning about a blank prefix.
+ // if we're asking for the per-SL-account directory but we haven't
+ // logged in yet (or otherwise don't know the account name from
+ // which to build this string), then intentionally return a blank
+ // string to the caller and skip the below warning about a blank
+ // prefix.
+ LL_DEBUGS("LLDir") << "getLindenUserDir() not yet set: "
+ << ELLPathToString(location)
+ << ", '" << subdir1 << "', '" << subdir2 << "', '" << in_filename
+ << "' => ''" << LL_ENDL;
return std::string();
}
break;
@@ -379,9 +450,7 @@ std::string LLDir::getExpandedFilename(ELLPath location, const std::string& subd
break;
case LL_PATH_LOGS:
- prefix = getOSUserAppDir();
- prefix += mDirDelimiter;
- prefix += "logs";
+ prefix = add(getOSUserAppDir(), "logs");
break;
case LL_PATH_TEMP:
@@ -405,9 +474,7 @@ std::string LLDir::getExpandedFilename(ELLPath location, const std::string& subd
break;
case LL_PATH_LOCAL_ASSETS:
- prefix = getAppRODataDir();
- prefix += mDirDelimiter;
- prefix += "local_assets";
+ prefix = add(getAppRODataDir(), "local_assets");
break;
case LL_PATH_EXECUTABLE:
@@ -415,56 +482,36 @@ std::string LLDir::getExpandedFilename(ELLPath location, const std::string& subd
break;
case LL_PATH_FONTS:
- prefix = getAppRODataDir();
- prefix += mDirDelimiter;
- prefix += "fonts";
+ prefix = add(getAppRODataDir(), "fonts");
break;
default:
llassert(0);
}
- std::string filename = in_filename;
- if (!subdir2.empty())
- {
- filename = subdir2 + mDirDelimiter + filename;
- }
-
- if (!subdir1.empty())
- {
- filename = subdir1 + mDirDelimiter + filename;
- }
-
if (prefix.empty())
{
- llwarns << "prefix is empty, possible bad filename" << llendl;
- }
-
- std::string expanded_filename;
- if (!filename.empty())
- {
- if (!prefix.empty())
- {
- expanded_filename += prefix;
- expanded_filename += mDirDelimiter;
- expanded_filename += filename;
- }
- else
- {
- expanded_filename = filename;
- }
- }
- else if (!prefix.empty())
- {
- // Directory only, no file name.
- expanded_filename = prefix;
+ llwarns << ELLPathToString(location)
+ << ", '" << subdir1 << "', '" << subdir2 << "', '" << in_filename
+ << "': prefix is empty, possible bad filename" << llendl;
}
- else
+
+ std::string expanded_filename = add(add(prefix, subdir1), subdir2);
+ if (expanded_filename.empty() && in_filename.empty())
{
- expanded_filename.assign("");
+ return "";
}
-
- //llinfos << "*** EXPANDED FILENAME: <" << expanded_filename << ">" << llendl;
+ // Use explicit concatenation here instead of another add() call. Callers
+ // passing in_filename as "" expect to obtain a pathname ending with
+ // mDirSeparator so they can later directly concatenate with a specific
+ // filename. A caller using add() doesn't care, but there's still code
+ // loose in the system that uses std::string::operator+().
+ expanded_filename += mDirDelimiter;
+ expanded_filename += in_filename;
+
+ LL_DEBUGS("LLDir") << ELLPathToString(location)
+ << ", '" << subdir1 << "', '" << subdir2 << "', '" << in_filename
+ << "' => '" << expanded_filename << "'" << LL_ENDL;
return expanded_filename;
}
@@ -504,31 +551,207 @@ std::string LLDir::getExtension(const std::string& filepath) const
return exten;
}
-std::string LLDir::findSkinnedFilename(const std::string &filename) const
+std::string LLDir::findSkinnedFilenameBaseLang(const std::string &subdir,
+ const std::string &filename,
+ ESkinConstraint constraint) const
{
- return findSkinnedFilename("", "", filename);
+ // This implementation is basically just as described in the declaration comments.
+ std::vector<std::string> found(findSkinnedFilenames(subdir, filename, constraint));
+ if (found.empty())
+ {
+ return "";
+ }
+ return found.front();
}
-std::string LLDir::findSkinnedFilename(const std::string &subdir, const std::string &filename) const
+std::string LLDir::findSkinnedFilename(const std::string &subdir,
+ const std::string &filename,
+ ESkinConstraint constraint) const
{
- return findSkinnedFilename("", subdir, filename);
+ // This implementation is basically just as described in the declaration comments.
+ std::vector<std::string> found(findSkinnedFilenames(subdir, filename, constraint));
+ if (found.empty())
+ {
+ return "";
+ }
+ return found.back();
}
-std::string LLDir::findSkinnedFilename(const std::string &subdir1, const std::string &subdir2, const std::string &filename) const
+// This method exists because the two code paths for
+// findSkinnedFilenames(ALL_SKINS) and findSkinnedFilenames(CURRENT_SKIN) must
+// generate the list of candidate pathnames in identical ways. The only
+// difference is in the body of the inner loop.
+template <typename FUNCTION>
+void LLDir::walkSearchSkinDirs(const std::string& subdir,
+ const std::vector<std::string>& subsubdirs,
+ const std::string& filename,
+ const FUNCTION& function) const
{
- // generate subdirectory path fragment, e.g. "/foo/bar", "/foo", ""
- std::string subdirs = ((subdir1.empty() ? "" : mDirDelimiter) + subdir1)
- + ((subdir2.empty() ? "" : mDirDelimiter) + subdir2);
+ BOOST_FOREACH(std::string skindir, mSearchSkinDirs)
+ {
+ std::string subdir_path(add(skindir, subdir));
+ BOOST_FOREACH(std::string subsubdir, subsubdirs)
+ {
+ std::string full_path(add(add(subdir_path, subsubdir), filename));
+ if (fileExists(full_path))
+ {
+ function(subsubdir, full_path);
+ }
+ }
+ }
+}
- std::vector<std::string> search_paths;
-
- search_paths.push_back(getUserSkinDir() + subdirs); // first look in user skin override
- search_paths.push_back(getSkinDir() + subdirs); // then in current skin
- search_paths.push_back(getDefaultSkinDir() + subdirs); // then default skin
- search_paths.push_back(getCacheDir() + subdirs); // and last in preload directory
+// ridiculous little helper function that should go away when we can use lambda
+inline void push_back(std::vector<std::string>& vector, const std::string& value)
+{
+ vector.push_back(value);
+}
- std::string found_file = findFile(filename, search_paths);
- return found_file;
+typedef std::map<std::string, std::string> StringMap;
+// ridiculous little helper function that should go away when we can use lambda
+inline void store_in_map(StringMap& map, const std::string& key, const std::string& value)
+{
+ map[key] = value;
+}
+
+std::vector<std::string> LLDir::findSkinnedFilenames(const std::string& subdir,
+ const std::string& filename,
+ ESkinConstraint constraint) const
+{
+ // Recognize subdirs that have no localization.
+ static const std::set<std::string> sUnlocalized = list_of
+ ("") // top-level directory not localized
+ ("textures") // textures not localized
+ ;
+
+ LL_DEBUGS("LLDir") << "subdir '" << subdir << "', filename '" << filename
+ << "', constraint "
+ << ((constraint == CURRENT_SKIN)? "CURRENT_SKIN" : "ALL_SKINS")
+ << LL_ENDL;
+
+ // Cache the default language directory for each subdir we've encountered.
+ // A cache entry whose value is the empty string means "not localized,
+ // don't bother checking again."
+ static StringMap sLocalized;
+
+ // Check whether we've already discovered if this subdir is localized.
+ StringMap::const_iterator found = sLocalized.find(subdir);
+ if (found == sLocalized.end())
+ {
+ // We have not yet determined that. Is it one of the subdirs "known"
+ // to be unlocalized?
+ if (sUnlocalized.find(subdir) != sUnlocalized.end())
+ {
+ // This subdir is known to be unlocalized. Remember that.
+ found = sLocalized.insert(StringMap::value_type(subdir, "")).first;
+ }
+ else
+ {
+ // We do not recognize this subdir. Investigate.
+ std::string subdir_path(add(getDefaultSkinDir(), subdir));
+ if (fileExists(add(subdir_path, "en")))
+ {
+ // defaultSkinDir/subdir contains subdir "en". That's our
+ // default language; this subdir is localized.
+ found = sLocalized.insert(StringMap::value_type(subdir, "en")).first;
+ }
+ else if (fileExists(add(subdir_path, "en-us")))
+ {
+ // defaultSkinDir/subdir contains subdir "en-us" but not "en".
+ // Set as default language; this subdir is localized.
+ found = sLocalized.insert(StringMap::value_type(subdir, "en-us")).first;
+ }
+ else
+ {
+ // defaultSkinDir/subdir contains neither "en" nor "en-us".
+ // Assume it's not localized. Remember that assumption.
+ found = sLocalized.insert(StringMap::value_type(subdir, "")).first;
+ }
+ }
+ }
+ // Every code path above should have resulted in 'found' becoming a valid
+ // iterator to an entry in sLocalized.
+ llassert(found != sLocalized.end());
+
+ // Now -- is this subdir localized, or not? The answer determines what
+ // subdirectories we check (under subdir) for the requested filename.
+ std::vector<std::string> subsubdirs;
+ if (found->second.empty())
+ {
+ // subdir is not localized. filename should be located directly within it.
+ subsubdirs.push_back("");
+ }
+ else
+ {
+ // subdir is localized, and found->second is the default language
+ // directory within it. Check both the default language and the
+ // current language -- if it differs from the default, of course.
+ subsubdirs.push_back(found->second);
+ if (mLanguage != found->second)
+ {
+ subsubdirs.push_back(mLanguage);
+ }
+ }
+
+ // Build results vector.
+ std::vector<std::string> results;
+ // The process we use depends on 'constraint'.
+ if (constraint != CURRENT_SKIN) // meaning ALL_SKINS
+ {
+ // ALL_SKINS is simpler: just return every pathname generated by
+ // walkSearchSkinDirs(). Tricky bit: walkSearchSkinDirs() passes its
+ // FUNCTION the subsubdir as well as the full pathname. We just want
+ // the full pathname.
+ walkSearchSkinDirs(subdir, subsubdirs, filename,
+ boost::bind(push_back, boost::ref(results), _2));
+ }
+ else // CURRENT_SKIN
+ {
+ // CURRENT_SKIN turns out to be a bit of a misnomer because we might
+ // still return files from two different skins. In any case, this
+ // value of 'constraint' means we will return at most two paths: one
+ // for the default language, one for the current language (supposing
+ // those differ).
+ // It is important to allow a user to override only the localization
+ // for a particular file, for all viewer installs, without also
+ // overriding the default-language file.
+ // It is important to allow a user to override only the default-
+ // language file, for all viewer installs, without also overriding the
+ // applicable localization of that file.
+ // Therefore, treat the default language and the current language as
+ // two separate cases. For each, capture the most-specialized file
+ // that exists.
+ // Use a map keyed by subsubdir (i.e. language code). This allows us
+ // to handle the case of a single subsubdirs entry with the same logic
+ // that handles two. For every real file path generated by
+ // walkSearchSkinDirs(), update the map entry for its subsubdir.
+ StringMap path_for;
+ walkSearchSkinDirs(subdir, subsubdirs, filename,
+ boost::bind(store_in_map, boost::ref(path_for), _1, _2));
+ // Now that we have a path for each of the default language and the
+ // current language, copy them -- in proper order -- into results.
+ // Don't drive this by walking the map itself: it matters that we
+ // generate results in the same order as subsubdirs.
+ BOOST_FOREACH(std::string subsubdir, subsubdirs)
+ {
+ StringMap::const_iterator found(path_for.find(subsubdir));
+ if (found != path_for.end())
+ {
+ results.push_back(found->second);
+ }
+ }
+ }
+
+ LL_DEBUGS("LLDir") << empty;
+ const char* comma = "";
+ BOOST_FOREACH(std::string path, results)
+ {
+ LL_CONT << comma << "'" << path << "'";
+ comma = ", ";
+ }
+ LL_CONT << LL_ENDL;
+
+ return results;
}
std::string LLDir::getTempFilename() const
@@ -539,12 +762,7 @@ std::string LLDir::getTempFilename() const
random_uuid.generate();
random_uuid.toString(uuid_str);
- std::string temp_filename = getTempDir();
- temp_filename += mDirDelimiter;
- temp_filename += uuid_str;
- temp_filename += ".tmp";
-
- return temp_filename;
+ return add(getTempDir(), uuid_str + ".tmp");
}
// static
@@ -580,9 +798,7 @@ void LLDir::setLindenUserDir(const std::string &username)
std::string userlower(username);
LLStringUtil::toLower(userlower);
LLStringUtil::replaceChar(userlower, ' ', '_');
- mLindenUserDir = getOSUserAppDir();
- mLindenUserDir += mDirDelimiter;
- mLindenUserDir += userlower;
+ mLindenUserDir = add(getOSUserAppDir(), userlower);
}
else
{
@@ -604,6 +820,11 @@ void LLDir::setChatLogsDir(const std::string &path)
}
}
+void LLDir::updatePerAccountChatLogsDir()
+{
+ mPerAccountChatLogsDir = add(getChatLogsDir(), mUserName);
+}
+
void LLDir::setPerAccountChatLogsDir(const std::string &username)
{
// if both first and last aren't set, assume we're grabbing the cached dir
@@ -614,36 +835,69 @@ void LLDir::setPerAccountChatLogsDir(const std::string &username)
std::string userlower(username);
LLStringUtil::toLower(userlower);
LLStringUtil::replaceChar(userlower, ' ', '_');
- mPerAccountChatLogsDir = getChatLogsDir();
- mPerAccountChatLogsDir += mDirDelimiter;
- mPerAccountChatLogsDir += userlower;
+
+ mUserName = userlower;
+ updatePerAccountChatLogsDir();
}
else
{
llerrs << "NULL name for LLDir::setPerAccountChatLogsDir" << llendl;
}
-
}
-void LLDir::setSkinFolder(const std::string &skin_folder)
+void LLDir::setSkinFolder(const std::string &skin_folder, const std::string& language)
{
- mSkinDir = getSkinBaseDir();
- mSkinDir += mDirDelimiter;
- mSkinDir += skin_folder;
+ LL_DEBUGS("LLDir") << "Setting skin '" << skin_folder << "', language '" << language << "'"
+ << LL_ENDL;
+ mSkinName = skin_folder;
+ mLanguage = language;
- // user modifications to current skin
- // e.g. c:\documents and settings\users\username\application data\second life\skins\dazzle
- mUserSkinDir = getOSUserAppDir();
- mUserSkinDir += mDirDelimiter;
- mUserSkinDir += "skins";
- mUserSkinDir += mDirDelimiter;
- mUserSkinDir += skin_folder;
+ // This method is called multiple times during viewer initialization. Each
+ // time it's called, reset mSearchSkinDirs.
+ mSearchSkinDirs.clear();
// base skin which is used as fallback for all skinned files
// e.g. c:\program files\secondlife\skins\default
mDefaultSkinDir = getSkinBaseDir();
- mDefaultSkinDir += mDirDelimiter;
- mDefaultSkinDir += "default";
+ append(mDefaultSkinDir, "default");
+ // This is always the most general of the search skin directories.
+ addSearchSkinDir(mDefaultSkinDir);
+
+ mSkinDir = getSkinBaseDir();
+ append(mSkinDir, skin_folder);
+ // Next level of generality is a skin installed with the viewer.
+ addSearchSkinDir(mSkinDir);
+
+ // user modifications to skins, current and default
+ // e.g. c:\documents and settings\users\username\application data\second life\skins\dazzle
+ mUserSkinDir = getOSUserAppDir();
+ append(mUserSkinDir, "skins");
+ mUserDefaultSkinDir = mUserSkinDir;
+ append(mUserDefaultSkinDir, "default");
+ append(mUserSkinDir, skin_folder);
+ // Next level of generality is user modifications to default skin...
+ addSearchSkinDir(mUserDefaultSkinDir);
+ // then user-defined skins.
+ addSearchSkinDir(mUserSkinDir);
+}
+
+void LLDir::addSearchSkinDir(const std::string& skindir)
+{
+ if (std::find(mSearchSkinDirs.begin(), mSearchSkinDirs.end(), skindir) == mSearchSkinDirs.end())
+ {
+ LL_DEBUGS("LLDir") << "search skin: '" << skindir << "'" << LL_ENDL;
+ mSearchSkinDirs.push_back(skindir);
+ }
+}
+
+std::string LLDir::getSkinFolder() const
+{
+ return mSkinName;
+}
+
+std::string LLDir::getLanguage() const
+{
+ return mLanguage;
}
bool LLDir::setCacheDir(const std::string &path)
@@ -657,7 +911,7 @@ bool LLDir::setCacheDir(const std::string &path)
else
{
LLFile::mkdir(path);
- std::string tempname = path + mDirDelimiter + "temp";
+ std::string tempname = add(path, "temp");
LLFILE* file = LLFile::fopen(tempname,"wt");
if (file)
{
@@ -690,6 +944,57 @@ void LLDir::dumpCurrentDirectories()
LL_DEBUGS2("AppInit","Directories") << " SkinDir: " << getSkinDir() << LL_ENDL;
}
+std::string LLDir::add(const std::string& path, const std::string& name) const
+{
+ std::string destpath(path);
+ append(destpath, name);
+ return destpath;
+}
+
+void LLDir::append(std::string& destpath, const std::string& name) const
+{
+ // Delegate question of whether we need a separator to helper method.
+ SepOff sepoff(needSep(destpath, name));
+ if (sepoff.first) // do we need a separator?
+ {
+ destpath += mDirDelimiter;
+ }
+ // If destpath ends with a separator, AND name starts with one, skip
+ // name's leading separator.
+ destpath += name.substr(sepoff.second);
+}
+
+LLDir::SepOff LLDir::needSep(const std::string& path, const std::string& name) const
+{
+ if (path.empty() || name.empty())
+ {
+ // If either path or name are empty, we do not need a separator
+ // between them.
+ return SepOff(false, 0);
+ }
+ // Here we know path and name are both non-empty. But if path already ends
+ // with a separator, or if name already starts with a separator, we need
+ // not add one.
+ std::string::size_type seplen(mDirDelimiter.length());
+ bool path_ends_sep(path.substr(path.length() - seplen) == mDirDelimiter);
+ bool name_starts_sep(name.substr(0, seplen) == mDirDelimiter);
+ if ((! path_ends_sep) && (! name_starts_sep))
+ {
+ // If neither path nor name brings a separator to the junction, then
+ // we need one.
+ return SepOff(true, 0);
+ }
+ if (path_ends_sep && name_starts_sep)
+ {
+ // But if BOTH path and name bring a separator, we need not add one.
+ // Moreover, we should actually skip the leading separator of 'name'.
+ return SepOff(false, seplen);
+ }
+ // Here we know that either path_ends_sep or name_starts_sep is true --
+ // but not both. So don't add a separator, and don't skip any characters:
+ // simple concatenation will do the trick.
+ return SepOff(false, 0);
+}
void dir_exists_or_crash(const std::string &dir_name)
{
diff --git a/indra/llvfs/lldir.h b/indra/llvfs/lldir.h
index 5ee8bdb542..e02bf552aa 100644..100755
--- a/indra/llvfs/lldir.h
+++ b/indra/llvfs/lldir.h
@@ -1,4 +1,4 @@
-/**
+/**
* @file lldir.h
* @brief Definition of directory utilities class
*
@@ -32,7 +32,7 @@
#define MAX_PATH MAXPATHLEN
#endif
-// these numbers *may* get serialized (really??), so we need to be explicit
+// these numbers are read from settings_files.xml, so we need to be explicit
typedef enum ELLPath
{
LL_PATH_NONE = 0,
@@ -56,7 +56,7 @@ typedef enum ELLPath
LL_PATH_LAST
} ELLPath;
-
+/// Directory operations
class LLDir
{
public:
@@ -73,10 +73,8 @@ class LLDir
virtual S32 deleteFilesInDir(const std::string &dirname, const std::string &mask);
// pure virtual functions
- virtual U32 countFilesInDir(const std::string &dirname, const std::string &mask) = 0;
-
virtual std::string getCurPath() = 0;
- virtual BOOL fileExists(const std::string &filename) const = 0;
+ virtual bool fileExists(const std::string &filename) const = 0;
const std::string findFile(const std::string& filename, const std::vector<std::string> filenames) const;
const std::string findFile(const std::string& filename, const std::string& searchPath1 = "", const std::string& searchPath2 = "", const std::string& searchPath3 = "") const;
@@ -100,11 +98,13 @@ class LLDir
const std::string &getOSCacheDir() const; // location of OS-specific cache folder (may be empty string)
const std::string &getCAFile() const; // File containing TLS certificate authorities
const std::string &getDirDelimiter() const; // directory separator for platform (ie. '\' or '/' or ':')
+ const std::string &getDefaultSkinDir() const; // folder for default skin. e.g. c:\program files\second life\skins\default
const std::string &getSkinDir() const; // User-specified skin folder.
+ const std::string &getUserDefaultSkinDir() const; // dir with user modifications to default skin
const std::string &getUserSkinDir() const; // User-specified skin folder with user modifications. e.g. c:\documents and settings\username\application data\second life\skins\curskin
- const std::string &getDefaultSkinDir() const; // folder for default skin. e.g. c:\program files\second life\skins\default
const std::string getSkinBaseDir() const; // folder that contains all installed skins (not user modifications). e.g. c:\program files\second life\skins
const std::string &getLLPluginDir() const; // Directory containing plugins and plugin shell
+ const std::string &getUserName() const;
// Expanded filename
std::string getExpandedFilename(ELLPath location, const std::string &filename) const;
@@ -117,10 +117,61 @@ class LLDir
std::string getExtension(const std::string& filepath) const; // Excludes '.', e.g getExtension("foo.wav") == "wav"
// these methods search the various skin paths for the specified file in the following order:
- // getUserSkinDir(), getSkinDir(), getDefaultSkinDir()
- std::string findSkinnedFilename(const std::string &filename) const;
- std::string findSkinnedFilename(const std::string &subdir, const std::string &filename) const;
- std::string findSkinnedFilename(const std::string &subdir1, const std::string &subdir2, const std::string &filename) const;
+ // getUserSkinDir(), getUserDefaultSkinDir(), getSkinDir(), getDefaultSkinDir()
+ /// param value for findSkinnedFilenames(), explained below
+ enum ESkinConstraint { CURRENT_SKIN, ALL_SKINS };
+ /**
+ * Given a filename within skin, return an ordered sequence of paths to
+ * search. Nonexistent files will be filtered out -- which means that the
+ * vector might be empty.
+ *
+ * @param subdir Identify top-level skin subdirectory by passing one of
+ * LLDir::XUI (file lives under "xui" subtree), LLDir::TEXTURES (file
+ * lives under "textures" subtree), LLDir::SKINBASE (file lives at top
+ * level of skin subdirectory).
+ * @param filename Desired filename within subdir within skin, e.g.
+ * "panel_login.xml". DO NOT prepend (e.g.) "xui" or the desired language.
+ * @param constraint Callers perform two different kinds of processing.
+ * When fetching a XUI file, for instance, the existence of @a filename in
+ * the specified skin completely supercedes any @a filename in the default
+ * skin. For that case, leave the default @a constraint=CURRENT_SKIN. The
+ * returned vector will contain only
+ * ".../<i>current_skin</i>/xui/en/<i>filename</i>",
+ * ".../<i>current_skin</i>/xui/<i>current_language</i>/<i>filename</i>".
+ * But for (e.g.) "strings.xml", we want a given skin to be able to
+ * override only specific entries from the default skin. Any string not
+ * defined in the specified skin will be sought in the default skin. For
+ * that case, pass @a constraint=ALL_SKINS. The returned vector will
+ * contain at least ".../default/xui/en/strings.xml",
+ * ".../default/xui/<i>current_language</i>/strings.xml",
+ * ".../<i>current_skin</i>/xui/en/strings.xml",
+ * ".../<i>current_skin</i>/xui/<i>current_language</i>/strings.xml".
+ */
+ std::vector<std::string> findSkinnedFilenames(const std::string& subdir,
+ const std::string& filename,
+ ESkinConstraint constraint=CURRENT_SKIN) const;
+ /// Values for findSkinnedFilenames(subdir) parameter
+ static const char *XUI, *TEXTURES, *SKINBASE;
+ /**
+ * Return the base-language pathname from findSkinnedFilenames(), or
+ * the empty string if no such file exists. Parameters are identical to
+ * findSkinnedFilenames(). This is shorthand for capturing the vector
+ * returned by findSkinnedFilenames(), checking for empty() and then
+ * returning front().
+ */
+ std::string findSkinnedFilenameBaseLang(const std::string &subdir,
+ const std::string &filename,
+ ESkinConstraint constraint=CURRENT_SKIN) const;
+ /**
+ * Return the "most localized" pathname from findSkinnedFilenames(), or
+ * the empty string if no such file exists. Parameters are identical to
+ * findSkinnedFilenames(). This is shorthand for capturing the vector
+ * returned by findSkinnedFilenames(), checking for empty() and then
+ * returning back().
+ */
+ std::string findSkinnedFilename(const std::string &subdir,
+ const std::string &filename,
+ ESkinConstraint constraint=CURRENT_SKIN) const;
// random filename in common temporary directory
std::string getTempFilename() const;
@@ -132,15 +183,38 @@ class LLDir
virtual void setChatLogsDir(const std::string &path); // Set the chat logs dir to this user's dir
virtual void setPerAccountChatLogsDir(const std::string &username); // Set the per user chat log directory.
virtual void setLindenUserDir(const std::string &username); // Set the linden user dir to this user's dir
- virtual void setSkinFolder(const std::string &skin_folder);
+ virtual void setSkinFolder(const std::string &skin_folder, const std::string& language);
+ virtual std::string getSkinFolder() const;
+ virtual std::string getLanguage() const;
virtual bool setCacheDir(const std::string &path);
+ virtual void updatePerAccountChatLogsDir();
virtual void dumpCurrentDirectories();
-
+
// Utility routine
std::string buildSLOSCacheDir() const;
+ /// Append specified @a name to @a destpath, separated by getDirDelimiter()
+ /// if both are non-empty.
+ void append(std::string& destpath, const std::string& name) const;
+ /// Append specified @a name to @a path, separated by getDirDelimiter()
+ /// if both are non-empty. Return result, leaving @a path unmodified.
+ std::string add(const std::string& path, const std::string& name) const;
+
protected:
+ // Does an add() or append() call need a directory delimiter?
+ typedef std::pair<bool, unsigned short> SepOff;
+ SepOff needSep(const std::string& path, const std::string& name) const;
+ // build mSearchSkinDirs without adding duplicates
+ void addSearchSkinDir(const std::string& skindir);
+
+ // Internal to findSkinnedFilenames()
+ template <typename FUNCTION>
+ void walkSearchSkinDirs(const std::string& subdir,
+ const std::vector<std::string>& subsubdirs,
+ const std::string& filename,
+ const FUNCTION& function) const;
+
std::string mAppName; // install directory under progams/ ie "SecondLife"
std::string mExecutablePathAndName; // full path + Filename of .exe
std::string mExecutableFilename; // Filename of .exe
@@ -158,11 +232,20 @@ protected:
std::string mDefaultCacheDir; // default cache diretory
std::string mOSCacheDir; // operating system cache dir
std::string mDirDelimiter;
+ std::string mSkinName; // caller-specified skin name
std::string mSkinBaseDir; // Base for skins paths.
- std::string mSkinDir; // Location for current skin info.
std::string mDefaultSkinDir; // Location for default skin info.
+ std::string mSkinDir; // Location for current skin info.
+ std::string mUserDefaultSkinDir; // Location for default skin info.
std::string mUserSkinDir; // Location for user-modified skin info.
+ // Skin directories to search, most general to most specific. This order
+ // works well for composing fine-grained files, in which an individual item
+ // in a specific file overrides the corresponding item in more general
+ // files. Of course, for a file-level search, iterate backwards.
+ std::vector<std::string> mSearchSkinDirs;
+ std::string mLanguage; // Current viewer language
std::string mLLPluginDir; // Location for plugins and plugin shell
+ std::string mUserName; // Current user name
};
void dir_exists_or_crash(const std::string &dir_name);
diff --git a/indra/llvfs/lldir_linux.cpp b/indra/llvfs/lldir_linux.cpp
index 407f3b93fb..4edd078640 100644..100755
--- a/indra/llvfs/lldir_linux.cpp
+++ b/indra/llvfs/lldir_linux.cpp
@@ -254,7 +254,7 @@ std::string LLDir_Linux::getCurPath()
}
-BOOL LLDir_Linux::fileExists(const std::string &filename) const
+bool LLDir_Linux::fileExists(const std::string &filename) const
{
struct stat stat_data;
// Check the age of the file
diff --git a/indra/llvfs/lldir_linux.h b/indra/llvfs/lldir_linux.h
index 7603239867..e83a020ba4 100644..100755
--- a/indra/llvfs/lldir_linux.h
+++ b/indra/llvfs/lldir_linux.h
@@ -47,7 +47,7 @@ public:
virtual std::string getCurPath();
virtual U32 countFilesInDir(const std::string &dirname, const std::string &mask);
- /*virtual*/ BOOL fileExists(const std::string &filename) const;
+ /*virtual*/ bool fileExists(const std::string &filename) const;
/*virtual*/ std::string getLLPluginLauncher();
/*virtual*/ std::string getLLPluginFilename(std::string base_name);
diff --git a/indra/llvfs/lldir_mac.cpp b/indra/llvfs/lldir_mac.cpp
index 489bc3e4a7..e00596cdb5 100644..100755
--- a/indra/llvfs/lldir_mac.cpp
+++ b/indra/llvfs/lldir_mac.cpp
@@ -22,7 +22,7 @@
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
- */
+ */
#if LL_DARWIN
@@ -35,73 +35,27 @@
#include <sys/stat.h>
#include <unistd.h>
#include <glob.h>
-
-#include <Carbon/Carbon.h>
-
-// --------------------------------------------------------------------------------
-
-static OSStatus CFCreateDirectory(FSRef *parentRef, CFStringRef name, FSRef *newRef)
-{
- OSStatus result = noErr;
- HFSUniStr255 uniStr;
-
- uniStr.length = CFStringGetLength(name);
- CFStringGetCharacters(name, CFRangeMake(0, uniStr.length), uniStr.unicode);
- result = FSMakeFSRefUnicode(parentRef, uniStr.length, uniStr.unicode, kTextEncodingMacRoman, newRef);
- if (result != noErr)
- {
- result = FSCreateDirectoryUnicode(parentRef, uniStr.length, uniStr.unicode, 0, NULL, newRef, NULL, NULL);
- }
-
- return result;
-}
+#include <boost/filesystem.hpp>
+#include "llvfs_objc.h"
// --------------------------------------------------------------------------------
-static void CFStringRefToLLString(CFStringRef stringRef, std::string &llString, bool releaseWhenDone)
+static bool CreateDirectory(const std::string &parent,
+ const std::string &child,
+ std::string *fullname)
{
- if (stringRef)
- {
- long stringSize = CFStringGetLength(stringRef) + 1;
- long bufferSize = CFStringGetMaximumSizeForEncoding(stringSize,kCFStringEncodingUTF8);
- char* buffer = new char[bufferSize];
- memset(buffer, 0, bufferSize);
- if (CFStringGetCString(stringRef, buffer, bufferSize, kCFStringEncodingUTF8))
- llString = buffer;
- delete[] buffer;
- if (releaseWhenDone)
- CFRelease(stringRef);
- }
-}
-
-// --------------------------------------------------------------------------------
-
-static void CFURLRefToLLString(CFURLRef urlRef, std::string &llString, bool releaseWhenDone)
-{
- if (urlRef)
- {
- CFURLRef absoluteURLRef = CFURLCopyAbsoluteURL(urlRef);
- if (absoluteURLRef)
- {
- CFStringRef stringRef = CFURLCopyFileSystemPath(absoluteURLRef, kCFURLPOSIXPathStyle);
- CFStringRefToLLString(stringRef, llString, true);
- CFRelease(absoluteURLRef);
- }
- if (releaseWhenDone)
- CFRelease(urlRef);
- }
-}
-
-// --------------------------------------------------------------------------------
-
-static void FSRefToLLString(FSRef *fsRef, std::string &llString)
-{
- OSStatus error = noErr;
- char path[MAX_PATH];
-
- error = FSRefMakePath(fsRef, (UInt8*) path, sizeof(path));
- if (error == noErr)
- llString = path;
+
+ boost::filesystem::path p(parent);
+ p /= child;
+
+ if (fullname)
+ *fullname = std::string(p.string());
+
+ if (! boost::filesystem::create_directory(p))
+ {
+ return (boost::filesystem::is_directory(p));
+ }
+ return true;
}
// --------------------------------------------------------------------------------
@@ -109,35 +63,28 @@ static void FSRefToLLString(FSRef *fsRef, std::string &llString)
LLDir_Mac::LLDir_Mac()
{
mDirDelimiter = "/";
- mCurrentDirIndex = -1;
- mCurrentDirCount = -1;
-
- CFBundleRef mainBundleRef = NULL;
- CFURLRef executableURLRef = NULL;
- CFStringRef stringRef = NULL;
- OSStatus error = noErr;
- FSRef fileRef;
- CFStringRef secondLifeString = CFSTR("SecondLife");
-
- mainBundleRef = CFBundleGetMainBundle();
-
- executableURLRef = CFBundleCopyExecutableURL(mainBundleRef);
-
- if (executableURLRef != NULL)
+
+ const std::string secondLifeString = "SecondLife";
+
+ std::string *executablepathstr = getSystemExecutableFolder();
+
+ //NOTE: LLINFOS/LLERRS will not output to log here. The streams are not initialized.
+
+ if (executablepathstr)
{
// mExecutablePathAndName
- CFURLRefToLLString(executableURLRef, mExecutablePathAndName, false);
-
- // mExecutableFilename
- stringRef = CFURLCopyLastPathComponent(executableURLRef);
- CFStringRefToLLString(stringRef, mExecutableFilename, true);
-
- // mExecutableDir
- CFURLRef executableParentURLRef = CFURLCreateCopyDeletingLastPathComponent(NULL, executableURLRef);
- CFURLRefToLLString(executableParentURLRef, mExecutableDir, true);
+ mExecutablePathAndName = *executablepathstr;
+
+ boost::filesystem::path executablepath(*executablepathstr);
+
+# ifndef BOOST_SYSTEM_NO_DEPRECATED
+#endif
+ mExecutableFilename = executablepath.filename().string();
+ mExecutableDir = executablepath.parent_path().string();
// mAppRODataDir
-
+ std::string *resourcepath = getSystemResourceFolder();
+ mAppRODataDir = *resourcepath;
// *NOTE: When running in a dev tree, use the copy of
// skins in indra/newview/ rather than in the application bundle. This
@@ -146,10 +93,7 @@ LLDir_Mac::LLDir_Mac()
// MBW -- This keeps the mac application from finding other things.
// If this is really for skins, it should JUST apply to skins.
-
- CFURLRef resourcesURLRef = CFBundleCopyResourcesDirectoryURL(mainBundleRef);
- CFURLRefToLLString(resourcesURLRef, mAppRODataDir, true);
-
+
U32 build_dir_pos = mExecutableDir.rfind("/build-darwin-");
if (build_dir_pos != std::string::npos)
{
@@ -166,55 +110,50 @@ LLDir_Mac::LLDir_Mac()
}
// mOSUserDir
- error = FSFindFolder(kUserDomain, kApplicationSupportFolderType, true, &fileRef);
- if (error == noErr)
- {
- FSRef newFileRef;
-
- // Create the directory
- error = CFCreateDirectory(&fileRef, secondLifeString, &newFileRef);
- if (error == noErr)
- {
- // Save the full path to the folder
- FSRefToLLString(&newFileRef, mOSUserDir);
-
- // Create our sub-dirs
- (void) CFCreateDirectory(&newFileRef, CFSTR("data"), NULL);
- //(void) CFCreateDirectory(&newFileRef, CFSTR("cache"), NULL);
- (void) CFCreateDirectory(&newFileRef, CFSTR("logs"), NULL);
- (void) CFCreateDirectory(&newFileRef, CFSTR("user_settings"), NULL);
- (void) CFCreateDirectory(&newFileRef, CFSTR("browser_profile"), NULL);
- }
- }
-
+ std::string *appdir = getSystemApplicationSupportFolder();
+ std::string rootdir;
+
+ //Create root directory
+ if (CreateDirectory(*appdir, secondLifeString, &rootdir))
+ {
+
+ // Save the full path to the folder
+ mOSUserDir = rootdir;
+
+ // Create our sub-dirs
+ CreateDirectory(rootdir, std::string("data"), NULL);
+ CreateDirectory(rootdir, std::string("logs"), NULL);
+ CreateDirectory(rootdir, std::string("user_settings"), NULL);
+ CreateDirectory(rootdir, std::string("browser_profile"), NULL);
+ }
+
//mOSCacheDir
- FSRef cacheDirRef;
- error = FSFindFolder(kUserDomain, kCachedDataFolderType, true, &cacheDirRef);
- if (error == noErr)
+ std::string *cachedir = getSystemCacheFolder();
+
+ if (cachedir)
+
{
- FSRefToLLString(&cacheDirRef, mOSCacheDir);
- (void)CFCreateDirectory(&cacheDirRef, CFSTR("SecondLife"),NULL);
+ mOSCacheDir = *cachedir;
+ //Aura TODO: This changes from ~/Library/Cache/Secondlife to ~/Library/Cache/com.app.secondlife/Secondlife. Last dir level could go away.
+ CreateDirectory(mOSCacheDir, secondLifeString, NULL);
}
// mOSUserAppDir
mOSUserAppDir = mOSUserDir;
// mTempDir
- error = FSFindFolder(kOnAppropriateDisk, kTemporaryFolderType, true, &fileRef);
- if (error == noErr)
- {
- FSRef tempRef;
- error = CFCreateDirectory(&fileRef, secondLifeString, &tempRef);
- if (error == noErr)
- FSRefToLLString(&tempRef, mTempDir);
- }
+ //Aura 120920 boost::filesystem::temp_directory_path() not yet implemented on mac. :(
+ std::string *tmpdir = getSystemTempFolder();
+ if (tmpdir)
+ {
+
+ CreateDirectory(*tmpdir, secondLifeString, &mTempDir);
+ if (tmpdir) delete tmpdir;
+ }
mWorkingDir = getCurPath();
mLLPluginDir = mAppRODataDir + mDirDelimiter + "llplugin";
-
- CFRelease(executableURLRef);
- executableURLRef = NULL;
}
}
@@ -235,52 +174,18 @@ void LLDir_Mac::initAppDirs(const std::string &app_name,
mSkinBaseDir = mAppRODataDir + mDirDelimiter + "skins";
}
mCAFile = getExpandedFilename(LL_PATH_APP_SETTINGS, "CA.pem");
-
- //dumpCurrentDirectories();
-}
-
-U32 LLDir_Mac::countFilesInDir(const std::string &dirname, const std::string &mask)
-{
- U32 file_count = 0;
- glob_t g;
-
- std::string tmp_str;
- tmp_str = dirname;
- tmp_str += mask;
-
- if(glob(tmp_str.c_str(), GLOB_NOSORT, NULL, &g) == 0)
- {
- file_count = g.gl_pathc;
-
- globfree(&g);
- }
-
- return (file_count);
}
std::string LLDir_Mac::getCurPath()
{
- char tmp_str[LL_MAX_PATH]; /* Flawfinder: ignore */
- getcwd(tmp_str, LL_MAX_PATH);
- return tmp_str;
+ return boost::filesystem::path( boost::filesystem::current_path() ).string();
}
-BOOL LLDir_Mac::fileExists(const std::string &filename) const
+bool LLDir_Mac::fileExists(const std::string &filename) const
{
- struct stat stat_data;
- // Check the age of the file
- // Now, we see if the files we've gathered are recent...
- int res = stat(filename.c_str(), &stat_data);
- if (!res)
- {
- return TRUE;
- }
- else
- {
- return FALSE;
- }
+ return boost::filesystem::exists(filename);
}
diff --git a/indra/llvfs/lldir_mac.h b/indra/llvfs/lldir_mac.h
index d190d70be4..558727ebbc 100644..100755
--- a/indra/llvfs/lldir_mac.h
+++ b/indra/llvfs/lldir_mac.h
@@ -22,7 +22,7 @@
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
- */
+ */
#if !LL_DARWIN
#error This header must not be included when compiling for any target other than Mac OS. Consider including lldir.h instead.
@@ -45,16 +45,10 @@ public:
const std::string& app_read_only_data_dir);
virtual std::string getCurPath();
- virtual U32 countFilesInDir(const std::string &dirname, const std::string &mask);
- virtual BOOL fileExists(const std::string &filename) const;
+ virtual bool fileExists(const std::string &filename) const;
/*virtual*/ std::string getLLPluginLauncher();
/*virtual*/ std::string getLLPluginFilename(std::string base_name);
-
-private:
- int mCurrentDirIndex;
- int mCurrentDirCount;
- std::string mCurrentDir;
};
#endif // LL_LLDIR_MAC_H
diff --git a/indra/llvfs/lldir_solaris.cpp b/indra/llvfs/lldir_solaris.cpp
index 21f8c3acdb..a97d72d539 100644..100755
--- a/indra/llvfs/lldir_solaris.cpp
+++ b/indra/llvfs/lldir_solaris.cpp
@@ -272,7 +272,7 @@ std::string LLDir_Solaris::getCurPath()
}
-BOOL LLDir_Solaris::fileExists(const std::string &filename) const
+bool LLDir_Solaris::fileExists(const std::string &filename) const
{
struct stat stat_data;
// Check the age of the file
diff --git a/indra/llvfs/lldir_solaris.h b/indra/llvfs/lldir_solaris.h
index 0b58a45b15..c6dac57e14 100644..100755
--- a/indra/llvfs/lldir_solaris.h
+++ b/indra/llvfs/lldir_solaris.h
@@ -47,7 +47,7 @@ public:
virtual std::string getCurPath();
virtual U32 countFilesInDir(const std::string &dirname, const std::string &mask);
- /*virtual*/ BOOL fileExists(const std::string &filename) const;
+ /*virtual*/ bool fileExists(const std::string &filename) const;
private:
DIR *mDirp;
diff --git a/indra/llvfs/lldir_win32.cpp b/indra/llvfs/lldir_win32.cpp
index 7709945123..6184095957 100644..100755
--- a/indra/llvfs/lldir_win32.cpp
+++ b/indra/llvfs/lldir_win32.cpp
@@ -131,7 +131,7 @@ LLDir_Win32::LLDir_Win32()
mAppRODataDir = mExecutableDir;
}
- llinfos << "mAppRODataDir = " << mAppRODataDir << llendl;
+// llinfos << "mAppRODataDir = " << mAppRODataDir << llendl;
mSkinBaseDir = mAppRODataDir + mDirDelimiter + "skins";
@@ -249,7 +249,7 @@ std::string LLDir_Win32::getCurPath()
}
-BOOL LLDir_Win32::fileExists(const std::string &filename) const
+bool LLDir_Win32::fileExists(const std::string &filename) const
{
llstat stat_data;
// Check the age of the file
diff --git a/indra/llvfs/lldir_win32.h b/indra/llvfs/lldir_win32.h
index 62fb4713ab..450efaf9da 100644..100755
--- a/indra/llvfs/lldir_win32.h
+++ b/indra/llvfs/lldir_win32.h
@@ -44,7 +44,7 @@ public:
/*virtual*/ std::string getCurPath();
/*virtual*/ U32 countFilesInDir(const std::string &dirname, const std::string &mask);
- /*virtual*/ BOOL fileExists(const std::string &filename) const;
+ /*virtual*/ bool fileExists(const std::string &filename) const;
/*virtual*/ std::string getLLPluginLauncher();
/*virtual*/ std::string getLLPluginFilename(std::string base_name);
diff --git a/indra/llvfs/lldirguard.h b/indra/llvfs/lldirguard.h
index 4330095ad0..4330095ad0 100644..100755
--- a/indra/llvfs/lldirguard.h
+++ b/indra/llvfs/lldirguard.h
diff --git a/indra/llvfs/lldiriterator.cpp b/indra/llvfs/lldiriterator.cpp
index ff92cbb7fd..460d2a8b4f 100644..100755
--- a/indra/llvfs/lldiriterator.cpp
+++ b/indra/llvfs/lldiriterator.cpp
@@ -26,6 +26,7 @@
#include "lldiriterator.h"
+#include "fix_macros.h"
#include <boost/filesystem.hpp>
#include <boost/regex.hpp>
@@ -59,7 +60,7 @@ LLDirIterator::Impl::Impl(const std::string &dirname, const std::string &mask)
{
is_dir = fs::is_directory(dir_path);
}
- catch (fs::basic_filesystem_error<fs::path>& e)
+ catch (const fs::filesystem_error& e)
{
llwarns << e.what() << llendl;
return;
@@ -76,7 +77,7 @@ LLDirIterator::Impl::Impl(const std::string &dirname, const std::string &mask)
{
mIter = fs::directory_iterator(dir_path);
}
- catch (fs::basic_filesystem_error<fs::path>& e)
+ catch (const fs::filesystem_error& e)
{
llwarns << e.what() << llendl;
return;
@@ -121,7 +122,7 @@ bool LLDirIterator::Impl::next(std::string &fname)
while (mIter != end_itr && !found)
{
boost::smatch match;
- std::string name = mIter->path().filename();
+ std::string name = mIter->path().filename().string();
if (found = boost::regex_match(name, match, mFilterExp))
{
fname = name;
diff --git a/indra/llvfs/lldiriterator.h b/indra/llvfs/lldiriterator.h
index 0b48be41b3..0b48be41b3 100644..100755
--- a/indra/llvfs/lldiriterator.h
+++ b/indra/llvfs/lldiriterator.h
diff --git a/indra/llvfs/lllfsthread.cpp b/indra/llvfs/lllfsthread.cpp
index 073b1af2a1..073b1af2a1 100644..100755
--- a/indra/llvfs/lllfsthread.cpp
+++ b/indra/llvfs/lllfsthread.cpp
diff --git a/indra/llvfs/lllfsthread.h b/indra/llvfs/lllfsthread.h
index cdb5c75946..cdb5c75946 100644..100755
--- a/indra/llvfs/lllfsthread.h
+++ b/indra/llvfs/lllfsthread.h
diff --git a/indra/llvfs/llpidlock.cpp b/indra/llvfs/llpidlock.cpp
index 0424f2379e..0424f2379e 100644..100755
--- a/indra/llvfs/llpidlock.cpp
+++ b/indra/llvfs/llpidlock.cpp
diff --git a/indra/llvfs/llpidlock.h b/indra/llvfs/llpidlock.h
index d3295f4911..d3295f4911 100644..100755
--- a/indra/llvfs/llpidlock.h
+++ b/indra/llvfs/llpidlock.h
diff --git a/indra/llvfs/llvfile.cpp b/indra/llvfs/llvfile.cpp
index ca749c5eaf..306d7d8ec7 100644..100755
--- a/indra/llvfs/llvfile.cpp
+++ b/indra/llvfs/llvfile.cpp
@@ -32,6 +32,7 @@
#include "llthread.h"
#include "llstat.h"
#include "llvfs.h"
+#include "llmemory.h"
const S32 LLVFile::READ = 0x00000001;
const S32 LLVFile::WRITE = 0x00000002;
@@ -135,12 +136,12 @@ U8* LLVFile::readFile(LLVFS *vfs, const LLUUID &uuid, LLAssetType::EType type, S
}
else
{
- data = new U8[file_size];
+ data = (U8*) ll_aligned_malloc_16(file_size);
file.read(data, file_size); /* Flawfinder: ignore */
if (file.getLastBytesRead() != (S32)file_size)
{
- delete[] data;
+ ll_aligned_free(data);
data = NULL;
file_size = 0;
}
diff --git a/indra/llvfs/llvfile.h b/indra/llvfs/llvfile.h
index 7e9d9f73e5..7e9d9f73e5 100644..100755
--- a/indra/llvfs/llvfile.h
+++ b/indra/llvfs/llvfile.h
diff --git a/indra/llvfs/llvfs.cpp b/indra/llvfs/llvfs.cpp
index 82c926620a..82c926620a 100644..100755
--- a/indra/llvfs/llvfs.cpp
+++ b/indra/llvfs/llvfs.cpp
diff --git a/indra/llvfs/llvfs.h b/indra/llvfs/llvfs.h
index 63f0f28933..63f0f28933 100644..100755
--- a/indra/llvfs/llvfs.h
+++ b/indra/llvfs/llvfs.h
diff --git a/indra/llvfs/llvfs_objc.h b/indra/llvfs/llvfs_objc.h
new file mode 100755
index 0000000000..90101eb2e9
--- /dev/null
+++ b/indra/llvfs/llvfs_objc.h
@@ -0,0 +1,43 @@
+/**
+ * @file llvfs_objc.h
+ * @brief Definition of directory utilities class for Mac OS X
+ *
+ * $LicenseInfo:firstyear=2000&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#if !LL_DARWIN
+#error This header must not be included when compiling for any target other than Mac OS. Consider including lldir.h instead.
+#endif // !LL_DARWIN
+
+#ifndef LL_LLVFS_OBJC_H
+#define LL_LLVFS_OBJC_H
+
+#include <iostream>
+
+std::string* getSystemTempFolder();
+std::string* getSystemCacheFolder();
+std::string* getSystemApplicationSupportFolder();
+std::string* getSystemResourceFolder();
+std::string* getSystemExecutableFolder();
+
+
+#endif LL_LLVFS_OBJC_H
diff --git a/indra/llvfs/llvfs_objc.mm b/indra/llvfs/llvfs_objc.mm
new file mode 100755
index 0000000000..47b0e73978
--- /dev/null
+++ b/indra/llvfs/llvfs_objc.mm
@@ -0,0 +1,108 @@
+/**
+ * @file llvfs_objc.cpp
+ * @brief Cocoa implementation of directory utilities for Mac OS X
+ *
+ * $LicenseInfo:firstyear=2002&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$
+ */
+#if LL_DARWIN
+
+//WARNING: This file CANNOT use standard linden includes due to conflicts between definitions of BOOL
+
+#include "llvfs_objc.h"
+#import <Cocoa/Cocoa.h>
+
+std::string* getSystemTempFolder()
+{
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ NSString * tempDir = NSTemporaryDirectory();
+ if (tempDir == nil)
+ tempDir = @"/tmp";
+ std::string *result = ( new std::string([tempDir UTF8String]) );
+ [pool release];
+
+ return result;
+}
+
+//findSystemDirectory scoped exclusively to this file.
+std::string* findSystemDirectory(NSSearchPathDirectory searchPathDirectory,
+ NSSearchPathDomainMask domainMask)
+{
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+
+ std::string *result;
+ NSString *path = nil;
+
+ // Search for the path
+ NSArray* paths = NSSearchPathForDirectoriesInDomains(searchPathDirectory,
+ domainMask,
+ YES);
+ if ([paths count])
+ {
+ path = [paths objectAtIndex:0];
+ //HACK: Always attempt to create directory, ignore errors.
+ NSError *error = nil;
+
+ [[NSFileManager defaultManager] createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:&error];
+
+
+ result = new std::string([path UTF8String]);
+ }
+ [pool release];
+ return result;
+}
+
+std::string* getSystemExecutableFolder()
+{
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+
+ NSString *bundlePath = [[NSBundle mainBundle] executablePath];
+ std::string *result = (new std::string([bundlePath UTF8String]));
+ [pool release];
+
+ return result;
+}
+
+std::string* getSystemResourceFolder()
+{
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+
+ NSString *bundlePath = [[NSBundle mainBundle] resourcePath];
+ std::string *result = (new std::string([bundlePath UTF8String]));
+ [pool release];
+
+ return result;
+}
+
+std::string* getSystemCacheFolder()
+{
+ return findSystemDirectory (NSCachesDirectory,
+ NSUserDomainMask);
+}
+
+std::string* getSystemApplicationSupportFolder()
+{
+ return findSystemDirectory (NSApplicationSupportDirectory,
+ NSUserDomainMask);
+
+}
+
+#endif // LL_DARWIN
diff --git a/indra/llvfs/llvfsthread.cpp b/indra/llvfs/llvfsthread.cpp
index a57e2b15ab..a57e2b15ab 100644..100755
--- a/indra/llvfs/llvfsthread.cpp
+++ b/indra/llvfs/llvfsthread.cpp
diff --git a/indra/llvfs/llvfsthread.h b/indra/llvfs/llvfsthread.h
index 95f3c857c6..95f3c857c6 100644..100755
--- a/indra/llvfs/llvfsthread.h
+++ b/indra/llvfs/llvfsthread.h
diff --git a/indra/llvfs/tests/lldir_test.cpp b/indra/llvfs/tests/lldir_test.cpp
index ea321c5ae9..3cff622a4b 100644..100755
--- a/indra/llvfs/tests/lldir_test.cpp
+++ b/indra/llvfs/tests/lldir_test.cpp
@@ -27,11 +27,167 @@
#include "linden_common.h"
+#include "llstring.h"
+#include "tests/StringVec.h"
#include "../lldir.h"
#include "../lldiriterator.h"
#include "../test/lltut.h"
+#include "stringize.h"
+#include <boost/foreach.hpp>
+#include <boost/assign/list_of.hpp>
+
+using boost::assign::list_of;
+
+// We use ensure_equals(..., vec(list_of(...))) not because it's functionally
+// required, but because ensure_equals() knows how to format a StringVec.
+// Turns out that when ensure_equals() displays a test failure with just
+// list_of("string")("another"), you see 'stringanother' vs. '("string",
+// "another")'.
+StringVec vec(const StringVec& v)
+{
+ return v;
+}
+// For some tests, use a dummy LLDir that uses memory data instead of touching
+// the filesystem
+struct LLDir_Dummy: public LLDir
+{
+ /*----------------------------- LLDir API ------------------------------*/
+ LLDir_Dummy()
+ {
+ // Initialize important LLDir data members based on the filesystem
+ // data below.
+ mDirDelimiter = "/";
+ mExecutableDir = "install";
+ mExecutableFilename = "test";
+ mExecutablePathAndName = add(mExecutableDir, mExecutableFilename);
+ mWorkingDir = mExecutableDir;
+ mAppRODataDir = "install";
+ mSkinBaseDir = add(mAppRODataDir, "skins");
+ mOSUserDir = "user";
+ mOSUserAppDir = mOSUserDir;
+ mLindenUserDir = "";
+
+ // Make the dummy filesystem look more or less like what we expect in
+ // the real one.
+ static const char* preload[] =
+ {
+ // We group these fixture-data pathnames by basename, rather than
+ // sorting by full path as you might expect, because the outcome
+ // of each test strongly depends on which skins/languages provide
+ // a given basename.
+ "install/skins/default/colors.xml",
+ "install/skins/steam/colors.xml",
+ "user/skins/default/colors.xml",
+ "user/skins/steam/colors.xml",
+
+ "install/skins/default/xui/en/strings.xml",
+ "install/skins/default/xui/fr/strings.xml",
+ "install/skins/steam/xui/en/strings.xml",
+ "install/skins/steam/xui/fr/strings.xml",
+ "user/skins/default/xui/en/strings.xml",
+ "user/skins/default/xui/fr/strings.xml",
+ "user/skins/steam/xui/en/strings.xml",
+ "user/skins/steam/xui/fr/strings.xml",
+
+ "install/skins/default/xui/en/floater.xml",
+ "install/skins/default/xui/fr/floater.xml",
+ "user/skins/default/xui/fr/floater.xml",
+
+ "install/skins/default/xui/en/newfile.xml",
+ "install/skins/default/xui/fr/newfile.xml",
+ "user/skins/default/xui/en/newfile.xml",
+
+ "install/skins/default/html/en-us/welcome.html",
+ "install/skins/default/html/fr/welcome.html",
+
+ "install/skins/default/textures/only_default.jpeg",
+ "install/skins/steam/textures/only_steam.jpeg",
+ "user/skins/default/textures/only_user_default.jpeg",
+ "user/skins/steam/textures/only_user_steam.jpeg",
+
+ "install/skins/default/future/somefile.txt"
+ };
+ BOOST_FOREACH(const char* path, preload)
+ {
+ buildFilesystem(path);
+ }
+ }
+
+ virtual ~LLDir_Dummy() {}
+
+ virtual void initAppDirs(const std::string& app_name, const std::string& app_read_only_data_dir)
+ {
+ // Implement this when we write a test that needs it
+ }
+
+ virtual std::string getCurPath()
+ {
+ // Implement this when we write a test that needs it
+ return "";
+ }
+
+ virtual U32 countFilesInDir(const std::string& dirname, const std::string& mask)
+ {
+ // Implement this when we write a test that needs it
+ return 0;
+ }
+
+ virtual bool fileExists(const std::string& pathname) const
+ {
+ // Record fileExists() calls so we can check whether caching is
+ // working right. Certain LLDir calls should be able to make decisions
+ // without calling fileExists() again, having already checked existence.
+ mChecked.insert(pathname);
+ // For our simple flat set of strings, see whether the identical
+ // pathname exists in our set.
+ return (mFilesystem.find(pathname) != mFilesystem.end());
+ }
+
+ virtual std::string getLLPluginLauncher()
+ {
+ // Implement this when we write a test that needs it
+ return "";
+ }
+
+ virtual std::string getLLPluginFilename(std::string base_name)
+ {
+ // Implement this when we write a test that needs it
+ return "";
+ }
+
+ /*----------------------------- Dummy data -----------------------------*/
+ void clearFilesystem() { mFilesystem.clear(); }
+ void buildFilesystem(const std::string& path)
+ {
+ // Split the pathname on slashes, ignoring leading, trailing, doubles
+ StringVec components;
+ LLStringUtil::getTokens(path, components, "/");
+ // Ensure we have an entry representing every level of this path
+ std::string partial;
+ BOOST_FOREACH(std::string component, components)
+ {
+ append(partial, component);
+ mFilesystem.insert(partial);
+ }
+ }
+
+ void clear_checked() { mChecked.clear(); }
+ void ensure_checked(const std::string& pathname) const
+ {
+ tut::ensure(STRINGIZE(pathname << " was not checked but should have been"),
+ mChecked.find(pathname) != mChecked.end());
+ }
+ void ensure_not_checked(const std::string& pathname) const
+ {
+ tut::ensure(STRINGIZE(pathname << " was checked but should not have been"),
+ mChecked.find(pathname) == mChecked.end());
+ }
+
+ std::set<std::string> mFilesystem;
+ mutable std::set<std::string> mChecked;
+};
namespace tut
{
@@ -419,5 +575,193 @@ namespace tut
LLFile::rmdir(dir1);
LLFile::rmdir(dir2);
}
-}
+ template<> template<>
+ void LLDirTest_object_t::test<6>()
+ {
+ set_test_name("findSkinnedFilenames()");
+ LLDir_Dummy lldir;
+ /*------------------------ "default", "en" -------------------------*/
+ // Setting "default" means we shouldn't consider any "*/skins/steam"
+ // directories; setting "en" means we shouldn't consider any "xui/fr"
+ // directories.
+ lldir.setSkinFolder("default", "en");
+ ensure_equals(lldir.getSkinFolder(), "default");
+ ensure_equals(lldir.getLanguage(), "en");
+
+ // top-level directory of a skin isn't localized
+ ensure_equals(lldir.findSkinnedFilenames(LLDir::SKINBASE, "colors.xml", LLDir::ALL_SKINS),
+ vec(list_of("install/skins/default/colors.xml")
+ ("user/skins/default/colors.xml")));
+ // We should not have needed to check for skins/default/en. We should
+ // just "know" that SKINBASE is not localized.
+ lldir.ensure_not_checked("install/skins/default/en");
+
+ ensure_equals(lldir.findSkinnedFilenames(LLDir::TEXTURES, "only_default.jpeg"),
+ vec(list_of("install/skins/default/textures/only_default.jpeg")));
+ // Nor should we have needed to check skins/default/textures/en
+ // because textures is known not to be localized.
+ lldir.ensure_not_checked("install/skins/default/textures/en");
+
+ StringVec expected(vec(list_of("install/skins/default/xui/en/strings.xml")
+ ("user/skins/default/xui/en/strings.xml")));
+ ensure_equals(lldir.findSkinnedFilenames(LLDir::XUI, "strings.xml", LLDir::ALL_SKINS),
+ expected);
+ // The first time, we had to probe to find out whether xui was localized.
+ lldir.ensure_checked("install/skins/default/xui/en");
+ lldir.clear_checked();
+ // Now make the same call again -- should return same result --
+ ensure_equals(lldir.findSkinnedFilenames(LLDir::XUI, "strings.xml", LLDir::ALL_SKINS),
+ expected);
+ // but this time it should remember that xui is localized.
+ lldir.ensure_not_checked("install/skins/default/xui/en");
+
+ // localized subdir with "en-us" instead of "en"
+ ensure_equals(lldir.findSkinnedFilenames("html", "welcome.html"),
+ vec(list_of("install/skins/default/html/en-us/welcome.html")));
+ lldir.ensure_checked("install/skins/default/html/en");
+ lldir.ensure_checked("install/skins/default/html/en-us");
+ lldir.clear_checked();
+ ensure_equals(lldir.findSkinnedFilenames("html", "welcome.html"),
+ vec(list_of("install/skins/default/html/en-us/welcome.html")));
+ lldir.ensure_not_checked("install/skins/default/html/en");
+ lldir.ensure_not_checked("install/skins/default/html/en-us");
+
+ ensure_equals(lldir.findSkinnedFilenames("future", "somefile.txt"),
+ vec(list_of("install/skins/default/future/somefile.txt")));
+ // Test probing for an unrecognized unlocalized future subdir.
+ lldir.ensure_checked("install/skins/default/future/en");
+ lldir.clear_checked();
+ ensure_equals(lldir.findSkinnedFilenames("future", "somefile.txt"),
+ vec(list_of("install/skins/default/future/somefile.txt")));
+ // Second time it should remember that future is unlocalized.
+ lldir.ensure_not_checked("install/skins/default/future/en");
+
+ // When language is set to "en", requesting an html file pulls up the
+ // "en-us" version -- not because it magically matches those strings,
+ // but because there's no "en" localization and it falls back on the
+ // default "en-us"! Note that it would probably still be better to
+ // make the default localization be "en" and allow "en-gb" (or
+ // whatever) localizations, which would work much more the way you'd
+ // expect.
+ ensure_equals(lldir.findSkinnedFilenames("html", "welcome.html"),
+ vec(list_of("install/skins/default/html/en-us/welcome.html")));
+
+ /*------------------------ "default", "fr" -------------------------*/
+ // We start being able to distinguish localized subdirs from
+ // unlocalized when we ask for a non-English language.
+ lldir.setSkinFolder("default", "fr");
+ ensure_equals(lldir.getLanguage(), "fr");
+
+ // pass merge=true to request this filename in all relevant skins
+ ensure_equals(lldir.findSkinnedFilenames(LLDir::XUI, "strings.xml", LLDir::ALL_SKINS),
+ vec(list_of
+ ("install/skins/default/xui/en/strings.xml")
+ ("install/skins/default/xui/fr/strings.xml")
+ ("user/skins/default/xui/en/strings.xml")
+ ("user/skins/default/xui/fr/strings.xml")));
+
+ // pass (or default) merge=false to request only most specific skin
+ ensure_equals(lldir.findSkinnedFilenames(LLDir::XUI, "strings.xml"),
+ vec(list_of
+ ("user/skins/default/xui/en/strings.xml")
+ ("user/skins/default/xui/fr/strings.xml")));
+
+ // Our dummy floater.xml has a user localization (for "fr") but no
+ // English override. This is a case in which CURRENT_SKIN nonetheless
+ // returns paths from two different skins.
+ ensure_equals(lldir.findSkinnedFilenames(LLDir::XUI, "floater.xml"),
+ vec(list_of
+ ("install/skins/default/xui/en/floater.xml")
+ ("user/skins/default/xui/fr/floater.xml")));
+
+ // Our dummy newfile.xml has an English override but no user
+ // localization. This is another case in which CURRENT_SKIN
+ // nonetheless returns paths from two different skins.
+ ensure_equals(lldir.findSkinnedFilenames(LLDir::XUI, "newfile.xml"),
+ vec(list_of
+ ("user/skins/default/xui/en/newfile.xml")
+ ("install/skins/default/xui/fr/newfile.xml")));
+
+ ensure_equals(lldir.findSkinnedFilenames("html", "welcome.html"),
+ vec(list_of
+ ("install/skins/default/html/en-us/welcome.html")
+ ("install/skins/default/html/fr/welcome.html")));
+
+ /*------------------------ "default", "zh" -------------------------*/
+ lldir.setSkinFolder("default", "zh");
+ // Because strings.xml has only a "fr" override but no "zh" override
+ // in any skin, the most localized version we can find is "en".
+ ensure_equals(lldir.findSkinnedFilenames(LLDir::XUI, "strings.xml"),
+ vec(list_of("user/skins/default/xui/en/strings.xml")));
+
+ /*------------------------- "steam", "en" --------------------------*/
+ lldir.setSkinFolder("steam", "en");
+
+ ensure_equals(lldir.findSkinnedFilenames(LLDir::SKINBASE, "colors.xml", LLDir::ALL_SKINS),
+ vec(list_of
+ ("install/skins/default/colors.xml")
+ ("install/skins/steam/colors.xml")
+ ("user/skins/default/colors.xml")
+ ("user/skins/steam/colors.xml")));
+
+ ensure_equals(lldir.findSkinnedFilenames(LLDir::TEXTURES, "only_default.jpeg"),
+ vec(list_of("install/skins/default/textures/only_default.jpeg")));
+
+ ensure_equals(lldir.findSkinnedFilenames(LLDir::TEXTURES, "only_steam.jpeg"),
+ vec(list_of("install/skins/steam/textures/only_steam.jpeg")));
+
+ ensure_equals(lldir.findSkinnedFilenames(LLDir::TEXTURES, "only_user_default.jpeg"),
+ vec(list_of("user/skins/default/textures/only_user_default.jpeg")));
+
+ ensure_equals(lldir.findSkinnedFilenames(LLDir::TEXTURES, "only_user_steam.jpeg"),
+ vec(list_of("user/skins/steam/textures/only_user_steam.jpeg")));
+
+ // CURRENT_SKIN
+ ensure_equals(lldir.findSkinnedFilenames(LLDir::XUI, "strings.xml"),
+ vec(list_of("user/skins/steam/xui/en/strings.xml")));
+
+ // pass constraint=ALL_SKINS to request this filename in all relevant skins
+ ensure_equals(lldir.findSkinnedFilenames(LLDir::XUI, "strings.xml", LLDir::ALL_SKINS),
+ vec(list_of
+ ("install/skins/default/xui/en/strings.xml")
+ ("install/skins/steam/xui/en/strings.xml")
+ ("user/skins/default/xui/en/strings.xml")
+ ("user/skins/steam/xui/en/strings.xml")));
+
+ /*------------------------- "steam", "fr" --------------------------*/
+ lldir.setSkinFolder("steam", "fr");
+
+ // pass CURRENT_SKIN to request only the most specialized files
+ ensure_equals(lldir.findSkinnedFilenames(LLDir::XUI, "strings.xml"),
+ vec(list_of
+ ("user/skins/steam/xui/en/strings.xml")
+ ("user/skins/steam/xui/fr/strings.xml")));
+
+ // pass ALL_SKINS to request this filename in all relevant skins
+ ensure_equals(lldir.findSkinnedFilenames(LLDir::XUI, "strings.xml", LLDir::ALL_SKINS),
+ vec(list_of
+ ("install/skins/default/xui/en/strings.xml")
+ ("install/skins/default/xui/fr/strings.xml")
+ ("install/skins/steam/xui/en/strings.xml")
+ ("install/skins/steam/xui/fr/strings.xml")
+ ("user/skins/default/xui/en/strings.xml")
+ ("user/skins/default/xui/fr/strings.xml")
+ ("user/skins/steam/xui/en/strings.xml")
+ ("user/skins/steam/xui/fr/strings.xml")));
+ }
+
+ template<> template<>
+ void LLDirTest_object_t::test<7>()
+ {
+ set_test_name("add()");
+ LLDir_Dummy lldir;
+ ensure_equals("both empty", lldir.add("", ""), "");
+ ensure_equals("path empty", lldir.add("", "b"), "b");
+ ensure_equals("name empty", lldir.add("a", ""), "a");
+ ensure_equals("both simple", lldir.add("a", "b"), "a/b");
+ ensure_equals("name leading slash", lldir.add("a", "/b"), "a/b");
+ ensure_equals("path trailing slash", lldir.add("a/", "b"), "a/b");
+ ensure_equals("both bring slashes", lldir.add("a/", "/b"), "a/b");
+ }
+}
diff --git a/indra/llvfs/tests/lldiriterator_test.cpp b/indra/llvfs/tests/lldiriterator_test.cpp
index 505d86faa7..505d86faa7 100644..100755
--- a/indra/llvfs/tests/lldiriterator_test.cpp
+++ b/indra/llvfs/tests/lldiriterator_test.cpp
diff --git a/indra/llwindow/CMakeLists.txt b/indra/llwindow/CMakeLists.txt
index 341bddfffd..aec6d7af4a 100644..100755
--- a/indra/llwindow/CMakeLists.txt
+++ b/indra/llwindow/CMakeLists.txt
@@ -32,12 +32,17 @@ include_directories(
${LLXML_INCLUDE_DIRS}
${DIRECTX_INCLUDE_DIR}
)
+include_directories(SYSTEM
+ ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+ ${LLXML_SYSTEM_INCLUDE_DIRS}
+ )
set(llwindow_SOURCE_FILES
llkeyboard.cpp
llkeyboardheadless.cpp
llwindowheadless.cpp
llwindowcallbacks.cpp
+ llwindow.cpp
)
set(llwindow_HEADER_FILES
@@ -50,7 +55,6 @@ set(llwindow_HEADER_FILES
)
set(viewer_SOURCE_FILES
- llwindow.cpp
llmousehandler.cpp
)
@@ -62,24 +66,57 @@ set(viewer_HEADER_FILES
# Libraries on which this library depends, needed for Linux builds
# Sort by high-level to low-level
-if (LINUX AND VIEWER)
+if (LINUX)
set(llwindow_LINK_LIBRARIES
+ ${LLCOMMON_LIBRARIES}
+ ${LLIMAGE_LIBRARIES}
+ ${LLMATH_LIBRARIES}
+ ${LLRENDER_LIBRARIES}
+ ${LLVFS_LIBRARIES}
+ ${LLWINDOW_LIBRARIES}
+ ${LLXML_LIBRARIES}
${UI_LIBRARIES} # for GTK
${SDL_LIBRARY}
fontconfig # For FCInit and other FC* functions.
)
-endif (LINUX AND VIEWER)
+
+ list(APPEND viewer_SOURCE_FILES
+ llkeyboardsdl.cpp
+ llwindowsdl.cpp
+ )
+ list(APPEND viewer_HEADER_FILES
+ llkeyboardsdl.h
+ llwindowsdl.h
+ )
+
+ if (BUILD_HEADLESS)
+ set(llwindowheadless_LINK_LIBRARIES
+ ${LLCOMMON_LIBRARIES}
+ ${LLIMAGE_LIBRARIES}
+ ${LLMATH_LIBRARIES}
+ ${LLRENDER_HEADLESS_LIBRARIES}
+ ${LLVFS_LIBRARIES}
+ ${LLWINDOW_HEADLESS_LIBRARIES}
+ ${LLXML_LIBRARIES}
+ fontconfig # For FCInit and other FC* functions.
+ )
+ endif (BUILD_HEADLESS)
+
+endif (LINUX)
if (DARWIN)
list(APPEND llwindow_SOURCE_FILES
llkeyboardmacosx.cpp
llwindowmacosx.cpp
llwindowmacosx-objc.mm
+ llopenglview-objc.mm
)
list(APPEND llwindow_HEADER_FILES
llkeyboardmacosx.h
llwindowmacosx.h
llwindowmacosx-objc.h
+ llopenglview-objc.h
+ llappdelegate-objc.h
)
# We use a bunch of deprecated system APIs.
@@ -91,16 +128,6 @@ if (DARWIN)
)
endif (DARWIN)
-if (LINUX AND VIEWER)
- list(APPEND viewer_SOURCE_FILES
- llkeyboardsdl.cpp
- llwindowsdl.cpp
- )
- list(APPEND viewer_HEADER_FILES
- llkeyboardsdl.h
- llwindowsdl.h
- )
-endif (LINUX AND VIEWER)
if (WINDOWS)
list(APPEND llwindow_SOURCE_FILES
@@ -133,40 +160,41 @@ endif (SOLARIS)
set_source_files_properties(${llwindow_HEADER_FILES}
PROPERTIES HEADER_FILE_ONLY TRUE)
-if (SERVER AND NOT WINDOWS AND NOT DARWIN)
- set(server_SOURCE_FILES
+if (BUILD_HEADLESS)
+ set(llwindowheadless_SOURCE_FILES
llwindowmesaheadless.cpp
+ llmousehandler.cpp
)
- set(server_HEADER_FILES
+ set(llwindowheadless_HEADER_FILES
llwindowmesaheadless.h
- )
- copy_server_sources(
- llwindow
- )
-
-
- set_source_files_properties(
- ${server_SOURCE_FILES}
- PROPERTIES
- COMPILE_FLAGS "-DLL_MESA=1 -DLL_MESA_HEADLESS=1"
+ llmousehandler.h
)
add_library (llwindowheadless
${llwindow_SOURCE_FILES}
- ${server_SOURCE_FILES}
+ ${llwindowheadless_SOURCE_FILES}
)
- target_link_libraries (llwindowheadless ${llwindow_LINK_LIBRARIES})
-endif (SERVER AND NOT WINDOWS AND NOT DARWIN)
+ set_property(TARGET llwindowheadless
+ PROPERTY COMPILE_DEFINITIONS LL_MESA=1 LL_MESA_HEADLESS=1
+ )
+ target_link_libraries (llwindowheadless ${llwindowheadless_LINK_LIBRARIES} dl)
+endif (BUILD_HEADLESS)
if (llwindow_HEADER_FILES)
list(APPEND llwindow_SOURCE_FILES ${llwindow_HEADER_FILES})
endif (llwindow_HEADER_FILES)
+
list(APPEND viewer_SOURCE_FILES ${viewer_HEADER_FILES})
-if (VIEWER)
add_library (llwindow
${llwindow_SOURCE_FILES}
${viewer_SOURCE_FILES}
)
+
+if (SDL_FOUND)
+ set_property(TARGET llwindow
+ PROPERTY COMPILE_DEFINITIONS LL_SDL=1
+ )
+endif (SDL_FOUND)
+
target_link_libraries (llwindow ${llwindow_LINK_LIBRARIES})
-endif (VIEWER)
diff --git a/indra/llwindow/GL/glh_extensions.h b/indra/llwindow/GL/glh_extensions.h
index d89d85930b..554cb1731f 100644..100755
--- a/indra/llwindow/GL/glh_extensions.h
+++ b/indra/llwindow/GL/glh_extensions.h
@@ -113,7 +113,7 @@ static const char* EatNonWhiteSpace(const char *str)
int glh_init_extensions(const char *origReqExts)
{
// Length of requested extensions string
- unsigned reqExtsLen;
+ //unsigned reqExtsLen;
char *reqExts;
// Ptr for individual extensions within reqExts
char *reqExt;
@@ -155,8 +155,8 @@ int glh_init_extensions(const char *origReqExts)
return TRUE;
}
reqExts = strdup(origReqExts);
- reqExtsLen = (S32)strlen(reqExts);
/*
+ reqExtsLen = (S32)strlen(reqExts);
if (NULL == gGLHExts.mUnsupportedExts)
{
gGLHExts.mUnsupportedExts = (char*)malloc(reqExtsLen + 1);
diff --git a/indra/llwindow/GL/glh_genext.h b/indra/llwindow/GL/glh_genext.h
index cd5d1604a8..cd5d1604a8 100644..100755
--- a/indra/llwindow/GL/glh_genext.h
+++ b/indra/llwindow/GL/glh_genext.h
diff --git a/indra/llwindow/llappdelegate-objc.h b/indra/llwindow/llappdelegate-objc.h
new file mode 100644
index 0000000000..faa5d3abb7
--- /dev/null
+++ b/indra/llwindow/llappdelegate-objc.h
@@ -0,0 +1,48 @@
+/**
+ * @file llappdelegate-objc.h
+ * @brief Class interface for the Mac version's application delegate.
+ *
+ * $LicenseInfo:firstyear=2000&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#import <Cocoa/Cocoa.h>
+#import "llopenglview-objc.h"
+
+@interface LLAppDelegate : NSObject <NSApplicationDelegate> {
+ LLNSWindow *window;
+ NSWindow *inputWindow;
+ LLNonInlineTextView *inputView;
+ NSTimer *frameTimer;
+ NSString *currentInputLanguage;
+}
+
+@property (assign) IBOutlet LLNSWindow *window;
+@property (assign) IBOutlet NSWindow *inputWindow;
+@property (assign) IBOutlet LLNonInlineTextView *inputView;
+
+@property (retain) NSString *currentInputLanguage;
+
+- (void) mainLoop;
+- (void) showInputWindow:(bool)show withEvent:(NSEvent*)textEvent;
+- (void) languageUpdated;
+- (bool) romanScript;
+@end
diff --git a/indra/llwindow/lldragdropwin32.cpp b/indra/llwindow/lldragdropwin32.cpp
index 15acddd987..15acddd987 100644..100755
--- a/indra/llwindow/lldragdropwin32.cpp
+++ b/indra/llwindow/lldragdropwin32.cpp
diff --git a/indra/llwindow/lldragdropwin32.h b/indra/llwindow/lldragdropwin32.h
index 929e7f9e37..a6824f3e90 100644..100755
--- a/indra/llwindow/lldragdropwin32.h
+++ b/indra/llwindow/lldragdropwin32.h
@@ -57,7 +57,7 @@ class LLDragDropWin32
#include <windows.h>
#include <ole2.h>
-// imposter class that does nothing
+// impostor class that does nothing
class LLDragDropWin32
{
public:
diff --git a/indra/llwindow/lldxhardware.cpp b/indra/llwindow/lldxhardware.cpp
index 3579b5d42f..3579b5d42f 100644..100755
--- a/indra/llwindow/lldxhardware.cpp
+++ b/indra/llwindow/lldxhardware.cpp
diff --git a/indra/llwindow/lldxhardware.h b/indra/llwindow/lldxhardware.h
index 61a32bf0fb..61a32bf0fb 100644..100755
--- a/indra/llwindow/lldxhardware.h
+++ b/indra/llwindow/lldxhardware.h
diff --git a/indra/llwindow/llkeyboard.cpp b/indra/llwindow/llkeyboard.cpp
index 53cecf9d4a..8b356ba138 100644..100755
--- a/indra/llwindow/llkeyboard.cpp
+++ b/indra/llwindow/llkeyboard.cpp
@@ -46,7 +46,7 @@ LLKeyStringTranslatorFunc* LLKeyboard::mStringTranslator = NULL; // Used for l10
// Class Implementation
//
-LLKeyboard::LLKeyboard() : mCallbacks(NULL), mNumpadDistinct(ND_NUMLOCK_OFF)
+LLKeyboard::LLKeyboard() : mCallbacks(NULL)
{
S32 i;
diff --git a/indra/llwindow/llkeyboard.h b/indra/llwindow/llkeyboard.h
index ba472cfde5..92449c123f 100644..100755
--- a/indra/llwindow/llkeyboard.h
+++ b/indra/llwindow/llkeyboard.h
@@ -63,14 +63,6 @@ class LLWindowCallbacks;
class LLKeyboard
{
public:
- typedef enum e_numpad_distinct
- {
- ND_NEVER,
- ND_NUMLOCK_OFF,
- ND_NUMLOCK_ON
- } ENumpadDistinct;
-
-public:
LLKeyboard();
virtual ~LLKeyboard();
@@ -90,6 +82,11 @@ public:
virtual BOOL handleKeyUp(const U16 key, MASK mask) = 0;
virtual BOOL handleKeyDown(const U16 key, MASK mask) = 0;
+
+#ifdef LL_DARWIN
+ // We only actually use this for OS X.
+ virtual void handleModifier(MASK mask) = 0;
+#endif // LL_DARWIN
// Asynchronously poll the control, alt, and shift keys and set the
// appropriate internal key masks.
@@ -107,8 +104,6 @@ public:
static BOOL keyFromString(const std::string& str, KEY *key); // False on failure
static std::string stringFromKey(KEY key);
static std::string stringFromAccelerator( MASK accel_mask, KEY key );
- e_numpad_distinct getNumpadDistinct() { return mNumpadDistinct; }
- void setNumpadDistinct(e_numpad_distinct val) { mNumpadDistinct = val; }
void setCallbacks(LLWindowCallbacks *cbs) { mCallbacks = cbs; }
F32 getKeyElapsedTime( KEY key ); // Returns time in seconds since key was pressed.
@@ -135,8 +130,6 @@ protected:
static LLKeyStringTranslatorFunc* mStringTranslator; // Used for l10n + PC/Mac/Linux accelerator labeling
- e_numpad_distinct mNumpadDistinct;
-
EKeyboardInsertMode mInsertMode;
static std::map<KEY,std::string> sKeysToNames;
diff --git a/indra/llwindow/llkeyboardheadless.cpp b/indra/llwindow/llkeyboardheadless.cpp
index c87617c9ff..a1b6b294e0 100644..100755
--- a/indra/llwindow/llkeyboardheadless.cpp
+++ b/indra/llwindow/llkeyboardheadless.cpp
@@ -45,6 +45,13 @@ BOOL LLKeyboardHeadless::handleKeyUp(const U16 key, const U32 mask)
MASK LLKeyboardHeadless::currentMask(BOOL for_mouse_event)
{ return MASK_NONE; }
+#ifdef LL_DARWIN
+void LLKeyboardHeadless::handleModifier(MASK mask)
+{
+
+}
+#endif
+
void LLKeyboardHeadless::scanKeyboard()
{
for (S32 key = 0; key < KEY_COUNT; key++)
diff --git a/indra/llwindow/llkeyboardheadless.h b/indra/llwindow/llkeyboardheadless.h
index 4e666f8ce8..8ed28ace90 100644..100755
--- a/indra/llwindow/llkeyboardheadless.h
+++ b/indra/llwindow/llkeyboardheadless.h
@@ -40,6 +40,9 @@ public:
/*virtual*/ void resetMaskKeys();
/*virtual*/ MASK currentMask(BOOL for_mouse_event);
/*virtual*/ void scanKeyboard();
+#ifdef LL_DARWIN
+ /*virtual*/ void handleModifier(MASK mask);
+#endif
};
#endif
diff --git a/indra/llwindow/llkeyboardmacosx.cpp b/indra/llwindow/llkeyboardmacosx.cpp
index ecc2631669..85bb7b9aeb 100644..100755
--- a/indra/llwindow/llkeyboardmacosx.cpp
+++ b/indra/llwindow/llkeyboardmacosx.cpp
@@ -30,7 +30,7 @@
#include "llkeyboardmacosx.h"
#include "llwindowcallbacks.h"
-#include <Carbon/Carbon.h>
+#include "llwindowmacosx-objc.h"
LLKeyboardMacOSX::LLKeyboardMacOSX()
{
@@ -162,23 +162,25 @@ LLKeyboardMacOSX::LLKeyboardMacOSX()
void LLKeyboardMacOSX::resetMaskKeys()
{
- U32 mask = GetCurrentEventKeyModifiers();
+ U32 mask = getModifiers();
// MBW -- XXX -- This mirrors the operation of the Windows version of resetMaskKeys().
// It looks a bit suspicious, as it won't correct for keys that have been released.
// Is this the way it's supposed to work?
+
+ // We apply the modifier masks directly within getModifiers. So check to see which masks we've applied.
- if(mask & shiftKey)
+ if(mask & MAC_SHIFT_KEY)
{
mKeyLevel[KEY_SHIFT] = TRUE;
}
- if(mask & (controlKey))
+ if(mask & MAC_CTRL_KEY)
{
mKeyLevel[KEY_CONTROL] = TRUE;
}
- if(mask & optionKey)
+ if(mask & MAC_ALT_KEY)
{
mKeyLevel[KEY_ALT] = TRUE;
}
@@ -196,22 +198,27 @@ static BOOL translateKeyMac(const U16 key, const U32 mask, KEY &outKey, U32 &out
}
*/
+void LLKeyboardMacOSX::handleModifier(MASK mask)
+{
+ updateModifiers(mask);
+}
+
MASK LLKeyboardMacOSX::updateModifiers(const U32 mask)
{
// translate the mask
MASK out_mask = 0;
- if(mask & shiftKey)
+ if(mask & MAC_SHIFT_KEY)
{
out_mask |= MASK_SHIFT;
}
- if(mask & (controlKey | cmdKey))
+ if(mask & (MAC_CTRL_KEY | MAC_CMD_KEY))
{
out_mask |= MASK_CONTROL;
}
- if(mask & optionKey)
+ if(mask & MAC_ALT_KEY)
{
out_mask |= MASK_ALT;
}
@@ -231,7 +238,7 @@ BOOL LLKeyboardMacOSX::handleKeyDown(const U16 key, const U32 mask)
{
handled = handleTranslatedKeyDown(translated_key, translated_mask);
}
-
+
return handled;
}
@@ -255,18 +262,18 @@ BOOL LLKeyboardMacOSX::handleKeyUp(const U16 key, const U32 mask)
MASK LLKeyboardMacOSX::currentMask(BOOL for_mouse_event)
{
MASK result = MASK_NONE;
- U32 mask = GetCurrentEventKeyModifiers();
+ U32 mask = getModifiers();
- if (mask & shiftKey) result |= MASK_SHIFT;
- if (mask & controlKey) result |= MASK_CONTROL;
- if (mask & optionKey) result |= MASK_ALT;
+ if (mask & MAC_SHIFT_KEY) result |= MASK_SHIFT;
+ if (mask & MAC_CTRL_KEY) result |= MASK_CONTROL;
+ if (mask & MAC_ALT_KEY) result |= MASK_ALT;
// For keyboard events, consider Command equivalent to Control
if (!for_mouse_event)
{
- if (mask & cmdKey) result |= MASK_CONTROL;
+ if (mask & MAC_CMD_KEY) result |= MASK_CONTROL;
}
-
+
return result;
}
@@ -299,28 +306,11 @@ void LLKeyboardMacOSX::scanKeyboard()
BOOL LLKeyboardMacOSX::translateNumpadKey( const U16 os_key, KEY *translated_key )
{
- if(mNumpadDistinct == ND_NUMLOCK_ON)
- {
- std::map<U16, KEY>::iterator iter= mTranslateNumpadMap.find(os_key);
- if(iter != mTranslateNumpadMap.end())
- {
- *translated_key = iter->second;
- return TRUE;
- }
- }
return translateKey(os_key, translated_key);
}
U16 LLKeyboardMacOSX::inverseTranslateNumpadKey(const KEY translated_key)
{
- if(mNumpadDistinct == ND_NUMLOCK_ON)
- {
- std::map<KEY, U16>::iterator iter= mInvTranslateNumpadMap.find(translated_key);
- if(iter != mInvTranslateNumpadMap.end())
- {
- return iter->second;
- }
- }
return inverseTranslateKey(translated_key);
}
diff --git a/indra/llwindow/llkeyboardmacosx.h b/indra/llwindow/llkeyboardmacosx.h
index f09ff720ce..f9d014ab70 100644..100755
--- a/indra/llwindow/llkeyboardmacosx.h
+++ b/indra/llwindow/llkeyboardmacosx.h
@@ -29,6 +29,15 @@
#include "llkeyboard.h"
+// These more or less mirror their equivalents in NSEvent.h.
+enum EMacEventKeys {
+ MAC_SHIFT_KEY = 1 << 17,
+ MAC_CTRL_KEY = 1 << 18,
+ MAC_ALT_KEY = 1 << 19,
+ MAC_CMD_KEY = 1 << 20,
+ MAC_FN_KEY = 1 << 23
+};
+
class LLKeyboardMacOSX : public LLKeyboard
{
public:
@@ -40,6 +49,7 @@ public:
/*virtual*/ void resetMaskKeys();
/*virtual*/ MASK currentMask(BOOL for_mouse_event);
/*virtual*/ void scanKeyboard();
+ /*virtual*/ void handleModifier(MASK mask);
protected:
MASK updateModifiers(const U32 mask);
diff --git a/indra/llwindow/llkeyboardsdl.cpp b/indra/llwindow/llkeyboardsdl.cpp
index 4bb9603368..7c9aa1d340 100644..100755
--- a/indra/llwindow/llkeyboardsdl.cpp
+++ b/indra/llwindow/llkeyboardsdl.cpp
@@ -312,29 +312,11 @@ void LLKeyboardSDL::scanKeyboard()
BOOL LLKeyboardSDL::translateNumpadKey( const U16 os_key, KEY *translated_key)
{
- if(mNumpadDistinct == ND_NUMLOCK_ON)
- {
- std::map<U16, KEY>::iterator iter= mTranslateNumpadMap.find(os_key);
- if(iter != mTranslateNumpadMap.end())
- {
- *translated_key = iter->second;
- return TRUE;
- }
- }
- BOOL success = translateKey(os_key, translated_key);
- return success;
+ return translateKey(os_key, translated_key);
}
U16 LLKeyboardSDL::inverseTranslateNumpadKey(const KEY translated_key)
{
- if(mNumpadDistinct == ND_NUMLOCK_ON)
- {
- std::map<KEY, U16>::iterator iter= mInvTranslateNumpadMap.find(translated_key);
- if(iter != mInvTranslateNumpadMap.end())
- {
- return iter->second;
- }
- }
return inverseTranslateKey(translated_key);
}
diff --git a/indra/llwindow/llkeyboardsdl.h b/indra/llwindow/llkeyboardsdl.h
index 02a71425f1..02a71425f1 100644..100755
--- a/indra/llwindow/llkeyboardsdl.h
+++ b/indra/llwindow/llkeyboardsdl.h
diff --git a/indra/llwindow/llkeyboardwin32.cpp b/indra/llwindow/llkeyboardwin32.cpp
index df78816bd6..be3fe5deb0 100644..100755
--- a/indra/llwindow/llkeyboardwin32.cpp
+++ b/indra/llwindow/llkeyboardwin32.cpp
@@ -299,69 +299,13 @@ void LLKeyboardWin32::scanKeyboard()
BOOL LLKeyboardWin32::translateExtendedKey(const U16 os_key, const MASK mask, KEY *translated_key)
{
- if(mNumpadDistinct == ND_NUMLOCK_ON)
- {
- std::map<U16, KEY>::iterator iter = mTranslateNumpadMap.find(os_key);
- if (iter != mTranslateNumpadMap.end())
- {
- *translated_key = iter->second;
- return TRUE;
- }
- }
-
- BOOL success = translateKey(os_key, translated_key);
- if(mNumpadDistinct != ND_NEVER) {
- if(!success) return success;
- if(mask & MASK_EXTENDED)
- {
- // this is where we'd create new keycodes for extended keys
- // the set of extended keys includes the 'normal' arrow keys and
- // the pgup/dn/insert/home/end/delete cluster above the arrow keys
- // see http://windowssdk.msdn.microsoft.com/en-us/library/ms646280.aspx
-
- // only process the return key if numlock is off
- if(((mNumpadDistinct == ND_NUMLOCK_OFF &&
- !(GetKeyState(VK_NUMLOCK) & 1))
- || mNumpadDistinct == ND_NUMLOCK_ON) &&
- *translated_key == KEY_RETURN) {
- *translated_key = KEY_PAD_RETURN;
- }
- }
- else
- {
- // the non-extended keys, those are in the numpad
- switch (*translated_key)
- {
- case KEY_LEFT:
- *translated_key = KEY_PAD_LEFT; break;
- case KEY_RIGHT:
- *translated_key = KEY_PAD_RIGHT; break;
- case KEY_UP:
- *translated_key = KEY_PAD_UP; break;
- case KEY_DOWN:
- *translated_key = KEY_PAD_DOWN; break;
- case KEY_HOME:
- *translated_key = KEY_PAD_HOME; break;
- case KEY_END:
- *translated_key = KEY_PAD_END; break;
- case KEY_PAGE_UP:
- *translated_key = KEY_PAD_PGUP; break;
- case KEY_PAGE_DOWN:
- *translated_key = KEY_PAD_PGDN; break;
- case KEY_INSERT:
- *translated_key = KEY_PAD_INS; break;
- case KEY_DELETE:
- *translated_key = KEY_PAD_DEL; break;
- }
- }
- }
- return success;
+ return translateKey(os_key, translated_key);
}
U16 LLKeyboardWin32::inverseTranslateExtendedKey(const KEY translated_key)
{
// if numlock is on, then we need to translate KEY_PAD_FOO to the corresponding number pad number
- if((mNumpadDistinct == ND_NUMLOCK_ON) && (GetKeyState(VK_NUMLOCK) & 1))
+ if(GetKeyState(VK_NUMLOCK) & 1)
{
std::map<KEY, U16>::iterator iter = mInvTranslateNumpadMap.find(translated_key);
if (iter != mInvTranslateNumpadMap.end())
diff --git a/indra/llwindow/llkeyboardwin32.h b/indra/llwindow/llkeyboardwin32.h
index b7da450164..b7da450164 100644..100755
--- a/indra/llwindow/llkeyboardwin32.h
+++ b/indra/llwindow/llkeyboardwin32.h
diff --git a/indra/llwindow/llmousehandler.cpp b/indra/llwindow/llmousehandler.cpp
index 8695e92f77..8695e92f77 100644..100755
--- a/indra/llwindow/llmousehandler.cpp
+++ b/indra/llwindow/llmousehandler.cpp
diff --git a/indra/llwindow/llmousehandler.h b/indra/llwindow/llmousehandler.h
index d825a3424c..d825a3424c 100644..100755
--- a/indra/llwindow/llmousehandler.h
+++ b/indra/llwindow/llmousehandler.h
diff --git a/indra/llwindow/llopenglview-objc.h b/indra/llwindow/llopenglview-objc.h
new file mode 100644
index 0000000000..1e0e47cd02
--- /dev/null
+++ b/indra/llwindow/llopenglview-objc.h
@@ -0,0 +1,111 @@
+/**
+ * @file llopenglview-objc.h
+ * @brief Class interfaces for most of the Mac facing window functionality.
+ *
+ * $LicenseInfo:firstyear=2000&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LLOpenGLView_H
+#define LLOpenGLView_H
+
+#import <Cocoa/Cocoa.h>
+#import <IOKit/IOKitLib.h>
+#import <CoreFoundation/CFBase.h>
+#import <CoreFoundation/CFNumber.h>
+#include <string>
+
+@interface LLOpenGLView : NSOpenGLView <NSTextInputClient>
+{
+ std::string mLastDraggedUrl;
+ unsigned int mModifiers;
+ float mMousePos[2];
+ bool mHasMarkedText;
+ unsigned int mMarkedTextLength;
+ bool mMarkedTextAllowed;
+ bool mSimulatedRightClick;
+}
+- (id) initWithSamples:(NSUInteger)samples;
+- (id) initWithSamples:(NSUInteger)samples andVsync:(BOOL)vsync;
+- (id) initWithFrame:(NSRect)frame withSamples:(NSUInteger)samples andVsync:(BOOL)vsync;
+
+- (void)commitCurrentPreedit;
+
+// rebuildContext
+// Destroys and recreates a context with the view's internal format set via setPixelFormat;
+// Use this in event of needing to rebuild a context for whatever reason, without needing to assign a new pixel format.
+- (BOOL) rebuildContext;
+
+// rebuildContextWithFormat
+// Destroys and recreates a context with the specified pixel format.
+- (BOOL) rebuildContextWithFormat:(NSOpenGLPixelFormat *)format;
+
+// These are mostly just for C++ <-> Obj-C interop. We can manipulate the CGLContext from C++ without reprecussions.
+- (CGLContextObj) getCGLContextObj;
+- (CGLPixelFormatObj*)getCGLPixelFormatObj;
+
+- (unsigned long) getVramSize;
+
+- (void) allowMarkedTextInput:(bool)allowed;
+- (void) viewDidEndLiveResize;
+
+@end
+
+@interface LLUserInputWindow : NSPanel
+
+@end
+
+@interface LLNonInlineTextView : NSTextView
+{
+ LLOpenGLView *glview;
+}
+
+- (void) setGLView:(LLOpenGLView*)view;
+
+@end
+
+@interface LLNSWindow : NSWindow
+
+- (NSPoint)convertToScreenFromLocalPoint:(NSPoint)point relativeToView:(NSView *)view;
+- (NSPoint)flipPoint:(NSPoint)aPoint;
+
+@end
+
+@interface NSScreen (PointConversion)
+
+/*
+ Returns the screen where the mouse resides
+ */
++ (NSScreen *)currentScreenForMouseLocation;
+
+/*
+ Allows you to convert a point from global coordinates to the current screen coordinates.
+ */
+- (NSPoint)convertPointToScreenCoordinates:(NSPoint)aPoint;
+
+/*
+ Allows to flip the point coordinates, so y is 0 at the top instead of the bottom. x remains the same
+ */
+- (NSPoint)flipPoint:(NSPoint)aPoint;
+
+@end
+
+#endif
diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm
new file mode 100644
index 0000000000..7415c9d8dc
--- /dev/null
+++ b/indra/llwindow/llopenglview-objc.mm
@@ -0,0 +1,692 @@
+/**
+ * @file llopenglview-objc.mm
+ * @brief Class implementation for most of the Mac facing window functionality.
+ *
+ * $LicenseInfo:firstyear=2000&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#import "llopenglview-objc.h"
+#include "llwindowmacosx-objc.h"
+#import "llappdelegate-objc.h"
+
+@implementation NSScreen (PointConversion)
+
++ (NSScreen *)currentScreenForMouseLocation
+{
+ NSPoint mouseLocation = [NSEvent mouseLocation];
+
+ NSEnumerator *screenEnumerator = [[NSScreen screens] objectEnumerator];
+ NSScreen *screen;
+ while ((screen = [screenEnumerator nextObject]) && !NSMouseInRect(mouseLocation, screen.frame, NO))
+ ;
+
+ return screen;
+}
+
+- (NSPoint)convertPointToScreenCoordinates:(NSPoint)aPoint
+{
+ float normalizedX = fabs(fabs(self.frame.origin.x) - fabs(aPoint.x));
+ float normalizedY = aPoint.y - self.frame.origin.y;
+
+ return NSMakePoint(normalizedX, normalizedY);
+}
+
+- (NSPoint)flipPoint:(NSPoint)aPoint
+{
+ return NSMakePoint(aPoint.x, self.frame.size.height - aPoint.y);
+}
+
+@end
+
+attributedStringInfo getSegments(NSAttributedString *str)
+{
+ attributedStringInfo segments;
+ segment_lengths seg_lengths;
+ segment_standouts seg_standouts;
+ NSRange effectiveRange;
+ NSRange limitRange = NSMakeRange(0, [str length]);
+
+ while (limitRange.length > 0) {
+ NSNumber *attr = [str attribute:NSUnderlineStyleAttributeName atIndex:limitRange.location longestEffectiveRange:&effectiveRange inRange:limitRange];
+ limitRange = NSMakeRange(NSMaxRange(effectiveRange), NSMaxRange(limitRange) - NSMaxRange(effectiveRange));
+
+ if (effectiveRange.length <= 0)
+ {
+ effectiveRange.length = 1;
+ }
+
+ if ([attr integerValue] == 2)
+ {
+ seg_lengths.push_back(effectiveRange.length);
+ seg_standouts.push_back(true);
+ } else
+ {
+ seg_lengths.push_back(effectiveRange.length);
+ seg_standouts.push_back(false);
+ }
+ }
+ segments.seg_lengths = seg_lengths;
+ segments.seg_standouts = seg_standouts;
+ return segments;
+}
+
+@implementation LLOpenGLView
+
+// Force a high quality update after live resizing
+- (void) viewDidEndLiveResize
+{
+ NSSize size = [self frame].size;
+ callResize(size.width, size.height);
+}
+
+- (unsigned long)getVramSize
+{
+ CGLRendererInfoObj info = 0;
+ GLint vram_bytes = 0;
+ int num_renderers = 0;
+ CGLError the_err = CGLQueryRendererInfo (CGDisplayIDToOpenGLDisplayMask(kCGDirectMainDisplay), &info, &num_renderers);
+ if(0 == the_err)
+ {
+ CGLDescribeRenderer (info, 0, kCGLRPTextureMemory, &vram_bytes);
+ CGLDestroyRendererInfo (info);
+ }
+ else
+ {
+ vram_bytes = (256 << 20);
+ }
+
+ return (unsigned long)vram_bytes / 1048576; // We need this in megabytes.
+}
+
+- (void)viewDidMoveToWindow
+{
+ [[NSNotificationCenter defaultCenter] addObserver:self
+ selector:@selector(windowResized:) name:NSWindowDidResizeNotification
+ object:[self window]];
+}
+
+- (void)windowResized:(NSNotification *)notification;
+{
+ //NSSize size = [self frame].size;
+ //callResize(size.width, size.height);
+}
+
+- (void)dealloc
+{
+ [[NSNotificationCenter defaultCenter] removeObserver:self];
+ [super dealloc];
+}
+
+- (id) init
+{
+ return [self initWithFrame:[self bounds] withSamples:2 andVsync:TRUE];
+}
+
+- (id) initWithSamples:(NSUInteger)samples
+{
+ return [self initWithFrame:[self bounds] withSamples:samples andVsync:TRUE];
+}
+
+- (id) initWithSamples:(NSUInteger)samples andVsync:(BOOL)vsync
+{
+ return [self initWithFrame:[self bounds] withSamples:samples andVsync:vsync];
+}
+
+- (id) initWithFrame:(NSRect)frame withSamples:(NSUInteger)samples andVsync:(BOOL)vsync
+{
+ [self registerForDraggedTypes:[NSArray arrayWithObject:NSURLPboardType]];
+ [self initWithFrame:frame];
+
+ // Initialize with a default "safe" pixel format that will work with versions dating back to OS X 10.6.
+ // Any specialized pixel formats, i.e. a core profile pixel format, should be initialized through rebuildContextWithFormat.
+ // 10.7 and 10.8 don't really care if we're defining a profile or not. If we don't explicitly request a core or legacy profile, it'll always assume a legacy profile (for compatibility reasons).
+ NSOpenGLPixelFormatAttribute attrs[] = {
+ NSOpenGLPFANoRecovery,
+ NSOpenGLPFADoubleBuffer,
+ NSOpenGLPFAClosestPolicy,
+ NSOpenGLPFAAccelerated,
+ NSOpenGLPFASampleBuffers, (samples > 0 ? 1 : 0),
+ NSOpenGLPFASamples, samples,
+ NSOpenGLPFAStencilSize, 8,
+ NSOpenGLPFADepthSize, 24,
+ NSOpenGLPFAAlphaSize, 8,
+ NSOpenGLPFAColorSize, 24,
+ 0
+ };
+
+ NSOpenGLPixelFormat *pixelFormat = [[[NSOpenGLPixelFormat alloc] initWithAttributes:attrs] autorelease];
+
+ if (pixelFormat == nil)
+ {
+ NSLog(@"Failed to create pixel format!", nil);
+ return nil;
+ }
+
+ NSOpenGLContext *glContext = [[NSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:nil];
+
+ if (glContext == nil)
+ {
+ NSLog(@"Failed to create OpenGL context!", nil);
+ return nil;
+ }
+
+ [self setPixelFormat:pixelFormat];
+
+ [self setOpenGLContext:glContext];
+
+ [glContext setView:self];
+
+ [glContext makeCurrentContext];
+
+ if (vsync)
+ {
+ [glContext setValues:(const GLint*)1 forParameter:NSOpenGLCPSwapInterval];
+ } else {
+ [glContext setValues:(const GLint*)0 forParameter:NSOpenGLCPSwapInterval];
+ }
+
+ return self;
+}
+
+- (BOOL) rebuildContext
+{
+ return [self rebuildContextWithFormat:[self pixelFormat]];
+}
+
+- (BOOL) rebuildContextWithFormat:(NSOpenGLPixelFormat *)format
+{
+ NSOpenGLContext *ctx = [self openGLContext];
+
+ [ctx clearDrawable];
+ [ctx initWithFormat:format shareContext:nil];
+
+ if (ctx == nil)
+ {
+ NSLog(@"Failed to create OpenGL context!", nil);
+ return false;
+ }
+
+ [self setOpenGLContext:ctx];
+ [ctx setView:self];
+ [ctx makeCurrentContext];
+ return true;
+}
+
+- (CGLContextObj)getCGLContextObj
+{
+ NSOpenGLContext *ctx = [self openGLContext];
+ return (CGLContextObj)[ctx CGLContextObj];
+}
+
+- (CGLPixelFormatObj*)getCGLPixelFormatObj
+{
+ NSOpenGLPixelFormat *fmt = [self pixelFormat];
+ return (CGLPixelFormatObj*)[fmt CGLPixelFormatObj];
+}
+
+// Various events can be intercepted by our view, thus not reaching our window.
+// Intercept these events, and pass them to the window as needed. - Geenz
+
+- (void) mouseDown:(NSEvent *)theEvent
+{
+ // Apparently people still use this?
+ if ([theEvent modifierFlags] & NSCommandKeyMask &&
+ !([theEvent modifierFlags] & NSControlKeyMask) &&
+ !([theEvent modifierFlags] & NSShiftKeyMask) &&
+ !([theEvent modifierFlags] & NSAlternateKeyMask) &&
+ !([theEvent modifierFlags] & NSAlphaShiftKeyMask) &&
+ !([theEvent modifierFlags] & NSFunctionKeyMask) &&
+ !([theEvent modifierFlags] & NSHelpKeyMask))
+ {
+ callRightMouseDown(mMousePos, mModifiers);
+ mSimulatedRightClick = true;
+ } else {
+ if ([theEvent clickCount] >= 2)
+ {
+ callDoubleClick(mMousePos, mModifiers);
+ } else if ([theEvent clickCount] == 1) {
+ callLeftMouseDown(mMousePos, mModifiers);
+ }
+ }
+}
+
+- (void) mouseUp:(NSEvent *)theEvent
+{
+ if (mSimulatedRightClick)
+ {
+ callRightMouseUp(mMousePos, mModifiers);
+ mSimulatedRightClick = false;
+ } else {
+ callLeftMouseUp(mMousePos, mModifiers);
+ }
+}
+
+- (void) rightMouseDown:(NSEvent *)theEvent
+{
+ callRightMouseDown(mMousePos, mModifiers);
+}
+
+- (void) rightMouseUp:(NSEvent *)theEvent
+{
+ callRightMouseUp(mMousePos, mModifiers);
+}
+
+- (void)mouseMoved:(NSEvent *)theEvent
+{
+ float mouseDeltas[2] = {
+ [theEvent deltaX],
+ [theEvent deltaY]
+ };
+
+ callDeltaUpdate(mouseDeltas, 0);
+
+ NSPoint mPoint = [theEvent locationInWindow];
+ mMousePos[0] = mPoint.x;
+ mMousePos[1] = mPoint.y;
+ callMouseMoved(mMousePos, 0);
+}
+
+// NSWindow doesn't trigger mouseMoved when the mouse is being clicked and dragged.
+// Use mouseDragged for situations like this to trigger our movement callback instead.
+
+- (void) mouseDragged:(NSEvent *)theEvent
+{
+ // Trust the deltas supplied by NSEvent.
+ // The old CoreGraphics APIs we previously relied on are now flagged as obsolete.
+ // NSEvent isn't obsolete, and provides us with the correct deltas.
+ float mouseDeltas[2] = {
+ [theEvent deltaX],
+ [theEvent deltaY]
+ };
+
+ callDeltaUpdate(mouseDeltas, 0);
+
+ NSPoint mPoint = [theEvent locationInWindow];
+ mMousePos[0] = mPoint.x;
+ mMousePos[1] = mPoint.y;
+ callMouseMoved(mMousePos, 0);
+}
+
+- (void) otherMouseDown:(NSEvent *)theEvent
+{
+ callMiddleMouseDown(mMousePos, mModifiers);
+}
+
+- (void) otherMouseUp:(NSEvent *)theEvent
+{
+ callMiddleMouseUp(mMousePos, mModifiers);
+}
+
+- (void) otherMouseDragged:(NSEvent *)theEvent
+{
+
+}
+
+- (void) scrollWheel:(NSEvent *)theEvent
+{
+ callScrollMoved(-[theEvent deltaY]);
+}
+
+- (void) mouseExited:(NSEvent *)theEvent
+{
+ callMouseExit();
+}
+
+- (void) keyUp:(NSEvent *)theEvent
+{
+ callKeyUp([theEvent keyCode], mModifiers);
+}
+
+- (void) keyDown:(NSEvent *)theEvent
+{
+ uint keycode = [theEvent keyCode];
+ bool acceptsText = mHasMarkedText ? false : callKeyDown(keycode, mModifiers);
+ if (acceptsText &&
+ !mMarkedTextAllowed &&
+ ![(LLAppDelegate*)[NSApp delegate] romanScript] &&
+ [[theEvent charactersIgnoringModifiers] characterAtIndex:0] != NSDeleteCharacter &&
+ [[theEvent charactersIgnoringModifiers] characterAtIndex:0] != NSBackspaceCharacter &&
+ [[theEvent charactersIgnoringModifiers] characterAtIndex:0] != NSDownArrowFunctionKey &&
+ [[theEvent charactersIgnoringModifiers] characterAtIndex:0] != NSUpArrowFunctionKey &&
+ [[theEvent charactersIgnoringModifiers] characterAtIndex:0] != NSLeftArrowFunctionKey &&
+ [[theEvent charactersIgnoringModifiers] characterAtIndex:0] != NSRightArrowFunctionKey)
+ {
+ [(LLAppDelegate*)[NSApp delegate] showInputWindow:true withEvent:theEvent];
+ } else
+ {
+ [[self inputContext] handleEvent:theEvent];
+ }
+
+ if ([[theEvent charactersIgnoringModifiers] characterAtIndex:0] == NSCarriageReturnCharacter ||
+ [[theEvent charactersIgnoringModifiers] characterAtIndex:0] == NSEnterCharacter)
+ {
+ // callKeyDown won't return the value we expect for enter or return. Handle them as a separate case.
+ [[self inputContext] handleEvent:theEvent];
+ }
+
+ // OS X intentionally does not send us key-up information on cmd-key combinations.
+ // This behaviour is not a bug, and only applies to cmd-combinations (no others).
+ // Since SL assumes we receive those, we fake it here.
+ if (mModifiers & NSCommandKeyMask && !mHasMarkedText)
+ {
+ callKeyUp([theEvent keyCode], mModifiers);
+ }
+}
+
+- (void)flagsChanged:(NSEvent *)theEvent {
+ mModifiers = [theEvent modifierFlags];
+ callModifier([theEvent modifierFlags]);
+}
+
+- (BOOL) acceptsFirstResponder
+{
+ return YES;
+}
+
+- (NSDragOperation) draggingEntered:(id<NSDraggingInfo>)sender
+{
+ NSPasteboard *pboard;
+ NSDragOperation sourceDragMask;
+
+ sourceDragMask = [sender draggingSourceOperationMask];
+
+ pboard = [sender draggingPasteboard];
+
+ if ([[pboard types] containsObject:NSURLPboardType])
+ {
+ if (sourceDragMask & NSDragOperationLink) {
+ NSURL *fileUrl = [[pboard readObjectsForClasses:[NSArray arrayWithObject:[NSURL class]] options:[NSDictionary dictionary]] objectAtIndex:0];
+ mLastDraggedUrl = [[fileUrl absoluteString] UTF8String];
+ return NSDragOperationLink;
+ }
+ }
+ return NSDragOperationNone;
+}
+
+- (NSDragOperation)draggingUpdated:(id <NSDraggingInfo>)sender
+{
+ callHandleDragUpdated(mLastDraggedUrl);
+
+ return NSDragOperationLink;
+}
+
+- (void) draggingExited:(id<NSDraggingInfo>)sender
+{
+ callHandleDragExited(mLastDraggedUrl);
+}
+
+- (BOOL)prepareForDragOperation:(id < NSDraggingInfo >)sender
+{
+ return YES;
+}
+
+- (BOOL) performDragOperation:(id<NSDraggingInfo>)sender
+{
+ callHandleDragDropped(mLastDraggedUrl);
+ return true;
+}
+
+- (BOOL)hasMarkedText
+{
+ return mHasMarkedText;
+}
+
+- (NSRange)markedRange
+{
+ int range[2];
+ getPreeditMarkedRange(&range[0], &range[1]);
+ return NSMakeRange(range[0], range[1]);
+}
+
+- (NSRange)selectedRange
+{
+ int range[2];
+ getPreeditSelectionRange(&range[0], &range[1]);
+ return NSMakeRange(range[0], range[1]);
+}
+
+- (void)setMarkedText:(id)aString selectedRange:(NSRange)selectedRange replacementRange:(NSRange)replacementRange
+{
+ if ([aString class] == NSClassFromString(@"NSConcreteMutableAttributedString"))
+ {
+ if (mMarkedTextAllowed)
+ {
+ unsigned int selected[2] = {
+ selectedRange.location,
+ selectedRange.length
+ };
+
+ unsigned int replacement[2] = {
+ replacementRange.location,
+ replacementRange.length
+ };
+
+ unichar text[[aString length]];
+ [[aString mutableString] getCharacters:text range:NSMakeRange(0, [aString length])];
+ attributedStringInfo segments = getSegments((NSAttributedString *)aString);
+ setMarkedText(text, selected, replacement, [aString length], segments);
+ mHasMarkedText = TRUE;
+ mMarkedTextLength = [aString length];
+ } else {
+ if (mHasMarkedText)
+ {
+ [self unmarkText];
+ }
+ }
+ }
+}
+
+- (void)commitCurrentPreedit
+{
+ if (mHasMarkedText)
+ {
+ if ([[self inputContext] respondsToSelector:@selector(commitEditing)])
+ {
+ [[self inputContext] commitEditing];
+ }
+ }
+}
+
+- (void)unmarkText
+{
+ [[self inputContext] discardMarkedText];
+ resetPreedit();
+ mHasMarkedText = FALSE;
+}
+
+// We don't support attributed strings.
+- (NSArray *)validAttributesForMarkedText
+{
+ return [NSArray array];
+}
+
+// See above.
+- (NSAttributedString *)attributedSubstringForProposedRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange
+{
+ return nil;
+}
+
+- (void)insertText:(id)insertString
+{
+ if (insertString != nil)
+ {
+ [self insertText:insertString replacementRange:NSMakeRange(0, [insertString length])];
+ }
+}
+
+- (void)insertText:(id)aString replacementRange:(NSRange)replacementRange
+{
+ if (!mHasMarkedText)
+ {
+ for (NSInteger i = 0; i < [aString length]; i++)
+ {
+ callUnicodeCallback([aString characterAtIndex:i], mModifiers);
+ }
+ } else {
+ resetPreedit();
+ // We may never get this point since unmarkText may be called before insertText ever gets called once we submit our text.
+ // But just in case...
+
+ for (NSInteger i = 0; i < [aString length]; i++)
+ {
+ handleUnicodeCharacter([aString characterAtIndex:i]);
+ }
+ mHasMarkedText = FALSE;
+ }
+}
+
+- (void) insertNewline:(id)sender
+{
+ if (!(mModifiers & NSCommandKeyMask) &&
+ !(mModifiers & NSShiftKeyMask) &&
+ !(mModifiers & NSAlternateKeyMask))
+ {
+ callUnicodeCallback(13, 0);
+ } else {
+ callUnicodeCallback(13, mModifiers);
+ }
+}
+
+- (NSUInteger)characterIndexForPoint:(NSPoint)aPoint
+{
+ return NSNotFound;
+}
+
+- (NSRect)firstRectForCharacterRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange
+{
+ float pos[4] = {0, 0, 0, 0};
+ getPreeditLocation(pos, mMarkedTextLength);
+ return NSMakeRect(pos[0], pos[1], pos[2], pos[3]);
+}
+
+- (void)doCommandBySelector:(SEL)aSelector
+{
+ if (aSelector == @selector(insertNewline:))
+ {
+ [self insertNewline:self];
+ }
+}
+
+- (BOOL)drawsVerticallyForCharacterAtIndex:(NSUInteger)charIndex
+{
+ return NO;
+}
+
+- (void) allowMarkedTextInput:(bool)allowed
+{
+ mMarkedTextAllowed = allowed;
+}
+
+@end
+
+@implementation LLUserInputWindow
+
+- (void) close
+{
+ [self orderOut:self];
+}
+
+@end
+
+@implementation LLNonInlineTextView
+
+- (void) setGLView:(LLOpenGLView *)view
+{
+ glview = view;
+}
+
+- (void) insertText:(id)insertString
+{
+ [[self inputContext] discardMarkedText];
+ [self setString:@""];
+ [_window orderOut:_window];
+ [self insertText:insertString replacementRange:NSMakeRange(0, [insertString length])];
+}
+
+- (void) insertText:(id)aString replacementRange:(NSRange)replacementRange
+{
+ [glview insertText:aString replacementRange:replacementRange];
+}
+
+- (void) insertNewline:(id)sender
+{
+ [[self textStorage] setValue:@""];
+ [[self inputContext] discardMarkedText];
+ [self setString:@""];
+}
+
+- (void)doCommandBySelector:(SEL)aSelector
+{
+ if (aSelector == @selector(insertNewline:))
+ {
+ [self insertNewline:self];
+ }
+}
+
+@end
+
+@implementation LLNSWindow
+
+- (id) init
+{
+ return self;
+}
+
+- (NSPoint)convertToScreenFromLocalPoint:(NSPoint)point relativeToView:(NSView *)view
+{
+ NSScreen *currentScreen = [NSScreen currentScreenForMouseLocation];
+ if(currentScreen)
+ {
+ NSPoint windowPoint = [view convertPoint:point toView:nil];
+ NSPoint screenPoint = [[view window] convertBaseToScreen:windowPoint];
+ NSPoint flippedScreenPoint = [currentScreen flipPoint:screenPoint];
+ flippedScreenPoint.y += [currentScreen frame].origin.y;
+
+ return flippedScreenPoint;
+ }
+
+ return NSZeroPoint;
+}
+
+- (NSPoint)flipPoint:(NSPoint)aPoint
+{
+ return NSMakePoint(aPoint.x, self.frame.size.height - aPoint.y);
+}
+
+- (BOOL) becomeFirstResponder
+{
+ callFocus();
+ return true;
+}
+
+- (BOOL) resignFirstResponder
+{
+ callFocusLost();
+ return true;
+}
+
+- (void) close
+{
+ callQuitHandler();
+}
+
+@end
diff --git a/indra/llwindow/llpreeditor.h b/indra/llwindow/llpreeditor.h
index 9802fd8606..9802fd8606 100644..100755
--- a/indra/llwindow/llpreeditor.h
+++ b/indra/llwindow/llpreeditor.h
diff --git a/indra/llwindow/llwindow.cpp b/indra/llwindow/llwindow.cpp
index 5b7424acbb..93b9d36939 100644..100755
--- a/indra/llwindow/llwindow.cpp
+++ b/indra/llwindow/llwindow.cpp
@@ -50,14 +50,15 @@ LLSplashScreen *gSplashScreenp = NULL;
BOOL gDebugClicks = FALSE;
BOOL gDebugWindowProc = FALSE;
-const S32 gURLProtocolWhitelistCount = 3;
-const std::string gURLProtocolWhitelist[] = { "file:", "http:", "https:" };
+const S32 gURLProtocolWhitelistCount = 4;
+const std::string gURLProtocolWhitelist[] = { "secondlife:", "http:", "https:", "data:" };
// CP: added a handler list - this is what's used to open the protocol and is based on registry entry
// only meaningful difference currently is that file: protocols are opened using http:
// since no protocol handler exists in registry for file:
// Important - these lists should match - protocol to handler
-const std::string gURLProtocolWhitelistHandler[] = { "http", "http", "https" };
+// Maestro: This list isn't referenced anywhere that I could find
+//const std::string gURLProtocolWhitelistHandler[] = { "http", "http", "https" };
S32 OSMessageBox(const std::string& text, const std::string& caption, U32 type)
diff --git a/indra/llwindow/llwindow.h b/indra/llwindow/llwindow.h
index 4da87f4e06..78186004b8 100644..100755
--- a/indra/llwindow/llwindow.h
+++ b/indra/llwindow/llwindow.h
@@ -42,6 +42,7 @@ class LLWindowCallbacks;
class LLWindow : public LLInstanceTracker<LLWindow>
{
public:
+
struct LLWindowResolution
{
S32 mWidth;
@@ -280,7 +281,7 @@ extern BOOL gDebugWindowProc;
// Protocols, like "http" and "https" we support in URLs
extern const S32 gURLProtocolWhitelistCount;
extern const std::string gURLProtocolWhitelist[];
-extern const std::string gURLProtocolWhitelistHandler[];
+//extern const std::string gURLProtocolWhitelistHandler[];
void simpleEscapeString ( std::string& stringIn );
diff --git a/indra/llwindow/llwindowcallbacks.cpp b/indra/llwindow/llwindowcallbacks.cpp
index 9712ae1d91..eadff8a6b4 100644..100755
--- a/indra/llwindow/llwindowcallbacks.cpp
+++ b/indra/llwindow/llwindowcallbacks.cpp
@@ -122,6 +122,7 @@ void LLWindowCallbacks::handleResize(LLWindow *window, const S32 width, const S3
void LLWindowCallbacks::handleFocus(LLWindow *window)
{
+ LL_WARNS("COCOA") << "Called handleFocus proto" << LL_ENDL;
}
void LLWindowCallbacks::handleFocusLost(LLWindow *window)
diff --git a/indra/llwindow/llwindowcallbacks.h b/indra/llwindow/llwindowcallbacks.h
index 7da5959700..7da5959700 100644..100755
--- a/indra/llwindow/llwindowcallbacks.h
+++ b/indra/llwindow/llwindowcallbacks.h
diff --git a/indra/llwindow/llwindowheadless.cpp b/indra/llwindow/llwindowheadless.cpp
index e6e6bc67ff..e6e6bc67ff 100644..100755
--- a/indra/llwindow/llwindowheadless.cpp
+++ b/indra/llwindow/llwindowheadless.cpp
diff --git a/indra/llwindow/llwindowheadless.h b/indra/llwindow/llwindowheadless.h
index 1f767f4c97..1f767f4c97 100644..100755
--- a/indra/llwindow/llwindowheadless.h
+++ b/indra/llwindow/llwindowheadless.h
diff --git a/indra/llwindow/llwindowmacosx-objc.h b/indra/llwindow/llwindowmacosx-objc.h
index 7893dedda4..81b25601a9 100644..100755
--- a/indra/llwindow/llwindowmacosx-objc.h
+++ b/indra/llwindow/llwindowmacosx-objc.h
@@ -25,13 +25,127 @@
* $/LicenseInfo$
*/
+#ifndef LL_LLWINDOWMACOSX_OBJC_H
+#define LL_LLWINDOWMACOSX_OBJC_H
+
+#include <map>
+#include <vector>
+
+typedef std::vector<std::pair<int, bool> > segment_t;
+
+typedef std::vector<int> segment_lengths;
+typedef std::vector<int> segment_standouts;
+
+struct attributedStringInfo {
+ segment_lengths seg_lengths;
+ segment_standouts seg_standouts;
+};
// This will actually hold an NSCursor*, but that type is only available in objective C.
typedef void *CursorRef;
+typedef void *NSWindowRef;
+typedef void *GLViewRef;
+
+// These are defined in llappviewermacosx.cpp.
+bool initViewer();
+void handleQuit();
+bool runMainLoop();
+void initMainLoop();
+void cleanupViewer();
+void handleUrl(const char* url);
/* Defined in llwindowmacosx-objc.mm: */
+int createNSApp(int argc, const char **argv);
void setupCocoa();
+bool pasteBoardAvailable();
+bool copyToPBoard(const unsigned short *str, unsigned int len);
+const unsigned short *copyFromPBoard();
CursorRef createImageCursor(const char *fullpath, int hotspotX, int hotspotY);
-OSErr releaseImageCursor(CursorRef ref);
-OSErr setImageCursor(CursorRef ref);
+short releaseImageCursor(CursorRef ref);
+short setImageCursor(CursorRef ref);
+void setArrowCursor();
+void setIBeamCursor();
+void setPointingHandCursor();
+void setCopyCursor();
+void setCrossCursor();
+void setNotAllowedCursor();
+void hideNSCursor();
+void showNSCursor();
+void hideNSCursorTillMove(bool hide);
+void requestUserAttention();
+long showAlert(std::string title, std::string text, int type);
+
+NSWindowRef createNSWindow(int x, int y, int width, int height);
+
+#include <OpenGL/OpenGL.h>
+GLViewRef createOpenGLView(NSWindowRef window, unsigned int samples, bool vsync);
+void glSwapBuffers(void* context);
+CGLContextObj getCGLContextObj(GLViewRef view);
+unsigned long getVramSize(GLViewRef view);
+void getContentViewBounds(NSWindowRef window, float* bounds);
+void getWindowSize(NSWindowRef window, float* size);
+void setWindowSize(NSWindowRef window, int width, int height);
+void getCursorPos(NSWindowRef window, float* pos);
+void makeWindowOrderFront(NSWindowRef window);
+void convertScreenToWindow(NSWindowRef window, float *coord);
+void convertWindowToScreen(NSWindowRef window, float *coord);
+void convertScreenToView(NSWindowRef window, float *coord);
+void convertRectToScreen(NSWindowRef window, float *coord);
+void convertRectFromScreen(NSWindowRef window, float *coord);
+void setWindowPos(NSWindowRef window, float* pos);
+void closeWindow(NSWindowRef window);
+void removeGLView(GLViewRef view);
+void makeFirstResponder(NSWindowRef window, GLViewRef view);
+void setupInputWindow(NSWindowRef window, GLViewRef view);
+
+// These are all implemented in llwindowmacosx.cpp.
+// This is largely for easier interop between Obj-C and C++ (at least in the viewer's case due to the BOOL vs. BOOL conflict)
+bool callKeyUp(unsigned short key, unsigned int mask);
+bool callKeyDown(unsigned short key, unsigned int mask);
+void callResetKeys();
+bool callUnicodeCallback(wchar_t character, unsigned int mask);
+void callRightMouseDown(float *pos, unsigned int mask);
+void callRightMouseUp(float *pos, unsigned int mask);
+void callLeftMouseDown(float *pos, unsigned int mask);
+void callLeftMouseUp(float *pos, unsigned int mask);
+void callDoubleClick(float *pos, unsigned int mask);
+void callResize(unsigned int width, unsigned int height);
+void callMouseMoved(float *pos, unsigned int mask);
+void callScrollMoved(float delta);
+void callMouseExit();
+void callWindowFocus();
+void callWindowUnfocus();
+void callDeltaUpdate(float *delta, unsigned int mask);
+void callMiddleMouseDown(float *pos, unsigned int mask);
+void callMiddleMouseUp(float *pos, unsigned int mask);
+void callFocus();
+void callFocusLost();
+void callModifier(unsigned int mask);
+void callQuitHandler();
+void commitCurrentPreedit(GLViewRef glView);
+
+#include <string>
+void callHandleDragEntered(std::string url);
+void callHandleDragExited(std::string url);
+void callHandleDragUpdated(std::string url);
+void callHandleDragDropped(std::string url);
+
+// LLPreeditor C bindings.
+std::basic_string<wchar_t> getPreeditString();
+void getPreeditSelectionRange(int *position, int *length);
+void getPreeditMarkedRange(int *position, int *length);
+bool handleUnicodeCharacter(wchar_t c);
+void updatePreeditor(unsigned short *str);
+void setPreeditMarkedRange(int position, int length);
+void resetPreedit();
+int wstring_length(const std::basic_string<wchar_t> & wstr, const int woffset, const int utf16_length, int *unaligned);
+void setMarkedText(unsigned short *text, unsigned int *selectedRange, unsigned int *replacementRange, long text_len, attributedStringInfo segments);
+void getPreeditLocation(float *location, unsigned int length);
+void allowDirectMarkedTextInput(bool allow, GLViewRef glView);
+
+NSWindowRef getMainAppWindow();
+GLViewRef getGLView();
+
+unsigned int getModifiers();
+#endif // LL_LLWINDOWMACOSX_OBJC_H
diff --git a/indra/llwindow/llwindowmacosx-objc.mm b/indra/llwindow/llwindowmacosx-objc.mm
index bebb537cd8..0768d0352e 100644..100755
--- a/indra/llwindow/llwindowmacosx-objc.mm
+++ b/indra/llwindow/llwindowmacosx-objc.mm
@@ -1,4 +1,4 @@
-/**
+/**
* @file llwindowmacosx-objc.mm
* @brief Definition of functions shared between llwindowmacosx.cpp
* and llwindowmacosx-objc.mm.
@@ -6,26 +6,30 @@
* $LicenseInfo:firstyear=2006&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 <AppKit/AppKit.h>
+#include <Cocoa/Cocoa.h>
+#include "llopenglview-objc.h"
+#include "llwindowmacosx-objc.h"
+#include "llappdelegate-objc.h"
/*
* These functions are broken out into a separate file because the
@@ -34,7 +38,10 @@
* linden headers with any objective-C++ source.
*/
-#include "llwindowmacosx-objc.h"
+int createNSApp(int argc, const char *argv[])
+{
+ return NSApplicationMain(argc, argv);
+}
void setupCocoa()
{
@@ -45,44 +52,122 @@ void setupCocoa()
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
// The following prevents the Cocoa command line parser from trying to open 'unknown' arguements as documents.
- // ie. running './secondlife -set Language fr' would cause a pop-up saying can't open document 'fr'
- // when init'ing the Cocoa App window.
+ // ie. running './secondlife -set Language fr' would cause a pop-up saying can't open document 'fr'
+ // when init'ing the Cocoa App window.
[[NSUserDefaults standardUserDefaults] setObject:@"NO" forKey:@"NSTreatUnknownArgumentsAsOpen"];
- // This is a bit of voodoo taken from the Apple sample code "CarbonCocoa_PictureCursor":
- // http://developer.apple.com/samplecode/CarbonCocoa_PictureCursor/index.html
-
- // Needed for Carbon based applications which call into Cocoa
- NSApplicationLoad();
-
- // Must first call [[[NSWindow alloc] init] release] to get the NSWindow machinery set up so that NSCursor can use a window to cache the cursor image
- [[[NSWindow alloc] init] release];
-
[pool release];
-
+
inited = true;
}
}
+bool copyToPBoard(const unsigned short *str, unsigned int len)
+{
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
+ NSPasteboard *pboard = [NSPasteboard generalPasteboard];
+ [pboard clearContents];
+
+ NSArray *contentsToPaste = [[NSArray alloc] initWithObjects:[NSString stringWithCharacters:str length:len], nil];
+ [pool release];
+ return [pboard writeObjects:contentsToPaste];
+}
+
+bool pasteBoardAvailable()
+{
+ NSArray *classArray = [NSArray arrayWithObject:[NSString class]];
+ return [[NSPasteboard generalPasteboard] canReadObjectForClasses:classArray options:[NSDictionary dictionary]];
+}
+
+const unsigned short *copyFromPBoard()
+{
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
+ NSPasteboard *pboard = [NSPasteboard generalPasteboard];
+ NSArray *classArray = [NSArray arrayWithObject:[NSString class]];
+ NSString *str = NULL;
+ BOOL ok = [pboard canReadObjectForClasses:classArray options:[NSDictionary dictionary]];
+ if (ok)
+ {
+ NSArray *objToPaste = [pboard readObjectsForClasses:classArray options:[NSDictionary dictionary]];
+ str = [objToPaste objectAtIndex:0];
+ }
+ unichar* temp = (unichar*)calloc([str length], sizeof(unichar));
+ [str getCharacters:temp];
+ [pool release];
+ return temp;
+}
+
CursorRef createImageCursor(const char *fullpath, int hotspotX, int hotspotY)
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-
+
// extra retain on the NSCursor since we want it to live for the lifetime of the app.
NSCursor *cursor =
- [[[NSCursor alloc]
- initWithImage:
- [[[NSImage alloc] initWithContentsOfFile:
- [NSString stringWithFormat:@"%s", fullpath]
- ]autorelease]
- hotSpot:NSMakePoint(hotspotX, hotspotY)
- ]retain];
-
+ [[[NSCursor alloc]
+ initWithImage:
+ [[[NSImage alloc] initWithContentsOfFile:
+ [NSString stringWithFormat:@"%s", fullpath]
+ ]autorelease]
+ hotSpot:NSMakePoint(hotspotX, hotspotY)
+ ]retain];
+
[pool release];
return (CursorRef)cursor;
}
+void setArrowCursor()
+{
+ NSCursor *cursor = [NSCursor arrowCursor];
+ [NSCursor unhide];
+ [cursor set];
+}
+
+void setIBeamCursor()
+{
+ NSCursor *cursor = [NSCursor IBeamCursor];
+ [cursor set];
+}
+
+void setPointingHandCursor()
+{
+ NSCursor *cursor = [NSCursor pointingHandCursor];
+ [cursor set];
+}
+
+void setCopyCursor()
+{
+ NSCursor *cursor = [NSCursor dragCopyCursor];
+ [cursor set];
+}
+
+void setCrossCursor()
+{
+ NSCursor *cursor = [NSCursor crosshairCursor];
+ [cursor set];
+}
+
+void setNotAllowedCursor()
+{
+ NSCursor *cursor = [NSCursor operationNotAllowedCursor];
+ [cursor set];
+}
+
+void hideNSCursor()
+{
+ [NSCursor hide];
+}
+
+void showNSCursor()
+{
+ [NSCursor unhide];
+}
+
+void hideNSCursorTillMove(bool hide)
+{
+ [NSCursor setHiddenUntilMouseMoves:hide];
+}
+
// This is currently unused, since we want all our cursors to persist for the life of the app, but I've included it for completeness.
OSErr releaseImageCursor(CursorRef ref)
{
@@ -118,3 +203,250 @@ OSErr setImageCursor(CursorRef ref)
return noErr;
}
+// Now for some unholy juggling between generic pointers and casting them to Obj-C objects!
+// Note: things can get a bit hairy from here. This is not for the faint of heart.
+
+NSWindowRef createNSWindow(int x, int y, int width, int height)
+{
+ LLNSWindow *window = [[LLNSWindow alloc]initWithContentRect:NSMakeRect(x, y, width, height)
+ styleMask:NSTitledWindowMask | NSResizableWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSTexturedBackgroundWindowMask backing:NSBackingStoreBuffered defer:NO];
+ [window makeKeyAndOrderFront:nil];
+ [window setAcceptsMouseMovedEvents:TRUE];
+ return window;
+}
+
+GLViewRef createOpenGLView(NSWindowRef window, unsigned int samples, bool vsync)
+{
+ LLOpenGLView *glview = [[LLOpenGLView alloc]initWithFrame:[(LLNSWindow*)window frame] withSamples:samples andVsync:vsync];
+ [(LLNSWindow*)window setContentView:glview];
+ return glview;
+}
+
+void glSwapBuffers(void* context)
+{
+ [(NSOpenGLContext*)context flushBuffer];
+}
+
+CGLContextObj getCGLContextObj(GLViewRef view)
+{
+ return [(LLOpenGLView *)view getCGLContextObj];
+}
+
+CGLPixelFormatObj* getCGLPixelFormatObj(NSWindowRef window)
+{
+ LLOpenGLView *glview = [(LLNSWindow*)window contentView];
+ return [glview getCGLPixelFormatObj];
+}
+
+unsigned long getVramSize(GLViewRef view)
+{
+ return [(LLOpenGLView *)view getVramSize];
+}
+
+void getContentViewBounds(NSWindowRef window, float* bounds)
+{
+ bounds[0] = [[(LLNSWindow*)window contentView] bounds].origin.x;
+ bounds[1] = [[(LLNSWindow*)window contentView] bounds].origin.y;
+ bounds[2] = [[(LLNSWindow*)window contentView] bounds].size.width;
+ bounds[3] = [[(LLNSWindow*)window contentView] bounds].size.height;
+}
+
+void getWindowSize(NSWindowRef window, float* size)
+{
+ NSRect frame = [(LLNSWindow*)window frame];
+ size[0] = frame.origin.x;
+ size[1] = frame.origin.y;
+ size[2] = frame.size.width;
+ size[3] = frame.size.height;
+}
+
+void setWindowSize(NSWindowRef window, int width, int height)
+{
+ NSRect frame = [(LLNSWindow*)window frame];
+ frame.size.width = width;
+ frame.size.height = height;
+ [(LLNSWindow*)window setFrame:frame display:TRUE];
+}
+
+void setWindowPos(NSWindowRef window, float* pos)
+{
+ NSPoint point;
+ point.x = pos[0];
+ point.y = pos[1];
+ [(LLNSWindow*)window setFrameOrigin:point];
+}
+
+void getCursorPos(NSWindowRef window, float* pos)
+{
+ NSPoint mLoc;
+ mLoc = [(LLNSWindow*)window mouseLocationOutsideOfEventStream];
+ pos[0] = mLoc.x;
+ pos[1] = mLoc.y;
+}
+
+void makeWindowOrderFront(NSWindowRef window)
+{
+ [(LLNSWindow*)window makeKeyAndOrderFront:nil];
+}
+
+void convertScreenToWindow(NSWindowRef window, float *coord)
+{
+ NSRect point;
+ point.origin.x = coord[0];
+ point.origin.y = coord[1];
+ point = [(LLNSWindow*)window convertRectFromScreen:point];
+ coord[0] = point.origin.x;
+ coord[1] = point.origin.y;
+}
+
+void convertRectToScreen(NSWindowRef window, float *coord)
+{
+ NSRect point;
+ point.origin.x = coord[0];
+ point.origin.y = coord[1];
+ point.size.width = coord[2];
+ point.size.height = coord[3];
+
+ point = [(LLNSWindow*)window convertRectToScreen:point];
+
+ coord[0] = point.origin.x;
+ coord[1] = point.origin.y;
+ coord[2] = point.size.width;
+ coord[3] = point.size.height;
+}
+
+void convertRectFromScreen(NSWindowRef window, float *coord)
+{
+ NSRect point;
+ point.origin.x = coord[0];
+ point.origin.y = coord[1];
+ point.size.width = coord[2];
+ point.size.height = coord[3];
+
+ point = [(LLNSWindow*)window convertRectFromScreen:point];
+
+ coord[0] = point.origin.x;
+ coord[1] = point.origin.y;
+ coord[2] = point.size.width;
+ coord[3] = point.size.height;
+}
+
+void convertScreenToView(NSWindowRef window, float *coord)
+{
+ NSRect point;
+ point.origin.x = coord[0];
+ point.origin.y = coord[1];
+ point.origin = [(LLNSWindow*)window convertScreenToBase:point.origin];
+ point.origin = [[(LLNSWindow*)window contentView] convertPoint:point.origin fromView:nil];
+}
+
+void convertWindowToScreen(NSWindowRef window, float *coord)
+{
+ NSPoint point;
+ point.x = coord[0];
+ point.y = coord[1];
+ point = [(LLNSWindow*)window convertToScreenFromLocalPoint:point relativeToView:[(LLNSWindow*)window contentView]];
+ coord[0] = point.x;
+ coord[1] = point.y;
+}
+
+void closeWindow(NSWindowRef window)
+{
+ [(LLNSWindow*)window close];
+ [(LLNSWindow*)window release];
+}
+
+void removeGLView(GLViewRef view)
+{
+ [(LLOpenGLView*)view removeFromSuperview];
+ [(LLOpenGLView*)view release];
+}
+
+void setupInputWindow(NSWindowRef window, GLViewRef glview)
+{
+ [[(LLAppDelegate*)[NSApp delegate] inputView] setGLView:(LLOpenGLView*)glview];
+}
+
+void commitCurrentPreedit(GLViewRef glView)
+{
+ [(LLOpenGLView*)glView commitCurrentPreedit];
+}
+
+void allowDirectMarkedTextInput(bool allow, GLViewRef glView)
+{
+ [(LLOpenGLView*)glView allowMarkedTextInput:allow];
+}
+
+NSWindowRef getMainAppWindow()
+{
+ LLNSWindow *winRef = [(LLAppDelegate*)[[NSApplication sharedApplication] delegate] window];
+
+ [winRef setAcceptsMouseMovedEvents:TRUE];
+ return winRef;
+}
+
+void makeFirstResponder(NSWindowRef window, GLViewRef view)
+{
+ [(LLNSWindow*)window makeFirstResponder:(LLOpenGLView*)view];
+}
+
+void requestUserAttention()
+{
+ [[NSApplication sharedApplication] requestUserAttention:NSInformationalRequest];
+}
+
+long showAlert(std::string text, std::string title, int type)
+{
+ NSAlert *alert = [[NSAlert alloc] init];
+
+ [alert setMessageText:[NSString stringWithCString:title.c_str() encoding:[NSString defaultCStringEncoding]]];
+ [alert setInformativeText:[NSString stringWithCString:text.c_str() encoding:[NSString defaultCStringEncoding]]];
+ if (type == 0)
+ {
+ [alert addButtonWithTitle:@"Okay"];
+ } else if (type == 1)
+ {
+ [alert addButtonWithTitle:@"Okay"];
+ [alert addButtonWithTitle:@"Cancel"];
+ } else if (type == 2)
+ {
+ [alert addButtonWithTitle:@"Yes"];
+ [alert addButtonWithTitle:@"No"];
+ }
+ long ret = [alert runModal];
+ [alert dealloc];
+
+ if (ret == NSAlertFirstButtonReturn)
+ {
+ if (type == 1)
+ {
+ ret = 3;
+ } else if (type == 2)
+ {
+ ret = 0;
+ }
+ } else if (ret == NSAlertSecondButtonReturn)
+ {
+ if (type == 0 || type == 1)
+ {
+ ret = 2;
+ } else if (type == 2)
+ {
+ ret = 1;
+ }
+ }
+
+ return ret;
+}
+
+/*
+ GLViewRef getGLView()
+ {
+ return [(LLAppDelegate*)[[NSApplication sharedApplication] delegate] glview];
+ }
+ */
+
+unsigned int getModifiers()
+{
+ return [NSEvent modifierFlags];
+}
diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp
index 32bb84cba5..11c0b51086 100644..100755
--- a/indra/llwindow/llwindowmacosx.cpp
+++ b/indra/llwindow/llwindowmacosx.cpp
@@ -30,7 +30,6 @@
#include "llkeyboardmacosx.h"
#include "llwindowcallbacks.h"
-#include "llwindowmacosx-objc.h"
#include "llpreeditor.h"
#include "llerror.h"
@@ -39,8 +38,8 @@
#include "lldir.h"
#include "indra_constants.h"
-#include <Carbon/Carbon.h>
#include <OpenGL/OpenGL.h>
+#include <CoreServices/CoreServices.h>
extern BOOL gDebugWindowProc;
@@ -58,7 +57,6 @@ const S32 MAX_NUM_RESOLUTIONS = 32;
//
BOOL LLWindowMacOSX::sUseMultGL = FALSE;
-WindowRef LLWindowMacOSX::sMediaWindow = NULL;
// Cross-platform bits:
@@ -98,105 +96,9 @@ BOOL check_for_card(const char* RENDERER, const char* bad_card)
// We may want to base this on the setting of _DEBUG...
#define CAPTURE_ALL_DISPLAYS 0
-static double getDictDouble (CFDictionaryRef refDict, CFStringRef key);
+//static double getDictDouble (CFDictionaryRef refDict, CFStringRef key);
static long getDictLong (CFDictionaryRef refDict, CFStringRef key);
-
-
-
-// CarbonEvents we're interested in.
-static EventTypeSpec WindowHandlerEventList[] =
-{
- // Window-related events
- { kEventClassWindow, kEventWindowActivated },
- { kEventClassWindow, kEventWindowDeactivated },
- { kEventClassWindow, kEventWindowShown },
- { kEventClassWindow, kEventWindowHidden },
- { kEventClassWindow, kEventWindowCollapsed },
- { kEventClassWindow, kEventWindowExpanded },
- { kEventClassWindow, kEventWindowGetClickActivation },
- { kEventClassWindow, kEventWindowClose },
- { kEventClassWindow, kEventWindowBoundsChanging },
- { kEventClassWindow, kEventWindowBoundsChanged },
- { kEventClassWindow, kEventWindowGetIdealSize },
-
- // Mouse events
- { kEventClassMouse, kEventMouseDown },
- { kEventClassMouse, kEventMouseUp },
- { kEventClassMouse, kEventMouseDragged },
- { kEventClassMouse, kEventMouseWheelMoved },
- { kEventClassMouse, kEventMouseMoved },
-
- // Keyboard events
- // No longer handle raw key down events directly.
- // When text input events come in, extract the raw key events from them and process at that point.
- // This allows input methods to eat keystrokes the way they're supposed to.
-// { kEventClassKeyboard, kEventRawKeyDown },
-// { kEventClassKeyboard, kEventRawKeyRepeat },
- { kEventClassKeyboard, kEventRawKeyUp },
- { kEventClassKeyboard, kEventRawKeyModifiersChanged },
-
- // Text input events
- { kEventClassTextInput, kEventTextInputUnicodeForKeyEvent },
- { kEventClassTextInput, kEventTextInputUpdateActiveInputArea },
- { kEventClassTextInput, kEventTextInputOffsetToPos },
- { kEventClassTextInput, kEventTextInputPosToOffset },
- { kEventClassTextInput, kEventTextInputShowHideBottomWindow },
- { kEventClassTextInput, kEventTextInputGetSelectedText },
- { kEventClassTextInput, kEventTextInputFilterText },
-
- // TSM Document Access events (advanced input method support)
- { kEventClassTSMDocumentAccess, kEventTSMDocumentAccessGetLength },
- { kEventClassTSMDocumentAccess, kEventTSMDocumentAccessGetSelectedRange },
- { kEventClassTSMDocumentAccess, kEventTSMDocumentAccessGetCharacters },
- { kEventClassTSMDocumentAccess, kEventTSMDocumentAccessGetFont },
- { kEventClassTSMDocumentAccess, kEventTSMDocumentAccessGetGlyphInfo },
- { kEventClassTSMDocumentAccess, kEventTSMDocumentAccessLockDocument },
- { kEventClassTSMDocumentAccess, kEventTSMDocumentAccessUnlockDocument }
-};
-
-static EventTypeSpec GlobalHandlerEventList[] =
-{
- // Mouse events
- { kEventClassMouse, kEventMouseDown },
- { kEventClassMouse, kEventMouseUp },
- { kEventClassMouse, kEventMouseDragged },
- { kEventClassMouse, kEventMouseWheelMoved },
- { kEventClassMouse, kEventMouseMoved },
-
- // Keyboard events
- // No longer handle raw key down events directly.
- // When text input events come in, extract the raw key events from them and process at that point.
- // This allows input methods to eat keystrokes the way they're supposed to.
-// { kEventClassKeyboard, kEventRawKeyDown },
-// { kEventClassKeyboard, kEventRawKeyRepeat },
- { kEventClassKeyboard, kEventRawKeyUp },
- { kEventClassKeyboard, kEventRawKeyModifiersChanged },
-
- // Text input events
- { kEventClassTextInput, kEventTextInputUpdateActiveInputArea },
- { kEventClassTextInput, kEventTextInputUnicodeForKeyEvent },
- { kEventClassTextInput, kEventTextInputOffsetToPos },
- { kEventClassTextInput, kEventTextInputPosToOffset },
- { kEventClassTextInput, kEventTextInputShowHideBottomWindow },
- { kEventClassTextInput, kEventTextInputGetSelectedText },
- { kEventClassTextInput, kEventTextInputFilterText },
-
- // TSM Document Access events (advanced input method support)
- { kEventClassTSMDocumentAccess, kEventTSMDocumentAccessGetLength },
- { kEventClassTSMDocumentAccess, kEventTSMDocumentAccessGetSelectedRange },
- { kEventClassTSMDocumentAccess, kEventTSMDocumentAccessGetCharacters },
- { kEventClassTSMDocumentAccess, kEventTSMDocumentAccessGetFont },
- { kEventClassTSMDocumentAccess, kEventTSMDocumentAccessGetGlyphInfo },
- { kEventClassTSMDocumentAccess, kEventTSMDocumentAccessLockDocument },
- { kEventClassTSMDocumentAccess, kEventTSMDocumentAccessUnlockDocument }
-};
-
-static EventTypeSpec CommandHandlerEventList[] =
-{
- { kEventClassCommand, kEventCommandProcess }
-};
-
// MBW -- HACK ALERT
// On the Mac, to put up an OS dialog in full screen mode, we must first switch OUT of full screen mode.
// The proper way to do this is to bracket the dialog with calls to beforeDialog() and afterDialog(), but these
@@ -204,8 +106,6 @@ static EventTypeSpec CommandHandlerEventList[] =
// This assumes that there will be only one object of this class at any time. Hopefully this is true.
static LLWindowMacOSX *gWindowImplementation = NULL;
-
-
LLWindowMacOSX::LLWindowMacOSX(LLWindowCallbacks* callbacks,
const std::string& title, const std::string& name, S32 x, S32 y, S32 width,
S32 height, U32 flags,
@@ -233,8 +133,6 @@ LLWindowMacOSX::LLWindowMacOSX(LLWindowCallbacks* callbacks,
mContext = NULL;
mPixelFormat = NULL;
mDisplay = CGMainDisplayID();
- mOldDisplayMode = NULL;
- mTimer = NULL;
mSimulatedRightClick = FALSE;
mLastModifiers = 0;
mHandsOffEvents = FALSE;
@@ -246,60 +144,31 @@ LLWindowMacOSX::LLWindowMacOSX(LLWindowCallbacks* callbacks,
mOverrideAspectRatio = 0.f;
mMaximized = FALSE;
mMinimized = FALSE;
- mTSMDocument = NULL; // Just in case.
mLanguageTextInputAllowed = FALSE;
- mTSMScriptCode = 0;
- mTSMLangCode = 0;
mPreeditor = NULL;
- mRawKeyEvent = NULL;
mFSAASamples = fsaa_samples;
mForceRebuild = FALSE;
- // For reasons that aren't clear to me, LLTimers seem to be created in the "started" state.
- // Since the started state of this one is used to track whether the NMRec has been installed, it wants to start out in the "stopped" state.
- mBounceTimer.stop();
-
// Get the original aspect ratio of the main device.
mOriginalAspectRatio = (double)CGDisplayPixelsWide(mDisplay) / (double)CGDisplayPixelsHigh(mDisplay);
// Stash the window title
- strcpy((char*)mWindowTitle + 1, title.c_str()); /* Flawfinder: ignore */
- mWindowTitle[0] = title.length();
-
- mEventHandlerUPP = NewEventHandlerUPP(staticEventHandler);
- mMoveEventCampartorUPP = NewEventComparatorUPP(staticMoveEventComparator);
- mGlobalHandlerRef = NULL;
- mWindowHandlerRef = NULL;
+ mWindowTitle = title;
+ //mWindowTitle[0] = title.length();
mDragOverrideCursor = -1;
- // We're not clipping yet
- SetRect( &mOldMouseClip, 0, 0, 0, 0 );
-
// Set up global event handlers (the fullscreen case needs this)
- InstallStandardEventHandler(GetApplicationEventTarget());
+ //InstallStandardEventHandler(GetApplicationEventTarget());
// Stash an object pointer for OSMessageBox()
gWindowImplementation = this;
-
// Create the GL context and set it up for windowed or fullscreen, as appropriate.
if(createContext(x, y, width, height, 32, fullscreen, disable_vsync))
{
if(mWindow != NULL)
{
- // MBW -- XXX -- I think we can now do this here?
- // Constrain the window to the screen it's mostly on, resizing if necessary.
- ConstrainWindowToScreen(
- mWindow,
- kWindowStructureRgn,
- kWindowConstrainMayResize |
- // kWindowConstrainStandardOptions |
- 0,
- NULL,
- NULL);
-
- MacShowWindow(mWindow);
- BringToFront(mWindow);
+ makeWindowOrderFront(mWindow);
}
if (!gGLManager.initGL())
@@ -317,480 +186,399 @@ LLWindowMacOSX::LLWindowMacOSX(LLWindowCallbacks* callbacks,
//start with arrow cursor
initCursors();
setCursor( UI_CURSOR_ARROW );
+
+ allowLanguageTextInput(NULL, FALSE);
}
mCallbacks = callbacks;
stop_glerror();
+
+
}
-BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits, BOOL fullscreen, BOOL disable_vsync)
-{
- OSStatus err;
- BOOL glNeedsInit = FALSE;
-
- if(mGlobalHandlerRef == NULL)
- {
- InstallApplicationEventHandler(mEventHandlerUPP, GetEventTypeCount (CommandHandlerEventList), CommandHandlerEventList, (void*)this, &mGlobalHandlerRef);
- }
-
- mFullscreen = fullscreen;
-
- if (mFullscreen && (mOldDisplayMode == NULL))
- {
- LL_INFOS("Window") << "createContext: setting up fullscreen " << width << "x" << height << LL_ENDL;
-
- // NOTE: The refresh rate will be REPORTED AS 0 for many DVI and notebook displays. Plan accordingly.
- double refresh = getDictDouble (CGDisplayCurrentMode (mDisplay), kCGDisplayRefreshRate);
-
- // If the requested width or height is 0, find the best default for the monitor.
- if((width == 0) || (height == 0))
- {
- // Scan through the list of modes, looking for one which has:
- // height between 700 and 800
- // aspect ratio closest to the user's original mode
- S32 resolutionCount = 0;
- LLWindowResolution *resolutionList = getSupportedResolutions(resolutionCount);
-
- if(resolutionList != NULL)
- {
- F32 closestAspect = 0;
- U32 closestHeight = 0;
- U32 closestWidth = 0;
- int i;
-
- LL_DEBUGS("Window") << "createContext: searching for a display mode, original aspect is " << mOriginalAspectRatio << LL_ENDL;
-
- for(i=0; i < resolutionCount; i++)
- {
- F32 aspect = (F32)resolutionList[i].mWidth / (F32)resolutionList[i].mHeight;
-
- LL_DEBUGS("Window") << "createContext: width " << resolutionList[i].mWidth << " height " << resolutionList[i].mHeight << " aspect " << aspect << LL_ENDL;
+// These functions are used as wrappers for our internal event handling callbacks.
+// It's a good idea to wrap these to avoid reworking more code than we need to within LLWindow.
- if( (resolutionList[i].mHeight >= 700) && (resolutionList[i].mHeight <= 800) &&
- (fabs(aspect - mOriginalAspectRatio) < fabs(closestAspect - mOriginalAspectRatio)))
- {
- LL_DEBUGS("Window") << " (new closest mode) " << LL_ENDL;
+bool callKeyUp(unsigned short key, unsigned int mask)
+{
+ return gKeyboard->handleKeyUp(key, mask);
+}
- // This is the closest mode we've seen yet.
- closestWidth = resolutionList[i].mWidth;
- closestHeight = resolutionList[i].mHeight;
- closestAspect = aspect;
- }
- }
+bool callKeyDown(unsigned short key, unsigned int mask)
+{
+ return gKeyboard->handleKeyDown(key, mask);
+}
- width = closestWidth;
- height = closestHeight;
- }
- }
+void callResetKeys()
+{
+ gKeyboard->resetKeys();
+}
- if((width == 0) || (height == 0))
- {
- // Mode search failed for some reason. Use the old-school default.
- width = 1024;
- height = 768;
- }
+bool callUnicodeCallback(wchar_t character, unsigned int mask)
+{
+ return gWindowImplementation->getCallbacks()->handleUnicodeChar(character, mask);
+}
- if (true)
- {
- // Fullscreen support
- CFDictionaryRef refDisplayMode = 0;
- boolean_t exactMatch = false;
-
-#if CAPTURE_ALL_DISPLAYS
- // Capture all displays (may want to do this for final build)
- CGCaptureAllDisplays ();
-#else
- // Capture only the main display (useful for debugging)
- CGDisplayCapture (mDisplay);
-#endif
+void callFocus()
+{
+ if (gWindowImplementation)
+ {
+ gWindowImplementation->getCallbacks()->handleFocus(gWindowImplementation);
+ }
+}
- // Switch the display to the desired resolution and refresh
- refDisplayMode = CGDisplayBestModeForParametersAndRefreshRate(
- mDisplay,
- BITS_PER_PIXEL,
- width,
- height,
- refresh,
- &exactMatch);
+void callFocusLost()
+{
+ gWindowImplementation->getCallbacks()->handleFocusLost(gWindowImplementation);
+}
- if (refDisplayMode)
- {
- LL_DEBUGS("Window") << "createContext: switching display resolution" << LL_ENDL;
- mOldDisplayMode = CGDisplayCurrentMode (mDisplay);
- CGDisplaySwitchToMode (mDisplay, refDisplayMode);
- // CFRelease(refDisplayMode);
+void callRightMouseDown(float *pos, MASK mask)
+{
+ if (gWindowImplementation->allowsLanguageInput())
+ {
+ gWindowImplementation->interruptLanguageTextInput();
+ }
+
+ LLCoordGL outCoords;
+ outCoords.mX = llround(pos[0]);
+ outCoords.mY = llround(pos[1]);
+ gWindowImplementation->getCallbacks()->handleRightMouseDown(gWindowImplementation, outCoords, gKeyboard->currentMask(TRUE));
+}
- AddEventTypesToHandler(mGlobalHandlerRef, GetEventTypeCount (GlobalHandlerEventList), GlobalHandlerEventList);
- }
+void callRightMouseUp(float *pos, MASK mask)
+{
+ if (gWindowImplementation->allowsLanguageInput())
+ {
+ gWindowImplementation->interruptLanguageTextInput();
+ }
+
+ LLCoordGL outCoords;
+ outCoords.mX = llround(pos[0]);
+ outCoords.mY = llround(pos[1]);
+ gWindowImplementation->getCallbacks()->handleRightMouseUp(gWindowImplementation, outCoords, gKeyboard->currentMask(TRUE));
+}
+void callLeftMouseDown(float *pos, MASK mask)
+{
+ if (gWindowImplementation->allowsLanguageInput())
+ {
+ gWindowImplementation->interruptLanguageTextInput();
+ }
+
+ LLCoordGL outCoords;
+ outCoords.mX = llround(pos[0]);
+ outCoords.mY = llround(pos[1]);
+ gWindowImplementation->getCallbacks()->handleMouseDown(gWindowImplementation, outCoords, gKeyboard->currentMask(TRUE));
+}
- mFullscreen = TRUE;
- mFullscreenWidth = CGDisplayPixelsWide(mDisplay);
- mFullscreenHeight = CGDisplayPixelsHigh(mDisplay);
- mFullscreenBits = CGDisplayBitsPerPixel(mDisplay);
- mFullscreenRefresh = llround(getDictDouble (CGDisplayCurrentMode (mDisplay), kCGDisplayRefreshRate));
+void callLeftMouseUp(float *pos, MASK mask)
+{
+ if (gWindowImplementation->allowsLanguageInput())
+ {
+ gWindowImplementation->interruptLanguageTextInput();
+ }
+
+ LLCoordGL outCoords;
+ outCoords.mX = llround(pos[0]);
+ outCoords.mY = llround(pos[1]);
+ gWindowImplementation->getCallbacks()->handleMouseUp(gWindowImplementation, outCoords, gKeyboard->currentMask(TRUE));
+
+}
- LL_INFOS("Window") << "Running at " << mFullscreenWidth
- << "x" << mFullscreenHeight
- << "x" << mFullscreenBits
- << " @ " << mFullscreenRefresh
- << LL_ENDL;
- }
- else
- {
- // No fullscreen support
- mFullscreen = FALSE;
- mFullscreenWidth = -1;
- mFullscreenHeight = -1;
- mFullscreenBits = -1;
- mFullscreenRefresh = -1;
-
- std::string error= llformat("Unable to run fullscreen at %d x %d.\nRunning in window.", width, height);
- OSMessageBox(error, "Error", OSMB_OK);
- }
- }
+void callDoubleClick(float *pos, MASK mask)
+{
+ if (gWindowImplementation->allowsLanguageInput())
+ {
+ gWindowImplementation->interruptLanguageTextInput();
+ }
+
+ LLCoordGL outCoords;
+ outCoords.mX = llround(pos[0]);
+ outCoords.mY = llround(pos[1]);
+ gWindowImplementation->getCallbacks()->handleDoubleClick(gWindowImplementation, outCoords, gKeyboard->currentMask(TRUE));
+}
- if(!mFullscreen && (mWindow == NULL))
+void callResize(unsigned int width, unsigned int height)
+{
+ if (gWindowImplementation != NULL)
{
- //int displayWidth = CGDisplayPixelsWide(mDisplay);
- //int displayHeight = CGDisplayPixelsHigh(mDisplay);
- //const int menuBarPlusTitleBar = 44; // Ugly magic number.
-
- LL_DEBUGS("Window") << "createContext: creating window" << LL_ENDL;
-
- mPreviousWindowRect.left = (long) x;
- mPreviousWindowRect.right = (long) x + width;
- mPreviousWindowRect.top = (long) y;
- mPreviousWindowRect.bottom = (long) y + height;
-
- //-----------------------------------------------------------------------
- // Create the window
- //-----------------------------------------------------------------------
- mWindow = NewCWindow(
- NULL,
- &mPreviousWindowRect,
- mWindowTitle,
- false, // Create the window invisible. Whoever calls createContext() should show it after any moving/resizing.
- // noGrowDocProc, // Window with no grow box and no zoom box
- zoomDocProc, // Window with a grow box and a zoom box
- // zoomNoGrow, // Window with a zoom box but no grow box
- kFirstWindowOfClass,
- true,
- (long)this);
+ gWindowImplementation->getCallbacks()->handleResize(gWindowImplementation, width, height);
+ }
+}
- if (!mWindow)
- {
- setupFailure("Window creation error", "Error", OSMB_OK);
- return FALSE;
- }
+void callMouseMoved(float *pos, MASK mask)
+{
+ LLCoordGL outCoords;
+ outCoords.mX = llround(pos[0]);
+ outCoords.mY = llround(pos[1]);
+ float deltas[2];
+ gWindowImplementation->getMouseDeltas(deltas);
+ outCoords.mX += deltas[0];
+ outCoords.mY += deltas[1];
+ gWindowImplementation->getCallbacks()->handleMouseMove(gWindowImplementation, outCoords, gKeyboard->currentMask(TRUE));
+ //gWindowImplementation->getCallbacks()->handleScrollWheel(gWindowImplementation, 0);
+}
- // Turn on live resize.
- // For this to work correctly, we need to be able to call LLViewerWindow::draw from
- // the event handler for kEventWindowBoundsChanged. It's not clear that we have access from here.
- // err = ChangeWindowAttributes(mWindow, kWindowLiveResizeAttribute, 0);
+void callScrollMoved(float delta)
+{
+ gWindowImplementation->getCallbacks()->handleScrollWheel(gWindowImplementation, delta);
+}
- // Set up window event handlers (some window-related events ONLY go to window handlers.)
- InstallStandardEventHandler(GetWindowEventTarget(mWindow));
- InstallWindowEventHandler(mWindow, mEventHandlerUPP, GetEventTypeCount (WindowHandlerEventList), WindowHandlerEventList, (void*)this, &mWindowHandlerRef); // add event handler
-#if LL_OS_DRAGDROP_ENABLED
- InstallTrackingHandler( dragTrackingHandler, mWindow, (void*)this );
- InstallReceiveHandler( dragReceiveHandler, mWindow, (void*)this );
-#endif // LL_OS_DRAGDROP_ENABLED
- }
+void callMouseExit()
+{
+ gWindowImplementation->getCallbacks()->handleMouseLeave(gWindowImplementation);
+}
+void callWindowFocus()
+{
+ if ( gWindowImplementation && gWindowImplementation->getCallbacks() )
{
- // Create and initialize our TSM document for language text input.
- // If an error occured, we can do nothing better than simply ignore it.
- // mTSMDocument will be kept NULL in case.
- if (mTSMDocument)
- {
- DeactivateTSMDocument(mTSMDocument);
- DeleteTSMDocument(mTSMDocument);
- mTSMDocument = NULL;
- }
- static InterfaceTypeList types = { kUnicodeDocument };
- err = NewTSMDocument(1, types, &mTSMDocument, 0);
- if (err != noErr)
- {
- LL_WARNS("Window") << "createContext: couldn't create a TSMDocument (" << err << ")" << LL_ENDL;
- }
- if (mTSMDocument)
- {
- ActivateTSMDocument(mTSMDocument);
- allowLanguageTextInput(NULL, FALSE);
- }
+ gWindowImplementation->getCallbacks()->handleFocus (gWindowImplementation);
}
-
- if(mContext == NULL)
+ else
{
- AGLRendererInfo rendererInfo = NULL;
+ LL_WARNS("COCOA") << "Window Implementation or callbacks not yet initialized." << LL_ENDL;
+ }
- //-----------------------------------------------------------------------
- // Create GL drawing context
- //-----------------------------------------------------------------------
- if(mPixelFormat == NULL)
- {
- if(mFullscreen)
- {
- GLint fullscreenAttrib[] =
- {
- AGL_RGBA,
- AGL_FULLSCREEN,
- AGL_NO_RECOVERY,
- AGL_SAMPLE_BUFFERS_ARB, mFSAASamples > 0 ? 1 : 0,
- AGL_SAMPLES_ARB, mFSAASamples,
- AGL_DOUBLEBUFFER,
- AGL_CLOSEST_POLICY,
- AGL_ACCELERATED,
- AGL_RED_SIZE, 8,
- AGL_GREEN_SIZE, 8,
- AGL_BLUE_SIZE, 8,
- AGL_ALPHA_SIZE, 8,
- AGL_DEPTH_SIZE, 24,
- AGL_STENCIL_SIZE, 8,
- AGL_NONE
- };
-
- LL_DEBUGS("Window") << "createContext: creating fullscreen pixelformat" << LL_ENDL;
-
- GDHandle gdhDisplay = NULL;
- err = DMGetGDeviceByDisplayID ((DisplayIDType)mDisplay, &gdhDisplay, false);
-
- mPixelFormat = aglChoosePixelFormat(&gdhDisplay, 1, fullscreenAttrib);
- rendererInfo = aglQueryRendererInfo(&gdhDisplay, 1);
- }
- else
- {
- // NOTE from Leslie:
- //
- // AGL_NO_RECOVERY, when combined with AGL_ACCELERATED prevents software rendering
- // fallback which means we won't hvae shaders that compile and link but then don't
- // work. The drawback is that our shader compilation will be a bit more finicky though.
+}
- GLint windowedAttrib[] =
- {
- AGL_RGBA,
- AGL_NO_RECOVERY,
- AGL_DOUBLEBUFFER,
- AGL_CLOSEST_POLICY,
- AGL_ACCELERATED,
- AGL_SAMPLE_BUFFERS_ARB, mFSAASamples > 0 ? 1 : 0,
- AGL_SAMPLES_ARB, mFSAASamples,
- AGL_RED_SIZE, 8,
- AGL_GREEN_SIZE, 8,
- AGL_BLUE_SIZE, 8,
- AGL_ALPHA_SIZE, 8,
- AGL_DEPTH_SIZE, 24,
- AGL_STENCIL_SIZE, 8,
- AGL_NONE
- };
-
- LL_DEBUGS("Window") << "createContext: creating windowed pixelformat" << LL_ENDL;
-
- mPixelFormat = aglChoosePixelFormat(NULL, 0, windowedAttrib);
-
- GDHandle gdhDisplay = GetMainDevice();
- rendererInfo = aglQueryRendererInfo(&gdhDisplay, 1);
- }
+void callWindowUnfocus()
+{
+ gWindowImplementation->getCallbacks()->handleFocusLost(gWindowImplementation);
+}
- // May want to get the real error text like this:
- // (char *) aglErrorString(aglGetError());
+void callDeltaUpdate(float *delta, MASK mask)
+{
+ gWindowImplementation->updateMouseDeltas(delta);
+}
- if(aglGetError() != AGL_NO_ERROR)
- {
- setupFailure("Can't find suitable pixel format", "Error", OSMB_OK);
- return FALSE;
- }
- }
+void callMiddleMouseDown(float *pos, MASK mask)
+{
+ LLCoordGL outCoords;
+ outCoords.mX = llround(pos[0]);
+ outCoords.mY = llround(pos[1]);
+ float deltas[2];
+ gWindowImplementation->getMouseDeltas(deltas);
+ outCoords.mX += deltas[0];
+ outCoords.mY += deltas[1];
+ gWindowImplementation->getCallbacks()->handleMiddleMouseDown(gWindowImplementation, outCoords, mask);
+}
- if(mPixelFormat)
- {
- LL_DEBUGS("Window") << "createContext: creating GL context" << LL_ENDL;
- mContext = aglCreateContext(mPixelFormat, NULL);
- }
+void callMiddleMouseUp(float *pos, MASK mask)
+{
+ LLCoordGL outCoords;
+ outCoords.mX = llround(pos[0]);
+ outCoords.mY = llround(pos[1]);
+ float deltas[2];
+ gWindowImplementation->getMouseDeltas(deltas);
+ outCoords.mX += deltas[0];
+ outCoords.mY += deltas[1];
+ gWindowImplementation->getCallbacks()->handleMiddleMouseUp(gWindowImplementation, outCoords, mask);
+}
- if(mContext == NULL)
- {
- setupFailure("Can't make GL context", "Error", OSMB_OK);
- return FALSE;
- }
+void callModifier(MASK mask)
+{
+ gKeyboard->handleModifier(mask);
+}
- gGLManager.mVRAM = 0;
+void callHandleDragEntered(std::string url)
+{
+ gWindowImplementation->handleDragNDrop(url, LLWindowCallbacks::DNDA_START_TRACKING);
+}
- if(rendererInfo != NULL)
- {
- GLint result;
+void callHandleDragExited(std::string url)
+{
+ gWindowImplementation->handleDragNDrop(url, LLWindowCallbacks::DNDA_STOP_TRACKING);
+}
- if(aglDescribeRenderer(rendererInfo, AGL_VIDEO_MEMORY, &result))
- {
- // llinfos << "createContext: aglDescribeRenderer(AGL_VIDEO_MEMORY) returned " << result << llendl;
- gGLManager.mVRAM = result / (1024 * 1024);
- }
- else
- {
- // llinfos << "createContext: aglDescribeRenderer(AGL_VIDEO_MEMORY) failed." << llendl;
- }
+void callHandleDragUpdated(std::string url)
+{
+ gWindowImplementation->handleDragNDrop(url, LLWindowCallbacks::DNDA_TRACK);
+}
- // This could be useful at some point, if it takes into account the memory already used by screen buffers, etc...
- if(aglDescribeRenderer(rendererInfo, AGL_TEXTURE_MEMORY, &result))
- {
- // llinfos << "createContext: aglDescribeRenderer(AGL_TEXTURE_MEMORY) returned " << result << llendl;
- }
- else
- {
- // llinfos << "createContext: aglDescribeRenderer(AGL_TEXTURE_MEMORY) failed." << llendl;
- }
+void callHandleDragDropped(std::string url)
+{
+ gWindowImplementation->handleDragNDrop(url, LLWindowCallbacks::DNDA_DROPPED);
+}
- aglDestroyRendererInfo(rendererInfo);
+void callQuitHandler()
+{
+ if (gWindowImplementation)
+ {
+ if(gWindowImplementation->getCallbacks()->handleCloseRequest(gWindowImplementation))
+ {
+ gWindowImplementation->getCallbacks()->handleQuit(gWindowImplementation);
}
-
- // Since we just created the context, it needs to be set up.
- glNeedsInit = TRUE;
}
+}
- // Hook up the context to a drawable
- if (mFullscreen && (mOldDisplayMode != NULL))
+void getPreeditSelectionRange(int *position, int *length)
+{
+ if (gWindowImplementation->getPreeditor())
{
- // We successfully captured the display. Use a fullscreen drawable
-
- LL_DEBUGS("Window") << "createContext: attaching fullscreen drawable" << LL_ENDL;
-
-#if CAPTURE_ALL_DISPLAYS
- // Capture all displays (may want to do this for final build)
- aglDisable (mContext, AGL_FS_CAPTURE_SINGLE);
-#else
- // Capture only the main display (useful for debugging)
- aglEnable (mContext, AGL_FS_CAPTURE_SINGLE);
-#endif
-
- if (!aglSetFullScreen (mContext, 0, 0, 0, 0))
- {
- setupFailure("Can't set GL fullscreen", "Error", OSMB_OK);
- return FALSE;
- }
+ gWindowImplementation->getPreeditor()->getSelectionRange(position, length);
}
- else if(!mFullscreen && (mWindow != NULL))
+}
+
+void getPreeditMarkedRange(int *position, int *length)
+{
+ if (gWindowImplementation->getPreeditor())
{
- LL_DEBUGS("Window") << "createContext: attaching windowed drawable" << LL_ENDL;
+ gWindowImplementation->getPreeditor()->getPreeditRange(position, length);
+ }
+}
- // We created a window. Use it as the drawable.
- if(!aglSetDrawable(mContext, GetWindowPort (mWindow)))
- {
- setupFailure("Can't set GL drawable", "Error", OSMB_OK);
- return FALSE;
- }
+void setPreeditMarkedRange(int position, int length)
+{
+ if (gWindowImplementation->getPreeditor())
+ {
+ gWindowImplementation->getPreeditor()->markAsPreedit(position, length);
}
- else
+}
+
+bool handleUnicodeCharacter(wchar_t c)
+{
+ bool success = false;
+ if (gWindowImplementation->getPreeditor())
{
- setupFailure("Can't get fullscreen or windowed drawable.", "Error", OSMB_OK);
- return FALSE;
+ success = gWindowImplementation->getPreeditor()->handleUnicodeCharHere(c);
}
+
+ return success;
+}
- if(mContext != NULL)
+void resetPreedit()
+{
+ if (gWindowImplementation->getPreeditor())
{
- LL_DEBUGS("Window") << "createContext: setting current context" << LL_ENDL;
+ gWindowImplementation->getPreeditor()->resetPreedit();
+ }
+}
- if (!aglSetCurrentContext(mContext))
+// For reasons of convenience, handle IME updates here.
+// This largely mirrors the old implementation, only sans the carbon parameters.
+void setMarkedText(unsigned short *unitext, unsigned int *selectedRange, unsigned int *replacementRange, long text_len, attributedStringInfo segments)
+{
+ if (gWindowImplementation->getPreeditor())
+ {
+ LLPreeditor *preeditor = gWindowImplementation->getPreeditor();
+ preeditor->resetPreedit();
+ // This should be a viable replacement for the kEventParamTextInputSendReplaceRange parameter.
+ if (replacementRange[0] < replacementRange[1])
{
- setupFailure("Can't activate GL rendering context", "Error", OSMB_OK);
- return FALSE;
+ const LLWString& text = preeditor->getPreeditString();
+ const S32 location = wstring_wstring_length_from_utf16_length(text, 0, replacementRange[0]);
+ const S32 length = wstring_wstring_length_from_utf16_length(text, location, replacementRange[1]);
+ preeditor->markAsPreedit(location, length);
}
+
+ LLWString fix_str = utf16str_to_wstring(llutf16string(unitext, text_len));
+
+ S32 caret_position = fix_str.length();
+
+ preeditor->updatePreedit(fix_str, segments.seg_lengths, segments.seg_standouts, caret_position);
}
+}
- if(glNeedsInit)
+void getPreeditLocation(float *location, unsigned int length)
+{
+ if (gWindowImplementation->getPreeditor())
{
- // Check for some explicitly unsupported cards.
- const char* RENDERER = (const char*) glGetString(GL_RENDERER);
-
- const char* CARD_LIST[] =
- { "RAGE 128",
- "RIVA TNT2",
- "Intel 810",
- "3Dfx/Voodoo3",
- "Radeon 7000",
- "Radeon 7200",
- "Radeon 7500",
- "Radeon DDR",
- "Radeon VE",
- "GDI Generic" };
- const S32 CARD_COUNT = LL_ARRAY_SIZE(CARD_LIST);
-
- // Future candidates:
- // ProSavage/Twister
- // SuperSavage
+ LLPreeditor *preeditor = gWindowImplementation->getPreeditor();
+ LLCoordGL coord;
+ LLCoordScreen screen;
+ LLRect rect;
+
+ preeditor->getPreeditLocation(length, &coord, &rect, NULL);
+
+ float c[4] = {coord.mX, coord.mY, 0, 0};
+
+ convertRectToScreen(gWindowImplementation->getWindow(), c);
+
+ location[0] = c[0];
+ location[1] = c[1];
+ }
+}
- S32 i;
- for (i = 0; i < CARD_COUNT; i++)
+void LLWindowMacOSX::updateMouseDeltas(float* deltas)
+{
+ if (mCursorDecoupled)
+ {
+ mCursorLastEventDeltaX = llround(deltas[0]);
+ mCursorLastEventDeltaY = llround(-deltas[1]);
+
+ if (mCursorIgnoreNextDelta)
{
- if (check_for_card(RENDERER, CARD_LIST[i]))
- {
- close();
- return FALSE;
- }
+ mCursorLastEventDeltaX = 0;
+ mCursorLastEventDeltaY = 0;
+ mCursorIgnoreNextDelta = FALSE;
}
+ } else {
+ mCursorLastEventDeltaX = 0;
+ mCursorLastEventDeltaY = 0;
}
+}
- GLint colorBits, alphaBits, depthBits, stencilBits;
+void LLWindowMacOSX::getMouseDeltas(float* delta)
+{
+ delta[0] = mCursorLastEventDeltaX;
+ delta[1] = mCursorLastEventDeltaY;
+}
- if( !aglDescribePixelFormat(mPixelFormat, AGL_BUFFER_SIZE, &colorBits) ||
- !aglDescribePixelFormat(mPixelFormat, AGL_ALPHA_SIZE, &alphaBits) ||
- !aglDescribePixelFormat(mPixelFormat, AGL_DEPTH_SIZE, &depthBits) ||
- !aglDescribePixelFormat(mPixelFormat, AGL_STENCIL_SIZE, &stencilBits))
+BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits, BOOL fullscreen, BOOL disable_vsync)
+{
+ BOOL glNeedsInit = FALSE;
+
+ mFullscreen = fullscreen;
+
+ if (mWindow == NULL)
{
- close();
- setupFailure("Can't get pixel format description", "Error", OSMB_OK);
- return FALSE;
+ mWindow = getMainAppWindow();
}
- LL_INFOS("GLInit") << "GL buffer: Color Bits " << S32(colorBits)
- << " Alpha Bits " << S32(alphaBits)
- << " Depth Bits " << S32(depthBits)
- << " Stencil Bits" << S32(stencilBits)
- << LL_ENDL;
-
- if (colorBits < 32)
+ if(mContext == NULL)
{
- close();
- setupFailure(
- "Second Life requires True Color (32-bit) to run in a window.\n"
- "Please go to Control Panels -> Display -> Settings and\n"
- "set the screen to 32-bit color.\n"
- "Alternately, if you choose to run fullscreen, Second Life\n"
- "will automatically adjust the screen each time it runs.",
- "Error",
- OSMB_OK);
- return FALSE;
+ // Our OpenGL view is already defined within SecondLife.xib.
+ // Get the view instead.
+ mGLView = createOpenGLView(mWindow, mFSAASamples, !disable_vsync);
+ mContext = getCGLContextObj(mGLView);
+
+ // Since we just created the context, it needs to be set up.
+ glNeedsInit = TRUE;
+
+ gGLManager.mVRAM = getVramSize(mGLView);
}
+
+ // This sets up our view to recieve text from our non-inline text input window.
+ setupInputWindow(mWindow, mGLView);
+
+ // Hook up the context to a drawable
- if (alphaBits < 8)
+ if(mContext != NULL)
{
- close();
- setupFailure(
- "Second Life is unable to run because it can't get an 8 bit alpha\n"
- "channel. Usually this is due to video card driver issues.\n"
- "Please make sure you have the latest video card drivers installed.\n"
- "Also be sure your monitor is set to True Color (32-bit) in\n"
- "Control Panels -> Display -> Settings.\n"
- "If you continue to receive this message, contact customer service.",
- "Error",
- OSMB_OK);
- return FALSE;
+
+
+ U32 err = CGLSetCurrentContext(mContext);
+ if (err != kCGLNoError)
+ {
+ setupFailure("Can't activate GL rendering context", "Error", OSMB_OK);
+ return FALSE;
+ }
}
// Disable vertical sync for swap
GLint frames_per_swap = 0;
if (disable_vsync)
{
- LL_DEBUGS("GLInit") << "Disabling vertical sync" << LL_ENDL;
frames_per_swap = 0;
}
else
{
- LL_DEBUGS("GLinit") << "Keeping vertical sync" << LL_ENDL;
frames_per_swap = 1;
}
- aglSetInteger(mContext, AGL_SWAP_INTERVAL, &frames_per_swap);
+
+ CGLSetParameter(mContext, kCGLCPSwapInterval, &frames_per_swap);
//enable multi-threaded OpenGL
if (sUseMultGL)
@@ -809,109 +597,17 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits
LL_DEBUGS("GLInit") << "Multi-threaded OpenGL enabled." << LL_ENDL;
}
}
-
- // Don't need to get the current gamma, since there's a call that restores it to the system defaults.
+ makeFirstResponder(mWindow, mGLView);
+
return TRUE;
}
-// changing fullscreen resolution, or switching between windowed and fullscreen mode.
+// We only support OS X 10.7's fullscreen app mode which is literally a full screen window that fills a virtual desktop.
+// This makes this method obsolete.
BOOL LLWindowMacOSX::switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL disable_vsync, const LLCoordScreen * const posp)
{
- BOOL needsRebuild = FALSE;
- BOOL result = true;
-
- if(fullscreen)
- {
- if(mFullscreen)
- {
- // Switching resolutions in fullscreen mode. Don't need to rebuild for this.
- // Fullscreen support
- CFDictionaryRef refDisplayMode = 0;
- boolean_t exactMatch = false;
-
- // Switch the display to the desired resolution and refresh
- refDisplayMode = CGDisplayBestModeForParametersAndRefreshRate(
- mDisplay,
- BITS_PER_PIXEL,
- size.mX,
- size.mY,
- getDictDouble (CGDisplayCurrentMode (mDisplay), kCGDisplayRefreshRate),
- &exactMatch);
-
- if (refDisplayMode)
- {
- CGDisplaySwitchToMode (mDisplay, refDisplayMode);
- // CFRelease(refDisplayMode);
- }
-
- mFullscreenWidth = CGDisplayPixelsWide(mDisplay);
- mFullscreenHeight = CGDisplayPixelsHigh(mDisplay);
- mFullscreenBits = CGDisplayBitsPerPixel(mDisplay);
- mFullscreenRefresh = llround(getDictDouble (CGDisplayCurrentMode (mDisplay), kCGDisplayRefreshRate));
-
- LL_INFOS("Window") << "Switched resolution to " << mFullscreenWidth
- << "x" << mFullscreenHeight
- << "x" << mFullscreenBits
- << " @ " << mFullscreenRefresh
- << LL_ENDL;
-
- // Update the GL context to the new screen size
- if (!aglUpdateContext(mContext))
- {
- setupFailure("Can't set GL fullscreen", "Error", OSMB_OK);
- result = FALSE;
- }
- }
- else
- {
- // Switching from windowed to fullscreen
- needsRebuild = TRUE;
- }
- }
- else
- {
- if(mFullscreen)
- {
- // Switching from fullscreen to windowed
- needsRebuild = TRUE;
- }
- else
- {
- // Windowed to windowed -- not sure why we would be called like this. Just change the window size.
- // The bounds changed event handler will do the rest.
- if(mWindow != NULL)
- {
- ::SizeWindow(mWindow, size.mX, size.mY, true);
- }
- }
- }
-
- stop_glerror();
- if(needsRebuild || mForceRebuild)
- {
- mForceRebuild = FALSE;
- destroyContext();
- result = createContext(0, 0, size.mX, size.mY, 0, fullscreen, disable_vsync);
- if (result)
- {
- if(mWindow != NULL)
- {
- MacShowWindow(mWindow);
- BringToFront(mWindow);
- }
-
- llverify(gGLManager.initGL());
-
- //start with arrow cursor
- initCursors();
- setCursor( UI_CURSOR_ARROW );
- }
- }
-
- stop_glerror();
-
- return result;
+ return FALSE;
}
void LLWindowMacOSX::destroyContext()
@@ -925,32 +621,7 @@ void LLWindowMacOSX::destroyContext()
if(mContext != NULL)
{
LL_DEBUGS("Window") << "destroyContext: unhooking drawable " << LL_ENDL;
-
- aglSetCurrentContext (NULL);
- aglSetDrawable(mContext, NULL);
- }
-
- // Make sure the display resolution gets restored
- if(mOldDisplayMode != NULL)
- {
- LL_DEBUGS("Window") << "destroyContext: restoring display resolution " << LL_ENDL;
-
- CGDisplaySwitchToMode (mDisplay, mOldDisplayMode);
-
-#if CAPTURE_ALL_DISPLAYS
- // Uncapture all displays (may want to do this for final build)
- CGReleaseAllDisplays ();
-#else
- // Uncapture only the main display (useful for debugging)
- CGDisplayRelease (mDisplay);
-#endif
-
- // CFRelease(mOldDisplayMode);
-
- mOldDisplayMode = NULL;
-
- // Remove the global event handlers the fullscreen case needed
- RemoveEventTypesFromHandler(mGlobalHandlerRef, GetEventTypeCount (GlobalHandlerEventList), GlobalHandlerEventList);
+ CGLSetCurrentContext(NULL);
}
// Clean up remaining GL state before blowing away window
@@ -959,49 +630,29 @@ void LLWindowMacOSX::destroyContext()
// Clean up the pixel format
if(mPixelFormat != NULL)
{
- LL_DEBUGS("Window") << "destroyContext: destroying pixel format " << LL_ENDL;
- aglDestroyPixelFormat(mPixelFormat);
+ CGLDestroyPixelFormat(mPixelFormat);
mPixelFormat = NULL;
}
- // Remove any Carbon Event handlers we installed
- if(mGlobalHandlerRef != NULL)
- {
- LL_DEBUGS("Window") << "destroyContext: removing global event handler" << LL_ENDL;
- RemoveEventHandler(mGlobalHandlerRef);
- mGlobalHandlerRef = NULL;
- }
-
- if(mWindowHandlerRef != NULL)
+ // Clean up the GL context
+ if(mContext != NULL)
{
- LL_DEBUGS("Window") << "destroyContext: removing window event handler" << LL_ENDL;
- RemoveEventHandler(mWindowHandlerRef);
- mWindowHandlerRef = NULL;
+ CGLDestroyContext(mContext);
}
-
- // Cleanup any TSM document we created.
- if(mTSMDocument != NULL)
+
+ // Destroy our LLOpenGLView
+ if(mGLView != NULL)
{
- LL_DEBUGS("Window") << "destroyContext: deleting TSM document" << LL_ENDL;
- DeactivateTSMDocument(mTSMDocument);
- DeleteTSMDocument(mTSMDocument);
- mTSMDocument = NULL;
+ removeGLView(mGLView);
+ mGLView = NULL;
}
-
+
// Close the window
if(mWindow != NULL)
{
- LL_DEBUGS("Window") << "destroyContext: disposing window" << LL_ENDL;
- DisposeWindow(mWindow);
- mWindow = NULL;
- }
-
- // Clean up the GL context
- if(mContext != NULL)
- {
- LL_DEBUGS("Window") << "destroyContext: destroying GL context" << LL_ENDL;
- aglDestroyContext(mContext);
- mContext = NULL;
+ NSWindowRef dead_window = mWindow;
+ mWindow = NULL;
+ closeWindow(dead_window);
}
}
@@ -1022,17 +673,11 @@ LLWindowMacOSX::~LLWindowMacOSX()
void LLWindowMacOSX::show()
{
- if(IsWindowCollapsed(mWindow))
- CollapseWindow(mWindow, false);
-
- MacShowWindow(mWindow);
- BringToFront(mWindow);
}
void LLWindowMacOSX::hide()
{
setMouseClipping(FALSE);
- HideWindow(mWindow);
}
//virtual
@@ -1040,7 +685,6 @@ void LLWindowMacOSX::minimize()
{
setMouseClipping(FALSE);
showCursor();
- CollapseWindow(mWindow, true);
}
//virtual
@@ -1086,7 +730,6 @@ BOOL LLWindowMacOSX::getVisible()
result = TRUE;
}if (mWindow)
{
- if(MacIsWindowVisible(mWindow))
result = TRUE;
}
@@ -1107,7 +750,6 @@ BOOL LLWindowMacOSX::maximize()
{
if (mWindow && !mMaximized)
{
- ZoomWindow(mWindow, inContent, true);
}
return mMaximized;
@@ -1120,58 +762,13 @@ BOOL LLWindowMacOSX::getFullscreen()
void LLWindowMacOSX::gatherInput()
{
- // stop bouncing icon after fixed period of time
- if (mBounceTimer.getStarted() && mBounceTimer.getElapsedTimeF32() > mBounceTime)
- {
- stopDockTileBounce();
- }
-
- // Use the old-school version so we get AppleEvent handler dispatch and menuselect handling.
- // Anything that has an event handler will get processed inside WaitNextEvent, so we only need to handle
- // the odd stuff here.
- EventRecord evt;
- while(WaitNextEvent(everyEvent, &evt, 0, NULL))
- {
- // printf("WaitNextEvent returned true, event is %d.\n", evt.what);
- switch(evt.what)
- {
- case mouseDown:
- {
- short part;
- WindowRef window;
- long selectResult;
- part = FindWindow(evt.where, &window);
- switch ( part )
- {
- case inMenuBar:
- selectResult = MenuSelect(evt.where);
-
- HiliteMenu(0);
- break;
- }
- }
- break;
-
- case kHighLevelEvent:
- AEProcessAppleEvent (&evt);
- break;
-
- case updateEvt:
- // We shouldn't be getting these regularly (since our window will be buffered), but we need to handle them correctly...
- BeginUpdate((WindowRef)evt.message);
- EndUpdate((WindowRef)evt.message);
- break;
-
- }
- }
-
updateCursor();
}
BOOL LLWindowMacOSX::getPosition(LLCoordScreen *position)
{
- Rect window_rect;
- OSStatus err = -1;
+ float rect[4];
+ S32 err = -1;
if(mFullscreen)
{
@@ -1181,10 +778,10 @@ BOOL LLWindowMacOSX::getPosition(LLCoordScreen *position)
}
else if(mWindow)
{
- err = GetWindowBounds(mWindow, kWindowContentRgn, &window_rect);
+ getContentViewBounds(mWindow, rect);
- position->mX = window_rect.left;
- position->mY = window_rect.top;
+ position->mX = rect[0];
+ position->mY = rect[1];
}
else
{
@@ -1196,8 +793,8 @@ BOOL LLWindowMacOSX::getPosition(LLCoordScreen *position)
BOOL LLWindowMacOSX::getSize(LLCoordScreen *size)
{
- Rect window_rect;
- OSStatus err = -1;
+ float rect[4];
+ S32 err = -1;
if(mFullscreen)
{
@@ -1207,10 +804,10 @@ BOOL LLWindowMacOSX::getSize(LLCoordScreen *size)
}
else if(mWindow)
{
- err = GetWindowBounds(mWindow, kWindowContentRgn, &window_rect);
+ getContentViewBounds(mWindow, rect);
- size->mX = window_rect.right - window_rect.left;
- size->mY = window_rect.bottom - window_rect.top;
+ size->mX = rect[2];
+ size->mY = rect[3];
}
else
{
@@ -1222,9 +819,9 @@ BOOL LLWindowMacOSX::getSize(LLCoordScreen *size)
BOOL LLWindowMacOSX::getSize(LLCoordWindow *size)
{
- Rect window_rect;
- OSStatus err = -1;
-
+ float rect[4];
+ S32 err = -1;
+
if(mFullscreen)
{
size->mX = mFullscreenWidth;
@@ -1233,16 +830,16 @@ BOOL LLWindowMacOSX::getSize(LLCoordWindow *size)
}
else if(mWindow)
{
- err = GetWindowBounds(mWindow, kWindowContentRgn, &window_rect);
-
- size->mX = window_rect.right - window_rect.left;
- size->mY = window_rect.bottom - window_rect.top;
+ getContentViewBounds(mWindow, rect);
+
+ size->mX = rect[2];
+ size->mY = rect[3];
}
else
{
llerrs << "LLWindowMacOSX::getPosition(): no window and not fullscreen!" << llendl;
}
-
+
return (err == noErr);
}
@@ -1250,7 +847,8 @@ BOOL LLWindowMacOSX::setPosition(const LLCoordScreen position)
{
if(mWindow)
{
- MacMoveWindow(mWindow, position.mX, position.mY, false);
+ float pos[2] = {position.mX, position.mY};
+ setWindowPos(mWindow, pos);
}
return TRUE;
@@ -1260,45 +858,35 @@ BOOL LLWindowMacOSX::setSizeImpl(const LLCoordScreen size)
{
if(mWindow)
{
- SizeWindow(mWindow, size.mX, size.mY, true);
+ LLCoordWindow to;
+ convertCoords(size, &to);
+ setWindowSize(mWindow, to.mX, to.mY);
+ return TRUE;
}
- return TRUE;
+ return FALSE;
}
BOOL LLWindowMacOSX::setSizeImpl(const LLCoordWindow size)
{
- Rect client_rect;
if (mWindow)
{
- OSStatus err = GetWindowBounds(mWindow, kWindowContentRgn, &client_rect);
- if (err == noErr)
- {
- client_rect.right = client_rect.left + size.mX;
- client_rect.bottom = client_rect.top + size.mY;
- err = SetWindowBounds(mWindow, kWindowContentRgn, &client_rect);
- }
- if (err == noErr)
- {
- return TRUE;
- }
- else
- {
- llinfos << "Error setting size" << err << llendl;
- return FALSE;
- }
+ const int titlePadding = 22;
+ setWindowSize(mWindow, size.mX, size.mY + titlePadding);
+ return TRUE;
}
+
return FALSE;
}
void LLWindowMacOSX::swapBuffers()
{
- aglSwapBuffers(mContext);
+ CGLFlushDrawable(mContext);
}
F32 LLWindowMacOSX::getGamma()
{
- F32 result = 1.8; // Default to something sane
+ F32 result = 2.2; // Default to something sane
CGGammaValue redMin;
CGGammaValue redMax;
@@ -1454,39 +1042,15 @@ BOOL LLWindowMacOSX::setCursorPosition(const LLCoordWindow position)
return result;
}
-static void fixOrigin(void)
-{
- GrafPtr port;
- Rect portrect;
-
- ::GetPort(&port);
- ::GetPortBounds(port, &portrect);
- if((portrect.left != 0) || (portrect.top != 0))
- {
- // Mozilla sometimes changes our port origin.
- ::SetOrigin(0,0);
- }
-}
-
BOOL LLWindowMacOSX::getCursorPosition(LLCoordWindow *position)
{
- Point cursor_point;
+ float cursor_point[2];
LLCoordScreen screen_pos;
- GrafPtr save;
if(mWindow == NULL)
return FALSE;
-
- ::GetPort(&save);
- ::SetPort(GetWindowPort(mWindow));
- fixOrigin();
-
- // gets the mouse location in local coordinates
- ::GetMouse(&cursor_point);
-
-// lldebugs << "getCursorPosition(): cursor is at " << cursor_point.h << ", " << cursor_point.v << " port origin: " << portrect.left << ", " << portrect.top << llendl;
-
- ::SetPort(save);
+
+ getCursorPos(mWindow, cursor_point);
if(mCursorDecoupled)
{
@@ -1499,12 +1063,12 @@ BOOL LLWindowMacOSX::getCursorPosition(LLCoordWindow *position)
// CGGetLastMouseDelta may behave strangely when the cursor's first captured.
// Stash in the event handler instead.
- cursor_point.h += mCursorLastEventDeltaX;
- cursor_point.v += mCursorLastEventDeltaY;
+ cursor_point[0] += mCursorLastEventDeltaX;
+ cursor_point[1] += mCursorLastEventDeltaY;
}
- position->mX = cursor_point.h;
- position->mY = cursor_point.v;
+ position->mX = cursor_point[0];
+ position->mY = cursor_point[1];
return TRUE;
}
@@ -1521,7 +1085,6 @@ void LLWindowMacOSX::adjustCursorDecouple(bool warpingMouse)
// llinfos << "adjustCursorDecouple: decoupling cursor" << llendl;
CGAssociateMouseAndMouseCursorPosition(false);
mCursorDecoupled = true;
- FlushSpecificEventsFromQueue(GetCurrentEventQueue(), mMoveEventCampartorUPP, NULL);
mCursorIgnoreNextDelta = TRUE;
}
}
@@ -1568,179 +1131,46 @@ F32 LLWindowMacOSX::getPixelAspectRatio()
// MBW -- XXX -- There's got to be a better way than this. Find it, please...
+// Since we're no longer supporting the "typical" fullscreen mode with CGL or NSOpenGL anymore, these are unnecessary. -Geenz
void LLWindowMacOSX::beforeDialog()
{
- if(mFullscreen)
- {
-
-#if CAPTURE_ALL_DISPLAYS
- // Uncapture all displays (may want to do this for final build)
- CGReleaseAllDisplays ();
-#else
- // Uncapture only the main display (useful for debugging)
- CGDisplayRelease (mDisplay);
-#endif
- // kDocumentWindowClass
- // kMovableModalWindowClass
- // kAllWindowClasses
-
- // GLint order = 0;
- // aglSetInteger(mContext, AGL_ORDER_CONTEXT_TO_FRONT, &order);
- aglSetDrawable(mContext, NULL);
- // GetWindowGroupLevel(GetWindowGroupOfClass(kAllWindowClasses), &oldWindowLevel);
- // SetWindowGroupLevel(GetWindowGroupOfClass(kAllWindowClasses), CGShieldingWindowLevel());
-
- mHandsOffEvents = TRUE;
-
- }
}
void LLWindowMacOSX::afterDialog()
{
- if(mFullscreen)
- {
- mHandsOffEvents = FALSE;
-
- // SetWindowGroupLevel(GetWindowGroupOfClass(kAllWindowClasses), oldWindowLevel);
- aglSetFullScreen(mContext, 0, 0, 0, 0);
- // GLint order = 1;
- // aglSetInteger(mContext, AGL_ORDER_CONTEXT_TO_FRONT, &order);
-
-#if CAPTURE_ALL_DISPLAYS
- // Capture all displays (may want to do this for final build)
- CGCaptureAllDisplays ();
-#else
- // Capture only the main display (useful for debugging)
- CGDisplayCapture (mDisplay);
-#endif
- }
}
void LLWindowMacOSX::flashIcon(F32 seconds)
{
- // Don't do this if we're already started, since this would try to install the NMRec twice.
- if(!mBounceTimer.getStarted())
- {
- OSErr err;
-
- mBounceTime = seconds;
- memset(&mBounceRec, 0, sizeof(mBounceRec));
- mBounceRec.qType = nmType;
- mBounceRec.nmMark = 1;
- err = NMInstall(&mBounceRec);
- if(err == noErr)
- {
- mBounceTimer.start();
- }
- else
- {
- // This is very not-fatal (only problem is the icon will not bounce), but we'd like to find out about it somehow...
- llinfos << "NMInstall failed with error code " << err << llendl;
- }
- }
+ // For consistency with OS X conventions, the number of seconds given is ignored and
+ // left up to the OS (which will actually bounce it for one second).
+ requestUserAttention();
}
BOOL LLWindowMacOSX::isClipboardTextAvailable()
{
- OSStatus err;
- ScrapRef scrap;
- ScrapFlavorFlags flags;
- BOOL result = false;
-
- err = GetCurrentScrap(&scrap);
-
- if(err == noErr)
- {
- err = GetScrapFlavorFlags(scrap, kScrapFlavorTypeUnicode, &flags);
- }
-
- if(err == noErr)
- result = true;
-
- return result;
+ return pasteBoardAvailable();
}
BOOL LLWindowMacOSX::pasteTextFromClipboard(LLWString &dst)
-{
- OSStatus err;
- ScrapRef scrap;
- Size len;
- BOOL result = false;
-
- err = GetCurrentScrap(&scrap);
-
- if(err == noErr)
+{
+ llutf16string str(copyFromPBoard());
+ dst = utf16str_to_wstring(str);
+ if (dst != L"")
{
- err = GetScrapFlavorSize(scrap, kScrapFlavorTypeUnicode, &len);
- }
-
- if((err == noErr) && (len > 0))
- {
- int u16len = len / sizeof(U16);
- U16 *temp = new U16[u16len + 1];
- if (temp)
- {
- memset(temp, 0, (u16len + 1) * sizeof(temp[0]));
- err = GetScrapFlavorData(scrap, kScrapFlavorTypeUnicode, &len, temp);
- if (err == noErr)
- {
- // convert \r\n to \n and \r to \n in the incoming text.
- U16 *s, *d;
- for(s = d = temp; s[0] != '\0'; s++, d++)
- {
- if(s[0] == '\r')
- {
- if(s[1] == '\n')
- {
- // CRLF, a.k.a. DOS newline. Collapse to a single '\n'.
- s++;
- }
-
- d[0] = '\n';
- }
- else
- {
- d[0] = s[0];
- }
- }
-
- d[0] = '\0';
-
- dst = utf16str_to_wstring(temp);
-
- result = true;
- }
- delete[] temp;
- }
+ return true;
+ } else {
+ return false;
}
-
- return result;
}
BOOL LLWindowMacOSX::copyTextToClipboard(const LLWString &s)
{
- OSStatus err;
- ScrapRef scrap;
- //Size len;
- //char *temp;
BOOL result = false;
-
- if (!s.empty())
- {
- err = GetCurrentScrap(&scrap);
- if (err == noErr)
- err = ClearScrap(&scrap);
-
- if (err == noErr)
- {
- llutf16string utf16str = wstring_to_utf16str(s);
- size_t u16len = utf16str.length() * sizeof(U16);
- err = PutScrapFlavor(scrap, kScrapFlavorTypeUnicode, kScrapFlavorMaskNone, u16len, utf16str.data());
- if (err == noErr)
- result = true;
- }
- }
+ llutf16string utf16str = wstring_to_utf16str(s);
+
+ result = copyToPBoard(utf16str.data(), utf16str.length());
return result;
}
@@ -1806,122 +1236,52 @@ LLWindow::LLWindowResolution* LLWindowMacOSX::getSupportedResolutions(S32 &num_r
BOOL LLWindowMacOSX::convertCoords(LLCoordGL from, LLCoordWindow *to)
{
- S32 client_height;
- Rect client_rect;
-
- if(mFullscreen)
- {
- // In the fullscreen case, the "window" is the entire screen.
- client_rect.left = 0;
- client_rect.top = 0;
- client_rect.right = mFullscreenWidth;
- client_rect.bottom = mFullscreenHeight;
- }
- else if (!mWindow ||
- (GetWindowBounds(mWindow, kWindowContentRgn, &client_rect) != noErr) ||
- NULL == to)
- {
- return FALSE;
- }
-
to->mX = from.mX;
- client_height = client_rect.bottom - client_rect.top;
- to->mY = client_height - from.mY - 1;
-
+ to->mY = from.mY;
return TRUE;
}
BOOL LLWindowMacOSX::convertCoords(LLCoordWindow from, LLCoordGL* to)
{
- S32 client_height;
- Rect client_rect;
-
- if(mFullscreen)
- {
- // In the fullscreen case, the "window" is the entire screen.
- client_rect.left = 0;
- client_rect.top = 0;
- client_rect.right = mFullscreenWidth;
- client_rect.bottom = mFullscreenHeight;
- }
- else if (!mWindow ||
- (GetWindowBounds(mWindow, kWindowContentRgn, &client_rect) != noErr) ||
- NULL == to)
- {
- return FALSE;
- }
-
to->mX = from.mX;
- client_height = client_rect.bottom - client_rect.top;
- to->mY = client_height - from.mY - 1;
-
+ to->mY = from.mY;
return TRUE;
}
BOOL LLWindowMacOSX::convertCoords(LLCoordScreen from, LLCoordWindow* to)
{
- if(mFullscreen)
- {
- // In the fullscreen case, window and screen coordinates are the same.
- to->mX = from.mX;
- to->mY = from.mY;
- return TRUE;
- }
- else if(mWindow)
+ if(mWindow)
{
- GrafPtr save;
- Point mouse_point;
-
- mouse_point.h = from.mX;
- mouse_point.v = from.mY;
+ float mouse_point[2];
- ::GetPort(&save);
- ::SetPort(GetWindowPort(mWindow));
- fixOrigin();
-
- ::GlobalToLocal(&mouse_point);
-
- to->mX = mouse_point.h;
- to->mY = mouse_point.v;
+ mouse_point[0] = from.mX;
+ mouse_point[1] = from.mY;
+
+ convertScreenToWindow(mWindow, mouse_point);
- ::SetPort(save);
+ to->mX = mouse_point[0];
+ to->mY = mouse_point[1];
return TRUE;
}
-
return FALSE;
}
BOOL LLWindowMacOSX::convertCoords(LLCoordWindow from, LLCoordScreen *to)
{
- if(mFullscreen)
- {
- // In the fullscreen case, window and screen coordinates are the same.
- to->mX = from.mX;
- to->mY = from.mY;
- return TRUE;
- }
- else if(mWindow)
+ if(mWindow)
{
- GrafPtr save;
- Point mouse_point;
+ float mouse_point[2];
- mouse_point.h = from.mX;
- mouse_point.v = from.mY;
- ::GetPort(&save);
- ::SetPort(GetWindowPort(mWindow));
- fixOrigin();
+ mouse_point[0] = from.mX;
+ mouse_point[1] = from.mY;
+ convertWindowToScreen(mWindow, mouse_point);
- LocalToGlobal(&mouse_point);
-
- to->mX = mouse_point.h;
- to->mY = mouse_point.v;
-
- ::SetPort(save);
+ to->mX = mouse_point[0];
+ to->mY = mouse_point[1];
return TRUE;
}
-
return FALSE;
}
@@ -1949,902 +1309,54 @@ void LLWindowMacOSX::setupFailure(const std::string& text, const std::string& ca
OSMessageBox(text, caption, type);
}
-pascal Boolean LLWindowMacOSX::staticMoveEventComparator( EventRef event, void* data)
-{
- UInt32 evtClass = GetEventClass (event);
- UInt32 evtKind = GetEventKind (event);
-
- if ((evtClass == kEventClassMouse) && ((evtKind == kEventMouseDragged) || (evtKind == kEventMouseMoved)))
- {
- return true;
- }
-
- else
- {
- return false;
- }
-}
-
-
-pascal OSStatus LLWindowMacOSX::staticEventHandler(EventHandlerCallRef myHandler, EventRef event, void* userData)
-{
- LLWindowMacOSX *self = (LLWindowMacOSX*)userData;
-
- return(self->eventHandler(myHandler, event));
-}
-
-OSStatus LLWindowMacOSX::eventHandler (EventHandlerCallRef myHandler, EventRef event)
-{
- OSStatus result = eventNotHandledErr;
- UInt32 evtClass = GetEventClass (event);
- UInt32 evtKind = GetEventKind (event);
-
- // Always handle command events, even in hands-off mode.
- if((evtClass == kEventClassCommand) && (evtKind == kEventCommandProcess))
- {
- HICommand command;
- GetEventParameter (event, kEventParamDirectObject, typeHICommand, NULL, sizeof(command), NULL, &command);
-
- switch(command.commandID)
- {
- case kHICommandQuit:
- if(mCallbacks->handleCloseRequest(this))
- {
- // Get the app to initiate cleanup.
- mCallbacks->handleQuit(this);
- // The app is responsible for calling destroyWindow when done with GL
- }
- result = noErr;
- break;
-
- default:
- // MBW -- XXX -- Should we handle other events here?
- break;
- }
- }
-
- if(mHandsOffEvents)
- {
- return(result);
- }
-
- switch (evtClass)
- {
- case kEventClassTextInput:
- {
- switch (evtKind)
- {
- case kEventTextInputUpdateActiveInputArea:
- {
- EventParamType param_type;
-
- long fix_len;
- UInt32 text_len;
- if (mPreeditor
- && (result = GetEventParameter(event, kEventParamTextInputSendFixLen,
- typeLongInteger, &param_type, sizeof(fix_len), NULL, &fix_len)) == noErr
- && typeLongInteger == param_type
- && (result = GetEventParameter(event, kEventParamTextInputSendText,
- typeUnicodeText, &param_type, 0, &text_len, NULL)) == noErr
- && typeUnicodeText == param_type)
- {
- // Handle an optional (but essential to facilitate TSMDA) ReplaceRange param.
- CFRange range;
- if (GetEventParameter(event, kEventParamTextInputSendReplaceRange,
- typeCFRange, &param_type, sizeof(range), NULL, &range) == noErr
- && typeCFRange == param_type)
- {
- // Although the spec. is unclear, replace range should
- // not present when there is an active preedit. We just
- // ignore the case. markAsPreedit will detect the case and warn it.
- const LLWString & text = mPreeditor->getPreeditString();
- const S32 location = wstring_wstring_length_from_utf16_length(text, 0, range.location);
- const S32 length = wstring_wstring_length_from_utf16_length(text, location, range.length);
- mPreeditor->markAsPreedit(location, length);
- }
- mPreeditor->resetPreedit();
-
- // Receive the text from input method.
- U16 *const text = new U16[text_len / sizeof(U16)];
- GetEventParameter(event, kEventParamTextInputSendText, typeUnicodeText, NULL, text_len, NULL, text);
- if (fix_len < 0)
- {
- // Do we still need this? Seems obsolete...
- fix_len = text_len;
- }
- const LLWString fix_string
- = utf16str_to_wstring(llutf16string(text, fix_len / sizeof(U16)));
- const LLWString preedit_string
- = utf16str_to_wstring(llutf16string(text + fix_len / sizeof(U16), (text_len - fix_len) / sizeof(U16)));
- delete[] text;
-
- // Handle fixed (comitted) string.
- if (fix_string.length() > 0)
- {
- for (LLWString::const_iterator i = fix_string.begin(); i != fix_string.end(); i++)
- {
- mPreeditor->handleUnicodeCharHere(*i);
- }
- }
-
- // Receive the segment info and caret position.
- LLPreeditor::segment_lengths_t preedit_segment_lengths;
- LLPreeditor::standouts_t preedit_standouts;
- S32 caret_position = preedit_string.length();
- UInt32 text_range_array_size;
- if (GetEventParameter(event, kEventParamTextInputSendHiliteRng, typeTextRangeArray,
- &param_type, 0, &text_range_array_size, NULL) == noErr
- && typeTextRangeArray == param_type
- && text_range_array_size > sizeof(TextRangeArray))
- {
- // TextRangeArray is a variable-length struct.
- TextRangeArray * const text_range_array = (TextRangeArray *) new char[text_range_array_size];
- GetEventParameter(event, kEventParamTextInputSendHiliteRng, typeTextRangeArray,
- NULL, text_range_array_size, NULL, text_range_array);
-
- // WARNING: We assume ranges are in ascending order,
- // although the condition is undocumented. It seems
- // OK to assume this. I also assumed
- // the ranges are contiguous in previous versions, but I
- // have heard a rumore that older versions os ATOK may
- // return ranges with some _gap_. I don't know whether
- // it is true, but I'm preparing my code for the case.
-
- const S32 ranges = text_range_array->fNumOfRanges;
- preedit_segment_lengths.reserve(ranges);
- preedit_standouts.reserve(ranges);
-
- S32 last_bytes = 0;
- S32 last_utf32 = 0;
- for (S32 i = 0; i < ranges; i++)
- {
- const TextRange &range = text_range_array->fRange[i];
- if (range.fStart > last_bytes)
- {
- const S32 length_utf16 = (range.fStart - last_bytes) / sizeof(U16);
- const S32 length_utf32 = wstring_wstring_length_from_utf16_length(preedit_string, last_utf32, length_utf16);
- preedit_segment_lengths.push_back(length_utf32);
- preedit_standouts.push_back(FALSE);
- last_utf32 += length_utf32;
- }
- if (range.fEnd > range.fStart)
- {
- const S32 length_utf16 = (range.fEnd - range.fStart) / sizeof(U16);
- const S32 length_utf32 = wstring_wstring_length_from_utf16_length(preedit_string, last_utf32, length_utf16);
- preedit_segment_lengths.push_back(length_utf32);
- preedit_standouts.push_back(
- kTSMHiliteSelectedRawText == range.fHiliteStyle
- || kTSMHiliteSelectedConvertedText == range.fHiliteStyle
- || kTSMHiliteSelectedText == range.fHiliteStyle);
- last_utf32 += length_utf32;
- }
- if (kTSMHiliteCaretPosition == range.fHiliteStyle)
- {
- caret_position = last_utf32;
- }
- last_bytes = range.fEnd;
- }
- if (preedit_string.length() > last_utf32)
- {
- preedit_segment_lengths.push_back(preedit_string.length() - last_utf32);
- preedit_standouts.push_back(FALSE);
- }
-
- delete[] (char *) text_range_array;
- }
-
- // Handle preedit string.
- if (preedit_string.length() == 0)
- {
- preedit_segment_lengths.clear();
- preedit_standouts.clear();
- }
- else if (preedit_segment_lengths.size() == 0)
- {
- preedit_segment_lengths.push_back(preedit_string.length());
- preedit_standouts.push_back(FALSE);
- }
- mPreeditor->updatePreedit(preedit_string, preedit_segment_lengths, preedit_standouts, caret_position);
-
- result = noErr;
- }
- }
- break;
-
- case kEventTextInputUnicodeForKeyEvent:
- {
- UInt32 modifiers = 0;
-
-
- // First, process the raw event.
- {
- EventRef rawEvent = NULL;
-
- // Get the original event and extract the modifier keys, so we can ignore command-key events.
- if (GetEventParameter(event, kEventParamTextInputSendKeyboardEvent, typeEventRef, NULL, sizeof(rawEvent), NULL, &rawEvent) == noErr)
- {
- // Grab the modifiers for later use in this function...
- GetEventParameter (rawEvent, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifiers);
-
- // and call this function recursively to handle the raw key event.
- eventHandler (myHandler, rawEvent);
-
- // save the raw event until we're done processing the unicode input as well.
- mRawKeyEvent = rawEvent;
- }
- }
-
- OSStatus err = noErr;
- EventParamType actualType = typeUnicodeText;
- UInt32 actualSize = 0;
- size_t actualCount = 0;
- U16 *buffer = NULL;
-
- // Get the size of the unicode data
- err = GetEventParameter (event, kEventParamTextInputSendText, typeUnicodeText, &actualType, 0, &actualSize, NULL);
- if(err == noErr)
- {
- // allocate a buffer and get the actual data.
- actualCount = actualSize / sizeof(U16);
- buffer = new U16[actualCount];
- err = GetEventParameter (event, kEventParamTextInputSendText, typeUnicodeText, &actualType, actualSize, &actualSize, buffer);
- }
-
- if(err == noErr)
- {
- if(modifiers & (cmdKey | controlKey))
- {
- // This was a menu key equivalent. Ignore it.
- }
- else
- {
- MASK mask = LLWindowMacOSX::modifiersToMask(modifiers);
-
- llassert( actualType == typeUnicodeText );
-
- // The result is a UTF16 buffer. Pass the characters in turn to handleUnicodeChar.
-
- // Convert to UTF32 and go character-by-character.
- llutf16string utf16(buffer, actualCount);
- LLWString utf32 = utf16str_to_wstring(utf16);
- LLWString::iterator iter;
-
- for(iter = utf32.begin(); iter != utf32.end(); iter++)
- {
- mCallbacks->handleUnicodeChar(*iter, mask);
- }
- }
- }
-
- if(buffer != NULL)
- {
- delete[] buffer;
- }
-
- mRawKeyEvent = NULL;
- result = err;
- }
- break;
-
- case kEventTextInputOffsetToPos:
- {
- EventParamType param_type;
- long offset;
- if (mPreeditor
- && GetEventParameter(event, kEventParamTextInputSendTextOffset, typeLongInteger,
- &param_type, sizeof(offset), NULL, &offset) == noErr
- && typeLongInteger == param_type)
- {
- S32 preedit, preedit_length;
- mPreeditor->getPreeditRange(&preedit, &preedit_length);
- const LLWString & text = mPreeditor->getPreeditString();
-
- LLCoordGL caret_coord;
- LLRect preedit_bounds;
- if (0 <= offset
- && mPreeditor->getPreeditLocation(wstring_wstring_length_from_utf16_length(text, preedit, offset / sizeof(U16)),
- &caret_coord, &preedit_bounds, NULL))
- {
- LLCoordGL caret_base_coord(caret_coord.mX, preedit_bounds.mBottom);
- LLCoordScreen caret_base_coord_screen;
- convertCoords(caret_base_coord, &caret_base_coord_screen);
- Point qd_point;
- qd_point.h = caret_base_coord_screen.mX;
- qd_point.v = caret_base_coord_screen.mY;
- SetEventParameter(event, kEventParamTextInputReplyPoint, typeQDPoint, sizeof(qd_point), &qd_point);
-
- short line_height = (short) preedit_bounds.getHeight();
- SetEventParameter(event, kEventParamTextInputReplyLineHeight, typeShortInteger, sizeof(line_height), &line_height);
-
- result = noErr;
- }
- else
- {
- result = errOffsetInvalid;
- }
- }
- }
- break;
-
- case kEventTextInputGetSelectedText:
- {
- if (mPreeditor)
- {
- S32 selection, selection_length;
- mPreeditor->getSelectionRange(&selection, &selection_length);
- if (selection_length)
- {
- const LLWString text = mPreeditor->getPreeditString().substr(selection, selection_length);
- const llutf16string text_utf16 = wstring_to_utf16str(text);
- result = SetEventParameter(event, kEventParamTextInputReplyText, typeUnicodeText,
- text_utf16.length() * sizeof(U16), text_utf16.c_str());
- }
- }
- }
- break;
- }
- }
- break;
-
- case kEventClassKeyboard:
- {
- UInt32 keyCode = 0;
- char charCode = 0;
- UInt32 modifiers = 0;
-
- // Some of these may fail for some event types. That's fine.
- GetEventParameter (event, kEventParamKeyCode, typeUInt32, NULL, sizeof(UInt32), NULL, &keyCode);
- GetEventParameter (event, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifiers);
-
- // save the raw event so getNativeKeyData can use it.
- mRawKeyEvent = event;
-
- // printf("key event, key code = 0x%08x, char code = 0x%02x (%c), modifiers = 0x%08x\n", keyCode, charCode, (char)charCode, modifiers);
- // fflush(stdout);
-
- switch (evtKind)
- {
- case kEventRawKeyDown:
- case kEventRawKeyRepeat:
- if (gDebugWindowProc)
- {
- printf("key down, key code = 0x%08x, char code = 0x%02x (%c), modifiers = 0x%08x\n",
- (unsigned int)keyCode, charCode, (char)charCode, (unsigned int)modifiers);
- fflush(stdout);
- }
- gKeyboard->handleKeyDown(keyCode, modifiers);
- result = eventNotHandledErr;
- break;
-
- case kEventRawKeyUp:
- if (gDebugWindowProc)
- {
- printf("key up, key code = 0x%08x, char code = 0x%02x (%c), modifiers = 0x%08x\n",
- (unsigned int)keyCode, charCode, (char)charCode, (unsigned int)modifiers);
- fflush(stdout);
- }
- gKeyboard->handleKeyUp(keyCode, modifiers);
- result = eventNotHandledErr;
- break;
-
- case kEventRawKeyModifiersChanged:
- // The keyboard input system wants key up/down events for modifier keys.
- // Mac OS doesn't supply these directly, but can supply events when the collective modifier state changes.
- // Use these events to generate up/down events for the modifiers.
-
- if((modifiers & shiftKey) && !(mLastModifiers & shiftKey))
- {
- if (gDebugWindowProc) printf("Shift key down event\n");
- gKeyboard->handleKeyDown(0x38, (modifiers & 0x00FFFFFF) | ((0x38 << 24) & 0xFF000000));
- }
- else if(!(modifiers & shiftKey) && (mLastModifiers & shiftKey))
- {
- if (gDebugWindowProc) printf("Shift key up event\n");
- gKeyboard->handleKeyUp(0x38, (modifiers & 0x00FFFFFF) | ((0x38 << 24) & 0xFF000000));
- }
-
- if((modifiers & alphaLock) && !(mLastModifiers & alphaLock))
- {
- if (gDebugWindowProc) printf("Caps lock down event\n");
- gKeyboard->handleKeyDown(0x39, (modifiers & 0x00FFFFFF) | ((0x39 << 24) & 0xFF000000));
- }
- else if(!(modifiers & alphaLock) && (mLastModifiers & alphaLock))
- {
- if (gDebugWindowProc) printf("Caps lock up event\n");
- gKeyboard->handleKeyUp(0x39, (modifiers & 0x00FFFFFF) | ((0x39 << 24) & 0xFF000000));
- }
-
- if((modifiers & controlKey) && !(mLastModifiers & controlKey))
- {
- if (gDebugWindowProc) printf("Control key down event\n");
- gKeyboard->handleKeyDown(0x3b, (modifiers & 0x00FFFFFF) | ((0x3b << 24) & 0xFF000000));
- }
- else if(!(modifiers & controlKey) && (mLastModifiers & controlKey))
- {
- if (gDebugWindowProc) printf("Control key up event\n");
- gKeyboard->handleKeyUp(0x3b, (modifiers & 0x00FFFFFF) | ((0x3b << 24) & 0xFF000000));
- }
-
- if((modifiers & optionKey) && !(mLastModifiers & optionKey))
- {
- if (gDebugWindowProc) printf("Option key down event\n");
- gKeyboard->handleKeyDown(0x3a, (modifiers & 0x00FFFFFF) | ((0x3a << 24) & 0xFF000000));
- }
- else if(!(modifiers & optionKey) && (mLastModifiers & optionKey))
- {
- if (gDebugWindowProc) printf("Option key up event\n");
- gKeyboard->handleKeyUp(0x3a, (modifiers & 0x00FFFFFF) | ((0x3a << 24) & 0xFF000000));
- }
-
- // When the state of the 'Fn' key (the one that changes some of the mappings on a powerbook/macbook keyboard
- // to an embedded keypad) changes, it may subsequently cause a key up event to be lost, which may lead to
- // a movement key getting "stuck" down. This is bad.
- // This is an OS bug -- even the GetKeys() API doesn't tell you the key has been released.
- // This workaround causes all held-down keys to be reset whenever the state of the Fn key changes. This isn't
- // exactly what we want, but it does avoid the case where you get stuck running forward.
- if((modifiers & kEventKeyModifierFnMask) != (mLastModifiers & kEventKeyModifierFnMask))
- {
- if (gDebugWindowProc) printf("Fn key state change event\n");
- gKeyboard->resetKeys();
- }
-
- if (gDebugWindowProc) fflush(stdout);
-
- mLastModifiers = modifiers;
- result = eventNotHandledErr;
- break;
- }
-
- mRawKeyEvent = NULL;
- }
- break;
-
- case kEventClassMouse:
- {
- result = CallNextEventHandler(myHandler, event);
- if (eventNotHandledErr == result)
- { // only handle events not already handled (prevents wierd resize interaction)
- EventMouseButton button = kEventMouseButtonPrimary;
- HIPoint location = {0.0f, 0.0f};
- UInt32 modifiers = 0;
- UInt32 clickCount = 1;
- long wheelDelta = 0;
- LLCoordScreen inCoords;
- LLCoordGL outCoords;
- MASK mask = 0;
-
- GetEventParameter(event, kEventParamMouseButton, typeMouseButton, NULL, sizeof(button), NULL, &button);
- GetEventParameter(event, kEventParamMouseLocation, typeHIPoint, NULL, sizeof(location), NULL, &location);
- GetEventParameter(event, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(modifiers), NULL, &modifiers);
- GetEventParameter(event, kEventParamMouseWheelDelta, typeLongInteger, NULL, sizeof(wheelDelta), NULL, &wheelDelta);
- GetEventParameter(event, kEventParamClickCount, typeUInt32, NULL, sizeof(clickCount), NULL, &clickCount);
-
- inCoords.mX = llround(location.x);
- inCoords.mY = llround(location.y);
-
- if(modifiers & shiftKey) { mask |= MASK_SHIFT; }
- if(modifiers & controlKey) { mask |= MASK_CONTROL; }
- if(modifiers & optionKey) { mask |= MASK_ALT; }
-
- if(mCursorDecoupled)
- {
- CGMouseDelta x, y;
-
- // If the cursor's decoupled, we need to read the latest movement delta as well.
- CGGetLastMouseDelta( &x, &y );
- mCursorLastEventDeltaX = x;
- mCursorLastEventDeltaY = y;
-
- if(mCursorIgnoreNextDelta)
- {
- mCursorLastEventDeltaX = 0;
- mCursorLastEventDeltaY = 0;
- mCursorIgnoreNextDelta = FALSE;
- }
- }
- else
- {
- mCursorLastEventDeltaX = 0;
- mCursorLastEventDeltaY = 0;
- }
-
- inCoords.mX += mCursorLastEventDeltaX;
- inCoords.mY += mCursorLastEventDeltaY;
-
- convertCoords(inCoords, &outCoords);
-
- // printf("coords in: %d, %d; coords out: %d, %d\n", inCoords.mX, inCoords.mY, outCoords.mX, outCoords.mY);
- // fflush(stdout);
-
-
- switch (evtKind)
- {
- case kEventMouseDown:
- if (mLanguageTextInputAllowed)
- {
- // We need to interrupt before handling mouse events,
- // so that the fixed string from IM are delivered to
- // the currently focused UI component.
- interruptLanguageTextInput();
- }
- switch(button)
- {
- case kEventMouseButtonPrimary:
- if(modifiers & cmdKey)
- {
- // Simulate a right click
- mSimulatedRightClick = true;
- mCallbacks->handleRightMouseDown(this, outCoords, mask);
- }
- else if(clickCount == 2)
- {
- // Windows double-click events replace the second mousedown event in a double-click.
- mCallbacks->handleDoubleClick(this, outCoords, mask);
- }
- else
- {
- mCallbacks->handleMouseDown(this, outCoords, mask);
- }
- break;
- case kEventMouseButtonSecondary:
- mCallbacks->handleRightMouseDown(this, outCoords, mask);
- break;
-
- case kEventMouseButtonTertiary:
- mCallbacks->handleMiddleMouseDown(this, outCoords, mask);
- break;
- }
- result = noErr;
- break;
- case kEventMouseUp:
-
- switch(button)
- {
- case kEventMouseButtonPrimary:
- if(mSimulatedRightClick)
- {
- // End of simulated right click
- mSimulatedRightClick = false;
- mCallbacks->handleRightMouseUp(this, outCoords, mask);
- }
- else
- {
- mCallbacks->handleMouseUp(this, outCoords, mask);
- }
- break;
- case kEventMouseButtonSecondary:
- mCallbacks->handleRightMouseUp(this, outCoords, mask);
- break;
-
- case kEventMouseButtonTertiary:
- mCallbacks->handleMiddleMouseUp(this, outCoords, mask);
- break;
- }
- result = noErr;
- break;
-
- case kEventMouseWheelMoved:
- {
- static S32 z_delta = 0;
-
- z_delta += wheelDelta;
-
- if (z_delta <= -WHEEL_DELTA || WHEEL_DELTA <= z_delta)
- {
- mCallbacks->handleScrollWheel(this, -z_delta / WHEEL_DELTA);
- z_delta = 0;
- }
- }
- result = noErr;
- break;
-
- case kEventMouseDragged:
- case kEventMouseMoved:
- mCallbacks->handleMouseMove(this, outCoords, mask);
- result = noErr;
- break;
-
- }
- }
- }
- break;
-
- case kEventClassWindow:
- switch(evtKind)
- {
- case kEventWindowActivated:
- if (mTSMDocument)
- {
- ActivateTSMDocument(mTSMDocument);
- }
- mCallbacks->handleFocus(this);
- break;
- case kEventWindowDeactivated:
- if (mTSMDocument)
- {
- DeactivateTSMDocument(mTSMDocument);
- }
- mCallbacks->handleFocusLost(this);
- break;
-
- case kEventWindowBoundsChanging:
- {
- // This is where we would constrain move/resize to a particular screen
-
- const S32 MIN_WIDTH = mMinWindowWidth;
- const S32 MIN_HEIGHT = mMinWindowHeight;
-
- Rect currentBounds;
- Rect previousBounds;
-
- GetEventParameter(event, kEventParamCurrentBounds, typeQDRectangle, NULL, sizeof(Rect), NULL, &currentBounds);
- GetEventParameter(event, kEventParamPreviousBounds, typeQDRectangle, NULL, sizeof(Rect), NULL, &previousBounds);
-
- // Put an offset into window un-maximize operation since the kEventWindowGetIdealSize
- // event only allows the specification of size and not position.
- if (mMaximized)
- {
- short leftOffset = mPreviousWindowRect.left - currentBounds.left;
- currentBounds.left += leftOffset;
- currentBounds.right += leftOffset;
-
- short topOffset = mPreviousWindowRect.top - currentBounds.top;
- currentBounds.top += topOffset;
- currentBounds.bottom += topOffset;
- }
- else
- {
- // Store off the size for future un-maximize operations
- mPreviousWindowRect = previousBounds;
- }
-
- if ((currentBounds.right - currentBounds.left) < MIN_WIDTH)
- {
- currentBounds.right = currentBounds.left + MIN_WIDTH;
- }
-
- if ((currentBounds.bottom - currentBounds.top) < MIN_HEIGHT)
- {
- currentBounds.bottom = currentBounds.top + MIN_HEIGHT;
- }
-
- SetEventParameter(event, kEventParamCurrentBounds, typeQDRectangle, sizeof(Rect), &currentBounds);
- result = noErr;
- }
- break;
-
- case kEventWindowBoundsChanged:
- {
- // Get new window bounds
- Rect newBounds;
- GetEventParameter(event, kEventParamCurrentBounds, typeQDRectangle, NULL, sizeof(Rect), NULL, &newBounds);
-
- // Get previous window bounds
- Rect oldBounds;
- GetEventParameter(event, kEventParamPreviousBounds, typeQDRectangle, NULL, sizeof(Rect), NULL, &oldBounds);
-
- // Determine if the new size is larger than the old
- bool newBoundsLarger = ((newBounds.right - newBounds.left) >= (oldBounds.right - oldBounds.left));
- newBoundsLarger &= ((newBounds.bottom - newBounds.top) >= (oldBounds.bottom - oldBounds.top));
-
- // Check to see if this is a zoom event (+ button on window pane)
- unsigned int eventParams;
- GetEventParameter(event, kEventParamAttributes, typeUInt32, NULL, sizeof(int), NULL, &eventParams);
- bool isZoomEvent = ((eventParams & kWindowBoundsChangeZoom) != 0);
-
- // Maximized flag is if zoom event and increasing window size
- mMaximized = (isZoomEvent && newBoundsLarger);
-
- aglUpdateContext(mContext);
-
- mCallbacks->handleResize(this, newBounds.right - newBounds.left, newBounds.bottom - newBounds.top);
- }
- break;
-
- case kEventWindowGetIdealSize:
- // Only recommend a new ideal size when un-maximizing
- if (mMaximized == TRUE)
- {
- Point nonMaximizedSize;
-
- nonMaximizedSize.v = mPreviousWindowRect.bottom - mPreviousWindowRect.top;
- nonMaximizedSize.h = mPreviousWindowRect.right - mPreviousWindowRect.left;
-
- SetEventParameter(event, kEventParamDimensions, typeQDPoint, sizeof(Point), &nonMaximizedSize);
- result = noErr;
- }
- break;
-
- case kEventWindowClose:
- if(mCallbacks->handleCloseRequest(this))
- {
- // Get the app to initiate cleanup.
- mCallbacks->handleQuit(this);
- // The app is responsible for calling destroyWindow when done with GL
- }
- result = noErr;
- break;
-
- case kEventWindowHidden:
- // llinfos << "LLWindowMacOSX: Deactivating on hide" << llendl;
- mMinimized = TRUE;
- mCallbacks->handleActivate(this, false);
- // result = noErr;
- break;
-
- case kEventWindowShown:
- // llinfos << "LLWindowMacOSX: Activating on show" << llendl;
- mMinimized = FALSE;
- mCallbacks->handleActivate(this, true);
- // result = noErr;
- break;
-
- case kEventWindowCollapsed:
- // llinfos << "LLWindowMacOSX: Deactivating on collapse" << llendl;
- mMinimized = TRUE;
- mCallbacks->handleActivate(this, false);
- // result = noErr;
- break;
-
- case kEventWindowExpanded:
- // llinfos << "LLWindowMacOSX: Activating on expand" << llendl;
- mMinimized = FALSE;
- mCallbacks->handleActivate(this, true);
- // result = noErr;
- break;
-
- case kEventWindowGetClickActivation:
- // BringToFront(mWindow);
- // result = noErr;
- break;
- }
- break;
-
- case kEventClassTSMDocumentAccess:
- if (mPreeditor)
- {
- switch(evtKind)
- {
-
- case kEventTSMDocumentAccessGetLength:
- {
- // Return the number of UTF-16 units in the text, excluding those for preedit.
-
- S32 preedit, preedit_length;
- mPreeditor->getPreeditRange(&preedit, &preedit_length);
- const LLWString & text = mPreeditor->getPreeditString();
- const CFIndex length = wstring_utf16_length(text, 0, preedit)
- + wstring_utf16_length(text, preedit + preedit_length, text.length());
- result = SetEventParameter(event, kEventParamTSMDocAccessCharacterCount, typeCFIndex, sizeof(length), &length);
- }
- break;
-
- case kEventTSMDocumentAccessGetSelectedRange:
- {
- // Return the selected range, excluding preedit.
- // In our preeditor, preedit and selection are exclusive, so,
- // when it has a preedit, there is no selection and the
- // insertion point is on the preedit that corrupses into the
- // beginning of the preedit when the preedit was removed.
-
- S32 preedit, preedit_length;
- mPreeditor->getPreeditRange(&preedit, &preedit_length);
- const LLWString & text = mPreeditor->getPreeditString();
-
- CFRange range;
- if (preedit_length)
- {
- range.location = wstring_utf16_length(text, 0, preedit);
- range.length = 0;
- }
- else
- {
- S32 selection, selection_length;
- mPreeditor->getSelectionRange(&selection, &selection_length);
- range.location = wstring_utf16_length(text, 0, selection);
- range.length = wstring_utf16_length(text, selection, selection_length);
- }
-
- result = SetEventParameter(event, kEventParamTSMDocAccessReplyCharacterRange, typeCFRange, sizeof(range), &range);
- }
- break;
-
- case kEventTSMDocumentAccessGetCharacters:
- {
- UniChar *target_pointer;
- CFRange range;
- EventParamType param_type;
- if ((result = GetEventParameter(event, kEventParamTSMDocAccessSendCharacterRange,
- typeCFRange, &param_type, sizeof(range), NULL, &range)) == noErr
- && typeCFRange == param_type
- && (result = GetEventParameter(event, kEventParamTSMDocAccessSendCharactersPtr,
- typePtr, &param_type, sizeof(target_pointer), NULL, &target_pointer)) == noErr
- && typePtr == param_type)
- {
- S32 preedit, preedit_length;
- mPreeditor->getPreeditRange(&preedit, &preedit_length);
- const LLWString & text = mPreeditor->getPreeditString();
-
- // The GetCharacters event of TSMDA has a fundamental flaw;
- // An input method need to decide the starting offset and length
- // *before* it actually see the contents, so it is impossible
- // to guarantee the character-aligned access. The event reply
- // has no way to indicate a condition something like "Request
- // was not fulfilled due to unaligned access. Please retry."
- // Any error sent back to the input method stops use of TSMDA
- // entirely during the session...
- // We need to simulate very strictly the behaviour as if the
- // underlying *text engine* holds the contents in UTF-16.
- // I guess this is the reason why Apple repeats saying "all
- // text handling application should use UTF-16." They are
- // trying to _fix_ the flaw by changing the appliations...
- // ... or, domination of UTF-16 in the industry may be a part
- // of the company vision, and Apple is trying to force third
- // party developers to obey their vision. Remember that use
- // of 16 bits per _a_character_ was one of the very fundamental
- // Unicode design policy on its early days (during late 80s)
- // and the original Unicode design was by two Apple employees...
-
- const llutf16string text_utf16
- = wstring_to_utf16str(text, preedit)
- + wstring_to_utf16str(text.substr(preedit + preedit_length));
-
- llassert_always(sizeof(U16) == sizeof(UniChar));
- llassert(0 <= range.location && 0 <= range.length && range.location + range.length <= text_utf16.length());
- memcpy(target_pointer, text_utf16.c_str() + range.location, range.length * sizeof(UniChar));
-
- // Note that result has already been set above.
- }
- }
- break;
-
- }
- }
- break;
- }
- return result;
-}
-
+ // Note on event recording - QUIT is a known special case and we are choosing NOT to record it for the record and playback feature
+ // it is handled at a very low-level
const char* cursorIDToName(int id)
{
switch (id)
{
- case UI_CURSOR_ARROW: return "UI_CURSOR_ARROW";
- case UI_CURSOR_WAIT: return "UI_CURSOR_WAIT";
- case UI_CURSOR_HAND: return "UI_CURSOR_HAND";
- case UI_CURSOR_IBEAM: return "UI_CURSOR_IBEAM";
- case UI_CURSOR_CROSS: return "UI_CURSOR_CROSS";
- case UI_CURSOR_SIZENWSE: return "UI_CURSOR_SIZENWSE";
- case UI_CURSOR_SIZENESW: return "UI_CURSOR_SIZENESW";
- case UI_CURSOR_SIZEWE: return "UI_CURSOR_SIZEWE";
- case UI_CURSOR_SIZENS: return "UI_CURSOR_SIZENS";
- case UI_CURSOR_NO: return "UI_CURSOR_NO";
- case UI_CURSOR_WORKING: return "UI_CURSOR_WORKING";
- case UI_CURSOR_TOOLGRAB: return "UI_CURSOR_TOOLGRAB";
- case UI_CURSOR_TOOLLAND: return "UI_CURSOR_TOOLLAND";
- case UI_CURSOR_TOOLFOCUS: return "UI_CURSOR_TOOLFOCUS";
- case UI_CURSOR_TOOLCREATE: return "UI_CURSOR_TOOLCREATE";
- case UI_CURSOR_ARROWDRAG: return "UI_CURSOR_ARROWDRAG";
- case UI_CURSOR_ARROWCOPY: return "UI_CURSOR_ARROWCOPY";
- case UI_CURSOR_ARROWDRAGMULTI: return "UI_CURSOR_ARROWDRAGMULTI";
- case UI_CURSOR_ARROWCOPYMULTI: return "UI_CURSOR_ARROWCOPYMULTI";
- case UI_CURSOR_NOLOCKED: return "UI_CURSOR_NOLOCKED";
- case UI_CURSOR_ARROWLOCKED: return "UI_CURSOR_ARROWLOCKED";
- case UI_CURSOR_GRABLOCKED: return "UI_CURSOR_GRABLOCKED";
- case UI_CURSOR_TOOLTRANSLATE: return "UI_CURSOR_TOOLTRANSLATE";
- case UI_CURSOR_TOOLROTATE: return "UI_CURSOR_TOOLROTATE";
- case UI_CURSOR_TOOLSCALE: return "UI_CURSOR_TOOLSCALE";
- case UI_CURSOR_TOOLCAMERA: return "UI_CURSOR_TOOLCAMERA";
- case UI_CURSOR_TOOLPAN: return "UI_CURSOR_TOOLPAN";
- case UI_CURSOR_TOOLZOOMIN: return "UI_CURSOR_TOOLZOOMIN";
- case UI_CURSOR_TOOLPICKOBJECT3: return "UI_CURSOR_TOOLPICKOBJECT3";
- case UI_CURSOR_TOOLPLAY: return "UI_CURSOR_TOOLPLAY";
- case UI_CURSOR_TOOLPAUSE: return "UI_CURSOR_TOOLPAUSE";
- case UI_CURSOR_TOOLMEDIAOPEN: return "UI_CURSOR_TOOLMEDIAOPEN";
- case UI_CURSOR_PIPETTE: return "UI_CURSOR_PIPETTE";
- case UI_CURSOR_TOOLSIT: return "UI_CURSOR_TOOLSIT";
- case UI_CURSOR_TOOLBUY: return "UI_CURSOR_TOOLBUY";
- case UI_CURSOR_TOOLOPEN: return "UI_CURSOR_TOOLOPEN";
+ case UI_CURSOR_ARROW: return "UI_CURSOR_ARROW";
+ case UI_CURSOR_WAIT: return "UI_CURSOR_WAIT";
+ case UI_CURSOR_HAND: return "UI_CURSOR_HAND";
+ case UI_CURSOR_IBEAM: return "UI_CURSOR_IBEAM";
+ case UI_CURSOR_CROSS: return "UI_CURSOR_CROSS";
+ case UI_CURSOR_SIZENWSE: return "UI_CURSOR_SIZENWSE";
+ case UI_CURSOR_SIZENESW: return "UI_CURSOR_SIZENESW";
+ case UI_CURSOR_SIZEWE: return "UI_CURSOR_SIZEWE";
+ case UI_CURSOR_SIZENS: return "UI_CURSOR_SIZENS";
+ case UI_CURSOR_NO: return "UI_CURSOR_NO";
+ case UI_CURSOR_WORKING: return "UI_CURSOR_WORKING";
+ case UI_CURSOR_TOOLGRAB: return "UI_CURSOR_TOOLGRAB";
+ case UI_CURSOR_TOOLLAND: return "UI_CURSOR_TOOLLAND";
+ case UI_CURSOR_TOOLFOCUS: return "UI_CURSOR_TOOLFOCUS";
+ case UI_CURSOR_TOOLCREATE: return "UI_CURSOR_TOOLCREATE";
+ case UI_CURSOR_ARROWDRAG: return "UI_CURSOR_ARROWDRAG";
+ case UI_CURSOR_ARROWCOPY: return "UI_CURSOR_ARROWCOPY";
+ case UI_CURSOR_ARROWDRAGMULTI: return "UI_CURSOR_ARROWDRAGMULTI";
+ case UI_CURSOR_ARROWCOPYMULTI: return "UI_CURSOR_ARROWCOPYMULTI";
+ case UI_CURSOR_NOLOCKED: return "UI_CURSOR_NOLOCKED";
+ case UI_CURSOR_ARROWLOCKED: return "UI_CURSOR_ARROWLOCKED";
+ case UI_CURSOR_GRABLOCKED: return "UI_CURSOR_GRABLOCKED";
+ case UI_CURSOR_TOOLTRANSLATE: return "UI_CURSOR_TOOLTRANSLATE";
+ case UI_CURSOR_TOOLROTATE: return "UI_CURSOR_TOOLROTATE";
+ case UI_CURSOR_TOOLSCALE: return "UI_CURSOR_TOOLSCALE";
+ case UI_CURSOR_TOOLCAMERA: return "UI_CURSOR_TOOLCAMERA";
+ case UI_CURSOR_TOOLPAN: return "UI_CURSOR_TOOLPAN";
+ case UI_CURSOR_TOOLZOOMIN: return "UI_CURSOR_TOOLZOOMIN";
+ case UI_CURSOR_TOOLPICKOBJECT3: return "UI_CURSOR_TOOLPICKOBJECT3";
+ case UI_CURSOR_TOOLPLAY: return "UI_CURSOR_TOOLPLAY";
+ case UI_CURSOR_TOOLPAUSE: return "UI_CURSOR_TOOLPAUSE";
+ case UI_CURSOR_TOOLMEDIAOPEN: return "UI_CURSOR_TOOLMEDIAOPEN";
+ case UI_CURSOR_PIPETTE: return "UI_CURSOR_PIPETTE";
+ case UI_CURSOR_TOOLSIT: return "UI_CURSOR_TOOLSIT";
+ case UI_CURSOR_TOOLBUY: return "UI_CURSOR_TOOLBUY";
+ case UI_CURSOR_TOOLOPEN: return "UI_CURSOR_TOOLOPEN";
+ case UI_CURSOR_TOOLPATHFINDING: return "UI_CURSOR_PATHFINDING";
+ case UI_CURSOR_TOOLPATHFINDING_PATH_START: return "UI_CURSOR_PATHFINDING_START";
+ case UI_CURSOR_TOOLPATHFINDING_PATH_START_ADD: return "UI_CURSOR_PATHFINDING_START_ADD";
+ case UI_CURSOR_TOOLPATHFINDING_PATH_END: return "UI_CURSOR_PATHFINDING_END";
+ case UI_CURSOR_TOOLPATHFINDING_PATH_END_ADD: return "UI_CURSOR_PATHFINDING_END_ADD";
+ case UI_CURSOR_TOOLNO: return "UI_CURSOR_NO";
}
llerrs << "cursorIDToName: unknown cursor id" << id << llendl;
@@ -2870,7 +1382,7 @@ static void initPixmapCursor(int cursorid, int hotspotX, int hotspotY)
void LLWindowMacOSX::updateCursor()
{
- OSStatus result = noErr;
+ S32 result = 0;
if (mDragOverrideCursor != -1)
{
@@ -2903,11 +1415,11 @@ void LLWindowMacOSX::updateCursor()
{
default:
case UI_CURSOR_ARROW:
- InitCursor();
+ setArrowCursor();
if(mCursorHidden)
{
// Since InitCursor resets the hide level, correct for it here.
- ::HideCursor();
+ hideNSCursor();
}
break;
@@ -2915,12 +1427,12 @@ void LLWindowMacOSX::updateCursor()
// Find out what they look like and replicate them.
// These are essentially correct
- case UI_CURSOR_WAIT: SetThemeCursor(kThemeWatchCursor); break;
- case UI_CURSOR_IBEAM: SetThemeCursor(kThemeIBeamCursor); break;
- case UI_CURSOR_CROSS: SetThemeCursor(kThemeCrossCursor); break;
- case UI_CURSOR_HAND: SetThemeCursor(kThemePointingHandCursor); break;
+ case UI_CURSOR_WAIT: /* Apple purposely doesn't allow us to set the beachball cursor manually. Let NSApp figure out when to do this. */ break;
+ case UI_CURSOR_IBEAM: setIBeamCursor(); break;
+ case UI_CURSOR_CROSS: setCrossCursor(); break;
+ case UI_CURSOR_HAND: setPointingHandCursor(); break;
// case UI_CURSOR_NO: SetThemeCursor(kThemeNotAllowedCursor); break;
- case UI_CURSOR_ARROWCOPY: SetThemeCursor(kThemeCopyArrowCursor); break;
+ case UI_CURSOR_ARROWCOPY: setCopyCursor(); break;
// Double-check these
case UI_CURSOR_NO:
@@ -2950,6 +1462,12 @@ void LLWindowMacOSX::updateCursor()
case UI_CURSOR_TOOLSIT:
case UI_CURSOR_TOOLBUY:
case UI_CURSOR_TOOLOPEN:
+ case UI_CURSOR_TOOLPATHFINDING:
+ case UI_CURSOR_TOOLPATHFINDING_PATH_START:
+ case UI_CURSOR_TOOLPATHFINDING_PATH_START_ADD:
+ case UI_CURSOR_TOOLPATHFINDING_PATH_END:
+ case UI_CURSOR_TOOLPATHFINDING_PATH_END_ADD:
+ case UI_CURSOR_TOOLNO:
result = setImageCursor(gCursors[mNextCursor]);
break;
@@ -2957,7 +1475,7 @@ void LLWindowMacOSX::updateCursor()
if(result != noErr)
{
- InitCursor();
+ setArrowCursor();
}
mCurrentCursor = mNextCursor;
@@ -2994,6 +1512,12 @@ void LLWindowMacOSX::initCursors()
initPixmapCursor(UI_CURSOR_TOOLSIT, 20, 15);
initPixmapCursor(UI_CURSOR_TOOLBUY, 20, 15);
initPixmapCursor(UI_CURSOR_TOOLOPEN, 20, 15);
+ initPixmapCursor(UI_CURSOR_TOOLPATHFINDING, 16, 16);
+ initPixmapCursor(UI_CURSOR_TOOLPATHFINDING_PATH_START, 16, 16);
+ initPixmapCursor(UI_CURSOR_TOOLPATHFINDING_PATH_START_ADD, 16, 16);
+ initPixmapCursor(UI_CURSOR_TOOLPATHFINDING_PATH_END, 16, 16);
+ initPixmapCursor(UI_CURSOR_TOOLPATHFINDING_PATH_END_ADD, 16, 16);
+ initPixmapCursor(UI_CURSOR_TOOLNO, 8, 8);
initPixmapCursor(UI_CURSOR_SIZENWSE, 10, 10);
initPixmapCursor(UI_CURSOR_SIZENESW, 10, 10);
@@ -3021,7 +1545,7 @@ void LLWindowMacOSX::hideCursor()
// llinfos << "hideCursor: hiding" << llendl;
mCursorHidden = TRUE;
mHideCursorPermanent = TRUE;
- ::HideCursor();
+ hideNSCursor();
}
else
{
@@ -3038,7 +1562,7 @@ void LLWindowMacOSX::showCursor()
// llinfos << "showCursor: showing" << llendl;
mCursorHidden = FALSE;
mHideCursorPermanent = FALSE;
- ::ShowCursor();
+ showNSCursor();
}
else
{
@@ -3082,24 +1606,6 @@ LLSplashScreenMacOSX::~LLSplashScreenMacOSX()
void LLSplashScreenMacOSX::showImpl()
{
// This code _could_ be used to display a spash screen...
-#if 0
- IBNibRef nib = NULL;
- OSStatus err;
-
- err = CreateNibReference(CFSTR("SecondLife"), &nib);
-
- if(err == noErr)
- {
- CreateWindowFromNib(nib, CFSTR("Splash Screen"), &mWindow);
-
- DisposeNibReference(nib);
- }
-
- if(mWindow != NULL)
- {
- ShowWindow(mWindow);
- }
-#endif
}
void LLSplashScreenMacOSX::updateImpl(const std::string& mesg)
@@ -3109,25 +1615,6 @@ void LLSplashScreenMacOSX::updateImpl(const std::string& mesg)
CFStringRef string = NULL;
string = CFStringCreateWithCString(NULL, mesg.c_str(), kCFStringEncodingUTF8);
-
- if(string != NULL)
- {
- ControlRef progressText = NULL;
- ControlID id;
- OSStatus err;
-
- id.signature = 'what';
- id.id = 0;
-
- err = GetControlByID(mWindow, &id, &progressText);
- if(err == noErr)
- {
- err = SetControlData(progressText, kControlEntireControl, kControlStaticTextCFStringTag, sizeof(CFStringRef), (Ptr)&string);
- Draw1Control(progressText);
- }
-
- CFRelease(string);
- }
}
}
@@ -3136,111 +1623,21 @@ void LLSplashScreenMacOSX::hideImpl()
{
if(mWindow != NULL)
{
- DisposeWindow(mWindow);
mWindow = NULL;
}
}
-
-
S32 OSMessageBoxMacOSX(const std::string& text, const std::string& caption, U32 type)
{
- S32 result = OSBTN_CANCEL;
- SInt16 retval_mac = 1;
- AlertStdCFStringAlertParamRec params;
- CFStringRef errorString = NULL;
- CFStringRef explanationString = NULL;
- DialogRef alert = NULL;
- AlertType alertType = kAlertCautionAlert;
- OSStatus err;
-
- explanationString = CFStringCreateWithCString(NULL, text.c_str(), kCFStringEncodingUTF8);
- errorString = CFStringCreateWithCString(NULL, caption.c_str(), kCFStringEncodingUTF8);
-
- params.version = kStdCFStringAlertVersionOne;
- params.movable = false;
- params.helpButton = false;
- params.defaultText = (CFStringRef)kAlertDefaultOKText;
- params.cancelText = 0;
- params.otherText = 0;
- params.defaultButton = 1;
- params.cancelButton = 0;
- params.position = kWindowDefaultPosition;
- params.flags = 0;
-
- switch(type)
- {
- case OSMB_OK:
- default:
- break;
- case OSMB_OKCANCEL:
- params.cancelText = (CFStringRef)kAlertDefaultCancelText;
- params.cancelButton = 2;
- break;
- case OSMB_YESNO:
- alertType = kAlertNoteAlert;
- params.defaultText = CFSTR("Yes");
- params.cancelText = CFSTR("No");
- params.cancelButton = 2;
- break;
- }
-
- if(gWindowImplementation != NULL)
- gWindowImplementation->beforeDialog();
-
- err = CreateStandardAlert(
- alertType,
- errorString,
- explanationString,
- &params,
- &alert);
-
- if(err == noErr)
- {
- err = RunStandardAlert(
- alert,
- NULL,
- &retval_mac);
- }
-
- if(gWindowImplementation != NULL)
- gWindowImplementation->afterDialog();
-
- switch(type)
- {
- case OSMB_OK:
- case OSMB_OKCANCEL:
- default:
- if(retval_mac == 1)
- result = OSBTN_OK;
- else
- result = OSBTN_CANCEL;
- break;
- case OSMB_YESNO:
- if(retval_mac == 1)
- result = OSBTN_YES;
- else
- result = OSBTN_NO;
- break;
- }
-
- if(errorString != NULL)
- {
- CFRelease(errorString);
- }
-
- if(explanationString != NULL)
- {
- CFRelease(explanationString);
- }
-
- return result;
+ return showAlert(text, caption, type);
}
// Open a URL with the user's default web browser.
// Must begin with protocol identifier.
void LLWindowMacOSX::spawnWebBrowser(const std::string& escaped_url, bool async)
{
+ // I'm fairly certain that this is all legitimate under Apple's currently supported APIs.
+
bool found = false;
S32 i;
for (i = 0; i < gURLProtocolWhitelistCount; i++)
@@ -3258,7 +1655,7 @@ void LLWindowMacOSX::spawnWebBrowser(const std::string& escaped_url, bool async)
return;
}
- OSStatus result = noErr;
+ S32 result = 0;
CFURLRef urlRef = NULL;
llinfos << "Opening URL " << escaped_url << llendl;
@@ -3295,7 +1692,7 @@ void LLWindowMacOSX::spawnWebBrowser(const std::string& escaped_url, bool async)
LLSD LLWindowMacOSX::getNativeKeyData()
{
LLSD result = LLSD::emptyMap();
-
+#if 0
if(mRawKeyEvent)
{
char char_code = 0;
@@ -3317,7 +1714,7 @@ LLSD LLWindowMacOSX::getNativeKeyData()
// This causes trouble for control characters -- apparently character codes less than 32 (escape, control-A, etc)
// cause llsd serialization to create XML that the llsd deserializer won't parse!
std::string unicode;
- OSStatus err = noErr;
+ S32 err = noErr;
EventParamType actualType = typeUTF8Text;
UInt32 actualSize = 0;
char *buffer = NULL;
@@ -3339,7 +1736,7 @@ LLSD LLWindowMacOSX::getNativeKeyData()
#endif
}
-
+#endif
lldebugs << "native key data is: " << result << llendl;
@@ -3349,34 +1746,9 @@ LLSD LLWindowMacOSX::getNativeKeyData()
BOOL LLWindowMacOSX::dialogColorPicker( F32 *r, F32 *g, F32 *b)
{
+ // Is this even used anywhere? Do we really need an OS color picker?
BOOL retval = FALSE;
- OSErr error = noErr;
- NColorPickerInfo info;
-
- memset(&info, 0, sizeof(info));
- info.theColor.color.rgb.red = (UInt16)(*r * 65535.f);
- info.theColor.color.rgb.green = (UInt16)(*g * 65535.f);
- info.theColor.color.rgb.blue = (UInt16)(*b * 65535.f);
- info.placeWhere = kCenterOnMainScreen;
-
- if(gWindowImplementation != NULL)
- gWindowImplementation->beforeDialog();
-
- error = NPickColor(&info);
-
- if(gWindowImplementation != NULL)
- gWindowImplementation->afterDialog();
-
- if (error == noErr)
- {
- retval = info.newColorChosen;
- if (info.newColorChosen)
- {
- *r = ((float) info.theColor.color.rgb.red) / 65535.0;
- *g = ((float) info.theColor.color.rgb.green) / 65535.0;
- *b = ((float) info.theColor.color.rgb.blue) / 65535.0;
- }
- }
+ //S32 error = 0;
return (retval);
}
@@ -3387,44 +1759,8 @@ void *LLWindowMacOSX::getPlatformWindow()
return (void*)mWindow;
}
-void *LLWindowMacOSX::getMediaWindow()
-{
- /*
- Mozilla needs to be initialized with a WindowRef to function properly.
- (There's no good reason for this, since it shouldn't be interacting with our window in any way, but that's another issue.)
- If we're in windowed mode, we _could_ hand it our actual window pointer, but a subsequent switch to fullscreen will destroy that window,
- which trips up Mozilla.
- Instead of using our actual window, we create an invisible window which will persist for the lifetime of the application and pass that to Mozilla.
- This satisfies its deep-seated need to latch onto a WindowRef and solves the issue with switching between fullscreen and windowed modes.
-
- Note that we will never destroy this window (by design!), but since only one will ever be created per run of the application, that's okay.
- */
-
- if(sMediaWindow == NULL)
- {
- Rect window_rect = {100, 100, 200, 200};
-
- sMediaWindow = NewCWindow(
- NULL,
- &window_rect,
- (ConstStr255Param) "\p",
- false, // Create the window invisible.
- zoomDocProc, // Window with a grow box and a zoom box
- kLastWindowOfClass, // create it behind other windows
- false, // no close box
- 0);
- }
-
- return (void*)sMediaWindow;
-}
-
-void LLWindowMacOSX::stopDockTileBounce()
-{
- NMRemove(&mBounceRec);
- mBounceTimer.stop();
-}
-
// get a double value from a dictionary
+/*
static double getDictDouble (CFDictionaryRef refDict, CFStringRef key)
{
double double_value;
@@ -3434,7 +1770,7 @@ static double getDictDouble (CFDictionaryRef refDict, CFStringRef key)
if (!CFNumberGetValue(number_value, kCFNumberDoubleType, &double_value)) // or if cant convert it
return -1; // fail
return double_value; // otherwise return the long value
-}
+}*/
// get a long value from a dictionary
static long getDictLong (CFDictionaryRef refDict, CFStringRef key)
@@ -3450,8 +1786,8 @@ static long getDictLong (CFDictionaryRef refDict, CFStringRef key)
void LLWindowMacOSX::allowLanguageTextInput(LLPreeditor *preeditor, BOOL b)
{
- ScriptLanguageRecord script_language;
-
+ allowDirectMarkedTextInput(b, mGLView);
+
if (preeditor != mPreeditor && !b)
{
// This condition may occur by a call to
@@ -3462,9 +1798,7 @@ void LLWindowMacOSX::allowLanguageTextInput(LLPreeditor *preeditor, BOOL b)
// is not disturbed.
return;
}
-
- UseInputWindow(mTSMDocument, !b);
-
+
// Take care of old and new preeditors.
if (preeditor != mPreeditor || !b)
{
@@ -3477,44 +1811,17 @@ void LLWindowMacOSX::allowLanguageTextInput(LLPreeditor *preeditor, BOOL b)
}
mPreeditor = (b ? preeditor : NULL);
}
-
+
if (b == mLanguageTextInputAllowed)
{
return;
}
mLanguageTextInputAllowed = b;
-
- if (b)
- {
- if (mTSMScriptCode != smRoman)
- {
- script_language.fScript = mTSMScriptCode;
- script_language.fLanguage = mTSMLangCode;
- SetTextServiceLanguage(&script_language);
- }
- }
- else
- {
- GetTextServiceLanguage(&script_language);
- mTSMScriptCode = script_language.fScript;
- mTSMLangCode = script_language.fLanguage;
- if (mTSMScriptCode != smRoman)
- {
- script_language.fScript = smRoman;
- script_language.fLanguage = langEnglish;
- SetTextServiceLanguage(&script_language);
- }
- }
}
void LLWindowMacOSX::interruptLanguageTextInput()
{
- if (mTSMDocument)
- {
- FixTSMDocument(mTSMDocument);
- }
- // Don't we need to call resetPreedit here?
- // Well, if Apple's TSM document is correct, we don't.
+ commitCurrentPreedit(mGLView);
}
//static
@@ -3525,21 +1832,21 @@ std::vector<std::string> LLWindowMacOSX::getDynamicFallbackFontList()
}
// static
-MASK LLWindowMacOSX::modifiersToMask(SInt16 modifiers)
+MASK LLWindowMacOSX::modifiersToMask(S16 modifiers)
{
MASK mask = 0;
- if(modifiers & shiftKey) { mask |= MASK_SHIFT; }
- if(modifiers & (cmdKey | controlKey)) { mask |= MASK_CONTROL; }
- if(modifiers & optionKey) { mask |= MASK_ALT; }
+ if(modifiers & MAC_SHIFT_KEY) { mask |= MASK_SHIFT; }
+ if(modifiers & (MAC_CMD_KEY | MAC_CTRL_KEY)) { mask |= MASK_CONTROL; }
+ if(modifiers & MAC_ALT_KEY) { mask |= MASK_ALT; }
return mask;
}
#if LL_OS_DRAGDROP_ENABLED
-
-OSErr LLWindowMacOSX::dragTrackingHandler(DragTrackingMessage message, WindowRef theWindow,
+/*
+S16 LLWindowMacOSX::dragTrackingHandler(DragTrackingMessage message, WindowRef theWindow,
void * handlerRefCon, DragRef drag)
{
- OSErr result = noErr;
+ S16 result = 0;
LLWindowMacOSX *self = (LLWindowMacOSX*)handlerRefCon;
lldebugs << "drag tracking handler, message = " << message << llendl;
@@ -3564,7 +1871,6 @@ OSErr LLWindowMacOSX::dragTrackingHandler(DragTrackingMessage message, WindowRef
return result;
}
-
OSErr LLWindowMacOSX::dragReceiveHandler(WindowRef theWindow, void * handlerRefCon,
DragRef drag)
{
@@ -3572,126 +1878,69 @@ OSErr LLWindowMacOSX::dragReceiveHandler(WindowRef theWindow, void * handlerRefC
return self->handleDragNDrop(drag, LLWindowCallbacks::DNDA_DROPPED);
}
-
-OSErr LLWindowMacOSX::handleDragNDrop(DragRef drag, LLWindowCallbacks::DragNDropAction action)
+*/
+void LLWindowMacOSX::handleDragNDrop(std::string url, LLWindowCallbacks::DragNDropAction action)
{
- OSErr result = dragNotAcceptedErr; // overall function result
- OSErr err = noErr; // for local error handling
-
- // Get the mouse position and modifiers of this drag.
- SInt16 modifiers, mouseDownModifiers, mouseUpModifiers;
- ::GetDragModifiers(drag, &modifiers, &mouseDownModifiers, &mouseUpModifiers);
- MASK mask = LLWindowMacOSX::modifiersToMask(modifiers);
+ MASK mask = LLWindowMacOSX::modifiersToMask(getModifiers());
- Point mouse_point;
- // This will return the mouse point in global screen coords
- ::GetDragMouse(drag, &mouse_point, NULL);
- LLCoordScreen screen_coords(mouse_point.h, mouse_point.v);
+ float mouse_point[2];
+ // This will return the mouse point in window coords
+ getCursorPos(mWindow, mouse_point);
+ LLCoordWindow window_coords(mouse_point[0], mouse_point[1]);
LLCoordGL gl_pos;
- convertCoords(screen_coords, &gl_pos);
-
- // Look at the pasteboard and try to extract an URL from it
- PasteboardRef pasteboard;
- if(GetDragPasteboard(drag, &pasteboard) == noErr)
+ convertCoords(window_coords, &gl_pos);
+
+ if(!url.empty())
{
- ItemCount num_items = 0;
- // Treat an error here as an item count of 0
- (void)PasteboardGetItemCount(pasteboard, &num_items);
-
- // Only deal with single-item drags.
- if(num_items == 1)
- {
- PasteboardItemID item_id = NULL;
- CFArrayRef flavors = NULL;
- CFDataRef data = NULL;
-
- err = PasteboardGetItemIdentifier(pasteboard, 1, &item_id); // Yes, this really is 1-based.
-
- // Try to extract an URL from the pasteboard
- if(err == noErr)
- {
- err = PasteboardCopyItemFlavors( pasteboard, item_id, &flavors);
- }
-
- if(err == noErr)
- {
- if(CFArrayContainsValue(flavors, CFRangeMake(0, CFArrayGetCount(flavors)), kUTTypeURL))
- {
- // This is an URL.
- err = PasteboardCopyItemFlavorData(pasteboard, item_id, kUTTypeURL, &data);
- }
- else if(CFArrayContainsValue(flavors, CFRangeMake(0, CFArrayGetCount(flavors)), kUTTypeUTF8PlainText))
+ LLWindowCallbacks::DragNDropResult res =
+ mCallbacks->handleDragNDrop(this, gl_pos, mask, action, url);
+
+ switch (res) {
+ case LLWindowCallbacks::DND_NONE: // No drop allowed
+ if (action == LLWindowCallbacks::DNDA_TRACK)
{
- // This is a string that might be an URL.
- err = PasteboardCopyItemFlavorData(pasteboard, item_id, kUTTypeUTF8PlainText, &data);
+ mDragOverrideCursor = 0;
}
-
- }
-
- if(flavors != NULL)
- {
- CFRelease(flavors);
- }
-
- if(data != NULL)
- {
- std::string url;
- url.assign((char*)CFDataGetBytePtr(data), CFDataGetLength(data));
- CFRelease(data);
-
- if(!url.empty())
- {
- LLWindowCallbacks::DragNDropResult res =
- mCallbacks->handleDragNDrop(this, gl_pos, mask, action, url);
-
- switch (res) {
- case LLWindowCallbacks::DND_NONE: // No drop allowed
- if (action == LLWindowCallbacks::DNDA_TRACK)
- {
- mDragOverrideCursor = kThemeNotAllowedCursor;
- }
- else {
- mDragOverrideCursor = -1;
- }
- break;
- case LLWindowCallbacks::DND_MOVE: // Drop accepted would result in a "move" operation
- mDragOverrideCursor = kThemePointingHandCursor;
- result = noErr;
- break;
- case LLWindowCallbacks::DND_COPY: // Drop accepted would result in a "copy" operation
- mDragOverrideCursor = kThemeCopyArrowCursor;
- result = noErr;
- break;
- case LLWindowCallbacks::DND_LINK: // Drop accepted would result in a "link" operation:
- mDragOverrideCursor = kThemeAliasArrowCursor;
- result = noErr;
- break;
- default:
- mDragOverrideCursor = -1;
- break;
- }
- // This overrides the cursor being set by setCursor.
- // This is a bit of a hack workaround because lots of areas
- // within the viewer just blindly set the cursor.
- if (mDragOverrideCursor == -1)
- {
- // Restore the cursor
- ECursorType temp_cursor = mCurrentCursor;
- // get around the "setting the same cursor" code in setCursor()
- mCurrentCursor = UI_CURSOR_COUNT;
- setCursor(temp_cursor);
- }
- else {
- // Override the cursor
- SetThemeCursor(mDragOverrideCursor);
- }
-
+ else {
+ mDragOverrideCursor = -1;
}
- }
+ break;
+ case LLWindowCallbacks::DND_MOVE: // Drop accepted would result in a "move" operation
+ mDragOverrideCursor = UI_CURSOR_NO;
+ break;
+ case LLWindowCallbacks::DND_COPY: // Drop accepted would result in a "copy" operation
+ mDragOverrideCursor = UI_CURSOR_ARROWCOPY;
+ break;
+ default:
+ mDragOverrideCursor = -1;
+ break;
+ }
+ // This overrides the cursor being set by setCursor.
+ // This is a bit of a hack workaround because lots of areas
+ // within the viewer just blindly set the cursor.
+ if (mDragOverrideCursor == -1)
+ {
+ // Restore the cursor
+ ECursorType temp_cursor = mCurrentCursor;
+ // get around the "setting the same cursor" code in setCursor()
+ mCurrentCursor = UI_CURSOR_COUNT;
+ setCursor(temp_cursor);
+ }
+ else {
+ // Override the cursor
+ switch (mDragOverrideCursor) {
+ case 0:
+ setArrowCursor();
+ break;
+ case UI_CURSOR_NO:
+ setNotAllowedCursor();
+ case UI_CURSOR_ARROWCOPY:
+ setCopyCursor();
+ default:
+ break;
+ };
}
}
-
- return result;
}
#endif // LL_OS_DRAGDROP_ENABLED
diff --git a/indra/llwindow/llwindowmacosx.h b/indra/llwindow/llwindowmacosx.h
index 52ba8b3bf3..6a6b39e674 100644..100755
--- a/indra/llwindow/llwindowmacosx.h
+++ b/indra/llwindow/llwindowmacosx.h
@@ -29,15 +29,16 @@
#include "llwindow.h"
#include "llwindowcallbacks.h"
+#include "llwindowmacosx-objc.h"
#include "lltimer.h"
-#include <Carbon/Carbon.h>
-#include <AGL/agl.h>
+#include <ApplicationServices/ApplicationServices.h>
+#include <OpenGL/OpenGL.h>
// AssertMacros.h does bad things.
+#include "fix_macros.h"
#undef verify
-#undef check
#undef require
@@ -106,7 +107,6 @@ public:
/*virtual*/ BOOL dialogColorPicker(F32 *r, F32 *g, F32 *b);
/*virtual*/ void *getPlatformWindow();
- /*virtual*/ void *getMediaWindow();
/*virtual*/ void bringToFront() {};
/*virtual*/ void allowLanguageTextInput(LLPreeditor *preeditor, BOOL b);
@@ -117,7 +117,17 @@ public:
// Provide native key event data
/*virtual*/ LLSD getNativeKeyData();
-
+
+ void* getWindow() { return mWindow; }
+ LLWindowCallbacks* getCallbacks() { return mCallbacks; }
+ LLPreeditor* getPreeditor() { return mPreeditor; }
+
+ void updateMouseDeltas(float* deltas);
+ void getMouseDeltas(float* delta);
+
+ void handleDragNDrop(std::string url, LLWindowCallbacks::DragNDropAction action);
+
+ bool allowsLanguageInput() { return mLanguageTextInputAllowed; }
protected:
LLWindowMacOSX(LLWindowCallbacks* callbacks,
@@ -153,40 +163,33 @@ protected:
BOOL createContext(int x, int y, int width, int height, int bits, BOOL fullscreen, BOOL disable_vsync);
void destroyContext();
void setupFailure(const std::string& text, const std::string& caption, U32 type);
- static pascal OSStatus staticEventHandler (EventHandlerCallRef myHandler, EventRef event, void* userData);
- static pascal Boolean staticMoveEventComparator( EventRef event, void* data);
- OSStatus eventHandler (EventHandlerCallRef myHandler, EventRef event);
void adjustCursorDecouple(bool warpingMouse = false);
- void stopDockTileBounce();
- static MASK modifiersToMask(SInt16 modifiers);
+ static MASK modifiersToMask(S16 modifiers);
#if LL_OS_DRAGDROP_ENABLED
- static OSErr dragTrackingHandler(DragTrackingMessage message, WindowRef theWindow,
- void * handlerRefCon, DragRef theDrag);
- static OSErr dragReceiveHandler(WindowRef theWindow, void * handlerRefCon, DragRef theDrag);
- OSErr handleDragNDrop(DragRef theDrag, LLWindowCallbacks::DragNDropAction action);
+
+ //static OSErr dragTrackingHandler(DragTrackingMessage message, WindowRef theWindow, void * handlerRefCon, DragRef theDrag);
+ //static OSErr dragReceiveHandler(WindowRef theWindow, void * handlerRefCon, DragRef theDrag);
+
+
#endif // LL_OS_DRAGDROP_ENABLED
//
// Platform specific variables
//
- WindowRef mWindow;
- AGLContext mContext;
- AGLPixelFormat mPixelFormat;
+
+ // Use generic pointers here. This lets us do some funky Obj-C interop using Obj-C objects without having to worry about any compilation problems that may arise.
+ NSWindowRef mWindow;
+ GLViewRef mGLView;
+ CGLContextObj mContext;
+ CGLPixelFormatObj mPixelFormat;
CGDirectDisplayID mDisplay;
- CFDictionaryRef mOldDisplayMode;
- EventLoopTimerRef mTimer;
- EventHandlerUPP mEventHandlerUPP;
- EventHandlerRef mGlobalHandlerRef;
- EventHandlerRef mWindowHandlerRef;
- EventComparatorUPP mMoveEventCampartorUPP;
- Rect mOldMouseClip; // Screen rect to which the mouse cursor was globally constrained before we changed it in clipMouse()
- Rect mPreviousWindowRect; // Save previous window for un-maximize event
- Str255 mWindowTitle;
+ LLRect mOldMouseClip; // Screen rect to which the mouse cursor was globally constrained before we changed it in clipMouse()
+ std::string mWindowTitle;
double mOriginalAspectRatio;
BOOL mSimulatedRightClick;
- UInt32 mLastModifiers;
+ U32 mLastModifiers;
BOOL mHandsOffEvents; // When true, temporarially disable CarbonEvent processing.
// Used to allow event processing when putting up dialogs in fullscreen mode.
BOOL mCursorDecoupled;
@@ -201,25 +204,16 @@ protected:
U32 mFSAASamples;
BOOL mForceRebuild;
- S32 mDragOverrideCursor;
-
- F32 mBounceTime;
- NMRec mBounceRec;
- LLTimer mBounceTimer;
+ S32 mDragOverrideCursor;
// Input method management through Text Service Manager.
- TSMDocumentID mTSMDocument;
BOOL mLanguageTextInputAllowed;
- ScriptCode mTSMScriptCode;
- LangCode mTSMLangCode;
LLPreeditor* mPreeditor;
static BOOL sUseMultGL;
friend class LLWindowManager;
- static WindowRef sMediaWindow;
- EventRef mRawKeyEvent;
-
+
};
diff --git a/indra/llwindow/llwindowmesaheadless.cpp b/indra/llwindow/llwindowmesaheadless.cpp
index 11c22ac94e..11c22ac94e 100644..100755
--- a/indra/llwindow/llwindowmesaheadless.cpp
+++ b/indra/llwindow/llwindowmesaheadless.cpp
diff --git a/indra/llwindow/llwindowmesaheadless.h b/indra/llwindow/llwindowmesaheadless.h
index 8f70aee4f6..8f70aee4f6 100644..100755
--- a/indra/llwindow/llwindowmesaheadless.h
+++ b/indra/llwindow/llwindowmesaheadless.h
diff --git a/indra/llwindow/llwindowsdl.cpp b/indra/llwindow/llwindowsdl.cpp
index 3d33af9d9b..205466e936 100644..100755
--- a/indra/llwindow/llwindowsdl.cpp
+++ b/indra/llwindow/llwindowsdl.cpp
@@ -1636,35 +1636,53 @@ void check_vm_bloat()
{
#if LL_LINUX
// watch our own VM and RSS sizes, warn if we bloated rapidly
- FILE *fp = fopen("/proc/self/stat", "r");
+ static const std::string STATS_FILE = "/proc/self/stat";
+ FILE *fp = fopen(STATS_FILE.c_str(), "r");
if (fp)
{
static long long last_vm_size = 0;
static long long last_rss_size = 0;
const long long significant_vm_difference = 250 * 1024*1024;
const long long significant_rss_difference = 50 * 1024*1024;
+ long long this_vm_size = 0;
+ long long this_rss_size = 0;
ssize_t res;
size_t dummy;
- char *ptr;
+ char *ptr = NULL;
for (int i=0; i<22; ++i) // parse past the values we don't want
{
- ptr = NULL;
res = getdelim(&ptr, &dummy, ' ', fp);
+ if (-1 == res)
+ {
+ llwarns << "Unable to parse " << STATS_FILE << llendl;
+ goto finally;
+ }
free(ptr);
+ ptr = NULL;
}
// 23rd space-delimited entry is vsize
- ptr = NULL;
res = getdelim(&ptr, &dummy, ' ', fp);
llassert(ptr);
- long long this_vm_size = atoll(ptr);
+ if (-1 == res)
+ {
+ llwarns << "Unable to parse " << STATS_FILE << llendl;
+ goto finally;
+ }
+ this_vm_size = atoll(ptr);
free(ptr);
- // 24th space-delimited entry is RSS
ptr = NULL;
+ // 24th space-delimited entry is RSS
res = getdelim(&ptr, &dummy, ' ', fp);
llassert(ptr);
- long long this_rss_size = getpagesize() * atoll(ptr);
+ if (-1 == res)
+ {
+ llwarns << "Unable to parse " << STATS_FILE << llendl;
+ goto finally;
+ }
+ this_rss_size = getpagesize() * atoll(ptr);
free(ptr);
+ ptr = NULL;
llinfos << "VM SIZE IS NOW " << (this_vm_size/(1024*1024)) << " MB, RSS SIZE IS NOW " << (this_rss_size/(1024*1024)) << " MB" << llendl;
@@ -1697,6 +1715,12 @@ void check_vm_bloat()
last_rss_size = this_rss_size;
last_vm_size = this_vm_size;
+finally:
+ if (NULL != ptr)
+ {
+ free(ptr);
+ ptr = NULL;
+ }
fclose(fp);
}
#endif // LL_LINUX
@@ -2117,6 +2141,12 @@ void LLWindowSDL::initCursors()
mSDLCursors[UI_CURSOR_TOOLSIT] = makeSDLCursorFromBMP("toolsit.BMP",20,15);
mSDLCursors[UI_CURSOR_TOOLBUY] = makeSDLCursorFromBMP("toolbuy.BMP",20,15);
mSDLCursors[UI_CURSOR_TOOLOPEN] = makeSDLCursorFromBMP("toolopen.BMP",20,15);
+ mSDLCursors[UI_CURSOR_TOOLPATHFINDING] = makeSDLCursorFromBMP("lltoolpathfinding.BMP", 16, 16);
+ mSDLCursors[UI_CURSOR_TOOLPATHFINDING_PATH_START] = makeSDLCursorFromBMP("lltoolpathfindingpathstart.BMP", 16, 16);
+ mSDLCursors[UI_CURSOR_TOOLPATHFINDING_PATH_START_ADD] = makeSDLCursorFromBMP("lltoolpathfindingpathstartadd.BMP", 16, 16);
+ mSDLCursors[UI_CURSOR_TOOLPATHFINDING_PATH_END] = makeSDLCursorFromBMP("lltoolpathfindingpathend.BMP", 16, 16);
+ mSDLCursors[UI_CURSOR_TOOLPATHFINDING_PATH_END_ADD] = makeSDLCursorFromBMP("lltoolpathfindingpathendadd.BMP", 16, 16);
+ mSDLCursors[UI_CURSOR_TOOLNO] = makeSDLCursorFromBMP("llno.BMP",8,8);
if (getenv("LL_ATI_MOUSE_CURSOR_BUG") != NULL) {
llinfos << "Disabling cursor updating due to LL_ATI_MOUSE_CURSOR_BUG" << llendl;
@@ -2510,6 +2540,23 @@ void exec_cmd(const std::string& cmd, const std::string& arg)
// Must begin with protocol identifier.
void LLWindowSDL::spawnWebBrowser(const std::string& escaped_url, bool async)
{
+ bool found = false;
+ S32 i;
+ for (i = 0; i < gURLProtocolWhitelistCount; i++)
+ {
+ if (escaped_url.find(gURLProtocolWhitelist[i]) != std::string::npos)
+ {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found)
+ {
+ llwarns << "spawn_web_browser called for url with protocol not on whitelist: " << escaped_url << llendl;
+ return;
+ }
+
llinfos << "spawn_web_browser: " << escaped_url << llendl;
#if LL_LINUX || LL_SOLARIS
@@ -2640,8 +2687,9 @@ std::vector<std::string> LLWindowSDL::getDynamicFallbackFontList()
if (sortpat)
{
// Sort the list of system fonts from most-to-least-desirable.
+ FcResult result;
fs = FcFontSort(NULL, sortpat, elide_unicode_coverage,
- NULL, NULL);
+ NULL, &result);
FcPatternDestroy(sortpat);
}
diff --git a/indra/llwindow/llwindowsdl.h b/indra/llwindow/llwindowsdl.h
index 4e2a269ea3..c5ce892a04 100644..100755
--- a/indra/llwindow/llwindowsdl.h
+++ b/indra/llwindow/llwindowsdl.h
@@ -41,8 +41,8 @@
#endif
// AssertMacros.h does bad things.
+#include "fix_macros.h"
#undef verify
-#undef check
#undef require
diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp
index bc85acbf45..30f5526500 100644..100755
--- a/indra/llwindow/llwindowwin32.cpp
+++ b/indra/llwindow/llwindowwin32.cpp
@@ -58,7 +58,6 @@
#include <dinput.h>
#include <Dbt.h.>
-#include "llmemtype.h"
// culled from winuser.h
#ifndef WM_MOUSEWHEEL /* Added to be compatible with later SDK's */
const S32 WM_MOUSEWHEEL = 0x020A;
@@ -160,9 +159,8 @@ LLWinImm LLWinImm::sTheInstance;
LLWinImm::LLWinImm() : mHImmDll(NULL)
{
// Check system metrics
- if ( !GetSystemMetrics( SM_DBCSENABLED ) )
+ if ( !GetSystemMetrics( SM_IMMENABLED ) )
return;
-
mHImmDll = LoadLibraryA("Imm32");
if (mHImmDll != NULL)
@@ -367,6 +365,10 @@ LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks,
U32 fsaa_samples)
: LLWindow(callbacks, fullscreen, flags)
{
+
+ //MAINT-516 -- force a load of opengl32.dll just in case windows went sideways
+ LoadLibrary(L"opengl32.dll");
+
mFSAASamples = fsaa_samples;
mIconResource = gIconResource;
mOverrideAspectRatio = 0.f;
@@ -1477,7 +1479,8 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BO
}
else
{
- llinfos << "Created OpenGL " << llformat("%d.%d", attribs[1], attribs[3]) << " context." << llendl;
+ llinfos << "Created OpenGL " << llformat("%d.%d", attribs[1], attribs[3]) <<
+ (LLRender::sGLCoreProfile ? " core" : " compatibility") << " context." << llendl;
done = true;
if (LLRender::sGLCoreProfile)
@@ -1697,6 +1700,12 @@ void LLWindowWin32::initCursors()
mCursor[ UI_CURSOR_TOOLSIT ] = LoadCursor(module, TEXT("TOOLSIT"));
mCursor[ UI_CURSOR_TOOLBUY ] = LoadCursor(module, TEXT("TOOLBUY"));
mCursor[ UI_CURSOR_TOOLOPEN ] = LoadCursor(module, TEXT("TOOLOPEN"));
+ mCursor[ UI_CURSOR_TOOLPATHFINDING ] = LoadCursor(module, TEXT("TOOLPATHFINDING"));
+ mCursor[ UI_CURSOR_TOOLPATHFINDING_PATH_START_ADD ] = LoadCursor(module, TEXT("TOOLPATHFINDINGPATHSTARTADD"));
+ mCursor[ UI_CURSOR_TOOLPATHFINDING_PATH_START ] = LoadCursor(module, TEXT("TOOLPATHFINDINGPATHSTART"));
+ mCursor[ UI_CURSOR_TOOLPATHFINDING_PATH_END ] = LoadCursor(module, TEXT("TOOLPATHFINDINGPATHEND"));
+ mCursor[ UI_CURSOR_TOOLPATHFINDING_PATH_END_ADD ] = LoadCursor(module, TEXT("TOOLPATHFINDINGPATHENDADD"));
+ mCursor[ UI_CURSOR_TOOLNO ] = LoadCursor(module, TEXT("TOOLNO"));
// Color cursors
mCursor[ UI_CURSOR_TOOLPLAY ] = loadColorCursor(TEXT("TOOLPLAY"));
@@ -1762,8 +1771,6 @@ void LLWindowWin32::gatherInput()
MSG msg;
int msg_count = 0;
- LLMemType m1(LLMemType::MTYPE_GATHER_INPUT);
-
while ((msg_count < MAX_MESSAGE_PER_UPDATE) && PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
mCallbacks->handlePingWatchdog(this, "Main:TranslateGatherInput");
@@ -3492,19 +3499,11 @@ void LLWindowWin32::updateLanguageTextInputArea()
void LLWindowWin32::interruptLanguageTextInput()
{
- if (mPreeditor)
+ if (mPreeditor && LLWinImm::isAvailable())
{
- if (LLWinImm::isAvailable())
- {
- HIMC himc = LLWinImm::getContext(mWindowHandle);
- LLWinImm::notifyIME(himc, NI_COMPOSITIONSTR, CPS_COMPLETE, 0);
- LLWinImm::releaseContext(mWindowHandle, himc);
- }
-
- // Win32 document says there will be no composition string
- // after NI_COMPOSITIONSTR returns. The following call to
- // resetPreedit should be a NOP unless IME goes mad...
- mPreeditor->resetPreedit();
+ HIMC himc = LLWinImm::getContext(mWindowHandle);
+ LLWinImm::notifyIME(himc, NI_COMPOSITIONSTR, CPS_COMPLETE, 0);
+ LLWinImm::releaseContext(mWindowHandle, himc);
}
}
diff --git a/indra/llwindow/llwindowwin32.h b/indra/llwindow/llwindowwin32.h
index 54c9ac4d4d..54c9ac4d4d 100644..100755
--- a/indra/llwindow/llwindowwin32.h
+++ b/indra/llwindow/llwindowwin32.h
diff --git a/indra/llxml/CMakeLists.txt b/indra/llxml/CMakeLists.txt
index beefcda361..17400a203e 100644..100755
--- a/indra/llxml/CMakeLists.txt
+++ b/indra/llxml/CMakeLists.txt
@@ -13,6 +13,9 @@ include_directories(
${LLMATH_INCLUDE_DIRS}
${LLVFS_INCLUDE_DIRS}
)
+include_directories(
+ ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+ )
set(llxml_SOURCE_FILES
llcontrol.cpp
@@ -40,8 +43,9 @@ add_library (llxml ${llxml_SOURCE_FILES})
# Libraries on which this library depends, needed for Linux builds
# Sort by high-level to low-level
target_link_libraries( llxml
- llvfs
- llmath
+ ${LLVFS_LIBRARIES}
+ ${LLMATH_LIBRARIES}
+ ${LLCOMMON_LIBRARIES}
${EXPAT_LIBRARIES}
)
diff --git a/indra/llxml/llcontrol.cpp b/indra/llxml/llcontrol.cpp
index 0809d95628..97fad7feb0 100644..100755
--- a/indra/llxml/llcontrol.cpp
+++ b/indra/llxml/llcontrol.cpp
@@ -132,14 +132,14 @@ bool LLControlVariable::llsd_compare(const LLSD& a, const LLSD & b)
LLControlVariable::LLControlVariable(const std::string& name, eControlType type,
LLSD initial, const std::string& comment,
- bool persist, bool hidefromsettingseditor)
+ ePersist persist, bool hidefromsettingseditor)
: mName(name),
mComment(comment),
mType(type),
mPersist(persist),
mHideFromSettingsEditor(hidefromsettingseditor)
{
- if (mPersist && mComment.empty())
+ if ((persist != PERSIST_NO) && mComment.empty())
{
llerrs << "Must supply a comment for control " << mName << llendl;
}
@@ -201,7 +201,8 @@ void LLControlVariable::setValue(const LLSD& new_value, bool saved_value)
}
LLSD storable_value = getComparableValue(new_value);
- bool value_changed = llsd_compare(getValue(), storable_value) == FALSE;
+ LLSD original_value = getValue();
+ bool value_changed = llsd_compare(original_value, storable_value) == FALSE;
if(saved_value)
{
// If we're going to save this value, return to default but don't fire
@@ -237,7 +238,7 @@ void LLControlVariable::setValue(const LLSD& new_value, bool saved_value)
if(value_changed)
{
- mCommitSignal(this, storable_value);
+ firePropertyChanged(original_value);
}
}
@@ -249,16 +250,17 @@ void LLControlVariable::setDefaultValue(const LLSD& value)
// *NOTE: Default values are not saved, only read.
LLSD comparable_value = getComparableValue(value);
- bool value_changed = (llsd_compare(getValue(), comparable_value) == FALSE);
+ LLSD original_value = getValue();
+ bool value_changed = (llsd_compare(original_value, comparable_value) == FALSE);
resetToDefault(false);
mValues[0] = comparable_value;
if(value_changed)
{
- firePropertyChanged();
+ firePropertyChanged(original_value);
}
}
-void LLControlVariable::setPersist(bool state)
+void LLControlVariable::setPersist(ePersist state)
{
mPersist = state;
}
@@ -277,6 +279,8 @@ void LLControlVariable::resetToDefault(bool fire_signal)
{
//The first setting is always the default
//Pop to it and fire off the listener
+ LLSD originalValue = mValues.back();
+
while(mValues.size() > 1)
{
mValues.pop_back();
@@ -284,14 +288,33 @@ void LLControlVariable::resetToDefault(bool fire_signal)
if(fire_signal)
{
- firePropertyChanged();
+ firePropertyChanged(originalValue);
}
}
-bool LLControlVariable::isSaveValueDefault()
-{
- return (mValues.size() == 1)
- || ((mValues.size() > 1) && llsd_compare(mValues[1], mValues[0]));
+bool LLControlVariable::shouldSave(bool nondefault_only)
+{
+ // This method is used to decide whether we should save a given
+ // variable. Two of the three values of mPersist are easy.
+ if (mPersist == PERSIST_NO)
+ return false;
+
+ if (mPersist == PERSIST_ALWAYS)
+ return true;
+
+ // PERSIST_NONDFT
+ // If caller doesn't need us to filter, just save.
+ if (! nondefault_only)
+ return true;
+
+ // PERSIST_NONDFT: caller only wants us to save this variable if its value
+ // differs from default.
+ if (isDefault()) // never been altered
+ return false;
+
+ // We've set at least one other value: compare it to default. Save only if
+ // they differ.
+ return ! llsd_compare(getSaveValue(), getDefault());
}
LLSD LLControlVariable::getSaveValue() const
@@ -351,12 +374,12 @@ std::string LLControlGroup::typeEnumToString(eControlType typeenum)
return mTypeString[typeenum];
}
-BOOL LLControlGroup::declareControl(const std::string& name, eControlType type, const LLSD initial_val, const std::string& comment, BOOL persist, BOOL hidefromsettingseditor)
+LLControlVariable* LLControlGroup::declareControl(const std::string& name, eControlType type, const LLSD initial_val, const std::string& comment, LLControlVariable::ePersist persist, BOOL hidefromsettingseditor)
{
LLControlVariable* existing_control = getControl(name);
if (existing_control)
{
- if (persist && existing_control->isType(type))
+ if ((persist != LLControlVariable::PERSIST_NO) && existing_control->isType(type))
{
if (!existing_control->llsd_compare(existing_control->getDefault(), initial_val))
{
@@ -368,68 +391,68 @@ BOOL LLControlGroup::declareControl(const std::string& name, eControlType type,
}
else
{
- llwarns << "Control named " << name << " already exists, ignoring new declaration." << llendl;
+ LL_WARNS("Settings") << "Control named " << name << " already exists, ignoring new declaration." << LL_ENDL;
}
- return TRUE;
+ return existing_control;
}
// if not, create the control and add it to the name table
LLControlVariable* control = new LLControlVariable(name, type, initial_val, comment, persist, hidefromsettingseditor);
mNameTable[name] = control;
- return TRUE;
+ return control;
}
-BOOL LLControlGroup::declareU32(const std::string& name, const U32 initial_val, const std::string& comment, BOOL persist)
+LLControlVariable* LLControlGroup::declareU32(const std::string& name, const U32 initial_val, const std::string& comment, LLControlVariable::ePersist persist)
{
return declareControl(name, TYPE_U32, (LLSD::Integer) initial_val, comment, persist);
}
-BOOL LLControlGroup::declareS32(const std::string& name, const S32 initial_val, const std::string& comment, BOOL persist)
+LLControlVariable* LLControlGroup::declareS32(const std::string& name, const S32 initial_val, const std::string& comment, LLControlVariable::ePersist persist)
{
return declareControl(name, TYPE_S32, initial_val, comment, persist);
}
-BOOL LLControlGroup::declareF32(const std::string& name, const F32 initial_val, const std::string& comment, BOOL persist)
+LLControlVariable* LLControlGroup::declareF32(const std::string& name, const F32 initial_val, const std::string& comment, LLControlVariable::ePersist persist)
{
return declareControl(name, TYPE_F32, initial_val, comment, persist);
}
-BOOL LLControlGroup::declareBOOL(const std::string& name, const BOOL initial_val, const std::string& comment, BOOL persist)
+LLControlVariable* LLControlGroup::declareBOOL(const std::string& name, const BOOL initial_val, const std::string& comment, LLControlVariable::ePersist persist)
{
return declareControl(name, TYPE_BOOLEAN, initial_val, comment, persist);
}
-BOOL LLControlGroup::declareString(const std::string& name, const std::string& initial_val, const std::string& comment, BOOL persist)
+LLControlVariable* LLControlGroup::declareString(const std::string& name, const std::string& initial_val, const std::string& comment, LLControlVariable::ePersist persist)
{
return declareControl(name, TYPE_STRING, initial_val, comment, persist);
}
-BOOL LLControlGroup::declareVec3(const std::string& name, const LLVector3 &initial_val, const std::string& comment, BOOL persist)
+LLControlVariable* LLControlGroup::declareVec3(const std::string& name, const LLVector3 &initial_val, const std::string& comment, LLControlVariable::ePersist persist)
{
return declareControl(name, TYPE_VEC3, initial_val.getValue(), comment, persist);
}
-BOOL LLControlGroup::declareVec3d(const std::string& name, const LLVector3d &initial_val, const std::string& comment, BOOL persist)
+LLControlVariable* LLControlGroup::declareVec3d(const std::string& name, const LLVector3d &initial_val, const std::string& comment, LLControlVariable::ePersist persist)
{
return declareControl(name, TYPE_VEC3D, initial_val.getValue(), comment, persist);
}
-BOOL LLControlGroup::declareRect(const std::string& name, const LLRect &initial_val, const std::string& comment, BOOL persist)
+LLControlVariable* LLControlGroup::declareRect(const std::string& name, const LLRect &initial_val, const std::string& comment, LLControlVariable::ePersist persist)
{
return declareControl(name, TYPE_RECT, initial_val.getValue(), comment, persist);
}
-BOOL LLControlGroup::declareColor4(const std::string& name, const LLColor4 &initial_val, const std::string& comment, BOOL persist )
+LLControlVariable* LLControlGroup::declareColor4(const std::string& name, const LLColor4 &initial_val, const std::string& comment, LLControlVariable::ePersist persist )
{
return declareControl(name, TYPE_COL4, initial_val.getValue(), comment, persist);
}
-BOOL LLControlGroup::declareColor3(const std::string& name, const LLColor3 &initial_val, const std::string& comment, BOOL persist )
+LLControlVariable* LLControlGroup::declareColor3(const std::string& name, const LLColor3 &initial_val, const std::string& comment, LLControlVariable::ePersist persist )
{
return declareControl(name, TYPE_COL3, initial_val.getValue(), comment, persist);
}
-BOOL LLControlGroup::declareLLSD(const std::string& name, const LLSD &initial_val, const std::string& comment, BOOL persist )
+LLControlVariable* LLControlGroup::declareLLSD(const std::string& name, const LLSD &initial_val, const std::string& comment, LLControlVariable::ePersist persist )
{
return declareControl(name, TYPE_LLSD, initial_val, comment, persist);
}
@@ -607,14 +630,14 @@ U32 LLControlGroup::loadFromFileLegacy(const std::string& filename, BOOL require
if (!xml_controls.parseFile(filename))
{
- llwarns << "Unable to open control file " << filename << llendl;
+ LL_WARNS("Settings") << "Unable to open control file " << filename << LL_ENDL;
return 0;
}
LLXmlTreeNode* rootp = xml_controls.getRoot();
if (!rootp || !rootp->hasAttribute("version"))
{
- llwarns << "No valid settings header found in control file " << filename << llendl;
+ LL_WARNS("Settings") << "No valid settings header found in control file " << filename << LL_ENDL;
return 0;
}
@@ -627,7 +650,7 @@ U32 LLControlGroup::loadFromFileLegacy(const std::string& filename, BOOL require
// Check file version
if (version != CURRENT_VERSION)
{
- llinfos << filename << " does not appear to be a version " << CURRENT_VERSION << " controls file" << llendl;
+ LL_INFOS("Settings") << filename << " does not appear to be a version " << CURRENT_VERSION << " controls file" << LL_ENDL;
return 0;
}
@@ -645,7 +668,7 @@ U32 LLControlGroup::loadFromFileLegacy(const std::string& filename, BOOL require
if (!name.empty())
{
//read in to end of line
- llwarns << "LLControlGroup::loadFromFile() : Trying to set \"" << name << "\", setting doesn't exist." << llendl;
+ LL_WARNS("Settings") << "LLControlGroup::loadFromFile() : Trying to set \"" << name << "\", setting doesn't exist." << LL_ENDL;
}
child_nodep = rootp->getNextChild();
continue;
@@ -660,11 +683,11 @@ U32 LLControlGroup::loadFromFileLegacy(const std::string& filename, BOOL require
switch(declare_as)
{
case TYPE_COL4:
- declareColor4(name, LLColor4::white, LLStringUtil::null, NO_PERSIST);
+ declareColor4(name, LLColor4::white, LLStringUtil::null, LLControlVariable::PERSIST_NO);
break;
case TYPE_STRING:
default:
- declareString(name, LLStringUtil::null, LLStringUtil::null, NO_PERSIST);
+ declareString(name, LLStringUtil::null, LLStringUtil::null, LLControlVariable::PERSIST_NO);
break;
}
}
@@ -799,23 +822,14 @@ U32 LLControlGroup::saveToFile(const std::string& filename, BOOL nondefault_only
LLControlVariable* control = iter->second;
if (!control)
{
- llwarns << "Tried to save invalid control: " << iter->first << llendl;
+ LL_WARNS("Settings") << "Tried to save invalid control: " << iter->first << LL_ENDL;
}
-
- if( control && control->isPersisted() )
+ else if( control->shouldSave(nondefault_only) )
{
- if (!(nondefault_only && (control->isSaveValueDefault())))
- {
- settings[iter->first]["Type"] = typeEnumToString(control->type());
- settings[iter->first]["Comment"] = control->getComment();
- settings[iter->first]["Value"] = control->getSaveValue();
- ++num_saved;
- }
- else
- {
- // Debug spam
- // llinfos << "Skipping " << control->getName() << llendl;
- }
+ settings[iter->first]["Type"] = typeEnumToString(control->type());
+ settings[iter->first]["Comment"] = control->getComment();
+ settings[iter->first]["Value"] = control->getSaveValue();
+ ++num_saved;
}
}
llofstream file;
@@ -824,12 +838,12 @@ U32 LLControlGroup::saveToFile(const std::string& filename, BOOL nondefault_only
{
LLSDSerialize::toPrettyXML(settings, file);
file.close();
- llinfos << "Saved to " << filename << llendl;
+ LL_INFOS("Settings") << "Saved to " << filename << LL_ENDL;
}
else
{
// This is a warning because sometime we want to use settings files which can't be written...
- llwarns << "Unable to open settings file: " << filename << llendl;
+ LL_WARNS("Settings") << "Unable to open settings file: " << filename << LL_ENDL;
return 0;
}
return num_saved;
@@ -842,16 +856,14 @@ U32 LLControlGroup::loadFromFile(const std::string& filename, bool set_default_v
infile.open(filename);
if(!infile.is_open())
{
- llwarns << "Cannot find file " << filename << " to load." << llendl;
+ LL_WARNS("Settings") << "Cannot find file " << filename << " to load." << LL_ENDL;
return 0;
}
- S32 ret = LLSDSerialize::fromXML(settings, infile);
-
- if (ret <= 0)
+ if (LLSDParser::PARSE_FAILURE == LLSDSerialize::fromXML(settings, infile))
{
infile.close();
- llwarns << "Unable to open LLSD control file " << filename << ". Trying Legacy Method." << llendl;
+ LL_WARNS("Settings") << "Unable to parse LLSD control file " << filename << ". Trying Legacy Method." << LL_ENDL;
return loadFromFileLegacy(filename, TRUE, TYPE_STRING);
}
@@ -860,13 +872,14 @@ U32 LLControlGroup::loadFromFile(const std::string& filename, bool set_default_v
for(LLSD::map_const_iterator itr = settings.beginMap(); itr != settings.endMap(); ++itr)
{
- bool persist = true;
+ LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT;
std::string const & name = itr->first;
LLSD const & control_map = itr->second;
if(control_map.has("Persist"))
{
- persist = control_map["Persist"].asInteger();
+ persist = control_map["Persist"].asInteger()?
+ LLControlVariable::PERSIST_NONDFT : LLControlVariable::PERSIST_NO;
}
// Sometimes we want to use the settings system to provide cheap persistence, but we
@@ -885,6 +898,8 @@ U32 LLControlGroup::loadFromFile(const std::string& filename, bool set_default_v
LLControlVariable* existing_control = getControl(name);
if(existing_control)
{
+ // set_default_values is true when we're loading the initial,
+ // immutable files from app_settings, e.g. settings.xml.
if(set_default_values)
{
// Override all previously set properties of this control.
@@ -906,6 +921,9 @@ U32 LLControlGroup::loadFromFile(const std::string& filename, bool set_default_v
}
else if(existing_control->isPersisted())
{
+ // save_values is specifically false for (e.g.)
+ // SessionSettingsFile and UserSessionSettingsFile -- in other
+ // words, for a file that's supposed to be transient.
existing_control->setValue(control_map["Value"], save_values);
}
// *NOTE: If not persisted and not setting defaults,
@@ -913,6 +931,39 @@ U32 LLControlGroup::loadFromFile(const std::string& filename, bool set_default_v
}
else
{
+ // We've never seen this control before. Either we're loading up
+ // the initial set of default settings files (set_default_values)
+ // -- or we're loading user settings last saved by a viewer that
+ // supports a superset of the variables we know.
+ // CHOP-962: if we're loading an unrecognized user setting, make
+ // sure we save it later. If you try an experimental viewer, tweak
+ // a new setting, briefly revert to an old viewer, then return to
+ // the new one, we don't want the old viewer to discard the
+ // setting you changed.
+ if (! set_default_values)
+ {
+ // Using PERSIST_ALWAYS insists that saveToFile() (which calls
+ // LLControlVariable::shouldSave()) must save this control
+ // variable regardless of its value. We can safely set this
+ // LLControlVariable persistent because the 'persistent' flag
+ // is not itself persisted!
+ persist = LLControlVariable::PERSIST_ALWAYS;
+ // We want to mention unrecognized user settings variables
+ // (e.g. from a newer version of the viewer) in the log. But
+ // we also arrive here for Boolean variables generated by
+ // the notifications subsystem when the user checks "Don't
+ // show me this again." These aren't declared in settings.xml;
+ // they're actually named for the notification they suppress.
+ // We don't want to mention those. Apologies, this is a bit of
+ // a hack: we happen to know that user settings go into an
+ // LLControlGroup whose name is "Global".
+ if (getKey() == "Global")
+ {
+ LL_INFOS("LLControlGroup") << "preserving unrecognized " << getKey()
+ << " settings variable " << name << LL_ENDL;
+ }
+ }
+
declareControl(name,
typeStringToEnum(control_map["Type"].asString()),
control_map["Value"],
@@ -921,10 +972,11 @@ U32 LLControlGroup::loadFromFile(const std::string& filename, bool set_default_v
hidefromsettingseditor
);
}
-
+
++validitems;
}
+ LL_DEBUGS("Settings") << "Loaded " << validitems << " settings from " << filename << LL_ENDL;
return validitems;
}
@@ -961,7 +1013,7 @@ void main()
BOOL_CONTROL baz;
U32 count = gGlobals.loadFromFile("controls.ini");
- llinfos << "Loaded " << count << " controls" << llendl;
+ LL_INFOS("Settings") << "Loaded " << count << " controls" << LL_ENDL;
// test insertion
foo = new LLControlVariable<F32>("gFoo", 5.f, 1.f, 20.f);
@@ -1222,19 +1274,19 @@ LLColor4 convert_from_llsd<LLColor4>(const LLSD& sd, eControlType type, const st
LLColor4 color(sd);
if (color.mV[VRED] < 0.f || color.mV[VRED] > 1.f)
{
- llwarns << "Color " << control_name << " red value out of range: " << color << llendl;
+ LL_WARNS("Settings") << "Color " << control_name << " red value out of range: " << color << LL_ENDL;
}
else if (color.mV[VGREEN] < 0.f || color.mV[VGREEN] > 1.f)
{
- llwarns << "Color " << control_name << " green value out of range: " << color << llendl;
+ LL_WARNS("Settings") << "Color " << control_name << " green value out of range: " << color << LL_ENDL;
}
else if (color.mV[VBLUE] < 0.f || color.mV[VBLUE] > 1.f)
{
- llwarns << "Color " << control_name << " blue value out of range: " << color << llendl;
+ LL_WARNS("Settings") << "Color " << control_name << " blue value out of range: " << color << LL_ENDL;
}
else if (color.mV[VALPHA] < 0.f || color.mV[VALPHA] > 1.f)
{
- llwarns << "Color " << control_name << " alpha value out of range: " << color << llendl;
+ LL_WARNS("Settings") << "Color " << control_name << " alpha value out of range: " << color << LL_ENDL;
}
return LLColor4(sd);
diff --git a/indra/llxml/llcontrol.h b/indra/llxml/llcontrol.h
index 597031ec70..f46d21408b 100644..100755
--- a/indra/llxml/llcontrol.h
+++ b/indra/llxml/llcontrol.h
@@ -72,8 +72,6 @@ class LLVector3d;
class LLColor4;
class LLColor3;
-const BOOL NO_PERSIST = FALSE;
-
typedef enum e_control_type
{
TYPE_U32 = 0,
@@ -98,23 +96,30 @@ class LLControlVariable : public LLRefCount
public:
typedef boost::signals2::signal<bool(LLControlVariable* control, const LLSD&), boost_boolean_combiner> validate_signal_t;
- typedef boost::signals2::signal<void(LLControlVariable* control, const LLSD&)> commit_signal_t;
+ typedef boost::signals2::signal<void(LLControlVariable* control, const LLSD&, const LLSD&)> commit_signal_t;
+
+ enum ePersist
+ {
+ PERSIST_NO, // don't save this var
+ PERSIST_NONDFT, // save this var if differs from default
+ PERSIST_ALWAYS // save this var even if has default value
+ };
private:
std::string mName;
std::string mComment;
eControlType mType;
- bool mPersist;
+ ePersist mPersist;
bool mHideFromSettingsEditor;
std::vector<LLSD> mValues;
-
+
commit_signal_t mCommitSignal;
validate_signal_t mValidateSignal;
public:
LLControlVariable(const std::string& name, eControlType type,
LLSD initial, const std::string& comment,
- bool persist = true, bool hidefromsettingseditor = false);
+ ePersist persist = PERSIST_NONDFT, bool hidefromsettingseditor = false);
virtual ~LLControlVariable();
@@ -131,8 +136,8 @@ public:
validate_signal_t* getValidateSignal() { return &mValidateSignal; }
bool isDefault() { return (mValues.size() == 1); }
- bool isSaveValueDefault();
- bool isPersisted() { return mPersist; }
+ bool shouldSave(bool nondefault_only);
+ bool isPersisted() { return mPersist != PERSIST_NO; }
bool isHiddenFromSettingsEditor() { return mHideFromSettingsEditor; }
LLSD get() const { return getValue(); }
LLSD getValue() const { return mValues.back(); }
@@ -142,15 +147,15 @@ public:
void set(const LLSD& val) { setValue(val); }
void setValue(const LLSD& value, bool saved_value = TRUE);
void setDefaultValue(const LLSD& value);
- void setPersist(bool state);
+ void setPersist(ePersist);
void setHiddenFromSettingsEditor(bool hide);
void setComment(const std::string& comment);
- void firePropertyChanged()
+private:
+ void firePropertyChanged(const LLSD &pPreviousValue)
{
- mCommitSignal(this, mValues.back());
+ mCommitSignal(this, mValues.back(), pPreviousValue);
}
-private:
LLSD getComparableValue(const LLSD& value);
bool llsd_compare(const LLSD& a, const LLSD & b);
};
@@ -207,19 +212,19 @@ public:
virtual void apply(const std::string& name, LLControlVariable* control) = 0;
};
void applyToAll(ApplyFunctor* func);
-
- BOOL declareControl(const std::string& name, eControlType type, const LLSD initial_val, const std::string& comment, BOOL persist, BOOL hidefromsettingseditor = FALSE);
- BOOL declareU32(const std::string& name, U32 initial_val, const std::string& comment, BOOL persist = TRUE);
- BOOL declareS32(const std::string& name, S32 initial_val, const std::string& comment, BOOL persist = TRUE);
- BOOL declareF32(const std::string& name, F32 initial_val, const std::string& comment, BOOL persist = TRUE);
- BOOL declareBOOL(const std::string& name, BOOL initial_val, const std::string& comment, BOOL persist = TRUE);
- BOOL declareString(const std::string& name, const std::string &initial_val, const std::string& comment, BOOL persist = TRUE);
- BOOL declareVec3(const std::string& name, const LLVector3 &initial_val,const std::string& comment, BOOL persist = TRUE);
- BOOL declareVec3d(const std::string& name, const LLVector3d &initial_val, const std::string& comment, BOOL persist = TRUE);
- BOOL declareRect(const std::string& name, const LLRect &initial_val, const std::string& comment, BOOL persist = TRUE);
- BOOL declareColor4(const std::string& name, const LLColor4 &initial_val, const std::string& comment, BOOL persist = TRUE);
- BOOL declareColor3(const std::string& name, const LLColor3 &initial_val, const std::string& comment, BOOL persist = TRUE);
- BOOL declareLLSD(const std::string& name, const LLSD &initial_val, const std::string& comment, BOOL persist = TRUE);
+
+ LLControlVariable* declareControl(const std::string& name, eControlType type, const LLSD initial_val, const std::string& comment, LLControlVariable::ePersist persist, BOOL hidefromsettingseditor = FALSE);
+ LLControlVariable* declareU32(const std::string& name, U32 initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT);
+ LLControlVariable* declareS32(const std::string& name, S32 initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT);
+ LLControlVariable* declareF32(const std::string& name, F32 initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT);
+ LLControlVariable* declareBOOL(const std::string& name, BOOL initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT);
+ LLControlVariable* declareString(const std::string& name, const std::string &initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT);
+ LLControlVariable* declareVec3(const std::string& name, const LLVector3 &initial_val,const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT);
+ LLControlVariable* declareVec3d(const std::string& name, const LLVector3d &initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT);
+ LLControlVariable* declareRect(const std::string& name, const LLRect &initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT);
+ LLControlVariable* declareColor4(const std::string& name, const LLColor4 &initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT);
+ LLControlVariable* declareColor3(const std::string& name, const LLColor3 &initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT);
+ LLControlVariable* declareLLSD(const std::string& name, const LLSD &initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT);
std::string getString(const std::string& name);
std::string getText(const std::string& name);
@@ -254,6 +259,7 @@ public:
else
{
llwarns << "Control " << name << " not found." << llendl;
+ return T();
}
return convert_from_llsd<T>(value, type, name);
}
@@ -367,7 +373,7 @@ private:
init_value = convert_to_llsd(default_value);
if(type < TYPE_COUNT)
{
- group.declareControl(name, type, init_value, comment, FALSE);
+ group.declareControl(name, type, init_value, comment, LLControlVariable::PERSIST_NO);
return true;
}
return false;
@@ -402,16 +408,6 @@ public:
}
}
- LLCachedControl(LLControlGroup& group,
- const std::string& name)
- {
- mCachedControlPtr = LLControlCache<T>::getInstance(name);
- if (mCachedControlPtr.isNull())
- {
- mCachedControlPtr = new LLControlCache<T>(group, name);
- }
- }
-
operator const T&() const { return mCachedControlPtr->getValue(); }
operator boost::function<const T&()> () const { return boost::function<const T&()>(*this); }
const T& operator()() { return mCachedControlPtr->getValue(); }
diff --git a/indra/llxml/llcontrolgroupreader.h b/indra/llxml/llcontrolgroupreader.h
index 6a27a65499..6a27a65499 100644..100755
--- a/indra/llxml/llcontrolgroupreader.h
+++ b/indra/llxml/llcontrolgroupreader.h
diff --git a/indra/llxml/llxmlnode.cpp b/indra/llxml/llxmlnode.cpp
index 2ffb0d8503..7aa2ce9606 100644..100755
--- a/indra/llxml/llxmlnode.cpp
+++ b/indra/llxml/llxmlnode.cpp
@@ -147,13 +147,15 @@ LLXMLNodePtr LLXMLNode::deepCopy()
for (LLXMLChildList::iterator iter = mChildren->map.begin();
iter != mChildren->map.end(); ++iter)
{
- newnode->addChild(iter->second->deepCopy());
+ LLXMLNodePtr temp_ptr_for_gcc(iter->second->deepCopy());
+ newnode->addChild(temp_ptr_for_gcc);
}
}
for (LLXMLAttribList::iterator iter = mAttributes.begin();
iter != mAttributes.end(); ++iter)
{
- newnode->addChild(iter->second->deepCopy());
+ LLXMLNodePtr temp_ptr_for_gcc(iter->second->deepCopy());
+ newnode->addChild(temp_ptr_for_gcc);
}
return newnode;
@@ -259,7 +261,7 @@ BOOL LLXMLNode::removeChild(LLXMLNode *target_child)
return FALSE;
}
-void LLXMLNode::addChild(LLXMLNodePtr new_child, LLXMLNodePtr after_child)
+void LLXMLNode::addChild(LLXMLNodePtr& new_child)
{
if (new_child->mParent != NULL)
{
@@ -273,6 +275,11 @@ void LLXMLNode::addChild(LLXMLNodePtr new_child, LLXMLNodePtr after_child)
new_child->mParent = this;
if (new_child->mIsAttribute)
{
+ LLXMLAttribList::iterator found_it = mAttributes.find(new_child->mName);
+ if (found_it != mAttributes.end())
+ {
+ removeChild(found_it->second);
+ }
mAttributes.insert(std::make_pair(new_child->mName, new_child));
}
else
@@ -285,49 +292,11 @@ void LLXMLNode::addChild(LLXMLNodePtr new_child, LLXMLNodePtr after_child)
}
mChildren->map.insert(std::make_pair(new_child->mName, new_child));
- // if after_child is specified, it damn well better be in the list of children
- // for this node. I'm not going to assert that, because it would be expensive,
- // but don't specify that parameter if you didn't get the value for it from the
- // list of children of this node!
- if (after_child.isNull())
- {
- if (mChildren->tail != new_child)
- {
- mChildren->tail->mNext = new_child;
- new_child->mPrev = mChildren->tail;
- mChildren->tail = new_child;
- }
- }
- // if after_child == parent, then put new_child at beginning
- else if (after_child == this)
- {
- // add to front of list
- new_child->mNext = mChildren->head;
- if (mChildren->head)
- {
- mChildren->head->mPrev = new_child;
- mChildren->head = new_child;
- }
- else // no children
- {
- mChildren->head = new_child;
- mChildren->tail = new_child;
- }
- }
- else
+ if (mChildren->tail != new_child)
{
- if (after_child->mNext.notNull())
- {
- // if after_child was not the last item, fix up some pointers
- after_child->mNext->mPrev = new_child;
- new_child->mNext = after_child->mNext;
- }
- new_child->mPrev = after_child;
- after_child->mNext = new_child;
- if (mChildren->tail == after_child)
- {
- mChildren->tail = new_child;
- }
+ mChildren->tail->mNext = new_child;
+ new_child->mPrev = mChildren->tail;
+ mChildren->tail = new_child;
}
}
@@ -343,8 +312,9 @@ LLXMLNodePtr LLXMLNode::createChild(const char* name, BOOL is_attribute)
// virtual
LLXMLNodePtr LLXMLNode::createChild(LLStringTableEntry* name, BOOL is_attribute)
{
- LLXMLNode* ret = new LLXMLNode(name, is_attribute);
+ LLXMLNodePtr ret(new LLXMLNode(name, is_attribute));
ret->mID.clear();
+
addChild(ret);
return ret;
}
@@ -358,11 +328,12 @@ BOOL LLXMLNode::deleteChild(LLXMLNode *child)
return FALSE;
}
-void LLXMLNode::setParent(LLXMLNodePtr new_parent)
+void LLXMLNode::setParent(LLXMLNodePtr& new_parent)
{
if (new_parent.notNull())
{
- new_parent->addChild(this);
+ LLXMLNodePtr this_ptr(this);
+ new_parent->addChild(this_ptr);
}
else
{
@@ -681,27 +652,6 @@ bool LLXMLNode::updateNode(
return TRUE;
}
-
-// static
-LLXMLNodePtr LLXMLNode::replaceNode(LLXMLNodePtr node, LLXMLNodePtr update_node)
-{
- if (!node || !update_node)
- {
- llwarns << "Node invalid" << llendl;
- return node;
- }
-
- LLXMLNodePtr cloned_node = update_node->deepCopy();
- node->mParent->addChild(cloned_node, node); // add after node
- LLXMLNodePtr parent = node->mParent;
- parent->removeChild(node);
- parent->updateDefault();
-
- return cloned_node;
-}
-
-
-
// static
bool LLXMLNode::parseFile(const std::string& filename, LLXMLNodePtr& node, LLXMLNode* defaults_tree)
{
@@ -897,7 +847,8 @@ bool LLXMLNode::getLayeredXMLNode(LLXMLNodePtr& root,
std::vector<std::string>::const_iterator itor;
- for (itor = paths.begin(), ++itor; itor != paths.end(); ++itor)
+ // We've already dealt with the first item, skip that one
+ for (itor = paths.begin() + 1; itor != paths.end(); ++itor)
{
std::string layer_filename = *itor;
if(layer_filename.empty() || layer_filename == filename)
@@ -1198,7 +1149,8 @@ void LLXMLNode::scrubToTree(LLXMLNode *tree)
std::vector<LLXMLNodePtr>::iterator itor3;
for (itor3=to_delete_list.begin(); itor3!=to_delete_list.end(); ++itor3)
{
- (*itor3)->setParent(NULL);
+ LLXMLNodePtr ptr;
+ (*itor3)->setParent(ptr);
}
}
}
@@ -2733,7 +2685,8 @@ void LLXMLNode::setName(LLStringTableEntry* name)
mName = name;
if (old_parent)
{
- old_parent->addChild(this);
+ LLXMLNodePtr this_ptr(this);
+ old_parent->addChild(this_ptr);
}
}
diff --git a/indra/llxml/llxmlnode.h b/indra/llxml/llxmlnode.h
index e3da7169e7..ec486d7957 100644..100755
--- a/indra/llxml/llxmlnode.h
+++ b/indra/llxml/llxmlnode.h
@@ -127,8 +127,8 @@ public:
BOOL isNull();
BOOL deleteChild(LLXMLNode* child);
- void addChild(LLXMLNodePtr new_child, LLXMLNodePtr after_child = LLXMLNodePtr(NULL));
- void setParent(LLXMLNodePtr new_parent); // reparent if necessary
+ void addChild(LLXMLNodePtr& new_child);
+ void setParent(LLXMLNodePtr& new_parent); // reparent if necessary
// Serialization
static bool parseFile(
@@ -147,7 +147,6 @@ public:
static bool updateNode(
LLXMLNodePtr& node,
LLXMLNodePtr& update_node);
- static LLXMLNodePtr replaceNode(LLXMLNodePtr node, LLXMLNodePtr replacement_node);
static bool getLayeredXMLNode(LLXMLNodePtr& root, const std::vector<std::string>& paths);
diff --git a/indra/llxml/llxmlparser.cpp b/indra/llxml/llxmlparser.cpp
index 7db4a90b57..7db4a90b57 100644..100755
--- a/indra/llxml/llxmlparser.cpp
+++ b/indra/llxml/llxmlparser.cpp
diff --git a/indra/llxml/llxmlparser.h b/indra/llxml/llxmlparser.h
index e0f8b69452..e0f8b69452 100644..100755
--- a/indra/llxml/llxmlparser.h
+++ b/indra/llxml/llxmlparser.h
diff --git a/indra/llxml/llxmltree.cpp b/indra/llxml/llxmltree.cpp
index f2386700a1..f2386700a1 100644..100755
--- a/indra/llxml/llxmltree.cpp
+++ b/indra/llxml/llxmltree.cpp
diff --git a/indra/llxml/llxmltree.h b/indra/llxml/llxmltree.h
index bdcb56f1f3..bdcb56f1f3 100644..100755
--- a/indra/llxml/llxmltree.h
+++ b/indra/llxml/llxmltree.h
diff --git a/indra/llxml/tests/llcontrol_test.cpp b/indra/llxml/tests/llcontrol_test.cpp
index ede81956ec..c273773c9b 100644..100755
--- a/indra/llxml/tests/llcontrol_test.cpp
+++ b/indra/llxml/tests/llcontrol_test.cpp
@@ -128,7 +128,11 @@ namespace tut
template<> template<>
void control_group_t::test<3>()
{
- int results = mCG->loadFromFile(mTestConfigFile.c_str());
+ // Pass default_values = true. This tells loadFromFile() we're loading
+ // a default settings file that declares variables, rather than a user
+ // settings file. When loadFromFile() encounters an unrecognized user
+ // settings variable, it forcibly preserves it (CHOP-962).
+ int results = mCG->loadFromFile(mTestConfigFile.c_str(), true);
LLControlVariable* control = mCG->getControl("TestSetting");
LLSD new_value = 13;
control->setValue(new_value, FALSE);
diff --git a/indra/llxuixml/CMakeLists.txt b/indra/llxuixml/CMakeLists.txt
deleted file mode 100644
index daed4de6ce..0000000000
--- a/indra/llxuixml/CMakeLists.txt
+++ /dev/null
@@ -1,45 +0,0 @@
-# -*- cmake -*-
-
-project(llxuixml)
-
-include(00-Common)
-include(LLCommon)
-include(LLMath)
-include(LLXML)
-
-include_directories(
- ${LLCOMMON_INCLUDE_DIRS}
- ${LLMATH_INCLUDE_DIRS}
- ${LLXML_INCLUDE_DIRS}
- )
-
-set(llxuixml_SOURCE_FILES
- llinitparam.cpp
- lltrans.cpp
- lluicolor.cpp
- llxuiparser.cpp
- )
-
-set(llxuixml_HEADER_FILES
- CMakeLists.txt
-
- llinitparam.h
- lltrans.h
- llregistry.h
- lluicolor.h
- llxuiparser.h
- )
-
-set_source_files_properties(${llxuixml_HEADER_FILES}
- PROPERTIES HEADER_FILE_ONLY TRUE)
-
-list(APPEND llxuixml_SOURCE_FILES ${llxuixml_HEADER_FILES})
-
-add_library (llxuixml ${llxuixml_SOURCE_FILES})
-# Libraries on which this library depends, needed for Linux builds
-# Sort by high-level to low-level
-target_link_libraries(llxuixml
- llxml
- llcommon
- llmath
- )
diff --git a/indra/llxuixml/llinitparam.cpp b/indra/llxuixml/llinitparam.cpp
deleted file mode 100644
index db72aa19b9..0000000000
--- a/indra/llxuixml/llinitparam.cpp
+++ /dev/null
@@ -1,469 +0,0 @@
-/**
- * @file llinitparam.cpp
- * @brief parameter block abstraction for creating complex objects and
- * parsing construction parameters from xml and LLSD
- *
- * $LicenseInfo:firstyear=2008&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 "llinitparam.h"
-
-
-namespace LLInitParam
-{
- //
- // Param
- //
- Param::Param(BaseBlock* enclosing_block)
- : mIsProvided(false)
- {
- const U8* my_addr = reinterpret_cast<const U8*>(this);
- const U8* block_addr = reinterpret_cast<const U8*>(enclosing_block);
- mEnclosingBlockOffset = 0x7FFFffff & (U32)(my_addr - block_addr);
- }
-
- //
- // ParamDescriptor
- //
- ParamDescriptor::ParamDescriptor(param_handle_t p,
- merge_func_t merge_func,
- deserialize_func_t deserialize_func,
- serialize_func_t serialize_func,
- validation_func_t validation_func,
- inspect_func_t inspect_func,
- S32 min_count,
- S32 max_count)
- : mParamHandle(p),
- mMergeFunc(merge_func),
- mDeserializeFunc(deserialize_func),
- mSerializeFunc(serialize_func),
- mValidationFunc(validation_func),
- mInspectFunc(inspect_func),
- mMinCount(min_count),
- mMaxCount(max_count),
- mUserData(NULL)
- {}
-
- ParamDescriptor::ParamDescriptor()
- : mParamHandle(0),
- mMergeFunc(NULL),
- mDeserializeFunc(NULL),
- mSerializeFunc(NULL),
- mValidationFunc(NULL),
- mInspectFunc(NULL),
- mMinCount(0),
- mMaxCount(0),
- mUserData(NULL)
- {}
-
- ParamDescriptor::~ParamDescriptor()
- {
- delete mUserData;
- }
-
- //
- // Parser
- //
- Parser::~Parser()
- {}
-
- void Parser::parserWarning(const std::string& message)
- {
- if (mParseSilently) return;
- llwarns << message << llendl;
- }
-
- void Parser::parserError(const std::string& message)
- {
- if (mParseSilently) return;
- llerrs << message << llendl;
- }
-
-
- //
- // BlockDescriptor
- //
- void BlockDescriptor::aggregateBlockData(BlockDescriptor& src_block_data)
- {
- mNamedParams.insert(src_block_data.mNamedParams.begin(), src_block_data.mNamedParams.end());
- std::copy(src_block_data.mUnnamedParams.begin(), src_block_data.mUnnamedParams.end(), std::back_inserter(mUnnamedParams));
- std::copy(src_block_data.mValidationList.begin(), src_block_data.mValidationList.end(), std::back_inserter(mValidationList));
- std::copy(src_block_data.mAllParams.begin(), src_block_data.mAllParams.end(), std::back_inserter(mAllParams));
- }
-
- BlockDescriptor::BlockDescriptor()
- : mMaxParamOffset(0),
- mInitializationState(UNINITIALIZED),
- mCurrentBlockPtr(NULL)
- {}
-
- // called by each derived class in least to most derived order
- void BaseBlock::init(BlockDescriptor& descriptor, BlockDescriptor& base_descriptor, size_t block_size)
- {
- descriptor.mCurrentBlockPtr = this;
- descriptor.mMaxParamOffset = block_size;
-
- switch(descriptor.mInitializationState)
- {
- case BlockDescriptor::UNINITIALIZED:
- // copy params from base class here
- descriptor.aggregateBlockData(base_descriptor);
-
- descriptor.mInitializationState = BlockDescriptor::INITIALIZING;
- break;
- case BlockDescriptor::INITIALIZING:
- descriptor.mInitializationState = BlockDescriptor::INITIALIZED;
- break;
- case BlockDescriptor::INITIALIZED:
- // nothing to do
- break;
- }
- }
-
- param_handle_t BaseBlock::getHandleFromParam(const Param* param) const
- {
- const U8* param_address = reinterpret_cast<const U8*>(param);
- const U8* baseblock_address = reinterpret_cast<const U8*>(this);
- return (param_address - baseblock_address);
- }
-
- bool BaseBlock::submitValue(Parser::name_stack_t& name_stack, Parser& p, bool silent)
- {
- if (!deserializeBlock(p, std::make_pair(name_stack.begin(), name_stack.end()), true))
- {
- if (!silent)
- {
- p.parserWarning(llformat("Failed to parse parameter \"%s\"", p.getCurrentElementName().c_str()));
- }
- return false;
- }
- return true;
- }
-
-
- bool BaseBlock::validateBlock(bool emit_errors) const
- {
- const BlockDescriptor& block_data = mostDerivedBlockDescriptor();
- for (BlockDescriptor::param_validation_list_t::const_iterator it = block_data.mValidationList.begin(); it != block_data.mValidationList.end(); ++it)
- {
- const Param* param = getParamFromHandle(it->first);
- if (!it->second(param))
- {
- if (emit_errors)
- {
- llwarns << "Invalid param \"" << getParamName(block_data, param) << "\"" << llendl;
- }
- return false;
- }
- }
- return true;
- }
-
- void BaseBlock::serializeBlock(Parser& parser, Parser::name_stack_t& name_stack, const LLInitParam::BaseBlock* diff_block) const
- {
- // named param is one like LLView::Params::follows
- // unnamed param is like LLView::Params::rect - implicit
- const BlockDescriptor& block_data = mostDerivedBlockDescriptor();
-
- for (BlockDescriptor::param_list_t::const_iterator it = block_data.mUnnamedParams.begin();
- it != block_data.mUnnamedParams.end();
- ++it)
- {
- param_handle_t param_handle = (*it)->mParamHandle;
- const Param* param = getParamFromHandle(param_handle);
- ParamDescriptor::serialize_func_t serialize_func = (*it)->mSerializeFunc;
- if (serialize_func)
- {
- const Param* diff_param = diff_block ? diff_block->getParamFromHandle(param_handle) : NULL;
- // each param descriptor remembers its serial number
- // so we can inspect the same param under different names
- // and see that it has the same number
- name_stack.push_back(std::make_pair("", true));
- serialize_func(*param, parser, name_stack, diff_param);
- name_stack.pop_back();
- }
- }
-
- for(BlockDescriptor::param_map_t::const_iterator it = block_data.mNamedParams.begin();
- it != block_data.mNamedParams.end();
- ++it)
- {
- param_handle_t param_handle = it->second->mParamHandle;
- const Param* param = getParamFromHandle(param_handle);
- ParamDescriptor::serialize_func_t serialize_func = it->second->mSerializeFunc;
- if (serialize_func && param->anyProvided())
- {
- // Ensure this param has not already been serialized
- // Prevents <rect> from being serialized as its own tag.
- bool duplicate = false;
- for (BlockDescriptor::param_list_t::const_iterator it2 = block_data.mUnnamedParams.begin();
- it2 != block_data.mUnnamedParams.end();
- ++it2)
- {
- if (param_handle == (*it2)->mParamHandle)
- {
- duplicate = true;
- break;
- }
- }
-
- //FIXME: for now, don't attempt to serialize values under synonyms, as current parsers
- // don't know how to detect them
- if (duplicate)
- {
- continue;
- }
-
- name_stack.push_back(std::make_pair(it->first, !duplicate));
- const Param* diff_param = diff_block ? diff_block->getParamFromHandle(param_handle) : NULL;
- serialize_func(*param, parser, name_stack, diff_param);
- name_stack.pop_back();
- }
- }
- }
-
- bool BaseBlock::inspectBlock(Parser& parser, Parser::name_stack_t name_stack, S32 min_count, S32 max_count) const
- {
- // named param is one like LLView::Params::follows
- // unnamed param is like LLView::Params::rect - implicit
- const BlockDescriptor& block_data = mostDerivedBlockDescriptor();
-
- for (BlockDescriptor::param_list_t::const_iterator it = block_data.mUnnamedParams.begin();
- it != block_data.mUnnamedParams.end();
- ++it)
- {
- param_handle_t param_handle = (*it)->mParamHandle;
- const Param* param = getParamFromHandle(param_handle);
- ParamDescriptor::inspect_func_t inspect_func = (*it)->mInspectFunc;
- if (inspect_func)
- {
- name_stack.push_back(std::make_pair("", true));
- inspect_func(*param, parser, name_stack, (*it)->mMinCount, (*it)->mMaxCount);
- name_stack.pop_back();
- }
- }
-
- for(BlockDescriptor::param_map_t::const_iterator it = block_data.mNamedParams.begin();
- it != block_data.mNamedParams.end();
- ++it)
- {
- param_handle_t param_handle = it->second->mParamHandle;
- const Param* param = getParamFromHandle(param_handle);
- ParamDescriptor::inspect_func_t inspect_func = it->second->mInspectFunc;
- if (inspect_func)
- {
- // Ensure this param has not already been inspected
- bool duplicate = false;
- for (BlockDescriptor::param_list_t::const_iterator it2 = block_data.mUnnamedParams.begin();
- it2 != block_data.mUnnamedParams.end();
- ++it2)
- {
- if (param_handle == (*it2)->mParamHandle)
- {
- duplicate = true;
- break;
- }
- }
-
- name_stack.push_back(std::make_pair(it->first, !duplicate));
- inspect_func(*param, parser, name_stack, it->second->mMinCount, it->second->mMaxCount);
- name_stack.pop_back();
- }
- }
-
- return true;
- }
-
- bool BaseBlock::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack_range, bool ignored)
- {
- BlockDescriptor& block_data = mostDerivedBlockDescriptor();
- bool names_left = name_stack_range.first != name_stack_range.second;
-
- bool new_name = names_left
- ? name_stack_range.first->second
- : true;
-
- if (names_left)
- {
- const std::string& top_name = name_stack_range.first->first;
-
- ParamDescriptor::deserialize_func_t deserialize_func = NULL;
- Param* paramp = NULL;
-
- BlockDescriptor::param_map_t::iterator found_it = block_data.mNamedParams.find(top_name);
- if (found_it != block_data.mNamedParams.end())
- {
- // find pointer to member parameter from offset table
- paramp = getParamFromHandle(found_it->second->mParamHandle);
- deserialize_func = found_it->second->mDeserializeFunc;
-
- Parser::name_stack_range_t new_name_stack(name_stack_range.first, name_stack_range.second);
- ++new_name_stack.first;
- if (deserialize_func(*paramp, p, new_name_stack, new_name))
- {
- // value is no longer new, we know about it now
- name_stack_range.first->second = false;
- return true;
- }
- else
- {
- return false;
- }
- }
- }
-
- // try to parse unnamed parameters, in declaration order
- for ( BlockDescriptor::param_list_t::iterator it = block_data.mUnnamedParams.begin();
- it != block_data.mUnnamedParams.end();
- ++it)
- {
- Param* paramp = getParamFromHandle((*it)->mParamHandle);
- ParamDescriptor::deserialize_func_t deserialize_func = (*it)->mDeserializeFunc;
-
- if (deserialize_func && deserialize_func(*paramp, p, name_stack_range, new_name))
- {
- return true;
- }
- }
-
- // if no match, and no names left on stack, this is just an existence assertion of this block
- // verify by calling readValue with NoParamValue type, an inherently unparseable type
- if (!names_left)
- {
- Flag no_value;
- return p.readValue(no_value);
- }
-
- return false;
- }
-
- //static
- void BaseBlock::addParam(BlockDescriptor& block_data, const ParamDescriptorPtr in_param, const char* char_name)
- {
- // create a copy of the param descriptor in mAllParams
- // so other data structures can store a pointer to it
- block_data.mAllParams.push_back(in_param);
- ParamDescriptorPtr param(block_data.mAllParams.back());
-
- std::string name(char_name);
- if ((size_t)param->mParamHandle > block_data.mMaxParamOffset)
- {
- llerrs << "Attempted to register param with block defined for parent class, make sure to derive from LLInitParam::Block<YOUR_CLASS, PARAM_BLOCK_BASE_CLASS>" << llendl;
- }
-
- if (name.empty())
- {
- block_data.mUnnamedParams.push_back(param);
- }
- else
- {
- // don't use insert, since we want to overwrite existing entries
- block_data.mNamedParams[name] = param;
- }
-
- if (param->mValidationFunc)
- {
- block_data.mValidationList.push_back(std::make_pair(param->mParamHandle, param->mValidationFunc));
- }
- }
-
- void BaseBlock::addSynonym(Param& param, const std::string& synonym)
- {
- BlockDescriptor& block_data = mostDerivedBlockDescriptor();
- if (block_data.mInitializationState == BlockDescriptor::INITIALIZING)
- {
- param_handle_t handle = getHandleFromParam(&param);
-
- // check for invalid derivation from a paramblock (i.e. without using
- // Block<T, Base_Class>
- if ((size_t)handle > block_data.mMaxParamOffset)
- {
- llerrs << "Attempted to register param with block defined for parent class, make sure to derive from LLInitParam::Block<YOUR_CLASS, PARAM_BLOCK_BASE_CLASS>" << llendl;
- }
-
- ParamDescriptorPtr param_descriptor = findParamDescriptor(param);
- if (param_descriptor)
- {
- if (synonym.empty())
- {
- block_data.mUnnamedParams.push_back(param_descriptor);
- }
- else
- {
- block_data.mNamedParams[synonym] = param_descriptor;
- }
- }
- }
- }
-
- const std::string& BaseBlock::getParamName(const BlockDescriptor& block_data, const Param* paramp) const
- {
- param_handle_t handle = getHandleFromParam(paramp);
- for (BlockDescriptor::param_map_t::const_iterator it = block_data.mNamedParams.begin(); it != block_data.mNamedParams.end(); ++it)
- {
- if (it->second->mParamHandle == handle)
- {
- return it->first;
- }
- }
-
- return LLStringUtil::null;
- }
-
- ParamDescriptorPtr BaseBlock::findParamDescriptor(const Param& param)
- {
- param_handle_t handle = getHandleFromParam(&param);
- BlockDescriptor& descriptor = mostDerivedBlockDescriptor();
- BlockDescriptor::all_params_list_t::iterator end_it = descriptor.mAllParams.end();
- for (BlockDescriptor::all_params_list_t::iterator it = descriptor.mAllParams.begin();
- it != end_it;
- ++it)
- {
- if ((*it)->mParamHandle == handle) return *it;
- }
- return ParamDescriptorPtr();
- }
-
- // take all provided params from other and apply to self
- // NOTE: this requires that "other" is of the same derived type as this
- bool BaseBlock::mergeBlock(BlockDescriptor& block_data, const BaseBlock& other, bool overwrite)
- {
- bool some_param_changed = false;
- BlockDescriptor::all_params_list_t::const_iterator end_it = block_data.mAllParams.end();
- for (BlockDescriptor::all_params_list_t::const_iterator it = block_data.mAllParams.begin();
- it != end_it;
- ++it)
- {
- const Param* other_paramp = other.getParamFromHandle((*it)->mParamHandle);
- ParamDescriptor::merge_func_t merge_func = (*it)->mMergeFunc;
- if (merge_func)
- {
- Param* paramp = getParamFromHandle((*it)->mParamHandle);
- llassert(paramp->mEnclosingBlockOffset == (*it)->mParamHandle);
- some_param_changed |= merge_func(*paramp, *other_paramp, overwrite);
- }
- }
- return some_param_changed;
- }
-}
diff --git a/indra/llxuixml/llinitparam.h b/indra/llxuixml/llinitparam.h
deleted file mode 100644
index 4ab1d891a3..0000000000
--- a/indra/llxuixml/llinitparam.h
+++ /dev/null
@@ -1,2299 +0,0 @@
-/**
- * @file llinitparam.h
- * @brief parameter block abstraction for creating complex objects and
- * parsing construction parameters from xml and LLSD
- *
- * $LicenseInfo:firstyear=2008&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$
- */
-
-#ifndef LL_LLPARAM_H
-#define LL_LLPARAM_H
-
-#include <vector>
-#include <boost/function.hpp>
-#include <boost/type_traits/is_convertible.hpp>
-#include <boost/unordered_map.hpp>
-#include <boost/shared_ptr.hpp>
-
-#include "llerror.h"
-
-namespace LLInitParam
-{
- // used to indicate no matching value to a given name when parsing
- struct Flag{};
-
- template<typename T> const T& defaultValue() { static T value; return value; }
-
- template <typename T, bool IS_BOOST_FUNCTION = boost::is_convertible<T, boost::function_base>::value >
- struct ParamCompare
- {
- static bool equals(const T &a, const T &b)
- {
- return a == b;
- }
- };
-
- // boost function types are not comparable
- template<typename T>
- struct ParamCompare<T, true>
- {
- static bool equals(const T&a, const T &b)
- {
- return false;
- }
- };
-
- template<>
- struct ParamCompare<LLSD, false>
- {
- static bool equals(const LLSD &a, const LLSD &b) { return false; }
- };
-
- template<>
- struct ParamCompare<Flag, false>
- {
- static bool equals(const Flag& a, const Flag& b) { return false; }
- };
-
-
- // helper functions and classes
- typedef ptrdiff_t param_handle_t;
-
- // empty default implementation of key cache
- // leverages empty base class optimization
- template <typename T>
- class TypeValues
- {
- private:
- struct Inaccessable{};
- public:
- typedef std::map<std::string, T> value_name_map_t;
- typedef Inaccessable name_t;
-
- void setValueName(const std::string& key) {}
- std::string getValueName() const { return ""; }
- std::string calcValueName(const T& value) const { return ""; }
- void clearValueName() const {}
-
- static bool getValueFromName(const std::string& name, T& value)
- {
- return false;
- }
-
- static bool valueNamesExist()
- {
- return false;
- }
-
- static std::vector<std::string>* getPossibleValues()
- {
- return NULL;
- }
-
- static value_name_map_t* getValueNames() {return NULL;}
- };
-
- template <typename T, typename DERIVED_TYPE = TypeValues<T> >
- class TypeValuesHelper
- {
- public:
- typedef typename std::map<std::string, T> value_name_map_t;
- typedef std::string name_t;
-
- //TODO: cache key by index to save on param block size
- void setValueName(const std::string& value_name)
- {
- mValueName = value_name;
- }
-
- std::string getValueName() const
- {
- return mValueName;
- }
-
- std::string calcValueName(const T& value) const
- {
- value_name_map_t* map = getValueNames();
- for (typename value_name_map_t::iterator it = map->begin(), end_it = map->end();
- it != end_it;
- ++it)
- {
- if (ParamCompare<T>::equals(it->second, value))
- {
- return it->first;
- }
- }
-
- return "";
- }
-
- void clearValueName() const
- {
- mValueName.clear();
- }
-
- static bool getValueFromName(const std::string& name, T& value)
- {
- value_name_map_t* map = getValueNames();
- typename value_name_map_t::iterator found_it = map->find(name);
- if (found_it == map->end()) return false;
-
- value = found_it->second;
- return true;
- }
-
- static bool valueNamesExist()
- {
- return !getValueNames()->empty();
- }
-
- static value_name_map_t* getValueNames()
- {
- static value_name_map_t sMap;
- static bool sInitialized = false;
-
- if (!sInitialized)
- {
- sInitialized = true;
- DERIVED_TYPE::declareValues();
- }
- return &sMap;
- }
-
- static std::vector<std::string>* getPossibleValues()
- {
- static std::vector<std::string> sValues;
-
- value_name_map_t* map = getValueNames();
- for (typename value_name_map_t::iterator it = map->begin(), end_it = map->end();
- it != end_it;
- ++it)
- {
- sValues.push_back(it->first);
- }
- return &sValues;
- }
-
- static void declare(const std::string& name, const T& value)
- {
- (*getValueNames())[name] = value;
- }
-
- protected:
- static void getName(const std::string& name, const T& value)
- {}
-
- mutable std::string mValueName;
- };
-
- class Parser
- {
- LOG_CLASS(Parser);
-
- public:
-
- struct CompareTypeID
- {
- bool operator()(const std::type_info* lhs, const std::type_info* rhs) const
- {
- return lhs->before(*rhs);
- }
- };
-
- typedef std::vector<std::pair<std::string, bool> > name_stack_t;
- typedef std::pair<name_stack_t::iterator, name_stack_t::iterator> name_stack_range_t;
- typedef std::vector<std::string> possible_values_t;
-
- typedef bool (*parser_read_func_t)(Parser& parser, void* output);
- typedef bool (*parser_write_func_t)(Parser& parser, const void*, name_stack_t&);
- typedef boost::function<void (name_stack_t&, S32, S32, const possible_values_t*)> parser_inspect_func_t;
-
- typedef std::map<const std::type_info*, parser_read_func_t, CompareTypeID> parser_read_func_map_t;
- typedef std::map<const std::type_info*, parser_write_func_t, CompareTypeID> parser_write_func_map_t;
- typedef std::map<const std::type_info*, parser_inspect_func_t, CompareTypeID> parser_inspect_func_map_t;
-
- Parser(parser_read_func_map_t& read_map, parser_write_func_map_t& write_map, parser_inspect_func_map_t& inspect_map)
- : mParseSilently(false),
- mParserReadFuncs(&read_map),
- mParserWriteFuncs(&write_map),
- mParserInspectFuncs(&inspect_map)
- {}
- virtual ~Parser();
-
- template <typename T> bool readValue(T& param)
- {
- parser_read_func_map_t::iterator found_it = mParserReadFuncs->find(&typeid(T));
- if (found_it != mParserReadFuncs->end())
- {
- return found_it->second(*this, (void*)&param);
- }
- return false;
- }
-
- template <typename T> bool writeValue(const T& param, name_stack_t& name_stack)
- {
- parser_write_func_map_t::iterator found_it = mParserWriteFuncs->find(&typeid(T));
- if (found_it != mParserWriteFuncs->end())
- {
- return found_it->second(*this, (const void*)&param, name_stack);
- }
- return false;
- }
-
- // dispatch inspection to registered inspection functions, for each parameter in a param block
- template <typename T> bool inspectValue(name_stack_t& name_stack, S32 min_count, S32 max_count, const possible_values_t* possible_values)
- {
- parser_inspect_func_map_t::iterator found_it = mParserInspectFuncs->find(&typeid(T));
- if (found_it != mParserInspectFuncs->end())
- {
- found_it->second(name_stack, min_count, max_count, possible_values);
- return true;
- }
- return false;
- }
-
- virtual std::string getCurrentElementName() = 0;
- virtual void parserWarning(const std::string& message);
- virtual void parserError(const std::string& message);
- void setParseSilently(bool silent) { mParseSilently = silent; }
-
- protected:
- template <typename T>
- void registerParserFuncs(parser_read_func_t read_func, parser_write_func_t write_func = NULL)
- {
- mParserReadFuncs->insert(std::make_pair(&typeid(T), read_func));
- mParserWriteFuncs->insert(std::make_pair(&typeid(T), write_func));
- }
-
- template <typename T>
- void registerInspectFunc(parser_inspect_func_t inspect_func)
- {
- mParserInspectFuncs->insert(std::make_pair(&typeid(T), inspect_func));
- }
-
- bool mParseSilently;
-
- private:
- parser_read_func_map_t* mParserReadFuncs;
- parser_write_func_map_t* mParserWriteFuncs;
- parser_inspect_func_map_t* mParserInspectFuncs;
- };
-
- class Param;
-
- // various callbacks and constraints associated with an individual param
- struct ParamDescriptor
- {
- struct UserData
- {
- virtual ~UserData() {}
- };
-
- typedef bool(*merge_func_t)(Param&, const Param&, bool);
- typedef bool(*deserialize_func_t)(Param&, Parser&, const Parser::name_stack_range_t&, bool);
- typedef void(*serialize_func_t)(const Param&, Parser&, Parser::name_stack_t&, const Param* diff_param);
- typedef void(*inspect_func_t)(const Param&, Parser&, Parser::name_stack_t&, S32 min_count, S32 max_count);
- typedef bool(*validation_func_t)(const Param*);
-
- ParamDescriptor(param_handle_t p,
- merge_func_t merge_func,
- deserialize_func_t deserialize_func,
- serialize_func_t serialize_func,
- validation_func_t validation_func,
- inspect_func_t inspect_func,
- S32 min_count,
- S32 max_count);
-
- ParamDescriptor();
- ~ParamDescriptor();
-
- param_handle_t mParamHandle;
- merge_func_t mMergeFunc;
- deserialize_func_t mDeserializeFunc;
- serialize_func_t mSerializeFunc;
- inspect_func_t mInspectFunc;
- validation_func_t mValidationFunc;
- S32 mMinCount;
- S32 mMaxCount;
- S32 mNumRefs;
- UserData* mUserData;
- };
-
- typedef boost::shared_ptr<ParamDescriptor> ParamDescriptorPtr;
-
- // each derived Block class keeps a static data structure maintaining offsets to various params
- class BlockDescriptor
- {
- public:
- BlockDescriptor();
-
- typedef enum e_initialization_state
- {
- UNINITIALIZED,
- INITIALIZING,
- INITIALIZED
- } EInitializationState;
-
- void aggregateBlockData(BlockDescriptor& src_block_data);
-
- typedef boost::unordered_map<const std::string, ParamDescriptorPtr> param_map_t;
- typedef std::vector<ParamDescriptorPtr> param_list_t;
- typedef std::list<ParamDescriptorPtr> all_params_list_t;
- typedef std::vector<std::pair<param_handle_t, ParamDescriptor::validation_func_t> > param_validation_list_t;
-
- param_map_t mNamedParams; // parameters with associated names
- param_list_t mUnnamedParams; // parameters with_out_ associated names
- param_validation_list_t mValidationList; // parameters that must be validated
- all_params_list_t mAllParams; // all parameters, owns descriptors
- size_t mMaxParamOffset;
- EInitializationState mInitializationState; // whether or not static block data has been initialized
- class BaseBlock* mCurrentBlockPtr; // pointer to block currently being constructed
- };
-
- class BaseBlock
- {
- public:
- //TODO: implement in terms of owned_ptr
- template<typename T>
- class Lazy
- {
- public:
- Lazy()
- : mPtr(NULL)
- {}
-
- ~Lazy()
- {
- delete mPtr;
- }
-
- Lazy(const Lazy& other)
- {
- if (other.mPtr)
- {
- mPtr = new T(*other.mPtr);
- }
- else
- {
- mPtr = NULL;
- }
- }
-
- Lazy<T>& operator = (const Lazy<T>& other)
- {
- if (other.mPtr)
- {
- mPtr = new T(*other.mPtr);
- }
- else
- {
- mPtr = NULL;
- }
- return *this;
- }
-
- bool empty() const
- {
- return mPtr == NULL;
- }
-
- void set(const T& other)
- {
- delete mPtr;
- mPtr = new T(other);
- }
-
- const T& get() const
- {
- return ensureInstance();
- }
-
- T& get()
- {
- return ensureInstance();
- }
-
- private:
- // lazily allocate an instance of T
- T* ensureInstance() const
- {
- if (mPtr == NULL)
- {
- mPtr = new T();
- }
- return mPtr;
- }
-
- private:
- // if you get a compilation error with this, that means you are using a forward declared struct for T
- // unfortunately, the type traits we rely on don't work with forward declared typed
- //static const int dummy = sizeof(T);
-
- mutable T* mPtr;
- };
-
- // "Multiple" constraint types, put here in root class to avoid ambiguity during use
- struct AnyAmount
- {
- enum { minCount = 0 };
- enum { maxCount = U32_MAX };
- };
-
- template<U32 MIN_AMOUNT>
- struct AtLeast
- {
- enum { minCount = MIN_AMOUNT };
- enum { maxCount = U32_MAX };
- };
-
- template<U32 MAX_AMOUNT>
- struct AtMost
- {
- enum { minCount = 0 };
- enum { maxCount = MAX_AMOUNT };
- };
-
- template<U32 MIN_AMOUNT, U32 MAX_AMOUNT>
- struct Between
- {
- enum { minCount = MIN_AMOUNT };
- enum { maxCount = MAX_AMOUNT };
- };
-
- template<U32 EXACT_COUNT>
- struct Exactly
- {
- enum { minCount = EXACT_COUNT };
- enum { maxCount = EXACT_COUNT };
- };
-
- // this typedef identifies derived classes as being blocks
- typedef void baseblock_base_class_t;
- LOG_CLASS(BaseBlock);
- friend class Param;
-
- virtual ~BaseBlock() {}
- bool submitValue(Parser::name_stack_t& name_stack, Parser& p, bool silent=false);
-
- param_handle_t getHandleFromParam(const Param* param) const;
- bool validateBlock(bool emit_errors = true) const;
-
- Param* getParamFromHandle(const param_handle_t param_handle)
- {
- if (param_handle == 0) return NULL;
-
- U8* baseblock_address = reinterpret_cast<U8*>(this);
- return reinterpret_cast<Param*>(baseblock_address + param_handle);
- }
-
- const Param* getParamFromHandle(const param_handle_t param_handle) const
- {
- const U8* baseblock_address = reinterpret_cast<const U8*>(this);
- return reinterpret_cast<const Param*>(baseblock_address + param_handle);
- }
-
- void addSynonym(Param& param, const std::string& synonym);
-
- // Blocks can override this to do custom tracking of changes
- virtual void paramChanged(const Param& changed_param, bool user_provided) {}
-
- bool deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack_range, bool new_name);
- void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const BaseBlock* diff_block = NULL) const;
- bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const;
-
- virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return selfBlockDescriptor(); }
- virtual BlockDescriptor& mostDerivedBlockDescriptor() { return selfBlockDescriptor(); }
-
- // take all provided params from other and apply to self
- bool overwriteFrom(const BaseBlock& other)
- {
- return false;
- }
-
- // take all provided params that are not already provided, and apply to self
- bool fillFrom(const BaseBlock& other)
- {
- return false;
- }
-
- static void addParam(BlockDescriptor& block_data, ParamDescriptorPtr param, const char* name);
-
- ParamDescriptorPtr findParamDescriptor(const Param& param);
-
- protected:
- void init(BlockDescriptor& descriptor, BlockDescriptor& base_descriptor, size_t block_size);
-
-
- bool mergeBlockParam(bool source_provided, bool dst_provided, BlockDescriptor& block_data, const BaseBlock& source, bool overwrite)
- {
- return mergeBlock(block_data, source, overwrite);
- }
- // take all provided params from other and apply to self
- bool mergeBlock(BlockDescriptor& block_data, const BaseBlock& other, bool overwrite);
-
- static BlockDescriptor& selfBlockDescriptor()
- {
- static BlockDescriptor sBlockDescriptor;
- return sBlockDescriptor;
- }
-
- private:
- const std::string& getParamName(const BlockDescriptor& block_data, const Param* paramp) const;
- };
-
- template<typename T>
- struct ParamCompare<BaseBlock::Lazy<T>, false >
- {
- static bool equals(const BaseBlock::Lazy<T>& a, const BaseBlock::Lazy<T>& b) { return !a.empty() || !b.empty(); }
- };
-
- class Param
- {
- public:
- void setProvided(bool is_provided = true)
- {
- mIsProvided = is_provided;
- enclosingBlock().paramChanged(*this, is_provided);
- }
-
- Param& operator =(const Param& other)
- {
- mIsProvided = other.mIsProvided;
- // don't change mEnclosingblockoffset
- return *this;
- }
- protected:
-
- bool anyProvided() const { return mIsProvided; }
-
- Param(BaseBlock* enclosing_block);
-
- // store pointer to enclosing block as offset to reduce space and allow for quick copying
- BaseBlock& enclosingBlock() const
- {
- const U8* my_addr = reinterpret_cast<const U8*>(this);
- // get address of enclosing BLOCK class using stored offset to enclosing BaseBlock class
- return *const_cast<BaseBlock*>
- (reinterpret_cast<const BaseBlock*>
- (my_addr - (ptrdiff_t)(S32)mEnclosingBlockOffset));
- }
-
- private:
- friend class BaseBlock;
-
- U32 mEnclosingBlockOffset:31;
- U32 mIsProvided:1;
-
- };
-
- // these templates allow us to distinguish between template parameters
- // that derive from BaseBlock and those that don't
- template<typename T, typename Void = void>
- struct IsBlock
- {
- static const bool value = false;
- struct EmptyBase {};
- typedef EmptyBase base_class_t;
- };
-
- template<typename T>
- struct IsBlock<T, typename T::baseblock_base_class_t>
- {
- static const bool value = true;
- typedef BaseBlock base_class_t;
- };
-
- template<typename T>
- struct IsBlock<BaseBlock::Lazy<T>, typename T::baseblock_base_class_t >
- {
- static const bool value = true;
- typedef BaseBlock base_class_t;
- };
-
- template<typename T, typename NAME_VALUE_LOOKUP, bool VALUE_IS_BLOCK = IsBlock<T>::value>
- class ParamValue : public NAME_VALUE_LOOKUP
- {
- public:
- typedef const T& value_assignment_t;
- typedef T value_t;
- typedef ParamValue<T, NAME_VALUE_LOOKUP, VALUE_IS_BLOCK> self_t;
-
- ParamValue(): mValue() {}
- ParamValue(value_assignment_t other) : mValue(other) {}
-
- void setValue(value_assignment_t val)
- {
- mValue = val;
- }
-
- value_assignment_t getValue() const
- {
- return mValue;
- }
-
- T& getValue()
- {
- return mValue;
- }
-
- operator value_assignment_t() const
- {
- return mValue;
- }
-
- value_assignment_t operator()() const
- {
- return mValue;
- }
-
- void operator ()(const typename NAME_VALUE_LOOKUP::name_t& name)
- {
- *this = name;
- }
-
- self_t& operator =(const typename NAME_VALUE_LOOKUP::name_t& name)
- {
- if (NAME_VALUE_LOOKUP::getValueFromName(name, mValue))
- {
- setValueName(name);
- }
-
- return *this;
- }
-
- protected:
- T mValue;
- };
-
- template<typename T, typename NAME_VALUE_LOOKUP>
- class ParamValue<T, NAME_VALUE_LOOKUP, true>
- : public T,
- public NAME_VALUE_LOOKUP
- {
- public:
- typedef const T& value_assignment_t;
- typedef T value_t;
- typedef ParamValue<T, NAME_VALUE_LOOKUP, true> self_t;
-
- ParamValue()
- : T(),
- mValidated(false)
- {}
-
- ParamValue(value_assignment_t other)
- : T(other),
- mValidated(false)
- {}
-
- void setValue(value_assignment_t val)
- {
- *this = val;
- }
-
- value_assignment_t getValue() const
- {
- return *this;
- }
-
- T& getValue()
- {
- return *this;
- }
-
- operator value_assignment_t() const
- {
- return *this;
- }
-
- value_assignment_t operator()() const
- {
- return *this;
- }
-
- void operator ()(const typename NAME_VALUE_LOOKUP::name_t& name)
- {
- *this = name;
- }
-
- self_t& operator =(const typename NAME_VALUE_LOOKUP::name_t& name)
- {
- if (NAME_VALUE_LOOKUP::getValueFromName(name, *this))
- {
- setValueName(name);
- }
-
- return *this;
- }
-
- protected:
- mutable bool mValidated; // lazy validation flag
- };
-
- template<typename NAME_VALUE_LOOKUP>
- class ParamValue<std::string, NAME_VALUE_LOOKUP, false>
- : public NAME_VALUE_LOOKUP
- {
- public:
- typedef const std::string& value_assignment_t;
- typedef std::string value_t;
- typedef ParamValue<std::string, NAME_VALUE_LOOKUP, false> self_t;
-
- ParamValue(): mValue() {}
- ParamValue(value_assignment_t other) : mValue(other) {}
-
- void setValue(value_assignment_t val)
- {
- if (NAME_VALUE_LOOKUP::getValueFromName(val, mValue))
- {
- NAME_VALUE_LOOKUP::setValueName(val);
- }
- else
- {
- mValue = val;
- }
- }
-
- value_assignment_t getValue() const
- {
- return mValue;
- }
-
- std::string& getValue()
- {
- return mValue;
- }
-
- operator value_assignment_t() const
- {
- return mValue;
- }
-
- value_assignment_t operator()() const
- {
- return mValue;
- }
-
- protected:
- std::string mValue;
- };
-
-
- template<typename T, typename NAME_VALUE_LOOKUP = TypeValues<T> >
- struct ParamIterator
- {
- typedef typename std::vector<ParamValue<T, NAME_VALUE_LOOKUP> >::const_iterator const_iterator;
- typedef typename std::vector<ParamValue<T, NAME_VALUE_LOOKUP> >::iterator iterator;
- };
-
- // specialize for custom parsing/decomposition of specific classes
- // e.g. TypedParam<LLRect> has left, top, right, bottom, etc...
- template<typename T,
- typename NAME_VALUE_LOOKUP = TypeValues<T>,
- bool HAS_MULTIPLE_VALUES = false,
- bool VALUE_IS_BLOCK = IsBlock<ParamValue<T, NAME_VALUE_LOOKUP> >::value>
- class TypedParam
- : public Param,
- public ParamValue<T, NAME_VALUE_LOOKUP>
- {
- public:
- typedef TypedParam<T, NAME_VALUE_LOOKUP, HAS_MULTIPLE_VALUES, VALUE_IS_BLOCK> self_t;
- typedef ParamValue<T, NAME_VALUE_LOOKUP> param_value_t;
- typedef typename param_value_t::value_assignment_t value_assignment_t;
- typedef NAME_VALUE_LOOKUP name_value_lookup_t;
-
- using param_value_t::operator();
-
- TypedParam(BlockDescriptor& block_descriptor, const char* name, value_assignment_t value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)
- : Param(block_descriptor.mCurrentBlockPtr)
- {
- if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))
- {
- ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor(
- block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
- &mergeWith,
- &deserializeParam,
- &serializeParam,
- validate_func,
- &inspectParam,
- min_count, max_count));
- BaseBlock::addParam(block_descriptor, param_descriptor, name);
- }
-
- setValue(value);
- }
-
- bool isProvided() const { return Param::anyProvided(); }
-
- static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack_range, bool new_name)
- {
- self_t& typed_param = static_cast<self_t&>(param);
- // no further names in stack, attempt to parse value now
- if (name_stack_range.first == name_stack_range.second)
- {
- if (parser.readValue(typed_param.getValue()))
- {
- typed_param.clearValueName();
- typed_param.setProvided();
- return true;
- }
-
- // try to parse a known named value
- if(name_value_lookup_t::valueNamesExist())
- {
- // try to parse a known named value
- std::string name;
- if (parser.readValue(name))
- {
- // try to parse a per type named value
- if (name_value_lookup_t::getValueFromName(name, typed_param.getValue()))
- {
- typed_param.setValueName(name);
- typed_param.setProvided();
- return true;
- }
-
- }
- }
- }
- return false;
- }
-
- static void serializeParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, const Param* diff_param)
- {
- const self_t& typed_param = static_cast<const self_t&>(param);
- if (!typed_param.isProvided()) return;
-
- if (!name_stack.empty())
- {
- name_stack.back().second = true;
- }
-
- std::string key = typed_param.getValueName();
-
- // first try to write out name of name/value pair
-
- if (!key.empty())
- {
- if (!diff_param || !ParamCompare<std::string>::equals(static_cast<const self_t*>(diff_param)->getValueName(), key))
- {
- parser.writeValue(key, name_stack);
- }
- }
- // then try to serialize value directly
- else if (!diff_param || !ParamCompare<T>::equals(typed_param.getValue(), static_cast<const self_t*>(diff_param)->getValue()))
- {
- if (!parser.writeValue(typed_param.getValue(), name_stack))
- {
- std::string calculated_key = typed_param.calcValueName(typed_param.getValue());
- if (!diff_param || !ParamCompare<std::string>::equals(static_cast<const self_t*>(diff_param)->getValueName(), calculated_key))
- {
- parser.writeValue(calculated_key, name_stack);
- }
- }
- }
- }
-
- static void inspectParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, S32 min_count, S32 max_count)
- {
- // tell parser about our actual type
- parser.inspectValue<T>(name_stack, min_count, max_count, NULL);
- // then tell it about string-based alternatives ("red", "blue", etc. for LLColor4)
- if (name_value_lookup_t::getPossibleValues())
- {
- parser.inspectValue<std::string>(name_stack, min_count, max_count, name_value_lookup_t::getPossibleValues());
- }
- }
-
- void set(value_assignment_t val, bool flag_as_provided = true)
- {
- param_value_t::clearValueName();
- setValue(val);
- setProvided(flag_as_provided);
- }
-
- self_t& operator =(const typename NAME_VALUE_LOOKUP::name_t& name)
- {
- return static_cast<self_t&>(param_value_t::operator =(name));
- }
-
- protected:
-
- self_t& operator =(const self_t& other)
- {
- param_value_t::operator =(other);
- Param::operator =(other);
- return *this;
- }
-
- static bool mergeWith(Param& dst, const Param& src, bool overwrite)
- {
- const self_t& src_typed_param = static_cast<const self_t&>(src);
- self_t& dst_typed_param = static_cast<self_t&>(dst);
-
- if (src_typed_param.isProvided()
- && (overwrite || !dst_typed_param.isProvided()))
- {
- dst_typed_param.set(src_typed_param.getValue());
- return true;
- }
- return false;
- }
- };
-
- // parameter that is a block
- template <typename T, typename NAME_VALUE_LOOKUP>
- class TypedParam<T, NAME_VALUE_LOOKUP, false, true>
- : public Param,
- public ParamValue<T, NAME_VALUE_LOOKUP>
- {
- public:
- typedef ParamValue<T, NAME_VALUE_LOOKUP> param_value_t;
- typedef typename param_value_t::value_assignment_t value_assignment_t;
- typedef TypedParam<T, NAME_VALUE_LOOKUP, false, true> self_t;
- typedef NAME_VALUE_LOOKUP name_value_lookup_t;
-
- using param_value_t::operator();
-
- TypedParam(BlockDescriptor& block_descriptor, const char* name, value_assignment_t value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)
- : Param(block_descriptor.mCurrentBlockPtr),
- param_value_t(value)
- {
- if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))
- {
- ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor(
- block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
- &mergeWith,
- &deserializeParam,
- &serializeParam,
- validate_func,
- &inspectParam,
- min_count, max_count));
- BaseBlock::addParam(block_descriptor, param_descriptor, name);
- }
- }
-
- static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack_range, bool new_name)
- {
- self_t& typed_param = static_cast<self_t&>(param);
- // attempt to parse block...
- if(typed_param.deserializeBlock(parser, name_stack_range, new_name))
- {
- typed_param.clearValueName();
- typed_param.setProvided();
- return true;
- }
-
- if(name_value_lookup_t::valueNamesExist())
- {
- // try to parse a known named value
- std::string name;
- if (parser.readValue(name))
- {
- // try to parse a per type named value
- if (name_value_lookup_t::getValueFromName(name, typed_param.getValue()))
- {
- typed_param.setValueName(name);
- typed_param.setProvided();
- return true;
- }
-
- }
- }
- return false;
- }
-
- static void serializeParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, const Param* diff_param)
- {
- const self_t& typed_param = static_cast<const self_t&>(param);
- if (!typed_param.isProvided()) return;
-
- if (!name_stack.empty())
- {
- name_stack.back().second = true;
- }
-
- std::string key = typed_param.getValueName();
- if (!key.empty())
- {
- if (!parser.writeValue(key, name_stack))
- {
- return;
- }
- }
- else
- {
- typed_param.serializeBlock(parser, name_stack, static_cast<const self_t*>(diff_param));
- }
- }
-
- static void inspectParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, S32 min_count, S32 max_count)
- {
- // I am a param that is also a block, so just recurse into my contents
- const self_t& typed_param = static_cast<const self_t&>(param);
- typed_param.inspectBlock(parser, name_stack, min_count, max_count);
- }
-
- // a param-that-is-a-block is provided when the user has set one of its child params
- // *and* the block as a whole validates
- bool isProvided() const
- {
- // only validate block when it hasn't already passed validation with current data
- if (Param::anyProvided() && !param_value_t::mValidated)
- {
- // a sub-block is "provided" when it has been filled in enough to be valid
- param_value_t::mValidated = param_value_t::validateBlock(false);
- }
- return Param::anyProvided() && param_value_t::mValidated;
- }
-
- // assign block contents to this param-that-is-a-block
- void set(value_assignment_t val, bool flag_as_provided = true)
- {
- setValue(val);
- param_value_t::clearValueName();
- // force revalidation of block
- // next call to isProvided() will update provision status based on validity
- param_value_t::mValidated = false;
- setProvided(flag_as_provided);
- }
-
- self_t& operator =(const typename NAME_VALUE_LOOKUP::name_t& name)
- {
- return static_cast<self_t&>(param_value_t::operator =(name));
- }
-
- // propagate changed status up to enclosing block
- /*virtual*/ void paramChanged(const Param& changed_param, bool user_provided)
- {
- param_value_t::paramChanged(changed_param, user_provided);
- if (user_provided)
- {
- // a child param has been explicitly changed
- // so *some* aspect of this block is now provided
- param_value_t::mValidated = false;
- setProvided();
- param_value_t::clearValueName();
- }
- else
- {
- Param::enclosingBlock().paramChanged(*this, user_provided);
- }
- }
-
- protected:
-
- self_t& operator =(const self_t& other)
- {
- param_value_t::operator =(other);
- Param::operator =(other);
- return *this;
- }
-
- static bool mergeWith(Param& dst, const Param& src, bool overwrite)
- {
- const self_t& src_typed_param = static_cast<const self_t&>(src);
- self_t& dst_typed_param = static_cast<self_t&>(dst);
-
- if (src_typed_param.anyProvided())
- {
- if (dst_typed_param.mergeBlockParam(src_typed_param.isProvided(), dst_typed_param.isProvided(), param_value_t::selfBlockDescriptor(), src_typed_param, overwrite))
- {
- dst_typed_param.clearValueName();
- dst_typed_param.setProvided(true);
- return true;
- }
- }
- return false;
- }
- };
-
- // container of non-block parameters
- template <typename VALUE_TYPE, typename NAME_VALUE_LOOKUP>
- class TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, false>
- : public Param
- {
- public:
- typedef TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, false> self_t;
- typedef ParamValue<VALUE_TYPE, NAME_VALUE_LOOKUP> param_value_t;
- typedef typename std::vector<param_value_t> container_t;
- typedef const container_t& value_assignment_t;
-
- typedef typename param_value_t::value_t value_t;
- typedef NAME_VALUE_LOOKUP name_value_lookup_t;
-
- TypedParam(BlockDescriptor& block_descriptor, const char* name, value_assignment_t value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)
- : Param(block_descriptor.mCurrentBlockPtr)
- {
- std::copy(value.begin(), value.end(), std::back_inserter(mValues));
-
- if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))
- {
- ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor(
- block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
- &mergeWith,
- &deserializeParam,
- &serializeParam,
- validate_func,
- &inspectParam,
- min_count, max_count));
- BaseBlock::addParam(block_descriptor, param_descriptor, name);
- }
- }
-
- bool isProvided() const { return Param::anyProvided(); }
-
- static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack_range, bool new_name)
- {
- self_t& typed_param = static_cast<self_t&>(param);
- value_t value;
- // no further names in stack, attempt to parse value now
- if (name_stack_range.first == name_stack_range.second)
- {
- // attempt to read value directly
- if (parser.readValue(value))
- {
- typed_param.add(value);
- return true;
- }
-
- // try to parse a known named value
- if(name_value_lookup_t::valueNamesExist())
- {
- // try to parse a known named value
- std::string name;
- if (parser.readValue(name))
- {
- // try to parse a per type named value
- if (name_value_lookup_t::getValueFromName(name, value))
- {
- typed_param.add(value);
- typed_param.mValues.back().setValueName(name);
- return true;
- }
-
- }
- }
- }
- return false;
- }
-
- static void serializeParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, const Param* diff_param)
- {
- const self_t& typed_param = static_cast<const self_t&>(param);
- if (!typed_param.isProvided() || name_stack.empty()) return;
-
- for (const_iterator it = typed_param.mValues.begin(), end_it = typed_param.mValues.end();
- it != end_it;
- ++it)
- {
- std::string key = it->getValueName();
- name_stack.back().second = true;
-
- if(key.empty())
- // not parsed via name values, write out value directly
- {
- bool value_written = parser.writeValue(*it, name_stack);
- if (!value_written)
- {
- std::string calculated_key = it->calcValueName(it->getValue());
- if (!parser.writeValue(calculated_key, name_stack))
- {
- break;
- }
- }
- }
- else
- {
- if(!parser.writeValue(key, name_stack))
- {
- break;
- }
- }
- }
- }
-
- static void inspectParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, S32 min_count, S32 max_count)
- {
- parser.inspectValue<VALUE_TYPE>(name_stack, min_count, max_count, NULL);
- if (name_value_lookup_t::getPossibleValues())
- {
- parser.inspectValue<std::string>(name_stack, min_count, max_count, name_value_lookup_t::getPossibleValues());
- }
- }
-
- void set(value_assignment_t val, bool flag_as_provided = true)
- {
- mValues = val;
- setProvided(flag_as_provided);
- }
-
- param_value_t& add()
- {
- mValues.push_back(param_value_t(value_t()));
- Param::setProvided();
- return mValues.back();
- }
-
- self_t& add(const value_t& item)
- {
- param_value_t param_value;
- param_value.setValue(item);
- mValues.push_back(param_value);
- setProvided();
- return *this;
- }
-
- self_t& add(const typename name_value_lookup_t::name_t& name)
- {
- value_t value;
-
- // try to parse a per type named value
- if (name_value_lookup_t::getValueFromName(name, value))
- {
- add(value);
- mValues.back().setValueName(name);
- }
-
- return *this;
- }
-
- // implicit conversion
- operator value_assignment_t() const { return mValues; }
- // explicit conversion
- value_assignment_t operator()() const { return mValues; }
-
- typedef typename container_t::iterator iterator;
- typedef typename container_t::const_iterator const_iterator;
- iterator begin() { return mValues.begin(); }
- iterator end() { return mValues.end(); }
- const_iterator begin() const { return mValues.begin(); }
- const_iterator end() const { return mValues.end(); }
- bool empty() const { return mValues.empty(); }
- size_t size() const { return mValues.size(); }
-
- U32 numValidElements() const
- {
- return mValues.size();
- }
-
- protected:
- static bool mergeWith(Param& dst, const Param& src, bool overwrite)
- {
- const self_t& src_typed_param = static_cast<const self_t&>(src);
- self_t& dst_typed_param = static_cast<self_t&>(dst);
-
- if (overwrite)
- {
- std::copy(src_typed_param.begin(), src_typed_param.end(), std::back_inserter(dst_typed_param.mValues));
- }
- else
- {
- container_t new_values(src_typed_param.mValues);
- std::copy(dst_typed_param.begin(), dst_typed_param.end(), std::back_inserter(new_values));
- std::swap(dst_typed_param.mValues, new_values);
- }
-
- if (src_typed_param.begin() != src_typed_param.end())
- {
- dst_typed_param.setProvided();
- }
- return true;
- }
-
- container_t mValues;
- };
-
- // container of block parameters
- template <typename VALUE_TYPE, typename NAME_VALUE_LOOKUP>
- class TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, true>
- : public Param
- {
- public:
- typedef TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, true> self_t;
- typedef ParamValue<VALUE_TYPE, NAME_VALUE_LOOKUP> param_value_t;
- typedef typename std::vector<param_value_t> container_t;
- typedef const container_t& value_assignment_t;
- typedef typename param_value_t::value_t value_t;
- typedef NAME_VALUE_LOOKUP name_value_lookup_t;
-
- TypedParam(BlockDescriptor& block_descriptor, const char* name, value_assignment_t value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)
- : Param(block_descriptor.mCurrentBlockPtr)
- {
- std::copy(value.begin(), value.end(), back_inserter(mValues));
-
- if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))
- {
- ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor(
- block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
- &mergeWith,
- &deserializeParam,
- &serializeParam,
- validate_func,
- &inspectParam,
- min_count, max_count));
- BaseBlock::addParam(block_descriptor, param_descriptor, name);
- }
- }
-
- bool isProvided() const { return Param::anyProvided(); }
-
- static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack_range, bool new_name)
- {
- self_t& typed_param = static_cast<self_t&>(param);
- bool new_value = false;
-
- if (new_name || typed_param.mValues.empty())
- {
- new_value = true;
- typed_param.mValues.push_back(value_t());
- }
-
- param_value_t& value = typed_param.mValues.back();
-
- // attempt to parse block...
- if(value.deserializeBlock(parser, name_stack_range, new_name))
- {
- typed_param.setProvided();
- return true;
- }
- else if(name_value_lookup_t::valueNamesExist())
- {
- // try to parse a known named value
- std::string name;
- if (parser.readValue(name))
- {
- // try to parse a per type named value
- if (name_value_lookup_t::getValueFromName(name, value.getValue()))
- {
- typed_param.mValues.back().setValueName(name);
- typed_param.setProvided();
- return true;
- }
-
- }
- }
-
- if (new_value)
- { // failed to parse new value, pop it off
- typed_param.mValues.pop_back();
- }
-
- return false;
- }
-
- static void serializeParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, const Param* diff_param)
- {
- const self_t& typed_param = static_cast<const self_t&>(param);
- if (!typed_param.isProvided() || name_stack.empty()) return;
-
- for (const_iterator it = typed_param.mValues.begin(), end_it = typed_param.mValues.end();
- it != end_it;
- ++it)
- {
- name_stack.back().second = true;
-
- std::string key = it->getValueName();
- if (!key.empty())
- {
- parser.writeValue(key, name_stack);
- }
- // Not parsed via named values, write out value directly
- // NOTE: currently we don't worry about removing default values in Multiple
- else
- {
- it->serializeBlock(parser, name_stack, NULL);
- }
- }
- }
-
- static void inspectParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, S32 min_count, S32 max_count)
- {
- // I am a vector of blocks, so describe my contents recursively
- param_value_t(value_t()).inspectBlock(parser, name_stack, min_count, max_count);
- }
-
- void set(value_assignment_t val, bool flag_as_provided = true)
- {
- mValues = val;
- setProvided(flag_as_provided);
- }
-
- param_value_t& add()
- {
- mValues.push_back(value_t());
- setProvided();
- return mValues.back();
- }
-
- self_t& add(const value_t& item)
- {
- mValues.push_back(item);
- setProvided();
- return *this;
- }
-
- self_t& add(const typename name_value_lookup_t::name_t& name)
- {
- value_t value;
-
- // try to parse a per type named value
- if (name_value_lookup_t::getValueFromName(name, value))
- {
- add(value);
- mValues.back().setValueName(name);
- }
- return *this;
- }
-
- // implicit conversion
- operator value_assignment_t() const { return mValues; }
- // explicit conversion
- value_assignment_t operator()() const { return mValues; }
-
- typedef typename container_t::iterator iterator;
- typedef typename container_t::const_iterator const_iterator;
- iterator begin() { return mValues.begin(); }
- iterator end() { return mValues.end(); }
- const_iterator begin() const { return mValues.begin(); }
- const_iterator end() const { return mValues.end(); }
- bool empty() const { return mValues.empty(); }
- size_t size() const { return mValues.size(); }
-
- U32 numValidElements() const
- {
- U32 count = 0;
- for (const_iterator it = mValues.begin(), end_it = mValues.end();
- it != end_it;
- ++it)
- {
- if(it->validateBlock(false)) count++;
- }
- return count;
- }
-
- protected:
-
- static bool mergeWith(Param& dst, const Param& src, bool overwrite)
- {
- const self_t& src_typed_param = static_cast<const self_t&>(src);
- self_t& dst_typed_param = static_cast<self_t&>(dst);
-
- if (overwrite)
- {
- std::copy(src_typed_param.begin(), src_typed_param.end(), std::back_inserter(dst_typed_param.mValues));
- }
- else
- {
- container_t new_values(src_typed_param.mValues);
- std::copy(dst_typed_param.begin(), dst_typed_param.end(), std::back_inserter(new_values));
- std::swap(dst_typed_param.mValues, new_values);
- }
-
- if (src_typed_param.begin() != src_typed_param.end())
- {
- dst_typed_param.setProvided();
- }
-
- return true;
- }
-
- container_t mValues;
- };
-
- template <typename DERIVED_BLOCK, typename BASE_BLOCK = BaseBlock>
- class ChoiceBlock : public BASE_BLOCK
- {
- typedef ChoiceBlock<DERIVED_BLOCK, BASE_BLOCK> self_t;
- typedef ChoiceBlock<DERIVED_BLOCK, BASE_BLOCK> enclosing_block_t;
- typedef BASE_BLOCK base_block_t;
-
- LOG_CLASS(self_t);
- public:
- // take all provided params from other and apply to self
- bool overwriteFrom(const self_t& other)
- {
- return static_cast<DERIVED_BLOCK*>(this)->mergeBlock(selfBlockDescriptor(), other, true);
- }
-
- // take all provided params that are not already provided, and apply to self
- bool fillFrom(const self_t& other)
- {
- return static_cast<DERIVED_BLOCK*>(this)->mergeBlock(selfBlockDescriptor(), other, false);
- }
-
- bool mergeBlockParam(bool source_provided, bool dest_provided, BlockDescriptor& block_data, const self_t& source, bool overwrite)
- {
- bool source_override = source_provided && (overwrite || !dest_provided);
-
- if (source_override || source.mCurChoice == mCurChoice)
- {
- return mergeBlock(block_data, source, overwrite);
- }
- return false;
- }
-
- // merge with other block
- bool mergeBlock(BlockDescriptor& block_data, const self_t& other, bool overwrite)
- {
- mCurChoice = other.mCurChoice;
- return base_block_t::mergeBlock(selfBlockDescriptor(), other, overwrite);
- }
-
- // clear out old choice when param has changed
- /*virtual*/ void paramChanged(const Param& changed_param, bool user_provided)
- {
- param_handle_t changed_param_handle = base_block_t::getHandleFromParam(&changed_param);
- // if we have a new choice...
- if (changed_param_handle != mCurChoice)
- {
- // clear provided flag on previous choice
- Param* previous_choice = base_block_t::getParamFromHandle(mCurChoice);
- if (previous_choice)
- {
- previous_choice->setProvided(false);
- }
- mCurChoice = changed_param_handle;
- }
- base_block_t::paramChanged(changed_param, user_provided);
- }
-
- virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return selfBlockDescriptor(); }
- virtual BlockDescriptor& mostDerivedBlockDescriptor() { return selfBlockDescriptor(); }
-
- protected:
- ChoiceBlock()
- : mCurChoice(0)
- {
- BaseBlock::init(selfBlockDescriptor(), base_block_t::selfBlockDescriptor(), sizeof(DERIVED_BLOCK));
- }
-
- // Alternatives are mutually exclusive wrt other Alternatives in the same block.
- // One alternative in a block will always have isChosen() == true.
- // At most one alternative in a block will have isProvided() == true.
- template <typename T, typename NAME_VALUE_LOOKUP = TypeValues<T> >
- class Alternative : public TypedParam<T, NAME_VALUE_LOOKUP, false>
- {
- public:
- friend class ChoiceBlock<DERIVED_BLOCK>;
-
- typedef Alternative<T, NAME_VALUE_LOOKUP> self_t;
- typedef TypedParam<T, NAME_VALUE_LOOKUP, false, IsBlock<ParamValue<T, NAME_VALUE_LOOKUP> >::value> super_t;
- typedef typename super_t::value_assignment_t value_assignment_t;
-
- using super_t::operator =;
-
- explicit Alternative(const char* name = "", value_assignment_t val = defaultValue<T>())
- : super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, val, NULL, 0, 1),
- mOriginalValue(val)
- {
- // assign initial choice to first declared option
- DERIVED_BLOCK* blockp = ((DERIVED_BLOCK*)DERIVED_BLOCK::selfBlockDescriptor().mCurrentBlockPtr);
- if (LL_UNLIKELY(DERIVED_BLOCK::selfBlockDescriptor().mInitializationState == BlockDescriptor::INITIALIZING))
- {
- if(blockp->mCurChoice == 0)
- {
- blockp->mCurChoice = Param::enclosingBlock().getHandleFromParam(this);
- }
- }
- }
-
- void choose()
- {
- static_cast<enclosing_block_t&>(Param::enclosingBlock()).paramChanged(*this, true);
- }
-
- void chooseAs(value_assignment_t val)
- {
- super_t::set(val);
- }
-
- void operator =(value_assignment_t val)
- {
- super_t::set(val);
- }
-
- void operator()(typename super_t::value_assignment_t val)
- {
- super_t::set(val);
- }
-
- operator value_assignment_t() const
- {
- return (*this)();
- }
-
- value_assignment_t operator()() const
- {
- if (static_cast<enclosing_block_t&>(Param::enclosingBlock()).getCurrentChoice() == this)
- {
- return super_t::getValue();
- }
- return mOriginalValue;
- }
-
- bool isChosen() const
- {
- return static_cast<enclosing_block_t&>(Param::enclosingBlock()).getCurrentChoice() == this;
- }
-
- private:
- T mOriginalValue;
- };
-
- protected:
- static BlockDescriptor& selfBlockDescriptor()
- {
- static BlockDescriptor sBlockDescriptor;
- return sBlockDescriptor;
- }
-
- private:
- param_handle_t mCurChoice;
-
- const Param* getCurrentChoice() const
- {
- return base_block_t::getParamFromHandle(mCurChoice);
- }
- };
-
- template <typename DERIVED_BLOCK, typename BASE_BLOCK = BaseBlock>
- class Block
- : public BASE_BLOCK
- {
- typedef Block<DERIVED_BLOCK, BASE_BLOCK> self_t;
- typedef Block<DERIVED_BLOCK, BASE_BLOCK> block_t;
-
- public:
- typedef BASE_BLOCK base_block_t;
-
- // take all provided params from other and apply to self
- bool overwriteFrom(const self_t& other)
- {
- return static_cast<DERIVED_BLOCK*>(this)->mergeBlock(selfBlockDescriptor(), other, true);
- }
-
- // take all provided params that are not already provided, and apply to self
- bool fillFrom(const self_t& other)
- {
- return static_cast<DERIVED_BLOCK*>(this)->mergeBlock(selfBlockDescriptor(), other, false);
- }
-
- virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return selfBlockDescriptor(); }
- virtual BlockDescriptor& mostDerivedBlockDescriptor() { return selfBlockDescriptor(); }
-
- protected:
- Block()
- {
- //#pragma message("Parsing LLInitParam::Block")
- BaseBlock::init(selfBlockDescriptor(), BASE_BLOCK::selfBlockDescriptor(), sizeof(DERIVED_BLOCK));
- }
-
- //
- // Nested classes for declaring parameters
- //
- template <typename T, typename NAME_VALUE_LOOKUP = TypeValues<T> >
- class Optional : public TypedParam<T, NAME_VALUE_LOOKUP, false>
- {
- public:
- typedef TypedParam<T, NAME_VALUE_LOOKUP, false, IsBlock<ParamValue<T, NAME_VALUE_LOOKUP> >::value> super_t;
- typedef typename super_t::value_assignment_t value_assignment_t;
-
- using super_t::operator();
- using super_t::operator =;
-
- explicit Optional(const char* name = "", value_assignment_t val = defaultValue<T>())
- : super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, val, NULL, 0, 1)
- {
- //#pragma message("Parsing LLInitParam::Block::Optional")
- }
-
- Optional& operator =(value_assignment_t val)
- {
- set(val);
- return *this;
- }
-
- DERIVED_BLOCK& operator()(value_assignment_t val)
- {
- super_t::set(val);
- return static_cast<DERIVED_BLOCK&>(Param::enclosingBlock());
- }
- };
-
- template <typename T, typename NAME_VALUE_LOOKUP = TypeValues<T> >
- class Mandatory : public TypedParam<T, NAME_VALUE_LOOKUP, false>
- {
- public:
- typedef TypedParam<T, NAME_VALUE_LOOKUP, false, IsBlock<ParamValue<T, NAME_VALUE_LOOKUP> >::value> super_t;
- typedef Mandatory<T, NAME_VALUE_LOOKUP> self_t;
- typedef typename super_t::value_assignment_t value_assignment_t;
-
- using super_t::operator();
- using super_t::operator =;
-
- // mandatory parameters require a name to be parseable
- explicit Mandatory(const char* name = "", value_assignment_t val = defaultValue<T>())
- : super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, val, &validate, 1, 1)
- {}
-
- Mandatory& operator =(value_assignment_t val)
- {
- set(val);
- return *this;
- }
-
- DERIVED_BLOCK& operator()(typename super_t::value_assignment_t val)
- {
- super_t::set(val);
- return static_cast<DERIVED_BLOCK&>(Param::enclosingBlock());
- }
-
- static bool validate(const Param* p)
- {
- // valid only if provided
- return static_cast<const self_t*>(p)->isProvided();
- }
-
- };
-
- template <typename T, typename RANGE = BaseBlock::AnyAmount, typename NAME_VALUE_LOOKUP = TypeValues<T> >
- class Multiple : public TypedParam<T, NAME_VALUE_LOOKUP, true>
- {
- public:
- typedef TypedParam<T, NAME_VALUE_LOOKUP, true, IsBlock<ParamValue<T, NAME_VALUE_LOOKUP> >::value> super_t;
- typedef Multiple<T, RANGE, NAME_VALUE_LOOKUP> self_t;
- typedef typename super_t::container_t container_t;
- typedef typename super_t::value_assignment_t value_assignment_t;
- typedef typename super_t::iterator iterator;
- typedef typename super_t::const_iterator const_iterator;
-
- explicit Multiple(const char* name = "")
- : super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, container_t(), &validate, RANGE::minCount, RANGE::maxCount)
- {}
-
- Multiple& operator =(value_assignment_t val)
- {
- set(val);
- return *this;
- }
-
- DERIVED_BLOCK& operator()(typename super_t::value_assignment_t val)
- {
- super_t::set(val);
- return static_cast<DERIVED_BLOCK&>(Param::enclosingBlock());
- }
-
- static bool validate(const Param* paramp)
- {
- U32 num_valid = ((super_t*)paramp)->numValidElements();
- return RANGE::minCount <= num_valid && num_valid <= RANGE::maxCount;
- }
- };
-
- class Deprecated : public Param
- {
- public:
- explicit Deprecated(const char* name)
- : Param(DERIVED_BLOCK::selfBlockDescriptor().mCurrentBlockPtr)
- {
- BlockDescriptor& block_descriptor = DERIVED_BLOCK::selfBlockDescriptor();
- if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))
- {
- ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor(
- block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
- NULL,
- &deserializeParam,
- NULL,
- NULL,
- NULL,
- 0, S32_MAX));
- BaseBlock::addParam(block_descriptor, param_descriptor, name);
- }
- }
-
- static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack_range, bool new_name)
- {
- if (name_stack_range.first == name_stack_range.second)
- {
- //std::string message = llformat("Deprecated value %s ignored", getName().c_str());
- //parser.parserWarning(message);
- return true;
- }
-
- return false;
- }
- };
-
- // different semantics for documentation purposes, but functionally identical
- typedef Deprecated Ignored;
-
- protected:
- static BlockDescriptor& selfBlockDescriptor()
- {
- static BlockDescriptor sBlockDescriptor;
- return sBlockDescriptor;
- }
-
- template <typename T, typename NAME_VALUE_LOOKUP, bool multiple, bool is_block>
- void changeDefault(TypedParam<T, NAME_VALUE_LOOKUP, multiple, is_block>& param,
- typename TypedParam<T, NAME_VALUE_LOOKUP, multiple, is_block>::value_assignment_t value)
- {
- if (!param.isProvided())
- {
- param.set(value, false);
- }
- }
-
- };
-
- template <typename DERIVED_BLOCK, typename BASE_BLOCK = BaseBlock>
- class BatchBlock
- : public Block<DERIVED_BLOCK, BASE_BLOCK>
- {
- public:
- typedef BatchBlock<DERIVED_BLOCK, BASE_BLOCK> self_t;
- typedef Block<DERIVED_BLOCK, BASE_BLOCK> super_t;
-
- BatchBlock()
- {}
-
- bool deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack_range, bool new_name)
- {
- if (new_name)
- {
- // reset block
- *static_cast<DERIVED_BLOCK*>(this) = defaultBatchValue();
- }
- return super_t::deserializeBlock(p, name_stack_range, new_name);
- }
-
- bool mergeBlock(BlockDescriptor& block_data, const BaseBlock& other, bool overwrite)
- {
- if (overwrite)
- {
- *static_cast<DERIVED_BLOCK*>(this) = defaultBatchValue();
- // merge individual parameters into destination
- return super_t::mergeBlock(super_t::selfBlockDescriptor(), other, overwrite);
- }
- return false;
- }
- protected:
- static const DERIVED_BLOCK& defaultBatchValue()
- {
- static DERIVED_BLOCK default_value;
- return default_value;
- }
- };
-
- // FIXME: this specialization is not currently used, as it only matches against the BatchBlock base class
- // and not the derived class with the actual params
- template<typename DERIVED_BLOCK,
- typename BASE_BLOCK,
- typename NAME_VALUE_LOOKUP>
- class ParamValue <BatchBlock<DERIVED_BLOCK, BASE_BLOCK>,
- NAME_VALUE_LOOKUP,
- true>
- : public NAME_VALUE_LOOKUP,
- protected BatchBlock<DERIVED_BLOCK, BASE_BLOCK>
- {
- public:
- typedef BatchBlock<DERIVED_BLOCK, BASE_BLOCK> block_t;
- typedef const BatchBlock<DERIVED_BLOCK, BASE_BLOCK>& value_assignment_t;
- typedef block_t value_t;
-
- ParamValue()
- : block_t(),
- mValidated(false)
- {}
-
- ParamValue(value_assignment_t other)
- : block_t(other),
- mValidated(false)
- {
- }
-
- void setValue(value_assignment_t val)
- {
- *this = val;
- }
-
- value_assignment_t getValue() const
- {
- return *this;
- }
-
- BatchBlock<DERIVED_BLOCK, BASE_BLOCK>& getValue()
- {
- return *this;
- }
-
- operator value_assignment_t() const
- {
- return *this;
- }
-
- value_assignment_t operator()() const
- {
- return *this;
- }
-
- protected:
- mutable bool mValidated; // lazy validation flag
- };
-
- template<typename T, bool IS_BLOCK>
- class ParamValue <BaseBlock::Lazy<T>,
- TypeValues<T>,
- IS_BLOCK>
- : public IsBlock<T>::base_class_t
- {
- public:
- typedef ParamValue <BaseBlock::Lazy<T>, TypeValues<T>, false> self_t;
- typedef const T& value_assignment_t;
- typedef T value_t;
-
- ParamValue()
- : mValue(),
- mValidated(false)
- {}
-
- ParamValue(value_assignment_t other)
- : mValue(other),
- mValidated(false)
- {}
-
- void setValue(value_assignment_t val)
- {
- mValue.set(val);
- }
-
- value_assignment_t getValue() const
- {
- return mValue.get();
- }
-
- T& getValue()
- {
- return mValue.get();
- }
-
- operator value_assignment_t() const
- {
- return mValue.get();
- }
-
- value_assignment_t operator()() const
- {
- return mValue.get();
- }
-
- bool deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack_range, bool new_name)
- {
- return mValue.get().deserializeBlock(p, name_stack_range, new_name);
- }
-
- void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const BaseBlock* diff_block = NULL) const
- {
- if (mValue.empty()) return;
-
- mValue.get().serializeBlock(p, name_stack, diff_block);
- }
-
- bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const
- {
- if (mValue.empty()) return false;
-
- return mValue.get().inspectBlock(p, name_stack, min_count, max_count);
- }
-
- protected:
- mutable bool mValidated; // lazy validation flag
-
- private:
- BaseBlock::Lazy<T> mValue;
- };
-
- template <>
- class ParamValue <LLSD,
- TypeValues<LLSD>,
- false>
- : public TypeValues<LLSD>,
- public BaseBlock
- {
- public:
- typedef ParamValue<LLSD, TypeValues<LLSD>, false> self_t;
- typedef const LLSD& value_assignment_t;
-
- ParamValue()
- : mValidated(false)
- {}
-
- ParamValue(value_assignment_t other)
- : mValue(other),
- mValidated(false)
- {}
-
- void setValue(value_assignment_t val) { mValue = val; }
-
- value_assignment_t getValue() const { return mValue; }
- LLSD& getValue() { return mValue; }
-
- operator value_assignment_t() const { return mValue; }
- value_assignment_t operator()() const { return mValue; }
-
-
- // block param interface
- bool deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack_range, bool new_name);
- void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const BaseBlock* diff_block = NULL) const;
- bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const
- {
- //TODO: implement LLSD params as schema type Any
- return true;
- }
-
- protected:
- mutable bool mValidated; // lazy validation flag
-
- private:
- static void serializeElement(Parser& p, const LLSD& sd, Parser::name_stack_t& name_stack);
-
- LLSD mValue;
- };
-
- template<typename T>
- class CustomParamValue
- : public Block<ParamValue<T, TypeValues<T> > >,
- public TypeValues<T>
- {
- public:
- typedef enum e_value_age
- {
- VALUE_NEEDS_UPDATE, // mValue needs to be refreshed from the block parameters
- VALUE_AUTHORITATIVE, // mValue holds the authoritative value (which has been replicated to the block parameters via updateBlockFromValue)
- BLOCK_AUTHORITATIVE // mValue is derived from the block parameters, which are authoritative
- } EValueAge;
-
- typedef ParamValue<T, TypeValues<T> > derived_t;
- typedef CustomParamValue<T> self_t;
- typedef Block<derived_t> block_t;
- typedef const T& value_assignment_t;
- typedef T value_t;
-
-
- CustomParamValue(const T& value = T())
- : mValue(value),
- mValueAge(VALUE_AUTHORITATIVE),
- mValidated(false)
- {}
-
- bool deserializeBlock(Parser& parser, Parser::name_stack_range_t name_stack_range, bool new_name)
- {
- derived_t& typed_param = static_cast<derived_t&>(*this);
- // try to parse direct value T
- if (name_stack_range.first == name_stack_range.second)
- {
- if(parser.readValue(typed_param.mValue))
- {
- typed_param.mValueAge = VALUE_AUTHORITATIVE;
- typed_param.updateBlockFromValue(false);
-
- typed_param.clearValueName();
-
- return true;
- }
- }
-
- // fall back on parsing block components for T
- return typed_param.BaseBlock::deserializeBlock(parser, name_stack_range, new_name);
- }
-
- void serializeBlock(Parser& parser, Parser::name_stack_t& name_stack, const BaseBlock* diff_block = NULL) const
- {
- const derived_t& typed_param = static_cast<const derived_t&>(*this);
- const derived_t* diff_param = static_cast<const derived_t*>(diff_block);
-
- std::string key = typed_param.getValueName();
-
- // first try to write out name of name/value pair
- if (!key.empty())
- {
- if (!diff_param || !ParamCompare<std::string>::equals(diff_param->getValueName(), key))
- {
- parser.writeValue(key, name_stack);
- }
- }
- // then try to serialize value directly
- else if (!diff_param || !ParamCompare<T>::equals(typed_param.getValue(), diff_param->getValue()))
- {
-
- if (!parser.writeValue(typed_param.getValue(), name_stack))
- {
- //RN: *always* serialize provided components of BlockValue (don't pass diff_param on),
- // since these tend to be viewed as the constructor arguments for the value T. It seems
- // cleaner to treat the uniqueness of a BlockValue according to the generated value, and
- // not the individual components. This way <color red="0" green="1" blue="0"/> will not
- // be exported as <color green="1"/>, since it was probably the intent of the user to
- // be specific about the RGB color values. This also fixes an issue where we distinguish
- // between rect.left not being provided and rect.left being explicitly set to 0 (same as default)
-
- if (typed_param.mValueAge == VALUE_AUTHORITATIVE)
- {
- // if the value is authoritative but the parser doesn't accept the value type
- // go ahead and make a copy, and splat the value out to its component params
- // and serialize those params
- derived_t copy(typed_param);
- copy.updateBlockFromValue(true);
- copy.block_t::serializeBlock(parser, name_stack, NULL);
- }
- else
- {
- block_t::serializeBlock(parser, name_stack, NULL);
- }
- }
- }
- }
-
- bool inspectBlock(Parser& parser, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const
- {
- // first, inspect with actual type...
- parser.inspectValue<T>(name_stack, min_count, max_count, NULL);
- if (TypeValues<T>::getPossibleValues())
- {
- //...then inspect with possible string values...
- parser.inspectValue<std::string>(name_stack, min_count, max_count, TypeValues<T>::getPossibleValues());
- }
- // then recursively inspect contents...
- return block_t::inspectBlock(parser, name_stack, min_count, max_count);
- }
-
- bool validateBlock(bool emit_errors = true) const
- {
- if (mValueAge == VALUE_NEEDS_UPDATE)
- {
- if (block_t::validateBlock(emit_errors))
- {
- // clear stale keyword associated with old value
- TypeValues<T>::clearValueName();
- mValueAge = BLOCK_AUTHORITATIVE;
- static_cast<derived_t*>(const_cast<self_t*>(this))->updateValueFromBlock();
- return true;
- }
- else
- {
- //block value incomplete, so not considered provided
- // will attempt to revalidate on next call to isProvided()
- return false;
- }
- }
- else
- {
- // we have a valid value in hand
- return true;
- }
- }
-
- // propagate change status up to enclosing block
- /*virtual*/ void paramChanged(const Param& changed_param, bool user_provided)
- {
- BaseBlock::paramChanged(changed_param, user_provided);
- if (user_provided)
- {
- // a parameter changed, so our value is out of date
- mValueAge = VALUE_NEEDS_UPDATE;
- }
- }
-
- void setValue(value_assignment_t val)
- {
- derived_t& typed_param = static_cast<derived_t&>(*this);
- // set param version number to be up to date, so we ignore block contents
- mValueAge = VALUE_AUTHORITATIVE;
- mValue = val;
- typed_param.clearValueName();
- static_cast<derived_t*>(this)->updateBlockFromValue(false);
- }
-
- value_assignment_t getValue() const
- {
- validateBlock(true);
- return mValue;
- }
-
- T& getValue()
- {
- validateBlock(true);
- return mValue;
- }
-
- operator value_assignment_t() const
- {
- return getValue();
- }
-
- value_assignment_t operator()() const
- {
- return getValue();
- }
-
- protected:
-
- // use this from within updateValueFromBlock() to set the value without making it authoritative
- void updateValue(value_assignment_t value)
- {
- mValue = value;
- }
-
- bool mergeBlockParam(bool source_provided, bool dst_provided, BlockDescriptor& block_data, const BaseBlock& source, bool overwrite)
- {
- bool source_override = source_provided && (overwrite || !dst_provided);
-
- const derived_t& src_typed_param = static_cast<const derived_t&>(source);
-
- if (source_override && src_typed_param.mValueAge == VALUE_AUTHORITATIVE)
- {
- // copy value over
- setValue(src_typed_param.getValue());
- return true;
- }
- // merge individual parameters into destination
- if (mValueAge == VALUE_AUTHORITATIVE)
- {
- static_cast<derived_t*>(this)->updateBlockFromValue(dst_provided);
- }
- return mergeBlock(block_data, source, overwrite);
- }
-
- bool mergeBlock(BlockDescriptor& block_data, const BaseBlock& source, bool overwrite)
- {
- return block_t::mergeBlock(block_data, source, overwrite);
- }
-
- mutable bool mValidated; // lazy validation flag
-
- private:
- mutable T mValue;
- mutable EValueAge mValueAge;
- };
-}
-
-
-#endif // LL_LLPARAM_H
diff --git a/indra/llxuixml/llregistry.h b/indra/llxuixml/llregistry.h
deleted file mode 100644
index 36ce6a97b7..0000000000
--- a/indra/llxuixml/llregistry.h
+++ /dev/null
@@ -1,351 +0,0 @@
-/**
- * @file llregistry.h
- * @brief template classes for registering name, value pairs in nested scopes, statically, etc.
- *
- * $LicenseInfo:firstyear=2001&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$
- */
-
-#ifndef LL_LLREGISTRY_H
-#define LL_LLREGISTRY_H
-
-#include <list>
-
-#include <boost/type_traits.hpp>
-#include "llsingleton.h"
-
-template <typename T>
-class LLRegistryDefaultComparator
-{
- bool operator()(const T& lhs, const T& rhs) { return lhs < rhs; }
-};
-
-template <typename KEY, typename VALUE, typename COMPARATOR = LLRegistryDefaultComparator<KEY> >
-class LLRegistry
-{
-public:
- typedef LLRegistry<KEY, VALUE, COMPARATOR> registry_t;
- typedef typename boost::add_reference<typename boost::add_const<KEY>::type>::type ref_const_key_t;
- typedef typename boost::add_reference<typename boost::add_const<VALUE>::type>::type ref_const_value_t;
- typedef typename boost::add_reference<VALUE>::type ref_value_t;
- typedef typename boost::add_pointer<typename boost::add_const<VALUE>::type>::type ptr_const_value_t;
- typedef typename boost::add_pointer<VALUE>::type ptr_value_t;
-
- class Registrar
- {
- friend class LLRegistry<KEY, VALUE, COMPARATOR>;
- public:
- typedef typename std::map<KEY, VALUE> registry_map_t;
-
- bool add(ref_const_key_t key, ref_const_value_t value)
- {
- if (mMap.insert(std::make_pair(key, value)).second == false)
- {
- llwarns << "Tried to register " << key << " but it was already registered!" << llendl;
- return false;
- }
- return true;
- }
-
- void remove(ref_const_key_t key)
- {
- mMap.erase(key);
- }
-
- void replace(ref_const_key_t key, ref_const_value_t value)
- {
- mMap[key] = value;
- }
-
- typename registry_map_t::const_iterator beginItems() const
- {
- return mMap.begin();
- }
-
- typename registry_map_t::const_iterator endItems() const
- {
- return mMap.end();
- }
-
- protected:
- ptr_value_t getValue(ref_const_key_t key)
- {
- typename registry_map_t::iterator found_it = mMap.find(key);
- if (found_it != mMap.end())
- {
- return &(found_it->second);
- }
- return NULL;
- }
-
- ptr_const_value_t getValue(ref_const_key_t key) const
- {
- typename registry_map_t::const_iterator found_it = mMap.find(key);
- if (found_it != mMap.end())
- {
- return &(found_it->second);
- }
- return NULL;
- }
-
- // if the registry is used to store pointers, and null values are valid entries
- // then use this function to check the existence of an entry
- bool exists(ref_const_key_t key) const
- {
- return mMap.find(key) != mMap.end();
- }
-
- bool empty() const
- {
- return mMap.empty();
- }
-
- protected:
- // use currentRegistrar() or defaultRegistrar()
- Registrar() {}
- ~Registrar() {}
-
- private:
- registry_map_t mMap;
- };
-
- typedef typename std::list<Registrar*> scope_list_t;
- typedef typename std::list<Registrar*>::iterator scope_list_iterator_t;
- typedef typename std::list<Registrar*>::const_iterator scope_list_const_iterator_t;
-
- LLRegistry()
- {}
-
- ~LLRegistry() {}
-
- ptr_value_t getValue(ref_const_key_t key)
- {
- for(scope_list_iterator_t it = mActiveScopes.begin();
- it != mActiveScopes.end();
- ++it)
- {
- ptr_value_t valuep = (*it)->getValue(key);
- if (valuep != NULL) return valuep;
- }
- return mDefaultRegistrar.getValue(key);
- }
-
- ptr_const_value_t getValue(ref_const_key_t key) const
- {
- for(scope_list_const_iterator_t it = mActiveScopes.begin();
- it != mActiveScopes.end();
- ++it)
- {
- ptr_value_t valuep = (*it)->getValue(key);
- if (valuep != NULL) return valuep;
- }
- return mDefaultRegistrar.getValue(key);
- }
-
- bool exists(ref_const_key_t key) const
- {
- for(scope_list_const_iterator_t it = mActiveScopes.begin();
- it != mActiveScopes.end();
- ++it)
- {
- if ((*it)->exists(key)) return true;
- }
-
- return mDefaultRegistrar.exists(key);
- }
-
- bool empty() const
- {
- for(scope_list_const_iterator_t it = mActiveScopes.begin();
- it != mActiveScopes.end();
- ++it)
- {
- if (!(*it)->empty()) return false;
- }
-
- return mDefaultRegistrar.empty();
- }
-
-
- Registrar& defaultRegistrar()
- {
- return mDefaultRegistrar;
- }
-
- const Registrar& defaultRegistrar() const
- {
- return mDefaultRegistrar;
- }
-
-
- Registrar& currentRegistrar()
- {
- if (!mActiveScopes.empty())
- {
- return *mActiveScopes.front();
- }
-
- return mDefaultRegistrar;
- }
-
- const Registrar& currentRegistrar() const
- {
- if (!mActiveScopes.empty())
- {
- return *mActiveScopes.front();
- }
-
- return mDefaultRegistrar;
- }
-
-
-protected:
- void addScope(Registrar* scope)
- {
- // newer scopes go up front
- mActiveScopes.insert(mActiveScopes.begin(), scope);
- }
-
- void removeScope(Registrar* scope)
- {
- // O(N) but should be near the beggining and N should be small and this is safer than storing iterators
- scope_list_iterator_t iter = std::find(mActiveScopes.begin(), mActiveScopes.end(), scope);
- if (iter != mActiveScopes.end())
- {
- mActiveScopes.erase(iter);
- }
- }
-
-private:
- scope_list_t mActiveScopes;
- Registrar mDefaultRegistrar;
-};
-
-template <typename KEY, typename VALUE, typename DERIVED_TYPE, typename COMPARATOR = LLRegistryDefaultComparator<KEY> >
-class LLRegistrySingleton
- : public LLRegistry<KEY, VALUE, COMPARATOR>,
- public LLSingleton<DERIVED_TYPE>
-{
- friend class LLSingleton<DERIVED_TYPE>;
-public:
- typedef LLRegistry<KEY, VALUE, COMPARATOR> registry_t;
- typedef const KEY& ref_const_key_t;
- typedef const VALUE& ref_const_value_t;
- typedef VALUE* ptr_value_t;
- typedef const VALUE* ptr_const_value_t;
- typedef LLSingleton<DERIVED_TYPE> singleton_t;
-
- class ScopedRegistrar : public registry_t::Registrar
- {
- public:
- ScopedRegistrar(bool push_scope = true)
- {
- if (push_scope)
- {
- pushScope();
- }
- }
-
- ~ScopedRegistrar()
- {
- if (!singleton_t::destroyed())
- {
- popScope();
- }
- }
-
- void pushScope()
- {
- singleton_t::instance().addScope(this);
- }
-
- void popScope()
- {
- singleton_t::instance().removeScope(this);
- }
-
- ptr_value_t getValueFromScope(ref_const_key_t key)
- {
- return getValue(key);
- }
-
- ptr_const_value_t getValueFromScope(ref_const_key_t key) const
- {
- return getValue(key);
- }
-
- private:
- typename std::list<typename registry_t::Registrar*>::iterator mListIt;
- };
-
- class StaticRegistrar : public registry_t::Registrar
- {
- public:
- virtual ~StaticRegistrar() {}
- StaticRegistrar(ref_const_key_t key, ref_const_value_t value)
- {
- singleton_t::instance().mStaticScope->add(key, value);
- }
- };
-
- // convenience functions
- typedef typename LLRegistry<KEY, VALUE, COMPARATOR>::Registrar& ref_registrar_t;
- static ref_registrar_t currentRegistrar()
- {
- return singleton_t::instance().registry_t::currentRegistrar();
- }
-
- static ref_registrar_t defaultRegistrar()
- {
- return singleton_t::instance().registry_t::defaultRegistrar();
- }
-
- static ptr_value_t getValue(ref_const_key_t key)
- {
- return singleton_t::instance().registry_t::getValue(key);
- }
-
-protected:
- // DERIVED_TYPE needs to derive from LLRegistrySingleton
- LLRegistrySingleton()
- : mStaticScope(NULL)
- {}
-
- virtual void initSingleton()
- {
- mStaticScope = new ScopedRegistrar();
- }
-
- virtual ~LLRegistrySingleton()
- {
- delete mStaticScope;
- }
-
-private:
- ScopedRegistrar* mStaticScope;
-};
-
-// helper macro for doing static registration
-#define GLUED_TOKEN(x, y) x ## y
-#define GLUE_TOKENS(x, y) GLUED_TOKEN(x, y)
-#define LLREGISTER_STATIC(REGISTRY, KEY, VALUE) static REGISTRY::StaticRegistrar GLUE_TOKENS(reg, __LINE__)(KEY, VALUE);
-
-#endif
diff --git a/indra/llxuixml/llxuiparser.cpp b/indra/llxuixml/llxuiparser.cpp
deleted file mode 100644
index afc76024d1..0000000000
--- a/indra/llxuixml/llxuiparser.cpp
+++ /dev/null
@@ -1,1756 +0,0 @@
-/**
- * @file llxuiparser.cpp
- * @brief Utility functions for handling XUI structures in XML
- *
- * $LicenseInfo:firstyear=2003&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 "llxuiparser.h"
-
-#include "llxmlnode.h"
-
-#ifdef LL_STANDALONE
-#include <expat.h>
-#else
-#include "expat/expat.h"
-#endif
-
-#include <fstream>
-#include <boost/tokenizer.hpp>
-//#include <boost/spirit/include/qi.hpp>
-#include <boost/spirit/include/classic_core.hpp>
-
-#include "lluicolor.h"
-
-using namespace BOOST_SPIRIT_CLASSIC_NS;
-
-const S32 MAX_STRING_ATTRIBUTE_SIZE = 40;
-
-static LLInitParam::Parser::parser_read_func_map_t sXSDReadFuncs;
-static LLInitParam::Parser::parser_write_func_map_t sXSDWriteFuncs;
-static LLInitParam::Parser::parser_inspect_func_map_t sXSDInspectFuncs;
-
-static LLInitParam::Parser::parser_read_func_map_t sSimpleXUIReadFuncs;
-static LLInitParam::Parser::parser_write_func_map_t sSimpleXUIWriteFuncs;
-static LLInitParam::Parser::parser_inspect_func_map_t sSimpleXUIInspectFuncs;
-
-const char* NO_VALUE_MARKER = "no_value";
-
-const S32 LINE_NUMBER_HERE = 0;
-
-struct MaxOccursValues : public LLInitParam::TypeValuesHelper<U32, MaxOccursValues>
-{
- static void declareValues()
- {
- declare("unbounded", U32_MAX);
- }
-};
-
-struct Occurs : public LLInitParam::Block<Occurs>
-{
- Optional<U32> minOccurs;
- Optional<U32, MaxOccursValues> maxOccurs;
-
- Occurs()
- : minOccurs("minOccurs", 0),
- maxOccurs("maxOccurs", U32_MAX)
-
- {}
-};
-
-
-typedef enum
-{
- USE_REQUIRED,
- USE_OPTIONAL
-} EUse;
-
-namespace LLInitParam
-{
- template<>
- struct TypeValues<EUse> : public TypeValuesHelper<EUse>
- {
- static void declareValues()
- {
- declare("required", USE_REQUIRED);
- declare("optional", USE_OPTIONAL);
- }
- };
-}
-
-struct Element;
-struct Group;
-struct Choice;
-struct Sequence;
-struct Any;
-
-struct Attribute : public LLInitParam::Block<Attribute>
-{
- Mandatory<std::string> name;
- Mandatory<std::string> type;
- Mandatory<EUse> use;
-
- Attribute()
- : name("name"),
- type("type"),
- use("use")
- {}
-};
-
-struct Any : public LLInitParam::Block<Any, Occurs>
-{
- Optional<std::string> _namespace;
-
- Any()
- : _namespace("namespace")
- {}
-};
-
-struct All : public LLInitParam::Block<All, Occurs>
-{
- Multiple< Lazy<Element> > elements;
-
- All()
- : elements("element")
- {
- maxOccurs = 1;
- }
-};
-
-struct Choice : public LLInitParam::ChoiceBlock<Choice, Occurs>
-{
- Alternative< Lazy<Element> > element;
- Alternative< Lazy<Group> > group;
- Alternative< Lazy<Choice> > choice;
- Alternative< Lazy<Sequence> > sequence;
- Alternative< Lazy<Any> > any;
-
- Choice()
- : element("element"),
- group("group"),
- choice("choice"),
- sequence("sequence"),
- any("any")
- {}
-
-};
-
-struct Sequence : public LLInitParam::ChoiceBlock<Sequence, Occurs>
-{
- Alternative< Lazy<Element> > element;
- Alternative< Lazy<Group> > group;
- Alternative< Lazy<Choice> > choice;
- Alternative< Lazy<Sequence> > sequence;
- Alternative< Lazy<Any> > any;
-};
-
-struct GroupContents : public LLInitParam::ChoiceBlock<GroupContents, Occurs>
-{
- Alternative<All> all;
- Alternative<Choice> choice;
- Alternative<Sequence> sequence;
-
- GroupContents()
- : all("all"),
- choice("choice"),
- sequence("sequence")
- {}
-};
-
-struct Group : public LLInitParam::Block<Group, GroupContents>
-{
- Optional<std::string> name,
- ref;
-
- Group()
- : name("name"),
- ref("ref")
- {}
-};
-
-struct Restriction : public LLInitParam::Block<Restriction>
-{
-};
-
-struct Extension : public LLInitParam::Block<Extension>
-{
-};
-
-struct SimpleContent : public LLInitParam::ChoiceBlock<SimpleContent>
-{
- Alternative<Restriction> restriction;
- Alternative<Extension> extension;
-
- SimpleContent()
- : restriction("restriction"),
- extension("extension")
- {}
-};
-
-struct SimpleType : public LLInitParam::Block<SimpleType>
-{
- // TODO
-};
-
-struct ComplexContent : public LLInitParam::Block<ComplexContent, SimpleContent>
-{
- Optional<bool> mixed;
-
- ComplexContent()
- : mixed("mixed", true)
- {}
-};
-
-struct ComplexTypeContents : public LLInitParam::ChoiceBlock<ComplexTypeContents>
-{
- Alternative<SimpleContent> simple_content;
- Alternative<ComplexContent> complex_content;
- Alternative<Group> group;
- Alternative<All> all;
- Alternative<Choice> choice;
- Alternative<Sequence> sequence;
-
- ComplexTypeContents()
- : simple_content("simpleContent"),
- complex_content("complexContent"),
- group("group"),
- all("all"),
- choice("choice"),
- sequence("sequence")
- {}
-};
-
-struct ComplexType : public LLInitParam::Block<ComplexType, ComplexTypeContents>
-{
- Optional<std::string> name;
- Optional<bool> mixed;
-
- Multiple<Attribute> attribute;
- Multiple< Lazy<Element> > elements;
-
- ComplexType()
- : name("name"),
- attribute("xs:attribute"),
- elements("xs:element"),
- mixed("mixed")
- {
- }
-};
-
-struct ElementContents : public LLInitParam::ChoiceBlock<ElementContents, Occurs>
-{
- Alternative<SimpleType> simpleType;
- Alternative<ComplexType> complexType;
-
- ElementContents()
- : simpleType("simpleType"),
- complexType("complexType")
- {}
-};
-
-struct Element : public LLInitParam::Block<Element, ElementContents>
-{
- Optional<std::string> name,
- ref,
- type;
-
- Element()
- : name("xs:name"),
- ref("xs:ref"),
- type("xs:type")
- {}
-};
-
-struct Schema : public LLInitParam::Block<Schema>
-{
-private:
- Mandatory<std::string> targetNamespace,
- xmlns,
- xs;
-
-public:
- Optional<std::string> attributeFormDefault,
- elementFormDefault;
-
- Mandatory<Element> root_element;
-
- void setNameSpace(const std::string& ns) {targetNamespace = ns; xmlns = ns;}
-
- Schema(const std::string& ns = LLStringUtil::null)
- : attributeFormDefault("attributeFormDefault"),
- elementFormDefault("elementFormDefault"),
- xs("xmlns:xs"),
- targetNamespace("targetNamespace"),
- xmlns("xmlns"),
- root_element("xs:element")
- {
- attributeFormDefault = "unqualified";
- elementFormDefault = "qualified";
- xs = "http://www.w3.org/2001/XMLSchema";
- if (!ns.empty())
- {
- setNameSpace(ns);
- };
- }
-
-};
-
-//
-// LLXSDWriter
-//
-LLXSDWriter::LLXSDWriter()
-: Parser(sXSDReadFuncs, sXSDWriteFuncs, sXSDInspectFuncs)
-{
- registerInspectFunc<bool>(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:boolean", _1, _2, _3, _4));
- registerInspectFunc<std::string>(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:string", _1, _2, _3, _4));
- registerInspectFunc<U8>(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:unsignedByte", _1, _2, _3, _4));
- registerInspectFunc<S8>(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:signedByte", _1, _2, _3, _4));
- registerInspectFunc<U16>(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:unsignedShort", _1, _2, _3, _4));
- registerInspectFunc<S16>(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:signedShort", _1, _2, _3, _4));
- registerInspectFunc<U32>(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:unsignedInt", _1, _2, _3, _4));
- registerInspectFunc<S32>(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:integer", _1, _2, _3, _4));
- registerInspectFunc<F32>(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:float", _1, _2, _3, _4));
- registerInspectFunc<F64>(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:double", _1, _2, _3, _4));
- registerInspectFunc<LLColor4>(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:string", _1, _2, _3, _4));
- registerInspectFunc<LLUIColor>(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:string", _1, _2, _3, _4));
- registerInspectFunc<LLUUID>(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:string", _1, _2, _3, _4));
- registerInspectFunc<LLSD>(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:string", _1, _2, _3, _4));
-}
-
-void LLXSDWriter::writeXSD(const std::string& type_name, LLXMLNodePtr node, const LLInitParam::BaseBlock& block, const std::string& xml_namespace)
-{
- Schema schema(xml_namespace);
-
- schema.root_element.name = type_name;
- Choice& choice = schema.root_element.complexType.choice;
-
- choice.minOccurs = 0;
- choice.maxOccurs = "unbounded";
-
- mSchemaNode = node;
- //node->setName("xs:schema");
- //node->createChild("attributeFormDefault", true)->setStringValue("unqualified");
- //node->createChild("elementFormDefault", true)->setStringValue("qualified");
- //node->createChild("targetNamespace", true)->setStringValue(xml_namespace);
- //node->createChild("xmlns:xs", true)->setStringValue("http://www.w3.org/2001/XMLSchema");
- //node->createChild("xmlns", true)->setStringValue(xml_namespace);
-
- //node = node->createChild("xs:complexType", false);
- //node->createChild("name", true)->setStringValue(type_name);
- //node->createChild("mixed", true)->setStringValue("true");
-
- //mAttributeNode = node;
- //mElementNode = node->createChild("xs:choice", false);
- //mElementNode->createChild("minOccurs", true)->setStringValue("0");
- //mElementNode->createChild("maxOccurs", true)->setStringValue("unbounded");
- block.inspectBlock(*this);
-
- // duplicate element choices
- LLXMLNodeList children;
- mElementNode->getChildren("xs:element", children, FALSE);
- for (LLXMLNodeList::iterator child_it = children.begin(); child_it != children.end(); ++child_it)
- {
- LLXMLNodePtr child_copy = child_it->second->deepCopy();
- std::string child_name;
- child_copy->getAttributeString("name", child_name);
- child_copy->setAttributeString("name", type_name + "." + child_name);
- mElementNode->addChild(child_copy);
- }
-
- LLXMLNodePtr element_declaration_node = mSchemaNode->createChild("xs:element", false);
- element_declaration_node->createChild("name", true)->setStringValue(type_name);
- element_declaration_node->createChild("type", true)->setStringValue(type_name);
-}
-
-void LLXSDWriter::writeAttribute(const std::string& type, const Parser::name_stack_t& stack, S32 min_count, S32 max_count, const std::vector<std::string>* possible_values)
-{
- name_stack_t non_empty_names;
- std::string attribute_name;
- for (name_stack_t::const_iterator it = stack.begin();
- it != stack.end();
- ++it)
- {
- const std::string& name = it->first;
- if (!name.empty())
- {
- non_empty_names.push_back(*it);
- }
- }
-
- for (name_stack_t::const_iterator it = non_empty_names.begin();
- it != non_empty_names.end();
- ++it)
- {
- if (!attribute_name.empty())
- {
- attribute_name += ".";
- }
- attribute_name += it->first;
- }
-
- // only flag non-nested attributes as mandatory, nested attributes have variant syntax
- // that can't be properly constrained in XSD
- // e.g. <foo mandatory.value="bar"/> vs <foo><mandatory value="bar"/></foo>
- bool attribute_mandatory = min_count == 1 && max_count == 1 && non_empty_names.size() == 1;
-
- // don't bother supporting "Multiple" params as xml attributes
- if (max_count <= 1)
- {
- // add compound attribute to root node
- addAttributeToSchema(mAttributeNode, attribute_name, type, attribute_mandatory, possible_values);
- }
-
- // now generated nested elements for compound attributes
- if (non_empty_names.size() > 1 && !attribute_mandatory)
- {
- std::string element_name;
-
- // traverse all but last element, leaving that as an attribute name
- name_stack_t::const_iterator end_it = non_empty_names.end();
- end_it--;
-
- for (name_stack_t::const_iterator it = non_empty_names.begin();
- it != end_it;
- ++it)
- {
- if (it != non_empty_names.begin())
- {
- element_name += ".";
- }
- element_name += it->first;
- }
-
- std::string short_attribute_name = non_empty_names.back().first;
-
- LLXMLNodePtr complex_type_node;
-
- // find existing element node here, starting at tail of child list
- if (mElementNode->mChildren.notNull())
- {
- for(LLXMLNodePtr element = mElementNode->mChildren->tail;
- element.notNull();
- element = element->mPrev)
- {
- std::string name;
- if(element->getAttributeString("name", name) && name == element_name)
- {
- complex_type_node = element->mChildren->head;
- break;
- }
- }
- }
- //create complex_type node
- //
- //<xs:element
- // maxOccurs="1"
- // minOccurs="0"
- // name="name">
- // <xs:complexType>
- // </xs:complexType>
- //</xs:element>
- if(complex_type_node.isNull())
- {
- complex_type_node = mElementNode->createChild("xs:element", false);
-
- complex_type_node->createChild("minOccurs", true)->setIntValue(min_count);
- complex_type_node->createChild("maxOccurs", true)->setIntValue(max_count);
- complex_type_node->createChild("name", true)->setStringValue(element_name);
- complex_type_node = complex_type_node->createChild("xs:complexType", false);
- }
-
- addAttributeToSchema(complex_type_node, short_attribute_name, type, false, possible_values);
- }
-}
-
-void LLXSDWriter::addAttributeToSchema(LLXMLNodePtr type_declaration_node, const std::string& attribute_name, const std::string& type, bool mandatory, const std::vector<std::string>* possible_values)
-{
- if (!attribute_name.empty())
- {
- LLXMLNodePtr new_enum_type_node;
- if (possible_values != NULL)
- {
- // custom attribute type, for example
- //<xs:simpleType>
- // <xs:restriction
- // base="xs:string">
- // <xs:enumeration
- // value="a" />
- // <xs:enumeration
- // value="b" />
- // </xs:restriction>
- // </xs:simpleType>
- new_enum_type_node = new LLXMLNode("xs:simpleType", false);
-
- LLXMLNodePtr restriction_node = new_enum_type_node->createChild("xs:restriction", false);
- restriction_node->createChild("base", true)->setStringValue("xs:string");
-
- for (std::vector<std::string>::const_iterator it = possible_values->begin();
- it != possible_values->end();
- ++it)
- {
- LLXMLNodePtr enum_node = restriction_node->createChild("xs:enumeration", false);
- enum_node->createChild("value", true)->setStringValue(*it);
- }
- }
-
- string_set_t& attributes_written = mAttributesWritten[type_declaration_node];
-
- string_set_t::iterator found_it = attributes_written.lower_bound(attribute_name);
-
- // attribute not yet declared
- if (found_it == attributes_written.end() || attributes_written.key_comp()(attribute_name, *found_it))
- {
- attributes_written.insert(found_it, attribute_name);
-
- LLXMLNodePtr attribute_node = type_declaration_node->createChild("xs:attribute", false);
-
- // attribute name
- attribute_node->createChild("name", true)->setStringValue(attribute_name);
-
- if (new_enum_type_node.notNull())
- {
- attribute_node->addChild(new_enum_type_node);
- }
- else
- {
- // simple attribute type
- attribute_node->createChild("type", true)->setStringValue(type);
- }
-
- // required or optional
- attribute_node->createChild("use", true)->setStringValue(mandatory ? "required" : "optional");
- }
- // attribute exists...handle collision of same name attributes with potentially different types
- else
- {
- LLXMLNodePtr attribute_declaration;
- if (type_declaration_node.notNull())
- {
- for(LLXMLNodePtr node = type_declaration_node->mChildren->tail;
- node.notNull();
- node = node->mPrev)
- {
- std::string name;
- if (node->getAttributeString("name", name) && name == attribute_name)
- {
- attribute_declaration = node;
- break;
- }
- }
- }
-
- bool new_type_is_enum = new_enum_type_node.notNull();
- bool existing_type_is_enum = !attribute_declaration->hasAttribute("type");
-
- // either type is enum, revert to string in collision
- // don't bother to check for enum equivalence
- if (new_type_is_enum || existing_type_is_enum)
- {
- if (attribute_declaration->hasAttribute("type"))
- {
- attribute_declaration->setAttributeString("type", "xs:string");
- }
- else
- {
- attribute_declaration->createChild("type", true)->setStringValue("xs:string");
- }
- attribute_declaration->deleteChildren("xs:simpleType");
- }
- else
- {
- // check for collision of different standard types
- std::string existing_type;
- attribute_declaration->getAttributeString("type", existing_type);
- // if current type is not the same as the new type, revert to strnig
- if (existing_type != type)
- {
- // ...than use most general type, string
- attribute_declaration->setAttributeString("type", "string");
- }
- }
- }
- }
-}
-
-//
-// LLXUIXSDWriter
-//
-void LLXUIXSDWriter::writeXSD(const std::string& type_name, const std::string& path, const LLInitParam::BaseBlock& block)
-{
- std::string file_name(path);
- file_name += type_name + ".xsd";
- LLXMLNodePtr root_nodep = new LLXMLNode();
-
- LLXSDWriter::writeXSD(type_name, root_nodep, block, "http://www.lindenlab.com/xui");
-
- // add includes for all possible children
- const std::type_info* type = *LLWidgetTypeRegistry::instance().getValue(type_name);
- const widget_registry_t* widget_registryp = LLChildRegistryRegistry::instance().getValue(type);
-
- // add choices for valid children
- if (widget_registryp)
- {
- // add include declarations for all valid children
- for (widget_registry_t::Registrar::registry_map_t::const_iterator it = widget_registryp->currentRegistrar().beginItems();
- it != widget_registryp->currentRegistrar().endItems();
- ++it)
- {
- std::string widget_name = it->first;
- if (widget_name == type_name)
- {
- continue;
- }
- LLXMLNodePtr nodep = new LLXMLNode("xs:include", false);
- nodep->createChild("schemaLocation", true)->setStringValue(widget_name + ".xsd");
-
- // add to front of schema
- mSchemaNode->addChild(nodep, mSchemaNode);
- }
-
- for (widget_registry_t::Registrar::registry_map_t::const_iterator it = widget_registryp->currentRegistrar().beginItems();
- it != widget_registryp->currentRegistrar().endItems();
- ++it)
- {
- std::string widget_name = it->first;
- //<xs:element name="widget_name" type="widget_name">
- LLXMLNodePtr widget_node = mElementNode->createChild("xs:element", false);
- widget_node->createChild("name", true)->setStringValue(widget_name);
- widget_node->createChild("type", true)->setStringValue(widget_name);
- }
- }
-
- LLFILE* xsd_file = LLFile::fopen(file_name.c_str(), "w");
- LLXMLNode::writeHeaderToFile(xsd_file);
- root_nodep->writeToFile(xsd_file);
- fclose(xsd_file);
-}
-
-static LLInitParam::Parser::parser_read_func_map_t sXUIReadFuncs;
-static LLInitParam::Parser::parser_write_func_map_t sXUIWriteFuncs;
-static LLInitParam::Parser::parser_inspect_func_map_t sXUIInspectFuncs;
-
-//
-// LLXUIParser
-//
-LLXUIParser::LLXUIParser()
-: Parser(sXUIReadFuncs, sXUIWriteFuncs, sXUIInspectFuncs),
- mCurReadDepth(0)
-{
- if (sXUIReadFuncs.empty())
- {
- registerParserFuncs<LLInitParam::Flag>(readFlag, writeFlag);
- registerParserFuncs<bool>(readBoolValue, writeBoolValue);
- registerParserFuncs<std::string>(readStringValue, writeStringValue);
- registerParserFuncs<U8>(readU8Value, writeU8Value);
- registerParserFuncs<S8>(readS8Value, writeS8Value);
- registerParserFuncs<U16>(readU16Value, writeU16Value);
- registerParserFuncs<S16>(readS16Value, writeS16Value);
- registerParserFuncs<U32>(readU32Value, writeU32Value);
- registerParserFuncs<S32>(readS32Value, writeS32Value);
- registerParserFuncs<F32>(readF32Value, writeF32Value);
- registerParserFuncs<F64>(readF64Value, writeF64Value);
- registerParserFuncs<LLColor4>(readColor4Value, writeColor4Value);
- registerParserFuncs<LLUIColor>(readUIColorValue, writeUIColorValue);
- registerParserFuncs<LLUUID>(readUUIDValue, writeUUIDValue);
- registerParserFuncs<LLSD>(readSDValue, writeSDValue);
- }
-}
-
-static LLFastTimer::DeclareTimer FTM_PARSE_XUI("XUI Parsing");
-const LLXMLNodePtr DUMMY_NODE = new LLXMLNode();
-
-void LLXUIParser::readXUI(LLXMLNodePtr node, LLInitParam::BaseBlock& block, const std::string& filename, bool silent)
-{
- LLFastTimer timer(FTM_PARSE_XUI);
- mNameStack.clear();
- mRootNodeName = node->getName()->mString;
- mCurFileName = filename;
- mCurReadDepth = 0;
- setParseSilently(silent);
-
- if (node.isNull())
- {
- parserWarning("Invalid node");
- }
- else
- {
- readXUIImpl(node, block);
- }
-}
-
-bool LLXUIParser::readXUIImpl(LLXMLNodePtr nodep, LLInitParam::BaseBlock& block)
-{
- typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
- boost::char_separator<char> sep(".");
-
- bool values_parsed = false;
- bool silent = mCurReadDepth > 0;
-
- if (nodep->getFirstChild().isNull()
- && nodep->mAttributes.empty()
- && nodep->getSanitizedValue().empty())
- {
- // empty node, just parse as flag
- mCurReadNode = DUMMY_NODE;
- return block.submitValue(mNameStack, *this, silent);
- }
-
- // submit attributes for current node
- values_parsed |= readAttributes(nodep, block);
-
- // treat text contents of xml node as "value" parameter
- std::string text_contents = nodep->getSanitizedValue();
- if (!text_contents.empty())
- {
- mCurReadNode = nodep;
- mNameStack.push_back(std::make_pair(std::string("value"), true));
- // child nodes are not necessarily valid parameters (could be a child widget)
- // so don't complain once we've recursed
- if (!block.submitValue(mNameStack, *this, true))
- {
- mNameStack.pop_back();
- block.submitValue(mNameStack, *this, silent);
- }
- else
- {
- mNameStack.pop_back();
- }
- }
-
- // then traverse children
- // child node must start with last name of parent node (our "scope")
- // for example: "<button><button.param nested_param1="foo"><param.nested_param2 nested_param3="bar"/></button.param></button>"
- // which equates to the following nesting:
- // button
- // param
- // nested_param1
- // nested_param2
- // nested_param3
- mCurReadDepth++;
- for(LLXMLNodePtr childp = nodep->getFirstChild(); childp.notNull();)
- {
- std::string child_name(childp->getName()->mString);
- S32 num_tokens_pushed = 0;
-
- // for non "dotted" child nodes check to see if child node maps to another widget type
- // and if not, treat as a child element of the current node
- // e.g. <button><rect left="10"/></button> will interpret <rect> as "button.rect"
- // since there is no widget named "rect"
- if (child_name.find(".") == std::string::npos)
- {
- mNameStack.push_back(std::make_pair(child_name, true));
- num_tokens_pushed++;
- }
- else
- {
- // parse out "dotted" name into individual tokens
- tokenizer name_tokens(child_name, sep);
-
- tokenizer::iterator name_token_it = name_tokens.begin();
- if(name_token_it == name_tokens.end())
- {
- childp = childp->getNextSibling();
- continue;
- }
-
- // check for proper nesting
- if (mNameStack.empty())
- {
- if (*name_token_it != mRootNodeName)
- {
- childp = childp->getNextSibling();
- continue;
- }
- }
- else if(mNameStack.back().first != *name_token_it)
- {
- childp = childp->getNextSibling();
- continue;
- }
-
- // now ignore first token
- ++name_token_it;
-
- // copy remaining tokens on to our running token list
- for(tokenizer::iterator token_to_push = name_token_it; token_to_push != name_tokens.end(); ++token_to_push)
- {
- mNameStack.push_back(std::make_pair(*token_to_push, true));
- num_tokens_pushed++;
- }
- }
-
- // recurse and visit children XML nodes
- if(readXUIImpl(childp, block))
- {
- // child node successfully parsed, remove from DOM
-
- values_parsed = true;
- LLXMLNodePtr node_to_remove = childp;
- childp = childp->getNextSibling();
-
- nodep->deleteChild(node_to_remove);
- }
- else
- {
- childp = childp->getNextSibling();
- }
-
- while(num_tokens_pushed-- > 0)
- {
- mNameStack.pop_back();
- }
- }
- mCurReadDepth--;
- return values_parsed;
-}
-
-bool LLXUIParser::readAttributes(LLXMLNodePtr nodep, LLInitParam::BaseBlock& block)
-{
- typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
- boost::char_separator<char> sep(".");
-
- bool any_parsed = false;
- bool silent = mCurReadDepth > 0;
-
- for(LLXMLAttribList::const_iterator attribute_it = nodep->mAttributes.begin();
- attribute_it != nodep->mAttributes.end();
- ++attribute_it)
- {
- S32 num_tokens_pushed = 0;
- std::string attribute_name(attribute_it->first->mString);
- mCurReadNode = attribute_it->second;
-
- tokenizer name_tokens(attribute_name, sep);
- // copy remaining tokens on to our running token list
- for(tokenizer::iterator token_to_push = name_tokens.begin(); token_to_push != name_tokens.end(); ++token_to_push)
- {
- mNameStack.push_back(std::make_pair(*token_to_push, true));
- num_tokens_pushed++;
- }
-
- // child nodes are not necessarily valid attributes, so don't complain once we've recursed
- any_parsed |= block.submitValue(mNameStack, *this, silent);
-
- while(num_tokens_pushed-- > 0)
- {
- mNameStack.pop_back();
- }
- }
-
- return any_parsed;
-}
-
-void LLXUIParser::writeXUI(LLXMLNodePtr node, const LLInitParam::BaseBlock &block, const LLInitParam::BaseBlock* diff_block)
-{
- mWriteRootNode = node;
- name_stack_t name_stack = Parser::name_stack_t();
- block.serializeBlock(*this, name_stack, diff_block);
- mOutNodes.clear();
-}
-
-// go from a stack of names to a specific XML node
-LLXMLNodePtr LLXUIParser::getNode(name_stack_t& stack)
-{
- LLXMLNodePtr out_node = mWriteRootNode;
-
- name_stack_t::iterator next_it = stack.begin();
- for (name_stack_t::iterator it = stack.begin();
- it != stack.end();
- it = next_it)
- {
- ++next_it;
- if (it->first.empty())
- {
- it->second = false;
- continue;
- }
-
- out_nodes_t::iterator found_it = mOutNodes.find(it->first);
-
- // node with this name not yet written
- if (found_it == mOutNodes.end() || it->second)
- {
- // make an attribute if we are the last element on the name stack
- bool is_attribute = next_it == stack.end();
- LLXMLNodePtr new_node = new LLXMLNode(it->first.c_str(), is_attribute);
- out_node->addChild(new_node);
- mOutNodes[it->first] = new_node;
- out_node = new_node;
- it->second = false;
- }
- else
- {
- out_node = found_it->second;
- }
- }
-
- return (out_node == mWriteRootNode ? LLXMLNodePtr(NULL) : out_node);
-}
-
-bool LLXUIParser::readFlag(Parser& parser, void* val_ptr)
-{
- LLXUIParser& self = static_cast<LLXUIParser&>(parser);
- return self.mCurReadNode == DUMMY_NODE;
-}
-
-bool LLXUIParser::writeFlag(Parser& parser, const void* val_ptr, name_stack_t& stack)
-{
- // just create node
- LLXUIParser& self = static_cast<LLXUIParser&>(parser);
- LLXMLNodePtr node = self.getNode(stack);
- return node.notNull();
-}
-
-bool LLXUIParser::readBoolValue(Parser& parser, void* val_ptr)
-{
- S32 value;
- LLXUIParser& self = static_cast<LLXUIParser&>(parser);
- bool success = self.mCurReadNode->getBoolValue(1, &value);
- *((bool*)val_ptr) = (value != FALSE);
- return success;
-}
-
-bool LLXUIParser::writeBoolValue(Parser& parser, const void* val_ptr, name_stack_t& stack)
-{
- LLXUIParser& self = static_cast<LLXUIParser&>(parser);
- LLXMLNodePtr node = self.getNode(stack);
- if (node.notNull())
- {
- node->setBoolValue(*((bool*)val_ptr));
- return true;
- }
- return false;
-}
-
-bool LLXUIParser::readStringValue(Parser& parser, void* val_ptr)
-{
- LLXUIParser& self = static_cast<LLXUIParser&>(parser);
- *((std::string*)val_ptr) = self.mCurReadNode->getSanitizedValue();
- return true;
-}
-
-bool LLXUIParser::writeStringValue(Parser& parser, const void* val_ptr, name_stack_t& stack)
-{
- LLXUIParser& self = static_cast<LLXUIParser&>(parser);
- LLXMLNodePtr node = self.getNode(stack);
- if (node.notNull())
- {
- const std::string* string_val = reinterpret_cast<const std::string*>(val_ptr);
- if (string_val->find('\n') != std::string::npos
- || string_val->size() > MAX_STRING_ATTRIBUTE_SIZE)
- {
- // don't write strings with newlines into attributes
- std::string attribute_name = node->getName()->mString;
- LLXMLNodePtr parent_node = node->mParent;
- parent_node->deleteChild(node);
- // write results in text contents of node
- if (attribute_name == "value")
- {
- // "value" is implicit, just write to parent
- node = parent_node;
- }
- else
- {
- // create a child that is not an attribute, but with same name
- node = parent_node->createChild(attribute_name.c_str(), false);
- }
- }
- node->setStringValue(*string_val);
- return true;
- }
- return false;
-}
-
-bool LLXUIParser::readU8Value(Parser& parser, void* val_ptr)
-{
- LLXUIParser& self = static_cast<LLXUIParser&>(parser);
- return self.mCurReadNode->getByteValue(1, (U8*)val_ptr);
-}
-
-bool LLXUIParser::writeU8Value(Parser& parser, const void* val_ptr, name_stack_t& stack)
-{
- LLXUIParser& self = static_cast<LLXUIParser&>(parser);
- LLXMLNodePtr node = self.getNode(stack);
- if (node.notNull())
- {
- node->setUnsignedValue(*((U8*)val_ptr));
- return true;
- }
- return false;
-}
-
-bool LLXUIParser::readS8Value(Parser& parser, void* val_ptr)
-{
- LLXUIParser& self = static_cast<LLXUIParser&>(parser);
- S32 value;
- if(self.mCurReadNode->getIntValue(1, &value))
- {
- *((S8*)val_ptr) = value;
- return true;
- }
- return false;
-}
-
-bool LLXUIParser::writeS8Value(Parser& parser, const void* val_ptr, name_stack_t& stack)
-{
- LLXUIParser& self = static_cast<LLXUIParser&>(parser);
- LLXMLNodePtr node = self.getNode(stack);
- if (node.notNull())
- {
- node->setIntValue(*((S8*)val_ptr));
- return true;
- }
- return false;
-}
-
-bool LLXUIParser::readU16Value(Parser& parser, void* val_ptr)
-{
- LLXUIParser& self = static_cast<LLXUIParser&>(parser);
- U32 value;
- if(self.mCurReadNode->getUnsignedValue(1, &value))
- {
- *((U16*)val_ptr) = value;
- return true;
- }
- return false;
-}
-
-bool LLXUIParser::writeU16Value(Parser& parser, const void* val_ptr, name_stack_t& stack)
-{
- LLXUIParser& self = static_cast<LLXUIParser&>(parser);
- LLXMLNodePtr node = self.getNode(stack);
- if (node.notNull())
- {
- node->setUnsignedValue(*((U16*)val_ptr));
- return true;
- }
- return false;
-}
-
-bool LLXUIParser::readS16Value(Parser& parser, void* val_ptr)
-{
- LLXUIParser& self = static_cast<LLXUIParser&>(parser);
- S32 value;
- if(self.mCurReadNode->getIntValue(1, &value))
- {
- *((S16*)val_ptr) = value;
- return true;
- }
- return false;
-}
-
-bool LLXUIParser::writeS16Value(Parser& parser, const void* val_ptr, name_stack_t& stack)
-{
- LLXUIParser& self = static_cast<LLXUIParser&>(parser);
- LLXMLNodePtr node = self.getNode(stack);
- if (node.notNull())
- {
- node->setIntValue(*((S16*)val_ptr));
- return true;
- }
- return false;
-}
-
-bool LLXUIParser::readU32Value(Parser& parser, void* val_ptr)
-{
- LLXUIParser& self = static_cast<LLXUIParser&>(parser);
- return self.mCurReadNode->getUnsignedValue(1, (U32*)val_ptr);
-}
-
-bool LLXUIParser::writeU32Value(Parser& parser, const void* val_ptr, name_stack_t& stack)
-{
- LLXUIParser& self = static_cast<LLXUIParser&>(parser);
- LLXMLNodePtr node = self.getNode(stack);
- if (node.notNull())
- {
- node->setUnsignedValue(*((U32*)val_ptr));
- return true;
- }
- return false;
-}
-
-bool LLXUIParser::readS32Value(Parser& parser, void* val_ptr)
-{
- LLXUIParser& self = static_cast<LLXUIParser&>(parser);
- return self.mCurReadNode->getIntValue(1, (S32*)val_ptr);
-}
-
-bool LLXUIParser::writeS32Value(Parser& parser, const void* val_ptr, name_stack_t& stack)
-{
- LLXUIParser& self = static_cast<LLXUIParser&>(parser);
- LLXMLNodePtr node = self.getNode(stack);
- if (node.notNull())
- {
- node->setIntValue(*((S32*)val_ptr));
- return true;
- }
- return false;
-}
-
-bool LLXUIParser::readF32Value(Parser& parser, void* val_ptr)
-{
- LLXUIParser& self = static_cast<LLXUIParser&>(parser);
- return self.mCurReadNode->getFloatValue(1, (F32*)val_ptr);
-}
-
-bool LLXUIParser::writeF32Value(Parser& parser, const void* val_ptr, name_stack_t& stack)
-{
- LLXUIParser& self = static_cast<LLXUIParser&>(parser);
- LLXMLNodePtr node = self.getNode(stack);
- if (node.notNull())
- {
- node->setFloatValue(*((F32*)val_ptr));
- return true;
- }
- return false;
-}
-
-bool LLXUIParser::readF64Value(Parser& parser, void* val_ptr)
-{
- LLXUIParser& self = static_cast<LLXUIParser&>(parser);
- return self.mCurReadNode->getDoubleValue(1, (F64*)val_ptr);
-}
-
-bool LLXUIParser::writeF64Value(Parser& parser, const void* val_ptr, name_stack_t& stack)
-{
- LLXUIParser& self = static_cast<LLXUIParser&>(parser);
- LLXMLNodePtr node = self.getNode(stack);
- if (node.notNull())
- {
- node->setDoubleValue(*((F64*)val_ptr));
- return true;
- }
- return false;
-}
-
-bool LLXUIParser::readColor4Value(Parser& parser, void* val_ptr)
-{
- LLXUIParser& self = static_cast<LLXUIParser&>(parser);
- LLColor4* colorp = (LLColor4*)val_ptr;
- if(self.mCurReadNode->getFloatValue(4, colorp->mV) >= 3)
- {
- return true;
- }
-
- return false;
-}
-
-bool LLXUIParser::writeColor4Value(Parser& parser, const void* val_ptr, name_stack_t& stack)
-{
- LLXUIParser& self = static_cast<LLXUIParser&>(parser);
- LLXMLNodePtr node = self.getNode(stack);
- if (node.notNull())
- {
- LLColor4 color = *((LLColor4*)val_ptr);
- node->setFloatValue(4, color.mV);
- return true;
- }
- return false;
-}
-
-bool LLXUIParser::readUIColorValue(Parser& parser, void* val_ptr)
-{
- LLXUIParser& self = static_cast<LLXUIParser&>(parser);
- LLUIColor* param = (LLUIColor*)val_ptr;
- LLColor4 color;
- bool success = self.mCurReadNode->getFloatValue(4, color.mV) >= 3;
- if (success)
- {
- param->set(color);
- return true;
- }
- return false;
-}
-
-bool LLXUIParser::writeUIColorValue(Parser& parser, const void* val_ptr, name_stack_t& stack)
-{
- LLXUIParser& self = static_cast<LLXUIParser&>(parser);
- LLXMLNodePtr node = self.getNode(stack);
- if (node.notNull())
- {
- LLUIColor color = *((LLUIColor*)val_ptr);
- //RN: don't write out the color that is represented by a function
- // rely on param block exporting to get the reference to the color settings
- if (color.isReference()) return false;
- node->setFloatValue(4, color.get().mV);
- return true;
- }
- return false;
-}
-
-bool LLXUIParser::readUUIDValue(Parser& parser, void* val_ptr)
-{
- LLXUIParser& self = static_cast<LLXUIParser&>(parser);
- LLUUID temp_id;
- // LLUUID::set is destructive, so use temporary value
- if (temp_id.set(self.mCurReadNode->getSanitizedValue()))
- {
- *(LLUUID*)(val_ptr) = temp_id;
- return true;
- }
- return false;
-}
-
-bool LLXUIParser::writeUUIDValue(Parser& parser, const void* val_ptr, name_stack_t& stack)
-{
- LLXUIParser& self = static_cast<LLXUIParser&>(parser);
- LLXMLNodePtr node = self.getNode(stack);
- if (node.notNull())
- {
- node->setStringValue(((LLUUID*)val_ptr)->asString());
- return true;
- }
- return false;
-}
-
-bool LLXUIParser::readSDValue(Parser& parser, void* val_ptr)
-{
- LLXUIParser& self = static_cast<LLXUIParser&>(parser);
- *((LLSD*)val_ptr) = LLSD(self.mCurReadNode->getSanitizedValue());
- return true;
-}
-
-bool LLXUIParser::writeSDValue(Parser& parser, const void* val_ptr, name_stack_t& stack)
-{
- LLXUIParser& self = static_cast<LLXUIParser&>(parser);
-
- LLXMLNodePtr node = self.getNode(stack);
- if (node.notNull())
- {
- std::string string_val = ((LLSD*)val_ptr)->asString();
- if (string_val.find('\n') != std::string::npos || string_val.size() > MAX_STRING_ATTRIBUTE_SIZE)
- {
- // don't write strings with newlines into attributes
- std::string attribute_name = node->getName()->mString;
- LLXMLNodePtr parent_node = node->mParent;
- parent_node->deleteChild(node);
- // write results in text contents of node
- if (attribute_name == "value")
- {
- // "value" is implicit, just write to parent
- node = parent_node;
- }
- else
- {
- node = parent_node->createChild(attribute_name.c_str(), false);
- }
- }
-
- node->setStringValue(string_val);
- return true;
- }
- return false;
-}
-
-/*virtual*/ std::string LLXUIParser::getCurrentElementName()
-{
- std::string full_name;
- for (name_stack_t::iterator it = mNameStack.begin();
- it != mNameStack.end();
- ++it)
- {
- full_name += it->first + "."; // build up dotted names: "button.param.nestedparam."
- }
-
- return full_name;
-}
-
-void LLXUIParser::parserWarning(const std::string& message)
-{
-#ifdef LL_WINDOWS
- // use Visual Studo friendly formatting of output message for easy access to originating xml
- llutf16string utf16str = utf8str_to_utf16str(llformat("%s(%d):\t%s", mCurFileName.c_str(), mCurReadNode->getLineNumber(), message.c_str()).c_str());
- utf16str += '\n';
- OutputDebugString(utf16str.c_str());
-#else
- Parser::parserWarning(message);
-#endif
-}
-
-void LLXUIParser::parserError(const std::string& message)
-{
-#ifdef LL_WINDOWS
- llutf16string utf16str = utf8str_to_utf16str(llformat("%s(%d):\t%s", mCurFileName.c_str(), mCurReadNode->getLineNumber(), message.c_str()).c_str());
- utf16str += '\n';
- OutputDebugString(utf16str.c_str());
-#else
- Parser::parserError(message);
-#endif
-}
-
-
-//
-// LLSimpleXUIParser
-//
-
-struct ScopedFile
-{
- ScopedFile( const std::string& filename, const char* accessmode )
- {
- mFile = LLFile::fopen(filename, accessmode);
- }
-
- ~ScopedFile()
- {
- fclose(mFile);
- mFile = NULL;
- }
-
- S32 getRemainingBytes()
- {
- if (!isOpen()) return 0;
-
- S32 cur_pos = ftell(mFile);
- fseek(mFile, 0L, SEEK_END);
- S32 file_size = ftell(mFile);
- fseek(mFile, cur_pos, SEEK_SET);
- return file_size - cur_pos;
- }
-
- bool isOpen() { return mFile != NULL; }
-
- LLFILE* mFile;
-};
-LLSimpleXUIParser::LLSimpleXUIParser(LLSimpleXUIParser::element_start_callback_t element_cb)
-: Parser(sSimpleXUIReadFuncs, sSimpleXUIWriteFuncs, sSimpleXUIInspectFuncs),
- mCurReadDepth(0),
- mElementCB(element_cb)
-{
- if (sSimpleXUIReadFuncs.empty())
- {
- registerParserFuncs<LLInitParam::Flag>(readFlag);
- registerParserFuncs<bool>(readBoolValue);
- registerParserFuncs<std::string>(readStringValue);
- registerParserFuncs<U8>(readU8Value);
- registerParserFuncs<S8>(readS8Value);
- registerParserFuncs<U16>(readU16Value);
- registerParserFuncs<S16>(readS16Value);
- registerParserFuncs<U32>(readU32Value);
- registerParserFuncs<S32>(readS32Value);
- registerParserFuncs<F32>(readF32Value);
- registerParserFuncs<F64>(readF64Value);
- registerParserFuncs<LLColor4>(readColor4Value);
- registerParserFuncs<LLUIColor>(readUIColorValue);
- registerParserFuncs<LLUUID>(readUUIDValue);
- registerParserFuncs<LLSD>(readSDValue);
- }
-}
-
-LLSimpleXUIParser::~LLSimpleXUIParser()
-{
-}
-
-
-bool LLSimpleXUIParser::readXUI(const std::string& filename, LLInitParam::BaseBlock& block, bool silent)
-{
- LLFastTimer timer(FTM_PARSE_XUI);
-
- mParser = XML_ParserCreate(NULL);
- XML_SetUserData(mParser, this);
- XML_SetElementHandler( mParser, startElementHandler, endElementHandler);
- XML_SetCharacterDataHandler( mParser, characterDataHandler);
-
- mOutputStack.push_back(std::make_pair(&block, 0));
- mNameStack.clear();
- mCurFileName = filename;
- mCurReadDepth = 0;
- setParseSilently(silent);
-
- ScopedFile file(filename, "rb");
- if( !file.isOpen() )
- {
- LL_WARNS("ReadXUI") << "Unable to open file " << filename << LL_ENDL;
- XML_ParserFree( mParser );
- return false;
- }
-
- S32 bytes_read = 0;
-
- S32 buffer_size = file.getRemainingBytes();
- void* buffer = XML_GetBuffer(mParser, buffer_size);
- if( !buffer )
- {
- LL_WARNS("ReadXUI") << "Unable to allocate XML buffer while reading file " << filename << LL_ENDL;
- XML_ParserFree( mParser );
- return false;
- }
-
- bytes_read = (S32)fread(buffer, 1, buffer_size, file.mFile);
- if( bytes_read <= 0 )
- {
- LL_WARNS("ReadXUI") << "Error while reading file " << filename << LL_ENDL;
- XML_ParserFree( mParser );
- return false;
- }
-
- mEmptyLeafNode.push_back(false);
-
- if( !XML_ParseBuffer(mParser, bytes_read, TRUE ) )
- {
- LL_WARNS("ReadXUI") << "Error while parsing file " << filename << LL_ENDL;
- XML_ParserFree( mParser );
- return false;
- }
-
- mEmptyLeafNode.pop_back();
-
- XML_ParserFree( mParser );
- return true;
-}
-
-void LLSimpleXUIParser::startElementHandler(void *userData, const char *name, const char **atts)
-{
- LLSimpleXUIParser* self = reinterpret_cast<LLSimpleXUIParser*>(userData);
- self->startElement(name, atts);
-}
-
-void LLSimpleXUIParser::endElementHandler(void *userData, const char *name)
-{
- LLSimpleXUIParser* self = reinterpret_cast<LLSimpleXUIParser*>(userData);
- self->endElement(name);
-}
-
-void LLSimpleXUIParser::characterDataHandler(void *userData, const char *s, int len)
-{
- LLSimpleXUIParser* self = reinterpret_cast<LLSimpleXUIParser*>(userData);
- self->characterData(s, len);
-}
-
-void LLSimpleXUIParser::characterData(const char *s, int len)
-{
- mTextContents += std::string(s, len);
-}
-
-void LLSimpleXUIParser::startElement(const char *name, const char **atts)
-{
- processText();
-
- typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
- boost::char_separator<char> sep(".");
-
- if (mElementCB)
- {
- LLInitParam::BaseBlock* blockp = mElementCB(*this, name);
- if (blockp)
- {
- mOutputStack.push_back(std::make_pair(blockp, 0));
- }
- }
-
- mOutputStack.back().second++;
- S32 num_tokens_pushed = 0;
- std::string child_name(name);
-
- if (mOutputStack.back().second == 1)
- { // root node for this block
- mScope.push_back(child_name);
- }
- else
- { // compound attribute
- if (child_name.find(".") == std::string::npos)
- {
- mNameStack.push_back(std::make_pair(child_name, true));
- num_tokens_pushed++;
- mScope.push_back(child_name);
- }
- else
- {
- // parse out "dotted" name into individual tokens
- tokenizer name_tokens(child_name, sep);
-
- tokenizer::iterator name_token_it = name_tokens.begin();
- if(name_token_it == name_tokens.end())
- {
- return;
- }
-
- // check for proper nesting
- if(!mScope.empty() && *name_token_it != mScope.back())
- {
- return;
- }
-
- // now ignore first token
- ++name_token_it;
-
- // copy remaining tokens on to our running token list
- for(tokenizer::iterator token_to_push = name_token_it; token_to_push != name_tokens.end(); ++token_to_push)
- {
- mNameStack.push_back(std::make_pair(*token_to_push, true));
- num_tokens_pushed++;
- }
- mScope.push_back(mNameStack.back().first);
- }
- }
-
- // parent node is not empty
- mEmptyLeafNode.back() = false;
- // we are empty if we have no attributes
- mEmptyLeafNode.push_back(atts[0] == NULL);
-
- mTokenSizeStack.push_back(num_tokens_pushed);
- readAttributes(atts);
-
-}
-
-void LLSimpleXUIParser::endElement(const char *name)
-{
- bool has_text = processText();
-
- // no text, attributes, or children
- if (!has_text && mEmptyLeafNode.back())
- {
- // submit this as a valueless name (even though there might be text contents we haven't seen yet)
- mCurAttributeValueBegin = NO_VALUE_MARKER;
- mOutputStack.back().first->submitValue(mNameStack, *this, mParseSilently);
- }
-
- if (--mOutputStack.back().second == 0)
- {
- if (mOutputStack.empty())
- {
- LL_ERRS("ReadXUI") << "Parameter block output stack popped while empty." << LL_ENDL;
- }
- mOutputStack.pop_back();
- }
-
- S32 num_tokens_to_pop = mTokenSizeStack.back();
- mTokenSizeStack.pop_back();
- while(num_tokens_to_pop-- > 0)
- {
- mNameStack.pop_back();
- }
- mScope.pop_back();
- mEmptyLeafNode.pop_back();
-}
-
-bool LLSimpleXUIParser::readAttributes(const char **atts)
-{
- typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
- boost::char_separator<char> sep(".");
-
- bool any_parsed = false;
- for(S32 i = 0; atts[i] && atts[i+1]; i += 2 )
- {
- std::string attribute_name(atts[i]);
- mCurAttributeValueBegin = atts[i+1];
-
- S32 num_tokens_pushed = 0;
- tokenizer name_tokens(attribute_name, sep);
- // copy remaining tokens on to our running token list
- for(tokenizer::iterator token_to_push = name_tokens.begin(); token_to_push != name_tokens.end(); ++token_to_push)
- {
- mNameStack.push_back(std::make_pair(*token_to_push, true));
- num_tokens_pushed++;
- }
-
- // child nodes are not necessarily valid attributes, so don't complain once we've recursed
- any_parsed |= mOutputStack.back().first->submitValue(mNameStack, *this, mParseSilently);
-
- while(num_tokens_pushed-- > 0)
- {
- mNameStack.pop_back();
- }
- }
- return any_parsed;
-}
-
-bool LLSimpleXUIParser::processText()
-{
- if (!mTextContents.empty())
- {
- LLStringUtil::trim(mTextContents);
- if (!mTextContents.empty())
- {
- mNameStack.push_back(std::make_pair(std::string("value"), true));
- mCurAttributeValueBegin = mTextContents.c_str();
- mOutputStack.back().first->submitValue(mNameStack, *this, mParseSilently);
- mNameStack.pop_back();
- }
- mTextContents.clear();
- return true;
- }
- return false;
-}
-
-/*virtual*/ std::string LLSimpleXUIParser::getCurrentElementName()
-{
- std::string full_name;
- for (name_stack_t::iterator it = mNameStack.begin();
- it != mNameStack.end();
- ++it)
- {
- full_name += it->first + "."; // build up dotted names: "button.param.nestedparam."
- }
-
- return full_name;
-}
-
-void LLSimpleXUIParser::parserWarning(const std::string& message)
-{
-#ifdef LL_WINDOWS
- // use Visual Studo friendly formatting of output message for easy access to originating xml
- llutf16string utf16str = utf8str_to_utf16str(llformat("%s(%d):\t%s", mCurFileName.c_str(), LINE_NUMBER_HERE, message.c_str()).c_str());
- utf16str += '\n';
- OutputDebugString(utf16str.c_str());
-#else
- Parser::parserWarning(message);
-#endif
-}
-
-void LLSimpleXUIParser::parserError(const std::string& message)
-{
-#ifdef LL_WINDOWS
- llutf16string utf16str = utf8str_to_utf16str(llformat("%s(%d):\t%s", mCurFileName.c_str(), LINE_NUMBER_HERE, message.c_str()).c_str());
- utf16str += '\n';
- OutputDebugString(utf16str.c_str());
-#else
- Parser::parserError(message);
-#endif
-}
-
-bool LLSimpleXUIParser::readFlag(Parser& parser, void* val_ptr)
-{
- LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser);
- return self.mCurAttributeValueBegin == NO_VALUE_MARKER;
-}
-
-bool LLSimpleXUIParser::readBoolValue(Parser& parser, void* val_ptr)
-{
- LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser);
- if (!strcmp(self.mCurAttributeValueBegin, "true"))
- {
- *((bool*)val_ptr) = true;
- return true;
- }
- else if (!strcmp(self.mCurAttributeValueBegin, "false"))
- {
- *((bool*)val_ptr) = false;
- return true;
- }
-
- return false;
-}
-
-bool LLSimpleXUIParser::readStringValue(Parser& parser, void* val_ptr)
-{
- LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser);
- *((std::string*)val_ptr) = self.mCurAttributeValueBegin;
- return true;
-}
-
-bool LLSimpleXUIParser::readU8Value(Parser& parser, void* val_ptr)
-{
- LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser);
- return parse(self.mCurAttributeValueBegin, uint_p[assign_a(*(U8*)val_ptr)]).full;
-}
-
-bool LLSimpleXUIParser::readS8Value(Parser& parser, void* val_ptr)
-{
- LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser);
- return parse(self.mCurAttributeValueBegin, int_p[assign_a(*(S8*)val_ptr)]).full;
-}
-
-bool LLSimpleXUIParser::readU16Value(Parser& parser, void* val_ptr)
-{
- LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser);
- return parse(self.mCurAttributeValueBegin, uint_p[assign_a(*(U16*)val_ptr)]).full;
-}
-
-bool LLSimpleXUIParser::readS16Value(Parser& parser, void* val_ptr)
-{
- LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser);
- return parse(self.mCurAttributeValueBegin, int_p[assign_a(*(S16*)val_ptr)]).full;
-}
-
-bool LLSimpleXUIParser::readU32Value(Parser& parser, void* val_ptr)
-{
- LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser);
- return parse(self.mCurAttributeValueBegin, uint_p[assign_a(*(U32*)val_ptr)]).full;
-}
-
-bool LLSimpleXUIParser::readS32Value(Parser& parser, void* val_ptr)
-{
- LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser);
- return parse(self.mCurAttributeValueBegin, int_p[assign_a(*(S32*)val_ptr)]).full;
-}
-
-bool LLSimpleXUIParser::readF32Value(Parser& parser, void* val_ptr)
-{
- LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser);
- return parse(self.mCurAttributeValueBegin, real_p[assign_a(*(F32*)val_ptr)]).full;
-}
-
-bool LLSimpleXUIParser::readF64Value(Parser& parser, void* val_ptr)
-{
- LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser);
- return parse(self.mCurAttributeValueBegin, real_p[assign_a(*(F64*)val_ptr)]).full;
-}
-
-bool LLSimpleXUIParser::readColor4Value(Parser& parser, void* val_ptr)
-{
- LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser);
- LLColor4 value;
-
- if (parse(self.mCurAttributeValueBegin, real_p[assign_a(value.mV[0])] >> real_p[assign_a(value.mV[1])] >> real_p[assign_a(value.mV[2])] >> real_p[assign_a(value.mV[3])], space_p).full)
- {
- *(LLColor4*)(val_ptr) = value;
- return true;
- }
- return false;
-}
-
-bool LLSimpleXUIParser::readUIColorValue(Parser& parser, void* val_ptr)
-{
- LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser);
- LLColor4 value;
- LLUIColor* colorp = (LLUIColor*)val_ptr;
-
- if (parse(self.mCurAttributeValueBegin, real_p[assign_a(value.mV[0])] >> real_p[assign_a(value.mV[1])] >> real_p[assign_a(value.mV[2])] >> real_p[assign_a(value.mV[3])], space_p).full)
- {
- colorp->set(value);
- return true;
- }
- return false;
-}
-
-bool LLSimpleXUIParser::readUUIDValue(Parser& parser, void* val_ptr)
-{
- LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser);
- LLUUID temp_id;
- // LLUUID::set is destructive, so use temporary value
- if (temp_id.set(std::string(self.mCurAttributeValueBegin)))
- {
- *(LLUUID*)(val_ptr) = temp_id;
- return true;
- }
- return false;
-}
-
-bool LLSimpleXUIParser::readSDValue(Parser& parser, void* val_ptr)
-{
- LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser);
- *((LLSD*)val_ptr) = LLSD(self.mCurAttributeValueBegin);
- return true;
-}
diff --git a/indra/llxuixml/llxuiparser.h b/indra/llxuixml/llxuiparser.h
deleted file mode 100644
index d7cd256967..0000000000
--- a/indra/llxuixml/llxuiparser.h
+++ /dev/null
@@ -1,242 +0,0 @@
-/**
- * @file llxuiparser.h
- * @brief Utility functions for handling XUI structures in XML
- *
- * $LicenseInfo:firstyear=2003&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$
- */
-
-#ifndef LLXUIPARSER_H
-#define LLXUIPARSER_H
-
-#include "llinitparam.h"
-#include "llregistry.h"
-#include "llpointer.h"
-
-#include <boost/function.hpp>
-#include <iosfwd>
-#include <stack>
-#include <set>
-
-
-
-class LLView;
-
-
-typedef LLPointer<class LLXMLNode> LLXMLNodePtr;
-
-
-// lookup widget type by name
-class LLWidgetTypeRegistry
-: public LLRegistrySingleton<std::string, const std::type_info*, LLWidgetTypeRegistry>
-{};
-
-
-// global static instance for registering all widget types
-typedef boost::function<LLView* (LLXMLNodePtr node, LLView *parent, LLXMLNodePtr output_node)> LLWidgetCreatorFunc;
-
-typedef LLRegistry<std::string, LLWidgetCreatorFunc> widget_registry_t;
-
-class LLChildRegistryRegistry
-: public LLRegistrySingleton<const std::type_info*, widget_registry_t, LLChildRegistryRegistry>
-{};
-
-
-
-class LLXSDWriter : public LLInitParam::Parser
-{
- LOG_CLASS(LLXSDWriter);
-public:
- void writeXSD(const std::string& name, LLXMLNodePtr node, const LLInitParam::BaseBlock& block, const std::string& xml_namespace);
-
- /*virtual*/ std::string getCurrentElementName() { return LLStringUtil::null; }
-
- LLXSDWriter();
-
-protected:
- void writeAttribute(const std::string& type, const Parser::name_stack_t&, S32 min_count, S32 max_count, const std::vector<std::string>* possible_values);
- void addAttributeToSchema(LLXMLNodePtr nodep, const std::string& attribute_name, const std::string& type, bool mandatory, const std::vector<std::string>* possible_values);
- LLXMLNodePtr mAttributeNode;
- LLXMLNodePtr mElementNode;
- LLXMLNodePtr mSchemaNode;
-
- typedef std::set<std::string> string_set_t;
- typedef std::map<LLXMLNodePtr, string_set_t> attributes_map_t;
- attributes_map_t mAttributesWritten;
-};
-
-
-
-// NOTE: DOES NOT WORK YET
-// should support child widgets for XUI
-class LLXUIXSDWriter : public LLXSDWriter
-{
-public:
- void writeXSD(const std::string& name, const std::string& path, const LLInitParam::BaseBlock& block);
-};
-
-
-class LLXUIParserImpl;
-
-class LLXUIParser : public LLInitParam::Parser
-{
-LOG_CLASS(LLXUIParser);
-
-public:
- LLXUIParser();
- typedef LLInitParam::Parser::name_stack_t name_stack_t;
-
- /*virtual*/ std::string getCurrentElementName();
- /*virtual*/ void parserWarning(const std::string& message);
- /*virtual*/ void parserError(const std::string& message);
-
- void readXUI(LLXMLNodePtr node, LLInitParam::BaseBlock& block, const std::string& filename = LLStringUtil::null, bool silent=false);
- void writeXUI(LLXMLNodePtr node, const LLInitParam::BaseBlock& block, const LLInitParam::BaseBlock* diff_block = NULL);
-
-private:
- bool readXUIImpl(LLXMLNodePtr node, LLInitParam::BaseBlock& block);
- bool readAttributes(LLXMLNodePtr nodep, LLInitParam::BaseBlock& block);
-
- //reader helper functions
- static bool readFlag(Parser& parser, void* val_ptr);
- static bool readBoolValue(Parser& parser, void* val_ptr);
- static bool readStringValue(Parser& parser, void* val_ptr);
- static bool readU8Value(Parser& parser, void* val_ptr);
- static bool readS8Value(Parser& parser, void* val_ptr);
- static bool readU16Value(Parser& parser, void* val_ptr);
- static bool readS16Value(Parser& parser, void* val_ptr);
- static bool readU32Value(Parser& parser, void* val_ptr);
- static bool readS32Value(Parser& parser, void* val_ptr);
- static bool readF32Value(Parser& parser, void* val_ptr);
- static bool readF64Value(Parser& parser, void* val_ptr);
- static bool readColor4Value(Parser& parser, void* val_ptr);
- static bool readUIColorValue(Parser& parser, void* val_ptr);
- static bool readUUIDValue(Parser& parser, void* val_ptr);
- static bool readSDValue(Parser& parser, void* val_ptr);
-
- //writer helper functions
- static bool writeFlag(Parser& parser, const void* val_ptr, name_stack_t&);
- static bool writeBoolValue(Parser& parser, const void* val_ptr, name_stack_t&);
- static bool writeStringValue(Parser& parser, const void* val_ptr, name_stack_t&);
- static bool writeU8Value(Parser& parser, const void* val_ptr, name_stack_t&);
- static bool writeS8Value(Parser& parser, const void* val_ptr, name_stack_t&);
- static bool writeU16Value(Parser& parser, const void* val_ptr, name_stack_t&);
- static bool writeS16Value(Parser& parser, const void* val_ptr, name_stack_t&);
- static bool writeU32Value(Parser& parser, const void* val_ptr, name_stack_t&);
- static bool writeS32Value(Parser& parser, const void* val_ptr, name_stack_t&);
- static bool writeF32Value(Parser& parser, const void* val_ptr, name_stack_t&);
- static bool writeF64Value(Parser& parser, const void* val_ptr, name_stack_t&);
- static bool writeColor4Value(Parser& parser, const void* val_ptr, name_stack_t&);
- static bool writeUIColorValue(Parser& parser, const void* val_ptr, name_stack_t&);
- static bool writeUUIDValue(Parser& parser, const void* val_ptr, name_stack_t&);
- static bool writeSDValue(Parser& parser, const void* val_ptr, name_stack_t&);
-
- LLXMLNodePtr getNode(name_stack_t& stack);
-
-private:
- Parser::name_stack_t mNameStack;
- LLXMLNodePtr mCurReadNode;
- // Root of the widget XML sub-tree, for example, "line_editor"
- LLXMLNodePtr mWriteRootNode;
-
- typedef std::map<std::string, LLXMLNodePtr> out_nodes_t;
- out_nodes_t mOutNodes;
- LLXMLNodePtr mLastWrittenChild;
- S32 mCurReadDepth;
- std::string mCurFileName;
- std::string mRootNodeName;
-};
-
-// LLSimpleXUIParser is a streamlined SAX-based XUI parser that does not support localization
-// or parsing of a tree of independent param blocks, such as child widgets.
-// Use this for reading non-localized files that only need a single param block as a result.
-//
-// NOTE: In order to support nested block parsing, we need callbacks for start element that
-// push new blocks contexts on the mScope stack.
-// NOTE: To support localization without building a DOM, we need to enforce consistent
-// ordering of child elements from base file to localized diff file. Then we can use a pair
-// of coroutines to perform matching of xml nodes during parsing. Not sure if the overhead
-// of coroutines would offset the gain from SAX parsing
-class LLSimpleXUIParserImpl;
-
-class LLSimpleXUIParser : public LLInitParam::Parser
-{
-LOG_CLASS(LLSimpleXUIParser);
-public:
- typedef LLInitParam::Parser::name_stack_t name_stack_t;
- typedef LLInitParam::BaseBlock* (*element_start_callback_t)(LLSimpleXUIParser&, const char* block_name);
-
- LLSimpleXUIParser(element_start_callback_t element_cb = NULL);
- virtual ~LLSimpleXUIParser();
-
- /*virtual*/ std::string getCurrentElementName();
- /*virtual*/ void parserWarning(const std::string& message);
- /*virtual*/ void parserError(const std::string& message);
-
- bool readXUI(const std::string& filename, LLInitParam::BaseBlock& block, bool silent=false);
-
-
-private:
- //reader helper functions
- static bool readFlag(Parser&, void* val_ptr);
- static bool readBoolValue(Parser&, void* val_ptr);
- static bool readStringValue(Parser&, void* val_ptr);
- static bool readU8Value(Parser&, void* val_ptr);
- static bool readS8Value(Parser&, void* val_ptr);
- static bool readU16Value(Parser&, void* val_ptr);
- static bool readS16Value(Parser&, void* val_ptr);
- static bool readU32Value(Parser&, void* val_ptr);
- static bool readS32Value(Parser&, void* val_ptr);
- static bool readF32Value(Parser&, void* val_ptr);
- static bool readF64Value(Parser&, void* val_ptr);
- static bool readColor4Value(Parser&, void* val_ptr);
- static bool readUIColorValue(Parser&, void* val_ptr);
- static bool readUUIDValue(Parser&, void* val_ptr);
- static bool readSDValue(Parser&, void* val_ptr);
-
-private:
- static void startElementHandler(void *userData, const char *name, const char **atts);
- static void endElementHandler(void *userData, const char *name);
- static void characterDataHandler(void *userData, const char *s, int len);
-
- void startElement(const char *name, const char **atts);
- void endElement(const char *name);
- void characterData(const char *s, int len);
- bool readAttributes(const char **atts);
- bool processText();
-
- Parser::name_stack_t mNameStack;
- struct XML_ParserStruct* mParser;
- LLXMLNodePtr mLastWrittenChild;
- S32 mCurReadDepth;
- std::string mCurFileName;
- std::string mTextContents;
- const char* mCurAttributeValueBegin;
- std::vector<S32> mTokenSizeStack;
- std::vector<std::string> mScope;
- std::vector<bool> mEmptyLeafNode;
- element_start_callback_t mElementCB;
-
- std::vector<std::pair<LLInitParam::BaseBlock*, S32> > mOutputStack;
-};
-
-
-#endif //LLXUIPARSER_H
diff --git a/indra/lscript/CMakeLists.txt b/indra/lscript/CMakeLists.txt
index 937e2ec0dc..937e2ec0dc 100644..100755
--- a/indra/lscript/CMakeLists.txt
+++ b/indra/lscript/CMakeLists.txt
diff --git a/indra/lscript/llscriptresource.h b/indra/lscript/llscriptresource.h
index 9dab9ff7ce..9dab9ff7ce 100644..100755
--- a/indra/lscript/llscriptresource.h
+++ b/indra/lscript/llscriptresource.h
diff --git a/indra/lscript/llscriptresourceconsumer.h b/indra/lscript/llscriptresourceconsumer.h
index 82a490d28f..82a490d28f 100644..100755
--- a/indra/lscript/llscriptresourceconsumer.h
+++ b/indra/lscript/llscriptresourceconsumer.h
diff --git a/indra/lscript/llscriptresourcepool.h b/indra/lscript/llscriptresourcepool.h
index 4ea2556e0f..4ea2556e0f 100644..100755
--- a/indra/lscript/llscriptresourcepool.h
+++ b/indra/lscript/llscriptresourcepool.h
diff --git a/indra/lscript/lscript_alloc.h b/indra/lscript/lscript_alloc.h
index f8a4e298d2..f8a4e298d2 100644..100755
--- a/indra/lscript/lscript_alloc.h
+++ b/indra/lscript/lscript_alloc.h
diff --git a/indra/lscript/lscript_byteconvert.h b/indra/lscript/lscript_byteconvert.h
index 5b08481d7d..5b08481d7d 100644..100755
--- a/indra/lscript/lscript_byteconvert.h
+++ b/indra/lscript/lscript_byteconvert.h
diff --git a/indra/lscript/lscript_byteformat.h b/indra/lscript/lscript_byteformat.h
index a294def734..54031aaf05 100644..100755
--- a/indra/lscript/lscript_byteformat.h
+++ b/indra/lscript/lscript_byteformat.h
@@ -530,6 +530,10 @@ typedef enum e_lscript_runtime_permissions
SCRIPT_PERMISSION_TRACK_CAMERA,
SCRIPT_PERMISSION_CONTROL_CAMERA,
SCRIPT_PERMISSION_TELEPORT,
+ SCRIPT_PERMISSION_EXPERIENCE,
+ SCRIPT_PERMISSION_SILENT_ESTATE_MANAGEMENT,
+ SCRIPT_PERMISSION_OVERRIDE_ANIMATIONS,
+ SCRIPT_PERMISSION_RETURN_OBJECTS,
SCRIPT_PERMISSION_EOF
} LSCRIPTRunTimePermissions;
@@ -547,6 +551,10 @@ const U32 LSCRIPTRunTimePermissionBits[SCRIPT_PERMISSION_EOF] =
(0x1 << 10),// SCRIPT_PERMISSION_TRACK_CAMERA
(0x1 << 11),// SCRIPT_PERMISSION_CONTROL_CAMERA
(0x1 << 12),// SCRIPT_PERMISSION_TELEPORT
+ (0x1 << 13),// SCRIPT_PERMISSION_EXPERIENCE,
+ (0x1 << 14),// SCRIPT_PERMISSION_SILENT_ESTATE_MANAGEMENT,
+ (0x1 << 15),// SCRIPT_PERMISSION_OVERRIDE_ANIMATIONS,
+ (0x1 << 16),// SCRIPT_PERMISSION_RETURN_OBJECTS,
};
// http_request string constants
diff --git a/indra/lscript/lscript_compile/CMakeLists.txt b/indra/lscript/lscript_compile/CMakeLists.txt
index 3ed2892e0e..07662005b9 100644..100755
--- a/indra/lscript/lscript_compile/CMakeLists.txt
+++ b/indra/lscript/lscript_compile/CMakeLists.txt
@@ -45,6 +45,9 @@ include_directories(
${LLPRIMITIVE_INCLUDE_DIRS}
${LSCRIPT_INCLUDE_DIRS}
)
+include_directories(SYSTEM
+ ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+ )
set(lscript_generated_SOURCE_FILES
indra.l.cpp
@@ -95,6 +98,7 @@ add_custom_command(
${CMAKE_CURRENT_BINARY_DIR}/indra.l.cpp
COMMAND ${FLEX}
ARGS
+ -P indra_
-o${CMAKE_CURRENT_BINARY_DIR}/indra.l.cpp
${CMAKE_CURRENT_SOURCE_DIR}/indra.l
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/indra.l
@@ -112,8 +116,10 @@ if (WINDOWS)
${CMAKE_CURRENT_BINARY_DIR}/indra.y.cpp
${CMAKE_CURRENT_BINARY_DIR}/indra.y.hpp
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/bison.bat
+ ARGS
${BISON} ${M4_PATH}
- ${CMAKE_CURRENT_BINARY_DIR}/indra.y.cpp
+ -p indra_
+ -d -o ${CMAKE_CURRENT_BINARY_DIR}/indra.y.cpp
${CMAKE_CURRENT_SOURCE_DIR}/indra.y
DEPENDS
${CMAKE_CURRENT_SOURCE_DIR}/bison.bat
@@ -128,6 +134,7 @@ else (WINDOWS)
COMMAND
${BISON}
ARGS
+ -p indra_
-d -o ${CMAKE_CURRENT_BINARY_DIR}/indra.y.cpp
${CMAKE_CURRENT_SOURCE_DIR}/indra.y
DEPENDS
diff --git a/indra/lscript/lscript_compile/bison.bat b/indra/lscript/lscript_compile/bison.bat
index 0baff4e5ef..d40997225e 100644
--- a/indra/lscript/lscript_compile/bison.bat
+++ b/indra/lscript/lscript_compile/bison.bat
@@ -2,10 +2,11 @@
@REM find m4, even if neither program is present in PATH.
@set bison=%1
-set M4PATH=%2
+shift
+set M4PATH=%1
+shift
set M4=
-@set output=%3
-@set input=%4
set PATH=%M4PATH%;%PATH%
-%bison% -d -o %output% %input%
+@REM %* does not work with shift...
+%bison% %1 %2 %3 %4 %5 %6 %7 %8 %9
diff --git a/indra/lscript/lscript_compile/indra.l b/indra/lscript/lscript_compile/indra.l
index 96b7e57e97..88dfc2e9f3 100644..100755
--- a/indra/lscript/lscript_compile/indra.l
+++ b/indra/lscript/lscript_compile/indra.l
@@ -56,11 +56,32 @@ void parse_string();
#define ECHO do { } while (0)
-#if defined(__cplusplus)
-extern "C" { int yylex( void ); }
-extern "C" { int yyparse( void ); }
-extern "C" { int yyerror(const char *fmt, ...); }
-#endif
+#define yyparse indra_parse
+#define yyerror indra_error
+#define yylval indra_lval
+#define yy_create_buffer indra__create_buffer
+#define yy_delete_buffer indra__delete_buffer
+#define yy_flex_debug indra__flex_debug
+#define yy_init_buffer indra__init_buffer
+#define yy_flush_buffer indra__flush_buffer
+#define yy_load_buffer_state indra__load_buffer_state
+#define yy_switch_to_buffer indra__switch_to_buffer
+#define yyin indra_in
+#define yyleng indra_leng
+#define yylex indra_lex
+#define yylineno indra_lineno
+#define yyout indra_out
+#define yyrestart indra_restart
+#define yytext indra_text
+#define yywrap indra_wrap
+#define yyalloc indra_alloc
+#define yyrealloc indra_realloc
+#define yyfree indra_free
+
+
+int yyparse( void );
+int yylex( void );
+int yyerror(const char *fmt, ...);
%}
@@ -140,6 +161,7 @@ extern "C" { int yyerror(const char *fmt, ...); }
"STATUS_DIE_AT_EDGE" { count(); yylval.ival = 0x80; return(INTEGER_CONSTANT); }
"STATUS_RETURN_AT_EDGE" { count(); yylval.ival = 0x100; return(INTEGER_CONSTANT); }
"STATUS_CAST_SHADOWS" { count(); yylval.ival = 0x200; return(INTEGER_CONSTANT); }
+"STATUS_BLOCK_GRAB_OBJECT" { count(); yylval.ival = 0x400; return(INTEGER_CONSTANT); }
"AGENT_FLYING" { count(); yylval.ival = AGENT_FLYING; return(INTEGER_CONSTANT); }
"AGENT_ATTACHMENTS" { count(); yylval.ival = AGENT_ATTACHMENTS; return(INTEGER_CONSTANT); }
@@ -214,6 +236,8 @@ extern "C" { int yyerror(const char *fmt, ...); }
"PERMISSION_TRACK_CAMERA" { count(); yylval.ival = LSCRIPTRunTimePermissionBits[SCRIPT_PERMISSION_TRACK_CAMERA]; return(INTEGER_CONSTANT); }
"PERMISSION_CONTROL_CAMERA" { count(); yylval.ival = LSCRIPTRunTimePermissionBits[SCRIPT_PERMISSION_CONTROL_CAMERA]; return(INTEGER_CONSTANT); }
"PERMISSION_TELEPORT" { count(); yylval.ival = LSCRIPTRunTimePermissionBits[SCRIPT_PERMISSION_TELEPORT]; return(INTEGER_CONSTANT); }
+"PERMISSION_SILENT_ESTATE_MANAGEMENT" { count(); yylval.ival = LSCRIPTRunTimePermissionBits[SCRIPT_PERMISSION_SILENT_ESTATE_MANAGEMENT]; return(INTEGER_CONSTANT); }
+"PERMISSION_OVERRIDE_ANIMATIONS" { count(); yylval.ival = LSCRIPTRunTimePermissionBits[SCRIPT_PERMISSION_OVERRIDE_ANIMATIONS]; return(INTEGER_CONSTANT); }
"INVENTORY_TEXTURE" { count(); yylval.ival = LLAssetType::AT_TEXTURE; return(INTEGER_CONSTANT); }
"INVENTORY_SOUND" { count(); yylval.ival = LLAssetType::AT_SOUND; return(INTEGER_CONSTANT); }
@@ -250,6 +274,22 @@ extern "C" { int yyerror(const char *fmt, ...); }
"OBJECT_OWNER" { count(); yylval.ival = OBJECT_OWNER; return(INTEGER_CONSTANT); }
"OBJECT_GROUP" { count(); yylval.ival = OBJECT_GROUP; return(INTEGER_CONSTANT); }
"OBJECT_CREATOR" { count(); yylval.ival = OBJECT_CREATOR; return(INTEGER_CONSTANT); }
+"OBJECT_RUNNING_SCRIPT_COUNT" { count(); yylval.ival = OBJECT_RUNNING_SCRIPT_COUNT; return(INTEGER_CONSTANT); }
+"OBJECT_TOTAL_SCRIPT_COUNT" { count(); yylval.ival = OBJECT_TOTAL_SCRIPT_COUNT; return(INTEGER_CONSTANT); }
+"OBJECT_SCRIPT_MEMORY" { count(); yylval.ival = OBJECT_SCRIPT_MEMORY; return(INTEGER_CONSTANT); }
+"OBJECT_SCRIPT_TIME" { count(); yylval.ival = OBJECT_SCRIPT_TIME; return(INTEGER_CONSTANT); }
+"OBJECT_PRIM_EQUIVALENCE" { count(); yylval.ival = OBJECT_PRIM_EQUIVALENCE; return(INTEGER_CONSTANT); }
+"OBJECT_SERVER_COST" { count(); yylval.ival = OBJECT_SERVER_COST; return(INTEGER_CONSTANT); }
+"OBJECT_STREAMING_COST" { count(); yylval.ival = OBJECT_STREAMING_COST; return(INTEGER_CONSTANT); }
+"OBJECT_PHYSICS_COST" { count(); yylval.ival = OBJECT_PHYSICS_COST; return(INTEGER_CONSTANT); }
+"OBJECT_CHARACTER_TIME" { count(); yylval.ival = OBJECT_CHARACTER_TIME; return(INTEGER_CONSTANT); }
+"OBJECT_ROOT" { count(); yylval.ival = OBJECT_ROOT; return(INTEGER_CONSTANT); }
+"OBJECT_ATTACHED_POINT" { count(); yylval.ival = OBJECT_ATTACHED_POINT; return(INTEGER_CONSTANT); }
+"OBJECT_PATHFINDING_TYPE" { count(); yylval.ival = OBJECT_PATHFINDING_TYPE; return(INTEGER_CONSTANT); }
+"OBJECT_PHYSICS" { count(); yylval.ival = OBJECT_PHYSICS; return(INTEGER_CONSTANT); }
+"OBJECT_PHANTOM" { count(); yylval.ival = OBJECT_PHANTOM; return(INTEGER_CONSTANT); }
+"OBJECT_TEMP_ON_REZ" { count(); yylval.ival = OBJECT_TEMP_ON_REZ; return(INTEGER_CONSTANT); }
+"OBJECT_RENDER_WEIGHT" { count(); yylval.ival = OBJECT_RENDER_WEIGHT; return(INTEGER_CONSTANT); }
"TYPE_INTEGER" { count(); yylval.ival = LST_INTEGER; return(INTEGER_CONSTANT); }
"TYPE_FLOAT" { count(); yylval.ival = LST_FLOATINGPOINT; return(INTEGER_CONSTANT); }
@@ -315,6 +355,8 @@ extern "C" { int yyerror(const char *fmt, ...); }
"ATTACH_HUD_BOTTOM_LEFT" { count(); yylval.ival = 36; return(INTEGER_CONSTANT); }
"ATTACH_HUD_BOTTOM" { count(); yylval.ival = 37; return(INTEGER_CONSTANT); }
"ATTACH_HUD_BOTTOM_RIGHT" { count(); yylval.ival = 38; return(INTEGER_CONSTANT); }
+"ATTACH_NECK" { count(); yylval.ival = 39; return(INTEGER_CONSTANT); }
+"ATTACH_AVATAR_CENTER" { count(); yylval.ival = 40; return(INTEGER_CONSTANT); }
"LAND_LEVEL" { count(); yylval.ival = E_LANDBRUSH_LEVEL; return(INTEGER_CONSTANT); }
"LAND_RAISE" { count(); yylval.ival = E_LANDBRUSH_RAISE; return(INTEGER_CONSTANT); }
@@ -353,6 +395,10 @@ extern "C" { int yyerror(const char *fmt, ...); }
"PSYS_PART_END_SCALE" { count(); yylval.ival = LLPS_PART_END_SCALE; return (INTEGER_CONSTANT); }
"PSYS_PART_MAX_AGE" { count(); yylval.ival = LLPS_PART_MAX_AGE; return (INTEGER_CONSTANT); }
+"PSYS_PART_BLEND_FUNC_SOURCE" { count(); yylval.ival = LLPS_PART_BLEND_FUNC_SOURCE; return (INTEGER_CONSTANT); }
+"PSYS_PART_BLEND_FUNC_DEST" { count(); yylval.ival = LLPS_PART_BLEND_FUNC_DEST; return (INTEGER_CONSTANT); }
+"PSYS_PART_START_GLOW" { count(); yylval.ival = LLPS_PART_START_GLOW; return (INTEGER_CONSTANT); }
+"PSYS_PART_END_GLOW" { count(); yylval.ival = LLPS_PART_END_GLOW; return (INTEGER_CONSTANT); }
"PSYS_PART_WIND_MASK" { count(); yylval.ival = LLPartData::LL_PART_WIND_MASK; return(INTEGER_CONSTANT); }
"PSYS_PART_INTERP_COLOR_MASK" { count(); yylval.ival = LLPartData::LL_PART_INTERP_COLOR_MASK; return(INTEGER_CONSTANT); }
@@ -363,6 +409,16 @@ extern "C" { int yyerror(const char *fmt, ...); }
"PSYS_PART_TARGET_POS_MASK" { count(); yylval.ival = LLPartData::LL_PART_TARGET_POS_MASK; return(INTEGER_CONSTANT); }
"PSYS_PART_EMISSIVE_MASK" { count(); yylval.ival = LLPartData::LL_PART_EMISSIVE_MASK; return(INTEGER_CONSTANT); }
"PSYS_PART_TARGET_LINEAR_MASK" { count(); yylval.ival = LLPartData::LL_PART_TARGET_LINEAR_MASK; return(INTEGER_CONSTANT); }
+"PSYS_PART_RIBBON_MASK" { count(); yylval.ival = LLPartData::LL_PART_RIBBON_MASK; return(INTEGER_CONSTANT); }
+
+"PSYS_PART_BF_ONE" { count(); yylval.ival = LLPartData::LL_PART_BF_ONE; return(INTEGER_CONSTANT); }
+"PSYS_PART_BF_ZERO" { count(); yylval.ival = LLPartData::LL_PART_BF_ZERO; return(INTEGER_CONSTANT); }
+"PSYS_PART_BF_DEST_COLOR" { count(); yylval.ival = LLPartData::LL_PART_BF_DEST_COLOR; return(INTEGER_CONSTANT); }
+"PSYS_PART_BF_SOURCE_COLOR" { count(); yylval.ival = LLPartData::LL_PART_BF_SOURCE_COLOR; return(INTEGER_CONSTANT); }
+"PSYS_PART_BF_ONE_MINUS_DEST_COLOR" { count(); yylval.ival = LLPartData::LL_PART_BF_ONE_MINUS_DEST_COLOR; return(INTEGER_CONSTANT); }
+"PSYS_PART_BF_ONE_MINUS_SOURCE_COLOR" { count(); yylval.ival = LLPartData::LL_PART_BF_ONE_MINUS_SOURCE_COLOR; return(INTEGER_CONSTANT); }
+"PSYS_PART_BF_SOURCE_ALPHA" { count(); yylval.ival = LLPartData::LL_PART_BF_SOURCE_ALPHA; return(INTEGER_CONSTANT); }
+"PSYS_PART_BF_ONE_MINUS_SOURCE_ALPHA" { count(); yylval.ival = LLPartData::LL_PART_BF_ONE_MINUS_SOURCE_ALPHA; return(INTEGER_CONSTANT); }
"PSYS_SRC_MAX_AGE" { count(); yylval.ival = LLPS_SRC_MAX_AGE; return(INTEGER_CONSTANT); }
@@ -458,7 +514,17 @@ extern "C" { int yyerror(const char *fmt, ...); }
"PRIM_BUMP_SHINY" { count(); yylval.ival = LSL_PRIM_BUMP_SHINY; return(INTEGER_CONSTANT); }
"PRIM_FULLBRIGHT" { count(); yylval.ival = LSL_PRIM_FULLBRIGHT; return(INTEGER_CONSTANT); }
"PRIM_TEXGEN" { count(); yylval.ival = LSL_PRIM_TEXGEN; return(INTEGER_CONSTANT); }
-"PRIM_GLOW" { count(); yylval.ival = LSL_PRIM_GLOW; return(INTEGER_CONSTANT); }
+"PRIM_GLOW" { count(); yylval.ival = LSL_PRIM_GLOW; return(INTEGER_CONSTANT); }
+"PRIM_TEXT" { count(); yylval.ival = LSL_PRIM_TEXT; return(INTEGER_CONSTANT); }
+"PRIM_NAME" { count(); yylval.ival = LSL_PRIM_NAME; return(INTEGER_CONSTANT); }
+"PRIM_DESC" { count(); yylval.ival = LSL_PRIM_DESC; return(INTEGER_CONSTANT); }
+"PRIM_OMEGA" { count(); yylval.ival = LSL_PRIM_OMEGA; return(INTEGER_CONSTANT); }
+"PRIM_LINK_TARGET" { count(); yylval.ival = LSL_PRIM_LINK_TARGET; return(INTEGER_CONSTANT); }
+"PRIM_SLICE" { count(); yylval.ival = LSL_PRIM_SLICE; return(INTEGER_CONSTANT); }
+
+"PRIM_PHYSICS_SHAPE_PRIM" { count(); yylval.ival = LSL_PRIM_PHYSICS_SHAPE_PRIM; return(INTEGER_CONSTANT); }
+"PRIM_PHYSICS_SHAPE_NONE" { count(); yylval.ival = LSL_PRIM_PHYSICS_SHAPE_NONE; return(INTEGER_CONSTANT); }
+"PRIM_PHYSICS_SHAPE_CONVEX" { count(); yylval.ival = LSL_PRIM_PHYSICS_SHAPE_CONVEX; return(INTEGER_CONSTANT); }
"PRIM_TYPE_BOX" { count(); yylval.ival = LSL_PRIM_TYPE_BOX; return(INTEGER_CONSTANT); }
"PRIM_TYPE_CYLINDER" { count(); yylval.ival = LSL_PRIM_TYPE_CYLINDER; return(INTEGER_CONSTANT); }
diff --git a/indra/lscript/lscript_compile/indra.y b/indra/lscript/lscript_compile/indra.y
index e4b10ffdd9..a0a034d21c 100644..100755
--- a/indra/lscript/lscript_compile/indra.y
+++ b/indra/lscript/lscript_compile/indra.y
@@ -2,10 +2,6 @@
#include "linden_common.h"
#include "lscript_tree.h"
- #ifdef __cplusplus
- extern "C" {
- #endif
-
int yylex(void);
int yyparse( void );
int yyerror(const char *fmt, ...);
@@ -20,9 +16,6 @@
#pragma warning( disable : 4065 ) // warning: switch statement contains 'default' but no 'case' labels
#endif
- #ifdef __cplusplus
- }
- #endif
%}
%union
diff --git a/indra/lscript/lscript_compile/lscript_alloc.cpp b/indra/lscript/lscript_compile/lscript_alloc.cpp
index 5856a94e48..5856a94e48 100644..100755
--- a/indra/lscript/lscript_compile/lscript_alloc.cpp
+++ b/indra/lscript/lscript_compile/lscript_alloc.cpp
diff --git a/indra/lscript/lscript_compile/lscript_bytecode.cpp b/indra/lscript/lscript_compile/lscript_bytecode.cpp
index 95b2f35a94..95b2f35a94 100644..100755
--- a/indra/lscript/lscript_compile/lscript_bytecode.cpp
+++ b/indra/lscript/lscript_compile/lscript_bytecode.cpp
diff --git a/indra/lscript/lscript_compile/lscript_bytecode.h b/indra/lscript/lscript_compile/lscript_bytecode.h
index 0933c78b6f..0933c78b6f 100644..100755
--- a/indra/lscript/lscript_compile/lscript_bytecode.h
+++ b/indra/lscript/lscript_compile/lscript_bytecode.h
diff --git a/indra/lscript/lscript_compile/lscript_error.cpp b/indra/lscript/lscript_compile/lscript_error.cpp
index a574981555..a574981555 100644..100755
--- a/indra/lscript/lscript_compile/lscript_error.cpp
+++ b/indra/lscript/lscript_compile/lscript_error.cpp
diff --git a/indra/lscript/lscript_compile/lscript_error.h b/indra/lscript/lscript_compile/lscript_error.h
index 43fb968a40..43fb968a40 100644..100755
--- a/indra/lscript/lscript_compile/lscript_error.h
+++ b/indra/lscript/lscript_compile/lscript_error.h
diff --git a/indra/lscript/lscript_compile/lscript_heap.cpp b/indra/lscript/lscript_compile/lscript_heap.cpp
index 476c1ac5a6..476c1ac5a6 100644..100755
--- a/indra/lscript/lscript_compile/lscript_heap.cpp
+++ b/indra/lscript/lscript_compile/lscript_heap.cpp
diff --git a/indra/lscript/lscript_compile/lscript_heap.h b/indra/lscript/lscript_compile/lscript_heap.h
index 7762a367d6..7762a367d6 100644..100755
--- a/indra/lscript/lscript_compile/lscript_heap.h
+++ b/indra/lscript/lscript_compile/lscript_heap.h
diff --git a/indra/lscript/lscript_compile/lscript_resource.cpp b/indra/lscript/lscript_compile/lscript_resource.cpp
index 6cc3e3c5ee..6cc3e3c5ee 100644..100755
--- a/indra/lscript/lscript_compile/lscript_resource.cpp
+++ b/indra/lscript/lscript_compile/lscript_resource.cpp
diff --git a/indra/lscript/lscript_compile/lscript_resource.h b/indra/lscript/lscript_compile/lscript_resource.h
index 82cece0a85..82cece0a85 100644..100755
--- a/indra/lscript/lscript_compile/lscript_resource.h
+++ b/indra/lscript/lscript_compile/lscript_resource.h
diff --git a/indra/lscript/lscript_compile/lscript_scope.cpp b/indra/lscript/lscript_compile/lscript_scope.cpp
index e0fdf44d7a..e0fdf44d7a 100644..100755
--- a/indra/lscript/lscript_compile/lscript_scope.cpp
+++ b/indra/lscript/lscript_compile/lscript_scope.cpp
diff --git a/indra/lscript/lscript_compile/lscript_scope.h b/indra/lscript/lscript_compile/lscript_scope.h
index 5b2a73ad92..5b2a73ad92 100644..100755
--- a/indra/lscript/lscript_compile/lscript_scope.h
+++ b/indra/lscript/lscript_compile/lscript_scope.h
diff --git a/indra/lscript/lscript_compile/lscript_tree.cpp b/indra/lscript/lscript_compile/lscript_tree.cpp
index 8a70dd9ac1..8a70dd9ac1 100644..100755
--- a/indra/lscript/lscript_compile/lscript_tree.cpp
+++ b/indra/lscript/lscript_compile/lscript_tree.cpp
diff --git a/indra/lscript/lscript_compile/lscript_tree.h b/indra/lscript/lscript_compile/lscript_tree.h
index bf29f44518..bf29f44518 100644..100755
--- a/indra/lscript/lscript_compile/lscript_tree.h
+++ b/indra/lscript/lscript_compile/lscript_tree.h
diff --git a/indra/lscript/lscript_compile/lscript_typecheck.cpp b/indra/lscript/lscript_compile/lscript_typecheck.cpp
index c685621538..c685621538 100644..100755
--- a/indra/lscript/lscript_compile/lscript_typecheck.cpp
+++ b/indra/lscript/lscript_compile/lscript_typecheck.cpp
diff --git a/indra/lscript/lscript_compile/lscript_typecheck.h b/indra/lscript/lscript_compile/lscript_typecheck.h
index 74f723506f..74f723506f 100644..100755
--- a/indra/lscript/lscript_compile/lscript_typecheck.h
+++ b/indra/lscript/lscript_compile/lscript_typecheck.h
diff --git a/indra/lscript/lscript_compile/windows/unistd.h b/indra/lscript/lscript_compile/windows/unistd.h
index 0b7e2581e3..0b7e2581e3 100644..100755
--- a/indra/lscript/lscript_compile/windows/unistd.h
+++ b/indra/lscript/lscript_compile/windows/unistd.h
diff --git a/indra/lscript/lscript_execute.h b/indra/lscript/lscript_execute.h
index fc491ead0f..fc491ead0f 100644..100755
--- a/indra/lscript/lscript_execute.h
+++ b/indra/lscript/lscript_execute.h
diff --git a/indra/lscript/lscript_execute/CMakeLists.txt b/indra/lscript/lscript_execute/CMakeLists.txt
index 3a16ffdc01..49605982a8 100644..100755
--- a/indra/lscript/lscript_execute/CMakeLists.txt
+++ b/indra/lscript/lscript_execute/CMakeLists.txt
@@ -10,6 +10,9 @@ include_directories(
${LLMATH_INCLUDE_DIRS}
${LSCRIPT_INCLUDE_DIRS}
)
+include_directories(SYSTEM
+ ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+ )
set(lscript_execute_SOURCE_FILES
llscriptresource.cpp
diff --git a/indra/lscript/lscript_execute/llscriptresource.cpp b/indra/lscript/lscript_execute/llscriptresource.cpp
index 2c6811b226..2c6811b226 100644..100755
--- a/indra/lscript/lscript_execute/llscriptresource.cpp
+++ b/indra/lscript/lscript_execute/llscriptresource.cpp
diff --git a/indra/lscript/lscript_execute/llscriptresourceconsumer.cpp b/indra/lscript/lscript_execute/llscriptresourceconsumer.cpp
index 55d47b6de2..55d47b6de2 100644..100755
--- a/indra/lscript/lscript_execute/llscriptresourceconsumer.cpp
+++ b/indra/lscript/lscript_execute/llscriptresourceconsumer.cpp
diff --git a/indra/lscript/lscript_execute/llscriptresourcepool.cpp b/indra/lscript/lscript_execute/llscriptresourcepool.cpp
index 6bdc2bbd48..6bdc2bbd48 100644..100755
--- a/indra/lscript/lscript_execute/llscriptresourcepool.cpp
+++ b/indra/lscript/lscript_execute/llscriptresourcepool.cpp
diff --git a/indra/lscript/lscript_execute/lscript_execute.cpp b/indra/lscript/lscript_execute/lscript_execute.cpp
index d79e9f8bde..b12d2e4a16 100644..100755
--- a/indra/lscript/lscript_execute/lscript_execute.cpp
+++ b/indra/lscript/lscript_execute/lscript_execute.cpp
@@ -806,16 +806,7 @@ void LLScriptExecute::runInstructions(BOOL b_print, const LLUUID &id,
// is there a fault?
// if yes, print out message and exit
S32 value = getVersion();
- S32 major_version = 0;
- if (value == LSL2_VERSION1_END_NUMBER)
- {
- major_version = 1;
- }
- else if (value == LSL2_VERSION_NUMBER)
- {
- major_version = 2;
- }
- else
+ if ( (value != LSL2_VERSION1_END_NUMBER) && (value != LSL2_VERSION_NUMBER) )
{
setFault(LSRF_VERSION_MISMATCH);
}
diff --git a/indra/lscript/lscript_execute/lscript_heapruntime.cpp b/indra/lscript/lscript_execute/lscript_heapruntime.cpp
index 749857753d..749857753d 100644..100755
--- a/indra/lscript/lscript_execute/lscript_heapruntime.cpp
+++ b/indra/lscript/lscript_execute/lscript_heapruntime.cpp
diff --git a/indra/lscript/lscript_execute/lscript_heapruntime.h b/indra/lscript/lscript_execute/lscript_heapruntime.h
index 0e924a2036..0e924a2036 100644..100755
--- a/indra/lscript/lscript_execute/lscript_heapruntime.h
+++ b/indra/lscript/lscript_execute/lscript_heapruntime.h
diff --git a/indra/lscript/lscript_execute/lscript_readlso.cpp b/indra/lscript/lscript_execute/lscript_readlso.cpp
index 35caa41ae1..6384a57100 100644..100755
--- a/indra/lscript/lscript_execute/lscript_readlso.cpp
+++ b/indra/lscript/lscript_execute/lscript_readlso.cpp
@@ -123,7 +123,7 @@ void LLScriptLSOParse::printRegisters(LLFILE *fp)
void LLScriptLSOParse::printGlobals(LLFILE *fp)
{
// print out registers first
- S32 offset, varoffset;
+ S32 varoffset;
S32 ivalue;
F32 fpvalue;
LLVector3 vvalue;
@@ -144,8 +144,7 @@ void LLScriptLSOParse::printGlobals(LLFILE *fp)
// get offset to skip past name
varoffset = global_v_offset;
- offset = bytestream2integer(mRawData, global_v_offset);
-
+ bytestream2integer(mRawData, global_v_offset);
// get typeexport
type = *(mRawData + global_v_offset++);
@@ -262,8 +261,6 @@ void LLScriptLSOParse::printGlobalFunctions(LLFILE *fp)
fprintf(fp, "[Function #%d] [0x%X] %s\n", function_number, orig_function_offset, name);
fprintf(fp, "\tReturn Type: %s\n", LSCRIPTTypeNames[type]);
type = *(mRawData + function_offset++);
- S32 params;
- params = 0;
S32 pcount = 0;
while (type)
{
@@ -347,16 +344,16 @@ void LLScriptLSOParse::printStates(LLFILE *fp)
read_ahead = event_jump_table;
S32 temp_end;
- S32 dummy;
opcode_end = worst_case_opcode_end;
+ (void)opcode_end;
for (k = LSTT_STATE_BEGIN; k < LSTT_STATE_END; k++)
{
if (event_handlers & LSCRIPTStateBitField[k])
{
temp_end = bytestream2integer(mRawData, read_ahead);
- dummy = bytestream2integer(mRawData, read_ahead);
+ bytestream2integer(mRawData, read_ahead);
if ( (temp_end < opcode_end)
&&(temp_end > event_offset))
{
diff --git a/indra/lscript/lscript_execute/lscript_readlso.h b/indra/lscript/lscript_execute/lscript_readlso.h
index a545a9daf8..a545a9daf8 100644..100755
--- a/indra/lscript/lscript_execute/lscript_readlso.h
+++ b/indra/lscript/lscript_execute/lscript_readlso.h
diff --git a/indra/lscript/lscript_export.h b/indra/lscript/lscript_export.h
index 2043dd4558..2043dd4558 100644..100755
--- a/indra/lscript/lscript_export.h
+++ b/indra/lscript/lscript_export.h
diff --git a/indra/lscript/lscript_http.h b/indra/lscript/lscript_http.h
index c6f2325995..c6f2325995 100644..100755
--- a/indra/lscript/lscript_http.h
+++ b/indra/lscript/lscript_http.h
diff --git a/indra/lscript/lscript_library.h b/indra/lscript/lscript_library.h
index 89a473a627..89a473a627 100644..100755
--- a/indra/lscript/lscript_library.h
+++ b/indra/lscript/lscript_library.h
diff --git a/indra/lscript/lscript_library/CMakeLists.txt b/indra/lscript/lscript_library/CMakeLists.txt
index f6bc67a994..5af850c41b 100644..100755
--- a/indra/lscript/lscript_library/CMakeLists.txt
+++ b/indra/lscript/lscript_library/CMakeLists.txt
@@ -28,5 +28,8 @@ include_directories(
${LLMATH_INCLUDE_DIRS}
${LSCRIPT_INCLUDE_DIRS}
)
+include_directories(SYSTEM
+ ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+ )
add_library (lscript_library ${lscript_library_SOURCE_FILES})
diff --git a/indra/lscript/lscript_library/lscript_alloc.cpp b/indra/lscript/lscript_library/lscript_alloc.cpp
index 92b1ab70fb..92b1ab70fb 100644..100755
--- a/indra/lscript/lscript_library/lscript_alloc.cpp
+++ b/indra/lscript/lscript_library/lscript_alloc.cpp
diff --git a/indra/lscript/lscript_library/lscript_export.cpp b/indra/lscript/lscript_library/lscript_export.cpp
index 0ed85e3686..0ed85e3686 100644..100755
--- a/indra/lscript/lscript_library/lscript_export.cpp
+++ b/indra/lscript/lscript_library/lscript_export.cpp
diff --git a/indra/lscript/lscript_library/lscript_library.cpp b/indra/lscript/lscript_library/lscript_library.cpp
index 7ffe53a307..7ffe53a307 100644..100755
--- a/indra/lscript/lscript_library/lscript_library.cpp
+++ b/indra/lscript/lscript_library/lscript_library.cpp
diff --git a/indra/lscript/lscript_rt_interface.h b/indra/lscript/lscript_rt_interface.h
index cdf2c5bbd7..cdf2c5bbd7 100644..100755
--- a/indra/lscript/lscript_rt_interface.h
+++ b/indra/lscript/lscript_rt_interface.h
diff --git a/indra/mac_crash_logger/CMakeLists.txt b/indra/mac_crash_logger/CMakeLists.txt
index 420e836e36..c59645bd70 100644..100755
--- a/indra/mac_crash_logger/CMakeLists.txt
+++ b/indra/mac_crash_logger/CMakeLists.txt
@@ -19,16 +19,22 @@ include_directories(
${LLVFS_INCLUDE_DIRS}
${LLXML_INCLUDE_DIRS}
)
+include_directories(SYSTEM
+ ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+ ${LLXML_SYSTEM_INCLUDE_DIRS}
+ )
set(mac_crash_logger_SOURCE_FILES
mac_crash_logger.cpp
llcrashloggermac.cpp
+ llcrashloggermacdelegate.mm
)
set(mac_crash_logger_HEADER_FILES
CMakeLists.txt
llcrashloggermac.h
+ llcrashloggermacdelegate.h
)
set_source_files_properties(${mac_crash_logger_HEADER_FILES}
@@ -55,9 +61,12 @@ set_target_properties(mac-crash-logger
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist
)
+find_library(COCOA_LIBRARY Cocoa)
+
target_link_libraries(mac-crash-logger
${LLCRASHLOGGER_LIBRARIES}
${LLVFS_LIBRARIES}
+ ${COCOA_LIBRARIES}
${LLXML_LIBRARIES}
${LLMESSAGE_LIBRARIES}
${LLVFS_LIBRARIES}
diff --git a/indra/mac_crash_logger/CrashReporter.nib b/indra/mac_crash_logger/CrashReporter.nib
new file mode 100755
index 0000000000..e9d9e05985
--- /dev/null
+++ b/indra/mac_crash_logger/CrashReporter.nib
Binary files differ
diff --git a/indra/mac_crash_logger/CrashReporter.nib/classes.nib b/indra/mac_crash_logger/CrashReporter.nib/classes.nib
deleted file mode 100644
index c4b887e72b..0000000000
--- a/indra/mac_crash_logger/CrashReporter.nib/classes.nib
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
- <key>IBVersion</key>
- <string>1</string>
-</dict>
-</plist>
diff --git a/indra/mac_crash_logger/CrashReporter.nib/info.nib b/indra/mac_crash_logger/CrashReporter.nib/info.nib
deleted file mode 100644
index 06805c0e4f..0000000000
--- a/indra/mac_crash_logger/CrashReporter.nib/info.nib
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
- <key>IBFramework Version</key>
- <string>629</string>
- <key>IBLastKnownRelativeProjectPath</key>
- <string>../../build-darwin-i386/SecondLife.xcodeproj</string>
- <key>IBOldestOS</key>
- <integer>5</integer>
- <key>IBOpenObjects</key>
- <array/>
- <key>IBSystem Version</key>
- <string>9E17</string>
- <key>targetFramework</key>
- <string>IBCarbonFramework</string>
-</dict>
-</plist>
diff --git a/indra/mac_crash_logger/CrashReporter.nib/objects.xib b/indra/mac_crash_logger/CrashReporter.nib/objects.xib
deleted file mode 100644
index 32647391b6..0000000000
--- a/indra/mac_crash_logger/CrashReporter.nib/objects.xib
+++ /dev/null
@@ -1,68 +0,0 @@
-<?xml version="1.0" standalone="yes"?>
-<object class="NSIBObjectData">
- <object name="rootObject" class="NSCustomObject" id="1">
- </object>
- <array count="7" name="allObjects">
- <object class="IBCarbonButton" id="182">
- <ostype name="command">ok </ostype>
- <string name="title">Send Report</string>
- <string name="bounds">414 273 434 378 </string>
- </object>
- <object class="IBCarbonButton" id="183">
- <ostype name="command">not!</ostype>
- <int name="buttonType">2</int>
- <string name="title">Don&apos;t Send</string>
- <string name="bounds">414 390 434 487 </string>
- </object>
- <object class="IBCarbonStaticText" id="181">
- <string name="title">Second Life appears to have crashed or frozen the last time it ran.&#10;&#10;This crash reporter collects information about your computer&apos;s hardware configuration, operating system, and some Second Life logs, all of which are used for debugging purposes only.&#10;&#10;In the space below, please briefly describe what you were doing or trying to do just prior to the crash. Thank you for your help!&#10;&#10;This report is NOT read by Customer Support. If you have billing or other questions, please go to: http://www.secondlife.com/support/&#10;&#10;If you don&apos;t wish to send Linden Lab a crash report, press Don&apos;t Send.&#10;</string>
- <string name="bounds">20 20 231 487 </string>
- </object>
- <object class="IBCarbonWindow" id="166">
- <int name="carbonWindowClass">2</int>
- <int name="themeBrush">3</int>
- <int name="windowPosition">7</int>
- <string name="title">Second Life Crash Logger</string>
- <object name="rootControl" class="IBCarbonRootControl" id="167">
- <array count="5" name="subviews">
- <reference idRef="181"/>
- <reference idRef="182"/>
- <reference idRef="183"/>
- <object class="IBCarbonEditText" id="185">
- <ostype name="controlSignature">text</ostype>
- <boolean name="isUnicode">TRUE</boolean>
- <string name="bounds">242 23 391 484 </string>
- </object>
- <object class="IBCarbonCheckBox" id="193">
- <ostype name="controlSignature">remb</ostype>
- <string name="title">Remember This Choice</string>
- <string name="bounds">415 20 433 186 </string>
- </object>
- </array>
- <string name="bounds">0 0 454 507 </string>
- </object>
- <string name="windowRect">257 653 711 1160 </string>
- <string name="ScreenRectAtEncodeTime">0 0 768 1024 </string>
- </object>
- <reference idRef="185"/>
- <reference idRef="167"/>
- <reference idRef="193"/>
- </array>
- <array count="7" name="allParents">
- <reference idRef="167"/>
- <reference idRef="167"/>
- <reference idRef="167"/>
- <reference idRef="1"/>
- <reference idRef="167"/>
- <reference idRef="166"/>
- <reference idRef="167"/>
- </array>
- <dictionary count="2" name="nameTable">
- <string>CrashReporter</string>
- <reference idRef="166"/>
- <string>File&apos;s Owner</string>
- <reference idRef="1"/>
- </dictionary>
- <string name="targetFramework">IBCarbonFramework</string>
- <unsigned_int name="nextObjectID">194</unsigned_int>
-</object>
diff --git a/indra/mac_crash_logger/CrashReporter.xib b/indra/mac_crash_logger/CrashReporter.xib
new file mode 100755
index 0000000000..f6d4776d51
--- /dev/null
+++ b/indra/mac_crash_logger/CrashReporter.xib
@@ -0,0 +1,3895 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<archive type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="8.00">
+ <data>
+ <int key="IBDocument.SystemTarget">1070</int>
+ <string key="IBDocument.SystemVersion">11G63</string>
+ <string key="IBDocument.InterfaceBuilderVersion">2182</string>
+ <string key="IBDocument.AppKitVersion">1138.51</string>
+ <string key="IBDocument.HIToolboxVersion">569.00</string>
+ <object class="NSMutableDictionary" key="IBDocument.PluginVersions">
+ <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="NS.object.0">2182</string>
+ </object>
+ <array key="IBDocument.IntegratedClassDependencies">
+ <string>NSTextField</string>
+ <string>NSView</string>
+ <string>NSWindowTemplate</string>
+ <string>NSMenu</string>
+ <string>NSMenuItem</string>
+ <string>NSTextFieldCell</string>
+ <string>NSButtonCell</string>
+ <string>IBNSLayoutConstraint</string>
+ <string>NSButton</string>
+ <string>NSCustomObject</string>
+ </array>
+ <array key="IBDocument.PluginDependencies">
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ </array>
+ <object class="NSMutableDictionary" key="IBDocument.Metadata">
+ <string key="NS.key.0">PluginDependencyRecalculationVersion</string>
+ <integer value="1" key="NS.object.0"/>
+ </object>
+ <array class="NSMutableArray" key="IBDocument.RootObjects" id="1048">
+ <object class="NSCustomObject" id="1021">
+ <string key="NSClassName">NSApplication</string>
+ </object>
+ <object class="NSCustomObject" id="1014">
+ <string key="NSClassName">FirstResponder</string>
+ </object>
+ <object class="NSCustomObject" id="1050">
+ <string key="NSClassName">NSApplication</string>
+ </object>
+ <object class="NSMenu" id="649796088">
+ <string key="NSTitle">AMainMenu</string>
+ <array class="NSMutableArray" key="NSMenuItems">
+ <object class="NSMenuItem" id="694149608">
+ <reference key="NSMenu" ref="649796088"/>
+ <string key="NSTitle">Second Life Crash Logger</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <object class="NSCustomResource" key="NSOnImage" id="35465992">
+ <string key="NSClassName">NSImage</string>
+ <string key="NSResourceName">NSMenuCheckmark</string>
+ </object>
+ <object class="NSCustomResource" key="NSMixedImage" id="502551668">
+ <string key="NSClassName">NSImage</string>
+ <string key="NSResourceName">NSMenuMixedState</string>
+ </object>
+ <string key="NSAction">submenuAction:</string>
+ <object class="NSMenu" key="NSSubmenu" id="110575045">
+ <string key="NSTitle">Second Life Crash Logger</string>
+ <array class="NSMutableArray" key="NSMenuItems">
+ <object class="NSMenuItem" id="238522557">
+ <reference key="NSMenu" ref="110575045"/>
+ <string key="NSTitle">About Second Life Crash Logger</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ <object class="NSMenuItem" id="304266470">
+ <reference key="NSMenu" ref="110575045"/>
+ <bool key="NSIsDisabled">YES</bool>
+ <bool key="NSIsSeparator">YES</bool>
+ <string key="NSTitle"/>
+ <string key="NSKeyEquiv"/>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ <object class="NSMenuItem" id="609285721">
+ <reference key="NSMenu" ref="110575045"/>
+ <string key="NSTitle">Preferences…</string>
+ <string key="NSKeyEquiv">,</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ <object class="NSMenuItem" id="481834944">
+ <reference key="NSMenu" ref="110575045"/>
+ <bool key="NSIsDisabled">YES</bool>
+ <bool key="NSIsSeparator">YES</bool>
+ <string key="NSTitle"/>
+ <string key="NSKeyEquiv"/>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ <object class="NSMenuItem" id="1046388886">
+ <reference key="NSMenu" ref="110575045"/>
+ <string key="NSTitle">Services</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ <string key="NSAction">submenuAction:</string>
+ <object class="NSMenu" key="NSSubmenu" id="752062318">
+ <string key="NSTitle">Services</string>
+ <array class="NSMutableArray" key="NSMenuItems"/>
+ <string key="NSName">_NSServicesMenu</string>
+ </object>
+ </object>
+ <object class="NSMenuItem" id="646227648">
+ <reference key="NSMenu" ref="110575045"/>
+ <bool key="NSIsDisabled">YES</bool>
+ <bool key="NSIsSeparator">YES</bool>
+ <string key="NSTitle"/>
+ <string key="NSKeyEquiv"/>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ <object class="NSMenuItem" id="755159360">
+ <reference key="NSMenu" ref="110575045"/>
+ <string key="NSTitle">Hide Second Life Crash Logger</string>
+ <string key="NSKeyEquiv">h</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ <object class="NSMenuItem" id="342932134">
+ <reference key="NSMenu" ref="110575045"/>
+ <string key="NSTitle">Hide Others</string>
+ <string key="NSKeyEquiv">h</string>
+ <int key="NSKeyEquivModMask">1572864</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ <object class="NSMenuItem" id="908899353">
+ <reference key="NSMenu" ref="110575045"/>
+ <string key="NSTitle">Show All</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ <object class="NSMenuItem" id="1056857174">
+ <reference key="NSMenu" ref="110575045"/>
+ <bool key="NSIsDisabled">YES</bool>
+ <bool key="NSIsSeparator">YES</bool>
+ <string key="NSTitle"/>
+ <string key="NSKeyEquiv"/>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ <object class="NSMenuItem" id="632727374">
+ <reference key="NSMenu" ref="110575045"/>
+ <string key="NSTitle">Quit Second Life Crash Logger</string>
+ <string key="NSKeyEquiv">q</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ </array>
+ <string key="NSName">_NSAppleMenu</string>
+ </object>
+ </object>
+ <object class="NSMenuItem" id="379814623">
+ <reference key="NSMenu" ref="649796088"/>
+ <string key="NSTitle">File</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ <string key="NSAction">submenuAction:</string>
+ <object class="NSMenu" key="NSSubmenu" id="720053764">
+ <string key="NSTitle">File</string>
+ <array class="NSMutableArray" key="NSMenuItems">
+ <object class="NSMenuItem" id="705341025">
+ <reference key="NSMenu" ref="720053764"/>
+ <string key="NSTitle">New</string>
+ <string key="NSKeyEquiv">n</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ <object class="NSMenuItem" id="722745758">
+ <reference key="NSMenu" ref="720053764"/>
+ <string key="NSTitle">Open…</string>
+ <string key="NSKeyEquiv">o</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ <object class="NSMenuItem" id="1025936716">
+ <reference key="NSMenu" ref="720053764"/>
+ <string key="NSTitle">Open Recent</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ <string key="NSAction">submenuAction:</string>
+ <object class="NSMenu" key="NSSubmenu" id="1065607017">
+ <string key="NSTitle">Open Recent</string>
+ <array class="NSMutableArray" key="NSMenuItems">
+ <object class="NSMenuItem" id="759406840">
+ <reference key="NSMenu" ref="1065607017"/>
+ <string key="NSTitle">Clear Menu</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ </array>
+ <string key="NSName">_NSRecentDocumentsMenu</string>
+ </object>
+ </object>
+ <object class="NSMenuItem" id="425164168">
+ <reference key="NSMenu" ref="720053764"/>
+ <bool key="NSIsDisabled">YES</bool>
+ <bool key="NSIsSeparator">YES</bool>
+ <string key="NSTitle"/>
+ <string key="NSKeyEquiv"/>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ <object class="NSMenuItem" id="776162233">
+ <reference key="NSMenu" ref="720053764"/>
+ <string key="NSTitle">Close</string>
+ <string key="NSKeyEquiv">w</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ <object class="NSMenuItem" id="1023925487">
+ <reference key="NSMenu" ref="720053764"/>
+ <string key="NSTitle">Save…</string>
+ <string key="NSKeyEquiv">s</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ <object class="NSMenuItem" id="579971712">
+ <reference key="NSMenu" ref="720053764"/>
+ <string key="NSTitle">Revert to Saved</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ <object class="NSMenuItem" id="1010469920">
+ <reference key="NSMenu" ref="720053764"/>
+ <bool key="NSIsDisabled">YES</bool>
+ <bool key="NSIsSeparator">YES</bool>
+ <string key="NSTitle"/>
+ <string key="NSKeyEquiv"/>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ <object class="NSMenuItem" id="294629803">
+ <reference key="NSMenu" ref="720053764"/>
+ <string key="NSTitle">Page Setup...</string>
+ <string key="NSKeyEquiv">P</string>
+ <int key="NSKeyEquivModMask">1179648</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ <string key="NSToolTip"/>
+ </object>
+ <object class="NSMenuItem" id="49223823">
+ <reference key="NSMenu" ref="720053764"/>
+ <string key="NSTitle">Print…</string>
+ <string key="NSKeyEquiv">p</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ </array>
+ </object>
+ </object>
+ <object class="NSMenuItem" id="952259628">
+ <reference key="NSMenu" ref="649796088"/>
+ <string key="NSTitle">Edit</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ <string key="NSAction">submenuAction:</string>
+ <object class="NSMenu" key="NSSubmenu" id="789758025">
+ <string key="NSTitle">Edit</string>
+ <array class="NSMutableArray" key="NSMenuItems">
+ <object class="NSMenuItem" id="1058277027">
+ <reference key="NSMenu" ref="789758025"/>
+ <string key="NSTitle">Undo</string>
+ <string key="NSKeyEquiv">z</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ <object class="NSMenuItem" id="790794224">
+ <reference key="NSMenu" ref="789758025"/>
+ <string key="NSTitle">Redo</string>
+ <string key="NSKeyEquiv">Z</string>
+ <int key="NSKeyEquivModMask">1179648</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ <object class="NSMenuItem" id="1040322652">
+ <reference key="NSMenu" ref="789758025"/>
+ <bool key="NSIsDisabled">YES</bool>
+ <bool key="NSIsSeparator">YES</bool>
+ <string key="NSTitle"/>
+ <string key="NSKeyEquiv"/>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ <object class="NSMenuItem" id="296257095">
+ <reference key="NSMenu" ref="789758025"/>
+ <string key="NSTitle">Cut</string>
+ <string key="NSKeyEquiv">x</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ <object class="NSMenuItem" id="860595796">
+ <reference key="NSMenu" ref="789758025"/>
+ <string key="NSTitle">Copy</string>
+ <string key="NSKeyEquiv">c</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ <object class="NSMenuItem" id="29853731">
+ <reference key="NSMenu" ref="789758025"/>
+ <string key="NSTitle">Paste</string>
+ <string key="NSKeyEquiv">v</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ <object class="NSMenuItem" id="82994268">
+ <reference key="NSMenu" ref="789758025"/>
+ <string key="NSTitle">Paste and Match Style</string>
+ <string key="NSKeyEquiv">V</string>
+ <int key="NSKeyEquivModMask">1572864</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ <object class="NSMenuItem" id="437104165">
+ <reference key="NSMenu" ref="789758025"/>
+ <string key="NSTitle">Delete</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ <object class="NSMenuItem" id="583158037">
+ <reference key="NSMenu" ref="789758025"/>
+ <string key="NSTitle">Select All</string>
+ <string key="NSKeyEquiv">a</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ <object class="NSMenuItem" id="212016141">
+ <reference key="NSMenu" ref="789758025"/>
+ <bool key="NSIsDisabled">YES</bool>
+ <bool key="NSIsSeparator">YES</bool>
+ <string key="NSTitle"/>
+ <string key="NSKeyEquiv"/>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ <object class="NSMenuItem" id="892235320">
+ <reference key="NSMenu" ref="789758025"/>
+ <string key="NSTitle">Find</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ <string key="NSAction">submenuAction:</string>
+ <object class="NSMenu" key="NSSubmenu" id="963351320">
+ <string key="NSTitle">Find</string>
+ <array class="NSMutableArray" key="NSMenuItems">
+ <object class="NSMenuItem" id="447796847">
+ <reference key="NSMenu" ref="963351320"/>
+ <string key="NSTitle">Find…</string>
+ <string key="NSKeyEquiv">f</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ <int key="NSTag">1</int>
+ </object>
+ <object class="NSMenuItem" id="738670835">
+ <reference key="NSMenu" ref="963351320"/>
+ <string key="NSTitle">Find and Replace…</string>
+ <string key="NSKeyEquiv">f</string>
+ <int key="NSKeyEquivModMask">1572864</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ <int key="NSTag">12</int>
+ </object>
+ <object class="NSMenuItem" id="326711663">
+ <reference key="NSMenu" ref="963351320"/>
+ <string key="NSTitle">Find Next</string>
+ <string key="NSKeyEquiv">g</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ <int key="NSTag">2</int>
+ </object>
+ <object class="NSMenuItem" id="270902937">
+ <reference key="NSMenu" ref="963351320"/>
+ <string key="NSTitle">Find Previous</string>
+ <string key="NSKeyEquiv">G</string>
+ <int key="NSKeyEquivModMask">1179648</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ <int key="NSTag">3</int>
+ </object>
+ <object class="NSMenuItem" id="159080638">
+ <reference key="NSMenu" ref="963351320"/>
+ <string key="NSTitle">Use Selection for Find</string>
+ <string key="NSKeyEquiv">e</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ <int key="NSTag">7</int>
+ </object>
+ <object class="NSMenuItem" id="88285865">
+ <reference key="NSMenu" ref="963351320"/>
+ <string key="NSTitle">Jump to Selection</string>
+ <string key="NSKeyEquiv">j</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ </array>
+ </object>
+ </object>
+ <object class="NSMenuItem" id="972420730">
+ <reference key="NSMenu" ref="789758025"/>
+ <string key="NSTitle">Spelling and Grammar</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ <string key="NSAction">submenuAction:</string>
+ <object class="NSMenu" key="NSSubmenu" id="769623530">
+ <string key="NSTitle">Spelling and Grammar</string>
+ <array class="NSMutableArray" key="NSMenuItems">
+ <object class="NSMenuItem" id="679648819">
+ <reference key="NSMenu" ref="769623530"/>
+ <string key="NSTitle">Show Spelling and Grammar</string>
+ <string key="NSKeyEquiv">:</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ <object class="NSMenuItem" id="96193923">
+ <reference key="NSMenu" ref="769623530"/>
+ <string key="NSTitle">Check Document Now</string>
+ <string key="NSKeyEquiv">;</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ <object class="NSMenuItem" id="859480356">
+ <reference key="NSMenu" ref="769623530"/>
+ <bool key="NSIsDisabled">YES</bool>
+ <bool key="NSIsSeparator">YES</bool>
+ <string key="NSTitle"/>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ <object class="NSMenuItem" id="948374510">
+ <reference key="NSMenu" ref="769623530"/>
+ <string key="NSTitle">Check Spelling While Typing</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ <object class="NSMenuItem" id="967646866">
+ <reference key="NSMenu" ref="769623530"/>
+ <string key="NSTitle">Check Grammar With Spelling</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ <object class="NSMenuItem" id="795346622">
+ <reference key="NSMenu" ref="769623530"/>
+ <string key="NSTitle">Correct Spelling Automatically</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ </array>
+ </object>
+ </object>
+ <object class="NSMenuItem" id="507821607">
+ <reference key="NSMenu" ref="789758025"/>
+ <string key="NSTitle">Substitutions</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ <string key="NSAction">submenuAction:</string>
+ <object class="NSMenu" key="NSSubmenu" id="698887838">
+ <string key="NSTitle">Substitutions</string>
+ <array class="NSMutableArray" key="NSMenuItems">
+ <object class="NSMenuItem" id="65139061">
+ <reference key="NSMenu" ref="698887838"/>
+ <string key="NSTitle">Show Substitutions</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ <object class="NSMenuItem" id="19036812">
+ <reference key="NSMenu" ref="698887838"/>
+ <bool key="NSIsDisabled">YES</bool>
+ <bool key="NSIsSeparator">YES</bool>
+ <string key="NSTitle"/>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ <object class="NSMenuItem" id="605118523">
+ <reference key="NSMenu" ref="698887838"/>
+ <string key="NSTitle">Smart Copy/Paste</string>
+ <string key="NSKeyEquiv">f</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ <int key="NSTag">1</int>
+ </object>
+ <object class="NSMenuItem" id="197661976">
+ <reference key="NSMenu" ref="698887838"/>
+ <string key="NSTitle">Smart Quotes</string>
+ <string key="NSKeyEquiv">g</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ <int key="NSTag">2</int>
+ </object>
+ <object class="NSMenuItem" id="672708820">
+ <reference key="NSMenu" ref="698887838"/>
+ <string key="NSTitle">Smart Dashes</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ <object class="NSMenuItem" id="708854459">
+ <reference key="NSMenu" ref="698887838"/>
+ <string key="NSTitle">Smart Links</string>
+ <string key="NSKeyEquiv">G</string>
+ <int key="NSKeyEquivModMask">1179648</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ <int key="NSTag">3</int>
+ </object>
+ <object class="NSMenuItem" id="537092702">
+ <reference key="NSMenu" ref="698887838"/>
+ <string key="NSTitle">Text Replacement</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ </array>
+ </object>
+ </object>
+ <object class="NSMenuItem" id="288088188">
+ <reference key="NSMenu" ref="789758025"/>
+ <string key="NSTitle">Transformations</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ <string key="NSAction">submenuAction:</string>
+ <object class="NSMenu" key="NSSubmenu" id="579392910">
+ <string key="NSTitle">Transformations</string>
+ <array class="NSMutableArray" key="NSMenuItems">
+ <object class="NSMenuItem" id="1060694897">
+ <reference key="NSMenu" ref="579392910"/>
+ <string key="NSTitle">Make Upper Case</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ <object class="NSMenuItem" id="879586729">
+ <reference key="NSMenu" ref="579392910"/>
+ <string key="NSTitle">Make Lower Case</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ <object class="NSMenuItem" id="56570060">
+ <reference key="NSMenu" ref="579392910"/>
+ <string key="NSTitle">Capitalize</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ </array>
+ </object>
+ </object>
+ <object class="NSMenuItem" id="676164635">
+ <reference key="NSMenu" ref="789758025"/>
+ <string key="NSTitle">Speech</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ <string key="NSAction">submenuAction:</string>
+ <object class="NSMenu" key="NSSubmenu" id="785027613">
+ <string key="NSTitle">Speech</string>
+ <array class="NSMutableArray" key="NSMenuItems">
+ <object class="NSMenuItem" id="731782645">
+ <reference key="NSMenu" ref="785027613"/>
+ <string key="NSTitle">Start Speaking</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ <object class="NSMenuItem" id="680220178">
+ <reference key="NSMenu" ref="785027613"/>
+ <string key="NSTitle">Stop Speaking</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ </array>
+ </object>
+ </object>
+ </array>
+ </object>
+ </object>
+ <object class="NSMenuItem" id="302598603">
+ <reference key="NSMenu" ref="649796088"/>
+ <string key="NSTitle">Format</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ <string key="NSAction">submenuAction:</string>
+ <object class="NSMenu" key="NSSubmenu" id="941447902">
+ <string key="NSTitle">Format</string>
+ <array class="NSMutableArray" key="NSMenuItems">
+ <object class="NSMenuItem" id="792887677">
+ <reference key="NSMenu" ref="941447902"/>
+ <string key="NSTitle">Font</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ <string key="NSAction">submenuAction:</string>
+ <object class="NSMenu" key="NSSubmenu" id="786677654">
+ <string key="NSTitle">Font</string>
+ <array class="NSMutableArray" key="NSMenuItems">
+ <object class="NSMenuItem" id="159677712">
+ <reference key="NSMenu" ref="786677654"/>
+ <string key="NSTitle">Show Fonts</string>
+ <string key="NSKeyEquiv">t</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ <object class="NSMenuItem" id="305399458">
+ <reference key="NSMenu" ref="786677654"/>
+ <string key="NSTitle">Bold</string>
+ <string key="NSKeyEquiv">b</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ <int key="NSTag">2</int>
+ </object>
+ <object class="NSMenuItem" id="814362025">
+ <reference key="NSMenu" ref="786677654"/>
+ <string key="NSTitle">Italic</string>
+ <string key="NSKeyEquiv">i</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ <int key="NSTag">1</int>
+ </object>
+ <object class="NSMenuItem" id="330926929">
+ <reference key="NSMenu" ref="786677654"/>
+ <string key="NSTitle">Underline</string>
+ <string key="NSKeyEquiv">u</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ <object class="NSMenuItem" id="533507878">
+ <reference key="NSMenu" ref="786677654"/>
+ <bool key="NSIsDisabled">YES</bool>
+ <bool key="NSIsSeparator">YES</bool>
+ <string key="NSTitle"/>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ <object class="NSMenuItem" id="158063935">
+ <reference key="NSMenu" ref="786677654"/>
+ <string key="NSTitle">Bigger</string>
+ <string key="NSKeyEquiv">+</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ <int key="NSTag">3</int>
+ </object>
+ <object class="NSMenuItem" id="885547335">
+ <reference key="NSMenu" ref="786677654"/>
+ <string key="NSTitle">Smaller</string>
+ <string key="NSKeyEquiv">-</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ <int key="NSTag">4</int>
+ </object>
+ <object class="NSMenuItem" id="901062459">
+ <reference key="NSMenu" ref="786677654"/>
+ <bool key="NSIsDisabled">YES</bool>
+ <bool key="NSIsSeparator">YES</bool>
+ <string key="NSTitle"/>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ <object class="NSMenuItem" id="767671776">
+ <reference key="NSMenu" ref="786677654"/>
+ <string key="NSTitle">Kern</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ <string key="NSAction">submenuAction:</string>
+ <object class="NSMenu" key="NSSubmenu" id="175441468">
+ <string key="NSTitle">Kern</string>
+ <array class="NSMutableArray" key="NSMenuItems">
+ <object class="NSMenuItem" id="252969304">
+ <reference key="NSMenu" ref="175441468"/>
+ <string key="NSTitle">Use Default</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ <object class="NSMenuItem" id="766922938">
+ <reference key="NSMenu" ref="175441468"/>
+ <string key="NSTitle">Use None</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ <object class="NSMenuItem" id="677519740">
+ <reference key="NSMenu" ref="175441468"/>
+ <string key="NSTitle">Tighten</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ <object class="NSMenuItem" id="238351151">
+ <reference key="NSMenu" ref="175441468"/>
+ <string key="NSTitle">Loosen</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ </array>
+ </object>
+ </object>
+ <object class="NSMenuItem" id="691570813">
+ <reference key="NSMenu" ref="786677654"/>
+ <string key="NSTitle">Ligature</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ <string key="NSAction">submenuAction:</string>
+ <object class="NSMenu" key="NSSubmenu" id="1058217995">
+ <string key="NSTitle">Ligature</string>
+ <array class="NSMutableArray" key="NSMenuItems">
+ <object class="NSMenuItem" id="706297211">
+ <reference key="NSMenu" ref="1058217995"/>
+ <string key="NSTitle">Use Default</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ <object class="NSMenuItem" id="568384683">
+ <reference key="NSMenu" ref="1058217995"/>
+ <string key="NSTitle">Use None</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ <object class="NSMenuItem" id="663508465">
+ <reference key="NSMenu" ref="1058217995"/>
+ <string key="NSTitle">Use All</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ </array>
+ </object>
+ </object>
+ <object class="NSMenuItem" id="769124883">
+ <reference key="NSMenu" ref="786677654"/>
+ <string key="NSTitle">Baseline</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ <string key="NSAction">submenuAction:</string>
+ <object class="NSMenu" key="NSSubmenu" id="18263474">
+ <string key="NSTitle">Baseline</string>
+ <array class="NSMutableArray" key="NSMenuItems">
+ <object class="NSMenuItem" id="257962622">
+ <reference key="NSMenu" ref="18263474"/>
+ <string key="NSTitle">Use Default</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ <object class="NSMenuItem" id="644725453">
+ <reference key="NSMenu" ref="18263474"/>
+ <string key="NSTitle">Superscript</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ <object class="NSMenuItem" id="1037576581">
+ <reference key="NSMenu" ref="18263474"/>
+ <string key="NSTitle">Subscript</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ <object class="NSMenuItem" id="941806246">
+ <reference key="NSMenu" ref="18263474"/>
+ <string key="NSTitle">Raise</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ <object class="NSMenuItem" id="1045724900">
+ <reference key="NSMenu" ref="18263474"/>
+ <string key="NSTitle">Lower</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ </array>
+ </object>
+ </object>
+ <object class="NSMenuItem" id="739652853">
+ <reference key="NSMenu" ref="786677654"/>
+ <bool key="NSIsDisabled">YES</bool>
+ <bool key="NSIsSeparator">YES</bool>
+ <string key="NSTitle"/>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ <object class="NSMenuItem" id="1012600125">
+ <reference key="NSMenu" ref="786677654"/>
+ <string key="NSTitle">Show Colors</string>
+ <string key="NSKeyEquiv">C</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ <object class="NSMenuItem" id="214559597">
+ <reference key="NSMenu" ref="786677654"/>
+ <bool key="NSIsDisabled">YES</bool>
+ <bool key="NSIsSeparator">YES</bool>
+ <string key="NSTitle"/>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ <object class="NSMenuItem" id="596732606">
+ <reference key="NSMenu" ref="786677654"/>
+ <string key="NSTitle">Copy Style</string>
+ <string key="NSKeyEquiv">c</string>
+ <int key="NSKeyEquivModMask">1572864</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ <object class="NSMenuItem" id="393423671">
+ <reference key="NSMenu" ref="786677654"/>
+ <string key="NSTitle">Paste Style</string>
+ <string key="NSKeyEquiv">v</string>
+ <int key="NSKeyEquivModMask">1572864</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ </array>
+ <string key="NSName">_NSFontMenu</string>
+ </object>
+ </object>
+ <object class="NSMenuItem" id="215659978">
+ <reference key="NSMenu" ref="941447902"/>
+ <string key="NSTitle">Text</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ <string key="NSAction">submenuAction:</string>
+ <object class="NSMenu" key="NSSubmenu" id="446991534">
+ <string key="NSTitle">Text</string>
+ <array class="NSMutableArray" key="NSMenuItems">
+ <object class="NSMenuItem" id="875092757">
+ <reference key="NSMenu" ref="446991534"/>
+ <string key="NSTitle">Align Left</string>
+ <string key="NSKeyEquiv">{</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ <object class="NSMenuItem" id="630155264">
+ <reference key="NSMenu" ref="446991534"/>
+ <string key="NSTitle">Center</string>
+ <string key="NSKeyEquiv">|</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ <object class="NSMenuItem" id="945678886">
+ <reference key="NSMenu" ref="446991534"/>
+ <string key="NSTitle">Justify</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ <object class="NSMenuItem" id="512868991">
+ <reference key="NSMenu" ref="446991534"/>
+ <string key="NSTitle">Align Right</string>
+ <string key="NSKeyEquiv">}</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ <object class="NSMenuItem" id="163117631">
+ <reference key="NSMenu" ref="446991534"/>
+ <bool key="NSIsDisabled">YES</bool>
+ <bool key="NSIsSeparator">YES</bool>
+ <string key="NSTitle"/>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ <object class="NSMenuItem" id="31516759">
+ <reference key="NSMenu" ref="446991534"/>
+ <string key="NSTitle">Writing Direction</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ <string key="NSAction">submenuAction:</string>
+ <object class="NSMenu" key="NSSubmenu" id="956096989">
+ <string key="NSTitle">Writing Direction</string>
+ <array class="NSMutableArray" key="NSMenuItems">
+ <object class="NSMenuItem" id="257099033">
+ <reference key="NSMenu" ref="956096989"/>
+ <bool key="NSIsDisabled">YES</bool>
+ <string key="NSTitle">Paragraph</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ <object class="NSMenuItem" id="551969625">
+ <reference key="NSMenu" ref="956096989"/>
+ <string type="base64-UTF8" key="NSTitle">CURlZmF1bHQ</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ <object class="NSMenuItem" id="249532473">
+ <reference key="NSMenu" ref="956096989"/>
+ <string type="base64-UTF8" key="NSTitle">CUxlZnQgdG8gUmlnaHQ</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ <object class="NSMenuItem" id="607364498">
+ <reference key="NSMenu" ref="956096989"/>
+ <string type="base64-UTF8" key="NSTitle">CVJpZ2h0IHRvIExlZnQ</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ <object class="NSMenuItem" id="508151438">
+ <reference key="NSMenu" ref="956096989"/>
+ <bool key="NSIsDisabled">YES</bool>
+ <bool key="NSIsSeparator">YES</bool>
+ <string key="NSTitle"/>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ <object class="NSMenuItem" id="981751889">
+ <reference key="NSMenu" ref="956096989"/>
+ <bool key="NSIsDisabled">YES</bool>
+ <string key="NSTitle">Selection</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ <object class="NSMenuItem" id="380031999">
+ <reference key="NSMenu" ref="956096989"/>
+ <string type="base64-UTF8" key="NSTitle">CURlZmF1bHQ</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ <object class="NSMenuItem" id="825984362">
+ <reference key="NSMenu" ref="956096989"/>
+ <string type="base64-UTF8" key="NSTitle">CUxlZnQgdG8gUmlnaHQ</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ <object class="NSMenuItem" id="560145579">
+ <reference key="NSMenu" ref="956096989"/>
+ <string type="base64-UTF8" key="NSTitle">CVJpZ2h0IHRvIExlZnQ</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ </array>
+ </object>
+ </object>
+ <object class="NSMenuItem" id="908105787">
+ <reference key="NSMenu" ref="446991534"/>
+ <bool key="NSIsDisabled">YES</bool>
+ <bool key="NSIsSeparator">YES</bool>
+ <string key="NSTitle"/>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ <object class="NSMenuItem" id="644046920">
+ <reference key="NSMenu" ref="446991534"/>
+ <string key="NSTitle">Show Ruler</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ <object class="NSMenuItem" id="231811626">
+ <reference key="NSMenu" ref="446991534"/>
+ <string key="NSTitle">Copy Ruler</string>
+ <string key="NSKeyEquiv">c</string>
+ <int key="NSKeyEquivModMask">1310720</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ <object class="NSMenuItem" id="883618387">
+ <reference key="NSMenu" ref="446991534"/>
+ <string key="NSTitle">Paste Ruler</string>
+ <string key="NSKeyEquiv">v</string>
+ <int key="NSKeyEquivModMask">1310720</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ </array>
+ </object>
+ </object>
+ </array>
+ </object>
+ </object>
+ <object class="NSMenuItem" id="586577488">
+ <reference key="NSMenu" ref="649796088"/>
+ <string key="NSTitle">View</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ <string key="NSAction">submenuAction:</string>
+ <object class="NSMenu" key="NSSubmenu" id="466310130">
+ <string key="NSTitle">View</string>
+ <array class="NSMutableArray" key="NSMenuItems">
+ <object class="NSMenuItem" id="102151532">
+ <reference key="NSMenu" ref="466310130"/>
+ <string key="NSTitle">Show Toolbar</string>
+ <string key="NSKeyEquiv">t</string>
+ <int key="NSKeyEquivModMask">1572864</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ <object class="NSMenuItem" id="237841660">
+ <reference key="NSMenu" ref="466310130"/>
+ <string key="NSTitle">Customize Toolbar…</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ </array>
+ </object>
+ </object>
+ <object class="NSMenuItem" id="713487014">
+ <reference key="NSMenu" ref="649796088"/>
+ <string key="NSTitle">Window</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ <string key="NSAction">submenuAction:</string>
+ <object class="NSMenu" key="NSSubmenu" id="835318025">
+ <string key="NSTitle">Window</string>
+ <array class="NSMutableArray" key="NSMenuItems">
+ <object class="NSMenuItem" id="1011231497">
+ <reference key="NSMenu" ref="835318025"/>
+ <string key="NSTitle">Minimize</string>
+ <string key="NSKeyEquiv">m</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ <object class="NSMenuItem" id="575023229">
+ <reference key="NSMenu" ref="835318025"/>
+ <string key="NSTitle">Zoom</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ <object class="NSMenuItem" id="299356726">
+ <reference key="NSMenu" ref="835318025"/>
+ <bool key="NSIsDisabled">YES</bool>
+ <bool key="NSIsSeparator">YES</bool>
+ <string key="NSTitle"/>
+ <string key="NSKeyEquiv"/>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ <object class="NSMenuItem" id="625202149">
+ <reference key="NSMenu" ref="835318025"/>
+ <string key="NSTitle">Bring All to Front</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ </array>
+ <string key="NSName">_NSWindowsMenu</string>
+ </object>
+ </object>
+ <object class="NSMenuItem" id="448692316">
+ <reference key="NSMenu" ref="649796088"/>
+ <string key="NSTitle">Help</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ <string key="NSAction">submenuAction:</string>
+ <object class="NSMenu" key="NSSubmenu" id="992780483">
+ <string key="NSTitle">Help</string>
+ <array class="NSMutableArray" key="NSMenuItems">
+ <object class="NSMenuItem" id="105068016">
+ <reference key="NSMenu" ref="992780483"/>
+ <string key="NSTitle">Second Life Crash Logger Help</string>
+ <string key="NSKeyEquiv">?</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="502551668"/>
+ </object>
+ </array>
+ <string key="NSName">_NSHelpMenu</string>
+ </object>
+ </object>
+ </array>
+ <string key="NSName">_NSMainMenu</string>
+ </object>
+ <object class="NSWindowTemplate" id="972006081">
+ <int key="NSWindowStyleMask">15</int>
+ <int key="NSWindowBacking">2</int>
+ <string key="NSWindowRect">{{335, 390}, {508, 477}}</string>
+ <int key="NSWTFlags">1954021376</int>
+ <string key="NSWindowTitle">Second Life Crash Logger</string>
+ <string key="NSWindowClass">NSWindow</string>
+ <nil key="NSViewClass"/>
+ <nil key="NSUserInterfaceItemIdentifier"/>
+ <object class="NSView" key="NSWindowView" id="439893737">
+ <reference key="NSNextResponder"/>
+ <int key="NSvFlags">256</int>
+ <array class="NSMutableArray" key="NSSubviews">
+ <object class="NSTextField" id="242877095">
+ <reference key="NSNextResponder" ref="439893737"/>
+ <int key="NSvFlags">268</int>
+ <string key="NSFrame">{{17, 228}, {474, 229}}</string>
+ <reference key="NSSuperview" ref="439893737"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="1018085422"/>
+ <string key="NSReuseIdentifierKey">_NS:9</string>
+ <string key="NSAntiCompressionPriority">{250, 750}</string>
+ <bool key="NSEnabled">YES</bool>
+ <object class="NSTextFieldCell" key="NSCell" id="502956757">
+ <int key="NSCellFlags">67239424</int>
+ <int key="NSCellFlags2">272891904</int>
+ <object class="NSMutableString" key="NSContents">
+ <bytes key="NS.bytes">U2Vjb25kIExpZmUgYXBwZWFycyB0byBoYXZlIGNyYXNoZWQgb3IgZnJvemVuIHRoZSBsYXN0IHRpbWUg
+aXQgcmFuLgoKVGhpcyBjcmFzaCByZXBvcnRlciBjb2xsZWN0cyBpbmZvcm1hdGlvbiBhYm91dCB5b3Vy
+IGNvbXB1dGVyJ3MgaGFyZHdhcmUgY29uZmlndXJhdGlvbiwgb3BlcmF0aW5nIHN5c3RlbSwgYW5kIHNv
+bWUgU2Vjb25kIExpZmUgbG9ncywgYWxsIG9mIHdoaWNoIGFyZSB1c2VkIGZvciBkZWJ1Z2dpbmcgcHVy
+cG9zZXMgb25seS4KCkluIHRoZSBzcGFjZSBiZWxvdywgcGxlYXNlIGJyaWVmbHkgZGVzY3JpYmUgd2hh
+dCB5b3Ugd2VyZSBkb2luZyBvciB0cnlpbmcgdG8gZG8ganVzdCBwcmlvciB0byB0aGUgY3Jhc2guICBU
+aGFuayB5b3UgZm9yIHlvdXIgaGVscCEKClRoaXMgcmVwb3J0IGlzIE5PVCByZWFkIGJ5IEN1c3RvbWVy
+IFN1cHBvcnQuICBJZiB5b3UgaGF2ZSBiaWxsaW5nIG9yIG90aGVyIHF1ZXN0aW9ucywgcGxlYXNlIGdv
+IHRvOiBodHRwOi8vd3d3LnNlY29uZGxpZmUuY29tL3N1cHBvcnQvCgpJZiB5b3UgZG9uJ3Qgd2lzaCB0
+byBzZW5kIExpbmRlbiBMYWIgYSBjcmFzaCByZXBvcnQsIHByZXNzIENhbmNlbC4</bytes>
+ </object>
+ <object class="NSFont" key="NSSupport" id="1010806345">
+ <string key="NSName">LucidaGrande</string>
+ <double key="NSSize">13</double>
+ <int key="NSfFlags">16</int>
+ </object>
+ <string key="NSCellIdentifier">_NS:9</string>
+ <reference key="NSControlView" ref="242877095"/>
+ <object class="NSColor" key="NSBackgroundColor">
+ <int key="NSColorSpace">6</int>
+ <string key="NSCatalogName">System</string>
+ <string key="NSColorName">controlColor</string>
+ <object class="NSColor" key="NSColor">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MC42NjY2NjY2NjY3AA</bytes>
+ </object>
+ </object>
+ <object class="NSColor" key="NSTextColor">
+ <int key="NSColorSpace">6</int>
+ <string key="NSCatalogName">System</string>
+ <string key="NSColorName">controlTextColor</string>
+ <object class="NSColor" key="NSColor" id="355388215">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MAA</bytes>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="NSTextField" id="1018085422">
+ <reference key="NSNextResponder" ref="439893737"/>
+ <int key="NSvFlags">268</int>
+ <string key="NSFrame">{{20, 64}, {468, 163}}</string>
+ <reference key="NSSuperview" ref="439893737"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="688522420"/>
+ <string key="NSReuseIdentifierKey">_NS:9</string>
+ <string key="NSAntiCompressionPriority">{250, 750}</string>
+ <bool key="NSEnabled">YES</bool>
+ <object class="NSTextFieldCell" key="NSCell" id="867418359">
+ <int key="NSCellFlags">-1805517311</int>
+ <int key="NSCellFlags2">272891904</int>
+ <string key="NSContents"/>
+ <object class="NSFont" key="NSSupport">
+ <string key="NSName">LucidaGrande</string>
+ <double key="NSSize">9</double>
+ <int key="NSfFlags">3614</int>
+ </object>
+ <string key="NSCellIdentifier">_NS:9</string>
+ <reference key="NSControlView" ref="1018085422"/>
+ <bool key="NSDrawsBackground">YES</bool>
+ <object class="NSColor" key="NSBackgroundColor">
+ <int key="NSColorSpace">6</int>
+ <string key="NSCatalogName">System</string>
+ <string key="NSColorName">textBackgroundColor</string>
+ <object class="NSColor" key="NSColor">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MQA</bytes>
+ </object>
+ </object>
+ <object class="NSColor" key="NSTextColor">
+ <int key="NSColorSpace">6</int>
+ <string key="NSCatalogName">System</string>
+ <string key="NSColorName">textColor</string>
+ <reference key="NSColor" ref="355388215"/>
+ </object>
+ </object>
+ </object>
+ <object class="NSButton" id="688522420">
+ <reference key="NSNextResponder" ref="439893737"/>
+ <int key="NSvFlags">268</int>
+ <string key="NSFrame">{{16, 18}, {189, 30}}</string>
+ <reference key="NSSuperview" ref="439893737"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="93467784"/>
+ <string key="NSReuseIdentifierKey">_NS:9</string>
+ <bool key="NSEnabled">YES</bool>
+ <object class="NSButtonCell" key="NSCell" id="445379790">
+ <int key="NSCellFlags">-2080244224</int>
+ <int key="NSCellFlags2">262144</int>
+ <string key="NSContents">Remember This Choice</string>
+ <reference key="NSSupport" ref="1010806345"/>
+ <string key="NSCellIdentifier">_NS:9</string>
+ <reference key="NSControlView" ref="688522420"/>
+ <int key="NSButtonFlags">1211912703</int>
+ <int key="NSButtonFlags2">2</int>
+ <object class="NSCustomResource" key="NSNormalImage">
+ <string key="NSClassName">NSImage</string>
+ <string key="NSResourceName">NSSwitch</string>
+ </object>
+ <object class="NSButtonImageSource" key="NSAlternateImage">
+ <string key="NSImageName">NSSwitch</string>
+ </object>
+ <string key="NSAlternateContents"/>
+ <string key="NSKeyEquivalent"/>
+ <int key="NSPeriodicDelay">200</int>
+ <int key="NSPeriodicInterval">25</int>
+ </object>
+ </object>
+ <object class="NSButton" id="93467784">
+ <reference key="NSNextResponder" ref="439893737"/>
+ <int key="NSvFlags">268</int>
+ <string key="NSFrame">{{285, 23}, {91, 17}}</string>
+ <reference key="NSSuperview" ref="439893737"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="46276252"/>
+ <string key="NSReuseIdentifierKey">_NS:9</string>
+ <bool key="NSEnabled">YES</bool>
+ <object class="NSButtonCell" key="NSCell" id="623922320">
+ <int key="NSCellFlags">-2080244224</int>
+ <int key="NSCellFlags2">134479872</int>
+ <string key="NSContents">Send Report</string>
+ <reference key="NSSupport" ref="1010806345"/>
+ <string key="NSCellIdentifier">_NS:9</string>
+ <reference key="NSControlView" ref="93467784"/>
+ <int key="NSButtonFlags">-2038152961</int>
+ <int key="NSButtonFlags2">164</int>
+ <string key="NSAlternateContents"/>
+ <string key="NSKeyEquivalent"/>
+ <int key="NSPeriodicDelay">400</int>
+ <int key="NSPeriodicInterval">75</int>
+ </object>
+ </object>
+ <object class="NSButton" id="46276252">
+ <reference key="NSNextResponder" ref="439893737"/>
+ <int key="NSvFlags">268</int>
+ <string key="NSFrame">{{388, 23}, {100, 17}}</string>
+ <reference key="NSSuperview" ref="439893737"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView"/>
+ <string key="NSReuseIdentifierKey">_NS:9</string>
+ <bool key="NSEnabled">YES</bool>
+ <object class="NSButtonCell" key="NSCell" id="398179500">
+ <int key="NSCellFlags">-2080244224</int>
+ <int key="NSCellFlags2">134479872</int>
+ <string key="NSContents">Don't Send</string>
+ <reference key="NSSupport" ref="1010806345"/>
+ <string key="NSCellIdentifier">_NS:9</string>
+ <reference key="NSControlView" ref="46276252"/>
+ <int key="NSButtonFlags">-2038152961</int>
+ <int key="NSButtonFlags2">164</int>
+ <string key="NSAlternateContents"/>
+ <string key="NSKeyEquivalent"/>
+ <int key="NSPeriodicDelay">400</int>
+ <int key="NSPeriodicInterval">75</int>
+ </object>
+ </object>
+ </array>
+ <string key="NSFrameSize">{508, 477}</string>
+ <reference key="NSSuperview"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="242877095"/>
+ </object>
+ <string key="NSScreenRect">{{0, 0}, {1680, 1028}}</string>
+ <string key="NSMaxSize">{10000000000000, 10000000000000}</string>
+ <bool key="NSWindowIsRestorable">YES</bool>
+ </object>
+ <object class="NSCustomObject" id="976324537">
+ <string key="NSClassName">LLCrashLoggerMacDelegate</string>
+ </object>
+ </array>
+ <object class="IBObjectContainer" key="IBDocument.Objects">
+ <array class="NSMutableArray" key="connectionRecords">
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">terminate:</string>
+ <reference key="source" ref="1050"/>
+ <reference key="destination" ref="632727374"/>
+ </object>
+ <int key="connectionID">449</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">orderFrontStandardAboutPanel:</string>
+ <reference key="source" ref="1021"/>
+ <reference key="destination" ref="238522557"/>
+ </object>
+ <int key="connectionID">142</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBOutletConnection" key="connection">
+ <string key="label">delegate</string>
+ <reference key="source" ref="1021"/>
+ <reference key="destination" ref="976324537"/>
+ </object>
+ <int key="connectionID">495</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">performMiniaturize:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="1011231497"/>
+ </object>
+ <int key="connectionID">37</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">arrangeInFront:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="625202149"/>
+ </object>
+ <int key="connectionID">39</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">print:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="49223823"/>
+ </object>
+ <int key="connectionID">86</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">runPageLayout:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="294629803"/>
+ </object>
+ <int key="connectionID">87</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">clearRecentDocuments:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="759406840"/>
+ </object>
+ <int key="connectionID">127</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">performClose:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="776162233"/>
+ </object>
+ <int key="connectionID">193</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">toggleContinuousSpellChecking:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="948374510"/>
+ </object>
+ <int key="connectionID">222</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">undo:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="1058277027"/>
+ </object>
+ <int key="connectionID">223</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">copy:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="860595796"/>
+ </object>
+ <int key="connectionID">224</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">checkSpelling:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="96193923"/>
+ </object>
+ <int key="connectionID">225</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">paste:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="29853731"/>
+ </object>
+ <int key="connectionID">226</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">stopSpeaking:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="680220178"/>
+ </object>
+ <int key="connectionID">227</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">cut:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="296257095"/>
+ </object>
+ <int key="connectionID">228</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">showGuessPanel:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="679648819"/>
+ </object>
+ <int key="connectionID">230</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">redo:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="790794224"/>
+ </object>
+ <int key="connectionID">231</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">selectAll:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="583158037"/>
+ </object>
+ <int key="connectionID">232</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">startSpeaking:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="731782645"/>
+ </object>
+ <int key="connectionID">233</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">delete:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="437104165"/>
+ </object>
+ <int key="connectionID">235</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">performZoom:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="575023229"/>
+ </object>
+ <int key="connectionID">240</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">performFindPanelAction:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="447796847"/>
+ </object>
+ <int key="connectionID">241</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">centerSelectionInVisibleArea:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="88285865"/>
+ </object>
+ <int key="connectionID">245</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">toggleGrammarChecking:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="967646866"/>
+ </object>
+ <int key="connectionID">347</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">toggleSmartInsertDelete:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="605118523"/>
+ </object>
+ <int key="connectionID">355</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">toggleAutomaticQuoteSubstitution:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="197661976"/>
+ </object>
+ <int key="connectionID">356</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">toggleAutomaticLinkDetection:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="708854459"/>
+ </object>
+ <int key="connectionID">357</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">saveDocument:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="1023925487"/>
+ </object>
+ <int key="connectionID">362</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">revertDocumentToSaved:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="579971712"/>
+ </object>
+ <int key="connectionID">364</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">runToolbarCustomizationPalette:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="237841660"/>
+ </object>
+ <int key="connectionID">365</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">toggleToolbarShown:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="102151532"/>
+ </object>
+ <int key="connectionID">366</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">hide:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="755159360"/>
+ </object>
+ <int key="connectionID">367</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">hideOtherApplications:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="342932134"/>
+ </object>
+ <int key="connectionID">368</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">unhideAllApplications:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="908899353"/>
+ </object>
+ <int key="connectionID">370</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">newDocument:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="705341025"/>
+ </object>
+ <int key="connectionID">373</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">openDocument:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="722745758"/>
+ </object>
+ <int key="connectionID">374</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">raiseBaseline:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="941806246"/>
+ </object>
+ <int key="connectionID">426</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">lowerBaseline:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="1045724900"/>
+ </object>
+ <int key="connectionID">427</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">copyFont:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="596732606"/>
+ </object>
+ <int key="connectionID">428</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">subscript:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="1037576581"/>
+ </object>
+ <int key="connectionID">429</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">superscript:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="644725453"/>
+ </object>
+ <int key="connectionID">430</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">tightenKerning:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="677519740"/>
+ </object>
+ <int key="connectionID">431</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">underline:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="330926929"/>
+ </object>
+ <int key="connectionID">432</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">orderFrontColorPanel:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="1012600125"/>
+ </object>
+ <int key="connectionID">433</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">useAllLigatures:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="663508465"/>
+ </object>
+ <int key="connectionID">434</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">loosenKerning:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="238351151"/>
+ </object>
+ <int key="connectionID">435</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">pasteFont:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="393423671"/>
+ </object>
+ <int key="connectionID">436</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">unscript:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="257962622"/>
+ </object>
+ <int key="connectionID">437</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">useStandardKerning:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="252969304"/>
+ </object>
+ <int key="connectionID">438</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">useStandardLigatures:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="706297211"/>
+ </object>
+ <int key="connectionID">439</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">turnOffLigatures:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="568384683"/>
+ </object>
+ <int key="connectionID">440</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">turnOffKerning:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="766922938"/>
+ </object>
+ <int key="connectionID">441</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">toggleAutomaticSpellingCorrection:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="795346622"/>
+ </object>
+ <int key="connectionID">456</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">orderFrontSubstitutionsPanel:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="65139061"/>
+ </object>
+ <int key="connectionID">458</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">toggleAutomaticDashSubstitution:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="672708820"/>
+ </object>
+ <int key="connectionID">461</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">toggleAutomaticTextReplacement:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="537092702"/>
+ </object>
+ <int key="connectionID">463</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">uppercaseWord:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="1060694897"/>
+ </object>
+ <int key="connectionID">464</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">capitalizeWord:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="56570060"/>
+ </object>
+ <int key="connectionID">467</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">lowercaseWord:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="879586729"/>
+ </object>
+ <int key="connectionID">468</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">pasteAsPlainText:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="82994268"/>
+ </object>
+ <int key="connectionID">486</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">performFindPanelAction:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="326711663"/>
+ </object>
+ <int key="connectionID">487</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">performFindPanelAction:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="270902937"/>
+ </object>
+ <int key="connectionID">488</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">performFindPanelAction:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="159080638"/>
+ </object>
+ <int key="connectionID">489</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">showHelp:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="105068016"/>
+ </object>
+ <int key="connectionID">493</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">alignCenter:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="630155264"/>
+ </object>
+ <int key="connectionID">518</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">pasteRuler:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="883618387"/>
+ </object>
+ <int key="connectionID">519</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">toggleRuler:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="644046920"/>
+ </object>
+ <int key="connectionID">520</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">alignRight:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="512868991"/>
+ </object>
+ <int key="connectionID">521</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">copyRuler:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="231811626"/>
+ </object>
+ <int key="connectionID">522</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">alignJustified:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="945678886"/>
+ </object>
+ <int key="connectionID">523</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">alignLeft:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="875092757"/>
+ </object>
+ <int key="connectionID">524</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">makeBaseWritingDirectionNatural:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="551969625"/>
+ </object>
+ <int key="connectionID">525</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">makeBaseWritingDirectionLeftToRight:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="249532473"/>
+ </object>
+ <int key="connectionID">526</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">makeBaseWritingDirectionRightToLeft:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="607364498"/>
+ </object>
+ <int key="connectionID">527</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">makeTextWritingDirectionNatural:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="380031999"/>
+ </object>
+ <int key="connectionID">528</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">makeTextWritingDirectionLeftToRight:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="825984362"/>
+ </object>
+ <int key="connectionID">529</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">makeTextWritingDirectionRightToLeft:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="560145579"/>
+ </object>
+ <int key="connectionID">530</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">performFindPanelAction:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="738670835"/>
+ </object>
+ <int key="connectionID">535</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBOutletConnection" key="connection">
+ <string key="label">window</string>
+ <reference key="source" ref="976324537"/>
+ <reference key="destination" ref="972006081"/>
+ </object>
+ <int key="connectionID">532</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">remember:</string>
+ <reference key="source" ref="976324537"/>
+ <reference key="destination" ref="688522420"/>
+ </object>
+ <int key="connectionID">1176</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">send:</string>
+ <reference key="source" ref="976324537"/>
+ <reference key="destination" ref="93467784"/>
+ </object>
+ <int key="connectionID">1177</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">cancel:</string>
+ <reference key="source" ref="976324537"/>
+ <reference key="destination" ref="46276252"/>
+ </object>
+ <int key="connectionID">1178</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBOutletConnection" key="connection">
+ <string key="label">crashText</string>
+ <reference key="source" ref="976324537"/>
+ <reference key="destination" ref="1018085422"/>
+ </object>
+ <int key="connectionID">1179</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBOutletConnection" key="connection">
+ <string key="label">rememberCheck</string>
+ <reference key="source" ref="976324537"/>
+ <reference key="destination" ref="688522420"/>
+ </object>
+ <int key="connectionID">1187</int>
+ </object>
+ </array>
+ <object class="IBMutableOrderedSet" key="objectRecords">
+ <array key="orderedObjects">
+ <object class="IBObjectRecord">
+ <int key="objectID">0</int>
+ <array key="object" id="0"/>
+ <reference key="children" ref="1048"/>
+ <nil key="parent"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">-2</int>
+ <reference key="object" ref="1021"/>
+ <reference key="parent" ref="0"/>
+ <string key="objectName">File's Owner</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">-1</int>
+ <reference key="object" ref="1014"/>
+ <reference key="parent" ref="0"/>
+ <string key="objectName">First Responder</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">-3</int>
+ <reference key="object" ref="1050"/>
+ <reference key="parent" ref="0"/>
+ <string key="objectName">Application</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">29</int>
+ <reference key="object" ref="649796088"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="713487014"/>
+ <reference ref="694149608"/>
+ <reference ref="952259628"/>
+ <reference ref="379814623"/>
+ <reference ref="586577488"/>
+ <reference ref="302598603"/>
+ <reference ref="448692316"/>
+ </array>
+ <reference key="parent" ref="0"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">19</int>
+ <reference key="object" ref="713487014"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="835318025"/>
+ </array>
+ <reference key="parent" ref="649796088"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">56</int>
+ <reference key="object" ref="694149608"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="110575045"/>
+ </array>
+ <reference key="parent" ref="649796088"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">217</int>
+ <reference key="object" ref="952259628"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="789758025"/>
+ </array>
+ <reference key="parent" ref="649796088"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">83</int>
+ <reference key="object" ref="379814623"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="720053764"/>
+ </array>
+ <reference key="parent" ref="649796088"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">81</int>
+ <reference key="object" ref="720053764"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="1023925487"/>
+ <reference ref="49223823"/>
+ <reference ref="722745758"/>
+ <reference ref="705341025"/>
+ <reference ref="1025936716"/>
+ <reference ref="294629803"/>
+ <reference ref="776162233"/>
+ <reference ref="425164168"/>
+ <reference ref="579971712"/>
+ <reference ref="1010469920"/>
+ </array>
+ <reference key="parent" ref="379814623"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">75</int>
+ <reference key="object" ref="1023925487"/>
+ <reference key="parent" ref="720053764"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">78</int>
+ <reference key="object" ref="49223823"/>
+ <reference key="parent" ref="720053764"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">72</int>
+ <reference key="object" ref="722745758"/>
+ <reference key="parent" ref="720053764"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">82</int>
+ <reference key="object" ref="705341025"/>
+ <reference key="parent" ref="720053764"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">124</int>
+ <reference key="object" ref="1025936716"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="1065607017"/>
+ </array>
+ <reference key="parent" ref="720053764"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">77</int>
+ <reference key="object" ref="294629803"/>
+ <reference key="parent" ref="720053764"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">73</int>
+ <reference key="object" ref="776162233"/>
+ <reference key="parent" ref="720053764"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">79</int>
+ <reference key="object" ref="425164168"/>
+ <reference key="parent" ref="720053764"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">112</int>
+ <reference key="object" ref="579971712"/>
+ <reference key="parent" ref="720053764"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">74</int>
+ <reference key="object" ref="1010469920"/>
+ <reference key="parent" ref="720053764"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">125</int>
+ <reference key="object" ref="1065607017"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="759406840"/>
+ </array>
+ <reference key="parent" ref="1025936716"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">126</int>
+ <reference key="object" ref="759406840"/>
+ <reference key="parent" ref="1065607017"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">205</int>
+ <reference key="object" ref="789758025"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="437104165"/>
+ <reference ref="583158037"/>
+ <reference ref="1058277027"/>
+ <reference ref="212016141"/>
+ <reference ref="296257095"/>
+ <reference ref="29853731"/>
+ <reference ref="860595796"/>
+ <reference ref="1040322652"/>
+ <reference ref="790794224"/>
+ <reference ref="892235320"/>
+ <reference ref="972420730"/>
+ <reference ref="676164635"/>
+ <reference ref="507821607"/>
+ <reference ref="288088188"/>
+ <reference ref="82994268"/>
+ </array>
+ <reference key="parent" ref="952259628"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">202</int>
+ <reference key="object" ref="437104165"/>
+ <reference key="parent" ref="789758025"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">198</int>
+ <reference key="object" ref="583158037"/>
+ <reference key="parent" ref="789758025"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">207</int>
+ <reference key="object" ref="1058277027"/>
+ <reference key="parent" ref="789758025"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">214</int>
+ <reference key="object" ref="212016141"/>
+ <reference key="parent" ref="789758025"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">199</int>
+ <reference key="object" ref="296257095"/>
+ <reference key="parent" ref="789758025"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">203</int>
+ <reference key="object" ref="29853731"/>
+ <reference key="parent" ref="789758025"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">197</int>
+ <reference key="object" ref="860595796"/>
+ <reference key="parent" ref="789758025"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">206</int>
+ <reference key="object" ref="1040322652"/>
+ <reference key="parent" ref="789758025"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">215</int>
+ <reference key="object" ref="790794224"/>
+ <reference key="parent" ref="789758025"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">218</int>
+ <reference key="object" ref="892235320"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="963351320"/>
+ </array>
+ <reference key="parent" ref="789758025"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">216</int>
+ <reference key="object" ref="972420730"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="769623530"/>
+ </array>
+ <reference key="parent" ref="789758025"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">200</int>
+ <reference key="object" ref="769623530"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="948374510"/>
+ <reference ref="96193923"/>
+ <reference ref="679648819"/>
+ <reference ref="967646866"/>
+ <reference ref="859480356"/>
+ <reference ref="795346622"/>
+ </array>
+ <reference key="parent" ref="972420730"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">219</int>
+ <reference key="object" ref="948374510"/>
+ <reference key="parent" ref="769623530"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">201</int>
+ <reference key="object" ref="96193923"/>
+ <reference key="parent" ref="769623530"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">204</int>
+ <reference key="object" ref="679648819"/>
+ <reference key="parent" ref="769623530"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">220</int>
+ <reference key="object" ref="963351320"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="270902937"/>
+ <reference ref="88285865"/>
+ <reference ref="159080638"/>
+ <reference ref="326711663"/>
+ <reference ref="447796847"/>
+ <reference ref="738670835"/>
+ </array>
+ <reference key="parent" ref="892235320"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">213</int>
+ <reference key="object" ref="270902937"/>
+ <reference key="parent" ref="963351320"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">210</int>
+ <reference key="object" ref="88285865"/>
+ <reference key="parent" ref="963351320"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">221</int>
+ <reference key="object" ref="159080638"/>
+ <reference key="parent" ref="963351320"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">208</int>
+ <reference key="object" ref="326711663"/>
+ <reference key="parent" ref="963351320"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">209</int>
+ <reference key="object" ref="447796847"/>
+ <reference key="parent" ref="963351320"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">57</int>
+ <reference key="object" ref="110575045"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="238522557"/>
+ <reference ref="755159360"/>
+ <reference ref="908899353"/>
+ <reference ref="632727374"/>
+ <reference ref="646227648"/>
+ <reference ref="609285721"/>
+ <reference ref="481834944"/>
+ <reference ref="304266470"/>
+ <reference ref="1046388886"/>
+ <reference ref="1056857174"/>
+ <reference ref="342932134"/>
+ </array>
+ <reference key="parent" ref="694149608"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">58</int>
+ <reference key="object" ref="238522557"/>
+ <reference key="parent" ref="110575045"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">134</int>
+ <reference key="object" ref="755159360"/>
+ <reference key="parent" ref="110575045"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">150</int>
+ <reference key="object" ref="908899353"/>
+ <reference key="parent" ref="110575045"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">136</int>
+ <reference key="object" ref="632727374"/>
+ <reference key="parent" ref="110575045"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">144</int>
+ <reference key="object" ref="646227648"/>
+ <reference key="parent" ref="110575045"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">129</int>
+ <reference key="object" ref="609285721"/>
+ <reference key="parent" ref="110575045"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">143</int>
+ <reference key="object" ref="481834944"/>
+ <reference key="parent" ref="110575045"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">236</int>
+ <reference key="object" ref="304266470"/>
+ <reference key="parent" ref="110575045"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">131</int>
+ <reference key="object" ref="1046388886"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="752062318"/>
+ </array>
+ <reference key="parent" ref="110575045"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">149</int>
+ <reference key="object" ref="1056857174"/>
+ <reference key="parent" ref="110575045"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">145</int>
+ <reference key="object" ref="342932134"/>
+ <reference key="parent" ref="110575045"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">130</int>
+ <reference key="object" ref="752062318"/>
+ <reference key="parent" ref="1046388886"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">24</int>
+ <reference key="object" ref="835318025"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="299356726"/>
+ <reference ref="625202149"/>
+ <reference ref="575023229"/>
+ <reference ref="1011231497"/>
+ </array>
+ <reference key="parent" ref="713487014"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">92</int>
+ <reference key="object" ref="299356726"/>
+ <reference key="parent" ref="835318025"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">5</int>
+ <reference key="object" ref="625202149"/>
+ <reference key="parent" ref="835318025"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">239</int>
+ <reference key="object" ref="575023229"/>
+ <reference key="parent" ref="835318025"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">23</int>
+ <reference key="object" ref="1011231497"/>
+ <reference key="parent" ref="835318025"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">295</int>
+ <reference key="object" ref="586577488"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="466310130"/>
+ </array>
+ <reference key="parent" ref="649796088"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">296</int>
+ <reference key="object" ref="466310130"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="102151532"/>
+ <reference ref="237841660"/>
+ </array>
+ <reference key="parent" ref="586577488"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">297</int>
+ <reference key="object" ref="102151532"/>
+ <reference key="parent" ref="466310130"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">298</int>
+ <reference key="object" ref="237841660"/>
+ <reference key="parent" ref="466310130"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">211</int>
+ <reference key="object" ref="676164635"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="785027613"/>
+ </array>
+ <reference key="parent" ref="789758025"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">212</int>
+ <reference key="object" ref="785027613"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="680220178"/>
+ <reference ref="731782645"/>
+ </array>
+ <reference key="parent" ref="676164635"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">195</int>
+ <reference key="object" ref="680220178"/>
+ <reference key="parent" ref="785027613"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">196</int>
+ <reference key="object" ref="731782645"/>
+ <reference key="parent" ref="785027613"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">346</int>
+ <reference key="object" ref="967646866"/>
+ <reference key="parent" ref="769623530"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">348</int>
+ <reference key="object" ref="507821607"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="698887838"/>
+ </array>
+ <reference key="parent" ref="789758025"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">349</int>
+ <reference key="object" ref="698887838"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="605118523"/>
+ <reference ref="197661976"/>
+ <reference ref="708854459"/>
+ <reference ref="65139061"/>
+ <reference ref="19036812"/>
+ <reference ref="672708820"/>
+ <reference ref="537092702"/>
+ </array>
+ <reference key="parent" ref="507821607"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">350</int>
+ <reference key="object" ref="605118523"/>
+ <reference key="parent" ref="698887838"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">351</int>
+ <reference key="object" ref="197661976"/>
+ <reference key="parent" ref="698887838"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">354</int>
+ <reference key="object" ref="708854459"/>
+ <reference key="parent" ref="698887838"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">371</int>
+ <reference key="object" ref="972006081"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="439893737"/>
+ </array>
+ <reference key="parent" ref="0"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">372</int>
+ <reference key="object" ref="439893737"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="242877095"/>
+ <reference ref="1018085422"/>
+ <reference ref="688522420"/>
+ <object class="IBNSLayoutConstraint" id="109434655">
+ <reference key="firstItem" ref="242877095"/>
+ <int key="firstAttribute">3</int>
+ <int key="relation">0</int>
+ <reference key="secondItem" ref="439893737"/>
+ <int key="secondAttribute">3</int>
+ <float key="multiplier">1</float>
+ <object class="IBNSLayoutSymbolicConstant" key="constant">
+ <double key="value">20</double>
+ </object>
+ <float key="priority">1000</float>
+ <int key="scoringType">8</int>
+ <float key="scoringTypeFloat">29</float>
+ <int key="contentType">3</int>
+ <reference key="containingView" ref="439893737"/>
+ </object>
+ <reference ref="46276252"/>
+ <reference ref="93467784"/>
+ <object class="IBNSLayoutConstraint" id="166525974">
+ <reference key="firstItem" ref="439893737"/>
+ <int key="firstAttribute">6</int>
+ <int key="relation">0</int>
+ <reference key="secondItem" ref="242877095"/>
+ <int key="secondAttribute">6</int>
+ <float key="multiplier">1</float>
+ <object class="IBNSLayoutSymbolicConstant" key="constant">
+ <double key="value">20</double>
+ </object>
+ <float key="priority">1000</float>
+ <int key="scoringType">8</int>
+ <float key="scoringTypeFloat">29</float>
+ <int key="contentType">3</int>
+ <reference key="containingView" ref="439893737"/>
+ </object>
+ <object class="IBNSLayoutConstraint" id="229833409">
+ <reference key="firstItem" ref="242877095"/>
+ <int key="firstAttribute">5</int>
+ <int key="relation">0</int>
+ <reference key="secondItem" ref="439893737"/>
+ <int key="secondAttribute">5</int>
+ <float key="multiplier">1</float>
+ <object class="IBNSLayoutSymbolicConstant" key="constant">
+ <double key="value">20</double>
+ </object>
+ <float key="priority">1000</float>
+ <int key="scoringType">8</int>
+ <float key="scoringTypeFloat">29</float>
+ <int key="contentType">3</int>
+ <reference key="containingView" ref="439893737"/>
+ </object>
+ <object class="IBNSLayoutConstraint" id="992363278">
+ <reference key="firstItem" ref="439893737"/>
+ <int key="firstAttribute">6</int>
+ <int key="relation">0</int>
+ <reference key="secondItem" ref="1018085422"/>
+ <int key="secondAttribute">6</int>
+ <float key="multiplier">1</float>
+ <object class="IBNSLayoutSymbolicConstant" key="constant">
+ <double key="value">20</double>
+ </object>
+ <float key="priority">1000</float>
+ <int key="scoringType">8</int>
+ <float key="scoringTypeFloat">29</float>
+ <int key="contentType">3</int>
+ <reference key="containingView" ref="439893737"/>
+ </object>
+ <object class="IBNSLayoutConstraint" id="646866003">
+ <reference key="firstItem" ref="1018085422"/>
+ <int key="firstAttribute">5</int>
+ <int key="relation">0</int>
+ <reference key="secondItem" ref="439893737"/>
+ <int key="secondAttribute">5</int>
+ <float key="multiplier">1</float>
+ <object class="IBNSLayoutSymbolicConstant" key="constant">
+ <double key="value">20</double>
+ </object>
+ <float key="priority">1000</float>
+ <int key="scoringType">8</int>
+ <float key="scoringTypeFloat">29</float>
+ <int key="contentType">3</int>
+ <reference key="containingView" ref="439893737"/>
+ </object>
+ <object class="IBNSLayoutConstraint" id="98217052">
+ <reference key="firstItem" ref="439893737"/>
+ <int key="firstAttribute">4</int>
+ <int key="relation">0</int>
+ <reference key="secondItem" ref="1018085422"/>
+ <int key="secondAttribute">4</int>
+ <float key="multiplier">1</float>
+ <object class="IBLayoutConstant" key="constant">
+ <double key="value">64</double>
+ </object>
+ <float key="priority">1000</float>
+ <int key="scoringType">3</int>
+ <float key="scoringTypeFloat">9</float>
+ <int key="contentType">3</int>
+ <reference key="containingView" ref="439893737"/>
+ </object>
+ <object class="IBNSLayoutConstraint" id="578918264">
+ <reference key="firstItem" ref="439893737"/>
+ <int key="firstAttribute">6</int>
+ <int key="relation">0</int>
+ <reference key="secondItem" ref="46276252"/>
+ <int key="secondAttribute">6</int>
+ <float key="multiplier">1</float>
+ <object class="IBNSLayoutSymbolicConstant" key="constant">
+ <double key="value">20</double>
+ </object>
+ <float key="priority">1000</float>
+ <int key="scoringType">8</int>
+ <float key="scoringTypeFloat">29</float>
+ <int key="contentType">3</int>
+ <reference key="containingView" ref="439893737"/>
+ </object>
+ <object class="IBNSLayoutConstraint" id="591594339">
+ <reference key="firstItem" ref="688522420"/>
+ <int key="firstAttribute">5</int>
+ <int key="relation">0</int>
+ <reference key="secondItem" ref="439893737"/>
+ <int key="secondAttribute">5</int>
+ <float key="multiplier">1</float>
+ <object class="IBNSLayoutSymbolicConstant" key="constant">
+ <double key="value">20</double>
+ </object>
+ <float key="priority">1000</float>
+ <int key="scoringType">8</int>
+ <float key="scoringTypeFloat">29</float>
+ <int key="contentType">3</int>
+ <reference key="containingView" ref="439893737"/>
+ </object>
+ <object class="IBNSLayoutConstraint" id="432526715">
+ <reference key="firstItem" ref="439893737"/>
+ <int key="firstAttribute">4</int>
+ <int key="relation">0</int>
+ <reference key="secondItem" ref="688522420"/>
+ <int key="secondAttribute">4</int>
+ <float key="multiplier">1</float>
+ <object class="IBLayoutConstant" key="constant">
+ <double key="value">21</double>
+ </object>
+ <float key="priority">1000</float>
+ <int key="scoringType">3</int>
+ <float key="scoringTypeFloat">9</float>
+ <int key="contentType">3</int>
+ <reference key="containingView" ref="439893737"/>
+ </object>
+ <object class="IBNSLayoutConstraint" id="891430181">
+ <reference key="firstItem" ref="439893737"/>
+ <int key="firstAttribute">6</int>
+ <int key="relation">0</int>
+ <reference key="secondItem" ref="93467784"/>
+ <int key="secondAttribute">6</int>
+ <float key="multiplier">1</float>
+ <object class="IBLayoutConstant" key="constant">
+ <double key="value">132</double>
+ </object>
+ <float key="priority">1000</float>
+ <int key="scoringType">3</int>
+ <float key="scoringTypeFloat">9</float>
+ <int key="contentType">3</int>
+ <reference key="containingView" ref="439893737"/>
+ </object>
+ <object class="IBNSLayoutConstraint" id="833183002">
+ <reference key="firstItem" ref="93467784"/>
+ <int key="firstAttribute">11</int>
+ <int key="relation">0</int>
+ <reference key="secondItem" ref="46276252"/>
+ <int key="secondAttribute">11</int>
+ <float key="multiplier">1</float>
+ <object class="IBLayoutConstant" key="constant">
+ <double key="value">0.0</double>
+ </object>
+ <float key="priority">1000</float>
+ <int key="scoringType">6</int>
+ <float key="scoringTypeFloat">24</float>
+ <int key="contentType">2</int>
+ <reference key="containingView" ref="439893737"/>
+ </object>
+ <object class="IBNSLayoutConstraint" id="670714078">
+ <reference key="firstItem" ref="93467784"/>
+ <int key="firstAttribute">10</int>
+ <int key="relation">0</int>
+ <reference key="secondItem" ref="688522420"/>
+ <int key="secondAttribute">10</int>
+ <float key="multiplier">1</float>
+ <object class="IBLayoutConstant" key="constant">
+ <double key="value">0.0</double>
+ </object>
+ <float key="priority">1000</float>
+ <int key="scoringType">6</int>
+ <float key="scoringTypeFloat">24</float>
+ <int key="contentType">2</int>
+ <reference key="containingView" ref="439893737"/>
+ </object>
+ </array>
+ <reference key="parent" ref="972006081"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">375</int>
+ <reference key="object" ref="302598603"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="941447902"/>
+ </array>
+ <reference key="parent" ref="649796088"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">376</int>
+ <reference key="object" ref="941447902"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="792887677"/>
+ <reference ref="215659978"/>
+ </array>
+ <reference key="parent" ref="302598603"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">377</int>
+ <reference key="object" ref="792887677"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="786677654"/>
+ </array>
+ <reference key="parent" ref="941447902"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">388</int>
+ <reference key="object" ref="786677654"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="159677712"/>
+ <reference ref="305399458"/>
+ <reference ref="814362025"/>
+ <reference ref="330926929"/>
+ <reference ref="533507878"/>
+ <reference ref="158063935"/>
+ <reference ref="885547335"/>
+ <reference ref="901062459"/>
+ <reference ref="767671776"/>
+ <reference ref="691570813"/>
+ <reference ref="769124883"/>
+ <reference ref="739652853"/>
+ <reference ref="1012600125"/>
+ <reference ref="214559597"/>
+ <reference ref="596732606"/>
+ <reference ref="393423671"/>
+ </array>
+ <reference key="parent" ref="792887677"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">389</int>
+ <reference key="object" ref="159677712"/>
+ <reference key="parent" ref="786677654"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">390</int>
+ <reference key="object" ref="305399458"/>
+ <reference key="parent" ref="786677654"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">391</int>
+ <reference key="object" ref="814362025"/>
+ <reference key="parent" ref="786677654"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">392</int>
+ <reference key="object" ref="330926929"/>
+ <reference key="parent" ref="786677654"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">393</int>
+ <reference key="object" ref="533507878"/>
+ <reference key="parent" ref="786677654"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">394</int>
+ <reference key="object" ref="158063935"/>
+ <reference key="parent" ref="786677654"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">395</int>
+ <reference key="object" ref="885547335"/>
+ <reference key="parent" ref="786677654"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">396</int>
+ <reference key="object" ref="901062459"/>
+ <reference key="parent" ref="786677654"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">397</int>
+ <reference key="object" ref="767671776"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="175441468"/>
+ </array>
+ <reference key="parent" ref="786677654"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">398</int>
+ <reference key="object" ref="691570813"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="1058217995"/>
+ </array>
+ <reference key="parent" ref="786677654"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">399</int>
+ <reference key="object" ref="769124883"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="18263474"/>
+ </array>
+ <reference key="parent" ref="786677654"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">400</int>
+ <reference key="object" ref="739652853"/>
+ <reference key="parent" ref="786677654"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">401</int>
+ <reference key="object" ref="1012600125"/>
+ <reference key="parent" ref="786677654"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">402</int>
+ <reference key="object" ref="214559597"/>
+ <reference key="parent" ref="786677654"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">403</int>
+ <reference key="object" ref="596732606"/>
+ <reference key="parent" ref="786677654"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">404</int>
+ <reference key="object" ref="393423671"/>
+ <reference key="parent" ref="786677654"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">405</int>
+ <reference key="object" ref="18263474"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="257962622"/>
+ <reference ref="644725453"/>
+ <reference ref="1037576581"/>
+ <reference ref="941806246"/>
+ <reference ref="1045724900"/>
+ </array>
+ <reference key="parent" ref="769124883"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">406</int>
+ <reference key="object" ref="257962622"/>
+ <reference key="parent" ref="18263474"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">407</int>
+ <reference key="object" ref="644725453"/>
+ <reference key="parent" ref="18263474"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">408</int>
+ <reference key="object" ref="1037576581"/>
+ <reference key="parent" ref="18263474"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">409</int>
+ <reference key="object" ref="941806246"/>
+ <reference key="parent" ref="18263474"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">410</int>
+ <reference key="object" ref="1045724900"/>
+ <reference key="parent" ref="18263474"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">411</int>
+ <reference key="object" ref="1058217995"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="706297211"/>
+ <reference ref="568384683"/>
+ <reference ref="663508465"/>
+ </array>
+ <reference key="parent" ref="691570813"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">412</int>
+ <reference key="object" ref="706297211"/>
+ <reference key="parent" ref="1058217995"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">413</int>
+ <reference key="object" ref="568384683"/>
+ <reference key="parent" ref="1058217995"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">414</int>
+ <reference key="object" ref="663508465"/>
+ <reference key="parent" ref="1058217995"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">415</int>
+ <reference key="object" ref="175441468"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="252969304"/>
+ <reference ref="766922938"/>
+ <reference ref="677519740"/>
+ <reference ref="238351151"/>
+ </array>
+ <reference key="parent" ref="767671776"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">416</int>
+ <reference key="object" ref="252969304"/>
+ <reference key="parent" ref="175441468"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">417</int>
+ <reference key="object" ref="766922938"/>
+ <reference key="parent" ref="175441468"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">418</int>
+ <reference key="object" ref="677519740"/>
+ <reference key="parent" ref="175441468"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">419</int>
+ <reference key="object" ref="238351151"/>
+ <reference key="parent" ref="175441468"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">450</int>
+ <reference key="object" ref="288088188"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="579392910"/>
+ </array>
+ <reference key="parent" ref="789758025"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">451</int>
+ <reference key="object" ref="579392910"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="1060694897"/>
+ <reference ref="879586729"/>
+ <reference ref="56570060"/>
+ </array>
+ <reference key="parent" ref="288088188"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">452</int>
+ <reference key="object" ref="1060694897"/>
+ <reference key="parent" ref="579392910"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">453</int>
+ <reference key="object" ref="859480356"/>
+ <reference key="parent" ref="769623530"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">454</int>
+ <reference key="object" ref="795346622"/>
+ <reference key="parent" ref="769623530"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">457</int>
+ <reference key="object" ref="65139061"/>
+ <reference key="parent" ref="698887838"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">459</int>
+ <reference key="object" ref="19036812"/>
+ <reference key="parent" ref="698887838"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">460</int>
+ <reference key="object" ref="672708820"/>
+ <reference key="parent" ref="698887838"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">462</int>
+ <reference key="object" ref="537092702"/>
+ <reference key="parent" ref="698887838"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">465</int>
+ <reference key="object" ref="879586729"/>
+ <reference key="parent" ref="579392910"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">466</int>
+ <reference key="object" ref="56570060"/>
+ <reference key="parent" ref="579392910"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">485</int>
+ <reference key="object" ref="82994268"/>
+ <reference key="parent" ref="789758025"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">490</int>
+ <reference key="object" ref="448692316"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="992780483"/>
+ </array>
+ <reference key="parent" ref="649796088"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">491</int>
+ <reference key="object" ref="992780483"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="105068016"/>
+ </array>
+ <reference key="parent" ref="448692316"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">492</int>
+ <reference key="object" ref="105068016"/>
+ <reference key="parent" ref="992780483"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">494</int>
+ <reference key="object" ref="976324537"/>
+ <reference key="parent" ref="0"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">496</int>
+ <reference key="object" ref="215659978"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="446991534"/>
+ </array>
+ <reference key="parent" ref="941447902"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">497</int>
+ <reference key="object" ref="446991534"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="875092757"/>
+ <reference ref="630155264"/>
+ <reference ref="945678886"/>
+ <reference ref="512868991"/>
+ <reference ref="163117631"/>
+ <reference ref="31516759"/>
+ <reference ref="908105787"/>
+ <reference ref="644046920"/>
+ <reference ref="231811626"/>
+ <reference ref="883618387"/>
+ </array>
+ <reference key="parent" ref="215659978"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">498</int>
+ <reference key="object" ref="875092757"/>
+ <reference key="parent" ref="446991534"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">499</int>
+ <reference key="object" ref="630155264"/>
+ <reference key="parent" ref="446991534"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">500</int>
+ <reference key="object" ref="945678886"/>
+ <reference key="parent" ref="446991534"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">501</int>
+ <reference key="object" ref="512868991"/>
+ <reference key="parent" ref="446991534"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">502</int>
+ <reference key="object" ref="163117631"/>
+ <reference key="parent" ref="446991534"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">503</int>
+ <reference key="object" ref="31516759"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="956096989"/>
+ </array>
+ <reference key="parent" ref="446991534"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">504</int>
+ <reference key="object" ref="908105787"/>
+ <reference key="parent" ref="446991534"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">505</int>
+ <reference key="object" ref="644046920"/>
+ <reference key="parent" ref="446991534"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">506</int>
+ <reference key="object" ref="231811626"/>
+ <reference key="parent" ref="446991534"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">507</int>
+ <reference key="object" ref="883618387"/>
+ <reference key="parent" ref="446991534"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">508</int>
+ <reference key="object" ref="956096989"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="257099033"/>
+ <reference ref="551969625"/>
+ <reference ref="249532473"/>
+ <reference ref="607364498"/>
+ <reference ref="508151438"/>
+ <reference ref="981751889"/>
+ <reference ref="380031999"/>
+ <reference ref="825984362"/>
+ <reference ref="560145579"/>
+ </array>
+ <reference key="parent" ref="31516759"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">509</int>
+ <reference key="object" ref="257099033"/>
+ <reference key="parent" ref="956096989"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">510</int>
+ <reference key="object" ref="551969625"/>
+ <reference key="parent" ref="956096989"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">511</int>
+ <reference key="object" ref="249532473"/>
+ <reference key="parent" ref="956096989"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">512</int>
+ <reference key="object" ref="607364498"/>
+ <reference key="parent" ref="956096989"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">513</int>
+ <reference key="object" ref="508151438"/>
+ <reference key="parent" ref="956096989"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">514</int>
+ <reference key="object" ref="981751889"/>
+ <reference key="parent" ref="956096989"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">515</int>
+ <reference key="object" ref="380031999"/>
+ <reference key="parent" ref="956096989"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">516</int>
+ <reference key="object" ref="825984362"/>
+ <reference key="parent" ref="956096989"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">517</int>
+ <reference key="object" ref="560145579"/>
+ <reference key="parent" ref="956096989"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">534</int>
+ <reference key="object" ref="738670835"/>
+ <reference key="parent" ref="963351320"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">536</int>
+ <reference key="object" ref="242877095"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="502956757"/>
+ <object class="IBNSLayoutConstraint" id="697106875">
+ <reference key="firstItem" ref="242877095"/>
+ <int key="firstAttribute">8</int>
+ <int key="relation">0</int>
+ <nil key="secondItem"/>
+ <int key="secondAttribute">0</int>
+ <float key="multiplier">1</float>
+ <object class="IBLayoutConstant" key="constant">
+ <double key="value">229</double>
+ </object>
+ <float key="priority">1000</float>
+ <int key="scoringType">3</int>
+ <float key="scoringTypeFloat">9</float>
+ <int key="contentType">1</int>
+ <reference key="containingView" ref="242877095"/>
+ </object>
+ </array>
+ <reference key="parent" ref="439893737"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">537</int>
+ <reference key="object" ref="502956757"/>
+ <reference key="parent" ref="242877095"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">593</int>
+ <reference key="object" ref="1018085422"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="867418359"/>
+ <object class="IBNSLayoutConstraint" id="276483890">
+ <reference key="firstItem" ref="1018085422"/>
+ <int key="firstAttribute">8</int>
+ <int key="relation">0</int>
+ <nil key="secondItem"/>
+ <int key="secondAttribute">0</int>
+ <float key="multiplier">1</float>
+ <object class="IBLayoutConstant" key="constant">
+ <double key="value">163</double>
+ </object>
+ <float key="priority">1000</float>
+ <int key="scoringType">3</int>
+ <float key="scoringTypeFloat">9</float>
+ <int key="contentType">1</int>
+ <reference key="containingView" ref="1018085422"/>
+ </object>
+ </array>
+ <reference key="parent" ref="439893737"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">594</int>
+ <reference key="object" ref="867418359"/>
+ <reference key="parent" ref="1018085422"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">727</int>
+ <reference key="object" ref="688522420"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="445379790"/>
+ <object class="IBNSLayoutConstraint" id="337680523">
+ <reference key="firstItem" ref="688522420"/>
+ <int key="firstAttribute">7</int>
+ <int key="relation">0</int>
+ <nil key="secondItem"/>
+ <int key="secondAttribute">0</int>
+ <float key="multiplier">1</float>
+ <object class="IBLayoutConstant" key="constant">
+ <double key="value">183</double>
+ </object>
+ <float key="priority">1000</float>
+ <int key="scoringType">3</int>
+ <float key="scoringTypeFloat">9</float>
+ <int key="contentType">1</int>
+ <reference key="containingView" ref="688522420"/>
+ </object>
+ <object class="IBNSLayoutConstraint" id="73036966">
+ <reference key="firstItem" ref="688522420"/>
+ <int key="firstAttribute">8</int>
+ <int key="relation">0</int>
+ <nil key="secondItem"/>
+ <int key="secondAttribute">0</int>
+ <float key="multiplier">1</float>
+ <object class="IBLayoutConstant" key="constant">
+ <double key="value">22</double>
+ </object>
+ <float key="priority">1000</float>
+ <int key="scoringType">3</int>
+ <float key="scoringTypeFloat">9</float>
+ <int key="contentType">1</int>
+ <reference key="containingView" ref="688522420"/>
+ </object>
+ </array>
+ <reference key="parent" ref="439893737"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">728</int>
+ <reference key="object" ref="445379790"/>
+ <reference key="parent" ref="688522420"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">775</int>
+ <reference key="object" ref="93467784"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="623922320"/>
+ </array>
+ <reference key="parent" ref="439893737"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">776</int>
+ <reference key="object" ref="623922320"/>
+ <reference key="parent" ref="93467784"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">780</int>
+ <reference key="object" ref="46276252"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="398179500"/>
+ <object class="IBNSLayoutConstraint" id="944606221">
+ <reference key="firstItem" ref="46276252"/>
+ <int key="firstAttribute">7</int>
+ <int key="relation">0</int>
+ <nil key="secondItem"/>
+ <int key="secondAttribute">0</int>
+ <float key="multiplier">1</float>
+ <object class="IBLayoutConstant" key="constant">
+ <double key="value">100</double>
+ </object>
+ <float key="priority">1000</float>
+ <int key="scoringType">3</int>
+ <float key="scoringTypeFloat">9</float>
+ <int key="contentType">1</int>
+ <reference key="containingView" ref="46276252"/>
+ </object>
+ </array>
+ <reference key="parent" ref="439893737"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">781</int>
+ <reference key="object" ref="398179500"/>
+ <reference key="parent" ref="46276252"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">884</int>
+ <reference key="object" ref="109434655"/>
+ <reference key="parent" ref="439893737"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">981</int>
+ <reference key="object" ref="229833409"/>
+ <reference key="parent" ref="439893737"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">982</int>
+ <reference key="object" ref="992363278"/>
+ <reference key="parent" ref="439893737"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">1022</int>
+ <reference key="object" ref="98217052"/>
+ <reference key="parent" ref="439893737"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">1026</int>
+ <reference key="object" ref="276483890"/>
+ <reference key="parent" ref="1018085422"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">979</int>
+ <reference key="object" ref="166525974"/>
+ <reference key="parent" ref="439893737"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">985</int>
+ <reference key="object" ref="646866003"/>
+ <reference key="parent" ref="439893737"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">977</int>
+ <reference key="object" ref="697106875"/>
+ <reference key="parent" ref="242877095"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">1099</int>
+ <reference key="object" ref="337680523"/>
+ <reference key="parent" ref="688522420"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">1093</int>
+ <reference key="object" ref="578918264"/>
+ <reference key="parent" ref="439893737"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">1100</int>
+ <reference key="object" ref="73036966"/>
+ <reference key="parent" ref="688522420"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">1098</int>
+ <reference key="object" ref="432526715"/>
+ <reference key="parent" ref="439893737"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">1168</int>
+ <reference key="object" ref="670714078"/>
+ <reference key="parent" ref="439893737"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">1167</int>
+ <reference key="object" ref="833183002"/>
+ <reference key="parent" ref="439893737"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">1095</int>
+ <reference key="object" ref="591594339"/>
+ <reference key="parent" ref="439893737"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">1166</int>
+ <reference key="object" ref="891430181"/>
+ <reference key="parent" ref="439893737"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">1076</int>
+ <reference key="object" ref="944606221"/>
+ <reference key="parent" ref="46276252"/>
+ </object>
+ </array>
+ </object>
+ <dictionary class="NSMutableDictionary" key="flattenedProperties">
+ <string key="-1.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="-2.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="-3.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="1022.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="1026.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="1076.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="1093.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="1095.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="1098.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="1099.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="1100.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="112.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="1166.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="1167.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="1168.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="124.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="125.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="126.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="129.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="130.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="131.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="134.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="136.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="143.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="144.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="145.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="149.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="150.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="19.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="195.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="196.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="197.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="198.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="199.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="200.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="201.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="202.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="203.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="204.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="205.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="206.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="207.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="208.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="209.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="210.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="211.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="212.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="213.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="214.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="215.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="216.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="217.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="218.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="219.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="220.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="221.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="23.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="236.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="239.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="24.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="29.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="295.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="296.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="297.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="298.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="346.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="348.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="349.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="350.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="351.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="354.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="371.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="371.IBWindowTemplateEditedContentRect">{{380, 496}, {480, 360}}</string>
+ <integer value="1" key="371.NSWindowTemplate.visibleAtLaunch"/>
+ <array class="NSMutableArray" key="372.IBNSViewMetadataConstraints">
+ <reference ref="109434655"/>
+ <reference ref="166525974"/>
+ <reference ref="229833409"/>
+ <reference ref="992363278"/>
+ <reference ref="646866003"/>
+ <reference ref="98217052"/>
+ <reference ref="578918264"/>
+ <reference ref="591594339"/>
+ <reference ref="432526715"/>
+ <reference ref="891430181"/>
+ <reference ref="833183002"/>
+ <reference ref="670714078"/>
+ </array>
+ <string key="372.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <reference key="372.IBUserGuides" ref="0"/>
+ <string key="375.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="376.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="377.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="388.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="389.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="390.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="391.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="392.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="393.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="394.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="395.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="396.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="397.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="398.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="399.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="400.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="401.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="402.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="403.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="404.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="405.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="406.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="407.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="408.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="409.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="410.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="411.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="412.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="413.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="414.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="415.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="416.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="417.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="418.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="419.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="450.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="451.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="452.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="453.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="454.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="457.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="459.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="460.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="462.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="465.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="466.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="485.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="490.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="491.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="492.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="494.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="496.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="497.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="498.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="499.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="5.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="500.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="501.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="502.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="503.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="504.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="505.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="506.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="507.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="508.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="509.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="510.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="511.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="512.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="513.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="514.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="515.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="516.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="517.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="534.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <array class="NSMutableArray" key="536.IBNSViewMetadataConstraints">
+ <reference ref="697106875"/>
+ </array>
+ <boolean value="NO" key="536.IBNSViewMetadataTranslatesAutoresizingMaskIntoConstraints"/>
+ <string key="536.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="537.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="56.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="57.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="58.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <array class="NSMutableArray" key="593.IBNSViewMetadataConstraints">
+ <reference ref="276483890"/>
+ </array>
+ <boolean value="NO" key="593.IBNSViewMetadataTranslatesAutoresizingMaskIntoConstraints"/>
+ <string key="593.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="594.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="72.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <array class="NSMutableArray" key="727.IBNSViewMetadataConstraints">
+ <reference ref="337680523"/>
+ <reference ref="73036966"/>
+ </array>
+ <boolean value="NO" key="727.IBNSViewMetadataTranslatesAutoresizingMaskIntoConstraints"/>
+ <string key="727.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="728.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="73.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="74.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="75.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="77.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <boolean value="NO" key="775.IBNSViewMetadataTranslatesAutoresizingMaskIntoConstraints"/>
+ <string key="775.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="776.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="78.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <array class="NSMutableArray" key="780.IBNSViewMetadataConstraints">
+ <reference ref="944606221"/>
+ </array>
+ <boolean value="NO" key="780.IBNSViewMetadataTranslatesAutoresizingMaskIntoConstraints"/>
+ <string key="780.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="781.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="79.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="81.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="82.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="83.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="884.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="92.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="977.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="979.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="981.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="982.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="985.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ </dictionary>
+ <dictionary class="NSMutableDictionary" key="unlocalizedProperties"/>
+ <nil key="activeLocalization"/>
+ <dictionary class="NSMutableDictionary" key="localizations"/>
+ <nil key="sourceID"/>
+ <int key="maxID">1187</int>
+ </object>
+ <object class="IBClassDescriber" key="IBDocument.Classes">
+ <array class="NSMutableArray" key="referencedPartialClassDescriptions">
+ <object class="IBPartialClassDescription">
+ <string key="className">LLCrashLoggerMacDelegate</string>
+ <string key="superclassName">NSObject</string>
+ <dictionary class="NSMutableDictionary" key="actions">
+ <string key="cancel:">id</string>
+ <string key="remember:">id</string>
+ <string key="send:">id</string>
+ </dictionary>
+ <dictionary class="NSMutableDictionary" key="actionInfosByName">
+ <object class="IBActionInfo" key="cancel:">
+ <string key="name">cancel:</string>
+ <string key="candidateClassName">id</string>
+ </object>
+ <object class="IBActionInfo" key="remember:">
+ <string key="name">remember:</string>
+ <string key="candidateClassName">id</string>
+ </object>
+ <object class="IBActionInfo" key="send:">
+ <string key="name">send:</string>
+ <string key="candidateClassName">id</string>
+ </object>
+ </dictionary>
+ <dictionary class="NSMutableDictionary" key="outlets">
+ <string key="crashText">NSTextField</string>
+ <string key="rememberCheck">NSButton</string>
+ <string key="window">NSWindow</string>
+ </dictionary>
+ <dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
+ <object class="IBToOneOutletInfo" key="crashText">
+ <string key="name">crashText</string>
+ <string key="candidateClassName">NSTextField</string>
+ </object>
+ <object class="IBToOneOutletInfo" key="rememberCheck">
+ <string key="name">rememberCheck</string>
+ <string key="candidateClassName">NSButton</string>
+ </object>
+ <object class="IBToOneOutletInfo" key="window">
+ <string key="name">window</string>
+ <string key="candidateClassName">NSWindow</string>
+ </object>
+ </dictionary>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">./Classes/LLCrashLoggerMacDelegate.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSLayoutConstraint</string>
+ <string key="superclassName">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">./Classes/NSLayoutConstraint.h</string>
+ </object>
+ </object>
+ </array>
+ </object>
+ <int key="IBDocument.localizationMode">0</int>
+ <string key="IBDocument.TargetRuntimeIdentifier">IBCocoaFramework</string>
+ <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencies">
+ <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin.macosx</string>
+ <integer value="1070" key="NS.object.0"/>
+ </object>
+ <bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
+ <int key="IBDocument.defaultPropertyAccessControl">3</int>
+ <dictionary class="NSMutableDictionary" key="IBDocument.LastKnownImageSizes">
+ <string key="NSMenuCheckmark">{11, 11}</string>
+ <string key="NSMenuMixedState">{10, 3}</string>
+ <string key="NSSwitch">{15, 15}</string>
+ </dictionary>
+ <bool key="IBDocument.UseAutolayout">YES</bool>
+ </data>
+</archive>
diff --git a/indra/mac_crash_logger/Info.plist b/indra/mac_crash_logger/Info.plist
index f48293e825..2ebed11c3f 100644..100755
--- a/indra/mac_crash_logger/Info.plist
+++ b/indra/mac_crash_logger/Info.plist
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
@@ -10,8 +10,6 @@
<string></string>
<key>CFBundleIconFile</key>
<string></string>
- <key>CFBundleIdentifier</key>
- <string>com.secondlife.indra.crashreporter</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
@@ -22,5 +20,9 @@
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0.0</string>
+ <key>NSMainNibFile</key>
+ <string>CrashReporter</string>
+ <key>NSPrincipalClass</key>
+ <string>NSApplication</string>
</dict>
</plist>
diff --git a/indra/mac_crash_logger/llcrashloggermac.cpp b/indra/mac_crash_logger/llcrashloggermac.cpp
index 8f1c1a2dd0..c5f660ca6e 100644..100755
--- a/indra/mac_crash_logger/llcrashloggermac.cpp
+++ b/indra/mac_crash_logger/llcrashloggermac.cpp
@@ -27,7 +27,6 @@
#include "llcrashloggermac.h"
-#include <Carbon/Carbon.h>
#include <iostream>
#include "indra_constants.h" // CRASH_BEHAVIOR_ASK, CRASH_SETTING_NAME
@@ -38,102 +37,14 @@
#include "lldir.h"
#include "llsdserialize.h"
-#define MAX_LOADSTRING 100
-const char* const SETTINGS_FILE_HEADER = "version";
-const S32 SETTINGS_FILE_VERSION = 101;
-
// Windows Message Handlers
-BOOL gFirstDialog = TRUE; // Are we currently handling the Send/Don't Send dialog?
+BOOL gFirstDialog = TRUE;
LLFILE *gDebugFile = NULL;
-WindowRef gWindow = NULL;
-EventHandlerRef gEventHandler = NULL;
std::string gUserNotes = "";
bool gSendReport = false;
bool gRememberChoice = false;
-IBNibRef nib = NULL;
-
-OSStatus dialogHandler(EventHandlerCallRef handler, EventRef event, void *userdata)
-{
- OSStatus result = eventNotHandledErr;
- OSStatus err;
- UInt32 evtClass = GetEventClass(event);
- UInt32 evtKind = GetEventKind(event);
- if((evtClass == kEventClassCommand) && (evtKind == kEventCommandProcess))
- {
- HICommand cmd;
- err = GetEventParameter(event, kEventParamDirectObject, typeHICommand, NULL, sizeof(cmd), NULL, &cmd);
-
-
-
- if(err == noErr)
- {
- //Get the value of the checkbox
- ControlID id;
- ControlRef checkBox = NULL;
- id.signature = 'remb';
- id.id = 0;
- err = GetControlByID(gWindow, &id, &checkBox);
-
- if(err == noErr)
- {
- if(GetControl32BitValue(checkBox) == kControlCheckBoxCheckedValue)
- {
- gRememberChoice = true;
- }
- else
- {
- gRememberChoice = false;
- }
- }
- switch(cmd.commandID)
- {
- case kHICommandOK:
- {
- char buffer[65535]; /* Flawfinder: ignore */
- Size size = sizeof(buffer) - 1;
- ControlRef textField = NULL;
-
- id.signature = 'text';
- id.id = 0;
-
- err = GetControlByID(gWindow, &id, &textField);
- if(err == noErr)
- {
- // Get the user response text
- err = GetControlData(textField, kControlNoPart, kControlEditTextTextTag, size, (Ptr)buffer, &size);
- }
- if(err == noErr)
- {
- // Make sure the string is terminated.
- buffer[size] = 0;
- gUserNotes = buffer;
-
- llinfos << buffer << llendl;
- }
-
- // Send the report.
-
- QuitAppModalLoopForWindow(gWindow);
- gSendReport = true;
- result = noErr;
- }
- break;
-
- case kHICommandCancel:
- QuitAppModalLoopForWindow(gWindow);
- result = noErr;
- break;
- default:
- result = eventNotHandledErr;
- }
- }
- }
-
- return(result);
-}
-
LLCrashLoggerMac::LLCrashLoggerMac(void)
{
@@ -146,73 +57,16 @@ LLCrashLoggerMac::~LLCrashLoggerMac(void)
bool LLCrashLoggerMac::init(void)
{
bool ok = LLCrashLogger::init();
- if(!ok) return false;
- if(mCrashBehavior != CRASH_BEHAVIOR_ASK) return true;
-
- // Real UI...
- OSStatus err;
-
- err = CreateNibReference(CFSTR("CrashReporter"), &nib);
-
- if(err == noErr)
- {
- err = CreateWindowFromNib(nib, CFSTR("CrashReporter"), &gWindow);
- }
-
- if(err == noErr)
- {
- // Set focus to the edit text area
- ControlRef textField = NULL;
- ControlID id;
-
- id.signature = 'text';
- id.id = 0;
-
- // Don't set err if any of this fails, since it's non-critical.
- if(GetControlByID(gWindow, &id, &textField) == noErr)
- {
- SetKeyboardFocus(gWindow, textField, kControlFocusNextPart);
- }
- }
-
- if(err == noErr)
- {
- ShowWindow(gWindow);
- }
-
- if(err == noErr)
- {
- // Set up an event handler for the window.
- EventTypeSpec handlerEvents[] =
- {
- { kEventClassCommand, kEventCommandProcess }
- };
-
- InstallWindowEventHandler(
- gWindow,
- NewEventHandlerUPP(dialogHandler),
- GetEventTypeCount (handlerEvents),
- handlerEvents,
- 0,
- &gEventHandler);
- }
- return true;
+ return ok;
}
void LLCrashLoggerMac::gatherPlatformSpecificFiles()
{
- updateApplication("Gathering hardware information...");
}
bool LLCrashLoggerMac::mainLoop()
{
- OSStatus err = noErr;
-
- if(err == noErr && mCrashBehavior == CRASH_BEHAVIOR_ASK)
- {
- RunAppModalLoopForWindow(gWindow);
- }
- else if (mCrashBehavior == CRASH_BEHAVIOR_ALWAYS_SEND)
+ if (mCrashBehavior == CRASH_BEHAVIOR_ALWAYS_SEND)
{
gSendReport = true;
}
@@ -227,26 +81,11 @@ bool LLCrashLoggerMac::mainLoop()
{
setUserText(gUserNotes);
sendCrashLogs();
- }
-
- if(gWindow != NULL)
- {
- DisposeWindow(gWindow);
- }
-
- if(nib != NULL)
- {
- DisposeNibReference(nib);
- }
-
+ }
+
return true;
}
-void LLCrashLoggerMac::updateApplication(const std::string& message)
-{
- LLCrashLogger::updateApplication(message);
-}
-
bool LLCrashLoggerMac::cleanup()
{
commonCleanup();
diff --git a/indra/mac_crash_logger/llcrashloggermac.h b/indra/mac_crash_logger/llcrashloggermac.h
index 4b1d235f24..6d8f63ecac 100644..100755
--- a/indra/mac_crash_logger/llcrashloggermac.h
+++ b/indra/mac_crash_logger/llcrashloggermac.h
@@ -38,7 +38,6 @@ public:
~LLCrashLoggerMac(void);
virtual bool init();
virtual bool mainLoop();
- virtual void updateApplication(const std::string& message = LLStringUtil::null);
virtual bool cleanup();
virtual void gatherPlatformSpecificFiles();
};
diff --git a/indra/mac_crash_logger/llcrashloggermacdelegate.h b/indra/mac_crash_logger/llcrashloggermacdelegate.h
new file mode 100755
index 0000000000..c998a8efe2
--- /dev/null
+++ b/indra/mac_crash_logger/llcrashloggermacdelegate.h
@@ -0,0 +1,52 @@
+/**
+ * @file llcrashloggermacdelegate.h
+ * @brief Mac OSX crash logger implementation
+ *
+ * $LicenseInfo:firstyear=2003&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+/*
+#import <Cocoa/Cocoa.h>
+
+@interface LLCrashLoggerMacDelegate : NSObject <NSApplicationDelegate>
+{
+ IBOutlet NSTextField *crashText;
+ IBOutlet NSButton *rememberCheck;
+
+ NSWindow *_window;
+ bool mRemember;
+
+}
+
+- (void)setWindow:(NSWindow *)newWindow;
+- (NSWindow *)window;
+
+- (IBAction)remember:(id)sender;
+- (IBAction)send:(id)sender;
+- (IBAction)cancel:(id)sender;
+
+@property (assign) IBOutlet NSWindow *window;
+
+@end
+*/
+
+
diff --git a/indra/mac_crash_logger/llcrashloggermacdelegate.mm b/indra/mac_crash_logger/llcrashloggermacdelegate.mm
new file mode 100755
index 0000000000..b2af76a47c
--- /dev/null
+++ b/indra/mac_crash_logger/llcrashloggermacdelegate.mm
@@ -0,0 +1,75 @@
+/**
+ * @file llcrashloggermacdelegate.mm
+ * @brief Mac OSX crash logger implementation
+ *
+ * $LicenseInfo:firstyear=2003&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+
+/*
+#import "llcrashloggermacdelegate.h"
+#include <iostream>
+
+extern std::string gUserNotes;
+extern bool gSendReport;
+extern bool gRememberChoice;
+
+@implementation LLCrashLoggerMacDelegate
+
+- (void)setWindow:(NSWindow *)window
+{
+ _window = window;
+}
+
+- (NSWindow *)window
+{
+ return _window;
+}
+
+- (void)dealloc
+{
+ [super dealloc];
+}
+
+std::string* NSToString( NSString *ns_str )
+{
+ return ( new std::string([ns_str UTF8String]) );
+}
+
+- (IBAction)remember:(id)sender
+{
+ gRememberChoice = [rememberCheck state];
+}
+
+- (IBAction)send:(id)sender
+{
+ std::string* user_input = NSToString([crashText stringValue]);
+ gUserNotes = *user_input;
+ gSendReport = true;
+}
+
+- (IBAction)cancel:(id)sender
+{
+ [ _window close];
+}
+@end
+*/ \ No newline at end of file
diff --git a/indra/mac_crash_logger/mac_crash_logger.cpp b/indra/mac_crash_logger/mac_crash_logger.cpp
index 6571b35241..6add74556f 100644..100755
--- a/indra/mac_crash_logger/mac_crash_logger.cpp
+++ b/indra/mac_crash_logger/mac_crash_logger.cpp
@@ -26,11 +26,12 @@
#include "linden_common.h"
#include "llcrashloggermac.h"
+#include "indra_constants.h"
+#include <iostream>
+
int main(int argc, char **argv)
{
- llinfos << "Starting crash reporter." << llendl;
-
LLCrashLoggerMac app;
app.parseCommandOptions(argc, argv);
@@ -39,9 +40,16 @@ int main(int argc, char **argv)
llwarns << "Unable to initialize application." << llendl;
return 1;
}
+ if (app.getCrashBehavior() != CRASH_BEHAVIOR_ALWAYS_SEND)
+ {
+// return NSApplicationMain(argc, (const char **)argv);
+ }
app.mainLoop();
+
app.cleanup();
+
llinfos << "Crash reporter finished normally." << llendl;
+
return 0;
}
diff --git a/indra/mac_updater/AutoUpdater.nib/classes.nib b/indra/mac_updater/AutoUpdater.nib/classes.nib
deleted file mode 100644
index ea58db1189..0000000000
--- a/indra/mac_updater/AutoUpdater.nib/classes.nib
+++ /dev/null
@@ -1,4 +0,0 @@
-{
-IBClasses = ();
-IBVersion = 1;
-}
diff --git a/indra/mac_updater/AutoUpdater.nib/info.nib b/indra/mac_updater/AutoUpdater.nib/info.nib
deleted file mode 100644
index a49a92385b..0000000000
--- a/indra/mac_updater/AutoUpdater.nib/info.nib
+++ /dev/null
@@ -1,14 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
- <key>IBDocumentLocation</key>
- <string>103 138 356 240 0 0 1280 1002 </string>
- <key>IBFramework Version</key>
- <string>362.0</string>
- <key>IBSystem Version</key>
- <string>7D24</string>
- <key>targetFramework</key>
- <string>IBCarbonFramework</string>
-</dict>
-</plist>
diff --git a/indra/mac_updater/AutoUpdater.nib/objects.xib b/indra/mac_updater/AutoUpdater.nib/objects.xib
deleted file mode 100644
index 310411b711..0000000000
--- a/indra/mac_updater/AutoUpdater.nib/objects.xib
+++ /dev/null
@@ -1,56 +0,0 @@
-<?xml version="1.0" standalone="yes"?>
-<object class="NSIBObjectData">
- <string name="targetFramework">IBCarbonFramework</string>
- <object name="rootObject" class="NSCustomObject" id="1">
- <string name="customClass">NSApplication</string>
- </object>
- <array count="5" name="allObjects">
- <object class="IBCarbonWindow" id="166">
- <string name="windowRect">405 222 533 663 </string>
- <string name="title">Second Life Updater</string>
- <object name="rootControl" class="IBCarbonRootControl" id="167">
- <string name="bounds">0 0 128 441 </string>
- <array count="3" name="subviews">
- <object class="IBCarbonStaticText" id="181">
- <string name="bounds">20 20 44 421 </string>
- <ostype name="controlSignature">what</ostype>
- <string name="title">Initializing…</string>
- </object>
- <object class="IBCarbonButton" id="183">
- <string name="bounds">88 351 108 421 </string>
- <string name="title">Cancel</string>
- <ostype name="command">not!</ostype>
- <int name="buttonType">2</int>
- </object>
- <object class="IBCarbonProgressBar" id="193">
- <string name="bounds">51 19 70 422 </string>
- <ostype name="controlSignature">prog</ostype>
- <int name="initialValue">50</int>
- </object>
- </array>
- </object>
- <boolean name="isResizable">FALSE</boolean>
- <int name="carbonWindowClass">2</int>
- <int name="themeBrush">3</int>
- <int name="windowPosition">7</int>
- </object>
- <reference idRef="167"/>
- <reference idRef="181"/>
- <reference idRef="183"/>
- <reference idRef="193"/>
- </array>
- <array count="5" name="allParents">
- <reference idRef="1"/>
- <reference idRef="166"/>
- <reference idRef="167"/>
- <reference idRef="167"/>
- <reference idRef="167"/>
- </array>
- <dictionary count="2" name="nameTable">
- <string>File&apos;s Owner</string>
- <reference idRef="1"/>
- <string>Updater</string>
- <reference idRef="166"/>
- </dictionary>
- <unsigned_int name="nextObjectID">194</unsigned_int>
-</object>
diff --git a/indra/mac_updater/CMakeLists.txt b/indra/mac_updater/CMakeLists.txt
deleted file mode 100644
index 00dcedecaa..0000000000
--- a/indra/mac_updater/CMakeLists.txt
+++ /dev/null
@@ -1,73 +0,0 @@
-# -*- cmake -*-
-
-project(mac_updater)
-
-include(00-Common)
-include(OpenSSL)
-include(CURL)
-include(CARes)
-include(LLCommon)
-include(LLVFS)
-include(Linking)
-
-include_directories(
- ${LLCOMMON_INCLUDE_DIRS}
- ${LLVFS_INCLUDE_DIRS}
- ${CURL_INCLUDE_DIRS}
- ${CARES_INCLUDE_DIRS}
- )
-
-set(mac_updater_SOURCE_FILES
- mac_updater.cpp
- )
-
-set(mac_updater_HEADER_FILES
- CMakeLists.txt
- )
-
-set_source_files_properties(${mac_updater_HEADER_FILES}
- PROPERTIES HEADER_FILE_ONLY TRUE)
-
-list(APPEND mac_updater_SOURCE_FILES ${mac_updater_HEADER_FILES})
-
-
-set(mac_updater_RESOURCE_FILES
- AutoUpdater.nib/
- )
-set_source_files_properties(
- ${mac_updater_RESOURCE_FILES}
- PROPERTIES
- HEADER_FILE_ONLY TRUE
- )
-SOURCE_GROUP("Resources" FILES ${mac_updater_RESOURCE_FILES})
-list(APPEND mac_updater_SOURCE_FILES ${mac_updater_RESOURCE_FILES})
-
-add_executable(mac-updater
- MACOSX_BUNDLE
- ${mac_updater_SOURCE_FILES})
-
-set_target_properties(mac-updater
- PROPERTIES
- MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist
- )
-
-target_link_libraries(mac-updater
- ${LLVFS_LIBRARIES}
- ${OPENSSL_LIBRARIES}
- ${CRYPTO_LIBRARIES}
- ${CURL_LIBRARIES}
- ${CARES_LIBRARIES}
- ${LLCOMMON_LIBRARIES}
- )
-
-add_custom_command(
- TARGET mac-updater POST_BUILD
- COMMAND ${CMAKE_COMMAND}
- ARGS
- -E
- copy_directory
- ${CMAKE_CURRENT_SOURCE_DIR}/AutoUpdater.nib
- ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/mac-updater.app/Contents/Resources/AutoUpdater.nib
- )
-
-ll_deploy_sharedlibs_command(mac-updater)
diff --git a/indra/mac_updater/Info.plist b/indra/mac_updater/Info.plist
deleted file mode 100644
index bb27fddb03..0000000000
--- a/indra/mac_updater/Info.plist
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
- <key>CFBundleDevelopmentRegion</key>
- <string>English</string>
- <key>CFBundleExecutable</key>
- <string>mac-updater</string>
- <key>CFBundleGetInfoString</key>
- <string></string>
- <key>CFBundleIconFile</key>
- <string></string>
- <key>CFBundleIdentifier</key>
- <string>com.secondlife.indra.autoupdater</string>
- <key>CFBundleInfoDictionaryVersion</key>
- <string>6.0</string>
- <key>CFBundlePackageType</key>
- <string>APPL</string>
- <key>CFBundleShortVersionString</key>
- <string></string>
- <key>CFBundleSignature</key>
- <string>????</string>
- <key>CFBundleVersion</key>
- <string>1.0.0</string>
-</dict>
-</plist>
diff --git a/indra/mac_updater/mac_updater.cpp b/indra/mac_updater/mac_updater.cpp
index 809f66cb1d..f533d47b18 100644
--- a/indra/mac_updater/mac_updater.cpp
+++ b/indra/mac_updater/mac_updater.cpp
@@ -47,6 +47,11 @@
#include "llerrorcontrol.h"
+#if LL_DARWIN
+// FSPathMakeRef, FSObjectCopy, deprecations...
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#endif
+
enum
{
kEventClassCustom = 'Cust',
@@ -1188,9 +1193,7 @@ void *updatethreadproc(void*)
llinfos << "Clearing cache..." << llendl;
- char mask[LL_MAX_PATH]; /* Flawfinder: ignore */
- snprintf(mask, LL_MAX_PATH, "%s*.*", gDirUtilp->getDirDelimiter().c_str());
- gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE,""),mask);
+ gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE,""), "*.*");
llinfos << "Clear complete." << llendl;
@@ -1257,3 +1260,7 @@ void *updatethreadproc(void*)
return(NULL);
}
+
+#if LL_DARWIN
+#pragma GCC diagnostic warning "-Wdeprecated-declarations"
+#endif
diff --git a/indra/media_plugins/CMakeLists.txt b/indra/media_plugins/CMakeLists.txt
index 85318aea3b..85318aea3b 100644..100755
--- a/indra/media_plugins/CMakeLists.txt
+++ b/indra/media_plugins/CMakeLists.txt
diff --git a/indra/media_plugins/base/CMakeLists.txt b/indra/media_plugins/base/CMakeLists.txt
index 3ad94b0c64..7367b9e5e6 100644..100755
--- a/indra/media_plugins/base/CMakeLists.txt
+++ b/indra/media_plugins/base/CMakeLists.txt
@@ -11,7 +11,7 @@ include(LLRender)
include(LLWindow)
include(Linking)
include(PluginAPI)
-include(FindOpenGL)
+include(OpenGL)
include_directories(
${LLPLUGIN_INCLUDE_DIRS}
@@ -21,6 +21,9 @@ include_directories(
${LLRENDER_INCLUDE_DIRS}
${LLWINDOW_INCLUDE_DIRS}
)
+include_directories(SYSTEM
+ ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+ )
### media_plugin_base
diff --git a/indra/media_plugins/base/media_plugin_base.cpp b/indra/media_plugins/base/media_plugin_base.cpp
index 37c498664a..37c498664a 100644..100755
--- a/indra/media_plugins/base/media_plugin_base.cpp
+++ b/indra/media_plugins/base/media_plugin_base.cpp
diff --git a/indra/media_plugins/base/media_plugin_base.exp b/indra/media_plugins/base/media_plugin_base.exp
index d8c7bb712a..d8c7bb712a 100644..100755
--- a/indra/media_plugins/base/media_plugin_base.exp
+++ b/indra/media_plugins/base/media_plugin_base.exp
diff --git a/indra/media_plugins/base/media_plugin_base.h b/indra/media_plugins/base/media_plugin_base.h
index 38b8226bb3..38b8226bb3 100644..100755
--- a/indra/media_plugins/base/media_plugin_base.h
+++ b/indra/media_plugins/base/media_plugin_base.h
diff --git a/indra/media_plugins/example/CMakeLists.txt b/indra/media_plugins/example/CMakeLists.txt
index 54dc5de1ea..171645ef04 100644..100755
--- a/indra/media_plugins/example/CMakeLists.txt
+++ b/indra/media_plugins/example/CMakeLists.txt
@@ -12,7 +12,7 @@ include(LLWindow)
include(Linking)
include(PluginAPI)
include(MediaPluginBase)
-include(FindOpenGL)
+include(OpenGL)
include(ExamplePlugin)
@@ -25,6 +25,9 @@ include_directories(
${LLRENDER_INCLUDE_DIRS}
${LLWINDOW_INCLUDE_DIRS}
)
+include_directories(SYSTEM
+ ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+ )
### media_plugin_example
diff --git a/indra/media_plugins/example/media_plugin_example.cpp b/indra/media_plugins/example/media_plugin_example.cpp
index da7de01799..da7de01799 100644..100755
--- a/indra/media_plugins/example/media_plugin_example.cpp
+++ b/indra/media_plugins/example/media_plugin_example.cpp
diff --git a/indra/media_plugins/gstreamer010/CMakeLists.txt b/indra/media_plugins/gstreamer010/CMakeLists.txt
index 5786bd1e25..447f6e0689 100644..100755
--- a/indra/media_plugins/gstreamer010/CMakeLists.txt
+++ b/indra/media_plugins/gstreamer010/CMakeLists.txt
@@ -12,7 +12,7 @@ include(LLWindow)
include(Linking)
include(PluginAPI)
include(MediaPluginBase)
-include(FindOpenGL)
+include(OpenGL)
include(GStreamer010Plugin)
@@ -27,6 +27,9 @@ include_directories(
${GSTREAMER010_INCLUDE_DIRS}
${GSTREAMER010_PLUGINS_BASE_INCLUDE_DIRS}
)
+include_directories(SYSTEM
+ ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+ )
### media_plugin_gstreamer010
diff --git a/indra/media_plugins/gstreamer010/llmediaimplgstreamer.h b/indra/media_plugins/gstreamer010/llmediaimplgstreamer.h
index 6bc272c009..6bc272c009 100644..100755
--- a/indra/media_plugins/gstreamer010/llmediaimplgstreamer.h
+++ b/indra/media_plugins/gstreamer010/llmediaimplgstreamer.h
diff --git a/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.cpp b/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.cpp
index 2e4baaa9eb..2e4baaa9eb 100644..100755
--- a/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.cpp
+++ b/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.cpp
diff --git a/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.h b/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.h
index d1559089c8..d1559089c8 100644..100755
--- a/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.h
+++ b/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.h
diff --git a/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms_raw.inc b/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms_raw.inc
index b33e59363d..b33e59363d 100644..100755
--- a/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms_raw.inc
+++ b/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms_raw.inc
diff --git a/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms_rawv.inc b/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms_rawv.inc
index 14fbcb48b9..14fbcb48b9 100644..100755
--- a/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms_rawv.inc
+++ b/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms_rawv.inc
diff --git a/indra/media_plugins/gstreamer010/llmediaimplgstreamertriviallogging.h b/indra/media_plugins/gstreamer010/llmediaimplgstreamertriviallogging.h
index e7b31bec94..e7b31bec94 100644..100755
--- a/indra/media_plugins/gstreamer010/llmediaimplgstreamertriviallogging.h
+++ b/indra/media_plugins/gstreamer010/llmediaimplgstreamertriviallogging.h
diff --git a/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.cpp b/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.cpp
index cdb7f4faeb..932aaffa1b 100644..100755
--- a/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.cpp
+++ b/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.cpp
@@ -278,10 +278,9 @@ gst_slvideo_set_caps (GstBaseSink * bsink, GstCaps * caps)
static gboolean
gst_slvideo_start (GstBaseSink * bsink)
{
- GstSLVideo *slvideo;
gboolean ret = TRUE;
- slvideo = GST_SLVIDEO(bsink);
+ GST_SLVIDEO(bsink);
return ret;
}
diff --git a/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.h b/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.h
index 29d65fa4e9..29d65fa4e9 100644..100755
--- a/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.h
+++ b/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.h
diff --git a/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp b/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp
index 352b63583e..352b63583e 100644..100755
--- a/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp
+++ b/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp
diff --git a/indra/media_plugins/quicktime/CMakeLists.txt b/indra/media_plugins/quicktime/CMakeLists.txt
index f0b8f0d167..58391007ff 100644..100755
--- a/indra/media_plugins/quicktime/CMakeLists.txt
+++ b/indra/media_plugins/quicktime/CMakeLists.txt
@@ -12,7 +12,7 @@ include(LLWindow)
include(Linking)
include(PluginAPI)
include(MediaPluginBase)
-include(FindOpenGL)
+include(OpenGL)
include(QuickTimePlugin)
include_directories(
@@ -24,6 +24,9 @@ include_directories(
${LLRENDER_INCLUDE_DIRS}
${LLWINDOW_INCLUDE_DIRS}
)
+include_directories(SYSTEM
+ ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+ )
if (DARWIN)
include(CMakeFindFrameworks)
diff --git a/indra/media_plugins/quicktime/media_plugin_quicktime.cpp b/indra/media_plugins/quicktime/media_plugin_quicktime.cpp
index 24328202cb..2dd97a9ba7 100644..100755
--- a/indra/media_plugins/quicktime/media_plugin_quicktime.cpp
+++ b/indra/media_plugins/quicktime/media_plugin_quicktime.cpp
@@ -232,12 +232,8 @@ private:
mMovieHandle = NULL;
};
- if ( mGWorldHandle )
- {
- DisposeGWorld( mGWorldHandle );
- mGWorldHandle = NULL;
- };
-
+ mGWorldHandle = NULL;
+
setStatus(STATUS_NONE);
return true;
@@ -273,6 +269,7 @@ private:
//std::cerr << "<--- Sending size change request to application with name: " << mTextureSegmentName << " - size is " << width << " x " << height << std::endl;
}
}
+
// sanitize destination size
Rect dest_rect = rectFromSize(mWidth, mHeight);
@@ -281,12 +278,10 @@ private:
int depth_bits = mDepth * 8;
long rowbytes = mDepth * mTextureWidth;
- GWorldPtr old_gworld_handle = mGWorldHandle;
-
if(mPixels != NULL)
{
// We have pixels. Set up a GWorld pointing at the texture.
- OSErr result = NewGWorldFromPtr( &mGWorldHandle, depth_bits, &dest_rect, NULL, NULL, 0, (Ptr)mPixels, rowbytes);
+ OSErr result = QTNewGWorldFromPtr( &mGWorldHandle, depth_bits, &dest_rect, NULL, NULL, 0, (Ptr)mPixels, rowbytes);
if ( noErr != result )
{
// TODO: unrecoverable?? throw exception? return something?
@@ -297,7 +292,7 @@ private:
{
// We don't have pixels. Create a fake GWorld we can point the movie at when it's not safe to render normally.
Rect tempRect = rectFromSize(1, 1);
- OSErr result = NewGWorld( &mGWorldHandle, depth_bits, &tempRect, NULL, NULL, 0);
+ OSErr result = QTNewGWorld( &mGWorldHandle, depth_bits, &tempRect, NULL, NULL, 0);
if ( noErr != result )
{
// TODO: unrecoverable?? throw exception? return something?
@@ -305,14 +300,8 @@ private:
}
}
- SetMovieGWorld( mMovieHandle, mGWorldHandle, GetGWorldDevice( mGWorldHandle ) );
-
- // If the GWorld was already set up, delete it.
- if(old_gworld_handle != NULL)
- {
- DisposeGWorld( old_gworld_handle );
- }
-
+ SetMovieGWorld( mMovieHandle, mGWorldHandle, NULL );
+
// Set up the movie display matrix
{
// scale movie to fit rect and invert vertically to match opengl image format
@@ -579,28 +568,7 @@ private:
}
};
-
- int getDataWidth() const
- {
- if ( mGWorldHandle )
- {
- int depth = mDepth;
-
- if (depth < 1)
- depth = 1;
-
- // ALWAYS use the row bytes from the PixMap if we have a GWorld because
- // sometimes it's not the same as mMediaDepth * mMediaWidth !
- PixMapHandle pix_map_handle = GetGWorldPixMap( mGWorldHandle );
- return QTGetPixMapHandleRowBytes( pix_map_handle ) / depth;
- }
- else
- {
- // TODO : return LLMediaImplCommon::getaDataWidth();
- return 0;
- }
- };
-
+
void seek( F64 time )
{
if ( mMovieController )
diff --git a/indra/media_plugins/webkit/CMakeLists.txt b/indra/media_plugins/webkit/CMakeLists.txt
index b36291f0e8..0c1c3d800e 100644..100755
--- a/indra/media_plugins/webkit/CMakeLists.txt
+++ b/indra/media_plugins/webkit/CMakeLists.txt
@@ -13,7 +13,7 @@ include(UI)
include(Linking)
include(PluginAPI)
include(MediaPluginBase)
-include(FindOpenGL)
+include(OpenGL)
include(PulseAudio)
include(WebKitLibPlugin)
@@ -29,6 +29,9 @@ include_directories(
${LLWINDOW_INCLUDE_DIRS}
${LLQTWEBKIT_INCLUDE_DIR}
)
+include_directories(SYSTEM
+ ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+ )
### media_plugin_webkit
diff --git a/indra/media_plugins/webkit/dummy_volume_catcher.cpp b/indra/media_plugins/webkit/dummy_volume_catcher.cpp
index d54b31b2ae..d54b31b2ae 100644..100755
--- a/indra/media_plugins/webkit/dummy_volume_catcher.cpp
+++ b/indra/media_plugins/webkit/dummy_volume_catcher.cpp
diff --git a/indra/media_plugins/webkit/linux_volume_catcher.cpp b/indra/media_plugins/webkit/linux_volume_catcher.cpp
index 91be3a89e9..91be3a89e9 100644..100755
--- a/indra/media_plugins/webkit/linux_volume_catcher.cpp
+++ b/indra/media_plugins/webkit/linux_volume_catcher.cpp
diff --git a/indra/media_plugins/webkit/linux_volume_catcher_pa_syms.inc b/indra/media_plugins/webkit/linux_volume_catcher_pa_syms.inc
index d806b48428..d806b48428 100644..100755
--- a/indra/media_plugins/webkit/linux_volume_catcher_pa_syms.inc
+++ b/indra/media_plugins/webkit/linux_volume_catcher_pa_syms.inc
diff --git a/indra/media_plugins/webkit/linux_volume_catcher_paglib_syms.inc b/indra/media_plugins/webkit/linux_volume_catcher_paglib_syms.inc
index abf628c96c..abf628c96c 100644..100755
--- a/indra/media_plugins/webkit/linux_volume_catcher_paglib_syms.inc
+++ b/indra/media_plugins/webkit/linux_volume_catcher_paglib_syms.inc
diff --git a/indra/media_plugins/webkit/mac_volume_catcher.cpp b/indra/media_plugins/webkit/mac_volume_catcher.cpp
index 8a06bb8487..cc94556413 100644..100755
--- a/indra/media_plugins/webkit/mac_volume_catcher.cpp
+++ b/indra/media_plugins/webkit/mac_volume_catcher.cpp
@@ -35,10 +35,13 @@
#include "volume_catcher.h"
-#include <Carbon/Carbon.h>
#include <QuickTime/QuickTime.h>
#include <AudioUnit/AudioUnit.h>
+#if LL_DARWIN
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#endif
+
struct VolumeCatcherStorage;
class VolumeCatcherImpl
@@ -266,3 +269,6 @@ void VolumeCatcher::pump()
// No periodic tasks are necessary for this implementation.
}
+#if LL_DARWIN
+#pragma GCC diagnostic warning "-Wdeprecated-declarations"
+#endif
diff --git a/indra/media_plugins/webkit/media_plugin_webkit.cpp b/indra/media_plugins/webkit/media_plugin_webkit.cpp
index 1812abd7d5..1812abd7d5 100644..100755
--- a/indra/media_plugins/webkit/media_plugin_webkit.cpp
+++ b/indra/media_plugins/webkit/media_plugin_webkit.cpp
diff --git a/indra/media_plugins/webkit/volume_catcher.h b/indra/media_plugins/webkit/volume_catcher.h
index 337f2913d3..337f2913d3 100644..100755
--- a/indra/media_plugins/webkit/volume_catcher.h
+++ b/indra/media_plugins/webkit/volume_catcher.h
diff --git a/indra/media_plugins/webkit/windows_volume_catcher.cpp b/indra/media_plugins/webkit/windows_volume_catcher.cpp
index 5fb84756ee..0cfb810906 100644..100755
--- a/indra/media_plugins/webkit/windows_volume_catcher.cpp
+++ b/indra/media_plugins/webkit/windows_volume_catcher.cpp
@@ -48,18 +48,37 @@ private:
set_volume_func_t mSetVolumeFunc;
set_mute_func_t mSetMuteFunc;
+ // tests if running on Vista, 7, 8 + once in CTOR
+ bool isWindowsVistaOrHigher();
+
F32 mVolume;
F32 mPan;
+ bool mSystemIsVistaOrHigher;
};
+
+bool VolumeCatcherImpl::isWindowsVistaOrHigher()
+{
+ OSVERSIONINFO osvi;
+ ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
+ osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+ GetVersionEx(&osvi);
+ return osvi.dwMajorVersion >= 6;
+}
+
VolumeCatcherImpl::VolumeCatcherImpl()
-: mVolume(1.0f), // default volume is max
- mPan(0.f) // default pan is centered
+: mVolume(1.0f), // default volume is max
+ mPan(0.f) // default pan is centered
{
- HMODULE handle = ::LoadLibrary(L"winmm.dll");
- if(handle)
+ mSystemIsVistaOrHigher = isWindowsVistaOrHigher();
+
+ if ( ! mSystemIsVistaOrHigher )
{
- mSetVolumeFunc = (set_volume_func_t)::GetProcAddress(handle, "setPluginVolume");
- mSetMuteFunc = (set_mute_func_t)::GetProcAddress(handle, "setPluginMute");
+ HMODULE handle = ::LoadLibrary(L"winmm.dll");
+ if(handle)
+ {
+ mSetVolumeFunc = (set_volume_func_t)::GetProcAddress(handle, "setPluginVolume");
+ mSetMuteFunc = (set_mute_func_t)::GetProcAddress(handle, "setPluginMute");
+ }
}
}
@@ -67,18 +86,29 @@ VolumeCatcherImpl::~VolumeCatcherImpl()
{
}
-
void VolumeCatcherImpl::setVolume(F32 volume)
{
mVolume = volume;
- if (mSetMuteFunc)
+ if ( mSystemIsVistaOrHigher )
{
- mSetMuteFunc(volume == 0.f);
+ // set both left/right to same volume
+ // TODO: use pan value to set independently
+ DWORD left_channel = (DWORD)(mVolume * 65535.0f);
+ DWORD right_channel = (DWORD)(mVolume * 65535.0f);
+ DWORD hw_volume = left_channel << 16 | right_channel;
+ ::waveOutSetVolume(NULL, hw_volume);
}
- if (mSetVolumeFunc)
+ else
{
- mSetVolumeFunc(mVolume);
+ if (mSetMuteFunc)
+ {
+ mSetMuteFunc(volume == 0.f);
+ }
+ if (mSetVolumeFunc)
+ {
+ mSetVolumeFunc(mVolume);
+ }
}
}
diff --git a/indra/media_plugins/winmmshim/CMakeLists.txt b/indra/media_plugins/winmmshim/CMakeLists.txt
index bf74f81809..bf74f81809 100644..100755
--- a/indra/media_plugins/winmmshim/CMakeLists.txt
+++ b/indra/media_plugins/winmmshim/CMakeLists.txt
diff --git a/indra/media_plugins/winmmshim/forwarding_api.cpp b/indra/media_plugins/winmmshim/forwarding_api.cpp
index 495e08942b..495e08942b 100644..100755
--- a/indra/media_plugins/winmmshim/forwarding_api.cpp
+++ b/indra/media_plugins/winmmshim/forwarding_api.cpp
diff --git a/indra/media_plugins/winmmshim/forwarding_api.h b/indra/media_plugins/winmmshim/forwarding_api.h
index 076a08f769..076a08f769 100644..100755
--- a/indra/media_plugins/winmmshim/forwarding_api.h
+++ b/indra/media_plugins/winmmshim/forwarding_api.h
diff --git a/indra/media_plugins/winmmshim/winmm.def b/indra/media_plugins/winmmshim/winmm.def
index c55a2845f8..c55a2845f8 100644..100755
--- a/indra/media_plugins/winmmshim/winmm.def
+++ b/indra/media_plugins/winmmshim/winmm.def
diff --git a/indra/media_plugins/winmmshim/winmm_shim.cpp b/indra/media_plugins/winmmshim/winmm_shim.cpp
index 47a1e5c018..aac349bf57 100644..100755
--- a/indra/media_plugins/winmmshim/winmm_shim.cpp
+++ b/indra/media_plugins/winmmshim/winmm_shim.cpp
@@ -56,7 +56,7 @@ void ll_winmm_shim_initialize(){
// grab winmm.dll from system path, where it should live
wsprintf(dll_path, "%s\\winmm.dll", system_path);
HMODULE winmm_handle = ::LoadLibrary(dll_path);
-
+
if (winmm_handle != NULL)
{ // we have a dll, let's get out pointers!
initialized = true;
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 9aaefa9c6a..1fea6dea9f 100644..100755
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -10,19 +10,21 @@ include(DirectX)
include(OpenSSL)
include(DragDrop)
include(EXPAT)
-include(FMOD)
+include(FMODEX)
include(OPENAL)
-include(FindOpenGL)
+include(OpenGL)
+include(Hunspell)
include(JsonCpp)
include(LLAudio)
include(LLCharacter)
include(LLCommon)
-include(LLConvexDecomposition)
+include(LLCoreHttp)
include(LLImage)
include(LLImageJ2COJ)
include(LLInventory)
include(LLMath)
include(LLMessage)
+include(LLPhysicsExtensions)
include(LLPlugin)
include(LLPrimitive)
include(LLRender)
@@ -30,10 +32,10 @@ include(LLUI)
include(LLVFS)
include(LLWindow)
include(LLXML)
-include(LLXUIXML)
include(LScript)
include(Linking)
include(NDOF)
+include(NVAPI)
include(GooglePerfTools)
include(TemplateCheck)
include(UI)
@@ -44,6 +46,16 @@ include(LLLogin)
include(VisualLeakDetector)
include(GLOD)
include(CMakeCopyIfDifferent)
+include(LLAppearance)
+
+if (NOT HAVOK_TPV)
+ # When using HAVOK_TPV, the library is precompiled, so no need for this
+ add_subdirectory(${LLPHYSICSEXTENSIONS_SRC_DIR} llphysicsextensions)
+endif (NOT HAVOK_TPV)
+
+if(FMODEX)
+ include_directories(${FMODEX_INCLUDE_DIR})
+endif(FMODEX)
include_directories(
${DBUSGLIB_INCLUDE_DIRS}
@@ -52,8 +64,8 @@ include_directories(
${LLAUDIO_INCLUDE_DIRS}
${LLCHARACTER_INCLUDE_DIRS}
${LLCOMMON_INCLUDE_DIRS}
- ${LLCONVEXDECOMP_INCLUDE_DIRS}
- ${FMOD_INCLUDE_DIR}
+ ${LLCOREHTTP_INCLUDE_DIRS}
+ ${LLPHYSICS_INCLUDE_DIRS}
${LLIMAGE_INCLUDE_DIRS}
${LLKDU_INCLUDE_DIRS}
${LLINVENTORY_INCLUDE_DIRS}
@@ -66,14 +78,22 @@ include_directories(
${LLVFS_INCLUDE_DIRS}
${LLWINDOW_INCLUDE_DIRS}
${LLXML_INCLUDE_DIRS}
- ${LLXUIXML_INCLUDE_DIRS}
${LSCRIPT_INCLUDE_DIRS}
${LSCRIPT_INCLUDE_DIRS}/lscript_compile
${LLLOGIN_INCLUDE_DIRS}
${UPDATER_INCLUDE_DIRS}
${LIBS_PREBUILT_DIR}/include/collada
+ ${LIBS_PREBUILD_DIR}/include/hunspell
${OPENAL_LIB_INCLUDE_DIRS}
${LIBS_PREBUILT_DIR}/include/collada/1.4
+ ${LLAPPEARANCE_INCLUDE_DIRS}
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ )
+
+include_directories(SYSTEM
+ ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+ ${LLXML_SYSTEM_INCLUDE_DIRS}
+ ${LLPHYSICSEXTENSIONS_INCLUDE_DIRS}
)
set(viewer_SOURCE_FILES
@@ -91,6 +111,7 @@ set(viewer_SOURCE_FILES
llagentwearables.cpp
llagentwearablesfetch.cpp
llanimstatelabels.cpp
+ llappcorehttp.cpp
llappearancemgr.cpp
llappviewer.cpp
llappviewerlistener.cpp
@@ -98,17 +119,20 @@ set(viewer_SOURCE_FILES
llassetuploadresponders.cpp
llattachmentsmgr.cpp
llaudiosourcevo.cpp
+ llautoreplace.cpp
llavataractions.cpp
llavatariconctrl.cpp
llavatarlist.cpp
llavatarlistitem.cpp
+ llavatarrenderinfoaccountant.cpp
llavatarpropertiesprocessor.cpp
+ llblockedlistitem.cpp
+ llblocklist.cpp
llbox.cpp
llbreadcrumbview.cpp
llbrowsernotification.cpp
llbuycurrencyhtml.cpp
llcallbacklist.cpp
- llcallfloater.cpp
llcallingcard.cpp
llcapabilitylistener.cpp
llcaphttpsender.cpp
@@ -126,16 +150,24 @@ set(viewer_SOURCE_FILES
llcommanddispatcherlistener.cpp
llcommandhandler.cpp
llcommandlineparser.cpp
+ llcommunicationchannel.cpp
llcompilequeue.cpp
llconfirmationmanager.cpp
+ llconversationlog.cpp
+ llconversationloglist.cpp
+ llconversationloglistitem.cpp
+ llconversationmodel.cpp
+ llconversationview.cpp
llcurrencyuimanager.cpp
llcylinder.cpp
lldateutil.cpp
lldaycyclemanager.cpp
lldebugmessagebox.cpp
lldebugview.cpp
+ lldeferredsounds.cpp
lldelayedgestureerror.cpp
lldirpicker.cpp
+ lldonotdisturbnotificationstorage.cpp
lldndbutton.cpp
lldrawable.cpp
lldrawpool.cpp
@@ -143,13 +175,13 @@ set(viewer_SOURCE_FILES
lldrawpoolavatar.cpp
lldrawpoolbump.cpp
lldrawpoolground.cpp
+ lldrawpoolmaterials.cpp
lldrawpoolsimple.cpp
lldrawpoolsky.cpp
lldrawpoolterrain.cpp
lldrawpooltree.cpp
lldrawpoolwater.cpp
lldrawpoolwlsky.cpp
- lldriverparam.cpp
lldynamictexture.cpp
llemote.cpp
llenvmanager.cpp
@@ -159,6 +191,7 @@ set(viewer_SOURCE_FILES
llexpandabletextbox.cpp
llexternaleditor.cpp
llface.cpp
+ llfacebookconnect.cpp
llfasttimerview.cpp
llfavoritesbar.cpp
llfeaturemanager.cpp
@@ -169,6 +202,7 @@ set(viewer_SOURCE_FILES
llfloaterabout.cpp
llfloaterbvhpreview.cpp
llfloaterauction.cpp
+ llfloaterautoreplacesettings.cpp
llfloateravatar.cpp
llfloateravatarpicker.cpp
llfloateravatartextures.cpp
@@ -182,7 +216,10 @@ set(viewer_SOURCE_FILES
llfloaterbuycurrencyhtml.cpp
llfloaterbuyland.cpp
llfloatercamera.cpp
+ llfloaterchatvoicevolume.cpp
llfloatercolorpicker.cpp
+ llfloaterconversationlog.cpp
+ llfloaterconversationpreview.cpp
llfloaterdeleteenvpreset.cpp
llfloaterdestinations.cpp
llfloaterdisplayname.cpp
@@ -194,6 +231,7 @@ set(viewer_SOURCE_FILES
llfloaterfonttest.cpp
llfloatergesture.cpp
llfloatergodtools.cpp
+ llfloatergotoline.cpp
llfloatergroupinvite.cpp
llfloatergroups.cpp
llfloaterhandler.cpp
@@ -212,12 +250,15 @@ set(viewer_SOURCE_FILES
llfloatermemleak.cpp
llfloatermodelpreview.cpp
llfloatermodeluploadbase.cpp
- llfloatermodelwizard.cpp
llfloaternamedesc.cpp
llfloaternotificationsconsole.cpp
llfloaterobjectweights.cpp
llfloateropenobject.cpp
llfloateroutbox.cpp
+ llfloaterpathfindingcharacters.cpp
+ llfloaterpathfindingconsole.cpp
+ llfloaterpathfindinglinksets.cpp
+ llfloaterpathfindingobjects.cpp
llfloaterpay.cpp
llfloaterperms.cpp
llfloaterpostprocess.cpp
@@ -233,10 +274,13 @@ set(viewer_SOURCE_FILES
llfloatersettingsdebug.cpp
llfloatersidepanelcontainer.cpp
llfloatersnapshot.cpp
+ llfloatersocial.cpp
llfloatersounddevices.cpp
+ llfloaterspellchecksettings.cpp
llfloatertelehub.cpp
llfloatertestinspectors.cpp
llfloatertestlistview.cpp
+ llfloatertexturefetchdebugger.cpp
llfloatertools.cpp
llfloatertopobjects.cpp
llfloatertos.cpp
@@ -245,13 +289,13 @@ set(viewer_SOURCE_FILES
llfloateruipreview.cpp
llfloaterurlentry.cpp
llfloatervoiceeffect.cpp
+ llfloatervoicevolume.cpp
llfloaterwebcontent.cpp
llfloaterwebprofile.cpp
llfloaterwhitelistentry.cpp
llfloaterwindowsize.cpp
llfloaterworldmap.cpp
- llfolderview.cpp
- llfolderviewitem.cpp
+ llfolderviewmodelinventory.cpp
llfollowcam.cpp
llfriendcard.cpp
llgesturelistener.cpp
@@ -262,6 +306,7 @@ set(viewer_SOURCE_FILES
llgroupiconctrl.cpp
llgrouplist.cpp
llgroupmgr.cpp
+ llhasheduniqueid.cpp
llhints.cpp
llhomelocationresponder.cpp
llhudeffect.cpp
@@ -277,8 +322,9 @@ set(viewer_SOURCE_FILES
llhudrender.cpp
llhudtext.cpp
llhudview.cpp
- llimfloater.cpp
- llimfloatercontainer.cpp
+ llfloaterimsessiontab.cpp
+ llfloaterimsession.cpp
+ llfloaterimcontainer.cpp
llimhandler.cpp
llimview.cpp
llinspect.cpp
@@ -304,7 +350,6 @@ set(viewer_SOURCE_FILES
lllistcontextmenu.cpp
lllistview.cpp
lllocalbitmaps.cpp
- lllocaltextureobject.cpp
lllocationhistory.cpp
lllocationinputctrl.cpp
lllogchat.cpp
@@ -318,9 +363,10 @@ set(viewer_SOURCE_FILES
llmaniptranslate.cpp
llmarketplacefunctions.cpp
llmarketplacenotifications.cpp
+ llmaterialmgr.cpp
llmediactrl.cpp
llmediadataclient.cpp
- llmemoryview.cpp
+ llmenuoptionpathfindingrebakenavmesh.cpp
llmeshrepository.cpp
llmimetypes.cpp
llmorphview.cpp
@@ -330,10 +376,9 @@ set(viewer_SOURCE_FILES
llnameeditor.cpp
llnamelistctrl.cpp
llnavigationbar.cpp
- llnearbychat.cpp
- llnearbychatbar.cpp
- llnearbychathandler.cpp
- llnearbychatbarlistener.cpp
+ llfloaterimnearbychat.cpp
+ llfloaterimnearbychathandler.cpp
+ llfloaterimnearbychatlistener.cpp
llnetmap.cpp
llnotificationalerthandler.cpp
llnotificationgrouphandler.cpp
@@ -363,7 +408,6 @@ set(viewer_SOURCE_FILES
llpanelgroupnotices.cpp
llpanelgrouproles.cpp
llpanelhome.cpp
- llpanelimcontrolpanel.cpp
llpanelland.cpp
llpanellandaudio.cpp
llpanellandmarkinfo.cpp
@@ -374,7 +418,6 @@ set(viewer_SOURCE_FILES
llpanelmaininventory.cpp
llpanelmarketplaceinbox.cpp
llpanelmarketplaceinboxinventory.cpp
- llpanelmarketplaceoutboxinventory.cpp
llpanelmediasettingsgeneral.cpp
llpanelmediasettingspermissions.cpp
llpanelmediasettingssecurity.cpp
@@ -413,13 +456,25 @@ set(viewer_SOURCE_FILES
llparcelselection.cpp
llparticipantlist.cpp
llpatchvertexarray.cpp
+ llpathfindingcharacter.cpp
+ llpathfindingcharacterlist.cpp
+ llpathfindinglinkset.cpp
+ llpathfindinglinksetlist.cpp
+ llpathfindingmanager.cpp
+ llpathfindingnavmesh.cpp
+ llpathfindingnavmeshstatus.cpp
+ llpathfindingnavmeshzone.cpp
+ llpathfindingobject.cpp
+ llpathfindingobjectlist.cpp
+ llpathfindingpathtool.cpp
+ llpersistentnotificationstorage.cpp
llphysicsmotion.cpp
llphysicsshapebuilderutil.cpp
+ llpipelinelistener.cpp
llplacesinventorybridge.cpp
llplacesinventorypanel.cpp
+ llplacesfolderview.cpp
llpopupview.cpp
- llpolymesh.cpp
- llpolymorph.cpp
llpostcard.cpp
llpreview.cpp
llpreviewanim.cpp
@@ -455,6 +510,7 @@ set(viewer_SOURCE_FILES
llsidetraypanelcontainer.cpp
llsky.cpp
llslurl.cpp
+ llsnapshotlivepreview.cpp
llspatialpartition.cpp
llspeakers.cpp
llspeakingindicatormanager.cpp
@@ -470,9 +526,6 @@ set(viewer_SOURCE_FILES
llsyswellwindow.cpp
llteleporthistory.cpp
llteleporthistorystorage.cpp
- lltexglobalcolor.cpp
- lltexlayer.cpp
- lltexlayerparams.cpp
lltextureatlas.cpp
lltextureatlasmanager.cpp
lltexturecache.cpp
@@ -490,6 +543,7 @@ set(viewer_SOURCE_FILES
lltoastnotifypanel.cpp
lltoastpanel.cpp
lltoastscripttextbox.cpp
+ lltoastscriptquestion.cpp
lltool.cpp
lltoolbarview.cpp
lltoolbrush.cpp
@@ -569,18 +623,18 @@ set(viewer_SOURCE_FILES
llviewershadermgr.cpp
llviewerstats.cpp
llviewerstatsrecorder.cpp
+ llviewertexlayer.cpp
llviewertexteditor.cpp
llviewertexture.cpp
llviewertextureanim.cpp
llviewertexturelist.cpp
llviewerthrottle.cpp
- llviewervisualparam.cpp
+ llviewerwearable.cpp
llviewerwindow.cpp
llviewerwindowlistener.cpp
llvlcomposition.cpp
llvlmanager.cpp
llvoavatar.cpp
- llvoavatardefines.cpp
llvoavatarself.cpp
llvocache.cpp
llvograss.cpp
@@ -601,10 +655,8 @@ set(viewer_SOURCE_FILES
llwatchdog.cpp
llwaterparammanager.cpp
llwaterparamset.cpp
- llwearable.cpp
llwearableitemslist.cpp
llwearablelist.cpp
- llwearabletype.cpp
llweb.cpp
llwebprofile.cpp
llwebsharing.cpp
@@ -646,6 +698,7 @@ set(viewer_HEADER_FILES
llagentwearables.h
llagentwearablesfetch.h
llanimstatelabels.h
+ llappcorehttp.h
llappearance.h
llappearancemgr.h
llappviewer.h
@@ -654,16 +707,19 @@ set(viewer_HEADER_FILES
llassetuploadresponders.h
llattachmentsmgr.h
llaudiosourcevo.h
+ llautoreplace.h
llavataractions.h
llavatariconctrl.h
llavatarlist.h
llavatarlistitem.h
llavatarpropertiesprocessor.h
+ llavatarrenderinfoaccountant.h
+ llblockedlistitem.h
+ llblocklist.h
llbox.h
llbreadcrumbview.h
llbuycurrencyhtml.h
llcallbacklist.h
- llcallfloater.h
llcallingcard.h
llcapabilitylistener.h
llcapabilityprovider.h
@@ -682,22 +738,31 @@ set(viewer_HEADER_FILES
llcommanddispatcherlistener.h
llcommandhandler.h
llcommandlineparser.h
+ llcommunicationchannel.h
llcompilequeue.h
llconfirmationmanager.h
+ llconversationlog.h
+ llconversationloglist.h
+ llconversationloglistitem.h
+ llconversationmodel.h
+ llconversationview.h
llcurrencyuimanager.h
llcylinder.h
lldateutil.h
lldaycyclemanager.h
lldebugmessagebox.h
lldebugview.h
+ lldeferredsounds.h
lldelayedgestureerror.h
lldirpicker.h
+ lldonotdisturbnotificationstorage.h
lldndbutton.h
lldrawable.h
lldrawpool.h
lldrawpoolalpha.h
lldrawpoolavatar.h
lldrawpoolbump.h
+ lldrawpoolmaterials.h
lldrawpoolground.h
lldrawpoolsimple.h
lldrawpoolsky.h
@@ -705,7 +770,6 @@ set(viewer_HEADER_FILES
lldrawpooltree.h
lldrawpoolwater.h
lldrawpoolwlsky.h
- lldriverparam.h
lldynamictexture.h
llemote.h
llenvmanager.h
@@ -715,6 +779,7 @@ set(viewer_HEADER_FILES
llexpandabletextbox.h
llexternaleditor.h
llface.h
+ llfacebookconnect.h
llfasttimerview.h
llfavoritesbar.h
llfeaturemanager.h
@@ -725,6 +790,7 @@ set(viewer_HEADER_FILES
llfloaterabout.h
llfloaterbvhpreview.h
llfloaterauction.h
+ llfloaterautoreplacesettings.h
llfloateravatar.h
llfloateravatarpicker.h
llfloateravatartextures.h
@@ -738,7 +804,10 @@ set(viewer_HEADER_FILES
llfloaterbuycurrencyhtml.h
llfloaterbuyland.h
llfloatercamera.h
+ llfloaterchatvoicevolume.h
llfloatercolorpicker.h
+ llfloaterconversationlog.h
+ llfloaterconversationpreview.h
llfloaterdeleteenvpreset.h
llfloaterdestinations.h
llfloaterdisplayname.h
@@ -750,6 +819,7 @@ set(viewer_HEADER_FILES
llfloaterfonttest.h
llfloatergesture.h
llfloatergodtools.h
+ llfloatergotoline.h
llfloatergroupinvite.h
llfloatergroups.h
llfloaterhandler.h
@@ -768,12 +838,15 @@ set(viewer_HEADER_FILES
llfloatermemleak.h
llfloatermodelpreview.h
llfloatermodeluploadbase.h
- llfloatermodelwizard.h
llfloaternamedesc.h
llfloaternotificationsconsole.h
llfloaterobjectweights.h
llfloateropenobject.h
llfloateroutbox.h
+ llfloaterpathfindingcharacters.h
+ llfloaterpathfindingconsole.h
+ llfloaterpathfindinglinksets.h
+ llfloaterpathfindingobjects.h
llfloaterpay.h
llfloaterperms.h
llfloaterpostprocess.h
@@ -789,10 +862,13 @@ set(viewer_HEADER_FILES
llfloatersettingsdebug.h
llfloatersidepanelcontainer.h
llfloatersnapshot.h
+ llfloatersocial.h
llfloatersounddevices.h
+ llfloaterspellchecksettings.h
llfloatertelehub.h
llfloatertestinspectors.h
llfloatertestlistview.h
+ llfloatertexturefetchdebugger.h
llfloatertools.h
llfloatertopobjects.h
llfloatertos.h
@@ -801,14 +877,13 @@ set(viewer_HEADER_FILES
llfloateruipreview.h
llfloaterurlentry.h
llfloatervoiceeffect.h
+ llfloatervoicevolume.h
llfloaterwebcontent.h
llfloaterwebprofile.h
llfloaterwhitelistentry.h
llfloaterwindowsize.h
llfloaterworldmap.h
- llfolderview.h
- llfoldervieweventlistener.h
- llfolderviewitem.h
+ llfolderviewmodelinventory.h
llfollowcam.h
llfriendcard.h
llgesturelistener.h
@@ -818,6 +893,7 @@ set(viewer_HEADER_FILES
llgroupiconctrl.h
llgrouplist.h
llgroupmgr.h
+ llhasheduniqueid.h
llhints.h
llhomelocationresponder.h
llhudeffect.h
@@ -833,8 +909,9 @@ set(viewer_HEADER_FILES
llhudrender.h
llhudtext.h
llhudview.h
- llimfloater.h
- llimfloatercontainer.h
+ llfloaterimsessiontab.h
+ llfloaterimsession.h
+ llfloaterimcontainer.h
llimview.h
llinspect.h
llinspectavatar.h
@@ -860,7 +937,6 @@ set(viewer_HEADER_FILES
lllistcontextmenu.h
lllistview.h
lllocalbitmaps.h
- lllocaltextureobject.h
lllocationhistory.h
lllocationinputctrl.h
lllogchat.h
@@ -874,9 +950,10 @@ set(viewer_HEADER_FILES
llmaniptranslate.h
llmarketplacefunctions.h
llmarketplacenotifications.h
+ llmaterialmgr.h
llmediactrl.h
llmediadataclient.h
- llmemoryview.h
+ llmenuoptionpathfindingrebakenavmesh.h
llmeshrepository.h
llmimetypes.h
llmorphview.h
@@ -886,10 +963,9 @@ set(viewer_HEADER_FILES
llnameeditor.h
llnamelistctrl.h
llnavigationbar.h
- llnearbychat.h
- llnearbychatbar.h
- llnearbychathandler.h
- llnearbychatbarlistener.h
+ llfloaterimnearbychat.h
+ llfloaterimnearbychathandler.h
+ llfloaterimnearbychatlistener.h
llnetmap.h
llnotificationhandler.h
llnotificationmanager.h
@@ -913,7 +989,6 @@ set(viewer_HEADER_FILES
llpanelgroupnotices.h
llpanelgrouproles.h
llpanelhome.h
- llpanelimcontrolpanel.h
llpanelland.h
llpanellandaudio.h
llpanellandmarkinfo.h
@@ -924,7 +999,6 @@ set(viewer_HEADER_FILES
llpanelmaininventory.h
llpanelmarketplaceinbox.h
llpanelmarketplaceinboxinventory.h
- llpanelmarketplaceoutboxinventory.h
llpanelmediasettingsgeneral.h
llpanelmediasettingspermissions.h
llpanelmediasettingssecurity.h
@@ -958,12 +1032,24 @@ set(viewer_HEADER_FILES
llparcelselection.h
llparticipantlist.h
llpatchvertexarray.h
+ llpathfindingcharacter.h
+ llpathfindingcharacterlist.h
+ llpathfindinglinkset.h
+ llpathfindinglinksetlist.h
+ llpathfindingmanager.h
+ llpathfindingnavmesh.h
+ llpathfindingnavmeshstatus.h
+ llpathfindingnavmeshzone.h
+ llpathfindingobject.h
+ llpathfindingobjectlist.h
+ llpathfindingpathtool.h
+ llpersistentnotificationstorage.h
llphysicsmotion.h
llphysicsshapebuilderutil.h
+ llpipelinelistener.h
llplacesinventorybridge.h
llplacesinventorypanel.h
- llpolymesh.h
- llpolymorph.h
+ llplacesfolderview.h
llpopupview.h
llpostcard.h
llpreview.h
@@ -1001,6 +1087,7 @@ set(viewer_HEADER_FILES
llsidetraypanelcontainer.h
llsky.h
llslurl.h
+ llsnapshotlivepreview.h
llspatialpartition.h
llspeakers.h
llspeakingindicatormanager.h
@@ -1017,9 +1104,6 @@ set(viewer_HEADER_FILES
lltable.h
llteleporthistory.h
llteleporthistorystorage.h
- lltexglobalcolor.h
- lltexlayer.h
- lltexlayerparams.h
lltextureatlas.h
lltextureatlasmanager.h
lltexturecache.h
@@ -1037,6 +1121,7 @@ set(viewer_HEADER_FILES
lltoastnotifypanel.h
lltoastpanel.h
lltoastscripttextbox.h
+ lltoastscriptquestion.h
lltool.h
lltoolbarview.h
lltoolbrush.h
@@ -1117,18 +1202,18 @@ set(viewer_HEADER_FILES
llviewershadermgr.h
llviewerstats.h
llviewerstatsrecorder.h
+ llviewertexlayer.h
llviewertexteditor.h
llviewertexture.h
llviewertextureanim.h
llviewertexturelist.h
llviewerthrottle.h
- llviewervisualparam.h
+ llviewerwearable.h
llviewerwindow.h
llviewerwindowlistener.h
llvlcomposition.h
llvlmanager.h
llvoavatar.h
- llvoavatardefines.h
llvoavatarself.h
llvocache.h
llvograss.h
@@ -1149,10 +1234,8 @@ set(viewer_HEADER_FILES
llwatchdog.h
llwaterparammanager.h
llwaterparamset.h
- llwearable.h
llwearableitemslist.h
llwearablelist.h
- llwearabletype.h
llweb.h
llwebprofile.h
llwebsharing.h
@@ -1179,8 +1262,29 @@ set(viewer_HEADER_FILES
source_group("CMake Rules" FILES ViewerInstall.cmake)
+# the viewer_version.txt file created here is for passing to viewer_manifest
+# the summary.json file is created for the benefit of the TeamCity builds, where
+# it is used to provide descriptive information to the build results page
+add_custom_target(generate_viewer_version ALL
+ COMMAND printf '${VIEWER_SHORT_VERSION}.${VIEWER_VERSION_REVISION}' > ${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt
+ COMMAND printf '{"Type":"viewer","Version":"${VIEWER_SHORT_VERSION}.${VIEWER_VERSION_REVISION}"}' > ${CMAKE_BINARY_DIR}/summary.json
+ COMMENT Generating viewer_version.txt for manifest processing
+ )
+
+set_source_files_properties(
+ llversioninfo.cpp tests/llversioninfo_test.cpp
+ PROPERTIES
+ DEPENDS generate_viewer_version # dummy dependency to force recompile every time
+ COMPILE_DEFINITIONS "${VIEWER_CHANNEL_VERSION_DEFINES}" # see BuildVersion.cmake
+ )
+
if (DARWIN)
LIST(APPEND viewer_SOURCE_FILES llappviewermacosx.cpp)
+ LIST(APPEND viewer_SOURCE_FILES llfilepicker_mac.mm)
+ LIST(APPEND viewer_HEADER_FILES llfilepicker_mac.h)
+
+ # This should be compiled with the viewer.
+ LIST(APPEND viewer_SOURCE_FILES llappdelegate-objc.mm)
find_library(AGL_LIBRARY AGL)
find_library(APPKIT_LIBRARY AppKit)
@@ -1201,7 +1305,7 @@ if (DARWIN)
macview.r
gpu_table.txt
Info-SecondLife.plist
- SecondLife.nib/
+ SecondLife.xib/
# CMake doesn't seem to support Xcode language variants well just yet
English.lproj/InfoPlist.strings
English.lproj/language.txt
@@ -1256,15 +1360,17 @@ if (WINDOWS)
# Replace the icons with the appropriate ones for the channel
# ('test' is the default)
set(ICON_PATH "test")
+ set(VIEWER_MACOSX_PHASE "d")
string(TOLOWER ${VIEWER_CHANNEL} channel_lower)
if(channel_lower MATCHES "^second life release")
set(ICON_PATH "release")
- elseif(channel_lower MATCHES "^second life beta viewer")
+ set(VIEWER_MACOSX_PHASE "f")
+ elseif(channel_lower MATCHES "^second life beta")
set(ICON_PATH "beta")
- elseif(channel_lower MATCHES "^second life development")
- set(ICON_PATH "development")
- elseif(channel_lower MATCHES "project")
+ set(VIEWER_MACOSX_PHASE "b")
+ elseif(channel_lower MATCHES "^second life project")
set(ICON_PATH "project")
+ set(VIEWER_MACOSX_PHASE "a")
endif()
message("Copying icons for ${ICON_PATH}")
execute_process(
@@ -1306,6 +1412,11 @@ if (WINDOWS)
res/lltoolgrab.cur
res/lltoolland.cur
res/lltoolpan.cur
+ res/lltoolpathfinding.cur
+ res/lltoolpathfindingpathend.cur
+ res/lltoolpathfindingpathendadd.cur
+ res/lltoolpathfindingpathstart.cur
+ res/lltoolpathfindingpathstartadd.cur
res/lltoolpipette.cur
res/lltoolrotate.cur
res/lltoolscale.cur
@@ -1328,11 +1439,18 @@ if (WINDOWS)
set_source_files_properties(${viewer_RESOURCE_FILES}
PROPERTIES HEADER_FILE_ONLY TRUE)
+ configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/res/viewerRes.rc
+ ${CMAKE_CURRENT_BINARY_DIR}/viewerRes.rc
+ )
set(viewer_RESOURCE_FILES
- res/viewerRes.rc
+ ${CMAKE_CURRENT_BINARY_DIR}/viewerRes.rc
${viewer_RESOURCE_FILES}
)
+ set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/viewerRes.rc
+ PROPERTIES COMPILE_FLAGS "-I${CMAKE_CURRENT_SOURCE_DIR}/res"
+ )
+
SOURCE_GROUP("Resource Files" FILES ${viewer_RESOURCE_FILES})
if (NOT STANDALONE)
@@ -1467,27 +1585,10 @@ if (OPENAL)
set(LLSTARTUP_COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS} -DLL_OPENAL")
endif (OPENAL)
-if (FMOD)
- set(LLSTARTUP_COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS} -DLL_FMOD")
-
- if (DARWIN)
- set(fmodwrapper_SOURCE_FILES fmodwrapper.cpp)
- add_library(fmodwrapper SHARED ${fmodwrapper_SOURCE_FILES})
- set(fmodwrapper_needed_LIBRARIES ${FMOD_LIBRARY} ${CARBON_LIBRARY})
- set_target_properties(
- fmodwrapper
- PROPERTIES
- BUILD_WITH_INSTALL_RPATH 1
- INSTALL_NAME_DIR "@executable_path/../Resources"
- LINK_FLAGS "-unexported_symbols_list ${CMAKE_CURRENT_SOURCE_DIR}/fmod_hidden_symbols.exp"
- )
- set(FMODWRAPPER_LIBRARY fmodwrapper)
- target_link_libraries(fmodwrapper ${fmodwrapper_needed_LIBRARIES})
- else (DARWIN)
- # fmodwrapper unnecessary on linux or windows
- set(FMODWRAPPER_LIBRARY ${FMOD_LIBRARY})
- endif (DARWIN)
-endif (FMOD)
+if (FMODEX)
+ set(LLSTARTUP_COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS} -DLL_FMODEX")
+ set(FMODWRAPPER_LIBRARY ${FMODEX_LIBRARY})
+endif (FMODEX)
set_source_files_properties(llstartup.cpp PROPERTIES COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS}")
@@ -1502,6 +1603,12 @@ add_executable(${VIEWER_BINARY_NAME}
${viewer_SOURCE_FILES}
)
+if (SDL_FOUND)
+ set_property(TARGET ${VIEWER_BINARY_NAME}
+ PROPERTY COMPILE_DEFINITIONS LL_SDL=1
+ )
+endif (SDL_FOUND)
+
# add package files
file(GLOB EVENT_HOST_SCRIPT_GLOB_LIST
${CMAKE_CURRENT_SOURCE_DIR}/../viewer_components/*.py)
@@ -1514,10 +1621,9 @@ if (WINDOWS)
set_target_properties(${VIEWER_BINARY_NAME}
PROPERTIES
# *TODO -reenable this once we get server usage sorted out
- #LINK_FLAGS "/debug /NODEFAULTLIB:LIBCMT /SUBSYSTEM:WINDOWS /INCLUDE:\"__tcmalloc\""
- LINK_FLAGS "/debug /NODEFAULTLIB:LIBCMT /SUBSYSTEM:WINDOWS /INCLUDE:__tcmalloc"
- LINK_FLAGS_DEBUG "/NODEFAULTLIB:\"LIBCMT;LIBCMTD;MSVCRT\" /INCREMENTAL:NO"
- LINK_FLAGS_RELEASE ""
+ LINK_FLAGS "/debug /NODEFAULTLIB:LIBCMT /SUBSYSTEM:WINDOWS ${TCMALLOC_LINK_FLAGS} /LARGEADDRESSAWARE"
+ LINK_FLAGS_DEBUG "/NODEFAULTLIB:\"LIBCMT;LIBCMTD;MSVCRT\" /INCREMENTAL:NO /LARGEADDRESSAWARE"
+ LINK_FLAGS_RELEASE "/FORCE:MULTIPLE /MAP\"secondlife-bin.MAP\" /OPT:REF /LARGEADDRESSAWARE"
)
if(USE_PRECOMPILED_HEADERS)
set_target_properties(
@@ -1534,7 +1640,7 @@ if (WINDOWS)
# In the meantime, if you have any ideas on how to easily maintain one list, either here or in viewer_manifest.py
# and have the build deps get tracked *please* tell me about it.
- if(USE_GOOGLE_PERFTOOLS)
+ if(USE_TCMALLOC)
# Configure a var for tcmalloc location, if used.
# Note the need to specify multiple names explicitly.
set(GOOGLE_PERF_TOOLS_SOURCE
@@ -1542,7 +1648,7 @@ if (WINDOWS)
${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/libtcmalloc_minimal.dll
${SHARED_LIB_STAGING_DIR}/Debug/libtcmalloc_minimal-debug.dll
)
- endif(USE_GOOGLE_PERFTOOLS)
+ endif(USE_TCMALLOC)
set(COPY_INPUT_DEPENDENCIES
@@ -1563,15 +1669,15 @@ if (WINDOWS)
${SHARED_LIB_STAGING_DIR}/Release/openjpeg.dll
${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/openjpeg.dll
${SHARED_LIB_STAGING_DIR}/Debug/openjpegd.dll
- ${SHARED_LIB_STAGING_DIR}/Release/fmod.dll
- ${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/fmod.dll
- ${SHARED_LIB_STAGING_DIR}/Debug/fmod.dll
${SHARED_LIB_STAGING_DIR}/Release/msvcr100.dll
${SHARED_LIB_STAGING_DIR}/Release/msvcp100.dll
${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/msvcr100.dll
${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/msvcp100.dll
${SHARED_LIB_STAGING_DIR}/Debug/msvcr100d.dll
${SHARED_LIB_STAGING_DIR}/Debug/msvcp100d.dll
+ ${SHARED_LIB_STAGING_DIR}/Release/libhunspell.dll
+ ${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/libhunspell.dll
+ ${SHARED_LIB_STAGING_DIR}/Debug/libhunspell.dll
${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/SLVoice.exe
${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/vivoxsdk.dll
${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/ortp.dll
@@ -1579,6 +1685,7 @@ if (WINDOWS)
${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/zlib1.dll
${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/vivoxplatform.dll
${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/vivoxoal.dll
+ ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/ca-bundle.crt
${GOOGLE_PERF_TOOLS_SOURCE}
${CMAKE_CURRENT_SOURCE_DIR}/licenses-win32.txt
${CMAKE_CURRENT_SOURCE_DIR}/featuretable.txt
@@ -1627,6 +1734,14 @@ if (WINDOWS)
windows-updater
)
+ if (FMODEX)
+ list(APPEND COPY_INPUT_DEPENDENCIES
+ ${SHARED_LIB_STAGING_DIR}/Release/fmodex.dll
+ ${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/fmodex.dll
+ ${SHARED_LIB_STAGING_DIR}/Debug/fmodexL.dll
+ )
+ endif (FMODEX)
+
add_custom_command(
OUTPUT ${CMAKE_CFG_INTDIR}/copy_touched.bat
COMMAND ${PYTHON_EXECUTABLE}
@@ -1639,10 +1754,13 @@ if (WINDOWS)
--configuration=${CMAKE_CFG_INTDIR}
--dest=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}
--grid=${GRID}
+ --channel=${VIEWER_CHANNEL}
+ --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt
--source=${CMAKE_CURRENT_SOURCE_DIR}
--touch=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/copy_touched.bat
DEPENDS
${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py
+ generate_viewer_version
stage_third_party_libs
${COPY_INPUT_DEPENDENCIES}
COMMENT "Performing viewer_manifest copy"
@@ -1701,27 +1819,40 @@ if (WINDOWS)
--build=${CMAKE_CURRENT_BINARY_DIR}
--buildtype=${CMAKE_BUILD_TYPE}
--channel=${VIEWER_CHANNEL}
+ --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt
--configuration=${CMAKE_CFG_INTDIR}
--dest=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}
--grid=${GRID}
- --login_channel=${VIEWER_LOGIN_CHANNEL}
--source=${CMAKE_CURRENT_SOURCE_DIR}
--touch=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/touched.bat
DEPENDS
${VIEWER_BINARY_NAME}
${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py
+ ${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt
${COPY_INPUT_DEPENDENCIES}
)
add_custom_target(package ALL DEPENDS
${CMAKE_CFG_INTDIR}/touched.bat
windows-setup-build-all
+ generate_viewer_version
)
# temporarily disable packaging of event_host until hg subrepos get
# sorted out on the parabuild cluster...
#${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/event_host.tar.bz2)
endif (PACKAGE)
+elseif (DARWIN)
+ set_target_properties(${VIEWER_BINARY_NAME}
+ PROPERTIES
+ LINK_FLAGS_RELEASE "${LINK_FLAGS_RELEASE} -Xlinker -dead_strip -Xlinker -map -Xlinker ${CMAKE_CURRENT_BINARY_DIR}/${VIEWER_BINARY_NAME}.MAP"
+ )
+else (WINDOWS)
+ # Linux
+ set_target_properties(${VIEWER_BINARY_NAME}
+ PROPERTIES
+ LINK_FLAGS_RELEASE "${LINK_FLAGS_RELEASE} -Wl,--Map=${VIEWER_BINARY_NAME}.MAP"
+ )
endif (WINDOWS)
# *NOTE - this list is very sensitive to ordering, test carefully on all
@@ -1746,14 +1877,17 @@ target_link_libraries(${VIEWER_BINARY_NAME}
${LLVFS_LIBRARIES}
${LLWINDOW_LIBRARIES}
${LLXML_LIBRARIES}
- ${LLXUIXML_LIBRARIES}
${LSCRIPT_LIBRARIES}
${LLMATH_LIBRARIES}
+ ${LLCOREHTTP_LIBRARIES}
${LLCOMMON_LIBRARIES}
${NDOF_LIBRARY}
+ ${NVAPI_LIBRARY}
+ ${HUNSPELL_LIBRARY}
${viewer_LIBRARIES}
${BOOST_PROGRAM_OPTIONS_LIBRARY}
${BOOST_REGEX_LIBRARY}
+ ${BOOST_CONTEXT_LIBRARY}
${DBUSGLIB_LIBRARIES}
${OPENGL_LIBRARIES}
${FMODWRAPPER_LIBRARY} # must come after LLAudio
@@ -1769,35 +1903,22 @@ target_link_libraries(${VIEWER_BINARY_NAME}
${OPENSSL_LIBRARIES}
${CRYPTO_LIBRARIES}
${LLLOGIN_LIBRARIES}
- ${LLCONVEXDECOMP_LIBRARY}
+ ${LLPHYSICS_LIBRARIES}
+ ${LLPHYSICSEXTENSIONS_LIBRARIES}
${TCMALLOC_LIBRARIES}
+ ${LLAPPEARANCE_LIBRARIES}
)
-if (USE_KDU)
- target_link_libraries(${VIEWER_BINARY_NAME}
- ${LLKDU_LIBRARIES}
- ${KDU_LIBRARY}
- )
-else (USE_KDU)
- target_link_libraries(${VIEWER_BINARY_NAME}
- ${LLIMAGEJ2COJ_LIBRARIES}
- )
-endif (USE_KDU)
-
-build_version(viewer)
-
set(ARTWORK_DIR ${CMAKE_CURRENT_SOURCE_DIR} CACHE PATH
"Path to artwork files.")
-
if (LINUX)
- set(product SecondLife-${ARCH}-${viewer_VERSION})
+ set(product SecondLife-${ARCH}-${VIEWER_SHORT_VERSION}.${VIEWER_VERSION_REVISION})
# These are the generated targets that are copied to package/
set(COPY_INPUT_DEPENDENCIES
${VIEWER_BINARY_NAME}
linux-crash-logger
- linux-updater
SLPlugin
media_plugin_webkit
media_plugin_gstreamer010
@@ -1814,20 +1935,22 @@ if (LINUX)
--build=${CMAKE_CURRENT_BINARY_DIR}
--buildtype=${CMAKE_BUILD_TYPE}
--channel=${VIEWER_CHANNEL}
+ --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt
--configuration=${CMAKE_CFG_INTDIR}
--dest=${CMAKE_CURRENT_BINARY_DIR}/packaged
--grid=${GRID}
--installer_name=${product}
- --login_channel=${VIEWER_LOGIN_CHANNEL}
--source=${CMAKE_CURRENT_SOURCE_DIR}
--touch=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/.${product}.touched
DEPENDS
${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py
+ generate_viewer_version
${COPY_INPUT_DEPENDENCIES}
)
if (PACKAGE)
endif (PACKAGE)
+
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/.${product}.copy_touched
COMMAND ${PYTHON_EXECUTABLE}
@@ -1841,9 +1964,12 @@ if (LINUX)
--configuration=${CMAKE_CFG_INTDIR}
--dest=${CMAKE_CURRENT_BINARY_DIR}/packaged
--grid=${GRID}
+ --channel=${VIEWER_CHANNEL}
+ --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt
--source=${CMAKE_CURRENT_SOURCE_DIR}
DEPENDS
${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py
+ generate_viewer_version
${COPY_INPUT_DEPENDENCIES}
COMMENT "Performing viewer_manifest copy"
)
@@ -1859,19 +1985,30 @@ if (LINUX)
endif (LINUX)
if (DARWIN)
+ # These all get set with PROPERTIES
set(product "Second Life")
+ set(MACOSX_BUNDLE_INFO_STRING "Second Life Viewer")
+ set(MACOSX_BUNDLE_ICON_FILE "secondlife.icns")
+ set(MACOSX_BUNDLE_GUI_IDENTIFIER "com.secondlife.indra.viewer")
+ set(MACOSX_BUNDLE_LONG_VERSION_STRING "${VIEWER_CHANNEL} ${VIEWER_SHORT_VERSION}.${VIEWER_VERSION_REVISION}")
+ set(MACOSX_BUNDLE_BUNDLE_NAME "SecondLife")
+ set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${VIEWER_SHORT_VERSION}")
+ set(MACOSX_BUNDLE_BUNDLE_VERSION "${VIEWER_SHORT_VERSION}${VIEWER_MACOSX_PHASE}${VIEWER_REVISION}")
+ set(MACOSX_BUNDLE_COPYRIGHT "Copyright © Linden Research, Inc. 2007")
+ set(MACOSX_BUNDLE_NSMAIN_NIB_FILE "SecondLife.nib")
+ set(MACOSX_BUNDLE_NSPRINCIPAL_CLASS "NSApplication")
+
set_target_properties(
${VIEWER_BINARY_NAME}
PROPERTIES
OUTPUT_NAME "${product}"
- MACOSX_BUNDLE_INFO_STRING "info string - localize me"
- MACOSX_BUNDLE_ICON_FILE "secondlife.icns"
- MACOSX_BUNDLE_GUI_IDENTIFIER "Second Life"
- MACOSX_BUNDLE_LONG_VERSION_STRING "ververver"
- MACOSX_BUNDLE_BUNDLE_NAME "Second Life"
- MACOSX_BUNDLE_SHORT_VERSION_STRING "asdf"
- MACOSX_BUNDLE_BUNDLE_VERSION "asdf"
- MACOSX_BUNDLE_COPYRIGHT "copyright linden lab 2007 - localize me and run me through a legal wringer"
+ MACOSX_BUNDLE_INFO_PLIST
+ "${CMAKE_CURRENT_SOURCE_DIR}/Info-SecondLife.plist"
+ )
+
+ configure_file(
+ "${CMAKE_CURRENT_SOURCE_DIR}/Info-SecondLife.plist"
+ "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${product}.app/Contents/Info.plist"
)
add_custom_command(
@@ -1886,14 +2023,26 @@ if (DARWIN)
--configuration=${CMAKE_CFG_INTDIR}
--dest=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${product}.app
--grid=${GRID}
+ --channel=${VIEWER_CHANNEL}
+ --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt
--source=${CMAKE_CURRENT_SOURCE_DIR}
- DEPENDS ${VIEWER_BINARY_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py
+ DEPENDS
+ ${VIEWER_BINARY_NAME}
+ ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py
+ generate_viewer_version
)
- add_dependencies(${VIEWER_BINARY_NAME} SLPlugin media_plugin_quicktime media_plugin_webkit mac-updater mac-crash-logger)
+ add_dependencies(${VIEWER_BINARY_NAME} SLPlugin media_plugin_quicktime media_plugin_webkit mac-crash-logger)
+
+ if (ENABLE_SIGNING)
+ set(SIGNING_SETTING "--signature=${SIGNING_IDENTITY}")
+ else (ENABLE_SIGNING)
+ set(SIGNING_SETTING "")
+ endif (ENABLE_SIGNING)
if (PACKAGE)
add_custom_target(package ALL DEPENDS ${VIEWER_BINARY_NAME})
+ add_dependencies(package generate_viewer_version)
add_custom_command(
TARGET package POST_BUILD
@@ -1907,11 +2056,14 @@ if (DARWIN)
--configuration=${CMAKE_CFG_INTDIR}
--dest=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${product}.app
--grid=${GRID}
- --login_channel=${VIEWER_LOGIN_CHANNEL}
+ --channel=${VIEWER_CHANNEL}
+ --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt
--source=${CMAKE_CURRENT_SOURCE_DIR}
--touch=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/.${product}.touched
+ ${SIGNING_SETTING}
DEPENDS
${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py
+ generate_viewer_version
)
endif (PACKAGE)
endif (DARWIN)
@@ -1921,8 +2073,9 @@ if (INSTALL)
endif (INSTALL)
if (PACKAGE)
+ set(SYMBOL_SEARCH_DIRS "")
if (WINDOWS)
- set(VIEWER_DIST_DIR "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}")
+ list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}")
set(VIEWER_SYMBOL_FILE "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/secondlife-symbols-windows.tar.bz2")
# slplugin.exe failing symbols dump - need to debug, might have to do with updated version of google breakpad
# set(VIEWER_EXE_GLOBS "${VIEWER_BINARY_NAME}${CMAKE_EXECUTABLE_SUFFIX} slplugin.exe")
@@ -1931,13 +2084,19 @@ if (PACKAGE)
set(VIEWER_COPY_MANIFEST copy_w_viewer_manifest)
endif (WINDOWS)
if (DARWIN)
- set(VIEWER_DIST_DIR "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${product}.app")
+ list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}")
+ # *TODO: Generate these search dirs in the cmake files related to each binary.
+ list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/llplugin/slplugin/${CMAKE_CFG_INTDIR}")
+ list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/mac_crash_logger/${CMAKE_CFG_INTDIR}")
+ list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/media_plugins/gstreamer010/${CMAKE_CFG_INTDIR}")
+ list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/media_plugins/quicktime/${CMAKE_CFG_INTDIR}")
+ list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/media_plugins/webkit/${CMAKE_CFG_INTDIR}")
set(VIEWER_SYMBOL_FILE "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/secondlife-symbols-darwin.tar.bz2")
- set(VIEWER_EXE_GLOBS "'Second Life' SLPlugin")
+ set(VIEWER_EXE_GLOBS "'Second Life' SLPlugin mac-crash-logger")
set(VIEWER_LIB_GLOB "*.dylib")
endif (DARWIN)
if (LINUX)
- set(VIEWER_DIST_DIR "${CMAKE_CURRENT_BINARY_DIR}/packaged")
+ list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_CURRENT_BINARY_DIR}/packaged")
set(VIEWER_SYMBOL_FILE "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/secondlife-symbols-linux.tar.bz2")
set(VIEWER_EXE_GLOBS "do-not-directly-run-secondlife-bin SLPlugin")
set(VIEWER_LIB_GLOB "*${CMAKE_SHARED_MODULE_SUFFIX}*")
@@ -1957,7 +2116,7 @@ if (PACKAGE)
ARGS
"${CMAKE_CURRENT_SOURCE_DIR}/generate_breakpad_symbols.py"
"${LLBUILD_CONFIG}"
- "${VIEWER_DIST_DIR}"
+ "${SYMBOL_SEARCH_DIRS}"
"${VIEWER_EXE_GLOBS}"
"${VIEWER_LIB_GLOB}"
"${AUTOBUILD_INSTALL_DIR}/bin/dump_syms"
@@ -1989,11 +2148,60 @@ if (LL_TESTS)
)
set_source_files_properties(
+ llworldmap.cpp
+ llworldmipmap.cpp
+ PROPERTIES
+ LL_TEST_ADDITIONAL_SOURCE_FILES
+ tests/llviewertexture_stub.cpp
+ #llviewertexturelist.cpp
+ )
+
+ set_source_files_properties(
lltranslate.cpp
PROPERTIES
LL_TEST_ADDITIONAL_LIBRARIES "${JSONCPP_LIBRARIES}"
)
+ set_source_files_properties(
+ llviewerhelputil.cpp
+ PROPERTIES
+ LL_TEST_ADDITIONAL_LIBRARIES "${BOOST_SYSTEM_LIBRARY}"
+ )
+
+ set_source_files_properties(
+ llremoteparcelrequest.cpp
+ PROPERTIES
+ LL_TEST_ADDITIONAL_LIBRARIES "${BOOST_SYSTEM_LIBRARY}"
+ )
+
+ set_source_files_properties(
+ llworldmap.cpp
+ llworldmipmap.cpp
+ PROPERTIES
+ LL_TEST_ADDITIONAL_SOURCE_FILES
+ tests/llviewertexture_stub.cpp
+ #llviewertexturelist.cpp
+ LL_TEST_ADDITIONAL_LIBRARIES "${BOOST_SYSTEM_LIBRARY}"
+ )
+
+ set_source_files_properties(
+ llmediadataclient.cpp
+ PROPERTIES
+ LL_TEST_ADDITIONAL_LIBRARIES "${LLPRIMITIVE_LIBRARIES}"
+ )
+
+ set_source_files_properties(
+ llagentaccess.cpp
+ PROPERTIES
+ LL_TEST_ADDITIONAL_LIBRARIES "${BOOST_SYSTEM_LIBRARY}"
+ )
+
+ set_source_files_properties(
+ lllogininstance.cpp
+ PROPERTIES
+ LL_TEST_ADDITIONAL_LIBRARIES "${BOOST_SYSTEM_LIBRARY}"
+ )
+
##################################################
# DISABLING PRECOMPILED HEADERS USAGE FOR TESTS
##################################################
diff --git a/indra/newview/English.lproj/InfoPlist.strings b/indra/newview/English.lproj/InfoPlist.strings
index 5c7cacedec..041b8cea0b 100644..100755
--- a/indra/newview/English.lproj/InfoPlist.strings
+++ b/indra/newview/English.lproj/InfoPlist.strings
@@ -2,6 +2,6 @@
CFBundleName = "Second Life";
-CFBundleShortVersionString = "Second Life version 2.1.0.13828";
-CFBundleGetInfoString = "Second Life version 2.1.0.13828, Copyright 2004-2009 Linden Research, Inc.";
+CFBundleShortVersionString = "Second Life version %%VERSION%%";
+CFBundleGetInfoString = "Second Life version %%VERSION%%, Copyright 2004 Linden Research, Inc.";
diff --git a/indra/newview/English.lproj/language.txt b/indra/newview/English.lproj/language.txt
index bc0aa577f9..bc0aa577f9 100644..100755
--- a/indra/newview/English.lproj/language.txt
+++ b/indra/newview/English.lproj/language.txt
diff --git a/indra/newview/German.lproj/language.txt b/indra/newview/German.lproj/language.txt
index c42e816f93..c42e816f93 100644..100755
--- a/indra/newview/German.lproj/language.txt
+++ b/indra/newview/German.lproj/language.txt
diff --git a/indra/newview/Info-SecondLife.plist b/indra/newview/Info-SecondLife.plist
index f7b11b217c..9b8136a827 100644..100755
--- a/indra/newview/Info-SecondLife.plist
+++ b/indra/newview/Info-SecondLife.plist
@@ -5,19 +5,33 @@
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
- <string>Second Life</string>
+ <string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string>
+ <key>CFBundleGetInfoString</key>
+ <string>${MACOSX_BUNDLE_INFO_STRING}</string>
<key>CFBundleIconFile</key>
- <string>secondlife.icns</string>
+ <string>${MACOSX_BUNDLE_ICON_FILE}</string>
<key>CFBundleIdentifier</key>
- <string>com.secondlife.indra.viewer</string>
+ <string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
+ <key>CFBundleLongVersionString</key>
+ <string>${MACOSX_BUNDLE_LONG_VERSION_STRING}</string>
<key>CFBundleName</key>
- <string>Second Life</string>
+ <string>${MACOSX_BUNDLE_BUNDLE_NAME}</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string>
<key>CFBundleSignature</key>
<string>????</string>
+ <key>CFBundleVersion</key>
+ <string>${VIEWER_VERSION_MAJOR}.${VIEWER_VERSION_MINOR}.${VIEWER_VERSION_PATCH}.${VIEWER_VERSION_REVISION}</string>
+ <key>CSResourcesFileMapped</key>
+ <true/>
+ <key>LSRequiresCarbon</key>
+ <true/>
+ <key>NSHumanReadableCopyright</key>
+ <string>${MACOSX_BUNDLE_COPYRIGHT}</string>
<key>CFBundleDocumentTypes</key>
<array>
<dict>
@@ -59,9 +73,9 @@
<true/>
</dict>
</array>
- <key>CFBundleVersion</key>
- <string>2.1.0.13828</string>
- <key>CSResourcesFileMapped</key>
- <true/>
+ <key>NSPrincipalClass</key>
+ <string>${MACOSX_BUNDLE_NSPRINCIPAL_CLASS}</string>
+ <key>NSMainNibFile</key>
+ <string>${MACOSX_BUNDLE_NSMAIN_NIB_FILE}</string>
</dict>
</plist>
diff --git a/indra/newview/Info-SecondLifeVorbis.plist b/indra/newview/Info-SecondLifeVorbis.plist
index 9cb367eec1..9cb367eec1 100644..100755
--- a/indra/newview/Info-SecondLifeVorbis.plist
+++ b/indra/newview/Info-SecondLifeVorbis.plist
diff --git a/indra/newview/Japanese.lproj/language.txt b/indra/newview/Japanese.lproj/language.txt
index c6e3ab6f3c..c6e3ab6f3c 100644..100755
--- a/indra/newview/Japanese.lproj/language.txt
+++ b/indra/newview/Japanese.lproj/language.txt
diff --git a/indra/newview/Korean.lproj/language.txt b/indra/newview/Korean.lproj/language.txt
index b03ec72ee0..b03ec72ee0 100644..100755
--- a/indra/newview/Korean.lproj/language.txt
+++ b/indra/newview/Korean.lproj/language.txt
diff --git a/indra/newview/SecondLife.nib b/indra/newview/SecondLife.nib
new file mode 100644
index 0000000000..8b99b5a770
--- /dev/null
+++ b/indra/newview/SecondLife.nib
Binary files differ
diff --git a/indra/newview/SecondLife.nib/classes.nib b/indra/newview/SecondLife.nib/classes.nib
deleted file mode 100644
index ea58db1189..0000000000
--- a/indra/newview/SecondLife.nib/classes.nib
+++ /dev/null
@@ -1,4 +0,0 @@
-{
-IBClasses = ();
-IBVersion = 1;
-}
diff --git a/indra/newview/SecondLife.nib/info.nib b/indra/newview/SecondLife.nib/info.nib
deleted file mode 100644
index 1b531de104..0000000000
--- a/indra/newview/SecondLife.nib/info.nib
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
- <key>IBDocumentLocation</key>
- <string>85 13 356 240 0 0 1280 1002 </string>
- <key>IBEditorPositions</key>
- <dict>
- <key>29</key>
- <string>27 314 247 44 0 0 1280 1002 </string>
- </dict>
- <key>IBFramework Version</key>
- <string>362.0</string>
- <key>IBOpenObjects</key>
- <array>
- <integer>191</integer>
- </array>
- <key>IBSystem Version</key>
- <string>7D24</string>
- <key>targetFramework</key>
- <string>IBCarbonFramework</string>
-</dict>
-</plist>
diff --git a/indra/newview/SecondLife.nib/objects.xib b/indra/newview/SecondLife.nib/objects.xib
deleted file mode 100644
index b7ff30f2b2..0000000000
--- a/indra/newview/SecondLife.nib/objects.xib
+++ /dev/null
@@ -1,259 +0,0 @@
-<?xml version="1.0" standalone="yes"?>
-<object class="NSIBObjectData">
- <string name="targetFramework">IBCarbonFramework</string>
- <object name="rootObject" class="NSCustomObject" id="1">
- <string name="customClass">NSApplication</string>
- </object>
- <array count="31" name="allObjects">
- <object class="IBCarbonMenu" id="29">
- <string name="title">SecondLife</string>
- <array count="4" name="items">
- <object class="IBCarbonMenuItem" id="182">
- <string name="title">Second Life</string>
- <object name="submenu" class="IBCarbonMenu" id="181">
- <string name="title">Second Life</string>
- <array count="1" name="items">
- <object class="IBCarbonMenuItem" id="183">
- <boolean name="disabled">TRUE</boolean>
- <boolean name="updateSingleItem">TRUE</boolean>
- <string name="title">About Second Life</string>
- <int name="keyEquivalentModifier">0</int>
- <ostype name="command">abou</ostype>
- </object>
- </array>
- <string name="name">_NSAppleMenu</string>
- </object>
- </object>
- <object class="IBCarbonMenuItem" id="127">
- <string name="title">File</string>
- <object name="submenu" class="IBCarbonMenu" id="131">
- <string name="title">File</string>
- </object>
- </object>
- <object class="IBCarbonMenuItem" id="152">
- <string name="title">Edit</string>
- <object name="submenu" class="IBCarbonMenu" id="147">
- <string name="title">Edit</string>
- <array count="10" name="items">
- <object class="IBCarbonMenuItem" id="141">
- <boolean name="updateSingleItem">TRUE</boolean>
- <string name="title">Undo</string>
- <string name="keyEquivalent">z</string>
- <ostype name="command">undo</ostype>
- </object>
- <object class="IBCarbonMenuItem" id="146">
- <boolean name="updateSingleItem">TRUE</boolean>
- <string name="title">Redo</string>
- <string name="keyEquivalent">Z</string>
- <ostype name="command">redo</ostype>
- </object>
- <object class="IBCarbonMenuItem" id="142">
- <boolean name="separator">TRUE</boolean>
- </object>
- <object class="IBCarbonMenuItem" id="143">
- <boolean name="updateSingleItem">TRUE</boolean>
- <string name="title">Cut</string>
- <string name="keyEquivalent">x</string>
- <ostype name="command">cut </ostype>
- </object>
- <object class="IBCarbonMenuItem" id="149">
- <boolean name="updateSingleItem">TRUE</boolean>
- <string name="title">Copy</string>
- <string name="keyEquivalent">c</string>
- <ostype name="command">copy</ostype>
- </object>
- <object class="IBCarbonMenuItem" id="144">
- <boolean name="updateSingleItem">TRUE</boolean>
- <string name="title">Paste</string>
- <string name="keyEquivalent">v</string>
- <ostype name="command">past</ostype>
- </object>
- <object class="IBCarbonMenuItem" id="151">
- <boolean name="updateSingleItem">TRUE</boolean>
- <string name="title">Delete</string>
- <ostype name="command">clea</ostype>
- </object>
- <object class="IBCarbonMenuItem" id="148">
- <boolean name="updateSingleItem">TRUE</boolean>
- <string name="title">Select All</string>
- <string name="keyEquivalent">a</string>
- <ostype name="command">sall</ostype>
- </object>
- <object class="IBCarbonMenuItem" id="188">
- <boolean name="separator">TRUE</boolean>
- </object>
- <object class="IBCarbonMenuItem" id="187">
- <boolean name="updateSingleItem">TRUE</boolean>
- <string name="title">Special Characters…</string>
- <ostype name="command">chrp</ostype>
- </object>
- </array>
- </object>
- </object>
- <object class="IBCarbonMenuItem" id="153">
- <string name="title">Window</string>
- <object name="submenu" class="IBCarbonMenu" id="154">
- <string name="title">Window</string>
- <array count="6" name="items">
- <object class="IBCarbonMenuItem" id="155">
- <boolean name="dynamic">TRUE</boolean>
- <boolean name="updateSingleItem">TRUE</boolean>
- <string name="title">Minimize Window</string>
- <string name="keyEquivalent">m</string>
- <ostype name="command">mini</ostype>
- </object>
- <object class="IBCarbonMenuItem" id="184">
- <boolean name="dynamic">TRUE</boolean>
- <boolean name="updateSingleItem">TRUE</boolean>
- <string name="title">Minimize All Windows</string>
- <string name="keyEquivalent">m</string>
- <int name="keyEquivalentModifier">1572864</int>
- <ostype name="command">mina</ostype>
- </object>
- <object class="IBCarbonMenuItem" id="186">
- <boolean name="updateSingleItem">TRUE</boolean>
- <string name="title">Zoom</string>
- <ostype name="command">zoom</ostype>
- </object>
- <object class="IBCarbonMenuItem" id="156">
- <boolean name="separator">TRUE</boolean>
- </object>
- <object class="IBCarbonMenuItem" id="157">
- <boolean name="dynamic">TRUE</boolean>
- <boolean name="updateSingleItem">TRUE</boolean>
- <string name="title">Bring All to Front</string>
- <ostype name="command">bfrt</ostype>
- </object>
- <object class="IBCarbonMenuItem" id="185">
- <boolean name="dynamic">TRUE</boolean>
- <boolean name="updateSingleItem">TRUE</boolean>
- <string name="title">Arrange in Front</string>
- <int name="keyEquivalentModifier">1572864</int>
- <ostype name="command">frnt</ostype>
- </object>
- </array>
- <string name="name">_NSWindowsMenu</string>
- </object>
- </object>
- </array>
- <string name="name">_NSMainMenu</string>
- </object>
- <reference idRef="127"/>
- <reference idRef="131"/>
- <reference idRef="141"/>
- <reference idRef="142"/>
- <reference idRef="143"/>
- <reference idRef="144"/>
- <reference idRef="146"/>
- <reference idRef="147"/>
- <reference idRef="148"/>
- <reference idRef="149"/>
- <reference idRef="151"/>
- <reference idRef="152"/>
- <reference idRef="153"/>
- <reference idRef="154"/>
- <reference idRef="155"/>
- <reference idRef="156"/>
- <reference idRef="157"/>
- <reference idRef="181"/>
- <reference idRef="182"/>
- <reference idRef="183"/>
- <reference idRef="184"/>
- <reference idRef="185"/>
- <reference idRef="186"/>
- <reference idRef="187"/>
- <reference idRef="188"/>
- <object class="IBCarbonRootControl" id="190">
- <string name="bounds">0 0 482 694 </string>
- <string name="viewFrame">0 0 694 482 </string>
- <array count="2" name="subviews">
- <object class="IBCarbonButton" id="192">
- <string name="bounds">442 604 462 674 </string>
- <string name="viewFrame">604 442 70 20 </string>
- <string name="title">OK</string>
- <ostype name="command">ok </ostype>
- <object name="layoutInfo" class="IBCarbonHILayoutInfo">
- <int name="bindingBottomKind">2</int>
- <int name="bindingRightKind">2</int>
- </object>
- <int name="buttonType">1</int>
- </object>
- <object class="IBCarbonScrollView" id="201">
- <string name="bounds">20 20 422 674 </string>
- <string name="viewFrame">20 20 654 402 </string>
- <array count="1" name="subviews">
- <object class="IBCarbonTextView" id="200">
- <string name="bounds">20 20 422 659 </string>
- <string name="viewFrame">0 0 639 402 </string>
- <ostype name="controlSignature">text</ostype>
- <int name="fontStyle">5</int>
- <boolean name="readOnly">TRUE</boolean>
- </object>
- </array>
- <boolean name="scrollHorizontally">FALSE</boolean>
- </object>
- </array>
- </object>
- <object class="IBCarbonWindow" id="191">
- <string name="windowRect">84 72 566 766 </string>
- <string name="title">Release Notes</string>
- <reference name="rootControl" idRef="190"/>
- <boolean name="receiveUpdates">FALSE</boolean>
- <boolean name="hasCloseBox">FALSE</boolean>
- <boolean name="hasCollapseBox">FALSE</boolean>
- <boolean name="hasHorizontalZoom">FALSE</boolean>
- <boolean name="isResizable">FALSE</boolean>
- <boolean name="hasVerticalZoom">FALSE</boolean>
- <boolean name="liveResize">TRUE</boolean>
- <boolean name="compositing">TRUE</boolean>
- <int name="carbonWindowClass">4</int>
- <int name="windowPosition">1</int>
- <boolean name="isConstrained">FALSE</boolean>
- </object>
- <reference idRef="192"/>
- <reference idRef="200"/>
- <reference idRef="201"/>
- </array>
- <array count="31" name="allParents">
- <reference idRef="1"/>
- <reference idRef="29"/>
- <reference idRef="127"/>
- <reference idRef="147"/>
- <reference idRef="147"/>
- <reference idRef="147"/>
- <reference idRef="147"/>
- <reference idRef="147"/>
- <reference idRef="152"/>
- <reference idRef="147"/>
- <reference idRef="147"/>
- <reference idRef="147"/>
- <reference idRef="29"/>
- <reference idRef="29"/>
- <reference idRef="153"/>
- <reference idRef="154"/>
- <reference idRef="154"/>
- <reference idRef="154"/>
- <reference idRef="182"/>
- <reference idRef="29"/>
- <reference idRef="181"/>
- <reference idRef="154"/>
- <reference idRef="154"/>
- <reference idRef="154"/>
- <reference idRef="147"/>
- <reference idRef="147"/>
- <reference idRef="191"/>
- <reference idRef="1"/>
- <reference idRef="190"/>
- <reference idRef="201"/>
- <reference idRef="190"/>
- </array>
- <dictionary count="3" name="nameTable">
- <string>Files Owner</string>
- <reference idRef="1"/>
- <string>MenuBar</string>
- <reference idRef="29"/>
- <string>Release Notes</string>
- <reference idRef="191"/>
- </dictionary>
- <unsigned_int name="nextObjectID">202</unsigned_int>
-</object>
diff --git a/indra/newview/SecondLife.xib b/indra/newview/SecondLife.xib
new file mode 100644
index 0000000000..370df6bf5f
--- /dev/null
+++ b/indra/newview/SecondLife.xib
@@ -0,0 +1,1136 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<archive type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="8.00">
+ <data>
+ <int key="IBDocument.SystemTarget">1060</int>
+ <string key="IBDocument.SystemVersion">12E55</string>
+ <string key="IBDocument.InterfaceBuilderVersion">4457.6</string>
+ <string key="IBDocument.AppKitVersion">1187.39</string>
+ <string key="IBDocument.HIToolboxVersion">626.00</string>
+ <object class="NSMutableDictionary" key="IBDocument.PluginVersions">
+ <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="NS.object.0">4457.6</string>
+ </object>
+ <array key="IBDocument.IntegratedClassDependencies">
+ <string>NSCustomObject</string>
+ <string>NSMenu</string>
+ <string>NSMenuItem</string>
+ <string>NSScrollView</string>
+ <string>NSScroller</string>
+ <string>NSTextView</string>
+ <string>NSView</string>
+ <string>NSWindowTemplate</string>
+ </array>
+ <array key="IBDocument.PluginDependencies">
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ </array>
+ <object class="NSMutableDictionary" key="IBDocument.Metadata">
+ <string key="NS.key.0">PluginDependencyRecalculationVersion</string>
+ <integer value="1" key="NS.object.0"/>
+ </object>
+ <array class="NSMutableArray" key="IBDocument.RootObjects" id="1048">
+ <object class="NSCustomObject" id="1021">
+ <string key="NSClassName">NSApplication</string>
+ </object>
+ <object class="NSCustomObject" id="1014">
+ <string key="NSClassName">FirstResponder</string>
+ </object>
+ <object class="NSCustomObject" id="1050">
+ <string key="NSClassName">NSApplication</string>
+ </object>
+ <object class="NSMenu" id="649796088">
+ <string key="NSTitle">Main Menu</string>
+ <array class="NSMutableArray" key="NSMenuItems">
+ <object class="NSMenuItem" id="694149608">
+ <reference key="NSMenu" ref="649796088"/>
+ <string key="NSTitle">Second Life</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <object class="NSCustomResource" key="NSOnImage" id="353210768">
+ <string key="NSClassName">NSImage</string>
+ <string key="NSResourceName">NSMenuCheckmark</string>
+ </object>
+ <object class="NSCustomResource" key="NSMixedImage" id="549394948">
+ <string key="NSClassName">NSImage</string>
+ <string key="NSResourceName">NSMenuMixedState</string>
+ </object>
+ <string key="NSAction">submenuAction:</string>
+ <object class="NSMenu" key="NSSubmenu" id="110575045">
+ <string key="NSTitle">Second Life</string>
+ <array class="NSMutableArray" key="NSMenuItems">
+ <object class="NSMenuItem" id="238522557">
+ <reference key="NSMenu" ref="110575045"/>
+ <string key="NSTitle">About Second Life</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ </object>
+ <object class="NSMenuItem" id="304266470">
+ <reference key="NSMenu" ref="110575045"/>
+ <bool key="NSIsDisabled">YES</bool>
+ <bool key="NSIsSeparator">YES</bool>
+ <string key="NSTitle"/>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ </object>
+ <object class="NSMenuItem" id="609285721">
+ <reference key="NSMenu" ref="110575045"/>
+ <string key="NSTitle">Preferences…</string>
+ <string key="NSKeyEquiv">,</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ </object>
+ <object class="NSMenuItem" id="481834944">
+ <reference key="NSMenu" ref="110575045"/>
+ <bool key="NSIsDisabled">YES</bool>
+ <bool key="NSIsSeparator">YES</bool>
+ <string key="NSTitle"/>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ </object>
+ <object class="NSMenuItem" id="1046388886">
+ <reference key="NSMenu" ref="110575045"/>
+ <string key="NSTitle">Services</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ <string key="NSAction">submenuAction:</string>
+ <object class="NSMenu" key="NSSubmenu" id="752062318">
+ <string key="NSTitle">Services</string>
+ <array class="NSMutableArray" key="NSMenuItems"/>
+ <string key="NSName">_NSServicesMenu</string>
+ </object>
+ </object>
+ <object class="NSMenuItem" id="646227648">
+ <reference key="NSMenu" ref="110575045"/>
+ <bool key="NSIsDisabled">YES</bool>
+ <bool key="NSIsSeparator">YES</bool>
+ <string key="NSTitle"/>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ </object>
+ <object class="NSMenuItem" id="755159360">
+ <reference key="NSMenu" ref="110575045"/>
+ <string key="NSTitle">Hide NewApplication</string>
+ <string key="NSKeyEquiv">h</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ </object>
+ <object class="NSMenuItem" id="342932134">
+ <reference key="NSMenu" ref="110575045"/>
+ <string key="NSTitle">Hide Others</string>
+ <string key="NSKeyEquiv">h</string>
+ <int key="NSKeyEquivModMask">1572864</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ </object>
+ <object class="NSMenuItem" id="908899353">
+ <reference key="NSMenu" ref="110575045"/>
+ <string key="NSTitle">Show All</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ </object>
+ <object class="NSMenuItem" id="1056857174">
+ <reference key="NSMenu" ref="110575045"/>
+ <bool key="NSIsDisabled">YES</bool>
+ <bool key="NSIsSeparator">YES</bool>
+ <string key="NSTitle"/>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ </object>
+ <object class="NSMenuItem" id="632727374">
+ <reference key="NSMenu" ref="110575045"/>
+ <string key="NSTitle">Quit Second Life</string>
+ <string key="NSKeyEquiv">q</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ </object>
+ </array>
+ <string key="NSName">_NSAppleMenu</string>
+ </object>
+ </object>
+ <object class="NSMenuItem" id="725688984">
+ <reference key="NSMenu" ref="649796088"/>
+ <string key="NSTitle">Edit</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ <string key="NSAction">submenuAction:</string>
+ <object class="NSMenu" key="NSSubmenu" id="701759256">
+ <string key="NSTitle">Edit</string>
+ <array class="NSMutableArray" key="NSMenuItems">
+ <object class="NSMenuItem" id="521487141">
+ <reference key="NSMenu" ref="701759256"/>
+ <string key="NSTitle">Undo</string>
+ <string key="NSKeyEquiv">z</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ </object>
+ <object class="NSMenuItem" id="668936019">
+ <reference key="NSMenu" ref="701759256"/>
+ <string key="NSTitle">Redo</string>
+ <string key="NSKeyEquiv">Z</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ </object>
+ <object class="NSMenuItem" id="383018193">
+ <reference key="NSMenu" ref="701759256"/>
+ <bool key="NSIsDisabled">YES</bool>
+ <bool key="NSIsSeparator">YES</bool>
+ <string key="NSTitle"/>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ </object>
+ <object class="NSMenuItem" id="984623395">
+ <reference key="NSMenu" ref="701759256"/>
+ <string key="NSTitle">Cut</string>
+ <string key="NSKeyEquiv">x</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ </object>
+ <object class="NSMenuItem" id="656529582">
+ <reference key="NSMenu" ref="701759256"/>
+ <string key="NSTitle">Copy</string>
+ <string key="NSKeyEquiv">c</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ </object>
+ <object class="NSMenuItem" id="1032676691">
+ <reference key="NSMenu" ref="701759256"/>
+ <string key="NSTitle">Paste</string>
+ <string key="NSKeyEquiv">v</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ </object>
+ <object class="NSMenuItem" id="538907583">
+ <reference key="NSMenu" ref="701759256"/>
+ <string key="NSTitle">Select All</string>
+ <string key="NSKeyEquiv">a</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ </object>
+ </array>
+ </object>
+ </object>
+ <object class="NSMenuItem" id="713487014">
+ <reference key="NSMenu" ref="649796088"/>
+ <string key="NSTitle">Window</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ <string key="NSAction">submenuAction:</string>
+ <object class="NSMenu" key="NSSubmenu" id="835318025">
+ <string key="NSTitle">Window</string>
+ <array class="NSMutableArray" key="NSMenuItems">
+ <object class="NSMenuItem" id="1011231497">
+ <reference key="NSMenu" ref="835318025"/>
+ <string key="NSTitle">Minimize</string>
+ <string key="NSKeyEquiv">m</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ </object>
+ <object class="NSMenuItem" id="575023229">
+ <reference key="NSMenu" ref="835318025"/>
+ <string key="NSTitle">Zoom</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ </object>
+ <object class="NSMenuItem" id="86356408">
+ <reference key="NSMenu" ref="835318025"/>
+ <string key="NSTitle">Enter Full Screen</string>
+ <string key="NSKeyEquiv">f</string>
+ <int key="NSKeyEquivModMask">1310720</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ </object>
+ <object class="NSMenuItem" id="299356726">
+ <reference key="NSMenu" ref="835318025"/>
+ <bool key="NSIsDisabled">YES</bool>
+ <bool key="NSIsSeparator">YES</bool>
+ <string key="NSTitle"/>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ </object>
+ <object class="NSMenuItem" id="625202149">
+ <reference key="NSMenu" ref="835318025"/>
+ <string key="NSTitle">Bring All to Front</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ </object>
+ </array>
+ <string key="NSName">_NSWindowsMenu</string>
+ </object>
+ </object>
+ <object class="NSMenuItem" id="391199113">
+ <reference key="NSMenu" ref="649796088"/>
+ <string key="NSTitle">Help</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="353210768"/>
+ <reference key="NSMixedImage" ref="549394948"/>
+ </object>
+ </array>
+ <string key="NSName">_NSMainMenu</string>
+ </object>
+ <object class="NSCustomObject" id="756173070">
+ <string key="NSClassName">LLAppDelegate</string>
+ </object>
+ <object class="NSWindowTemplate" id="110292814">
+ <int key="NSWindowStyleMask">15</int>
+ <int key="NSWindowBacking">2</int>
+ <string key="NSWindowRect">{{196, 240}, {1024, 600}}</string>
+ <int key="NSWTFlags">74974208</int>
+ <string key="NSWindowTitle">Second Life</string>
+ <string key="NSWindowClass">LLNSWindow</string>
+ <nil key="NSViewClass"/>
+ <nil key="NSUserInterfaceItemIdentifier"/>
+ <object class="NSView" key="NSWindowView" id="305280978">
+ <reference key="NSNextResponder"/>
+ <int key="NSvFlags">256</int>
+ <array class="NSMutableArray" key="NSSubviews"/>
+ <string key="NSFrameSize">{1024, 600}</string>
+ <reference key="NSSuperview"/>
+ <reference key="NSWindow"/>
+ <string key="NSReuseIdentifierKey">_NS:20</string>
+ </object>
+ <string key="NSScreenRect">{{0, 0}, {2560, 1418}}</string>
+ <string key="NSMaxSize">{10000000000000, 10000000000000}</string>
+ <string key="NSFrameAutosaveName">Second Life</string>
+ <int key="NSWindowCollectionBehavior">128</int>
+ <bool key="NSWindowIsRestorable">YES</bool>
+ </object>
+ <object class="NSWindowTemplate" id="979091056">
+ <int key="NSWindowStyleMask">31</int>
+ <int key="NSWindowBacking">2</int>
+ <string key="NSWindowRect">{{272, 176}, {938, 42}}</string>
+ <int key="NSWTFlags">-1535638528</int>
+ <string key="NSWindowTitle">Input Window</string>
+ <string key="NSWindowClass">LLUserInputWindow</string>
+ <nil key="NSViewClass"/>
+ <nil key="NSUserInterfaceItemIdentifier"/>
+ <object class="NSView" key="NSWindowView" id="1044753903">
+ <reference key="NSNextResponder"/>
+ <int key="NSvFlags">256</int>
+ <array class="NSMutableArray" key="NSSubviews">
+ <object class="NSScrollView" id="238626476">
+ <reference key="NSNextResponder" ref="1044753903"/>
+ <int key="NSvFlags">256</int>
+ <array class="NSMutableArray" key="NSSubviews">
+ <object class="NSClipView" id="871543330">
+ <reference key="NSNextResponder" ref="238626476"/>
+ <int key="NSvFlags">2322</int>
+ <array class="NSMutableArray" key="NSSubviews">
+ <object class="NSTextView" id="395788163">
+ <reference key="NSNextResponder" ref="871543330"/>
+ <int key="NSvFlags">2322</int>
+ <set class="NSMutableSet" key="NSDragTypes">
+ <string>Apple HTML pasteboard type</string>
+ <string>Apple PDF pasteboard type</string>
+ <string>Apple PICT pasteboard type</string>
+ <string>Apple PNG pasteboard type</string>
+ <string>Apple URL pasteboard type</string>
+ <string>CorePasteboardFlavorType 0x6D6F6F76</string>
+ <string>NSColor pasteboard type</string>
+ <string>NSFilenamesPboardType</string>
+ <string>NSStringPboardType</string>
+ <string>NeXT Encapsulated PostScript v1.2 pasteboard type</string>
+ <string>NeXT RTFD pasteboard type</string>
+ <string>NeXT Rich Text Format v1.0 pasteboard type</string>
+ <string>NeXT TIFF v4.0 pasteboard type</string>
+ <string>NeXT font pasteboard type</string>
+ <string>NeXT ruler pasteboard type</string>
+ <string>WebURLsWithTitlesPboardType</string>
+ <string>public.url</string>
+ </set>
+ <string key="NSFrameSize">{938, 42}</string>
+ <reference key="NSSuperview" ref="871543330"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="339833963"/>
+ <string key="NSReuseIdentifierKey">_NS:13</string>
+ <object class="NSTextContainer" key="NSTextContainer" id="648552009">
+ <object class="NSLayoutManager" key="NSLayoutManager">
+ <object class="NSTextStorage" key="NSTextStorage">
+ <object class="NSMutableString" key="NSString">
+ <characters key="NS.bytes"/>
+ </object>
+ <nil key="NSDelegate"/>
+ </object>
+ <array class="NSMutableArray" key="NSTextContainers">
+ <reference ref="648552009"/>
+ </array>
+ <int key="NSLMFlags">166</int>
+ <nil key="NSDelegate"/>
+ </object>
+ <reference key="NSTextView" ref="395788163"/>
+ <double key="NSWidth">938</double>
+ <int key="NSTCFlags">1</int>
+ </object>
+ <object class="NSTextViewSharedData" key="NSSharedData">
+ <int key="NSFlags">67121127</int>
+ <int key="NSTextCheckingTypes">0</int>
+ <nil key="NSMarkedAttributes"/>
+ <object class="NSColor" key="NSBackgroundColor" id="535647664">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MQA</bytes>
+ </object>
+ <dictionary key="NSSelectedAttributes">
+ <object class="NSColor" key="NSBackgroundColor">
+ <int key="NSColorSpace">6</int>
+ <string key="NSCatalogName">System</string>
+ <string key="NSColorName">selectedTextBackgroundColor</string>
+ <object class="NSColor" key="NSColor">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MC42NjY2NjY2NjY3AA</bytes>
+ </object>
+ </object>
+ <object class="NSColor" key="NSColor">
+ <int key="NSColorSpace">6</int>
+ <string key="NSCatalogName">System</string>
+ <string key="NSColorName">selectedTextColor</string>
+ <object class="NSColor" key="NSColor" id="835883401">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MAA</bytes>
+ </object>
+ </object>
+ </dictionary>
+ <reference key="NSInsertionColor" ref="835883401"/>
+ <dictionary key="NSLinkAttributes">
+ <object class="NSColor" key="NSColor">
+ <int key="NSColorSpace">1</int>
+ <bytes key="NSRGB">MCAwIDEAA</bytes>
+ </object>
+ <object class="NSCursor" key="NSCursor">
+ <string key="NSHotSpot">{8, -8}</string>
+ <int key="NSCursorType">13</int>
+ </object>
+ <integer value="1" key="NSUnderline"/>
+ </dictionary>
+ <nil key="NSDefaultParagraphStyle"/>
+ <nil key="NSTextFinder"/>
+ <int key="NSPreferredTextFinderStyle">1</int>
+ </object>
+ <int key="NSTVFlags">6</int>
+ <string key="NSMaxSize">{939, 10000000}</string>
+ <nil key="NSDelegate"/>
+ </object>
+ </array>
+ <string key="NSFrame">{{1, 1}, {938, 42}}</string>
+ <reference key="NSSuperview" ref="238626476"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="395788163"/>
+ <string key="NSReuseIdentifierKey">_NS:11</string>
+ <reference key="NSDocView" ref="395788163"/>
+ <reference key="NSBGColor" ref="535647664"/>
+ <object class="NSCursor" key="NSCursor">
+ <string key="NSHotSpot">{4, 5}</string>
+ <object class="NSImage" key="NSImage">
+ <int key="NSImageFlags">79691776</int>
+ <array key="NSReps">
+ <array>
+ <integer value="5"/>
+ <object class="NSURL">
+ <nil key="NS.base"/>
+ <string key="NS.relative">file://localhost/Applications/Xcode.app/Contents/SharedFrameworks/DVTKit.framework/Resources/DVTIbeamCursor.tiff</string>
+ </object>
+ </array>
+ </array>
+ <object class="NSColor" key="NSColor">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MCAwAA</bytes>
+ </object>
+ </object>
+ </object>
+ <int key="NScvFlags">4</int>
+ </object>
+ <object class="NSScroller" id="339833963">
+ <reference key="NSNextResponder" ref="238626476"/>
+ <int key="NSvFlags">256</int>
+ <string key="NSFrame">{{923, 1}, {16, 42}}</string>
+ <reference key="NSSuperview" ref="238626476"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView"/>
+ <string key="NSReuseIdentifierKey">_NS:83</string>
+ <bool key="NSAllowsLogicalLayoutDirection">NO</bool>
+ <reference key="NSTarget" ref="238626476"/>
+ <string key="NSAction">_doScroller:</string>
+ <double key="NSPercent">0.96666666666666667</double>
+ </object>
+ <object class="NSScroller" id="1067057765">
+ <reference key="NSNextResponder" ref="238626476"/>
+ <int key="NSvFlags">-2147483392</int>
+ <string key="NSFrame">{{-100, -100}, {87, 18}}</string>
+ <reference key="NSSuperview" ref="238626476"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="871543330"/>
+ <string key="NSReuseIdentifierKey">_NS:33</string>
+ <bool key="NSAllowsLogicalLayoutDirection">NO</bool>
+ <int key="NSsFlags">1</int>
+ <reference key="NSTarget" ref="238626476"/>
+ <string key="NSAction">_doScroller:</string>
+ <double key="NSCurValue">1</double>
+ <double key="NSPercent">0.94565218687057495</double>
+ </object>
+ </array>
+ <string key="NSFrame">{{-1, -1}, {940, 44}}</string>
+ <reference key="NSSuperview" ref="1044753903"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="1067057765"/>
+ <string key="NSReuseIdentifierKey">_NS:9</string>
+ <int key="NSsFlags">133138</int>
+ <reference key="NSVScroller" ref="339833963"/>
+ <reference key="NSHScroller" ref="1067057765"/>
+ <reference key="NSContentView" ref="871543330"/>
+ <double key="NSMinMagnification">0.25</double>
+ <double key="NSMaxMagnification">4</double>
+ <double key="NSMagnification">1</double>
+ </object>
+ </array>
+ <string key="NSFrameSize">{938, 42}</string>
+ <reference key="NSSuperview"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="238626476"/>
+ <string key="NSReuseIdentifierKey">_NS:21</string>
+ </object>
+ <string key="NSScreenRect">{{0, 0}, {2560, 1418}}</string>
+ <string key="NSMaxSize">{10000000000000, 10000000000000}</string>
+ <bool key="NSWindowIsRestorable">YES</bool>
+ </object>
+ </array>
+ <object class="IBObjectContainer" key="IBDocument.Objects">
+ <array class="NSMutableArray" key="connectionRecords">
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">terminate:</string>
+ <reference key="source" ref="1050"/>
+ <reference key="destination" ref="632727374"/>
+ </object>
+ <int key="connectionID">823</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">orderFrontStandardAboutPanel:</string>
+ <reference key="source" ref="1021"/>
+ <reference key="destination" ref="238522557"/>
+ </object>
+ <int key="connectionID">142</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBOutletConnection" key="connection">
+ <string key="label">delegate</string>
+ <reference key="source" ref="1021"/>
+ <reference key="destination" ref="756173070"/>
+ </object>
+ <int key="connectionID">845</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">performMiniaturize:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="1011231497"/>
+ </object>
+ <int key="connectionID">37</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">arrangeInFront:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="625202149"/>
+ </object>
+ <int key="connectionID">39</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">performZoom:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="575023229"/>
+ </object>
+ <int key="connectionID">240</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">hide:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="755159360"/>
+ </object>
+ <int key="connectionID">369</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">hideOtherApplications:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="342932134"/>
+ </object>
+ <int key="connectionID">370</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">unhideAllApplications:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="908899353"/>
+ </object>
+ <int key="connectionID">372</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">cut:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="984623395"/>
+ </object>
+ <int key="connectionID">768</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">paste:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="1032676691"/>
+ </object>
+ <int key="connectionID">769</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">undo:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="521487141"/>
+ </object>
+ <int key="connectionID">776</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">copy:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="656529582"/>
+ </object>
+ <int key="connectionID">782</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">selectAll:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="538907583"/>
+ </object>
+ <int key="connectionID">785</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">toggleFullScreen:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="86356408"/>
+ </object>
+ <int key="connectionID">842</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBOutletConnection" key="connection">
+ <string key="label">window</string>
+ <reference key="source" ref="756173070"/>
+ <reference key="destination" ref="110292814"/>
+ </object>
+ <int key="connectionID">850</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBOutletConnection" key="connection">
+ <string key="label">inputWindow</string>
+ <reference key="source" ref="756173070"/>
+ <reference key="destination" ref="979091056"/>
+ </object>
+ <int key="connectionID">953</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBOutletConnection" key="connection">
+ <string key="label">inputView</string>
+ <reference key="source" ref="756173070"/>
+ <reference key="destination" ref="395788163"/>
+ </object>
+ <int key="connectionID">954</int>
+ </object>
+ </array>
+ <object class="IBMutableOrderedSet" key="objectRecords">
+ <array key="orderedObjects">
+ <object class="IBObjectRecord">
+ <int key="objectID">0</int>
+ <array key="object" id="0"/>
+ <reference key="children" ref="1048"/>
+ <nil key="parent"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">-2</int>
+ <reference key="object" ref="1021"/>
+ <reference key="parent" ref="0"/>
+ <string key="objectName">File's Owner</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">-1</int>
+ <reference key="object" ref="1014"/>
+ <reference key="parent" ref="0"/>
+ <string key="objectName">First Responder</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">-3</int>
+ <reference key="object" ref="1050"/>
+ <reference key="parent" ref="0"/>
+ <string key="objectName">Application</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">29</int>
+ <reference key="object" ref="649796088"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="713487014"/>
+ <reference ref="694149608"/>
+ <reference ref="391199113"/>
+ <reference ref="725688984"/>
+ </array>
+ <reference key="parent" ref="0"/>
+ <string key="objectName">Main Menu</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">19</int>
+ <reference key="object" ref="713487014"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="835318025"/>
+ </array>
+ <reference key="parent" ref="649796088"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">56</int>
+ <reference key="object" ref="694149608"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="110575045"/>
+ </array>
+ <reference key="parent" ref="649796088"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">103</int>
+ <reference key="object" ref="391199113"/>
+ <array class="NSMutableArray" key="children"/>
+ <reference key="parent" ref="649796088"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">57</int>
+ <reference key="object" ref="110575045"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="238522557"/>
+ <reference ref="755159360"/>
+ <reference ref="908899353"/>
+ <reference ref="632727374"/>
+ <reference ref="646227648"/>
+ <reference ref="609285721"/>
+ <reference ref="481834944"/>
+ <reference ref="304266470"/>
+ <reference ref="1046388886"/>
+ <reference ref="1056857174"/>
+ <reference ref="342932134"/>
+ </array>
+ <reference key="parent" ref="694149608"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">58</int>
+ <reference key="object" ref="238522557"/>
+ <reference key="parent" ref="110575045"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">134</int>
+ <reference key="object" ref="755159360"/>
+ <reference key="parent" ref="110575045"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">150</int>
+ <reference key="object" ref="908899353"/>
+ <reference key="parent" ref="110575045"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">136</int>
+ <reference key="object" ref="632727374"/>
+ <reference key="parent" ref="110575045"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">144</int>
+ <reference key="object" ref="646227648"/>
+ <reference key="parent" ref="110575045"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">129</int>
+ <reference key="object" ref="609285721"/>
+ <reference key="parent" ref="110575045"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">143</int>
+ <reference key="object" ref="481834944"/>
+ <reference key="parent" ref="110575045"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">236</int>
+ <reference key="object" ref="304266470"/>
+ <reference key="parent" ref="110575045"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">131</int>
+ <reference key="object" ref="1046388886"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="752062318"/>
+ </array>
+ <reference key="parent" ref="110575045"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">149</int>
+ <reference key="object" ref="1056857174"/>
+ <reference key="parent" ref="110575045"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">145</int>
+ <reference key="object" ref="342932134"/>
+ <reference key="parent" ref="110575045"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">130</int>
+ <reference key="object" ref="752062318"/>
+ <reference key="parent" ref="1046388886"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">24</int>
+ <reference key="object" ref="835318025"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="299356726"/>
+ <reference ref="625202149"/>
+ <reference ref="575023229"/>
+ <reference ref="1011231497"/>
+ <reference ref="86356408"/>
+ </array>
+ <reference key="parent" ref="713487014"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">92</int>
+ <reference key="object" ref="299356726"/>
+ <reference key="parent" ref="835318025"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">5</int>
+ <reference key="object" ref="625202149"/>
+ <reference key="parent" ref="835318025"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">239</int>
+ <reference key="object" ref="575023229"/>
+ <reference key="parent" ref="835318025"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">23</int>
+ <reference key="object" ref="1011231497"/>
+ <reference key="parent" ref="835318025"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">711</int>
+ <reference key="object" ref="725688984"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="701759256"/>
+ </array>
+ <reference key="parent" ref="649796088"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">712</int>
+ <reference key="object" ref="701759256"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="521487141"/>
+ <reference ref="668936019"/>
+ <reference ref="383018193"/>
+ <reference ref="984623395"/>
+ <reference ref="656529582"/>
+ <reference ref="1032676691"/>
+ <reference ref="538907583"/>
+ </array>
+ <reference key="parent" ref="725688984"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">716</int>
+ <reference key="object" ref="984623395"/>
+ <reference key="parent" ref="701759256"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">717</int>
+ <reference key="object" ref="656529582"/>
+ <reference key="parent" ref="701759256"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">718</int>
+ <reference key="object" ref="1032676691"/>
+ <reference key="parent" ref="701759256"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">721</int>
+ <reference key="object" ref="538907583"/>
+ <reference key="parent" ref="701759256"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">824</int>
+ <reference key="object" ref="756173070"/>
+ <reference key="parent" ref="0"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">841</int>
+ <reference key="object" ref="86356408"/>
+ <reference key="parent" ref="835318025"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">828</int>
+ <reference key="object" ref="110292814"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="305280978"/>
+ </array>
+ <reference key="parent" ref="0"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">829</int>
+ <reference key="object" ref="305280978"/>
+ <array class="NSMutableArray" key="children"/>
+ <reference key="parent" ref="110292814"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">713</int>
+ <reference key="object" ref="521487141"/>
+ <reference key="parent" ref="701759256"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">714</int>
+ <reference key="object" ref="668936019"/>
+ <reference key="parent" ref="701759256"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">715</int>
+ <reference key="object" ref="383018193"/>
+ <reference key="parent" ref="701759256"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">941</int>
+ <reference key="object" ref="979091056"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="1044753903"/>
+ </array>
+ <reference key="parent" ref="0"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">942</int>
+ <reference key="object" ref="1044753903"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="238626476"/>
+ </array>
+ <reference key="parent" ref="979091056"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">943</int>
+ <reference key="object" ref="238626476"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="395788163"/>
+ <reference ref="1067057765"/>
+ <reference ref="339833963"/>
+ </array>
+ <reference key="parent" ref="1044753903"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">944</int>
+ <reference key="object" ref="395788163"/>
+ <reference key="parent" ref="238626476"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">945</int>
+ <reference key="object" ref="1067057765"/>
+ <reference key="parent" ref="238626476"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">946</int>
+ <reference key="object" ref="339833963"/>
+ <reference key="parent" ref="238626476"/>
+ </object>
+ </array>
+ </object>
+ <dictionary class="NSMutableDictionary" key="flattenedProperties">
+ <string key="-1.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="-2.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="-3.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="103.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="129.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="130.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="131.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="134.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="136.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="143.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="144.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="145.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="149.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="150.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="19.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="23.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="236.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="239.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="24.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="29.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="5.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="56.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="57.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="58.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="711.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="712.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="713.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="714.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="715.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="716.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="717.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="718.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="721.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="824.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <boolean value="YES" key="828.IBNSWindowAutoPositionCentersHorizontal"/>
+ <boolean value="YES" key="828.IBNSWindowAutoPositionCentersVertical"/>
+ <string key="828.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <boolean value="YES" key="828.NSWindowTemplate.visibleAtLaunch"/>
+ <string key="829.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="841.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="92.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="941.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <boolean value="NO" key="941.NSWindowTemplate.visibleAtLaunch"/>
+ <string key="942.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="943.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="944.CustomClassName">LLNonInlineTextView</string>
+ <string key="944.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="945.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="946.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ </dictionary>
+ <dictionary class="NSMutableDictionary" key="unlocalizedProperties"/>
+ <nil key="activeLocalization"/>
+ <dictionary class="NSMutableDictionary" key="localizations"/>
+ <nil key="sourceID"/>
+ <int key="maxID">954</int>
+ </object>
+ <object class="IBClassDescriber" key="IBDocument.Classes">
+ <array class="NSMutableArray" key="referencedPartialClassDescriptions">
+ <object class="IBPartialClassDescription">
+ <string key="className">LLAppDelegate</string>
+ <string key="superclassName">NSObject</string>
+ <dictionary class="NSMutableDictionary" key="outlets">
+ <string key="inputView">LLNonInlineTextView</string>
+ <string key="inputWindow">NSWindow</string>
+ <string key="window">LLNSWindow</string>
+ </dictionary>
+ <dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
+ <object class="IBToOneOutletInfo" key="inputView">
+ <string key="name">inputView</string>
+ <string key="candidateClassName">LLNonInlineTextView</string>
+ </object>
+ <object class="IBToOneOutletInfo" key="inputWindow">
+ <string key="name">inputWindow</string>
+ <string key="candidateClassName">NSWindow</string>
+ </object>
+ <object class="IBToOneOutletInfo" key="window">
+ <string key="name">window</string>
+ <string key="candidateClassName">LLNSWindow</string>
+ </object>
+ </dictionary>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">./Classes/LLAppDelegate.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">LLNSWindow</string>
+ <string key="superclassName">NSWindow</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">./Classes/LLNSWindow.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">LLNonInlineTextView</string>
+ <string key="superclassName">NSTextView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">./Classes/LLNonInlineTextView.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">LLUserInputWindow</string>
+ <string key="superclassName">NSPanel</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">./Classes/LLUserInputWindow.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSTextView</string>
+ <dictionary class="NSMutableDictionary" key="actions">
+ <string key="orderFrontSharingServicePicker:">id</string>
+ <string key="toggleQuickLookPreviewPanel:">id</string>
+ </dictionary>
+ <dictionary class="NSMutableDictionary" key="actionInfosByName">
+ <object class="IBActionInfo" key="orderFrontSharingServicePicker:">
+ <string key="name">orderFrontSharingServicePicker:</string>
+ <string key="candidateClassName">id</string>
+ </object>
+ <object class="IBActionInfo" key="toggleQuickLookPreviewPanel:">
+ <string key="name">toggleQuickLookPreviewPanel:</string>
+ <string key="candidateClassName">id</string>
+ </object>
+ </dictionary>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">./Classes/NSTextView.h</string>
+ </object>
+ </object>
+ </array>
+ </object>
+ <int key="IBDocument.localizationMode">0</int>
+ <string key="IBDocument.TargetRuntimeIdentifier">IBCocoaFramework</string>
+ <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencies">
+ <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin.macosx</string>
+ <real value="1060" key="NS.object.0"/>
+ </object>
+ <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDevelopmentDependencies">
+ <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3</string>
+ <integer value="4600" key="NS.object.0"/>
+ </object>
+ <bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
+ <int key="IBDocument.defaultPropertyAccessControl">3</int>
+ <dictionary class="NSMutableDictionary" key="IBDocument.LastKnownImageSizes">
+ <string key="NSMenuCheckmark">{11, 11}</string>
+ <string key="NSMenuMixedState">{10, 3}</string>
+ </dictionary>
+ </data>
+</archive>
diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt
new file mode 100644
index 0000000000..e8b6c77dc9
--- /dev/null
+++ b/indra/newview/VIEWER_VERSION.txt
@@ -0,0 +1 @@
+3.6.11
diff --git a/indra/newview/VertexCache.h b/indra/newview/VertexCache.h
index 0eadad7e01..0eadad7e01 100644..100755
--- a/indra/newview/VertexCache.h
+++ b/indra/newview/VertexCache.h
diff --git a/indra/newview/ViewerInstall.cmake b/indra/newview/ViewerInstall.cmake
index 0b0d3e2adc..0b0d3e2adc 100644..100755
--- a/indra/newview/ViewerInstall.cmake
+++ b/indra/newview/ViewerInstall.cmake
diff --git a/indra/newview/VorbisFramework.h b/indra/newview/VorbisFramework.h
index 874a22fc30..874a22fc30 100644..100755
--- a/indra/newview/VorbisFramework.h
+++ b/indra/newview/VorbisFramework.h
diff --git a/indra/newview/app_settings/CA.pem b/indra/newview/app_settings/CA.pem
index 8c1b9a1f37..8c1b9a1f37 100644..100755
--- a/indra/newview/app_settings/CA.pem
+++ b/indra/newview/app_settings/CA.pem
diff --git a/indra/newview/app_settings/anim.ini b/indra/newview/app_settings/anim.ini
index 63c84e544d..63c84e544d 100644..100755
--- a/indra/newview/app_settings/anim.ini
+++ b/indra/newview/app_settings/anim.ini
diff --git a/indra/newview/app_settings/autoreplace.xml b/indra/newview/app_settings/autoreplace.xml
new file mode 100755
index 0000000000..09d19f7b04
--- /dev/null
+++ b/indra/newview/app_settings/autoreplace.xml
@@ -0,0 +1,8330 @@
+<llsd>
+ <array>
+ <map>
+ <key>name</key>
+ <string>Abbreviations</string>
+ <key>replacements</key>
+ <map>
+ <key>afaic</key>
+ <string>As far as I am concerned</string>
+ <key>afaik</key>
+ <string>As far as I know</string>
+ <key>afk</key>
+ <string>away from keyboard</string>
+ <key>atm</key>
+ <string>at the moment</string>
+ <key>bbiab</key>
+ <string>be back in a bit</string>
+ <key>bbl</key>
+ <string>be back later</string>
+ <key>brb</key>
+ <string>be right back</string>
+ <key>btw</key>
+ <string>by the way</string>
+ <key>fyi</key>
+ <string>For your information</string>
+ <key>fwiw</key>
+ <string>For what its worth</string>
+ <key>gtg</key>
+ <string>got to go</string>
+ <key>idk</key>
+ <string>I don't know</string>
+ <key>iirc</key>
+ <string>if I recall correctly</string>
+ <key>imho</key>
+ <string>in my humble opinion</string>
+ <key>imo</key>
+ <string>in my opinion</string>
+ <key>irl</key>
+ <string>in real life</string>
+ <key>np</key>
+ <string>no problem</string>
+ <key>nsfw</key>
+ <string>not safe for work</string>
+ <key>nvm</key>
+ <string>nevermind</string>
+ <key>tc</key>
+ <string>take care</string>
+ <key>thx</key>
+ <string>thanks</string>
+ <key>ttfn</key>
+ <string>ta-ta for now</string>
+ <key>ttyl</key>
+ <string>talk to you later</string>
+ <key>ty</key>
+ <string>thank you</string>
+ <key>tyvm</key>
+ <string>thank you very much</string>
+ <key>wb</key>
+ <string>welcome back</string>
+ <key>yw</key>
+ <string>you&apos;re welcome</string>
+ <key>yvw</key>
+ <string>you&apos;re very welcome</string>
+ </map>
+ </map>
+ <map>
+ <key>name</key>
+ <string>Spelling Corrections</string>
+ <key>replacements</key>
+ <map>
+ <key>Amercia</key>
+ <string>America</string>
+ <key>Bernouilli</key>
+ <string>Bernoulli</string>
+ <key>Blitzkreig</key>
+ <string>Blitzkrieg</string>
+ <key>Bonnano</key>
+ <string>Bonanno</string>
+ <key>Brasillian</key>
+ <string>Brazilian</string>
+ <key>Britian</key>
+ <string>Britain</string>
+ <key>Brittish</key>
+ <string>British</string>
+ <key>Buddah</key>
+ <string>Buddha</string>
+ <key>Buddist</key>
+ <string>Buddhist</string>
+ <key>Cambrige</key>
+ <string>Cambridge</string>
+ <key>Capetown</key>
+ <string>Cape Town</string>
+ <key>Carmalite</key>
+ <string>Carmelite</string>
+ <key>Carnagie</key>
+ <string>Carnegie</string>
+ <key>Carnagie-Mellon</key>
+ <string>Carnegie-Mellon</string>
+ <key>Carnigie</key>
+ <string>Carnegie</string>
+ <key>Carnigie-Mellon</key>
+ <string>Carnegie-Mellon</string>
+ <key>Carribbean</key>
+ <string>Caribbean</string>
+ <key>Carribean</key>
+ <string>Caribbean</string>
+ <key>Carthagian</key>
+ <string>Carthaginian</string>
+ <key>Cataline</key>
+ <string>Catiline</string>
+ <key>Ceasar</key>
+ <string>Caesar</string>
+ <key>Celcius</key>
+ <string>Celsius</string>
+ <key>Champange</key>
+ <string>Champagne</string>
+ <key>Cincinatti</key>
+ <string>Cincinnati</string>
+ <key>Cincinnatti</key>
+ <string>Cincinnati</string>
+ <key>Conneticut</key>
+ <string>Connecticut</string>
+ <key>Dardenelles</key>
+ <string>Dardanelles</string>
+ <key>Dravadian</key>
+ <string>Dravidian</string>
+ <key>Enlish</key>
+ <string>English</string>
+ <key>Europian</key>
+ <string>European</string>
+ <key>Europians</key>
+ <string>Europeans</string>
+ <key>Eurpean</key>
+ <string>European</string>
+ <key>Eurpoean</key>
+ <string>European</string>
+ <key>Farenheit</key>
+ <string>Fahrenheit</string>
+ <key>Febuary</key>
+ <string>February</string>
+ <key>Feburary</key>
+ <string>February</string>
+ <key>Flemmish</key>
+ <string>Flemish</string>
+ <key>Formalhaut</key>
+ <string>Fomalhaut</string>
+ <key>Foundland</key>
+ <string>Newfoundland</string>
+ <key>Fransiscan</key>
+ <string>Franciscan</string>
+ <key>Fransiscans</key>
+ <string>Franciscans</string>
+ <key>Galations</key>
+ <string>Galatians</string>
+ <key>Gameboy</key>
+ <string>Game Boy</string>
+ <key>Ghandi</key>
+ <string>Gandhi</string>
+ <key>Godounov</key>
+ <string>Godunov</string>
+ <key>Gothenberg</key>
+ <string>Gothenburg</string>
+ <key>Gottleib</key>
+ <string>Gottlieb</string>
+ <key>Guaduloupe</key>
+ <string>Guadalupe</string>
+ <key>Guadulupe</key>
+ <string>Guadalupe</string>
+ <key>Guatamala</key>
+ <string>Guatemala</string>
+ <key>Guatamalan</key>
+ <string>Guatemalan</string>
+ <key>Guilia</key>
+ <string>Giulia</string>
+ <key>Guilio</key>
+ <string>Giulio</string>
+ <key>Guiness</key>
+ <string>Guinness</string>
+ <key>Guiseppe</key>
+ <string>Giuseppe</string>
+ <key>Habsbourg</key>
+ <string>Habsburg</string>
+ <key>Hallowean</key>
+ <string>Halloween</string>
+ <key>Heidelburg</key>
+ <string>Heidelberg</string>
+ <key>Ihaca</key>
+ <string>Ithaca</string>
+ <key>Israelies</key>
+ <string>Israelis</string>
+ <key>Janurary</key>
+ <string>January</string>
+ <key>Januray</key>
+ <string>January</string>
+ <key>Japanes</key>
+ <string>Japanese</string>
+ <key>Johanine</key>
+ <string>Johannine</string>
+ <key>Jospeh</key>
+ <string>Joseph</string>
+ <key>Juadaism</key>
+ <string>Judaism</string>
+ <key>Juadism</key>
+ <string>Judaism</string>
+ <key>Lybia</key>
+ <string>Libya</string>
+ <key>Malcom</key>
+ <string>Malcolm</string>
+ <key>Massachussets</key>
+ <string>Massachusetts</string>
+ <key>Massachussetts</key>
+ <string>Massachusetts</string>
+ <key>Mediteranean</key>
+ <string>Mediterranean</string>
+ <key>Michagan</key>
+ <string>Michigan</string>
+ <key>Misouri</key>
+ <string>Missouri</string>
+ <key>Missisipi</key>
+ <string>Mississippi</string>
+ <key>Missisippi</key>
+ <string>Mississippi</string>
+ <key>Monserrat</key>
+ <string>Montserrat</string>
+ <key>Montnana</key>
+ <string>Montana</string>
+ <key>Morisette</key>
+ <string>Morissette</string>
+ <key>Morrisette</key>
+ <string>Morissette</string>
+ <key>Mythraic</key>
+ <string>Mithraic</string>
+ <key>Naploeon</key>
+ <string>Napoleon</string>
+ <key>Napolean</key>
+ <string>Napoleon</string>
+ <key>Napoleonian</key>
+ <string>Napoleonic</string>
+ <key>Nazereth</key>
+ <string>Nazareth</string>
+ <key>Newyorker</key>
+ <string>New Yorker</string>
+ <key>Novermber</key>
+ <string>November</string>
+ <key>Nullabour</key>
+ <string>Nullarbor</string>
+ <key>Nuremburg</key>
+ <string>Nuremberg</string>
+ <key>Palistian</key>
+ <string>Palestinian</string>
+ <key>Palistinian</key>
+ <string>Palestinian</string>
+ <key>Palistinians</key>
+ <string>Palestinians</string>
+ <key>Papanicalou</key>
+ <string>Papanicolaou</string>
+ <key>Peloponnes</key>
+ <string>Peloponnesus</string>
+ <key>Pennyslvania</key>
+ <string>Pennsylvania</string>
+ <key>Pharoah</key>
+ <string>Pharaoh</string>
+ <key>Philipines</key>
+ <string>Philippines</string>
+ <key>Phillipine</key>
+ <string>Philippine</string>
+ <key>Phillipines</key>
+ <string>Philippines</string>
+ <key>Phillippines</key>
+ <string>Philippines</string>
+ <key>Phonecian</key>
+ <string>Phoenecian</string>
+ <key>Portugese</key>
+ <string>Portuguese</string>
+ <key>Postdam</key>
+ <string>Potsdam</string>
+ <key>Premonasterians</key>
+ <string>Premonstratensians</string>
+ <key>Pucini</key>
+ <string>Puccini</string>
+ <key>Puertorrican</key>
+ <string>Puerto Rican</string>
+ <key>Puertorricans</key>
+ <string>Puerto Ricans</string>
+ <key>Queenland</key>
+ <string>Queensland</string>
+ <key>Rockerfeller</key>
+ <string>Rockefeller</string>
+ <key>Russion</key>
+ <string>Russian</string>
+ <key>Sanhedrim</key>
+ <string>Sanhedrin</string>
+ <key>Saterday</key>
+ <string>Saturday</string>
+ <key>Saterdays</key>
+ <string>Saturdays</string>
+ <key>Sionist</key>
+ <string>Zionist</string>
+ <key>Sionists</key>
+ <string>Zionists</string>
+ <key>Sixtin</key>
+ <string>Sistine</string>
+ <key>Skagerak</key>
+ <string>Skagerrak</string>
+ <key>Tolkein</key>
+ <string>Tolkien</string>
+ <key>Tuscon</key>
+ <string>Tucson</string>
+ <key>Ukranian</key>
+ <string>Ukrainian</string>
+ <key>UnitesStates</key>
+ <string>UnitedStates</string>
+ <key>Yementite</key>
+ <string>Yemenite</string>
+ <key>abandonned</key>
+ <string>abandoned</string>
+ <key>aberation</key>
+ <string>aberration</string>
+ <key>abilties</key>
+ <string>abilities</string>
+ <key>abilty</key>
+ <string>ability</string>
+ <key>abondon</key>
+ <string>abandon</string>
+ <key>abondoned</key>
+ <string>abandoned</string>
+ <key>abondoning</key>
+ <string>abandoning</string>
+ <key>abondons</key>
+ <string>abandons</string>
+ <key>aborigene</key>
+ <string>aborigine</string>
+ <key>abortificant</key>
+ <string>abortifacient</string>
+ <key>abreviate</key>
+ <string>abbreviate</string>
+ <key>abreviated</key>
+ <string>abbreviated</string>
+ <key>abreviation</key>
+ <string>abbreviation</string>
+ <key>abritrary</key>
+ <string>arbitrary</string>
+ <key>absail</key>
+ <string>abseil</string>
+ <key>absailing</key>
+ <string>abseiling</string>
+ <key>absense</key>
+ <string>absence</string>
+ <key>absolutly</key>
+ <string>absolutely</string>
+ <key>absorbsion</key>
+ <string>absorption</string>
+ <key>absorbtion</key>
+ <string>absorption</string>
+ <key>abundacies</key>
+ <string>abundances</string>
+ <key>abundancies</key>
+ <string>abundances</string>
+ <key>abundunt</key>
+ <string>abundant</string>
+ <key>abutts</key>
+ <string>abuts</string>
+ <key>acadamy</key>
+ <string>academy</string>
+ <key>acadmic</key>
+ <string>academic</string>
+ <key>accademic</key>
+ <string>academic</string>
+ <key>accademy</key>
+ <string>academy</string>
+ <key>acccused</key>
+ <string>accused</string>
+ <key>accelleration</key>
+ <string>acceleration</string>
+ <key>accension</key>
+ <string>ascension</string>
+ <key>acceptence</key>
+ <string>acceptance</string>
+ <key>acceptible</key>
+ <string>acceptable</string>
+ <key>accessable</key>
+ <string>accessible</string>
+ <key>accidentaly</key>
+ <string>accidentally</string>
+ <key>accidently</key>
+ <string>accidentally</string>
+ <key>acclimitization</key>
+ <string>acclimatization</string>
+ <key>accomadate</key>
+ <string>accommodate</string>
+ <key>accomadated</key>
+ <string>accommodated</string>
+ <key>accomadates</key>
+ <string>accommodates</string>
+ <key>accomadating</key>
+ <string>accommodating</string>
+ <key>accomadation</key>
+ <string>accommodation</string>
+ <key>accomadations</key>
+ <string>accommodations</string>
+ <key>accomdate</key>
+ <string>accommodate</string>
+ <key>accomodate</key>
+ <string>accommodate</string>
+ <key>accomodated</key>
+ <string>accommodated</string>
+ <key>accomodates</key>
+ <string>accommodates</string>
+ <key>accomodating</key>
+ <string>accommodating</string>
+ <key>accomodation</key>
+ <string>accommodation</string>
+ <key>accomodations</key>
+ <string>accommodations</string>
+ <key>accompanyed</key>
+ <string>accompanied</string>
+ <key>accordeon</key>
+ <string>accordion</string>
+ <key>accordian</key>
+ <string>accordion</string>
+ <key>accoring</key>
+ <string>according</string>
+ <key>accoustic</key>
+ <string>acoustic</string>
+ <key>accquainted</key>
+ <string>acquainted </string>
+ <key>accrediation</key>
+ <string>accreditation</string>
+ <key>accredidation</key>
+ <string>accreditation</string>
+ <key>accross</key>
+ <string>across</string>
+ <key>accussed</key>
+ <string>accused</string>
+ <key>acedemic</key>
+ <string>academic</string>
+ <key>acheive</key>
+ <string>achieve</string>
+ <key>acheived</key>
+ <string>achieved</string>
+ <key>acheivement</key>
+ <string>achievement</string>
+ <key>acheivements</key>
+ <string>achievements</string>
+ <key>acheives</key>
+ <string>achieves</string>
+ <key>acheiving</key>
+ <string>achieving</string>
+ <key>acheivment</key>
+ <string>achievement</string>
+ <key>acheivments</key>
+ <string>achievements</string>
+ <key>achievment</key>
+ <string>achievement</string>
+ <key>achievments</key>
+ <string>achievements</string>
+ <key>achivement</key>
+ <string>achievement</string>
+ <key>achivements</key>
+ <string>achievements</string>
+ <key>acknowldeged</key>
+ <string>acknowledged</string>
+ <key>acknowledgeing</key>
+ <string>acknowledging</string>
+ <key>ackward</key>
+ <string>awkward</string>
+ <key>acommodate</key>
+ <string>accommodate</string>
+ <key>acomplish</key>
+ <string>accomplish</string>
+ <key>acomplished</key>
+ <string>accomplished</string>
+ <key>acomplishment</key>
+ <string>accomplishment</string>
+ <key>acomplishments</key>
+ <string>accomplishments</string>
+ <key>acording</key>
+ <string>according</string>
+ <key>acordingly</key>
+ <string>accordingly</string>
+ <key>acquaintence</key>
+ <string>acquaintance</string>
+ <key>acquaintences</key>
+ <string>acquaintances</string>
+ <key>acquiantence</key>
+ <string>acquaintance</string>
+ <key>acquiantences</key>
+ <string>acquaintances</string>
+ <key>acquited</key>
+ <string>acquitted</string>
+ <key>activites</key>
+ <string>activities</string>
+ <key>activly</key>
+ <string>actively</string>
+ <key>actualy</key>
+ <string>actually</string>
+ <key>acuracy</key>
+ <string>accuracy</string>
+ <key>acused</key>
+ <string>accused</string>
+ <key>acustom</key>
+ <string>accustom</string>
+ <key>acustommed</key>
+ <string>accustomed</string>
+ <key>adavanced</key>
+ <string>advanced</string>
+ <key>adbandon</key>
+ <string>abandon</string>
+ <key>additinally</key>
+ <string>additionally</string>
+ <key>additionaly</key>
+ <string>additionally</string>
+ <key>additonal</key>
+ <string>additional</string>
+ <key>additonally</key>
+ <string>additionally</string>
+ <key>addmission</key>
+ <string>admission</string>
+ <key>addopt</key>
+ <string>adopt</string>
+ <key>addopted</key>
+ <string>adopted</string>
+ <key>addoptive</key>
+ <string>adoptive</string>
+ <key>addres</key>
+ <string>address</string>
+ <key>addresable</key>
+ <string>addressable</string>
+ <key>addresed</key>
+ <string>addressed</string>
+ <key>addresing</key>
+ <string>addressing</string>
+ <key>addressess</key>
+ <string>addresses</string>
+ <key>addtion</key>
+ <string>addition</string>
+ <key>addtional</key>
+ <string>additional</string>
+ <key>adecuate</key>
+ <string>adequate</string>
+ <key>adequit</key>
+ <string>adequate</string>
+ <key>adhearing</key>
+ <string>adhering</string>
+ <key>adherance</key>
+ <string>adherence</string>
+ <key>admendment</key>
+ <string>amendment</string>
+ <key>admininistrative</key>
+ <string>administrative</string>
+ <key>adminstered</key>
+ <string>administered</string>
+ <key>adminstrate</key>
+ <string>administrate</string>
+ <key>adminstration</key>
+ <string>administration</string>
+ <key>adminstrative</key>
+ <string>administrative</string>
+ <key>adminstrator</key>
+ <string>administrator</string>
+ <key>admissability</key>
+ <string>admissibility</string>
+ <key>admissable</key>
+ <string>admissible</string>
+ <key>admited</key>
+ <string>admitted</string>
+ <key>admitedly</key>
+ <string>admittedly</string>
+ <key>adn</key>
+ <string>and</string>
+ <key>adolecent</key>
+ <string>adolescent</string>
+ <key>adquire</key>
+ <string>acquire</string>
+ <key>adquired</key>
+ <string>acquired</string>
+ <key>adquires</key>
+ <string>acquires</string>
+ <key>adquiring</key>
+ <string>acquiring</string>
+ <key>adres</key>
+ <string>address</string>
+ <key>adresable</key>
+ <string>addressable</string>
+ <key>adresing</key>
+ <string>addressing</string>
+ <key>adress</key>
+ <string>address</string>
+ <key>adressable</key>
+ <string>addressable</string>
+ <key>adressed</key>
+ <string>addressed</string>
+ <key>adressing</key>
+ <string>addressing</string>
+ <key>adventrous</key>
+ <string>adventurous</string>
+ <key>advertisment</key>
+ <string>advertisement</string>
+ <key>advertisments</key>
+ <string>advertisements</string>
+ <key>advesary</key>
+ <string>adversary</string>
+ <key>adviced</key>
+ <string>advised</string>
+ <key>aeriel</key>
+ <string>aerial</string>
+ <key>aeriels</key>
+ <string>aerials</string>
+ <key>afair</key>
+ <string>affair</string>
+ <key>afficianados</key>
+ <string>aficionados</string>
+ <key>afficionado</key>
+ <string>aficionado</string>
+ <key>afficionados</key>
+ <string>aficionados</string>
+ <key>affilate</key>
+ <string>affiliate</string>
+ <key>affilliate</key>
+ <string>affiliate</string>
+ <key>affort</key>
+ <string>afford</string>
+ <key>aforememtioned</key>
+ <string>aforementioned</string>
+ <key>againnst</key>
+ <string>against</string>
+ <key>agains</key>
+ <string>against</string>
+ <key>agaisnt</key>
+ <string>against</string>
+ <key>aganist</key>
+ <string>against</string>
+ <key>aggaravates</key>
+ <string>aggravates</string>
+ <key>aggreed</key>
+ <string>agreed</string>
+ <key>aggreement</key>
+ <string>agreement</string>
+ <key>aggregious</key>
+ <string>egregious</string>
+ <key>aggresive</key>
+ <string>aggressive</string>
+ <key>agian</key>
+ <string>again</string>
+ <key>agianst</key>
+ <string>against</string>
+ <key>agin</key>
+ <string>again</string>
+ <key>agina</key>
+ <string>again</string>
+ <key>aginst</key>
+ <string>against</string>
+ <key>agravate</key>
+ <string>aggravate</string>
+ <key>agre</key>
+ <string>agree</string>
+ <key>agred</key>
+ <string>agreed</string>
+ <key>agreeement</key>
+ <string>agreement</string>
+ <key>agreemnt</key>
+ <string>agreement</string>
+ <key>agregate</key>
+ <string>aggregate</string>
+ <key>agregates</key>
+ <string>aggregates</string>
+ <key>agreing</key>
+ <string>agreeing</string>
+ <key>agression</key>
+ <string>aggression</string>
+ <key>agressive</key>
+ <string>aggressive</string>
+ <key>agressively</key>
+ <string>aggressively</string>
+ <key>agressor</key>
+ <string>aggressor</string>
+ <key>agricuture</key>
+ <string>agriculture</string>
+ <key>agrieved</key>
+ <string>aggrieved</string>
+ <key>ahev</key>
+ <string>have</string>
+ <key>ahppen</key>
+ <string>happen</string>
+ <key>ahve</key>
+ <string>have</string>
+ <key>aicraft</key>
+ <string>aircraft</string>
+ <key>aiport</key>
+ <string>airport</string>
+ <key>airbourne</key>
+ <string>airborne</string>
+ <key>aircaft</key>
+ <string>aircraft</string>
+ <key>aircrafts</key>
+ <string>aircraft</string>
+ <key>airporta</key>
+ <string>airports</string>
+ <key>airrcraft</key>
+ <string>aircraft</string>
+ <key>aisian</key>
+ <string>asian</string>
+ <key>albiet</key>
+ <string>albeit</string>
+ <key>alchohol</key>
+ <string>alcohol</string>
+ <key>alchoholic</key>
+ <string>alcoholic</string>
+ <key>alchol</key>
+ <string>alcohol</string>
+ <key>alcholic</key>
+ <string>alcoholic</string>
+ <key>alcohal</key>
+ <string>alcohol</string>
+ <key>alcoholical</key>
+ <string>alcoholic</string>
+ <key>aledge</key>
+ <string>allege</string>
+ <key>aledged</key>
+ <string>alleged</string>
+ <key>aledges</key>
+ <string>alleges</string>
+ <key>alege</key>
+ <string>allege</string>
+ <key>aleged</key>
+ <string>alleged</string>
+ <key>alegience</key>
+ <string>allegiance</string>
+ <key>algebraical</key>
+ <string>algebraic</string>
+ <key>algorhitms</key>
+ <string>algorithms</string>
+ <key>algoritm</key>
+ <string>algorithm</string>
+ <key>algoritms</key>
+ <string>algorithms</string>
+ <key>alientating</key>
+ <string>alienating</string>
+ <key>alledge</key>
+ <string>allege</string>
+ <key>alledged</key>
+ <string>alleged</string>
+ <key>alledgedly</key>
+ <string>allegedly</string>
+ <key>alledges</key>
+ <string>alleges</string>
+ <key>allegedely</key>
+ <string>allegedly</string>
+ <key>allegedy</key>
+ <string>allegedly</string>
+ <key>allegely</key>
+ <string>allegedly</string>
+ <key>allegence</key>
+ <string>allegiance</string>
+ <key>allegience</key>
+ <string>allegiance</string>
+ <key>allign</key>
+ <string>align</string>
+ <key>alligned</key>
+ <string>aligned</string>
+ <key>alliviate</key>
+ <string>alleviate</string>
+ <key>allopone</key>
+ <string>allophone</string>
+ <key>allopones</key>
+ <string>allophones</string>
+ <key>allready</key>
+ <string>already</string>
+ <key>allthough</key>
+ <string>although</string>
+ <key>alltime</key>
+ <string>all-time</string>
+ <key>alltogether</key>
+ <string>altogether</string>
+ <key>almsot</key>
+ <string>almost</string>
+ <key>alochol</key>
+ <string>alcohol</string>
+ <key>alomst</key>
+ <string>almost</string>
+ <key>alot</key>
+ <string>a lot</string>
+ <key>alotted</key>
+ <string>allotted</string>
+ <key>alowed</key>
+ <string>allowed</string>
+ <key>alowing</key>
+ <string>allowing</string>
+ <key>alreayd</key>
+ <string>already</string>
+ <key>alse</key>
+ <string>else</string>
+ <key>alsot</key>
+ <string>also</string>
+ <key>alternitives</key>
+ <string>alternatives</string>
+ <key>altho</key>
+ <string>although</string>
+ <key>althought</key>
+ <string>although</string>
+ <key>altough</key>
+ <string>although</string>
+ <key>alusion</key>
+ <string>allusion</string>
+ <key>alwasy</key>
+ <string>always</string>
+ <key>alwyas</key>
+ <string>always</string>
+ <key>amalgomated</key>
+ <string>amalgamated</string>
+ <key>amatuer</key>
+ <string>amateur</string>
+ <key>amature</key>
+ <string>armature</string>
+ <key>amendmant</key>
+ <string>amendment</string>
+ <key>amerliorate</key>
+ <string>ameliorate</string>
+ <key>amke</key>
+ <string>make</string>
+ <key>amking</key>
+ <string>making</string>
+ <key>ammend</key>
+ <string>amend</string>
+ <key>ammended</key>
+ <string>amended</string>
+ <key>ammendment</key>
+ <string>amendment</string>
+ <key>ammendments</key>
+ <string>amendments</string>
+ <key>ammount</key>
+ <string>amount</string>
+ <key>ammused</key>
+ <string>amused</string>
+ <key>amoung</key>
+ <string>among</string>
+ <key>amoungst</key>
+ <string>amongst</string>
+ <key>amung</key>
+ <string>among</string>
+ <key>amunition</key>
+ <string>ammunition</string>
+ <key>analagous</key>
+ <string>analogous</string>
+ <key>analitic</key>
+ <string>analytic</string>
+ <key>analogeous</key>
+ <string>analogous</string>
+ <key>anarchim</key>
+ <string>anarchism</string>
+ <key>anarchistm</key>
+ <string>anarchism</string>
+ <key>anbd</key>
+ <string>and</string>
+ <key>ancestory</key>
+ <string>ancestry</string>
+ <key>ancilliary</key>
+ <string>ancillary</string>
+ <key>androgenous</key>
+ <string>androgynous</string>
+ <key>androgeny</key>
+ <string>androgyny</string>
+ <key>anihilation</key>
+ <string>annihilation</string>
+ <key>aniversary</key>
+ <string>anniversary</string>
+ <key>annoint</key>
+ <string>anoint</string>
+ <key>annointed</key>
+ <string>anointed</string>
+ <key>annointing</key>
+ <string>anointing</string>
+ <key>annoints</key>
+ <string>anoints</string>
+ <key>annouced</key>
+ <string>announced</string>
+ <key>annualy</key>
+ <string>annually</string>
+ <key>annuled</key>
+ <string>annulled</string>
+ <key>anohter</key>
+ <string>another</string>
+ <key>anomolies</key>
+ <string>anomalies</string>
+ <key>anomolous</key>
+ <string>anomalous</string>
+ <key>anomoly</key>
+ <string>anomaly</string>
+ <key>anonimity</key>
+ <string>anonymity</string>
+ <key>anounced</key>
+ <string>announced</string>
+ <key>anouncement</key>
+ <string>announcement</string>
+ <key>ansalisation</key>
+ <string>nasalisation</string>
+ <key>ansalization</key>
+ <string>nasalization</string>
+ <key>ansestors</key>
+ <string>ancestors</string>
+ <key>antartic</key>
+ <string>antarctic</string>
+ <key>anthromorphization</key>
+ <string>anthropomorphization</string>
+ <key>anthropolgist</key>
+ <string>anthropologist</string>
+ <key>anthropolgy</key>
+ <string>anthropology</string>
+ <key>anual</key>
+ <string>annual</string>
+ <key>anulled</key>
+ <string>annulled</string>
+ <key>anwsered</key>
+ <string>answered</string>
+ <key>anyhwere</key>
+ <string>anywhere</string>
+ <key>anyother</key>
+ <string>any other</string>
+ <key>anytying</key>
+ <string>anything</string>
+ <key>aparent</key>
+ <string>apparent</string>
+ <key>aparment</key>
+ <string>apartment</string>
+ <key>apenines</key>
+ <string>apennines</string>
+ <key>aplication</key>
+ <string>application</string>
+ <key>aplied</key>
+ <string>applied</string>
+ <key>apolegetics</key>
+ <string>apologetics</string>
+ <key>apon</key>
+ <string>apron</string>
+ <key>apparant</key>
+ <string>apparent</string>
+ <key>apparantly</key>
+ <string>apparently</string>
+ <key>appart</key>
+ <string>apart</string>
+ <key>appartment</key>
+ <string>apartment</string>
+ <key>appartments</key>
+ <string>apartments</string>
+ <key>appealling</key>
+ <string>appealing</string>
+ <key>appeareance</key>
+ <string>appearance</string>
+ <key>appearence</key>
+ <string>appearance</string>
+ <key>appearences</key>
+ <string>appearances</string>
+ <key>apperance</key>
+ <string>appearance</string>
+ <key>apperances</key>
+ <string>appearances</string>
+ <key>appereance</key>
+ <string>appearance</string>
+ <key>appereances</key>
+ <string>appearances</string>
+ <key>applicaiton</key>
+ <string>application</string>
+ <key>applicaitons</key>
+ <string>applications</string>
+ <key>appologies</key>
+ <string>apologies</string>
+ <key>appology</key>
+ <string>apology</string>
+ <key>apprearance</key>
+ <string>appearance</string>
+ <key>apprieciate</key>
+ <string>appreciate</string>
+ <key>approachs</key>
+ <string>approaches</string>
+ <key>appropiate</key>
+ <string>appropriate</string>
+ <key>appropraite</key>
+ <string>appropriate</string>
+ <key>appropropiate</key>
+ <string>appropriate</string>
+ <key>approproximate</key>
+ <string>approximate</string>
+ <key>approxamately</key>
+ <string>approximately</string>
+ <key>approxiately</key>
+ <string>approximately</string>
+ <key>approximitely</key>
+ <string>approximately</string>
+ <key>aprehensive</key>
+ <string>apprehensive</string>
+ <key>apropriate</key>
+ <string>appropriate</string>
+ <key>aproximate</key>
+ <string>approximate</string>
+ <key>aproximately</key>
+ <string>approximately</string>
+ <key>aquaduct</key>
+ <string>aqueduct</string>
+ <key>aquaintance</key>
+ <string>acquaintance</string>
+ <key>aquainted</key>
+ <string>acquainted</string>
+ <key>aquiantance</key>
+ <string>acquaintance</string>
+ <key>aquire</key>
+ <string>acquire</string>
+ <key>aquired</key>
+ <string>acquired</string>
+ <key>aquiring</key>
+ <string>acquiring</string>
+ <key>aquisition</key>
+ <string>acquisition</string>
+ <key>aquitted</key>
+ <string>acquitted</string>
+ <key>aranged</key>
+ <string>arranged</string>
+ <key>arangement</key>
+ <string>arrangement</string>
+ <key>arbitarily</key>
+ <string>arbitrarily</string>
+ <key>arbitary</key>
+ <string>arbitrary</string>
+ <key>archaelogists</key>
+ <string>archaeologists</string>
+ <key>archaelogy</key>
+ <string>archaeology</string>
+ <key>archaoelogy</key>
+ <string>archaeology</string>
+ <key>archaology</key>
+ <string>archaeology</string>
+ <key>archeaologist</key>
+ <string>archaeologist</string>
+ <key>archeaologists</key>
+ <string>archaeologists</string>
+ <key>archetect</key>
+ <string>architect</string>
+ <key>archetects</key>
+ <string>architects</string>
+ <key>archetectural</key>
+ <string>architectural</string>
+ <key>archetecturally</key>
+ <string>architecturally</string>
+ <key>archetecture</key>
+ <string>architecture</string>
+ <key>archiac</key>
+ <string>archaic</string>
+ <key>archictect</key>
+ <string>architect</string>
+ <key>archimedian</key>
+ <string>archimedean</string>
+ <key>architecht</key>
+ <string>architect</string>
+ <key>architechturally</key>
+ <string>architecturally</string>
+ <key>architechture</key>
+ <string>architecture</string>
+ <key>architechtures</key>
+ <string>architectures</string>
+ <key>architectual</key>
+ <string>architectural</string>
+ <key>archtype</key>
+ <string>archetype</string>
+ <key>archtypes</key>
+ <string>archetypes</string>
+ <key>aready</key>
+ <string>already</string>
+ <key>areodynamics</key>
+ <string>aerodynamics</string>
+ <key>argubly</key>
+ <string>arguably</string>
+ <key>arguement</key>
+ <string>argument</string>
+ <key>arguements</key>
+ <string>arguments</string>
+ <key>arised</key>
+ <string>arose</string>
+ <key>arival</key>
+ <string>arrival</string>
+ <key>armamant</key>
+ <string>armament</string>
+ <key>armistace</key>
+ <string>armistice</string>
+ <key>arogant</key>
+ <string>arrogant</string>
+ <key>arogent</key>
+ <string>arrogant</string>
+ <key>aroud</key>
+ <string>around</string>
+ <key>arrangment</key>
+ <string>arrangement</string>
+ <key>arrangments</key>
+ <string>arrangements</string>
+ <key>arround</key>
+ <string>around</string>
+ <key>artical</key>
+ <string>article</string>
+ <key>artice</key>
+ <string>article</string>
+ <key>articel</key>
+ <string>article</string>
+ <key>artifical</key>
+ <string>artificial</string>
+ <key>artifically</key>
+ <string>artificially</string>
+ <key>artillary</key>
+ <string>artillery</string>
+ <key>arund</key>
+ <string>around</string>
+ <key>asetic</key>
+ <string>ascetic</string>
+ <key>asfar</key>
+ <string>as far</string>
+ <key>asign</key>
+ <string>assign</string>
+ <key>aslo</key>
+ <string>also</string>
+ <key>asociated</key>
+ <string>associated</string>
+ <key>asorbed</key>
+ <string>absorbed</string>
+ <key>asphyxation</key>
+ <string>asphyxiation</string>
+ <key>assasin</key>
+ <string>assassin</string>
+ <key>assasinate</key>
+ <string>assassinate</string>
+ <key>assasinated</key>
+ <string>assassinated</string>
+ <key>assasinates</key>
+ <string>assassinates</string>
+ <key>assasination</key>
+ <string>assassination</string>
+ <key>assasinations</key>
+ <string>assassinations</string>
+ <key>assasined</key>
+ <string>assassinated</string>
+ <key>assasins</key>
+ <string>assassins</string>
+ <key>assassintation</key>
+ <string>assassination</string>
+ <key>assemple</key>
+ <string>assemble</string>
+ <key>assertation</key>
+ <string>assertion</string>
+ <key>asside</key>
+ <string>aside</string>
+ <key>assisnate</key>
+ <string>assassinate</string>
+ <key>assit</key>
+ <string>assist</string>
+ <key>assitant</key>
+ <string>assistant</string>
+ <key>assocation</key>
+ <string>association</string>
+ <key>assoicate</key>
+ <string>associate</string>
+ <key>assoicated</key>
+ <string>associated</string>
+ <key>assoicates</key>
+ <string>associates</string>
+ <key>assosication</key>
+ <string>assassination</string>
+ <key>asssassans</key>
+ <string>assassins</string>
+ <key>assualt</key>
+ <string>assault</string>
+ <key>assualted</key>
+ <string>assaulted</string>
+ <key>assymetric</key>
+ <string>asymmetric</string>
+ <key>assymetrical</key>
+ <string>asymmetrical</string>
+ <key>asteriod</key>
+ <string>asteroid</string>
+ <key>asthetic</key>
+ <string>aesthetic</string>
+ <key>asthetical</key>
+ <string>aesthetical</string>
+ <key>asthetically</key>
+ <string>aesthetically</string>
+ <key>asume</key>
+ <string>assume</string>
+ <key>aswell</key>
+ <string>as well</string>
+ <key>atain</key>
+ <string>attain</string>
+ <key>atempting</key>
+ <string>attempting</string>
+ <key>atheistical</key>
+ <string>atheistic</string>
+ <key>athenean</key>
+ <string>athenian</string>
+ <key>atheneans</key>
+ <string>athenians</string>
+ <key>athiesm</key>
+ <string>atheism</string>
+ <key>athiest</key>
+ <string>atheist</string>
+ <key>atorney</key>
+ <string>attorney</string>
+ <key>atribute</key>
+ <string>attribute</string>
+ <key>atributed</key>
+ <string>attributed</string>
+ <key>atributes</key>
+ <string>attributes</string>
+ <key>attaindre</key>
+ <string>attainder</string>
+ <key>attemp</key>
+ <string>attempt</string>
+ <key>attemped</key>
+ <string>attempted</string>
+ <key>attemt</key>
+ <string>attempt</string>
+ <key>attemted</key>
+ <string>attempted</string>
+ <key>attemting</key>
+ <string>attempting</string>
+ <key>attemts</key>
+ <string>attempts</string>
+ <key>attendence</key>
+ <string>attendance</string>
+ <key>attendent</key>
+ <string>attendant</string>
+ <key>attendents</key>
+ <string>attendants</string>
+ <key>attened</key>
+ <string>attended</string>
+ <key>attension</key>
+ <string>attention</string>
+ <key>attitide</key>
+ <string>attitude</string>
+ <key>attributred</key>
+ <string>attributed</string>
+ <key>attrocities</key>
+ <string>atrocities</string>
+ <key>audeince</key>
+ <string>audience</string>
+ <key>auromated</key>
+ <string>automated</string>
+ <key>austrailia</key>
+ <string>Australia</string>
+ <key>austrailian</key>
+ <string>Australian</string>
+ <key>auther</key>
+ <string>author</string>
+ <key>authobiographic</key>
+ <string>autobiographic</string>
+ <key>authobiography</key>
+ <string>autobiography</string>
+ <key>authorative</key>
+ <string>authoritative</string>
+ <key>authorites</key>
+ <string>authorities</string>
+ <key>authorithy</key>
+ <string>authority</string>
+ <key>authoritiers</key>
+ <string>authorities</string>
+ <key>authoritive</key>
+ <string>authoritative</string>
+ <key>authrorities</key>
+ <string>authorities</string>
+ <key>autochtonous</key>
+ <string>autochthonous</string>
+ <key>autoctonous</key>
+ <string>autochthonous</string>
+ <key>automaticly</key>
+ <string>automatically</string>
+ <key>automibile</key>
+ <string>automobile</string>
+ <key>automonomous</key>
+ <string>autonomous</string>
+ <key>autor</key>
+ <string>author</string>
+ <key>autority</key>
+ <string>authority</string>
+ <key>auxilary</key>
+ <string>auxiliary</string>
+ <key>auxillaries</key>
+ <string>auxiliaries</string>
+ <key>auxillary</key>
+ <string>auxiliary</string>
+ <key>auxilliaries</key>
+ <string>auxiliaries</string>
+ <key>auxilliary</key>
+ <string>auxiliary</string>
+ <key>availabe</key>
+ <string> available</string>
+ <key>availablity</key>
+ <string>availability</string>
+ <key>availaible</key>
+ <string>available</string>
+ <key>availble</key>
+ <string>available</string>
+ <key>availiable</key>
+ <string>available</string>
+ <key>availible</key>
+ <string>available</string>
+ <key>avalable</key>
+ <string>available</string>
+ <key>avalance</key>
+ <string>avalanche</string>
+ <key>avaliable</key>
+ <string>available</string>
+ <key>avation</key>
+ <string>aviation</string>
+ <key>avengence</key>
+ <string>a vengeance</string>
+ <key>averageed</key>
+ <string>averaged</string>
+ <key>avilable</key>
+ <string>available</string>
+ <key>awared</key>
+ <string>awarded</string>
+ <key>awya</key>
+ <string>away</string>
+ <key>baceause</key>
+ <string>because</string>
+ <key>backgorund</key>
+ <string>background</string>
+ <key>backrounds</key>
+ <string>backgrounds</string>
+ <key>bakc</key>
+ <string>back</string>
+ <key>banannas</key>
+ <string>bananas</string>
+ <key>bandwith</key>
+ <string>bandwidth</string>
+ <key>bankrupcy</key>
+ <string>bankruptcy</string>
+ <key>banruptcy</key>
+ <string>bankruptcy</string>
+ <key>baout</key>
+ <string>about</string>
+ <key>basicaly</key>
+ <string>basically</string>
+ <key>basicly</key>
+ <string>basically</string>
+ <key>bcak</key>
+ <string>back</string>
+ <key>beachead</key>
+ <string>beachhead</string>
+ <key>beacuse</key>
+ <string>because</string>
+ <key>beastiality</key>
+ <string>bestiality</string>
+ <key>beatiful</key>
+ <string>beautiful</string>
+ <key>beaurocracy</key>
+ <string>bureaucracy</string>
+ <key>beaurocratic</key>
+ <string>bureaucratic</string>
+ <key>beautyfull</key>
+ <string>beautiful</string>
+ <key>becamae</key>
+ <string>became</string>
+ <key>becames</key>
+ <string>becomes</string>
+ <key>becasue</key>
+ <string>because</string>
+ <key>beccause</key>
+ <string>because</string>
+ <key>becomeing</key>
+ <string>becoming</string>
+ <key>becomming</key>
+ <string>becoming</string>
+ <key>becouse</key>
+ <string>because</string>
+ <key>becuase</key>
+ <string>because</string>
+ <key>bedore</key>
+ <string>before</string>
+ <key>befoer</key>
+ <string>before</string>
+ <key>beggin</key>
+ <string>begin</string>
+ <key>begginer</key>
+ <string>beginner</string>
+ <key>begginers</key>
+ <string>beginners</string>
+ <key>beggining</key>
+ <string>beginning</string>
+ <key>begginings</key>
+ <string>beginnings</string>
+ <key>beggins</key>
+ <string>begins</string>
+ <key>begining</key>
+ <string>beginning</string>
+ <key>beginnig</key>
+ <string>beginning</string>
+ <key>behavour</key>
+ <string>behavior</string>
+ <key>beleagured</key>
+ <string>beleaguered</string>
+ <key>beleif</key>
+ <string>belief</string>
+ <key>beleive</key>
+ <string>believe</string>
+ <key>beleived</key>
+ <string>believed</string>
+ <key>beleives</key>
+ <string>believes</string>
+ <key>beleiving</key>
+ <string>believing</string>
+ <key>beligum</key>
+ <string>belgium</string>
+ <key>belive</key>
+ <string>believe</string>
+ <key>belived</key>
+ <string>believed</string>
+ <key>belives</key>
+ <string>believes</string>
+ <key>belligerant</key>
+ <string>belligerent</string>
+ <key>bellweather</key>
+ <string>bellwether</string>
+ <key>bemusemnt</key>
+ <string>bemusement</string>
+ <key>beneficary</key>
+ <string>beneficiary</string>
+ <key>beng</key>
+ <string>being</string>
+ <key>benificial</key>
+ <string>beneficial</string>
+ <key>benifit</key>
+ <string>benefit</string>
+ <key>benifits</key>
+ <string>benefits</string>
+ <key>bergamont</key>
+ <string>bergamot</string>
+ <key>beseige</key>
+ <string>besiege</string>
+ <key>beseiged</key>
+ <string>besieged</string>
+ <key>beseiging</key>
+ <string>besieging</string>
+ <key>betwen</key>
+ <string>between</string>
+ <key>beween</key>
+ <string>between</string>
+ <key>bewteen</key>
+ <string>between</string>
+ <key>bilateraly</key>
+ <string>bilaterally</string>
+ <key>billingualism</key>
+ <string>bilingualism</string>
+ <key>binominal</key>
+ <string>binomial</string>
+ <key>bizzare</key>
+ <string>bizarre</string>
+ <key>blaim</key>
+ <string>blame</string>
+ <key>blaimed</key>
+ <string>blamed</string>
+ <key>blessure</key>
+ <string>blessing</string>
+ <key>bodydbuilder</key>
+ <string>bodybuilder</string>
+ <key>bombardement</key>
+ <string>bombardment</string>
+ <key>bombarment</key>
+ <string>bombardment</string>
+ <key>bondary</key>
+ <string>boundary</string>
+ <key>borke</key>
+ <string>broke</string>
+ <key>boundry</key>
+ <string>boundary</string>
+ <key>bouyancy</key>
+ <string>buoyancy</string>
+ <key>bouyant</key>
+ <string>buoyant</string>
+ <key>boyant</key>
+ <string>buoyant</string>
+ <key>breakthough</key>
+ <string>breakthrough</string>
+ <key>breakthroughts</key>
+ <string>breakthroughs</string>
+ <key>breif</key>
+ <string>brief</string>
+ <key>breifly</key>
+ <string>briefly</string>
+ <key>brethen</key>
+ <string>brethren</string>
+ <key>bretheren</key>
+ <string>brethren</string>
+ <key>briliant</key>
+ <string>brilliant</string>
+ <key>brillant</key>
+ <string>brilliant</string>
+ <key>brimestone</key>
+ <string>brimstone</string>
+ <key>broacasted</key>
+ <string>broadcast</string>
+ <key>broadacasting</key>
+ <string>broadcasting</string>
+ <key>broady</key>
+ <string>broadly</string>
+ <key>buisness</key>
+ <string>business</string>
+ <key>buisnessman</key>
+ <string>businessman</string>
+ <key>buoancy</key>
+ <string>buoyancy</string>
+ <key>burried</key>
+ <string>buried</string>
+ <key>busineses</key>
+ <string>businesses</string>
+ <key>busness</key>
+ <string>business</string>
+ <key>bussiness</key>
+ <string>business</string>
+ <key>caculater</key>
+ <string>calculator</string>
+ <key>cacuses</key>
+ <string>caucuses</string>
+ <key>cahracters</key>
+ <string>characters</string>
+ <key>calaber</key>
+ <string>caliber</string>
+ <key>calculater</key>
+ <string>calculator</string>
+ <key>calculs</key>
+ <string>calculus</string>
+ <key>calenders</key>
+ <string>calendars</string>
+ <key>caligraphy</key>
+ <string>calligraphy</string>
+ <key>caluclate</key>
+ <string>calculate</string>
+ <key>caluclated</key>
+ <string>calculated</string>
+ <key>caluculate</key>
+ <string>calculate</string>
+ <key>caluculated</key>
+ <string>calculated</string>
+ <key>calulate</key>
+ <string>calculate</string>
+ <key>calulated</key>
+ <string>calculated</string>
+ <key>calulater</key>
+ <string>calculator</string>
+ <key>camoflage</key>
+ <string>camouflage</string>
+ <key>campain</key>
+ <string>campaign</string>
+ <key>campains</key>
+ <string>campaigns</string>
+ <key>candadate</key>
+ <string>candidate</string>
+ <key>candiate</key>
+ <string>candidate</string>
+ <key>candidiate</key>
+ <string>candidate</string>
+ <key>cannister</key>
+ <string>canister</string>
+ <key>cannisters</key>
+ <string>canisters</string>
+ <key>cannnot</key>
+ <string>cannot</string>
+ <key>cannonical</key>
+ <string>canonical</string>
+ <key>cannotation</key>
+ <string>connotation</string>
+ <key>cannotations</key>
+ <string>connotations</string>
+ <key>cant</key>
+ <string>can&apos;t</string>
+ <key>caost</key>
+ <string>coast</string>
+ <key>caperbility</key>
+ <string>capability</string>
+ <key>capible</key>
+ <string>capable</string>
+ <key>captial</key>
+ <string>capital</string>
+ <key>captued</key>
+ <string>captured</string>
+ <key>capturd</key>
+ <string>captured</string>
+ <key>carachter</key>
+ <string>character</string>
+ <key>caracterized</key>
+ <string>characterized</string>
+ <key>carcas</key>
+ <string>carcass</string>
+ <key>carefull</key>
+ <string>careful</string>
+ <key>careing</key>
+ <string>caring</string>
+ <key>carismatic</key>
+ <string>charismatic</string>
+ <key>carnege</key>
+ <string>carnage</string>
+ <key>carnige</key>
+ <string>carnage</string>
+ <key>carniverous</key>
+ <string>carnivorous</string>
+ <key>carreer</key>
+ <string>career</string>
+ <key>carrers</key>
+ <string>careers</string>
+ <key>cartdridge</key>
+ <string>cartridge</string>
+ <key>carthographer</key>
+ <string>cartographer</string>
+ <key>cartilege</key>
+ <string>cartilage</string>
+ <key>cartilidge</key>
+ <string>cartilage</string>
+ <key>cartrige</key>
+ <string>cartridge</string>
+ <key>casette</key>
+ <string>cassette</string>
+ <key>casion</key>
+ <string>caisson</string>
+ <key>cassawory</key>
+ <string>cassowary</string>
+ <key>cassowarry</key>
+ <string>cassowary</string>
+ <key>casulaties</key>
+ <string>casualties</string>
+ <key>casulaty</key>
+ <string>casualty</string>
+ <key>catagories</key>
+ <string>categories</string>
+ <key>catagorized</key>
+ <string>categorized</string>
+ <key>catagory</key>
+ <string>category</string>
+ <key>catapillar</key>
+ <string>caterpillar</string>
+ <key>catapillars</key>
+ <string>caterpillars</string>
+ <key>catapiller</key>
+ <string>caterpillar</string>
+ <key>catapillers</key>
+ <string>caterpillars</string>
+ <key>catepillar</key>
+ <string>caterpillar</string>
+ <key>catepillars</key>
+ <string>caterpillars</string>
+ <key>catergorize</key>
+ <string>categorize</string>
+ <key>catergorized</key>
+ <string>categorized</string>
+ <key>caterpilar</key>
+ <string>caterpillar</string>
+ <key>caterpilars</key>
+ <string>caterpillars</string>
+ <key>caterpiller</key>
+ <string>caterpillar</string>
+ <key>caterpillers</key>
+ <string>caterpillars</string>
+ <key>cathlic</key>
+ <string>catholic</string>
+ <key>catholocism</key>
+ <string>catholicism</string>
+ <key>catterpilar</key>
+ <string>caterpillar</string>
+ <key>catterpilars</key>
+ <string>caterpillars</string>
+ <key>catterpillar</key>
+ <string>caterpillar</string>
+ <key>catterpillars</key>
+ <string>caterpillars</string>
+ <key>cattleship</key>
+ <string>battleship</string>
+ <key>causalities</key>
+ <string>casualties</string>
+ <key>cellpading</key>
+ <string>cellpadding</string>
+ <key>cementary</key>
+ <string>cemetery</string>
+ <key>cemetarey</key>
+ <string>cemetery</string>
+ <key>cemetaries</key>
+ <string>cemeteries</string>
+ <key>cemetary</key>
+ <string>cemetery</string>
+ <key>cencus</key>
+ <string>census</string>
+ <key>censur</key>
+ <string>censor</string>
+ <key>cententenial</key>
+ <string>centennial</string>
+ <key>centruies</key>
+ <string>centuries</string>
+ <key>centruy</key>
+ <string>century</string>
+ <key>ceratin</key>
+ <string>certain</string>
+ <key>cerimonial</key>
+ <string>ceremonial</string>
+ <key>cerimonies</key>
+ <string>ceremonies</string>
+ <key>cerimonious</key>
+ <string>ceremonious</string>
+ <key>cerimony</key>
+ <string>ceremony</string>
+ <key>ceromony</key>
+ <string>ceremony</string>
+ <key>certainity</key>
+ <string>certainty</string>
+ <key>certian</key>
+ <string>certain</string>
+ <key>chalenging</key>
+ <string>challenging</string>
+ <key>challange</key>
+ <string>challenge</string>
+ <key>challanged</key>
+ <string>challenged</string>
+ <key>challege</key>
+ <string>challenge</string>
+ <key>changable</key>
+ <string>changeable</string>
+ <key>charachter</key>
+ <string>character</string>
+ <key>charachters</key>
+ <string>characters</string>
+ <key>charactersistic</key>
+ <string>characteristic</string>
+ <key>charactor</key>
+ <string>character </string>
+ <key>charactors</key>
+ <string>characters</string>
+ <key>charasmatic</key>
+ <string>charismatic</string>
+ <key>charaterized</key>
+ <string>characterized</string>
+ <key>chariman</key>
+ <string>chairman</string>
+ <key>charistics</key>
+ <string>characteristics</string>
+ <key>cheif</key>
+ <string>chief</string>
+ <key>cheifs</key>
+ <string>chiefs</string>
+ <key>chemcial</key>
+ <string>chemical</string>
+ <key>chemcially</key>
+ <string>chemically</string>
+ <key>chemestry</key>
+ <string>chemistry</string>
+ <key>chemicaly</key>
+ <string>chemically</string>
+ <key>childbird</key>
+ <string>childbirth</string>
+ <key>childen</key>
+ <string>children</string>
+ <key>choosen</key>
+ <string>chosen</string>
+ <key>chracter</key>
+ <string>character</string>
+ <key>chuch</key>
+ <string>church</string>
+ <key>churchs</key>
+ <string>churches</string>
+ <key>circulaton</key>
+ <string>circulation</string>
+ <key>circumsicion</key>
+ <string>circumcision</string>
+ <key>circut</key>
+ <string>circuit</string>
+ <key>ciricuit</key>
+ <string>circuit</string>
+ <key>ciriculum</key>
+ <string>curriculum</string>
+ <key>civillian</key>
+ <string>civilian</string>
+ <key>claer</key>
+ <string>clear</string>
+ <key>claerer</key>
+ <string>clearer</string>
+ <key>claerly</key>
+ <string>clearly</string>
+ <key>claimes</key>
+ <string>claims</string>
+ <key>clas</key>
+ <string>class</string>
+ <key>clasic</key>
+ <string>classic</string>
+ <key>clasical</key>
+ <string>classical</string>
+ <key>clasically</key>
+ <string>classically</string>
+ <key>cleareance</key>
+ <string>clearance</string>
+ <key>clera</key>
+ <string>clear</string>
+ <key>clincial</key>
+ <string>clinical</string>
+ <key>clinicaly</key>
+ <string>clinically</string>
+ <key>cmo</key>
+ <string>com</string>
+ <key>cmoputer</key>
+ <string>computer</string>
+ <key>co-incided</key>
+ <string>coincided</string>
+ <key>coctail</key>
+ <string>cocktail</string>
+ <key>coform</key>
+ <string>conform</string>
+ <key>cognizent</key>
+ <string>cognizant</string>
+ <key>coincedentally</key>
+ <string>coincidentally</string>
+ <key>colaborations</key>
+ <string>collaborations</string>
+ <key>colateral</key>
+ <string>collateral</string>
+ <key>colelctive</key>
+ <string>collective</string>
+ <key>collaberative</key>
+ <string>collaborative</string>
+ <key>collecton</key>
+ <string>collection</string>
+ <key>collegue</key>
+ <string>colleague</string>
+ <key>collegues</key>
+ <string>colleagues</string>
+ <key>collonade</key>
+ <string>colonnade</string>
+ <key>collonies</key>
+ <string>colonies</string>
+ <key>collony</key>
+ <string>colony </string>
+ <key>collosal</key>
+ <string>colossal</string>
+ <key>colonizators</key>
+ <string>colonizers</string>
+ <key>comander</key>
+ <string>commander</string>
+ <key>comando</key>
+ <string>commando</string>
+ <key>comandos</key>
+ <string>commandos</string>
+ <key>comany</key>
+ <string>company</string>
+ <key>comapany</key>
+ <string>company</string>
+ <key>comback</key>
+ <string>comeback</string>
+ <key>combanations</key>
+ <string>combinations</string>
+ <key>combinatins</key>
+ <string>combinations</string>
+ <key>combusion</key>
+ <string>combustion</string>
+ <key>comdemnation</key>
+ <string>condemnation</string>
+ <key>comemmorates</key>
+ <string>commemorates</string>
+ <key>comemoretion</key>
+ <string>commemoration</string>
+ <key>comision</key>
+ <string>commission</string>
+ <key>comisioned</key>
+ <string>commissioned</string>
+ <key>comisioner</key>
+ <string>commissioner</string>
+ <key>comisioning</key>
+ <string>commissioning</string>
+ <key>comisions</key>
+ <string>commissions</string>
+ <key>comission</key>
+ <string>commission</string>
+ <key>comissioned</key>
+ <string>commissioned</string>
+ <key>comissioner</key>
+ <string>commissioner</string>
+ <key>comissioning</key>
+ <string>commissioning</string>
+ <key>comissions</key>
+ <string>commissions</string>
+ <key>comited</key>
+ <string>committed</string>
+ <key>comiting</key>
+ <string>committing</string>
+ <key>comitted</key>
+ <string>committed</string>
+ <key>comittee</key>
+ <string>committee</string>
+ <key>comitting</key>
+ <string>committing</string>
+ <key>commandoes</key>
+ <string>commandos</string>
+ <key>commedic</key>
+ <string>comedic</string>
+ <key>commemerative</key>
+ <string>commemorative</string>
+ <key>commemmorate</key>
+ <string>commemorate</string>
+ <key>commemmorating</key>
+ <string>commemorating</string>
+ <key>commerical</key>
+ <string>commercial</string>
+ <key>commerically</key>
+ <string>commercially</string>
+ <key>commericial</key>
+ <string>commercial</string>
+ <key>commericially</key>
+ <string>commercially</string>
+ <key>commerorative</key>
+ <string>commemorative</string>
+ <key>comming</key>
+ <string>coming</string>
+ <key>comminication</key>
+ <string>communication</string>
+ <key>commision</key>
+ <string>commission</string>
+ <key>commisioned</key>
+ <string>commissioned</string>
+ <key>commisioner</key>
+ <string>commissioner</string>
+ <key>commisioning</key>
+ <string>commissioning</string>
+ <key>commisions</key>
+ <string>commissions</string>
+ <key>commited</key>
+ <string>committed</string>
+ <key>commitee</key>
+ <string>committee</string>
+ <key>commiting</key>
+ <string>committing</string>
+ <key>committe</key>
+ <string>committee</string>
+ <key>committment</key>
+ <string>commitment</string>
+ <key>committments</key>
+ <string>commitments</string>
+ <key>commmemorated</key>
+ <string>commemorated</string>
+ <key>commongly</key>
+ <string>commonly</string>
+ <key>commonweath</key>
+ <string>commonwealth</string>
+ <key>commuications</key>
+ <string>communications</string>
+ <key>commuinications</key>
+ <string>communications</string>
+ <key>communciation</key>
+ <string>communication</string>
+ <key>communiation</key>
+ <string>communication</string>
+ <key>communites</key>
+ <string>communities</string>
+ <key>compability</key>
+ <string>compatibility</string>
+ <key>comparision</key>
+ <string>comparison</string>
+ <key>comparisions</key>
+ <string>comparisons</string>
+ <key>comparitive</key>
+ <string>comparative</string>
+ <key>comparitively</key>
+ <string>comparatively</string>
+ <key>compatabilities</key>
+ <string>compatibilities</string>
+ <key>compatability</key>
+ <string>compatibility</string>
+ <key>compatable</key>
+ <string>compatible</string>
+ <key>compatablities</key>
+ <string>compatibilities</string>
+ <key>compatablity</key>
+ <string>compatibility</string>
+ <key>compatiable</key>
+ <string>compatible</string>
+ <key>compatiblities</key>
+ <string>compatibilities</string>
+ <key>compatiblity</key>
+ <string>compatibility</string>
+ <key>compeitions</key>
+ <string>competitions</string>
+ <key>compensantion</key>
+ <string>compensation</string>
+ <key>competance</key>
+ <string>competence</string>
+ <key>competant</key>
+ <string>competent</string>
+ <key>competative</key>
+ <string>competitive</string>
+ <key>competion</key>
+ <string>competition</string>
+ <key>competitiion</key>
+ <string>competition</string>
+ <key>competive</key>
+ <string>competitive</string>
+ <key>competiveness</key>
+ <string>competitiveness</string>
+ <key>comphrehensive</key>
+ <string>comprehensive</string>
+ <key>compitent</key>
+ <string>competent</string>
+ <key>completedthe</key>
+ <string>completed the</string>
+ <key>completelyl</key>
+ <string>completely</string>
+ <key>completetion</key>
+ <string>completion</string>
+ <key>complier</key>
+ <string>compiler</string>
+ <key>componant</key>
+ <string>component</string>
+ <key>comprable</key>
+ <string>comparable</string>
+ <key>comprimise</key>
+ <string>compromise</string>
+ <key>compulsary</key>
+ <string>compulsory</string>
+ <key>compulsery</key>
+ <string>compulsory</string>
+ <key>computarized</key>
+ <string>computerized</string>
+ <key>concensus</key>
+ <string>consensus</string>
+ <key>concider</key>
+ <string>consider</string>
+ <key>concidered</key>
+ <string>considered</string>
+ <key>concidering</key>
+ <string>considering</string>
+ <key>conciders</key>
+ <string>considers</string>
+ <key>concieted</key>
+ <string>conceited</string>
+ <key>concieved</key>
+ <string>conceived</string>
+ <key>concious</key>
+ <string>conscious</string>
+ <key>conciously</key>
+ <string>consciously</string>
+ <key>conciousness</key>
+ <string>consciousness</string>
+ <key>condamned</key>
+ <string>condemned</string>
+ <key>condemmed</key>
+ <string>condemned</string>
+ <key>condidtion</key>
+ <string>condition</string>
+ <key>condidtions</key>
+ <string>conditions</string>
+ <key>conditionsof</key>
+ <string>conditions of</string>
+ <key>conected</key>
+ <string>connected</string>
+ <key>conection</key>
+ <string>connection</string>
+ <key>conesencus</key>
+ <string>consensus</string>
+ <key>confidental</key>
+ <string>confidential</string>
+ <key>confidentally</key>
+ <string>confidentially</string>
+ <key>confids</key>
+ <string>confides</string>
+ <key>configureable</key>
+ <string>configurable</string>
+ <key>confortable</key>
+ <string>comfortable</string>
+ <key>congradulations</key>
+ <string>congratulations</string>
+ <key>congresional</key>
+ <string>congressional</string>
+ <key>conived</key>
+ <string>connived</string>
+ <key>conjecutre</key>
+ <string>conjecture</string>
+ <key>conjuction</key>
+ <string>conjunction</string>
+ <key>conotations</key>
+ <string>connotations</string>
+ <key>conquerd</key>
+ <string>conquered</string>
+ <key>conquerer</key>
+ <string>conqueror</string>
+ <key>conquerers</key>
+ <string>conquerors</string>
+ <key>conqured</key>
+ <string>conquered</string>
+ <key>conscent</key>
+ <string>consent</string>
+ <key>consciouness</key>
+ <string>consciousness</string>
+ <key>consdider</key>
+ <string>consider</string>
+ <key>consdidered</key>
+ <string>considered</string>
+ <key>consdiered</key>
+ <string>considered</string>
+ <key>consectutive</key>
+ <string>consecutive</string>
+ <key>consenquently</key>
+ <string>consequently</string>
+ <key>consentrate</key>
+ <string>concentrate</string>
+ <key>consentrated</key>
+ <string>concentrated</string>
+ <key>consentrates</key>
+ <string>concentrates</string>
+ <key>consept</key>
+ <string>concept</string>
+ <key>consequentually</key>
+ <string>consequently</string>
+ <key>consequeseces</key>
+ <string>consequences</string>
+ <key>consern</key>
+ <string>concern</string>
+ <key>conserned</key>
+ <string>concerned</string>
+ <key>conserning</key>
+ <string>concerning</string>
+ <key>conservitive</key>
+ <string>conservative</string>
+ <key>consiciousness</key>
+ <string>consciousness</string>
+ <key>consicousness</key>
+ <string>consciousness</string>
+ <key>considerd</key>
+ <string>considered</string>
+ <key>consideres</key>
+ <string>considered</string>
+ <key>consious</key>
+ <string>conscious</string>
+ <key>consistant</key>
+ <string>consistent</string>
+ <key>consistantly</key>
+ <string>consistently</string>
+ <key>consituencies</key>
+ <string>constituencies</string>
+ <key>consituency</key>
+ <string>constituency</string>
+ <key>consituted</key>
+ <string>constituted</string>
+ <key>consitution</key>
+ <string>constitution</string>
+ <key>consitutional</key>
+ <string>constitutional</string>
+ <key>consolodate</key>
+ <string>consolidate</string>
+ <key>consolodated</key>
+ <string>consolidated</string>
+ <key>consonent</key>
+ <string>consonant</string>
+ <key>consonents</key>
+ <string>consonants</string>
+ <key>consorcium</key>
+ <string>consortium</string>
+ <key>conspiracys</key>
+ <string>conspiracies</string>
+ <key>conspiriator</key>
+ <string>conspirator</string>
+ <key>constaints</key>
+ <string>constraints</string>
+ <key>constanly</key>
+ <string>constantly</string>
+ <key>constarnation</key>
+ <string>consternation</string>
+ <key>constatn</key>
+ <string>constant</string>
+ <key>constinually</key>
+ <string>continually</string>
+ <key>constituant</key>
+ <string>constituent</string>
+ <key>constituants</key>
+ <string>constituents</string>
+ <key>constituion</key>
+ <string>constitution</string>
+ <key>constituional</key>
+ <string>constitutional</string>
+ <key>consttruction</key>
+ <string>construction</string>
+ <key>constuction</key>
+ <string>construction</string>
+ <key>consulant</key>
+ <string>consultant</string>
+ <key>consumate</key>
+ <string>consummate</string>
+ <key>consumated</key>
+ <string>consummated</string>
+ <key>contaiminate</key>
+ <string>contaminate</string>
+ <key>containes</key>
+ <string>contains</string>
+ <key>contamporaries</key>
+ <string>contemporaries</string>
+ <key>contamporary</key>
+ <string>contemporary</string>
+ <key>contempoary</key>
+ <string>contemporary</string>
+ <key>contemporaneus</key>
+ <string>contemporaneous</string>
+ <key>contempory</key>
+ <string>contemporary</string>
+ <key>contendor</key>
+ <string>contender</string>
+ <key>contibute</key>
+ <string>contribute </string>
+ <key>contibuted</key>
+ <string>contributed </string>
+ <key>contibutes</key>
+ <string>contributes </string>
+ <key>contigent</key>
+ <string>contingent</string>
+ <key>contined</key>
+ <string>continued</string>
+ <key>continous</key>
+ <string>continuous</string>
+ <key>continously</key>
+ <string>continuously</string>
+ <key>continueing</key>
+ <string>continuing</string>
+ <key>contravercial</key>
+ <string>controversial</string>
+ <key>contraversy</key>
+ <string>controversy</string>
+ <key>contributer</key>
+ <string>contributor</string>
+ <key>contributers</key>
+ <string>contributors</string>
+ <key>contritutions</key>
+ <string>contributions</string>
+ <key>controled</key>
+ <string>controlled</string>
+ <key>controling</key>
+ <string>controlling</string>
+ <key>controll</key>
+ <string>control</string>
+ <key>controlls</key>
+ <string>controls</string>
+ <key>controvercial</key>
+ <string>controversial</string>
+ <key>controvercy</key>
+ <string>controversy</string>
+ <key>controveries</key>
+ <string>controversies</string>
+ <key>controversal</key>
+ <string>controversial</string>
+ <key>controversey</key>
+ <string>controversy</string>
+ <key>controvertial</key>
+ <string>controversial</string>
+ <key>controvery</key>
+ <string>controversy</string>
+ <key>contruction</key>
+ <string>construction</string>
+ <key>conveinent</key>
+ <string>convenient</string>
+ <key>convenant</key>
+ <string>covenant</string>
+ <key>convential</key>
+ <string>conventional</string>
+ <key>convertables</key>
+ <string>convertibles</string>
+ <key>convertion</key>
+ <string>conversion</string>
+ <key>conveyer</key>
+ <string>conveyor</string>
+ <key>conviced</key>
+ <string>convinced</string>
+ <key>convienient</key>
+ <string>convenient</string>
+ <key>coordiantion</key>
+ <string>coordination</string>
+ <key>coorperations</key>
+ <string>corporations</string>
+ <key>copmetitors</key>
+ <string>competitors</string>
+ <key>coputer</key>
+ <string>computer</string>
+ <key>copywrite</key>
+ <string>copyright</string>
+ <key>coridal</key>
+ <string>cordial</string>
+ <key>cornmitted</key>
+ <string>committed</string>
+ <key>corosion</key>
+ <string>corrosion</string>
+ <key>corparate</key>
+ <string>corporate</string>
+ <key>corperations</key>
+ <string>corporations</string>
+ <key>correcters</key>
+ <string>correctors</string>
+ <key>correponding</key>
+ <string>corresponding</string>
+ <key>correposding</key>
+ <string>corresponding</string>
+ <key>correspondant</key>
+ <string>correspondent</string>
+ <key>correspondants</key>
+ <string>correspondents</string>
+ <key>corridoors</key>
+ <string>corridors</string>
+ <key>corrispond</key>
+ <string>correspond</string>
+ <key>corrispondant</key>
+ <string>correspondent</string>
+ <key>corrispondants</key>
+ <string>correspondents</string>
+ <key>corrisponded</key>
+ <string>corresponded</string>
+ <key>corrisponding</key>
+ <string>corresponding</string>
+ <key>corrisponds</key>
+ <string>corresponds</string>
+ <key>costitution</key>
+ <string>constitution</string>
+ <key>coucil</key>
+ <string>council</string>
+ <key>counries</key>
+ <string>countries</string>
+ <key>countains</key>
+ <string>contains</string>
+ <key>countires</key>
+ <string>countries</string>
+ <key>coururier</key>
+ <string>courier</string>
+ <key>coverted</key>
+ <string>converted</string>
+ <key>cpoy</key>
+ <string>copy</string>
+ <key>creaeted</key>
+ <string>created</string>
+ <key>creedence</key>
+ <string>credence</string>
+ <key>critereon</key>
+ <string>criterion</string>
+ <key>criterias</key>
+ <string>criteria</string>
+ <key>criticists</key>
+ <string>critics</string>
+ <key>critising</key>
+ <string>criticising</string>
+ <key>critisising</key>
+ <string>criticising</string>
+ <key>critisism</key>
+ <string>criticism</string>
+ <key>critisisms</key>
+ <string>criticisms</string>
+ <key>critisize</key>
+ <string>criticise</string>
+ <key>critisized</key>
+ <string>criticised</string>
+ <key>critisizes</key>
+ <string>criticises</string>
+ <key>critisizing</key>
+ <string>criticising</string>
+ <key>critized</key>
+ <string>criticized</string>
+ <key>critizing</key>
+ <string>criticizing</string>
+ <key>crockodiles</key>
+ <string>crocodiles</string>
+ <key>crowm</key>
+ <string>crown</string>
+ <key>crtical</key>
+ <string>critical</string>
+ <key>crticised</key>
+ <string>criticised</string>
+ <key>crucifiction</key>
+ <string>crucifixion</string>
+ <key>crusies</key>
+ <string>cruises</string>
+ <key>crystalisation</key>
+ <string>crystallisation</string>
+ <key>culiminating</key>
+ <string>culminating</string>
+ <key>cumulatative</key>
+ <string>cumulative</string>
+ <key>curch</key>
+ <string>church</string>
+ <key>curcuit</key>
+ <string>circuit</string>
+ <key>currenly</key>
+ <string>currently</string>
+ <key>curriculem</key>
+ <string>curriculum</string>
+ <key>cxan</key>
+ <string>cyan</string>
+ <key>cyclinder</key>
+ <string>cylinder</string>
+ <key>dacquiri</key>
+ <string>daiquiri</string>
+ <key>dael</key>
+ <string>deal</string>
+ <key>dalmation</key>
+ <string>dalmatian</string>
+ <key>damenor</key>
+ <string>demeanor</string>
+ <key>dammage</key>
+ <string>damage</string>
+ <key>daugher</key>
+ <string>daughter</string>
+ <key>debateable</key>
+ <string>debatable</string>
+ <key>decendant</key>
+ <string>descendant</string>
+ <key>decendants</key>
+ <string>descendants</string>
+ <key>decendent</key>
+ <string>descendant</string>
+ <key>decendents</key>
+ <string>descendants</string>
+ <key>decideable</key>
+ <string>decidable</string>
+ <key>decidely</key>
+ <string>decidedly</string>
+ <key>decieved</key>
+ <string>deceived</string>
+ <key>decison</key>
+ <string>decision</string>
+ <key>decomissioned</key>
+ <string>decommissioned</string>
+ <key>decomposit</key>
+ <string>decompose</string>
+ <key>decomposited</key>
+ <string>decomposed</string>
+ <key>decompositing</key>
+ <string>decomposing</string>
+ <key>decomposits</key>
+ <string>decomposes</string>
+ <key>decress</key>
+ <string>decrees</string>
+ <key>decribe</key>
+ <string>describe</string>
+ <key>decribed</key>
+ <string>described</string>
+ <key>decribes</key>
+ <string>describes</string>
+ <key>decribing</key>
+ <string>describing</string>
+ <key>dectect</key>
+ <string>detect</string>
+ <key>defendent</key>
+ <string>defendant</string>
+ <key>defendents</key>
+ <string>defendants</string>
+ <key>deffensively</key>
+ <string>defensively</string>
+ <key>deffine</key>
+ <string>define</string>
+ <key>deffined</key>
+ <string>defined</string>
+ <key>definance</key>
+ <string>defiance</string>
+ <key>definate</key>
+ <string>definite</string>
+ <key>definately</key>
+ <string>definitely</string>
+ <key>definatly</key>
+ <string>definitely</string>
+ <key>definetly</key>
+ <string>definitely</string>
+ <key>definining</key>
+ <string>defining</string>
+ <key>definit</key>
+ <string>definite</string>
+ <key>definitly</key>
+ <string>definitely</string>
+ <key>definiton</key>
+ <string>definition</string>
+ <key>defintion</key>
+ <string>definition</string>
+ <key>degrate</key>
+ <string>degrade</string>
+ <key>delagates</key>
+ <string>delegates</string>
+ <key>delapidated</key>
+ <string>dilapidated</string>
+ <key>delerious</key>
+ <string>delirious</string>
+ <key>delevopment</key>
+ <string>development</string>
+ <key>deliberatly</key>
+ <string>deliberately</string>
+ <key>delusionally</key>
+ <string>delusively</string>
+ <key>demenor</key>
+ <string>demeanor</string>
+ <key>demographical</key>
+ <string>demographic</string>
+ <key>demolision</key>
+ <string>demolition</string>
+ <key>demorcracy</key>
+ <string>democracy</string>
+ <key>demostration</key>
+ <string>demonstration</string>
+ <key>denegrating</key>
+ <string>denigrating</string>
+ <key>densly</key>
+ <string>densely</string>
+ <key>deparment</key>
+ <string>department</string>
+ <key>deparmental</key>
+ <string>departmental</string>
+ <key>deparments</key>
+ <string>departments</string>
+ <key>dependance</key>
+ <string>dependence</string>
+ <key>dependancy</key>
+ <string>dependency</string>
+ <key>dependant</key>
+ <string>dependent</string>
+ <key>deram</key>
+ <string>dream</string>
+ <key>deriviated</key>
+ <string>derived</string>
+ <key>derivitive</key>
+ <string>derivative</string>
+ <key>derogitory</key>
+ <string>derogatory</string>
+ <key>descendands</key>
+ <string>descendants</string>
+ <key>descibed</key>
+ <string>described</string>
+ <key>descision</key>
+ <string>decision</string>
+ <key>descisions</key>
+ <string>decisions</string>
+ <key>descriibes</key>
+ <string>describes</string>
+ <key>descripters</key>
+ <string>descriptors</string>
+ <key>descripton</key>
+ <string>description</string>
+ <key>desctruction</key>
+ <string>destruction</string>
+ <key>descuss</key>
+ <string>discuss</string>
+ <key>desgined</key>
+ <string>designed</string>
+ <key>deside</key>
+ <string>decide</string>
+ <key>desigining</key>
+ <string>designing</string>
+ <key>desinations</key>
+ <string>destinations</string>
+ <key>desintegrated</key>
+ <string>disintegrated</string>
+ <key>desintegration</key>
+ <string>disintegration</string>
+ <key>desireable</key>
+ <string>desirable</string>
+ <key>desitned</key>
+ <string>destined</string>
+ <key>desktiop</key>
+ <string>desktop</string>
+ <key>desorder</key>
+ <string>disorder</string>
+ <key>desoriented</key>
+ <string>disoriented</string>
+ <key>desparate</key>
+ <string>desperate</string>
+ <key>despict</key>
+ <string>depict</string>
+ <key>despiration</key>
+ <string>desperation</string>
+ <key>dessicated</key>
+ <string>desiccated</string>
+ <key>dessigned</key>
+ <string>designed</string>
+ <key>destablized</key>
+ <string>destabilized</string>
+ <key>destory</key>
+ <string>destroy</string>
+ <key>detailled</key>
+ <string>detailed</string>
+ <key>detatched</key>
+ <string>detached</string>
+ <key>deteoriated</key>
+ <string>deteriorated</string>
+ <key>deteriate</key>
+ <string>deteriorate</string>
+ <key>deterioriating</key>
+ <string>deteriorating</string>
+ <key>determinining</key>
+ <string>determining</string>
+ <key>detremental</key>
+ <string>detrimental</string>
+ <key>devasted</key>
+ <string>devastated</string>
+ <key>develope</key>
+ <string>develop</string>
+ <key>developement</key>
+ <string>development</string>
+ <key>developped</key>
+ <string>developed</string>
+ <key>develpment</key>
+ <string>development</string>
+ <key>devels</key>
+ <string>delves</string>
+ <key>devestated</key>
+ <string>devastated</string>
+ <key>devestating</key>
+ <string>devastating</string>
+ <key>devide</key>
+ <string>divide</string>
+ <key>devided</key>
+ <string>divided</string>
+ <key>devistating</key>
+ <string>devastating</string>
+ <key>devolopement</key>
+ <string>development</string>
+ <key>diablical</key>
+ <string>diabolical</string>
+ <key>diamons</key>
+ <string>diamonds</string>
+ <key>diaster</key>
+ <string>disaster</string>
+ <key>dichtomy</key>
+ <string>dichotomy</string>
+ <key>diconnects</key>
+ <string>disconnects</string>
+ <key>dicover</key>
+ <string>discover</string>
+ <key>dicovered</key>
+ <string>discovered</string>
+ <key>dicovering</key>
+ <string>discovering</string>
+ <key>dicovers</key>
+ <string>discovers</string>
+ <key>dicovery</key>
+ <string>discovery</string>
+ <key>dicussed</key>
+ <string>discussed</string>
+ <key>didnt</key>
+ <string>didn&apos;t</string>
+ <key>diea</key>
+ <string>idea</string>
+ <key>dieing</key>
+ <string>dying</string>
+ <key>dieties</key>
+ <string>deities</string>
+ <key>diety</key>
+ <string>deity</string>
+ <key>diferent</key>
+ <string>different</string>
+ <key>diferrent</key>
+ <string>different</string>
+ <key>differentiatiations</key>
+ <string>differentiations</string>
+ <key>differnt</key>
+ <string>different</string>
+ <key>difficulity</key>
+ <string>difficulty</string>
+ <key>diffrent</key>
+ <string>different</string>
+ <key>dificulties</key>
+ <string>difficulties</string>
+ <key>dificulty</key>
+ <string>difficulty</string>
+ <key>dimenions</key>
+ <string>dimensions</string>
+ <key>dimention</key>
+ <string>dimension</string>
+ <key>dimentional</key>
+ <string>dimensional</string>
+ <key>dimentions</key>
+ <string>dimensions</string>
+ <key>dimesnional</key>
+ <string>dimensional</string>
+ <key>diminuitive</key>
+ <string>diminutive</string>
+ <key>dimunitive</key>
+ <string>diminutive</string>
+ <key>diosese</key>
+ <string>diocese</string>
+ <key>diphtong</key>
+ <string>diphthong</string>
+ <key>diphtongs</key>
+ <string>diphthongs</string>
+ <key>diplomancy</key>
+ <string>diplomacy</string>
+ <key>dipthong</key>
+ <string>diphthong</string>
+ <key>dipthongs</key>
+ <string>diphthongs</string>
+ <key>dirived</key>
+ <string>derived</string>
+ <key>disagreeed</key>
+ <string>disagreed</string>
+ <key>disapeared</key>
+ <string>disappeared</string>
+ <key>disapointing</key>
+ <string>disappointing</string>
+ <key>disappearred</key>
+ <string>disappeared</string>
+ <key>disaproval</key>
+ <string>disapproval</string>
+ <key>disasterous</key>
+ <string>disastrous</string>
+ <key>disatisfaction</key>
+ <string>dissatisfaction</string>
+ <key>disatisfied</key>
+ <string>dissatisfied</string>
+ <key>disatrous</key>
+ <string>disastrous</string>
+ <key>discontentment</key>
+ <string>discontent</string>
+ <key>discribe</key>
+ <string>describe</string>
+ <key>discribed</key>
+ <string>described</string>
+ <key>discribes</key>
+ <string>describes</string>
+ <key>discribing</key>
+ <string>describing</string>
+ <key>disctinction</key>
+ <string>distinction</string>
+ <key>disctinctive</key>
+ <string>distinctive</string>
+ <key>disemination</key>
+ <string>dissemination</string>
+ <key>disenchanged</key>
+ <string>disenchanted</string>
+ <key>disiplined</key>
+ <string>disciplined</string>
+ <key>disobediance</key>
+ <string>disobedience</string>
+ <key>disobediant</key>
+ <string>disobedient</string>
+ <key>disolved</key>
+ <string>dissolved</string>
+ <key>disover</key>
+ <string>discover</string>
+ <key>dispair</key>
+ <string>despair</string>
+ <key>disparingly</key>
+ <string>disparagingly</string>
+ <key>dispence</key>
+ <string>dispense</string>
+ <key>dispenced</key>
+ <string>dispensed</string>
+ <key>dispencing</key>
+ <string>dispensing</string>
+ <key>dispicable</key>
+ <string>despicable</string>
+ <key>dispite</key>
+ <string>despite</string>
+ <key>dispostion</key>
+ <string>disposition</string>
+ <key>disproportiate</key>
+ <string>disproportionate</string>
+ <key>disputandem</key>
+ <string>disputandum</string>
+ <key>disricts</key>
+ <string>districts</string>
+ <key>dissagreement</key>
+ <string>disagreement</string>
+ <key>dissapear</key>
+ <string>disappear</string>
+ <key>dissapearance</key>
+ <string>disappearance</string>
+ <key>dissapeared</key>
+ <string>disappeared</string>
+ <key>dissapearing</key>
+ <string>disappearing</string>
+ <key>dissapears</key>
+ <string>disappears</string>
+ <key>dissappear</key>
+ <string>disappear</string>
+ <key>dissappears</key>
+ <string>disappears</string>
+ <key>dissappointed</key>
+ <string>disappointed</string>
+ <key>dissarray</key>
+ <string>disarray</string>
+ <key>dissobediance</key>
+ <string>disobedience</string>
+ <key>dissobediant</key>
+ <string>disobedient</string>
+ <key>dissobedience</key>
+ <string>disobedience</string>
+ <key>dissobedient</key>
+ <string>disobedient</string>
+ <key>distiction</key>
+ <string>distinction</string>
+ <key>distingish</key>
+ <string>distinguish</string>
+ <key>distingished</key>
+ <string>distinguished</string>
+ <key>distingishes</key>
+ <string>distinguishes</string>
+ <key>distingishing</key>
+ <string>distinguishing</string>
+ <key>distingquished</key>
+ <string>distinguished</string>
+ <key>distrubution</key>
+ <string>distribution</string>
+ <key>distruction</key>
+ <string>destruction</string>
+ <key>distructive</key>
+ <string>destructive</string>
+ <key>ditributed</key>
+ <string>distributed</string>
+ <key>diversed</key>
+ <string>diverged</string>
+ <key>divice</key>
+ <string>device</string>
+ <key>divison</key>
+ <string>division</string>
+ <key>divisons</key>
+ <string>divisions</string>
+ <key>doccument</key>
+ <string>document</string>
+ <key>doccumented</key>
+ <string>documented</string>
+ <key>doccuments</key>
+ <string>documents</string>
+ <key>docrines</key>
+ <string>doctrines</string>
+ <key>doctines</key>
+ <string>doctrines</string>
+ <key>documenatry</key>
+ <string>documentary</string>
+ <key>doens</key>
+ <string>does</string>
+ <key>doesnt</key>
+ <string>doesn&apos;t</string>
+ <key>doign</key>
+ <string>doing</string>
+ <key>dominaton</key>
+ <string>domination</string>
+ <key>dominent</key>
+ <string>dominant</string>
+ <key>dominiant</key>
+ <string>dominant</string>
+ <key>donig</key>
+ <string>doing</string>
+ <key>dont</key>
+ <string>don&apos;t</string>
+ <key>dosen&apos;t</key>
+ <string>doesn&apos;t</string>
+ <key>doub</key>
+ <string>doubt</string>
+ <key>doulbe</key>
+ <string>double</string>
+ <key>dowloads</key>
+ <string>downloads</string>
+ <key>dramtic</key>
+ <string>dramatic</string>
+ <key>draughtman</key>
+ <string>draughtsman</string>
+ <key>dreasm</key>
+ <string>dreams</string>
+ <key>driectly</key>
+ <string>directly</string>
+ <key>drnik</key>
+ <string>drink</string>
+ <key>druming</key>
+ <string>drumming</string>
+ <key>drummless</key>
+ <string>drumless</string>
+ <key>dupicate</key>
+ <string>duplicate</string>
+ <key>durig</key>
+ <string>during</string>
+ <key>durring</key>
+ <string>during</string>
+ <key>duting</key>
+ <string>during</string>
+ <key>dyas</key>
+ <string>dryas</string>
+ <key>eahc</key>
+ <string>each</string>
+ <key>ealier</key>
+ <string>earlier</string>
+ <key>earlies</key>
+ <string>earliest</string>
+ <key>earnt</key>
+ <string>earned</string>
+ <key>ecclectic</key>
+ <string>eclectic</string>
+ <key>eceonomy</key>
+ <string>economy</string>
+ <key>ecidious</key>
+ <string>deciduous</string>
+ <key>eclispe</key>
+ <string>eclipse</string>
+ <key>ecomonic</key>
+ <string>economic</string>
+ <key>ect</key>
+ <string>etc</string>
+ <key>eearly</key>
+ <string>early</string>
+ <key>efel</key>
+ <string>evil</string>
+ <key>effeciency</key>
+ <string>efficiency</string>
+ <key>effecient</key>
+ <string>efficient</string>
+ <key>effeciently</key>
+ <string>efficiently</string>
+ <key>efficency</key>
+ <string>efficiency</string>
+ <key>efficent</key>
+ <string>efficient</string>
+ <key>efficently</key>
+ <string>efficiently</string>
+ <key>efford</key>
+ <string>effort</string>
+ <key>effords</key>
+ <string>efforts</string>
+ <key>effulence</key>
+ <string>effluence</string>
+ <key>eigth</key>
+ <string>eight</string>
+ <key>eiter</key>
+ <string>either</string>
+ <key>elction</key>
+ <string>election</string>
+ <key>electic</key>
+ <string>electric</string>
+ <key>electon</key>
+ <string>electron</string>
+ <key>electrial</key>
+ <string>electrical</string>
+ <key>electricly</key>
+ <string>electrically</string>
+ <key>electricty</key>
+ <string>electricity</string>
+ <key>elementay</key>
+ <string>elementary</string>
+ <key>eleminated</key>
+ <string>eliminated</string>
+ <key>eleminating</key>
+ <string>eliminating</string>
+ <key>eles</key>
+ <string>eels</string>
+ <key>eletricity</key>
+ <string>electricity</string>
+ <key>elicided</key>
+ <string>elicited</string>
+ <key>eligable</key>
+ <string>eligible</string>
+ <key>elimentary</key>
+ <string>elementary</string>
+ <key>ellected</key>
+ <string>elected</string>
+ <key>elphant</key>
+ <string>elephant</string>
+ <key>embarass</key>
+ <string>embarrass</string>
+ <key>embarassed</key>
+ <string>embarrassed</string>
+ <key>embarassing</key>
+ <string>embarrassing</string>
+ <key>embarassment</key>
+ <string>embarrassment</string>
+ <key>embargos</key>
+ <string>embargoes</string>
+ <key>embarras</key>
+ <string>embarrass</string>
+ <key>embarrased</key>
+ <string>embarrassed</string>
+ <key>embarrasing</key>
+ <string>embarrassing</string>
+ <key>embarrasment</key>
+ <string>embarrassment</string>
+ <key>embezelled</key>
+ <string>embezzled</string>
+ <key>emblamatic</key>
+ <string>emblematic</string>
+ <key>eminate</key>
+ <string>emanate</string>
+ <key>eminated</key>
+ <string>emanated</string>
+ <key>emision</key>
+ <string>emission</string>
+ <key>emited</key>
+ <string>emitted</string>
+ <key>emiting</key>
+ <string>emitting</string>
+ <key>emition</key>
+ <string>emission</string>
+ <key>emmediately</key>
+ <string>immediately</string>
+ <key>emmigrated</key>
+ <string>immigrated</string>
+ <key>emminently</key>
+ <string>eminently</string>
+ <key>emmisaries</key>
+ <string>emissaries</string>
+ <key>emmisarries</key>
+ <string>emissaries</string>
+ <key>emmisarry</key>
+ <string>emissary</string>
+ <key>emmisary</key>
+ <string>emissary</string>
+ <key>emmision</key>
+ <string>emission</string>
+ <key>emmisions</key>
+ <string>emissions</string>
+ <key>emmited</key>
+ <string>emitted</string>
+ <key>emmiting</key>
+ <string>emitting</string>
+ <key>emmitted</key>
+ <string>emitted</string>
+ <key>emmitting</key>
+ <string>emitting</string>
+ <key>emnity</key>
+ <string>enmity</string>
+ <key>emperical</key>
+ <string>empirical</string>
+ <key>emphaised</key>
+ <string>emphasised</string>
+ <key>emphsis</key>
+ <string>emphasis</string>
+ <key>emphysyma</key>
+ <string>emphysema</string>
+ <key>emprisoned</key>
+ <string>imprisoned</string>
+ <key>enameld</key>
+ <string>enameled</string>
+ <key>enchancement</key>
+ <string>enhancement</string>
+ <key>encouraing</key>
+ <string>encouraging</string>
+ <key>encryptiion</key>
+ <string>encryption</string>
+ <key>encylopedia</key>
+ <string>encyclopedia</string>
+ <key>endevors</key>
+ <string>endeavors</string>
+ <key>endevour</key>
+ <string>endeavour</string>
+ <key>endig</key>
+ <string>ending</string>
+ <key>endolithes</key>
+ <string>endoliths</string>
+ <key>enduce</key>
+ <string>induce</string>
+ <key>ened</key>
+ <string>need</string>
+ <key>enflamed</key>
+ <string>inflamed</string>
+ <key>enforceing</key>
+ <string>enforcing</string>
+ <key>engagment</key>
+ <string>engagement</string>
+ <key>engeneer</key>
+ <string>engineer</string>
+ <key>engeneering</key>
+ <string>engineering</string>
+ <key>engieneer</key>
+ <string>engineer</string>
+ <key>engieneers</key>
+ <string>engineers</string>
+ <key>enlargment</key>
+ <string>enlargement</string>
+ <key>enlargments</key>
+ <string>enlargements</string>
+ <key>enourmous</key>
+ <string>enormous</string>
+ <key>enourmously</key>
+ <string>enormously</string>
+ <key>ensconsed</key>
+ <string>ensconced</string>
+ <key>entaglements</key>
+ <string>entanglements</string>
+ <key>enteratinment</key>
+ <string>entertainment</string>
+ <key>enthusiatic</key>
+ <string>enthusiastic</string>
+ <key>entitity</key>
+ <string>entity</string>
+ <key>entitlied</key>
+ <string>entitled</string>
+ <key>entrepeneur</key>
+ <string>entrepreneur</string>
+ <key>entrepeneurs</key>
+ <string>entrepreneurs</string>
+ <key>enviorment</key>
+ <string>environment</string>
+ <key>enviormental</key>
+ <string>environmental</string>
+ <key>enviormentally</key>
+ <string>environmentally</string>
+ <key>enviorments</key>
+ <string>environments</string>
+ <key>enviornment</key>
+ <string>environment</string>
+ <key>enviornmental</key>
+ <string>environmental</string>
+ <key>enviornmentalist</key>
+ <string>environmentalist</string>
+ <key>enviornmentally</key>
+ <string>environmentally</string>
+ <key>enviornments</key>
+ <string>environments</string>
+ <key>enviroment</key>
+ <string>environment</string>
+ <key>enviromental</key>
+ <string>environmental</string>
+ <key>enviromentalist</key>
+ <string>environmentalist</string>
+ <key>enviromentally</key>
+ <string>environmentally</string>
+ <key>enviroments</key>
+ <string>environments</string>
+ <key>envolutionary</key>
+ <string>evolutionary</string>
+ <key>envrionments</key>
+ <string>environments</string>
+ <key>enxt</key>
+ <string>next</string>
+ <key>epidsodes</key>
+ <string>episodes</string>
+ <key>epsiode</key>
+ <string>episode</string>
+ <key>equialent</key>
+ <string>equivalent</string>
+ <key>equilibium</key>
+ <string>equilibrium</string>
+ <key>equilibrum</key>
+ <string>equilibrium</string>
+ <key>equiped</key>
+ <string>equipped</string>
+ <key>equippment</key>
+ <string>equipment</string>
+ <key>equitorial</key>
+ <string>equatorial</string>
+ <key>equivelant</key>
+ <string>equivalent</string>
+ <key>equivelent</key>
+ <string>equivalent</string>
+ <key>equivilant</key>
+ <string>equivalent</string>
+ <key>equivilent</key>
+ <string>equivalent</string>
+ <key>equivlalent</key>
+ <string>equivalent</string>
+ <key>erally</key>
+ <string>really</string>
+ <key>eratic</key>
+ <string>erratic</string>
+ <key>eratically</key>
+ <string>erratically</string>
+ <key>eraticly</key>
+ <string>erratically</string>
+ <key>errupted</key>
+ <string>erupted</string>
+ <key>esential</key>
+ <string>essential</string>
+ <key>esitmated</key>
+ <string>estimated</string>
+ <key>esle</key>
+ <string>else</string>
+ <key>especialy</key>
+ <string>especially</string>
+ <key>essencial</key>
+ <string>essential</string>
+ <key>essense</key>
+ <string>essence</string>
+ <key>essentail</key>
+ <string>essential</string>
+ <key>essentialy</key>
+ <string>essentially</string>
+ <key>essentual</key>
+ <string>essential</string>
+ <key>essesital</key>
+ <string>essential</string>
+ <key>estabishes</key>
+ <string>establishes</string>
+ <key>establising</key>
+ <string>establishing</string>
+ <key>ethnocentricm</key>
+ <string>ethnocentrism</string>
+ <key>ethose</key>
+ <string>those</string>
+ <key>evenhtually</key>
+ <string>eventually</string>
+ <key>eventally</key>
+ <string>eventually</string>
+ <key>eventhough</key>
+ <string>even though</string>
+ <key>eventially</key>
+ <string>eventually</string>
+ <key>eventualy</key>
+ <string>eventually</string>
+ <key>everthing</key>
+ <string>everything</string>
+ <key>everytime</key>
+ <string>every time</string>
+ <key>everyting</key>
+ <string>everything</string>
+ <key>eveyr</key>
+ <string>every</string>
+ <key>evidentally</key>
+ <string>evidently</string>
+ <key>exagerate</key>
+ <string>exaggerate</string>
+ <key>exagerated</key>
+ <string>exaggerated</string>
+ <key>exagerates</key>
+ <string>exaggerates</string>
+ <key>exagerating</key>
+ <string>exaggerating</string>
+ <key>exagerrate</key>
+ <string>exaggerate</string>
+ <key>exagerrated</key>
+ <string>exaggerated</string>
+ <key>exagerrates</key>
+ <string>exaggerates</string>
+ <key>exagerrating</key>
+ <string>exaggerating</string>
+ <key>examinated</key>
+ <string>examined</string>
+ <key>exampt</key>
+ <string>exempt</string>
+ <key>exapansion</key>
+ <string>expansion</string>
+ <key>excact</key>
+ <string>exact</string>
+ <key>excange</key>
+ <string>exchange</string>
+ <key>excecute</key>
+ <string>execute</string>
+ <key>excecuted</key>
+ <string>executed</string>
+ <key>excecutes</key>
+ <string>executes</string>
+ <key>excecuting</key>
+ <string>executing</string>
+ <key>excecution</key>
+ <string>execution</string>
+ <key>excedded</key>
+ <string>exceeded</string>
+ <key>excelent</key>
+ <string>excellent</string>
+ <key>excell</key>
+ <string>excel</string>
+ <key>excellance</key>
+ <string>excellence</string>
+ <key>excellant</key>
+ <string>excellent</string>
+ <key>excells</key>
+ <string>excels</string>
+ <key>excercise</key>
+ <string>exercise</string>
+ <key>exchanching</key>
+ <string>exchanging</string>
+ <key>excisted</key>
+ <string>existed</string>
+ <key>exculsivly</key>
+ <string>exclusively</string>
+ <key>execising</key>
+ <string>exercising</string>
+ <key>exection</key>
+ <string>execution</string>
+ <key>exectued</key>
+ <string>executed</string>
+ <key>exeedingly</key>
+ <string>exceedingly</string>
+ <key>exelent</key>
+ <string>excellent</string>
+ <key>exellent</key>
+ <string>excellent</string>
+ <key>exemple</key>
+ <string>example</string>
+ <key>exept</key>
+ <string>except</string>
+ <key>exeptional</key>
+ <string>exceptional</string>
+ <key>exerbate</key>
+ <string>exacerbate</string>
+ <key>exerbated</key>
+ <string>exacerbated</string>
+ <key>exerciese</key>
+ <string>exercises</string>
+ <key>exerpt</key>
+ <string>excerpt</string>
+ <key>exerpts</key>
+ <string>excerpts</string>
+ <key>exersize</key>
+ <string>exercise</string>
+ <key>exerternal</key>
+ <string>external</string>
+ <key>exhalted</key>
+ <string>exalted</string>
+ <key>exhibtion</key>
+ <string>exhibition</string>
+ <key>exibition</key>
+ <string>exhibition</string>
+ <key>exibitions</key>
+ <string>exhibitions</string>
+ <key>exicting</key>
+ <string>exciting</string>
+ <key>exinct</key>
+ <string>extinct</string>
+ <key>existance</key>
+ <string>existence</string>
+ <key>existant</key>
+ <string>existent</string>
+ <key>existince</key>
+ <string>existence</string>
+ <key>exliled</key>
+ <string>exiled</string>
+ <key>exludes</key>
+ <string>excludes</string>
+ <key>exmaple</key>
+ <string>example</string>
+ <key>exonorate</key>
+ <string>exonerate</string>
+ <key>exoskelaton</key>
+ <string>exoskeleton</string>
+ <key>expalin</key>
+ <string>explain</string>
+ <key>expatriot</key>
+ <string>expatriate</string>
+ <key>expeced</key>
+ <string>expected</string>
+ <key>expecially</key>
+ <string>especially</string>
+ <key>expeditonary</key>
+ <string>expeditionary</string>
+ <key>expeiments</key>
+ <string>experiments</string>
+ <key>expell</key>
+ <string>expel</string>
+ <key>expells</key>
+ <string>expels</string>
+ <key>experiance</key>
+ <string>experience</string>
+ <key>experianced</key>
+ <string>experienced</string>
+ <key>expiditions</key>
+ <string>expeditions</string>
+ <key>expierence</key>
+ <string>experience</string>
+ <key>explaination</key>
+ <string>explanation</string>
+ <key>explaning</key>
+ <string>explaining</string>
+ <key>explictly</key>
+ <string>explicitly</string>
+ <key>exploititive</key>
+ <string>exploitative</string>
+ <key>explotation</key>
+ <string>exploitation</string>
+ <key>expropiated</key>
+ <string>expropriated</string>
+ <key>expropiation</key>
+ <string>expropriation</string>
+ <key>exressed</key>
+ <string>expressed</string>
+ <key>extemely</key>
+ <string>extremely</string>
+ <key>extention</key>
+ <string>extension</string>
+ <key>extentions</key>
+ <string>extensions</string>
+ <key>extered</key>
+ <string>exerted</string>
+ <key>extermist</key>
+ <string>extremist</string>
+ <key>extint</key>
+ <string>extinct</string>
+ <key>extradiction</key>
+ <string>extradition</string>
+ <key>extraterrestial</key>
+ <string>extraterrestrial</string>
+ <key>extraterrestials</key>
+ <string>extraterrestrials</string>
+ <key>extravagent</key>
+ <string>extravagant</string>
+ <key>extrememly</key>
+ <string>extremely</string>
+ <key>extremeophile</key>
+ <string>extremophile</string>
+ <key>extremly</key>
+ <string>extremely</string>
+ <key>extrordinarily</key>
+ <string>extraordinarily</string>
+ <key>extrordinary</key>
+ <string>extraordinary</string>
+ <key>eyar</key>
+ <string>year</string>
+ <key>eyars</key>
+ <string>years</string>
+ <key>eyasr</key>
+ <string>years</string>
+ <key>faciliate</key>
+ <string>facilitate</string>
+ <key>faciliated</key>
+ <string>facilitated</string>
+ <key>faciliates</key>
+ <string>facilitates</string>
+ <key>facilites</key>
+ <string>facilities</string>
+ <key>facillitate</key>
+ <string>facilitate</string>
+ <key>facinated</key>
+ <string>fascinated</string>
+ <key>facist</key>
+ <string>fascist</string>
+ <key>familes</key>
+ <string>families</string>
+ <key>familliar</key>
+ <string>familiar</string>
+ <key>famoust</key>
+ <string>famous</string>
+ <key>fanatism</key>
+ <string>fanaticism</string>
+ <key>fatc</key>
+ <string>fact</string>
+ <key>faught</key>
+ <string>fought</string>
+ <key>favoutrable</key>
+ <string>favourable</string>
+ <key>feasable</key>
+ <string>feasible</string>
+ <key>fedreally</key>
+ <string>federally</string>
+ <key>feromone</key>
+ <string>pheromone</string>
+ <key>fertily</key>
+ <string>fertility</string>
+ <key>fianite</key>
+ <string>finite</string>
+ <key>fianlly</key>
+ <string>finally</string>
+ <key>ficticious</key>
+ <string>fictitious</string>
+ <key>fictious</key>
+ <string>fictitious</string>
+ <key>fidn</key>
+ <string>find</string>
+ <key>fiercly</key>
+ <string>fiercely</string>
+ <key>fightings</key>
+ <string>fighting</string>
+ <key>filiament</key>
+ <string>filament</string>
+ <key>fimilies</key>
+ <string>families</string>
+ <key>finacial</key>
+ <string>financial</string>
+ <key>finaly</key>
+ <string>finally</string>
+ <key>financialy</key>
+ <string>financially</string>
+ <key>firends</key>
+ <string>friends</string>
+ <key>firts</key>
+ <string>first</string>
+ <key>fisionable</key>
+ <string>fissionable</string>
+ <key>flamable</key>
+ <string>flammable</string>
+ <key>flawess</key>
+ <string>flawless</string>
+ <key>fleed</key>
+ <string>fled</string>
+ <key>florescent</key>
+ <string>fluorescent</string>
+ <key>flourescent</key>
+ <string>fluorescent</string>
+ <key>flourine</key>
+ <string>fluorine</string>
+ <key>fluorish</key>
+ <string>flourish</string>
+ <key>follwoing</key>
+ <string>following</string>
+ <key>folowing</key>
+ <string>following</string>
+ <key>fomed</key>
+ <string>formed</string>
+ <key>fomr</key>
+ <string>from</string>
+ <key>fonetic</key>
+ <string>phonetic</string>
+ <key>fontrier</key>
+ <string>fontier</string>
+ <key>foootball</key>
+ <string>football</string>
+ <key>forbad</key>
+ <string>forbade</string>
+ <key>forbiden</key>
+ <string>forbidden</string>
+ <key>foreward</key>
+ <string>foreword</string>
+ <key>forfiet</key>
+ <string>forfeit</string>
+ <key>forhead</key>
+ <string>forehead</string>
+ <key>foriegn</key>
+ <string>foreign</string>
+ <key>formallize</key>
+ <string>formalize</string>
+ <key>formallized</key>
+ <string>formalized</string>
+ <key>formaly</key>
+ <string>formally</string>
+ <key>formelly</key>
+ <string>formerly</string>
+ <key>formidible</key>
+ <string>formidable</string>
+ <key>formost</key>
+ <string>foremost</string>
+ <key>forsaw</key>
+ <string>foresaw</string>
+ <key>forseeable</key>
+ <string>foreseeable</string>
+ <key>fortelling</key>
+ <string>foretelling</string>
+ <key>forunner</key>
+ <string>forerunner</string>
+ <key>foucs</key>
+ <string>focus</string>
+ <key>foudn</key>
+ <string>found</string>
+ <key>fougth</key>
+ <string>fought</string>
+ <key>foundaries</key>
+ <string>foundries</string>
+ <key>foundary</key>
+ <string>foundry</string>
+ <key>fourties</key>
+ <string>forties</string>
+ <key>fourty</key>
+ <string>forty</string>
+ <key>fouth</key>
+ <string>fourth</string>
+ <key>foward</key>
+ <string>forward</string>
+ <key>freind</key>
+ <string>friend</string>
+ <key>freindly</key>
+ <string>friendly</string>
+ <key>frequentily</key>
+ <string>frequently</string>
+ <key>frome</key>
+ <string>from</string>
+ <key>fromed</key>
+ <string>formed</string>
+ <key>froniter</key>
+ <string>frontier</string>
+ <key>fucntion</key>
+ <string>function</string>
+ <key>fucntioning</key>
+ <string>functioning</string>
+ <key>fufill</key>
+ <string>fulfill</string>
+ <key>fufilled</key>
+ <string>fulfilled</string>
+ <key>fulfiled</key>
+ <string>fulfilled</string>
+ <key>fullfill</key>
+ <string>fulfill</string>
+ <key>fullfilled</key>
+ <string>fulfilled</string>
+ <key>fundametal</key>
+ <string>fundamental</string>
+ <key>fundametals</key>
+ <string>fundamentals</string>
+ <key>funguses</key>
+ <string>fungi</string>
+ <key>funtion</key>
+ <string>function</string>
+ <key>furuther</key>
+ <string>further</string>
+ <key>futher</key>
+ <string>further</string>
+ <key>futhermore</key>
+ <string>furthermore</string>
+ <key>galatic</key>
+ <string>galactic</string>
+ <key>gallaxies</key>
+ <string>galaxies</string>
+ <key>galvinized</key>
+ <string>galvanized</string>
+ <key>ganerate</key>
+ <string>generate</string>
+ <key>ganes</key>
+ <string>games</string>
+ <key>ganster</key>
+ <string>gangster</string>
+ <key>garantee</key>
+ <string>guarantee</string>
+ <key>garanteed</key>
+ <string>guaranteed</string>
+ <key>garantees</key>
+ <string>guarantees</string>
+ <key>garnison</key>
+ <string>garrison</string>
+ <key>gaurantee</key>
+ <string>guarantee</string>
+ <key>gauranteed</key>
+ <string>guaranteed</string>
+ <key>gaurantees</key>
+ <string>guarantees</string>
+ <key>gaurd</key>
+ <string>guard</string>
+ <key>gaurentee</key>
+ <string>guarantee</string>
+ <key>gaurenteed</key>
+ <string>guaranteed</string>
+ <key>gaurentees</key>
+ <string>guarantees</string>
+ <key>geneological</key>
+ <string>genealogical</string>
+ <key>geneologies</key>
+ <string>genealogies</string>
+ <key>geneology</key>
+ <string>genealogy</string>
+ <key>generaly</key>
+ <string>generally</string>
+ <key>generatting</key>
+ <string>generating</string>
+ <key>genialia</key>
+ <string>genitalia</string>
+ <key>geographicial</key>
+ <string>geographical</string>
+ <key>geometrician</key>
+ <string>geometer</string>
+ <key>geometricians</key>
+ <string>geometers</string>
+ <key>gerat</key>
+ <string>great</string>
+ <key>glight</key>
+ <string>flight</string>
+ <key>gnawwed</key>
+ <string>gnawed</string>
+ <key>godess</key>
+ <string>goddess</string>
+ <key>godesses</key>
+ <string>goddesses</string>
+ <key>gogin</key>
+ <string>going</string>
+ <key>goign</key>
+ <string>going</string>
+ <key>gonig</key>
+ <string>going</string>
+ <key>gouvener</key>
+ <string>governor</string>
+ <key>govement</key>
+ <string>government</string>
+ <key>govenment</key>
+ <string>government</string>
+ <key>govenrment</key>
+ <string>government</string>
+ <key>goverance</key>
+ <string>governance</string>
+ <key>goverment</key>
+ <string>government</string>
+ <key>govermental</key>
+ <string>governmental</string>
+ <key>governer</key>
+ <string>governor</string>
+ <key>governmnet</key>
+ <string>government</string>
+ <key>govorment</key>
+ <string>government</string>
+ <key>govormental</key>
+ <string>governmental</string>
+ <key>govornment</key>
+ <string>government</string>
+ <key>gracefull</key>
+ <string>graceful</string>
+ <key>graet</key>
+ <string>great</string>
+ <key>grafitti</key>
+ <string>graffiti</string>
+ <key>gramatically</key>
+ <string>grammatically</string>
+ <key>grammaticaly</key>
+ <string>grammatically</string>
+ <key>grammer</key>
+ <string>grammar</string>
+ <key>grat</key>
+ <string>great</string>
+ <key>gratuitious</key>
+ <string>gratuitous</string>
+ <key>greatful</key>
+ <string>grateful</string>
+ <key>greatfully</key>
+ <string>gratefully</string>
+ <key>greif</key>
+ <string>grief</string>
+ <key>gridles</key>
+ <string>griddles</string>
+ <key>gropu</key>
+ <string>group</string>
+ <key>grwo</key>
+ <string>grow</string>
+ <key>guage</key>
+ <string>gauge</string>
+ <key>guarentee</key>
+ <string>guarantee</string>
+ <key>guarenteed</key>
+ <string>guaranteed</string>
+ <key>guarentees</key>
+ <string>guarantees</string>
+ <key>guerilla</key>
+ <string>guerrilla</string>
+ <key>guerillas</key>
+ <string>guerrillas</string>
+ <key>guerrila</key>
+ <string>guerrilla</string>
+ <key>guerrilas</key>
+ <string>guerrillas</string>
+ <key>guidence</key>
+ <string>guidance</string>
+ <key>gunanine</key>
+ <string>guanine</string>
+ <key>gurantee</key>
+ <string>guarantee</string>
+ <key>guranteed</key>
+ <string>guaranteed</string>
+ <key>gurantees</key>
+ <string>guarantees</string>
+ <key>guttaral</key>
+ <string>guttural</string>
+ <key>gutteral</key>
+ <string>guttural</string>
+ <key>habaeus</key>
+ <string>habeas</string>
+ <key>habeus</key>
+ <string>habeas</string>
+ <key>haemorrage</key>
+ <string>haemorrhage</string>
+ <key>haev</key>
+ <string>have</string>
+ <key>halp</key>
+ <string>help</string>
+ <key>hapen</key>
+ <string>happen</string>
+ <key>hapened</key>
+ <string>happened</string>
+ <key>hapening</key>
+ <string>happening</string>
+ <key>happend</key>
+ <string>happened</string>
+ <key>happended</key>
+ <string>happened</string>
+ <key>happenned</key>
+ <string>happened</string>
+ <key>harased</key>
+ <string>harassed</string>
+ <key>harases</key>
+ <string>harasses</string>
+ <key>harasment</key>
+ <string>harassment</string>
+ <key>harasments</key>
+ <string>harassments</string>
+ <key>harassement</key>
+ <string>harassment</string>
+ <key>harras</key>
+ <string>harass</string>
+ <key>harrased</key>
+ <string>harassed</string>
+ <key>harrases</key>
+ <string>harasses</string>
+ <key>harrasing</key>
+ <string>harassing</string>
+ <key>harrasment</key>
+ <string>harassment</string>
+ <key>harrasments</key>
+ <string>harassments</string>
+ <key>harrassed</key>
+ <string>harassed</string>
+ <key>harrasses</key>
+ <string>harassed</string>
+ <key>harrassing</key>
+ <string>harassing</string>
+ <key>harrassment</key>
+ <string>harassment</string>
+ <key>harrassments</key>
+ <string>harassments</string>
+ <key>hasnt</key>
+ <string>hasn&apos;t</string>
+ <key>haviest</key>
+ <string>heaviest</string>
+ <key>headquarer</key>
+ <string>headquarter</string>
+ <key>headquater</key>
+ <string>headquarter</string>
+ <key>headquatered</key>
+ <string>headquartered</string>
+ <key>headquaters</key>
+ <string>headquarters</string>
+ <key>healthercare</key>
+ <string>healthcare</string>
+ <key>heared</key>
+ <string>heard</string>
+ <key>heathy</key>
+ <string>healthy</string>
+ <key>heigher</key>
+ <string>higher</string>
+ <key>heirarchy</key>
+ <string>hierarchy</string>
+ <key>heiroglyphics</key>
+ <string>hieroglyphics</string>
+ <key>helment</key>
+ <string>helmet</string>
+ <key>helpfull</key>
+ <string>helpful</string>
+ <key>helpped</key>
+ <string>helped</string>
+ <key>hemmorhage</key>
+ <string>hemorrhage</string>
+ <key>herad</key>
+ <string>heard</string>
+ <key>heridity</key>
+ <string>heredity</string>
+ <key>heroe</key>
+ <string>hero</string>
+ <key>heros</key>
+ <string>heroes</string>
+ <key>hertiage</key>
+ <string>heritage</string>
+ <key>hertzs</key>
+ <string>hertz</string>
+ <key>hesistant</key>
+ <string>hesitant</string>
+ <key>heterogenous</key>
+ <string>heterogeneous</string>
+ <key>hieght</key>
+ <string>height</string>
+ <key>hierachical</key>
+ <string>hierarchical</string>
+ <key>hierachies</key>
+ <string>hierarchies</string>
+ <key>hierachy</key>
+ <string>hierarchy</string>
+ <key>hierarcical</key>
+ <string>hierarchical</string>
+ <key>hierarcy</key>
+ <string>hierarchy</string>
+ <key>hieroglph</key>
+ <string>hieroglyph</string>
+ <key>hieroglphs</key>
+ <string>hieroglyphs</string>
+ <key>higer</key>
+ <string>higher</string>
+ <key>higest</key>
+ <string>highest</string>
+ <key>higway</key>
+ <string>highway</string>
+ <key>hillarious</key>
+ <string>hilarious</string>
+ <key>himselv</key>
+ <string>himself</string>
+ <key>hinderance</key>
+ <string>hindrance</string>
+ <key>hinderence</key>
+ <string>hindrance</string>
+ <key>hindrence</key>
+ <string>hindrance</string>
+ <key>hipopotamus</key>
+ <string>hippopotamus</string>
+ <key>hismelf</key>
+ <string>himself</string>
+ <key>histocompatability</key>
+ <string>histocompatibility</string>
+ <key>historicians</key>
+ <string>historians</string>
+ <key>hitsingles</key>
+ <string>hit singles</string>
+ <key>holliday</key>
+ <string>holiday</string>
+ <key>homestate</key>
+ <string>home state</string>
+ <key>homogeneize</key>
+ <string>homogenize</string>
+ <key>homogeneized</key>
+ <string>homogenized</string>
+ <key>honory</key>
+ <string>honorary</string>
+ <key>horrifing</key>
+ <string>horrifying</string>
+ <key>hosited</key>
+ <string>hoisted</string>
+ <key>hospitible</key>
+ <string>hospitable</string>
+ <key>hounour</key>
+ <string>honour</string>
+ <key>housr</key>
+ <string>hours</string>
+ <key>howver</key>
+ <string>however</string>
+ <key>hsitorians</key>
+ <string>historians</string>
+ <key>hstory</key>
+ <string>history</string>
+ <key>hten</key>
+ <string>then</string>
+ <key>htere</key>
+ <string>there</string>
+ <key>htey</key>
+ <string>they</string>
+ <key>htikn</key>
+ <string>think</string>
+ <key>hting</key>
+ <string>thing</string>
+ <key>htink</key>
+ <string>think</string>
+ <key>htis</key>
+ <string>this</string>
+ <key>humer</key>
+ <string>humor</string>
+ <key>humerous</key>
+ <string>humorous</string>
+ <key>huminoid</key>
+ <string>humanoid</string>
+ <key>humoural</key>
+ <string>humoral</string>
+ <key>humurous</key>
+ <string>humorous</string>
+ <key>husban</key>
+ <string>husband</string>
+ <key>hvae</key>
+ <string>have</string>
+ <key>hvaing</key>
+ <string>having</string>
+ <key>hvea</key>
+ <string>have</string>
+ <key>hwihc</key>
+ <string>which</string>
+ <key>hwile</key>
+ <string>while</string>
+ <key>hwole</key>
+ <string>whole</string>
+ <key>hydogen</key>
+ <string>hydrogen</string>
+ <key>hydropile</key>
+ <string>hydrophile</string>
+ <key>hydropilic</key>
+ <string>hydrophilic</string>
+ <key>hydropobe</key>
+ <string>hydrophobe</string>
+ <key>hydropobic</key>
+ <string>hydrophobic</string>
+ <key>hygeine</key>
+ <string>hygiene</string>
+ <key>hypocracy</key>
+ <string>hypocrisy</string>
+ <key>hypocrasy</key>
+ <string>hypocrisy</string>
+ <key>hypocricy</key>
+ <string>hypocrisy</string>
+ <key>hypocrit</key>
+ <string>hypocrite</string>
+ <key>hypocrits</key>
+ <string>hypocrites</string>
+ <key>i</key>
+ <string>I</string>
+ <key>iconclastic</key>
+ <string>iconoclastic</string>
+ <key>idaeidae</key>
+ <string>idea</string>
+ <key>idaes</key>
+ <string>ideas</string>
+ <key>idealogies</key>
+ <string>ideologies</string>
+ <key>idealogy</key>
+ <string>ideology</string>
+ <key>identicial</key>
+ <string>identical</string>
+ <key>identifers</key>
+ <string>identifiers</string>
+ <key>ideosyncratic</key>
+ <string>idiosyncratic</string>
+ <key>idesa</key>
+ <string>ideas</string>
+ <key>idiosyncracy</key>
+ <string>idiosyncrasy</string>
+ <key>illegimacy</key>
+ <string>illegitimacy</string>
+ <key>illegitmate</key>
+ <string>illegitimate</string>
+ <key>illess</key>
+ <string>illness</string>
+ <key>illiegal</key>
+ <string>illegal</string>
+ <key>illution</key>
+ <string>illusion</string>
+ <key>ilness</key>
+ <string>illness</string>
+ <key>ilogical</key>
+ <string>illogical</string>
+ <key>imagenary</key>
+ <string>imaginary</string>
+ <key>imagin</key>
+ <string>imagine</string>
+ <key>imaginery</key>
+ <string>imaginary</string>
+ <key>imcomplete</key>
+ <string>incomplete</string>
+ <key>imediately</key>
+ <string>immediately</string>
+ <key>imense</key>
+ <string>immense</string>
+ <key>immediatley</key>
+ <string>immediately</string>
+ <key>immediatly</key>
+ <string>immediately</string>
+ <key>immidately</key>
+ <string>immediately</string>
+ <key>immidiately</key>
+ <string>immediately</string>
+ <key>immitate</key>
+ <string>imitate</string>
+ <key>immitated</key>
+ <string>imitated</string>
+ <key>immitating</key>
+ <string>imitating</string>
+ <key>immitator</key>
+ <string>imitator</string>
+ <key>immunosupressant</key>
+ <string>immunosuppressant</string>
+ <key>impecabbly</key>
+ <string>impeccably</string>
+ <key>impedence</key>
+ <string>impedance</string>
+ <key>implamenting</key>
+ <string>implementing</string>
+ <key>impliment</key>
+ <string>implement</string>
+ <key>implimented</key>
+ <string>implemented</string>
+ <key>imploys</key>
+ <string>employs</string>
+ <key>importamt</key>
+ <string>important</string>
+ <key>imprioned</key>
+ <string>imprisoned</string>
+ <key>imprisonned</key>
+ <string>imprisoned</string>
+ <key>improvision</key>
+ <string>improvisation</string>
+ <key>improvments</key>
+ <string>improvements</string>
+ <key>inablility</key>
+ <string>inability</string>
+ <key>inaccessable</key>
+ <string>inaccessible</string>
+ <key>inadiquate</key>
+ <string>inadequate</string>
+ <key>inadquate</key>
+ <string>inadequate</string>
+ <key>inadvertant</key>
+ <string>inadvertent</string>
+ <key>inadvertantly</key>
+ <string>inadvertently</string>
+ <key>inagurated</key>
+ <string>inaugurated</string>
+ <key>inaguration</key>
+ <string>inauguration</string>
+ <key>inappropiate</key>
+ <string>inappropriate</string>
+ <key>inaugures</key>
+ <string>inaugurates</string>
+ <key>inbalance</key>
+ <string>imbalance</string>
+ <key>inbalanced</key>
+ <string>imbalanced</string>
+ <key>inbetween</key>
+ <string>between</string>
+ <key>incarcirated</key>
+ <string>incarcerated</string>
+ <key>incidentially</key>
+ <string>incidentally</string>
+ <key>incidently</key>
+ <string>incidentally</string>
+ <key>inclreased</key>
+ <string>increased</string>
+ <key>includ</key>
+ <string>include</string>
+ <key>includng</key>
+ <string>including</string>
+ <key>incompatabilities</key>
+ <string>incompatibilities</string>
+ <key>incompatability</key>
+ <string>incompatibility</string>
+ <key>incompatable</key>
+ <string>incompatible</string>
+ <key>incompatablities</key>
+ <string>incompatibilities</string>
+ <key>incompatablity</key>
+ <string>incompatibility</string>
+ <key>incompatiblities</key>
+ <string>incompatibilities</string>
+ <key>incompatiblity</key>
+ <string>incompatibility</string>
+ <key>incompetance</key>
+ <string>incompetence</string>
+ <key>incompetant</key>
+ <string>incompetent</string>
+ <key>incomptable</key>
+ <string>incompatible</string>
+ <key>incomptetent</key>
+ <string>incompetent</string>
+ <key>inconsistant</key>
+ <string>inconsistent</string>
+ <key>incoroporated</key>
+ <string>incorporated</string>
+ <key>incorperation</key>
+ <string>incorporation</string>
+ <key>incorportaed</key>
+ <string>incorporated</string>
+ <key>incorprates</key>
+ <string>incorporates</string>
+ <key>incorruptable</key>
+ <string>incorruptible</string>
+ <key>incramentally</key>
+ <string>incrementally</string>
+ <key>increadible</key>
+ <string>incredible</string>
+ <key>incredable</key>
+ <string>incredible</string>
+ <key>inctroduce</key>
+ <string>introduce</string>
+ <key>inctroduced</key>
+ <string>introduced</string>
+ <key>incuding</key>
+ <string>including</string>
+ <key>incunabla</key>
+ <string>incunabula</string>
+ <key>indefinately</key>
+ <string>indefinitely</string>
+ <key>indefineable</key>
+ <string>undefinable</string>
+ <key>indefinitly</key>
+ <string>indefinitely</string>
+ <key>indentical</key>
+ <string>identical</string>
+ <key>indepedantly</key>
+ <string>independently</string>
+ <key>indepedence</key>
+ <string>independence</string>
+ <key>independance</key>
+ <string>independence</string>
+ <key>independant</key>
+ <string>independent</string>
+ <key>independantly</key>
+ <string>independently</string>
+ <key>independece</key>
+ <string>independence</string>
+ <key>independendet</key>
+ <string>independent</string>
+ <key>indespensable</key>
+ <string>indispensable</string>
+ <key>indespensible</key>
+ <string>indispensable</string>
+ <key>indictement</key>
+ <string>indictment</string>
+ <key>indigineous</key>
+ <string>indigenous</string>
+ <key>indipendence</key>
+ <string>independence</string>
+ <key>indipendent</key>
+ <string>independent</string>
+ <key>indipendently</key>
+ <string>independently</string>
+ <key>indispensible</key>
+ <string>indispensable</string>
+ <key>indisputible</key>
+ <string>indisputable</string>
+ <key>indisputibly</key>
+ <string>indisputably</string>
+ <key>indite</key>
+ <string>indict</string>
+ <key>individualy</key>
+ <string>individually</string>
+ <key>indpendent</key>
+ <string>independent</string>
+ <key>indpendently</key>
+ <string>independently</string>
+ <key>indulgue</key>
+ <string>indulge</string>
+ <key>indutrial</key>
+ <string>industrial</string>
+ <key>indviduals</key>
+ <string>individuals</string>
+ <key>inefficienty</key>
+ <string>inefficiently</string>
+ <key>inevatible</key>
+ <string>inevitable</string>
+ <key>inevitible</key>
+ <string>inevitable</string>
+ <key>inevititably</key>
+ <string>inevitably</string>
+ <key>infalability</key>
+ <string>infallibility</string>
+ <key>infallable</key>
+ <string>infallible</string>
+ <key>infectuous</key>
+ <string>infectious</string>
+ <key>infered</key>
+ <string>inferred</string>
+ <key>infilitrate</key>
+ <string>infiltrate</string>
+ <key>infilitrated</key>
+ <string>infiltrated</string>
+ <key>infilitration</key>
+ <string>infiltration</string>
+ <key>infinit</key>
+ <string>infinite</string>
+ <key>inflamation</key>
+ <string>inflammation</string>
+ <key>influencial</key>
+ <string>influential</string>
+ <key>influented</key>
+ <string>influenced</string>
+ <key>infomation</key>
+ <string>information</string>
+ <key>informtion</key>
+ <string>information</string>
+ <key>infrantryman</key>
+ <string>infantryman</string>
+ <key>infrigement</key>
+ <string>infringement</string>
+ <key>ingenius</key>
+ <string>ingenious</string>
+ <key>ingreediants</key>
+ <string>ingredients</string>
+ <key>inhabitans</key>
+ <string>inhabitants</string>
+ <key>inherantly</key>
+ <string>inherently</string>
+ <key>inheritence</key>
+ <string>inheritance</string>
+ <key>inital</key>
+ <string>initial</string>
+ <key>initally</key>
+ <string>initially</string>
+ <key>initation</key>
+ <string>initiation</string>
+ <key>initiaitive</key>
+ <string>initiative</string>
+ <key>inlcuding</key>
+ <string>including</string>
+ <key>inmigrant</key>
+ <string>immigrant</string>
+ <key>inmigrants</key>
+ <string>immigrants</string>
+ <key>innoculated</key>
+ <string>inoculated</string>
+ <key>inocence</key>
+ <string>innocence</string>
+ <key>inofficial</key>
+ <string>unofficial</string>
+ <key>inot</key>
+ <string>into</string>
+ <key>inpeach</key>
+ <string>impeach</string>
+ <key>inpolite</key>
+ <string>impolite</string>
+ <key>inprisonment</key>
+ <string>imprisonment</string>
+ <key>inproving</key>
+ <string>improving</string>
+ <key>insectiverous</key>
+ <string>insectivorous</string>
+ <key>insensative</key>
+ <string>insensitive</string>
+ <key>inseperable</key>
+ <string>inseparable</string>
+ <key>insistance</key>
+ <string>insistence</string>
+ <key>insitution</key>
+ <string>institution</string>
+ <key>insitutions</key>
+ <string>institutions</string>
+ <key>inspite</key>
+ <string>in spite</string>
+ <key>instade</key>
+ <string>instead</string>
+ <key>instatance</key>
+ <string>instance</string>
+ <key>institue</key>
+ <string>institute</string>
+ <key>instuction</key>
+ <string>instruction</string>
+ <key>instuments</key>
+ <string>instruments</string>
+ <key>instutionalized</key>
+ <string>institutionalized</string>
+ <key>instutions</key>
+ <string>intuitions</string>
+ <key>insurence</key>
+ <string>insurance</string>
+ <key>intelectual</key>
+ <string>intellectual</string>
+ <key>inteligence</key>
+ <string>intelligence</string>
+ <key>inteligent</key>
+ <string>intelligent</string>
+ <key>intenational</key>
+ <string>international</string>
+ <key>intented</key>
+ <string>intended</string>
+ <key>intepretation</key>
+ <string>interpretation</string>
+ <key>intepretator</key>
+ <string>interpretor</string>
+ <key>interational</key>
+ <string>international</string>
+ <key>interbread</key>
+ <string>interbreed</string>
+ <key>interchangable</key>
+ <string>interchangeable</string>
+ <key>interchangably</key>
+ <string>interchangeably</string>
+ <key>intercontinetal</key>
+ <string>intercontinental</string>
+ <key>intered</key>
+ <string>interred</string>
+ <key>interelated</key>
+ <string>interrelated</string>
+ <key>interferance</key>
+ <string>interference</string>
+ <key>interfereing</key>
+ <string>interfering</string>
+ <key>intergrated</key>
+ <string>integrated</string>
+ <key>intergration</key>
+ <string>integration</string>
+ <key>interm</key>
+ <string>interim</string>
+ <key>internation</key>
+ <string>international</string>
+ <key>interpet</key>
+ <string>interpret</string>
+ <key>interrim</key>
+ <string>interim</string>
+ <key>interrugum</key>
+ <string>interregnum</string>
+ <key>intertaining</key>
+ <string>entertaining</string>
+ <key>interupt</key>
+ <string>interrupt</string>
+ <key>intervines</key>
+ <string>intervenes</string>
+ <key>intevene</key>
+ <string>intervene</string>
+ <key>intial</key>
+ <string>initial</string>
+ <key>intially</key>
+ <string>initially</string>
+ <key>intrduced</key>
+ <string>introduced</string>
+ <key>intrest</key>
+ <string>interest</string>
+ <key>introdued</key>
+ <string>introduced</string>
+ <key>intruduced</key>
+ <string>introduced</string>
+ <key>intrument</key>
+ <string>instrument</string>
+ <key>intrumental</key>
+ <string>instrumental</string>
+ <key>intruments</key>
+ <string>instruments</string>
+ <key>intrusted</key>
+ <string>entrusted</string>
+ <key>intutive</key>
+ <string>intuitive</string>
+ <key>intutively</key>
+ <string>intuitively</string>
+ <key>inudstry</key>
+ <string>industry</string>
+ <key>inventer</key>
+ <string>inventor</string>
+ <key>invertibrates</key>
+ <string>invertebrates</string>
+ <key>investingate</key>
+ <string>investigate</string>
+ <key>involvment</key>
+ <string>involvement</string>
+ <key>irelevent</key>
+ <string>irrelevant</string>
+ <key>iresistable</key>
+ <string>irresistible</string>
+ <key>iresistably</key>
+ <string>irresistibly</string>
+ <key>iresistible</key>
+ <string>irresistible</string>
+ <key>iresistibly</key>
+ <string>irresistibly</string>
+ <key>iritable</key>
+ <string>irritable</string>
+ <key>iritated</key>
+ <string>irritated</string>
+ <key>ironicly</key>
+ <string>ironically</string>
+ <key>irregardless</key>
+ <string>regardless</string>
+ <key>irrelevent</key>
+ <string>irrelevant</string>
+ <key>irreplacable</key>
+ <string>irreplaceable</string>
+ <key>irresistable</key>
+ <string>irresistible</string>
+ <key>irresistably</key>
+ <string>irresistibly</string>
+ <key>isnt</key>
+ <string>isn&apos;t</string>
+ <key>issueing</key>
+ <string>issuing</string>
+ <key>itnroduced</key>
+ <string>introduced</string>
+ <key>iunior</key>
+ <string>junior</string>
+ <key>iwll</key>
+ <string>will</string>
+ <key>iwth</key>
+ <string>with</string>
+ <key>jaques</key>
+ <string>jacques</string>
+ <key>jeapardy</key>
+ <string>jeopardy</string>
+ <key>jewllery</key>
+ <string>jewellery</string>
+ <key>jouney</key>
+ <string>journey</string>
+ <key>journied</key>
+ <string>journeyed</string>
+ <key>journies</key>
+ <string>journeys</string>
+ <key>jstu</key>
+ <string>just</string>
+ <key>jsut</key>
+ <string>just</string>
+ <key>judical</key>
+ <string>judicial</string>
+ <key>judisuary</key>
+ <string>judiciary</string>
+ <key>juducial</key>
+ <string>judicial</string>
+ <key>juristiction</key>
+ <string>jurisdiction</string>
+ <key>juristictions</key>
+ <string>jurisdictions</string>
+ <key>kindergarden</key>
+ <string>kindergarten</string>
+ <key>klenex</key>
+ <string>kleenex</string>
+ <key>knifes</key>
+ <string>knives</string>
+ <key>knive</key>
+ <string>knife</string>
+ <key>knowlege</key>
+ <string>knowledge</string>
+ <key>knowlegeable</key>
+ <string>knowledgeable</string>
+ <key>knwo</key>
+ <string>know</string>
+ <key>knwos</key>
+ <string>knows</string>
+ <key>konw</key>
+ <string>know</string>
+ <key>konws</key>
+ <string>knows</string>
+ <key>kwno</key>
+ <string>know</string>
+ <key>labatory</key>
+ <string>laboratory</string>
+ <key>labratory</key>
+ <string>laboratory</string>
+ <key>laguage</key>
+ <string>language</string>
+ <key>laguages</key>
+ <string>languages</string>
+ <key>larg</key>
+ <string>large</string>
+ <key>largst</key>
+ <string>largest</string>
+ <key>larrry</key>
+ <string>larry</string>
+ <key>lastr</key>
+ <string>last</string>
+ <key>lattitude</key>
+ <string>latitude</string>
+ <key>launhed</key>
+ <string>launched</string>
+ <key>lavae</key>
+ <string>larvae</string>
+ <key>layed</key>
+ <string>laid</string>
+ <key>lazyness</key>
+ <string>laziness</string>
+ <key>leage</key>
+ <string>league</string>
+ <key>leanr</key>
+ <string>learn</string>
+ <key>leathal</key>
+ <string>lethal</string>
+ <key>lefted</key>
+ <string>left</string>
+ <key>legitamate</key>
+ <string>legitimate</string>
+ <key>legitmate</key>
+ <string>legitimate</string>
+ <key>leibnitz</key>
+ <string>leibniz</string>
+ <key>lenght</key>
+ <string>length</string>
+ <key>leran</key>
+ <string>learn</string>
+ <key>lerans</key>
+ <string>learns</string>
+ <key>leutenant</key>
+ <string>lieutenant</string>
+ <key>levetate</key>
+ <string>levitate</string>
+ <key>levetated</key>
+ <string>levitated</string>
+ <key>levetates</key>
+ <string>levitates</string>
+ <key>levetating</key>
+ <string>levitating</string>
+ <key>levle</key>
+ <string>level</string>
+ <key>liasion</key>
+ <string>liaison</string>
+ <key>liason</key>
+ <string>liaison</string>
+ <key>liasons</key>
+ <string>liaisons</string>
+ <key>libary</key>
+ <string>library</string>
+ <key>libell</key>
+ <string>libel</string>
+ <key>libguistic</key>
+ <string>linguistic</string>
+ <key>libguistics</key>
+ <string>linguistics</string>
+ <key>libitarianisn</key>
+ <string>libertarianism</string>
+ <key>lieing</key>
+ <string>lying</string>
+ <key>liek</key>
+ <string>like</string>
+ <key>liekd</key>
+ <string>liked</string>
+ <key>liesure</key>
+ <string>leisure</string>
+ <key>lieuenant</key>
+ <string>lieutenant</string>
+ <key>lieved</key>
+ <string>lived</string>
+ <key>liftime</key>
+ <string>lifetime</string>
+ <key>lightyear</key>
+ <string>light year</string>
+ <key>lightyears</key>
+ <string>light years</string>
+ <key>likelyhood</key>
+ <string>likelihood</string>
+ <key>linnaena</key>
+ <string>linnaean</string>
+ <key>lippizaner</key>
+ <string>lipizzaner</string>
+ <key>liquify</key>
+ <string>liquefy</string>
+ <key>liscense</key>
+ <string>license</string>
+ <key>lisence</key>
+ <string>license</string>
+ <key>lisense</key>
+ <string>license</string>
+ <key>listners</key>
+ <string>listeners</string>
+ <key>litature</key>
+ <string>literature</string>
+ <key>literaly</key>
+ <string>literally</string>
+ <key>literture</key>
+ <string>literature</string>
+ <key>littel</key>
+ <string>little</string>
+ <key>litterally</key>
+ <string>literally</string>
+ <key>liuke</key>
+ <string>like</string>
+ <key>livley</key>
+ <string>lively</string>
+ <key>lmits</key>
+ <string>limits</string>
+ <key>loev</key>
+ <string>love</string>
+ <key>lonelyness</key>
+ <string>loneliness</string>
+ <key>longitudonal</key>
+ <string>longitudinal</string>
+ <key>lonley</key>
+ <string>lonely</string>
+ <key>lonly</key>
+ <string>lonely</string>
+ <key>loosing</key>
+ <string>losing</string>
+ <key>lotharingen</key>
+ <string>lothringen</string>
+ <key>lsat</key>
+ <string>last</string>
+ <key>lukid</key>
+ <string>likud</string>
+ <key>lveo</key>
+ <string>love</string>
+ <key>lvoe</key>
+ <string>love</string>
+ <key>maching</key>
+ <string>machine</string>
+ <key>mackeral</key>
+ <string>mackerel</string>
+ <key>magasine</key>
+ <string>magazine</string>
+ <key>magincian</key>
+ <string>magician</string>
+ <key>magnificient</key>
+ <string>magnificent</string>
+ <key>magolia</key>
+ <string>magnolia</string>
+ <key>mailny</key>
+ <string>mainly</string>
+ <key>maintainance</key>
+ <string>maintenance</string>
+ <key>maintainence</key>
+ <string>maintenance</string>
+ <key>maintance</key>
+ <string>maintenance</string>
+ <key>maintenence</key>
+ <string>maintenance</string>
+ <key>maintinaing</key>
+ <string>maintaining</string>
+ <key>maintioned</key>
+ <string>mentioned</string>
+ <key>majoroty</key>
+ <string>majority</string>
+ <key>maked</key>
+ <string>marked</string>
+ <key>makse</key>
+ <string>makes</string>
+ <key>maltesian</key>
+ <string>Maltese</string>
+ <key>mamal</key>
+ <string>mammal</string>
+ <key>mamalian</key>
+ <string>mammalian</string>
+ <key>managable</key>
+ <string>manageable</string>
+ <key>managment</key>
+ <string>management</string>
+ <key>maneouvre</key>
+ <string>manoeuvre</string>
+ <key>maneouvred</key>
+ <string>manoeuvred</string>
+ <key>maneouvres</key>
+ <string>manoeuvres</string>
+ <key>maneouvring</key>
+ <string>manoeuvring</string>
+ <key>manisfestations</key>
+ <string>manifestations</string>
+ <key>manoeuverability</key>
+ <string>maneuverability</string>
+ <key>manouver</key>
+ <string>maneuver</string>
+ <key>manouverability</key>
+ <string>maneuverability</string>
+ <key>manouverable</key>
+ <string>maneuverable</string>
+ <key>manouvers</key>
+ <string>maneuvers</string>
+ <key>mantained</key>
+ <string>maintained</string>
+ <key>manuever</key>
+ <string>maneuver</string>
+ <key>manuevers</key>
+ <string>maneuvers</string>
+ <key>manufacturedd</key>
+ <string>manufactured</string>
+ <key>manufature</key>
+ <string>manufacture</string>
+ <key>manufatured</key>
+ <string>manufactured</string>
+ <key>manufaturing</key>
+ <string>manufacturing</string>
+ <key>manuver</key>
+ <string>maneuver</string>
+ <key>mariage</key>
+ <string>marriage</string>
+ <key>marjority</key>
+ <string>majority</string>
+ <key>markes</key>
+ <string>marks</string>
+ <key>marketting</key>
+ <string>marketing</string>
+ <key>marmelade</key>
+ <string>marmalade</string>
+ <key>marrage</key>
+ <string>marriage</string>
+ <key>marraige</key>
+ <string>marriage</string>
+ <key>marrtyred</key>
+ <string>martyred</string>
+ <key>marryied</key>
+ <string>married</string>
+ <key>massmedia</key>
+ <string>mass media</string>
+ <key>masterbation</key>
+ <string>masturbation</string>
+ <key>mataphysical</key>
+ <string>metaphysical</string>
+ <key>materalists</key>
+ <string>materialist</string>
+ <key>mathamatics</key>
+ <string>mathematics</string>
+ <key>mathematican</key>
+ <string>mathematician</string>
+ <key>mathematicas</key>
+ <string>mathematics</string>
+ <key>matheticians</key>
+ <string>mathematicians</string>
+ <key>mathmatically</key>
+ <string>mathematically</string>
+ <key>mathmatician</key>
+ <string>mathematician</string>
+ <key>mathmaticians</key>
+ <string>mathematicians</string>
+ <key>mccarthyst</key>
+ <string>mccarthyist</string>
+ <key>mchanics</key>
+ <string>mechanics</string>
+ <key>meaninng</key>
+ <string>meaning</string>
+ <key>mear</key>
+ <string>wear</string>
+ <key>mechandise</key>
+ <string>merchandise</string>
+ <key>medacine</key>
+ <string>medicine</string>
+ <key>medeival</key>
+ <string>medieval</string>
+ <key>medevial</key>
+ <string>medieval</string>
+ <key>mediciney</key>
+ <string>mediciny</string>
+ <key>medievel</key>
+ <string>medieval</string>
+ <key>mediterainnean</key>
+ <string>mediterranean</string>
+ <key>meerkrat</key>
+ <string>meerkat</string>
+ <key>melieux</key>
+ <string>milieux</string>
+ <key>membranaphone</key>
+ <string>membranophone</string>
+ <key>memeber</key>
+ <string>member</string>
+ <key>menally</key>
+ <string>mentally</string>
+ <key>meranda</key>
+ <string>Miranda</string>
+ <key>mercentile</key>
+ <string>mercantile</string>
+ <key>messanger</key>
+ <string>messenger</string>
+ <key>messenging</key>
+ <string>messaging</string>
+ <key>metalic</key>
+ <string>metallic</string>
+ <key>metalurgic</key>
+ <string>metallurgic</string>
+ <key>metalurgical</key>
+ <string>metallurgical</string>
+ <key>metalurgy</key>
+ <string>metallurgy</string>
+ <key>metamorphysis</key>
+ <string>metamorphosis</string>
+ <key>metaphoricial</key>
+ <string>metaphorical</string>
+ <key>meterologist</key>
+ <string>meteorologist</string>
+ <key>meterology</key>
+ <string>meteorology</string>
+ <key>methaphor</key>
+ <string>metaphor</string>
+ <key>methaphors</key>
+ <string>metaphors</string>
+ <key>micoscopy</key>
+ <string>microscopy</string>
+ <key>midwifes</key>
+ <string>midwives</string>
+ <key>mileau</key>
+ <string>milieu</string>
+ <key>milennia</key>
+ <string>millennia</string>
+ <key>milennium</key>
+ <string>millennium</string>
+ <key>mileu</key>
+ <string>milieu</string>
+ <key>miliary</key>
+ <string>military</string>
+ <key>milion</key>
+ <string>million</string>
+ <key>miliraty</key>
+ <string>military</string>
+ <key>millenia</key>
+ <string>millennia</string>
+ <key>millenial</key>
+ <string>millennial</string>
+ <key>millenialism</key>
+ <string>millennialism</string>
+ <key>millenium</key>
+ <string>millennium</string>
+ <key>millepede</key>
+ <string>millipede</string>
+ <key>millioniare</key>
+ <string>millionaire</string>
+ <key>millitary</key>
+ <string>military</string>
+ <key>millon</key>
+ <string>million</string>
+ <key>miltary</key>
+ <string>military</string>
+ <key>minature</key>
+ <string>miniature</string>
+ <key>minerial</key>
+ <string>mineral</string>
+ <key>miniscule</key>
+ <string>minuscule</string>
+ <key>ministery</key>
+ <string>ministry</string>
+ <key>minstries</key>
+ <string>ministries</string>
+ <key>minstry</key>
+ <string>ministry</string>
+ <key>minumum</key>
+ <string>minimum</string>
+ <key>mirrorred</key>
+ <string>mirrored</string>
+ <key>miscelaneous</key>
+ <string>miscellaneous</string>
+ <key>miscellanious</key>
+ <string>miscellaneous</string>
+ <key>miscellanous</key>
+ <string>miscellaneous</string>
+ <key>mischeivous</key>
+ <string>mischievous</string>
+ <key>mischevious</key>
+ <string>mischievous</string>
+ <key>mischievious</key>
+ <string>mischievous</string>
+ <key>misdameanor</key>
+ <string>misdemeanor</string>
+ <key>misdameanors</key>
+ <string>misdemeanors</string>
+ <key>misdemenor</key>
+ <string>misdemeanor</string>
+ <key>misdemenors</key>
+ <string>misdemeanors</string>
+ <key>misfourtunes</key>
+ <string>misfortunes</string>
+ <key>misile</key>
+ <string>missile</string>
+ <key>mispell</key>
+ <string>misspell</string>
+ <key>mispelled</key>
+ <string>misspelled</string>
+ <key>mispelling</key>
+ <string>misspelling</string>
+ <key>missen</key>
+ <string>mizzen</string>
+ <key>missle</key>
+ <string>missile</string>
+ <key>missonary</key>
+ <string>missionary</string>
+ <key>misterious</key>
+ <string>mysterious</string>
+ <key>mistery</key>
+ <string>mystery</string>
+ <key>misteryous</key>
+ <string>mysterious</string>
+ <key>mkae</key>
+ <string>make</string>
+ <key>mkaes</key>
+ <string>makes</string>
+ <key>mkaing</key>
+ <string>making</string>
+ <key>mkea</key>
+ <string>make</string>
+ <key>moderm</key>
+ <string>modem</string>
+ <key>modle</key>
+ <string>model</string>
+ <key>moent</key>
+ <string>moment</string>
+ <key>moeny</key>
+ <string>money</string>
+ <key>mohammedans</key>
+ <string>muslims</string>
+ <key>moil</key>
+ <string>soil</string>
+ <key>moleclues</key>
+ <string>molecules</string>
+ <key>momento</key>
+ <string>memento</string>
+ <key>monestaries</key>
+ <string>monasteries</string>
+ <key>monestary</key>
+ <string>monastery</string>
+ <key>monickers</key>
+ <string>monikers</string>
+ <key>monolite</key>
+ <string>monolithic</string>
+ <key>montains</key>
+ <string>mountains</string>
+ <key>montanous</key>
+ <string>mountainous</string>
+ <key>monts</key>
+ <string>months</string>
+ <key>montypic</key>
+ <string>monotypic</string>
+ <key>moreso</key>
+ <string>more so</string>
+ <key>morgage</key>
+ <string>mortgage</string>
+ <key>morroccan</key>
+ <string>moroccan</string>
+ <key>morrocco</key>
+ <string>morocco</string>
+ <key>morroco</key>
+ <string>morocco</string>
+ <key>mortage</key>
+ <string>mortgage</string>
+ <key>mosture</key>
+ <string>moisture</string>
+ <key>motiviated</key>
+ <string>motivated</string>
+ <key>mounth</key>
+ <string>month</string>
+ <key>movei</key>
+ <string>movie</string>
+ <key>movment</key>
+ <string>movement</string>
+ <key>mroe</key>
+ <string>more</string>
+ <key>mucuous</key>
+ <string>mucous</string>
+ <key>muder</key>
+ <string>murder</string>
+ <key>mudering</key>
+ <string>murdering</string>
+ <key>muhammadan</key>
+ <string>muslim</string>
+ <key>multicultralism</key>
+ <string>multiculturalism</string>
+ <key>multipled</key>
+ <string>multiplied</string>
+ <key>multiplers</key>
+ <string>multipliers</string>
+ <key>munbers</key>
+ <string>numbers</string>
+ <key>muncipalities</key>
+ <string>municipalities</string>
+ <key>muncipality</key>
+ <string>municipality</string>
+ <key>munnicipality</key>
+ <string>municipality</string>
+ <key>muscels</key>
+ <string>muscles</string>
+ <key>muscial</key>
+ <string>musical</string>
+ <key>muscician</key>
+ <string>musician</string>
+ <key>muscicians</key>
+ <string>musicians</string>
+ <key>mutiliated</key>
+ <string>mutilated</string>
+ <key>myraid</key>
+ <string>myriad</string>
+ <key>mysef</key>
+ <string>myself</string>
+ <key>mysogynist</key>
+ <string>misogynist</string>
+ <key>mysogyny</key>
+ <string>misogyny</string>
+ <key>mysterous</key>
+ <string>mysterious</string>
+ <key>naieve</key>
+ <string>naive</string>
+ <key>naturaly</key>
+ <string>naturally</string>
+ <key>naturely</key>
+ <string>naturally</string>
+ <key>naturual</key>
+ <string>natural</string>
+ <key>naturually</key>
+ <string>naturally</string>
+ <key>neccesarily</key>
+ <string>necessarily</string>
+ <key>neccesary</key>
+ <string>necessary</string>
+ <key>neccessarily</key>
+ <string>necessarily</string>
+ <key>neccessary</key>
+ <string>necessary</string>
+ <key>neccessities</key>
+ <string>necessities</string>
+ <key>necesarily</key>
+ <string>necessarily</string>
+ <key>necesary</key>
+ <string>necessary</string>
+ <key>necessiate</key>
+ <string>necessitate</string>
+ <key>neglible</key>
+ <string>negligible</string>
+ <key>negligable</key>
+ <string>negligible</string>
+ <key>negociate</key>
+ <string>negotiate</string>
+ <key>negociation</key>
+ <string>negotiation</string>
+ <key>negociations</key>
+ <string>negotiations</string>
+ <key>negotation</key>
+ <string>negotiation</string>
+ <key>neice</key>
+ <string>niece</string>
+ <key>neigborhood</key>
+ <string>neighborhood</string>
+ <key>neigbour</key>
+ <string>neighbour</string>
+ <key>neigbourhood</key>
+ <string>neighbourhood</string>
+ <key>neolitic</key>
+ <string>neolithic</string>
+ <key>nessasarily</key>
+ <string>necessarily</string>
+ <key>nessecary</key>
+ <string>necessary</string>
+ <key>nestin</key>
+ <string>nesting</string>
+ <key>neverthless</key>
+ <string>nevertheless</string>
+ <key>newletters</key>
+ <string>newsletters</string>
+ <key>nickle</key>
+ <string>nickel</string>
+ <key>nightfa;;</key>
+ <string>nightfall</string>
+ <key>nightime</key>
+ <string>nighttime</string>
+ <key>nineth</key>
+ <string>ninth</string>
+ <key>ninteenth</key>
+ <string>nineteenth</string>
+ <key>ninties</key>
+ <string>1990s</string>
+ <key>ninty</key>
+ <string>ninety</string>
+ <key>nkow</key>
+ <string>know</string>
+ <key>nkwo</key>
+ <string>know</string>
+ <key>nmae</key>
+ <string>name</string>
+ <key>noncombatents</key>
+ <string>noncombatants</string>
+ <key>nonsence</key>
+ <string>nonsense</string>
+ <key>nontheless</key>
+ <string>nonetheless</string>
+ <key>noone</key>
+ <string>no one</string>
+ <key>norhern</key>
+ <string>northern</string>
+ <key>northen</key>
+ <string>northern</string>
+ <key>northereastern</key>
+ <string>northeastern</string>
+ <key>notabley</key>
+ <string>notably</string>
+ <key>noteable</key>
+ <string>notable</string>
+ <key>noteably</key>
+ <string>notably</string>
+ <key>noteriety</key>
+ <string>notoriety</string>
+ <key>noth</key>
+ <string>north</string>
+ <key>nothern</key>
+ <string>northern</string>
+ <key>noticable</key>
+ <string>noticeable</string>
+ <key>noticably</key>
+ <string>noticeably</string>
+ <key>noticeing</key>
+ <string>noticing</string>
+ <key>noticible</key>
+ <string>noticeable</string>
+ <key>notwhithstanding</key>
+ <string>notwithstanding</string>
+ <key>noveau</key>
+ <string>nouveau</string>
+ <key>nowdays</key>
+ <string>nowadays</string>
+ <key>nowe</key>
+ <string>now</string>
+ <key>nto</key>
+ <string>not</string>
+ <key>nucular</key>
+ <string>nuclear</string>
+ <key>nuculear</key>
+ <string>nuclear</string>
+ <key>nuisanse</key>
+ <string>nuisance</string>
+ <key>numberous</key>
+ <string>numerous</string>
+ <key>nusance</key>
+ <string>nuisance</string>
+ <key>nutritent</key>
+ <string>nutrient</string>
+ <key>nutritents</key>
+ <string>nutrients</string>
+ <key>nuturing</key>
+ <string>nurturing</string>
+ <key>obediance</key>
+ <string>obedience</string>
+ <key>obediant</key>
+ <string>obedient</string>
+ <key>obession</key>
+ <string>obsession</string>
+ <key>obssessed</key>
+ <string>obsessed</string>
+ <key>obstacal</key>
+ <string>obstacle</string>
+ <key>obstancles</key>
+ <string>obstacles</string>
+ <key>obstruced</key>
+ <string>obstructed</string>
+ <key>ocasion</key>
+ <string>occasion</string>
+ <key>ocasional</key>
+ <string>occasional</string>
+ <key>ocasionally</key>
+ <string>occasionally</string>
+ <key>ocasionaly</key>
+ <string>occasionally</string>
+ <key>ocasioned</key>
+ <string>occasioned</string>
+ <key>ocasions</key>
+ <string>occasions</string>
+ <key>ocassion</key>
+ <string>occasion</string>
+ <key>ocassional</key>
+ <string>occasional</string>
+ <key>ocassionally</key>
+ <string>occasionally</string>
+ <key>ocassionaly</key>
+ <string>occasionally</string>
+ <key>ocassioned</key>
+ <string>occasioned</string>
+ <key>ocassions</key>
+ <string>occasions</string>
+ <key>occaison</key>
+ <string>occasion</string>
+ <key>occassion</key>
+ <string>occasion</string>
+ <key>occassional</key>
+ <string>occasional</string>
+ <key>occassionally</key>
+ <string>occasionally</string>
+ <key>occassionaly</key>
+ <string>occasionally</string>
+ <key>occassioned</key>
+ <string>occasioned</string>
+ <key>occassions</key>
+ <string>occasions</string>
+ <key>occationally</key>
+ <string>occasionally</string>
+ <key>occour</key>
+ <string>occur</string>
+ <key>occurance</key>
+ <string>occurrence</string>
+ <key>occurances</key>
+ <string>occurrences</string>
+ <key>occured</key>
+ <string>occurred</string>
+ <key>occurence</key>
+ <string>occurrence</string>
+ <key>occurences</key>
+ <string>occurrences</string>
+ <key>occuring</key>
+ <string>occurring</string>
+ <key>occurr</key>
+ <string>occur</string>
+ <key>occurrance</key>
+ <string>occurrence</string>
+ <key>occurrances</key>
+ <string>occurrences</string>
+ <key>octohedra</key>
+ <string>octahedra</string>
+ <key>octohedral</key>
+ <string>octahedral</string>
+ <key>octohedron</key>
+ <string>octahedron</string>
+ <key>ocuntries</key>
+ <string>countries</string>
+ <key>ocuntry</key>
+ <string>country</string>
+ <key>ocurr</key>
+ <string>occur</string>
+ <key>ocurrance</key>
+ <string>occurrence</string>
+ <key>ocurred</key>
+ <string>occurred</string>
+ <key>ocurrence</key>
+ <string>occurrence</string>
+ <key>offcers</key>
+ <string>officers</string>
+ <key>offcially</key>
+ <string>officially</string>
+ <key>offereings</key>
+ <string>offerings</string>
+ <key>offical</key>
+ <string>official</string>
+ <key>offically</key>
+ <string>officially</string>
+ <key>officals</key>
+ <string>officials</string>
+ <key>officaly</key>
+ <string>officially</string>
+ <key>officialy</key>
+ <string>officially</string>
+ <key>offred</key>
+ <string>offered</string>
+ <key>oftenly</key>
+ <string>often</string>
+ <key>oging</key>
+ <string>going</string>
+ <key>omision</key>
+ <string>omission</string>
+ <key>omited</key>
+ <string>omitted</string>
+ <key>omiting</key>
+ <string>omitting</string>
+ <key>omlette</key>
+ <string>omelette</string>
+ <key>ommision</key>
+ <string>omission</string>
+ <key>ommited</key>
+ <string>omitted</string>
+ <key>ommiting</key>
+ <string>omitting</string>
+ <key>ommitted</key>
+ <string>omitted</string>
+ <key>ommitting</key>
+ <string>omitting</string>
+ <key>omniverous</key>
+ <string>omnivorous</string>
+ <key>omniverously</key>
+ <string>omnivorously</string>
+ <key>omre</key>
+ <string>more</string>
+ <key>onot</key>
+ <string>note</string>
+ <key>onxy</key>
+ <string>onyx</string>
+ <key>onyl</key>
+ <string>only</string>
+ <key>openess</key>
+ <string>openness</string>
+ <key>oponent</key>
+ <string>opponent</string>
+ <key>oportunity</key>
+ <string>opportunity</string>
+ <key>opose</key>
+ <string>oppose</string>
+ <key>oposite</key>
+ <string>opposite</string>
+ <key>oposition</key>
+ <string>opposition</string>
+ <key>oppenly</key>
+ <string>openly</string>
+ <key>oppinion</key>
+ <string>opinion</string>
+ <key>opponant</key>
+ <string>opponent</string>
+ <key>oppononent</key>
+ <string>opponent</string>
+ <key>oppositition</key>
+ <string>opposition</string>
+ <key>oppossed</key>
+ <string>opposed</string>
+ <key>opprotunity</key>
+ <string>opportunity</string>
+ <key>opression</key>
+ <string>oppression</string>
+ <key>opressive</key>
+ <string>oppressive</string>
+ <key>opthalmic</key>
+ <string>ophthalmic</string>
+ <key>opthalmologist</key>
+ <string>ophthalmologist</string>
+ <key>opthalmology</key>
+ <string>ophthalmology</string>
+ <key>opthamologist</key>
+ <string>ophthalmologist</string>
+ <key>optmizations</key>
+ <string>optimizations</string>
+ <key>optomism</key>
+ <string>optimism</string>
+ <key>orded</key>
+ <string>ordered</string>
+ <key>organim</key>
+ <string>organism</string>
+ <key>organistion</key>
+ <string>organisation</string>
+ <key>organiztion</key>
+ <string>organization</string>
+ <key>orgin</key>
+ <string>origin</string>
+ <key>orginal</key>
+ <string>original</string>
+ <key>orginally</key>
+ <string>originally</string>
+ <key>orginize</key>
+ <string>organise</string>
+ <key>oridinarily</key>
+ <string>ordinarily</string>
+ <key>origanaly</key>
+ <string>originally</string>
+ <key>originall</key>
+ <string>original</string>
+ <key>originaly</key>
+ <string>originally</string>
+ <key>originially</key>
+ <string>originally</string>
+ <key>originnally</key>
+ <string>originally</string>
+ <key>origional</key>
+ <string>original</string>
+ <key>orignally</key>
+ <string>originally</string>
+ <key>orignially</key>
+ <string>originally</string>
+ <key>otehr</key>
+ <string>other</string>
+ <key>oublisher</key>
+ <string>publisher</string>
+ <key>ouevre</key>
+ <string>oeuvre</string>
+ <key>oustanding</key>
+ <string>outstanding</string>
+ <key>overshaddowed</key>
+ <string>overshadowed</string>
+ <key>overthere</key>
+ <string>over there</string>
+ <key>overwelming</key>
+ <string>overwhelming</string>
+ <key>overwheliming</key>
+ <string>overwhelming</string>
+ <key>owrk</key>
+ <string>work</string>
+ <key>owudl</key>
+ <string>would</string>
+ <key>oxigen</key>
+ <string>oxygen</string>
+ <key>oximoron</key>
+ <string>oxymoron</string>
+ <key>p0enis</key>
+ <string>penis</string>
+ <key>paide</key>
+ <string>paid</string>
+ <key>paitience</key>
+ <string>patience</string>
+ <key>palce</key>
+ <string>place</string>
+ <key>paleolitic</key>
+ <string>paleolithic</string>
+ <key>paliamentarian</key>
+ <string>parliamentarian</string>
+ <key>pallete</key>
+ <string>palette</string>
+ <key>pamflet</key>
+ <string>pamphlet</string>
+ <key>pamplet</key>
+ <string>pamphlet</string>
+ <key>pantomine</key>
+ <string>pantomime</string>
+ <key>paralel</key>
+ <string>parallel</string>
+ <key>paralell</key>
+ <string>parallel</string>
+ <key>paralelly</key>
+ <string>parallelly</string>
+ <key>paralely</key>
+ <string>parallelly</string>
+ <key>parallely</key>
+ <string>parallelly</string>
+ <key>paranthesis</key>
+ <string>parenthesis</string>
+ <key>paraphenalia</key>
+ <string>paraphernalia</string>
+ <key>parellels</key>
+ <string>parallels</string>
+ <key>parituclar</key>
+ <string>particular</string>
+ <key>parliment</key>
+ <string>parliament</string>
+ <key>parrakeets</key>
+ <string>parakeets</string>
+ <key>parralel</key>
+ <string>parallel</string>
+ <key>parrallel</key>
+ <string>parallel</string>
+ <key>parrallell</key>
+ <string>parallel</string>
+ <key>parrallelly</key>
+ <string>parallelly</string>
+ <key>parrallely</key>
+ <string>parallelly</string>
+ <key>partialy</key>
+ <string>partially</string>
+ <key>particually</key>
+ <string>particularly</string>
+ <key>particualr</key>
+ <string>particular</string>
+ <key>particuarly</key>
+ <string>particularly</string>
+ <key>particularily</key>
+ <string>particularly</string>
+ <key>particulary</key>
+ <string>particularly</string>
+ <key>pary</key>
+ <string>party</string>
+ <key>pased</key>
+ <string>passed</string>
+ <key>pasengers</key>
+ <string>passengers</string>
+ <key>passerbys</key>
+ <string>passersby</string>
+ <key>pasttime</key>
+ <string>pastime</string>
+ <key>pastural</key>
+ <string>pastoral</string>
+ <key>paticular</key>
+ <string>particular</string>
+ <key>pattented</key>
+ <string>patented</string>
+ <key>pavillion</key>
+ <string>pavilion</string>
+ <key>payed</key>
+ <string>paid</string>
+ <key>pblisher</key>
+ <string>publisher</string>
+ <key>pbulisher</key>
+ <string>publisher</string>
+ <key>peacefuland</key>
+ <string>peaceful and</string>
+ <key>peageant</key>
+ <string>pageant</string>
+ <key>peculure</key>
+ <string>peculiar</string>
+ <key>pedestrain</key>
+ <string>pedestrian</string>
+ <key>peformed</key>
+ <string>performed</string>
+ <key>peice</key>
+ <string>piece</string>
+ <key>penatly</key>
+ <string>penalty</string>
+ <key>penerator</key>
+ <string>penetrator</string>
+ <key>penisula</key>
+ <string>peninsula</string>
+ <key>penisular</key>
+ <string>peninsular</string>
+ <key>penninsula</key>
+ <string>peninsula</string>
+ <key>penninsular</key>
+ <string>peninsular</string>
+ <key>pennisula</key>
+ <string>peninsula</string>
+ <key>pensinula</key>
+ <string>peninsula</string>
+ <key>peom</key>
+ <string>poem</string>
+ <key>peoms</key>
+ <string>poems</string>
+ <key>peopel</key>
+ <string>people</string>
+ <key>peotry</key>
+ <string>poetry</string>
+ <key>perade</key>
+ <string>parade</string>
+ <key>percepted</key>
+ <string>perceived</string>
+ <key>percieve</key>
+ <string>perceive</string>
+ <key>percieved</key>
+ <string>perceived</string>
+ <key>perenially</key>
+ <string>perennially</string>
+ <key>perfomance</key>
+ <string>performance</string>
+ <key>perfomers</key>
+ <string>performers</string>
+ <key>performence</key>
+ <string>performance</string>
+ <key>performes</key>
+ <string>performed</string>
+ <key>perhasp</key>
+ <string>perhaps</string>
+ <key>perheaps</key>
+ <string>perhaps</string>
+ <key>perhpas</key>
+ <string>perhaps</string>
+ <key>peripathetic</key>
+ <string>peripatetic</string>
+ <key>peristent</key>
+ <string>persistent</string>
+ <key>perjery</key>
+ <string>perjury</string>
+ <key>perjorative</key>
+ <string>pejorative</string>
+ <key>permanant</key>
+ <string>permanent</string>
+ <key>permenant</key>
+ <string>permanent</string>
+ <key>permenantly</key>
+ <string>permanently</string>
+ <key>permissable</key>
+ <string>permissible</string>
+ <key>perogative</key>
+ <string>prerogative</string>
+ <key>peronal</key>
+ <string>personal</string>
+ <key>perosnality</key>
+ <string>personality</string>
+ <key>perphas</key>
+ <string>perhaps</string>
+ <key>perpindicular</key>
+ <string>perpendicular</string>
+ <key>perseverence</key>
+ <string>perseverance</string>
+ <key>persistance</key>
+ <string>persistence</string>
+ <key>persistant</key>
+ <string>persistent</string>
+ <key>personel</key>
+ <string>personnel</string>
+ <key>personell</key>
+ <string>personnel</string>
+ <key>personnell</key>
+ <string>personnel</string>
+ <key>persuded</key>
+ <string>persuaded</string>
+ <key>persue</key>
+ <string>pursue</string>
+ <key>persued</key>
+ <string>pursued</string>
+ <key>persuing</key>
+ <string>pursuing</string>
+ <key>persuit</key>
+ <string>pursuit</string>
+ <key>persuits</key>
+ <string>pursuits</string>
+ <key>pertubation</key>
+ <string>perturbation</string>
+ <key>pertubations</key>
+ <string>perturbations</string>
+ <key>pessiary</key>
+ <string>pessary</string>
+ <key>petetion</key>
+ <string>petition</string>
+ <key>phenomenom</key>
+ <string>phenomenon</string>
+ <key>phenomenonal</key>
+ <string>phenomenal</string>
+ <key>phenomenonly</key>
+ <string>phenomenally</string>
+ <key>phenomonenon</key>
+ <string>phenomenon</string>
+ <key>phenomonon</key>
+ <string>phenomenon</string>
+ <key>phenonmena</key>
+ <string>phenomena</string>
+ <key>philisopher</key>
+ <string>philosopher</string>
+ <key>philisophical</key>
+ <string>philosophical</string>
+ <key>philisophy</key>
+ <string>philosophy</string>
+ <key>phillosophically</key>
+ <string>philosophically</string>
+ <key>philospher</key>
+ <string>philosopher</string>
+ <key>philosphies</key>
+ <string>philosophies</string>
+ <key>philosphy</key>
+ <string>philosophy</string>
+ <key>phongraph</key>
+ <string>phonograph</string>
+ <key>phylosophical</key>
+ <string>philosophical</string>
+ <key>physicaly</key>
+ <string>physically</string>
+ <key>piblisher</key>
+ <string>publisher</string>
+ <key>pich</key>
+ <string>pitch</string>
+ <key>pilgrimmage</key>
+ <string>pilgrimage</string>
+ <key>pilgrimmages</key>
+ <string>pilgrimages</string>
+ <key>pinapple</key>
+ <string>pineapple</string>
+ <key>pinnaple</key>
+ <string>pineapple</string>
+ <key>pinoneered</key>
+ <string>pioneered</string>
+ <key>plagarism</key>
+ <string>plagiarism</string>
+ <key>planation</key>
+ <string>plantation</string>
+ <key>planed</key>
+ <string>planned</string>
+ <key>plantiff</key>
+ <string>plaintiff</string>
+ <key>plateu</key>
+ <string>plateau</string>
+ <key>plausable</key>
+ <string>plausible</string>
+ <key>playright</key>
+ <string>playwright</string>
+ <key>playwrite</key>
+ <string>playwright</string>
+ <key>playwrites</key>
+ <string>playwrights</string>
+ <key>pleasent</key>
+ <string>pleasant</string>
+ <key>plebicite</key>
+ <string>plebiscite</string>
+ <key>plesant</key>
+ <string>pleasant</string>
+ <key>poenis</key>
+ <string>penis</string>
+ <key>poeoples</key>
+ <string>peoples</string>
+ <key>poety</key>
+ <string>poetry</string>
+ <key>poisin</key>
+ <string>poison</string>
+ <key>polical</key>
+ <string>political</string>
+ <key>polinator</key>
+ <string>pollinator</string>
+ <key>polinators</key>
+ <string>pollinators</string>
+ <key>politican</key>
+ <string>politician</string>
+ <key>politicans</key>
+ <string>politicians</string>
+ <key>poltical</key>
+ <string>political</string>
+ <key>polute</key>
+ <string>pollute</string>
+ <key>poluted</key>
+ <string>polluted</string>
+ <key>polutes</key>
+ <string>pollutes</string>
+ <key>poluting</key>
+ <string>polluting</string>
+ <key>polution</key>
+ <string>pollution</string>
+ <key>polyphonyic</key>
+ <string>polyphonic</string>
+ <key>polysaccaride</key>
+ <string>polysaccharide</string>
+ <key>polysaccharid</key>
+ <string>polysaccharide</string>
+ <key>pomegranite</key>
+ <string>pomegranate</string>
+ <key>pomotion</key>
+ <string>promotion</string>
+ <key>poportional</key>
+ <string>proportional</string>
+ <key>popoulation</key>
+ <string>population</string>
+ <key>popularaty</key>
+ <string>popularity</string>
+ <key>populare</key>
+ <string>popular</string>
+ <key>populer</key>
+ <string>popular</string>
+ <key>portait</key>
+ <string>portrait</string>
+ <key>portayed</key>
+ <string>portrayed</string>
+ <key>portraing</key>
+ <string>portraying</string>
+ <key>portuguease</key>
+ <string>portuguese</string>
+ <key>portugues</key>
+ <string>Portuguese</string>
+ <key>posess</key>
+ <string>possess</string>
+ <key>posessed</key>
+ <string>possessed</string>
+ <key>posesses</key>
+ <string>possesses</string>
+ <key>posessing</key>
+ <string>possessing</string>
+ <key>posession</key>
+ <string>possession</string>
+ <key>posessions</key>
+ <string>possessions</string>
+ <key>posion</key>
+ <string>poison</string>
+ <key>positon</key>
+ <string>position</string>
+ <key>possable</key>
+ <string>possible</string>
+ <key>possably</key>
+ <string>possibly</string>
+ <key>posseses</key>
+ <string>possesses</string>
+ <key>possesing</key>
+ <string>possessing</string>
+ <key>possesion</key>
+ <string>possession</string>
+ <key>possessess</key>
+ <string>possesses</string>
+ <key>possibile</key>
+ <string>possible</string>
+ <key>possibilty</key>
+ <string>possibility</string>
+ <key>possiblility</key>
+ <string>possibility</string>
+ <key>possiblilty</key>
+ <string>possibility</string>
+ <key>possiblities</key>
+ <string>possibilities</string>
+ <key>possiblity</key>
+ <string>possibility</string>
+ <key>possition</key>
+ <string>position</string>
+ <key>posthomous</key>
+ <string>posthumous</string>
+ <key>postion</key>
+ <string>position</string>
+ <key>postive</key>
+ <string>positive</string>
+ <key>potatos</key>
+ <string>potatoes</string>
+ <key>potrait</key>
+ <string>portrait</string>
+ <key>potrayed</key>
+ <string>portrayed</string>
+ <key>poulations</key>
+ <string>populations</string>
+ <key>poverful</key>
+ <string>powerful</string>
+ <key>poweful</key>
+ <string>powerful</string>
+ <key>powerfull</key>
+ <string>powerful</string>
+ <key>ppublisher</key>
+ <string>publisher</string>
+ <key>practial</key>
+ <string>practical</string>
+ <key>practially</key>
+ <string>practically</string>
+ <key>practicaly</key>
+ <string>practically</string>
+ <key>practicioner</key>
+ <string>practitioner</string>
+ <key>practicioners</key>
+ <string>practitioners</string>
+ <key>practicly</key>
+ <string>practically</string>
+ <key>practioner</key>
+ <string>practitioner</string>
+ <key>practioners</key>
+ <string>practitioners</string>
+ <key>prairy</key>
+ <string>prairie</string>
+ <key>prarie</key>
+ <string>prairie</string>
+ <key>praries</key>
+ <string>prairies</string>
+ <key>pratice</key>
+ <string>practice</string>
+ <key>preample</key>
+ <string>preamble</string>
+ <key>precedessor</key>
+ <string>predecessor</string>
+ <key>preceed</key>
+ <string>precede</string>
+ <key>preceeded</key>
+ <string>preceded</string>
+ <key>preceeding</key>
+ <string>preceding</string>
+ <key>preceeds</key>
+ <string>precedes</string>
+ <key>precentage</key>
+ <string>percentage</string>
+ <key>precice</key>
+ <string>precise</string>
+ <key>precisly</key>
+ <string>precisely</string>
+ <key>precurser</key>
+ <string>precursor</string>
+ <key>predecesors</key>
+ <string>predecessors</string>
+ <key>predicatble</key>
+ <string>predictable</string>
+ <key>predicitons</key>
+ <string>predictions</string>
+ <key>predomiantly</key>
+ <string>predominately</string>
+ <key>prefered</key>
+ <string>preferred</string>
+ <key>prefering</key>
+ <string>preferring</string>
+ <key>preferrably</key>
+ <string>preferably</string>
+ <key>pregancies</key>
+ <string>pregnancies</string>
+ <key>preiod</key>
+ <string>period</string>
+ <key>preliferation</key>
+ <string>proliferation</string>
+ <key>premeire</key>
+ <string>premiere</string>
+ <key>premeired</key>
+ <string>premiered</string>
+ <key>premillenial</key>
+ <string>premillennial</string>
+ <key>preminence</key>
+ <string>preeminence</string>
+ <key>premission</key>
+ <string>permission</string>
+ <key>preocupation</key>
+ <string>preoccupation</string>
+ <key>prepair</key>
+ <string>prepare</string>
+ <key>prepartion</key>
+ <string>preparation</string>
+ <key>prepatory</key>
+ <string>preparatory</string>
+ <key>preperation</key>
+ <string>preparation</string>
+ <key>preperations</key>
+ <string>preparations</string>
+ <key>preriod</key>
+ <string>period</string>
+ <key>presedential</key>
+ <string>presidential</string>
+ <key>presense</key>
+ <string>presence</string>
+ <key>presidenital</key>
+ <string>presidential</string>
+ <key>presidental</key>
+ <string>presidential</string>
+ <key>presitgious</key>
+ <string>prestigious</string>
+ <key>prespective</key>
+ <string>perspective</string>
+ <key>prestigeous</key>
+ <string>prestigious</string>
+ <key>prestigous</key>
+ <string>prestigious</string>
+ <key>presumabely</key>
+ <string>presumably</string>
+ <key>presumibly</key>
+ <string>presumably</string>
+ <key>pretection</key>
+ <string>protection</string>
+ <key>prevelant</key>
+ <string>prevalent</string>
+ <key>preverse</key>
+ <string>perverse</string>
+ <key>previvous</key>
+ <string>previous</string>
+ <key>pricipal</key>
+ <string>principal</string>
+ <key>priciple</key>
+ <string>principle</string>
+ <key>priestood</key>
+ <string>priesthood</string>
+ <key>primarly</key>
+ <string>primarily</string>
+ <key>primative</key>
+ <string>primitive</string>
+ <key>primatively</key>
+ <string>primitively</string>
+ <key>primatives</key>
+ <string>primitives</string>
+ <key>primordal</key>
+ <string>primordial</string>
+ <key>priveledges</key>
+ <string>privileges</string>
+ <key>privelege</key>
+ <string>privilege</string>
+ <key>priveleged</key>
+ <string>privileged</string>
+ <key>priveleges</key>
+ <string>privileges</string>
+ <key>privelige</key>
+ <string>privilege</string>
+ <key>priveliged</key>
+ <string>privileged</string>
+ <key>priveliges</key>
+ <string>privileges</string>
+ <key>privelleges</key>
+ <string>privileges</string>
+ <key>privilage</key>
+ <string>privilege</string>
+ <key>priviledge</key>
+ <string>privilege</string>
+ <key>priviledges</key>
+ <string>privileges</string>
+ <key>privledge</key>
+ <string>privilege</string>
+ <key>privte</key>
+ <string>private</string>
+ <key>probabilaty</key>
+ <string>probability</string>
+ <key>probablistic</key>
+ <string>probabilistic</string>
+ <key>probablly</key>
+ <string>probably</string>
+ <key>probalibity</key>
+ <string>probability</string>
+ <key>probaly</key>
+ <string>probably</string>
+ <key>probelm</key>
+ <string>problem</string>
+ <key>proccess</key>
+ <string>process</string>
+ <key>proccessing</key>
+ <string>processing</string>
+ <key>procede</key>
+ <string>proceed</string>
+ <key>proceded</key>
+ <string>proceeded</string>
+ <key>procedes</key>
+ <string>proceeds</string>
+ <key>procedger</key>
+ <string>procedure</string>
+ <key>proceding</key>
+ <string>proceeding</string>
+ <key>procedings</key>
+ <string>proceedings</string>
+ <key>proceedure</key>
+ <string>procedure</string>
+ <key>proces</key>
+ <string>process</string>
+ <key>processer</key>
+ <string>processor</string>
+ <key>proclaimation</key>
+ <string>proclamation</string>
+ <key>proclamed</key>
+ <string>proclaimed</string>
+ <key>proclaming</key>
+ <string>proclaiming</string>
+ <key>proclomation</key>
+ <string>proclamation</string>
+ <key>profesion</key>
+ <string>profession</string>
+ <key>profesor</key>
+ <string>professor</string>
+ <key>professer</key>
+ <string>professor</string>
+ <key>proffesed</key>
+ <string>professed</string>
+ <key>proffesion</key>
+ <string>profession</string>
+ <key>proffesional</key>
+ <string>professional</string>
+ <key>proffesor</key>
+ <string>professor</string>
+ <key>profilic</key>
+ <string>prolific</string>
+ <key>progessed</key>
+ <string>progressed</string>
+ <key>programable</key>
+ <string>programmable</string>
+ <key>progrom</key>
+ <string>program</string>
+ <key>progroms</key>
+ <string>programs</string>
+ <key>prohabition</key>
+ <string>prohibition</string>
+ <key>prologomena</key>
+ <string>prolegomena</string>
+ <key>prominance</key>
+ <string>prominence</string>
+ <key>prominant</key>
+ <string>prominent</string>
+ <key>prominantly</key>
+ <string>prominently</string>
+ <key>prominately</key>
+ <string>prominently</string>
+ <key>promiscous</key>
+ <string>promiscuous</string>
+ <key>promotted</key>
+ <string>promoted</string>
+ <key>pronomial</key>
+ <string>pronominal</string>
+ <key>pronouced</key>
+ <string>pronounced</string>
+ <key>pronounched</key>
+ <string>pronounced</string>
+ <key>pronounciation</key>
+ <string>pronunciation</string>
+ <key>proove</key>
+ <string>prove</string>
+ <key>prooved</key>
+ <string>proved</string>
+ <key>prophacy</key>
+ <string>prophecy</string>
+ <key>propietary</key>
+ <string>proprietary</string>
+ <key>propmted</key>
+ <string>prompted</string>
+ <key>propoganda</key>
+ <string>propaganda</string>
+ <key>propogate</key>
+ <string>propagate</string>
+ <key>propogates</key>
+ <string>propagates</string>
+ <key>propogation</key>
+ <string>propagation</string>
+ <key>propostion</key>
+ <string>proposition</string>
+ <key>propotions</key>
+ <string>proportions</string>
+ <key>propper</key>
+ <string>proper</string>
+ <key>propperly</key>
+ <string>properly</string>
+ <key>proprietory</key>
+ <string>proprietary</string>
+ <key>proseletyzing</key>
+ <string>proselytizing</string>
+ <key>protaganist</key>
+ <string>protagonist</string>
+ <key>protaganists</key>
+ <string>protagonists</string>
+ <key>protocal</key>
+ <string>protocol</string>
+ <key>protoganist</key>
+ <string>protagonist</string>
+ <key>protrayed</key>
+ <string>portrayed</string>
+ <key>protruberance</key>
+ <string>protuberance</string>
+ <key>protruberances</key>
+ <string>protuberances</string>
+ <key>prouncements</key>
+ <string>pronouncements</string>
+ <key>provacative</key>
+ <string>provocative</string>
+ <key>provded</key>
+ <string>provided</string>
+ <key>provicial</key>
+ <string>provincial</string>
+ <key>provinicial</key>
+ <string>provincial</string>
+ <key>provisiosn</key>
+ <string>provision</string>
+ <key>provisonal</key>
+ <string>provisional</string>
+ <key>proximty</key>
+ <string>proximity</string>
+ <key>pseudononymous</key>
+ <string>pseudonymous</string>
+ <key>pseudonyn</key>
+ <string>pseudonym</string>
+ <key>psuedo</key>
+ <string>pseudo</string>
+ <key>psycology</key>
+ <string>psychology</string>
+ <key>psyhic</key>
+ <string>psychic</string>
+ <key>pubilsher</key>
+ <string>publisher</string>
+ <key>pubisher</key>
+ <string>publisher</string>
+ <key>publiaher</key>
+ <string>publisher</string>
+ <key>publically</key>
+ <string>publicly</string>
+ <key>publicaly</key>
+ <string>publicly</string>
+ <key>publicher</key>
+ <string>publisher</string>
+ <key>publihser</key>
+ <string>publisher</string>
+ <key>publisehr</key>
+ <string>publisher</string>
+ <key>publiser</key>
+ <string>publisher</string>
+ <key>publisger</key>
+ <string>publisher</string>
+ <key>publisheed</key>
+ <string>published</string>
+ <key>publisherr</key>
+ <string>publisher</string>
+ <key>publishher</key>
+ <string>publisher</string>
+ <key>publishor</key>
+ <string>publisher</string>
+ <key>publishre</key>
+ <string>publisher</string>
+ <key>publissher</key>
+ <string>publisher</string>
+ <key>publlisher</key>
+ <string>publisher</string>
+ <key>publsiher</key>
+ <string>publisher</string>
+ <key>publusher</key>
+ <string>publisher</string>
+ <key>puchasing</key>
+ <string>purchasing</string>
+ <key>pulisher</key>
+ <string>publisher</string>
+ <key>pumkin</key>
+ <string>pumpkin</string>
+ <key>puplisher</key>
+ <string>publisher</string>
+ <key>puritannical</key>
+ <string>puritanical</string>
+ <key>purposedly</key>
+ <string>purposely</string>
+ <key>purpotedly</key>
+ <string>purportedly</string>
+ <key>pursuade</key>
+ <string>persuade</string>
+ <key>pursuaded</key>
+ <string>persuaded</string>
+ <key>pursuades</key>
+ <string>persuades</string>
+ <key>pususading</key>
+ <string>persuading</string>
+ <key>puting</key>
+ <string>putting</string>
+ <key>pwoer</key>
+ <string>power</string>
+ <key>pyscic</key>
+ <string>psychic</string>
+ <key>qtuie</key>
+ <string>quiet</string>
+ <key>quantaty</key>
+ <string>quantity</string>
+ <key>quantitiy</key>
+ <string>quantity</string>
+ <key>quarantaine</key>
+ <string>quarantine</string>
+ <key>questonable</key>
+ <string>questionable</string>
+ <key>quicklyu</key>
+ <string>quickly</string>
+ <key>quinessential</key>
+ <string>quintessential</string>
+ <key>quitted</key>
+ <string>quit</string>
+ <key>quizes</key>
+ <string>quizzes</string>
+ <key>qutie</key>
+ <string>quiet</string>
+ <key>rabinnical</key>
+ <string>rabbinical</string>
+ <key>racaus</key>
+ <string>raucous</string>
+ <key>radiactive</key>
+ <string>radioactive</string>
+ <key>radify</key>
+ <string>ratify</string>
+ <key>raelly</key>
+ <string>really</string>
+ <key>rarified</key>
+ <string>rarefied</string>
+ <key>reaccurring</key>
+ <string>recurring</string>
+ <key>reacing</key>
+ <string>reaching</string>
+ <key>reacll</key>
+ <string>recall</string>
+ <key>readmition</key>
+ <string>readmission</string>
+ <key>realitvely</key>
+ <string>relatively</string>
+ <key>realsitic</key>
+ <string>realistic</string>
+ <key>realtions</key>
+ <string>relations</string>
+ <key>realy</key>
+ <string>really</string>
+ <key>realyl</key>
+ <string>really</string>
+ <key>reasearch</key>
+ <string>research</string>
+ <key>rebiulding</key>
+ <string>rebuilding</string>
+ <key>rebllions</key>
+ <string>rebellions</string>
+ <key>rebounce</key>
+ <string>rebound</string>
+ <key>reccomend</key>
+ <string>recommend</string>
+ <key>reccomendations</key>
+ <string>recommendations</string>
+ <key>reccomended</key>
+ <string>recommended</string>
+ <key>reccomending</key>
+ <string>recommending</string>
+ <key>reccommend</key>
+ <string>recommend</string>
+ <key>reccommended</key>
+ <string>recommended</string>
+ <key>reccommending</key>
+ <string>recommending</string>
+ <key>reccuring</key>
+ <string>recurring</string>
+ <key>receeded</key>
+ <string>receded</string>
+ <key>receeding</key>
+ <string>receding</string>
+ <key>receivedfrom</key>
+ <string>received from</string>
+ <key>recepient</key>
+ <string>recipient</string>
+ <key>recepients</key>
+ <string>recipients</string>
+ <key>receving</key>
+ <string>receiving</string>
+ <key>rechargable</key>
+ <string>rechargeable</string>
+ <key>reched</key>
+ <string>reached</string>
+ <key>recide</key>
+ <string>reside</string>
+ <key>recided</key>
+ <string>resided</string>
+ <key>recident</key>
+ <string>resident</string>
+ <key>recidents</key>
+ <string>residents</string>
+ <key>reciding</key>
+ <string>residing</string>
+ <key>reciepents</key>
+ <string>recipients</string>
+ <key>reciept</key>
+ <string>receipt</string>
+ <key>recieve</key>
+ <string>receive</string>
+ <key>recieved</key>
+ <string>received</string>
+ <key>reciever</key>
+ <string>receiver</string>
+ <key>recievers</key>
+ <string>receivers</string>
+ <key>recieves</key>
+ <string>receives</string>
+ <key>recieving</key>
+ <string>receiving</string>
+ <key>recipiant</key>
+ <string>recipient</string>
+ <key>recipiants</key>
+ <string>recipients</string>
+ <key>recived</key>
+ <string>received</string>
+ <key>recivership</key>
+ <string>receivership</string>
+ <key>recogise</key>
+ <string>recognise</string>
+ <key>recogize</key>
+ <string>recognize</string>
+ <key>recomend</key>
+ <string>recommend</string>
+ <key>recomended</key>
+ <string>recommended</string>
+ <key>recomending</key>
+ <string>recommending</string>
+ <key>recomends</key>
+ <string>recommends</string>
+ <key>recommedations</key>
+ <string>recommendations</string>
+ <key>reconaissance</key>
+ <string>reconnaissance</string>
+ <key>reconcilation</key>
+ <string>reconciliation</string>
+ <key>reconized</key>
+ <string>recognized</string>
+ <key>reconnaisance</key>
+ <string>reconnaissance</string>
+ <key>reconnaissence</key>
+ <string>reconnaissance</string>
+ <key>recontructed</key>
+ <string>reconstructed</string>
+ <key>recordproducer</key>
+ <string>record producer</string>
+ <key>recquired</key>
+ <string>required</string>
+ <key>recrational</key>
+ <string>recreational</string>
+ <key>recrod</key>
+ <string>record</string>
+ <key>recuiting</key>
+ <string>recruiting</string>
+ <key>recuring</key>
+ <string>recurring</string>
+ <key>recurrance</key>
+ <string>recurrence</string>
+ <key>rediculous</key>
+ <string>ridiculous</string>
+ <key>reedeming</key>
+ <string>redeeming</string>
+ <key>reenforced</key>
+ <string>reinforced</string>
+ <key>refect</key>
+ <string>reflect</string>
+ <key>refedendum</key>
+ <string>referendum</string>
+ <key>referal</key>
+ <string>referral</string>
+ <key>referece</key>
+ <string>reference</string>
+ <key>refereces</key>
+ <string>references</string>
+ <key>refered</key>
+ <string>referred</string>
+ <key>referemce</key>
+ <string>reference</string>
+ <key>referemces</key>
+ <string>references</string>
+ <key>referencs</key>
+ <string>references</string>
+ <key>referenece</key>
+ <string>reference</string>
+ <key>refereneced</key>
+ <string>referenced</string>
+ <key>refereneces</key>
+ <string>references</string>
+ <key>referiang</key>
+ <string>referring</string>
+ <key>refering</key>
+ <string>referring</string>
+ <key>refernce</key>
+ <string>references</string>
+ <key>refernces</key>
+ <string>references</string>
+ <key>referrence</key>
+ <string>reference</string>
+ <key>referrences</key>
+ <string>references</string>
+ <key>referrs</key>
+ <string>refers</string>
+ <key>reffered</key>
+ <string>referred</string>
+ <key>refference</key>
+ <string>reference</string>
+ <key>reffering</key>
+ <string>referring</string>
+ <key>refrence</key>
+ <string>reference</string>
+ <key>refrences</key>
+ <string>references</string>
+ <key>refrers</key>
+ <string>refers</string>
+ <key>refridgeration</key>
+ <string>refrigeration</string>
+ <key>refridgerator</key>
+ <string>refrigerator</string>
+ <key>refromist</key>
+ <string>reformist</string>
+ <key>refusla</key>
+ <string>refusal</string>
+ <key>regardes</key>
+ <string>regards</string>
+ <key>regluar</key>
+ <string>regular</string>
+ <key>reguarly</key>
+ <string>regularly</string>
+ <key>regulaion</key>
+ <string>regulation</string>
+ <key>regulaotrs</key>
+ <string>regulators</string>
+ <key>regularily</key>
+ <string>regularly</string>
+ <key>rehersal</key>
+ <string>rehearsal</string>
+ <key>reicarnation</key>
+ <string>reincarnation</string>
+ <key>reigining</key>
+ <string>reigning</string>
+ <key>reknown</key>
+ <string>renown</string>
+ <key>reknowned</key>
+ <string>renowned</string>
+ <key>rela</key>
+ <string>real</string>
+ <key>relaly</key>
+ <string>really</string>
+ <key>relatiopnship</key>
+ <string>relationship</string>
+ <key>relativly</key>
+ <string>relatively</string>
+ <key>relected</key>
+ <string>reelected</string>
+ <key>releive</key>
+ <string>relieve</string>
+ <key>releived</key>
+ <string>relieved</string>
+ <key>releiver</key>
+ <string>reliever</string>
+ <key>releses</key>
+ <string>releases</string>
+ <key>relevence</key>
+ <string>relevance</string>
+ <key>relevent</key>
+ <string>relevant</string>
+ <key>reliablity</key>
+ <string>reliability</string>
+ <key>relient</key>
+ <string>reliant</string>
+ <key>religeous</key>
+ <string>religious</string>
+ <key>religous</key>
+ <string>religious</string>
+ <key>religously</key>
+ <string>religiously</string>
+ <key>relinqushment</key>
+ <string>relinquishment</string>
+ <key>relitavely</key>
+ <string>relatively</string>
+ <key>relized</key>
+ <string>realized</string>
+ <key>relpacement</key>
+ <string>replacement</string>
+ <key>remaing</key>
+ <string>remaining</string>
+ <key>remeber</key>
+ <string>remember</string>
+ <key>rememberable</key>
+ <string>memorable</string>
+ <key>rememberance</key>
+ <string>remembrance</string>
+ <key>remembrence</key>
+ <string>remembrance</string>
+ <key>remenant</key>
+ <string>remnant</string>
+ <key>remenicent</key>
+ <string>reminiscent</string>
+ <key>reminent</key>
+ <string>remnant</string>
+ <key>reminescent</key>
+ <string>reminiscent</string>
+ <key>reminscent</key>
+ <string>reminiscent</string>
+ <key>reminsicent</key>
+ <string>reminiscent</string>
+ <key>rendevous</key>
+ <string>rendezvous</string>
+ <key>rendezous</key>
+ <string>rendezvous</string>
+ <key>renedered</key>
+ <string>rende</string>
+ <key>renewl</key>
+ <string>renewal</string>
+ <key>rennovate</key>
+ <string>renovate</string>
+ <key>rennovated</key>
+ <string>renovated</string>
+ <key>rennovating</key>
+ <string>renovating</string>
+ <key>rennovation</key>
+ <string>renovation</string>
+ <key>rentors</key>
+ <string>renters</string>
+ <key>reoccurrence</key>
+ <string>recurrence</string>
+ <key>reorganision</key>
+ <string>reorganisation</string>
+ <key>repatition</key>
+ <string>repetition</string>
+ <key>repectively</key>
+ <string>respectively</string>
+ <key>repeition</key>
+ <string>repetition</string>
+ <key>repentence</key>
+ <string>repentance</string>
+ <key>repentent</key>
+ <string>repentant</string>
+ <key>repeteadly</key>
+ <string>repeatedly</string>
+ <key>repetion</key>
+ <string>repetition</string>
+ <key>repid</key>
+ <string>rapid</string>
+ <key>reponse</key>
+ <string>response</string>
+ <key>reponsible</key>
+ <string>responsible</string>
+ <key>reportadly</key>
+ <string>reportedly</string>
+ <key>represantative</key>
+ <string>representative</string>
+ <key>representive</key>
+ <string>representative</string>
+ <key>representives</key>
+ <string>representatives</string>
+ <key>reproducable</key>
+ <string>reproducible</string>
+ <key>reprtoire</key>
+ <string>repertoire</string>
+ <key>repsectively</key>
+ <string>respectively</string>
+ <key>reptition</key>
+ <string>repetition</string>
+ <key>requirment</key>
+ <string>requirement</string>
+ <key>requred</key>
+ <string>required</string>
+ <key>resaurant</key>
+ <string>restaurant</string>
+ <key>resembelance</key>
+ <string>resemblance</string>
+ <key>resembes</key>
+ <string>resembles</string>
+ <key>resemblence</key>
+ <string>resemblance</string>
+ <key>resevoir</key>
+ <string>reservoir</string>
+ <key>residental</key>
+ <string>residential</string>
+ <key>resignement</key>
+ <string>resignment</string>
+ <key>resistable</key>
+ <string>resistible</string>
+ <key>resistence</key>
+ <string>resistance</string>
+ <key>resistent</key>
+ <string>resistant</string>
+ <key>respectivly</key>
+ <string>respectively</string>
+ <key>responce</key>
+ <string>response</string>
+ <key>responibilities</key>
+ <string>responsibilities</string>
+ <key>responisble</key>
+ <string>responsible</string>
+ <key>responnsibilty</key>
+ <string>responsibility</string>
+ <key>responsability</key>
+ <string>responsibility</string>
+ <key>responsibile</key>
+ <string>responsible</string>
+ <key>responsibilites</key>
+ <string>responsibilities</string>
+ <key>responsiblities</key>
+ <string>responsibilities</string>
+ <key>responsiblity</key>
+ <string>responsibility</string>
+ <key>ressemblance</key>
+ <string>resemblance</string>
+ <key>ressemble</key>
+ <string>resemble</string>
+ <key>ressembled</key>
+ <string>resembled</string>
+ <key>ressemblence</key>
+ <string>resemblance</string>
+ <key>ressembling</key>
+ <string>resembling</string>
+ <key>resssurecting</key>
+ <string>resurrecting</string>
+ <key>ressurect</key>
+ <string>resurrect</string>
+ <key>ressurected</key>
+ <string>resurrected</string>
+ <key>ressurection</key>
+ <string>resurrection</string>
+ <key>ressurrection</key>
+ <string>resurrection</string>
+ <key>restarant</key>
+ <string>restaurant</string>
+ <key>restarants</key>
+ <string>restaurants</string>
+ <key>restaraunt</key>
+ <string>restaurant</string>
+ <key>restaraunteur</key>
+ <string>restaurateur</string>
+ <key>restaraunteurs</key>
+ <string>restaurateurs</string>
+ <key>restaraunts</key>
+ <string>restaurants</string>
+ <key>restauranteurs</key>
+ <string>restaurateurs</string>
+ <key>restauration</key>
+ <string>restoration</string>
+ <key>restauraunt</key>
+ <string>restaurant</string>
+ <key>resteraunt</key>
+ <string>restaurant</string>
+ <key>resteraunts</key>
+ <string>restaurants</string>
+ <key>resticted</key>
+ <string>restricted</string>
+ <key>restraunt</key>
+ <string>restraint</string>
+ <key>resturant</key>
+ <string>restaurant</string>
+ <key>resturants</key>
+ <string>restaurants</string>
+ <key>resturaunt</key>
+ <string>restaurant</string>
+ <key>resturaunts</key>
+ <string>restaurants</string>
+ <key>resurecting</key>
+ <string>resurrecting</string>
+ <key>retalitated</key>
+ <string>retaliated</string>
+ <key>retalitation</key>
+ <string>retaliation</string>
+ <key>retreive</key>
+ <string>retrieve</string>
+ <key>returnd</key>
+ <string>returned</string>
+ <key>revaluated</key>
+ <string>reevaluated</string>
+ <key>reveiw</key>
+ <string>review</string>
+ <key>reveral</key>
+ <string>reversal</string>
+ <key>reversable</key>
+ <string>reversible</string>
+ <key>revolutionar</key>
+ <string>revolutionary</string>
+ <key>rewitten</key>
+ <string>rewritten</string>
+ <key>rewriet</key>
+ <string>rewrite</string>
+ <key>rference</key>
+ <string>reference</string>
+ <key>rferences</key>
+ <string>references</string>
+ <key>rhymme</key>
+ <string>rhyme</string>
+ <key>rhythem</key>
+ <string>rhythm</string>
+ <key>rhythim</key>
+ <string>rhythm</string>
+ <key>rhytmic</key>
+ <string>rhythmic</string>
+ <key>rigourous</key>
+ <string>rigorous</string>
+ <key>rininging</key>
+ <string>ringing</string>
+ <key>rised</key>
+ <string>rose</string>
+ <key>rococco</key>
+ <string>rococo</string>
+ <key>rocord</key>
+ <string>record</string>
+ <key>roomate</key>
+ <string>roommate</string>
+ <key>rougly</key>
+ <string>roughly</string>
+ <key>rucuperate</key>
+ <string>recuperate</string>
+ <key>rudimentatry</key>
+ <string>rudimentary</string>
+ <key>rulle</key>
+ <string>rule</string>
+ <key>runing</key>
+ <string>running</string>
+ <key>runnung</key>
+ <string>running</string>
+ <key>russina</key>
+ <string>Russian</string>
+ <key>rwite</key>
+ <string>write</string>
+ <key>rythem</key>
+ <string>rhythm</string>
+ <key>rythim</key>
+ <string>rhythm</string>
+ <key>rythm</key>
+ <string>rhythm</string>
+ <key>rythmic</key>
+ <string>rhythmic</string>
+ <key>rythyms</key>
+ <string>rhythms</string>
+ <key>sacrafice</key>
+ <string>sacrifice</string>
+ <key>sacreligious</key>
+ <string>sacrilegious</string>
+ <key>sacrifical</key>
+ <string>sacrificial</string>
+ <key>saftey</key>
+ <string>safety</string>
+ <key>safty</key>
+ <string>safety</string>
+ <key>salery</key>
+ <string>salary</string>
+ <key>sanctionning</key>
+ <string>sanctioning</string>
+ <key>sandwhich</key>
+ <string>sandwich</string>
+ <key>santioned</key>
+ <string>sanctioned</string>
+ <key>sargant</key>
+ <string>sergeant</string>
+ <key>sargeant</key>
+ <string>sergeant</string>
+ <key>satelite</key>
+ <string>satellite</string>
+ <key>satelites</key>
+ <string>satellites</string>
+ <key>satisfactority</key>
+ <string>satisfactorily</string>
+ <key>satric</key>
+ <string>satiric</string>
+ <key>satrical</key>
+ <string>satirical</string>
+ <key>satrically</key>
+ <string>satirically</string>
+ <key>sattelite</key>
+ <string>satellite</string>
+ <key>sattelites</key>
+ <string>satellites</string>
+ <key>saught</key>
+ <string>sought</string>
+ <key>saveing</key>
+ <string>saving</string>
+ <key>saxaphone</key>
+ <string>saxophone</string>
+ <key>scaleable</key>
+ <string>scalable</string>
+ <key>scandanavia</key>
+ <string>Scandinavia</string>
+ <key>scaricity</key>
+ <string>scarcity</string>
+ <key>scavanged</key>
+ <string>scavenged</string>
+ <key>schedual</key>
+ <string>schedule</string>
+ <key>scholarhip</key>
+ <string>scholarship</string>
+ <key>scholarstic</key>
+ <string>scholastic</string>
+ <key>scientfic</key>
+ <string>scientific</string>
+ <key>scientifc</key>
+ <string>scientific</string>
+ <key>scientis</key>
+ <string>scientist</string>
+ <key>scince</key>
+ <string>science</string>
+ <key>scinece</key>
+ <string>science</string>
+ <key>scirpt</key>
+ <string>script</string>
+ <key>scoll</key>
+ <string>scroll</string>
+ <key>screenwrighter</key>
+ <string>screenwriter</string>
+ <key>scrutinity</key>
+ <string>scrutiny</string>
+ <key>scuptures</key>
+ <string>sculptures</string>
+ <key>seach</key>
+ <string>search</string>
+ <key>seached</key>
+ <string>searched</string>
+ <key>seaches</key>
+ <string>searches</string>
+ <key>secratary</key>
+ <string>secretary</string>
+ <key>secretery</key>
+ <string>secretary</string>
+ <key>sedereal</key>
+ <string>sidereal</string>
+ <key>seeked</key>
+ <string>sought</string>
+ <key>segementation</key>
+ <string>segmentation</string>
+ <key>seguoys</key>
+ <string>segues</string>
+ <key>seige</key>
+ <string>siege</string>
+ <key>seing</key>
+ <string>seeing</string>
+ <key>seinor</key>
+ <string>senior</string>
+ <key>seldomly</key>
+ <string>seldom</string>
+ <key>senarios</key>
+ <string>scenarios</string>
+ <key>senstive</key>
+ <string>sensitive</string>
+ <key>sensure</key>
+ <string>censure</string>
+ <key>seperate</key>
+ <string>separate</string>
+ <key>seperated</key>
+ <string>separated</string>
+ <key>seperately</key>
+ <string>separately</string>
+ <key>seperates</key>
+ <string>separates</string>
+ <key>seperating</key>
+ <string>separating</string>
+ <key>seperation</key>
+ <string>separation</string>
+ <key>seperatism</key>
+ <string>separatism</string>
+ <key>seperatist</key>
+ <string>separatist</string>
+ <key>sepina</key>
+ <string>subpoena</string>
+ <key>sergent</key>
+ <string>sergeant</string>
+ <key>settelement</key>
+ <string>settlement</string>
+ <key>settlment</key>
+ <string>settlement</string>
+ <key>severeal</key>
+ <string>several</string>
+ <key>severley</key>
+ <string>severely</string>
+ <key>severly</key>
+ <string>severely</string>
+ <key>sevice</key>
+ <string>service</string>
+ <key>shadasloo</key>
+ <string>shadaloo</string>
+ <key>shaddow</key>
+ <string>shadow</string>
+ <key>shadoloo</key>
+ <string>shadaloo</string>
+ <key>shamen</key>
+ <string>shaman</string>
+ <key>sheat</key>
+ <string>sheath</string>
+ <key>sheild</key>
+ <string>shield</string>
+ <key>sherif</key>
+ <string>sheriff</string>
+ <key>shineing</key>
+ <string>shining</string>
+ <key>shiped</key>
+ <string>shipped</string>
+ <key>shiping</key>
+ <string>shipping</string>
+ <key>shopkeeepers</key>
+ <string>shopkeepers</string>
+ <key>shorly</key>
+ <string>shortly</string>
+ <key>shortwhile</key>
+ <string>short while</string>
+ <key>shoudl</key>
+ <string>should</string>
+ <key>shoudln</key>
+ <string>shouldn&apos;t</string>
+ <key>shouldnt</key>
+ <string>shouldn&apos;t</string>
+ <key>shreak</key>
+ <string>shriek</string>
+ <key>shrinked</key>
+ <string>shrunk</string>
+ <key>sicne</key>
+ <string>since</string>
+ <key>sideral</key>
+ <string>sidereal</string>
+ <key>siezure</key>
+ <string>seizure</string>
+ <key>siezures</key>
+ <string>seizures</string>
+ <key>siginificant</key>
+ <string>significant</string>
+ <key>signficant</key>
+ <string>significant</string>
+ <key>signficiant</key>
+ <string>significant</string>
+ <key>signfies</key>
+ <string>signifies</string>
+ <key>signifantly</key>
+ <string>significantly</string>
+ <key>significently</key>
+ <string>significantly</string>
+ <key>signifigant</key>
+ <string>significant</string>
+ <key>signifigantly</key>
+ <string>significantly</string>
+ <key>signitories</key>
+ <string>signatories</string>
+ <key>signitory</key>
+ <string>signatory</string>
+ <key>similarily</key>
+ <string>similarly</string>
+ <key>similiar</key>
+ <string>similar</string>
+ <key>similiarity</key>
+ <string>similarity</string>
+ <key>similiarly</key>
+ <string>similarly</string>
+ <key>simmilar</key>
+ <string>similar</string>
+ <key>simpley</key>
+ <string>simply</string>
+ <key>simplier</key>
+ <string>simpler</string>
+ <key>simultanous</key>
+ <string>simultaneous</string>
+ <key>simultanously</key>
+ <string>simultaneously</string>
+ <key>sincerley</key>
+ <string>sincerely</string>
+ <key>singsog</key>
+ <string>singsong</string>
+ <key>sinse</key>
+ <string>since</string>
+ <key>skateing</key>
+ <string>skating</string>
+ <key>slaugterhouses</key>
+ <string>slaughterhouses</string>
+ <key>slighly</key>
+ <string>slightly</string>
+ <key>slowy</key>
+ <string>slowly</string>
+ <key>smae</key>
+ <string>same</string>
+ <key>smealting</key>
+ <string>smelting</string>
+ <key>smoe</key>
+ <string>some</string>
+ <key>sneeks</key>
+ <string>sneaks</string>
+ <key>snese</key>
+ <string>sneeze</string>
+ <key>socalism</key>
+ <string>socialism</string>
+ <key>socities</key>
+ <string>societies</string>
+ <key>soem</key>
+ <string>some</string>
+ <key>sofware</key>
+ <string>software</string>
+ <key>sohw</key>
+ <string>show</string>
+ <key>soilders</key>
+ <string>soldiers</string>
+ <key>solatary</key>
+ <string>solitary</string>
+ <key>soley</key>
+ <string>solely</string>
+ <key>soliders</key>
+ <string>soldiers</string>
+ <key>soliliquy</key>
+ <string>soliloquy</string>
+ <key>soluable</key>
+ <string>soluble</string>
+ <key>somene</key>
+ <string>someone</string>
+ <key>somtimes</key>
+ <string>sometimes</string>
+ <key>somwhere</key>
+ <string>somewhere</string>
+ <key>sophicated</key>
+ <string>sophisticated</string>
+ <key>sophmore</key>
+ <string>sophomore</string>
+ <key>sorceror</key>
+ <string>sorcerer</string>
+ <key>sorrounding</key>
+ <string>surrounding</string>
+ <key>sotry</key>
+ <string>story</string>
+ <key>sotyr</key>
+ <string>story</string>
+ <key>soudn</key>
+ <string>sound</string>
+ <key>soudns</key>
+ <string>sounds</string>
+ <key>sould</key>
+ <string>could</string>
+ <key>sountrack</key>
+ <string>soundtrack</string>
+ <key>sourth</key>
+ <string>south</string>
+ <key>sourthern</key>
+ <string>southern</string>
+ <key>souvenier</key>
+ <string>souvenir</string>
+ <key>souveniers</key>
+ <string>souvenirs</string>
+ <key>soveits</key>
+ <string>soviets</string>
+ <key>sovereignity</key>
+ <string>sovereignty</string>
+ <key>soverign</key>
+ <string>sovereign</string>
+ <key>soverignity</key>
+ <string>sovereignty</string>
+ <key>soverignty</key>
+ <string>sovereignty</string>
+ <key>spainish</key>
+ <string>Spanish</string>
+ <key>speach</key>
+ <string>speech</string>
+ <key>specfic</key>
+ <string>specific</string>
+ <key>speciallized</key>
+ <string>specialized</string>
+ <key>specifiying</key>
+ <string>specifying</string>
+ <key>speciman</key>
+ <string>specimen</string>
+ <key>spectauclar</key>
+ <string>spectacular</string>
+ <key>spectaulars</key>
+ <string>spectaculars</string>
+ <key>spectum</key>
+ <string>spectrum</string>
+ <key>speices</key>
+ <string>species</string>
+ <key>spendour</key>
+ <string>splendour</string>
+ <key>spermatozoan</key>
+ <string>spermatozoon</string>
+ <key>spoace</key>
+ <string>space</string>
+ <key>sponser</key>
+ <string>sponsor</string>
+ <key>sponsered</key>
+ <string>sponsored</string>
+ <key>spontanous</key>
+ <string>spontaneous</string>
+ <key>sponzored</key>
+ <string>sponsored</string>
+ <key>spoonfulls</key>
+ <string>spoonfuls</string>
+ <key>sppeches</key>
+ <string>speeches</string>
+ <key>spreaded</key>
+ <string>spread</string>
+ <key>sprech</key>
+ <string>speech</string>
+ <key>spred</key>
+ <string>spread</string>
+ <key>spriritual</key>
+ <string>spiritual</string>
+ <key>spritual</key>
+ <string>spiritual</string>
+ <key>sqaure</key>
+ <string>square</string>
+ <key>stablility</key>
+ <string>stability</string>
+ <key>stainlees</key>
+ <string>stainless</string>
+ <key>staion</key>
+ <string>station</string>
+ <key>standars</key>
+ <string>standards</string>
+ <key>stange</key>
+ <string>strange</string>
+ <key>startegic</key>
+ <string>strategic</string>
+ <key>startegies</key>
+ <string>strategies</string>
+ <key>startegy</key>
+ <string>strategy</string>
+ <key>stateman</key>
+ <string>statesman</string>
+ <key>statememts</key>
+ <string>statements</string>
+ <key>statment</key>
+ <string>statement</string>
+ <key>steriods</key>
+ <string>steroids</string>
+ <key>sterotypes</key>
+ <string>stereotypes</string>
+ <key>stilus</key>
+ <string>stylus</string>
+ <key>stingent</key>
+ <string>stringent</string>
+ <key>stiring</key>
+ <string>stirring</string>
+ <key>stirrs</key>
+ <string>stirs</string>
+ <key>stlye</key>
+ <string>style</string>
+ <key>stomache</key>
+ <string>stomach</string>
+ <key>stong</key>
+ <string>strong</string>
+ <key>stopry</key>
+ <string>story</string>
+ <key>storeis</key>
+ <string>stories</string>
+ <key>storise</key>
+ <string>stories</string>
+ <key>stornegst</key>
+ <string>strongest</string>
+ <key>stoyr</key>
+ <string>story</string>
+ <key>stpo</key>
+ <string>stop</string>
+ <key>stradegies</key>
+ <string>strategies</string>
+ <key>stradegy</key>
+ <string>strategy</string>
+ <key>strat</key>
+ <string>start</string>
+ <key>stratagically</key>
+ <string>strategically</string>
+ <key>streemlining</key>
+ <string>streamlining</string>
+ <key>stregth</key>
+ <string>strength</string>
+ <key>strenghen</key>
+ <string>strengthen</string>
+ <key>strenghened</key>
+ <string>strengthened</string>
+ <key>strenghening</key>
+ <string>strengthening</string>
+ <key>strenght</key>
+ <string>strength</string>
+ <key>strenghten</key>
+ <string>strengthen</string>
+ <key>strenghtened</key>
+ <string>strengthened</string>
+ <key>strenghtening</key>
+ <string>strengthening</string>
+ <key>strengtened</key>
+ <string>strengthened</string>
+ <key>strenous</key>
+ <string>strenuous</string>
+ <key>strictist</key>
+ <string>strictest</string>
+ <key>strikely</key>
+ <string>strikingly</string>
+ <key>strnad</key>
+ <string>strand</string>
+ <key>stroy</key>
+ <string>story</string>
+ <key>structual</key>
+ <string>structural</string>
+ <key>stubborness</key>
+ <string>stubbornness</string>
+ <key>stucture</key>
+ <string>structure</string>
+ <key>stuctured</key>
+ <string>structured</string>
+ <key>studdy</key>
+ <string>study</string>
+ <key>studing</key>
+ <string>studying</string>
+ <key>stuggling</key>
+ <string>struggling</string>
+ <key>sturcture</key>
+ <string>structure</string>
+ <key>subcatagories</key>
+ <string>subcategories</string>
+ <key>subcatagory</key>
+ <string>subcategory</string>
+ <key>subconsiously</key>
+ <string>subconsciously</string>
+ <key>subjudgation</key>
+ <string>subjugation</string>
+ <key>submachne</key>
+ <string>submachine</string>
+ <key>subpecies</key>
+ <string>subspecies</string>
+ <key>subsidary</key>
+ <string>subsidiary</string>
+ <key>subsiduary</key>
+ <string>subsidiary</string>
+ <key>subsquent</key>
+ <string>subsequent</string>
+ <key>subsquently</key>
+ <string>subsequently</string>
+ <key>substace</key>
+ <string>substance</string>
+ <key>substancial</key>
+ <string>substantial</string>
+ <key>substatial</key>
+ <string>substantial</string>
+ <key>substituded</key>
+ <string>substituted</string>
+ <key>substract</key>
+ <string>subtract</string>
+ <key>substracted</key>
+ <string>subtracted</string>
+ <key>substracting</key>
+ <string>subtracting</string>
+ <key>substraction</key>
+ <string>subtraction</string>
+ <key>substracts</key>
+ <string>subtracts</string>
+ <key>subtances</key>
+ <string>substances</string>
+ <key>subterranian</key>
+ <string>subterranean</string>
+ <key>suburburban</key>
+ <string>suburban</string>
+ <key>succceeded</key>
+ <string>succeeded</string>
+ <key>succcesses</key>
+ <string>successes</string>
+ <key>succedded</key>
+ <string>succeeded</string>
+ <key>succeded</key>
+ <string>succeeded</string>
+ <key>succeds</key>
+ <string>succeeds</string>
+ <key>succesful</key>
+ <string>successful</string>
+ <key>succesfully</key>
+ <string>successfully</string>
+ <key>succesfuly</key>
+ <string>successfully</string>
+ <key>succesion</key>
+ <string>succession</string>
+ <key>succesive</key>
+ <string>successive</string>
+ <key>successfull</key>
+ <string>successful</string>
+ <key>successully</key>
+ <string>successfully</string>
+ <key>succsess</key>
+ <string>success</string>
+ <key>succsessfull</key>
+ <string>successful</string>
+ <key>suceed</key>
+ <string>succeed</string>
+ <key>suceeded</key>
+ <string>succeeded</string>
+ <key>suceeding</key>
+ <string>succeeding</string>
+ <key>suceeds</key>
+ <string>succeeds</string>
+ <key>sucesful</key>
+ <string>successful</string>
+ <key>sucesfully</key>
+ <string>successfully</string>
+ <key>sucesfuly</key>
+ <string>successfully</string>
+ <key>sucesion</key>
+ <string>succession</string>
+ <key>sucess</key>
+ <string>success</string>
+ <key>sucesses</key>
+ <string>successes</string>
+ <key>sucessful</key>
+ <string>successful</string>
+ <key>sucessfull</key>
+ <string>successful</string>
+ <key>sucessfully</key>
+ <string>successfully</string>
+ <key>sucessfuly</key>
+ <string>successfully</string>
+ <key>sucession</key>
+ <string>succession</string>
+ <key>sucessive</key>
+ <string>successive</string>
+ <key>sucessor</key>
+ <string>successor</string>
+ <key>sucessot</key>
+ <string>successor</string>
+ <key>sucide</key>
+ <string>suicide</string>
+ <key>sucidial</key>
+ <string>suicidal</string>
+ <key>sufferage</key>
+ <string>suffrage</string>
+ <key>sufferred</key>
+ <string>suffered</string>
+ <key>sufferring</key>
+ <string>suffering</string>
+ <key>sufficent</key>
+ <string>sufficient</string>
+ <key>sufficently</key>
+ <string>sufficiently</string>
+ <key>sumary</key>
+ <string>summary</string>
+ <key>sunglases</key>
+ <string>sunglasses</string>
+ <key>suop</key>
+ <string>soup</string>
+ <key>superceeded</key>
+ <string>superseded</string>
+ <key>superintendant</key>
+ <string>superintendent</string>
+ <key>suphisticated</key>
+ <string>sophisticated</string>
+ <key>suplimented</key>
+ <string>supplemented</string>
+ <key>supose</key>
+ <string>suppose</string>
+ <key>suposed</key>
+ <string>supposed</string>
+ <key>suposedly</key>
+ <string>supposedly</string>
+ <key>suposes</key>
+ <string>supposes</string>
+ <key>suposing</key>
+ <string>supposing</string>
+ <key>supplamented</key>
+ <string>supplemented</string>
+ <key>suppliementing</key>
+ <string>supplementing</string>
+ <key>suppoed</key>
+ <string>supposed</string>
+ <key>supposingly</key>
+ <string>supposedly</string>
+ <key>suppy</key>
+ <string>supply</string>
+ <key>supress</key>
+ <string>suppress</string>
+ <key>supressed</key>
+ <string>suppressed</string>
+ <key>supresses</key>
+ <string>suppresses</string>
+ <key>supressing</key>
+ <string>suppressing</string>
+ <key>suprise</key>
+ <string>surprise</string>
+ <key>suprised</key>
+ <string>surprised</string>
+ <key>suprising</key>
+ <string>surprising</string>
+ <key>suprisingly</key>
+ <string>surprisingly</string>
+ <key>suprize</key>
+ <string>surprise</string>
+ <key>suprized</key>
+ <string>surprised</string>
+ <key>suprizing</key>
+ <string>surprising</string>
+ <key>suprizingly</key>
+ <string>surprisingly</string>
+ <key>surfce</key>
+ <string>surface</string>
+ <key>surley</key>
+ <string>surely</string>
+ <key>suround</key>
+ <string>surround</string>
+ <key>surounded</key>
+ <string>surrounded</string>
+ <key>surounding</key>
+ <string>surrounding</string>
+ <key>suroundings</key>
+ <string>surroundings</string>
+ <key>surounds</key>
+ <string>surrounds</string>
+ <key>surplanted</key>
+ <string>supplanted</string>
+ <key>surpress</key>
+ <string>suppress</string>
+ <key>surpressed</key>
+ <string>suppressed</string>
+ <key>surprize</key>
+ <string>surprise</string>
+ <key>surprized</key>
+ <string>surprised</string>
+ <key>surprizing</key>
+ <string>surprising</string>
+ <key>surprizingly</key>
+ <string>surprisingly</string>
+ <key>surrended</key>
+ <string>surrendered</string>
+ <key>surrepetitious</key>
+ <string>surreptitious</string>
+ <key>surrepetitiously</key>
+ <string>surreptitiously</string>
+ <key>surreptious</key>
+ <string>surreptitious</string>
+ <key>surreptiously</key>
+ <string>surreptitiously</string>
+ <key>surronded</key>
+ <string>surrounded</string>
+ <key>surrouded</key>
+ <string>surrounded</string>
+ <key>surrouding</key>
+ <string>surrounding</string>
+ <key>surrundering</key>
+ <string>surrendering</string>
+ <key>surveilence</key>
+ <string>surveillance</string>
+ <key>surveill</key>
+ <string>surveil</string>
+ <key>surveyer</key>
+ <string>surveyor</string>
+ <key>surviver</key>
+ <string>survivor</string>
+ <key>survivers</key>
+ <string>survivors</string>
+ <key>survivied</key>
+ <string>survived</string>
+ <key>suseptable</key>
+ <string>susceptible</string>
+ <key>suseptible</key>
+ <string>susceptible</string>
+ <key>suspention</key>
+ <string>suspension</string>
+ <key>swaer</key>
+ <string>swear</string>
+ <key>swaers</key>
+ <string>swears</string>
+ <key>swepth</key>
+ <string>swept</string>
+ <key>swiming</key>
+ <string>swimming</string>
+ <key>syas</key>
+ <string>says</string>
+ <key>symetrical</key>
+ <string>symmetrical</string>
+ <key>symetrically</key>
+ <string>symmetrically</string>
+ <key>symetry</key>
+ <string>symmetry</string>
+ <key>symettric</key>
+ <string>symmetric</string>
+ <key>symmetral</key>
+ <string>symmetric</string>
+ <key>symmetricaly</key>
+ <string>symmetrically</string>
+ <key>synagouge</key>
+ <string>synagogue</string>
+ <key>syncronization</key>
+ <string>synchronization</string>
+ <key>synonomous</key>
+ <string>synonymous</string>
+ <key>synonymns</key>
+ <string>synonyms</string>
+ <key>synphony</key>
+ <string>symphony</string>
+ <key>syphyllis</key>
+ <string>syphilis</string>
+ <key>sypmtoms</key>
+ <string>symptoms</string>
+ <key>syrap</key>
+ <string>syrup</string>
+ <key>sysmatically</key>
+ <string>systematically</string>
+ <key>sytem</key>
+ <string>system</string>
+ <key>sytle</key>
+ <string>style</string>
+ <key>tabacco</key>
+ <string>tobacco</string>
+ <key>tahn</key>
+ <string>than</string>
+ <key>taht</key>
+ <string>that</string>
+ <key>talekd</key>
+ <string>talked</string>
+ <key>targetted</key>
+ <string>targeted</string>
+ <key>targetting</key>
+ <string>targeting</string>
+ <key>tast</key>
+ <string>taste</string>
+ <key>tath</key>
+ <string>that</string>
+ <key>tattooes</key>
+ <string>tattoos</string>
+ <key>taxanomic</key>
+ <string>taxonomic</string>
+ <key>taxanomy</key>
+ <string>taxonomy</string>
+ <key>teached</key>
+ <string>taught</string>
+ <key>techician</key>
+ <string>technician</string>
+ <key>techicians</key>
+ <string>technicians</string>
+ <key>techiniques</key>
+ <string>techniques</string>
+ <key>technitian</key>
+ <string>technician</string>
+ <key>technnology</key>
+ <string>technology</string>
+ <key>technolgy</key>
+ <string>technology</string>
+ <key>teh</key>
+ <string>the</string>
+ <key>tehy</key>
+ <string>they</string>
+ <key>telelevision</key>
+ <string>television</string>
+ <key>televsion</key>
+ <string>television</string>
+ <key>telphony</key>
+ <string>telephony</string>
+ <key>temerature</key>
+ <string>temperature</string>
+ <key>tempalte</key>
+ <string>template</string>
+ <key>tempaltes</key>
+ <string>templates</string>
+ <key>temparate</key>
+ <string>temperate</string>
+ <key>temperarily</key>
+ <string>temporarily</string>
+ <key>temperment</key>
+ <string>temperament</string>
+ <key>tempertaure</key>
+ <string>temperature</string>
+ <key>temperture</key>
+ <string>temperature</string>
+ <key>temprary</key>
+ <string>temporary</string>
+ <key>tenacle</key>
+ <string>tentacle</string>
+ <key>tenacles</key>
+ <string>tentacles</string>
+ <key>tendacy</key>
+ <string>tendency</string>
+ <key>tendancies</key>
+ <string>tendencies</string>
+ <key>tendancy</key>
+ <string>tendency</string>
+ <key>tennisplayer</key>
+ <string>tennis player</string>
+ <key>tepmorarily</key>
+ <string>temporarily</string>
+ <key>terrestial</key>
+ <string>terrestrial</string>
+ <key>terriories</key>
+ <string>territories</string>
+ <key>terriory</key>
+ <string>territory</string>
+ <key>territorist</key>
+ <string>terrorist</string>
+ <key>territoy</key>
+ <string>territory</string>
+ <key>terroist</key>
+ <string>terrorist</string>
+ <key>testiclular</key>
+ <string>testicular</string>
+ <key>tghe</key>
+ <string>the</string>
+ <key>thast</key>
+ <string>that&apos;s</string>
+ <key>theather</key>
+ <string>theater</string>
+ <key>theese</key>
+ <string>these</string>
+ <key>theif</key>
+ <string>thief</string>
+ <key>theives</key>
+ <string>thieves</string>
+ <key>themselfs</key>
+ <string>themselves</string>
+ <key>themslves</key>
+ <string>themselves</string>
+ <key>ther</key>
+ <string>there</string>
+ <key>therafter</key>
+ <string>thereafter</string>
+ <key>therby</key>
+ <string>thereby</string>
+ <key>theri</key>
+ <string>their</string>
+ <key>theyre</key>
+ <string>they&apos;re</string>
+ <key>thgat</key>
+ <string>that</string>
+ <key>thge</key>
+ <string>the</string>
+ <key>thier</key>
+ <string>their</string>
+ <key>thign</key>
+ <string>thing</string>
+ <key>thigns</key>
+ <string>things</string>
+ <key>thigsn</key>
+ <string>things</string>
+ <key>thikn</key>
+ <string>think</string>
+ <key>thikning</key>
+ <string>thinking</string>
+ <key>thikns</key>
+ <string>thinks</string>
+ <key>thiunk</key>
+ <string>think</string>
+ <key>thn</key>
+ <string>then</string>
+ <key>thna</key>
+ <string>than</string>
+ <key>thne</key>
+ <string>then</string>
+ <key>thnig</key>
+ <string>thing</string>
+ <key>thnigs</key>
+ <string>things</string>
+ <key>thoughout</key>
+ <string>throughout</string>
+ <key>threatend</key>
+ <string>threatened</string>
+ <key>threatning</key>
+ <string>threatening</string>
+ <key>threee</key>
+ <string>three</string>
+ <key>threshhold</key>
+ <string>threshold</string>
+ <key>thrid</key>
+ <string>third</string>
+ <key>throrough</key>
+ <string>thorough</string>
+ <key>throughly</key>
+ <string>thoroughly</string>
+ <key>throught</key>
+ <string>throat</string>
+ <key>througout</key>
+ <string>throughout</string>
+ <key>thru</key>
+ <string>through</string>
+ <key>thsi</key>
+ <string>this</string>
+ <key>thsoe</key>
+ <string>those</string>
+ <key>thta</key>
+ <string>that</string>
+ <key>thyat</key>
+ <string>that</string>
+ <key>tiem</key>
+ <string>time</string>
+ <key>tihkn</key>
+ <string>think</string>
+ <key>tihs</key>
+ <string>this</string>
+ <key>timne</key>
+ <string>time</string>
+ <key>tiome</key>
+ <string>time</string>
+ <key>tje</key>
+ <string>the</string>
+ <key>tjhe</key>
+ <string>the</string>
+ <key>tjpanishad</key>
+ <string>upanishad</string>
+ <key>tkae</key>
+ <string>take</string>
+ <key>tkaes</key>
+ <string>takes</string>
+ <key>tkaing</key>
+ <string>taking</string>
+ <key>tlaking</key>
+ <string>talking</string>
+ <key>tobbaco</key>
+ <string>tobacco</string>
+ <key>todays</key>
+ <string>today&apos;s</string>
+ <key>todya</key>
+ <string>today</string>
+ <key>toghether</key>
+ <string>together</string>
+ <key>toke</key>
+ <string>took</string>
+ <key>tolerence</key>
+ <string>tolerance</string>
+ <key>tomatos</key>
+ <string>tomatoes</string>
+ <key>tommorow</key>
+ <string>tomorrow</string>
+ <key>tommorrow</key>
+ <string>tomorrow</string>
+ <key>tongiht</key>
+ <string>tonight</string>
+ <key>toriodal</key>
+ <string>toroidal</string>
+ <key>tormenters</key>
+ <string>tormentors</string>
+ <key>tornadoe</key>
+ <string>tornado</string>
+ <key>torpeados</key>
+ <string>torpedoes</string>
+ <key>torpedos</key>
+ <string>torpedoes</string>
+ <key>tothe</key>
+ <string>to the</string>
+ <key>toubles</key>
+ <string>troubles</string>
+ <key>tounge</key>
+ <string>tongue</string>
+ <key>tourch</key>
+ <string>torch</string>
+ <key>towords</key>
+ <string>towards</string>
+ <key>towrad</key>
+ <string>toward</string>
+ <key>tradionally</key>
+ <string>traditionally</string>
+ <key>traditionaly</key>
+ <string>traditionally</string>
+ <key>traditionnal</key>
+ <string>traditional</string>
+ <key>traditition</key>
+ <string>tradition</string>
+ <key>tradtionally</key>
+ <string>traditionally</string>
+ <key>trafficed</key>
+ <string>trafficked</string>
+ <key>trafficing</key>
+ <string>trafficking</string>
+ <key>trafic</key>
+ <string>traffic</string>
+ <key>trancendent</key>
+ <string>transcendent</string>
+ <key>trancending</key>
+ <string>transcending</string>
+ <key>tranform</key>
+ <string>transform</string>
+ <key>tranformed</key>
+ <string>transformed</string>
+ <key>transcendance</key>
+ <string>transcendence</string>
+ <key>transcendant</key>
+ <string>transcendent</string>
+ <key>transcendentational</key>
+ <string>transcendental</string>
+ <key>transcripting</key>
+ <string>transcribing</string>
+ <key>transending</key>
+ <string>transcending</string>
+ <key>transesxuals</key>
+ <string>transsexuals</string>
+ <key>transfered</key>
+ <string>transferred</string>
+ <key>transfering</key>
+ <string>transferring</string>
+ <key>transformaton</key>
+ <string>transformation</string>
+ <key>transistion</key>
+ <string>transition</string>
+ <key>translater</key>
+ <string>translator</string>
+ <key>translaters</key>
+ <string>translators</string>
+ <key>transmissable</key>
+ <string>transmissible</string>
+ <key>transporation</key>
+ <string>transportation</string>
+ <key>tremelo</key>
+ <string>tremolo</string>
+ <key>tremelos</key>
+ <string>tremolos</string>
+ <key>triguered</key>
+ <string>triggered</string>
+ <key>triology</key>
+ <string>trilogy</string>
+ <key>troling</key>
+ <string>trolling</string>
+ <key>troup</key>
+ <string>troupe</string>
+ <key>troups</key>
+ <string>troops</string>
+ <key>truely</key>
+ <string>truly</string>
+ <key>trustworthyness</key>
+ <string>trustworthiness</string>
+ <key>turnk</key>
+ <string>trunk</string>
+ <key>tust</key>
+ <string>trust</string>
+ <key>twelth</key>
+ <string>twelfth</string>
+ <key>twon</key>
+ <string>town</string>
+ <key>twpo</key>
+ <string>two</string>
+ <key>tyhat</key>
+ <string>that</string>
+ <key>tyhe</key>
+ <string>they</string>
+ <key>typcial</key>
+ <string>typical</string>
+ <key>typicaly</key>
+ <string>typically</string>
+ <key>tyranies</key>
+ <string>tyrannies</string>
+ <key>tyrany</key>
+ <string>tyranny</string>
+ <key>tyrranies</key>
+ <string>tyrannies</string>
+ <key>tyrrany</key>
+ <string>tyranny</string>
+ <key>ubiquitious</key>
+ <string>ubiquitous</string>
+ <key>ublisher</key>
+ <string>publisher</string>
+ <key>uise</key>
+ <string>use</string>
+ <key>ultimely</key>
+ <string>ultimately</string>
+ <key>unacompanied</key>
+ <string>unaccompanied</string>
+ <key>unahppy</key>
+ <string>unhappy</string>
+ <key>unanymous</key>
+ <string>unanimous</string>
+ <key>unathorised</key>
+ <string>unauthorised</string>
+ <key>unavailible</key>
+ <string>unavailable</string>
+ <key>unballance</key>
+ <string>unbalance</string>
+ <key>unbeknowst</key>
+ <string>unbeknownst</string>
+ <key>unbeleivable</key>
+ <string>unbelievable</string>
+ <key>uncertainity</key>
+ <string>uncertainty</string>
+ <key>unchallengable</key>
+ <string>unchallengeable</string>
+ <key>unchangable</key>
+ <string>unchangeable</string>
+ <key>uncompetive</key>
+ <string>uncompetitive</string>
+ <key>unconcious</key>
+ <string>unconscious</string>
+ <key>unconciousness</key>
+ <string>unconsciousness</string>
+ <key>unconfortability</key>
+ <string>discomfort</string>
+ <key>uncontitutional</key>
+ <string>unconstitutional</string>
+ <key>unconvential</key>
+ <string>unconventional</string>
+ <key>undecideable</key>
+ <string>undecidable</string>
+ <key>understoon</key>
+ <string>understood</string>
+ <key>undesireable</key>
+ <string>undesirable</string>
+ <key>undetecable</key>
+ <string>undetectable</string>
+ <key>undoubtely</key>
+ <string>undoubtedly</string>
+ <key>undreground</key>
+ <string>underground</string>
+ <key>uneccesary</key>
+ <string>unnecessary</string>
+ <key>unecessary</key>
+ <string>unnecessary</string>
+ <key>unequalities</key>
+ <string>inequalities</string>
+ <key>unforetunately</key>
+ <string>unfortunately</string>
+ <key>unforgetable</key>
+ <string>unforgettable</string>
+ <key>unforgiveable</key>
+ <string>unforgivable</string>
+ <key>unfortunatley</key>
+ <string>unfortunately</string>
+ <key>unfortunatly</key>
+ <string>unfortunately</string>
+ <key>unfourtunately</key>
+ <string>unfortunately</string>
+ <key>unihabited</key>
+ <string>uninhabited</string>
+ <key>unilateraly</key>
+ <string>unilaterally</string>
+ <key>unilatreal</key>
+ <string>unilateral</string>
+ <key>unilatreally</key>
+ <string>unilaterally</string>
+ <key>uninterruped</key>
+ <string>uninterrupted</string>
+ <key>uninterupted</key>
+ <string>uninterrupted</string>
+ <key>univeral</key>
+ <string>universal</string>
+ <key>univeristies</key>
+ <string>universities</string>
+ <key>univeristy</key>
+ <string>university</string>
+ <key>univerity</key>
+ <string>university</string>
+ <key>universtiy</key>
+ <string>university</string>
+ <key>univesities</key>
+ <string>universities</string>
+ <key>univesity</key>
+ <string>university</string>
+ <key>unkown</key>
+ <string>unknown</string>
+ <key>unlikey</key>
+ <string>unlikely</string>
+ <key>unmanouverable</key>
+ <string>unmaneuverable</string>
+ <key>unmistakeably</key>
+ <string>unmistakably</string>
+ <key>unneccesarily</key>
+ <string>unnecessarily</string>
+ <key>unneccesary</key>
+ <string>unnecessary</string>
+ <key>unneccessarily</key>
+ <string>unnecessarily</string>
+ <key>unneccessary</key>
+ <string>unnecessary</string>
+ <key>unnecesarily</key>
+ <string>unnecessarily</string>
+ <key>unnecesary</key>
+ <string>unnecessary</string>
+ <key>unoffical</key>
+ <string>unofficial</string>
+ <key>unoperational</key>
+ <string>nonoperational</string>
+ <key>unoticeable</key>
+ <string>unnoticeable</string>
+ <key>unplease</key>
+ <string>displease</string>
+ <key>unplesant</key>
+ <string>unpleasant</string>
+ <key>unprecendented</key>
+ <string>unprecedented</string>
+ <key>unprecidented</key>
+ <string>unprecedented</string>
+ <key>unrepentent</key>
+ <string>unrepentant</string>
+ <key>unrepetant</key>
+ <string>unrepentant</string>
+ <key>unrepetent</key>
+ <string>unrepentant</string>
+ <key>unsed</key>
+ <string>unused</string>
+ <key>unsubstanciated</key>
+ <string>unsubstantiated</string>
+ <key>unsuccesful</key>
+ <string>unsuccessful</string>
+ <key>unsuccesfully</key>
+ <string>unsuccessfully</string>
+ <key>unsuccessfull</key>
+ <string>unsuccessful</string>
+ <key>unsucesful</key>
+ <string>unsuccessful</string>
+ <key>unsucesfuly</key>
+ <string>unsuccessfully</string>
+ <key>unsucessful</key>
+ <string>unsuccessful</string>
+ <key>unsucessfull</key>
+ <string>unsuccessful</string>
+ <key>unsucessfully</key>
+ <string>unsuccessfully</string>
+ <key>unsuprised</key>
+ <string>unsurprised</string>
+ <key>unsuprising</key>
+ <string>unsurprising</string>
+ <key>unsuprisingly</key>
+ <string>unsurprisingly</string>
+ <key>unsuprized</key>
+ <string>unsurprised</string>
+ <key>unsuprizing</key>
+ <string>unsurprising</string>
+ <key>unsuprizingly</key>
+ <string>unsurprisingly</string>
+ <key>unsurprized</key>
+ <string>unsurprised</string>
+ <key>unsurprizing</key>
+ <string>unsurprising</string>
+ <key>unsurprizingly</key>
+ <string>unsurprisingly</string>
+ <key>untill</key>
+ <string>until</string>
+ <key>untranslateable</key>
+ <string>untranslatable</string>
+ <key>unuseable</key>
+ <string>unusable</string>
+ <key>unusuable</key>
+ <string>unusable</string>
+ <key>unviersity</key>
+ <string>university</string>
+ <key>unwarrented</key>
+ <string>unwarranted</string>
+ <key>unweildly</key>
+ <string>unwieldy</string>
+ <key>unwieldly</key>
+ <string>unwieldy</string>
+ <key>upcomming</key>
+ <string>upcoming</string>
+ <key>upgradded</key>
+ <string>upgraded</string>
+ <key>upto</key>
+ <string>up to</string>
+ <key>usally</key>
+ <string>usually</string>
+ <key>useage</key>
+ <string>usage</string>
+ <key>usefull</key>
+ <string>useful</string>
+ <key>usefuly</key>
+ <string>usefully</string>
+ <key>useing</key>
+ <string>using</string>
+ <key>usualy</key>
+ <string>usually</string>
+ <key>ususally</key>
+ <string>usually</string>
+ <key>vaccum</key>
+ <string>vacuum</string>
+ <key>vaccume</key>
+ <string>vacuum</string>
+ <key>vacinity</key>
+ <string>vicinity</string>
+ <key>vaguaries</key>
+ <string>vagaries</string>
+ <key>vaieties</key>
+ <string>varieties</string>
+ <key>vailidty</key>
+ <string>validity</string>
+ <key>valetta</key>
+ <string>valletta</string>
+ <key>valuble</key>
+ <string>valuable</string>
+ <key>valueable</key>
+ <string>valuable</string>
+ <key>varations</key>
+ <string>variations</string>
+ <key>varient</key>
+ <string>variant</string>
+ <key>variey</key>
+ <string>variety</string>
+ <key>varing</key>
+ <string>varying</string>
+ <key>varities</key>
+ <string>varieties</string>
+ <key>varity</key>
+ <string>variety</string>
+ <key>vasall</key>
+ <string>vassal</string>
+ <key>vasalls</key>
+ <string>vassals</string>
+ <key>vegatarian</key>
+ <string>vegetarian</string>
+ <key>vegitable</key>
+ <string>vegetable</string>
+ <key>vegitables</key>
+ <string>vegetables</string>
+ <key>vegtable</key>
+ <string>vegetable</string>
+ <key>vehicule</key>
+ <string>vehicle</string>
+ <key>vell</key>
+ <string>well</string>
+ <key>venemous</key>
+ <string>venomous</string>
+ <key>vengance</key>
+ <string>vengeance</string>
+ <key>vengence</key>
+ <string>vengeance</string>
+ <key>verfication</key>
+ <string>verification</string>
+ <key>verison</key>
+ <string>version</string>
+ <key>verisons</key>
+ <string>versions</string>
+ <key>vermillion</key>
+ <string>vermilion</string>
+ <key>versitilaty</key>
+ <string>versatility</string>
+ <key>versitlity</key>
+ <string>versatility</string>
+ <key>vetween</key>
+ <string>between</string>
+ <key>veyr</key>
+ <string>very</string>
+ <key>vigeur</key>
+ <string>vigor</string>
+ <key>vigilence</key>
+ <string>vigilance</string>
+ <key>vigourous</key>
+ <string>vigorous</string>
+ <key>villian</key>
+ <string>villain</string>
+ <key>villification</key>
+ <string>vilification</string>
+ <key>villify</key>
+ <string>vilify</string>
+ <key>villin</key>
+ <string>villain</string>
+ <key>vincinity</key>
+ <string>vicinity</string>
+ <key>violentce</key>
+ <string>violence</string>
+ <key>virtualy</key>
+ <string>virtually</string>
+ <key>virutal</key>
+ <string>virtual</string>
+ <key>virutally</key>
+ <string>virtually</string>
+ <key>visable</key>
+ <string>visible</string>
+ <key>visably</key>
+ <string>visibly</string>
+ <key>visting</key>
+ <string>visiting</string>
+ <key>vistors</key>
+ <string>visitors</string>
+ <key>vitories</key>
+ <string>victories</string>
+ <key>volcanoe</key>
+ <string>volcano</string>
+ <key>voleyball</key>
+ <string>volleyball</string>
+ <key>volontary</key>
+ <string>voluntary</string>
+ <key>volonteer</key>
+ <string>volunteer</string>
+ <key>volonteered</key>
+ <string>volunteered</string>
+ <key>volonteering</key>
+ <string>volunteering</string>
+ <key>volonteers</key>
+ <string>volunteers</string>
+ <key>volounteer</key>
+ <string>volunteer</string>
+ <key>volounteered</key>
+ <string>volunteered</string>
+ <key>volounteering</key>
+ <string>volunteering</string>
+ <key>volounteers</key>
+ <string>volunteers</string>
+ <key>volumne</key>
+ <string>volume</string>
+ <key>vreity</key>
+ <string>variety</string>
+ <key>vrey</key>
+ <string>very</string>
+ <key>vriety</key>
+ <string>variety</string>
+ <key>vulnerablility</key>
+ <string>vulnerability</string>
+ <key>vyer</key>
+ <string>very</string>
+ <key>vyre</key>
+ <string>very</string>
+ <key>waht</key>
+ <string>what</string>
+ <key>wanna</key>
+ <string>want to</string>
+ <key>warantee</key>
+ <string>warranty</string>
+ <key>wardobe</key>
+ <string>wardrobe</string>
+ <key>warrent</key>
+ <string>warrant</string>
+ <key>warrriors</key>
+ <string>warriors</string>
+ <key>wasnt</key>
+ <string>wasn&apos;t</string>
+ <key>wass</key>
+ <string>was</string>
+ <key>watn</key>
+ <string>want</string>
+ <key>wayword</key>
+ <string>wayward</string>
+ <key>weaponary</key>
+ <string>weaponry</string>
+ <key>weas</key>
+ <string>was</string>
+ <key>wehn</key>
+ <string>when</string>
+ <key>weild</key>
+ <string>wield</string>
+ <key>weilded</key>
+ <string>wielded</string>
+ <key>wendsay</key>
+ <string>Wednesday</string>
+ <key>wensday</key>
+ <string>Wednesday</string>
+ <key>wereabouts</key>
+ <string>whereabouts</string>
+ <key>whant</key>
+ <string>want</string>
+ <key>whants</key>
+ <string>wants</string>
+ <key>whcih</key>
+ <string>which</string>
+ <key>wheras</key>
+ <string>whereas</string>
+ <key>wherease</key>
+ <string>whereas</string>
+ <key>whereever</key>
+ <string>wherever</string>
+ <key>whic</key>
+ <string>which</string>
+ <key>whihc</key>
+ <string>which</string>
+ <key>whith</key>
+ <string>with</string>
+ <key>whlch</key>
+ <string>which</string>
+ <key>whn</key>
+ <string>when</string>
+ <key>wholey</key>
+ <string>wholly</string>
+ <key>wholy</key>
+ <string>holy</string>
+ <key>whta</key>
+ <string>what</string>
+ <key>whther</key>
+ <string>whether</string>
+ <key>wich</key>
+ <string>which</string>
+ <key>widesread</key>
+ <string>widespread</string>
+ <key>wief</key>
+ <string>wife</string>
+ <key>wierd</key>
+ <string>weird</string>
+ <key>wiew</key>
+ <string>view</string>
+ <key>wih</key>
+ <string>with</string>
+ <key>wiht</key>
+ <string>with</string>
+ <key>wille</key>
+ <string>will</string>
+ <key>willingless</key>
+ <string>willingness</string>
+ <key>wirting</key>
+ <string>writing</string>
+ <key>withdrawl</key>
+ <string>withdrawal</string>
+ <key>witheld</key>
+ <string>withheld</string>
+ <key>withh</key>
+ <string>with</string>
+ <key>withing</key>
+ <string>within</string>
+ <key>withold</key>
+ <string>withhold</string>
+ <key>witht</key>
+ <string>with</string>
+ <key>witn</key>
+ <string>with</string>
+ <key>wiull</key>
+ <string>will</string>
+ <key>wnat</key>
+ <string>want</string>
+ <key>wnated</key>
+ <string>wanted</string>
+ <key>wnats</key>
+ <string>wants</string>
+ <key>wohle</key>
+ <string>whole</string>
+ <key>wokr</key>
+ <string>work</string>
+ <key>wokring</key>
+ <string>working</string>
+ <key>wonderfull</key>
+ <string>wonderful</string>
+ <key>wont</key>
+ <string>won&apos;t</string>
+ <key>wordlwide</key>
+ <string>worldwide</string>
+ <key>workststion</key>
+ <string>workstation</string>
+ <key>worls</key>
+ <string>world</string>
+ <key>worstened</key>
+ <string>worsened</string>
+ <key>woudl</key>
+ <string>would</string>
+ <key>wresters</key>
+ <string>wrestlers</string>
+ <key>wriet</key>
+ <string>write</string>
+ <key>writen</key>
+ <string>written</string>
+ <key>wroet</key>
+ <string>wrote</string>
+ <key>wrok</key>
+ <string>work</string>
+ <key>wroking</key>
+ <string>working</string>
+ <key>wtih</key>
+ <string>with</string>
+ <key>wupport</key>
+ <string>support</string>
+ <key>xenophoby</key>
+ <string>xenophobia</string>
+ <key>yaching</key>
+ <string>yachting</string>
+ <key>yaer</key>
+ <string>year</string>
+ <key>yaerly</key>
+ <string>yearly</string>
+ <key>yaers</key>
+ <string>years</string>
+ <key>yatch</key>
+ <string>yacht</string>
+ <key>yearm</key>
+ <string>year</string>
+ <key>yeasr</key>
+ <string>years</string>
+ <key>yeild</key>
+ <string>yield</string>
+ <key>yeilding</key>
+ <string>yielding</string>
+ <key>yera</key>
+ <string>year</string>
+ <key>yeras</key>
+ <string>years</string>
+ <key>yersa</key>
+ <string>years</string>
+ <key>yotube</key>
+ <string>YouTube</string>
+ <key>youre</key>
+ <string>you&apos;re</string>
+ <key>youseff</key>
+ <string>yousef</string>
+ <key>youself</key>
+ <string>yourself</string>
+ <key>ytou</key>
+ <string>you</string>
+ <key>yuo</key>
+ <string>you</string>
+ <key>zeebra</key>
+ <string>zebra</string>
+ </map>
+ </map>
+ </array>
+</llsd>
diff --git a/indra/newview/app_settings/cmd_line.xml b/indra/newview/app_settings/cmd_line.xml
index 15434f2b8f..a9f6079630 100644..100755
--- a/indra/newview/app_settings/cmd_line.xml
+++ b/indra/newview/app_settings/cmd_line.xml
@@ -1,117 +1,180 @@
<?xml version="1.0"?>
<llsd>
<map>
- <key>help</key>
+ <!-- Please insert new keys in alphabetical order. -->
+ <key>analyzeperformance</key>
<map>
<key>desc</key>
- <string>display this help message</string>
+ <string>When used in conjunction with logperformance, analyzes result of log against baseline.</string>
+ <key>map-to</key>
+ <string>AnalyzePerformance</string>
+ </map>
- <key>short</key>
- <string>h</string>
+ <key>autologin</key>
+ <map>
+ <key>desc</key>
+ <string>log in as last saved user</string>
+ <key>map-to</key>
+ <string>AutoLogin</string>
</map>
- <key>port</key>
+ <key>channel</key>
<map>
<key>count</key>
<integer>1</integer>
<key>map-to</key>
- <string>UserConnectionPort</string>
+ <string>CmdLineChannel</string>
</map>
- <key>drop</key>
+ <key>console</key>
<map>
<key>count</key>
<integer>1</integer>
<key>map-to</key>
- <string>PacketDropPercentage</string>
+ <string>ShowConsoleWindow</string>
</map>
- <key>inbw</key>
+ <key>cooperative</key>
<map>
+ <key>desc</key>
+ <string>Yield some idle time to local host.</string>
<key>count</key>
<integer>1</integer>
<key>map-to</key>
- <string>InBandwidth</string>
+ <string>YieldTime</string>
</map>
- <key>outbw</key>
+ <key>crashonstartup</key>
+ <map>
+ <key>desc</key>
+ <string>Crashes on startup. For QA use.</string>
+ <key>map-to</key>
+ <string>CrashOnStartup</string>
+ </map>
+
+ <key>debugsession</key>
+ <map>
+ <key>desc</key>
+ <string>Run as if RenderDebugGL is TRUE, but log errors until end of session.</string>
+ <key>map-to</key>
+ <string>DebugSession</string>
+ </map>
+
+ <key>debugviews</key>
+ <map>
+ <key>map-to</key>
+ <string>DebugViews</string>
+ </map>
+
+ <key>disablecrashlogger</key>
+ <map>
+ <key>desc</key>
+ <string>Disables the crash logger and lets the OS handle crashes</string>
+ <key>map-to</key>
+ <string>DisableCrashLogger</string>
+ </map>
+
+ <key>drop</key>
<map>
<key>count</key>
<integer>1</integer>
<key>map-to</key>
- <string>OutBandwidth</string>
+ <string>PacketDropPercentage</string>
</map>
- <key>grid</key>
+ <key>god</key>
<map>
<key>desc</key>
- <string>Specify the name of the grid, local, or an IP address to connect to.</string>
+ <string>Log in a god if you have god access.</string>
+ <key>map-to</key>
+ <string>ConnectAsGod</string>
+ </map>
+
+ <key>graphicslevel</key>
+ <map>
+ <key>desc</key>
+ <string>Set the detail level.
+0 - low, 1 - medium, 2 - high, 3 - ultra</string>
<key>count</key>
<integer>1</integer>
<key>map-to</key>
- <string>CmdLineGridChoice</string>
+ <string>RenderQualityPerformance</string>
</map>
- <key>loginuri</key>
+ <key>grid</key>
<map>
<key>desc</key>
- <string>login server and CGI script to use</string>
+ <string>Specify the name of the grid to connect to.</string>
<key>count</key>
<integer>1</integer>
- <key>compose</key>
- <boolean>true</boolean>
<key>map-to</key>
- <string>CmdLineLoginURI</string>
+ <string>CmdLineGridChoice</string>
</map>
- <key>helperuri</key>
+ <key>update-service</key>
<map>
<key>desc</key>
- <string>helper web CGI prefix to use</string>
+ <string>Override the url base for the update query.</string>
<key>count</key>
<integer>1</integer>
<key>map-to</key>
- <string>CmdLineHelperURI</string>
+ <string>CmdLineUpdateService</string>
</map>
- <key>debugviews</key>
+ <key>help</key>
<map>
- <key>map-to</key>
- <string>DebugViews</string>
+ <key>desc</key>
+ <string>display this help message</string>
+
+ <key>short</key>
+ <string>h</string>
</map>
- <key>skin</key>
+ <key>ignorepixeldepth</key>
<map>
<key>desc</key>
- <string>ui/branding skin folder to use</string>
+ <string>Ignore pixel depth settings.</string>
+ <key>map-to</key>
+ <string>IgnorePixelDepth</string>
+ </map>
+
+ <key>inbw</key>
+ <map>
<key>count</key>
<integer>1</integer>
<key>map-to</key>
- <string>SkinFolder</string>
+ <string>InBandwidth</string>
</map>
- <key>autologin</key>
+ <key>leap</key>
<map>
<key>desc</key>
- <string>log in as last saved user</string>
+ <string>command line to run an LLSD Event API Plugin</string>
+ <key>count</key>
+ <integer>1</integer>
+ <!-- you can specify multiple such plugins -->
+ <key>compose</key>
+ <boolean>true</boolean>
<key>map-to</key>
- <string>AutoLogin</string>
+ <string>LeapCommand</string>
</map>
- <key>quitafter</key>
+ <key>logfile</key>
<map>
<key>count</key>
<integer>1</integer>
<key>map-to</key>
- <string>QuitAfterSeconds</string>
+ <string>UserLogFile</string>
</map>
- <key>logperformance</key>
+ <key>login</key>
<map>
<key>desc</key>
- <string>Log performance metrics for benchmarking</string>
+ <string>3 tokens: first, last and password</string>
+ <key>count</key>
+ <integer>3</integer>
<key>map-to</key>
- <string>LogPerformance</string>
+ <string>UserLoginInfo</string>
</map>
<key>logmetrics</key>
@@ -123,55 +186,49 @@
<key>map-to</key>
<string>LogMetrics</string>
</map>
-
- <key>analyzeperformance</key>
- <map>
- <key>desc</key>
- <string>When used in conjunction with logperformance, analyzes result of log against baseline.</string>
- <key>map-to</key>
- <string>AnalyzePerformance</string>
- </map>
- <key>debugsession</key>
+ <key>logperformance</key>
<map>
<key>desc</key>
- <string>Run as if RenderDebugGL is TRUE, but log errors until end of session.</string>
+ <string>Log performance metrics for benchmarking</string>
<key>map-to</key>
- <string>DebugSession</string>
+ <string>LogPerformance</string>
</map>
- <key>replaysession</key>
+ <key>multiple</key>
<map>
<key>desc</key>
- <string>After login, replay last recorded session and quit.</string>
+ <string>Allow multiple viewers.</string>
<key>map-to</key>
- <string>ReplaySession</string>
+ <string>AllowMultipleViewers</string>
</map>
- <key>nonotifications</key>
+ <key>noaudio</key>
<map>
- <key>desc</key>
- <string>User will not get any notifications. NOTE: All notifications that occur will get added to ignore file for future runs.</string>
<key>map-to</key>
- <string>IgnoreAllNotifications</string>
+ <string>NoAudio</string>
</map>
- <key>rotate</key>
+ <key>noinvlib</key>
<map>
+ <key>desc</key>
+ <string>Do not request the inventory library.</string>
<key>map-to</key>
- <string>RotateRight</string>
+ <string>NoInventoryLibrary</string>
</map>
- <key>noaudio</key>
+ <key>nonotifications</key>
<map>
+ <key>desc</key>
+ <string>User will not get any notifications. NOTE: All notifications that occur will get added to ignore file for future runs.</string>
<key>map-to</key>
- <string>NoAudio</string>
+ <string>IgnoreAllNotifications</string>
</map>
- <key>nosound</key>
+ <key>nopreload</key>
<map>
<key>map-to</key>
- <string>NoAudio</string>
+ <string>NoPreload</string>
</map>
<key>noprobe</key>
@@ -186,151 +243,134 @@
<string>NoQuickTime</string>
</map>
- <key>nopreload</key>
+ <key>nosound</key>
<map>
<key>map-to</key>
- <string>NoPreload</string>
+ <string>NoAudio</string>
</map>
- <key>purge</key>
+ <key>no-verify-ssl-cert</key>
<map>
- <key>desc</key>
- <string>Delete files in the cache.</string>
<key>map-to</key>
- <string>PurgeCacheOnNextStartup</string>
+ <string>NoVerifySSLCert</string>
</map>
- <key>noinvlib</key>
+ <key>novoice</key>
<map>
<key>desc</key>
- <string>Do not request the inventory library.</string>
+ <string>Disable voice.</string>
<key>map-to</key>
- <string>NoInventoryLibrary</string>
+ <string>CmdLineDisableVoice</string>
</map>
- <key>logfile</key>
+ <key>outbw</key>
<map>
<key>count</key>
<integer>1</integer>
<key>map-to</key>
- <string>UserLogFile</string>
+ <string>OutBandwidth</string>
</map>
- <key>graphicslevel</key>
+ <key>port</key>
<map>
- <key>desc</key>
- <string>Set the detail level.
-0 - low, 1 - medium, 2 - high, 3 - ultra</string>
<key>count</key>
<integer>1</integer>
+ <key>map-to</key>
+ <string>UserConnectionPort</string>
</map>
- <key>setdefault</key>
+ <key>purge</key>
<map>
<key>desc</key>
- <string>specify the value of a particular configuration variable which can be overridden by settings.xml.</string>
- <key>count</key>
- <integer>2</integer>
- <!-- Special case. Mapped to settings procedurally. -->
+ <string>Delete files in the cache.</string>
+ <key>map-to</key>
+ <string>PurgeCacheOnNextStartup</string>
</map>
- <key>set</key>
+ <key>qa</key>
<map>
<key>desc</key>
- <string>specify the value of a particular configuration variable that overrides all other settings.</string>
- <key>count</key>
- <integer>2</integer>
- <key>compose</key>
- <boolean>true</boolean>
- <!-- Special case. Mapped to settings procedurally. -->
+ <string>Activated debugging menu in Advanced Settings.</string>
+ <key>map-to</key>
+ <string>QAMode</string>
</map>
- <key>settings</key>
+ <key>quitafter</key>
<map>
- <key>desc</key>
- <string>Specify the filename of a configuration file.</string>
<key>count</key>
<integer>1</integer>
- <!-- Special case. Mapped to settings procedurally. -->
+ <key>map-to</key>
+ <string>QuitAfterSeconds</string>
</map>
- <key>sessionsettings</key>
+ <key>replaysession</key>
<map>
<key>desc</key>
- <string>Specify the filename of a configuration file that contains temporary per-session configuration overrides.</string>
- <key>count</key>
- <integer>1</integer>
- <!-- Special case. Mapped to settings procedurally. -->
+ <string>After login, replay last recorded session and quit.</string>
+ <key>map-to</key>
+ <string>ReplaySession</string>
</map>
- <key>usersessionsettings</key>
+ <key>rotate</key>
<map>
- <key>desc</key>
- <string>Specify the filename of a configuration file that contains temporary per-session configuration user overrides.</string>
- <key>count</key>
- <integer>1</integer>
- <!-- Special case. Mapped to settings procedurally. -->
+ <key>map-to</key>
+ <string>RotateRight</string>
</map>
- <key>login</key>
+ <key>safe</key>
<map>
<key>desc</key>
- <string>3 tokens: first, last and password</string>
- <key>count</key>
- <integer>3</integer>
+ <string>Reset preferences, run in safe mode.</string>
<key>map-to</key>
- <string>UserLoginInfo</string>
+ <string>SafeMode</string>
</map>
- <key>god</key>
+ <key>sessionsettings</key>
<map>
<key>desc</key>
- <string>Log in a god if you have god access.</string>
- <key>map-to</key>
- <string>ConnectAsGod</string>
- </map>
-
- <key>console</key>
- <map>
+ <string>Specify the filename of a configuration file that contains temporary per-session configuration overrides.</string>
<key>count</key>
<integer>1</integer>
- <key>map-to</key>
- <string>ShowConsoleWindow</string>
+ <!-- Special case. Mapped to settings procedurally. -->
</map>
- <key>safe</key>
+ <key>set</key>
<map>
<key>desc</key>
- <string>Reset preferences, run in safe mode.</string>
- <key>map-to</key>
- <string>SafeMode</string>
+ <string>specify the value of a particular configuration variable that overrides all other settings.</string>
+ <key>count</key>
+ <integer>2</integer>
+ <key>compose</key>
+ <boolean>true</boolean>
+ <!-- Special case. Mapped to settings procedurally. -->
</map>
- <key>multiple</key>
+ <key>setdefault</key>
<map>
<key>desc</key>
- <string>Allow multiple viewers.</string>
- <key>map-to</key>
- <string>AllowMultipleViewers</string>
+ <string>specify the value of a particular configuration variable which can be overridden by settings.xml.</string>
+ <key>count</key>
+ <integer>2</integer>
+ <!-- Special case. Mapped to settings procedurally. -->
</map>
- <key>novoice</key>
+ <key>settings</key>
<map>
<key>desc</key>
- <string>Disable voice.</string>
- <key>map-to</key>
- <string>CmdLineDisableVoice</string>
+ <string>Specify the filename of a configuration file.</string>
+ <key>count</key>
+ <integer>1</integer>
+ <!-- Special case. Mapped to settings procedurally. -->
</map>
- <key>url</key>
+ <key>skin</key>
<map>
<key>desc</key>
- <string>Startup location</string>
+ <string>ui/branding skin folder to use</string>
<key>count</key>
<integer>1</integer>
- <key>last_option</key>
- <boolean>true</boolean>
- <!-- Special case. Not mapped to a setting. -->
+ <key>map-to</key>
+ <string>SkinCurrent</string>
</map>
<key>slurl</key>
@@ -343,72 +383,29 @@
<boolean>true</boolean>
<key>last_option</key>
<boolean>true</boolean>
- <!-- Special case. Not mapped to a setting. -->
- </map>
-
- <key>ignorepixeldepth</key>
- <map>
- <key>desc</key>
- <string>Ignore pixel depth settings.</string>
<key>map-to</key>
- <string>IgnorePixelDepth</string>
+ <string>CmdLineLoginLocation</string>
</map>
- <key>cooperative</key>
+ <key>url</key>
<map>
<key>desc</key>
- <string>Yield some idle time to local host.</string>
+ <string>Startup location</string>
<key>count</key>
<integer>1</integer>
+ <key>last_option</key>
+ <boolean>true</boolean>
<key>map-to</key>
- <string>YieldTime</string>
- </map>
-
- <key>no-verify-ssl-cert</key>
- <map>
- <key>map-to</key>
- <string>NoVerifySSLCert</string>
+ <string>CmdLineLoginLocation</string>
</map>
- <key>channel</key>
- <map>
- <key>count</key>
- <integer>1</integer>
- <!-- Special case. Not mapped to a setting. -->
- </map>
-
- <key>loginpage</key>
+ <key>usersessionsettings</key>
<map>
<key>desc</key>
- <string>Login authentication page to use.</string>
+ <string>Specify the filename of a configuration file that contains temporary per-session configuration user overrides.</string>
<key>count</key>
<integer>1</integer>
- <key>map-to</key>
- <string>LoginPage</string>
- </map>
-
- <key>qa</key>
- <map>
- <key>desc</key>
- <string>Activated debugging menu in Advanced Settings.</string>
- <key>map-to</key>
- <string>QAMode</string>
- </map>
-
- <key>crashonstartup</key>
- <map>
- <key>desc</key>
- <string>Crashes on startup. For QA use.</string>
- <key>map-to</key>
- <string>CrashOnStartup</string>
- </map>
-
- <key>disablecrashlogger</key>
- <map>
- <key>desc</key>
- <string>Disables the crash logger and lets the OS handle crashes</string>
- <key>map-to</key>
- <string>DisableCrashLogger</string>
+ <!-- Special case. Mapped to settings procedurally. -->
</map>
</map>
</llsd>
diff --git a/indra/newview/app_settings/commands.xml b/indra/newview/app_settings/commands.xml
index 73df064ab2..ce878f156b 100644..100755
--- a/indra/newview/app_settings/commands.xml
+++ b/indra/newview/app_settings/commands.xml
@@ -3,6 +3,8 @@
<command name="aboutland"
available_in_toybox="true"
icon="Command_AboutLand_Icon"
+ hover_icon_unselected="Command_Highlighting_Icon"
+ hover_icon_selected="Command_Highlighting_Selected_Icon"
label_ref="Command_AboutLand_Label"
tooltip_ref="Command_AboutLand_Tooltip"
execute_function="Floater.ToggleOrBringToFront"
@@ -13,6 +15,8 @@
<command name="appearance"
available_in_toybox="true"
icon="Command_Appearance_Icon"
+ hover_icon_unselected="Command_Highlighting_Icon"
+ hover_icon_selected="Command_Highlighting_Selected_Icon"
label_ref="Command_Appearance_Label"
tooltip_ref="Command_Appearance_Tooltip"
execute_function="Floater.ToggleOrBringToFront"
@@ -23,6 +27,8 @@
<command name="avatar"
available_in_toybox="true"
icon="Command_Avatar_Icon"
+ hover_icon_unselected="Command_Highlighting_Icon"
+ hover_icon_selected="Command_Highlighting_Selected_Icon"
label_ref="Command_Avatar_Label"
tooltip_ref="Command_Avatar_Tooltip"
execute_function="Floater.ToggleOrBringToFront"
@@ -33,6 +39,8 @@
<command name="build"
available_in_toybox="true"
icon="Command_Build_Icon"
+ hover_icon_unselected="Command_Highlighting_Icon"
+ hover_icon_selected="Command_Highlighting_Selected_Icon"
label_ref="Command_Build_Label"
tooltip_ref="Command_Build_Tooltip"
execute_function="Build.Toggle"
@@ -44,17 +52,22 @@
/>
<command name="chat"
available_in_toybox="true"
+ is_flashing_allowed="true"
icon="Command_Chat_Icon"
+ hover_icon_unselected="Command_Highlighting_Icon"
+ hover_icon_selected="Command_Highlighting_Selected_Icon"
label_ref="Command_Chat_Label"
- tooltip_ref="Command_Chat_Tooltip"
+ tooltip_ref="Command_Conversations_Tooltip"
execute_function="Floater.ToggleOrBringToFront"
- execute_parameters="chat_bar"
+ execute_parameters="im_container"
is_running_function="Floater.IsOpen"
- is_running_parameters="chat_bar"
+ is_running_parameters="im_container"
/>
<command name="compass"
available_in_toybox="false"
icon="Command_Compass_Icon"
+ hover_icon_unselected="Command_Highlighting_Icon"
+ hover_icon_selected="Command_Highlighting_Selected_Icon"
label_ref="Command_Compass_Label"
tooltip_ref="Command_Compass_Tooltip"
execute_function="Floater.ToggleOrBringToFront"
@@ -65,6 +78,8 @@
<command name="destinations"
available_in_toybox="true"
icon="Command_Destinations_Icon"
+ hover_icon_unselected="Command_Highlighting_Icon"
+ hover_icon_selected="Command_Highlighting_Selected_Icon"
label_ref="Command_Destinations_Label"
tooltip_ref="Command_Destinations_Tooltip"
execute_function="Floater.ToggleOrBringToFront"
@@ -75,6 +90,8 @@
<command name="gestures"
available_in_toybox="true"
icon="Command_Gestures_Icon"
+ hover_icon_unselected="Command_Highlighting_Icon"
+ hover_icon_selected="Command_Highlighting_Selected_Icon"
label_ref="Command_Gestures_Label"
tooltip_ref="Command_Gestures_Tooltip"
execute_function="Floater.ToggleOrBringToFront"
@@ -85,6 +102,8 @@
<command name="howto"
available_in_toybox="true"
icon="Command_HowTo_Icon"
+ hover_icon_unselected="Command_Highlighting_Icon"
+ hover_icon_selected="Command_Highlighting_Selected_Icon"
label_ref="Command_HowTo_Label"
tooltip_ref="Command_HowTo_Tooltip"
execute_function="Help.ToggleHowTo"
@@ -93,6 +112,8 @@
<command name="inventory"
available_in_toybox="true"
icon="Command_Inventory_Icon"
+ hover_icon_unselected="Command_Highlighting_Icon"
+ hover_icon_selected="Command_Highlighting_Selected_Icon"
label_ref="Command_Inventory_Label"
tooltip_ref="Command_Inventory_Tooltip"
execute_function="Floater.ToggleOrBringToFront"
@@ -103,6 +124,8 @@
<command name="map"
available_in_toybox="true"
icon="Command_Map_Icon"
+ hover_icon_unselected="Command_Highlighting_Icon"
+ hover_icon_selected="Command_Highlighting_Selected_Icon"
label_ref="Command_Map_Label"
tooltip_ref="Command_Map_Tooltip"
execute_function="Floater.ToggleOrBringToFront"
@@ -113,6 +136,8 @@
<command name="marketplace"
available_in_toybox="false"
icon="Command_Marketplace_Icon"
+ hover_icon_unselected="Command_Highlighting_Icon"
+ hover_icon_selected="Command_Highlighting_Selected_Icon"
label_ref="Command_Marketplace_Label"
tooltip_ref="Command_Marketplace_Tooltip"
execute_function="Avatar.OpenMarketplace"
@@ -120,6 +145,8 @@
<command name="minimap"
available_in_toybox="true"
icon="Command_MiniMap_Icon"
+ hover_icon_unselected="Command_Highlighting_Icon"
+ hover_icon_selected="Command_Highlighting_Selected_Icon"
label_ref="Command_MiniMap_Label"
tooltip_ref="Command_MiniMap_Tooltip"
execute_function="Floater.ToggleOrBringToFront"
@@ -130,6 +157,8 @@
<command name="move"
available_in_toybox="true"
icon="Command_Move_Icon"
+ hover_icon_unselected="Command_Highlighting_Icon"
+ hover_icon_selected="Command_Highlighting_Selected_Icon"
label_ref="Command_Move_Label"
tooltip_ref="Command_Move_Tooltip"
execute_function="Floater.ToggleOrBringToFront"
@@ -140,6 +169,8 @@
<command name="outbox"
available_in_toybox="false"
icon="Command_Outbox_Icon"
+ hover_icon_unselected="Command_Highlighting_Icon"
+ hover_icon_selected="Command_Highlighting_Selected_Icon"
label_ref="Command_Outbox_Label"
tooltip_ref="Command_Outbox_Tooltip"
execute_function="Floater.ToggleOrBringToFront"
@@ -150,6 +181,8 @@
<command name="people"
available_in_toybox="true"
icon="Command_People_Icon"
+ hover_icon_unselected="Command_Highlighting_Icon"
+ hover_icon_selected="Command_Highlighting_Selected_Icon"
label_ref="Command_People_Label"
tooltip_ref="Command_People_Tooltip"
execute_function="Floater.ToggleOrBringToFront"
@@ -160,6 +193,8 @@
<command name="picks"
available_in_toybox="true"
icon="Command_Picks_Icon"
+ hover_icon_unselected="Command_Highlighting_Icon"
+ hover_icon_selected="Command_Highlighting_Selected_Icon"
label_ref="Command_Picks_Label"
tooltip_ref="Command_Picks_Tooltip"
execute_function="Floater.ToggleOrBringToFront"
@@ -170,6 +205,8 @@
<command name="places"
available_in_toybox="true"
icon="Command_Places_Icon"
+ hover_icon_unselected="Command_Highlighting_Icon"
+ hover_icon_selected="Command_Highlighting_Selected_Icon"
label_ref="Command_Places_Label"
tooltip_ref="Command_Places_Tooltip"
execute_function="Floater.ToggleOrBringToFront"
@@ -180,6 +217,8 @@
<command name="preferences"
available_in_toybox="true"
icon="Command_Preferences_Icon"
+ hover_icon_unselected="Command_Highlighting_Icon"
+ hover_icon_selected="Command_Highlighting_Selected_Icon"
label_ref="Command_Preferences_Label"
tooltip_ref="Command_Preferences_Tooltip"
execute_function="Floater.ToggleOrBringToFront"
@@ -190,6 +229,8 @@
<command name="profile"
available_in_toybox="true"
icon="Command_Profile_Icon"
+ hover_icon_unselected="Command_Highlighting_Icon"
+ hover_icon_selected="Command_Highlighting_Selected_Icon"
label_ref="Command_Profile_Label"
tooltip_ref="Command_Profile_Tooltip"
execute_function="Avatar.ToggleMyProfile"
@@ -198,6 +239,8 @@
<command name="search"
available_in_toybox="true"
icon="Command_Search_Icon"
+ hover_icon_unselected="Command_Highlighting_Icon"
+ hover_icon_selected="Command_Highlighting_Selected_Icon"
label_ref="Command_Search_Label"
tooltip_ref="Command_Search_Tooltip"
execute_function="Floater.ToggleOrBringToFront"
@@ -208,6 +251,8 @@
<command name="snapshot"
available_in_toybox="true"
icon="Command_Snapshot_Icon"
+ hover_icon_unselected="Command_Highlighting_Icon"
+ hover_icon_selected="Command_Highlighting_Selected_Icon"
label_ref="Command_Snapshot_Label"
tooltip_ref="Command_Snapshot_Tooltip"
execute_function="Floater.ToggleOrBringToFront"
@@ -215,9 +260,21 @@
is_running_function="Floater.IsOpen"
is_running_parameters="snapshot"
/>
+ <command name="social"
+ available_in_toybox="true"
+ icon="Command_Social_Icon"
+ label_ref="Command_Social_Label"
+ tooltip_ref="Command_Social_Tooltip"
+ execute_function="Floater.ToggleOrBringToFront"
+ execute_parameters="social"
+ is_running_function="Floater.IsOpen"
+ is_running_parameters="social"
+ />
<command name="speak"
available_in_toybox="true"
icon="Command_Speak_Icon"
+ hover_icon_unselected="Command_Highlighting_Icon"
+ hover_icon_selected="Command_Highlighting_Selected_Icon"
label_ref="Command_Speak_Label"
tooltip_ref="Command_Speak_Tooltip"
execute_function="Agent.PressMicrophone"
@@ -232,6 +289,8 @@
<command name="view"
available_in_toybox="true"
icon="Command_View_Icon"
+ hover_icon_unselected="Command_Highlighting_Icon"
+ hover_icon_selected="Command_Highlighting_Selected_Icon"
label_ref="Command_View_Label"
tooltip_ref="Command_View_Tooltip"
execute_function="Floater.ToggleOrBringToFront"
@@ -239,14 +298,4 @@
is_running_function="Floater.IsOpen"
is_running_parameters="camera"
/>
- <command name="voice"
- available_in_toybox="true"
- icon="Command_Voice_Icon"
- label_ref="Command_Voice_Label"
- tooltip_ref="Command_Voice_Tooltip"
- execute_function="Floater.ToggleOrBringToFront"
- execute_parameters="voice_controls"
- is_running_function="Floater.IsOpen"
- is_running_parameters="voice_controls"
- />
</commands>
diff --git a/indra/newview/app_settings/foldertypes.xml b/indra/newview/app_settings/foldertypes.xml
index 0d539177f3..0d539177f3 100644..100755
--- a/indra/newview/app_settings/foldertypes.xml
+++ b/indra/newview/app_settings/foldertypes.xml
diff --git a/indra/newview/app_settings/grass.xml b/indra/newview/app_settings/grass.xml
index 4fc3b798af..4fc3b798af 100644..100755
--- a/indra/newview/app_settings/grass.xml
+++ b/indra/newview/app_settings/grass.xml
diff --git a/indra/newview/app_settings/high_graphics.xml b/indra/newview/app_settings/high_graphics.xml
index 5bc2e1b7e6..5bc2e1b7e6 100644..100755
--- a/indra/newview/app_settings/high_graphics.xml
+++ b/indra/newview/app_settings/high_graphics.xml
diff --git a/indra/newview/app_settings/ignorable_dialogs.xml b/indra/newview/app_settings/ignorable_dialogs.xml
index 17d3d3c9c5..17d3d3c9c5 100644..100755
--- a/indra/newview/app_settings/ignorable_dialogs.xml
+++ b/indra/newview/app_settings/ignorable_dialogs.xml
diff --git a/indra/newview/app_settings/keys.xml b/indra/newview/app_settings/keys.xml
index 6e3673e7d9..6e3673e7d9 100644..100755
--- a/indra/newview/app_settings/keys.xml
+++ b/indra/newview/app_settings/keys.xml
diff --git a/indra/newview/app_settings/keywords.ini b/indra/newview/app_settings/keywords.ini
index 318b69438a..ad843bca14 100644..100755
--- a/indra/newview/app_settings/keywords.ini
+++ b/indra/newview/app_settings/keywords.ini
@@ -62,10 +62,12 @@ STATUS_ROTATE_X Passed in the llSetStatus library function. If FALSE, object do
STATUS_ROTATE_Y Passed in the llSetStatus library function. If FALSE, object doesn't rotate around local Y axis
STATUS_ROTATE_Z Passed in the llSetStatus library function. If FALSE, object doesn't rotate around local Z axis
STATUS_SANDBOX Passed in the llSetStatus library function. If TRUE, object can't cross region boundaries or move more than 10 meters from its start location
-STATUS_BLOCK_GRAB Passed in the llSetStatus library function. If TRUE, object can't be grabbed and physically dragged
+STATUS_BLOCK_GRAB Passed in the llSetStatus library function. If TRUE, root prim of linkset (or unlinked prim) can't be grabbed and physically dragged
STATUS_DIE_AT_EDGE Passed in the llSetStatus library function. If TRUE, objects that reach the edge of the world just die:rather than teleporting back to the owner
STATUS_RETURN_AT_EDGE Passed in the llSetStatus library function. If TRUE, script rezzed objects that reach the edge of the world:are returned rather than killed:STATUS_RETURN_AT_EDGE trumps STATUS_DIE_AT_EDGE if both are set
STATUS_CAST_SHADOWS Passed in the llSetStatus library function. If TRUE, object casts shadows on other objects
+STATUS_BLOCK_GRAB_OBJECT Passed in the llSetStatus library function. If TRUE, no prims in linkset can be grabbed or physically dragged
+
AGENT Passed in llSensor library function to look for other Agents
ACTIVE Passed in llSensor library function to look for moving objects
PASSIVE Passed in llSensor library function to look for objects that aren't moving
@@ -92,6 +94,9 @@ PERMISSION_CHANGE_LINKS Passed to llRequestPermissions library function to req
PERMISSION_TRACK_CAMERA Passed to llRequestPermissions library function to request permission to track agent's camera
PERMISSION_CONTROL_CAMERA Passed to llRequestPermissions library function to request permission to change agent's camera
PERMISSION_TELEPORT Passed to llRequestPermissions library function to request permission to teleport agent
+PERMISSION_SILENT_ESTATE_MANAGEMENT Passed to llRequestPermissions library function to request permission to silently modify estate access lists
+PERMISSION_OVERRIDE_ANIMATIONS Passed to llRequestPermissions library function to request permission to override animations on agent
+PERMISSION_RETURN_OBJECTS Passed to llRequestPermissions library function to request permission to return objects
DEBUG_CHANNEL Chat channel reserved for debug and error messages from scripts
PUBLIC_CHANNEL Chat channel that broadcasts to all nearby users
@@ -129,6 +134,7 @@ PSYS_PART_FOLLOW_VELOCITY_MASK
PSYS_PART_TARGET_POS_MASK
PSYS_PART_EMISSIVE_MASK
PSYS_PART_TARGET_LINEAR_MASK
+PSYS_PART_RIBBON_MASK
PSYS_SRC_PATTERN
PSYS_SRC_INNERANGLE Deprecated -- Use PSYS_SRC_ANGLE_BEGIN
@@ -145,12 +151,24 @@ PSYS_SRC_ACCEL
PSYS_SRC_TEXTURE
PSYS_SRC_TARGET_KEY
PSYS_SRC_OMEGA
+PSYS_PART_BLEND_FUNC_SOURCE
+PSYS_PART_BLEND_FUNC_DEST
+PSYS_PART_START_GLOW
+PSYS_PART_END_GLOW
PSYS_SRC_PATTERN_DROP
PSYS_SRC_PATTERN_EXPLODE
PSYS_SRC_PATTERN_ANGLE
PSYS_SRC_PATTERN_ANGLE_CONE
PSYS_SRC_PATTERN_ANGLE_CONE_EMPTY
+PSYS_PART_BF_ONE
+PSYS_PART_BF_ZERO
+PSYS_PART_BF_DEST_COLOR
+PSYS_PART_BF_SOURCE_COLOR
+PSYS_PART_BF_ONE_MINUS_DEST_COLOR
+PSYS_PART_BF_ONE_MINUS_SOURCE_COLOR
+PSYS_PART_BF_SOURCE_ALPHA
+PSYS_PART_BF_ONE_MINUS_SOURCE_ALPHA
OBJECT_UNKNOWN_DETAIL Returned by llGetObjectDetails when passed an invalid object parameter type
OBJECT_NAME Used with llGetObjectDetails to get an object's name
@@ -161,6 +179,23 @@ OBJECT_VELOCITY Used with llGetObjectDetails to get an object's velocity
OBJECT_OWNER Used with llGetObjectDetails to get an object's owner's key. Will be NULL_KEY if group owned
OBJECT_GROUP Used with llGetObjectDetails to get an object's group's key
OBJECT_CREATOR Used with llGetObjectDetails to get an object's creator's key
+OBJECT_RUNNING_SCRIPT_COUNT Used with llGetObjectDetails to get the number of running scripts in an object
+OBJECT_TOTAL_SCRIPT_COUNT Used with llGetObjectDetails to get the total number of scripts in an object
+OBJECT_SCRIPT_MEMORY Used with llGetObjectDetails to get the total amount of script memory in an object
+OBJECT_SCRIPT_TIME Used with llGetObjectDetails to get the average script time used by an object
+OBJECT_PRIM_EQUIVALENCE Used with llGetObjectDetails to get the prim equivalence of an object
+OBJECT_SERVER_COST Used with llGetObjectDetails to get the server cost of an object
+OBJECT_STREAMING_COST Used with llGetObjectDetails to get the streaming (download) cost of an object
+OBJECT_PHYSICS_COST Used with llGetObjectDetails to get the physics cost of an object
+OBJECT_CHARACTER_TIME Used with llGetObjectDetails to get the pathfinding time (seconds) for an object
+OBJECT_ROOT Used with llGetObjectDetails to get root ID of an object
+OBJECT_ATTACHED_POINT Used with llGetObjectDetails to get attachent point where an object is attached
+OBJECT_PATHFINDING_TYPE Used with llGetObjectDetails to get the pathfinding setting of an object
+OBJECT_PHYSICS Used with llGetObjectDetails to determine if the object is physical or not
+OBJECT_PHANTOM Used with llGetObjectDetails to determine if the object is phantom or not
+OBJECT_TEMP_ON_REZ Used with llGetObjectDetails to determine if the object is temporary or not
+OBJECT_RENDER_WEIGHT Used with llGetObjectDetails to return an avatar's rendering weight
+
# some vehicle params
VEHICLE_TYPE_NONE
@@ -271,7 +306,8 @@ ATTACH_LLLEG Passed to llAttachToAvatar to attach task to left lower leg
ATTACH_BELLY Passed to llAttachToAvatar to attach task to belly
ATTACH_LEFT_PEC Passed to llAttachToAvatar to attach task to left pectoral
ATTACH_RIGHT_PEC Passed to llAttachToAvatar to attach task to right pectoral
-
+ATTACH_NECK Passed to llAttachToAvatar to attach task to neck
+ATTACH_AVATAR_CENTER Passed to llAttachToAvatar to attach task to avatar center
LAND_LEVEL Passed to llModifyLand to level terrain
LAND_RAISE Passed to llModifyLand to raise terrain
LAND_LOWER Passed to llModifyLand to lower terrain
@@ -342,7 +378,7 @@ PRIM_MATERIAL Followed by PRIM_MATERIAL_STONE, PRIM_MATERIAL_METAL, PRIM_MATERI
PRIM_PHYSICS Sets physics to TRUE or FALSE
PRIM_FLEXIBLE Followed by TRUE or FALSE, integer softness, float gravity, float friction, float wind, float tension, and vector force
PRIM_POINT_LIGHT Followed by TRUE or FALSE, vector color, float intensity, float radius, float falloff
-PRIM_TEMP_ON_REZ Sets temporay on rez to TRUE or FALSE
+PRIM_TEMP_ON_REZ Sets temporary on rez to TRUE or FALSE
PRIM_PHANTOM Sets phantom to TRUE or FALSE
PRIM_CAST_SHADOWS DEPRECATED. Takes 1 parameter, an integer, but has no effect when set and always returns 0 if used in llGetPrimitiveParams
PRIM_POSITION Sets primitive position to a vector position
@@ -354,6 +390,19 @@ PRIM_BUMP_SHINY Followed by an integer face, one of PRIM_SHINY_NONE, PRIM_SHINY
PRIM_FULLBRIGHT Followed by an integer face, and TRUE or FALSE
PRIM_TEXGEN Followed by an integer face, and one of PRIM_TEXGEN_DEFAULT or PRIM_TEXGEN_PLANAR
PRIM_GLOW Followed by an integer face, and a float from 0.0 to 1.0 specifying glow amount
+PRIM_TEXT Followed by string text, vector color, and float alpha
+PRIM_NAME Followed by string name
+PRIM_DESC Followed by string description
+PRIM_ROT_LOCAL Followed by rotation rot
+PRIM_PHYSICS_SHAPE_TYPE Followed by PRIM_PHYSICS_SHAPE_PRIM, PRIM_PHYSICS_SHAPE_NONE, or PRIM_PHYSICS_SHAPE_CONVEX
+PRIM_OMEGA Followed by vector axis, float spinrate, and float gain
+PRIM_POS_LOCAL Followed by vector position
+PRIM_LINK_TARGET Followed by integer link_target, then additional prim parameter flags
+PRIM_SLICE Followed by vector slice
+
+PRIM_PHYSICS_SHAPE_PRIM Use the default physics shape
+PRIM_PHYSICS_SHAPE_CONVEX Use the convex hull of the prim shape for physics
+PRIM_PHYSICS_SHAPE_NONE Ignore this prim in the physics shape
PRIM_TYPE_BOX Followed by integer hole shape, vector cut, float hollow, vector twist,:vector top size, and vector top shear
PRIM_TYPE_CYLINDER Followed by integer hole shape, vector cut, float hollow, vector twist,:vector top size, and vector top shear
@@ -559,6 +608,98 @@ STATUS_NOT_SUPPORTED Feature not supported
STATUS_INTERNAL_ERROR An internal error occurred
STATUS_WHITELIST_FAILED URL failed to pass whitelist
+PROFILE_NONE Disables profiling
+PROFILE_SCRIPT_MEMORY Enables memory profiling
+
+RC_DATA_FLAGS TODO: add documentation
+RC_DETECT_PHANTOM TODO: add documentation
+RC_GET_LINK_NUM TODO: add documentation
+RC_GET_NORMAL TODO: add documentation
+RC_GET_ROOT_KEY TODO: add documentation
+RC_MAX_HITS TODO: add documentation
+RC_REJECT_TYPES Optional parameter set in llCastRay() to reject hit against certain object types.
+RC_REJECT_AGENTS Bit mask for RC_REJECT_TYPES, rejects hits against avatars.
+RC_REJECT_PHYSICAL Bit mask for RC_REJECT_TYPES, rejects hits against moving objects.
+RC_REJECT_NONPHYSICAL Bit mask for RC_REJECT_TYPES, rejects hits against non-moving objects.
+RC_REJECT_LAND Bit mask for RC_REJECT_TYPES, rejects hits against the terrian.
+
+RCERR_CAST_TIME_EXCEEDED TODO: add documentation
+RCERR_SIM_PERF_LOW TODO: add documentation
+RCERR_UNKNOWN TODO: add documentation
+
+ESTATE_ACCESS_ALLOWED_AGENT_ADD TODO: add documentation
+ESTATE_ACCESS_ALLOWED_AGENT_REMOVE TODO: add documentation
+ESTATE_ACCESS_ALLOWED_GROUP_ADD TODO: add documentation
+ESTATE_ACCESS_ALLOWED_GROUP_REMOVE TODO: add documentation
+ESTATE_ACCESS_BANNED_AGENT_ADD TODO: add documentation
+ESTATE_ACCESS_BANNED_AGENT_REMOVE TODO: add documentation
+
+DENSITY TODO: add documentation
+FRICTION TODO: add documentation
+RESTITUTION TODO: add documentation
+GRAVITY_MULTIPLIER TODO: add documentation
+
+KFM_COMMAND TODO: add documentation
+KFM_CMD_PLAY TODO: add documentation
+KFM_CMD_STOP TODO: add documentation
+KFM_CMD_PAUSE TODO: add documentation
+KFM_CMD_SET_MODE TODO: add documentation
+KFM_MODE TODO: add documentation
+KFM_FORWARD TODO: add documentation
+KFM_LOOP TODO: add documentation
+KFM_PING_PONG TODO: add documentation
+KFM_REVERSE TODO: add documentation
+KFM_DATA TODO: add documentation
+KFM_ROTATION TODO: add documentation
+KFM_TRANSLATION TODO: add documentation
+
+CHARACTER_CMD_STOP TODO: add documentation
+CHARACTER_CMD_JUMP TODO: add documentation
+
+CHARACTER_DESIRED_SPEED TODO: add documentation
+CHARACTER_RADIUS TODO: add documentation
+CHARACTER_LENGTH TODO: add documentation
+CHARACTER_ORIENTATION TODO: add documentation
+CHARACTER_AVOIDANCE_MODE TODO: add documentation
+PURSUIT_OFFSET TODO: add documentation
+REQUIRE_LINE_OF_SIGHT TODO: add documentation
+PURSUIT_FUZZ_FACTOR TODO: add documentation
+PURSUIT_INTERCEPT TODO: add documentation
+FORCE_DIRECT_PATH TODO: add documentation
+VERTICAL TODO: add documentation
+HORIZONTAL TODO: add documentation
+AVOID_CHARACTERS TODO: add documentation
+AVOID_DYNAMIC_OBSTACLES TODO: add documentation
+
+PU_EVADE_HIDDEN Triggered when an llEvade character thinks it has hidden from its pursuer.
+PU_EVADE_SPOTTED Triggered when an llEvade character switches from hiding to running
+PU_FAILURE_INVALID_GOAL Goal is not on the navigation-mesh and cannot be reached.
+PU_FAILURE_INVALID_START Character cannot navigate from the current location - e.g., the character is off the navmesh or too high above it.
+PU_FAILURE_NO_VALID_DESTINATION There's no good place for the character to go - e.g., it is patrolling and all the patrol points are now unreachable.
+PU_FAILURE_OTHER Unknown failure
+PU_FAILURE_TARGET_GONE Target (for llPursue or llEvade) can no longer be tracked - e.g., it left the region or is an avatar that is now more than about 30m outside the region.
+PU_FAILURE_UNREACHABLE Goal is no longer reachable for some reason - e.g., an obstacle blocks the path.
+PU_GOAL_REACHED Character has reached the goal and will stop or choose a new goal (if wandering).
+PU_SLOWDOWN_DISTANCE_REACHED Character is near current goal.
+
+CHARACTER_TYPE TODO: add documentation
+CHARACTER_TYPE_A TODO: add documentation
+CHARACTER_TYPE_B TODO: add documentation
+CHARACTER_TYPE_C TODO: add documentation
+CHARACTER_TYPE_D TODO: add documentation
+CHARACTER_TYPE_NONE TODO: add documentation
+
+TRAVERSAL_TYPE TODO: add documentation
+TRAVERSAL_TYPE_SLOW TODO: add documentation
+TRAVERSAL_TYPE_FAST TODO: add documentation
+TRAVERSAL_TYPE_NONE TODO: add documentation
+
+CHARACTER_MAX_ACCEL TODO: add documentation
+CHARACTER_MAX_DECEL TODO: add documentation
+CHARACTER_MAX_ANGULAR_SPEED TODO: add documentation
+CHARACTER_MAX_ANGULAR_ACCEL TODO: add documentation
+CHARACTER_TURN_SPEED_MULTIPLIER TODO: add documentation
+
# string constants
[word .1, .3, .5]
NULL_KEY Indicates an empty key
diff --git a/indra/newview/app_settings/lindenlab.pem b/indra/newview/app_settings/lindenlab.pem
index eddae0426d..eddae0426d 100644..100755
--- a/indra/newview/app_settings/lindenlab.pem
+++ b/indra/newview/app_settings/lindenlab.pem
diff --git a/indra/newview/app_settings/llsd.xsd b/indra/newview/app_settings/llsd.xsd
index 34612d9faa..34612d9faa 100644..100755
--- a/indra/newview/app_settings/llsd.xsd
+++ b/indra/newview/app_settings/llsd.xsd
diff --git a/indra/newview/app_settings/logcontrol.xml b/indra/newview/app_settings/logcontrol.xml
index a76eb3cd37..92a241857e 100644..100755
--- a/indra/newview/app_settings/logcontrol.xml
+++ b/indra/newview/app_settings/logcontrol.xml
@@ -20,7 +20,7 @@
<key>tags</key>
<array>
<string>AppInit</string>
- <string>Capabilities</string>
+ <string>Capabilities</string>
<string>SystemInfo</string>
<string>TextureCache</string>
<string>AppCache</string>
@@ -42,10 +42,12 @@
</array>
<key>tags</key>
<array>
- <!-- sample entry for debugging a specific item -->
-<!-- <string>Voice</string> -->
+ <!-- sample entry for debugging specific items
+ <string>Avatar</string>
+ <string>Voice</string>
+ -->
</array>
</map>
- </array>
+ </array>
</map>
</llsd>
diff --git a/indra/newview/app_settings/low_graphics.xml b/indra/newview/app_settings/low_graphics.xml
index ca1dae0b86..ca1dae0b86 100644..100755
--- a/indra/newview/app_settings/low_graphics.xml
+++ b/indra/newview/app_settings/low_graphics.xml
diff --git a/indra/newview/app_settings/mid_graphics.xml b/indra/newview/app_settings/mid_graphics.xml
index 01822fe64c..01822fe64c 100644..100755
--- a/indra/newview/app_settings/mid_graphics.xml
+++ b/indra/newview/app_settings/mid_graphics.xml
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 203f6800aa..9cb63c6518 100644..100755
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -2,6 +2,28 @@
<llsd xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="llsd.xsd">
<map>
+ <key>IMShowTime</key>
+ <map>
+ <key>Comment</key>
+ <string>Enable(disable) timestamp showing in the chat.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>IMShowNamesForP2PConv</key>
+ <map>
+ <key>Comment</key>
+ <string>Enable(disable) showing of a names in the chat.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
<key>CrashHostUrl</key>
<map>
<key>Comment</key>
@@ -47,7 +69,7 @@
<key>Type</key>
<string>F32</string>
<key>Value</key>
- <real>0.95</real>
+ <real>1</real>
</map>
<key>AdvanceSnapshot</key>
<map>
@@ -104,6 +126,17 @@
<key>Value</key>
<integer>1</integer>
</map>
+ <key>AnalyzePerformance</key>
+ <map>
+ <key>Comment</key>
+ <string>Request performance analysis for a particular viewer run</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>AnimateTextures</key>
<map>
<key>Comment</key>
@@ -148,7 +181,7 @@
<key>Value</key>
<integer>1</integer>
</map>
- <key>ApplyTextureImmediately</key>
+ <key>TextureLivePreview</key>
<map>
<key>Comment</key>
<string>Preview selections in texture picker immediately</string>
@@ -269,6 +302,17 @@
<key>Value</key>
<real>1.0</real>
</map>
+ <key>AudioLevelUnderwaterRolloff</key>
+ <map>
+ <key>Comment</key>
+ <string>Controls the distance-based dropoff of audio volume underwater(fraction or multiple of default audio rolloff)</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>5.0</real>
+ </map>
<key>AudioLevelSFX</key>
<map>
<key>Comment</key>
@@ -335,17 +379,17 @@
<key>Value</key>
<integer>1</integer>
</map>
- <key>AuditTexture</key>
- <map>
- <key>Comment</key>
- <string>Enable texture auditting.</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>0</integer>
- </map>
+ <key>AutoReplace</key>
+ <map>
+ <key>Comment</key>
+ <string>Replaces keywords with a configured word or phrase</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>AutoAcceptNewInventory</key>
<map>
<key>Comment</key>
@@ -1562,6 +1606,28 @@
<key>Value</key>
<integer>0</integer>
</map>
+ <key>ChatLoadGroupMaxMembers</key>
+ <map>
+ <key>Comment</key>
+ <string>Max number of active members we'll show up for an unresponsive group</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <real>100</real>
+ </map>
+ <key>ChatLoadGroupTimeout</key>
+ <map>
+ <key>Comment</key>
+ <string>Time we give the server to send group participants before we hit the server for group info (seconds)</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>10.0</real>
+ </map>
<key>ChatOnlineNotification</key>
<map>
<key>Comment</key>
@@ -1595,17 +1661,6 @@
<key>Value</key>
<integer>1</integer>
</map>
- <key>ChatWindow</key>
- <map>
- <key>Comment</key>
- <string>Show chat in multiple windows(by default) or in one multi-tabbed window(requires restart)</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>0</integer>
- </map>
<key>CheesyBeacon</key>
<map>
<key>Comment</key>
@@ -1628,6 +1683,61 @@
<key>Value</key>
<string />
</map>
+ <key>ContextConeInAlpha</key>
+ <map>
+ <key>Comment</key>
+ <string>Cone In Alpha</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>0.0</real>
+ </map>
+ <key>ContextConeOutAlpha</key>
+ <map>
+ <key>Comment</key>
+ <string>Cone Out Alpha</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>1.0</real>
+ </map>
+ <key>ContextConeFadeTime</key>
+ <map>
+ <key>Comment</key>
+ <string>Cone Fade Time</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>.08</real>
+ </map>
+ <key>ConversationHistoryPageSize</key>
+ <map>
+ <key>Comment</key>
+ <string>Chat history of conversation opened from call log is displayed by pages. So this is number of entries per page.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>100</integer>
+ </map>
+ <key>ConversationSortOrder</key>
+ <map>
+ <key>Comment</key>
+ <string>Specifies sort key for conversations</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>U32</string>
+ <key>Value</key>
+ <integer>131073</integer>
+ </map>
<key>CloseChatOnReturn</key>
<map>
<key>Comment</key>
@@ -1639,6 +1749,17 @@
<key>Value</key>
<integer>0</integer>
</map>
+ <key>CmdLineChannel</key>
+ <map>
+ <key>Comment</key>
+ <string>Command line specified channel name</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>String</string>
+ <key>Value</key>
+ <string />
+ </map>
<key>CmdLineDisableVoice</key>
<map>
<key>Comment</key>
@@ -1661,6 +1782,17 @@
<key>Value</key>
<string />
</map>
+ <key>CmdLineUpdateService</key>
+ <map>
+ <key>Comment</key>
+ <string>Override the url base for the update query.</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>String</string>
+ <key>Value</key>
+ <string />
+ </map>
<key>CmdLineHelperURI</key>
<map>
<key>Comment</key>
@@ -1685,6 +1817,17 @@
<string />
</array>
</map>
+ <key>CmdLineLoginLocation</key>
+ <map>
+ <key>Comment</key>
+ <string>Startup destination requested on command line</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>String</string>
+ <key>Value</key>
+ <string/>
+ </map>
<key>ConnectAsGod</key>
<map>
<key>Comment</key>
@@ -1806,6 +1949,28 @@
<key>Value</key>
<integer>0</integer>
</map>
+ <key>CoroutineStackSize</key>
+ <map>
+ <key>Comment</key>
+ <string>Size (in bytes) for each coroutine stack</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>262144</integer>
+ </map>
+ <key>CrashOnStartup</key>
+ <map>
+ <key>Comment</key>
+ <string>User-requested crash on viewer startup</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>CreateToolCopyCenters</key>
<map>
<key>Comment</key>
@@ -1916,6 +2081,39 @@
<key>Value</key>
<string />
</map>
+ <key>DebugAvatarAppearanceMessage</key>
+ <map>
+ <key>Comment</key>
+ <string>Dump a bunch of XML files when handling appearance messages</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>DebugAvatarExperimentalServerAppearanceUpdate</key>
+ <map>
+ <key>Comment</key>
+ <string>Experiment with sending full cof_contents instead of cof_version</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>DebugAvatarAppearanceServiceURLOverride</key>
+ <map>
+ <key>Comment</key>
+ <string>URL to use for baked texture requests; overrides value returned by login server.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>String</string>
+ <key>Value</key>
+ <string />
+ </map>
<key>DebugAvatarRezTime</key>
<map>
<key>Comment</key>
@@ -1936,6 +2134,17 @@
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>DebugAvatarCompositeBaked</key>
+ <map>
+ <key>Comment</key>
+ <string>Colorize avatar meshes based on baked/composite state.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
<integer>0</integer>
</map>
<key>DebugBeaconLineWidth</key>
@@ -1949,6 +2158,17 @@
<key>Value</key>
<integer>1</integer>
</map>
+ <key>DebugForceAppearanceRequestFailure</key>
+ <map>
+ <key>Comment</key>
+ <string>Request wrong cof version to test the failure path for server appearance update requests.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>DebugHideEmptySystemFolders</key>
<map>
<key>Comment</key>
@@ -1993,6 +2213,28 @@
<key>Value</key>
<integer>0</integer>
</map>
+ <key>DebugSession</key>
+ <map>
+ <key>Comment</key>
+ <string>Request debugging for a particular viewer session</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>DebugShowAvatarRenderInfo</key>
+ <map>
+ <key>Comment</key>
+ <string>Show avatar render cost information</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>DebugShowColor</key>
<map>
<key>Comment</key>
@@ -2708,6 +2950,17 @@
<key>Value</key>
<integer>0</integer>
</map>
+ <key>DefaultBlankNormalTexture</key>
+ <map>
+ <key>Comment</key>
+ <string>Texture used as 'Blank' in texture picker for normal maps. (UUID texture reference)</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>String</string>
+ <key>Value</key>
+ <string>5b53359e-59dd-d8a2-04c3-9e65134da47a</string>
+ </map>
<key>DefaultFemaleAvatar</key>
<map>
<key>Comment</key>
@@ -2730,8 +2983,29 @@
<key>Value</key>
<string>Male Shape &amp; Outfit</string>
</map>
-
- <key>DefaultObjectTexture</key>
+ <key>DefaultObjectNormalTexture</key>
+ <map>
+ <key>Comment</key>
+ <string>Texture used as 'Default' in texture picker for normal map. (UUID texture reference)</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>String</string>
+ <key>Value</key>
+ <string>85f28839-7a1c-b4e3-d71d-967792970a7b</string>
+ </map>
+ <key>DefaultObjectSpecularTexture</key>
+ <map>
+ <key>Comment</key>
+ <string>Texture used as 'Default' in texture picker for specular map. (UUID texture reference)</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>String</string>
+ <key>Value</key>
+ <string>87e0e8f7-8729-1ea8-cfc9-8915773009db</string>
+ </map>
+ <key>DefaultObjectTexture</key>
<map>
<key>Comment</key>
<string>Texture used as 'Default' in texture picker. (UUID texture reference)</string>
@@ -2775,6 +3049,17 @@
<key>Value</key>
<integer>0</integer>
</map>
+ <key>DisableCrashLogger</key>
+ <map>
+ <key>Comment</key>
+ <string>Do not send crash report to Linden server</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>DisableMouseWarp</key>
<map>
<key>Comment</key>
@@ -3182,17 +3467,6 @@
<key>Value</key>
<integer>1</integer>
</map>
- <key>EnableTextureAtlas</key>
- <map>
- <key>Comment</key>
- <string>Whether to use texture atlas or not</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>0</integer>
- </map>
<key>EnableUIHints</key>
<map>
<key>Comment</key>
@@ -3259,6 +3533,17 @@
<key>Value</key>
<string>http://events.secondlife.com/viewer/embed/event/</string>
</map>
+ <key>FastCacheFetchEnabled</key>
+ <map>
+ <key>Comment</key>
+ <string>Enable texture fast cache fetching if set</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <string>1</string>
+ </map>
<key>FeatureManagerHTTPTable</key>
<map>
<key>Comment</key>
@@ -3281,16 +3566,27 @@
<key>Value</key>
<real>10.0</real>
</map>
- <key>FilterItemsPerFrame</key>
+ <key>FilterItemsMaxTimePerFrameVisible</key>
<map>
- <key>Comment</key>
- <string>Maximum number of inventory items to match against search filter every frame (lower to increase framerate while searching, higher to improve search speed)</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>500</integer>
+ <key>Comment</key>
+ <string>Max time devoted to items filtering per frame for visible inventory listings (in milliseconds)</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>10</integer>
+ </map>
+ <key>FilterItemsMaxTimePerFrameUnvisible</key>
+ <map>
+ <key>Comment</key>
+ <string>Max time devoted to items filtering per frame for non visible inventory listings (in milliseconds)</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>1</integer>
</map>
<key>FindLandArea</key>
<map>
@@ -4029,17 +4325,6 @@
<key>Value</key>
<integer>305</integer>
</map>
- <key>HelpUseLocal</key>
- <map>
- <key>Comment</key>
- <string>If set, always use this for help: skins/default/html/[LANGUAGE]/help-offline/index.html</string>
- <key>Persist</key>
- <integer>0</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>0</integer>
- </map>
<key>HelpURLFormat</key>
<map>
<key>Comment</key>
@@ -4172,6 +4457,17 @@
<key>Value</key>
<integer>1</integer>
</map>
+ <key>IMShowContentPanel</key>
+ <map>
+ <key>Comment</key>
+ <string>Show Toolbar and Body Panels</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
<key>IgnoreAllNotifications</key>
<map>
<key>Comment</key>
@@ -4214,7 +4510,7 @@
<key>Type</key>
<string>F32</string>
<key>Value</key>
- <real>0.65</real>
+ <real>0.95</real>
</map>
<key>InBandwidth</key>
<map>
@@ -4271,6 +4567,28 @@
<key>Value</key>
<real>1.0</real>
</map>
+ <key>InventoryDebugSimulateOpFailureRate</key>
+ <map>
+ <key>Comment</key>
+ <string>Rate at which we simulate failures of copy/link requests in some operations</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>0.0</real>
+ </map>
+ <key>InventoryDebugSimulateLateOpRate</key>
+ <map>
+ <key>Comment</key>
+ <string>Rate at which we simulate late-completing copy/link requests in some operations</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>0.0</real>
+ </map>
<key>InventoryDisplayInbox</key>
<map>
<key>Comment</key>
@@ -4293,6 +4611,17 @@
<key>Value</key>
<integer>0</integer>
</map>
+ <key>InventoryInboxToggleState</key>
+ <map>
+ <key>Comment</key>
+ <string>Stores the open/closed state of inventory Received items panel</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>InventoryLinking</key>
<map>
<key>Comment</key>
@@ -4590,6 +4919,27 @@
<key>Value</key>
<integer>0</integer>
</map>
+ <key>LeapCommand</key>
+ <map>
+ <key>Comment</key>
+ <string>Zero or more command lines to run LLSD Event API Plugin programs.</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>LLSD</string>
+ <key>Value</key>
+ <array />
+ </map>
+ <key>LeapPlaybackEventsCommand</key>
+ <map>
+ <key>Comment</key>
+ <string>Command line to use leap to launch playback of event recordings</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>LLSD</string>
+ <key>Value</key>
+ </map>
<key>LSLFindCaseInsensitivity</key>
<map>
<key>Comment</key>
@@ -4965,6 +5315,28 @@
<key>Value</key>
<integer>0</integer>
</map>
+ <key>LogMetrics</key>
+ <map>
+ <key>Comment</key>
+ <string>Log viewer metrics</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>String</string>
+ <key>Value</key>
+ <string/>
+ </map>
+ <key>LogPerformance</key>
+ <map>
+ <key>Comment</key>
+ <string>Log performance analysis for a particular viewer run</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>LogTextureNetworkTraffic</key>
<map>
<key>Comment</key>
@@ -4990,7 +5362,7 @@
<key>LoginLocation</key>
<map>
<key>Comment</key>
- <string>Login location ('last', 'home')</string>
+ <string>Default Login location ('last', 'home') preference</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -5135,7 +5507,7 @@
<key>Comment</key>
<string>Center the focal point of the minimap.</string>
<key>Persist</key>
- <integer>0</integer>
+ <integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
@@ -5559,6 +5931,17 @@
<key>Value</key>
<real>1.6</real>
</map>
+ <key>MaxPersistentNotifications</key>
+ <map>
+ <key>Comment</key>
+ <string>Maximum amount of persistent notifications</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <real>250</real>
+ </map>
<key>MaxSelectDistance</key>
<map>
<key>Comment</key>
@@ -5722,7 +6105,7 @@
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
- <integer>1</integer>
+ <integer>0</integer>
</map>
<key>MemoryPrivatePoolSize</key>
<map>
@@ -6057,7 +6440,7 @@
<key>NextLoginLocation</key>
<map>
<key>Comment</key>
- <string>Location to log into by default.</string>
+ <string>Location to log into for this session - set from command line or the login panel, cleared following a successfull login.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -6109,6 +6492,17 @@
<key>Value</key>
<integer>0</integer>
</map>
+ <key>NoQuickTime</key>
+ <map>
+ <key>Comment</key>
+ <string>Disable QuickTime for a particular viewer run</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>NoVerifySSLCert</key>
<map>
<key>Comment</key>
@@ -6142,6 +6536,90 @@
<key>Value</key>
<integer>305</integer>
</map>
+ <key>NotificationConferenceIMOptions</key>
+ <map>
+ <key>Comment</key>
+ <string>
+ Specifies how the UI responds to Conference IM Notifications.
+ Allowed values: [openconversations,toast,flash,noaction]
+ </string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>String</string>
+ <key>Value</key>
+ <string>toast</string>
+ </map>
+ <key>NotificationFriendIMOptions</key>
+ <map>
+ <key>Comment</key>
+ <string>
+ Specifies how the UI responds to Friend IM Notifications.
+ Allowed values: [openconversations,toast,flash,noaction]
+ </string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>String</string>
+ <key>Value</key>
+ <string>toast</string>
+ </map>
+ <key>NotificationGroupChatOptions</key>
+ <map>
+ <key>Comment</key>
+ <string>
+ Specifies how the UI responds to Group Chat Notifications.
+ Allowed values: [openconversations,toast,flash,noaction]
+ </string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>String</string>
+ <key>Value</key>
+ <string>toast</string>
+ </map>
+ <key>NotificationNearbyChatOptions</key>
+ <map>
+ <key>Comment</key>
+ <string>
+ Specifies how the UI responds to Nearby Chat Notifications.
+ Allowed values: [openconversations,toast,flash,noaction]
+ </string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>String</string>
+ <key>Value</key>
+ <string>toast</string>
+ </map>
+ <key>NotificationNonFriendIMOptions</key>
+ <map>
+ <key>Comment</key>
+ <string>
+ Specifies how the UI responds to Non Friend IM Notifications.
+ Allowed values: [openconversations,toast,flash,noaction]
+ </string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>String</string>
+ <key>Value</key>
+ <string>toast</string>
+ </map>
+ <key>NotificationObjectIMOptions</key>
+ <map>
+ <key>Comment</key>
+ <string>
+ Specifies how the UI responds to Object IM Notifications.
+ Allowed values: [openconversations,toast,flash,noaction]
+ </string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>String</string>
+ <key>Value</key>
+ <string>toast</string>
+ </map>
<key>NotificationToastLifeTime</key>
<map>
<key>Comment</key>
@@ -6312,17 +6790,6 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>NumpadControl</key>
- <map>
- <key>Comment</key>
- <string>How numpad keys control your avatar. 0 = Like the normal arrow keys, 1 = Numpad moves avatar when numlock is off, 2 = Numpad moves avatar regardless of numlock (use this if you have no numlock)</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>0</integer>
- </map>
<key>ObjectCacheEnabled</key>
<map>
<key>Comment</key>
@@ -6658,6 +7125,17 @@
<key>Value</key>
<real>90.0</real>
</map>
+ <key>PlayChatAnim</key>
+ <map>
+ <key>Comment</key>
+ <string>Your avatar plays the chat animation whenever you say, shout or whisper something in nearby chat</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
<key>PlayTypingAnim</key>
<map>
<key>Comment</key>
@@ -6669,6 +7147,116 @@
<key>Value</key>
<integer>1</integer>
</map>
+ <key>PlaySoundIncomingVoiceCall</key>
+ <map>
+ <key>Comment</key>
+ <string>Plays a sound when have an incoming voice call.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>PlaySoundInventoryOffer</key>
+ <map>
+ <key>Comment</key>
+ <string>Plays a sound when have an inventory offer.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>PlaySoundFriendIM</key>
+ <map>
+ <key>Comment</key>
+ <string>Plays a sound when friend's IM received.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>PlaySoundNonFriendIM</key>
+ <map>
+ <key>Comment</key>
+ <string>Plays a sound when non-friend's IM received.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>PlaySoundConferenceIM</key>
+ <map>
+ <key>Comment</key>
+ <string>Plays a sound when conference IM received.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>PlaySoundGroupChatIM</key>
+ <map>
+ <key>Comment</key>
+ <string>Plays a sound when group chat IM received.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>PlaySoundNearbyChatIM</key>
+ <map>
+ <key>Comment</key>
+ <string>Plays a sound when nearby chat IM received.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>PlaySoundObjectIM</key>
+ <map>
+ <key>Comment</key>
+ <string>Plays a sound when IM fom an object received.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>PlaySoundNewConversation</key>
+ <map>
+ <key>Comment</key>
+ <string>Plays a sound when have a new conversation.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>PlaySoundTeleportOffer</key>
+ <map>
+ <key>Comment</key>
+ <string>Plays a sound when have a teleport offer.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>PluginAttachDebuggerToPlugins</key>
<map>
<key>Comment</key>
@@ -7120,7 +7708,7 @@
<key>QAModeEventHostPort</key>
<map>
<key>Comment</key>
- <string>Port on which lleventhost should listen</string>
+ <string>DEPRECATED: Port on which lleventhost should listen</string>
<key>Persist</key>
<integer>0</integer>
<key>Type</key>
@@ -7139,6 +7727,17 @@
<key>Value</key>
<integer>-1</integer>
</map>
+ <key>QAModeMetrics</key>
+ <map>
+ <key>Comment</key>
+ <string>"Enables QA features (logging, faster cycling) for metrics collector"</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>QuietSnapshotsToDisk</key>
<map>
<key>Comment</key>
@@ -7219,7 +7818,7 @@
<key>WebContentWindowLimit</key>
<map>
<key>Comment</key>
- <string>Maximum number of web brower windows that can be open at once in the Web content floater (0 for no limit)</string>
+ <string>Maximum number of web browser windows that can be open at once in the Web content floater (0 for no limit)</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -7348,7 +7947,7 @@
<key>Type</key>
<string>S32</string>
<key>Value</key>
- <integer>4</integer>
+ <integer>3</integer>
</map>
<key>OctreeAlphaDistanceFactor</key>
@@ -7587,6 +8186,17 @@
<key>Value</key>
<integer>1</integer>
</map>
+ <key>RenderCompressTextures</key>
+ <map>
+ <key>Comment</key>
+ <string>Enable texture compression on OpenGL 3.0 and later implementations (EXPERIMENTAL, requires restart)</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>RenderPerformanceTest</key>
<map>
<key>Comment</key>
@@ -8013,7 +8623,7 @@
<key>Type</key>
<string>F32</string>
<key>Value</key>
- <real>0</real>
+ <real>-0.007</real>
</map>
<key>RenderShadowOffsetError</key>
<map>
@@ -8027,6 +8637,18 @@
<real>0</real>
</map>
+ <key>RenderDepthPrePass</key>
+ <map>
+ <key>Comment</key>
+ <string>EXPERIMENTAL: Prime the depth buffer with simple prim geometry before rendering with textures.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+
<key>RenderDepthOfField</key>
<map>
<key>Comment</key>
@@ -8039,6 +8661,18 @@
<integer>0</integer>
</map>
+ <key>RenderDepthOfFieldInEditMode</key>
+ <map>
+ <key>Comment</key>
+ <string>Whether to use depth of field effect when in edit mode</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+
<key>CameraDoFResScale</key>
<map>
<key>Comment</key>
@@ -8054,7 +8688,7 @@
<key>RenderSpotLightsInNondeferred</key>
<map>
<key>Comment</key>
- <string>Whether to support projectors as spotlights when Lighting and Shadows is disabled</string>
+ <string>Whether to support projectors as spotlights when Advanced Lighting Model is disabled</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -8097,7 +8731,6 @@
<key>Value</key>
<real>1.0</real>
</map>
-
<key>RenderDeferredTreeShadowBias</key>
<map>
<key>Comment</key>
@@ -8186,6 +8819,18 @@
</array>
</map>
+ <key>RenderSpecularPrecision</key>
+ <map>
+ <key>Comment</key>
+ <string>Force 32-bit floating point LUT</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>U32</string>
+ <key>Value</key>
+ <real>0</real>
+ </map>
+
<key>RenderSpecularResX</key>
<map>
<key>Comment</key>
@@ -8195,7 +8840,7 @@
<key>Type</key>
<string>U32</string>
<key>Value</key>
- <real>512</real>
+ <real>1024</real>
</map>
<key>RenderSpecularResY</key>
@@ -8207,7 +8852,7 @@
<key>Type</key>
<string>U32</string>
<key>Value</key>
- <real>128</real>
+ <real>256</real>
</map>
<key>RenderSpecularExponent</key>
@@ -8225,7 +8870,7 @@
<key>RenderDeferred</key>
<map>
<key>Comment</key>
- <string>Use deferred rendering pipeline.</string>
+ <string>Use deferred rendering pipeline (Advanced Lighting Model).</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -8413,7 +9058,7 @@
<key>RenderAutoMaskAlphaNonDeferred</key>
<map>
<key>Comment</key>
- <string>Use alpha masks where appropriate, in the non-deferred (non-'Lighting and Shadows') graphics mode</string>
+ <string>Use alpha masks where appropriate when not using the Advanced Lighting Model</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -8424,7 +9069,7 @@
<key>RenderAutoMaskAlphaDeferred</key>
<map>
<key>Comment</key>
- <string>Use alpha masks where appropriate, in the deferred ('Lighting and Shadows') graphics mode</string>
+ <string>Use alpha masks where appropriate in the Advanced Lighting Model</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -8476,6 +9121,17 @@
<key>Value</key>
<real>1.0</real>
</map>
+ <key>RenderDeferredDisplayGamma</key>
+ <map>
+ <key>Comment</key>
+ <string>Gamma ramp exponent for final correction before display gamma.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>2.2</real>
+ </map>
<key>RenderGLCoreProfile</key>
<map>
<key>Comment</key>
@@ -8616,6 +9272,28 @@
<key>Value</key>
<integer>1</integer>
</map>
+ <key>DisableAllRenderTypes</key>
+ <map>
+ <key>Comment</key>
+ <string>Disables all rendering types.</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>DisableAllRenderFeatures</key>
+ <map>
+ <key>Comment</key>
+ <string>Disables all rendering features.</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>RenderHUDInSnapshot</key>
<map>
<key>Comment</key>
@@ -9057,10 +9735,22 @@
<key>Value</key>
<integer>1</integer>
</map>
+
<key>RenderAutoMuteByteLimit</key>
<map>
<key>Comment</key>
- <string>Maximum bytes of attachments before an avatar is automatically visually muted (0 for no limit).</string>
+ <string>Maximum bytes of attachments before an avatar is rendered as a simple impostor (0 for no limit).</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>U32</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>RenderAutoMuteRenderWeightLimit</key>
+ <map>
+ <key>Comment</key>
+ <string>Maximum render weight before an avatar is rendered as a simple impostor (0 to not use this limit).</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -9071,7 +9761,7 @@
<key>RenderAutoMuteSurfaceAreaLimit</key>
<map>
<key>Comment</key>
- <string>Maximum surface area of attachments before an avatar is automatically visually muted (0 for no limit).</string>
+ <string>Maximum surface area of attachments before an avatar is rendered as a simple impostor (0 to not use this limit).</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -9079,28 +9769,40 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>RenderUseShaderLOD</key>
- <map>
- <key>Comment</key>
- <string>Whether we want to have different shaders for LOD</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
- <key>RenderUseShaderNearParticles</key>
- <map>
- <key>Comment</key>
- <string>Whether we want to use shaders on near particles</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>0</integer>
- </map>
+ <key>RenderAutoMuteFunctions</key>
+ <map>
+ <key>Comment</key>
+ <string>Developing feature to render some avatars using simple impostors or colored silhouettes. (Set to 7 for all functionality)</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>U32</string>
+ <key>Value</key>
+ <real>0</real>
+ </map>
+ <key>RenderAutoMuteLogging</key>
+ <map>
+ <key>Comment</key>
+ <string>Show extra information in viewer logs about avatar rendering costs</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>RenderAutoHideSurfaceAreaLimit</key>
+ <map>
+ <key>Comment</key>
+ <string>Maximum surface area of a set of proximal objects inworld before automatically hiding geometry to prevent system overload.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+
<key>RenderVBOEnable</key>
<map>
<key>Comment</key>
@@ -9115,7 +9817,7 @@
<key>RenderUseVAO</key>
<map>
<key>Comment</key>
- <string>Use GL Vertex Array Objects</string>
+ <string>[EXPERIMENTAL] Use GL Vertex Array Objects.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -9123,7 +9825,19 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>RenderVBOMappingDisable</key>
+ <key>RenderUseTransformFeedback</key>
+ <map>
+ <key>Comment</key>
+ <string>[EXPERIMENTAL] Use transform feedback shaders for LoD updates</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+
+ <key>RenderVBOMappingDisable</key>
<map>
<key>Comment</key>
<string>Disable VBO glMapBufferARB</string>
@@ -9178,6 +9892,17 @@
<key>Value</key>
<integer>1</integer>
</map>
+ <key>RenderWaterMaterials</key>
+ <map>
+ <key>Comment</key>
+ <string>Water planar reflections include materials rendering.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>RenderWaterMipNormal</key>
<map>
<key>Comment</key>
@@ -9211,6 +9936,28 @@
<key>Value</key>
<integer>1</integer>
</map>
+ <key>ReplaySession</key>
+ <map>
+ <key>Comment</key>
+ <string>Request replay of previously-recorded pilot file</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>RevokePermsOnStopAnimation</key>
+ <map>
+ <key>Comment</key>
+ <string>Clear animation permssions when choosing "Stop Animating Me"</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
<key>RotateRight</key>
<map>
<key>Comment</key>
@@ -9663,6 +10410,17 @@
<key>Value</key>
<integer>0</integer>
</map>
+ <key>ShowEventRecorderMenuItems</key>
+ <map>
+ <key>Comment</key>
+ <string>Whether or not Event Recorder menu choices - Start / Stop event recording should appear in the (currently) Develop menu</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>ShowGestureButton</key>
<map>
<key>Comment</key>
@@ -9732,7 +10490,7 @@
<key>ShowScriptErrorsLocation</key>
<map>
<key>Comment</key>
- <string>Show script error in chat or window</string>
+ <string>Show script error in chat (0) or window (1).</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -9916,6 +10674,39 @@
<key>Value</key>
<integer>2</integer>
</map>
+ <key>BlockPeopleSortOrder</key>
+ <map>
+ <key>Comment</key>
+ <string>Specifies sort order for recent people (0 = by name, 1 = by type)</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>U32</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>CallLogSortOrder</key>
+ <map>
+ <key>Comment</key>
+ <string>Specifies sort order for Call Log (0 = by name, 1 = by date)</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>U32</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>SortFriendsFirst</key>
+ <map>
+ <key>Comment</key>
+ <string>Specifies whether friends will be sorted first in Call Log</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
<key>ShowPGSearchAll</key>
<map>
<key>Comment</key>
@@ -10609,6 +11400,39 @@
<key>Value</key>
<real>20.0</real>
</map>
+ <key>TexelPixelRatio</key>
+ <map>
+ <key>Comment</key>
+ <string>texel pixel ratio = texel / pixel</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>1.0</real>
+ </map>
+ <key>TextureCameraMotionThreshold</key>
+ <map>
+ <key>Comment</key>
+ <string>If the overall motion is lower than this value, textures will be loaded faster</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>0.2</real>
+ </map>
+ <key>TextureCameraMotionBoost</key>
+ <map>
+ <key>Comment</key>
+ <string>Progressive discard level decrement when the camera is still</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>3</integer>
+ </map>
<key>TextureDecodeDisabled</key>
<map>
<key>Comment</key>
@@ -10642,6 +11466,105 @@
<key>Value</key>
<integer>0</integer>
</map>
+ <key>TextureFetchConcurrency</key>
+ <map>
+ <key>Comment</key>
+ <string>Maximum number of HTTP connections used for texture fetches</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>U32</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>TextureFetchDebuggerEnabled</key>
+ <map>
+ <key>Comment</key>
+ <string>Enable the texture fetching debugger if set</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>TextureFetchSource</key>
+ <map>
+ <key>Comment</key>
+ <string>Debug use: Source to fetch textures</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>TextureFetchUpdateHighPriority</key>
+ <map>
+ <key>Comment</key>
+ <string>Number of high priority textures to update per frame</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>32</integer>
+ </map>
+ <key>TextureFetchUpdateMaxMediumPriority</key>
+ <map>
+ <key>Comment</key>
+ <string>Maximum number of medium priority textures to update per frame</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>256</integer>
+ </map>
+ <key>TextureFetchUpdateMinMediumPriority</key>
+ <map>
+ <key>Comment</key>
+ <string>Minimum number of medium priority textures to update per frame</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>32</integer>
+ </map>
+ <key>TextureFetchUpdatePriorityThreshold</key>
+ <map>
+ <key>Comment</key>
+ <string>Threshold under which textures will be considered too low priority and skipped for update</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>0.0</real>
+ </map>
+ <key>TextureFetchUpdateSkipLowPriority</key>
+ <map>
+ <key>Comment</key>
+ <string>Flag indicating if we want to skip textures with too low of a priority</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>TextureFetchUpdatePriorities</key>
+ <map>
+ <key>Comment</key>
+ <string>Number of priority texture to update per frame</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>32</integer>
+ </map>
<key>TextureLoadFullRes</key>
<map>
<key>Comment</key>
@@ -10664,6 +11587,17 @@
<key>Value</key>
<integer>0</integer>
</map>
+ <key>TextureNewByteRange</key>
+ <map>
+ <key>Comment</key>
+ <string>Use the new more accurate byte range computation for j2c discard levels</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
<key>TexturePickerShowFolders</key>
<map>
<key>Comment</key>
@@ -10686,6 +11620,17 @@
<key>Value</key>
<integer>2</integer>
</map>
+ <key>TextureReverseByteRange</key>
+ <map>
+ <key>Comment</key>
+ <string>Minimal percent of the optimal byte range allowed to render a given discard level</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>50</integer>
+ </map>
<key>ThrottleBandwidthKBPS</key>
<map>
<key>Comment</key>
@@ -10729,7 +11674,8 @@
<string>F32</string>
<key>Value</key>
<real>0.1</real>
- </map> <key>ToolTipFadeTime</key>
+ </map>
+ <key>ToolTipFadeTime</key>
<map>
<key>Comment</key>
<string>Seconds over which tooltip fades away</string>
@@ -11884,16 +12830,16 @@
<key>Value</key>
<string>update</string>
</map>
- <key>UpdaterServiceProtocolVersion</key>
+ <key>UpdaterWillingToTest</key>
<map>
<key>Comment</key>
- <string>The update protocol version to use.</string>
+ <string>Whether or not the updater should offer test candidate upgrades.</string>
<key>Persist</key>
- <integer>0</integer>
+ <integer>1</integer>
<key>Type</key>
- <string>String</string>
+ <string>Boolean</string>
<key>Value</key>
- <string>v1.0</string>
+ <string>1</string>
</map>
<key>UploadBakedTexOld</key>
<map>
@@ -12093,6 +13039,17 @@
<key>Value</key>
<integer>1</integer>
</map>
+ <key>RenderSynchronousOcclusion</key>
+ <map>
+ <key>Comment</key>
+ <string>Don't let occlusion queries get more than one frame behind (block until they complete).</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
<key>RenderDelayVBUpdate</key>
<map>
<key>Comment</key>
@@ -12104,16 +13061,27 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>SpeakerParticipantDefaultOrder</key>
+ <key>SocialPhotoResolution</key>
<map>
<key>Comment</key>
- <string>Order for displaying speakers in voice controls. 0 = alphabetical. 1 = recent.</string>
+ <string>Default resolution when sharing photo using the social floater</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
- <string>U32</string>
+ <string>String</string>
<key>Value</key>
+ <string>[i800,i600]</string>
+ </map>
+ <key>sourceid</key>
+ <map>
+ <key>Comment</key>
+ <string>Identify referring agency to Linden web servers</string>
+ <key>Persist</key>
<integer>1</integer>
+ <key>Type</key>
+ <string>String</string>
+ <key>Value</key>
+ <string />
</map>
<key>SpeakerParticipantRemoveDelay</key>
<map>
@@ -12126,6 +13094,28 @@
<key>Value</key>
<real>10.0</real>
</map>
+ <key>SpellCheck</key>
+ <map>
+ <key>Comment</key>
+ <string>Enable spellchecking on line and text editors</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>SpellCheckDictionary</key>
+ <map>
+ <key>Comment</key>
+ <string>Current primary and secondary dictionaries used for spell checking</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>String</string>
+ <key>Value</key>
+ <string>English (United States),Second Life Glossary</string>
+ </map>
<key>UseNewWalkRun</key>
<map>
<key>Comment</key>
@@ -12137,6 +13127,17 @@
<key>Value</key>
<integer>1</integer>
</map>
+ <key>UsePeopleAPI</key>
+ <map>
+ <key>Comment</key>
+ <string>Use the people API cap for avatar name fetching, use old legacy protocol if false. Requires restart.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
<key>UseStartScreen</key>
<map>
<key>Comment</key>
@@ -12184,12 +13185,13 @@
<key>UserLoginInfo</key>
<map>
<key>Comment</key>
- <string>Users loging data.</string>
+ <string>User login data.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>LLSD</string>
<key>Value</key>
+ <string/>
</map>
<key>VFSOldSize</key>
<map>
@@ -12288,7 +13290,7 @@
<key>Type</key>
<string>String</string>
<key>Value</key>
- <string>-1</string>
+ <string>0</string>
</map>
<key>VivoxDebugSIPURIHostName</key>
<map>
@@ -12631,10 +13633,10 @@
<key>Value</key>
<real>50.0</real>
</map>
- <key>WellIconFlashCount</key>
+ <key>FlashCount</key>
<map>
<key>Comment</key>
- <string>Number of flashes of IM Well and Notification Well icons after which flashing buttons stay lit up. Requires restart.</string>
+ <string>Number of flashes of item. Requires restart.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -12642,16 +13644,16 @@
<key>Value</key>
<integer>3</integer>
</map>
- <key>WellIconFlashPeriod</key>
+ <key>FlashPeriod</key>
<map>
<key>Comment</key>
- <string>Period at which IM Well and Notification Well icons flash (seconds). Requires restart.</string>
+ <string>Period at which item flash (seconds). Requires restart.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>F32</string>
<key>Value</key>
- <real>0.25</real>
+ <real>0.5</real>
</map>
<key>WindLightUseAtmosShaders</key>
<map>
@@ -12807,6 +13809,28 @@
<key>Value</key>
<integer>-1</integer>
</map>
+ <key>MaxFPS</key>
+ <map>
+ <key>Comment</key>
+ <string>Yield some time to the local host if we reach a threshold framerate.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>-1.0</real>
+ </map>
+ <key>ForcePeriodicRenderingTime</key>
+ <map>
+ <key>Comment</key>
+ <string>Periodically enable all rendering masks for a single frame.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>-1.0</real>
+ </map>
<key>ZoomDirect</key>
<map>
<key>Comment</key>
@@ -13791,5 +14815,404 @@
<key>Value</key>
<integer>0</integer>
</map>
+ <key>PathfindingRetrieveNeighboringRegion</key>
+ <map>
+ <key>Comment</key>
+ <string>Download a neighboring region when visualizing a pathfinding navmesh (default val 99 means do not download neighbors).</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>U32</string>
+ <key>Value</key>
+ <integer>99</integer>
+ </map>
+ <key>PathfindingNavMeshClear</key>
+ <map>
+ <key>Comment</key>
+ <string>Background color when displaying pathfinding navmesh.</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>Color4</string>
+ <key>Value</key>
+ <array>
+ <real>0</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1.0</real>
+ </array>
+ </map>
+ <key>PathfindingWalkable</key>
+ <map>
+ <key>Comment</key>
+ <string>Color of walkable objects when displaying pathfinding navmesh object types.</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>Color4</string>
+ <key>Value</key>
+ <array>
+ <real>0.45490196078431372549019607843137</real>
+ <real>0.93333333333333333333333333333333</real>
+ <real>0.38823529411764705882352941176471</real>
+ <real>1.0</real>
+ </array>
+ </map>
+ <key>PathfindingObstacle</key>
+ <map>
+ <key>Comment</key>
+ <string>Color of static obstacle objects when displaying pathfinding navmesh object types.</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>Color4</string>
+ <key>Value</key>
+ <array>
+ <real>1.0</real>
+ <real>0.0</real>
+ <real>0.0</real>
+ <real>1.0</real>
+ </array>
+ </map>
+ <key>PathfindingMaterial</key>
+ <map>
+ <key>Comment</key>
+ <string>Color of material volumes when displaying pathfinding navmesh object types.</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>Color4</string>
+ <key>Value</key>
+ <array>
+ <real>0.5</real>
+ <real>0.0</real>
+ <real>1.0</real>
+ <real>0.3</real>
+ </array>
+ </map>
+ <key>PathfindingExclusion</key>
+ <map>
+ <key>Comment</key>
+ <string>Color of exclusion volumes when displaying pathfinding navmesh object types.</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>Color4</string>
+ <key>Value</key>
+ <array>
+ <real>1.0</real>
+ <real>1.0</real>
+ <real>0.0</real>
+ <real>0.3</real>
+ </array>
+ </map>
+ <key>PathfindingConnectedEdge</key>
+ <map>
+ <key>Comment</key>
+ <string>Color of a connected (crossable) edge when displaying pathfinding navmesh.</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>Color4</string>
+ <key>Value</key>
+ <array>
+ <real>0.86</real>
+ <real>0.86</real>
+ <real>0.86</real>
+ <real>1.0</real>
+ </array>
+ </map>
+ <key>PathfindingBoundaryEdge</key>
+ <map>
+ <key>Comment</key>
+ <string>Color of a boundary (non-crossable) edge when displaying pathfinding navmesh.</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>Color4</string>
+ <key>Value</key>
+ <array>
+ <real>1.0</real>
+ <real>0.0</real>
+ <real>0.0</real>
+ <real>1.0</real>
+ </array>
+ </map>
+ <key>PathfindingHeatColorBase</key>
+ <map>
+ <key>Comment</key>
+ <string>Color of the least walkable value when displaying the pathfinding navmesh as a heatmap.</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>Color4</string>
+ <key>Value</key>
+ <array>
+ <real>1.0</real>
+ <real>0.0</real>
+ <real>0.0</real>
+ <real>1.0</real>
+ </array>
+ </map>
+ <key>PathfindingHeatColorMax</key>
+ <map>
+ <key>Comment</key>
+ <string>Color of the most walkable value when displaying the pathfinding navmesh as a heatmap.</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>Color4</string>
+ <key>Value</key>
+ <array>
+ <real>1.0</real>
+ <real>1.0</real>
+ <real>1.0</real>
+ <real>1.0</real>
+ </array>
+ </map>
+ <key>PathfindingFaceColor</key>
+ <map>
+ <key>Comment</key>
+ <string>Color of the faces when displaying the default view of the pathfinding navmesh.</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>Color4</string>
+ <key>Value</key>
+ <array>
+ <real>1.0</real>
+ <real>1.0</real>
+ <real>1.0</real>
+ <real>1.0</real>
+ </array>
+ </map>
+ <key>PathfindingTestPathValidEndColor</key>
+ <map>
+ <key>Comment</key>
+ <string>Color of the pathfinding test-pathing tool end-point when the path is valid.</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>Color4</string>
+ <key>Value</key>
+ <array>
+ <real>0.78</real>
+ <real>0.47</real>
+ <real>0.0</real>
+ <real>1.0</real>
+ </array>
+ </map>
+ <key>PathfindingTestPathInvalidEndColor</key>
+ <map>
+ <key>Comment</key>
+ <string>Color of the pathfinding test-pathing tool end-point when the path is invalid.</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>Color4</string>
+ <key>Value</key>
+ <array>
+ <real>1.0</real>
+ <real>0.0</real>
+ <real>1.0</real>
+ <real>1.0</real>
+ </array>
+ </map>
+ <key>PathfindingTestPathColor</key>
+ <map>
+ <key>Comment</key>
+ <string>Color of the pathfinding test-path when the path is valid.</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>Color4</string>
+ <key>Value</key>
+ <array>
+ <real>1.0</real>
+ <real>0.59</real>
+ <real>0.0</real>
+ <real>0.9</real>
+ </array>
+ </map>
+ <key>PathfindingAmbiance</key>
+ <map>
+ <key>Comment</key>
+ <string>Ambiance of lit pathfinding navmesh displays.</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>0.5</real>
+ </map>
+
+ <key>PathfindingXRayTint</key>
+ <map>
+ <key>Comment</key>
+ <string>Amount to darken/lighten x-ray lines in pathfinding display.</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>0.8</real>
+ </map>
+
+ <key>PathfindingXRayOpacity</key>
+ <map>
+ <key>Comment</key>
+ <string>Opacity of xray lines in pathfinding display.</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>0.25</real>
+ </map>
+
+ <key>PathfindingXRayWireframe</key>
+ <map>
+ <key>Comment</key>
+ <string>Render pathfinding navmesh xray as a wireframe.</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+
+ <key>PathfindingLineWidth</key>
+ <map>
+ <key>Comment</key>
+ <string>Width of volume outlines in pathfinding navmesh display.</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>2.0</real>
+ </map>
+
+ <key>PathfindingLineOffset</key>
+ <map>
+ <key>Comment</key>
+ <string>Depth offset of volume outlines in pathfinding display.</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>2.3</real>
+ </map>
+
+ <key>PathfindingWaterColor</key>
+ <map>
+ <key>Comment</key>
+ <string>Color of water plane when displaying pathfinding navmesh.</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>Color4</string>
+ <key>Value</key>
+ <array>
+ <real>0.0</real>
+ <real>0.0</real>
+ <real>1.0</real>
+ <real>1.0</real>
+ </array>
+ </map>
+
+ <key>HideUIControls</key>
+ <map>
+ <key>Comment</key>
+ <string>Hide all menu items and buttons</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+
+ <key>SimulateFBOFailure</key>
+ <map>
+ <key>Comment</key>
+ <string>[DEBUG] Make allocateScreenBuffer return false. Used to test error handling.</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>DisablePrecacheDelayAfterTeleporting</key>
+ <map>
+ <key>Comment</key>
+ <string>Disables the artificial delay in the viewer that precaches some incoming assets</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>FMODExProfilerEnable</key>
+ <map>
+ <key>Comment</key>
+ <string>Enable profiler tool if using FMOD Ex</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>FMODExDecodeBufferSize</key>
+ <map>
+ <key>Comment</key>
+ <string>Sets the streaming decode buffer size (in milliseconds)</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>U32</string>
+ <key>Value</key>
+ <integer>1000</integer>
+ </map>
+ <key>FMODExStreamBufferSize</key>
+ <map>
+ <key>Comment</key>
+ <string>Sets the streaming buffer size (in milliseconds)</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>U32</string>
+ <key>Value</key>
+ <integer>7000</integer>
+ </map>
+ <key>DisablePrecacheDelayAfterTeleporting</key>
+ <map>
+ <key>Comment</key>
+ <string>Disables the artificial delay in the viewer that precaches some incoming assets</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+
+ <key>VersionChannelName</key>
+ <map>
+ <key>Comment</key>
+ <string>Version information generated by running the viewer</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>String</string>
+ <key>Value</key>
+ <string />
+ </map>
</map>
</llsd>
+
diff --git a/indra/newview/app_settings/settings_crash_behavior.xml b/indra/newview/app_settings/settings_crash_behavior.xml
index 97651ff4ca..97651ff4ca 100644..100755
--- a/indra/newview/app_settings/settings_crash_behavior.xml
+++ b/indra/newview/app_settings/settings_crash_behavior.xml
diff --git a/indra/newview/app_settings/settings_files.xml b/indra/newview/app_settings/settings_files.xml
index bfc09286e3..4a9e522a96 100644..100755
--- a/indra/newview/app_settings/settings_files.xml
+++ b/indra/newview/app_settings/settings_files.xml
@@ -4,6 +4,9 @@
<file name="Global"
file_name="settings.xml"
required="true"/>
+ <file name="Global"
+ file_name="settings_install.xml"
+ required="false"/>
<file name="PerAccount"
file_name="settings_per_account.xml"
required="true"/>
diff --git a/indra/newview/app_settings/settings_minimal.xml b/indra/newview/app_settings/settings_minimal.xml
index 01a70f2671..e660c1a33b 100644..100755
--- a/indra/newview/app_settings/settings_minimal.xml
+++ b/indra/newview/app_settings/settings_minimal.xml
@@ -1 +1,4 @@
-<llsd/> \ No newline at end of file
+<?xml version="1.0"?>
+<llsd>
+ <undef/>
+</llsd>
diff --git a/indra/newview/app_settings/settings_per_account.xml b/indra/newview/app_settings/settings_per_account.xml
index 143126b334..500151c935 100644..100755
--- a/indra/newview/app_settings/settings_per_account.xml
+++ b/indra/newview/app_settings/settings_per_account.xml
@@ -1,9 +1,9 @@
<llsd>
<map>
- <key>BusyResponseChanged</key>
+ <key>DoNotDisturbResponseChanged</key>
<map>
<key>Comment</key>
- <string>Does user's busy mode message differ from default?</string>
+ <string>Does user's do not disturb mode message differ from default?</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -11,17 +11,83 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>BusyModeResponse</key>
+ <key>DoNotDisturbModeResponse</key>
<map>
<key>Comment</key>
- <string>Auto response to instant messages while in busy mode.</string>
+ <string>Auto response to instant messages while in do not disturb mode.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>String</string>
<key>Value</key>
- <string>The Resident you messaged is in &apos;busy mode&apos; which means they have requested not to be disturbed. Your message will still be shown in their IM panel for later viewing.</string>
+ <string>This resident has turned on &apos;Do Not Disturb&apos; and will see your message later.</string>
</map>
+ <key>ConversationsExpandMessagePaneFirst</key>
+ <map>
+ <key>Comment</key>
+ <string>Expand either messages or conversations list pane from Conversations compact mode.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>ConversationsListPaneCollapsed</key>
+ <map>
+ <key>Comment</key>
+ <string>Stores the expanded/collapsed state of the conversations list pane in Conversations floater.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>ConversationsListPaneWidth</key>
+ <map>
+ <key>Comment</key>
+ <string>Conversations floater list pane width.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>205</integer>
+ </map>
+ <key>ConversationsMessagePaneCollapsed</key>
+ <map>
+ <key>Comment</key>
+ <string>Stores the expanded/collapsed state of Conversations floater message pane.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>ConversationsMessagePaneWidth</key>
+ <map>
+ <key>Comment</key>
+ <string>Conversations floater message pane width.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>412</integer>
+ </map>
+ <key>ConversationsParticipantListCollapsed</key>
+ <map>
+ <key>Comment</key>
+ <string>Stores the expanded/collapsed state of Nearby chat participant list</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>true</integer>
+ </map>
<key>InstantMessageLogPath</key>
<map>
<key>Comment</key>
@@ -54,18 +120,7 @@
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
- </map>
- <key>DisplayDestinationsOnInitialRun</key>
- <map>
- <key>Comment</key>
- <string>Display the destinations guide when a user first launches Second Life.</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
+ </map>
<key>LastInventoryInboxActivity</key>
<map>
<key>Comment</key>
@@ -121,17 +176,6 @@
<key>Value</key>
<integer>1</integer>
</map>
- <key>LogInstantMessages</key>
- <map>
- <key>Comment</key>
- <string>Log Instant Messages</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
<key>LogShowHistory</key>
<map>
<key>Comment</key>
@@ -215,7 +259,51 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>ShowFavoritesOnLogin</key>
+ <key>TranslatingEnabled</key>
+ <map>
+ <key>Comment</key>
+ <string>Translation prefs are set</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>KeepConversationLogTranscripts</key>
+ <map>
+ <key>Comment</key>
+ <string>Keep a conversation log and transcripts</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>2</integer>
+ </map>
+ <key>NearbyChatIsNotTornOff</key>
+ <map>
+ <key>Comment</key>
+ <string>saving torn-off state of the nearby chat between sessions</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>NearbyChatIsNotCollapsed</key>
+ <map>
+ <key>Comment</key>
+ <string>Saving expanded/collapsed state of the nearby chat between sessions</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>ShowFavoritesOnLogin</key>
<map>
<key>Comment</key>
<string>Determines whether favorites of last logged in user will be saved on exit from viewer and shown on login screen</string>
diff --git a/indra/newview/app_settings/shaders/class1/avatar/avatarF.glsl b/indra/newview/app_settings/shaders/class1/avatar/avatarF.glsl
index b631ecb7d2..b631ecb7d2 100644..100755
--- a/indra/newview/app_settings/shaders/class1/avatar/avatarF.glsl
+++ b/indra/newview/app_settings/shaders/class1/avatar/avatarF.glsl
diff --git a/indra/newview/app_settings/shaders/class1/avatar/avatarSkinV.glsl b/indra/newview/app_settings/shaders/class1/avatar/avatarSkinV.glsl
index bc63d07d72..c98e7d1cd3 100644..100755
--- a/indra/newview/app_settings/shaders/class1/avatar/avatarSkinV.glsl
+++ b/indra/newview/app_settings/shaders/class1/avatar/avatarSkinV.glsl
@@ -33,8 +33,8 @@ mat4 getSkinnedTransform()
mat4 ret;
int i = int(floor(weight.x));
float x = fract(weight.x);
-
- ret[0] = mix(matrixPalette[i+0], matrixPalette[i+1], x);
+
+ ret[0] = mix(matrixPalette[i+0], matrixPalette[i+1], x);
ret[1] = mix(matrixPalette[i+15],matrixPalette[i+16], x);
ret[2] = mix(matrixPalette[i+30],matrixPalette[i+31], x);
ret[3] = vec4(0,0,0,1);
diff --git a/indra/newview/app_settings/shaders/class1/avatar/avatarV.glsl b/indra/newview/app_settings/shaders/class1/avatar/avatarV.glsl
index 19203ab670..19203ab670 100644..100755
--- a/indra/newview/app_settings/shaders/class1/avatar/avatarV.glsl
+++ b/indra/newview/app_settings/shaders/class1/avatar/avatarV.glsl
diff --git a/indra/newview/app_settings/shaders/class1/avatar/eyeballF.glsl b/indra/newview/app_settings/shaders/class1/avatar/eyeballF.glsl
index 4296e551db..4296e551db 100644..100755
--- a/indra/newview/app_settings/shaders/class1/avatar/eyeballF.glsl
+++ b/indra/newview/app_settings/shaders/class1/avatar/eyeballF.glsl
diff --git a/indra/newview/app_settings/shaders/class1/avatar/eyeballV.glsl b/indra/newview/app_settings/shaders/class1/avatar/eyeballV.glsl
index 82db15c3ae..82db15c3ae 100644..100755
--- a/indra/newview/app_settings/shaders/class1/avatar/eyeballV.glsl
+++ b/indra/newview/app_settings/shaders/class1/avatar/eyeballV.glsl
diff --git a/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl b/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl
index 43ed41a205..12996cf0d6 100644..100755
--- a/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl
+++ b/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl
@@ -34,14 +34,18 @@ mat4 getObjectSkinnedTransform()
vec4 w = fract(weight4);
vec4 index = floor(weight4);
-
+
+ index = min(index, vec4(31.0));
+ index = max(index, vec4( 0.0));
+
float scale = 1.0/(w.x+w.y+w.z+w.w);
w *= scale;
-
- mat4 mat = matrixPalette[int(index.x)]*w.x;
- mat += matrixPalette[int(index.y)]*w.y;
- mat += matrixPalette[int(index.z)]*w.z;
- mat += matrixPalette[int(index.w)]*w.w;
+
+ mat4 mat = matrixPalette[int(index.x)]*w.x;
+ mat += matrixPalette[int(index.y)]*w.y;
+ mat += matrixPalette[int(index.z)]*w.z;
+ mat += matrixPalette[int(index.w)]*w.w;
return mat;
}
+
diff --git a/indra/newview/app_settings/shaders/class1/avatar/pickAvatarF.glsl b/indra/newview/app_settings/shaders/class1/avatar/pickAvatarF.glsl
index 7a35905280..7a35905280 100644..100755
--- a/indra/newview/app_settings/shaders/class1/avatar/pickAvatarF.glsl
+++ b/indra/newview/app_settings/shaders/class1/avatar/pickAvatarF.glsl
diff --git a/indra/newview/app_settings/shaders/class1/avatar/pickAvatarV.glsl b/indra/newview/app_settings/shaders/class1/avatar/pickAvatarV.glsl
index 78b5328c9a..78b5328c9a 100644..100755
--- a/indra/newview/app_settings/shaders/class1/avatar/pickAvatarV.glsl
+++ b/indra/newview/app_settings/shaders/class1/avatar/pickAvatarV.glsl
diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl
index dd87ddb330..e5f7366b70 100644..100755
--- a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl
@@ -25,31 +25,429 @@
#extension GL_ARB_texture_rectangle : enable
+#define INDEXED 1
+#define NON_INDEXED 2
+#define NON_INDEXED_NO_COLOR 3
+
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
#else
#define frag_color gl_FragColor
#endif
-uniform sampler2DRect depthMap;
+uniform float display_gamma;
+uniform vec4 gamma;
+uniform vec4 lightnorm;
+uniform vec4 sunlight_color;
+uniform vec4 ambient;
+uniform vec4 blue_horizon;
+uniform vec4 blue_density;
+uniform float haze_horizon;
+uniform float haze_density;
+uniform float cloud_shadow;
+uniform float density_multiplier;
+uniform float distance_multiplier;
+uniform float max_y;
+uniform vec4 glow;
+uniform float scene_light_strength;
+uniform mat3 env_mat;
+uniform mat3 ssao_effect_mat;
-vec4 diffuseLookup(vec2 texcoord);
+uniform vec3 sun_dir;
-uniform vec2 screen_res;
+#if HAS_SHADOW
+uniform sampler2DShadow shadowMap0;
+uniform sampler2DShadow shadowMap1;
+uniform sampler2DShadow shadowMap2;
+uniform sampler2DShadow shadowMap3;
+
+uniform vec2 shadow_res;
+
+uniform mat4 shadow_matrix[6];
+uniform vec4 shadow_clip;
+uniform float shadow_bias;
+
+#endif
-vec3 atmosLighting(vec3 light);
-vec3 scaleSoftClip(vec3 light);
+#ifdef USE_DIFFUSE_TEX
+uniform sampler2D diffuseMap;
+#endif
-VARYING vec3 vary_ambient;
-VARYING vec3 vary_directional;
VARYING vec3 vary_fragcoord;
VARYING vec3 vary_position;
-VARYING vec3 vary_pointlight_col;
+VARYING vec2 vary_texcoord0;
+VARYING vec3 vary_norm;
+#ifdef USE_VERTEX_COLOR
VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
+#endif
+
+vec3 vary_PositionEye;
+vec3 vary_SunlitColor;
+vec3 vary_AmblitColor;
+vec3 vary_AdditiveColor;
+vec3 vary_AtmosAttenuation;
uniform mat4 inv_proj;
+uniform vec2 screen_res;
+
+uniform vec4 light_position[8];
+uniform vec3 light_direction[8];
+uniform vec3 light_attenuation[8];
+uniform vec3 light_diffuse[8];
+
+vec3 srgb_to_linear(vec3 cs)
+{
+ vec3 low_range = cs / vec3(12.92);
+ vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
+ bvec3 lte = lessThanEqual(cs,vec3(0.04045));
+
+#ifdef OLD_SELECT
+ vec3 result;
+ result.r = lte.r ? low_range.r : high_range.r;
+ result.g = lte.g ? low_range.g : high_range.g;
+ result.b = lte.b ? low_range.b : high_range.b;
+ return result;
+#else
+ return mix(high_range, low_range, lte);
+#endif
+
+}
+
+vec3 linear_to_srgb(vec3 cl)
+{
+ cl = clamp(cl, vec3(0), vec3(1));
+ vec3 low_range = cl * 12.92;
+ vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
+ bvec3 lt = lessThan(cl,vec3(0.0031308));
+
+#ifdef OLD_SELECT
+ vec3 result;
+ result.r = lt.r ? low_range.r : high_range.r;
+ result.g = lt.g ? low_range.g : high_range.g;
+ result.b = lt.b ? low_range.b : high_range.b;
+ return result;
+#else
+ return mix(high_range, low_range, lt);
+#endif
+
+}
+
+vec2 encode_normal(vec3 n)
+{
+ float f = sqrt(8 * n.z + 8);
+ return n.xy / f + 0.5;
+}
+
+vec3 decode_normal (vec2 enc)
+{
+ vec2 fenc = enc*4-2;
+ float f = dot(fenc,fenc);
+ float g = sqrt(1-f/4);
+ vec3 n;
+ n.xy = fenc*g;
+ n.z = 1-f/2;
+ return n;
+}
+
+vec3 calcDirectionalLight(vec3 n, vec3 l)
+{
+ float a = max(dot(n,l),0.0);
+ a = pow(a, 1.0/1.3);
+ return vec3(a,a,a);
+}
+
+vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 diffuse, vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight)
+{
+ //get light vector
+ vec3 lv = lp.xyz-v;
+
+ //get distance
+ float d = length(lv);
+
+ float da = 1.0;
+
+ vec3 col = vec3(0);
+
+ if (d > 0.0 && la > 0.0 && fa > 0.0)
+ {
+ //normalize light vector
+ lv = normalize(lv);
+
+ //distance attenuation
+ float dist = d/la;
+ float dist_atten = clamp(1.0-(dist-1.0*(1.0-fa))/fa, 0.0, 1.0);
+ dist_atten *= dist_atten;
+ dist_atten *= 2.0;
+
+ // spotlight coefficient.
+ float spot = max(dot(-ln, lv), is_pointlight);
+ da *= spot*spot; // GL_SPOT_EXPONENT=2
+
+ //angular attenuation
+ da *= max(dot(n, lv), 0.0);
+
+ float lit = max(da * dist_atten,0.0);
+
+ col = light_col * lit * diffuse;
+
+ // no spec for alpha shader...
+ }
+
+ return max(col, vec3(0.0,0.0,0.0));
+}
+
+#if HAS_SHADOW
+float pcfShadow(sampler2DShadow shadowMap, vec4 stc)
+{
+ stc.xyz /= stc.w;
+ stc.z += shadow_bias;
+
+ stc.x = floor(stc.x*shadow_res.x + fract(stc.y*shadow_res.y*12345))/shadow_res.x; // add some chaotic jitter to X sample pos according to Y to disguise the snapping going on here
+
+ float cs = shadow2D(shadowMap, stc.xyz).x;
+ float shadow = cs;
+
+ shadow += shadow2D(shadowMap, stc.xyz+vec3(2.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x;
+ shadow += shadow2D(shadowMap, stc.xyz+vec3(1.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x;
+ shadow += shadow2D(shadowMap, stc.xyz+vec3(-1.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x;
+ shadow += shadow2D(shadowMap, stc.xyz+vec3(-2.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x;
+
+ return shadow*0.2;
+}
+#endif
+
+#ifdef WATER_FOG
+uniform vec4 waterPlane;
+uniform vec4 waterFogColor;
+uniform float waterFogDensity;
+uniform float waterFogKS;
+
+vec4 applyWaterFogDeferred(vec3 pos, vec4 color)
+{
+ //normalize view vector
+ vec3 view = normalize(pos);
+ float es = -(dot(view, waterPlane.xyz));
+
+ //find intersection point with water plane and eye vector
+
+ //get eye depth
+ float e0 = max(-waterPlane.w, 0.0);
+
+ vec3 int_v = waterPlane.w > 0.0 ? view * waterPlane.w/es : vec3(0.0, 0.0, 0.0);
+
+ //get object depth
+ float depth = length(pos - int_v);
+
+ //get "thickness" of water
+ float l = max(depth, 0.1);
+
+ float kd = waterFogDensity;
+ float ks = waterFogKS;
+ vec4 kc = waterFogColor;
+
+ float F = 0.98;
+
+ float t1 = -kd * pow(F, ks * e0);
+ float t2 = kd + ks * es;
+ float t3 = pow(F, t2*l) - 1.0;
+
+ float L = min(t1/t2*t3, 1.0);
+
+ float D = pow(0.98, l*kd);
+
+ color.rgb = color.rgb * D + kc.rgb * L;
+ color.a = kc.a + color.a;
+
+ return color;
+}
+#endif
+
+vec3 getSunlitColor()
+{
+ return vary_SunlitColor;
+}
+vec3 getAmblitColor()
+{
+ return vary_AmblitColor;
+}
+vec3 getAdditiveColor()
+{
+ return vary_AdditiveColor;
+}
+vec3 getAtmosAttenuation()
+{
+ return vary_AtmosAttenuation;
+}
+
+void setPositionEye(vec3 v)
+{
+ vary_PositionEye = v;
+}
+
+void setSunlitColor(vec3 v)
+{
+ vary_SunlitColor = v;
+}
+
+void setAmblitColor(vec3 v)
+{
+ vary_AmblitColor = v;
+}
+
+void setAdditiveColor(vec3 v)
+{
+ vary_AdditiveColor = v;
+}
+
+void setAtmosAttenuation(vec3 v)
+{
+ vary_AtmosAttenuation = v;
+}
+
+void calcAtmospherics(vec3 inPositionEye, float ambFactor) {
+
+ vec3 P = inPositionEye;
+ setPositionEye(P);
+
+ vec3 tmpLightnorm = lightnorm.xyz;
+
+ vec3 Pn = normalize(P);
+ float Plen = length(P);
+
+ vec4 temp1 = vec4(0);
+ vec3 temp2 = vec3(0);
+ vec4 blue_weight;
+ vec4 haze_weight;
+ vec4 sunlight = sunlight_color;
+ vec4 light_atten;
+
+ //sunlight attenuation effect (hue and brightness) due to atmosphere
+ //this is used later for sunlight modulation at various altitudes
+ light_atten = (blue_density + vec4(haze_density * 0.25)) * (density_multiplier * max_y);
+ //I had thought blue_density and haze_density should have equal weighting,
+ //but attenuation due to haze_density tends to seem too strong
+
+ temp1 = blue_density + vec4(haze_density);
+ blue_weight = blue_density / temp1;
+ haze_weight = vec4(haze_density) / temp1;
+
+ //(TERRAIN) compute sunlight from lightnorm only (for short rays like terrain)
+ temp2.y = max(0.0, tmpLightnorm.y);
+ temp2.y = 1. / temp2.y;
+ sunlight *= exp( - light_atten * temp2.y);
+
+ // main atmospheric scattering line integral
+ temp2.z = Plen * density_multiplier;
+
+ // Transparency (-> temp1)
+ // ATI Bugfix -- can't store temp1*temp2.z*distance_multiplier in a variable because the ati
+ // compiler gets confused.
+ temp1 = exp(-temp1 * temp2.z * distance_multiplier);
+
+ //final atmosphere attenuation factor
+ setAtmosAttenuation(temp1.rgb);
+
+ //compute haze glow
+ //(can use temp2.x as temp because we haven't used it yet)
+ temp2.x = dot(Pn, tmpLightnorm.xyz);
+ temp2.x = 1. - temp2.x;
+ //temp2.x is 0 at the sun and increases away from sun
+ temp2.x = max(temp2.x, .03); //was glow.y
+ //set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)
+ temp2.x *= glow.x;
+ //higher glow.x gives dimmer glow (because next step is 1 / "angle")
+ temp2.x = pow(temp2.x, glow.z);
+ //glow.z should be negative, so we're doing a sort of (1 / "angle") function
+
+ //add "minimum anti-solar illumination"
+ temp2.x += .25;
+
+ //increase ambient when there are more clouds
+ vec4 tmpAmbient = ambient + (vec4(1.) - ambient) * cloud_shadow * 0.5;
+
+ /* decrease value and saturation (that in HSV, not HSL) for occluded areas
+ * // for HSV color/geometry used here, see http://gimp-savvy.com/BOOK/index.html?node52.html
+ * // The following line of code performs the equivalent of:
+ * float ambAlpha = tmpAmbient.a;
+ * float ambValue = dot(vec3(tmpAmbient), vec3(0.577)); // projection onto <1/rt(3), 1/rt(3), 1/rt(3)>, the neutral white-black axis
+ * vec3 ambHueSat = vec3(tmpAmbient) - vec3(ambValue);
+ * tmpAmbient = vec4(RenderSSAOEffect.valueFactor * vec3(ambValue) + RenderSSAOEffect.saturationFactor *(1.0 - ambFactor) * ambHueSat, ambAlpha);
+ */
+ tmpAmbient = vec4(mix(ssao_effect_mat * tmpAmbient.rgb, tmpAmbient.rgb, ambFactor), tmpAmbient.a);
+
+ //haze color
+ setAdditiveColor(
+ vec3(blue_horizon * blue_weight * (sunlight*(1.-cloud_shadow) + tmpAmbient)
+ + (haze_horizon * haze_weight) * (sunlight*(1.-cloud_shadow) * temp2.x
+ + tmpAmbient)));
+
+ //brightness of surface both sunlight and ambient
+ setSunlitColor(vec3(sunlight * .5));
+ setAmblitColor(vec3(tmpAmbient * .25));
+ setAdditiveColor(getAdditiveColor() * vec3(1.0 - temp1));
+}
+
+vec3 atmosLighting(vec3 light)
+{
+ light *= getAtmosAttenuation().r;
+ light += getAdditiveColor();
+ return (2.0 * light);
+}
+
+vec3 atmosTransport(vec3 light) {
+ light *= getAtmosAttenuation().r;
+ light += getAdditiveColor() * 2.0;
+ return light;
+}
+vec3 atmosGetDiffuseSunlightColor()
+{
+ return getSunlitColor();
+}
+
+vec3 scaleDownLight(vec3 light)
+{
+ return (light / vec3(scene_light_strength, scene_light_strength, scene_light_strength));
+}
+
+vec3 scaleUpLight(vec3 light)
+{
+ return (light * vec3(scene_light_strength, scene_light_strength, scene_light_strength));
+}
+
+vec3 atmosAmbient(vec3 light)
+{
+ return getAmblitColor() + (light * vec3(0.5f, 0.5f, 0.5f));
+}
+
+vec3 atmosAffectDirectionalLight(float lightIntensity)
+{
+ return getSunlitColor() * vec3(lightIntensity, lightIntensity, lightIntensity);
+}
+
+vec3 scaleSoftClip(vec3 light)
+{
+ //soft clip effect:
+ vec3 zeroes = vec3(0.0f, 0.0f, 0.0f);
+ vec3 ones = vec3(1.0f, 1.0f, 1.0f);
+
+ light = ones - clamp(light, zeroes, ones);
+ light = ones - pow(light, gamma.xxx);
+
+ return light;
+}
+
+vec3 fullbrightAtmosTransport(vec3 light) {
+ float brightness = dot(light.rgb, vec3(0.33333));
+
+ return mix(atmosTransport(light.rgb), light.rgb + getAdditiveColor().rgb, brightness * brightness);
+}
+
+vec3 fullbrightScaleSoftClip(vec3 light)
+{
+ //soft clip effect:
+ return light;
+}
void main()
{
@@ -58,16 +456,172 @@ void main()
vec4 pos = vec4(vary_position, 1.0);
- vec4 diff= diffuseLookup(vary_texcoord0.xy);
+ float shadow = 1.0;
+
+#if HAS_SHADOW
+ vec4 spos = pos;
+
+ if (spos.z > -shadow_clip.w)
+ {
+ shadow = 0.0;
- vec4 col = vec4(vary_ambient + vary_directional.rgb, vertex_color.a);
- vec4 color = diff * col;
+ vec4 lpos;
+
+ vec4 near_split = shadow_clip*-0.75;
+ vec4 far_split = shadow_clip*-1.25;
+ vec4 transition_domain = near_split-far_split;
+ float weight = 0.0;
+
+ if (spos.z < near_split.z)
+ {
+ lpos = shadow_matrix[3]*spos;
+
+ float w = 1.0;
+ w -= max(spos.z-far_split.z, 0.0)/transition_domain.z;
+ shadow += pcfShadow(shadowMap3, lpos)*w;
+ weight += w;
+ shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0);
+ }
+
+ if (spos.z < near_split.y && spos.z > far_split.z)
+ {
+ lpos = shadow_matrix[2]*spos;
+
+ float w = 1.0;
+ w -= max(spos.z-far_split.y, 0.0)/transition_domain.y;
+ w -= max(near_split.z-spos.z, 0.0)/transition_domain.z;
+ shadow += pcfShadow(shadowMap2, lpos)*w;
+ weight += w;
+ }
+
+ if (spos.z < near_split.x && spos.z > far_split.y)
+ {
+ lpos = shadow_matrix[1]*spos;
+
+ float w = 1.0;
+ w -= max(spos.z-far_split.x, 0.0)/transition_domain.x;
+ w -= max(near_split.y-spos.z, 0.0)/transition_domain.y;
+ shadow += pcfShadow(shadowMap1, lpos)*w;
+ weight += w;
+ }
+
+ if (spos.z > far_split.x)
+ {
+ lpos = shadow_matrix[0]*spos;
+
+ float w = 1.0;
+ w -= max(near_split.x-spos.z, 0.0)/transition_domain.x;
+
+ shadow += pcfShadow(shadowMap0, lpos)*w;
+ weight += w;
+ }
+
+
+ shadow /= weight;
+ }
+ else
+ {
+ shadow = 1.0;
+ }
+#endif
+
+#ifdef USE_INDEXED_TEX
+ vec4 diff = diffuseLookup(vary_texcoord0.xy);
+#else
+ vec4 diff = texture2D(diffuseMap,vary_texcoord0.xy);
+#endif
+
+#ifdef FOR_IMPOSTOR
+ vec4 color;
+ color.rgb = diff.rgb;
+
+#ifdef USE_VERTEX_COLOR
+ float final_alpha = diff.a * vertex_color.a;
+ diff.rgb *= vertex_color.rgb;
+#else
+ float final_alpha = diff.a;
+#endif
- color.rgb = atmosLighting(color.rgb);
+ // Insure we don't pollute depth with invis pixels in impostor rendering
+ //
+ if (final_alpha < 0.01)
+ {
+ discard;
+ }
+#else
+
+#ifdef USE_VERTEX_COLOR
+ float final_alpha = diff.a * vertex_color.a;
+ diff.rgb *= vertex_color.rgb;
+#else
+ float final_alpha = diff.a;
+#endif
+
+
+ vec4 gamma_diff = diff;
+ diff.rgb = srgb_to_linear(diff.rgb);
+
+ vec3 norm = vary_norm;
+
+ calcAtmospherics(pos.xyz, 1.0);
+
+ vec2 abnormal = encode_normal(norm.xyz);
+ norm.xyz = decode_normal(abnormal.xy);
+
+ float da = dot(norm.xyz, sun_dir.xyz);
+
+ float final_da = da;
+ final_da = min(final_da, shadow);
+ final_da = max(final_da, 0.0f);
+ final_da = min(final_da, 1.0f);
+ final_da = pow(final_da, 1.0/1.3);
+
+ vec4 color = vec4(0,0,0,0);
+
+ color.rgb = atmosAmbient(color.rgb);
+ color.a = final_alpha;
+
+ float ambient = abs(da);
+ ambient *= 0.5;
+ ambient *= ambient;
+ ambient = (1.0-ambient);
+
+ color.rgb *= ambient;
+ color.rgb += atmosAffectDirectionalLight(final_da);
+ color.rgb *= gamma_diff.rgb;
+ //color.rgb = mix(diff.rgb, color.rgb, final_alpha);
+
+ color.rgb = atmosLighting(color.rgb);
color.rgb = scaleSoftClip(color.rgb);
- color.rgb += diff.rgb * vary_pointlight_col.rgb;
+ vec4 light = vec4(0,0,0,0);
+
+ color.rgb = srgb_to_linear(color.rgb);
+
+ #define LIGHT_LOOP(i) light.rgb += calcPointLightOrSpotLight(light_diffuse[i].rgb, diff.rgb, pos.xyz, norm, light_position[i], light_direction[i].xyz, light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z);
+
+ LIGHT_LOOP(1)
+ LIGHT_LOOP(2)
+ LIGHT_LOOP(3)
+ LIGHT_LOOP(4)
+ LIGHT_LOOP(5)
+ LIGHT_LOOP(6)
+ LIGHT_LOOP(7)
+
+ // keep it linear
+ //
+ color.rgb += light.rgb;
+
+ // straight to display gamma, we're post-deferred
+ //
+ color.rgb = linear_to_srgb(color.rgb);
+
+#ifdef WATER_FOG
+ color = applyWaterFogDeferred(pos.xyz, color);
+#endif
+
+#endif
frag_color = color;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaNonIndexedF.glsl
deleted file mode 100644
index beb3290187..0000000000
--- a/indra/newview/app_settings/shaders/class1/deferred/alphaNonIndexedF.glsl
+++ /dev/null
@@ -1,89 +0,0 @@
-/**
- * @file alphaF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, 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$
- */
-
-#extension GL_ARB_texture_rectangle : enable
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-uniform sampler2DRect depthMap;
-uniform sampler2D diffuseMap;
-
-
-uniform vec2 screen_res;
-
-vec3 atmosLighting(vec3 light);
-vec3 scaleSoftClip(vec3 light);
-
-VARYING vec3 vary_ambient;
-VARYING vec3 vary_directional;
-VARYING vec3 vary_fragcoord;
-VARYING vec3 vary_position;
-VARYING vec3 vary_pointlight_col;
-VARYING vec2 vary_texcoord0;
-VARYING vec4 vertex_color;
-
-uniform mat4 inv_proj;
-
-vec4 getPosition(vec2 pos_screen)
-{
- float depth = texture2DRect(depthMap, pos_screen.xy).a;
- vec2 sc = pos_screen.xy*2.0;
- sc /= screen_res;
- sc -= vec2(1.0,1.0);
- vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
- vec4 pos = inv_proj * ndc;
- pos /= pos.w;
- pos.w = 1.0;
- return pos;
-}
-
-void main()
-{
- vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5;
- frag *= screen_res;
-
- vec4 pos = vec4(vary_position, 1.0);
-
- vec4 diff= texture2D(diffuseMap,vary_texcoord0.xy);
-
- vec4 col = vec4(vary_ambient + vary_directional.rgb, vertex_color.a);
- vec4 color = diff * col;
-
- color.rgb = atmosLighting(color.rgb);
-
- color.rgb = scaleSoftClip(color.rgb);
-
- color.rgb += diff.rgb * vary_pointlight_col.rgb;
-
- frag_color = color;
- //frag_color = vec4(1,0,1,1);
- //frag_color = vec4(1,0,1,1)*shadow;
-
-}
-
diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaNonIndexedNoColorF.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaNonIndexedNoColorF.glsl
deleted file mode 100644
index cb87b754b4..0000000000
--- a/indra/newview/app_settings/shaders/class1/deferred/alphaNonIndexedNoColorF.glsl
+++ /dev/null
@@ -1,84 +0,0 @@
-/**
- * @file alphaNonIndexedNoColorF.glsl
- *
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2005, 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$
- */
-
-#extension GL_ARB_texture_rectangle : enable
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-uniform sampler2DRect depthMap;
-uniform sampler2D diffuseMap;
-
-uniform vec2 screen_res;
-
-vec3 atmosLighting(vec3 light);
-vec3 scaleSoftClip(vec3 light);
-
-VARYING vec3 vary_ambient;
-VARYING vec3 vary_directional;
-VARYING vec3 vary_fragcoord;
-VARYING vec3 vary_position;
-VARYING vec3 vary_pointlight_col;
-VARYING vec2 vary_texcoord0;
-
-uniform mat4 inv_proj;
-
-vec4 getPosition(vec2 pos_screen)
-{
- float depth = texture2DRect(depthMap, pos_screen.xy).a;
- vec2 sc = pos_screen.xy*2.0;
- sc /= screen_res;
- sc -= vec2(1.0,1.0);
- vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
- vec4 pos = inv_proj * ndc;
- pos /= pos.w;
- pos.w = 1.0;
- return pos;
-}
-
-void main()
-{
- vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5;
- frag *= screen_res;
-
- vec4 pos = vec4(vary_position, 1.0);
-
- vec4 diff= texture2D(diffuseMap,vary_texcoord0.xy);
-
- vec4 col = vec4(vary_ambient + vary_directional.rgb, 1.0);
- vec4 color = diff * col;
-
- color.rgb = atmosLighting(color.rgb);
-
- color.rgb = scaleSoftClip(color.rgb);
-
- color.rgb += diff.rgb * vary_pointlight_col.rgb;
-
- frag_color = color;
-}
-
diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaSkinnedV.glsl
deleted file mode 100644
index 5a0e8ff684..0000000000
--- a/indra/newview/app_settings/shaders/class1/deferred/alphaSkinnedV.glsl
+++ /dev/null
@@ -1,144 +0,0 @@
-/**
- * @file alphaSkinnedV.glsl
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, 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$
- */
-
-uniform mat4 projection_matrix;
-uniform mat4 modelview_matrix;
-
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec3 normal;
-ATTRIBUTE vec4 diffuse_color;
-ATTRIBUTE vec2 texcoord0;
-
-mat4 getObjectSkinnedTransform();
-void calcAtmospherics(vec3 inPositionEye);
-
-float calcDirectionalLight(vec3 n, vec3 l);
-
-vec3 atmosAmbient(vec3 light);
-vec3 atmosAffectDirectionalLight(float lightIntensity);
-
-VARYING vec3 vary_position;
-VARYING vec3 vary_ambient;
-VARYING vec3 vary_directional;
-VARYING vec3 vary_fragcoord;
-VARYING vec3 vary_pointlight_col;
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
-
-
-uniform float near_clip;
-
-uniform vec4 light_position[8];
-uniform vec3 light_direction[8];
-uniform vec3 light_attenuation[8];
-uniform vec3 light_diffuse[8];
-
-float calcDirectionalLight(vec3 n, vec3 l)
-{
- float a = max(dot(n,l),0.0);
- return a;
-}
-
-float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight)
-{
- //get light vector
- vec3 lv = lp.xyz-v;
-
- //get distance
- float d = dot(lv,lv);
-
- float da = 0.0;
-
- if (d > 0.0 && la > 0.0 && fa > 0.0)
- {
- //normalize light vector
- lv = normalize(lv);
-
- //distance attenuation
- float dist2 = d/la;
- da = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0);
-
- // spotlight coefficient.
- float spot = max(dot(-ln, lv), is_pointlight);
- da *= spot*spot; // GL_SPOT_EXPONENT=2
-
- //angular attenuation
- da *= max(dot(n, lv), 0.0);
- }
-
- return da;
-}
-
-void main()
-{
- vary_texcoord0 = texcoord0;
-
- vec4 pos;
- vec3 norm;
-
- mat4 trans = getObjectSkinnedTransform();
- trans = modelview_matrix * trans;
-
- pos = trans * vec4(position.xyz, 1.0);
-
- norm = position.xyz + normal.xyz;
- norm = normalize(( trans*vec4(norm, 1.0) ).xyz-pos.xyz);
-
- vec4 frag_pos = projection_matrix * pos;
- gl_Position = frag_pos;
-
- vary_position = pos.xyz;
-
- calcAtmospherics(pos.xyz);
-
- vec4 col = vec4(0.0, 0.0, 0.0, diffuse_color.a);
-
- // Collect normal lights
- col.rgb += light_diffuse[2].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[2], light_direction[2], light_attenuation[2].x, light_attenuation[2].y, light_attenuation[2].z);
- col.rgb += light_diffuse[3].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[3], light_direction[3], light_attenuation[3].x, light_attenuation[3].y, light_attenuation[3].z);
- col.rgb += light_diffuse[4].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[4], light_direction[4], light_attenuation[4].x, light_attenuation[4].y, light_attenuation[4].z);
- col.rgb += light_diffuse[5].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[5], light_direction[5], light_attenuation[5].x, light_attenuation[5].y, light_attenuation[5].z);
- col.rgb += light_diffuse[6].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[6], light_direction[6], light_attenuation[6].x, light_attenuation[6].y, light_attenuation[6].z);
- col.rgb += light_diffuse[7].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[7], light_direction[7], light_attenuation[7].x, light_attenuation[7].y, light_attenuation[7].z);
-
- vary_pointlight_col = col.rgb*diffuse_color.rgb;
-
- col.rgb = vec3(0,0,0);
-
- // Add windlight lights
- col.rgb = atmosAmbient(vec3(0.));
-
- vary_ambient = col.rgb*diffuse_color.rgb;
- vary_directional = diffuse_color.rgb*atmosAffectDirectionalLight(max(calcDirectionalLight(norm, light_position[0].xyz), (1.0-diffuse_color.a)*(1.0-diffuse_color.a)));
-
- col.rgb = min(col.rgb*diffuse_color.rgb, 1.0);
-
- vertex_color = col;
-
-
-
- vary_fragcoord.xyz = frag_pos.xyz + vec3(0,0,near_clip);
-}
-
-
diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl
index cf38a2f4f7..b40785bbd7 100644..100755
--- a/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl
@@ -23,126 +23,118 @@
* $/LicenseInfo$
*/
+#define INDEXED 1
+#define NON_INDEXED 2
+#define NON_INDEXED_NO_COLOR 3
+
uniform mat3 normal_matrix;
uniform mat4 texture_matrix0;
+uniform mat4 projection_matrix;
uniform mat4 modelview_matrix;
uniform mat4 modelview_projection_matrix;
ATTRIBUTE vec3 position;
+
+#ifdef USE_INDEXED_TEX
void passTextureIndex();
+#endif
+
ATTRIBUTE vec3 normal;
-ATTRIBUTE vec4 diffuse_color;
-ATTRIBUTE vec2 texcoord0;
-vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
-void calcAtmospherics(vec3 inPositionEye);
+#ifdef USE_VERTEX_COLOR
+ATTRIBUTE vec4 diffuse_color;
+#endif
-float calcDirectionalLight(vec3 n, vec3 l);
+ATTRIBUTE vec2 texcoord0;
-vec3 atmosAmbient(vec3 light);
-vec3 atmosAffectDirectionalLight(float lightIntensity);
-vec3 scaleDownLight(vec3 light);
-vec3 scaleUpLight(vec3 light);
+#ifdef HAS_SKIN
+mat4 getObjectSkinnedTransform();
+#else
+#ifdef IS_AVATAR_SKIN
+mat4 getSkinnedTransform();
+#endif
+#endif
-VARYING vec3 vary_ambient;
-VARYING vec3 vary_directional;
VARYING vec3 vary_fragcoord;
VARYING vec3 vary_position;
-VARYING vec3 vary_pointlight_col;
+#ifdef USE_VERTEX_COLOR
VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
+#endif
+VARYING vec2 vary_texcoord0;
+VARYING vec3 vary_norm;
uniform float near_clip;
-uniform float shadow_offset;
-uniform float shadow_bias;
-
-uniform vec4 light_position[8];
-uniform vec3 light_direction[8];
-uniform vec3 light_attenuation[8];
-uniform vec3 light_diffuse[8];
-float calcDirectionalLight(vec3 n, vec3 l)
-{
- float a = max(dot(n,l),0.0);
- return a;
-}
-
-float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight)
+void main()
{
- //get light vector
- vec3 lv = lp.xyz-v;
+ vec4 pos;
+ vec3 norm;
- //get distance
- float d = dot(lv,lv);
+ //transform vertex
+#ifdef HAS_SKIN
+ mat4 trans = getObjectSkinnedTransform();
+ trans = modelview_matrix * trans;
- float da = 0.0;
-
- if (d > 0.0 && la > 0.0 && fa > 0.0)
- {
- //normalize light vector
- lv = normalize(lv);
+ pos = trans * vec4(position.xyz, 1.0);
- //distance attenuation
- float dist2 = d/la;
- da = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0);
-
- // spotlight coefficient.
- float spot = max(dot(-ln, lv), is_pointlight);
- da *= spot*spot; // GL_SPOT_EXPONENT=2
-
- //angular attenuation
- da *= max(dot(n, lv), 0.0);
- }
-
- return da;
-}
-
-void main()
-{
- //transform vertex
+ norm = position.xyz + normal.xyz;
+ norm = normalize((trans * vec4(norm, 1.0)).xyz - pos.xyz);
+ vec4 frag_pos = projection_matrix * pos;
+ gl_Position = frag_pos;
+#else
+
+#ifdef IS_AVATAR_SKIN
+ mat4 trans = getSkinnedTransform();
+ vec4 pos_in = vec4(position.xyz, 1.0);
+ pos.x = dot(trans[0], pos_in);
+ pos.y = dot(trans[1], pos_in);
+ pos.z = dot(trans[2], pos_in);
+ pos.w = 1.0;
+
+ norm.x = dot(trans[0].xyz, normal);
+ norm.y = dot(trans[1].xyz, normal);
+ norm.z = dot(trans[2].xyz, normal);
+ norm = normalize(norm);
+
+ vec4 frag_pos = projection_matrix * pos;
+ gl_Position = frag_pos;
+#else
+ norm = normalize(normal_matrix * normal);
vec4 vert = vec4(position.xyz, 1.0);
- passTextureIndex();
- vec4 pos = (modelview_matrix * vert);
+ pos = (modelview_matrix * vert);
gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);
+#endif
+#endif
+
+#ifdef USE_INDEXED_TEX
+ passTextureIndex();
vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
+#else
+ vary_texcoord0 = texcoord0;
+#endif
- vec3 norm = normalize(normal_matrix * normal);
-
- float dp_directional_light = max(0.0, dot(norm, light_position[0].xyz));
- vary_position = pos.xyz + light_position[0].xyz * (1.0-dp_directional_light)*shadow_offset;
-
- calcAtmospherics(pos.xyz);
-
- //vec4 color = calcLighting(pos.xyz, norm, diffuse_color, vec4(0.));
- vec4 col = vec4(0.0, 0.0, 0.0, diffuse_color.a);
-
- // Collect normal lights
- col.rgb += light_diffuse[2].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[2], light_direction[2], light_attenuation[2].x, light_attenuation[2].y, light_attenuation[2].z);
- col.rgb += light_diffuse[3].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[3], light_direction[3], light_attenuation[3].x, light_attenuation[3].y, light_attenuation[3].z);
- col.rgb += light_diffuse[4].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[4], light_direction[4], light_attenuation[4].x, light_attenuation[4].y, light_attenuation[4].z);
- col.rgb += light_diffuse[5].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[5], light_direction[5], light_attenuation[5].x, light_attenuation[5].y, light_attenuation[5].z);
- col.rgb += light_diffuse[6].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[6], light_direction[6], light_attenuation[6].x, light_attenuation[6].y, light_attenuation[6].z);
- col.rgb += light_diffuse[7].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[7], light_direction[7], light_attenuation[7].x, light_attenuation[7].y, light_attenuation[7].z);
-
- vary_pointlight_col = col.rgb*diffuse_color.rgb;
- col.rgb = vec3(0,0,0);
+ vary_norm = norm;
+ vary_position = pos.xyz;
- // Add windlight lights
- col.rgb = atmosAmbient(vec3(0.));
-
- vary_ambient = col.rgb*diffuse_color.rgb;
- vary_directional.rgb = diffuse_color.rgb*atmosAffectDirectionalLight(max(calcDirectionalLight(norm, light_position[0].xyz), (1.0-diffuse_color.a)*(1.0-diffuse_color.a)));
+#ifdef USE_VERTEX_COLOR
+ vertex_color = diffuse_color;
+#endif
- col.rgb = col.rgb*diffuse_color.rgb;
-
- vertex_color = col;
+#ifdef HAS_SKIN
+ vary_fragcoord.xyz = frag_pos.xyz + vec3(0,0,near_clip);
+#else
-
-
+#ifdef IS_AVATAR_SKIN
+ vary_fragcoord.xyz = pos.xyz + vec3(0,0,near_clip);
+#else
pos = modelview_projection_matrix * vert;
vary_fragcoord.xyz = pos.xyz + vec3(0,0,near_clip);
+#endif
+#endif
+
}
+
diff --git a/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowF.glsl
index 22c9a4d14e..22c9a4d14e 100644..100755
--- a/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowF.glsl
diff --git a/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowV.glsl b/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowV.glsl
index 81961d7746..3f90600ace 100644..100755
--- a/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowV.glsl
@@ -39,7 +39,12 @@ void main()
mat = modelview_matrix * mat;
vec3 pos = (mat*vec4(position.xyz, 1.0)).xyz;
+
vec4 p = projection_matrix * vec4(pos, 1.0);
+#if !DEPTH_CLAMP
p.z = max(p.z, -p.w+0.01);
gl_Position = p;
+#else
+ gl_Position = p;
+#endif
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaNoColorV.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaNoColorV.glsl
index 5f395801e5..c8ddefac26 100644..100755
--- a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaNoColorV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaNoColorV.glsl
@@ -47,6 +47,7 @@ VARYING vec3 vary_directional;
VARYING vec3 vary_fragcoord;
VARYING vec3 vary_pointlight_col;
VARYING vec2 vary_texcoord0;
+VARYING vec3 vary_norm;
uniform float near_clip;
@@ -112,6 +113,7 @@ void main()
norm.y = dot(trans[1].xyz, normal);
norm.z = dot(trans[2].xyz, normal);
norm = normalize(norm);
+ vary_norm = norm;
vec4 frag_pos = projection_matrix * pos;
gl_Position = frag_pos;
diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaV.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaV.glsl
deleted file mode 100644
index d6149fcc32..0000000000
--- a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaV.glsl
+++ /dev/null
@@ -1,153 +0,0 @@
-/**
- * @file avatarAlphaV.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, 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$
- */
-
-uniform mat4 projection_matrix;
-
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec3 normal;
-ATTRIBUTE vec2 texcoord0;
-
-vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
-mat4 getSkinnedTransform();
-void calcAtmospherics(vec3 inPositionEye);
-
-float calcDirectionalLight(vec3 n, vec3 l);
-float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float is_pointlight);
-
-vec3 atmosAmbient(vec3 light);
-vec3 atmosAffectDirectionalLight(float lightIntensity);
-vec3 scaleDownLight(vec3 light);
-vec3 scaleUpLight(vec3 light);
-
-VARYING vec3 vary_position;
-VARYING vec3 vary_ambient;
-VARYING vec3 vary_directional;
-VARYING vec3 vary_fragcoord;
-VARYING vec3 vary_pointlight_col;
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
-
-
-uniform float near_clip;
-
-uniform vec4 color;
-
-uniform vec4 light_position[8];
-uniform vec3 light_direction[8];
-uniform vec3 light_attenuation[8];
-uniform vec3 light_diffuse[8];
-
-float calcDirectionalLight(vec3 n, vec3 l)
-{
- float a = max(dot(n,l),0.0);
- return a;
-}
-
-float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight)
-{
- //get light vector
- vec3 lv = lp.xyz-v;
-
- //get distance
- float d = dot(lv,lv);
-
- float da = 0.0;
-
- if (d > 0.0 && la > 0.0 && fa > 0.0)
- {
- //normalize light vector
- lv = normalize(lv);
-
- //distance attenuation
- float dist2 = d/la;
- da = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0);
-
- // spotlight coefficient.
- float spot = max(dot(-ln, lv), is_pointlight);
- da *= spot*spot; // GL_SPOT_EXPONENT=2
-
- //angular attenuation
- da *= max(dot(n, lv), 0.0);
- }
-
- return da;
-}
-
-void main()
-{
- vary_texcoord0 = texcoord0;
-
- vec4 pos;
- vec3 norm;
-
- mat4 trans = getSkinnedTransform();
- vec4 pos_in = vec4(position.xyz, 1.0);
- pos.x = dot(trans[0], pos_in);
- pos.y = dot(trans[1], pos_in);
- pos.z = dot(trans[2], pos_in);
- pos.w = 1.0;
-
- norm.x = dot(trans[0].xyz, normal);
- norm.y = dot(trans[1].xyz, normal);
- norm.z = dot(trans[2].xyz, normal);
- norm = normalize(norm);
-
- vec4 frag_pos = projection_matrix * pos;
- gl_Position = frag_pos;
-
- vary_position = pos.xyz;
-
- calcAtmospherics(pos.xyz);
-
- vec4 col = vec4(0.0, 0.0, 0.0, 1.0);
-
- // Collect normal lights
- col.rgb += light_diffuse[2].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[2], light_direction[2], light_attenuation[2].x, light_attenuation[2].y, light_attenuation[2].z);
- col.rgb += light_diffuse[3].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[3], light_direction[3], light_attenuation[3].x, light_attenuation[3].y, light_attenuation[3].z);
- col.rgb += light_diffuse[4].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[4], light_direction[4], light_attenuation[4].x, light_attenuation[4].y, light_attenuation[4].z);
- col.rgb += light_diffuse[5].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[5], light_direction[5], light_attenuation[5].x, light_attenuation[5].y, light_attenuation[5].z);
- col.rgb += light_diffuse[6].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[6], light_direction[6], light_attenuation[6].x, light_attenuation[6].y, light_attenuation[6].z);
- col.rgb += light_diffuse[7].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[7], light_direction[7], light_attenuation[7].x, light_attenuation[7].y, light_attenuation[7].z);
-
- vary_pointlight_col = col.rgb*color.rgb;
-
- col.rgb = vec3(0,0,0);
-
- // Add windlight lights
- col.rgb = atmosAmbient(vec3(0.));
-
- vary_ambient = col.rgb*color.rgb;
- vary_directional = color.rgb*atmosAffectDirectionalLight(max(calcDirectionalLight(norm, light_position[0].xyz), 0.0));
-
- col.rgb = col.rgb * color.rgb;
-
- vertex_color = col;
-
-
-
- vary_fragcoord.xyz = frag_pos.xyz + vec3(0,0,near_clip);
-}
-
-
diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarEyesV.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarEyesV.glsl
index 01ffb862f7..01ffb862f7 100644..100755
--- a/indra/newview/app_settings/shaders/class1/deferred/avatarEyesV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/avatarEyesV.glsl
diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl
index 46d2aa4877..662c762bca 100644..100755
--- a/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl
@@ -31,14 +31,22 @@ out vec4 frag_data[3];
uniform sampler2D diffuseMap;
+uniform float minimum_alpha;
+
VARYING vec3 vary_normal;
VARYING vec2 vary_texcoord0;
+vec2 encode_normal(vec3 n)
+{
+ float f = sqrt(8 * n.z + 8);
+ return n.xy / f + 0.5;
+}
+
void main()
{
vec4 diff = texture2D(diffuseMap, vary_texcoord0.xy);
- if (diff.a < 0.2)
+ if (diff.a < minimum_alpha)
{
discard;
}
@@ -46,6 +54,6 @@ void main()
frag_data[0] = vec4(diff.rgb, 0.0);
frag_data[1] = vec4(0,0,0,0);
vec3 nvn = normalize(vary_normal);
- frag_data[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0);
+ frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, 0.0);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl
index 3686f2f647..b809b73973 100644..100755
--- a/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl
@@ -31,12 +31,16 @@ out vec4 frag_color;
uniform sampler2D diffuseMap;
+#if !DEPTH_CLAMP
VARYING vec4 post_pos;
+#endif
void main()
{
frag_color = vec4(1,1,1,1);
+#if !DEPTH_CLAMP
gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0);
+#endif
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarShadowV.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarShadowV.glsl
index 23feb09d72..bde1ad4e9f 100644..100755
--- a/indra/newview/app_settings/shaders/class1/deferred/avatarShadowV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/avatarShadowV.glsl
@@ -31,7 +31,9 @@ ATTRIBUTE vec3 position;
ATTRIBUTE vec3 normal;
ATTRIBUTE vec2 texcoord0;
+#if !DEPTH_CLAMP
VARYING vec4 post_pos;
+#endif
void main()
{
@@ -51,9 +53,13 @@ void main()
norm = normalize(norm);
pos = projection_matrix * pos;
+#if !DEPTH_CLAMP
post_pos = pos;
gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
+#else
+ gl_Position = pos;
+#endif
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarV.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarV.glsl
index 1bd8fee7c9..1bd8fee7c9 100644..100755
--- a/indra/newview/app_settings/shaders/class1/deferred/avatarV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/avatarV.glsl
diff --git a/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl
index f400eb7a5b..a4f54dff70 100644..100755
--- a/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl
@@ -46,11 +46,6 @@ VARYING vec2 vary_fragcoord;
uniform mat4 inv_proj;
uniform vec2 screen_res;
-vec3 getKern(int i)
-{
- return kern[i];
-}
-
vec4 getPosition(vec2 pos_screen)
{
float depth = texture2DRect(depthMap, pos_screen.xy).r;
@@ -64,18 +59,36 @@ vec4 getPosition(vec2 pos_screen)
return pos;
}
+vec2 encode_normal(vec3 n)
+{
+ float f = sqrt(8 * n.z + 8);
+ return n.xy / f + 0.5;
+}
+
+vec3 decode_normal (vec2 enc)
+{
+ vec2 fenc = enc*4-2;
+ float f = dot(fenc,fenc);
+ float g = sqrt(1-f/4);
+ vec3 n;
+ n.xy = fenc*g;
+ n.z = 1-f/2;
+ return n;
+}
+
void main()
{
vec2 tc = vary_fragcoord.xy;
vec3 norm = texture2DRect(normalMap, tc).xyz;
- norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
+ norm = decode_normal(norm.xy); // unpack norm
+
vec3 pos = getPosition(tc).xyz;
vec4 ccol = texture2DRect(lightMap, tc).rgba;
vec2 dlt = kern_scale * delta / (1.0+norm.xy*norm.xy);
dlt /= max(-pos.z*dist_factor, 1.0);
- vec2 defined_weight = getKern(0).xy; // special case the first (centre) sample's weight in the blur; we have to sample it anyway so we get it for 'free'
+ vec2 defined_weight = kern[0].xy; // special case the first (centre) sample's weight in the blur; we have to sample it anyway so we get it for 'free'
vec4 col = defined_weight.xyxx * ccol;
// relax tolerance according to distance to avoid speckling artifacts, as angles and distances are a lot more abrupt within a small screen area at larger distances
@@ -85,28 +98,33 @@ void main()
float tc_mod = 0.5*(tc.x + tc.y); // mod(tc.x+tc.y,2)
tc_mod -= floor(tc_mod);
tc_mod *= 2.0;
- tc += ( (tc_mod - 0.5) * getKern(1).z * dlt * 0.5 );
+ tc += ( (tc_mod - 0.5) * kern[1].z * dlt * 0.5 );
for (int i = 1; i < 4; i++)
{
- vec2 samptc = tc + getKern(i).z*dlt;
- vec3 samppos = getPosition(samptc).xyz;
+ vec2 samptc = tc + kern[i].z*dlt;
+ vec3 samppos = getPosition(samptc).xyz;
+
float d = dot(norm.xyz, samppos.xyz-pos.xyz);// dist from plane
+
if (d*d <= pointplanedist_tolerance_pow2)
{
- col += texture2DRect(lightMap, samptc)*getKern(i).xyxx;
- defined_weight += getKern(i).xy;
+ col += texture2DRect(lightMap, samptc)*kern[i].xyxx;
+ defined_weight += kern[i].xy;
}
}
+
for (int i = 1; i < 4; i++)
{
- vec2 samptc = tc - getKern(i).z*dlt;
- vec3 samppos = getPosition(samptc).xyz;
+ vec2 samptc = tc - kern[i].z*dlt;
+ vec3 samppos = getPosition(samptc).xyz;
+
float d = dot(norm.xyz, samppos.xyz-pos.xyz);// dist from plane
+
if (d*d <= pointplanedist_tolerance_pow2)
{
- col += texture2DRect(lightMap, samptc)*getKern(i).xyxx;
- defined_weight += getKern(i).xy;
+ col += texture2DRect(lightMap, samptc)*kern[i].xyxx;
+ defined_weight += kern[i].xy;
}
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/blurLightV.glsl b/indra/newview/app_settings/shaders/class1/deferred/blurLightV.glsl
index 212f7e56ad..212f7e56ad 100644..100755
--- a/indra/newview/app_settings/shaders/class1/deferred/blurLightV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/blurLightV.glsl
diff --git a/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl b/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl
index 680eadb852..595c11fae2 100644..100755
--- a/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl
@@ -39,6 +39,12 @@ VARYING vec3 vary_mat2;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
+vec2 encode_normal(vec3 n)
+{
+ float f = sqrt(8 * n.z + 8);
+ return n.xy / f + 0.5;
+}
+
void main()
{
vec3 col = vertex_color.rgb * texture2D(diffuseMap, vary_texcoord0.xy).rgb;
@@ -52,5 +58,5 @@ void main()
frag_data[1] = vertex_color.aaaa; // spec
//frag_data[1] = vec4(vec3(vertex_color.a), vertex_color.a+(1.0-vertex_color.a)*vertex_color.a); // spec - from former class3 - maybe better, but not so well tested
vec3 nvn = normalize(tnorm);
- frag_data[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0);
+ frag_data[2] = vec4(encode_normal(nvn.xyz), vertex_color.a, 0.0);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/bumpSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/deferred/bumpSkinnedV.glsl
index 8ba75010a2..10144f3e16 100644..100755
--- a/indra/newview/app_settings/shaders/class1/deferred/bumpSkinnedV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/bumpSkinnedV.glsl
@@ -30,7 +30,7 @@ ATTRIBUTE vec3 position;
ATTRIBUTE vec4 diffuse_color;
ATTRIBUTE vec3 normal;
ATTRIBUTE vec2 texcoord0;
-ATTRIBUTE vec3 binormal;
+ATTRIBUTE vec4 tangent;
VARYING vec3 vary_mat0;
VARYING vec3 vary_mat1;
@@ -52,8 +52,8 @@ void main()
vec3 n = normalize((mat * vec4(normal.xyz+position.xyz, 1.0)).xyz-pos.xyz);
- vec3 b = normalize((mat * vec4(binormal.xyz+position.xyz, 1.0)).xyz-pos.xyz);
- vec3 t = cross(b, n);
+ vec3 t = normalize((mat * vec4(tangent.xyz+position.xyz, 1.0)).xyz-pos.xyz);
+ vec3 b = cross(n, t) * tangent.w;
vary_mat0 = vec3(t.x, b.x, n.x);
vary_mat1 = vec3(t.y, b.y, n.y);
diff --git a/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl b/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl
index c8d38bb8f7..9f9749394e 100644..100755
--- a/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl
@@ -31,7 +31,7 @@ ATTRIBUTE vec3 position;
ATTRIBUTE vec4 diffuse_color;
ATTRIBUTE vec3 normal;
ATTRIBUTE vec2 texcoord0;
-ATTRIBUTE vec3 binormal;
+ATTRIBUTE vec4 tangent;
VARYING vec3 vary_mat0;
VARYING vec3 vary_mat1;
@@ -46,8 +46,8 @@ void main()
vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
vec3 n = normalize(normal_matrix * normal);
- vec3 b = normalize(normal_matrix * binormal);
- vec3 t = cross(b, n);
+ vec3 t = normalize(normal_matrix * tangent.xyz);
+ vec3 b = cross(n, t) * tangent.w;
vary_mat0 = vec3(t.x, b.x, n.x);
vary_mat1 = vec3(t.y, b.y, n.y);
diff --git a/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl b/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl
index 1d8ca04ccd..1d8ca04ccd 100644..100755
--- a/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl
diff --git a/indra/newview/app_settings/shaders/class1/deferred/cloudsV.glsl b/indra/newview/app_settings/shaders/class1/deferred/cloudsV.glsl
index 17f425475c..17f425475c 100644..100755
--- a/indra/newview/app_settings/shaders/class1/deferred/cloudsV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/cloudsV.glsl
diff --git a/indra/newview/app_settings/shaders/class1/deferred/cofF.glsl b/indra/newview/app_settings/shaders/class1/deferred/cofF.glsl
index ccbc3c557c..ccbc3c557c 100644..100755
--- a/indra/newview/app_settings/shaders/class1/deferred/cofF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/cofF.glsl
diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl
index b2027d3a5d..7930b5d18b 100644..100755
--- a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl
@@ -37,6 +37,12 @@ VARYING vec3 vary_normal;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
+vec2 encode_normal(vec3 n)
+{
+ float f = sqrt(8 * n.z + 8);
+ return n.xy / f + 0.5;
+}
+
void main()
{
vec4 col = texture2D(diffuseMap, vary_texcoord0.xy) * vertex_color;
@@ -49,6 +55,6 @@ void main()
frag_data[0] = vec4(col.rgb, 0.0);
frag_data[1] = vec4(0,0,0,0); // spec
vec3 nvn = normalize(vary_normal);
- frag_data[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0);
+ frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, 0.0);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl
index ead384b07c..8525e13333 100644..100755
--- a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl
@@ -36,6 +36,12 @@ uniform float minimum_alpha;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
+vec2 encode_normal(vec3 n)
+{
+ float f = sqrt(8 * n.z + 8);
+ return n.xy / f + 0.5;
+}
+
void main()
{
vec4 col = diffuseLookup(vary_texcoord0.xy) * vertex_color;
@@ -44,9 +50,9 @@ void main()
{
discard;
}
-
+
frag_data[0] = vec4(col.rgb, 0.0);
frag_data[1] = vec4(0,0,0,0);
vec3 nvn = normalize(vary_normal);
- frag_data[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0);
+ frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, 0.0);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl
index f73fa6f231..37d70a2412 100644..100755
--- a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl
@@ -37,6 +37,12 @@ uniform sampler2D diffuseMap;
VARYING vec3 vary_normal;
VARYING vec2 vary_texcoord0;
+vec2 encode_normal(vec3 n)
+{
+ float f = sqrt(8 * n.z + 8);
+ return n.xy / f + 0.5;
+}
+
void main()
{
vec4 col = texture2D(diffuseMap, vary_texcoord0.xy);
@@ -49,6 +55,6 @@ void main()
frag_data[0] = vec4(col.rgb, 0.0);
frag_data[1] = vec4(0,0,0,0); // spec
vec3 nvn = normalize(vary_normal);
- frag_data[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0);
+ frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, 0.0);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl
index 227aa2aae3..6befb1bd8b 100644..100755
--- a/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl
@@ -35,6 +35,12 @@ VARYING vec3 vary_normal;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
+vec2 encode_normal(vec3 n)
+{
+ float f = sqrt(8 * n.z + 8);
+ return n.xy / f + 0.5;
+}
+
void main()
{
vec3 col = vertex_color.rgb * texture2D(diffuseMap, vary_texcoord0.xy).rgb;
@@ -42,6 +48,6 @@ void main()
frag_data[1] = vertex_color.aaaa; // spec
//frag_data[1] = vec4(vec3(vertex_color.a), vertex_color.a+(1.0-vertex_color.a)*vertex_color.a); // spec - from former class3 - maybe better, but not so well tested
vec3 nvn = normalize(vary_normal);
- frag_data[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0);
+ frag_data[2] = vec4(encode_normal(nvn.xyz), vertex_color.a, 0.0);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl
index d442e5403a..adc361d7a2 100644..100755
--- a/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl
@@ -33,13 +33,22 @@ VARYING vec3 vary_normal;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
+vec2 encode_normal(vec3 n)
+{
+ float f = sqrt(8 * n.z + 8);
+ return n.xy / f + 0.5;
+}
+
+
void main()
{
vec3 col = vertex_color.rgb * diffuseLookup(vary_texcoord0.xy).rgb;
+
+ vec3 spec;
+ spec.rgb = vec3(vertex_color.a);
frag_data[0] = vec4(col, 0.0);
- frag_data[1] = vertex_color.aaaa; // spec
- //frag_data[1] = vec4(vec3(vertex_color.a), vertex_color.a+(1.0-vertex_color.a)*vertex_color.a); // spec - from former class3 - maybe better, but not so well tested
+ frag_data[1] = vec4(spec, vertex_color.a); // spec
vec3 nvn = normalize(vary_normal);
- frag_data[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0);
+ frag_data[2] = vec4(encode_normal(nvn.xyz), vertex_color.a, 0.0);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseNoColorV.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseNoColorV.glsl
index 9461e3e32e..9461e3e32e 100644..100755
--- a/indra/newview/app_settings/shaders/class1/deferred/diffuseNoColorV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseNoColorV.glsl
diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseSkinnedV.glsl
index a74290bfcd..a74290bfcd 100644..100755
--- a/indra/newview/app_settings/shaders/class1/deferred/diffuseSkinnedV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseSkinnedV.glsl
diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl
index 76d29b1df7..3c026796c8 100644..100755
--- a/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl
@@ -47,6 +47,6 @@ void main()
passTextureIndex();
vary_normal = normalize(normal_matrix * normal);
-
+
vertex_color = diffuse_color;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/dofCombineF.glsl b/indra/newview/app_settings/shaders/class1/deferred/dofCombineF.glsl
index a425e5062e..a425e5062e 100644..100755
--- a/indra/newview/app_settings/shaders/class1/deferred/dofCombineF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/dofCombineF.glsl
diff --git a/indra/newview/app_settings/shaders/class1/deferred/emissiveF.glsl b/indra/newview/app_settings/shaders/class1/deferred/emissiveF.glsl
index 6aa4d7b4ed..ed02c4a481 100644..100755
--- a/indra/newview/app_settings/shaders/class1/deferred/emissiveF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/emissiveF.glsl
@@ -42,7 +42,7 @@ void main()
float shadow = 1.0;
vec4 color = diffuseLookup(vary_texcoord0.xy)*vertex_color;
-
+ color.rgb = pow(color.rgb, vec3(2.2));
color.rgb = fullbrightAtmosTransport(color.rgb);
color.rgb = fullbrightScaleSoftClip(color.rgb);
diff --git a/indra/newview/app_settings/shaders/class1/deferred/emissiveV.glsl b/indra/newview/app_settings/shaders/class1/deferred/emissiveV.glsl
index 115b04797f..115b04797f 100644..100755
--- a/indra/newview/app_settings/shaders/class1/deferred/emissiveV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/emissiveV.glsl
diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl
index 36433a5827..f22b16965c 100644..100755
--- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl
@@ -31,23 +31,147 @@ out vec4 frag_color;
#define frag_color gl_FragColor
#endif
+#if !HAS_DIFFUSE_LOOKUP
+uniform sampler2D diffuseMap;
+#endif
+
+VARYING vec3 vary_position;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
-vec3 fullbrightAtmosTransport(vec3 light);
-vec3 fullbrightScaleSoftClip(vec3 light);
+vec3 srgb_to_linear(vec3 cs)
+{
+ vec3 low_range = cs / vec3(12.92);
+ vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
+ bvec3 lte = lessThanEqual(cs,vec3(0.04045));
+
+#ifdef OLD_SELECT
+ vec3 result;
+ result.r = lte.r ? low_range.r : high_range.r;
+ result.g = lte.g ? low_range.g : high_range.g;
+ result.b = lte.b ? low_range.b : high_range.b;
+ return result;
+#else
+ return mix(high_range, low_range, lte);
+#endif
+
+}
+
+vec3 linear_to_srgb(vec3 cl)
+{
+ cl = clamp(cl, vec3(0), vec3(1));
+ vec3 low_range = cl * 12.92;
+ vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
+ bvec3 lt = lessThan(cl,vec3(0.0031308));
+
+#ifdef OLD_SELECT
+ vec3 result;
+ result.r = lt.r ? low_range.r : high_range.r;
+ result.g = lt.g ? low_range.g : high_range.g;
+ result.b = lt.b ? low_range.b : high_range.b;
+ return result;
+#else
+ return mix(high_range, low_range, lt);
+#endif
+
+}
+
+vec3 fullbrightAtmosTransportDeferred(vec3 light)
+{
+ return light;
+}
+
+vec3 fullbrightScaleSoftClipDeferred(vec3 light)
+{
+ //soft clip effect:
+ return light;
+}
+
+#ifdef HAS_ALPHA_MASK
+uniform float minimum_alpha;
+#endif
+
+#ifdef WATER_FOG
+uniform vec4 waterPlane;
+uniform vec4 waterFogColor;
+uniform float waterFogDensity;
+uniform float waterFogKS;
+
+vec4 applyWaterFogDeferred(vec3 pos, vec4 color)
+{
+ //normalize view vector
+ vec3 view = normalize(pos);
+ float es = -(dot(view, waterPlane.xyz));
+
+ //find intersection point with water plane and eye vector
+
+ //get eye depth
+ float e0 = max(-waterPlane.w, 0.0);
+
+ vec3 int_v = waterPlane.w > 0.0 ? view * waterPlane.w/es : vec3(0.0, 0.0, 0.0);
+
+ //get object depth
+ float depth = length(pos - int_v);
+
+ //get "thickness" of water
+ float l = max(depth, 0.1);
+
+ float kd = waterFogDensity;
+ float ks = waterFogKS;
+ vec4 kc = waterFogColor;
+
+ float F = 0.98;
+
+ float t1 = -kd * pow(F, ks * e0);
+ float t2 = kd + ks * es;
+ float t3 = pow(F, t2*l) - 1.0;
+
+ float L = min(t1/t2*t3, 1.0);
+
+ float D = pow(0.98, l*kd);
+
+ color.rgb = color.rgb * D + kc.rgb * L;
+ color.a = kc.a + color.a;
+
+ return color;
+}
+#endif
void main()
{
- float shadow = 1.0;
+#if HAS_DIFFUSE_LOOKUP
+ vec4 color = diffuseLookup(vary_texcoord0.xy);
+#else
+ vec4 color = texture2D(diffuseMap, vary_texcoord0.xy);
+#endif
- vec4 color = diffuseLookup(vary_texcoord0.xy)*vertex_color;
+ float final_alpha = color.a * vertex_color.a;
+
+#ifdef HAS_ALPHA_MASK
+ if (color.a < minimum_alpha)
+ {
+ discard;
+ }
+#endif
+
+ color.rgb *= vertex_color.rgb;
+ color.rgb = srgb_to_linear(color.rgb);
+ color.rgb = fullbrightAtmosTransportDeferred(color.rgb);
+ color.rgb = fullbrightScaleSoftClipDeferred(color.rgb);
- color.rgb = fullbrightAtmosTransport(color.rgb);
+ color.rgb = linear_to_srgb(color.rgb);
- color.rgb = fullbrightScaleSoftClip(color.rgb);
+#ifdef WATER_FOG
+ vec3 pos = vary_position;
+ vec4 fogged = applyWaterFogDeferred(pos, vec4(color.rgb, final_alpha));
+ color.rgb = fogged.rgb;
+ color.a = fogged.a;
+#else
+ color.a = final_alpha;
+#endif
- frag_color = color;
+ frag_color.rgb = color.rgb;
+ frag_color.a = color.a;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyF.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyF.glsl
new file mode 100644
index 0000000000..b0db9876d3
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyF.glsl
@@ -0,0 +1,72 @@
+/**
+ * @file fullbrightShinyF.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, 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$
+ */
+
+
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_color;
+#else
+#define frag_color gl_FragColor
+#endif
+
+#ifndef diffuseLookup
+uniform sampler2D diffuseMap;
+#endif
+
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
+VARYING vec3 vary_texcoord1;
+
+uniform samplerCube environmentMap;
+
+vec3 fullbrightShinyAtmosTransport(vec3 light);
+vec3 fullbrightScaleSoftClip(vec3 light);
+
+void main()
+{
+#if HAS_DIFFUSE_LOOKUP
+ vec4 color = diffuseLookup(vary_texcoord0.xy);
+#else
+ vec4 color = texture2D(diffuseMap, vary_texcoord0.xy);
+#endif
+
+
+ color.rgb *= vertex_color.rgb;
+
+ vec3 envColor = textureCube(environmentMap, vary_texcoord1.xyz).rgb;
+ color.rgb = mix(color.rgb, envColor.rgb, vertex_color.a);
+
+ color.rgb = pow(color.rgb,vec3(2.2f,2.2f,2.2f));
+
+ color.rgb = fullbrightShinyAtmosTransport(color.rgb);
+ color.rgb = fullbrightScaleSoftClip(color.rgb);
+
+ color.a = 1.0;
+
+ color.rgb = pow(color.rgb, vec3(1.0/2.2));
+
+ frag_color = color;
+}
+
diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyV.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyV.glsl
new file mode 100644
index 0000000000..34bd8d445a
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyV.glsl
@@ -0,0 +1,67 @@
+/**
+ * @file fullbrightShinyV.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, 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$
+ */
+
+uniform mat3 normal_matrix;
+uniform mat4 texture_matrix0;
+uniform mat4 texture_matrix1;
+uniform mat4 modelview_matrix;
+uniform mat4 modelview_projection_matrix;
+
+
+void calcAtmospherics(vec3 inPositionEye);
+
+uniform vec4 origin;
+
+
+
+ATTRIBUTE vec3 position;
+void passTextureIndex();
+ATTRIBUTE vec3 normal;
+ATTRIBUTE vec4 diffuse_color;
+ATTRIBUTE vec2 texcoord0;
+
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
+VARYING vec3 vary_texcoord1;
+
+
+void main()
+{
+ //transform vertex
+ vec4 vert = vec4(position.xyz,1.0);
+ passTextureIndex();
+ vec4 pos = (modelview_matrix * vert);
+ gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);
+
+ vec3 norm = normalize(normal_matrix * normal);
+ vec3 ref = reflect(pos.xyz, -norm);
+
+ vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
+ vary_texcoord1 = (texture_matrix1*vec4(ref,1.0)).xyz;
+
+ calcAtmospherics(pos.xyz);
+
+ vertex_color = diffuse_color;
+}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl
index 2e6982d101..8e899e3e0f 100644..100755
--- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl
@@ -40,6 +40,9 @@ vec3 atmosAffectDirectionalLight(float lightIntensity);
vec3 scaleDownLight(vec3 light);
vec3 scaleUpLight(vec3 light);
+#ifdef WATER_FOG
+VARYING vec3 vary_position;
+#endif
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
@@ -53,12 +56,14 @@ void main()
passTextureIndex();
gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);
-
+
+#ifdef WATER_FOG
+ vary_position = pos.xyz;
+#endif
+
vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
calcAtmospherics(pos.xyz);
-
- vertex_color = diffuse_color;
-
+ vertex_color = diffuse_color;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/fxaaF.glsl b/indra/newview/app_settings/shaders/class1/deferred/fxaaF.glsl
index e02a7b405b..a2b4b3b8c8 100644..100755
--- a/indra/newview/app_settings/shaders/class1/deferred/fxaaF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/fxaaF.glsl
@@ -24,6 +24,7 @@
*/
#extension GL_ARB_texture_rectangle : enable
+#extension GL_ARB_shader_texture_lod : enable
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
@@ -2093,7 +2094,6 @@ uniform sampler2D diffuseMap;
uniform vec2 rcp_screen_res;
uniform vec4 rcp_frame_opt;
uniform vec4 rcp_frame_opt2;
-uniform vec2 screen_res;
VARYING vec2 vary_fragcoord;
VARYING vec2 vary_tc;
diff --git a/indra/newview/app_settings/shaders/class1/deferred/giF.glsl b/indra/newview/app_settings/shaders/class1/deferred/giF.glsl
deleted file mode 100644
index da1b234240..0000000000
--- a/indra/newview/app_settings/shaders/class1/deferred/giF.glsl
+++ /dev/null
@@ -1,190 +0,0 @@
-/**
- * @file giF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, 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$
- */
-
-#extension GL_ARB_texture_rectangle : enable
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-uniform sampler2DRect depthMap;
-uniform sampler2DRect normalMap;
-uniform sampler2D noiseMap;
-
-uniform sampler2D diffuseGIMap;
-uniform sampler2D normalGIMap;
-uniform sampler2D depthGIMap;
-
-uniform sampler2D lightFunc;
-
-// Inputs
-VARYING vec2 vary_fragcoord;
-
-uniform vec2 screen_res;
-
-uniform mat4 inv_proj;
-uniform mat4 gi_mat; //gPipeline.mGIMatrix - eye space to sun space
-uniform mat4 gi_mat_proj; //gPipeline.mGIMatrixProj - eye space to projected sun space
-uniform mat4 gi_norm_mat; //gPipeline.mGINormalMatrix - eye space normal to sun space normal matrix
-uniform mat4 gi_inv_proj; //gPipeline.mGIInvProj - projected sun space to sun space
-uniform float gi_radius;
-uniform float gi_intensity;
-uniform int gi_samples;
-uniform vec2 gi_kern[25];
-uniform vec2 gi_scale;
-uniform vec3 gi_quad;
-uniform vec3 gi_spec;
-uniform float gi_direction_weight;
-uniform float gi_light_offset;
-
-vec4 getPosition(vec2 pos_screen)
-{
- float depth = texture2DRect(depthMap, pos_screen.xy).a;
- vec2 sc = pos_screen.xy*2.0;
- sc /= screen_res;
- sc -= vec2(1.0,1.0);
- vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
- vec4 pos = inv_proj * ndc;
- pos /= pos.w;
- pos.w = 1.0;
- return pos;
-}
-
-vec4 getGIPosition(vec2 gi_tc)
-{
- float depth = texture2D(depthGIMap, gi_tc).a;
- vec2 sc = gi_tc*2.0;
- sc -= vec2(1.0, 1.0);
- vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
- vec4 pos = gi_inv_proj*ndc;
- pos.xyz /= pos.w;
- pos.w = 1.0;
- return pos;
-}
-
-vec3 giAmbient(vec3 pos, vec3 norm)
-{
- vec4 gi_c = gi_mat_proj * vec4(pos, 1.0);
- gi_c.xyz /= gi_c.w;
-
- vec4 gi_pos = gi_mat*vec4(pos,1.0);
- vec3 gi_norm = (gi_norm_mat*vec4(norm,1.0)).xyz;
- gi_norm = normalize(gi_norm);
-
- vec2 tcx = gi_norm.xy;
- vec2 tcy = gi_norm.yx;
-
- vec4 eye_pos = gi_mat*vec4(0,0,0,1.0);
-
- vec3 eye_dir = normalize(gi_pos.xyz-eye_pos.xyz/eye_pos.w);
-
- //vec3 eye_dir = vec3(0,0,-1);
- //eye_dir = (gi_norm_mat*vec4(eye_dir, 1.0)).xyz;
- //eye_dir = normalize(eye_dir);
-
- //float round_x = gi_scale.x;
- //float round_y = gi_scale.y;
-
- vec3 debug = texture2D(normalGIMap, gi_c.xy).rgb*0.5+0.5;
- debug.xz = vec2(0.0,0.0);
- //debug = fract(debug);
-
- float round_x = 1.0/64.0;
- float round_y = 1.0/64.0;
-
- //gi_c.x = floor(gi_c.x/round_x+0.5)*round_x;
- //gi_c.y = floor(gi_c.y/round_y+0.5)*round_y;
-
- float fda = 0.0;
- vec3 fdiff = vec3(0,0,0);
-
- vec3 rcol = vec3(0,0,0);
-
- float fsa = 0.0;
-
- for (int i = -1; i < 2; i+=2 )
- {
- for (int j = -1; j < 2; j+=2)
- {
- vec2 tc = vec2(i, j)*0.75;
- vec3 nz = texture2D(noiseMap, vary_fragcoord.xy/128.0+tc*0.5).xyz;
- //tc += gi_norm.xy*nz.z;
- tc += nz.xy*2.0;
- tc /= gi_samples;
- tc += gi_c.xy;
-
- vec3 lnorm = -normalize(texture2D(normalGIMap, tc.xy).xyz*2.0-1.0);
- vec3 lpos = getGIPosition(tc.xy).xyz;
-
- vec3 at = lpos-gi_pos.xyz;
- float dist = dot(at,at);
- float da = clamp(1.0/(gi_spec.x*dist), 0.0, 1.0);
-
- if (da > 0.0)
- {
- //add angular attenuation
- vec3 ldir = at;
- float ang_atten = clamp(dot(ldir, gi_norm), 0.0, 1.0);
-
- float ld = -dot(ldir, lnorm);
-
- if (ang_atten > 0.0 && ld < 0.0)
- {
- vec3 diff = texture2D(diffuseGIMap, tc.xy).xyz;
- da = da*ang_atten;
- fda += da;
- fdiff += diff*da;
- }
- }
- }
- }
-
- fdiff /= max(gi_spec.y*fda, gi_quad.z);
- fdiff = clamp(fdiff, vec3(0), vec3(1));
-
- vec3 ret = fda*fdiff;
- //ret = ret*ret*gi_quad.x+ret*gi_quad.y+gi_quad.z;
-
- //fda *= nz.z;
-
- //rcol.rgb *= gi_intensity;
- //return rcol.rgb+vary_AmblitColor.rgb*0.25;
- //return vec4(debug, 0.0);
- //return vec4(fda*fdiff, 0.0);
- return clamp(ret,vec3(0.0), vec3(1.0));
- //return debug.xyz;
-}
-
-void main()
-{
- vec2 pos_screen = vary_fragcoord.xy;
- vec4 pos = getPosition(pos_screen);
- vec3 norm = texture2DRect(normalMap, pos_screen).xyz;
- norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
-
- frag_color.xyz = giAmbient(pos, norm);
-}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl b/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl
index bc0719cb82..f8fdde43f9 100644..100755
--- a/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl
@@ -38,6 +38,42 @@ uniform sampler2D specularMap;
VARYING vec2 vary_texcoord0;
+vec3 decode_normal (vec2 enc)
+{
+ vec2 fenc = enc*4-2;
+ float f = dot(fenc,fenc);
+ float g = sqrt(1-f/4);
+ vec3 n;
+ n.xy = fenc*g;
+ n.z = 1-f/2;
+ return n;
+}
+
+vec2 encode_normal(vec3 n)
+{
+ float f = sqrt(8 * n.z + 8);
+ return n.xy / f + 0.5;
+}
+
+vec3 linear_to_srgb(vec3 cl)
+{
+ cl = clamp(cl, vec3(0), vec3(1));
+ vec3 low_range = cl * 12.92;
+ vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
+ bvec3 lt = lessThan(cl,vec3(0.0031308));
+
+#ifdef OLD_SELECT
+ vec3 result;
+ result.r = lt.r ? low_range.r : high_range.r;
+ result.g = lt.g ? low_range.g : high_range.g;
+ result.b = lt.b ? low_range.b : high_range.b;
+ return result;
+#else
+ return mix(high_range, low_range, lt);
+#endif
+
+}
+
void main()
{
vec4 col = texture2D(diffuseMap, vary_texcoord0.xy);
@@ -47,7 +83,12 @@ void main()
discard;
}
- frag_data[0] = vec4(col.rgb, col.a * 0.005);
- frag_data[1] = texture2D(specularMap, vary_texcoord0.xy);
- frag_data[2] = vec4(texture2D(normalMap, vary_texcoord0.xy).xyz, 0.0);
+ vec4 norm = texture2D(normalMap, vary_texcoord0.xy);
+ vec4 spec = texture2D(specularMap, vary_texcoord0.xy);
+
+ col.rgb = linear_to_srgb(col.rgb);
+
+ frag_data[0] = vec4(col.rgb, 0.0);
+ frag_data[1] = spec;
+ frag_data[2] = vec4(norm.xy,0,0);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/impostorV.glsl b/indra/newview/app_settings/shaders/class1/deferred/impostorV.glsl
index 42266e9378..42266e9378 100644..100755
--- a/indra/newview/app_settings/shaders/class1/deferred/impostorV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/impostorV.glsl
diff --git a/indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl b/indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl
index dcf474824d..dcf474824d 100644..100755
--- a/indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl
diff --git a/indra/newview/app_settings/shaders/class1/deferred/luminanceV.glsl b/indra/newview/app_settings/shaders/class1/deferred/luminanceV.glsl
index f2dc60aa5d..f2dc60aa5d 100644..100755
--- a/indra/newview/app_settings/shaders/class1/deferred/luminanceV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/luminanceV.glsl
diff --git a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl
new file mode 100644
index 0000000000..07d28ed4cd
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl
@@ -0,0 +1,788 @@
+/**
+ * @file materialF.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, 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$
+ */
+
+#define DIFFUSE_ALPHA_MODE_IGNORE 0
+#define DIFFUSE_ALPHA_MODE_BLEND 1
+#define DIFFUSE_ALPHA_MODE_MASK 2
+#define DIFFUSE_ALPHA_MODE_EMISSIVE 3
+
+uniform float emissive_brightness;
+uniform float display_gamma;
+
+vec3 srgb_to_linear(vec3 cs)
+{
+ vec3 low_range = cs / vec3(12.92);
+ vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
+ bvec3 lte = lessThanEqual(cs,vec3(0.04045));
+
+#ifdef OLD_SELECT
+ vec3 result;
+ result.r = lte.r ? low_range.r : high_range.r;
+ result.g = lte.g ? low_range.g : high_range.g;
+ result.b = lte.b ? low_range.b : high_range.b;
+ return result;
+#else
+ return mix(high_range, low_range, lte);
+#endif
+
+}
+
+vec3 linear_to_srgb(vec3 cl)
+{
+ cl = clamp(cl, vec3(0), vec3(1));
+ vec3 low_range = cl * 12.92;
+ vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
+ bvec3 lt = lessThan(cl,vec3(0.0031308));
+
+#ifdef OLD_SELECT
+ vec3 result;
+ result.r = lt.r ? low_range.r : high_range.r;
+ result.g = lt.g ? low_range.g : high_range.g;
+ result.b = lt.b ? low_range.b : high_range.b;
+ return result;
+#else
+ return mix(high_range, low_range, lt);
+#endif
+
+}
+
+#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_color;
+#else
+#define frag_color gl_FragColor
+#endif
+
+#if HAS_SUN_SHADOW
+
+uniform sampler2DShadow shadowMap0;
+uniform sampler2DShadow shadowMap1;
+uniform sampler2DShadow shadowMap2;
+uniform sampler2DShadow shadowMap3;
+
+uniform mat4 shadow_matrix[6];
+uniform vec4 shadow_clip;
+uniform vec2 shadow_res;
+uniform float shadow_bias;
+
+float pcfShadow(sampler2DShadow shadowMap, vec4 stc)
+{
+ stc.xyz /= stc.w;
+ stc.z += shadow_bias;
+
+ stc.x = floor(stc.x*shadow_res.x + fract(stc.y*shadow_res.y*12345))/shadow_res.x; // add some chaotic jitter to X sample pos according to Y to disguise the snapping going on here
+
+ float cs = shadow2D(shadowMap, stc.xyz).x;
+ float shadow = cs;
+
+ shadow += shadow2D(shadowMap, stc.xyz+vec3(2.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x;
+ shadow += shadow2D(shadowMap, stc.xyz+vec3(1.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x;
+ shadow += shadow2D(shadowMap, stc.xyz+vec3(-1.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x;
+ shadow += shadow2D(shadowMap, stc.xyz+vec3(-2.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x;
+
+ return shadow*0.2;
+}
+
+#endif
+
+uniform samplerCube environmentMap;
+uniform sampler2D lightFunc;
+
+// Inputs
+uniform vec4 morphFactor;
+uniform vec3 camPosLocal;
+//uniform vec4 camPosWorld;
+uniform vec4 gamma;
+uniform vec4 lightnorm;
+uniform vec4 sunlight_color;
+uniform vec4 ambient;
+uniform vec4 blue_horizon;
+uniform vec4 blue_density;
+uniform float haze_horizon;
+uniform float haze_density;
+uniform float cloud_shadow;
+uniform float density_multiplier;
+uniform float distance_multiplier;
+uniform float max_y;
+uniform vec4 glow;
+uniform float scene_light_strength;
+uniform mat3 env_mat;
+uniform mat3 ssao_effect_mat;
+
+uniform vec3 sun_dir;
+VARYING vec2 vary_fragcoord;
+
+VARYING vec3 vary_position;
+
+vec3 vary_PositionEye;
+
+vec3 vary_SunlitColor;
+vec3 vary_AmblitColor;
+vec3 vary_AdditiveColor;
+vec3 vary_AtmosAttenuation;
+
+uniform mat4 inv_proj;
+uniform vec2 screen_res;
+
+uniform vec4 light_position[8];
+uniform vec3 light_direction[8];
+uniform vec3 light_attenuation[8];
+uniform vec3 light_diffuse[8];
+
+#ifdef WATER_FOG
+uniform vec4 waterPlane;
+uniform vec4 waterFogColor;
+uniform float waterFogDensity;
+uniform float waterFogKS;
+
+vec4 applyWaterFogDeferred(vec3 pos, vec4 color)
+{
+ //normalize view vector
+ vec3 view = normalize(pos);
+ float es = -(dot(view, waterPlane.xyz));
+
+ //find intersection point with water plane and eye vector
+
+ //get eye depth
+ float e0 = max(-waterPlane.w, 0.0);
+
+ vec3 int_v = waterPlane.w > 0.0 ? view * waterPlane.w/es : vec3(0.0, 0.0, 0.0);
+
+ //get object depth
+ float depth = length(pos - int_v);
+
+ //get "thickness" of water
+ float l = max(depth, 0.1);
+
+ float kd = waterFogDensity;
+ float ks = waterFogKS;
+ vec4 kc = waterFogColor;
+
+ float F = 0.98;
+
+ float t1 = -kd * pow(F, ks * e0);
+ float t2 = kd + ks * es;
+ float t3 = pow(F, t2*l) - 1.0;
+
+ float L = min(t1/t2*t3, 1.0);
+
+ float D = pow(0.98, l*kd);
+
+ color.rgb = color.rgb * D + kc.rgb * L;
+ color.a = kc.a + color.a;
+
+ return color;
+}
+#endif
+
+vec3 calcDirectionalLight(vec3 n, vec3 l)
+{
+ float a = max(dot(n,l),0.0);
+ return vec3(a,a,a);
+}
+
+
+vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 npos, vec3 diffuse, vec4 spec, vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight, inout float glare)
+{
+ //get light vector
+ vec3 lv = lp.xyz-v;
+
+ //get distance
+ float d = length(lv);
+
+ float da = 1.0;
+
+ vec3 col = vec3(0,0,0);
+
+ if (d > 0.0 && la > 0.0 && fa > 0.0)
+ {
+ //normalize light vector
+ lv = normalize(lv);
+
+ //distance attenuation
+ float dist = d/la;
+ float dist_atten = clamp(1.0-(dist-1.0*(1.0-fa))/fa, 0.0, 1.0);
+ dist_atten *= dist_atten;
+ dist_atten *= 2.0;
+
+ // spotlight coefficient.
+ float spot = max(dot(-ln, lv), is_pointlight);
+ da *= spot*spot; // GL_SPOT_EXPONENT=2
+
+ //angular attenuation
+ da *= max(dot(n, lv), 0.0);
+
+ float lit = max(da * dist_atten, 0.0);
+
+ col = light_col*lit*diffuse;
+
+ if (spec.a > 0.0)
+ {
+ //vec3 ref = dot(pos+lv, norm);
+ vec3 h = normalize(lv+npos);
+ float nh = dot(n, h);
+ float nv = dot(n, npos);
+ float vh = dot(npos, h);
+ float sa = nh;
+ float fres = pow(1 - dot(h, npos), 5)*0.4+0.5;
+
+ float gtdenom = 2 * nh;
+ float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh));
+
+ if (nh > 0.0)
+ {
+ float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da);
+ vec3 speccol = lit*scol*light_col.rgb*spec.rgb;
+ col += speccol;
+
+ float cur_glare = max(speccol.r, speccol.g);
+ cur_glare = max(cur_glare, speccol.b);
+ glare = max(glare, speccol.r);
+ glare += max(cur_glare, 0.0);
+ //col += spec.rgb;
+ }
+ }
+ }
+
+ return max(col, vec3(0.0,0.0,0.0));
+
+}
+
+vec4 getPosition_d(vec2 pos_screen, float depth)
+{
+ vec2 sc = pos_screen.xy*2.0;
+ sc /= screen_res;
+ sc -= vec2(1.0,1.0);
+ vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
+ vec4 pos = inv_proj * ndc;
+ pos /= pos.w;
+ pos.w = 1.0;
+ return pos;
+}
+
+#ifndef WATER_FOG
+vec3 getPositionEye()
+{
+ return vary_PositionEye;
+}
+#endif
+
+vec3 getSunlitColor()
+{
+ return vary_SunlitColor;
+}
+vec3 getAmblitColor()
+{
+ return vary_AmblitColor;
+}
+vec3 getAdditiveColor()
+{
+ return vary_AdditiveColor;
+}
+vec3 getAtmosAttenuation()
+{
+ return vary_AtmosAttenuation;
+}
+
+void setPositionEye(vec3 v)
+{
+ vary_PositionEye = v;
+}
+
+void setSunlitColor(vec3 v)
+{
+ vary_SunlitColor = v;
+}
+
+void setAmblitColor(vec3 v)
+{
+ vary_AmblitColor = v;
+}
+
+void setAdditiveColor(vec3 v)
+{
+ vary_AdditiveColor = v;
+}
+
+void setAtmosAttenuation(vec3 v)
+{
+ vary_AtmosAttenuation = v;
+}
+
+void calcAtmospherics(vec3 inPositionEye, float ambFactor) {
+
+ vec3 P = inPositionEye;
+ setPositionEye(P);
+
+ vec3 tmpLightnorm = lightnorm.xyz;
+
+ vec3 Pn = normalize(P);
+ float Plen = length(P);
+
+ vec4 temp1 = vec4(0);
+ vec3 temp2 = vec3(0);
+ vec4 blue_weight;
+ vec4 haze_weight;
+ vec4 sunlight = sunlight_color;
+ vec4 light_atten;
+
+ //sunlight attenuation effect (hue and brightness) due to atmosphere
+ //this is used later for sunlight modulation at various altitudes
+ light_atten = (blue_density + vec4(haze_density * 0.25)) * (density_multiplier * max_y);
+ //I had thought blue_density and haze_density should have equal weighting,
+ //but attenuation due to haze_density tends to seem too strong
+
+ temp1 = blue_density + vec4(haze_density);
+ blue_weight = blue_density / temp1;
+ haze_weight = vec4(haze_density) / temp1;
+
+ //(TERRAIN) compute sunlight from lightnorm only (for short rays like terrain)
+ temp2.y = max(0.0, tmpLightnorm.y);
+ temp2.y = 1. / temp2.y;
+ sunlight *= exp( - light_atten * temp2.y);
+
+ // main atmospheric scattering line integral
+ temp2.z = Plen * density_multiplier;
+
+ // Transparency (-> temp1)
+ // ATI Bugfix -- can't store temp1*temp2.z*distance_multiplier in a variable because the ati
+ // compiler gets confused.
+ temp1 = exp(-temp1 * temp2.z * distance_multiplier);
+
+ //final atmosphere attenuation factor
+ setAtmosAttenuation(temp1.rgb);
+
+ //compute haze glow
+ //(can use temp2.x as temp because we haven't used it yet)
+ temp2.x = dot(Pn, tmpLightnorm.xyz);
+ temp2.x = 1. - temp2.x;
+ //temp2.x is 0 at the sun and increases away from sun
+ temp2.x = max(temp2.x, .03); //was glow.y
+ //set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)
+ temp2.x *= glow.x;
+ //higher glow.x gives dimmer glow (because next step is 1 / "angle")
+ temp2.x = pow(temp2.x, glow.z);
+ //glow.z should be negative, so we're doing a sort of (1 / "angle") function
+
+ //add "minimum anti-solar illumination"
+ temp2.x += .25;
+
+ //increase ambient when there are more clouds
+ vec4 tmpAmbient = ambient + (vec4(1.) - ambient) * cloud_shadow * 0.5;
+
+ /* decrease value and saturation (that in HSV, not HSL) for occluded areas
+ * // for HSV color/geometry used here, see http://gimp-savvy.com/BOOK/index.html?node52.html
+ * // The following line of code performs the equivalent of:
+ * float ambAlpha = tmpAmbient.a;
+ * float ambValue = dot(vec3(tmpAmbient), vec3(0.577)); // projection onto <1/rt(3), 1/rt(3), 1/rt(3)>, the neutral white-black axis
+ * vec3 ambHueSat = vec3(tmpAmbient) - vec3(ambValue);
+ * tmpAmbient = vec4(RenderSSAOEffect.valueFactor * vec3(ambValue) + RenderSSAOEffect.saturationFactor *(1.0 - ambFactor) * ambHueSat, ambAlpha);
+ */
+ tmpAmbient = vec4(mix(ssao_effect_mat * tmpAmbient.rgb, tmpAmbient.rgb, ambFactor), tmpAmbient.a);
+
+ //haze color
+ setAdditiveColor(
+ vec3(blue_horizon * blue_weight * (sunlight*(1.-cloud_shadow) + tmpAmbient)
+ + (haze_horizon * haze_weight) * (sunlight*(1.-cloud_shadow) * temp2.x
+ + tmpAmbient)));
+
+ //brightness of surface both sunlight and ambient
+ setSunlitColor(vec3(sunlight * .5));
+ setAmblitColor(vec3(tmpAmbient * .25));
+ setAdditiveColor(getAdditiveColor() * vec3(1.0 - temp1));
+}
+
+vec3 atmosLighting(vec3 light)
+{
+ light *= getAtmosAttenuation().r;
+ light += getAdditiveColor();
+ return (2.0 * light);
+}
+
+vec3 atmosTransport(vec3 light) {
+ light *= getAtmosAttenuation().r;
+ light += getAdditiveColor() * 2.0;
+ return light;
+}
+vec3 atmosGetDiffuseSunlightColor()
+{
+ return getSunlitColor();
+}
+
+vec3 scaleDownLight(vec3 light)
+{
+ return (light / vec3(scene_light_strength, scene_light_strength, scene_light_strength));
+}
+
+vec3 scaleUpLight(vec3 light)
+{
+ return (light * vec3(scene_light_strength, scene_light_strength, scene_light_strength));
+}
+
+vec3 atmosAmbient(vec3 light)
+{
+ return getAmblitColor() + (light * vec3(0.5f, 0.5f, 0.5f));
+}
+
+vec3 atmosAffectDirectionalLight(float lightIntensity)
+{
+ return getSunlitColor() * vec3(lightIntensity, lightIntensity, lightIntensity);
+}
+
+vec3 scaleSoftClip(vec3 light)
+{
+ //soft clip effect:
+ vec3 zeroes = vec3(0.0f, 0.0f, 0.0f);
+ vec3 ones = vec3(1.0f, 1.0f, 1.0f);
+
+ light = ones - clamp(light, zeroes, ones);
+ light = ones - pow(light, gamma.xxx);
+
+ return light;
+}
+
+vec3 fullbrightAtmosTransport(vec3 light) {
+ float brightness = dot(light.rgb, vec3(0.33333));
+
+ return mix(atmosTransport(light.rgb), light.rgb + getAdditiveColor().rgb, brightness * brightness);
+}
+
+vec3 fullbrightScaleSoftClip(vec3 light)
+{
+ //soft clip effect:
+ return light;
+}
+
+#else
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_data[3];
+#else
+#define frag_data gl_FragData
+#endif
+#endif
+
+uniform sampler2D diffuseMap;
+
+#if HAS_NORMAL_MAP
+uniform sampler2D bumpMap;
+#endif
+
+#if HAS_SPECULAR_MAP
+uniform sampler2D specularMap;
+
+VARYING vec2 vary_texcoord2;
+#endif
+
+uniform float env_intensity;
+uniform vec4 specular_color; // specular color RGB and specular exponent (glossiness) in alpha
+
+#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_MASK)
+uniform float minimum_alpha;
+#endif
+
+#if HAS_NORMAL_MAP
+VARYING vec3 vary_mat0;
+VARYING vec3 vary_mat1;
+VARYING vec3 vary_mat2;
+VARYING vec2 vary_texcoord1;
+#else
+VARYING vec3 vary_normal;
+#endif
+
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
+
+vec2 encode_normal(vec3 n)
+{
+ float f = sqrt(8 * n.z + 8);
+ return n.xy / f + 0.5;
+}
+
+vec3 decode_normal (vec2 enc)
+{
+ vec2 fenc = enc*4-2;
+ float f = dot(fenc,fenc);
+ float g = sqrt(1-f/4);
+ vec3 n;
+ n.xy = fenc*g;
+ n.z = 1-f/2;
+ return n;
+}
+
+void main()
+{
+ vec4 diffcol = texture2D(diffuseMap, vary_texcoord0.xy);
+ diffcol.rgb *= vertex_color.rgb;
+
+#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_MASK)
+ if (diffcol.a < minimum_alpha)
+ {
+ discard;
+ }
+#endif
+
+#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
+ vec3 gamma_diff = diffcol.rgb;
+ diffcol.rgb = srgb_to_linear(diffcol.rgb);
+#endif
+
+#if HAS_SPECULAR_MAP
+ vec4 spec = texture2D(specularMap, vary_texcoord2.xy);
+ spec.rgb *= specular_color.rgb;
+#else
+ vec4 spec = vec4(specular_color.rgb, 1.0);
+#endif
+
+#if HAS_NORMAL_MAP
+ vec4 norm = texture2D(bumpMap, vary_texcoord1.xy);
+
+ norm.xyz = norm.xyz * 2 - 1;
+
+ vec3 tnorm = vec3(dot(norm.xyz,vary_mat0),
+ dot(norm.xyz,vary_mat1),
+ dot(norm.xyz,vary_mat2));
+#else
+ vec4 norm = vec4(0,0,0,1.0);
+ vec3 tnorm = vary_normal;
+#endif
+
+ norm.xyz = tnorm;
+ norm.xyz = normalize(norm.xyz);
+
+ vec2 abnormal = encode_normal(norm.xyz);
+ norm.xyz = decode_normal(abnormal.xy);
+
+ vec4 final_color = diffcol;
+
+#if (DIFFUSE_ALPHA_MODE != DIFFUSE_ALPHA_MODE_EMISSIVE)
+ final_color.a = emissive_brightness;
+#else
+ final_color.a = max(final_color.a, emissive_brightness);
+#endif
+
+ vec4 final_specular = spec;
+#if HAS_SPECULAR_MAP
+ vec4 final_normal = vec4(encode_normal(normalize(tnorm)), env_intensity * spec.a, 0.0);
+ final_specular.a = specular_color.a * norm.a;
+#else
+ vec4 final_normal = vec4(encode_normal(normalize(tnorm)), env_intensity, 0.0);
+ final_specular.a = specular_color.a;
+#endif
+
+
+#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
+ //forward rendering, output just lit RGBA
+ vec3 pos = vary_position;
+
+#if HAS_SUN_SHADOW
+ float shadow = 0.0;
+
+ vec4 spos = vec4(pos,1.0);
+
+ if (spos.z > -shadow_clip.w)
+ {
+ vec4 lpos;
+
+ vec4 near_split = shadow_clip*-0.75;
+ vec4 far_split = shadow_clip*-1.25;
+ vec4 transition_domain = near_split-far_split;
+ float weight = 0.0;
+
+ if (spos.z < near_split.z)
+ {
+ lpos = shadow_matrix[3]*spos;
+
+ float w = 1.0;
+ w -= max(spos.z-far_split.z, 0.0)/transition_domain.z;
+ shadow += pcfShadow(shadowMap3, lpos)*w;
+ weight += w;
+ shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0);
+ }
+
+ if (spos.z < near_split.y && spos.z > far_split.z)
+ {
+ lpos = shadow_matrix[2]*spos;
+
+ float w = 1.0;
+ w -= max(spos.z-far_split.y, 0.0)/transition_domain.y;
+ w -= max(near_split.z-spos.z, 0.0)/transition_domain.z;
+ shadow += pcfShadow(shadowMap2, lpos)*w;
+ weight += w;
+ }
+
+ if (spos.z < near_split.x && spos.z > far_split.y)
+ {
+ lpos = shadow_matrix[1]*spos;
+
+ float w = 1.0;
+ w -= max(spos.z-far_split.x, 0.0)/transition_domain.x;
+ w -= max(near_split.y-spos.z, 0.0)/transition_domain.y;
+ shadow += pcfShadow(shadowMap1, lpos)*w;
+ weight += w;
+ }
+
+ if (spos.z > far_split.x)
+ {
+ lpos = shadow_matrix[0]*spos;
+
+ float w = 1.0;
+ w -= max(near_split.x-spos.z, 0.0)/transition_domain.x;
+
+ shadow += pcfShadow(shadowMap0, lpos)*w;
+ weight += w;
+ }
+
+
+ shadow /= weight;
+ }
+ else
+ {
+ shadow = 1.0;
+ }
+#else
+ float shadow = 1.0;
+#endif
+
+ spec = final_specular;
+ vec4 diffuse = final_color;
+ float envIntensity = final_normal.z;
+
+ vec3 col = vec3(0.0f,0.0f,0.0f);
+
+ float bloom = 0.0;
+ calcAtmospherics(pos.xyz, 1.0);
+
+ vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
+
+ float da =dot(norm.xyz, sun_dir.xyz);
+
+ float final_da = da;
+ final_da = min(final_da, shadow);
+ //final_da = max(final_da, diffuse.a);
+ final_da = max(final_da, 0.0f);
+ final_da = min(final_da, 1.0f);
+ final_da = pow(final_da, 1.0/1.3);
+
+ col.rgb = atmosAmbient(col);
+
+ float ambient = min(abs(da), 1.0);
+ ambient *= 0.5;
+ ambient *= ambient;
+ ambient = (1.0-ambient);
+
+ col.rgb *= ambient;
+
+ col.rgb = col.rgb + atmosAffectDirectionalLight(final_da);
+
+ col.rgb *= gamma_diff.rgb;
+
+
+ float glare = 0.0;
+
+ if (spec.a > 0.0) // specular reflection
+ {
+ // the old infinite-sky shiny reflection
+ //
+
+ float sa = dot(refnormpersp, sun_dir.xyz);
+ vec3 dumbshiny = vary_SunlitColor*shadow*(texture2D(lightFunc, vec2(sa, spec.a)).r);
+
+ // add the two types of shiny together
+ vec3 spec_contrib = dumbshiny * spec.rgb;
+ bloom = dot(spec_contrib, spec_contrib) / 6;
+
+ glare = max(spec_contrib.r, spec_contrib.g);
+ glare = max(glare, spec_contrib.b);
+
+ col += spec_contrib;
+ }
+
+
+ col = mix(col.rgb, diffcol.rgb, diffuse.a);
+
+ if (envIntensity > 0.0)
+ {
+ //add environmentmap
+ vec3 env_vec = env_mat * refnormpersp;
+
+ vec3 refcol = textureCube(environmentMap, env_vec).rgb;
+
+ col = mix(col.rgb, refcol,
+ envIntensity);
+
+ float cur_glare = max(refcol.r, refcol.g);
+ cur_glare = max(cur_glare, refcol.b);
+ cur_glare *= envIntensity*4.0;
+ glare += cur_glare;
+ }
+
+ //col = mix(atmosLighting(col), fullbrightAtmosTransport(col), diffuse.a);
+ //col = mix(scaleSoftClip(col), fullbrightScaleSoftClip(col), diffuse.a);
+
+ col = atmosLighting(col);
+ col = scaleSoftClip(col);
+
+ //convert to linear space before adding local lights
+ col = srgb_to_linear(col);
+
+ vec3 npos = normalize(-pos.xyz);
+
+ vec3 light = vec3(0,0,0);
+
+ #define LIGHT_LOOP(i) light.rgb += calcPointLightOrSpotLight(light_diffuse[i].rgb, npos, diffuse.rgb, final_specular, pos.xyz, norm.xyz, light_position[i], light_direction[i].xyz, light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z, glare);
+
+ LIGHT_LOOP(1)
+ LIGHT_LOOP(2)
+ LIGHT_LOOP(3)
+ LIGHT_LOOP(4)
+ LIGHT_LOOP(5)
+ LIGHT_LOOP(6)
+ LIGHT_LOOP(7)
+
+ col.rgb += light.rgb;
+
+ glare = min(glare, 1.0);
+ float al = max(diffcol.a,glare)*vertex_color.a;
+
+ //convert to gamma space for display on screen
+ col.rgb = linear_to_srgb(col.rgb);
+
+#ifdef WATER_FOG
+ vec4 temp = applyWaterFogDeferred(pos, vec4(col.rgb, al));
+ col.rgb = temp.rgb;
+ al = temp.a;
+#endif
+
+ frag_color.rgb = col.rgb;
+ frag_color.a = al;
+
+#else
+ frag_data[0] = final_color;
+ frag_data[1] = final_specular; // XYZ = Specular color. W = Specular exponent.
+ frag_data[2] = final_normal; // XY = Normal. Z = Env. intensity.
+#endif
+}
+
diff --git a/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl b/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl
new file mode 100644
index 0000000000..393d1e69da
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl
@@ -0,0 +1,145 @@
+/**
+ * @file bumpV.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, 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$
+ */
+
+#define DIFFUSE_ALPHA_MODE_IGNORE 0
+#define DIFFUSE_ALPHA_MODE_BLEND 1
+#define DIFFUSE_ALPHA_MODE_MASK 2
+#define DIFFUSE_ALPHA_MODE_EMISSIVE 3
+
+#if HAS_SKIN
+uniform mat4 modelview_matrix;
+uniform mat4 projection_matrix;
+mat4 getObjectSkinnedTransform();
+#else
+uniform mat3 normal_matrix;
+uniform mat4 modelview_projection_matrix;
+#endif
+
+#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
+
+#if !HAS_SKIN
+uniform mat4 modelview_matrix;
+#endif
+
+VARYING vec3 vary_position;
+
+#endif
+
+uniform mat4 texture_matrix0;
+
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec4 diffuse_color;
+ATTRIBUTE vec3 normal;
+ATTRIBUTE vec2 texcoord0;
+
+
+#if HAS_NORMAL_MAP
+ATTRIBUTE vec4 tangent;
+ATTRIBUTE vec2 texcoord1;
+
+VARYING vec3 vary_mat0;
+VARYING vec3 vary_mat1;
+VARYING vec3 vary_mat2;
+
+VARYING vec2 vary_texcoord1;
+#else
+VARYING vec3 vary_normal;
+#endif
+
+#if HAS_SPECULAR_MAP
+ATTRIBUTE vec2 texcoord2;
+VARYING vec2 vary_texcoord2;
+#endif
+
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
+
+void main()
+{
+#if HAS_SKIN
+ mat4 mat = getObjectSkinnedTransform();
+
+ mat = modelview_matrix * mat;
+
+ vec3 pos = (mat*vec4(position.xyz,1.0)).xyz;
+
+#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
+ vary_position = pos;
+#endif
+
+ gl_Position = projection_matrix*vec4(pos,1.0);
+
+#else
+ //transform vertex
+ gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
+
+#endif
+
+ vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
+
+#if HAS_NORMAL_MAP
+ vary_texcoord1 = (texture_matrix0 * vec4(texcoord1,0,1)).xy;
+#endif
+
+#if HAS_SPECULAR_MAP
+ vary_texcoord2 = (texture_matrix0 * vec4(texcoord2,0,1)).xy;
+#endif
+
+#if HAS_SKIN
+ vec3 n = normalize((mat*vec4(normal.xyz+position.xyz,1.0)).xyz-pos.xyz);
+#if HAS_NORMAL_MAP
+ vec3 t = normalize((mat*vec4(tangent.xyz+position.xyz,1.0)).xyz-pos.xyz);
+ vec3 b = cross(n, t)*tangent.w;
+
+ vary_mat0 = vec3(t.x, b.x, n.x);
+ vary_mat1 = vec3(t.y, b.y, n.y);
+ vary_mat2 = vec3(t.z, b.z, n.z);
+#else //HAS_NORMAL_MAP
+vary_normal = n;
+#endif //HAS_NORMAL_MAP
+#else //HAS_SKIN
+ vec3 n = normalize(normal_matrix * normal);
+#if HAS_NORMAL_MAP
+ vec3 t = normalize(normal_matrix * tangent.xyz);
+ vec3 b = cross(n,t)*tangent.w;
+ //vec3 t = cross(b,n) * binormal.w;
+
+ vary_mat0 = vec3(t.x, b.x, n.x);
+ vary_mat1 = vec3(t.y, b.y, n.y);
+ vary_mat2 = vec3(t.z, b.z, n.z);
+#else //HAS_NORMAL_MAP
+ vary_normal = n;
+#endif //HAS_NORMAL_MAP
+#endif //HAS_SKIN
+
+ vertex_color = diffuse_color;
+
+#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
+#if !HAS_SKIN
+ vary_position = (modelview_matrix*vec4(position.xyz, 1.0)).xyz;
+#endif
+#endif
+}
+
diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl
index 4d01eeb64e..236567219b 100644..100755
--- a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl
@@ -45,9 +45,8 @@ uniform float sun_wash;
uniform int light_count;
-#define MAX_LIGHT_COUNT 16
-uniform vec4 light[MAX_LIGHT_COUNT];
-uniform vec4 light_col[MAX_LIGHT_COUNT];
+uniform vec4 light[LIGHT_COUNT];
+uniform vec4 light_col[LIGHT_COUNT];
VARYING vec4 vary_fragcoord;
uniform vec2 screen_res;
@@ -56,6 +55,23 @@ uniform float far_z;
uniform mat4 inv_proj;
+vec2 encode_normal(vec3 n)
+{
+ float f = sqrt(8 * n.z + 8);
+ return n.xy / f + 0.5;
+}
+
+vec3 decode_normal (vec2 enc)
+{
+ vec2 fenc = enc*4-2;
+ float f = dot(fenc,fenc);
+ float g = sqrt(1-f/4);
+ vec3 n;
+ n.xy = fenc*g;
+ n.z = 1-f/2;
+ return n;
+}
+
vec4 getPosition(vec2 pos_screen)
{
float depth = texture2DRect(depthMap, pos_screen.xy).r;
@@ -79,70 +95,70 @@ void main()
}
vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
- norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
+ norm = decode_normal(norm.xy); // unpack norm
norm = normalize(norm);
vec4 spec = texture2DRect(specularRect, frag.xy);
vec3 diff = texture2DRect(diffuseRect, frag.xy).rgb;
+
float noise = texture2D(noiseMap, frag.xy/128.0).b;
vec3 out_col = vec3(0,0,0);
vec3 npos = normalize(-pos);
// As of OSX 10.6.7 ATI Apple's crash when using a variable size loop
- for (int i = 0; i < MAX_LIGHT_COUNT; ++i)
+ for (int i = 0; i < LIGHT_COUNT; ++i)
{
- bool light_contrib = (i < light_count);
-
vec3 lv = light[i].xyz-pos;
- float dist2 = dot(lv,lv);
- dist2 /= light[i].w;
- if (dist2 > 1.0)
+ float dist = length(lv);
+ dist /= light[i].w;
+ if (dist <= 1.0)
{
- light_contrib = false;
- }
-
float da = dot(norm, lv);
- if (da < 0.0)
- {
- light_contrib = false;
- }
-
- if (light_contrib)
+ if (da > 0.0)
{
lv = normalize(lv);
da = dot(norm, lv);
-
+
float fa = light_col[i].a+1.0;
- float dist_atten = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0);
+ float dist_atten = clamp(1.0-(dist-1.0*(1.0-fa))/fa, 0.0, 1.0);
+ dist_atten *= dist_atten;
+ dist_atten *= 2.0;
+
dist_atten *= noise;
float lit = da * dist_atten;
-
+
vec3 col = light_col[i].rgb*lit*diff;
+
//vec3 col = vec3(dist2, light_col[i].a, lit);
if (spec.a > 0.0)
{
+ lit = min(da*6.0, 1.0) * dist_atten;
//vec3 ref = dot(pos+lv, norm);
-
- float sa = dot(normalize(lv+npos),norm);
-
- if (sa > 0.0)
+ vec3 h = normalize(lv+npos);
+ float nh = dot(norm, h);
+ float nv = dot(norm, npos);
+ float vh = dot(npos, h);
+ float sa = nh;
+ float fres = pow(1 - dot(h, npos), 5)*0.4+0.5;
+
+ float gtdenom = 2 * nh;
+ float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh));
+
+ if (nh > 0.0)
{
- sa = 6 * texture2D(lightFunc, vec2(sa, spec.a)).r * min(dist_atten*4.0, 1.0);
- sa *= noise;
- col += da*sa*light_col[i].rgb*spec.rgb;
+ float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da);
+ col += lit*scol*light_col[i].rgb*spec.rgb;
+ //col += spec.rgb;
}
}
out_col += col;
}
}
-
- if (dot(out_col, out_col) <= 0.0)
- {
- discard;
}
+
frag_color.rgb = out_col;
frag_color.a = 0.0;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightV.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightV.glsl
index eefefa640d..eefefa640d 100644..100755
--- a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightV.glsl
diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl
index 75de47614c..0e6ab80d4d 100644..100755
--- a/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl
@@ -32,6 +32,7 @@ out vec4 frag_color;
//class 1 -- no shadows
#extension GL_ARB_texture_rectangle : enable
+#extension GL_ARB_shader_texture_lod : enable
uniform sampler2DRect diffuseRect;
uniform sampler2DRect specularRect;
@@ -40,6 +41,7 @@ uniform sampler2DRect normalMap;
uniform samplerCube environmentMap;
uniform sampler2D noiseMap;
uniform sampler2D projectionMap;
+uniform sampler2D lightFunc;
uniform mat4 proj_mat; //screen space to light space
uniform float proj_near; //near clip for projection
@@ -55,8 +57,6 @@ uniform float far_clip;
uniform vec3 proj_origin; //origin of projection to be used for angular attenuation
uniform float sun_wash;
-uniform int proj_shadow_idx;
-uniform float shadow_fade;
uniform vec3 center;
uniform vec3 color;
@@ -68,9 +68,64 @@ uniform vec2 screen_res;
uniform mat4 inv_proj;
+vec2 encode_normal(vec3 n)
+{
+ float f = sqrt(8 * n.z + 8);
+ return n.xy / f + 0.5;
+}
+
+vec3 decode_normal (vec2 enc)
+{
+ vec2 fenc = enc*4-2;
+ float f = dot(fenc,fenc);
+ float g = sqrt(1-f/4);
+ vec3 n;
+ n.xy = fenc*g;
+ n.z = 1-f/2;
+ return n;
+}
+vec3 srgb_to_linear(vec3 cs)
+{
+ vec3 low_range = cs / vec3(12.92);
+ vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
+ bvec3 lte = lessThanEqual(cs,vec3(0.04045));
+
+#ifdef OLD_SELECT
+ vec3 result;
+ result.r = lte.r ? low_range.r : high_range.r;
+ result.g = lte.g ? low_range.g : high_range.g;
+ result.b = lte.b ? low_range.b : high_range.b;
+ return result;
+#else
+ return mix(high_range, low_range, lte);
+#endif
+
+}
+
+vec3 linear_to_srgb(vec3 cl)
+{
+ cl = clamp(cl, vec3(0), vec3(1));
+ vec3 low_range = cl * 12.92;
+ vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
+ bvec3 lt = lessThan(cl,vec3(0.0031308));
+
+#ifdef OLD_SELECT
+ vec3 result;
+ result.r = lt.r ? low_range.r : high_range.r;
+ result.g = lt.g ? low_range.g : high_range.g;
+ result.b = lt.b ? low_range.b : high_range.b;
+ return result;
+#else
+ return mix(high_range, low_range, lt);
+#endif
+
+}
+
+
vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
{
vec4 ret = texture2DLod(projectionMap, tc, lod);
+ ret.rgb = srgb_to_linear(ret.rgb);
vec2 dist = tc-vec2(0.5);
@@ -86,6 +141,7 @@ vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)
{
vec4 ret = texture2DLod(projectionMap, tc, lod);
+ ret.rgb = srgb_to_linear(ret.rgb);
vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
@@ -103,6 +159,7 @@ vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)
vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)
{
vec4 ret = texture2DLod(projectionMap, tc, lod);
+ ret.rgb = srgb_to_linear(ret.rgb);
vec2 dist = tc-vec2(0.5);
@@ -136,14 +193,17 @@ void main()
vec3 pos = getPosition(frag.xy).xyz;
vec3 lv = center.xyz-pos.xyz;
- float dist2 = dot(lv,lv);
- dist2 /= size;
- if (dist2 > 1.0)
+ float dist = length(lv);
+ dist /= size;
+ if (dist > 1.0)
{
discard;
}
- vec3 norm = texture2DRect(normalMap, frag.xy).xyz*2.0-1.0;
+ vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
+ float envIntensity = norm.z;
+
+ norm = decode_normal(norm.xy);
norm = normalize(norm);
float l_dist = -dot(lv, proj_n);
@@ -157,7 +217,10 @@ void main()
proj_tc.xyz /= proj_tc.w;
float fa = falloff+1.0;
- float dist_atten = min(1.0-(dist2-1.0*(1.0-fa))/fa, 1.0);
+ float dist_atten = min(1.0-(dist-1.0*(1.0-fa))/fa, 1.0);
+ dist_atten *= dist_atten;
+ dist_atten *= 2.0;
+
if (dist_atten <= 0.0)
{
discard;
@@ -170,7 +233,8 @@ void main()
vec3 col = vec3(0,0,0);
vec3 diff_tex = texture2DRect(diffuseRect, frag.xy).rgb;
-
+ vec3 dlit = vec3(0, 0, 0);
+
float noise = texture2D(noiseMap, frag.xy/128.0).b;
if (proj_tc.z > 0.0 &&
proj_tc.x < 1.0 &&
@@ -188,14 +252,13 @@ void main()
vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod);
- vec3 lcol = color.rgb * plcol.rgb * plcol.a;
+ dlit = color.rgb * plcol.rgb * plcol.a;
lit = da * dist_atten * noise;
- col = lcol*lit*diff_tex;
+ col = dlit*lit*diff_tex;
amb_da += (da*0.5)*proj_ambiance;
}
-
//float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0);
vec4 amb_plcol = texture2DLodAmbient(projectionMap, proj_tc.xy, proj_lod);
@@ -204,14 +267,39 @@ void main()
amb_da *= dist_atten * noise;
amb_da = min(amb_da, 1.0-lit);
-
- col += amb_da*color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a;
+ col += amb_da*color.rgb*diff_tex*amb_plcol.rgb*amb_plcol.a;
}
vec4 spec = texture2DRect(specularRect, frag.xy);
+
if (spec.a > 0.0)
{
+ dlit *= min(da*6.0, 1.0) * dist_atten;
+
+ vec3 npos = -normalize(pos);
+
+ //vec3 ref = dot(pos+lv, norm);
+ vec3 h = normalize(lv+npos);
+ float nh = dot(norm, h);
+ float nv = dot(norm, npos);
+ float vh = dot(npos, h);
+ float sa = nh;
+ float fres = pow(1 - dot(h, npos), 5)*0.4+0.5;
+
+ float gtdenom = 2 * nh;
+ float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh));
+
+ if (nh > 0.0)
+ {
+ float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da);
+ col += dlit*scol*spec.rgb;
+ //col += spec.rgb;
+ }
+ }
+
+ if (envIntensity > 0.0)
+ {
vec3 ref = reflect(normalize(pos), norm);
//project from point pos in direction ref to plane proj_p, proj_n
@@ -223,12 +311,10 @@ void main()
vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds;
vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0));
-
+ stc /= stc.w;
if (stc.z > 0.0)
{
- stc.xy /= stc.w;
-
- float fatten = clamp(spec.a*spec.a+spec.a*0.5, 0.25, 1.0);
+ float fatten = clamp(envIntensity*envIntensity+envIntensity*0.25, 0.25, 1.0);
stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5);
@@ -237,8 +323,7 @@ void main()
stc.x > 0.0 &&
stc.y > 0.0)
{
- vec4 scol = texture2DLodSpecular(projectionMap, stc.xy, proj_lod-spec.a*proj_lod);
- col += dist_atten*scol.rgb*color.rgb*scol.a*spec.rgb;
+ col += color.rgb*texture2DLodSpecular(projectionMap, stc.xy, proj_lod).rgb*spec.rgb;
}
}
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/normgenF.glsl b/indra/newview/app_settings/shaders/class1/deferred/normgenF.glsl
index 62cfa5c316..62cfa5c316 100644..100755
--- a/indra/newview/app_settings/shaders/class1/deferred/normgenF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/normgenF.glsl
diff --git a/indra/newview/app_settings/shaders/class1/deferred/normgenV.glsl b/indra/newview/app_settings/shaders/class1/deferred/normgenV.glsl
index 9bceae05b7..9bceae05b7 100644..100755
--- a/indra/newview/app_settings/shaders/class1/deferred/normgenV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/normgenV.glsl
diff --git a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl
index 19800a8b8e..106d48bd71 100644..100755
--- a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl
@@ -42,17 +42,35 @@ uniform sampler2DRect depthMap;
uniform vec3 env_mat[3];
uniform float sun_wash;
-uniform vec3 center;
uniform vec3 color;
uniform float falloff;
uniform float size;
VARYING vec4 vary_fragcoord;
+VARYING vec3 trans_center;
+
uniform vec2 screen_res;
uniform mat4 inv_proj;
uniform vec4 viewport;
+vec2 encode_normal(vec3 n)
+{
+ float f = sqrt(8 * n.z + 8);
+ return n.xy / f + 0.5;
+}
+
+vec3 decode_normal (vec2 enc)
+{
+ vec2 fenc = enc*4-2;
+ float f = dot(fenc,fenc);
+ float g = sqrt(1-f/4);
+ vec3 n;
+ n.xy = fenc*g;
+ n.z = 1-f/2;
+ return n;
+}
+
vec4 getPosition(vec2 pos_screen)
{
float depth = texture2DRect(depthMap, pos_screen.xy).r;
@@ -74,16 +92,16 @@ void main()
frag.xy *= screen_res;
vec3 pos = getPosition(frag.xy).xyz;
- vec3 lv = center.xyz-pos;
- float dist2 = dot(lv,lv);
- dist2 /= size;
- if (dist2 > 1.0)
+ vec3 lv = trans_center.xyz-pos;
+ float dist = length(lv);
+ dist /= size;
+ if (dist > 1.0)
{
discard;
}
vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
- norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
+ norm = decode_normal(norm.xy); // unpack norm
float da = dot(norm, lv);
if (da < 0.0)
{
@@ -98,20 +116,33 @@ void main()
vec3 col = texture2DRect(diffuseRect, frag.xy).rgb;
float fa = falloff+1.0;
- float dist_atten = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0);
- float lit = da * dist_atten * noise;
+ float dist_atten = clamp(1.0-(dist-1.0*(1.0-fa))/fa, 0.0, 1.0);
+ dist_atten *= dist_atten;
+ dist_atten *= 2.0;
+ float lit = da * dist_atten * noise;
+
col = color.rgb*lit*col;
vec4 spec = texture2DRect(specularRect, frag.xy);
if (spec.a > 0.0)
{
- float sa = dot(normalize(lv-normalize(pos)),norm);
- if (sa > 0.0)
+ lit = min(da*6.0, 1.0) * dist_atten;
+
+ vec3 npos = -normalize(pos);
+ vec3 h = normalize(lv+npos);
+ float nh = dot(norm, h);
+ float nv = dot(norm, npos);
+ float vh = dot(npos, h);
+ float sa = nh;
+ float fres = pow(1 - dot(h, npos), 5) * 0.4+0.5;
+ float gtdenom = 2 * nh;
+ float gt = max(0,(min(gtdenom * nv / vh, gtdenom * da / vh)));
+
+ if (nh > 0.0)
{
- sa = 6 * texture2D(lightFunc, vec2(sa, spec.a)).r * min(dist_atten*4.0, 1.0);
- sa *= noise;
- col += da*sa*color.rgb*spec.rgb;
+ float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da);
+ col += lit*scol*color.rgb*spec.rgb;
}
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/pointLightV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pointLightV.glsl
index cb14e6d4e8..a5625fbc16 100644..100755
--- a/indra/newview/app_settings/shaders/class1/deferred/pointLightV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/pointLightV.glsl
@@ -24,16 +24,22 @@
*/
uniform mat4 modelview_projection_matrix;
+uniform mat4 modelview_matrix;
ATTRIBUTE vec3 position;
+uniform vec3 center;
+uniform float size;
+
VARYING vec4 vary_fragcoord;
+VARYING vec3 trans_center;
void main()
{
//transform vertex
- vec4 pos = modelview_projection_matrix * vec4(position.xyz, 1.0);
+ vec3 p = position*size+center;
+ vec4 pos = modelview_projection_matrix * vec4(p.xyz, 1.0);
vary_fragcoord = pos;
-
+ trans_center = (modelview_matrix*vec4(center.xyz, 1.0)).xyz;
gl_Position = pos;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl
index bf362e21a4..bf362e21a4 100644..100755
--- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl
diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl
new file mode 100644
index 0000000000..4e2f98aa29
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl
@@ -0,0 +1,67 @@
+/**
+ * @file postDeferredGammaCorrect.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, 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$
+ */
+
+#extension GL_ARB_texture_rectangle : enable
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_color;
+#else
+#define frag_color gl_FragColor
+#endif
+
+uniform sampler2DRect diffuseRect;
+
+uniform vec2 screen_res;
+VARYING vec2 vary_fragcoord;
+
+uniform float display_gamma;
+
+vec3 linear_to_srgb(vec3 cl)
+{
+ cl = clamp(cl, vec3(0), vec3(1));
+ vec3 low_range = cl * 12.92;
+ vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
+ bvec3 lt = lessThan(cl,vec3(0.0031308));
+
+#ifdef OLD_SELECT
+ vec3 result;
+ result.r = lt.r ? low_range.r : high_range.r;
+ result.g = lt.g ? low_range.g : high_range.g;
+ result.b = lt.b ? low_range.b : high_range.b;
+ return result;
+#else
+ return mix(high_range, low_range, lt);
+#endif
+
+}
+
+
+void main()
+{
+ vec4 diff = texture2DRect(diffuseRect, vary_fragcoord);
+ diff.rgb = linear_to_srgb(diff.rgb);
+ frag_color = diff;
+}
+
diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoDoFF.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoDoFF.glsl
index eb5beeef39..eb5beeef39 100644..100755
--- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoDoFF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoDoFF.glsl
diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoTCV.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoTCV.glsl
index bd0cb50464..bd0cb50464 100644..100755
--- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoTCV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoTCV.glsl
diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredV.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredV.glsl
index 8edf5b2723..8edf5b2723 100644..100755
--- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredV.glsl
diff --git a/indra/newview/app_settings/shaders/class1/deferred/postgiF.glsl b/indra/newview/app_settings/shaders/class1/deferred/postgiF.glsl
index 96f9628424..96f9628424 100644..100755
--- a/indra/newview/app_settings/shaders/class1/deferred/postgiF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/postgiF.glsl
diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskF.glsl
index cf8cf8364a..91a96977f0 100644..100755
--- a/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskF.glsl
@@ -29,11 +29,15 @@ out vec4 frag_color;
#define frag_color gl_FragColor
#endif
-uniform float minimum_alpha;
-
uniform sampler2D diffuseMap;
-VARYING vec4 post_pos;
+#if !DEPTH_CLAMP
+VARYING float pos_zd2;
+#endif
+
+VARYING float pos_w;
+
+VARYING float target_pos_x;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
@@ -41,12 +45,22 @@ void main()
{
float alpha = diffuseLookup(vary_texcoord0.xy).a * vertex_color.a;
- if (alpha < minimum_alpha)
+ if (alpha < 0.05) // treat as totally transparent
{
discard;
}
+ if (alpha < 0.88) // treat as semi-transparent
+ {
+ if (fract(0.5*floor(target_pos_x / pos_w )) < 0.25)
+ {
+ discard;
+ }
+ }
+
frag_color = vec4(1,1,1,1);
- gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0);
+#if !DEPTH_CLAMP
+ gl_FragDepth = max(pos_zd2/pos_w+0.5, 0.0);
+#endif
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskV.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskV.glsl
index 7d3b06c56e..11411a605c 100644..100755
--- a/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskV.glsl
@@ -25,12 +25,19 @@
uniform mat4 texture_matrix0;
uniform mat4 modelview_projection_matrix;
+uniform float shadow_target_width;
ATTRIBUTE vec3 position;
ATTRIBUTE vec4 diffuse_color;
ATTRIBUTE vec2 texcoord0;
-VARYING vec4 post_pos;
+#if !DEPTH_CLAMP
+VARYING float pos_zd2;
+#endif
+
+VARYING float pos_w;
+
+VARYING float target_pos_x;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
@@ -39,10 +46,19 @@ void passTextureIndex();
void main()
{
//transform vertex
- vec4 pos = modelview_projection_matrix*vec4(position.xyz, 1.0);
- post_pos = pos;
+ vec4 pre_pos = vec4(position.xyz, 1.0);
+ vec4 pos = modelview_projection_matrix * pre_pos;
+ target_pos_x = 0.5 * (shadow_target_width - 1.0) * pos.x;
+
+ pos_w = pos.w;
+
+#if !DEPTH_CLAMP
+ pos_zd2 = pos.z * 0.5;
gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
+#else
+ gl_Position = pos;
+#endif
passTextureIndex();
diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowCubeV.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowCubeV.glsl
new file mode 100755
index 0000000000..ef153dfc5b
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/shadowCubeV.glsl
@@ -0,0 +1,50 @@
+/**
+ * @file shadowCubeV.glsl
+ *
+ * $LicenseInfo:firstyear=2011&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, 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$
+ */
+
+uniform mat4 modelview_projection_matrix;
+
+ATTRIBUTE vec3 position;
+
+#if !DEPTH_CLAMP
+VARYING vec4 post_pos;
+#endif
+
+uniform vec3 box_center;
+uniform vec3 box_size;
+
+void main()
+{
+ //transform vertex
+ vec3 p = position*box_size+box_center;
+ vec4 pos = modelview_projection_matrix*vec4(p.xyz, 1.0);
+
+#if !DEPTH_CLAMP
+ post_pos = pos;
+
+ gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
+#else
+ gl_Position = pos;
+#endif
+}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl
index 7e55fdc12a..3d1b182875 100644..100755
--- a/indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl
@@ -29,11 +29,16 @@ out vec4 frag_color;
#define frag_color gl_FragColor
#endif
+#if !DEPTH_CLAMP
VARYING vec4 post_pos;
+#endif
void main()
{
frag_color = vec4(1,1,1,1);
+#if !DEPTH_CLAMP
gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0);
+#endif
+
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowV.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowV.glsl
index 8b46e81f90..cc77a4cea0 100644..100755
--- a/indra/newview/app_settings/shaders/class1/deferred/shadowV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/shadowV.glsl
@@ -27,14 +27,20 @@ uniform mat4 modelview_projection_matrix;
ATTRIBUTE vec3 position;
+#if !DEPTH_CLAMP
VARYING vec4 post_pos;
+#endif
void main()
{
//transform vertex
vec4 pos = modelview_projection_matrix*vec4(position.xyz, 1.0);
+#if !DEPTH_CLAMP
post_pos = pos;
-
+
gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
+#else
+ gl_Position = pos;
+#endif
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl b/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl
index faa54a316e..22f4729e2e 100644..100755
--- a/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl
@@ -61,6 +61,6 @@ void main()
/// Gamma correct for WL (soft clip effect).
frag_data[0] = vec4(scaleSoftClip(color.rgb), 1.0);
frag_data[1] = vec4(0.0,0.0,0.0,0.0);
- frag_data[2] = vec4(0,0,1,0);
+ frag_data[2] = vec4(0.5,0.5,0.0,1.0); //1.0 in norm.w masks off fog
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl b/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl
index 7c02d31d43..7c02d31d43 100644..100755
--- a/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl
diff --git a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl
index 66e3cf6d13..760d52a9ce 100644..100755
--- a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl
@@ -24,6 +24,7 @@
*/
#extension GL_ARB_texture_rectangle : enable
+#extension GL_ARB_shader_texture_lod : enable
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
@@ -60,6 +61,7 @@ uniform float density_multiplier;
uniform float distance_multiplier;
uniform float max_y;
uniform vec4 glow;
+uniform float global_gamma;
uniform float scene_light_strength;
uniform mat3 env_mat;
uniform mat3 ssao_effect_mat;
@@ -77,6 +79,54 @@ vec3 vary_AtmosAttenuation;
uniform mat4 inv_proj;
uniform vec2 screen_res;
+vec3 srgb_to_linear(vec3 cs)
+{
+ vec3 low_range = cs / vec3(12.92);
+ vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
+ bvec3 lte = lessThanEqual(cs,vec3(0.04045));
+
+#ifdef OLD_SELECT
+ vec3 result;
+ result.r = lte.r ? low_range.r : high_range.r;
+ result.g = lte.g ? low_range.g : high_range.g;
+ result.b = lte.b ? low_range.b : high_range.b;
+ return result;
+#else
+ return mix(high_range, low_range, lte);
+#endif
+
+}
+
+vec3 linear_to_srgb(vec3 cl)
+{
+ vec3 low_range = cl * 12.92;
+ vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
+ bvec3 lt = lessThan(cl,vec3(0.0031308));
+
+#ifdef OLD_SELECT
+ vec3 result;
+ result.r = lt.r ? low_range.r : high_range.r;
+ result.g = lt.g ? low_range.g : high_range.g;
+ result.b = lt.b ? low_range.b : high_range.b;
+ return result;
+#else
+ return mix(high_range, low_range, lt);
+#endif
+
+}
+
+
+vec3 decode_normal (vec2 enc)
+{
+ vec2 fenc = enc*4-2;
+ float f = dot(fenc,fenc);
+ float g = sqrt(1-f/4);
+ vec3 n;
+ n.xy = fenc*g;
+ n.z = 1-f/2;
+ return n;
+}
+
vec4 getPosition_d(vec2 pos_screen, float depth)
{
vec2 sc = pos_screen.xy*2.0;
@@ -116,7 +166,6 @@ vec3 getAtmosAttenuation()
return vary_AtmosAttenuation;
}
-
void setPositionEye(vec3 v)
{
vary_PositionEye = v;
@@ -142,6 +191,53 @@ void setAtmosAttenuation(vec3 v)
vary_AtmosAttenuation = v;
}
+
+#ifdef WATER_FOG
+uniform vec4 waterPlane;
+uniform vec4 waterFogColor;
+uniform float waterFogDensity;
+uniform float waterFogKS;
+
+vec4 applyWaterFogDeferred(vec3 pos, vec4 color)
+{
+ //normalize view vector
+ vec3 view = normalize(pos);
+ float es = -(dot(view, waterPlane.xyz));
+
+ //find intersection point with water plane and eye vector
+
+ //get eye depth
+ float e0 = max(-waterPlane.w, 0.0);
+
+ vec3 int_v = waterPlane.w > 0.0 ? view * waterPlane.w/es : vec3(0.0, 0.0, 0.0);
+
+ //get object depth
+ float depth = length(pos - int_v);
+
+ //get "thickness" of water
+ float l = max(depth, 0.1);
+
+ float kd = waterFogDensity;
+ float ks = waterFogKS;
+ vec4 kc = waterFogColor;
+
+ float F = 0.98;
+
+ float t1 = -kd * pow(F, ks * e0);
+ float t2 = kd + ks * es;
+ float t3 = pow(F, t2*l) - 1.0;
+
+ float L = min(t1/t2*t3, 1.0);
+
+ float D = pow(0.98, l*kd);
+
+ color.rgb = color.rgb * D + kc.rgb * L;
+ color.a = kc.a + color.a;
+
+ return color;
+}
+#endif
+
void calcAtmospherics(vec3 inPositionEye, float ambFactor) {
vec3 P = inPositionEye;
@@ -237,6 +333,15 @@ vec3 atmosTransport(vec3 light) {
light += getAdditiveColor() * 2.0;
return light;
}
+
+vec3 fullbrightAtmosTransport(vec3 light) {
+ float brightness = dot(light.rgb, vec3(0.33333));
+
+ return mix(atmosTransport(light.rgb), light.rgb + getAdditiveColor().rgb, brightness * brightness);
+}
+
+
+
vec3 atmosGetDiffuseSunlightColor()
{
return getSunlitColor();
@@ -271,60 +376,100 @@ vec3 scaleSoftClip(vec3 light)
return light;
}
+
+vec3 fullbrightScaleSoftClip(vec3 light)
+{
+ //soft clip effect:
+ return light;
+}
+
void main()
{
vec2 tc = vary_fragcoord.xy;
float depth = texture2DRect(depthMap, tc.xy).r;
vec3 pos = getPosition_d(tc, depth).xyz;
- vec3 norm = texture2DRect(normalMap, tc).xyz;
- norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
+ vec4 norm = texture2DRect(normalMap, tc);
+ float envIntensity = norm.z;
+ norm.xyz = decode_normal(norm.xy); // unpack norm
- float da = max(dot(norm.xyz, sun_dir.xyz), 0.0);
-
+ float da = dot(norm.xyz, sun_dir.xyz);
+
+ float final_da = max(0.0,da);
+ final_da = min(final_da, 1.0f);
+ final_da = pow(final_da, 1.0/1.3);
+
vec4 diffuse = texture2DRect(diffuseRect, tc);
+
+ //convert to gamma space
+ diffuse.rgb = linear_to_srgb(diffuse.rgb);
+
vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy);
-
vec3 col;
float bloom = 0.0;
- if (diffuse.a < 0.9)
{
calcAtmospherics(pos.xyz, 1.0);
col = atmosAmbient(vec3(0));
- col += atmosAffectDirectionalLight(max(min(da, 1.0), diffuse.a));
+ float ambient = min(abs(dot(norm.xyz, sun_dir.xyz)), 1.0);
+ ambient *= 0.5;
+ ambient *= ambient;
+ ambient = (1.0-ambient);
+
+ col.rgb *= ambient;
+
+ col += atmosAffectDirectionalLight(final_da);
col *= diffuse.rgb;
+ vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
+
if (spec.a > 0.0) // specular reflection
{
// the old infinite-sky shiny reflection
//
- vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
+
float sa = dot(refnormpersp, sun_dir.xyz);
- vec3 dumbshiny = vary_SunlitColor*(6 * texture2D(lightFunc, vec2(sa, spec.a)).r);
+ vec3 dumbshiny = vary_SunlitColor*(texture2D(lightFunc, vec2(sa, spec.a)).r);
// add the two types of shiny together
vec3 spec_contrib = dumbshiny * spec.rgb;
- bloom = dot(spec_contrib, spec_contrib) / 4;
+ bloom = dot(spec_contrib, spec_contrib) / 6;
col += spec_contrib;
-
- //add environmentmap
+ }
+
+
+ col = mix(col.rgb, diffuse.rgb, diffuse.a);
+
+ if (envIntensity > 0.0)
+ { //add environmentmap
vec3 env_vec = env_mat * refnormpersp;
- col = mix(col.rgb, textureCube(environmentMap, env_vec).rgb,
- max(spec.a-diffuse.a*2.0, 0.0));
+
+
+ vec3 refcol = textureCube(environmentMap, env_vec).rgb;
+
+ col = mix(col.rgb, refcol,
+ envIntensity);
+ }
+
+ if (norm.w < 0.5)
+ {
+ col = mix(atmosLighting(col), fullbrightAtmosTransport(col), diffuse.a);
+ col = mix(scaleSoftClip(col), fullbrightScaleSoftClip(col), diffuse.a);
}
-
- col = atmosLighting(col);
- col = scaleSoftClip(col);
- col = mix(col.rgb, diffuse.rgb, diffuse.a);
- }
- else
- {
- col = diffuse.rgb;
- }
+ #ifdef WATER_FOG
+ vec4 fogged = applyWaterFogDeferred(pos,vec4(col, bloom));
+ col = fogged.rgb;
+ bloom = fogged.a;
+ #endif
+
+ col = srgb_to_linear(col);
- frag_color.rgb = col;
+ //col = vec3(1,0,1);
+ //col.g = envIntensity;
+ }
+ frag_color.rgb = col.rgb;
frag_color.a = bloom;
}
+
diff --git a/indra/newview/app_settings/shaders/class1/deferred/softenLightV.glsl b/indra/newview/app_settings/shaders/class1/deferred/softenLightV.glsl
index c6031fc45a..b59fcbe017 100644..100755
--- a/indra/newview/app_settings/shaders/class1/deferred/softenLightV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/softenLightV.glsl
@@ -35,6 +35,6 @@ void main()
//transform vertex
vec4 pos = modelview_projection_matrix * vec4(position.xyz, 1.0);
gl_Position = pos;
-
+
vary_fragcoord = (pos.xy*0.5+0.5)*screen_res;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl
index 7ed8ed3370..8d8a6c9dde 100644..100755
--- a/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl
@@ -23,8 +23,8 @@
* $/LicenseInfo$
*/
-
#extension GL_ARB_texture_rectangle : enable
+#extension GL_ARB_shader_texture_lod : enable
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
@@ -32,12 +32,16 @@ out vec4 frag_color;
#define frag_color gl_FragColor
#endif
+//class 1 -- no shadows
+
uniform sampler2DRect diffuseRect;
uniform sampler2DRect specularRect;
uniform sampler2DRect depthMap;
uniform sampler2DRect normalMap;
+uniform samplerCube environmentMap;
uniform sampler2D noiseMap;
uniform sampler2D projectionMap;
+uniform sampler2D lightFunc;
uniform mat4 proj_mat; //screen space to light space
uniform float proj_near; //near clip for projection
@@ -46,6 +50,7 @@ uniform vec3 proj_n;
uniform float proj_focus; //distance from plane to begin blurring
uniform float proj_lod; //(number of mips in proj map)
uniform float proj_range; //range between near clip and far clip plane of projection
+uniform float proj_ambient_lod;
uniform float proj_ambiance;
uniform float near_clip;
uniform float far_clip;
@@ -53,19 +58,127 @@ uniform float far_clip;
uniform vec3 proj_origin; //origin of projection to be used for angular attenuation
uniform float sun_wash;
-uniform vec3 center;
+uniform float size;
uniform vec3 color;
uniform float falloff;
-uniform float size;
+VARYING vec3 trans_center;
VARYING vec4 vary_fragcoord;
uniform vec2 screen_res;
uniform mat4 inv_proj;
+vec2 encode_normal(vec3 n)
+{
+ float f = sqrt(8 * n.z + 8);
+ return n.xy / f + 0.5;
+}
+
+vec3 decode_normal (vec2 enc)
+{
+ vec2 fenc = enc*4-2;
+ float f = dot(fenc,fenc);
+ float g = sqrt(1-f/4);
+ vec3 n;
+ n.xy = fenc*g;
+ n.z = 1-f/2;
+ return n;
+}
+
+vec3 srgb_to_linear(vec3 cs)
+{
+ vec3 low_range = cs / vec3(12.92);
+ vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
+ bvec3 lte = lessThanEqual(cs,vec3(0.04045));
+
+#ifdef OLD_SELECT
+ vec3 result;
+ result.r = lte.r ? low_range.r : high_range.r;
+ result.g = lte.g ? low_range.g : high_range.g;
+ result.b = lte.b ? low_range.b : high_range.b;
+ return result;
+#else
+ return mix(high_range, low_range, lte);
+#endif
+
+}
+
+vec3 linear_to_srgb(vec3 cl)
+{
+ cl = clamp(cl, vec3(0), vec3(1));
+ vec3 low_range = cl * 12.92;
+ vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
+ bvec3 lt = lessThan(cl,vec3(0.0031308));
+
+#ifdef OLD_SELECT
+ vec3 result;
+ result.r = lt.r ? low_range.r : high_range.r;
+ result.g = lt.g ? low_range.g : high_range.g;
+ result.b = lt.b ? low_range.b : high_range.b;
+ return result;
+#else
+ return mix(high_range, low_range, lt);
+#endif
+
+}
+
+vec4 correctWithGamma(vec4 col)
+{
+ return vec4(srgb_to_linear(col.rgb), col.a);
+}
+
+vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
+{
+ vec4 ret = texture2DLod(projectionMap, tc, lod);
+ ret = correctWithGamma(ret);
+
+ vec2 dist = tc-vec2(0.5);
+
+ float det = max(1.0-lod/(proj_lod*0.5), 0.0);
+
+ float d = dot(dist,dist);
+
+ ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0)+det, 1.0);
+
+ return ret;
+}
+
+vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)
+{
+ vec4 ret = texture2DLod(projectionMap, tc, lod);
+ ret = correctWithGamma(ret);
+
+ vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
+
+ float det = min(lod/(proj_lod*0.5), 1.0);
+
+ float d = min(dist.x, dist.y);
+
+ float edge = 0.25*det;
+
+ ret *= clamp(d/edge, 0.0, 1.0);
+
+ return ret;
+}
+
+vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)
+{
+ vec4 ret = texture2DLod(projectionMap, tc, lod);
+ ret = correctWithGamma(ret);
+
+ vec2 dist = tc-vec2(0.5);
+
+ float d = dot(dist,dist);
+
+ ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0), 1.0);
+
+ return ret;
+}
+
+
vec4 getPosition(vec2 pos_screen)
{
- float depth = texture2DRect(depthMap, pos_screen.xy).a;
+ float depth = texture2DRect(depthMap, pos_screen.xy).r;
vec2 sc = pos_screen.xy*2.0;
sc /= screen_res;
sc -= vec2(1.0,1.0);
@@ -84,16 +197,18 @@ void main()
frag.xy *= screen_res;
vec3 pos = getPosition(frag.xy).xyz;
- vec3 lv = center.xyz-pos.xyz;
- float dist2 = dot(lv,lv);
- dist2 /= size;
- if (dist2 > 1.0)
+ vec3 lv = trans_center.xyz-pos.xyz;
+ float dist = length(lv);
+ dist /= size;
+ if (dist > 1.0)
{
discard;
}
+
vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
- norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
+ float envIntensity = norm.z;
+ norm = decode_normal(norm.xy);
norm = normalize(norm);
float l_dist = -dot(lv, proj_n);
@@ -107,7 +222,14 @@ void main()
proj_tc.xyz /= proj_tc.w;
float fa = falloff+1.0;
- float dist_atten = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0);
+ float dist_atten = min(1.0-(dist-1.0*(1.0-fa))/fa, 1.0);
+ dist_atten *= dist_atten;
+ dist_atten *= 2.0;
+
+ if (dist_atten <= 0.0)
+ {
+ discard;
+ }
lv = proj_origin-pos.xyz;
lv = normalize(lv);
@@ -117,47 +239,75 @@ void main()
vec3 diff_tex = texture2DRect(diffuseRect, frag.xy).rgb;
+ vec4 spec = texture2DRect(specularRect, frag.xy);
+
+
+
float noise = texture2D(noiseMap, frag.xy/128.0).b;
+ vec3 dlit = vec3(0, 0, 0);
+
if (proj_tc.z > 0.0 &&
proj_tc.x < 1.0 &&
proj_tc.y < 1.0 &&
proj_tc.x > 0.0 &&
proj_tc.y > 0.0)
{
+ float amb_da = proj_ambiance;
float lit = 0.0;
+
if (da > 0.0)
{
+ lit = da * dist_atten * noise;
+
float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0);
float lod = diff * proj_lod;
- vec4 plcol = texture2DLod(projectionMap, proj_tc.xy, lod);
-
- vec3 lcol = color.rgb * plcol.rgb * plcol.a;
+ vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod);
+ dlit = color.rgb * plcol.rgb * plcol.a;
- lit = da * dist_atten * noise;
-
- col = lcol*lit*diff_tex;
+ col = dlit*lit*diff_tex;
+ //amb_da += (da*0.5)*(1.0-shadow)*proj_ambiance;
}
-
- float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0);
- float lod = diff * proj_lod;
- vec4 amb_plcol = texture2DLod(projectionMap, proj_tc.xy, lod);
- //float amb_da = mix(proj_ambiance, proj_ambiance*max(-da, 0.0), max(da, 0.0));
- float amb_da = proj_ambiance;
-
+ //float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0);
+ vec4 amb_plcol = texture2DLodAmbient(projectionMap, proj_tc.xy, proj_lod);
+
amb_da += (da*da*0.5+0.5)*proj_ambiance;
-
+
amb_da *= dist_atten * noise;
-
+
amb_da = min(amb_da, 1.0-lit);
-
- col += amb_da*color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a;
+ col += amb_da*color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a*diff_tex.rgb;
}
-
- vec4 spec = texture2DRect(specularRect, frag.xy);
+
if (spec.a > 0.0)
{
+ dlit *= min(da*6.0, 1.0) * dist_atten;
+ vec3 npos = -normalize(pos);
+
+ //vec3 ref = dot(pos+lv, norm);
+ vec3 h = normalize(lv+npos);
+ float nh = dot(norm, h);
+ float nv = dot(norm, npos);
+ float vh = dot(npos, h);
+ float sa = nh;
+ float fres = pow(1 - dot(h, npos), 5)*0.4+0.5;
+
+ float gtdenom = 2 * nh;
+ float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh));
+
+ if (nh > 0.0)
+ {
+
+ float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da);
+ col += dlit*scol*spec.rgb;
+ //col += spec.rgb;
+ }
+ }
+
+
+ if (envIntensity > 0.0)
+ {
vec3 ref = reflect(normalize(pos), norm);
//project from point pos in direction ref to plane proj_p, proj_n
@@ -168,19 +318,23 @@ void main()
{
vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds;
- vec3 stc = (proj_mat * vec4(pfinal.xyz, 1.0)).xyz;
+ vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0));
if (stc.z > 0.0)
{
- stc.xy /= stc.z+proj_near;
-
+ stc.xy /= stc.w;
+
+ float fatten = clamp(envIntensity*envIntensity+envIntensity*0.5, 0.25, 1.0);
+
+ //stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5);
+ stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5);
+
if (stc.x < 1.0 &&
stc.y < 1.0 &&
stc.x > 0.0 &&
stc.y > 0.0)
{
- vec4 scol = texture2DLod(projectionMap, stc.xy, proj_lod-spec.a*proj_lod);
- col += dist_atten*scol.rgb*color.rgb*scol.a*spec.rgb;
+ col += color.rgb*texture2DLodSpecular(projectionMap, stc.xy, proj_lod-envIntensity*proj_lod).rgb*spec.rgb;
}
}
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/srgb.glsl b/indra/newview/app_settings/shaders/class1/deferred/srgb.glsl
new file mode 100644
index 0000000000..587f3d5a94
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/srgb.glsl
@@ -0,0 +1,46 @@
+/**
+ * @file srgb.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, 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$
+ */
+
+vec3 srgb_to_linear(vec3 cs)
+{
+ vec3 low_range = cs / vec3(12.92);
+ vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
+
+ bvec3 lte = lessThanEqual(cs,vec3(0.04045));
+ return mix(high_range, low_range, lte);
+
+}
+
+vec3 linear_to_srgb(vec3 cl)
+{
+ cl = clamp(cl, vec3(0), vec3(1));
+ vec3 low_range = cl * 12.92;
+ vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
+
+ bvec3 lt = lessThan(cl,vec3(0.0031308));
+ return mix(high_range, low_range, lt);
+
+}
+
diff --git a/indra/newview/app_settings/shaders/class1/deferred/srgb_mac.glsl b/indra/newview/app_settings/shaders/class1/deferred/srgb_mac.glsl
new file mode 100644
index 0000000000..6cc1e6e798
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/srgb_mac.glsl
@@ -0,0 +1,54 @@
+/**
+ * @file srgb.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, 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$
+ */
+
+vec3 srgb_to_linear(vec3 cs)
+{
+ vec3 low_range = cs / vec3(12.92);
+ vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
+
+ bvec3 lte = lessThanEqual(cs,vec3(0.04045));
+
+ vec3 result;
+ result.r = lte.r ? low_range.r : high_range.r;
+ result.g = lte.g ? low_range.g : high_range.g;
+ result.b = lte.b ? low_range.b : high_range.b;
+ return result;
+}
+
+vec3 linear_to_srgb(vec3 cl)
+{
+ cl = clamp(cl, vec3(0), vec3(1));
+ vec3 low_range = cl * 12.92;
+ vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
+
+ bvec3 lt = lessThan(cl,vec3(0.0031308));
+
+ vec3 result;
+ result.r = lt.r ? low_range.r : high_range.r;
+ result.g = lt.g ? low_range.g : high_range.g;
+ result.b = lt.b ? low_range.b : high_range.b;
+ return result;
+}
+
diff --git a/indra/newview/app_settings/shaders/class1/deferred/starsF.glsl b/indra/newview/app_settings/shaders/class1/deferred/starsF.glsl
index 821058804c..821058804c 100644..100755
--- a/indra/newview/app_settings/shaders/class1/deferred/starsF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/starsF.glsl
diff --git a/indra/newview/app_settings/shaders/class1/deferred/starsV.glsl b/indra/newview/app_settings/shaders/class1/deferred/starsV.glsl
index 8bc5b06379..8bc5b06379 100644..100755
--- a/indra/newview/app_settings/shaders/class1/deferred/starsV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/starsV.glsl
diff --git a/indra/newview/app_settings/shaders/class1/deferred/sunLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/sunLightF.glsl
index 5ca817aff6..5ca817aff6 100644..100755
--- a/indra/newview/app_settings/shaders/class1/deferred/sunLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/sunLightF.glsl
diff --git a/indra/newview/app_settings/shaders/class1/deferred/sunLightNoFragCoordV.glsl b/indra/newview/app_settings/shaders/class1/deferred/sunLightNoFragCoordV.glsl
index 47e9d15fbc..47e9d15fbc 100644..100755
--- a/indra/newview/app_settings/shaders/class1/deferred/sunLightNoFragCoordV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/sunLightNoFragCoordV.glsl
diff --git a/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl b/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl
index 2422d73a3e..c0a5865bef 100644..100755
--- a/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl
@@ -49,6 +49,23 @@ VARYING vec2 vary_fragcoord;
uniform mat4 inv_proj;
uniform vec2 screen_res;
+vec2 encode_normal(vec3 n)
+{
+ float f = sqrt(8 * n.z + 8);
+ return n.xy / f + 0.5;
+}
+
+vec3 decode_normal (vec2 enc)
+{
+ vec2 fenc = enc*4-2;
+ float f = dot(fenc,fenc);
+ float g = sqrt(1-f/4);
+ vec3 n;
+ n.xy = fenc*g;
+ n.z = 1-f/2;
+ return n;
+}
+
vec4 getPosition(vec2 pos_screen)
{
float depth = texture2DRect(depthMap, pos_screen.xy).r;
@@ -123,7 +140,7 @@ void main()
vec4 pos = getPosition(pos_screen);
vec3 norm = texture2DRect(normalMap, pos_screen).xyz;
- norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
+ norm = decode_normal(norm.xy);
frag_color[0] = 1.0;
frag_color[1] = calcAmbientOcclusion(pos, norm);
diff --git a/indra/newview/app_settings/shaders/class1/deferred/sunLightV.glsl b/indra/newview/app_settings/shaders/class1/deferred/sunLightV.glsl
index 473d6df8fa..473d6df8fa 100644..100755
--- a/indra/newview/app_settings/shaders/class1/deferred/sunLightV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/sunLightV.glsl
diff --git a/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl
index 8a5e482e80..52a429465f 100644..100755
--- a/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl
@@ -39,6 +39,12 @@ VARYING vec3 vary_normal;
VARYING vec4 vary_texcoord0;
VARYING vec4 vary_texcoord1;
+vec2 encode_normal(vec3 n)
+{
+ float f = sqrt(8 * n.z + 8);
+ return n.xy / f + 0.5;
+}
+
void main()
{
/// Note: This should duplicate the blending functionality currently used for the terrain rendering.
@@ -56,6 +62,6 @@ void main()
frag_data[0] = vec4(outColor.rgb, 0.0);
frag_data[1] = vec4(0,0,0,0);
vec3 nvn = normalize(vary_normal);
- frag_data[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0);
+ frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, 0.0);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl b/indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl
index 5effee4e4e..5effee4e4e 100644..100755
--- a/indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl
diff --git a/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl b/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl
index 6cf6106b51..808750496f 100644..100755
--- a/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl
@@ -37,6 +37,12 @@ VARYING vec2 vary_texcoord0;
uniform float minimum_alpha;
+vec2 encode_normal(vec3 n)
+{
+ float f = sqrt(8 * n.z + 8);
+ return n.xy / f + 0.5;
+}
+
void main()
{
vec4 col = texture2D(diffuseMap, vary_texcoord0.xy);
@@ -48,5 +54,5 @@ void main()
frag_data[0] = vec4(vertex_color.rgb*col.rgb, 0.0);
frag_data[1] = vec4(0,0,0,0);
vec3 nvn = normalize(vary_normal);
- frag_data[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0);
+ frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, 0.0);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/treeShadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/treeShadowF.glsl
index d4d2f5f571..d4d2f5f571 100644..100755
--- a/indra/newview/app_settings/shaders/class1/deferred/treeShadowF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/treeShadowF.glsl
diff --git a/indra/newview/app_settings/shaders/class1/deferred/treeShadowV.glsl b/indra/newview/app_settings/shaders/class1/deferred/treeShadowV.glsl
index e472a75304..e472a75304 100644..100755
--- a/indra/newview/app_settings/shaders/class1/deferred/treeShadowV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/treeShadowV.glsl
diff --git a/indra/newview/app_settings/shaders/class1/deferred/treeV.glsl b/indra/newview/app_settings/shaders/class1/deferred/treeV.glsl
index 3b6571a24a..3b6571a24a 100644..100755
--- a/indra/newview/app_settings/shaders/class1/deferred/treeV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/treeV.glsl
diff --git a/indra/newview/app_settings/shaders/class1/deferred/underWaterF.glsl b/indra/newview/app_settings/shaders/class1/deferred/underWaterF.glsl
new file mode 100644
index 0000000000..78f841c733
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/underWaterF.glsl
@@ -0,0 +1,157 @@
+/**
+ * @file underWaterF.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, 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$
+ */
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_data[3];
+#else
+#define frag_data gl_FragData
+#endif
+
+uniform sampler2D diffuseMap;
+uniform sampler2D bumpMap;
+uniform sampler2D screenTex;
+uniform sampler2D refTex;
+uniform sampler2D screenDepth;
+
+uniform vec4 fogCol;
+uniform vec3 lightDir;
+uniform vec3 specular;
+uniform float lightExp;
+uniform vec2 fbScale;
+uniform float refScale;
+uniform float znear;
+uniform float zfar;
+uniform float kd;
+uniform vec4 waterPlane;
+uniform vec3 eyeVec;
+uniform vec4 waterFogColor;
+uniform float waterFogDensity;
+uniform float waterFogKS;
+uniform vec2 screenRes;
+
+//bigWave is (refCoord.w, view.w);
+VARYING vec4 refCoord;
+VARYING vec4 littleWave;
+VARYING vec4 view;
+
+vec3 srgb_to_linear(vec3 cs)
+{
+ vec3 low_range = cs / vec3(12.92);
+ vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
+ bvec3 lte = lessThanEqual(cs,vec3(0.04045));
+
+#ifdef OLD_SELECT
+ vec3 result;
+ result.r = lte.r ? low_range.r : high_range.r;
+ result.g = lte.g ? low_range.g : high_range.g;
+ result.b = lte.b ? low_range.b : high_range.b;
+ return result;
+#else
+ return mix(high_range, low_range, lte);
+#endif
+
+}
+
+vec3 linear_to_srgb(vec3 cl)
+{
+ cl = clamp(cl, vec3(0), vec3(1));
+ vec3 low_range = cl * 12.92;
+ vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
+ bvec3 lt = lessThan(cl,vec3(0.0031308));
+
+#ifdef OLD_SELECT
+ vec3 result;
+ result.r = lt.r ? low_range.r : high_range.r;
+ result.g = lt.g ? low_range.g : high_range.g;
+ result.b = lt.b ? low_range.b : high_range.b;
+ return result;
+#else
+ return mix(high_range, low_range, lt);
+#endif
+
+}
+
+vec2 encode_normal(vec3 n)
+{
+ float f = sqrt(8 * n.z + 8);
+ return n.xy / f + 0.5;
+}
+
+vec4 applyWaterFog(vec4 color, vec3 viewVec)
+{
+ //normalize view vector
+ vec3 view = normalize(viewVec);
+ float es = -view.z;
+
+ //find intersection point with water plane and eye vector
+
+ //get eye depth
+ float e0 = max(-waterPlane.w, 0.0);
+
+ //get object depth
+ float depth = length(viewVec);
+
+ //get "thickness" of water
+ float l = max(depth, 0.1);
+
+ float kd = waterFogDensity;
+ float ks = waterFogKS;
+ vec4 kc = waterFogColor;
+
+ float F = 0.98;
+
+ float t1 = -kd * pow(F, ks * e0);
+ float t2 = kd + ks * es;
+ float t3 = pow(F, t2*l) - 1.0;
+
+ float L = min(t1/t2*t3, 1.0);
+
+ float D = pow(0.98, l*kd);
+ //return vec4(1.0, 0.0, 1.0, 1.0);
+ return color * D + kc * L;
+ //depth /= 10.0;
+ //return vec4(depth,depth,depth,0.0);
+}
+
+void main()
+{
+ vec4 color;
+
+ //get detail normals
+ vec3 wave1 = texture2D(bumpMap, vec2(refCoord.w, view.w)).xyz*2.0-1.0;
+ vec3 wave2 = texture2D(bumpMap, littleWave.xy).xyz*2.0-1.0;
+ vec3 wave3 = texture2D(bumpMap, littleWave.zw).xyz*2.0-1.0;
+ vec3 wavef = normalize(wave1+wave2+wave3);
+
+ //figure out distortion vector (ripply)
+ vec2 distort = (refCoord.xy/refCoord.z) * 0.5 + 0.5;
+ distort = distort+wavef.xy*refScale;
+
+ vec4 fb = texture2D(screenTex, distort);
+
+ frag_data[0] = vec4(linear_to_srgb(fb.rgb), 1.0); // diffuse
+ frag_data[1] = vec4(0.5,0.5,0.5, 0.95); // speccolor*spec, spec
+ frag_data[2] = vec4(encode_normal(wavef), 0.0, 0.0); // normalxyz, displace
+}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl b/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl
index 42dc7c0980..1c3ad49a21 100644..100755
--- a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl
@@ -67,6 +67,49 @@ VARYING vec4 littleWave;
VARYING vec4 view;
VARYING vec4 vary_position;
+vec3 srgb_to_linear(vec3 cs)
+{
+ vec3 low_range = cs / vec3(12.92);
+ vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
+ bvec3 lte = lessThanEqual(cs,vec3(0.04045));
+
+#ifdef OLD_SELECT
+ vec3 result;
+ result.r = lte.r ? low_range.r : high_range.r;
+ result.g = lte.g ? low_range.g : high_range.g;
+ result.b = lte.b ? low_range.b : high_range.b;
+ return result;
+#else
+ return mix(high_range, low_range, lte);
+#endif
+
+}
+
+vec3 linear_to_srgb(vec3 cl)
+{
+ cl = clamp(cl, vec3(0), vec3(1));
+ vec3 low_range = cl * 12.92;
+ vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
+ bvec3 lt = lessThan(cl,vec3(0.0031308));
+
+#ifdef OLD_SELECT
+ vec3 result;
+ result.r = lt.r ? low_range.r : high_range.r;
+ result.g = lt.g ? low_range.g : high_range.g;
+ result.b = lt.b ? low_range.b : high_range.b;
+ return result;
+#else
+ return mix(high_range, low_range, lt);
+#endif
+
+}
+
+vec2 encode_normal(vec3 n)
+{
+ float f = sqrt(8 * n.z + 8);
+ return n.xy / f + 0.5;
+}
+
void main()
{
vec4 color;
@@ -115,7 +158,7 @@ void main()
refcol *= df1 * 0.333;
vec3 wavef = (wave1 + wave2 * 0.4 + wave3 * 0.6) * 0.5;
- //wavef.z *= max(-viewVec.z, 0.1);
+ wavef.z *= max(-viewVec.z, 0.1);
wavef = normalize(wavef);
float df2 = dot(viewVec, wavef) * fresnelScale+fresnelOffset;
@@ -125,13 +168,14 @@ void main()
vec2 refvec4 = distort+refdistort4/dmod;
float dweight = min(dist2*blurMultiplier, 1.0);
vec4 baseCol = texture2D(refTex, refvec4);
+
refcol = mix(baseCol*df2, refcol, dweight);
//get specular component
- //float spec = clamp(dot(lightDir, (reflect(viewVec,wavef))),0.0,1.0);
+ float spec = clamp(dot(lightDir, (reflect(viewVec,wavef))),0.0,1.0);
//harden specular
- //spec = pow(spec, 128.0);
+ spec = pow(spec, 128.0);
//figure out distortion vector (ripply)
vec2 distort2 = distort+wavef.xy*refScale/max(dmod*df1, 1.0);
@@ -142,24 +186,17 @@ void main()
// Note we actually want to use just df1, but multiplying by 0.999999 gets around an nvidia compiler bug
color.rgb = mix(fb.rgb, refcol.rgb, df1 * 0.99999);
- float shadow = 1.0;
vec4 pos = vary_position;
- //vec3 nz = texture2D(noiseMap, gl_FragCoord.xy/128.0).xyz;
- vec4 spos = pos;
-
- //spec *= shadow;
- //color.rgb += spec * specular;
+ color.rgb += spec * specular;
- //color.rgb = atmosTransport(color.rgb);
- //color.rgb = scaleSoftClip(color.rgb);
- //color.a = spec * sunAngle2;
+ color.rgb = atmosTransport(color.rgb);
+ color.rgb = scaleSoftClip(color.rgb);
+ color.a = spec * sunAngle2;
- //wavef.z *= 0.1f;
- //wavef = normalize(wavef);
- vec3 screenspacewavef = (norm_mat*vec4(wavef, 1.0)).xyz;
+ vec3 screenspacewavef = normalize((norm_mat*vec4(wavef, 1.0)).xyz);
- frag_data[0] = vec4(color.rgb, 0.5); // diffuse
- frag_data[1] = vec4(0.5,0.5,0.5, 0.95); // speccolor*spec, spec
- frag_data[2] = vec4(screenspacewavef.xy*0.5+0.5, screenspacewavef.z, screenspacewavef.z*0.5); // normalxyz, displace
+ frag_data[0] = vec4(color.rgb, color); // diffuse
+ frag_data[1] = vec4(0); // speccolor, spec
+ frag_data[2] = vec4(encode_normal(screenspacewavef.xyz*0.5+0.5), 0.05, 0);// normalxy, 0, 0
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/waterV.glsl b/indra/newview/app_settings/shaders/class1/deferred/waterV.glsl
index 9734acf005..9734acf005 100644..100755
--- a/indra/newview/app_settings/shaders/class1/deferred/waterV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/waterV.glsl
diff --git a/indra/newview/app_settings/shaders/class1/effects/glowExtractF.glsl b/indra/newview/app_settings/shaders/class1/effects/glowExtractF.glsl
index 0f5eb288fd..0f5eb288fd 100644..100755
--- a/indra/newview/app_settings/shaders/class1/effects/glowExtractF.glsl
+++ b/indra/newview/app_settings/shaders/class1/effects/glowExtractF.glsl
diff --git a/indra/newview/app_settings/shaders/class1/effects/glowExtractV.glsl b/indra/newview/app_settings/shaders/class1/effects/glowExtractV.glsl
index 1396dc6973..1396dc6973 100644..100755
--- a/indra/newview/app_settings/shaders/class1/effects/glowExtractV.glsl
+++ b/indra/newview/app_settings/shaders/class1/effects/glowExtractV.glsl
diff --git a/indra/newview/app_settings/shaders/class1/effects/glowF.glsl b/indra/newview/app_settings/shaders/class1/effects/glowF.glsl
index c1f6af9f57..c1f6af9f57 100644..100755
--- a/indra/newview/app_settings/shaders/class1/effects/glowF.glsl
+++ b/indra/newview/app_settings/shaders/class1/effects/glowF.glsl
diff --git a/indra/newview/app_settings/shaders/class1/effects/glowV.glsl b/indra/newview/app_settings/shaders/class1/effects/glowV.glsl
index cdb2281578..cdb2281578 100644..100755
--- a/indra/newview/app_settings/shaders/class1/effects/glowV.glsl
+++ b/indra/newview/app_settings/shaders/class1/effects/glowV.glsl
diff --git a/indra/newview/app_settings/shaders/class1/environment/terrainF.glsl b/indra/newview/app_settings/shaders/class1/environment/terrainF.glsl
index 668a710c04..668a710c04 100644..100755
--- a/indra/newview/app_settings/shaders/class1/environment/terrainF.glsl
+++ b/indra/newview/app_settings/shaders/class1/environment/terrainF.glsl
diff --git a/indra/newview/app_settings/shaders/class1/environment/terrainV.glsl b/indra/newview/app_settings/shaders/class1/environment/terrainV.glsl
index d09c5f9247..d09c5f9247 100644..100755
--- a/indra/newview/app_settings/shaders/class1/environment/terrainV.glsl
+++ b/indra/newview/app_settings/shaders/class1/environment/terrainV.glsl
diff --git a/indra/newview/app_settings/shaders/class1/environment/terrainWaterF.glsl b/indra/newview/app_settings/shaders/class1/environment/terrainWaterF.glsl
index a956562396..a956562396 100644..100755
--- a/indra/newview/app_settings/shaders/class1/environment/terrainWaterF.glsl
+++ b/indra/newview/app_settings/shaders/class1/environment/terrainWaterF.glsl
diff --git a/indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl b/indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl
index 0d8dab0a41..0d8dab0a41 100644..100755
--- a/indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl
+++ b/indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl
diff --git a/indra/newview/app_settings/shaders/class1/environment/waterF.glsl b/indra/newview/app_settings/shaders/class1/environment/waterF.glsl
index 79bffab745..79bffab745 100644..100755
--- a/indra/newview/app_settings/shaders/class1/environment/waterF.glsl
+++ b/indra/newview/app_settings/shaders/class1/environment/waterF.glsl
diff --git a/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl b/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl
index 4bdfce9260..4bdfce9260 100644..100755
--- a/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl
+++ b/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl
diff --git a/indra/newview/app_settings/shaders/class1/environment/waterV.glsl b/indra/newview/app_settings/shaders/class1/environment/waterV.glsl
index f66ba1d2d9..352cea7aaa 100644..100755
--- a/indra/newview/app_settings/shaders/class1/environment/waterV.glsl
+++ b/indra/newview/app_settings/shaders/class1/environment/waterV.glsl
@@ -28,6 +28,7 @@ uniform mat4 modelview_projection_matrix;
ATTRIBUTE vec3 position;
+
void calcAtmospherics(vec3 inPositionEye);
uniform vec2 d1;
@@ -48,35 +49,35 @@ float wave(vec2 v, float t, float f, vec2 d, float s)
void main()
{
//transform vertex
+ vec4 pos = vec4(position.xyz, 1.0);
mat4 modelViewProj = modelview_projection_matrix;
vec4 oPosition;
//get view vector
vec3 oEyeVec;
- oEyeVec.xyz = position.xyz-eyeVec;
+ oEyeVec.xyz = pos.xyz-eyeVec;
float d = length(oEyeVec.xy);
float ld = min(d, 2560.0);
- vec3 lpos = position;
- lpos.xy = eyeVec.xy + oEyeVec.xy/d*ld;
+ pos.xy = eyeVec.xy + oEyeVec.xy/d*ld;
view.xyz = oEyeVec;
d = clamp(ld/1536.0-0.5, 0.0, 1.0);
d *= d;
- oPosition = vec4(lpos, 1.0);
+ oPosition = vec4(position, 1.0);
oPosition.z = mix(oPosition.z, max(eyeVec.z*0.75, 0.0), d);
oPosition = modelViewProj * oPosition;
+
refCoord.xyz = oPosition.xyz + vec3(0,0,0.2);
//get wave position parameter (create sweeping horizontal waves)
- vec3 v = lpos;
+ vec3 v = pos.xyz;
v.x += (cos(v.x*0.08/*+time*0.01*/)+sin(v.y*0.02))*6.0;
//push position for further horizon effect.
- vec4 pos;
pos.xyz = oEyeVec.xyz*(waterHeight/oEyeVec.z);
pos.w = 1.0;
pos = modelview_matrix*pos;
diff --git a/indra/newview/app_settings/shaders/class1/interface/alphamaskF.glsl b/indra/newview/app_settings/shaders/class1/interface/alphamaskF.glsl
index f520f301d9..f520f301d9 100644..100755
--- a/indra/newview/app_settings/shaders/class1/interface/alphamaskF.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/alphamaskF.glsl
diff --git a/indra/newview/app_settings/shaders/class1/interface/alphamaskV.glsl b/indra/newview/app_settings/shaders/class1/interface/alphamaskV.glsl
index 3580d1f27b..3580d1f27b 100644..100755
--- a/indra/newview/app_settings/shaders/class1/interface/alphamaskV.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/alphamaskV.glsl
diff --git a/indra/newview/app_settings/shaders/class1/interface/clipF.glsl b/indra/newview/app_settings/shaders/class1/interface/clipF.glsl
new file mode 100755
index 0000000000..ac2bc8703b
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/interface/clipF.glsl
@@ -0,0 +1,46 @@
+/**
+ * @file debugF.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_color;
+#else
+#define frag_color gl_FragColor
+#endif
+
+uniform vec4 color;
+uniform vec4 clip_plane;
+
+VARYING vec3 vary_position;
+
+
+void main()
+{
+ if (dot(vary_position,clip_plane.xyz)+clip_plane.w < 0.0)
+ {
+ discard;
+ }
+
+ frag_color = color;
+}
diff --git a/indra/newview/app_settings/shaders/class1/interface/clipV.glsl b/indra/newview/app_settings/shaders/class1/interface/clipV.glsl
new file mode 100755
index 0000000000..e376b25a71
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/interface/clipV.glsl
@@ -0,0 +1,38 @@
+/**
+ * @file debugV.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+uniform mat4 modelview_projection_matrix;
+uniform mat4 modelview_matrix;
+
+ATTRIBUTE vec3 position;
+
+VARYING vec3 vary_position;
+
+void main()
+{
+ vary_position = (modelview_matrix*vec4(position.xyz,1.0)).xyz;
+ gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
+}
+
diff --git a/indra/newview/app_settings/shaders/class1/interface/customalphaF.glsl b/indra/newview/app_settings/shaders/class1/interface/customalphaF.glsl
index a96d04cc39..a96d04cc39 100644..100755
--- a/indra/newview/app_settings/shaders/class1/interface/customalphaF.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/customalphaF.glsl
diff --git a/indra/newview/app_settings/shaders/class1/interface/customalphaV.glsl b/indra/newview/app_settings/shaders/class1/interface/customalphaV.glsl
index 890474d6d8..890474d6d8 100644..100755
--- a/indra/newview/app_settings/shaders/class1/interface/customalphaV.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/customalphaV.glsl
diff --git a/indra/newview/app_settings/shaders/class1/interface/debugF.glsl b/indra/newview/app_settings/shaders/class1/interface/debugF.glsl
index 67c6baddbb..67c6baddbb 100644..100755
--- a/indra/newview/app_settings/shaders/class1/interface/debugF.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/debugF.glsl
diff --git a/indra/newview/app_settings/shaders/class1/interface/debugV.glsl b/indra/newview/app_settings/shaders/class1/interface/debugV.glsl
index f4d704577a..f4d704577a 100644..100755
--- a/indra/newview/app_settings/shaders/class1/interface/debugV.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/debugV.glsl
diff --git a/indra/newview/app_settings/shaders/class1/interface/downsampleDepthF.glsl b/indra/newview/app_settings/shaders/class1/interface/downsampleDepthF.glsl
new file mode 100644
index 0000000000..f8efd7cb4a
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/interface/downsampleDepthF.glsl
@@ -0,0 +1,65 @@
+/**
+ * @file debugF.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_color;
+#else
+#define frag_color gl_FragColor
+#endif
+
+uniform sampler2D depthMap;
+
+VARYING vec2 tc0;
+VARYING vec2 tc1;
+VARYING vec2 tc2;
+VARYING vec2 tc3;
+VARYING vec2 tc4;
+VARYING vec2 tc5;
+VARYING vec2 tc6;
+VARYING vec2 tc7;
+VARYING vec2 tc8;
+
+void main()
+{
+ vec4 depth1 =
+ vec4(texture2D(depthMap, tc0).r,
+ texture2D(depthMap, tc1).r,
+ texture2D(depthMap, tc2).r,
+ texture2D(depthMap, tc3).r);
+
+ vec4 depth2 =
+ vec4(texture2D(depthMap, tc4).r,
+ texture2D(depthMap, tc5).r,
+ texture2D(depthMap, tc6).r,
+ texture2D(depthMap, tc7).r);
+
+ depth1 = min(depth1, depth2);
+ float depth = min(depth1.x, depth1.y);
+ depth = min(depth, depth1.z);
+ depth = min(depth, depth1.w);
+ depth = min(depth, texture2D(depthMap, tc8).r);
+
+ gl_FragDepth = depth;
+}
diff --git a/indra/newview/app_settings/shaders/class1/interface/downsampleDepthRectF.glsl b/indra/newview/app_settings/shaders/class1/interface/downsampleDepthRectF.glsl
new file mode 100644
index 0000000000..942c5888e7
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/interface/downsampleDepthRectF.glsl
@@ -0,0 +1,67 @@
+/**
+ * @file debugF.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#extension GL_ARB_texture_rectangle : enable
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_color;
+#else
+#define frag_color gl_FragColor
+#endif
+
+uniform sampler2DRect depthMap;
+
+VARYING vec2 tc0;
+VARYING vec2 tc1;
+VARYING vec2 tc2;
+VARYING vec2 tc3;
+VARYING vec2 tc4;
+VARYING vec2 tc5;
+VARYING vec2 tc6;
+VARYING vec2 tc7;
+VARYING vec2 tc8;
+
+void main()
+{
+ vec4 depth1 =
+ vec4(texture2DRect(depthMap, tc0).r,
+ texture2DRect(depthMap, tc1).r,
+ texture2DRect(depthMap, tc2).r,
+ texture2DRect(depthMap, tc3).r);
+
+ vec4 depth2 =
+ vec4(texture2DRect(depthMap, tc4).r,
+ texture2DRect(depthMap, tc5).r,
+ texture2DRect(depthMap, tc6).r,
+ texture2DRect(depthMap, tc7).r);
+
+ depth1 = min(depth1, depth2);
+ float depth = min(depth1.x, depth1.y);
+ depth = min(depth, depth1.z);
+ depth = min(depth, depth1.w);
+ depth = min(depth, texture2DRect(depthMap, tc8).r);
+
+ gl_FragDepth = depth;
+}
diff --git a/indra/newview/app_settings/shaders/class1/interface/downsampleDepthV.glsl b/indra/newview/app_settings/shaders/class1/interface/downsampleDepthV.glsl
new file mode 100644
index 0000000000..71d80911d6
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/interface/downsampleDepthV.glsl
@@ -0,0 +1,59 @@
+/**
+ * @file debugV.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+uniform mat4 modelview_projection_matrix;
+
+ATTRIBUTE vec3 position;
+
+uniform vec2 screen_res;
+
+uniform vec2 delta;
+
+VARYING vec2 tc0;
+VARYING vec2 tc1;
+VARYING vec2 tc2;
+VARYING vec2 tc3;
+VARYING vec2 tc4;
+VARYING vec2 tc5;
+VARYING vec2 tc6;
+VARYING vec2 tc7;
+VARYING vec2 tc8;
+
+void main()
+{
+ gl_Position = vec4(position, 1.0);
+
+ vec2 tc = (position.xy*0.5+0.5)*screen_res;
+ tc0 = tc+vec2(-delta.x,-delta.y);
+ tc1 = tc+vec2(0,-delta.y);
+ tc2 = tc+vec2(delta.x,-delta.y);
+ tc3 = tc+vec2(-delta.x,0);
+ tc4 = tc+vec2(0,0);
+ tc5 = tc+vec2(delta.x,0);
+ tc6 = tc+vec2(-delta.x,delta.y);
+ tc7 = tc+vec2(0,delta.y);
+ tc8 = tc+vec2(delta.x,delta.y);
+}
+
diff --git a/indra/newview/app_settings/shaders/class1/interface/glowcombineF.glsl b/indra/newview/app_settings/shaders/class1/interface/glowcombineF.glsl
index ed803de277..ed803de277 100644..100755
--- a/indra/newview/app_settings/shaders/class1/interface/glowcombineF.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/glowcombineF.glsl
diff --git a/indra/newview/app_settings/shaders/class1/interface/glowcombineFXAAF.glsl b/indra/newview/app_settings/shaders/class1/interface/glowcombineFXAAF.glsl
index 59520bb99f..59520bb99f 100644..100755
--- a/indra/newview/app_settings/shaders/class1/interface/glowcombineFXAAF.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/glowcombineFXAAF.glsl
diff --git a/indra/newview/app_settings/shaders/class1/interface/glowcombineFXAAV.glsl b/indra/newview/app_settings/shaders/class1/interface/glowcombineFXAAV.glsl
index 058f3b1b82..058f3b1b82 100644..100755
--- a/indra/newview/app_settings/shaders/class1/interface/glowcombineFXAAV.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/glowcombineFXAAV.glsl
diff --git a/indra/newview/app_settings/shaders/class1/interface/glowcombineV.glsl b/indra/newview/app_settings/shaders/class1/interface/glowcombineV.glsl
index f7970b7f78..f7970b7f78 100644..100755
--- a/indra/newview/app_settings/shaders/class1/interface/glowcombineV.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/glowcombineV.glsl
diff --git a/indra/newview/app_settings/shaders/class1/interface/highlightF.glsl b/indra/newview/app_settings/shaders/class1/interface/highlightF.glsl
index 6cc9bbbea2..6cc9bbbea2 100644..100755
--- a/indra/newview/app_settings/shaders/class1/interface/highlightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/highlightF.glsl
diff --git a/indra/newview/app_settings/shaders/class1/interface/highlightNormV.glsl b/indra/newview/app_settings/shaders/class1/interface/highlightNormV.glsl
new file mode 100644
index 0000000000..947c2b0065
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/interface/highlightNormV.glsl
@@ -0,0 +1,42 @@
+/**
+ * @file highlightV.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, 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$
+ */
+
+uniform mat4 texture_matrix0;
+uniform mat4 modelview_projection_matrix;
+
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec2 texcoord0;
+ATTRIBUTE vec2 texcoord1;
+ATTRIBUTE vec2 texcoord2;
+
+VARYING vec2 vary_texcoord0;
+
+void main()
+{
+ //transform vertex
+ gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
+ vary_texcoord0 = (texture_matrix0 * vec4(texcoord1,0,1)).xy;
+}
+
diff --git a/indra/newview/app_settings/shaders/class1/interface/highlightSpecV.glsl b/indra/newview/app_settings/shaders/class1/interface/highlightSpecV.glsl
new file mode 100644
index 0000000000..c5d102b739
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/interface/highlightSpecV.glsl
@@ -0,0 +1,42 @@
+/**
+ * @file highlightV.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, 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$
+ */
+
+uniform mat4 texture_matrix0;
+uniform mat4 modelview_projection_matrix;
+
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec2 texcoord0;
+ATTRIBUTE vec2 texcoord1;
+ATTRIBUTE vec2 texcoord2;
+
+VARYING vec2 vary_texcoord0;
+
+void main()
+{
+ //transform vertex
+ gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
+ vary_texcoord0 = (texture_matrix0 * vec4(texcoord2,0,1)).xy;
+}
+
diff --git a/indra/newview/app_settings/shaders/class1/interface/highlightV.glsl b/indra/newview/app_settings/shaders/class1/interface/highlightV.glsl
index 9bf7b60eb7..9bf7b60eb7 100644..100755
--- a/indra/newview/app_settings/shaders/class1/interface/highlightV.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/highlightV.glsl
diff --git a/indra/newview/app_settings/shaders/class1/interface/occlusionCubeV.glsl b/indra/newview/app_settings/shaders/class1/interface/occlusionCubeV.glsl
new file mode 100755
index 0000000000..5c479d27a9
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/interface/occlusionCubeV.glsl
@@ -0,0 +1,38 @@
+/**
+ * @file occlusionCubeV.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, 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$
+ */
+
+uniform mat4 modelview_projection_matrix;
+
+ATTRIBUTE vec3 position;
+
+uniform vec3 box_center;
+uniform vec3 box_size;
+
+void main()
+{
+ vec3 p = position*box_size+box_center;
+ gl_Position = modelview_projection_matrix * vec4(p.xyz, 1.0);
+}
+
diff --git a/indra/newview/app_settings/shaders/class1/interface/occlusionF.glsl b/indra/newview/app_settings/shaders/class1/interface/occlusionF.glsl
index db130e456c..db130e456c 100644..100755
--- a/indra/newview/app_settings/shaders/class1/interface/occlusionF.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/occlusionF.glsl
diff --git a/indra/newview/app_settings/shaders/class1/interface/occlusionV.glsl b/indra/newview/app_settings/shaders/class1/interface/occlusionV.glsl
index c26fa08ddc..c26fa08ddc 100644..100755
--- a/indra/newview/app_settings/shaders/class1/interface/occlusionV.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/occlusionV.glsl
diff --git a/indra/newview/app_settings/shaders/class1/interface/onetexturenocolorF.glsl b/indra/newview/app_settings/shaders/class1/interface/onetexturenocolorF.glsl
index 415181126b..415181126b 100644..100755
--- a/indra/newview/app_settings/shaders/class1/interface/onetexturenocolorF.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/onetexturenocolorF.glsl
diff --git a/indra/newview/app_settings/shaders/class1/interface/onetexturenocolorV.glsl b/indra/newview/app_settings/shaders/class1/interface/onetexturenocolorV.glsl
index 6b9986c8d7..6b9986c8d7 100644..100755
--- a/indra/newview/app_settings/shaders/class1/interface/onetexturenocolorV.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/onetexturenocolorV.glsl
diff --git a/indra/newview/app_settings/shaders/class1/interface/pathfindingF.glsl b/indra/newview/app_settings/shaders/class1/interface/pathfindingF.glsl
new file mode 100755
index 0000000000..7379360e17
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/interface/pathfindingF.glsl
@@ -0,0 +1,37 @@
+/**
+ * @file pathfindingF.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, 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$
+ */
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_color;
+#else
+#define frag_color gl_FragColor
+#endif
+
+VARYING vec4 vertex_color;
+
+void main()
+{
+ frag_color = vertex_color;
+}
diff --git a/indra/newview/app_settings/shaders/class1/interface/pathfindingNoNormalV.glsl b/indra/newview/app_settings/shaders/class1/interface/pathfindingNoNormalV.glsl
new file mode 100755
index 0000000000..19fa607307
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/interface/pathfindingNoNormalV.glsl
@@ -0,0 +1,42 @@
+/**
+ * @file pathfindingV.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, 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$
+ */
+
+uniform mat4 modelview_projection_matrix;
+
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec4 diffuse_color;
+
+VARYING vec4 vertex_color;
+
+uniform float tint;
+uniform float alpha_scale;
+
+void main()
+{
+ gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
+
+ vertex_color = vec4(diffuse_color.rgb * tint, diffuse_color.a*alpha_scale);
+}
+
diff --git a/indra/newview/app_settings/shaders/class1/interface/pathfindingV.glsl b/indra/newview/app_settings/shaders/class1/interface/pathfindingV.glsl
new file mode 100755
index 0000000000..91f252cf1e
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/interface/pathfindingV.glsl
@@ -0,0 +1,54 @@
+/**
+ * @file pathfindingV.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, 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$
+ */
+
+uniform mat4 modelview_projection_matrix;
+
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec4 diffuse_color;
+ATTRIBUTE vec3 normal;
+
+VARYING vec4 vertex_color;
+
+uniform float tint;
+uniform float ambiance;
+uniform float alpha_scale;
+
+void main()
+{
+ gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
+
+ vec3 l1 = vec3(-0.75, 1, 1.0)*0.5;
+ vec3 l2 = vec3(0.5, -0.6, 0.4)*0.25;
+ vec3 l3 = vec3(0.5, -0.8, 0.3)*0.5;
+
+ float lit = max(dot(normal, l1), 0.0);
+ lit += max(dot(normal, l2), 0.0);
+ lit += max(dot(normal, l3), 0.0);
+
+ lit = clamp(lit, ambiance, 1.0);
+
+ vertex_color = vec4(diffuse_color.rgb * tint * lit, diffuse_color.a*alpha_scale);
+}
+
diff --git a/indra/newview/app_settings/shaders/class1/interface/solidcolorF.glsl b/indra/newview/app_settings/shaders/class1/interface/solidcolorF.glsl
index 67dc500493..67dc500493 100644..100755
--- a/indra/newview/app_settings/shaders/class1/interface/solidcolorF.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/solidcolorF.glsl
diff --git a/indra/newview/app_settings/shaders/class1/interface/solidcolorV.glsl b/indra/newview/app_settings/shaders/class1/interface/solidcolorV.glsl
index c58f9dfdaf..c58f9dfdaf 100644..100755
--- a/indra/newview/app_settings/shaders/class1/interface/solidcolorV.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/solidcolorV.glsl
diff --git a/indra/newview/app_settings/shaders/class1/interface/splattexturerectF.glsl b/indra/newview/app_settings/shaders/class1/interface/splattexturerectF.glsl
index 772bb374e8..772bb374e8 100644..100755
--- a/indra/newview/app_settings/shaders/class1/interface/splattexturerectF.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/splattexturerectF.glsl
diff --git a/indra/newview/app_settings/shaders/class1/interface/splattexturerectV.glsl b/indra/newview/app_settings/shaders/class1/interface/splattexturerectV.glsl
index 641d670c26..641d670c26 100644..100755
--- a/indra/newview/app_settings/shaders/class1/interface/splattexturerectV.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/splattexturerectV.glsl
diff --git a/indra/newview/app_settings/shaders/class1/interface/twotextureaddF.glsl b/indra/newview/app_settings/shaders/class1/interface/twotextureaddF.glsl
index 95679e93e7..95679e93e7 100644..100755
--- a/indra/newview/app_settings/shaders/class1/interface/twotextureaddF.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/twotextureaddF.glsl
diff --git a/indra/newview/app_settings/shaders/class1/interface/twotextureaddV.glsl b/indra/newview/app_settings/shaders/class1/interface/twotextureaddV.glsl
index 3c2f297f7f..3c2f297f7f 100644..100755
--- a/indra/newview/app_settings/shaders/class1/interface/twotextureaddV.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/twotextureaddV.glsl
diff --git a/indra/newview/app_settings/shaders/class1/interface/uiF.glsl b/indra/newview/app_settings/shaders/class1/interface/uiF.glsl
index 299bfb72aa..299bfb72aa 100644..100755
--- a/indra/newview/app_settings/shaders/class1/interface/uiF.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/uiF.glsl
diff --git a/indra/newview/app_settings/shaders/class1/interface/uiV.glsl b/indra/newview/app_settings/shaders/class1/interface/uiV.glsl
index 220dafef25..220dafef25 100644..100755
--- a/indra/newview/app_settings/shaders/class1/interface/uiV.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/uiV.glsl
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskF.glsl
index cf29939cb2..cad5b9ff04 100644..100755
--- a/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskF.glsl
@@ -39,8 +39,10 @@ VARYING vec2 vary_texcoord0;
void default_lighting()
{
- vec4 color = diffuseLookup(vary_texcoord0.xy) * vertex_color;
+ vec4 color = diffuseLookup(vary_texcoord0.xy);
+ color *= vertex_color;
+
if (color.a < minimum_alpha)
{
discard;
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskNonIndexedF.glsl
index 4070d41f47..b9ddbc8e1c 100644..100755
--- a/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskNonIndexedF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskNonIndexedF.glsl
@@ -41,13 +41,15 @@ VARYING vec2 vary_texcoord0;
void default_lighting()
{
- vec4 color = texture2D(diffuseMap,vary_texcoord0.xy) * vertex_color;
+ vec4 color = texture2D(diffuseMap,vary_texcoord0.xy);
if (color.a < minimum_alpha)
{
discard;
}
+ color.rgb *= vertex_color.rgb;
+
color.rgb = atmosLighting(color.rgb);
color.rgb = scaleSoftClip(color.rgb);
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightF.glsl
index d6ebfcb825..d6ebfcb825 100644..100755
--- a/indra/newview/app_settings/shaders/class1/lighting/lightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightF.glsl
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightAlphaMaskF.glsl
index 6c34643aab..5740987ab1 100644..100755
--- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightAlphaMaskF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightAlphaMaskF.glsl
@@ -30,6 +30,7 @@ out vec4 frag_color;
#endif
uniform float minimum_alpha;
+uniform float texture_gamma;
vec3 fullbrightAtmosTransport(vec3 light);
vec3 fullbrightScaleSoftClip(vec3 light);
@@ -39,13 +40,16 @@ VARYING vec2 vary_texcoord0;
void fullbright_lighting()
{
- vec4 color = diffuseLookup(vary_texcoord0.xy) * vertex_color;
+ vec4 color = diffuseLookup(vary_texcoord0.xy);
if (color.a < minimum_alpha)
{
discard;
}
+ color.rgb *= vertex_color.rgb;
+
+ color.rgb = pow(color.rgb, vec3(texture_gamma));
color.rgb = fullbrightAtmosTransport(color.rgb);
color.rgb = fullbrightScaleSoftClip(color.rgb);
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl
index 2ff7f795b0..c8771a3f1e 100644..100755
--- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl
@@ -32,6 +32,8 @@ out vec4 frag_color;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
+uniform float texture_gamma;
+
vec3 fullbrightAtmosTransport(vec3 light);
vec3 fullbrightScaleSoftClip(vec3 light);
@@ -39,10 +41,14 @@ void fullbright_lighting()
{
vec4 color = diffuseLookup(vary_texcoord0.xy) * vertex_color;
+ color.rgb = pow(color.rgb, vec3(texture_gamma));
+
color.rgb = fullbrightAtmosTransport(color.rgb);
color.rgb = fullbrightScaleSoftClip(color.rgb);
+ color.rgb = pow(color.rgb, vec3(1.0/texture_gamma));
+
frag_color = color;
}
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightNonIndexedAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightNonIndexedAlphaMaskF.glsl
index f4477bd29a..f72f20b03d 100644..100755
--- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightNonIndexedAlphaMaskF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightNonIndexedAlphaMaskF.glsl
@@ -30,6 +30,7 @@ out vec4 frag_color;
#endif
uniform float minimum_alpha;
+uniform float texture_gamma;
vec3 fullbrightAtmosTransport(vec3 light);
vec3 fullbrightScaleSoftClip(vec3 light);
@@ -41,17 +42,22 @@ VARYING vec2 vary_texcoord0;
void fullbright_lighting()
{
- vec4 color = texture2D(diffuseMap,vary_texcoord0.xy) * vertex_color;
+ vec4 color = texture2D(diffuseMap,vary_texcoord0.xy);
if (color.a < minimum_alpha)
{
discard;
}
+
+ color.rgb *= vertex_color.rgb;
+ color.rgb = pow(color.rgb, vec3(texture_gamma));
color.rgb = fullbrightAtmosTransport(color.rgb);
color.rgb = fullbrightScaleSoftClip(color.rgb);
+ color.rgb = pow(color.rgb, vec3(1.0/texture_gamma));
+
frag_color = color;
}
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightNonIndexedF.glsl
index 2738ff8947..2738ff8947 100644..100755
--- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightNonIndexedF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightNonIndexedF.glsl
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyF.glsl
index 777c8b45bb..c8282e9a51 100644..100755
--- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyF.glsl
@@ -50,7 +50,7 @@ void fullbright_shiny_lighting()
color.rgb = fullbrightScaleSoftClip(color.rgb);
- color.a = max(color.a, vertex_color.a);
+ color.a = 1.0;
frag_color = color;
}
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyNonIndexedF.glsl
index 4fa3b1d939..e7dbd4bbd2 100644..100755
--- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyNonIndexedF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyNonIndexedF.glsl
@@ -51,7 +51,7 @@ void fullbright_shiny_lighting()
color.rgb = fullbrightScaleSoftClip(color.rgb);
- color.a = max(color.a, vertex_color.a);
+ color.a = 1.0;
frag_color = color;
}
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterF.glsl
index 58984a4263..5886fc65be 100644..100755
--- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterF.glsl
@@ -48,7 +48,7 @@ void fullbright_shiny_lighting_water()
color.rgb = fullbrightShinyAtmosTransport(color.rgb);
color.rgb = fullbrightScaleSoftClip(color.rgb);
- color.a = max(color.a, vertex_color.a);
+ color.a = 1.0;
frag_color = applyWaterFog(color);
}
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterNonIndexedF.glsl
index a39b7205d7..cddc7d8df8 100644..100755
--- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterNonIndexedF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterNonIndexedF.glsl
@@ -49,7 +49,7 @@ void fullbright_shiny_lighting_water()
color.rgb = fullbrightShinyAtmosTransport(color.rgb);
color.rgb = fullbrightScaleSoftClip(color.rgb);
- color.a = max(color.a, vertex_color.a);
+ color.a = 1.0;
frag_color = applyWaterFog(color);
}
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterAlphaMaskF.glsl
index 99a6fe85fe..6dd3bb937f 100644..100755
--- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterAlphaMaskF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterAlphaMaskF.glsl
@@ -31,7 +31,7 @@ out vec4 frag_color;
uniform float minimum_alpha;
-vec4 diffuseLookup(vec2 texcoord);
+/* vec4 diffuseLookup(vec2 texcoord); */
vec3 fullbrightAtmosTransport(vec3 light);
vec4 applyWaterFog(vec4 color);
@@ -41,7 +41,9 @@ VARYING vec2 vary_texcoord0;
void fullbright_lighting_water()
{
- vec4 color = diffuseLookup(vary_texcoord0.xy) * vertex_color;
+ vec4 color = diffuseLookup(vary_texcoord0.xy);
+
+ color.rgb *= vertex_color.rgb;
if (color.a < minimum_alpha)
{
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterF.glsl
index df182168f3..d3dacf9bc4 100644..100755
--- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterF.glsl
@@ -32,7 +32,7 @@ out vec4 frag_color;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
-vec4 diffuseLookup(vec2 texcoord);
+/* vec4 diffuseLookup(vec2 texcoord); */
vec3 fullbrightAtmosTransport(vec3 light);
vec4 applyWaterFog(vec4 color);
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterNonIndexedAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterNonIndexedAlphaMaskF.glsl
index 63f92a8844..63f92a8844 100644..100755
--- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterNonIndexedAlphaMaskF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterNonIndexedAlphaMaskF.glsl
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterNonIndexedF.glsl
index 0e68091e7c..0e68091e7c 100644..100755
--- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterNonIndexedF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterNonIndexedF.glsl
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFuncSpecularV.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFuncSpecularV.glsl
index 85cddc647d..85cddc647d 100644..100755
--- a/indra/newview/app_settings/shaders/class1/lighting/lightFuncSpecularV.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightFuncSpecularV.glsl
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFuncV.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFuncV.glsl
index a9288b3df6..a9288b3df6 100644..100755
--- a/indra/newview/app_settings/shaders/class1/lighting/lightFuncV.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightFuncV.glsl
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightNonIndexedF.glsl
index 0aca768021..0aca768021 100644..100755
--- a/indra/newview/app_settings/shaders/class1/lighting/lightNonIndexedF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightNonIndexedF.glsl
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightShinyF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightShinyF.glsl
index 52e3b2ad02..9208c148ef 100644..100755
--- a/indra/newview/app_settings/shaders/class1/lighting/lightShinyF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightShinyF.glsl
@@ -50,7 +50,7 @@ void shiny_lighting()
color.rgb = atmosLighting(color.rgb);
color.rgb = scaleSoftClip(color.rgb);
- color.a = max(color.a, vertex_color.a);
+ color.a = 1.0;
frag_color = color;
}
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightShinyNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightShinyNonIndexedF.glsl
index 474d5ea496..92628faa68 100644..100755
--- a/indra/newview/app_settings/shaders/class1/lighting/lightShinyNonIndexedF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightShinyNonIndexedF.glsl
@@ -51,7 +51,7 @@ void shiny_lighting()
color.rgb = atmosLighting(color.rgb);
color.rgb = scaleSoftClip(color.rgb);
- color.a = max(color.a, vertex_color.a);
+ color.a = 1.0;
frag_color = color;
}
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterF.glsl
index d2a4c47aac..61841674e2 100644..100755
--- a/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterF.glsl
@@ -47,7 +47,7 @@ void shiny_lighting_water()
color.rgb = mix(color.rgb, envColor.rgb, vertex_color.a);
color.rgb = atmosLighting(color.rgb);
- color.a = max(color.a, vertex_color.a);
+ color.a = 1.0;
frag_color = applyWaterFog(color);
}
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterNonIndexedF.glsl
index f3bd662364..0b6e835fd0 100644..100755
--- a/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterNonIndexedF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterNonIndexedF.glsl
@@ -48,7 +48,7 @@ void shiny_lighting_water()
color.rgb = mix(color.rgb, envColor.rgb, vertex_color.a);
color.rgb = atmosLighting(color.rgb);
- color.a = max(color.a, vertex_color.a);
+ color.a = 1.0;
frag_color = applyWaterFog(color);
}
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightSpecularV.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightSpecularV.glsl
index 24bf9b3cee..24bf9b3cee 100644..100755
--- a/indra/newview/app_settings/shaders/class1/lighting/lightSpecularV.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightSpecularV.glsl
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightV.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightV.glsl
index 8045809b82..8045809b82 100644..100755
--- a/indra/newview/app_settings/shaders/class1/lighting/lightV.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightV.glsl
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskF.glsl
index b68240ba0d..3426fea52f 100644..100755
--- a/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskF.glsl
@@ -39,7 +39,9 @@ VARYING vec2 vary_texcoord0;
void default_lighting_water()
{
- vec4 color = diffuseLookup(vary_texcoord0.xy) * vertex_color;
+ vec4 color = diffuseLookup(vary_texcoord0.xy);
+
+ color.rgb *= vertex_color.rgb;
if (color.a < minimum_alpha)
{
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskNonIndexedF.glsl
index da3b20012d..d9faa9b314 100644..100755
--- a/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskNonIndexedF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskNonIndexedF.glsl
@@ -41,7 +41,9 @@ VARYING vec2 vary_texcoord0;
void default_lighting_water()
{
- vec4 color = texture2D(diffuseMap,vary_texcoord0.xy) * vertex_color;
+ vec4 color = texture2D(diffuseMap,vary_texcoord0.xy);
+
+ color.rgb *= vertex_color.rgb;
if (color.a < minimum_alpha)
{
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightWaterF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightWaterF.glsl
index 00609e93cd..00609e93cd 100644..100755
--- a/indra/newview/app_settings/shaders/class1/lighting/lightWaterF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightWaterF.glsl
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightWaterNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightWaterNonIndexedF.glsl
index 13ecb7a636..13ecb7a636 100644..100755
--- a/indra/newview/app_settings/shaders/class1/lighting/lightWaterNonIndexedF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightWaterNonIndexedF.glsl
diff --git a/indra/newview/app_settings/shaders/class1/lighting/sumLightsSpecularV.glsl b/indra/newview/app_settings/shaders/class1/lighting/sumLightsSpecularV.glsl
index 7059ff31ae..7059ff31ae 100644..100755
--- a/indra/newview/app_settings/shaders/class1/lighting/sumLightsSpecularV.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/sumLightsSpecularV.glsl
diff --git a/indra/newview/app_settings/shaders/class1/lighting/sumLightsV.glsl b/indra/newview/app_settings/shaders/class1/lighting/sumLightsV.glsl
index 41288c21c1..41288c21c1 100644..100755
--- a/indra/newview/app_settings/shaders/class1/lighting/sumLightsV.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/sumLightsV.glsl
diff --git a/indra/newview/app_settings/shaders/class1/objects/bumpF.glsl b/indra/newview/app_settings/shaders/class1/objects/bumpF.glsl
index d55f0db530..d55f0db530 100644..100755
--- a/indra/newview/app_settings/shaders/class1/objects/bumpF.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/bumpF.glsl
diff --git a/indra/newview/app_settings/shaders/class1/objects/bumpV.glsl b/indra/newview/app_settings/shaders/class1/objects/bumpV.glsl
index a7738087dc..a7738087dc 100644..100755
--- a/indra/newview/app_settings/shaders/class1/objects/bumpV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/bumpV.glsl
diff --git a/indra/newview/app_settings/shaders/class1/objects/emissiveSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/objects/emissiveSkinnedV.glsl
index 8494ffba52..9064904191 100644..100755
--- a/indra/newview/app_settings/shaders/class1/objects/emissiveSkinnedV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/emissiveSkinnedV.glsl
@@ -48,11 +48,9 @@ void main()
mat = modelview_matrix * mat;
vec3 pos = (mat*vec4(position.xyz, 1.0)).xyz;
+ vertex_color = emissive;
+
calcAtmospherics(pos.xyz);
- vertex_color = emissive;
-
gl_Position = projection_matrix*vec4(pos, 1.0);
-
-
}
diff --git a/indra/newview/app_settings/shaders/class1/objects/emissiveV.glsl b/indra/newview/app_settings/shaders/class1/objects/emissiveV.glsl
index e984deb0c8..e984deb0c8 100644..100755
--- a/indra/newview/app_settings/shaders/class1/objects/emissiveV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/emissiveV.glsl
diff --git a/indra/newview/app_settings/shaders/class1/objects/fullbrightF.glsl b/indra/newview/app_settings/shaders/class1/objects/fullbrightF.glsl
index a54c0caf81..a54c0caf81 100644..100755
--- a/indra/newview/app_settings/shaders/class1/objects/fullbrightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/fullbrightF.glsl
diff --git a/indra/newview/app_settings/shaders/class1/objects/fullbrightNoColorV.glsl b/indra/newview/app_settings/shaders/class1/objects/fullbrightNoColorV.glsl
index 5d6f14230c..5d6f14230c 100644..100755
--- a/indra/newview/app_settings/shaders/class1/objects/fullbrightNoColorV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/fullbrightNoColorV.glsl
diff --git a/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyF.glsl b/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyF.glsl
index b312665032..b312665032 100644..100755
--- a/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyF.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyF.glsl
diff --git a/indra/newview/app_settings/shaders/class1/objects/fullbrightShinySkinnedV.glsl b/indra/newview/app_settings/shaders/class1/objects/fullbrightShinySkinnedV.glsl
index 79b552ee1a..79b552ee1a 100644..100755
--- a/indra/newview/app_settings/shaders/class1/objects/fullbrightShinySkinnedV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/fullbrightShinySkinnedV.glsl
diff --git a/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyV.glsl b/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyV.glsl
index 34bd8d445a..34bd8d445a 100644..100755
--- a/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyV.glsl
diff --git a/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyWaterF.glsl b/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyWaterF.glsl
index e1f3919907..e1f3919907 100644..100755
--- a/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyWaterF.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyWaterF.glsl
diff --git a/indra/newview/app_settings/shaders/class1/objects/fullbrightSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/objects/fullbrightSkinnedV.glsl
index eff75435a9..eff75435a9 100644..100755
--- a/indra/newview/app_settings/shaders/class1/objects/fullbrightSkinnedV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/fullbrightSkinnedV.glsl
diff --git a/indra/newview/app_settings/shaders/class1/objects/fullbrightV.glsl b/indra/newview/app_settings/shaders/class1/objects/fullbrightV.glsl
index fc20d3270e..fc20d3270e 100644..100755
--- a/indra/newview/app_settings/shaders/class1/objects/fullbrightV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/fullbrightV.glsl
diff --git a/indra/newview/app_settings/shaders/class1/objects/fullbrightWaterF.glsl b/indra/newview/app_settings/shaders/class1/objects/fullbrightWaterF.glsl
index 5d0ea0a8dd..5d0ea0a8dd 100644..100755
--- a/indra/newview/app_settings/shaders/class1/objects/fullbrightWaterF.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/fullbrightWaterF.glsl
diff --git a/indra/newview/app_settings/shaders/class1/objects/impostorF.glsl b/indra/newview/app_settings/shaders/class1/objects/impostorF.glsl
index add437d144..add437d144 100644..100755
--- a/indra/newview/app_settings/shaders/class1/objects/impostorF.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/impostorF.glsl
diff --git a/indra/newview/app_settings/shaders/class1/objects/impostorV.glsl b/indra/newview/app_settings/shaders/class1/objects/impostorV.glsl
index e90dbb115a..e90dbb115a 100644..100755
--- a/indra/newview/app_settings/shaders/class1/objects/impostorV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/impostorV.glsl
diff --git a/indra/newview/app_settings/shaders/class1/objects/indexedTextureF.glsl b/indra/newview/app_settings/shaders/class1/objects/indexedTextureF.glsl
index 254c1d4fc2..254c1d4fc2 100644..100755
--- a/indra/newview/app_settings/shaders/class1/objects/indexedTextureF.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/indexedTextureF.glsl
diff --git a/indra/newview/app_settings/shaders/class1/objects/indexedTextureV.glsl b/indra/newview/app_settings/shaders/class1/objects/indexedTextureV.glsl
index 7c0699d72f..ca29bf3143 100644..100755
--- a/indra/newview/app_settings/shaders/class1/objects/indexedTextureV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/indexedTextureV.glsl
@@ -23,9 +23,9 @@
* $/LicenseInfo$
*/
-ATTRIBUTE ivec4 texture_index;
+ATTRIBUTE int texture_index;
-VARYING_FLAT ivec4 vary_texture_index;
+VARYING_FLAT int vary_texture_index;
void passTextureIndex()
{
diff --git a/indra/newview/app_settings/shaders/class1/objects/nonindexedTextureV.glsl b/indra/newview/app_settings/shaders/class1/objects/nonindexedTextureV.glsl
index 80ea286ac0..80ea286ac0 100644..100755
--- a/indra/newview/app_settings/shaders/class1/objects/nonindexedTextureV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/nonindexedTextureV.glsl
diff --git a/indra/newview/app_settings/shaders/class1/objects/previewF.glsl b/indra/newview/app_settings/shaders/class1/objects/previewF.glsl
new file mode 100755
index 0000000000..284da3d0ac
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/objects/previewF.glsl
@@ -0,0 +1,41 @@
+/**
+ * @file previewF.glsl
+ *
+ * $LicenseInfo:firstyear=2011&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_color;
+#else
+#define frag_color gl_FragColor
+#endif
+
+uniform sampler2D diffuseMap;
+
+VARYING vec4 vertex_color;
+VARYING vec2 vary_texcoord0;
+
+void main()
+{
+ vec4 color = texture2D(diffuseMap,vary_texcoord0.xy) * vertex_color;
+ frag_color = color;
+}
diff --git a/indra/newview/app_settings/shaders/class1/objects/previewV.glsl b/indra/newview/app_settings/shaders/class1/objects/previewV.glsl
index 5dcfa87066..7f3f84398b 100644..100755
--- a/indra/newview/app_settings/shaders/class1/objects/previewV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/previewV.glsl
@@ -32,12 +32,51 @@ ATTRIBUTE vec3 position;
ATTRIBUTE vec3 normal;
ATTRIBUTE vec2 texcoord0;
+uniform vec4 color;
+
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
+uniform vec4 light_position[8];
+uniform vec3 light_direction[8];
+uniform vec3 light_attenuation[8];
+uniform vec3 light_diffuse[8];
+
+//===================================================================================================
+//declare these here explicitly to separate them from atmospheric lighting elsewhere to work around
+//drivers that are picky about functions being declared but not defined even if they aren't called
+float calcDirectionalLight(vec3 n, vec3 l)
+{
+ float a = max(dot(n,l),0.0);
+ return a;
+}
+
+
+float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float is_pointlight)
+{
+ //get light vector
+ vec3 lv = lp.xyz-v;
+
+ //get distance
+ float d = length(lv);
+
+ //normalize light vector
+ lv *= 1.0/d;
+
+ //distance attenuation
+ float da = clamp(1.0/(la * d), 0.0, 1.0);
+
+ // spotlight coefficient.
+ float spot = max(dot(-ln, lv), is_pointlight);
+ da *= spot*spot; // GL_SPOT_EXPONENT=2
+
+ //angular attenuation
+ da *= calcDirectionalLight(n, lv);
+
+ return da;
+}
+//====================================================================================================
-vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
-void calcAtmospherics(vec3 inPositionEye);
void main()
{
@@ -45,13 +84,15 @@ void main()
vec4 pos = (modelview_matrix * vec4(position.xyz, 1.0));
gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
-
+
vec3 norm = normalize(normal_matrix * normal);
- calcAtmospherics(pos.xyz);
-
- vec4 color = calcLighting(pos.xyz, norm, vec4(1,1,1,1), vec4(0.));
- vertex_color = color;
+ vec4 col = vec4(0,0,0,1);
-
+ // Collect normal lights (need to be divided by two, as we later multiply by 2)
+ col.rgb += light_diffuse[1].rgb * calcDirectionalLight(norm, light_position[1].xyz);
+ col.rgb += light_diffuse[2].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[2], light_direction[2], light_attenuation[2].x, light_attenuation[2].z);
+ col.rgb += light_diffuse[3].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[3], light_direction[3], light_attenuation[3].x, light_attenuation[3].z);
+
+ vertex_color = col*color;
}
diff --git a/indra/newview/app_settings/shaders/class1/objects/shinyF.glsl b/indra/newview/app_settings/shaders/class1/objects/shinyF.glsl
index f8f88e2577..f8f88e2577 100644..100755
--- a/indra/newview/app_settings/shaders/class1/objects/shinyF.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/shinyF.glsl
diff --git a/indra/newview/app_settings/shaders/class1/objects/shinySimpleSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/objects/shinySimpleSkinnedV.glsl
index 591d6fc5c9..591d6fc5c9 100644..100755
--- a/indra/newview/app_settings/shaders/class1/objects/shinySimpleSkinnedV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/shinySimpleSkinnedV.glsl
diff --git a/indra/newview/app_settings/shaders/class1/objects/shinyV.glsl b/indra/newview/app_settings/shaders/class1/objects/shinyV.glsl
index fdb3453cc5..fdb3453cc5 100644..100755
--- a/indra/newview/app_settings/shaders/class1/objects/shinyV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/shinyV.glsl
diff --git a/indra/newview/app_settings/shaders/class1/objects/shinyWaterF.glsl b/indra/newview/app_settings/shaders/class1/objects/shinyWaterF.glsl
index 1e72e23eef..1e72e23eef 100644..100755
--- a/indra/newview/app_settings/shaders/class1/objects/shinyWaterF.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/shinyWaterF.glsl
diff --git a/indra/newview/app_settings/shaders/class1/objects/simpleF.glsl b/indra/newview/app_settings/shaders/class1/objects/simpleF.glsl
index 29a2ce617b..29a2ce617b 100644..100755
--- a/indra/newview/app_settings/shaders/class1/objects/simpleF.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/simpleF.glsl
diff --git a/indra/newview/app_settings/shaders/class1/objects/simpleNoColorV.glsl b/indra/newview/app_settings/shaders/class1/objects/simpleNoColorV.glsl
index 0be52a52af..0be52a52af 100644..100755
--- a/indra/newview/app_settings/shaders/class1/objects/simpleNoColorV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/simpleNoColorV.glsl
diff --git a/indra/newview/app_settings/shaders/class1/objects/simpleNonIndexedV.glsl b/indra/newview/app_settings/shaders/class1/objects/simpleNonIndexedV.glsl
index cb80697d15..cb80697d15 100644..100755
--- a/indra/newview/app_settings/shaders/class1/objects/simpleNonIndexedV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/simpleNonIndexedV.glsl
diff --git a/indra/newview/app_settings/shaders/class1/objects/simpleSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/objects/simpleSkinnedV.glsl
index 1c6e53b187..1c6e53b187 100644..100755
--- a/indra/newview/app_settings/shaders/class1/objects/simpleSkinnedV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/simpleSkinnedV.glsl
diff --git a/indra/newview/app_settings/shaders/class1/objects/simpleTexGenV.glsl b/indra/newview/app_settings/shaders/class1/objects/simpleTexGenV.glsl
index d4dee78793..d4dee78793 100644..100755
--- a/indra/newview/app_settings/shaders/class1/objects/simpleTexGenV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/simpleTexGenV.glsl
diff --git a/indra/newview/app_settings/shaders/class1/objects/simpleV.glsl b/indra/newview/app_settings/shaders/class1/objects/simpleV.glsl
index 37a20383e2..37a20383e2 100644..100755
--- a/indra/newview/app_settings/shaders/class1/objects/simpleV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/simpleV.glsl
diff --git a/indra/newview/app_settings/shaders/class1/objects/simpleWaterF.glsl b/indra/newview/app_settings/shaders/class1/objects/simpleWaterF.glsl
index 2e87ac5bbc..2e87ac5bbc 100644..100755
--- a/indra/newview/app_settings/shaders/class1/objects/simpleWaterF.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/simpleWaterF.glsl
diff --git a/indra/newview/app_settings/shaders/class1/objects/treeV.glsl b/indra/newview/app_settings/shaders/class1/objects/treeV.glsl
index fa01a27ec0..fa01a27ec0 100644..100755
--- a/indra/newview/app_settings/shaders/class1/objects/treeV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/treeV.glsl
diff --git a/indra/newview/app_settings/shaders/class1/transform/binormalV.glsl b/indra/newview/app_settings/shaders/class1/transform/binormalV.glsl
new file mode 100755
index 0000000000..449d8d8b4e
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/transform/binormalV.glsl
@@ -0,0 +1,36 @@
+/**
+ * @file binormalV.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, 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$
+ */
+
+uniform mat3 normal_matrix;
+
+ATTRIBUTE vec4 tangent;
+
+VARYING vec4 tangent_out;
+
+void main()
+{
+ tangent_out = vec4(normal_matrix * tangent.xyz), tangent.w);
+}
+
diff --git a/indra/newview/app_settings/shaders/class1/transform/colorV.glsl b/indra/newview/app_settings/shaders/class1/transform/colorV.glsl
new file mode 100755
index 0000000000..59c4a7d895
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/transform/colorV.glsl
@@ -0,0 +1,36 @@
+/**
+ * @file colorV.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, 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$
+ */
+
+uniform int color_in;
+
+ATTRIBUTE vec3 position;
+
+VARYING int color_out;
+
+void main()
+{
+ color_out = color_in;
+}
+
diff --git a/indra/newview/app_settings/shaders/class1/transform/normalV.glsl b/indra/newview/app_settings/shaders/class1/transform/normalV.glsl
new file mode 100755
index 0000000000..a213aa0ae8
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/transform/normalV.glsl
@@ -0,0 +1,36 @@
+/**
+ * @file normalV.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, 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$
+ */
+
+uniform mat3 normal_matrix;
+
+ATTRIBUTE vec3 normal;
+
+VARYING vec4 normal_out;
+
+void main()
+{
+ normal_out = vec4(normalize(normal_matrix * normal), 0.0);
+}
+
diff --git a/indra/newview/app_settings/shaders/class1/transform/positionV.glsl b/indra/newview/app_settings/shaders/class1/transform/positionV.glsl
new file mode 100755
index 0000000000..01eed18de4
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/transform/positionV.glsl
@@ -0,0 +1,40 @@
+/**
+ * @file positionV.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, 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$
+ */
+
+uniform mat4 modelview_matrix;
+
+uniform int texture_index_in;
+
+ATTRIBUTE vec3 position;
+
+VARYING vec3 position_out;
+VARYING int texture_index_out;
+
+void main()
+{
+ texture_index_out = texture_index_in;
+ position_out = (modelview_matrix*vec4(position, 1.0)).xyz;
+}
+
diff --git a/indra/newview/app_settings/shaders/class1/transform/texcoordV.glsl b/indra/newview/app_settings/shaders/class1/transform/texcoordV.glsl
new file mode 100755
index 0000000000..0e074f3cec
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/transform/texcoordV.glsl
@@ -0,0 +1,35 @@
+/**
+ * @file texcoordV.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, 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$
+ */
+
+
+ATTRIBUTE vec2 texcoord0;
+
+VARYING vec2 texcoord_out;
+
+void main()
+{
+ texcoord_out = texcoord0;
+}
+
diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsF.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsF.glsl
index aacc503e13..aacc503e13 100644..100755
--- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsF.glsl
+++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsF.glsl
diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsHelpersV.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsHelpersV.glsl
index 6ff860362c..6ff860362c 100644..100755
--- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsHelpersV.glsl
+++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsHelpersV.glsl
diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsV.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsV.glsl
index 76d7d5059d..76d7d5059d 100644..100755
--- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsV.glsl
+++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsV.glsl
diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsF.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsF.glsl
index 8bdae328bd..8bdae328bd 100644..100755
--- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsF.glsl
+++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsF.glsl
diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsV.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsV.glsl
index 8ec9ae617c..8ec9ae617c 100644..100755
--- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsV.glsl
+++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsV.glsl
diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsWaterF.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsWaterF.glsl
index 636d4af006..636d4af006 100644..100755
--- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsWaterF.glsl
+++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsWaterF.glsl
diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsWaterV.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsWaterV.glsl
index 8afcc20f6d..8afcc20f6d 100644..100755
--- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsWaterV.glsl
+++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsWaterV.glsl
diff --git a/indra/newview/app_settings/shaders/class1/windlight/gammaF.glsl b/indra/newview/app_settings/shaders/class1/windlight/gammaF.glsl
index 62f4e51449..62f4e51449 100644..100755
--- a/indra/newview/app_settings/shaders/class1/windlight/gammaF.glsl
+++ b/indra/newview/app_settings/shaders/class1/windlight/gammaF.glsl
diff --git a/indra/newview/app_settings/shaders/class1/windlight/transportF.glsl b/indra/newview/app_settings/shaders/class1/windlight/transportF.glsl
index 7c95ecdb14..7c95ecdb14 100644..100755
--- a/indra/newview/app_settings/shaders/class1/windlight/transportF.glsl
+++ b/indra/newview/app_settings/shaders/class1/windlight/transportF.glsl
diff --git a/indra/newview/app_settings/shaders/class2/avatar/eyeballV.glsl b/indra/newview/app_settings/shaders/class2/avatar/eyeballV.glsl
index 5af9f5c902..5af9f5c902 100644..100755
--- a/indra/newview/app_settings/shaders/class2/avatar/eyeballV.glsl
+++ b/indra/newview/app_settings/shaders/class2/avatar/eyeballV.glsl
diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl
deleted file mode 100644
index 08f6ec63fe..0000000000
--- a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl
+++ /dev/null
@@ -1,166 +0,0 @@
-/**
- * @file alphaF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, 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$
- */
-
-#extension GL_ARB_texture_rectangle : enable
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
-
-uniform sampler2DRectShadow shadowMap0;
-uniform sampler2DRectShadow shadowMap1;
-uniform sampler2DRectShadow shadowMap2;
-uniform sampler2DRectShadow shadowMap3;
-uniform sampler2DRect depthMap;
-
-uniform mat4 shadow_matrix[6];
-uniform vec4 shadow_clip;
-uniform vec2 screen_res;
-uniform vec2 shadow_res;
-
-vec3 atmosLighting(vec3 light);
-vec3 scaleSoftClip(vec3 light);
-
-VARYING vec3 vary_ambient;
-VARYING vec3 vary_directional;
-VARYING vec3 vary_fragcoord;
-VARYING vec3 vary_position;
-VARYING vec3 vary_pointlight_col;
-
-uniform float shadow_bias;
-
-uniform mat4 inv_proj;
-
-float pcfShadow(sampler2DRectShadow shadowMap, vec4 stc, float scl)
-{
- stc.xyz /= stc.w;
- stc.z += shadow_bias;
-
- float cs = shadow2DRect(shadowMap, stc.xyz).x;
- float shadow = cs;
-
- shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(scl, scl, 0.0)).x, cs);
- shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(scl, -scl, 0.0)).x, cs);
- shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(-scl, scl, 0.0)).x, cs);
- shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(-scl, -scl, 0.0)).x, cs);
-
- return shadow/5.0;
-}
-
-
-void main()
-{
- vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5;
- frag *= screen_res;
-
- float shadow = 0.0;
- vec4 pos = vec4(vary_position, 1.0);
-
- vec4 spos = pos;
-
- if (spos.z > -shadow_clip.w)
- {
- vec4 lpos;
-
- vec4 near_split = shadow_clip*-0.75;
- vec4 far_split = shadow_clip*-1.25;
- vec4 transition_domain = near_split-far_split;
- float weight = 0.0;
-
- if (spos.z < near_split.z)
- {
- lpos = shadow_matrix[3]*spos;
- lpos.xy *= shadow_res;
-
- float w = 1.0;
- w -= max(spos.z-far_split.z, 0.0)/transition_domain.z;
- shadow += pcfShadow(shadowMap3, lpos, 0.25)*w;
- weight += w;
- shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0);
- }
-
- if (spos.z < near_split.y && spos.z > far_split.z)
- {
- lpos = shadow_matrix[2]*spos;
- lpos.xy *= shadow_res;
-
- float w = 1.0;
- w -= max(spos.z-far_split.y, 0.0)/transition_domain.y;
- w -= max(near_split.z-spos.z, 0.0)/transition_domain.z;
- shadow += pcfShadow(shadowMap2, lpos, 0.75)*w;
- weight += w;
- }
-
- if (spos.z < near_split.x && spos.z > far_split.y)
- {
- lpos = shadow_matrix[1]*spos;
- lpos.xy *= shadow_res;
-
- float w = 1.0;
- w -= max(spos.z-far_split.x, 0.0)/transition_domain.x;
- w -= max(near_split.y-spos.z, 0.0)/transition_domain.y;
- shadow += pcfShadow(shadowMap1, lpos, 0.75)*w;
- weight += w;
- }
-
- if (spos.z > far_split.x)
- {
- lpos = shadow_matrix[0]*spos;
- lpos.xy *= shadow_res;
-
- float w = 1.0;
- w -= max(near_split.x-spos.z, 0.0)/transition_domain.x;
-
- shadow += pcfShadow(shadowMap0, lpos, 1.0)*w;
- weight += w;
- }
-
-
- shadow /= weight;
- }
- else
- {
- shadow = 1.0;
- }
-
- vec4 diff = diffuseLookup(vary_texcoord0.xy);
-
- vec4 col = vec4(vary_ambient + vary_directional.rgb*shadow, vertex_color.a);
- vec4 color = diff * col;
-
- color.rgb = atmosLighting(color.rgb);
-
- color.rgb = scaleSoftClip(color.rgb);
-
- color.rgb += diff.rgb * vary_pointlight_col.rgb;
-
- frag_color = color;
-}
-
diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedF.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedF.glsl
deleted file mode 100644
index aae6a070e2..0000000000
--- a/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedF.glsl
+++ /dev/null
@@ -1,180 +0,0 @@
-/**
- * @file alphaF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, 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$
- */
-
-#extension GL_ARB_texture_rectangle : enable
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-uniform sampler2DRectShadow shadowMap0;
-uniform sampler2DRectShadow shadowMap1;
-uniform sampler2DRectShadow shadowMap2;
-uniform sampler2DRectShadow shadowMap3;
-uniform sampler2DRect depthMap;
-uniform sampler2D diffuseMap;
-
-uniform mat4 shadow_matrix[6];
-uniform vec4 shadow_clip;
-uniform vec2 screen_res;
-uniform vec2 shadow_res;
-
-vec3 atmosLighting(vec3 light);
-vec3 scaleSoftClip(vec3 light);
-
-VARYING vec3 vary_ambient;
-VARYING vec3 vary_directional;
-VARYING vec3 vary_fragcoord;
-VARYING vec3 vary_position;
-VARYING vec3 vary_pointlight_col;
-VARYING vec2 vary_texcoord0;
-VARYING vec4 vertex_color;
-
-uniform float shadow_bias;
-
-uniform mat4 inv_proj;
-
-vec4 getPosition(vec2 pos_screen)
-{
- float depth = texture2DRect(depthMap, pos_screen.xy).a;
- vec2 sc = pos_screen.xy*2.0;
- sc /= screen_res;
- sc -= vec2(1.0,1.0);
- vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
- vec4 pos = inv_proj * ndc;
- pos.xyz /= pos.w;
- pos.w = 1.0;
- return pos;
-}
-
-float pcfShadow(sampler2DRectShadow shadowMap, vec4 stc, float scl)
-{
- stc.xyz /= stc.w;
- stc.z += shadow_bias;
-
- float cs = shadow2DRect(shadowMap, stc.xyz).x;
- float shadow = cs;
-
- shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(scl, scl, 0.0)).x, cs);
- shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(scl, -scl, 0.0)).x, cs);
- shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(-scl, scl, 0.0)).x, cs);
- shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(-scl, -scl, 0.0)).x, cs);
-
- return shadow/5.0;
-}
-
-
-void main()
-{
- vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5;
- frag *= screen_res;
-
- float shadow = 0.0;
- vec4 pos = vec4(vary_position, 1.0);
-
- vec4 spos = pos;
-
- if (spos.z > -shadow_clip.w)
- {
- vec4 lpos;
-
- vec4 near_split = shadow_clip*-0.75;
- vec4 far_split = shadow_clip*-1.25;
- vec4 transition_domain = near_split-far_split;
- float weight = 0.0;
-
- if (spos.z < near_split.z)
- {
- lpos = shadow_matrix[3]*spos;
- lpos.xy *= shadow_res;
-
- float w = 1.0;
- w -= max(spos.z-far_split.z, 0.0)/transition_domain.z;
- shadow += pcfShadow(shadowMap3, lpos, 0.25)*w;
- weight += w;
- shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0);
- }
-
- if (spos.z < near_split.y && spos.z > far_split.z)
- {
- lpos = shadow_matrix[2]*spos;
- lpos.xy *= shadow_res;
-
- float w = 1.0;
- w -= max(spos.z-far_split.y, 0.0)/transition_domain.y;
- w -= max(near_split.z-spos.z, 0.0)/transition_domain.z;
- shadow += pcfShadow(shadowMap2, lpos, 0.75)*w;
- weight += w;
- }
-
- if (spos.z < near_split.x && spos.z > far_split.y)
- {
- lpos = shadow_matrix[1]*spos;
- lpos.xy *= shadow_res;
-
- float w = 1.0;
- w -= max(spos.z-far_split.x, 0.0)/transition_domain.x;
- w -= max(near_split.y-spos.z, 0.0)/transition_domain.y;
- shadow += pcfShadow(shadowMap1, lpos, 0.75)*w;
- weight += w;
- }
-
- if (spos.z > far_split.x)
- {
- lpos = shadow_matrix[0]*spos;
- lpos.xy *= shadow_res;
-
- float w = 1.0;
- w -= max(near_split.x-spos.z, 0.0)/transition_domain.x;
-
- shadow += pcfShadow(shadowMap0, lpos, 1.0)*w;
- weight += w;
- }
-
-
- shadow /= weight;
-
- }
- else
- {
- shadow = 1.0;
- }
-
- vec4 diff = texture2D(diffuseMap,vary_texcoord0.xy);
-
- vec4 col = vec4(vary_ambient + vary_directional.rgb*shadow, vertex_color.a);
- vec4 color = diff * col;
-
- color.rgb = atmosLighting(color.rgb);
-
- color.rgb = scaleSoftClip(color.rgb);
-
- color.rgb += diff.rgb * vary_pointlight_col.rgb;
-
- frag_color = color;
-}
-
diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedNoColorF.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedNoColorF.glsl
deleted file mode 100644
index 931577359e..0000000000
--- a/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedNoColorF.glsl
+++ /dev/null
@@ -1,178 +0,0 @@
-/**
- * @file alphaNonIndexedNoColorF.glsl
- *
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2005, 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$
- */
-
-#extension GL_ARB_texture_rectangle : enable
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-uniform sampler2DRectShadow shadowMap0;
-uniform sampler2DRectShadow shadowMap1;
-uniform sampler2DRectShadow shadowMap2;
-uniform sampler2DRectShadow shadowMap3;
-uniform sampler2DRect depthMap;
-uniform sampler2D diffuseMap;
-
-uniform mat4 shadow_matrix[6];
-uniform vec4 shadow_clip;
-uniform vec2 screen_res;
-uniform vec2 shadow_res;
-
-vec3 atmosLighting(vec3 light);
-vec3 scaleSoftClip(vec3 light);
-
-VARYING vec3 vary_ambient;
-VARYING vec3 vary_directional;
-VARYING vec3 vary_fragcoord;
-VARYING vec3 vary_position;
-VARYING vec3 vary_pointlight_col;
-VARYING vec2 vary_texcoord0;
-
-uniform float shadow_bias;
-
-uniform mat4 inv_proj;
-
-vec4 getPosition(vec2 pos_screen)
-{
- float depth = texture2DRect(depthMap, pos_screen.xy).a;
- vec2 sc = pos_screen.xy*2.0;
- sc /= screen_res;
- sc -= vec2(1.0,1.0);
- vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
- vec4 pos = inv_proj * ndc;
- pos.xyz /= pos.w;
- pos.w = 1.0;
- return pos;
-}
-
-float pcfShadow(sampler2DRectShadow shadowMap, vec4 stc, float scl)
-{
- stc.xyz /= stc.w;
- stc.z += shadow_bias;
-
- float cs = shadow2DRect(shadowMap, stc.xyz).x;
- float shadow = cs;
-
- shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(scl, scl, 0.0)).x, cs);
- shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(scl, -scl, 0.0)).x, cs);
- shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(-scl, scl, 0.0)).x, cs);
- shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(-scl, -scl, 0.0)).x, cs);
-
- return shadow/5.0;
-}
-
-
-void main()
-{
- vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5;
- frag *= screen_res;
-
- float shadow = 0.0;
- vec4 pos = vec4(vary_position, 1.0);
-
- vec4 spos = pos;
-
- if (spos.z > -shadow_clip.w)
- {
- vec4 lpos;
-
- vec4 near_split = shadow_clip*-0.75;
- vec4 far_split = shadow_clip*-1.25;
- vec4 transition_domain = near_split-far_split;
- float weight = 0.0;
-
- if (spos.z < near_split.z)
- {
- lpos = shadow_matrix[3]*spos;
- lpos.xy *= shadow_res;
-
- float w = 1.0;
- w -= max(spos.z-far_split.z, 0.0)/transition_domain.z;
- shadow += pcfShadow(shadowMap3, lpos, 0.25)*w;
- weight += w;
- shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0);
- }
-
- if (spos.z < near_split.y && spos.z > far_split.z)
- {
- lpos = shadow_matrix[2]*spos;
- lpos.xy *= shadow_res;
-
- float w = 1.0;
- w -= max(spos.z-far_split.y, 0.0)/transition_domain.y;
- w -= max(near_split.z-spos.z, 0.0)/transition_domain.z;
- shadow += pcfShadow(shadowMap2, lpos, 0.75)*w;
- weight += w;
- }
-
- if (spos.z < near_split.x && spos.z > far_split.y)
- {
- lpos = shadow_matrix[1]*spos;
- lpos.xy *= shadow_res;
-
- float w = 1.0;
- w -= max(spos.z-far_split.x, 0.0)/transition_domain.x;
- w -= max(near_split.y-spos.z, 0.0)/transition_domain.y;
- shadow += pcfShadow(shadowMap1, lpos, 0.75)*w;
- weight += w;
- }
-
- if (spos.z > far_split.x)
- {
- lpos = shadow_matrix[0]*spos;
- lpos.xy *= shadow_res;
-
- float w = 1.0;
- w -= max(near_split.x-spos.z, 0.0)/transition_domain.x;
-
- shadow += pcfShadow(shadowMap0, lpos, 1.0)*w;
- weight += w;
- }
-
-
- shadow /= weight;
- }
- else
- {
- shadow = 1.0;
- }
-
- vec4 diff = texture2D(diffuseMap,vary_texcoord0.xy);
-
- vec4 col = vec4(vary_ambient + vary_directional.rgb*shadow, 1.0);
- vec4 color = diff * col;
-
- color.rgb = atmosLighting(color.rgb);
-
- color.rgb = scaleSoftClip(color.rgb);
-
- color.rgb += diff.rgb * vary_pointlight_col.rgb;
-
- frag_color = color;
-}
-
diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaSkinnedV.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaSkinnedV.glsl
deleted file mode 100644
index 9629cfe824..0000000000
--- a/indra/newview/app_settings/shaders/class2/deferred/alphaSkinnedV.glsl
+++ /dev/null
@@ -1,155 +0,0 @@
-/**
- * @file alphaSkinnedV.glsl
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, 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$
- */
-
-uniform mat4 projection_matrix;
-uniform mat4 texture_matrix0;
-uniform mat4 modelview_matrix;
-uniform mat4 modelview_projection_matrix;
-
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec3 normal;
-ATTRIBUTE vec4 diffuse_color;
-ATTRIBUTE vec2 texcoord0;
-
-vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
-void calcAtmospherics(vec3 inPositionEye);
-
-float calcDirectionalLight(vec3 n, vec3 l);
-mat4 getObjectSkinnedTransform();
-vec3 atmosAmbient(vec3 light);
-vec3 atmosAffectDirectionalLight(float lightIntensity);
-vec3 scaleDownLight(vec3 light);
-vec3 scaleUpLight(vec3 light);
-
-VARYING vec3 vary_ambient;
-VARYING vec3 vary_directional;
-VARYING vec3 vary_fragcoord;
-VARYING vec3 vary_position;
-VARYING vec3 vary_pointlight_col;
-
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
-
-
-uniform float near_clip;
-uniform float shadow_offset;
-uniform float shadow_bias;
-
-uniform vec4 light_position[8];
-uniform vec3 light_direction[8];
-uniform vec3 light_attenuation[8];
-uniform vec3 light_diffuse[8];
-
-float calcDirectionalLight(vec3 n, vec3 l)
-{
- float a = max(dot(n,l),0.0);
- return a;
-}
-
-float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight)
-{
-//get light vector
- vec3 lv = lp.xyz-v;
-
- //get distance
- float d = dot(lv,lv);
-
- float da = 0.0;
-
- if (d > 0.0 && la > 0.0 && fa > 0.0)
- {
- //normalize light vector
- lv = normalize(lv);
-
- //distance attenuation
- float dist2 = d/la;
- da = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0);
-
- // spotlight coefficient.
- float spot = max(dot(-ln, lv), is_pointlight);
- da *= spot*spot; // GL_SPOT_EXPONENT=2
-
- //angular attenuation
- da *= max(dot(n, lv), 0.0);
- }
-
- return da;
-}
-
-void main()
-{
- vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
-
- mat4 mat = getObjectSkinnedTransform();
-
- mat = modelview_matrix * mat;
-
- vec3 pos = (mat*vec4(position, 1.0)).xyz;
-
- gl_Position = projection_matrix * vec4(pos, 1.0);
-
- vec4 n = vec4(position, 1.0);
- n.xyz += normal.xyz;
- n.xyz = (mat*n).xyz;
- n.xyz = normalize(n.xyz-pos.xyz);
-
- vec3 norm = n.xyz;
-
- float dp_directional_light = max(0.0, dot(norm, light_position[0].xyz));
- vary_position = pos.xyz + light_position[0].xyz * (1.0-dp_directional_light)*shadow_offset;
-
- calcAtmospherics(pos.xyz);
-
- //vec4 color = calcLighting(pos.xyz, norm, diffuse_color, vec4(0.));
- vec4 col = vec4(0.0, 0.0, 0.0, diffuse_color.a);
-
- // Collect normal lights
- col.rgb += light_diffuse[2].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[2], light_direction[2], light_attenuation[2].x, light_attenuation[2].y, light_attenuation[2].z);
- col.rgb += light_diffuse[3].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[3], light_direction[3], light_attenuation[3].x, light_attenuation[3].y, light_attenuation[3].z);
- col.rgb += light_diffuse[4].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[4], light_direction[4], light_attenuation[4].x, light_attenuation[4].y, light_attenuation[4].z);
- col.rgb += light_diffuse[5].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[5], light_direction[5], light_attenuation[5].x, light_attenuation[5].y, light_attenuation[5].z);
- col.rgb += light_diffuse[6].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[6], light_direction[6], light_attenuation[6].x, light_attenuation[6].y, light_attenuation[6].z);
- col.rgb += light_diffuse[7].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[7], light_direction[7], light_attenuation[7].x, light_attenuation[7].y, light_attenuation[7].z);
-
- vary_pointlight_col = col.rgb*diffuse_color.rgb;
-
- col.rgb = vec3(0,0,0);
-
- // Add windlight lights
- col.rgb = atmosAmbient(vec3(0.));
-
- vary_ambient = col.rgb*diffuse_color.rgb;
- vary_directional.rgb = diffuse_color.rgb*atmosAffectDirectionalLight(max(calcDirectionalLight(norm, light_position[0].xyz), (1.0-diffuse_color.a)*(1.0-diffuse_color.a)));
-
- col.rgb = min(col.rgb*diffuse_color.rgb, 1.0);
-
- vertex_color = col;
-
-
-
- pos.xyz = (modelview_projection_matrix * vec4(position.xyz, 1.0)).xyz;
- vary_fragcoord.xyz = pos.xyz + vec3(0,0,near_clip);
-
-}
-
diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl
deleted file mode 100644
index 1586aab0f2..0000000000
--- a/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl
+++ /dev/null
@@ -1,150 +0,0 @@
-/**
- * @file alphaV.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, 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$
- */
-
-uniform mat3 normal_matrix;
-uniform mat4 texture_matrix0;
-uniform mat4 modelview_matrix;
-uniform mat4 modelview_projection_matrix;
-
-ATTRIBUTE vec3 position;
-void passTextureIndex();
-ATTRIBUTE vec3 normal;
-ATTRIBUTE vec4 diffuse_color;
-ATTRIBUTE vec2 texcoord0;
-
-vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
-void calcAtmospherics(vec3 inPositionEye);
-
-float calcDirectionalLight(vec3 n, vec3 l);
-
-vec3 atmosAmbient(vec3 light);
-vec3 atmosAffectDirectionalLight(float lightIntensity);
-vec3 scaleDownLight(vec3 light);
-vec3 scaleUpLight(vec3 light);
-
-VARYING vec3 vary_ambient;
-VARYING vec3 vary_directional;
-VARYING vec3 vary_fragcoord;
-VARYING vec3 vary_position;
-VARYING vec3 vary_pointlight_col;
-
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
-
-
-uniform float near_clip;
-uniform float shadow_offset;
-uniform float shadow_bias;
-
-uniform vec4 light_position[8];
-uniform vec3 light_direction[8];
-uniform vec3 light_attenuation[8];
-uniform vec3 light_diffuse[8];
-
-float calcDirectionalLight(vec3 n, vec3 l)
-{
- float a = max(dot(n,l),0.0);
- return a;
-}
-
-float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight)
-{
- //get light vector
- vec3 lv = lp.xyz-v;
-
- //get distance
- float d = dot(lv,lv);
-
- float da = 0.0;
-
- if (d > 0.0 && la > 0.0 && fa > 0.0)
- {
- //normalize light vector
- lv = normalize(lv);
-
- //distance attenuation
- float dist2 = d/la;
- da = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0);
-
- // spotlight coefficient.
- float spot = max(dot(-ln, lv), is_pointlight);
- da *= spot*spot; // GL_SPOT_EXPONENT=2
-
- //angular attenuation
- da *= max(dot(n, lv), 0.0);
- }
-
- return da;
-}
-
-void main()
-{
- //transform vertex
- vec4 vert = vec4(position.xyz, 1.0);
- passTextureIndex();
- vec4 pos = (modelview_matrix * vert);
- gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);
-
- vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
-
- vec3 norm = normalize(normal_matrix * normal);
-
- float dp_directional_light = max(0.0, dot(norm, light_position[0].xyz));
- vary_position = pos.xyz + light_position[0].xyz * (1.0-dp_directional_light)*shadow_offset;
-
- calcAtmospherics(pos.xyz);
-
- //vec4 color = calcLighting(pos.xyz, norm, diffuse_color, vec4(0.));
- vec4 col = vec4(0.0, 0.0, 0.0, diffuse_color.a);
-
-
- // Collect normal lights
- col.rgb += light_diffuse[2].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[2], light_direction[2], light_attenuation[2].x, light_attenuation[2].y, light_attenuation[2].z);
- col.rgb += light_diffuse[3].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[3], light_direction[3], light_attenuation[3].x, light_attenuation[3].y, light_attenuation[3].z);
- col.rgb += light_diffuse[4].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[4], light_direction[4], light_attenuation[4].x, light_attenuation[4].y, light_attenuation[4].z);
- col.rgb += light_diffuse[5].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[5], light_direction[5], light_attenuation[5].x, light_attenuation[5].y, light_attenuation[5].z);
- col.rgb += light_diffuse[6].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[6], light_direction[6], light_attenuation[6].x, light_attenuation[6].y, light_attenuation[6].z);
- col.rgb += light_diffuse[7].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[7], light_direction[7], light_attenuation[7].x, light_attenuation[7].y, light_attenuation[7].z);
-
- vary_pointlight_col = col.rgb*diffuse_color.rgb;
-
- col.rgb = vec3(0,0,0);
-
- // Add windlight lights
- col.rgb = atmosAmbient(vec3(0.));
-
- vary_ambient = col.rgb*diffuse_color.rgb;
- vary_directional.rgb = diffuse_color.rgb*atmosAffectDirectionalLight(max(calcDirectionalLight(norm, light_position[0].xyz), (1.0-diffuse_color.a)*(1.0-diffuse_color.a)));
-
- col.rgb = col.rgb*diffuse_color.rgb;
-
- vertex_color = col;
-
-
-
- pos = modelview_projection_matrix * vert;
- vary_fragcoord.xyz = pos.xyz + vec3(0,0,near_clip);
-
-}
diff --git a/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaV.glsl b/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaV.glsl
deleted file mode 100644
index 44aaa98b97..0000000000
--- a/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaV.glsl
+++ /dev/null
@@ -1,153 +0,0 @@
-/**
- * @file avatarAlphaV.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, 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$
- */
-
-uniform mat4 projection_matrix;
-
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec3 normal;
-ATTRIBUTE vec2 texcoord0;
-
-vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
-mat4 getSkinnedTransform();
-void calcAtmospherics(vec3 inPositionEye);
-
-float calcDirectionalLight(vec3 n, vec3 l);
-float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float is_pointlight);
-
-vec3 atmosAmbient(vec3 light);
-vec3 atmosAffectDirectionalLight(float lightIntensity);
-vec3 scaleDownLight(vec3 light);
-vec3 scaleUpLight(vec3 light);
-
-VARYING vec3 vary_position;
-VARYING vec3 vary_ambient;
-VARYING vec3 vary_directional;
-VARYING vec3 vary_fragcoord;
-VARYING vec3 vary_pointlight_col;
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
-
-uniform vec4 color;
-
-uniform float near_clip;
-uniform float shadow_offset;
-uniform float shadow_bias;
-
-uniform vec4 light_position[8];
-uniform vec3 light_direction[8];
-uniform vec3 light_attenuation[8];
-uniform vec3 light_diffuse[8];
-
-float calcDirectionalLight(vec3 n, vec3 l)
-{
- float a = max(dot(n,l),0.0);
- return a;
-}
-
-float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight)
-{
- //get light vector
- vec3 lv = lp.xyz-v;
-
- //get distance
- float d = dot(lv,lv);
-
- float da = 0.0;
-
- if (d > 0.0 && la > 0.0 && fa > 0.0)
- {
- //normalize light vector
- lv = normalize(lv);
-
- //distance attenuation
- float dist2 = d/la;
- da = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0);
-
- // spotlight coefficient.
- float spot = max(dot(-ln, lv), is_pointlight);
- da *= spot*spot; // GL_SPOT_EXPONENT=2
-
- //angular attenuation
- da *= max(dot(n, lv), 0.0);
- }
-
- return da;
-}
-
-void main()
-{
- vary_texcoord0 = texcoord0;
-
- vec4 pos;
- vec3 norm;
-
- mat4 trans = getSkinnedTransform();
- vec4 pos_in = vec4(position.xyz, 1.0);
- pos.x = dot(trans[0], pos_in);
- pos.y = dot(trans[1], pos_in);
- pos.z = dot(trans[2], pos_in);
- pos.w = 1.0;
-
- norm.x = dot(trans[0].xyz, normal);
- norm.y = dot(trans[1].xyz, normal);
- norm.z = dot(trans[2].xyz, normal);
- norm = normalize(norm);
-
- gl_Position = projection_matrix * pos;
-
- float dp_directional_light = max(0.0, dot(norm, light_position[0].xyz));
- vary_position = pos.xyz + light_position[0].xyz * (1.0-dp_directional_light)*shadow_offset;
-
- calcAtmospherics(pos.xyz);
-
- vec4 col = vec4(0.0, 0.0, 0.0, 1.0);
-
- // Collect normal lights
- col.rgb += light_diffuse[2].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[2], light_direction[2], light_attenuation[2].x, light_attenuation[2].y, light_attenuation[2].z);
- col.rgb += light_diffuse[3].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[3], light_direction[3], light_attenuation[3].x, light_attenuation[3].y, light_attenuation[3].z);
- col.rgb += light_diffuse[4].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[4], light_direction[4], light_attenuation[4].x, light_attenuation[4].y, light_attenuation[4].z);
- col.rgb += light_diffuse[5].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[5], light_direction[5], light_attenuation[5].x, light_attenuation[5].y, light_attenuation[5].z);
- col.rgb += light_diffuse[6].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[6], light_direction[6], light_attenuation[6].x, light_attenuation[6].y, light_attenuation[6].z);
- col.rgb += light_diffuse[7].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[7], light_direction[7], light_attenuation[7].x, light_attenuation[7].y, light_attenuation[7].z);
-
- vary_pointlight_col = col.rgb*color.rgb;
-
- col.rgb = vec3(0,0,0);
-
- // Add windlight lights
- col.rgb = atmosAmbient(vec3(0.));
-
- vary_ambient = col.rgb*color.rgb;
- vary_directional = atmosAffectDirectionalLight(max(calcDirectionalLight(norm, light_position[0].xyz), 0.0));
-
- col.rgb = col.rgb*color.rgb;
-
- vertex_color = col;
-
-
- vary_fragcoord.xyz = pos.xyz + vec3(0,0,near_clip);
-}
-
-
diff --git a/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl
index f7f1f649ce..c20e00163c 100644..100755
--- a/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl
@@ -24,6 +24,7 @@
*/
#extension GL_ARB_texture_rectangle : enable
+#extension GL_ARB_shader_texture_lod : enable
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
@@ -39,6 +40,7 @@ uniform samplerCube environmentMap;
uniform sampler2DRect lightMap;
uniform sampler2D noiseMap;
uniform sampler2D projectionMap;
+uniform sampler2D lightFunc;
uniform mat4 proj_mat; //screen space to light space
uniform float proj_near; //near clip for projection
@@ -67,10 +69,70 @@ uniform vec2 screen_res;
uniform mat4 inv_proj;
+vec3 srgb_to_linear(vec3 cs)
+{
+ vec3 low_range = cs / vec3(12.92);
+ vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
+ bvec3 lte = lessThanEqual(cs,vec3(0.04045));
+
+#ifdef OLD_SELECT
+ vec3 result;
+ result.r = lte.r ? low_range.r : high_range.r;
+ result.g = lte.g ? low_range.g : high_range.g;
+ result.b = lte.b ? low_range.b : high_range.b;
+ return result;
+#else
+ return mix(high_range, low_range, lte);
+#endif
+
+}
+
+vec3 linear_to_srgb(vec3 cl)
+{
+ cl = clamp(cl, vec3(0), vec3(1));
+ vec3 low_range = cl * 12.92;
+ vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
+ bvec3 lt = lessThan(cl,vec3(0.0031308));
+
+#ifdef OLD_SELECT
+ vec3 result;
+ result.r = lt.r ? low_range.r : high_range.r;
+ result.g = lt.g ? low_range.g : high_range.g;
+ result.b = lt.b ? low_range.b : high_range.b;
+ return result;
+#else
+ return mix(high_range, low_range, lt);
+#endif
+
+}
+
+vec2 encode_normal(vec3 n)
+{
+ float f = sqrt(8 * n.z + 8);
+ return n.xy / f + 0.5;
+}
+
+vec3 decode_normal (vec2 enc)
+{
+ vec2 fenc = enc*4-2;
+ float f = dot(fenc,fenc);
+ float g = sqrt(1-f/4);
+ vec3 n;
+ n.xy = fenc*g;
+ n.z = 1-f/2;
+ return n;
+}
+
+vec4 correctWithGamma(vec4 col)
+{
+ return vec4(srgb_to_linear(col.rgb), col.a);
+}
+
vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
{
vec4 ret = texture2DLod(projectionMap, tc, lod);
-
+ ret = correctWithGamma(ret);
+
vec2 dist = tc-vec2(0.5);
float det = max(1.0-lod/(proj_lod*0.5), 0.0);
@@ -85,7 +147,8 @@ vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)
{
vec4 ret = texture2DLod(projectionMap, tc, lod);
-
+ ret = correctWithGamma(ret);
+
vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
float det = min(lod/(proj_lod*0.5), 1.0);
@@ -102,7 +165,8 @@ vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)
vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)
{
vec4 ret = texture2DLod(projectionMap, tc, lod);
-
+ ret = correctWithGamma(ret);
+
vec2 dist = tc-vec2(0.5);
float d = dot(dist,dist);
@@ -135,9 +199,9 @@ void main()
vec3 pos = getPosition(frag.xy).xyz;
vec3 lv = center.xyz-pos.xyz;
- float dist2 = dot(lv,lv);
- dist2 /= size;
- if (dist2 > 1.0)
+ float dist = length(lv);
+ dist /= size;
+ if (dist > 1.0)
{
discard;
}
@@ -154,7 +218,10 @@ void main()
}
vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
- norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
+
+ float envIntensity = norm.z;
+
+ norm = decode_normal(norm.xy);
norm = normalize(norm);
float l_dist = -dot(lv, proj_n);
@@ -168,7 +235,9 @@ void main()
proj_tc.xyz /= proj_tc.w;
float fa = falloff+1.0;
- float dist_atten = min(1.0-(dist2-1.0*(1.0-fa))/fa, 1.0);
+ float dist_atten = min(1.0-(dist-1.0*(1.0-fa))/fa, 1.0);
+ dist_atten *= dist_atten;
+ dist_atten *= 2.0;
if (dist_atten <= 0.0)
{
discard;
@@ -177,11 +246,15 @@ void main()
lv = proj_origin-pos.xyz;
lv = normalize(lv);
float da = dot(norm, lv);
-
+
vec3 col = vec3(0,0,0);
vec3 diff_tex = texture2DRect(diffuseRect, frag.xy).rgb;
-
+
+ vec4 spec = texture2DRect(specularRect, frag.xy);
+
+ vec3 dlit = vec3(0, 0, 0);
+
float noise = texture2D(noiseMap, frag.xy/128.0).b;
if (proj_tc.z > 0.0 &&
proj_tc.x < 1.0 &&
@@ -189,21 +262,21 @@ void main()
proj_tc.x > 0.0 &&
proj_tc.y > 0.0)
{
- float lit = 0.0;
float amb_da = proj_ambiance;
-
+ float lit = 0.0;
+
if (da > 0.0)
{
+ lit = da * dist_atten * noise;
+
float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0);
float lod = diff * proj_lod;
vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod);
- vec3 lcol = color.rgb * plcol.rgb * plcol.a;
+ dlit = color.rgb * plcol.rgb * plcol.a;
- lit = da * dist_atten * noise;
-
- col = lcol*lit*diff_tex*shadow;
+ col = dlit*lit*diff_tex*shadow;
amb_da += (da*0.5)*(1.0-shadow)*proj_ambiance;
}
@@ -219,10 +292,37 @@ void main()
col += amb_da*color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a;
}
-
- vec4 spec = texture2DRect(specularRect, frag.xy);
+
if (spec.a > 0.0)
{
+ vec3 npos = -normalize(pos);
+ dlit *= min(da*6.0, 1.0) * dist_atten;
+
+ //vec3 ref = dot(pos+lv, norm);
+ vec3 h = normalize(lv+npos);
+ float nh = dot(norm, h);
+ float nv = dot(norm, npos);
+ float vh = dot(npos, h);
+ float sa = nh;
+ float fres = pow(1 - dot(h, npos), 5)*0.4+0.5;
+
+ float gtdenom = 2 * nh;
+ float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh));
+
+ if (nh > 0.0)
+ {
+ float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da);
+ col += dlit*scol*spec.rgb*shadow;
+ //col += spec.rgb;
+ }
+ }
+
+
+
+
+
+ if (envIntensity > 0.0)
+ {
vec3 ref = reflect(normalize(pos), norm);
//project from point pos in direction ref to plane proj_p, proj_n
@@ -234,13 +334,12 @@ void main()
vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds;
vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0));
+ stc /= stc.w;
if (stc.z > 0.0)
{
- stc.xy /= stc.w;
+ float fatten = clamp(envIntensity*envIntensity+envIntensity*0.25, 0.25, 1.0);
- float fatten = clamp(spec.a*spec.a+spec.a*0.5, 0.25, 1.0);
-
stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5);
if (stc.x < 1.0 &&
@@ -248,13 +347,16 @@ void main()
stc.x > 0.0 &&
stc.y > 0.0)
{
- vec4 scol = texture2DLodSpecular(projectionMap, stc.xy, proj_lod-spec.a*proj_lod);
- col += dist_atten*scol.rgb*color.rgb*scol.a*spec.rgb*shadow;
+ col += color.rgb*texture2DLodSpecular(projectionMap, stc.xy, proj_lod).rgb*shadow*spec.rgb;
}
}
}
}
+
+ //not sure why, but this line prevents MATBUG-194
+ col = max(col, vec3(0.0));
+
frag_color.rgb = col;
frag_color.a = 0.0;
}
diff --git a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
index a137bea30f..1022c23f7b 100644..100755
--- a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
@@ -38,7 +38,6 @@ uniform sampler2DRect lightMap;
uniform sampler2DRect depthMap;
uniform samplerCube environmentMap;
uniform sampler2D lightFunc;
-uniform vec3 gi_quad;
uniform float blur_size;
uniform float blur_fidelity;
@@ -60,16 +59,13 @@ uniform float density_multiplier;
uniform float distance_multiplier;
uniform float max_y;
uniform vec4 glow;
+uniform float global_gamma;
uniform float scene_light_strength;
uniform mat3 env_mat;
uniform vec4 shadow_clip;
uniform mat3 ssao_effect_mat;
-uniform mat4 inv_proj;
-uniform vec2 screen_res;
-
uniform vec3 sun_dir;
-
VARYING vec2 vary_fragcoord;
vec3 vary_PositionEye;
@@ -79,6 +75,63 @@ vec3 vary_AmblitColor;
vec3 vary_AdditiveColor;
vec3 vary_AtmosAttenuation;
+uniform mat4 inv_proj;
+uniform vec2 screen_res;
+
+vec3 srgb_to_linear(vec3 cs)
+{
+ vec3 low_range = cs / vec3(12.92);
+ vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
+ bvec3 lte = lessThanEqual(cs,vec3(0.04045));
+
+#ifdef OLD_SELECT
+ vec3 result;
+ result.r = lte.r ? low_range.r : high_range.r;
+ result.g = lte.g ? low_range.g : high_range.g;
+ result.b = lte.b ? low_range.b : high_range.b;
+ return result;
+#else
+ return mix(high_range, low_range, lte);
+#endif
+
+}
+
+vec3 linear_to_srgb(vec3 cl)
+{
+ cl = clamp(cl, vec3(0), vec3(1));
+ vec3 low_range = cl * 12.92;
+ vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
+ bvec3 lt = lessThan(cl,vec3(0.0031308));
+
+#ifdef OLD_SELECT
+ vec3 result;
+ result.r = lt.r ? low_range.r : high_range.r;
+ result.g = lt.g ? low_range.g : high_range.g;
+ result.b = lt.b ? low_range.b : high_range.b;
+ return result;
+#else
+ return mix(high_range, low_range, lt);
+#endif
+
+}
+
+vec2 encode_normal(vec3 n)
+{
+ float f = sqrt(8 * n.z + 8);
+ return n.xy / f + 0.5;
+}
+
+vec3 decode_normal (vec2 enc)
+{
+ vec2 fenc = enc*4-2;
+ float f = dot(fenc,fenc);
+ float g = sqrt(1-f/4);
+ vec3 n;
+ n.xy = fenc*g;
+ n.z = 1-f/2;
+ return n;
+}
+
vec4 getPosition_d(vec2 pos_screen, float depth)
{
vec2 sc = pos_screen.xy*2.0;
@@ -118,7 +171,6 @@ vec3 getAtmosAttenuation()
return vary_AtmosAttenuation;
}
-
void setPositionEye(vec3 v)
{
vary_PositionEye = v;
@@ -222,11 +274,61 @@ void calcAtmospherics(vec3 inPositionEye, float ambFactor) {
+ tmpAmbient)));
//brightness of surface both sunlight and ambient
+ /*setSunlitColor(pow(vec3(sunlight * .5), vec3(global_gamma)) * global_gamma);
+ setAmblitColor(pow(vec3(tmpAmbient * .25), vec3(global_gamma)) * global_gamma);
+ setAdditiveColor(pow(getAdditiveColor() * vec3(1.0 - temp1), vec3(global_gamma)) * global_gamma);*/
+
setSunlitColor(vec3(sunlight * .5));
setAmblitColor(vec3(tmpAmbient * .25));
setAdditiveColor(getAdditiveColor() * vec3(1.0 - temp1));
}
+#ifdef WATER_FOG
+uniform vec4 waterPlane;
+uniform vec4 waterFogColor;
+uniform float waterFogDensity;
+uniform float waterFogKS;
+
+vec4 applyWaterFogDeferred(vec3 pos, vec4 color)
+{
+ //normalize view vector
+ vec3 view = normalize(pos);
+ float es = -(dot(view, waterPlane.xyz));
+
+ //find intersection point with water plane and eye vector
+
+ //get eye depth
+ float e0 = max(-waterPlane.w, 0.0);
+
+ vec3 int_v = waterPlane.w > 0.0 ? view * waterPlane.w/es : vec3(0.0, 0.0, 0.0);
+
+ //get object depth
+ float depth = length(pos - int_v);
+
+ //get "thickness" of water
+ float l = max(depth, 0.1);
+
+ float kd = waterFogDensity;
+ float ks = waterFogKS;
+ vec4 kc = waterFogColor;
+
+ float F = 0.98;
+
+ float t1 = -kd * pow(F, ks * e0);
+ float t2 = kd + ks * es;
+ float t3 = pow(F, t2*l) - 1.0;
+
+ float L = min(t1/t2*t3, 1.0);
+
+ float D = pow(0.98, l*kd);
+
+ color.rgb = color.rgb * D + kc.rgb * L;
+ color.a = kc.a + color.a;
+
+ return color;
+}
+#endif
+
vec3 atmosLighting(vec3 light)
{
light *= getAtmosAttenuation().r;
@@ -239,6 +341,15 @@ vec3 atmosTransport(vec3 light) {
light += getAdditiveColor() * 2.0;
return light;
}
+
+vec3 fullbrightAtmosTransport(vec3 light) {
+ float brightness = dot(light.rgb, vec3(0.33333));
+
+ return mix(atmosTransport(light.rgb), light.rgb + getAdditiveColor().rgb, brightness * brightness);
+}
+
+
+
vec3 atmosGetDiffuseSunlightColor()
{
return getSunlitColor();
@@ -273,65 +384,109 @@ vec3 scaleSoftClip(vec3 light)
return light;
}
+
+vec3 fullbrightScaleSoftClip(vec3 light)
+{
+ //soft clip effect:
+ return light;
+}
+
void main()
{
vec2 tc = vary_fragcoord.xy;
float depth = texture2DRect(depthMap, tc.xy).r;
vec3 pos = getPosition_d(tc, depth).xyz;
- vec3 norm = texture2DRect(normalMap, tc).xyz;
- norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
+ vec4 norm = texture2DRect(normalMap, tc);
+ float envIntensity = norm.z;
+ norm.xyz = decode_normal(norm.xy); // unpack norm
float da = max(dot(norm.xyz, sun_dir.xyz), 0.0);
-
+
+ float light_gamma = 1.0/1.3;
+ da = pow(da, light_gamma);
+
+
vec4 diffuse = texture2DRect(diffuseRect, tc);
+ //convert to gamma space
+ diffuse.rgb = linear_to_srgb(diffuse.rgb);
+
vec3 col;
float bloom = 0.0;
-
- if (diffuse.a < 0.9)
{
vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy);
vec2 scol_ambocc = texture2DRect(lightMap, vary_fragcoord.xy).rg;
+ scol_ambocc = pow(scol_ambocc, vec2(light_gamma));
+
float scol = max(scol_ambocc.r, diffuse.a);
+
+
+
float ambocc = scol_ambocc.g;
calcAtmospherics(pos.xyz, ambocc);
col = atmosAmbient(vec3(0));
- col += atmosAffectDirectionalLight(max(min(da, scol), diffuse.a));
+ float ambient = min(abs(dot(norm.xyz, sun_dir.xyz)), 1.0);
+ ambient *= 0.5;
+ ambient *= ambient;
+ ambient = (1.0-ambient);
+
+ col.rgb *= ambient;
+
+ col += atmosAffectDirectionalLight(max(min(da, scol), 0.0));
col *= diffuse.rgb;
+ vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
+
if (spec.a > 0.0) // specular reflection
{
// the old infinite-sky shiny reflection
//
- vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
+
float sa = dot(refnormpersp, sun_dir.xyz);
- vec3 dumbshiny = vary_SunlitColor*scol_ambocc.r*(6 * texture2D(lightFunc, vec2(sa, spec.a)).r);
-
+ vec3 dumbshiny = vary_SunlitColor*scol_ambocc.r*(texture2D(lightFunc, vec2(sa, spec.a)).r);
+
// add the two types of shiny together
vec3 spec_contrib = dumbshiny * spec.rgb;
- bloom = dot(spec_contrib, spec_contrib) / 4;
+ bloom = dot(spec_contrib, spec_contrib) / 6;
col += spec_contrib;
+ }
+
+
+ col = mix(col, diffuse.rgb, diffuse.a);
- //add environmentmap
+ if (envIntensity > 0.0)
+ { //add environmentmap
vec3 env_vec = env_mat * refnormpersp;
- col = mix(col.rgb, textureCube(environmentMap, env_vec).rgb,
- max(spec.a-diffuse.a*2.0, 0.0));
- }
- col = atmosLighting(col);
- col = scaleSoftClip(col);
+ vec3 refcol = textureCube(environmentMap, env_vec).rgb;
- col = mix(col, diffuse.rgb, diffuse.a);
- }
- else
- {
- col = diffuse.rgb;
+ col = mix(col.rgb, refcol,
+ envIntensity);
+
+ }
+
+ if (norm.w < 0.5)
+ {
+ col = mix(atmosLighting(col), fullbrightAtmosTransport(col), diffuse.a);
+ col = mix(scaleSoftClip(col), fullbrightScaleSoftClip(col), diffuse.a);
+ }
+
+ #ifdef WATER_FOG
+ vec4 fogged = applyWaterFogDeferred(pos,vec4(col, bloom));
+ col = fogged.rgb;
+ bloom = fogged.a;
+ #endif
+
+ col = srgb_to_linear(col);
+
+ //col = vec3(1,0,1);
+ //col.g = envIntensity;
}
-
+
frag_color.rgb = col;
frag_color.a = bloom;
}
diff --git a/indra/newview/app_settings/shaders/class2/deferred/softenLightV.glsl b/indra/newview/app_settings/shaders/class2/deferred/softenLightV.glsl
index c840d72784..c840d72784 100644..100755
--- a/indra/newview/app_settings/shaders/class2/deferred/softenLightV.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/softenLightV.glsl
diff --git a/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl
index 99a277fbfc..7689b72d20 100644..100755
--- a/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl
@@ -24,6 +24,7 @@
*/
#extension GL_ARB_texture_rectangle : enable
+#extension GL_ARB_shader_texture_lod : enable
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
@@ -31,8 +32,6 @@ out vec4 frag_color;
#define frag_color gl_FragColor
#endif
-VARYING vec4 vertex_color;
-
uniform sampler2DRect diffuseRect;
uniform sampler2DRect specularRect;
uniform sampler2DRect depthMap;
@@ -41,6 +40,7 @@ uniform samplerCube environmentMap;
uniform sampler2DRect lightMap;
uniform sampler2D noiseMap;
uniform sampler2D projectionMap;
+uniform sampler2D lightFunc;
uniform mat4 proj_mat; //screen space to light space
uniform float proj_near; //near clip for projection
@@ -49,6 +49,7 @@ uniform vec3 proj_n;
uniform float proj_focus; //distance from plane to begin blurring
uniform float proj_lod; //(number of mips in proj map)
uniform float proj_range; //range between near clip and far clip plane of projection
+uniform float proj_ambient_lod;
uniform float proj_ambiance;
uniform float near_clip;
uniform float far_clip;
@@ -58,16 +59,127 @@ uniform float sun_wash;
uniform int proj_shadow_idx;
uniform float shadow_fade;
-VARYING vec4 vary_light;
+uniform float size;
+uniform vec3 color;
+uniform float falloff;
+VARYING vec3 trans_center;
VARYING vec4 vary_fragcoord;
uniform vec2 screen_res;
uniform mat4 inv_proj;
+vec2 encode_normal(vec3 n)
+{
+ float f = sqrt(8 * n.z + 8);
+ return n.xy / f + 0.5;
+}
+
+vec3 decode_normal (vec2 enc)
+{
+ vec2 fenc = enc*4-2;
+ float f = dot(fenc,fenc);
+ float g = sqrt(1-f/4);
+ vec3 n;
+ n.xy = fenc*g;
+ n.z = 1-f/2;
+ return n;
+}
+
+vec3 srgb_to_linear(vec3 cs)
+{
+ vec3 low_range = cs / vec3(12.92);
+ vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
+ bvec3 lte = lessThanEqual(cs,vec3(0.04045));
+
+#ifdef OLD_SELECT
+ vec3 result;
+ result.r = lte.r ? low_range.r : high_range.r;
+ result.g = lte.g ? low_range.g : high_range.g;
+ result.b = lte.b ? low_range.b : high_range.b;
+ return result;
+#else
+ return mix(high_range, low_range, lte);
+#endif
+
+}
+
+vec3 linear_to_srgb(vec3 cl)
+{
+ cl = clamp(cl, vec3(0), vec3(1));
+ vec3 low_range = cl * 12.92;
+ vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
+ bvec3 lt = lessThan(cl,vec3(0.0031308));
+
+#ifdef OLD_SELECT
+ vec3 result;
+ result.r = lt.r ? low_range.r : high_range.r;
+ result.g = lt.g ? low_range.g : high_range.g;
+ result.b = lt.b ? low_range.b : high_range.b;
+ return result;
+#else
+ return mix(high_range, low_range, lt);
+#endif
+
+}
+
+vec4 correctWithGamma(vec4 col)
+{
+ return vec4(srgb_to_linear(col.rgb), col.a);
+}
+
+vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
+{
+ vec4 ret = texture2DLod(projectionMap, tc, lod);
+ ret = correctWithGamma(ret);
+
+ vec2 dist = tc-vec2(0.5);
+
+ float det = max(1.0-lod/(proj_lod*0.5), 0.0);
+
+ float d = dot(dist,dist);
+
+ ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0)+det, 1.0);
+
+ return ret;
+}
+
+vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)
+{
+ vec4 ret = texture2DLod(projectionMap, tc, lod);
+ ret = correctWithGamma(ret);
+
+ vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
+
+ float det = min(lod/(proj_lod*0.5), 1.0);
+
+ float d = min(dist.x, dist.y);
+
+ float edge = 0.25*det;
+
+ ret *= clamp(d/edge, 0.0, 1.0);
+
+ return ret;
+}
+
+vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)
+{
+ vec4 ret = texture2DLod(projectionMap, tc, lod);
+ ret = correctWithGamma(ret);
+
+ vec2 dist = tc-vec2(0.5);
+
+ float d = dot(dist,dist);
+
+ ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0), 1.0);
+
+ return ret;
+}
+
+
vec4 getPosition(vec2 pos_screen)
{
- float depth = texture2DRect(depthMap, pos_screen.xy).a;
+ float depth = texture2DRect(depthMap, pos_screen.xy).r;
vec2 sc = pos_screen.xy*2.0;
sc /= screen_res;
sc -= vec2(1.0,1.0);
@@ -85,6 +197,15 @@ void main()
frag.xyz = frag.xyz*0.5+0.5;
frag.xy *= screen_res;
+ vec3 pos = getPosition(frag.xy).xyz;
+ vec3 lv = trans_center.xyz-pos.xyz;
+ float dist = length(lv);
+ dist /= size;
+ if (dist > 1.0)
+ {
+ discard;
+ }
+
float shadow = 1.0;
if (proj_shadow_idx >= 0)
@@ -96,17 +217,9 @@ void main()
shadow = min(sh[proj_shadow_idx]+shadow_fade, 1.0);
}
- vec3 pos = getPosition(frag.xy).xyz;
- vec3 lv = vary_light.xyz-pos.xyz;
- float dist2 = dot(lv,lv);
- dist2 /= vary_light.w;
- if (dist2 > 1.0)
- {
- discard;
- }
-
vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
- norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
+ float envIntensity = norm.z;
+ norm = decode_normal(norm.xy);
norm = normalize(norm);
float l_dist = -dot(lv, proj_n);
@@ -119,8 +232,15 @@ void main()
proj_tc.xyz /= proj_tc.w;
- float fa = vertex_color.a+1.0;
- float dist_atten = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0);
+ float fa = falloff+1.0;
+ float dist_atten = min(1.0-(dist-1.0*(1.0-fa))/fa, 1.0);
+ dist_atten *= dist_atten;
+ dist_atten *= 2.0;
+
+ if (dist_atten <= 0.0)
+ {
+ discard;
+ }
lv = proj_origin-pos.xyz;
lv = normalize(lv);
@@ -130,6 +250,10 @@ void main()
vec3 diff_tex = texture2DRect(diffuseRect, frag.xy).rgb;
+ vec4 spec = texture2DRect(specularRect, frag.xy);
+
+ vec3 dlit = vec3(0, 0, 0);
+
float noise = texture2D(noiseMap, frag.xy/128.0).b;
if (proj_tc.z > 0.0 &&
proj_tc.x < 1.0 &&
@@ -137,44 +261,67 @@ void main()
proj_tc.x > 0.0 &&
proj_tc.y > 0.0)
{
+ float amb_da = proj_ambiance;
float lit = 0.0;
+
if (da > 0.0)
{
+ lit = da * dist_atten * noise;
+
float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0);
float lod = diff * proj_lod;
- vec4 plcol = texture2DLod(projectionMap, proj_tc.xy, lod);
+ vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod);
- vec3 lcol = vertex_color.rgb * plcol.rgb * plcol.a;
+ dlit = color.rgb * plcol.rgb * plcol.a;
- lit = da * dist_atten * noise;
-
- col = lcol*lit*diff_tex*shadow;
- }
-
- float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0);
- float lod = diff * proj_lod;
- vec4 amb_plcol = texture2DLod(projectionMap, proj_tc.xy, lod);
- //float amb_da = mix(proj_ambiance, proj_ambiance*max(-da, 0.0), max(da, 0.0));
- float amb_da = proj_ambiance;
- if (da > 0.0)
- {
+ col = dlit*lit*diff_tex*shadow;
amb_da += (da*0.5)*(1.0-shadow)*proj_ambiance;
}
+ //float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0);
+ vec4 amb_plcol = texture2DLodAmbient(projectionMap, proj_tc.xy, proj_lod);
+
amb_da += (da*da*0.5+0.5)*proj_ambiance;
-
+
amb_da *= dist_atten * noise;
-
+
amb_da = min(amb_da, 1.0-lit);
-
- col += amb_da*vertex_color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a;
+
+ col += amb_da*color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a;
}
-
- vec4 spec = texture2DRect(specularRect, frag.xy);
+
if (spec.a > 0.0)
{
+ dlit *= min(da*6.0, 1.0) * dist_atten;
+ vec3 npos = -normalize(pos);
+
+ //vec3 ref = dot(pos+lv, norm);
+ vec3 h = normalize(lv+npos);
+ float nh = dot(norm, h);
+ float nv = dot(norm, npos);
+ float vh = dot(npos, h);
+ float sa = nh;
+ float fres = pow(1 - dot(h, npos), 5)*0.4+0.5;
+
+ float gtdenom = 2 * nh;
+ float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh));
+
+ if (nh > 0.0)
+ {
+ float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da);
+ col += dlit*scol*spec.rgb*shadow;
+ //col += spec.rgb;
+ }
+ }
+
+
+
+
+
+ if (envIntensity > 0.0)
+ {
vec3 ref = reflect(normalize(pos), norm);
//project from point pos in direction ref to plane proj_p, proj_n
@@ -185,24 +332,31 @@ void main()
{
vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds;
- vec3 stc = (proj_mat * vec4(pfinal.xyz, 1.0)).xyz;
+ vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0));
if (stc.z > 0.0)
{
- stc.xy /= stc.z+proj_near;
-
+ stc.xy /= stc.w;
+
+ float fatten = clamp(envIntensity*envIntensity+envIntensity*0.5, 0.25, 1.0);
+
+ //stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5);
+ stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5);
+
if (stc.x < 1.0 &&
stc.y < 1.0 &&
stc.x > 0.0 &&
stc.y > 0.0)
{
- vec4 scol = texture2DLod(projectionMap, stc.xy, proj_lod-spec.a*proj_lod);
- col += dist_atten*scol.rgb*vertex_color.rgb*scol.a*spec.rgb*shadow;
+ col += color.rgb*texture2DLodSpecular(projectionMap, stc.xy, proj_lod-envIntensity*proj_lod).rgb*shadow*spec.rgb;
}
}
}
}
+ //not sure why, but this line prevents MATBUG-194
+ col = max(col, vec3(0.0));
+
frag_color.rgb = col;
frag_color.a = 0.0;
}
diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl
index 8c4ccf9cb3..95c09d3238 100644..100755
--- a/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl
@@ -35,10 +35,10 @@ out vec4 frag_color;
uniform sampler2DRect depthMap;
uniform sampler2DRect normalMap;
-uniform sampler2DRectShadow shadowMap0;
-uniform sampler2DRectShadow shadowMap1;
-uniform sampler2DRectShadow shadowMap2;
-uniform sampler2DRectShadow shadowMap3;
+uniform sampler2DShadow shadowMap0;
+uniform sampler2DShadow shadowMap1;
+uniform sampler2DShadow shadowMap2;
+uniform sampler2DShadow shadowMap3;
uniform sampler2DShadow shadowMap4;
uniform sampler2DShadow shadowMap5;
@@ -55,16 +55,33 @@ VARYING vec2 vary_fragcoord;
uniform mat4 inv_proj;
uniform vec2 screen_res;
-uniform vec2 shadow_res;
uniform vec2 proj_shadow_res;
uniform vec3 sun_dir;
+uniform vec2 shadow_res;
uniform float shadow_bias;
uniform float shadow_offset;
uniform float spot_shadow_bias;
uniform float spot_shadow_offset;
+vec2 encode_normal(vec3 n)
+{
+ float f = sqrt(8 * n.z + 8);
+ return n.xy / f + 0.5;
+}
+
+vec3 decode_normal (vec2 enc)
+{
+ vec2 fenc = enc*4-2;
+ float f = dot(fenc,fenc);
+ float g = sqrt(1-f/4);
+ vec3 n;
+ n.xy = fenc*g;
+ n.z = 1-f/2;
+ return n;
+}
+
vec4 getPosition(vec2 pos_screen)
{
float depth = texture2DRect(depthMap, pos_screen.xy).r;
@@ -78,42 +95,43 @@ vec4 getPosition(vec2 pos_screen)
return pos;
}
-float pcfShadow(sampler2DRectShadow shadowMap, vec4 stc, float scl)
+float pcfShadow(sampler2DShadow shadowMap, vec4 stc, float scl, vec2 pos_screen)
{
stc.xyz /= stc.w;
- stc.z += shadow_bias*scl;
-
- float cs = shadow2DRect(shadowMap, stc.xyz).x;
+ stc.z += shadow_bias;
+
+ stc.x = floor(stc.x*shadow_res.x + fract(pos_screen.y*0.666666666))/shadow_res.x; // add some jitter to X sample pos according to Y to disguise the snapping going on here
+ float cs = shadow2D(shadowMap, stc.xyz).x;
+
float shadow = cs;
- shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(1.5, 1.5, 0.0)).x, cs);
- shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(1.5, -1.5, 0.0)).x, cs);
- shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(-1.5, 1.5, 0.0)).x, cs);
- shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(-1.5, -1.5, 0.0)).x, cs);
+ shadow += shadow2D(shadowMap, stc.xyz+vec3(2.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x;
+ shadow += shadow2D(shadowMap, stc.xyz+vec3(1.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x;
+ shadow += shadow2D(shadowMap, stc.xyz+vec3(-2.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x;
+ shadow += shadow2D(shadowMap, stc.xyz+vec3(-1.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x;
+
- return shadow/5.0;
-
- //return shadow;
+ return shadow*0.2;
}
-float pcfShadow(sampler2DShadow shadowMap, vec4 stc, float scl)
+float pcfSpotShadow(sampler2DShadow shadowMap, vec4 stc, float scl, vec2 pos_screen)
{
stc.xyz /= stc.w;
stc.z += spot_shadow_bias*scl;
-
+ stc.x = floor(proj_shadow_res.x * stc.x + fract(pos_screen.y*0.666666666)) / proj_shadow_res.x; // snap
+
float cs = shadow2D(shadowMap, stc.xyz).x;
float shadow = cs;
- vec2 off = 1.5/proj_shadow_res;
-
- shadow += max(shadow2D(shadowMap, stc.xyz+vec3(off.x, off.y, 0.0)).x, cs);
- shadow += max(shadow2D(shadowMap, stc.xyz+vec3(off.x, -off.y, 0.0)).x, cs);
- shadow += max(shadow2D(shadowMap, stc.xyz+vec3(-off.x, off.y, 0.0)).x, cs);
- shadow += max(shadow2D(shadowMap, stc.xyz+vec3(-off.x, -off.y, 0.0)).x, cs);
-
- return shadow/5.0;
+ vec2 off = 1.0/proj_shadow_res;
+ off.y *= 1.5;
- //return shadow;
+ shadow += shadow2D(shadowMap, stc.xyz+vec3(off.x*2.0, off.y, 0.0)).x;
+ shadow += shadow2D(shadowMap, stc.xyz+vec3(off.x, -off.y, 0.0)).x;
+ shadow += shadow2D(shadowMap, stc.xyz+vec3(-off.x, off.y, 0.0)).x;
+ shadow += shadow2D(shadowMap, stc.xyz+vec3(-off.x*2.0, -off.y, 0.0)).x;
+
+ return shadow*0.2;
}
void main()
@@ -124,11 +142,9 @@ void main()
vec4 pos = getPosition(pos_screen);
- vec4 nmap4 = texture2DRect(normalMap, pos_screen);
- nmap4 = vec4((nmap4.xy-0.5)*2.0,nmap4.z,nmap4.w); // unpack norm
- float displace = nmap4.w;
- vec3 norm = nmap4.xyz;
-
+ vec3 norm = texture2DRect(normalMap, pos_screen).xyz;
+ norm = decode_normal(norm.xy); // unpack norm
+
/*if (pos.z == 0.0) // do nothing for sky *FIX: REMOVE THIS IF/WHEN THE POSITION MAP IS BEING USED AS A STENCIL
{
frag_color = vec4(0.0); // doesn't matter
@@ -137,8 +153,8 @@ void main()
float shadow = 0.0;
float dp_directional_light = max(0.0, dot(norm, sun_dir.xyz));
-
- vec3 shadow_pos = pos.xyz + displace*norm;
+
+ vec3 shadow_pos = pos.xyz;
vec3 offset = sun_dir.xyz * (1.0-dp_directional_light);
vec4 spos = vec4(shadow_pos+offset*shadow_offset, 1.0);
@@ -162,11 +178,10 @@ void main()
if (spos.z < near_split.z)
{
lpos = shadow_matrix[3]*spos;
- lpos.xy *= shadow_res;
-
+
float w = 1.0;
w -= max(spos.z-far_split.z, 0.0)/transition_domain.z;
- shadow += pcfShadow(shadowMap3, lpos, 0.25)*w;
+ shadow += pcfShadow(shadowMap3, lpos, 0.25, pos_screen)*w;
weight += w;
shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0);
}
@@ -174,36 +189,33 @@ void main()
if (spos.z < near_split.y && spos.z > far_split.z)
{
lpos = shadow_matrix[2]*spos;
- lpos.xy *= shadow_res;
-
+
float w = 1.0;
w -= max(spos.z-far_split.y, 0.0)/transition_domain.y;
w -= max(near_split.z-spos.z, 0.0)/transition_domain.z;
- shadow += pcfShadow(shadowMap2, lpos, 0.75)*w;
+ shadow += pcfShadow(shadowMap2, lpos, 0.5, pos_screen)*w;
weight += w;
}
if (spos.z < near_split.x && spos.z > far_split.y)
{
lpos = shadow_matrix[1]*spos;
- lpos.xy *= shadow_res;
float w = 1.0;
w -= max(spos.z-far_split.x, 0.0)/transition_domain.x;
w -= max(near_split.y-spos.z, 0.0)/transition_domain.y;
- shadow += pcfShadow(shadowMap1, lpos, 0.75)*w;
+ shadow += pcfShadow(shadowMap1, lpos, 0.75, pos_screen)*w;
weight += w;
}
if (spos.z > far_split.x)
{
lpos = shadow_matrix[0]*spos;
- lpos.xy *= shadow_res;
float w = 1.0;
w -= max(near_split.x-spos.z, 0.0)/transition_domain.x;
- shadow += pcfShadow(shadowMap0, lpos, 1.0)*w;
+ shadow += pcfShadow(shadowMap0, lpos, 1.0, pos_screen)*w;
weight += w;
}
@@ -237,11 +249,11 @@ void main()
//spotlight shadow 1
vec4 lpos = shadow_matrix[4]*spos;
- frag_color[2] = pcfShadow(shadowMap4, lpos, 0.8);
+ frag_color[2] = pcfSpotShadow(shadowMap4, lpos, 0.8, pos_screen);
//spotlight shadow 2
lpos = shadow_matrix[5]*spos;
- frag_color[3] = pcfShadow(shadowMap5, lpos, 0.8);
+ frag_color[3] = pcfSpotShadow(shadowMap5, lpos, 0.8, pos_screen);
//frag_color.rgb = pos.xyz;
//frag_color.b = shadow;
diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl
index 02075a7687..b5ff6404ea 100644..100755
--- a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl
@@ -34,10 +34,10 @@ out vec4 frag_color;
uniform sampler2DRect depthMap;
uniform sampler2DRect normalMap;
-uniform sampler2DRectShadow shadowMap0;
-uniform sampler2DRectShadow shadowMap1;
-uniform sampler2DRectShadow shadowMap2;
-uniform sampler2DRectShadow shadowMap3;
+uniform sampler2DShadow shadowMap0;
+uniform sampler2DShadow shadowMap1;
+uniform sampler2DShadow shadowMap2;
+uniform sampler2DShadow shadowMap3;
uniform sampler2DShadow shadowMap4;
uniform sampler2DShadow shadowMap5;
uniform sampler2D noiseMap;
@@ -55,16 +55,34 @@ VARYING vec2 vary_fragcoord;
uniform mat4 inv_proj;
uniform vec2 screen_res;
-uniform vec2 shadow_res;
uniform vec2 proj_shadow_res;
uniform vec3 sun_dir;
+uniform vec2 shadow_res;
+
uniform float shadow_bias;
uniform float shadow_offset;
uniform float spot_shadow_bias;
uniform float spot_shadow_offset;
+vec2 encode_normal(vec3 n)
+{
+ float f = sqrt(8 * n.z + 8);
+ return n.xy / f + 0.5;
+}
+
+vec3 decode_normal (vec2 enc)
+{
+ vec2 fenc = enc*4-2;
+ float f = dot(fenc,fenc);
+ float g = sqrt(1-f/4);
+ vec3 n;
+ n.xy = fenc*g;
+ n.z = 1-f/2;
+ return n;
+}
+
vec4 getPosition(vec2 pos_screen)
{
float depth = texture2DRect(depthMap, pos_screen.xy).r;
@@ -90,7 +108,7 @@ vec2 getKern(int i)
kern[5] = vec2(-0.7071, -0.7071) * 0.750*0.750;
kern[6] = vec2(-0.7071, 0.7071) * 0.875*0.875;
kern[7] = vec2(0.7071, -0.7071) * 1.000*1.000;
-
+
return kern[i];
}
@@ -139,42 +157,42 @@ float calcAmbientOcclusion(vec4 pos, vec3 norm)
return min(ret, 1.0);
}
-float pcfShadow(sampler2DRectShadow shadowMap, vec4 stc, float scl)
+float pcfShadow(sampler2DShadow shadowMap, vec4 stc, float scl, vec2 pos_screen)
{
stc.xyz /= stc.w;
- stc.z += shadow_bias*scl;
+ stc.z += shadow_bias;
+
+ stc.x = floor(stc.x*shadow_res.x + fract(pos_screen.y*0.666666666))/shadow_res.x;
+ float cs = shadow2D(shadowMap, stc.xyz).x;
- float cs = shadow2DRect(shadowMap, stc.xyz).x;
float shadow = cs;
-
- shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(1.5, 1.5, 0.0)).x, cs);
- shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(1.5, -1.5, 0.0)).x, cs);
- shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(-1.5, 1.5, 0.0)).x, cs);
- shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(-1.5, -1.5, 0.0)).x, cs);
-
- return shadow/5.0;
- //return shadow;
+ shadow += shadow2D(shadowMap, stc.xyz+vec3(2.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x;
+ shadow += shadow2D(shadowMap, stc.xyz+vec3(1.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x;
+ shadow += shadow2D(shadowMap, stc.xyz+vec3(-1.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x;
+ shadow += shadow2D(shadowMap, stc.xyz+vec3(-2.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x;
+
+ return shadow*0.2;
}
-float pcfShadow(sampler2DShadow shadowMap, vec4 stc, float scl)
+float pcfSpotShadow(sampler2DShadow shadowMap, vec4 stc, float scl, vec2 pos_screen)
{
stc.xyz /= stc.w;
stc.z += spot_shadow_bias*scl;
-
+ stc.x = floor(proj_shadow_res.x * stc.x + fract(pos_screen.y*0.666666666)) / proj_shadow_res.x; // snap
+
float cs = shadow2D(shadowMap, stc.xyz).x;
float shadow = cs;
- vec2 off = 1.5/proj_shadow_res;
-
- shadow += max(shadow2D(shadowMap, stc.xyz+vec3(off.x, off.y, 0.0)).x, cs);
- shadow += max(shadow2D(shadowMap, stc.xyz+vec3(off.x, -off.y, 0.0)).x, cs);
- shadow += max(shadow2D(shadowMap, stc.xyz+vec3(-off.x, off.y, 0.0)).x, cs);
- shadow += max(shadow2D(shadowMap, stc.xyz+vec3(-off.x, -off.y, 0.0)).x, cs);
+ vec2 off = 1.0/proj_shadow_res;
+ off.y *= 1.5;
- return shadow/5.0;
-
- //return shadow;
+ shadow += shadow2D(shadowMap, stc.xyz+vec3(off.x*2.0, off.y, 0.0)).x;
+ shadow += shadow2D(shadowMap, stc.xyz+vec3(off.x, -off.y, 0.0)).x;
+ shadow += shadow2D(shadowMap, stc.xyz+vec3(-off.x, off.y, 0.0)).x;
+ shadow += shadow2D(shadowMap, stc.xyz+vec3(-off.x*2.0, -off.y, 0.0)).x;
+
+ return shadow*0.2;
}
void main()
@@ -185,11 +203,9 @@ void main()
vec4 pos = getPosition(pos_screen);
- vec4 nmap4 = texture2DRect(normalMap, pos_screen);
- nmap4 = vec4((nmap4.xy-0.5)*2.0,nmap4.z,nmap4.w); // unpack norm
- float displace = nmap4.w;
- vec3 norm = nmap4.xyz;
-
+ vec3 norm = texture2DRect(normalMap, pos_screen).xyz;
+ norm = decode_normal(norm.xy); // unpack norm
+
/*if (pos.z == 0.0) // do nothing for sky *FIX: REMOVE THIS IF/WHEN THE POSITION MAP IS BEING USED AS A STENCIL
{
frag_color = vec4(0.0); // doesn't matter
@@ -198,8 +214,8 @@ void main()
float shadow = 0.0;
float dp_directional_light = max(0.0, dot(norm, sun_dir.xyz));
-
- vec3 shadow_pos = pos.xyz + displace*norm;
+
+ vec3 shadow_pos = pos.xyz;
vec3 offset = sun_dir.xyz * (1.0-dp_directional_light);
vec4 spos = vec4(shadow_pos+offset*shadow_offset, 1.0);
@@ -223,11 +239,10 @@ void main()
if (spos.z < near_split.z)
{
lpos = shadow_matrix[3]*spos;
- lpos.xy *= shadow_res;
-
+
float w = 1.0;
w -= max(spos.z-far_split.z, 0.0)/transition_domain.z;
- shadow += pcfShadow(shadowMap3, lpos, 0.25)*w;
+ shadow += pcfShadow(shadowMap3, lpos, 0.25, pos_screen)*w;
weight += w;
shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0);
}
@@ -235,36 +250,33 @@ void main()
if (spos.z < near_split.y && spos.z > far_split.z)
{
lpos = shadow_matrix[2]*spos;
- lpos.xy *= shadow_res;
-
+
float w = 1.0;
w -= max(spos.z-far_split.y, 0.0)/transition_domain.y;
w -= max(near_split.z-spos.z, 0.0)/transition_domain.z;
- shadow += pcfShadow(shadowMap2, lpos, 0.75)*w;
+ shadow += pcfShadow(shadowMap2, lpos, 0.5, pos_screen)*w;
weight += w;
}
if (spos.z < near_split.x && spos.z > far_split.y)
{
lpos = shadow_matrix[1]*spos;
- lpos.xy *= shadow_res;
-
+
float w = 1.0;
w -= max(spos.z-far_split.x, 0.0)/transition_domain.x;
w -= max(near_split.y-spos.z, 0.0)/transition_domain.y;
- shadow += pcfShadow(shadowMap1, lpos, 0.75)*w;
+ shadow += pcfShadow(shadowMap1, lpos, 0.75, pos_screen)*w;
weight += w;
}
if (spos.z > far_split.x)
{
lpos = shadow_matrix[0]*spos;
- lpos.xy *= shadow_res;
-
+
float w = 1.0;
w -= max(near_split.x-spos.z, 0.0)/transition_domain.x;
- shadow += pcfShadow(shadowMap0, lpos, 1.0)*w;
+ shadow += pcfShadow(shadowMap0, lpos, 1.0, pos_screen)*w;
weight += w;
}
@@ -298,11 +310,11 @@ void main()
//spotlight shadow 1
vec4 lpos = shadow_matrix[4]*spos;
- frag_color[2] = pcfShadow(shadowMap4, lpos, 0.8);
+ frag_color[2] = pcfSpotShadow(shadowMap4, lpos, 0.8, pos_screen);
//spotlight shadow 2
lpos = shadow_matrix[5]*spos;
- frag_color[3] = pcfShadow(shadowMap5, lpos, 0.8);
+ frag_color[3] = pcfSpotShadow(shadowMap5, lpos, 0.8, pos_screen);
//frag_color.rgb = pos.xyz;
//frag_color.b = shadow;
diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightV.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightV.glsl
index bc5eb5181d..bc5eb5181d 100644..100755
--- a/indra/newview/app_settings/shaders/class2/deferred/sunLightV.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightV.glsl
diff --git a/indra/newview/app_settings/shaders/class2/lighting/sumLightsSpecularV.glsl b/indra/newview/app_settings/shaders/class2/lighting/sumLightsSpecularV.glsl
index 3acf9fe883..3acf9fe883 100644..100755
--- a/indra/newview/app_settings/shaders/class2/lighting/sumLightsSpecularV.glsl
+++ b/indra/newview/app_settings/shaders/class2/lighting/sumLightsSpecularV.glsl
diff --git a/indra/newview/app_settings/shaders/class2/lighting/sumLightsV.glsl b/indra/newview/app_settings/shaders/class2/lighting/sumLightsV.glsl
index c9987ef3b9..c9987ef3b9 100644..100755
--- a/indra/newview/app_settings/shaders/class2/lighting/sumLightsV.glsl
+++ b/indra/newview/app_settings/shaders/class2/lighting/sumLightsV.glsl
diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl
index fea3cbf69b..fea3cbf69b 100644..100755
--- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl
diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsHelpersV.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsHelpersV.glsl
index 62a034ce05..62a034ce05 100644..100755
--- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsHelpersV.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsHelpersV.glsl
diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsV.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsV.glsl
index da3d922017..d174805cc0 100644..100755
--- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsV.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsV.glsl
@@ -129,7 +129,7 @@ void calcAtmospherics(vec3 inPositionEye) {
vec3(blue_horizon * blue_weight * (sunlight*(1.-cloud_shadow) + tmpAmbient)
+ (haze_horizon * haze_weight) * (sunlight*(1.-cloud_shadow) * temp2.x
+ tmpAmbient)));
-
+
//brightness of surface both sunlight and ambient
setSunlitColor(vec3(sunlight * .5));
setAmblitColor(vec3(tmpAmbient * .25));
diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsF.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsF.glsl
index 765b0927c3..765b0927c3 100644..100755
--- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsF.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsF.glsl
diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsV.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsV.glsl
index 99dbee15ee..99dbee15ee 100644..100755
--- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsV.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsV.glsl
diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsWaterF.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsWaterF.glsl
index 163ef26444..163ef26444 100644..100755
--- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsWaterF.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsWaterF.glsl
diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsWaterV.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsWaterV.glsl
index 553f6752e6..553f6752e6 100644..100755
--- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsWaterV.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsWaterV.glsl
diff --git a/indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl b/indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl
index 96c70651b1..96c70651b1 100644..100755
--- a/indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl
diff --git a/indra/newview/app_settings/shaders/class2/windlight/cloudsV.glsl b/indra/newview/app_settings/shaders/class2/windlight/cloudsV.glsl
index c1dd45cd67..c1dd45cd67 100644..100755
--- a/indra/newview/app_settings/shaders/class2/windlight/cloudsV.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/cloudsV.glsl
diff --git a/indra/newview/app_settings/shaders/class2/windlight/gammaF.glsl b/indra/newview/app_settings/shaders/class2/windlight/gammaF.glsl
index 478373d729..478373d729 100644..100755
--- a/indra/newview/app_settings/shaders/class2/windlight/gammaF.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/gammaF.glsl
diff --git a/indra/newview/app_settings/shaders/class2/windlight/skyF.glsl b/indra/newview/app_settings/shaders/class2/windlight/skyF.glsl
index e2a2367626..e2a2367626 100644..100755
--- a/indra/newview/app_settings/shaders/class2/windlight/skyF.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/skyF.glsl
diff --git a/indra/newview/app_settings/shaders/class2/windlight/skyV.glsl b/indra/newview/app_settings/shaders/class2/windlight/skyV.glsl
index 3788ddaf2d..3788ddaf2d 100644..100755
--- a/indra/newview/app_settings/shaders/class2/windlight/skyV.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/skyV.glsl
diff --git a/indra/newview/app_settings/shaders/class2/windlight/transportF.glsl b/indra/newview/app_settings/shaders/class2/windlight/transportF.glsl
index 8a8e4cb0f6..8a8e4cb0f6 100644..100755
--- a/indra/newview/app_settings/shaders/class2/windlight/transportF.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/transportF.glsl
diff --git a/indra/newview/app_settings/shaders/class3/avatar/avatarV.glsl b/indra/newview/app_settings/shaders/class3/avatar/avatarV.glsl
index 721054b5ad..721054b5ad 100644..100755
--- a/indra/newview/app_settings/shaders/class3/avatar/avatarV.glsl
+++ b/indra/newview/app_settings/shaders/class3/avatar/avatarV.glsl
diff --git a/indra/newview/app_settings/shaders/class3/lighting/sumLightsSpecularV.glsl b/indra/newview/app_settings/shaders/class3/lighting/sumLightsSpecularV.glsl
index e043ac873e..e043ac873e 100644..100755
--- a/indra/newview/app_settings/shaders/class3/lighting/sumLightsSpecularV.glsl
+++ b/indra/newview/app_settings/shaders/class3/lighting/sumLightsSpecularV.glsl
diff --git a/indra/newview/app_settings/shaders/class3/lighting/sumLightsV.glsl b/indra/newview/app_settings/shaders/class3/lighting/sumLightsV.glsl
index dadff40933..dadff40933 100644..100755
--- a/indra/newview/app_settings/shaders/class3/lighting/sumLightsV.glsl
+++ b/indra/newview/app_settings/shaders/class3/lighting/sumLightsV.glsl
diff --git a/indra/newview/app_settings/shaders/shader_hierarchy.txt b/indra/newview/app_settings/shaders/shader_hierarchy.txt
index d8bbf69b38..d8bbf69b38 100644..100755
--- a/indra/newview/app_settings/shaders/shader_hierarchy.txt
+++ b/indra/newview/app_settings/shaders/shader_hierarchy.txt
diff --git a/indra/newview/app_settings/static_data.db2 b/indra/newview/app_settings/static_data.db2
index f85aa81601..f85aa81601 100644..100755
--- a/indra/newview/app_settings/static_data.db2
+++ b/indra/newview/app_settings/static_data.db2
Binary files differ
diff --git a/indra/newview/app_settings/static_index.db2 b/indra/newview/app_settings/static_index.db2
index a5440f96f2..a5440f96f2 100644..100755
--- a/indra/newview/app_settings/static_index.db2
+++ b/indra/newview/app_settings/static_index.db2
Binary files differ
diff --git a/indra/newview/app_settings/std_bump.ini b/indra/newview/app_settings/std_bump.ini
index 561e04c33c..561e04c33c 100644..100755
--- a/indra/newview/app_settings/std_bump.ini
+++ b/indra/newview/app_settings/std_bump.ini
diff --git a/indra/newview/app_settings/toolbars.xml b/indra/newview/app_settings/toolbars.xml
index 29c019719d..86f9912815 100644..100755
--- a/indra/newview/app_settings/toolbars.xml
+++ b/indra/newview/app_settings/toolbars.xml
@@ -6,6 +6,7 @@
<command name="speak"/>
<command name="destinations"/>
<command name="people"/>
+ <command name="social"/>
<command name="profile"/>
<command name="move"/>
<command name="view"/>
diff --git a/indra/newview/app_settings/trees.xml b/indra/newview/app_settings/trees.xml
index 213ee85fc7..213ee85fc7 100644..100755
--- a/indra/newview/app_settings/trees.xml
+++ b/indra/newview/app_settings/trees.xml
diff --git a/indra/newview/app_settings/ultra_graphics.xml b/indra/newview/app_settings/ultra_graphics.xml
index 71459e5470..71459e5470 100644..100755
--- a/indra/newview/app_settings/ultra_graphics.xml
+++ b/indra/newview/app_settings/ultra_graphics.xml
diff --git a/indra/newview/app_settings/viewerart.xml b/indra/newview/app_settings/viewerart.xml
index d56efeae09..d56efeae09 100644..100755
--- a/indra/newview/app_settings/viewerart.xml
+++ b/indra/newview/app_settings/viewerart.xml
diff --git a/indra/newview/app_settings/windlight/clouds2.tga b/indra/newview/app_settings/windlight/clouds2.tga
index c95ce7fec4..c95ce7fec4 100644..100755
--- a/indra/newview/app_settings/windlight/clouds2.tga
+++ b/indra/newview/app_settings/windlight/clouds2.tga
Binary files differ
diff --git a/indra/newview/app_settings/windlight/days/Colder%20Tones.xml b/indra/newview/app_settings/windlight/days/Colder%20Tones.xml
index 63d0b099e1..63d0b099e1 100644..100755
--- a/indra/newview/app_settings/windlight/days/Colder%20Tones.xml
+++ b/indra/newview/app_settings/windlight/days/Colder%20Tones.xml
diff --git a/indra/newview/app_settings/windlight/days/Default.xml b/indra/newview/app_settings/windlight/days/Default.xml
index 3d3afd5075..3d3afd5075 100644..100755
--- a/indra/newview/app_settings/windlight/days/Default.xml
+++ b/indra/newview/app_settings/windlight/days/Default.xml
diff --git a/indra/newview/app_settings/windlight/days/Dynamic%20Richness.xml b/indra/newview/app_settings/windlight/days/Dynamic%20Richness.xml
index f75b52e6ed..f75b52e6ed 100644..100755
--- a/indra/newview/app_settings/windlight/days/Dynamic%20Richness.xml
+++ b/indra/newview/app_settings/windlight/days/Dynamic%20Richness.xml
diff --git a/indra/newview/app_settings/windlight/days/Pirate%27s%20Dream.xml b/indra/newview/app_settings/windlight/days/Pirate%27s%20Dream.xml
index 6dc1ba9f4d..6dc1ba9f4d 100644..100755
--- a/indra/newview/app_settings/windlight/days/Pirate%27s%20Dream.xml
+++ b/indra/newview/app_settings/windlight/days/Pirate%27s%20Dream.xml
diff --git a/indra/newview/app_settings/windlight/days/Psycho%20Strobe%21.xml b/indra/newview/app_settings/windlight/days/Psycho%20Strobe%21.xml
index 302af5a9ba..302af5a9ba 100644..100755
--- a/indra/newview/app_settings/windlight/days/Psycho%20Strobe%21.xml
+++ b/indra/newview/app_settings/windlight/days/Psycho%20Strobe%21.xml
diff --git a/indra/newview/app_settings/windlight/days/Tropicalia.xml b/indra/newview/app_settings/windlight/days/Tropicalia.xml
index 89a56d4a13..89a56d4a13 100644..100755
--- a/indra/newview/app_settings/windlight/days/Tropicalia.xml
+++ b/indra/newview/app_settings/windlight/days/Tropicalia.xml
diff --git a/indra/newview/app_settings/windlight/days/Weird-O.xml b/indra/newview/app_settings/windlight/days/Weird-O.xml
index 1e312f2464..1e312f2464 100644..100755
--- a/indra/newview/app_settings/windlight/days/Weird-O.xml
+++ b/indra/newview/app_settings/windlight/days/Weird-O.xml
diff --git a/indra/newview/app_settings/windlight/postprocesseffects.xml b/indra/newview/app_settings/windlight/postprocesseffects.xml
index 60fbfd3483..60fbfd3483 100644..100755
--- a/indra/newview/app_settings/windlight/postprocesseffects.xml
+++ b/indra/newview/app_settings/windlight/postprocesseffects.xml
diff --git a/indra/newview/app_settings/windlight/skies/A%2D12AM.xml b/indra/newview/app_settings/windlight/skies/A%2D12AM.xml
index 0aba31214a..0aba31214a 100644..100755
--- a/indra/newview/app_settings/windlight/skies/A%2D12AM.xml
+++ b/indra/newview/app_settings/windlight/skies/A%2D12AM.xml
diff --git a/indra/newview/app_settings/windlight/skies/A%2D12PM.xml b/indra/newview/app_settings/windlight/skies/A%2D12PM.xml
index 119b3e1418..119b3e1418 100644..100755
--- a/indra/newview/app_settings/windlight/skies/A%2D12PM.xml
+++ b/indra/newview/app_settings/windlight/skies/A%2D12PM.xml
diff --git a/indra/newview/app_settings/windlight/skies/A%2D3AM.xml b/indra/newview/app_settings/windlight/skies/A%2D3AM.xml
index f790d3d961..f790d3d961 100644..100755
--- a/indra/newview/app_settings/windlight/skies/A%2D3AM.xml
+++ b/indra/newview/app_settings/windlight/skies/A%2D3AM.xml
diff --git a/indra/newview/app_settings/windlight/skies/A%2D3PM.xml b/indra/newview/app_settings/windlight/skies/A%2D3PM.xml
index ec9706773e..ec9706773e 100644..100755
--- a/indra/newview/app_settings/windlight/skies/A%2D3PM.xml
+++ b/indra/newview/app_settings/windlight/skies/A%2D3PM.xml
diff --git a/indra/newview/app_settings/windlight/skies/A%2D6AM.xml b/indra/newview/app_settings/windlight/skies/A%2D6AM.xml
index bbc7aeec59..bbc7aeec59 100644..100755
--- a/indra/newview/app_settings/windlight/skies/A%2D6AM.xml
+++ b/indra/newview/app_settings/windlight/skies/A%2D6AM.xml
diff --git a/indra/newview/app_settings/windlight/skies/A%2D6PM.xml b/indra/newview/app_settings/windlight/skies/A%2D6PM.xml
index ebf08e1a3f..ebf08e1a3f 100644..100755
--- a/indra/newview/app_settings/windlight/skies/A%2D6PM.xml
+++ b/indra/newview/app_settings/windlight/skies/A%2D6PM.xml
diff --git a/indra/newview/app_settings/windlight/skies/A%2D9AM.xml b/indra/newview/app_settings/windlight/skies/A%2D9AM.xml
index 413e3a27d9..413e3a27d9 100644..100755
--- a/indra/newview/app_settings/windlight/skies/A%2D9AM.xml
+++ b/indra/newview/app_settings/windlight/skies/A%2D9AM.xml
diff --git a/indra/newview/app_settings/windlight/skies/A%2D9PM.xml b/indra/newview/app_settings/windlight/skies/A%2D9PM.xml
index 292f6713b7..292f6713b7 100644..100755
--- a/indra/newview/app_settings/windlight/skies/A%2D9PM.xml
+++ b/indra/newview/app_settings/windlight/skies/A%2D9PM.xml
diff --git a/indra/newview/app_settings/windlight/skies/Barcelona.xml b/indra/newview/app_settings/windlight/skies/Barcelona.xml
index ea9cab8fbb..ea9cab8fbb 100644..100755
--- a/indra/newview/app_settings/windlight/skies/Barcelona.xml
+++ b/indra/newview/app_settings/windlight/skies/Barcelona.xml
diff --git a/indra/newview/app_settings/windlight/skies/Blizzard.xml b/indra/newview/app_settings/windlight/skies/Blizzard.xml
index d17d2790a8..d17d2790a8 100644..100755
--- a/indra/newview/app_settings/windlight/skies/Blizzard.xml
+++ b/indra/newview/app_settings/windlight/skies/Blizzard.xml
diff --git a/indra/newview/app_settings/windlight/skies/Blue%20Midday.xml b/indra/newview/app_settings/windlight/skies/Blue%20Midday.xml
index 570f059961..570f059961 100644..100755
--- a/indra/newview/app_settings/windlight/skies/Blue%20Midday.xml
+++ b/indra/newview/app_settings/windlight/skies/Blue%20Midday.xml
diff --git a/indra/newview/app_settings/windlight/skies/Coastal%20Afternoon.xml b/indra/newview/app_settings/windlight/skies/Coastal%20Afternoon.xml
index 4925b29eea..4925b29eea 100644..100755
--- a/indra/newview/app_settings/windlight/skies/Coastal%20Afternoon.xml
+++ b/indra/newview/app_settings/windlight/skies/Coastal%20Afternoon.xml
diff --git a/indra/newview/app_settings/windlight/skies/Coastal%20Sunset.xml b/indra/newview/app_settings/windlight/skies/Coastal%20Sunset.xml
index f4736cf4c6..f4736cf4c6 100644..100755
--- a/indra/newview/app_settings/windlight/skies/Coastal%20Sunset.xml
+++ b/indra/newview/app_settings/windlight/skies/Coastal%20Sunset.xml
diff --git a/indra/newview/app_settings/windlight/skies/Default.xml b/indra/newview/app_settings/windlight/skies/Default.xml
index 13a2c75046..13a2c75046 100644..100755
--- a/indra/newview/app_settings/windlight/skies/Default.xml
+++ b/indra/newview/app_settings/windlight/skies/Default.xml
diff --git a/indra/newview/app_settings/windlight/skies/Desert%20Sunset.xml b/indra/newview/app_settings/windlight/skies/Desert%20Sunset.xml
index b2a611163d..b2a611163d 100644..100755
--- a/indra/newview/app_settings/windlight/skies/Desert%20Sunset.xml
+++ b/indra/newview/app_settings/windlight/skies/Desert%20Sunset.xml
diff --git a/indra/newview/app_settings/windlight/skies/Fine%20Day.xml b/indra/newview/app_settings/windlight/skies/Fine%20Day.xml
index e053815be1..e053815be1 100644..100755
--- a/indra/newview/app_settings/windlight/skies/Fine%20Day.xml
+++ b/indra/newview/app_settings/windlight/skies/Fine%20Day.xml
diff --git a/indra/newview/app_settings/windlight/skies/Fluffy%20Big%20Clouds.xml b/indra/newview/app_settings/windlight/skies/Fluffy%20Big%20Clouds.xml
index 8576ec125c..8576ec125c 100644..100755
--- a/indra/newview/app_settings/windlight/skies/Fluffy%20Big%20Clouds.xml
+++ b/indra/newview/app_settings/windlight/skies/Fluffy%20Big%20Clouds.xml
diff --git a/indra/newview/app_settings/windlight/skies/Foggy.xml b/indra/newview/app_settings/windlight/skies/Foggy.xml
index cb7395d589..cb7395d589 100644..100755
--- a/indra/newview/app_settings/windlight/skies/Foggy.xml
+++ b/indra/newview/app_settings/windlight/skies/Foggy.xml
diff --git a/indra/newview/app_settings/windlight/skies/Funky%20Funky%20Funky.xml b/indra/newview/app_settings/windlight/skies/Funky%20Funky%20Funky.xml
index 32be0d25e6..32be0d25e6 100644..100755
--- a/indra/newview/app_settings/windlight/skies/Funky%20Funky%20Funky.xml
+++ b/indra/newview/app_settings/windlight/skies/Funky%20Funky%20Funky.xml
diff --git a/indra/newview/app_settings/windlight/skies/Funky%20Funky.xml b/indra/newview/app_settings/windlight/skies/Funky%20Funky.xml
index ae16b2d135..ae16b2d135 100644..100755
--- a/indra/newview/app_settings/windlight/skies/Funky%20Funky.xml
+++ b/indra/newview/app_settings/windlight/skies/Funky%20Funky.xml
diff --git a/indra/newview/app_settings/windlight/skies/Gelatto.xml b/indra/newview/app_settings/windlight/skies/Gelatto.xml
index 66b3d317b8..66b3d317b8 100644..100755
--- a/indra/newview/app_settings/windlight/skies/Gelatto.xml
+++ b/indra/newview/app_settings/windlight/skies/Gelatto.xml
diff --git a/indra/newview/app_settings/windlight/skies/Ghost.xml b/indra/newview/app_settings/windlight/skies/Ghost.xml
index 447202ed51..447202ed51 100644..100755
--- a/indra/newview/app_settings/windlight/skies/Ghost.xml
+++ b/indra/newview/app_settings/windlight/skies/Ghost.xml
diff --git a/indra/newview/app_settings/windlight/skies/Incongruent%20Truths.xml b/indra/newview/app_settings/windlight/skies/Incongruent%20Truths.xml
index 098844e16e..098844e16e 100644..100755
--- a/indra/newview/app_settings/windlight/skies/Incongruent%20Truths.xml
+++ b/indra/newview/app_settings/windlight/skies/Incongruent%20Truths.xml
diff --git a/indra/newview/app_settings/windlight/skies/Midday%201.xml b/indra/newview/app_settings/windlight/skies/Midday%201.xml
index 13a2c75046..13a2c75046 100644..100755
--- a/indra/newview/app_settings/windlight/skies/Midday%201.xml
+++ b/indra/newview/app_settings/windlight/skies/Midday%201.xml
diff --git a/indra/newview/app_settings/windlight/skies/Midday%202.xml b/indra/newview/app_settings/windlight/skies/Midday%202.xml
index 04f2ba85ee..04f2ba85ee 100644..100755
--- a/indra/newview/app_settings/windlight/skies/Midday%202.xml
+++ b/indra/newview/app_settings/windlight/skies/Midday%202.xml
diff --git a/indra/newview/app_settings/windlight/skies/Midday%203.xml b/indra/newview/app_settings/windlight/skies/Midday%203.xml
index a23dcab60b..a23dcab60b 100644..100755
--- a/indra/newview/app_settings/windlight/skies/Midday%203.xml
+++ b/indra/newview/app_settings/windlight/skies/Midday%203.xml
diff --git a/indra/newview/app_settings/windlight/skies/Midday%204.xml b/indra/newview/app_settings/windlight/skies/Midday%204.xml
index 255e314e0f..255e314e0f 100644..100755
--- a/indra/newview/app_settings/windlight/skies/Midday%204.xml
+++ b/indra/newview/app_settings/windlight/skies/Midday%204.xml
diff --git a/indra/newview/app_settings/windlight/skies/Midday.xml b/indra/newview/app_settings/windlight/skies/Midday.xml
index 119b3e1418..119b3e1418 100644..100755
--- a/indra/newview/app_settings/windlight/skies/Midday.xml
+++ b/indra/newview/app_settings/windlight/skies/Midday.xml
diff --git a/indra/newview/app_settings/windlight/skies/Midnight.xml b/indra/newview/app_settings/windlight/skies/Midnight.xml
index 0aba31214a..0aba31214a 100644..100755
--- a/indra/newview/app_settings/windlight/skies/Midnight.xml
+++ b/indra/newview/app_settings/windlight/skies/Midnight.xml
diff --git a/indra/newview/app_settings/windlight/skies/Night.xml b/indra/newview/app_settings/windlight/skies/Night.xml
index c4938949ce..c4938949ce 100644..100755
--- a/indra/newview/app_settings/windlight/skies/Night.xml
+++ b/indra/newview/app_settings/windlight/skies/Night.xml
diff --git a/indra/newview/app_settings/windlight/skies/Pirate.xml b/indra/newview/app_settings/windlight/skies/Pirate.xml
index dcb9c27ba4..dcb9c27ba4 100644..100755
--- a/indra/newview/app_settings/windlight/skies/Pirate.xml
+++ b/indra/newview/app_settings/windlight/skies/Pirate.xml
diff --git a/indra/newview/app_settings/windlight/skies/Purple.xml b/indra/newview/app_settings/windlight/skies/Purple.xml
index 0e9ac3f36e..0e9ac3f36e 100644..100755
--- a/indra/newview/app_settings/windlight/skies/Purple.xml
+++ b/indra/newview/app_settings/windlight/skies/Purple.xml
diff --git a/indra/newview/app_settings/windlight/skies/Sailor%27s%20Delight.xml b/indra/newview/app_settings/windlight/skies/Sailor%27s%20Delight.xml
index 70df6b0e60..70df6b0e60 100644..100755
--- a/indra/newview/app_settings/windlight/skies/Sailor%27s%20Delight.xml
+++ b/indra/newview/app_settings/windlight/skies/Sailor%27s%20Delight.xml
diff --git a/indra/newview/app_settings/windlight/skies/Sheer%20Surreality.xml b/indra/newview/app_settings/windlight/skies/Sheer%20Surreality.xml
index 4c44a1bdb2..4c44a1bdb2 100644..100755
--- a/indra/newview/app_settings/windlight/skies/Sheer%20Surreality.xml
+++ b/indra/newview/app_settings/windlight/skies/Sheer%20Surreality.xml
diff --git a/indra/newview/app_settings/windlight/skies/Sunrise.xml b/indra/newview/app_settings/windlight/skies/Sunrise.xml
index bbc7aeec59..bbc7aeec59 100644..100755
--- a/indra/newview/app_settings/windlight/skies/Sunrise.xml
+++ b/indra/newview/app_settings/windlight/skies/Sunrise.xml
diff --git a/indra/newview/app_settings/windlight/skies/Sunset.xml b/indra/newview/app_settings/windlight/skies/Sunset.xml
index ebf08e1a3f..ebf08e1a3f 100644..100755
--- a/indra/newview/app_settings/windlight/skies/Sunset.xml
+++ b/indra/newview/app_settings/windlight/skies/Sunset.xml
diff --git a/indra/newview/app_settings/windlight/water/Default.xml b/indra/newview/app_settings/windlight/water/Default.xml
index dce4148c7d..dce4148c7d 100644..100755
--- a/indra/newview/app_settings/windlight/water/Default.xml
+++ b/indra/newview/app_settings/windlight/water/Default.xml
diff --git a/indra/newview/app_settings/windlight/water/Glassy.xml b/indra/newview/app_settings/windlight/water/Glassy.xml
index 01183e4687..01183e4687 100644..100755
--- a/indra/newview/app_settings/windlight/water/Glassy.xml
+++ b/indra/newview/app_settings/windlight/water/Glassy.xml
diff --git a/indra/newview/app_settings/windlight/water/Murky.xml b/indra/newview/app_settings/windlight/water/Murky.xml
index 1d9e022422..1d9e022422 100644..100755
--- a/indra/newview/app_settings/windlight/water/Murky.xml
+++ b/indra/newview/app_settings/windlight/water/Murky.xml
diff --git a/indra/newview/app_settings/windlight/water/Pond.xml b/indra/newview/app_settings/windlight/water/Pond.xml
index 59e3c441ea..59e3c441ea 100644..100755
--- a/indra/newview/app_settings/windlight/water/Pond.xml
+++ b/indra/newview/app_settings/windlight/water/Pond.xml
diff --git a/indra/newview/app_settings/windlight/water/SNAKE%21%21%21.xml b/indra/newview/app_settings/windlight/water/SNAKE%21%21%21.xml
index 6dbc4e8719..6dbc4e8719 100644..100755
--- a/indra/newview/app_settings/windlight/water/SNAKE%21%21%21.xml
+++ b/indra/newview/app_settings/windlight/water/SNAKE%21%21%21.xml
diff --git a/indra/newview/app_settings/windlight/water/Second%20Plague.xml b/indra/newview/app_settings/windlight/water/Second%20Plague.xml
index 137483ab64..137483ab64 100644..100755
--- a/indra/newview/app_settings/windlight/water/Second%20Plague.xml
+++ b/indra/newview/app_settings/windlight/water/Second%20Plague.xml
diff --git a/indra/newview/app_settings/windlight/water/Valdez.xml b/indra/newview/app_settings/windlight/water/Valdez.xml
index eb70a142e0..eb70a142e0 100644..100755
--- a/indra/newview/app_settings/windlight/water/Valdez.xml
+++ b/indra/newview/app_settings/windlight/water/Valdez.xml
diff --git a/indra/newview/build_win32_appConfig.py b/indra/newview/build_win32_appConfig.py
index 9fdceee1be..9fdceee1be 100644..100755
--- a/indra/newview/build_win32_appConfig.py
+++ b/indra/newview/build_win32_appConfig.py
diff --git a/indra/newview/character/attentions.xml b/indra/newview/character/attentions.xml
index be9a2b28fc..be9a2b28fc 100644..100755
--- a/indra/newview/character/attentions.xml
+++ b/indra/newview/character/attentions.xml
diff --git a/indra/newview/character/attentionsN.xml b/indra/newview/character/attentionsN.xml
index e7d9bb6a16..e7d9bb6a16 100644..100755
--- a/indra/newview/character/attentionsN.xml
+++ b/indra/newview/character/attentionsN.xml
diff --git a/indra/newview/character/avatar_eye.llm b/indra/newview/character/avatar_eye.llm
index 8c6e74e1de..8c6e74e1de 100644..100755
--- a/indra/newview/character/avatar_eye.llm
+++ b/indra/newview/character/avatar_eye.llm
Binary files differ
diff --git a/indra/newview/character/avatar_eye_1.llm b/indra/newview/character/avatar_eye_1.llm
index 7a3b0d6f28..7a3b0d6f28 100644..100755
--- a/indra/newview/character/avatar_eye_1.llm
+++ b/indra/newview/character/avatar_eye_1.llm
Binary files differ
diff --git a/indra/newview/character/avatar_eyelashes.llm b/indra/newview/character/avatar_eyelashes.llm
index 99995b5758..99995b5758 100644..100755
--- a/indra/newview/character/avatar_eyelashes.llm
+++ b/indra/newview/character/avatar_eyelashes.llm
Binary files differ
diff --git a/indra/newview/character/avatar_hair.llm b/indra/newview/character/avatar_hair.llm
index df99de8db7..df99de8db7 100644..100755
--- a/indra/newview/character/avatar_hair.llm
+++ b/indra/newview/character/avatar_hair.llm
Binary files differ
diff --git a/indra/newview/character/avatar_hair_1.llm b/indra/newview/character/avatar_hair_1.llm
index 6de31fdc23..6de31fdc23 100644..100755
--- a/indra/newview/character/avatar_hair_1.llm
+++ b/indra/newview/character/avatar_hair_1.llm
Binary files differ
diff --git a/indra/newview/character/avatar_hair_2.llm b/indra/newview/character/avatar_hair_2.llm
index 47d02ba9ce..47d02ba9ce 100644..100755
--- a/indra/newview/character/avatar_hair_2.llm
+++ b/indra/newview/character/avatar_hair_2.llm
Binary files differ
diff --git a/indra/newview/character/avatar_hair_3.llm b/indra/newview/character/avatar_hair_3.llm
index 107f9e2a53..107f9e2a53 100644..100755
--- a/indra/newview/character/avatar_hair_3.llm
+++ b/indra/newview/character/avatar_hair_3.llm
Binary files differ
diff --git a/indra/newview/character/avatar_hair_4.llm b/indra/newview/character/avatar_hair_4.llm
index 1b9a12a0ca..1b9a12a0ca 100644..100755
--- a/indra/newview/character/avatar_hair_4.llm
+++ b/indra/newview/character/avatar_hair_4.llm
Binary files differ
diff --git a/indra/newview/character/avatar_hair_5.llm b/indra/newview/character/avatar_hair_5.llm
index 1b9a12a0ca..1b9a12a0ca 100644..100755
--- a/indra/newview/character/avatar_hair_5.llm
+++ b/indra/newview/character/avatar_hair_5.llm
Binary files differ
diff --git a/indra/newview/character/avatar_head.llm b/indra/newview/character/avatar_head.llm
index 8d8b5e0442..8d8b5e0442 100644..100755
--- a/indra/newview/character/avatar_head.llm
+++ b/indra/newview/character/avatar_head.llm
Binary files differ
diff --git a/indra/newview/character/avatar_head_1.llm b/indra/newview/character/avatar_head_1.llm
index 26291e6584..26291e6584 100644..100755
--- a/indra/newview/character/avatar_head_1.llm
+++ b/indra/newview/character/avatar_head_1.llm
Binary files differ
diff --git a/indra/newview/character/avatar_head_2.llm b/indra/newview/character/avatar_head_2.llm
index c2b808b1a6..c2b808b1a6 100644..100755
--- a/indra/newview/character/avatar_head_2.llm
+++ b/indra/newview/character/avatar_head_2.llm
Binary files differ
diff --git a/indra/newview/character/avatar_head_3.llm b/indra/newview/character/avatar_head_3.llm
index a0676b1f1c..a0676b1f1c 100644..100755
--- a/indra/newview/character/avatar_head_3.llm
+++ b/indra/newview/character/avatar_head_3.llm
Binary files differ
diff --git a/indra/newview/character/avatar_head_4.llm b/indra/newview/character/avatar_head_4.llm
index 5035585770..5035585770 100644..100755
--- a/indra/newview/character/avatar_head_4.llm
+++ b/indra/newview/character/avatar_head_4.llm
Binary files differ
diff --git a/indra/newview/character/avatar_lad.xml b/indra/newview/character/avatar_lad.xml
index 99dbfcae51..e5b385f4aa 100644..100755
--- a/indra/newview/character/avatar_lad.xml
+++ b/indra/newview/character/avatar_lad.xml
@@ -1084,6 +1084,22 @@
scale="0 0 .5" />
</param_skeleton>
</param>
+ <param
+ id="11001"
+ group="0"
+ name="Hover"
+ wearable="shape"
+ edit_group="shape_body"
+ edit_group_order="4"
+ label_min="Lower"
+ label_max="Higher"
+ value_min="-2"
+ value_max="2"
+ value_default="0"
+ camera_distance="2.5">
+ <param_skeleton />
+ </param>
+
</skeleton>
<mesh
@@ -12291,6 +12307,17 @@ render_pass="bump">
<param_driver />
</param>
+ <param
+ id="11000"
+ group="0"
+ name="AppearanceMessage_Version"
+ label="AppearanceMessage Version"
+ value_default="0"
+ value_min="0"
+ value_max="255">
+ <param_driver />
+ </param>
+
</driver_parameters>
<morph_masks>
diff --git a/indra/newview/character/avatar_lower_body.llm b/indra/newview/character/avatar_lower_body.llm
index 0420899739..0420899739 100644..100755
--- a/indra/newview/character/avatar_lower_body.llm
+++ b/indra/newview/character/avatar_lower_body.llm
Binary files differ
diff --git a/indra/newview/character/avatar_lower_body_1.llm b/indra/newview/character/avatar_lower_body_1.llm
index 1394eb848b..1394eb848b 100644..100755
--- a/indra/newview/character/avatar_lower_body_1.llm
+++ b/indra/newview/character/avatar_lower_body_1.llm
Binary files differ
diff --git a/indra/newview/character/avatar_lower_body_2.llm b/indra/newview/character/avatar_lower_body_2.llm
index 0da9c1249e..0da9c1249e 100644..100755
--- a/indra/newview/character/avatar_lower_body_2.llm
+++ b/indra/newview/character/avatar_lower_body_2.llm
Binary files differ
diff --git a/indra/newview/character/avatar_lower_body_3.llm b/indra/newview/character/avatar_lower_body_3.llm
index f3c49a1568..f3c49a1568 100644..100755
--- a/indra/newview/character/avatar_lower_body_3.llm
+++ b/indra/newview/character/avatar_lower_body_3.llm
Binary files differ
diff --git a/indra/newview/character/avatar_lower_body_4.llm b/indra/newview/character/avatar_lower_body_4.llm
index e71721063e..e71721063e 100644..100755
--- a/indra/newview/character/avatar_lower_body_4.llm
+++ b/indra/newview/character/avatar_lower_body_4.llm
Binary files differ
diff --git a/indra/newview/character/avatar_skeleton.xml b/indra/newview/character/avatar_skeleton.xml
index 5e73804f2d..5e73804f2d 100644..100755
--- a/indra/newview/character/avatar_skeleton.xml
+++ b/indra/newview/character/avatar_skeleton.xml
diff --git a/indra/newview/character/avatar_skirt.llm b/indra/newview/character/avatar_skirt.llm
index 08ce3d1700..08ce3d1700 100644..100755
--- a/indra/newview/character/avatar_skirt.llm
+++ b/indra/newview/character/avatar_skirt.llm
Binary files differ
diff --git a/indra/newview/character/avatar_skirt_1.llm b/indra/newview/character/avatar_skirt_1.llm
index 88076c321f..88076c321f 100644..100755
--- a/indra/newview/character/avatar_skirt_1.llm
+++ b/indra/newview/character/avatar_skirt_1.llm
Binary files differ
diff --git a/indra/newview/character/avatar_skirt_2.llm b/indra/newview/character/avatar_skirt_2.llm
index 73b3effbc6..73b3effbc6 100644..100755
--- a/indra/newview/character/avatar_skirt_2.llm
+++ b/indra/newview/character/avatar_skirt_2.llm
Binary files differ
diff --git a/indra/newview/character/avatar_skirt_3.llm b/indra/newview/character/avatar_skirt_3.llm
index ded546fdea..ded546fdea 100644..100755
--- a/indra/newview/character/avatar_skirt_3.llm
+++ b/indra/newview/character/avatar_skirt_3.llm
Binary files differ
diff --git a/indra/newview/character/avatar_skirt_4.llm b/indra/newview/character/avatar_skirt_4.llm
index b9d5cb945e..b9d5cb945e 100644..100755
--- a/indra/newview/character/avatar_skirt_4.llm
+++ b/indra/newview/character/avatar_skirt_4.llm
Binary files differ
diff --git a/indra/newview/character/avatar_upper_body.llm b/indra/newview/character/avatar_upper_body.llm
index da7d990540..da7d990540 100644..100755
--- a/indra/newview/character/avatar_upper_body.llm
+++ b/indra/newview/character/avatar_upper_body.llm
Binary files differ
diff --git a/indra/newview/character/avatar_upper_body_1.llm b/indra/newview/character/avatar_upper_body_1.llm
index 31e104cc20..31e104cc20 100644..100755
--- a/indra/newview/character/avatar_upper_body_1.llm
+++ b/indra/newview/character/avatar_upper_body_1.llm
Binary files differ
diff --git a/indra/newview/character/avatar_upper_body_2.llm b/indra/newview/character/avatar_upper_body_2.llm
index c1f4199b9c..c1f4199b9c 100644..100755
--- a/indra/newview/character/avatar_upper_body_2.llm
+++ b/indra/newview/character/avatar_upper_body_2.llm
Binary files differ
diff --git a/indra/newview/character/avatar_upper_body_3.llm b/indra/newview/character/avatar_upper_body_3.llm
index 9e89ed8b3e..9e89ed8b3e 100644..100755
--- a/indra/newview/character/avatar_upper_body_3.llm
+++ b/indra/newview/character/avatar_upper_body_3.llm
Binary files differ
diff --git a/indra/newview/character/avatar_upper_body_4.llm b/indra/newview/character/avatar_upper_body_4.llm
index ec836d1dc3..ec836d1dc3 100644..100755
--- a/indra/newview/character/avatar_upper_body_4.llm
+++ b/indra/newview/character/avatar_upper_body_4.llm
Binary files differ
diff --git a/indra/newview/character/blush_alpha.tga b/indra/newview/character/blush_alpha.tga
index 05be7e7e3d..05be7e7e3d 100644..100755
--- a/indra/newview/character/blush_alpha.tga
+++ b/indra/newview/character/blush_alpha.tga
Binary files differ
diff --git a/indra/newview/character/body_skingrain.tga b/indra/newview/character/body_skingrain.tga
index 7264baac14..7264baac14 100644..100755
--- a/indra/newview/character/body_skingrain.tga
+++ b/indra/newview/character/body_skingrain.tga
Binary files differ
diff --git a/indra/newview/character/bodyfreckles_alpha.tga b/indra/newview/character/bodyfreckles_alpha.tga
index d30ab3d122..d30ab3d122 100644..100755
--- a/indra/newview/character/bodyfreckles_alpha.tga
+++ b/indra/newview/character/bodyfreckles_alpha.tga
Binary files differ
diff --git a/indra/newview/character/bump_face_wrinkles.tga b/indra/newview/character/bump_face_wrinkles.tga
index 54bf7a55be..54bf7a55be 100644..100755
--- a/indra/newview/character/bump_face_wrinkles.tga
+++ b/indra/newview/character/bump_face_wrinkles.tga
Binary files differ
diff --git a/indra/newview/character/bump_head_base.tga b/indra/newview/character/bump_head_base.tga
index fa3568573a..fa3568573a 100644..100755
--- a/indra/newview/character/bump_head_base.tga
+++ b/indra/newview/character/bump_head_base.tga
Binary files differ
diff --git a/indra/newview/character/bump_lowerbody_base.tga b/indra/newview/character/bump_lowerbody_base.tga
index 498ea3c721..498ea3c721 100644..100755
--- a/indra/newview/character/bump_lowerbody_base.tga
+++ b/indra/newview/character/bump_lowerbody_base.tga
Binary files differ
diff --git a/indra/newview/character/bump_pants_wrinkles.tga b/indra/newview/character/bump_pants_wrinkles.tga
index cca72415e8..cca72415e8 100644..100755
--- a/indra/newview/character/bump_pants_wrinkles.tga
+++ b/indra/newview/character/bump_pants_wrinkles.tga
Binary files differ
diff --git a/indra/newview/character/bump_shirt_wrinkles.tga b/indra/newview/character/bump_shirt_wrinkles.tga
index 9e0d757a48..9e0d757a48 100644..100755
--- a/indra/newview/character/bump_shirt_wrinkles.tga
+++ b/indra/newview/character/bump_shirt_wrinkles.tga
Binary files differ
diff --git a/indra/newview/character/bump_upperbody_base.tga b/indra/newview/character/bump_upperbody_base.tga
index e57d6352e6..e57d6352e6 100644..100755
--- a/indra/newview/character/bump_upperbody_base.tga
+++ b/indra/newview/character/bump_upperbody_base.tga
Binary files differ
diff --git a/indra/newview/character/checkerboard.tga b/indra/newview/character/checkerboard.tga
index 1950d7403d..1950d7403d 100644..100755
--- a/indra/newview/character/checkerboard.tga
+++ b/indra/newview/character/checkerboard.tga
Binary files differ
diff --git a/indra/newview/character/eyebrows_alpha.tga b/indra/newview/character/eyebrows_alpha.tga
index c363e482e1..c363e482e1 100644..100755
--- a/indra/newview/character/eyebrows_alpha.tga
+++ b/indra/newview/character/eyebrows_alpha.tga
Binary files differ
diff --git a/indra/newview/character/eyeliner_alpha.tga b/indra/newview/character/eyeliner_alpha.tga
index 1611eb3355..1611eb3355 100644..100755
--- a/indra/newview/character/eyeliner_alpha.tga
+++ b/indra/newview/character/eyeliner_alpha.tga
Binary files differ
diff --git a/indra/newview/character/eyeshadow_inner_alpha.tga b/indra/newview/character/eyeshadow_inner_alpha.tga
index 37d7919395..37d7919395 100644..100755
--- a/indra/newview/character/eyeshadow_inner_alpha.tga
+++ b/indra/newview/character/eyeshadow_inner_alpha.tga
Binary files differ
diff --git a/indra/newview/character/eyeshadow_outer_alpha.tga b/indra/newview/character/eyeshadow_outer_alpha.tga
index 00eef9d9f7..00eef9d9f7 100644..100755
--- a/indra/newview/character/eyeshadow_outer_alpha.tga
+++ b/indra/newview/character/eyeshadow_outer_alpha.tga
Binary files differ
diff --git a/indra/newview/character/eyewhite.tga b/indra/newview/character/eyewhite.tga
index a720496988..a720496988 100644..100755
--- a/indra/newview/character/eyewhite.tga
+++ b/indra/newview/character/eyewhite.tga
Binary files differ
diff --git a/indra/newview/character/facehair_chincurtains_alpha.tga b/indra/newview/character/facehair_chincurtains_alpha.tga
index b10397063c..b10397063c 100644..100755
--- a/indra/newview/character/facehair_chincurtains_alpha.tga
+++ b/indra/newview/character/facehair_chincurtains_alpha.tga
Binary files differ
diff --git a/indra/newview/character/facehair_moustache_alpha.tga b/indra/newview/character/facehair_moustache_alpha.tga
index 4068c4f2b1..4068c4f2b1 100644..100755
--- a/indra/newview/character/facehair_moustache_alpha.tga
+++ b/indra/newview/character/facehair_moustache_alpha.tga
Binary files differ
diff --git a/indra/newview/character/facehair_sideburns_alpha.tga b/indra/newview/character/facehair_sideburns_alpha.tga
index acddc2d9bd..acddc2d9bd 100644..100755
--- a/indra/newview/character/facehair_sideburns_alpha.tga
+++ b/indra/newview/character/facehair_sideburns_alpha.tga
Binary files differ
diff --git a/indra/newview/character/facehair_soulpatch_alpha.tga b/indra/newview/character/facehair_soulpatch_alpha.tga
index 687091a29f..687091a29f 100644..100755
--- a/indra/newview/character/facehair_soulpatch_alpha.tga
+++ b/indra/newview/character/facehair_soulpatch_alpha.tga
Binary files differ
diff --git a/indra/newview/character/freckles_alpha.tga b/indra/newview/character/freckles_alpha.tga
index a9a4ec0735..a9a4ec0735 100644..100755
--- a/indra/newview/character/freckles_alpha.tga
+++ b/indra/newview/character/freckles_alpha.tga
Binary files differ
diff --git a/indra/newview/character/genepool.xml b/indra/newview/character/genepool.xml
index 52300c2bab..52300c2bab 100644..100755
--- a/indra/newview/character/genepool.xml
+++ b/indra/newview/character/genepool.xml
diff --git a/indra/newview/character/glove_length_alpha.tga b/indra/newview/character/glove_length_alpha.tga
index db89ad57e7..db89ad57e7 100644..100755
--- a/indra/newview/character/glove_length_alpha.tga
+++ b/indra/newview/character/glove_length_alpha.tga
Binary files differ
diff --git a/indra/newview/character/gloves_fingers_alpha.tga b/indra/newview/character/gloves_fingers_alpha.tga
index dba2eec277..dba2eec277 100644..100755
--- a/indra/newview/character/gloves_fingers_alpha.tga
+++ b/indra/newview/character/gloves_fingers_alpha.tga
Binary files differ
diff --git a/indra/newview/character/head_alpha.tga b/indra/newview/character/head_alpha.tga
index 8164525353..8164525353 100644..100755
--- a/indra/newview/character/head_alpha.tga
+++ b/indra/newview/character/head_alpha.tga
Binary files differ
diff --git a/indra/newview/character/head_color.tga b/indra/newview/character/head_color.tga
index 74b1b3078b..74b1b3078b 100644..100755
--- a/indra/newview/character/head_color.tga
+++ b/indra/newview/character/head_color.tga
Binary files differ
diff --git a/indra/newview/character/head_hair.tga b/indra/newview/character/head_hair.tga
index 5321f35204..5321f35204 100644..100755
--- a/indra/newview/character/head_hair.tga
+++ b/indra/newview/character/head_hair.tga
Binary files differ
diff --git a/indra/newview/character/head_highlights_alpha.tga b/indra/newview/character/head_highlights_alpha.tga
index 8dc5239f97..8dc5239f97 100644..100755
--- a/indra/newview/character/head_highlights_alpha.tga
+++ b/indra/newview/character/head_highlights_alpha.tga
Binary files differ
diff --git a/indra/newview/character/head_shading_alpha.tga b/indra/newview/character/head_shading_alpha.tga
index e8ea490109..e8ea490109 100644..100755
--- a/indra/newview/character/head_shading_alpha.tga
+++ b/indra/newview/character/head_shading_alpha.tga
Binary files differ
diff --git a/indra/newview/character/head_skingrain.tga b/indra/newview/character/head_skingrain.tga
index b42dee0809..b42dee0809 100644..100755
--- a/indra/newview/character/head_skingrain.tga
+++ b/indra/newview/character/head_skingrain.tga
Binary files differ
diff --git a/indra/newview/character/jacket_length_lower_alpha.tga b/indra/newview/character/jacket_length_lower_alpha.tga
index 722bc192a8..722bc192a8 100644..100755
--- a/indra/newview/character/jacket_length_lower_alpha.tga
+++ b/indra/newview/character/jacket_length_lower_alpha.tga
Binary files differ
diff --git a/indra/newview/character/jacket_length_upper_alpha.tga b/indra/newview/character/jacket_length_upper_alpha.tga
index e9db7e7b1f..e9db7e7b1f 100644..100755
--- a/indra/newview/character/jacket_length_upper_alpha.tga
+++ b/indra/newview/character/jacket_length_upper_alpha.tga
Binary files differ
diff --git a/indra/newview/character/jacket_open_lower_alpha.tga b/indra/newview/character/jacket_open_lower_alpha.tga
index db0c2fb0e3..db0c2fb0e3 100644..100755
--- a/indra/newview/character/jacket_open_lower_alpha.tga
+++ b/indra/newview/character/jacket_open_lower_alpha.tga
Binary files differ
diff --git a/indra/newview/character/jacket_open_upper_alpha.tga b/indra/newview/character/jacket_open_upper_alpha.tga
index 71b8a0b805..71b8a0b805 100644..100755
--- a/indra/newview/character/jacket_open_upper_alpha.tga
+++ b/indra/newview/character/jacket_open_upper_alpha.tga
Binary files differ
diff --git a/indra/newview/character/lipgloss_alpha.tga b/indra/newview/character/lipgloss_alpha.tga
index 78ceecaf85..78ceecaf85 100644..100755
--- a/indra/newview/character/lipgloss_alpha.tga
+++ b/indra/newview/character/lipgloss_alpha.tga
Binary files differ
diff --git a/indra/newview/character/lips_mask.tga b/indra/newview/character/lips_mask.tga
index ae1401c006..ae1401c006 100644..100755
--- a/indra/newview/character/lips_mask.tga
+++ b/indra/newview/character/lips_mask.tga
Binary files differ
diff --git a/indra/newview/character/lipstick_alpha.tga b/indra/newview/character/lipstick_alpha.tga
index 2795f1bd40..2795f1bd40 100644..100755
--- a/indra/newview/character/lipstick_alpha.tga
+++ b/indra/newview/character/lipstick_alpha.tga
Binary files differ
diff --git a/indra/newview/character/lowerbody_color.tga b/indra/newview/character/lowerbody_color.tga
index a63aa12fca..a63aa12fca 100644..100755
--- a/indra/newview/character/lowerbody_color.tga
+++ b/indra/newview/character/lowerbody_color.tga
Binary files differ
diff --git a/indra/newview/character/lowerbody_highlights_alpha.tga b/indra/newview/character/lowerbody_highlights_alpha.tga
index ae3413ac8b..ae3413ac8b 100644..100755
--- a/indra/newview/character/lowerbody_highlights_alpha.tga
+++ b/indra/newview/character/lowerbody_highlights_alpha.tga
Binary files differ
diff --git a/indra/newview/character/lowerbody_shading_alpha.tga b/indra/newview/character/lowerbody_shading_alpha.tga
index 0242663a7d..0242663a7d 100644..100755
--- a/indra/newview/character/lowerbody_shading_alpha.tga
+++ b/indra/newview/character/lowerbody_shading_alpha.tga
Binary files differ
diff --git a/indra/newview/character/nailpolish_alpha.tga b/indra/newview/character/nailpolish_alpha.tga
index 91af762902..91af762902 100644..100755
--- a/indra/newview/character/nailpolish_alpha.tga
+++ b/indra/newview/character/nailpolish_alpha.tga
Binary files differ
diff --git a/indra/newview/character/pants_length_alpha.tga b/indra/newview/character/pants_length_alpha.tga
index 3c4f21c0f2..3c4f21c0f2 100644..100755
--- a/indra/newview/character/pants_length_alpha.tga
+++ b/indra/newview/character/pants_length_alpha.tga
Binary files differ
diff --git a/indra/newview/character/pants_waist_alpha.tga b/indra/newview/character/pants_waist_alpha.tga
index 35658c0896..35658c0896 100644..100755
--- a/indra/newview/character/pants_waist_alpha.tga
+++ b/indra/newview/character/pants_waist_alpha.tga
Binary files differ
diff --git a/indra/newview/character/rosyface_alpha.tga b/indra/newview/character/rosyface_alpha.tga
index a0c8513da2..a0c8513da2 100644..100755
--- a/indra/newview/character/rosyface_alpha.tga
+++ b/indra/newview/character/rosyface_alpha.tga
Binary files differ
diff --git a/indra/newview/character/rouge_alpha.tga b/indra/newview/character/rouge_alpha.tga
index a0c8513da2..a0c8513da2 100644..100755
--- a/indra/newview/character/rouge_alpha.tga
+++ b/indra/newview/character/rouge_alpha.tga
Binary files differ
diff --git a/indra/newview/character/shirt_bottom_alpha.tga b/indra/newview/character/shirt_bottom_alpha.tga
index 7cce03dbe0..7cce03dbe0 100644..100755
--- a/indra/newview/character/shirt_bottom_alpha.tga
+++ b/indra/newview/character/shirt_bottom_alpha.tga
Binary files differ
diff --git a/indra/newview/character/shirt_collar_alpha.tga b/indra/newview/character/shirt_collar_alpha.tga
index f55f635473..f55f635473 100644..100755
--- a/indra/newview/character/shirt_collar_alpha.tga
+++ b/indra/newview/character/shirt_collar_alpha.tga
Binary files differ
diff --git a/indra/newview/character/shirt_collar_back_alpha.tga b/indra/newview/character/shirt_collar_back_alpha.tga
index 43a6453107..43a6453107 100644..100755
--- a/indra/newview/character/shirt_collar_back_alpha.tga
+++ b/indra/newview/character/shirt_collar_back_alpha.tga
Binary files differ
diff --git a/indra/newview/character/shirt_sleeve_alpha.tga b/indra/newview/character/shirt_sleeve_alpha.tga
index e3b18f4fc6..e3b18f4fc6 100644..100755
--- a/indra/newview/character/shirt_sleeve_alpha.tga
+++ b/indra/newview/character/shirt_sleeve_alpha.tga
Binary files differ
diff --git a/indra/newview/character/shoe_height_alpha.tga b/indra/newview/character/shoe_height_alpha.tga
index d08dd750f3..d08dd750f3 100644..100755
--- a/indra/newview/character/shoe_height_alpha.tga
+++ b/indra/newview/character/shoe_height_alpha.tga
Binary files differ
diff --git a/indra/newview/character/skirt_length_alpha.tga b/indra/newview/character/skirt_length_alpha.tga
index c86799469d..c86799469d 100644..100755
--- a/indra/newview/character/skirt_length_alpha.tga
+++ b/indra/newview/character/skirt_length_alpha.tga
Binary files differ
diff --git a/indra/newview/character/skirt_slit_back_alpha.tga b/indra/newview/character/skirt_slit_back_alpha.tga
index 0e49688b14..0e49688b14 100644..100755
--- a/indra/newview/character/skirt_slit_back_alpha.tga
+++ b/indra/newview/character/skirt_slit_back_alpha.tga
Binary files differ
diff --git a/indra/newview/character/skirt_slit_front_alpha.tga b/indra/newview/character/skirt_slit_front_alpha.tga
index 888bbf71a1..888bbf71a1 100644..100755
--- a/indra/newview/character/skirt_slit_front_alpha.tga
+++ b/indra/newview/character/skirt_slit_front_alpha.tga
Binary files differ
diff --git a/indra/newview/character/skirt_slit_left_alpha.tga b/indra/newview/character/skirt_slit_left_alpha.tga
index 210feac1ea..210feac1ea 100644..100755
--- a/indra/newview/character/skirt_slit_left_alpha.tga
+++ b/indra/newview/character/skirt_slit_left_alpha.tga
Binary files differ
diff --git a/indra/newview/character/skirt_slit_right_alpha.tga b/indra/newview/character/skirt_slit_right_alpha.tga
index ce11c64bf6..ce11c64bf6 100644..100755
--- a/indra/newview/character/skirt_slit_right_alpha.tga
+++ b/indra/newview/character/skirt_slit_right_alpha.tga
Binary files differ
diff --git a/indra/newview/character/underpants_trial_female.tga b/indra/newview/character/underpants_trial_female.tga
index 96bf732351..96bf732351 100644..100755
--- a/indra/newview/character/underpants_trial_female.tga
+++ b/indra/newview/character/underpants_trial_female.tga
Binary files differ
diff --git a/indra/newview/character/underpants_trial_male.tga b/indra/newview/character/underpants_trial_male.tga
index 095695ca1c..095695ca1c 100644..100755
--- a/indra/newview/character/underpants_trial_male.tga
+++ b/indra/newview/character/underpants_trial_male.tga
Binary files differ
diff --git a/indra/newview/character/undershirt_trial_female.tga b/indra/newview/character/undershirt_trial_female.tga
index e17a309531..e17a309531 100644..100755
--- a/indra/newview/character/undershirt_trial_female.tga
+++ b/indra/newview/character/undershirt_trial_female.tga
Binary files differ
diff --git a/indra/newview/character/upperbody_color.tga b/indra/newview/character/upperbody_color.tga
index 85fcc41142..85fcc41142 100644..100755
--- a/indra/newview/character/upperbody_color.tga
+++ b/indra/newview/character/upperbody_color.tga
Binary files differ
diff --git a/indra/newview/character/upperbody_highlights_alpha.tga b/indra/newview/character/upperbody_highlights_alpha.tga
index 2d8102b583..2d8102b583 100644..100755
--- a/indra/newview/character/upperbody_highlights_alpha.tga
+++ b/indra/newview/character/upperbody_highlights_alpha.tga
Binary files differ
diff --git a/indra/newview/character/upperbody_shading_alpha.tga b/indra/newview/character/upperbody_shading_alpha.tga
index b420506b3e..b420506b3e 100644..100755
--- a/indra/newview/character/upperbody_shading_alpha.tga
+++ b/indra/newview/character/upperbody_shading_alpha.tga
Binary files differ
diff --git a/indra/newview/character/upperbodyfreckles_alpha.tga b/indra/newview/character/upperbodyfreckles_alpha.tga
index 76c7ce8849..76c7ce8849 100644..100755
--- a/indra/newview/character/upperbodyfreckles_alpha.tga
+++ b/indra/newview/character/upperbodyfreckles_alpha.tga
Binary files differ
diff --git a/indra/newview/cursors_mac/UI_CURSOR_ARROW.tif b/indra/newview/cursors_mac/UI_CURSOR_ARROW.tif
index a20893b1ee..a20893b1ee 100644..100755
--- a/indra/newview/cursors_mac/UI_CURSOR_ARROW.tif
+++ b/indra/newview/cursors_mac/UI_CURSOR_ARROW.tif
Binary files differ
diff --git a/indra/newview/cursors_mac/UI_CURSOR_ARROWDRAG.tif b/indra/newview/cursors_mac/UI_CURSOR_ARROWDRAG.tif
index ab84bfbcc5..ab84bfbcc5 100644..100755
--- a/indra/newview/cursors_mac/UI_CURSOR_ARROWDRAG.tif
+++ b/indra/newview/cursors_mac/UI_CURSOR_ARROWDRAG.tif
Binary files differ
diff --git a/indra/newview/cursors_mac/UI_CURSOR_ARROWLOCKED.tif b/indra/newview/cursors_mac/UI_CURSOR_ARROWLOCKED.tif
index 400ae42943..400ae42943 100644..100755
--- a/indra/newview/cursors_mac/UI_CURSOR_ARROWLOCKED.tif
+++ b/indra/newview/cursors_mac/UI_CURSOR_ARROWLOCKED.tif
Binary files differ
diff --git a/indra/newview/cursors_mac/UI_CURSOR_GRABLOCKED.tif b/indra/newview/cursors_mac/UI_CURSOR_GRABLOCKED.tif
index 1cae801ee3..1cae801ee3 100644..100755
--- a/indra/newview/cursors_mac/UI_CURSOR_GRABLOCKED.tif
+++ b/indra/newview/cursors_mac/UI_CURSOR_GRABLOCKED.tif
Binary files differ
diff --git a/indra/newview/cursors_mac/UI_CURSOR_NO.tif b/indra/newview/cursors_mac/UI_CURSOR_NO.tif
index bc4a7a75e2..bc4a7a75e2 100644..100755
--- a/indra/newview/cursors_mac/UI_CURSOR_NO.tif
+++ b/indra/newview/cursors_mac/UI_CURSOR_NO.tif
Binary files differ
diff --git a/indra/newview/cursors_mac/UI_CURSOR_NOLOCKED.tif b/indra/newview/cursors_mac/UI_CURSOR_NOLOCKED.tif
index 62332fc956..62332fc956 100644..100755
--- a/indra/newview/cursors_mac/UI_CURSOR_NOLOCKED.tif
+++ b/indra/newview/cursors_mac/UI_CURSOR_NOLOCKED.tif
Binary files differ
diff --git a/indra/newview/cursors_mac/UI_CURSOR_PATHFINDING.tif b/indra/newview/cursors_mac/UI_CURSOR_PATHFINDING.tif
new file mode 100755
index 0000000000..ba6f30fa0e
--- /dev/null
+++ b/indra/newview/cursors_mac/UI_CURSOR_PATHFINDING.tif
Binary files differ
diff --git a/indra/newview/cursors_mac/UI_CURSOR_PATHFINDING_END.tif b/indra/newview/cursors_mac/UI_CURSOR_PATHFINDING_END.tif
new file mode 100755
index 0000000000..830d5692fd
--- /dev/null
+++ b/indra/newview/cursors_mac/UI_CURSOR_PATHFINDING_END.tif
Binary files differ
diff --git a/indra/newview/cursors_mac/UI_CURSOR_PATHFINDING_END_ADD.tif b/indra/newview/cursors_mac/UI_CURSOR_PATHFINDING_END_ADD.tif
new file mode 100755
index 0000000000..e05284214a
--- /dev/null
+++ b/indra/newview/cursors_mac/UI_CURSOR_PATHFINDING_END_ADD.tif
Binary files differ
diff --git a/indra/newview/cursors_mac/UI_CURSOR_PATHFINDING_START.tif b/indra/newview/cursors_mac/UI_CURSOR_PATHFINDING_START.tif
new file mode 100755
index 0000000000..c4822adf64
--- /dev/null
+++ b/indra/newview/cursors_mac/UI_CURSOR_PATHFINDING_START.tif
Binary files differ
diff --git a/indra/newview/cursors_mac/UI_CURSOR_PATHFINDING_START_ADD.tif b/indra/newview/cursors_mac/UI_CURSOR_PATHFINDING_START_ADD.tif
new file mode 100755
index 0000000000..5166af6e05
--- /dev/null
+++ b/indra/newview/cursors_mac/UI_CURSOR_PATHFINDING_START_ADD.tif
Binary files differ
diff --git a/indra/newview/cursors_mac/UI_CURSOR_SIZENESW.tif b/indra/newview/cursors_mac/UI_CURSOR_SIZENESW.tif
index de2c28bbbc..de2c28bbbc 100644..100755
--- a/indra/newview/cursors_mac/UI_CURSOR_SIZENESW.tif
+++ b/indra/newview/cursors_mac/UI_CURSOR_SIZENESW.tif
Binary files differ
diff --git a/indra/newview/cursors_mac/UI_CURSOR_SIZENS.tif b/indra/newview/cursors_mac/UI_CURSOR_SIZENS.tif
index 2676c78a4f..2676c78a4f 100644..100755
--- a/indra/newview/cursors_mac/UI_CURSOR_SIZENS.tif
+++ b/indra/newview/cursors_mac/UI_CURSOR_SIZENS.tif
Binary files differ
diff --git a/indra/newview/cursors_mac/UI_CURSOR_SIZENWSE.tif b/indra/newview/cursors_mac/UI_CURSOR_SIZENWSE.tif
index 33df3392f3..33df3392f3 100644..100755
--- a/indra/newview/cursors_mac/UI_CURSOR_SIZENWSE.tif
+++ b/indra/newview/cursors_mac/UI_CURSOR_SIZENWSE.tif
Binary files differ
diff --git a/indra/newview/cursors_mac/UI_CURSOR_SIZEWE.tif b/indra/newview/cursors_mac/UI_CURSOR_SIZEWE.tif
index 8952054c23..8952054c23 100644..100755
--- a/indra/newview/cursors_mac/UI_CURSOR_SIZEWE.tif
+++ b/indra/newview/cursors_mac/UI_CURSOR_SIZEWE.tif
Binary files differ
diff --git a/indra/newview/cursors_mac/UI_CURSOR_TOOLBUY.tif b/indra/newview/cursors_mac/UI_CURSOR_TOOLBUY.tif
index f366026c33..f366026c33 100644..100755
--- a/indra/newview/cursors_mac/UI_CURSOR_TOOLBUY.tif
+++ b/indra/newview/cursors_mac/UI_CURSOR_TOOLBUY.tif
Binary files differ
diff --git a/indra/newview/cursors_mac/UI_CURSOR_TOOLCAMERA.tif b/indra/newview/cursors_mac/UI_CURSOR_TOOLCAMERA.tif
index bbf415a2f1..bbf415a2f1 100644..100755
--- a/indra/newview/cursors_mac/UI_CURSOR_TOOLCAMERA.tif
+++ b/indra/newview/cursors_mac/UI_CURSOR_TOOLCAMERA.tif
Binary files differ
diff --git a/indra/newview/cursors_mac/UI_CURSOR_TOOLCREATE.tif b/indra/newview/cursors_mac/UI_CURSOR_TOOLCREATE.tif
index 2ab71c8af6..2ab71c8af6 100644..100755
--- a/indra/newview/cursors_mac/UI_CURSOR_TOOLCREATE.tif
+++ b/indra/newview/cursors_mac/UI_CURSOR_TOOLCREATE.tif
Binary files differ
diff --git a/indra/newview/cursors_mac/UI_CURSOR_TOOLFOCUS.tif b/indra/newview/cursors_mac/UI_CURSOR_TOOLFOCUS.tif
index db4ca17de9..db4ca17de9 100644..100755
--- a/indra/newview/cursors_mac/UI_CURSOR_TOOLFOCUS.tif
+++ b/indra/newview/cursors_mac/UI_CURSOR_TOOLFOCUS.tif
Binary files differ
diff --git a/indra/newview/cursors_mac/UI_CURSOR_TOOLGRAB.tif b/indra/newview/cursors_mac/UI_CURSOR_TOOLGRAB.tif
index 366630d6b2..366630d6b2 100644..100755
--- a/indra/newview/cursors_mac/UI_CURSOR_TOOLGRAB.tif
+++ b/indra/newview/cursors_mac/UI_CURSOR_TOOLGRAB.tif
Binary files differ
diff --git a/indra/newview/cursors_mac/UI_CURSOR_TOOLLAND.tif b/indra/newview/cursors_mac/UI_CURSOR_TOOLLAND.tif
index ad5a9ca06d..ad5a9ca06d 100644..100755
--- a/indra/newview/cursors_mac/UI_CURSOR_TOOLLAND.tif
+++ b/indra/newview/cursors_mac/UI_CURSOR_TOOLLAND.tif
Binary files differ
diff --git a/indra/newview/cursors_mac/UI_CURSOR_TOOLMEDIAOPEN.tif b/indra/newview/cursors_mac/UI_CURSOR_TOOLMEDIAOPEN.tif
index 7c0bcfcbc5..7c0bcfcbc5 100644..100755
--- a/indra/newview/cursors_mac/UI_CURSOR_TOOLMEDIAOPEN.tif
+++ b/indra/newview/cursors_mac/UI_CURSOR_TOOLMEDIAOPEN.tif
Binary files differ
diff --git a/indra/newview/cursors_mac/UI_CURSOR_TOOLOPEN.tif b/indra/newview/cursors_mac/UI_CURSOR_TOOLOPEN.tif
index e9e6a20cd9..e9e6a20cd9 100644..100755
--- a/indra/newview/cursors_mac/UI_CURSOR_TOOLOPEN.tif
+++ b/indra/newview/cursors_mac/UI_CURSOR_TOOLOPEN.tif
Binary files differ
diff --git a/indra/newview/cursors_mac/UI_CURSOR_TOOLPAN.tif b/indra/newview/cursors_mac/UI_CURSOR_TOOLPAN.tif
index 0a89f9bd91..0a89f9bd91 100644..100755
--- a/indra/newview/cursors_mac/UI_CURSOR_TOOLPAN.tif
+++ b/indra/newview/cursors_mac/UI_CURSOR_TOOLPAN.tif
Binary files differ
diff --git a/indra/newview/cursors_mac/UI_CURSOR_TOOLPAUSE.tif b/indra/newview/cursors_mac/UI_CURSOR_TOOLPAUSE.tif
index 3431887aff..3431887aff 100644..100755
--- a/indra/newview/cursors_mac/UI_CURSOR_TOOLPAUSE.tif
+++ b/indra/newview/cursors_mac/UI_CURSOR_TOOLPAUSE.tif
Binary files differ
diff --git a/indra/newview/cursors_mac/UI_CURSOR_TOOLPICKOBJECT3.tif b/indra/newview/cursors_mac/UI_CURSOR_TOOLPICKOBJECT3.tif
index 55317f19aa..55317f19aa 100644..100755
--- a/indra/newview/cursors_mac/UI_CURSOR_TOOLPICKOBJECT3.tif
+++ b/indra/newview/cursors_mac/UI_CURSOR_TOOLPICKOBJECT3.tif
Binary files differ
diff --git a/indra/newview/cursors_mac/UI_CURSOR_TOOLPLAY.tif b/indra/newview/cursors_mac/UI_CURSOR_TOOLPLAY.tif
index 796bbb78e3..796bbb78e3 100644..100755
--- a/indra/newview/cursors_mac/UI_CURSOR_TOOLPLAY.tif
+++ b/indra/newview/cursors_mac/UI_CURSOR_TOOLPLAY.tif
Binary files differ
diff --git a/indra/newview/cursors_mac/UI_CURSOR_TOOLROTATE.tif b/indra/newview/cursors_mac/UI_CURSOR_TOOLROTATE.tif
index 98881561cb..98881561cb 100644..100755
--- a/indra/newview/cursors_mac/UI_CURSOR_TOOLROTATE.tif
+++ b/indra/newview/cursors_mac/UI_CURSOR_TOOLROTATE.tif
Binary files differ
diff --git a/indra/newview/cursors_mac/UI_CURSOR_TOOLSCALE.tif b/indra/newview/cursors_mac/UI_CURSOR_TOOLSCALE.tif
index 316dd38c69..316dd38c69 100644..100755
--- a/indra/newview/cursors_mac/UI_CURSOR_TOOLSCALE.tif
+++ b/indra/newview/cursors_mac/UI_CURSOR_TOOLSCALE.tif
Binary files differ
diff --git a/indra/newview/cursors_mac/UI_CURSOR_TOOLSIT.tif b/indra/newview/cursors_mac/UI_CURSOR_TOOLSIT.tif
index bea3d9d442..bea3d9d442 100644..100755
--- a/indra/newview/cursors_mac/UI_CURSOR_TOOLSIT.tif
+++ b/indra/newview/cursors_mac/UI_CURSOR_TOOLSIT.tif
Binary files differ
diff --git a/indra/newview/cursors_mac/UI_CURSOR_TOOLTRANSLATE.tif b/indra/newview/cursors_mac/UI_CURSOR_TOOLTRANSLATE.tif
index 0cd06379e8..0cd06379e8 100644..100755
--- a/indra/newview/cursors_mac/UI_CURSOR_TOOLTRANSLATE.tif
+++ b/indra/newview/cursors_mac/UI_CURSOR_TOOLTRANSLATE.tif
Binary files differ
diff --git a/indra/newview/cursors_mac/UI_CURSOR_TOOLZOOMIN.tif b/indra/newview/cursors_mac/UI_CURSOR_TOOLZOOMIN.tif
index 65f3b6de28..65f3b6de28 100644..100755
--- a/indra/newview/cursors_mac/UI_CURSOR_TOOLZOOMIN.tif
+++ b/indra/newview/cursors_mac/UI_CURSOR_TOOLZOOMIN.tif
Binary files differ
diff --git a/indra/newview/cursors_mac/UI_CURSOR_WORKING.tif b/indra/newview/cursors_mac/UI_CURSOR_WORKING.tif
index c49f16a1c4..c49f16a1c4 100644..100755
--- a/indra/newview/cursors_mac/UI_CURSOR_WORKING.tif
+++ b/indra/newview/cursors_mac/UI_CURSOR_WORKING.tif
Binary files differ
diff --git a/indra/newview/da.lproj/language.txt b/indra/newview/da.lproj/language.txt
index 316d25d903..316d25d903 100644..100755
--- a/indra/newview/da.lproj/language.txt
+++ b/indra/newview/da.lproj/language.txt
diff --git a/indra/newview/es.lproj/language.txt b/indra/newview/es.lproj/language.txt
index 6c4381495c..6c4381495c 100644..100755
--- a/indra/newview/es.lproj/language.txt
+++ b/indra/newview/es.lproj/language.txt
diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt
index 76bb2b0976..4030324ecb 100644..100755
--- a/indra/newview/featuretable.txt
+++ b/indra/newview/featuretable.txt
@@ -1,4 +1,4 @@
-version 32
+version 33
// The version number above should be implemented IF AND ONLY IF some
// change has been made that is sufficiently important to justify
// resetting the graphics preferences of all users to the recommended
@@ -61,6 +61,7 @@ WLSkyDetail 1 128
Disregard128DefaultDrawDistance 1 1
Disregard96DefaultDrawDistance 1 1
RenderTextureMemoryMultiple 1 1.0
+RenderCompressTextures 1 1
RenderShaderLightingMaxLevel 1 3
RenderDeferred 1 1
RenderDeferredSSAO 1 1
@@ -72,9 +73,9 @@ RenderMaxTextureIndex 1 16
//
-// Low Graphics Settings
+// Low Graphics Settings (fixed function)
//
-list Low
+list LowFixedFunction
RenderAnisotropic 1 0
RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 0
@@ -96,16 +97,48 @@ RenderUseImpostors 1 1
RenderVolumeLODFactor 1 1.125
VertexShaderEnable 1 0
WindLightUseAtmosShaders 1 0
+RenderDeferred 1 0
+RenderDeferredSSAO 1 0
+RenderShadowDetail 1 0
WLSkyDetail 1 48
+RenderFSAASamples 1 0
+
+
+//
+// Low Graphics Settings
+//
+list Low
+RenderAnisotropic 1 0
+RenderAvatarCloth 1 0
+RenderAvatarLODFactor 1 0
+RenderAvatarPhysicsLODFactor 1 0
+RenderAvatarMaxVisible 1 3
+RenderAvatarVP 1 0
+RenderFarClip 1 64
+RenderFlexTimeFactor 1 0
+RenderGlowResolutionPow 1 8
+RenderMaxPartCount 1 0
+RenderObjectBump 1 0
+RenderLocalLights 1 0
+RenderReflectionDetail 1 0
+RenderTerrainDetail 1 0
+RenderTerrainLODFactor 1 1
+RenderTransparentWater 1 0
+RenderTreeLODFactor 1 0
+RenderUseImpostors 1 1
+RenderVolumeLODFactor 1 1.125
+VertexShaderEnable 1 1
+WindLightUseAtmosShaders 1 0
RenderDeferred 1 0
RenderDeferredSSAO 1 0
RenderShadowDetail 1 0
+WLSkyDetail 1 48
RenderFSAASamples 1 0
//
-// Mid Graphics Settings
+// Medium Low Graphics Settings
//
-list Mid
+list LowMid
RenderAnisotropic 1 0
RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 0.5
@@ -126,16 +159,16 @@ RenderUseImpostors 1 1
RenderVolumeLODFactor 1 1.125
VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 0
-WLSkyDetail 1 48
RenderDeferred 1 0
RenderDeferredSSAO 1 0
RenderShadowDetail 1 0
+WLSkyDetail 1 48
RenderFSAASamples 1 0
//
-// High Graphics Settings (purty)
+// Medium Graphics Settings (standard)
//
-list High
+list Mid
RenderAnisotropic 1 1
RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 1.0
@@ -156,13 +189,104 @@ RenderUseImpostors 1 1
RenderVolumeLODFactor 1 1.125
VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 1
-WLSkyDetail 1 48
RenderDeferred 1 0
RenderDeferredSSAO 1 0
RenderShadowDetail 1 0
+WLSkyDetail 1 48
+RenderFSAASamples 1 2
+
+//
+// Medium High Graphics Settings (deferred enabled)
+//
+list MidHigh
+RenderAnisotropic 1 1
+RenderAvatarCloth 1 0
+RenderAvatarLODFactor 1 1.0
+RenderAvatarPhysicsLODFactor 1 1.0
+RenderAvatarVP 1 1
+RenderFarClip 1 128
+RenderFlexTimeFactor 1 1.0
+RenderGlowResolutionPow 1 9
+RenderMaxPartCount 1 4096
+RenderObjectBump 1 1
+RenderLocalLights 1 1
+RenderReflectionDetail 1 0
+RenderTerrainDetail 1 1
+RenderTerrainLODFactor 1 2.0
+RenderTransparentWater 1 1
+RenderTreeLODFactor 1 0.5
+RenderUseImpostors 1 1
+RenderVolumeLODFactor 1 1.125
+VertexShaderEnable 1 1
+WindLightUseAtmosShaders 1 1
+RenderDeferred 1 1
+RenderDeferredSSAO 1 0
+RenderShadowDetail 1 0
+WLSkyDetail 1 48
RenderFSAASamples 1 2
//
+// High Graphics Settings (deferred + SSAO)
+//
+list High
+RenderAnisotropic 1 1
+RenderAvatarCloth 1 0
+RenderAvatarLODFactor 1 1.0
+RenderAvatarPhysicsLODFactor 1 1.0
+RenderAvatarVP 1 1
+RenderFarClip 1 128
+RenderFlexTimeFactor 1 1.0
+RenderGlowResolutionPow 1 9
+RenderMaxPartCount 1 4096
+RenderObjectBump 1 1
+RenderLocalLights 1 1
+RenderReflectionDetail 1 0
+RenderTerrainDetail 1 1
+RenderTerrainLODFactor 1 2.0
+RenderTransparentWater 1 1
+RenderTreeLODFactor 1 0.5
+RenderUseImpostors 1 1
+RenderVolumeLODFactor 1 1.125
+VertexShaderEnable 1 1
+WindLightUseAtmosShaders 1 1
+RenderDeferred 1 1
+RenderDeferredSSAO 1 1
+RenderShadowDetail 1 0
+WLSkyDetail 1 48
+RenderFSAASamples 1 2
+
+//
+// High Ultra Graphics Settings (deferred + SSAO + shadows)
+//
+list HighUltra
+RenderAnisotropic 1 1
+RenderAvatarCloth 1 0
+RenderAvatarLODFactor 1 1.0
+RenderAvatarPhysicsLODFactor 1 1.0
+RenderAvatarVP 1 1
+RenderFarClip 1 128
+RenderFlexTimeFactor 1 1.0
+RenderGlowResolutionPow 1 9
+RenderMaxPartCount 1 4096
+RenderObjectBump 1 1
+RenderLocalLights 1 1
+RenderReflectionDetail 1 0
+RenderTerrainDetail 1 1
+RenderTerrainLODFactor 1 2.0
+RenderTransparentWater 1 1
+RenderTreeLODFactor 1 0.5
+RenderUseImpostors 1 1
+RenderVolumeLODFactor 1 1.125
+VertexShaderEnable 1 1
+WindLightUseAtmosShaders 1 1
+RenderDeferred 1 1
+RenderDeferredSSAO 1 1
+RenderShadowDetail 1 2
+WLSkyDetail 1 48
+RenderFSAASamples 1 2
+
+
+//
// Ultra graphics (REALLY PURTY!)
//
list Ultra
@@ -197,6 +321,9 @@ RenderFSAASamples 1 2
//
list Unknown
RenderVBOEnable 1 0
+RenderShadowDetail 1 0
+RenderDeferred 1 0
+RenderDeferredSSAO 1 0
//
// Class 0 Hardware (just old)
@@ -211,18 +338,36 @@ list Class1
RenderVBOEnable 1 1
//
-// Class 2 Hardware (make it purty)
+// Class 2 Hardware
//
list Class2
RenderVBOEnable 1 1
//
-// Class 3 Hardware (make it purty)
+// Class 3 Hardware
//
list Class3
RenderVBOEnable 1 1
//
+// Class 4 Hardware
+//
+list Class4
+RenderVBOEnable 1 1
+
+//
+// Class 5 Hardware
+//
+list Class5
+RenderVBOEnable 1 1
+
+//
+// VRAM > 512MB
+//
+list VRAMGT512
+RenderCompressTextures 1 0
+
+//
// No Pixel Shaders available
//
list NoPixelShaders
@@ -302,6 +447,7 @@ RenderMaxTextureIndex 1 1
list Intel
RenderAnisotropic 1 0
RenderVBOEnable 1 0
+RenderFSAASamples 1 0
list GeForce2
RenderAnisotropic 1 0
@@ -480,6 +626,7 @@ Disregard128DefaultDrawDistance 1 0
list ATIOldDriver
RenderAvatarVP 0 0
RenderAvatarCloth 0 0
+RenderVBOEnable 1 0
// ATI cards generally perform better when not using VBOs for streaming data
diff --git a/indra/newview/featuretable_linux.txt b/indra/newview/featuretable_linux.txt
index 5e217e000a..6d5284c602 100644..100755
--- a/indra/newview/featuretable_linux.txt
+++ b/indra/newview/featuretable_linux.txt
@@ -1,4 +1,4 @@
-version 27
+version 28
// The version number above should be implemented IF AND ONLY IF some
// change has been made that is sufficiently important to justify
// resetting the graphics preferences of all users to the recommended
@@ -61,6 +61,7 @@ WLSkyDetail 1 128
Disregard128DefaultDrawDistance 1 1
Disregard96DefaultDrawDistance 1 1
RenderTextureMemoryMultiple 1 1.0
+RenderCompressTextures 1 1
RenderShaderLightingMaxLevel 1 3
RenderDeferred 1 1
RenderDeferredSSAO 1 1
@@ -69,6 +70,37 @@ RenderFSAASamples 1 16
RenderMaxTextureIndex 1 16
//
+// Low Graphics Settings (fixed function)
+//
+list LowFixedFunction
+RenderAnisotropic 1 0
+RenderAvatarCloth 1 0
+RenderAvatarLODFactor 1 0
+RenderAvatarPhysicsLODFactor 1 0
+RenderAvatarMaxVisible 1 3
+RenderAvatarVP 1 0
+RenderFarClip 1 64
+RenderFlexTimeFactor 1 0
+RenderGlowResolutionPow 1 8
+RenderLocalLights 1 0
+RenderMaxPartCount 1 0
+RenderObjectBump 1 0
+RenderReflectionDetail 1 0
+RenderTerrainDetail 1 0
+RenderTerrainLODFactor 1 1
+RenderTransparentWater 1 0
+RenderTreeLODFactor 1 0
+RenderUseImpostors 1 1
+RenderVolumeLODFactor 1 0.5
+VertexShaderEnable 1 1
+WindLightUseAtmosShaders 1 0
+RenderDeferred 1 0
+RenderDeferredSSAO 1 0
+RenderShadowDetail 1 0
+WLSkyDetail 1 48
+RenderFSAASamples 1 0
+
+//
// Low Graphics Settings
//
list Low
@@ -93,16 +125,16 @@ RenderUseImpostors 1 1
RenderVolumeLODFactor 1 0.5
VertexShaderEnable 1 0
WindLightUseAtmosShaders 1 0
-WLSkyDetail 1 48
RenderDeferred 1 0
RenderDeferredSSAO 1 0
RenderShadowDetail 1 0
+WLSkyDetail 1 48
RenderFSAASamples 1 0
//
-// Mid Graphics Settings
+// Medium Low Graphics Settings
//
-list Mid
+list LowMid
RenderAnisotropic 1 0
RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 0.5
@@ -111,9 +143,9 @@ RenderAvatarVP 1 1
RenderFarClip 1 96
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 8
-RenderLocalLights 1 1
RenderMaxPartCount 1 2048
RenderObjectBump 1 1
+RenderLocalLights 1 1
RenderReflectionDetail 1 0
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 1.0
@@ -123,16 +155,16 @@ RenderUseImpostors 1 1
RenderVolumeLODFactor 1 1.125
VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 0
-WLSkyDetail 1 48
RenderDeferred 1 0
RenderDeferredSSAO 1 0
RenderShadowDetail 1 0
+WLSkyDetail 1 48
RenderFSAASamples 1 0
//
-// High Graphics Settings (purty)
+// Medium Graphics Settings (standard)
//
-list High
+list Mid
RenderAnisotropic 1 1
RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 1.0
@@ -141,9 +173,9 @@ RenderAvatarVP 1 1
RenderFarClip 1 128
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
-RenderLocalLights 1 1
RenderMaxPartCount 1 4096
RenderObjectBump 1 1
+RenderLocalLights 1 1
RenderReflectionDetail 1 0
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
@@ -153,10 +185,100 @@ RenderUseImpostors 1 1
RenderVolumeLODFactor 1 1.125
VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 1
-WLSkyDetail 1 48
RenderDeferred 1 0
RenderDeferredSSAO 1 0
RenderShadowDetail 1 0
+WLSkyDetail 1 48
+RenderFSAASamples 1 2
+
+//
+// Medium High Graphics Settings (deferred enabled)
+//
+list MidHigh
+RenderAnisotropic 1 1
+RenderAvatarCloth 1 0
+RenderAvatarLODFactor 1 1.0
+RenderAvatarPhysicsLODFactor 1 1.0
+RenderAvatarVP 1 1
+RenderFarClip 1 128
+RenderFlexTimeFactor 1 1.0
+RenderGlowResolutionPow 1 9
+RenderMaxPartCount 1 4096
+RenderObjectBump 1 1
+RenderLocalLights 1 1
+RenderReflectionDetail 1 0
+RenderTerrainDetail 1 1
+RenderTerrainLODFactor 1 2.0
+RenderTransparentWater 1 1
+RenderTreeLODFactor 1 0.5
+RenderUseImpostors 1 1
+RenderVolumeLODFactor 1 1.125
+VertexShaderEnable 1 1
+WindLightUseAtmosShaders 1 1
+RenderDeferred 1 1
+RenderDeferredSSAO 1 0
+RenderShadowDetail 1 0
+WLSkyDetail 1 48
+RenderFSAASamples 1 2
+
+//
+// High Graphics Settings (deferred + SSAO)
+//
+list High
+RenderAnisotropic 1 1
+RenderAvatarCloth 1 0
+RenderAvatarLODFactor 1 1.0
+RenderAvatarPhysicsLODFactor 1 1.0
+RenderAvatarVP 1 1
+RenderFarClip 1 128
+RenderFlexTimeFactor 1 1.0
+RenderGlowResolutionPow 1 9
+RenderMaxPartCount 1 4096
+RenderObjectBump 1 1
+RenderLocalLights 1 1
+RenderReflectionDetail 1 0
+RenderTerrainDetail 1 1
+RenderTerrainLODFactor 1 2.0
+RenderTransparentWater 1 1
+RenderTreeLODFactor 1 0.5
+RenderUseImpostors 1 1
+RenderVolumeLODFactor 1 1.125
+VertexShaderEnable 1 1
+WindLightUseAtmosShaders 1 1
+RenderDeferred 1 1
+RenderDeferredSSAO 1 1
+RenderShadowDetail 1 0
+WLSkyDetail 1 48
+RenderFSAASamples 1 2
+
+//
+// High Ultra Graphics Settings (deferred + SSAO + shadows)
+//
+list HighUltra
+RenderAnisotropic 1 1
+RenderAvatarCloth 1 0
+RenderAvatarLODFactor 1 1.0
+RenderAvatarPhysicsLODFactor 1 1.0
+RenderAvatarVP 1 1
+RenderFarClip 1 128
+RenderFlexTimeFactor 1 1.0
+RenderGlowResolutionPow 1 9
+RenderMaxPartCount 1 4096
+RenderObjectBump 1 1
+RenderLocalLights 1 1
+RenderReflectionDetail 1 0
+RenderTerrainDetail 1 1
+RenderTerrainLODFactor 1 2.0
+RenderTransparentWater 1 1
+RenderTreeLODFactor 1 0.5
+RenderUseImpostors 1 1
+RenderVolumeLODFactor 1 1.125
+VertexShaderEnable 1 1
+WindLightUseAtmosShaders 1 1
+RenderDeferred 1 1
+RenderDeferredSSAO 1 1
+RenderShadowDetail 1 2
+WLSkyDetail 1 48
RenderFSAASamples 1 2
//
@@ -194,6 +316,9 @@ RenderFSAASamples 1 2
//
list Unknown
RenderVBOEnable 1 0
+RenderShadowDetail 1 0
+RenderDeferred 1 0
+RenderDeferredSSAO 1 0
//
// Class 0 Hardware (just old)
@@ -208,18 +333,36 @@ list Class1
RenderVBOEnable 1 1
//
-// Class 2 Hardware (make it purty)
+// Class 2 Hardware
//
list Class2
RenderVBOEnable 1 1
//
-// Class 3 Hardware (make it purty)
+// Class 3 Hardware
//
list Class3
RenderVBOEnable 1 1
//
+// Class 4 Hardware
+//
+list Class4
+RenderVBOEnable 1 1
+
+//
+// Class 5 Hardware
+//
+list Class5
+RenderVBOEnable 1 1
+
+//
+// VRAM > 512MB
+//
+list VRAMGT512
+RenderCompressTextures 1 0
+
+//
// No Pixel Shaders available
//
list NoPixelShaders
@@ -291,10 +434,15 @@ RenderObjectBump 0 0
list OpenGLPre15
RenderVBOEnable 1 0
+list OpenGLPre30
+RenderDeferred 0 0
+RenderMaxTextureIndex 1 1
+
list Intel
RenderAnisotropic 1 0
// Avoid some Intel crashes on Linux
RenderCubeMap 0 0
+RenderFSAASamples 1 0
list GeForce2
RenderAnisotropic 1 0
diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt
index 915a012a39..0bdd425504 100644..100755
--- a/indra/newview/featuretable_mac.txt
+++ b/indra/newview/featuretable_mac.txt
@@ -1,4 +1,4 @@
-version 32
+version 35
// The version number above should be implemented IF AND ONLY IF some
// change has been made that is sufficiently important to justify
// resetting the graphics preferences of all users to the recommended
@@ -61,6 +61,7 @@ WLSkyDetail 1 128
Disregard128DefaultDrawDistance 1 1
Disregard96DefaultDrawDistance 1 1
RenderTextureMemoryMultiple 1 0.5
+RenderCompressTextures 1 1
RenderShaderLightingMaxLevel 1 3
RenderDeferred 1 1
RenderDeferredSSAO 1 1
@@ -71,9 +72,9 @@ RenderFSAASamples 1 16
RenderMaxTextureIndex 1 16
//
-// Low Graphics Settings
+// Low Graphics Settings (fixed function)
//
-list Low
+list LowFixedFunction
RenderAnisotropic 1 0
RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 0
@@ -95,16 +96,47 @@ RenderUseImpostors 1 1
RenderVolumeLODFactor 1 0.5
VertexShaderEnable 1 0
WindLightUseAtmosShaders 1 0
+RenderDeferred 1 0
+RenderDeferredSSAO 1 0
+RenderShadowDetail 1 0
WLSkyDetail 1 48
+RenderFSAASamples 1 0
+
+//
+// Low Graphics Settings
+//
+list Low
+RenderAnisotropic 1 0
+RenderAvatarCloth 1 0
+RenderAvatarLODFactor 1 0
+RenderAvatarPhysicsLODFactor 1 0
+RenderAvatarMaxVisible 1 3
+RenderAvatarVP 1 0
+RenderFarClip 1 64
+RenderFlexTimeFactor 1 0
+RenderGlowResolutionPow 1 8
+RenderLocalLights 1 0
+RenderMaxPartCount 1 0
+RenderObjectBump 1 0
+RenderReflectionDetail 1 0
+RenderTerrainDetail 1 0
+RenderTerrainLODFactor 1 1
+RenderTransparentWater 1 0
+RenderTreeLODFactor 1 0
+RenderUseImpostors 1 1
+RenderVolumeLODFactor 1 0.5
+VertexShaderEnable 1 1
+WindLightUseAtmosShaders 1 0
RenderDeferred 1 0
RenderDeferredSSAO 1 0
RenderShadowDetail 1 0
+WLSkyDetail 1 48
RenderFSAASamples 1 0
//
-// Mid Graphics Settings
+// Medium Low Graphics Settings
//
-list Mid
+list LowMid
RenderAnisotropic 1 0
RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 0.5
@@ -113,9 +145,9 @@ RenderAvatarVP 1 1
RenderFarClip 1 96
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 8
-RenderLocalLights 1 1
RenderMaxPartCount 1 2048
RenderObjectBump 1 1
+RenderLocalLights 1 1
RenderReflectionDetail 1 0
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 1.0
@@ -125,16 +157,16 @@ RenderUseImpostors 1 1
RenderVolumeLODFactor 1 1.125
VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 0
-WLSkyDetail 1 48
RenderDeferred 1 0
RenderDeferredSSAO 1 0
RenderShadowDetail 1 0
+WLSkyDetail 1 48
RenderFSAASamples 1 0
//
-// High Graphics Settings (purty)
+// Medium Graphics Settings (standard)
//
-list High
+list Mid
RenderAnisotropic 1 1
RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 1.0
@@ -143,9 +175,9 @@ RenderAvatarVP 1 1
RenderFarClip 1 128
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
-RenderLocalLights 1 1
RenderMaxPartCount 1 4096
RenderObjectBump 1 1
+RenderLocalLights 1 1
RenderReflectionDetail 1 0
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
@@ -155,12 +187,103 @@ RenderUseImpostors 1 1
RenderVolumeLODFactor 1 1.125
VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 1
-WLSkyDetail 1 48
RenderDeferred 1 0
RenderDeferredSSAO 1 0
+RenderShadowDetail 1 0
+WLSkyDetail 1 48
+RenderFSAASamples 1 2
+
+//
+// Medium High Graphics Settings (deferred enabled)
+//
+list MidHigh
+RenderAnisotropic 1 1
+RenderAvatarCloth 1 0
+RenderAvatarLODFactor 1 1.0
+RenderAvatarPhysicsLODFactor 1 1.0
+RenderAvatarVP 1 1
+RenderFarClip 1 128
+RenderFlexTimeFactor 1 1.0
+RenderGlowResolutionPow 1 9
+RenderMaxPartCount 1 4096
+RenderObjectBump 1 1
+RenderLocalLights 1 1
+RenderReflectionDetail 1 0
+RenderTerrainDetail 1 1
+RenderTerrainLODFactor 1 2.0
+RenderTransparentWater 1 1
+RenderTreeLODFactor 1 0.5
+RenderUseImpostors 1 1
+RenderVolumeLODFactor 1 1.125
+VertexShaderEnable 1 1
+WindLightUseAtmosShaders 1 1
+RenderDeferred 1 1
+RenderDeferredSSAO 1 0
+RenderShadowDetail 1 0
+WLSkyDetail 1 48
+RenderFSAASamples 1 2
+
+//
+// High Graphics Settings (deferred + SSAO)
+//
+list High
+RenderAnisotropic 1 1
+RenderAvatarCloth 1 0
+RenderAvatarLODFactor 1 1.0
+RenderAvatarPhysicsLODFactor 1 1.0
+RenderAvatarVP 1 1
+RenderFarClip 1 128
+RenderFlexTimeFactor 1 1.0
+RenderGlowResolutionPow 1 9
+RenderMaxPartCount 1 4096
+RenderObjectBump 1 1
+RenderLocalLights 1 1
+RenderReflectionDetail 1 0
+RenderTerrainDetail 1 1
+RenderTerrainLODFactor 1 2.0
+RenderTransparentWater 1 1
+RenderTreeLODFactor 1 0.5
+RenderUseImpostors 1 1
+RenderVolumeLODFactor 1 1.125
+VertexShaderEnable 1 1
+WindLightUseAtmosShaders 1 1
+RenderDeferred 1 1
+RenderDeferredSSAO 1 1
+RenderShadowDetail 1 0
+WLSkyDetail 1 48
+RenderFSAASamples 1 2
+
+//
+// High Ultra Graphics Settings (deferred + SSAO + shadows)
+//
+list HighUltra
+RenderAnisotropic 1 1
+RenderAvatarCloth 1 0
+RenderAvatarLODFactor 1 1.0
+RenderAvatarPhysicsLODFactor 1 1.0
+RenderAvatarVP 1 1
+RenderFarClip 1 128
+RenderFlexTimeFactor 1 1.0
+RenderGlowResolutionPow 1 9
+RenderMaxPartCount 1 4096
+RenderObjectBump 1 1
+RenderLocalLights 1 1
+RenderReflectionDetail 1 0
+RenderTerrainDetail 1 1
+RenderTerrainLODFactor 1 2.0
+RenderTransparentWater 1 1
+RenderTreeLODFactor 1 0.5
+RenderUseImpostors 1 1
+RenderVolumeLODFactor 1 1.125
+VertexShaderEnable 1 1
+WindLightUseAtmosShaders 1 1
+RenderDeferred 1 1
+RenderDeferredSSAO 1 1
RenderShadowDetail 1 2
+WLSkyDetail 1 48
RenderFSAASamples 1 2
+
//
// Ultra graphics (REALLY PURTY!)
//
@@ -186,8 +309,8 @@ RenderVolumeLODFactor 1 2.0
VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 1
WLSkyDetail 1 128
-RenderDeferred 1 0
-RenderDeferredSSAO 1 0
+RenderDeferred 1 1
+RenderDeferredSSAO 1 1
RenderShadowDetail 1 2
RenderFSAASamples 1 2
@@ -210,16 +333,27 @@ list Class1
RenderVBOEnable 1 1
//
-// Class 2 Hardware (make it purty)
+// Class 2 Hardware
//
list Class2
RenderVBOEnable 1 1
//
-// Class 3 Hardware (make it purty)
+// Class 3 Hardware
//
list Class3
RenderVBOEnable 1 1
+//
+// Class 4 Hardware
+//
+list Class4
+RenderVBOEnable 1 1
+
+//
+// Class 5 Hardware
+//
+list Class5
+RenderVBOEnable 1 1
//
// No Pixel Shaders available
@@ -248,6 +382,12 @@ RenderDeferredSSAO 0 0
RenderShadowDetail 0 0
//
+// VRAM > 512MB
+//
+list VRAMGT512
+RenderCompressTextures 1 0
+
+//
// "Default" setups for safe, low, medium, high
//
list safe
@@ -286,6 +426,7 @@ RenderObjectBump 0 0
list OpenGLPre15
RenderVBOEnable 1 0
+
list TexUnit8orLess
RenderDeferredSSAO 0 0
@@ -295,6 +436,7 @@ RenderDeferredSSAO 1 0
list Intel
RenderAnisotropic 1 0
RenderLocalLights 1 0
+RenderFSAASamples 1 0
list GeForce2
RenderAnisotropic 1 0
diff --git a/indra/newview/featuretable_solaris.txt b/indra/newview/featuretable_solaris.txt
index e7cae1abdc..e7cae1abdc 100644..100755
--- a/indra/newview/featuretable_solaris.txt
+++ b/indra/newview/featuretable_solaris.txt
diff --git a/indra/newview/featuretable_xp.txt b/indra/newview/featuretable_xp.txt
index ae2cf910f2..68e09d010e 100644..100755
--- a/indra/newview/featuretable_xp.txt
+++ b/indra/newview/featuretable_xp.txt
@@ -1,4 +1,4 @@
-version 31
+version 32
// The version number above should be implemented IF AND ONLY IF some
// change has been made that is sufficiently important to justify
// resetting the graphics preferences of all users to the recommended
@@ -61,19 +61,20 @@ WLSkyDetail 1 128
Disregard128DefaultDrawDistance 1 1
Disregard96DefaultDrawDistance 1 1
RenderTextureMemoryMultiple 1 1.0
+RenderCompressTextures 1 1
RenderShaderLightingMaxLevel 1 3
-RenderDeferred 1 0
-RenderDeferredSSAO 1 0
-RenderShadowDetail 1 0
+RenderDeferred 1 1
+RenderDeferredSSAO 1 1
+RenderShadowDetail 1 2
WatchdogDisabled 1 1
RenderUseStreamVBO 1 1
RenderFSAASamples 1 16
RenderMaxTextureIndex 1 16
//
-// Low Graphics Settings
+// Low Graphics Settings (fixed function)
//
-list Low
+list LowFixedFunction
RenderAnisotropic 1 0
RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 0
@@ -95,16 +96,47 @@ RenderUseImpostors 1 1
RenderVolumeLODFactor 1 0.5
VertexShaderEnable 1 0
WindLightUseAtmosShaders 1 0
+RenderDeferred 1 0
+RenderDeferredSSAO 1 0
+RenderShadowDetail 1 0
WLSkyDetail 1 48
+RenderFSAASamples 1 0
+
+//
+// Low Graphics Settings
+//
+list Low
+RenderAnisotropic 1 0
+RenderAvatarCloth 1 0
+RenderAvatarLODFactor 1 0
+RenderAvatarPhysicsLODFactor 1 0
+RenderAvatarMaxVisible 1 3
+RenderAvatarVP 1 0
+RenderFarClip 1 64
+RenderFlexTimeFactor 1 0
+RenderGlowResolutionPow 1 8
+RenderLocalLights 1 0
+RenderMaxPartCount 1 0
+RenderObjectBump 1 0
+RenderReflectionDetail 1 0
+RenderTerrainDetail 1 0
+RenderTerrainLODFactor 1 1
+RenderTransparentWater 1 0
+RenderTreeLODFactor 1 0
+RenderUseImpostors 1 1
+RenderVolumeLODFactor 1 0.5
+VertexShaderEnable 1 1
+WindLightUseAtmosShaders 1 0
RenderDeferred 1 0
RenderDeferredSSAO 1 0
RenderShadowDetail 1 0
+WLSkyDetail 1 48
RenderFSAASamples 1 0
//
-// Mid Graphics Settings
+// Medium Low Graphics Settings
//
-list Mid
+list LowMid
RenderAnisotropic 1 0
RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 0.5
@@ -113,9 +145,9 @@ RenderAvatarVP 1 1
RenderFarClip 1 96
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 8
-RenderLocalLights 1 1
RenderMaxPartCount 1 2048
RenderObjectBump 1 1
+RenderLocalLights 1 1
RenderReflectionDetail 1 0
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 1.0
@@ -125,16 +157,16 @@ RenderUseImpostors 1 1
RenderVolumeLODFactor 1 1.125
VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 0
-WLSkyDetail 1 48
RenderDeferred 1 0
RenderDeferredSSAO 1 0
RenderShadowDetail 1 0
+WLSkyDetail 1 48
RenderFSAASamples 1 0
//
-// High Graphics Settings (purty)
+// Medium Graphics Settings (standard)
//
-list High
+list Mid
RenderAnisotropic 1 1
RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 1.0
@@ -143,9 +175,9 @@ RenderAvatarVP 1 1
RenderFarClip 1 128
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
-RenderLocalLights 1 1
RenderMaxPartCount 1 4096
RenderObjectBump 1 1
+RenderLocalLights 1 1
RenderReflectionDetail 1 0
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
@@ -155,10 +187,100 @@ RenderUseImpostors 1 1
RenderVolumeLODFactor 1 1.125
VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 1
-WLSkyDetail 1 48
RenderDeferred 1 0
RenderDeferredSSAO 1 0
+RenderShadowDetail 1 0
+WLSkyDetail 1 48
+RenderFSAASamples 1 2
+
+//
+// Medium High Graphics Settings (deferred enabled)
+//
+list MidHigh
+RenderAnisotropic 1 1
+RenderAvatarCloth 1 0
+RenderAvatarLODFactor 1 1.0
+RenderAvatarPhysicsLODFactor 1 1.0
+RenderAvatarVP 1 1
+RenderFarClip 1 128
+RenderFlexTimeFactor 1 1.0
+RenderGlowResolutionPow 1 9
+RenderMaxPartCount 1 4096
+RenderObjectBump 1 1
+RenderLocalLights 1 1
+RenderReflectionDetail 1 0
+RenderTerrainDetail 1 1
+RenderTerrainLODFactor 1 2.0
+RenderTransparentWater 1 1
+RenderTreeLODFactor 1 0.5
+RenderUseImpostors 1 1
+RenderVolumeLODFactor 1 1.125
+VertexShaderEnable 1 1
+WindLightUseAtmosShaders 1 1
+RenderDeferred 1 1
+RenderDeferredSSAO 1 0
+RenderShadowDetail 1 0
+WLSkyDetail 1 48
+RenderFSAASamples 1 2
+
+//
+// High Graphics Settings (deferred + SSAO)
+//
+list High
+RenderAnisotropic 1 1
+RenderAvatarCloth 1 0
+RenderAvatarLODFactor 1 1.0
+RenderAvatarPhysicsLODFactor 1 1.0
+RenderAvatarVP 1 1
+RenderFarClip 1 128
+RenderFlexTimeFactor 1 1.0
+RenderGlowResolutionPow 1 9
+RenderMaxPartCount 1 4096
+RenderObjectBump 1 1
+RenderLocalLights 1 1
+RenderReflectionDetail 1 0
+RenderTerrainDetail 1 1
+RenderTerrainLODFactor 1 2.0
+RenderTransparentWater 1 1
+RenderTreeLODFactor 1 0.5
+RenderUseImpostors 1 1
+RenderVolumeLODFactor 1 1.125
+VertexShaderEnable 1 1
+WindLightUseAtmosShaders 1 1
+RenderDeferred 1 1
+RenderDeferredSSAO 1 1
+RenderShadowDetail 1 0
+WLSkyDetail 1 48
+RenderFSAASamples 1 2
+
+//
+// High Ultra Graphics Settings (deferred + SSAO + shadows)
+//
+list HighUltra
+RenderAnisotropic 1 1
+RenderAvatarCloth 1 0
+RenderAvatarLODFactor 1 1.0
+RenderAvatarPhysicsLODFactor 1 1.0
+RenderAvatarVP 1 1
+RenderFarClip 1 128
+RenderFlexTimeFactor 1 1.0
+RenderGlowResolutionPow 1 9
+RenderMaxPartCount 1 4096
+RenderObjectBump 1 1
+RenderLocalLights 1 1
+RenderReflectionDetail 1 0
+RenderTerrainDetail 1 1
+RenderTerrainLODFactor 1 2.0
+RenderTransparentWater 1 1
+RenderTreeLODFactor 1 0.5
+RenderUseImpostors 1 1
+RenderVolumeLODFactor 1 1.125
+VertexShaderEnable 1 1
+WindLightUseAtmosShaders 1 1
+RenderDeferred 1 1
+RenderDeferredSSAO 1 1
RenderShadowDetail 1 2
+WLSkyDetail 1 48
RenderFSAASamples 1 2
//
@@ -210,18 +332,36 @@ list Class1
RenderVBOEnable 1 1
//
-// Class 2 Hardware (make it purty)
+// Class 2 Hardware
//
list Class2
RenderVBOEnable 1 1
//
-// Class 3 Hardware (make it purty)
+// Class 3 Hardware
//
list Class3
RenderVBOEnable 1 1
//
+// Class 4 Hardware (deferred + SSAO)
+//
+list Class4
+RenderVBOEnable 1 1
+
+//
+// Class 5 Hardware
+//
+list Class5
+RenderVBOEnable 1 1
+
+//
+// VRAM > 512MB
+//
+list VRAMGT512
+RenderCompressTextures 1 0
+
+//
// No Pixel Shaders available
//
list NoPixelShaders
@@ -299,6 +439,7 @@ RenderMaxTextureIndex 1 1
list Intel
RenderAnisotropic 1 0
RenderVBOEnable 1 0
+RenderFSAASamples 1 0
list GeForce2
RenderAnisotropic 1 0
@@ -478,6 +619,7 @@ Disregard128DefaultDrawDistance 1 0
list ATIOldDriver
RenderAvatarVP 0 0
RenderAvatarCloth 0 0
+RenderVBOEnable 1 0
// ATI cards generally perform better when not using VBOs for streaming data
diff --git a/indra/newview/fmod_hidden_symbols.exp b/indra/newview/fmod_hidden_symbols.exp
deleted file mode 100644
index 1e790255bc..0000000000
--- a/indra/newview/fmod_hidden_symbols.exp
+++ /dev/null
@@ -1,240 +0,0 @@
-_CarbonSndPlayDoubleBuffer
-_ConvertFromIeeeExtended
-__book_maptype1_quantvals
-__book_unquantize
-__float32_pack
-__float32_unpack
-__ilog
-__make_words
-_lpc_clear
-_lpc_init
-__vorbis_block_alloc
-__vorbis_block_ripcord
-__vorbis_apply_window
-__vorbis_window_get
-_vorbis_analysis_blockout
-_vorbis_analysis_buffer
-_vorbis_analysis_wrote
-_vorbis_block_clear
-_vorbis_block_init
-_vorbis_dsp_clear
-_vorbis_synthesis_blockin
-_vorbis_synthesis_init
-_vorbis_synthesis_pcmout
-_vorbis_synthesis_read
-_vorbis_packet_blocksize
-_vorbis_synthesis
-_vorbis_book_clear
-_vorbis_book_decode
-_vorbis_book_decodev_add
-_vorbis_book_decodev_set
-_vorbis_book_decodevs_add
-_vorbis_book_decodevv_add
-_vorbis_book_init_decode
-_vorbis_comment_add
-_vorbis_comment_add_tag
-_vorbis_comment_clear
-_vorbis_comment_init
-_vorbis_comment_query
-_vorbis_comment_query_count
-_vorbis_coslook
-_vorbis_fromdBlook
-_vorbis_info_blocksize
-_vorbis_info_clear
-_vorbis_info_init
-_vorbis_invsq2explook
-_vorbis_invsqlook
-_vorbis_lpc_from_curve
-_vorbis_lpc_from_data
-_vorbis_lpc_predict
-_vorbis_lsp_to_curve
-_vorbis_staticbook_clear
-_vorbis_staticbook_destroy
-_vorbis_staticbook_unpack
-_vorbis_synthesis_headerin
-_vorbis_synthesis_lapout
-_vorbis_synthesis_restart
-_vorbis_synthesis_trackonly
-_vorbis_window
-_ogg_packet_clear
-_ogg_page_bos
-_ogg_page_checksum_set
-_ogg_page_continued
-_ogg_page_eos
-_ogg_page_granulepos
-_ogg_page_packets
-_ogg_page_pageno
-_ogg_page_serialno
-_ogg_page_version
-_ogg_stream_reset_serialno
-_ogg_stream_clear
-_ogg_stream_destroy
-_ogg_stream_eos
-_ogg_stream_flush
-_ogg_stream_init
-_ogg_stream_packetout
-_ogg_stream_packetpeek
-_ogg_stream_pagein
-_ogg_stream_pageout
-_ogg_stream_reset
-_ogg_sync_buffer
-_ogg_sync_clear
-_ogg_sync_destroy
-_ogg_sync_init
-_ogg_sync_pageout
-_ogg_sync_pageseek
-_ogg_sync_reset
-_ogg_sync_wrote
-_ov_bitrate
-_ov_bitrate_instant
-_ov_clear
-_ov_comment
-_ov_info
-_ov_open
-_ov_open_callbacks
-_ov_pcm_seek
-_ov_pcm_seek_page
-_ov_pcm_tell
-_ov_pcm_total
-_ov_raw_seek
-_ov_raw_tell
-_ov_raw_total
-_ov_read
-_ov_read_float
-_ov_seekable
-_ov_serialnumber
-_ov_streams
-_ov_test
-_ov_test_callbacks
-_ov_test_open
-_ov_time_seek
-_ov_time_seek_page
-_ov_time_tell
-_ov_time_total
-_ogg_toupper
-_oggpackB_adv
-_oggpackB_adv1
-_oggpackB_bits
-_oggpackB_bytes
-_oggpackB_get_buffer
-_oggpackB_look
-_oggpackB_look1
-_oggpackB_read
-_oggpackB_read1
-_oggpackB_readinit
-_oggpackB_reset
-_oggpack_adv
-_oggpack_adv1
-_oggpack_bits
-_oggpack_bytes
-_oggpack_get_buffer
-_oggpack_look
-_oggpack_look1
-_oggpack_read
-_oggpack_read1
-_oggpack_readinit
-_oggpack_reset
-_ov_crosslap
-_ov_pcm_seek_lap
-_ov_pcm_seek_page_lap
-_ov_raw_seek_lap
-_ov_time_seek_lap
-_ov_time_seek_page_lap
-_II_step_one
-_II_step_two
-_MyRecComp
-_SampleRates
-_Sinfo
-_ValidStepIndex
-__Z11fmodwrapperv
-__Z11fmodwrapperv.eh
-__floor_P
-__mapping_P
-__residue_P
-__ve_envelope_clear
-__ve_envelope_init
-__ve_envelope_mark
-__ve_envelope_search
-__ve_envelope_shift
-__vi_gpsy_free
-__vi_psy_free
-__vorbis_window_init
-__vp_ampmax_decay
-__vp_couple
-__vp_global_free
-__vp_global_look
-__vp_noise_normalize
-__vp_noise_normalize_sort
-__vp_noisemask
-__vp_offset_and_mix
-__vp_psy_clear
-__vp_psy_init
-__vp_quantize_couple_memo
-__vp_quantize_couple_sort
-__vp_remove_floor
-__vp_tonemask
-_alloc_0
-_alloc_1
-_alloc_2
-_alloc_3
-_alloc_4
-_bandInfo
-_cdcallback
-_cdchannel
-_cdmode
-_cdnumtracks
-_cdstream
-_cdtrack
-_drft_backward
-_drft_clear
-_drft_forward
-_drft_init
-_eatwhite
-_floor0_exportbundle
-_floor1_exportbundle
-_gFreeList
-_gNMRecBusy
-_gNMRecPtr
-_gSilenceOnes
-_gSilenceTwos
-_longLimit
-_mapping0_exportbundle
-_mdct_backward
-_mdct_clear
-_mdct_forward
-_mdct_init
-_muls
-_mystrdup
-_res0_free_info
-_res0_free_look
-_res0_inverse
-_res0_look
-_res0_unpack
-_res1_class
-_res1_inverse
-_res2_inverse
-_residue0_exportbundle
-_residue1_exportbundle
-_residue2_exportbundle
-_scale
-_shortLimit
-_tabsel_123
-_F_Free
-_F_Malloc
-_F_ReAlloc
-_F_memcmp
-_F_memmove
-_F_strcat
-_F_strchr
-_F_strcmp
-_F_strcpy
-_F_stricmp
-_F_strlen
-_F_strncat
-_F_strncmp
-_F_strncpy
-_F_strnicmp
-_F_strstr
-_F_strupr
-_F_tolower
-_F_toupper
diff --git a/indra/newview/fmodwrapper.cpp b/indra/newview/fmodwrapper.cpp
deleted file mode 100644
index 16f1d19a78..0000000000
--- a/indra/newview/fmodwrapper.cpp
+++ /dev/null
@@ -1,37 +0,0 @@
-/**
- * @file fmodwrapper.cpp
- * @brief dummy source file for building a shared library to wrap libfmod.a
- *
- * $LicenseInfo:firstyear=2005&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$
- */
-
-extern "C"
-{
- void FSOUND_Init(void);
-}
-
-void* fmodwrapper(void)
-{
- // When building the fmodwrapper library, the linker doesn't seem to want to bring in libfmod.a unless I explicitly
- // reference at least one symbol in the library. This seemed like the simplest way.
- return (void*)&FSOUND_Init;
-}
diff --git a/indra/newview/fonts/DejaVu-license.txt b/indra/newview/fonts/DejaVu-license.txt
index 254e2cc42a..254e2cc42a 100644..100755
--- a/indra/newview/fonts/DejaVu-license.txt
+++ b/indra/newview/fonts/DejaVu-license.txt
diff --git a/indra/newview/fonts/DejaVuSans-Bold.ttf b/indra/newview/fonts/DejaVuSans-Bold.ttf
index ec1a2ebaf2..ec1a2ebaf2 100644..100755
--- a/indra/newview/fonts/DejaVuSans-Bold.ttf
+++ b/indra/newview/fonts/DejaVuSans-Bold.ttf
Binary files differ
diff --git a/indra/newview/fonts/DejaVuSans-BoldOblique.ttf b/indra/newview/fonts/DejaVuSans-BoldOblique.ttf
index 1a5576460d..1a5576460d 100644..100755
--- a/indra/newview/fonts/DejaVuSans-BoldOblique.ttf
+++ b/indra/newview/fonts/DejaVuSans-BoldOblique.ttf
Binary files differ
diff --git a/indra/newview/fonts/DejaVuSans-Oblique.ttf b/indra/newview/fonts/DejaVuSans-Oblique.ttf
index becc549927..becc549927 100644..100755
--- a/indra/newview/fonts/DejaVuSans-Oblique.ttf
+++ b/indra/newview/fonts/DejaVuSans-Oblique.ttf
Binary files differ
diff --git a/indra/newview/fonts/DejaVuSans.ttf b/indra/newview/fonts/DejaVuSans.ttf
index c1b19d8705..c1b19d8705 100644..100755
--- a/indra/newview/fonts/DejaVuSans.ttf
+++ b/indra/newview/fonts/DejaVuSans.ttf
Binary files differ
diff --git a/indra/newview/fonts/DejaVuSansMono.ttf b/indra/newview/fonts/DejaVuSansMono.ttf
index 6bc854ddae..6bc854ddae 100644..100755
--- a/indra/newview/fonts/DejaVuSansMono.ttf
+++ b/indra/newview/fonts/DejaVuSansMono.ttf
Binary files differ
diff --git a/indra/newview/fr.lproj/language.txt b/indra/newview/fr.lproj/language.txt
index 717280ac26..717280ac26 100644..100755
--- a/indra/newview/fr.lproj/language.txt
+++ b/indra/newview/fr.lproj/language.txt
diff --git a/indra/newview/generate_breakpad_symbols.py b/indra/newview/generate_breakpad_symbols.py
index 5ebec1563e..4181e4ebb3 100644..100755
--- a/indra/newview/generate_breakpad_symbols.py
+++ b/indra/newview/generate_breakpad_symbols.py
@@ -39,17 +39,20 @@ import shlex
import subprocess
import tarfile
import StringIO
+import pprint
+
+DEBUG=False
def usage():
- print >>sys.stderr, "usage: %s viewer_dir viewer_exes libs_suffix dump_syms_tool viewer_symbol_file" % sys.argv[0]
+ print >>sys.stderr, "usage: %s search_dirs viewer_exes libs_suffix dump_syms_tool viewer_symbol_file" % sys.argv[0]
class MissingModuleError(Exception):
def __init__(self, modules):
Exception.__init__(self, "Failed to find required modules: %r" % modules)
self.modules = modules
-def main(configuration, viewer_dir, viewer_exes, libs_suffix, dump_syms_tool, viewer_symbol_file):
- print "generate_breakpad_symbols run with args: %s" % str((configuration, viewer_dir, viewer_exes, libs_suffix, dump_syms_tool, viewer_symbol_file))
+def main(configuration, search_dirs, viewer_exes, libs_suffix, dump_syms_tool, viewer_symbol_file):
+ print "generate_breakpad_symbols run with args: %s" % str((configuration, search_dirs, viewer_exes, libs_suffix, dump_syms_tool, viewer_symbol_file))
if not re.match("release", configuration, re.IGNORECASE):
print "skipping breakpad symbol generation for non-release build."
@@ -67,21 +70,49 @@ def main(configuration, viewer_dir, viewer_exes, libs_suffix, dump_syms_tool, vi
return True
return fnmatch.fnmatch(f, libs_suffix)
+ search_dirs = search_dirs.split(";")
+
def list_files():
- for (dirname, subdirs, filenames) in os.walk(viewer_dir):
- #print "scanning '%s' for modules..." % dirname
- for f in itertools.ifilter(matches, filenames):
- yield os.path.join(dirname, f)
+ for search_dir in search_dirs:
+ for (dirname, subdirs, filenames) in os.walk(search_dir):
+ if DEBUG:
+ print "scanning '%s' for modules..." % dirname
+ for f in itertools.ifilter(matches, filenames):
+ yield os.path.join(dirname, f)
def dump_module(m):
print "dumping module '%s' with '%s'..." % (m, dump_syms_tool)
- child = subprocess.Popen([dump_syms_tool, m] , stdout=subprocess.PIPE)
+ dsym_full_path = m
+ child = subprocess.Popen([dump_syms_tool, dsym_full_path] , stdout=subprocess.PIPE)
out, err = child.communicate()
return (m,child.returncode, out, err)
- out = tarfile.open(viewer_symbol_file, 'w:bz2')
+
+ modules = {}
+
+ for m in list_files():
+ if DEBUG:
+ print "examining module '%s' ... " % m,
+ filename=os.path.basename(m)
+ if -1 != m.find("DWARF"):
+ # Just use this module; it has the symbols we want.
+ modules[filename] = m
+ if DEBUG:
+ print "found dSYM entry"
+ elif filename not in modules:
+ # Only use this if we don't already have a (possibly better) entry.
+ modules[filename] = m
+ if DEBUG:
+ print "found new entry"
+ elif DEBUG:
+ print "ignoring entry"
+
+
+ print "Found these following modules:"
+ pprint.pprint( modules )
- for (filename,status,symbols,err) in itertools.imap(dump_module, list_files()):
+ out = tarfile.open(viewer_symbol_file, 'w:bz2')
+ for (filename,status,symbols,err) in itertools.imap(dump_module, modules.values()):
if status == 0:
module_line = symbols[:symbols.index('\n')]
module_line = module_line.split()
diff --git a/indra/newview/gpu_table.txt b/indra/newview/gpu_table.txt
index 198e702459..23a065caff 100644..100755
--- a/indra/newview/gpu_table.txt
+++ b/indra/newview/gpu_table.txt
@@ -1,3 +1,4 @@
+//GPU_TABLE - that token on line 1 tags this as a gpu table file
//
// Categorizes graphics chips into various classes by name
//
@@ -17,519 +18,546 @@
//
// Format:
// Fields are separated by one or more tab (not space) characters
-// <recognizer name> <regular expression> <class> <supported>
+// <recognizer name> <regular expression> <class> <supported> <stats based> <expected OpenGL version>
//
// Class Numbers:
// 0 - Defaults to low graphics settings. No shaders on by default
// 1 - Defaults to mid graphics settings. Basic shaders on by default
// 2 - Defaults to high graphics settings. Atmospherics on by default.
-// 3 - Same as class 2 for now.
+// 3 - Same as 2, but with lighting and shadows enabled.
+// 4 - Same as 3, but with ambient occlusion enabled.
+// 5 - Same as 4, but with shadows set to "Sun/Moon+Projectors."
//
// Supported Number:
// 0 - We claim to not support this card.
// 1 - We claim to support this card.
//
-3Dfx .*3Dfx.* 0 0
-3Dlabs .*3Dlabs.* 0 0
-ATI 3D-Analyze .*ATI.*3D-Analyze.* 0 0
-ATI All-in-Wonder 7500 .*ATI.*All-in-Wonder 75.* 0 1
-ATI All-in-Wonder 8500 .*ATI.*All-in-Wonder 85.* 0 1
-ATI All-in-Wonder 9200 .*ATI.*All-in-Wonder 92.* 0 1
-ATI All-in-Wonder 9xxx .*ATI.*All-in-Wonder 9.* 1 1
-ATI All-in-Wonder HD .*ATI.*All-in-Wonder HD.* 1 1
-ATI All-in-Wonder X600 .*ATI.*All-in-Wonder X6.* 1 1
-ATI All-in-Wonder X800 .*ATI.*All-in-Wonder X8.* 2 1
-ATI All-in-Wonder X1800 .*ATI.*All-in-Wonder X18.* 3 1
-ATI All-in-Wonder X1900 .*ATI.*All-in-Wonder X19.* 3 1
-ATI All-in-Wonder PCI-E .*ATI.*All-in-Wonder.*PCI-E.* 1 1
-ATI All-in-Wonder Radeon .*ATI.*All-in-Wonder Radeon.* 0 1
-ATI ASUS ARES .*ATI.*ASUS.*ARES.* 3 1
-ATI ASUS A9xxx .*ATI.*ASUS.*A9.* 1 1
-ATI ASUS AH24xx .*ATI.*ASUS.*AH24.* 1 1
-ATI ASUS AH26xx .*ATI.*ASUS.*AH26.* 3 1
-ATI ASUS AH34xx .*ATI.*ASUS.*AH34.* 1 1
-ATI ASUS AH36xx .*ATI.*ASUS.*AH36.* 3 1
-ATI ASUS AH46xx .*ATI.*ASUS.*AH46.* 3 1
-ATI ASUS AX3xx .*ATI.*ASUS.*AX3.* 1 1
-ATI ASUS AX5xx .*ATI.*ASUS.*AX5.* 1 1
-ATI ASUS AX8xx .*ATI.*ASUS.*AX8.* 2 1
-ATI ASUS EAH24xx .*ATI.*ASUS.*EAH24.* 2 1
-ATI ASUS EAH26xx .*ATI.*ASUS.*EAH26.* 3 1
-ATI ASUS EAH29xx .*ATI.*ASUS.*EAH29.* 3 1
-ATI ASUS EAH34xx .*ATI.*ASUS.*EAH34.* 1 1
-ATI ASUS EAH36xx .*ATI.*ASUS.*EAH36.* 3 1
-ATI ASUS EAH38xx .*ATI.*ASUS.*EAH38.* 3 1
-ATI ASUS EAH43xx .*ATI.*ASUS.*EAH43.* 1 1
-ATI ASUS EAH45xx .*ATI.*ASUS.*EAH45.* 1 1
-ATI ASUS EAH48xx .*ATI.*ASUS.*EAH48.* 3 1
-ATI ASUS EAH57xx .*ATI.*ASUS.*EAH57.* 3 1
-ATI ASUS EAH58xx .*ATI.*ASUS.*EAH58.* 3 1
-ATI ASUS EAH6xxx .*ATI.*ASUS.*EAH6.* 3 1
-ATI ASUS Radeon X1xxx .*ATI.*ASUS.*X1.* 3 1
-ATI Radeon X7xx .*ATI.*ASUS.*X7.* 1 1
-ATI Radeon X19xx .*ATI.*(Radeon|Diamond) X19.* ?.* 3 1
-ATI Radeon X18xx .*ATI.*(Radeon|Diamond) X18.* ?.* 3 1
-ATI Radeon X17xx .*ATI.*(Radeon|Diamond) X17.* ?.* 2 1
-ATI Radeon X16xx .*ATI.*(Radeon|Diamond) X16.* ?.* 2 1
-ATI Radeon X15xx .*ATI.*(Radeon|Diamond) X15.* ?.* 2 1
-ATI Radeon X13xx .*ATI.*(Radeon|Diamond) X13.* ?.* 1 1
-ATI Radeon X1xxx .*ATI.*(Radeon|Diamond) X1.. ?.* 1 1
-ATI Radeon X2xxx .*ATI.*(Radeon|Diamond) X2.. ?.* 1 1
-ATI Display Adapter .*ATI.*display adapter.* 0 1
-ATI FireGL 5200 .*ATI.*FireGL V52.* 0 1
-ATI FireGL 5xxx .*ATI.*FireGL V5.* 1 1
-ATI FireGL .*ATI.*Fire.*GL.* 0 1
-ATI FirePro M3900 .*ATI.*FirePro.*M39.* 2 1
-ATI FirePro M5800 .*ATI.*FirePro.*M58.* 3 1
-ATI FirePro M7740 .*ATI.*FirePro.*M77.* 3 1
-ATI FirePro M7820 .*ATI.*FirePro.*M78.* 3 1
-ATI FireMV .*ATI.*FireMV.* 0 1
-ATI Geforce 9500 GT .*ATI.*Geforce 9500 *GT.* 2 1
-ATI Geforce 9600 GT .*ATI.*Geforce 9600 *GT.* 2 1
-ATI Geforce 9800 GT .*ATI.*Geforce 9800 *GT.* 2 1
-ATI Generic .*ATI.*Generic.* 0 0
-ATI Hercules 9800 .*ATI.*Hercules.*9800.* 1 1
-ATI IGP 340M .*ATI.*IGP.*340M.* 0 0
-ATI M52 .*ATI.*M52.* 1 1
-ATI M54 .*ATI.*M54.* 1 1
-ATI M56 .*ATI.*M56.* 1 1
-ATI M71 .*ATI.*M71.* 1 1
-ATI M72 .*ATI.*M72.* 1 1
-ATI M76 .*ATI.*M76.* 3 1
-ATI Radeon HD 64xx .*ATI.*AMD Radeon.* HD [67]4..[MG] 3 1
-ATI Radeon HD 65xx .*ATI.*AMD Radeon.* HD [67]5..[MG] 3 1
-ATI Radeon HD 66xx .*ATI.*AMD Radeon.* HD [67]6..[MG] 3 1
-ATI Mobility Radeon 4100 .*ATI.*Mobility.*41.. 1 1
-ATI Mobility Radeon 7xxx .*ATI.*Mobility.*Radeon 7.* 0 1
-ATI Mobility Radeon 8xxx .*ATI.*Mobility.*Radeon 8.* 0 1
-ATI Mobility Radeon 9800 .*ATI.*Mobility.*98.* 1 1
-ATI Mobility Radeon 9700 .*ATI.*Mobility.*97.* 1 1
-ATI Mobility Radeon 9600 .*ATI.*Mobility.*96.* 0 1
-ATI Mobility Radeon HD 530v .*ATI.*Mobility.*HD *530v.* 1 1
-ATI Mobility Radeon HD 540v .*ATI.*Mobility.*HD *540v.* 2 1
-ATI Mobility Radeon HD 545v .*ATI.*Mobility.*HD *545v.* 2 1
-ATI Mobility Radeon HD 550v .*ATI.*Mobility.*HD *550v.* 2 1
-ATI Mobility Radeon HD 560v .*ATI.*Mobility.*HD *560v.* 2 1
-ATI Mobility Radeon HD 565v .*ATI.*Mobility.*HD *565v.* 2 1
-ATI Mobility Radeon HD 2300 .*ATI.*Mobility.*HD *23.* 2 1
-ATI Mobility Radeon HD 2400 .*ATI.*Mobility.*HD *24.* 2 1
-ATI Mobility Radeon HD 2600 .*ATI.*Mobility.*HD *26.* 3 1
-ATI Mobility Radeon HD 2700 .*ATI.*Mobility.*HD *27.* 3 1
-ATI Mobility Radeon HD 3100 .*ATI.*Mobility.*HD *31.* 0 1
-ATI Mobility Radeon HD 3200 .*ATI.*Mobility.*HD *32.* 0 1
-ATI Mobility Radeon HD 3400 .*ATI.*Mobility.*HD *34.* 2 1
-ATI Mobility Radeon HD 3600 .*ATI.*Mobility.*HD *36.* 3 1
-ATI Mobility Radeon HD 3800 .*ATI.*Mobility.*HD *38.* 3 1
-ATI Mobility Radeon HD 4200 .*ATI.*Mobility.*HD *42.* 2 1
-ATI Mobility Radeon HD 4300 .*ATI.*Mobility.*HD *43.* 2 1
-ATI Mobility Radeon HD 4500 .*ATI.*Mobility.*HD *45.* 3 1
-ATI Mobility Radeon HD 4600 .*ATI.*Mobility.*HD *46.* 3 1
-ATI Mobility Radeon HD 4800 .*ATI.*Mobility.*HD *48.* 3 1
-ATI Mobility Radeon HD 5100 .*ATI.*Mobility.*HD *51.* 3 1
-ATI Mobility Radeon HD 5300 .*ATI.*Mobility.*HD *53.* 3 1
-ATI Mobility Radeon HD 5400 .*ATI.*Mobility.*HD *54.* 3 1
-ATI Mobility Radeon HD 5500 .*ATI.*Mobility.*HD *55.* 3 1
-ATI Mobility Radeon HD 5600 .*ATI.*Mobility.*HD *56.* 3 1
-ATI Mobility Radeon HD 5700 .*ATI.*Mobility.*HD *57.* 3 1
-ATI Mobility Radeon HD 6200 .*ATI.*Mobility.*HD *62.* 3 1
-ATI Mobility Radeon HD 6300 .*ATI.*Mobility.*HD *63.* 3 1
-ATI Mobility Radeon HD 6400M .*ATI.*Mobility.*HD *64.* 3 1
-ATI Mobility Radeon HD 6500M .*ATI.*Mobility.*HD *65.* 3 1
-ATI Mobility Radeon HD 6600M .*ATI.*Mobility.*HD *66.* 3 1
-ATI Mobility Radeon HD 6700M .*ATI.*Mobility.*HD *67.* 3 1
-ATI Mobility Radeon HD 6800M .*ATI.*Mobility.*HD *68.* 3 1
-ATI Mobility Radeon HD 6900M .*ATI.*Mobility.*HD *69.* 3 1
-ATI Radeon HD 2300 .*ATI.*Radeon HD *23.. 2 1
-ATI Radeon HD 2400 .*ATI.*Radeon HD *24.. 2 1
-ATI Radeon HD 2600 .*ATI.*Radeon HD *26.. 2 1
-ATI Radeon HD 2900 .*ATI.*Radeon HD *29.. 3 1
-ATI Radeon HD 3000 .*ATI.*Radeon HD *30.. 0 1
-ATI Radeon HD 3100 .*ATI.*Radeon HD *31.. 1 1
-ATI Radeon HD 3200 .*ATI.*Radeon HD *32.. 1 1
-ATI Radeon HD 3300 .*ATI.*Radeon HD *33.. 2 1
-ATI Radeon HD 3400 .*ATI.*Radeon HD *34.. 2 1
-ATI Radeon HD 3500 .*ATI.*Radeon HD *35.. 2 1
-ATI Radeon HD 3600 .*ATI.*Radeon HD *36.. 3 1
-ATI Radeon HD 3700 .*ATI.*Radeon HD *37.. 3 1
-ATI Radeon HD 3800 .*ATI.*Radeon HD *38.. 3 1
-ATI Radeon HD 4100 .*ATI.*Radeon HD *41.. 1 1
-ATI Radeon HD 4200 .*ATI.*Radeon HD *42.. 1 1
-ATI Radeon HD 4300 .*ATI.*Radeon HD *43.. 2 1
-ATI Radeon HD 4400 .*ATI.*Radeon HD *44.. 2 1
-ATI Radeon HD 4500 .*ATI.*Radeon HD *45.. 3 1
-ATI Radeon HD 4600 .*ATI.*Radeon HD *46.. 3 1
-ATI Radeon HD 4700 .*ATI.*Radeon HD *47.. 3 1
-ATI Radeon HD 4800 .*ATI.*Radeon HD *48.. 3 1
-ATI Radeon HD 5400 .*ATI.*Radeon HD *54.. 3 1
-ATI Radeon HD 5500 .*ATI.*Radeon HD *55.. 3 1
-ATI Radeon HD 5600 .*ATI.*Radeon HD *56.. 3 1
-ATI Radeon HD 5700 .*ATI.*Radeon HD *57.. 3 1
-ATI Radeon HD 5800 .*ATI.*Radeon HD *58.. 3 1
-ATI Radeon HD 5900 .*ATI.*Radeon HD *59.. 3 1
-ATI Radeon HD 6200 .*ATI.*Radeon HD *62.. 3 1
-ATI Radeon HD 6300 .*ATI.*Radeon HD *63.. 3 1
-ATI Radeon HD 6400 .*ATI.*Radeon HD *64.. 3 1
-ATI Radeon HD 6500 .*ATI.*Radeon HD *65.. 3 1
-ATI Radeon HD 6600 .*ATI.*Radeon HD *66.. 3 1
-ATI Radeon HD 6700 .*ATI.*Radeon HD *67.. 3 1
-ATI Radeon HD 6800 .*ATI.*Radeon HD *68.. 3 1
-ATI Radeon HD 6900 .*ATI.*Radeon HD *69.. 3 1
-ATI Radeon OpenGL .*ATI.*Radeon OpenGL.* 0 0
-ATI Radeon 2100 .*ATI.*Radeon 21.. 0 1
-ATI Radeon 3000 .*ATI.*Radeon 30.. 0 1
-ATI Radeon 3100 .*ATI.*Radeon 31.. 1 1
-ATI Radeon 5xxx .*ATI.*Radeon 5... 3 1
-ATI Radeon 7xxx .*ATI.*Radeon 7... 0 1
-ATI Radeon 8xxx .*ATI.*Radeon 8... 0 1
-ATI Radeon 9000 .*ATI.*Radeon 90.. 0 1
-ATI Radeon 9100 .*ATI.*Radeon 91.. 0 1
-ATI Radeon 9200 .*ATI.*Radeon 92.. 0 1
-ATI Radeon 9500 .*ATI.*Radeon 95.. 0 1
-ATI Radeon 9600 .*ATI.*Radeon 96.. 0 1
-ATI Radeon 9700 .*ATI.*Radeon 97.. 1 1
-ATI Radeon 9800 .*ATI.*Radeon 98.. 1 1
-ATI Radeon RV250 .*ATI.*RV250.* 0 1
-ATI Radeon RV600 .*ATI.*RV6.* 1 1
-ATI Radeon RX700 .*ATI.*RX70.* 1 1
-ATI Radeon RX800 .*ATI.*Radeon *RX80.* 2 1
-ATI RS880M .*ATI.*RS880M 1 1
-ATI Radeon RX9550 .*ATI.*RX9550.* 1 1
-ATI Radeon VE .*ATI.*Radeon.*VE.* 0 0
-ATI Radeon X300 .*ATI.*Radeon *X3.* 0 1
-ATI Radeon X400 .*ATI.*Radeon ?X4.* 0 1
-ATI Radeon X500 .*ATI.*Radeon ?X5.* 0 1
-ATI Radeon X600 .*ATI.*Radeon ?X6.* 1 1
-ATI Radeon X700 .*ATI.*Radeon ?X7.* 1 1
-ATI Radeon X800 .*ATI.*Radeon ?X8.* 2 1
-ATI Radeon X900 .*ATI.*Radeon ?X9.* 2 1
-ATI Radeon Xpress .*ATI.*Radeon Xpress.* 0 1
-ATI Rage 128 .*ATI.*Rage 128.* 0 1
-ATI R350 (9800) .*R350.* 1 1
-ATI R580 (X1900) .*R580.* 3 1
-ATI RC410 (Xpress 200) .*RC410.* 0 0
-ATI RS48x (Xpress 200x) .*RS48.* 0 0
-ATI RS600 (Xpress 3200) .*RS600.* 0 0
-ATI RV350 (9600) .*RV350.* 0 1
-ATI RV370 (X300) .*RV370.* 0 1
-ATI RV410 (X700) .*RV410.* 1 1
-ATI RV515 .*RV515.* 1 1
-ATI RV570 (X1900 GT/PRO) .*RV570.* 3 1
-ATI RV380 .*RV380.* 0 1
-ATI RV530 .*RV530.* 1 1
-ATI RX480 (Xpress 200P) .*RX480.* 0 1
-ATI RX700 .*RX700.* 1 1
-AMD ANTILLES (HD 6990) .*(AMD|ATI).*Antilles.* 3 1
-AMD BARTS (HD 6800) .*(AMD|ATI).*Barts.* 3 1
-AMD CAICOS (HD 6400) .*(AMD|ATI).*Caicos.* 3 1
-AMD CAYMAN (HD 6900) .*(AMD|ATI).*(Cayman|CAYMAM).* 3 1
-AMD CEDAR (HD 5450) .*(AMD|ATI).*Cedar.* 2 1
-AMD CYPRESS (HD 5800) .*(AMD|ATI).*Cypress.* 3 1
-AMD HEMLOCK (HD 5970) .*(AMD|ATI).*Hemlock.* 3 1
-AMD JUNIPER (HD 5700) .*(AMD|ATI).*Juniper.* 3 1
-AMD PARK .*(AMD|ATI).*Park.* 3 1
-AMD REDWOOD (HD 5500/5600) .*(AMD|ATI).*Redwood.* 3 1
-AMD TURKS (HD 6500/6600) .*(AMD|ATI).*Turks.* 3 1
-AMD RS780 (HD 3200) .*RS780.* 0 1
-AMD RS880 (HD 4200) .*RS880.* 1 1
-AMD RV610 (HD 2400) .*RV610.* 1 1
-AMD RV620 (HD 3400) .*RV620.* 1 1
-AMD RV630 (HD 2600) .*RV630.* 2 1
-AMD RV635 (HD 3600) .*RV635.* 3 1
-AMD RV670 (HD 3800) .*RV670.* 3 1
-AMD R680 (HD 3870 X2) .*R680.* 3 1
-AMD R700 (HD 4800 X2) .*R700.* 3 1
-AMD RV710 (HD 4300) .*RV710.* 1 1
-AMD RV730 (HD 4600) .*RV730.* 3 1
-AMD RV740 (HD 4700) .*RV740.* 3 1
-AMD RV770 (HD 4800) .*RV770.* 3 1
-AMD RV790 (HD 4800) .*RV790.* 3 1
-ATI 760G/Radeon 3000 .*ATI.*AMD 760G.* 1 1
-ATI 780L/Radeon 3000 .*ATI.*AMD 780L.* 1 1
-ATI Radeon DDR .*ATI.*Radeon ?DDR.* 0 1
-ATI FirePro 2000 .*ATI.*FirePro 2.* 1 1
-ATI FirePro 3000 .*ATI.*FirePro V3.* 1 1
-ATI FirePro 4000 .*ATI.*FirePro V4.* 2 1
-ATI FirePro 5000 .*ATI.*FirePro V5.* 3 1
-ATI FirePro 7000 .*ATI.*FirePro V7.* 3 1
-ATI FirePro M .*ATI.*FirePro M.* 3 1
-ATI Technologies .*ATI *Technologies.* 0 1
-// This entry is last to work around the "R300" driver problem.
-ATI R300 (9700) .*R300.* 1 1
-ATI Radeon .*ATI.*(Diamond|Radeon).* 0 1
-Intel X3100 .*Intel.*X3100.* 0 1
-Intel 830M .*Intel.*830M 0 0
-Intel 845G .*Intel.*845G 0 0
-Intel 855GM .*Intel.*855GM 0 0
-Intel 865G .*Intel.*865G 0 0
-Intel 900 .*Intel.*900.*900 0 0
-Intel 915GM .*Intel.*915GM 0 0
-Intel 915G .*Intel.*915G 0 0
-Intel 945GM .*Intel.*945GM.* 0 1
-Intel 945G .*Intel.*945G.* 0 1
-Intel 950 .*Intel.*950.* 0 1
-Intel 965 .*Intel.*965.* 0 1
-Intel G33 .*Intel.*G33.* 0 0
-Intel G41 .*Intel.*G41.* 0 1
-Intel G45 .*Intel.*G45.* 0 1
-Intel Bear Lake .*Intel.*Bear Lake.* 0 0
-Intel Broadwater .*Intel.*Broadwater.* 0 0
-Intel Brookdale .*Intel.*Brookdale.* 0 0
-Intel Cantiga .*Intel.*Cantiga.* 0 0
-Intel Eaglelake .*Intel.*Eaglelake.* 0 1
-Intel Graphics Media HD .*Intel.*Graphics Media.*HD.* 0 1
-Intel HD Graphics .*Intel.*HD Graphics.* 2 1
-Intel Mobile 4 Series .*Intel.*Mobile.* 4 Series.* 0 1
-Intel Media Graphics HD .*Intel.*Media Graphics HD.* 0 1
-Intel Montara .*Intel.*Montara.* 0 0
-Intel Pineview .*Intel.*Pineview.* 0 1
-Intel Springdale .*Intel.*Springdale.* 0 0
-Intel HD Graphics 2000 .*Intel.*HD2000.* 1 1
-Intel HD Graphics 3000 .*Intel.*HD3000.* 2 1
-Matrox .*Matrox.* 0 0
-Mesa .*Mesa.* 0 0
-NVIDIA 205 .*NVIDIA .*GeForce 205.* 2 1
-NVIDIA 210 .*NVIDIA .*GeForce 210.* 2 1
-NVIDIA 310M .*NVIDIA .*GeForce 310M.* 1 1
-NVIDIA 310 .*NVIDIA .*GeForce 310.* 3 1
-NVIDIA 315M .*NVIDIA .*GeForce 315M.* 2 1
-NVIDIA 315 .*NVIDIA .*GeForce 315.* 3 1
-NVIDIA 320M .*NVIDIA .*GeForce 320M.* 2 1
-NVIDIA G100M .*NVIDIA .*100M.* 0 1
-NVIDIA G100 .*NVIDIA .*100.* 0 1
-NVIDIA G102M .*NVIDIA .*102M.* 0 1
-NVIDIA G103M .*NVIDIA .*103M.* 0 1
-NVIDIA G105M .*NVIDIA .*105M.* 0 1
-NVIDIA G 110M .*NVIDIA .*110M.* 0 1
-NVIDIA G 120M .*NVIDIA .*120M.* 1 1
-NVIDIA G 200 .*NVIDIA .*200(M)?.* 0 1
-NVIDIA G 205M .*NVIDIA .*205(M)?.* 0 1
-NVIDIA G 210 .*NVIDIA .*210(M)?.* 1 1
-NVIDIA 305M .*NVIDIA .*305(M)?.* 1 1
-NVIDIA G 310M .*NVIDIA .*310(M)?.* 2 1
-NVIDIA G 315 .*NVIDIA .*315(M)?.* 2 1
-NVIDIA G 320M .*NVIDIA .*320(M)?.* 2 1
-NVIDIA G 405 .*NVIDIA .*405(M)?.* 1 1
-NVIDIA G 410M .*NVIDIA .*410(M)?.* 1 1
-NVIDIA GT 120M .*NVIDIA .*GT *120(M)?.* 2 1
-NVIDIA GT 120 .*NVIDIA .*GT.*120 2 1
-NVIDIA GT 130M .*NVIDIA .*GT *130(M)?.* 2 1
-NVIDIA GT 140M .*NVIDIA .*GT *140(M)?.* 2 1
-NVIDIA GT 150M .*NVIDIA .*GT(S)? *150(M)?.* 2 1
-NVIDIA GT 160M .*NVIDIA .*GT *160(M)?.* 2 1
-NVIDIA GT 220M .*NVIDIA .*GT *220(M)?.* 2 1
-NVIDIA GT 230M .*NVIDIA .*GT *230(M)?.* 2 1
-NVIDIA GT 240M .*NVIDIA .*GT *240(M)?.* 2 1
-NVIDIA GT 250M .*NVIDIA .*GT *250(M)?.* 2 1
-NVIDIA GT 260M .*NVIDIA .*GT *260(M)?.* 2 1
-NVIDIA GT 320M .*NVIDIA .*GT *320(M)?.* 2 1
-NVIDIA GT 325M .*NVIDIA .*GT *325(M)?.* 0 1
-NVIDIA GT 330M .*NVIDIA .*GT *330(M)?.* 3 1
-NVIDIA GT 335M .*NVIDIA .*GT *335(M)?.* 1 1
-NVIDIA GT 340M .*NVIDIA .*GT *340(M)?.* 2 1
-NVIDIA GT 415M .*NVIDIA .*GT *415(M)?.* 2 1
-NVIDIA GT 420M .*NVIDIA .*GT *420(M)?.* 2 1
-NVIDIA GT 425M .*NVIDIA .*GT *425(M)?.* 3 1
-NVIDIA GT 430M .*NVIDIA .*GT *430(M)?.* 3 1
-NVIDIA GT 435M .*NVIDIA .*GT *435(M)?.* 3 1
-NVIDIA GT 440M .*NVIDIA .*GT *440(M)?.* 3 1
-NVIDIA GT 445M .*NVIDIA .*GT *445(M)?.* 3 1
-NVIDIA GT 450M .*NVIDIA .*GT *450(M)?.* 3 1
-NVIDIA GT 520M .*NVIDIA .*GT *52.(M)?.* 3 1
-NVIDIA GT 530M .*NVIDIA .*GT *530(M)?.* 3 1
-NVIDIA GT 540M .*NVIDIA .*GT *54.(M)?.* 3 1
-NVIDIA GT 550M .*NVIDIA .*GT *550(M)?.* 3 1
-NVIDIA GT 555M .*NVIDIA .*GT *555(M)?.* 3 1
-NVIDIA GTS 160M .*NVIDIA .*GT(S)? *160(M)?.* 2 1
-NVIDIA GTS 240 .*NVIDIA .*GTS *24.* 3 1
-NVIDIA GTS 250 .*NVIDIA .*GTS *25.* 3 1
-NVIDIA GTS 350M .*NVIDIA .*GTS *350M.* 3 1
-NVIDIA GTS 360M .*NVIDIA .*GTS *360M.* 3 1
-NVIDIA GTS 360 .*NVIDIA .*GTS *360.* 3 1
-NVIDIA GTS 450 .*NVIDIA .*GTS *45.* 3 1
-NVIDIA GTX 260 .*NVIDIA .*GTX *26.* 3 1
-NVIDIA GTX 275 .*NVIDIA .*GTX *275.* 3 1
-NVIDIA GTX 270 .*NVIDIA .*GTX *27.* 3 1
-NVIDIA GTX 285 .*NVIDIA .*GTX *285.* 3 1
-NVIDIA GTX 280 .*NVIDIA .*GTX *280.* 3 1
-NVIDIA GTX 290 .*NVIDIA .*GTX *290.* 3 1
-NVIDIA GTX 295 .*NVIDIA .*GTX *295.* 3 1
-NVIDIA GTX 460M .*NVIDIA .*GTX *460M.* 3 1
-NVIDIA GTX 465 .*NVIDIA .*GTX *465.* 3 1
-NVIDIA GTX 460 .*NVIDIA .*GTX *46.* 3 1
-NVIDIA GTX 470M .*NVIDIA .*GTX *470M.* 3 1
-NVIDIA GTX 470 .*NVIDIA .*GTX *47.* 3 1
-NVIDIA GTX 480M .*NVIDIA .*GTX *480M.* 3 1
-NVIDIA GTX 485M .*NVIDIA .*GTX *485M.* 3 1
-NVIDIA GTX 480 .*NVIDIA .*GTX *48.* 3 1
-NVIDIA GTX 530 .*NVIDIA .*GTX *53.* 3 1
-NVIDIA GTX 550 .*NVIDIA .*GTX *55.* 3 1
-NVIDIA GTX 560 .*NVIDIA .*GTX *56.* 3 1
-NVIDIA GTX 570 .*NVIDIA .*GTX *57.* 3 1
-NVIDIA GTX 580M .*NVIDIA .*GTX *580M.* 3 1
-NVIDIA GTX 580 .*NVIDIA .*GTX *58.* 3 1
-NVIDIA GTX 590 .*NVIDIA .*GTX *59.* 3 1
-NVIDIA C51 .*NVIDIA .*C51.* 0 1
-NVIDIA G72 .*NVIDIA .*G72.* 1 1
-NVIDIA G73 .*NVIDIA .*G73.* 1 1
-NVIDIA G84 .*NVIDIA .*G84.* 2 1
-NVIDIA G86 .*NVIDIA .*G86.* 3 1
-NVIDIA G92 .*NVIDIA .*G92.* 3 1
-NVIDIA GeForce .*GeForce 256.* 0 0
-NVIDIA GeForce 2 .*GeForce ?2 ?.* 0 1
-NVIDIA GeForce 3 .*GeForce ?3 ?.* 0 1
-NVIDIA GeForce 3 Ti .*GeForce ?3 Ti.* 0 1
-NVIDIA GeForce 4 .*NVIDIA .*GeForce ?4.* 0 1
-NVIDIA GeForce 4 Go .*NVIDIA .*GeForce ?4.*Go.* 0 1
-NVIDIA GeForce 4 MX .*NVIDIA .*GeForce ?4 MX.* 0 1
-NVIDIA GeForce 4 PCX .*NVIDIA .*GeForce ?4 PCX.* 0 1
-NVIDIA GeForce 4 Ti .*NVIDIA .*GeForce ?4 Ti.* 0 1
-NVIDIA GeForce 6100 .*NVIDIA .*GeForce 61.* 0 1
-NVIDIA GeForce 6200 .*NVIDIA .*GeForce 62.* 0 1
-NVIDIA GeForce 6500 .*NVIDIA .*GeForce 65.* 0 1
-NVIDIA GeForce 6600 .*NVIDIA .*GeForce 66.* 1 1
-NVIDIA GeForce 6700 .*NVIDIA .*GeForce 67.* 2 1
-NVIDIA GeForce 6800 .*NVIDIA .*GeForce 68.* 2 1
-NVIDIA GeForce 7000 .*NVIDIA .*GeForce 70.* 0 1
-NVIDIA GeForce 7100 .*NVIDIA .*GeForce 71.* 0 1
-NVIDIA GeForce 7200 .*NVIDIA .*GeForce 72.* 1 1
-NVIDIA GeForce 7300 .*NVIDIA .*GeForce 73.* 1 1
-NVIDIA GeForce 7500 .*NVIDIA .*GeForce 75.* 1 1
-NVIDIA GeForce 7600 .*NVIDIA .*GeForce 76.* 2 1
-NVIDIA GeForce 7800 .*NVIDIA .*GeForce 78.* 2 1
-NVIDIA GeForce 7900 .*NVIDIA .*GeForce 79.* 2 1
-NVIDIA GeForce 8100 .*NVIDIA .*GeForce 81.* 1 1
-NVIDIA GeForce 8200M .*NVIDIA .*GeForce 8200M.* 1 1
-NVIDIA GeForce 8200 .*NVIDIA .*GeForce 82.* 1 1
-NVIDIA GeForce 8300 .*NVIDIA .*GeForce 83.* 2 1
-NVIDIA GeForce 8400M .*NVIDIA .*GeForce 8400M.* 2 1
-NVIDIA GeForce 8400 .*NVIDIA .*GeForce 84.* 2 1
-NVIDIA GeForce 8500 .*NVIDIA .*GeForce 85.* 3 1
-NVIDIA GeForce 8600M .*NVIDIA .*GeForce 8600M.* 2 1
-NVIDIA GeForce 8600 .*NVIDIA .*GeForce 86.* 3 1
-NVIDIA GeForce 8700M .*NVIDIA .*GeForce 8700M.* 3 1
-NVIDIA GeForce 8700 .*NVIDIA .*GeForce 87.* 3 1
-NVIDIA GeForce 8800M .*NVIDIA .*GeForce 8800M.* 3 1
-NVIDIA GeForce 8800 .*NVIDIA .*GeForce 88.* 3 1
-NVIDIA GeForce 9100M .*NVIDIA .*GeForce 9100M.* 0 1
-NVIDIA GeForce 9100 .*NVIDIA .*GeForce 91.* 0 1
-NVIDIA GeForce 9200M .*NVIDIA .*GeForce 9200M.* 1 1
-NVIDIA GeForce 9200 .*NVIDIA .*GeForce 92.* 1 1
-NVIDIA GeForce 9300M .*NVIDIA .*GeForce 9300M.* 2 1
-NVIDIA GeForce 9300 .*NVIDIA .*GeForce 93.* 2 1
-NVIDIA GeForce 9400M .*NVIDIA .*GeForce 9400M.* 2 1
-NVIDIA GeForce 9400 .*NVIDIA .*GeForce 94.* 2 1
-NVIDIA GeForce 9500M .*NVIDIA .*GeForce 9500M.* 2 1
-NVIDIA GeForce 9500 .*NVIDIA .*GeForce 95.* 2 1
-NVIDIA GeForce 9600M .*NVIDIA .*GeForce 9600M.* 3 1
-NVIDIA GeForce 9600 .*NVIDIA .*GeForce 96.* 2 1
-NVIDIA GeForce 9700M .*NVIDIA .*GeForce 9700M.* 2 1
-NVIDIA GeForce 9800M .*NVIDIA .*GeForce 9800M.* 3 1
-NVIDIA GeForce 9800 .*NVIDIA .*GeForce 98.* 3 1
-NVIDIA GeForce FX 5100 .*NVIDIA .*GeForce FX 51.* 0 1
-NVIDIA GeForce FX 5200 .*NVIDIA .*GeForce FX 52.* 0 1
-NVIDIA GeForce FX 5300 .*NVIDIA .*GeForce FX 53.* 0 1
-NVIDIA GeForce FX 5500 .*NVIDIA .*GeForce FX 55.* 0 1
-NVIDIA GeForce FX 5600 .*NVIDIA .*GeForce FX 56.* 0 1
-NVIDIA GeForce FX 5700 .*NVIDIA .*GeForce FX 57.* 1 1
-NVIDIA GeForce FX 5800 .*NVIDIA .*GeForce FX 58.* 1 1
-NVIDIA GeForce FX 5900 .*NVIDIA .*GeForce FX 59.* 1 1
-NVIDIA GeForce FX Go5100 .*NVIDIA .*GeForce FX Go51.* 0 1
-NVIDIA GeForce FX Go5200 .*NVIDIA .*GeForce FX Go52.* 0 1
-NVIDIA GeForce FX Go5300 .*NVIDIA .*GeForce FX Go53.* 0 1
-NVIDIA GeForce FX Go5500 .*NVIDIA .*GeForce FX Go55.* 0 1
-NVIDIA GeForce FX Go5600 .*NVIDIA .*GeForce FX Go56.* 0 1
-NVIDIA GeForce FX Go5700 .*NVIDIA .*GeForce FX Go57.* 1 1
-NVIDIA GeForce FX Go5800 .*NVIDIA .*GeForce FX Go58.* 1 1
-NVIDIA GeForce FX Go5900 .*NVIDIA .*GeForce FX Go59.* 1 1
-NVIDIA GeForce FX Go5xxx .*NVIDIA .*GeForce FX Go.* 0 1
-NVIDIA GeForce Go 6100 .*NVIDIA .*GeForce Go 61.* 0 1
-NVIDIA GeForce Go 6200 .*NVIDIA .*GeForce Go 62.* 0 1
-NVIDIA GeForce Go 6400 .*NVIDIA .*GeForce Go 64.* 1 1
-NVIDIA GeForce Go 6500 .*NVIDIA .*GeForce Go 65.* 1 1
-NVIDIA GeForce Go 6600 .*NVIDIA .*GeForce Go 66.* 1 1
-NVIDIA GeForce Go 6700 .*NVIDIA .*GeForce Go 67.* 1 1
-NVIDIA GeForce Go 6800 .*NVIDIA .*GeForce Go 68.* 1 1
-NVIDIA GeForce Go 7200 .*NVIDIA .*GeForce Go 72.* 1 1
-NVIDIA GeForce Go 7300 LE .*NVIDIA .*GeForce Go 73.*LE.* 0 1
-NVIDIA GeForce Go 7300 .*NVIDIA .*GeForce Go 73.* 1 1
-NVIDIA GeForce Go 7400 .*NVIDIA .*GeForce Go 74.* 1 1
-NVIDIA GeForce Go 7600 .*NVIDIA .*GeForce Go 76.* 2 1
-NVIDIA GeForce Go 7700 .*NVIDIA .*GeForce Go 77.* 2 1
-NVIDIA GeForce Go 7800 .*NVIDIA .*GeForce Go 78.* 2 1
-NVIDIA GeForce Go 7900 .*NVIDIA .*GeForce Go 79.* 2 1
-NVIDIA D9M .*NVIDIA .*D9M.* 1 1
-NVIDIA G94 .*NVIDIA .*G94.* 3 1
-NVIDIA GeForce Go 6 .*GeForce Go 6.* 1 1
-NVIDIA ION 2 .*NVIDIA .*ION 2.* 2 1
-NVIDIA ION .*NVIDIA .*ION.* 2 1
-NVIDIA NB8M .*NVIDIA .*NB8M.* 1 1
-NVIDIA NB8P .*NVIDIA .*NB8P.* 2 1
-NVIDIA NB9E .*NVIDIA .*NB9E.* 3 1
-NVIDIA NB9M .*NVIDIA .*NB9M.* 1 1
-NVIDIA NB9P .*NVIDIA .*NB9P.* 2 1
-NVIDIA N10 .*NVIDIA .*N10.* 1 1
-NVIDIA GeForce PCX .*GeForce PCX.* 0 1
-NVIDIA Generic .*NVIDIA .*Unknown.* 0 0
-NVIDIA NV17 .*NVIDIA .*NV17.* 0 1
-NVIDIA NV34 .*NVIDIA .*NV34.* 0 1
-NVIDIA NV35 .*NVIDIA .*NV35.* 0 1
-NVIDIA NV36 .*NVIDIA .*NV36.* 1 1
-NVIDIA NV41 .*NVIDIA .*NV41.* 1 1
-NVIDIA NV43 .*NVIDIA .*NV43.* 1 1
-NVIDIA NV44 .*NVIDIA .*NV44.* 1 1
-NVIDIA nForce .*NVIDIA .*nForce.* 0 0
-NVIDIA MCP51 .*NVIDIA .*MCP51.* 1 1
-NVIDIA MCP61 .*NVIDIA .*MCP61.* 1 1
-NVIDIA MCP67 .*NVIDIA .*MCP67.* 1 1
-NVIDIA MCP68 .*NVIDIA .*MCP68.* 1 1
-NVIDIA MCP73 .*NVIDIA .*MCP73.* 1 1
-NVIDIA MCP77 .*NVIDIA .*MCP77.* 1 1
-NVIDIA MCP78 .*NVIDIA .*MCP78.* 1 1
-NVIDIA MCP79 .*NVIDIA .*MCP79.* 1 1
-NVIDIA MCP7A .*NVIDIA .*MCP7A.* 1 1
-NVIDIA Quadro2 .*Quadro2.* 0 1
-NVIDIA Quadro 1000M .*Quadro.*1000M.* 2 1
-NVIDIA Quadro 2000 M/D .*Quadro.*2000.* 3 1
-NVIDIA Quadro 3000M .*Quadro.*3000M.* 3 1
-NVIDIA Quadro 4000M .*Quadro.*4000M.* 3 1
-NVIDIA Quadro 4000 .*Quadro *4000.* 3 1
-NVIDIA Quadro 50x0 M .*Quadro.*50.0.* 3 1
-NVIDIA Quadro 6000 .*Quadro.*6000.* 3 1
-NVIDIA Quadro 400 .*Quadro.*400.* 2 1
-NVIDIA Quadro 600 .*Quadro.*600.* 2 1
-NVIDIA Quadro4 .*Quadro4.* 0 1
-NVIDIA Quadro DCC .*Quadro DCC.* 0 1
-NVIDIA Quadro CX .*Quadro.*CX.* 3 1
-NVIDIA Quadro FX 770M .*Quadro.*FX *770M.* 2 1
-NVIDIA Quadro FX 1500M .*Quadro.*FX *1500M.* 1 1
-NVIDIA Quadro FX 1600M .*Quadro.*FX *1600M.* 2 1
-NVIDIA Quadro FX 2500M .*Quadro.*FX *2500M.* 2 1
-NVIDIA Quadro FX 2700M .*Quadro.*FX *2700M.* 3 1
-NVIDIA Quadro FX 2800M .*Quadro.*FX *2800M.* 3 1
-NVIDIA Quadro FX 3500 .*Quadro.*FX *3500.* 2 1
-NVIDIA Quadro FX 3600 .*Quadro.*FX *3600.* 3 1
-NVIDIA Quadro FX 3700 .*Quadro.*FX *3700.* 3 1
-NVIDIA Quadro FX 3800 .*Quadro.*FX *3800.* 3 1
-NVIDIA Quadro FX 4500 .*Quadro.*FX *45.* 3 1
-NVIDIA Quadro FX 880M .*Quadro.*FX *880M.* 3 1
-NVIDIA Quadro FX 4800 .*NVIDIA .*Quadro *FX *4800.* 3 1
-NVIDIA Quadro FX .*Quadro FX.* 1 1
-NVIDIA Quadro NVS 1xxM .*Quadro NVS *1.[05]M.* 0 1
-NVIDIA Quadro NVS 300M .*NVIDIA .*NVS *300M.* 2 1
-NVIDIA Quadro NVS 320M .*NVIDIA .*NVS *320M.* 2 1
-NVIDIA Quadro NVS 2100M .*NVIDIA .*NVS *2100M.* 2 1
-NVIDIA Quadro NVS 3100M .*NVIDIA .*NVS *3100M.* 2 1
-NVIDIA Quadro NVS 4200M .*NVIDIA .*NVS *4200M.* 2 1
-NVIDIA Quadro NVS 5100M .*NVIDIA .*NVS *5100M.* 2 1
-NVIDIA Quadro NVS .*NVIDIA .*NVS 0 1
-NVIDIA RIVA TNT .*RIVA TNT.* 0 0
-S3 .*S3 Graphics.* 0 0
-SiS SiS.* 0 0
-Trident Trident.* 0 0
-Tungsten Graphics Tungsten.* 0 0
-XGI XGI.* 0 0
-VIA VIA.* 0 0
-Apple Generic Apple.*Generic.* 0 0
-Apple Software Renderer Apple.*Software Renderer.* 0 0
-Humper Humper.* 0 1
+3Dfx .*3Dfx.* 0 0 0 0
+3Dlabs .*3Dlabs.* 0 0 0 0
+ATI 3D-Analyze .*ATI.*3D-Analyze.* 0 0 0 0
+ATI All-in-Wonder 7500 .*ATI.*All-in-Wonder 75.* 0 1 0 0
+ATI All-in-Wonder 8500 .*ATI.*All-in-Wonder 85.* 0 1 0 0
+ATI All-in-Wonder 9200 .*ATI.*All-in-Wonder 92.* 0 1 0 0
+ATI All-in-Wonder 9xxx .*ATI.*All-in-Wonder 9.* 1 1 0 2.1
+ATI All-in-Wonder HD .*ATI.*All-in-Wonder HD.* 1 1 1 3.3
+ATI All-in-Wonder X600 .*ATI.*All-in-Wonder X6.* 1 1 0 0
+ATI All-in-Wonder X800 .*ATI.*All-in-Wonder X8.* 1 1 1 2.1
+ATI All-in-Wonder X1800 .*ATI.*All-in-Wonder X18.* 3 1 0 0
+ATI All-in-Wonder X1900 .*ATI.*All-in-Wonder X19.* 3 1 0 0
+ATI All-in-Wonder PCI-E .*ATI.*All-in-Wonder.*PCI-E.* 1 1 0 0
+ATI All-in-Wonder Radeon .*ATI.*All-in-Wonder Radeon.* 0 1 0 0
+ATI Radeon X1300 .*ATI.*(ASUS|Radeon).*X13.* 2 1 1 2.1
+ATI Radeon X1500 .*ATI.*(ASUS|Radeon).*X15.* 2 1 1 2.1
+ATI Radeon X1600 .*ATI.*(ASUS|Radeon).*X16.* 2 1 1 2.1
+ATI Radeon X1700 .*ATI.*(ASUS|Radeon).*X17.* 2 1 1 2.1
+ATI Radeon X1800 .*ATI.*(Radeon|Diamond) X18.* ?.* 3 1 1 2.1
+ATI Radeon X1900 .*ATI.*(Radeon|Diamond|ASUS) X19.* ?.* 2 1 1 2.1
+ATI Radeon X17xx .*ATI.*(Radeon|Diamond) X17.* ?.* 1 1 1 2.1
+ATI Radeon X16xx .*ATI.*(Radeon|Diamond) X17.* ?.* 1 1 1 2.1
+ATI Radeon X28xx .*ATI.*(Radeon|Diamond) X28.. ?.* 1 1 1 2.1
+ATI Display Adapter .*ATI.*display adapter.* 1 1 1 4.1
+ATI FireGL 5200 .*ATI.*FireGL V52.* 1 1 1 2.1
+ATI FireGL 5xxx .*ATI.*FireGL V5.* 2 1 1 3.3
+ATI FireGL .*ATI.*Fire.*GL.* 4 1 1 4.2
+ATI FirePro M3900 .*ATI.*FirePro.*M39.* 2 1 0 4.1
+ATI FirePro M5800 .*ATI.*FirePro.*M58.* 3 1 0 0
+ATI FirePro M7740 .*ATI.*FirePro.*M77.* 3 1 0 0
+ATI FirePro M7820 .*ATI.*FirePro.*M78.* 5 1 1 4.2
+ATI FireMV .*ATI.*FireMV.* 0 1 1 3.2
+ATI Generic .*ATI.*Generic.* 0 0 0 0
+ATI Hercules 9800 .*ATI.*Hercules.* 9800.* 1 1 0 0
+ATI IGP 340M .*ATI.*IGP.* 34[0-9]M.* 0 0 0 1.3
+ATI M52 .*ATI.*M52.* 1 1 0 0
+ATI M54 .*ATI.*M54.* 1 1 0 0
+ATI M56 .*ATI.*M56.* 1 1 0 0
+ATI M71 .*ATI.*M71.* 1 1 0 0
+ATI M72 .*ATI.*M72.* 1 1 0 0
+ATI M76 .*ATI.*M76.* 3 1 0 0
+ATI Radeon HD 6300M .*ATI.*AMD Radeon.* (HD|HD )63..M 2 1 1 4.2
+ATI Radeon HD 6400M .*ATI.*AMD Radeon.* (HD|HD )64..M 2 1 1 4.2
+ATI Radeon HD 6500M .*ATI.*AMD Radeon.* (HD|HD )65..M 2 1 1 4.2
+ATI Radeon HD 6600M .*ATI.*AMD Radeon.* (HD 6|6)6..M 3 1 1 4.2
+ATI Radeon HD 6700M .*ATI.*AMD Radeon.* (HD|HD )67..M 3 1 1 4.2
+ATI Radeon HD 6800M .*ATI.*AMD Radeon.* (HD|HD )68..M 3 1 1 4.2
+ATI Radeon HD 6300G .*ATI.*AMD Radeon.* (HD|HD )63..G 2 1 1 4.2
+ATI Radeon HD 6400G .*ATI.*AMD Radeon.* (HD|HD )64..G 2 1 1 4.2
+ATI Radeon HD 6500G .*ATI.*AMD Radeon.* (HD|HD )65..G 2 1 1 4.2
+ATI Radeon HD 6600G .*ATI.*AMD Radeon.* (HD|HD )66..G 3 1 1 4.2
+ATI Radeon HD 7100 .*ATI.*(Radeon|ASUS).* (HD|HD )71.* 2 1 0 0
+ATI Radeon HD 7200 .*ATI.*(Radeon|ASUS).* (HD|HD )72.* 2 1 0 4.2
+ATI Radeon HD 7300 .*ATI.*(Radeon|ASUS).* (HD|HD )73.* 2 1 0 4.2
+ATI Radeon HD 7400 .*ATI.*(Radeon|ASUS).* (HD|HD )74.* 2 1 0 4.2
+ATI Radeon HD 7500 .*ATI.*(Radeon|ASUS).* (HD|HD )75.* 3 1 1 4.2
+ATI Radeon HD 7600 .*ATI.*(Radeon|ASUS).* (HD|HD )76.* 3 1 0 4.2
+ATI Radeon HD 7700 .*ATI.*(Radeon|ASUS).* (HD|HD )77.* 4 1 1 4.2
+ATI Radeon HD 7800 .*ATI.*(Radeon|ASUS).* (HD|HD )78.* 5 1 1 4.2
+ATI Radeon HD 7900 .*ATI.*(Radeon|ASUS).* (HD|HD )79.* 5 1 1 4.2
+ATI Radeon HD 7000 Series .*ATI.*(Radeon|ASUS).* (HD|HD )7000 Series.* 3 1 1 4.2
+ATI Mobility Radeon 4100 .*ATI.*Mobility.* 41.. 1 1 1 3.3
+ATI Mobility Radeon 5000 .*ATI.*Mobility.* 50.. 1 1 1 4.2
+ATI Mobility Radeon 7xxx .*ATI.*Mobility.*Radeon 7.* 0 1 1 1.3
+ATI Mobility Radeon 8xxx .*ATI.*Mobility.*Radeon 8.* 0 1 0 0
+ATI Mobility Radeon 9800 .*ATI.*Mobility.* 98.* 1 1 0 0
+ATI Mobility Radeon 9700 .*ATI.*Mobility.* 97.* 0 1 1 2.1
+ATI Mobility Radeon 9600 .*ATI.*Mobility.* 96.* 1 1 1 2.1
+ATI Mobility Radeon HD 530v .*ATI.*Mobility.*HD 530v.* 1 1 1 3.3
+ATI Mobility Radeon HD 540v .*ATI.*Mobility.*HD 540v.* 1 1 1 3.3
+ATI Mobility Radeon HD 545v .*ATI.*Mobility.*HD 545v.* 2 1 1 4
+ATI Mobility Radeon HD 550v .*ATI.*Mobility.*HD 550v.* 3 1 1 4
+ATI Mobility Radeon HD 560v .*ATI.*Mobility.*HD 560v.* 3 1 1 3.2
+ATI Mobility Radeon HD 565v .*ATI.*Mobility.*HD 565v.* 3 1 1 3.3
+ATI Mobility Radeon HD 2300 .*ATI.*Mobility.*HD 23.* 0 1 1 2.1
+ATI Mobility Radeon HD 2400 .*ATI.*Mobility.*HD 24.* 1 1 1 3.3
+ATI Mobility Radeon HD 2600 .*ATI.*Mobility.*HD 26.* 1 1 1 3.3
+ATI Mobility Radeon HD 2700 .*ATI.*Mobility.*HD 27.* 3 1 0 0
+ATI Mobility Radeon HD 3100 .*ATI.*Mobility.*HD 31.* 0 1 0 0
+ATI Mobility Radeon HD 3200 .*ATI.*Mobility.*HD 32.* 0 1 0 0
+ATI Mobility Radeon HD 3400 .*ATI.*Mobility.*HD 34.* 1 1 1 4
+ATI Mobility Radeon HD 3600 .*ATI.*Mobility.*HD 36.* 1 1 1 4
+ATI Mobility Radeon HD 3800 .*ATI.*Mobility.*HD 38.* 3 1 1 3.3
+ATI Mobility Radeon HD 4200 .*ATI.*Mobility.*HD 42.* 1 1 1 4
+ATI Mobility Radeon HD 4300 .*ATI.*Mobility.*(HD |HD)43.* 1 1 1 4
+ATI Mobility Radeon HD 4500 .*ATI.*Mobility.*HD 45.* 1 1 1 4
+ATI Mobility Radeon HD 4600 .*ATI.*Mobility.*HD 46.* 2 1 1 3.3
+ATI Mobility Radeon HD 4800 .*ATI.*Mobility.*HD 48.* 3 1 1 3.3
+ATI Mobility Radeon HD 5000 Series .*ATI.*Mobility.*HD 50.* 3 1 1 3.2
+ATI Mobility Radeon HD 5100 .*ATI.*Mobility.*HD 51.* 3 1 1 3.2
+ATI Mobility Radeon HD 5300 .*ATI.*Mobility.*HD 53.* 3 1 0 0
+ATI Mobility Radeon HD 5400 .*ATI.*Mobility.*HD 54.* 2 1 1 4.2
+ATI Mobility Radeon HD 5500 .*ATI.*Mobility.*HD 55.* 3 1 0 4.2
+ATI Mobility Radeon HD 5600 .*ATI.*Mobility.*HD 56.* 3 1 1 4.2
+ATI Mobility Radeon HD 5700 .*ATI.*Mobility.*HD 57.* 3 1 1 4.1
+ATI Mobility Radeon HD 6200 .*ATI.*Mobility.*HD 62.* 3 1 0 0
+ATI Mobility Radeon HD 6300 .*ATI.*Mobility.*HD 63.* 3 1 1 4.2
+ATI Mobility Radeon HD 6400M .*ATI.*Mobility.*HD 64.* 3 1 0 0
+ATI Mobility Radeon HD 6500M .*ATI.*Mobility.*HD 65.* 5 1 1 4.2
+ATI Mobility Radeon HD 6600M .*ATI.*Mobility.*HD 66.* 5 1 0 0
+ATI Mobility Radeon HD 6700M .*ATI.*Mobility.*HD 67.* 5 1 0 0
+ATI Mobility Radeon HD 6800M .*ATI.*Mobility.*HD 68.* 5 1 0 0
+ATI Mobility Radeon HD 6900M .*ATI.*Mobility.*HD 69.* 5 1 0 0
+ATI Mobility Radeon Graphics .*ATI Mobility Radeon Graphics.* 1 1 0 4
+ATI Radeon HD 2300 .*ATI.*Radeon.* (HD|HD )23.. 0 1 1 3.3
+ATI Radeon HD 2400 .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)24.. 1 1 1 4
+ATI Radeon HD 2600 .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)26.. 2 1 1 4
+ATI Radeon HD 2900 .*ATI.*Radeon.* (HD|HD )29.. 3 1 1 3.3
+ATI Radeon HD 3000 .*ATI.*Radeon.* (HD|HD )30.. 0 1 0 0
+ATI Radeon HD 3100 .*ATI.*Radeon.* (HD|HD )31.. 1 1 0 0
+ATI Radeon HD 3200 .*ATI.*Radeon.* (HD|HD )32.. 1 1 1 4
+ATI Radeon HD 3300 .*ATI.*Radeon.* (HD|HD )33.. 1 1 1 3.3
+ATI Radeon HD 3400 .*ATI.*(Radeon|ASUS).* (HD|HD |AH|EAH)34.. 1 1 1 4
+ATI Radeon HD 3500 .*ATI.*Radeon.* (HD|HD )35.. 2 1 0 0
+ATI Radeon HD 3600 .*ATI.*(Radeon|ASUS).* (HD|HD |AH|EAH)36.. 3 1 1 4
+ATI Radeon HD 3700 .*ATI.*Radeon.* (HD|HD )37.. 3 1 0 3.3
+ATI HD3700 .*ATI.* HD37.. 3 1 0 3.3
+ATI Radeon HD 3800 .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)38.. 3 1 1 4
+ATI Radeon HD 4100 .*ATI.*Radeon.* (HD|HD )41.. 1 1 0 0
+ATI Radeon HD 4200 .*ATI.*Radeon.* (HD|HD )42.. 1 1 1 4
+ATI Radeon HD 4300 .*ATI.*(Radeon|ASUS).* (HD4|HD 4|EAH4|4)3.. 2 1 1 4
+ATI Radeon HD 4400 .*ATI.*Radeon.* (HD|HD )44.. 2 1 0 0
+ATI Radeon HD 4500 .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)45.. 2 1 1 3.3
+ATI Radeon HD 4600 .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)46.. 3 1 1 4
+ATI Radeon HD 4700 .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)47.. 3 1 1 3.3
+ATI Radeon HD 4800 .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)48.. 3 1 1 4
+ATI Radeon HD 5400 .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)54.. 3 1 1 4.2
+ATI Radeon HD 5500 .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)55.. 3 1 1 4.2
+ATI Radeon HD 5600 .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)56.. 3 1 1 4.2
+ATI Radeon HD 5700 .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)57.. 3 1 1 4.2
+ATI Radeon HD 5800 .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)58.. 4 1 1 4.2
+ATI Radeon HD 5900 .*ATI.*Radeon.* (HD|HD )59.. 4 1 1 4.2
+ATI Radeon HD 6200 .*ATI.*Radeon.* (HD|HD )62.. 0 1 1 4.2
+ATI Radeon HD 6300 .*ATI.*Radeon.* (HD|HD )63.. 1 1 1 4.2
+ATI Radeon HD 6400 .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)64.. 3 1 1 4.2
+ATI Radeon HD 6500 .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)65.. 3 1 1 4.2
+ATI Radeon HD 6600 .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)66.. 3 1 1 4.2
+ATI Radeon HD 6700 .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)67.. 3 1 1 4.2
+ATI Radeon HD 6800 .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)68.. 4 1 1 4.2
+ATI Radeon HD 6900 .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)69.. 5 1 1 4.2
+ATI Radeon OpenGL .*ATI.*Radeon OpenGL.* 0 0 0 0
+ATI Radeon 2100 .*ATI.*Radeon 21.. 0 1 1 2.1
+ATI Radeon 3000 .*ATI.*Radeon 30.. 1 1 1 4
+ATI Radeon 3100 .*ATI.*Radeon 31.. 0 1 1 3.3
+ATI Radeon 5xxx .*ATI.*Radeon 5... 3 1 0 0
+ATI Radeon 7xxx .*ATI.*Radeon 7... 0 1 1 2
+ATI Radeon 8xxx .*ATI.*Radeon 8... 0 1 0 0
+ATI Radeon 9000 .*ATI.*Radeon 90.. 0 1 1 1.3
+ATI Radeon 9100 .*ATI.*Radeon 91.. 0 1 0 0
+ATI Radeon 9200 .*ATI.*Radeon 92.. 0 1 1 1.3
+ATI Radeon 9500 .*ATI.*Radeon 95.. 0 1 1 2.1
+ATI Radeon 9600 .*ATI.*Radeon 96.. 0 1 1 2.1
+ATI Radeon 9700 .*ATI.*Radeon 97.. 1 1 0 0
+ATI Radeon 9800 .*ATI.*Radeon 98.. 1 1 1 2.1
+ATI Radeon RV250 .*ATI.*RV250.* 0 1 0 0
+ATI Radeon RV600 .*ATI.*RV6.* 1 1 0 0
+ATI Radeon RX700 .*ATI.*RX70.* 1 1 0 0
+ATI Radeon RX800 .*ATI.*Radeon RX80.* 2 1 0 0
+ATI RS880M .*ATI.*RS880M 1 1 0 0
+ATI Radeon RX9550 .*ATI.*RX9550.* 1 1 0 0
+ATI Radeon VE .*ATI.*Radeon.*VE.* 0 0 0 0
+ATI Radeon X300 .*ATI.*Radeon X3.* 1 1 1 2.1
+ATI Radeon X400 .*ATI.*Radeon ?X4.* 0 1 0 0
+ATI Radeon X500 .*ATI.*Radeon ?X5.* 1 1 1 2.1
+ATI Radeon X600 .*ATI.*(Radeon |ASUS Extreme A)X6.* 1 1 1 2.1
+ATI Radeon X700 .*ATI.*Radeon ?X7.* 2 1 1 2.1
+ATI Radeon X800 .*ATI.*Radeon ?X8.* 1 1 1 2.1
+ATI Radeon X900 .*ATI.*Radeon ?X9.* 2 1 0 0
+ATI Radeon X1000 .*ATI.*Radeon ?X10.* 2 1 0 2.1
+ATI Radeon X1200 .*ATI.*Radeon ?X12.* 2 1 0 2.1
+ATI Radeon X1400 .*ATI.*Radeon ?X14.* 2 1 0 2.1
+ATI Radeon X2300 .*ATI.*Radeon ?X23.* 2 1 0 2.1
+ATI Radeon Xpress .*ATI.*Radeon Xpress.* 0 1 1 2.1
+ATI Rage 128 .*ATI.*Rage 128.* 0 1 0 0
+ATI R300 (9700) .*R300.* 0 1 1 2.1
+ATI R350 (9800) .*R350.* 1 1 0 0
+ATI R580 (X1900) .*R580.* 3 1 0 0
+ATI RC410 (Xpress 200) .*RC410.* 0 0 0 0
+ATI RS48x (Xpress 200x) .*RS48.* 0 0 0 0
+ATI RS600 (Xpress 3200) .*RS600.* 0 0 0 0
+ATI RV350 (9600) .*RV350.* 0 1 0 0
+ATI RV370 (X300) .*RV370.* 0 1 0 0
+ATI RV410 (X700) .*RV410.* 1 1 0 0
+ATI RV515 .*RV515.* 1 1 0 0
+ATI RV570 (X1900 GT/PRO) .*RV570.* 3 1 0 0
+ATI RV380 .*RV380.* 0 1 0 0
+ATI RV530 .*RV530.* 1 1 0 0
+ATI RX480 (Xpress 200P) .*RX480.* 0 1 0 0
+ATI RX700 .*RX700.* 1 1 0 0
+AMD ANTILLES (HD 6990) .*(AMD|ATI).*Antilles.* 3 1 0 0
+ATI ROBSON .*(AMD|ATI).*ROBSON.* 3 1 0 4
+AMD BARTS (HD 6800) .*(AMD|ATI).*Barts.* 3 1 1 2.1
+AMD WRESTLER .*(AMD|ATI).*WRESTLER.* 3 1 1 4
+AMD SUMO .*(AMD|ATI).*SUMO.* 3 1 1 4.1
+AMD CAICOS (HD 6400) .*(AMD|ATI).*Caicos.* 3 1 0 0
+AMD CAYMAN (HD 6900) .*(AMD|ATI).*(Cayman|CAYMAM).* 3 1 0 0
+AMD CEDAR (HD 5450) .*(AMD|ATI).*Cedar.* 2 1 0 2.1
+AMD CYPRESS (HD 5800) .*(AMD|ATI).*Cypress.* 3 1 0 0
+AMD HEMLOCK (HD 5970) .*(AMD|ATI).*Hemlock.* 3 1 0 0
+AMD JUNIPER (HD 5700) .*(AMD|ATI).*Juniper.* 3 1 0 0
+AMD PARK .*(AMD|ATI).*Park.* 3 1 0 0
+AMD REDWOOD (HD 5500/5600) .*(AMD|ATI).*Redwood.* 3 1 0 1.4
+AMD TURKS (HD 6500/6600) .*(AMD|ATI).*Turks.* 3 1 0 2.1
+AMD RS780 (HD 3200) .*RS780.* 0 1 1 2.1
+AMD RS880 (HD 4200) .*RS880.* 0 1 1 3.2
+AMD RV610 (HD 2400) .*RV610.* 1 1 0 0
+AMD RV620 (HD 3400) .*RV620.* 1 1 0 0
+AMD RV630 (HD 2600) .*RV630.* 2 1 0 0
+AMD RV635 (HD 3600) .*RV635.* 3 1 0 1.4
+AMD RV670 (HD 3800) .*RV670.* 3 1 0 0
+AMD R680 (HD 3870 X2) .*R680.* 3 1 0 0
+AMD R700 (HD 4800 X2) .*R700.* 3 1 0 0
+AMD RV710 (HD 4300) .*RV710.* 0 1 1 1.4
+AMD RV730 (HD 4600) .*RV730.* 3 1 0 1.4
+AMD RV740 (HD 4700) .*RV740.* 3 1 0 0
+AMD RV770 (HD 4800) .*RV770.* 3 1 0 0
+AMD RV790 (HD 4800) .*RV790.* 3 1 0 0
+ATI 760G/Radeon 3000 .*ATI.*AMD 760G.* 1 1 1 3.3
+ATI 780L/Radeon 3000 .*ATI.*AMD 780L.* 1 1 0 0
+ATI Radeon DDR .*ATI.*Radeon ?DDR.* 0 1 0 0
+ATI FirePro 2000 .*ATI.*FirePro 2.* 2 1 1 4.2
+ATI FirePro 3000 .*ATI.*FirePro V3.* 2 1 0 0
+ATI FirePro 4000 .*ATI.*FirePro V4.* 2 1 0 4.1
+ATI FirePro 5000 .*ATI.*FirePro V5.* 3 1 0 0
+ATI FirePro 7000 .*ATI.*FirePro V7.* 3 1 0 0
+ATI FirePro M .*ATI.*FirePro M.* 3 1 1 4.2
+ATI R300 (9700) .*R300.* 0 1 1 2.1
+Intel X3100 .*Intel.*X3100.* 1 1 1 2.1
+Intel GMA 3600 .*Intel.* 3600.* 0 1 1 3
+Intel 830M .*Intel.*830M 0 0 0 0
+Intel 845G .*Intel.*845G 0 0 1 1.4
+Intel 855GM .*Intel.*855GM 0 0 1 1.4
+Intel 865G .*Intel.*865G 0 0 1 1.4
+Intel 900 .*Intel.*900.*900 0 0 0 0
+Intel 915GM .*Intel.*915GM 0 0 1 1.4
+Intel 915G .*Intel.*915G 0 0 1 1.4
+Intel 945GM .*Intel.*945GM.* 0 1 1 1.4
+Intel 945G .*Intel.*945G.* 0 1 1 1.4
+Intel 950 .*Intel.*950.* 0 1 1 1.4
+Intel 965 .*Intel.*965.* 0 1 1 2.1
+Intel G33 .*Intel.*G33.* 1 0 1 1.4
+Intel G41 .*Intel.*G41.* 1 1 1 2.1
+Intel G45 .*Intel.*G45.* 1 1 1 2.1
+Intel Bear Lake .*Intel.*Bear Lake.* 1 0 1 1.4
+Intel Broadwater .*Intel.*Broadwater.* 0 0 1 1.4
+Intel Brookdale .*Intel.*Brookdale.* 0 0 1 1.3
+Intel Cantiga .*Intel.*Cantiga.* 0 0 1 2
+Intel Eaglelake .*Intel.*Eaglelake.* 1 1 1 2
+Intel Graphics Media HD .*Intel.*Graphics Media.*HD.* 1 1 1 2.1
+Intel HD Graphics 2000 .*Intel.*HD Graphics 2.* 2 1 0 4
+Intel HD Graphics 3000 .*Intel.*HD Graphics 3.* 3 1 1 3.1
+Intel HD Graphics 4000 .*Intel.*HD Graphics 4.* 3 1 1 4
+Intel HD Graphics .*Intel.*HD Graphics.* 2 1 1 4
+Intel Mobile 4 Series .*Intel.*Mobile.* 4 Series.* 0 1 1 2.1
+Intel 4 Series Internal .*Intel.* 4 Series Internal.* 1 1 1 2.1
+Intel Media Graphics HD .*Intel.*Media Graphics HD.* 0 1 0 0
+Intel Montara .*Intel.*Montara.* 0 0 1 1.3
+Intel Pineview .*Intel.*Pineview.* 0 1 1 1.4
+Intel Springdale .*Intel.*Springdale.* 0 0 1 1.3
+Intel Grantsdale .*Intel.*Grantsdale.* 1 1 0 0
+Intel Q45/Q43 .*Intel.*Q4.* 1 1 1 2.1
+Intel B45/B43 .*Intel.*B4.* 1 1 1 2.1
+Intel 3D-Analyze .*Intel.*3D-Analyze.* 2 1 0 0
+Matrox .*Matrox.* 0 0 0 0
+Mesa .*Mesa.* 1 0 1 3
+Gallium .*Gallium.* 1 1 1 2.1
+NVIDIA G100M .*NVIDIA .* 10[0-9]M.* 4 1 1 3.3
+NVIDIA G 110M .*NVIDIA .* 11[0-9]M.* 1 1 1 3.3
+NVIDIA G 120M .*NVIDIA .* 12[0-9]M.* 1 1 1 3.3
+NVIDIA G 200M .*NVIDIA .* 20[0-9]M.* 1 1 0 0
+NVIDIA G 410M .*NVIDIA .* 41[0-9]M.* 3 1 1 4.2
+NVIDIA GT 130M .*NVIDIA .*GT 13[0-9]M.* 3 1 1 3.3
+NVIDIA GT 140M .*NVIDIA .*GT 14[0-9]M.* 3 1 1 3.3
+NVIDIA GT 150M .*NVIDIA .*GTS 15[0-9]M.* 2 1 0 0
+NVIDIA GTS 160M .*NVIDIA .*GTS 16[0-9]M.* 2 1 0 0
+NVIDIA G210M .*NVIDIA .*G21[0-9]M.* 3 1 0 3.3
+NVIDIA GT 220M .*NVIDIA .*GT 22[0-9]M.* 3 1 1 3.3
+NVIDIA GT 230M .*NVIDIA .*GT 23[0-9]M.* 3 1 1 3.3
+NVIDIA GT 240M .*NVIDIA .*GT 24[0-9]M.* 3 1 1 3.3
+NVIDIA GTS 250M .*NVIDIA .*GTS 25[0-9]M.* 3 1 0 3.3
+NVIDIA GTS 260M .*NVIDIA .*GTS 26[0-9]M.* 3 1 0 0
+NVIDIA GTX 260M .*NVIDIA .*GTX 26[0-9]M.* 3 1 0 3.3
+NVIDIA GTX 270M .*NVIDIA .*GTX 27[0-9]M.* 3 1 0 0
+NVIDIA GTX 280M .*NVIDIA .*GTX 28[0-9]M.* 3 1 0 3.3
+NVIDIA 300M .*NVIDIA .*GT 30[0-9]M.* 3 1 1 4.2
+NVIDIA G 310M .*NVIDIA .* 31[0-9]M.* 2 1 0 3.3
+NVIDIA GT 320M .*NVIDIA .* 32[0-9]M.* 3 1 0 3.3
+NVIDIA GT 330M .*NVIDIA .*GT 33[0-9]M.* 3 1 1 3.3
+NVIDIA GT 340M .*NVIDIA .*GT 34[0-9]M.* 4 1 1 3.3
+NVIDIA GTS 350M .*NVIDIA .*GTS 35[0-9]M.* 4 1 1 3.3
+NVIDIA GTS 360M .*NVIDIA .*GTS 36[0-9]M.* 5 1 1 3.3
+NVIDIA 400M .*NVIDIA .* 40[0-9]M.* 2 1 0 0
+NVIDIA 410M .*NVIDIA .* 41[0-9]M.* 3 1 0 0
+NVIDIA GT 420M .*NVIDIA .*GT 42[0-9]M.* 3 1 1 4.2
+NVIDIA GT 430M .*NVIDIA .*GT 43[0-9]M.* 3 1 1 4.2
+NVIDIA GT 440M .*NVIDIA .*GT 44[0-9]M.* 3 1 1 4.2
+NVIDIA GT 450M .*NVIDIA .*GT 45[0-9]M.* 3 1 0 0
+NVIDIA GTX 460M .*NVIDIA .*GTX 46[0-9]M.* 4 1 1 4.3
+NVIDIA GTX 470M .*NVIDIA .*GTX 47[0-9]M.* 3 1 0 4.2
+NVIDIA GTX 480M .*NVIDIA .*GTX 48[0-9]M.* 3 1 1 4.2
+NVIDIA GT 520M .*NVIDIA .*GT 52[0-9]M.* 3 1 1 4.2
+NVIDIA GT 530M .*NVIDIA .*GT 53[0-9]M.* 3 1 1 4.2
+NVIDIA GT 540M .*NVIDIA .*GT 54[0-9]M.* 3 1 1 4.2
+NVIDIA GT 550M .*GeForce GT 55[0-9]M.* 3 1 1 4.2
+NVIDIA GTX 560M .*NVIDIA .*GTX 56[0-9]M.* 3 1 0 4.2
+NVIDIA GTX 570M .*NVIDIA .*GTX 57[0-9]M.* 5 1 0 4.2
+NVIDIA GTX 580M .*NVIDIA .*GTX 58[0-9]M.* 5 1 1 4.2
+NVIDIA 610M .*NVIDIA.* 61[0-9]M.* 3 1 1 4.2
+NVIDIA GT 620M .*NVIDIA .*GT 62[0-9]M.* 3 1 0 4.2
+NVIDIA GT 630M .*NVIDIA .*GT 63[0-9]M.* 3 1 0 4.2
+NVIDIA GT 640M .*NVIDIA .*GT 64[0-9]M.* 3 1 0 4.2
+NVIDIA GT 650M .*NVIDIA .*GT 65[0-9]M.* 3 1 0 4.2
+NVIDIA GTX 660M .*NVIDIA .*GTX 66[0-9]M.* 5 1 0 4.3
+NVIDIA GTX 670M .*NVIDIA .*GTX 67[0-9]M.* 5 1 1 4.2
+NVIDIA GTX 680M .*NVIDIA .*GTX 68[0-9]M.* 5 1 0 4.2
+NVIDIA GTX 690M .*NVIDIA .*GTX 69[0-9]M.* 5 1 0 0
+NVIDIA G100 .*NVIDIA .*G10.* 3 1 1 4.2
+NVIDIA GT 120 .*NVIDIA .*GT 12.* 2 1 0 3.3
+NVIDIA GT 130 .*NVIDIA .*GT 13.* 2 1 0 3.3
+NVIDIA GT 140 .*NVIDIA .*GT 14.* 2 1 0 3.3
+NVIDIA GTS 150 .*NVIDIA .*GTS 15.* 2 1 0 0
+NVIDIA 200 .*NVIDIA .*GeForce 20.* 2 1 1 3.3
+NVIDIA G200 .*NVIDIA .*GeForce G20.* 2 1 1 3.3
+NVIDIA G210 .*NVIDIA .*GeForce G210.* 3 1 1 3.3
+NVIDIA 210 .*NVIDIA .*GeForce 210.* 3 1 1 3.3
+NVIDIA GT 220 .*NVIDIA .*GT 22.* 2 1 1 3.3
+NVIDIA GT 230 .*NVIDIA .*GT 23.* 2 1 1 3.3
+NVIDIA GT 240 .*NVIDIA .*GT 24.* 4 1 1 3.3
+NVIDIA GTS 240 .*NVIDIA .*GTS 24.* 4 1 1 3.3
+NVIDIA GTS 250 .*NVIDIA .*GTS 25.* 4 1 1 3.3
+NVIDIA GTX 260 .*NVIDIA .*GTX 26.* 4 1 1 3.3
+NVIDIA GTX 270 .*NVIDIA .*GTX 27.* 4 1 0 3.3
+NVIDIA GTX 280 .*NVIDIA .*GTX 28.* 4 1 1 3.3
+NVIDIA GTX 290 .*NVIDIA .*GTX 29.* 5 1 0 3.3
+NVIDIA 310 .*NVIDIA .*GeForce 310.* 3 1 1 3.3
+NVIDIA 315 .*NVIDIA .*GeForce 315.* 3 1 1 3.3
+NVIDIA GT 320 .*NVIDIA .*GT 32.* 3 1 0 3.3
+NVIDIA GT 330 .*NVIDIA .*GT 33.* 3 1 0 3.3
+NVIDIA GT 340 .*NVIDIA .*GT 34.* 3 1 0 3.3
+NVIDIA 405 .*NVIDIA .* 405.* 3 1 0 3.3
+NVIDIA GT 420 .*NVIDIA .*GT 42.* 3 1 1 4.2
+NVIDIA GT 430 .*NVIDIA .*GT 43.* 3 1 1 4.3
+NVIDIA GT 440 .*NVIDIA .*GT 44.* 4 1 0 4.3
+NVIDIA GTS 450 .*NVIDIA .*GTS 45.* 4 1 1 4.2
+NVIDIA GTX 460 .*NVIDIA .*GTX 46.* 5 1 1 4.3
+NVIDIA GTX 470 .*NVIDIA .*GTX 47.* 5 1 1 4.2
+NVIDIA GTX 480 .*NVIDIA .*GTX 48.* 5 1 1 4.2
+NVIDIA 510 .*NVIDIA .* 510.* 3 1 0 4.2
+NVIDIA GT 520 .*NVIDIA .*GT 52.* 3 1 1 4.2
+NVIDIA GT 530 .*NVIDIA .*GT 53.* 3 1 1 4.2
+NVIDIA GT 540 .*NVIDIA .*GT 54.* 3 1 1 4.2
+NVIDIA GTX 550 .*NVIDIA .*GTX 55.* 5 1 1 4.3
+NVIDIA GTX 560 .*NVIDIA .*GTX 56.* 5 1 1 4.3
+NVIDIA GTX 570 .*NVIDIA .*GTX 57.* 5 1 1 4.2
+NVIDIA GTX 580 .*NVIDIA .*GTX 58.* 5 1 1 4.3
+NVIDIA GTX 590 .*NVIDIA .*GTX 59.* 5 1 1 4.2
+NVIDIA 605 .*NVIDIA .* 605.* 3 1 1 4.2
+NVIDIA GT 610 .*NVIDIA .*GT 61.* 3 1 1 4.2
+NVIDIA GT 620 .*NVIDIA .*GT 62.* 3 1 0 4.2
+NVIDIA GT 630 .*NVIDIA .*GT 63.* 3 1 0 4.2
+NVIDIA GT 640 .*NVIDIA .*GT 64.* 3 1 0 4.2
+NVIDIA GT 650 .*NVIDIA .*GT 65.* 3 1 1 4.2
+NVIDIA GTX 650 .*NVIDIA .*GTX 65.* 3 1 1 4.2
+NVIDIA GTX 660 .*NVIDIA .*GTX 66.* 5 1 0 4.3
+NVIDIA GTX 670 .*NVIDIA .*GTX 67.* 5 1 1 4.2
+NVIDIA GTX 680 .*NVIDIA .*GTX 68.* 5 1 1 4.2
+NVIDIA GTX 690 .*NVIDIA .*GTX 69.* 5 1 1 4.2
+NVIDIA C51 .*NVIDIA .*C51.* 0 1 1 2
+NVIDIA G72 .*NVIDIA .*G72.* 1 1 0 0
+NVIDIA G73 .*NVIDIA .*G73.* 1 1 0 0
+NVIDIA G84 .*NVIDIA .*G84.* 2 1 0 0
+NVIDIA G86 .*NVIDIA .*G86.* 3 1 0 0
+NVIDIA G92 .*NVIDIA .*G92.* 3 1 0 0
+NVIDIA GeForce .*GeForce 256.* 0 0 0 0
+NVIDIA GeForce 2 .*GeForce ?2 ?.* 0 1 1 1.5
+NVIDIA GeForce 4 .*NVIDIA .*GeForce ?4.* 0 1 1 1.5
+NVIDIA GeForce 6100 .*NVIDIA .*GeForce 61.* 3 1 1 4.2
+NVIDIA GeForce 6200 .*NVIDIA .*GeForce 62.* 0 1 1 2.1
+NVIDIA GeForce 6500 .*NVIDIA .*GeForce 65.* 1 1 1 2.1
+NVIDIA GeForce 6600 .*NVIDIA .*GeForce 66.* 2 1 1 2.1
+NVIDIA GeForce 6700 .*NVIDIA .*GeForce 67.* 2 1 1 2.1
+NVIDIA GeForce 6800 .*NVIDIA .*GeForce 68.* 1 1 1 2.1
+NVIDIA GeForce 7000 .*NVIDIA .*GeForce 70.* 1 1 1 2.1
+NVIDIA GeForce 7100 .*NVIDIA .*GeForce 71.* 1 1 1 2.1
+NVIDIA GeForce 7200 .*NVIDIA .*GeForce 72.* 1 1 0 0
+NVIDIA GeForce 7300 .*NVIDIA .*GeForce 73.* 1 1 1 2.1
+NVIDIA GeForce 7500 .*NVIDIA .*GeForce 75.* 2 1 1 2.1
+NVIDIA GeForce 7600 .*NVIDIA .*GeForce 76.* 2 1 1 2.1
+NVIDIA GeForce 7800 .*NVIDIA .*GeForce 78.* 2 1 1 2.1
+NVIDIA GeForce 7900 .*NVIDIA .*GeForce 79.* 3 1 1 2.1
+NVIDIA GeForce 8100 .*NVIDIA .*GeForce 81.* 1 1 0 3.3
+NVIDIA GeForce 8200M .*NVIDIA .*GeForce 820[0-9]M.* 1 1 0 3.3
+NVIDIA GeForce 8200 .*NVIDIA .*GeForce 82.* 1 1 0 3.3
+NVIDIA GeForce 8300 .*NVIDIA .*GeForce 83.* 3 1 1 3.3
+NVIDIA GeForce 8400M .*NVIDIA .*GeForce 840[0-9]M.* 1 1 1 3.3
+NVIDIA GeForce 8400 .*NVIDIA .*GeForce 84.* 2 1 1 3.3
+NVIDIA GeForce 8500 .*NVIDIA .*GeForce 85.* 2 1 1 3.3
+NVIDIA GeForce 8600M .*NVIDIA .*GeForce 860[0-9]M.* 2 1 1 3.3
+NVIDIA GeForce 8600 .*NVIDIA .*GeForce 86.* 3 1 1 3.3
+NVIDIA GeForce 8700M .*NVIDIA .*GeForce 870[0-9]M.* 2 1 1 3.3
+NVIDIA GeForce 8700 .*NVIDIA .*GeForce 87.* 3 1 0 0
+NVIDIA GeForce 8800M .*NVIDIA .*GeForce 880[0-9]M.* 2 1 1 3.3
+NVIDIA GeForce 8800 .*NVIDIA .*GeForce 88.* 3 1 1 3.3
+NVIDIA GeForce 9100M .*NVIDIA .*GeForce 910[0-9]M.* 0 1 0 3.3
+NVIDIA GeForce 9100 .*NVIDIA .*GeForce 91.* 0 1 0 3.3
+NVIDIA GeForce 9200M .*NVIDIA .*GeForce 920[0-9]M.* 1 1 0 3.3
+NVIDIA GeForce 9200 .*NVIDIA .*GeForce 92.* 1 1 0 3.3
+NVIDIA GeForce 9300M .*NVIDIA .*GeForce 930[0-9]M.* 1 1 1 3.3
+NVIDIA GeForce 9300 .*NVIDIA .*GeForce 93.* 1 1 1 3.3
+NVIDIA GeForce 9400M .*NVIDIA .*GeForce 940[0-9]M.* 2 1 1 3.3
+NVIDIA GeForce 9400 .*NVIDIA .*GeForce 94.* 3 1 1 3.3
+NVIDIA GeForce 9500M .*NVIDIA .*GeForce 950[0-9]M.* 1 1 1 3.3
+NVIDIA GeForce 9500 .*NVIDIA .*GeForce 95.* 3 1 1 3.3
+NVIDIA GeForce 9600M .*NVIDIA .*GeForce 960[0-9]M.* 2 1 1 3.3
+NVIDIA GeForce 9600 .*NVIDIA .*GeForce 96.* 3 1 1 3.3
+NVIDIA GeForce 9700M .*NVIDIA .*GeForce 970[0-9]M.* 0 1 1 3.3
+NVIDIA GeForce 9800M .*NVIDIA .*GeForce 980[0-9]M.* 2 1 1 3.3
+NVIDIA GeForce 9800 .*NVIDIA .*GeForce 98.* 3 1 1 3.3
+NVIDIA GeForce FX 5100 .*NVIDIA .*GeForce FX 51.* 0 1 0 0
+NVIDIA GeForce FX 5200 .*NVIDIA .*GeForce FX 52.* 0 1 0 2.1
+NVIDIA GeForce FX 5300 .*NVIDIA .*GeForce FX 53.* 0 1 0 0
+NVIDIA GeForce FX 5500 .*NVIDIA .*GeForce FX 55.* 0 1 1 2.1
+NVIDIA GeForce FX 5600 .*NVIDIA .*GeForce FX 56.* 1 1 1 2.1
+NVIDIA GeForce FX 5700 .*NVIDIA .*GeForce FX 57.* 0 1 1 2.1
+NVIDIA GeForce FX 5800 .*NVIDIA .*GeForce FX 58.* 1 1 0 0
+NVIDIA GeForce FX 5900 .*NVIDIA .*GeForce FX 59.* 1 1 1 2.1
+NVIDIA GeForce FX Go5100 .*NVIDIA .*GeForce FX Go51.* 0 1 0 0
+NVIDIA GeForce FX Go5200 .*NVIDIA .*GeForce FX Go52.* 0 1 0 1.5
+NVIDIA GeForce FX Go5300 .*NVIDIA .*GeForce FX Go53.* 0 1 0 0
+NVIDIA GeForce FX Go5500 .*NVIDIA .*GeForce FX Go55.* 0 1 0 0
+NVIDIA GeForce FX Go5600 .*NVIDIA .*GeForce FX Go56.* 0 1 1 2.1
+NVIDIA GeForce FX Go5700 .*NVIDIA .*GeForce FX Go57.* 1 1 1 1.5
+NVIDIA GeForce FX Go5800 .*NVIDIA .*GeForce FX Go58.* 1 1 0 0
+NVIDIA GeForce FX Go5900 .*NVIDIA .*GeForce FX Go59.* 1 1 0 0
+NVIDIA GeForce FX Go5xxx .*NVIDIA .*GeForce FX Go.* 0 1 0 0
+NVIDIA GeForce Go 6100 .*NVIDIA .*GeForce Go 61.* 0 1 1 2.1
+NVIDIA GeForce Go 6200 .*NVIDIA .*GeForce Go 62.* 0 1 0 1.5
+NVIDIA GeForce Go 6400 .*NVIDIA .*GeForce Go 64.* 1 1 1 2.1
+NVIDIA GeForce Go 6500 .*NVIDIA .*GeForce Go 65.* 1 1 0 0
+NVIDIA GeForce Go 6600 .*NVIDIA .*GeForce Go 66.* 0 1 1 2.1
+NVIDIA GeForce Go 6700 .*NVIDIA .*GeForce Go 67.* 1 1 0 0
+NVIDIA GeForce Go 6800 .*NVIDIA .*GeForce Go 68.* 0 1 1 2.1
+NVIDIA GeForce Go 7200 .*NVIDIA .*GeForce Go 72.* 1 1 0 2.1
+NVIDIA GeForce Go 7300 LE .*NVIDIA .*GeForce Go 73.*LE.* 1 1 0 0
+NVIDIA GeForce Go 7300 .*NVIDIA .*GeForce Go 73.* 1 1 1 2.1
+NVIDIA GeForce Go 7400 .*NVIDIA .*GeForce Go 74.* 1 1 1 2.1
+NVIDIA GeForce Go 7600 .*NVIDIA .*GeForce Go 76.* 1 1 1 2.1
+NVIDIA GeForce Go 7700 .*NVIDIA .*GeForce Go 77.* 0 1 1 2.1
+NVIDIA GeForce Go 7800 .*NVIDIA .*GeForce Go 78.* 2 1 0 0
+NVIDIA GeForce Go 7900 .*NVIDIA .*GeForce Go 79.* 1 1 1 2.1
+NVIDIA D9M .*NVIDIA .*D9M.* 1 1 0 0
+NVIDIA G94 .*NVIDIA .*G94.* 3 1 0 0
+NVIDIA GeForce Go 6 .*GeForce Go 6.* 1 1 0 0
+NVIDIA ION 2 .*NVIDIA .*ION 2.* 2 1 0 0
+NVIDIA ION .*NVIDIA Corporation.*ION.* 2 1 1 3.3
+NVIDIA NB8M .*NVIDIA .*NB8M.* 1 1 0 0
+NVIDIA NB8P .*NVIDIA .*NB8P.* 2 1 0 0
+NVIDIA NB9E .*NVIDIA .*NB9E.* 3 1 0 0
+NVIDIA NB9M .*NVIDIA .*NB9M.* 1 1 0 0
+NVIDIA NB9P .*NVIDIA .*NB9P.* 2 1 0 0
+NVIDIA N10 .*NVIDIA .*N10.* 1 1 0 2.1
+NVIDIA GeForce PCX .*GeForce PCX.* 0 1 0 1.5
+NVIDIA Generic .*NVIDIA .*Unknown.* 0 0 0 2.1
+NVIDIA NV17 .*NVIDIA .*NV17.* 0 1 0 0
+NVIDIA NV34 .*NVIDIA .*NV34.* 0 1 0 0
+NVIDIA NV35 .*NVIDIA .*NV35.* 0 1 0 0
+NVIDIA NV36 .*NVIDIA .*NV36.* 1 1 0 0
+NVIDIA NV41 .*NVIDIA .*NV41.* 1 1 0 0
+NVIDIA NV43 .*NVIDIA .*NV43.* 1 1 0 0
+NVIDIA NV44 .*NVIDIA .*NV44.* 1 1 0 0
+NVIDIA nForce .*NVIDIA .*nForce.* 0 0 0 3.3
+NVIDIA MCP51 .*NVIDIA .*MCP51.* 1 1 0 0
+NVIDIA MCP61 .*NVIDIA .*MCP61.* 1 1 0 2.1
+NVIDIA MCP67 .*NVIDIA .*MCP67.* 1 1 0 0
+NVIDIA MCP68 .*NVIDIA .*MCP68.* 1 1 0 0
+NVIDIA MCP73 .*NVIDIA .*MCP73.* 1 1 0 0
+NVIDIA MCP77 .*NVIDIA .*MCP77.* 1 1 0 0
+NVIDIA MCP78 .*NVIDIA .*MCP78.* 1 1 0 0
+NVIDIA MCP79 .*NVIDIA .*MCP79.* 1 1 0 0
+NVIDIA MCP7A .*NVIDIA .*MCP7A.* 1 1 0 0
+NVIDIA Quadro2 .*Quadro2.* 0 1 0 1.5
+NVIDIA Quadro 1000M .*Quadro.* (K1|1)00[0-9]M.* 2 1 0 4.2
+NVIDIA Quadro 2000 M/D .*Quadro.* (K2|2)000.* 3 1 0 4.2
+NVIDIA Quadro 3000M .*Quadro.* (K3|3)00[0-9]M.* 3 1 0 4.2
+NVIDIA Quadro 4000M .*Quadro.* (K4|4)00[0-9]M.* 3 1 0 4.2
+NVIDIA Quadro 4000 .*Quadro 4000.* 3 1 0 4.2
+NVIDIA Quadro 50x0 M .*Quadro.* 50.0.* 3 1 0 4.2
+NVIDIA Quadro 6000 .*Quadro.* 6000.* 3 1 0 0
+NVIDIA Quadro 400 .*Quadro.* 400.* 2 1 0 3.3
+NVIDIA Quadro 600 .*Quadro.* 600.* 2 1 0 4.2
+NVIDIA Quadro4 .*Quadro4.* 0 1 0 1.5
+NVIDIA Quadro DCC .*Quadro DCC.* 0 1 0 0
+NVIDIA Quadro CX .*Quadro.*CX.* 3 1 0 0
+NVIDIA Quadro FX 770M .*Quadro.*FX 77[0-9]M.* 2 1 0 3.3
+NVIDIA Quadro FX 1500M .*Quadro.*FX 150[0-9]M.* 1 1 0 2.1
+NVIDIA Quadro FX 1600M .*Quadro.*FX 160[0-9]M.* 2 1 0 3.3
+NVIDIA Quadro FX 2500M .*Quadro.*FX 250[0-9]M.* 2 1 0 2.1
+NVIDIA Quadro FX 2700M .*Quadro.*FX 270[0-9]M.* 3 1 0 3.3
+NVIDIA Quadro FX 2800M .*Quadro.*FX 280[0-9]M.* 3 1 0 3.3
+NVIDIA Quadro FX 3500 .*Quadro.*FX 3500.* 2 1 0 2.1
+NVIDIA Quadro FX 3600 .*Quadro.*FX 3600.* 3 1 0 3.3
+NVIDIA Quadro FX 3700 .*Quadro.*FX 3700.* 3 1 0 3.3
+NVIDIA Quadro FX 3800 .*Quadro.*FX 3800.* 3 1 0 3.3
+NVIDIA Quadro FX 4500 .*Quadro.*FX 45.* 3 1 0 2.1
+NVIDIA Quadro FX 880M .*Quadro.*FX 88[0-9]M.* 3 1 0 3.3
+NVIDIA Quadro FX 4800 .*NVIDIA .*Quadro FX 4800.* 3 1 0 3.1
+NVIDIA Quadro FX .*Quadro FX.* 1 1 0 3.3
+NVIDIA Quadro NVS 1xxM .*Quadro NVS 1.[05]M.* 0 1 1 3.3
+NVIDIA Quadro NVS 300M .*NVIDIA .*NVS 30[0-9]M.* 2 1 0 0
+NVIDIA Quadro NVS 320M .*NVIDIA .*NVS 32[0-9]M.* 2 1 0 0
+NVIDIA Quadro NVS 2100M .*NVIDIA .*NVS 210[0-9]M.* 2 1 0 3.3
+NVIDIA Quadro NVS 3100M .*NVIDIA .*NVS 310[0-9]M.* 2 1 0 3.3
+NVIDIA Quadro NVS 4200M .*NVIDIA .*NVS 420[0-9]M.* 2 1 0 4.2
+NVIDIA Quadro NVS 5100M .*NVIDIA .*NVS 510[0-9]M.* 2 1 0 0
+NVIDIA Quadro NVS .*NVIDIA .*NVS 0 1 0 4.2
+NVIDIA Corporation N12P .*NVIDIA .*N12P.* 1 1 1 4.1
+NVIDIA Corporation N11M .*NVIDIA .*N11M.* 2 1 0 3.1
+NVIDIA RIVA TNT .*RIVA TNT.* 0 0 0 1.5
+S3 .*S3 Graphics.* 0 0 1 1.4
+SiS SiS.* 0 0 1 1.5
+Trident Trident.* 0 0 0 0
+Tungsten Graphics Tungsten.* 0 0 0 0
+XGI XGI.* 0 0 0 0
+VIA VIA.* 0 0 0 0
+Apple Generic Apple.*Generic.* 0 0 0 0
+Apple Software Renderer Apple.*Software Renderer.* 0 0 0 0
+Humper Humper.* 0 1 1 2.1
+PowerVR SGX545 .*PowerVR SGX.* 1 1 1 3
diff --git a/indra/newview/groupchatlistener.cpp b/indra/newview/groupchatlistener.cpp
index ef015a950d..ef015a950d 100644..100755
--- a/indra/newview/groupchatlistener.cpp
+++ b/indra/newview/groupchatlistener.cpp
diff --git a/indra/newview/groupchatlistener.h b/indra/newview/groupchatlistener.h
index 0c76db305e..0c76db305e 100644..100755
--- a/indra/newview/groupchatlistener.h
+++ b/indra/newview/groupchatlistener.h
diff --git a/indra/newview/hu.lproj/language.txt b/indra/newview/hu.lproj/language.txt
index 6c604cf2a9..6c604cf2a9 100644..100755
--- a/indra/newview/hu.lproj/language.txt
+++ b/indra/newview/hu.lproj/language.txt
diff --git a/indra/newview/icons/beta/secondlife.icns b/indra/newview/icons/beta/secondlife.icns
index 1fa50547bb..1fa50547bb 100644..100755
--- a/indra/newview/icons/beta/secondlife.icns
+++ b/indra/newview/icons/beta/secondlife.icns
Binary files differ
diff --git a/indra/newview/icons/beta/secondlife.ico b/indra/newview/icons/beta/secondlife.ico
index 9bdd21b904..9bdd21b904 100644..100755
--- a/indra/newview/icons/beta/secondlife.ico
+++ b/indra/newview/icons/beta/secondlife.ico
Binary files differ
diff --git a/indra/newview/icons/beta/secondlife_128.png b/indra/newview/icons/beta/secondlife_128.png
index fa42aa764b..fa42aa764b 100644..100755
--- a/indra/newview/icons/beta/secondlife_128.png
+++ b/indra/newview/icons/beta/secondlife_128.png
Binary files differ
diff --git a/indra/newview/icons/beta/secondlife_16.png b/indra/newview/icons/beta/secondlife_16.png
index ff648cf3fc..ff648cf3fc 100644..100755
--- a/indra/newview/icons/beta/secondlife_16.png
+++ b/indra/newview/icons/beta/secondlife_16.png
Binary files differ
diff --git a/indra/newview/icons/beta/secondlife_256.BMP b/indra/newview/icons/beta/secondlife_256.BMP
index 97bd67d3d6..97bd67d3d6 100644..100755
--- a/indra/newview/icons/beta/secondlife_256.BMP
+++ b/indra/newview/icons/beta/secondlife_256.BMP
Binary files differ
diff --git a/indra/newview/icons/beta/secondlife_256.png b/indra/newview/icons/beta/secondlife_256.png
index 245e2c3e9f..245e2c3e9f 100644..100755
--- a/indra/newview/icons/beta/secondlife_256.png
+++ b/indra/newview/icons/beta/secondlife_256.png
Binary files differ
diff --git a/indra/newview/icons/beta/secondlife_32.png b/indra/newview/icons/beta/secondlife_32.png
index fd7f46bf4d..fd7f46bf4d 100644..100755
--- a/indra/newview/icons/beta/secondlife_32.png
+++ b/indra/newview/icons/beta/secondlife_32.png
Binary files differ
diff --git a/indra/newview/icons/beta/secondlife_48.png b/indra/newview/icons/beta/secondlife_48.png
index cc3a795e2b..cc3a795e2b 100644..100755
--- a/indra/newview/icons/beta/secondlife_48.png
+++ b/indra/newview/icons/beta/secondlife_48.png
Binary files differ
diff --git a/indra/newview/icons/beta/secondlife_512.png b/indra/newview/icons/beta/secondlife_512.png
index a959bd9a9e..a959bd9a9e 100644..100755
--- a/indra/newview/icons/beta/secondlife_512.png
+++ b/indra/newview/icons/beta/secondlife_512.png
Binary files differ
diff --git a/indra/newview/icons/development/secondlife.icns b/indra/newview/icons/development/secondlife.icns
deleted file mode 100644
index 44f63d384c..0000000000
--- a/indra/newview/icons/development/secondlife.icns
+++ /dev/null
Binary files differ
diff --git a/indra/newview/icons/development/secondlife.ico b/indra/newview/icons/development/secondlife.ico
deleted file mode 100644
index b53f23ae58..0000000000
--- a/indra/newview/icons/development/secondlife.ico
+++ /dev/null
Binary files differ
diff --git a/indra/newview/icons/development/secondlife_128.png b/indra/newview/icons/development/secondlife_128.png
deleted file mode 100644
index 9b9fe656fc..0000000000
--- a/indra/newview/icons/development/secondlife_128.png
+++ /dev/null
Binary files differ
diff --git a/indra/newview/icons/development/secondlife_16.png b/indra/newview/icons/development/secondlife_16.png
deleted file mode 100644
index 91493a033c..0000000000
--- a/indra/newview/icons/development/secondlife_16.png
+++ /dev/null
Binary files differ
diff --git a/indra/newview/icons/development/secondlife_256.BMP b/indra/newview/icons/development/secondlife_256.BMP
deleted file mode 100644
index 174b22319a..0000000000
--- a/indra/newview/icons/development/secondlife_256.BMP
+++ /dev/null
Binary files differ
diff --git a/indra/newview/icons/development/secondlife_256.png b/indra/newview/icons/development/secondlife_256.png
deleted file mode 100644
index 29ed40abdc..0000000000
--- a/indra/newview/icons/development/secondlife_256.png
+++ /dev/null
Binary files differ
diff --git a/indra/newview/icons/development/secondlife_32.png b/indra/newview/icons/development/secondlife_32.png
deleted file mode 100644
index 3b84f5ec77..0000000000
--- a/indra/newview/icons/development/secondlife_32.png
+++ /dev/null
Binary files differ
diff --git a/indra/newview/icons/development/secondlife_48.png b/indra/newview/icons/development/secondlife_48.png
deleted file mode 100644
index d2636d9d72..0000000000
--- a/indra/newview/icons/development/secondlife_48.png
+++ /dev/null
Binary files differ
diff --git a/indra/newview/icons/development/secondlife_512.png b/indra/newview/icons/development/secondlife_512.png
deleted file mode 100644
index 75f9b231f4..0000000000
--- a/indra/newview/icons/development/secondlife_512.png
+++ /dev/null
Binary files differ
diff --git a/indra/newview/icons/project/secondlife.icns b/indra/newview/icons/project/secondlife.icns
index d6e26a8ed9..d6e26a8ed9 100644..100755
--- a/indra/newview/icons/project/secondlife.icns
+++ b/indra/newview/icons/project/secondlife.icns
Binary files differ
diff --git a/indra/newview/icons/project/secondlife.ico b/indra/newview/icons/project/secondlife.ico
index ebb27e5325..ebb27e5325 100644..100755
--- a/indra/newview/icons/project/secondlife.ico
+++ b/indra/newview/icons/project/secondlife.ico
Binary files differ
diff --git a/indra/newview/icons/project/secondlife_128.png b/indra/newview/icons/project/secondlife_128.png
index d67b8228f9..d67b8228f9 100644..100755
--- a/indra/newview/icons/project/secondlife_128.png
+++ b/indra/newview/icons/project/secondlife_128.png
Binary files differ
diff --git a/indra/newview/icons/project/secondlife_16.png b/indra/newview/icons/project/secondlife_16.png
index 91493a033c..91493a033c 100644..100755
--- a/indra/newview/icons/project/secondlife_16.png
+++ b/indra/newview/icons/project/secondlife_16.png
Binary files differ
diff --git a/indra/newview/icons/project/secondlife_256.BMP b/indra/newview/icons/project/secondlife_256.BMP
index cd890725f8..cd890725f8 100644..100755
--- a/indra/newview/icons/project/secondlife_256.BMP
+++ b/indra/newview/icons/project/secondlife_256.BMP
Binary files differ
diff --git a/indra/newview/icons/project/secondlife_256.png b/indra/newview/icons/project/secondlife_256.png
index cccfaf7cba..cccfaf7cba 100644..100755
--- a/indra/newview/icons/project/secondlife_256.png
+++ b/indra/newview/icons/project/secondlife_256.png
Binary files differ
diff --git a/indra/newview/icons/project/secondlife_32.png b/indra/newview/icons/project/secondlife_32.png
index ad7b33f789..ad7b33f789 100644..100755
--- a/indra/newview/icons/project/secondlife_32.png
+++ b/indra/newview/icons/project/secondlife_32.png
Binary files differ
diff --git a/indra/newview/icons/project/secondlife_48.png b/indra/newview/icons/project/secondlife_48.png
index 104a931fbc..104a931fbc 100644..100755
--- a/indra/newview/icons/project/secondlife_48.png
+++ b/indra/newview/icons/project/secondlife_48.png
Binary files differ
diff --git a/indra/newview/icons/project/secondlife_512.png b/indra/newview/icons/project/secondlife_512.png
index 74e2fa9bc6..74e2fa9bc6 100644..100755
--- a/indra/newview/icons/project/secondlife_512.png
+++ b/indra/newview/icons/project/secondlife_512.png
Binary files differ
diff --git a/indra/newview/icons/release/secondlife.icns b/indra/newview/icons/release/secondlife.icns
index e15e34140d..e15e34140d 100644..100755
--- a/indra/newview/icons/release/secondlife.icns
+++ b/indra/newview/icons/release/secondlife.icns
Binary files differ
diff --git a/indra/newview/icons/release/secondlife.ico b/indra/newview/icons/release/secondlife.ico
index 28bf1e7664..28bf1e7664 100644..100755
--- a/indra/newview/icons/release/secondlife.ico
+++ b/indra/newview/icons/release/secondlife.ico
Binary files differ
diff --git a/indra/newview/icons/release/secondlife_128.png b/indra/newview/icons/release/secondlife_128.png
index bcf94dcae8..bcf94dcae8 100644..100755
--- a/indra/newview/icons/release/secondlife_128.png
+++ b/indra/newview/icons/release/secondlife_128.png
Binary files differ
diff --git a/indra/newview/icons/release/secondlife_16.png b/indra/newview/icons/release/secondlife_16.png
index 90311ea8b0..90311ea8b0 100644..100755
--- a/indra/newview/icons/release/secondlife_16.png
+++ b/indra/newview/icons/release/secondlife_16.png
Binary files differ
diff --git a/indra/newview/icons/release/secondlife_256.BMP b/indra/newview/icons/release/secondlife_256.BMP
index 74deedd7d3..74deedd7d3 100644..100755
--- a/indra/newview/icons/release/secondlife_256.BMP
+++ b/indra/newview/icons/release/secondlife_256.BMP
Binary files differ
diff --git a/indra/newview/icons/release/secondlife_256.png b/indra/newview/icons/release/secondlife_256.png
index a89fb4c74f..a89fb4c74f 100644..100755
--- a/indra/newview/icons/release/secondlife_256.png
+++ b/indra/newview/icons/release/secondlife_256.png
Binary files differ
diff --git a/indra/newview/icons/release/secondlife_32.png b/indra/newview/icons/release/secondlife_32.png
index 530e8fc80c..530e8fc80c 100644..100755
--- a/indra/newview/icons/release/secondlife_32.png
+++ b/indra/newview/icons/release/secondlife_32.png
Binary files differ
diff --git a/indra/newview/icons/release/secondlife_48.png b/indra/newview/icons/release/secondlife_48.png
index cb33c51f8a..cb33c51f8a 100644..100755
--- a/indra/newview/icons/release/secondlife_48.png
+++ b/indra/newview/icons/release/secondlife_48.png
Binary files differ
diff --git a/indra/newview/icons/release/secondlife_512.png b/indra/newview/icons/release/secondlife_512.png
index f291e60586..f291e60586 100644..100755
--- a/indra/newview/icons/release/secondlife_512.png
+++ b/indra/newview/icons/release/secondlife_512.png
Binary files differ
diff --git a/indra/newview/icons/test/secondlife.icns b/indra/newview/icons/test/secondlife.icns
index eb8d16a7e7..eb8d16a7e7 100644..100755
--- a/indra/newview/icons/test/secondlife.icns
+++ b/indra/newview/icons/test/secondlife.icns
Binary files differ
diff --git a/indra/newview/icons/test/secondlife.ico b/indra/newview/icons/test/secondlife.ico
index ceb8e8e6eb..ceb8e8e6eb 100644..100755
--- a/indra/newview/icons/test/secondlife.ico
+++ b/indra/newview/icons/test/secondlife.ico
Binary files differ
diff --git a/indra/newview/icons/test/secondlife_128.png b/indra/newview/icons/test/secondlife_128.png
index 019f65db28..019f65db28 100644..100755
--- a/indra/newview/icons/test/secondlife_128.png
+++ b/indra/newview/icons/test/secondlife_128.png
Binary files differ
diff --git a/indra/newview/icons/test/secondlife_16.png b/indra/newview/icons/test/secondlife_16.png
index 91493a033c..91493a033c 100644..100755
--- a/indra/newview/icons/test/secondlife_16.png
+++ b/indra/newview/icons/test/secondlife_16.png
Binary files differ
diff --git a/indra/newview/icons/test/secondlife_256.BMP b/indra/newview/icons/test/secondlife_256.BMP
index e23fcfdbe9..e23fcfdbe9 100644..100755
--- a/indra/newview/icons/test/secondlife_256.BMP
+++ b/indra/newview/icons/test/secondlife_256.BMP
Binary files differ
diff --git a/indra/newview/icons/test/secondlife_256.png b/indra/newview/icons/test/secondlife_256.png
index f402424c51..f402424c51 100644..100755
--- a/indra/newview/icons/test/secondlife_256.png
+++ b/indra/newview/icons/test/secondlife_256.png
Binary files differ
diff --git a/indra/newview/icons/test/secondlife_32.png b/indra/newview/icons/test/secondlife_32.png
index 80d6efe13d..80d6efe13d 100644..100755
--- a/indra/newview/icons/test/secondlife_32.png
+++ b/indra/newview/icons/test/secondlife_32.png
Binary files differ
diff --git a/indra/newview/icons/test/secondlife_48.png b/indra/newview/icons/test/secondlife_48.png
index bba938feba..bba938feba 100644..100755
--- a/indra/newview/icons/test/secondlife_48.png
+++ b/indra/newview/icons/test/secondlife_48.png
Binary files differ
diff --git a/indra/newview/icons/test/secondlife_512.png b/indra/newview/icons/test/secondlife_512.png
index 10ff65312b..10ff65312b 100644..100755
--- a/indra/newview/icons/test/secondlife_512.png
+++ b/indra/newview/icons/test/secondlife_512.png
Binary files differ
diff --git a/indra/newview/installers/darwin/dmg-cleanup.applescript b/indra/newview/installers/darwin/dmg-cleanup.applescript
index 8a71b392f9..8a71b392f9 100644..100755
--- a/indra/newview/installers/darwin/dmg-cleanup.applescript
+++ b/indra/newview/installers/darwin/dmg-cleanup.applescript
diff --git a/indra/newview/installers/darwin/fix_application_icon_position.sh b/indra/newview/installers/darwin/fix_application_icon_position.sh
index 618e34820c..618e34820c 100644..100755
--- a/indra/newview/installers/darwin/fix_application_icon_position.sh
+++ b/indra/newview/installers/darwin/fix_application_icon_position.sh
diff --git a/indra/newview/installers/darwin/release-dmg/Applications-alias.r b/indra/newview/installers/darwin/release-dmg/Applications-alias.r
index aa3cfb87d8..aa3cfb87d8 100644..100755
--- a/indra/newview/installers/darwin/release-dmg/Applications-alias.r
+++ b/indra/newview/installers/darwin/release-dmg/Applications-alias.r
diff --git a/indra/newview/installers/darwin/release-dmg/_DS_Store b/indra/newview/installers/darwin/release-dmg/_DS_Store
index 747ca961d8..747ca961d8 100644..100755
--- a/indra/newview/installers/darwin/release-dmg/_DS_Store
+++ b/indra/newview/installers/darwin/release-dmg/_DS_Store
Binary files differ
diff --git a/indra/newview/installers/darwin/release-dmg/_VolumeIcon.icns b/indra/newview/installers/darwin/release-dmg/_VolumeIcon.icns
index da5307e389..da5307e389 100644..100755
--- a/indra/newview/installers/darwin/release-dmg/_VolumeIcon.icns
+++ b/indra/newview/installers/darwin/release-dmg/_VolumeIcon.icns
Binary files differ
diff --git a/indra/newview/installers/darwin/release-dmg/background.jpg b/indra/newview/installers/darwin/release-dmg/background.jpg
index 55294dcc9a..55294dcc9a 100644..100755
--- a/indra/newview/installers/darwin/release-dmg/background.jpg
+++ b/indra/newview/installers/darwin/release-dmg/background.jpg
Binary files differ
diff --git a/indra/newview/installers/windows/FILES_ARE_UNICODE_UTF-16LE.txt b/indra/newview/installers/windows/FILES_ARE_UNICODE_UTF-16LE.txt
index 185c0180fb..185c0180fb 100644..100755
--- a/indra/newview/installers/windows/FILES_ARE_UNICODE_UTF-16LE.txt
+++ b/indra/newview/installers/windows/FILES_ARE_UNICODE_UTF-16LE.txt
diff --git a/indra/newview/installers/windows/install_icon.BMP b/indra/newview/installers/windows/install_icon.BMP
index 09df573870..09df573870 100644..100755
--- a/indra/newview/installers/windows/install_icon.BMP
+++ b/indra/newview/installers/windows/install_icon.BMP
Binary files differ
diff --git a/indra/newview/installers/windows/install_icon.ico b/indra/newview/installers/windows/install_icon.ico
index efe6c4f323..efe6c4f323 100644..100755
--- a/indra/newview/installers/windows/install_icon.ico
+++ b/indra/newview/installers/windows/install_icon.ico
Binary files differ
diff --git a/indra/newview/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi
index 8a6114f0d5..8a6114f0d5 100644..100755
--- a/indra/newview/installers/windows/installer_template.nsi
+++ b/indra/newview/installers/windows/installer_template.nsi
diff --git a/indra/newview/installers/windows/lang_da.nsi b/indra/newview/installers/windows/lang_da.nsi
index 0c832e8ba9..0c832e8ba9 100644..100755
--- a/indra/newview/installers/windows/lang_da.nsi
+++ b/indra/newview/installers/windows/lang_da.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_de.nsi b/indra/newview/installers/windows/lang_de.nsi
index b717a4d3a5..b717a4d3a5 100644..100755
--- a/indra/newview/installers/windows/lang_de.nsi
+++ b/indra/newview/installers/windows/lang_de.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_en-us.nsi b/indra/newview/installers/windows/lang_en-us.nsi
index da0d7f54d2..da0d7f54d2 100644..100755
--- a/indra/newview/installers/windows/lang_en-us.nsi
+++ b/indra/newview/installers/windows/lang_en-us.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_es.nsi b/indra/newview/installers/windows/lang_es.nsi
index c6a7f38f3f..c6a7f38f3f 100644..100755
--- a/indra/newview/installers/windows/lang_es.nsi
+++ b/indra/newview/installers/windows/lang_es.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_fr.nsi b/indra/newview/installers/windows/lang_fr.nsi
index 008c240ed7..008c240ed7 100644..100755
--- a/indra/newview/installers/windows/lang_fr.nsi
+++ b/indra/newview/installers/windows/lang_fr.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_it.nsi b/indra/newview/installers/windows/lang_it.nsi
index eccd965a92..eccd965a92 100644..100755
--- a/indra/newview/installers/windows/lang_it.nsi
+++ b/indra/newview/installers/windows/lang_it.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_ja.nsi b/indra/newview/installers/windows/lang_ja.nsi
index f564291f7d..f564291f7d 100644..100755
--- a/indra/newview/installers/windows/lang_ja.nsi
+++ b/indra/newview/installers/windows/lang_ja.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_pl.nsi b/indra/newview/installers/windows/lang_pl.nsi
index 191bae4755..191bae4755 100644..100755
--- a/indra/newview/installers/windows/lang_pl.nsi
+++ b/indra/newview/installers/windows/lang_pl.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_pt-br.nsi b/indra/newview/installers/windows/lang_pt-br.nsi
index da56a3c336..da56a3c336 100644..100755
--- a/indra/newview/installers/windows/lang_pt-br.nsi
+++ b/indra/newview/installers/windows/lang_pt-br.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_ru.nsi b/indra/newview/installers/windows/lang_ru.nsi
index de7affe08a..de7affe08a 100644..100755
--- a/indra/newview/installers/windows/lang_ru.nsi
+++ b/indra/newview/installers/windows/lang_ru.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_tr.nsi b/indra/newview/installers/windows/lang_tr.nsi
index 5e7e3d797b..5e7e3d797b 100644..100755
--- a/indra/newview/installers/windows/lang_tr.nsi
+++ b/indra/newview/installers/windows/lang_tr.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_zh.nsi b/indra/newview/installers/windows/lang_zh.nsi
index ecf1185fbb..ecf1185fbb 100644..100755
--- a/indra/newview/installers/windows/lang_zh.nsi
+++ b/indra/newview/installers/windows/lang_zh.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/language_menu.nsi b/indra/newview/installers/windows/language_menu.nsi
index 08ad42532f..08ad42532f 100644..100755
--- a/indra/newview/installers/windows/language_menu.nsi
+++ b/indra/newview/installers/windows/language_menu.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/uninstall_icon.BMP b/indra/newview/installers/windows/uninstall_icon.BMP
index 562b56676a..562b56676a 100644..100755
--- a/indra/newview/installers/windows/uninstall_icon.BMP
+++ b/indra/newview/installers/windows/uninstall_icon.BMP
Binary files differ
diff --git a/indra/newview/installers/windows/uninstall_icon.ico b/indra/newview/installers/windows/uninstall_icon.ico
index 05e1546860..05e1546860 100644..100755
--- a/indra/newview/installers/windows/uninstall_icon.ico
+++ b/indra/newview/installers/windows/uninstall_icon.ico
Binary files differ
diff --git a/indra/newview/it.lproj/language.txt b/indra/newview/it.lproj/language.txt
index c91971434c..c91971434c 100644..100755
--- a/indra/newview/it.lproj/language.txt
+++ b/indra/newview/it.lproj/language.txt
diff --git a/indra/newview/licenses-linux.txt b/indra/newview/licenses-linux.txt
index b43c402e64..b43c402e64 100644..100755
--- a/indra/newview/licenses-linux.txt
+++ b/indra/newview/licenses-linux.txt
diff --git a/indra/newview/licenses-mac.txt b/indra/newview/licenses-mac.txt
index af80bff5d9..af80bff5d9 100644..100755
--- a/indra/newview/licenses-mac.txt
+++ b/indra/newview/licenses-mac.txt
diff --git a/indra/newview/licenses-solaris.txt b/indra/newview/licenses-solaris.txt
index c19f939a80..c19f939a80 100644..100755
--- a/indra/newview/licenses-solaris.txt
+++ b/indra/newview/licenses-solaris.txt
diff --git a/indra/newview/licenses-win32.txt b/indra/newview/licenses-win32.txt
index 8736626907..8736626907 100644..100755
--- a/indra/newview/licenses-win32.txt
+++ b/indra/newview/licenses-win32.txt
diff --git a/indra/newview/linux_tools/client-readme-joystick.txt b/indra/newview/linux_tools/client-readme-joystick.txt
index 4f89a73ccb..4f89a73ccb 100644..100755
--- a/indra/newview/linux_tools/client-readme-joystick.txt
+++ b/indra/newview/linux_tools/client-readme-joystick.txt
diff --git a/indra/newview/linux_tools/client-readme-voice.txt b/indra/newview/linux_tools/client-readme-voice.txt
index bfefdf3471..bfefdf3471 100644..100755
--- a/indra/newview/linux_tools/client-readme-voice.txt
+++ b/indra/newview/linux_tools/client-readme-voice.txt
diff --git a/indra/newview/linux_tools/client-readme.txt b/indra/newview/linux_tools/client-readme.txt
index e01b9e4bc6..e01b9e4bc6 100644..100755
--- a/indra/newview/linux_tools/client-readme.txt
+++ b/indra/newview/linux_tools/client-readme.txt
diff --git a/indra/newview/linux_tools/wrapper.sh b/indra/newview/linux_tools/wrapper.sh
index 283a28a0aa..c23401d5a6 100755
--- a/indra/newview/linux_tools/wrapper.sh
+++ b/indra/newview/linux_tools/wrapper.sh
@@ -4,17 +4,17 @@
## These options are for self-assisted troubleshooting during this beta
## testing phase; you should not usually need to touch them.
+## - Avoids using any FMOD Ex audio driver.
+#export LL_BAD_FMODEX_DRIVER=x
## - Avoids using any OpenAL audio driver.
#export LL_BAD_OPENAL_DRIVER=x
-## - Avoids using any FMOD audio driver.
-#export LL_BAD_FMOD_DRIVER=x
-## - Avoids using the FMOD ESD audio driver.
-#export LL_BAD_FMOD_ESD=x
-## - Avoids using the FMOD OSS audio driver.
-#export LL_BAD_FMOD_OSS=x
-## - Avoids using the FMOD ALSA audio driver.
+## - Avoids using the FMOD Ex PulseAudio audio driver.
+#export LL_BAD_FMOD_PULSEAUDIO=x
+## - Avoids using the FMOD or FMOD Ex ALSA audio driver.
#export LL_BAD_FMOD_ALSA=x
+## - Avoids using the FMOD or FMOD Ex OSS audio driver.
+#export LL_BAD_FMOD_OSS=x
## - Avoids the optional OpenGL extensions which have proven most problematic
## on some hardware. Disabling this option may cause BETTER PERFORMANCE but
@@ -45,6 +45,7 @@ if [ "`uname -m`" = "x86_64" ]; then
echo '64-bit Linux detected.'
fi
+
## Everything below this line is just for advanced troubleshooters.
##-------------------------------------------------------------------
@@ -60,7 +61,15 @@ fi
export SDL_VIDEO_X11_DGAMOUSE=0
## - Works around a problem with misconfigured 64-bit systems not finding GL
-export LIBGL_DRIVERS_PATH="${LIBGL_DRIVERS_PATH}":/usr/lib64/dri:/usr/lib32/dri:/usr/lib/dri
+I386_MULTIARCH="$(dpkg-architecture -ai386 -qDEB_HOST_MULTIARCH 2>/dev/null)"
+MULTIARCH_ERR=$?
+if [ $MULTIARCH_ERR -eq 0 ]; then
+ echo 'Multi-arch support detected.'
+ MULTIARCH_GL_DRIVERS="/usr/lib/${I386_MULTIARCH}/dri"
+ export LIBGL_DRIVERS_PATH="${LIBGL_DRIVERS_PATH}:${MULTIARCH_GL_DRIVERS}:/usr/lib64/dri:/usr/lib32/dri:/usr/lib/dri"
+else
+ export LIBGL_DRIVERS_PATH="${LIBGL_DRIVERS_PATH}:/usr/lib64/dri:/usr/lib32/dri:/usr/lib/dri"
+fi
## - The 'scim' GTK IM module widely crashes the viewer. Avoid it.
if [ "$GTK_IM_MODULE" = "scim" ]; then
@@ -110,22 +119,32 @@ export SAVED_LD_LIBRARY_PATH="${LD_LIBRARY_PATH}"
# fi
#fi
-export SL_ENV='LD_LIBRARY_PATH="`pwd`"/lib:"${LD_LIBRARY_PATH}"'
-export SL_CMD='$LL_WRAPPER bin/do-not-directly-run-secondlife-bin'
-export SL_OPT="`cat etc/gridargs.dat` $@"
-
-# Run the program
-eval ${SL_ENV} ${SL_CMD} ${SL_OPT} || LL_RUN_ERR=runerr
+export LD_LIBRARY_PATH="$PWD/lib:${LD_LIBRARY_PATH}"
+
+# Copy "$@" to ARGS array specifically to delete the --skip-gridargs switch.
+# The gridargs.dat file is no more, but we still want to avoid breaking
+# scripts that invoke this one with --skip-gridargs.
+ARGS=()
+for ARG in "$@"; do
+ if [ "--skip-gridargs" != "$ARG" ]; then
+ ARGS[${#ARGS[*]}]="$ARG"
+ fi
+done
+
+# Run the program.
+# Don't quote $LL_WRAPPER because, if empty, it should simply vanish from the
+# command line. But DO quote "${ARGS[@]}": preserve separate args as
+# individually quoted.
+$LL_WRAPPER bin/do-not-directly-run-secondlife-bin "${ARGS[@]}"
+LL_RUN_ERR=$?
# Handle any resulting errors
-if [ -n "$LL_RUN_ERR" ]; then
- LL_RUN_ERR_MSG=""
- if [ "$LL_RUN_ERR" = "runerr" ]; then
- # generic error running the binary
- echo '*** Bad shutdown. ***'
- if [ "`uname -m`" = "x86_64" ]; then
- echo
- cat << EOFMARKER
+if [ $LL_RUN_ERR -ne 0 ]; then
+ # generic error running the binary
+ echo '*** Bad shutdown ($LL_RUN_ERR). ***'
+ if [ "$(uname -m)" = "x86_64" ]; then
+ echo
+ cat << EOFMARKER
You are running the Second Life Viewer on a x86_64 platform. The
most common problems when launching the Viewer (particularly
'bin/do-not-directly-run-secondlife-bin: not found' and 'error while
@@ -134,10 +153,8 @@ distribution's 32-bit compatibility packages.
For example, on Ubuntu and other Debian-based Linuxes you might run:
$ sudo apt-get install ia32-libs ia32-libs-gtk ia32-libs-kde ia32-libs-sdl
EOFMARKER
- fi
fi
fi
-
echo
echo '*******************************************************'
diff --git a/indra/newview/llaccountingcostmanager.cpp b/indra/newview/llaccountingcostmanager.cpp
index 8767955fcb..7662a9689d 100644..100755
--- a/indra/newview/llaccountingcostmanager.cpp
+++ b/indra/newview/llaccountingcostmanager.cpp
@@ -56,9 +56,9 @@ public:
}
}
- void error( U32 statusNum, const std::string& reason )
+ void errorWithContent( U32 statusNum, const std::string& reason, const LLSD& content )
{
- llwarns << "Transport error "<<reason<<llendl;
+ llwarns << "Transport error [status:" << statusNum << "]: " << content <<llendl;
clearPendingRequests();
LLAccountingCostObserver* observer = mObserverHandle.get();
diff --git a/indra/newview/llaccountingcostmanager.h b/indra/newview/llaccountingcostmanager.h
index 0bca1f54ef..0bca1f54ef 100644..100755
--- a/indra/newview/llaccountingcostmanager.h
+++ b/indra/newview/llaccountingcostmanager.h
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index f9301b61a1..7d2b4f6269 100755
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -35,15 +35,19 @@
#include "llagentlistener.h"
#include "llagentwearables.h"
#include "llagentui.h"
+#include "llappearancemgr.h"
#include "llanimationstates.h"
#include "llcallingcard.h"
#include "llcapabilitylistener.h"
#include "llchannelmanager.h"
#include "llchicletbar.h"
#include "llconsole.h"
+#include "lldonotdisturbnotificationstorage.h"
#include "llenvmanager.h"
#include "llfirstuse.h"
#include "llfloatercamera.h"
+#include "llfloaterimcontainer.h"
+#include "llfloaterperms.h"
#include "llfloaterreg.h"
#include "llfloatertools.h"
#include "llgroupactions.h"
@@ -54,7 +58,7 @@
#include "llmorphview.h"
#include "llmoveview.h"
#include "llnavigationbar.h" // to show/hide navigation bar when changing mouse look state
-#include "llnearbychatbar.h"
+#include "llfloaterimnearbychat.h"
#include "llnotificationsutil.h"
#include "llpaneltopinfobar.h"
#include "llparcel.h"
@@ -81,15 +85,18 @@
#include "llviewermenu.h"
#include "llviewerobjectlist.h"
#include "llviewerparcelmgr.h"
+#include "llviewerregion.h"
#include "llviewerstats.h"
#include "llviewerwindow.h"
#include "llvoavatarself.h"
#include "llwindow.h"
#include "llworld.h"
#include "llworldmap.h"
+#include "lscript_byteformat.h"
#include "stringize.h"
+#include "boost/foreach.hpp"
-using namespace LLVOAvatarDefines;
+using namespace LLAvatarAppearanceDefines;
extern LLMenuBarGL* gMenuBarView;
@@ -112,6 +119,105 @@ const F32 MAX_FIDGET_TIME = 20.f; // seconds
// The agent instance.
LLAgent gAgent;
+class LLTeleportRequest
+{
+public:
+ enum EStatus
+ {
+ kPending,
+ kStarted,
+ kFailed,
+ kRestartPending
+ };
+
+ LLTeleportRequest();
+ virtual ~LLTeleportRequest();
+
+ EStatus getStatus() const {return mStatus;};
+ void setStatus(EStatus pStatus) {mStatus = pStatus;};
+
+ virtual bool canRestartTeleport();
+
+ virtual void startTeleport() = 0;
+ virtual void restartTeleport();
+
+protected:
+
+private:
+ EStatus mStatus;
+};
+
+class LLTeleportRequestViaLandmark : public LLTeleportRequest
+{
+public:
+ LLTeleportRequestViaLandmark(const LLUUID &pLandmarkId);
+ virtual ~LLTeleportRequestViaLandmark();
+
+ virtual bool canRestartTeleport();
+
+ virtual void startTeleport();
+ virtual void restartTeleport();
+
+protected:
+ inline const LLUUID &getLandmarkId() const {return mLandmarkId;};
+
+private:
+ LLUUID mLandmarkId;
+};
+
+class LLTeleportRequestViaLure : public LLTeleportRequestViaLandmark
+{
+public:
+ LLTeleportRequestViaLure(const LLUUID &pLureId, BOOL pIsLureGodLike);
+ virtual ~LLTeleportRequestViaLure();
+
+ virtual bool canRestartTeleport();
+
+ virtual void startTeleport();
+
+protected:
+ inline BOOL isLureGodLike() const {return mIsLureGodLike;};
+
+private:
+ BOOL mIsLureGodLike;
+};
+
+class LLTeleportRequestViaLocation : public LLTeleportRequest
+{
+public:
+ LLTeleportRequestViaLocation(const LLVector3d &pPosGlobal);
+ virtual ~LLTeleportRequestViaLocation();
+
+ virtual bool canRestartTeleport();
+
+ virtual void startTeleport();
+ virtual void restartTeleport();
+
+protected:
+ inline const LLVector3d &getPosGlobal() const {return mPosGlobal;};
+
+private:
+ LLVector3d mPosGlobal;
+};
+
+
+class LLTeleportRequestViaLocationLookAt : public LLTeleportRequestViaLocation
+{
+public:
+ LLTeleportRequestViaLocationLookAt(const LLVector3d &pPosGlobal);
+ virtual ~LLTeleportRequestViaLocationLookAt();
+
+ virtual bool canRestartTeleport();
+
+ virtual void startTeleport();
+ virtual void restartTeleport();
+
+protected:
+
+private:
+
+};
+
//--------------------------------------------------------------------
// Statics
//
@@ -243,8 +349,20 @@ LLAgent::LLAgent() :
mbTeleportKeepsLookAt(false),
mAgentAccess(new LLAgentAccess(gSavedSettings)),
+ mGodLevelChangeSignal(),
mCanEditParcel(false),
mTeleportSourceSLURL(new LLSLURL),
+ mTeleportRequest(),
+ mTeleportFinishedSlot(),
+ mTeleportFailedSlot(),
+ mIsMaturityRatingChangingDuringTeleport(false),
+ mMaturityRatingChange(0U),
+ mIsDoSendMaturityPreferenceToServer(false),
+ mMaturityPreferenceRequestId(0U),
+ mMaturityPreferenceResponseId(0U),
+ mMaturityPreferenceNumRetries(0U),
+ mLastKnownRequestMaturity(SIM_ACCESS_MIN),
+ mLastKnownResponseMaturity(SIM_ACCESS_MIN),
mTeleportState( TELEPORT_NONE ),
mRegionp(NULL),
@@ -263,7 +381,7 @@ LLAgent::LLAgent() :
mShowAvatar(TRUE),
mFrameAgent(),
- mIsBusy(FALSE),
+ mIsDoNotDisturb(false),
mControlFlags(0x00000000),
mbFlagsDirty(FALSE),
@@ -319,7 +437,7 @@ void LLAgent::init()
{
mMoveTimer.start();
- gSavedSettings.declareBOOL("SlowMotionAnimation", FALSE, "Declared in code", FALSE);
+ gSavedSettings.declareBOOL("SlowMotionAnimation", FALSE, "Declared in code", LLControlVariable::PERSIST_NO);
gSavedSettings.getControl("SlowMotionAnimation")->getSignal()->connect(boost::bind(&handleSlowMotionAnimation, _2));
// *Note: this is where LLViewerCamera::getInstance() used to be constructed.
@@ -330,9 +448,21 @@ void LLAgent::init()
gSavedSettings.getControl("PreferredMaturity")->getValidateSignal()->connect(boost::bind(&LLAgent::validateMaturity, this, _2));
gSavedSettings.getControl("PreferredMaturity")->getSignal()->connect(boost::bind(&LLAgent::handleMaturity, this, _2));
+ mLastKnownResponseMaturity = static_cast<U8>(gSavedSettings.getU32("PreferredMaturity"));
+ mLastKnownRequestMaturity = mLastKnownResponseMaturity;
+ mIsDoSendMaturityPreferenceToServer = true;
LLViewerParcelMgr::getInstance()->addAgentParcelChangedCallback(boost::bind(&LLAgent::parcelChangedCallback));
+ if (!mTeleportFinishedSlot.connected())
+ {
+ mTeleportFinishedSlot = LLViewerParcelMgr::getInstance()->setTeleportFinishedCallback(boost::bind(&LLAgent::handleTeleportFinished, this));
+ }
+ if (!mTeleportFailedSlot.connected())
+ {
+ mTeleportFailedSlot = LLViewerParcelMgr::getInstance()->setTeleportFailedCallback(boost::bind(&LLAgent::handleTeleportFailed, this));
+ }
+
mInitialized = TRUE;
}
@@ -342,6 +472,14 @@ void LLAgent::init()
void LLAgent::cleanup()
{
mRegionp = NULL;
+ if (mTeleportFinishedSlot.connected())
+ {
+ mTeleportFinishedSlot.disconnect();
+ }
+ if (mTeleportFailedSlot.connected())
+ {
+ mTeleportFailedSlot.disconnect();
+ }
}
//-----------------------------------------------------------------------------
@@ -675,6 +813,29 @@ void LLAgent::standUp()
}
+void LLAgent::handleServerBakeRegionTransition(const LLUUID& region_id)
+{
+ llinfos << "called" << llendl;
+
+
+ // Old-style appearance entering a server-bake region.
+ if (isAgentAvatarValid() &&
+ !gAgentAvatarp->isUsingServerBakes() &&
+ (mRegionp->getCentralBakeVersion()>0))
+ {
+ llinfos << "update requested due to region transition" << llendl;
+ LLAppearanceMgr::instance().requestServerAppearanceUpdate();
+ }
+ // new-style appearance entering a non-bake region,
+ // need to check for existence of the baking service.
+ else if (isAgentAvatarValid() &&
+ gAgentAvatarp->isUsingServerBakes() &&
+ mRegionp->getCentralBakeVersion()==0)
+ {
+ gAgentAvatarp->checkForUnsupportedServerBakeAppearance();
+ }
+}
+
//-----------------------------------------------------------------------------
// setRegion()
//-----------------------------------------------------------------------------
@@ -773,6 +934,19 @@ void LLAgent::setRegion(LLViewerRegion *regionp)
{
LLEnvManagerNew::instance().onRegionCrossing();
}
+
+ // If the newly entered region is using server bakes, and our
+ // current appearance is non-baked, request appearance update from
+ // server.
+ if (mRegionp->capabilitiesReceived())
+ {
+ handleServerBakeRegionTransition(mRegionp->getRegionID());
+ }
+ else
+ {
+ // Need to handle via callback after caps arrive.
+ mRegionp->setCapabilitiesReceivedCallback(boost::bind(&LLAgent::handleServerBakeRegionTransition,this,_1));
+ }
}
@@ -922,11 +1096,19 @@ const LLVector3d &LLAgent::getPositionGlobal() const
//-----------------------------------------------------------------------------
const LLVector3 &LLAgent::getPositionAgent()
{
- if (isAgentAvatarValid() && !gAgentAvatarp->mDrawable.isNull())
+ if (isAgentAvatarValid())
{
- mFrameAgent.setOrigin(gAgentAvatarp->getRenderPosition());
+ if(gAgentAvatarp->mDrawable.isNull())
+ {
+ mFrameAgent.setOrigin(gAgentAvatarp->getPositionAgent());
+ }
+ else
+ {
+ mFrameAgent.setOrigin(gAgentAvatarp->getRenderPosition());
+ }
}
+
return mFrameAgent.getOrigin();
}
@@ -1226,12 +1408,7 @@ void LLAgent::setAFK()
{
sendAnimationRequest(ANIM_AGENT_AWAY, ANIM_REQUEST_START);
setControlFlags(AGENT_CONTROL_AWAY | AGENT_CONTROL_STOP);
- LL_INFOS("AFK") << "Setting Away" << LL_ENDL;
gAwayTimer.start();
- if (gAFKMenu)
- {
- gAFKMenu->setLabel(LLTrans::getString("AvatarSetNotAway"));
- }
}
}
@@ -1250,11 +1427,6 @@ void LLAgent::clearAFK()
{
sendAnimationRequest(ANIM_AGENT_AWAY, ANIM_REQUEST_STOP);
clearControlFlags(AGENT_CONTROL_AWAY);
- LL_INFOS("AFK") << "Clearing Away" << LL_ENDL;
- if (gAFKMenu)
- {
- gAFKMenu->setLabel(LLTrans::getString("AvatarSetAway"));
- }
}
}
@@ -1267,39 +1439,26 @@ BOOL LLAgent::getAFK() const
}
//-----------------------------------------------------------------------------
-// setBusy()
+// setDoNotDisturb()
//-----------------------------------------------------------------------------
-void LLAgent::setBusy()
+void LLAgent::setDoNotDisturb(bool pIsDoNotDisturb)
{
- sendAnimationRequest(ANIM_AGENT_BUSY, ANIM_REQUEST_START);
- mIsBusy = TRUE;
- if (gBusyMenu)
+ bool isDoNotDisturbSwitchedOff = (mIsDoNotDisturb && !pIsDoNotDisturb);
+ mIsDoNotDisturb = pIsDoNotDisturb;
+ sendAnimationRequest(ANIM_AGENT_DO_NOT_DISTURB, (pIsDoNotDisturb ? ANIM_REQUEST_START : ANIM_REQUEST_STOP));
+ LLNotificationsUI::LLChannelManager::getInstance()->muteAllChannels(pIsDoNotDisturb);
+ if (isDoNotDisturbSwitchedOff)
{
- gBusyMenu->setLabel(LLTrans::getString("AvatarSetNotBusy"));
+ LLDoNotDisturbNotificationStorage::getInstance()->updateNotifications();
}
- LLNotificationsUI::LLChannelManager::getInstance()->muteAllChannels(true);
}
//-----------------------------------------------------------------------------
-// clearBusy()
+// isDoNotDisturb()
//-----------------------------------------------------------------------------
-void LLAgent::clearBusy()
+bool LLAgent::isDoNotDisturb() const
{
- mIsBusy = FALSE;
- sendAnimationRequest(ANIM_AGENT_BUSY, ANIM_REQUEST_STOP);
- if (gBusyMenu)
- {
- gBusyMenu->setLabel(LLTrans::getString("AvatarSetBusy"));
- }
- LLNotificationsUI::LLChannelManager::getInstance()->muteAllChannels(false);
-}
-
-//-----------------------------------------------------------------------------
-// getBusy()
-//-----------------------------------------------------------------------------
-BOOL LLAgent::getBusy() const
-{
- return mIsBusy;
+ return mIsDoNotDisturb;
}
@@ -1578,13 +1737,11 @@ void LLAgent::autoPilot(F32 *delta_yaw)
*delta_yaw = yaw;
- // Compute when to start slowing down and when to stop
- F32 stop_distance = mAutoPilotStopDistance;
+ // Compute when to start slowing down
F32 slow_distance;
if (getFlying())
{
slow_distance = llmax(6.f, mAutoPilotStopDistance + 5.f);
- stop_distance = llmax(2.f, mAutoPilotStopDistance);
}
else
{
@@ -1781,7 +1938,8 @@ void LLAgent::startTyping()
{
sendAnimationRequest(ANIM_AGENT_TYPE, ANIM_REQUEST_START);
}
- LLNearbyChatBar::getInstance()->sendChatFromViewer("", CHAT_TYPE_START, FALSE);
+ (LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat"))->
+ sendChatFromViewer("", CHAT_TYPE_START, FALSE);
}
//-----------------------------------------------------------------------------
@@ -1793,7 +1951,8 @@ void LLAgent::stopTyping()
{
clearRenderState(AGENT_STATE_TYPING);
sendAnimationRequest(ANIM_AGENT_TYPE, ANIM_REQUEST_STOP);
- LLNearbyChatBar::getInstance()->sendChatFromViewer("", CHAT_TYPE_STOP, FALSE);
+ (LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat"))->
+ sendChatFromViewer("", CHAT_TYPE_STOP, FALSE);
}
}
@@ -1893,7 +2052,16 @@ void LLAgent::endAnimationUpdateUI()
{
skip_list.insert(LLFloaterReg::findInstance("mini_map"));
}
-
+
+ LLFloaterIMContainer* im_box = LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container");
+ LLFloaterIMContainer::floater_list_t conversations;
+ im_box->getDetachedConversationFloaters(conversations);
+ BOOST_FOREACH(LLFloater* conversation, conversations)
+ {
+ llinfos << "skip_list.insert(session_floater): " << conversation->getTitle() << llendl;
+ skip_list.insert(conversation);
+ }
+
gFloaterView->popVisibleAll(skip_list);
#endif
mViewsPushed = FALSE;
@@ -2168,7 +2336,7 @@ void LLAgent::setStartPosition( U32 location_id )
if (isAgentAvatarValid())
{
// the z height is at the agent's feet
- agent_pos.mV[VZ] -= 0.5f * gAgentAvatarp->mBodySize.mV[VZ];
+ agent_pos.mV[VZ] -= 0.5f * (gAgentAvatarp->mBodySize.mV[VZ] + gAgentAvatarp->mAvatarOffset.mV[VZ]);
}
agent_pos.mV[VX] = llclamp( agent_pos.mV[VX], INSET, REGION_WIDTH - INSET );
@@ -2374,49 +2542,249 @@ bool LLAgent::isAdult() const
return mAgentAccess->isAdult();
}
-void LLAgent::setTeen(bool teen)
-{
- mAgentAccess->setTeen(teen);
-}
-
//static
int LLAgent::convertTextToMaturity(char text)
{
return LLAgentAccess::convertTextToMaturity(text);
}
-bool LLAgent::sendMaturityPreferenceToServer(int preferredMaturity)
+class LLMaturityPreferencesResponder : public LLHTTPClient::Responder
{
- if (!getRegion())
- return false;
-
- // Update agent access preference on the server
- std::string url = getRegion()->getCapability("UpdateAgentInformation");
- if (!url.empty())
+public:
+ LLMaturityPreferencesResponder(LLAgent *pAgent, U8 pPreferredMaturity, U8 pPreviousMaturity);
+ virtual ~LLMaturityPreferencesResponder();
+
+ virtual void result(const LLSD &pContent);
+ virtual void errorWithContent(U32 pStatus, const std::string& pReason, const LLSD& pContent);
+
+protected:
+
+private:
+ U8 parseMaturityFromServerResponse(const LLSD &pContent);
+
+ LLAgent *mAgent;
+ U8 mPreferredMaturity;
+ U8 mPreviousMaturity;
+};
+
+LLMaturityPreferencesResponder::LLMaturityPreferencesResponder(LLAgent *pAgent, U8 pPreferredMaturity, U8 pPreviousMaturity)
+ : LLHTTPClient::Responder(),
+ mAgent(pAgent),
+ mPreferredMaturity(pPreferredMaturity),
+ mPreviousMaturity(pPreviousMaturity)
+{
+}
+
+LLMaturityPreferencesResponder::~LLMaturityPreferencesResponder()
+{
+}
+
+void LLMaturityPreferencesResponder::result(const LLSD &pContent)
+{
+ U8 actualMaturity = parseMaturityFromServerResponse(pContent);
+
+ if (actualMaturity != mPreferredMaturity)
{
- // Set new access preference
- LLSD access_prefs = LLSD::emptyMap();
- if (preferredMaturity == SIM_ACCESS_PG)
+ llwarns << "while attempting to change maturity preference from '" << LLViewerRegion::accessToString(mPreviousMaturity)
+ << "' to '" << LLViewerRegion::accessToString(mPreferredMaturity) << "', the server responded with '"
+ << LLViewerRegion::accessToString(actualMaturity) << "' [value:" << static_cast<U32>(actualMaturity) << ", llsd:"
+ << pContent << "]" << llendl;
+ }
+ mAgent->handlePreferredMaturityResult(actualMaturity);
+}
+
+void LLMaturityPreferencesResponder::errorWithContent(U32 pStatus, const std::string& pReason, const LLSD& pContent)
+{
+ llwarns << "while attempting to change maturity preference from '" << LLViewerRegion::accessToString(mPreviousMaturity)
+ << "' to '" << LLViewerRegion::accessToString(mPreferredMaturity) << "', we got an error with [status:"
+ << pStatus << "]: " << (pContent.isDefined() ? pContent : LLSD(pReason)) << llendl;
+ mAgent->handlePreferredMaturityError();
+}
+
+U8 LLMaturityPreferencesResponder::parseMaturityFromServerResponse(const LLSD &pContent)
+{
+ U8 maturity = SIM_ACCESS_MIN;
+
+ llassert(!pContent.isUndefined());
+ llassert(pContent.isMap());
+ llassert(pContent.has("access_prefs"));
+ llassert(pContent.get("access_prefs").isMap());
+ llassert(pContent.get("access_prefs").has("max"));
+ llassert(pContent.get("access_prefs").get("max").isString());
+ if (!pContent.isUndefined() && pContent.isMap() && pContent.has("access_prefs")
+ && pContent.get("access_prefs").isMap() && pContent.get("access_prefs").has("max")
+ && pContent.get("access_prefs").get("max").isString())
+ {
+ LLSD::String actualPreference = pContent.get("access_prefs").get("max").asString();
+ LLStringUtil::trim(actualPreference);
+ maturity = LLViewerRegion::shortStringToAccess(actualPreference);
+ }
+
+ return maturity;
+}
+
+void LLAgent::handlePreferredMaturityResult(U8 pServerMaturity)
+{
+ // Update the number of responses received
+ ++mMaturityPreferenceResponseId;
+ llassert(mMaturityPreferenceResponseId <= mMaturityPreferenceRequestId);
+
+ // Update the last known server maturity response
+ mLastKnownResponseMaturity = pServerMaturity;
+
+ // Ignore all responses if we know there are more unanswered requests that are expected
+ if (mMaturityPreferenceResponseId == mMaturityPreferenceRequestId)
+ {
+ // If we received a response that matches the last known request, then we are good
+ if (mLastKnownRequestMaturity == mLastKnownResponseMaturity)
{
- access_prefs["max"] = "PG";
+ mMaturityPreferenceNumRetries = 0;
+ reportPreferredMaturitySuccess();
+ llassert(static_cast<U8>(gSavedSettings.getU32("PreferredMaturity")) == mLastKnownResponseMaturity);
}
- else if (preferredMaturity == SIM_ACCESS_MATURE)
+ // Else, the viewer is out of sync with the server, so let's try to re-sync with the
+ // server by re-sending our last known request. Cap the re-tries at 3 just to be safe.
+ else if (++mMaturityPreferenceNumRetries <= 3)
{
- access_prefs["max"] = "M";
+ llinfos << "Retrying attempt #" << mMaturityPreferenceNumRetries << " to set viewer preferred maturity to '"
+ << LLViewerRegion::accessToString(mLastKnownRequestMaturity) << "'" << llendl;
+ sendMaturityPreferenceToServer(mLastKnownRequestMaturity);
}
- if (preferredMaturity == SIM_ACCESS_ADULT)
+ // Else, the viewer is style out of sync with the server after 3 retries, so inform the user
+ else
{
- access_prefs["max"] = "A";
+ mMaturityPreferenceNumRetries = 0;
+ reportPreferredMaturityError();
+ }
+ }
+}
+
+void LLAgent::handlePreferredMaturityError()
+{
+ // Update the number of responses received
+ ++mMaturityPreferenceResponseId;
+ llassert(mMaturityPreferenceResponseId <= mMaturityPreferenceRequestId);
+
+ // Ignore all responses if we know there are more unanswered requests that are expected
+ if (mMaturityPreferenceResponseId == mMaturityPreferenceRequestId)
+ {
+ mMaturityPreferenceNumRetries = 0;
+
+ // If we received a response that matches the last known request, then we are synced with
+ // the server, but not quite sure why we are
+ if (mLastKnownRequestMaturity == mLastKnownResponseMaturity)
+ {
+ llwarns << "Got an error but maturity preference '" << LLViewerRegion::accessToString(mLastKnownRequestMaturity)
+ << "' seems to be in sync with the server" << llendl;
+ reportPreferredMaturitySuccess();
+ }
+ // Else, the more likely case is that the last request does not match the last response,
+ // so inform the user
+ else
+ {
+ reportPreferredMaturityError();
+ }
+ }
+}
+
+void LLAgent::reportPreferredMaturitySuccess()
+{
+ // If there is a pending teleport request waiting for the maturity preference to be synced with
+ // the server, let's start the pending request
+ if (hasPendingTeleportRequest())
+ {
+ startTeleportRequest();
+ }
+}
+
+void LLAgent::reportPreferredMaturityError()
+{
+ // If there is a pending teleport request waiting for the maturity preference to be synced with
+ // the server, we were unable to successfully sync with the server on maturity preference, so let's
+ // just raise the screen.
+ mIsMaturityRatingChangingDuringTeleport = false;
+ if (hasPendingTeleportRequest())
+ {
+ setTeleportState(LLAgent::TELEPORT_NONE);
+ }
+
+ // Get the last known maturity request from the user activity
+ std::string preferredMaturity = LLViewerRegion::accessToString(mLastKnownRequestMaturity);
+ LLStringUtil::toLower(preferredMaturity);
+
+ // Get the last known maturity response from the server
+ std::string actualMaturity = LLViewerRegion::accessToString(mLastKnownResponseMaturity);
+ LLStringUtil::toLower(actualMaturity);
+
+ // Notify the user
+ LLSD args = LLSD::emptyMap();
+ args["PREFERRED_MATURITY"] = preferredMaturity;
+ args["ACTUAL_MATURITY"] = actualMaturity;
+ LLNotificationsUtil::add("MaturityChangeError", args);
+
+ // Check the saved settings to ensure that we are consistent. If we are not consistent, update
+ // the viewer, but do not send anything to server
+ U8 localMaturity = static_cast<U8>(gSavedSettings.getU32("PreferredMaturity"));
+ if (localMaturity != mLastKnownResponseMaturity)
+ {
+ bool tmpIsDoSendMaturityPreferenceToServer = mIsDoSendMaturityPreferenceToServer;
+ mIsDoSendMaturityPreferenceToServer = false;
+ llinfos << "Setting viewer preferred maturity to '" << LLViewerRegion::accessToString(mLastKnownResponseMaturity) << "'" << llendl;
+ gSavedSettings.setU32("PreferredMaturity", static_cast<U32>(mLastKnownResponseMaturity));
+ mIsDoSendMaturityPreferenceToServer = tmpIsDoSendMaturityPreferenceToServer;
+ }
+}
+
+bool LLAgent::isMaturityPreferenceSyncedWithServer() const
+{
+ return (mMaturityPreferenceRequestId == mMaturityPreferenceResponseId);
+}
+
+void LLAgent::sendMaturityPreferenceToServer(U8 pPreferredMaturity)
+{
+ // Only send maturity preference to the server if enabled
+ if (mIsDoSendMaturityPreferenceToServer)
+ {
+ // Increment the number of requests. The handlers manage a separate count of responses.
+ ++mMaturityPreferenceRequestId;
+
+ // Update the last know maturity request
+ mLastKnownRequestMaturity = pPreferredMaturity;
+
+ // Create a response handler
+ LLHTTPClient::ResponderPtr responderPtr = LLHTTPClient::ResponderPtr(new LLMaturityPreferencesResponder(this, pPreferredMaturity, mLastKnownResponseMaturity));
+
+ // If we don't have a region, report it as an error
+ if (getRegion() == NULL)
+ {
+ responderPtr->errorWithContent(0U, "region is not defined", LLSD());
+ }
+ else
+ {
+ // Find the capability to send maturity preference
+ std::string url = getRegion()->getCapability("UpdateAgentInformation");
+
+ // If the capability is not defined, report it as an error
+ if (url.empty())
+ {
+ responderPtr->errorWithContent(0U,
+ "capability 'UpdateAgentInformation' is not defined for region", LLSD());
+ }
+ else
+ {
+ // Set new access preference
+ LLSD access_prefs = LLSD::emptyMap();
+ access_prefs["max"] = LLViewerRegion::accessToShortString(pPreferredMaturity);
+
+ LLSD body = LLSD::emptyMap();
+ body["access_prefs"] = access_prefs;
+ llinfos << "Sending viewer preferred maturity to '" << LLViewerRegion::accessToString(pPreferredMaturity)
+ << "' via capability to: " << url << llendl;
+ LLSD headers;
+ LLHTTPClient::post(url, body, responderPtr, headers, 30.0f);
+ }
}
-
- LLSD body = LLSD::emptyMap();
- body["access_prefs"] = access_prefs;
- llinfos << "Sending access prefs update to " << (access_prefs["max"].asString()) << " via capability to: "
- << url << llendl;
- LLHTTPClient::post(url, body, new LLHTTPClient::Responder()); // Ignore response
- return true;
}
- return false;
}
BOOL LLAgent::getAdminOverride() const
@@ -2437,11 +2805,12 @@ void LLAgent::setAdminOverride(BOOL b)
void LLAgent::setGodLevel(U8 god_level)
{
mAgentAccess->setGodLevel(god_level);
+ mGodLevelChangeSignal(god_level);
}
-void LLAgent::setAOTransition()
+LLAgent::god_level_change_slot_t LLAgent::registerGodLevelChanageListener(god_level_change_callback_t pGodLevelChangeCallback)
{
- mAgentAccess->setTransition();
+ return mGodLevelChangeSignal.connect(pGodLevelChangeCallback);
}
const LLAgentAccess& LLAgent::getAgentAccess()
@@ -2454,9 +2823,9 @@ bool LLAgent::validateMaturity(const LLSD& newvalue)
return mAgentAccess->canSetMaturity(newvalue.asInteger());
}
-void LLAgent::handleMaturity(const LLSD& newvalue)
+void LLAgent::handleMaturity(const LLSD &pNewValue)
{
- sendMaturityPreferenceToServer(newvalue.asInteger());
+ sendMaturityPreferenceToServer(static_cast<U8>(pNewValue.asInteger()));
}
//----------------------------------------------------------------------------
@@ -2703,6 +3072,55 @@ void LLAgent::sendAnimationRequest(const LLUUID &anim_id, EAnimRequest request)
sendReliableMessage();
}
+// Send a message to the region to stop the NULL animation state
+// This will reset animation state overrides for the agent.
+void LLAgent::sendAnimationStateReset()
+{
+ if (gAgentID.isNull() || !mRegionp)
+ {
+ return;
+ }
+
+ LLMessageSystem* msg = gMessageSystem;
+ msg->newMessageFast(_PREHASH_AgentAnimation);
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, getID());
+ msg->addUUIDFast(_PREHASH_SessionID, getSessionID());
+
+ msg->nextBlockFast(_PREHASH_AnimationList);
+ msg->addUUIDFast(_PREHASH_AnimID, LLUUID::null );
+ msg->addBOOLFast(_PREHASH_StartAnim, FALSE);
+
+ msg->nextBlockFast(_PREHASH_PhysicalAvatarEventList);
+ msg->addBinaryDataFast(_PREHASH_TypeData, NULL, 0);
+ sendReliableMessage();
+}
+
+
+// Send a message to the region to revoke sepecified permissions on ALL scripts in the region
+// If the target is an object in the region, permissions in scripts on that object are cleared.
+// If it is the region ID, all scripts clear the permissions for this agent
+void LLAgent::sendRevokePermissions(const LLUUID & target, U32 permissions)
+{
+ // Currently only the bits for SCRIPT_PERMISSION_TRIGGER_ANIMATION and SCRIPT_PERMISSION_OVERRIDE_ANIMATIONS
+ // are supported by the server. Sending any other bits will cause the message to be dropped without changing permissions
+
+ if (gAgentID.notNull() && gMessageSystem)
+ {
+ LLMessageSystem* msg = gMessageSystem;
+ msg->newMessageFast(_PREHASH_RevokePermissions);
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, getID()); // Must be our ID
+ msg->addUUIDFast(_PREHASH_SessionID, getSessionID());
+
+ msg->nextBlockFast(_PREHASH_Data);
+ msg->addUUIDFast(_PREHASH_ObjectID, target); // Must be in the region
+ msg->addS32Fast(_PREHASH_ObjectPermissions, (S32) permissions);
+
+ sendReliableMessage();
+ }
+}
+
void LLAgent::sendWalkRun(bool running)
{
LLMessageSystem* msgsys = gMessageSystem;
@@ -3256,6 +3674,10 @@ void LLAgent::processControlRelease(LLMessageSystem *msg, void **)
void LLAgent::processAgentCachedTextureResponse(LLMessageSystem *mesgsys, void **user_data)
{
gAgentQueryManager.mNumPendingQueries--;
+ if (gAgentQueryManager.mNumPendingQueries == 0)
+ {
+ selfStopPhase("fetch_texture_cache_entries");
+ }
if (!isAgentAvatarValid() || gAgentAvatarp->isDead())
{
@@ -3263,7 +3685,7 @@ void LLAgent::processAgentCachedTextureResponse(LLMessageSystem *mesgsys, void *
return;
}
- if (isAgentAvatarValid() && !gAgentAvatarp->isUsingBakedTextures())
+ if (isAgentAvatarValid() && gAgentAvatarp->isEditingAppearance())
{
// ignore baked textures when in customize mode
return;
@@ -3287,7 +3709,7 @@ void LLAgent::processAgentCachedTextureResponse(LLMessageSystem *mesgsys, void *
if ((S32)texture_index < TEX_NUM_INDICES )
{
- const LLVOAvatarDictionary::TextureEntry *texture_entry = LLVOAvatarDictionary::instance().getTexture((ETextureIndex)texture_index);
+ const LLAvatarAppearanceDictionary::TextureEntry *texture_entry = LLAvatarAppearanceDictionary::instance().getTexture((ETextureIndex)texture_index);
if (texture_entry)
{
EBakedTextureIndex baked_index = texture_entry->mBakedTextureIndex;
@@ -3305,13 +3727,12 @@ void LLAgent::processAgentCachedTextureResponse(LLMessageSystem *mesgsys, void *
else
{
// no cache of this bake. request upload.
- gAgentAvatarp->requestLayerSetUpload(baked_index);
+ gAgentAvatarp->invalidateComposite(gAgentAvatarp->getLayerSet(baked_index),TRUE);
}
}
}
}
}
-
llinfos << "Received cached texture response for " << num_results << " textures." << llendl;
gAgentAvatarp->outputRezTiming("Fetched agent wearables textures from cache. Will now load them");
@@ -3388,7 +3809,7 @@ void LLAgent::clearVisualParams(void *data)
// protected
bool LLAgent::teleportCore(bool is_local)
{
- if(TELEPORT_NONE != mTeleportState)
+ if ((TELEPORT_NONE != mTeleportState) && (mTeleportState != TELEPORT_PENDING))
{
llwarns << "Attempt to teleport when already teleporting." << llendl;
return false;
@@ -3466,6 +3887,102 @@ bool LLAgent::teleportCore(bool is_local)
return true;
}
+bool LLAgent::hasRestartableFailedTeleportRequest()
+{
+ return ((mTeleportRequest != NULL) && (mTeleportRequest->getStatus() == LLTeleportRequest::kFailed) &&
+ mTeleportRequest->canRestartTeleport());
+}
+
+void LLAgent::restartFailedTeleportRequest()
+{
+ if (hasRestartableFailedTeleportRequest())
+ {
+ mTeleportRequest->setStatus(LLTeleportRequest::kRestartPending);
+ startTeleportRequest();
+ }
+}
+
+void LLAgent::clearTeleportRequest()
+{
+ mTeleportRequest.reset();
+}
+
+void LLAgent::setMaturityRatingChangeDuringTeleport(U8 pMaturityRatingChange)
+{
+ mIsMaturityRatingChangingDuringTeleport = true;
+ mMaturityRatingChange = pMaturityRatingChange;
+}
+
+bool LLAgent::hasPendingTeleportRequest()
+{
+ return ((mTeleportRequest != NULL) &&
+ ((mTeleportRequest->getStatus() == LLTeleportRequest::kPending) ||
+ (mTeleportRequest->getStatus() == LLTeleportRequest::kRestartPending)));
+}
+
+void LLAgent::startTeleportRequest()
+{
+ if (hasPendingTeleportRequest())
+ {
+ if (!isMaturityPreferenceSyncedWithServer())
+ {
+ gTeleportDisplay = TRUE;
+ setTeleportState(TELEPORT_PENDING);
+ }
+ else
+ {
+ switch (mTeleportRequest->getStatus())
+ {
+ case LLTeleportRequest::kPending :
+ mTeleportRequest->setStatus(LLTeleportRequest::kStarted);
+ mTeleportRequest->startTeleport();
+ break;
+ case LLTeleportRequest::kRestartPending :
+ llassert(mTeleportRequest->canRestartTeleport());
+ mTeleportRequest->setStatus(LLTeleportRequest::kStarted);
+ mTeleportRequest->restartTeleport();
+ break;
+ default :
+ llassert(0);
+ break;
+ }
+ }
+ }
+}
+
+void LLAgent::handleTeleportFinished()
+{
+ clearTeleportRequest();
+ if (mIsMaturityRatingChangingDuringTeleport)
+ {
+ // notify user that the maturity preference has been changed
+ std::string maturityRating = LLViewerRegion::accessToString(mMaturityRatingChange);
+ LLStringUtil::toLower(maturityRating);
+ LLSD args;
+ args["RATING"] = maturityRating;
+ LLNotificationsUtil::add("PreferredMaturityChanged", args);
+ mIsMaturityRatingChangingDuringTeleport = false;
+ }
+}
+
+void LLAgent::handleTeleportFailed()
+{
+ if (mTeleportRequest != NULL)
+ {
+ mTeleportRequest->setStatus(LLTeleportRequest::kFailed);
+ }
+ if (mIsMaturityRatingChangingDuringTeleport)
+ {
+ // notify user that the maturity preference has been changed
+ std::string maturityRating = LLViewerRegion::accessToString(mMaturityRatingChange);
+ LLStringUtil::toLower(maturityRating);
+ LLSD args;
+ args["RATING"] = maturityRating;
+ LLNotificationsUtil::add("PreferredMaturityChanged", args);
+ mIsMaturityRatingChangingDuringTeleport = false;
+ }
+}
+
void LLAgent::teleportRequest(
const U64& region_handle,
const LLVector3& pos_local,
@@ -3498,6 +4015,12 @@ void LLAgent::teleportRequest(
// Landmark ID = LLUUID::null means teleport home
void LLAgent::teleportViaLandmark(const LLUUID& landmark_asset_id)
{
+ mTeleportRequest = LLTeleportRequestPtr(new LLTeleportRequestViaLandmark(landmark_asset_id));
+ startTeleportRequest();
+}
+
+void LLAgent::doTeleportViaLandmark(const LLUUID& landmark_asset_id)
+{
LLViewerRegion *regionp = getRegion();
if(regionp && teleportCore())
{
@@ -3513,6 +4036,12 @@ void LLAgent::teleportViaLandmark(const LLUUID& landmark_asset_id)
void LLAgent::teleportViaLure(const LLUUID& lure_id, BOOL godlike)
{
+ mTeleportRequest = LLTeleportRequestPtr(new LLTeleportRequestViaLure(lure_id, godlike));
+ startTeleportRequest();
+}
+
+void LLAgent::doTeleportViaLure(const LLUUID& lure_id, BOOL godlike)
+{
LLViewerRegion* regionp = getRegion();
if(regionp && teleportCore())
{
@@ -3544,25 +4073,40 @@ void LLAgent::teleportViaLure(const LLUUID& lure_id, BOOL godlike)
// James Cook, July 28, 2005
void LLAgent::teleportCancel()
{
- LLViewerRegion* regionp = getRegion();
- if(regionp)
+ if (!hasPendingTeleportRequest())
{
- // send the message
- LLMessageSystem* msg = gMessageSystem;
- msg->newMessage("TeleportCancel");
- msg->nextBlockFast(_PREHASH_Info);
- msg->addUUIDFast(_PREHASH_AgentID, getID());
- msg->addUUIDFast(_PREHASH_SessionID, getSessionID());
- sendReliableMessage();
- }
- gTeleportDisplay = FALSE;
+ LLViewerRegion* regionp = getRegion();
+ if(regionp)
+ {
+ // send the message
+ LLMessageSystem* msg = gMessageSystem;
+ msg->newMessage("TeleportCancel");
+ msg->nextBlockFast(_PREHASH_Info);
+ msg->addUUIDFast(_PREHASH_AgentID, getID());
+ msg->addUUIDFast(_PREHASH_SessionID, getSessionID());
+ sendReliableMessage();
+ }
+ }
+ clearTeleportRequest();
gAgent.setTeleportState( LLAgent::TELEPORT_NONE );
}
void LLAgent::teleportViaLocation(const LLVector3d& pos_global)
{
+ mTeleportRequest = LLTeleportRequestPtr(new LLTeleportRequestViaLocation(pos_global));
+ startTeleportRequest();
+}
+
+void LLAgent::doTeleportViaLocation(const LLVector3d& pos_global)
+{
LLViewerRegion* regionp = getRegion();
+
+ if (!regionp)
+ {
+ return;
+ }
+
U64 handle = to_region_handle(pos_global);
LLSimInfo* info = LLWorldMap::getInstance()->simInfoFromHandle(handle);
if(regionp && info)
@@ -3604,6 +4148,12 @@ void LLAgent::teleportViaLocation(const LLVector3d& pos_global)
// Teleport to global position, but keep facing in the same direction
void LLAgent::teleportViaLocationLookAt(const LLVector3d& pos_global)
{
+ mTeleportRequest = LLTeleportRequestPtr(new LLTeleportRequestViaLocationLookAt(pos_global));
+ startTeleportRequest();
+}
+
+void LLAgent::doTeleportViaLocationLookAt(const LLVector3d& pos_global)
+{
mbTeleportKeepsLookAt = true;
gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE); // detach camera form avatar, so it keeps direction
U64 region_handle = to_region_handle(pos_global);
@@ -3649,6 +4199,8 @@ void LLAgent::stopCurrentAnimations()
// avatar, propagating this change back to the server.
if (isAgentAvatarValid())
{
+ LLDynamicArray<LLUUID> anim_ids;
+
for ( LLVOAvatar::AnimIterator anim_it =
gAgentAvatarp->mPlayingAnimations.begin();
anim_it != gAgentAvatarp->mPlayingAnimations.end();
@@ -3666,7 +4218,24 @@ void LLAgent::stopCurrentAnimations()
// stop this animation locally
gAgentAvatarp->stopMotion(anim_it->first, TRUE);
// ...and tell the server to tell everyone.
- sendAnimationRequest(anim_it->first, ANIM_REQUEST_STOP);
+ anim_ids.push_back(anim_it->first);
+ }
+ }
+
+ sendAnimationRequests(anim_ids, ANIM_REQUEST_STOP);
+
+ // Tell the region to clear any animation state overrides
+ sendAnimationStateReset();
+
+ // Revoke all animation permissions
+ if (mRegionp &&
+ gSavedSettings.getBOOL("RevokePermsOnStopAnimation"))
+ {
+ U32 permissions = LSCRIPTRunTimePermissionBits[SCRIPT_PERMISSION_TRIGGER_ANIMATION] | LSCRIPTRunTimePermissionBits[SCRIPT_PERMISSION_OVERRIDE_ANIMATIONS];
+ sendRevokePermissions(mRegionp->getRegionID(), permissions);
+ if (gAgentAvatarp->isSitting())
+ { // Also stand up, since auto-granted sit animation permission has been revoked
+ gAgent.standUp();
}
}
@@ -3766,19 +4335,82 @@ void LLAgent::requestLeaveGodMode()
sendReliableMessage();
}
+// For debugging, trace agent state at times appearance message are sent out.
+void LLAgent::dumpSentAppearance(const std::string& dump_prefix)
+{
+ std::string outfilename = get_sequential_numbered_file_name(dump_prefix,".xml");
+
+ LLAPRFile outfile;
+ std::string fullpath = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,outfilename);
+ outfile.open(fullpath, LL_APR_WB );
+ apr_file_t* file = outfile.getFileHandle();
+ if (!file)
+ {
+ return;
+ }
+ else
+ {
+ LL_DEBUGS("Avatar") << "dumping sent appearance message to " << fullpath << llendl;
+ }
+
+ LLVisualParam* appearance_version_param = gAgentAvatarp->getVisualParam(11000);
+ if (appearance_version_param)
+ {
+ F32 value = appearance_version_param->getWeight();
+ dump_visual_param(file, appearance_version_param, value);
+ }
+ for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getTextures().begin();
+ iter != LLAvatarAppearanceDictionary::getInstance()->getTextures().end();
+ ++iter)
+ {
+ const ETextureIndex index = iter->first;
+ const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = iter->second;
+ if (texture_dict->mIsBakedTexture)
+ {
+ LLTextureEntry* entry = gAgentAvatarp->getTE((U8) index);
+ const LLUUID& uuid = entry->getID();
+ apr_file_printf( file, "\t\t<texture te=\"%i\" uuid=\"%s\"/>\n", index, uuid.asString().c_str());
+ }
+ }
+}
+
//-----------------------------------------------------------------------------
// sendAgentSetAppearance()
//-----------------------------------------------------------------------------
void LLAgent::sendAgentSetAppearance()
{
- if (!isAgentAvatarValid()) return;
-
- if (gAgentQueryManager.mNumPendingQueries > 0 && (isAgentAvatarValid() && gAgentAvatarp->isUsingBakedTextures()))
+ if (gAgentQueryManager.mNumPendingQueries > 0)
{
return;
}
- llinfos << "TAT: Sent AgentSetAppearance: " << gAgentAvatarp->getBakedStatusForPrintout() << llendl;
+ if (!isAgentAvatarValid() || (getRegion() && getRegion()->getCentralBakeVersion())) return;
+
+ // At this point we have a complete appearance to send and are in a non-baking region.
+ // DRANO FIXME
+ //gAgentAvatarp->setIsUsingServerBakes(FALSE);
+ S32 sb_count, host_count, both_count, neither_count;
+ gAgentAvatarp->bakedTextureOriginCounts(sb_count, host_count, both_count, neither_count);
+ if (both_count != 0 || neither_count != 0)
+ {
+ llwarns << "bad bake texture state " << sb_count << "," << host_count << "," << both_count << "," << neither_count << llendl;
+ }
+ if (sb_count != 0 && host_count == 0)
+ {
+ gAgentAvatarp->setIsUsingServerBakes(true);
+ }
+ else if (sb_count == 0 && host_count != 0)
+ {
+ gAgentAvatarp->setIsUsingServerBakes(false);
+ }
+ else if (sb_count + host_count > 0)
+ {
+ llwarns << "unclear baked texture state, not sending appearance" << llendl;
+ return;
+ }
+
+
+ LL_DEBUGS("Avatar") << gAgentAvatarp->avString() << "TAT: Sent AgentSetAppearance: " << gAgentAvatarp->getBakedStatusForPrintout() << LL_ENDL;
//dumpAvatarTEs( "sendAgentSetAppearance()" );
LLMessageSystem* msg = gMessageSystem;
@@ -3792,7 +4424,7 @@ void LLAgent::sendAgentSetAppearance()
// NOTE -- when we start correcting all of the other Havok geometry
// to compensate for the COLLISION_TOLERANCE ugliness we will have
// to tweak this number again
- const LLVector3 body_size = gAgentAvatarp->mBodySize;
+ const LLVector3 body_size = gAgentAvatarp->mBodySize + gAgentAvatarp->mAvatarOffset;
msg->addVector3Fast(_PREHASH_Size, body_size);
// To guard against out of order packets
@@ -3806,7 +4438,7 @@ void LLAgent::sendAgentSetAppearance()
for(U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++ )
{
- const ETextureIndex texture_index = LLVOAvatarDictionary::bakedToLocalTextureIndex((EBakedTextureIndex)baked_index);
+ const ETextureIndex texture_index = LLAvatarAppearanceDictionary::bakedToLocalTextureIndex((EBakedTextureIndex)baked_index);
// if we're not wearing a skirt, we don't need the texture to be baked
if (texture_index == TEX_SKIRT_BAKED && !gAgentAvatarp->isWearingWearableType(LLWearableType::WT_SKIRT))
@@ -3817,28 +4449,39 @@ void LLAgent::sendAgentSetAppearance()
// IMG_DEFAULT_AVATAR means not baked. 0 index should be ignored for baked textures
if (!gAgentAvatarp->isTextureDefined(texture_index, 0))
{
+ LL_DEBUGS("Avatar") << "texture not current for baked " << (S32)baked_index << " local " << (S32)texture_index << llendl;
textures_current = FALSE;
break;
}
}
// only update cache entries if we have all our baked textures
+
+ // FIXME DRANO need additional check for not in appearance editing
+ // mode, if still using local composites need to set using local
+ // composites to false, and update mesh textures.
if (textures_current)
{
- llinfos << "TAT: Sending cached texture data" << llendl;
+ bool enable_verbose_dumps = gSavedSettings.getBOOL("DebugAvatarAppearanceMessage");
+ std::string dump_prefix = gAgentAvatarp->getFullname() + "_sent_appearance";
+ if (enable_verbose_dumps)
+ {
+ dumpSentAppearance(dump_prefix);
+ }
+ LL_DEBUGS("Avatar") << gAgentAvatarp->avString() << "TAT: Sending cached texture data" << LL_ENDL;
for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++)
{
BOOL generate_valid_hash = TRUE;
- if (isAgentAvatarValid() && !gAgentAvatarp->isBakedTextureFinal((LLVOAvatarDefines::EBakedTextureIndex)baked_index))
+ if (isAgentAvatarValid() && !gAgentAvatarp->isBakedTextureFinal((LLAvatarAppearanceDefines::EBakedTextureIndex)baked_index))
{
generate_valid_hash = FALSE;
- llinfos << "Not caching baked texture upload for " << (U32)baked_index << " due to being uploaded at low resolution." << llendl;
+ LL_DEBUGS("Avatar") << gAgentAvatarp->avString() << "Not caching baked texture upload for " << (U32)baked_index << " due to being uploaded at low resolution." << LL_ENDL;
}
const LLUUID hash = gAgentWearables.computeBakedTextureHash((EBakedTextureIndex) baked_index, generate_valid_hash);
if (hash.notNull())
{
- ETextureIndex texture_index = LLVOAvatarDictionary::bakedToLocalTextureIndex((EBakedTextureIndex) baked_index);
+ ETextureIndex texture_index = LLAvatarAppearanceDictionary::bakedToLocalTextureIndex((EBakedTextureIndex) baked_index);
msg->nextBlockFast(_PREHASH_WearableData);
msg->addUUIDFast(_PREHASH_CacheID, hash);
msg->addU8Fast(_PREHASH_TextureIndex, (U8)texture_index);
@@ -4037,5 +4680,149 @@ LLAgentQueryManager::~LLAgentQueryManager()
{
}
-// EOF
+//-----------------------------------------------------------------------------
+// LLTeleportRequest
+//-----------------------------------------------------------------------------
+
+LLTeleportRequest::LLTeleportRequest()
+ : mStatus(kPending)
+{
+}
+
+LLTeleportRequest::~LLTeleportRequest()
+{
+}
+
+bool LLTeleportRequest::canRestartTeleport()
+{
+ return false;
+}
+
+void LLTeleportRequest::restartTeleport()
+{
+ llassert(0);
+}
+
+//-----------------------------------------------------------------------------
+// LLTeleportRequestViaLandmark
+//-----------------------------------------------------------------------------
+
+LLTeleportRequestViaLandmark::LLTeleportRequestViaLandmark(const LLUUID &pLandmarkId)
+ : LLTeleportRequest(),
+ mLandmarkId(pLandmarkId)
+{
+}
+
+LLTeleportRequestViaLandmark::~LLTeleportRequestViaLandmark()
+{
+}
+
+bool LLTeleportRequestViaLandmark::canRestartTeleport()
+{
+ return true;
+}
+
+void LLTeleportRequestViaLandmark::startTeleport()
+{
+ gAgent.doTeleportViaLandmark(getLandmarkId());
+}
+
+void LLTeleportRequestViaLandmark::restartTeleport()
+{
+ gAgent.doTeleportViaLandmark(getLandmarkId());
+}
+
+//-----------------------------------------------------------------------------
+// LLTeleportRequestViaLure
+//-----------------------------------------------------------------------------
+LLTeleportRequestViaLure::LLTeleportRequestViaLure(const LLUUID &pLureId, BOOL pIsLureGodLike)
+ : LLTeleportRequestViaLandmark(pLureId),
+ mIsLureGodLike(pIsLureGodLike)
+{
+}
+
+LLTeleportRequestViaLure::~LLTeleportRequestViaLure()
+{
+}
+
+bool LLTeleportRequestViaLure::canRestartTeleport()
+{
+ // stinson 05/17/2012 : cannot restart a teleport via lure because of server-side restrictions
+ // The current scenario is as follows:
+ // 1. User A initializes a request for User B to teleport via lure
+ // 2. User B accepts the teleport via lure request
+ // 3. The server sees the init request from User A and the accept request from User B and matches them up
+ // 4. The server then removes the paired requests up from the "queue"
+ // 5. The server then fails User B's teleport for reason of maturity level (for example)
+ // 6. User B's viewer prompts user to increase their maturity level profile value.
+ // 7. User B confirms and accepts increase in maturity level
+ // 8. User B's viewer then attempts to teleport via lure again
+ // 9. This request will time-out on the viewer-side because User A's initial request has been removed from the "queue" in step 4
+
+ return false;
+}
+
+void LLTeleportRequestViaLure::startTeleport()
+{
+ gAgent.doTeleportViaLure(getLandmarkId(), isLureGodLike());
+}
+
+//-----------------------------------------------------------------------------
+// LLTeleportRequestViaLocation
+//-----------------------------------------------------------------------------
+
+LLTeleportRequestViaLocation::LLTeleportRequestViaLocation(const LLVector3d &pPosGlobal)
+ : LLTeleportRequest(),
+ mPosGlobal(pPosGlobal)
+{
+}
+
+LLTeleportRequestViaLocation::~LLTeleportRequestViaLocation()
+{
+}
+
+bool LLTeleportRequestViaLocation::canRestartTeleport()
+{
+ return true;
+}
+
+void LLTeleportRequestViaLocation::startTeleport()
+{
+ gAgent.doTeleportViaLocation(getPosGlobal());
+}
+
+void LLTeleportRequestViaLocation::restartTeleport()
+{
+ gAgent.doTeleportViaLocation(getPosGlobal());
+}
+
+//-----------------------------------------------------------------------------
+// LLTeleportRequestViaLocationLookAt
+//-----------------------------------------------------------------------------
+
+LLTeleportRequestViaLocationLookAt::LLTeleportRequestViaLocationLookAt(const LLVector3d &pPosGlobal)
+ : LLTeleportRequestViaLocation(pPosGlobal)
+{
+}
+
+LLTeleportRequestViaLocationLookAt::~LLTeleportRequestViaLocationLookAt()
+{
+}
+
+bool LLTeleportRequestViaLocationLookAt::canRestartTeleport()
+{
+ return true;
+}
+
+void LLTeleportRequestViaLocationLookAt::startTeleport()
+{
+ gAgent.doTeleportViaLocationLookAt(getPosGlobal());
+}
+
+void LLTeleportRequestViaLocationLookAt::restartTeleport()
+{
+ gAgent.doTeleportViaLocationLookAt(getPosGlobal());
+}
+
+// EOF
diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h
index 740770bbdf..7fac17d098 100644..100755
--- a/indra/newview/llagent.h
+++ b/indra/newview/llagent.h
@@ -33,8 +33,11 @@
#include "llagentdata.h" // gAgentID, gAgentSessionID
#include "llcharacter.h"
#include "llcoordframe.h" // for mFrameAgent
-#include "llvoavatardefines.h"
+#include "llavatarappearancedefines.h"
+#include "llpermissionsflags.h"
+#include <boost/function.hpp>
+#include <boost/shared_ptr.hpp>
#include <boost/signals2.hpp>
extern const BOOL ANIMATE;
@@ -56,6 +59,9 @@ class LLAgentAccess;
class LLSLURL;
class LLPauseRequestHandle;
class LLUIColor;
+class LLTeleportRequest;
+
+typedef boost::shared_ptr<LLTeleportRequest> LLTeleportRequestPtr;
//--------------------------------------------------------------------
// Types
@@ -373,14 +379,13 @@ public:
void sitDown();
//--------------------------------------------------------------------
- // Busy
+ // Do Not Disturb
//--------------------------------------------------------------------
public:
- void setBusy();
- void clearBusy();
- BOOL getBusy() const;
+ void setDoNotDisturb(bool pIsDoNotDisturb);
+ bool isDoNotDisturb() const;
private:
- BOOL mIsBusy;
+ bool mIsDoNotDisturb;
//--------------------------------------------------------------------
// Grab
@@ -426,6 +431,9 @@ public:
void onAnimStop(const LLUUID& id);
void sendAnimationRequests(LLDynamicArray<LLUUID> &anim_ids, EAnimRequest request);
void sendAnimationRequest(const LLUUID &anim_id, EAnimRequest request);
+ void sendAnimationStateReset();
+ void sendRevokePermissions(const LLUUID & target, U32 permissions);
+
void endAnimationUpdateUI();
void unpauseAnimation() { mPauseRequest = NULL; }
BOOL getCustomAnim() const { return mCustomAnim; }
@@ -539,7 +547,8 @@ public:
TELEPORT_MOVING = 3, // Viewer has received destination location from source simulator
TELEPORT_START_ARRIVAL = 4, // Transition to ARRIVING. Viewer has received avatar update, etc., from destination simulator
TELEPORT_ARRIVING = 5, // Make the user wait while content "pre-caches"
- TELEPORT_LOCAL = 6 // Teleporting in-sim without showing the progress screen
+ TELEPORT_LOCAL = 6, // Teleporting in-sim without showing the progress screen
+ TELEPORT_PENDING = 7
};
public:
@@ -556,9 +565,6 @@ private:
// Teleport Actions
//--------------------------------------------------------------------
public:
- void teleportRequest(const U64& region_handle,
- const LLVector3& pos_local, // Go to a named location home
- bool look_at_from_camera = false);
void teleportViaLandmark(const LLUUID& landmark_id); // Teleport to a landmark
void teleportHome() { teleportViaLandmark(LLUUID::null); } // Go home
void teleportViaLure(const LLUUID& lure_id, BOOL godlike); // To an invited location
@@ -572,6 +578,45 @@ protected:
//--------------------------------------------------------------------
// Teleport State
//--------------------------------------------------------------------
+
+public:
+ bool hasRestartableFailedTeleportRequest();
+ void restartFailedTeleportRequest();
+ void clearTeleportRequest();
+ void setMaturityRatingChangeDuringTeleport(U8 pMaturityRatingChange);
+
+private:
+ friend class LLTeleportRequest;
+ friend class LLTeleportRequestViaLandmark;
+ friend class LLTeleportRequestViaLure;
+ friend class LLTeleportRequestViaLocation;
+ friend class LLTeleportRequestViaLocationLookAt;
+
+ LLTeleportRequestPtr mTeleportRequest;
+ boost::signals2::connection mTeleportFinishedSlot;
+ boost::signals2::connection mTeleportFailedSlot;
+
+ bool mIsMaturityRatingChangingDuringTeleport;
+ U8 mMaturityRatingChange;
+
+ bool hasPendingTeleportRequest();
+ void startTeleportRequest();
+
+ void teleportRequest(const U64& region_handle,
+ const LLVector3& pos_local, // Go to a named location home
+ bool look_at_from_camera = false);
+ void doTeleportViaLandmark(const LLUUID& landmark_id); // Teleport to a landmark
+ void doTeleportViaLure(const LLUUID& lure_id, BOOL godlike); // To an invited location
+ void doTeleportViaLocation(const LLVector3d& pos_global); // To a global location - this will probably need to be deprecated
+ void doTeleportViaLocationLookAt(const LLVector3d& pos_global);// To a global location, preserving camera rotation
+
+ void handleTeleportFinished();
+ void handleTeleportFailed();
+ void handleServerBakeRegionTransition(const LLUUID& region_id);
+
+ //--------------------------------------------------------------------
+ // Teleport State
+ //--------------------------------------------------------------------
public:
ETeleportState getTeleportState() const { return mTeleportState; }
void setTeleportState(ETeleportState state);
@@ -614,8 +659,6 @@ public:
const LLAgentAccess& getAgentAccess();
BOOL canManageEstate() const;
BOOL getAdminOverride() const;
- // ! BACKWARDS COMPATIBILITY ! This function can go away after the AO transition (see llstartup.cpp).
- void setAOTransition();
private:
LLAgentAccess * mAgentAccess;
@@ -631,6 +674,16 @@ public:
void requestEnterGodMode();
void requestLeaveGodMode();
+ typedef boost::function<void (U8)> god_level_change_callback_t;
+ typedef boost::signals2::signal<void (U8)> god_level_change_signal_t;
+ typedef boost::signals2::connection god_level_change_slot_t;
+
+ god_level_change_slot_t registerGodLevelChanageListener(god_level_change_callback_t pGodLevelChangeCallback);
+
+private:
+ god_level_change_signal_t mGodLevelChangeSignal;
+
+
//--------------------------------------------------------------------
// Maturity
//--------------------------------------------------------------------
@@ -650,13 +703,28 @@ public:
bool isTeen() const;
bool isMature() const;
bool isAdult() const;
- void setTeen(bool teen);
void setMaturity(char text);
- static int convertTextToMaturity(char text);
- bool sendMaturityPreferenceToServer(int preferredMaturity); // ! "U8" instead of "int"?
+ static int convertTextToMaturity(char text);
+
+private:
+ bool mIsDoSendMaturityPreferenceToServer;
+ unsigned int mMaturityPreferenceRequestId;
+ unsigned int mMaturityPreferenceResponseId;
+ unsigned int mMaturityPreferenceNumRetries;
+ U8 mLastKnownRequestMaturity;
+ U8 mLastKnownResponseMaturity;
+
+ bool isMaturityPreferenceSyncedWithServer() const;
+ void sendMaturityPreferenceToServer(U8 pPreferredMaturity);
+
+ friend class LLMaturityPreferencesResponder;
+ void handlePreferredMaturityResult(U8 pServerMaturity);
+ void handlePreferredMaturityError();
+ void reportPreferredMaturitySuccess();
+ void reportPreferredMaturityError();
// Maturity callbacks for PreferredMaturity control variable
- void handleMaturity(const LLSD& newvalue);
+ void handleMaturity(const LLSD &pNewValue);
bool validateMaturity(const LLSD& newvalue);
@@ -779,6 +847,7 @@ private:
public:
void sendMessage(); // Send message to this agent's region
void sendReliableMessage();
+ void dumpSentAppearance(const std::string& dump_prefix);
void sendAgentSetAppearance();
void sendAgentDataUpdateRequest();
void sendAgentUserInfoRequest();
@@ -837,7 +906,7 @@ private:
S32 mNumPendingQueries;
S32 mWearablesCacheQueryID;
U32 mUpdateSerialNum;
- S32 mActiveCacheQueries[LLVOAvatarDefines::BAKED_NUM_INDICES];
+ S32 mActiveCacheQueries[LLAvatarAppearanceDefines::BAKED_NUM_INDICES];
};
extern LLAgentQueryManager gAgentQueryManager;
diff --git a/indra/newview/llagentaccess.cpp b/indra/newview/llagentaccess.cpp
index 08a33ab04a..c4ee321e04 100644..100755
--- a/indra/newview/llagentaccess.cpp
+++ b/indra/newview/llagentaccess.cpp
@@ -33,8 +33,7 @@ LLAgentAccess::LLAgentAccess(LLControlGroup& savedSettings) :
mSavedSettings(savedSettings),
mAccess(SIM_ACCESS_PG),
mAdminOverride(false),
- mGodLevel(GOD_NOT),
- mAOTransition(false)
+ mGodLevel(GOD_NOT)
{
}
@@ -133,18 +132,6 @@ bool LLAgentAccess::isAdult() const
return mAccess >= SIM_ACCESS_ADULT;
}
-void LLAgentAccess::setTeen(bool teen)
-{
- if (teen)
- {
- mAccess = SIM_ACCESS_PG;
- }
- else
- {
- mAccess = SIM_ACCESS_MATURE;
- }
-}
-
//static
int LLAgentAccess::convertTextToMaturity(char text)
{
@@ -182,16 +169,6 @@ void LLAgentAccess::setMaturity(char text)
mSavedSettings.setU32("PreferredMaturity", preferred_access);
}
-void LLAgentAccess::setTransition()
-{
- mAOTransition = true;
-}
-
-bool LLAgentAccess::isInTransition() const
-{
- return mAOTransition;
-}
-
bool LLAgentAccess::canSetMaturity(S32 maturity)
{
if (isGodlike()) // Gods can always set their Maturity level
diff --git a/indra/newview/llagentaccess.h b/indra/newview/llagentaccess.h
index 2e98e4eea1..4e851b0aa0 100644..100755
--- a/indra/newview/llagentaccess.h
+++ b/indra/newview/llagentaccess.h
@@ -59,13 +59,10 @@ public:
bool isMature() const;
bool isAdult() const;
- void setTeen(bool teen);
void setMaturity(char text);
static int convertTextToMaturity(char text);
- void setTransition(); // sets the transition bit, which defaults to false
- bool isInTransition() const;
bool canSetMaturity(S32 maturity);
private:
@@ -73,13 +70,6 @@ private:
U8 mGodLevel;
bool mAdminOverride;
- // this should be deleted after the 60-day AO transition.
- // It should be safe to remove it in Viewer 2009
- // It's set by a special short-term flag in login.cgi
- // called ao_transition. When that's gone, this can go, along with
- // all of the code that depends on it.
- bool mAOTransition;
-
LLControlGroup& mSavedSettings;
};
diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp
index 751b73e1eb..488a134aa2 100644..100755
--- a/indra/newview/llagentcamera.cpp
+++ b/indra/newview/llagentcamera.cpp
@@ -35,6 +35,7 @@
#include "llfloaterreg.h"
#include "llhudmanager.h"
#include "lljoystickbutton.h"
+#include "llmoveview.h"
#include "llselectmgr.h"
#include "llsmoothstep.h"
#include "lltoolmgr.h"
@@ -49,7 +50,7 @@
#include "llwindow.h"
#include "llworld.h"
-using namespace LLVOAvatarDefines;
+using namespace LLAvatarAppearanceDefines;
extern LLMenuBarGL* gMenuBarView;
@@ -593,7 +594,6 @@ BOOL LLAgentCamera::calcCameraMinDistance(F32 &obj_min_distance)
abs_target_offset.abs();
LLVector3 target_offset_dir = target_offset_origin;
- F32 object_radius = mFocusObject->getVObjRadius();
BOOL target_outside_object_extents = FALSE;
@@ -688,17 +688,6 @@ BOOL LLAgentCamera::calcCameraMinDistance(F32 &obj_min_distance)
LLVector3 camera_offset_object(getCameraPositionAgent() - mFocusObject->getPositionAgent());
- // length projected orthogonal to target offset
- F32 camera_offset_dist = (camera_offset_object - target_offset_dir * (camera_offset_object * target_offset_dir)).magVec();
-
- // calculate whether the target point would be "visible" if it were outside the bounding box
- // on the opposite of the splitting plane defined by object_split_axis;
- BOOL exterior_target_visible = FALSE;
- if (camera_offset_dist > object_radius)
- {
- // target is visible from camera, so turn off fov zoom
- exterior_target_visible = TRUE;
- }
F32 camera_offset_clip = camera_offset_object * object_split_axis;
F32 target_offset_clip = target_offset_dir * object_split_axis;
@@ -1078,8 +1067,8 @@ void LLAgentCamera::updateLookAt(const S32 mouse_x, const S32 mouse_y)
if (!isAgentAvatarValid()) return;
- LLQuaternion av_inv_rot = ~gAgentAvatarp->mRoot.getWorldRotation();
- LLVector3 root_at = LLVector3::x_axis * gAgentAvatarp->mRoot.getWorldRotation();
+ LLQuaternion av_inv_rot = ~gAgentAvatarp->mRoot->getWorldRotation();
+ LLVector3 root_at = LLVector3::x_axis * gAgentAvatarp->mRoot->getWorldRotation();
if ((gViewerWindow->getMouseVelocityStat()->getCurrent() < 0.01f) &&
(root_at * last_at_axis > 0.95f))
@@ -1432,7 +1421,7 @@ void LLAgentCamera::updateCamera()
LLVector3(0.08f, 0.f, 0.05f) * gAgentAvatarp->mHeadp->getWorldRotation() +
LLVector3(0.1f, 0.f, 0.f) * gAgentAvatarp->mPelvisp->getWorldRotation();
LLVector3 diff = mCameraPositionAgent - head_pos;
- diff = diff * ~gAgentAvatarp->mRoot.getWorldRotation();
+ diff = diff * ~gAgentAvatarp->mRoot->getWorldRotation();
LLJoint* torso_joint = gAgentAvatarp->mTorsop;
LLJoint* chest_joint = gAgentAvatarp->mChestp;
@@ -1456,7 +1445,7 @@ void LLAgentCamera::updateCamera()
gAgentAvatarp->mPelvisp->setPosition(gAgentAvatarp->mPelvisp->getPosition() + diff);
- gAgentAvatarp->mRoot.updateWorldMatrixChildren();
+ gAgentAvatarp->mRoot->updateWorldMatrixChildren();
for (LLVOAvatar::attachment_map_t::iterator iter = gAgentAvatarp->mAttachmentPoints.begin();
iter != gAgentAvatarp->mAttachmentPoints.end(); )
@@ -1657,7 +1646,6 @@ F32 LLAgentCamera::calcCameraFOVZoomFactor()
else if (mFocusObject.notNull() && !mFocusObject->isAvatar() && !mFocusOnAvatar)
{
// don't FOV zoom on mostly transparent objects
- LLVector3 focus_offset = mFocusObjectOffset;
F32 obj_min_dist = 0.f;
calcCameraMinDistance(obj_min_dist);
F32 current_distance = llmax(0.001f, camera_offset_dir.magVec());
@@ -1684,7 +1672,7 @@ LLVector3d LLAgentCamera::calcCameraPositionTargetGlobal(BOOL *hit_limit)
F32 camera_land_height;
LLVector3d frame_center_global = !isAgentAvatarValid() ?
gAgent.getPositionGlobal() :
- gAgent.getPosGlobalFromAgent(gAgentAvatarp->mRoot.getWorldPosition());
+ gAgent.getPosGlobalFromAgent(gAgentAvatarp->mRoot->getWorldPosition());
BOOL isConstrained = FALSE;
LLVector3d head_offset;
@@ -1819,7 +1807,6 @@ LLVector3d LLAgentCamera::calcCameraPositionTargetGlobal(BOOL *hit_limit)
// set the global camera position
LLVector3d camera_offset;
- LLVector3 av_pos = !isAgentAvatarValid() ? LLVector3::zero : gAgentAvatarp->getRenderPosition();
camera_offset.setVec( local_camera_offset );
camera_position_global = frame_center_global + head_offset + camera_offset;
@@ -2113,6 +2100,11 @@ void LLAgentCamera::changeCameraToDefault()
{
changeCameraToThirdPerson();
}
+ if (gSavedSettings.getBOOL("HideUIControls"))
+ {
+ gViewerWindow->setUIVisibility(false);
+ LLPanelStandStopFlying::getInstance()->setVisible(false);
+ }
}
@@ -2251,7 +2243,7 @@ void LLAgentCamera::changeCameraToThirdPerson(BOOL animate)
//-----------------------------------------------------------------------------
void LLAgentCamera::changeCameraToCustomizeAvatar()
{
- if (LLViewerJoystick::getInstance()->getOverrideCamera())
+ if (LLViewerJoystick::getInstance()->getOverrideCamera() || !isAgentAvatarValid())
{
return;
}
@@ -2275,10 +2267,6 @@ void LLAgentCamera::changeCameraToCustomizeAvatar()
gFocusMgr.setKeyboardFocus( NULL );
gFocusMgr.setMouseCapture( NULL );
- LLVOAvatarSelf::onCustomizeStart();
-
- if (isAgentAvatarValid())
- {
// Remove any pitch or rotation from the avatar
LLVector3 at = gAgent.getAtAxis();
at.mV[VZ] = 0.f;
@@ -2295,10 +2283,6 @@ void LLAgentCamera::changeCameraToCustomizeAvatar()
// delay camera animation long enough to play through turn animation
setAnimationDuration(turn_motion->getDuration() + CUSTOMIZE_AVATAR_CAMERA_ANIM_SLOP);
}
-
- gAgentAvatarp->invalidateAll();
- gAgentAvatarp->updateMeshTextures();
- }
}
LLVector3 agent_at = gAgent.getAtAxis();
diff --git a/indra/newview/llagentcamera.h b/indra/newview/llagentcamera.h
index 00fa6ea189..00fa6ea189 100644..100755
--- a/indra/newview/llagentcamera.h
+++ b/indra/newview/llagentcamera.h
diff --git a/indra/newview/llagentdata.cpp b/indra/newview/llagentdata.cpp
index 5f6a082d75..5f6a082d75 100644..100755
--- a/indra/newview/llagentdata.cpp
+++ b/indra/newview/llagentdata.cpp
diff --git a/indra/newview/llagentdata.h b/indra/newview/llagentdata.h
index 83d6a53d5e..83d6a53d5e 100644..100755
--- a/indra/newview/llagentdata.h
+++ b/indra/newview/llagentdata.h
diff --git a/indra/newview/llagentlanguage.cpp b/indra/newview/llagentlanguage.cpp
index fe6236a32a..fe6236a32a 100644..100755
--- a/indra/newview/llagentlanguage.cpp
+++ b/indra/newview/llagentlanguage.cpp
diff --git a/indra/newview/llagentlanguage.h b/indra/newview/llagentlanguage.h
index 2bb2eb7809..2bb2eb7809 100644..100755
--- a/indra/newview/llagentlanguage.h
+++ b/indra/newview/llagentlanguage.h
diff --git a/indra/newview/llagentlistener.cpp b/indra/newview/llagentlistener.cpp
index a8d2222c03..a4c0b056ac 100644..100755
--- a/indra/newview/llagentlistener.cpp
+++ b/indra/newview/llagentlistener.cpp
@@ -126,6 +126,17 @@ LLAgentListener::LLAgentListener(LLAgent &agent)
"[\"obj_uuid\"]: id of object to look at, use this or [\"position\"] to indicate the target\n"
"[\"position\"]: region position {x, y, z} where to find closest object or avatar to look at",
&LLAgentListener::lookAt);
+ add("getGroups",
+ "Send information about the agent's groups on [\"reply\"]:\n"
+ "[\"groups\"]: array of group information\n"
+ "[\"id\"]: group id\n"
+ "[\"name\"]: group name\n"
+ "[\"insignia\"]: group insignia texture id\n"
+ "[\"notices\"]: boolean indicating if this user accepts notices from this group\n"
+ "[\"display\"]: boolean indicating if this group is listed in the user's profile\n"
+ "[\"contrib\"]: user's land contribution to this group\n",
+ &LLAgentListener::getGroups,
+ LLSDMap("reply", LLSD()));
}
void LLAgentListener::requestTeleport(LLSD const & event_data) const
diff --git a/indra/newview/llagentlistener.h b/indra/newview/llagentlistener.h
index 9a9c4073fe..9a9c4073fe 100644..100755
--- a/indra/newview/llagentlistener.h
+++ b/indra/newview/llagentlistener.h
diff --git a/indra/newview/llagentpicksinfo.cpp b/indra/newview/llagentpicksinfo.cpp
index 192ed141c7..192ed141c7 100644..100755
--- a/indra/newview/llagentpicksinfo.cpp
+++ b/indra/newview/llagentpicksinfo.cpp
diff --git a/indra/newview/llagentpicksinfo.h b/indra/newview/llagentpicksinfo.h
index abf7027ed2..abf7027ed2 100644..100755
--- a/indra/newview/llagentpicksinfo.h
+++ b/indra/newview/llagentpicksinfo.h
diff --git a/indra/newview/llagentpilot.cpp b/indra/newview/llagentpilot.cpp
index 734c502fcf..c7872fc5f6 100644..100755
--- a/indra/newview/llagentpilot.cpp
+++ b/indra/newview/llagentpilot.cpp
@@ -139,7 +139,7 @@ void LLAgentPilot::loadXML(const std::string& filename)
mActions.reset();
LLSD record;
- while (!file.eof() && LLSDSerialize::fromXML(record, file))
+ while (!file.eof() && LLSDParser::PARSE_FAILURE != LLSDSerialize::fromXML(record, file))
{
Action action;
action.mTime = record["time"].asReal();
diff --git a/indra/newview/llagentpilot.h b/indra/newview/llagentpilot.h
index dd1709ec0c..dd1709ec0c 100644..100755
--- a/indra/newview/llagentpilot.h
+++ b/indra/newview/llagentpilot.h
diff --git a/indra/newview/llagentui.cpp b/indra/newview/llagentui.cpp
index b9ec304b7e..3410a37890 100644..100755
--- a/indra/newview/llagentui.cpp
+++ b/indra/newview/llagentui.cpp
@@ -112,6 +112,11 @@ BOOL LLAgentUI::buildLocationString(std::string& str, ELocationFormat fmt,const
case LOCATION_FORMAT_NORMAL:
buffer = llformat("%s", region_name.c_str());
break;
+ case LOCATION_FORMAT_NORMAL_COORDS:
+ buffer = llformat("%s (%d, %d, %d)",
+ region_name.c_str(),
+ pos_x, pos_y, pos_z);
+ break;
case LOCATION_FORMAT_NO_COORDS:
buffer = llformat("%s%s%s",
region_name.c_str(),
@@ -143,6 +148,11 @@ BOOL LLAgentUI::buildLocationString(std::string& str, ELocationFormat fmt,const
case LOCATION_FORMAT_NORMAL:
buffer = llformat("%s, %s", parcel_name.c_str(), region_name.c_str());
break;
+ case LOCATION_FORMAT_NORMAL_COORDS:
+ buffer = llformat("%s (%d, %d, %d)",
+ parcel_name.c_str(),
+ pos_x, pos_y, pos_z);
+ break;
case LOCATION_FORMAT_NO_MATURITY:
buffer = llformat("%s, %s (%d, %d, %d)",
parcel_name.c_str(),
diff --git a/indra/newview/llagentui.h b/indra/newview/llagentui.h
index dda5dc1fd1..bb48dad14c 100644..100755
--- a/indra/newview/llagentui.h
+++ b/indra/newview/llagentui.h
@@ -35,6 +35,7 @@ public:
enum ELocationFormat
{
LOCATION_FORMAT_NORMAL, // Parcel
+ LOCATION_FORMAT_NORMAL_COORDS, // Parcel (x, y, z)
LOCATION_FORMAT_LANDMARK, // Parcel, Region
LOCATION_FORMAT_NO_MATURITY, // Parcel, Region (x, y, z)
LOCATION_FORMAT_NO_COORDS, // Parcel, Region - Maturity
diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp
index 654a785a1a..c741f6403d 100644..100755
--- a/indra/newview/llagentwearables.cpp
+++ b/indra/newview/llagentwearables.cpp
@@ -47,7 +47,7 @@
#include "lltooldraganddrop.h"
#include "llviewerregion.h"
#include "llvoavatarself.h"
-#include "llwearable.h"
+#include "llviewerwearable.h"
#include "llwearablelist.h"
#include "llfloaterperms.h"
@@ -57,14 +57,12 @@ LLAgentWearables gAgentWearables;
BOOL LLAgentWearables::mInitialWearablesUpdateReceived = FALSE;
-using namespace LLVOAvatarDefines;
+using namespace LLAvatarAppearanceDefines;
///////////////////////////////////////////////////////////////////////////////
// Callback to wear and start editing an item that has just been created.
-class LLWearAndEditCallback : public LLInventoryCallback
-{
- void fire(const LLUUID& inv_item)
+void wear_and_edit_cb(const LLUUID& inv_item)
{
if (inv_item.isNull()) return;
@@ -87,7 +85,6 @@ class LLWearAndEditCallback : public LLInventoryCallback
// Wear it.
LLAppearanceMgr::instance().wearItemOnAvatar(inv_item);
}
-};
class LLCreateWearableCallback : public LLInventoryCallback
{
@@ -118,7 +115,7 @@ class LLCreateWearableCallback : public LLInventoryCallback
// wearable type stored in asset is some other value.
// Calling this function whenever a wearable is added to increase visibility if this problem
// turns up in other inventories.
-void checkWearableAgainstInventory(LLWearable *wearable)
+void checkWearableAgainstInventory(LLViewerWearable *wearable)
{
if (wearable->getItemID().isNull())
return;
@@ -155,7 +152,7 @@ void LLAgentWearables::dump()
llinfos << "Type: " << i << " count " << count << llendl;
for (U32 j=0; j<count; j++)
{
- LLWearable* wearable = getWearable((LLWearableType::EType)i,j);
+ LLViewerWearable* wearable = getViewerWearable((LLWearableType::EType)i,j);
if (wearable == NULL)
{
llinfos << " " << j << " NULL wearable" << llendl;
@@ -195,6 +192,7 @@ struct LLAgentDumper
};
LLAgentWearables::LLAgentWearables() :
+ LLWearableData(),
mWearablesLoaded(FALSE)
, mCOFChangeInProgress(false)
{
@@ -219,11 +217,10 @@ void LLAgentWearables::initClass()
void LLAgentWearables::setAvatarObject(LLVOAvatarSelf *avatar)
{
- if (avatar)
- {
+ llassert(avatar);
avatar->outputRezTiming("Sending wearables request");
sendAgentWearablesRequest();
- }
+ setAvatarAppearance(avatar);
}
// wearables
@@ -249,12 +246,13 @@ LLAgentWearables::sendAgentWearablesUpdateCallback::~sendAgentWearablesUpdateCal
* @param todo Bitmask of actions to take on completion.
*/
LLAgentWearables::addWearableToAgentInventoryCallback::addWearableToAgentInventoryCallback(
- LLPointer<LLRefCount> cb, LLWearableType::EType type, U32 index, LLWearable* wearable, U32 todo) :
+ LLPointer<LLRefCount> cb, LLWearableType::EType type, U32 index, LLViewerWearable* wearable, U32 todo, const std::string description) :
mType(type),
mIndex(index),
mWearable(wearable),
mTodo(todo),
- mCB(cb)
+ mCB(cb),
+ mDescription(description)
{
llinfos << "constructor" << llendl;
}
@@ -294,14 +292,14 @@ void LLAgentWearables::addWearableToAgentInventoryCallback::fire(const LLUUID& i
}
if (mTodo & CALL_WEARITEM)
{
- LLAppearanceMgr::instance().addCOFItemLink(inv_item, true);
+ LLAppearanceMgr::instance().addCOFItemLink(inv_item, true, NULL, mDescription);
}
}
void LLAgentWearables::addWearabletoAgentInventoryDone(const LLWearableType::EType type,
const U32 index,
const LLUUID& item_id,
- LLWearable* wearable)
+ LLViewerWearable* wearable)
{
llinfos << "type " << type << " index " << index << " item " << item_id.asString() << llendl;
@@ -348,7 +346,7 @@ void LLAgentWearables::sendAgentWearablesUpdate()
{
for (U32 index=0; index < getWearableCount((LLWearableType::EType)type); ++index)
{
- LLWearable* wearable = getWearable((LLWearableType::EType)type,index);
+ LLViewerWearable* wearable = getViewerWearable((LLWearableType::EType)type,index);
if (wearable)
{
if (wearable->getItemID().isNull())
@@ -390,7 +388,7 @@ void LLAgentWearables::sendAgentWearablesUpdate()
U8 type_u8 = (U8)type;
gMessageSystem->addU8Fast(_PREHASH_WearableType, type_u8);
- LLWearable* wearable = getWearable((LLWearableType::EType)type, 0);
+ LLViewerWearable* wearable = getViewerWearable((LLWearableType::EType)type, 0);
if (wearable)
{
//llinfos << "Sending wearable " << wearable->getName() << llendl;
@@ -418,14 +416,14 @@ void LLAgentWearables::sendAgentWearablesUpdate()
void LLAgentWearables::saveWearable(const LLWearableType::EType type, const U32 index, BOOL send_update,
const std::string new_name)
{
- LLWearable* old_wearable = getWearable(type, index);
+ LLViewerWearable* old_wearable = getViewerWearable(type, index);
if(!old_wearable) return;
bool name_changed = !new_name.empty() && (new_name != old_wearable->getName());
if (name_changed || old_wearable->isDirty() || old_wearable->isOldVersion())
{
LLUUID old_item_id = old_wearable->getItemID();
- LLWearable* new_wearable = LLWearableList::instance().createCopy(old_wearable);
- new_wearable->setItemID(old_item_id); // should this be in LLWearable::copyDataFrom()?
+ LLViewerWearable* new_wearable = LLWearableList::instance().createCopy(old_wearable);
+ new_wearable->setItemID(old_item_id); // should this be in LLViewerWearable::copyDataFrom()?
setWearable(type,index,new_wearable);
// old_wearable may still be referred to by other inventory items. Revert
@@ -494,6 +492,7 @@ void LLAgentWearables::saveWearable(const LLWearableType::EType type, const U32
void LLAgentWearables::saveWearableAs(const LLWearableType::EType type,
const U32 index,
const std::string& new_name,
+ const std::string& description,
BOOL save_in_lost_and_found)
{
if (!isWearableCopyable(type, index))
@@ -501,7 +500,7 @@ void LLAgentWearables::saveWearableAs(const LLWearableType::EType type,
llwarns << "LLAgent::saveWearableAs() not copyable." << llendl;
return;
}
- LLWearable* old_wearable = getWearable(type, index);
+ LLViewerWearable* old_wearable = getViewerWearable(type, index);
if (!old_wearable)
{
llwarns << "LLAgent::saveWearableAs() no old wearable." << llendl;
@@ -516,7 +515,7 @@ void LLAgentWearables::saveWearableAs(const LLWearableType::EType type,
}
std::string trunc_name(new_name);
LLStringUtil::truncate(trunc_name, DB_INV_ITEM_NAME_STR_LEN);
- LLWearable* new_wearable = LLWearableList::instance().createCopy(
+ LLViewerWearable* new_wearable = LLWearableList::instance().createCopy(
old_wearable,
trunc_name);
@@ -526,7 +525,9 @@ void LLAgentWearables::saveWearableAs(const LLWearableType::EType type,
type,
index,
new_wearable,
- addWearableToAgentInventoryCallback::CALL_WEARITEM);
+ addWearableToAgentInventoryCallback::CALL_WEARITEM,
+ description
+ );
LLUUID category_id;
if (save_in_lost_and_found)
{
@@ -555,7 +556,7 @@ void LLAgentWearables::saveWearableAs(const LLWearableType::EType type,
void LLAgentWearables::revertWearable(const LLWearableType::EType type, const U32 index)
{
- LLWearable* wearable = getWearable(type, index);
+ LLViewerWearable* wearable = getViewerWearable(type, index);
llassert(wearable);
if (wearable)
{
@@ -590,13 +591,13 @@ void LLAgentWearables::setWearableName(const LLUUID& item_id, const std::string&
LLUUID curr_item_id = getWearableItemID((LLWearableType::EType)i,j);
if (curr_item_id == item_id)
{
- LLWearable* old_wearable = getWearable((LLWearableType::EType)i,j);
+ LLViewerWearable* old_wearable = getViewerWearable((LLWearableType::EType)i,j);
llassert(old_wearable);
if (!old_wearable) continue;
std::string old_name = old_wearable->getName();
old_wearable->setName(new_name);
- LLWearable* new_wearable = LLWearableList::instance().createCopy(old_wearable);
+ LLViewerWearable* new_wearable = LLWearableList::instance().createCopy(old_wearable);
new_wearable->setItemID(item_id);
LLInventoryItem* item = gInventory.getItem(item_id);
if (item)
@@ -677,14 +678,14 @@ LLInventoryItem* LLAgentWearables::getWearableInventoryItem(LLWearableType::ETyp
return item;
}
-const LLWearable* LLAgentWearables::getWearableFromItemID(const LLUUID& item_id) const
+const LLViewerWearable* LLAgentWearables::getWearableFromItemID(const LLUUID& item_id) const
{
const LLUUID& base_item_id = gInventory.getLinkedItemID(item_id);
for (S32 i=0; i < LLWearableType::WT_COUNT; i++)
{
for (U32 j=0; j < getWearableCount((LLWearableType::EType)i); j++)
{
- const LLWearable * curr_wearable = getWearable((LLWearableType::EType)i, j);
+ const LLViewerWearable * curr_wearable = getViewerWearable((LLWearableType::EType)i, j);
if (curr_wearable && (curr_wearable->getItemID() == base_item_id))
{
return curr_wearable;
@@ -694,14 +695,14 @@ const LLWearable* LLAgentWearables::getWearableFromItemID(const LLUUID& item_id)
return NULL;
}
-LLWearable* LLAgentWearables::getWearableFromItemID(const LLUUID& item_id)
+LLViewerWearable* LLAgentWearables::getWearableFromItemID(const LLUUID& item_id)
{
const LLUUID& base_item_id = gInventory.getLinkedItemID(item_id);
for (S32 i=0; i < LLWearableType::WT_COUNT; i++)
{
for (U32 j=0; j < getWearableCount((LLWearableType::EType)i); j++)
{
- LLWearable * curr_wearable = getWearable((LLWearableType::EType)i, j);
+ LLViewerWearable * curr_wearable = getViewerWearable((LLWearableType::EType)i, j);
if (curr_wearable && (curr_wearable->getItemID() == base_item_id))
{
return curr_wearable;
@@ -711,13 +712,13 @@ LLWearable* LLAgentWearables::getWearableFromItemID(const LLUUID& item_id)
return NULL;
}
-LLWearable* LLAgentWearables::getWearableFromAssetID(const LLUUID& asset_id)
+LLViewerWearable* LLAgentWearables::getWearableFromAssetID(const LLUUID& asset_id)
{
for (S32 i=0; i < LLWearableType::WT_COUNT; i++)
{
for (U32 j=0; j < getWearableCount((LLWearableType::EType)i); j++)
{
- LLWearable * curr_wearable = getWearable((LLWearableType::EType)i, j);
+ LLViewerWearable * curr_wearable = getViewerWearable((LLWearableType::EType)i, j);
if (curr_wearable && (curr_wearable->getAssetID() == asset_id))
{
return curr_wearable;
@@ -736,85 +737,37 @@ void LLAgentWearables::sendAgentWearablesRequest()
gAgent.sendReliableMessage();
}
-// static
-BOOL LLAgentWearables::selfHasWearable(LLWearableType::EType type)
+LLViewerWearable* LLAgentWearables::getViewerWearable(const LLWearableType::EType type, U32 index /*= 0*/)
{
- return (gAgentWearables.getWearableCount(type) > 0);
+ return dynamic_cast<LLViewerWearable*> (getWearable(type, index));
}
-LLWearable* LLAgentWearables::getWearable(const LLWearableType::EType type, U32 index)
-{
- wearableentry_map_t::iterator wearable_iter = mWearableDatas.find(type);
- if (wearable_iter == mWearableDatas.end())
- {
- return NULL;
- }
- wearableentry_vec_t& wearable_vec = wearable_iter->second;
- if (index>=wearable_vec.size())
+const LLViewerWearable* LLAgentWearables::getViewerWearable(const LLWearableType::EType type, U32 index /*= 0*/) const
{
- return NULL;
- }
- else
- {
- return wearable_vec[index];
- }
+ return dynamic_cast<const LLViewerWearable*> (getWearable(type, index));
}
-void LLAgentWearables::setWearable(const LLWearableType::EType type, U32 index, LLWearable *wearable)
+// static
+BOOL LLAgentWearables::selfHasWearable(LLWearableType::EType type)
{
-
- LLWearable *old_wearable = getWearable(type,index);
- if (!old_wearable)
- {
- pushWearable(type,wearable);
- return;
+ return (gAgentWearables.getWearableCount(type) > 0);
}
- wearableentry_map_t::iterator wearable_iter = mWearableDatas.find(type);
- if (wearable_iter == mWearableDatas.end())
- {
- llwarns << "invalid type, type " << type << " index " << index << llendl;
- return;
- }
- wearableentry_vec_t& wearable_vec = wearable_iter->second;
- if (index>=wearable_vec.size())
+// virtual
+void LLAgentWearables::wearableUpdated(LLWearable *wearable, BOOL removed)
{
- llwarns << "invalid index, type " << type << " index " << index << llendl;
- }
- else
+ if (isAgentAvatarValid())
{
- wearable_vec[index] = wearable;
- old_wearable->setLabelUpdated();
- wearableUpdated(wearable);
- checkWearableAgainstInventory(wearable);
- }
+ const BOOL upload_result = removed;
+ gAgentAvatarp->wearableUpdated(wearable->getType(), upload_result);
}
-U32 LLAgentWearables::pushWearable(const LLWearableType::EType type, LLWearable *wearable)
-{
- if (wearable == NULL)
- {
- // no null wearables please!
- llwarns << "Null wearable sent for type " << type << llendl;
- return MAX_CLOTHING_PER_TYPE;
- }
- if (type < LLWearableType::WT_COUNT || mWearableDatas[type].size() < MAX_CLOTHING_PER_TYPE)
- {
- mWearableDatas[type].push_back(wearable);
- wearableUpdated(wearable);
- checkWearableAgainstInventory(wearable);
- return mWearableDatas[type].size()-1;
- }
- return MAX_CLOTHING_PER_TYPE;
-}
+ LLWearableData::wearableUpdated(wearable, removed);
-void LLAgentWearables::wearableUpdated(LLWearable *wearable)
+ if (!removed)
{
- gAgentAvatarp->wearableUpdated(wearable->getType(), FALSE);
- wearable->refreshName();
- wearable->setLabelUpdated();
-
- wearable->pullCrossWearableValues();
+ LLViewerWearable* viewer_wearable = dynamic_cast<LLViewerWearable*>(wearable);
+ viewer_wearable->refreshName();
// Hack pt 2. If the wearable we just loaded has definition version 24,
// then force a re-save of this wearable after slamming the version number to 22.
@@ -825,126 +778,14 @@ void LLAgentWearables::wearableUpdated(LLWearable *wearable)
{
wearable->setDefinitionVersion(22);
U32 index = getWearableIndex(wearable);
- llinfos << "forcing werable type " << wearable->getType() << " to version 22 from 24" << llendl;
+ llinfos << "forcing wearable type " << wearable->getType() << " to version 22 from 24" << llendl;
saveWearable(wearable->getType(),index,TRUE);
}
+ checkWearableAgainstInventory(viewer_wearable);
}
-
-void LLAgentWearables::popWearable(LLWearable *wearable)
-{
- if (wearable == NULL)
- {
- // nothing to do here. move along.
- return;
- }
-
- U32 index = getWearableIndex(wearable);
- LLWearableType::EType type = wearable->getType();
-
- if (index < MAX_CLOTHING_PER_TYPE && index < getWearableCount(type))
- {
- popWearable(type, index);
- }
-}
-
-void LLAgentWearables::popWearable(const LLWearableType::EType type, U32 index)
-{
- LLWearable *wearable = getWearable(type, index);
- if (wearable)
- {
- mWearableDatas[type].erase(mWearableDatas[type].begin() + index);
- if (isAgentAvatarValid())
- {
- gAgentAvatarp->wearableUpdated(wearable->getType(), TRUE);
- }
- wearable->setLabelUpdated();
- }
-}
-
-U32 LLAgentWearables::getWearableIndex(const LLWearable *wearable) const
-{
- if (wearable == NULL)
- {
- return MAX_CLOTHING_PER_TYPE;
- }
-
- const LLWearableType::EType type = wearable->getType();
- wearableentry_map_t::const_iterator wearable_iter = mWearableDatas.find(type);
- if (wearable_iter == mWearableDatas.end())
- {
- llwarns << "tried to get wearable index with an invalid type!" << llendl;
- return MAX_CLOTHING_PER_TYPE;
- }
- const wearableentry_vec_t& wearable_vec = wearable_iter->second;
- for(U32 index = 0; index < wearable_vec.size(); index++)
- {
- if (wearable_vec[index] == wearable)
- {
- return index;
- }
- }
-
- return MAX_CLOTHING_PER_TYPE;
-}
-
-const LLWearable* LLAgentWearables::getWearable(const LLWearableType::EType type, U32 index) const
-{
- wearableentry_map_t::const_iterator wearable_iter = mWearableDatas.find(type);
- if (wearable_iter == mWearableDatas.end())
- {
- return NULL;
- }
- const wearableentry_vec_t& wearable_vec = wearable_iter->second;
- if (index>=wearable_vec.size())
- {
- return NULL;
- }
- else
- {
- return wearable_vec[index];
- }
-}
-
-LLWearable* LLAgentWearables::getTopWearable(const LLWearableType::EType type)
-{
- U32 count = getWearableCount(type);
- if ( count == 0)
- {
- return NULL;
- }
-
- return getWearable(type, count-1);
-}
-
-LLWearable* LLAgentWearables::getBottomWearable(const LLWearableType::EType type)
-{
- if (getWearableCount(type) == 0)
- {
- return NULL;
- }
-
- return getWearable(type, 0);
}
-U32 LLAgentWearables::getWearableCount(const LLWearableType::EType type) const
-{
- wearableentry_map_t::const_iterator wearable_iter = mWearableDatas.find(type);
- if (wearable_iter == mWearableDatas.end())
- {
- return 0;
- }
- const wearableentry_vec_t& wearable_vec = wearable_iter->second;
- return wearable_vec.size();
-}
-
-U32 LLAgentWearables::getWearableCount(const U32 tex_index) const
-{
- const LLWearableType::EType wearable_type = LLVOAvatarDictionary::getTEWearableType((LLVOAvatarDefines::ETextureIndex)tex_index);
- return getWearableCount(wearable_type);
-}
-
-
BOOL LLAgentWearables::itemUpdatePending(const LLUUID& item_id) const
{
return mItemsAwaitingWearableUpdate.find(item_id) != mItemsAwaitingWearableUpdate.end();
@@ -957,7 +798,7 @@ U32 LLAgentWearables::itemUpdatePendingCount() const
const LLUUID LLAgentWearables::getWearableItemID(LLWearableType::EType type, U32 index) const
{
- const LLWearable *wearable = getWearable(type,index);
+ const LLViewerWearable *wearable = getViewerWearable(type,index);
if (wearable)
return wearable->getItemID();
else
@@ -966,7 +807,7 @@ const LLUUID LLAgentWearables::getWearableItemID(LLWearableType::EType type, U32
const LLUUID LLAgentWearables::getWearableAssetID(LLWearableType::EType type, U32 index) const
{
- const LLWearable *wearable = getWearable(type,index);
+ const LLViewerWearable *wearable = getViewerWearable(type,index);
if (wearable)
return wearable->getAssetID();
else
@@ -992,6 +833,7 @@ void LLAgentWearables::processAgentInitialWearablesUpdate(LLMessageSystem* mesgs
if (isAgentAvatarValid())
{
+ gAgentAvatarp->startPhase("process_initial_wearables_update");
gAgentAvatarp->outputRezTiming("Received initial wearables update");
}
@@ -1047,7 +889,7 @@ void LLAgentWearables::processAgentInitialWearablesUpdate(LLMessageSystem* mesgs
gMessageSystem->getUUIDFast(_PREHASH_WearableData, _PREHASH_AssetID, asset_id, i);
if (asset_id.isNull())
{
- LLWearable::removeFromAvatar(type, FALSE);
+ LLViewerWearable::removeFromAvatar(type, FALSE);
}
else
{
@@ -1093,7 +935,7 @@ void LLAgentWearables::recoverMissingWearable(const LLWearableType::EType type,
// Try to recover by replacing missing wearable with a new one.
LLNotificationsUtil::add("ReplacedMissingWearable");
lldebugs << "Wearable " << LLWearableType::getTypeLabel(type) << " could not be downloaded. Replaced inventory item with default wearable." << llendl;
- LLWearable* new_wearable = LLWearableList::instance().createNewWearable(type);
+ LLViewerWearable* new_wearable = LLWearableList::instance().createNewWearable(type, gAgentAvatarp);
setWearable(type,index,new_wearable);
//new_wearable->writeToAvatar(TRUE);
@@ -1128,9 +970,9 @@ void LLAgentWearables::recoverMissingWearableDone()
}
}
-void LLAgentWearables::addLocalTextureObject(const LLWearableType::EType wearable_type, const LLVOAvatarDefines::ETextureIndex texture_type, U32 wearable_index)
+void LLAgentWearables::addLocalTextureObject(const LLWearableType::EType wearable_type, const LLAvatarAppearanceDefines::ETextureIndex texture_type, U32 wearable_index)
{
- LLWearable* wearable = getWearable((LLWearableType::EType)wearable_type, wearable_index);
+ LLViewerWearable* wearable = getViewerWearable((LLWearableType::EType)wearable_type, wearable_index);
if (!wearable)
{
llerrs << "Tried to add local texture object to invalid wearable with type " << wearable_type << " and index " << wearable_index << llendl;
@@ -1163,7 +1005,7 @@ public:
mItemsToLink,
link_waiter);
}
- void addPendingWearable(LLWearable *wearable)
+ void addPendingWearable(LLViewerWearable *wearable)
{
if (!wearable)
{
@@ -1198,7 +1040,7 @@ public:
LLWearableType::EType type = item->getWearableType();
if (type < LLWearableType::WT_COUNT)
{
- LLWearable *wearable = mWearablesAwaitingItems[type];
+ LLViewerWearable *wearable = mWearablesAwaitingItems[type];
if (wearable)
wearable->setItemID(inv_item);
}
@@ -1211,7 +1053,7 @@ public:
private:
LLInventoryModel::item_array_t mItemsToLink;
- std::vector<LLWearable*> mWearablesAwaitingItems;
+ std::vector<LLViewerWearable*> mWearablesAwaitingItems;
};
void LLAgentWearables::createStandardWearables()
@@ -1243,7 +1085,7 @@ void LLAgentWearables::createStandardWearables()
if (create[i])
{
llassert(getWearableCount((LLWearableType::EType)i) == 0);
- LLWearable* wearable = LLWearableList::instance().createNewWearable((LLWearableType::EType)i);
+ LLViewerWearable* wearable = LLWearableList::instance().createNewWearable((LLWearableType::EType)i, gAgentAvatarp);
((OnWearableItemCreatedCB*)(&(*cb)))->addPendingWearable(wearable);
// no need to update here...
LLUUID category_id = LLUUID::null;
@@ -1302,7 +1144,7 @@ void LLAgentWearables::makeNewOutfitDone(S32 type, U32 index)
void LLAgentWearables::addWearableToAgentInventory(LLPointer<LLInventoryCallback> cb,
- LLWearable* wearable,
+ LLViewerWearable* wearable,
const LLUUID& category_id,
BOOL notify)
{
@@ -1340,7 +1182,7 @@ void LLAgentWearables::removeWearable(const LLWearableType::EType type, bool do_
}
else
{
- LLWearable* old_wearable = getWearable(type,index);
+ LLViewerWearable* old_wearable = getViewerWearable(type,index);
if (old_wearable)
{
@@ -1395,10 +1237,10 @@ void LLAgentWearables::removeWearableFinal(const LLWearableType::EType type, boo
//LLAgentDumper dumper("removeWearable");
if (do_remove_all)
{
- S32 max_entry = mWearableDatas[type].size()-1;
+ S32 max_entry = getWearableCount(type)-1;
for (S32 i=max_entry; i>=0; i--)
{
- LLWearable* old_wearable = getWearable(type,i);
+ LLViewerWearable* old_wearable = getViewerWearable(type,i);
//queryWearableCache(); // moved below
if (old_wearable)
{
@@ -1406,11 +1248,11 @@ void LLAgentWearables::removeWearableFinal(const LLWearableType::EType type, boo
old_wearable->removeFromAvatar(TRUE);
}
}
- mWearableDatas[type].clear();
+ clearWearableType(type);
}
else
{
- LLWearable* old_wearable = getWearable(type, index);
+ LLViewerWearable* old_wearable = getViewerWearable(type, index);
//queryWearableCache(); // moved below
if (old_wearable)
@@ -1429,7 +1271,7 @@ void LLAgentWearables::removeWearableFinal(const LLWearableType::EType type, boo
// Assumes existing wearables are not dirty.
void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& items,
- const LLDynamicArray< LLWearable* >& wearables,
+ const LLDynamicArray< LLViewerWearable* >& wearables,
BOOL remove)
{
llinfos << "setWearableOutfit() start" << llendl;
@@ -1454,7 +1296,7 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it
S32 i;
for (i = 0; i < count; i++)
{
- LLWearable* new_wearable = wearables[i];
+ LLViewerWearable* new_wearable = wearables[i];
LLPointer<LLInventoryItem> new_item = items[i];
llassert(new_wearable);
@@ -1474,8 +1316,8 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it
{
pushWearable(type,new_wearable);
}
- wearableUpdated(new_wearable);
- checkWearableAgainstInventory(new_wearable);
+ const BOOL removed = FALSE;
+ wearableUpdated(new_wearable, removed);
}
}
@@ -1485,7 +1327,16 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it
{
gAgentAvatarp->setCompositeUpdatesEnabled(TRUE);
gAgentAvatarp->updateVisualParams();
- gAgentAvatarp->invalidateAll();
+
+ // If we have not yet declouded, we may want to use
+ // baked texture UUIDs sent from the first objectUpdate message
+ // don't overwrite these. If we have already declouded, we've saved
+ // these ids as the last known good textures and can invalidate without
+ // re-clouding.
+ if (!gAgentAvatarp->getIsCloud())
+ {
+ gAgentAvatarp->invalidateAll();
+ }
}
// Start rendering & update the server
@@ -1502,7 +1353,7 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it
// User has picked "wear on avatar" from a menu.
-void LLAgentWearables::setWearableItem(LLInventoryItem* new_item, LLWearable* new_wearable, bool do_append)
+void LLAgentWearables::setWearableItem(LLInventoryItem* new_item, LLViewerWearable* new_wearable, bool do_append)
{
//LLAgentDumper dumper("setWearableItem");
if (isWearingItem(new_item->getUUID()))
@@ -1517,7 +1368,7 @@ void LLAgentWearables::setWearableItem(LLInventoryItem* new_item, LLWearable* ne
{
// Remove old wearable, if any
// MULTI_WEARABLE: hardwired to 0
- LLWearable* old_wearable = getWearable(type,0);
+ LLViewerWearable* old_wearable = getViewerWearable(type,0);
if (old_wearable)
{
const LLUUID& old_item_id = old_wearable->getItemID();
@@ -1543,7 +1394,7 @@ void LLAgentWearables::setWearableItem(LLInventoryItem* new_item, LLWearable* ne
}
// static
-bool LLAgentWearables::onSetWearableDialog(const LLSD& notification, const LLSD& response, LLWearable* wearable)
+bool LLAgentWearables::onSetWearableDialog(const LLSD& notification, const LLSD& response, LLViewerWearable* wearable)
{
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
LLInventoryItem* new_item = gInventory.getItem(notification["payload"]["item_id"].asUUID());
@@ -1579,16 +1430,17 @@ bool LLAgentWearables::onSetWearableDialog(const LLSD& notification, const LLSD&
// Called from setWearableItem() and onSetWearableDialog() to actually set the wearable.
// MULTI_WEARABLE: unify code after null objects are gone.
-void LLAgentWearables::setWearableFinal(LLInventoryItem* new_item, LLWearable* new_wearable, bool do_append)
+void LLAgentWearables::setWearableFinal(LLInventoryItem* new_item, LLViewerWearable* new_wearable, bool do_append)
{
const LLWearableType::EType type = new_wearable->getType();
if (do_append && getWearableItemID(type,0).notNull())
{
new_wearable->setItemID(new_item->getUUID());
- mWearableDatas[type].push_back(new_wearable);
+ const bool trigger_updated = false;
+ pushWearable(type, new_wearable, trigger_updated);
llinfos << "Added additional wearable for type " << type
- << " size is now " << mWearableDatas[type].size() << llendl;
+ << " size is now " << getWearableCount(type) << llendl;
checkWearableAgainstInventory(new_wearable);
}
else
@@ -1596,7 +1448,7 @@ void LLAgentWearables::setWearableFinal(LLInventoryItem* new_item, LLWearable* n
// Replace the old wearable with a new one.
llassert(new_item->getAssetUUID() == new_wearable->getAssetID());
- LLWearable *old_wearable = getWearable(type,0);
+ LLViewerWearable *old_wearable = getViewerWearable(type,0);
LLUUID old_item_id;
if (old_wearable)
{
@@ -1611,7 +1463,7 @@ void LLAgentWearables::setWearableFinal(LLInventoryItem* new_item, LLWearable* n
gInventory.notifyObservers();
}
llinfos << "Replaced current element 0 for type " << type
- << " size is now " << mWearableDatas[type].size() << llendl;
+ << " size is now " << getWearableCount(type) << llendl;
}
//llinfos << "LLVOAvatar::setWearableItem()" << llendl;
@@ -1623,7 +1475,7 @@ void LLAgentWearables::setWearableFinal(LLInventoryItem* new_item, LLWearable* n
void LLAgentWearables::queryWearableCache()
{
- if (!areWearablesLoaded())
+ if (!areWearablesLoaded() || (gAgent.getRegion() && gAgent.getRegion()->getCentralBakeVersion()))
{
return;
}
@@ -1652,7 +1504,7 @@ void LLAgentWearables::queryWearableCache()
num_queries++;
// *NOTE: make sure at least one request gets packed
- ETextureIndex te_index = LLVOAvatarDictionary::bakedToLocalTextureIndex((EBakedTextureIndex)baked_index);
+ ETextureIndex te_index = LLAvatarAppearanceDictionary::bakedToLocalTextureIndex((EBakedTextureIndex)baked_index);
//llinfos << "Requesting texture for hash " << hash << " in baked texture slot " << baked_index << llendl;
gMessageSystem->nextBlockFast(_PREHASH_WearableData);
@@ -1667,57 +1519,26 @@ void LLAgentWearables::queryWearableCache()
{
if (isAgentAvatarValid())
{
+ selfStartPhase("fetch_texture_cache_entries");
gAgentAvatarp->outputRezTiming("Fetching textures from cache");
}
- llinfos << "Requesting texture cache entry for " << num_queries << " baked textures" << llendl;
+ LL_DEBUGS("Avatar") << gAgentAvatarp->avString() << "Requesting texture cache entry for " << num_queries << " baked textures" << LL_ENDL;
gMessageSystem->sendReliable(gAgent.getRegion()->getHost());
gAgentQueryManager.mNumPendingQueries++;
gAgentQueryManager.mWearablesCacheQueryID++;
}
}
-LLUUID LLAgentWearables::computeBakedTextureHash(LLVOAvatarDefines::EBakedTextureIndex baked_index,
- BOOL generate_valid_hash) // Set to false if you want to upload the baked texture w/o putting it in the cache
+// virtual
+void LLAgentWearables::invalidateBakedTextureHash(LLMD5& hash) const
{
- LLUUID hash_id;
- bool hash_computed = false;
- LLMD5 hash;
- const LLVOAvatarDictionary::BakedEntry *baked_dict = LLVOAvatarDictionary::getInstance()->getBakedTexture(baked_index);
-
- for (U8 i=0; i < baked_dict->mWearables.size(); i++)
- {
- const LLWearableType::EType baked_type = baked_dict->mWearables[i];
- const U32 num_wearables = getWearableCount(baked_type);
- for (U32 index = 0; index < num_wearables; ++index)
- {
- const LLWearable* wearable = getWearable(baked_type,index);
- if (wearable)
- {
- LLUUID asset_id = wearable->getAssetID();
- hash.update((const unsigned char*)asset_id.mData, UUID_BYTES);
- hash_computed = true;
- }
- }
- }
- if (hash_computed)
- {
- hash.update((const unsigned char*)baked_dict->mWearablesHashID.mData, UUID_BYTES);
-
// Add some garbage into the hash so that it becomes invalid.
- if (!generate_valid_hash)
- {
if (isAgentAvatarValid())
{
hash.update((const unsigned char*)gAgentAvatarp->getID().mData, UUID_BYTES);
}
}
- hash.finalize();
- hash.raw_digest(hash_id.mData);
- }
-
- return hash_id;
-}
// User has picked "remove from avatar" from a menu.
// static
@@ -1740,7 +1561,7 @@ void LLAgentWearables::userRemoveWearablesOfType(const LLWearableType::EType &ty
}
}
-// Combines userRemoveAllAttachments() and userAttachMultipleAttachments() logic to
+// Combines userRemoveMulipleAttachments() and userAttachMultipleAttachments() logic to
// get attachments into desired state with minimal number of adds/removes.
void LLAgentWearables::userUpdateAttachments(LLInventoryModel::item_array_t& obj_item_array)
{
@@ -1754,7 +1575,11 @@ void LLAgentWearables::userUpdateAttachments(LLInventoryModel::item_array_t& obj
std::set<LLUUID> requested_item_ids;
std::set<LLUUID> current_item_ids;
for (S32 i=0; i<obj_item_array.count(); i++)
- requested_item_ids.insert(obj_item_array[i].get()->getLinkedUUID());
+ {
+ const LLUUID & requested_id = obj_item_array[i].get()->getLinkedUUID();
+ //llinfos << "Requested attachment id " << requested_id << llendl;
+ requested_item_ids.insert(requested_id);
+ }
// Build up list of objects to be removed and items currently attached.
llvo_vec_t objects_to_remove;
@@ -1771,17 +1596,28 @@ void LLAgentWearables::userUpdateAttachments(LLInventoryModel::item_array_t& obj
if (objectp)
{
LLUUID object_item_id = objectp->getAttachmentItemID();
+
+ bool remove_attachment = true;
if (requested_item_ids.find(object_item_id) != requested_item_ids.end())
- {
- // Object currently worn, was requested.
+ { // Object currently worn, was requested to keep it
// Flag as currently worn so we won't have to add it again.
- current_item_ids.insert(object_item_id);
+ remove_attachment = false;
}
- else
+ else if (objectp->isTempAttachment())
+ { // Check if we should keep this temp attachment
+ remove_attachment = LLAppearanceMgr::instance().shouldRemoveTempAttachment(objectp->getID());
+ }
+
+ if (remove_attachment)
{
- // object currently worn, not requested.
+ // llinfos << "found object to remove, id " << objectp->getID() << ", item " << objectp->getAttachmentItemID() << llendl;
objects_to_remove.push_back(objectp);
}
+ else
+ {
+ // llinfos << "found object to keep, id " << objectp->getID() << ", item " << objectp->getAttachmentItemID() << llendl;
+ current_item_ids.insert(object_item_id);
+ }
}
}
}
@@ -1836,31 +1672,6 @@ void LLAgentWearables::userRemoveMultipleAttachments(llvo_vec_t& objects_to_remo
gMessageSystem->sendReliable(gAgent.getRegionHost());
}
-void LLAgentWearables::userRemoveAllAttachments()
-{
- if (!isAgentAvatarValid()) return;
-
- llvo_vec_t objects_to_remove;
-
- for (LLVOAvatar::attachment_map_t::iterator iter = gAgentAvatarp->mAttachmentPoints.begin();
- iter != gAgentAvatarp->mAttachmentPoints.end();)
- {
- LLVOAvatar::attachment_map_t::iterator curiter = iter++;
- LLViewerJointAttachment* attachment = curiter->second;
- for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
- attachment_iter != attachment->mAttachedObjects.end();
- ++attachment_iter)
- {
- LLViewerObject *attached_object = (*attachment_iter);
- if (attached_object)
- {
- objects_to_remove.push_back(attached_object);
- }
- }
- }
- userRemoveMultipleAttachments(objects_to_remove);
-}
-
void LLAgentWearables::userAttachMultipleAttachments(LLInventoryModel::item_array_t& obj_item_array)
{
// Build a compound message to send all the objects that need to be rezzed.
@@ -1925,7 +1736,7 @@ void LLAgentWearables::checkWearablesLoaded() const
// Returns false if the given wearable is already topmost/bottommost
// (depending on closer_to_body parameter).
-bool LLAgentWearables::canMoveWearable(const LLUUID& item_id, bool closer_to_body)
+bool LLAgentWearables::canMoveWearable(const LLUUID& item_id, bool closer_to_body) const
{
const LLWearable* wearable = getWearableFromItemID(item_id);
if (!wearable) return false;
@@ -1953,7 +1764,7 @@ void LLAgentWearables::updateWearablesLoaded()
}
}
-bool LLAgentWearables::canWearableBeRemoved(const LLWearable* wearable) const
+bool LLAgentWearables::canWearableBeRemoved(const LLViewerWearable* wearable) const
{
if (!wearable) return false;
@@ -1968,7 +1779,7 @@ void LLAgentWearables::animateAllWearableParams(F32 delta, BOOL upload_bake)
{
for (S32 count = 0; count < (S32)getWearableCount((LLWearableType::EType)type); ++count)
{
- LLWearable *wearable = getWearable((LLWearableType::EType)type,count);
+ LLViewerWearable *wearable = getViewerWearable((LLWearableType::EType)type,count);
llassert(wearable);
if (wearable)
{
@@ -1983,28 +1794,39 @@ bool LLAgentWearables::moveWearable(const LLViewerInventoryItem* item, bool clos
if (!item) return false;
if (!item->isWearableType()) return false;
- wearableentry_map_t::iterator wearable_iter = mWearableDatas.find(item->getWearableType());
- if (wearable_iter == mWearableDatas.end()) return false;
-
- wearableentry_vec_t& wearable_vec = wearable_iter->second;
- if (wearable_vec.empty()) return false;
+ LLWearableType::EType type = item->getWearableType();
+ U32 wearable_count = getWearableCount(type);
+ if (0 == wearable_count) return false;
const LLUUID& asset_id = item->getAssetUUID();
//nowhere to move if the wearable is already on any boundary (closest to the body/furthest from the body)
- if (closer_to_body && asset_id == wearable_vec.front()->getAssetID()) return false;
- if (!closer_to_body && asset_id == wearable_vec.back()->getAssetID()) return false;
+ if (closer_to_body)
+ {
+ LLViewerWearable* bottom_wearable = dynamic_cast<LLViewerWearable*>( getBottomWearable(type) );
+ if (bottom_wearable->getAssetID() == asset_id)
+ {
+ return false;
+ }
+ }
+ else // !closer_to_body
+ {
+ LLViewerWearable* top_wearable = dynamic_cast<LLViewerWearable*>( getTopWearable(type) );
+ if (top_wearable->getAssetID() == asset_id)
+ {
+ return false;
+ }
+ }
- for (U32 i = 0; i < wearable_vec.size(); ++i)
+ for (U32 i = 0; i < wearable_count; ++i)
{
- LLWearable* wearable = wearable_vec[i];
+ LLViewerWearable* wearable = getViewerWearable(type, i);
if (!wearable) continue;
if (wearable->getAssetID() != asset_id) continue;
//swapping wearables
U32 swap_i = closer_to_body ? i-1 : i+1;
- wearable_vec[i] = wearable_vec[swap_i];
- wearable_vec[swap_i] = wearable;
+ swapWearables(type, i, swap_i);
return true;
}
@@ -2016,19 +1838,10 @@ void LLAgentWearables::createWearable(LLWearableType::EType type, bool wear, con
{
if (type == LLWearableType::WT_INVALID || type == LLWearableType::WT_NONE) return;
- LLWearable* wearable = LLWearableList::instance().createNewWearable(type);
+ LLViewerWearable* wearable = LLWearableList::instance().createNewWearable(type, gAgentAvatarp);
LLAssetType::EType asset_type = wearable->getAssetType();
LLInventoryType::EType inv_type = LLInventoryType::IT_WEARABLE;
- LLPointer<LLInventoryCallback> cb;
- if (wear)
- {
- cb = new LLWearAndEditCallback;
- }
- else
- {
- cb = new LLCreateWearableCallback;
- }
-
+ LLPointer<LLInventoryCallback> cb = wear ? new LLBoostFuncInventoryCallback(wear_and_edit_cb) : NULL;
LLUUID folder_id;
if (parent_id.notNull())
@@ -2063,7 +1876,7 @@ void LLAgentWearables::editWearable(const LLUUID& item_id)
return;
}
- LLWearable* wearable = gAgentWearables.getWearableFromItemID(item_id);
+ LLViewerWearable* wearable = gAgentWearables.getWearableFromItemID(item_id);
if (!wearable)
{
llwarns << "Cannot get wearable" << llendl;
@@ -2132,6 +1945,11 @@ boost::signals2::connection LLAgentWearables::addLoadedCallback(loaded_callback_
return mLoadedSignal.connect(cb);
}
+bool LLAgentWearables::changeInProgress() const
+{
+ return mCOFChangeInProgress;
+}
+
void LLAgentWearables::notifyLoadingStarted()
{
mCOFChangeInProgress = true;
diff --git a/indra/newview/llagentwearables.h b/indra/newview/llagentwearables.h
index 01cae3ffd8..5be4648636 100644..100755
--- a/indra/newview/llagentwearables.h
+++ b/indra/newview/llagentwearables.h
@@ -36,16 +36,16 @@
// newview
#include "llinventorymodel.h"
#include "llviewerinventory.h"
-#include "llvoavatardefines.h"
+#include "llavatarappearancedefines.h"
+#include "llwearabledata.h"
class LLInventoryItem;
class LLVOAvatarSelf;
-class LLWearable;
+class LLViewerWearable;
class LLInitialWearablesFetch;
class LLViewerObject;
-class LLTexLayerTemplate;
-class LLAgentWearables : public LLInitClass<LLAgentWearables>
+class LLAgentWearables : public LLInitClass<LLAgentWearables>, public LLWearableData
{
//--------------------------------------------------------------------
// Constructors / destructors / Initializers
@@ -79,10 +79,10 @@ public:
bool isCOFChangeInProgress() const { return mCOFChangeInProgress; }
void updateWearablesLoaded();
void checkWearablesLoaded() const;
- bool canMoveWearable(const LLUUID& item_id, bool closer_to_body);
+ bool canMoveWearable(const LLUUID& item_id, bool closer_to_body) const;
// Note: False for shape, skin, eyes, and hair, unless you have MORE than 1.
- bool canWearableBeRemoved(const LLWearable* wearable) const;
+ bool canWearableBeRemoved(const LLViewerWearable* wearable) const;
void animateAllWearableParams(F32 delta, BOOL upload_bake);
@@ -92,52 +92,38 @@ public:
public:
const LLUUID getWearableItemID(LLWearableType::EType type, U32 index /*= 0*/) const;
const LLUUID getWearableAssetID(LLWearableType::EType type, U32 index /*= 0*/) const;
- const LLWearable* getWearableFromItemID(const LLUUID& item_id) const;
- LLWearable* getWearableFromItemID(const LLUUID& item_id);
- LLWearable* getWearableFromAssetID(const LLUUID& asset_id);
+ const LLViewerWearable* getWearableFromItemID(const LLUUID& item_id) const;
+ LLViewerWearable* getWearableFromItemID(const LLUUID& item_id);
+ LLViewerWearable* getWearableFromAssetID(const LLUUID& asset_id);
+ LLViewerWearable* getViewerWearable(const LLWearableType::EType type, U32 index /*= 0*/);
+ const LLViewerWearable* getViewerWearable(const LLWearableType::EType type, U32 index /*= 0*/) const;
LLInventoryItem* getWearableInventoryItem(LLWearableType::EType type, U32 index /*= 0*/);
static BOOL selfHasWearable(LLWearableType::EType type);
- LLWearable* getWearable(const LLWearableType::EType type, U32 index /*= 0*/);
- const LLWearable* getWearable(const LLWearableType::EType type, U32 index /*= 0*/) const;
- LLWearable* getTopWearable(const LLWearableType::EType type);
- LLWearable* getBottomWearable(const LLWearableType::EType type);
- U32 getWearableCount(const LLWearableType::EType type) const;
- U32 getWearableCount(const U32 tex_index) const;
-
- static const U32 MAX_CLOTHING_PER_TYPE = 5;
-
//--------------------------------------------------------------------
// Setters
//--------------------------------------------------------------------
-
private:
- // Low-level data structure setter - public access is via setWearableItem, etc.
- void setWearable(const LLWearableType::EType type, U32 index, LLWearable *wearable);
- U32 pushWearable(const LLWearableType::EType type, LLWearable *wearable);
- void wearableUpdated(LLWearable *wearable);
- void popWearable(LLWearable *wearable);
- void popWearable(const LLWearableType::EType type, U32 index);
-
+ /*virtual*/void wearableUpdated(LLWearable *wearable, BOOL removed);
public:
- void setWearableItem(LLInventoryItem* new_item, LLWearable* wearable, bool do_append = false);
- void setWearableOutfit(const LLInventoryItem::item_array_t& items, const LLDynamicArray< LLWearable* >& wearables, BOOL remove);
+ void setWearableItem(LLInventoryItem* new_item, LLViewerWearable* wearable, bool do_append = false);
+ void setWearableOutfit(const LLInventoryItem::item_array_t& items, const LLDynamicArray< LLViewerWearable* >& wearables, BOOL remove);
void setWearableName(const LLUUID& item_id, const std::string& new_name);
- void addLocalTextureObject(const LLWearableType::EType wearable_type, const LLVOAvatarDefines::ETextureIndex texture_type, U32 wearable_index);
- U32 getWearableIndex(const LLWearable *wearable) const;
+ // *TODO: Move this into llappearance/LLWearableData ?
+ void addLocalTextureObject(const LLWearableType::EType wearable_type, const LLAvatarAppearanceDefines::ETextureIndex texture_type, U32 wearable_index);
protected:
- void setWearableFinal(LLInventoryItem* new_item, LLWearable* new_wearable, bool do_append = false);
- static bool onSetWearableDialog(const LLSD& notification, const LLSD& response, LLWearable* wearable);
+ void setWearableFinal(LLInventoryItem* new_item, LLViewerWearable* new_wearable, bool do_append = false);
+ static bool onSetWearableDialog(const LLSD& notification, const LLSD& response, LLViewerWearable* wearable);
void addWearableToAgentInventory(LLPointer<LLInventoryCallback> cb,
- LLWearable* wearable,
+ LLViewerWearable* wearable,
const LLUUID& category_id = LLUUID::null,
BOOL notify = TRUE);
void addWearabletoAgentInventoryDone(const LLWearableType::EType type,
const U32 index,
const LLUUID& item_id,
- LLWearable* wearable);
+ LLViewerWearable* wearable);
void recoverMissingWearable(const LLWearableType::EType type, U32 index /*= 0*/);
void recoverMissingWearableDone();
@@ -172,15 +158,14 @@ protected:
public:
// Processes the initial wearables update message (if necessary, since the outfit folder makes it redundant)
static void processAgentInitialWearablesUpdate(LLMessageSystem* mesgsys, void** user_data);
- LLUUID computeBakedTextureHash(LLVOAvatarDefines::EBakedTextureIndex baked_index,
- BOOL generate_valid_hash = TRUE);
protected:
+ /*virtual*/ void invalidateBakedTextureHash(LLMD5& hash) const;
void sendAgentWearablesUpdate();
void sendAgentWearablesRequest();
void queryWearableCache();
void updateServer();
- static void onInitialWearableAssetArrived(LLWearable* wearable, void* userdata);
+ static void onInitialWearableAssetArrived(LLViewerWearable* wearable, void* userdata);
//--------------------------------------------------------------------
// Outfits
@@ -198,7 +183,7 @@ private:
// Save Wearables
//--------------------------------------------------------------------
public:
- void saveWearableAs(const LLWearableType::EType type, const U32 index, const std::string& new_name, BOOL save_in_lost_and_found);
+ void saveWearableAs(const LLWearableType::EType type, const U32 index, const std::string& new_name, const std::string& description, BOOL save_in_lost_and_found);
void saveWearable(const LLWearableType::EType type, const U32 index, BOOL send_update = TRUE,
const std::string new_name = "");
void saveAllWearables();
@@ -215,7 +200,6 @@ public:
static void userUpdateAttachments(LLInventoryModel::item_array_t& obj_item_array);
static void userRemoveMultipleAttachments(llvo_vec_t& llvo_array);
- static void userRemoveAllAttachments();
static void userAttachMultipleAttachments(LLInventoryModel::item_array_t& obj_item_array);
BOOL itemUpdatePending(const LLUUID& item_id) const;
@@ -233,6 +217,7 @@ public:
typedef boost::signals2::signal<void()> loaded_signal_t;
boost::signals2::connection addLoadedCallback(loaded_callback_t cb);
+ bool changeInProgress() const;
void notifyLoadingStarted();
void notifyLoadingFinished();
@@ -244,10 +229,6 @@ private:
// Member variables
//--------------------------------------------------------------------
private:
- typedef std::vector<LLWearable*> wearableentry_vec_t; // all wearables of a certain type (EG all shirts)
- typedef std::map<LLWearableType::EType, wearableentry_vec_t> wearableentry_map_t; // wearable "categories" arranged by wearable type
- wearableentry_map_t mWearableDatas;
-
static BOOL mInitialWearablesUpdateReceived;
BOOL mWearablesLoaded;
std::set<LLUUID> mItemsAwaitingWearableUpdate;
@@ -288,15 +269,17 @@ private:
addWearableToAgentInventoryCallback(LLPointer<LLRefCount> cb,
LLWearableType::EType type,
U32 index,
- LLWearable* wearable,
- U32 todo = CALL_NONE);
+ LLViewerWearable* wearable,
+ U32 todo = CALL_NONE,
+ const std::string description = "");
virtual void fire(const LLUUID& inv_item);
private:
LLWearableType::EType mType;
U32 mIndex;
- LLWearable* mWearable;
+ LLViewerWearable* mWearable;
U32 mTodo;
LLPointer<LLRefCount> mCB;
+ std::string mDescription;
};
}; // LLAgentWearables
diff --git a/indra/newview/llagentwearablesfetch.cpp b/indra/newview/llagentwearablesfetch.cpp
index 8cba54347e..8b6b6db525 100644..100755
--- a/indra/newview/llagentwearablesfetch.cpp
+++ b/indra/newview/llagentwearablesfetch.cpp
@@ -35,12 +35,7 @@
#include "llvoavatarself.h"
-class LLOrderMyOutfitsOnDestroy: public LLInventoryCallback
-{
-public:
- LLOrderMyOutfitsOnDestroy() {};
-
- virtual ~LLOrderMyOutfitsOnDestroy()
+void order_my_outfits_cb()
{
if (!LLApp::isRunning())
{
@@ -80,15 +75,12 @@ public:
llinfos << "Finished updating My Outfits with wearables ordering information" << llendl;
}
- /* virtual */ void fire(const LLUUID& inv_item) {};
-};
-
-
LLInitialWearablesFetch::LLInitialWearablesFetch(const LLUUID& cof_id) :
LLInventoryFetchDescendentsObserver(cof_id)
{
if (isAgentAvatarValid())
{
+ gAgentAvatarp->startPhase("initial_wearables_fetch");
gAgentAvatarp->outputRezTiming("Initial wearables fetch started");
}
}
@@ -107,6 +99,7 @@ void LLInitialWearablesFetch::done()
doOnIdleOneTime(boost::bind(&LLInitialWearablesFetch::processContents,this));
if (isAgentAvatarValid())
{
+ gAgentAvatarp->stopPhase("initial_wearables_fetch");
gAgentAvatarp->outputRezTiming("Initial wearables fetch done");
}
}
@@ -340,7 +333,7 @@ void LLLibraryOutfitsFetch::folderDone()
}
mClothingID = gInventory.findCategoryUUIDForType(LLFolderType::FT_CLOTHING);
- mLibraryClothingID = gInventory.findCategoryUUIDForType(LLFolderType::FT_CLOTHING, false, true);
+ mLibraryClothingID = gInventory.findLibraryCategoryUUIDForType(LLFolderType::FT_CLOTHING, false);
// If Library->Clothing->Initial Outfits exists, use that.
LLNameCategoryCollector matchFolderFunctor("Initial Outfits");
@@ -561,7 +554,7 @@ void LLLibraryOutfitsFetch::contentsDone()
LLInventoryModel::cat_array_t cat_array;
LLInventoryModel::item_array_t wearable_array;
- LLPointer<LLOrderMyOutfitsOnDestroy> order_myoutfits_on_destroy = new LLOrderMyOutfitsOnDestroy;
+ LLPointer<LLInventoryCallback> order_myoutfits_on_destroy = new LLBoostFuncInventoryCallback(no_op_inventory_func, order_my_outfits_cb);
for (uuid_vec_t::const_iterator folder_iter = mImportedClothingFolders.begin();
folder_iter != mImportedClothingFolders.end();
diff --git a/indra/newview/llagentwearablesfetch.h b/indra/newview/llagentwearablesfetch.h
index bedc445c0e..bedc445c0e 100644..100755
--- a/indra/newview/llagentwearablesfetch.h
+++ b/indra/newview/llagentwearablesfetch.h
diff --git a/indra/newview/llanimstatelabels.cpp b/indra/newview/llanimstatelabels.cpp
index a0858612c2..a0858612c2 100644..100755
--- a/indra/newview/llanimstatelabels.cpp
+++ b/indra/newview/llanimstatelabels.cpp
diff --git a/indra/newview/llanimstatelabels.h b/indra/newview/llanimstatelabels.h
index 97aabf5378..97aabf5378 100644..100755
--- a/indra/newview/llanimstatelabels.h
+++ b/indra/newview/llanimstatelabels.h
diff --git a/indra/newview/llappcorehttp.cpp b/indra/newview/llappcorehttp.cpp
new file mode 100755
index 0000000000..0d7d41304d
--- /dev/null
+++ b/indra/newview/llappcorehttp.cpp
@@ -0,0 +1,192 @@
+/**
+ * @file llappcorehttp.cpp
+ * @brief
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 "llappcorehttp.h"
+
+#include "llviewercontrol.h"
+
+
+const F64 LLAppCoreHttp::MAX_THREAD_WAIT_TIME(10.0);
+
+LLAppCoreHttp::LLAppCoreHttp()
+ : mRequest(NULL),
+ mStopHandle(LLCORE_HTTP_HANDLE_INVALID),
+ mStopRequested(0.0),
+ mStopped(false),
+ mPolicyDefault(-1)
+{}
+
+
+LLAppCoreHttp::~LLAppCoreHttp()
+{
+ delete mRequest;
+ mRequest = NULL;
+}
+
+
+void LLAppCoreHttp::init()
+{
+ LLCore::HttpStatus status = LLCore::HttpRequest::createService();
+ if (! status)
+ {
+ LL_ERRS("Init") << "Failed to initialize HTTP services. Reason: "
+ << status.toString()
+ << LL_ENDL;
+ }
+
+ // Point to our certs or SSH/https: will fail on connect
+ status = LLCore::HttpRequest::setPolicyGlobalOption(LLCore::HttpRequest::GP_CA_FILE,
+ gDirUtilp->getCAFile());
+ if (! status)
+ {
+ LL_ERRS("Init") << "Failed to set CA File for HTTP services. Reason: "
+ << status.toString()
+ << LL_ENDL;
+ }
+
+ // Establish HTTP Proxy. "LLProxy" is a special string which directs
+ // the code to use LLProxy::applyProxySettings() to establish any
+ // HTTP or SOCKS proxy for http operations.
+ status = LLCore::HttpRequest::setPolicyGlobalOption(LLCore::HttpRequest::GP_LLPROXY, 1);
+ if (! status)
+ {
+ LL_ERRS("Init") << "Failed to set HTTP proxy for HTTP services. Reason: "
+ << status.toString()
+ << LL_ENDL;
+ }
+
+ // Tracing levels for library & libcurl (note that 2 & 3 are beyond spammy):
+ // 0 - None
+ // 1 - Basic start, stop simple transitions
+ // 2 - libcurl CURLOPT_VERBOSE mode with brief lines
+ // 3 - with partial data content
+ static const std::string http_trace("QAModeHttpTrace");
+ if (gSavedSettings.controlExists(http_trace))
+ {
+ long trace_level(0L);
+ trace_level = long(gSavedSettings.getU32(http_trace));
+ status = LLCore::HttpRequest::setPolicyGlobalOption(LLCore::HttpRequest::GP_TRACE, trace_level);
+ }
+
+ // Setup default policy and constrain if directed to
+ mPolicyDefault = LLCore::HttpRequest::DEFAULT_POLICY_ID;
+ static const std::string texture_concur("TextureFetchConcurrency");
+ if (gSavedSettings.controlExists(texture_concur))
+ {
+ U32 concur(llmin(gSavedSettings.getU32(texture_concur), U32(12)));
+
+ if (concur > 0)
+ {
+ LLCore::HttpStatus status;
+ status = LLCore::HttpRequest::setPolicyClassOption(mPolicyDefault,
+ LLCore::HttpRequest::CP_CONNECTION_LIMIT,
+ concur);
+ if (! status)
+ {
+ LL_WARNS("Init") << "Unable to set texture fetch concurrency. Reason: "
+ << status.toString()
+ << LL_ENDL;
+ }
+ else
+ {
+ LL_INFOS("Init") << "Application settings overriding default texture fetch concurrency. New value: "
+ << concur
+ << LL_ENDL;
+ }
+ }
+ }
+
+ // Kick the thread
+ status = LLCore::HttpRequest::startThread();
+ if (! status)
+ {
+ LL_ERRS("Init") << "Failed to start HTTP servicing thread. Reason: "
+ << status.toString()
+ << LL_ENDL;
+ }
+
+ mRequest = new LLCore::HttpRequest;
+}
+
+
+void LLAppCoreHttp::requestStop()
+{
+ llassert_always(mRequest);
+
+ mStopHandle = mRequest->requestStopThread(this);
+ if (LLCORE_HTTP_HANDLE_INVALID != mStopHandle)
+ {
+ mStopRequested = LLTimer::getTotalSeconds();
+ }
+}
+
+
+void LLAppCoreHttp::cleanup()
+{
+ if (LLCORE_HTTP_HANDLE_INVALID == mStopHandle)
+ {
+ // Should have been started already...
+ requestStop();
+ }
+
+ if (LLCORE_HTTP_HANDLE_INVALID == mStopHandle)
+ {
+ LL_WARNS("Cleanup") << "Attempting to cleanup HTTP services without thread shutdown"
+ << LL_ENDL;
+ }
+ else
+ {
+ while (! mStopped && LLTimer::getTotalSeconds() < (mStopRequested + MAX_THREAD_WAIT_TIME))
+ {
+ mRequest->update(200000);
+ ms_sleep(50);
+ }
+ if (! mStopped)
+ {
+ LL_WARNS("Cleanup") << "Attempting to cleanup HTTP services with thread shutdown incomplete"
+ << LL_ENDL;
+ }
+ }
+
+ delete mRequest;
+ mRequest = NULL;
+
+ LLCore::HttpStatus status = LLCore::HttpRequest::destroyService();
+ if (! status)
+ {
+ LL_WARNS("Cleanup") << "Failed to shutdown HTTP services, continuing. Reason: "
+ << status.toString()
+ << LL_ENDL;
+ }
+}
+
+
+void LLAppCoreHttp::onCompleted(LLCore::HttpHandle, LLCore::HttpResponse *)
+{
+ mStopped = true;
+}
diff --git a/indra/newview/llappcorehttp.h b/indra/newview/llappcorehttp.h
new file mode 100755
index 0000000000..241d73ad52
--- /dev/null
+++ b/indra/newview/llappcorehttp.h
@@ -0,0 +1,86 @@
+/**
+ * @file llappcorehttp.h
+ * @brief Singleton initialization/shutdown class for llcorehttp library
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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_APP_COREHTTP_H_
+#define _LL_APP_COREHTTP_H_
+
+
+#include "httprequest.h"
+#include "httphandler.h"
+#include "httpresponse.h"
+
+
+// This class manages the lifecyle of the core http library.
+// Slightly different style than traditional code but reflects
+// the use of handler classes and light-weight interface
+// object instances of the new libraries. To be used
+// as a singleton and static construction is fine.
+class LLAppCoreHttp : public LLCore::HttpHandler
+{
+public:
+ LLAppCoreHttp();
+ ~LLAppCoreHttp();
+
+ // Initialize the LLCore::HTTP library creating service classes
+ // and starting the servicing thread. Caller is expected to do
+ // other initializations (SSL mutex, thread hash function) appropriate
+ // for the application.
+ void init();
+
+ // Request that the servicing thread stop servicing requests,
+ // release resource references and stop. Request is asynchronous
+ // and @see cleanup() will perform a limited wait loop for this
+ // request to stop the thread.
+ void requestStop();
+
+ // Terminate LLCore::HTTP library services. Caller is expected
+ // to have made a best-effort to shutdown the servicing thread
+ // by issuing a requestThreadStop() and waiting for completion
+ // notification that the stop has completed.
+ void cleanup();
+
+ // Notification when the stop request is complete.
+ virtual void onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response);
+
+ // Retrieve the policy class for default operations.
+ int getPolicyDefault() const
+ {
+ return mPolicyDefault;
+ }
+
+private:
+ static const F64 MAX_THREAD_WAIT_TIME;
+
+private:
+ LLCore::HttpRequest * mRequest;
+ LLCore::HttpHandle mStopHandle;
+ F64 mStopRequested;
+ bool mStopped;
+ int mPolicyDefault;
+};
+
+
+#endif // _LL_APP_COREHTTP_H_
diff --git a/indra/newview/llappdelegate-objc.mm b/indra/newview/llappdelegate-objc.mm
new file mode 100644
index 0000000000..91251ed7c0
--- /dev/null
+++ b/indra/newview/llappdelegate-objc.mm
@@ -0,0 +1,157 @@
+/**
+ * @file llappdelegate-objc.mm
+ * @brief Class implementation for the Mac version's application delegate.
+ *
+ * $LicenseInfo:firstyear=2000&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#import "llappdelegate-objc.h"
+#include "llwindowmacosx-objc.h"
+#include <Carbon/Carbon.h> // Used for Text Input Services ("Safe" API - it's supported)
+
+@implementation LLAppDelegate
+
+@synthesize window;
+@synthesize inputWindow;
+@synthesize inputView;
+@synthesize currentInputLanguage;
+
+- (void)dealloc
+{
+ [super dealloc];
+}
+
+- (void) applicationDidFinishLaunching:(NSNotification *)notification
+{
+ frameTimer = nil;
+
+ [self languageUpdated];
+
+ if (initViewer())
+ {
+ frameTimer = [NSTimer scheduledTimerWithTimeInterval:0.0 target:self selector:@selector(mainLoop) userInfo:nil repeats:YES];
+ } else {
+ handleQuit();
+ }
+
+ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(languageUpdated) name:@"NSTextInputContextKeyboardSelectionDidChangeNotification" object:nil];
+
+ [[NSAppleEventManager sharedAppleEventManager] setEventHandler:self andSelector:@selector(handleGetURLEvent:withReplyEvent:) forEventClass:kInternetEventClass andEventID:kAEGetURL];
+}
+
+- (void) handleGetURLEvent:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent {
+ NSString *url= nil;
+ url = [[[[NSAppleEventManager sharedAppleEventManager]// 1
+ currentAppleEvent]// 2
+ paramDescriptorForKeyword:keyDirectObject]// 3
+ stringValue];// 4
+
+ const char* url_utf8 = [url UTF8String];
+ handleUrl(url_utf8);
+}
+
+- (void) applicationDidBecomeActive:(NSNotification *)notification
+{
+ callWindowFocus();
+}
+
+- (void) applicationDidResignActive:(NSNotification *)notification
+{
+ callWindowUnfocus();
+}
+
+- (NSApplicationDelegateReply) applicationShouldTerminate:(NSApplication *)sender
+{
+ if (!runMainLoop())
+ {
+ handleQuit();
+ return NSTerminateCancel;
+ } else {
+ [frameTimer release];
+ cleanupViewer();
+ return NSTerminateNow;
+ }
+}
+
+- (void) mainLoop
+{
+ bool appExiting = runMainLoop();
+ if (appExiting)
+ {
+ [frameTimer release];
+ [[NSApplication sharedApplication] terminate:self];
+ }
+}
+
+- (void) showInputWindow:(bool)show withEvent:(NSEvent*)textEvent
+{
+ if (![self romanScript])
+ {
+ if (show)
+ {
+ NSLog(@"Showing input window.");
+ [inputWindow makeKeyAndOrderFront:inputWindow];
+ if (textEvent != nil)
+ {
+ [[inputView inputContext] discardMarkedText];
+ [[inputView inputContext] handleEvent:textEvent];
+ }
+ } else {
+ NSLog(@"Hiding input window.");
+ [inputWindow orderOut:inputWindow];
+ [window makeKeyAndOrderFront:window];
+ }
+ }
+}
+
+// This will get called multiple times by NSNotificationCenter.
+// It will be called every time that the window focus changes, and every time that the input language gets changed.
+// The primary use case for this selector is to update our current input language when the user, for whatever reason, changes the input language.
+// This is the more elegant way of handling input language changes instead of checking every time we want to use the input window.
+
+- (void) languageUpdated
+{
+ TISInputSourceRef currentInput = TISCopyCurrentKeyboardInputSource();
+ CFArrayRef languages = (CFArrayRef)TISGetInputSourceProperty(currentInput, kTISPropertyInputSourceLanguages);
+
+#if 0 // In the event of ever needing to add new language sources, change this to 1 and watch the terminal for "languages:"
+ NSLog(@"languages: %@", TISGetInputSourceProperty(currentInput, kTISPropertyInputSourceLanguages));
+#endif
+
+ // Typically the language we want is going to be the very first result in the array.
+ currentInputLanguage = (NSString*)CFArrayGetValueAtIndex(languages, 0);
+}
+
+- (bool) romanScript
+{
+ // How to add support for new languages with the input window:
+ // Simply append this array with the language code (ja for japanese, ko for korean, zh for chinese, etc.)
+ NSArray *nonRomanScript = [[NSArray alloc] initWithObjects:@"ja", @"ko", @"zh-Hant", @"zh-Hans", nil];
+ if ([nonRomanScript containsObject:currentInputLanguage])
+ {
+ return false;
+ }
+
+ return true;
+}
+
+@end
diff --git a/indra/newview/llappearance.h b/indra/newview/llappearance.h
index a28b77b1fc..05dfac4e42 100644..100755
--- a/indra/newview/llappearance.h
+++ b/indra/newview/llappearance.h
@@ -38,14 +38,14 @@ public:
void addParam( S32 id, F32 value ) { mParamMap[id] = value; }
F32 getParam( S32 id, F32 defval ) { return get_if_there(mParamMap, id, defval ); }
- void addTexture( S32 te, const LLUUID& uuid ) { if( te < LLVOAvatarDefines::TEX_NUM_INDICES ) mTextures[te] = uuid; }
- const LLUUID& getTexture( S32 te ) { return ( te < LLVOAvatarDefines::TEX_NUM_INDICES ) ? mTextures[te] : LLUUID::null; }
+ void addTexture( S32 te, const LLUUID& uuid ) { if( te < LLAvatarAppearanceDefines::TEX_NUM_INDICES ) mTextures[te] = uuid; }
+ const LLUUID& getTexture( S32 te ) { return ( te < LLAvatarAppearanceDefines::TEX_NUM_INDICES ) ? mTextures[te] : LLUUID::null; }
- void clear() { mParamMap.clear(); for( S32 i=0; i<LLVOAvatarDefines::TEX_NUM_INDICES; i++ ) mTextures[i].setNull(); }
+ void clear() { mParamMap.clear(); for( S32 i=0; i<LLAvatarAppearanceDefines::TEX_NUM_INDICES; i++ ) mTextures[i].setNull(); }
typedef std::map<S32, F32> param_map_t;
param_map_t mParamMap;
- LLUUID mTextures[LLVOAvatarDefines::TEX_NUM_INDICES];
+ LLUUID mTextures[LLAvatarAppearanceDefines::TEX_NUM_INDICES];
};
#endif // LL_LLAPPEARANCE_H
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index 33f5373d7e..da1609297e 100644..100755
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -26,6 +26,7 @@
#include "llviewerprecompiledheaders.h"
+#include <boost/lexical_cast.hpp>
#include "llaccordionctrltab.h"
#include "llagent.h"
#include "llagentcamera.h"
@@ -49,6 +50,19 @@
#include "llvoavatarself.h"
#include "llviewerregion.h"
#include "llwearablelist.h"
+#include "llsdutil.h"
+#include "llsdserialize.h"
+
+#if LL_MSVC
+// disable boost::lexical_cast warning
+#pragma warning (disable:4702)
+#endif
+
+std::string self_av_string()
+{
+ // On logout gAgentAvatarp can already be invalid
+ return isAgentAvatarValid() ? gAgentAvatarp->avString() : "";
+}
// RAII thingy to guarantee that a variable gets reset when the Setter
// goes out of scope. More general utility would be handy - TODO:
@@ -149,77 +163,359 @@ LLUUID findDescendentCategoryIDByName(const LLUUID& parent_id, const std::string
}
}
-class LLWearInventoryCategoryCallback : public LLInventoryCallback
+// We want this to be much lower (e.g. 15.0 is usually fine), bumping
+// up for now until we can diagnose some cases of very slow response
+// to requests.
+const F32 DEFAULT_RETRY_AFTER_INTERVAL = 300.0;
+
+// Given the current back-end problems, retrying is causing too many
+// duplicate items. Bump this back to 2 once they are resolved (or can
+// leave at 0 if the operations become actually reliable).
+const S32 DEFAULT_MAX_RETRIES = 0;
+
+class LLCallAfterInventoryBatchMgr: public LLEventTimer
{
public:
- LLWearInventoryCategoryCallback(const LLUUID& cat_id, bool append)
+ LLCallAfterInventoryBatchMgr(const LLUUID& dst_cat_id,
+ const std::string& phase_name,
+ nullary_func_t on_completion_func,
+ nullary_func_t on_failure_func = no_op,
+ F32 retry_after = DEFAULT_RETRY_AFTER_INTERVAL,
+ S32 max_retries = DEFAULT_MAX_RETRIES
+ ):
+ mDstCatID(dst_cat_id),
+ mTrackingPhase(phase_name),
+ mOnCompletionFunc(on_completion_func),
+ mOnFailureFunc(on_failure_func),
+ mRetryAfter(retry_after),
+ mMaxRetries(max_retries),
+ mPendingRequests(0),
+ mFailCount(0),
+ mCompletionOrFailureCalled(false),
+ mRetryCount(0),
+ LLEventTimer(5.0)
+ {
+ if (!mTrackingPhase.empty())
+ {
+ selfStartPhase(mTrackingPhase);
+ }
+ }
+
+ void addItems(LLInventoryModel::item_array_t& src_items)
+ {
+ for (LLInventoryModel::item_array_t::const_iterator it = src_items.begin();
+ it != src_items.end();
+ ++it)
+ {
+ LLViewerInventoryItem* item = *it;
+ llassert(item);
+ addItem(item->getUUID());
+ }
+ }
+
+ // Request or re-request operation for specified item.
+ void addItem(const LLUUID& item_id)
{
- mCatID = cat_id;
- mAppend = append;
+ LL_DEBUGS("Avatar") << "item_id " << item_id << llendl;
+
+ if (!requestOperation(item_id))
+ {
+ LL_DEBUGS("Avatar") << "item_id " << item_id << " requestOperation false, skipping" << llendl;
+ return;
}
- void fire(const LLUUID& item_id)
+
+ mPendingRequests++;
+ // On a re-request, this will reset the timer.
+ mWaitTimes[item_id] = LLTimer();
+ if (mRetryCounts.find(item_id) == mRetryCounts.end())
{
- /*
- * Do nothing. We only care about the destructor
- *
- * The reason for this is that this callback is used in a hack where the
- * same callback is given to dozens of items, and the destructor is called
- * after the last item has fired the event and dereferenced it -- if all
- * the events actually fire!
- */
+ mRetryCounts[item_id] = 0;
+ }
+ else
+ {
+ mRetryCounts[item_id]++;
+ }
}
-protected:
- ~LLWearInventoryCategoryCallback()
+ virtual bool requestOperation(const LLUUID& item_id) = 0;
+
+ void onOp(const LLUUID& src_id, const LLUUID& dst_id, LLTimer timestamp)
+ {
+ if (ll_frand() < gSavedSettings.getF32("InventoryDebugSimulateLateOpRate"))
{
- llinfos << "done all inventory callbacks" << llendl;
+ llwarns << "Simulating late operation by punting handling to later" << llendl;
+ doAfterInterval(boost::bind(&LLCallAfterInventoryBatchMgr::onOp,this,src_id,dst_id,timestamp),
+ mRetryAfter);
+ return;
+ }
+ mPendingRequests--;
+ F32 elapsed = timestamp.getElapsedTimeF32();
+ LL_DEBUGS("Avatar") << "op done, src_id " << src_id << " dst_id " << dst_id << " after " << elapsed << " seconds" << llendl;
+ if (mWaitTimes.find(src_id) == mWaitTimes.end())
+ {
+ // No longer waiting for this item - either serviced
+ // already or gave up after too many retries.
+ llwarns << "duplicate or late operation, src_id " << src_id << "dst_id " << dst_id
+ << " elapsed " << elapsed << " after end " << (S32) mCompletionOrFailureCalled << llendl;
+ }
+ mTimeStats.push(elapsed);
+ mWaitTimes.erase(src_id);
+ if (mWaitTimes.empty() && !mCompletionOrFailureCalled)
+ {
+ onCompletionOrFailure();
+ }
+ }
- // Is the destructor called by ordinary dereference, or because the app's shutting down?
- // If the inventory callback manager goes away, we're shutting down, no longer want the callback.
- if( LLInventoryCallbackManager::is_instantiated() )
+ void onCompletionOrFailure()
+ {
+ assert (!mCompletionOrFailureCalled);
+ mCompletionOrFailureCalled = true;
+
+ // Will never call onCompletion() if any item has been flagged as
+ // a failure - otherwise could wind up with corrupted
+ // outfit, involuntary nudity, etc.
+ reportStats();
+ if (!mTrackingPhase.empty())
+ {
+ selfStopPhase(mTrackingPhase);
+ }
+ if (!mFailCount)
{
- LLAppearanceMgr::instance().wearInventoryCategoryOnAvatar(gInventory.getCategory(mCatID), mAppend);
+ onCompletion();
}
else
{
- llwarns << "Dropping unhandled LLWearInventoryCategoryCallback" << llendl;
+ onFailure();
}
}
+
+ void onFailure()
+ {
+ llinfos << "failed" << llendl;
+ mOnFailureFunc();
+ }
-private:
- LLUUID mCatID;
- bool mAppend;
-};
+ void onCompletion()
+ {
+ llinfos << "done" << llendl;
+ mOnCompletionFunc();
+ }
+
+ // virtual
+ // Will be deleted after returning true - only safe to do this if all callbacks have fired.
+ BOOL tick()
+ {
+ // mPendingRequests will be zero if all requests have been
+ // responded to. mWaitTimes.empty() will be true if we have
+ // received at least one reply for each UUID. If requests
+ // have been dropped and retried, these will not necessarily
+ // be the same. Only safe to return true if all requests have
+ // been serviced, since it will result in this object being
+ // deleted.
+ bool all_done = (mPendingRequests==0);
+
+ if (!mWaitTimes.empty())
+ {
+ llwarns << "still waiting on " << mWaitTimes.size() << " items" << llendl;
+ for (std::map<LLUUID,LLTimer>::iterator it = mWaitTimes.begin();
+ it != mWaitTimes.end();)
+ {
+ // Use a copy of iterator because it may be erased/invalidated.
+ std::map<LLUUID,LLTimer>::iterator curr_it = it;
+ ++it;
+
+ F32 time_waited = curr_it->second.getElapsedTimeF32();
+ S32 retries = mRetryCounts[curr_it->first];
+ if (time_waited > mRetryAfter)
+ {
+ if (retries < mMaxRetries)
+ {
+ LL_DEBUGS("Avatar") << "Waited " << time_waited <<
+ " for " << curr_it->first << ", retrying" << llendl;
+ mRetryCount++;
+ addItem(curr_it->first);
+ }
+ else
+ {
+ llwarns << "Giving up on " << curr_it->first << " after too many retries" << llendl;
+ mWaitTimes.erase(curr_it);
+ mFailCount++;
+ }
+ }
+ if (mWaitTimes.empty())
+ {
+ onCompletionOrFailure();
+ }
+
+ }
+ }
+ return all_done;
+ }
+
+ void reportStats()
+ {
+ LL_DEBUGS("Avatar") << "Phase: " << mTrackingPhase << llendl;
+ LL_DEBUGS("Avatar") << "mFailCount: " << mFailCount << llendl;
+ LL_DEBUGS("Avatar") << "mRetryCount: " << mRetryCount << llendl;
+ LL_DEBUGS("Avatar") << "Times: n " << mTimeStats.getCount() << " min " << mTimeStats.getMinValue() << " max " << mTimeStats.getMaxValue() << llendl;
+ LL_DEBUGS("Avatar") << "Mean " << mTimeStats.getMean() << " stddev " << mTimeStats.getStdDev() << llendl;
+ }
+ virtual ~LLCallAfterInventoryBatchMgr()
+ {
+ LL_DEBUGS("Avatar") << "deleting" << llendl;
+ }
+
+protected:
+ std::string mTrackingPhase;
+ std::map<LLUUID,LLTimer> mWaitTimes;
+ std::map<LLUUID,S32> mRetryCounts;
+ LLUUID mDstCatID;
+ nullary_func_t mOnCompletionFunc;
+ nullary_func_t mOnFailureFunc;
+ F32 mRetryAfter;
+ S32 mMaxRetries;
+ S32 mPendingRequests;
+ S32 mFailCount;
+ S32 mRetryCount;
+ bool mCompletionOrFailureCalled;
+ LLViewerStats::StatsAccumulator mTimeStats;
+};
-//Inventory callback updating "dirty" state when destroyed
-class LLUpdateDirtyState: public LLInventoryCallback
+class LLCallAfterInventoryCopyMgr: public LLCallAfterInventoryBatchMgr
{
public:
- LLUpdateDirtyState() {}
- virtual ~LLUpdateDirtyState()
+ LLCallAfterInventoryCopyMgr(LLInventoryModel::item_array_t& src_items,
+ const LLUUID& dst_cat_id,
+ const std::string& phase_name,
+ nullary_func_t on_completion_func,
+ nullary_func_t on_failure_func = no_op,
+ F32 retry_after = DEFAULT_RETRY_AFTER_INTERVAL,
+ S32 max_retries = DEFAULT_MAX_RETRIES
+ ):
+ LLCallAfterInventoryBatchMgr(dst_cat_id, phase_name, on_completion_func, on_failure_func, retry_after, max_retries)
{
- if (LLAppearanceMgr::instanceExists())
+ addItems(src_items);
+ }
+
+ virtual bool requestOperation(const LLUUID& item_id)
+ {
+ LLViewerInventoryItem *item = gInventory.getItem(item_id);
+ llassert(item);
+ LL_DEBUGS("Avatar") << "copying item " << item_id << llendl;
+ if (ll_frand() < gSavedSettings.getF32("InventoryDebugSimulateOpFailureRate"))
{
- LLAppearanceMgr::getInstance()->updateIsDirty();
+ LL_DEBUGS("Avatar") << "simulating failure by not sending request for item " << item_id << llendl;
+ return true;
}
+ copy_inventory_item(
+ gAgent.getID(),
+ item->getPermissions().getOwner(),
+ item->getUUID(),
+ mDstCatID,
+ std::string(),
+ new LLBoostFuncInventoryCallback(boost::bind(&LLCallAfterInventoryBatchMgr::onOp,this,item_id,_1,LLTimer()))
+ );
+ return true;
}
- virtual void fire(const LLUUID&) {}
};
+class LLCallAfterInventoryLinkMgr: public LLCallAfterInventoryBatchMgr
+{
+public:
+ LLCallAfterInventoryLinkMgr(LLInventoryModel::item_array_t& src_items,
+ const LLUUID& dst_cat_id,
+ const std::string& phase_name,
+ nullary_func_t on_completion_func,
+ nullary_func_t on_failure_func = no_op,
+ F32 retry_after = DEFAULT_RETRY_AFTER_INTERVAL,
+ S32 max_retries = DEFAULT_MAX_RETRIES
+ ):
+ LLCallAfterInventoryBatchMgr(dst_cat_id, phase_name, on_completion_func, on_failure_func, retry_after, max_retries)
+ {
+ addItems(src_items);
+ }
+
+ virtual bool requestOperation(const LLUUID& item_id)
+ {
+ bool request_sent = false;
+ LLViewerInventoryItem *item = gInventory.getItem(item_id);
+ if (item)
+ {
+ if (item->getParentUUID() == mDstCatID)
+ {
+ LL_DEBUGS("Avatar") << "item " << item_id << " name " << item->getName() << " is already a child of " << mDstCatID << llendl;
+ return false;
+ }
+ LL_DEBUGS("Avatar") << "linking item " << item_id << " name " << item->getName() << " to " << mDstCatID << llendl;
+ // create an inventory item link.
+ if (ll_frand() < gSavedSettings.getF32("InventoryDebugSimulateOpFailureRate"))
+ {
+ LL_DEBUGS("Avatar") << "simulating failure by not sending request for item " << item_id << llendl;
+ return true;
+ }
+ link_inventory_item(gAgent.getID(),
+ item->getLinkedUUID(),
+ mDstCatID,
+ item->getName(),
+ item->getActualDescription(),
+ LLAssetType::AT_LINK,
+ new LLBoostFuncInventoryCallback(
+ boost::bind(&LLCallAfterInventoryBatchMgr::onOp,this,item_id,_1,LLTimer())));
+ return true;
+ }
+ else
+ {
+ // create a base outfit link if appropriate.
+ LLViewerInventoryCategory *catp = gInventory.getCategory(item_id);
+ if (!catp)
+ {
+ llwarns << "link request failed, id not found as inventory item or category " << item_id << llendl;
+ return false;
+ }
+ const LLUUID cof = LLAppearanceMgr::instance().getCOF();
+ std::string new_outfit_name = "";
+
+ LLAppearanceMgr::instance().purgeBaseOutfitLink(cof);
+
+ if (catp && catp->getPreferredType() == LLFolderType::FT_OUTFIT)
+ {
+ if (ll_frand() < gSavedSettings.getF32("InventoryDebugSimulateOpFailureRate"))
+ {
+ LL_DEBUGS("Avatar") << "simulating failure by not sending request for item " << item_id << llendl;
+ return true;
+ }
+ LL_DEBUGS("Avatar") << "linking folder " << item_id << " name " << catp->getName() << " to cof " << cof << llendl;
+ link_inventory_item(gAgent.getID(), item_id, cof, catp->getName(), "",
+ LLAssetType::AT_LINK_FOLDER,
+ new LLBoostFuncInventoryCallback(
+ boost::bind(&LLCallAfterInventoryBatchMgr::onOp,this,item_id,_1,LLTimer())));
+ new_outfit_name = catp->getName();
+ request_sent = true;
+ }
+
+ LLAppearanceMgr::instance().updatePanelOutfitName(new_outfit_name);
+ }
+ return request_sent;
+ }
+};
LLUpdateAppearanceOnDestroy::LLUpdateAppearanceOnDestroy(bool update_base_outfit_ordering):
mFireCount(0),
mUpdateBaseOrder(update_base_outfit_ordering)
{
+ selfStartPhase("update_appearance_on_destroy");
}
LLUpdateAppearanceOnDestroy::~LLUpdateAppearanceOnDestroy()
{
- llinfos << "done update appearance on destroy" << llendl;
-
if (!LLApp::isExiting())
{
+ // speculative fix for MAINT-1150
+ LL_INFOS("Avatar") << self_av_string() << "done update appearance on destroy" << LL_ENDL;
+
+ selfStopPhase("update_appearance_on_destroy");
+
LLAppearanceMgr::instance().updateAppearanceFromCOF(mUpdateBaseOrder);
}
}
@@ -229,7 +525,7 @@ void LLUpdateAppearanceOnDestroy::fire(const LLUUID& inv_item)
LLViewerInventoryItem* item = (LLViewerInventoryItem*)gInventory.getItem(inv_item);
const std::string item_name = item ? item->getName() : "ITEM NOT FOUND";
#ifndef LL_RELEASE_FOR_DOWNLOAD
- llinfos << "callback fired [ name:" << item_name << " UUID:" << inv_item << " count:" << mFireCount << " ] " << llendl;
+ LL_DEBUGS("Avatar") << self_av_string() << "callback fired [ name:" << item_name << " UUID:" << inv_item << " count:" << mFireCount << " ] " << LL_ENDL;
#endif
mFireCount++;
}
@@ -261,7 +557,7 @@ struct LLFoundData
std::string mName;
LLAssetType::EType mAssetType;
LLWearableType::EType mWearableType;
- LLWearable* mWearable;
+ LLViewerWearable* mWearable;
bool mIsReplacement;
};
@@ -285,7 +581,7 @@ public:
void recoverMissingWearable(LLWearableType::EType type);
void clearCOFLinksForMissingWearables();
- void onWearableAssetFetch(LLWearable *wearable);
+ void onWearableAssetFetch(LLViewerWearable *wearable);
void onAllComplete();
typedef std::list<LLFoundData> found_list_t;
@@ -311,7 +607,7 @@ private:
typedef std::set<LLWearableHoldingPattern*> type_set_hp;
static type_set_hp sActiveHoldingPatterns;
bool mIsMostRecent;
- std::set<LLWearable*> mLateArrivals;
+ std::set<LLViewerWearable*> mLateArrivals;
bool mIsAllComplete;
};
@@ -339,11 +635,16 @@ LLWearableHoldingPattern::LLWearableHoldingPattern():
}
sActiveHoldingPatterns.insert(this);
+ selfStartPhase("holding_pattern");
}
LLWearableHoldingPattern::~LLWearableHoldingPattern()
{
sActiveHoldingPatterns.erase(this);
+ if (isMostRecent())
+ {
+ selfStopPhase("holding_pattern");
+ }
}
bool LLWearableHoldingPattern::isMostRecent()
@@ -390,9 +691,10 @@ void LLWearableHoldingPattern::checkMissingWearables()
{
if (!isMostRecent())
{
- llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl;
+ // runway why don't we actually skip here?
+ llwarns << self_av_string() << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl;
}
-
+
std::vector<S32> found_by_type(LLWearableType::WT_COUNT,0);
std::vector<S32> requested_by_type(LLWearableType::WT_COUNT,0);
for (found_list_t::iterator it = getFoundList().begin(); it != getFoundList().end(); ++it)
@@ -408,7 +710,7 @@ void LLWearableHoldingPattern::checkMissingWearables()
{
if (requested_by_type[type] > found_by_type[type])
{
- llwarns << "got fewer wearables than requested, type " << type << ": requested " << requested_by_type[type] << ", found " << found_by_type[type] << llendl;
+ llwarns << self_av_string() << "got fewer wearables than requested, type " << type << ": requested " << requested_by_type[type] << ", found " << found_by_type[type] << llendl;
}
if (found_by_type[type] > 0)
continue;
@@ -425,11 +727,13 @@ void LLWearableHoldingPattern::checkMissingWearables()
mTypesToRecover.insert(type);
mTypesToLink.insert(type);
recoverMissingWearable((LLWearableType::EType)type);
- llwarns << "need to replace " << type << llendl;
+ llwarns << self_av_string() << "need to replace " << type << llendl;
}
}
resetTime(60.0F);
+
+ selfStartPhase("get_missing_wearables");
if (!pollMissingWearables())
{
doOnIdleRepeating(boost::bind(&LLWearableHoldingPattern::pollMissingWearables,this));
@@ -445,13 +749,14 @@ void LLWearableHoldingPattern::onAllComplete()
if (!isMostRecent())
{
- llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl;
+ // runway need to skip here?
+ llwarns << self_av_string() << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl;
}
// Activate all gestures in this folder
if (mGestItems.count() > 0)
{
- llinfos << "Activating " << mGestItems.count() << " gestures" << llendl;
+ LL_DEBUGS("Avatar") << self_av_string() << "Activating " << mGestItems.count() << " gestures" << LL_ENDL;
LLGestureMgr::instance().activateGestures(mGestItems);
@@ -468,13 +773,13 @@ void LLWearableHoldingPattern::onAllComplete()
}
// Update wearables.
- llinfos << "Updating agent wearables with " << mResolved << " wearable items " << llendl;
+ LL_INFOS("Avatar") << self_av_string() << "Updating agent wearables with " << mResolved << " wearable items " << LL_ENDL;
LLAppearanceMgr::instance().updateAgentWearables(this, false);
// Update attachments to match those requested.
if (isAgentAvatarValid())
{
- llinfos << "Updating " << mObjItems.count() << " attachments" << llendl;
+ LL_DEBUGS("Avatar") << self_av_string() << "Updating " << mObjItems.count() << " attachments" << LL_ENDL;
LLAgentWearables::userUpdateAttachments(mObjItems);
}
@@ -492,9 +797,12 @@ void LLWearableHoldingPattern::onAllComplete()
void LLWearableHoldingPattern::onFetchCompletion()
{
+ selfStopPhase("get_wearables");
+
if (!isMostRecent())
{
- llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl;
+ // runway skip here?
+ llwarns << self_av_string() << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl;
}
checkMissingWearables();
@@ -505,7 +813,8 @@ bool LLWearableHoldingPattern::pollFetchCompletion()
{
if (!isMostRecent())
{
- llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl;
+ // runway skip here?
+ llwarns << self_av_string() << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl;
}
bool completed = isFetchCompleted();
@@ -514,14 +823,14 @@ bool LLWearableHoldingPattern::pollFetchCompletion()
if (done)
{
- llinfos << "polling, done status: " << completed << " timed out " << timed_out
- << " elapsed " << mWaitTime.getElapsedTimeF32() << llendl;
+ LL_INFOS("Avatar") << self_av_string() << "polling, done status: " << completed << " timed out " << timed_out
+ << " elapsed " << mWaitTime.getElapsedTimeF32() << LL_ENDL;
mFired = true;
if (timed_out)
{
- llwarns << "Exceeded max wait time for wearables, updating appearance based on what has arrived" << llendl;
+ llwarns << self_av_string() << "Exceeded max wait time for wearables, updating appearance based on what has arrived" << llendl;
}
onFetchCompletion();
@@ -529,24 +838,16 @@ bool LLWearableHoldingPattern::pollFetchCompletion()
return done;
}
-class RecoveredItemLinkCB: public LLInventoryCallback
+void recovered_item_link_cb(const LLUUID& item_id, LLWearableType::EType type, LLViewerWearable *wearable, LLWearableHoldingPattern* holder)
{
-public:
- RecoveredItemLinkCB(LLWearableType::EType type, LLWearable *wearable, LLWearableHoldingPattern* holder):
- mHolder(holder),
- mWearable(wearable),
- mType(type)
- {
- }
- void fire(const LLUUID& item_id)
- {
- if (!mHolder->isMostRecent())
+ if (!holder->isMostRecent())
{
llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl;
+ // runway skip here?
}
- llinfos << "Recovered item link for type " << mType << llendl;
- mHolder->eraseTypeToLink(mType);
+ llinfos << "Recovered item link for type " << type << llendl;
+ holder->eraseTypeToLink(type);
// Add wearable to FoundData for actual wearing
LLViewerInventoryItem *item = gInventory.getItem(item_id);
LLViewerInventoryItem *linked_item = item ? item->getLinkedItem() : NULL;
@@ -564,46 +865,33 @@ public:
linked_item->isWearableType() ? linked_item->getWearableType() : LLWearableType::WT_INVALID,
true // is replacement
);
- found.mWearable = mWearable;
- mHolder->getFoundList().push_front(found);
+ found.mWearable = wearable;
+ holder->getFoundList().push_front(found);
}
else
{
- llwarns << "inventory item not found for recovered wearable" << llendl;
+ llwarns << self_av_string() << "inventory item not found for recovered wearable" << llendl;
}
}
else
{
- llwarns << "inventory link not found for recovered wearable" << llendl;
+ llwarns << self_av_string() << "inventory link not found for recovered wearable" << llendl;
}
}
-private:
- LLWearableHoldingPattern* mHolder;
- LLWearable *mWearable;
- LLWearableType::EType mType;
-};
-class RecoveredItemCB: public LLInventoryCallback
+void recovered_item_cb(const LLUUID& item_id, LLWearableType::EType type, LLViewerWearable *wearable, LLWearableHoldingPattern* holder)
{
-public:
- RecoveredItemCB(LLWearableType::EType type, LLWearable *wearable, LLWearableHoldingPattern* holder):
- mHolder(holder),
- mWearable(wearable),
- mType(type)
- {
- }
- void fire(const LLUUID& item_id)
- {
- if (!mHolder->isMostRecent())
+ if (!holder->isMostRecent())
{
- llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl;
+ // runway skip here?
+ llwarns << self_av_string() << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl;
}
- llinfos << "Recovered item for type " << mType << llendl;
+ LL_DEBUGS("Avatar") << self_av_string() << "Recovered item for type " << type << LL_ENDL;
LLViewerInventoryItem *itemp = gInventory.getItem(item_id);
- mWearable->setItemID(item_id);
- LLPointer<LLInventoryCallback> cb = new RecoveredItemLinkCB(mType,mWearable,mHolder);
- mHolder->eraseTypeToRecover(mType);
+ wearable->setItemID(item_id);
+ LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(recovered_item_link_cb,_1,type,wearable,holder));
+ holder->eraseTypeToRecover(type);
llassert(itemp);
if (itemp)
{
@@ -616,28 +904,24 @@ public:
cb);
}
}
-private:
- LLWearableHoldingPattern* mHolder;
- LLWearable *mWearable;
- LLWearableType::EType mType;
-};
void LLWearableHoldingPattern::recoverMissingWearable(LLWearableType::EType type)
{
if (!isMostRecent())
{
- llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl;
+ // runway skip here?
+ llwarns << self_av_string() << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl;
}
// Try to recover by replacing missing wearable with a new one.
LLNotificationsUtil::add("ReplacedMissingWearable");
lldebugs << "Wearable " << LLWearableType::getTypeLabel(type)
<< " could not be downloaded. Replaced inventory item with default wearable." << llendl;
- LLWearable* wearable = LLWearableList::instance().createNewWearable(type);
+ LLViewerWearable* wearable = LLWearableList::instance().createNewWearable(type, gAgentAvatarp);
// Add a new one in the lost and found folder.
const LLUUID lost_and_found_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND);
- LLPointer<LLInventoryCallback> cb = new RecoveredItemCB(type,wearable,this);
+ LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(recovered_item_cb,_1,type,wearable,this));
create_inventory_item(gAgent.getID(),
gAgent.getSessionID(),
@@ -665,8 +949,8 @@ void LLWearableHoldingPattern::clearCOFLinksForMissingWearables()
if ((data.mWearableType < LLWearableType::WT_COUNT) && (!data.mWearable))
{
// Wearable link that was never resolved; remove links to it from COF
- llinfos << "removing link for unresolved item " << data.mItemID.asString() << llendl;
- LLAppearanceMgr::instance().removeCOFItemLinks(data.mItemID,false);
+ LL_INFOS("Avatar") << self_av_string() << "removing link for unresolved item " << data.mItemID.asString() << LL_ENDL;
+ LLAppearanceMgr::instance().removeCOFItemLinks(data.mItemID);
}
}
}
@@ -675,7 +959,8 @@ bool LLWearableHoldingPattern::pollMissingWearables()
{
if (!isMostRecent())
{
- llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl;
+ // runway skip here?
+ llwarns << self_av_string() << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl;
}
bool timed_out = isTimedOut();
@@ -684,15 +969,17 @@ bool LLWearableHoldingPattern::pollMissingWearables()
if (!done)
{
- llinfos << "polling missing wearables, waiting for items " << mTypesToRecover.size()
+ LL_INFOS("Avatar") << self_av_string() << "polling missing wearables, waiting for items " << mTypesToRecover.size()
<< " links " << mTypesToLink.size()
<< " wearables, timed out " << timed_out
<< " elapsed " << mWaitTime.getElapsedTimeF32()
- << " done " << done << llendl;
+ << " done " << done << LL_ENDL;
}
if (done)
{
+ selfStopPhase("get_missing_wearables");
+
gAgentAvatarp->debugWearablesLoaded();
// BAP - if we don't call clearCOFLinksForMissingWearables()
@@ -722,14 +1009,14 @@ void LLWearableHoldingPattern::handleLateArrivals()
}
if (!isMostRecent())
{
- llwarns << "Late arrivals not handled - outfit change no longer valid" << llendl;
+ llwarns << self_av_string() << "Late arrivals not handled - outfit change no longer valid" << llendl;
}
if (!mIsAllComplete)
{
- llwarns << "Late arrivals not handled - in middle of missing wearables processing" << llendl;
+ llwarns << self_av_string() << "Late arrivals not handled - in middle of missing wearables processing" << llendl;
}
- llinfos << "Need to handle " << mLateArrivals.size() << " late arriving wearables" << llendl;
+ LL_INFOS("Avatar") << self_av_string() << "Need to handle " << mLateArrivals.size() << " late arriving wearables" << LL_ENDL;
// Update mFoundList using late-arriving wearables.
std::set<LLWearableType::EType> replaced_types;
@@ -737,11 +1024,11 @@ void LLWearableHoldingPattern::handleLateArrivals()
iter != getFoundList().end(); ++iter)
{
LLFoundData& data = *iter;
- for (std::set<LLWearable*>::iterator wear_it = mLateArrivals.begin();
+ for (std::set<LLViewerWearable*>::iterator wear_it = mLateArrivals.begin();
wear_it != mLateArrivals.end();
++wear_it)
{
- LLWearable *wearable = *wear_it;
+ LLViewerWearable *wearable = *wear_it;
if(wearable->getAssetID() == data.mAssetID)
{
@@ -777,7 +1064,7 @@ void LLWearableHoldingPattern::handleLateArrivals()
if (data.mWearable && data.mIsReplacement &&
replaced_types.find(data.mWearableType) != replaced_types.end())
{
- LLAppearanceMgr::instance().removeCOFItemLinks(data.mItemID,false);
+ LLAppearanceMgr::instance().removeCOFItemLinks(data.mItemID);
std::list<LLFoundData>::iterator clobber_ator = iter;
++iter;
getFoundList().erase(clobber_ator);
@@ -801,23 +1088,23 @@ void LLWearableHoldingPattern::resetTime(F32 timeout)
mWaitTime.setTimerExpirySec(timeout);
}
-void LLWearableHoldingPattern::onWearableAssetFetch(LLWearable *wearable)
+void LLWearableHoldingPattern::onWearableAssetFetch(LLViewerWearable *wearable)
{
if (!isMostRecent())
{
- llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl;
+ llwarns << self_av_string() << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl;
}
mResolved += 1; // just counting callbacks, not successes.
- llinfos << "resolved " << mResolved << "/" << getFoundList().size() << llendl;
+ LL_DEBUGS("Avatar") << self_av_string() << "resolved " << mResolved << "/" << getFoundList().size() << LL_ENDL;
if (!wearable)
{
- llwarns << "no wearable found" << llendl;
+ llwarns << self_av_string() << "no wearable found" << llendl;
}
if (mFired)
{
- llwarns << "called after holder fired" << llendl;
+ llwarns << self_av_string() << "called after holder fired" << llendl;
if (wearable)
{
mLateArrivals.insert(wearable);
@@ -843,7 +1130,7 @@ void LLWearableHoldingPattern::onWearableAssetFetch(LLWearable *wearable)
// Failing this means inventory or asset server are corrupted in a way we don't handle.
if ((data.mWearableType >= LLWearableType::WT_COUNT) || (wearable->getType() != data.mWearableType))
{
- llwarns << "recovered wearable but type invalid. inventory wearable type: " << data.mWearableType << " asset wearable type: " << wearable->getType() << llendl;
+ llwarns << self_av_string() << "recovered wearable but type invalid. inventory wearable type: " << data.mWearableType << " asset wearable type: " << wearable->getType() << llendl;
break;
}
@@ -852,7 +1139,7 @@ void LLWearableHoldingPattern::onWearableAssetFetch(LLWearable *wearable)
}
}
-static void onWearableAssetFetch(LLWearable* wearable, void* data)
+static void onWearableAssetFetch(LLViewerWearable* wearable, void* data)
{
LLWearableHoldingPattern* holder = (LLWearableHoldingPattern*)data;
holder->onWearableAssetFetch(wearable);
@@ -891,6 +1178,18 @@ const LLUUID LLAppearanceMgr::getCOF() const
return gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT);
}
+S32 LLAppearanceMgr::getCOFVersion() const
+{
+ LLViewerInventoryCategory *cof = gInventory.getCategory(getCOF());
+ if (cof)
+ {
+ return cof->getVersion();
+ }
+ else
+ {
+ return LLViewerInventoryCategory::VERSION_UNKNOWN;
+ }
+}
const LLViewerInventoryItem* LLAppearanceMgr::getBaseOutfitLink()
{
@@ -959,6 +1258,18 @@ const LLUUID LLAppearanceMgr::getBaseOutfitUUID()
return outfit_cat->getUUID();
}
+void wear_on_avatar_cb(const LLUUID& inv_item, bool do_replace = false)
+{
+ if (inv_item.isNull())
+ return;
+
+ LLViewerInventoryItem *item = gInventory.getItem(inv_item);
+ if (item)
+ {
+ LLAppearanceMgr::instance().wearItemOnAvatar(inv_item, true, do_replace);
+ }
+}
+
bool LLAppearanceMgr::wearItemOnAvatar(const LLUUID& item_id_to_wear, bool do_update, bool replace, LLPointer<LLInventoryCallback> cb)
{
if (item_id_to_wear.isNull()) return false;
@@ -978,7 +1289,7 @@ bool LLAppearanceMgr::wearItemOnAvatar(const LLUUID& item_id_to_wear, bool do_up
if (gInventory.isObjectDescendentOf(item_to_wear->getUUID(), gInventory.getLibraryRootFolderID()))
{
- LLPointer<LLInventoryCallback> cb = new WearOnAvatarCallback(replace);
+ LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(wear_on_avatar_cb,_1,replace));
copy_inventory_item(gAgent.getID(), item_to_wear->getPermissions().getOwner(), item_to_wear->getUUID(), LLUUID::null, std::string(),cb);
return false;
}
@@ -1005,7 +1316,7 @@ bool LLAppearanceMgr::wearItemOnAvatar(const LLUUID& item_id_to_wear, bool do_up
if ((replace && wearable_count != 0) ||
(wearable_count >= LLAgentWearables::MAX_CLOTHING_PER_TYPE) )
{
- removeCOFItemLinks(gAgentWearables.getWearableItemID(item_to_wear->getWearableType(), wearable_count-1), false);
+ removeCOFItemLinks(gAgentWearables.getWearableItemID(item_to_wear->getWearableType(), wearable_count-1));
}
addCOFItemLink(item_to_wear, do_update, cb);
}
@@ -1015,7 +1326,7 @@ bool LLAppearanceMgr::wearItemOnAvatar(const LLUUID& item_id_to_wear, bool do_up
// Remove the existing wearables of the same type.
// Remove existing body parts anyway because we must not be able to wear e.g. two skins.
- removeCOFLinksOfType(item_to_wear->getWearableType(), false);
+ removeCOFLinksOfType(item_to_wear->getWearableType());
addCOFItemLink(item_to_wear, do_update, cb);
break;
@@ -1113,11 +1424,13 @@ void LLAppearanceMgr::takeOffOutfit(const LLUUID& cat_id)
LLInventoryModel::item_array_t::const_iterator it = items.begin();
const LLInventoryModel::item_array_t::const_iterator it_end = items.end();
+ uuid_vec_t uuids_to_remove;
for( ; it_end != it; ++it)
{
LLViewerInventoryItem* item = *it;
- removeItemFromAvatar(item->getUUID());
+ uuids_to_remove.push_back(item->getUUID());
}
+ removeItemsFromAvatar(uuids_to_remove);
}
// Create a copy of src_id + contents as a subfolder of dst_id.
@@ -1161,13 +1474,13 @@ void LLAppearanceMgr::shallowCopyCategoryContents(const LLUUID& src_id, const LL
{
case LLAssetType::AT_LINK:
{
- //LLInventoryItem::getDescription() is used for a new description
+ //getActualDescription() is used for a new description
//to propagate ordering information saved in descriptions of links
link_inventory_item(gAgent.getID(),
item->getLinkedUUID(),
dst_id,
item->getName(),
- item->LLInventoryItem::getDescription(),
+ item->getActualDescription(),
LLAssetType::AT_LINK, cb);
break;
}
@@ -1347,7 +1660,7 @@ void LLAppearanceMgr::purgeBaseOutfitLink(const LLUUID& category)
}
}
-void LLAppearanceMgr::purgeCategory(const LLUUID& category, bool keep_outfit_links)
+void LLAppearanceMgr::purgeCategory(const LLUUID& category, bool keep_outfit_links, LLInventoryModel::item_array_t* keep_items)
{
LLInventoryModel::cat_array_t cats;
LLInventoryModel::item_array_t items;
@@ -1360,8 +1673,19 @@ void LLAppearanceMgr::purgeCategory(const LLUUID& category, bool keep_outfit_lin
continue;
if (item->getIsLinkType())
{
+#if 0
+ if (keep_items && keep_items->find(item) != LLInventoryModel::item_array_t::FAIL)
+ {
+ llinfos << "preserved item" << llendl;
+ }
+ else
+ {
+ gInventory.purgeObject(item->getUUID());
+ }
+#else
gInventory.purgeObject(item->getUUID());
}
+#endif
}
}
@@ -1391,8 +1715,8 @@ void LLAppearanceMgr::filterWearableItems(
// Create links to all listed items.
void LLAppearanceMgr::linkAll(const LLUUID& cat_uuid,
- LLInventoryModel::item_array_t& items,
- LLPointer<LLInventoryCallback> cb)
+ LLInventoryModel::item_array_t& items,
+ LLPointer<LLInventoryCallback> cb)
{
for (S32 i=0; i<items.count(); i++)
{
@@ -1401,14 +1725,14 @@ void LLAppearanceMgr::linkAll(const LLUUID& cat_uuid,
item->getLinkedUUID(),
cat_uuid,
item->getName(),
- item->LLInventoryItem::getDescription(),
+ item->getActualDescription(),
LLAssetType::AT_LINK,
cb);
const LLViewerInventoryCategory *cat = gInventory.getCategory(cat_uuid);
const std::string cat_name = cat ? cat->getName() : "CAT NOT FOUND";
#ifndef LL_RELEASE_FOR_DOWNLOAD
- llinfos << "Linking Item [ name:" << item->getName() << " UUID:" << item->getUUID() << " ] to Category [ name:" << cat_name << " UUID:" << cat_uuid << " ] " << llendl;
+ LL_DEBUGS("Avatar") << self_av_string() << "Linking Item [ name:" << item->getName() << " UUID:" << item->getUUID() << " ] to Category [ name:" << cat_name << " UUID:" << cat_uuid << " ] " << LL_ENDL;
#endif
}
}
@@ -1416,7 +1740,7 @@ void LLAppearanceMgr::linkAll(const LLUUID& cat_uuid,
void LLAppearanceMgr::updateCOF(const LLUUID& category, bool append)
{
LLViewerInventoryCategory *pcat = gInventory.getCategory(category);
- llinfos << "starting, cat " << (pcat ? pcat->getName() : "[UNKNOWN]") << llendl;
+ LL_INFOS("Avatar") << self_av_string() << "starting, cat '" << (pcat ? pcat->getName() : "[UNKNOWN]") << "'" << LL_ENDL;
const LLUUID cof = getCOF();
@@ -1472,41 +1796,32 @@ void LLAppearanceMgr::updateCOF(const LLUUID& category, bool append)
getDescendentsOfAssetType(category, gest_items, LLAssetType::AT_GESTURE, false);
removeDuplicateItems(gest_items);
- // Remove current COF contents.
- bool keep_outfit_links = append;
- purgeCategory(cof, keep_outfit_links);
- gInventory.notifyObservers();
-
// Create links to new COF contents.
- llinfos << "creating LLUpdateAppearanceOnDestroy" << llendl;
- LLPointer<LLInventoryCallback> link_waiter = new LLUpdateAppearanceOnDestroy(!append);
+ LLInventoryModel::item_array_t all_items;
+ all_items += body_items;
+ all_items += wear_items;
+ all_items += obj_items;
+ all_items += gest_items;
-#ifndef LL_RELEASE_FOR_DOWNLOAD
- llinfos << "Linking body items" << llendl;
-#endif
- linkAll(cof, body_items, link_waiter);
-
-#ifndef LL_RELEASE_FOR_DOWNLOAD
- llinfos << "Linking wear items" << llendl;
-#endif
- linkAll(cof, wear_items, link_waiter);
-
-#ifndef LL_RELEASE_FOR_DOWNLOAD
- llinfos << "Linking obj items" << llendl;
-#endif
- linkAll(cof, obj_items, link_waiter);
-
-#ifndef LL_RELEASE_FOR_DOWNLOAD
- llinfos << "Linking gesture items" << llendl;
-#endif
- linkAll(cof, gest_items, link_waiter);
+ // Will link all the above items.
+ LLPointer<LLInventoryCallback> link_waiter = new LLUpdateAppearanceOnDestroy;
+ linkAll(cof,all_items,link_waiter);
// Add link to outfit if category is an outfit.
if (!append)
{
createBaseOutfitLink(category, link_waiter);
}
- llinfos << "waiting for LLUpdateAppearanceOnDestroy" << llendl;
+
+ // Remove current COF contents. Have to do this after creating
+ // the link_waiter so links can be followed for any items that get
+ // carried over (e.g. keeping old shape if the new outfit does not
+ // contain one)
+ bool keep_outfit_links = append;
+ purgeCategory(cof, keep_outfit_links, &all_items);
+ gInventory.notifyObservers();
+
+ LL_DEBUGS("Avatar") << self_av_string() << "waiting for LLUpdateAppearanceOnDestroy" << LL_ENDL;
}
void LLAppearanceMgr::updatePanelOutfitName(const std::string& name)
@@ -1541,7 +1856,7 @@ void LLAppearanceMgr::updateAgentWearables(LLWearableHoldingPattern* holder, boo
{
lldebugs << "updateAgentWearables()" << llendl;
LLInventoryItem::item_array_t items;
- LLDynamicArray< LLWearable* > wearables;
+ LLDynamicArray< LLViewerWearable* > wearables;
// For each wearable type, find the wearables of that type.
for( S32 i = 0; i < LLWearableType::WT_COUNT; i++ )
@@ -1550,7 +1865,7 @@ void LLAppearanceMgr::updateAgentWearables(LLWearableHoldingPattern* holder, boo
iter != holder->getFoundList().end(); ++iter)
{
LLFoundData& data = *iter;
- LLWearable* wearable = data.mWearable;
+ LLViewerWearable* wearable = data.mWearable;
if( wearable && ((S32)wearable->getType() == i) )
{
LLViewerInventoryItem* item = (LLViewerInventoryItem*)gInventory.getItem(data.mItemID);
@@ -1567,8 +1882,6 @@ void LLAppearanceMgr::updateAgentWearables(LLWearableHoldingPattern* holder, boo
{
gAgentWearables.setWearableOutfit(items, wearables, !append);
}
-
-// dec_busy_count();
}
static void remove_non_link_items(LLInventoryModel::item_array_t &items)
@@ -1588,7 +1901,7 @@ static void remove_non_link_items(LLInventoryModel::item_array_t &items)
}
//a predicate for sorting inventory items by actual descriptions
-bool sort_by_description(const LLInventoryItem* item1, const LLInventoryItem* item2)
+bool sort_by_actual_description(const LLInventoryItem* item1, const LLInventoryItem* item2)
{
if (!item1 || !item2)
{
@@ -1596,7 +1909,7 @@ bool sort_by_description(const LLInventoryItem* item1, const LLInventoryItem* it
return true;
}
- return item1->LLInventoryItem::getDescription() < item2->LLInventoryItem::getDescription();
+ return item1->getActualDescription() < item2->getActualDescription();
}
void item_array_diff(LLInventoryModel::item_array_t& full_list,
@@ -1663,7 +1976,7 @@ void LLAppearanceMgr::enforceItemRestrictions()
++it)
{
LLViewerInventoryItem *item = *it;
- llinfos << "purging duplicate or excess item " << item->getName() << llendl;
+ LL_DEBUGS("Avatar") << self_av_string() << "purging duplicate or excess item " << item->getName() << LL_ENDL;
gInventory.purgeObject(item->getUUID());
}
gInventory.notifyObservers();
@@ -1679,8 +1992,9 @@ void LLAppearanceMgr::updateAppearanceFromCOF(bool update_base_outfit_ordering)
}
BoolSetter setIsInUpdateAppearanceFromCOF(mIsInUpdateAppearanceFromCOF);
+ selfStartPhase("update_appearance_from_cof");
- llinfos << "starting" << llendl;
+ LL_DEBUGS("Avatar") << self_av_string() << "starting" << LL_ENDL;
//checking integrity of the COF in terms of ordering of wearables,
//checking and updating links' descriptions of wearables in the COF (before analyzed for "dirty" state)
@@ -1694,9 +2008,18 @@ void LLAppearanceMgr::updateAppearanceFromCOF(bool update_base_outfit_ordering)
// the saved outfit stored as a folder link
updateIsDirty();
+ // Send server request for appearance update
+ if (gAgent.getRegion() && gAgent.getRegion()->getCentralBakeVersion())
+ {
+ requestServerAppearanceUpdate();
+ }
+ // DRANO really should wait for the appearance message to set this.
+ // verify that deleting this line doesn't break anything.
+ //gAgentAvatarp->setIsUsingServerBakes(gAgent.getRegion() && gAgent.getRegion()->getCentralBakeVersion());
+
//dumpCat(getCOF(),"COF, start");
- bool follow_folder_links = true;
+ bool follow_folder_links = false;
LLUUID current_outfit_id = getCOF();
// Find all the wearables that are in the COF's subtree.
@@ -1772,16 +2095,19 @@ void LLAppearanceMgr::updateAppearanceFromCOF(bool update_base_outfit_ordering)
}
}
+ selfStartPhase("get_wearables");
+
for (LLWearableHoldingPattern::found_list_t::iterator it = holder->getFoundList().begin();
it != holder->getFoundList().end(); ++it)
{
LLFoundData& found = *it;
- lldebugs << "waiting for onWearableAssetFetch callback, asset " << found.mAssetID.asString() << llendl;
+ lldebugs << self_av_string() << "waiting for onWearableAssetFetch callback, asset " << found.mAssetID.asString() << llendl;
// Fetch the wearables about to be worn.
LLWearableList::instance().getAsset(found.mAssetID,
found.mName,
+ gAgentAvatarp,
found.mAssetType,
onWearableAssetFetch,
(void*)holder);
@@ -1849,11 +2175,15 @@ void LLAppearanceMgr::wearInventoryCategory(LLInventoryCategory* category, bool
{
if(!category) return;
+ selfClearPhases();
+ selfStartPhase("wear_inventory_category");
+
gAgentWearables.notifyLoadingStarted();
- llinfos << "wearInventoryCategory( " << category->getName()
- << " )" << llendl;
+ LL_INFOS("Avatar") << self_av_string() << "wearInventoryCategory( " << category->getName()
+ << " )" << LL_ENDL;
+ selfStartPhase("wear_inventory_category_fetch");
callAfterCategoryFetch(category->getUUID(),boost::bind(&LLAppearanceMgr::wearCategoryFinal,
&LLAppearanceMgr::instance(),
category->getUUID(), copy, append));
@@ -1861,7 +2191,9 @@ void LLAppearanceMgr::wearInventoryCategory(LLInventoryCategory* category, bool
void LLAppearanceMgr::wearCategoryFinal(LLUUID& cat_id, bool copy_items, bool append)
{
- llinfos << "starting" << llendl;
+ LL_INFOS("Avatar") << self_av_string() << "starting" << LL_ENDL;
+
+ selfStopPhase("wear_inventory_category_fetch");
// We now have an outfit ready to be copied to agent inventory. Do
// it, and wear that outfit normally.
@@ -1910,22 +2242,15 @@ void LLAppearanceMgr::wearCategoryFinal(LLUUID& cat_id, bool copy_items, bool ap
pid,
LLFolderType::FT_NONE,
name);
- LLPointer<LLInventoryCallback> cb = new LLWearInventoryCategoryCallback(new_cat_id, append);
- it = items->begin();
- for(; it < end; ++it)
- {
- item = *it;
- if(item)
- {
- copy_inventory_item(
- gAgent.getID(),
- item->getPermissions().getOwner(),
- item->getUUID(),
- new_cat_id,
- std::string(),
- cb);
- }
- }
+
+ // Create a CopyMgr that will copy items, manage its own destruction
+ new LLCallAfterInventoryCopyMgr(
+ *items, new_cat_id, std::string("wear_inventory_category_callback"),
+ boost::bind(&LLAppearanceMgr::wearInventoryCategoryOnAvatar,
+ LLAppearanceMgr::getInstance(),
+ gInventory.getCategory(new_cat_id),
+ append));
+
// BAP fixes a lag in display of created dir.
gInventory.notifyObservers();
}
@@ -1944,8 +2269,14 @@ void LLAppearanceMgr::wearInventoryCategoryOnAvatar( LLInventoryCategory* catego
// wearables being dirty.
if(!category) return;
- llinfos << "wearInventoryCategoryOnAvatar( " << category->getName()
- << " )" << llendl;
+ if ( !LLInventoryCallbackManager::is_instantiated() )
+ {
+ // shutting down, ignore.
+ return;
+ }
+
+ LL_INFOS("Avatar") << self_av_string() << "wearInventoryCategoryOnAvatar '" << category->getName()
+ << "'" << LL_ENDL;
if (gAgentCamera.cameraCustomizeAvatar())
{
@@ -1958,8 +2289,7 @@ void LLAppearanceMgr::wearInventoryCategoryOnAvatar( LLInventoryCategory* catego
void LLAppearanceMgr::wearOutfitByName(const std::string& name)
{
- llinfos << "Wearing category " << name << llendl;
- //inc_busy_count();
+ LL_INFOS("Avatar") << self_av_string() << "Wearing category " << name << LL_ENDL;
LLInventoryModel::cat_array_t cat_array;
LLInventoryModel::item_array_t item_array;
@@ -1999,8 +2329,6 @@ void LLAppearanceMgr::wearOutfitByName(const std::string& name)
llwarns << "Couldn't find outfit " <<name<< " in wearOutfitByName()"
<< llendl;
}
-
- //dec_busy_count();
}
bool areMatchingWearables(const LLViewerInventoryItem *a, const LLViewerInventoryItem *b)
@@ -2012,10 +2340,11 @@ bool areMatchingWearables(const LLViewerInventoryItem *a, const LLViewerInventor
class LLDeferredCOFLinkObserver: public LLInventoryObserver
{
public:
- LLDeferredCOFLinkObserver(const LLUUID& item_id, bool do_update, LLPointer<LLInventoryCallback> cb = NULL):
+ LLDeferredCOFLinkObserver(const LLUUID& item_id, bool do_update, LLPointer<LLInventoryCallback> cb = NULL, std::string description = ""):
mItemID(item_id),
mDoUpdate(do_update),
- mCallback(cb)
+ mCallback(cb),
+ mDescription(description)
{
}
@@ -2037,28 +2366,49 @@ public:
private:
const LLUUID mItemID;
bool mDoUpdate;
+ std::string mDescription;
LLPointer<LLInventoryCallback> mCallback;
};
// BAP - note that this runs asynchronously if the item is not already loaded from inventory.
// Dangerous if caller assumes link will exist after calling the function.
-void LLAppearanceMgr::addCOFItemLink(const LLUUID &item_id, bool do_update, LLPointer<LLInventoryCallback> cb)
+void LLAppearanceMgr::addCOFItemLink(const LLUUID &item_id, bool do_update, LLPointer<LLInventoryCallback> cb, const std::string description)
{
const LLInventoryItem *item = gInventory.getItem(item_id);
if (!item)
{
- LLDeferredCOFLinkObserver *observer = new LLDeferredCOFLinkObserver(item_id, do_update, cb);
+ LLDeferredCOFLinkObserver *observer = new LLDeferredCOFLinkObserver(item_id, do_update, cb, description);
gInventory.addObserver(observer);
}
else
{
- addCOFItemLink(item, do_update, cb);
+ addCOFItemLink(item, do_update, cb, description);
}
}
-void LLAppearanceMgr::addCOFItemLink(const LLInventoryItem *item, bool do_update, LLPointer<LLInventoryCallback> cb)
+void modified_cof_cb(const LLUUID& inv_item)
{
+ LLAppearanceMgr::instance().updateAppearanceFromCOF();
+
+ // Start editing the item if previously requested.
+ gAgentWearables.editWearableIfRequested(inv_item);
+
+ // TODO: camera mode may not be changed if a debug setting is tweaked
+ if( gAgentCamera.cameraCustomizeAvatar() )
+ {
+ // If we're in appearance editing mode, the current tab may need to be refreshed
+ LLSidepanelAppearance *panel = dynamic_cast<LLSidepanelAppearance*>(LLFloaterSidePanelContainer::getPanel("appearance"));
+ if (panel)
+ {
+ panel->showDefaultSubpart();
+ }
+ }
+}
+
+void LLAppearanceMgr::addCOFItemLink(const LLInventoryItem *item, bool do_update, LLPointer<LLInventoryCallback> cb, const std::string description)
+{
+ std::string link_description = description;
const LLViewerInventoryItem *vitem = dynamic_cast<const LLViewerInventoryItem*>(item);
if (!vitem)
{
@@ -2120,37 +2470,106 @@ void LLAppearanceMgr::addCOFItemLink(const LLInventoryItem *item, bool do_update
{
if(do_update && cb.isNull())
{
- cb = new ModifiedCOFCallback;
+ cb = new LLBoostFuncInventoryCallback(modified_cof_cb);
+ }
+ if (vitem->getIsLinkType())
+ {
+ link_description = vitem->getActualDescription();
}
- const std::string description = vitem->getIsLinkType() ? vitem->getDescription() : "";
link_inventory_item( gAgent.getID(),
vitem->getLinkedUUID(),
getCOF(),
vitem->getName(),
- description,
+ link_description,
LLAssetType::AT_LINK,
cb);
}
return;
}
-// BAP remove ensemble code for 2.1?
-void LLAppearanceMgr::addEnsembleLink( LLInventoryCategory* cat, bool do_update )
+LLInventoryModel::item_array_t LLAppearanceMgr::findCOFItemLinks(const LLUUID& item_id)
{
-#if SUPPORT_ENSEMBLES
- // BAP add check for already in COF.
- LLPointer<LLInventoryCallback> cb = do_update ? new ModifiedCOFCallback : 0;
- link_inventory_item( gAgent.getID(),
- cat->getLinkedUUID(),
- getCOF(),
- cat->getName(),
- cat->getDescription(),
- LLAssetType::AT_LINK_FOLDER,
- cb);
-#endif
+
+ LLInventoryModel::item_array_t result;
+ const LLViewerInventoryItem *vitem =
+ dynamic_cast<const LLViewerInventoryItem*>(gInventory.getItem(item_id));
+
+ if (vitem)
+ {
+ LLInventoryModel::cat_array_t cat_array;
+ LLInventoryModel::item_array_t item_array;
+ gInventory.collectDescendents(LLAppearanceMgr::getCOF(),
+ cat_array,
+ item_array,
+ LLInventoryModel::EXCLUDE_TRASH);
+ for (S32 i=0; i<item_array.count(); i++)
+ {
+ const LLViewerInventoryItem* inv_item = item_array.get(i).get();
+ if (inv_item->getLinkedUUID() == vitem->getLinkedUUID())
+ {
+ result.put(item_array.get(i));
+ }
+ }
+ }
+ return result;
+}
+
+void LLAppearanceMgr::removeAllClothesFromAvatar()
+{
+ // Fetch worn clothes (i.e. the ones in COF).
+ LLInventoryModel::item_array_t clothing_items;
+ LLInventoryModel::cat_array_t dummy;
+ LLIsType is_clothing(LLAssetType::AT_CLOTHING);
+ gInventory.collectDescendentsIf(getCOF(),
+ dummy,
+ clothing_items,
+ LLInventoryModel::EXCLUDE_TRASH,
+ is_clothing,
+ false);
+ uuid_vec_t item_ids;
+ for (LLInventoryModel::item_array_t::iterator it = clothing_items.begin();
+ it != clothing_items.end(); ++it)
+ {
+ item_ids.push_back((*it).get()->getLinkedUUID());
+ }
+
+ // Take them off by removing from COF.
+ removeItemsFromAvatar(item_ids);
}
-void LLAppearanceMgr::removeCOFItemLinks(const LLUUID& item_id, bool do_update)
+void LLAppearanceMgr::removeAllAttachmentsFromAvatar()
+{
+ if (!isAgentAvatarValid()) return;
+
+ LLAgentWearables::llvo_vec_t objects_to_remove;
+
+ for (LLVOAvatar::attachment_map_t::iterator iter = gAgentAvatarp->mAttachmentPoints.begin();
+ iter != gAgentAvatarp->mAttachmentPoints.end();)
+ {
+ LLVOAvatar::attachment_map_t::iterator curiter = iter++;
+ LLViewerJointAttachment* attachment = curiter->second;
+ for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
+ attachment_iter != attachment->mAttachedObjects.end();
+ ++attachment_iter)
+ {
+ LLViewerObject *attached_object = (*attachment_iter);
+ if (attached_object)
+ {
+ objects_to_remove.push_back(attached_object);
+ }
+ }
+ }
+ uuid_vec_t ids_to_remove;
+ for (LLAgentWearables::llvo_vec_t::iterator it = objects_to_remove.begin();
+ it != objects_to_remove.end();
+ ++it)
+ {
+ ids_to_remove.push_back((*it)->getAttachmentItemID());
+ }
+ removeItemsFromAvatar(ids_to_remove);
+}
+
+void LLAppearanceMgr::removeCOFItemLinks(const LLUUID& item_id)
{
gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id);
@@ -2168,13 +2587,9 @@ void LLAppearanceMgr::removeCOFItemLinks(const LLUUID& item_id, bool do_update)
gInventory.purgeObject(item->getUUID());
}
}
- if (do_update)
- {
- LLAppearanceMgr::updateAppearanceFromCOF();
- }
}
-void LLAppearanceMgr::removeCOFLinksOfType(LLWearableType::EType type, bool do_update)
+void LLAppearanceMgr::removeCOFLinksOfType(LLWearableType::EType type)
{
LLFindWearablesOfType filter_wearables_of_type(type);
LLInventoryModel::cat_array_t cats;
@@ -2190,11 +2605,6 @@ void LLAppearanceMgr::removeCOFLinksOfType(LLWearableType::EType type, bool do_u
gInventory.purgeObject(item->getUUID());
}
}
-
- if (do_update)
- {
- updateAppearanceFromCOF();
- }
}
bool sort_by_linked_uuid(const LLViewerInventoryItem* item1, const LLViewerInventoryItem* item2)
@@ -2262,7 +2672,7 @@ void LLAppearanceMgr::updateIsDirty()
if (item1->getLinkedUUID() != item2->getLinkedUUID() ||
item1->getName() != item2->getName() ||
- item1->LLInventoryItem::getDescription() != item2->LLInventoryItem::getDescription())
+ item1->getActualDescription() != item2->getActualDescription())
{
mOutfitIsDirty = true;
return;
@@ -2281,11 +2691,11 @@ const std::string OTHER_GESTURES_FOLDER = "Other Gestures";
void LLAppearanceMgr::copyLibraryGestures()
{
- llinfos << "Copying library gestures" << llendl;
+ LL_INFOS("Avatar") << self_av_string() << "Copying library gestures" << LL_ENDL;
// Copy gestures
LLUUID lib_gesture_cat_id =
- gInventory.findCategoryUUIDForType(LLFolderType::FT_GESTURE,false,true);
+ gInventory.findLibraryCategoryUUIDForType(LLFolderType::FT_GESTURE,false);
if (lib_gesture_cat_id.isNull())
{
llwarns << "Unable to copy gestures, source category not found" << llendl;
@@ -2331,17 +2741,17 @@ void LLAppearanceMgr::copyLibraryGestures()
folder_name == COMMON_GESTURES_FOLDER ||
folder_name == OTHER_GESTURES_FOLDER)
{
- cb = new ActivateGestureCallback;
+ cb = new LLBoostFuncInventoryCallback(activate_gesture_cb);
}
LLUUID cat_id = findDescendentCategoryIDByName(lib_gesture_cat_id,folder_name);
if (cat_id.isNull())
{
- llwarns << "failed to find gesture folder for " << folder_name << llendl;
+ llwarns << self_av_string() << "failed to find gesture folder for " << folder_name << llendl;
}
else
{
- llinfos << "initiating fetch and copy for " << folder_name << " cat_id " << cat_id << llendl;
+ LL_DEBUGS("Avatar") << self_av_string() << "initiating fetch and copy for " << folder_name << " cat_id " << cat_id << LL_ENDL;
callAfterCategoryFetch(cat_id,
boost::bind(&LLAppearanceMgr::shallowCopyCategory,
&LLAppearanceMgr::instance(),
@@ -2355,7 +2765,7 @@ void LLAppearanceMgr::autopopulateOutfits()
// If this is the very first time the user has logged into viewer2+ (from a legacy viewer, or new account)
// then auto-populate outfits from the library into the My Outfits folder.
- llinfos << "avatar fully visible" << llendl;
+ LL_INFOS("Avatar") << self_av_string() << "avatar fully visible" << LL_ENDL;
static bool check_populate_my_outfits = true;
if (check_populate_my_outfits &&
@@ -2385,6 +2795,16 @@ void LLAppearanceMgr::onFirstFullyVisible()
}
}
+// update "dirty" state - defined outside class to allow for calling
+// after appearance mgr instance has been destroyed.
+void appearance_mgr_update_dirty_state()
+{
+ if (LLAppearanceMgr::instanceExists())
+ {
+ LLAppearanceMgr::getInstance()->updateIsDirty();
+ }
+}
+
bool LLAppearanceMgr::updateBaseOutfit()
{
if (isOutfitLocked())
@@ -2405,8 +2825,8 @@ bool LLAppearanceMgr::updateBaseOutfit()
// in a Base Outfit we do not remove items, only links
purgeCategory(base_outfit_id, false);
-
- LLPointer<LLInventoryCallback> dirty_state_updater = new LLUpdateDirtyState();
+ LLPointer<LLInventoryCallback> dirty_state_updater =
+ new LLBoostFuncInventoryCallback(no_op_inventory_func, appearance_mgr_update_dirty_state);
//COF contains only links so we copy to the Base Outfit only links
shallowCopyCategoryContents(getCOF(), base_outfit_id, dirty_state_updater);
@@ -2463,8 +2883,8 @@ struct WearablesOrderComparator
return true;
}
- const std::string& desc1 = item1->LLInventoryItem::getDescription();
- const std::string& desc2 = item2->LLInventoryItem::getDescription();
+ const std::string& desc1 = item1->getActualDescription();
+ const std::string& desc2 = item2->getActualDescription();
bool item1_valid = (desc1.size() == mControlSize) && (ORDER_NUMBER_SEPARATOR == desc1[0]);
bool item2_valid = (desc2.size() == mControlSize) && (ORDER_NUMBER_SEPARATOR == desc2[0]);
@@ -2522,7 +2942,7 @@ void LLAppearanceMgr::updateClothingOrderingInfo(LLUUID cat_id, bool update_base
if (!item) continue;
std::string new_order_str = build_order_string((LLWearableType::EType)type, i);
- if (new_order_str == item->LLInventoryItem::getDescription()) continue;
+ if (new_order_str == item->getActualDescription()) continue;
item->setDescription(new_order_str);
item->setComplete(TRUE);
@@ -2537,16 +2957,396 @@ void LLAppearanceMgr::updateClothingOrderingInfo(LLUUID cat_id, bool update_base
if (inventory_changed) gInventory.notifyObservers();
}
+// This is intended for use with HTTP Clients/Responders, but is not
+// specifically coupled with those classes.
+class LLHTTPRetryPolicy: public LLThreadSafeRefCount
+{
+public:
+ LLHTTPRetryPolicy() {}
+ virtual ~LLHTTPRetryPolicy() {}
+ virtual bool shouldRetry(U32 status, F32& seconds_to_wait) = 0;
+};
+// Example of simplest possible policy, not necessarily recommended.
+class LLAlwaysRetryImmediatelyPolicy: public LLHTTPRetryPolicy
+{
+public:
+ LLAlwaysRetryImmediatelyPolicy() {}
+ bool shouldRetry(U32 status, F32& seconds_to_wait)
+ {
+ seconds_to_wait = 0.0;
+ return true;
+ }
+};
+// Very general policy with geometric back-off after failures,
+// up to a maximum delay, and maximum number of retries.
+class LLAdaptiveRetryPolicy: public LLHTTPRetryPolicy
+{
+public:
+ LLAdaptiveRetryPolicy(F32 min_delay, F32 max_delay, F32 backoff_factor, U32 max_retries):
+ mMinDelay(min_delay),
+ mMaxDelay(max_delay),
+ mBackoffFactor(backoff_factor),
+ mMaxRetries(max_retries),
+ mDelay(min_delay),
+ mRetryCount(0)
+ {
+ }
-class LLShowCreatedOutfit: public LLInventoryCallback
+ bool shouldRetry(U32 status, F32& seconds_to_wait)
+ {
+ seconds_to_wait = mDelay;
+ mDelay = llclamp(mDelay*mBackoffFactor,mMinDelay,mMaxDelay);
+ mRetryCount++;
+ return (mRetryCount<=mMaxRetries);
+ }
+
+private:
+ F32 mMinDelay; // delay never less than this value
+ F32 mMaxDelay; // delay never exceeds this value
+ F32 mBackoffFactor; // delay increases by this factor after each retry, up to mMaxDelay.
+ U32 mMaxRetries; // maximum number of times shouldRetry will return true.
+ F32 mDelay; // current delay.
+ U32 mRetryCount; // number of times shouldRetry has been called.
+};
+
+class RequestAgentUpdateAppearanceResponder: public LLHTTPClient::Responder
{
public:
- LLShowCreatedOutfit(LLUUID& folder_id, bool show_panel = true): mFolderID(folder_id), mShowPanel(show_panel)
- {}
+ RequestAgentUpdateAppearanceResponder()
+ {
+ mRetryPolicy = new LLAdaptiveRetryPolicy(1.0, 32.0, 2.0, 10);
+ }
+
+ virtual ~RequestAgentUpdateAppearanceResponder()
+ {
+ }
- virtual ~LLShowCreatedOutfit()
+ // Successful completion.
+ /* virtual */ void result(const LLSD& content)
+ {
+ LL_DEBUGS("Avatar") << "content: " << ll_pretty_print_sd(content) << LL_ENDL;
+ if (content["success"].asBoolean())
+ {
+ LL_DEBUGS("Avatar") << "OK" << LL_ENDL;
+ if (gSavedSettings.getBOOL("DebugAvatarAppearanceMessage"))
+ {
+ dumpContents(gAgentAvatarp->getFullname() + "_appearance_request_ok", content);
+ }
+ }
+ else
+ {
+ onFailure(200);
+ }
+ }
+
+ // Error
+ /*virtual*/ void errorWithContent(U32 status, const std::string& reason, const LLSD& content)
+ {
+ llwarns << "appearance update request failed, status: " << status << " reason: " << reason << " code: " << content["code"].asInteger() << " error: \"" << content["error"].asString() << "\"" << llendl;
+ if (gSavedSettings.getBOOL("DebugAvatarAppearanceMessage"))
+ {
+ dumpContents(gAgentAvatarp->getFullname() + "_appearance_request_error", content);
+ debugCOF(content);
+
+ }
+ onFailure(status);
+ }
+
+ void onFailure(U32 status)
+ {
+ F32 seconds_to_wait;
+ if (mRetryPolicy->shouldRetry(status,seconds_to_wait))
+ {
+ llinfos << "retrying" << llendl;
+ doAfterInterval(boost::bind(&LLAppearanceMgr::requestServerAppearanceUpdate,
+ LLAppearanceMgr::getInstance(),
+ LLCurl::ResponderPtr(this)),
+ seconds_to_wait);
+ }
+ else
+ {
+ llwarns << "giving up after too many retries" << llendl;
+ }
+ }
+
+ void dumpContents(const std::string outprefix, const LLSD& content)
+ {
+ std::string outfilename = get_sequential_numbered_file_name(outprefix,".xml");
+ std::string fullpath = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,outfilename);
+ std::ofstream ofs(fullpath.c_str(), std::ios_base::out);
+ ofs << LLSDOStreamer<LLSDXMLFormatter>(content, LLSDFormatter::OPTIONS_PRETTY);
+ LL_DEBUGS("Avatar") << "results saved to: " << fullpath << LL_ENDL;
+ }
+
+ void debugCOF(const LLSD& content)
+ {
+ LL_DEBUGS("Avatar") << "AIS COF, version found: " << content["expected"].asInteger() << llendl;
+ std::set<LLUUID> ais_items, local_items;
+ const LLSD& cof_raw = content["cof_raw"];
+ for (LLSD::array_const_iterator it = cof_raw.beginArray();
+ it != cof_raw.endArray(); ++it)
+ {
+ const LLSD& item = *it;
+ if (item["parent_id"].asUUID() == LLAppearanceMgr::instance().getCOF())
+ {
+ ais_items.insert(item["item_id"].asUUID());
+ if (item["type"].asInteger() == 24) // link
+ {
+ LL_DEBUGS("Avatar") << "Link: item_id: " << item["item_id"].asUUID()
+ << " linked_item_id: " << item["asset_id"].asUUID()
+ << " name: " << item["name"].asString()
+ << llendl;
+ }
+ else if (item["type"].asInteger() == 25) // folder link
+ {
+ LL_DEBUGS("Avatar") << "Folder link: item_id: " << item["item_id"].asUUID()
+ << " linked_item_id: " << item["asset_id"].asUUID()
+ << " name: " << item["name"].asString()
+ << llendl;
+
+ }
+ else
+ {
+ LL_DEBUGS("Avatar") << "Other: item_id: " << item["item_id"].asUUID()
+ << " linked_item_id: " << item["asset_id"].asUUID()
+ << " name: " << item["name"].asString()
+ << llendl;
+ }
+ }
+ }
+ LL_DEBUGS("Avatar") << llendl;
+ LL_DEBUGS("Avatar") << "Local COF, version requested: " << content["observed"].asInteger() << llendl;
+ LLInventoryModel::cat_array_t cat_array;
+ LLInventoryModel::item_array_t item_array;
+ gInventory.collectDescendents(LLAppearanceMgr::instance().getCOF(),
+ cat_array,item_array,LLInventoryModel::EXCLUDE_TRASH);
+ for (S32 i=0; i<item_array.count(); i++)
+ {
+ const LLViewerInventoryItem* inv_item = item_array.get(i).get();
+ local_items.insert(inv_item->getUUID());
+ LL_DEBUGS("Avatar") << "item_id: " << inv_item->getUUID()
+ << " linked_item_id: " << inv_item->getLinkedUUID()
+ << " name: " << inv_item->getName()
+ << llendl;
+ }
+ LL_DEBUGS("Avatar") << llendl;
+ for (std::set<LLUUID>::iterator it = local_items.begin(); it != local_items.end(); ++it)
+ {
+ if (ais_items.find(*it) == ais_items.end())
+ {
+ LL_DEBUGS("Avatar") << "LOCAL ONLY: " << *it << llendl;
+ }
+ }
+ for (std::set<LLUUID>::iterator it = ais_items.begin(); it != ais_items.end(); ++it)
+ {
+ if (local_items.find(*it) == local_items.end())
+ {
+ LL_DEBUGS("Avatar") << "AIS ONLY: " << *it << llendl;
+ }
+ }
+ }
+
+ LLPointer<LLHTTPRetryPolicy> mRetryPolicy;
+};
+
+LLSD LLAppearanceMgr::dumpCOF() const
+{
+ LLSD links = LLSD::emptyArray();
+ LLMD5 md5;
+
+ LLInventoryModel::cat_array_t cat_array;
+ LLInventoryModel::item_array_t item_array;
+ gInventory.collectDescendents(getCOF(),cat_array,item_array,LLInventoryModel::EXCLUDE_TRASH);
+ for (S32 i=0; i<item_array.count(); i++)
+ {
+ const LLViewerInventoryItem* inv_item = item_array.get(i).get();
+ LLSD item;
+ LLUUID item_id(inv_item->getUUID());
+ md5.update((unsigned char*)item_id.mData, 16);
+ item["description"] = inv_item->getActualDescription();
+ md5.update(inv_item->getActualDescription());
+ item["asset_type"] = inv_item->getActualType();
+ LLUUID linked_id(inv_item->getLinkedUUID());
+ item["linked_id"] = linked_id;
+ md5.update((unsigned char*)linked_id.mData, 16);
+
+ if (LLAssetType::AT_LINK == inv_item->getActualType())
+ {
+ const LLViewerInventoryItem* linked_item = inv_item->getLinkedItem();
+ if (NULL == linked_item)
+ {
+ llwarns << "Broken link for item '" << inv_item->getName()
+ << "' (" << inv_item->getUUID()
+ << ") during requestServerAppearanceUpdate" << llendl;
+ continue;
+ }
+ // Some assets may be 'hidden' and show up as null in the viewer.
+ //if (linked_item->getAssetUUID().isNull())
+ //{
+ // llwarns << "Broken link (null asset) for item '" << inv_item->getName()
+ // << "' (" << inv_item->getUUID()
+ // << ") during requestServerAppearanceUpdate" << llendl;
+ // continue;
+ //}
+ LLUUID linked_asset_id(linked_item->getAssetUUID());
+ md5.update((unsigned char*)linked_asset_id.mData, 16);
+ U32 flags = linked_item->getFlags();
+ md5.update(boost::lexical_cast<std::string>(flags));
+ }
+ else if (LLAssetType::AT_LINK_FOLDER != inv_item->getActualType())
+ {
+ llwarns << "Non-link item '" << inv_item->getName()
+ << "' (" << inv_item->getUUID()
+ << ") type " << (S32) inv_item->getActualType()
+ << " during requestServerAppearanceUpdate" << llendl;
+ continue;
+ }
+ links.append(item);
+ }
+ LLSD result = LLSD::emptyMap();
+ result["cof_contents"] = links;
+ char cof_md5sum[MD5HEX_STR_SIZE];
+ md5.finalize();
+ md5.hex_digest(cof_md5sum);
+ result["cof_md5sum"] = std::string(cof_md5sum);
+ return result;
+}
+
+void LLAppearanceMgr::requestServerAppearanceUpdate(LLCurl::ResponderPtr responder_ptr)
+{
+ if (gAgentAvatarp->isEditingAppearance())
+ {
+ // don't send out appearance updates if in appearance editing mode
+ return;
+ }
+
+ if (!gAgent.getRegion())
+ {
+ llwarns << "Region not set, cannot request server appearance update" << llendl;
+ return;
+ }
+ if (gAgent.getRegion()->getCentralBakeVersion()==0)
+ {
+ llwarns << "Region does not support baking" << llendl;
+ }
+ std::string url = gAgent.getRegion()->getCapability("UpdateAvatarAppearance");
+ if (url.empty())
+ {
+ llwarns << "No cap for UpdateAvatarAppearance." << llendl;
+ return;
+ }
+
+ LLSD body;
+ S32 cof_version = getCOFVersion();
+ if (gSavedSettings.getBOOL("DebugAvatarExperimentalServerAppearanceUpdate"))
+ {
+ body = dumpCOF();
+ }
+ else
+ {
+ body["cof_version"] = cof_version;
+ if (gSavedSettings.getBOOL("DebugForceAppearanceRequestFailure"))
+ {
+ body["cof_version"] = cof_version+999;
+ }
+ }
+ LL_DEBUGS("Avatar") << "request url " << url << " my_cof_version " << cof_version << llendl;
+
+ //LLCurl::ResponderPtr responder_ptr;
+ if (!responder_ptr.get())
+ {
+ responder_ptr = new RequestAgentUpdateAppearanceResponder;
+ }
+ LLHTTPClient::post(url, body, responder_ptr);
+ llassert(cof_version >= gAgentAvatarp->mLastUpdateRequestCOFVersion);
+ gAgentAvatarp->mLastUpdateRequestCOFVersion = cof_version;
+}
+
+class LLIncrementCofVersionResponder : public LLHTTPClient::Responder
+{
+public:
+ LLIncrementCofVersionResponder() : LLHTTPClient::Responder()
+ {
+ mRetryPolicy = new LLAdaptiveRetryPolicy(1.0, 16.0, 2.0, 5);
+ }
+
+ virtual ~LLIncrementCofVersionResponder()
+ {
+ }
+
+ virtual void result(const LLSD &pContent)
+ {
+ llinfos << "Successfully incremented agent's COF." << llendl;
+ S32 new_version = pContent["category"]["version"].asInteger();
+
+ // cof_version should have increased
+ llassert(new_version > gAgentAvatarp->mLastUpdateRequestCOFVersion);
+
+ gAgentAvatarp->mLastUpdateRequestCOFVersion = new_version;
+ }
+ virtual void errorWithContent(U32 pStatus, const std::string& pReason, const LLSD& content)
+ {
+ llwarns << "While attempting to increment the agent's cof we got an error with [status:"
+ << pStatus << "]: " << content << llendl;
+ F32 seconds_to_wait;
+ if (mRetryPolicy->shouldRetry(pStatus,seconds_to_wait))
+ {
+ llinfos << "retrying" << llendl;
+ doAfterInterval(boost::bind(&LLAppearanceMgr::incrementCofVersion,
+ LLAppearanceMgr::getInstance(),
+ LLHTTPClient::ResponderPtr(this)),
+ seconds_to_wait);
+ }
+ else
+ {
+ llwarns << "giving up after too many retries" << llendl;
+ }
+ }
+
+ LLPointer<LLHTTPRetryPolicy> mRetryPolicy;
+};
+
+void LLAppearanceMgr::incrementCofVersion(LLHTTPClient::ResponderPtr responder_ptr)
+{
+ // If we don't have a region, report it as an error
+ if (gAgent.getRegion() == NULL)
+ {
+ llwarns << "Region not set, cannot request cof_version increment" << llendl;
+ return;
+ }
+
+ std::string url = gAgent.getRegion()->getCapability("IncrementCofVersion");
+ if (url.empty())
+ {
+ llwarns << "No cap for IncrementCofVersion." << llendl;
+ return;
+ }
+
+ llinfos << "Requesting cof_version be incremented via capability to: "
+ << url << llendl;
+ LLSD headers;
+ LLSD body = LLSD::emptyMap();
+
+ if (!responder_ptr.get())
+ {
+ responder_ptr = LLHTTPClient::ResponderPtr(new LLIncrementCofVersionResponder());
+ }
+
+ LLHTTPClient::get(url, body, responder_ptr, headers, 30.0f);
+}
+
+std::string LLAppearanceMgr::getAppearanceServiceURL() const
+{
+ if (gSavedSettings.getString("DebugAvatarAppearanceServiceURLOverride").empty())
+ {
+ return mAppearanceServiceURL;
+ }
+ return gSavedSettings.getString("DebugAvatarAppearanceServiceURLOverride");
+}
+
+void show_created_outfit(LLUUID& folder_id, bool show_panel = true)
{
if (!LLApp::isRunning())
{
@@ -2556,9 +3356,9 @@ public:
LLSD key;
- //EXT-7727. For new accounts LLShowCreatedOutfit is created during login process
- // add may be processed after login process is finished
- if (mShowPanel)
+ //EXT-7727. For new accounts inventory callback is created during login process
+ // and may be processed after login process is finished
+ if (show_panel)
{
LLFloaterSidePanelContainer::showPanel("appearance", "panel_outfits_inventory", key);
@@ -2567,7 +3367,7 @@ public:
dynamic_cast<LLOutfitsList*>(LLFloaterSidePanelContainer::getPanel("appearance", "outfitslist_tab"));
if (outfits_list)
{
- outfits_list->setSelectedOutfitByUUID(mFolderID);
+ outfits_list->setSelectedOutfitByUUID(folder_id);
}
LLAppearanceMgr::getInstance()->updateIsDirty();
@@ -2575,14 +3375,6 @@ public:
LLAppearanceMgr::getInstance()->updatePanelOutfitName("");
}
- virtual void fire(const LLUUID&)
- {}
-
-private:
- LLUUID mFolderID;
- bool mShowPanel;
-};
-
LLUUID LLAppearanceMgr::makeNewOutfitLinks(const std::string& new_folder_name, bool show_panel)
{
if (!isAgentAvatarValid()) return LLUUID::null;
@@ -2598,7 +3390,8 @@ LLUUID LLAppearanceMgr::makeNewOutfitLinks(const std::string& new_folder_name, b
updateClothingOrderingInfo();
- LLPointer<LLInventoryCallback> cb = new LLShowCreatedOutfit(folder_id,show_panel);
+ LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(no_op_inventory_func,
+ boost::bind(show_created_outfit,folder_id,show_panel));
shallowCopyCategoryContents(getCOF(),folder_id, cb);
createBaseOutfitLink(folder_id, cb);
@@ -2615,35 +3408,57 @@ void LLAppearanceMgr::wearBaseOutfit()
updateCOF(base_outfit_id);
}
+void LLAppearanceMgr::removeItemsFromAvatar(const uuid_vec_t& ids_to_remove)
+{
+ if (ids_to_remove.empty())
+ {
+ llwarns << "called with empty list, nothing to do" << llendl;
+ }
+ for (uuid_vec_t::const_iterator it = ids_to_remove.begin(); it != ids_to_remove.end(); ++it)
+ {
+ const LLUUID& id_to_remove = *it;
+ const LLUUID& linked_item_id = gInventory.getLinkedItemID(id_to_remove);
+ removeCOFItemLinks(linked_item_id);
+ addDoomedTempAttachment(linked_item_id);
+ }
+ updateAppearanceFromCOF();
+}
+
void LLAppearanceMgr::removeItemFromAvatar(const LLUUID& id_to_remove)
{
- LLViewerInventoryItem * item_to_remove = gInventory.getItem(id_to_remove);
- if (!item_to_remove) return;
+ LLUUID linked_item_id = gInventory.getLinkedItemID(id_to_remove);
+ removeCOFItemLinks(linked_item_id);
+ addDoomedTempAttachment(linked_item_id);
+ updateAppearanceFromCOF();
+}
+
+
+// Adds the given item ID to mDoomedTempAttachmentIDs iff it's a temp attachment
+void LLAppearanceMgr::addDoomedTempAttachment(const LLUUID& id_to_remove)
+{
+ LLViewerObject * attachmentp = gAgentAvatarp->findAttachmentByID(id_to_remove);
+ if (attachmentp &&
+ attachmentp->isTempAttachment())
+ { // If this is a temp attachment and we want to remove it, record the ID
+ // so it will be deleted when attachments are synced up with COF
+ mDoomedTempAttachmentIDs.insert(id_to_remove);
+ //llinfos << "Will remove temp attachment id " << id_to_remove << llendl;
+ }
+}
- switch (item_to_remove->getType())
+// Find AND REMOVES the given UUID from mDoomedTempAttachmentIDs
+bool LLAppearanceMgr::shouldRemoveTempAttachment(const LLUUID& item_id)
+{
+ doomed_temp_attachments_t::iterator iter = mDoomedTempAttachmentIDs.find(item_id);
+ if (iter != mDoomedTempAttachmentIDs.end())
{
- case LLAssetType::AT_CLOTHING:
- if (get_is_item_worn(id_to_remove))
- {
- //*TODO move here the exact removing code from LLWearableBridge::removeItemFromAvatar in the future
- LLWearableBridge::removeItemFromAvatar(item_to_remove);
- }
- break;
- case LLAssetType::AT_OBJECT:
- LLVOAvatarSelf::detachAttachmentIntoInventory(item_to_remove->getLinkedUUID());
- default:
- break;
+ mDoomedTempAttachmentIDs.erase(iter);
+ return true;
}
-
- // *HACK: Force to remove garbage from COF.
- // Unworn links or objects can't be processed by existed removing functionality
- // since it is not designed for such cases. As example attachment object can't be removed
- // since sever don't sends message _PREHASH_KillObject in that case.
- // Also we can't check is link was successfully removed from COF since in case
- // deleting attachment link removing performs asynchronously in process_kill_object callback.
- removeCOFItemLinks(id_to_remove,false);
+ return false;
}
+
bool LLAppearanceMgr::moveWearable(LLViewerInventoryItem* item, bool closer_to_body)
{
if (!item || !item->isWearableType()) return false;
@@ -2670,8 +3485,8 @@ bool LLAppearanceMgr::moveWearable(LLViewerInventoryItem* item, bool closer_to_b
closer_to_body ? --it : ++it;
LLViewerInventoryItem* swap_item = *it;
if (!swap_item) return false;
- std::string tmp = swap_item->LLInventoryItem::getDescription();
- swap_item->setDescription(item->LLInventoryItem::getDescription());
+ std::string tmp = swap_item->getActualDescription();
+ swap_item->setDescription(item->getActualDescription());
item->setDescription(tmp);
@@ -2704,7 +3519,7 @@ void LLAppearanceMgr::sortItemsByActualDescription(LLInventoryModel::item_array_
{
if (items.size() < 2) return;
- std::sort(items.begin(), items.end(), sort_by_description);
+ std::sort(items.begin(), items.end(), sort_by_actual_description);
}
//#define DUMP_CAT_VERBOSE
@@ -2731,7 +3546,7 @@ void LLAppearanceMgr::dumpCat(const LLUUID& cat_id, const std::string& msg)
}
void LLAppearanceMgr::dumpItemArray(const LLInventoryModel::item_array_t& items,
- const std::string& msg)
+ const std::string& msg)
{
for (S32 i=0; i<items.count(); i++)
{
@@ -2742,9 +3557,8 @@ void LLAppearanceMgr::dumpItemArray(const LLInventoryModel::item_array_t& items,
{
asset_id = linked_item->getAssetUUID();
}
- llinfos << msg << " " << i <<" " << (item ? item->getName() : "(nullitem)") << " " << asset_id.asString() << llendl;
+ LL_DEBUGS("Avatar") << self_av_string() << msg << " " << i <<" " << (item ? item->getName() : "(nullitem)") << " " << asset_id.asString() << LL_ENDL;
}
- llinfos << llendl;
}
LLAppearanceMgr::LLAppearanceMgr():
@@ -2771,7 +3585,7 @@ LLAppearanceMgr::~LLAppearanceMgr()
void LLAppearanceMgr::setAttachmentInvLinkEnable(bool val)
{
- llinfos << "setAttachmentInvLinkEnable => " << (int) val << llendl;
+ LL_DEBUGS("Avatar") << "setAttachmentInvLinkEnable => " << (int) val << llendl;
mAttachmentInvLinkEnabled = val;
}
@@ -2815,7 +3629,7 @@ void LLAppearanceMgr::unregisterAttachment(const LLUUID& item_id)
if (mAttachmentInvLinkEnabled)
{
- LLAppearanceMgr::removeCOFItemLinks(item_id, false);
+ LLAppearanceMgr::removeCOFItemLinks(item_id);
}
else
{
@@ -2909,9 +3723,9 @@ public:
}
virtual void done()
{
- // What we do here is get the complete information on the items in
- // the library, and set up an observer that will wait for that to
- // happen.
+ // What we do here is get the complete information on the
+ // items in the requested category, and set up an observer
+ // that will wait for that to happen.
LLInventoryModel::cat_array_t cat_array;
LLInventoryModel::item_array_t item_array;
gInventory.collectDescendents(mComplete.front(),
@@ -2923,11 +3737,9 @@ public:
{
llwarns << "Nothing fetched in category " << mComplete.front()
<< llendl;
- //dec_busy_count();
gInventory.removeObserver(this);
+ doOnIdleOneTime(mCallable);
- // lets notify observers that loading is finished.
- gAgentWearables.notifyLoadingFinished();
delete this;
return;
}
diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h
index c1d561781d..5ec80f1cf0 100644..100755
--- a/indra/newview/llappearancemgr.h
+++ b/indra/newview/llappearancemgr.h
@@ -35,7 +35,6 @@
#include "llinventoryobserver.h"
#include "llviewerinventory.h"
-class LLWearable;
class LLWearableHoldingPattern;
class LLInventoryCallback;
class LLOutfitUnLockTimer;
@@ -93,6 +92,10 @@ public:
// Find the Current Outfit folder.
const LLUUID getCOF() const;
+ S32 getCOFVersion() const;
+
+ // Debugging - get truncated LLSD summary of COF contents.
+ LLSD dumpCOF() const;
// Finds the folder link to the currently worn outfit
const LLViewerInventoryItem *getBaseOutfitLink();
@@ -107,6 +110,7 @@ public:
// Update the displayed outfit name in UI.
void updatePanelOutfitName(const std::string& name);
+ void purgeBaseOutfitLink(const LLUUID& category);
void createBaseOutfitLink(const LLUUID& category, LLPointer<LLInventoryCallback> link_waiter);
void updateAgentWearables(LLWearableHoldingPattern* holder, bool append);
@@ -126,15 +130,20 @@ public:
LLPointer<LLInventoryCallback> cb);
// Add COF link to individual item.
- void addCOFItemLink(const LLUUID& item_id, bool do_update = true, LLPointer<LLInventoryCallback> cb = NULL);
- void addCOFItemLink(const LLInventoryItem *item, bool do_update = true, LLPointer<LLInventoryCallback> cb = NULL);
+ void addCOFItemLink(const LLUUID& item_id, bool do_update = true, LLPointer<LLInventoryCallback> cb = NULL, const std::string description = "");
+ void addCOFItemLink(const LLInventoryItem *item, bool do_update = true, LLPointer<LLInventoryCallback> cb = NULL, const std::string description = "");
+
+ // Find COF entries referencing the given item.
+ LLInventoryModel::item_array_t findCOFItemLinks(const LLUUID& item_id);
// Remove COF entries
- void removeCOFItemLinks(const LLUUID& item_id, bool do_update = true);
- void removeCOFLinksOfType(LLWearableType::EType type, bool do_update = true);
+ void removeCOFItemLinks(const LLUUID& item_id);
+ void removeCOFLinksOfType(LLWearableType::EType type);
+ void removeAllClothesFromAvatar();
+ void removeAllAttachmentsFromAvatar();
- // Add COF link to ensemble folder.
- void addEnsembleLink(LLInventoryCategory* item, bool do_update = true);
+ // Special handling of temp attachments, which are not in the COF
+ bool shouldRemoveTempAttachment(const LLUUID& item_id);
//has the current outfit changed since it was loaded?
bool isOutfitDirty() { return mOutfitIsDirty; }
@@ -162,6 +171,7 @@ public:
bool updateBaseOutfit();
//Remove clothing or detach an object from the agent (a bodypart cannot be removed)
+ void removeItemsFromAvatar(const uuid_vec_t& item_ids);
void removeItemFromAvatar(const LLUUID& item_id);
@@ -182,6 +192,20 @@ public:
bool isInUpdateAppearanceFromCOF() { return mIsInUpdateAppearanceFromCOF; }
+ void requestServerAppearanceUpdate(LLCurl::ResponderPtr responder_ptr = NULL);
+
+ void incrementCofVersion(LLHTTPClient::ResponderPtr responder_ptr = NULL);
+
+ // *HACK Remove this after server side texture baking is deployed on all sims.
+ void incrementCofVersionLegacy();
+
+ void setAppearanceServiceURL(const std::string& url) { mAppearanceServiceURL = url; }
+ std::string getAppearanceServiceURL() const;
+
+private:
+ std::string mAppearanceServiceURL;
+
+
protected:
LLAppearanceMgr();
~LLAppearanceMgr();
@@ -201,9 +225,7 @@ private:
LLInventoryModel::item_array_t& gest_items,
bool follow_folder_links);
- void purgeCategory(const LLUUID& category, bool keep_outfit_links);
- void purgeBaseOutfitLink(const LLUUID& category);
-
+ void purgeCategory(const LLUUID& category, bool keep_outfit_links, LLInventoryModel::item_array_t* keep_items = NULL);
static void onOutfitRename(const LLSD& notification, const LLSD& response);
void setOutfitLocked(bool locked);
@@ -220,6 +242,12 @@ private:
std::auto_ptr<LLOutfitUnLockTimer> mUnlockOutfitTimer;
+ // Set of temp attachment UUIDs that should be removed
+ typedef std::set<LLUUID> doomed_temp_attachments_t;
+ doomed_temp_attachments_t mDoomedTempAttachmentIDs;
+
+ void addDoomedTempAttachment(const LLUUID& id_to_remove);
+
//////////////////////////////////////////////////////////////////////////////////
// Item-specific convenience functions
public:
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 1174d108d2..539d186441 100644..100755
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -4,7 +4,7 @@
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
+ * Copyright (C) 2012, 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
@@ -30,7 +30,6 @@
// Viewer includes
#include "llversioninfo.h"
-#include "llversionviewer.h"
#include "llfeaturemanager.h"
#include "lluictrlfactory.h"
#include "lltexteditor.h"
@@ -42,6 +41,7 @@
#include "llagentcamera.h"
#include "llagentlanguage.h"
#include "llagentwearables.h"
+#include "llfloaterimcontainer.h"
#include "llwindow.h"
#include "llviewerstats.h"
#include "llviewerstatsrecorder.h"
@@ -59,6 +59,7 @@
#include "llares.h"
#include "llcurl.h"
#include "llcalc.h"
+#include "llconversationlog.h"
#include "lltexturestats.h"
#include "lltexturestats.h"
#include "llviewerwindow.h"
@@ -89,10 +90,13 @@
#include "lllogininstance.h"
#include "llprogressview.h"
#include "llvocache.h"
+#include "llvopartgroup.h"
#include "llweb.h"
#include "llsecondlifeurls.h"
#include "llupdaterservice.h"
-#include "llcallfloater.h"
+#include "llfloatertexturefetchdebugger.h"
+#include "llspellcheck.h"
+#include "llavatarrenderinfoaccountant.h"
// Linden library includes
#include "llavatarnamecache.h"
@@ -106,25 +110,30 @@
#include "llvfsthread.h"
#include "llvolumemgr.h"
#include "llxfermanager.h"
+#include "llphysicsextensions.h"
#include "llnotificationmanager.h"
#include "llnotifications.h"
#include "llnotificationsutil.h"
+#include "llleap.h"
+#include "stringize.h"
+#include "llcoros.h"
+
// Third party library includes
#include <boost/bind.hpp>
#include <boost/foreach.hpp>
-
+#include <boost/algorithm/string.hpp>
+#include <boost/regex.hpp>
#if LL_WINDOWS
-# include <share.h> // For _SH_DENYWR in initMarkerFile
+# include <share.h> // For _SH_DENYWR in processMarkerFiles
#else
-# include <sys/file.h> // For initMarkerFile support
+# include <sys/file.h> // For processMarkerFiles
#endif
#include "llapr.h"
-#include "apr_dso.h"
#include <boost/lexical_cast.hpp>
#include "llviewerkeyboard.h"
@@ -161,6 +170,7 @@
#include "llcontainerview.h"
#include "lltooltip.h"
+#include "llsdutil.h"
#include "llsdserialize.h"
#include "llworld.h"
@@ -193,6 +203,7 @@
#include "llviewercontrol.h"
#include "lleventnotifier.h"
#include "llcallbacklist.h"
+#include "lldeferredsounds.h"
#include "pipeline.h"
#include "llgesturemgr.h"
#include "llsky.h"
@@ -212,6 +223,10 @@
#include "llmachineid.h"
#include "llmainlooprepeater.h"
+
+#include "llviewereventrecorder.h"
+
+
// *FIX: These extern globals should be cleaned up.
// The globals either represent state/config/resource-storage of either
// this app, or another 'component' of the viewer. App globals should be
@@ -243,6 +258,7 @@ static LLAppViewerListener sAppViewerListener(LLAppViewer::instance);
// viewer.cpp - these are only used in viewer, should be easily moved.
#if LL_DARWIN
+const char * const LL_VERSION_BUNDLE_ID = "com.secondlife.indra.viewer";
extern void init_apple_menu(const char* product);
#endif // LL_DARWIN
@@ -260,6 +276,20 @@ BOOL gShowObjectUpdates = FALSE;
BOOL gUseQuickTime = TRUE;
eLastExecEvent gLastExecEvent = LAST_EXEC_NORMAL;
+S32 gLastExecDuration = -1; // (<0 indicates unknown)
+
+#if LL_WINDOWS
+# define LL_PLATFORM_KEY "win"
+#elif LL_DARWIN
+# define LL_PLATFORM_KEY "mac"
+#elif LL_LINUX
+# define LL_PLATFORM_KEY "lnx"
+#elif LL_SOLARIS
+# define LL_PLATFORM_KEY "sol"
+#else
+# error "Unknown Platform"
+#endif
+const char* gPlatform = LL_PLATFORM_KEY;
LLSD gDebugInfo;
@@ -283,6 +313,10 @@ LLTimer gLogoutTimer;
static const F32 LOGOUT_REQUEST_TIME = 6.f; // this will be cut short by the LogoutReply msg.
F32 gLogoutMaxTime = LOGOUT_REQUEST_TIME;
+
+S32 gPendingMetricsUploads = 0;
+
+
BOOL gDisconnected = FALSE;
// used to restore texture state after a mode switch
@@ -315,8 +349,9 @@ BOOL gLogoutInProgress = FALSE;
////////////////////////////////////////////////////////////
// Internal globals... that should be removed.
static std::string gArgs;
-
+const int MAX_MARKER_LENGTH = 1024;
const std::string MARKER_FILE_NAME("SecondLife.exec_marker");
+const std::string START_MARKER_FILE_NAME("SecondLife.start_marker");
const std::string ERROR_MARKER_FILE_NAME("SecondLife.error_marker");
const std::string LLERROR_MARKER_FILE_NAME("SecondLife.llerror_marker");
const std::string LOGOUT_MARKER_FILE_NAME("SecondLife.logout_marker");
@@ -372,6 +407,9 @@ void init_default_trans_args()
default_trans_args.insert("CAPITALIZED_APP_NAME");
default_trans_args.insert("SECOND_LIFE_GRID");
default_trans_args.insert("SUPPORT_SITE");
+ // This URL shows up in a surprising number of places in various skin
+ // files. We really only want to have to maintain a single copy of it.
+ default_trans_args.insert("create_account_url");
}
//----------------------------------------------------------------------------
@@ -448,7 +486,18 @@ static void ui_audio_callback(const LLUUID& uuid)
{
if (gAudiop)
{
- gAudiop->triggerSound(uuid, gAgent.getID(), 1.0f, LLAudioEngine::AUDIO_TYPE_UI);
+ SoundData soundData(uuid, gAgent.getID(), 1.0f, LLAudioEngine::AUDIO_TYPE_UI);
+ gAudiop->triggerSound(soundData);
+ }
+}
+
+// A callback set in LLAppViewer::init()
+static void deferred_ui_audio_callback(const LLUUID& uuid)
+{
+ if (gAudiop)
+ {
+ SoundData soundData(uuid, gAgent.getID(), 1.0f, LLAudioEngine::AUDIO_TYPE_UI);
+ LLDeferredSounds::instance().deferSound(soundData);
}
}
@@ -526,8 +575,9 @@ static void settings_to_globals()
LLSurface::setTextureSize(gSavedSettings.getU32("RegionTextureSize"));
LLRender::sGLCoreProfile = gSavedSettings.getBOOL("RenderGLCoreProfile");
-
+ LLVertexBuffer::sUseVAO = gSavedSettings.getBOOL("RenderUseVAO");
LLImageGL::sGlobalUseAnisotropic = gSavedSettings.getBOOL("RenderAnisotropic");
+ LLImageGL::sCompressTextures = gSavedSettings.getBOOL("RenderCompressTextures");
LLVOVolume::sLODFactor = gSavedSettings.getF32("RenderVolumeLODFactor");
LLVOVolume::sDistanceFactor = 1.f-LLVOVolume::sLODFactor * 0.1f;
LLVolumeImplFlexible::sUpdateFactor = gSavedSettings.getF32("RenderFlexTimeFactor");
@@ -545,7 +595,7 @@ static void settings_to_globals()
gAgentPilot.setNumRuns(gSavedSettings.getS32("StatsNumRuns"));
gAgentPilot.setQuitAfterRuns(gSavedSettings.getBOOL("StatsQuitAfterRuns"));
gAgent.setHideGroupTitle(gSavedSettings.getBOOL("RenderHideGroupTitle"));
-
+
gDebugWindowProc = gSavedSettings.getBOOL("DebugWindowProc");
gShowObjectUpdates = gSavedSettings.getBOOL("ShowObjectUpdates");
LLWorldMapView::sMapScale = gSavedSettings.getF32("MapScale");
@@ -554,13 +604,13 @@ static void settings_to_globals()
static void settings_modify()
{
LLRenderTarget::sUseFBO = gSavedSettings.getBOOL("RenderDeferred");
- LLPipeline::sRenderDeferred = gSavedSettings.getBOOL("RenderDeferred");
+ LLPipeline::sRenderBump = gSavedSettings.getBOOL("RenderObjectBump");
+ LLPipeline::sRenderDeferred = LLPipeline::sRenderBump && gSavedSettings.getBOOL("RenderDeferred");
LLVOAvatar::sUseImpostors = gSavedSettings.getBOOL("RenderUseImpostors");
LLVOSurfacePatch::sLODFactor = gSavedSettings.getF32("RenderTerrainLODFactor");
LLVOSurfacePatch::sLODFactor *= LLVOSurfacePatch::sLODFactor; //square lod factor to get exponential range of [1,4]
gDebugGL = gSavedSettings.getBOOL("RenderDebugGL") || gDebugSession;
gDebugPipeline = gSavedSettings.getBOOL("RenderDebugPipeline");
- gAuditTexture = gSavedSettings.getBOOL("AuditTexture");
}
class LLFastTimerLogThread : public LLThread
@@ -615,14 +665,14 @@ LLTextureFetch* LLAppViewer::sTextureFetch = NULL;
LLAppViewer::LLAppViewer() :
mMarkerFile(),
- mLogoutMarkerFile(NULL),
+ mLogoutMarkerFile(),
mReportedCrash(false),
mNumSessions(0),
mPurgeCache(false),
mPurgeOnExit(false),
mSecondInstance(false),
mSavedFinalSnapshot(false),
- mForceGraphicsDetail(false),
+ mSavePerAccountSettings(false), // don't save settings on logout unless login succeeded.
mQuitRequested(false),
mLogoutRequestSent(false),
mYieldTime(-1),
@@ -644,11 +694,13 @@ LLAppViewer::LLAppViewer() :
gLoggedInTime.stop();
LLLoginInstance::instance().setUpdaterService(mUpdater.get());
+ LLLoginInstance::instance().setPlatformInfo(gPlatform, getOSInfo().getOSVersionString());
}
LLAppViewer::~LLAppViewer()
{
delete mSettingsLocationList;
+ LLViewerEventRecorder::instance().~LLViewerEventRecorder();
LLLoginInstance::instance().setUpdaterService(0);
@@ -658,6 +710,15 @@ LLAppViewer::~LLAppViewer()
removeMarkerFile();
}
+class LLUITranslationBridge : public LLTranslationBridge
+{
+public:
+ virtual std::string getString(const std::string &xml_desc)
+ {
+ return LLTrans::getString(xml_desc);
+ }
+};
+
bool LLAppViewer::init()
{
//
@@ -668,19 +729,33 @@ bool LLAppViewer::init()
// we run the "program crashed last time" error handler below.
//
LLFastTimer::reset();
+
+
+#ifdef LL_DARWIN
+ mMainLoopInitialized = false;
+#endif
+
+ // initialize LLWearableType translation bridge.
+ // Memory will be cleaned up in ::cleanupClass()
+ LLWearableType::initClass(new LLUITranslationBridge());
// initialize SSE options
LLVector4a::initClass();
+ //initialize particle index pool
+ LLVOPartGroup::initClass();
+
// Need to do this initialization before we do anything else, since anything
// that touches files should really go through the lldir API
gDirUtilp->initAppDirs("SecondLife");
// set skin search path to default, will be overridden later
// this allows simple skinned file lookups to work
- gDirUtilp->setSkinFolder("default");
+ gDirUtilp->setSkinFolder("default", "en");
- initLogging();
+ initLoggingAndGetLastDuration();
+ processMarkerFiles();
+
//
// OK to write stuff to logs now, we've now crash reported if necessary
//
@@ -694,15 +769,16 @@ bool LLAppViewer::init()
//set the max heap size.
initMaxHeapSize() ;
+ LLCoros::instance().setStackSize(gSavedSettings.getS32("CoroutineStackSize"));
- LLPrivateMemoryPoolManager::initClass((BOOL)gSavedSettings.getBOOL("MemoryPrivatePoolEnabled"), (U32)gSavedSettings.getU32("MemoryPrivatePoolSize")) ;
+ LLPrivateMemoryPoolManager::initClass((BOOL)gSavedSettings.getBOOL("MemoryPrivatePoolEnabled"), (U32)gSavedSettings.getU32("MemoryPrivatePoolSize")*1024*1024) ;
// write Google Breakpad minidump files to our log directory
std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "");
logdir += gDirUtilp->getDirDelimiter();
setMiniDumpDir(logdir);
- // Although initLogging() is the right place to mess with
+ // Although initLoggingAndGetLastDuration() is the right place to mess with
// setFatalFunction(), we can't query gSavedSettings until after
// initConfiguration().
S32 rc(gSavedSettings.getS32("QAModeTermCode"));
@@ -716,10 +792,10 @@ bool LLAppViewer::init()
mAlloc.setProfilingEnabled(gSavedSettings.getBOOL("MemProfiling"));
-#if LL_RECORD_VIEWER_STATS
- LLViewerStatsRecorder::initClass();
-#endif
-
+ // Initialize the non-LLCurl libcurl library. Should be called
+ // before consumers (LLTextureFetch).
+ mAppCoreHttp.init();
+
// *NOTE:Mani - LLCurl::initClass is not thread safe.
// Called before threads are created.
LLCurl::initClass(gSavedSettings.getF32("CurlRequestTimeOut"),
@@ -731,12 +807,12 @@ bool LLAppViewer::init()
{
// Viewer metrics initialization
- static LLCachedControl<bool> metrics_submode(gSavedSettings,
- "QAModeMetrics",
- false,
- "Enables QA features (logging, faster cycling) for metrics collector");
+ //static LLCachedControl<bool> metrics_submode(gSavedSettings,
+ // "QAModeMetrics",
+ // false,
+ // "Enables QA features (logging, faster cycling) for metrics collector");
- if (metrics_submode)
+ if (gSavedSettings.getBOOL("QAModeMetrics"))
{
app_metrics_qa_mode = true;
app_metrics_interval = METRICS_INTERVAL_QA;
@@ -758,15 +834,19 @@ bool LLAppViewer::init()
LLUI::initClass(settings_map,
LLUIImageList::getInstance(),
ui_audio_callback,
- &LLUI::sGLScaleFactor);
+ deferred_ui_audio_callback,
+ &LLUI::getScaleFactor());
LL_INFOS("InitInfo") << "UI initialized." << LL_ENDL ;
- // Setup paths and LLTrans after LLUI::initClass has been called.
- LLUI::setupPaths();
- LLTransUtil::parseStrings("strings.xml", default_trans_args);
- LLTransUtil::parseLanguageStrings("language_settings.xml");
+ // NOW LLUI::getLanguage() should work. gDirUtilp must know the language
+ // for this session ASAP so all the file-loading commands that follow,
+ // that use findSkinnedFilenames(), will include the localized files.
+ gDirUtilp->setSkinFolder(gDirUtilp->getSkinFolder(), LLUI::getLanguage());
- // Setup notifications after LLUI::setupPaths() has been called.
+ // Setup LLTrans after LLUI::initClass has been called.
+ initStrings();
+
+ // Setup notifications after LLUI::initClass() has been called.
LLNotifications::instance();
LL_INFOS("InitInfo") << "Notifications initialized." << LL_ENDL ;
@@ -786,9 +866,6 @@ bool LLAppViewer::init()
//////////////////////////////////////////////////////////////////////////////
// *FIX: The following code isn't grouped into functions yet.
- // Statistics / debug timer initialization
- init_statistics();
-
//
// Various introspection concerning the libs we're using - particularly
// the libs involved in getting to a full login screen.
@@ -1014,6 +1091,24 @@ bool LLAppViewer::init()
}
}
+#if LL_WINDOWS
+ if (gGLManager.mGLVersion < LLFeatureManager::getInstance()->getExpectedGLVersion())
+ {
+ if (gGLManager.mIsIntel)
+ {
+ LLNotificationsUtil::add("IntelOldDriver");
+ }
+ else if (gGLManager.mIsNVIDIA)
+ {
+ LLNotificationsUtil::add("NVIDIAOldDriver");
+ }
+ else if (gGLManager.mIsATI)
+ {
+ LLNotificationsUtil::add("AMDOldDriver");
+ }
+ }
+#endif
+
// save the graphics card
gDebugInfo["GraphicsCard"] = LLFeatureManager::getInstance()->getGPUString();
@@ -1038,11 +1133,38 @@ bool LLAppViewer::init()
gGLActive = FALSE;
+
+ // Iterate over --leap command-line options. But this is a bit tricky: if
+ // there's only one, it won't be an array at all.
+ LLSD LeapCommand(gSavedSettings.getLLSD("LeapCommand"));
+ LL_DEBUGS("InitInfo") << "LeapCommand: " << LeapCommand << LL_ENDL;
+ if (LeapCommand.isDefined() && ! LeapCommand.isArray())
+ {
+ // If LeapCommand is actually a scalar value, make an array of it.
+ // Have to do it in two steps because LeapCommand.append(LeapCommand)
+ // trashes content! :-P
+ LLSD item(LeapCommand);
+ LeapCommand.append(item);
+ }
+ BOOST_FOREACH(const std::string& leap, llsd::inArray(LeapCommand))
+ {
+ LL_INFOS("InitInfo") << "processing --leap \"" << leap << '"' << LL_ENDL;
+ // We don't have any better description of this plugin than the
+ // user-specified command line. Passing "" causes LLLeap to derive a
+ // description from the command line itself.
+ // Suppress LLLeap::Error exception: trust LLLeap's own logging. We
+ // don't consider any one --leap command mission-critical, so if one
+ // fails, log it, shrug and carry on.
+ LLLeap::create("", leap, false); // exception=false
+ }
+
if (gSavedSettings.getBOOL("QAMode") && gSavedSettings.getS32("QAModeEventHostPort") > 0)
{
- loadEventHostModule(gSavedSettings.getS32("QAModeEventHostPort"));
+ LL_WARNS("InitInfo") << "QAModeEventHostPort DEPRECATED: "
+ << "lleventhost no longer supported as a dynamic library"
+ << LL_ENDL;
}
-
+
LLViewerMedia::initClass();
LL_INFOS("InitInfo") << "Viewer media initialized." << LL_ENDL ;
@@ -1123,6 +1245,8 @@ void LLAppViewer::checkMemory()
static LLFastTimer::DeclareTimer FTM_MESSAGES("System Messages");
static LLFastTimer::DeclareTimer FTM_SLEEP("Sleep");
+static LLFastTimer::DeclareTimer FTM_YIELD("Yield");
+
static LLFastTimer::DeclareTimer FTM_TEXTURE_CACHE("Texture Cache");
static LLFastTimer::DeclareTimer FTM_DECODE("Image Decode");
static LLFastTimer::DeclareTimer FTM_VFS("VFS Thread");
@@ -1136,45 +1260,64 @@ static LLFastTimer::DeclareTimer FTM_SERVICE_CALLBACK("Callback");
static LLFastTimer::DeclareTimer FTM_AGENT_AUTOPILOT("Autopilot");
static LLFastTimer::DeclareTimer FTM_AGENT_UPDATE("Update");
+LLFastTimer::DeclareTimer FTM_FRAME("Frame", true);
+
bool LLAppViewer::mainLoop()
{
- LLMemType mt1(LLMemType::MTYPE_MAIN);
- mMainloopTimeout = new LLWatchdogTimeout();
+#ifdef LL_DARWIN
+ if (!mMainLoopInitialized)
+#endif
+ {
+ mMainloopTimeout = new LLWatchdogTimeout();
+
+ //-------------------------------------------
+ // Run main loop until time to quit
+ //-------------------------------------------
+
+ // Create IO Pump to use for HTTP Requests.
+ gServicePump = new LLPumpIO(gAPRPoolp);
+ LLHTTPClient::setPump(*gServicePump);
+ LLCurl::setCAFile(gDirUtilp->getCAFile());
+
+ // Note: this is where gLocalSpeakerMgr and gActiveSpeakerMgr used to be instantiated.
+
+ LLVoiceChannel::initClass();
+ LLVoiceClient::getInstance()->init(gServicePump);
+ LLVoiceChannel::setCurrentVoiceChannelChangedCallback(boost::bind(&LLFloaterIMContainer::onCurrentChannelChanged, _1), true);
+
+ joystick = LLViewerJoystick::getInstance();
+ joystick->setNeedsReset(true);
+
+#ifdef LL_DARWIN
+ // Ensure that this section of code never gets called again on OS X.
+ mMainLoopInitialized = true;
+#endif
+ }
+ // As we do not (yet) send data on the mainloop LLEventPump that varies
+ // with each frame, no need to instantiate a new LLSD event object each
+ // time. Obviously, if that changes, just instantiate the LLSD at the
+ // point of posting.
+
+ LLEventPump& mainloop(LLEventPumps::instance().obtain("mainloop"));
+
+ LLSD newFrame;
- //-------------------------------------------
- // Run main loop until time to quit
- //-------------------------------------------
-
- // Create IO Pump to use for HTTP Requests.
- gServicePump = new LLPumpIO(gAPRPoolp);
- LLHTTPClient::setPump(*gServicePump);
- LLCurl::setCAFile(gDirUtilp->getCAFile());
-
- // Note: this is where gLocalSpeakerMgr and gActiveSpeakerMgr used to be instantiated.
-
- LLVoiceChannel::initClass();
- LLVoiceClient::getInstance()->init(gServicePump);
- LLVoiceChannel::setCurrentVoiceChannelChangedCallback(boost::bind(&LLCallFloater::sOnCurrentChannelChanged, _1), true);
LLTimer frameTimer,idleTimer;
LLTimer debugTime;
- LLViewerJoystick* joystick(LLViewerJoystick::getInstance());
- joystick->setNeedsReset(true);
-
- LLEventPump& mainloop(LLEventPumps::instance().obtain("mainloop"));
- // As we do not (yet) send data on the mainloop LLEventPump that varies
- // with each frame, no need to instantiate a new LLSD event object each
- // time. Obviously, if that changes, just instantiate the LLSD at the
- // point of posting.
- LLSD newFrame;
-
+
//LLPrivateMemoryPoolTester::getInstance()->run(false) ;
//LLPrivateMemoryPoolTester::getInstance()->run(true) ;
//LLPrivateMemoryPoolTester::destroy() ;
// Handle messages
+#ifdef LL_DARWIN
+ if (!LLApp::isExiting())
+#else
while (!LLApp::isExiting())
+#endif
{
- LLFastTimer::nextFrame(); // Should be outside of any timer instances
+ LLFastTimer _(FTM_FRAME);
+ LLFastTimer::nextFrame();
//clear call stack records
llclearcallstacks;
@@ -1219,7 +1362,7 @@ bool LLAppViewer::mainLoop()
if(mem_leak_instance)
{
mem_leak_instance->idle() ;
- }
+ }
// canonical per-frame event
mainloop.post(newFrame);
@@ -1238,7 +1381,6 @@ bool LLAppViewer::mainLoop()
&& (gHeadlessClient || !gViewerWindow->getShowProgress())
&& !gFocusMgr.focusLocked())
{
- LLMemType mjk(LLMemType::MTYPE_JOY_KEY);
joystick->scanJoystick();
gKeyboard->scanKeyboard();
}
@@ -1252,7 +1394,6 @@ bool LLAppViewer::mainLoop()
if (gAres != NULL && gAres->isInitialized())
{
- LLMemType mt_ip(LLMemType::MTYPE_IDLE_PUMP);
pingMainloopTimeout("Main:ServicePump");
LLFastTimer t4(FTM_PUMP);
{
@@ -1302,12 +1443,12 @@ bool LLAppViewer::mainLoop()
// Sleep and run background threads
{
- LLMemType mt_sleep(LLMemType::MTYPE_SLEEP);
LLFastTimer t2(FTM_SLEEP);
// yield some time to the os based on command line option
if(mYieldTime >= 0)
{
+ LLFastTimer t(FTM_YIELD);
ms_sleep(mYieldTime);
}
@@ -1340,13 +1481,11 @@ bool LLAppViewer::mainLoop()
ms_sleep(500);
}
- static const F64 FRAME_SLOW_THRESHOLD = 0.5; //2 frames per seconds
const F64 max_idle_time = llmin(.005*10.0*gFrameTimeSeconds, 0.005); // 5 ms a second
idleTimer.reset();
- bool is_slow = (frameTimer.getElapsedTimeF64() > FRAME_SLOW_THRESHOLD) ;
S32 total_work_pending = 0;
S32 total_io_pending = 0;
- while(!is_slow)//do not unpause threads if the frame rates are very low.
+ while(1)
{
S32 work_pending = 0;
S32 io_pending = 0;
@@ -1406,6 +1545,17 @@ bool LLAppViewer::mainLoop()
LLLFSThread::sLocal->pause();
}
+ //texture fetching debugger
+ if(LLTextureFetchDebugger::isEnabled())
+ {
+ LLFloaterTextureFetchDebugger* tex_fetch_debugger_instance =
+ LLFloaterReg::findTypedInstance<LLFloaterTextureFetchDebugger>("tex_fetch_debugger");
+ if(tex_fetch_debugger_instance)
+ {
+ tex_fetch_debugger_instance->idle() ;
+ }
+ }
+
if ((LLStartUp::getStartupState() >= STATE_CLEANUP) &&
(frameTimer.getElapsedTimeF64() > FRAME_STALL_THRESHOLD))
{
@@ -1440,34 +1590,37 @@ bool LLAppViewer::mainLoop()
}
}
- // Save snapshot for next time, if we made it through initialization
- if (STATE_STARTED == LLStartUp::getStartupState())
+ if (LLApp::isExiting())
{
- try
- {
- saveFinalSnapshot();
- }
- catch(std::bad_alloc)
+ // Save snapshot for next time, if we made it through initialization
+ if (STATE_STARTED == LLStartUp::getStartupState())
{
- llwarns << "Bad memory allocation when saveFinalSnapshot() is called!" << llendl ;
-
- //stop memory leaking simulation
- LLFloaterMemLeak* mem_leak_instance =
- LLFloaterReg::findTypedInstance<LLFloaterMemLeak>("mem_leaking");
- if(mem_leak_instance)
+ try
{
- mem_leak_instance->stop() ;
- }
+ saveFinalSnapshot();
+ }
+ catch(std::bad_alloc)
+ {
+ llwarns << "Bad memory allocation when saveFinalSnapshot() is called!" << llendl ;
+
+ //stop memory leaking simulation
+ LLFloaterMemLeak* mem_leak_instance =
+ LLFloaterReg::findTypedInstance<LLFloaterMemLeak>("mem_leaking");
+ if(mem_leak_instance)
+ {
+ mem_leak_instance->stop() ;
+ }
+ }
}
+
+ delete gServicePump;
+
+ destroyMainloopTimeout();
+
+ llinfos << "Exiting main_loop" << llendflush;
}
-
- delete gServicePump;
-
- destroyMainloopTimeout();
-
- llinfos << "Exiting main_loop" << llendflush;
- return true;
+ return LLApp::isExiting();
}
void LLAppViewer::flushVFSIO()
@@ -1490,6 +1643,8 @@ bool LLAppViewer::cleanup()
//ditch LLVOAvatarSelf instance
gAgentAvatarp = NULL;
+ LLNotifications::instance().clear();
+
// workaround for DEV-35406 crash on shutdown
LLEventPumps::instance().reset();
@@ -1511,21 +1666,27 @@ bool LLAppViewer::cleanup()
if (! isError())
{
std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "");
- logdir += gDirUtilp->getDirDelimiter();
gDirUtilp->deleteFilesInDir(logdir, "*-*-*-*-*.dmp");
}
- // *TODO - generalize this and move DSO wrangling to a helper class -brad
- std::set<struct apr_dso_handle_t *>::const_iterator i;
- for(i = mPlugins.begin(); i != mPlugins.end(); ++i)
{
- int (*ll_plugin_stop_func)(void) = NULL;
- apr_status_t rv = apr_dso_sym((apr_dso_handle_sym_t*)&ll_plugin_stop_func, *i, "ll_plugin_stop");
- ll_plugin_stop_func();
-
- rv = apr_dso_unload(*i);
- }
- mPlugins.clear();
+ // Kill off LLLeap objects. We can find them all because LLLeap is derived
+ // from LLInstanceTracker. But collect instances first: LLInstanceTracker
+ // specifically forbids adding/deleting instances while iterating.
+ std::vector<LLLeap*> leaps;
+ leaps.reserve(LLLeap::instanceCount());
+ for (LLLeap::instance_iter li(LLLeap::beginInstances()), lend(LLLeap::endInstances());
+ li != lend; ++li)
+ {
+ leaps.push_back(&*li);
+ }
+ // Okay, now trash them all. We don't have to NULL or erase the entry
+ // in 'leaps' because the whole vector is going away momentarily.
+ BOOST_FOREACH(LLLeap* leap, leaps)
+ {
+ delete leap;
+ }
+ } // destroy 'leaps'
//flag all elements as needing to be destroyed immediately
// to ensure shutdown order
@@ -1548,6 +1709,9 @@ bool LLAppViewer::cleanup()
// shut down mesh streamer
gMeshRepo.shutdown();
+ // shut down Havok
+ LLPhysicsExtensions::quitSystem();
+
// Must clean up texture references before viewer window is destroyed.
if(LLHUDManager::instanceExists())
{
@@ -1597,19 +1761,7 @@ bool LLAppViewer::cleanup()
gAudiop->setStreamingAudioImpl(NULL);
// shut down the audio subsystem
-
- bool want_longname = false;
- if (gAudiop->getDriverName(want_longname) == "FMOD")
- {
- // This hack exists because fmod likes to occasionally
- // crash or hang forever when shutting down, for no
- // apparent reason.
- llwarns << "Hack, skipping FMOD audio engine cleanup" << llendflush;
- }
- else
- {
gAudiop->shutdown();
- }
delete gAudiop;
gAudiop = NULL;
@@ -1682,6 +1834,10 @@ bool LLAppViewer::cleanup()
llinfos << "Cleaning up Objects" << llendflush;
LLViewerObject::cleanupVOClasses();
+
+ LLAvatarAppearance::cleanupClass();
+
+ LLAvatarAppearance::cleanupClass();
LLPostProcess::cleanupClass();
@@ -1742,6 +1898,13 @@ bool LLAppViewer::cleanup()
{
llinfos << "Not saving per-account settings; don't know the account name yet." << llendl;
}
+ // Only save per account settings if the previous login succeeded, otherwise
+ // we might end up with a cleared out settings file in case a previous login
+ // failed after loading per account settings.
+ else if (!mSavePerAccountSettings)
+ {
+ llinfos << "Not saving per-account settings; last login was not successful." << llendl;
+ }
else
{
gSavedPerAccountSettings.saveToFile(gSavedSettings.getString("PerAccountSettingsFile"), TRUE);
@@ -1757,11 +1920,13 @@ bool LLAppViewer::cleanup()
// save mute list. gMuteList used to also be deleted here too.
LLMuteList::getInstance()->cache(gAgent.getID());
+ //save call log list
+ LLConversationLog::instance().cache();
+
if (mPurgeOnExit)
{
llinfos << "Purging all cache files on exit" << llendflush;
- std::string mask = gDirUtilp->getDirDelimiter() + "*.*";
- gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE,""),mask);
+ gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE,""), "*.*");
}
removeMarkerFile(); // Any crashes from here on we'll just have to ignore
@@ -1807,6 +1972,7 @@ bool LLAppViewer::cleanup()
// Delete workers first
// shotdown all worker threads before deleting them in case of co-dependencies
+ mAppCoreHttp.requestStop();
sTextureFetch->shutdown();
sTextureCache->shutdown();
sImageDecodeThread->shutdown();
@@ -1814,8 +1980,20 @@ bool LLAppViewer::cleanup()
sTextureFetch->shutDownTextureCacheThread() ;
sTextureFetch->shutDownImageDecodeThread() ;
+ llinfos << "Shutting down message system" << llendflush;
+ end_messaging_system();
+
+ // *NOTE:Mani - The following call is not thread safe.
+ LL_CHECK_MEMORY
+ LLCurl::cleanupClass();
+ LL_CHECK_MEMORY
+
+ // Non-LLCurl libcurl library
+ mAppCoreHttp.cleanup();
+
LLFilePickerThread::cleanupClass();
+ //MUST happen AFTER LLCurl::cleanupClass
delete sTextureCache;
sTextureCache = NULL;
delete sTextureFetch;
@@ -1841,10 +2019,6 @@ bool LLAppViewer::cleanup()
LLMetricPerformanceTesterBasic::cleanClass() ;
-#if LL_RECORD_VIEWER_STATS
- LLViewerStatsRecorder::cleanupClass();
-#endif
-
llinfos << "Cleaning up Media and Textures" << llendflush;
//Note:
@@ -1884,12 +2058,6 @@ bool LLAppViewer::cleanup()
LLViewerAssetStatsFF::cleanup();
- llinfos << "Shutting down message system" << llendflush;
- end_messaging_system();
-
- // *NOTE:Mani - The following call is not thread safe.
- LLCurl::cleanupClass();
-
// If we're exiting to launch an URL, do that here so the screen
// is at the right resolution before we launch IE.
if (!gLaunchFileOnQuit.empty())
@@ -1909,6 +2077,8 @@ bool LLAppViewer::cleanup()
llinfos << "Cleaning up LLProxy." << llendl;
LLProxy::cleanupClass();
+ LLWearableType::cleanupClass();
+
LLMainLoopRepeater::instance().stop();
//release all private memory pools.
@@ -1951,7 +2121,7 @@ bool LLAppViewer::initThreads()
static const bool enable_threads = true;
#endif
- LLImage::initClass();
+ LLImage::initClass(gSavedSettings.getBOOL("TextureNewByteRange"),gSavedSettings.getS32("TextureReverseByteRange"));
LLVFSThread::initClass(enable_threads && false);
LLLFSThread::initClass(enable_threads && false);
@@ -1992,7 +2162,7 @@ void errorCallback(const std::string &error_string)
LLError::crashAndLoop(error_string);
}
-bool LLAppViewer::initLogging()
+void LLAppViewer::initLoggingAndGetLastDuration()
{
//
// Set up logging defaults for the viewer
@@ -2006,17 +2176,61 @@ bool LLAppViewer::initLogging()
"SecondLife.old");
LLFile::remove(old_log_file);
- // Rename current log file to ".old"
+ // Get name of the log file
std::string log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,
"SecondLife.log");
+ /*
+ * Before touching any log files, compute the duration of the last run
+ * by comparing the ctime of the previous start marker file with the ctime
+ * of the last log file.
+ */
+ std::string start_marker_file_name = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, START_MARKER_FILE_NAME);
+ llstat start_marker_stat;
+ llstat log_file_stat;
+ std::ostringstream duration_log_stream; // can't log yet, so save any message for when we can below
+ int start_stat_result = LLFile::stat(start_marker_file_name, &start_marker_stat);
+ int log_stat_result = LLFile::stat(log_file, &log_file_stat);
+ if ( 0 == start_stat_result && 0 == log_stat_result )
+ {
+ int elapsed_seconds = log_file_stat.st_ctime - start_marker_stat.st_ctime;
+ // only report a last run time if the last viewer was the same version
+ // because this stat will be counted against this version
+ if ( markerIsSameVersion(start_marker_file_name) )
+ {
+ gLastExecDuration = elapsed_seconds;
+ }
+ else
+ {
+ duration_log_stream << "start marker from some other version; duration is not reported";
+ gLastExecDuration = -1;
+ }
+ }
+ else
+ {
+ // at least one of the LLFile::stat calls failed, so we can't compute the run time
+ duration_log_stream << "duration stat failure; start: "<< start_stat_result << " log: " << log_stat_result;
+ gLastExecDuration = -1; // unknown
+ }
+ std::string duration_log_msg(duration_log_stream.str());
+
+ // Create a new start marker file for comparison with log file time for the next run
+ LLAPRFile start_marker_file ;
+ start_marker_file.open(start_marker_file_name, LL_APR_WB);
+ if (start_marker_file.getFileHandle())
+ {
+ recordMarkerVersion(start_marker_file);
+ start_marker_file.close();
+ }
+
+ // Rename current log file to ".old"
LLFile::rename(log_file, old_log_file);
// Set the log file to SecondLife.log
-
LLError::logToFile(log_file);
-
- // *FIX:Mani no error handling here!
- return true;
+ if (!duration_log_msg.empty())
+ {
+ LL_WARNS("MarkerFile") << duration_log_msg << LL_ENDL;
+ }
}
bool LLAppViewer::loadSettingsFromDirectory(const std::string& location_key,
@@ -2041,13 +2255,13 @@ bool LLAppViewer::loadSettingsFromDirectory(const std::string& location_key,
BOOST_FOREACH(const SettingsFile& file, group.files)
{
- llinfos << "Attempting to load settings for the group " << file.name()
- << " - from location " << location_key << llendl;
+ LL_INFOS("Settings") << "Attempting to load settings for the group " << file.name()
+ << " - from location " << location_key << LL_ENDL;
LLControlGroup* settings_group = LLControlGroup::getInstance(file.name);
if(!settings_group)
{
- llwarns << "No matching settings group for name " << file.name() << llendl;
+ LL_WARNS("Settings") << "No matching settings group for name " << file.name() << LL_ENDL;
continue;
}
@@ -2076,7 +2290,7 @@ bool LLAppViewer::loadSettingsFromDirectory(const std::string& location_key,
if(settings_group->loadFromFile(full_settings_path, set_defaults, file.persistent))
{ // success!
- llinfos << "Loaded settings file " << full_settings_path << llendl;
+ LL_INFOS("Settings") << "Loaded settings file " << full_settings_path << LL_ENDL;
}
else
{ // failed to load
@@ -2090,7 +2304,7 @@ bool LLAppViewer::loadSettingsFromDirectory(const std::string& location_key,
// only complain if we actually have a filename at this point
if (!full_settings_path.empty())
{
- llinfos << "Cannot load " << full_settings_path << " - No settings found." << llendl;
+ LL_INFOS("Settings") << "Cannot load " << full_settings_path << " - No settings found." << LL_ENDL;
}
}
}
@@ -2125,17 +2339,24 @@ void LLAppViewer::loadColorSettings()
LLUIColorTable::instance().loadFromSettings();
}
+namespace
+{
+ void handleCommandLineError(LLControlGroupCLP& clp)
+ {
+ llwarns << "Error parsing command line options. Command Line options ignored." << llendl;
+
+ llinfos << "Command line usage:\n" << clp << llendl;
+
+ OSMessageBox(STRINGIZE(LLTrans::getString("MBCmdLineError") << clp.getErrorMessage()),
+ LLStringUtil::null,
+ OSMB_OK);
+ }
+} // anonymous namespace
+
bool LLAppViewer::initConfiguration()
{
//Load settings files list
std::string settings_file_list = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "settings_files.xml");
- //LLControlGroup settings_control("SettingsFiles");
- //llinfos << "Loading settings file list " << settings_file_list << llendl;
- //if (0 == settings_control.loadFromFile(settings_file_list))
- //{
- // llerrs << "Cannot load default configuration file " << settings_file_list << llendl;
- //}
-
LLXMLNodePtr root;
BOOL success = LLXMLNode::parseFile(settings_file_list, root, NULL);
if (!success)
@@ -2172,17 +2393,13 @@ bool LLAppViewer::initConfiguration()
OSMessageBox(msg.str(),LLStringUtil::null,OSMB_OK);
return false;
}
-
- LLUI::setupPaths(); // setup paths for LLTrans based on settings files only
- LLTransUtil::parseStrings("strings.xml", default_trans_args);
- LLTransUtil::parseLanguageStrings("language_settings.xml");
+
+ initStrings(); // setup paths for LLTrans based on settings files only
// - set procedural settings
// Note: can't use LL_PATH_PER_SL_ACCOUNT for any of these since we haven't logged in yet
gSavedSettings.setString("ClientSettingsFile",
gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, getSettingsFilename("Default", "Global")));
- gSavedSettings.setString("VersionChannelName", LLVersionInfo::getChannel());
-
#ifndef LL_RELEASE_FOR_DOWNLOAD
// provide developer build only overrides for these control variables that are not
// persisted to settings.xml
@@ -2196,9 +2413,7 @@ bool LLAppViewer::initConfiguration()
{
c->setValue(true, false);
}
-#endif
-#ifndef LL_RELEASE_FOR_DOWNLOAD
gSavedSettings.setBOOL("QAMode", TRUE );
gSavedSettings.setS32("WatchdogEnabled", 0);
#endif
@@ -2234,13 +2449,7 @@ bool LLAppViewer::initConfiguration()
if(!initParseCommandLine(clp))
{
- llwarns << "Error parsing command line options. Command Line options ignored." << llendl;
-
- llinfos << "Command line usage:\n" << clp << llendl;
-
- std::ostringstream msg;
- msg << LLTrans::getString("MBCmdLineError") << clp.getErrorMessage();
- OSMessageBox(msg.str(),LLStringUtil::null,OSMB_OK);
+ handleCommandLineError(clp);
return false;
}
@@ -2254,8 +2463,8 @@ bool LLAppViewer::initConfiguration()
gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS,
clp.getOption("settings")[0]);
gSavedSettings.setString("ClientSettingsFile", user_settings_filename);
- llinfos << "Using command line specified settings filename: "
- << user_settings_filename << llendl;
+ LL_INFOS("Settings") << "Using command line specified settings filename: "
+ << user_settings_filename << LL_ENDL;
}
// - load overrides from user_settings
@@ -2271,8 +2480,8 @@ bool LLAppViewer::initConfiguration()
{
std::string session_settings_filename = clp.getOption("sessionsettings")[0];
gSavedSettings.setString("SessionSettingsFile", session_settings_filename);
- llinfos << "Using session settings filename: "
- << session_settings_filename << llendl;
+ LL_INFOS("Settings") << "Using session settings filename: "
+ << session_settings_filename << LL_ENDL;
}
loadSettingsFromDirectory("Session");
@@ -2280,19 +2489,23 @@ bool LLAppViewer::initConfiguration()
{
std::string user_session_settings_filename = clp.getOption("usersessionsettings")[0];
gSavedSettings.setString("UserSessionSettingsFile", user_session_settings_filename);
- llinfos << "Using user session settings filename: "
- << user_session_settings_filename << llendl;
+ LL_INFOS("Settings") << "Using user session settings filename: "
+ << user_session_settings_filename << LL_ENDL;
}
loadSettingsFromDirectory("UserSession");
// - apply command line settings
- clp.notify();
+ if (! clp.notify())
+ {
+ handleCommandLineError(clp);
+ return false;
+ }
// Register the core crash option as soon as we can
// if we want gdb post-mortem on cores we need to be up and running
// ASAP or we might miss init issue etc.
- if(clp.hasOption("disablecrashlogger"))
+ if(gSavedSettings.getBOOL("DisableCrashLogger"))
{
llwarns << "Crashes will be handled by system, stack trace logs and crash logger are both disabled" << llendl;
LLAppViewer::instance()->disableCrashlogger();
@@ -2365,91 +2578,56 @@ bool LLAppViewer::initConfiguration()
}
}
- if(clp.hasOption("channel"))
+ if (clp.hasOption("logevents")) {
+ LLViewerEventRecorder::instance().setEventLoggingOn();
+ }
+
+ std::string CmdLineChannel(gSavedSettings.getString("CmdLineChannel"));
+ if(! CmdLineChannel.empty())
{
- LLVersionInfo::resetChannel(clp.getOption("channel")[0]);
+ LLVersionInfo::resetChannel(CmdLineChannel);
}
// If we have specified crash on startup, set the global so we'll trigger the crash at the right time
- if(clp.hasOption("crashonstartup"))
- {
- gCrashOnStartup = TRUE;
- }
+ gCrashOnStartup = gSavedSettings.getBOOL("CrashOnStartup");
- if (clp.hasOption("logperformance"))
+ if (gSavedSettings.getBOOL("LogPerformance"))
{
LLFastTimer::sLog = TRUE;
LLFastTimer::sLogName = std::string("performance");
}
- if (clp.hasOption("logmetrics"))
+ std::string test_name(gSavedSettings.getString("LogMetrics"));
+ if (! test_name.empty())
{
LLFastTimer::sMetricLog = TRUE ;
- // '--logmetrics' can be specified with a named test metric argument so the data gathering is done only on that test
- // In the absence of argument, every metric is gathered (makes for a rather slow run and hard to decipher report...)
- std::string test_name = clp.getOption("logmetrics")[0];
+ // '--logmetrics' is specified with a named test metric argument so the data gathering is done only on that test
+ // In the absence of argument, every metric would be gathered (makes for a rather slow run and hard to decipher report...)
llinfos << "'--logmetrics' argument : " << test_name << llendl;
- if (test_name == "")
- {
- llwarns << "No '--logmetrics' argument given, will output all metrics to " << DEFAULT_METRIC_NAME << llendl;
- LLFastTimer::sLogName = DEFAULT_METRIC_NAME;
- }
- else
- {
LLFastTimer::sLogName = test_name;
}
- }
if (clp.hasOption("graphicslevel"))
{
- const LLCommandLineParser::token_vector_t& value = clp.getOption("graphicslevel");
- if(value.size() != 1)
- {
- llwarns << "Usage: -graphicslevel <0-3>" << llendl;
- }
- else
+ // User explicitly requested --graphicslevel on the command line. We
+ // expect this switch has already set RenderQualityPerformance. Check
+ // that value for validity.
+ U32 graphicslevel = gSavedSettings.getU32("RenderQualityPerformance");
+ if (LLFeatureManager::instance().isValidGraphicsLevel(graphicslevel))
{
- std::string detail = value.front();
- mForceGraphicsDetail = TRUE;
-
- switch (detail.c_str()[0])
- {
- case '0':
- gSavedSettings.setU32("RenderQualityPerformance", 0);
- break;
- case '1':
- gSavedSettings.setU32("RenderQualityPerformance", 1);
- break;
- case '2':
- gSavedSettings.setU32("RenderQualityPerformance", 2);
- break;
- case '3':
- gSavedSettings.setU32("RenderQualityPerformance", 3);
- break;
- default:
- mForceGraphicsDetail = FALSE;
- llwarns << "Usage: -graphicslevel <0-3>" << llendl;
- break;
- }
+ // graphicslevel is valid: save it and engage it later. Capture
+ // the requested value separately from the settings variable
+ // because, if this is the first run, LLViewerWindow's constructor
+ // will call LLFeatureManager::applyRecommendedSettings(), which
+ // overwrites this settings variable!
+ mForceGraphicsLevel = graphicslevel;
}
}
- if (clp.hasOption("analyzeperformance"))
- {
- LLFastTimerView::sAnalyzePerformance = TRUE;
- }
-
- if (clp.hasOption("replaysession"))
- {
- gAgentPilot.setReplaySession(TRUE);
- }
+ LLFastTimerView::sAnalyzePerformance = gSavedSettings.getBOOL("AnalyzePerformance");
+ gAgentPilot.setReplaySession(gSavedSettings.getBOOL("ReplaySession"));
- if (clp.hasOption("nonotifications"))
- {
- gSavedSettings.getControl("IgnoreAllNotifications")->setValue(true, false);
- }
-
- if (clp.hasOption("debugsession"))
+ if (gSavedSettings.getBOOL("DebugSession"))
{
gDebugSession = TRUE;
gDebugGL = TRUE;
@@ -2474,29 +2652,56 @@ bool LLAppViewer::initConfiguration()
// What can happen is that someone can use IE (or potentially
// other browsers) and do the rough equivalent of command
// injection and steal passwords. Phoenix. SL-55321
- if(clp.hasOption("url"))
+ LLSLURL start_slurl;
+ std::string CmdLineLoginLocation(gSavedSettings.getString("CmdLineLoginLocation"));
+ if(! CmdLineLoginLocation.empty())
{
- LLStartUp::setStartSLURL(LLSLURL(clp.getOption("url")[0]));
- if(LLStartUp::getStartSLURL().getType() == LLSLURL::LOCATION)
+ start_slurl = CmdLineLoginLocation;
+ LLStartUp::setStartSLURL(start_slurl);
+ if(start_slurl.getType() == LLSLURL::LOCATION)
{
- LLGridManager::getInstance()->setGridChoice(LLStartUp::getStartSLURL().getGrid());
-
- }
+ LLGridManager::getInstance()->setGridChoice(start_slurl.getGrid());
}
- else if(clp.hasOption("slurl"))
- {
- LLSLURL start_slurl(clp.getOption("slurl")[0]);
- LLStartUp::setStartSLURL(start_slurl);
}
- const LLControlVariable* skinfolder = gSavedSettings.getControl("SkinCurrent");
- if(skinfolder && LLStringUtil::null != skinfolder->getValue().asString())
- {
- // hack to force the skin to default.
- gDirUtilp->setSkinFolder(skinfolder->getValue().asString());
- //gDirUtilp->setSkinFolder("default");
+ //RN: if we received a URL, hand it off to the existing instance.
+ // don't call anotherInstanceRunning() when doing URL handoff, as
+ // it relies on checking a marker file which will not work when running
+ // out of different directories
+
+ if (start_slurl.isValid() &&
+ (gSavedSettings.getBOOL("SLURLPassToOtherInstance")))
+ {
+ if (sendURLToOtherInstance(start_slurl.getSLURLString()))
+ {
+ // successfully handed off URL to existing instance, exit
+ return false;
+ }
}
+ const LLControlVariable* skinfolder = gSavedSettings.getControl("SkinCurrent");
+ if(skinfolder && LLStringUtil::null != skinfolder->getValue().asString())
+ {
+ // Examining "Language" may not suffice -- see LLUI::getLanguage()
+ // logic. Unfortunately LLUI::getLanguage() doesn't yet do us much
+ // good because we haven't yet called LLUI::initClass().
+ gDirUtilp->setSkinFolder(skinfolder->getValue().asString(),
+ gSavedSettings.getString("Language"));
+ }
+
+ if (gSavedSettings.getBOOL("SpellCheck"))
+ {
+ std::list<std::string> dict_list;
+ std::string dict_setting = gSavedSettings.getString("SpellCheckDictionary");
+ boost::split(dict_list, dict_setting, boost::is_any_of(std::string(",")));
+ if (!dict_list.empty())
+ {
+ LLSpellChecker::setUseSpellCheck(dict_list.front());
+ dict_list.pop_front();
+ LLSpellChecker::instance().setSecondaryDictionaries(dict_list);
+ }
+ }
+
mYieldTime = gSavedSettings.getS32("YieldTime");
// Read skin/branding settings if specified.
@@ -2513,8 +2718,6 @@ bool LLAppViewer::initConfiguration()
//}
#if LL_DARWIN
- // Initialize apple menubar and various callbacks
- init_apple_menu(LLTrans::getString("APP_NAME").c_str());
#if __ppc__
// If the CPU doesn't have Altivec (i.e. it's not at least a G4), don't go any further.
@@ -2578,75 +2781,120 @@ bool LLAppViewer::initConfiguration()
}
}
- // If automatic login from command line with --login switch
- // init StartSLURL location. In interactive login, LLPanelLogin
- // will take care of it.
- if ((clp.hasOption("login") || clp.hasOption("autologin")) && !clp.hasOption("url") && !clp.hasOption("slurl"))
+ //
+ // Check for another instance of the app running
+ //
+ if (mSecondInstance && !gSavedSettings.getBOOL("AllowMultipleViewers"))
{
- LLStartUp::setStartSLURL(LLSLURL(gSavedSettings.getString("LoginLocation")));
+ std::ostringstream msg;
+ msg << LLTrans::getString("MBAlreadyRunning");
+ OSMessageBox(
+ msg.str(),
+ LLStringUtil::null,
+ OSMB_OK);
+ return false;
}
- if (!gSavedSettings.getBOOL("AllowMultipleViewers"))
+ if (mSecondInstance)
{
- //
- // Check for another instance of the app running
- //
-
- mSecondInstance = anotherInstanceRunning();
-
- if (mSecondInstance)
+ // This is the second instance of SL. Turn off voice support,
+ // but make sure the setting is *not* persisted.
+ LLControlVariable* disable_voice = gSavedSettings.getControl("CmdLineDisableVoice");
+ if(disable_voice)
{
- std::ostringstream msg;
- msg << LLTrans::getString("MBAlreadyRunning");
- OSMessageBox(
- msg.str(),
- LLStringUtil::null,
- OSMB_OK);
- return false;
+ const BOOL DO_NOT_PERSIST = FALSE;
+ disable_voice->setValue(LLSD(TRUE), DO_NOT_PERSIST);
}
-
- initMarkerFile();
-
- checkForCrash();
- }
+ }
else
{
- mSecondInstance = anotherInstanceRunning();
-
- if (mSecondInstance)
- {
- // This is the second instance of SL. Turn off voice support,
- // but make sure the setting is *not* persisted.
- LLControlVariable* disable_voice = gSavedSettings.getControl("CmdLineDisableVoice");
- if(disable_voice)
- {
- const BOOL DO_NOT_PERSIST = FALSE;
- disable_voice->setValue(LLSD(TRUE), DO_NOT_PERSIST);
- }
- }
-
- initMarkerFile();
-
- if(!mSecondInstance)
- {
- checkForCrash();
- }
+ checkForCrash();
}
- // need to do this here - need to have initialized global settings first
+ // NextLoginLocation is set from the command line option
std::string nextLoginLocation = gSavedSettings.getString( "NextLoginLocation" );
if ( !nextLoginLocation.empty() )
{
+ LL_DEBUGS("AppInit")<<"set start from NextLoginLocation: "<<nextLoginLocation<<LL_ENDL;
LLStartUp::setStartSLURL(LLSLURL(nextLoginLocation));
- };
+ }
+ else if ( ( clp.hasOption("login") || clp.hasOption("autologin"))
+ && gSavedSettings.getString("CmdLineLoginLocation").empty())
+ {
+ // If automatic login from command line with --login switch
+ // init StartSLURL location.
+ std::string start_slurl_setting = gSavedSettings.getString("LoginLocation");
+ LL_DEBUGS("AppInit") << "start slurl setting '" << start_slurl_setting << "'" << LL_ENDL;
+ LLStartUp::setStartSLURL(LLSLURL(start_slurl_setting));
+ }
+ else
+ {
+ // the login location will be set by the login panel (see LLPanelLogin)
+ }
gLastRunVersion = gSavedSettings.getString("LastRunVersion");
loadColorSettings();
+ // Let anyone else who cares know that we've populated our settings
+ // variables.
+ for (LLControlGroup::key_iter ki(LLControlGroup::beginKeys()), kend(LLControlGroup::endKeys());
+ ki != kend; ++ki)
+ {
+ // For each named instance of LLControlGroup, send an event saying
+ // we've initialized an LLControlGroup instance by that name.
+ LLEventPumps::instance().obtain("LLControlGroup").post(LLSDMap("init", *ki));
+ }
+
return true; // Config was successful.
}
+// The following logic is replicated in initConfiguration() (to be able to get
+// some initial strings before we've finished initializing enough to know the
+// current language) and also in init() (to initialize for real). Somehow it
+// keeps growing, necessitating a method all its own.
+void LLAppViewer::initStrings()
+{
+ LLTransUtil::parseStrings("strings.xml", default_trans_args);
+ LLTransUtil::parseLanguageStrings("language_settings.xml");
+
+ // parseStrings() sets up the LLTrans substitution table. Add this one item.
+ LLTrans::setDefaultArg("[sourceid]", gSavedSettings.getString("sourceid"));
+
+ // Now that we've set "[sourceid]", have to go back through
+ // default_trans_args and reinitialize all those other keys because some
+ // of them, in turn, reference "[sourceid]".
+ BOOST_FOREACH(std::string key, default_trans_args)
+ {
+ std::string brackets(key), nobrackets(key);
+ // Invalid to inspect key[0] if key is empty(). But then, the entire
+ // body of this loop is pointless if key is empty().
+ if (key.empty())
+ continue;
+
+ if (key[0] != '[')
+ {
+ // key was passed without brackets. That means that 'nobrackets'
+ // is correct but 'brackets' is not.
+ brackets = STRINGIZE('[' << brackets << ']');
+ }
+ else
+ {
+ // key was passed with brackets. That means that 'brackets' is
+ // correct but 'nobrackets' is not. Erase the left bracket.
+ nobrackets.erase(0, 1);
+ std::string::size_type length(nobrackets.length());
+ if (length && nobrackets[length - 1] == ']')
+ {
+ nobrackets.erase(length - 1);
+ }
+ }
+ // Calling LLTrans::getString() is what embeds the other default
+ // translation strings into this one.
+ LLTrans::setDefaultArg(brackets, LLTrans::getString(nobrackets));
+ }
+}
+
namespace {
// *TODO - decide if there's a better place for these functions.
// do we need a file llupdaterui.cpp or something? -brad
@@ -2676,25 +2924,46 @@ namespace {
std::string notification_name;
void (*apply_callback)(LLSD const &, LLSD const &) = NULL;
+ /* Build up the notification name...
+ * it can be any of these, which are included here for the sake of grep:
+ * RequiredUpdateDownloadedDialog
+ * RequiredUpdateDownloadedVerboseDialog
+ * OtherChannelRequiredUpdateDownloadedDialog
+ * OtherChannelRequiredUpdateDownloadedVerbose
+ * DownloadBackgroundTip
+ * DownloadBackgroundDialog
+ * OtherChannelDownloadBackgroundTip
+ * OtherChannelDownloadBackgroundDialog
+ */
+ {
+ LL_DEBUGS("UpdaterService") << "data = ";
+ std::ostringstream data_dump;
+ LLSDSerialize::toNotation(data, data_dump);
+ LL_CONT << data_dump.str() << LL_ENDL;
+ }
+ if(data["channel"].asString() != LLVersionInfo::getChannel())
+ {
+ notification_name.append("OtherChannel");
+ }
if(data["required"].asBoolean())
{
if(LLStartUp::getStartupState() <= STATE_LOGIN_WAIT)
{
// The user never saw the progress bar.
apply_callback = &apply_update_ok_callback;
- notification_name = "RequiredUpdateDownloadedVerboseDialog";
+ notification_name += "RequiredUpdateDownloadedVerboseDialog";
}
else if(LLStartUp::getStartupState() < STATE_WORLD_INIT)
{
// The user is logging in but blocked.
apply_callback = &apply_update_ok_callback;
- notification_name = "RequiredUpdateDownloadedDialog";
+ notification_name += "RequiredUpdateDownloadedDialog";
}
else
{
// The user is already logged in; treat like an optional update.
apply_callback = &apply_update_callback;
- notification_name = "DownloadBackgroundTip";
+ notification_name += "DownloadBackgroundTip";
}
}
else
@@ -2704,16 +2973,26 @@ namespace {
{
// CHOP-262 we need to use a different notification
// method prior to login.
- notification_name = "DownloadBackgroundDialog";
+ notification_name += "DownloadBackgroundDialog";
}
else
{
- notification_name = "DownloadBackgroundTip";
+ notification_name += "DownloadBackgroundTip";
}
}
LLSD substitutions;
substitutions["VERSION"] = data["version"];
+ std::string new_channel = data["channel"].asString();
+ substitutions["NEW_CHANNEL"] = new_channel;
+ std::string info_url = data["info_url"].asString();
+ if ( !info_url.empty() )
+ {
+ substitutions["INFO_URL"] = info_url;
+ }
+ else
+ {
+ LL_WARNS("UpdaterService") << "no info url supplied - defaulting to hard coded release notes pattern" << LL_ENDL;
// truncate version at the rightmost '.'
std::string version_short(data["version"]);
@@ -2732,7 +3011,8 @@ namespace {
relnotes_url.setArg("[CHANNEL_URL]", channel_escaped.get());
relnotes_url.setArg("[RELEASE_NOTES_BASE_URL]", LLTrans::getString("RELEASE_NOTES_BASE_URL"));
- substitutions["RELEASE_NOTES_FULL_URL"] = relnotes_url.getString();
+ substitutions["INFO_URL"] = relnotes_url.getString();
+ }
LLNotificationsUtil::add(notification_name, substitutions, LLSD(), apply_callback);
}
@@ -2775,22 +3055,50 @@ namespace {
void LLAppViewer::initUpdater()
{
// Initialize the updater service.
- // Generate URL to the udpater service
// Get Channel
// Get Version
- std::string url = gSavedSettings.getString("UpdaterServiceURL");
+
+ /*****************************************************************
+ * Previously, the url was derived from the settings
+ * UpdaterServiceURL
+ * UpdaterServicePath
+ * it is now obtained from the grid manager. The settings above
+ * are no longer used.
+ *****************************************************************/
std::string channel = LLVersionInfo::getChannel();
std::string version = LLVersionInfo::getVersion();
- std::string protocol_version = gSavedSettings.getString("UpdaterServiceProtocolVersion");
- std::string service_path = gSavedSettings.getString("UpdaterServicePath");
+
U32 check_period = gSavedSettings.getU32("UpdaterServiceCheckPeriod");
+ bool willing_to_test;
+ LL_DEBUGS("UpdaterService") << "channel " << channel << LL_ENDL;
+ static const boost::regex is_test_channel("\\bTest$");
+ if (boost::regex_search(channel, is_test_channel))
+ {
+ LL_INFOS("UpdaterService") << "Test build: overriding willing_to_test by sending testno" << LL_ENDL;
+ willing_to_test = false;
+ }
+ else
+ {
+ willing_to_test = gSavedSettings.getBOOL("UpdaterWillingToTest");
+ }
+ unsigned char unique_id[MD5HEX_STR_SIZE];
+ if ( ! llHashedUniqueID(unique_id) )
+ {
+ if ( willing_to_test )
+ {
+ LL_WARNS("UpdaterService") << "Unable to provide a unique id; overriding willing_to_test by sending testno" << LL_ENDL;
+ }
+ willing_to_test = false;
+ }
mUpdater->setAppExitCallback(boost::bind(&LLAppViewer::forceQuit, this));
- mUpdater->initialize(protocol_version,
- url,
- service_path,
- channel,
- version);
+ mUpdater->initialize(channel,
+ version,
+ gPlatform,
+ getOSInfo().getOSVersionString(),
+ unique_id,
+ willing_to_test
+ );
mUpdater->setCheckPeriod(check_period);
mUpdater->setBandwidthLimit((int)gSavedSettings.getF32("UpdaterMaximumBandwidth") * (1024/8));
gSavedSettings.getControl("UpdaterMaximumBandwidth")->getSignal()->
@@ -2889,9 +3197,10 @@ bool LLAppViewer::initWindow()
// Initialize GL stuff
//
- if (mForceGraphicsDetail)
+ if (mForceGraphicsLevel)
{
- LLFeatureManager::getInstance()->setGraphicsLevel(gSavedSettings.getU32("RenderQualityPerformance"), false);
+ LLFeatureManager::getInstance()->setGraphicsLevel(*mForceGraphicsLevel, false);
+ gSavedSettings.setU32("RenderQualityPerformance", *mForceGraphicsLevel);
}
// Set this flag in case we crash while initializing GL
@@ -2995,8 +3304,7 @@ void LLAppViewer::cleanupSavedSettings()
void LLAppViewer::removeCacheFiles(const std::string& file_mask)
{
- std::string mask = gDirUtilp->getDirDelimiter() + file_mask;
- gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, ""), mask);
+ gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, ""), file_mask);
}
void LLAppViewer::writeSystemInfo()
@@ -3023,8 +3331,8 @@ void LLAppViewer::writeSystemInfo()
gDebugInfo["OSInfo"] = getOSInfo().getOSStringSimple();
// The user is not logged on yet, but record the current grid choice login url
- // which may have been the intended grid. This can b
- gDebugInfo["GridName"] = LLGridManager::getInstance()->getGridLabel();
+ // which may have been the intended grid.
+ gDebugInfo["GridName"] = LLGridManager::getInstance()->getGridId();
// *FIX:Mani - move this down in llappviewerwin32
#ifdef LL_WINDOWS
@@ -3049,8 +3357,8 @@ void LLAppViewer::writeSystemInfo()
}
// Dump some debugging info
- LL_INFOS("SystemInfo") << LLTrans::getString("APP_NAME")
- << " version " << LLVersionInfo::getShortVersion() << LL_ENDL;
+ LL_INFOS("SystemInfo") << "Application: " << LLTrans::getString("APP_NAME") << LL_ENDL;
+ LL_INFOS("SystemInfo") << "Version: " << LLVersionInfo::getChannelAndVersion() << LL_ENDL;
// Dump the local time and time zone
time_t now;
@@ -3065,8 +3373,6 @@ void LLAppViewer::writeSystemInfo()
LL_INFOS("SystemInfo") << "OS: " << getOSInfo().getOSStringSimple() << LL_ENDL;
LL_INFOS("SystemInfo") << "OS info: " << getOSInfo() << LL_ENDL;
- LL_INFOS("SystemInfo") << "Timers: " << LLFastTimer::sClockType << LL_ENDL;
-
writeDebugInfo(); // Save out debug_info.log early, in case of crash.
}
@@ -3178,22 +3484,26 @@ void LLAppViewer::handleViewerCrash()
//we're already in a crash situation
if (gDirUtilp)
{
- std::string crash_file_name;
- if(gLLErrorActivated) crash_file_name = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,LLERROR_MARKER_FILE_NAME);
- else crash_file_name = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,ERROR_MARKER_FILE_NAME);
- llinfos << "Creating crash marker file " << crash_file_name << llendl;
-
- LLAPRFile crash_file ;
- crash_file.open(crash_file_name, LL_APR_W);
- if (crash_file.getFileHandle())
+ std::string crash_marker_file_name = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,
+ gLLErrorActivated
+ ? LLERROR_MARKER_FILE_NAME
+ : ERROR_MARKER_FILE_NAME);
+ LLAPRFile crash_marker_file ;
+ crash_marker_file.open(crash_marker_file_name, LL_APR_WB);
+ if (crash_marker_file.getFileHandle())
{
- LL_INFOS("MarkerFile") << "Created crash marker file " << crash_file_name << LL_ENDL;
+ LL_INFOS("MarkerFile") << "Created crash marker file " << crash_marker_file_name << LL_ENDL;
+ recordMarkerVersion(crash_marker_file);
}
else
{
- LL_WARNS("MarkerFile") << "Cannot create error marker file " << crash_file_name << LL_ENDL;
- }
+ LL_WARNS("MarkerFile") << "Cannot create error marker file " << crash_marker_file_name << LL_ENDL;
+ }
}
+ else
+ {
+ LL_WARNS("MarkerFile") << "No gDirUtilp with which to create error marker file name" << LL_ENDL;
+ }
if (gMessageSystem && gDirUtilp)
{
@@ -3239,46 +3549,52 @@ void LLAppViewer::handleViewerCrash()
return;
}
-bool LLAppViewer::anotherInstanceRunning()
+// static
+void LLAppViewer::recordMarkerVersion(LLAPRFile& marker_file)
+{
+ std::string marker_version(LLVersionInfo::getChannelAndVersion());
+ if ( marker_version.length() > MAX_MARKER_LENGTH )
+ {
+ LL_WARNS_ONCE("MarkerFile") << "Version length ("<< marker_version.length()<< ")"
+ << " greater than maximum (" << MAX_MARKER_LENGTH << ")"
+ << ": marker matching may be incorrect"
+ << LL_ENDL;
+ }
+
+ // record the viewer version in the marker file
+ marker_file.write(marker_version.data(), marker_version.length());
+}
+
+bool LLAppViewer::markerIsSameVersion(const std::string& marker_name) const
{
- // We create a marker file when the program starts and remove the file when it finishes.
- // If the file is currently locked, that means another process is already running.
+ bool sameVersion = false;
- std::string marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, MARKER_FILE_NAME);
- LL_DEBUGS("MarkerFile") << "Checking marker file for lock..." << LL_ENDL;
+ std::string my_version(LLVersionInfo::getChannelAndVersion());
+ char marker_version[MAX_MARKER_LENGTH];
+ S32 marker_version_length;
- //Freeze case checks
- if (LLAPRFile::isExist(marker_file, NULL, LL_APR_RB))
+ LLAPRFile marker_file;
+ marker_file.open(marker_name, LL_APR_RB);
+ if (marker_file.getFileHandle())
{
- // File exists, try opening with write permissions
- LLAPRFile outfile ;
- outfile.open(marker_file, LL_APR_WB);
- apr_file_t* fMarker = outfile.getFileHandle() ;
- if (!fMarker)
+ marker_version_length = marker_file.read(marker_version, sizeof(marker_version));
+ std::string marker_string(marker_version, marker_version_length);
+ if ( 0 == my_version.compare( 0, my_version.length(), marker_version, 0, marker_version_length ) )
{
- // Another instance is running. Skip the rest of these operations.
- LL_INFOS("MarkerFile") << "Marker file is locked." << LL_ENDL;
- return true;
+ sameVersion = true;
}
- if (apr_file_lock(fMarker, APR_FLOCK_NONBLOCK | APR_FLOCK_EXCLUSIVE) != APR_SUCCESS) //flock(fileno(fMarker), LOCK_EX | LOCK_NB) == -1)
- {
- LL_INFOS("MarkerFile") << "Marker file is locked." << LL_ENDL;
- return true;
- }
- // No other instances; we'll lock this file now & delete on quit.
- }
- LL_DEBUGS("MarkerFile") << "Marker file isn't locked." << LL_ENDL;
- return false;
+ LL_DEBUGS("MarkerFile") << "Compare markers for '" << marker_name << "': "
+ << "\n mine '" << my_version << "'"
+ << "\n marker '" << marker_string << "'"
+ << "\n " << ( sameVersion ? "same" : "different" ) << " version"
+ << LL_ENDL;
+ marker_file.close();
+ }
+ return sameVersion;
}
-void LLAppViewer::initMarkerFile()
+void LLAppViewer::processMarkerFiles()
{
- //First, check for the existence of other files.
- //There are marker files for two different types of crashes
-
- mMarkerFileName = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,MARKER_FILE_NAME);
- LL_DEBUGS("MarkerFile") << "Checking marker file for lock..." << LL_ENDL;
-
//We've got 4 things to test for here
// - Other Process Running (SecondLife.exec_marker present, locked)
// - Freeze (SecondLife.exec_marker present, not locked)
@@ -3286,78 +3602,179 @@ void LLAppViewer::initMarkerFile()
// - Other Crash (SecondLife.error_marker present)
// These checks should also remove these files for the last 2 cases if they currently exist
- //LLError/Error checks. Only one of these should ever happen at a time.
- std::string logout_marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, LOGOUT_MARKER_FILE_NAME);
- std::string llerror_marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, LLERROR_MARKER_FILE_NAME);
- std::string error_marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, ERROR_MARKER_FILE_NAME);
+ bool marker_is_same_version = true;
+ // first, look for the marker created at startup and deleted on a clean exit
+ mMarkerFileName = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,MARKER_FILE_NAME);
+ if (LLAPRFile::isExist(mMarkerFileName, NULL, LL_APR_RB))
+ {
+ // File exists...
+ // first, read it to see if it was created by the same version (we need this later)
+ marker_is_same_version = markerIsSameVersion(mMarkerFileName);
+
+ // now test to see if this file is locked by a running process (try to open for write)
+ LL_DEBUGS("MarkerFile") << "Checking exec marker file for lock..." << LL_ENDL;
+ mMarkerFile.open(mMarkerFileName, LL_APR_WB);
+ apr_file_t* fMarker = mMarkerFile.getFileHandle() ;
+ if (!fMarker)
+ {
+ LL_INFOS("MarkerFile") << "Exec marker file open failed - assume it is locked." << LL_ENDL;
+ mSecondInstance = true; // lock means that instance is running.
+ }
+ else
+ {
+ // We were able to open it, now try to lock it ourselves...
+ if (apr_file_lock(fMarker, APR_FLOCK_NONBLOCK | APR_FLOCK_EXCLUSIVE) != APR_SUCCESS)
+ {
+ LL_WARNS_ONCE("MarkerFile") << "Locking exec marker failed." << LL_ENDL;
+ mSecondInstance = true; // lost a race? be conservative
+ }
+ else
+ {
+ // No other instances; we've locked this file now, so record our version; delete on quit.
+ recordMarkerVersion(mMarkerFile);
+ LL_DEBUGS("MarkerFile") << "Exec marker file existed but was not locked; rewritten." << LL_ENDL;
+ }
+ }
- if (LLAPRFile::isExist(mMarkerFileName, NULL, LL_APR_RB) && !anotherInstanceRunning())
+ if (mSecondInstance)
+ {
+ LL_INFOS("MarkerFile") << "Exec marker '"<< mMarkerFileName << "' owned by another instance" << LL_ENDL;
+ }
+ else if (marker_is_same_version)
+ {
+ // the file existed, is ours, and matched our version, so we can report on what it says
+ LL_INFOS("MarkerFile") << "Exec marker '"<< mMarkerFileName << "' found; last exec FROZE" << LL_ENDL;
+ gLastExecEvent = LAST_EXEC_FROZE;
+
+ }
+ else
+ {
+ LL_INFOS("MarkerFile") << "Exec marker '"<< mMarkerFileName << "' found, but versions did not match" << LL_ENDL;
+ }
+ }
+ else // marker did not exist... last exec (if any) did not freeze
{
- gLastExecEvent = LAST_EXEC_FROZE;
- LL_INFOS("MarkerFile") << "Exec marker found: program froze on previous execution" << LL_ENDL;
- }
+ // Create the marker file for this execution & lock it; it will be deleted on a clean exit
+ apr_status_t s;
+ s = mMarkerFile.open(mMarkerFileName, LL_APR_WB, TRUE);
+
+ if (s == APR_SUCCESS && mMarkerFile.getFileHandle())
+ {
+ LL_DEBUGS("MarkerFile") << "Exec marker file '"<< mMarkerFileName << "' created." << LL_ENDL;
+ if (APR_SUCCESS == apr_file_lock(mMarkerFile.getFileHandle(), APR_FLOCK_NONBLOCK | APR_FLOCK_EXCLUSIVE))
+ {
+ recordMarkerVersion(mMarkerFile);
+ LL_DEBUGS("MarkerFile") << "Exec marker file locked." << LL_ENDL;
+ }
+ else
+ {
+ LL_WARNS("MarkerFile") << "Exec marker file cannot be locked." << LL_ENDL;
+ }
+ }
+ else
+ {
+ LL_WARNS("MarkerFile") << "Failed to create exec marker file '"<< mMarkerFileName << "'." << LL_ENDL;
+ }
+ }
+
+ // now check for cases in which the exec marker may have been cleaned up by crash handlers
+
+ // check for any last exec event report based on whether or not it happened during logout
+ // (the logout marker is created when logout begins)
+ std::string logout_marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, LOGOUT_MARKER_FILE_NAME);
if(LLAPRFile::isExist(logout_marker_file, NULL, LL_APR_RB))
{
- gLastExecEvent = LAST_EXEC_LOGOUT_FROZE;
- LL_INFOS("MarkerFile") << "Last exec LLError crashed, setting LastExecEvent to " << gLastExecEvent << LL_ENDL;
+ if (markerIsSameVersion(logout_marker_file))
+ {
+ gLastExecEvent = LAST_EXEC_LOGOUT_FROZE;
+ LL_INFOS("MarkerFile") << "Logout crash marker '"<< logout_marker_file << "', changing LastExecEvent to LOGOUT_FROZE" << LL_ENDL;
+ }
+ else
+ {
+ LL_INFOS("MarkerFile") << "Logout crash marker '"<< logout_marker_file << "' found, but versions did not match" << LL_ENDL;
+ }
LLAPRFile::remove(logout_marker_file);
}
+ // further refine based on whether or not a marker created during an llerr crash is found
+ std::string llerror_marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, LLERROR_MARKER_FILE_NAME);
if(LLAPRFile::isExist(llerror_marker_file, NULL, LL_APR_RB))
{
- if(gLastExecEvent == LAST_EXEC_LOGOUT_FROZE) gLastExecEvent = LAST_EXEC_LOGOUT_CRASH;
- else gLastExecEvent = LAST_EXEC_LLERROR_CRASH;
- LL_INFOS("MarkerFile") << "Last exec LLError crashed, setting LastExecEvent to " << gLastExecEvent << LL_ENDL;
+ if (markerIsSameVersion(llerror_marker_file))
+ {
+ if ( gLastExecEvent == LAST_EXEC_LOGOUT_FROZE )
+ {
+ gLastExecEvent = LAST_EXEC_LOGOUT_CRASH;
+ LL_INFOS("MarkerFile") << "LLError marker '"<< llerror_marker_file << "' crashed, setting LastExecEvent to LOGOUT_CRASH" << LL_ENDL;
+ }
+ else
+ {
+ gLastExecEvent = LAST_EXEC_LLERROR_CRASH;
+ LL_INFOS("MarkerFile") << "LLError marker '"<< llerror_marker_file << "' crashed, setting LastExecEvent to LLERROR_CRASH" << LL_ENDL;
+ }
+ }
+ else
+ {
+ LL_INFOS("MarkerFile") << "LLError marker '"<< llerror_marker_file << "' found, but versions did not match" << LL_ENDL;
+ }
LLAPRFile::remove(llerror_marker_file);
}
+ // and last refine based on whether or not a marker created during a non-llerr crash is found
+ std::string error_marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, ERROR_MARKER_FILE_NAME);
if(LLAPRFile::isExist(error_marker_file, NULL, LL_APR_RB))
{
- if(gLastExecEvent == LAST_EXEC_LOGOUT_FROZE) gLastExecEvent = LAST_EXEC_LOGOUT_CRASH;
- else gLastExecEvent = LAST_EXEC_OTHER_CRASH;
- LL_INFOS("MarkerFile") << "Last exec crashed, setting LastExecEvent to " << gLastExecEvent << LL_ENDL;
+ if (markerIsSameVersion(error_marker_file))
+ {
+ if (gLastExecEvent == LAST_EXEC_LOGOUT_FROZE)
+ {
+ gLastExecEvent = LAST_EXEC_LOGOUT_CRASH;
+ LL_INFOS("MarkerFile") << "Error marker '"<< error_marker_file << "' crashed, setting LastExecEvent to LOGOUT_CRASH" << LL_ENDL;
+ }
+ else
+ {
+ gLastExecEvent = LAST_EXEC_OTHER_CRASH;
+ LL_INFOS("MarkerFile") << "Error marker '"<< error_marker_file << "' crashed, setting LastExecEvent to " << gLastExecEvent << LL_ENDL;
+ }
+ }
+ else
+ {
+ LL_INFOS("MarkerFile") << "Error marker '"<< error_marker_file << "' marker found, but versions did not match" << LL_ENDL;
+ }
LLAPRFile::remove(error_marker_file);
}
-
- // No new markers if another instance is running.
- if(anotherInstanceRunning())
- {
- return;
- }
-
- // Create the marker file for this execution & lock it
- apr_status_t s;
- s = mMarkerFile.open(mMarkerFileName, LL_APR_W, TRUE);
-
- if (s == APR_SUCCESS && mMarkerFile.getFileHandle())
- {
- LL_DEBUGS("MarkerFile") << "Marker file created." << LL_ENDL;
- }
- else
- {
- LL_INFOS("MarkerFile") << "Failed to create marker file." << LL_ENDL;
- return;
- }
- if (apr_file_lock(mMarkerFile.getFileHandle(), APR_FLOCK_NONBLOCK | APR_FLOCK_EXCLUSIVE) != APR_SUCCESS)
- {
- mMarkerFile.close() ;
- LL_INFOS("MarkerFile") << "Marker file cannot be locked." << LL_ENDL;
- return;
- }
-
- LL_DEBUGS("MarkerFile") << "Marker file locked." << LL_ENDL;
}
void LLAppViewer::removeMarkerFile(bool leave_logout_marker)
{
- LL_DEBUGS("MarkerFile") << "removeMarkerFile()" << LL_ENDL;
- if (mMarkerFile.getFileHandle())
- {
- mMarkerFile.close() ;
- LLAPRFile::remove( mMarkerFileName );
+ if (!mSecondInstance)
+ {
+ LL_DEBUGS("MarkerFile") << (leave_logout_marker?"leave":"remove") <<" logout" << LL_ENDL;
+ if (mMarkerFile.getFileHandle())
+ {
+ LL_DEBUGS("MarkerFile") << "removing exec marker '"<<mMarkerFileName<<"'"<< LL_ENDL;
+ mMarkerFile.close() ;
+ LLAPRFile::remove( mMarkerFileName );
+ }
+ else
+ {
+ LL_WARNS("MarkerFile") << "marker '"<<mMarkerFileName<<"' not open"<< LL_ENDL;
+ }
+ if (!leave_logout_marker)
+ {
+ if (mLogoutMarkerFile.getFileHandle())
+ {
+ LL_DEBUGS("MarkerFile") << "removing logout marker '"<<mLogoutMarkerFileName<<"'"<< LL_ENDL;
+ mLogoutMarkerFile.close();
+ }
+ else
+ {
+ LL_WARNS("MarkerFile") << "logout marker '"<<mLogoutMarkerFileName<<"' not open"<< LL_ENDL;
+ }
+ LLAPRFile::remove( mLogoutMarkerFileName );
+ }
}
- if (mLogoutMarkerFile != NULL && !leave_logout_marker)
+ else
{
- LLAPRFile::remove( mLogoutMarkerFileName );
- mLogoutMarkerFile = NULL;
+ LL_WARNS("MarkerFile") << "leaving markers because this is a second instance" << LL_ENDL;
}
}
@@ -3405,6 +3822,18 @@ void LLAppViewer::requestQuit()
// Try to send metrics back to the grid
metricsSend(!gDisconnected);
+
+ // Try to send last batch of avatar rez metrics.
+ if (!gDisconnected && isAgentAvatarValid())
+ {
+ gAgentAvatarp->updateAvatarRezMetrics(true); // force a last packet to be sent.
+ }
+
+ // Try to send last batch of avatar rez metrics.
+ if (!gDisconnected && isAgentAvatarValid())
+ {
+ gAgentAvatarp->updateAvatarRezMetrics(true); // force a last packet to be sent.
+ }
LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral*)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_POINT, TRUE);
effectp->setPositionGlobal(gAgent.getPositionGlobal());
@@ -3500,8 +3929,7 @@ void LLAppViewer::migrateCacheDirectory()
{
gSavedSettings.setBOOL("MigrateCacheDirectory", FALSE);
- std::string delimiter = gDirUtilp->getDirDelimiter();
- std::string old_cache_dir = gDirUtilp->getOSUserAppDir() + delimiter + "cache";
+ std::string old_cache_dir = gDirUtilp->add(gDirUtilp->getOSUserAppDir(), "cache");
std::string new_cache_dir = gDirUtilp->getCacheDir(true);
if (gDirUtilp->fileExists(old_cache_dir))
@@ -3517,8 +3945,8 @@ void LLAppViewer::migrateCacheDirectory()
while (iter.next(file_name))
{
if (file_name == "." || file_name == "..") continue;
- std::string source_path = old_cache_dir + delimiter + file_name;
- std::string dest_path = new_cache_dir + delimiter + file_name;
+ std::string source_path = gDirUtilp->add(old_cache_dir, file_name);
+ std::string dest_path = gDirUtilp->add(new_cache_dir, file_name);
if (!LLFile::rename(source_path, dest_path))
{
file_count++;
@@ -3749,7 +4177,7 @@ bool LLAppViewer::initCache()
LLDirIterator iter(dir, mask);
if (iter.next(found_file))
{
- old_vfs_data_file = dir + gDirUtilp->getDirDelimiter() + found_file;
+ old_vfs_data_file = gDirUtilp->add(dir, found_file);
S32 start_pos = found_file.find_last_of('.');
if (start_pos > 0)
@@ -3855,8 +4283,7 @@ void LLAppViewer::purgeCache()
LL_INFOS("AppCache") << "Purging Cache and Texture Cache..." << LL_ENDL;
LLAppViewer::getTextureCache()->purgeCache(LL_PATH_CACHE);
LLVOCache::getInstance()->removeCache(LL_PATH_CACHE);
- std::string mask = "*.*";
- gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, ""), mask);
+ gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, ""), "*.*");
}
std::string LLAppViewer::getSecondLifeTitle() const
@@ -4052,7 +4479,6 @@ static LLFastTimer::DeclareTimer FTM_VLMANAGER("VL Manager");
///////////////////////////////////////////////////////
void LLAppViewer::idle()
{
- LLMemType mt_idle(LLMemType::MTYPE_IDLE);
pingMainloopTimeout("Main:Idle");
// Update frame timers
@@ -4165,7 +4591,6 @@ void LLAppViewer::idle()
// of SEND_STATS_PERIOD so that the initial stats report will
// be sent immediately.
static LLFrameStatsTimer viewer_stats_timer(SEND_STATS_PERIOD);
- reset_statistics();
// Update session stats every large chunk of time
// *FIX: (???) SAMANTHA
@@ -4186,11 +4611,6 @@ void LLAppViewer::idle()
llinfos << "Dead object updates: " << gObjectList.mNumDeadObjectUpdates << llendl;
gObjectList.mNumDeadObjectUpdates = 0;
}
- if (gObjectList.mNumUnknownKills)
- {
- llinfos << "Kills on unknown objects: " << gObjectList.mNumUnknownKills << llendl;
- gObjectList.mNumUnknownKills = 0;
- }
if (gObjectList.mNumUnknownUpdates)
{
llinfos << "Unknown object updates: " << gObjectList.mNumUnknownUpdates << llendl;
@@ -4224,7 +4644,7 @@ void LLAppViewer::idle()
idle_afk_check();
// Update statistics for this frame
- update_statistics(gFrameCount);
+ update_statistics();
}
////////////////////////////////////////
@@ -4248,7 +4668,8 @@ void LLAppViewer::idle()
static LLTimer report_interval;
// *TODO: Add configuration controls for this
- if (report_interval.getElapsedTimeF32() >= app_metrics_interval)
+ F32 seconds = report_interval.getElapsedTimeF32();
+ if (seconds >= app_metrics_interval)
{
metricsSend(! gDisconnected);
report_interval.reset();
@@ -4259,6 +4680,10 @@ void LLAppViewer::idle()
{
return;
}
+ if (gTeleportDisplay)
+ {
+ return;
+ }
gViewerWindow->updateUI();
@@ -4422,6 +4847,9 @@ void LLAppViewer::idle()
gObjectList.updateApparentAngles(gAgent);
}
+ // Update AV render info
+ LLAvatarRenderInfoAccountant::idle();
+
{
LLFastTimer t(FTM_AUDIO_UPDATE);
@@ -4511,6 +4939,13 @@ void LLAppViewer::idleShutdown()
return;
}
+ if (gPendingMetricsUploads > 0
+ && gLogoutTimer.getElapsedTimeF32() < SHUTDOWN_UPLOAD_SAVE_TIME
+ && !logoutRequestSent())
+ {
+ return;
+ }
+
// All floaters are closed. Tell server we want to quit.
if( !logoutRequestSent() )
{
@@ -4536,6 +4971,22 @@ void LLAppViewer::sendLogoutRequest()
{
if(!mLogoutRequestSent && gMessageSystem)
{
+ //Set internal status variables and marker files before actually starting the logout process
+ gLogoutInProgress = TRUE;
+ mLogoutMarkerFileName = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,LOGOUT_MARKER_FILE_NAME);
+
+ LLAPRFile outfile ;
+ mLogoutMarkerFile.open(mLogoutMarkerFileName, LL_APR_WB);
+ if (mLogoutMarkerFile.getFileHandle())
+ {
+ LL_INFOS("MarkerFile") << "Created logout marker file '"<< mLogoutMarkerFileName << "' " << LL_ENDL;
+ recordMarkerVersion(outfile);
+ }
+ else
+ {
+ LL_WARNS("MarkerFile") << "Cannot create logout marker file " << mLogoutMarkerFileName << LL_ENDL;
+ }
+
LLMessageSystem* msg = gMessageSystem;
msg->newMessageFast(_PREHASH_LogoutRequest);
msg->nextBlockFast(_PREHASH_AgentData);
@@ -4551,23 +5002,6 @@ void LLAppViewer::sendLogoutRequest()
{
LLVoiceClient::getInstance()->leaveChannel();
}
-
- //Set internal status variables and marker files
- gLogoutInProgress = TRUE;
- mLogoutMarkerFileName = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,LOGOUT_MARKER_FILE_NAME);
-
- LLAPRFile outfile ;
- outfile.open(mLogoutMarkerFileName, LL_APR_W);
- mLogoutMarkerFile = outfile.getFileHandle() ;
- if (mLogoutMarkerFile)
- {
- llinfos << "Created logout marker file " << mLogoutMarkerFileName << llendl;
- apr_file_close(mLogoutMarkerFile);
- }
- else
- {
- llwarns << "Cannot create logout marker file " << mLogoutMarkerFileName << llendl;
- }
}
}
@@ -4645,7 +5079,6 @@ static LLFastTimer::DeclareTimer FTM_CHECK_REGION_CIRCUIT("Check Region Circuit"
void LLAppViewer::idleNetwork()
{
- LLMemType mt_in(LLMemType::MTYPE_IDLE_NETWORK);
pingMainloopTimeout("idleNetwork");
gObjectList.mNumNewObjects = 0;
@@ -4817,11 +5250,12 @@ void LLAppViewer::disconnectViewer()
void LLAppViewer::forceErrorLLError()
{
- llerrs << "This is an llerror" << llendl;
+ llerrs << "This is a deliberate llerror" << llendl;
}
void LLAppViewer::forceErrorBreakpoint()
{
+ llwarns << "Forcing a deliberate breakpoint" << llendl;
#ifdef LL_WINDOWS
DebugBreak();
#endif
@@ -4830,6 +5264,7 @@ void LLAppViewer::forceErrorBreakpoint()
void LLAppViewer::forceErrorBadMemoryAccess()
{
+ llwarns << "Forcing a deliberate bad memory access" << llendl;
S32* crash = NULL;
*crash = 0xDEADBEEF;
return;
@@ -4837,6 +5272,7 @@ void LLAppViewer::forceErrorBadMemoryAccess()
void LLAppViewer::forceErrorInfiniteLoop()
{
+ llwarns << "Forcing a deliberate infinite loop" << llendl;
while(true)
{
;
@@ -4846,12 +5282,14 @@ void LLAppViewer::forceErrorInfiniteLoop()
void LLAppViewer::forceErrorSoftwareException()
{
+ llwarns << "Forcing a deliberate exception" << llendl;
// *FIX: Any way to insure it won't be handled?
throw;
}
void LLAppViewer::forceErrorDriverCrash()
{
+ llwarns << "Forcing a deliberate driver crash" << llendl;
glDeleteTextures(1, NULL);
}
@@ -4956,105 +5394,20 @@ void LLAppViewer::handleLoginComplete()
mOnLoginCompleted();
writeDebugInfo();
-}
-
-// *TODO - generalize this and move DSO wrangling to a helper class -brad
-void LLAppViewer::loadEventHostModule(S32 listen_port)
-{
- std::string dso_name =
-#if LL_WINDOWS
- "lleventhost.dll";
-#elif LL_DARWIN
- "liblleventhost.dylib";
-#else
- "liblleventhost.so";
-#endif
-
- std::string dso_path = gDirUtilp->findFile(dso_name,
- gDirUtilp->getAppRODataDir(),
- gDirUtilp->getExecutableDir());
- if(dso_path == "")
- {
- llerrs << "QAModeEventHost requested but module \"" << dso_name << "\" not found!" << llendl;
- return;
- }
-
- LL_INFOS("eventhost") << "Found lleventhost at '" << dso_path << "'" << LL_ENDL;
-#if ! defined(LL_WINDOWS)
- {
- std::string outfile("/tmp/lleventhost.file.out");
- std::string command("file '" + dso_path + "' > '" + outfile + "' 2>&1");
- int rc = system(command.c_str());
- if (rc != 0)
- {
- LL_WARNS("eventhost") << command << " ==> " << rc << ':' << LL_ENDL;
- }
- else
- {
- LL_INFOS("eventhost") << command << ':' << LL_ENDL;
- }
- {
- std::ifstream reader(outfile.c_str());
- std::string line;
- while (std::getline(reader, line))
- {
- size_t len = line.length();
- if (len && line[len-1] == '\n')
- line.erase(len-1);
- LL_INFOS("eventhost") << line << LL_ENDL;
- }
- }
- remove(outfile.c_str());
- }
-#endif // LL_WINDOWS
-
- apr_dso_handle_t * eventhost_dso_handle = NULL;
- apr_pool_t * eventhost_dso_memory_pool = NULL;
-
- //attempt to load the shared library
- apr_pool_create(&eventhost_dso_memory_pool, NULL);
- apr_status_t rv = apr_dso_load(&eventhost_dso_handle,
- dso_path.c_str(),
- eventhost_dso_memory_pool);
- llassert_always(! ll_apr_warn_status(rv, eventhost_dso_handle));
- llassert_always(eventhost_dso_handle != NULL);
-
- int (*ll_plugin_start_func)(LLSD const &) = NULL;
- rv = apr_dso_sym((apr_dso_handle_sym_t*)&ll_plugin_start_func, eventhost_dso_handle, "ll_plugin_start");
-
- llassert_always(! ll_apr_warn_status(rv, eventhost_dso_handle));
- llassert_always(ll_plugin_start_func != NULL);
-
- LLSD args;
- args["listen_port"] = listen_port;
-
- int status = ll_plugin_start_func(args);
-
- if(status != 0)
- {
- llerrs << "problem loading eventhost plugin, status: " << status << llendl;
- }
-
- mPlugins.insert(eventhost_dso_handle);
+ // we logged in successfully, so save settings on logout
+ llinfos << "Login successful, per account settings will be saved on log out." << llendl;
+ mSavePerAccountSettings=true;
}
void LLAppViewer::launchUpdater()
{
LLSD query_map = LLSD::emptyMap();
- // *TODO place os string in a global constant
-#if LL_WINDOWS
- query_map["os"] = "win";
-#elif LL_DARWIN
- query_map["os"] = "mac";
-#elif LL_LINUX
- query_map["os"] = "lnx";
-#elif LL_SOLARIS
- query_map["os"] = "sol";
-#endif
+ query_map["os"] = gPlatform;
+
// *TODO change userserver to be grid on both viewer and sim, since
// userserver no longer exists.
- query_map["userserver"] = LLGridManager::getInstance()->getGridLabel();
+ query_map["userserver"] = LLGridManager::getInstance()->getGridId();
query_map["channel"] = LLVersionInfo::getChannel();
// *TODO constantize this guy
// *NOTE: This URL is also used in win_setup/lldownloader.cpp
@@ -5136,20 +5489,20 @@ void LLAppViewer::launchUpdater()
// we tell the updater where to find the xml containing string
// translations which it can use for its own UI
std::string xml_strings_file = "strings.xml";
- std::vector<std::string> xui_path_vec = LLUI::getXUIPaths();
+ std::vector<std::string> xui_path_vec =
+ gDirUtilp->findSkinnedFilenames(LLDir::XUI, xml_strings_file);
std::string xml_search_paths;
- std::vector<std::string>::const_iterator iter;
+ const char* delim = "";
// build comma-delimited list of xml paths to pass to updater
- for (iter = xui_path_vec.begin(); iter != xui_path_vec.end(); )
- {
- std::string this_skin_dir = gDirUtilp->getDefaultSkinDir()
- + gDirUtilp->getDirDelimiter()
- + (*iter);
- llinfos << "Got a XUI path: " << this_skin_dir << llendl;
- xml_search_paths.append(this_skin_dir);
- ++iter;
- if (iter != xui_path_vec.end())
- xml_search_paths.append(","); // comma-delimit
+ BOOST_FOREACH(std::string this_skin_path, xui_path_vec)
+ {
+ // Although we already have the full set of paths with the filename
+ // appended, the linux-updater.bin command-line switches require us to
+ // snip the filename OFF and pass it as a separate switch argument. :-P
+ llinfos << "Got a XUI path: " << this_skin_path << llendl;
+ xml_search_paths.append(delim);
+ xml_search_paths.append(gDirUtilp->getDirName(this_skin_path));
+ delim = ",";
}
// build the overall command-line to run the updater correctly
LLAppViewer::sUpdaterInfo->mUpdateExePath =
diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h
index 71a7868191..3ae8a78845 100644..100755
--- a/indra/newview/llappviewer.h
+++ b/indra/newview/llappviewer.h
@@ -31,6 +31,8 @@
#include "llcontrol.h"
#include "llsys.h" // for LLOSInfo
#include "lltimer.h"
+#include "llappcorehttp.h"
+#include <boost/optional.hpp>
class LLCommandLineParser;
class LLFrameTimer;
@@ -40,8 +42,10 @@ class LLImageDecodeThread;
class LLTextureFetch;
class LLWatchdogTimeout;
class LLUpdaterService;
+class LLViewerJoystick;
+
+extern LLFastTimer::DeclareTimer FTM_FRAME;
-struct apr_dso_handle_t;
class LLAppViewer : public LLApp
{
@@ -175,10 +179,13 @@ public:
// Metrics policy helper statics.
static void metricsUpdateRegion(U64 region_handle);
static void metricsSend(bool enable_reporting);
+
+ // llcorehttp init/shutdown/config information.
+ LLAppCoreHttp & getAppCoreHttp() { return mAppCoreHttp; }
protected:
virtual bool initWindow(); // Initialize the viewer's window.
- virtual bool initLogging(); // Initialize log files, logging system, return false on failure.
+ virtual void initLoggingAndGetLastDuration(); // Initialize log files, logging system
virtual void initConsole() {}; // Initialize OS level debugging console.
virtual bool initHardwareTest() { return true; } // A false result indicates the app should quit.
virtual bool initSLURLHandler();
@@ -196,6 +203,7 @@ private:
void initMaxHeapSize();
bool initThreads(); // Initialize viewer threads, return false on failure.
bool initConfiguration(); // Initialize settings from the command line/config file.
+ void initStrings(); // Initialize LLTrans machinery
void initUpdater(); // Initialize the updater service.
bool initCache(); // Initialize local client cache.
void checkMemory() ;
@@ -209,9 +217,10 @@ private:
void writeSystemInfo(); // Write system info to "debug_info.log"
- bool anotherInstanceRunning();
- void initMarkerFile();
-
+ void processMarkerFiles();
+ static void recordMarkerVersion(LLAPRFile& marker_file);
+ bool markerIsSameVersion(const std::string& marker_name) const;
+
void idle();
void idleShutdown();
// update avatar SLID and display name caches
@@ -220,8 +229,6 @@ private:
void sendLogoutRequest();
void disconnectViewer();
-
- void loadEventHostModule(S32 listen_port);
// *FIX: the app viewer class should be some sort of singleton, no?
// Perhaps its child class is the singleton and this should be an abstract base.
@@ -233,7 +240,7 @@ private:
LLAPRFile mMarkerFile; // A file created to indicate the app is running.
std::string mLogoutMarkerFileName;
- apr_file_t* mLogoutMarkerFile; // A file created to indicate the app is running.
+ LLAPRFile mLogoutMarkerFile; // A file created to indicate the app is running.
LLOSInfo mSysOSInfo;
@@ -249,10 +256,13 @@ private:
std::string mSerialNumber;
bool mPurgeCache;
bool mPurgeOnExit;
+ bool mMainLoopInitialized;
+ LLViewerJoystick* joystick;
bool mSavedFinalSnapshot;
+ bool mSavePerAccountSettings; // only save per account settings if login succeeded
- bool mForceGraphicsDetail;
+ boost::optional<U32> mForceGraphicsLevel;
bool mQuitRequested; // User wants to quit, may have modified documents open.
bool mLogoutRequestSent; // Disconnect message sent to simulator, no longer safe to send messages to the sim.
@@ -270,12 +280,13 @@ private:
LLAllocator mAlloc;
- std::set<struct apr_dso_handle_t*> mPlugins;
-
LLFrameTimer mMemCheckTimer;
boost::scoped_ptr<LLUpdaterService> mUpdater;
+ // llcorehttp library init/shutdown helper
+ LLAppCoreHttp mAppCoreHttp;
+
//---------------------------------------------
//*NOTE: Mani - legacy updater stuff
// Still useable?
@@ -315,6 +326,9 @@ typedef enum
} eLastExecEvent;
extern eLastExecEvent gLastExecEvent; // llstartup
+extern S32 gLastExecDuration; ///< the duration of the previous run in seconds (<0 indicates unknown)
+
+extern const char* gPlatform;
extern U32 gFrameCount;
extern U32 gForegroundFrameCount;
@@ -336,6 +350,8 @@ extern LLFrameTimer gLoggedInTime;
extern F32 gLogoutMaxTime;
extern LLTimer gLogoutTimer;
+extern S32 gPendingMetricsUploads;
+
extern F32 gSimLastTime;
extern F32 gSimFrames;
diff --git a/indra/newview/llappviewerlinux.cpp b/indra/newview/llappviewerlinux.cpp
index 48d02dfeaa..b16bb573e1 100644..100755
--- a/indra/newview/llappviewerlinux.cpp
+++ b/indra/newview/llappviewerlinux.cpp
@@ -31,7 +31,6 @@
#include "llcommandlineparser.h"
#include "lldiriterator.h"
-#include "llmemtype.h"
#include "llurldispatcher.h" // SLURL from other app instance
#include "llviewernetwork.h"
#include "llviewercontrol.h"
@@ -71,8 +70,6 @@ static void exceptionTerminateHandler()
int main( int argc, char **argv )
{
- LLMemType mt1(LLMemType::MTYPE_STARTUP);
-
#if LL_SOLARIS && defined(__sparc)
asm ("ta\t6"); // NOTE: Make sure memory alignment is enforced on SPARC
#endif
@@ -365,7 +362,7 @@ void LLAppViewerLinux::handleCrashReporting(bool reportFreeze)
const char * cmdargv[] =
{cmd.c_str(),
"-user",
- (char*)LLGridManager::getInstance()->getGridLabel().c_str(),
+ (char*)LLGridManager::getInstance()->getGridId().c_str(),
"-name",
LLAppViewer::instance()->getSecondLifeTitle().c_str(),
NULL};
@@ -443,7 +440,7 @@ bool LLAppViewerLinux::beingDebugged()
#endif
}
-bool LLAppViewerLinux::initLogging()
+void LLAppViewerLinux::initLoggingAndGetLastDuration()
{
// Remove the last stack trace, if any
// This file is no longer created, since the move to Google Breakpad
@@ -452,7 +449,7 @@ bool LLAppViewerLinux::initLogging()
gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"stack_trace.log");
LLFile::remove(old_stack_file);
- return LLAppViewer::initLogging();
+ LLAppViewer::initLoggingAndGetLastDuration();
}
bool LLAppViewerLinux::initParseCommandLine(LLCommandLineParser& clp)
diff --git a/indra/newview/llappviewerlinux.h b/indra/newview/llappviewerlinux.h
index 58e5160180..fb77600c10 100644..100755
--- a/indra/newview/llappviewerlinux.h
+++ b/indra/newview/llappviewerlinux.h
@@ -63,7 +63,7 @@ protected:
virtual bool restoreErrorTrap();
virtual void handleCrashReporting(bool reportFreeze);
- virtual bool initLogging();
+ virtual void initLoggingAndGetLastDuration();
virtual bool initParseCommandLine(LLCommandLineParser& clp);
virtual bool initSLURLHandler();
diff --git a/indra/newview/llappviewerlinux_api.h b/indra/newview/llappviewerlinux_api.h
index 5d5fcaa3d6..5d5fcaa3d6 100644..100755
--- a/indra/newview/llappviewerlinux_api.h
+++ b/indra/newview/llappviewerlinux_api.h
diff --git a/indra/newview/llappviewerlinux_api.xml b/indra/newview/llappviewerlinux_api.xml
index fac35b7adc..fac35b7adc 100644..100755
--- a/indra/newview/llappviewerlinux_api.xml
+++ b/indra/newview/llappviewerlinux_api.xml
diff --git a/indra/newview/llappviewerlinux_api_dbus.cpp b/indra/newview/llappviewerlinux_api_dbus.cpp
index 32e7e0a83d..32e7e0a83d 100644..100755
--- a/indra/newview/llappviewerlinux_api_dbus.cpp
+++ b/indra/newview/llappviewerlinux_api_dbus.cpp
diff --git a/indra/newview/llappviewerlinux_api_dbus.h b/indra/newview/llappviewerlinux_api_dbus.h
index 3eee25b53d..3eee25b53d 100644..100755
--- a/indra/newview/llappviewerlinux_api_dbus.h
+++ b/indra/newview/llappviewerlinux_api_dbus.h
diff --git a/indra/newview/llappviewerlinux_api_dbus_syms_raw.inc b/indra/newview/llappviewerlinux_api_dbus_syms_raw.inc
index c0548e2fba..c0548e2fba 100644..100755
--- a/indra/newview/llappviewerlinux_api_dbus_syms_raw.inc
+++ b/indra/newview/llappviewerlinux_api_dbus_syms_raw.inc
diff --git a/indra/newview/llappviewerlistener.cpp b/indra/newview/llappviewerlistener.cpp
index 94250f1fc2..94250f1fc2 100644..100755
--- a/indra/newview/llappviewerlistener.cpp
+++ b/indra/newview/llappviewerlistener.cpp
diff --git a/indra/newview/llappviewerlistener.h b/indra/newview/llappviewerlistener.h
index 78c8b1909e..78c8b1909e 100644..100755
--- a/indra/newview/llappviewerlistener.h
+++ b/indra/newview/llappviewerlistener.h
diff --git a/indra/newview/llappviewermacosx.cpp b/indra/newview/llappviewermacosx.cpp
index c2916717bd..2723f0b90d 100644..100755
--- a/indra/newview/llappviewermacosx.cpp
+++ b/indra/newview/llappviewermacosx.cpp
@@ -30,17 +30,21 @@
#error "Use only with Mac OS X"
#endif
+#define LL_CARBON_CRASH_HANDLER 1
+
#include "llappviewermacosx.h"
+#include "llwindowmacosx-objc.h"
#include "llcommandlineparser.h"
-#include "llmemtype.h"
-
#include "llviewernetwork.h"
#include "llviewercontrol.h"
#include "llmd5.h"
#include "llfloaterworldmap.h"
#include "llurldispatcher.h"
+#include <ApplicationServices/ApplicationServices.h>
+#ifdef LL_CARBON_CRASH_HANDLER
#include <Carbon/Carbon.h>
+#endif
#include "lldir.h"
#include <signal.h>
#include <CoreAudio/CoreAudio.h> // for systemwide mute
@@ -52,9 +56,9 @@ namespace
// They are not used immediately by the app.
int gArgC;
char** gArgV;
-
bool sCrashReporterIsRunning = false;
-
+ LLAppViewerMacOSX* gViewerAppPtr;
+#ifdef LL_CARBON_CRASH_HANDLER
OSErr AEQuitHandler(const AppleEvent *messagein, AppleEvent *reply, long refIn)
{
OSErr result = noErr;
@@ -63,12 +67,11 @@ namespace
return(result);
}
+#endif
}
-int main( int argc, char **argv )
+bool initViewer()
{
- LLMemType mt1(LLMemType::MTYPE_STARTUP);
-
#if LL_SOLARIS && defined(__sparc)
asm ("ta\t6"); // NOTE: Make sure memory alignment is enforced on SPARC
#endif
@@ -77,43 +80,60 @@ int main( int argc, char **argv )
if (chdir(gDirUtilp->getAppRODataDir().c_str()) == -1)
{
llwarns << "Could not change directory to "
- << gDirUtilp->getAppRODataDir() << ": " << strerror(errno)
- << llendl;
+ << gDirUtilp->getAppRODataDir() << ": " << strerror(errno)
+ << llendl;
}
-
- LLAppViewerMacOSX* viewer_app_ptr = new LLAppViewerMacOSX();
-
- viewer_app_ptr->setErrorHandler(LLAppViewer::handleViewerCrash);
-
- // Store off the command line args for use later.
- gArgC = argc;
- gArgV = argv;
- bool ok = viewer_app_ptr->init();
+ gViewerAppPtr = new LLAppViewerMacOSX();
+
+ gViewerAppPtr->setErrorHandler(LLAppViewer::handleViewerCrash);
+
+
+
+ bool ok = gViewerAppPtr->init();
if(!ok)
{
llwarns << "Application init failed." << llendl;
- return -1;
}
+
+ return ok;
+}
- // Run the application main loop
- if(!LLApp::isQuitting())
+void handleQuit()
+{
+ LLAppViewer::instance()->userQuit();
+}
+
+bool runMainLoop()
+{
+ bool ret = LLApp::isQuitting();
+ if (!ret && gViewerAppPtr != NULL)
{
- viewer_app_ptr->mainLoop();
+ ret = gViewerAppPtr->mainLoop();
+ } else {
+ ret = true;
}
+
+ return ret;
+}
- if (!LLApp::isError())
+void cleanupViewer()
+{
+ if(!LLApp::isError())
{
- //
- // We don't want to do cleanup here if the error handler got called -
- // the assumption is that the error handler is responsible for doing
- // app cleanup if there was a problem.
- //
- viewer_app_ptr->cleanup();
+ gViewerAppPtr->cleanup();
}
- delete viewer_app_ptr;
- viewer_app_ptr = NULL;
- return 0;
+
+ delete gViewerAppPtr;
+ gViewerAppPtr = NULL;
+}
+
+int main( int argc, char **argv )
+{
+ // Store off the command line args for use later.
+ gArgC = argc;
+ gArgV = argv;
+ return createNSApp(argc, (const char**)argv);
}
LLAppViewerMacOSX::LLAppViewerMacOSX()
@@ -152,28 +172,13 @@ bool LLAppViewerMacOSX::initParseCommandLine(LLCommandLineParser& clp)
// The next two lines add the support for parsing the mac -psn_XXX arg.
clp.addOptionDesc("psn", NULL, 1, "MacOSX process serial number");
clp.setCustomParser(parse_psn);
-
- // First read in the args from arguments txt.
- const char* filename = "arguments.txt";
- llifstream ifs(filename, llifstream::binary);
- if (!ifs.is_open())
- {
- llwarns << "Unable to open file" << filename << llendl;
- return false;
- }
-
- if(clp.parseCommandLineFile(ifs) == false)
- {
- return false;
- }
- // Then parse the user's command line, so that any --url arg can appear last
- // Succesive calls to clp.parse... will NOT override earlier options.
+ // parse the user's command line
if(clp.parseCommandLine(gArgC, gArgV) == false)
{
return false;
}
-
+
// Get the user's preferred language string based on the Mac OS localization mechanism.
// To add a new localization:
// go to the "Resources" section of the project
@@ -258,23 +263,24 @@ bool LLAppViewerMacOSX::restoreErrorTrap()
return reset_count == 0;
}
-static OSStatus CarbonEventHandler(EventHandlerCallRef inHandlerCallRef,
- EventRef inEvent,
+#ifdef LL_CARBON_CRASH_HANDLER
+static OSStatus CarbonEventHandler(EventHandlerCallRef inHandlerCallRef,
+ EventRef inEvent,
void* inUserData)
{
ProcessSerialNumber psn;
- GetEventParameter(inEvent,
- kEventParamProcessID,
- typeProcessSerialNumber,
- NULL,
- sizeof(psn),
- NULL,
+ GetEventParameter(inEvent,
+ kEventParamProcessID,
+ typeProcessSerialNumber,
+ NULL,
+ sizeof(psn),
+ NULL,
&psn);
- if( GetEventKind(inEvent) == kEventAppTerminated )
+ if( GetEventKind(inEvent) == kEventAppTerminated )
{
- Boolean matching_psn = FALSE;
+ Boolean matching_psn = FALSE;
OSErr os_result = SameProcess(&psn, (ProcessSerialNumber*)inUserData, &matching_psn);
if(os_result >= 0 && matching_psn)
{
@@ -284,48 +290,58 @@ static OSStatus CarbonEventHandler(EventHandlerCallRef inHandlerCallRef,
}
return noErr;
}
+#endif
void LLAppViewerMacOSX::handleCrashReporting(bool reportFreeze)
{
- // This used to use fork&exec, but is switched to LSOpenApplication to
+#ifdef LL_CARBON_CRASH_HANDLER
+ // This used to use fork&exec, but is switched to LSOpenApplication to
// Make sure the crash reporter launches in front of the SL window.
std::string command_str;
//command_str = "open Second Life.app/Contents/Resources/mac-crash-logger.app";
command_str = "mac-crash-logger.app/Contents/MacOS/mac-crash-logger";
+ CFURLRef urlRef = CFURLCreateFromFileSystemRepresentation(NULL, (UInt8*)command_str.c_str(), strlen(command_str.c_str()), FALSE);
+
+ // FSRef apparently isn't deprecated.
+ // There's other funcitonality that depends on it existing as well that isn't deprecated.
+ // There doesn't seem to be much to directly verify what the status of FSRef is, outside of some documentation pointing at FSRef being valid, and other documentation pointing to everything in Files.h being deprecated.
+ // We'll assume it isn't for now, since all non-deprecated functions that use it seem to assume similar.
+
FSRef appRef;
- Boolean isDir = 0;
- OSStatus os_result = FSPathMakeRef((UInt8*)command_str.c_str(),
- &appRef,
- &isDir);
- if(os_result >= 0)
+ Boolean pathstatus = CFURLGetFSRef(urlRef, &appRef);
+
+ OSStatus os_result = noErr;
+
+ if(pathstatus == true)
{
LSApplicationParameters appParams;
memset(&appParams, 0, sizeof(appParams));
appParams.version = 0;
appParams.flags = kLSLaunchNoParams | kLSLaunchStartClassic;
+
appParams.application = &appRef;
if(reportFreeze)
{
- // Make sure freeze reporting launches the crash logger synchronously, lest
+ // Make sure freeze reporting launches the crash logger synchronously, lest
// Log files get changed by SL while the logger is running.
-
+
// *NOTE:Mani A better way - make a copy of the data that the crash reporter will send
// and let SL go about its business. This way makes the mac work like windows and linux
- // and is the smallest patch for the issue.
+ // and is the smallest patch for the issue.
sCrashReporterIsRunning = false;
ProcessSerialNumber o_psn;
-
+
static EventHandlerRef sCarbonEventsRef = NULL;
- static const EventTypeSpec kEvents[] =
+ static const EventTypeSpec kEvents[] =
{
{ kEventClassApplication, kEventAppTerminated }
};
// Install the handler to detect crash logger termination
- InstallEventHandler(GetApplicationEventTarget(),
+ InstallEventHandler(GetApplicationEventTarget(),
(EventHandlerUPP) CarbonEventHandler,
GetEventTypeCount(kEvents),
kEvents,
@@ -333,31 +349,31 @@ void LLAppViewerMacOSX::handleCrashReporting(bool reportFreeze)
&sCarbonEventsRef
);
- // Remove, temporarily the quit handler - which has *crash* behavior before
+ // Remove, temporarily the quit handler - which has *crash* behavior before
// the mainloop gets running!
- AERemoveEventHandler(kCoreEventClass,
- kAEQuitApplication,
+ AERemoveEventHandler(kCoreEventClass,
+ kAEQuitApplication,
NewAEEventHandlerUPP(AEQuitHandler),
false);
-
+
// Launch the crash reporter.
os_result = LSOpenApplication(&appParams, &o_psn);
if(os_result >= 0)
- {
+ {
sCrashReporterIsRunning = true;
}
-
+
while(sCrashReporterIsRunning)
{
RunApplicationEventLoop();
}
-
+
// Re-install the apps quit handler.
- AEInstallEventHandler(kCoreEventClass,
- kAEQuitApplication,
+ AEInstallEventHandler(kCoreEventClass,
+ kAEQuitApplication,
NewAEEventHandlerUPP(AEQuitHandler),
- 0,
+ 0,
false);
// Remove the crash reporter quit handler.
@@ -367,12 +383,12 @@ void LLAppViewerMacOSX::handleCrashReporting(bool reportFreeze)
{
appParams.flags |= kLSLaunchAsync;
clear_signals();
-
+
ProcessSerialNumber o_psn;
os_result = LSOpenApplication(&appParams, &o_psn);
}
-
}
+#endif
}
std::string LLAppViewerMacOSX::generateSerialNumber()
@@ -467,111 +483,24 @@ bool LLAppViewerMacOSX::getMasterSystemAudioMute()
return (mute != 0);
}
-OSErr AEGURLHandler(const AppleEvent *messagein, AppleEvent *reply, long refIn)
-{
- OSErr result = noErr;
- DescType actualType;
- char buffer[1024]; // Flawfinder: ignore
- Size size;
-
- result = AEGetParamPtr (
- messagein,
- keyDirectObject,
- typeCString,
- &actualType,
- (Ptr)buffer,
- sizeof(buffer),
- &size);
-
- if(result == noErr)
- {
- std::string url = buffer;
-
- // Safari 3.2 silently mangles secondlife:///app/ URLs into
- // secondlife:/app/ (only one leading slash).
- // Fix them up to meet the URL specification. JC
- const std::string prefix = "secondlife:/app/";
- std::string test_prefix = url.substr(0, prefix.length());
- LLStringUtil::toLower(test_prefix);
- if (test_prefix == prefix)
- {
- url.replace(0, prefix.length(), "secondlife:///app/");
- }
-
- LLMediaCtrl* web = NULL;
- const bool trusted_browser = false;
- LLURLDispatcher::dispatch(url, "", web, trusted_browser);
- }
-
- return(result);
-}
-
-OSStatus simpleDialogHandler(EventHandlerCallRef handler, EventRef event, void *userdata)
-{
- OSStatus result = eventNotHandledErr;
- OSStatus err;
- UInt32 evtClass = GetEventClass(event);
- UInt32 evtKind = GetEventKind(event);
- WindowRef window = (WindowRef)userdata;
-
- if((evtClass == kEventClassCommand) && (evtKind == kEventCommandProcess))
- {
- HICommand cmd;
- err = GetEventParameter(event, kEventParamDirectObject, typeHICommand, NULL, sizeof(cmd), NULL, &cmd);
-
- if(err == noErr)
- {
- switch(cmd.commandID)
- {
- case kHICommandOK:
- QuitAppModalLoopForWindow(window);
- result = noErr;
- break;
-
- case kHICommandCancel:
- QuitAppModalLoopForWindow(window);
- result = userCanceledErr;
- break;
- }
- }
- }
-
- return(result);
-}
-
-void init_apple_menu(const char* product)
+void handleUrl(const char* url_utf8)
{
- // Load up a proper menu bar.
- {
- OSStatus err;
- IBNibRef nib = NULL;
- // NOTE: DO NOT translate or brand this string. It's an internal name in the .nib file, and MUST match exactly.
- err = CreateNibReference(CFSTR("SecondLife"), &nib);
+ if (url_utf8)
+ {
+ std::string url = url_utf8;
+ // Safari 3.2 silently mangles secondlife:///app/ URLs into
+ // secondlife:/app/ (only one leading slash).
+ // Fix them up to meet the URL specification. JC
+ const std::string prefix = "secondlife:/app/";
+ std::string test_prefix = url.substr(0, prefix.length());
+ LLStringUtil::toLower(test_prefix);
+ if (test_prefix == prefix)
+ {
+ url.replace(0, prefix.length(), "secondlife:///app/");
+ }
- if(err == noErr)
- {
- // NOTE: DO NOT translate or brand this string. It's an internal name in the .nib file, and MUST match exactly.
- SetMenuBarFromNib(nib, CFSTR("MenuBar"));
- }
-
- if(nib != NULL)
- {
- DisposeNibReference(nib);
- }
- }
-
- // Install a handler for 'gurl' AppleEvents. This is how secondlife:// URLs get passed to the viewer.
-
- if(AEInstallEventHandler('GURL', 'GURL', NewAEEventHandlerUPP(AEGURLHandler),0, false) != noErr)
- {
- // Couldn't install AppleEvent handler. This error shouldn't be fatal.
- llinfos << "Couldn't install 'GURL' AppleEvent handler. Continuing..." << llendl;
- }
-
- // Install a handler for 'quit' AppleEvents. This makes quitting the application from the dock work.
- if(AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, NewAEEventHandlerUPP(AEQuitHandler),0, false) != noErr)
- {
- // Couldn't install AppleEvent handler. This error shouldn't be fatal.
- llinfos << "Couldn't install Quit AppleEvent handler. Continuing..." << llendl;
- }
+ LLMediaCtrl* web = NULL;
+ const bool trusted_browser = false;
+ LLURLDispatcher::dispatch(url, "", web, trusted_browser);
+ }
}
diff --git a/indra/newview/llappviewermacosx.h b/indra/newview/llappviewermacosx.h
index 25053da5e8..25053da5e8 100644..100755
--- a/indra/newview/llappviewermacosx.h
+++ b/indra/newview/llappviewermacosx.h
diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp
index bad60a9757..80a80f4298 100644..100755
--- a/indra/newview/llappviewerwin32.cpp
+++ b/indra/newview/llappviewerwin32.cpp
@@ -32,7 +32,6 @@
#include "llappviewerwin32.h"
-#include "llmemtype.h"
#include "llwindowwin32.h" // *FIX: for setting gIconResource.
#include "llgl.h"
@@ -47,6 +46,11 @@
#include "llviewercontrol.h"
#include "lldxhardware.h"
+#include "nvapi/nvapi.h"
+#include "nvapi/NvApiDriverSettings.h"
+
+#include <stdlib.h>
+
#include "llweb.h"
#include "llsecondlifeurls.h"
@@ -61,6 +65,7 @@
#include "llwindebug.h"
#endif
+
// *FIX:Mani - This hack is to fix a linker issue with libndofdev.lib
// The lib was compiled under VS2005 - in VS2003 we need to remap assert
#ifdef LL_DEBUG
@@ -76,6 +81,20 @@ extern "C" {
const std::string LLAppViewerWin32::sWindowClass = "Second Life";
+/*
+ This function is used to print to the command line a text message
+ describing the nvapi error and quits
+*/
+void nvapi_error(NvAPI_Status status)
+{
+ NvAPI_ShortString szDesc = {0};
+ NvAPI_GetErrorMessage(status, szDesc);
+ llwarns << szDesc << llendl;
+
+ //should always trigger when asserts are enabled
+ //llassert(status == NVAPI_OK);
+}
+
// Create app mutex creates a unique global windows object.
// If the object can be created it returns true, otherwise
// it returns false. The false result can be used to determine
@@ -97,6 +116,78 @@ bool create_app_mutex()
return result;
}
+void ll_nvapi_init(NvDRSSessionHandle hSession)
+{
+ // (2) load all the system settings into the session
+ NvAPI_Status status = NvAPI_DRS_LoadSettings(hSession);
+ if (status != NVAPI_OK)
+ {
+ nvapi_error(status);
+ return;
+ }
+
+ NvAPI_UnicodeString profile_name;
+ std::string app_name = LLTrans::getString("APP_NAME");
+ llutf16string w_app_name = utf8str_to_utf16str(app_name);
+ wsprintf(profile_name, L"%s", w_app_name.c_str());
+ status = NvAPI_DRS_SetCurrentGlobalProfile(hSession, profile_name);
+ if (status != NVAPI_OK)
+ {
+ nvapi_error(status);
+ return;
+ }
+
+ // (3) Obtain the current profile.
+ NvDRSProfileHandle hProfile = 0;
+ status = NvAPI_DRS_GetCurrentGlobalProfile(hSession, &hProfile);
+ if (status != NVAPI_OK)
+ {
+ nvapi_error(status);
+ return;
+ }
+
+ // load settings for querying
+ status = NvAPI_DRS_LoadSettings(hSession);
+ if (status != NVAPI_OK)
+ {
+ nvapi_error(status);
+ return;
+ }
+
+ //get the preferred power management mode for Second Life
+ NVDRS_SETTING drsSetting = {0};
+ drsSetting.version = NVDRS_SETTING_VER;
+ status = NvAPI_DRS_GetSetting(hSession, hProfile, PREFERRED_PSTATE_ID, &drsSetting);
+ if (status == NVAPI_SETTING_NOT_FOUND)
+ { //only override if the user hasn't specifically set this setting
+ // (4) Specify that we want the VSYNC disabled setting
+ // first we fill the NVDRS_SETTING struct, then we call the function
+ drsSetting.version = NVDRS_SETTING_VER;
+ drsSetting.settingId = PREFERRED_PSTATE_ID;
+ drsSetting.settingType = NVDRS_DWORD_TYPE;
+ drsSetting.u32CurrentValue = PREFERRED_PSTATE_PREFER_MAX;
+ status = NvAPI_DRS_SetSetting(hSession, hProfile, &drsSetting);
+ if (status != NVAPI_OK)
+ {
+ nvapi_error(status);
+ return;
+ }
+
+ // (5) Now we apply (or save) our changes to the system
+ status = NvAPI_DRS_SaveSettings(hSession);
+ if (status != NVAPI_OK)
+ {
+ nvapi_error(status);
+ return;
+ }
+ }
+ else if (status != NVAPI_OK)
+ {
+ nvapi_error(status);
+ return;
+ }
+}
+
//#define DEBUGGING_SEH_FILTER 1
#if DEBUGGING_SEH_FILTER
# define WINMAIN DebuggingWinMain
@@ -117,19 +208,21 @@ int APIENTRY WINMAIN(HINSTANCE hInstance,
#endif // _DEBUG
#endif // INCLUDE_VLD
- LLMemType mt1(LLMemType::MTYPE_STARTUP);
-
const S32 MAX_HEAPS = 255;
DWORD heap_enable_lfh_error[MAX_HEAPS];
S32 num_heaps = 0;
#if WINDOWS_CRT_MEM_CHECKS && !INCLUDE_VLD
_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); // dump memory leaks on exit
-#elif 1
+#elif 0
// Experimental - enable the low fragmentation heap
// This results in a 2-3x improvement in opening a new Inventory window (which uses a large numebr of allocations)
// Note: This won't work when running from the debugger unless the _NO_DEBUG_HEAP environment variable is set to 1
+ // Enable to get mem debugging within visual studio.
+#if LL_DEBUG
+ _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
+#else
_CrtSetDbgFlag(0); // default, just making explicit
ULONG ulEnableLFH = 2;
@@ -144,6 +237,7 @@ int APIENTRY WINMAIN(HINSTANCE hInstance,
heap_enable_lfh_error[i] = GetLastError();
}
#endif
+#endif
// *FIX: global
gIconResource = MAKEINTRESOURCE(IDI_LL_ICON);
@@ -163,6 +257,27 @@ int APIENTRY WINMAIN(HINSTANCE hInstance,
return -1;
}
+ NvAPI_Status status;
+
+ // Initialize NVAPI
+ status = NvAPI_Initialize();
+ NvDRSSessionHandle hSession = 0;
+
+ if (status == NVAPI_OK)
+ {
+ // Create the session handle to access driver settings
+ status = NvAPI_DRS_CreateSession(&hSession);
+ if (status != NVAPI_OK)
+ {
+ nvapi_error(status);
+ }
+ else
+ {
+ //override driver setting as needed
+ ll_nvapi_init(hSession);
+ }
+ }
+
// Have to wait until after logging is initialized to display LFH info
if (num_heaps > 0)
{
@@ -230,6 +345,15 @@ int APIENTRY WINMAIN(HINSTANCE hInstance,
LLAppViewer::sUpdaterInfo = NULL ;
}
+
+
+ // (NVAPI) (6) We clean up. This is analogous to doing a free()
+ if (hSession)
+ {
+ NvAPI_DRS_DestroySession(hSession);
+ hSession = 0;
+ }
+
return 0;
}
@@ -365,7 +489,7 @@ bool LLAppViewerWin32::init()
// (Don't send our data to Microsoft--at least until we are Logo approved and have a way
// of getting the data back from them.)
//
- llinfos << "Turning off Windows error reporting." << llendl;
+ // llinfos << "Turning off Windows error reporting." << llendl;
disableWinErrorReporting();
#ifndef LL_RELEASE_FOR_DOWNLOAD
@@ -384,9 +508,9 @@ bool LLAppViewerWin32::cleanup()
return result;
}
-bool LLAppViewerWin32::initLogging()
+void LLAppViewerWin32::initLoggingAndGetLastDuration()
{
- return LLAppViewer::initLogging();
+ LLAppViewer::initLoggingAndGetLastDuration();
}
void LLAppViewerWin32::initConsole()
diff --git a/indra/newview/llappviewerwin32.h b/indra/newview/llappviewerwin32.h
index 67594aea48..386bddd495 100644..100755
--- a/indra/newview/llappviewerwin32.h
+++ b/indra/newview/llappviewerwin32.h
@@ -44,7 +44,7 @@ public:
virtual bool cleanup();
protected:
- virtual bool initLogging(); // Override to clean stack_trace info.
+ virtual void initLoggingAndGetLastDuration(); // Override to clean stack_trace info.
virtual void initConsole(); // Initialize OS level debugging console.
virtual bool initHardwareTest(); // Win32 uses DX9 to test hardware.
virtual bool initParseCommandLine(LLCommandLineParser& clp);
diff --git a/indra/newview/llassetuploadqueue.cpp b/indra/newview/llassetuploadqueue.cpp
index f943759bb8..4bdb690225 100644..100755
--- a/indra/newview/llassetuploadqueue.cpp
+++ b/indra/newview/llassetuploadqueue.cpp
@@ -69,10 +69,11 @@ public:
delete mData;
}
- virtual void error(U32 statusNum, const std::string& reason)
+ virtual void errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content)
{
- llwarns << "Error: " << reason << llendl;
- LLUpdateTaskInventoryResponder::error(statusNum, reason);
+ llwarns << "LLAssetUploadChainResponder Error [status:"
+ << statusNum << "]: " << content << llendl;
+ LLUpdateTaskInventoryResponder::errorWithContent(statusNum, reason, content);
LLAssetUploadQueue *queue = mSupplier->get();
if (queue)
{
diff --git a/indra/newview/llassetuploadqueue.h b/indra/newview/llassetuploadqueue.h
index 434f3e5c03..434f3e5c03 100644..100755
--- a/indra/newview/llassetuploadqueue.h
+++ b/indra/newview/llassetuploadqueue.h
diff --git a/indra/newview/llassetuploadresponders.cpp b/indra/newview/llassetuploadresponders.cpp
index 65bfc990d1..2564802387 100644..100755
--- a/indra/newview/llassetuploadresponders.cpp
+++ b/indra/newview/llassetuploadresponders.cpp
@@ -48,8 +48,8 @@
#include "llviewercontrol.h"
#include "llviewerobjectlist.h"
#include "llviewermenufile.h"
+#include "llviewertexlayer.h"
#include "llviewerwindow.h"
-#include "lltexlayer.h"
#include "lltrans.h"
// library includes
@@ -225,10 +225,10 @@ LLAssetUploadResponder::~LLAssetUploadResponder()
}
// virtual
-void LLAssetUploadResponder::error(U32 statusNum, const std::string& reason)
+void LLAssetUploadResponder::errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content)
{
- llinfos << "LLAssetUploadResponder::error " << statusNum
- << " reason: " << reason << llendl;
+ llinfos << "LLAssetUploadResponder::error [status:"
+ << statusNum << "]: " << content << llendl;
LLSD args;
switch(statusNum)
{
@@ -340,9 +340,9 @@ LLNewAgentInventoryResponder::LLNewAgentInventoryResponder(
}
// virtual
-void LLNewAgentInventoryResponder::error(U32 statusNum, const std::string& reason)
+void LLNewAgentInventoryResponder::errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content)
{
- LLAssetUploadResponder::error(statusNum, reason);
+ LLAssetUploadResponder::errorWithContent(statusNum, reason, content);
//LLImportColladaAssetCache::getInstance()->assetUploaded(mVFileID, LLUUID(), FALSE);
}
@@ -456,7 +456,7 @@ LLSendTexLayerResponder::LLSendTexLayerResponder(const LLSD& post_data,
LLSendTexLayerResponder::~LLSendTexLayerResponder()
{
- // mBakedUploadData is normally deleted by calls to LLTexLayerSetBuffer::onTextureUploadComplete() below
+ // mBakedUploadData is normally deleted by calls to LLViewerTexLayerSetBuffer::onTextureUploadComplete() below
if (mBakedUploadData)
{ // ...but delete it in the case where uploadComplete() is never called
delete mBakedUploadData;
@@ -477,22 +477,23 @@ void LLSendTexLayerResponder::uploadComplete(const LLSD& content)
if (result == "complete"
&& mBakedUploadData != NULL)
{ // Invoke
- LLTexLayerSetBuffer::onTextureUploadComplete(new_id, (void*) mBakedUploadData, 0, LL_EXSTAT_NONE);
+ LLViewerTexLayerSetBuffer::onTextureUploadComplete(new_id, (void*) mBakedUploadData, 0, LL_EXSTAT_NONE);
mBakedUploadData = NULL; // deleted in onTextureUploadComplete()
}
else
{ // Invoke the original callback with an error result
- LLTexLayerSetBuffer::onTextureUploadComplete(new_id, (void*) mBakedUploadData, -1, LL_EXSTAT_NONE);
+ LLViewerTexLayerSetBuffer::onTextureUploadComplete(new_id, (void*) mBakedUploadData, -1, LL_EXSTAT_NONE);
mBakedUploadData = NULL; // deleted in onTextureUploadComplete()
}
}
-void LLSendTexLayerResponder::error(U32 statusNum, const std::string& reason)
+void LLSendTexLayerResponder::errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content)
{
- llinfos << "status: " << statusNum << " reason: " << reason << llendl;
+ llinfos << "LLSendTexLayerResponder error [status:"
+ << statusNum << "]: " << content << llendl;
// Invoke the original callback with an error result
- LLTexLayerSetBuffer::onTextureUploadComplete(LLUUID(), (void*) mBakedUploadData, -1, LL_EXSTAT_NONE);
+ LLViewerTexLayerSetBuffer::onTextureUploadComplete(LLUUID(), (void*) mBakedUploadData, -1, LL_EXSTAT_NONE);
mBakedUploadData = NULL; // deleted in onTextureUploadComplete()
}
@@ -919,7 +920,7 @@ public:
bool uploadConfirmationCallback(
const LLSD& notification,
const LLSD& response,
- boost::intrusive_ptr<LLNewAgentInventoryVariablePriceResponder> responder)
+ LLPointer<LLNewAgentInventoryVariablePriceResponder> responder)
{
S32 option;
std::string confirmation_url;
@@ -949,7 +950,7 @@ public:
void confirmUpload(
const std::string& confirmation_url,
- boost::intrusive_ptr<LLNewAgentInventoryVariablePriceResponder> responder)
+ LLPointer<LLNewAgentInventoryVariablePriceResponder> responder)
{
if ( getFilename().empty() )
{
@@ -1124,7 +1125,7 @@ void LLNewAgentInventoryVariablePriceResponder::showConfirmationDialog(
// and cause sadness.
mImpl->confirmUpload(
confirmation_url,
- boost::intrusive_ptr<LLNewAgentInventoryVariablePriceResponder>(this));
+ LLPointer<LLNewAgentInventoryVariablePriceResponder>(this));
}
else
{
@@ -1157,7 +1158,7 @@ void LLNewAgentInventoryVariablePriceResponder::showConfirmationDialog(
mImpl,
_1,
_2,
- boost::intrusive_ptr<LLNewAgentInventoryVariablePriceResponder>(this)));
+ LLPointer<LLNewAgentInventoryVariablePriceResponder>(this)));
}
}
diff --git a/indra/newview/llassetuploadresponders.h b/indra/newview/llassetuploadresponders.h
index 381b919c4a..a6d1016136 100644..100755
--- a/indra/newview/llassetuploadresponders.h
+++ b/indra/newview/llassetuploadresponders.h
@@ -42,7 +42,7 @@ public:
LLAssetType::EType asset_type);
~LLAssetUploadResponder();
- virtual void error(U32 statusNum, const std::string& reason);
+ virtual void errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content);
virtual void result(const LLSD& content);
virtual void uploadUpload(const LLSD& content);
virtual void uploadComplete(const LLSD& content);
@@ -67,7 +67,7 @@ public:
const LLSD& post_data,
const std::string& file_name,
LLAssetType::EType asset_type);
- virtual void error(U32 statusNum, const std::string& reason);
+ virtual void errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content);
virtual void uploadComplete(const LLSD& content);
virtual void uploadFailure(const LLSD& content);
};
@@ -122,7 +122,7 @@ public:
~LLSendTexLayerResponder();
virtual void uploadComplete(const LLSD& content);
- virtual void error(U32 statusNum, const std::string& reason);
+ virtual void errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content);
LLBakedUploadData * mBakedUploadData;
};
diff --git a/indra/newview/llattachmentsmgr.cpp b/indra/newview/llattachmentsmgr.cpp
index c9543988a6..ea0b8f00a4 100644..100755
--- a/indra/newview/llattachmentsmgr.cpp
+++ b/indra/newview/llattachmentsmgr.cpp
@@ -62,6 +62,12 @@ void LLAttachmentsMgr::onIdle(void *)
void LLAttachmentsMgr::onIdle()
{
+ // Make sure we got a region before trying anything else
+ if( !gAgent.getRegion() )
+ {
+ return;
+ }
+
S32 obj_count = mPendingAttachments.size();
if (obj_count == 0)
{
diff --git a/indra/newview/llattachmentsmgr.h b/indra/newview/llattachmentsmgr.h
index 1d8ab74dfd..1d8ab74dfd 100644..100755
--- a/indra/newview/llattachmentsmgr.h
+++ b/indra/newview/llattachmentsmgr.h
diff --git a/indra/newview/llaudiosourcevo.cpp b/indra/newview/llaudiosourcevo.cpp
index b37aba6c15..b37aba6c15 100644..100755
--- a/indra/newview/llaudiosourcevo.cpp
+++ b/indra/newview/llaudiosourcevo.cpp
diff --git a/indra/newview/llaudiosourcevo.h b/indra/newview/llaudiosourcevo.h
index f1d8ef4528..f1d8ef4528 100644..100755
--- a/indra/newview/llaudiosourcevo.h
+++ b/indra/newview/llaudiosourcevo.h
diff --git a/indra/newview/llautoreplace.cpp b/indra/newview/llautoreplace.cpp
new file mode 100755
index 0000000000..dd9354fe3a
--- /dev/null
+++ b/indra/newview/llautoreplace.cpp
@@ -0,0 +1,802 @@
+/**
+ * @file llautoreplace.cpp
+ * @brief Auto Replace Manager
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * 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
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+#include "llautoreplace.h"
+#include "llsdserialize.h"
+#include "llboost.h"
+#include "llcontrol.h"
+#include "llviewercontrol.h"
+#include "llnotificationsutil.h"
+
+const char* LLAutoReplace::SETTINGS_FILE_NAME = "autoreplace.xml";
+
+void LLAutoReplace::autoreplaceCallback(S32& replacement_start, S32& replacement_length, LLWString& replacement_string, S32& cursor_pos, const LLWString& input_text)
+{
+ // make sure these returned values are cleared in case there is no replacement
+ replacement_start = 0;
+ replacement_length = 0;
+ replacement_string.clear();
+
+ static LLCachedControl<bool> perform_autoreplace(gSavedSettings, "AutoReplace", 0);
+ if (perform_autoreplace)
+ {
+ S32 word_end = cursor_pos - 1;
+
+ bool at_space = (input_text[word_end] == ' ');
+ bool have_word = (LLWStringUtil::isPartOfWord(input_text[word_end]));
+
+ if (at_space || have_word)
+ {
+ if (at_space && word_end > 0)
+ {
+ // find out if this space immediately follows a word
+ word_end--;
+ have_word = (LLWStringUtil::isPartOfWord(input_text[word_end]));
+ }
+ if (have_word)
+ {
+ // word_end points to the end of a word, now find the start of the word
+ std::string word;
+ S32 word_start = word_end;
+ for (S32 back_one = word_start - 1;
+ back_one >= 0 && LLWStringUtil::isPartOfWord(input_text[back_one]);
+ back_one--
+ )
+ {
+ word_start--; // walk word_start back to the beginning of the word
+ }
+ LL_DEBUGS("AutoReplace") << "word_start: " << word_start << " word_end: " << word_end << LL_ENDL;
+ std::string str_text = std::string(input_text.begin(), input_text.end());
+ std::string last_word = str_text.substr(word_start, word_end - word_start + 1);
+ std::string replacement_word(mSettings.replaceWord(last_word));
+
+ if (replacement_word != last_word)
+ {
+ // The last word is one for which we have a replacement
+ if (at_space)
+ {
+ // return the replacement string
+ replacement_start = word_start;
+ replacement_length = last_word.length();
+ replacement_string = utf8str_to_wstring(replacement_word);
+ LLWString old_string = utf8str_to_wstring(last_word);
+ S32 size_change = replacement_string.size() - old_string.size();
+ cursor_pos += size_change;
+ }
+ }
+ }
+ }
+ }
+}
+
+std::string LLAutoReplace::getUserSettingsFileName()
+{
+ std::string path=gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "");
+
+ if (!path.empty())
+ {
+ path = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, SETTINGS_FILE_NAME);
+ }
+ return path;
+}
+
+std::string LLAutoReplace::getAppSettingsFileName()
+{
+ std::string path=gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "");
+
+ if (!path.empty())
+ {
+ path = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, SETTINGS_FILE_NAME);
+ }
+ else
+ {
+ LL_ERRS("AutoReplace") << "Failed to get app settings directory name" << LL_ENDL;
+ }
+ return path;
+}
+
+LLAutoReplaceSettings LLAutoReplace::getSettings()
+{
+ return mSettings;
+}
+
+void LLAutoReplace::setSettings(const LLAutoReplaceSettings& newSettings)
+{
+ mSettings.set(newSettings);
+ /// Make the newSettings active and write them to user storage
+ saveToUserSettings();
+}
+
+LLAutoReplace::LLAutoReplace()
+{
+}
+
+void LLAutoReplace::initSingleton()
+{
+ loadFromSettings();
+}
+
+void LLAutoReplace::loadFromSettings()
+{
+ std::string filename=getUserSettingsFileName();
+ if (filename.empty())
+ {
+ LL_INFOS("AutoReplace") << "no valid user settings directory." << LL_ENDL;
+ }
+ if(gDirUtilp->fileExists(filename))
+ {
+ LLSD userSettings;
+ llifstream file;
+ file.open(filename.c_str());
+ if (file.is_open())
+ {
+ LLSDSerialize::fromXML(userSettings, file);
+ }
+ file.close();
+ if ( mSettings.setFromLLSD(userSettings) )
+ {
+ LL_INFOS("AutoReplace") << "settings loaded from '" << filename << "'" << LL_ENDL;
+ }
+ else
+ {
+ LL_WARNS("AutoReplace") << "invalid settings found in '" << filename << "'" << LL_ENDL;
+ }
+ }
+ else // no user settings found, try application settings
+ {
+ std::string defaultName = getAppSettingsFileName();
+ LL_INFOS("AutoReplace") << " user settings file '" << filename << "' not found"<< LL_ENDL;
+
+ bool gotSettings = false;
+ if(gDirUtilp->fileExists(defaultName))
+ {
+ LLSD appDefault;
+ llifstream file;
+ file.open(defaultName.c_str());
+ if (file.is_open())
+ {
+ LLSDSerialize::fromXMLDocument(appDefault, file);
+ }
+ file.close();
+
+ if ( mSettings.setFromLLSD(appDefault) )
+ {
+ LL_INFOS("AutoReplace") << "settings loaded from '" << defaultName.c_str() << "'" << LL_ENDL;
+ gotSettings = true;
+ }
+ else
+ {
+ LL_WARNS("AutoReplace") << "invalid settings found in '" << defaultName.c_str() << "'" << LL_ENDL;
+ }
+ }
+
+ if ( ! gotSettings )
+ {
+ if (mSettings.setFromLLSD(mSettings.getExampleLLSD()))
+ {
+ LL_WARNS("AutoReplace") << "no settings found; loaded example." << LL_ENDL;
+ }
+ else
+ {
+ LL_WARNS("AutoReplace") << "no settings found and example invalid!" << LL_ENDL;
+ }
+ }
+ }
+}
+
+void LLAutoReplace::saveToUserSettings()
+{
+ std::string filename=getUserSettingsFileName();
+ llofstream file;
+ file.open(filename.c_str());
+ LLSDSerialize::toPrettyXML(mSettings.asLLSD(), file);
+ file.close();
+ LL_INFOS("AutoReplace") << "settings saved to '" << filename << "'" << LL_ENDL;
+}
+
+// ================================================================
+// LLAutoReplaceSettings
+// ================================================================
+
+const std::string LLAutoReplaceSettings::AUTOREPLACE_LIST_NAME = "name"; ///< key for looking up list names
+const std::string LLAutoReplaceSettings::AUTOREPLACE_LIST_REPLACEMENTS = "replacements"; ///< key for looking up replacement map
+
+LLAutoReplaceSettings::LLAutoReplaceSettings()
+{
+}
+
+LLAutoReplaceSettings::LLAutoReplaceSettings(const LLAutoReplaceSettings& settings)
+{
+ // copy all values through fundamental type intermediates for thread safety
+ mLists = LLSD::emptyArray();
+
+ for ( LLSD::array_const_iterator list = settings.mLists.beginArray(), listEnd = settings.mLists.endArray();
+ list != listEnd;
+ list++
+ )
+ {
+ if ( (*list).isMap() ) // can fail due to LLSD-30: ignore it
+ {
+ LLSD listMap = LLSD::emptyMap();
+ std::string listName = (*list)[AUTOREPLACE_LIST_NAME];
+ listMap[AUTOREPLACE_LIST_NAME] = listName;
+ listMap[AUTOREPLACE_LIST_REPLACEMENTS] = LLSD::emptyMap();
+
+ for ( LLSD::map_const_iterator
+ entry = (*list)[AUTOREPLACE_LIST_REPLACEMENTS].beginMap(),
+ entriesEnd = (*list)[AUTOREPLACE_LIST_REPLACEMENTS].endMap();
+ entry != entriesEnd;
+ entry++
+ )
+ {
+ std::string keyword = entry->first;
+ std::string replacement = entry->second.asString();
+ listMap[AUTOREPLACE_LIST_REPLACEMENTS].insert(keyword, LLSD(replacement));
+ }
+
+ mLists.append(listMap);
+ }
+ }
+}
+
+void LLAutoReplaceSettings::set(const LLAutoReplaceSettings& newSettings)
+{
+ mLists = newSettings.mLists;
+}
+
+bool LLAutoReplaceSettings::setFromLLSD(const LLSD& settingsFromLLSD)
+{
+ bool settingsValid = true;
+
+ if ( settingsFromLLSD.isArray() )
+ {
+ for ( LLSD::array_const_iterator
+ list = settingsFromLLSD.beginArray(),
+ listEnd = settingsFromLLSD.endArray();
+ settingsValid && list != listEnd;
+ list++
+ )
+ {
+ if ( (*list).isDefined() ) // can be undef due to LLSD-30: ignore it
+ {
+ settingsValid = listIsValid(*list);
+ }
+ }
+ }
+ else
+ {
+ settingsValid = false;
+ LL_WARNS("AutoReplace") << "settings are not an array" << LL_ENDL;
+ }
+
+ if ( settingsValid )
+ {
+ mLists = settingsFromLLSD;
+ }
+ else
+ {
+ LL_WARNS("AutoReplace") << "invalid settings discarded; using hard coded example" << LL_ENDL;
+ }
+
+ return settingsValid;
+}
+
+bool LLAutoReplaceSettings::listNameMatches( const LLSD& list, const std::string name )
+{
+ return list.isMap()
+ && list.has(AUTOREPLACE_LIST_NAME)
+ && list[AUTOREPLACE_LIST_NAME].asString() == name;
+}
+
+const LLSD* LLAutoReplaceSettings::getListEntries(std::string listName)
+{
+ const LLSD* returnedEntries = NULL;
+ for( LLSD::array_const_iterator list = mLists.beginArray(), endList = mLists.endArray();
+ returnedEntries == NULL && list != endList;
+ list++
+ )
+ {
+ const LLSD& thisList = *list;
+ if ( listNameMatches(thisList, listName) )
+ {
+ returnedEntries = &thisList[AUTOREPLACE_LIST_REPLACEMENTS];
+ }
+ }
+ return returnedEntries;
+}
+
+std::string LLAutoReplaceSettings::replacementFor(std::string keyword, std::string listName)
+{
+ std::string replacement;
+ bool foundList = false;
+ for( LLSD::array_const_iterator list = mLists.beginArray(), endList = mLists.endArray();
+ ! foundList && list != endList;
+ list++
+ )
+ {
+ const LLSD& thisList = *list;
+ if ( listNameMatches(thisList, listName) )
+ {
+ foundList = true; // whether there is a replacement or not, we're done
+ if ( thisList.isMap()
+ && thisList.has(AUTOREPLACE_LIST_REPLACEMENTS)
+ && thisList[AUTOREPLACE_LIST_REPLACEMENTS].has(keyword)
+ )
+ {
+ replacement = thisList[AUTOREPLACE_LIST_REPLACEMENTS][keyword].asString();
+ LL_DEBUGS("AutoReplace")<<"'"<<keyword<<"' -> '"<<replacement<<"'"<<LL_ENDL;
+ }
+ }
+ if (!foundList)
+ {
+ LL_WARNS("AutoReplace")<<"failed to find list '"<<listName<<"'"<<LL_ENDL;
+ }
+ }
+ if (replacement.empty())
+ {
+ LL_WARNS("AutoReplace")<<"failed to find '"<<keyword<<"'"<<LL_ENDL;
+ }
+ return replacement;
+}
+
+LLSD LLAutoReplaceSettings::getListNames()
+{
+ LL_DEBUGS("AutoReplace")<<"====="<<LL_ENDL;
+ LLSD toReturn = LLSD::emptyArray();
+ S32 counter=0;
+ for( LLSD::array_const_iterator list = mLists.beginArray(), endList = mLists.endArray();
+ list != endList;
+ list++
+ )
+ {
+ const LLSD& thisList = *list;
+ if ( thisList.isMap() )
+ {
+ if ( thisList.has(AUTOREPLACE_LIST_NAME) )
+ {
+ std::string name = thisList[AUTOREPLACE_LIST_NAME].asString();
+ LL_DEBUGS("AutoReplace")<<counter<<" '"<<name<<"'"<<LL_ENDL;
+ toReturn.append(LLSD(name));
+ }
+ else
+ {
+ LL_ERRS("AutoReplace") <<counter<<" ! MISSING "<<AUTOREPLACE_LIST_NAME<< LL_ENDL;
+ }
+ }
+ else
+ {
+ LL_WARNS("AutoReplace")<<counter<<" ! not a map: "<<LLSD::typeString(thisList.type())<< LL_ENDL;
+ }
+ counter++;
+ }
+ LL_DEBUGS("AutoReplace")<<"^^^^^^"<<LL_ENDL;
+ return toReturn;
+}
+
+bool LLAutoReplaceSettings::listIsValid(const LLSD& list)
+{
+ bool listValid = true;
+ if ( ! list.isMap() )
+ {
+ listValid = false;
+ LL_WARNS("AutoReplace") << "list is not a map" << LL_ENDL;
+ }
+ else if ( ! list.has(AUTOREPLACE_LIST_NAME)
+ || ! list[AUTOREPLACE_LIST_NAME].isString()
+ || list[AUTOREPLACE_LIST_NAME].asString().empty()
+ )
+ {
+ listValid = false;
+ LL_WARNS("AutoReplace")
+ << "list found without " << AUTOREPLACE_LIST_NAME
+ << " (or it is empty)"
+ << LL_ENDL;
+ }
+ else if ( ! list.has(AUTOREPLACE_LIST_REPLACEMENTS) || ! list[AUTOREPLACE_LIST_REPLACEMENTS].isMap() )
+ {
+ listValid = false;
+ LL_WARNS("AutoReplace") << "list '" << list[AUTOREPLACE_LIST_NAME].asString() << "' without " << AUTOREPLACE_LIST_REPLACEMENTS << LL_ENDL;
+ }
+ else
+ {
+ for ( LLSD::map_const_iterator
+ entry = list[AUTOREPLACE_LIST_REPLACEMENTS].beginMap(),
+ entriesEnd = list[AUTOREPLACE_LIST_REPLACEMENTS].endMap();
+ listValid && entry != entriesEnd;
+ entry++
+ )
+ {
+ if ( ! entry->second.isString() )
+ {
+ listValid = false;
+ LL_WARNS("AutoReplace")
+ << "non-string replacement value found in list '"
+ << list[AUTOREPLACE_LIST_NAME].asString() << "'"
+ << LL_ENDL;
+ }
+ }
+ }
+
+ return listValid;
+}
+
+const LLSD* LLAutoReplaceSettings::exportList(std::string listName)
+{
+ const LLSD* exportedList = NULL;
+ for ( LLSD::array_const_iterator list = mLists.beginArray(), listEnd = mLists.endArray();
+ exportedList == NULL && list != listEnd;
+ list++
+ )
+ {
+ if ( listNameMatches(*list, listName) )
+ {
+ const LLSD& namedList = (*list);
+ exportedList = &namedList;
+ }
+ }
+ return exportedList;
+}
+
+bool LLAutoReplaceSettings::listNameIsUnique(const LLSD& newList)
+{
+ bool nameIsUnique = true;
+ // this must always be called with a valid list, so it is safe to assume it has a name
+ std::string newListName = newList[AUTOREPLACE_LIST_NAME].asString();
+ for ( LLSD::array_const_iterator list = mLists.beginArray(), listEnd = mLists.endArray();
+ nameIsUnique && list != listEnd;
+ list++
+ )
+ {
+ if ( listNameMatches(*list, newListName) )
+ {
+ LL_WARNS("AutoReplace")<<"duplicate list name '"<<newListName<<"'"<<LL_ENDL;
+ nameIsUnique = false;
+ }
+ }
+ return nameIsUnique;
+}
+
+/* static */
+void LLAutoReplaceSettings::createEmptyList(LLSD& emptyList)
+{
+ emptyList = LLSD::emptyMap();
+ emptyList[AUTOREPLACE_LIST_NAME] = "Empty";
+ emptyList[AUTOREPLACE_LIST_REPLACEMENTS] = LLSD::emptyMap();
+}
+
+/* static */
+void LLAutoReplaceSettings::setListName(LLSD& list, const std::string& newName)
+{
+ list[AUTOREPLACE_LIST_NAME] = newName;
+}
+
+/* static */
+std::string LLAutoReplaceSettings::getListName(LLSD& list)
+{
+ std::string name;
+ if ( list.isMap() && list.has(AUTOREPLACE_LIST_NAME) && list[AUTOREPLACE_LIST_NAME].isString() )
+ {
+ name = list[AUTOREPLACE_LIST_NAME].asString();
+ }
+ return name;
+}
+
+LLAutoReplaceSettings::AddListResult LLAutoReplaceSettings::addList(const LLSD& newList)
+{
+ AddListResult result;
+ if ( listIsValid( newList ) )
+ {
+ if ( listNameIsUnique( newList ) )
+ {
+ mLists.append(newList);
+ result = AddListOk;
+ }
+ else
+ {
+ LL_WARNS("AutoReplace") << "attempt to add duplicate name" << LL_ENDL;
+ result = AddListDuplicateName;
+ }
+ }
+ else
+ {
+ LL_WARNS("AutoReplace") << "attempt to add invalid list" << LL_ENDL;
+ result = AddListInvalidList;
+ }
+ return result;
+}
+
+LLAutoReplaceSettings::AddListResult LLAutoReplaceSettings::replaceList(const LLSD& newList)
+{
+ AddListResult result = AddListInvalidList;
+ if ( listIsValid( newList ) )
+ {
+ std::string listName = newList[AUTOREPLACE_LIST_NAME].asString();
+ bool listFound = false;
+ S32 search_index;
+ LLSD targetList;
+ // The following is working around the fact that LLSD arrays containing maps also seem to have undefined entries... see LLSD-30
+ for ( search_index = 0, targetList = mLists[0];
+ !listFound && search_index < mLists.size();
+ search_index += 1, targetList = mLists[search_index]
+ )
+ {
+ if ( targetList.isMap() )
+ {
+ if ( listNameMatches( targetList, listName) )
+ {
+ LL_DEBUGS("AutoReplace")<<"list to replace found at "<<search_index<<LL_ENDL;
+ mLists.erase(search_index);
+ mLists.insert(search_index, newList);
+ listFound = true;
+ result = AddListOk;
+ }
+ }
+ }
+
+ if ( ! listFound )
+ {
+ LL_WARNS("AutoReplace") << "attempt to replace unconfigured list" << LL_ENDL;
+ }
+ }
+ else
+ {
+ LL_WARNS("AutoReplace") << "attempt to add invalid list" << LL_ENDL;
+ }
+ return result;
+}
+
+bool LLAutoReplaceSettings::removeReplacementList(std::string listName)
+{
+ bool found = false;
+ for( S32 index = 0; !found && mLists[index].isDefined(); index++ )
+ {
+ if( listNameMatches(mLists.get(index), listName) )
+ {
+ LL_DEBUGS("AutoReplace")<<"list '"<<listName<<"'"<<LL_ENDL;
+ mLists.erase(index);
+ found = true;
+ }
+ }
+ return found;
+}
+
+/// Move the named list up in the priority order
+bool LLAutoReplaceSettings::increaseListPriority(std::string listName)
+{
+ LL_DEBUGS("AutoReplace")<<listName<<LL_ENDL;
+ bool found = false;
+ S32 search_index, previous_index;
+ LLSD targetList;
+ // The following is working around the fact that LLSD arrays containing maps also seem to have undefined entries... see LLSD-30
+ previous_index = -1;
+ for ( search_index = 0, targetList = mLists[0];
+ !found && search_index < mLists.size();
+ search_index += 1, targetList = mLists[search_index]
+ )
+ {
+ if ( targetList.isMap() )
+ {
+ if ( listNameMatches( targetList, listName) )
+ {
+ LL_DEBUGS("AutoReplace")<<"found at "<<search_index<<", previous is "<<previous_index<<LL_ENDL;
+ found = true;
+ if (previous_index >= 0)
+ {
+ LL_DEBUGS("AutoReplace") << "erase "<<search_index<<LL_ENDL;
+ mLists.erase(search_index);
+ LL_DEBUGS("AutoReplace") << "insert at "<<previous_index<<LL_ENDL;
+ mLists.insert(previous_index, targetList);
+ }
+ else
+ {
+ LL_WARNS("AutoReplace") << "attempted to move top list up" << LL_ENDL;
+ }
+ }
+ else
+ {
+ previous_index = search_index;
+ }
+ }
+ else
+ {
+ LL_DEBUGS("AutoReplace") << search_index<<" is "<<LLSD::typeString(targetList.type())<<LL_ENDL;
+ }
+ }
+ return found;
+}
+
+/// Move the named list down in the priority order
+bool LLAutoReplaceSettings::decreaseListPriority(std::string listName)
+{
+ LL_DEBUGS("AutoReplace")<<listName<<LL_ENDL;
+ S32 found_index = -1;
+ S32 search_index;
+ for ( search_index = 0;
+ found_index == -1 && search_index < mLists.size();
+ search_index++
+ )
+ {
+ if ( listNameMatches( mLists[search_index], listName) )
+ {
+ LL_DEBUGS("AutoReplace")<<"found at index "<<search_index<<LL_ENDL;
+ found_index = search_index;
+ }
+ }
+ if (found_index != -1)
+ {
+ S32 next_index;
+ for ( next_index = found_index+1;
+ next_index < mLists.size() && ! mLists[next_index].isMap();
+ next_index++
+ )
+ {
+ // skipping over any undefined slots (see LLSD-30)
+ LL_WARNS("AutoReplace")<<next_index<<" ! not a map: "<<LLSD::typeString(mLists[next_index].type())<< LL_ENDL;
+ }
+ if ( next_index < mLists.size() )
+ {
+ LLSD next_list = mLists[next_index];
+ LL_DEBUGS("AutoReplace") << "erase "<<next_index<<LL_ENDL;
+ mLists.erase(next_index);
+ LL_DEBUGS("AutoReplace") << "insert at "<<found_index<<LL_ENDL;
+ mLists.insert(found_index, next_list);
+ }
+ else
+ {
+ LL_WARNS("AutoReplace") << "attempted to move bottom list down" << LL_ENDL;
+ }
+ }
+ else
+ {
+ LL_WARNS("AutoReplace") << "not found" << LL_ENDL;
+ }
+ return (found_index != -1);
+}
+
+
+std::string LLAutoReplaceSettings::replaceWord(const std::string currentWord)
+{
+ std::string returnedWord = currentWord; // in case no replacement is found
+ static LLCachedControl<bool> autoreplace_enabled(gSavedSettings, "AutoReplace", false);
+ if ( autoreplace_enabled )
+ {
+ LL_DEBUGS("AutoReplace")<<"checking '"<<currentWord<<"'"<< LL_ENDL;
+ //loop through lists in order
+ bool found = false;
+ for( LLSD::array_const_iterator list = mLists.beginArray(), endLists = mLists.endArray();
+ ! found && list != endLists;
+ list++
+ )
+ {
+ const LLSD& checkList = *list;
+ const LLSD& replacements = checkList[AUTOREPLACE_LIST_REPLACEMENTS];
+
+ if ( replacements.has(currentWord) )
+ {
+ found = true;
+ LL_DEBUGS("AutoReplace")
+ << " found in list '" << checkList[AUTOREPLACE_LIST_NAME].asString()
+ << " => '" << replacements[currentWord].asString() << "'"
+ << LL_ENDL;
+ returnedWord = replacements[currentWord].asString();
+ }
+ }
+ }
+ return returnedWord;
+}
+
+bool LLAutoReplaceSettings::addEntryToList(LLWString keyword, LLWString replacement, std::string listName)
+{
+ bool added = false;
+
+ if ( ! keyword.empty() && ! replacement.empty() )
+ {
+ bool isOneWord = true;
+ for (S32 character = 0; isOneWord && character < keyword.size(); character++ )
+ {
+ if ( ! LLWStringUtil::isPartOfWord(keyword[character]) )
+ {
+ LL_WARNS("AutoReplace") << "keyword '" << wstring_to_utf8str(keyword) << "' not a single word (len "<<keyword.size()<<" '"<<character<<"')" << LL_ENDL;
+ isOneWord = false;
+ }
+ }
+
+ if ( isOneWord )
+ {
+ bool listFound = false;
+ for( LLSD::array_iterator list = mLists.beginArray(), endLists = mLists.endArray();
+ ! listFound && list != endLists;
+ list++
+ )
+ {
+ if ( listNameMatches(*list, listName) )
+ {
+ listFound = true;
+ (*list)[AUTOREPLACE_LIST_REPLACEMENTS][wstring_to_utf8str(keyword)]=wstring_to_utf8str(replacement);
+ }
+ }
+ if (listFound)
+ {
+ added = true;
+ }
+ else
+ {
+ LL_WARNS("AutoReplace") << "list '" << listName << "' not found" << LL_ENDL;
+ }
+ }
+ }
+
+ return added;
+}
+
+bool LLAutoReplaceSettings::removeEntryFromList(std::string keyword, std::string listName)
+{
+ bool found = false;
+ for( LLSD::array_iterator list = mLists.beginArray(), endLists = mLists.endArray();
+ ! found && list != endLists;
+ list++
+ )
+ {
+ if ( listNameMatches(*list, listName) )
+ {
+ found = true;
+ (*list)[AUTOREPLACE_LIST_REPLACEMENTS].erase(keyword);
+ }
+ }
+ if (!found)
+ {
+ LL_WARNS("AutoReplace") << "list '" << listName << "' not found" << LL_ENDL;
+ }
+ return found;
+}
+
+LLSD LLAutoReplaceSettings::getExampleLLSD()
+{
+ LL_DEBUGS("AutoReplace")<<LL_ENDL;
+ LLSD example = LLSD::emptyArray();
+
+ example[0] = LLSD::emptyMap();
+ example[0][AUTOREPLACE_LIST_NAME] = "Example List 1";
+ example[0][AUTOREPLACE_LIST_REPLACEMENTS] = LLSD::emptyMap();
+ example[0][AUTOREPLACE_LIST_REPLACEMENTS]["keyword1"] = "replacement string 1";
+ example[0][AUTOREPLACE_LIST_REPLACEMENTS]["keyword2"] = "replacement string 2";
+
+ example[1] = LLSD::emptyMap();
+ example[1][AUTOREPLACE_LIST_NAME] = "Example List 2";
+ example[1][AUTOREPLACE_LIST_REPLACEMENTS] = LLSD::emptyMap();
+ example[1][AUTOREPLACE_LIST_REPLACEMENTS]["mistake1"] = "correction 1";
+ example[1][AUTOREPLACE_LIST_REPLACEMENTS]["mistake2"] = "correction 2";
+
+ return example;
+}
+
+const LLSD& LLAutoReplaceSettings::asLLSD()
+{
+ return mLists;
+}
+
+LLAutoReplaceSettings::~LLAutoReplaceSettings()
+{
+}
diff --git a/indra/newview/llautoreplace.h b/indra/newview/llautoreplace.h
new file mode 100755
index 0000000000..9eecc2d981
--- /dev/null
+++ b/indra/newview/llautoreplace.h
@@ -0,0 +1,227 @@
+/**
+ * @file llautoreplace.h
+ * @brief Auto Replace Manager
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * 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
+ */
+#ifndef LLAUTOREPLACE_H
+#define LLAUTOREPLACE_H
+
+#include "lllineeditor.h"
+
+class LLAutoReplace;
+
+/** The configuration data for the LLAutoReplace object
+ *
+ * This is a separate class so that the LLFloaterAutoReplaceSettings
+ * can have a copy of the configuration to manipulate before committing
+ * the changes back to the LLAutoReplace singleton that provides the
+ * autoreplace callback.
+ */
+class LLAutoReplaceSettings
+{
+ public:
+ LLAutoReplaceSettings();
+ ~LLAutoReplaceSettings();
+
+ /// Constructor for creating a tempory copy of the current settings
+ LLAutoReplaceSettings(const LLAutoReplaceSettings& settings);
+
+ /// Replace the current settings with new ones and save them to the user settings file
+ void set(const LLAutoReplaceSettings& newSettings);
+
+ /// Load the current settings read from an LLSD file
+ bool setFromLLSD(const LLSD& settingsFromLLSD);
+ ///< @returns whether or not the settingsFromLLSD were valid
+
+ // ================================================================
+ ///@{ @name List Operations
+ // ================================================================
+
+ /// @returns the configured list names as an LLSD Array of strings
+ LLSD getListNames();
+
+ /// Status values returned from the addList method
+ typedef enum
+ {
+ AddListOk,
+ AddListDuplicateName,
+ AddListInvalidList,
+ } AddListResult;
+
+ /// Inserts a new list at the end of the priority order
+ AddListResult addList(const LLSD& newList);
+
+ /// Inserts a list in place of an existing list of the same name
+ AddListResult replaceList(const LLSD& newList);
+
+ /// Removes the named list, @returns false if not found
+ bool removeReplacementList(std::string listName);
+
+ /// Move the named list up in the priority order
+ bool increaseListPriority(std::string listName);
+ ///< @returns false if the list is not found
+
+ /// Move the named list down in the priority order
+ bool decreaseListPriority(std::string listName);
+ ///< @returns false if the list is not found
+
+ /// Get a copy of just one list (for saving to an export file)
+ const LLSD* exportList(std::string listName);
+ /// @returns an LLSD map
+
+ /// Checks for required elements, and that each has the correct type.
+ bool listIsValid(const LLSD& listSettings);
+
+ /// Checks for required elements, and that each has the correct type.
+ bool listNameIs(const LLSD& listSettings);
+
+ /// Checks to see if a new lists name conflicts with one in the settings
+ bool listNameIsUnique(const LLSD& newList);
+ /// @note must be called with LLSD that has passed listIsValid
+
+ /// Initializes emptyList to an empty list named 'Empty'
+ static void createEmptyList(LLSD& emptyList);
+
+ /// Resets the name of a list to a new value
+ static void setListName(LLSD& list, const std::string& newName);
+
+ /// Gets the name of a list
+ static std::string getListName(LLSD& list);
+
+ ///@}
+ // ================================================================
+ ///@{ @name Replacement Entry Operations
+ // ================================================================
+
+ /// Get the replacements specified by a given list
+ const LLSD* getListEntries(std::string listName);
+ ///< @returns an LLSD Map of keyword -> replacement test pairs
+
+ /// Get the replacement for the keyword from the specified list
+ std::string replacementFor(std::string keyword, std::string listName);
+
+ /// Adds a keywword/replacement pair to the named list
+ bool addEntryToList(LLWString keyword, LLWString replacement, std::string listName);
+
+ /// Removes the keywword and its replacement from the named list
+ bool removeEntryFromList(std::string keyword, std::string listName);
+
+ /**
+ * Look for currentWord in the lists in order, returning any substitution found
+ * If no configured substitution is found, returns currentWord
+ */
+ std::string replaceWord(const std::string currentWord /**< word to search for */ );
+
+ /// Provides a hard-coded example of settings
+ LLSD getExampleLLSD();
+
+ /// Get the actual settings as LLSD
+ const LLSD& asLLSD();
+ ///< @note for use only in AutoReplace::saveToUserSettings
+
+ private:
+ /// Efficiently and safely compare list names
+ bool listNameMatches( const LLSD& list, const std::string name );
+
+ /// The actual llsd data structure
+ LLSD mLists;
+
+ static const std::string AUTOREPLACE_LIST_NAME; ///< key for looking up list names
+ static const std::string AUTOREPLACE_LIST_REPLACEMENTS; ///< key for looking up replacement map
+
+ /**<
+ * LLSD structure of the lists
+ * - The configuration is an array (mLists),
+ * - Each entry in the array is a replacement list
+ * - Each replacement list is a map with three keys:
+ * @verbatim
+ * "name" String the name of the list
+ * "replacements" Map keyword -> replacement pairs
+ *
+ * <llsd>
+ * <array>
+ * <map>
+ * <key>name</key> <string>List 1</string>
+ * <key>data</key>
+ * <map>
+ * <key>keyword1</key> <string>replacement1</string>
+ * <key>keyword2</key> <string>replacement2</string>
+ * </map>
+ * </map>
+ * <map>
+ * <key>name</key> <string>List 2</string>
+ * <key>data</key>
+ * <map>
+ * <key>keyword1</key> <string>replacement1</string>
+ * <key>keyword2</key> <string>replacement2</string>
+ * </map>
+ * </map>
+ * </array>
+ * </llsd>
+ * @endverbatim
+ */
+};
+
+/** Provides a facility to auto-replace text dynamically as it is entered.
+ *
+ * When the end of a word is detected (defined as any punctuation character,
+ * or any whitespace except newline or return), the preceding word is used
+ * as a lookup key in an ordered list of maps. If a match is found in any
+ * map, the replacement start index and length are returned along with the
+ * new replacement string.
+ *
+ * See the autoreplaceCallback method for how to add autoreplace functionality
+ * to a text entry tool.
+ */
+class LLAutoReplace : public LLSingleton<LLAutoReplace>
+{
+public:
+ /// Callback that provides the hook for use in text entry methods
+ void autoreplaceCallback(S32& replacement_start, S32& replacement_length, LLWString& replacement_string, S32& cursor_pos, const LLWString& input_text);
+
+ /// Get a copy of the current settings
+ LLAutoReplaceSettings getSettings();
+
+ /// Commit new settings after making changes
+ void setSettings(const LLAutoReplaceSettings& settings);
+
+private:
+ friend class LLSingleton<LLAutoReplace>;
+ LLAutoReplace();
+ /*virtual*/ void initSingleton();
+
+ LLAutoReplaceSettings mSettings; ///< configuration information
+
+ /// Read settings from persistent storage
+ void loadFromSettings();
+
+ /// Make the newSettings active and write them to user storage
+ void saveToUserSettings();
+
+ /// Compute the user settings file name
+ std::string getUserSettingsFileName();
+
+ /// Compute the (read-ony) application settings file name
+ std::string getAppSettingsFileName();
+
+ /// basename for the settings files
+ static const char* SETTINGS_FILE_NAME;
+};
+
+#endif /* LLAUTOREPLACE_H */
diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index f618af9536..70cc48f12b 100755
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -42,7 +42,9 @@
#include "llappviewer.h" // for gLastVersionChannel
#include "llcachename.h"
#include "llcallingcard.h" // for LLAvatarTracker
+#include "llconversationlog.h"
#include "llfloateravatarpicker.h" // for LLFloaterAvatarPicker
+#include "llfloaterconversationpreview.h"
#include "llfloatergroupinvite.h"
#include "llfloatergroups.h"
#include "llfloaterreg.h"
@@ -55,6 +57,7 @@
#include "llinventorybridge.h"
#include "llinventorymodel.h" // for gInventory.findCategoryUUIDForType
#include "llinventorypanel.h"
+#include "llfloaterimcontainer.h"
#include "llimview.h" // for gIMMgr
#include "llmutelist.h"
#include "llnotificationsutil.h" // for LLNotificationsUtil
@@ -66,11 +69,12 @@
#include "llviewerobjectlist.h"
#include "llviewermessage.h" // for handle_lure
#include "llviewerregion.h"
-#include "llimfloater.h"
#include "lltrans.h"
#include "llcallingcard.h"
#include "llslurl.h" // IDEVO
#include "llsidepanelinventory.h"
+#include "llavatarname.h"
+#include "llagentui.h"
// static
void LLAvatarActions::requestFriendshipDialog(const LLUUID& id, const std::string& name)
@@ -93,7 +97,7 @@ void LLAvatarActions::requestFriendshipDialog(const LLUUID& id, const std::strin
LLRecentPeople::instance().add(id);
}
-void on_avatar_name_friendship(const LLUUID& id, const LLAvatarName av_name)
+static void on_avatar_name_friendship(const LLUUID& id, const LLAvatarName av_name)
{
LLAvatarActions::requestFriendshipDialog(id, av_name.getCompleteName());
}
@@ -134,7 +138,7 @@ void LLAvatarActions::removeFriendsDialog(const uuid_vec_t& ids)
LLAvatarName av_name;
if(LLAvatarNameCache::get(agent_id, &av_name))
{
- args["NAME"] = av_name.mDisplayName;
+ args["NAME"] = av_name.getDisplayName();
}
msgType = "RemoveFromFriends";
@@ -179,11 +183,11 @@ void LLAvatarActions::offerTeleport(const uuid_vec_t& ids)
static void on_avatar_name_cache_start_im(const LLUUID& agent_id,
const LLAvatarName& av_name)
{
- std::string name = av_name.getCompleteName();
+ std::string name = av_name.getDisplayName();
LLUUID session_id = gIMMgr->addSession(name, IM_NOTHING_SPECIAL, agent_id);
if (session_id != LLUUID::null)
{
- LLIMFloater::show(session_id);
+ LLFloaterIMContainer::getInstance()->showConversation(session_id);
}
make_ui_sound("UISndStartIM");
}
@@ -191,11 +195,10 @@ static void on_avatar_name_cache_start_im(const LLUUID& agent_id,
// static
void LLAvatarActions::startIM(const LLUUID& id)
{
- if (id.isNull())
+ if (id.isNull() || gAgent.getID() == id)
return;
- LLAvatarNameCache::get(id,
- boost::bind(&on_avatar_name_cache_start_im, _1, _2));
+ LLAvatarNameCache::get(id, boost::bind(&on_avatar_name_cache_start_im, _1, _2));
}
// static
@@ -214,7 +217,7 @@ void LLAvatarActions::endIM(const LLUUID& id)
static void on_avatar_name_cache_start_call(const LLUUID& agent_id,
const LLAvatarName& av_name)
{
- std::string name = av_name.getCompleteName();
+ std::string name = av_name.getDisplayName();
LLUUID session_id = gIMMgr->addSession(name, IM_NOTHING_SPECIAL, agent_id, true);
if (session_id != LLUUID::null)
{
@@ -230,12 +233,11 @@ void LLAvatarActions::startCall(const LLUUID& id)
{
return;
}
- LLAvatarNameCache::get(id,
- boost::bind(&on_avatar_name_cache_start_call, _1, _2));
+ LLAvatarNameCache::get(id, boost::bind(&on_avatar_name_cache_start_call, _1, _2));
}
// static
-void LLAvatarActions::startAdhocCall(const uuid_vec_t& ids)
+void LLAvatarActions::startAdhocCall(const uuid_vec_t& ids, const LLUUID& floater_id)
{
if (ids.size() == 0)
{
@@ -252,7 +254,7 @@ void LLAvatarActions::startAdhocCall(const uuid_vec_t& ids)
// create the new ad hoc voice session
const std::string title = LLTrans::getString("conference-title");
LLUUID session_id = gIMMgr->addSession(title, IM_SESSION_CONFERENCE_START,
- ids[0], id_array, true);
+ ids[0], id_array, true, floater_id);
if (session_id == LLUUID::null)
{
return;
@@ -285,7 +287,7 @@ bool LLAvatarActions::canCall()
}
// static
-void LLAvatarActions::startConference(const uuid_vec_t& ids)
+void LLAvatarActions::startConference(const uuid_vec_t& ids, const LLUUID& floater_id)
{
// *HACK: Copy into dynamic array
LLDynamicArray<LLUUID> id_array;
@@ -294,11 +296,15 @@ void LLAvatarActions::startConference(const uuid_vec_t& ids)
id_array.push_back(*it);
}
const std::string title = LLTrans::getString("conference-title");
- LLUUID session_id = gIMMgr->addSession(title, IM_SESSION_CONFERENCE_START, ids[0], id_array);
- if (session_id != LLUUID::null)
+ LLUUID session_id = gIMMgr->addSession(title, IM_SESSION_CONFERENCE_START, ids[0], id_array, false, floater_id);
+
+ if (session_id == LLUUID::null)
{
- LLIMFloater::show(session_id);
+ return;
}
+
+ LLFloaterIMContainer::getInstance()->showConversation(session_id);
+
make_ui_sound("UISndStartIM");
}
@@ -310,19 +316,11 @@ static const char* get_profile_floater_name(const LLUUID& avatar_id)
static void on_avatar_name_show_profile(const LLUUID& agent_id, const LLAvatarName& av_name)
{
- std::string username = av_name.mUsername;
- if (username.empty())
- {
- username = LLCacheName::buildUsername(av_name.mDisplayName);
- }
-
- llinfos << "opening web profile for " << username << llendl;
- std::string url = getProfileURL(username);
+ std::string url = getProfileURL(av_name.getAccountName());
// PROFILES: open in webkit window
LLFloaterWebContent::Params p;
- p.url(url).
- id(agent_id.asString());
+ p.url(url).id(agent_id.asString());
LLFloaterReg::showInstance(get_profile_floater_name(agent_id), p);
}
@@ -374,19 +372,19 @@ void LLAvatarActions::showOnMap(const LLUUID& id)
return;
}
- gFloaterWorldMap->trackAvatar(id, av_name.mDisplayName);
+ gFloaterWorldMap->trackAvatar(id, av_name.getDisplayName());
LLFloaterReg::showInstance("world_map");
}
// static
void LLAvatarActions::pay(const LLUUID& id)
{
- LLNotification::Params params("BusyModePay");
+ LLNotification::Params params("DoNotDisturbModePay");
params.functor.function(boost::bind(&LLAvatarActions::handlePay, _1, _2, id));
- if (gAgent.getBusy())
+ if (gAgent.isDoNotDisturb())
{
- // warn users of being in busy mode during a transaction
+ // warn users of being in do not disturb mode during a transaction
LLNotifications::instance().add(params);
}
else
@@ -395,6 +393,72 @@ void LLAvatarActions::pay(const LLUUID& id)
}
}
+void LLAvatarActions::teleport_request_callback(const LLSD& notification, const LLSD& response)
+{
+ S32 option;
+ if (response.isInteger())
+ {
+ option = response.asInteger();
+ }
+ else
+ {
+ option = LLNotificationsUtil::getSelectedOption(notification, response);
+ }
+
+ if (0 == option)
+ {
+ LLMessageSystem* msg = gMessageSystem;
+
+ msg->newMessageFast(_PREHASH_ImprovedInstantMessage);
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+
+ msg->nextBlockFast(_PREHASH_MessageBlock);
+ msg->addBOOLFast(_PREHASH_FromGroup, FALSE);
+ msg->addUUIDFast(_PREHASH_ToAgentID, notification["substitutions"]["uuid"] );
+ msg->addU8Fast(_PREHASH_Offline, IM_ONLINE);
+ msg->addU8Fast(_PREHASH_Dialog, IM_TELEPORT_REQUEST);
+ msg->addUUIDFast(_PREHASH_ID, LLUUID::null);
+ msg->addU32Fast(_PREHASH_Timestamp, NO_TIMESTAMP); // no timestamp necessary
+
+ std::string name;
+ LLAgentUI::buildFullname(name);
+
+ msg->addStringFast(_PREHASH_FromAgentName, name);
+ msg->addStringFast(_PREHASH_Message, response["message"]);
+ msg->addU32Fast(_PREHASH_ParentEstateID, 0);
+ msg->addUUIDFast(_PREHASH_RegionID, LLUUID::null);
+ msg->addVector3Fast(_PREHASH_Position, gAgent.getPositionAgent());
+
+ gMessageSystem->addBinaryDataFast(
+ _PREHASH_BinaryBucket,
+ EMPTY_BINARY_BUCKET,
+ EMPTY_BINARY_BUCKET_SIZE);
+
+ gAgent.sendReliableMessage();
+ }
+}
+
+// static
+void LLAvatarActions::teleportRequest(const LLUUID& id)
+{
+ LLSD notification;
+ notification["uuid"] = id;
+ LLAvatarName av_name;
+ if (!LLAvatarNameCache::get(id, &av_name))
+ {
+ // unlikely ... they just picked this name from somewhere...
+ LLAvatarNameCache::get(id, boost::bind(&LLAvatarActions::teleportRequest, id));
+ return; // reinvoke this when the name resolves
+ }
+ notification["NAME"] = av_name.getCompleteName();
+
+ LLSD payload;
+
+ LLNotificationsUtil::add("TeleportRequestPrompt", notification, payload, teleport_request_callback);
+}
+
// static
void LLAvatarActions::kick(const LLUUID& id)
{
@@ -448,6 +512,7 @@ void LLAvatarActions::share(const LLUUID& id)
{
LLSD key;
LLFloaterSidePanelContainer::showPanel("inventory", key);
+ LLFloaterReg::showInstance("im_container");
LLUUID session_id = gIMMgr->computeSessionID(IM_NOTHING_SPECIAL,id);
@@ -529,23 +594,6 @@ namespace action_give_inventory
return acceptable;
}
- static void build_residents_string(const std::vector<LLAvatarName> avatar_names, std::string& residents_string)
- {
- llassert(avatar_names.size() > 0);
-
- const std::string& separator = LLTrans::getString("words_separator");
- for (std::vector<LLAvatarName>::const_iterator it = avatar_names.begin(); ; )
- {
- LLAvatarName av_name = *it;
- residents_string.append(av_name.mDisplayName);
- if (++it == avatar_names.end())
- {
- break;
- }
- residents_string.append(separator);
- }
- }
-
static void build_items_string(const std::set<LLUUID>& inventory_selected_uuids , std::string& items_string)
{
llassert(inventory_selected_uuids.size() > 0);
@@ -594,7 +642,7 @@ namespace action_give_inventory
}
S32 count = LLShareInfo::instance().mAvatarNames.size();
- bool shared = false;
+ bool shared = count && !inventory_selected_uuids.empty();
// iterate through avatars
for(S32 i = 0; i < count; ++i)
@@ -616,8 +664,10 @@ namespace action_give_inventory
LLViewerInventoryCategory* inv_cat = gInventory.getCategory(*it);
if (inv_cat)
{
- LLGiveInventory::doGiveInventoryCategory(avatar_uuid, inv_cat, session_id);
- shared = true;
+ if (!LLGiveInventory::doGiveInventoryCategory(avatar_uuid, inv_cat, session_id, "ItemsShared"))
+ {
+ shared = false;
+ }
break;
}
LLViewerInventoryItem* inv_item = gInventory.getItem(*it);
@@ -632,8 +682,10 @@ namespace action_give_inventory
}
else
{
- LLGiveInventory::doGiveInventoryItem(avatar_uuid, inv_item, session_id);
- shared = true;
+ if (!LLGiveInventory::doGiveInventoryItem(avatar_uuid, inv_item, session_id))
+ {
+ shared = false;
+ }
}
}
if (noncopy_items.beginArray() != noncopy_items.endArray())
@@ -643,8 +695,10 @@ namespace action_give_inventory
LLSD payload;
payload["agent_id"] = avatar_uuid;
payload["items"] = noncopy_items;
+ payload["success_notification"] = "ItemsShared";
LLNotificationsUtil::add("CannotCopyWarning", substitutions, payload,
&LLGiveInventory::handleCopyProtectedItem);
+ shared = false;
break;
}
}
@@ -675,7 +729,7 @@ namespace action_give_inventory
}
std::string residents;
- build_residents_string(avatar_names, residents);
+ LLAvatarActions::buildResidentsString(avatar_names, residents);
std::string items;
build_items_string(inventory_selected_uuids, items);
@@ -706,38 +760,84 @@ namespace action_give_inventory
}
}
+// static
+void LLAvatarActions::buildResidentsString(std::vector<LLAvatarName> avatar_names, std::string& residents_string)
+{
+ llassert(avatar_names.size() > 0);
+
+ std::sort(avatar_names.begin(), avatar_names.end());
+ const std::string& separator = LLTrans::getString("words_separator");
+ for (std::vector<LLAvatarName>::const_iterator it = avatar_names.begin(); ; )
+ {
+ residents_string.append((*it).getDisplayName());
+ if (++it == avatar_names.end())
+ {
+ break;
+ }
+ residents_string.append(separator);
+ }
+}
+// static
+void LLAvatarActions::buildResidentsString(const uuid_vec_t& avatar_uuids, std::string& residents_string)
+{
+ std::vector<LLAvatarName> avatar_names;
+ uuid_vec_t::const_iterator it = avatar_uuids.begin();
+ for (; it != avatar_uuids.end(); ++it)
+ {
+ LLAvatarName av_name;
+ if (LLAvatarNameCache::get(*it, &av_name))
+ {
+ avatar_names.push_back(av_name);
+ }
+ }
+
+ // We should check whether the vector is not empty to pass the assertion
+ // that avatar_names.size() > 0 in LLAvatarActions::buildResidentsString.
+ if (!avatar_names.empty())
+ {
+ LLAvatarActions::buildResidentsString(avatar_names, residents_string);
+ }
+}
//static
std::set<LLUUID> LLAvatarActions::getInventorySelectedUUIDs()
{
- std::set<LLUUID> inventory_selected_uuids;
+ std::set<LLFolderViewItem*> inventory_selected;
LLInventoryPanel* active_panel = action_give_inventory::get_active_inventory_panel();
if (active_panel)
{
- inventory_selected_uuids = active_panel->getRootFolder()->getSelectionList();
+ inventory_selected= active_panel->getRootFolder()->getSelectionList();
}
- if (inventory_selected_uuids.empty())
+ if (inventory_selected.empty())
{
LLSidepanelInventory *sidepanel_inventory = LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory");
if (sidepanel_inventory)
{
- inventory_selected_uuids = sidepanel_inventory->getInboxSelectionList();
+ inventory_selected= sidepanel_inventory->getInboxSelectionList();
}
}
+ std::set<LLUUID> inventory_selected_uuids;
+ for (std::set<LLFolderViewItem*>::iterator it = inventory_selected.begin(), end_it = inventory_selected.end();
+ it != end_it;
+ ++it)
+ {
+ inventory_selected_uuids.insert(static_cast<LLFolderViewModelItemInventory*>((*it)->getViewModelItem())->getUUID());
+ }
return inventory_selected_uuids;
}
//static
-void LLAvatarActions::shareWithAvatars()
+void LLAvatarActions::shareWithAvatars(LLView * panel)
{
using namespace action_give_inventory;
+ LLFloater* root_floater = gFloaterView->getParentFloater(panel);
LLFloaterAvatarPicker* picker =
- LLFloaterAvatarPicker::show(boost::bind(give_inventory, _1, _2), TRUE, FALSE);
+ LLFloaterAvatarPicker::show(boost::bind(give_inventory, _1, _2), TRUE, FALSE, FALSE, root_floater->getName());
if (!picker)
{
return;
@@ -745,6 +845,11 @@ void LLAvatarActions::shareWithAvatars()
picker->setOkBtnEnableCb(boost::bind(is_give_inventory_acceptable));
picker->openFriendsTab();
+
+ if (root_floater)
+ {
+ root_floater->addDependentFloater(picker);
+ }
LLNotificationsUtil::add("ShareNotification");
}
@@ -763,15 +868,15 @@ bool LLAvatarActions::canShareSelectedItems(LLInventoryPanel* inv_panel /* = NUL
// check selection in the panel
LLFolderView* root_folder = inv_panel->getRootFolder();
- const std::set<LLUUID> inventory_selected_uuids = root_folder->getSelectionList();
- if (inventory_selected_uuids.empty()) return false; // nothing selected
+ const std::set<LLFolderViewItem*> inventory_selected = root_folder->getSelectionList();
+ if (inventory_selected.empty()) return false; // nothing selected
bool can_share = true;
- std::set<LLUUID>::const_iterator it = inventory_selected_uuids.begin();
- const std::set<LLUUID>::const_iterator it_end = inventory_selected_uuids.end();
+ std::set<LLFolderViewItem*>::const_iterator it = inventory_selected.begin();
+ const std::set<LLFolderViewItem*>::const_iterator it_end = inventory_selected.end();
for (; it != it_end; ++it)
{
- LLViewerInventoryCategory* inv_cat = gInventory.getCategory(*it);
+ LLViewerInventoryCategory* inv_cat = gInventory.getCategory(static_cast<LLFolderViewModelItemInventory*>((*it)->getViewModelItem())->getUUID());
// any category can be offered.
if (inv_cat)
{
@@ -779,9 +884,9 @@ bool LLAvatarActions::canShareSelectedItems(LLInventoryPanel* inv_panel /* = NUL
}
// check if inventory item can be given
- LLFolderViewItem* item = root_folder->getItemByID(*it);
+ LLFolderViewItem* item = *it;
if (!item) return false;
- LLInvFVBridge* bridge = dynamic_cast<LLInvFVBridge*>(item->getListener());
+ LLInvFVBridge* bridge = dynamic_cast<LLInvFVBridge*>(item->getViewModelItem());
if (bridge && bridge->canShare())
{
continue;
@@ -814,6 +919,26 @@ void LLAvatarActions::toggleBlock(const LLUUID& id)
}
// static
+void LLAvatarActions::toggleMuteVoice(const LLUUID& id)
+{
+ std::string name;
+ gCacheName->getFullName(id, name); // needed for mute
+
+ LLMuteList* mute_list = LLMuteList::getInstance();
+ bool is_muted = mute_list->isMuted(id, LLMute::flagVoiceChat);
+
+ LLMute mute(id, name, LLMute::AGENT);
+ if (!is_muted)
+ {
+ mute_list->add(mute, LLMute::flagVoiceChat);
+ }
+ else
+ {
+ mute_list->remove(mute, LLMute::flagVoiceChat);
+ }
+}
+
+// static
bool LLAvatarActions::canOfferTeleport(const LLUUID& id)
{
// First use LLAvatarTracker::isBuddy()
@@ -859,6 +984,33 @@ void LLAvatarActions::inviteToGroup(const LLUUID& id)
}
}
+// static
+void LLAvatarActions::viewChatHistory(const LLUUID& id)
+{
+ const std::vector<LLConversation>& conversations = LLConversationLog::instance().getConversations();
+ std::vector<LLConversation>::const_iterator iter = conversations.begin();
+
+ for (; iter != conversations.end(); ++iter)
+ {
+ if (iter->getParticipantID() == id)
+ {
+ LLFloaterReg::showInstance("preview_conversation", iter->getSessionID(), true);
+ return;
+ }
+ }
+
+ if (LLLogChat::isTranscriptExist(id))
+ {
+ LLAvatarName avatar_name;
+ LLSD extended_id(id);
+
+ LLAvatarNameCache::get(id, &avatar_name);
+ extended_id[LL_FCP_COMPLETE_NAME] = avatar_name.getCompleteName();
+ extended_id[LL_FCP_ACCOUNT_NAME] = avatar_name.getAccountName();
+ LLFloaterReg::showInstance("preview_conversation", extended_id, true);
+ }
+}
+
//== private methods ========================================================================================
// static
@@ -901,7 +1053,7 @@ bool LLAvatarActions::handlePay(const LLSD& notification, const LLSD& response,
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
if (option == 0)
{
- gAgent.clearBusy();
+ gAgent.setDoNotDisturb(false);
}
LLFloaterPayUtil::payDirectly(&give_money, avatar_id, /*is_group=*/false);
@@ -1009,7 +1161,6 @@ void LLAvatarActions::requestFriendship(const LLUUID& target_id, const std::stri
LLSD payload;
payload["from_id"] = target_id;
- payload["SUPPRESS_TOAST"] = true;
LLNotificationsUtil::add("FriendshipOffered", args, payload);
}
@@ -1028,6 +1179,12 @@ bool LLAvatarActions::isBlocked(const LLUUID& id)
}
// static
+bool LLAvatarActions::isVoiceMuted(const LLUUID& id)
+{
+ return LLMuteList::getInstance()->isMuted(id, LLMute::flagVoiceChat);
+}
+
+// static
bool LLAvatarActions::canBlock(const LLUUID& id)
{
std::string full_name;
diff --git a/indra/newview/llavataractions.h b/indra/newview/llavataractions.h
index 748b7cb3d1..403414558e 100644..100755
--- a/indra/newview/llavataractions.h
+++ b/indra/newview/llavataractions.h
@@ -34,8 +34,10 @@
#include <string>
#include <vector>
+class LLAvatarName;
class LLInventoryPanel;
class LLFloater;
+class LLView;
/**
* Friend-related actions (add, remove, offer teleport, etc)
@@ -81,14 +83,14 @@ public:
static void startCall(const LLUUID& id);
/**
- * Start an ad-hoc conference voice call with multiple users
+ * Start an ad-hoc conference voice call with multiple users in a specific IM floater.
*/
- static void startAdhocCall(const uuid_vec_t& ids);
+ static void startAdhocCall(const uuid_vec_t& ids, const LLUUID& floater_id = LLUUID::null);
/**
- * Start conference chat with the given avatars.
+ * Start conference chat with the given avatars in a specific IM floater.
*/
- static void startConference(const uuid_vec_t& ids);
+ static void startConference(const uuid_vec_t& ids, const LLUUID& floater_id = LLUUID::null);
/**
* Show avatar profile.
@@ -109,6 +111,12 @@ public:
static void pay(const LLUUID& id);
/**
+ * Request teleport from other avatar
+ */
+ static void teleportRequest(const LLUUID& id);
+ static void teleport_request_callback(const LLSD& notification, const LLSD& response);
+
+ /**
* Share items with the avatar.
*/
static void share(const LLUUID& id);
@@ -116,7 +124,7 @@ public:
/**
* Share items with the picked avatars.
*/
- static void shareWithAvatars();
+ static void shareWithAvatars(LLView * panel);
/**
* Block/unblock the avatar.
@@ -124,6 +132,11 @@ public:
static void toggleBlock(const LLUUID& id);
/**
+ * Block/unblock the avatar voice.
+ */
+ static void toggleMuteVoice(const LLUUID& id);
+
+ /**
* Return true if avatar with "id" is a friend
*/
static bool isFriend(const LLUUID& id);
@@ -134,6 +147,11 @@ public:
static bool isBlocked(const LLUUID& id);
/**
+ * @return true if the avatar voice is blocked
+ */
+ static bool isVoiceMuted(const LLUUID& id);
+
+ /**
* @return true if you can block the avatar
*/
static bool canBlock(const LLUUID& id);
@@ -198,6 +216,27 @@ public:
*/
static bool canShareSelectedItems(LLInventoryPanel* inv_panel = NULL);
+ /**
+ * Builds a string of residents' display names separated by "words_separator" string.
+ *
+ * @param avatar_names - a vector of given avatar names from which resulting string is built
+ * @param residents_string - the resulting string
+ */
+ static void buildResidentsString(std::vector<LLAvatarName> avatar_names, std::string& residents_string);
+
+ /**
+ * Builds a string of residents' display names separated by "words_separator" string.
+ *
+ * @param avatar_uuids - a vector of given avatar uuids from which resulting string is built
+ * @param residents_string - the resulting string
+ */
+ static void buildResidentsString(const uuid_vec_t& avatar_uuids, std::string& residents_string);
+
+ /**
+ * Opens the chat history for avatar
+ */
+ static void viewChatHistory(const LLUUID& id);
+
static std::set<LLUUID> getInventorySelectedUUIDs();
private:
diff --git a/indra/newview/llavatariconctrl.cpp b/indra/newview/llavatariconctrl.cpp
index b539ac38ed..f34ad23769 100755
--- a/indra/newview/llavatariconctrl.cpp
+++ b/indra/newview/llavatariconctrl.cpp
@@ -28,6 +28,8 @@
#include "llavatariconctrl.h"
+#include <boost/signals2.hpp>
+
// viewer includes
#include "llagent.h"
#include "llavatarconstants.h"
@@ -36,7 +38,9 @@
#include "llmenugl.h"
#include "lluictrlfactory.h"
#include "llagentdata.h"
-#include "llimfloater.h"
+#include "llfloaterimsession.h"
+#include "llviewertexture.h"
+#include "llavatarappearancedefines.h"
// library includes
#include "llavatarnamecache.h"
@@ -148,9 +152,13 @@ LLAvatarIconCtrl::Params::Params()
LLAvatarIconCtrl::LLAvatarIconCtrl(const LLAvatarIconCtrl::Params& p)
-: LLIconCtrl(p),
+ : LLIconCtrl(p),
+ LLAvatarPropertiesObserver(),
+ mAvatarId(),
+ mFullName(),
mDrawTooltip(p.draw_tooltip),
- mDefaultIconName(p.default_icon_name)
+ mDefaultIconName(p.default_icon_name),
+ mAvatarNameCacheConnection()
{
mPriority = LLViewerFetchedTexture::BOOST_ICON;
@@ -203,6 +211,11 @@ LLAvatarIconCtrl::~LLAvatarIconCtrl()
LLAvatarPropertiesProcessor::getInstance()->removeObserver(mAvatarId, this);
// Name callbacks will be automatically disconnected since LLUICtrl is trackable
}
+
+ if (mAvatarNameCacheConnection.connected())
+ {
+ mAvatarNameCacheConnection.disconnect();
+ }
}
//virtual
@@ -245,9 +258,19 @@ void LLAvatarIconCtrl::setValue(const LLSD& value)
LLIconCtrl::setValue(value);
}
- LLAvatarNameCache::get(mAvatarId,
- boost::bind(&LLAvatarIconCtrl::onAvatarNameCache,
- this, _1, _2));
+ fetchAvatarName();
+}
+
+void LLAvatarIconCtrl::fetchAvatarName()
+{
+ if (mAvatarId.notNull())
+ {
+ if (mAvatarNameCacheConnection.connected())
+ {
+ mAvatarNameCacheConnection.disconnect();
+ }
+ mAvatarNameCacheConnection = LLAvatarNameCache::get(mAvatarId, boost::bind(&LLAvatarIconCtrl::onAvatarNameCache, this, _1, _2));
+ }
}
bool LLAvatarIconCtrl::updateFromCache()
@@ -292,11 +315,13 @@ void LLAvatarIconCtrl::processProperties(void* data, EAvatarProcessorType type)
void LLAvatarIconCtrl::onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name)
{
+ mAvatarNameCacheConnection.disconnect();
+
if (agent_id == mAvatarId)
{
// Most avatar icon controls are next to a UI element that shows
// a display name, so only show username.
- mFullName = av_name.mUsername;
+ mFullName = av_name.getUserName();
if (mDrawTooltip)
{
diff --git a/indra/newview/llavatariconctrl.h b/indra/newview/llavatariconctrl.h
index 7f568fc5b8..4929efb7d0 100644..100755
--- a/indra/newview/llavatariconctrl.h
+++ b/indra/newview/llavatariconctrl.h
@@ -27,7 +27,9 @@
#ifndef LL_LLAVATARICONCTRL_H
#define LL_LLAVATARICONCTRL_H
-#include "lliconctrl.h"
+#include <boost/signals2.hpp>
+
+#include "../llui/lliconctrl.h"
#include "llavatarpropertiesprocessor.h"
#include "llviewermenu.h"
@@ -86,20 +88,24 @@ public:
// LLAvatarPropertiesProcessor observer trigger
virtual void processProperties(void* data, EAvatarProcessorType type);
- void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name);
-
const LLUUID& getAvatarId() const { return mAvatarId; }
const std::string& getFullName() const { return mFullName; }
void setDrawTooltip(bool value) { mDrawTooltip = value;}
protected:
- LLUUID mAvatarId;
- std::string mFullName;
- bool mDrawTooltip;
- std::string mDefaultIconName;
+ LLUUID mAvatarId;
+ std::string mFullName;
+ bool mDrawTooltip;
+ std::string mDefaultIconName;
bool updateFromCache();
+
+private:
+ void fetchAvatarName();
+ void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name);
+
+ boost::signals2::connection mAvatarNameCacheConnection;
};
#endif // LL_LLAVATARICONCTRL_H
diff --git a/indra/newview/llavatarlist.cpp b/indra/newview/llavatarlist.cpp
index 771419f60a..9f02f301a1 100644..100755
--- a/indra/newview/llavatarlist.cpp
+++ b/indra/newview/llavatarlist.cpp
@@ -46,6 +46,7 @@
#include "lluuid.h"
#include "llvoiceclient.h"
#include "llviewercontrol.h" // for gSavedSettings
+#include "lltooldraganddrop.h"
static LLDefaultChildRegistry::Register<LLAvatarList> r("avatar_list");
@@ -278,7 +279,7 @@ void LLAvatarList::refresh()
LLAvatarName av_name;
have_names &= LLAvatarNameCache::get(buddy_id, &av_name);
- if (!have_filter || findInsensitive(av_name.mDisplayName, mNameFilter))
+ if (!have_filter || findInsensitive(av_name.getDisplayName(), mNameFilter))
{
if (nadded >= ADD_LIMIT)
{
@@ -296,8 +297,9 @@ void LLAvatarList::refresh()
}
else
{
+ std::string display_name = av_name.getDisplayName();
addNewItem(buddy_id,
- av_name.mDisplayName.empty() ? waiting_str : av_name.mDisplayName,
+ display_name.empty() ? waiting_str : display_name,
LLAvatarTracker::instance().isBuddyOnline(buddy_id));
}
@@ -325,7 +327,7 @@ void LLAvatarList::refresh()
const LLUUID& buddy_id = it->asUUID();
LLAvatarName av_name;
have_names &= LLAvatarNameCache::get(buddy_id, &av_name);
- if (!findInsensitive(av_name.mDisplayName, mNameFilter))
+ if (!findInsensitive(av_name.getDisplayName(), mNameFilter))
{
removeItemByUUID(buddy_id);
modified = true;
@@ -398,7 +400,7 @@ bool LLAvatarList::filterHasMatches()
// If name has not been loaded yet we consider it as a match.
// When the name will be loaded the filter will be applied again(in refresh()).
- if (have_name && !findInsensitive(av_name.mDisplayName, mNameFilter))
+ if (have_name && !findInsensitive(av_name.getDisplayName(), mNameFilter))
{
continue;
}
@@ -461,6 +463,57 @@ BOOL LLAvatarList::handleRightMouseDown(S32 x, S32 y, MASK mask)
return handled;
}
+BOOL LLAvatarList::handleMouseDown(S32 x, S32 y, MASK mask)
+{
+ gFocusMgr.setMouseCapture(this);
+
+ S32 screen_x;
+ S32 screen_y;
+ localPointToScreen(x, y, &screen_x, &screen_y);
+ LLToolDragAndDrop::getInstance()->setDragStart(screen_x, screen_y);
+
+ return LLFlatListViewEx::handleMouseDown(x, y, mask);
+}
+
+BOOL LLAvatarList::handleMouseUp( S32 x, S32 y, MASK mask )
+{
+ if(hasMouseCapture())
+ {
+ gFocusMgr.setMouseCapture(NULL);
+ }
+
+ return LLFlatListViewEx::handleMouseUp(x, y, mask);
+}
+
+BOOL LLAvatarList::handleHover(S32 x, S32 y, MASK mask)
+{
+ bool handled = hasMouseCapture();
+ if(handled)
+ {
+ S32 screen_x;
+ S32 screen_y;
+ localPointToScreen(x, y, &screen_x, &screen_y);
+
+ if(LLToolDragAndDrop::getInstance()->isOverThreshold(screen_x, screen_y))
+ {
+ // First, create the global drag and drop object
+ std::vector<EDragAndDropType> types;
+ uuid_vec_t cargo_ids;
+ getSelectedUUIDs(cargo_ids);
+ types.resize(cargo_ids.size(), DAD_PERSON);
+ LLToolDragAndDrop::ESource src = LLToolDragAndDrop::SOURCE_PEOPLE;
+ LLToolDragAndDrop::getInstance()->beginMultiDrag(types, cargo_ids, src);
+ }
+ }
+
+ if(!handled)
+ {
+ handled = LLFlatListViewEx::handleHover(x, y, mask);
+ }
+
+ return handled;
+}
+
bool LLAvatarList::isAvalineItemSelected()
{
std::vector<LLPanel*> selected_items;
diff --git a/indra/newview/llavatarlist.h b/indra/newview/llavatarlist.h
index 4814a88a79..3542577ae3 100644..100755
--- a/indra/newview/llavatarlist.h
+++ b/indra/newview/llavatarlist.h
@@ -84,6 +84,9 @@ public:
bool getIconsVisible() const { return mShowIcons; }
const std::string getIconParamName() const{return mIconParamName;}
virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
+ /*virtual*/ BOOL handleMouseDown( S32 x, S32 y, MASK mask );
+ /*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask);
+ /*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask);
// Return true if filter has at least one match.
bool filterHasMatches();
diff --git a/indra/newview/llavatarlistitem.cpp b/indra/newview/llavatarlistitem.cpp
index 30eecfe323..3e6c817dd6 100644..100755
--- a/indra/newview/llavatarlistitem.cpp
+++ b/indra/newview/llavatarlistitem.cpp
@@ -27,6 +27,8 @@
#include "llviewerprecompiledheaders.h"
+#include <boost/signals2.hpp>
+
#include "llavataractions.h"
#include "llavatarlistitem.h"
@@ -38,6 +40,7 @@
#include "llavatarnamecache.h"
#include "llavatariconctrl.h"
#include "lloutputmonitorctrl.h"
+#include "lltooldraganddrop.h"
bool LLAvatarListItem::sStaticInitialized = false;
S32 LLAvatarListItem::sLeftPadding = 0;
@@ -58,7 +61,8 @@ LLAvatarListItem::Params::Params()
LLAvatarListItem::LLAvatarListItem(bool not_from_ui_factory/* = true*/)
-: LLPanel(),
+ : LLPanel(),
+ LLFriendObserver(),
mAvatarIcon(NULL),
mAvatarName(NULL),
mLastInteractionTime(NULL),
@@ -73,7 +77,8 @@ LLAvatarListItem::LLAvatarListItem(bool not_from_ui_factory/* = true*/)
mShowInfoBtn(true),
mShowProfileBtn(true),
mShowPermissions(false),
- mHovered(false)
+ mHovered(false),
+ mAvatarNameCacheConnection()
{
if (not_from_ui_factory)
{
@@ -86,7 +91,14 @@ LLAvatarListItem::LLAvatarListItem(bool not_from_ui_factory/* = true*/)
LLAvatarListItem::~LLAvatarListItem()
{
if (mAvatarId.notNull())
+ {
LLAvatarTracker::instance().removeParticularFriendObserver(mAvatarId, this);
+ }
+
+ if (mAvatarNameCacheConnection.connected())
+ {
+ mAvatarNameCacheConnection.disconnect();
+ }
}
BOOL LLAvatarListItem::postBuild()
@@ -129,6 +141,29 @@ BOOL LLAvatarListItem::postBuild()
return TRUE;
}
+void LLAvatarListItem::handleVisibilityChange ( BOOL new_visibility )
+{
+ //Adjust positions of icons (info button etc) when
+ //speaking indicator visibility was changed/toggled while panel was closed (not visible)
+ if(new_visibility && mSpeakingIndicator->getIndicatorToggled())
+ {
+ updateChildren();
+ mSpeakingIndicator->setIndicatorToggled(false);
+ }
+}
+
+void LLAvatarListItem::fetchAvatarName()
+{
+ if (mAvatarId.notNull())
+ {
+ if (mAvatarNameCacheConnection.connected())
+ {
+ mAvatarNameCacheConnection.disconnect();
+ }
+ mAvatarNameCacheConnection = LLAvatarNameCache::get(getAvatarId(), boost::bind(&LLAvatarListItem::onAvatarNameCache, this, _2));
+ }
+}
+
S32 LLAvatarListItem::notifyParent(const LLSD& info)
{
if (info.has("visibility_changed"))
@@ -259,8 +294,7 @@ void LLAvatarListItem::setAvatarId(const LLUUID& id, const LLUUID& session_id, b
mAvatarIcon->setValue(id);
// Set avatar name.
- LLAvatarNameCache::get(id,
- boost::bind(&LLAvatarListItem::onAvatarNameCache, this, _2));
+ fetchAvatarName();
}
}
@@ -358,8 +392,7 @@ std::string LLAvatarListItem::getAvatarToolTip() const
void LLAvatarListItem::updateAvatarName()
{
- LLAvatarNameCache::get(getAvatarId(),
- boost::bind(&LLAvatarListItem::onAvatarNameCache, this, _2));
+ fetchAvatarName();
}
//== PRIVATE SECITON ==========================================================
@@ -371,8 +404,10 @@ void LLAvatarListItem::setNameInternal(const std::string& name, const std::strin
void LLAvatarListItem::onAvatarNameCache(const LLAvatarName& av_name)
{
- setAvatarName(av_name.mDisplayName);
- setAvatarToolTip(av_name.mUsername);
+ mAvatarNameCacheConnection.disconnect();
+
+ setAvatarName(av_name.getDisplayName());
+ setAvatarToolTip(av_name.getUserName());
//requesting the list to resort
notifyParent(LLSD().with("sort", LLSD()));
diff --git a/indra/newview/llavatarlistitem.h b/indra/newview/llavatarlistitem.h
index c95ac39696..7ef35a746e 100644..100755
--- a/indra/newview/llavatarlistitem.h
+++ b/indra/newview/llavatarlistitem.h
@@ -27,6 +27,8 @@
#ifndef LL_LLAVATARLISTITEM_H
#define LL_LLAVATARLISTITEM_H
+#include <boost/signals2.hpp>
+
#include "llpanel.h"
#include "lloutputmonitorctrl.h"
#include "llbutton.h"
@@ -82,6 +84,7 @@ public:
/**
* Processes notification from speaker indicator to update children when indicator's visibility is changed.
*/
+ virtual void handleVisibilityChange ( BOOL new_visibility );
virtual S32 notifyParent(const LLSD& info);
virtual void onMouseLeave(S32 x, S32 y, MASK mask);
virtual void onMouseEnter(S32 x, S32 y, MASK mask);
@@ -214,6 +217,9 @@ private:
/// true when the mouse pointer is hovering over this item
bool mHovered;
+
+ void fetchAvatarName();
+ boost::signals2::connection mAvatarNameCacheConnection;
static bool sStaticInitialized; // this variable is introduced to improve code readability
static S32 sLeftPadding; // padding to first left visible child (icon or name)
diff --git a/indra/newview/llavatarpropertiesprocessor.cpp b/indra/newview/llavatarpropertiesprocessor.cpp
index b1cd83a1fb..706bc42ea0 100644..100755
--- a/indra/newview/llavatarpropertiesprocessor.cpp
+++ b/indra/newview/llavatarpropertiesprocessor.cpp
@@ -33,6 +33,7 @@
#include "llagentpicksinfo.h"
#include "lldateutil.h"
#include "llviewergenericmessage.h"
+#include "llstartup.h"
// Linden library includes
#include "llavatarconstants.h" // AVATAR_TRANSACTED, etc.
@@ -113,6 +114,14 @@ void LLAvatarPropertiesProcessor::sendGenericRequest(const LLUUID& avatar_id, EA
void LLAvatarPropertiesProcessor::sendAvatarPropertiesRequest(const LLUUID& avatar_id)
{
+ // 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
diff --git a/indra/newview/llavatarpropertiesprocessor.h b/indra/newview/llavatarpropertiesprocessor.h
index fdb88a41a1..fdb88a41a1 100644..100755
--- a/indra/newview/llavatarpropertiesprocessor.h
+++ b/indra/newview/llavatarpropertiesprocessor.h
diff --git a/indra/newview/llavatarrenderinfoaccountant.cpp b/indra/newview/llavatarrenderinfoaccountant.cpp
new file mode 100644
index 0000000000..77d734cbfe
--- /dev/null
+++ b/indra/newview/llavatarrenderinfoaccountant.cpp
@@ -0,0 +1,398 @@
+/**
+ * @file llavatarrenderinfoaccountant.cpp
+ * @author Dave Simmons
+ * @date 2013-02-28
+ * @brief
+ *
+ * $LicenseInfo:firstyear=2013&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2013, 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$
+ */
+
+// Precompiled header
+#include "llviewerprecompiledheaders.h"
+// associated header
+#include "llavatarrenderinfoaccountant.h"
+// STL headers
+// std headers
+// external library headers
+// other Linden headers
+#include "llcharacter.h"
+#include "llhttpclient.h"
+#include "lltimer.h"
+#include "llviewercontrol.h"
+#include "llviewermenu.h"
+#include "llviewerobjectlist.h"
+#include "llviewerregion.h"
+#include "llvoavatar.h"
+#include "llworld.h"
+
+
+static const std::string KEY_AGENTS = "agents"; // map
+static const std::string KEY_WEIGHT = "weight"; // integer
+
+static const std::string KEY_IDENTIFIER = "identifier";
+static const std::string KEY_MESSAGE = "message";
+static const std::string KEY_ERROR = "error";
+
+
+// Send data updates about once per minute, only need per-frame resolution
+LLFrameTimer LLAvatarRenderInfoAccountant::sRenderInfoReportTimer;
+
+
+// HTTP responder class for GET request for avatar render weight information
+class LLAvatarRenderInfoGetResponder : public LLHTTPClient::Responder
+{
+public:
+ LLAvatarRenderInfoGetResponder(U64 region_handle) : mRegionHandle(region_handle)
+ {
+ }
+
+ virtual void error(U32 statusNum, const std::string& reason)
+ {
+ LLViewerRegion * regionp = LLWorld::getInstance()->getRegionFromHandle(mRegionHandle);
+ if (regionp)
+ {
+ llwarns << "HTTP error result for avatar weight GET: " << statusNum
+ << ", " << reason
+ << " returned by region " << regionp->getName()
+ << llendl;
+ }
+ else
+ {
+ llwarns << "Avatar render weight GET error recieved but region not found for "
+ << mRegionHandle
+ << ", error " << statusNum
+ << ", " << reason
+ << llendl;
+ }
+
+ }
+
+ virtual void result(const LLSD& content)
+ {
+ LLViewerRegion * regionp = LLWorld::getInstance()->getRegionFromHandle(mRegionHandle);
+ if (regionp)
+ {
+ if (LLAvatarRenderInfoAccountant::logRenderInfo())
+ {
+ llinfos << "LRI: Result for avatar weights request for region " << regionp->getName() << ":" << llendl;
+ }
+
+ if (content.isMap())
+ {
+ if (content.has(KEY_AGENTS))
+ {
+ const LLSD & agents = content[KEY_AGENTS];
+ if (agents.isMap())
+ {
+ LLSD::map_const_iterator report_iter = agents.beginMap();
+ while (report_iter != agents.endMap())
+ {
+ LLUUID target_agent_id = LLUUID(report_iter->first);
+ const LLSD & agent_info_map = report_iter->second;
+ LLViewerObject* avatarp = gObjectList.findObject(target_agent_id);
+ if (avatarp &&
+ avatarp->isAvatar() &&
+ agent_info_map.isMap())
+ { // Extract the data for this avatar
+
+ if (LLAvatarRenderInfoAccountant::logRenderInfo())
+ {
+ llinfos << "LRI: Agent " << target_agent_id
+ << ": " << agent_info_map << llendl;
+ }
+
+ if (agent_info_map.has(KEY_WEIGHT))
+ {
+ ((LLVOAvatar *) avatarp)->setReportedVisualComplexity(agent_info_map[KEY_WEIGHT].asInteger());
+ }
+ }
+ report_iter++;
+ }
+ }
+ } // has "agents"
+ else if (content.has(KEY_ERROR))
+ {
+ const LLSD & error = content[KEY_ERROR];
+ llwarns << "Avatar render info GET error: "
+ << error[KEY_IDENTIFIER]
+ << ": " << error[KEY_MESSAGE]
+ << " from region " << regionp->getName()
+ << llendl;
+ }
+ }
+ }
+ else
+ {
+ llinfos << "Avatar render weight info recieved but region not found for "
+ << mRegionHandle << llendl;
+ }
+ }
+
+private:
+ U64 mRegionHandle;
+};
+
+
+// HTTP responder class for POST request for avatar render weight information
+class LLAvatarRenderInfoPostResponder : public LLHTTPClient::Responder
+{
+public:
+ LLAvatarRenderInfoPostResponder(U64 region_handle) : mRegionHandle(region_handle)
+ {
+ }
+
+ virtual void error(U32 statusNum, const std::string& reason)
+ {
+ LLViewerRegion * regionp = LLWorld::getInstance()->getRegionFromHandle(mRegionHandle);
+ if (regionp)
+ {
+ llwarns << "HTTP error result for avatar weight POST: " << statusNum
+ << ", " << reason
+ << " returned by region " << regionp->getName()
+ << llendl;
+ }
+ else
+ {
+ llwarns << "Avatar render weight POST error recieved but region not found for "
+ << mRegionHandle
+ << ", error " << statusNum
+ << ", " << reason
+ << llendl;
+ }
+ }
+
+ virtual void result(const LLSD& content)
+ {
+ LLViewerRegion * regionp = LLWorld::getInstance()->getRegionFromHandle(mRegionHandle);
+ if (regionp)
+ {
+ if (LLAvatarRenderInfoAccountant::logRenderInfo())
+ {
+ llinfos << "LRI: Result for avatar weights POST for region " << regionp->getName()
+ << ": " << content << llendl;
+ }
+
+ if (content.isMap())
+ {
+ if (content.has(KEY_ERROR))
+ {
+ const LLSD & error = content[KEY_ERROR];
+ llwarns << "Avatar render info POST error: "
+ << error[KEY_IDENTIFIER]
+ << ": " << error[KEY_MESSAGE]
+ << " from region " << regionp->getName()
+ << llendl;
+ }
+ }
+ }
+ else
+ {
+ llinfos << "Avatar render weight POST result recieved but region not found for "
+ << mRegionHandle << llendl;
+ }
+ }
+
+private:
+ U64 mRegionHandle;
+};
+
+
+// static
+// Send request for one region, no timer checks
+void LLAvatarRenderInfoAccountant::sendRenderInfoToRegion(LLViewerRegion * regionp)
+{
+ std::string url = regionp->getCapability("AvatarRenderInfo");
+ if (!url.empty())
+ {
+ if (logRenderInfo())
+ {
+ llinfos << "LRI: Sending avatar render info to region "
+ << regionp->getName()
+ << " from " << url
+ << llendl;
+ }
+
+ // Build the render info to POST to the region
+ LLSD report = LLSD::emptyMap();
+ LLSD agents = LLSD::emptyMap();
+
+ std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
+ while( iter != LLCharacter::sInstances.end() )
+ {
+ LLVOAvatar* avatar = dynamic_cast<LLVOAvatar*>(*iter);
+ if (avatar &&
+ avatar->getRezzedStatus() >= 2 && // Mostly rezzed (maybe without baked textures downloaded)
+ !avatar->isDead() && // Not dead yet
+ avatar->getObjectHost() == regionp->getHost()) // Ensure it's on the same region
+ {
+ avatar->calculateUpdateRenderCost(); // Make sure the numbers are up-to-date
+
+ LLSD info = LLSD::emptyMap();
+ if (avatar->getVisualComplexity() > 0)
+ {
+ info[KEY_WEIGHT] = avatar->getVisualComplexity();
+ agents[avatar->getID().asString()] = info;
+
+ if (logRenderInfo())
+ {
+ llinfos << "LRI: Sending avatar render info for " << avatar->getID()
+ << ": " << info << llendl;
+ llinfos << "LRI: geometry " << avatar->getAttachmentGeometryBytes()
+ << ", area " << avatar->getAttachmentSurfaceArea()
+ << llendl;
+ }
+ }
+ }
+ iter++;
+ }
+
+ report[KEY_AGENTS] = agents;
+ if (agents.size() > 0)
+ {
+ LLHTTPClient::post(url, report, new LLAvatarRenderInfoPostResponder(regionp->getHandle()));
+ }
+ }
+}
+
+
+
+
+// static
+// Send request for one region, no timer checks
+void LLAvatarRenderInfoAccountant::getRenderInfoFromRegion(LLViewerRegion * regionp)
+{
+ std::string url = regionp->getCapability("AvatarRenderInfo");
+ if (!url.empty())
+ {
+ if (logRenderInfo())
+ {
+ llinfos << "LRI: Requesting avatar render info for region "
+ << regionp->getName()
+ << " from " << url
+ << llendl;
+ }
+
+ // First send a request to get the latest data
+ LLHTTPClient::get(url, new LLAvatarRenderInfoGetResponder(regionp->getHandle()));
+ }
+}
+
+
+// static
+// Called every frame - send render weight requests to every region
+void LLAvatarRenderInfoAccountant::idle()
+{
+ if (sRenderInfoReportTimer.hasExpired())
+ {
+ const F32 SECS_BETWEEN_REGION_SCANS = 5.f; // Scan the region list every 5 seconds
+ const F32 SECS_BETWEEN_REGION_REQUEST = 60.0; // Update each region every 60 seconds
+
+ S32 num_avs = LLCharacter::sInstances.size();
+
+ if (logRenderInfo())
+ {
+ llinfos << "LRI: Scanning all regions and checking for render info updates"
+ << llendl;
+ }
+
+ // Check all regions and see if it's time to fetch/send data
+ for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
+ iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
+ {
+ LLViewerRegion* regionp = *iter;
+ if (regionp &&
+ regionp->isAlive() &&
+ regionp->capabilitiesReceived() && // Region has capability URLs available
+ regionp->getRenderInfoRequestTimer().hasExpired()) // Time to make request
+ {
+ sendRenderInfoToRegion(regionp);
+ getRenderInfoFromRegion(regionp);
+
+ // Reset this regions timer, moving to longer intervals if there are lots of avatars around
+ regionp->getRenderInfoRequestTimer().resetWithExpiry(SECS_BETWEEN_REGION_REQUEST + (2.f * num_avs));
+ }
+ }
+
+ // We scanned all the regions, reset the request timer.
+ sRenderInfoReportTimer.resetWithExpiry(SECS_BETWEEN_REGION_SCANS);
+ }
+
+ static LLCachedControl<U32> render_auto_mute_functions(gSavedSettings, "RenderAutoMuteFunctions", 0);
+ static U32 prev_render_auto_mute_functions = (U32) -1;
+ if (prev_render_auto_mute_functions != render_auto_mute_functions)
+ {
+ prev_render_auto_mute_functions = render_auto_mute_functions;
+
+ // Adjust menus
+ BOOL show_items = (BOOL)(render_auto_mute_functions & 0x04);
+ gMenuAvatarOther->setItemVisible( std::string("Normal"), show_items);
+ gMenuAvatarOther->setItemVisible( std::string("Always use impostor"), show_items);
+ gMenuAvatarOther->setItemVisible( std::string("Never use impostor"), show_items);
+ gMenuAvatarOther->setItemVisible( std::string("Impostor seperator"), show_items);
+
+ gMenuAttachmentOther->setItemVisible( std::string("Normal"), show_items);
+ gMenuAttachmentOther->setItemVisible( std::string("Always use impostor"), show_items);
+ gMenuAttachmentOther->setItemVisible( std::string("Never use impostor"), show_items);
+ gMenuAttachmentOther->setItemVisible( std::string("Impostor seperator"), show_items);
+
+ if (!show_items)
+ { // Turning off visual muting
+ for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
+ iter != LLCharacter::sInstances.end(); ++iter)
+ { // Make sure all AVs have the setting cleared
+ LLVOAvatar* inst = (LLVOAvatar*) *iter;
+ inst->setCachedVisualMute(false);
+ }
+ }
+ }
+}
+
+
+// static
+// Make sRenderInfoReportTimer expire so the next call to idle() will scan and query a new region
+// called via LLViewerRegion::setCapabilitiesReceived() boost signals when the capabilities
+// are returned for a new LLViewerRegion, and is the earliest time to get render info
+void LLAvatarRenderInfoAccountant::expireRenderInfoReportTimer(const LLUUID& region_id)
+{
+ if (logRenderInfo())
+ {
+ llinfos << "LRI: Viewer has new region capabilities, clearing global render info timer"
+ << " and timer for region " << region_id
+ << llendl;
+ }
+
+ // Reset the global timer so it will scan regions immediately
+ sRenderInfoReportTimer.reset();
+
+ LLViewerRegion* regionp = LLWorld::instance().getRegionFromID(region_id);
+ if (regionp)
+ { // Reset the region's timer so it will request data immediately
+ regionp->getRenderInfoRequestTimer().reset();
+ }
+}
+
+// static
+bool LLAvatarRenderInfoAccountant::logRenderInfo()
+{
+ static LLCachedControl<bool> render_mute_logging_enabled(gSavedSettings, "RenderAutoMuteLogging", false);
+ return render_mute_logging_enabled;
+}
diff --git a/indra/newview/llavatarrenderinfoaccountant.h b/indra/newview/llavatarrenderinfoaccountant.h
new file mode 100644
index 0000000000..d68f2dccfb
--- /dev/null
+++ b/indra/newview/llavatarrenderinfoaccountant.h
@@ -0,0 +1,56 @@
+/**
+ * @file llavatarrenderinfoaccountant.h
+ * @author Dave Simmons
+ * @date 2013-02-28
+ * @brief
+ *
+ * $LicenseInfo:firstyear=2013&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2013, 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$
+ */
+
+#if ! defined(LL_llavatarrenderinfoaccountant_H)
+#define LL_llavatarrenderinfoaccountant_H
+
+class LLViewerRegion;
+
+// Class to gather avatar rendering information
+// that is sent to or fetched from regions.
+class LLAvatarRenderInfoAccountant
+{
+public:
+ LLAvatarRenderInfoAccountant() {};
+ ~LLAvatarRenderInfoAccountant() {};
+
+ static void sendRenderInfoToRegion(LLViewerRegion * regionp);
+ static void getRenderInfoFromRegion(LLViewerRegion * regionp);
+
+ static void expireRenderInfoReportTimer(const LLUUID& region_id);
+
+ static void idle();
+
+ static bool logRenderInfo();
+
+private:
+ // Send data updates about once per minute, only need per-frame resolution
+ static LLFrameTimer sRenderInfoReportTimer;
+};
+
+#endif /* ! defined(LL_llavatarrenderinfoaccountant_H) */
diff --git a/indra/newview/llblockedlistitem.cpp b/indra/newview/llblockedlistitem.cpp
new file mode 100755
index 0000000000..d9afd2b629
--- /dev/null
+++ b/indra/newview/llblockedlistitem.cpp
@@ -0,0 +1,114 @@
+/**
+ * @file llviewerobjectlistitem.cpp
+ * @brief viewer object list item implementation
+ *
+ * Class LLPanelInventoryListItemBase displays inventory item as an element
+ * of LLInventoryItemsList.
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 "llblockedlistitem.h"
+
+// llui
+#include "lliconctrl.h"
+#include "lltextbox.h"
+#include "lltextutil.h"
+
+// newview
+#include "llavatariconctrl.h"
+#include "llgroupiconctrl.h"
+#include "llinventoryicon.h"
+#include "llviewerobject.h"
+
+LLBlockedListItem::LLBlockedListItem(const LLMute* item)
+: LLPanel(),
+ mItemID(item->mID),
+ mItemName(item->mName),
+ mMuteType(item->mType)
+{
+ buildFromFile("panel_blocked_list_item.xml");
+}
+
+BOOL LLBlockedListItem::postBuild()
+{
+ mTitleCtrl = getChild<LLTextBox>("item_name");
+ mTitleCtrl->setValue(mItemName);
+
+ switch (mMuteType)
+ {
+ case LLMute::AGENT:
+ case LLMute::EXTERNAL:
+ {
+ LLAvatarIconCtrl* avatar_icon = getChild<LLAvatarIconCtrl>("avatar_icon");
+ avatar_icon->setVisible(TRUE);
+ avatar_icon->setValue(mItemID);
+ }
+ break;
+ case LLMute::GROUP:
+ {
+ LLGroupIconCtrl* group_icon = getChild<LLGroupIconCtrl>("group_icon");
+ group_icon->setVisible(TRUE);
+ group_icon->setValue(mItemID);
+ }
+ break;
+ case LLMute::OBJECT:
+ case LLMute::BY_NAME:
+ getChild<LLUICtrl>("object_icon")->setVisible(TRUE);
+ break;
+
+ default:
+ break;
+ }
+
+ return TRUE;
+}
+
+void LLBlockedListItem::onMouseEnter(S32 x, S32 y, MASK mask)
+{
+ getChildView("hovered_icon")->setVisible(true);
+ LLPanel::onMouseEnter(x, y, mask);
+}
+
+void LLBlockedListItem::onMouseLeave(S32 x, S32 y, MASK mask)
+{
+ getChildView("hovered_icon")->setVisible(false);
+ LLPanel::onMouseLeave(x, y, mask);
+}
+
+void LLBlockedListItem::setValue(const LLSD& value)
+{
+ if (!value.isMap() || !value.has("selected"))
+ {
+ return;
+ }
+
+ getChildView("selected_icon")->setVisible(value["selected"]);
+}
+
+void LLBlockedListItem::highlightName(const std::string& highlited_text)
+{
+ LLStyle::Params params;
+ LLTextUtil::textboxSetHighlightedVal(mTitleCtrl, params, mItemName, highlited_text);
+}
diff --git a/indra/newview/llblockedlistitem.h b/indra/newview/llblockedlistitem.h
new file mode 100755
index 0000000000..05409e8a3b
--- /dev/null
+++ b/indra/newview/llblockedlistitem.h
@@ -0,0 +1,73 @@
+/**
+ * @file llviewerobjectlistitem.h
+ * @brief viewer object list item header file
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 LLVIEWEROBJECTLISTITEM_H_
+#define LLVIEWEROBJECTLISTITEM_H_
+
+#include "llmutelist.h"
+#include "llpanel.h"
+#include "llstyle.h"
+#include "lltextbox.h"
+#include "lliconctrl.h"
+
+/**
+ * This class represents items of LLBlockList, which represents
+ * contents of LLMuteList. LLMuteList "consists" of LLMute items.
+ * Each LLMute represents either blocked avatar or object and
+ * stores info about mute type (avatar or object)
+ *
+ * Each item consists if object/avatar icon and object/avatar name
+ *
+ * To create a blocked list item just need to pass LLMute pointer
+ * and appropriate block list item will be created depending on
+ * LLMute type (LLMute::EType) and other LLMute's info
+ */
+class LLBlockedListItem : public LLPanel
+{
+public:
+
+ LLBlockedListItem(const LLMute* item);
+ virtual BOOL postBuild();
+
+ void onMouseEnter(S32 x, S32 y, MASK mask);
+ void onMouseLeave(S32 x, S32 y, MASK mask);
+
+ virtual void setValue(const LLSD& value);
+
+ void highlightName(const std::string& highlited_text);
+ const std::string& getName() const { return mItemName; }
+ const LLMute::EType& getType() const { return mMuteType; }
+ const LLUUID& getUUID() const { return mItemID; }
+
+private:
+
+ LLTextBox* mTitleCtrl;
+ const LLUUID mItemID;
+ std::string mItemName;
+ LLMute::EType mMuteType;
+
+};
+
+#endif /* LLVIEWEROBJECTLISTITEM_H_ */
diff --git a/indra/newview/llblocklist.cpp b/indra/newview/llblocklist.cpp
new file mode 100755
index 0000000000..ac41b26a34
--- /dev/null
+++ b/indra/newview/llblocklist.cpp
@@ -0,0 +1,362 @@
+/**
+ * @file llblocklist.cpp
+ * @brief List of the blocked avatars and objects.
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 "llblocklist.h"
+
+#include "llavataractions.h"
+#include "llblockedlistitem.h"
+#include "llfloatersidepanelcontainer.h"
+#include "llviewermenu.h"
+
+static LLDefaultChildRegistry::Register<LLBlockList> r("block_list");
+
+static const LLBlockListNameComparator NAME_COMPARATOR;
+static const LLBlockListNameTypeComparator NAME_TYPE_COMPARATOR;
+
+LLBlockList::LLBlockList(const Params& p)
+: LLFlatListViewEx(p),
+ mSelectedItem(NULL),
+ mDirty(true),
+ mShouldAddAll(true),
+ mActionType(NONE),
+ mMuteListSize(0)
+{
+
+ LLMuteList::getInstance()->addObserver(this);
+ mMuteListSize = LLMuteList::getInstance()->getMutes().size();
+
+ // Set up context menu.
+ LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
+ LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
+
+ registrar.add ("Block.Action", boost::bind(&LLBlockList::onCustomAction, this, _2));
+ enable_registrar.add("Block.Enable", boost::bind(&LLBlockList::isActionEnabled, this, _2));
+
+ LLToggleableMenu* context_menu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>(
+ "menu_people_blocked_gear.xml",
+ gMenuHolder,
+ LLViewerMenuHolderGL::child_registry_t::instance());
+ if(context_menu)
+ {
+ mContextMenu = context_menu->getHandle();
+ }
+}
+
+LLBlockList::~LLBlockList()
+{
+ if (mContextMenu.get())
+ {
+ mContextMenu.get()->die();
+ }
+
+ LLMuteList::getInstance()->removeObserver(this);
+}
+
+void LLBlockList::createList()
+{
+ std::vector<LLMute> mutes = LLMuteList::instance().getMutes();
+ std::vector<LLMute>::const_iterator mute_it = mutes.begin();
+
+ for (; mute_it != mutes.end(); ++mute_it)
+ {
+ addNewItem(&*mute_it);
+ }
+}
+
+BlockListActionType LLBlockList::getCurrentMuteListActionType()
+{
+ BlockListActionType type = NONE;
+ U32 curSize = LLMuteList::getInstance()->getMutes().size();
+ if( curSize > mMuteListSize)
+ type = ADD;
+ else if(curSize < mMuteListSize)
+ type = REMOVE;
+
+ return type;
+}
+
+void LLBlockList::onChangeDetailed(const LLMute &mute)
+{
+ mActionType = getCurrentMuteListActionType();
+
+ mCurItemId = mute.mID;
+ mCurItemName = mute.mName;
+ mCurItemType = mute.mType;
+ mCurItemFlags = mute.mFlags;
+
+ refresh();
+}
+
+BOOL LLBlockList::handleRightMouseDown(S32 x, S32 y, MASK mask)
+{
+ BOOL handled = LLUICtrl::handleRightMouseDown(x, y, mask);
+
+ LLToggleableMenu* context_menu = mContextMenu.get();
+ if (context_menu && size())
+ {
+ context_menu->buildDrawLabels();
+ context_menu->updateParent(LLMenuGL::sMenuContainer);
+ LLMenuGL::showPopup(this, context_menu, x, y);
+ }
+
+ return handled;
+}
+
+void LLBlockList::removeListItem(const LLMute* mute)
+{
+ removeItemByUUID(mute->mID);
+}
+
+void LLBlockList::hideListItem(LLBlockedListItem* item, bool show)
+{
+ item->setVisible(show);
+}
+
+void LLBlockList::setNameFilter(const std::string& filter)
+{
+ std::string filter_upper = filter;
+ LLStringUtil::toUpper(filter_upper);
+ if (mNameFilter != filter_upper)
+ {
+ mNameFilter = filter_upper;
+ setDirty();
+ }
+}
+
+void LLBlockList::sortByName()
+{
+ setComparator(&NAME_COMPARATOR);
+ sort();
+}
+
+void LLBlockList::sortByType()
+{
+ setComparator(&NAME_TYPE_COMPARATOR);
+ sort();
+}
+
+void LLBlockList::draw()
+{
+ if (mDirty)
+ {
+ refresh();
+ }
+
+ LLFlatListView::draw();
+}
+
+void LLBlockList::addNewItem(const LLMute* mute)
+{
+ LLBlockedListItem* item = new LLBlockedListItem(mute);
+ if (!mNameFilter.empty())
+ {
+ item->highlightName(mNameFilter);
+ }
+ addItem(item, item->getUUID(), ADD_BOTTOM);
+}
+
+void LLBlockList::refresh()
+{
+ bool have_filter = !mNameFilter.empty();
+
+ // save selection to restore it after list rebuilt
+ LLUUID selected = getSelectedUUID(), next_selected;
+
+ if(mShouldAddAll) // creating list of blockers
+ {
+ clear();
+ createList();
+ mShouldAddAll = false;
+ }
+ else
+ {
+ // handle remove/add functionality
+ LLMute mute(mCurItemId, mCurItemName, mCurItemType, mCurItemFlags);
+ if(mActionType == ADD)
+ {
+ addNewItem(&mute);
+ }
+ else if(mActionType == REMOVE)
+ {
+ if(selected == mute.mID)
+ {
+ // we are going to remove currently selected item, so select next item and save the selection to restore it
+ if (!selectNextItemPair(false, true))
+ {
+ selectNextItemPair(true, true);
+ }
+ next_selected = getSelectedUUID();
+ }
+ removeListItem(&mute);
+ }
+ mActionType = NONE;
+ }
+
+ // handle filter functionality
+ if(have_filter || (!have_filter && !mPrevNameFilter.empty()))
+ {
+ // we should update visibility of our items if previous filter was not empty
+ std::vector < LLPanel* > allItems;
+ getItems(allItems);
+ std::vector < LLPanel* >::iterator it = allItems.begin();
+
+ for(; it != allItems.end() ; ++it)
+ {
+ LLBlockedListItem * curItem = dynamic_cast<LLBlockedListItem *> (*it);
+ if(curItem)
+ {
+ hideListItem(curItem, findInsensitive(curItem->getName(), mNameFilter));
+ }
+ }
+ }
+ mPrevNameFilter = mNameFilter;
+
+ if (getItemPair(selected))
+ {
+ // restore previously selected item
+ selectItemPair(getItemPair(selected), true);
+ }
+ else if (getItemPair(next_selected))
+ {
+ // previously selected item was removed, so select next item
+ selectItemPair(getItemPair(next_selected), true);
+ }
+ mMuteListSize = LLMuteList::getInstance()->getMutes().size();
+
+ // Sort the list.
+ sort();
+
+ setDirty(false);
+}
+
+bool LLBlockList::findInsensitive(std::string haystack, const std::string& needle_upper)
+{
+ LLStringUtil::toUpper(haystack);
+ return haystack.find(needle_upper) != std::string::npos;
+}
+
+LLBlockedListItem* LLBlockList::getBlockedItem() const
+{
+ LLPanel* panel = LLFlatListView::getSelectedItem();
+ LLBlockedListItem* item = dynamic_cast<LLBlockedListItem*>(panel);
+ return item;
+}
+
+bool LLBlockList::isActionEnabled(const LLSD& userdata)
+{
+ bool action_enabled = true;
+
+ const std::string command_name = userdata.asString();
+
+ if ("profile_item" == command_name)
+ {
+ LLBlockedListItem* item = getBlockedItem();
+ action_enabled = item && (LLMute::AGENT == item->getType());
+ }
+
+ if ("unblock_item" == command_name)
+ {
+ action_enabled = getSelectedItem() != NULL;
+ }
+
+ return action_enabled;
+}
+
+void LLBlockList::onCustomAction(const LLSD& userdata)
+{
+ if (!isActionEnabled(userdata))
+ {
+ return;
+ }
+
+ LLBlockedListItem* item = getBlockedItem();
+ const std::string command_name = userdata.asString();
+
+ if ("unblock_item" == command_name)
+ {
+ LLMute mute(item->getUUID(), item->getName());
+ LLMuteList::getInstance()->remove(mute);
+ }
+ else if ("profile_item" == command_name)
+ {
+ switch(item->getType())
+ {
+
+ case LLMute::AGENT:
+ LLAvatarActions::showProfile(item->getUUID());
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
+bool LLBlockListItemComparator::compare(const LLPanel* item1, const LLPanel* item2) const
+{
+ const LLBlockedListItem* blocked_item1 = dynamic_cast<const LLBlockedListItem*>(item1);
+ const LLBlockedListItem* blocked_item2 = dynamic_cast<const LLBlockedListItem*>(item2);
+
+ if (!blocked_item1 || !blocked_item2)
+ {
+ llerror("blocked_item1 and blocked_item2 cannot be null", 0);
+ return true;
+ }
+
+ return doCompare(blocked_item1, blocked_item2);
+}
+
+bool LLBlockListNameComparator::doCompare(const LLBlockedListItem* blocked_item1, const LLBlockedListItem* blocked_item2) const
+{
+ std::string name1 = blocked_item1->getName();
+ std::string name2 = blocked_item2->getName();
+
+ LLStringUtil::toUpper(name1);
+ LLStringUtil::toUpper(name2);
+
+ return name1 < name2;
+}
+
+bool LLBlockListNameTypeComparator::doCompare(const LLBlockedListItem* blocked_item1, const LLBlockedListItem* blocked_item2) const
+{
+ LLMute::EType type1 = blocked_item1->getType();
+ LLMute::EType type2 = blocked_item2->getType();
+
+ // if mute type is LLMute::BY_NAME or LLMute::OBJECT it means that this mute is an object
+ bool both_mutes_are_objects = (LLMute::OBJECT == type1 || LLMute::BY_NAME == type1) && (LLMute::OBJECT == type2 || LLMute::BY_NAME == type2);
+
+ // mute types may be different, but since both LLMute::BY_NAME and LLMute::OBJECT types represent objects
+ // it's needed to perform additional checking of both_mutes_are_objects variable
+ if (type1 != type2 && !both_mutes_are_objects)
+ {
+ // objects in block list go first, so return true if mute type is not an avatar
+ return LLMute::AGENT != type1;
+ }
+
+ return NAME_COMPARATOR.compare(blocked_item1, blocked_item2);
+}
diff --git a/indra/newview/llblocklist.h b/indra/newview/llblocklist.h
new file mode 100755
index 0000000000..b1ea7e98e5
--- /dev/null
+++ b/indra/newview/llblocklist.h
@@ -0,0 +1,155 @@
+/**
+ * @file llblocklist.h
+ * @brief List of the blocked avatars and objects.
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 LLBLOCKLIST_H_
+#define LLBLOCKLIST_H_
+
+#include "llflatlistview.h"
+#include "lllistcontextmenu.h"
+#include "llmutelist.h"
+#include "lltoggleablemenu.h"
+
+class LLBlockedListItem;
+class LLMute;
+
+enum BlockListActionType {NONE, ADD, REMOVE};
+
+/**
+ * List of blocked avatars and objects.
+ * This list represents contents of the LLMuteList.
+ * Each change in LLMuteList leads to rebuilding this list, so
+ * it's always in actual state.
+ */
+class LLBlockList: public LLFlatListViewEx, public LLMuteListObserver
+{
+ LOG_CLASS(LLBlockList);
+public:
+ struct Params : public LLInitParam::Block<Params, LLFlatListViewEx::Params>
+ {
+ Params(){};
+ };
+
+ LLBlockList(const Params& p);
+ virtual ~LLBlockList();
+
+ virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
+ LLToggleableMenu* getContextMenu() const { return mContextMenu.get(); }
+ LLBlockedListItem* getBlockedItem() const;
+
+ virtual void onChange() { }
+ virtual void onChangeDetailed(const LLMute& );
+ virtual void draw();
+
+ void setNameFilter(const std::string& filter);
+ void sortByName();
+ void sortByType();
+ void refresh();
+
+private:
+
+ void addNewItem(const LLMute* mute);
+ void removeListItem(const LLMute* mute);
+ void hideListItem(LLBlockedListItem* item, bool show);
+ void setDirty(bool dirty = true) { mDirty = dirty; }
+ bool findInsensitive(std::string haystack, const std::string& needle_upper);
+
+ bool isActionEnabled(const LLSD& userdata);
+ void onCustomAction (const LLSD& userdata);
+ void createList();
+
+ BlockListActionType getCurrentMuteListActionType();
+
+ LLHandle<LLToggleableMenu> mContextMenu;
+
+ LLBlockedListItem* mSelectedItem;
+ std::string mNameFilter;
+ bool mDirty;
+ bool mShouldAddAll;
+ BlockListActionType mActionType;
+ U32 mMuteListSize;
+
+ // This data is used to save information about item that currently changed(added or removed)
+ LLUUID mCurItemId;
+ std::string mCurItemName;
+ LLMute::EType mCurItemType;
+ U32 mCurItemFlags;
+ std::string mPrevNameFilter;
+
+};
+
+
+/*
+ * Abstract comparator for blocked items
+ */
+class LLBlockListItemComparator : public LLFlatListView::ItemComparator
+{
+ LOG_CLASS(LLBlockListItemComparator);
+
+public:
+ LLBlockListItemComparator() {};
+ virtual ~LLBlockListItemComparator() {};
+
+ virtual bool compare(const LLPanel* item1, const LLPanel* item2) const;
+
+protected:
+
+ virtual bool doCompare(const LLBlockedListItem* blocked_item1, const LLBlockedListItem* blocked_item2) const = 0;
+};
+
+
+/*
+ * Compares items by name
+ */
+class LLBlockListNameComparator : public LLBlockListItemComparator
+{
+ LOG_CLASS(LLBlockListNameComparator);
+
+public:
+ LLBlockListNameComparator() {};
+ virtual ~LLBlockListNameComparator() {};
+
+protected:
+
+ virtual bool doCompare(const LLBlockedListItem* blocked_item1, const LLBlockedListItem* blocked_item2) const;
+};
+
+/*
+ * Compares items by type and then by name within type
+ * Objects come first then avatars
+ */
+class LLBlockListNameTypeComparator : public LLBlockListItemComparator
+{
+ LOG_CLASS(LLBlockListNameTypeComparator);
+
+public:
+ LLBlockListNameTypeComparator() {};
+ virtual ~LLBlockListNameTypeComparator() {};
+
+protected:
+
+ virtual bool doCompare(const LLBlockedListItem* blocked_item1, const LLBlockedListItem* blocked_item2) const;
+};
+
+#endif /* LLBLOCKLIST_H_ */
diff --git a/indra/newview/llbox.cpp b/indra/newview/llbox.cpp
index faf82695fe..faf82695fe 100644..100755
--- a/indra/newview/llbox.cpp
+++ b/indra/newview/llbox.cpp
diff --git a/indra/newview/llbox.h b/indra/newview/llbox.h
index ff641ad7cf..ff641ad7cf 100644..100755
--- a/indra/newview/llbox.h
+++ b/indra/newview/llbox.h
diff --git a/indra/newview/llbreadcrumbview.cpp b/indra/newview/llbreadcrumbview.cpp
index 92310452dd..92310452dd 100644..100755
--- a/indra/newview/llbreadcrumbview.cpp
+++ b/indra/newview/llbreadcrumbview.cpp
diff --git a/indra/newview/llbreadcrumbview.h b/indra/newview/llbreadcrumbview.h
index f1b53ab526..f1b53ab526 100644..100755
--- a/indra/newview/llbreadcrumbview.h
+++ b/indra/newview/llbreadcrumbview.h
diff --git a/indra/newview/llbreastmotion.cpp b/indra/newview/llbreastmotion.cpp
index 9a8cd5ceae..9a8cd5ceae 100644..100755
--- a/indra/newview/llbreastmotion.cpp
+++ b/indra/newview/llbreastmotion.cpp
diff --git a/indra/newview/llbreastmotion.h b/indra/newview/llbreastmotion.h
index aa0fdf9f8b..aa0fdf9f8b 100644..100755
--- a/indra/newview/llbreastmotion.h
+++ b/indra/newview/llbreastmotion.h
diff --git a/indra/newview/llbrowsernotification.cpp b/indra/newview/llbrowsernotification.cpp
index 6e77d1e336..19747757db 100644..100755
--- a/indra/newview/llbrowsernotification.cpp
+++ b/indra/newview/llbrowsernotification.cpp
@@ -35,11 +35,13 @@
using namespace LLNotificationsUI;
-bool LLBrowserNotification::processNotification(const LLSD& notify)
+LLBrowserNotification::LLBrowserNotification()
+ : LLSystemNotificationHandler("Browser", "browser")
{
- LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID());
- if (!notification) return false;
+}
+bool LLBrowserNotification::processNotification(const LLNotificationPtr& notification)
+{
LLUUID media_id = notification->getPayload()["media_id"].asUUID();
LLMediaCtrl* media_instance = LLMediaCtrl::getInstance(media_id);
if (media_instance)
diff --git a/indra/newview/llbuycurrencyhtml.cpp b/indra/newview/llbuycurrencyhtml.cpp
index e5a9be0203..459123a5d8 100644..100755
--- a/indra/newview/llbuycurrencyhtml.cpp
+++ b/indra/newview/llbuycurrencyhtml.cpp
@@ -61,6 +61,10 @@ public:
if ( params.size() >= 3 )
{
result_code = params[ 2 ].asInteger();
+ if ( result_code != 0 )
+ {
+ LL_WARNS("LLBuyCurrency") << "Received nonzero result code: " << result_code << LL_ENDL ;
+ }
};
// open the legacy XUI based currency floater
diff --git a/indra/newview/llbuycurrencyhtml.h b/indra/newview/llbuycurrencyhtml.h
index 8d8857ffe3..8d8857ffe3 100644..100755
--- a/indra/newview/llbuycurrencyhtml.h
+++ b/indra/newview/llbuycurrencyhtml.h
diff --git a/indra/newview/llcallbacklist.cpp b/indra/newview/llcallbacklist.cpp
index 357a6582d1..79ec43dfe9 100644..100755
--- a/indra/newview/llcallbacklist.cpp
+++ b/indra/newview/llcallbacklist.cpp
@@ -27,6 +27,7 @@
#include "llviewerprecompiledheaders.h"
#include "llcallbacklist.h"
+#include "lleventtimer.h"
// Library includes
#include "llerror.h"
@@ -180,6 +181,54 @@ void doOnIdleRepeating(bool_func_t callable)
gIdleCallbacks.addFunction(&OnIdleCallbackRepeating::onIdle,cb_functor);
}
+class NullaryFuncEventTimer: public LLEventTimer
+{
+public:
+ NullaryFuncEventTimer(nullary_func_t callable, F32 seconds):
+ LLEventTimer(seconds),
+ mCallable(callable)
+ {
+ }
+
+private:
+ BOOL tick()
+ {
+ mCallable();
+ return TRUE;
+ }
+
+ nullary_func_t mCallable;
+};
+
+// Call a given callable once after specified interval.
+void doAfterInterval(nullary_func_t callable, F32 seconds)
+{
+ new NullaryFuncEventTimer(callable, seconds);
+}
+
+class BoolFuncEventTimer: public LLEventTimer
+{
+public:
+ BoolFuncEventTimer(bool_func_t callable, F32 seconds):
+ LLEventTimer(seconds),
+ mCallable(callable)
+ {
+ }
+private:
+ BOOL tick()
+ {
+ return mCallable();
+ }
+
+ bool_func_t mCallable;
+};
+
+// Call a given callable every specified number of seconds, until it returns true.
+void doPeriodically(bool_func_t callable, F32 seconds)
+{
+ new BoolFuncEventTimer(callable, seconds);
+}
+
#ifdef _DEBUG
void test1(void *data)
diff --git a/indra/newview/llcallbacklist.h b/indra/newview/llcallbacklist.h
index 97f3bfd9ee..0516c9cdb4 100644..100755
--- a/indra/newview/llcallbacklist.h
+++ b/indra/newview/llcallbacklist.h
@@ -61,6 +61,12 @@ void doOnIdleOneTime(nullary_func_t callable);
// Repeatedly call a callable in idle loop until it returns true.
void doOnIdleRepeating(bool_func_t callable);
+// Call a given callable once after specified interval.
+void doAfterInterval(nullary_func_t callable, F32 seconds);
+
+// Call a given callable every specified number of seconds, until it returns true.
+void doPeriodically(bool_func_t callable, F32 seconds);
+
extern LLCallbackList gIdleCallbacks;
#endif
diff --git a/indra/newview/llcallfloater.cpp b/indra/newview/llcallfloater.cpp
deleted file mode 100644
index f2375bfa4f..0000000000
--- a/indra/newview/llcallfloater.cpp
+++ /dev/null
@@ -1,821 +0,0 @@
-/**
- * @file llcallfloater.cpp
- * @author Mike Antipov
- * @brief Voice Control Panel in a Voice Chats (P2P, Group, Nearby...).
- *
- * $LicenseInfo:firstyear=2009&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 "llviewerprecompiledheaders.h"
-
-#include "llcallfloater.h"
-
-#include "llnotificationsutil.h"
-#include "lltrans.h"
-
-#include "llagent.h"
-#include "llagentdata.h" // for gAgentID
-#include "llavatarnamecache.h"
-#include "llavatariconctrl.h"
-#include "llavatarlist.h"
-#include "lldraghandle.h"
-#include "llimfloater.h"
-#include "llimview.h"
-#include "llfloaterreg.h"
-#include "llparticipantlist.h"
-#include "llspeakers.h"
-#include "lltextutil.h"
-#include "lltransientfloatermgr.h"
-#include "llviewercontrol.h"
-#include "llviewerdisplayname.h"
-#include "llviewerwindow.h"
-#include "llvoicechannel.h"
-#include "llviewerparcelmgr.h"
-#include "llfirstuse.h"
-
-static void get_voice_participants_uuids(uuid_vec_t& speakers_uuids);
-void reshape_floater(LLCallFloater* floater, S32 delta_height);
-
-class LLNonAvatarCaller : public LLAvatarListItem
-{
-public:
- LLNonAvatarCaller() : LLAvatarListItem(false)
- {
-
- }
- BOOL postBuild()
- {
- BOOL rv = LLAvatarListItem::postBuild();
-
- if (rv)
- {
- setOnline(true);
- showLastInteractionTime(false);
- setShowProfileBtn(false);
- setShowInfoBtn(false);
- mAvatarIcon->setValue("Avaline_Icon");
- mAvatarIcon->setToolTip(std::string(""));
- }
- return rv;
- }
-
- void setName(const std::string& name)
- {
- const std::string& formatted_phone = LLTextUtil::formatPhoneNumber(name);
- LLAvatarListItem::setAvatarName(formatted_phone);
- LLAvatarListItem::setAvatarToolTip(formatted_phone);
- }
-
- void setSpeakerId(const LLUUID& id) { mSpeakingIndicator->setSpeakerId(id); }
-};
-
-
-static void* create_non_avatar_caller(void*)
-{
- return new LLNonAvatarCaller;
-}
-
-LLVoiceChannel* LLCallFloater::sCurrentVoiceChannel = NULL;
-
-LLCallFloater::LLCallFloater(const LLSD& key)
-: LLTransientDockableFloater(NULL, false, key)
-, mSpeakerManager(NULL)
-, mParticipants(NULL)
-, mAvatarList(NULL)
-, mNonAvatarCaller(NULL)
-, mVoiceType(VC_LOCAL_CHAT)
-, mAgentPanel(NULL)
-, mSpeakingIndicator(NULL)
-, mIsModeratorMutedVoice(false)
-, mInitParticipantsVoiceState(false)
-{
- static LLUICachedControl<S32> voice_left_remove_delay ("VoiceParticipantLeftRemoveDelay", 10);
- mSpeakerDelayRemover = new LLSpeakersDelayActionsStorage(boost::bind(&LLCallFloater::removeVoiceLeftParticipant, this, _1), voice_left_remove_delay);
-
- mFactoryMap["non_avatar_caller"] = LLCallbackMap(create_non_avatar_caller, NULL);
- LLVoiceClient::instance().addObserver(this);
- LLTransientFloaterMgr::getInstance()->addControlView(this);
-
- // update the agent's name if display name setting change
- LLAvatarNameCache::addUseDisplayNamesCallback(boost::bind(&LLCallFloater::updateAgentModeratorState, this));
- LLViewerDisplayName::addNameChangedCallback(boost::bind(&LLCallFloater::updateAgentModeratorState, this));
-
-}
-
-LLCallFloater::~LLCallFloater()
-{
- resetVoiceRemoveTimers();
- delete mSpeakerDelayRemover;
-
- delete mParticipants;
- mParticipants = NULL;
-
- mAvatarListRefreshConnection.disconnect();
- mVoiceChannelStateChangeConnection.disconnect();
-
- if(LLVoiceClient::instanceExists())
- {
- LLVoiceClient::getInstance()->removeObserver(this);
- }
- LLTransientFloaterMgr::getInstance()->removeControlView(this);
-}
-
-// virtual
-BOOL LLCallFloater::postBuild()
-{
- mAvatarList = getChild<LLAvatarList>("speakers_list");
- mAvatarListRefreshConnection = mAvatarList->setRefreshCompleteCallback(boost::bind(&LLCallFloater::onAvatarListRefreshed, this));
-
- childSetAction("leave_call_btn", boost::bind(&LLCallFloater::leaveCall, this));
-
- mNonAvatarCaller = findChild<LLNonAvatarCaller>("non_avatar_caller");
- mNonAvatarCaller->setVisible(FALSE);
-
- initAgentData();
-
- connectToChannel(LLVoiceChannel::getCurrentVoiceChannel());
-
- updateTransparency(TT_ACTIVE); // force using active floater transparency (STORM-730)
-
- updateSession();
- return TRUE;
-}
-
-// virtual
-void LLCallFloater::onOpen(const LLSD& /*key*/)
-{
- LLFirstUse::speak(false);
-}
-
-// virtual
-void LLCallFloater::draw()
-{
- // we have to refresh participants to display ones not in voice as disabled.
- // It should be done only when she joins or leaves voice chat.
- // But seems that LLVoiceClientParticipantObserver is not enough to satisfy this requirement.
- // *TODO: mantipov: remove from draw()
-
- // NOTE: it looks like calling onChange() here is not necessary,
- // but sometime it is not called properly from the observable object.
- // Seems this is a problem somewhere in Voice Client (LLVoiceClient::participantAddedEvent)
-// onChange();
-
- bool is_moderator_muted = LLVoiceClient::getInstance()->getIsModeratorMuted(gAgentID);
-
- if (mIsModeratorMutedVoice != is_moderator_muted)
- {
- setModeratorMutedVoice(is_moderator_muted);
- }
-
- // Need to resort the participant list if it's in sort by recent speaker order.
- if (mParticipants)
- mParticipants->update();
-
- LLFloater::draw();
-}
-
-// virtual
-void LLCallFloater::setFocus( BOOL b )
-{
- LLFloater::setFocus(b);
-
- // Force using active floater transparency (STORM-730).
- // We have to override setFocus() for LLCallFloater because selecting an item
- // of the voice morphing combobox causes the floater to lose focus and thus become transparent.
- updateTransparency(TT_ACTIVE);
-}
-
-// virtual
-void LLCallFloater::onParticipantsChanged()
-{
- if (NULL == mParticipants) return;
- updateParticipantsVoiceState();
-
- // Add newly joined participants.
- uuid_vec_t speakers_uuids;
- get_voice_participants_uuids(speakers_uuids);
- for (uuid_vec_t::const_iterator it = speakers_uuids.begin(); it != speakers_uuids.end(); it++)
- {
- mParticipants->addAvatarIDExceptAgent(*it);
- }
-}
-
-//////////////////////////////////////////////////////////////////////////
-/// PRIVATE SECTION
-//////////////////////////////////////////////////////////////////////////
-
-void LLCallFloater::leaveCall()
-{
- LLVoiceChannel* voice_channel = LLVoiceChannel::getCurrentVoiceChannel();
- if (voice_channel)
- {
- gIMMgr->endCall(voice_channel->getSessionID());
- }
-}
-
-void LLCallFloater::updateSession()
-{
- LLVoiceChannel* voice_channel = LLVoiceChannel::getCurrentVoiceChannel();
- if (voice_channel)
- {
- LL_DEBUGS("Voice") << "Current voice channel: " << voice_channel->getSessionID() << LL_ENDL;
-
- if (mSpeakerManager && voice_channel->getSessionID() == mSpeakerManager->getSessionID())
- {
- LL_DEBUGS("Voice") << "Speaker manager is already set for session: " << voice_channel->getSessionID() << LL_ENDL;
- return;
- }
- else
- {
- mSpeakerManager = NULL;
- }
- }
-
- const LLUUID& session_id = voice_channel ? voice_channel->getSessionID() : LLUUID::null;
-
- LLIMModel::LLIMSession* im_session = LLIMModel::getInstance()->findIMSession(session_id);
- if (im_session)
- {
- mSpeakerManager = LLIMModel::getInstance()->getSpeakerManager(session_id);
- switch (im_session->mType)
- {
- case IM_NOTHING_SPECIAL:
- case IM_SESSION_P2P_INVITE:
- mVoiceType = VC_PEER_TO_PEER;
-
- if (!im_session->mOtherParticipantIsAvatar)
- {
- mVoiceType = VC_PEER_TO_PEER_AVALINE;
- }
- break;
- case IM_SESSION_CONFERENCE_START:
- case IM_SESSION_GROUP_START:
- case IM_SESSION_INVITE:
- if (gAgent.isInGroup(session_id))
- {
- mVoiceType = VC_GROUP_CHAT;
- }
- else
- {
- mVoiceType = VC_AD_HOC_CHAT;
- }
- break;
- default:
- llwarning("Failed to determine voice call IM type", 0);
- mVoiceType = VC_GROUP_CHAT;
- break;
- }
- }
-
- if (NULL == mSpeakerManager)
- {
- // By default show nearby chat participants
- mSpeakerManager = LLLocalSpeakerMgr::getInstance();
- LL_DEBUGS("Voice") << "Set DEFAULT speaker manager" << LL_ENDL;
- mVoiceType = VC_LOCAL_CHAT;
- }
-
- updateTitle();
-
- // Hide "Leave Call" button for nearby chat
- bool is_local_chat = mVoiceType == VC_LOCAL_CHAT;
- getChildView("leave_call_btn_panel")->setVisible( !is_local_chat);
-
- refreshParticipantList();
- updateAgentModeratorState();
-
- // Show floater for voice calls & only in CONNECTED to voice channel state
- if (!is_local_chat &&
- voice_channel &&
- LLVoiceChannel::STATE_CONNECTED == voice_channel->getState())
- {
- LLIMFloater* im_floater = LLIMFloater::findInstance(session_id);
- bool show_me = !(im_floater && im_floater->getVisible());
- if (show_me)
- {
- setVisible(true);
- }
- }
-}
-
-void LLCallFloater::refreshParticipantList()
-{
- bool non_avatar_caller = VC_PEER_TO_PEER_AVALINE == mVoiceType;
-
- if (non_avatar_caller)
- {
- LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(mSpeakerManager->getSessionID());
- mNonAvatarCaller->setSpeakerId(session->mOtherParticipantID);
- mNonAvatarCaller->setName(session->mName);
- }
-
- mNonAvatarCaller->setVisible(non_avatar_caller);
- mAvatarList->setVisible(!non_avatar_caller);
-
- if (!non_avatar_caller)
- {
- llassert(mParticipants == NULL); // check for possible memory leak
- mParticipants = new LLParticipantList(mSpeakerManager, mAvatarList, true, mVoiceType != VC_GROUP_CHAT && mVoiceType != VC_AD_HOC_CHAT, false);
- mParticipants->setValidateSpeakerCallback(boost::bind(&LLCallFloater::validateSpeaker, this, _1));
- const U32 speaker_sort_order = gSavedSettings.getU32("SpeakerParticipantDefaultOrder");
- mParticipants->setSortOrder(LLParticipantList::EParticipantSortOrder(speaker_sort_order));
-
- if (LLLocalSpeakerMgr::getInstance() == mSpeakerManager)
- {
- mAvatarList->setNoItemsCommentText(getString("no_one_near"));
- }
-
- // we have to made delayed initialization of voice state of participant list.
- // it will be performed after first LLAvatarList refreshing in the onAvatarListRefreshed().
- mInitParticipantsVoiceState = true;
- }
-}
-
-void LLCallFloater::onAvatarListRefreshed()
-{
- if (mInitParticipantsVoiceState)
- {
- initParticipantsVoiceState();
- mInitParticipantsVoiceState = false;
- }
- else
- {
- updateParticipantsVoiceState();
- }
-}
-
-// static
-void LLCallFloater::sOnCurrentChannelChanged(const LLUUID& /*session_id*/)
-{
- LLVoiceChannel* channel = LLVoiceChannel::getCurrentVoiceChannel();
-
- // *NOTE: if signal was sent for voice channel with LLVoiceChannel::STATE_NO_CHANNEL_INFO
- // it sill be sent for the same channel again (when state is changed).
- // So, lets ignore this call.
- if (channel == sCurrentVoiceChannel) return;
-
- LLCallFloater* call_floater = LLFloaterReg::getTypedInstance<LLCallFloater>("voice_controls");
-
- call_floater->connectToChannel(channel);
-}
-
-void LLCallFloater::onAvatarNameCache(const LLUUID& agent_id,
- const LLAvatarName& av_name)
-{
- LLStringUtil::format_map_t args;
- args["[NAME]"] = av_name.getCompleteName();
- std::string title = getString("title_peer_2_peer", args);
- setTitle(title);
-}
-
-void LLCallFloater::updateTitle()
-{
- LLVoiceChannel* voice_channel = LLVoiceChannel::getCurrentVoiceChannel();
- if (mVoiceType == VC_PEER_TO_PEER)
- {
- LLUUID session_id = voice_channel->getSessionID();
- LLIMModel::LLIMSession* im_session =
- LLIMModel::getInstance()->findIMSession(session_id);
- if (im_session)
- {
- LLAvatarNameCache::get(im_session->mOtherParticipantID,
- boost::bind(&LLCallFloater::onAvatarNameCache,
- this, _1, _2));
- return;
- }
- }
- std::string title;
- switch (mVoiceType)
- {
- case VC_LOCAL_CHAT:
- title = getString("title_nearby");
- break;
- case VC_PEER_TO_PEER:
- case VC_PEER_TO_PEER_AVALINE:
- {
- title = voice_channel->getSessionName();
-
- if (VC_PEER_TO_PEER_AVALINE == mVoiceType)
- {
- title = LLTextUtil::formatPhoneNumber(title);
- }
-
- LLStringUtil::format_map_t args;
- args["[NAME]"] = title;
- title = getString("title_peer_2_peer", args);
- }
- break;
- case VC_AD_HOC_CHAT:
- title = getString("title_adhoc");
- break;
- case VC_GROUP_CHAT:
- {
- LLStringUtil::format_map_t args;
- args["[GROUP]"] = voice_channel->getSessionName();
- title = getString("title_group", args);
- }
- break;
- }
-
- setTitle(title);
-}
-
-void LLCallFloater::initAgentData()
-{
- mAgentPanel = getChild<LLPanel> ("my_panel");
-
- if ( mAgentPanel )
- {
- mAgentPanel->getChild<LLUICtrl>("user_icon")->setValue(gAgentID);
-
- // Just use display name, because it's you
- LLAvatarName av_name;
- LLAvatarNameCache::get( gAgentID, &av_name );
- mAgentPanel->getChild<LLUICtrl>("user_text")->setValue(av_name.mDisplayName);
-
- mSpeakingIndicator = mAgentPanel->getChild<LLOutputMonitorCtrl>("speaking_indicator");
- mSpeakingIndicator->setSpeakerId(gAgentID);
- }
-}
-
-void LLCallFloater::setModeratorMutedVoice(bool moderator_muted)
-{
- mIsModeratorMutedVoice = moderator_muted;
-
- if (moderator_muted)
- {
- LLNotificationsUtil::add("VoiceIsMutedByModerator");
- }
- mSpeakingIndicator->setIsMuted(moderator_muted);
-}
-
-void LLCallFloater::onModeratorNameCache(const LLAvatarName& av_name)
-{
- std::string name;
- name = av_name.mDisplayName;
-
- if(mSpeakerManager && gAgent.isInGroup(mSpeakerManager->getSessionID()))
- {
- // This method can be called when LLVoiceChannel.mState == STATE_NO_CHANNEL_INFO
- // in this case there are not any speakers yet.
- if (mSpeakerManager->findSpeaker(gAgentID))
- {
- // Agent is Moderator
- if (mSpeakerManager->findSpeaker(gAgentID)->mIsModerator)
-
- {
- const std::string moderator_indicator(LLTrans::getString("IM_moderator_label"));
- name += " " + moderator_indicator;
- }
- }
- }
- mAgentPanel->getChild<LLUICtrl>("user_text")->setValue(name);
-}
-
-void LLCallFloater::updateAgentModeratorState()
-{
- LLAvatarNameCache::get(gAgentID, boost::bind(&LLCallFloater::onModeratorNameCache, this, _2));
-}
-
-static void get_voice_participants_uuids(uuid_vec_t& speakers_uuids)
-{
- // Get a list of participants from VoiceClient
- std::set<LLUUID> participants;
- LLVoiceClient::getInstance()->getParticipantList(participants);
-
- for (std::set<LLUUID>::const_iterator iter = participants.begin();
- iter != participants.end(); ++iter)
- {
- speakers_uuids.push_back(*iter);
- }
-
-}
-
-void LLCallFloater::initParticipantsVoiceState()
-{
- // Set initial status for each participant in the list.
- std::vector<LLPanel*> items;
- mAvatarList->getItems(items);
- std::vector<LLPanel*>::const_iterator
- it = items.begin(),
- it_end = items.end();
-
-
- uuid_vec_t speakers_uuids;
- get_voice_participants_uuids(speakers_uuids);
-
- for(; it != it_end; ++it)
- {
- LLAvatarListItem *item = dynamic_cast<LLAvatarListItem*>(*it);
-
- if (!item) continue;
-
- LLUUID speaker_id = item->getAvatarId();
-
- uuid_vec_t::const_iterator speaker_iter = std::find(speakers_uuids.begin(), speakers_uuids.end(), speaker_id);
-
- // If an avatarID assigned to a panel is found in a speakers list
- // obtained from VoiceClient we assign the JOINED status to the owner
- // of this avatarID.
- if (speaker_iter != speakers_uuids.end())
- {
- setState(item, STATE_JOINED);
- }
- else
- {
- LLPointer<LLSpeaker> speakerp = mSpeakerManager->findSpeaker(speaker_id);
- // If someone has already left the call before, we create his
- // avatar row panel with HAS_LEFT status and remove it after
- // the timeout, otherwise we create a panel with INVITED status
- if (speakerp.notNull() && speakerp.get()->mHasLeftCurrentCall)
- {
- setState(item, STATE_LEFT);
- }
- else
- {
- setState(item, STATE_INVITED);
- }
- }
- }
-}
-
-void LLCallFloater::updateParticipantsVoiceState()
-{
- uuid_vec_t speakers_list;
-
- // Get a list of participants from VoiceClient
- uuid_vec_t speakers_uuids;
- get_voice_participants_uuids(speakers_uuids);
-
- // Updating the status for each participant already in list.
- std::vector<LLPanel*> items;
- mAvatarList->getItems(items);
- std::vector<LLPanel*>::const_iterator
- it = items.begin(),
- it_end = items.end();
-
- for(; it != it_end; ++it)
- {
- LLAvatarListItem *item = dynamic_cast<LLAvatarListItem*>(*it);
- if (!item) continue;
-
- const LLUUID participant_id = item->getAvatarId();
- bool found = false;
-
- uuid_vec_t::iterator speakers_iter = std::find(speakers_uuids.begin(), speakers_uuids.end(), participant_id);
-
- LL_DEBUGS("Voice") << "processing speaker: " << item->getAvatarName() << ", " << item->getAvatarId() << LL_ENDL;
-
- // If an avatarID assigned to a panel is found in a speakers list
- // obtained from VoiceClient we assign the JOINED status to the owner
- // of this avatarID.
- if (speakers_iter != speakers_uuids.end())
- {
- setState(item, STATE_JOINED);
-
- LLPointer<LLSpeaker> speaker = mSpeakerManager->findSpeaker(participant_id);
- if (speaker.isNull())
- continue;
- speaker->mHasLeftCurrentCall = FALSE;
-
- speakers_uuids.erase(speakers_iter);
- found = true;
- }
-
- if (!found)
- {
- updateNotInVoiceParticipantState(item);
- }
- }
-}
-
-void LLCallFloater::updateNotInVoiceParticipantState(LLAvatarListItem* item)
-{
- LLUUID participant_id = item->getAvatarId();
- ESpeakerState current_state = getState(participant_id);
-
- switch (current_state)
- {
- case STATE_JOINED:
- // If an avatarID is not found in a speakers list from VoiceClient and
- // a panel with this ID has a JOINED status this means that this person
- // HAS LEFT the call.
- setState(item, STATE_LEFT);
-
- {
- LLPointer<LLSpeaker> speaker = mSpeakerManager->findSpeaker(participant_id);
- if (speaker.notNull())
- {
- speaker->mHasLeftCurrentCall = TRUE;
- }
- }
- break;
- case STATE_LEFT:
- // nothing to do. These states should not be changed.
- break;
- case STATE_INVITED:
- // If avatar was invited into group chat and went offline it is still exists in mSpeakerStateMap
- // If it goes online it will be rendered as JOINED via LAvatarListItem.
- // Lets update its visual representation. See EXT-6660
- case STATE_UNKNOWN:
- // If an avatarID is not found in a speakers list from VoiceClient and
- // a panel with this ID has an UNKNOWN status this means that this person
- // HAS ENTERED session but it is not in voice chat yet. So, set INVITED status
- setState(item, STATE_INVITED);
- break;
- default:
- // for possible new future states.
- llwarns << "Unsupported (" << getState(participant_id) << ") state for: " << item->getAvatarName() << llendl;
- break;
- }
-}
-
-void LLCallFloater::setState(LLAvatarListItem* item, ESpeakerState state)
-{
- // *HACK: mantipov: sometimes such situation is possible while switching to voice channel:
-/*
- - voice channel is switched to the one user is joining
- - participant list is initialized with voice states: agent is in voice
- - than such log messages were found (with agent UUID)
- - LLVivoxProtocolParser::process_impl: parsing: <Response requestId="22" action="Session.MediaDisconnect.1"><ReturnCode>0</ReturnCode><Results><StatusCode>0</StatusCode><StatusString /></Results><InputXml><Request requestId="22" action="Session.MediaDisconnect.1"><SessionGroupHandle>9</SessionGroupHandle><SessionHandle>12</SessionHandle><Media>Audio</Media></Request></InputXml></Response>
- - LLVoiceClient::sessionState::removeParticipant: participant "sip:x2pwNkMbpR_mK4rtB_awASA==@bhr.vivox.com" (da9c0d90-c6e9-47f9-8ae2-bb41fdac0048) removed.
- - and than while updating participants voice states agent is marked as HAS LEFT
- - next updating of LLVoiceClient state makes agent JOINED
- So, lets skip HAS LEFT state for agent's avatar
-*/
- if (STATE_LEFT == state && item->getAvatarId() == gAgentID) return;
-
- setState(item->getAvatarId(), state);
-
- switch (state)
- {
- case STATE_INVITED:
- item->setState(LLAvatarListItem::IS_VOICE_INVITED);
- break;
- case STATE_JOINED:
- removeVoiceRemoveTimer(item->getAvatarId());
- item->setState(LLAvatarListItem::IS_VOICE_JOINED);
- break;
- case STATE_LEFT:
- {
- setVoiceRemoveTimer(item->getAvatarId());
- item->setState(LLAvatarListItem::IS_VOICE_LEFT);
- }
- break;
- default:
- llwarns << "Unrecognized avatar panel state (" << state << ")" << llendl;
- break;
- }
-}
-
-void LLCallFloater::setVoiceRemoveTimer(const LLUUID& voice_speaker_id)
-{
- mSpeakerDelayRemover->setActionTimer(voice_speaker_id);
-}
-
-bool LLCallFloater::removeVoiceLeftParticipant(const LLUUID& voice_speaker_id)
-{
- uuid_vec_t& speaker_uuids = mAvatarList->getIDs();
- uuid_vec_t::iterator pos = std::find(speaker_uuids.begin(), speaker_uuids.end(), voice_speaker_id);
- if(pos != speaker_uuids.end())
- {
- speaker_uuids.erase(pos);
- mAvatarList->setDirty();
- }
-
- return false;
-}
-
-
-void LLCallFloater::resetVoiceRemoveTimers()
-{
- mSpeakerDelayRemover->removeAllTimers();
-}
-
-void LLCallFloater::removeVoiceRemoveTimer(const LLUUID& voice_speaker_id)
-{
- mSpeakerDelayRemover->unsetActionTimer(voice_speaker_id);
-}
-
-bool LLCallFloater::validateSpeaker(const LLUUID& speaker_id)
-{
- bool is_valid = true;
- switch (mVoiceType)
- {
- case VC_LOCAL_CHAT:
- {
- // A nearby chat speaker is considered valid it it's known to LLVoiceClient (i.e. has enabled voice).
- uuid_vec_t speakers;
- get_voice_participants_uuids(speakers);
- is_valid = std::find(speakers.begin(), speakers.end(), speaker_id) != speakers.end();
- }
- break;
- case VC_GROUP_CHAT:
- // if participant had left this call before do not allow add her again. See EXT-4216.
- // but if she Join she will be added into the list from the LLCallFloater::onChange()
- is_valid = STATE_LEFT != getState(speaker_id);
- break;
- default:
- // do nothing. required for Linux build
- break;
- }
-
- return is_valid;
-}
-
-void LLCallFloater::connectToChannel(LLVoiceChannel* channel)
-{
- mVoiceChannelStateChangeConnection.disconnect();
-
- sCurrentVoiceChannel = channel;
-
- mVoiceChannelStateChangeConnection = sCurrentVoiceChannel->setStateChangedCallback(boost::bind(&LLCallFloater::onVoiceChannelStateChanged, this, _1, _2));
-
- updateState(channel->getState());
-}
-
-void LLCallFloater::onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state)
-{
- // check is voice operational and if it doesn't work hide VCP (EXT-4397)
- if(LLVoiceClient::getInstance()->voiceEnabled() && LLVoiceClient::getInstance()->isVoiceWorking())
- {
- updateState(new_state);
- }
- else
- {
- closeFloater();
- }
-}
-
-void LLCallFloater::updateState(const LLVoiceChannel::EState& new_state)
-{
- LL_DEBUGS("Voice") << "Updating state: " << new_state << ", session name: " << sCurrentVoiceChannel->getSessionName() << LL_ENDL;
- if (LLVoiceChannel::STATE_CONNECTED == new_state)
- {
- updateSession();
- }
- else
- {
- reset(new_state);
- }
-}
-
-void LLCallFloater::reset(const LLVoiceChannel::EState& new_state)
-{
- // lets forget states from the previous session
- // for timers...
- resetVoiceRemoveTimers();
-
- // ...and for speaker state
- mSpeakerStateMap.clear();
-
- delete mParticipants;
- mParticipants = NULL;
- mAvatarList->clear();
-
- // These ifs were added instead of simply showing "loading" to make VCP work correctly in parcels
- // with disabled voice (EXT-4648 and EXT-4649)
- if (!LLViewerParcelMgr::getInstance()->allowAgentVoice() && LLVoiceChannel::STATE_HUNG_UP == new_state)
- {
- // hides "Leave Call" when call is ended in parcel with disabled voice- hiding usually happens in
- // updateSession() which won't be called here because connect to nearby voice never happens
- getChildView("leave_call_btn_panel")->setVisible( false);
- // setting title to nearby chat an "no one near..." text- because in region with disabled
- // voice we won't have chance to really connect to nearby, so VCP is changed here manually
- setTitle(getString("title_nearby"));
- mAvatarList->setNoItemsCommentText(getString("no_one_near"));
- }
- // "loading" is shown only when state is "ringing" to avoid showing it in nearby chat vcp
- // of parcels with disabled voice all the time- "no_one_near" is now shown there (EXT-4648)
- else if (new_state == LLVoiceChannel::STATE_RINGING)
- {
- // update floater to show Loading while waiting for data.
- mAvatarList->setNoItemsCommentText(LLTrans::getString("LoadingData"));
- }
-
- mAvatarList->setVisible(TRUE);
- mNonAvatarCaller->setVisible(FALSE);
-
- mSpeakerManager = NULL;
-}
-
-//EOF
diff --git a/indra/newview/llcallfloater.h b/indra/newview/llcallfloater.h
deleted file mode 100644
index 00a3f76e56..0000000000
--- a/indra/newview/llcallfloater.h
+++ /dev/null
@@ -1,273 +0,0 @@
-/**
- * @file llcallfloater.h
- * @author Mike Antipov
- * @brief Voice Control Panel in a Voice Chats (P2P, Group, Nearby...).
- *
- * $LicenseInfo:firstyear=2009&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$
- */
-
-#ifndef LL_LLCALLFLOATER_H
-#define LL_LLCALLFLOATER_H
-
-#include "lltransientdockablefloater.h"
-#include "llvoicechannel.h"
-#include "llvoiceclient.h"
-
-class LLAvatarList;
-class LLAvatarListItem;
-class LLAvatarName;
-class LLNonAvatarCaller;
-class LLOutputMonitorCtrl;
-class LLParticipantList;
-class LLSpeakerMgr;
-class LLSpeakersDelayActionsStorage;
-
-/**
- * The Voice Control Panel is an ambient window summoned by clicking the flyout chevron
- * on the Speak button. It can be torn-off and freely positioned onscreen.
- *
- * When the Resident is engaged in Voice Chat, the Voice Control Panel provides control
- * over the audible volume of each of the other participants, the Resident's own Voice
- * Morphing settings (if she has subscribed to enable the feature), and Voice Recording.
- *
- * When the Resident is engaged in any chat except Nearby Chat, the Voice Control Panel
- * also provides a 'Leave Call' button to allow the Resident to leave that voice channel.
- */
-class LLCallFloater : public LLTransientDockableFloater, LLVoiceClientParticipantObserver
-{
-public:
-
- LOG_CLASS(LLCallFloater);
-
- LLCallFloater(const LLSD& key);
- ~LLCallFloater();
-
- /*virtual*/ BOOL postBuild();
- /*virtual*/ void onOpen(const LLSD& key);
- /*virtual*/ void draw();
- /*virtual*/ void setFocus( BOOL b );
-
- /**
- * Is called by LLVoiceClient::notifyParticipantObservers when voice participant list is changed.
- *
- * Refreshes list to display participants not in voice as disabled.
- */
- /*virtual*/ void onParticipantsChanged();
-
- static void sOnCurrentChannelChanged(const LLUUID& session_id);
-
-private:
- typedef enum e_voice_controls_type
- {
- VC_LOCAL_CHAT,
- VC_GROUP_CHAT,
- VC_AD_HOC_CHAT,
- VC_PEER_TO_PEER,
- VC_PEER_TO_PEER_AVALINE
- }EVoiceControls;
-
- typedef enum e_speaker_state
- {
- STATE_UNKNOWN,
- STATE_INVITED,
- STATE_JOINED,
- STATE_LEFT,
- } ESpeakerState;
-
- typedef std::map<LLUUID, ESpeakerState> speaker_state_map_t;
-
- void leaveCall();
-
- /**
- * Updates mSpeakerManager and list according to current Voice Channel
- *
- * It compares mSpeakerManager & current Voice Channel session IDs.
- * If they are different gets Speaker manager related to current channel and updates channel participant list.
- */
- void updateSession();
-
- /**
- * Refreshes participant list according to current Voice Channel
- */
- void refreshParticipantList();
-
- /**
- * Handles event on avatar list is refreshed after it was marked dirty.
- *
- * It sets initial participants voice states (once after the first refreshing)
- * and updates voice states each time anybody is joined/left voice chat in session.
- */
- void onAvatarListRefreshed();
-
- /**
- * Updates window title with an avatar name
- */
- void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name);
-
- void updateTitle();
- void initAgentData();
- void setModeratorMutedVoice(bool moderator_muted);
- void updateAgentModeratorState();
- void onModeratorNameCache(const LLAvatarName& av_name);
-
- /**
- * Sets initial participants voice states in avatar list (Invited, Joined, Has Left).
- *
- * @see refreshParticipantList()
- * @see onAvatarListRefreshed()
- * @see mInitParticipantsVoiceState
- */
- void initParticipantsVoiceState();
-
- /**
- * Updates participants voice states in avatar list (Invited, Joined, Has Left).
- *
- * @see onAvatarListRefreshed()
- * @see onChanged()
- */
- void updateParticipantsVoiceState();
-
- /**
- * Updates voice state of participant not in current voice channel depend on its current state.
- */
- void updateNotInVoiceParticipantState(LLAvatarListItem* item);
- void setState(LLAvatarListItem* item, ESpeakerState state);
- void setState(const LLUUID& speaker_id, ESpeakerState state)
- {
- lldebugs << "Storing state: " << speaker_id << ", " << state << llendl;
- mSpeakerStateMap[speaker_id] = state;
- }
-
- ESpeakerState getState(const LLUUID& speaker_id)
- {
- lldebugs << "Getting state: " << speaker_id << ", " << mSpeakerStateMap[speaker_id] << llendl;
-
- return mSpeakerStateMap[speaker_id];
- }
-
- /**
- * Instantiates new LLAvatarListItemRemoveTimer and adds it into the map if it is not already created.
- *
- * @param voice_speaker_id LLUUID of Avatar List item to be removed from the list when timer expires.
- */
- void setVoiceRemoveTimer(const LLUUID& voice_speaker_id);
-
- /**
- * Removes specified by UUID Avatar List item.
- *
- * @param voice_speaker_id LLUUID of Avatar List item to be removed from the list.
- */
- bool removeVoiceLeftParticipant(const LLUUID& voice_speaker_id);
-
- /**
- * Deletes all timers from the list to prevent started timers from ticking after destruction
- * and after switching on another voice channel.
- */
- void resetVoiceRemoveTimers();
-
- /**
- * Removes specified by UUID timer from the map.
- *
- * @param voice_speaker_id LLUUID of Avatar List item whose timer should be removed from the map.
- */
- void removeVoiceRemoveTimer(const LLUUID& voice_speaker_id);
-
- /**
- * Called by LLParticipantList before adding a speaker to the participant list.
- *
- * If false is returned, the speaker will not be added to the list.
- *
- * @param speaker_id Speaker to validate.
- * @return true if this is a valid speaker, false otherwise.
- */
- bool validateSpeaker(const LLUUID& speaker_id);
-
- /**
- * Connects to passed channel to be updated according to channel's voice states.
- */
- void connectToChannel(LLVoiceChannel* channel);
-
- /**
- * Callback to process changing of voice channel's states.
- */
- void onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state);
-
- /**
- * Updates floater according to passed channel's voice state.
- */
- void updateState(const LLVoiceChannel::EState& new_state);
-
- /**
- * Resets floater to be ready to show voice participants.
- *
- * Clears all data from the latest voice session.
- */
- void reset(const LLVoiceChannel::EState& new_state);
-
-private:
- speaker_state_map_t mSpeakerStateMap;
- LLSpeakerMgr* mSpeakerManager;
- LLParticipantList* mParticipants;
- LLAvatarList* mAvatarList;
- LLNonAvatarCaller* mNonAvatarCaller;
- EVoiceControls mVoiceType;
- LLPanel* mAgentPanel;
- LLOutputMonitorCtrl* mSpeakingIndicator;
- bool mIsModeratorMutedVoice;
-
- /**
- * Flag indicated that participants voice states should be initialized.
- *
- * It is used due to Avatar List has delayed refreshing after it content is changed.
- * Real initializing is performed when Avatar List is first time refreshed.
- *
- * @see onAvatarListRefreshed()
- * @see initParticipantsVoiceState()
- */
- bool mInitParticipantsVoiceState;
-
- boost::signals2::connection mAvatarListRefreshConnection;
-
-
- /**
- * time out speakers when they are not part of current session
- */
- LLSpeakersDelayActionsStorage* mSpeakerDelayRemover;
-
- /**
- * Stores reference to current voice channel.
- *
- * Is used to ignore voice channel changed callback for the same channel.
- *
- * @see sOnCurrentChannelChanged()
- */
- static LLVoiceChannel* sCurrentVoiceChannel;
-
- /* virtual */
- LLTransientFloaterMgr::ETransientGroup getGroup() { return LLTransientFloaterMgr::IM; }
-
- boost::signals2::connection mVoiceChannelStateChangeConnection;
-};
-
-
-#endif //LL_LLCALLFLOATER_H
-
diff --git a/indra/newview/llcallingcard.cpp b/indra/newview/llcallingcard.cpp
index 0d55c4429a..14583e402d 100644..100755
--- a/indra/newview/llcallingcard.cpp
+++ b/indra/newview/llcallingcard.cpp
@@ -54,6 +54,7 @@
#include "llresmgr.h"
#include "llslurl.h"
#include "llimview.h"
+#include "lltrans.h"
#include "llviewercontrol.h"
#include "llviewernetwork.h"
#include "llviewerobjectlist.h"
@@ -183,7 +184,8 @@ LLVector3d LLAvatarTracker::getGlobalPos()
global_pos = object->getPositionGlobal();
// HACK - for making the tracker point above the avatar's head
// rather than its groin
- global_pos.mdV[VZ] += 0.7f * ((LLVOAvatar *)object)->mBodySize.mV[VZ];
+ LLVOAvatar* av = (LLVOAvatar*)object;
+ global_pos.mdV[VZ] += 0.7f * (av->mBodySize.mV[VZ] + av->mAvatarOffset.mV[VZ]);
mTrackingData->mGlobalPositionEstimate = global_pos;
}
@@ -703,9 +705,7 @@ void LLAvatarTracker::processNotify(LLMessageSystem* msg, bool online)
if(chat_notify)
{
// Look up the name of this agent for the notification
- LLAvatarNameCache::get(agent_id,
- boost::bind(&on_avatar_name_cache_notify,
- _1, _2, online, payload));
+ LLAvatarNameCache::get(agent_id,boost::bind(&on_avatar_name_cache_notify,_1, _2, online, payload));
}
mModifyMask |= LLFriendObserver::ONLINE;
@@ -722,13 +722,14 @@ static void on_avatar_name_cache_notify(const LLUUID& agent_id,
// Popup a notify box with online status of this agent
// Use display name only because this user is your friend
LLSD args;
- args["NAME"] = av_name.mDisplayName;
+ args["NAME"] = av_name.getDisplayName();
+ args["STATUS"] = online ? LLTrans::getString("OnlineStatus") : LLTrans::getString("OfflineStatus");
LLNotificationPtr notification;
if (online)
{
notification =
- LLNotificationsUtil::add("FriendOnline",
+ LLNotificationsUtil::add("FriendOnlineOffline",
args,
payload.with("respond_on_mousedown", TRUE),
boost::bind(&LLAvatarActions::startIM, agent_id));
@@ -736,7 +737,7 @@ static void on_avatar_name_cache_notify(const LLUUID& agent_id,
else
{
notification =
- LLNotificationsUtil::add("FriendOffline", args, payload);
+ LLNotificationsUtil::add("FriendOnlineOffline", args, payload);
}
// If there's an open IM session with this agent, send a notification there too.
@@ -867,7 +868,7 @@ bool LLCollectMappableBuddies::operator()(const LLUUID& buddy_id, LLRelationship
{
LLAvatarName av_name;
LLAvatarNameCache::get( buddy_id, &av_name);
- buddy_map_t::value_type value(av_name.mDisplayName, buddy_id);
+ buddy_map_t::value_type value(av_name.getDisplayName(), buddy_id);
if(buddy->isOnline() && buddy->isRightGrantedFrom(LLRelationship::GRANT_MAP_LOCATION))
{
mMappable.insert(value);
@@ -890,7 +891,7 @@ bool LLCollectAllBuddies::operator()(const LLUUID& buddy_id, LLRelationship* bud
{
LLAvatarName av_name;
LLAvatarNameCache::get(buddy_id, &av_name);
- mFullName = av_name.mDisplayName;
+ mFullName = av_name.getDisplayName();
buddy_map_t::value_type value(mFullName, buddy_id);
if(buddy->isOnline())
{
diff --git a/indra/newview/llcallingcard.h b/indra/newview/llcallingcard.h
index 8803cce59d..8803cce59d 100644..100755
--- a/indra/newview/llcallingcard.h
+++ b/indra/newview/llcallingcard.h
diff --git a/indra/newview/llcapabilitylistener.cpp b/indra/newview/llcapabilitylistener.cpp
index ef9b910ae5..ef9b910ae5 100644..100755
--- a/indra/newview/llcapabilitylistener.cpp
+++ b/indra/newview/llcapabilitylistener.cpp
diff --git a/indra/newview/llcapabilitylistener.h b/indra/newview/llcapabilitylistener.h
index e7535013e7..e7535013e7 100644..100755
--- a/indra/newview/llcapabilitylistener.h
+++ b/indra/newview/llcapabilitylistener.h
diff --git a/indra/newview/llcapabilityprovider.h b/indra/newview/llcapabilityprovider.h
index 9d91245597..9d91245597 100644..100755
--- a/indra/newview/llcapabilityprovider.h
+++ b/indra/newview/llcapabilityprovider.h
diff --git a/indra/newview/llcaphttpsender.cpp b/indra/newview/llcaphttpsender.cpp
index 16bb48da93..16bb48da93 100644..100755
--- a/indra/newview/llcaphttpsender.cpp
+++ b/indra/newview/llcaphttpsender.cpp
diff --git a/indra/newview/llcaphttpsender.h b/indra/newview/llcaphttpsender.h
index e1f4c813f6..e1f4c813f6 100644..100755
--- a/indra/newview/llcaphttpsender.h
+++ b/indra/newview/llcaphttpsender.h
diff --git a/indra/newview/llchannelmanager.cpp b/indra/newview/llchannelmanager.cpp
index 987651fc80..8b2d9e639f 100644..100755
--- a/indra/newview/llchannelmanager.cpp
+++ b/indra/newview/llchannelmanager.cpp
@@ -29,7 +29,8 @@
#include "llchannelmanager.h"
#include "llappviewer.h"
-#include "llnotificationstorage.h"
+#include "lldonotdisturbnotificationstorage.h"
+#include "llpersistentnotificationstorage.h"
#include "llviewercontrol.h"
#include "llviewerwindow.h"
#include "llrootview.h"
@@ -138,6 +139,7 @@ void LLChannelManager::onLoginCompleted()
}
LLPersistentNotificationStorage::getInstance()->loadNotifications();
+ LLDoNotDisturbNotificationStorage::getInstance()->loadNotifications();
}
//--------------------------------------------------------------------------
diff --git a/indra/newview/llchannelmanager.h b/indra/newview/llchannelmanager.h
index a5de8a5327..a5de8a5327 100644..100755
--- a/indra/newview/llchannelmanager.h
+++ b/indra/newview/llchannelmanager.h
diff --git a/indra/newview/llchatbar.cpp b/indra/newview/llchatbar.cpp
index d6095cce07..b3bc0ba966 100644..100755
--- a/indra/newview/llchatbar.cpp
+++ b/indra/newview/llchatbar.cpp
@@ -381,7 +381,7 @@ void LLChatBar::sendChat( EChatType type )
if (!utf8_revised_text.empty())
{
// Chat with animation
- sendChatFromViewer(utf8_revised_text, type, TRUE);
+ sendChatFromViewer(utf8_revised_text, type, gSavedSettings.getBOOL("PlayChatAnim"));
}
}
}
@@ -669,47 +669,3 @@ void LLChatBar::onCommitGesture(LLUICtrl* ctrl)
mGestureCombo->setFocus(FALSE);
}
}
-
-
-/* Cruft - global gChatHandler declared below has been commented out,
- so this class is never used. See similar code in llnearbychatbar.cpp
-class LLChatHandler : public LLCommandHandler
-{
-public:
- // not allowed from outside the app
- LLChatHandler() : LLCommandHandler("chat", UNTRUSTED_BLOCK) { }
-
- // Your code here
- bool handle(const LLSD& tokens, const LLSD& query_map,
- LLMediaCtrl* web)
- {
- bool retval = false;
- // Need at least 2 tokens to have a valid message.
- if (tokens.size() < 2)
- {
- retval = false;
- }
- else
- {
- S32 channel = tokens[0].asInteger();
- // VWR-19499 Restrict function to chat channels greater than 0.
- if ((channel > 0) && (channel < CHAT_CHANNEL_DEBUG))
- {
- retval = true;
- // Say mesg on channel
- std::string mesg = tokens[1].asString();
- send_chat_from_viewer(mesg, CHAT_TYPE_NORMAL, channel);
- }
- else
- {
- retval = false;
- // Tell us this is an unsupported SLurl.
- }
- }
- return retval;
- }
-};
-
-// Creating the object registers with the dispatcher.
-//LLChatHandler gChatHandler;
-cruft */
diff --git a/indra/newview/llchatbar.h b/indra/newview/llchatbar.h
index 26ef5f1535..26ef5f1535 100644..100755
--- a/indra/newview/llchatbar.h
+++ b/indra/newview/llchatbar.h
diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp
index f530d10ddc..ae0ac57e76 100644..100755
--- a/indra/newview/llchathistory.cpp
+++ b/indra/newview/llchathistory.cpp
@@ -28,6 +28,8 @@
#include "llchathistory.h"
+#include <boost/signals2.hpp>
+
#include "llavatarnamecache.h"
#include "llinstantmessage.h"
@@ -56,8 +58,10 @@
#include "llworld.h"
#include "lluiconstants.h"
#include "llstring.h"
-
+#include "llurlaction.h"
#include "llviewercontrol.h"
+#include "llviewerobjectlist.h"
+#include "llmutelist.h"
static LLDefaultChildRegistry::Register<LLChatHistory> r("chat_history");
@@ -110,7 +114,10 @@ public:
mFrom(),
mSessionID(),
mMinUserNameWidth(0),
- mUserNameFont(NULL)
+ mUserNameFont(NULL),
+ mUserNameTextBox(NULL),
+ mTimeBoxTextBox(NULL),
+ mAvatarNameCacheConnection()
{}
static LLChatHistoryHeader* createInstance(const std::string& file_name)
@@ -124,6 +131,11 @@ public:
{
// Detach the info button so that it doesn't get destroyed (EXT-8463).
hideInfoCtrl();
+
+ if (mAvatarNameCacheConnection.connected())
+ {
+ mAvatarNameCacheConnection.disconnect();
+ }
}
BOOL handleMouseUp(S32 x, S32 y, MASK mask)
@@ -143,8 +155,20 @@ public:
{
LLMuteList::getInstance()->add(LLMute(getAvatarId(), mFrom, LLMute::OBJECT));
- LLFloaterSidePanelContainer::showPanel("people", "panel_block_list_sidetray", LLSD().with("blocked_to_select", getAvatarId()));
+ LLFloaterSidePanelContainer::showPanel("people", "panel_people",
+ LLSD().with("people_panel_tab_name", "blocked_panel").with("blocked_to_select", getAvatarId()));
+ }
+ else if (level == "map")
+ {
+ std::string url = "secondlife://" + mObjectData["slurl"].asString();
+ LLUrlAction::showLocationOnMap(url);
+ }
+ else if (level == "teleport")
+ {
+ std::string url = "secondlife://" + mObjectData["slurl"].asString();
+ LLUrlAction::teleportToLocation(url);
}
+
}
void onAvatarIconContextMenuItemClicked(const LLSD& userdata)
@@ -159,6 +183,18 @@ public:
{
LLAvatarActions::startIM(getAvatarId());
}
+ else if (level == "teleport")
+ {
+ LLAvatarActions::offerTeleport(getAvatarId());
+ }
+ else if (level == "voice_call")
+ {
+ LLAvatarActions::startCall(getAvatarId());
+ }
+ else if (level == "chat_history")
+ {
+ LLAvatarActions::viewChatHistory(getAvatarId());
+ }
else if (level == "add")
{
LLAvatarActions::requestFriendshipDialog(getAvatarId(), mFrom);
@@ -167,13 +203,75 @@ public:
{
LLAvatarActions::removeFriendDialog(getAvatarId());
}
+ else if (level == "invite_to_group")
+ {
+ LLAvatarActions::inviteToGroup(getAvatarId());
+ }
+ else if (level == "zoom_in")
+ {
+ handle_zoom_to_object(getAvatarId());
+ }
+ else if (level == "map")
+ {
+ LLAvatarActions::showOnMap(getAvatarId());
+ }
+ else if (level == "share")
+ {
+ LLAvatarActions::share(getAvatarId());
+ }
+ else if (level == "pay")
+ {
+ LLAvatarActions::pay(getAvatarId());
+ }
+ else if(level == "block_unblock")
+ {
+ mute(getAvatarId(), LLMute::flagVoiceChat);
+ }
+ else if(level == "mute_unmute")
+ {
+ mute(getAvatarId(), LLMute::flagTextChat);
+ }
+ }
+
+ bool onAvatarIconContextMenuItemChecked(const LLSD& userdata)
+ {
+ std::string level = userdata.asString();
+
+ if (level == "is_blocked")
+ {
+ return LLMuteList::getInstance()->isMuted(getAvatarId(), LLMute::flagVoiceChat);
+ }
+ if (level == "is_muted")
+ {
+ return LLMuteList::getInstance()->isMuted(getAvatarId(), LLMute::flagTextChat);
+ }
+ return false;
+ }
+
+ void mute(const LLUUID& participant_id, U32 flags)
+ {
+ BOOL is_muted = LLMuteList::getInstance()->isMuted(participant_id, flags);
+ std::string name;
+ gCacheName->getFullName(participant_id, name);
+ LLMute mute(participant_id, name, LLMute::AGENT);
+
+ if (!is_muted)
+ {
+ LLMuteList::getInstance()->add(mute, flags);
+ }
+ else
+ {
+ LLMuteList::getInstance()->remove(mute, flags);
+ }
}
BOOL postBuild()
{
LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
+ LLUICtrl::EnableCallbackRegistry::ScopedRegistrar registrar_enable;
registrar.add("AvatarIcon.Action", boost::bind(&LLChatHistoryHeader::onAvatarIconContextMenuItemClicked, this, _2));
+ registrar_enable.add("AvatarIcon.Check", boost::bind(&LLChatHistoryHeader::onAvatarIconContextMenuItemChecked, this, _2));
registrar.add("ObjectIcon.Action", boost::bind(&LLChatHistoryHeader::onObjectIconContextMenuItemClicked, this, _2));
LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_avatar_icon.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
@@ -187,6 +285,9 @@ public:
setMouseEnterCallback(boost::bind(&LLChatHistoryHeader::showInfoCtrl, this));
setMouseLeaveCallback(boost::bind(&LLChatHistoryHeader::hideInfoCtrl, this));
+ mUserNameTextBox = getChild<LLTextBox>("user_name");
+ mTimeBoxTextBox = getChild<LLTextBox>("time_box");
+
return LLPanel::postBuild();
}
@@ -282,8 +383,7 @@ public:
// Start with blank so sample data from XUI XML doesn't
// flash on the screen
user_name->setValue( LLSD() );
- LLAvatarNameCache::get(mAvatarID,
- boost::bind(&LLChatHistoryHeader::onAvatarNameCache, this, _1, _2));
+ fetchAvatarName();
}
else if (chat.mChatStyle == CHAT_STYLE_HISTORY ||
mSourceType == CHAT_SOURCE_AGENT)
@@ -377,23 +477,14 @@ public:
/*virtual*/ void draw()
{
- LLTextBox* user_name = getChild<LLTextBox>("user_name");
- LLTextBox* time_box = getChild<LLTextBox>("time_box");
+ LLTextBox* user_name = mUserNameTextBox; //getChild<LLTextBox>("user_name");
+ LLTextBox* time_box = mTimeBoxTextBox; //getChild<LLTextBox>("time_box");
LLRect user_name_rect = user_name->getRect();
S32 user_name_width = user_name_rect.getWidth();
S32 time_box_width = time_box->getRect().getWidth();
- if (time_box->getVisible() && user_name_width <= mMinUserNameWidth)
- {
- time_box->setVisible(FALSE);
-
- user_name_rect.mRight += time_box_width;
- user_name->reshape(user_name_rect.getWidth(), user_name_rect.getHeight());
- user_name->setRect(user_name_rect);
- }
-
- if (!time_box->getVisible() && user_name_width > mMinUserNameWidth + time_box_width)
+ if (!time_box->getVisible() && user_name_width > mMinUserNameWidth)
{
user_name_rect.mRight -= time_box_width;
user_name->reshape(user_name_rect.getWidth(), user_name_rect.getHeight());
@@ -415,31 +506,6 @@ public:
}
}
- void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name)
- {
- mFrom = av_name.mDisplayName;
-
- LLTextBox* user_name = getChild<LLTextBox>("user_name");
- user_name->setValue( LLSD(av_name.mDisplayName ) );
- user_name->setToolTip( av_name.mUsername );
-
- if (gSavedSettings.getBOOL("NameTagShowUsernames") &&
- LLAvatarNameCache::useDisplayNames() &&
- !av_name.mIsDisplayNameDefault)
- {
- LLStyle::Params style_params_name;
- LLColor4 userNameColor = LLUIColorTable::instance().getColor("EmphasisColor");
- style_params_name.color(userNameColor);
- style_params_name.font.name("SansSerifSmall");
- style_params_name.font.style("NORMAL");
- style_params_name.readonly_color(userNameColor);
- user_name->appendText(" - " + av_name.mUsername, FALSE, style_params_name);
- }
- setToolTip( av_name.mUsername );
- // name might have changed, update width
- updateMinUserNameWidth();
- }
-
protected:
static const S32 PADDING = 20;
@@ -470,7 +536,7 @@ protected:
if(menu)
{
- bool is_friend = LLAvatarTracker::instance().getBuddyInfo(mAvatarID) != NULL;
+ bool is_friend = LLAvatarActions::isFriend(mAvatarID);
menu->setItemEnabled("Add Friend", !is_friend);
menu->setItemEnabled("Remove Friend", is_friend);
@@ -480,13 +546,34 @@ protected:
menu->setItemEnabled("Add Friend", false);
menu->setItemEnabled("Send IM", false);
menu->setItemEnabled("Remove Friend", false);
+ menu->setItemEnabled("Offer Teleport",false);
+ menu->setItemEnabled("Voice Call", false);
+ menu->setItemEnabled("Invite Group", false);
+ menu->setItemEnabled("Zoom In", false);
+ menu->setItemEnabled("Share", false);
+ menu->setItemEnabled("Pay", false);
+ menu->setItemEnabled("Block Unblock", false);
+ menu->setItemEnabled("Mute Text", false);
}
-
- if (mSessionID == LLIMMgr::computeSessionID(IM_NOTHING_SPECIAL, mAvatarID))
+ else
{
- menu->setItemVisible("Send IM", false);
+ LLUUID currentSessionID = LLIMMgr::computeSessionID(IM_NOTHING_SPECIAL, mAvatarID);
+ if (mSessionID == currentSessionID)
+ {
+ menu->setItemVisible("Send IM", false);
+ }
+ menu->setItemEnabled("Offer Teleport", LLAvatarActions::canOfferTeleport(mAvatarID));
+ menu->setItemEnabled("Voice Call", LLAvatarActions::canCall());
+
+ // We should only show 'Zoom in' item in a nearby chat
+ bool should_show_zoom = !LLIMModel::getInstance()->findIMSession(currentSessionID);
+ menu->setItemVisible("Zoom In", should_show_zoom && gObjectList.findObject(mAvatarID));
+ menu->setItemEnabled("Block Unblock", LLAvatarActions::canBlock(mAvatarID));
+ menu->setItemEnabled("Mute Text", LLAvatarActions::canBlock(mAvatarID));
}
+ menu->setItemEnabled("Chat History", LLLogChat::isTranscriptExist(mAvatarID));
+ menu->setItemEnabled("Map", (LLAvatarTracker::instance().isBuddyOnline(mAvatarID) && is_agent_mappable(mAvatarID)) || gAgent.isGodlike() );
menu->buildDrawLabels();
menu->updateParent(LLMenuGL::sMenuContainer);
LLMenuGL::showPopup(this, menu, x, y);
@@ -495,7 +582,7 @@ protected:
void showInfoCtrl()
{
- if (mAvatarID.isNull() || mFrom.empty() || SYSTEM_FROM == mFrom) return;
+ if (mAvatarID.isNull() || mFrom.empty() || CHAT_SOURCE_SYSTEM == mSourceType) return;
if (!sInfoCtrl)
{
@@ -554,6 +641,46 @@ private:
user_name->reshape(user_rect.getWidth() + delta_pos_x, user_rect.getHeight());
}
+ void fetchAvatarName()
+ {
+ if (mAvatarID.notNull())
+ {
+ if (mAvatarNameCacheConnection.connected())
+ {
+ mAvatarNameCacheConnection.disconnect();
+ }
+ mAvatarNameCacheConnection = LLAvatarNameCache::get(mAvatarID,
+ boost::bind(&LLChatHistoryHeader::onAvatarNameCache, this, _1, _2));
+ }
+ }
+
+ void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name)
+ {
+ mAvatarNameCacheConnection.disconnect();
+
+ mFrom = av_name.getDisplayName();
+
+ LLTextBox* user_name = getChild<LLTextBox>("user_name");
+ user_name->setValue( LLSD(av_name.getDisplayName() ) );
+ user_name->setToolTip( av_name.getUserName() );
+
+ if (gSavedSettings.getBOOL("NameTagShowUsernames") &&
+ av_name.useDisplayNames() &&
+ !av_name.isDisplayNameDefault())
+ {
+ LLStyle::Params style_params_name;
+ LLColor4 userNameColor = LLUIColorTable::instance().getColor("EmphasisColor");
+ style_params_name.color(userNameColor);
+ style_params_name.font.name("SansSerifSmall");
+ style_params_name.font.style("NORMAL");
+ style_params_name.readonly_color(userNameColor);
+ user_name->appendText(" - " + av_name.getUserName(), FALSE, style_params_name);
+ }
+ setToolTip( av_name.getUserName() );
+ // name might have changed, update width
+ updateMinUserNameWidth();
+ }
+
protected:
LLHandle<LLView> mPopupMenuHandleAvatar;
LLHandle<LLView> mPopupMenuHandleObject;
@@ -568,6 +695,11 @@ protected:
S32 mMinUserNameWidth;
const LLFontGL* mUserNameFont;
+ LLTextBox* mUserNameTextBox;
+ LLTextBox* mTimeBoxTextBox;
+
+private:
+ boost::signals2::connection mAvatarNameCacheConnection;
};
LLUICtrl* LLChatHistoryHeader::sInfoCtrl = NULL;
@@ -584,7 +716,8 @@ LLChatHistory::LLChatHistory(const LLChatHistory::Params& p)
mBottomSeparatorPad(p.bottom_separator_pad),
mTopHeaderPad(p.top_header_pad),
mBottomHeaderPad(p.bottom_header_pad),
- mIsLastMessageFromLog(false)
+ mIsLastMessageFromLog(false),
+ mNotifyAboutUnreadMsg(p.notify_unread_msg)
{
LLTextEditor::Params editor_params(p);
editor_params.rect = getLocalRect();
@@ -592,6 +725,15 @@ LLChatHistory::LLChatHistory(const LLChatHistory::Params& p)
editor_params.enabled = false; // read only
editor_params.show_context_menu = "true";
mEditor = LLUICtrlFactory::create<LLTextEditor>(editor_params, this);
+ mEditor->setIsFriendCallback(LLAvatarActions::isFriend);
+}
+
+LLSD LLChatHistory::getValue() const
+{
+ LLSD* text=new LLSD();
+ text->assign(mEditor->getText());
+ return *text;
+
}
LLChatHistory::~LLChatHistory()
@@ -689,9 +831,13 @@ void LLChatHistory::clear()
mLastFromID = LLUUID::null;
}
+static LLFastTimer::DeclareTimer FTM_APPEND_MESSAGE("Append Chat Message");
+
void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LLStyle::Params& input_append_params)
{
+ LLFastTimer _(FTM_APPEND_MESSAGE);
bool use_plain_text_chat_history = args["use_plain_text_chat_history"].asBoolean();
+ bool square_brackets = false; // square brackets necessary for a system messages
llassert(mEditor);
if (!mEditor)
@@ -699,9 +845,10 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
return;
}
+ bool from_me = chat.mFromID == gAgent.getID();
mEditor->setPlainText(use_plain_text_chat_history);
- if (!mEditor->scrolledToEnd() && chat.mFromID != gAgent.getID() && !chat.mFromName.empty())
+ if (mNotifyAboutUnreadMsg && !mEditor->scrolledToEnd() && !from_me && !chat.mFromName.empty())
{
mUnreadChatSources.insert(chat.mFromName);
mMoreChatPanel->setVisible(TRUE);
@@ -731,16 +878,23 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
}
LLColor4 txt_color = LLUIColorTable::instance().getColor("White");
+ LLColor4 name_color(txt_color);
+
LLViewerChat::getChatColor(chat,txt_color);
LLFontGL* fontp = LLViewerChat::getChatFont();
std::string font_name = LLFontGL::nameFromFont(fontp);
std::string font_size = LLFontGL::sizeFromFont(fontp);
- LLStyle::Params style_params;
- style_params.color(txt_color);
- style_params.readonly_color(txt_color);
- style_params.font.name(font_name);
- style_params.font.size(font_size);
- style_params.font.style(input_append_params.font.style);
+
+ LLStyle::Params body_message_params;
+ body_message_params.color(txt_color);
+ body_message_params.readonly_color(txt_color);
+ body_message_params.font.name(font_name);
+ body_message_params.font.size(font_size);
+ body_message_params.font.style(input_append_params.font.style);
+
+ LLStyle::Params name_params(body_message_params);
+ name_params.color(name_color);
+ name_params.readonly_color(name_color);
std::string prefix = chat.mText.substr(0, 4);
@@ -763,29 +917,60 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
if (irc_me || chat.mChatStyle == CHAT_STYLE_IRC)
{
delimiter = LLStringUtil::null;
- style_params.font.style = "ITALIC";
+ body_message_params.font.style = "ITALIC";
+ }
+
+ if(chat.mChatType == CHAT_TYPE_WHISPER)
+ {
+ body_message_params.font.style = "ITALIC";
+ }
+ else if(chat.mChatType == CHAT_TYPE_SHOUT)
+ {
+ body_message_params.font.style = "BOLD";
}
bool message_from_log = chat.mChatStyle == CHAT_STYLE_HISTORY;
// We graying out chat history by graying out messages that contains full date in a time string
if (message_from_log)
{
- style_params.color(LLColor4::grey);
- style_params.readonly_color(LLColor4::grey);
+ txt_color = LLColor4::grey;
+ body_message_params.color(txt_color);
+ body_message_params.readonly_color(txt_color);
+ name_params.color(txt_color);
+ name_params.readonly_color(txt_color);
}
+ bool prependNewLineState = mEditor->getText().size() != 0;
+
+ // compact mode: show a timestamp and name
if (use_plain_text_chat_history)
{
- LLStyle::Params timestamp_style(style_params);
+ square_brackets = chat.mFromName == SYSTEM_FROM;
+
+ LLStyle::Params timestamp_style(body_message_params);
+
+ // out of the timestamp
+ if (args["show_time"].asBoolean())
+ {
if (!message_from_log)
{
LLColor4 timestamp_color = LLUIColorTable::instance().getColor("ChatTimestampColor");
timestamp_style.color(timestamp_color);
timestamp_style.readonly_color(timestamp_color);
}
- mEditor->appendText("[" + chat.mTimeStr + "] ", mEditor->getText().size() != 0, timestamp_style);
+ mEditor->appendText("[" + chat.mTimeStr + "] ", prependNewLineState, timestamp_style);
+ prependNewLineState = false;
+ }
- if (utf8str_trim(chat.mFromName).size() != 0)
+ // out the opening square bracket (if need)
+ if (square_brackets)
+ {
+ mEditor->appendText("[", prependNewLineState, body_message_params);
+ prependNewLineState = false;
+ }
+
+ // names showing
+ if (args["show_names_for_p2p_conv"].asBoolean() && utf8str_trim(chat.mFromName).size() != 0)
{
// Don't hotlink any messages from the system (e.g. "Second Life:"), so just add those in plain text.
if ( chat.mSourceType == CHAT_SOURCE_OBJECT && chat.mFromID.notNull())
@@ -795,32 +980,37 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
// set the link for the object name to be the objectim SLapp
// (don't let object names with hyperlinks override our objectim Url)
- LLStyle::Params link_params(style_params);
+ LLStyle::Params link_params(body_message_params);
LLColor4 link_color = LLUIColorTable::instance().getColor("HTMLLinkColor");
link_params.color = link_color;
link_params.readonly_color = link_color;
link_params.is_link = true;
link_params.link_href = url;
- mEditor->appendText(chat.mFromName + delimiter,
- false, link_params);
+ mEditor->appendText(chat.mFromName + delimiter, prependNewLineState, link_params);
+ prependNewLineState = false;
}
else if ( chat.mFromName != SYSTEM_FROM && chat.mFromID.notNull() && !message_from_log)
{
- LLStyle::Params link_params(style_params);
+ LLStyle::Params link_params(body_message_params);
link_params.overwriteFrom(LLStyleMap::instance().lookupAgent(chat.mFromID));
// Add link to avatar's inspector and delimiter to message.
- mEditor->appendText(std::string(link_params.link_href) + delimiter, false, link_params);
+ mEditor->appendText(std::string(link_params.link_href) + delimiter,
+ prependNewLineState, link_params);
+ prependNewLineState = false;
}
else
{
- mEditor->appendText("<nolink>" + chat.mFromName + "</nolink>" + delimiter, false, style_params);
+ mEditor->appendText("<nolink>" + chat.mFromName + "</nolink>" + delimiter,
+ prependNewLineState, body_message_params);
+ prependNewLineState = false;
}
}
}
- else
+ else // showing timestamp and name in the expanded mode
{
+ prependNewLineState = false;
LLView* view = NULL;
LLInlineViewSegment::Params p;
p.force_newline = true;
@@ -841,8 +1031,8 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
}
else
{
- view = getHeader(chat, style_params, args);
- if (mEditor->getText().size() == 0)
+ view = getHeader(chat, name_params, args);
+ if (mEditor->getLength() == 0)
p.top_pad = 0;
else
p.top_pad = mTopHeaderPad;
@@ -870,57 +1060,51 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
mIsLastMessageFromLog = message_from_log;
}
+ // body of the message processing
+
+ // notify processing
if (chat.mNotifId.notNull())
{
- LLNotificationPtr notification = LLNotificationsUtil::find(chat.mNotifId);
- if (notification != NULL)
- {
- LLIMToastNotifyPanel* notify_box = new LLIMToastNotifyPanel(
- notification, chat.mSessionID, LLRect::null, !use_plain_text_chat_history);
- //we can't set follows in xml since it broke toasts behavior
- notify_box->setFollowsLeft();
- notify_box->setFollowsRight();
- notify_box->setFollowsTop();
-
- ctrl_list_t ctrls = notify_box->getControlPanel()->getCtrlList();
- S32 offset = 0;
- // Children were added by addChild() which uses push_front to insert them into list,
- // so to get buttons in correct order reverse iterator is used (EXT-5906)
- for (ctrl_list_t::reverse_iterator it = ctrls.rbegin(); it != ctrls.rend(); it++)
+ bool create_toast = true;
+ for (LLToastNotifyPanel::instance_iter ti(LLToastNotifyPanel::beginInstances())
+ , tend(LLToastNotifyPanel::endInstances()); ti != tend; ++ti)
+ {
+ LLToastNotifyPanel& panel = *ti;
+ LLIMToastNotifyPanel * imtoastp = dynamic_cast<LLIMToastNotifyPanel *>(&panel);
+ const std::string& notification_name = panel.getNotificationName();
+ if (notification_name == "OfferFriendship" && panel.isControlPanelEnabled() && imtoastp)
{
- LLButton * button = dynamic_cast<LLButton*> (*it);
- if (button != NULL)
- {
- button->setOrigin( offset,
- button->getRect().mBottom);
- button->setLeftHPad(2 * HPAD);
- button->setRightHPad(2 * HPAD);
- // set zero width before perform autoResize()
- button->setRect(LLRect(button->getRect().mLeft,
- button->getRect().mTop, button->getRect().mLeft,
- button->getRect().mBottom));
- button->setAutoResize(true);
- button->autoResize();
- offset += HPAD + button->getRect().getWidth();
- button->setFollowsNone();
- }
+ create_toast = false;
+ break;
}
+ }
- //Prepare the rect for the view
- LLRect target_rect = mEditor->getDocumentView()->getRect();
- // squeeze down the widget by subtracting padding off left and right
- target_rect.mLeft += mLeftWidgetPad + mEditor->getHPad();
- target_rect.mRight -= mRightWidgetPad;
- notify_box->reshape(target_rect.getWidth(), notify_box->getRect().getHeight());
- notify_box->setOrigin(target_rect.mLeft, notify_box->getRect().mBottom);
-
- LLInlineViewSegment::Params params;
- params.view = notify_box;
- params.left_pad = mLeftWidgetPad;
- params.right_pad = mRightWidgetPad;
- mEditor->appendWidget(params, "\n", false);
+ if (create_toast)
+ {
+ LLNotificationPtr notification = LLNotificationsUtil::find(chat.mNotifId);
+ if (notification != NULL)
+ {
+ LLIMToastNotifyPanel* notify_box = new LLIMToastNotifyPanel(
+ notification, chat.mSessionID, LLRect::null, !use_plain_text_chat_history, mEditor);
+
+ //Prepare the rect for the view
+ LLRect target_rect = mEditor->getDocumentView()->getRect();
+ // squeeze down the widget by subtracting padding off left and right
+ target_rect.mLeft += mLeftWidgetPad + mEditor->getHPad();
+ target_rect.mRight -= mRightWidgetPad;
+ notify_box->reshape(target_rect.getWidth(), notify_box->getRect().getHeight());
+ notify_box->setOrigin(target_rect.mLeft, notify_box->getRect().mBottom);
+
+ LLInlineViewSegment::Params params;
+ params.view = notify_box;
+ params.left_pad = mLeftWidgetPad;
+ params.right_pad = mRightWidgetPad;
+ mEditor->appendWidget(params, "\n", false);
+ }
}
}
+
+ // usual messages showing
else
{
std::string message = irc_me ? chat.mText.substr(3) : chat.mText;
@@ -928,7 +1112,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
//MESSAGE TEXT PROCESSING
//*HACK getting rid of redundant sender names in system notifications sent using sender name (see EXT-5010)
- if (use_plain_text_chat_history && gAgentID != chat.mFromID && chat.mFromID.notNull())
+ if (use_plain_text_chat_history && !from_me && chat.mFromID.notNull())
{
std::string slurl_about = SLURL_APP_AGENT + chat.mFromID.asString() + SLURL_ABOUT;
if (message.length() > slurl_about.length() &&
@@ -943,13 +1127,19 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
message = chat.mFromName + message;
}
- mEditor->appendText(message, FALSE, style_params);
+ if (square_brackets)
+ {
+ message += "]";
+ }
+
+ mEditor->appendText(message, prependNewLineState, body_message_params);
+ prependNewLineState = false;
}
mEditor->blockUndo();
// automatically scroll to end when receiving chat from myself
- if (chat.mFromID == gAgentID)
+ if (from_me)
{
mEditor->setCursorAndScrollToEnd();
}
diff --git a/indra/newview/llchathistory.h b/indra/newview/llchathistory.h
index 28344e6a10..bb6d4fb59c 100644..100755
--- a/indra/newview/llchathistory.h
+++ b/indra/newview/llchathistory.h
@@ -60,6 +60,8 @@ class LLChatHistory : public LLUICtrl
Optional<LLTextBox::Params> more_chat_text;
+ Optional<bool> notify_unread_msg;
+
Params()
: message_header("message_header"),
message_separator("message_separator"),
@@ -71,7 +73,8 @@ class LLChatHistory : public LLUICtrl
bottom_separator_pad("bottom_separator_pad"),
top_header_pad("top_header_pad"),
bottom_header_pad("bottom_header_pad"),
- more_chat_text("more_chat_text")
+ more_chat_text("more_chat_text"),
+ notify_unread_msg("notify_unread_msg", true)
{}
};
@@ -100,7 +103,7 @@ class LLChatHistory : public LLUICtrl
public:
~LLChatHistory();
-
+ LLSD getValue() const;
void initFromParams(const Params&);
/**
@@ -122,6 +125,7 @@ class LLChatHistory : public LLUICtrl
LLUUID mLastFromID;
LLDate mLastMessageTime;
bool mIsLastMessageFromLog;
+ bool mNotifyAboutUnreadMsg;
//std::string mLastMessageTimeStr;
std::string mMessageHeaderFilename;
diff --git a/indra/newview/llchatitemscontainerctrl.cpp b/indra/newview/llchatitemscontainerctrl.cpp
index 9a84280f25..fd4f17b694 100644..100755
--- a/indra/newview/llchatitemscontainerctrl.cpp
+++ b/indra/newview/llchatitemscontainerctrl.cpp
@@ -35,7 +35,7 @@
#include "llfloaterreg.h"
#include "lllocalcliprect.h"
#include "lltrans.h"
-#include "llnearbychatbar.h"
+#include "llfloaterimnearbychat.h"
#include "llviewercontrol.h"
#include "llagentdata.h"
@@ -81,23 +81,30 @@ public:
LLObjectHandler gObjectHandler;
//*******************************************************************************************************************
-//LLNearbyChatToastPanel
+//LLFloaterIMNearbyChatToastPanel
//*******************************************************************************************************************
-LLNearbyChatToastPanel* LLNearbyChatToastPanel::createInstance()
+LLFloaterIMNearbyChatToastPanel* LLFloaterIMNearbyChatToastPanel::createInstance()
{
- LLNearbyChatToastPanel* item = new LLNearbyChatToastPanel();
+ LLFloaterIMNearbyChatToastPanel* item = new LLFloaterIMNearbyChatToastPanel();
item->buildFromFile("panel_chat_item.xml");
item->setFollows(FOLLOWS_NONE);
return item;
}
-void LLNearbyChatToastPanel::reshape (S32 width, S32 height, BOOL called_from_parent )
+void LLFloaterIMNearbyChatToastPanel::reshape (S32 width, S32 height, BOOL called_from_parent )
{
LLPanel::reshape(width, height,called_from_parent);
- LLUICtrl* msg_text = getChild<LLUICtrl>("msg_text", false);
- LLUICtrl* icon = getChild<LLUICtrl>("avatar_icon", false);
+ // reshape() may be called from LLView::initFromParams() before the children are created.
+ // We call findChild() instead of getChild() here to avoid creating dummy controls.
+ LLUICtrl* msg_text = findChild<LLUICtrl>("msg_text", false);
+ LLUICtrl* icon = findChild<LLUICtrl>("avatar_icon", false);
+
+ if (!msg_text || !icon)
+ {
+ return;
+ }
LLRect msg_text_rect = msg_text->getRect();
LLRect avatar_rect = icon->getRect();
@@ -114,12 +121,12 @@ void LLNearbyChatToastPanel::reshape (S32 width, S32 height, BOOL called_from_p
msg_text->setRect(msg_text_rect);
}
-BOOL LLNearbyChatToastPanel::postBuild()
+BOOL LLFloaterIMNearbyChatToastPanel::postBuild()
{
return LLPanel::postBuild();
}
-void LLNearbyChatToastPanel::addMessage(LLSD& notification)
+void LLFloaterIMNearbyChatToastPanel::addMessage(LLSD& notification)
{
std::string messageText = notification["message"].asString(); // UTF-8 line of text
@@ -171,7 +178,7 @@ void LLNearbyChatToastPanel::addMessage(LLSD& notification)
}
-void LLNearbyChatToastPanel::init(LLSD& notification)
+void LLFloaterIMNearbyChatToastPanel::init(LLSD& notification)
{
std::string messageText = notification["message"].asString(); // UTF-8 line of text
std::string fromName = notification["from"].asString(); // agent or object name
@@ -266,7 +273,7 @@ void LLNearbyChatToastPanel::init(LLSD& notification)
mIsDirty = true;//will set Avatar Icon in draw
}
-void LLNearbyChatToastPanel::snapToMessageHeight ()
+void LLFloaterIMNearbyChatToastPanel::snapToMessageHeight ()
{
LLChatMsgBox* text_box = getChild<LLChatMsgBox>("msg_text", false);
S32 new_height = llmax (text_box->getTextPixelHeight() + 2*text_box->getVPad() + 2*msg_height_pad, 25);
@@ -281,22 +288,22 @@ void LLNearbyChatToastPanel::snapToMessageHeight ()
}
-void LLNearbyChatToastPanel::onMouseLeave (S32 x, S32 y, MASK mask)
+void LLFloaterIMNearbyChatToastPanel::onMouseLeave (S32 x, S32 y, MASK mask)
{
}
-void LLNearbyChatToastPanel::onMouseEnter (S32 x, S32 y, MASK mask)
+void LLFloaterIMNearbyChatToastPanel::onMouseEnter (S32 x, S32 y, MASK mask)
{
if(mSourceType != CHAT_SOURCE_AGENT)
return;
}
-BOOL LLNearbyChatToastPanel::handleMouseDown (S32 x, S32 y, MASK mask)
+BOOL LLFloaterIMNearbyChatToastPanel::handleMouseDown (S32 x, S32 y, MASK mask)
{
return LLPanel::handleMouseDown(x,y,mask);
}
-BOOL LLNearbyChatToastPanel::handleMouseUp (S32 x, S32 y, MASK mask)
+BOOL LLFloaterIMNearbyChatToastPanel::handleMouseUp (S32 x, S32 y, MASK mask)
{
/*
fix for request EXT-4780
@@ -316,16 +323,15 @@ BOOL LLNearbyChatToastPanel::handleMouseUp (S32 x, S32 y, MASK mask)
return TRUE;
else
{
- LLNearbyChatBar::getInstance()->showHistory();
+ LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat")->showHistory();
return FALSE;
}
}
-
- LLNearbyChatBar::getInstance()->showHistory();
+ LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat")->showHistory();
return LLPanel::handleMouseUp(x,y,mask);
}
-void LLNearbyChatToastPanel::setHeaderVisibility(EShowItemHeader e)
+void LLFloaterIMNearbyChatToastPanel::setHeaderVisibility(EShowItemHeader e)
{
LLUICtrl* icon = getChild<LLUICtrl>("avatar_icon", false);
if(icon)
@@ -333,7 +339,7 @@ void LLNearbyChatToastPanel::setHeaderVisibility(EShowItemHeader e)
}
-bool LLNearbyChatToastPanel::canAddText ()
+bool LLFloaterIMNearbyChatToastPanel::canAddText ()
{
LLChatMsgBox* msg_text = findChild<LLChatMsgBox>("msg_text");
if(!msg_text)
@@ -341,7 +347,7 @@ bool LLNearbyChatToastPanel::canAddText ()
return msg_text->getLineCount()<10;
}
-BOOL LLNearbyChatToastPanel::handleRightMouseDown(S32 x, S32 y, MASK mask)
+BOOL LLFloaterIMNearbyChatToastPanel::handleRightMouseDown(S32 x, S32 y, MASK mask)
{
LLUICtrl* avatar_icon = getChild<LLUICtrl>("avatar_icon", false);
@@ -353,8 +359,10 @@ BOOL LLNearbyChatToastPanel::handleRightMouseDown(S32 x, S32 y, MASK mask)
return TRUE;
return LLPanel::handleRightMouseDown(x,y,mask);
}
-void LLNearbyChatToastPanel::draw()
+void LLFloaterIMNearbyChatToastPanel::draw()
{
+ LLPanel::draw();
+
if(mIsDirty)
{
LLAvatarIconCtrl* icon = getChild<LLAvatarIconCtrl>("avatar_icon", false);
@@ -372,7 +380,6 @@ void LLNearbyChatToastPanel::draw()
}
mIsDirty = false;
}
- LLToastPanelBase::draw();
}
diff --git a/indra/newview/llchatitemscontainerctrl.h b/indra/newview/llchatitemscontainerctrl.h
index 1d700dcede..54b6499d52 100644..100755
--- a/indra/newview/llchatitemscontainerctrl.h
+++ b/indra/newview/llchatitemscontainerctrl.h
@@ -40,18 +40,18 @@ typedef enum e_show_item_header
CHATITEMHEADER_SHOW_BOTH
} EShowItemHeader;
-class LLNearbyChatToastPanel: public LLToastPanelBase
+class LLFloaterIMNearbyChatToastPanel : public LLPanel
{
protected:
- LLNearbyChatToastPanel()
+ LLFloaterIMNearbyChatToastPanel()
:
mIsDirty(false),
mSourceType(CHAT_SOURCE_OBJECT)
{};
public:
- ~LLNearbyChatToastPanel(){}
+ ~LLFloaterIMNearbyChatToastPanel(){}
- static LLNearbyChatToastPanel* createInstance();
+ static LLFloaterIMNearbyChatToastPanel* createInstance();
const LLUUID& getFromID() const { return mFromID;}
const std::string& getFromName() const { return mFromName; }
diff --git a/indra/newview/llchatmsgbox.cpp b/indra/newview/llchatmsgbox.cpp
index aa6c9c094c..aa6c9c094c 100644..100755
--- a/indra/newview/llchatmsgbox.cpp
+++ b/indra/newview/llchatmsgbox.cpp
diff --git a/indra/newview/llchatmsgbox.h b/indra/newview/llchatmsgbox.h
index 7e008dba46..7e008dba46 100644..100755
--- a/indra/newview/llchatmsgbox.h
+++ b/indra/newview/llchatmsgbox.h
diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp
index a661808d1f..131aea9da3 100644..100755
--- a/indra/newview/llchiclet.cpp
+++ b/indra/newview/llchiclet.cpp
@@ -27,35 +27,17 @@
#include "llviewerprecompiledheaders.h" // must be first include
#include "llchiclet.h"
-#include "llagent.h"
-#include "llavataractions.h"
#include "llchicletbar.h"
-#include "lleventtimer.h"
-#include "llgroupactions.h"
-#include "lliconctrl.h"
-#include "llimfloater.h"
-#include "llimview.h"
+#include "llfloaterimsession.h"
+#include "llfloaterimcontainer.h"
#include "llfloaterreg.h"
#include "lllocalcliprect.h"
-#include "llmenugl.h"
-#include "llnotifications.h"
-#include "llnotificationsutil.h"
-#include "lloutputmonitorctrl.h"
#include "llscriptfloater.h"
-#include "llspeakers.h"
-#include "lltextbox.h"
-#include "llvoiceclient.h"
-#include "llgroupmgr.h"
-#include "llnotificationmanager.h"
-#include "lltransientfloatermgr.h"
+#include "llsingleton.h"
#include "llsyswellwindow.h"
static LLDefaultChildRegistry::Register<LLChicletPanel> t1("chiclet_panel");
-static LLDefaultChildRegistry::Register<LLIMWellChiclet> t2_0("chiclet_im_well");
static LLDefaultChildRegistry::Register<LLNotificationChiclet> t2("chiclet_notification");
-static LLDefaultChildRegistry::Register<LLIMP2PChiclet> t3("chiclet_im_p2p");
-static LLDefaultChildRegistry::Register<LLIMGroupChiclet> t4("chiclet_im_group");
-static LLDefaultChildRegistry::Register<LLAdHocChiclet> t5("chiclet_im_adhoc");
static LLDefaultChildRegistry::Register<LLScriptChiclet> t6("chiclet_script");
static LLDefaultChildRegistry::Register<LLInvOfferChiclet> t7("chiclet_offer");
@@ -66,65 +48,10 @@ boost::signals2::signal<LLChiclet* (const LLUUID&),
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
-/**
- * Updates the Well's 'Lit' state to flash it when "new messages" are come.
- *
- * It gets callback which will be called 2*N times with passed period. See EXT-3147
- */
-class LLSysWellChiclet::FlashToLitTimer : public LLEventTimer
-{
-public:
- typedef boost::function<void()> callback_t;
-
- /**
- * Constructor.
- *
- * @param count - how many times callback should be called (twice to not change original state)
- * @param period - how frequently callback should be called
- * @param cb - callback to be called each tick
- */
- FlashToLitTimer(S32 count, F32 period, callback_t cb)
- : LLEventTimer(period)
- , mCallback(cb)
- , mFlashCount(2 * count)
- , mCurrentFlashCount(0)
- {
- mEventTimer.stop();
- }
-
- BOOL tick()
- {
- mCallback();
-
- if (++mCurrentFlashCount == mFlashCount) mEventTimer.stop();
- return FALSE;
- }
-
- void flash()
- {
- mCurrentFlashCount = 0;
- mEventTimer.start();
- }
-
- void stopFlashing()
- {
- mEventTimer.stop();
- }
-
-private:
- callback_t mCallback;
-
- /**
- * How many times Well will blink.
- */
- S32 mFlashCount;
- S32 mCurrentFlashCount;
-};
-
LLSysWellChiclet::Params::Params()
-: button("button")
-, unread_notifications("unread_notifications")
-, max_displayed_count("max_displayed_count", 99)
+ : button("button")
+ , unread_notifications("unread_notifications")
+ , max_displayed_count("max_displayed_count", 99)
{
button.name = "button";
button.tab_stop = FALSE;
@@ -132,30 +59,24 @@ LLSysWellChiclet::Params::Params()
}
LLSysWellChiclet::LLSysWellChiclet(const Params& p)
-: LLChiclet(p)
-, mButton(NULL)
-, mCounter(0)
-, mMaxDisplayedCount(p.max_displayed_count)
-, mIsNewMessagesState(false)
-, mFlashToLitTimer(NULL)
-, mContextMenu(NULL)
+ : LLChiclet(p)
+ , mButton(NULL)
+ , mCounter(0)
+ , mMaxDisplayedCount(p.max_displayed_count)
+ , mIsNewMessagesState(false)
+ , mFlashToLitTimer(NULL)
+ , mContextMenu(NULL)
{
LLButton::Params button_params = p.button;
mButton = LLUICtrlFactory::create<LLButton>(button_params);
addChild(mButton);
- // use settings from settings.xml to be able change them via Debug settings. See EXT-5973.
- // Due to Timer is implemented as derived class from EventTimer it is impossible to change period
- // in runtime. So, both settings are made as required restart.
- static S32 flash_to_lit_count = gSavedSettings.getS32("WellIconFlashCount");
- static F32 flash_period = gSavedSettings.getF32("WellIconFlashPeriod");
-
- mFlashToLitTimer = new FlashToLitTimer(flash_to_lit_count, flash_period, boost::bind(&LLSysWellChiclet::changeLitState, this));
+ mFlashToLitTimer = new LLFlashTimer(boost::bind(&LLSysWellChiclet::changeLitState, this, _1));
}
LLSysWellChiclet::~LLSysWellChiclet()
{
- delete mFlashToLitTimer;
+ mFlashToLitTimer->unset();
}
void LLSysWellChiclet::setCounter(S32 counter)
@@ -190,7 +111,7 @@ void LLSysWellChiclet::setToggleState(BOOL toggled) {
mButton->setToggleState(toggled);
}
-void LLSysWellChiclet::changeLitState()
+void LLSysWellChiclet::changeLitState(bool blink)
{
setNewMessagesState(!mIsNewMessagesState);
}
@@ -235,136 +156,25 @@ BOOL LLSysWellChiclet::handleRightMouseDown(S32 x, S32 y, MASK mask)
}
/************************************************************************/
-/* LLIMWellChiclet implementation */
-/************************************************************************/
-LLIMWellChiclet::LLIMWellChiclet(const Params& p)
-: LLSysWellChiclet(p)
-{
- LLIMModel::instance().addNewMsgCallback(boost::bind(&LLIMWellChiclet::messageCountChanged, this, _1));
- LLIMModel::instance().addNoUnreadMsgsCallback(boost::bind(&LLIMWellChiclet::messageCountChanged, this, _1));
-
- LLIMMgr::getInstance()->addSessionObserver(this);
-
- LLIMWellWindow::getInstance()->setSysWellChiclet(this);
-}
-
-LLIMWellChiclet::~LLIMWellChiclet()
-{
- LLIMWellWindow* im_well_window = LLIMWellWindow::findInstance();
- if (im_well_window)
- {
- im_well_window->setSysWellChiclet(NULL);
- }
-
- LLIMMgr::getInstance()->removeSessionObserver(this);
-}
-
-void LLIMWellChiclet::onMenuItemClicked(const LLSD& user_data)
-{
- std::string action = user_data.asString();
- if("close all" == action)
- {
- LLIMWellWindow::getInstance()->closeAll();
- }
-}
-
-bool LLIMWellChiclet::enableMenuItem(const LLSD& user_data)
-{
- std::string item = user_data.asString();
- if (item == "can close all")
- {
- return !LLIMWellWindow::getInstance()->isWindowEmpty();
- }
- return true;
-}
-
-void LLIMWellChiclet::createMenu()
-{
- if(mContextMenu)
- {
- llwarns << "Menu already exists" << llendl;
- return;
- }
-
- LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
- registrar.add("IMWellChicletMenu.Action",
- boost::bind(&LLIMWellChiclet::onMenuItemClicked, this, _2));
-
- LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
- enable_registrar.add("IMWellChicletMenu.EnableItem",
- boost::bind(&LLIMWellChiclet::enableMenuItem, this, _2));
-
- mContextMenu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>
- ("menu_im_well_button.xml",
- LLMenuGL::sMenuContainer,
- LLViewerMenuHolderGL::child_registry_t::instance());
-}
-
-void LLIMWellChiclet::messageCountChanged(const LLSD& session_data)
-{
- // The singleton class LLChicletBar instance might be already deleted
- // so don't create a new one.
- if (!LLChicletBar::instanceExists())
- {
- return;
- }
-
- const LLUUID& session_id = session_data["session_id"];
- const S32 counter = LLChicletBar::getInstance()->getTotalUnreadIMCount();
- const bool im_not_visible = !LLFloaterReg::instanceVisible("im_container")
- && !LLFloaterReg::instanceVisible("impanel", session_id);
-
- setNewMessagesState(counter > mCounter && im_not_visible);
-
- // we have to flash to 'Lit' state each time new unread message is coming.
- if (counter > mCounter && im_not_visible)
- {
- mFlashToLitTimer->flash();
- }
- else if (counter == 0)
- {
- // if notification is resolved while well is flashing it can leave in the 'Lit' state
- // when flashing finishes itself. Let break flashing here.
- mFlashToLitTimer->stopFlashing();
- }
-
- setCounter(counter);
-}
-
-/************************************************************************/
/* LLNotificationChiclet implementation */
/************************************************************************/
LLNotificationChiclet::LLNotificationChiclet(const Params& p)
-: LLSysWellChiclet(p)
-, mUreadSystemNotifications(0)
+: LLSysWellChiclet(p),
+ mUreadSystemNotifications(0)
{
- // connect counter handlers to the signals
- connectCounterUpdatersToSignal("notify");
- connectCounterUpdatersToSignal("groupnotify");
- connectCounterUpdatersToSignal("offer");
-
+ mNotificationChannel.reset(new ChicletNotificationChannel(this));
// ensure that notification well window exists, to synchronously
// handle toast add/delete events.
LLNotificationWellWindow::getInstance()->setSysWellChiclet(this);
}
-void LLNotificationChiclet::connectCounterUpdatersToSignal(const std::string& notification_type)
-{
- LLNotificationsUI::LLNotificationManager* manager = LLNotificationsUI::LLNotificationManager::getInstance();
- LLNotificationsUI::LLEventHandler* n_handler = manager->getHandlerForNotification(notification_type);
- if(n_handler)
- {
- n_handler->setNewNotificationCallback(boost::bind(&LLNotificationChiclet::incUreadSystemNotifications, this));
- n_handler->setDelNotification(boost::bind(&LLNotificationChiclet::decUreadSystemNotifications, this));
- }
-}
-
void LLNotificationChiclet::onMenuItemClicked(const LLSD& user_data)
{
std::string action = user_data.asString();
if("close all" == action)
{
LLNotificationWellWindow::getInstance()->closeAll();
+ LLIMWellWindow::getInstance()->closeAll();
}
}
@@ -407,6 +217,30 @@ void LLNotificationChiclet::setCounter(S32 counter)
updateWidget(getCounter() == 0);
}
+
+bool LLNotificationChiclet::ChicletNotificationChannel::filterNotification( LLNotificationPtr notification )
+{
+ bool displayNotification;
+ if ( (notification->getName() == "ScriptDialog") // special case for scripts
+ // if there is no toast window for the notification, filter it
+ || (!LLNotificationWellWindow::getInstance()->findItemByID(notification->getID()))
+ )
+ {
+ displayNotification = false;
+ }
+ else if( !(notification->canLogToIM() && notification->hasFormElements())
+ && (!notification->getPayload().has("give_inventory_notification")
+ || notification->getPayload()["give_inventory_notification"]))
+ {
+ displayNotification = true;
+ }
+ else
+ {
+ displayNotification = false;
+ }
+ return displayNotification;
+}
+
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
@@ -422,12 +256,6 @@ LLChiclet::LLChiclet(const Params& p)
, mSessionId(LLUUID::null)
, mShowCounter(p.show_counter)
{
-
-}
-
-LLChiclet::~LLChiclet()
-{
-
}
boost::signals2::connection LLChiclet::setLeftButtonClickCallback(
@@ -462,7 +290,9 @@ LLSD LLChiclet::getValue() const
void LLChiclet::setValue(const LLSD& value)
{
if(value.isUUID())
+ {
setSessionId(value.asUUID());
+ }
}
//////////////////////////////////////////////////////////////////////////
@@ -474,12 +304,9 @@ LLIMChiclet::LLIMChiclet(const LLIMChiclet::Params& p)
, mShowSpeaker(false)
, mDefaultWidth(p.rect().getWidth())
, mNewMessagesIcon(NULL)
-, mSpeakerCtrl(NULL)
-, mCounterCtrl(NULL)
, mChicletButton(NULL)
, mPopupMenu(NULL)
{
- enableCounterControl(p.enable_counter);
}
/* virtual*/
@@ -490,16 +317,6 @@ BOOL LLIMChiclet::postBuild()
mChicletButton->setDoubleClickCallback(boost::bind(&LLIMChiclet::onMouseDown, this));
return TRUE;
}
-void LLIMChiclet::setShowSpeaker(bool show)
-{
- bool needs_resize = getShowSpeaker() != show;
- if(needs_resize)
- {
- mShowSpeaker = show;
- }
-
- toggleSpeakerControl();
-}
void LLIMChiclet::enableCounterControl(bool enable)
{
@@ -510,87 +327,13 @@ void LLIMChiclet::enableCounterControl(bool enable)
}
}
-void LLIMChiclet::setShowCounter(bool show)
-{
- if(!mCounterEnabled)
- {
- return;
- }
-
- bool needs_resize = getShowCounter() != show;
- if(needs_resize)
- {
- LLChiclet::setShowCounter(show);
- toggleCounterControl();
- }
-}
-
-void LLIMChiclet::initSpeakerControl()
-{
- // virtual
-}
-
void LLIMChiclet::setRequiredWidth()
{
- bool show_speaker = getShowSpeaker();
- bool show_counter = getShowCounter();
S32 required_width = mDefaultWidth;
-
- if (show_counter)
- {
- required_width += mCounterCtrl->getRect().getWidth();
- }
- if (show_speaker)
- {
- required_width += mSpeakerCtrl->getRect().getWidth();
- }
-
reshape(required_width, getRect().getHeight());
-
onChicletSizeChanged();
}
-void LLIMChiclet::toggleSpeakerControl()
-{
- if(getShowSpeaker())
- {
- // move speaker to the right of chiclet icon
- LLRect speaker_rc = mSpeakerCtrl->getRect();
- speaker_rc.setLeftTopAndSize(mDefaultWidth, speaker_rc.mTop, speaker_rc.getWidth(), speaker_rc.getHeight());
- mSpeakerCtrl->setRect(speaker_rc);
-
- if(getShowCounter())
- {
- // move speaker to the right of counter
- mSpeakerCtrl->translate(mCounterCtrl->getRect().getWidth(), 0);
- }
-
- initSpeakerControl();
- }
-
- setRequiredWidth();
- mSpeakerCtrl->setSpeakerId(LLUUID::null);
- mSpeakerCtrl->setVisible(getShowSpeaker());
-}
-
-void LLIMChiclet::setCounter(S32 counter)
-{
- if (mCounterCtrl->getCounter() == counter)
- {
- return;
- }
-
- mCounterCtrl->setCounter(counter);
- setShowCounter(counter);
- setShowNewMessagesIcon(counter);
-}
-
-void LLIMChiclet::toggleCounterControl()
-{
- setRequiredWidth();
- mCounterCtrl->setVisible(getShowCounter());
-}
-
void LLIMChiclet::setShowNewMessagesIcon(bool show)
{
if(mNewMessagesIcon)
@@ -607,8 +350,7 @@ bool LLIMChiclet::getShowNewMessagesIcon()
void LLIMChiclet::onMouseDown()
{
- LLIMFloater::toggle(getSessionId());
- setCounter(0);
+ LLFloaterIMSession::toggle(getSessionId());
}
void LLIMChiclet::setToggleState(bool toggle)
@@ -616,52 +358,6 @@ void LLIMChiclet::setToggleState(bool toggle)
mChicletButton->setToggleState(toggle);
}
-void LLIMChiclet::draw()
-{
- LLUICtrl::draw();
-}
-
-// static
-LLIMChiclet::EType LLIMChiclet::getIMSessionType(const LLUUID& session_id)
-{
- EType type = TYPE_UNKNOWN;
-
- if(session_id.isNull())
- return type;
-
- EInstantMessage im_type = LLIMModel::getInstance()->getType(session_id);
- if (IM_COUNT == im_type)
- {
- llassert_always(0 && "IM session not found"); // should never happen
- return type;
- }
-
- switch(im_type)
- {
- case IM_NOTHING_SPECIAL:
- case IM_SESSION_P2P_INVITE:
- type = TYPE_IM;
- break;
- case IM_SESSION_GROUP_START:
- case IM_SESSION_INVITE:
- if (gAgent.isInGroup(session_id))
- {
- type = TYPE_GROUP;
- }
- else
- {
- type = TYPE_AD_HOC;
- }
- break;
- case IM_SESSION_CONFERENCE_START:
- type = TYPE_AD_HOC;
- default:
- break;
- }
-
- return type;
-}
-
BOOL LLIMChiclet::handleRightMouseDown(S32 x, S32 y, MASK mask)
{
if(!mPopupMenu)
@@ -697,382 +393,6 @@ bool LLIMChiclet::canCreateMenu()
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
-LLIMP2PChiclet::Params::Params()
-: avatar_icon("avatar_icon")
-, chiclet_button("chiclet_button")
-, unread_notifications("unread_notifications")
-, speaker("speaker")
-, new_message_icon("new_message_icon")
-, show_speaker("show_speaker")
-{
-}
-
-LLIMP2PChiclet::LLIMP2PChiclet(const Params& p)
-: LLIMChiclet(p)
-, mChicletIconCtrl(NULL)
-{
- LLButton::Params button_params = p.chiclet_button;
- mChicletButton = LLUICtrlFactory::create<LLButton>(button_params);
- addChild(mChicletButton);
-
- LLIconCtrl::Params new_msg_params = p.new_message_icon;
- mNewMessagesIcon = LLUICtrlFactory::create<LLIconCtrl>(new_msg_params);
- addChild(mNewMessagesIcon);
-
- LLChicletAvatarIconCtrl::Params avatar_params = p.avatar_icon;
- mChicletIconCtrl = LLUICtrlFactory::create<LLChicletAvatarIconCtrl>(avatar_params);
- addChild(mChicletIconCtrl);
-
- LLChicletNotificationCounterCtrl::Params unread_params = p.unread_notifications;
- mCounterCtrl = LLUICtrlFactory::create<LLChicletNotificationCounterCtrl>(unread_params);
- addChild(mCounterCtrl);
-
- setCounter(getCounter());
- setShowCounter(getShowCounter());
-
- LLChicletSpeakerCtrl::Params speaker_params = p.speaker;
- mSpeakerCtrl = LLUICtrlFactory::create<LLChicletSpeakerCtrl>(speaker_params);
- addChild(mSpeakerCtrl);
-
- sendChildToFront(mNewMessagesIcon);
- setShowSpeaker(p.show_speaker);
-}
-
-void LLIMP2PChiclet::initSpeakerControl()
-{
- mSpeakerCtrl->setSpeakerId(getOtherParticipantId());
-}
-
-void LLIMP2PChiclet::setOtherParticipantId(const LLUUID& other_participant_id)
-{
- LLIMChiclet::setOtherParticipantId(other_participant_id);
- mChicletIconCtrl->setValue(getOtherParticipantId());
-}
-
-void LLIMP2PChiclet::updateMenuItems()
-{
- if(!mPopupMenu)
- return;
- if(getSessionId().isNull())
- return;
-
- LLIMFloater* open_im_floater = LLIMFloater::findInstance(getSessionId());
- bool open_window_exists = open_im_floater && open_im_floater->getVisible();
- mPopupMenu->getChild<LLUICtrl>("Send IM")->setEnabled(!open_window_exists);
-
- bool is_friend = LLAvatarActions::isFriend(getOtherParticipantId());
- mPopupMenu->getChild<LLUICtrl>("Add Friend")->setEnabled(!is_friend);
-}
-
-void LLIMP2PChiclet::createPopupMenu()
-{
- if(!canCreateMenu())
- return;
-
- LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
- registrar.add("IMChicletMenu.Action", boost::bind(&LLIMP2PChiclet::onMenuItemClicked, this, _2));
-
- mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>
- ("menu_imchiclet_p2p.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
-}
-
-void LLIMP2PChiclet::onMenuItemClicked(const LLSD& user_data)
-{
- std::string level = user_data.asString();
- LLUUID other_participant_id = getOtherParticipantId();
-
- if("profile" == level)
- {
- LLAvatarActions::showProfile(other_participant_id);
- }
- else if("im" == level)
- {
- LLAvatarActions::startIM(other_participant_id);
- }
- else if("add" == level)
- {
- LLAvatarActions::requestFriendshipDialog(other_participant_id);
- }
- else if("end" == level)
- {
- LLAvatarActions::endIM(other_participant_id);
- }
-}
-
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-
-LLAdHocChiclet::Params::Params()
-: avatar_icon("avatar_icon")
-, chiclet_button("chiclet_button")
-, unread_notifications("unread_notifications")
-, speaker("speaker")
-, new_message_icon("new_message_icon")
-, show_speaker("show_speaker")
-, avatar_icon_color("avatar_icon_color", LLColor4::green)
-{
-}
-
-LLAdHocChiclet::LLAdHocChiclet(const Params& p)
-: LLIMChiclet(p)
-, mChicletIconCtrl(NULL)
-{
- LLButton::Params button_params = p.chiclet_button;
- mChicletButton = LLUICtrlFactory::create<LLButton>(button_params);
- addChild(mChicletButton);
-
- LLIconCtrl::Params new_msg_params = p.new_message_icon;
- mNewMessagesIcon = LLUICtrlFactory::create<LLIconCtrl>(new_msg_params);
- addChild(mNewMessagesIcon);
-
- LLChicletAvatarIconCtrl::Params avatar_params = p.avatar_icon;
- mChicletIconCtrl = LLUICtrlFactory::create<LLChicletAvatarIconCtrl>(avatar_params);
- //Make the avatar modified
- mChicletIconCtrl->setColor(p.avatar_icon_color);
- addChild(mChicletIconCtrl);
-
- LLChicletNotificationCounterCtrl::Params unread_params = p.unread_notifications;
- mCounterCtrl = LLUICtrlFactory::create<LLChicletNotificationCounterCtrl>(unread_params);
- addChild(mCounterCtrl);
-
- setCounter(getCounter());
- setShowCounter(getShowCounter());
-
- LLChicletSpeakerCtrl::Params speaker_params = p.speaker;
- mSpeakerCtrl = LLUICtrlFactory::create<LLChicletSpeakerCtrl>(speaker_params);
- addChild(mSpeakerCtrl);
-
- sendChildToFront(mNewMessagesIcon);
- setShowSpeaker(p.show_speaker);
-}
-
-void LLAdHocChiclet::setSessionId(const LLUUID& session_id)
-{
- LLChiclet::setSessionId(session_id);
- LLIMModel::LLIMSession* im_session = LLIMModel::getInstance()->findIMSession(session_id);
- mChicletIconCtrl->setValue(im_session->mOtherParticipantID);
-}
-
-void LLAdHocChiclet::draw()
-{
- switchToCurrentSpeaker();
- LLIMChiclet::draw();
-}
-
-void LLAdHocChiclet::initSpeakerControl()
-{
- switchToCurrentSpeaker();
-}
-
-void LLAdHocChiclet::switchToCurrentSpeaker()
-{
- LLUUID speaker_id;
- LLSpeakerMgr::speaker_list_t speaker_list;
-
- LLIMModel::getInstance()->findIMSession(getSessionId())->mSpeakers->getSpeakerList(&speaker_list, FALSE);
- for (LLSpeakerMgr::speaker_list_t::iterator i = speaker_list.begin(); i != speaker_list.end(); ++i)
- {
- LLPointer<LLSpeaker> s = *i;
- if (s->mSpeechVolume > 0 || s->mStatus == LLSpeaker::STATUS_SPEAKING)
- {
- speaker_id = s->mID;
- break;
- }
- }
-
- mSpeakerCtrl->setSpeakerId(speaker_id);
-}
-
-void LLAdHocChiclet::createPopupMenu()
-{
- if(!canCreateMenu())
- return;
-
- LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
- registrar.add("IMChicletMenu.Action", boost::bind(&LLAdHocChiclet::onMenuItemClicked, this, _2));
-
- mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>
- ("menu_imchiclet_adhoc.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
-}
-
-void LLAdHocChiclet::onMenuItemClicked(const LLSD& user_data)
-{
- std::string level = user_data.asString();
- LLUUID group_id = getSessionId();
-
- if("end" == level)
- {
- LLGroupActions::endIM(group_id);
- }
-}
-
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-
-LLIMGroupChiclet::Params::Params()
-: group_icon("group_icon")
-, chiclet_button("chiclet_button")
-, unread_notifications("unread_notifications")
-, speaker("speaker")
-, new_message_icon("new_message_icon")
-, show_speaker("show_speaker")
-{
-}
-
-LLIMGroupChiclet::LLIMGroupChiclet(const Params& p)
-: LLIMChiclet(p)
-, LLGroupMgrObserver(LLUUID::null)
-, mChicletIconCtrl(NULL)
-{
- LLButton::Params button_params = p.chiclet_button;
- mChicletButton = LLUICtrlFactory::create<LLButton>(button_params);
- addChild(mChicletButton);
-
- LLIconCtrl::Params new_msg_params = p.new_message_icon;
- mNewMessagesIcon = LLUICtrlFactory::create<LLIconCtrl>(new_msg_params);
- addChild(mNewMessagesIcon);
-
- LLChicletGroupIconCtrl::Params avatar_params = p.group_icon;
- mChicletIconCtrl = LLUICtrlFactory::create<LLChicletGroupIconCtrl>(avatar_params);
- addChild(mChicletIconCtrl);
-
- LLChicletNotificationCounterCtrl::Params unread_params = p.unread_notifications;
- mCounterCtrl = LLUICtrlFactory::create<LLChicletNotificationCounterCtrl>(unread_params);
- addChild(mCounterCtrl);
-
- setCounter(getCounter());
- setShowCounter(getShowCounter());
-
- LLChicletSpeakerCtrl::Params speaker_params = p.speaker;
- mSpeakerCtrl = LLUICtrlFactory::create<LLChicletSpeakerCtrl>(speaker_params);
- addChild(mSpeakerCtrl);
-
- sendChildToFront(mNewMessagesIcon);
- setShowSpeaker(p.show_speaker);
-}
-
-LLIMGroupChiclet::~LLIMGroupChiclet()
-{
- LLGroupMgr::getInstance()->removeObserver(this);
-}
-
-void LLIMGroupChiclet::draw()
-{
- if(getShowSpeaker())
- {
- switchToCurrentSpeaker();
- }
- LLIMChiclet::draw();
-}
-
-void LLIMGroupChiclet::initSpeakerControl()
-{
- switchToCurrentSpeaker();
-}
-
-void LLIMGroupChiclet::switchToCurrentSpeaker()
-{
- LLUUID speaker_id;
- LLSpeakerMgr::speaker_list_t speaker_list;
-
- LLIMModel::getInstance()->findIMSession(getSessionId())->mSpeakers->getSpeakerList(&speaker_list, FALSE);
- for (LLSpeakerMgr::speaker_list_t::iterator i = speaker_list.begin(); i != speaker_list.end(); ++i)
- {
- LLPointer<LLSpeaker> s = *i;
- if (s->mSpeechVolume > 0 || s->mStatus == LLSpeaker::STATUS_SPEAKING)
- {
- speaker_id = s->mID;
- break;
- }
- }
-
- mSpeakerCtrl->setSpeakerId(speaker_id);
-}
-
-void LLIMGroupChiclet::setSessionId(const LLUUID& session_id)
-{
- LLChiclet::setSessionId(session_id);
-
- LLGroupMgr* grp_mgr = LLGroupMgr::getInstance();
- LLGroupMgrGroupData* group_data = grp_mgr->getGroupData(session_id);
- if (group_data && group_data->mInsigniaID.notNull())
- {
- mChicletIconCtrl->setValue(group_data->mInsigniaID);
- }
- else
- {
- if(getSessionId() != mID)
- {
- grp_mgr->removeObserver(this);
- mID = getSessionId();
- grp_mgr->addObserver(this);
- }
- grp_mgr->sendGroupPropertiesRequest(session_id);
- }
-}
-
-void LLIMGroupChiclet::changed(LLGroupChange gc)
-{
- if (GC_PROPERTIES == gc)
- {
- LLGroupMgrGroupData* group_data = LLGroupMgr::getInstance()->getGroupData(getSessionId());
- if (group_data)
- {
- mChicletIconCtrl->setValue(group_data->mInsigniaID);
- }
- }
-}
-
-void LLIMGroupChiclet::updateMenuItems()
-{
- if(!mPopupMenu)
- return;
- if(getSessionId().isNull())
- return;
-
- LLIMFloater* open_im_floater = LLIMFloater::findInstance(getSessionId());
- bool open_window_exists = open_im_floater && open_im_floater->getVisible();
- mPopupMenu->getChild<LLUICtrl>("Chat")->setEnabled(!open_window_exists);
-}
-
-void LLIMGroupChiclet::createPopupMenu()
-{
- if(!canCreateMenu())
- return;
-
- LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
- registrar.add("IMChicletMenu.Action", boost::bind(&LLIMGroupChiclet::onMenuItemClicked, this, _2));
-
- mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>
- ("menu_imchiclet_group.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
-}
-
-void LLIMGroupChiclet::onMenuItemClicked(const LLSD& user_data)
-{
- std::string level = user_data.asString();
- LLUUID group_id = getSessionId();
-
- if("group chat" == level)
- {
- LLGroupActions::startIM(group_id);
- }
- else if("info" == level)
- {
- LLGroupActions::show(group_id);
- }
- else if("end" == level)
- {
- LLGroupActions::endIM(group_id);
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-
LLChicletPanel::Params::Params()
: chiclet_padding("chiclet_padding")
, scrolling_offset("scrolling_offset")
@@ -1115,28 +435,15 @@ LLChicletPanel::~LLChicletPanel()
void LLChicletPanel::onMessageCountChanged(const LLSD& data)
{
- LLUUID session_id = data["session_id"].asUUID();
- S32 unread = data["participant_unread"].asInteger();
+ // *TODO : we either suppress this method or return a value. Right now, it servers no purpose.
+ /*
- LLIMFloater* im_floater = LLIMFloater::findInstance(session_id);
- if (im_floater && im_floater->getVisible() && im_floater->hasFocus())
- {
- unread = 0;
- }
-
- std::list<LLChiclet*> chiclets = LLIMChiclet::sFindChicletsSignal(session_id);
- std::list<LLChiclet *>::iterator iter;
- for (iter = chiclets.begin(); iter != chiclets.end(); iter++) {
- LLChiclet* chiclet = *iter;
- if (chiclet != NULL)
- {
- chiclet->setCounter(unread);
- }
- else
- {
- llwarns << "Unable to set counter for chiclet " << session_id << llendl;
- }
- }
+ //LLFloaterIMSession* im_floater = LLFloaterIMSession::findInstance(session_id);
+ //if (im_floater && im_floater->getVisible() && im_floater->hasFocus())
+ //{
+ // unread = 0;
+ //}
+ */
}
void LLChicletPanel::objectChicletCallback(const LLSD& data)
@@ -1151,10 +458,6 @@ void LLChicletPanel::objectChicletCallback(const LLSD& data)
LLIMChiclet* chiclet = dynamic_cast<LLIMChiclet*>(*iter);
if (chiclet != NULL)
{
- if(data.has("unread"))
- {
- chiclet->setCounter(data["unread"]);
- }
chiclet->setShowNewMessagesIcon(new_message);
}
}
@@ -1196,28 +499,13 @@ void LLChicletPanel::onCurrentVoiceChannelChanged(const LLUUID& session_id)
LLIMChiclet* chiclet = dynamic_cast<LLIMChiclet*>(*it);
if(chiclet)
{
- chiclet->setShowSpeaker(true);
if (gSavedSettings.getBOOL("OpenIMOnVoice"))
{
- LLIMFloater::show(chiclet->getSessionId());
+ LLFloaterIMContainer::getInstance()->showConversation(session_id);
}
}
}
- if(!s_previous_active_voice_session_id.isNull() && s_previous_active_voice_session_id != session_id)
- {
- chiclets = LLIMChiclet::sFindChicletsSignal(s_previous_active_voice_session_id);
-
- for(std::list<LLChiclet *>::iterator it = chiclets.begin(); it != chiclets.end(); ++it)
- {
- LLIMChiclet* chiclet = dynamic_cast<LLIMChiclet*>(*it);
- if(chiclet)
- {
- chiclet->setShowSpeaker(false);
- }
- }
- }
-
s_previous_active_voice_session_id = session_id;
}
@@ -1690,7 +978,7 @@ bool LLChicletPanel::isAnyIMFloaterDoked()
for (chiclet_list_t::iterator it = mChicletList.begin(); it
!= mChicletList.end(); it++)
{
- LLIMFloater* im_floater = LLFloaterReg::findTypedInstance<LLIMFloater>(
+ LLFloaterIMSession* im_floater = LLFloaterReg::findTypedInstance<LLFloaterIMSession>(
"impanel", (*it)->getSessionId());
if (im_floater != NULL && im_floater->getVisible()
&& !im_floater->isMinimized() && im_floater->isDocked())
@@ -1703,89 +991,17 @@ bool LLChicletPanel::isAnyIMFloaterDoked()
return res;
}
-S32 LLChicletPanel::getTotalUnreadIMCount()
-{
- S32 count = 0;
- chiclet_list_t::const_iterator it = mChicletList.begin();
- for( ; mChicletList.end() != it; ++it)
- {
- LLIMChiclet* chiclet = dynamic_cast<LLIMChiclet*>(*it);
- if(chiclet)
- {
- count += chiclet->getCounter();
- }
- }
- return count;
-}
-
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
LLChicletNotificationCounterCtrl::Params::Params()
-: max_displayed_count("max_displayed_count", 99)
-{
-}
-
-LLChicletNotificationCounterCtrl::LLChicletNotificationCounterCtrl(const Params& p)
- : LLTextBox(p)
- , mCounter(0)
- , mInitialWidth(0)
- , mMaxDisplayedCount(p.max_displayed_count)
+ : max_displayed_count("max_displayed_count", 99)
{
- mInitialWidth = getRect().getWidth();
-}
-
-void LLChicletNotificationCounterCtrl::setCounter(S32 counter)
-{
- mCounter = counter;
-
- // note same code in LLSysWellChiclet::setCounter(S32 counter)
- std::string s_count;
- if(counter != 0)
- {
- static std::string more_messages_exist("+");
- std::string more_messages(counter > mMaxDisplayedCount ? more_messages_exist : "");
- s_count = llformat("%d%s"
- , llmin(counter, mMaxDisplayedCount)
- , more_messages.c_str()
- );
- }
-
- if(mCounter != 0)
- {
- setText(s_count);
- }
- else
- {
- setText(std::string(""));
- }
-}
-
-LLRect LLChicletNotificationCounterCtrl::getRequiredRect()
-{
- LLRect rc;
- S32 text_width = getTextPixelWidth();
-
- rc.mRight = rc.mLeft + llmax(text_width, mInitialWidth);
-
- return rc;
-}
-
-void LLChicletNotificationCounterCtrl::setValue(const LLSD& value)
-{
- if(value.isInteger())
- setCounter(value.asInteger());
-}
-
-LLSD LLChicletNotificationCounterCtrl::getValue() const
-{
- return LLSD(getCounter());
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
-
LLChicletAvatarIconCtrl::LLChicletAvatarIconCtrl(const Params& p)
: LLAvatarIconCtrl(p)
{
@@ -1795,29 +1011,6 @@ LLChicletAvatarIconCtrl::LLChicletAvatarIconCtrl(const Params& p)
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
-LLChicletGroupIconCtrl::LLChicletGroupIconCtrl(const Params& p)
-: LLIconCtrl(p)
-, mDefaultIcon(p.default_icon)
-{
- setValue(LLUUID::null);
-}
-
-void LLChicletGroupIconCtrl::setValue(const LLSD& value )
-{
- if(value.asUUID().isNull())
- {
- LLIconCtrl::setValue(mDefaultIcon);
- }
- else
- {
- LLIconCtrl::setValue(value);
- }
-}
-
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-
LLChicletInvOfferIconCtrl::LLChicletInvOfferIconCtrl(const Params& p)
: LLChicletAvatarIconCtrl(p)
, mDefaultIcon(p.default_icon)
@@ -1840,15 +1033,6 @@ void LLChicletInvOfferIconCtrl::setValue(const LLSD& value )
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
-LLChicletSpeakerCtrl::LLChicletSpeakerCtrl(const Params&p)
- : LLOutputMonitorCtrl(p)
-{
-}
-
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-
LLScriptChiclet::Params::Params()
: icon("icon")
, chiclet_button("chiclet_button")
@@ -1884,11 +1068,6 @@ void LLScriptChiclet::setSessionId(const LLUUID& session_id)
setToolTip(LLScriptFloaterManager::getObjectName(session_id));
}
-void LLScriptChiclet::setCounter(S32 counter)
-{
- setShowNewMessagesIcon( counter > 0 );
-}
-
void LLScriptChiclet::onMouseDown()
{
LLScriptFloaterManager::getInstance()->toggleScriptFloater(getSessionId());
@@ -1967,11 +1146,6 @@ void LLInvOfferChiclet::setSessionId(const LLUUID& session_id)
}
}
-void LLInvOfferChiclet::setCounter(S32 counter)
-{
- setShowNewMessagesIcon( counter > 0 );
-}
-
void LLInvOfferChiclet::onMouseDown()
{
LLScriptFloaterManager::instance().toggleScriptFloater(getSessionId());
diff --git a/indra/newview/llchiclet.h b/indra/newview/llchiclet.h
index 19683492c2..efaf03384a 100644..100755
--- a/indra/newview/llchiclet.h
+++ b/indra/newview/llchiclet.h
@@ -29,14 +29,11 @@
#include "llavatariconctrl.h"
#include "llbutton.h"
-#include "llpanel.h"
+#include "llnotifications.h"
#include "lltextbox.h"
-#include "lloutputmonitorctrl.h"
-#include "llgroupmgr.h"
-#include "llimview.h"
class LLMenuGL;
-class LLIMFloater;
+class LLFloaterIMSession;
/**
* Class for displaying amount of messages/notifications(unread).
@@ -48,11 +45,11 @@ public:
struct Params : public LLInitParam::Block<Params, LLTextBox::Params>
{
/**
- * Contains maximum displayed count of unread messages. Default value is 9.
- *
- * If count is less than "max_unread_count" will be displayed as is.
- * Otherwise 9+ will be shown (for default value).
- */
+ * Contains maximum displayed count of unread messages. Default value is 9.
+ *
+ * If count is less than "max_unread_count" will be displayed as is.
+ * Otherwise 9+ will be shown (for default value).
+ */
Optional<S32> max_displayed_count;
Params();
@@ -120,35 +117,6 @@ protected:
};
/**
- * Class for displaying group's icon in Group chiclet.
- */
-class LLChicletGroupIconCtrl : public LLIconCtrl
-{
-public:
-
- struct Params : public LLInitParam::Block<Params, LLIconCtrl::Params>
- {
- Optional<std::string> default_icon;
-
- Params()
- : default_icon("default_icon", "Generic_Group")
- {}
- };
-
- /**
- * Sets icon, if value is LLUUID::null - default icon will be set.
- */
- virtual void setValue(const LLSD& value );
-
-protected:
-
- LLChicletGroupIconCtrl(const Params& p);
- friend class LLUICtrlFactory;
-
- std::string mDefaultIcon;
-};
-
-/**
* Class for displaying icon in inventory offer chiclet.
*/
class LLChicletInvOfferIconCtrl : public LLChicletAvatarIconCtrl
@@ -182,23 +150,6 @@ private:
};
/**
- * Class for displaying of speaker's voice indicator
- */
-class LLChicletSpeakerCtrl : public LLOutputMonitorCtrl
-{
-public:
-
- struct Params : public LLInitParam::Block<Params, LLOutputMonitorCtrl::Params>
- {
- Params(){};
- };
-protected:
-
- LLChicletSpeakerCtrl(const Params&p);
- friend class LLUICtrlFactory;
-};
-
-/**
* Base class for all chiclets.
*/
class LLChiclet : public LLUICtrl
@@ -213,7 +164,7 @@ public:
Params();
};
- /*virtual*/ ~LLChiclet();
+ virtual ~LLChiclet() {}
/**
* Associates chat session id with chiclet.
@@ -226,26 +177,11 @@ public:
virtual const LLUUID& getSessionId() const { return mSessionId; }
/**
- * Sets number of unread notifications.
- */
- virtual void setCounter(S32 counter) = 0;
-
- /**
- * Returns number of unread notifications.
- */
- virtual S32 getCounter() = 0;
-
- /**
* Sets show counter state.
*/
virtual void setShowCounter(bool show) { mShowCounter = show; }
/**
- * Returns show counter state.
- */
- virtual bool getShowCounter() {return mShowCounter;};
-
- /**
* Connects chiclet clicked event with callback.
*/
/*virtual*/ boost::signals2::connection setLeftButtonClickCallback(
@@ -322,6 +258,7 @@ public:
* It is used for default setting up of chicklet:click handler, etc.
*/
BOOL postBuild();
+
/**
* Sets IM session name. This name will be displayed in chiclet tooltip.
*/
@@ -334,52 +271,11 @@ public:
virtual void setOtherParticipantId(const LLUUID& other_participant_id) { mOtherParticipantId = other_participant_id; }
/**
- * Gets id of person/group user is chatting with.
+ * Enables/disables the counter control for a chiclet.
*/
- virtual LLUUID getOtherParticipantId() { return mOtherParticipantId; }
-
- /**
- * Init Speaker Control with speaker's ID
- */
- virtual void initSpeakerControl();
-
- /**
- * set status (Shows/Hide) for voice control.
- */
- virtual void setShowSpeaker(bool show);
-
- /**
- * Returns voice chat status control visibility.
- */
- virtual bool getShowSpeaker() {return mShowSpeaker;};
-
- /**
- * Shows/Hides for voice control for a chiclet.
- */
- virtual void toggleSpeakerControl();
-
- /**
- * Sets number of unread messages. Will update chiclet's width if number text
- * exceeds size of counter and notify it's parent about size change.
- */
- virtual void setCounter(S32);
-
- /**
- * Enables/disables the counter control for a chiclet.
- */
virtual void enableCounterControl(bool enable);
/**
- * Sets show counter state.
- */
- virtual void setShowCounter(bool show);
-
- /**
- * Shows/Hides for counter control for a chiclet.
- */
- virtual void toggleCounterControl();
-
- /**
* Sets required width for a chiclet according to visible controls.
*/
virtual void setRequiredWidth();
@@ -394,21 +290,6 @@ public:
*/
virtual bool getShowNewMessagesIcon();
- virtual void draw();
-
- /**
- * Determine whether given ID refers to a group or an IM chat session.
- *
- * This is used when we need to chose what IM chiclet (P2P/group)
- * class to instantiate.
- *
- * @param session_id session ID.
- * @return TYPE_GROUP in case of group chat session,
- * TYPE_IM in case of P2P session,
- * TYPE_UNKNOWN otherwise.
- */
- static EType getIMSessionType(const LLUUID& session_id);
-
/**
* The action taken on mouse down event.
*
@@ -450,8 +331,6 @@ protected:
S32 mDefaultWidth;
LLIconCtrl* mNewMessagesIcon;
- LLChicletNotificationCounterCtrl* mCounterCtrl;
- LLChicletSpeakerCtrl* mSpeakerCtrl;
LLButton* mChicletButton;
/** the id of another participant, either an avatar id or a group id*/
@@ -479,137 +358,6 @@ public:
sFindChicletsSignal;
};
-/**
- * Implements P2P chiclet.
- */
-class LLIMP2PChiclet : public LLIMChiclet
-{
-public:
- struct Params : public LLInitParam::Block<Params, LLIMChiclet::Params>
- {
- Optional<LLButton::Params> chiclet_button;
-
- Optional<LLChicletAvatarIconCtrl::Params> avatar_icon;
-
- Optional<LLChicletNotificationCounterCtrl::Params> unread_notifications;
-
- Optional<LLChicletSpeakerCtrl::Params> speaker;
-
- Optional<LLIconCtrl::Params> new_message_icon;
-
- Optional<bool> show_speaker;
-
- Params();
- };
-
- /* virtual */ void setOtherParticipantId(const LLUUID& other_participant_id);
-
- /**
- * Init Speaker Control with speaker's ID
- */
- /*virtual*/ void initSpeakerControl();
-
- /**
- * Returns number of unread messages.
- */
- /*virtual*/ S32 getCounter() { return mCounterCtrl->getCounter(); }
-
-protected:
- LLIMP2PChiclet(const Params& p);
- friend class LLUICtrlFactory;
-
- /**
- * Creates chiclet popup menu. Will create P2P or Group IM Chat menu
- * based on other participant's id.
- */
- virtual void createPopupMenu();
-
- /**
- * Processes clicks on chiclet popup menu.
- */
- virtual void onMenuItemClicked(const LLSD& user_data);
-
- /**
- * Enables/disables menus based on relationship with other participant.
- * Enables/disables "show session" menu item depending on visible IM floater existence.
- */
- virtual void updateMenuItems();
-
-private:
-
- LLChicletAvatarIconCtrl* mChicletIconCtrl;
-};
-
-/**
- * Implements AD-HOC chiclet.
- */
-class LLAdHocChiclet : public LLIMChiclet
-{
-public:
- struct Params : public LLInitParam::Block<Params, LLIMChiclet::Params>
- {
- Optional<LLButton::Params> chiclet_button;
-
- Optional<LLChicletAvatarIconCtrl::Params> avatar_icon;
-
- Optional<LLChicletNotificationCounterCtrl::Params> unread_notifications;
-
- Optional<LLChicletSpeakerCtrl::Params> speaker;
-
- Optional<LLIconCtrl::Params> new_message_icon;
-
- Optional<bool> show_speaker;
-
- Optional<LLColor4> avatar_icon_color;
-
- Params();
- };
-
- /**
- * Sets session id.
- * Session ID for group chat is actually Group ID.
- */
- /*virtual*/ void setSessionId(const LLUUID& session_id);
-
- /**
- * Keep Speaker Control with actual speaker's ID
- */
- /*virtual*/ void draw();
-
- /**
- * Init Speaker Control with speaker's ID
- */
- /*virtual*/ void initSpeakerControl();
-
- /**
- * Returns number of unread messages.
- */
- /*virtual*/ S32 getCounter() { return mCounterCtrl->getCounter(); }
-
-protected:
- LLAdHocChiclet(const Params& p);
- friend class LLUICtrlFactory;
-
- /**
- * Creates chiclet popup menu. Will create AdHoc Chat menu
- * based on other participant's id.
- */
- virtual void createPopupMenu();
-
- /**
- * Processes clicks on chiclet popup menu.
- */
- virtual void onMenuItemClicked(const LLSD& user_data);
-
- /**
- * Finds a current speaker and resets the SpeakerControl with speaker's ID
- */
- /*virtual*/ void switchToCurrentSpeaker();
-
-private:
-
- LLChicletAvatarIconCtrl* mChicletIconCtrl;
-};
/**
* Chiclet for script floaters.
@@ -631,10 +379,6 @@ public:
/*virtual*/ void setSessionId(const LLUUID& session_id);
- /*virtual*/ void setCounter(S32 counter);
-
- /*virtual*/ S32 getCounter() { return 0; }
-
/**
* Toggle script floater
*/
@@ -680,10 +424,6 @@ public:
/*virtual*/ void setSessionId(const LLUUID& session_id);
- /*virtual*/ void setCounter(S32 counter);
-
- /*virtual*/ S32 getCounter() { return 0; }
-
/**
* Toggle script floater
*/
@@ -708,96 +448,13 @@ private:
};
/**
- * Implements Group chat chiclet.
- */
-class LLIMGroupChiclet : public LLIMChiclet, public LLGroupMgrObserver
-{
-public:
-
- struct Params : public LLInitParam::Block<Params, LLIMChiclet::Params>
- {
- Optional<LLButton::Params> chiclet_button;
-
- Optional<LLChicletGroupIconCtrl::Params> group_icon;
-
- Optional<LLChicletNotificationCounterCtrl::Params> unread_notifications;
-
- Optional<LLChicletSpeakerCtrl::Params> speaker;
-
- Optional<LLIconCtrl::Params> new_message_icon;
-
- Optional<bool> show_speaker;
-
- Params();
- };
-
- /**
- * Sets session id.
- * Session ID for group chat is actually Group ID.
- */
- /*virtual*/ void setSessionId(const LLUUID& session_id);
-
- /**
- * Keep Speaker Control with actual speaker's ID
- */
- /*virtual*/ void draw();
-
- /**
- * Callback for LLGroupMgrObserver, we get this when group data is available or changed.
- * Sets group icon.
- */
- /*virtual*/ void changed(LLGroupChange gc);
-
- /**
- * Init Speaker Control with speaker's ID
- */
- /*virtual*/ void initSpeakerControl();
-
- /**
- * Returns number of unread messages.
- */
- /*virtual*/ S32 getCounter() { return mCounterCtrl->getCounter(); }
-
- ~LLIMGroupChiclet();
-
-protected:
- LLIMGroupChiclet(const Params& p);
- friend class LLUICtrlFactory;
-
- /**
- * Finds a current speaker and resets the SpeakerControl with speaker's ID
- */
- /*virtual*/ void switchToCurrentSpeaker();
-
- /**
- * Creates chiclet popup menu. Will create P2P or Group IM Chat menu
- * based on other participant's id.
- */
- virtual void createPopupMenu();
-
- /**
- * Processes clicks on chiclet popup menu.
- */
- virtual void onMenuItemClicked(const LLSD& user_data);
-
- /**
- * Enables/disables "show session" menu item depending on visible IM floater existence.
- */
- virtual void updateMenuItems();
-
-private:
-
- LLChicletGroupIconCtrl* mChicletIconCtrl;
-};
-
-/**
* Implements notification chiclet. Used to display total amount of unread messages
* across all IM sessions, total amount of system notifications. See EXT-3147 for details
*/
class LLSysWellChiclet : public LLChiclet
{
public:
-
+
struct Params : public LLInitParam::Block<Params, LLChiclet::Params>
{
Optional<LLButton::Params> button;
@@ -843,7 +500,7 @@ protected:
* There is an assumption that it will be called 2*N times to do not change its start state.
* @see FlashToLitTimer
*/
- void changeLitState();
+ void changeLitState(bool blink);
/**
* Displays menu.
@@ -859,86 +516,58 @@ protected:
S32 mMaxDisplayedCount;
bool mIsNewMessagesState;
- FlashToLitTimer* mFlashToLitTimer;
+ LLFlashTimer* mFlashToLitTimer;
LLContextMenu* mContextMenu;
};
-/**
- * Class represented a chiclet for IM Well Icon.
- *
- * It displays a count of unread messages from other participants in all IM sessions.
- */
-class LLIMWellChiclet : public LLSysWellChiclet, LLIMSessionObserver
-{
- friend class LLUICtrlFactory;
-public:
- virtual void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id) {}
- virtual void sessionRemoved(const LLUUID& session_id) { messageCountChanged(LLSD()); }
- virtual void sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id) {}
-
- ~LLIMWellChiclet();
-protected:
- LLIMWellChiclet(const Params& p);
-
- /**
- * Processes clicks on chiclet popup menu.
- */
- virtual void onMenuItemClicked(const LLSD& user_data);
-
- /**
- * Enables chiclet menu items.
- */
- bool enableMenuItem(const LLSD& user_data);
-
- /**
- * Creates menu.
- */
- /*virtual*/ void createMenu();
-
- /**
- * Handles changes in a session (message was added, messages were read, etc.)
- *
- * It get total count of unread messages from a LLIMMgr in all opened sessions and display it.
- *
- * @param[in] session_data contains session related data, is not used now
- * ["session_id"] - id of an appropriate session
- * ["participant_unread"] - count of unread messages from "real" participants.
- *
- * @see LLIMMgr::getNumberOfUnreadParticipantMessages()
- */
- void messageCountChanged(const LLSD& session_data);
-};
-
class LLNotificationChiclet : public LLSysWellChiclet
{
+ LOG_CLASS(LLNotificationChiclet);
+
friend class LLUICtrlFactory;
public:
struct Params : public LLInitParam::Block<Params, LLSysWellChiclet::Params>{};
-
+
protected:
+ struct ChicletNotificationChannel : public LLNotificationChannel
+ {
+ ChicletNotificationChannel(LLNotificationChiclet* chiclet)
+ : LLNotificationChannel(LLNotificationChannel::Params().filter(filterNotification).name(chiclet->getSessionId().asString()))
+ , mChiclet(chiclet)
+ {
+ // connect counter handlers to the signals
+ connectToChannel("Group Notifications");
+ connectToChannel("Offer");
+ connectToChannel("Notifications");
+ }
+
+ static bool filterNotification(LLNotificationPtr notify);
+ // connect counter updaters to the corresponding signals
+ /*virtual*/ void onAdd(LLNotificationPtr p) { mChiclet->setCounter(++mChiclet->mUreadSystemNotifications); }
+ /*virtual*/ void onDelete(LLNotificationPtr p) { mChiclet->setCounter(--mChiclet->mUreadSystemNotifications); }
+
+ LLNotificationChiclet* const mChiclet;
+ };
+
+ boost::scoped_ptr<ChicletNotificationChannel> mNotificationChannel;
+
LLNotificationChiclet(const Params& p);
-
+
/**
* Processes clicks on chiclet menu.
*/
void onMenuItemClicked(const LLSD& user_data);
-
+
/**
* Enables chiclet menu items.
*/
bool enableMenuItem(const LLSD& user_data);
-
+
/**
* Creates menu.
*/
/*virtual*/ void createMenu();
- // connect counter updaters to the corresponding signals
- void connectCounterUpdatersToSignal(const std::string& notification_type);
-
- // methods for updating a number of unread System notifications
- void incUreadSystemNotifications() { setCounter(++mUreadSystemNotifications); }
- void decUreadSystemNotifications() { setCounter(--mUreadSystemNotifications); }
/*virtual*/ void setCounter(S32 counter);
S32 mUreadSystemNotifications;
};
@@ -1044,9 +673,7 @@ public:
S32 getMinWidth() const { return mMinWidth; }
- S32 getTotalUnreadIMCount();
-
- S32 notifyParent(const LLSD& info);
+ /*virtual*/ S32 notifyParent(const LLSD& info);
/**
* Toggle chiclet by session id ON and toggle OFF all other chiclets.
diff --git a/indra/newview/llchicletbar.cpp b/indra/newview/llchicletbar.cpp
index f1bc51fbe7..a51c844775 100644..100755
--- a/indra/newview/llchicletbar.cpp
+++ b/indra/newview/llchicletbar.cpp
@@ -25,16 +25,10 @@
*/
#include "llviewerprecompiledheaders.h" // must be first include
-
#include "llchicletbar.h"
-// library includes
-#include "llfloaterreg.h"
-#include "lllayoutstack.h"
-
-// newview includes
#include "llchiclet.h"
-#include "llimfloater.h" // for LLIMFloater
+#include "lllayoutstack.h"
#include "llpaneltopinfobar.h"
#include "llsyswellwindow.h"
@@ -57,107 +51,14 @@ LLChicletBar::LLChicletBar(const LLSD&)
: mChicletPanel(NULL),
mToolbarStack(NULL)
{
- // Firstly add our self to IMSession observers, so we catch session events
- // before chiclets do that.
- LLIMMgr::getInstance()->addSessionObserver(this);
-
buildFromFile("panel_chiclet_bar.xml");
}
-LLChicletBar::~LLChicletBar()
-{
- if (!LLSingleton<LLIMMgr>::destroyed())
- {
- LLIMMgr::getInstance()->removeSessionObserver(this);
- }
-}
-
-LLIMChiclet* LLChicletBar::createIMChiclet(const LLUUID& session_id)
-{
- LLIMChiclet::EType im_chiclet_type = LLIMChiclet::getIMSessionType(session_id);
-
- switch (im_chiclet_type)
- {
- case LLIMChiclet::TYPE_IM:
- return getChicletPanel()->createChiclet<LLIMP2PChiclet>(session_id);
- case LLIMChiclet::TYPE_GROUP:
- return getChicletPanel()->createChiclet<LLIMGroupChiclet>(session_id);
- case LLIMChiclet::TYPE_AD_HOC:
- return getChicletPanel()->createChiclet<LLAdHocChiclet>(session_id);
- case LLIMChiclet::TYPE_UNKNOWN:
- break;
- }
-
- return NULL;
-}
-
-//virtual
-void LLChicletBar::sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id)
-{
- if (!getChicletPanel()) return;
-
- LLIMModel::LLIMSession* session = LLIMModel::getInstance()->findIMSession(session_id);
- if (!session) return;
-
- // no need to spawn chiclets for participants in P2P calls called through Avaline
- if (session->isP2P() && session->isOtherParticipantAvaline()) return;
-
- if (getChicletPanel()->findChiclet<LLChiclet>(session_id)) return;
-
- LLIMChiclet* chiclet = createIMChiclet(session_id);
- if(chiclet)
- {
- chiclet->setIMSessionName(name);
- chiclet->setOtherParticipantId(other_participant_id);
-
- LLIMFloater::onIMChicletCreated(session_id);
-
- }
- else
- {
- llwarns << "Could not create chiclet" << llendl;
- }
-}
-
-//virtual
-void LLChicletBar::sessionRemoved(const LLUUID& session_id)
-{
- if(getChicletPanel())
- {
- // IM floater should be closed when session removed and associated chiclet closed
- LLIMFloater* iMfloater = LLFloaterReg::findTypedInstance<LLIMFloater>("impanel", session_id);
- if (iMfloater != NULL)
- {
- iMfloater->closeFloater();
- }
-
- getChicletPanel()->removeChiclet(session_id);
- }
-}
-
-void LLChicletBar::sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id)
-{
- //this is only needed in case of outgoing ad-hoc/group chat sessions
- LLChicletPanel* chiclet_panel = getChicletPanel();
- if (chiclet_panel)
- {
- //it should be ad-hoc im chiclet or group im chiclet
- LLChiclet* chiclet = chiclet_panel->findChiclet<LLChiclet>(old_session_id);
- if (chiclet) chiclet->setSessionId(new_session_id);
- }
-}
-
-S32 LLChicletBar::getTotalUnreadIMCount()
-{
- return getChicletPanel()->getTotalUnreadIMCount();
-}
-
BOOL LLChicletBar::postBuild()
{
mToolbarStack = getChild<LLLayoutStack>("toolbar_stack");
mChicletPanel = getChild<LLChicletPanel>("chiclet_list");
- showWellButton("im_well", !LLIMWellWindow::getInstance()->isWindowEmpty());
showWellButton("notification_well", !LLNotificationWellWindow::getInstance()->isWindowEmpty());
LLPanelTopInfoBar::instance().setResizeCallback(boost::bind(&LLChicletBar::fitWithTopInfoBar, this));
diff --git a/indra/newview/llchicletbar.h b/indra/newview/llchicletbar.h
index 1427bf95e0..956c82cb77 100644..100755
--- a/indra/newview/llchicletbar.h
+++ b/indra/newview/llchicletbar.h
@@ -28,7 +28,6 @@
#define LL_LLCHICLETBAR_H
#include "llpanel.h"
-#include "llimview.h"
class LLChicletPanel;
class LLIMChiclet;
@@ -38,30 +37,17 @@ class LLLayoutStack;
class LLChicletBar
: public LLSingleton<LLChicletBar>
, public LLPanel
- , public LLIMSessionObserver
{
LOG_CLASS(LLChicletBar);
friend class LLSingleton<LLChicletBar>;
public:
- ~LLChicletBar();
BOOL postBuild();
LLChicletPanel* getChicletPanel() { return mChicletPanel; }
- // LLIMSessionObserver observe triggers
- virtual void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id);
- virtual void sessionRemoved(const LLUUID& session_id);
- void sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id);
-
- S32 getTotalUnreadIMCount();
-
/*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent);
- /**
- * Creates IM Chiclet based on session type (IM chat or Group chat)
- */
- LLIMChiclet* createIMChiclet(const LLUUID& session_id);
/**
* Shows/hides panel with specified well button (IM or Notification)
diff --git a/indra/newview/llclassifiedinfo.cpp b/indra/newview/llclassifiedinfo.cpp
index 800aff149a..800aff149a 100644..100755
--- a/indra/newview/llclassifiedinfo.cpp
+++ b/indra/newview/llclassifiedinfo.cpp
diff --git a/indra/newview/llclassifiedinfo.h b/indra/newview/llclassifiedinfo.h
index 3ff793b168..3ff793b168 100644..100755
--- a/indra/newview/llclassifiedinfo.h
+++ b/indra/newview/llclassifiedinfo.h
diff --git a/indra/newview/llclassifiedstatsresponder.cpp b/indra/newview/llclassifiedstatsresponder.cpp
index b4da31895f..e3cd83e174 100644..100755
--- a/indra/newview/llclassifiedstatsresponder.cpp
+++ b/indra/newview/llclassifiedstatsresponder.cpp
@@ -62,8 +62,7 @@ void LLClassifiedStatsResponder::result(const LLSD& content)
}
/*virtual*/
-void LLClassifiedStatsResponder::error(U32 status, const std::string& reason)
+void LLClassifiedStatsResponder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)
{
- llinfos << "LLClassifiedStatsResponder::error("
- << status << ": " << reason << ")" << llendl;
+ llinfos << "LLClassifiedStatsResponder::error [status:" << status << "]: " << content << llendl;
}
diff --git a/indra/newview/llclassifiedstatsresponder.h b/indra/newview/llclassifiedstatsresponder.h
index 3db1868cb2..06dcb62fd0 100644..100755
--- a/indra/newview/llclassifiedstatsresponder.h
+++ b/indra/newview/llclassifiedstatsresponder.h
@@ -39,7 +39,7 @@ public:
virtual void result(const LLSD& content);
//If we get back an error (not found, etc...), handle it here
- virtual void error(U32 status, const std::string& reason);
+ virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content);
protected:
LLUUID mClassifiedID;
diff --git a/indra/newview/llcofwearables.cpp b/indra/newview/llcofwearables.cpp
index e9c7a3fa03..e86d6930e8 100644..100755
--- a/indra/newview/llcofwearables.cpp
+++ b/indra/newview/llcofwearables.cpp
@@ -139,8 +139,7 @@ protected:
{
LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
- functor_t take_off = boost::bind(&LLAppearanceMgr::removeItemFromAvatar, LLAppearanceMgr::getInstance(), _1);
- registrar.add("Attachment.Detach", boost::bind(handleMultiple, take_off, mUUIDs));
+ registrar.add("Attachment.Detach", boost::bind(&LLAppearanceMgr::removeItemsFromAvatar, LLAppearanceMgr::getInstance(), mUUIDs));
return createFromFile("menu_cof_attachment.xml");
}
@@ -173,9 +172,8 @@ protected:
LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
LLUUID selected_id = mUUIDs.back();
- functor_t take_off = boost::bind(&LLAppearanceMgr::removeItemFromAvatar, LLAppearanceMgr::getInstance(), _1);
- registrar.add("Clothing.TakeOff", boost::bind(handleMultiple, take_off, mUUIDs));
+ registrar.add("Clothing.TakeOff", boost::bind(&LLAppearanceMgr::removeItemsFromAvatar, LLAppearanceMgr::getInstance(), mUUIDs));
registrar.add("Clothing.Replace", boost::bind(replaceWearable, selected_id));
registrar.add("Clothing.Edit", boost::bind(LLAgentWearables::editWearable, selected_id));
registrar.add("Clothing.Create", boost::bind(&CofClothingContextMenu::createNew, this, selected_id));
diff --git a/indra/newview/llcofwearables.h b/indra/newview/llcofwearables.h
index 9957d6a64e..9957d6a64e 100644..100755
--- a/indra/newview/llcofwearables.h
+++ b/indra/newview/llcofwearables.h
diff --git a/indra/newview/llcolorswatch.cpp b/indra/newview/llcolorswatch.cpp
index 5b942f283a..f1f7da5fd1 100644..100755
--- a/indra/newview/llcolorswatch.cpp
+++ b/indra/newview/llcolorswatch.cpp
@@ -241,8 +241,8 @@ void LLColorSwatchCtrl::draw()
{
if (!mFallbackImageName.empty())
{
- LLPointer<LLViewerFetchedTexture> fallback_image = LLViewerTextureManager::getFetchedTextureFromFile(mFallbackImageName, TRUE,
- LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
+ LLPointer<LLViewerFetchedTexture> fallback_image = LLViewerTextureManager::getFetchedTextureFromFile(mFallbackImageName, FTT_LOCAL_FILE, TRUE,
+ LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
if( fallback_image->getComponents() == 4 )
{
gl_rect_2d_checkerboard( interior );
diff --git a/indra/newview/llcolorswatch.h b/indra/newview/llcolorswatch.h
index 5bdd1712d2..5bdd1712d2 100644..100755
--- a/indra/newview/llcolorswatch.h
+++ b/indra/newview/llcolorswatch.h
diff --git a/indra/newview/llcommanddispatcherlistener.cpp b/indra/newview/llcommanddispatcherlistener.cpp
index 586f45fd8f..586f45fd8f 100644..100755
--- a/indra/newview/llcommanddispatcherlistener.cpp
+++ b/indra/newview/llcommanddispatcherlistener.cpp
diff --git a/indra/newview/llcommanddispatcherlistener.h b/indra/newview/llcommanddispatcherlistener.h
index 024cc1a18d..024cc1a18d 100644..100755
--- a/indra/newview/llcommanddispatcherlistener.h
+++ b/indra/newview/llcommanddispatcherlistener.h
diff --git a/indra/newview/llcommandhandler.h b/indra/newview/llcommandhandler.h
index 1e0895565a..1e0895565a 100644..100755
--- a/indra/newview/llcommandhandler.h
+++ b/indra/newview/llcommandhandler.h
diff --git a/indra/newview/llcommandlineparser.cpp b/indra/newview/llcommandlineparser.cpp
index 65c61c4a8b..a6384ded12 100644..100755
--- a/indra/newview/llcommandlineparser.cpp
+++ b/indra/newview/llcommandlineparser.cpp
@@ -38,16 +38,23 @@
#endif
#include <boost/program_options.hpp>
+#include <boost/lexical_cast.hpp>
#include <boost/bind.hpp>
-#include<boost/tokenizer.hpp>
+#include <boost/tokenizer.hpp>
+#include <boost/assign/list_of.hpp>
#if _MSC_VER
# pragma warning(pop)
#endif
#include "llsdserialize.h"
+#include "llerror.h"
+#include "stringize.h"
+#include <string>
+#include <set>
#include <iostream>
#include <sstream>
+#include <typeinfo>
#include "llcontrol.h"
@@ -63,10 +70,22 @@ namespace po = boost::program_options;
// This could be good or bad, and probably won't matter for most use cases.
namespace
{
+ // List of command-line switches that can't map-to settings variables.
+ // Going forward, we want every new command-line switch to map-to some
+ // settings variable. This list is used to validate that.
+ const std::set<std::string> unmapped_options = boost::assign::list_of
+ ("help")
+ ("set")
+ ("setdefault")
+ ("settings")
+ ("sessionsettings")
+ ("usersessionsettings")
+ ;
+
po::options_description gOptionsDesc;
po::positional_options_description gPositionalOptions;
po::variables_map gVariableMap;
-
+
const LLCommandLineParser::token_vector_t gEmptyValue;
void read_file_into_string(std::string& str, const std::basic_istream < char >& file)
@@ -342,6 +361,15 @@ bool LLCommandLineParser::parseCommandLine(int argc, char **argv)
return parseAndStoreResults(clp);
}
+// TODO:
+// - Break out this funky parsing logic into separate method
+// - Unit-test it with tests like LLStringUtil::getTokens() (the command-line
+// overload that supports quoted tokens)
+// - Unless this logic offers significant semantic benefits, replace it with
+// LLStringUtil::getTokens(). This would fix a known bug: you cannot --set a
+// string-valued variable to the empty string, because empty strings are
+// eliminated below.
+
bool LLCommandLineParser::parseCommandLineString(const std::string& str)
{
// Split the string content into tokens
@@ -375,9 +403,19 @@ bool LLCommandLineParser::parseCommandLineFile(const std::basic_istream < char >
return parseCommandLineString(args);
}
-void LLCommandLineParser::notify()
+bool LLCommandLineParser::notify()
{
- po::notify(gVariableMap);
+ try
+ {
+ po::notify(gVariableMap);
+ return true;
+ }
+ catch (const LLCLPError& e)
+ {
+ llwarns << "Caught Error: " << e.what() << llendl;
+ mErrorMsg = e.what();
+ return false;
+ }
}
void LLCommandLineParser::printOptions() const
@@ -419,43 +457,129 @@ const LLCommandLineParser::token_vector_t& LLCommandLineParser::getOption(const
//----------------------------------------------------------------------------
// LLControlGroupCLP defintions
//----------------------------------------------------------------------------
+namespace {
+LLCommandLineParser::token_vector_t::value_type
+onevalue(const std::string& option,
+ const LLCommandLineParser::token_vector_t& value)
+{
+ if (value.empty())
+ {
+ // What does it mean when the user specifies a command-line switch
+ // that requires a value, but omits the value? Complain.
+ throw LLCLPError(STRINGIZE("No value specified for --" << option << "!"));
+ }
+ else if (value.size() > 1)
+ {
+ llwarns << "Ignoring extra tokens specified for --"
+ << option << "." << llendl;
+ }
+ return value[0];
+}
+
+void badvalue(const std::string& option,
+ const std::string& varname,
+ const std::string& type,
+ const std::string& value)
+{
+ // If the user passes an unusable value for a command-line switch, it
+ // seems like a really bad idea to just ignore it, even with a log
+ // warning.
+ throw LLCLPError(STRINGIZE("Invalid value specified by command-line switch '" << option
+ << "' for variable '" << varname << "' of type " << type
+ << ": '" << value << "'"));
+}
+
+template <typename T>
+T convertTo(const std::string& option,
+ const std::string& varname,
+ const LLCommandLineParser::token_vector_t::value_type& value)
+{
+ try
+ {
+ return boost::lexical_cast<T>(value);
+ }
+ catch (const boost::bad_lexical_cast&)
+ {
+ badvalue(option, varname, typeid(T).name(), value);
+ // bogus return; compiler unaware that badvalue() won't return
+ return T();
+ }
+}
+
void setControlValueCB(const LLCommandLineParser::token_vector_t& value,
- const std::string& opt_name,
- LLControlGroup* ctrlGroup)
+ const std::string& option,
+ LLControlVariable* ctrl)
{
- // *FIX: Do sematic conversion here.
+ // *FIX: Do semantic conversion here.
// LLSD (ImplString) Is no good for doing string to type conversion for...
// booleans
// compound types
// ?...
- LLControlVariable* ctrl = ctrlGroup->getControl(opt_name);
if(NULL != ctrl)
{
switch(ctrl->type())
{
case TYPE_BOOLEAN:
- if(value.size() > 1)
+ if (value.empty())
{
- llwarns << "Ignoring extra tokens." << llendl;
+ // Boolean-valued command-line switches are unusual. If you
+ // simply specify the switch without an explicit value, we can
+ // infer you mean 'true'.
+ ctrl->setValue(LLSD(true), false);
}
-
- if(value.size() > 0)
+ else
{
+ // Only call onevalue() AFTER handling value.empty() case!
+ std::string token(onevalue(option, value));
+
// There's a token. check the string for true/false/1/0 etc.
BOOL result = false;
- BOOL gotSet = LLStringUtil::convertToBOOL(value[0], result);
- if(gotSet)
+ BOOL gotSet = LLStringUtil::convertToBOOL(token, result);
+ if (gotSet)
{
ctrl->setValue(LLSD(result), false);
}
+ else
+ {
+ badvalue(option, ctrl->getName(), "bool", token);
+ }
+ }
+ break;
+
+ case TYPE_U32:
+ {
+ std::string token(onevalue(option, value));
+ // To my surprise, for an unsigned target, lexical_cast() doesn't
+ // complain about an input string such as "-17". In that case, you
+ // get a very large positive result. So for U32, make sure there's
+ // no minus sign!
+ if (token.find('-') == std::string::npos)
+ {
+ ctrl->setValue(LLSD::Integer(convertTo<U32>(option, ctrl->getName(), token)),
+ false);
}
else
{
- ctrl->setValue(LLSD(true), false);
+ badvalue(option, ctrl->getName(), "unsigned", token);
}
break;
+ }
+ case TYPE_S32:
+ ctrl->setValue(convertTo<S32>(option, ctrl->getName(),
+ onevalue(option, value)), false);
+ break;
+
+ case TYPE_F32:
+ ctrl->setValue(convertTo<F32>(option, ctrl->getName(),
+ onevalue(option, value)), false);
+ break;
+
+ // It appears that no one has yet tried to define a command-line
+ // switch mapped to a settings variable of TYPE_VEC3, TYPE_VEC3D,
+ // TYPE_RECT, TYPE_COL4, TYPE_COL3. Such types would certainly seem to
+ // call for a bit of special handling here...
default:
{
// For the default types, let llsd do the conversion.
@@ -472,16 +596,9 @@ void setControlValueCB(const LLCommandLineParser::token_vector_t& value,
ctrl->setValue(llsdArray, false);
}
- else if(value.size() > 0)
+ else
{
- if(value.size() > 1)
- {
- llwarns << "Ignoring extra tokens mapped to the setting: " << opt_name << "." << llendl;
- }
-
- LLSD llsdValue;
- llsdValue.assign(LLSD::String(value[0]));
- ctrl->setValue(llsdValue, false);
+ ctrl->setValue(onevalue(option, value), false);
}
}
break;
@@ -489,12 +606,14 @@ void setControlValueCB(const LLCommandLineParser::token_vector_t& value,
}
else
{
- llwarns << "Command Line option mapping '"
- << opt_name
- << "' not found! Ignoring."
- << llendl;
+ // This isn't anything a user can affect -- it's a misconfiguration on
+ // the part of the coder. Rub the coder's nose in the problem right
+ // away so even preliminary testing will surface it.
+ llerrs << "Command Line option --" << option
+ << " maps to unknown setting!" << llendl;
}
}
+} // anonymous namespace
void LLControlGroupCLP::configure(const std::string& config_filename, LLControlGroup* controlGroup)
{
@@ -552,11 +671,37 @@ void LLControlGroupCLP::configure(const std::string& config_filename, LLControlG
}
boost::function1<void, const token_vector_t&> callback;
- if(option_params.has("map-to") && (NULL != controlGroup))
+ if (! option_params.has("map-to"))
+ {
+ // If this option isn't mapped to a settings variable, is it
+ // one of the ones for which that's unreasonable, or did
+ // someone carelessly add a new option? (Make all these
+ // configuration errors fatal so a maintainer will catch them
+ // right away.)
+ std::set<std::string>::const_iterator found = unmapped_options.find(long_name);
+ if (found == unmapped_options.end())
+ {
+ llerrs << "New command-line option " << long_name
+ << " should map-to a variable in settings.xml" << llendl;
+ }
+ }
+ else // option specifies map-to
{
std::string controlName = option_params["map-to"].asString();
- callback = boost::bind(setControlValueCB, _1,
- controlName, controlGroup);
+ if (! controlGroup)
+ {
+ llerrs << "Must pass gSavedSettings to LLControlGroupCLP::configure() for "
+ << long_name << " (map-to " << controlName << ")" << llendl;
+ }
+
+ LLControlVariable* ctrl = controlGroup->getControl(controlName);
+ if (! ctrl)
+ {
+ llerrs << "Option " << long_name << " specifies map-to " << controlName
+ << " which does not exist" << llendl;
+ }
+
+ callback = boost::bind(setControlValueCB, _1, long_name, ctrl);
}
this->addOptionDesc(
diff --git a/indra/newview/llcommandlineparser.h b/indra/newview/llcommandlineparser.h
index 44f2a26843..71388b8217 100644..100755
--- a/indra/newview/llcommandlineparser.h
+++ b/indra/newview/llcommandlineparser.h
@@ -86,7 +86,7 @@ public:
*
* Use this to handle the results of parsing.
*/
- void notify();
+ bool notify();
/** @brief Print a description of the configured options.
*
diff --git a/indra/newview/llcommunicationchannel.cpp b/indra/newview/llcommunicationchannel.cpp
new file mode 100755
index 0000000000..0821510645
--- /dev/null
+++ b/indra/newview/llcommunicationchannel.cpp
@@ -0,0 +1,113 @@
+/**
+* @file llcommunicationchannel.cpp
+* @brief Implementation of llcommunicationchannel
+* @author Stinson@lindenlab.com
+*
+* $LicenseInfo:firstyear=2012&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2012, 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" // must be first include
+
+#include "llcommunicationchannel.h"
+
+#include <string>
+#include <map>
+
+#include "llagent.h"
+#include "lldate.h"
+#include "llnotifications.h"
+
+
+LLCommunicationChannel::LLCommunicationChannel(const std::string& pName, const std::string& pParentName)
+ : LLNotificationChannel(pName, pParentName, filterByDoNotDisturbStatus)
+ , mHistory()
+{
+}
+
+LLCommunicationChannel::~LLCommunicationChannel()
+{
+}
+
+bool LLCommunicationChannel::filterByDoNotDisturbStatus(LLNotificationPtr)
+{
+ return !gAgent.isDoNotDisturb();
+}
+
+S32 LLCommunicationChannel::getHistorySize() const
+{
+ return mHistory.size();
+}
+
+LLCommunicationChannel::history_list_t::const_iterator LLCommunicationChannel::beginHistory() const
+{
+ return mHistory.begin();
+}
+
+LLCommunicationChannel::history_list_t::const_iterator LLCommunicationChannel::endHistory() const
+{
+ return mHistory.end();
+}
+
+LLCommunicationChannel::history_list_t::iterator LLCommunicationChannel::beginHistory()
+{
+ return mHistory.begin();
+}
+
+LLCommunicationChannel::history_list_t::iterator LLCommunicationChannel::endHistory()
+{
+ return mHistory.end();
+}
+
+void LLCommunicationChannel::clearHistory()
+{
+ mHistory.clear();
+}
+
+void LLCommunicationChannel::removeItemFromHistory(LLNotificationPtr p)
+{
+ //Find the notification and removes it from mHistory
+ for(history_list_t::iterator it = beginHistory(); it != endHistory(); ++it)
+ {
+ if(it->second == p)
+ {
+ mHistory.erase(it);
+ break;
+ }
+ }
+}
+
+void LLCommunicationChannel::onDelete(LLNotificationPtr p)
+{
+ removeItemFromHistory(p);
+}
+
+void LLCommunicationChannel::onFilterFail(LLNotificationPtr pNotificationPtr)
+{
+ std::string notificationType = pNotificationPtr->getType();
+ if ((notificationType == "groupnotify")
+ || (notificationType == "offer")
+ || (notificationType == "notifytoast")
+ && !pNotificationPtr->isCancelled())
+ {
+ mHistory.insert(std::make_pair<LLDate, LLNotificationPtr>(pNotificationPtr->getDate(), pNotificationPtr));
+ }
+}
diff --git a/indra/newview/llcommunicationchannel.h b/indra/newview/llcommunicationchannel.h
new file mode 100755
index 0000000000..0d8f7f4387
--- /dev/null
+++ b/indra/newview/llcommunicationchannel.h
@@ -0,0 +1,66 @@
+/**
+* @file llcommunicationchannel.h
+* @brief Header file for llcommunicationchannel
+* @author Stinson@lindenlab.com
+*
+* $LicenseInfo:firstyear=2012&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2012, 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_LLCOMMUNICATIONCHANNEL_H
+#define LL_LLCOMMUNICATIONCHANNEL_H
+
+#include <string>
+#include <map>
+
+#include "lldate.h"
+#include "llerror.h"
+#include "llnotifications.h"
+
+class LLCommunicationChannel : public LLNotificationChannel
+{
+ LOG_CLASS(LLCommunicationChannel);
+public:
+ LLCommunicationChannel(const std::string& pName, const std::string& pParentName);
+ virtual ~LLCommunicationChannel();
+
+ static bool filterByDoNotDisturbStatus(LLNotificationPtr);
+
+ typedef std::multimap<LLDate, LLNotificationPtr> history_list_t;
+ S32 getHistorySize() const;
+ history_list_t::const_iterator beginHistory() const;
+ history_list_t::const_iterator endHistory() const;
+ history_list_t::iterator beginHistory();
+ history_list_t::iterator endHistory();
+
+ void clearHistory();
+ void removeItemFromHistory(LLNotificationPtr p);
+
+protected:
+ virtual void onDelete(LLNotificationPtr p);
+ virtual void onFilterFail(LLNotificationPtr pNotificationPtr);
+
+private:
+
+ history_list_t mHistory;
+};
+
+#endif // LL_LLCOMMUNICATIONCHANNEL_H
+
diff --git a/indra/newview/llcompilequeue.cpp b/indra/newview/llcompilequeue.cpp
index 4f5f9e22b6..4588424474 100644..100755
--- a/indra/newview/llcompilequeue.cpp
+++ b/indra/newview/llcompilequeue.cpp
@@ -161,18 +161,6 @@ BOOL LLFloaterScriptQueue::start()
{
std::string buffer;
- LLSelectMgr *mgr = LLSelectMgr::getInstance();
- LLObjectSelectionHandle selectHandle = mgr->getSelection();
- U32 n_objects = 0;
- if (gSavedSettings.getBOOL("EditLinkedParts"))
- {
- n_objects = selectHandle->getObjectCount();
- }
- else
- {
- n_objects = selectHandle->getRootObjectCount();
- }
-
LLStringUtil::format_map_t args;
args["[START]"] = mStartString;
args["[COUNT]"] = llformat ("%d", mObjectIDs.count());
diff --git a/indra/newview/llcompilequeue.h b/indra/newview/llcompilequeue.h
index 4ddab29d00..4ddab29d00 100644..100755
--- a/indra/newview/llcompilequeue.h
+++ b/indra/newview/llcompilequeue.h
diff --git a/indra/newview/llconfirmationmanager.cpp b/indra/newview/llconfirmationmanager.cpp
index 8ea59fdd83..8ea59fdd83 100644..100755
--- a/indra/newview/llconfirmationmanager.cpp
+++ b/indra/newview/llconfirmationmanager.cpp
diff --git a/indra/newview/llconfirmationmanager.h b/indra/newview/llconfirmationmanager.h
index d791a8b41a..d791a8b41a 100644..100755
--- a/indra/newview/llconfirmationmanager.h
+++ b/indra/newview/llconfirmationmanager.h
diff --git a/indra/newview/llconversationlog.cpp b/indra/newview/llconversationlog.cpp
new file mode 100755
index 0000000000..7883e4cb89
--- /dev/null
+++ b/indra/newview/llconversationlog.cpp
@@ -0,0 +1,615 @@
+/**
+ * @file llconversationlog.h
+ *
+ * $LicenseInfo:firstyear=2002&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 "llagent.h"
+#include "llavatarnamecache.h"
+#include "llconversationlog.h"
+#include "lldiriterator.h"
+#include "llnotificationsutil.h"
+#include "lltrans.h"
+
+#include <boost/foreach.hpp>
+#include "boost/lexical_cast.hpp"
+
+const int CONVERSATION_LIFETIME = 30; // lifetime of LLConversation is 30 days by spec
+
+struct ConversationParams
+{
+ ConversationParams(time_t time)
+ : mTime(time),
+ mTimestamp(LLConversation::createTimestamp(time))
+ {}
+
+ time_t mTime;
+ std::string mTimestamp;
+ SessionType mConversationType;
+ std::string mConversationName;
+ std::string mHistoryFileName;
+ LLUUID mSessionID;
+ LLUUID mParticipantID;
+ bool mHasOfflineIMs;
+};
+
+/************************************************************************/
+/* LLConversation implementation */
+/************************************************************************/
+
+LLConversation::LLConversation(const ConversationParams& params)
+: mTime(params.mTime),
+ mTimestamp(params.mTimestamp),
+ mConversationType(params.mConversationType),
+ mConversationName(params.mConversationName),
+ mHistoryFileName(params.mHistoryFileName),
+ mSessionID(params.mSessionID),
+ mParticipantID(params.mParticipantID),
+ mHasOfflineIMs(params.mHasOfflineIMs)
+{
+ setListenIMFloaterOpened();
+}
+
+LLConversation::LLConversation(const LLIMModel::LLIMSession& session)
+: mTime(time_corrected()),
+ mTimestamp(createTimestamp(mTime)),
+ mConversationType(session.mSessionType),
+ mConversationName(session.mName),
+ mHistoryFileName(session.mHistoryFileName),
+ mSessionID(session.isOutgoingAdHoc() ? session.generateOutgouigAdHocHash() : session.mSessionID),
+ mParticipantID(session.mOtherParticipantID),
+ mHasOfflineIMs(session.mHasOfflineMessage)
+{
+ setListenIMFloaterOpened();
+}
+
+LLConversation::LLConversation(const LLConversation& conversation)
+{
+ mTime = conversation.getTime();
+ mTimestamp = conversation.getTimestamp();
+ mConversationType = conversation.getConversationType();
+ mConversationName = conversation.getConversationName();
+ mHistoryFileName = conversation.getHistoryFileName();
+ mSessionID = conversation.getSessionID();
+ mParticipantID = conversation.getParticipantID();
+ mHasOfflineIMs = conversation.hasOfflineMessages();
+
+ setListenIMFloaterOpened();
+}
+
+LLConversation::~LLConversation()
+{
+ mIMFloaterShowedConnection.disconnect();
+}
+
+void LLConversation::updateTimestamp()
+{
+ mTime = time_corrected();
+ mTimestamp = createTimestamp(mTime);
+}
+
+void LLConversation::onIMFloaterShown(const LLUUID& session_id)
+{
+ if (mSessionID == session_id)
+ {
+ mHasOfflineIMs = false;
+ }
+}
+
+// static
+const std::string LLConversation::createTimestamp(const time_t& utc_time)
+{
+ std::string timeStr;
+ LLSD substitution;
+ substitution["datetime"] = (S32) utc_time;
+
+ timeStr = "["+LLTrans::getString ("TimeMonth")+"]/["
+ +LLTrans::getString ("TimeDay")+"]/["
+ +LLTrans::getString ("TimeYear")+"] ["
+ +LLTrans::getString ("TimeHour")+"]:["
+ +LLTrans::getString ("TimeMin")+"]";
+
+
+ LLStringUtil::format (timeStr, substitution);
+ return timeStr;
+}
+
+bool LLConversation::isOlderThan(U32 days) const
+{
+ time_t now = time_corrected();
+ U32 age = (U32)((now - mTime) / SEC_PER_DAY); // age of conversation in days
+
+ return age > days;
+}
+
+void LLConversation::setListenIMFloaterOpened()
+{
+ LLFloaterIMSession* floater = LLFloaterIMSession::findInstance(mSessionID);
+
+ bool offline_ims_visible = LLFloaterIMSession::isVisible(floater) && floater->hasFocus();
+
+ // we don't need to listen for im floater with this conversation is opened
+ // if floater is already opened or this conversation doesn't have unread offline messages
+ if (mHasOfflineIMs && !offline_ims_visible)
+ {
+ mIMFloaterShowedConnection = LLFloaterIMSession::setIMFloaterShowedCallback(boost::bind(&LLConversation::onIMFloaterShown, this, _1));
+ }
+ else
+ {
+ mHasOfflineIMs = false;
+ }
+}
+
+/************************************************************************/
+/* LLConversationLogFriendObserver implementation */
+/************************************************************************/
+
+// Note : An LLSingleton like LLConversationLog cannot be an LLFriendObserver
+// at the same time.
+// This is because avatar observers are deleted by the observed object which
+// conflicts with the way LLSingleton are deleted.
+
+class LLConversationLogFriendObserver : public LLFriendObserver
+{
+public:
+ LLConversationLogFriendObserver() {}
+ virtual ~LLConversationLogFriendObserver() {}
+ virtual void changed(U32 mask);
+};
+
+void LLConversationLogFriendObserver::changed(U32 mask)
+{
+ if (mask & (LLFriendObserver::ADD | LLFriendObserver::REMOVE))
+ {
+ LLConversationLog::instance().notifyObservers();
+ }
+}
+
+/************************************************************************/
+/* LLConversationLog implementation */
+/************************************************************************/
+
+LLConversationLog::LLConversationLog() :
+ mAvatarNameCacheConnection(),
+ mLoggingEnabled(false)
+{
+ if(gSavedPerAccountSettings.controlExists("KeepConversationLogTranscripts"))
+ {
+ LLControlVariable * keep_log_ctrlp = gSavedPerAccountSettings.getControl("KeepConversationLogTranscripts").get();
+ S32 log_mode = keep_log_ctrlp->getValue();
+ keep_log_ctrlp->getSignal()->connect(boost::bind(&LLConversationLog::enableLogging, this, _2));
+ if (log_mode > 0)
+ {
+ loadFromFile(getFileName());
+
+ enableLogging(log_mode);
+ }
+ }
+}
+
+void LLConversationLog::enableLogging(S32 log_mode)
+{
+ mLoggingEnabled = log_mode > 0;
+ if (log_mode > 0)
+ {
+ mConversations.clear();
+ loadFromFile(getFileName());
+ LLIMMgr::instance().addSessionObserver(this);
+ mNewMessageSignalConnection = LLIMModel::instance().addNewMsgCallback(boost::bind(&LLConversationLog::onNewMessageReceived, this, _1));
+
+ mFriendObserver = new LLConversationLogFriendObserver;
+ LLAvatarTracker::instance().addObserver(mFriendObserver);
+ }
+ else
+ {
+ saveToFile(getFileName());
+
+ LLIMMgr::instance().removeSessionObserver(this);
+ mNewMessageSignalConnection.disconnect();
+ LLAvatarTracker::instance().removeObserver(mFriendObserver);
+ }
+
+ notifyObservers();
+}
+
+void LLConversationLog::logConversation(const LLUUID& session_id, BOOL has_offline_msg)
+{
+ const LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(session_id);
+ LLConversation* conversation = findConversation(session);
+
+ if (session && session->mOtherParticipantID != gAgentID)
+ {
+ if (conversation)
+ {
+ if(has_offline_msg)
+ {
+ updateOfflineIMs(session, has_offline_msg);
+ }
+ updateConversationTimestamp(conversation);
+ }
+ else
+ {
+ createConversation(session);
+ }
+ }
+}
+
+void LLConversationLog::createConversation(const LLIMModel::LLIMSession* session)
+{
+ if (session)
+ {
+ LLConversation conversation(*session);
+ mConversations.push_back(conversation);
+
+ if (LLIMModel::LLIMSession::P2P_SESSION == session->mSessionType)
+ {
+ if (mAvatarNameCacheConnection.connected())
+ {
+ mAvatarNameCacheConnection.disconnect();
+ }
+ mAvatarNameCacheConnection = LLAvatarNameCache::get(session->mOtherParticipantID, boost::bind(&LLConversationLog::onAvatarNameCache, this, _1, _2, session));
+ }
+
+ notifyObservers();
+ }
+}
+
+void LLConversationLog::updateConversationName(const LLIMModel::LLIMSession* session, const std::string& name)
+{
+ if (!session)
+ {
+ return;
+ }
+
+ LLConversation* conversation = findConversation(session);
+ if (conversation)
+ {
+ conversation->setConversationName(name);
+ notifyParticularConversationObservers(conversation->getSessionID(), LLConversationLogObserver::CHANGED_NAME);
+ }
+}
+
+void LLConversationLog::updateOfflineIMs(const LLIMModel::LLIMSession* session, BOOL new_messages)
+{
+ if (!session)
+ {
+ return;
+ }
+
+ LLConversation* conversation = findConversation(session);
+ if (conversation)
+ {
+ conversation->setOfflineMessages(new_messages);
+ notifyParticularConversationObservers(conversation->getSessionID(), LLConversationLogObserver::CHANGED_OfflineIMs);
+ }
+}
+
+void LLConversationLog::updateConversationTimestamp(LLConversation* conversation)
+{
+ if (conversation)
+ {
+ conversation->updateTimestamp();
+ notifyParticularConversationObservers(conversation->getSessionID(), LLConversationLogObserver::CHANGED_TIME);
+ }
+}
+
+LLConversation* LLConversationLog::findConversation(const LLIMModel::LLIMSession* session)
+{
+ if (session)
+ {
+ const LLUUID session_id = session->isOutgoingAdHoc() ? session->generateOutgouigAdHocHash() : session->mSessionID;
+
+ conversations_vec_t::iterator conv_it = mConversations.begin();
+ for(; conv_it != mConversations.end(); ++conv_it)
+ {
+ if (conv_it->getSessionID() == session_id)
+ {
+ return &*conv_it;
+ }
+ }
+ }
+
+ return NULL;
+}
+
+void LLConversationLog::removeConversation(const LLConversation& conversation)
+{
+ conversations_vec_t::iterator conv_it = mConversations.begin();
+ for(; conv_it != mConversations.end(); ++conv_it)
+ {
+ if (conv_it->getSessionID() == conversation.getSessionID() && conv_it->getTime() == conversation.getTime())
+ {
+ mConversations.erase(conv_it);
+ notifyObservers();
+ cache();
+ return;
+ }
+ }
+}
+
+const LLConversation* LLConversationLog::getConversation(const LLUUID& session_id)
+{
+ conversations_vec_t::const_iterator conv_it = mConversations.begin();
+ for(; conv_it != mConversations.end(); ++conv_it)
+ {
+ if (conv_it->getSessionID() == session_id)
+ {
+ return &*conv_it;
+ }
+ }
+
+ return NULL;
+}
+
+void LLConversationLog::addObserver(LLConversationLogObserver* observer)
+{
+ mObservers.insert(observer);
+}
+
+void LLConversationLog::removeObserver(LLConversationLogObserver* observer)
+{
+ mObservers.erase(observer);
+}
+
+void LLConversationLog::sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id, BOOL has_offline_msg)
+{
+ logConversation(session_id, has_offline_msg);
+}
+
+void LLConversationLog::cache()
+{
+ if (gSavedPerAccountSettings.getS32("KeepConversationLogTranscripts") > 0)
+ {
+ saveToFile(getFileName());
+ }
+}
+
+void LLConversationLog::getListOfBackupLogs(std::vector<std::string>& list_of_backup_logs)
+{
+ // get Users log directory
+ std::string dirname = gDirUtilp->getPerAccountChatLogsDir();
+
+ // add final OS dependent delimiter
+ dirname += gDirUtilp->getDirDelimiter();
+
+ // create search pattern
+ std::string pattern = "conversation.log.backup*";
+
+ LLDirIterator iter(dirname, pattern);
+ std::string filename;
+ while (iter.next(filename))
+ {
+ list_of_backup_logs.push_back(gDirUtilp->add(dirname, filename));
+ }
+}
+
+void LLConversationLog::deleteBackupLogs()
+{
+ std::vector<std::string> backup_logs;
+ getListOfBackupLogs(backup_logs);
+
+ BOOST_FOREACH(const std::string& fullpath, backup_logs)
+ {
+ LLFile::remove(fullpath);
+ }
+}
+
+bool LLConversationLog::moveLog(const std::string &originDirectory, const std::string &targetDirectory)
+{
+
+ std::string backupFileName;
+ unsigned backupFileCount = 0;
+
+ //Does the file exist in the current path, if it does lets move it
+ if(LLFile::isfile(originDirectory))
+ {
+ //The target directory contains that file already, so lets store it
+ if(LLFile::isfile(targetDirectory))
+ {
+ backupFileName = targetDirectory + ".backup";
+
+ //If needed store backup file as .backup1 etc.
+ while(LLFile::isfile(backupFileName))
+ {
+ ++backupFileCount;
+ backupFileName = targetDirectory + ".backup" + boost::lexical_cast<std::string>(backupFileCount);
+ }
+
+ //Rename the file to its backup name so it is not overwritten
+ LLFile::rename(targetDirectory, backupFileName);
+ }
+
+ //Move the file from the current path to target path
+ if(LLFile::rename(originDirectory, targetDirectory) != 0)
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+std::string LLConversationLog::getFileName()
+{
+ std::string filename = "conversation";
+ return gDirUtilp->getExpandedFilename(LL_PATH_PER_ACCOUNT_CHAT_LOGS, filename) + ".log";
+}
+
+bool LLConversationLog::saveToFile(const std::string& filename)
+{
+ if (!filename.size())
+ {
+ llwarns << "Call log list filename is empty!" << llendl;
+ return false;
+ }
+
+ LLFILE* fp = LLFile::fopen(filename, "wb");
+ if (!fp)
+ {
+ llwarns << "Couldn't open call log list" << filename << llendl;
+ return false;
+ }
+
+ std::string participant_id;
+ std::string conversation_id;
+
+ conversations_vec_t::const_iterator conv_it = mConversations.begin();
+ for (; conv_it != mConversations.end(); ++conv_it)
+ {
+ conv_it->getSessionID().toString(conversation_id);
+ conv_it->getParticipantID().toString(participant_id);
+
+ // examples of two file entries
+ // [1343221177] 0 1 0 John Doe| 7e4ec5be-783f-49f5-71dz-16c58c64c145 4ec62a74-c246-0d25-2af6-846beac2aa55 john.doe|
+ // [1343222639] 2 0 0 Ad-hoc Conference| c3g67c89-c479-4c97-b21d-32869bcfe8rc 68f1c33e-4135-3e3e-a897-8c9b23115c09 Ad-hoc Conference hash597394a0-9982-766d-27b8-c75560213b9a|
+
+ fprintf(fp, "[%lld] %d %d %d %s| %s %s %s|\n",
+ (S64)conv_it->getTime(),
+ (S32)conv_it->getConversationType(),
+ (S32)0,
+ (S32)conv_it->hasOfflineMessages(),
+ conv_it->getConversationName().c_str(),
+ participant_id.c_str(),
+ conversation_id.c_str(),
+ conv_it->getHistoryFileName().c_str());
+ }
+ fclose(fp);
+ return true;
+}
+bool LLConversationLog::loadFromFile(const std::string& filename)
+{
+ if(!filename.size())
+ {
+ llwarns << "Call log list filename is empty!" << llendl;
+ return false;
+ }
+
+ LLFILE* fp = LLFile::fopen(filename, "rb");
+ if (!fp)
+ {
+ llwarns << "Couldn't open call log list" << filename << llendl;
+ return false;
+ }
+
+ char buffer[MAX_STRING];
+ char conv_name_buffer[MAX_STRING];
+ char part_id_buffer[MAX_STRING];
+ char conv_id_buffer[MAX_STRING];
+ char history_file_name[MAX_STRING];
+ S32 has_offline_ims;
+ S32 stype;
+ S64 time;
+ // before CHUI-348 it was a flag of conversation voice state
+ int prereserved_unused;
+
+ while (!feof(fp) && fgets(buffer, MAX_STRING, fp))
+ {
+ conv_name_buffer[0] = '\0';
+ part_id_buffer[0] = '\0';
+ conv_id_buffer[0] = '\0';
+
+ sscanf(buffer, "[%lld] %d %d %d %[^|]| %s %s %[^|]|",
+ &time,
+ &stype,
+ &prereserved_unused,
+ &has_offline_ims,
+ conv_name_buffer,
+ part_id_buffer,
+ conv_id_buffer,
+ history_file_name);
+
+ ConversationParams params((time_t)time);
+ params.mConversationType = (SessionType)stype;
+ params.mHasOfflineIMs = has_offline_ims;
+ params.mConversationName = std::string(conv_name_buffer);
+ params.mParticipantID = LLUUID(part_id_buffer);
+ params.mSessionID = LLUUID(conv_id_buffer);
+ params.mHistoryFileName = std::string(history_file_name);
+
+ LLConversation conversation(params);
+
+ // CHUI-325
+ // The conversation log should be capped to the last 30 days. Conversations with the last utterance
+ // being over 30 days old should be purged from the conversation log text file on login.
+ if (conversation.isOlderThan(CONVERSATION_LIFETIME))
+ {
+ continue;
+ }
+
+ mConversations.push_back(conversation);
+ }
+ fclose(fp);
+
+ LLFile::remove(filename);
+ cache();
+
+ notifyObservers();
+ return true;
+}
+
+void LLConversationLog::notifyObservers()
+{
+ std::set<LLConversationLogObserver*>::const_iterator iter = mObservers.begin();
+ for (; iter != mObservers.end(); ++iter)
+ {
+ (*iter)->changed();
+ }
+}
+
+void LLConversationLog::notifyParticularConversationObservers(const LLUUID& session_id, U32 mask)
+{
+ std::set<LLConversationLogObserver*>::const_iterator iter = mObservers.begin();
+ for (; iter != mObservers.end(); ++iter)
+ {
+ (*iter)->changed(session_id, mask);
+ }
+}
+
+void LLConversationLog::onNewMessageReceived(const LLSD& data)
+{
+ const LLUUID session_id = data["session_id"].asUUID();
+ logConversation(session_id, false);
+}
+
+void LLConversationLog::onAvatarNameCache(const LLUUID& participant_id, const LLAvatarName& av_name, const LLIMModel::LLIMSession* session)
+{
+ mAvatarNameCacheConnection.disconnect();
+ updateConversationName(session, av_name.getCompleteName());
+}
+
+void LLConversationLog::onClearLog()
+{
+ LLNotificationsUtil::add("PreferenceChatClearLog", LLSD(), LLSD(), boost::bind(&LLConversationLog::onClearLogResponse, this, _1, _2));
+}
+
+void LLConversationLog::onClearLogResponse(const LLSD& notification, const LLSD& response)
+{
+ if (0 == LLNotificationsUtil::getSelectedOption(notification, response))
+ {
+ mConversations.clear();
+ notifyObservers();
+ cache();
+ deleteBackupLogs();
+ }
+}
diff --git a/indra/newview/llconversationlog.h b/indra/newview/llconversationlog.h
new file mode 100755
index 0000000000..265b1f0ef0
--- /dev/null
+++ b/indra/newview/llconversationlog.h
@@ -0,0 +1,216 @@
+/**
+ * @file llconversationlog.h
+ *
+ * $LicenseInfo:firstyear=2002&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 LLCONVERSATIONLOG_H_
+#define LLCONVERSATIONLOG_H_
+
+#include "llcallingcard.h"
+#include "llfloaterimsession.h"
+#include "llimview.h"
+
+class LLConversationLogObserver;
+struct ConversationParams;
+
+typedef LLIMModel::LLIMSession::SType SessionType;
+
+/*
+ * This class represents a particular session(conversation) of any type(im/voice/p2p/group/...) by storing some of session's data.
+ * Each LLConversation object has a corresponding visual representation in a form of LLConversationLogListItem.
+ */
+class LLConversation
+{
+public:
+
+ LLConversation(const ConversationParams& params);
+ LLConversation(const LLIMModel::LLIMSession& session);
+ LLConversation(const LLConversation& conversation);
+
+ ~LLConversation();
+
+ const SessionType& getConversationType() const { return mConversationType; }
+ const std::string& getConversationName() const { return mConversationName; }
+ const std::string& getHistoryFileName() const { return mHistoryFileName; }
+ const LLUUID& getSessionID() const { return mSessionID; }
+ const LLUUID& getParticipantID() const { return mParticipantID; }
+ const std::string& getTimestamp() const { return mTimestamp; }
+ const time_t& getTime() const { return mTime; }
+ bool hasOfflineMessages() const { return mHasOfflineIMs; }
+
+ void setConversationName(std::string conv_name) { mConversationName = conv_name; }
+ void setOfflineMessages(bool new_messages) { mHasOfflineIMs = new_messages; }
+ bool isOlderThan(U32 days) const;
+
+ /*
+ * updates last interaction time
+ */
+ void updateTimestamp();
+
+ /*
+ * Resets flag of unread offline message to false when im floater with this conversation is opened.
+ */
+ void onIMFloaterShown(const LLUUID& session_id);
+
+ /*
+ * returns string representation(in form of: mm/dd/yyyy hh:mm) of time when conversation was started
+ */
+ static const std::string createTimestamp(const time_t& utc_time);
+
+private:
+
+ /*
+ * If conversation has unread offline messages sets callback for opening LLFloaterIMSession
+ * with this conversation.
+ */
+ void setListenIMFloaterOpened();
+
+ boost::signals2::connection mIMFloaterShowedConnection;
+
+ time_t mTime; // last interaction time
+ SessionType mConversationType;
+ std::string mConversationName;
+ std::string mHistoryFileName;
+ LLUUID mSessionID;
+ LLUUID mParticipantID;
+ bool mHasOfflineIMs;
+ std::string mTimestamp; // last interaction time in form of: mm/dd/yyyy hh:mm
+};
+
+/**
+ * LLConversationLog stores all agent's conversations.
+ * This class is responsible for creating and storing LLConversation objects when im or voice session starts.
+ * Also this class saves/retrieves conversations to/from file.
+ *
+ * Also please note that it may be several conversations with the same sessionID stored in the conversation log.
+ * To distinguish two conversations with the same sessionID it's also needed to compare their creation date.
+ */
+
+class LLConversationLog : public LLSingleton<LLConversationLog>, LLIMSessionObserver
+{
+ friend class LLSingleton<LLConversationLog>;
+public:
+
+ void removeConversation(const LLConversation& conversation);
+
+ /**
+ * Returns first conversation with matched session_id
+ */
+ const LLConversation* getConversation(const LLUUID& session_id);
+ const std::vector<LLConversation>& getConversations() { return mConversations; }
+
+ void addObserver(LLConversationLogObserver* observer);
+ void removeObserver(LLConversationLogObserver* observer);
+
+ // LLIMSessionObserver triggers
+ virtual void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id, BOOL has_offline_msg);
+ virtual void sessionActivated(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id) {}; // Stub
+ virtual void sessionRemoved(const LLUUID& session_id){} // Stub
+ virtual void sessionVoiceOrIMStarted(const LLUUID& session_id){}; // Stub
+ virtual void sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id){}; // Stub
+
+ void notifyObservers();
+
+ void onNewMessageReceived(const LLSD& data);
+
+ /**
+ * public method which is called on viewer exit to save conversation log
+ */
+ void cache();
+ bool moveLog(const std::string &originDirectory, const std::string &targetDirectory);
+ void getListOfBackupLogs(std::vector<std::string>& list_of_backup_logs);
+ void deleteBackupLogs();
+
+ void onClearLog();
+ void onClearLogResponse(const LLSD& notification, const LLSD& response);
+
+ bool getIsLoggingEnabled() { return mLoggingEnabled; }
+ bool isLogEmpty() { return mConversations.empty(); }
+
+ /**
+ * constructs file name in which conversations log will be saved
+ * file name is conversation.log
+ */
+ std::string getFileName();
+
+private:
+
+ LLConversationLog();
+ virtual ~LLConversationLog()
+ {
+ if (mAvatarNameCacheConnection.connected())
+ {
+ mAvatarNameCacheConnection.disconnect();
+ }
+ }
+
+ void enableLogging(S32 log_mode);
+
+ /**
+ * adds conversation to the conversation list and notifies observers
+ */
+ void logConversation(const LLUUID& session_id, BOOL has_offline_msg);
+
+ void notifyParticularConversationObservers(const LLUUID& session_id, U32 mask);
+
+ bool saveToFile(const std::string& filename);
+ bool loadFromFile(const std::string& filename);
+
+ void onAvatarNameCache(const LLUUID& participant_id, const LLAvatarName& av_name, const LLIMModel::LLIMSession* session);
+
+ void createConversation(const LLIMModel::LLIMSession* session);
+ void updateConversationTimestamp(LLConversation* conversation);
+ void updateConversationName(const LLIMModel::LLIMSession* session, const std::string& name);
+ void updateOfflineIMs(const LLIMModel::LLIMSession* session, BOOL new_messages);
+
+ LLConversation* findConversation(const LLIMModel::LLIMSession* session);
+
+ typedef std::vector<LLConversation> conversations_vec_t;
+ std::vector<LLConversation> mConversations;
+ std::set<LLConversationLogObserver*> mObservers;
+
+ LLFriendObserver* mFriendObserver; // Observer of the LLAvatarTracker instance
+
+ boost::signals2::connection mNewMessageSignalConnection;
+ boost::signals2::connection mAvatarNameCacheConnection;
+
+ bool mLoggingEnabled;
+};
+
+class LLConversationLogObserver
+{
+public:
+
+ enum EConversationChange
+ {
+ CHANGED_TIME = 1, // last interaction time changed
+ CHANGED_NAME = 2, // conversation name changed
+ CHANGED_OfflineIMs = 3
+ };
+
+ virtual ~LLConversationLogObserver(){}
+ virtual void changed() = 0;
+ virtual void changed(const LLUUID& session_id, U32 mask){};
+};
+
+#endif /* LLCONVERSATIONLOG_H_ */
diff --git a/indra/newview/llconversationloglist.cpp b/indra/newview/llconversationloglist.cpp
new file mode 100755
index 0000000000..44212298cf
--- /dev/null
+++ b/indra/newview/llconversationloglist.cpp
@@ -0,0 +1,537 @@
+/**
+ * @file llconversationloglist.cpp
+ *
+ * $LicenseInfo:firstyear=2002&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 "llavataractions.h"
+#include "llagent.h"
+#include "llfloaterreg.h"
+#include "llfloaterconversationpreview.h"
+#include "llgroupactions.h"
+#include "llconversationloglist.h"
+#include "llconversationloglistitem.h"
+#include "llviewermenu.h"
+#include "lltrans.h"
+
+static LLDefaultChildRegistry::Register<LLConversationLogList> r("conversation_log_list");
+
+static LLConversationLogListNameComparator NAME_COMPARATOR;
+static LLConversationLogListDateComparator DATE_COMPARATOR;
+
+LLConversationLogList::LLConversationLogList(const Params& p)
+: LLFlatListViewEx(p),
+ mIsDirty(true)
+{
+ LLConversationLog::instance().addObserver(this);
+
+ // Set up context menu.
+ LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
+ LLUICtrl::EnableCallbackRegistry::ScopedRegistrar check_registrar;
+ LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
+
+ registrar.add ("Calllog.Action", boost::bind(&LLConversationLogList::onCustomAction, this, _2));
+ check_registrar.add ("Calllog.Check", boost::bind(&LLConversationLogList::isActionChecked,this, _2));
+ enable_registrar.add("Calllog.Enable", boost::bind(&LLConversationLogList::isActionEnabled,this, _2));
+
+ LLToggleableMenu* context_menu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>(
+ "menu_conversation_log_gear.xml",
+ gMenuHolder,
+ LLViewerMenuHolderGL::child_registry_t::instance());
+ if(context_menu)
+ {
+ mContextMenu = context_menu->getHandle();
+ }
+
+ mIsFriendsOnTop = gSavedSettings.getBOOL("SortFriendsFirst");
+}
+
+LLConversationLogList::~LLConversationLogList()
+{
+ if (mContextMenu.get())
+ {
+ mContextMenu.get()->die();
+ }
+
+ LLConversationLog::instance().removeObserver(this);
+}
+
+void LLConversationLogList::draw()
+{
+ if (mIsDirty)
+ {
+ refresh();
+ }
+ LLFlatListViewEx::draw();
+}
+
+BOOL LLConversationLogList::handleRightMouseDown(S32 x, S32 y, MASK mask)
+{
+ BOOL handled = LLUICtrl::handleRightMouseDown(x, y, mask);
+
+ LLToggleableMenu* context_menu = mContextMenu.get();
+ {
+ context_menu->buildDrawLabels();
+ if (context_menu && size())
+ context_menu->updateParent(LLMenuGL::sMenuContainer);
+ LLMenuGL::showPopup(this, context_menu, x, y);
+ }
+
+ return handled;
+}
+
+void LLConversationLogList::setNameFilter(const std::string& filter)
+{
+ std::string filter_upper = filter;
+ LLStringUtil::toUpper(filter_upper);
+ if (mNameFilter != filter_upper)
+ {
+ mNameFilter = filter_upper;
+ setDirty();
+ }
+}
+
+bool LLConversationLogList::findInsensitive(std::string haystack, const std::string& needle_upper)
+{
+ LLStringUtil::toUpper(haystack);
+ return haystack.find(needle_upper) != std::string::npos;
+}
+
+void LLConversationLogList::sortByName()
+{
+ setComparator(&NAME_COMPARATOR);
+ sort();
+}
+
+void LLConversationLogList::sortByDate()
+{
+ setComparator(&DATE_COMPARATOR);
+ sort();
+}
+
+void LLConversationLogList::toggleSortFriendsOnTop()
+{
+ mIsFriendsOnTop = !mIsFriendsOnTop;
+ gSavedSettings.setBOOL("SortFriendsFirst", mIsFriendsOnTop);
+ sort();
+}
+
+void LLConversationLogList::changed()
+{
+ refresh();
+}
+
+void LLConversationLogList::changed(const LLUUID& session_id, U32 mask)
+{
+ LLConversationLogListItem* item = getConversationLogListItem(session_id);
+
+ if (!item)
+ {
+ return;
+ }
+
+ if (mask & LLConversationLogObserver::CHANGED_TIME)
+ {
+ item->updateTimestamp();
+
+ // if list is sorted by date and a date of some item has changed,
+ // than the whole list should be rebuilt
+ if (E_SORT_BY_DATE == getSortOrder())
+ {
+ mIsDirty = true;
+ }
+ }
+ else if (mask & LLConversationLogObserver::CHANGED_NAME)
+ {
+ item->updateName();
+ // if list is sorted by name and a name of some item has changed,
+ // than the whole list should be rebuilt
+ if (E_SORT_BY_DATE == getSortOrder())
+ {
+ mIsDirty = true;
+ }
+ }
+ else if (mask & LLConversationLogObserver::CHANGED_OfflineIMs)
+ {
+ item->updateOfflineIMs();
+ }
+}
+
+void LLConversationLogList::addNewItem(const LLConversation* conversation)
+{
+ LLConversationLogListItem* item = new LLConversationLogListItem(&*conversation);
+ if (!mNameFilter.empty())
+ {
+ item->highlightNameDate(mNameFilter);
+ }
+ addItem(item, conversation->getSessionID(), ADD_TOP);
+}
+
+void LLConversationLogList::refresh()
+{
+ rebuildList();
+ sort();
+
+ mIsDirty = false;
+}
+
+void LLConversationLogList::rebuildList()
+{
+ const LLConversation * selected_conversationp = getSelectedConversation();
+
+ clear();
+
+ bool have_filter = !mNameFilter.empty();
+ LLConversationLog &log_instance = LLConversationLog::instance();
+
+ const std::vector<LLConversation>& conversations = log_instance.getConversations();
+ std::vector<LLConversation>::const_iterator iter = conversations.begin();
+
+ for (; iter != conversations.end(); ++iter)
+ {
+ bool not_found = have_filter && !findInsensitive(iter->getConversationName(), mNameFilter) && !findInsensitive(iter->getTimestamp(), mNameFilter);
+ if (not_found)
+ continue;
+
+ addNewItem(&*iter);
+ }
+
+ // try to restore selection of item
+ if (NULL != selected_conversationp)
+ {
+ selectItemByUUID(selected_conversationp->getSessionID());
+ }
+
+ bool logging_enabled = log_instance.getIsLoggingEnabled();
+ bool log_empty = log_instance.isLogEmpty();
+ if (!logging_enabled && log_empty)
+ {
+ setNoItemsCommentText(LLTrans::getString("logging_calls_disabled_log_empty"));
+ }
+ else if (!logging_enabled && !log_empty)
+ {
+ setNoItemsCommentText(LLTrans::getString("logging_calls_disabled_log_not_empty"));
+ }
+ else if (logging_enabled && log_empty)
+ {
+ setNoItemsCommentText(LLTrans::getString("logging_calls_enabled_log_empty"));
+ }
+ else if (logging_enabled && !log_empty)
+ {
+ setNoItemsCommentText("");
+ }
+}
+
+void LLConversationLogList::onCustomAction(const LLSD& userdata)
+{
+ const LLConversation * selected_conversationp = getSelectedConversation();
+
+ if (NULL == selected_conversationp)
+ {
+ return;
+ }
+
+ const std::string command_name = userdata.asString();
+ const LLUUID& selected_conversation_participant_id = selected_conversationp->getParticipantID();
+ const LLUUID& selected_conversation_session_id = selected_conversationp->getSessionID();
+ LLIMModel::LLIMSession::SType stype = getSelectedSessionType();
+
+ if ("im" == command_name)
+ {
+ switch (stype)
+ {
+ case LLIMModel::LLIMSession::P2P_SESSION:
+ LLAvatarActions::startIM(selected_conversation_participant_id);
+ break;
+
+ case LLIMModel::LLIMSession::GROUP_SESSION:
+ LLGroupActions::startIM(selected_conversation_session_id);
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if ("call" == command_name)
+ {
+ switch (stype)
+ {
+ case LLIMModel::LLIMSession::P2P_SESSION:
+ LLAvatarActions::startCall(selected_conversation_participant_id);
+ break;
+
+ case LLIMModel::LLIMSession::GROUP_SESSION:
+ LLGroupActions::startCall(selected_conversation_session_id);
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if ("view_profile" == command_name)
+ {
+ switch (stype)
+ {
+ case LLIMModel::LLIMSession::P2P_SESSION:
+ LLAvatarActions::showProfile(selected_conversation_participant_id);
+ break;
+
+ case LLIMModel::LLIMSession::GROUP_SESSION:
+ LLGroupActions::show(selected_conversation_session_id);
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if ("chat_history" == command_name)
+ {
+ LLFloaterReg::showInstance("preview_conversation", selected_conversation_session_id, true);
+ }
+ else if ("offer_teleport" == command_name)
+ {
+ LLAvatarActions::offerTeleport(selected_conversation_participant_id);
+ }
+ else if ("request_teleport" == command_name)
+ {
+ LLAvatarActions::teleportRequest(selected_conversation_participant_id);
+ }
+ else if("add_friend" == command_name)
+ {
+ if (!LLAvatarActions::isFriend(selected_conversation_participant_id))
+ {
+ LLAvatarActions::requestFriendshipDialog(selected_conversation_participant_id);
+ }
+ }
+ else if("remove_friend" == command_name)
+ {
+ if (LLAvatarActions::isFriend(selected_conversation_participant_id))
+ {
+ LLAvatarActions::removeFriendDialog(selected_conversation_participant_id);
+ }
+ }
+ else if ("invite_to_group" == command_name)
+ {
+ LLAvatarActions::inviteToGroup(selected_conversation_participant_id);
+ }
+ else if ("show_on_map" == command_name)
+ {
+ LLAvatarActions::showOnMap(selected_conversation_participant_id);
+ }
+ else if ("share" == command_name)
+ {
+ LLAvatarActions::share(selected_conversation_participant_id);
+ }
+ else if ("pay" == command_name)
+ {
+ LLAvatarActions::pay(selected_conversation_participant_id);
+ }
+ else if ("block" == command_name)
+ {
+ LLAvatarActions::toggleBlock(selected_conversation_participant_id);
+ }
+}
+
+bool LLConversationLogList::isActionEnabled(const LLSD& userdata)
+{
+ const LLConversation * selected_conversationp = getSelectedConversation();
+
+ if (NULL == selected_conversationp || numSelected() > 1)
+ {
+ return false;
+ }
+
+ const std::string command_name = userdata.asString();
+
+ LLIMModel::LLIMSession::SType stype = getSelectedSessionType();
+ const LLUUID& selected_id = selected_conversationp->getParticipantID();
+
+ bool is_p2p = LLIMModel::LLIMSession::P2P_SESSION == stype;
+ bool is_group = LLIMModel::LLIMSession::GROUP_SESSION == stype;
+
+ if ("can_im" == command_name || "can_view_profile" == command_name)
+ {
+ return is_p2p || is_group;
+ }
+ else if ("can_view_chat_history" == command_name)
+ {
+ return true;
+ }
+ else if ("can_call" == command_name)
+ {
+ return (is_p2p || is_group) && LLAvatarActions::canCall();
+ }
+ else if ("add_rem_friend" == command_name ||
+ "can_invite_to_group" == command_name ||
+ "can_share" == command_name ||
+ "can_block" == command_name ||
+ "can_pay" == command_name)
+ {
+ return is_p2p;
+ }
+ else if("can_offer_teleport" == command_name)
+ {
+ return is_p2p && LLAvatarActions::canOfferTeleport(selected_id);
+ }
+ else if ("can_show_on_map" == command_name)
+ {
+ return is_p2p && ((LLAvatarTracker::instance().isBuddyOnline(selected_id) && is_agent_mappable(selected_id)) || gAgent.isGodlike());
+ }
+
+ return false;
+}
+
+bool LLConversationLogList::isActionChecked(const LLSD& userdata)
+{
+ const LLConversation * selected_conversationp = getSelectedConversation();
+
+ if (NULL == selected_conversationp)
+ {
+ return false;
+ }
+
+ const std::string command_name = userdata.asString();
+
+ const LLUUID& selected_id = selected_conversationp->getParticipantID();
+ bool is_p2p = LLIMModel::LLIMSession::P2P_SESSION == getSelectedSessionType();
+
+ if ("is_blocked" == command_name)
+ {
+ return is_p2p && LLAvatarActions::isBlocked(selected_id);
+ }
+ else if ("is_friend" == command_name)
+ {
+ return is_p2p && LLAvatarActions::isFriend(selected_id);
+ }
+ else if ("is_not_friend" == command_name)
+ {
+ return is_p2p && !LLAvatarActions::isFriend(selected_id);
+ }
+
+ return false;
+}
+
+LLIMModel::LLIMSession::SType LLConversationLogList::getSelectedSessionType()
+{
+ const LLConversationLogListItem* item = getSelectedConversationPanel();
+
+ if (item)
+ {
+ return item->getConversation()->getConversationType();
+ }
+
+ return LLIMModel::LLIMSession::NONE_SESSION;
+}
+
+const LLConversationLogListItem* LLConversationLogList::getSelectedConversationPanel()
+{
+ LLPanel* panel = LLFlatListViewEx::getSelectedItem();
+ LLConversationLogListItem* conv_panel = dynamic_cast<LLConversationLogListItem*>(panel);
+
+ return conv_panel;
+}
+
+const LLConversation* LLConversationLogList::getSelectedConversation()
+{
+ const LLConversationLogListItem* panel = getSelectedConversationPanel();
+
+ if (panel)
+ {
+ return panel->getConversation();
+ }
+
+ return NULL;
+}
+
+LLConversationLogListItem* LLConversationLogList::getConversationLogListItem(const LLUUID& session_id)
+{
+ std::vector<LLPanel*> panels;
+ LLFlatListViewEx::getItems(panels);
+ std::vector<LLPanel*>::iterator iter = panels.begin();
+
+ for (; iter != panels.end(); ++iter)
+ {
+ LLConversationLogListItem* item = dynamic_cast<LLConversationLogListItem*>(*iter);
+ if (item && session_id == item->getConversation()->getSessionID())
+ {
+ return item;
+ }
+ }
+
+ return NULL;
+}
+
+LLConversationLogList::ESortOrder LLConversationLogList::getSortOrder()
+{
+ return static_cast<ESortOrder>(gSavedSettings.getU32("CallLogSortOrder"));
+}
+
+bool LLConversationLogListItemComparator::compare(const LLPanel* item1, const LLPanel* item2) const
+{
+ const LLConversationLogListItem* conversation_item1 = dynamic_cast<const LLConversationLogListItem*>(item1);
+ const LLConversationLogListItem* conversation_item2 = dynamic_cast<const LLConversationLogListItem*>(item2);
+
+ if (!conversation_item1 || !conversation_item2)
+ {
+ llerror("conversation_item1 and conversation_item2 cannot be null", 0);
+ return true;
+ }
+
+ return doCompare(conversation_item1, conversation_item2);
+}
+
+bool LLConversationLogListNameComparator::doCompare(const LLConversationLogListItem* conversation1, const LLConversationLogListItem* conversation2) const
+{
+ std::string name1 = conversation1->getConversation()->getConversationName();
+ std::string name2 = conversation2->getConversation()->getConversationName();
+ const LLUUID& id1 = conversation1->getConversation()->getParticipantID();
+ const LLUUID& id2 = conversation2->getConversation()->getParticipantID();
+
+ LLStringUtil::toUpper(name1);
+ LLStringUtil::toUpper(name2);
+
+ bool friends_first = gSavedSettings.getBOOL("SortFriendsFirst");
+ if (friends_first && (LLAvatarActions::isFriend(id1) ^ LLAvatarActions::isFriend(id2)))
+ {
+ return LLAvatarActions::isFriend(id1);
+ }
+
+ return name1 < name2;
+}
+
+bool LLConversationLogListDateComparator::doCompare(const LLConversationLogListItem* conversation1, const LLConversationLogListItem* conversation2) const
+{
+ time_t date1 = conversation1->getConversation()->getTime();
+ time_t date2 = conversation2->getConversation()->getTime();
+ const LLUUID& id1 = conversation1->getConversation()->getParticipantID();
+ const LLUUID& id2 = conversation2->getConversation()->getParticipantID();
+
+ bool friends_first = gSavedSettings.getBOOL("SortFriendsFirst");
+ if (friends_first && (LLAvatarActions::isFriend(id1) ^ LLAvatarActions::isFriend(id2)))
+ {
+ return LLAvatarActions::isFriend(id1);
+ }
+
+ return date1 > date2;
+}
diff --git a/indra/newview/llconversationloglist.h b/indra/newview/llconversationloglist.h
new file mode 100755
index 0000000000..62ec57e09e
--- /dev/null
+++ b/indra/newview/llconversationloglist.h
@@ -0,0 +1,153 @@
+/**
+ * @file llconversationloglist.h
+ *
+ * $LicenseInfo:firstyear=2002&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 LLCONVERSATIONLOGLIST_H_
+#define LLCONVERSATIONLOGLIST_H_
+
+#include "llconversationlog.h"
+#include "llflatlistview.h"
+#include "lltoggleablemenu.h"
+
+class LLConversationLogListItem;
+
+/**
+ * List of all agent's conversations. I.e. history of conversations.
+ * This list represents contents of the LLConversationLog.
+ * Each change in LLConversationLog leads to rebuilding this list, so
+ * it's always in actual state.
+ */
+
+class LLConversationLogList: public LLFlatListViewEx, public LLConversationLogObserver
+{
+ LOG_CLASS(LLConversationLogList);
+public:
+
+ typedef enum e_sort_oder{
+ E_SORT_BY_NAME = 0,
+ E_SORT_BY_DATE = 1,
+ } ESortOrder;
+
+ struct Params : public LLInitParam::Block<Params, LLFlatListViewEx::Params>
+ {
+ Params(){};
+ };
+
+ LLConversationLogList(const Params& p);
+ virtual ~LLConversationLogList();
+
+ virtual void draw();
+
+ virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
+
+ LLToggleableMenu* getContextMenu() const { return mContextMenu.get(); }
+
+ void addNewItem(const LLConversation* conversation);
+ void setNameFilter(const std::string& filter);
+ void sortByName();
+ void sortByDate();
+ void toggleSortFriendsOnTop();
+ bool getSortFriendsOnTop() const { return mIsFriendsOnTop; }
+
+ /**
+ * Changes from LLConversationLogObserver
+ */
+ virtual void changed();
+ virtual void changed(const LLUUID& session_id, U32 mask);
+
+private:
+
+ void setDirty(bool dirty = true) { mIsDirty = dirty; }
+ void refresh();
+
+ /**
+ * Clears list and re-adds items from LLConverstationLog
+ * If filter is not empty re-adds items which match the filter
+ */
+ void rebuildList();
+
+ bool findInsensitive(std::string haystack, const std::string& needle_upper);
+
+ void onCustomAction (const LLSD& userdata);
+ bool isActionEnabled(const LLSD& userdata);
+ bool isActionChecked(const LLSD& userdata);
+
+ LLIMModel::LLIMSession::SType getSelectedSessionType();
+ const LLConversationLogListItem* getSelectedConversationPanel();
+ const LLConversation* getSelectedConversation();
+ LLConversationLogListItem* getConversationLogListItem(const LLUUID& session_id);
+
+ ESortOrder getSortOrder();
+
+ LLHandle<LLToggleableMenu> mContextMenu;
+ bool mIsDirty;
+ bool mIsFriendsOnTop;
+ std::string mNameFilter;
+};
+
+/**
+ * Abstract comparator for ConversationLogList items
+ */
+class LLConversationLogListItemComparator : public LLFlatListView::ItemComparator
+{
+ LOG_CLASS(LLConversationLogListItemComparator);
+
+public:
+ LLConversationLogListItemComparator() {};
+ virtual ~LLConversationLogListItemComparator() {};
+
+ virtual bool compare(const LLPanel* item1, const LLPanel* item2) const;
+
+protected:
+
+ virtual bool doCompare(const LLConversationLogListItem* conversation1, const LLConversationLogListItem* conversation2) const = 0;
+};
+
+class LLConversationLogListNameComparator : public LLConversationLogListItemComparator
+{
+ LOG_CLASS(LLConversationLogListNameComparator);
+
+public:
+ LLConversationLogListNameComparator() {};
+ virtual ~LLConversationLogListNameComparator() {};
+
+protected:
+
+ virtual bool doCompare(const LLConversationLogListItem* conversation1, const LLConversationLogListItem* conversation2) const;
+};
+
+class LLConversationLogListDateComparator : public LLConversationLogListItemComparator
+{
+ LOG_CLASS(LLConversationLogListDateComparator);
+
+public:
+ LLConversationLogListDateComparator() {};
+ virtual ~LLConversationLogListDateComparator() {};
+
+protected:
+
+ virtual bool doCompare(const LLConversationLogListItem* conversation1, const LLConversationLogListItem* conversation2) const;
+};
+
+#endif /* LLCONVERSATIONLOGLIST_H_ */
diff --git a/indra/newview/llconversationloglistitem.cpp b/indra/newview/llconversationloglistitem.cpp
new file mode 100755
index 0000000000..4e984d603b
--- /dev/null
+++ b/indra/newview/llconversationloglistitem.cpp
@@ -0,0 +1,184 @@
+/**
+ * @file llconversationloglistitem.cpp
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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"
+
+// llui
+#include "lliconctrl.h"
+#include "lltextbox.h"
+#include "lltextutil.h"
+
+// newview
+#include "llavataractions.h"
+#include "llavatariconctrl.h"
+#include "llconversationlog.h"
+#include "llconversationloglistitem.h"
+#include "llgroupactions.h"
+#include "llgroupiconctrl.h"
+#include "llinventoryicon.h"
+
+LLConversationLogListItem::LLConversationLogListItem(const LLConversation* conversation)
+: LLPanel(),
+ mConversation(conversation),
+ mConversationName(NULL),
+ mConversationDate(NULL)
+{
+ buildFromFile("panel_conversation_log_list_item.xml");
+
+ LLFloaterIMSession* floater = LLFloaterIMSession::findInstance(mConversation->getSessionID());
+
+ bool ims_are_read = LLFloaterIMSession::isVisible(floater) && floater->hasFocus();
+
+ if (mConversation->hasOfflineMessages() && !ims_are_read)
+ {
+ mIMFloaterShowedConnection = LLFloaterIMSession::setIMFloaterShowedCallback(boost::bind(&LLConversationLogListItem::onIMFloaterShown, this, _1));
+ }
+}
+
+LLConversationLogListItem::~LLConversationLogListItem()
+{
+ mIMFloaterShowedConnection.disconnect();
+}
+
+BOOL LLConversationLogListItem::postBuild()
+{
+ initIcons();
+
+ // set conversation name
+ mConversationName = getChild<LLTextBox>("conversation_name");
+ mConversationName->setValue(mConversation->getConversationName());
+
+ // set conversation date and time
+ mConversationDate = getChild<LLTextBox>("date_time");
+ mConversationDate->setValue(mConversation->getTimestamp());
+
+ getChild<LLButton>("delete_btn")->setClickedCallback(boost::bind(&LLConversationLogListItem::onRemoveBtnClicked, this));
+ setDoubleClickCallback(boost::bind(&LLConversationLogListItem::onDoubleClick, this));
+
+ return TRUE;
+}
+
+void LLConversationLogListItem::initIcons()
+{
+ switch (mConversation->getConversationType())
+ {
+ case LLIMModel::LLIMSession::P2P_SESSION:
+ case LLIMModel::LLIMSession::ADHOC_SESSION:
+ {
+ LLAvatarIconCtrl* avatar_icon = getChild<LLAvatarIconCtrl>("avatar_icon");
+ avatar_icon->setVisible(TRUE);
+ avatar_icon->setValue(mConversation->getParticipantID());
+ break;
+ }
+ case LLIMModel::LLIMSession::GROUP_SESSION:
+ {
+ LLGroupIconCtrl* group_icon = getChild<LLGroupIconCtrl>("group_icon");
+ group_icon->setVisible(TRUE);
+ group_icon->setValue(mConversation->getSessionID());
+ break;
+ }
+ default:
+ break;
+ }
+
+ if (mConversation->hasOfflineMessages())
+ {
+ getChild<LLIconCtrl>("unread_ims_icon")->setVisible(TRUE);
+ }
+}
+
+void LLConversationLogListItem::updateTimestamp()
+{
+ mConversationDate->setValue(mConversation->getTimestamp());
+}
+
+void LLConversationLogListItem::updateName()
+{
+ mConversationName->setValue(mConversation->getConversationName());
+}
+
+void LLConversationLogListItem::updateOfflineIMs()
+{
+ getChild<LLIconCtrl>("unread_ims_icon")->setVisible(mConversation->hasOfflineMessages());
+}
+
+void LLConversationLogListItem::onMouseEnter(S32 x, S32 y, MASK mask)
+{
+ getChildView("hovered_icon")->setVisible(true);
+ LLPanel::onMouseEnter(x, y, mask);
+}
+
+void LLConversationLogListItem::onMouseLeave(S32 x, S32 y, MASK mask)
+{
+ getChildView("hovered_icon")->setVisible(false);
+ LLPanel::onMouseLeave(x, y, mask);
+}
+
+void LLConversationLogListItem::setValue(const LLSD& value)
+{
+ if (!value.isMap() || !value.has("selected"))
+ {
+ return;
+ }
+
+ getChildView("selected_icon")->setVisible(value["selected"]);
+}
+
+void LLConversationLogListItem::onIMFloaterShown(const LLUUID& session_id)
+{
+ if (mConversation->getSessionID() == session_id)
+ {
+ getChild<LLIconCtrl>("unread_ims_icon")->setVisible(FALSE);
+ }
+}
+
+void LLConversationLogListItem::onRemoveBtnClicked()
+{
+ LLConversationLog::instance().removeConversation(*mConversation);
+}
+
+void LLConversationLogListItem::highlightNameDate(const std::string& highlited_text)
+{
+ LLStyle::Params params;
+ LLTextUtil::textboxSetHighlightedVal(mConversationName, params, mConversation->getConversationName(), highlited_text);
+ LLTextUtil::textboxSetHighlightedVal(mConversationDate, params, mConversation->getTimestamp(), highlited_text);
+}
+
+void LLConversationLogListItem::onDoubleClick()
+{
+ switch (mConversation->getConversationType())
+ {
+ case LLIMModel::LLIMSession::P2P_SESSION:
+ LLAvatarActions::startIM(mConversation->getParticipantID());
+ break;
+
+ case LLIMModel::LLIMSession::GROUP_SESSION:
+ LLGroupActions::startIM(mConversation->getSessionID());
+ break;
+
+ default:
+ break;
+ }
+}
diff --git a/indra/newview/llconversationloglistitem.h b/indra/newview/llconversationloglistitem.h
new file mode 100755
index 0000000000..ee28456bbb
--- /dev/null
+++ b/indra/newview/llconversationloglistitem.h
@@ -0,0 +1,86 @@
+/**
+ * @file llconversationloglistitem.h
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 LLCONVERSATIONLOGLISTITEM_H_
+#define LLCONVERSATIONLOGLISTITEM_H_
+
+#include "llfloaterimsession.h"
+#include "llpanel.h"
+
+class LLTextBox;
+class LLConversation;
+
+/**
+ * This class is a visual representation of LLConversation, each of which is LLConversationLog entry.
+ * LLConversationLogList consists of these LLConversationLogListItems.
+ * LLConversationLogListItem consists of:
+ * conversaion_type_icon
+ * conversaion_name
+ * conversaion_date
+ * Also LLConversationLogListItem holds pointer to its LLConversationLog.
+ */
+
+class LLConversationLogListItem : public LLPanel
+{
+public:
+ LLConversationLogListItem(const LLConversation* conversation);
+ virtual ~LLConversationLogListItem();
+
+ void onMouseEnter(S32 x, S32 y, MASK mask);
+ void onMouseLeave(S32 x, S32 y, MASK mask);
+
+ virtual void setValue(const LLSD& value);
+
+ virtual BOOL postBuild();
+
+ void onIMFloaterShown(const LLUUID& session_id);
+ void onRemoveBtnClicked();
+
+ const LLConversation* getConversation() const { return mConversation; }
+
+ void highlightNameDate(const std::string& highlited_text);
+
+ void onDoubleClick();
+
+ /**
+ * updates string value of last interaction time from conversation
+ */
+ void updateTimestamp();
+ void updateName();
+ void updateOfflineIMs();
+
+private:
+
+ void initIcons();
+
+ const LLConversation* mConversation;
+
+ LLTextBox* mConversationName;
+ LLTextBox* mConversationDate;
+
+ boost::signals2::connection mIMFloaterShowedConnection;
+};
+
+#endif /* LLCONVERSATIONLOGITEM_H_ */
diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
new file mode 100755
index 0000000000..affa24f78c
--- /dev/null
+++ b/indra/newview/llconversationmodel.cpp
@@ -0,0 +1,710 @@
+/**
+ * @file llconversationmodel.cpp
+ * @brief Implementation of conversations list
+ *
+ * $LicenseInfo:firstyear=2009&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 "llviewerprecompiledheaders.h"
+
+#include "llagent.h"
+#include "llavatarnamecache.h"
+#include "llavataractions.h"
+#include "llevents.h"
+#include "llfloaterimsession.h"
+#include "llsdutil.h"
+#include "llconversationmodel.h"
+#include "llimview.h" //For LLIMModel
+#include "lltrans.h"
+
+#include <boost/foreach.hpp>
+
+//
+// Conversation items : common behaviors
+//
+
+LLConversationItem::LLConversationItem(std::string display_name, const LLUUID& uuid, LLFolderViewModelInterface& root_view_model) :
+ LLFolderViewModelItemCommon(root_view_model),
+ mName(display_name),
+ mUUID(uuid),
+ mNeedsRefresh(true),
+ mConvType(CONV_UNKNOWN),
+ mLastActiveTime(0.0),
+ mDisplayModeratorOptions(false),
+ mAvatarNameCacheConnection()
+{
+}
+
+LLConversationItem::LLConversationItem(const LLUUID& uuid, LLFolderViewModelInterface& root_view_model) :
+ LLFolderViewModelItemCommon(root_view_model),
+ mName(""),
+ mUUID(uuid),
+ mNeedsRefresh(true),
+ mConvType(CONV_UNKNOWN),
+ mLastActiveTime(0.0),
+ mDisplayModeratorOptions(false),
+ mAvatarNameCacheConnection()
+{
+}
+
+LLConversationItem::LLConversationItem(LLFolderViewModelInterface& root_view_model) :
+ LLFolderViewModelItemCommon(root_view_model),
+ mName(""),
+ mUUID(),
+ mNeedsRefresh(true),
+ mConvType(CONV_UNKNOWN),
+ mLastActiveTime(0.0),
+ mDisplayModeratorOptions(false),
+ mAvatarNameCacheConnection()
+{
+}
+
+LLConversationItem::~LLConversationItem()
+{
+ // Disconnect any previous avatar name cache connection to ensure
+ // that the callback method is not called after destruction
+ if (mAvatarNameCacheConnection.connected())
+ {
+ mAvatarNameCacheConnection.disconnect();
+ }
+}
+
+void LLConversationItem::postEvent(const std::string& event_type, LLConversationItemSession* session, LLConversationItemParticipant* participant)
+{
+ LLUUID session_id = (session ? session->getUUID() : LLUUID());
+ LLUUID participant_id = (participant ? participant->getUUID() : LLUUID());
+ LLSD event(LLSDMap("type", event_type)("session_uuid", session_id)("participant_uuid", participant_id));
+ LLEventPumps::instance().obtain("ConversationsEvents").post(event);
+}
+
+// Virtual action callbacks
+void LLConversationItem::performAction(LLInventoryModel* model, std::string action)
+{
+}
+
+void LLConversationItem::openItem( void )
+{
+}
+
+void LLConversationItem::closeItem( void )
+{
+}
+
+void LLConversationItem::previewItem( void )
+{
+}
+
+void LLConversationItem::showProperties(void)
+{
+}
+
+void LLConversationItem::buildParticipantMenuOptions(menuentry_vec_t& items, U32 flags)
+{
+ if (flags & ITEM_IN_MULTI_SELECTION)
+ {
+ items.push_back(std::string("im"));
+ items.push_back(std::string("offer_teleport"));
+ items.push_back(std::string("voice_call"));
+ items.push_back(std::string("remove_friends"));
+ }
+ else
+ {
+ items.push_back(std::string("view_profile"));
+ items.push_back(std::string("im"));
+ items.push_back(std::string("offer_teleport"));
+ items.push_back(std::string("request_teleport"));
+ items.push_back(std::string("voice_call"));
+ items.push_back(std::string("chat_history"));
+ items.push_back(std::string("separator_chat_history"));
+ items.push_back(std::string("add_friend"));
+ items.push_back(std::string("remove_friend"));
+ items.push_back(std::string("invite_to_group"));
+ items.push_back(std::string("separator_invite_to_group"));
+ if (static_cast<LLConversationItem*>(mParent)->getType() == CONV_SESSION_NEARBY)
+ items.push_back(std::string("zoom_in"));
+ items.push_back(std::string("map"));
+ items.push_back(std::string("share"));
+ items.push_back(std::string("pay"));
+ items.push_back(std::string("block_unblock"));
+ items.push_back(std::string("MuteText"));
+
+ if ((getType() != CONV_SESSION_1_ON_1) && mDisplayModeratorOptions)
+ {
+ items.push_back(std::string("Moderator Options Separator"));
+ items.push_back(std::string("Moderator Options"));
+ items.push_back(std::string("AllowTextChat"));
+ items.push_back(std::string("moderate_voice_separator"));
+ items.push_back(std::string("ModerateVoiceMuteSelected"));
+ items.push_back(std::string("ModerateVoiceUnMuteSelected"));
+ items.push_back(std::string("ModerateVoiceMute"));
+ items.push_back(std::string("ModerateVoiceUnmute"));
+ }
+ }
+}
+
+// method does subscription to changes in avatar name cache for current session/participant conversation item.
+void LLConversationItem::fetchAvatarName(bool isParticipant /*= true*/)
+{
+ LLUUID item_id = getUUID();
+
+ // item should not be null for participants
+ if (isParticipant)
+ {
+ llassert(item_id.notNull());
+ }
+
+ // disconnect any previous avatar name cache connection
+ if (mAvatarNameCacheConnection.connected())
+ {
+ mAvatarNameCacheConnection.disconnect();
+ }
+
+ // exclude nearby chat item
+ if (item_id.notNull())
+ {
+ // for P2P session item, override it as item of called agent
+ if (CONV_SESSION_1_ON_1 == getType())
+ {
+ item_id = LLIMModel::getInstance()->getOtherParticipantID(item_id);
+ }
+
+ // subscribe on avatar name cache changes for participant and session items
+ mAvatarNameCacheConnection = LLAvatarNameCache::get(item_id, boost::bind(&LLConversationItem::onAvatarNameCache, this, _2));
+ }
+}
+
+//
+// LLConversationItemSession
+//
+
+LLConversationItemSession::LLConversationItemSession(std::string display_name, const LLUUID& uuid, LLFolderViewModelInterface& root_view_model) :
+ LLConversationItem(display_name,uuid,root_view_model),
+ mIsLoaded(false)
+{
+ mConvType = CONV_SESSION_UNKNOWN;
+}
+
+LLConversationItemSession::LLConversationItemSession(const LLUUID& uuid, LLFolderViewModelInterface& root_view_model) :
+ LLConversationItem(uuid,root_view_model)
+{
+ mConvType = CONV_SESSION_UNKNOWN;
+}
+
+bool LLConversationItemSession::hasChildren() const
+{
+ return getChildrenCount() > 0;
+}
+
+void LLConversationItemSession::addParticipant(LLConversationItemParticipant* participant)
+{
+ addChild(participant);
+ mIsLoaded = true;
+ mNeedsRefresh = true;
+ updateName(participant);
+ postEvent("add_participant", this, participant);
+}
+
+void LLConversationItemSession::updateName(LLConversationItemParticipant* participant)
+{
+ EConversationType conversation_type = getType();
+ // We modify the session name only in the case of an ad-hoc session or P2P session, exit otherwise (nothing to do)
+ if ((conversation_type != CONV_SESSION_AD_HOC) && (conversation_type != CONV_SESSION_1_ON_1))
+ {
+ return;
+ }
+
+ // Avoid changing the default name if no participant present yet
+ if (mChildren.size() == 0)
+ {
+ return;
+ }
+
+ uuid_vec_t temp_uuids; // uuids vector for building the added participants' names string
+ if (conversation_type == CONV_SESSION_AD_HOC || conversation_type == CONV_SESSION_1_ON_1)
+ {
+ // Build a string containing the participants UUIDs (minus own agent) and check if ready for display (we don't want "(waiting)" in there)
+ // Note: we don't bind ourselves to the LLAvatarNameCache event as updateParticipantName() is called by
+ // onAvatarNameCache() which is itself attached to the same event.
+
+ // In the case of a P2P conversation, we need to grab the name of the other participant in the session instance itself
+ // as we do not create participants for such a session.
+
+ LLFolderViewModelItem * itemp;
+ BOOST_FOREACH(itemp, mChildren)
+ {
+ LLConversationItem* current_participant = dynamic_cast<LLConversationItem*>(itemp);
+ // Add the avatar uuid to the list (except if it's the own agent uuid)
+ if (current_participant->getUUID() != gAgentID)
+ {
+ LLAvatarName av_name;
+ if (LLAvatarNameCache::get(current_participant->getUUID(), &av_name))
+ {
+ temp_uuids.push_back(current_participant->getUUID());
+
+ if (conversation_type == CONV_SESSION_1_ON_1)
+ {
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ if (temp_uuids.size() != 0)
+ {
+ std::string new_session_name;
+ LLAvatarActions::buildResidentsString(temp_uuids, new_session_name);
+ renameItem(new_session_name);
+ postEvent("update_session", this, NULL);
+ }
+}
+
+void LLConversationItemSession::removeParticipant(LLConversationItemParticipant* participant)
+{
+ removeChild(participant);
+ mNeedsRefresh = true;
+ updateName(participant);
+ postEvent("remove_participant", this, participant);
+}
+
+void LLConversationItemSession::removeParticipant(const LLUUID& participant_id)
+{
+ LLConversationItemParticipant* participant = findParticipant(participant_id);
+ if (participant)
+ {
+ removeParticipant(participant);
+ }
+}
+
+void LLConversationItemSession::clearParticipants()
+{
+ clearChildren();
+ mIsLoaded = false;
+ mNeedsRefresh = true;
+}
+
+LLConversationItemParticipant* LLConversationItemSession::findParticipant(const LLUUID& participant_id)
+{
+ // This is *not* a general tree parsing algorithm. It assumes that a session contains only
+ // items (LLConversationItemParticipant) that have themselve no children.
+ LLConversationItemParticipant* participant = NULL;
+ child_list_t::iterator iter;
+ for (iter = mChildren.begin(); iter != mChildren.end(); iter++)
+ {
+ participant = dynamic_cast<LLConversationItemParticipant*>(*iter);
+ if (participant->hasSameValue(participant_id))
+ {
+ break;
+ }
+ }
+ return (iter == mChildren.end() ? NULL : participant);
+}
+
+void LLConversationItemSession::setParticipantIsMuted(const LLUUID& participant_id, bool is_muted)
+{
+ LLConversationItemParticipant* participant = findParticipant(participant_id);
+ if (participant)
+ {
+ participant->muteVoice(is_muted);
+ }
+}
+
+void LLConversationItemSession::setParticipantIsModerator(const LLUUID& participant_id, bool is_moderator)
+{
+ LLConversationItemParticipant* participant = findParticipant(participant_id);
+ if (participant)
+ {
+ participant->setIsModerator(is_moderator);
+ }
+}
+
+void LLConversationItemSession::setTimeNow(const LLUUID& participant_id)
+{
+ mLastActiveTime = LLFrameTimer::getElapsedSeconds();
+ mNeedsRefresh = true;
+ LLConversationItemParticipant* participant = findParticipant(participant_id);
+ if (participant)
+ {
+ participant->setTimeNow();
+ }
+}
+
+void LLConversationItemSession::setDistance(const LLUUID& participant_id, F64 dist)
+{
+ LLConversationItemParticipant* participant = findParticipant(participant_id);
+ if (participant)
+ {
+ participant->setDistance(dist);
+ mNeedsRefresh = true;
+ }
+}
+
+void LLConversationItemSession::buildContextMenu(LLMenuGL& menu, U32 flags)
+{
+ lldebugs << "LLConversationItemParticipant::buildContextMenu()" << llendl;
+ menuentry_vec_t items;
+ menuentry_vec_t disabled_items;
+ if((flags & ITEM_IN_MULTI_SELECTION) && (this->getType() != CONV_SESSION_NEARBY))
+ {
+ items.push_back(std::string("close_selected_conversations"));
+ }
+ if(this->getType() == CONV_SESSION_1_ON_1)
+ {
+ items.push_back(std::string("close_conversation"));
+ items.push_back(std::string("separator_disconnect_from_voice"));
+ buildParticipantMenuOptions(items, flags);
+ }
+ else if(this->getType() == CONV_SESSION_GROUP)
+ {
+ items.push_back(std::string("close_conversation"));
+ addVoiceOptions(items);
+ items.push_back(std::string("chat_history"));
+ items.push_back(std::string("separator_chat_history"));
+ items.push_back(std::string("group_profile"));
+ items.push_back(std::string("activate_group"));
+ items.push_back(std::string("leave_group"));
+ }
+ else if(this->getType() == CONV_SESSION_AD_HOC)
+ {
+ items.push_back(std::string("close_conversation"));
+ addVoiceOptions(items);
+ items.push_back(std::string("chat_history"));
+ }
+ else if(this->getType() == CONV_SESSION_NEARBY)
+ {
+ items.push_back(std::string("chat_history"));
+ }
+
+ hide_context_entries(menu, items, disabled_items);
+}
+
+void LLConversationItemSession::addVoiceOptions(menuentry_vec_t& items)
+{
+ LLVoiceChannel* voice_channel = LLIMModel::getInstance() ? LLIMModel::getInstance()->getVoiceChannel(this->getUUID()) : NULL;
+
+ if(voice_channel != LLVoiceChannel::getCurrentVoiceChannel())
+ {
+ items.push_back(std::string("open_voice_conversation"));
+ }
+ else
+ {
+ items.push_back(std::string("disconnect_from_voice"));
+ }
+}
+
+// The time of activity of a session is the time of the most recent activity, session and participants included
+const bool LLConversationItemSession::getTime(F64& time) const
+{
+ F64 most_recent_time = mLastActiveTime;
+ bool has_time = (most_recent_time > 0.1);
+ LLConversationItemParticipant* participant = NULL;
+ child_list_t::const_iterator iter;
+ for (iter = mChildren.begin(); iter != mChildren.end(); iter++)
+ {
+ participant = dynamic_cast<LLConversationItemParticipant*>(*iter);
+ F64 participant_time;
+ if (participant->getTime(participant_time))
+ {
+ has_time = true;
+ most_recent_time = llmax(most_recent_time,participant_time);
+ }
+ }
+ if (has_time)
+ {
+ time = most_recent_time;
+ }
+ return has_time;
+}
+
+void LLConversationItemSession::dumpDebugData(bool dump_children)
+{
+ // Session info
+ llinfos << "Merov debug : session " << this << ", uuid = " << mUUID << ", name = " << mName << ", is loaded = " << mIsLoaded << llendl;
+ // Children info
+ if (dump_children)
+ {
+ for (child_list_t::iterator iter = mChildren.begin(); iter != mChildren.end(); iter++)
+ {
+ LLConversationItemParticipant* participant = dynamic_cast<LLConversationItemParticipant*>(*iter);
+ if (participant)
+ {
+ participant->dumpDebugData();
+ }
+ }
+ }
+}
+
+// should be invoked only for P2P sessions
+void LLConversationItemSession::onAvatarNameCache(const LLAvatarName& av_name)
+{
+ if (mAvatarNameCacheConnection.connected())
+ {
+ mAvatarNameCacheConnection.disconnect();
+ }
+
+ renameItem(av_name.getDisplayName());
+ postEvent("update_session", this, NULL);
+}
+
+//
+// LLConversationItemParticipant
+//
+
+LLConversationItemParticipant::LLConversationItemParticipant(std::string display_name, const LLUUID& uuid, LLFolderViewModelInterface& root_view_model) :
+ LLConversationItem(display_name,uuid,root_view_model),
+ mIsModerator(false),
+ mDisplayModeratorLabel(false),
+ mDistToAgent(-1.0)
+{
+ mDisplayName = display_name;
+ mConvType = CONV_PARTICIPANT;
+}
+
+LLConversationItemParticipant::LLConversationItemParticipant(const LLUUID& uuid, LLFolderViewModelInterface& root_view_model) :
+ LLConversationItem(uuid,root_view_model),
+ mIsModerator(false),
+ mDisplayModeratorLabel(false),
+ mDistToAgent(-1.0)
+{
+ mConvType = CONV_PARTICIPANT;
+}
+
+void LLConversationItemParticipant::updateName()
+{
+ llassert(getUUID().notNull());
+ if (getUUID().notNull())
+ {
+ LLAvatarName av_name;
+ if (LLAvatarNameCache::get(getUUID(),&av_name))
+ {
+ updateName(av_name);
+ }
+ }
+}
+
+void LLConversationItemParticipant::onAvatarNameCache(const LLAvatarName& av_name)
+{
+ if (mAvatarNameCacheConnection.connected())
+ {
+ mAvatarNameCacheConnection.disconnect();
+ }
+
+ updateName(av_name);
+}
+
+void LLConversationItemParticipant::updateName(const LLAvatarName& av_name)
+{
+ mName = av_name.getUserName();
+ mDisplayName = av_name.getDisplayName();
+
+ if (mDisplayModeratorLabel)
+ {
+ mDisplayName += " " + LLTrans::getString("IM_moderator_label");
+ }
+
+ renameItem(mDisplayName);
+ if (mParent != NULL)
+ {
+ LLConversationItemSession* parent_session = dynamic_cast<LLConversationItemSession*>(mParent);
+ if (parent_session != NULL)
+ {
+ parent_session->requestSort();
+ parent_session->updateName(this);
+ postEvent("update_participant", parent_session, this);
+ }
+ }
+}
+
+void LLConversationItemParticipant::buildContextMenu(LLMenuGL& menu, U32 flags)
+{
+ menuentry_vec_t items;
+ menuentry_vec_t disabled_items;
+
+ buildParticipantMenuOptions(items, flags);
+
+ hide_context_entries(menu, items, disabled_items);
+}
+
+LLConversationItemSession* LLConversationItemParticipant::getParentSession()
+{
+ LLConversationItemSession* parent_session = NULL;
+ if (hasParent())
+ {
+ parent_session = dynamic_cast<LLConversationItemSession*>(mParent);
+ }
+ return parent_session;
+}
+
+void LLConversationItemParticipant::dumpDebugData()
+{
+ llinfos << "Merov debug : participant, uuid = " << mUUID << ", name = " << mName << ", display name = " << mDisplayName << ", muted = " << isVoiceMuted() << ", moderator = " << mIsModerator << llendl;
+}
+
+void LLConversationItemParticipant::setDisplayModeratorRole(bool displayRole)
+{
+ if (displayRole != mDisplayModeratorLabel)
+ {
+ mDisplayModeratorLabel = displayRole;
+ updateName();
+ }
+}
+
+bool LLConversationItemParticipant::isVoiceMuted()
+{
+ return LLMuteList::getInstance()->isMuted(mUUID, LLMute::flagVoiceChat);
+}
+
+void LLConversationItemParticipant::muteVoice(bool mute_voice)
+{
+ std::string name;
+ gCacheName->getFullName(mUUID, name);
+ LLMuteList * mute_listp = LLMuteList::getInstance();
+ bool voice_already_muted = mute_listp->isMuted(mUUID, name);
+
+ LLMute mute(mUUID, name, LLMute::AGENT);
+ if (voice_already_muted && !mute_voice)
+ {
+ mute_listp->remove(mute);
+ }
+ else if (!voice_already_muted && mute_voice)
+ {
+ mute_listp->add(mute);
+ }
+}
+
+//
+// LLConversationSort
+//
+
+// Comparison operator: returns "true" is a comes before b, "false" otherwise
+bool LLConversationSort::operator()(const LLConversationItem* const& a, const LLConversationItem* const& b) const
+{
+ LLConversationItem::EConversationType type_a = a->getType();
+ LLConversationItem::EConversationType type_b = b->getType();
+
+ if ((type_a == LLConversationItem::CONV_PARTICIPANT) && (type_b == LLConversationItem::CONV_PARTICIPANT))
+ {
+ // If both items are participants
+ U32 sort_order = getSortOrderParticipants();
+ if (sort_order == LLConversationFilter::SO_DATE)
+ {
+ F64 time_a = 0.0;
+ F64 time_b = 0.0;
+ bool has_time_a = a->getTime(time_a);
+ bool has_time_b = b->getTime(time_b);
+ if (has_time_a && has_time_b)
+ {
+ // Most recent comes first
+ return (time_a > time_b);
+ }
+ else if (has_time_a || has_time_b)
+ {
+ // If we have only one time available, the element with time must come first
+ return has_time_a;
+ }
+ // If no time available, we'll default to sort by name at the end of this method
+ }
+ else if (sort_order == LLConversationFilter::SO_DISTANCE)
+ {
+ F64 dist_a = 0.0;
+ F64 dist_b = 0.0;
+ bool has_dist_a = a->getDistanceToAgent(dist_a);
+ bool has_dist_b = b->getDistanceToAgent(dist_b);
+ if (has_dist_a && has_dist_b)
+ {
+ // Closest comes first
+ return (dist_a < dist_b);
+ }
+ else if (has_dist_a || has_dist_b)
+ {
+ // If we have only one distance available, the element with it must come first
+ return has_dist_a;
+ }
+ // If no distance available, we'll default to sort by name at the end of this method
+ }
+ }
+ else if ((type_a > LLConversationItem::CONV_PARTICIPANT) && (type_b > LLConversationItem::CONV_PARTICIPANT))
+ {
+ // If both are sessions
+ U32 sort_order = getSortOrderSessions();
+
+ if (sort_order == LLConversationFilter::SO_DATE)
+ {
+ // Sort by time
+ F64 time_a = 0.0;
+ F64 time_b = 0.0;
+ bool has_time_a = a->getTime(time_a);
+ bool has_time_b = b->getTime(time_b);
+ if (has_time_a && has_time_b)
+ {
+ // Most recent comes first
+ return (time_a > time_b);
+ }
+ else if (has_time_a || has_time_b)
+ {
+ // If we have only one time available, the element with time must come first
+ return has_time_a;
+ }
+ // If no time available, we'll default to sort by name at the end of this method
+ }
+ else
+ {
+ if ((type_a == LLConversationItem::CONV_SESSION_NEARBY) || (type_b == LLConversationItem::CONV_SESSION_NEARBY))
+ {
+ // If one is the nearby session, put nearby session *always* last
+ return (type_b == LLConversationItem::CONV_SESSION_NEARBY);
+ }
+ else if (sort_order == LLConversationFilter::SO_SESSION_TYPE)
+ {
+ if (type_a != type_b)
+ {
+ // Lowest types come first. See LLConversationItem definition of types
+ return (type_a < type_b);
+ }
+ // If types are identical, we'll default to sort by name at the end of this method
+ }
+ }
+ }
+ else
+ {
+ // If one item is a participant and the other a session, the session comes before the participant
+ // so we simply compare the type
+ // Notes: as a consequence, CONV_UNKNOWN (which should never get created...) always come first
+ return (type_a > type_b);
+ }
+ // By default, in all other possible cases (including sort order type LLConversationFilter::SO_NAME of course),
+ // we sort by name
+ S32 compare = LLStringUtil::compareDict(a->getName(), b->getName());
+ return (compare < 0);
+}
+
+//
+// LLConversationViewModel
+//
+
+void LLConversationViewModel::sort(LLFolderViewFolder* folder)
+{
+ base_t::sort(folder);
+}
+
+// EOF
diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h
new file mode 100644
index 0000000000..d8cdcdfc97
--- /dev/null
+++ b/indra/newview/llconversationmodel.h
@@ -0,0 +1,313 @@
+/**
+ * @file llconversationmodel.h
+ * @brief Implementation of conversations list
+ *
+ * $LicenseInfo:firstyear=2009&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$
+ */
+
+#ifndef LL_LLCONVERSATIONMODEL_H
+#define LL_LLCONVERSATIONMODEL_H
+
+#include <boost/signals2.hpp>
+
+#include "llavatarname.h"
+#include "../llui/llfolderviewitem.h"
+#include "../llui/llfolderviewmodel.h"
+#include "llviewerfoldertype.h"
+
+// Implementation of conversations list
+
+class LLConversationItem;
+class LLConversationItemSession;
+class LLConversationItemParticipant;
+
+typedef std::map<LLUUID, LLConversationItem*> conversations_items_map;
+typedef std::map<LLUUID, LLFolderViewItem*> conversations_widgets_map;
+
+typedef std::vector<std::string> menuentry_vec_t;
+
+// Conversation items: we hold a list of those and create an LLFolderViewItem widget for each
+// that we tuck into the mConversationsListPanel.
+class LLConversationItem : public LLFolderViewModelItemCommon
+{
+public:
+ enum EConversationType
+ {
+ CONV_UNKNOWN = 0,
+ CONV_PARTICIPANT = 1,
+ CONV_SESSION_NEARBY = 2, // The order counts here as it is used to sort sessions by type
+ CONV_SESSION_1_ON_1 = 3,
+ CONV_SESSION_AD_HOC = 4,
+ CONV_SESSION_GROUP = 5,
+ CONV_SESSION_UNKNOWN = 6
+ };
+
+ LLConversationItem(std::string display_name, const LLUUID& uuid, LLFolderViewModelInterface& root_view_model);
+ LLConversationItem(const LLUUID& uuid, LLFolderViewModelInterface& root_view_model);
+ LLConversationItem(LLFolderViewModelInterface& root_view_model);
+ virtual ~LLConversationItem();
+
+ // Stub those things we won't really be using in this conversation context
+ virtual const std::string& getName() const { return mName; }
+ virtual const std::string& getDisplayName() const { return mName; }
+ virtual const std::string& getSearchableName() const { return mName; }
+ virtual const LLUUID& getUUID() const { return mUUID; }
+ virtual time_t getCreationDate() const { return 0; }
+ virtual LLPointer<LLUIImage> getIcon() const { return NULL; }
+ virtual LLPointer<LLUIImage> getOpenIcon() const { return getIcon(); }
+ virtual LLFontGL::StyleFlags getLabelStyle() const { return LLFontGL::NORMAL; }
+ virtual std::string getLabelSuffix() const { return LLStringUtil::null; }
+ virtual BOOL isItemRenameable() const { return TRUE; }
+ virtual BOOL renameItem(const std::string& new_name) { mName = new_name; mNeedsRefresh = true; return TRUE; }
+ virtual BOOL isItemMovable( void ) const { return FALSE; }
+ virtual BOOL isItemRemovable( void ) const { return FALSE; }
+ virtual BOOL isItemInTrash( void) const { return FALSE; }
+ 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 copyToClipboard() const { return FALSE; }
+ virtual BOOL cutToClipboard() const { return FALSE; }
+ virtual BOOL isClipboardPasteable() const { return FALSE; }
+ virtual void pasteFromClipboard() { }
+ virtual void pasteLinkFromClipboard() { }
+ virtual void buildContextMenu(LLMenuGL& menu, U32 flags) { }
+ virtual BOOL isUpToDate() const { return TRUE; }
+ virtual bool hasChildren() const { return FALSE; }
+
+ virtual bool potentiallyVisible() { return true; }
+ virtual bool filter( LLFolderViewFilter& filter) { return false; }
+ virtual bool descendantsPassedFilter(S32 filter_generation = -1) { return true; }
+ virtual void setPassedFilter(bool passed, S32 filter_generation, std::string::size_type string_offset = std::string::npos, std::string::size_type string_size = 0) { }
+ virtual bool passedFilter(S32 filter_generation = -1) { return true; }
+
+ // The action callbacks
+ virtual void performAction(LLInventoryModel* model, std::string action);
+ virtual void openItem( void );
+ virtual void closeItem( void );
+ virtual void previewItem( void );
+ virtual void selectItem(void) { }
+ virtual void showProperties(void);
+
+ // Methods used in sorting (see LLConversationSort::operator())
+ EConversationType const getType() const { return mConvType; }
+ virtual const bool getTime(F64& time) const { time = mLastActiveTime; return (time > 0.1); }
+ virtual const bool getDistanceToAgent(F64& distance) const { return false; }
+
+ // This method will be called to determine if a drop can be
+ // performed, and will set drop to TRUE if a drop is
+ // requested.
+ // Returns TRUE if a drop is possible/happened, FALSE otherwise.
+ virtual BOOL dragOrDrop(MASK mask, BOOL drop,
+ EDragAndDropType cargo_type,
+ void* cargo_data,
+ std::string& tooltip_msg) { return FALSE; }
+
+// bool hasSameValues(std::string name, const LLUUID& uuid) { return ((name == mName) && (uuid == mUUID)); }
+ bool hasSameValue(const LLUUID& uuid) { return (uuid == mUUID); }
+
+ void resetRefresh() { mNeedsRefresh = false; }
+ bool needsRefresh() { return mNeedsRefresh; }
+
+ void postEvent(const std::string& event_type, LLConversationItemSession* session, LLConversationItemParticipant* participant);
+
+ void buildParticipantMenuOptions(menuentry_vec_t& items, U32 flags);
+
+ void fetchAvatarName(bool isParticipant = true); // fetch and update the avatar name
+
+protected:
+ virtual void onAvatarNameCache(const LLAvatarName& av_name) {}
+
+ std::string mName; // Name of the session or the participant
+ LLUUID mUUID; // UUID of the session or the participant
+ EConversationType mConvType; // Type of conversation item
+ bool mNeedsRefresh; // Flag signaling to the view that something changed for this item
+ F64 mLastActiveTime;
+ bool mDisplayModeratorOptions;
+ boost::signals2::connection mAvatarNameCacheConnection;
+};
+
+class LLConversationItemSession : public LLConversationItem
+{
+public:
+ LLConversationItemSession(std::string display_name, const LLUUID& uuid, LLFolderViewModelInterface& root_view_model);
+ LLConversationItemSession(const LLUUID& uuid, LLFolderViewModelInterface& root_view_model);
+
+ /*virtual*/ bool hasChildren() const;
+ LLPointer<LLUIImage> getIcon() const { return NULL; }
+ void setSessionID(const LLUUID& session_id) { mUUID = session_id; mNeedsRefresh = true; }
+ void addParticipant(LLConversationItemParticipant* participant);
+ void updateName(LLConversationItemParticipant* participant);
+ void removeParticipant(LLConversationItemParticipant* participant);
+ void removeParticipant(const LLUUID& participant_id);
+ void clearParticipants();
+ LLConversationItemParticipant* findParticipant(const LLUUID& participant_id);
+
+ void setParticipantIsMuted(const LLUUID& participant_id, bool is_muted);
+ void setParticipantIsModerator(const LLUUID& participant_id, bool is_moderator);
+ void setTimeNow(const LLUUID& participant_id);
+ void setDistance(const LLUUID& participant_id, F64 dist);
+
+ bool isLoaded() { return mIsLoaded; }
+
+ void buildContextMenu(LLMenuGL& menu, U32 flags);
+ void addVoiceOptions(menuentry_vec_t& items);
+ virtual const bool getTime(F64& time) const;
+
+ void dumpDebugData(bool dump_children = false);
+
+private:
+ /*virtual*/ void onAvatarNameCache(const LLAvatarName& av_name);
+
+ bool mIsLoaded; // true if at least one participant has been added to the session, false otherwise
+};
+
+class LLConversationItemParticipant : public LLConversationItem
+{
+public:
+ LLConversationItemParticipant(std::string display_name, const LLUUID& uuid, LLFolderViewModelInterface& root_view_model);
+ LLConversationItemParticipant(const LLUUID& uuid, LLFolderViewModelInterface& root_view_model);
+
+ virtual const std::string& getDisplayName() const { return mDisplayName; }
+
+ bool isVoiceMuted();
+ bool isModerator() const { return mIsModerator; }
+ void muteVoice(bool mute_voice);
+ void setIsModerator(bool is_moderator) { mIsModerator = is_moderator; mNeedsRefresh = true; }
+ void setTimeNow() { mLastActiveTime = LLFrameTimer::getElapsedSeconds(); mNeedsRefresh = true; }
+ void setDistance(F64 dist) { mDistToAgent = dist; mNeedsRefresh = true; }
+
+ void buildContextMenu(LLMenuGL& menu, U32 flags);
+
+ virtual const bool getDistanceToAgent(F64& dist) const { dist = mDistToAgent; return (dist >= 0.0); }
+
+ void updateName(); // get from the cache (do *not* fetch) and update the avatar name
+ LLConversationItemSession* getParentSession();
+
+ void dumpDebugData();
+ void setModeratorOptionsVisible(bool visible) { mDisplayModeratorOptions = visible; }
+ void setDisplayModeratorRole(bool displayRole);
+
+private:
+ void onAvatarNameCache(const LLAvatarName& av_name); // callback used by fetchAvatarName
+ void updateName(const LLAvatarName& av_name);
+
+ bool mIsMuted; // default is false
+ bool mIsModerator; // default is false
+ bool mDisplayModeratorLabel; // default is false
+ std::string mDisplayName;
+ F64 mDistToAgent; // Distance to the agent. A negative (meaningless) value means the distance has not been set.
+ boost::signals2::connection mAvatarNameCacheConnection;
+};
+
+// We don't want to ever filter conversations but we need to declare that class to create a conversation view model.
+// We just stubb everything for the moment.
+class LLConversationFilter : public LLFolderViewFilter
+{
+public:
+
+ enum ESortOrderType
+ {
+ SO_NAME = 0, // Sort by name
+ SO_DATE = 0x1, // Sort by date (most recent)
+ SO_SESSION_TYPE = 0x2, // Sort by type (valid only for sessions)
+ SO_DISTANCE = 0x3, // Sort by distance (valid only for participants in nearby chat)
+ };
+ // Default sort order is by type for sessions and by date for participants
+ static const U32 SO_DEFAULT = (SO_SESSION_TYPE << 16) | (SO_DATE);
+
+ LLConversationFilter() { mEmpty = ""; }
+ ~LLConversationFilter() {}
+
+ bool check(const LLFolderViewModelItem* item) { return true; }
+ bool checkFolder(const LLFolderViewModelItem* folder) const { return true; }
+ void setEmptyLookupMessage(const std::string& message) { }
+ std::string getEmptyLookupMessage() const { return mEmpty; }
+ bool showAllResults() const { return true; }
+ std::string::size_type getStringMatchOffset(LLFolderViewModelItem* item) const { return std::string::npos; }
+ std::string::size_type getFilterStringSize() const { return 0; }
+
+ bool isActive() const { return false; }
+ bool isModified() const { return false; }
+ void clearModified() { }
+ const std::string& getName() const { return mEmpty; }
+ const std::string& getFilterText() { return mEmpty; }
+ void setModified(EFilterModified behavior = FILTER_RESTART) { }
+
+ void resetTime(S32 timeout) { }
+ bool isTimedOut() { return false; }
+
+ bool isDefault() const { return true; }
+ bool isNotDefault() const { return false; }
+ void markDefault() { }
+ void resetDefault() { }
+
+ S32 getCurrentGeneration() const { return 0; }
+ S32 getFirstSuccessGeneration() const { return 0; }
+ S32 getFirstRequiredGeneration() const { return 0; }
+private:
+ std::string mEmpty;
+};
+
+class LLConversationSort
+{
+public:
+ LLConversationSort(U32 order = LLConversationFilter::SO_DEFAULT) : mSortOrder(order) { }
+
+ // 16 LSB bits used for participants, 16 MSB bits for sessions
+ U32 getSortOrderSessions() const { return ((mSortOrder >> 16) & 0xFFFF); }
+ U32 getSortOrderParticipants() const { return (mSortOrder & 0xFFFF); }
+ void setSortOrderSessions(LLConversationFilter::ESortOrderType session) { mSortOrder = ((session & 0xFFFF) << 16) | (mSortOrder & 0xFFFF); }
+ void setSortOrderParticipants(LLConversationFilter::ESortOrderType participant) { mSortOrder = (mSortOrder & 0xFFFF0000) | (participant & 0xFFFF); }
+
+ bool operator()(const LLConversationItem* const& a, const LLConversationItem* const& b) const;
+ operator U32() const { return mSortOrder; }
+private:
+ // Note: we're treating this value as a sort order bitmask as done in other places in the code (e.g. inventory)
+ U32 mSortOrder;
+};
+
+class LLConversationViewModel
+: public LLFolderViewModel<LLConversationSort, LLConversationItem, LLConversationItem, LLConversationFilter>
+{
+public:
+ typedef LLFolderViewModel<LLConversationSort, LLConversationItem, LLConversationItem, LLConversationFilter> base_t;
+
+ void sort(LLFolderViewFolder* folder);
+ bool contentsReady() { return true; } // *TODO : we need to check that participants names are available somewhat
+ bool startDrag(std::vector<LLFolderViewModelItem*>& items) { return false; } // We do not allow drag of conversation items
+
+private:
+};
+
+// Utility function to hide all entries except those in the list
+// Can be called multiple times on the same menu (e.g. if multiple items
+// are selected). If "append" is false, then only common enabled items
+// are set as enabled.
+
+//(defined in inventorybridge.cpp)
+//TODO: Gilbert Linden - Refactor to make this function non-global
+void hide_context_entries(LLMenuGL& menu,
+ const menuentry_vec_t &entries_to_show,
+ const menuentry_vec_t &disabled_entries);
+
+#endif // LL_LLCONVERSATIONMODEL_H
diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
new file mode 100644
index 0000000000..82d3fe74c0
--- /dev/null
+++ b/indra/newview/llconversationview.cpp
@@ -0,0 +1,749 @@
+/**
+ * @file llconversationview.cpp
+ * @brief Implementation of conversations list widgets and views
+ *
+ * $LicenseInfo:firstyear=2009&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 "llviewerprecompiledheaders.h"
+
+#include "llconversationview.h"
+
+#include <boost/bind.hpp>
+#include "llagentdata.h"
+#include "llconversationmodel.h"
+#include "llfloaterimsession.h"
+#include "llfloaterimnearbychat.h"
+#include "llfloaterimsessiontab.h"
+#include "llfloaterimcontainer.h"
+#include "llfloaterreg.h"
+#include "llgroupiconctrl.h"
+#include "lluictrlfactory.h"
+#include "lltoolbarview.h"
+
+//
+// Implementation of conversations list session widgets
+//
+static LLDefaultChildRegistry::Register<LLConversationViewSession> r_conversation_view_session("conversation_view_session");
+
+const LLColor4U DEFAULT_WHITE(255, 255, 255);
+
+class LLNearbyVoiceClientStatusObserver : public LLVoiceClientStatusObserver
+{
+public:
+
+ LLNearbyVoiceClientStatusObserver(LLConversationViewSession* conv)
+ : conversation(conv)
+ {}
+
+ virtual void onChange(EStatusType status, const std::string &channelURI, bool proximal)
+ {
+ conversation->showVoiceIndicator(conversation
+ && status != STATUS_JOINING
+ && status != STATUS_LEFT_CHANNEL
+ && LLVoiceClient::getInstance()->voiceEnabled()
+ && LLVoiceClient::getInstance()->isVoiceWorking());
+ }
+
+private:
+ LLConversationViewSession* conversation;
+};
+
+LLConversationViewSession::Params::Params() :
+ container()
+{}
+
+LLConversationViewSession::LLConversationViewSession(const LLConversationViewSession::Params& p):
+ LLFolderViewFolder(p),
+ mContainer(p.container),
+ mItemPanel(NULL),
+ mCallIconLayoutPanel(NULL),
+ mSessionTitle(NULL),
+ mSpeakingIndicator(NULL),
+ mVoiceClientObserver(NULL),
+ mCollapsedMode(false),
+ mHasArrow(true),
+ mIsInActiveVoiceChannel(false),
+ mFlashStateOn(false),
+ mFlashStarted(false)
+{
+ mFlashTimer = new LLFlashTimer();
+}
+
+LLConversationViewSession::~LLConversationViewSession()
+{
+ mActiveVoiceChannelConnection.disconnect();
+
+ if(LLVoiceClient::instanceExists() && mVoiceClientObserver)
+ {
+ LLVoiceClient::getInstance()->removeObserver(mVoiceClientObserver);
+ }
+
+ mFlashTimer->unset();
+}
+
+void LLConversationViewSession::setFlashState(bool flash_state)
+{
+ if (flash_state && !mFlashStateOn)
+ {
+ // flash chat toolbar button if scrolled out of sight (because flashing will not be visible)
+ if (mContainer->isScrolledOutOfSight(this))
+ {
+ gToolBarView->flashCommand(LLCommandId("chat"), true);
+ }
+ }
+
+ mFlashStateOn = flash_state;
+ mFlashStarted = false;
+ mFlashTimer->stopFlashing();
+}
+
+void LLConversationViewSession::setHighlightState(bool hihglight_state)
+{
+ mFlashStateOn = hihglight_state;
+ mFlashStarted = true;
+ mFlashTimer->stopFlashing();
+}
+
+void LLConversationViewSession::startFlashing()
+{
+ LLFloaterIMContainer* im_box = LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container");
+
+ // Need to start flashing only when "Conversations" is opened or brought on top
+ if (isInVisibleChain() && !im_box->isMinimized() && mFlashStateOn && !mFlashStarted)
+ {
+ mFlashStarted = true;
+ mFlashTimer->startFlashing();
+ }
+}
+
+bool LLConversationViewSession::isHighlightAllowed()
+{
+ return mFlashStateOn || mIsSelected;
+}
+
+bool LLConversationViewSession::isHighlightActive()
+{
+ return (mFlashStateOn ? (mFlashTimer->isFlashingInProgress() ? mFlashTimer->isCurrentlyHighlighted() : true) : mIsCurSelection);
+}
+
+BOOL LLConversationViewSession::postBuild()
+{
+ LLFolderViewItem::postBuild();
+
+ mItemPanel = LLUICtrlFactory::getInstance()->createFromFile<LLPanel>("panel_conversation_list_item.xml", NULL, LLPanel::child_registry_t::instance());
+ addChild(mItemPanel);
+
+ mCallIconLayoutPanel = mItemPanel->getChild<LLPanel>("call_icon_panel");
+ mSessionTitle = mItemPanel->getChild<LLTextBox>("conversation_title");
+
+ mActiveVoiceChannelConnection = LLVoiceChannel::setCurrentVoiceChannelChangedCallback(boost::bind(&LLConversationViewSession::onCurrentVoiceSessionChanged, this, _1));
+ mSpeakingIndicator = getChild<LLOutputMonitorCtrl>("speaking_indicator");
+
+ LLConversationItem* vmi = dynamic_cast<LLConversationItem*>(getViewModelItem());
+ if (vmi)
+ {
+ switch(vmi->getType())
+ {
+ case LLConversationItem::CONV_PARTICIPANT:
+ case LLConversationItem::CONV_SESSION_1_ON_1:
+ {
+ LLIMModel::LLIMSession* session= LLIMModel::instance().findIMSession(vmi->getUUID());
+ if (session)
+ {
+ LLAvatarIconCtrl* icon = mItemPanel->getChild<LLAvatarIconCtrl>("avatar_icon");
+ icon->setVisible(true);
+ icon->setValue(session->mOtherParticipantID);
+ mSpeakingIndicator->setSpeakerId(gAgentID, session->mSessionID, true);
+ mHasArrow = false;
+ }
+ break;
+ }
+ case LLConversationItem::CONV_SESSION_AD_HOC:
+ {
+ LLGroupIconCtrl* icon = mItemPanel->getChild<LLGroupIconCtrl>("group_icon");
+ icon->setVisible(true);
+ mSpeakingIndicator->setSpeakerId(gAgentID, vmi->getUUID(), true);
+ break;
+ }
+ case LLConversationItem::CONV_SESSION_GROUP:
+ {
+ LLGroupIconCtrl* icon = mItemPanel->getChild<LLGroupIconCtrl>("group_icon");
+ icon->setVisible(true);
+ icon->setValue(vmi->getUUID());
+ mSpeakingIndicator->setSpeakerId(gAgentID, vmi->getUUID(), true);
+ break;
+ }
+ case LLConversationItem::CONV_SESSION_NEARBY:
+ {
+ LLIconCtrl* icon = mItemPanel->getChild<LLIconCtrl>("nearby_chat_icon");
+ icon->setVisible(true);
+ mSpeakingIndicator->setSpeakerId(gAgentID, LLUUID::null, true);
+ mIsInActiveVoiceChannel = true;
+ if(LLVoiceClient::instanceExists())
+ {
+ LLNearbyVoiceClientStatusObserver* mVoiceClientObserver = new LLNearbyVoiceClientStatusObserver(this);
+ LLVoiceClient::getInstance()->addObserver(mVoiceClientObserver);
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ refresh();
+
+ return TRUE;
+}
+
+void LLConversationViewSession::draw()
+{
+ getViewModelItem()->update();
+
+ const LLFolderViewItem::Params& default_params = LLUICtrlFactory::getDefaultParams<LLFolderViewItem>();
+ const BOOL show_context = (getRoot() ? getRoot()->getShowSelectionContext() : FALSE);
+
+ // Indicate that flash can start (moot operation if already started, done or not flashing)
+ startFlashing();
+
+ // draw highlight for selected items
+ drawHighlight(show_context, true, sHighlightBgColor, sFlashBgColor, sFocusOutlineColor, sMouseOverColor);
+
+ // Draw children if root folder, or any other folder that is open. Do not draw children when animating to closed state or you get rendering overlap.
+ bool draw_children = getRoot() == static_cast<LLFolderViewFolder*>(this) || isOpen();
+
+ for (folders_t::iterator iter = mFolders.begin();
+ iter != mFolders.end();)
+ {
+ folders_t::iterator fit = iter++;
+ (*fit)->setVisible(draw_children);
+ }
+ for (items_t::iterator iter = mItems.begin();
+ iter != mItems.end();)
+ {
+ items_t::iterator iit = iter++;
+ (*iit)->setVisible(draw_children);
+ }
+
+ // we don't draw the open folder arrow in minimized mode
+ if (mHasArrow && !mCollapsedMode)
+ {
+ // update the rotation angle of open folder arrow
+ updateLabelRotation();
+ drawOpenFolderArrow(default_params, sFgColor);
+ }
+
+ refresh();
+
+ LLView::draw();
+}
+
+BOOL LLConversationViewSession::handleMouseDown( S32 x, S32 y, MASK mask )
+{
+ //Will try to select a child node and then itself (if a child was not selected)
+ BOOL result = LLFolderViewFolder::handleMouseDown(x, y, mask);
+
+ //This node (conversation) was selected and a child (participant) was not
+ if(result && getRoot())
+ {
+
+ if(getRoot()->getCurSelectedItem() == this)
+ {
+ LLConversationItem* item = dynamic_cast<LLConversationItem *>(getViewModelItem());
+ LLUUID session_id = item? item->getUUID() : LLUUID();
+
+ LLFloaterIMContainer *im_container = LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container");
+ if (im_container->isConversationsPaneCollapsed() && im_container->getSelectedSession() == session_id)
+ {
+ im_container->collapseMessagesPane(!im_container->isMessagesPaneCollapsed());
+ }
+ else
+ {
+ im_container->collapseMessagesPane(false);
+ }
+
+ }
+ selectConversationItem();
+ }
+
+ return result;
+}
+
+BOOL LLConversationViewSession::handleMouseUp( S32 x, S32 y, MASK mask )
+{
+ BOOL result = LLFolderViewFolder::handleMouseUp(x, y, mask);
+
+ LLFloater* volume_floater = LLFloaterReg::findInstance("floater_voice_volume");
+ LLFloater* chat_volume_floater = LLFloaterReg::findInstance("chat_voice");
+ if (result
+ && getRoot()
+ && !(volume_floater && volume_floater->isShown() && volume_floater->hasFocus())
+ && !(chat_volume_floater && chat_volume_floater->isShown() && chat_volume_floater->hasFocus()))
+ {
+ LLConversationItem* item = dynamic_cast<LLConversationItem *>(getViewModelItem());
+ LLUUID session_id = item? item->getUUID() : LLUUID();
+ LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::findConversation(session_id);
+ if(!session_floater->hasFocus())
+ {
+ session_floater->setFocus(true);
+ }
+ }
+
+ return result;
+}
+
+BOOL LLConversationViewSession::handleRightMouseDown( S32 x, S32 y, MASK mask )
+{
+ BOOL result = LLFolderViewFolder::handleRightMouseDown(x, y, mask);
+
+ if(result)
+ {
+ selectConversationItem();
+ }
+
+ return result;
+}
+
+void LLConversationViewSession::selectConversationItem()
+{
+ if(getRoot()->getCurSelectedItem() == this)
+ {
+ LLConversationItem* item = dynamic_cast<LLConversationItem *>(getViewModelItem());
+ LLUUID session_id = item? item->getUUID() : LLUUID();
+
+ LLFloaterIMContainer *im_container = LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container");
+ im_container->flashConversationItemWidget(session_id,false);
+ im_container->selectConversationPair(session_id, false);
+ }
+}
+
+// virtual
+S32 LLConversationViewSession::arrange(S32* width, S32* height)
+{
+ //LLFolderViewFolder::arrange computes value for getIndentation() function below
+ S32 arranged = LLFolderViewFolder::arrange(width, height);
+
+ S32 h_pad = mHasArrow ? getIndentation() + mArrowSize : getIndentation();
+
+ LLRect rect(mCollapsedMode ? getLocalRect().mLeft : h_pad,
+ getLocalRect().mTop,
+ getLocalRect().mRight,
+ getLocalRect().mTop - getItemHeight());
+ mItemPanel->setShape(rect);
+
+ return arranged;
+}
+
+// virtual
+void LLConversationViewSession::toggleOpen()
+{
+ // conversations should not be opened while in minimized mode
+ if (!mCollapsedMode)
+ {
+ LLFolderViewFolder::toggleOpen();
+
+ // do item's selection when opened
+ if (LLFolderViewFolder::isOpen())
+ {
+ getParentFolder()->setSelection(this, true);
+ }
+ mContainer->reSelectConversation();
+ }
+}
+
+void LLConversationViewSession::toggleCollapsedMode(bool is_collapsed)
+{
+ mCollapsedMode = is_collapsed;
+
+ // hide the layout stack which contains all item's child widgets
+ // except for the icon which we display in minimized mode
+ getChild<LLView>("conversation_item_stack")->setVisible(!mCollapsedMode);
+
+ S32 h_pad = mHasArrow ? getIndentation() + mArrowSize : getIndentation();
+
+ mItemPanel->translate(mCollapsedMode ? -h_pad : h_pad, 0);
+}
+
+void LLConversationViewSession::setVisibleIfDetached(BOOL visible)
+{
+ // Do this only if the conversation floater has been torn off (i.e. no multi floater host) and is not minimized
+ // Note: minimized dockable floaters are brought to front hence unminimized when made visible and we don't want that here
+ LLFloater* session_floater = getSessionFloater();
+ if (session_floater && session_floater->isDetachedAndNotMinimized())
+ {
+ session_floater->setVisible(visible);
+ }
+}
+
+LLFloater* LLConversationViewSession::getSessionFloater()
+{
+ LLFolderViewModelItem* item = mViewModelItem;
+ LLUUID session_uuid = dynamic_cast<LLConversationItem*>(item)->getUUID();
+ return LLFloaterIMSessionTab::getConversation(session_uuid);
+}
+
+LLConversationViewParticipant* LLConversationViewSession::findParticipant(const LLUUID& participant_id)
+{
+ // This is *not* a general tree parsing algorithm. We search only in the mItems list
+ // assuming there is no mFolders which makes sense for sessions (sessions don't contain
+ // sessions).
+ LLConversationViewParticipant* participant = NULL;
+ items_t::const_iterator iter;
+ for (iter = getItemsBegin(); iter != getItemsEnd(); iter++)
+ {
+ participant = dynamic_cast<LLConversationViewParticipant*>(*iter);
+ if (participant->hasSameValue(participant_id))
+ {
+ break;
+ }
+ }
+ return (iter == getItemsEnd() ? NULL : participant);
+}
+
+void LLConversationViewSession::showVoiceIndicator(bool visible)
+{
+ mCallIconLayoutPanel->setVisible(visible && LLVoiceChannel::getCurrentVoiceChannel()->getSessionID().isNull());
+ requestArrange();
+}
+
+void LLConversationViewSession::refresh()
+{
+ // Refresh the session view from its model data
+ LLConversationItem* vmi = dynamic_cast<LLConversationItem*>(getViewModelItem());
+ vmi->resetRefresh();
+
+ if (mSessionTitle)
+ {
+ mSessionTitle->setText(vmi->getDisplayName());
+ }
+
+ // Update all speaking indicators
+ LLSpeakingIndicatorManager::updateSpeakingIndicators();
+
+ // we should show indicator for specified voice session only if this is current channel. EXT-5562.
+ if (!mIsInActiveVoiceChannel)
+ {
+ if (mSpeakingIndicator)
+ {
+ mSpeakingIndicator->setVisible(false);
+ }
+ LLConversationViewParticipant* participant = NULL;
+ items_t::const_iterator iter;
+ for (iter = getItemsBegin(); iter != getItemsEnd(); iter++)
+ {
+ participant = dynamic_cast<LLConversationViewParticipant*>(*iter);
+ if (participant)
+ {
+ participant->hideSpeakingIndicator();
+ }
+ }
+ }
+ requestArrange();
+ // Do the regular upstream refresh
+ LLFolderViewFolder::refresh();
+}
+
+void LLConversationViewSession::onCurrentVoiceSessionChanged(const LLUUID& session_id)
+{
+ LLConversationItem* vmi = dynamic_cast<LLConversationItem*>(getViewModelItem());
+
+ if (vmi)
+ {
+ mIsInActiveVoiceChannel = vmi->getUUID() == session_id;
+ mCallIconLayoutPanel->setVisible(mIsInActiveVoiceChannel);
+ }
+}
+
+//
+// Implementation of conversations list participant (avatar) widgets
+//
+
+static LLDefaultChildRegistry::Register<LLConversationViewParticipant> r("conversation_view_participant");
+bool LLConversationViewParticipant::sStaticInitialized = false;
+S32 LLConversationViewParticipant::sChildrenWidths[LLConversationViewParticipant::ALIC_COUNT];
+
+LLConversationViewParticipant::Params::Params() :
+container(),
+participant_id(),
+avatar_icon("avatar_icon"),
+info_button("info_button"),
+output_monitor("output_monitor")
+{}
+
+LLConversationViewParticipant::LLConversationViewParticipant( const LLConversationViewParticipant::Params& p ):
+ LLFolderViewItem(p),
+ mAvatarIcon(NULL),
+ mInfoBtn(NULL),
+ mSpeakingIndicator(NULL),
+ mUUID(p.participant_id)
+{
+}
+
+LLConversationViewParticipant::~LLConversationViewParticipant()
+{
+ mActiveVoiceChannelConnection.disconnect();
+}
+
+void LLConversationViewParticipant::initFromParams(const LLConversationViewParticipant::Params& params)
+{
+ LLAvatarIconCtrl::Params avatar_icon_params(params.avatar_icon());
+ applyXUILayout(avatar_icon_params, this);
+ LLAvatarIconCtrl * avatarIcon = LLUICtrlFactory::create<LLAvatarIconCtrl>(avatar_icon_params);
+ addChild(avatarIcon);
+
+ LLButton::Params info_button_params(params.info_button());
+ applyXUILayout(info_button_params, this);
+ LLButton * button = LLUICtrlFactory::create<LLButton>(info_button_params);
+ addChild(button);
+
+ LLOutputMonitorCtrl::Params output_monitor_params(params.output_monitor());
+ applyXUILayout(output_monitor_params, this);
+ LLOutputMonitorCtrl * outputMonitor = LLUICtrlFactory::create<LLOutputMonitorCtrl>(output_monitor_params);
+ addChild(outputMonitor);
+}
+
+BOOL LLConversationViewParticipant::postBuild()
+{
+ mAvatarIcon = getChild<LLAvatarIconCtrl>("avatar_icon");
+
+ mInfoBtn = getChild<LLButton>("info_btn");
+ mInfoBtn->setClickedCallback(boost::bind(&LLConversationViewParticipant::onInfoBtnClick, this));
+ mInfoBtn->setVisible(false);
+
+ mSpeakingIndicator = getChild<LLOutputMonitorCtrl>("speaking_indicator");
+
+ if (!sStaticInitialized)
+ {
+ // Remember children widths including their padding from the next sibling,
+ // so that we can hide and show them again later.
+ initChildrenWidths(this);
+ sStaticInitialized = true;
+ }
+
+ updateChildren();
+ return LLFolderViewItem::postBuild();
+}
+
+void LLConversationViewParticipant::draw()
+{
+ static LLUIColor sFgColor = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE);
+ static LLUIColor sFgDisabledColor = LLUIColorTable::instance().getColor("MenuItemDisabledColor", DEFAULT_WHITE);
+ static LLUIColor sHighlightFgColor = LLUIColorTable::instance().getColor("MenuItemHighlightFgColor", DEFAULT_WHITE);
+ static LLUIColor sHighlightBgColor = LLUIColorTable::instance().getColor("MenuItemHighlightBgColor", DEFAULT_WHITE);
+ static LLUIColor sFlashBgColor = LLUIColorTable::instance().getColor("MenuItemFlashBgColor", DEFAULT_WHITE);
+ static LLUIColor sFocusOutlineColor = LLUIColorTable::instance().getColor("InventoryFocusOutlineColor", DEFAULT_WHITE);
+ static LLUIColor sMouseOverColor = LLUIColorTable::instance().getColor("InventoryMouseOverColor", DEFAULT_WHITE);
+
+ const BOOL show_context = (getRoot() ? getRoot()->getShowSelectionContext() : FALSE);
+
+ const LLFontGL* font = getLabelFontForStyle(mLabelStyle);
+ F32 right_x = 0;
+
+ F32 y = (F32)getRect().getHeight() - font->getLineHeight() - (F32)mTextPad;
+ F32 text_left = (F32)getLabelXPos();
+
+ LLColor4 color;
+ LLLocalSpeakerMgr *speakerMgr = LLLocalSpeakerMgr::getInstance();
+
+ if (speakerMgr && speakerMgr->isSpeakerToBeRemoved(mUUID))
+ {
+ color = sFgDisabledColor;
+ }
+ else
+ {
+ color = mIsSelected ? sHighlightFgColor : sFgColor;
+ }
+
+ drawHighlight(show_context, mIsSelected, sHighlightBgColor, sFlashBgColor, sFocusOutlineColor, sMouseOverColor);
+ drawLabel(font, text_left, y, color, right_x);
+ refresh();
+
+ LLView::draw();
+}
+
+// virtual
+S32 LLConversationViewParticipant::arrange(S32* width, S32* height)
+{
+ //Need to call arrange first since it computes value used in getIndentation()
+ S32 arranged = LLFolderViewItem::arrange(width, height);
+
+ //Adjusts the avatar icon based upon the indentation
+ LLRect avatarRect(getIndentation(),
+ mAvatarIcon->getRect().mTop,
+ getIndentation() + mAvatarIcon->getRect().getWidth(),
+ mAvatarIcon->getRect().mBottom);
+ mAvatarIcon->setShape(avatarRect);
+
+ //Since dimensions changed, adjust the children (info button, speaker indicator)
+ updateChildren();
+
+ return arranged;
+}
+
+void LLConversationViewParticipant::addToFolder(LLFolderViewFolder* folder)
+{
+ // Add the item to the folder (conversation)
+ LLFolderViewItem::addToFolder(folder);
+
+ // Retrieve the folder (conversation) UUID, which is also the speaker session UUID
+ LLConversationItem* vmi = getParentFolder() ? dynamic_cast<LLConversationItem*>(getParentFolder()->getViewModelItem()) : NULL;
+ if (vmi)
+ {
+ addToSession(vmi->getUUID());
+ }
+}
+
+void LLConversationViewParticipant::addToSession(const LLUUID& session_id)
+{
+ //Allows speaking icon image to be loaded based on mUUID
+ mAvatarIcon->setValue(mUUID);
+
+ //Allows the speaker indicator to be activated based on the user and conversation
+ mSpeakingIndicator->setSpeakerId(mUUID, session_id);
+}
+
+void LLConversationViewParticipant::onInfoBtnClick()
+{
+ LLFloaterReg::showInstance("inspect_avatar", LLSD().with("avatar_id", mUUID));
+}
+
+BOOL LLConversationViewParticipant::handleMouseDown( S32 x, S32 y, MASK mask )
+{
+ BOOL result = LLFolderViewItem::handleMouseDown(x, y, mask);
+
+ if(result && getRoot())
+ {
+ if(getRoot()->getCurSelectedItem() == this)
+ {
+ LLConversationItem* vmi = getParentFolder() ? dynamic_cast<LLConversationItem*>(getParentFolder()->getViewModelItem()) : NULL;
+ LLUUID session_id = vmi? vmi->getUUID() : LLUUID();
+
+ LLFloaterIMContainer *im_container = LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container");
+ LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::findConversation(session_id);
+ im_container->setSelectedSession(session_id);
+ im_container->flashConversationItemWidget(session_id,false);
+ im_container->selectFloater(session_floater);
+ im_container->collapseMessagesPane(false);
+ }
+ }
+ return result;
+}
+
+void LLConversationViewParticipant::onMouseEnter(S32 x, S32 y, MASK mask)
+{
+ mInfoBtn->setVisible(true);
+ updateChildren();
+ LLFolderViewItem::onMouseEnter(x, y, mask);
+}
+
+void LLConversationViewParticipant::onMouseLeave(S32 x, S32 y, MASK mask)
+{
+ mInfoBtn->setVisible(false);
+ updateChildren();
+ LLFolderViewItem::onMouseLeave(x, y, mask);
+}
+
+S32 LLConversationViewParticipant::getLabelXPos()
+{
+ return getIndentation() + mAvatarIcon->getRect().getWidth() + mIconPad;
+}
+
+// static
+void LLConversationViewParticipant::initChildrenWidths(LLConversationViewParticipant* self)
+{
+ //speaking indicator width + padding
+ S32 speaking_indicator_width = self->getRect().getWidth() - self->mSpeakingIndicator->getRect().mLeft;
+
+ //info btn width + padding
+ S32 info_btn_width = self->mSpeakingIndicator->getRect().mLeft - self->mInfoBtn->getRect().mLeft;
+
+ S32 index = ALIC_COUNT;
+ sChildrenWidths[--index] = info_btn_width;
+ sChildrenWidths[--index] = speaking_indicator_width;
+ llassert(index == 0);
+}
+
+void LLConversationViewParticipant::updateChildren()
+{
+ mLabelPaddingRight = DEFAULT_LABEL_PADDING_RIGHT;
+ LLView* control;
+ S32 ctrl_width;
+ LLRect controlRect;
+
+ //Cycles through controls starting from right to left
+ for (S32 i = 0; i < ALIC_COUNT; ++i)
+ {
+ control = getItemChildView((EAvatarListItemChildIndex)i);
+
+ // skip invisible views
+ if (!control->getVisible()) continue;
+
+ //Get current pos/dimensions
+ controlRect = control->getRect();
+
+ ctrl_width = sChildrenWidths[i]; // including space between current & left controls
+ // accumulate the amount of space taken by the controls
+ mLabelPaddingRight += ctrl_width;
+
+ //Reposition visible controls in case adjacent controls to the right are hidden.
+ controlRect.setLeftTopAndSize(
+ getLocalRect().getWidth() - mLabelPaddingRight,
+ controlRect.mTop,
+ controlRect.getWidth(),
+ controlRect.getHeight());
+
+ //Sets the new position
+ control->setShape(controlRect);
+ }
+}
+
+LLView* LLConversationViewParticipant::getItemChildView(EAvatarListItemChildIndex child_view_index)
+{
+ LLView* child_view = NULL;
+
+ switch (child_view_index)
+ {
+ case ALIC_SPEAKER_INDICATOR:
+ child_view = mSpeakingIndicator;
+ break;
+ case ALIC_INFO_BUTTON:
+ child_view = mInfoBtn;
+ break;
+ default:
+ LL_WARNS("AvatarItemReshape") << "Unexpected child view index is passed: " << child_view_index << LL_ENDL;
+ llassert(0);
+ break;
+ // leave child_view untouched
+ }
+
+ return child_view;
+}
+
+void LLConversationViewParticipant::hideSpeakingIndicator()
+{
+ mSpeakingIndicator->setVisible(false);
+}
+
+// EOF
+
diff --git a/indra/newview/llconversationview.h b/indra/newview/llconversationview.h
new file mode 100644
index 0000000000..5a74974302
--- /dev/null
+++ b/indra/newview/llconversationview.h
@@ -0,0 +1,181 @@
+/**
+ * @file llconversationview.h
+ * @brief Implementation of conversations list widgets and views
+ *
+ * $LicenseInfo:firstyear=2009&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$
+ */
+
+#ifndef LL_LLCONVERSATIONVIEW_H
+#define LL_LLCONVERSATIONVIEW_H
+
+#include "../llui/llfolderviewitem.h"
+
+#include "llavatariconctrl.h"
+#include "../llui/llbutton.h"
+#include "lloutputmonitorctrl.h"
+
+class LLTextBox;
+class LLFloaterIMContainer;
+class LLConversationViewSession;
+class LLConversationViewParticipant;
+
+class LLVoiceClientStatusObserver;
+
+// Implementation of conversations list session widgets
+
+class LLConversationViewSession : public LLFolderViewFolder
+{
+public:
+ struct Params : public LLInitParam::Block<Params, LLFolderViewItem::Params>
+ {
+ Optional<LLFloaterIMContainer*> container;
+
+ Params();
+ };
+
+protected:
+ friend class LLUICtrlFactory;
+ LLConversationViewSession( const Params& p );
+
+ /*virtual*/ bool isHighlightAllowed();
+ /*virtual*/ bool isHighlightActive();
+ /*virtual*/ bool isFlashing() { return mFlashStateOn; }
+
+ LLFloaterIMContainer* mContainer;
+
+public:
+ virtual ~LLConversationViewSession();
+
+ /*virtual*/ BOOL postBuild();
+ /*virtual*/ void draw();
+ /*virtual*/ BOOL handleMouseDown( S32 x, S32 y, MASK mask );
+ /*virtual*/ BOOL handleRightMouseDown( S32 x, S32 y, MASK mask );
+ /*virtual*/ BOOL handleMouseUp( S32 x, S32 y, MASK mask );
+
+ /*virtual*/ S32 arrange(S32* width, S32* height);
+
+ /*virtual*/ void toggleOpen();
+
+ /*virtual*/ bool isCollapsed() { return mCollapsedMode; }
+
+ void toggleCollapsedMode(bool is_collapsed);
+
+ void setVisibleIfDetached(BOOL visible);
+ LLConversationViewParticipant* findParticipant(const LLUUID& participant_id);
+
+ void showVoiceIndicator(bool visible);
+
+ virtual void refresh();
+
+ /*virtual*/ void setFlashState(bool flash_state);
+ void setHighlightState(bool hihglight_state);
+
+ LLFloater* getSessionFloater();
+
+private:
+
+ void onCurrentVoiceSessionChanged(const LLUUID& session_id);
+ void startFlashing();
+ void selectConversationItem();
+
+ LLPanel* mItemPanel;
+ LLPanel* mCallIconLayoutPanel;
+ LLTextBox* mSessionTitle;
+ LLOutputMonitorCtrl* mSpeakingIndicator;
+ LLFlashTimer* mFlashTimer;
+ bool mFlashStateOn;
+ bool mFlashStarted;
+
+ bool mCollapsedMode;
+ bool mHasArrow;
+
+ bool mIsInActiveVoiceChannel;
+
+ LLVoiceClientStatusObserver* mVoiceClientObserver;
+
+ boost::signals2::connection mActiveVoiceChannelConnection;
+};
+
+// Implementation of conversations list participant (avatar) widgets
+
+class LLConversationViewParticipant : public LLFolderViewItem
+{
+
+public:
+
+ struct Params : public LLInitParam::Block<Params, LLFolderViewItem::Params>
+ {
+ Optional<LLFloaterIMContainer*> container;
+ Optional<LLUUID> participant_id;
+ Optional<LLAvatarIconCtrl::Params> avatar_icon;
+ Optional<LLButton::Params> info_button;
+ Optional<LLOutputMonitorCtrl::Params> output_monitor;
+
+ Params();
+ };
+
+ virtual ~LLConversationViewParticipant( void );
+
+ bool hasSameValue(const LLUUID& uuid) { return (uuid == mUUID); }
+ void addToFolder(LLFolderViewFolder* folder);
+ void addToSession(const LLUUID& session_id);
+
+ void onMouseEnter(S32 x, S32 y, MASK mask);
+ void onMouseLeave(S32 x, S32 y, MASK mask);
+
+ /*virtual*/ S32 getLabelXPos();
+ /*virtual*/ BOOL handleMouseDown( S32 x, S32 y, MASK mask );
+ void hideSpeakingIndicator();
+
+protected:
+ friend class LLUICtrlFactory;
+ LLConversationViewParticipant( const Params& p );
+ void initFromParams(const Params& params);
+ BOOL postBuild();
+ /*virtual*/ void draw();
+ /*virtual*/ S32 arrange(S32* width, S32* height);
+
+ void onInfoBtnClick();
+
+private:
+
+ LLAvatarIconCtrl* mAvatarIcon;
+ LLButton * mInfoBtn;
+ LLOutputMonitorCtrl* mSpeakingIndicator;
+ LLUUID mUUID; // UUID of the participant
+
+ typedef enum e_avatar_item_child {
+ ALIC_SPEAKER_INDICATOR,
+ ALIC_INFO_BUTTON,
+ ALIC_COUNT,
+ } EAvatarListItemChildIndex;
+
+ static bool sStaticInitialized; // this variable is introduced to improve code readability
+ static S32 sChildrenWidths[ALIC_COUNT];
+ static void initChildrenWidths(LLConversationViewParticipant* self);
+ void updateChildren();
+ LLView* getItemChildView(EAvatarListItemChildIndex child_view_index);
+
+ boost::signals2::connection mActiveVoiceChannelConnection;
+};
+
+#endif // LL_LLCONVERSATIONVIEW_H
diff --git a/indra/newview/llcurrencyuimanager.cpp b/indra/newview/llcurrencyuimanager.cpp
index b4a1457f47..b4a1457f47 100644..100755
--- a/indra/newview/llcurrencyuimanager.cpp
+++ b/indra/newview/llcurrencyuimanager.cpp
diff --git a/indra/newview/llcurrencyuimanager.h b/indra/newview/llcurrencyuimanager.h
index 3f37db8db1..3f37db8db1 100644..100755
--- a/indra/newview/llcurrencyuimanager.h
+++ b/indra/newview/llcurrencyuimanager.h
diff --git a/indra/newview/llcylinder.cpp b/indra/newview/llcylinder.cpp
index f353851a25..f353851a25 100644..100755
--- a/indra/newview/llcylinder.cpp
+++ b/indra/newview/llcylinder.cpp
diff --git a/indra/newview/llcylinder.h b/indra/newview/llcylinder.h
index 4369f06659..4369f06659 100644..100755
--- a/indra/newview/llcylinder.h
+++ b/indra/newview/llcylinder.h
diff --git a/indra/newview/lldateutil.cpp b/indra/newview/lldateutil.cpp
index c7fc45f61e..c7fc45f61e 100644..100755
--- a/indra/newview/lldateutil.cpp
+++ b/indra/newview/lldateutil.cpp
diff --git a/indra/newview/lldateutil.h b/indra/newview/lldateutil.h
index f027d360f7..f027d360f7 100644..100755
--- a/indra/newview/lldateutil.h
+++ b/indra/newview/lldateutil.h
diff --git a/indra/newview/lldaycyclemanager.cpp b/indra/newview/lldaycyclemanager.cpp
index 347a467a8b..8af2f4ea33 100644..100755
--- a/indra/newview/lldaycyclemanager.cpp
+++ b/indra/newview/lldaycyclemanager.cpp
@@ -184,7 +184,7 @@ void LLDayCycleManager::loadPresets(const std::string& dir)
{
std::string file;
if (!dir_iter.next(file)) break; // no more files
- loadPreset(dir + file);
+ loadPreset(gDirUtilp->add(dir, file));
}
}
diff --git a/indra/newview/lldaycyclemanager.h b/indra/newview/lldaycyclemanager.h
index 3d2144960d..3d2144960d 100644..100755
--- a/indra/newview/lldaycyclemanager.h
+++ b/indra/newview/lldaycyclemanager.h
diff --git a/indra/newview/lldebugmessagebox.cpp b/indra/newview/lldebugmessagebox.cpp
index 9ad812ab1e..9ad812ab1e 100644..100755
--- a/indra/newview/lldebugmessagebox.cpp
+++ b/indra/newview/lldebugmessagebox.cpp
diff --git a/indra/newview/lldebugmessagebox.h b/indra/newview/lldebugmessagebox.h
index 211af9e074..211af9e074 100644..100755
--- a/indra/newview/lldebugmessagebox.h
+++ b/indra/newview/lldebugmessagebox.h
diff --git a/indra/newview/lldebugview.cpp b/indra/newview/lldebugview.cpp
index 7d3170cb76..aeecf054b8 100644..100755
--- a/indra/newview/lldebugview.cpp
+++ b/indra/newview/lldebugview.cpp
@@ -30,7 +30,6 @@
// library includes
#include "llfasttimerview.h"
-#include "llmemoryview.h"
#include "llconsole.h"
#include "lltextureview.h"
#include "llresmgr.h"
@@ -38,7 +37,6 @@
#include "llviewercontrol.h"
#include "llviewerwindow.h"
#include "llappviewer.h"
-#include "llmemoryview.h"
#include "llsceneview.h"
#include "llviewertexture.h"
#include "llfloaterreg.h"
@@ -68,8 +66,6 @@ LLDebugView::~LLDebugView()
gDebugView = NULL;
gTextureView = NULL;
gSceneView = NULL;
- gTextureSizeView = NULL;
- gTextureCategoryView = NULL;
}
void LLDebugView::init()
@@ -105,47 +101,16 @@ void LLDebugView::init()
r.setLeftTopAndSize(25, rect.getHeight() - 50, (S32) (gViewerWindow->getWindowRectScaled().getWidth() * 0.75f),
(S32) (gViewerWindow->getWindowRectScaled().getHeight() * 0.75f));
- LLMemoryView::Params mp;
- mp.name("memory");
- mp.rect(r);
- mp.follows.flags(FOLLOWS_TOP | FOLLOWS_LEFT);
- mp.visible(false);
- mMemoryView = LLUICtrlFactory::create<LLMemoryView>(mp);
- addChild(mMemoryView);
r.set(150, rect.getHeight() - 50, 820, 100);
LLTextureView::Params tvp;
tvp.name("gTextureView");
tvp.rect(r);
- tvp.follows.flags(FOLLOWS_BOTTOM|FOLLOWS_LEFT);
+ tvp.follows.flags(FOLLOWS_TOP|FOLLOWS_LEFT);
tvp.visible(false);
gTextureView = LLUICtrlFactory::create<LLTextureView>(tvp);
addChild(gTextureView);
//gTextureView->reshape(r.getWidth(), r.getHeight(), TRUE);
-
-
- if(gAuditTexture)
- {
- r.set(150, rect.getHeight() - 50, 900 + LLImageGL::sTextureLoadedCounter.size() * 30, 100);
- LLTextureSizeView::Params tsv ;
- tsv.name("gTextureSizeView");
- tsv.rect(r);
- tsv.follows.flags(FOLLOWS_BOTTOM|FOLLOWS_LEFT);
- tsv.visible(false);
- gTextureSizeView = LLUICtrlFactory::create<LLTextureSizeView>(tsv);
- addChild(gTextureSizeView);
- gTextureSizeView->setType(LLTextureSizeView::TEXTURE_MEM_OVER_SIZE) ;
-
- r.set(150, rect.getHeight() - 50, 900 + LLViewerTexture::getTotalNumOfCategories() * 30, 100);
- LLTextureSizeView::Params tcv ;
- tcv.name("gTextureCategoryView");
- tcv.rect(r);
- tcv.follows.flags(FOLLOWS_BOTTOM|FOLLOWS_LEFT);
- tcv.visible(false);
- gTextureCategoryView = LLUICtrlFactory::create<LLTextureSizeView>(tcv);
- gTextureCategoryView->setType(LLTextureSizeView::TEXTURE_MEM_OVER_CATEGORY);
- addChild(gTextureCategoryView);
- }
}
void LLDebugView::draw()
diff --git a/indra/newview/lldebugview.h b/indra/newview/lldebugview.h
index 5aec77ad62..5aec77ad62 100644..100755
--- a/indra/newview/lldebugview.h
+++ b/indra/newview/lldebugview.h
diff --git a/indra/newview/lldeferredsounds.cpp b/indra/newview/lldeferredsounds.cpp
new file mode 100755
index 0000000000..9416e7cd29
--- /dev/null
+++ b/indra/newview/lldeferredsounds.cpp
@@ -0,0 +1,45 @@
+/**
+* @file lldeferredsounds.cpp
+* @brief Implementation of lldeferredsounds
+* @author Gilbert@lindenlab.com
+*
+* $LicenseInfo:firstyear=2013&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2013, 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 "lldeferredsounds.h"
+
+#include "llaudioengine.h"
+
+void LLDeferredSounds::deferSound(SoundData& sound)
+{
+ soundVector.push_back(sound);
+}
+void LLDeferredSounds::playdeferredSounds()
+{
+ while(soundVector.size())
+ {
+ gAudiop->triggerSound(soundVector.back());
+ soundVector.pop_back();
+ }
+}
diff --git a/indra/newview/lldeferredsounds.h b/indra/newview/lldeferredsounds.h
new file mode 100755
index 0000000000..bf1eb62957
--- /dev/null
+++ b/indra/newview/lldeferredsounds.h
@@ -0,0 +1,46 @@
+/**
+* @file lldeferredsounds.h
+* @brief Header file for lldeferredsounds
+* @author Gilbert@lindenlab.com
+*
+* $LicenseInfo:firstyear=2013&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2013, 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_LLDEFERREDSOUNDS_H
+#define LL_LLDEFERREDSOUNDS_H
+
+#include "llsingleton.h"
+
+struct SoundData;
+
+class LLDeferredSounds : public LLSingleton<LLDeferredSounds>
+{
+private:
+ std::vector<SoundData> soundVector;
+public:
+ //Add sounds to be played once progress bar is hidden (such as after teleport or loading screen)
+ void deferSound(SoundData& sound);
+
+ void playdeferredSounds();
+};
+
+#endif // LL_LLDEFERREDSOUNDS_H
+
diff --git a/indra/newview/lldelayedgestureerror.cpp b/indra/newview/lldelayedgestureerror.cpp
index 80e7c9f1b2..ef1b644ad4 100644..100755
--- a/indra/newview/lldelayedgestureerror.cpp
+++ b/indra/newview/lldelayedgestureerror.cpp
@@ -113,9 +113,11 @@ bool LLDelayedGestureError::doDialog(const LLErrorEntry &ent, bool uuid_ok)
}
}
-
- LLNotificationsUtil::add(ent.mNotifyName, args);
-
+ if(!LLApp::isQuitting())
+ {
+ LLNotificationsUtil::add(ent.mNotifyName, args);
+ }
+
return true;
}
diff --git a/indra/newview/lldelayedgestureerror.h b/indra/newview/lldelayedgestureerror.h
index 7ecadb4e7d..7ecadb4e7d 100644..100755
--- a/indra/newview/lldelayedgestureerror.h
+++ b/indra/newview/lldelayedgestureerror.h
diff --git a/indra/newview/lldirpicker.cpp b/indra/newview/lldirpicker.cpp
index 1e03582a29..4c4424edc4 100644..100755
--- a/indra/newview/lldirpicker.cpp
+++ b/indra/newview/lldirpicker.cpp
@@ -37,7 +37,7 @@
#include "llwindow.h" // beforeDialog()
#include "llviewercontrol.h"
-#if LL_LINUX || LL_SOLARIS
+#if LL_LINUX || LL_SOLARIS || LL_DARWIN
# include "llfilepicker.h"
#endif
@@ -147,152 +147,36 @@ std::string LLDirPicker::getDirName()
#elif LL_DARWIN
LLDirPicker::LLDirPicker() :
- mFileName(NULL),
- mLocked(false)
+mFileName(NULL),
+mLocked(false)
{
+ mFilePicker = new LLFilePicker();
reset();
-
- memset(&mNavOptions, 0, sizeof(mNavOptions));
- OSStatus error = NavGetDefaultDialogCreationOptions(&mNavOptions);
- if (error == noErr)
- {
- mNavOptions.modality = kWindowModalityAppModal;
- }
}
LLDirPicker::~LLDirPicker()
{
- // nothing
+ delete mFilePicker;
}
-//static
-pascal void LLDirPicker::doNavCallbackEvent(NavEventCallbackMessage callBackSelector,
- NavCBRecPtr callBackParms, void* callBackUD)
+void LLDirPicker::reset()
{
- switch(callBackSelector)
- {
- case kNavCBStart:
- {
- if (!sInstance.mFileName) break;
-
- OSStatus error = noErr;
- AEDesc theLocation = {typeNull, NULL};
- FSSpec outFSSpec;
-
- //Convert string to a FSSpec
- FSRef myFSRef;
-
- const char* filename=sInstance.mFileName->c_str();
-
- error = FSPathMakeRef ((UInt8*)filename, &myFSRef, NULL);
-
- if (error != noErr) break;
-
- error = FSGetCatalogInfo (&myFSRef, kFSCatInfoNone, NULL, NULL, &outFSSpec, NULL);
-
- if (error != noErr) break;
-
- error = AECreateDesc(typeFSS, &outFSSpec, sizeof(FSSpec), &theLocation);
-
- if (error != noErr) break;
-
- error = NavCustomControl(callBackParms->context,
- kNavCtlSetLocation, (void*)&theLocation);
-
- }
- }
+ if (mFilePicker)
+ mFilePicker->reset();
}
-OSStatus LLDirPicker::doNavChooseDialog()
-{
- OSStatus error = noErr;
- NavDialogRef navRef = NULL;
- NavReplyRecord navReply;
-
- memset(&navReply, 0, sizeof(navReply));
-
- // NOTE: we are passing the address of a local variable here.
- // This is fine, because the object this call creates will exist for less than the lifetime of this function.
- // (It is destroyed by NavDialogDispose() below.)
-
- error = NavCreateChooseFolderDialog(&mNavOptions, &doNavCallbackEvent, NULL, NULL, &navRef);
-
- gViewerWindow->getWindow()->beforeDialog();
-
- if (error == noErr)
- error = NavDialogRun(navRef);
-
- gViewerWindow->getWindow()->afterDialog();
-
- if (error == noErr)
- error = NavDialogGetReply(navRef, &navReply);
-
- if (navRef)
- NavDialogDispose(navRef);
-
- if (error == noErr && navReply.validRecord)
- {
- FSRef fsRef;
- AEKeyword theAEKeyword;
- DescType typeCode;
- Size actualSize = 0;
- char path[LL_MAX_PATH]; /*Flawfinder: ignore*/
-
- memset(&fsRef, 0, sizeof(fsRef));
- error = AEGetNthPtr(&navReply.selection, 1, typeFSRef, &theAEKeyword, &typeCode, &fsRef, sizeof(fsRef), &actualSize);
-
- if (error == noErr)
- error = FSRefMakePath(&fsRef, (UInt8*) path, sizeof(path));
-
- if (error == noErr)
- mDir = path;
- }
-
- return error;
-}
+//static
BOOL LLDirPicker::getDir(std::string* filename)
{
- if( mLocked ) return FALSE;
- BOOL success = FALSE;
- OSStatus error = noErr;
-
- // if local file browsing is turned off, return without opening dialog
- if ( check_local_file_access_enabled() == false )
- {
- return FALSE;
- }
-
- mFileName = filename;
-
-// mNavOptions.saveFileName
-
- // Modal, so pause agent
- send_agent_pause();
- {
- error = doNavChooseDialog();
- }
- send_agent_resume();
- if (error == noErr)
- {
- if (mDir.length() > 0)
- success = true;
- }
-
- // Account for the fact that the app has been stalled.
- LLFrameTimer::updateFrameTime();
- return success;
+ LLFilePicker::ELoadFilter filter=LLFilePicker::FFLOAD_DIRECTORY;
+
+ return mFilePicker->getOpenFile(filter, true);
}
std::string LLDirPicker::getDirName()
{
- return mDir;
-}
-
-void LLDirPicker::reset()
-{
- mLocked = false;
- mDir.clear();
+ return mFilePicker->getFirstFile();
}
#elif LL_LINUX || LL_SOLARIS
@@ -327,6 +211,8 @@ BOOL LLDirPicker::getDir(std::string* filename)
return FALSE;
}
+#if !LL_MESA_HEADLESS
+
if (mFilePicker)
{
GtkWindow* picker = mFilePicker->buildFilePicker(false, true,
@@ -340,6 +226,8 @@ BOOL LLDirPicker::getDir(std::string* filename)
return (!mFilePicker->getFirstFile().empty());
}
}
+#endif // !LL_MESA_HEADLESS
+
return FALSE;
}
diff --git a/indra/newview/lldirpicker.h b/indra/newview/lldirpicker.h
index 2188b7edd0..9cc62431ef 100644..100755
--- a/indra/newview/lldirpicker.h
+++ b/indra/newview/lldirpicker.h
@@ -34,7 +34,6 @@
#include "stdtypes.h"
#if LL_DARWIN
-#include <Carbon/Carbon.h>
// AssertMacros.h does bad things.
#undef verify
@@ -77,15 +76,7 @@ private:
void buildDirname( void );
bool check_local_file_access_enabled();
-#if LL_DARWIN
- NavDialogCreationOptions mNavOptions;
- static pascal void doNavCallbackEvent(NavEventCallbackMessage callBackSelector,
- NavCBRecPtr callBackParms, void* callBackUD);
- OSStatus doNavChooseDialog();
-
-#endif
-
-#if LL_LINUX || LL_SOLARIS
+#if LL_LINUX || LL_SOLARIS || LL_DARWIN
// On Linux we just implement LLDirPicker on top of LLFilePicker
LLFilePicker *mFilePicker;
#endif
diff --git a/indra/newview/lldndbutton.cpp b/indra/newview/lldndbutton.cpp
index 7c9dda6b1d..7c9dda6b1d 100644..100755
--- a/indra/newview/lldndbutton.cpp
+++ b/indra/newview/lldndbutton.cpp
diff --git a/indra/newview/lldndbutton.h b/indra/newview/lldndbutton.h
index 53ea2f5ea7..53ea2f5ea7 100644..100755
--- a/indra/newview/lldndbutton.h
+++ b/indra/newview/lldndbutton.h
diff --git a/indra/newview/lldonotdisturbnotificationstorage.cpp b/indra/newview/lldonotdisturbnotificationstorage.cpp
new file mode 100755
index 0000000000..495cd01349
--- /dev/null
+++ b/indra/newview/lldonotdisturbnotificationstorage.cpp
@@ -0,0 +1,343 @@
+/**
+* @file lldonotdisturbnotificationstorage.cpp
+* @brief Implementation of lldonotdisturbnotificationstorage
+* @author Stinson@lindenlab.com
+*
+* $LicenseInfo:firstyear=2012&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2012, 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 "lldonotdisturbnotificationstorage.h"
+
+#include "llcommunicationchannel.h"
+#include "lldir.h"
+#include "llerror.h"
+#include "llfloaterreg.h"
+#include "llimview.h"
+#include "llnotifications.h"
+#include "llnotificationhandler.h"
+#include "llnotificationstorage.h"
+#include "llscriptfloater.h"
+#include "llsd.h"
+#include "llsingleton.h"
+#include "lluuid.h"
+
+static const F32 DND_TIMER = 3.0;
+const char * LLDoNotDisturbNotificationStorage::toastName = "IMToast";
+const char * LLDoNotDisturbNotificationStorage::offerName = "UserGiveItem";
+
+LLDoNotDisturbNotificationStorageTimer::LLDoNotDisturbNotificationStorageTimer() : LLEventTimer(DND_TIMER)
+{
+
+}
+
+LLDoNotDisturbNotificationStorageTimer::~LLDoNotDisturbNotificationStorageTimer()
+{
+
+}
+
+BOOL LLDoNotDisturbNotificationStorageTimer::tick()
+{
+ LLDoNotDisturbNotificationStorage * doNotDisturbNotificationStorage = LLDoNotDisturbNotificationStorage::getInstance();
+
+ if(doNotDisturbNotificationStorage
+ && doNotDisturbNotificationStorage->getDirty())
+ {
+ doNotDisturbNotificationStorage->saveNotifications();
+ }
+ return FALSE;
+}
+
+LLDoNotDisturbNotificationStorage::LLDoNotDisturbNotificationStorage()
+ : LLSingleton<LLDoNotDisturbNotificationStorage>()
+ , LLNotificationStorage("")
+ , mDirty(false)
+{
+ nameToPayloadParameterMap[toastName] = "SESSION_ID";
+ nameToPayloadParameterMap[offerName] = "object_id";
+}
+
+LLDoNotDisturbNotificationStorage::~LLDoNotDisturbNotificationStorage()
+{
+}
+
+void LLDoNotDisturbNotificationStorage::initialize()
+{
+ setFileName(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "dnd_notifications.xml"));
+ getCommunicationChannel()->connectFailedFilter(boost::bind(&LLDoNotDisturbNotificationStorage::onChannelChanged, this, _1));
+}
+
+bool LLDoNotDisturbNotificationStorage::getDirty()
+{
+ return mDirty;
+}
+
+void LLDoNotDisturbNotificationStorage::resetDirty()
+{
+ mDirty = false;
+}
+
+static LLFastTimer::DeclareTimer FTM_SAVE_DND_NOTIFICATIONS("Save DND Notifications");
+
+void LLDoNotDisturbNotificationStorage::saveNotifications()
+{
+ LLFastTimer _(FTM_SAVE_DND_NOTIFICATIONS);
+
+ LLNotificationChannelPtr channelPtr = getCommunicationChannel();
+ const LLCommunicationChannel *commChannel = dynamic_cast<LLCommunicationChannel*>(channelPtr.get());
+ llassert(commChannel != NULL);
+
+ LLSD output = LLSD::emptyMap();
+ LLSD& data = output["data"];
+ data = LLSD::emptyArray();
+
+ for (LLCommunicationChannel::history_list_t::const_iterator historyIter = commChannel->beginHistory();
+ historyIter != commChannel->endHistory(); ++historyIter)
+ {
+ LLNotificationPtr notificationPtr = historyIter->second;
+
+ if (!notificationPtr->isRespondedTo() && !notificationPtr->isCancelled() &&
+ !notificationPtr->isExpired() && !notificationPtr->isPersistent())
+ {
+ data.append(notificationPtr->asLLSD(true));
+ }
+ }
+
+ writeNotifications(output);
+
+ resetDirty();
+}
+
+static LLFastTimer::DeclareTimer FTM_LOAD_DND_NOTIFICATIONS("Load DND Notifications");
+
+void LLDoNotDisturbNotificationStorage::loadNotifications()
+{
+ LLFastTimer _(FTM_LOAD_DND_NOTIFICATIONS);
+
+ LL_INFOS("LLDoNotDisturbNotificationStorage") << "start loading notifications" << LL_ENDL;
+
+ LLSD input;
+ if (!readNotifications(input) ||input.isUndefined())
+ {
+ return;
+ }
+
+ LLSD& data = input["data"];
+ if (data.isUndefined())
+ {
+ return;
+ }
+
+ LLNotifications& instance = LLNotifications::instance();
+ bool imToastExists = false;
+ bool group_ad_hoc_toast_exists = false;
+ S32 toastSessionType;
+ bool offerExists = false;
+
+ for (LLSD::array_const_iterator notification_it = data.beginArray();
+ notification_it != data.endArray();
+ ++notification_it)
+ {
+ LLSD notification_params = *notification_it;
+ const LLUUID& notificationID = notification_params["id"];
+ std::string notificationName = notification_params["name"];
+ LLNotificationPtr notification = instance.find(notificationID);
+
+ if(notificationName == toastName)
+ {
+ toastSessionType = notification_params["payload"]["SESSION_TYPE"];
+ if(toastSessionType == LLIMModel::LLIMSession::P2P_SESSION)
+ {
+ imToastExists = true;
+ }
+ //Don't add group/ad-hoc messages to the notification system because
+ //this means the group/ad-hoc session has to be re-created
+ else if(toastSessionType == LLIMModel::LLIMSession::GROUP_SESSION
+ || toastSessionType == LLIMModel::LLIMSession::ADHOC_SESSION)
+ {
+ //Just allows opening the conversation log for group/ad-hoc messages upon startup
+ group_ad_hoc_toast_exists = true;
+ continue;
+ }
+ }
+ else if(notificationName == offerName)
+ {
+ offerExists = true;
+ }
+
+ //Notification already exists due to persistent storage adding it first into the notification system
+ if(notification)
+ {
+ notification->setDND(true);
+ instance.update(instance.find(notificationID));
+ }
+ //New notification needs to be added
+ else
+ {
+ notification = (LLNotificationPtr) new LLNotification(notification_params.with("is_dnd", true));
+ LLNotificationResponderInterface* responder = createResponder(notification_params["responder_sd"]["responder_type"], notification_params["responder_sd"]);
+ if (responder == NULL)
+ {
+ LL_WARNS("LLDoNotDisturbNotificationStorage") << "cannot create responder for notification of type '"
+ << notification->getType() << "'" << LL_ENDL;
+ }
+ else
+ {
+ LLNotificationResponderPtr responderPtr(responder);
+ notification->setResponseFunctor(responderPtr);
+ }
+
+ instance.add(notification);
+ }
+
+ }
+
+ bool isConversationLoggingAllowed = gSavedPerAccountSettings.getS32("KeepConversationLogTranscripts") > 0;
+ if(group_ad_hoc_toast_exists && isConversationLoggingAllowed)
+ {
+ LLFloaterReg::showInstance("conversation");
+ }
+
+ if(imToastExists || group_ad_hoc_toast_exists || offerExists)
+ {
+ make_ui_sound_deferred("UISndNewIncomingIMSession");
+ }
+
+ //writes out empty .xml file (since LLCommunicationChannel::mHistory is empty)
+ saveNotifications();
+
+ LL_INFOS("LLDoNotDisturbNotificationStorage") << "finished loading notifications" << LL_ENDL;
+}
+
+void LLDoNotDisturbNotificationStorage::updateNotifications()
+{
+
+ LLNotificationChannelPtr channelPtr = getCommunicationChannel();
+ LLCommunicationChannel *commChannel = dynamic_cast<LLCommunicationChannel*>(channelPtr.get());
+ llassert(commChannel != NULL);
+
+ LLNotifications& instance = LLNotifications::instance();
+ bool imToastExists = false;
+ bool offerExists = false;
+
+ for (LLCommunicationChannel::history_list_t::const_iterator it = commChannel->beginHistory();
+ it != commChannel->endHistory();
+ ++it)
+ {
+ LLNotificationPtr notification = it->second;
+ std::string notificationName = notification->getName();
+
+ if(notificationName == toastName)
+ {
+ imToastExists = true;
+ }
+ else if(notificationName == offerName)
+ {
+ offerExists = true;
+ }
+
+ //Notification already exists in notification pipeline (same instance of app running)
+ if (notification)
+ {
+ notification->setDND(true);
+ instance.update(notification);
+ }
+ }
+
+ if(imToastExists || offerExists)
+ {
+ make_ui_sound("UISndNewIncomingIMSession");
+ }
+
+ //When exit DND mode, write empty notifications file
+ if(commChannel->getHistorySize())
+ {
+ commChannel->clearHistory();
+ saveNotifications();
+ }
+}
+
+LLNotificationChannelPtr LLDoNotDisturbNotificationStorage::getCommunicationChannel() const
+{
+ LLNotificationChannelPtr channelPtr = LLNotifications::getInstance()->getChannel("Communication");
+ llassert(channelPtr);
+ return channelPtr;
+}
+
+void LLDoNotDisturbNotificationStorage::removeNotification(const char * name, const LLUUID& id)
+{
+ LLNotifications& instance = LLNotifications::instance();
+ LLNotificationChannelPtr channelPtr = getCommunicationChannel();
+ LLCommunicationChannel *commChannel = dynamic_cast<LLCommunicationChannel*>(channelPtr.get());
+ LLNotificationPtr notification;
+ LLSD payload;
+ LLUUID notificationObjectID;
+ std::string notificationName;
+ std::string payloadVariable = nameToPayloadParameterMap[name];
+ LLCommunicationChannel::history_list_t::iterator it;
+ std::vector<LLCommunicationChannel::history_list_t::iterator> itemsToRemove;
+
+ //Find notification with the matching session id
+ for (it = commChannel->beginHistory();
+ it != commChannel->endHistory();
+ ++it)
+ {
+ notification = it->second;
+ payload = notification->getPayload();
+ notificationObjectID = payload[payloadVariable].asUUID();
+ notificationName = notification->getName();
+
+ if((notificationName == name)
+ && id == notificationObjectID)
+ {
+ itemsToRemove.push_back(it);
+ }
+ }
+
+
+ //Remove the notifications
+ if(itemsToRemove.size())
+ {
+ while(itemsToRemove.size())
+ {
+ it = itemsToRemove.back();
+ notification = it->second;
+ commChannel->removeItemFromHistory(notification);
+ instance.cancel(notification);
+ itemsToRemove.pop_back();
+ }
+ //Trigger saving of notifications to xml once all have been removed
+ saveNotifications();
+ }
+}
+
+
+bool LLDoNotDisturbNotificationStorage::onChannelChanged(const LLSD& pPayload)
+{
+ if (pPayload["sigtype"].asString() != "load")
+ {
+ mDirty = true;
+ }
+
+ return false;
+}
diff --git a/indra/newview/lldonotdisturbnotificationstorage.h b/indra/newview/lldonotdisturbnotificationstorage.h
new file mode 100755
index 0000000000..6e68b0d1be
--- /dev/null
+++ b/indra/newview/lldonotdisturbnotificationstorage.h
@@ -0,0 +1,78 @@
+/**
+* @file lldonotdisturbnotificationstorage.h
+* @brief Header file for lldonotdisturbnotificationstorage
+* @author Stinson@lindenlab.com
+*
+* $LicenseInfo:firstyear=2012&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2012, 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_LLDONOTDISTURBNOTIFICATIONSTORAGE_H
+#define LL_LLDONOTDISTURBNOTIFICATIONSTORAGE_H
+
+#include "llerror.h"
+#include "lleventtimer.h"
+#include "llnotifications.h"
+#include "llnotificationstorage.h"
+#include "llsingleton.h"
+
+class LLSD;
+
+class LLDoNotDisturbNotificationStorageTimer : public LLEventTimer
+{
+public:
+ LLDoNotDisturbNotificationStorageTimer();
+ ~LLDoNotDisturbNotificationStorageTimer();
+
+public:
+ BOOL tick();
+};
+
+class LLDoNotDisturbNotificationStorage : public LLSingleton<LLDoNotDisturbNotificationStorage>, public LLNotificationStorage
+{
+ LOG_CLASS(LLDoNotDisturbNotificationStorage);
+public:
+ static const char * toastName;
+ static const char * offerName;
+
+ LLDoNotDisturbNotificationStorage();
+ ~LLDoNotDisturbNotificationStorage();
+
+ void initialize();
+ bool getDirty();
+ void resetDirty();
+ void saveNotifications();
+ void loadNotifications();
+ void updateNotifications();
+ void removeNotification(const char * name, const LLUUID& id);
+
+protected:
+
+private:
+ bool mDirty;
+ LLDoNotDisturbNotificationStorageTimer mTimer;
+
+ LLNotificationChannelPtr getCommunicationChannel() const;
+ bool onChannelChanged(const LLSD& pPayload);
+ std::map<std::string, std::string> nameToPayloadParameterMap;
+};
+
+#endif // LL_LLDONOTDISTURBNOTIFICATIONSTORAGE_H
+
diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp
index 21b21c152a..9682f38227 100644..100755
--- a/indra/newview/lldrawable.cpp
+++ b/indra/newview/lldrawable.cpp
@@ -57,6 +57,8 @@ const F32 MIN_SHADOW_CASTER_RADIUS = 2.0f;
static LLFastTimer::DeclareTimer FTM_CULL_REBOUND("Cull Rebound");
+extern bool gShiftFrame;
+
////////////////////////
//
@@ -97,7 +99,6 @@ void LLDrawable::init()
mPositionGroup.clear();
mExtents[0].clear();
mExtents[1].clear();
- mQuietCount = 0;
mState = 0;
mVObjp = NULL;
@@ -108,6 +109,8 @@ void LLDrawable::init()
mGeneration = -1;
mBinRadius = 1.f;
+ mBinIndex = -1;
+
mSpatialBridge = NULL;
}
@@ -129,10 +132,16 @@ void LLDrawable::destroy()
sNumZombieDrawables--;
}
+ // Attempt to catch violations of this in debug,
+ // knowing that some false alarms may result
+ //
+ llassert(!LLSpatialGroup::sNoDelete);
+
+ /* cannot be guaranteed and causes crashes on false alarms
if (LLSpatialGroup::sNoDelete)
{
llerrs << "Illegal deletion of LLDrawable!" << llendl;
- }
+ }*/
std::for_each(mFaces.begin(), mFaces.end(), DeletePointer());
mFaces.clear();
@@ -251,11 +260,17 @@ S32 LLDrawable::findReferences(LLDrawable *drawablep)
return count;
}
+static LLFastTimer::DeclareTimer FTM_ALLOCATE_FACE("Allocate Face", true);
+
LLFace* LLDrawable::addFace(LLFacePool *poolp, LLViewerTexture *texturep)
{
- LLMemType mt(LLMemType::MTYPE_DRAWABLE);
- LLFace *face = new LLFace(this, mVObjp);
+ LLFace *face;
+ {
+ LLFastTimer t(FTM_ALLOCATE_FACE);
+ face = new LLFace(this, mVObjp);
+ }
+
if (!face) llerrs << "Allocating new Face: " << mFaces.size() << llendl;
if (face)
@@ -277,10 +292,12 @@ LLFace* LLDrawable::addFace(LLFacePool *poolp, LLViewerTexture *texturep)
LLFace* LLDrawable::addFace(const LLTextureEntry *te, LLViewerTexture *texturep)
{
- LLMemType mt(LLMemType::MTYPE_DRAWABLE);
-
LLFace *face;
- face = new LLFace(this, mVObjp);
+
+ {
+ LLFastTimer t(FTM_ALLOCATE_FACE);
+ face = new LLFace(this, mVObjp);
+ }
face->setTEOffset(mFaces.size());
face->setTexture(texturep);
@@ -297,6 +314,49 @@ LLFace* LLDrawable::addFace(const LLTextureEntry *te, LLViewerTexture *texturep)
}
+LLFace* LLDrawable::addFace(const LLTextureEntry *te, LLViewerTexture *texturep, LLViewerTexture *normalp)
+{
+ LLFace *face;
+ face = new LLFace(this, mVObjp);
+
+ face->setTEOffset(mFaces.size());
+ face->setTexture(texturep);
+ face->setNormalMap(normalp);
+ face->setPoolType(gPipeline.getPoolTypeFromTE(te, texturep));
+
+ mFaces.push_back(face);
+
+ if (isState(UNLIT))
+ {
+ face->setState(LLFace::FULLBRIGHT);
+ }
+
+ return face;
+
+}
+
+LLFace* LLDrawable::addFace(const LLTextureEntry *te, LLViewerTexture *texturep, LLViewerTexture *normalp, LLViewerTexture *specularp)
+{
+ LLFace *face;
+ face = new LLFace(this, mVObjp);
+
+ face->setTEOffset(mFaces.size());
+ face->setTexture(texturep);
+ face->setNormalMap(normalp);
+ face->setSpecularMap(specularp);
+ face->setPoolType(gPipeline.getPoolTypeFromTE(te, texturep));
+
+ mFaces.push_back(face);
+
+ if (isState(UNLIT))
+ {
+ face->setState(LLFace::FULLBRIGHT);
+ }
+
+ return face;
+
+}
+
void LLDrawable::setNumFaces(const S32 newFaces, LLFacePool *poolp, LLViewerTexture *texturep)
{
if (newFaces == (S32)mFaces.size())
@@ -403,6 +463,8 @@ void LLDrawable::makeActive()
if (!isRoot() && !mParent->isActive())
{
mParent->makeActive();
+ //NOTE: linked set will now NEVER become static
+ mParent->setState(LLDrawable::ACTIVE_CHILD);
}
//all child objects must also be active
@@ -422,40 +484,26 @@ void LLDrawable::makeActive()
if (mVObjp->getPCode() == LL_PCODE_VOLUME)
{
- if (mVObjp->isFlexible())
- {
- return;
- }
- }
-
- if (mVObjp->getPCode() == LL_PCODE_VOLUME)
- {
gPipeline.markRebuild(this, LLDrawable::REBUILD_VOLUME, TRUE);
}
updatePartition();
}
- if (isRoot())
- {
- mQuietCount = 0;
- }
- else
- {
- getParent()->mQuietCount = 0;
- }
+ llassert(isAvatar() || isRoot() || mParent->isActive());
}
void LLDrawable::makeStatic(BOOL warning_enabled)
{
- if (isState(ACTIVE))
+ if (isState(ACTIVE) &&
+ !isState(ACTIVE_CHILD) &&
+ !mVObjp->isAttachment() &&
+ !mVObjp->isFlexible())
{
- clearState(ACTIVE);
+ clearState(ACTIVE | ANIMATED_CHILD);
- if (mParent.notNull() && mParent->isActive() && warning_enabled)
- {
- LL_WARNS_ONCE("Drawable") << "Drawable becomes static with active parent!" << LL_ENDL;
- }
+ //drawable became static with active parent, not acceptable
+ llassert(mParent.isNull() || !mParent->isActive() || !warning_enabled);
LLViewerObject::const_child_list_t& child_list = mVObjp->getChildren();
for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
@@ -483,8 +531,10 @@ void LLDrawable::makeStatic(BOOL warning_enabled)
mSpatialBridge->markDead();
setSpatialBridge(NULL);
}
+ updatePartition();
}
- updatePartition();
+
+ llassert(isAvatar() || isRoot() || mParent->isStatic());
}
// Returns "distance" between target destination and resulting xfrom
@@ -512,7 +562,6 @@ F32 LLDrawable::updateXform(BOOL undamped)
//scaling
LLVector3 target_scale = mVObjp->getScale();
LLVector3 old_scale = mCurrentScale;
- LLVector3 dest_scale = target_scale;
// Damping
F32 dist_squared = 0.f;
@@ -525,6 +574,7 @@ F32 LLDrawable::updateXform(BOOL undamped)
dist_squared = dist_vec_squared(new_pos, target_pos);
LLQuaternion new_rot = nlerp(lerp_amt, old_rot, target_rot);
+ // FIXME: This can be negative! It is be possible for some rots to 'cancel out' pos or size changes.
dist_squared += (1.f - dot(new_rot, target_rot)) * 10.f;
LLVector3 new_scale = lerp(old_scale, target_scale, lerp_amt);
@@ -538,9 +588,9 @@ F32 LLDrawable::updateXform(BOOL undamped)
target_rot = new_rot;
target_scale = new_scale;
}
- else
+ else if (mVObjp->getAngularVelocity().isExactlyZero())
{
- // snap to final position
+ // snap to final position (only if no target omega is applied)
dist_squared = 0.0f;
if (getVOVolume() && !isRoot())
{ //child prim snapping to some position, needs a rebuild
@@ -548,16 +598,41 @@ F32 LLDrawable::updateXform(BOOL undamped)
}
}
}
+ else
+ {
+ // The following fixes MAINT-1742 but breaks vehicles similar to MAINT-2275
+ // dist_squared = dist_vec_squared(old_pos, target_pos);
+
+ // The following fixes MAINT-2247 but causes MAINT-2275
+ //dist_squared += (1.f - dot(old_rot, target_rot)) * 10.f;
+ //dist_squared += dist_vec_squared(old_scale, target_scale);
+ }
- if ((mCurrentScale != target_scale) ||
- (!isRoot() &&
- (dist_squared >= MIN_INTERPOLATE_DISTANCE_SQUARED ||
- !mVObjp->getAngularVelocity().isExactlyZero() ||
- target_pos != mXform.getPosition() ||
- target_rot != mXform.getRotation())))
- { //child prim moving or scale change requires immediate rebuild
+ LLVector3 vec = mCurrentScale-target_scale;
+
+ if (vec*vec > MIN_INTERPOLATE_DISTANCE_SQUARED)
+ { //scale change requires immediate rebuild
+ mCurrentScale = target_scale;
gPipeline.markRebuild(this, LLDrawable::REBUILD_POSITION, TRUE);
}
+ else if (!isRoot() &&
+ (!mVObjp->getAngularVelocity().isExactlyZero() ||
+ dist_squared > 0.f))
+ { //child prim moving relative to parent, tag as needing to be rendered atomically and rebuild
+ dist_squared = 1.f; //keep this object on the move list
+ if (!isState(LLDrawable::ANIMATED_CHILD))
+ {
+ setState(LLDrawable::ANIMATED_CHILD);
+ gPipeline.markRebuild(this, LLDrawable::REBUILD_ALL, TRUE);
+ mVObjp->dirtySpatialGroup();
+ }
+ }
+ else if (!isRoot() &&
+ ((dist_vec_squared(old_pos, target_pos) > 0.f)
+ || (1.f - dot(old_rot, target_rot)) > 0.f))
+ { //fix for BUG-840, MAINT-2275, MAINT-1742, MAINT-2247
+ gPipeline.markRebuild(this, LLDrawable::REBUILD_POSITION, TRUE);
+ }
else if (!getVOVolume() && !isAvatar())
{
movePartition();
@@ -568,9 +643,7 @@ F32 LLDrawable::updateXform(BOOL undamped)
mXform.setRotation(target_rot);
mXform.setScale(LLVector3(1,1,1)); //no scale in drawable transforms (IT'S A RULE!)
mXform.updateMatrix();
-
- mCurrentScale = target_scale;
-
+
if (mSpatialBridge)
{
gPipeline.markMoved(mSpatialBridge, FALSE);
@@ -596,7 +669,11 @@ void LLDrawable::moveUpdatePipeline(BOOL moved)
// Update the face centers.
for (S32 i = 0; i < getNumFaces(); i++)
{
- getFace(i)->updateCenterAgent();
+ LLFace* face = getFace(i);
+ if (face)
+ {
+ face->updateCenterAgent();
+ }
}
}
@@ -623,18 +700,8 @@ BOOL LLDrawable::updateMove()
}
makeActive();
-
- BOOL done;
- if (isState(MOVE_UNDAMPED))
- {
- done = updateMoveUndamped();
- }
- else
- {
- done = updateMoveDamped();
- }
- return done;
+ return isState(MOVE_UNDAMPED) ? updateMoveUndamped() : updateMoveDamped();
}
BOOL LLDrawable::updateMoveUndamped()
@@ -651,7 +718,6 @@ BOOL LLDrawable::updateMoveUndamped()
}
mVObjp->clearChanged(LLXform::MOVED);
-
return TRUE;
}
@@ -703,6 +769,11 @@ void LLDrawable::updateDistance(LLCamera& camera, bool force_update)
return;
}
+ if (gShiftFrame)
+ {
+ return;
+ }
+
//switch LOD with the spatial group to avoid artifacts
//LLSpatialGroup* sg = getSpatialGroup();
@@ -727,7 +798,8 @@ void LLDrawable::updateDistance(LLCamera& camera, bool force_update)
for (S32 i = 0; i < getNumFaces(); i++)
{
LLFace* facep = getFace(i);
- if (force_update || facep->getPoolType() == LLDrawPool::POOL_ALPHA)
+ if (facep &&
+ (force_update || facep->getPoolType() == LLDrawPool::POOL_ALPHA))
{
LLVector4a box;
box.setSub(facep->mExtents[1], facep->mExtents[0]);
@@ -756,8 +828,6 @@ void LLDrawable::updateDistance(LLCamera& camera, bool force_update)
void LLDrawable::updateTexture()
{
- LLMemType mt(LLMemType::MTYPE_DRAWABLE);
-
if (isDead())
{
llwarns << "Dead drawable updating texture!" << llendl;
@@ -771,18 +841,6 @@ void LLDrawable::updateTexture()
if (getVOVolume())
{
- /*if (isActive())
- {
- if (isRoot())
- {
- mQuietCount = 0;
- }
- else
- {
- getParent()->mQuietCount = 0;
- }
- }*/
-
gPipeline.markRebuild(this, LLDrawable::REBUILD_MATERIAL, TRUE);
}
}
@@ -811,14 +869,19 @@ void LLDrawable::shiftPos(const LLVector4a &shift_vector)
mXform.setPosition(mVObjp->getPositionAgent());
}
- mXform.setRotation(mVObjp->getRotation());
- mXform.setScale(1,1,1);
mXform.updateMatrix();
if (isStatic())
{
LLVOVolume* volume = getVOVolume();
- if (!volume)
+
+ bool rebuild = (!volume &&
+ getRenderType() != LLPipeline::RENDER_TYPE_TREE &&
+ getRenderType() != LLPipeline::RENDER_TYPE_TERRAIN &&
+ getRenderType() != LLPipeline::RENDER_TYPE_SKY &&
+ getRenderType() != LLPipeline::RENDER_TYPE_GROUND);
+
+ if (rebuild)
{
gPipeline.markRebuild(this, LLDrawable::REBUILD_ALL, TRUE);
}
@@ -826,13 +889,16 @@ void LLDrawable::shiftPos(const LLVector4a &shift_vector)
for (S32 i = 0; i < getNumFaces(); i++)
{
LLFace *facep = getFace(i);
- facep->mCenterAgent += LLVector3(shift_vector.getF32ptr());
- facep->mExtents[0].add(shift_vector);
- facep->mExtents[1].add(shift_vector);
-
- if (!volume && facep->hasGeometry())
+ if (facep)
{
- facep->clearVertexBuffer();
+ facep->mCenterAgent += LLVector3(shift_vector.getF32ptr());
+ facep->mExtents[0].add(shift_vector);
+ facep->mExtents[1].add(shift_vector);
+
+ if (rebuild && facep->hasGeometry())
+ {
+ facep->clearVertexBuffer();
+ }
}
}
@@ -940,8 +1006,20 @@ void LLDrawable::updateUVMinMax()
{
}
+LLSpatialGroup* LLDrawable::getSpatialGroup() const
+{
+ llassert((mSpatialGroupp == NULL) ? getBinIndex() == -1 : getBinIndex() != -1);
+ return mSpatialGroupp;
+}
+
void LLDrawable::setSpatialGroup(LLSpatialGroup *groupp)
{
+ //precondition: mSpatialGroupp MUST be null or DEAD or mSpatialGroupp MUST NOT contain this
+ llassert(!mSpatialGroupp || mSpatialGroupp->isDead() || !mSpatialGroupp->hasElement(this));
+
+ //precondition: groupp MUST be null or groupp MUST contain this
+ llassert(!groupp || groupp->hasElement(this));
+
/*if (mSpatialGroupp && (groupp != mSpatialGroupp))
{
mSpatialGroupp->setState(LLSpatialGroup::GEOM_DIRTY);
@@ -954,10 +1032,18 @@ void LLDrawable::setSpatialGroup(LLSpatialGroup *groupp)
for (S32 i = 0; i < getNumFaces(); ++i)
{
LLFace* facep = getFace(i);
- facep->clearVertexBuffer();
+ if (facep)
+ {
+ facep->clearVertexBuffer();
+ }
}
}
+ //postcondition: if next group is NULL, previous group must be dead OR NULL OR binIndex must be -1
+ //postcondition: if next group is NOT NULL, binIndex must not be -1
+ llassert(groupp == NULL ? (mSpatialGroupp == NULL || mSpatialGroupp->isDead()) || getBinIndex() == -1 :
+ getBinIndex() != -1);
+
mSpatialGroupp = groupp;
}
@@ -1081,6 +1167,8 @@ LLSpatialBridge::LLSpatialBridge(LLDrawable* root, BOOL render_by_group, U32 dat
mDrawable = root;
root->setSpatialBridge(this);
+ mBinIndex = -1;
+
mRenderType = mDrawable->mRenderType;
mDrawableType = mDrawable->mRenderType;
@@ -1199,7 +1287,6 @@ LLCamera LLSpatialBridge::transformCamera(LLCamera& camera)
LLCamera ret = camera;
LLXformMatrix* mat = mDrawable->getXform();
LLVector3 center = LLVector3(0,0,0) * mat->getWorldMatrix();
- LLQuaternion rotation = LLQuaternion(mat->getWorldMatrix());
LLVector3 delta = ret.getOrigin() - center;
LLQuaternion rot = ~mat->getRotation();
@@ -1385,6 +1472,11 @@ void LLSpatialBridge::updateDistance(LLCamera& camera_in, bool force_update)
return;
}
+ if (gShiftFrame)
+ {
+ return;
+ }
+
if (mDrawable->getVObj())
{
if (mDrawable->getVObj()->isAttachment())
@@ -1462,6 +1554,10 @@ void LLSpatialBridge::cleanupReferences()
LLDrawable::cleanupReferences();
if (mDrawable)
{
+ /*
+
+ DON'T DO THIS -- this should happen through octree destruction
+
mDrawable->setSpatialGroup(NULL);
if (mDrawable->getVObj())
{
@@ -1476,7 +1572,7 @@ void LLSpatialBridge::cleanupReferences()
drawable->setSpatialGroup(NULL);
}
}
- }
+ }*/
LLDrawable* drawablep = mDrawable;
mDrawable = NULL;
@@ -1529,10 +1625,10 @@ BOOL LLDrawable::isAnimating() const
return TRUE;
}
- if (!isRoot() && !mVObjp->getAngularVelocity().isExactlyZero())
- {
+ /*if (!isRoot() && !mVObjp->getAngularVelocity().isExactlyZero())
+ { //target omega
return TRUE;
- }
+ }*/
return FALSE;
}
diff --git a/indra/newview/lldrawable.h b/indra/newview/lldrawable.h
index e268640a21..c3f6d77edc 100644..100755
--- a/indra/newview/lldrawable.h
+++ b/indra/newview/lldrawable.h
@@ -38,7 +38,6 @@
#include "llvector4a.h"
#include "llquaternion.h"
#include "xform.h"
-#include "llmemtype.h"
#include "lldarray.h"
#include "llviewerobject.h"
#include "llrect.h"
@@ -59,6 +58,7 @@ class LLViewerTexture;
const U32 SILHOUETTE_HIGHLIGHT = 0;
// All data for new renderer goes into this class.
+LL_ALIGN_PREFIX(16)
class LLDrawable : public LLRefCount
{
public:
@@ -75,8 +75,17 @@ public:
static void initClass();
+ void* operator new(size_t size)
+ {
+ return ll_aligned_malloc_16(size);
+ }
+
+ void operator delete(void* ptr)
+ {
+ ll_aligned_free_16(ptr);
+ }
+
LLDrawable() { init(); }
- MEM_TYPE_NEW(LLMemType::MTYPE_DRAWABLE);
void markDead(); // Mark this drawable as dead
BOOL isDead() const { return isState(DEAD); }
@@ -109,6 +118,9 @@ public:
F32 getIntensity() const { return llmin(mXform.getScale().mV[0], 4.f); }
S32 getLOD() const { return mVObjp ? mVObjp->getLOD() : 1; }
F32 getBinRadius() const { return mBinRadius; }
+ S32 getBinIndex() const { return mBinIndex; }
+ void setBinIndex(S32 index) const { mBinIndex = index; }
+
void getMinMax(LLVector3& min,LLVector3& max) const { mXform.getMinMax(min,max); }
LLXformMatrix* getXform() { return &mXform; }
@@ -133,6 +145,8 @@ public:
//void removeFace(const S32 i); // SJB: Avoid using this, it's slow
LLFace* addFace(LLFacePool *poolp, LLViewerTexture *texturep);
LLFace* addFace(const LLTextureEntry *te, LLViewerTexture *texturep);
+ LLFace* addFace(const LLTextureEntry *te, LLViewerTexture *texturep, LLViewerTexture *normalp);
+ LLFace* addFace(const LLTextureEntry *te, LLViewerTexture *texturep, LLViewerTexture *normalp, LLViewerTexture *specularp);
void deleteFaces(S32 offset, S32 count);
void setNumFaces(const S32 numFaces, LLFacePool *poolp, LLViewerTexture *texturep);
void setNumFacesFast(const S32 numFaces, LLFacePool *poolp, LLViewerTexture *texturep);
@@ -194,7 +208,7 @@ public:
S32 findReferences(LLDrawable *drawablep); // Not const because of @#$! iterators...
void setSpatialGroup(LLSpatialGroup *groupp);
- LLSpatialGroup *getSpatialGroup() const { return mSpatialGroupp; }
+ LLSpatialGroup *getSpatialGroup() const;
LLSpatialPartition* getSpatialPartition();
// Statics
@@ -272,16 +286,17 @@ public:
NEARBY_LIGHT = 0x00200000, // In gPipeline.mNearbyLightSet
BUILT = 0x00400000,
FORCE_INVISIBLE = 0x00800000, // stay invis until CLEAR_INVISIBLE is set (set of orphaned)
- CLEAR_INVISIBLE = 0x01000000, // clear FORCE_INVISIBLE next draw frame
REBUILD_SHADOW = 0x02000000,
HAS_ALPHA = 0x04000000,
RIGGED = 0x08000000,
PARTITION_MOVE = 0x10000000,
+ ANIMATED_CHILD = 0x20000000,
+ ACTIVE_CHILD = 0x40000000,
} EDrawableFlags;
private: //aligned members
- LLVector4a mExtents[2];
- LLVector4a mPositionGroup;
+ LL_ALIGN_16(LLVector4a mExtents[2]);
+ LL_ALIGN_16(LLVector4a mPositionGroup);
public:
LLXformMatrix mXform;
@@ -290,8 +305,6 @@ public:
LLPointer<LLDrawable> mParent;
F32 mDistanceWRTCamera;
-
- S32 mQuietCount;
static S32 getCurrentFrame() { return sCurVisible; }
static S32 getMinVisFrameRange();
@@ -314,6 +327,7 @@ private:
mutable U32 mVisible;
F32 mRadius;
F32 mBinRadius;
+ mutable S32 mBinIndex;
S32 mGeneration;
LLVector3 mCurrentScale;
@@ -322,7 +336,7 @@ private:
static U32 sNumZombieDrawables;
static LLDynamicArrayPtr<LLPointer<LLDrawable> > sDeadList;
-};
+} LL_ALIGN_POSTFIX(16);
inline LLFace* LLDrawable::getFace(const S32 i) const
@@ -333,12 +347,14 @@ inline LLFace* LLDrawable::getFace(const S32 i) const
if ((U32) i >= mFaces.size())
{
- llerrs << "Invalid face index." << llendl;
+ llwarns << "Invalid face index." << llendl;
+ return NULL;
}
if (!mFaces[i])
{
- llerrs << "Null face found." << llendl;
+ llwarns << "Null face found." << llendl;
+ return NULL;
}
return mFaces[i];
diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp
index 35f8a85796..714f9a1718 100644..100755
--- a/indra/newview/lldrawpool.cpp
+++ b/indra/newview/lldrawpool.cpp
@@ -35,6 +35,7 @@
#include "lldrawpoolalpha.h"
#include "lldrawpoolavatar.h"
#include "lldrawpoolbump.h"
+#include "lldrawpoolmaterials.h"
#include "lldrawpoolground.h"
#include "lldrawpoolsimple.h"
#include "lldrawpoolsky.h"
@@ -47,6 +48,7 @@
#include "llspatialpartition.h"
#include "llviewercamera.h"
#include "lldrawpoolwlsky.h"
+#include "llglslshader.h"
S32 LLDrawPool::sNumDrawPools = 0;
@@ -64,6 +66,12 @@ LLDrawPool *LLDrawPool::createPool(const U32 type, LLViewerTexture *tex0)
case POOL_GRASS:
poolp = new LLDrawPoolGrass();
break;
+ case POOL_ALPHA_MASK:
+ poolp = new LLDrawPoolAlphaMask();
+ break;
+ case POOL_FULLBRIGHT_ALPHA_MASK:
+ poolp = new LLDrawPoolFullbrightAlphaMask();
+ break;
case POOL_FULLBRIGHT:
poolp = new LLDrawPoolFullbright();
break;
@@ -98,6 +106,9 @@ LLDrawPool *LLDrawPool::createPool(const U32 type, LLViewerTexture *tex0)
case POOL_BUMP:
poolp = new LLDrawPoolBump();
break;
+ case POOL_MATERIALS:
+ poolp = new LLDrawPoolMaterials();
+ break;
case POOL_WL_SKY:
poolp = new LLDrawPoolWLSky();
break;
@@ -116,6 +127,7 @@ LLDrawPool::LLDrawPool(const U32 type)
sNumDrawPools++;
mId = sNumDrawPools;
mVertexShaderLevel = 0;
+ mSkipRender = false;
}
LLDrawPool::~LLDrawPool()
@@ -253,48 +265,6 @@ void LLFacePool::dirtyTextures(const std::set<LLViewerFetchedTexture*>& textures
{
}
-// static
-S32 LLFacePool::drawLoop(face_array_t& face_list)
-{
- S32 res = 0;
- if (!face_list.empty())
- {
- for (std::vector<LLFace*>::iterator iter = face_list.begin();
- iter != face_list.end(); iter++)
- {
- LLFace *facep = *iter;
- res += facep->renderIndexed();
- }
- }
- return res;
-}
-
-// static
-S32 LLFacePool::drawLoopSetTex(face_array_t& face_list, S32 stage)
-{
- S32 res = 0;
- if (!face_list.empty())
- {
- for (std::vector<LLFace*>::iterator iter = face_list.begin();
- iter != face_list.end(); iter++)
- {
- LLFace *facep = *iter;
- gGL.getTexUnit(stage)->bind(facep->getTexture(), TRUE) ;
- gGL.getTexUnit(0)->activate();
- res += facep->renderIndexed();
- }
- }
- return res;
-}
-
-void LLFacePool::drawLoop()
-{
- if (!mDrawFace.empty())
- {
- drawLoop(mDrawFace);
- }
-}
-
void LLFacePool::enqueue(LLFace* facep)
{
mDrawFace.push_back(facep);
@@ -442,11 +412,32 @@ void LLRenderPass::renderTexture(U32 type, U32 mask)
void LLRenderPass::pushBatches(U32 type, U32 mask, BOOL texture, BOOL batch_textures)
{
- for (LLCullResult::drawinfo_list_t::iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i)
+ for (LLCullResult::drawinfo_iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i)
+ {
+ LLDrawInfo* pparams = *i;
+ if (pparams)
+ {
+ pushBatch(*pparams, mask, texture, batch_textures);
+ }
+ }
+}
+
+void LLRenderPass::pushMaskBatches(U32 type, U32 mask, BOOL texture, BOOL batch_textures)
+{
+ for (LLCullResult::drawinfo_iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i)
{
LLDrawInfo* pparams = *i;
if (pparams)
{
+ if (LLGLSLShader::sCurBoundShaderPtr)
+ {
+ LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(pparams->mAlphaMaskCutoff);
+ }
+ else
+ {
+ gGL.setAlphaRejectSettings(LLRender::CF_GREATER, pparams->mAlphaMaskCutoff);
+ }
+
pushBatch(*pparams, mask, texture, batch_textures);
}
}
@@ -460,6 +451,7 @@ void LLRenderPass::applyModelMatrix(LLDrawInfo& params)
gGL.loadMatrix(gGLModelView);
if (params.mModelMatrix)
{
+ llassert(gGL.getMatrixMode() == LLRender::MM_MODELVIEW);
gGL.multMatrix((GLfloat*) params.mModelMatrix->mMatrix);
}
gPipeline.mMatrixOpCount++;
@@ -512,6 +504,7 @@ void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL ba
{
params.mGroup->rebuildMesh();
}
+
params.mVertexBuffer->setBuffer(mask);
params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode);
diff --git a/indra/newview/lldrawpool.h b/indra/newview/lldrawpool.h
index 64774d06df..3bde0d29be 100644..100755
--- a/indra/newview/lldrawpool.h
+++ b/indra/newview/lldrawpool.h
@@ -50,10 +50,13 @@ public:
POOL_GROUND,
POOL_FULLBRIGHT,
POOL_BUMP,
+ POOL_MATERIALS,
POOL_TERRAIN,
POOL_SKY,
POOL_WL_SKY,
POOL_TREE,
+ POOL_ALPHA_MASK,
+ POOL_FULLBRIGHT_ALPHA_MASK,
POOL_GRASS,
POOL_INVISIBLE, // see below *
POOL_AVATAR,
@@ -77,6 +80,9 @@ public:
S32 getId() const { return mId; }
U32 getType() const { return mType; }
+ BOOL getSkipRenderFlag() const { return mSkipRender;}
+ void setSkipRenderFlag( BOOL flag ) { mSkipRender = flag; }
+
virtual LLViewerTexture *getDebugTexture();
virtual void beginRenderPass( S32 pass );
virtual void endRenderPass( S32 pass );
@@ -113,6 +119,7 @@ protected:
S32 mVertexShaderLevel;
S32 mId;
U32 mType; // Type of draw pool
+ BOOL mSkipRender;
};
class LLRenderPass : public LLDrawPool
@@ -129,6 +136,22 @@ public:
PASS_SHINY,
PASS_BUMP,
PASS_POST_BUMP,
+ PASS_MATERIAL,
+ PASS_MATERIAL_ALPHA,
+ PASS_MATERIAL_ALPHA_MASK,
+ PASS_MATERIAL_ALPHA_EMISSIVE,
+ PASS_SPECMAP,
+ PASS_SPECMAP_BLEND,
+ PASS_SPECMAP_MASK,
+ PASS_SPECMAP_EMISSIVE,
+ PASS_NORMMAP,
+ PASS_NORMMAP_BLEND,
+ PASS_NORMMAP_MASK,
+ PASS_NORMMAP_EMISSIVE,
+ PASS_NORMSPEC,
+ PASS_NORMSPEC_BLEND,
+ PASS_NORMSPEC_MASK,
+ PASS_NORMSPEC_EMISSIVE,
PASS_GLOW,
PASS_ALPHA,
PASS_ALPHA_MASK,
@@ -147,6 +170,7 @@ public:
static void applyModelMatrix(LLDrawInfo& params);
virtual void pushBatches(U32 type, U32 mask, BOOL texture = TRUE, BOOL batch_textures = FALSE);
+ virtual void pushMaskBatches(U32 type, U32 mask, BOOL texture = TRUE, BOOL batch_textures = FALSE);
virtual void pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures = FALSE);
virtual void renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture = TRUE);
virtual void renderGroups(U32 type, U32 mask, BOOL texture = TRUE);
@@ -186,10 +210,6 @@ public:
void buildEdges();
- static S32 drawLoop(face_array_t& face_list);
- static S32 drawLoopSetTex(face_array_t& face_list, S32 stage);
- void drawLoop();
-
void addFaceReference(LLFace *facep);
void removeFaceReference(LLFace *facep);
diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp
index 5b62dbc560..e27dc279f4 100644..100755
--- a/indra/newview/lldrawpoolalpha.cpp
+++ b/indra/newview/lldrawpoolalpha.cpp
@@ -71,33 +71,6 @@ void LLDrawPoolAlpha::prerender()
mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
}
-S32 LLDrawPoolAlpha::getNumDeferredPasses()
-{
- return 1;
-}
-
-void LLDrawPoolAlpha::beginDeferredPass(S32 pass)
-{
-
-}
-
-void LLDrawPoolAlpha::endDeferredPass(S32 pass)
-{
-
-}
-
-void LLDrawPoolAlpha::renderDeferred(S32 pass)
-{
- LLFastTimer t(FTM_RENDER_GRASS);
- gDeferredDiffuseAlphaMaskProgram.bind();
- gDeferredDiffuseAlphaMaskProgram.setMinimumAlpha(0.33f);
-
- //render alpha masked objects
- LLRenderPass::pushBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
- gDeferredDiffuseAlphaMaskProgram.unbind();
-}
-
-
S32 LLDrawPoolAlpha::getNumPostDeferredPasses()
{
if (LLPipeline::sImpostorRender)
@@ -120,25 +93,63 @@ void LLDrawPoolAlpha::beginPostDeferredPass(S32 pass)
if (pass == 0)
{
+ if (LLPipeline::sImpostorRender)
+ {
+ simple_shader = &gDeferredAlphaImpostorProgram;
+ fullbright_shader = &gDeferredFullbrightProgram;
+ }
+ else if (LLPipeline::sUnderWaterRender)
+ {
+ simple_shader = &gDeferredAlphaWaterProgram;
+ fullbright_shader = &gDeferredFullbrightWaterProgram;
+ }
+ else
+ {
simple_shader = &gDeferredAlphaProgram;
- fullbright_shader = &gObjectFullbrightAlphaMaskProgram;
+ fullbright_shader = &gDeferredFullbrightProgram;
+ }
+
+ F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma");
+
+ fullbright_shader->bind();
+ fullbright_shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
+ fullbright_shader->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f));
+ fullbright_shader->unbind();
//prime simple shader (loads shadow relevant uniforms)
gPipeline.bindDeferredShader(*simple_shader);
+
+ simple_shader->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f));
}
- else
+ else if (!LLPipeline::sImpostorRender)
{
//update depth buffer sampler
gPipeline.mScreen.flush();
gPipeline.mDeferredDepth.copyContents(gPipeline.mDeferredScreen, 0, 0, gPipeline.mDeferredScreen.getWidth(), gPipeline.mDeferredScreen.getHeight(),
0, 0, gPipeline.mDeferredDepth.getWidth(), gPipeline.mDeferredDepth.getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST);
gPipeline.mDeferredDepth.bindTarget();
- simple_shader = NULL;
- fullbright_shader = NULL;
+ simple_shader = fullbright_shader = &gObjectFullbrightAlphaMaskProgram;
gObjectFullbrightAlphaMaskProgram.bind();
gObjectFullbrightAlphaMaskProgram.setMinimumAlpha(0.33f);
}
+
+ if (LLPipeline::sRenderDeferred)
+ {
+ emissive_shader = &gDeferredEmissiveProgram;
+ }
+ else
+ {
+ if (LLPipeline::sUnderWaterRender)
+ {
+ emissive_shader = &gObjectEmissiveWaterProgram;
+ }
+ else
+ {
+ emissive_shader = &gObjectEmissiveProgram;
+ }
+ }
+
deferred_render = TRUE;
if (mVertexShaderLevel > 0)
{
@@ -150,8 +161,7 @@ void LLDrawPoolAlpha::beginPostDeferredPass(S32 pass)
void LLDrawPoolAlpha::endPostDeferredPass(S32 pass)
{
-
- if (pass == 1)
+ if (pass == 1 && !LLPipeline::sImpostorRender)
{
gPipeline.mDeferredDepth.flush();
gPipeline.mScreen.bindTarget();
@@ -171,16 +181,22 @@ void LLDrawPoolAlpha::beginRenderPass(S32 pass)
{
LLFastTimer t(FTM_RENDER_ALPHA);
- if (LLPipeline::sUnderWaterRender)
+ if (LLPipeline::sImpostorRender)
{
- simple_shader = &gObjectSimpleWaterAlphaMaskProgram;
- fullbright_shader = &gObjectFullbrightWaterAlphaMaskProgram;
+ simple_shader = &gObjectSimpleImpostorProgram;
+ fullbright_shader = &gObjectFullbrightProgram;
+ emissive_shader = &gObjectEmissiveProgram;
+ }
+ else if (LLPipeline::sUnderWaterRender)
+ {
+ simple_shader = &gObjectSimpleWaterProgram;
+ fullbright_shader = &gObjectFullbrightWaterProgram;
emissive_shader = &gObjectEmissiveWaterProgram;
}
else
{
- simple_shader = &gObjectSimpleAlphaMaskProgram;
- fullbright_shader = &gObjectFullbrightAlphaMaskProgram;
+ simple_shader = &gObjectSimpleProgram;
+ fullbright_shader = &gObjectFullbrightProgram;
emissive_shader = &gObjectEmissiveProgram;
}
@@ -218,45 +234,14 @@ void LLDrawPoolAlpha::render(S32 pass)
{
gGL.setColorMask(true, true);
}
+
+ bool write_depth = LLDrawPoolWater::sSkipScreenCopy
+ || (deferred_render && pass == 1)
+ // we want depth written so that rendered alpha will
+ // contribute to the alpha mask used for impostors
+ || LLPipeline::sImpostorRenderAlphaDepthPass;
- if (LLPipeline::sAutoMaskAlphaNonDeferred)
- {
- mColorSFactor = LLRender::BF_ONE; // }
- mColorDFactor = LLRender::BF_ZERO; // } these are like disabling blend on the color channels, but we're still blending on the alpha channel so that we can suppress glow
- mAlphaSFactor = LLRender::BF_ZERO;
- mAlphaDFactor = LLRender::BF_ZERO; // block (zero-out) glow where the alpha test succeeds
- gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor);
-
- if (mVertexShaderLevel > 0)
- {
- if (!LLPipeline::sRenderDeferred || !deferred_render)
- {
- simple_shader->bind();
- simple_shader->setMinimumAlpha(0.33f);
-
- pushBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
- }
- if (fullbright_shader)
- {
- fullbright_shader->bind();
- fullbright_shader->setMinimumAlpha(0.33f);
- }
- pushBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
- //LLGLSLShader::bindNoShader();
- }
- else
- {
- gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.33f); //OK
- gPipeline.enableLightsFullbright(LLColor4(1,1,1,1));
- pushBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, getVertexDataMask());
- gPipeline.enableLightsDynamic();
- pushBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask());
- gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); //OK
- }
- }
-
- LLGLDepthTest depth(GL_TRUE, LLDrawPoolWater::sSkipScreenCopy ||
- (deferred_render && pass == 1) ? GL_TRUE : GL_FALSE);
+ LLGLDepthTest depth(GL_TRUE, write_depth ? GL_TRUE : GL_FALSE);
if (deferred_render && pass == 1)
{
@@ -302,11 +287,11 @@ void LLDrawPoolAlpha::render(S32 pass)
if (mVertexShaderLevel > 0)
{
- renderAlpha(getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX);
+ renderAlpha(getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2, pass);
}
else
{
- renderAlpha(getVertexDataMask());
+ renderAlpha(getVertexDataMask(), pass);
}
gGL.setColorMask(true, false);
@@ -348,7 +333,7 @@ void LLDrawPoolAlpha::render(S32 pass)
void LLDrawPoolAlpha::renderAlphaHighlight(U32 mask)
{
- for (LLCullResult::sg_list_t::iterator i = gPipeline.beginAlphaGroups(); i != gPipeline.endAlphaGroups(); ++i)
+ for (LLCullResult::sg_iterator i = gPipeline.beginAlphaGroups(); i != gPipeline.endAlphaGroups(); ++i)
{
LLSpatialGroup* group = *i;
if (group->mSpatialPartition->mRenderByGroup &&
@@ -378,14 +363,14 @@ void LLDrawPoolAlpha::renderAlphaHighlight(U32 mask)
}
}
-void LLDrawPoolAlpha::renderAlpha(U32 mask)
+void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
{
BOOL initialized_lighting = FALSE;
BOOL light_enabled = TRUE;
BOOL use_shaders = gPipeline.canUseVertexShaders();
- for (LLCullResult::sg_list_t::iterator i = gPipeline.beginAlphaGroups(); i != gPipeline.endAlphaGroups(); ++i)
+ for (LLCullResult::sg_iterator i = gPipeline.beginAlphaGroups(); i != gPipeline.endAlphaGroups(); ++i)
{
LLSpatialGroup* group = *i;
llassert(group);
@@ -394,10 +379,16 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)
if (group->mSpatialPartition->mRenderByGroup &&
!group->isDead())
{
- bool draw_glow_for_this_partition = mVertexShaderLevel > 0 && // no shaders = no glow.
- // All particle systems seem to come off the wire with texture entries which claim that they glow. This is probably a bug in the data. Suppress.
- group->mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_PARTICLE &&
- group->mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_HUD_PARTICLE;
+ bool is_particle_or_hud_particle = group->mSpatialPartition->mPartitionType == LLViewerRegion::PARTITION_PARTICLE
+ || group->mSpatialPartition->mPartitionType == LLViewerRegion::PARTITION_HUD_PARTICLE;
+
+ bool draw_glow_for_this_partition = mVertexShaderLevel > 0; // no shaders = no glow.
+
+ static LLFastTimer::DeclareTimer FTM_RENDER_ALPHA_GROUP_LOOP("Alpha Group");
+ LLFastTimer t(FTM_RENDER_ALPHA_GROUP_LOOP);
+
+ bool disable_cull = is_particle_or_hud_particle;
+ LLGLDisable cull(disable_cull ? GL_CULL_FACE : 0);
LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[LLRenderPass::PASS_ALPHA];
@@ -405,9 +396,38 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)
{
LLDrawInfo& params = **k;
- LLRenderPass::applyModelMatrix(params);
+ if ((params.mVertexBuffer->getTypeMask() & mask) != mask)
+ { //FIXME!
+ llwarns << "Missing required components, skipping render batch." << llendl;
+ continue;
+ }
+ // Fix for bug - NORSPEC-271
+ // If the face is more than 90% transparent, then don't update the Depth buffer for Dof
+ // We don't want the nearly invisible objects to cause of DoF effects
+ if(pass == 1 && !LLPipeline::sImpostorRender)
+ {
+ LLFace* face = params.mFace;
+ if(face)
+ {
+ const LLTextureEntry* tep = face->getTextureEntry();
+ if(tep)
+ {
+ if(tep->getColor().mV[3] < 0.1f)
+ continue;
+ }
+ }
+ }
+
+ LLRenderPass::applyModelMatrix(params);
+ LLMaterial* mat = NULL;
+
+ if (deferred_render)
+ {
+ mat = params.mMaterial;
+ }
+
if (params.mFullbright)
{
// Turn off lighting if it hasn't already been so.
@@ -440,11 +460,35 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)
light_enabled = TRUE;
}
- // If we need shaders, and we're not ALREADY using the proper shader, then bind it
- // (this way we won't rebind shaders unnecessarily).
- if(use_shaders && (current_shader != target_shader))
+ if (deferred_render && mat)
{
- llassert(target_shader != NULL);
+ U32 mask = params.mShaderMask;
+
+ llassert(mask < LLMaterial::SHADER_COUNT);
+ target_shader = &(gDeferredMaterialProgram[mask]);
+
+ if (LLPipeline::sUnderWaterRender)
+ {
+ target_shader = &(gDeferredMaterialWaterProgram[mask]);
+ }
+
+ if (current_shader != target_shader)
+ {
+ gPipeline.bindDeferredShader(*target_shader);
+ }
+ }
+ else if (!params.mFullbright)
+ {
+ target_shader = simple_shader;
+ }
+ else
+ {
+ target_shader = fullbright_shader;
+ }
+
+ if(use_shaders && (current_shader != target_shader))
+ {// If we need shaders, and we're not ALREADY using the proper shader, then bind it
+ // (this way we won't rebind shaders unnecessarily).
current_shader = target_shader;
current_shader->bind();
}
@@ -453,6 +497,38 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)
LLGLSLShader::bindNoShader();
current_shader = NULL;
}
+
+ if (use_shaders && mat)
+ {
+ // We have a material. Supply the appropriate data here.
+ if (LLPipeline::sRenderDeferred)
+ {
+ current_shader->uniform4f(LLShaderMgr::SPECULAR_COLOR, params.mSpecColor.mV[0], params.mSpecColor.mV[1], params.mSpecColor.mV[2], params.mSpecColor.mV[3]);
+ current_shader->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, params.mEnvIntensity);
+ current_shader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, params.mFullbright ? 1.f : 0.f);
+
+ if (params.mNormalMap)
+ {
+ params.mNormalMap->addTextureStats(params.mVSize);
+ current_shader->bindTexture(LLShaderMgr::BUMP_MAP, params.mNormalMap);
+ }
+
+ if (params.mSpecularMap)
+ {
+ params.mSpecularMap->addTextureStats(params.mVSize);
+ current_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, params.mSpecularMap);
+ }
+ }
+
+ } else if (LLPipeline::sRenderDeferred && current_shader && (current_shader == simple_shader))
+ {
+ current_shader->uniform4f(LLShaderMgr::SPECULAR_COLOR, 1.0f, 1.0f, 1.0f, 1.0f);
+ current_shader->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, 0.0f);
+ LLViewerFetchedTexture::sFlatNormalImagep->addTextureStats(params.mVSize);
+ current_shader->bindTexture(LLShaderMgr::BUMP_MAP, LLViewerFetchedTexture::sFlatNormalImagep);
+ LLViewerFetchedTexture::sWhiteImagep->addTextureStats(params.mVSize);
+ current_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, LLViewerFetchedTexture::sWhiteImagep);
+ }
if (params.mGroup)
{
@@ -471,12 +547,20 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)
}
}
}
- else
+ else
{ //not batching textures or batch has only 1 texture -- might need a texture matrix
if (params.mTexture.notNull())
{
params.mTexture->addTextureStats(params.mVSize);
- gGL.getTexUnit(0)->bind(params.mTexture, TRUE) ;
+ if (use_shaders && mat)
+ {
+ current_shader->bindTexture(LLShaderMgr::DIFFUSE_MAP, params.mTexture);
+ }
+ else
+ {
+ gGL.getTexUnit(0)->bind(params.mTexture, TRUE);
+ }
+
if (params.mTextureMatrix)
{
tex_setup = true;
@@ -492,9 +576,15 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)
}
}
- params.mVertexBuffer->setBuffer(mask);
+ static LLFastTimer::DeclareTimer FTM_RENDER_ALPHA_PUSH("Alpha Push Verts");
+ {
+ LLFastTimer t(FTM_RENDER_ALPHA_PUSH);
+ gGL.blendFunc((LLRender::eBlendFactor) params.mBlendFuncSrc, (LLRender::eBlendFactor) params.mBlendFuncDst, mAlphaSFactor, mAlphaDFactor);
+ params.mVertexBuffer->setBuffer(mask & ~(params.mFullbright ? (LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2) : 0));
+
params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode);
+ }
// If this alpha mesh has glow, then draw it a second time to add the destination-alpha (=glow). Interleaving these state-changing calls could be expensive, but glow must be drawn Z-sorted with alpha.
if (current_shader &&
@@ -507,7 +597,6 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)
emissive_shader->bind();
- // glow doesn't use vertex colors from the mesh data
params.mVertexBuffer->setBuffer((mask & ~LLVertexBuffer::MAP_COLOR) | LLVertexBuffer::MAP_EMISSIVE);
// do the actual drawing, again
@@ -530,6 +619,8 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)
}
}
+ gGL.setSceneBlendType(LLRender::BT_ALPHA);
+
LLVertexBuffer::unbind();
if (!light_enabled)
diff --git a/indra/newview/lldrawpoolalpha.h b/indra/newview/lldrawpoolalpha.h
index a4245e561d..d064a3a324 100644..100755
--- a/indra/newview/lldrawpoolalpha.h
+++ b/indra/newview/lldrawpoolalpha.h
@@ -50,11 +50,6 @@ public:
LLDrawPoolAlpha(U32 type = LLDrawPool::POOL_ALPHA);
/*virtual*/ ~LLDrawPoolAlpha();
- /*virtual*/ S32 getNumDeferredPasses();
- /*virtual*/ void beginDeferredPass(S32 pass);
- /*virtual*/ void endDeferredPass(S32 pass);
- /*virtual*/ void renderDeferred(S32 pass);
-
/*virtual*/ S32 getNumPostDeferredPasses();
/*virtual*/ void beginPostDeferredPass(S32 pass);
/*virtual*/ void endPostDeferredPass(S32 pass);
@@ -68,9 +63,9 @@ public:
/*virtual*/ void prerender();
void renderGroupAlpha(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture = TRUE);
- void renderAlpha(U32 mask);
+ void renderAlpha(U32 mask, S32 pass);
void renderAlphaHighlight(U32 mask);
-
+
static BOOL sShowDebugAlpha;
private:
diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp
index 0103373fd2..f622d5a63a 100644..100755
--- a/indra/newview/lldrawpoolavatar.cpp
+++ b/indra/newview/lldrawpoolavatar.cpp
@@ -49,6 +49,7 @@
#include "llappviewer.h"
#include "llrendersphere.h"
#include "llviewerpartsim.h"
+#include "llviewercontrol.h" // for gSavedSettings
static U32 sDataMask = LLDrawPoolAvatar::VERTEX_DATA_MASK;
static U32 sBufferUsage = GL_STREAM_DRAW_ARB;
@@ -59,9 +60,11 @@ LLGLSLShader* LLDrawPoolAvatar::sVertexProgram = NULL;
BOOL LLDrawPoolAvatar::sSkipOpaque = FALSE;
BOOL LLDrawPoolAvatar::sSkipTransparent = FALSE;
S32 LLDrawPoolAvatar::sDiffuseChannel = 0;
+F32 LLDrawPoolAvatar::sMinimumAlpha = 0.2f;
static bool is_deferred_render = false;
+static bool is_post_deferred_render = false;
extern BOOL gUseGLPick;
@@ -134,6 +137,16 @@ void LLDrawPoolAvatar::prerender()
{
sBufferUsage = GL_STREAM_DRAW_ARB;
}
+
+ if (!mDrawFace.empty())
+ {
+ const LLFace *facep = mDrawFace[0];
+ if (facep && facep->getDrawable())
+ {
+ LLVOAvatar* avatarp = (LLVOAvatar *)facep->getDrawable()->getVObj().get();
+ updateRiggedVertexBuffers(avatarp);
+ }
+ }
}
LLMatrix4& LLDrawPoolAvatar::getModelView()
@@ -183,6 +196,9 @@ void LLDrawPoolAvatar::beginDeferredPass(S32 pass)
case 4:
beginDeferredRiggedBump();
break;
+ default:
+ beginDeferredRiggedMaterial(pass-5);
+ break;
}
}
@@ -215,6 +231,9 @@ void LLDrawPoolAvatar::endDeferredPass(S32 pass)
case 4:
endDeferredRiggedBump();
break;
+ default:
+ endDeferredRiggedMaterial(pass-5);
+ break;
}
}
@@ -225,7 +244,7 @@ void LLDrawPoolAvatar::renderDeferred(S32 pass)
S32 LLDrawPoolAvatar::getNumPostDeferredPasses()
{
- return 6;
+ return 10;
}
void LLDrawPoolAvatar::beginPostDeferredPass(S32 pass)
@@ -247,9 +266,12 @@ void LLDrawPoolAvatar::beginPostDeferredPass(S32 pass)
case 4:
beginRiggedFullbrightAlpha();
break;
- case 5:
+ case 9:
beginRiggedGlow();
break;
+ default:
+ beginDeferredRiggedMaterialAlpha(pass-5);
+ break;
}
}
@@ -261,7 +283,9 @@ void LLDrawPoolAvatar::beginPostDeferredAlpha()
sRenderingSkinned = TRUE;
gPipeline.bindDeferredShader(*sVertexProgram);
-
+
+ sVertexProgram->setMinimumAlpha(LLDrawPoolAvatar::sMinimumAlpha);
+
sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
}
@@ -273,11 +297,39 @@ void LLDrawPoolAvatar::beginDeferredRiggedAlpha()
gPipeline.enableLightsDynamic();
}
+void LLDrawPoolAvatar::beginDeferredRiggedMaterialAlpha(S32 pass)
+{
+ switch (pass)
+ {
+ case 0: pass = 1; break;
+ case 1: pass = 5; break;
+ case 2: pass = 9; break;
+ default: pass = 13; break;
+ }
+
+ pass += LLMaterial::SHADER_COUNT;
+
+ sVertexProgram = &gDeferredMaterialProgram[pass];
+
+ if (LLPipeline::sUnderWaterRender)
+ {
+ sVertexProgram = &(gDeferredMaterialWaterProgram[pass]);
+ }
+
+ gPipeline.bindDeferredShader(*sVertexProgram);
+ sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
+ normal_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::BUMP_MAP);
+ specular_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::SPECULAR_MAP);
+ gPipeline.enableLightsDynamic();
+}
+
void LLDrawPoolAvatar::endDeferredRiggedAlpha()
{
LLVertexBuffer::unbind();
gPipeline.unbindDeferredShader(*sVertexProgram);
sDiffuseChannel = 0;
+ normal_channel = -1;
+ specular_channel = -1;
sVertexProgram = NULL;
}
@@ -303,6 +355,9 @@ void LLDrawPoolAvatar::endPostDeferredPass(S32 pass)
case 5:
endRiggedGlow();
break;
+ default:
+ endDeferredRiggedAlpha();
+ break;
}
}
@@ -326,17 +381,23 @@ void LLDrawPoolAvatar::renderPostDeferred(S32 pass)
6, //rigged fullbright shiny
7, //rigged alpha
8, //rigged fullbright alpha
- 9, //rigged glow
+ 9, //rigged material alpha 1
+ 10,//rigged material alpha 2
+ 11,//rigged material alpha 3
+ 12,//rigged material alpha 4
+ 13, //rigged glow
};
- pass = actual_pass[pass];
+ S32 p = actual_pass[pass];
if (LLPipeline::sImpostorRender)
{ //HACK for impostors so actual pass ends up being proper pass
- pass -= 2;
+ p -= 2;
}
- render(pass);
+ is_post_deferred_render = true;
+ render(p);
+ is_post_deferred_render = false;
}
@@ -423,12 +484,10 @@ void LLDrawPoolAvatar::renderShadow(S32 pass)
}
else
{
- renderRigged(avatarp, RIGGED_SIMPLE);
- renderRigged(avatarp, RIGGED_ALPHA);
- renderRigged(avatarp, RIGGED_FULLBRIGHT);
- renderRigged(avatarp, RIGGED_FULLBRIGHT_SHINY);
- renderRigged(avatarp, RIGGED_SHINY);
- renderRigged(avatarp, RIGGED_FULLBRIGHT_ALPHA);
+ for (U32 i = 0; i < NUM_RIGGED_PASSES; ++i)
+ {
+ renderRigged(avatarp, i);
+ }
}
}
@@ -449,11 +508,11 @@ S32 LLDrawPoolAvatar::getNumDeferredPasses()
{
if (LLPipeline::sImpostorRender)
{
- return 3;
+ return 19;
}
else
{
- return 5;
+ return 21;
}
}
@@ -608,7 +667,7 @@ void LLDrawPoolAvatar::beginRigid()
if (sVertexProgram != NULL)
{ //eyeballs render with the specular shader
sVertexProgram->bind();
- sVertexProgram->setMinimumAlpha(0.2f);
+ sVertexProgram->setMinimumAlpha(LLDrawPoolAvatar::sMinimumAlpha);
}
}
else
@@ -635,11 +694,9 @@ void LLDrawPoolAvatar::beginDeferredImpostor()
}
sVertexProgram = &gDeferredImpostorProgram;
-
specular_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::SPECULAR_MAP);
normal_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::DEFERRED_NORMAL);
sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
-
sVertexProgram->bind();
sVertexProgram->setMinimumAlpha(0.01f);
}
@@ -650,8 +707,9 @@ void LLDrawPoolAvatar::endDeferredImpostor()
sVertexProgram->disableTexture(LLViewerShaderMgr::DEFERRED_NORMAL);
sVertexProgram->disableTexture(LLViewerShaderMgr::SPECULAR_MAP);
sVertexProgram->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
- sVertexProgram->unbind();
- gGL.getTexUnit(0)->activate();
+ gPipeline.unbindDeferredShader(*sVertexProgram);
+ sVertexProgram = NULL;
+ sDiffuseChannel = 0;
}
void LLDrawPoolAvatar::beginDeferredRigid()
@@ -659,7 +717,7 @@ void LLDrawPoolAvatar::beginDeferredRigid()
sVertexProgram = &gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram;
sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
sVertexProgram->bind();
- sVertexProgram->setMinimumAlpha(0.2f);
+ sVertexProgram->setMinimumAlpha(LLDrawPoolAvatar::sMinimumAlpha);
}
void LLDrawPoolAvatar::endDeferredRigid()
@@ -717,7 +775,7 @@ void LLDrawPoolAvatar::beginSkinned()
if (LLGLSLShader::sNoFixedFunction)
{
- sVertexProgram->setMinimumAlpha(0.2f);
+ sVertexProgram->setMinimumAlpha(LLDrawPoolAvatar::sMinimumAlpha);
}
}
@@ -837,6 +895,10 @@ void LLDrawPoolAvatar::beginRiggedGlow()
{
sDiffuseChannel = 0;
sVertexProgram->bind();
+
+ sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, LLPipeline::sRenderDeferred ? 2.2f : 1.1f);
+ F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma");
+ sVertexProgram->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f));
}
}
@@ -855,7 +917,14 @@ void LLDrawPoolAvatar::beginRiggedFullbright()
}
else
{
- sVertexProgram = &gSkinnedObjectFullbrightProgram;
+ if (LLPipeline::sRenderDeferred)
+ {
+ sVertexProgram = &gDeferredSkinnedFullbrightProgram;
+ }
+ else
+ {
+ sVertexProgram = &gSkinnedObjectFullbrightProgram;
+ }
}
}
else
@@ -874,6 +943,18 @@ void LLDrawPoolAvatar::beginRiggedFullbright()
{
sDiffuseChannel = 0;
sVertexProgram->bind();
+
+ if (LLPipeline::sRenderingHUDs || !LLPipeline::sRenderDeferred)
+ {
+ sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f);
+ }
+ else
+ {
+ sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
+
+ F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma");
+ sVertexProgram->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f));
+ }
}
}
@@ -940,7 +1021,14 @@ void LLDrawPoolAvatar::beginRiggedFullbrightShiny()
}
else
{
- sVertexProgram = &gSkinnedObjectFullbrightShinyProgram;
+ if (LLPipeline::sRenderDeferred)
+ {
+ sVertexProgram = &gDeferredSkinnedFullbrightShinyProgram;
+ }
+ else
+ {
+ sVertexProgram = &gSkinnedObjectFullbrightShinyProgram;
+ }
}
}
else
@@ -955,11 +1043,21 @@ void LLDrawPoolAvatar::beginRiggedFullbrightShiny()
}
}
-
if (sShaderLevel > 0 || gPipeline.canUseVertexShaders())
{
sVertexProgram->bind();
LLDrawPoolBump::bindCubeMap(sVertexProgram, 2, sDiffuseChannel, cube_channel, false);
+
+ if (LLPipeline::sRenderingHUDs || !LLPipeline::sRenderDeferred)
+ {
+ sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f);
+ }
+ else
+ {
+ sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
+ F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma");
+ sVertexProgram->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f));
+ }
}
}
@@ -1008,6 +1106,48 @@ void LLDrawPoolAvatar::endDeferredRiggedBump()
sVertexProgram = NULL;
}
+void LLDrawPoolAvatar::beginDeferredRiggedMaterial(S32 pass)
+{
+ if (pass == 1 ||
+ pass == 5 ||
+ pass == 9 ||
+ pass == 13)
+ { //skip alpha passes
+ return;
+ }
+ sVertexProgram = &gDeferredMaterialProgram[pass+LLMaterial::SHADER_COUNT];
+
+ if (LLPipeline::sUnderWaterRender)
+ {
+ sVertexProgram = &(gDeferredMaterialWaterProgram[pass+LLMaterial::SHADER_COUNT]);
+ }
+
+ sVertexProgram->bind();
+ normal_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::BUMP_MAP);
+ specular_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::SPECULAR_MAP);
+ sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
+}
+
+void LLDrawPoolAvatar::endDeferredRiggedMaterial(S32 pass)
+{
+ if (pass == 1 ||
+ pass == 5 ||
+ pass == 9 ||
+ pass == 13)
+ {
+ return;
+ }
+
+ LLVertexBuffer::unbind();
+ sVertexProgram->disableTexture(LLViewerShaderMgr::BUMP_MAP);
+ sVertexProgram->disableTexture(LLViewerShaderMgr::SPECULAR_MAP);
+ sVertexProgram->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
+ sVertexProgram->unbind();
+ normal_channel = -1;
+ sDiffuseChannel = 0;
+ sVertexProgram = NULL;
+}
+
void LLDrawPoolAvatar::beginDeferredSkinned()
{
sShaderLevel = mVertexShaderLevel;
@@ -1015,7 +1155,7 @@ void LLDrawPoolAvatar::beginDeferredSkinned()
sRenderingSkinned = TRUE;
sVertexProgram->bind();
- sVertexProgram->setMinimumAlpha(0.2f);
+ sVertexProgram->setMinimumAlpha(LLDrawPoolAvatar::sMinimumAlpha);
sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
gGL.getTexUnit(0)->activate();
@@ -1034,9 +1174,13 @@ void LLDrawPoolAvatar::endDeferredSkinned()
gGL.getTexUnit(0)->activate();
}
+static LLFastTimer::DeclareTimer FTM_RENDER_AVATARS("renderAvatars");
+
void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
{
+ LLFastTimer t(FTM_RENDER_AVATARS);
+
if (pass == -1)
{
for (S32 i = 1; i < getNumPasses(); i++)
@@ -1161,6 +1305,22 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
else
{
renderRiggedSimple(avatarp);
+
+ if (LLPipeline::sRenderDeferred)
+ { //render "simple" materials
+ renderRigged(avatarp, RIGGED_MATERIAL);
+ renderRigged(avatarp, RIGGED_MATERIAL_ALPHA_MASK);
+ renderRigged(avatarp, RIGGED_MATERIAL_ALPHA_EMISSIVE);
+ renderRigged(avatarp, RIGGED_NORMMAP);
+ renderRigged(avatarp, RIGGED_NORMMAP_MASK);
+ renderRigged(avatarp, RIGGED_NORMMAP_EMISSIVE);
+ renderRigged(avatarp, RIGGED_SPECMAP);
+ renderRigged(avatarp, RIGGED_SPECMAP_MASK);
+ renderRigged(avatarp, RIGGED_SPECMAP_EMISSIVE);
+ renderRigged(avatarp, RIGGED_NORMSPEC);
+ renderRigged(avatarp, RIGGED_NORMSPEC_MASK);
+ renderRigged(avatarp, RIGGED_NORMSPEC_EMISSIVE);
+ }
}
return;
}
@@ -1179,9 +1339,27 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
return;
}
+ if (is_deferred_render && pass >= 5 && pass <= 21)
+ {
+ S32 p = pass-5;
+
+ if (p != 1 &&
+ p != 5 &&
+ p != 9 &&
+ p != 13)
+ {
+ renderDeferredRiggedMaterial(avatarp, p);
+ }
+ return;
+ }
+
+
+
+
if (pass == 5)
{
renderRiggedShinySimple(avatarp);
+
return;
}
@@ -1191,20 +1369,29 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
return;
}
- if (pass >= 7 && pass < 9)
+ if (pass >= 7 && pass < 13)
{
- LLGLEnable blend(GL_BLEND);
-
- gGL.setColorMask(true, true);
- gGL.blendFunc(LLRender::BF_SOURCE_ALPHA,
- LLRender::BF_ONE_MINUS_SOURCE_ALPHA,
- LLRender::BF_ZERO,
- LLRender::BF_ONE_MINUS_SOURCE_ALPHA);
-
-
if (pass == 7)
{
renderRiggedAlpha(avatarp);
+
+ if (LLPipeline::sRenderDeferred && !is_post_deferred_render)
+ { //render transparent materials under water
+ LLGLEnable blend(GL_BLEND);
+
+ gGL.setColorMask(true, true);
+ gGL.blendFunc(LLRender::BF_SOURCE_ALPHA,
+ LLRender::BF_ONE_MINUS_SOURCE_ALPHA,
+ LLRender::BF_ZERO,
+ LLRender::BF_ONE_MINUS_SOURCE_ALPHA);
+
+ renderRigged(avatarp, RIGGED_MATERIAL_ALPHA);
+ renderRigged(avatarp, RIGGED_SPECMAP_BLEND);
+ renderRigged(avatarp, RIGGED_NORMMAP_BLEND);
+ renderRigged(avatarp, RIGGED_NORMSPEC_BLEND);
+
+ gGL.setColorMask(true, false);
+ }
return;
}
@@ -1213,24 +1400,35 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
renderRiggedFullbrightAlpha(avatarp);
return;
}
- }
-
- if (pass == 9)
- {
- LLGLEnable blend(GL_BLEND);
- LLGLDisable test(GL_ALPHA_TEST);
- gGL.flush();
- LLGLEnable polyOffset(GL_POLYGON_OFFSET_FILL);
- glPolygonOffset(-1.0f, -1.0f);
- gGL.setSceneBlendType(LLRender::BT_ADD);
+ if (LLPipeline::sRenderDeferred && is_post_deferred_render)
+ {
+ S32 p = 0;
+ switch (pass)
+ {
+ case 9: p = 1; break;
+ case 10: p = 5; break;
+ case 11: p = 9; break;
+ case 12: p = 13; break;
+ }
- LLGLDepthTest depth(GL_TRUE, GL_FALSE);
- gGL.setColorMask(false, true);
+ {
+ LLGLEnable blend(GL_BLEND);
+ renderDeferredRiggedMaterial(avatarp, p);
+ }
+ return;
+ }
+ else if (pass == 9)
+ {
+ renderRiggedGlow(avatarp);
+ return;
+ }
+ }
+ if (pass == 13)
+ {
renderRiggedGlow(avatarp);
- gGL.setColorMask(true, false);
- gGL.setSceneBlendType(LLRender::BT_ALPHA);
+
return;
}
@@ -1265,6 +1463,65 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
}
}
+void LLDrawPoolAvatar::getRiggedGeometry(LLFace* face, LLPointer<LLVertexBuffer>& buffer, U32 data_mask, const LLMeshSkinInfo* skin, LLVolume* volume, const LLVolumeFace& vol_face)
+{
+ face->setGeomIndex(0);
+ face->setIndicesIndex(0);
+
+ //rigged faces do not batch textures
+ face->setTextureIndex(255);
+
+ if (buffer.isNull() || buffer->getTypeMask() != data_mask || !buffer->isWriteable())
+ { //make a new buffer
+ if (sShaderLevel > 0)
+ {
+ buffer = new LLVertexBuffer(data_mask, GL_DYNAMIC_DRAW_ARB);
+ }
+ else
+ {
+ buffer = new LLVertexBuffer(data_mask, GL_STREAM_DRAW_ARB);
+ }
+ buffer->allocateBuffer(vol_face.mNumVertices, vol_face.mNumIndices, true);
+ }
+ else
+ { //resize existing buffer
+ buffer->resizeBuffer(vol_face.mNumVertices, vol_face.mNumIndices);
+ }
+
+ face->setSize(vol_face.mNumVertices, vol_face.mNumIndices);
+ face->setVertexBuffer(buffer);
+
+ U16 offset = 0;
+
+ LLMatrix4 mat_vert = skin->mBindShapeMatrix;
+ glh::matrix4f m((F32*) mat_vert.mMatrix);
+ m = m.inverse().transpose();
+
+ F32 mat3[] =
+ { m.m[0], m.m[1], m.m[2],
+ m.m[4], m.m[5], m.m[6],
+ m.m[8], m.m[9], m.m[10] };
+
+ LLMatrix3 mat_normal(mat3);
+
+ //let getGeometryVolume know if alpha should override shiny
+ U32 type = gPipeline.getPoolTypeFromTE(face->getTextureEntry(), face->getTexture());
+
+ if (type == LLDrawPool::POOL_ALPHA)
+ {
+ face->setPoolType(LLDrawPool::POOL_ALPHA);
+ }
+ else
+ {
+ face->setPoolType(LLDrawPool::POOL_AVATAR);
+ }
+
+ //llinfos << "Rebuilt face " << face->getTEOffset() << " of " << face->getDrawable() << " at " << gFrameTimeSeconds << llendl;
+ face->getGeometryVolume(*volume, face->getTEOffset(), mat_vert, mat_normal, offset, true);
+
+ buffer->flush();
+}
+
void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace* face, const LLMeshSkinInfo* skin, LLVolume* volume, const LLVolumeFace& vol_face)
{
LLVector4a* weight = vol_face.mWeights;
@@ -1284,57 +1541,27 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace*
buffer->getNumIndices() != vol_face.mNumIndices ||
(drawable && drawable->isState(LLDrawable::REBUILD_ALL)))
{
- face->setGeomIndex(0);
- face->setIndicesIndex(0);
-
- if (buffer.isNull() || buffer->getTypeMask() != data_mask || !buffer->isWriteable())
- { //make a new buffer
- if (sShaderLevel > 0)
+ if (drawable && drawable->isState(LLDrawable::REBUILD_ALL))
+ { //rebuild EVERY face in the drawable, not just this one, to avoid missing drawable wide rebuild issues
+ for (S32 i = 0; i < drawable->getNumFaces(); ++i)
{
- buffer = new LLVertexBuffer(data_mask, GL_DYNAMIC_DRAW_ARB);
- }
- else
- {
- buffer = new LLVertexBuffer(data_mask, GL_STREAM_DRAW_ARB);
+ LLFace* facep = drawable->getFace(i);
+ U32 face_data_mask = facep->getRiggedVertexBufferDataMask();
+ if (face_data_mask)
+ {
+ LLPointer<LLVertexBuffer> cur_buffer = facep->getVertexBuffer();
+ const LLVolumeFace& cur_vol_face = volume->getVolumeFace(i);
+ getRiggedGeometry(facep, cur_buffer, face_data_mask, skin, volume, cur_vol_face);
+ }
}
- buffer->allocateBuffer(vol_face.mNumVertices, vol_face.mNumIndices, true);
- }
- else
- { //resize existing buffer
- buffer->resizeBuffer(vol_face.mNumVertices, vol_face.mNumIndices);
- }
-
- face->setSize(vol_face.mNumVertices, vol_face.mNumIndices);
- face->setVertexBuffer(buffer);
-
- U16 offset = 0;
-
- LLMatrix4 mat_vert = skin->mBindShapeMatrix;
- glh::matrix4f m((F32*) mat_vert.mMatrix);
- m = m.inverse().transpose();
-
- F32 mat3[] =
- { m.m[0], m.m[1], m.m[2],
- m.m[4], m.m[5], m.m[6],
- m.m[8], m.m[9], m.m[10] };
+ drawable->clearState(LLDrawable::REBUILD_ALL);
- LLMatrix3 mat_normal(mat3);
-
- //let getGeometryVolume know if alpha should override shiny
- U32 type = gPipeline.getPoolTypeFromTE(face->getTextureEntry(), face->getTexture());
-
- if (type == LLDrawPool::POOL_ALPHA)
- {
- face->setPoolType(LLDrawPool::POOL_ALPHA);
+ buffer = face->getVertexBuffer();
}
else
- {
- face->setPoolType(LLDrawPool::POOL_AVATAR);
+ { //just rebuild this face
+ getRiggedGeometry(face, buffer, data_mask, skin, volume, vol_face);
}
-
- face->getGeometryVolume(*volume, face->getTEOffset(), mat_vert, mat_normal, offset, true);
-
- buffer->flush();
}
if (sShaderLevel <= 0 && face->mLastSkinTime < avatar->getLastSkinTime())
@@ -1419,16 +1646,11 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace*
}
}
}
-
- if (drawable && (face->getTEOffset() == drawable->getNumFaces()-1))
- {
- drawable->clearState(LLDrawable::REBUILD_ALL);
- }
}
void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
{
- if (avatar->isSelf() && !gAgent.needsRenderAvatar() || !gMeshRepo.meshRezEnabled())
+ if (avatar->isSelf() && !gAgent.needsRenderAvatar())
{
return;
}
@@ -1486,9 +1708,11 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
{
if (sShaderLevel > 0)
{ //upload matrix palette to shader
- LLMatrix4 mat[64];
+ LLMatrix4 mat[32];
+
+ U32 count = llmin((U32) skin->mJointNames.size(), (U32) 32);
- for (U32 i = 0; i < skin->mJointNames.size(); ++i)
+ for (U32 i = 0; i < count; ++i)
{
LLJoint* joint = avatar->getJoint(skin->mJointNames[i]);
if (joint)
@@ -1500,8 +1724,8 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
stop_glerror();
- LLDrawPoolAvatar::sVertexProgram->uniformMatrix4fv("matrixPalette",
- skin->mJointNames.size(),
+ LLDrawPoolAvatar::sVertexProgram->uniformMatrix4fv(LLViewerShaderMgr::AVATAR_MATRIX,
+ count,
FALSE,
(GLfloat*) mat[0].mMatrix);
@@ -1522,13 +1746,62 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
gGL.diffuseColor4f(0,0,0,face->getTextureEntry()->getGlow());
}*/
- gGL.getTexUnit(sDiffuseChannel)->bind(face->getTexture());
- if (normal_channel > -1)
+ const LLTextureEntry* te = face->getTextureEntry();
+ LLMaterial* mat = te->getMaterialParams().get();
+
+ if (mat)
+ {
+ gGL.getTexUnit(sDiffuseChannel)->bind(face->getTexture(LLRender::DIFFUSE_MAP));
+ gGL.getTexUnit(normal_channel)->bind(face->getTexture(LLRender::NORMAL_MAP));
+ gGL.getTexUnit(specular_channel)->bind(face->getTexture(LLRender::SPECULAR_MAP));
+
+ LLColor4 col = mat->getSpecularLightColor();
+ F32 spec = mat->getSpecularLightExponent()/255.f;
+
+ F32 env = mat->getEnvironmentIntensity()/255.f;
+
+ if (mat->getSpecularID().isNull())
+ {
+ env = te->getShiny()*0.25f;
+ col.set(env,env,env,0);
+ spec = env;
+ }
+
+ BOOL fullbright = te->getFullbright();
+
+ sVertexProgram->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, fullbright ? 1.f : 0.f);
+ sVertexProgram->uniform4f(LLShaderMgr::SPECULAR_COLOR, col.mV[0], col.mV[1], col.mV[2], spec);
+ sVertexProgram->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, env);
+
+ if (mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK)
+ {
+ sVertexProgram->setMinimumAlpha(mat->getAlphaMaskCutoff()/255.f);
+ }
+ else
+ {
+ sVertexProgram->setMinimumAlpha(0.f);
+ }
+
+ for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i)
+ {
+ LLViewerTexture* tex = face->getTexture(i);
+ if (tex)
+ {
+ tex->addTextureStats(avatar->getPixelArea());
+ }
+ }
+ }
+ else
{
- LLDrawPoolBump::bindBumpMap(face, normal_channel);
+ gGL.getTexUnit(sDiffuseChannel)->bind(face->getTexture());
+ sVertexProgram->setMinimumAlpha(0.f);
+ if (normal_channel > -1)
+ {
+ LLDrawPoolBump::bindBumpMap(face, normal_channel);
+ }
}
- if (face->mTextureMatrix)
+ if (face->mTextureMatrix && vobj->mTexAnimMode)
{
gGL.matrixMode(LLRender::MM_TEXTURE);
gGL.loadMatrix((F32*) face->mTextureMatrix->mMatrix);
@@ -1542,13 +1815,14 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
buff->setBuffer(data_mask);
buff->drawRange(LLRender::TRIANGLES, start, end, count, offset);
}
+
+ gPipeline.addTrianglesDrawn(count, LLRender::TRIANGLES);
}
}
}
void LLDrawPoolAvatar::renderDeferredRiggedSimple(LLVOAvatar* avatar)
{
- updateRiggedVertexBuffers(avatar);
renderRigged(avatar, RIGGED_DEFERRED_SIMPLE);
}
@@ -1557,8 +1831,17 @@ void LLDrawPoolAvatar::renderDeferredRiggedBump(LLVOAvatar* avatar)
renderRigged(avatar, RIGGED_DEFERRED_BUMP);
}
+void LLDrawPoolAvatar::renderDeferredRiggedMaterial(LLVOAvatar* avatar, S32 pass)
+{
+ renderRigged(avatar, pass);
+}
+
+static LLFastTimer::DeclareTimer FTM_RIGGED_VBO("Rigged VBO");
+
void LLDrawPoolAvatar::updateRiggedVertexBuffers(LLVOAvatar* avatar)
{
+ LLFastTimer t(FTM_RIGGED_VBO);
+
//update rigged vertex buffers
for (U32 type = 0; type < NUM_RIGGED_PASSES; ++type)
{
@@ -1608,7 +1891,6 @@ void LLDrawPoolAvatar::updateRiggedVertexBuffers(LLVOAvatar* avatar)
void LLDrawPoolAvatar::renderRiggedSimple(LLVOAvatar* avatar)
{
- updateRiggedVertexBuffers(avatar);
renderRigged(avatar, RIGGED_SIMPLE);
}
@@ -1630,17 +1912,58 @@ void LLDrawPoolAvatar::renderRiggedFullbrightShiny(LLVOAvatar* avatar)
void LLDrawPoolAvatar::renderRiggedAlpha(LLVOAvatar* avatar)
{
- renderRigged(avatar, RIGGED_ALPHA);
+ if (!mRiggedFace[RIGGED_ALPHA].empty())
+ {
+ LLGLEnable blend(GL_BLEND);
+
+ gGL.setColorMask(true, true);
+ gGL.blendFunc(LLRender::BF_SOURCE_ALPHA,
+ LLRender::BF_ONE_MINUS_SOURCE_ALPHA,
+ LLRender::BF_ZERO,
+ LLRender::BF_ONE_MINUS_SOURCE_ALPHA);
+
+ renderRigged(avatar, RIGGED_ALPHA);
+ gGL.setColorMask(true, false);
+ }
}
void LLDrawPoolAvatar::renderRiggedFullbrightAlpha(LLVOAvatar* avatar)
{
- renderRigged(avatar, RIGGED_FULLBRIGHT_ALPHA);
+ if (!mRiggedFace[RIGGED_FULLBRIGHT_ALPHA].empty())
+ {
+ LLGLEnable blend(GL_BLEND);
+
+ gGL.setColorMask(true, true);
+ gGL.blendFunc(LLRender::BF_SOURCE_ALPHA,
+ LLRender::BF_ONE_MINUS_SOURCE_ALPHA,
+ LLRender::BF_ZERO,
+ LLRender::BF_ONE_MINUS_SOURCE_ALPHA);
+
+ renderRigged(avatar, RIGGED_FULLBRIGHT_ALPHA);
+ gGL.setColorMask(true, false);
+ }
}
void LLDrawPoolAvatar::renderRiggedGlow(LLVOAvatar* avatar)
{
- renderRigged(avatar, RIGGED_GLOW, true);
+ if (!mRiggedFace[RIGGED_GLOW].empty())
+ {
+ LLGLEnable blend(GL_BLEND);
+ LLGLDisable test(GL_ALPHA_TEST);
+ gGL.flush();
+
+ LLGLEnable polyOffset(GL_POLYGON_OFFSET_FILL);
+ glPolygonOffset(-1.0f, -1.0f);
+ gGL.setSceneBlendType(LLRender::BT_ADD);
+
+ LLGLDepthTest depth(GL_TRUE, GL_FALSE);
+ gGL.setColorMask(false, true);
+
+ renderRigged(avatar, RIGGED_GLOW, true);
+
+ gGL.setColorMask(true, false);
+ gGL.setSceneBlendType(LLRender::BT_ALPHA);
+ }
}
diff --git a/indra/newview/lldrawpoolavatar.h b/indra/newview/lldrawpoolavatar.h
index 69e3068858..b9d2204052 100644..100755
--- a/indra/newview/lldrawpoolavatar.h
+++ b/indra/newview/lldrawpoolavatar.h
@@ -75,7 +75,7 @@ public:
/*virtual*/ void beginDeferredPass(S32 pass);
/*virtual*/ void endDeferredPass(S32 pass);
/*virtual*/ void renderDeferred(S32 pass);
-
+
/*virtual*/ S32 getNumPostDeferredPasses();
/*virtual*/ void beginPostDeferredPass(S32 pass);
/*virtual*/ void endPostDeferredPass(S32 pass);
@@ -113,6 +113,8 @@ public:
void beginRiggedFullbrightAlpha();
void beginRiggedGlow();
void beginDeferredRiggedAlpha();
+ void beginDeferredRiggedMaterial(S32 pass);
+ void beginDeferredRiggedMaterialAlpha(S32 pass);
void endRiggedSimple();
void endRiggedFullbright();
@@ -122,6 +124,8 @@ public:
void endRiggedFullbrightAlpha();
void endRiggedGlow();
void endDeferredRiggedAlpha();
+ void endDeferredRiggedMaterial(S32 pass);
+ void endDeferredRiggedMaterialAlpha(S32 pass);
void beginDeferredRiggedSimple();
void beginDeferredRiggedBump();
@@ -129,6 +133,7 @@ public:
void endDeferredRiggedSimple();
void endDeferredRiggedBump();
+ void getRiggedGeometry(LLFace* face, LLPointer<LLVertexBuffer>& buffer, U32 data_mask, const LLMeshSkinInfo* skin, LLVolume* volume, const LLVolumeFace& vol_face);
void updateRiggedFaceVertexBuffer(LLVOAvatar* avatar,
LLFace* facep,
const LLMeshSkinInfo* skin,
@@ -146,10 +151,27 @@ public:
void renderRiggedGlow(LLVOAvatar* avatar);
void renderDeferredRiggedSimple(LLVOAvatar* avatar);
void renderDeferredRiggedBump(LLVOAvatar* avatar);
-
+ void renderDeferredRiggedMaterial(LLVOAvatar* avatar, S32 pass);
+
typedef enum
{
- RIGGED_SIMPLE = 0,
+ RIGGED_MATERIAL=0,
+ RIGGED_MATERIAL_ALPHA,
+ RIGGED_MATERIAL_ALPHA_MASK,
+ RIGGED_MATERIAL_ALPHA_EMISSIVE,
+ RIGGED_SPECMAP,
+ RIGGED_SPECMAP_BLEND,
+ RIGGED_SPECMAP_MASK,
+ RIGGED_SPECMAP_EMISSIVE,
+ RIGGED_NORMMAP,
+ RIGGED_NORMMAP_BLEND,
+ RIGGED_NORMMAP_MASK,
+ RIGGED_NORMMAP_EMISSIVE,
+ RIGGED_NORMSPEC,
+ RIGGED_NORMSPEC_BLEND,
+ RIGGED_NORMSPEC_MASK,
+ RIGGED_NORMSPEC_EMISSIVE,
+ RIGGED_SIMPLE,
RIGGED_FULLBRIGHT,
RIGGED_SHINY,
RIGGED_FULLBRIGHT_SHINY,
@@ -164,6 +186,48 @@ public:
typedef enum
{
+ RIGGED_MATERIAL_MASK =
+ LLVertexBuffer::MAP_VERTEX |
+ LLVertexBuffer::MAP_NORMAL |
+ LLVertexBuffer::MAP_TEXCOORD0 |
+ LLVertexBuffer::MAP_COLOR |
+ LLVertexBuffer::MAP_WEIGHT4,
+ RIGGED_MATERIAL_ALPHA_VMASK = RIGGED_MATERIAL_MASK,
+ RIGGED_MATERIAL_ALPHA_MASK_MASK = RIGGED_MATERIAL_MASK,
+ RIGGED_MATERIAL_ALPHA_EMISSIVE_MASK = RIGGED_MATERIAL_MASK,
+ RIGGED_SPECMAP_VMASK =
+ LLVertexBuffer::MAP_VERTEX |
+ LLVertexBuffer::MAP_NORMAL |
+ LLVertexBuffer::MAP_TEXCOORD0 |
+ LLVertexBuffer::MAP_TEXCOORD2 |
+ LLVertexBuffer::MAP_COLOR |
+ LLVertexBuffer::MAP_WEIGHT4,
+ RIGGED_SPECMAP_BLEND_MASK = RIGGED_SPECMAP_VMASK,
+ RIGGED_SPECMAP_MASK_MASK = RIGGED_SPECMAP_VMASK,
+ RIGGED_SPECMAP_EMISSIVE_MASK = RIGGED_SPECMAP_VMASK,
+ RIGGED_NORMMAP_VMASK =
+ LLVertexBuffer::MAP_VERTEX |
+ LLVertexBuffer::MAP_NORMAL |
+ LLVertexBuffer::MAP_TANGENT |
+ LLVertexBuffer::MAP_TEXCOORD0 |
+ LLVertexBuffer::MAP_TEXCOORD1 |
+ LLVertexBuffer::MAP_COLOR |
+ LLVertexBuffer::MAP_WEIGHT4,
+ RIGGED_NORMMAP_BLEND_MASK = RIGGED_NORMMAP_VMASK,
+ RIGGED_NORMMAP_MASK_MASK = RIGGED_NORMMAP_VMASK,
+ RIGGED_NORMMAP_EMISSIVE_MASK = RIGGED_NORMMAP_VMASK,
+ RIGGED_NORMSPEC_VMASK =
+ LLVertexBuffer::MAP_VERTEX |
+ LLVertexBuffer::MAP_NORMAL |
+ LLVertexBuffer::MAP_TANGENT |
+ LLVertexBuffer::MAP_TEXCOORD0 |
+ LLVertexBuffer::MAP_TEXCOORD1 |
+ LLVertexBuffer::MAP_TEXCOORD2 |
+ LLVertexBuffer::MAP_COLOR |
+ LLVertexBuffer::MAP_WEIGHT4,
+ RIGGED_NORMSPEC_BLEND_MASK = RIGGED_NORMSPEC_VMASK,
+ RIGGED_NORMSPEC_MASK_MASK = RIGGED_NORMSPEC_VMASK,
+ RIGGED_NORMSPEC_EMISSIVE_MASK = RIGGED_NORMSPEC_VMASK,
RIGGED_SIMPLE_MASK = LLVertexBuffer::MAP_VERTEX |
LLVertexBuffer::MAP_NORMAL |
LLVertexBuffer::MAP_TEXCOORD0 |
@@ -184,7 +248,7 @@ public:
RIGGED_DEFERRED_BUMP_MASK = LLVertexBuffer::MAP_VERTEX |
LLVertexBuffer::MAP_NORMAL |
LLVertexBuffer::MAP_TEXCOORD0 |
- LLVertexBuffer::MAP_BINORMAL |
+ LLVertexBuffer::MAP_TANGENT |
LLVertexBuffer::MAP_COLOR |
LLVertexBuffer::MAP_WEIGHT4,
RIGGED_DEFERRED_SIMPLE_MASK = LLVertexBuffer::MAP_VERTEX |
@@ -208,6 +272,7 @@ public:
static BOOL sSkipOpaque;
static BOOL sSkipTransparent;
static S32 sDiffuseChannel;
+ static F32 sMinimumAlpha;
static LLGLSLShader* sVertexProgram;
};
diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp
index b58efe62ab..6b4c5cfca1 100644..100755
--- a/indra/newview/lldrawpoolbump.cpp
+++ b/indra/newview/lldrawpoolbump.cpp
@@ -153,7 +153,7 @@ void LLStandardBumpmap::addstandard()
gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mLabel = label;
gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage =
LLViewerTextureManager::getFetchedTexture(LLUUID(bump_image_id));
- gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage->setBoostLevel(LLViewerTexture::BOOST_BUMP) ;
+ gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage->setBoostLevel(LLGLTexture::LOCAL) ;
gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage->setLoadedCallback(LLBumpImageList::onSourceStandardLoaded, 0, TRUE, FALSE, NULL, NULL );
gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage->forceToSaveRawImage(0) ;
LLStandardBumpmap::sStandardBumpmapCount++;
@@ -449,9 +449,6 @@ void LLDrawPoolBump::unbindCubeMap(LLGLSLShader* shader, S32 shader_level, S32&
LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL;
if( cube_map )
{
- cube_map->disable();
- cube_map->restoreMatrix();
-
if (!invisible && shader_level > 1)
{
shader->disableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP);
@@ -464,6 +461,10 @@ void LLDrawPoolBump::unbindCubeMap(LLGLSLShader* shader, S32 shader_level, S32&
}
}
}
+ // Moved below shader->disableTexture call to avoid false alarms from auto-re-enable of textures on stage 0
+ // MAINT-755
+ cube_map->disable();
+ cube_map->restoreMatrix();
}
if (!LLGLSLShader::sNoFixedFunction)
@@ -514,7 +515,14 @@ void LLDrawPoolBump::beginFullbrightShiny()
}
else
{
- shader = &gObjectFullbrightShinyProgram;
+ if (LLPipeline::sRenderDeferred)
+ {
+ shader = &gDeferredFullbrightShinyProgram;
+ }
+ else
+ {
+ shader = &gObjectFullbrightShinyProgram;
+ }
}
LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL;
@@ -847,12 +855,12 @@ void LLDrawPoolBump::renderDeferred(S32 pass)
LLFastTimer ftm(FTM_RENDER_BUMP);
U32 type = LLRenderPass::PASS_BUMP;
- LLCullResult::drawinfo_list_t::iterator begin = gPipeline.beginRenderMap(type);
- LLCullResult::drawinfo_list_t::iterator end = gPipeline.endRenderMap(type);
+ LLCullResult::drawinfo_iterator begin = gPipeline.beginRenderMap(type);
+ LLCullResult::drawinfo_iterator end = gPipeline.endRenderMap(type);
- U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_BINORMAL | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_COLOR;
+ U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_COLOR;
- for (LLCullResult::drawinfo_list_t::iterator i = begin; i != end; ++i)
+ for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i)
{
LLDrawInfo& params = **i;
@@ -915,6 +923,8 @@ void LLBumpImageList::init()
llassert( mDarknessEntries.size() == 0 );
LLStandardBumpmap::init();
+
+ LLStandardBumpmap::restoreGL();
}
void LLBumpImageList::clear()
@@ -1075,7 +1085,7 @@ LLViewerTexture* LLBumpImageList::getBrightnessDarknessImage(LLViewerFetchedText
src_image->getHeight() != bump->getHeight())// ||
//(LLPipeline::sRenderDeferred && bump->getComponents() != 4))
{
- src_image->setBoostLevel(LLViewerTexture::BOOST_BUMP) ;
+ src_image->setBoostLevel(LLGLTexture::BOOST_BUMP) ;
src_image->setLoadedCallback( callback_func, 0, TRUE, FALSE, new LLUUID(src_image->getID()), NULL );
src_image->forceToSaveRawImage(0) ;
}
@@ -1192,7 +1202,7 @@ static LLFastTimer::DeclareTimer FTM_BUMP_SOURCE_MIN_MAX("Min/Max");
static LLFastTimer::DeclareTimer FTM_BUMP_SOURCE_RGB2LUM("RGB to Luminance");
static LLFastTimer::DeclareTimer FTM_BUMP_SOURCE_RESCALE("Rescale");
static LLFastTimer::DeclareTimer FTM_BUMP_SOURCE_GEN_NORMAL("Generate Normal");
-static LLFastTimer::DeclareTimer FTM_BUMP_SOURCE_CREATE("Create");
+static LLFastTimer::DeclareTimer FTM_BUMP_SOURCE_CREATE("Bump Source Create");
// static
void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLImageRaw* src, LLUUID& source_asset_id, EBumpEffect bump_code )
@@ -1341,8 +1351,7 @@ void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLI
// immediately assign bump to a global smart pointer in case some local smart pointer
// accidentally releases it.
LLPointer<LLViewerTexture> bump = LLViewerTextureManager::getLocalTexture( TRUE );
-
-
+
if (!LLPipeline::sRenderDeferred)
{
LLFastTimer t(FTM_BUMP_SOURCE_CREATE);
@@ -1351,6 +1360,10 @@ void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLI
}
else
{ //convert to normal map
+
+ //disable compression on normal maps to prevent errors below
+ bump->getGLTexture()->setAllowCompression(false);
+
{
LLFastTimer t(FTM_BUMP_SOURCE_CREATE);
bump->setExplicitFormat(GL_RGBA8, GL_ALPHA);
@@ -1366,9 +1379,14 @@ void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLI
LLGLDisable blend(GL_BLEND);
gGL.setColorMask(TRUE, TRUE);
gNormalMapGenProgram.bind();
- gNormalMapGenProgram.uniform1f("norm_scale", gSavedSettings.getF32("RenderNormalMapScale"));
- gNormalMapGenProgram.uniform1f("stepX", 1.f/bump->getWidth());
- gNormalMapGenProgram.uniform1f("stepY", 1.f/bump->getHeight());
+
+ static LLStaticHashedString sNormScale("norm_scale");
+ static LLStaticHashedString sStepX("stepX");
+ static LLStaticHashedString sStepY("stepY");
+
+ gNormalMapGenProgram.uniform1f(sNormScale, gSavedSettings.getF32("RenderNormalMapScale"));
+ gNormalMapGenProgram.uniform1f(sStepX, 1.f/bump->getWidth());
+ gNormalMapGenProgram.uniform1f(sStepY, 1.f/bump->getHeight());
LLVector2 v((F32) bump->getWidth()/gPipeline.mScreen.getWidth(),
(F32) bump->getHeight()/gPipeline.mScreen.getHeight());
@@ -1445,10 +1463,10 @@ void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLI
void LLDrawPoolBump::renderBump(U32 type, U32 mask)
{
- LLCullResult::drawinfo_list_t::iterator begin = gPipeline.beginRenderMap(type);
- LLCullResult::drawinfo_list_t::iterator end = gPipeline.endRenderMap(type);
+ LLCullResult::drawinfo_iterator begin = gPipeline.beginRenderMap(type);
+ LLCullResult::drawinfo_iterator end = gPipeline.endRenderMap(type);
- for (LLCullResult::drawinfo_list_t::iterator i = begin; i != end; ++i)
+ for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i)
{
LLDrawInfo& params = **i;
diff --git a/indra/newview/lldrawpoolbump.h b/indra/newview/lldrawpoolbump.h
index 476b1d41b7..476b1d41b7 100644..100755
--- a/indra/newview/lldrawpoolbump.h
+++ b/indra/newview/lldrawpoolbump.h
diff --git a/indra/newview/lldrawpoolground.cpp b/indra/newview/lldrawpoolground.cpp
index 59c3fbf7a1..59c3fbf7a1 100644..100755
--- a/indra/newview/lldrawpoolground.cpp
+++ b/indra/newview/lldrawpoolground.cpp
diff --git a/indra/newview/lldrawpoolground.h b/indra/newview/lldrawpoolground.h
index a4f8a3fcf5..a4f8a3fcf5 100644..100755
--- a/indra/newview/lldrawpoolground.h
+++ b/indra/newview/lldrawpoolground.h
diff --git a/indra/newview/lldrawpoolmaterials.cpp b/indra/newview/lldrawpoolmaterials.cpp
new file mode 100644
index 0000000000..d1b5080650
--- /dev/null
+++ b/indra/newview/lldrawpoolmaterials.cpp
@@ -0,0 +1,224 @@
+/**
+ * @file lldrawpool.cpp
+ * @brief LLDrawPoolMaterials class implementation
+ * @author Jonathan "Geenz" Goodman
+ *
+ * $LicenseInfo:firstyear=2002&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2013, 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 "lldrawpoolmaterials.h"
+#include "llviewershadermgr.h"
+#include "pipeline.h"
+
+S32 diffuse_channel = -1;
+
+LLDrawPoolMaterials::LLDrawPoolMaterials()
+: LLRenderPass(LLDrawPool::POOL_MATERIALS)
+{
+
+}
+
+void LLDrawPoolMaterials::prerender()
+{
+ mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
+}
+
+S32 LLDrawPoolMaterials::getNumDeferredPasses()
+{
+ return 12;
+}
+
+void LLDrawPoolMaterials::beginDeferredPass(S32 pass)
+{
+ U32 shader_idx[] =
+ {
+ 0, //LLRenderPass::PASS_MATERIAL,
+ //1, //LLRenderPass::PASS_MATERIAL_ALPHA,
+ 2, //LLRenderPass::PASS_MATERIAL_ALPHA_MASK,
+ 3, //LLRenderPass::PASS_MATERIAL_ALPHA_GLOW,
+ 4, //LLRenderPass::PASS_SPECMAP,
+ //5, //LLRenderPass::PASS_SPECMAP_BLEND,
+ 6, //LLRenderPass::PASS_SPECMAP_MASK,
+ 7, //LLRenderPass::PASS_SPECMAP_GLOW,
+ 8, //LLRenderPass::PASS_NORMMAP,
+ //9, //LLRenderPass::PASS_NORMMAP_BLEND,
+ 10, //LLRenderPass::PASS_NORMMAP_MASK,
+ 11, //LLRenderPass::PASS_NORMMAP_GLOW,
+ 12, //LLRenderPass::PASS_NORMSPEC,
+ //13, //LLRenderPass::PASS_NORMSPEC_BLEND,
+ 14, //LLRenderPass::PASS_NORMSPEC_MASK,
+ 15, //LLRenderPass::PASS_NORMSPEC_GLOW,
+ };
+
+ mShader = &(gDeferredMaterialProgram[shader_idx[pass]]);
+
+ if (LLPipeline::sUnderWaterRender)
+ {
+ mShader = &(gDeferredMaterialWaterProgram[shader_idx[pass]]);
+ }
+
+ mShader->bind();
+
+ diffuse_channel = mShader->enableTexture(LLShaderMgr::DIFFUSE_MAP);
+
+ LLFastTimer t(FTM_RENDER_MATERIALS);
+}
+
+void LLDrawPoolMaterials::endDeferredPass(S32 pass)
+{
+ LLFastTimer t(FTM_RENDER_MATERIALS);
+
+ mShader->unbind();
+
+ LLRenderPass::endRenderPass(pass);
+}
+
+void LLDrawPoolMaterials::renderDeferred(S32 pass)
+{
+ U32 type_list[] =
+ {
+ LLRenderPass::PASS_MATERIAL,
+ //LLRenderPass::PASS_MATERIAL_ALPHA,
+ LLRenderPass::PASS_MATERIAL_ALPHA_MASK,
+ LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE,
+ LLRenderPass::PASS_SPECMAP,
+ //LLRenderPass::PASS_SPECMAP_BLEND,
+ LLRenderPass::PASS_SPECMAP_MASK,
+ LLRenderPass::PASS_SPECMAP_EMISSIVE,
+ LLRenderPass::PASS_NORMMAP,
+ //LLRenderPass::PASS_NORMMAP_BLEND,
+ LLRenderPass::PASS_NORMMAP_MASK,
+ LLRenderPass::PASS_NORMMAP_EMISSIVE,
+ LLRenderPass::PASS_NORMSPEC,
+ //LLRenderPass::PASS_NORMSPEC_BLEND,
+ LLRenderPass::PASS_NORMSPEC_MASK,
+ LLRenderPass::PASS_NORMSPEC_EMISSIVE,
+ };
+
+ llassert(pass < sizeof(type_list)/sizeof(U32));
+
+ U32 type = type_list[pass];
+
+ U32 mask = mShader->mAttributeMask;
+
+ LLCullResult::drawinfo_iterator begin = gPipeline.beginRenderMap(type);
+ LLCullResult::drawinfo_iterator end = gPipeline.endRenderMap(type);
+
+ for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i)
+ {
+ LLDrawInfo& params = **i;
+
+ mShader->uniform4f(LLShaderMgr::SPECULAR_COLOR, params.mSpecColor.mV[0], params.mSpecColor.mV[1], params.mSpecColor.mV[2], params.mSpecColor.mV[3]);
+ mShader->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, params.mEnvIntensity);
+
+ if (params.mNormalMap)
+ {
+ params.mNormalMap->addTextureStats(params.mVSize);
+ bindNormalMap(params.mNormalMap);
+ }
+
+ if (params.mSpecularMap)
+ {
+ params.mSpecularMap->addTextureStats(params.mVSize);
+ bindSpecularMap(params.mSpecularMap);
+ }
+
+ mShader->setMinimumAlpha(params.mAlphaMaskCutoff);
+ mShader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, params.mFullbright ? 1.f : 0.f);
+
+ pushBatch(params, mask, TRUE);
+ }
+}
+
+void LLDrawPoolMaterials::bindSpecularMap(LLViewerTexture* tex)
+{
+ mShader->bindTexture(LLShaderMgr::SPECULAR_MAP, tex);
+}
+
+void LLDrawPoolMaterials::bindNormalMap(LLViewerTexture* tex)
+{
+ mShader->bindTexture(LLShaderMgr::BUMP_MAP, tex);
+}
+
+void LLDrawPoolMaterials::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures)
+{
+ applyModelMatrix(params);
+
+ bool tex_setup = false;
+
+ if (batch_textures && params.mTextureList.size() > 1)
+ {
+ for (U32 i = 0; i < params.mTextureList.size(); ++i)
+ {
+ if (params.mTextureList[i].notNull())
+ {
+ gGL.getTexUnit(i)->bind(params.mTextureList[i], TRUE);
+ }
+ }
+ }
+ else
+ { //not batching textures or batch has only 1 texture -- might need a texture matrix
+ if (params.mTextureMatrix)
+ {
+ //if (mShiny)
+ {
+ gGL.getTexUnit(0)->activate();
+ gGL.matrixMode(LLRender::MM_TEXTURE);
+ }
+
+ gGL.loadMatrix((GLfloat*) params.mTextureMatrix->mMatrix);
+ gPipeline.mTextureMatrixOps++;
+
+ tex_setup = true;
+ }
+
+ if (mVertexShaderLevel > 1 && texture)
+ {
+ if (params.mTexture.notNull())
+ {
+ gGL.getTexUnit(diffuse_channel)->bind(params.mTexture);
+ params.mTexture->addTextureStats(params.mVSize);
+ }
+ else
+ {
+ gGL.getTexUnit(diffuse_channel)->unbind(LLTexUnit::TT_TEXTURE);
+ }
+ }
+ }
+
+ if (params.mGroup)
+ {
+ params.mGroup->rebuildMesh();
+ }
+ params.mVertexBuffer->setBuffer(mask);
+ params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
+ gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode);
+ if (tex_setup)
+ {
+ gGL.getTexUnit(0)->activate();
+ gGL.loadIdentity();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ }
+}
+
diff --git a/indra/newview/lldrawpoolmaterials.h b/indra/newview/lldrawpoolmaterials.h
new file mode 100644
index 0000000000..eae1aba87c
--- /dev/null
+++ b/indra/newview/lldrawpoolmaterials.h
@@ -0,0 +1,75 @@
+/**
+ * @file lldrawpoolmaterials.h
+ * @brief LLDrawPoolMaterials class definition
+ * @author Jonathan "Geenz" Goodman
+ *
+ * $LicenseInfo:firstyear=2002&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2013, 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_LLDRAWPOOLMATERIALS_H
+#define LL_LLDRAWPOOLMATERIALS_H
+
+#include "v4coloru.h"
+#include "v2math.h"
+#include "v3math.h"
+#include "llvertexbuffer.h"
+#include "lldrawpool.h"
+
+class LLViewerTexture;
+class LLDrawInfo;
+class LLGLSLShader;
+
+class LLDrawPoolMaterials : public LLRenderPass
+{
+ LLGLSLShader *mShader;
+public:
+ LLDrawPoolMaterials();
+
+ enum
+ {
+ VERTEX_DATA_MASK = LLVertexBuffer::MAP_VERTEX |
+ LLVertexBuffer::MAP_NORMAL |
+ LLVertexBuffer::MAP_TEXCOORD0 |
+ LLVertexBuffer::MAP_TEXCOORD1 |
+ LLVertexBuffer::MAP_TEXCOORD2 |
+ LLVertexBuffer::MAP_COLOR |
+ LLVertexBuffer::MAP_TANGENT
+ };
+
+ /*virtual*/ U32 getVertexDataMask() { return VERTEX_DATA_MASK; }
+
+ /*virtual*/ void render(S32 pass = 0) { }
+ /*virtual*/ S32 getNumPasses() {return 0;}
+ /*virtual*/ void prerender();
+
+ /*virtual*/ S32 getNumDeferredPasses();
+ /*virtual*/ void beginDeferredPass(S32 pass);
+ /*virtual*/ void endDeferredPass(S32 pass);
+ /*virtual*/ void renderDeferred(S32 pass);
+
+ void bindSpecularMap(LLViewerTexture* tex);
+ void bindNormalMap(LLViewerTexture* tex);
+
+ /*virtual*/ void pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures = FALSE);
+};
+
+#endif //LL_LLDRAWPOOLMATERIALS_H
diff --git a/indra/newview/lldrawpoolsimple.cpp b/indra/newview/lldrawpoolsimple.cpp
index 6e0ea78af2..8926f64c64 100644..100755
--- a/indra/newview/lldrawpoolsimple.cpp
+++ b/indra/newview/lldrawpoolsimple.cpp
@@ -37,6 +37,7 @@
#include "llviewershadermgr.h"
#include "llrender.h"
+#define GE_FORCE_WORKAROUND LL_DARWIN
static LLGLSLShader* simple_shader = NULL;
static LLGLSLShader* fullbright_shader = NULL;
@@ -47,6 +48,7 @@ static LLFastTimer::DeclareTimer FTM_RENDER_GRASS_DEFERRED("Deferred Grass");
void LLDrawPoolGlow::beginPostDeferredPass(S32 pass)
{
gDeferredEmissiveProgram.bind();
+ gDeferredEmissiveProgram.uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
}
static LLFastTimer::DeclareTimer FTM_RENDER_GLOW_PUSH("Glow Push");
@@ -110,6 +112,14 @@ void LLDrawPoolGlow::render(S32 pass)
LLGLSLShader* shader = LLPipeline::sUnderWaterRender ? &gObjectEmissiveWaterProgram : &gObjectEmissiveProgram;
shader->bind();
+ if (LLPipeline::sRenderDeferred)
+ {
+ shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
+ }
+ else
+ {
+ shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.f);
+ }
LLGLDepthTest depth(GL_TRUE, GL_FALSE);
gGL.setColorMask(false, true);
@@ -146,7 +156,11 @@ void LLDrawPoolSimple::beginRenderPass(S32 pass)
{
LLFastTimer t(FTM_RENDER_SIMPLE);
- if (LLPipeline::sUnderWaterRender)
+ if (LLPipeline::sImpostorRender)
+ {
+ simple_shader = &gObjectSimpleImpostorProgram;
+ }
+ else if (LLPipeline::sUnderWaterRender)
{
simple_shader = &gObjectSimpleWaterProgram;
}
@@ -198,7 +212,11 @@ void LLDrawPoolSimple::render(S32 pass)
if (LLPipeline::sRenderDeferred)
{ //if deferred rendering is enabled, bump faces aren't registered as simple
//render bump faces here as simple so bump faces will appear under water
- pushBatches(LLRenderPass::PASS_BUMP, mask, TRUE, TRUE);
+ pushBatches(LLRenderPass::PASS_BUMP, mask, TRUE, TRUE);
+ pushBatches(LLRenderPass::PASS_MATERIAL, mask, TRUE, TRUE);
+ pushBatches(LLRenderPass::PASS_SPECMAP, mask, TRUE, TRUE);
+ pushBatches(LLRenderPass::PASS_NORMMAP, mask, TRUE, TRUE);
+ pushBatches(LLRenderPass::PASS_NORMSPEC, mask, TRUE, TRUE);
}
}
else
@@ -210,6 +228,169 @@ void LLDrawPoolSimple::render(S32 pass)
}
}
+
+
+
+
+
+
+
+
+
+static LLFastTimer::DeclareTimer FTM_RENDER_ALPHA_MASK("Alpha Mask");
+
+LLDrawPoolAlphaMask::LLDrawPoolAlphaMask() :
+ LLRenderPass(POOL_ALPHA_MASK)
+{
+}
+
+void LLDrawPoolAlphaMask::prerender()
+{
+ mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
+}
+
+void LLDrawPoolAlphaMask::beginRenderPass(S32 pass)
+{
+ LLFastTimer t(FTM_RENDER_ALPHA_MASK);
+
+ if (LLPipeline::sUnderWaterRender)
+ {
+ simple_shader = &gObjectSimpleWaterAlphaMaskProgram;
+ }
+ else
+ {
+ simple_shader = &gObjectSimpleAlphaMaskProgram;
+ }
+
+ if (mVertexShaderLevel > 0)
+ {
+ simple_shader->bind();
+ }
+ else
+ {
+ // don't use shaders!
+ if (gGLManager.mHasShaderObjects)
+ {
+ LLGLSLShader::bindNoShader();
+ }
+ }
+}
+
+void LLDrawPoolAlphaMask::endRenderPass(S32 pass)
+{
+ LLFastTimer t(FTM_RENDER_ALPHA_MASK);
+ stop_glerror();
+ LLRenderPass::endRenderPass(pass);
+ stop_glerror();
+ if (mVertexShaderLevel > 0)
+ {
+ simple_shader->unbind();
+ }
+}
+
+void LLDrawPoolAlphaMask::render(S32 pass)
+{
+ LLGLDisable blend(GL_BLEND);
+ LLFastTimer t(FTM_RENDER_ALPHA_MASK);
+
+ if (mVertexShaderLevel > 0)
+ {
+ simple_shader->bind();
+ simple_shader->setMinimumAlpha(0.33f);
+
+ pushMaskBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
+ pushMaskBatches(LLRenderPass::PASS_MATERIAL_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
+ pushMaskBatches(LLRenderPass::PASS_SPECMAP_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
+ pushMaskBatches(LLRenderPass::PASS_NORMMAP_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
+ pushMaskBatches(LLRenderPass::PASS_NORMSPEC_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
+ }
+ else
+ {
+ LLGLEnable test(GL_ALPHA_TEST);
+ pushMaskBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask(), TRUE, FALSE);
+ gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); //OK
+ }
+}
+
+LLDrawPoolFullbrightAlphaMask::LLDrawPoolFullbrightAlphaMask() :
+ LLRenderPass(POOL_FULLBRIGHT_ALPHA_MASK)
+{
+}
+
+void LLDrawPoolFullbrightAlphaMask::prerender()
+{
+ mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
+}
+
+void LLDrawPoolFullbrightAlphaMask::beginRenderPass(S32 pass)
+{
+ LLFastTimer t(FTM_RENDER_ALPHA_MASK);
+
+ if (LLPipeline::sUnderWaterRender)
+ {
+ simple_shader = &gObjectFullbrightWaterAlphaMaskProgram;
+ }
+ else
+ {
+ simple_shader = &gObjectFullbrightAlphaMaskProgram;
+ }
+
+ if (mVertexShaderLevel > 0)
+ {
+ simple_shader->bind();
+ }
+ else
+ {
+ // don't use shaders!
+ if (gGLManager.mHasShaderObjects)
+ {
+ LLGLSLShader::bindNoShader();
+ }
+ }
+}
+
+void LLDrawPoolFullbrightAlphaMask::endRenderPass(S32 pass)
+{
+ LLFastTimer t(FTM_RENDER_ALPHA_MASK);
+ stop_glerror();
+ LLRenderPass::endRenderPass(pass);
+ stop_glerror();
+ if (mVertexShaderLevel > 0)
+ {
+ simple_shader->unbind();
+ }
+}
+
+void LLDrawPoolFullbrightAlphaMask::render(S32 pass)
+{
+ LLFastTimer t(FTM_RENDER_ALPHA_MASK);
+
+ if (mVertexShaderLevel > 0)
+ {
+ if (simple_shader)
+ {
+ simple_shader->bind();
+ simple_shader->setMinimumAlpha(0.33f);
+ if (LLPipeline::sRenderingHUDs || !LLPipeline::sRenderDeferred)
+ {
+ simple_shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f);
+ } else {
+ simple_shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
+ }
+ }
+ pushMaskBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
+ //LLGLSLShader::bindNoShader();
+ }
+ else
+ {
+ LLGLEnable test(GL_ALPHA_TEST);
+ gPipeline.enableLightsFullbright(LLColor4(1,1,1,1));
+ pushMaskBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, getVertexDataMask(), TRUE, FALSE);
+ gPipeline.enableLightsDynamic();
+ gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); //OK
+ }
+}
+
//===============================
//DEFERRED IMPLEMENTATION
//===============================
@@ -239,6 +420,28 @@ void LLDrawPoolSimple::renderDeferred(S32 pass)
}
}
+static LLFastTimer::DeclareTimer FTM_RENDER_ALPHA_MASK_DEFERRED("Deferred Alpha Mask");
+
+void LLDrawPoolAlphaMask::beginDeferredPass(S32 pass)
+{
+
+}
+
+void LLDrawPoolAlphaMask::endDeferredPass(S32 pass)
+{
+
+}
+
+void LLDrawPoolAlphaMask::renderDeferred(S32 pass)
+{
+ LLFastTimer t(FTM_RENDER_ALPHA_MASK_DEFERRED);
+ gDeferredDiffuseAlphaMaskProgram.bind();
+ gDeferredDiffuseAlphaMaskProgram.setMinimumAlpha(0.33f);
+ pushMaskBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
+ gDeferredDiffuseAlphaMaskProgram.unbind();
+}
+
+
// grass drawpool
LLDrawPoolGrass::LLDrawPoolGrass() :
LLRenderPass(POOL_GRASS)
@@ -345,7 +548,15 @@ void LLDrawPoolFullbright::prerender()
void LLDrawPoolFullbright::beginPostDeferredPass(S32 pass)
{
- gDeferredFullbrightProgram.bind();
+ if (LLPipeline::sUnderWaterRender)
+ {
+ gDeferredFullbrightWaterProgram.bind();
+ }
+ else
+ {
+ gDeferredFullbrightProgram.bind();
+ }
+
}
void LLDrawPoolFullbright::renderPostDeferred(S32 pass)
@@ -359,7 +570,14 @@ void LLDrawPoolFullbright::renderPostDeferred(S32 pass)
void LLDrawPoolFullbright::endPostDeferredPass(S32 pass)
{
- gDeferredFullbrightProgram.unbind();
+ if (LLPipeline::sUnderWaterRender)
+ {
+ gDeferredFullbrightWaterProgram.unbind();
+ }
+ else
+ {
+ gDeferredFullbrightProgram.unbind();
+ }
LLRenderPass::endRenderPass(pass);
}
@@ -403,14 +621,24 @@ void LLDrawPoolFullbright::render(S32 pass)
{
fullbright_shader->bind();
fullbright_shader->uniform1f(LLViewerShaderMgr::FULLBRIGHT, 1.f);
+ fullbright_shader->uniform1f(LLViewerShaderMgr::TEXTURE_GAMMA, 1.f);
+
U32 fullbright_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXTURE_INDEX;
pushBatches(LLRenderPass::PASS_FULLBRIGHT, fullbright_mask, TRUE, TRUE);
+ pushBatches(LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE, fullbright_mask, TRUE, TRUE);
+ pushBatches(LLRenderPass::PASS_SPECMAP_EMISSIVE, fullbright_mask, TRUE, TRUE);
+ pushBatches(LLRenderPass::PASS_NORMMAP_EMISSIVE, fullbright_mask, TRUE, TRUE);
+ pushBatches(LLRenderPass::PASS_NORMSPEC_EMISSIVE, fullbright_mask, TRUE, TRUE);
}
else
{
gPipeline.enableLightsFullbright(LLColor4(1,1,1,1));
U32 fullbright_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR;
renderTexture(LLRenderPass::PASS_FULLBRIGHT, fullbright_mask);
+ pushBatches(LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE, fullbright_mask);
+ pushBatches(LLRenderPass::PASS_SPECMAP_EMISSIVE, fullbright_mask);
+ pushBatches(LLRenderPass::PASS_NORMMAP_EMISSIVE, fullbright_mask);
+ pushBatches(LLRenderPass::PASS_NORMSPEC_EMISSIVE, fullbright_mask);
}
stop_glerror();
@@ -421,3 +649,75 @@ S32 LLDrawPoolFullbright::getNumPasses()
return 1;
}
+
+void LLDrawPoolFullbrightAlphaMask::beginPostDeferredPass(S32 pass)
+{
+
+ if (LLPipeline::sRenderingHUDs || !LLPipeline::sRenderDeferred)
+ {
+ gObjectFullbrightAlphaMaskProgram.bind();
+ gObjectFullbrightAlphaMaskProgram.uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f);
+ }
+ else
+ {
+
+// Work-around until we can figure out why the right shader causes
+// the GeForce driver to go tango uniform on OS X 10.6.8 only
+//
+#if GE_FORCE_WORKAROUND
+ gObjectFullbrightAlphaMaskProgram.bind();
+ gObjectFullbrightAlphaMaskProgram.uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
+#else
+ if (LLPipeline::sUnderWaterRender)
+ {
+ gDeferredFullbrightAlphaMaskWaterProgram.bind();
+ gDeferredFullbrightAlphaMaskWaterProgram.uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
+ }
+ else
+ {
+ gDeferredFullbrightAlphaMaskProgram.bind();
+ gDeferredFullbrightAlphaMaskProgram.uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
+ }
+#endif
+ }
+
+}
+
+void LLDrawPoolFullbrightAlphaMask::renderPostDeferred(S32 pass)
+{
+ LLFastTimer t(FTM_RENDER_FULLBRIGHT);
+ LLGLDisable blend(GL_BLEND);
+ U32 fullbright_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXTURE_INDEX;
+ pushMaskBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, fullbright_mask, TRUE, TRUE);
+}
+
+void LLDrawPoolFullbrightAlphaMask::endPostDeferredPass(S32 pass)
+{
+ if (LLPipeline::sRenderingHUDs || !LLPipeline::sRenderDeferred)
+ {
+ gObjectFullbrightAlphaMaskProgram.unbind();
+ }
+ else
+ {
+
+// Work-around until we can figure out why the right shader causes
+// the GeForce driver to go tango uniform on OS X 10.6.8 only
+//
+#if GE_FORCE_WORKAROUND
+ gObjectFullbrightAlphaMaskProgram.unbind();
+#else
+ if (LLPipeline::sUnderWaterRender)
+ {
+ gDeferredFullbrightAlphaMaskWaterProgram.unbind();
+ }
+ else
+ {
+ gDeferredFullbrightAlphaMaskProgram.unbind();
+ }
+#endif
+
+ }
+ LLRenderPass::endRenderPass(pass);
+}
+
+
diff --git a/indra/newview/lldrawpoolsimple.h b/indra/newview/lldrawpoolsimple.h
index bd62bc7502..608ad9e1eb 100644..100755
--- a/indra/newview/lldrawpoolsimple.h
+++ b/indra/newview/lldrawpoolsimple.h
@@ -84,6 +84,59 @@ public:
/*virtual*/ void prerender();
};
+class LLDrawPoolAlphaMask : public LLRenderPass
+{
+public:
+ enum
+ {
+ VERTEX_DATA_MASK = LLVertexBuffer::MAP_VERTEX |
+ LLVertexBuffer::MAP_NORMAL |
+ LLVertexBuffer::MAP_TEXCOORD0 |
+ LLVertexBuffer::MAP_COLOR
+ };
+ virtual U32 getVertexDataMask() { return VERTEX_DATA_MASK; }
+
+ LLDrawPoolAlphaMask();
+
+ /*virtual*/ S32 getNumDeferredPasses() { return 1; }
+ /*virtual*/ void beginDeferredPass(S32 pass);
+ /*virtual*/ void endDeferredPass(S32 pass);
+ /*virtual*/ void renderDeferred(S32 pass);
+
+ /*virtual*/ S32 getNumPasses() { return 1; }
+ /*virtual*/ void beginRenderPass(S32 pass);
+ /*virtual*/ void endRenderPass(S32 pass);
+ /*virtual*/ void render(S32 pass = 0);
+ /*virtual*/ void prerender();
+
+};
+
+class LLDrawPoolFullbrightAlphaMask : public LLRenderPass
+{
+public:
+ enum
+ {
+ VERTEX_DATA_MASK = LLVertexBuffer::MAP_VERTEX |
+ LLVertexBuffer::MAP_TEXCOORD0 |
+ LLVertexBuffer::MAP_COLOR
+ };
+ virtual U32 getVertexDataMask() { return VERTEX_DATA_MASK; }
+
+ LLDrawPoolFullbrightAlphaMask();
+
+ /*virtual*/ S32 getNumPostDeferredPasses() { return 1; }
+ /*virtual*/ void beginPostDeferredPass(S32 pass);
+ /*virtual*/ void endPostDeferredPass(S32 pass);
+ /*virtual*/ void renderPostDeferred(S32 pass);
+
+ /*virtual*/ S32 getNumPasses() { return 1; }
+ /*virtual*/ void beginRenderPass(S32 pass);
+ /*virtual*/ void endRenderPass(S32 pass);
+ /*virtual*/ void render(S32 pass = 0);
+ /*virtual*/ void prerender();
+};
+
+
class LLDrawPoolFullbright : public LLRenderPass
{
public:
diff --git a/indra/newview/lldrawpoolsky.cpp b/indra/newview/lldrawpoolsky.cpp
index 7f7d9f65c6..ef8bdc3304 100644..100755
--- a/indra/newview/lldrawpoolsky.cpp
+++ b/indra/newview/lldrawpoolsky.cpp
@@ -155,3 +155,4 @@ void LLDrawPoolSky::renderSkyCubeFace(U8 side)
void LLDrawPoolSky::endRenderPass( S32 pass )
{
}
+
diff --git a/indra/newview/lldrawpoolsky.h b/indra/newview/lldrawpoolsky.h
index 098bd2134a..098bd2134a 100644..100755
--- a/indra/newview/lldrawpoolsky.h
+++ b/indra/newview/lldrawpoolsky.h
diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp
index b95d8296fa..c3ec234223 100644..100755
--- a/indra/newview/lldrawpoolterrain.cpp
+++ b/indra/newview/lldrawpoolterrain.cpp
@@ -69,7 +69,8 @@ LLDrawPoolTerrain::LLDrawPoolTerrain(LLViewerTexture *texturep) :
sDetailScale = 1.f/gSavedSettings.getF32("RenderTerrainScale");
sDetailMode = gSavedSettings.getS32("RenderTerrainDetail");
mAlphaRampImagep = LLViewerTextureManager::getFetchedTextureFromFile("alpha_gradient.tga",
- TRUE, LLViewerTexture::BOOST_UI,
+ FTT_LOCAL_FILE,
+ TRUE, LLGLTexture::BOOST_UI,
LLViewerTexture::FETCHED_TEXTURE,
format, int_format,
LLUUID("e97cf410-8e61-7005-ec06-629eba4cd1fb"));
@@ -78,7 +79,8 @@ LLDrawPoolTerrain::LLDrawPoolTerrain(LLViewerTexture *texturep) :
mAlphaRampImagep->setAddressMode(LLTexUnit::TAM_CLAMP);
m2DAlphaRampImagep = LLViewerTextureManager::getFetchedTextureFromFile("alpha_gradient_2d.j2c",
- TRUE, LLViewerTexture::BOOST_UI,
+ FTT_LOCAL_FILE,
+ TRUE, LLGLTexture::BOOST_UI,
LLViewerTexture::FETCHED_TEXTURE,
format, int_format,
LLUUID("38b86f85-2575-52a9-a531-23108d8da837"));
@@ -86,7 +88,7 @@ LLDrawPoolTerrain::LLDrawPoolTerrain(LLViewerTexture *texturep) :
//gGL.getTexUnit(0)->bind(m2DAlphaRampImagep.get());
m2DAlphaRampImagep->setAddressMode(LLTexUnit::TAM_CLAMP);
- mTexturep->setBoostLevel(LLViewerTexture::BOOST_TERRAIN);
+ mTexturep->setBoostLevel(LLGLTexture::BOOST_TERRAIN);
//gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
}
@@ -170,7 +172,7 @@ void LLDrawPoolTerrain::render(S32 pass)
LLVLComposition *compp = regionp->getComposition();
for (S32 i = 0; i < 4; i++)
{
- compp->mDetailTextures[i]->setBoostLevel(LLViewerTexture::BOOST_TERRAIN);
+ compp->mDetailTextures[i]->setBoostLevel(LLGLTexture::BOOST_TERRAIN);
compp->mDetailTextures[i]->addTextureStats(1024.f*1024.f); // assume large pixel area
}
@@ -294,6 +296,35 @@ void LLDrawPoolTerrain::renderShadow(S32 pass)
//glCullFace(GL_BACK);
}
+
+void LLDrawPoolTerrain::drawLoop()
+{
+ if (!mDrawFace.empty())
+ {
+ for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
+ iter != mDrawFace.end(); iter++)
+ {
+ LLFace *facep = *iter;
+
+ LLMatrix4* model_matrix = &(facep->getDrawable()->getRegion()->mRenderMatrix);
+
+ if (model_matrix != gGLLastMatrix)
+ {
+ llassert(gGL.getMatrixMode() == LLRender::MM_MODELVIEW);
+ gGLLastMatrix = model_matrix;
+ gGL.loadMatrix(gGLModelView);
+ if (model_matrix)
+ {
+ gGL.multMatrix((GLfloat*) model_matrix->mMatrix);
+ }
+ gPipeline.mMatrixOpCount++;
+ }
+
+ facep->renderIndexed();
+ }
+ }
+}
+
void LLDrawPoolTerrain::renderFullShader()
{
// Hack! Get the region that this draw pool is rendering from!
@@ -323,8 +354,8 @@ void LLDrawPoolTerrain::renderFullShader()
LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
llassert(shader);
- shader->uniform4fv("object_plane_s", 1, tp0.mV);
- shader->uniform4fv("object_plane_t", 1, tp1.mV);
+ shader->uniform4fv(LLShaderMgr::OBJECT_PLANE_S, 1, tp0.mV);
+ shader->uniform4fv(LLShaderMgr::OBJECT_PLANE_T, 1, tp1.mV);
gGL.matrixMode(LLRender::MM_TEXTURE);
gGL.loadIdentity();
@@ -566,7 +597,8 @@ void LLDrawPoolTerrain::renderFull4TU()
gGL.matrixMode(LLRender::MM_TEXTURE);
gGL.loadIdentity();
gGL.translatef(-1.f, 0.f, 0.f);
-
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+
// Set alpha texture and do lighting modulation
gGL.getTexUnit(3)->setTextureColorBlend(LLTexUnit::TBO_MULT, LLTexUnit::TBS_PREV_COLOR, LLTexUnit::TBS_VERT_COLOR);
gGL.getTexUnit(3)->setTextureAlphaBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_TEX_ALPHA);
@@ -714,6 +746,7 @@ void LLDrawPoolTerrain::renderFull2TU()
gGL.matrixMode(LLRender::MM_TEXTURE);
gGL.loadIdentity();
gGL.translatef(-1.f, 0.f, 0.f);
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
// Care about alpha only
gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_PREV_COLOR);
@@ -753,6 +786,7 @@ void LLDrawPoolTerrain::renderFull2TU()
gGL.matrixMode(LLRender::MM_TEXTURE);
gGL.loadIdentity();
gGL.translatef(-2.f, 0.f, 0.f);
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
// Care about alpha only
gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_PREV_COLOR);
@@ -830,8 +864,8 @@ void LLDrawPoolTerrain::renderSimple()
if (LLGLSLShader::sNoFixedFunction)
{
- sShader->uniform4fv("object_plane_s", 1, tp0.mV);
- sShader->uniform4fv("object_plane_t", 1, tp1.mV);
+ sShader->uniform4fv(LLShaderMgr::OBJECT_PLANE_S, 1, tp0.mV);
+ sShader->uniform4fv(LLShaderMgr::OBJECT_PLANE_T, 1, tp1.mV);
}
else
{
diff --git a/indra/newview/lldrawpoolterrain.h b/indra/newview/lldrawpoolterrain.h
index 283ed87f1a..2163d087e1 100644..100755
--- a/indra/newview/lldrawpoolterrain.h
+++ b/indra/newview/lldrawpoolterrain.h
@@ -83,6 +83,7 @@ protected:
void renderFull2TU();
void renderFull4TU();
void renderFullShader();
+ void drawLoop();
};
#endif // LL_LLDRAWPOOLSIMPLE_H
diff --git a/indra/newview/lldrawpooltree.cpp b/indra/newview/lldrawpooltree.cpp
index 3165a3516c..fedbd782dc 100644..100755
--- a/indra/newview/lldrawpooltree.cpp
+++ b/indra/newview/lldrawpooltree.cpp
@@ -37,6 +37,7 @@
#include "llviewershadermgr.h"
#include "llrender.h"
#include "llviewercontrol.h"
+#include "llviewerregion.h"
S32 LLDrawPoolTree::sDiffTex = 0;
static LLGLSLShader* shader = NULL;
@@ -104,8 +105,23 @@ void LLDrawPoolTree::render(S32 pass)
{
LLFace *face = *iter;
LLVertexBuffer* buff = face->getVertexBuffer();
+
if(buff)
{
+ LLMatrix4* model_matrix = &(face->getDrawable()->getRegion()->mRenderMatrix);
+
+ if (model_matrix != gGLLastMatrix)
+ {
+ gGLLastMatrix = model_matrix;
+ gGL.loadMatrix(gGLModelView);
+ if (model_matrix)
+ {
+ llassert(gGL.getMatrixMode() == LLRender::MM_MODELVIEW);
+ gGL.multMatrix((GLfloat*) model_matrix->mMatrix);
+ }
+ gPipeline.mMatrixOpCount++;
+ }
+
buff->setBuffer(LLDrawPoolTree::VERTEX_DATA_MASK);
buff->drawRange(LLRender::TRIANGLES, 0, buff->getNumVerts()-1, buff->getNumIndices(), 0);
gPipeline.addTrianglesDrawn(buff->getNumIndices());
diff --git a/indra/newview/lldrawpooltree.h b/indra/newview/lldrawpooltree.h
index e7e25453cf..e7e25453cf 100644..100755
--- a/indra/newview/lldrawpooltree.h
+++ b/indra/newview/lldrawpooltree.h
diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp
index 4f6eaa5a5b..76e89b26e4 100644..100755
--- a/indra/newview/lldrawpoolwater.cpp
+++ b/indra/newview/lldrawpoolwater.cpp
@@ -66,11 +66,11 @@ LLVector3 LLDrawPoolWater::sLightDir;
LLDrawPoolWater::LLDrawPoolWater() :
LLFacePool(POOL_WATER)
{
- mHBTex[0] = LLViewerTextureManager::getFetchedTexture(gSunTextureID, TRUE, LLViewerTexture::BOOST_UI);
+ mHBTex[0] = LLViewerTextureManager::getFetchedTexture(gSunTextureID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);
gGL.getTexUnit(0)->bind(mHBTex[0]) ;
mHBTex[0]->setAddressMode(LLTexUnit::TAM_CLAMP);
- mHBTex[1] = LLViewerTextureManager::getFetchedTexture(gMoonTextureID, TRUE, LLViewerTexture::BOOST_UI);
+ mHBTex[1] = LLViewerTextureManager::getFetchedTexture(gMoonTextureID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);
gGL.getTexUnit(0)->bind(mHBTex[1]);
mHBTex[1]->setAddressMode(LLTexUnit::TAM_CLAMP);
@@ -407,8 +407,8 @@ void LLDrawPoolWater::renderOpaqueLegacyWater()
}
else
{
- shader->uniform4fv("object_plane_s", 1, tp0);
- shader->uniform4fv("object_plane_t", 1, tp1);
+ shader->uniform4fv(LLShaderMgr::OBJECT_PLANE_S, 1, tp0);
+ shader->uniform4fv(LLShaderMgr::OBJECT_PLANE_T, 1, tp1);
}
gGL.diffuseColor3f(1.f, 1.f, 1.f);
@@ -522,14 +522,21 @@ void LLDrawPoolWater::shade()
F32 eyedepth = LLViewerCamera::getInstance()->getOrigin().mV[2] - gAgent.getRegion()->getWaterHeight();
+ if (eyedepth < 0.f && LLPipeline::sWaterReflections)
+ {
if (deferred_render)
{
- shader = &gDeferredWaterProgram;
+ shader = &gDeferredUnderWaterProgram;
}
- else if (eyedepth < 0.f && LLPipeline::sWaterReflections)
+ else
{
shader = &gUnderWaterProgram;
}
+ }
+ else if (deferred_render)
+ {
+ shader = &gDeferredWaterProgram;
+ }
else
{
shader = &gWaterProgram;
@@ -546,7 +553,7 @@ void LLDrawPoolWater::shade()
sTime = (F32)LLFrameTimer::getElapsedSeconds()*0.5f;
- S32 reftex = shader->enableTexture(LLViewerShaderMgr::WATER_REFTEX);
+ S32 reftex = shader->enableTexture(LLShaderMgr::WATER_REFTEX);
if (reftex > -1)
{
@@ -577,12 +584,12 @@ void LLDrawPoolWater::shade()
mWaterNormp->setFilteringOption(LLTexUnit::TFO_POINT);
}
- S32 screentex = shader->enableTexture(LLViewerShaderMgr::WATER_SCREENTEX);
+ S32 screentex = shader->enableTexture(LLShaderMgr::WATER_SCREENTEX);
if (screentex > -1)
{
- shader->uniform4fv(LLViewerShaderMgr::WATER_FOGCOLOR, 1, sWaterFogColor.mV);
- shader->uniform1f(LLViewerShaderMgr::WATER_FOGDENSITY,
+ shader->uniform4fv(LLShaderMgr::WATER_FOGCOLOR, 1, sWaterFogColor.mV);
+ shader->uniform1f(LLShaderMgr::WATER_FOGDENSITY,
param_mgr->getFogDensity());
gPipeline.mWaterDis.bindTexture(0, screentex);
}
@@ -594,7 +601,7 @@ void LLDrawPoolWater::shade()
if (mVertexShaderLevel == 1)
{
sWaterFogColor.mV[3] = param_mgr->mDensitySliderValue;
- shader->uniform4fv(LLViewerShaderMgr::WATER_FOGCOLOR, 1, sWaterFogColor.mV);
+ shader->uniform4fv(LLShaderMgr::WATER_FOGCOLOR, 1, sWaterFogColor.mV);
}
F32 screenRes[] =
@@ -602,10 +609,10 @@ void LLDrawPoolWater::shade()
1.f/gGLViewport[2],
1.f/gGLViewport[3]
};
- shader->uniform2fv("screenRes", 1, screenRes);
+ shader->uniform2fv(LLShaderMgr::DEFERRED_SCREEN_RES, 1, screenRes);
stop_glerror();
- S32 diffTex = shader->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
+ S32 diffTex = shader->enableTexture(LLShaderMgr::DIFFUSE_MAP);
stop_glerror();
light_dir.normVec();
@@ -614,26 +621,26 @@ void LLDrawPoolWater::shade()
light_diffuse *= 6.f;
//shader->uniformMatrix4fv("inverse_ref", 1, GL_FALSE, (GLfloat*) gGLObliqueProjectionInverse.mMatrix);
- shader->uniform1f(LLViewerShaderMgr::WATER_WATERHEIGHT, eyedepth);
- shader->uniform1f(LLViewerShaderMgr::WATER_TIME, sTime);
- shader->uniform3fv(LLViewerShaderMgr::WATER_EYEVEC, 1, LLViewerCamera::getInstance()->getOrigin().mV);
- shader->uniform3fv(LLViewerShaderMgr::WATER_SPECULAR, 1, light_diffuse.mV);
- shader->uniform1f(LLViewerShaderMgr::WATER_SPECULAR_EXP, light_exp);
- shader->uniform2fv(LLViewerShaderMgr::WATER_WAVE_DIR1, 1, param_mgr->getWave1Dir().mV);
- shader->uniform2fv(LLViewerShaderMgr::WATER_WAVE_DIR2, 1, param_mgr->getWave2Dir().mV);
- shader->uniform3fv(LLViewerShaderMgr::WATER_LIGHT_DIR, 1, light_dir.mV);
-
- shader->uniform3fv("normScale", 1, param_mgr->getNormalScale().mV);
- shader->uniform1f("fresnelScale", param_mgr->getFresnelScale());
- shader->uniform1f("fresnelOffset", param_mgr->getFresnelOffset());
- shader->uniform1f("blurMultiplier", param_mgr->getBlurMultiplier());
+ shader->uniform1f(LLShaderMgr::WATER_WATERHEIGHT, eyedepth);
+ shader->uniform1f(LLShaderMgr::WATER_TIME, sTime);
+ shader->uniform3fv(LLShaderMgr::WATER_EYEVEC, 1, LLViewerCamera::getInstance()->getOrigin().mV);
+ shader->uniform3fv(LLShaderMgr::WATER_SPECULAR, 1, light_diffuse.mV);
+ shader->uniform1f(LLShaderMgr::WATER_SPECULAR_EXP, light_exp);
+ shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR1, 1, param_mgr->getWave1Dir().mV);
+ shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR2, 1, param_mgr->getWave2Dir().mV);
+ shader->uniform3fv(LLShaderMgr::WATER_LIGHT_DIR, 1, light_dir.mV);
+
+ shader->uniform3fv(LLShaderMgr::WATER_NORM_SCALE, 1, param_mgr->getNormalScale().mV);
+ shader->uniform1f(LLShaderMgr::WATER_FRESNEL_SCALE, param_mgr->getFresnelScale());
+ shader->uniform1f(LLShaderMgr::WATER_FRESNEL_OFFSET, param_mgr->getFresnelOffset());
+ shader->uniform1f(LLShaderMgr::WATER_BLUR_MULTIPLIER, param_mgr->getBlurMultiplier());
F32 sunAngle = llmax(0.f, light_dir.mV[2]);
F32 scaledAngle = 1.f - sunAngle;
- shader->uniform1f("sunAngle", sunAngle);
- shader->uniform1f("scaledAngle", scaledAngle);
- shader->uniform1f("sunAngle2", 0.1f + 0.2f*sunAngle);
+ shader->uniform1f(LLShaderMgr::WATER_SUN_ANGLE, sunAngle);
+ shader->uniform1f(LLShaderMgr::WATER_SCALED_ANGLE, scaledAngle);
+ shader->uniform1f(LLShaderMgr::WATER_SUN_ANGLE2, 0.1f + 0.2f*sunAngle);
LLColor4 water_color;
LLVector3 camera_up = LLViewerCamera::getInstance()->getUpAxis();
@@ -641,12 +648,12 @@ void LLDrawPoolWater::shade()
if (LLViewerCamera::getInstance()->cameraUnderWater())
{
water_color.setVec(1.f, 1.f, 1.f, 0.4f);
- shader->uniform1f(LLViewerShaderMgr::WATER_REFSCALE, param_mgr->getScaleBelow());
+ shader->uniform1f(LLShaderMgr::WATER_REFSCALE, param_mgr->getScaleBelow());
}
else
{
water_color.setVec(1.f, 1.f, 1.f, 0.5f*(1.f + up_dot));
- shader->uniform1f(LLViewerShaderMgr::WATER_REFSCALE, param_mgr->getScaleAbove());
+ shader->uniform1f(LLShaderMgr::WATER_REFSCALE, param_mgr->getScaleAbove());
}
if (water_color.mV[3] > 0.9f)
@@ -689,12 +696,12 @@ void LLDrawPoolWater::shade()
}
}
- shader->disableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP);
- shader->disableTexture(LLViewerShaderMgr::WATER_SCREENTEX);
- shader->disableTexture(LLViewerShaderMgr::BUMP_MAP);
- shader->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
- shader->disableTexture(LLViewerShaderMgr::WATER_REFTEX);
- shader->disableTexture(LLViewerShaderMgr::WATER_SCREENDEPTH);
+ shader->disableTexture(LLShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP);
+ shader->disableTexture(LLShaderMgr::WATER_SCREENTEX);
+ shader->disableTexture(LLShaderMgr::BUMP_MAP);
+ shader->disableTexture(LLShaderMgr::DIFFUSE_MAP);
+ shader->disableTexture(LLShaderMgr::WATER_REFTEX);
+ shader->disableTexture(LLShaderMgr::WATER_SCREENDEPTH);
if (deferred_render)
{
diff --git a/indra/newview/lldrawpoolwater.h b/indra/newview/lldrawpoolwater.h
index aeeba179d6..aeeba179d6 100644..100755
--- a/indra/newview/lldrawpoolwater.h
+++ b/indra/newview/lldrawpoolwater.h
diff --git a/indra/newview/lldrawpoolwlsky.cpp b/indra/newview/lldrawpoolwlsky.cpp
index caf15fe1cb..a98d3e6b05 100644..100755
--- a/indra/newview/lldrawpoolwlsky.cpp
+++ b/indra/newview/lldrawpoolwlsky.cpp
@@ -152,7 +152,8 @@ void LLDrawPoolWLSky::renderDome(F32 camHeightLocal, LLGLSLShader * shader) cons
gGL.translatef(0.f,-camHeightLocal, 0.f);
// Draw WL Sky
- shader->uniform3f("camPosLocal", 0.f, camHeightLocal, 0.f);
+ static LLStaticHashedString sCamPosLocal("camPosLocal");
+ shader->uniform3f(sCamPosLocal, 0.f, camHeightLocal, 0.f);
gSky.mVOWLSkyp->drawDome();
@@ -192,18 +193,23 @@ void LLDrawPoolWLSky::renderStars(void) const
bool error;
LLColor4 star_alpha(LLColor4::black);
star_alpha.mV[3] = LLWLParamManager::getInstance()->mCurParams.getFloat("star_brightness", error) / 2.f;
- llassert_always(!error);
+
+ // If start_brightness is not set, exit
+ if( error )
+ {
+ llwarns << "star_brightness missing in mCurParams" << llendl;
+ return;
+ }
gGL.getTexUnit(0)->bind(gSky.mVOSkyp->getBloomTex());
gGL.pushMatrix();
gGL.rotatef(gFrameTimeSeconds*0.01f, 0.f, 0.f, 1.f);
- // gl_FragColor.rgb = gl_Color.rgb;
- // gl_FragColor.a = gl_Color.a * star_alpha.a;
if (LLGLSLShader::sNoFixedFunction)
{
gCustomAlphaProgram.bind();
- gCustomAlphaProgram.uniform1f("custom_alpha", star_alpha.mV[3]);
+ static LLStaticHashedString sCustomAlpha("custom_alpha");
+ gCustomAlphaProgram.uniform1f(sCustomAlpha, star_alpha.mV[3]);
}
else
{
@@ -416,3 +422,4 @@ void LLDrawPoolWLSky::restoreGL()
sCloudNoiseTexture = LLViewerTextureManager::getLocalTexture(sCloudNoiseRawImage.get(), TRUE);
}
}
+
diff --git a/indra/newview/lldrawpoolwlsky.h b/indra/newview/lldrawpoolwlsky.h
index cd15c991ee..cd15c991ee 100644..100755
--- a/indra/newview/lldrawpoolwlsky.h
+++ b/indra/newview/lldrawpoolwlsky.h
diff --git a/indra/newview/lldriverparam.cpp b/indra/newview/lldriverparam.cpp
deleted file mode 100644
index 64eb11fc9b..0000000000
--- a/indra/newview/lldriverparam.cpp
+++ /dev/null
@@ -1,634 +0,0 @@
-/**
- * @file lldriverparam.cpp
- * @brief A visual parameter that drives (controls) other visual parameters.
- *
- * $LicenseInfo:firstyear=2002&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 "llviewerprecompiledheaders.h"
-
-#include "lldriverparam.h"
-
-#include "llfasttimer.h"
-#include "llvoavatar.h"
-#include "llvoavatarself.h"
-#include "llagent.h"
-#include "llwearable.h"
-#include "llagentwearables.h"
-
-//-----------------------------------------------------------------------------
-// LLDriverParamInfo
-//-----------------------------------------------------------------------------
-
-LLDriverParamInfo::LLDriverParamInfo()
-{
-}
-
-BOOL LLDriverParamInfo::parseXml(LLXmlTreeNode* node)
-{
- llassert( node->hasName( "param" ) && node->getChildByName( "param_driver" ) );
-
- if( !LLViewerVisualParamInfo::parseXml( node ))
- return FALSE;
-
- LLXmlTreeNode* param_driver_node = node->getChildByName( "param_driver" );
- if( !param_driver_node )
- return FALSE;
-
- for (LLXmlTreeNode* child = param_driver_node->getChildByName( "driven" );
- child;
- child = param_driver_node->getNextNamedChild())
- {
- S32 driven_id;
- static LLStdStringHandle id_string = LLXmlTree::addAttributeString("id");
- if( child->getFastAttributeS32( id_string, driven_id ) )
- {
- F32 min1 = mMinWeight;
- F32 max1 = mMaxWeight;
- F32 max2 = max1;
- F32 min2 = max1;
-
- // driven ________ //
- // ^ /| |\ //
- // | / | | \ //
- // | / | | \ //
- // | / | | \ //
- // | / | | \ //
- //-------|----|-------|----|-------> driver //
- // | min1 max1 max2 min2
-
- static LLStdStringHandle min1_string = LLXmlTree::addAttributeString("min1");
- child->getFastAttributeF32( min1_string, min1 ); // optional
- static LLStdStringHandle max1_string = LLXmlTree::addAttributeString("max1");
- child->getFastAttributeF32( max1_string, max1 ); // optional
- static LLStdStringHandle max2_string = LLXmlTree::addAttributeString("max2");
- child->getFastAttributeF32( max2_string, max2 ); // optional
- static LLStdStringHandle min2_string = LLXmlTree::addAttributeString("min2");
- child->getFastAttributeF32( min2_string, min2 ); // optional
-
- // Push these on the front of the deque, so that we can construct
- // them in order later (faster)
- mDrivenInfoList.push_front( LLDrivenEntryInfo( driven_id, min1, max1, max2, min2 ) );
- }
- else
- {
- llerrs << "<driven> Unable to resolve driven parameter: " << driven_id << llendl;
- return FALSE;
- }
- }
- return TRUE;
-}
-
-//virtual
-void LLDriverParamInfo::toStream(std::ostream &out)
-{
- LLViewerVisualParamInfo::toStream(out);
- out << "driver" << "\t";
- out << mDrivenInfoList.size() << "\t";
- for (entry_info_list_t::iterator iter = mDrivenInfoList.begin(); iter != mDrivenInfoList.end(); iter++)
- {
- LLDrivenEntryInfo driven = *iter;
- out << driven.mDrivenID << "\t";
- }
-
- out << std::endl;
-
- if(isAgentAvatarValid())
- {
- for (entry_info_list_t::iterator iter = mDrivenInfoList.begin(); iter != mDrivenInfoList.end(); iter++)
- {
- LLDrivenEntryInfo driven = *iter;
- LLViewerVisualParam *param = (LLViewerVisualParam*)gAgentAvatarp->getVisualParam(driven.mDrivenID);
- if (param)
- {
- param->getInfo()->toStream(out);
- if (param->getWearableType() != mWearableType)
- {
- if(param->getCrossWearable())
- {
- out << "cross-wearable" << "\t";
- }
- else
- {
- out << "ERROR!" << "\t";
- }
- }
- else
- {
- out << "valid" << "\t";
- }
- }
- else
- {
- llwarns << "could not get parameter " << driven.mDrivenID << " from avatar " << gAgentAvatarp.get() << " for driver parameter " << getID() << llendl;
- }
- out << std::endl;
- }
- }
-}
-
-//-----------------------------------------------------------------------------
-// LLDriverParam
-//-----------------------------------------------------------------------------
-
-LLDriverParam::LLDriverParam(LLVOAvatar *avatarp) :
- mCurrentDistortionParam( NULL ),
- mAvatarp(avatarp),
- mWearablep(NULL)
-{
-}
-
-LLDriverParam::LLDriverParam(LLWearable *wearablep) :
- mCurrentDistortionParam( NULL ),
- mAvatarp(NULL),
- mWearablep(wearablep)
-{
-}
-
-LLDriverParam::~LLDriverParam()
-{
-}
-
-BOOL LLDriverParam::setInfo(LLDriverParamInfo *info)
-{
- llassert(mInfo == NULL);
- if (info->mID < 0)
- return FALSE;
- mInfo = info;
- mID = info->mID;
-
- setWeight(getDefaultWeight(), FALSE );
-
- return TRUE;
-}
-
-void LLDriverParam::setWearable(LLWearable *wearablep)
-{
- if (wearablep)
- {
- mWearablep = wearablep;
- mAvatarp = NULL;
- }
-}
-
-void LLDriverParam::setAvatar(LLVOAvatar *avatarp)
-{
- if (avatarp)
- {
- mWearablep = NULL;
- mAvatarp = avatarp;
- }
-}
-
-/*virtual*/ LLViewerVisualParam* LLDriverParam::cloneParam(LLWearable* wearable) const
-{
- LLDriverParam *new_param;
- if (wearable)
- {
- new_param = new LLDriverParam(wearable);
- }
- else
- {
- if (mWearablep)
- {
- new_param = new LLDriverParam(mWearablep);
- }
- else
- {
- new_param = new LLDriverParam(mAvatarp);
- }
- }
- *new_param = *this;
- return new_param;
-}
-
-#if 0 // obsolete
-BOOL LLDriverParam::parseData(LLXmlTreeNode* node)
-{
- LLDriverParamInfo* info = new LLDriverParamInfo;
-
- info->parseXml(node);
- if (!setInfo(info))
- {
- delete info;
- return FALSE;
- }
- return TRUE;
-}
-#endif
-
-void LLDriverParam::setWeight(F32 weight, BOOL upload_bake)
-{
- F32 min_weight = getMinWeight();
- F32 max_weight = getMaxWeight();
- if (mIsAnimating)
- {
- // allow overshoot when animating
- mCurWeight = weight;
- }
- else
- {
- mCurWeight = llclamp(weight, min_weight, max_weight);
- }
-
- // driven ________
- // ^ /| |\ ^
- // | / | | \ |
- // | / | | \ |
- // | / | | \ |
- // | / | | \ |
- //-------|----|-------|----|-------> driver
- // | min1 max1 max2 min2
-
- for( entry_list_t::iterator iter = mDriven.begin(); iter != mDriven.end(); iter++ )
- {
- LLDrivenEntry* driven = &(*iter);
- LLDrivenEntryInfo* info = driven->mInfo;
-
- F32 driven_weight = 0.f;
- F32 driven_min = driven->mParam->getMinWeight();
- F32 driven_max = driven->mParam->getMaxWeight();
-
- if (mIsAnimating)
- {
- // driven param doesn't interpolate (textures, for example)
- if (!driven->mParam->getAnimating())
- {
- continue;
- }
- if( mCurWeight < info->mMin1 )
- {
- if (info->mMin1 == min_weight)
- {
- if (info->mMin1 == info->mMax1)
- {
- driven_weight = driven_max;
- }
- else
- {
- //up slope extrapolation
- F32 t = (mCurWeight - info->mMin1) / (info->mMax1 - info->mMin1 );
- driven_weight = driven_min + t * (driven_max - driven_min);
- }
- }
- else
- {
- driven_weight = driven_min;
- }
-
- setDrivenWeight(driven,driven_weight,upload_bake);
- continue;
- }
- else
- if ( mCurWeight > info->mMin2 )
- {
- if (info->mMin2 == max_weight)
- {
- if (info->mMin2 == info->mMax2)
- {
- driven_weight = driven_max;
- }
- else
- {
- //down slope extrapolation
- F32 t = (mCurWeight - info->mMax2) / (info->mMin2 - info->mMax2 );
- driven_weight = driven_max + t * (driven_min - driven_max);
- }
- }
- else
- {
- driven_weight = driven_min;
- }
-
- setDrivenWeight(driven,driven_weight,upload_bake);
- continue;
- }
- }
-
- driven_weight = getDrivenWeight(driven, mCurWeight);
- setDrivenWeight(driven,driven_weight,upload_bake);
- }
-}
-
-F32 LLDriverParam::getTotalDistortion()
-{
- F32 sum = 0.f;
- for( entry_list_t::iterator iter = mDriven.begin(); iter != mDriven.end(); iter++ )
- {
- LLDrivenEntry* driven = &(*iter);
- sum += driven->mParam->getTotalDistortion();
- }
-
- return sum;
-}
-
-const LLVector3 &LLDriverParam::getAvgDistortion()
-{
- // It's not actually correct to take the average of averages, but it good enough here.
- LLVector3 sum;
- S32 count = 0;
- for( entry_list_t::iterator iter = mDriven.begin(); iter != mDriven.end(); iter++ )
- {
- LLDrivenEntry* driven = &(*iter);
- sum += driven->mParam->getAvgDistortion();
- count++;
- }
- sum /= (F32)count;
-
- mDefaultVec = sum;
- return mDefaultVec;
-}
-
-F32 LLDriverParam::getMaxDistortion()
-{
- F32 max = 0.f;
- for( entry_list_t::iterator iter = mDriven.begin(); iter != mDriven.end(); iter++ )
- {
- LLDrivenEntry* driven = &(*iter);
- F32 param_max = driven->mParam->getMaxDistortion();
- if( param_max > max )
- {
- max = param_max;
- }
- }
-
- return max;
-}
-
-
-LLVector3 LLDriverParam::getVertexDistortion(S32 index, LLPolyMesh *poly_mesh)
-{
- LLVector3 sum;
- for( entry_list_t::iterator iter = mDriven.begin(); iter != mDriven.end(); iter++ )
- {
- LLDrivenEntry* driven = &(*iter);
- sum += driven->mParam->getVertexDistortion( index, poly_mesh );
- }
- return sum;
-}
-
-const LLVector3* LLDriverParam::getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh)
-{
- mCurrentDistortionParam = NULL;
- const LLVector3* v = NULL;
- for( entry_list_t::iterator iter = mDriven.begin(); iter != mDriven.end(); iter++ )
- {
- LLDrivenEntry* driven = &(*iter);
- v = driven->mParam->getFirstDistortion( index, poly_mesh );
- if( v )
- {
- mCurrentDistortionParam = driven->mParam;
- break;
- }
- }
-
- return v;
-};
-
-const LLVector3* LLDriverParam::getNextDistortion(U32 *index, LLPolyMesh **poly_mesh)
-{
- llassert( mCurrentDistortionParam );
- if( !mCurrentDistortionParam )
- {
- return NULL;
- }
-
- LLDrivenEntry* driven = NULL;
- entry_list_t::iterator iter;
-
- // Set mDriven iteration to the right point
- for( iter = mDriven.begin(); iter != mDriven.end(); iter++ )
- {
- driven = &(*iter);
- if( driven->mParam == mCurrentDistortionParam )
- {
- break;
- }
- }
-
- llassert(driven);
- if (!driven)
- {
- return NULL; // shouldn't happen, but...
- }
-
- // We're already in the middle of a param's distortions, so get the next one.
- const LLVector3* v = driven->mParam->getNextDistortion( index, poly_mesh );
- if( (!v) && (iter != mDriven.end()) )
- {
- // This param is finished, so start the next param. It might not have any
- // distortions, though, so we have to loop to find the next param that does.
- for( iter++; iter != mDriven.end(); iter++ )
- {
- driven = &(*iter);
- v = driven->mParam->getFirstDistortion( index, poly_mesh );
- if( v )
- {
- mCurrentDistortionParam = driven->mParam;
- break;
- }
- }
- }
-
- return v;
-};
-
-//-----------------------------------------------------------------------------
-// setAnimationTarget()
-//-----------------------------------------------------------------------------
-void LLDriverParam::setAnimationTarget( F32 target_value, BOOL upload_bake )
-{
- LLVisualParam::setAnimationTarget(target_value, upload_bake);
-
- for( entry_list_t::iterator iter = mDriven.begin(); iter != mDriven.end(); iter++ )
- {
- LLDrivenEntry* driven = &(*iter);
- F32 driven_weight = getDrivenWeight(driven, mTargetWeight);
-
- // this isn't normally necessary, as driver params handle interpolation of their driven params
- // but texture params need to know to assume their final value at beginning of interpolation
- driven->mParam->setAnimationTarget(driven_weight, upload_bake);
- }
-}
-
-//-----------------------------------------------------------------------------
-// stopAnimating()
-//-----------------------------------------------------------------------------
-void LLDriverParam::stopAnimating(BOOL upload_bake)
-{
- LLVisualParam::stopAnimating(upload_bake);
-
- for( entry_list_t::iterator iter = mDriven.begin(); iter != mDriven.end(); iter++ )
- {
- LLDrivenEntry* driven = &(*iter);
- driven->mParam->setAnimating(FALSE);
- }
-}
-
-/*virtual*/
-BOOL LLDriverParam::linkDrivenParams(visual_param_mapper mapper, BOOL only_cross_params)
-{
- BOOL success = TRUE;
- LLDriverParamInfo::entry_info_list_t::iterator iter;
- for (iter = getInfo()->mDrivenInfoList.begin(); iter != getInfo()->mDrivenInfoList.end(); ++iter)
- {
- LLDrivenEntryInfo *driven_info = &(*iter);
- S32 driven_id = driven_info->mDrivenID;
-
- // check for already existing links. Do not overwrite.
- BOOL found = FALSE;
- for (entry_list_t::iterator driven_iter = mDriven.begin(); driven_iter != mDriven.end() && !found; ++driven_iter)
- {
- if (driven_iter->mInfo->mDrivenID == driven_id)
- {
- found = TRUE;
- }
- }
-
- if (!found)
- {
- LLViewerVisualParam* param = (LLViewerVisualParam*)mapper(driven_id);
- bool push = param && (!only_cross_params || param->getCrossWearable());
- if (push)
- {
- mDriven.push_back(LLDrivenEntry( param, driven_info ));
- }
- else
- {
- success = FALSE;
- }
- }
- }
-
- return success;
-}
-
-void LLDriverParam::resetDrivenParams()
-{
- mDriven.clear();
- mDriven.reserve(getInfo()->mDrivenInfoList.size());
-}
-
-void LLDriverParam::updateCrossDrivenParams(LLWearableType::EType driven_type)
-{
- bool needs_update = (getWearableType()==driven_type);
-
- // if the driver has a driven entry for the passed-in wearable type, we need to refresh the value
- for( entry_list_t::iterator iter = mDriven.begin(); iter != mDriven.end(); iter++ )
- {
- LLDrivenEntry* driven = &(*iter);
- if (driven && driven->mParam && driven->mParam->getCrossWearable() && driven->mParam->getWearableType() == driven_type)
- {
- needs_update = true;
- }
- }
-
-
- if (needs_update)
- {
- LLWearableType::EType driver_type = (LLWearableType::EType)getWearableType();
-
- // If we've gotten here, we've added a new wearable of type "type"
- // Thus this wearable needs to get updates from the driver wearable.
- // The call to setVisualParamWeight seems redundant, but is necessary
- // as the number of driven wearables has changed since the last update. -Nyx
- LLWearable *wearable = gAgentWearables.getTopWearable(driver_type);
- if (wearable)
- {
- wearable->setVisualParamWeight(mID, wearable->getVisualParamWeight(mID), false);
- }
- }
-}
-
-
-//-----------------------------------------------------------------------------
-// getDrivenWeight()
-//-----------------------------------------------------------------------------
-F32 LLDriverParam::getDrivenWeight(const LLDrivenEntry* driven, F32 input_weight)
-{
- F32 min_weight = getMinWeight();
- F32 max_weight = getMaxWeight();
- const LLDrivenEntryInfo* info = driven->mInfo;
-
- F32 driven_weight = 0.f;
- F32 driven_min = driven->mParam->getMinWeight();
- F32 driven_max = driven->mParam->getMaxWeight();
-
- if( input_weight <= info->mMin1 )
- {
- if( info->mMin1 == info->mMax1 &&
- info->mMin1 <= min_weight)
- {
- driven_weight = driven_max;
- }
- else
- {
- driven_weight = driven_min;
- }
- }
- else
- if( input_weight <= info->mMax1 )
- {
- F32 t = (input_weight - info->mMin1) / (info->mMax1 - info->mMin1 );
- driven_weight = driven_min + t * (driven_max - driven_min);
- }
- else
- if( input_weight <= info->mMax2 )
- {
- driven_weight = driven_max;
- }
- else
- if( input_weight <= info->mMin2 )
- {
- F32 t = (input_weight - info->mMax2) / (info->mMin2 - info->mMax2 );
- driven_weight = driven_max + t * (driven_min - driven_max);
- }
- else
- {
- if (info->mMax2 >= max_weight)
- {
- driven_weight = driven_max;
- }
- else
- {
- driven_weight = driven_min;
- }
- }
-
- return driven_weight;
-}
-
-void LLDriverParam::setDrivenWeight(LLDrivenEntry *driven, F32 driven_weight, bool upload_bake)
-{
- if(isAgentAvatarValid() &&
- mWearablep &&
- driven->mParam->getCrossWearable() &&
- mWearablep->isOnTop())
- {
- // call setWeight through LLVOAvatarSelf so other wearables can be updated with the correct values
- gAgentAvatarp->setVisualParamWeight( (LLVisualParam*)driven->mParam, driven_weight, upload_bake );
- }
- else
- {
- driven->mParam->setWeight( driven_weight, upload_bake );
- }
-}
diff --git a/indra/newview/lldriverparam.h b/indra/newview/lldriverparam.h
deleted file mode 100644
index fb1b44458c..0000000000
--- a/indra/newview/lldriverparam.h
+++ /dev/null
@@ -1,128 +0,0 @@
-/**
- * @file lldriverparam.h
- * @brief A visual parameter that drives (controls) other visual parameters.
- *
- * $LicenseInfo:firstyear=2002&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$
- */
-
-#ifndef LL_LLDRIVERPARAM_H
-#define LL_LLDRIVERPARAM_H
-
-#include "llviewervisualparam.h"
-#include "llwearabletype.h"
-
-class LLPhysicsMotion;
-class LLVOAvatar;
-class LLWearable;
-
-//-----------------------------------------------------------------------------
-
-struct LLDrivenEntryInfo
-{
- LLDrivenEntryInfo( S32 id, F32 min1, F32 max1, F32 max2, F32 min2 )
- : mDrivenID( id ), mMin1( min1 ), mMax1( max1 ), mMax2( max2 ), mMin2( min2 ) {}
- S32 mDrivenID;
- F32 mMin1;
- F32 mMax1;
- F32 mMax2;
- F32 mMin2;
-};
-
-struct LLDrivenEntry
-{
- LLDrivenEntry( LLViewerVisualParam* param, LLDrivenEntryInfo *info )
- : mParam( param ), mInfo( info ) {}
- LLViewerVisualParam* mParam;
- LLDrivenEntryInfo* mInfo;
-};
-
-//-----------------------------------------------------------------------------
-
-class LLDriverParamInfo : public LLViewerVisualParamInfo
-{
- friend class LLDriverParam;
-public:
- LLDriverParamInfo();
- /*virtual*/ ~LLDriverParamInfo() {};
-
- /*virtual*/ BOOL parseXml(LLXmlTreeNode* node);
-
- /*virtual*/ void toStream(std::ostream &out);
-
-protected:
- typedef std::deque<LLDrivenEntryInfo> entry_info_list_t;
- entry_info_list_t mDrivenInfoList;
-};
-
-//-----------------------------------------------------------------------------
-
-class LLDriverParam : public LLViewerVisualParam
-{
- friend class LLPhysicsMotion; // physics motion needs to access driven params directly.
-public:
- LLDriverParam(LLVOAvatar *avatarp);
- LLDriverParam(LLWearable *wearablep);
- ~LLDriverParam();
-
- // Special: These functions are overridden by child classes
- LLDriverParamInfo* getInfo() const { return (LLDriverParamInfo*)mInfo; }
- // This sets mInfo and calls initialization functions
- BOOL setInfo(LLDriverParamInfo *info);
-
- void setWearable(LLWearable *wearablep);
- void setAvatar(LLVOAvatar *avatarp);
- void updateCrossDrivenParams(LLWearableType::EType driven_type);
-
- /*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable) const;
-
- // LLVisualParam Virtual functions
- ///*virtual*/ BOOL parseData(LLXmlTreeNode* node);
- /*virtual*/ void apply( ESex sex ) {} // apply is called separately for each driven param.
- /*virtual*/ void setWeight(F32 weight, BOOL upload_bake);
- /*virtual*/ void setAnimationTarget( F32 target_value, BOOL upload_bake );
- /*virtual*/ void stopAnimating(BOOL upload_bake);
- /*virtual*/ BOOL linkDrivenParams(visual_param_mapper mapper, BOOL only_cross_params);
- /*virtual*/ void resetDrivenParams();
-
- // LLViewerVisualParam Virtual functions
- /*virtual*/ F32 getTotalDistortion();
- /*virtual*/ const LLVector3& getAvgDistortion();
- /*virtual*/ F32 getMaxDistortion();
- /*virtual*/ LLVector3 getVertexDistortion(S32 index, LLPolyMesh *poly_mesh);
- /*virtual*/ const LLVector3* getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh);
- /*virtual*/ const LLVector3* getNextDistortion(U32 *index, LLPolyMesh **poly_mesh);
-
-protected:
- F32 getDrivenWeight(const LLDrivenEntry* driven, F32 input_weight);
- void setDrivenWeight(LLDrivenEntry *driven, F32 driven_weight, bool upload_bake);
-
-
- LLVector3 mDefaultVec; // temp holder
- typedef std::vector<LLDrivenEntry> entry_list_t;
- entry_list_t mDriven;
- LLViewerVisualParam* mCurrentDistortionParam;
- // Backlink only; don't make this an LLPointer.
- LLVOAvatar* mAvatarp;
- LLWearable* mWearablep;
-};
-
-#endif // LL_LLDRIVERPARAM_H
diff --git a/indra/newview/lldynamictexture.cpp b/indra/newview/lldynamictexture.cpp
index a93b2b71de..29ad4f34d2 100644..100755
--- a/indra/newview/lldynamictexture.cpp
+++ b/indra/newview/lldynamictexture.cpp
@@ -107,7 +107,7 @@ void LLViewerDynamicTexture::generateGLTexture(LLGLint internal_format, LLGLenum
{
setExplicitFormat(internal_format, primary_format, type_format, swap_bytes);
}
- createGLTexture(0, raw_image, 0, TRUE, LLViewerTexture::DYNAMIC_TEX);
+ createGLTexture(0, raw_image, 0, TRUE, LLGLTexture::DYNAMIC_TEX);
setAddressMode((mClamp) ? LLTexUnit::TAM_CLAMP : LLTexUnit::TAM_WRAP);
mGLTexturep->setGLTextureCreated(false);
}
@@ -129,7 +129,7 @@ void LLViewerDynamicTexture::preRender(BOOL clear_depth)
llassert(mFullHeight <= 512);
llassert(mFullWidth <= 512);
- if (gGLManager.mHasFramebufferObject && gPipeline.mWaterDis.isComplete())
+ if (gGLManager.mHasFramebufferObject && gPipeline.mWaterDis.isComplete() && !gGLManager.mIsATI)
{ //using offscreen render target, just use the bottom left corner
mOrigin.set(0, 0);
}
@@ -216,7 +216,7 @@ BOOL LLViewerDynamicTexture::updateAllInstances()
return TRUE;
}
- bool use_fbo = gGLManager.mHasFramebufferObject && gPipeline.mWaterDis.isComplete();
+ bool use_fbo = gGLManager.mHasFramebufferObject && gPipeline.mWaterDis.isComplete() && !gGLManager.mIsATI;
if (use_fbo)
{
diff --git a/indra/newview/lldynamictexture.h b/indra/newview/lldynamictexture.h
index e18090545d..d287ae6eeb 100644..100755
--- a/indra/newview/lldynamictexture.h
+++ b/indra/newview/lldynamictexture.h
@@ -36,6 +36,16 @@
class LLViewerDynamicTexture : public LLViewerTexture
{
public:
+ void* operator new(size_t size)
+ {
+ return ll_aligned_malloc_16(size);
+ }
+
+ void operator delete(void* ptr)
+ {
+ ll_aligned_free_16(ptr);
+ }
+
enum
{
LL_VIEWER_DYNAMIC_TEXTURE = LLViewerTexture::DYNAMIC_TEXTURE,
@@ -62,8 +72,8 @@ public:
/*virtual*/ S8 getType() const ;
- S32 getOriginX() { return mOrigin.mX; }
- S32 getOriginY() { return mOrigin.mY; }
+ S32 getOriginX() const { return mOrigin.mX; }
+ S32 getOriginY() const { return mOrigin.mY; }
S32 getSize() { return mFullWidth * mFullHeight * mComponents; }
@@ -85,7 +95,7 @@ protected:
protected:
BOOL mClamp;
LLCoordGL mOrigin;
- LLCamera mCamera;
+ LL_ALIGN_16(LLCamera mCamera);
typedef std::set<LLViewerDynamicTexture*> instance_list_t;
static instance_list_t sInstances[ LLViewerDynamicTexture::ORDER_COUNT ];
diff --git a/indra/newview/llemote.cpp b/indra/newview/llemote.cpp
index 510ff69acf..510ff69acf 100644..100755
--- a/indra/newview/llemote.cpp
+++ b/indra/newview/llemote.cpp
diff --git a/indra/newview/llemote.h b/indra/newview/llemote.h
index 4c516998dc..4c516998dc 100644..100755
--- a/indra/newview/llemote.h
+++ b/indra/newview/llemote.h
diff --git a/indra/newview/llenvmanager.cpp b/indra/newview/llenvmanager.cpp
index 86fe6754dc..86fe6754dc 100644..100755
--- a/indra/newview/llenvmanager.cpp
+++ b/indra/newview/llenvmanager.cpp
diff --git a/indra/newview/llenvmanager.h b/indra/newview/llenvmanager.h
index ad56761bc7..ad56761bc7 100644..100755
--- a/indra/newview/llenvmanager.h
+++ b/indra/newview/llenvmanager.h
diff --git a/indra/newview/llestateinfomodel.cpp b/indra/newview/llestateinfomodel.cpp
index 7ed22d68f6..2669b0340f 100644..100755
--- a/indra/newview/llestateinfomodel.cpp
+++ b/indra/newview/llestateinfomodel.cpp
@@ -65,12 +65,12 @@ void LLEstateInfoModel::sendEstateInfo()
}
}
-bool LLEstateInfoModel::getUseFixedSun() const { return mFlags & REGION_FLAGS_SUN_FIXED; }
-bool LLEstateInfoModel::getIsExternallyVisible() const { return mFlags & REGION_FLAGS_EXTERNALLY_VISIBLE; }
-bool LLEstateInfoModel::getAllowDirectTeleport() const { return mFlags & REGION_FLAGS_ALLOW_DIRECT_TELEPORT; }
-bool LLEstateInfoModel::getDenyAnonymous() const { return mFlags & REGION_FLAGS_DENY_ANONYMOUS; }
-bool LLEstateInfoModel::getDenyAgeUnverified() const { return mFlags & REGION_FLAGS_DENY_AGEUNVERIFIED; }
-bool LLEstateInfoModel::getAllowVoiceChat() const { return mFlags & REGION_FLAGS_ALLOW_VOICE; }
+bool LLEstateInfoModel::getUseFixedSun() const { return getFlag(REGION_FLAGS_SUN_FIXED); }
+bool LLEstateInfoModel::getIsExternallyVisible() const { return getFlag(REGION_FLAGS_EXTERNALLY_VISIBLE); }
+bool LLEstateInfoModel::getAllowDirectTeleport() const { return getFlag(REGION_FLAGS_ALLOW_DIRECT_TELEPORT); }
+bool LLEstateInfoModel::getDenyAnonymous() const { return getFlag(REGION_FLAGS_DENY_ANONYMOUS); }
+bool LLEstateInfoModel::getDenyAgeUnverified() const { return getFlag(REGION_FLAGS_DENY_AGEUNVERIFIED); }
+bool LLEstateInfoModel::getAllowVoiceChat() const { return getFlag(REGION_FLAGS_ALLOW_VOICE); }
void LLEstateInfoModel::setUseFixedSun(bool val) { setFlag(REGION_FLAGS_SUN_FIXED, val); }
void LLEstateInfoModel::setIsExternallyVisible(bool val) { setFlag(REGION_FLAGS_EXTERNALLY_VISIBLE, val); }
@@ -122,9 +122,9 @@ public:
}
// if we get an error response
- virtual void error(U32 status, const std::string& reason)
+ virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content)
{
- llwarns << "Failed to commit estate info (" << status << "): " << reason << llendl;
+ llwarns << "Failed to commit estate info [status:" << status << "]: " << content << llendl;
}
};
@@ -199,18 +199,6 @@ void LLEstateInfoModel::commitEstateInfoDataserver()
gAgent.sendMessage();
}
-void LLEstateInfoModel::setFlag(U32 flag, bool val)
-{
- if (val)
- {
- mFlags |= flag;
- }
- else
- {
- mFlags &= ~flag;
- }
-}
-
std::string LLEstateInfoModel::getInfoDump()
{
LLSD dump;
diff --git a/indra/newview/llestateinfomodel.h b/indra/newview/llestateinfomodel.h
index 56391eda91..538f2f7c75 100644..100755
--- a/indra/newview/llestateinfomodel.h
+++ b/indra/newview/llestateinfomodel.h
@@ -85,19 +85,38 @@ protected:
private:
bool commitEstateInfoCaps();
void commitEstateInfoDataserver();
- U32 getFlags() const { return mFlags; }
- void setFlag(U32 flag, bool val);
+ inline bool getFlag(U64 flag) const;
+ inline void setFlag(U64 flag, bool val);
+ U64 getFlags() const { return mFlags; }
std::string getInfoDump();
// estate info
std::string mName; /// estate name
LLUUID mOwnerID; /// estate owner id
U32 mID; /// estate id
- U32 mFlags; /// estate flags
+ U64 mFlags; /// estate flags
F32 mSunHour; /// estate sun hour
update_signal_t mUpdateSignal; /// emitted when we receive update from sim
update_signal_t mCommitSignal; /// emitted when our update gets applied to sim
};
+inline bool LLEstateInfoModel::getFlag(U64 flag) const
+{
+ return ((mFlags & flag) != 0);
+}
+
+inline void LLEstateInfoModel::setFlag(U64 flag, bool val)
+{
+ if (val)
+ {
+ mFlags |= flag;
+ }
+ else
+ {
+ mFlags &= ~flag;
+ }
+}
+
+
#endif // LL_LLESTATEINFOMODEL_H
diff --git a/indra/newview/lleventnotifier.cpp b/indra/newview/lleventnotifier.cpp
index bedab75f98..bedab75f98 100644..100755
--- a/indra/newview/lleventnotifier.cpp
+++ b/indra/newview/lleventnotifier.cpp
diff --git a/indra/newview/lleventnotifier.h b/indra/newview/lleventnotifier.h
index 3fee46c2f6..3fee46c2f6 100644..100755
--- a/indra/newview/lleventnotifier.h
+++ b/indra/newview/lleventnotifier.h
diff --git a/indra/newview/lleventpoll.cpp b/indra/newview/lleventpoll.cpp
index 4f4d9a40b4..c1630318e8 100644..100755
--- a/indra/newview/lleventpoll.cpp
+++ b/indra/newview/lleventpoll.cpp
@@ -62,7 +62,7 @@ namespace
void handleMessage(const LLSD& content);
- virtual void error(U32 status, const std::string& reason);
+ virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content);
virtual void result(const LLSD& content);
virtual void completedRaw(U32 status,
@@ -86,7 +86,7 @@ namespace
class LLEventPollEventTimer : public LLEventTimer
{
- typedef boost::intrusive_ptr<LLEventPollResponder> EventPollResponderPtr;
+ typedef LLPointer<LLEventPollResponder> EventPollResponderPtr;
public:
LLEventPollEventTimer(F32 period, EventPollResponderPtr responder)
@@ -187,7 +187,7 @@ namespace
}
//virtual
- void LLEventPollResponder::error(U32 status, const std::string& reason)
+ void LLEventPollResponder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)
{
if (mDone) return;
@@ -207,12 +207,12 @@ namespace
+ mErrorCount * EVENT_POLL_ERROR_RETRY_SECONDS_INC
, this);
- llwarns << "Unexpected HTTP error. status: " << status << ", reason: " << reason << llendl;
+ llwarns << "LLEventPollResponder error [status:" << status << "]: " << content << llendl;
}
else
{
- llwarns << "LLEventPollResponder::error: <" << mCount << "> got "
- << status << ": " << reason
+ llwarns << "LLEventPollResponder error <" << mCount
+ << "> [status:" << status << "]: " << content
<< (mDone ? " -- done" : "") << llendl;
stop();
diff --git a/indra/newview/lleventpoll.h b/indra/newview/lleventpoll.h
index e8d98062aa..e8d98062aa 100644..100755
--- a/indra/newview/lleventpoll.h
+++ b/indra/newview/lleventpoll.h
diff --git a/indra/newview/llexpandabletextbox.cpp b/indra/newview/llexpandabletextbox.cpp
index 935dcb74b0..a50184460b 100644..100755
--- a/indra/newview/llexpandabletextbox.cpp
+++ b/indra/newview/llexpandabletextbox.cpp
@@ -150,7 +150,7 @@ void LLExpandableTextBox::LLTextBoxEx::showExpandText()
std::pair<S32, S32> visible_lines = getVisibleLines(true);
S32 last_line = visible_lines.second - 1;
- LLStyle::Params expander_style(getDefaultStyleParams());
+ LLStyle::Params expander_style(getStyleParams());
expander_style.font.style = "UNDERLINE";
expander_style.color = LLUIColorTable::instance().getColor("HTMLLinkColor");
LLExpanderSegment* expanderp = new LLExpanderSegment(new LLStyle(expander_style), getLineStart(last_line), getLength() + 1, mExpanderLabel, *this);
@@ -166,7 +166,7 @@ void LLExpandableTextBox::LLTextBoxEx::hideExpandText()
if (mExpanderVisible)
{
// this will overwrite the expander segment and all text styling with a single style
- LLStyleConstSP sp(new LLStyle(getDefaultStyleParams()));
+ LLStyleConstSP sp(new LLStyle(getStyleParams()));
LLNormalTextSegment* segmentp = new LLNormalTextSegment(sp, 0, getLength() + 1, *this);
insertSegment(segmentp);
diff --git a/indra/newview/llexpandabletextbox.h b/indra/newview/llexpandabletextbox.h
index 399e48bea2..399e48bea2 100644..100755
--- a/indra/newview/llexpandabletextbox.h
+++ b/indra/newview/llexpandabletextbox.h
diff --git a/indra/newview/llexternaleditor.cpp b/indra/newview/llexternaleditor.cpp
index ed1d7e860a..9480e54809 100644..100755
--- a/indra/newview/llexternaleditor.cpp
+++ b/indra/newview/llexternaleditor.cpp
@@ -29,6 +29,9 @@
#include "lltrans.h"
#include "llui.h"
+#include "llprocess.h"
+#include "llsdutil.h"
+#include <boost/foreach.hpp>
// static
const std::string LLExternalEditor::sFilenameMarker = "%s";
@@ -45,19 +48,8 @@ LLExternalEditor::EErrorCode LLExternalEditor::setCommand(const std::string& env
return EC_NOT_SPECIFIED;
}
- // Add the filename marker if missing.
- if (cmd.find(sFilenameMarker) == std::string::npos)
- {
- cmd += " \"" + sFilenameMarker + "\"";
- llinfos << "Adding the filename marker (" << sFilenameMarker << ")" << llendl;
- }
-
string_vec_t tokens;
- if (tokenize(tokens, cmd) < 2) // 2 = bin + at least one arg (%s)
- {
- llwarns << "Error parsing editor command" << llendl;
- return EC_PARSE_ERROR;
- }
+ tokenize(tokens, cmd);
// Check executable for existence.
std::string bin_path = tokens[0];
@@ -68,51 +60,48 @@ LLExternalEditor::EErrorCode LLExternalEditor::setCommand(const std::string& env
}
// Save command.
- mProcess.setExecutable(bin_path);
- mArgs.clear();
+ mProcessParams = LLProcess::Params();
+ mProcessParams.executable = bin_path;
for (size_t i = 1; i < tokens.size(); ++i)
{
- if (i > 1) mArgs += " ";
- mArgs += "\"" + tokens[i] + "\"";
+ mProcessParams.args.add(tokens[i]);
}
- llinfos << "Setting command [" << bin_path << " " << mArgs << "]" << llendl;
+
+ // Add the filename marker if missing.
+ if (cmd.find(sFilenameMarker) == std::string::npos)
+ {
+ mProcessParams.args.add(sFilenameMarker);
+ llinfos << "Adding the filename marker (" << sFilenameMarker << ")" << llendl;
+ }
+
+ llinfos << "Setting command [" << mProcessParams << "]" << llendl;
return EC_SUCCESS;
}
LLExternalEditor::EErrorCode LLExternalEditor::run(const std::string& file_path)
{
- std::string args = mArgs;
- if (mProcess.getExecutable().empty() || args.empty())
+ if (std::string(mProcessParams.executable).empty() || mProcessParams.args.empty())
{
llwarns << "Editor command not set" << llendl;
return EC_NOT_SPECIFIED;
}
- // Substitute the filename marker in the command with the actual passed file name.
- LLStringUtil::replaceString(args, sFilenameMarker, file_path);
-
- // Split command into separate tokens.
- string_vec_t tokens;
- tokenize(tokens, args);
+ // Copy params block so we can replace sFilenameMarker
+ LLProcess::Params params;
+ params.executable = mProcessParams.executable;
- // Set process arguments taken from the command.
- mProcess.clearArguments();
- for (string_vec_t::const_iterator arg_it = tokens.begin(); arg_it != tokens.end(); ++arg_it)
- {
- mProcess.addArgument(*arg_it);
- }
-
- // Run the editor.
- llinfos << "Running editor command [" << mProcess.getExecutable() + " " + args << "]" << llendl;
- int result = mProcess.launch();
- if (result == 0)
+ // Substitute the filename marker in the command with the actual passed file name.
+ BOOST_FOREACH(const std::string& arg, mProcessParams.args)
{
- // Prevent killing the process in destructor (will add it to the zombies list).
- mProcess.orphan();
+ std::string fixed(arg);
+ LLStringUtil::replaceString(fixed, sFilenameMarker, file_path);
+ params.args.add(fixed);
}
- return result == 0 ? EC_SUCCESS : EC_FAILED_TO_RUN;
+ // Run the editor. Prevent killing the process in destructor.
+ params.autokill = false;
+ return LLProcess::create(params) ? EC_SUCCESS : EC_FAILED_TO_RUN;
}
// static
@@ -130,6 +119,12 @@ std::string LLExternalEditor::getErrorMessage(EErrorCode code)
return LLTrans::getString("Unknown");
}
+// TODO:
+// - Unit-test this with tests like LLStringUtil::getTokens() (the
+// command-line overload that supports quoted tokens)
+// - Unless there are significant semantic differences, eliminate this method
+// and use LLStringUtil::getTokens() instead.
+
// static
size_t LLExternalEditor::tokenize(string_vec_t& tokens, const std::string& str)
{
diff --git a/indra/newview/llexternaleditor.h b/indra/newview/llexternaleditor.h
index ef5db56c6e..fd2c25020c 100644..100755
--- a/indra/newview/llexternaleditor.h
+++ b/indra/newview/llexternaleditor.h
@@ -27,7 +27,7 @@
#ifndef LL_LLEXTERNALEDITOR_H
#define LL_LLEXTERNALEDITOR_H
-#include <llprocesslauncher.h>
+#include "llprocess.h"
/**
* Usage:
@@ -97,9 +97,7 @@ private:
*/
static const std::string sSetting;
-
- std::string mArgs;
- LLProcessLauncher mProcess;
+ LLProcess::Params mProcessParams;
};
#endif // LL_LLEXTERNALEDITOR_H
diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp
index 4108d69e82..ae62be0ad0 100644..100755
--- a/indra/newview/llface.cpp
+++ b/indra/newview/llface.cpp
@@ -44,19 +44,32 @@
#include "llsky.h"
#include "llviewercamera.h"
#include "llviewertexturelist.h"
+#include "llvopartgroup.h"
#include "llvosky.h"
#include "llvovolume.h"
#include "pipeline.h"
#include "llviewerregion.h"
#include "llviewerwindow.h"
+#include "llviewershadermgr.h"
+#include "llviewertexture.h"
+#include "llvoavatar.h"
+#if LL_LINUX
+// Work-around spurious used before init warning on Vector4a
+//
+#pragma GCC diagnostic ignored "-Wuninitialized"
+#endif
+
+extern BOOL gGLDebugLoggingEnabled;
#define LL_MAX_INDICES_COUNT 1000000
+static LLStaticHashedString sTextureIndexIn("texture_index_in");
+static LLStaticHashedString sColorIn("color_in");
+
BOOL LLFace::sSafeRenderSelect = TRUE; // FALSE
#define DOTVEC(a,b) (a.mV[0]*b.mV[0] + a.mV[1]*b.mV[1] + a.mV[2]*b.mV[2])
-
/*
For each vertex, given:
B - binormal
@@ -104,41 +117,6 @@ void planarProjection(LLVector2 &tc, const LLVector4a& normal,
tc.mV[0] = 1.0f+((binormal.dot3(vec).getF32())*2 - 0.5f);
}
-void sphericalProjection(LLVector2 &tc, const LLVector4a& normal,
- const LLVector4a &mCenter, const LLVector4a& vec)
-{ //BROKEN
- /*tc.mV[0] = acosf(vd.mNormal * LLVector3(1,0,0))/3.14159f;
-
- tc.mV[1] = acosf(vd.mNormal * LLVector3(0,0,1))/6.284f;
- if (vd.mNormal.mV[1] > 0)
- {
- tc.mV[1] = 1.0f-tc.mV[1];
- }*/
-}
-
-void cylindricalProjection(LLVector2 &tc, const LLVector4a& normal, const LLVector4a &mCenter, const LLVector4a& vec)
-{ //BROKEN
- /*LLVector3 binormal;
- float d = vd.mNormal * LLVector3(1,0,0);
- if (d >= 0.5f || d <= -0.5f)
- {
- binormal = LLVector3(0,1,0);
- }
- else{
- binormal = LLVector3(1,0,0);
- }
- LLVector3 tangent = binormal % vd.mNormal;
-
- tc.mV[1] = -((tangent*vec)*2 - 0.5f);
-
- tc.mV[0] = acosf(vd.mNormal * LLVector3(1,0,0))/6.284f;
-
- if (vd.mNormal.mV[1] < 0)
- {
- tc.mV[0] = 1.0f-tc.mV[0];
- }*/
-}
-
////////////////////
//
// LLFace implementation
@@ -161,9 +139,16 @@ void LLFace::init(LLDrawable* drawablep, LLViewerObject* objp)
mGeomCount = 0;
mGeomIndex = 0;
mIndicesCount = 0;
- mIndicesIndex = 0;
- mIndexInTex = 0;
- mTexture = NULL;
+
+ //special value to indicate uninitialized position
+ mIndicesIndex = 0xFFFFFFFF;
+
+ for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i)
+ {
+ mIndexInTex[i] = 0;
+ mTexture[i] = NULL;
+ }
+
mTEOffset = -1;
mTextureIndex = 255;
@@ -177,17 +162,9 @@ void LLFace::init(LLDrawable* drawablep, LLViewerObject* objp)
mFaceColor = LLColor4(1,0,0,1);
- mLastVertexBuffer = mVertexBuffer;
- mLastGeomCount = mGeomCount;
- mLastGeomIndex = mGeomIndex;
- mLastIndicesCount = mIndicesCount;
- mLastIndicesIndex = mIndicesIndex;
-
mImportanceToCamera = 0.f ;
mBoundingSphereRadius = 0.0f ;
- mAtlasInfop = NULL ;
- mUsingAtlas = FALSE ;
mHasMedia = FALSE ;
}
@@ -198,11 +175,20 @@ void LLFace::destroy()
gPipeline.checkReferences(this);
}
- if(mTexture.notNull())
+ for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i)
{
- mTexture->removeFace(this) ;
+ if(mTexture[i].notNull())
+ {
+ mTexture[i]->removeFace(i, this) ;
+ }
}
+ if (isState(LLFace::PARTICLE))
+ {
+ LLVOPartGroup::freeVBSlot(getGeomIndex()/4);
+ clearState(LLFace::PARTICLE);
+ }
+
if (mDrawPoolp)
{
if (this->isState(LLFace::RIGGED) && mDrawPoolp->getType() == LLDrawPool::POOL_AVATAR)
@@ -234,8 +220,7 @@ void LLFace::destroy()
}
setDrawInfo(NULL);
- removeAtlas();
-
+
mDrawablep = NULL;
mVObjp = NULL;
}
@@ -258,8 +243,6 @@ void LLFace::setPool(LLFacePool* pool)
void LLFace::setPool(LLFacePool* new_pool, LLViewerTexture *texturep)
{
- LLMemType mt1(LLMemType::MTYPE_DRAWABLE);
-
if (!new_pool)
{
llerrs << "Setting pool to null!" << llendl;
@@ -290,35 +273,82 @@ void LLFace::setPool(LLFacePool* new_pool, LLViewerTexture *texturep)
setTexture(texturep) ;
}
-void LLFace::setTexture(LLViewerTexture* tex)
+void LLFace::setTexture(U32 ch, LLViewerTexture* tex)
{
- if(mTexture == tex)
+ llassert(ch < LLRender::NUM_TEXTURE_CHANNELS);
+
+ if(mTexture[ch] == tex)
{
return ;
}
- if(mTexture.notNull())
+ if(mTexture[ch].notNull())
{
- mTexture->removeFace(this) ;
- removeAtlas() ;
+ mTexture[ch]->removeFace(ch, this) ;
}
if(tex)
{
- tex->addFace(this) ;
+ tex->addFace(ch, this) ;
}
- mTexture = tex ;
+ mTexture[ch] = tex ;
+}
+
+void LLFace::setTexture(LLViewerTexture* tex)
+{
+ setDiffuseMap(tex);
+}
+
+void LLFace::setDiffuseMap(LLViewerTexture* tex)
+{
+ setTexture(LLRender::DIFFUSE_MAP, tex);
+}
+
+void LLFace::setNormalMap(LLViewerTexture* tex)
+{
+ setTexture(LLRender::NORMAL_MAP, tex);
+}
+
+void LLFace::setSpecularMap(LLViewerTexture* tex)
+{
+ setTexture(LLRender::SPECULAR_MAP, tex);
}
void LLFace::dirtyTexture()
{
- gPipeline.markTextured(getDrawable());
+ LLDrawable* drawablep = getDrawable();
+
+ if (mVObjp.notNull() && mVObjp->getVolume())
+ {
+ for (U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch)
+ {
+ if (mTexture[ch].notNull() && mTexture[ch]->getComponents() == 4)
+ { //dirty texture on an alpha object should be treated as an LoD update
+ LLVOVolume* vobj = drawablep->getVOVolume();
+ if (vobj)
+ {
+ vobj->mLODChanged = TRUE;
+
+ LLVOAvatar* avatar = vobj->getAvatar();
+ if (avatar)
+ { //avatar render cost may have changed
+ avatar->updateVisualComplexity();
+ }
+ }
+ gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_VOLUME, FALSE);
+ }
+ }
+ }
+
+ gPipeline.markTextured(drawablep);
}
-void LLFace::switchTexture(LLViewerTexture* new_texture)
+void LLFace::switchTexture(U32 ch, LLViewerTexture* new_texture)
{
- if(mTexture == new_texture)
+ llassert(ch < LLRender::NUM_TEXTURE_CHANNELS);
+
+ if(mTexture[ch] == new_texture)
{
return ;
}
@@ -328,10 +358,17 @@ void LLFace::switchTexture(LLViewerTexture* new_texture)
llerrs << "Can not switch to a null texture." << llendl;
return;
}
- new_texture->addTextureStats(mTexture->getMaxVirtualSize()) ;
- getViewerObject()->changeTEImage(mTEOffset, new_texture) ;
- setTexture(new_texture) ;
+ llassert(mTexture[ch].notNull());
+
+ new_texture->addTextureStats(mTexture[ch]->getMaxVirtualSize()) ;
+
+ if (ch == LLRender::DIFFUSE_MAP)
+ {
+ getViewerObject()->changeTEImage(mTEOffset, new_texture) ;
+ }
+
+ setTexture(ch, new_texture) ;
dirtyTexture();
}
@@ -372,7 +409,6 @@ void LLFace::setSize(S32 num_vertices, S32 num_indices, bool align)
mGeomCount = num_vertices;
mIndicesCount = num_indices;
mVertexBuffer = NULL;
- mLastVertexBuffer = NULL;
}
llassert(verify());
@@ -425,8 +461,6 @@ U16 LLFace::getGeometryAvatar(
LLStrider<F32> &vertex_weights,
LLStrider<LLVector4> &clothing_weights)
{
- LLMemType mt1(LLMemType::MTYPE_DRAWABLE);
-
if (mVertexBuffer.notNull())
{
mVertexBuffer->getVertexStrider (vertices, mGeomIndex, mGeomCount);
@@ -442,8 +476,6 @@ U16 LLFace::getGeometryAvatar(
U16 LLFace::getGeometry(LLStrider<LLVector3> &vertices, LLStrider<LLVector3> &normals,
LLStrider<LLVector2> &tex_coords, LLStrider<U16> &indicesp)
{
- LLMemType mt1(LLMemType::MTYPE_DRAWABLE);
-
if (mVertexBuffer.notNull())
{
mVertexBuffer->getVertexStrider(vertices, mGeomIndex, mGeomCount);
@@ -532,7 +564,9 @@ void LLFace::renderSelected(LLViewerTexture *imagep, const LLColor4& color)
}
else
{
- mVertexBuffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0);
+ // cheaters sometimes prosper...
+ //
+ mVertexBuffer->setBuffer(mVertexBuffer->getTypeMask());
mVertexBuffer->draw(LLRender::TRIANGLES, mIndicesCount, mIndicesIndex);
}
@@ -544,8 +578,8 @@ void LLFace::renderSelected(LLViewerTexture *imagep, const LLColor4& color)
/* removed in lieu of raycast uv detection
void LLFace::renderSelectedUV()
{
- LLViewerTexture* red_blue_imagep = LLViewerTextureManager::getFetchedTextureFromFile("uv_test1.j2c", TRUE, LLViewerTexture::BOOST_UI);
- LLViewerTexture* green_imagep = LLViewerTextureManager::getFetchedTextureFromFile("uv_test2.tga", TRUE, LLViewerTexture::BOOST_UI);
+ LLViewerTexture* red_blue_imagep = LLViewerTextureManager::getFetchedTextureFromFile("uv_test1.j2c", TRUE, LLGLTexture::BOOST_UI);
+ LLViewerTexture* green_imagep = LLViewerTextureManager::getFetchedTextureFromFile("uv_test2.tga", TRUE, LLGLTexture::BOOST_UI);
LLGLSUVSelect object_select;
@@ -751,10 +785,8 @@ bool less_than_max_mag(const LLVector4a& vec)
}
BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f,
- const LLMatrix4& mat_vert_in, const LLMatrix3& mat_normal_in, BOOL global_volume)
+ const LLMatrix4& mat_vert_in, BOOL global_volume)
{
- LLMemType mt1(LLMemType::MTYPE_DRAWABLE);
-
//get bounding box
if (mDrawablep->isState(LLDrawable::REBUILD_VOLUME | LLDrawable::REBUILD_POSITION | LLDrawable::REBUILD_RIGGED))
{
@@ -762,16 +794,6 @@ BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f,
LLMatrix4a mat_vert;
mat_vert.loadu(mat_vert_in);
- LLMatrix4a mat_normal;
- mat_normal.loadu(mat_normal_in);
-
- //if (mDrawablep->isState(LLDrawable::REBUILD_VOLUME))
- //{ //vertex buffer no longer valid
- // mVertexBuffer = NULL;
- // mLastVertexBuffer = NULL;
- //}
-
- //VECTORIZE THIS
LLVector4a min,max;
if (f >= volume.getNumVolumeFaces())
@@ -788,94 +810,68 @@ BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f,
llassert(less_than_max_mag(max));
//min, max are in volume space, convert to drawable render space
- LLVector4a center;
- LLVector4a t;
- t.setAdd(min, max);
- t.mul(0.5f);
- mat_vert.affineTransform(t, center);
- LLVector4a size;
- size.setSub(max, min);
- size.mul(0.5f);
- llassert(less_than_max_mag(min));
- llassert(less_than_max_mag(max));
+ //get 8 corners of bounding box
+ LLVector4Logical mask[6];
- if (!global_volume)
+ for (U32 i = 0; i < 6; ++i)
{
- //VECTORIZE THIS
- LLVector4a scale;
- scale.load3(mDrawablep->getVObj()->getScale().mV);
- size.mul(scale);
+ mask[i].clear();
}
- mat_normal.mMatrix[0].normalize3fast();
- mat_normal.mMatrix[1].normalize3fast();
- mat_normal.mMatrix[2].normalize3fast();
+ mask[0].setElement<2>(); //001
+ mask[1].setElement<1>(); //010
+ mask[2].setElement<1>(); //011
+ mask[2].setElement<2>();
+ mask[3].setElement<0>(); //100
+ mask[4].setElement<0>(); //101
+ mask[4].setElement<2>();
+ mask[5].setElement<0>(); //110
+ mask[5].setElement<1>();
- LLVector4a v[4];
+ LLVector4a v[8];
- //get 4 corners of bounding box
- mat_normal.rotate(size,v[0]);
+ v[6] = min;
+ v[7] = max;
- //VECTORIZE THIS
- LLVector4a scale;
-
- scale.set(-1.f, -1.f, 1.f);
- scale.mul(size);
- mat_normal.rotate(scale, v[1]);
-
- scale.set(1.f, -1.f, -1.f);
- scale.mul(size);
- mat_normal.rotate(scale, v[2]);
-
- scale.set(-1.f, 1.f, -1.f);
- scale.mul(size);
- mat_normal.rotate(scale, v[3]);
+ for (U32 i = 0; i < 6; ++i)
+ {
+ v[i].setSelectWithMask(mask[i], min, max);
+ }
+ LLVector4a tv[8];
+
+ //transform bounding box into drawable space
+ for (U32 i = 0; i < 8; ++i)
+ {
+ mat_vert.affineTransform(v[i], tv[i]);
+ }
+
+ //find bounding box
LLVector4a& newMin = mExtents[0];
LLVector4a& newMax = mExtents[1];
-
- newMin = newMax = center;
-
- llassert(less_than_max_mag(center));
-
- for (U32 i = 0; i < 4; i++)
- {
- LLVector4a delta;
- delta.setAbs(v[i]);
- LLVector4a min;
- min.setSub(center, delta);
- LLVector4a max;
- max.setAdd(center, delta);
- newMin.setMin(newMin,min);
- newMax.setMax(newMax,max);
+ newMin = newMax = tv[0];
- llassert(less_than_max_mag(newMin));
- llassert(less_than_max_mag(newMax));
+ for (U32 i = 1; i < 8; ++i)
+ {
+ newMin.setMin(newMin, tv[i]);
+ newMax.setMax(newMax, tv[i]);
}
if (!mDrawablep->isActive())
- {
+ { // Shift position for region
LLVector4a offset;
offset.load3(mDrawablep->getRegion()->getOriginAgent().mV);
newMin.add(offset);
newMax.add(offset);
-
- llassert(less_than_max_mag(newMin));
- llassert(less_than_max_mag(newMax));
}
- t.setAdd(newMin, newMax);
+ LLVector4a t;
+ t.setAdd(newMin,newMax);
t.mul(0.5f);
- llassert(less_than_max_mag(t));
-
- //VECTORIZE THIS
mCenterLocal.set(t.getF32ptr());
-
- llassert(less_than_max_mag(newMin));
- llassert(less_than_max_mag(newMax));
t.setSub(newMax,newMin);
mBoundingSphereRadius = t.getLength3().getF32()*0.5f;
@@ -893,7 +889,7 @@ BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f,
// integrated with getGeometryVolume() for its texture coordinate
// generation - but i'll leave that to someone more familiar
// with the implications.
-LLVector2 LLFace::surfaceToTexture(LLVector2 surface_coord, LLVector3 position, LLVector3 normal)
+LLVector2 LLFace::surfaceToTexture(LLVector2 surface_coord, const LLVector4a& position, const LLVector4a& normal)
{
LLVector2 tc = surface_coord;
@@ -913,7 +909,9 @@ LLVector2 LLFace::surfaceToTexture(LLVector2 surface_coord, LLVector3 position,
LLVector4a& center = *(mDrawablep->getVOVolume()->getVolume()->getVolumeFace(mTEOffset).mCenter);
LLVector4a volume_position;
- volume_position.load3(mDrawablep->getVOVolume()->agentPositionToVolume(position).mV);
+ LLVector3 v_position(position.getF32ptr());
+
+ volume_position.load3(mDrawablep->getVOVolume()->agentPositionToVolume(v_position).mV);
if (!mDrawablep->getVOVolume()->isVolumeGlobal())
{
@@ -923,23 +921,14 @@ LLVector2 LLFace::surfaceToTexture(LLVector2 surface_coord, LLVector3 position,
}
LLVector4a volume_normal;
- volume_normal.load3(mDrawablep->getVOVolume()->agentDirectionToVolume(normal).mV);
+ LLVector3 v_normal(normal.getF32ptr());
+ volume_normal.load3(mDrawablep->getVOVolume()->agentDirectionToVolume(v_normal).mV);
volume_normal.normalize3fast();
- switch (texgen)
+ if (texgen == LLTextureEntry::TEX_GEN_PLANAR)
{
- case LLTextureEntry::TEX_GEN_PLANAR:
planarProjection(tc, volume_normal, center, volume_position);
- break;
- case LLTextureEntry::TEX_GEN_SPHERICAL:
- sphericalProjection(tc, volume_normal, center, volume_position);
- break;
- case LLTextureEntry::TEX_GEN_CYLINDRICAL:
- cylindricalProjection(tc, volume_normal, center, volume_position);
- break;
- default:
- break;
- }
+ }
}
if (mTextureMatrix) // if we have a texture matrix, use it
@@ -966,7 +955,12 @@ void LLFace::getPlanarProjectedParams(LLQuaternion* face_rot, LLVector3* face_po
const LLMatrix4& vol_mat = getWorldMatrix();
const LLVolumeFace& vf = getViewerObject()->getVolume()->getVolumeFace(mTEOffset);
const LLVector4a& normal4a = vf.mNormals[0];
- const LLVector4a& binormal4a = vf.mBinormals[0];
+ const LLVector4a& tangent = vf.mTangents[0];
+
+ LLVector4a binormal4a;
+ binormal4a.setCross3(normal4a, tangent);
+ binormal4a.mul(tangent.getF32ptr()[3]);
+
LLVector2 projected_binormal;
planarProjection(projected_binormal, normal4a, *vf.mCenter, binormal4a);
projected_binormal -= LLVector2(0.5f, 0.5f); // this normally happens in xform()
@@ -1032,30 +1026,13 @@ bool LLFace::calcAlignedPlanarTE(const LLFace* align_to, LLVector2* res_st_offs
void LLFace::updateRebuildFlags()
{
- if (!mDrawablep->isState(LLDrawable::REBUILD_VOLUME))
- {
- BOOL moved = TRUE;
- if (mLastVertexBuffer == mVertexBuffer &&
- !mVertexBuffer->isEmpty())
- { //this face really doesn't need to be regenerated, try real hard not to do so
- if (mLastGeomCount == mGeomCount &&
- mLastGeomIndex == mGeomIndex &&
- mLastIndicesCount == mIndicesCount &&
- mLastIndicesIndex == mIndicesIndex)
- { //data is in same location in vertex buffer
- moved = FALSE;
- }
- }
- mLastMoveTime = gFrameTimeSeconds;
-
- if (moved)
- {
- mDrawablep->setState(LLDrawable::REBUILD_VOLUME);
- }
+ if (mDrawablep->isState(LLDrawable::REBUILD_VOLUME))
+ { //this rebuild is zero overhead (direct consequence of some change that affects this face)
+ mLastUpdateTime = gFrameTimeSeconds;
}
else
- {
- mLastUpdateTime = gFrameTimeSeconds;
+ { //this rebuild is overhead (side effect of some change that does not affect this face)
+ mLastMoveTime = gFrameTimeSeconds;
}
}
@@ -1068,7 +1045,17 @@ bool LLFace::canRenderAsMask()
}
const LLTextureEntry* te = getTextureEntry();
-
+ if( !te || !getViewerObject() || !getTexture() )
+ {
+ return false;
+ }
+
+ LLMaterial* mat = te->getMaterialParams();
+ if (mat && mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND)
+ {
+ return false;
+ }
+
if ((te->getColor().mV[3] == 1.0f) && // can't treat as mask if we have face alpha
(te->getGlow() == 0.f) && // glowing masks are hard to implement - don't mask
getTexture()->getIsAlphaMask()) // texture actually qualifies for masking (lazily recalculated but expensive)
@@ -1094,6 +1081,73 @@ bool LLFace::canRenderAsMask()
}
+static LLFastTimer::DeclareTimer FTM_FACE_GEOM_VOLUME("Volume VB Cache");
+
+//static
+void LLFace::cacheFaceInVRAM(const LLVolumeFace& vf)
+{
+ LLFastTimer t(FTM_FACE_GEOM_VOLUME);
+ U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 |
+ LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_NORMAL;
+
+ if (vf.mWeights)
+ {
+ mask |= LLVertexBuffer::MAP_WEIGHT4;
+ }
+
+ LLVertexBuffer* buff = new LLVertexBuffer(mask, GL_STATIC_DRAW_ARB);
+ vf.mVertexBuffer = buff;
+
+ buff->allocateBuffer(vf.mNumVertices, 0, true);
+
+ LLStrider<LLVector4a> f_vert;
+ LLStrider<LLVector4a> f_tangent;
+ LLStrider<LLVector3> f_norm;
+ LLStrider<LLVector2> f_tc;
+
+ buff->getTangentStrider(f_tangent);
+ buff->getVertexStrider(f_vert);
+ buff->getNormalStrider(f_norm);
+ buff->getTexCoord0Strider(f_tc);
+
+ for (U32 i = 0; i < vf.mNumVertices; ++i)
+ {
+ *f_vert++ = vf.mPositions[i];
+ *f_tangent++ = vf.mTangents[i];
+ *f_tc++ = vf.mTexCoords[i];
+ (*f_norm++).set(vf.mNormals[i].getF32ptr());
+ }
+
+ if (vf.mWeights)
+ {
+ LLStrider<LLVector4> f_wght;
+ buff->getWeight4Strider(f_wght);
+ for (U32 i = 0; i < vf.mNumVertices; ++i)
+ {
+ (*f_wght++).set(vf.mWeights[i].getF32ptr());
+ }
+ }
+
+ buff->flush();
+}
+
+//helper function for pushing primitives for transform shaders and cleaning up
+//uninitialized data on the tail, plus tracking number of expected primitives
+void push_for_transform(LLVertexBuffer* buff, U32 source_count, U32 dest_count)
+{
+ if (source_count > 0 && dest_count >= source_count) //protect against possible U32 wrapping
+ {
+ //push source primitives
+ buff->drawArrays(LLRender::POINTS, 0, source_count);
+ U32 tail = dest_count-source_count;
+ for (U32 i = 0; i < tail; ++i)
+ { //copy last source primitive into each element in tail
+ buff->drawArrays(LLRender::POINTS, source_count-1, 1);
+ }
+ gPipeline.mTransformFeedbackPrimitives += dest_count;
+ }
+}
+
static LLFastTimer::DeclareTimer FTM_FACE_GET_GEOM("Face Geom");
static LLFastTimer::DeclareTimer FTM_FACE_GEOM_POSITION("Position");
static LLFastTimer::DeclareTimer FTM_FACE_GEOM_NORMAL("Normal");
@@ -1101,7 +1155,16 @@ static LLFastTimer::DeclareTimer FTM_FACE_GEOM_TEXTURE("Texture");
static LLFastTimer::DeclareTimer FTM_FACE_GEOM_COLOR("Color");
static LLFastTimer::DeclareTimer FTM_FACE_GEOM_EMISSIVE("Emissive");
static LLFastTimer::DeclareTimer FTM_FACE_GEOM_WEIGHTS("Weights");
-static LLFastTimer::DeclareTimer FTM_FACE_GEOM_BINORMAL("Binormal");
+static LLFastTimer::DeclareTimer FTM_FACE_GEOM_TANGENT("Binormal");
+
+static LLFastTimer::DeclareTimer FTM_FACE_GEOM_FEEDBACK("Face Feedback");
+static LLFastTimer::DeclareTimer FTM_FACE_GEOM_FEEDBACK_POSITION("Feedback Position");
+static LLFastTimer::DeclareTimer FTM_FACE_GEOM_FEEDBACK_NORMAL("Feedback Normal");
+static LLFastTimer::DeclareTimer FTM_FACE_GEOM_FEEDBACK_TEXTURE("Feedback Texture");
+static LLFastTimer::DeclareTimer FTM_FACE_GEOM_FEEDBACK_COLOR("Feedback Color");
+static LLFastTimer::DeclareTimer FTM_FACE_GEOM_FEEDBACK_EMISSIVE("Feedback Emissive");
+static LLFastTimer::DeclareTimer FTM_FACE_GEOM_FEEDBACK_BINORMAL("Feedback Binormal");
+
static LLFastTimer::DeclareTimer FTM_FACE_GEOM_INDEX("Index");
static LLFastTimer::DeclareTimer FTM_FACE_GEOM_INDEX_TAIL("Tail");
static LLFastTimer::DeclareTimer FTM_FACE_POSITION_STORE("Pos");
@@ -1111,7 +1174,6 @@ static LLFastTimer::DeclareTimer FTM_FACE_TEX_DEFAULT("Default");
static LLFastTimer::DeclareTimer FTM_FACE_TEX_QUICK("Quick");
static LLFastTimer::DeclareTimer FTM_FACE_TEX_QUICK_NO_XFORM("No Xform");
static LLFastTimer::DeclareTimer FTM_FACE_TEX_QUICK_XFORM("Xform");
-
static LLFastTimer::DeclareTimer FTM_FACE_TEX_QUICK_PLANAR("Quick Planar");
BOOL LLFace::getGeometryVolume(const LLVolume& volume,
@@ -1139,31 +1201,36 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
{
if (num_indices + (S32) mIndicesIndex > mVertexBuffer->getNumIndices())
{
- llwarns << "Index buffer overflow!" << llendl;
- llwarns << "Indices Count: " << mIndicesCount
- << " VF Num Indices: " << num_indices
- << " Indices Index: " << mIndicesIndex
- << " VB Num Indices: " << mVertexBuffer->getNumIndices() << llendl;
- llwarns << "Last Indices Count: " << mLastIndicesCount
- << " Last Indices Index: " << mLastIndicesIndex
- << " Face Index: " << f
- << " Pool Type: " << mPoolType << llendl;
+ if (gDebugGL)
+ {
+ llwarns << "Index buffer overflow!" << llendl;
+ llwarns << "Indices Count: " << mIndicesCount
+ << " VF Num Indices: " << num_indices
+ << " Indices Index: " << mIndicesIndex
+ << " VB Num Indices: " << mVertexBuffer->getNumIndices() << llendl;
+ llwarns << " Face Index: " << f
+ << " Pool Type: " << mPoolType << llendl;
+ }
return FALSE;
}
if (num_vertices + mGeomIndex > mVertexBuffer->getNumVerts())
{
- llwarns << "Vertex buffer overflow!" << llendl;
+ if (gDebugGL)
+ {
+ llwarns << "Vertex buffer overflow!" << llendl;
+ }
return FALSE;
}
}
LLStrider<LLVector3> vert;
- LLStrider<LLVector2> tex_coords;
+ LLStrider<LLVector2> tex_coords0;
+ LLStrider<LLVector2> tex_coords1;
LLStrider<LLVector2> tex_coords2;
LLStrider<LLVector3> norm;
LLStrider<LLColor4U> colors;
- LLStrider<LLVector3> binorm;
+ LLStrider<LLVector3> tangent;
LLStrider<U16> indicesp;
LLStrider<LLVector4> wght;
@@ -1185,33 +1252,12 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
bool rebuild_emissive = rebuild_color && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_EMISSIVE);
bool rebuild_tcoord = full_rebuild || mDrawablep->isState(LLDrawable::REBUILD_TCOORD);
bool rebuild_normal = rebuild_pos && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_NORMAL);
- bool rebuild_binormal = rebuild_pos && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_BINORMAL);
+ bool rebuild_tangent = rebuild_pos && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TANGENT);
bool rebuild_weights = rebuild_pos && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_WEIGHT4);
const LLTextureEntry *tep = mVObjp->getTE(f);
const U8 bump_code = tep ? tep->getBumpmap() : 0;
- F32 tcoord_xoffset = 0.f ;
- F32 tcoord_yoffset = 0.f ;
- F32 tcoord_xscale = 1.f ;
- F32 tcoord_yscale = 1.f ;
- BOOL in_atlas = FALSE ;
-
- if (rebuild_tcoord)
- {
- in_atlas = isAtlasInUse() ;
- if(in_atlas)
- {
- const LLVector2* tmp = getTexCoordOffset() ;
- tcoord_xoffset = tmp->mV[0] ;
- tcoord_yoffset = tmp->mV[1] ;
-
- tmp = getTexCoordScale() ;
- tcoord_xscale = tmp->mV[0] ;
- tcoord_yscale = tmp->mV[1] ;
- }
- }
-
BOOL is_static = mDrawablep->isStatic();
BOOL is_global = is_static;
@@ -1229,19 +1275,41 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
LLColor4U color = tep->getColor();
if (rebuild_color)
- {
- if (tep)
+ { //decide if shiny goes in alpha channel of color
+ if (tep &&
+ getPoolType() != LLDrawPool::POOL_ALPHA) // <--- alpha channel MUST contain transparency, not shiny
{
- GLfloat alpha[4] =
- {
- 0.00f,
- 0.25f,
- 0.5f,
- 0.75f
- };
+ LLMaterial* mat = tep->getMaterialParams().get();
+
+ bool shiny_in_alpha = false;
- if (getPoolType() != LLDrawPool::POOL_ALPHA && (LLPipeline::sRenderDeferred || (LLPipeline::sRenderBump && tep->getShiny())))
+ if (LLPipeline::sRenderDeferred)
+ { //store shiny in alpha if we don't have a specular map
+ if (!mat || mat->getSpecularID().isNull())
+ {
+ shiny_in_alpha = true;
+ }
+ }
+ else
+ {
+ if (!mat || mat->getDiffuseAlphaMode() != LLMaterial::DIFFUSE_ALPHA_MODE_MASK)
+ {
+ shiny_in_alpha = true;
+ }
+ }
+
+ if (shiny_in_alpha)
{
+
+ GLfloat alpha[4] =
+ {
+ 0.00f,
+ 0.25f,
+ 0.5f,
+ 0.75f
+ };
+
+ llassert(tep->getShiny() <= 3);
color.mV[3] = U8 (alpha[tep->getShiny()] * 255);
}
}
@@ -1284,17 +1352,10 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
LLMatrix4a mat_normal;
mat_normal.loadu(mat_norm_in);
- //if it's not fullbright and has no normals, bake sunlight based on face normal
- //bool bake_sunlight = !getTextureEntry()->getFullbright() &&
- // !mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_NORMAL);
-
F32 r = 0, os = 0, ot = 0, ms = 0, mt = 0, cos_ang = 0, sin_ang = 0;
-
+ bool do_xform = false;
if (rebuild_tcoord)
{
- LLFastTimer t(FTM_FACE_GEOM_TEXTURE);
- bool do_xform;
-
if (tep)
{
r = tep->getRotation();
@@ -1323,599 +1384,785 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
{
do_xform = false;
}
+ }
+
+ static LLCachedControl<bool> use_transform_feedback(gSavedSettings, "RenderUseTransformFeedback", false);
+
+#ifdef GL_TRANSFORM_FEEDBACK_BUFFER
+ if (use_transform_feedback &&
+ mVertexBuffer->getUsage() == GL_DYNAMIC_COPY_ARB &&
+ gTransformPositionProgram.mProgramObject && //transform shaders are loaded
+ mVertexBuffer->useVBOs() && //target buffer is in VRAM
+ !rebuild_weights && //TODO: add support for weights
+ !volume.isUnique()) //source volume is NOT flexi
+ { //use transform feedback to pack vertex buffer
+ //gGLDebugLoggingEnabled = TRUE;
+ LLFastTimer t(FTM_FACE_GEOM_FEEDBACK);
+ LLGLEnable discard(GL_RASTERIZER_DISCARD);
+ LLVertexBuffer* buff = (LLVertexBuffer*) vf.mVertexBuffer.get();
+
+ if (vf.mVertexBuffer.isNull() || buff->getNumVerts() != vf.mNumVertices)
+ {
+ mVObjp->getVolume()->genTangents(f);
+ LLFace::cacheFaceInVRAM(vf);
+ buff = (LLVertexBuffer*) vf.mVertexBuffer.get();
+ }
+
+ LLGLSLShader* cur_shader = LLGLSLShader::sCurBoundShaderPtr;
+
+ gGL.pushMatrix();
+ gGL.loadMatrix((GLfloat*) mat_vert_in.mMatrix);
+
+ if (rebuild_pos)
+ {
+ LLFastTimer t(FTM_FACE_GEOM_FEEDBACK_POSITION);
+ gTransformPositionProgram.bind();
+
+ mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_VERTEX, mGeomIndex, mGeomCount);
+
+ U8 index = mTextureIndex < 255 ? mTextureIndex : 0;
+
+ S32 val = 0;
+ U8* vp = (U8*) &val;
+ vp[0] = index;
+ vp[1] = 0;
+ vp[2] = 0;
+ vp[3] = 0;
+
+ gTransformPositionProgram.uniform1i(sTextureIndexIn, val);
+ glBeginTransformFeedback(GL_POINTS);
+ buff->setBuffer(LLVertexBuffer::MAP_VERTEX);
+
+ push_for_transform(buff, vf.mNumVertices, mGeomCount);
+
+ glEndTransformFeedback();
+ }
+
+ if (rebuild_color)
+ {
+ LLFastTimer t(FTM_FACE_GEOM_FEEDBACK_COLOR);
+ gTransformColorProgram.bind();
+
+ mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_COLOR, mGeomIndex, mGeomCount);
+
+ S32 val = *((S32*) color.mV);
+
+ gTransformColorProgram.uniform1i(sColorIn, val);
+ glBeginTransformFeedback(GL_POINTS);
+ buff->setBuffer(LLVertexBuffer::MAP_VERTEX);
+ push_for_transform(buff, vf.mNumVertices, mGeomCount);
+ glEndTransformFeedback();
+ }
+
+ if (rebuild_emissive)
+ {
+ LLFastTimer t(FTM_FACE_GEOM_FEEDBACK_EMISSIVE);
+ gTransformColorProgram.bind();
+
+ mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_EMISSIVE, mGeomIndex, mGeomCount);
+
+ U8 glow = (U8) llclamp((S32) (getTextureEntry()->getGlow()*255), 0, 255);
+
+ S32 glow32 = glow |
+ (glow << 8) |
+ (glow << 16) |
+ (glow << 24);
+
+ gTransformColorProgram.uniform1i(sColorIn, glow32);
+ glBeginTransformFeedback(GL_POINTS);
+ buff->setBuffer(LLVertexBuffer::MAP_VERTEX);
+ push_for_transform(buff, vf.mNumVertices, mGeomCount);
+ glEndTransformFeedback();
+ }
+
+ if (rebuild_normal)
+ {
+ LLFastTimer t(FTM_FACE_GEOM_FEEDBACK_NORMAL);
+ gTransformNormalProgram.bind();
+
+ mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_NORMAL, mGeomIndex, mGeomCount);
- //bump setup
- LLVector4a binormal_dir( -sin_ang, cos_ang, 0.f );
- LLVector4a bump_s_primary_light_ray(0.f, 0.f, 0.f);
- LLVector4a bump_t_primary_light_ray(0.f, 0.f, 0.f);
+ glBeginTransformFeedback(GL_POINTS);
+ buff->setBuffer(LLVertexBuffer::MAP_NORMAL);
+ push_for_transform(buff, vf.mNumVertices, mGeomCount);
+ glEndTransformFeedback();
+ }
- LLQuaternion bump_quat;
- if (mDrawablep->isActive())
+ if (rebuild_tangent)
{
- bump_quat = LLQuaternion(mDrawablep->getRenderMatrix());
+ LLFastTimer t(FTM_FACE_GEOM_TANGENT);
+ gTransformTangentProgram.bind();
+
+ mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_TANGENT, mGeomIndex, mGeomCount);
+
+ glBeginTransformFeedback(GL_POINTS);
+ buff->setBuffer(LLVertexBuffer::MAP_TANGENT);
+ push_for_transform(buff, vf.mNumVertices, mGeomCount);
+ glEndTransformFeedback();
}
-
- if (bump_code)
+
+ if (rebuild_tcoord)
+ {
+ LLFastTimer t(FTM_FACE_GEOM_FEEDBACK_TEXTURE);
+ gTransformTexCoordProgram.bind();
+
+ mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_TEXCOORD0, mGeomIndex, mGeomCount);
+
+ glBeginTransformFeedback(GL_POINTS);
+ buff->setBuffer(LLVertexBuffer::MAP_TEXCOORD0);
+ push_for_transform(buff, vf.mNumVertices, mGeomCount);
+ glEndTransformFeedback();
+
+ bool do_bump = bump_code && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1);
+
+ if (do_bump)
+ {
+ mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_TEXCOORD1, mGeomIndex, mGeomCount);
+ glBeginTransformFeedback(GL_POINTS);
+ buff->setBuffer(LLVertexBuffer::MAP_TEXCOORD0);
+ push_for_transform(buff, vf.mNumVertices, mGeomCount);
+ glEndTransformFeedback();
+ }
+ }
+
+ glBindBufferARB(GL_TRANSFORM_FEEDBACK_BUFFER, 0);
+ gGL.popMatrix();
+
+ if (cur_shader)
+ {
+ cur_shader->bind();
+ }
+ }
+ else
+#endif
+ {
+ //if it's not fullbright and has no normals, bake sunlight based on face normal
+ //bool bake_sunlight = !getTextureEntry()->getFullbright() &&
+ // !mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_NORMAL);
+
+ if (rebuild_tcoord)
{
- mVObjp->getVolume()->genBinormals(f);
- F32 offset_multiple;
- switch( bump_code )
+ LLFastTimer t(FTM_FACE_GEOM_TEXTURE);
+
+ //bump setup
+ LLVector4a binormal_dir( -sin_ang, cos_ang, 0.f );
+ LLVector4a bump_s_primary_light_ray(0.f, 0.f, 0.f);
+ LLVector4a bump_t_primary_light_ray(0.f, 0.f, 0.f);
+
+ LLQuaternion bump_quat;
+ if (mDrawablep->isActive())
{
- case BE_NO_BUMP:
- offset_multiple = 0.f;
- break;
- case BE_BRIGHTNESS:
- case BE_DARKNESS:
- if( mTexture.notNull() && mTexture->hasGLTexture())
+ bump_quat = LLQuaternion(mDrawablep->getRenderMatrix());
+ }
+
+ if (bump_code)
+ {
+ mVObjp->getVolume()->genTangents(f);
+ F32 offset_multiple;
+ switch( bump_code )
{
- // Offset by approximately one texel
- S32 cur_discard = mTexture->getDiscardLevel();
- S32 max_size = llmax( mTexture->getWidth(), mTexture->getHeight() );
- max_size <<= cur_discard;
- const F32 ARTIFICIAL_OFFSET = 2.f;
- offset_multiple = ARTIFICIAL_OFFSET / (F32)max_size;
+ case BE_NO_BUMP:
+ offset_multiple = 0.f;
+ break;
+ case BE_BRIGHTNESS:
+ case BE_DARKNESS:
+ if( mTexture[LLRender::DIFFUSE_MAP].notNull() && mTexture[LLRender::DIFFUSE_MAP]->hasGLTexture())
+ {
+ // Offset by approximately one texel
+ S32 cur_discard = mTexture[LLRender::DIFFUSE_MAP]->getDiscardLevel();
+ S32 max_size = llmax( mTexture[LLRender::DIFFUSE_MAP]->getWidth(), mTexture[LLRender::DIFFUSE_MAP]->getHeight() );
+ max_size <<= cur_discard;
+ const F32 ARTIFICIAL_OFFSET = 2.f;
+ offset_multiple = ARTIFICIAL_OFFSET / (F32)max_size;
+ }
+ else
+ {
+ offset_multiple = 1.f/256;
+ }
+ break;
+
+ default: // Standard bumpmap textures. Assumed to be 256x256
+ offset_multiple = 1.f / 256;
+ break;
}
- else
+
+ F32 s_scale = 1.f;
+ F32 t_scale = 1.f;
+ if( tep )
{
- offset_multiple = 1.f/256;
+ tep->getScale( &s_scale, &t_scale );
}
- break;
-
- default: // Standard bumpmap textures. Assumed to be 256x256
- offset_multiple = 1.f / 256;
- break;
+ // Use the nudged south when coming from above sun angle, such
+ // that emboss mapping always shows up on the upward faces of cubes when
+ // it's noon (since a lot of builders build with the sun forced to noon).
+ LLVector3 sun_ray = gSky.mVOSkyp->mBumpSunDir;
+ LLVector3 moon_ray = gSky.getMoonDirection();
+ LLVector3& primary_light_ray = (sun_ray.mV[VZ] > 0) ? sun_ray : moon_ray;
+
+ bump_s_primary_light_ray.load3((offset_multiple * s_scale * primary_light_ray).mV);
+ bump_t_primary_light_ray.load3((offset_multiple * t_scale * primary_light_ray).mV);
}
- F32 s_scale = 1.f;
- F32 t_scale = 1.f;
- if( tep )
- {
- tep->getScale( &s_scale, &t_scale );
+ U8 texgen = getTextureEntry()->getTexGen();
+ if (rebuild_tcoord && texgen != LLTextureEntry::TEX_GEN_DEFAULT)
+ { //planar texgen needs binormals
+ mVObjp->getVolume()->genTangents(f);
}
- // Use the nudged south when coming from above sun angle, such
- // that emboss mapping always shows up on the upward faces of cubes when
- // it's noon (since a lot of builders build with the sun forced to noon).
- LLVector3 sun_ray = gSky.mVOSkyp->mBumpSunDir;
- LLVector3 moon_ray = gSky.getMoonDirection();
- LLVector3& primary_light_ray = (sun_ray.mV[VZ] > 0) ? sun_ray : moon_ray;
-
- bump_s_primary_light_ray.load3((offset_multiple * s_scale * primary_light_ray).mV);
- bump_t_primary_light_ray.load3((offset_multiple * t_scale * primary_light_ray).mV);
- }
-
- U8 texgen = getTextureEntry()->getTexGen();
- if (rebuild_tcoord && texgen != LLTextureEntry::TEX_GEN_DEFAULT)
- { //planar texgen needs binormals
- mVObjp->getVolume()->genBinormals(f);
- }
- U8 tex_mode = 0;
+ U8 tex_mode = 0;
- if (isState(TEXTURE_ANIM))
- {
+ bool tex_anim = false;
+
LLVOVolume* vobj = (LLVOVolume*) (LLViewerObject*) mVObjp;
tex_mode = vobj->mTexAnimMode;
- if (!tex_mode)
- {
- clearState(TEXTURE_ANIM);
+ if (vobj->mTextureAnimp)
+ { //texture animation is in play, override specular and normal map tex coords with diffuse texcoords
+ tex_anim = true;
}
- else
- {
- os = ot = 0.f;
- r = 0.f;
- cos_ang = 1.f;
- sin_ang = 0.f;
- ms = mt = 1.f;
- do_xform = false;
- }
+ if (isState(TEXTURE_ANIM))
+ {
+ if (!tex_mode)
+ {
+ clearState(TEXTURE_ANIM);
+ }
+ else
+ {
+ os = ot = 0.f;
+ r = 0.f;
+ cos_ang = 1.f;
+ sin_ang = 0.f;
+ ms = mt = 1.f;
- if (getVirtualSize() >= MIN_TEX_ANIM_SIZE)
- { //don't override texture transform during tc bake
- tex_mode = 0;
+ do_xform = false;
+ }
+
+ if (getVirtualSize() >= MIN_TEX_ANIM_SIZE)
+ { //don't override texture transform during tc bake
+ tex_mode = 0;
+ }
}
- }
- LLVector4a scalea;
- scalea.load3(scale.mV);
+ LLVector4a scalea;
+ scalea.load3(scale.mV);
- bool do_bump = bump_code && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1);
- bool do_tex_mat = tex_mode && mTextureMatrix;
+ LLMaterial* mat = tep->getMaterialParams().get();
- if (!in_atlas && !do_bump)
- { //not in atlas or not bump mapped, might be able to do a cheap update
- mVertexBuffer->getTexCoord0Strider(tex_coords, mGeomIndex, mGeomCount);
+ bool do_bump = bump_code && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1);
- if (texgen != LLTextureEntry::TEX_GEN_PLANAR)
+ if (mat && !do_bump)
{
- LLFastTimer t(FTM_FACE_TEX_QUICK);
- if (!do_tex_mat)
+ do_bump = mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1)
+ || mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD2);
+ }
+
+ bool do_tex_mat = tex_mode && mTextureMatrix;
+
+ if (!do_bump)
+ { //not bump mapped, might be able to do a cheap update
+ mVertexBuffer->getTexCoord0Strider(tex_coords0, mGeomIndex, mGeomCount);
+
+ if (texgen != LLTextureEntry::TEX_GEN_PLANAR)
{
- if (!do_xform)
+ LLFastTimer t(FTM_FACE_TEX_QUICK);
+ if (!do_tex_mat)
{
- LLFastTimer t(FTM_FACE_TEX_QUICK_NO_XFORM);
- LLVector4a::memcpyNonAliased16((F32*) tex_coords.get(), (F32*) vf.mTexCoords, num_vertices*2*sizeof(F32));
- }
- else
- {
- LLFastTimer t(FTM_FACE_TEX_QUICK_XFORM);
- F32* dst = (F32*) tex_coords.get();
- LLVector4a* src = (LLVector4a*) vf.mTexCoords;
+ if (!do_xform)
+ {
+ LLFastTimer t(FTM_FACE_TEX_QUICK_NO_XFORM);
+ S32 tc_size = (num_vertices*2*sizeof(F32)+0xF) & ~0xF;
+ LLVector4a::memcpyNonAliased16((F32*) tex_coords0.get(), (F32*) vf.mTexCoords, tc_size);
+ }
+ else
+ {
+ LLFastTimer t(FTM_FACE_TEX_QUICK_XFORM);
+ F32* dst = (F32*) tex_coords0.get();
+ LLVector4a* src = (LLVector4a*) vf.mTexCoords;
- LLVector4a trans;
- trans.splat(-0.5f);
+ LLVector4a trans;
+ trans.splat(-0.5f);
- LLVector4a rot0;
- rot0.set(cos_ang, -sin_ang, cos_ang, -sin_ang);
+ LLVector4a rot0;
+ rot0.set(cos_ang, -sin_ang, cos_ang, -sin_ang);
- LLVector4a rot1;
- rot1.set(sin_ang, cos_ang, sin_ang, cos_ang);
+ LLVector4a rot1;
+ rot1.set(sin_ang, cos_ang, sin_ang, cos_ang);
- LLVector4a scale;
- scale.set(ms, mt, ms, mt);
+ LLVector4a scale;
+ scale.set(ms, mt, ms, mt);
- LLVector4a offset;
- offset.set(os+0.5f, ot+0.5f, os+0.5f, ot+0.5f);
+ LLVector4a offset;
+ offset.set(os+0.5f, ot+0.5f, os+0.5f, ot+0.5f);
- LLVector4Logical mask;
- mask.clear();
- mask.setElement<2>();
- mask.setElement<3>();
+ LLVector4Logical mask;
+ mask.clear();
+ mask.setElement<2>();
+ mask.setElement<3>();
- U32 count = num_vertices/2 + num_vertices%2;
+ U32 count = num_vertices/2 + num_vertices%2;
- for (S32 i = 0; i < count; i++)
+ for (S32 i = 0; i < count; i++)
+ {
+ LLVector4a res = *src++;
+ xform4a(res, trans, mask, rot0, rot1, offset, scale);
+ res.store4a(dst);
+ dst += 4;
+ }
+ }
+ }
+ else
+ { //do tex mat, no texgen, no bump
+ for (S32 i = 0; i < num_vertices; i++)
{
- LLVector4a res = *src++;
- xform4a(res, trans, mask, rot0, rot1, offset, scale);
- res.store4a(dst);
- dst += 4;
+ LLVector2 tc(vf.mTexCoords[i]);
+ //LLVector4a& norm = vf.mNormals[i];
+ //LLVector4a& center = *(vf.mCenter);
+
+ LLVector3 tmp(tc.mV[0], tc.mV[1], 0.f);
+ tmp = tmp * *mTextureMatrix;
+ tc.mV[0] = tmp.mV[0];
+ tc.mV[1] = tmp.mV[1];
+ *tex_coords0++ = tc;
}
}
}
else
- { //do tex mat, no texgen, no atlas, no bump
- for (S32 i = 0; i < num_vertices; i++)
- {
- LLVector2 tc(vf.mTexCoords[i]);
- //LLVector4a& norm = vf.mNormals[i];
- //LLVector4a& center = *(vf.mCenter);
-
- LLVector3 tmp(tc.mV[0], tc.mV[1], 0.f);
- tmp = tmp * *mTextureMatrix;
- tc.mV[0] = tmp.mV[0];
- tc.mV[1] = tmp.mV[1];
- *tex_coords++ = tc;
- }
- }
- }
- else
- { //no bump, no atlas, tex gen planar
- LLFastTimer t(FTM_FACE_TEX_QUICK_PLANAR);
- if (do_tex_mat)
- {
- for (S32 i = 0; i < num_vertices; i++)
- {
- LLVector2 tc(vf.mTexCoords[i]);
- LLVector4a& norm = vf.mNormals[i];
- LLVector4a& center = *(vf.mCenter);
- LLVector4a vec = vf.mPositions[i];
- vec.mul(scalea);
- planarProjection(tc, norm, center, vec);
+ { //no bump, tex gen planar
+ LLFastTimer t(FTM_FACE_TEX_QUICK_PLANAR);
+ if (do_tex_mat)
+ {
+ for (S32 i = 0; i < num_vertices; i++)
+ {
+ LLVector2 tc(vf.mTexCoords[i]);
+ LLVector4a& norm = vf.mNormals[i];
+ LLVector4a& center = *(vf.mCenter);
+ LLVector4a vec = vf.mPositions[i];
+ vec.mul(scalea);
+ planarProjection(tc, norm, center, vec);
- LLVector3 tmp(tc.mV[0], tc.mV[1], 0.f);
- tmp = tmp * *mTextureMatrix;
- tc.mV[0] = tmp.mV[0];
- tc.mV[1] = tmp.mV[1];
+ LLVector3 tmp(tc.mV[0], tc.mV[1], 0.f);
+ tmp = tmp * *mTextureMatrix;
+ tc.mV[0] = tmp.mV[0];
+ tc.mV[1] = tmp.mV[1];
- *tex_coords++ = tc;
+ *tex_coords0++ = tc;
+ }
}
- }
- else
- {
- for (S32 i = 0; i < num_vertices; i++)
- {
- LLVector2 tc(vf.mTexCoords[i]);
- LLVector4a& norm = vf.mNormals[i];
- LLVector4a& center = *(vf.mCenter);
- LLVector4a vec = vf.mPositions[i];
- vec.mul(scalea);
- planarProjection(tc, norm, center, vec);
+ else
+ {
+ for (S32 i = 0; i < num_vertices; i++)
+ {
+ LLVector2 tc(vf.mTexCoords[i]);
+ LLVector4a& norm = vf.mNormals[i];
+ LLVector4a& center = *(vf.mCenter);
+ LLVector4a vec = vf.mPositions[i];
+ vec.mul(scalea);
+ planarProjection(tc, norm, center, vec);
- xform(tc, cos_ang, sin_ang, os, ot, ms, mt);
+ xform(tc, cos_ang, sin_ang, os, ot, ms, mt);
- *tex_coords++ = tc;
+ *tex_coords0++ = tc;
+ }
}
}
- }
-
- if (map_range)
- {
- mVertexBuffer->flush();
- }
- }
- else
- { //either bump mapped or in atlas, just do the whole expensive loop
- LLFastTimer t(FTM_FACE_TEX_DEFAULT);
- mVertexBuffer->getTexCoord0Strider(tex_coords, mGeomIndex, mGeomCount, map_range);
- std::vector<LLVector2> bump_tc;
-
- for (S32 i = 0; i < num_vertices; i++)
- {
- LLVector2 tc(vf.mTexCoords[i]);
-
- LLVector4a& norm = vf.mNormals[i];
-
- LLVector4a& center = *(vf.mCenter);
-
- if (texgen != LLTextureEntry::TEX_GEN_DEFAULT)
+ if (map_range)
{
- LLVector4a vec = vf.mPositions[i];
+ mVertexBuffer->flush();
+ }
+ }
+ else
+ { //bump mapped or has material, just do the whole expensive loop
+ LLFastTimer t(FTM_FACE_TEX_DEFAULT);
- vec.mul(scalea);
+ std::vector<LLVector2> bump_tc;
- switch (texgen)
- {
- case LLTextureEntry::TEX_GEN_PLANAR:
- planarProjection(tc, norm, center, vec);
- break;
- case LLTextureEntry::TEX_GEN_SPHERICAL:
- sphericalProjection(tc, norm, center, vec);
- break;
- case LLTextureEntry::TEX_GEN_CYLINDRICAL:
- cylindricalProjection(tc, norm, center, vec);
- break;
- default:
- break;
- }
+ if (mat && !mat->getNormalID().isNull())
+ { //writing out normal and specular texture coordinates, not bump offsets
+ do_bump = false;
}
- if (tex_mode && mTextureMatrix)
- {
- LLVector3 tmp(tc.mV[0], tc.mV[1], 0.f);
- tmp = tmp * *mTextureMatrix;
- tc.mV[0] = tmp.mV[0];
- tc.mV[1] = tmp.mV[1];
- }
- else
- {
- xform(tc, cos_ang, sin_ang, os, ot, ms, mt);
- }
+ LLStrider<LLVector2> dst;
- if(in_atlas)
+ for (U32 ch = 0; ch < 3; ++ch)
{
- //
- //manually calculate tex-coord per vertex for varying address modes.
- //should be removed if shader can handle this.
- //
-
- S32 int_part = 0 ;
- switch(mTexture->getAddressMode())
+ switch (ch)
{
- case LLTexUnit::TAM_CLAMP:
- if(tc.mV[0] < 0.f)
- {
- tc.mV[0] = 0.f ;
- }
- else if(tc.mV[0] > 1.f)
- {
- tc.mV[0] = 1.f;
- }
+ case 0:
+ mVertexBuffer->getTexCoord0Strider(dst, mGeomIndex, mGeomCount, map_range);
+ break;
+ case 1:
+ if (mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1))
+ {
+ mVertexBuffer->getTexCoord1Strider(dst, mGeomIndex, mGeomCount, map_range);
+ if (mat && !tex_anim)
+ {
+ r = mat->getNormalRotation();
+ mat->getNormalOffset(os, ot);
+ mat->getNormalRepeat(ms, mt);
+
+ cos_ang = cos(r);
+ sin_ang = sin(r);
+
+ }
+ }
+ else
+ {
+ continue;
+ }
+ break;
+ case 2:
+ if (mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD2))
+ {
+ mVertexBuffer->getTexCoord2Strider(dst, mGeomIndex, mGeomCount, map_range);
+ if (mat && !tex_anim)
+ {
+ r = mat->getSpecularRotation();
+ mat->getSpecularOffset(os, ot);
+ mat->getSpecularRepeat(ms, mt);
+
+ cos_ang = cos(r);
+ sin_ang = sin(r);
+ }
+ }
+ else
+ {
+ continue;
+ }
+ break;
+ }
+
- if(tc.mV[1] < 0.f)
- {
- tc.mV[1] = 0.f ;
- }
- else if(tc.mV[1] > 1.f)
- {
- tc.mV[1] = 1.f;
- }
- break;
- case LLTexUnit::TAM_MIRROR:
- if(tc.mV[0] < 0.f)
- {
- tc.mV[0] = -tc.mV[0] ;
- }
- int_part = (S32)tc.mV[0] ;
- if(int_part & 1) //odd number
- {
- tc.mV[0] = int_part + 1 - tc.mV[0] ;
- }
- else //even number
+ for (S32 i = 0; i < num_vertices; i++)
+ {
+ LLVector2 tc(vf.mTexCoords[i]);
+
+ LLVector4a& norm = vf.mNormals[i];
+
+ LLVector4a& center = *(vf.mCenter);
+
+ if (texgen != LLTextureEntry::TEX_GEN_DEFAULT)
{
- tc.mV[0] -= int_part ;
- }
+ LLVector4a vec = vf.mPositions[i];
+
+ vec.mul(scalea);
- if(tc.mV[1] < 0.f)
- {
- tc.mV[1] = -tc.mV[1] ;
- }
- int_part = (S32)tc.mV[1] ;
- if(int_part & 1) //odd number
- {
- tc.mV[1] = int_part + 1 - tc.mV[1] ;
+ if (texgen == LLTextureEntry::TEX_GEN_PLANAR)
+ {
+ planarProjection(tc, norm, center, vec);
+ }
}
- else //even number
+
+ if (tex_mode && mTextureMatrix)
{
- tc.mV[1] -= int_part ;
+ LLVector3 tmp(tc.mV[0], tc.mV[1], 0.f);
+ tmp = tmp * *mTextureMatrix;
+ tc.mV[0] = tmp.mV[0];
+ tc.mV[1] = tmp.mV[1];
}
- break;
- case LLTexUnit::TAM_WRAP:
- if(tc.mV[0] > 1.f)
- tc.mV[0] -= (S32)(tc.mV[0] - 0.00001f) ;
- else if(tc.mV[0] < -1.f)
- tc.mV[0] -= (S32)(tc.mV[0] + 0.00001f) ;
-
- if(tc.mV[1] > 1.f)
- tc.mV[1] -= (S32)(tc.mV[1] - 0.00001f) ;
- else if(tc.mV[1] < -1.f)
- tc.mV[1] -= (S32)(tc.mV[1] + 0.00001f) ;
-
- if(tc.mV[0] < 0.f)
+ else
{
- tc.mV[0] = 1.0f + tc.mV[0] ;
+ xform(tc, cos_ang, sin_ang, os, ot, ms, mt);
}
- if(tc.mV[1] < 0.f)
+
+ *dst++ = tc;
+ if (do_bump)
{
- tc.mV[1] = 1.0f + tc.mV[1] ;
+ bump_tc.push_back(tc);
}
- break;
- default:
- break;
}
-
- tc.mV[0] = tcoord_xoffset + tcoord_xscale * tc.mV[0] ;
- tc.mV[1] = tcoord_yoffset + tcoord_yscale * tc.mV[1] ;
}
-
- *tex_coords++ = tc;
- if (do_bump)
+ if (map_range)
{
- bump_tc.push_back(tc);
+ mVertexBuffer->flush();
}
- }
-
- if (map_range)
- {
- mVertexBuffer->flush();
- }
- if (do_bump)
- {
- mVertexBuffer->getTexCoord1Strider(tex_coords2, mGeomIndex, mGeomCount, map_range);
-
- for (S32 i = 0; i < num_vertices; i++)
+ if (!mat && do_bump)
{
- LLVector4a tangent;
- tangent.setCross3(vf.mBinormals[i], vf.mNormals[i]);
-
- LLMatrix4a tangent_to_object;
- tangent_to_object.setRows(tangent, vf.mBinormals[i], vf.mNormals[i]);
- LLVector4a t;
- tangent_to_object.rotate(binormal_dir, t);
- LLVector4a binormal;
- mat_normal.rotate(t, binormal);
-
- //VECTORIZE THIS
- if (mDrawablep->isActive())
+ mVertexBuffer->getTexCoord1Strider(tex_coords1, mGeomIndex, mGeomCount, map_range);
+
+ for (S32 i = 0; i < num_vertices; i++)
{
- LLVector3 t;
- t.set(binormal.getF32ptr());
- t *= bump_quat;
- binormal.load3(t.mV);
- }
+ LLVector4a tangent = vf.mTangents[i];
+
+ LLVector4a binorm;
+ binorm.setCross3(vf.mNormals[i], tangent);
+ binorm.mul(tangent.getF32ptr()[3]);
+
+ LLMatrix4a tangent_to_object;
+ tangent_to_object.setRows(tangent, binorm, vf.mNormals[i]);
+ LLVector4a t;
+ tangent_to_object.rotate(binormal_dir, t);
+ LLVector4a binormal;
+ mat_normal.rotate(t, binormal);
+
+ //VECTORIZE THIS
+ if (mDrawablep->isActive())
+ {
+ LLVector3 t;
+ t.set(binormal.getF32ptr());
+ t *= bump_quat;
+ binormal.load3(t.mV);
+ }
+
+ binormal.normalize3fast();
- binormal.normalize3fast();
- LLVector2 tc = bump_tc[i];
- tc += LLVector2( bump_s_primary_light_ray.dot3(tangent).getF32(), bump_t_primary_light_ray.dot3(binormal).getF32() );
+ LLVector2 tc = bump_tc[i];
+ tc += LLVector2( bump_s_primary_light_ray.dot3(tangent).getF32(), bump_t_primary_light_ray.dot3(binormal).getF32() );
- *tex_coords2++ = tc;
- }
+ *tex_coords1++ = tc;
+ }
- if (map_range)
- {
- mVertexBuffer->flush();
+ if (map_range)
+ {
+ mVertexBuffer->flush();
+ }
}
}
}
- }
- if (rebuild_pos)
- {
- LLFastTimer t(FTM_FACE_GEOM_POSITION);
- llassert(num_vertices > 0);
+ if (rebuild_pos)
+ {
+ LLVector4a* src = vf.mPositions;
+
+ //_mm_prefetch((char*)src, _MM_HINT_T0);
+
+ LLVector4a* end = src+num_vertices;
+ //LLVector4a* end_64 = end-4;
+
+ //LLFastTimer t(FTM_FACE_GEOM_POSITION);
+ llassert(num_vertices > 0);
- mVertexBuffer->getVertexStrider(vert, mGeomIndex, mGeomCount, map_range);
+ mVertexBuffer->getVertexStrider(vert, mGeomIndex, mGeomCount, map_range);
+ LLMatrix4a mat_vert;
+ mat_vert.loadu(mat_vert_in);
- LLMatrix4a mat_vert;
- mat_vert.loadu(mat_vert_in);
+ F32* dst = (F32*) vert.get();
+ F32* end_f32 = dst+mGeomCount*4;
- LLVector4a* src = vf.mPositions;
- volatile F32* dst = (volatile F32*) vert.get();
+ //_mm_prefetch((char*)dst, _MM_HINT_NTA);
+ //_mm_prefetch((char*)src, _MM_HINT_NTA);
+
+ //_mm_prefetch((char*)dst, _MM_HINT_NTA);
- volatile F32* end = dst+num_vertices*4;
- LLVector4a res;
- LLVector4a texIdx;
+ LLVector4a res0; //,res1,res2,res3;
- U8 index = mTextureIndex < 255 ? mTextureIndex : 0;
+ LLVector4a texIdx;
- F32 val = 0.f;
- U8* vp = (U8*) &val;
- vp[0] = index;
- vp[1] = 0;
- vp[2] = 0;
- vp[3] = 0;
+ S32 index = mTextureIndex < 255 ? mTextureIndex : 0;
- llassert(index <= LLGLSLShader::sIndexedTextureChannels-1);
+ F32 val = 0.f;
+ S32* vp = (S32*) &val;
+ *vp = index;
+
+ llassert(index <= LLGLSLShader::sIndexedTextureChannels-1);
- LLVector4Logical mask;
- mask.clear();
- mask.setElement<3>();
+ LLVector4Logical mask;
+ mask.clear();
+ mask.setElement<3>();
- texIdx.set(0,0,0,val);
+ texIdx.set(0,0,0,val);
- {
- LLFastTimer t(FTM_FACE_POSITION_STORE);
LLVector4a tmp;
- do
- {
- mat_vert.affineTransform(*src++, res);
- tmp.setSelectWithMask(mask, texIdx, res);
- tmp.store4a((F32*) dst);
- dst += 4;
+ {
+ //LLFastTimer t2(FTM_FACE_POSITION_STORE);
+
+ /*if (num_vertices > 4)
+ { //more than 64 bytes
+ while (src < end_64)
+ {
+ _mm_prefetch((char*)src + 64, _MM_HINT_T0);
+ _mm_prefetch((char*)dst + 64, _MM_HINT_T0);
+
+ mat_vert.affineTransform(*src, res0);
+ tmp.setSelectWithMask(mask, texIdx, res0);
+ tmp.store4a((F32*) dst);
+
+ mat_vert.affineTransform(*(src+1), res1);
+ tmp.setSelectWithMask(mask, texIdx, res1);
+ tmp.store4a((F32*) dst+4);
+
+ mat_vert.affineTransform(*(src+2), res2);
+ tmp.setSelectWithMask(mask, texIdx, res2);
+ tmp.store4a((F32*) dst+8);
+
+ mat_vert.affineTransform(*(src+3), res3);
+ tmp.setSelectWithMask(mask, texIdx, res3);
+ tmp.store4a((F32*) dst+12);
+
+ dst += 16;
+ src += 4;
+ }
+ }*/
+
+ while (src < end)
+ {
+ mat_vert.affineTransform(*src++, res0);
+ tmp.setSelectWithMask(mask, texIdx, res0);
+ tmp.store4a((F32*) dst);
+ dst += 4;
+ }
}
- while(dst < end);
- }
- {
- LLFastTimer t(FTM_FACE_POSITION_PAD);
- S32 aligned_pad_vertices = mGeomCount - num_vertices;
- res.set(res[0], res[1], res[2], 0.f);
+ {
+ //LLFastTimer t(FTM_FACE_POSITION_PAD);
+ while (dst < end_f32)
+ {
+ res0.store4a((F32*) dst);
+ dst += 4;
+ }
+ }
- while (aligned_pad_vertices > 0)
+ if (map_range)
{
- --aligned_pad_vertices;
- res.store4a((F32*) dst);
- dst += 4;
+ mVertexBuffer->flush();
}
}
- if (map_range)
- {
- mVertexBuffer->flush();
- }
- }
- if (rebuild_normal)
- {
- LLFastTimer t(FTM_FACE_GEOM_NORMAL);
- mVertexBuffer->getNormalStrider(norm, mGeomIndex, mGeomCount, map_range);
- F32* normals = (F32*) norm.get();
-
- for (S32 i = 0; i < num_vertices; i++)
- {
- LLVector4a normal;
- mat_normal.rotate(vf.mNormals[i], normal);
- normal.normalize3fast();
- normal.store4a(normals);
- normals += 4;
- }
-
- if (map_range)
+ if (rebuild_normal)
{
- mVertexBuffer->flush();
+ //LLFastTimer t(FTM_FACE_GEOM_NORMAL);
+ mVertexBuffer->getNormalStrider(norm, mGeomIndex, mGeomCount, map_range);
+ F32* normals = (F32*) norm.get();
+ LLVector4a* src = vf.mNormals;
+ LLVector4a* end = src+num_vertices;
+
+ while (src < end)
+ {
+ LLVector4a normal;
+ mat_normal.rotate(*src++, normal);
+ normal.store4a(normals);
+ normals += 4;
+ }
+
+ if (map_range)
+ {
+ mVertexBuffer->flush();
+ }
}
- }
- if (rebuild_binormal)
- {
- LLFastTimer t(FTM_FACE_GEOM_BINORMAL);
- mVertexBuffer->getBinormalStrider(binorm, mGeomIndex, mGeomCount, map_range);
- F32* binormals = (F32*) binorm.get();
-
- for (S32 i = 0; i < num_vertices; i++)
- {
- LLVector4a binormal;
- mat_normal.rotate(vf.mBinormals[i], binormal);
- binormal.normalize3fast();
- binormal.store4a(binormals);
- binormals += 4;
- }
-
- if (map_range)
+ if (rebuild_tangent)
{
- mVertexBuffer->flush();
+ LLFastTimer t(FTM_FACE_GEOM_TANGENT);
+ mVertexBuffer->getTangentStrider(tangent, mGeomIndex, mGeomCount, map_range);
+ F32* tangents = (F32*) tangent.get();
+
+ mVObjp->getVolume()->genTangents(f);
+
+ LLVector4Logical mask;
+ mask.clear();
+ mask.setElement<3>();
+
+ LLVector4a* src = vf.mTangents;
+ LLVector4a* end = vf.mTangents+num_vertices;
+
+ while (src < end)
+ {
+ LLVector4a tangent_out;
+ mat_normal.rotate(*src, tangent_out);
+ tangent_out.normalize3fast();
+ tangent_out.setSelectWithMask(mask, *src, tangent_out);
+ tangent_out.store4a(tangents);
+
+ src++;
+ tangents += 4;
+ }
+
+ if (map_range)
+ {
+ mVertexBuffer->flush();
+ }
}
- }
- if (rebuild_weights && vf.mWeights)
- {
- LLFastTimer t(FTM_FACE_GEOM_WEIGHTS);
- mVertexBuffer->getWeight4Strider(wght, mGeomIndex, mGeomCount, map_range);
- F32* weights = (F32*) wght.get();
- LLVector4a::memcpyNonAliased16(weights, (F32*) vf.mWeights, num_vertices*4*sizeof(F32));
- if (map_range)
+ if (rebuild_weights && vf.mWeights)
{
- mVertexBuffer->flush();
+ LLFastTimer t(FTM_FACE_GEOM_WEIGHTS);
+ mVertexBuffer->getWeight4Strider(wght, mGeomIndex, mGeomCount, map_range);
+ F32* weights = (F32*) wght.get();
+ LLVector4a::memcpyNonAliased16(weights, (F32*) vf.mWeights, num_vertices*4*sizeof(F32));
+ if (map_range)
+ {
+ mVertexBuffer->flush();
+ }
}
- }
- if (rebuild_color && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_COLOR) )
- {
- LLFastTimer t(FTM_FACE_GEOM_COLOR);
- mVertexBuffer->getColorStrider(colors, mGeomIndex, mGeomCount, map_range);
+ if (rebuild_color && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_COLOR) )
+ {
+ LLFastTimer t(FTM_FACE_GEOM_COLOR);
+ mVertexBuffer->getColorStrider(colors, mGeomIndex, mGeomCount, map_range);
- LLVector4a src;
+ LLVector4a src;
- U32 vec[4];
- vec[0] = vec[1] = vec[2] = vec[3] = color.mAll;
+ U32 vec[4];
+ vec[0] = vec[1] = vec[2] = vec[3] = color.mAll;
- src.loadua((F32*) vec);
+ src.loadua((F32*) vec);
- F32* dst = (F32*) colors.get();
- S32 num_vecs = num_vertices/4;
- if (num_vertices%4 > 0)
- {
- ++num_vecs;
- }
+ F32* dst = (F32*) colors.get();
+ S32 num_vecs = num_vertices/4;
+ if (num_vertices%4 > 0)
+ {
+ ++num_vecs;
+ }
- for (S32 i = 0; i < num_vecs; i++)
- {
- src.store4a(dst);
- dst += 4;
- }
+ for (S32 i = 0; i < num_vecs; i++)
+ {
+ src.store4a(dst);
+ dst += 4;
+ }
- if (map_range)
- {
- mVertexBuffer->flush();
+ if (map_range)
+ {
+ mVertexBuffer->flush();
+ }
}
- }
- if (rebuild_emissive)
- {
- LLFastTimer t(FTM_FACE_GEOM_EMISSIVE);
- LLStrider<LLColor4U> emissive;
- mVertexBuffer->getEmissiveStrider(emissive, mGeomIndex, mGeomCount, map_range);
+ if (rebuild_emissive)
+ {
+ LLFastTimer t(FTM_FACE_GEOM_EMISSIVE);
+ LLStrider<LLColor4U> emissive;
+ mVertexBuffer->getEmissiveStrider(emissive, mGeomIndex, mGeomCount, map_range);
- U8 glow = (U8) llclamp((S32) (getTextureEntry()->getGlow()*255), 0, 255);
+ U8 glow = (U8) llclamp((S32) (getTextureEntry()->getGlow()*255), 0, 255);
- LLVector4a src;
+ LLVector4a src;
- U32 glow32 = glow |
- (glow << 8) |
- (glow << 16) |
- (glow << 24);
+ LLColor4U glow4u = LLColor4U(0,0,0,glow);
- U32 vec[4];
- vec[0] = vec[1] = vec[2] = vec[3] = glow32;
+ U32 glow32 = glow4u.mAll;
+
+ U32 vec[4];
+ vec[0] = vec[1] = vec[2] = vec[3] = glow32;
- src.loadua((F32*) vec);
+ src.loadua((F32*) vec);
- F32* dst = (F32*) emissive.get();
- S32 num_vecs = num_vertices/4;
- if (num_vertices%4 > 0)
- {
- ++num_vecs;
- }
+ F32* dst = (F32*) emissive.get();
+ S32 num_vecs = num_vertices/4;
+ if (num_vertices%4 > 0)
+ {
+ ++num_vecs;
+ }
- for (S32 i = 0; i < num_vecs; i++)
- {
- src.store4a(dst);
- dst += 4;
- }
+ for (S32 i = 0; i < num_vecs; i++)
+ {
+ src.store4a(dst);
+ dst += 4;
+ }
- if (map_range)
- {
- mVertexBuffer->flush();
+ if (map_range)
+ {
+ mVertexBuffer->flush();
+ }
}
}
+
if (rebuild_tcoord)
{
mTexExtents[0].setVec(0,0);
@@ -1932,12 +2179,6 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
}
- mLastVertexBuffer = mVertexBuffer;
- mLastGeomCount = mGeomCount;
- mLastGeomIndex = mGeomIndex;
- mLastIndicesCount = mIndicesCount;
- mLastIndicesIndex = mIndicesIndex;
-
return TRUE;
}
@@ -1948,9 +2189,9 @@ BOOL LLFace::hasMedia() const
{
return TRUE ;
}
- if(mTexture.notNull())
+ if(mTexture[LLRender::DIFFUSE_MAP].notNull())
{
- return mTexture->hasParcelMedia() ; //if has a parcel media
+ return mTexture[LLRender::DIFFUSE_MAP]->hasParcelMedia() ; //if has a parcel media
}
return FALSE ; //no media.
@@ -1959,6 +2200,12 @@ BOOL LLFace::hasMedia() const
const F32 LEAST_IMPORTANCE = 0.05f ;
const F32 LEAST_IMPORTANCE_FOR_LARGE_IMAGE = 0.3f ;
+void LLFace::resetVirtualSize()
+{
+ setVirtualSize(0.f);
+ mImportanceToCamera = 0.f;
+}
+
F32 LLFace::getTextureVirtualSize()
{
F32 radius;
@@ -1996,7 +2243,7 @@ F32 LLFace::getTextureVirtualSize()
face_area = LLFace::adjustPixelArea(mImportanceToCamera, face_area) ;
if(face_area > LLViewerTexture::sMinLargeImageSize) //if is large image, shrink face_area by considering the partial overlapping.
{
- if(mImportanceToCamera > LEAST_IMPORTANCE_FOR_LARGE_IMAGE && mTexture.notNull() && mTexture->isLargeImage())
+ if(mImportanceToCamera > LEAST_IMPORTANCE_FOR_LARGE_IMAGE && mTexture[LLRender::DIFFUSE_MAP].notNull() && mTexture[LLRender::DIFFUSE_MAP]->isLargeImage())
{
face_area *= adjustPartialOverlapPixelArea(cos_angle_to_view_dir, radius );
}
@@ -2024,9 +2271,18 @@ BOOL LLFace::calcPixelArea(F32& cos_angle_to_view_dir, F32& radius)
LLVector4a t;
t.load3(camera->getOrigin().mV);
lookAt.setSub(center, t);
+
F32 dist = lookAt.getLength3().getF32();
- dist = llmax(dist-size.getLength3().getF32(), 0.f);
- lookAt.normalize3fast() ;
+ dist = llmax(dist-size.getLength3().getF32(), 0.001f);
+ //ramp down distance for nearby objects
+ if (dist < 16.f)
+ {
+ dist /= 16.f;
+ dist *= dist;
+ dist *= 16.f;
+ }
+
+ lookAt.normalize3fast();
//get area of circle around node
F32 app_angle = atanf((F32) sqrt(size_squared) / dist);
@@ -2354,159 +2610,13 @@ LLVector3 LLFace::getPositionAgent() const
}
}
-//
-//atlas
-//
-void LLFace::removeAtlas()
-{
- setAtlasInUse(FALSE) ;
- mAtlasInfop = NULL ;
-}
-
-const LLTextureAtlas* LLFace::getAtlas()const
-{
- if(mAtlasInfop)
- {
- return mAtlasInfop->getAtlas() ;
- }
- return NULL ;
-}
-
-const LLVector2* LLFace::getTexCoordOffset()const
-{
- if(isAtlasInUse())
- {
- return mAtlasInfop->getTexCoordOffset() ;
- }
- return NULL ;
-}
-const LLVector2* LLFace::getTexCoordScale() const
-{
- if(isAtlasInUse())
- {
- return mAtlasInfop->getTexCoordScale() ;
- }
- return NULL ;
-}
-
-BOOL LLFace::isAtlasInUse()const
-{
- return mUsingAtlas ;
-}
-
-BOOL LLFace::canUseAtlas()const
-{
- //no drawable or no spatial group, do not use atlas
- if(!mDrawablep || !mDrawablep->getSpatialGroup())
- {
- return FALSE ;
- }
-
- //if bump face, do not use atlas
- if(getTextureEntry() && getTextureEntry()->getBumpmap())
- {
- return FALSE ;
- }
-
- //if animated texture, do not use atlas
- if(isState(TEXTURE_ANIM))
- {
- return FALSE ;
- }
-
- return TRUE ;
-}
-
-void LLFace::setAtlasInUse(BOOL flag)
-{
- //no valid atlas to use.
- if(flag && (!mAtlasInfop || !mAtlasInfop->isValid()))
- {
- flag = FALSE ;
- }
-
- if(!flag && !mUsingAtlas)
- {
- return ;
- }
-
- //
- //at this stage (flag || mUsingAtlas) is always true.
- //
-
- //rebuild the tex coords
- if(mDrawablep)
- {
- gPipeline.markRebuild(mDrawablep, LLDrawable::REBUILD_TCOORD);
- mUsingAtlas = flag ;
- }
- else
- {
- mUsingAtlas = FALSE ;
- }
-}
-
-LLTextureAtlasSlot* LLFace::getAtlasInfo()
-{
- return mAtlasInfop ;
-}
-
-void LLFace::setAtlasInfo(LLTextureAtlasSlot* atlasp)
-{
- if(mAtlasInfop != atlasp)
- {
- if(mAtlasInfop)
- {
- //llerrs << "Atlas slot changed!" << llendl ;
- }
- mAtlasInfop = atlasp ;
- }
-}
-
-LLViewerTexture* LLFace::getTexture() const
+LLViewerTexture* LLFace::getTexture(U32 ch) const
{
- if(isAtlasInUse())
- {
- return (LLViewerTexture*)mAtlasInfop->getAtlas() ;
- }
+ llassert(ch < LLRender::NUM_TEXTURE_CHANNELS);
- return mTexture ;
+ return mTexture[ch] ;
}
-//switch to atlas or switch back to gl texture
-//return TRUE if using atlas.
-BOOL LLFace::switchTexture()
-{
- //no valid atlas or texture
- if(!mAtlasInfop || !mAtlasInfop->isValid() || !mTexture)
- {
- return FALSE ;
- }
-
- if(mTexture->getTexelsInAtlas() >= (U32)mVSize ||
- mTexture->getTexelsInAtlas() >= mTexture->getTexelsInGLTexture())
- {
- //switch to use atlas
- //atlas resolution is qualified, use it.
- if(!mUsingAtlas)
- {
- setAtlasInUse(TRUE) ;
- }
- }
- else //if atlas not qualified.
- {
- //switch back to GL texture
- if(mUsingAtlas && mTexture->isGLTextureCreated() &&
- mTexture->getDiscardLevel() < mTexture->getDiscardLevelInAtlas())
- {
- setAtlasInUse(FALSE) ;
- }
- }
-
- return mUsingAtlas ;
-}
-
-
void LLFace::setVertexBuffer(LLVertexBuffer* buffer)
{
mVertexBuffer = buffer;
@@ -2516,13 +2626,28 @@ void LLFace::setVertexBuffer(LLVertexBuffer* buffer)
void LLFace::clearVertexBuffer()
{
mVertexBuffer = NULL;
- mLastVertexBuffer = NULL;
}
//static
U32 LLFace::getRiggedDataMask(U32 type)
{
static const U32 rigged_data_mask[] = {
+ LLDrawPoolAvatar::RIGGED_MATERIAL_MASK,
+ LLDrawPoolAvatar::RIGGED_MATERIAL_ALPHA_VMASK,
+ LLDrawPoolAvatar::RIGGED_MATERIAL_ALPHA_MASK_MASK,
+ LLDrawPoolAvatar::RIGGED_MATERIAL_ALPHA_EMISSIVE_MASK,
+ LLDrawPoolAvatar::RIGGED_SPECMAP_VMASK,
+ LLDrawPoolAvatar::RIGGED_SPECMAP_BLEND_MASK,
+ LLDrawPoolAvatar::RIGGED_SPECMAP_MASK_MASK,
+ LLDrawPoolAvatar::RIGGED_SPECMAP_EMISSIVE_MASK,
+ LLDrawPoolAvatar::RIGGED_NORMMAP_VMASK,
+ LLDrawPoolAvatar::RIGGED_NORMMAP_BLEND_MASK,
+ LLDrawPoolAvatar::RIGGED_NORMMAP_MASK_MASK,
+ LLDrawPoolAvatar::RIGGED_NORMMAP_EMISSIVE_MASK,
+ LLDrawPoolAvatar::RIGGED_NORMSPEC_VMASK,
+ LLDrawPoolAvatar::RIGGED_NORMSPEC_BLEND_MASK,
+ LLDrawPoolAvatar::RIGGED_NORMSPEC_MASK_MASK,
+ LLDrawPoolAvatar::RIGGED_NORMSPEC_EMISSIVE_MASK,
LLDrawPoolAvatar::RIGGED_SIMPLE_MASK,
LLDrawPoolAvatar::RIGGED_FULLBRIGHT_MASK,
LLDrawPoolAvatar::RIGGED_SHINY_MASK,
diff --git a/indra/newview/llface.h b/indra/newview/llface.h
index 82e4ab61b7..c9037ce1eb 100644..100755
--- a/indra/newview/llface.h
+++ b/indra/newview/llface.h
@@ -41,7 +41,6 @@
#include "llvertexbuffer.h"
#include "llviewertexture.h"
#include "lldrawable.h"
-#include "lltextureatlasmanager.h"
class LLFacePool;
class LLVolume;
@@ -50,7 +49,6 @@ class LLTextureEntry;
class LLVertexProgram;
class LLViewerTexture;
class LLGeometryManager;
-class LLTextureAtlasSlot;
const F32 MIN_ALPHA_SIZE = 1024.f;
const F32 MIN_TEX_ANIM_SIZE = 512.f;
@@ -59,6 +57,17 @@ class LLFace
{
public:
+ void* operator new(size_t size)
+ {
+ return ll_aligned_malloc_16(size);
+ }
+
+ void operator delete(void* ptr)
+ {
+ ll_aligned_free_16(ptr);
+ }
+
+
LLFace(const LLFace& rhs)
{
*this = rhs;
@@ -79,10 +88,13 @@ public:
USE_FACE_COLOR = 0x0010,
TEXTURE_ANIM = 0x0020,
RIGGED = 0x0040,
+ PARTICLE = 0x0080,
};
static void initClass();
+ static void cacheFaceInVRAM(const LLVolumeFace& vf);
+
public:
LLFace(LLDrawable* drawablep, LLViewerObject* objp) { init(drawablep, objp); }
~LLFace() { destroy(); }
@@ -96,13 +108,17 @@ public:
U16 getGeomStart() const { return mGeomIndex; } // index into draw pool
void setTextureIndex(U8 index);
U8 getTextureIndex() const { return mTextureIndex; }
+ void setTexture(U32 ch, LLViewerTexture* tex);
void setTexture(LLViewerTexture* tex) ;
- void switchTexture(LLViewerTexture* new_texture);
+ void setDiffuseMap(LLViewerTexture* tex);
+ void setNormalMap(LLViewerTexture* tex);
+ void setSpecularMap(LLViewerTexture* tex);
+ void switchTexture(U32 ch, LLViewerTexture* new_texture);
void dirtyTexture();
LLXformMatrix* getXform() const { return mXform; }
BOOL hasGeometry() const { return mGeomCount > 0; }
LLVector3 getPositionAgent() const;
- LLVector2 surfaceToTexture(LLVector2 surface_coord, LLVector3 position, LLVector3 normal);
+ LLVector2 surfaceToTexture(LLVector2 surface_coord, const LLVector4a& position, const LLVector4a& normal);
void getPlanarProjectedParams(LLQuaternion* face_rot, LLVector3* face_pos, F32* scale) const;
bool calcAlignedPlanarTE(const LLFace* align_to, LLVector2* st_offset,
LLVector2* st_scale, F32* st_rot) const;
@@ -116,8 +132,8 @@ public:
F32 getVirtualSize() const { return mVSize; }
F32 getPixelArea() const { return mPixelArea; }
- S32 getIndexInTex() const {return mIndexInTex ;}
- void setIndexInTex(S32 index) { mIndexInTex = index ;}
+ S32 getIndexInTex(U32 ch) const {llassert(ch < LLRender::NUM_TEXTURE_CHANNELS); return mIndexInTex[ch];}
+ void setIndexInTex(U32 ch, S32 index) { llassert(ch < LLRender::NUM_TEXTURE_CHANNELS); mIndexInTex[ch] = index ;}
void renderSetColor() const;
S32 renderElements(const U16 *index_array) const;
@@ -135,7 +151,7 @@ public:
S32 getLOD() const { return mVObjp.notNull() ? mVObjp->getLOD() : 0; }
void setPoolType(U32 type) { mPoolType = type; }
S32 getTEOffset() { return mTEOffset; }
- LLViewerTexture* getTexture() const;
+ LLViewerTexture* getTexture(U32 ch = LLRender::DIFFUSE_MAP) const;
void setViewerObject(LLViewerObject* object);
void setPool(LLFacePool *pool, LLViewerTexture *texturep);
@@ -179,7 +195,7 @@ public:
void setSize(S32 numVertices, S32 num_indices = 0, bool align = false);
BOOL genVolumeBBoxes(const LLVolume &volume, S32 f,
- const LLMatrix4& mat, const LLMatrix3& inv_trans_mat, BOOL global_volume = FALSE);
+ const LLMatrix4& mat_vert_in, BOOL global_volume = FALSE);
void init(LLDrawable* drawablep, LLViewerObject* objp);
void destroy();
@@ -204,25 +220,16 @@ public:
F32 getTextureVirtualSize() ;
F32 getImportanceToCamera()const {return mImportanceToCamera ;}
+ void resetVirtualSize();
void setHasMedia(bool has_media) { mHasMedia = has_media ;}
BOOL hasMedia() const ;
- //for atlas
- LLTextureAtlasSlot* getAtlasInfo() ;
- void setAtlasInUse(BOOL flag);
- void setAtlasInfo(LLTextureAtlasSlot* atlasp);
- BOOL isAtlasInUse()const;
- BOOL canUseAtlas() const;
- const LLVector2* getTexCoordScale() const ;
- const LLVector2* getTexCoordOffset()const;
- const LLTextureAtlas* getAtlas()const ;
- void removeAtlas() ;
BOOL switchTexture() ;
//vertex buffer tracking
void setVertexBuffer(LLVertexBuffer* buffer);
- void clearVertexBuffer(); //sets mVertexBuffer and mLastVertexBuffer to NULL
+ void clearVertexBuffer(); //sets mVertexBuffer to NULL
LLVertexBuffer* getVertexBuffer() const { return mVertexBuffer; }
U32 getRiggedVertexBufferDataMask() const;
S32 getRiggedIndex(U32 type) const;
@@ -251,12 +258,13 @@ public:
F32 mLastSkinTime;
F32 mLastMoveTime;
LLMatrix4* mTextureMatrix;
+ LLMatrix4* mSpecMapMatrix;
+ LLMatrix4* mNormalMapMatrix;
LLDrawInfo* mDrawInfo;
private:
LLPointer<LLVertexBuffer> mVertexBuffer;
- LLPointer<LLVertexBuffer> mLastVertexBuffer;
-
+
U32 mState;
LLFacePool* mDrawPoolp;
U32 mPoolType;
@@ -267,16 +275,12 @@ private:
U8 mTextureIndex; // index of texture channel to use for pseudo-atlasing
U32 mIndicesCount;
U32 mIndicesIndex; // index into draw pool for indices (yeah, I know!)
- S32 mIndexInTex ;
-
- //previous rebuild's geometry info
- U16 mLastGeomCount;
- U16 mLastGeomIndex;
- U32 mLastIndicesCount;
- U32 mLastIndicesIndex;
+ S32 mIndexInTex[LLRender::NUM_TEXTURE_CHANNELS];
LLXformMatrix* mXform;
- LLPointer<LLViewerTexture> mTexture;
+
+ LLPointer<LLViewerTexture> mTexture[LLRender::NUM_TEXTURE_CHANNELS];
+
LLPointer<LLDrawable> mDrawablep;
LLPointer<LLViewerObject> mVObjp;
S32 mTEOffset;
@@ -294,9 +298,6 @@ private:
F32 mBoundingSphereRadius ;
bool mHasMedia ;
- //atlas
- LLPointer<LLTextureAtlasSlot> mAtlasInfop ;
- BOOL mUsingAtlas ;
protected:
static BOOL sSafeRenderSelect;
diff --git a/indra/newview/llface.inl b/indra/newview/llface.inl
index 85c35a88f3..85c35a88f3 100644..100755
--- a/indra/newview/llface.inl
+++ b/indra/newview/llface.inl
diff --git a/indra/newview/llfacebookconnect.cpp b/indra/newview/llfacebookconnect.cpp
new file mode 100644
index 0000000000..9a20ce8f1b
--- /dev/null
+++ b/indra/newview/llfacebookconnect.cpp
@@ -0,0 +1,582 @@
+/**
+ * @file llfacebookconnect.h
+ * @author Merov, Cho, Gil
+ * @brief Connection to Facebook Service
+ *
+ * $LicenseInfo:firstyear=2013&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2013, 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 "llfacebookconnect.h"
+
+#include "llagent.h"
+#include "llcallingcard.h" // for LLAvatarTracker
+#include "llcommandhandler.h"
+#include "llhttpclient.h"
+#include "llnotificationsutil.h"
+#include "llurlaction.h"
+#include "llimagepng.h"
+#include "llimagejpeg.h"
+#include "lltrans.h"
+#include "llevents.h"
+#include "llviewerregion.h"
+
+#include "llfloaterwebcontent.h"
+#include "llfloaterreg.h"
+
+boost::scoped_ptr<LLEventPump> LLFacebookConnect::sStateWatcher(new LLEventStream("FacebookConnectState"));
+boost::scoped_ptr<LLEventPump> LLFacebookConnect::sInfoWatcher(new LLEventStream("FacebookConnectInfo"));
+boost::scoped_ptr<LLEventPump> LLFacebookConnect::sContentWatcher(new LLEventStream("FacebookConnectContent"));
+
+// Local functions
+void log_facebook_connect_error(const std::string& request, U32 status, const std::string& reason, const std::string& code, const std::string& description)
+{
+ // Note: 302 (redirect) is *not* an error that warrants logging
+ if (status != 302)
+ {
+ LL_WARNS("FacebookConnect") << request << " request failed with a " << status << " " << reason << ". Reason: " << code << " (" << description << ")" << LL_ENDL;
+ }
+}
+
+void toast_user_for_success()
+{
+ LLSD args;
+ args["MESSAGE"] = LLTrans::getString("facebook_post_success");
+ LLNotificationsUtil::add("FacebookConnect", args);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+class LLFacebookConnectHandler : public LLCommandHandler
+{
+public:
+ LLFacebookConnectHandler() : LLCommandHandler("fbc", UNTRUSTED_THROTTLE) { }
+
+ bool handle(const LLSD& tokens, const LLSD& query_map, LLMediaCtrl* web)
+ {
+ if (tokens.size() > 0)
+ {
+ if (tokens[0].asString() == "connect")
+ {
+ // this command probably came from the fbc_web browser, so close it
+ LLFloater* fbc_web = LLFloaterReg::getInstance("fbc_web");
+ if (fbc_web)
+ {
+ fbc_web->closeFloater();
+ }
+
+ // connect to facebook
+ if (query_map.has("code"))
+ {
+ LLFacebookConnect::instance().connectToFacebook(query_map["code"], query_map.get("state"));
+ }
+ return true;
+ }
+ }
+ return false;
+ }
+};
+LLFacebookConnectHandler gFacebookConnectHandler;
+
+///////////////////////////////////////////////////////////////////////////////
+//
+class LLFacebookConnectResponder : public LLHTTPClient::Responder
+{
+ LOG_CLASS(LLFacebookConnectResponder);
+public:
+
+ LLFacebookConnectResponder()
+ {
+ LLFacebookConnect::instance().setConnectionState(LLFacebookConnect::FB_CONNECTION_IN_PROGRESS);
+ }
+
+ virtual void completed(U32 status, const std::string& reason, const LLSD& content)
+ {
+ if (isGoodStatus(status))
+ {
+ LL_DEBUGS("FacebookConnect") << "Connect successful. content: " << content << LL_ENDL;
+
+ LLFacebookConnect::instance().setConnectionState(LLFacebookConnect::FB_CONNECTED);
+ }
+ else if (status != 302)
+ {
+ LLFacebookConnect::instance().setConnectionState(LLFacebookConnect::FB_CONNECTION_FAILED);
+ log_facebook_connect_error("Connect", status, reason, content.get("error_code"), content.get("error_description"));
+ }
+ }
+
+ void completedHeader(U32 status, const std::string& reason, const LLSD& content)
+ {
+ if (status == 302)
+ {
+ LLFacebookConnect::instance().openFacebookWeb(content["location"]);
+ }
+ }
+};
+
+///////////////////////////////////////////////////////////////////////////////
+//
+class LLFacebookShareResponder : public LLHTTPClient::Responder
+{
+ LOG_CLASS(LLFacebookShareResponder);
+public:
+
+ LLFacebookShareResponder()
+ {
+ LLFacebookConnect::instance().setConnectionState(LLFacebookConnect::FB_POSTING);
+ }
+
+ virtual void completed(U32 status, const std::string& reason, const LLSD& content)
+ {
+ if (isGoodStatus(status))
+ {
+ toast_user_for_success();
+ LL_DEBUGS("FacebookConnect") << "Post successful. content: " << content << LL_ENDL;
+
+ LLFacebookConnect::instance().setConnectionState(LLFacebookConnect::FB_POSTED);
+ }
+ else if (status == 404)
+ {
+ LLFacebookConnect::instance().connectToFacebook();
+ }
+ else
+ {
+ LLFacebookConnect::instance().setConnectionState(LLFacebookConnect::FB_POST_FAILED);
+ log_facebook_connect_error("Share", status, reason, content.get("error_code"), content.get("error_description"));
+ }
+ }
+
+ void completedHeader(U32 status, const std::string& reason, const LLSD& content)
+ {
+ if (status == 302)
+ {
+ LLFacebookConnect::instance().openFacebookWeb(content["location"]);
+ }
+ }
+};
+
+///////////////////////////////////////////////////////////////////////////////
+//
+class LLFacebookDisconnectResponder : public LLHTTPClient::Responder
+{
+ LOG_CLASS(LLFacebookDisconnectResponder);
+public:
+
+ LLFacebookDisconnectResponder()
+ {
+ LLFacebookConnect::instance().setConnectionState(LLFacebookConnect::FB_DISCONNECTING);
+ }
+
+ void setUserDisconnected()
+ {
+ // Clear data
+ LLFacebookConnect::instance().clearInfo();
+ LLFacebookConnect::instance().clearContent();
+ //Notify state change
+ LLFacebookConnect::instance().setConnectionState(LLFacebookConnect::FB_NOT_CONNECTED);
+ }
+
+ virtual void completed(U32 status, const std::string& reason, const LLSD& content)
+ {
+ if (isGoodStatus(status))
+ {
+ LL_DEBUGS("FacebookConnect") << "Disconnect successful. content: " << content << LL_ENDL;
+ setUserDisconnected();
+
+ }
+ //User not found so already disconnected
+ else if(status == 404)
+ {
+ LL_DEBUGS("FacebookConnect") << "Already disconnected. content: " << content << LL_ENDL;
+ setUserDisconnected();
+ }
+ else
+ {
+ LLFacebookConnect::instance().setConnectionState(LLFacebookConnect::FB_DISCONNECT_FAILED);
+ log_facebook_connect_error("Disconnect", status, reason, content.get("error_code"), content.get("error_description"));
+ }
+ }
+};
+
+///////////////////////////////////////////////////////////////////////////////
+//
+class LLFacebookConnectedResponder : public LLHTTPClient::Responder
+{
+ LOG_CLASS(LLFacebookConnectedResponder);
+public:
+
+ LLFacebookConnectedResponder(bool auto_connect) : mAutoConnect(auto_connect)
+ {
+ LLFacebookConnect::instance().setConnectionState(LLFacebookConnect::FB_CONNECTION_IN_PROGRESS);
+ }
+
+ virtual void completed(U32 status, const std::string& reason, const LLSD& content)
+ {
+ if (isGoodStatus(status))
+ {
+ LL_DEBUGS("FacebookConnect") << "Connect successful. content: " << content << LL_ENDL;
+
+ LLFacebookConnect::instance().setConnectionState(LLFacebookConnect::FB_CONNECTED);
+ }
+ else
+ {
+ // show the facebook login page if not connected yet
+ if (status == 404)
+ {
+ if (mAutoConnect)
+ {
+ LLFacebookConnect::instance().connectToFacebook();
+ }
+ else
+ {
+ LLFacebookConnect::instance().setConnectionState(LLFacebookConnect::FB_NOT_CONNECTED);
+ }
+ }
+ else
+ {
+ LLFacebookConnect::instance().setConnectionState(LLFacebookConnect::FB_CONNECTION_FAILED);
+ log_facebook_connect_error("Connected", status, reason, content.get("error_code"), content.get("error_description"));
+ }
+ }
+ }
+
+private:
+ bool mAutoConnect;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+//
+class LLFacebookInfoResponder : public LLHTTPClient::Responder
+{
+ LOG_CLASS(LLFacebookInfoResponder);
+public:
+
+ virtual void completed(U32 status, const std::string& reason, const LLSD& info)
+ {
+ if (isGoodStatus(status))
+ {
+ llinfos << "Facebook: Info received" << llendl;
+ LL_DEBUGS("FacebookConnect") << "Getting Facebook info successful. info: " << info << LL_ENDL;
+ LLFacebookConnect::instance().storeInfo(info);
+ }
+ else
+ {
+ log_facebook_connect_error("Info", status, reason, info.get("error_code"), info.get("error_description"));
+ }
+ }
+
+ void completedHeader(U32 status, const std::string& reason, const LLSD& content)
+ {
+ if (status == 302)
+ {
+ LLFacebookConnect::instance().openFacebookWeb(content["location"]);
+ }
+ }
+};
+
+///////////////////////////////////////////////////////////////////////////////
+//
+class LLFacebookFriendsResponder : public LLHTTPClient::Responder
+{
+ LOG_CLASS(LLFacebookFriendsResponder);
+public:
+
+ virtual void completed(U32 status, const std::string& reason, const LLSD& content)
+ {
+ if (isGoodStatus(status))
+ {
+ LL_DEBUGS("FacebookConnect") << "Getting Facebook friends successful. content: " << content << LL_ENDL;
+ LLFacebookConnect::instance().storeContent(content);
+ }
+ else
+ {
+ log_facebook_connect_error("Friends", status, reason, content.get("error_code"), content.get("error_description"));
+ }
+ }
+
+ void completedHeader(U32 status, const std::string& reason, const LLSD& content)
+ {
+ if (status == 302)
+ {
+ LLFacebookConnect::instance().openFacebookWeb(content["location"]);
+ }
+ }
+};
+
+///////////////////////////////////////////////////////////////////////////////
+//
+LLFacebookConnect::LLFacebookConnect()
+: mConnectionState(FB_NOT_CONNECTED),
+ mConnected(false),
+ mInfo(),
+ mContent(),
+ mRefreshInfo(false),
+ mRefreshContent(false),
+ mReadFromMaster(false)
+{
+}
+
+void LLFacebookConnect::openFacebookWeb(std::string url)
+{
+ // Open the URL in an internal browser window without navigation UI
+ LLFloaterWebContent::Params p;
+ p.url(url).show_chrome(true);
+ p.url(url).allow_address_entry(false);
+ p.url(url).allow_back_forward_navigation(false);
+ p.url(url).trusted_content(true);
+ LLFloater *floater = LLFloaterReg::showInstance("fbc_web", p);
+ //the internal web browser has a bug that prevents it from gaining focus unless a mouse event occurs first (it seems).
+ //So when showing the internal web browser, set focus to it's containing floater "fbc_web". When a mouse event
+ //occurs on the "webbrowser" panel part of the floater, a mouse cursor will properly show and the "webbrowser" will gain focus.
+ //fbc_web floater contains the "webbrowser" panel. JIRA: ACME-744
+ gFocusMgr.setKeyboardFocus( floater );
+
+ //LLUrlAction::openURLExternal(url);
+}
+
+std::string LLFacebookConnect::getFacebookConnectURL(const std::string& route, bool include_read_from_master)
+{
+ std::string url("");
+ LLViewerRegion *regionp = gAgent.getRegion();
+ if (regionp)
+ {
+ url = regionp->getCapability("FacebookConnect");
+ url += route;
+
+ if (include_read_from_master && mReadFromMaster)
+ {
+ url += "?read_from_master=true";
+ }
+ }
+ return url;
+}
+
+void LLFacebookConnect::connectToFacebook(const std::string& auth_code, const std::string& auth_state)
+{
+ LLSD body;
+ if (!auth_code.empty())
+ body["code"] = auth_code;
+ if (!auth_state.empty())
+ body["state"] = auth_state;
+
+ LLHTTPClient::put(getFacebookConnectURL("/connection"), body, new LLFacebookConnectResponder());
+}
+
+void LLFacebookConnect::disconnectFromFacebook()
+{
+ LLHTTPClient::del(getFacebookConnectURL("/connection"), new LLFacebookDisconnectResponder());
+}
+
+void LLFacebookConnect::checkConnectionToFacebook(bool auto_connect)
+{
+ const bool follow_redirects = false;
+ const F32 timeout = HTTP_REQUEST_EXPIRY_SECS;
+ LLHTTPClient::get(getFacebookConnectURL("/connection", true), new LLFacebookConnectedResponder(auto_connect),
+ LLSD(), timeout, follow_redirects);
+}
+
+void LLFacebookConnect::loadFacebookInfo()
+{
+ if(mRefreshInfo)
+ {
+ const bool follow_redirects = false;
+ const F32 timeout = HTTP_REQUEST_EXPIRY_SECS;
+ LLHTTPClient::get(getFacebookConnectURL("/info", true), new LLFacebookInfoResponder(),
+ LLSD(), timeout, follow_redirects);
+ }
+}
+
+void LLFacebookConnect::loadFacebookFriends()
+{
+ if(mRefreshContent)
+ {
+ const bool follow_redirects = false;
+ const F32 timeout = HTTP_REQUEST_EXPIRY_SECS;
+ LLHTTPClient::get(getFacebookConnectURL("/friends", true), new LLFacebookFriendsResponder(),
+ LLSD(), timeout, follow_redirects);
+ }
+}
+
+void LLFacebookConnect::postCheckin(const std::string& location, const std::string& name, const std::string& description, const std::string& image, const std::string& message)
+{
+ LLSD body;
+ if (!location.empty())
+ body["location"] = location;
+ if (!name.empty())
+ body["name"] = name;
+ if (!description.empty())
+ body["description"] = description;
+ if (!image.empty())
+ body["image"] = image;
+ if (!message.empty())
+ body["message"] = message;
+
+ // Note: we can use that route for different publish action. We should be able to use the same responder.
+ LLHTTPClient::post(getFacebookConnectURL("/share/checkin", true), body, new LLFacebookShareResponder());
+}
+
+void LLFacebookConnect::sharePhoto(const std::string& image_url, const std::string& caption)
+{
+ LLSD body;
+ body["image"] = image_url;
+ body["caption"] = caption;
+
+ // Note: we can use that route for different publish action. We should be able to use the same responder.
+ LLHTTPClient::post(getFacebookConnectURL("/share/photo", true), body, new LLFacebookShareResponder());
+}
+
+void LLFacebookConnect::sharePhoto(LLPointer<LLImageFormatted> image, const std::string& caption)
+{
+ std::string imageFormat;
+ if (dynamic_cast<LLImagePNG*>(image.get()))
+ {
+ imageFormat = "png";
+ }
+ else if (dynamic_cast<LLImageJPEG*>(image.get()))
+ {
+ imageFormat = "jpg";
+ }
+ else
+ {
+ llwarns << "Image to upload is not a PNG or JPEG" << llendl;
+ return;
+ }
+
+ // All this code is mostly copied from LLWebProfile::post()
+ const std::string boundary = "----------------------------0123abcdefab";
+
+ LLSD headers;
+ headers["Content-Type"] = "multipart/form-data; boundary=" + boundary;
+
+ std::ostringstream body;
+
+ // *NOTE: The order seems to matter.
+ body << "--" << boundary << "\r\n"
+ << "Content-Disposition: form-data; name=\"caption\"\r\n\r\n"
+ << caption << "\r\n";
+
+ body << "--" << boundary << "\r\n"
+ << "Content-Disposition: form-data; name=\"image\"; filename=\"snapshot." << imageFormat << "\"\r\n"
+ << "Content-Type: image/" << imageFormat << "\r\n\r\n";
+
+ // Insert the image data.
+ // *FIX: Treating this as a string will probably screw it up ...
+ U8* image_data = image->getData();
+ for (S32 i = 0; i < image->getDataSize(); ++i)
+ {
+ body << image_data[i];
+ }
+
+ body << "\r\n--" << boundary << "--\r\n";
+
+ // postRaw() takes ownership of the buffer and releases it later.
+ size_t size = body.str().size();
+ U8 *data = new U8[size];
+ memcpy(data, body.str().data(), size);
+
+ // Note: we can use that route for different publish action. We should be able to use the same responder.
+ LLHTTPClient::postRaw(getFacebookConnectURL("/share/photo", true), data, size, new LLFacebookShareResponder(), headers);
+}
+
+void LLFacebookConnect::updateStatus(const std::string& message)
+{
+ LLSD body;
+ body["message"] = message;
+
+ // Note: we can use that route for different publish action. We should be able to use the same responder.
+ LLHTTPClient::post(getFacebookConnectURL("/share/wall", true), body, new LLFacebookShareResponder());
+}
+
+void LLFacebookConnect::storeInfo(const LLSD& info)
+{
+ mInfo = info;
+ mRefreshInfo = false;
+
+ sInfoWatcher->post(info);
+}
+
+const LLSD& LLFacebookConnect::getInfo() const
+{
+ return mInfo;
+}
+
+void LLFacebookConnect::clearInfo()
+{
+ mInfo = LLSD();
+}
+
+void LLFacebookConnect::storeContent(const LLSD& content)
+{
+ mContent = content;
+ mRefreshContent = false;
+
+ sContentWatcher->post(content);
+}
+
+const LLSD& LLFacebookConnect::getContent() const
+{
+ return mContent;
+}
+
+void LLFacebookConnect::clearContent()
+{
+ mContent = LLSD();
+}
+
+void LLFacebookConnect::setDataDirty()
+{
+ mRefreshInfo = true;
+ mRefreshContent = true;
+}
+
+void LLFacebookConnect::setConnectionState(LLFacebookConnect::EConnectionState connection_state)
+{
+ if(connection_state == FB_CONNECTED)
+ {
+ mReadFromMaster = true;
+ setConnected(true);
+ setDataDirty();
+ }
+ else if(connection_state == FB_NOT_CONNECTED)
+ {
+ setConnected(false);
+ }
+ else if(connection_state == FB_POSTED)
+ {
+ mReadFromMaster = false;
+ }
+
+ if (mConnectionState != connection_state)
+ {
+ LLSD state_info;
+ state_info["enum"] = connection_state;
+ sStateWatcher->post(state_info);
+ }
+
+ mConnectionState = connection_state;
+}
+
+void LLFacebookConnect::setConnected(bool connected)
+{
+ mConnected = connected;
+}
diff --git a/indra/newview/llfacebookconnect.h b/indra/newview/llfacebookconnect.h
new file mode 100644
index 0000000000..a77ac24167
--- /dev/null
+++ b/indra/newview/llfacebookconnect.h
@@ -0,0 +1,106 @@
+/**
+ * @file llfacebookconnect.h
+ * @author Merov, Cho, Gil
+ * @brief Connection to Facebook Service
+ *
+ * $LicenseInfo:firstyear=2013&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2013, 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_LLFACEBOOKCONNECT_H
+#define LL_LLFACEBOOKCONNECT_H
+
+#include "llsingleton.h"
+#include "llimage.h"
+
+class LLEventPump;
+
+/**
+ * @class LLFacebookConnect
+ *
+ * Manages authentication to, and interaction with, a web service allowing the
+ * the viewer to get Facebook OpenGraph data.
+ */
+class LLFacebookConnect : public LLSingleton<LLFacebookConnect>
+{
+ LOG_CLASS(LLFacebookConnect);
+public:
+ enum EConnectionState
+ {
+ FB_NOT_CONNECTED = 0,
+ FB_CONNECTION_IN_PROGRESS = 1,
+ FB_CONNECTED = 2,
+ FB_CONNECTION_FAILED = 3,
+ FB_POSTING = 4,
+ FB_POSTED = 5,
+ FB_POST_FAILED = 6,
+ FB_DISCONNECTING = 7,
+ FB_DISCONNECT_FAILED = 8
+ };
+
+ void connectToFacebook(const std::string& auth_code = "", const std::string& auth_state = ""); // Initiate the complete FB connection. Please use checkConnectionToFacebook() in normal use.
+ void disconnectFromFacebook(); // Disconnect from the FBC service.
+ void checkConnectionToFacebook(bool auto_connect = false); // Check if an access token is available on the FBC service. If not, call connectToFacebook().
+
+ void loadFacebookInfo();
+ void loadFacebookFriends();
+ void postCheckin(const std::string& location, const std::string& name, const std::string& description, const std::string& picture, const std::string& message);
+ void sharePhoto(const std::string& image_url, const std::string& caption);
+ void sharePhoto(LLPointer<LLImageFormatted> image, const std::string& caption);
+ void updateStatus(const std::string& message);
+
+ void storeInfo(const LLSD& info);
+ const LLSD& getInfo() const;
+ void clearInfo();
+ void storeContent(const LLSD& content);
+ const LLSD& getContent() const;
+ void clearContent();
+ void setDataDirty();
+
+ void setConnectionState(EConnectionState connection_state);
+ void setConnected(bool connected);
+ bool isConnected() { return mConnected; }
+ bool isTransactionOngoing() { return ((mConnectionState == FB_CONNECTION_IN_PROGRESS) || (mConnectionState == FB_POSTING) || (mConnectionState == FB_DISCONNECTING)); }
+ EConnectionState getConnectionState() { return mConnectionState; }
+
+ void openFacebookWeb(std::string url);
+
+private:
+ friend class LLSingleton<LLFacebookConnect>;
+
+ LLFacebookConnect();
+ ~LLFacebookConnect() {};
+ std::string getFacebookConnectURL(const std::string& route = "", bool include_read_from_master = false);
+
+ EConnectionState mConnectionState;
+ BOOL mConnected;
+ LLSD mInfo;
+ LLSD mContent;
+ bool mRefreshInfo;
+ bool mRefreshContent;
+ bool mReadFromMaster;
+
+ static boost::scoped_ptr<LLEventPump> sStateWatcher;
+ static boost::scoped_ptr<LLEventPump> sInfoWatcher;
+ static boost::scoped_ptr<LLEventPump> sContentWatcher;
+};
+
+#endif // LL_LLFACEBOOKCONNECT_H
diff --git a/indra/newview/llfasttimerview.cpp b/indra/newview/llfasttimerview.cpp
index 9664aa7dbe..06119620de 100644..100755
--- a/indra/newview/llfasttimerview.cpp
+++ b/indra/newview/llfasttimerview.cpp
@@ -95,7 +95,6 @@ LLFastTimerView::LLFastTimerView(const LLSD& key)
mHoverBarIndex = -1;
FTV_NUM_TIMERS = LLFastTimer::NamedTimer::instanceCount();
mPrintStats = -1;
- mAverageCyclesPerTimer = 0;
}
void LLFastTimerView::onPause()
@@ -161,7 +160,7 @@ LLFastTimer::NamedTimer* LLFastTimerView::getLegendID(S32 y)
BOOL LLFastTimerView::handleDoubleClick(S32 x, S32 y, MASK mask)
{
- for(timer_tree_iterator_t it = begin_timer_tree(LLFastTimer::NamedTimer::getRootNamedTimer());
+ for(timer_tree_iterator_t it = begin_timer_tree(getFrameTimer());
it != end_timer_tree();
++it)
{
@@ -258,7 +257,7 @@ BOOL LLFastTimerView::handleHover(S32 x, S32 y, MASK mask)
}
S32 i = 0;
- for(timer_tree_iterator_t it = begin_timer_tree(LLFastTimer::NamedTimer::getRootNamedTimer());
+ for(timer_tree_iterator_t it = begin_timer_tree(getFrameTimer());
it != end_timer_tree();
++it, ++i)
{
@@ -346,7 +345,7 @@ BOOL LLFastTimerView::handleScrollWheel(S32 x, S32 y, S32 clicks)
return TRUE;
}
-static LLFastTimer::DeclareTimer FTM_RENDER_TIMER("Timers", true);
+static LLFastTimer::DeclareTimer FTM_RENDER_TIMER("Timers");
static std::map<LLFastTimer::NamedTimer*, LLColor4> sTimerColors;
@@ -369,7 +368,7 @@ void LLFastTimerView::draw()
S32 left, top, right, bottom;
S32 x, y, barw, barh, dx, dy;
- S32 texth, textw;
+ S32 texth;
LLPointer<LLUIImage> box_imagep = LLUI::getUIImage("Rounded_Square");
// Draw the window background
@@ -379,12 +378,6 @@ void LLFastTimerView::draw()
S32 xleft = margin;
S32 ytop = margin;
- mAverageCyclesPerTimer = LLFastTimer::sTimerCalls == 0
- ? 0
- : llround(lerp((F32)mAverageCyclesPerTimer, (F32)(LLFastTimer::sTimerCycles / (U64)LLFastTimer::sTimerCalls), 0.1f));
- LLFastTimer::sTimerCycles = 0;
- LLFastTimer::sTimerCalls = 0;
-
// Draw some help
{
@@ -392,10 +385,6 @@ void LLFastTimerView::draw()
y = height - ytop;
texth = (S32)LLFontGL::getFontMonospace()->getLineHeight();
-#if TIME_FAST_TIMERS
- tdesc = llformat("Cycles per timer call: %d", mAverageCyclesPerTimer);
- LLFontGL::getFontMonospace()->renderUTF8(tdesc, 0, x, y, LLColor4::white, LLFontGL::LEFT, LLFontGL::TOP);
-#else
char modedesc[][32] = {
"2 x Average ",
"Max ",
@@ -410,7 +399,6 @@ void LLFastTimerView::draw()
tdesc = llformat("Full bar = %s [Click to pause/reset] [SHIFT-Click to toggle]",modedesc[mDisplayMode]);
LLFontGL::getFontMonospace()->renderUTF8(tdesc, 0, x, y, LLColor4::white, LLFontGL::LEFT, LLFontGL::TOP);
- textw = LLFontGL::getFontMonospace()->getWidth(tdesc);
x = xleft, y -= (texth + 2);
tdesc = llformat("Justification = %s [CTRL-Click to toggle]",centerdesc[mDisplayCenter]);
@@ -419,7 +407,6 @@ void LLFastTimerView::draw()
LLFontGL::getFontMonospace()->renderUTF8(std::string("[Right-Click log selected] [ALT-Click toggle counts] [ALT-SHIFT-Click sub hidden]"),
0, x, y, LLColor4::white, LLFontGL::LEFT, LLFontGL::TOP);
-#endif
y -= (texth + 2);
}
@@ -431,11 +418,11 @@ void LLFastTimerView::draw()
y -= (texth + 2);
- sTimerColors[&LLFastTimer::NamedTimer::getRootNamedTimer()] = LLColor4::grey;
+ sTimerColors[&getFrameTimer()] = LLColor4::grey;
F32 hue = 0.f;
- for (timer_tree_iterator_t it = begin_timer_tree(LLFastTimer::NamedTimer::getRootNamedTimer());
+ for (timer_tree_iterator_t it = begin_timer_tree(getFrameTimer());
it != timer_tree_iterator_t();
++it)
{
@@ -460,7 +447,7 @@ void LLFastTimerView::draw()
S32 cur_line = 0;
ft_display_idx.clear();
std::map<LLFastTimer::NamedTimer*, S32> display_line;
- for (timer_tree_iterator_t it = begin_timer_tree(LLFastTimer::NamedTimer::getRootNamedTimer());
+ for (timer_tree_iterator_t it = begin_timer_tree(getFrameTimer());
it != timer_tree_iterator_t();
++it)
{
@@ -526,6 +513,7 @@ void LLFastTimerView::draw()
while(!is_child_of_hover_item && next_parent)
{
is_child_of_hover_item = (mHoverID == next_parent);
+ if (next_parent->getParent() == next_parent) break;
next_parent = next_parent->getParent();
}
@@ -537,8 +525,6 @@ void LLFastTimerView::draw()
y -= (texth + 2);
- textw = dx + LLFontGL::getFontMonospace()->getWidth(idp->getName()) + 40;
-
if (idp->getCollapsed())
{
it.skipDescendants();
@@ -570,7 +556,7 @@ void LLFastTimerView::draw()
U64 totalticks;
if (!LLFastTimer::sPauseHistory)
{
- U64 ticks = LLFastTimer::NamedTimer::getRootNamedTimer().getHistoricalCount(mScrollIndex);
+ U64 ticks = getFrameTimer().getHistoricalCount(mScrollIndex);
if (LLFastTimer::getCurFrameIndex() >= 10)
{
@@ -610,7 +596,7 @@ void LLFastTimerView::draw()
totalticks = 0;
for (S32 j=0; j<histmax; j++)
{
- U64 ticks = LLFastTimer::NamedTimer::getRootNamedTimer().getHistoricalCount(j);
+ U64 ticks = getFrameTimer().getHistoricalCount(j);
if (ticks > totalticks)
totalticks = ticks;
@@ -716,7 +702,7 @@ void LLFastTimerView::draw()
LLFastTimer::NamedTimer* prev_id = NULL;
S32 i = 0;
- for(timer_tree_iterator_t it = begin_timer_tree(LLFastTimer::NamedTimer::getRootNamedTimer());
+ for(timer_tree_iterator_t it = begin_timer_tree(getFrameTimer());
it != end_timer_tree();
++it, ++i)
{
@@ -793,6 +779,7 @@ void LLFastTimerView::draw()
while(!is_child_of_hover_item && next_parent)
{
is_child_of_hover_item = (mHoverID == next_parent);
+ if (next_parent->getParent() == next_parent) break;
next_parent = next_parent->getParent();
}
@@ -879,7 +866,7 @@ void LLFastTimerView::draw()
}
U64 cur_max = 0;
- for(timer_tree_iterator_t it = begin_timer_tree(LLFastTimer::NamedTimer::getRootNamedTimer());
+ for(timer_tree_iterator_t it = begin_timer_tree(getFrameTimer());
it != end_timer_tree();
++it)
{
@@ -980,7 +967,7 @@ void LLFastTimerView::draw()
{
std::string legend_stat;
bool first = true;
- for(timer_tree_iterator_t it = begin_timer_tree(LLFastTimer::NamedTimer::getRootNamedTimer());
+ for(timer_tree_iterator_t it = begin_timer_tree(getFrameTimer());
it != end_timer_tree();
++it)
{
@@ -1002,7 +989,7 @@ void LLFastTimerView::draw()
std::string timer_stat;
first = true;
- for(timer_tree_iterator_t it = begin_timer_tree(LLFastTimer::NamedTimer::getRootNamedTimer());
+ for(timer_tree_iterator_t it = begin_timer_tree(getFrameTimer());
it != end_timer_tree();
++it)
{
@@ -1083,7 +1070,7 @@ void LLFastTimerView::exportCharts(const std::string& base, const std::string& t
{ //read base log into memory
S32 i = 0;
std::ifstream is(base.c_str());
- while (!is.eof() && LLSDSerialize::fromXML(cur, is))
+ while (!is.eof() && LLSDParser::PARSE_FAILURE != LLSDSerialize::fromXML(cur, is))
{
base_data[i++] = cur;
}
@@ -1096,7 +1083,7 @@ void LLFastTimerView::exportCharts(const std::string& base, const std::string& t
{ //read current log into memory
S32 i = 0;
std::ifstream is(target.c_str());
- while (!is.eof() && LLSDSerialize::fromXML(cur, is))
+ while (!is.eof() && LLSDParser::PARSE_FAILURE != LLSDSerialize::fromXML(cur, is))
{
cur_data[i++] = cur;
@@ -1387,7 +1374,7 @@ LLSD LLFastTimerView::analyzePerformanceLogDefault(std::istream& is)
stats_map_t time_stats;
stats_map_t sample_stats;
- while (!is.eof() && LLSDSerialize::fromXML(cur, is))
+ while (!is.eof() && LLSDParser::PARSE_FAILURE != LLSDSerialize::fromXML(cur, is))
{
for (LLSD::map_iterator iter = cur.beginMap(); iter != cur.endMap(); ++iter)
{
@@ -1558,8 +1545,14 @@ void LLFastTimerView::doAnalysis(std::string baseline, std::string target, std::
return ;
}
}
-void LLFastTimerView::onClickCloseBtn()
+void LLFastTimerView::onClickCloseBtn(bool)
{
setVisible(false);
}
+LLFastTimer::NamedTimer& LLFastTimerView::getFrameTimer()
+{
+ return FTM_FRAME.getNamedTimer();
+}
+
+
diff --git a/indra/newview/llfasttimerview.h b/indra/newview/llfasttimerview.h
index a349e7ad4c..1349b1e99c 100644..100755
--- a/indra/newview/llfasttimerview.h
+++ b/indra/newview/llfasttimerview.h
@@ -46,6 +46,7 @@ private:
static LLSD analyzePerformanceLogDefault(std::istream& is) ;
static void exportCharts(const std::string& base, const std::string& target);
void onPause();
+ LLFastTimer::NamedTimer& getFrameTimer();
public:
@@ -62,7 +63,7 @@ public:
F64 getTime(const std::string& name);
protected:
- virtual void onClickCloseBtn();
+ virtual void onClickCloseBtn(bool app_quitting = false);
private:
typedef std::vector<std::vector<S32> > bar_positions_t;
bar_positions_t mBarStart;
@@ -90,7 +91,6 @@ private:
S32 mHoverBarIndex;
LLFrameTimer mHighlightTimer;
S32 mPrintStats;
- S32 mAverageCyclesPerTimer;
LLRect mGraphRect;
};
diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp
index 575b613ccf..a2d0759587 100644..100755
--- a/indra/newview/llfavoritesbar.cpp
+++ b/indra/newview/llfavoritesbar.cpp
@@ -38,6 +38,7 @@
#include "lltooltip.h"
#include "llagent.h"
+#include "llavatarnamecache.h"
#include "llclipboard.h"
#include "llclipboard.h"
#include "llinventorybridge.h"
@@ -45,12 +46,14 @@
#include "llfloatersidepanelcontainer.h"
#include "llfloaterworldmap.h"
#include "lllandmarkactions.h"
+#include "lllogininstance.h"
#include "llnotificationsutil.h"
#include "lltoggleablemenu.h"
#include "llviewerinventory.h"
#include "llviewermenu.h"
#include "llviewermenu.h"
#include "lltooldraganddrop.h"
+#include "llsdserialize.h"
static LLDefaultChildRegistry::Register<LLFavoritesBarCtrl> r("favorites_bar");
@@ -317,7 +320,8 @@ public:
if (item)
{
- item->setSortField(mSortField);
+ LLFavoritesOrderStorage::instance().setSortIndex(item, mSortField);
+
item->setComplete(TRUE);
item->updateServer(FALSE);
@@ -339,8 +343,8 @@ struct LLFavoritesSort
// TODO - made it customizible using gSavedSettings
bool operator()(const LLViewerInventoryItem* const& a, const LLViewerInventoryItem* const& b)
{
- S32 sortField1 = a->getSortField();
- S32 sortField2 = b->getSortField();
+ S32 sortField1 = LLFavoritesOrderStorage::instance().getSortIndex(a->getUUID());
+ S32 sortField2 = LLFavoritesOrderStorage::instance().getSortIndex(b->getUUID());
if (!(sortField1 < 0 && sortField2 < 0))
{
@@ -396,6 +400,8 @@ LLFavoritesBarCtrl::LLFavoritesBarCtrl(const LLFavoritesBarCtrl::Params& p)
mMoreTextBox->setClickedCallback(boost::bind(&LLFavoritesBarCtrl::showDropDownMenu, this));
addChild(mMoreTextBox);
+ mDropDownItemsCount = 0;
+
LLTextBox::Params label_param(p.label);
mBarLabel = LLUICtrlFactory::create<LLTextBox> (label_param);
addChild(mBarLabel);
@@ -528,7 +534,7 @@ void LLFavoritesBarCtrl::handleExistingFavoriteDragAndDrop(S32 x, S32 y)
mItems.push_back(gInventory.getItem(mDragItemId));
}
- gInventory.saveItemsOrder(mItems);
+ LLFavoritesOrderStorage::instance().saveItemsOrder(mItems);
LLToggleableMenu* menu = (LLToggleableMenu*) mOverflowMenuHandle.get();
@@ -546,6 +552,10 @@ void LLFavoritesBarCtrl::handleNewFavoriteDragAndDrop(LLInventoryItem *item, con
bool insert_before = true;
if (!mItems.empty())
{
+ // [MAINT-2386] When multiple landmarks are selected and dragged onto an empty favorites bar,
+ // the viewer would crash when casting mLastTab below, as mLastTab is still null when the
+ // second landmark is being added.
+ // To ensure mLastTab is valid, we need to call updateButtons() at the end of this function
dest = dynamic_cast<LLFavoriteLandmarkButton*>(mLandingTab);
if (!dest)
{
@@ -587,7 +597,8 @@ void LLFavoritesBarCtrl::handleNewFavoriteDragAndDrop(LLInventoryItem *item, con
}
else
{
- currItem->setSortField(++sortField);
+ LLFavoritesOrderStorage::instance().setSortIndex(currItem, ++sortField);
+
currItem->setComplete(TRUE);
currItem->updateServer(FALSE);
@@ -616,6 +627,11 @@ void LLFavoritesBarCtrl::handleNewFavoriteDragAndDrop(LLInventoryItem *item, con
cb);
}
+ // [MAINT-2386] Ensure the favorite button has been created and is valid.
+ // This also ensures that mLastTab will be valid when dropping multiple
+ // landmarks to an empty favorites bar.
+ updateButtons();
+
llinfos << "Copied inventory item #" << item->getUUID() << " to favorites." << llendl;
}
@@ -640,7 +656,7 @@ void LLFavoritesBarCtrl::changed(U32 mask)
for (LLInventoryModel::item_array_t::iterator i = items.begin(); i != items.end(); ++i)
{
- (*i)->getSLURL();
+ LLFavoritesOrderStorage::instance().getSLURL((*i)->getAssetUUID());
}
updateButtons();
}
@@ -815,11 +831,13 @@ void LLFavoritesBarCtrl::updateButtons()
}
// Update overflow menu
LLToggleableMenu* overflow_menu = static_cast <LLToggleableMenu*> (mOverflowMenuHandle.get());
- if (overflow_menu && overflow_menu->getVisible())
+ if (overflow_menu && overflow_menu->getVisible() && (overflow_menu->getItemCount() != mDropDownItemsCount))
{
overflow_menu->setVisible(FALSE);
if (mUpdateDropDownItems)
+ {
showDropDownMenu();
+ }
}
}
else
@@ -909,7 +927,7 @@ BOOL LLFavoritesBarCtrl::collectFavoriteItems(LLInventoryModel::item_array_t &it
S32 sortField = 0;
for (LLInventoryModel::item_array_t::iterator i = items.begin(); i != items.end(); ++i)
{
- (*i)->setSortField(++sortField);
+ LLFavoritesOrderStorage::instance().setSortIndex((*i), ++sortField);
}
}
@@ -935,6 +953,7 @@ void LLFavoritesBarCtrl::showDropDownMenu()
menu->updateParent(LLMenuGL::sMenuContainer);
menu->setButtonRect(mMoreTextBox->getRect(), this);
positionAndShowMenu(menu);
+ mDropDownItemsCount = menu->getItemCount();
}
}
@@ -1191,7 +1210,7 @@ void LLFavoritesBarCtrl::doToSelected(const LLSD& userdata)
}
else if (action == "paste")
{
- pastFromClipboard();
+ pasteFromClipboard();
}
else if (action == "delete")
{
@@ -1239,7 +1258,7 @@ BOOL LLFavoritesBarCtrl::isClipboardPasteable() const
return TRUE;
}
-void LLFavoritesBarCtrl::pastFromClipboard() const
+void LLFavoritesBarCtrl::pasteFromClipboard() const
{
LLInventoryModel* model = &gInventory;
if(model && isClipboardPasteable())
@@ -1355,7 +1374,7 @@ BOOL LLFavoritesBarCtrl::needToSaveItemsOrder(const LLInventoryModel::item_array
// if there is an item without sort order field set, we need to save items order
for (LLInventoryModel::item_array_t::const_iterator i = items.begin(); i != items.end(); ++i)
{
- if ((*i)->getSortField() < 0)
+ if (LLFavoritesOrderStorage::instance().getSortIndex((*i)->getUUID()) < 0)
{
result = TRUE;
break;
@@ -1390,4 +1409,294 @@ void LLFavoritesBarCtrl::insertItem(LLInventoryModel::item_array_t& items, const
}
}
+const std::string LLFavoritesOrderStorage::SORTING_DATA_FILE_NAME = "landmarks_sorting.xml";
+const S32 LLFavoritesOrderStorage::NO_INDEX = -1;
+
+void LLFavoritesOrderStorage::setSortIndex(const LLViewerInventoryItem* inv_item, S32 sort_index)
+{
+ mSortIndexes[inv_item->getUUID()] = sort_index;
+ mIsDirty = true;
+ getSLURL(inv_item->getAssetUUID());
+}
+
+S32 LLFavoritesOrderStorage::getSortIndex(const LLUUID& inv_item_id)
+{
+ sort_index_map_t::const_iterator it = mSortIndexes.find(inv_item_id);
+ if (it != mSortIndexes.end())
+ {
+ return it->second;
+ }
+ return NO_INDEX;
+}
+
+void LLFavoritesOrderStorage::removeSortIndex(const LLUUID& inv_item_id)
+{
+ mSortIndexes.erase(inv_item_id);
+ mIsDirty = true;
+}
+
+void LLFavoritesOrderStorage::getSLURL(const LLUUID& asset_id)
+{
+ slurls_map_t::iterator slurl_iter = mSLURLs.find(asset_id);
+ if (slurl_iter != mSLURLs.end()) return; // SLURL for current landmark is already cached
+
+ LLLandmark* lm = gLandmarkList.getAsset(asset_id,
+ boost::bind(&LLFavoritesOrderStorage::onLandmarkLoaded, this, asset_id, _1));
+ if (lm)
+ {
+ onLandmarkLoaded(asset_id, lm);
+ }
+}
+
+// static
+void LLFavoritesOrderStorage::destroyClass()
+{
+ LLFavoritesOrderStorage::instance().cleanup();
+ if (gSavedPerAccountSettings.getBOOL("ShowFavoritesOnLogin"))
+ {
+ LLFavoritesOrderStorage::instance().saveFavoritesSLURLs();
+ }
+ else
+ {
+ LLFavoritesOrderStorage::instance().removeFavoritesRecordOfUser();
+ }
+}
+
+void LLFavoritesOrderStorage::load()
+{
+ // load per-resident sorting information
+ std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, SORTING_DATA_FILE_NAME);
+
+ LLSD settings_llsd;
+ llifstream file;
+ file.open(filename);
+ if (file.is_open())
+ {
+ LLSDSerialize::fromXML(settings_llsd, file);
+ }
+
+ for (LLSD::map_const_iterator iter = settings_llsd.beginMap();
+ iter != settings_llsd.endMap(); ++iter)
+ {
+ mSortIndexes.insert(std::make_pair(LLUUID(iter->first), (S32)iter->second.asInteger()));
+ }
+}
+
+void LLFavoritesOrderStorage::saveFavoritesSLURLs()
+{
+ // Do not change the file if we are not logged in yet.
+ if (!LLLoginInstance::getInstance()->authSuccess())
+ {
+ llwarns << "Cannot save favorites: not logged in" << llendl;
+ return;
+ }
+
+ std::string user_dir = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "");
+ if (user_dir.empty())
+ {
+ llwarns << "Cannot save favorites: empty user dir name" << llendl;
+ return;
+ }
+
+ std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "stored_favorites.xml");
+ llifstream in_file;
+ in_file.open(filename);
+ LLSD fav_llsd;
+ if (in_file.is_open())
+ {
+ LLSDSerialize::fromXML(fav_llsd, in_file);
+ }
+
+ const LLUUID fav_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
+ LLInventoryModel::cat_array_t cats;
+ LLInventoryModel::item_array_t items;
+ gInventory.collectDescendents(fav_id, cats, items, LLInventoryModel::EXCLUDE_TRASH);
+
+ LLSD user_llsd;
+ for (LLInventoryModel::item_array_t::iterator it = items.begin(); it != items.end(); it++)
+ {
+ LLSD value;
+ value["name"] = (*it)->getName();
+ value["asset_id"] = (*it)->getAssetUUID();
+
+ slurls_map_t::iterator slurl_iter = mSLURLs.find(value["asset_id"]);
+ if (slurl_iter != mSLURLs.end())
+ {
+ lldebugs << "Saving favorite: idx=" << LLFavoritesOrderStorage::instance().getSortIndex((*it)->getUUID()) << ", SLURL=" << slurl_iter->second << ", value=" << value << llendl;
+ value["slurl"] = slurl_iter->second;
+ user_llsd[LLFavoritesOrderStorage::instance().getSortIndex((*it)->getUUID())] = value;
+ }
+ else
+ {
+ llwarns << "Not saving favorite " << value["name"] << ": no matching SLURL" << llendl;
+ }
+ }
+
+ LLAvatarName av_name;
+ LLAvatarNameCache::get( gAgentID, &av_name );
+ // Note : use the "John Doe" and not the "john.doe" version of the name
+ // as we'll compare it with the stored credentials in the login panel.
+ lldebugs << "Saved favorites for " << av_name.getUserName() << llendl;
+ fav_llsd[av_name.getUserName()] = user_llsd;
+
+ llofstream file;
+ file.open(filename);
+ LLSDSerialize::toPrettyXML(fav_llsd, file);
+}
+
+void LLFavoritesOrderStorage::removeFavoritesRecordOfUser()
+{
+ std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "stored_favorites.xml");
+ LLSD fav_llsd;
+ llifstream file;
+ file.open(filename);
+ if (!file.is_open()) return;
+ LLSDSerialize::fromXML(fav_llsd, file);
+
+ LLAvatarName av_name;
+ LLAvatarNameCache::get( gAgentID, &av_name );
+ // Note : use the "John Doe" and not the "john.doe" version of the name.
+ // See saveFavoritesSLURLs() here above for the reason why.
+ lldebugs << "Removed favorites for " << av_name.getUserName() << llendl;
+ if (fav_llsd.has(av_name.getUserName()))
+ {
+ fav_llsd.erase(av_name.getUserName());
+ }
+
+ llofstream out_file;
+ out_file.open(filename);
+ LLSDSerialize::toPrettyXML(fav_llsd, out_file);
+
+}
+
+void LLFavoritesOrderStorage::onLandmarkLoaded(const LLUUID& asset_id, LLLandmark* landmark)
+{
+ if (!landmark) return;
+
+ LLVector3d pos_global;
+ if (!landmark->getGlobalPos(pos_global))
+ {
+ // If global position was unknown on first getGlobalPos() call
+ // it should be set for the subsequent calls.
+ landmark->getGlobalPos(pos_global);
+ }
+
+ if (!pos_global.isExactlyZero())
+ {
+ LLLandmarkActions::getSLURLfromPosGlobal(pos_global,
+ boost::bind(&LLFavoritesOrderStorage::storeFavoriteSLURL, this, asset_id, _1));
+ }
+}
+
+void LLFavoritesOrderStorage::storeFavoriteSLURL(const LLUUID& asset_id, std::string& slurl)
+{
+ lldebugs << "Saving landmark SLURL: " << slurl << llendl;
+ mSLURLs[asset_id] = slurl;
+}
+
+void LLFavoritesOrderStorage::save()
+{
+ // nothing to save if clean
+ if (!mIsDirty) return;
+
+ // If we quit from the login screen we will not have an SL account
+ // name. Don't try to save, otherwise we'll dump a file in
+ // C:\Program Files\SecondLife\ or similar. JC
+ std::string user_dir = gDirUtilp->getLindenUserDir();
+ if (!user_dir.empty())
+ {
+ std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, SORTING_DATA_FILE_NAME);
+ LLSD settings_llsd;
+
+ for(sort_index_map_t::const_iterator iter = mSortIndexes.begin(); iter != mSortIndexes.end(); ++iter)
+ {
+ settings_llsd[iter->first.asString()] = iter->second;
+ }
+
+ llofstream file;
+ file.open(filename);
+ LLSDSerialize::toPrettyXML(settings_llsd, file);
+ }
+}
+
+void LLFavoritesOrderStorage::cleanup()
+{
+ // nothing to clean
+ if (!mIsDirty) return;
+
+ const LLUUID fav_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
+ LLInventoryModel::cat_array_t cats;
+ LLInventoryModel::item_array_t items;
+ gInventory.collectDescendents(fav_id, cats, items, LLInventoryModel::EXCLUDE_TRASH);
+
+ IsNotInFavorites is_not_in_fav(items);
+
+ sort_index_map_t aTempMap;
+ //copy unremoved values from mSortIndexes to aTempMap
+ std::remove_copy_if(mSortIndexes.begin(), mSortIndexes.end(),
+ inserter(aTempMap, aTempMap.begin()),
+ is_not_in_fav);
+
+ //Swap the contents of mSortIndexes and aTempMap
+ mSortIndexes.swap(aTempMap);
+}
+
+void LLFavoritesOrderStorage::saveItemsOrder( const LLInventoryModel::item_array_t& items )
+{
+ int sortField = 0;
+
+ // current order is saved by setting incremental values (1, 2, 3, ...) for the sort field
+ for (LLInventoryModel::item_array_t::const_iterator i = items.begin(); i != items.end(); ++i)
+ {
+ LLViewerInventoryItem* item = *i;
+
+ setSortIndex(item, ++sortField);
+
+ item->setComplete(TRUE);
+ item->updateServer(FALSE);
+
+ gInventory.updateItem(item);
+
+ // Tell the parent folder to refresh its sort order.
+ gInventory.addChangedMask(LLInventoryObserver::SORT, item->getParentUUID());
+ }
+
+ gInventory.notifyObservers();
+}
+// See also LLInventorySort where landmarks in the Favorites folder are sorted.
+class LLViewerInventoryItemSort
+{
+public:
+ bool operator()(const LLPointer<LLViewerInventoryItem>& a, const LLPointer<LLViewerInventoryItem>& b)
+ {
+ return LLFavoritesOrderStorage::instance().getSortIndex(a->getUUID())
+ < LLFavoritesOrderStorage::instance().getSortIndex(b->getUUID());
+ }
+};
+
+// * @param source_item_id - LLUUID of the source item to be moved into new position
+// * @param target_item_id - LLUUID of the target item before which source item should be placed.
+void LLFavoritesOrderStorage::rearrangeFavoriteLandmarks(const LLUUID& source_item_id, const LLUUID& target_item_id)
+{
+ LLInventoryModel::cat_array_t cats;
+ LLInventoryModel::item_array_t items;
+ LLIsType is_type(LLAssetType::AT_LANDMARK);
+ LLUUID favorites_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
+ gInventory.collectDescendentsIf(favorites_id, cats, items, LLInventoryModel::EXCLUDE_TRASH, is_type);
+
+ // ensure items are sorted properly before changing order. EXT-3498
+ std::sort(items.begin(), items.end(), LLViewerInventoryItemSort());
+
+ // update order
+ gInventory.updateItemsOrder(items, source_item_id, target_item_id);
+
+ saveItemsOrder(items);
+}
+
+void AddFavoriteLandmarkCallback::fire(const LLUUID& inv_item_id)
+{
+ if (mTargetLandmarkId.isNull()) return;
+
+ LLFavoritesOrderStorage::instance().rearrangeFavoriteLandmarks(inv_item_id, mTargetLandmarkId);
+}
// EOF
diff --git a/indra/newview/llfavoritesbar.h b/indra/newview/llfavoritesbar.h
index 2f75b3bb0e..211d3c4ce3 100644..100755
--- a/indra/newview/llfavoritesbar.h
+++ b/indra/newview/llfavoritesbar.h
@@ -33,6 +33,7 @@
#include "llinventoryobserver.h"
#include "llinventorymodel.h"
+#include "llviewerinventory.h"
class LLMenuItemCallGL;
class LLToggleableMenu;
@@ -90,7 +91,7 @@ protected:
bool enableSelected(const LLSD& userdata);
void doToSelected(const LLSD& userdata);
BOOL isClipboardPasteable() const;
- void pastFromClipboard() const;
+ void pasteFromClipboard() const;
void showDropDownMenu();
@@ -100,6 +101,7 @@ protected:
LLUUID mFavoriteFolderId;
const LLFontGL *mFont;
S32 mFirstDropDownItem;
+ S32 mDropDownItemsCount;
bool mUpdateDropDownItems;
bool mRestoreOverflowMenu;
@@ -160,6 +162,115 @@ private:
boost::signals2::connection mEndDragConnection;
};
+/*
+class AddFavoriteLandmarkCallback : public LLInventoryCallback
+{
+public:
+ AddFavoriteLandmarkCallback() : mTargetLandmarkId(LLUUID::null) {}
+ void setTargetLandmarkId(const LLUUID& target_uuid) { mTargetLandmarkId = target_uuid; }
+
+private:
+ void fire(const LLUUID& inv_item);
+
+ LLUUID mTargetLandmarkId;
+};
+*/
+/**
+ * Class to store sorting order of favorites landmarks in a local file. EXT-3985.
+ * It replaced previously implemented solution to store sort index in landmark's name as a "<N>@" prefix.
+ * Data are stored in user home directory.
+ */
+class LLFavoritesOrderStorage : public LLSingleton<LLFavoritesOrderStorage>
+ , public LLDestroyClass<LLFavoritesOrderStorage>
+{
+ LOG_CLASS(LLFavoritesOrderStorage);
+public:
+ /**
+ * Sets sort index for specified with LLUUID favorite landmark
+ */
+ void setSortIndex(const LLViewerInventoryItem* inv_item, S32 sort_index);
+
+ /**
+ * Gets sort index for specified with LLUUID favorite landmark
+ */
+ S32 getSortIndex(const LLUUID& inv_item_id);
+ void removeSortIndex(const LLUUID& inv_item_id);
+
+ void getSLURL(const LLUUID& asset_id);
+
+ // Saves current order of the passed items using inventory item sort field.
+ // Resets 'items' sort fields and saves them on server.
+ // Is used to save order for Favorites folder.
+ void saveItemsOrder(const LLInventoryModel::item_array_t& items);
+
+ void rearrangeFavoriteLandmarks(const LLUUID& source_item_id, const LLUUID& target_item_id);
+
+ /**
+ * Implementation of LLDestroyClass. Calls cleanup() instance method.
+ *
+ * It is important this callback is called before gInventory is cleaned.
+ * For now it is called from LLAppViewer::cleanup() -> LLAppViewer::disconnectViewer(),
+ * Inventory is cleaned later from LLAppViewer::cleanup() after LLAppViewer::disconnectViewer() is called.
+ * @see cleanup()
+ */
+ static void destroyClass();
+
+ const static S32 NO_INDEX;
+private:
+ friend class LLSingleton<LLFavoritesOrderStorage>;
+ LLFavoritesOrderStorage() : mIsDirty(false) { load(); }
+ ~LLFavoritesOrderStorage() { save(); }
+
+ /**
+ * Removes sort indexes for items which are not in Favorites bar for now.
+ */
+ void cleanup();
+
+ const static std::string SORTING_DATA_FILE_NAME;
+
+ void load();
+ void save();
+ void saveFavoritesSLURLs();
+ // Remove record of current user's favorites from file on disk.
+ void removeFavoritesRecordOfUser();
+
+ void onLandmarkLoaded(const LLUUID& asset_id, class LLLandmark* landmark);
+ void storeFavoriteSLURL(const LLUUID& asset_id, std::string& slurl);
+
+ typedef std::map<LLUUID, S32> sort_index_map_t;
+ sort_index_map_t mSortIndexes;
+
+ typedef std::map<LLUUID, std::string> slurls_map_t;
+ slurls_map_t mSLURLs;
+
+ bool mIsDirty;
+
+ struct IsNotInFavorites
+ {
+ IsNotInFavorites(const LLInventoryModel::item_array_t& items)
+ : mFavoriteItems(items)
+ {
+
+ }
+
+ /**
+ * Returns true if specified item is not found among inventory items
+ */
+ bool operator()(const sort_index_map_t::value_type& id_index_pair) const
+ {
+ LLPointer<LLViewerInventoryItem> item = gInventory.getItem(id_index_pair.first);
+ if (item.isNull()) return true;
+
+ LLInventoryModel::item_array_t::const_iterator found_it =
+ std::find(mFavoriteItems.begin(), mFavoriteItems.end(), item);
+
+ return found_it == mFavoriteItems.end();
+ }
+ private:
+ LLInventoryModel::item_array_t mFavoriteItems;
+ };
+
+};
#endif // LL_LLFAVORITESBARCTRL_H
diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp
index 08f9d26705..c47618e1ec 100644..100755
--- a/indra/newview/llfeaturemanager.cpp
+++ b/indra/newview/llfeaturemanager.cpp
@@ -30,6 +30,7 @@
#include <fstream>
#include <boost/regex.hpp>
+#include <boost/assign/list_of.hpp>
#include "llfeaturemanager.h"
#include "lldir.h"
@@ -52,11 +53,14 @@
#include "llboost.h"
#include "llweb.h"
#include "llviewershadermgr.h"
+#include "llstring.h"
+#include "stringize.h"
#if LL_WINDOWS
#include "lldxhardware.h"
#endif
+#define LL_EXPORT_GPU_TABLE 0
#if LL_DARWIN
const char FEATURE_TABLE_FILENAME[] = "featuretable_mac.txt";
@@ -186,6 +190,55 @@ void LLFeatureList::dump()
LL_DEBUGS("RenderInit") << LL_ENDL;
}
+static const std::vector<std::string> sGraphicsLevelNames = boost::assign::list_of
+ ("Low")
+ ("LowMid")
+ ("Mid")
+ ("MidHigh")
+ ("High")
+ ("HighUltra")
+ ("Ultra")
+;
+
+U32 LLFeatureManager::getMaxGraphicsLevel() const
+{
+ return sGraphicsLevelNames.size() - 1;
+}
+
+bool LLFeatureManager::isValidGraphicsLevel(U32 level) const
+{
+ return (level <= getMaxGraphicsLevel());
+}
+
+std::string LLFeatureManager::getNameForGraphicsLevel(U32 level) const
+{
+ if (isValidGraphicsLevel(level))
+ {
+ return sGraphicsLevelNames[level];
+ }
+ return STRINGIZE("Invalid graphics level " << level << ", valid are 0 .. "
+ << getMaxGraphicsLevel());
+}
+
+S32 LLFeatureManager::getGraphicsLevelForName(const std::string& name) const
+{
+ const std::string FixedFunction("FixedFunction");
+ std::string rname(name);
+ if (LLStringUtil::endsWith(rname, FixedFunction))
+ {
+ // chop off any "FixedFunction" suffix
+ rname = rname.substr(0, rname.length() - FixedFunction.length());
+ }
+ for (S32 i(0), iend(getMaxGraphicsLevel()); i <= iend; ++i)
+ {
+ if (sGraphicsLevelNames[i] == rname)
+ {
+ return i;
+ }
+ }
+ return -1;
+}
+
LLFeatureList *LLFeatureManager::findMask(const std::string& name)
{
if (mMaskList.count(name))
@@ -208,7 +261,7 @@ BOOL LLFeatureManager::maskFeatures(const std::string& name)
return maskList(*maskp);
}
-BOOL LLFeatureManager::loadFeatureTables()
+bool LLFeatureManager::loadFeatureTables()
{
// *TODO - if I or anyone else adds something else to the skipped list
// make this data driven. Put it in the feature table and parse it
@@ -249,28 +302,36 @@ BOOL LLFeatureManager::loadFeatureTables()
// use HTTP table if it exists
std::string path;
+ bool parse_ok = false;
if (gDirUtilp->fileExists(http_path))
{
- path = http_path;
+ parse_ok = parseFeatureTable(http_path);
+ if (!parse_ok)
+ {
+ // the HTTP table failed to parse, so delete it
+ LLFile::remove(http_path);
+ LL_WARNS("RenderInit") << "Removed invalid feature table '" << http_path << "'" << LL_ENDL;
+ }
}
- else
+
+ if (!parse_ok)
{
- path = app_path;
+ parse_ok = parseFeatureTable(app_path);
}
-
- return parseFeatureTable(path);
+ return parse_ok;
}
-BOOL LLFeatureManager::parseFeatureTable(std::string filename)
+bool LLFeatureManager::parseFeatureTable(std::string filename)
{
- llinfos << "Looking for feature table in " << filename << llendl;
+ LL_INFOS("RenderInit") << "Attempting to parse feature table from " << filename << LL_ENDL;
llifstream file;
std::string name;
U32 version;
+ cleanupFeatureTables(); // in case an earlier attempt left partial results
file.open(filename); /*Flawfinder: ignore*/
if (!file)
@@ -285,13 +346,14 @@ BOOL LLFeatureManager::parseFeatureTable(std::string filename)
if (name != "version")
{
LL_WARNS("RenderInit") << filename << " does not appear to be a valid feature table!" << LL_ENDL;
- return FALSE;
+ return false;
}
mTableVersion = version;
-
+
LLFeatureList *flp = NULL;
- while (file >> name)
+ bool parse_ok = true;
+ while (file >> name && parse_ok)
{
char buffer[MAX_STRING]; /*Flawfinder: ignore*/
@@ -304,39 +366,58 @@ BOOL LLFeatureManager::parseFeatureTable(std::string filename)
if (name == "list")
{
+ LL_DEBUGS("RenderInit") << "Before new list" << std::endl;
if (flp)
{
- //flp->dump();
+ flp->dump();
+ }
+ else
+ {
+ LL_CONT << "No current list";
}
+ LL_CONT << LL_ENDL;
+
// It's a new mask, create it.
file >> name;
- if (mMaskList.count(name))
+ if (!mMaskList.count(name))
{
- LL_ERRS("RenderInit") << "Overriding mask " << name << ", this is invalid!" << LL_ENDL;
+ flp = new LLFeatureList(name);
+ mMaskList[name] = flp;
+ }
+ else
+ {
+ LL_WARNS("RenderInit") << "Overriding mask " << name << ", this is invalid!" << LL_ENDL;
+ parse_ok = false;
}
-
- flp = new LLFeatureList(name);
- mMaskList[name] = flp;
}
else
{
- if (!flp)
+ if (flp)
{
- LL_ERRS("RenderInit") << "Specified parameter before <list> keyword!" << LL_ENDL;
- return FALSE;
+ S32 available;
+ F32 recommended;
+ file >> available >> recommended;
+ flp->addFeature(name, available, recommended);
+ }
+ else
+ {
+ LL_WARNS("RenderInit") << "Specified parameter before <list> keyword!" << LL_ENDL;
+ parse_ok = false;
}
- S32 available;
- F32 recommended;
- file >> available >> recommended;
- flp->addFeature(name, available, recommended);
}
}
file.close();
- return TRUE;
+ if (!parse_ok)
+ {
+ LL_WARNS("RenderInit") << "Discarding feature table data from " << filename << LL_ENDL;
+ cleanupFeatureTables();
+ }
+
+ return parse_ok;
}
-void LLFeatureManager::loadGPUClass()
+bool LLFeatureManager::loadGPUClass()
{
// defaults
mGPUClass = GPU_CLASS_UNKNOWN;
@@ -354,29 +435,49 @@ void LLFeatureManager::loadGPUClass()
// use HTTP table if it exists
std::string path;
+ bool parse_ok = false;
if (gDirUtilp->fileExists(http_path))
{
- path = http_path;
+ parse_ok = parseGPUTable(http_path);
+ if (!parse_ok)
+ {
+ // the HTTP table failed to parse, so delete it
+ LLFile::remove(http_path);
+ LL_WARNS("RenderInit") << "Removed invalid gpu table '" << http_path << "'" << LL_ENDL;
+ }
}
- else
+
+ if (!parse_ok)
{
- path = app_path;
+ parse_ok = parseGPUTable(app_path);
}
- parseGPUTable(path);
+ return parse_ok; // indicates that the file parsed correctly, not that the gpu was recognized
}
-void LLFeatureManager::parseGPUTable(std::string filename)
+bool LLFeatureManager::parseGPUTable(std::string filename)
{
llifstream file;
-
+
+ LL_INFOS("RenderInit") << "Attempting to parse GPU table from " << filename << LL_ENDL;
file.open(filename);
- if (!file)
+ if (file)
+ {
+ const char recognizer[] = "//GPU_TABLE";
+ char first_line[MAX_STRING];
+ file.getline(first_line, MAX_STRING);
+ if (0 != strncmp(first_line, recognizer, strlen(recognizer)))
+ {
+ LL_WARNS("RenderInit") << "Invalid GPU table: " << filename << "!" << LL_ENDL;
+ return false;
+ }
+ }
+ else
{
LL_WARNS("RenderInit") << "Unable to open GPU table: " << filename << "!" << LL_ENDL;
- return;
+ return false;
}
std::string rawRenderer = gGLManager.getRawGLString();
@@ -386,6 +487,13 @@ void LLFeatureManager::parseGPUTable(std::string filename)
*i = tolower(*i);
}
+#if LL_EXPORT_GPU_TABLE
+ llofstream json;
+ json.open("gpu_table.json");
+
+ json << "var gpu_table = [" << std::endl;
+#endif
+
bool gpuFound;
U32 lineNumber;
for (gpuFound = false, lineNumber = 0; !gpuFound && !file.eof(); lineNumber++)
@@ -411,7 +519,7 @@ void LLFeatureManager::parseGPUTable(std::string filename)
// setup the tokenizer
std::string buf(buffer);
- std::string cls, label, expr, supported;
+ std::string cls, label, expr, supported, stats_based, expected_gl_version;
boost_tokenizer tokens(buf, boost::char_separator<char>("\t\n"));
boost_tokenizer::iterator token_iter = tokens.begin();
@@ -432,13 +540,29 @@ void LLFeatureManager::parseGPUTable(std::string filename)
{
supported = *token_iter++;
}
+ if (token_iter != tokens.end())
+ {
+ stats_based = *token_iter++;
+ }
+ if (token_iter != tokens.end())
+ {
+ expected_gl_version = *token_iter++;
+ }
if (label.empty() || expr.empty() || cls.empty() || supported.empty())
{
LL_WARNS("RenderInit") << "invald gpu_table.txt:" << lineNumber << ": '" << buffer << "'" << LL_ENDL;
continue;
}
-
+#if LL_EXPORT_GPU_TABLE
+ json << "{'label' : '" << label << "',\n" <<
+ "'regexp' : '" << expr << "',\n" <<
+ "'class' : '" << cls << "',\n" <<
+ "'supported' : '" << supported << "',\n" <<
+ "'stats_based' : " << stats_based << ",\n" <<
+ "'gl_version' : " << expected_gl_version << "\n},\n";
+#endif
+
for (U32 i = 0; i < expr.length(); i++) /*Flawfinder: ignore*/
{
expr[i] = tolower(expr[i]);
@@ -449,12 +573,19 @@ void LLFeatureManager::parseGPUTable(std::string filename)
if(boost::regex_search(renderer, re))
{
// if we found it, stop!
+#if !LL_EXPORT_GPU_TABLE
gpuFound = true;
+#endif
mGPUString = label;
mGPUClass = (EGPUClass) strtol(cls.c_str(), NULL, 10);
mGPUSupported = (BOOL) strtol(supported.c_str(), NULL, 10);
+ sscanf(expected_gl_version.c_str(), "%f", &mExpectedGLVersion);
}
}
+#if LL_EXPORT_GPU_TABLE
+ json << "];\n\n";
+ json.close();
+#endif
file.close();
if ( gpuFound )
@@ -469,6 +600,11 @@ void LLFeatureManager::parseGPUTable(std::string filename)
{
LL_WARNS("RenderInit") << "GPU '" << rawRenderer << "' not recognized" << LL_ENDL;
}
+
+#if LL_DARWIN // never go over "Mid" settings by default on OS X
+ mGPUClass = llmin(mGPUClass, GPU_CLASS_2);
+#endif
+ return true;
}
// responder saves table into file
@@ -585,7 +721,7 @@ void LLFeatureManager::applyRecommendedSettings()
{
// apply saved settings
// cap the level at 2 (high)
- S32 level = llmax(GPU_CLASS_0, llmin(mGPUClass, GPU_CLASS_2));
+ U32 level = llmax(GPU_CLASS_0, llmin(mGPUClass, GPU_CLASS_5));
llinfos << "Applying Recommended Features" << llendl;
@@ -661,35 +797,38 @@ void LLFeatureManager::applyFeatures(bool skipFeatures)
}
}
-void LLFeatureManager::setGraphicsLevel(S32 level, bool skipFeatures)
+void LLFeatureManager::setGraphicsLevel(U32 level, bool skipFeatures)
{
LLViewerShaderMgr::sSkipReload = true;
applyBaseMasks();
-
- switch (level)
- {
- case 0:
- maskFeatures("Low");
- break;
- case 1:
- maskFeatures("Mid");
- break;
- case 2:
- maskFeatures("High");
- break;
- case 3:
- maskFeatures("Ultra");
- break;
- default:
- maskFeatures("Low");
- break;
+
+ // if we're passed an invalid level, default to "Low"
+ std::string features(isValidGraphicsLevel(level)? getNameForGraphicsLevel(level) : "Low");
+ if (features == "Low")
+ {
+#if LL_DARWIN
+ // This Mac-specific change is to insure that we force 'Basic Shaders' for all Mac
+ // systems which support them instead of falling back to fixed-function unnecessarily
+ // MAINT-2157
+ if (gGLManager.mGLVersion < 2.1f)
+#else
+ // only use fixed function by default if GL version < 3.0 or this is an intel graphics chip
+ if (gGLManager.mGLVersion < 3.f || gGLManager.mIsIntel)
+#endif
+ {
+ // same as Low, but with "Basic Shaders" disabled
+ features = "LowFixedFunction";
+ }
}
+ maskFeatures(features);
+
applyFeatures(skipFeatures);
LLViewerShaderMgr::sSkipReload = false;
LLViewerShaderMgr::instance()->setShaders();
+ gPipeline.refreshCachedSettings();
}
void LLFeatureManager::applyBaseMasks()
@@ -707,14 +846,16 @@ void LLFeatureManager::applyBaseMasks()
mFeatures = maskp->getFeatures();
// mask class
- if (mGPUClass >= 0 && mGPUClass < 4)
+ if (mGPUClass >= 0 && mGPUClass < 6)
{
const char* class_table[] =
{
"Class0",
"Class1",
"Class2",
- "Class3"
+ "Class3",
+ "Class4",
+ "Class5",
};
LL_INFOS("RenderInit") << "Setting GPU Class to " << class_table[mGPUClass] << LL_ENDL;
@@ -779,6 +920,10 @@ void LLFeatureManager::applyBaseMasks()
{
maskFeatures("MapBufferRange");
}
+ if (gGLManager.mVRAM > 512)
+ {
+ maskFeatures("VRAMGT512");
+ }
// now mask by gpu string
// Replaces ' ' with '_' in mGPUString to deal with inability for parser to handle spaces
diff --git a/indra/newview/llfeaturemanager.h b/indra/newview/llfeaturemanager.h
index c9cb397fcc..95141b241d 100644..100755
--- a/indra/newview/llfeaturemanager.h
+++ b/indra/newview/llfeaturemanager.h
@@ -39,7 +39,9 @@ typedef enum EGPUClass
GPU_CLASS_0 = 0,
GPU_CLASS_1 = 1,
GPU_CLASS_2 = 2,
- GPU_CLASS_3 = 3
+ GPU_CLASS_3 = 3,
+ GPU_CLASS_4 = 4,
+ GPU_CLASS_5 = 5
} EGPUClass;
@@ -73,7 +75,7 @@ public:
void setFeatureAvailable(const std::string& name, const BOOL available);
void setRecommendedLevel(const std::string& name, const F32 level);
- BOOL loadFeatureList(LLFILE *fp);
+ bool loadFeatureList(LLFILE *fp);
BOOL maskList(LLFeatureList &mask);
@@ -101,7 +103,8 @@ public:
mTableVersion(0),
mSafe(FALSE),
mGPUClass(GPU_CLASS_UNKNOWN),
- mGPUSupported(FALSE)
+ mExpectedGLVersion(0.f),
+ mGPUSupported(FALSE)
{
}
~LLFeatureManager() {cleanupFeatureTables();}
@@ -111,11 +114,12 @@ public:
void maskCurrentList(const std::string& name); // Mask the current feature list with the named list
- BOOL loadFeatureTables();
+ bool loadFeatureTables();
EGPUClass getGPUClass() { return mGPUClass; }
std::string& getGPUString() { return mGPUString; }
BOOL isGPUSupported() { return mGPUSupported; }
+ F32 getExpectedGLVersion() { return mExpectedGLVersion; }
void cleanupFeatureTables();
@@ -130,8 +134,18 @@ public:
// skipFeatures forces skipping of mostly hardware settings
// that we don't want to change when we change graphics
// settings
- void setGraphicsLevel(S32 level, bool skipFeatures);
-
+ void setGraphicsLevel(U32 level, bool skipFeatures);
+
+ // What 'level' values are valid to pass to setGraphicsLevel()?
+ // 0 is the low end...
+ U32 getMaxGraphicsLevel() const;
+ bool isValidGraphicsLevel(U32 level) const;
+
+ // setGraphicsLevel() levels have names.
+ std::string getNameForGraphicsLevel(U32 level) const;
+ // returns -1 for unrecognized name (hence S32 rather than U32)
+ S32 getGraphicsLevelForName(const std::string& name) const;
+
void applyBaseMasks();
void applyRecommendedSettings();
@@ -143,9 +157,14 @@ public:
void fetchHTTPTables();
protected:
- void loadGPUClass();
- BOOL parseFeatureTable(std::string filename);
- void parseGPUTable(std::string filename);
+ bool loadGPUClass();
+
+ bool parseFeatureTable(std::string filename);
+ ///< @returns TRUE is file parsed correctly, FALSE if not
+
+ bool parseGPUTable(std::string filename);
+ ///< @returns true if file parsed correctly, false if not - does not reflect whether or not the gpu was recognized
+
void initBaseMask();
@@ -155,6 +174,7 @@ protected:
S32 mTableVersion;
BOOL mSafe; // Reinitialize everything to the "safe" mask
EGPUClass mGPUClass;
+ F32 mExpectedGLVersion; //expected GL version according to gpu table
std::string mGPUString;
BOOL mGPUSupported;
};
diff --git a/indra/newview/llfilepicker.cpp b/indra/newview/llfilepicker.cpp
index 8986a694f9..16eacc9392 100644..100755
--- a/indra/newview/llfilepicker.cpp
+++ b/indra/newview/llfilepicker.cpp
@@ -59,6 +59,12 @@ LLFilePicker LLFilePicker::sInstance;
#define RAW_FILTER L"RAW files (*.raw)\0*.raw\0"
#define MODEL_FILTER L"Model files (*.dae)\0*.dae\0"
#define SCRIPT_FILTER L"Script files (*.lsl)\0*.lsl\0"
+#define DICTIONARY_FILTER L"Dictionary files (*.dic; *.xcu)\0*.dic;*.xcu\0"
+#endif
+
+#ifdef LL_DARWIN
+#include "llfilepicker_mac.h"
+//#include <boost/algorithm/string/predicate.hpp>
#endif
//
@@ -93,14 +99,6 @@ LLFilePicker::LLFilePicker()
mFilesW[0] = '\0';
#endif
-#if LL_DARWIN
- memset(&mNavOptions, 0, sizeof(mNavOptions));
- OSStatus error = NavGetDefaultDialogCreationOptions(&mNavOptions);
- if (error == noErr)
- {
- mNavOptions.modality = kWindowModalityAppModal;
- }
-#endif
}
LLFilePicker::~LLFilePicker()
@@ -218,6 +216,10 @@ BOOL LLFilePicker::setupFilter(ELoadFilter filter)
mOFN.lpstrFilter = SCRIPT_FILTER \
L"\0";
break;
+ case FFLOAD_DICTIONARY:
+ mOFN.lpstrFilter = DICTIONARY_FILTER \
+ L"\0";
+ break;
default:
res = FALSE;
break;
@@ -420,6 +422,19 @@ BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename)
L"PNG Images (*.png)\0*.png\0" \
L"\0";
break;
+ case FFSAVE_TGAPNG:
+ if (filename.empty())
+ {
+ wcsncpy( mFilesW,L"untitled.png", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/
+ //PNG by default
+ }
+ mOFN.lpstrDefExt = L"png";
+ mOFN.lpstrFilter =
+ L"PNG Images (*.png)\0*.png\0" \
+ L"Targa Images (*.tga)\0*.tga\0" \
+ L"\0";
+ break;
+
case FFSAVE_JPEG:
if (filename.empty())
{
@@ -541,359 +556,200 @@ BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename)
#elif LL_DARWIN
-Boolean LLFilePicker::navOpenFilterProc(AEDesc *theItem, void *info, void *callBackUD, NavFilterModes filterMode)
+std::vector<std::string>* LLFilePicker::navOpenFilterProc(ELoadFilter filter) //(AEDesc *theItem, void *info, void *callBackUD, NavFilterModes filterMode)
{
- Boolean result = true;
- ELoadFilter filter = *((ELoadFilter*) callBackUD);
- OSStatus error = noErr;
-
- if (filterMode == kNavFilteringBrowserList && filter != FFLOAD_ALL && (theItem->descriptorType == typeFSRef || theItem->descriptorType == typeFSS))
- {
- // navInfo is only valid for typeFSRef and typeFSS
- NavFileOrFolderInfo *navInfo = (NavFileOrFolderInfo*) info;
- if (!navInfo->isFolder)
- {
- AEDesc desc;
- error = AECoerceDesc(theItem, typeFSRef, &desc);
- if (error == noErr)
- {
- FSRef fileRef;
- error = AEGetDescData(&desc, &fileRef, sizeof(fileRef));
- if (error == noErr)
- {
- LSItemInfoRecord fileInfo;
- error = LSCopyItemInfoForRef(&fileRef, kLSRequestExtension | kLSRequestTypeCreator, &fileInfo);
- if (error == noErr)
- {
- if (filter == FFLOAD_IMAGE)
- {
- if (fileInfo.filetype != 'JPEG' && fileInfo.filetype != 'JPG ' &&
- fileInfo.filetype != 'BMP ' && fileInfo.filetype != 'TGA ' &&
- fileInfo.filetype != 'BMPf' && fileInfo.filetype != 'TPIC' &&
- fileInfo.filetype != 'PNG ' &&
- (fileInfo.extension && (CFStringCompare(fileInfo.extension, CFSTR("jpeg"), kCFCompareCaseInsensitive) != kCFCompareEqualTo &&
- CFStringCompare(fileInfo.extension, CFSTR("jpg"), kCFCompareCaseInsensitive) != kCFCompareEqualTo &&
- CFStringCompare(fileInfo.extension, CFSTR("bmp"), kCFCompareCaseInsensitive) != kCFCompareEqualTo &&
- CFStringCompare(fileInfo.extension, CFSTR("tga"), kCFCompareCaseInsensitive) != kCFCompareEqualTo &&
- CFStringCompare(fileInfo.extension, CFSTR("png"), kCFCompareCaseInsensitive) != kCFCompareEqualTo))
- )
- {
- result = false;
- }
- }
- else if (filter == FFLOAD_WAV)
- {
- if (fileInfo.filetype != 'WAVE' && fileInfo.filetype != 'WAV ' &&
- (fileInfo.extension && (CFStringCompare(fileInfo.extension, CFSTR("wave"), kCFCompareCaseInsensitive) != kCFCompareEqualTo &&
- CFStringCompare(fileInfo.extension, CFSTR("wav"), kCFCompareCaseInsensitive) != kCFCompareEqualTo))
- )
- {
- result = false;
- }
- }
- else if (filter == FFLOAD_ANIM)
- {
- if (fileInfo.filetype != 'BVH ' &&
- fileInfo.filetype != 'ANIM' &&
- (fileInfo.extension && (CFStringCompare(fileInfo.extension, CFSTR("bvh"), kCFCompareCaseInsensitive) != kCFCompareEqualTo) &&
- fileInfo.extension && (CFStringCompare(fileInfo.extension, CFSTR("anim"), kCFCompareCaseInsensitive) != kCFCompareEqualTo))
- )
- {
- result = false;
- }
- }
- else if (filter == FFLOAD_COLLADA)
- {
- if (fileInfo.filetype != 'DAE ' &&
- (fileInfo.extension && (CFStringCompare(fileInfo.extension, CFSTR("dae"), kCFCompareCaseInsensitive) != kCFCompareEqualTo))
- )
- {
- result = false;
- }
- }
+ std::vector<std::string> *allowedv = new std::vector< std::string >;
+ switch(filter)
+ {
+ case FFLOAD_ALL:
+ allowedv->push_back("wav");
+ allowedv->push_back("bvh");
+ allowedv->push_back("anim");
+ allowedv->push_back("dae");
+ allowedv->push_back("raw");
+ allowedv->push_back("lsl");
+ allowedv->push_back("dic");
+ allowedv->push_back("xcu");
+ case FFLOAD_IMAGE:
+ allowedv->push_back("jpg");
+ allowedv->push_back("jpeg");
+ allowedv->push_back("bmp");
+ allowedv->push_back("tga");
+ allowedv->push_back("bmpf");
+ allowedv->push_back("tpic");
+ allowedv->push_back("png");
+ break;
+ case FFLOAD_WAV:
+ allowedv->push_back("wav");
+ break;
+ case FFLOAD_ANIM:
+ allowedv->push_back("bvh");
+ allowedv->push_back("anim");
+ break;
+ case FFLOAD_COLLADA:
+ allowedv->push_back("dae");
+ break;
#ifdef _CORY_TESTING
- else if (filter == FFLOAD_GEOMETRY)
- {
- if (fileInfo.filetype != 'SLG ' &&
- (fileInfo.extension && (CFStringCompare(fileInfo.extension, CFSTR("slg"), kCFCompareCaseInsensitive) != kCFCompareEqualTo))
- )
- {
- result = false;
- }
- }
+ case FFLOAD_GEOMETRY:
+ allowedv->push_back("slg");
+ break;
#endif
- else if (filter == FFLOAD_SLOBJECT)
- {
- llwarns << "*** navOpenFilterProc: FFLOAD_SLOBJECT NOT IMPLEMENTED ***" << llendl;
- }
- else if (filter == FFLOAD_RAW)
- {
- if (fileInfo.filetype != '\?\?\?\?' &&
- (fileInfo.extension && (CFStringCompare(fileInfo.extension, CFSTR("raw"), kCFCompareCaseInsensitive) != kCFCompareEqualTo))
- )
- {
- result = false;
- }
- }
- else if (filter == FFLOAD_SCRIPT)
- {
- if (fileInfo.filetype != 'LSL ' &&
- (fileInfo.extension && (CFStringCompare(fileInfo.extension, CFSTR("lsl"), kCFCompareCaseInsensitive) != kCFCompareEqualTo)) )
- {
- result = false;
- }
- }
-
- if (fileInfo.extension)
- {
- CFRelease(fileInfo.extension);
- }
- }
- }
- AEDisposeDesc(&desc);
- }
- }
- }
- return result;
+ case FFLOAD_RAW:
+ allowedv->push_back("raw");
+ break;
+ case FFLOAD_SCRIPT:
+ allowedv->push_back("lsl");
+ break;
+ case FFLOAD_DICTIONARY:
+ allowedv->push_back("dic");
+ allowedv->push_back("xcu");
+ break;
+ case FFLOAD_DIRECTORY:
+ break;
+ default:
+ llwarns << "Unsupported format." << llendl;
+ }
+
+ return allowedv;
}
-OSStatus LLFilePicker::doNavChooseDialog(ELoadFilter filter)
+bool LLFilePicker::doNavChooseDialog(ELoadFilter filter)
{
- OSStatus error = noErr;
- NavDialogRef navRef = NULL;
- NavReplyRecord navReply;
-
// if local file browsing is turned off, return without opening dialog
if ( check_local_file_access_enabled() == false )
{
- return FALSE;
+ return false;
}
-
- memset(&navReply, 0, sizeof(navReply));
-
- // NOTE: we are passing the address of a local variable here.
- // This is fine, because the object this call creates will exist for less than the lifetime of this function.
- // (It is destroyed by NavDialogDispose() below.)
- error = NavCreateChooseFileDialog(&mNavOptions, NULL, NULL, NULL, navOpenFilterProc, (void*)(&filter), &navRef);
-
+
gViewerWindow->getWindow()->beforeDialog();
-
- if (error == noErr)
- error = NavDialogRun(navRef);
+
+ std::vector<std::string> *allowed_types=navOpenFilterProc(filter);
+
+ std::vector<std::string> *filev = doLoadDialog(allowed_types,
+ mPickOptions);
gViewerWindow->getWindow()->afterDialog();
- if (error == noErr)
- error = NavDialogGetReply(navRef, &navReply);
-
- if (navRef)
- NavDialogDispose(navRef);
- if (error == noErr && navReply.validRecord)
- {
- SInt32 count = 0;
- SInt32 index;
-
- // AE indexes are 1 based...
- error = AECountItems(&navReply.selection, &count);
- for (index = 1; index <= count; index++)
- {
- FSRef fsRef;
- AEKeyword theAEKeyword;
- DescType typeCode;
- Size actualSize = 0;
- char path[MAX_PATH]; /*Flawfinder: ignore*/
-
- memset(&fsRef, 0, sizeof(fsRef));
- error = AEGetNthPtr(&navReply.selection, index, typeFSRef, &theAEKeyword, &typeCode, &fsRef, sizeof(fsRef), &actualSize);
-
- if (error == noErr)
- error = FSRefMakePath(&fsRef, (UInt8*) path, sizeof(path));
-
- if (error == noErr)
- mFiles.push_back(std::string(path));
- }
- }
+ if (filev && filev->size() > 0)
+ {
+ mFiles.insert(mFiles.end(), filev->begin(), filev->end());
+ return true;
+ }
- return error;
+ return false;
}
-OSStatus LLFilePicker::doNavSaveDialog(ESaveFilter filter, const std::string& filename)
+bool LLFilePicker::doNavSaveDialog(ESaveFilter filter, const std::string& filename)
{
- OSStatus error = noErr;
- NavDialogRef navRef = NULL;
- NavReplyRecord navReply;
-
- memset(&navReply, 0, sizeof(navReply));
// Setup the type, creator, and extension
- OSType type, creator;
- CFStringRef extension = NULL;
+ std::string extension, type, creator;
+
switch (filter)
{
case FFSAVE_WAV:
- type = 'WAVE';
- creator = 'TVOD';
- extension = CFSTR(".wav");
+ type = "WAVE";
+ creator = "TVOD";
+ extension = "wav";
break;
-
case FFSAVE_TGA:
- type = 'TPIC';
- creator = 'prvw';
- extension = CFSTR(".tga");
+ type = "TPIC";
+ creator = "prvw";
+ extension = "tga";
+ break;
+ case FFSAVE_TGAPNG:
+ type = "PNG";
+ creator = "prvw";
+ extension = "png";
break;
-
case FFSAVE_BMP:
- type = 'BMPf';
- creator = 'prvw';
- extension = CFSTR(".bmp");
+ type = "BMPf";
+ creator = "prvw";
+ extension = "bmp";
break;
case FFSAVE_JPEG:
- type = 'JPEG';
- creator = 'prvw';
- extension = CFSTR(".jpeg");
+ type = "JPEG";
+ creator = "prvw";
+ extension = "jpeg";
break;
case FFSAVE_PNG:
- type = 'PNG ';
- creator = 'prvw';
- extension = CFSTR(".png");
+ type = "PNG ";
+ creator = "prvw";
+ extension = "png";
break;
case FFSAVE_AVI:
- type = '\?\?\?\?';
- creator = '\?\?\?\?';
- extension = CFSTR(".mov");
+ type = "\?\?\?\?";
+ creator = "\?\?\?\?";
+ extension = "mov";
break;
case FFSAVE_ANIM:
- type = '\?\?\?\?';
- creator = '\?\?\?\?';
- extension = CFSTR(".xaf");
+ type = "\?\?\?\?";
+ creator = "\?\?\?\?";
+ extension = "xaf";
break;
#ifdef _CORY_TESTING
case FFSAVE_GEOMETRY:
- type = '\?\?\?\?';
- creator = '\?\?\?\?';
- extension = CFSTR(".slg");
+ type = "\?\?\?\?";
+ creator = "\?\?\?\?";
+ extension = "slg";
break;
#endif
case FFSAVE_RAW:
- type = '\?\?\?\?';
- creator = '\?\?\?\?';
- extension = CFSTR(".raw");
+ type = "\?\?\?\?";
+ creator = "\?\?\?\?";
+ extension = "raw";
break;
case FFSAVE_J2C:
- type = '\?\?\?\?';
- creator = 'prvw';
- extension = CFSTR(".j2c");
+ type = "\?\?\?\?";
+ creator = "prvw";
+ extension = "j2c";
break;
case FFSAVE_SCRIPT:
- type = 'LSL ';
- creator = '\?\?\?\?';
- extension = CFSTR(".lsl");
+ type = "LSL ";
+ creator = "\?\?\?\?";
+ extension = "lsl";
break;
case FFSAVE_ALL:
default:
- type = '\?\?\?\?';
- creator = '\?\?\?\?';
- extension = CFSTR("");
+ type = "\?\?\?\?";
+ creator = "\?\?\?\?";
+ extension = "";
break;
}
- // Create the dialog
- error = NavCreatePutFileDialog(&mNavOptions, type, creator, NULL, NULL, &navRef);
- if (error == noErr)
- {
- CFStringRef nameString = NULL;
- bool hasExtension = true;
-
- // Create a CFString of the initial file name
- if (!filename.empty())
- nameString = CFStringCreateWithCString(NULL, filename.c_str(), kCFStringEncodingUTF8);
- else
- nameString = CFSTR("Untitled");
-
- // Add the extension if one was not provided
- if (nameString && !CFStringHasSuffix(nameString, extension))
- {
- CFStringRef tempString = nameString;
- hasExtension = false;
- nameString = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@%@"), tempString, extension);
- CFRelease(tempString);
- }
-
- // Set the name in the dialog
- if (nameString)
- {
- error = NavDialogSetSaveFileName(navRef, nameString);
- CFRelease(nameString);
- }
- else
- {
- error = paramErr;
- }
- }
-
+ std::string namestring = filename;
+ if (namestring.empty()) namestring="Untitled";
+
+// if (! boost::algorithm::ends_with(namestring, extension) )
+// {
+// namestring = namestring + "." + extension;
+//
+// }
+
gViewerWindow->getWindow()->beforeDialog();
// Run the dialog
- if (error == noErr)
- error = NavDialogRun(navRef);
+ std::string* filev = doSaveDialog(&namestring,
+ &type,
+ &creator,
+ &extension,
+ mPickOptions);
gViewerWindow->getWindow()->afterDialog();
- if (error == noErr)
- error = NavDialogGetReply(navRef, &navReply);
-
- if (navRef)
- NavDialogDispose(navRef);
-
- if (error == noErr && navReply.validRecord)
+ if ( filev && !filev->empty() )
{
- SInt32 count = 0;
-
- // AE indexes are 1 based...
- error = AECountItems(&navReply.selection, &count);
- if (count > 0)
- {
- // Get the FSRef to the containing folder
- FSRef fsRef;
- AEKeyword theAEKeyword;
- DescType typeCode;
- Size actualSize = 0;
-
- memset(&fsRef, 0, sizeof(fsRef));
- error = AEGetNthPtr(&navReply.selection, 1, typeFSRef, &theAEKeyword, &typeCode, &fsRef, sizeof(fsRef), &actualSize);
-
- if (error == noErr)
- {
- char path[PATH_MAX]; /*Flawfinder: ignore*/
- char newFileName[SINGLE_FILENAME_BUFFER_SIZE]; /*Flawfinder: ignore*/
-
- error = FSRefMakePath(&fsRef, (UInt8*)path, PATH_MAX);
- if (error == noErr)
- {
- if (CFStringGetCString(navReply.saveFileName, newFileName, sizeof(newFileName), kCFStringEncodingUTF8))
- {
- mFiles.push_back(std::string(path) + "/" + std::string(newFileName));
- }
- else
- {
- error = paramErr;
- }
- }
- else
- {
- error = paramErr;
- }
- }
- }
- }
+ mFiles.push_back(*filev);
+ return true;
+ }
- return error;
+ return false;
}
BOOL LLFilePicker::getOpenFile(ELoadFilter filter, bool blocking)
@@ -909,16 +765,21 @@ BOOL LLFilePicker::getOpenFile(ELoadFilter filter, bool blocking)
return FALSE;
}
- OSStatus error = noErr;
-
reset();
- mNavOptions.optionFlags &= ~kNavAllowMultipleFiles;
+ mPickOptions &= ~F_MULTIPLE;
+ mPickOptions |= F_FILE;
+
+ if (filter == FFLOAD_DIRECTORY) //This should only be called from lldirpicker.
+ {
+
+ mPickOptions |= ( F_NAV_SUPPORT | F_DIRECTORY );
+ mPickOptions &= ~F_FILE;
+ }
if(filter == FFLOAD_ALL) // allow application bundles etc. to be traversed; important for DEV-16869, but generally useful
{
- // mNavOptions.optionFlags |= kNavAllowOpenPackages;
- mNavOptions.optionFlags |= kNavSupportPackages;
+ mPickOptions &= F_NAV_SUPPORT;
}
if (blocking)
@@ -927,14 +788,13 @@ BOOL LLFilePicker::getOpenFile(ELoadFilter filter, bool blocking)
send_agent_pause();
}
+
+ success = doNavChooseDialog(filter);
+
+ if (success)
{
- error = doNavChooseDialog(filter);
- }
-
- if (error == noErr)
- {
- if (getFileCount())
- success = true;
+ if (!getFileCount())
+ success = false;
}
if (blocking)
@@ -960,21 +820,22 @@ BOOL LLFilePicker::getMultipleOpenFiles(ELoadFilter filter)
return FALSE;
}
- OSStatus error = noErr;
-
reset();
-
- mNavOptions.optionFlags |= kNavAllowMultipleFiles;
+
+ mPickOptions |= F_FILE;
+
+ mPickOptions |= F_MULTIPLE;
// Modal, so pause agent
send_agent_pause();
+
+ success = doNavChooseDialog(filter);
+
+ send_agent_resume();
+
+ if (success)
{
- error = doNavChooseDialog(filter);
- }
- send_agent_resume();
- if (error == noErr)
- {
- if (getFileCount())
- success = true;
+ if (!getFileCount())
+ success = false;
if (getFileCount() > 1)
mLocked = true;
}
@@ -986,37 +847,39 @@ BOOL LLFilePicker::getMultipleOpenFiles(ELoadFilter filter)
BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename)
{
+
if( mLocked )
- return FALSE;
- BOOL success = FALSE;
- OSStatus error = noErr;
+ return false;
+ BOOL success = false;
// if local file browsing is turned off, return without opening dialog
if ( check_local_file_access_enabled() == false )
{
- return FALSE;
+ return false;
}
reset();
- mNavOptions.optionFlags &= ~kNavAllowMultipleFiles;
+ mPickOptions &= ~F_MULTIPLE;
// Modal, so pause agent
send_agent_pause();
+
+ success = doNavSaveDialog(filter, filename);
+
+ if (success)
{
- error = doNavSaveDialog(filter, filename);
+ if (!getFileCount())
+ success = false;
}
+
send_agent_resume();
- if (error == noErr)
- {
- if (getFileCount())
- success = true;
- }
// Account for the fact that the app has been stalled.
LLFrameTimer::updateFrameTime();
return success;
}
+//END LL_DARWIN
#elif LL_LINUX || LL_SOLARIS
@@ -1074,6 +937,22 @@ void LLFilePicker::chooser_responder(GtkWidget *widget, gint response, gpointer
g_slist_free (file_list);
}
+ // let's save the extension of the last added file(considering current filter)
+ GtkFileFilter *gfilter = gtk_file_chooser_get_filter(GTK_FILE_CHOOSER(widget));
+ if(gfilter)
+ {
+ std::string filter = gtk_file_filter_get_name(gfilter);
+
+ if(filter == LLTrans::getString("png_image_files"))
+ {
+ picker->mCurrentExtension = ".png";
+ }
+ else if(filter == LLTrans::getString("targa_image_files"))
+ {
+ picker->mCurrentExtension = ".tga";
+ }
+ }
+
// set the default path for this usage context.
const char* cur_folder = gtk_file_chooser_get_current_folder(GTK_FILE_CHOOSER(widget));
if (cur_folder != NULL)
@@ -1088,6 +967,7 @@ void LLFilePicker::chooser_responder(GtkWidget *widget, gint response, gpointer
GtkWindow* LLFilePicker::buildFilePicker(bool is_save, bool is_folder, std::string context)
{
+#ifndef LL_MESA_HEADLESS
if (LLWindowSDL::ll_try_gtk_init())
{
GtkWidget *win = NULL;
@@ -1159,6 +1039,9 @@ GtkWindow* LLFilePicker::buildFilePicker(bool is_save, bool is_folder, std::stri
{
return NULL;
}
+#else
+ return NULL;
+#endif //LL_MESA_HEADLESS
}
static void add_common_filters_to_gtkchooser(GtkFileFilter *gfilter,
@@ -1235,6 +1118,30 @@ static std::string add_script_filter_to_gtkchooser(GtkWindow *picker)
LLTrans::getString("script_files") + " (*.lsl)");
}
+static std::string add_dictionary_filter_to_gtkchooser(GtkWindow *picker)
+{
+ return add_simple_mime_filter_to_gtkchooser(picker, "text/plain",
+ LLTrans::getString("dictionary_files") + " (*.dic; *.xcu)");
+}
+
+static std::string add_save_texture_filter_to_gtkchooser(GtkWindow *picker)
+{
+ GtkFileFilter *gfilter_tga = gtk_file_filter_new();
+ GtkFileFilter *gfilter_png = gtk_file_filter_new();
+
+ gtk_file_filter_add_pattern(gfilter_tga, "*.tga");
+ gtk_file_filter_add_mime_type(gfilter_png, "image/png");
+ std::string caption = LLTrans::getString("save_texture_image_files") + " (*.tga; *.png)";
+ gtk_file_filter_set_name(gfilter_tga, LLTrans::getString("targa_image_files").c_str());
+ gtk_file_filter_set_name(gfilter_png, LLTrans::getString("png_image_files").c_str());
+
+ gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(picker),
+ gfilter_png);
+ gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(picker),
+ gfilter_tga);
+ return caption;
+}
+
BOOL LLFilePicker::getSaveFile( ESaveFilter filter, const std::string& filename )
{
BOOL rtn = FALSE;
@@ -1272,6 +1179,15 @@ BOOL LLFilePicker::getSaveFile( ESaveFilter filter, const std::string& filename
(picker, "image/bmp", LLTrans::getString("bitmap_image_files") + " (*.bmp)");
suggest_ext = ".bmp";
break;
+ case FFSAVE_PNG:
+ caption += add_simple_mime_filter_to_gtkchooser
+ (picker, "image/png", LLTrans::getString("png_image_files") + " (*.png)");
+ suggest_ext = ".png";
+ break;
+ case FFSAVE_TGAPNG:
+ caption += add_save_texture_filter_to_gtkchooser(picker);
+ suggest_ext = ".png";
+ break;
case FFSAVE_AVI:
caption += add_simple_mime_filter_to_gtkchooser
(picker, "video/x-msvideo",
@@ -1324,9 +1240,17 @@ BOOL LLFilePicker::getSaveFile( ESaveFilter filter, const std::string& filename
}
gtk_widget_show_all(GTK_WIDGET(picker));
+
gtk_main();
rtn = (getFileCount() == 1);
+
+ if(rtn && filter == FFSAVE_TGAPNG)
+ {
+ std::string selected_file = mFiles.back();
+ mFiles.pop_back();
+ mFiles.push_back(selected_file + mCurrentExtension);
+ }
}
gViewerWindow->getWindow()->afterDialog();
@@ -1371,6 +1295,9 @@ BOOL LLFilePicker::getOpenFile( ELoadFilter filter, bool blocking )
case FFLOAD_SCRIPT:
filtername = add_script_filter_to_gtkchooser(picker);
break;
+ case FFLOAD_DICTIONARY:
+ filtername = add_dictionary_filter_to_gtkchooser(picker);
+ break;
default:;
break;
}
@@ -1449,7 +1376,7 @@ BOOL LLFilePicker::getSaveFile( ESaveFilter filter, const std::string& filename
return FALSE;
}
-BOOL LLFilePicker::getOpenFile( ELoadFilter filter )
+BOOL LLFilePicker::getOpenFile( ELoadFilter filter, bool blocking )
{
// if local file browsing is turned off, return without opening dialog
// (Even though this is a stub, I think we still should not return anything at all)
@@ -1470,7 +1397,7 @@ BOOL LLFilePicker::getOpenFile( ELoadFilter filter )
default: break;
}
mFiles.push_back(filename);
- llinfos << "getOpenFile: Will try to open file: " << hackyfilename << llendl;
+ llinfos << "getOpenFile: Will try to open file: " << filename << llendl;
return TRUE;
}
@@ -1509,4 +1436,4 @@ BOOL LLFilePicker::getMultipleOpenFiles( ELoadFilter filter )
return FALSE;
}
-#endif
+#endif // LL_LINUX || LL_SOLARIS
diff --git a/indra/newview/llfilepicker.h b/indra/newview/llfilepicker.h
index a4d5d68ff5..f0f82c51db 100644..100755
--- a/indra/newview/llfilepicker.h
+++ b/indra/newview/llfilepicker.h
@@ -85,6 +85,8 @@ public:
FFLOAD_MODEL = 9,
FFLOAD_COLLADA = 10,
FFLOAD_SCRIPT = 11,
+ FFLOAD_DICTIONARY = 12,
+ FFLOAD_DIRECTORY = 13 //To call from lldirpicker.
};
enum ESaveFilter
@@ -105,6 +107,7 @@ public:
FFSAVE_PNG = 13,
FFSAVE_JPEG = 14,
FFSAVE_SCRIPT = 15,
+ FFSAVE_TGAPNG = 16
};
// open the dialog. This is a modal operation
@@ -157,15 +160,14 @@ private:
#endif
#if LL_DARWIN
- NavDialogCreationOptions mNavOptions;
+ S32 mPickOptions;
std::vector<std::string> mFileVector;
UInt32 mFileIndex;
- OSStatus doNavChooseDialog(ELoadFilter filter);
- OSStatus doNavSaveDialog(ESaveFilter filter, const std::string& filename);
- void getFilePath(SInt32 index);
- void getFileName(SInt32 index);
- static Boolean navOpenFilterProc(AEDesc *theItem, void *info, void *callBackUD, NavFilterModes filterMode);
+ bool doNavChooseDialog(ELoadFilter filter);
+ bool doNavSaveDialog(ESaveFilter filter, const std::string& filename);
+ //static Boolean navOpenFilterProc(AEDesc *theItem, void *info, void *callBackUD, NavFilterModes filterMode);
+ std::vector<std::string>* navOpenFilterProc(ELoadFilter filter);
#endif
#if LL_GTK
@@ -174,6 +176,8 @@ private:
// we remember the last path that was accessed for a particular usage
std::map <std::string, std::string> mContextToPathMap;
std::string mCurContextName;
+ // we also remember the extension of the last added file.
+ std::string mCurrentExtension;
#endif
std::vector<std::string> mFiles;
diff --git a/indra/newview/llfilepicker_mac.h b/indra/newview/llfilepicker_mac.h
new file mode 100644
index 0000000000..e0b7e2e8ce
--- /dev/null
+++ b/indra/newview/llfilepicker_mac.h
@@ -0,0 +1,58 @@
+/**
+ * @file llfilepicker_mac.h
+ * @brief OS-specific file picker
+ *
+ * $LicenseInfo:firstyear=2001&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$
+ */
+
+// OS specific file selection dialog. This is implemented as a
+// singleton class, so call the instance() method to get the working
+// instance. When you call getMultipleOpenFile(), it locks the picker
+// until you iterate to the end of the list of selected files with
+// getNextFile() or call reset().
+
+#ifndef LL_LLFILEPICKER_MAC_H
+#define LL_LLFILEPICKER_MAC_H
+
+#if LL_DARWIN
+
+#include <string>
+#include <vector>
+
+//void modelessPicker();
+std::vector<std::string>* doLoadDialog(const std::vector<std::string>* allowed_types,
+ unsigned int flags);
+std::string* doSaveDialog(const std::string* file,
+ const std::string* type,
+ const std::string* creator,
+ const std::string* extension,
+ unsigned int flags);
+enum {
+ F_FILE = 0x00000001,
+ F_DIRECTORY = 0x00000002,
+ F_MULTIPLE = 0x00000004,
+ F_NAV_SUPPORT=0x00000008
+};
+
+#endif
+
+#endif
diff --git a/indra/newview/llfilepicker_mac.mm b/indra/newview/llfilepicker_mac.mm
new file mode 100644
index 0000000000..13757904e3
--- /dev/null
+++ b/indra/newview/llfilepicker_mac.mm
@@ -0,0 +1,133 @@
+/**
+ * @file llfilepicker_mac.cpp
+ * @brief OS-specific file picker
+ *
+ * $LicenseInfo:firstyear=2001&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$
+ */
+
+#ifdef LL_DARWIN
+#import <Cocoa/Cocoa.h>
+#include <iostream>
+#include "llfilepicker_mac.h"
+
+std::vector<std::string>* doLoadDialog(const std::vector<std::string>* allowed_types,
+ unsigned int flags)
+{
+ int i, result;
+
+ //Aura TODO: We could init a small window and release it at the end of this routine
+ //for a modeless interface.
+
+ NSOpenPanel *panel = [NSOpenPanel openPanel];
+ //NSString *fileName = nil;
+ NSMutableArray *fileTypes = nil;
+
+
+ if ( allowed_types && !allowed_types->empty())
+ {
+ fileTypes = [[NSMutableArray alloc] init];
+
+ for (i=0;i<allowed_types->size();++i)
+ {
+ [fileTypes addObject:
+ [NSString stringWithCString:(*allowed_types)[i].c_str()
+ encoding:[NSString defaultCStringEncoding]]];
+ }
+ }
+
+ //[panel setMessage:@"Import one or more files or directories."];
+ [panel setAllowsMultipleSelection: ( (flags & F_MULTIPLE)?true:false ) ];
+ [panel setCanChooseDirectories: ( (flags & F_DIRECTORY)?true:false ) ];
+ [panel setCanCreateDirectories: true];
+ [panel setResolvesAliases: true];
+ [panel setCanChooseFiles: ( (flags & F_FILE)?true:false )];
+ [panel setTreatsFilePackagesAsDirectories: ( flags & F_NAV_SUPPORT ) ];
+
+ std::vector<std::string>* outfiles = NULL;
+
+ if (fileTypes)
+ {
+ [panel setAllowedFileTypes:fileTypes];
+ result = [panel runModal];
+ }
+ else
+ {
+ // I suggest it's better to open the last path and let this default to home dir as necessary
+ // for consistency with other OS X apps
+ //
+ //[panel setDirectoryURL: fileURLWithPath(NSHomeDirectory()) ];
+ result = [panel runModal];
+ }
+
+ if (result == NSOKButton)
+ {
+ NSArray *filesToOpen = [panel URLs];
+ int i, count = [filesToOpen count];
+
+ if (count > 0)
+ {
+ outfiles = new std::vector<std::string>;
+ }
+
+ for (i=0; i<count; i++) {
+ NSString *aFile = [[filesToOpen objectAtIndex:i] path];
+ std::string *afilestr = new std::string([aFile UTF8String]);
+ outfiles->push_back(*afilestr);
+ }
+ }
+ return outfiles;
+}
+
+
+std::string* doSaveDialog(const std::string* file,
+ const std::string* type,
+ const std::string* creator,
+ const std::string* extension,
+ unsigned int flags)
+{
+ NSSavePanel *panel = [NSSavePanel savePanel];
+
+ NSString *extensionns = [NSString stringWithCString:extension->c_str() encoding:[NSString defaultCStringEncoding]];
+ NSArray *fileType = [[NSArray alloc] initWithObjects:extensionns,nil];
+
+ //[panel setMessage:@"Save Image File"];
+ [panel setTreatsFilePackagesAsDirectories: ( flags & F_NAV_SUPPORT ) ];
+ [panel setCanSelectHiddenExtension:true];
+ [panel setAllowedFileTypes:fileType];
+ NSString *fileName = [NSString stringWithCString:file->c_str() encoding:[NSString defaultCStringEncoding]];
+
+ std::string *outfile = NULL;
+ NSURL* url = [NSURL fileURLWithPath:fileName];
+ [panel setNameFieldStringValue: fileName];
+ [panel setDirectoryURL: url];
+ if([panel runModal] ==
+ NSFileHandlingPanelOKButton)
+ {
+ NSURL* url = [panel URL];
+ NSString* p = [url path];
+ outfile = new std::string( [p UTF8String] );
+ // write the file
+ }
+ return outfile;
+}
+
+#endif
diff --git a/indra/newview/llfilteredwearablelist.cpp b/indra/newview/llfilteredwearablelist.cpp
index a29ccf2b6d..a29ccf2b6d 100644..100755
--- a/indra/newview/llfilteredwearablelist.cpp
+++ b/indra/newview/llfilteredwearablelist.cpp
diff --git a/indra/newview/llfilteredwearablelist.h b/indra/newview/llfilteredwearablelist.h
index c21458ca98..c21458ca98 100644..100755
--- a/indra/newview/llfilteredwearablelist.h
+++ b/indra/newview/llfilteredwearablelist.h
diff --git a/indra/newview/llfirstuse.cpp b/indra/newview/llfirstuse.cpp
index a9f52282a5..e2850f5181 100644..100755
--- a/indra/newview/llfirstuse.cpp
+++ b/indra/newview/llfirstuse.cpp
@@ -74,7 +74,7 @@ void LLFirstUse::resetFirstUse()
// static
void LLFirstUse::otherAvatarChatFirst(bool enable)
{
- firstUseNotification("FirstOtherChatBeforeUser", enable, "HintChat", LLSD(), LLSD().with("target", "chat_bar").with("direction", "top_right").with("distance", 24));
+ firstUseNotification("FirstOtherChatBeforeUser", enable, "HintChat", LLSD(), LLSD().with("target", "nearby_chat").with("direction", "top_right").with("distance", 24));
}
// static
diff --git a/indra/newview/llfirstuse.h b/indra/newview/llfirstuse.h
index 4c8c9d3cde..4c8c9d3cde 100644..100755
--- a/indra/newview/llfirstuse.h
+++ b/indra/newview/llfirstuse.h
diff --git a/indra/newview/llflexibleobject.cpp b/indra/newview/llflexibleobject.cpp
index 32a533570a..98c0c0bf51 100644..100755
--- a/indra/newview/llflexibleobject.cpp
+++ b/indra/newview/llflexibleobject.cpp
@@ -44,9 +44,11 @@
#include "llvoavatar.h"
/*static*/ F32 LLVolumeImplFlexible::sUpdateFactor = 1.0f;
+std::vector<LLVolumeImplFlexible*> LLVolumeImplFlexible::sInstanceList;
+std::vector<S32> LLVolumeImplFlexible::sUpdateDelay;
static LLFastTimer::DeclareTimer FTM_FLEXIBLE_REBUILD("Rebuild");
-static LLFastTimer::DeclareTimer FTM_DO_FLEXIBLE_UPDATE("Update");
+static LLFastTimer::DeclareTimer FTM_DO_FLEXIBLE_UPDATE("Flexible Update");
// LLFlexibleObjectData::pack/unpack now in llprimitive.cpp
@@ -64,14 +66,51 @@ LLVolumeImplFlexible::LLVolumeImplFlexible(LLViewerObject* vo, LLFlexibleObjectD
mSimulateRes = 0;
mFrameNum = 0;
mCollisionSphereRadius = 0.f;
- mRenderRes = 1;
-
+ mRenderRes = -1;
+
if(mVO->mDrawable.notNull())
{
mVO->mDrawable->makeActive() ;
}
+
+ mInstanceIndex = sInstanceList.size();
+ sInstanceList.push_back(this);
+ sUpdateDelay.push_back(0);
}//-----------------------------------------------
+LLVolumeImplFlexible::~LLVolumeImplFlexible()
+{
+ S32 end_idx = sInstanceList.size()-1;
+
+ if (end_idx != mInstanceIndex)
+ {
+ sInstanceList[mInstanceIndex] = sInstanceList[end_idx];
+ sInstanceList[mInstanceIndex]->mInstanceIndex = mInstanceIndex;
+ sUpdateDelay[mInstanceIndex] = sUpdateDelay[end_idx];
+ }
+
+ sInstanceList.pop_back();
+ sUpdateDelay.pop_back();
+}
+
+//static
+void LLVolumeImplFlexible::updateClass()
+{
+ std::vector<S32>::iterator delay_iter = sUpdateDelay.begin();
+
+ for (std::vector<LLVolumeImplFlexible*>::iterator iter = sInstanceList.begin();
+ iter != sInstanceList.end();
+ ++iter)
+ {
+ --(*delay_iter);
+ if (*delay_iter <= 0)
+ {
+ (*iter)->doIdleUpdate();
+ }
+ ++delay_iter;
+ }
+}
+
LLVector3 LLVolumeImplFlexible::getFramePosition() const
{
return mVO->getRenderPosition();
@@ -231,9 +270,6 @@ void LLVolumeImplFlexible::setAttributesOfAllSections(LLVector3* inScale)
mSection[0].mVelocity.setVec(0,0,0);
mSection[0].mAxisRotation.setQuat(begin_rot,0,0,1);
- LLVector3 parentSectionPosition = mSection[0].mPosition;
- LLVector3 last_direction = mSection[0].mDirection;
-
remapSections(mSection, mInitializedRes, mSection, mSimulateRes);
mInitializedRes = mSimulateRes;
@@ -255,50 +291,31 @@ void LLVolumeImplFlexible::onSetVolume(const LLVolumeParams &volume_params, cons
{
}
-//---------------------------------------------------------------------------------
-// This calculates the physics of the flexible object. Note that it has to be 0
-// updated every time step. In the future, perhaps there could be an
-// optimization similar to what Havok does for objects that are stationary.
-//---------------------------------------------------------------------------------
-static LLFastTimer::DeclareTimer FTM_FLEXIBLE_UPDATE("Update Flexies");
-BOOL LLVolumeImplFlexible::doIdleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
+
+void LLVolumeImplFlexible::updateRenderRes()
{
- if (mVO->mDrawable.isNull())
- {
- // Don't do anything until we have a drawable
- return FALSE; // (we are not initialized or updated)
- }
+ if (!mAttributes)
+ return;
- BOOL force_update = mSimulateRes == 0 ? TRUE : FALSE;
+ LLDrawable* drawablep = mVO->mDrawable;
- //flexible objects never go static
- mVO->mDrawable->mQuietCount = 0;
- if (!mVO->mDrawable->isRoot())
- {
- LLViewerObject* parent = (LLViewerObject*) mVO->getParent();
- parent->mDrawable->mQuietCount = 0;
- }
-
- LLFastTimer ftm(FTM_FLEXIBLE_UPDATE);
-
S32 new_res = mAttributes->getSimulateLOD();
- //number of segments only cares about z axis
- F32 app_angle = llround((F32) atan2( mVO->getScale().mV[2]*2.f, mVO->mDrawable->mDistanceWRTCamera) * RAD_TO_DEG, 0.01f);
+#if 1 //optimal approximation of previous behavior that doesn't rely on atan2
+ F32 app_angle = mVO->getScale().mV[2]/drawablep->mDistanceWRTCamera;
// Rendering sections increases with visible angle on the screen
- mRenderRes = (S32)(FLEXIBLE_OBJECT_MAX_SECTIONS*4*app_angle*DEG_TO_RAD/LLViewerCamera::getInstance()->getView());
- if (mRenderRes > FLEXIBLE_OBJECT_MAX_SECTIONS)
- {
- mRenderRes = FLEXIBLE_OBJECT_MAX_SECTIONS;
- }
-
+ mRenderRes = (S32) (12.f*app_angle);
+#else //legacy behavior
+ //number of segments only cares about z axis
+ F32 app_angle = llround((F32) atan2( mVO->getScale().mV[2]*2.f, drawablep->mDistanceWRTCamera) * RAD_TO_DEG, 0.01f);
- // Bottom cap at 1/4 the original number of sections
- if (mRenderRes < mAttributes->getSimulateLOD()-1)
- {
- mRenderRes = mAttributes->getSimulateLOD()-1;
- }
+ // Rendering sections increases with visible angle on the screen
+ mRenderRes = (S32)(FLEXIBLE_OBJECT_MAX_SECTIONS*4*app_angle*DEG_TO_RAD/LLViewerCamera::getInstance()->getView());
+#endif
+
+ mRenderRes = llclamp(mRenderRes, new_res-1, (S32) FLEXIBLE_OBJECT_MAX_SECTIONS);
+
// Throttle back simulation of segments we're not rendering
if (mRenderRes < new_res)
{
@@ -311,43 +328,87 @@ BOOL LLVolumeImplFlexible::doIdleUpdate(LLAgent &agent, LLWorld &world, const F6
setAttributesOfAllSections();
mInitialized = TRUE;
}
- if (!gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_FLEXIBLE))
- {
- return FALSE; // (we are not initialized or updated)
- }
-
- bool visible = mVO->mDrawable->isVisible();
+}
+//---------------------------------------------------------------------------------
+// This calculates the physics of the flexible object. Note that it has to be 0
+// updated every time step. In the future, perhaps there could be an
+// optimization similar to what Havok does for objects that are stationary.
+//---------------------------------------------------------------------------------
+static LLFastTimer::DeclareTimer FTM_FLEXIBLE_UPDATE("Update Flexies");
+void LLVolumeImplFlexible::doIdleUpdate()
+{
+ LLDrawable* drawablep = mVO->mDrawable;
- if (force_update && visible)
+ if (drawablep)
{
- gPipeline.markRebuild(mVO->mDrawable, LLDrawable::REBUILD_POSITION, FALSE);
- }
- else if (visible &&
- !mVO->mDrawable->isState(LLDrawable::IN_REBUILD_Q1) &&
- mVO->getPixelArea() > 256.f)
- {
- U32 id;
- F32 pixel_area = mVO->getPixelArea();
+ //LLFastTimer ftm(FTM_FLEXIBLE_UPDATE);
- if (mVO->isRootEdit())
- {
- id = mID;
- }
- else
+ //ensure drawable is active
+ drawablep->makeActive();
+
+ if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_FLEXIBLE))
{
- LLVOVolume* parent = (LLVOVolume*) mVO->getParent();
- id = parent->getVolumeInterfaceID();
- }
+ bool visible = drawablep->isVisible();
- U32 update_period = (U32) (LLViewerCamera::getInstance()->getScreenPixelArea()*0.01f/(pixel_area*(sUpdateFactor+1.f)))+1;
+ if (mRenderRes == -1)
+ {
+ updateRenderRes();
+ gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_POSITION, FALSE);
+ sUpdateDelay[mInstanceIndex] = 0;
+ }
+ else
+ {
+ F32 pixel_area = mVO->getPixelArea();
+
+ U32 update_period = (U32) (llmax((S32) (LLViewerCamera::getInstance()->getScreenPixelArea()*0.01f/(pixel_area*(sUpdateFactor+1.f))),0)+1);
+ // MAINT-1890 Clamp the update period to ensure that the update_period is no greater than 32 frames
+ update_period = llclamp(update_period, 0U, 32U);
+
+ if (visible)
+ {
+ if (!drawablep->isState(LLDrawable::IN_REBUILD_Q1) &&
+ pixel_area > 256.f)
+ {
+ U32 id;
+
+ if (mVO->isRootEdit())
+ {
+ id = mID;
+ }
+ else
+ {
+ LLVOVolume* parent = (LLVOVolume*) mVO->getParent();
+ id = parent->getVolumeInterfaceID();
+ }
+
+ if (mVO->isRootEdit())
+ {
+ id = mID;
+ }
+ else
+ {
+ LLVOVolume* parent = (LLVOVolume*) mVO->getParent();
+ id = parent->getVolumeInterfaceID();
+ }
+
+ if ((LLDrawable::getCurrentFrame()+id)%update_period == 0)
+ {
+ sUpdateDelay[mInstanceIndex] = (S32) update_period-1;
+
+ updateRenderRes();
+
+ gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_POSITION, FALSE);
+ }
+ }
+ }
+ else
+ {
+ sUpdateDelay[mInstanceIndex] = (S32) update_period;
+ }
+}
- if ((LLDrawable::getCurrentFrame()+id)%update_period == 0)
- {
- gPipeline.markRebuild(mVO->mDrawable, LLDrawable::REBUILD_POSITION, FALSE);
}
}
-
- return force_update;
}
inline S32 log2(S32 x)
@@ -368,18 +429,29 @@ void LLVolumeImplFlexible::doFlexibleUpdate()
LLPath *path = &volume->getPath();
if ((mSimulateRes == 0 || !mInitialized) && mVO->mDrawable->isVisible())
{
- mVO->markForUpdate(TRUE);
- if (!doIdleUpdate(gAgent, *LLWorld::getInstance(), 0.0))
+ BOOL force_update = mSimulateRes == 0 ? TRUE : FALSE;
+ doIdleUpdate();
+
+ if (!force_update || !gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_FLEXIBLE))
{
return; // we did not get updated or initialized, proceeding without can be dangerous
}
}
- if(!mInitialized)
+ if(!mInitialized || !mAttributes)
{
//the object is not visible
return ;
}
+
+ // Fix for MAINT-1894
+ // Skipping the flexible update if render res is negative. If we were to continue with a negative value,
+ // the subsequent S32 num_render_sections = 1<<mRenderRes; code will specify a really large number of
+ // render sections which will then create a length exception in the std::vector::resize() method.
+ if (mRenderRes < 0)
+ {
+ return;
+ }
S32 num_sections = 1 << mSimulateRes;
@@ -588,6 +660,7 @@ void LLVolumeImplFlexible::doFlexibleUpdate()
mSection[i].mdPosition = (mSection[i].mPosition - mSection[i-1].mPosition) * inv_section_length;
// Create points
+ llassert(mRenderRes > -1)
S32 num_render_sections = 1<<mRenderRes;
if (path->getPathLength() != num_render_sections+1)
{
@@ -619,30 +692,36 @@ void LLVolumeImplFlexible::doFlexibleUpdate()
LLVector4(z_axis, 0.f),
LLVector4(delta_pos, 1.f));
+ LL_CHECK_MEMORY
for (i=0; i<=num_render_sections; ++i)
{
new_point = &path->mPath[i];
LLVector3 pos = newSection[i].mPosition * rel_xform;
LLQuaternion rot = mSection[i].mAxisRotation * newSection[i].mRotation * delta_rot;
-
- if (!mUpdated || (new_point->mPos-pos).magVec()/mVO->mDrawable->mDistanceWRTCamera > 0.001f)
+
+ LLVector3 np(new_point->mPos.getF32ptr());
+
+ if (!mUpdated || (np-pos).magVec()/mVO->mDrawable->mDistanceWRTCamera > 0.001f)
{
- new_point->mPos = newSection[i].mPosition * rel_xform;
+ new_point->mPos.load3((newSection[i].mPosition * rel_xform).mV);
mUpdated = FALSE;
}
- new_point->mRot = rot;
- new_point->mScale = newSection[i].mScale;
+ new_point->mRot.loadu(LLMatrix3(rot));
+ new_point->mScale.set(newSection[i].mScale.mV[0], newSection[i].mScale.mV[1], 0,1);
new_point->mTexT = ((F32)i)/(num_render_sections);
}
-
+ LL_CHECK_MEMORY
mLastSegmentRotation = parentSegmentRotation;
}
+static LLFastTimer::DeclareTimer FTM_FLEXI_PREBUILD("Flexi Prebuild");
+
void LLVolumeImplFlexible::preRebuild()
{
if (!mUpdated)
{
+ LLFastTimer t(FTM_FLEXI_PREBUILD);
doFlexibleRebuild();
}
}
@@ -729,7 +808,11 @@ BOOL LLVolumeImplFlexible::doUpdateGeometry(LLDrawable *drawable)
else if (!mUpdated || rotated)
{
volume->mDrawable->setState(LLDrawable::REBUILD_POSITION);
- volume->dirtyMesh();
+ LLSpatialGroup* group = volume->mDrawable->getSpatialGroup();
+ if (group)
+ {
+ group->dirtyMesh();
+ }
volume->genBBoxes(isVolumeGlobal());
}
@@ -814,15 +897,17 @@ LLQuaternion LLVolumeImplFlexible::getEndRotation()
}//------------------------------------------------------------------
-void LLVolumeImplFlexible::updateRelativeXform()
+void LLVolumeImplFlexible::updateRelativeXform(bool force_identity)
{
LLQuaternion delta_rot;
LLVector3 delta_pos, delta_scale;
LLVOVolume* vo = (LLVOVolume*) mVO;
+ bool use_identity = vo->mDrawable->isSpatialRoot() || force_identity;
+
//matrix from local space to parent relative/global space
- delta_rot = vo->mDrawable->isSpatialRoot() ? LLQuaternion() : vo->mDrawable->getRotation();
- delta_pos = vo->mDrawable->isSpatialRoot() ? LLVector3(0,0,0) : vo->mDrawable->getPosition();
+ delta_rot = use_identity ? LLQuaternion() : vo->mDrawable->getRotation();
+ delta_pos = use_identity ? LLVector3(0,0,0) : vo->mDrawable->getPosition();
delta_scale = LLVector3(1,1,1);
// Vertex transform (4x4)
diff --git a/indra/newview/llflexibleobject.h b/indra/newview/llflexibleobject.h
index fef43d464d..beb281a906 100644..100755
--- a/indra/newview/llflexibleobject.h
+++ b/indra/newview/llflexibleobject.h
@@ -70,15 +70,24 @@ struct LLFlexibleObjectSection
//---------------------------------------------------------
class LLVolumeImplFlexible : public LLVolumeInterface
{
+private:
+ static std::vector<LLVolumeImplFlexible*> sInstanceList;
+ static std::vector<S32> sUpdateDelay;
+ S32 mInstanceIndex;
+
public:
+ static void updateClass();
+
LLVolumeImplFlexible(LLViewerObject* volume, LLFlexibleObjectData* attributes);
+ ~LLVolumeImplFlexible();
// Implements LLVolumeInterface
U32 getID() const { return mID; }
LLVector3 getFramePosition() const;
LLQuaternion getFrameRotation() const;
LLVolumeInterfaceType getInterfaceType() const { return INTERFACE_FLEXIBLE; }
- BOOL doIdleUpdate(LLAgent &agent, LLWorld &world, const F64 &time);
+ void updateRenderRes();
+ void doIdleUpdate();
BOOL doUpdateGeometry(LLDrawable *drawable);
LLVector3 getPivotPosition() const;
void onSetVolume(const LLVolumeParams &volume_params, const S32 detail);
@@ -89,7 +98,7 @@ class LLVolumeImplFlexible : public LLVolumeInterface
bool isVolumeGlobal() const { return true; }
bool isActive() const { return true; }
const LLMatrix4& getWorldMatrix(LLXformMatrix* xform) const;
- void updateRelativeXform();
+ void updateRelativeXform(bool force_identity);
void doFlexibleUpdate(); // Called to update the simulation
void doFlexibleRebuild(); // Called to rebuild the geometry
void preRebuild();
@@ -128,7 +137,7 @@ class LLVolumeImplFlexible : public LLVolumeInterface
LLVector3 mCollisionSpherePosition;
F32 mCollisionSphereRadius;
U32 mID;
-
+
//--------------------------------------
// private methods
//--------------------------------------
diff --git a/indra/newview/llfloaterabout.cpp b/indra/newview/llfloaterabout.cpp
index 83fb887d81..fea8e34729 100644..100755
--- a/indra/newview/llfloaterabout.cpp
+++ b/indra/newview/llfloaterabout.cpp
@@ -33,8 +33,10 @@
// Viewer includes
#include "llagent.h"
+#include "llagentui.h"
#include "llappviewer.h"
#include "llsecondlifeurls.h"
+#include "llslurl.h"
#include "llvoiceclient.h"
#include "lluictrlfactory.h"
#include "llviewertexteditor.h"
@@ -250,12 +252,16 @@ LLSD LLFloaterAbout::getInfo()
LLViewerRegion* region = gAgent.getRegion();
if (region)
{
- const LLVector3d &pos = gAgent.getPositionGlobal();
+ LLVector3d pos = gAgent.getPositionGlobal();
info["POSITION"] = ll_sd_from_vector3d(pos);
+ info["POSITION_LOCAL"] = ll_sd_from_vector3(gAgent.getPosAgentFromGlobal(pos));
info["REGION"] = gAgent.getRegion()->getName();
info["HOSTNAME"] = gAgent.getRegion()->getHost().getHostName();
info["HOSTIP"] = gAgent.getRegion()->getHost().getString();
info["SERVER_VERSION"] = gLastVersionChannel;
+ LLSLURL slurl;
+ LLAgentUI::buildSLURL(slurl);
+ info["SLURL"] = slurl.getSLURLString();
}
// CPU
@@ -307,12 +313,12 @@ LLSD LLFloaterAbout::getInfo()
static std::string get_viewer_release_notes_url()
{
// return a URL to the release notes for this viewer, such as:
- // http://wiki.secondlife.com/wiki/Release_Notes/Second Life Beta Viewer/2.1.0
+ // http://wiki.secondlife.com/wiki/Release_Notes/Second Life Beta Viewer/2.1.0.123456
std::string url = LLTrans::getString("RELEASE_NOTES_BASE_URL");
if (! LLStringUtil::endsWith(url, "/"))
url += "/";
url += LLVersionInfo::getChannel() + "/";
- url += LLVersionInfo::getShortVersion();
+ url += LLVersionInfo::getVersion();
return LLWeb::escapeURL(url);
}
diff --git a/indra/newview/llfloaterabout.h b/indra/newview/llfloaterabout.h
index 8fc1aa4f29..8fc1aa4f29 100644..100755
--- a/indra/newview/llfloaterabout.h
+++ b/indra/newview/llfloaterabout.h
diff --git a/indra/newview/llfloaterauction.cpp b/indra/newview/llfloaterauction.cpp
index 2939d31087..3c40e2d4bc 100644..100755
--- a/indra/newview/llfloaterauction.cpp
+++ b/indra/newview/llfloaterauction.cpp
@@ -38,6 +38,7 @@
#include "message.h"
#include "llagent.h"
+#include "llassetstorage.h"
#include "llcombobox.h"
#include "llestateinfomodel.h"
#include "llmimetypes.h"
diff --git a/indra/newview/llfloaterauction.h b/indra/newview/llfloaterauction.h
index 9c0c0f7775..9c0c0f7775 100644..100755
--- a/indra/newview/llfloaterauction.h
+++ b/indra/newview/llfloaterauction.h
diff --git a/indra/newview/llfloaterautoreplacesettings.cpp b/indra/newview/llfloaterautoreplacesettings.cpp
new file mode 100755
index 0000000000..6e56e929df
--- /dev/null
+++ b/indra/newview/llfloaterautoreplacesettings.cpp
@@ -0,0 +1,665 @@
+/**
+ * @file llfloaterautoreplacesettings.cpp
+ * @brief Auto Replace List floater
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * 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
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llfloaterautoreplacesettings.h"
+
+#include "llagentdata.h"
+#include "llcommandhandler.h"
+#include "llfloater.h"
+#include "lluictrlfactory.h"
+#include "llagent.h"
+#include "llpanel.h"
+#include "llbutton.h"
+#include "llcolorswatch.h"
+#include "llcombobox.h"
+#include "llview.h"
+#include "llhttpclient.h"
+#include "llbufferstream.h"
+#include "llcheckboxctrl.h"
+#include "llviewercontrol.h"
+
+#include "llui.h"
+#include "llcontrol.h"
+#include "llscrollingpanellist.h"
+#include "llautoreplace.h"
+#include "llfilepicker.h"
+#include "llfile.h"
+#include "llsdserialize.h"
+#include "llsdutil.h"
+
+#include "llchat.h"
+#include "llinventorymodel.h"
+#include "llhost.h"
+#include "llassetstorage.h"
+#include "roles_constants.h"
+#include "llviewertexteditor.h"
+#include <boost/tokenizer.hpp>
+
+#include <iosfwd>
+#include "llfloaterreg.h"
+#include "llinspecttoast.h"
+#include "llnotificationhandler.h"
+#include "llnotificationmanager.h"
+#include "llnotificationsutil.h"
+
+
+LLFloaterAutoReplaceSettings::LLFloaterAutoReplaceSettings(const LLSD& key)
+ : LLFloater(key)
+ , mSelectedListName("")
+ , mListNames(NULL)
+ , mReplacementsList(NULL)
+ , mKeyword(NULL)
+ , mPreviousKeyword("")
+ , mReplacement(NULL)
+{
+}
+
+void LLFloaterAutoReplaceSettings::onClose(bool app_quitting)
+{
+ cleanUp();
+}
+
+BOOL LLFloaterAutoReplaceSettings::postBuild(void)
+{
+ // get copies of the current settings that we will operate on
+ mEnabled = gSavedSettings.getBOOL("AutoReplace");
+ LL_DEBUGS("AutoReplace") << ( mEnabled ? "enabled" : "disabled") << LL_ENDL;
+
+ mSettings = LLAutoReplace::getInstance()->getSettings();
+
+ // global checkbox for whether or not autoreplace is active
+ LLUICtrl* enabledCheckbox = getChild<LLUICtrl>("autoreplace_enable");
+ enabledCheckbox->setCommitCallback(boost::bind(&LLFloaterAutoReplaceSettings::onAutoReplaceToggled, this));
+ enabledCheckbox->setValue(LLSD(mEnabled));
+
+ // top row list creation and deletion
+ getChild<LLUICtrl>("autoreplace_import_list")->setCommitCallback(boost::bind(&LLFloaterAutoReplaceSettings::onImportList,this));
+ getChild<LLUICtrl>("autoreplace_export_list")->setCommitCallback(boost::bind(&LLFloaterAutoReplaceSettings::onExportList,this));
+ getChild<LLUICtrl>("autoreplace_new_list")->setCommitCallback( boost::bind(&LLFloaterAutoReplaceSettings::onNewList,this));
+ getChild<LLUICtrl>("autoreplace_delete_list")->setCommitCallback(boost::bind(&LLFloaterAutoReplaceSettings::onDeleteList,this));
+
+ // the list of keyword->replacement lists
+ mListNames = getChild<LLScrollListCtrl>("autoreplace_list_name");
+ mListNames->setCommitCallback(boost::bind(&LLFloaterAutoReplaceSettings::onSelectList, this));
+ mListNames->setCommitOnSelectionChange(true);
+
+ // list ordering
+ getChild<LLUICtrl>("autoreplace_list_up")->setCommitCallback( boost::bind(&LLFloaterAutoReplaceSettings::onListUp,this));
+ getChild<LLUICtrl>("autoreplace_list_down")->setCommitCallback(boost::bind(&LLFloaterAutoReplaceSettings::onListDown,this));
+
+ // keyword->replacement entry add / delete
+ getChild<LLUICtrl>("autoreplace_add_entry")->setCommitCallback( boost::bind(&LLFloaterAutoReplaceSettings::onAddEntry,this));
+ getChild<LLUICtrl>("autoreplace_delete_entry")->setCommitCallback(boost::bind(&LLFloaterAutoReplaceSettings::onDeleteEntry,this));
+
+ // entry edits
+ mKeyword = getChild<LLLineEditor>("autoreplace_keyword");
+ mReplacement = getChild<LLLineEditor>("autoreplace_replacement");
+ getChild<LLUICtrl>("autoreplace_save_entry")->setCommitCallback(boost::bind(&LLFloaterAutoReplaceSettings::onSaveEntry, this));
+
+ // dialog termination ( Save Changes / Cancel )
+ getChild<LLUICtrl>("autoreplace_save_changes")->setCommitCallback(boost::bind(&LLFloaterAutoReplaceSettings::onSaveChanges, this));
+ getChild<LLUICtrl>("autoreplace_cancel")->setCommitCallback(boost::bind(&LLFloaterAutoReplaceSettings::onCancel, this));
+
+ // the list of keyword->replacement pairs
+ mReplacementsList = getChild<LLScrollListCtrl>("autoreplace_list_replacements");
+ mReplacementsList->setCommitCallback(boost::bind(&LLFloaterAutoReplaceSettings::onSelectEntry, this));
+ mReplacementsList->setCommitOnSelectionChange(true);
+
+ center();
+
+ mSelectedListName.clear();
+ updateListNames();
+ updateListNamesControls();
+ updateReplacementsList();
+
+ return true;
+}
+
+
+void LLFloaterAutoReplaceSettings::updateListNames()
+{
+ mListNames->deleteAllItems(); // start from scratch
+
+ LLSD listNames = mSettings.getListNames(); // Array of Strings
+
+ for ( LLSD::array_const_iterator entry = listNames.beginArray(), end = listNames.endArray();
+ entry != end;
+ ++entry
+ )
+ {
+ const std::string& listName = entry->asString();
+ mListNames->addSimpleElement(listName);
+ }
+
+ if (!mSelectedListName.empty())
+ {
+ mListNames->setSelectedByValue( LLSD(mSelectedListName), true );
+ }
+}
+
+void LLFloaterAutoReplaceSettings::updateListNamesControls()
+{
+ if ( mSelectedListName.empty() )
+ {
+ // There is no selected list
+
+ // Disable all controls that operate on the selected list
+ getChild<LLButton>("autoreplace_export_list")->setEnabled(false);
+ getChild<LLButton>("autoreplace_delete_list")->setEnabled(false);
+ getChild<LLButton>("autoreplace_list_up")->setEnabled(false);
+ getChild<LLButton>("autoreplace_list_down")->setEnabled(false);
+
+ mReplacementsList->deleteAllItems();
+ }
+ else
+ {
+ // Enable the controls that operate on the selected list
+ getChild<LLButton>("autoreplace_export_list")->setEnabled(true);
+ getChild<LLButton>("autoreplace_delete_list")->setEnabled(true);
+ getChild<LLButton>("autoreplace_list_up")->setEnabled(!selectedListIsFirst());
+ getChild<LLButton>("autoreplace_list_down")->setEnabled(!selectedListIsLast());
+ }
+}
+
+void LLFloaterAutoReplaceSettings::onSelectList()
+{
+ std::string previousSelectedListName = mSelectedListName;
+ // only one selection allowed
+ LLSD selected = mListNames->getSelectedValue();
+ if (selected.isDefined())
+ {
+ mSelectedListName = selected.asString();
+ LL_DEBUGS("AutoReplace")<<"selected list '"<<mSelectedListName<<"'"<<LL_ENDL;
+ }
+ else
+ {
+ mSelectedListName.clear();
+ LL_DEBUGS("AutoReplace")<<"unselected"<<LL_ENDL;
+ }
+
+ updateListNamesControls();
+
+ if ( previousSelectedListName != mSelectedListName )
+ {
+ updateReplacementsList();
+ }
+}
+
+void LLFloaterAutoReplaceSettings::onSelectEntry()
+{
+ LLSD selectedRow = mReplacementsList->getSelectedValue();
+ if (selectedRow.isDefined())
+ {
+ mPreviousKeyword = selectedRow.asString();
+ LL_DEBUGS("AutoReplace")<<"selected entry '"<<mPreviousKeyword<<"'"<<LL_ENDL;
+ mKeyword->setValue(selectedRow);
+ std::string replacement = mSettings.replacementFor(mPreviousKeyword, mSelectedListName );
+ mReplacement->setValue(replacement);
+ enableReplacementEntry();
+ mReplacement->setFocus(true);
+ }
+ else
+ {
+ // no entry selection, so the entry panel should be off
+ disableReplacementEntry();
+ LL_DEBUGS("AutoReplace")<<"no row selected"<<LL_ENDL;
+ }
+}
+
+void LLFloaterAutoReplaceSettings::updateReplacementsList()
+{
+ // start from scratch, since this should only be called when the list changes
+ mReplacementsList->deleteAllItems();
+
+ if ( mSelectedListName.empty() )
+ {
+ mReplacementsList->setEnabled(false);
+ getChild<LLButton>("autoreplace_add_entry")->setEnabled(false);
+ disableReplacementEntry();
+ }
+ else
+ {
+ // Populate the keyword->replacement list from the selected list
+ const LLSD* mappings = mSettings.getListEntries(mSelectedListName);
+ for ( LLSD::map_const_iterator entry = mappings->beginMap(), end = mappings->endMap();
+ entry != end;
+ entry++
+ )
+ {
+ LLSD row;
+ row["id"] = entry->first;
+ row["columns"][0]["column"] = "keyword";
+ row["columns"][0]["value"] = entry->first;
+ row["columns"][1]["column"] = "replacement";
+ row["columns"][1]["value"] = entry->second;
+
+ mReplacementsList->addElement(row, ADD_BOTTOM);
+ }
+
+ mReplacementsList->deselectAllItems(false /* don't call commit */);
+ mReplacementsList->setEnabled(true);
+
+ getChild<LLButton>("autoreplace_add_entry")->setEnabled(true);
+ disableReplacementEntry();
+ }
+}
+
+void LLFloaterAutoReplaceSettings::enableReplacementEntry()
+{
+ LL_DEBUGS("AutoReplace")<<LL_ENDL;
+ mKeyword->setEnabled(true);
+ mReplacement->setEnabled(true);
+ getChild<LLButton>("autoreplace_save_entry")->setEnabled(true);
+ getChild<LLButton>("autoreplace_delete_entry")->setEnabled(true);
+}
+
+void LLFloaterAutoReplaceSettings::disableReplacementEntry()
+{
+ LL_DEBUGS("AutoReplace")<<LL_ENDL;
+ mPreviousKeyword.clear();
+ mKeyword->clear();
+ mKeyword->setEnabled(false);
+ mReplacement->clear();
+ mReplacement->setEnabled(false);
+ getChild<LLButton>("autoreplace_save_entry")->setEnabled(false);
+ getChild<LLButton>("autoreplace_delete_entry")->setEnabled(false);
+}
+
+// called when the global settings checkbox is changed
+void LLFloaterAutoReplaceSettings::onAutoReplaceToggled()
+{
+ // set our local copy of the flag, copied to the global preference in onOk
+ mEnabled = childGetValue("autoreplace_enable").asBoolean();
+ LL_DEBUGS("AutoReplace")<< "autoreplace_enable " << ( mEnabled ? "on" : "off" ) << LL_ENDL;
+}
+
+// called when the List Up button is pressed
+void LLFloaterAutoReplaceSettings::onListUp()
+{
+ S32 selectedRow = mListNames->getFirstSelectedIndex();
+ LLSD selectedName = mListNames->getSelectedValue().asString();
+
+ if ( mSettings.increaseListPriority(selectedName) )
+ {
+ updateListNames();
+ updateListNamesControls();
+ }
+ else
+ {
+ LL_WARNS("AutoReplace")
+ << "invalid row ("<<selectedRow<<") selected '"<<selectedName<<"'"
+ <<LL_ENDL;
+ }
+}
+
+// called when the List Down button is pressed
+void LLFloaterAutoReplaceSettings::onListDown()
+{
+ S32 selectedRow = mListNames->getFirstSelectedIndex();
+ std::string selectedName = mListNames->getSelectedValue().asString();
+
+ if ( mSettings.decreaseListPriority(selectedName) )
+ {
+ updateListNames();
+ updateListNamesControls();
+ }
+ else
+ {
+ LL_WARNS("AutoReplace")
+ << "invalid row ("<<selectedRow<<") selected '"<<selectedName<<"'"
+ <<LL_ENDL;
+ }
+}
+
+// called when the Delete Entry button is pressed
+void LLFloaterAutoReplaceSettings::onDeleteEntry()
+{
+ LLSD selectedRow = mReplacementsList->getSelectedValue();
+ if (selectedRow.isDefined())
+ {
+ std::string keyword = selectedRow.asString();
+ mReplacementsList->deleteSelectedItems(); // delete from the control
+ mSettings.removeEntryFromList(keyword, mSelectedListName); // delete from the local settings copy
+ disableReplacementEntry(); // no selection active, so turn off the buttons
+ }
+}
+
+// called when the Import List button is pressed
+void LLFloaterAutoReplaceSettings::onImportList()
+{
+ LLFilePicker& picker = LLFilePicker::instance();
+ if( picker.getOpenFile( LLFilePicker::FFLOAD_XML) )
+ {
+ llifstream file;
+ file.open(picker.getFirstFile().c_str());
+ LLSD newList;
+ if (file.is_open())
+ {
+ LLSDSerialize::fromXMLDocument(newList, file);
+ }
+ file.close();
+
+ switch ( mSettings.addList(newList) )
+ {
+ case LLAutoReplaceSettings::AddListOk:
+ mSelectedListName = LLAutoReplaceSettings::getListName(newList);
+
+ updateListNames();
+ updateListNamesControls();
+ updateReplacementsList();
+ break;
+
+ case LLAutoReplaceSettings::AddListDuplicateName:
+ {
+ std::string newName = LLAutoReplaceSettings::getListName(newList);
+ LL_WARNS("AutoReplace")<<"name '"<<newName<<"' is in use; prompting for new name"<<LL_ENDL;
+ LLSD newPayload;
+ newPayload["list"] = newList;
+ LLSD args;
+ args["DUPNAME"] = newName;
+
+ LLNotificationsUtil::add("RenameAutoReplaceList", args, newPayload,
+ boost::bind(&LLFloaterAutoReplaceSettings::callbackListNameConflict, this, _1, _2));
+ }
+ break;
+
+ case LLAutoReplaceSettings::AddListInvalidList:
+ LLNotificationsUtil::add("InvalidAutoReplaceList");
+ LL_WARNS("AutoReplace") << "imported list was invalid" << LL_ENDL;
+
+ mSelectedListName.clear();
+ updateListNames();
+ updateListNamesControls();
+ updateReplacementsList();
+ break;
+
+ default:
+ LL_ERRS("AutoReplace") << "invalid AddListResult" << LL_ENDL;
+
+ }
+
+ }
+ else
+ {
+ LL_DEBUGS("AutoReplace") << "file selection failed for import list" << LL_ENDL;
+ }
+}
+
+void LLFloaterAutoReplaceSettings::onNewList()
+{
+ LLSD payload;
+ LLSD emptyList;
+ LLAutoReplaceSettings::createEmptyList(emptyList);
+ payload["list"] = emptyList;
+ LLSD args;
+
+ LLNotificationsUtil::add("AddAutoReplaceList", args, payload,
+ boost::bind(&LLFloaterAutoReplaceSettings::callbackNewListName, this, _1, _2));
+}
+
+bool LLFloaterAutoReplaceSettings::callbackNewListName(const LLSD& notification, const LLSD& response)
+{
+ LL_DEBUGS("AutoReplace")<<"called"<<LL_ENDL;
+
+ LLSD newList = notification["payload"]["list"];
+
+ if ( response.has("listname") && response["listname"].isString() )
+ {
+ std::string newName = response["listname"].asString();
+ LLAutoReplaceSettings::setListName(newList, newName);
+
+ switch ( mSettings.addList(newList) )
+ {
+ case LLAutoReplaceSettings::AddListOk:
+ LL_INFOS("AutoReplace") << "added new list '"<<newName<<"'"<<LL_ENDL;
+ mSelectedListName = newName;
+ updateListNames();
+ updateListNamesControls();
+ updateReplacementsList();
+ break;
+
+ case LLAutoReplaceSettings::AddListDuplicateName:
+ {
+ LL_WARNS("AutoReplace")<<"name '"<<newName<<"' is in use; prompting for new name"<<LL_ENDL;
+ LLSD newPayload;
+ newPayload["list"] = notification["payload"]["list"];
+ LLSD args;
+ args["DUPNAME"] = newName;
+
+ LLNotificationsUtil::add("RenameAutoReplaceList", args, newPayload,
+ boost::bind(&LLFloaterAutoReplaceSettings::callbackListNameConflict, this, _1, _2));
+ }
+ break;
+
+ case LLAutoReplaceSettings::AddListInvalidList:
+ LLNotificationsUtil::add("InvalidAutoReplaceList");
+
+ mSelectedListName.clear();
+ updateListNames();
+ updateListNamesControls();
+ updateReplacementsList();
+ break;
+
+ default:
+ LL_ERRS("AutoReplace") << "invalid AddListResult" << LL_ENDL;
+ }
+ }
+ else
+ {
+ LL_ERRS("AutoReplace") << "adding notification response" << LL_ENDL;
+ }
+ return false;
+}
+
+// callback for the RenameAutoReplaceList notification
+bool LLFloaterAutoReplaceSettings::callbackListNameConflict(const LLSD& notification, const LLSD& response)
+{
+ LLSD newList = notification["payload"]["list"];
+ std::string listName = LLAutoReplaceSettings::getListName(newList);
+
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ switch ( option )
+ {
+ case 0:
+ // Replace current list
+ if ( LLAutoReplaceSettings::AddListOk == mSettings.replaceList(newList) )
+ {
+ LL_INFOS("AutoReplace") << "replaced list '"<<listName<<"'"<<LL_ENDL;
+ mSelectedListName = listName;
+ updateListNames();
+ updateListNamesControls();
+ updateReplacementsList();
+ }
+ else
+ {
+ LL_WARNS("AutoReplace")<<"failed to replace list '"<<listName<<"'"<<LL_ENDL;
+ }
+ break;
+
+ case 1:
+ // Use New Name
+ LL_INFOS("AutoReplace")<<"option 'use new name' selected"<<LL_ENDL;
+ callbackNewListName(notification, response);
+ break;
+
+ default:
+ LL_ERRS("AutoReplace")<<"invalid selected option "<<option<<LL_ENDL;
+ }
+
+ return false;
+}
+
+void LLFloaterAutoReplaceSettings::onDeleteList()
+{
+ std::string listName = mListNames->getSelectedValue().asString();
+ if ( ! listName.empty() )
+ {
+ if ( mSettings.removeReplacementList(listName) )
+ {
+ LL_INFOS("AutoReplace")<<"deleted list '"<<listName<<"'"<<LL_ENDL;
+ mReplacementsList->deleteSelectedItems(); // remove from the scrolling list
+ mSelectedListName.clear();
+ updateListNames();
+ updateListNamesControls();
+ updateReplacementsList();
+ }
+ else
+ {
+ LL_WARNS("AutoReplace")<<"failed to delete list '"<<listName<<"'"<<LL_ENDL;
+ }
+ }
+ else
+ {
+ LL_DEBUGS("AutoReplace")<<"no list selected for delete"<<LL_ENDL;
+ }
+}
+
+void LLFloaterAutoReplaceSettings::onExportList()
+{
+ std::string listName=mListNames->getFirstSelected()->getColumn(0)->getValue().asString();
+ const LLSD* list = mSettings.exportList(listName);
+ std::string listFileName = listName + ".xml";
+ LLFilePicker& picker = LLFilePicker::instance();
+ if( picker.getSaveFile( LLFilePicker::FFSAVE_XML, listFileName) )
+ {
+ llofstream file;
+ file.open(picker.getFirstFile().c_str());
+ LLSDSerialize::toPrettyXML(*list, file);
+ file.close();
+ }
+}
+
+void LLFloaterAutoReplaceSettings::onAddEntry()
+{
+ mPreviousKeyword.clear();
+ mReplacementsList->deselectAllItems(false /* don't call commit */);
+ mKeyword->clear();
+ mReplacement->clear();
+ enableReplacementEntry();
+ mKeyword->setFocus(true);
+}
+
+void LLFloaterAutoReplaceSettings::onSaveEntry()
+{
+ LL_DEBUGS("AutoReplace")<<"called"<<LL_ENDL;
+
+ if ( ! mPreviousKeyword.empty() )
+ {
+ // delete any existing value for the key that was editted
+ LL_INFOS("AutoReplace")
+ << "list '" << mSelectedListName << "' "
+ << "removed '" << mPreviousKeyword
+ << "'" << LL_ENDL;
+ mSettings.removeEntryFromList( mPreviousKeyword, mSelectedListName );
+ }
+
+ LLWString keyword = mKeyword->getWText();
+ LLWString replacement = mReplacement->getWText();
+ if ( mSettings.addEntryToList(keyword, replacement, mSelectedListName) )
+ {
+ // insert the new keyword->replacement pair
+ LL_INFOS("AutoReplace")
+ << "list '" << mSelectedListName << "' "
+ << "added '" << wstring_to_utf8str(keyword)
+ << "' -> '" << wstring_to_utf8str(replacement)
+ << "'" << LL_ENDL;
+
+ updateReplacementsList();
+ }
+ else
+ {
+ LLNotificationsUtil::add("InvalidAutoReplaceEntry");
+ LL_WARNS("AutoReplace")<<"invalid entry "
+ << "keyword '" << wstring_to_utf8str(keyword)
+ << "' replacement '" << wstring_to_utf8str(replacement)
+ << "'" << LL_ENDL;
+ }
+}
+
+void LLFloaterAutoReplaceSettings::onCancel()
+{
+ cleanUp();
+ closeFloater(false /* not quitting */);
+}
+
+void LLFloaterAutoReplaceSettings::onSaveChanges()
+{
+ // put our local copy of the settings into the active copy
+ LLAutoReplace::getInstance()->setSettings( mSettings );
+ // save our local copy of the global feature enable/disable value
+ gSavedSettings.setBOOL("AutoReplace", mEnabled);
+ cleanUp();
+ closeFloater(false /* not quitting */);
+}
+
+void LLFloaterAutoReplaceSettings::cleanUp()
+{
+
+}
+
+bool LLFloaterAutoReplaceSettings::selectedListIsFirst()
+{
+ bool isFirst = false;
+
+ if (!mSelectedListName.empty())
+ {
+ LLSD lists = mSettings.getListNames(); // an Array of Strings
+ LLSD first = lists.get(0);
+ if ( first.isString() && first.asString() == mSelectedListName )
+ {
+ isFirst = true;
+ }
+ }
+ return isFirst;
+}
+
+bool LLFloaterAutoReplaceSettings::selectedListIsLast()
+{
+ bool isLast = false;
+
+ if (!mSelectedListName.empty())
+ {
+ LLSD last;
+ LLSD lists = mSettings.getListNames(); // an Array of Strings
+ for ( LLSD::array_const_iterator list = lists.beginArray(), listEnd = lists.endArray();
+ list != listEnd;
+ list++
+ )
+ {
+ last = *list;
+ }
+ if ( last.isString() && last.asString() == mSelectedListName )
+ {
+ isLast = true;
+ }
+ }
+ return isLast;
+}
+
+/* TBD
+mOldText = getChild<LLLineEditor>("autoreplace_old_text");
+mNewText = getChild<LLLineEditor>("autoreplace_new_text");
+*/
diff --git a/indra/newview/llfloaterautoreplacesettings.h b/indra/newview/llfloaterautoreplacesettings.h
new file mode 100755
index 0000000000..629aea3e3c
--- /dev/null
+++ b/indra/newview/llfloaterautoreplacesettings.h
@@ -0,0 +1,117 @@
+/**
+ * @file llfloaterautoreplacesettings.h
+ * @brief Auto Replace List floater
+ * @copyright Copyright (c) 2011 LordGregGreg Back
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * 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
+ * $/LicenseInfo$
+ */
+
+#ifndef LLFLOATERAUTOREPLACESETTINGS_H
+#define LLFLOATERAUTOREPLACESETTINGS_H
+
+#include "llfloater.h"
+#include "llmediactrl.h"
+#include "llscrolllistctrl.h"
+#include "lllineeditor.h"
+
+#include "llviewerinventory.h"
+#include <boost/bind.hpp>
+#include "llautoreplace.h"
+
+class LLFloaterAutoReplaceSettings : public LLFloater
+{
+public:
+ LLFloaterAutoReplaceSettings(const LLSD& key);
+
+ /*virtual*/ BOOL postBuild();
+ /*virtual*/ void onClose(bool app_quitting);
+
+ void setData(void * data);
+
+private:
+
+ /** @{ @name Local Copies of Settings
+ * These are populated in the postBuild method with the values
+ * current when the floater is instantiated, and then either
+ * discarded when Cancel is pressed, or copied back to the active
+ * settings if Ok is pressed.
+ */
+ bool mEnabled; ///< the global preference for AutoReplace
+ LLAutoReplaceSettings mSettings; ///< settings being modified
+ /** @} */
+
+ /// convenience variable - the name of the currently selected list (if any)
+ std::string mSelectedListName;
+ /// the scrolling list of list names (one column, no headings, order manually controlled)
+ LLScrollListCtrl* mListNames;
+ /// the scroling list of keyword->replacement pairs
+ LLScrollListCtrl* mReplacementsList;
+
+ /// the keyword for the entry editing pane
+ LLLineEditor* mKeyword;
+ /// saved keyword value
+ std::string mPreviousKeyword;
+ /// the replacement for the entry editing pane
+ LLLineEditor* mReplacement;
+
+ /// callback for when the feature enable/disable checkbox changes
+ void onAutoReplaceToggled();
+ /// callback for when an entry in the list of list names is selected
+ void onSelectList();
+
+ void onImportList();
+ void onExportList();
+ void onNewList();
+ void onDeleteList();
+
+ void onListUp();
+ void onListDown();
+
+ void onSelectEntry();
+ void onAddEntry();
+ void onDeleteEntry();
+ void onSaveEntry();
+
+ void onSaveChanges();
+ void onCancel();
+
+ /// updates the contents of the mListNames
+ void updateListNames();
+ /// updates the controls associated with mListNames (depends on whether a name is selected or not)
+ void updateListNamesControls();
+ /// updates the contents of the mReplacementsList
+ void updateReplacementsList();
+ /// enables the components that should only be active when a keyword is selected
+ void enableReplacementEntry();
+ /// disables the components that should only be active when a keyword is selected
+ void disableReplacementEntry();
+
+ /// called from the AddAutoReplaceList notification dialog
+ bool callbackNewListName(const LLSD& notification, const LLSD& response);
+ /// called from the RenameAutoReplaceList notification dialog
+ bool callbackListNameConflict(const LLSD& notification, const LLSD& response);
+
+ bool selectedListIsFirst();
+ bool selectedListIsLast();
+
+ void cleanUp();
+};
+
+#endif // LLFLOATERAUTOREPLACESETTINGS_H
diff --git a/indra/newview/llfloateravatar.cpp b/indra/newview/llfloateravatar.cpp
index bdc5b581a9..bdc5b581a9 100644..100755
--- a/indra/newview/llfloateravatar.cpp
+++ b/indra/newview/llfloateravatar.cpp
diff --git a/indra/newview/llfloateravatar.h b/indra/newview/llfloateravatar.h
index cadc5e4028..cadc5e4028 100644..100755
--- a/indra/newview/llfloateravatar.h
+++ b/indra/newview/llfloateravatar.h
diff --git a/indra/newview/llfloateravatarpicker.cpp b/indra/newview/llfloateravatarpicker.cpp
index 0290e7cdf0..c0afb72cff 100644..100755
--- a/indra/newview/llfloateravatarpicker.cpp
+++ b/indra/newview/llfloateravatarpicker.cpp
@@ -49,6 +49,8 @@
#include "llscrolllistcell.h"
#include "lltabcontainer.h"
#include "lluictrlfactory.h"
+#include "llfocusmgr.h"
+#include "lldraghandle.h"
#include "message.h"
//#include "llsdserialize.h"
@@ -58,11 +60,14 @@ static std::map<LLUUID, LLAvatarName> sAvatarNameMap;
LLFloaterAvatarPicker* LLFloaterAvatarPicker::show(select_callback_t callback,
BOOL allow_multiple,
- BOOL closeOnSelect)
+ BOOL closeOnSelect,
+ BOOL skip_agent,
+ const std::string& name,
+ LLView * frustumOrigin)
{
// *TODO: Use a key to allow this not to be an effective singleton
LLFloaterAvatarPicker* floater =
- LLFloaterReg::showTypedInstance<LLFloaterAvatarPicker>("avatar_picker");
+ LLFloaterReg::showTypedInstance<LLFloaterAvatarPicker>("avatar_picker", LLSD(name));
if (!floater)
{
llwarns << "Cannot instantiate avatar picker" << llendl;
@@ -73,6 +78,7 @@ LLFloaterAvatarPicker* LLFloaterAvatarPicker::show(select_callback_t callback,
floater->setAllowMultiple(allow_multiple);
floater->mNearMeListComplete = FALSE;
floater->mCloseOnSelect = closeOnSelect;
+ floater->mExcludeAgentFromSearchResults = skip_agent;
if (!closeOnSelect)
{
@@ -83,6 +89,11 @@ LLFloaterAvatarPicker* LLFloaterAvatarPicker::show(select_callback_t callback,
floater->getChild<LLButton>("cancel_btn")->setLabel(close_string);
}
+ if(frustumOrigin)
+ {
+ floater->mFrustumOrigin = frustumOrigin->getHandle();
+ }
+
return floater;
}
@@ -91,9 +102,17 @@ LLFloaterAvatarPicker::LLFloaterAvatarPicker(const LLSD& key)
: LLFloater(key),
mNumResultsReturned(0),
mNearMeListComplete(FALSE),
- mCloseOnSelect(FALSE)
+ mCloseOnSelect(FALSE),
+ mContextConeOpacity (0.f),
+ mContextConeInAlpha(0.f),
+ mContextConeOutAlpha(0.f),
+ mContextConeFadeTime(0.f)
{
mCommitCallbackRegistrar.add("Refresh.FriendList", boost::bind(&LLFloaterAvatarPicker::populateFriend, this));
+
+ mContextConeInAlpha = gSavedSettings.getF32("ContextConeInAlpha");
+ mContextConeOutAlpha = gSavedSettings.getF32("ContextConeOutAlpha");
+ mContextConeFadeTime = gSavedSettings.getF32("ContextConeFadeTime");
}
BOOL LLFloaterAvatarPicker::postBuild()
@@ -288,9 +307,9 @@ void LLFloaterAvatarPicker::populateNearMe()
else
{
element["columns"][0]["column"] = "name";
- element["columns"][0]["value"] = av_name.mDisplayName;
+ element["columns"][0]["value"] = av_name.getDisplayName();
element["columns"][1]["column"] = "username";
- element["columns"][1]["value"] = av_name.mUsername;
+ element["columns"][1]["value"] = av_name.getUserName();
sAvatarNameMap[av] = av_name;
}
@@ -338,8 +357,67 @@ void LLFloaterAvatarPicker::populateFriend()
friends_scroller->sortByColumnIndex(0, TRUE);
}
+void LLFloaterAvatarPicker::drawFrustum()
+{
+ if(mFrustumOrigin.get())
+ {
+ LLView * frustumOrigin = mFrustumOrigin.get();
+ LLRect origin_rect;
+ frustumOrigin->localRectToOtherView(frustumOrigin->getLocalRect(), &origin_rect, this);
+ // draw context cone connecting color picker with color swatch in parent floater
+ LLRect local_rect = getLocalRect();
+ if (hasFocus() && frustumOrigin->isInVisibleChain() && mContextConeOpacity > 0.001f)
+ {
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ LLGLEnable(GL_CULL_FACE);
+ gGL.begin(LLRender::QUADS);
+ {
+ gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
+ gGL.vertex2i(origin_rect.mLeft, origin_rect.mTop);
+ gGL.vertex2i(origin_rect.mRight, origin_rect.mTop);
+ gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
+ gGL.vertex2i(local_rect.mRight, local_rect.mTop);
+ gGL.vertex2i(local_rect.mLeft, local_rect.mTop);
+
+ gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
+ gGL.vertex2i(local_rect.mLeft, local_rect.mTop);
+ gGL.vertex2i(local_rect.mLeft, local_rect.mBottom);
+ gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
+ gGL.vertex2i(origin_rect.mLeft, origin_rect.mBottom);
+ gGL.vertex2i(origin_rect.mLeft, origin_rect.mTop);
+
+ gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
+ gGL.vertex2i(local_rect.mRight, local_rect.mBottom);
+ gGL.vertex2i(local_rect.mRight, local_rect.mTop);
+ gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
+ gGL.vertex2i(origin_rect.mRight, origin_rect.mTop);
+ gGL.vertex2i(origin_rect.mRight, origin_rect.mBottom);
+
+ gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
+ gGL.vertex2i(local_rect.mLeft, local_rect.mBottom);
+ gGL.vertex2i(local_rect.mRight, local_rect.mBottom);
+ gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
+ gGL.vertex2i(origin_rect.mRight, origin_rect.mBottom);
+ gGL.vertex2i(origin_rect.mLeft, origin_rect.mBottom);
+ }
+ gGL.end();
+ }
+
+ if (gFocusMgr.childHasMouseCapture(getDragHandle()))
+ {
+ mContextConeOpacity = lerp(mContextConeOpacity, gSavedSettings.getF32("PickerContextOpacity"), LLCriticalDamp::getInterpolant(mContextConeFadeTime));
+ }
+ else
+ {
+ mContextConeOpacity = lerp(mContextConeOpacity, 0.f, LLCriticalDamp::getInterpolant(mContextConeFadeTime));
+ }
+ }
+}
+
void LLFloaterAvatarPicker::draw()
{
+ drawFrustum();
+
// sometimes it is hard to determine when Select/Ok button should be disabled (see LLAvatarActions::shareWithAvatars).
// lets check this via mOkButtonValidateSignal callback periodically.
static LLFrameTimer timer;
@@ -382,8 +460,9 @@ class LLAvatarPickerResponder : public LLHTTPClient::Responder
{
public:
LLUUID mQueryID;
+ std::string mName;
- LLAvatarPickerResponder(const LLUUID& id) : mQueryID(id) { }
+ LLAvatarPickerResponder(const LLUUID& id, const std::string& name) : mQueryID(id), mName(name) { }
/*virtual*/ void completed(U32 status, const std::string& reason, const LLSD& content)
{
@@ -396,7 +475,7 @@ public:
if (isGoodStatus(status) || status == 400)
{
LLFloaterAvatarPicker* floater =
- LLFloaterReg::findTypedInstance<LLFloaterAvatarPicker>("avatar_picker");
+ LLFloaterReg::findTypedInstance<LLFloaterAvatarPicker>("avatar_picker", mName);
if (floater)
{
floater->processResponse(mQueryID, content);
@@ -404,8 +483,7 @@ public:
}
else
{
- llinfos << "avatar picker failed " << status
- << " reason " << reason << llendl;
+ llwarns << "avatar picker failed [status:" << status << "]: " << content << llendl;
}
}
@@ -426,9 +504,7 @@ void LLFloaterAvatarPicker::find()
LLViewerRegion* region = gAgent.getRegion();
url = region->getCapability("AvatarPickerSearch");
// Prefer use of capabilities to search on both SLID and display name
- // but allow display name search to be manually turned off for test
- if (!url.empty()
- && LLAvatarNameCache::useDisplayNames())
+ if (!url.empty())
{
// capability urls don't end in '/', but we need one to parse
// query parameters correctly
@@ -437,9 +513,10 @@ void LLFloaterAvatarPicker::find()
url += "/";
}
url += "?page_size=100&names=";
+ std::replace(text.begin(), text.end(), '.', ' ');
url += LLURI::escape(text);
llinfos << "avatar picker " << url << llendl;
- LLHTTPClient::get(url, new LLAvatarPickerResponder(mQueryID));
+ LLHTTPClient::get(url, new LLAvatarPickerResponder(mQueryID, getKey().asString()));
}
else
{
@@ -581,35 +658,36 @@ void LLFloaterAvatarPicker::processAvatarPickerReply(LLMessageSystem* msg, void*
msg->getUUIDFast( _PREHASH_Data,_PREHASH_AvatarID, avatar_id, i);
msg->getStringFast(_PREHASH_Data,_PREHASH_FirstName, first_name, i);
msg->getStringFast(_PREHASH_Data,_PREHASH_LastName, last_name, i);
-
- std::string avatar_name;
- if (avatar_id.isNull())
- {
- LLStringUtil::format_map_t map;
- map["[TEXT]"] = floater->getChild<LLUICtrl>("Edit")->getValue().asString();
- avatar_name = floater->getString("not_found", map);
- search_results->setEnabled(FALSE);
- floater->getChildView("ok_btn")->setEnabled(FALSE);
- }
- else
+
+ if (avatar_id != agent_id || !floater->isExcludeAgentFromSearchResults()) // exclude agent from search results?
{
- avatar_name = LLCacheName::buildFullName(first_name, last_name);
- search_results->setEnabled(TRUE);
- found_one = TRUE;
+ std::string avatar_name;
+ if (avatar_id.isNull())
+ {
+ LLStringUtil::format_map_t map;
+ map["[TEXT]"] = floater->getChild<LLUICtrl>("Edit")->getValue().asString();
+ avatar_name = floater->getString("not_found", map);
+ search_results->setEnabled(FALSE);
+ floater->getChildView("ok_btn")->setEnabled(FALSE);
+ }
+ else
+ {
+ avatar_name = LLCacheName::buildFullName(first_name, last_name);
+ search_results->setEnabled(TRUE);
+ found_one = TRUE;
- LLAvatarName av_name;
- av_name.mLegacyFirstName = first_name;
- av_name.mLegacyLastName = last_name;
- av_name.mDisplayName = avatar_name;
- const LLUUID& agent_id = avatar_id;
- sAvatarNameMap[agent_id] = av_name;
+ LLAvatarName av_name;
+ av_name.fromString(avatar_name);
+ const LLUUID& agent_id = avatar_id;
+ sAvatarNameMap[agent_id] = av_name;
+ }
+ LLSD element;
+ element["id"] = avatar_id; // value
+ element["columns"][0]["column"] = "name";
+ element["columns"][0]["value"] = avatar_name;
+ search_results->addElement(element);
}
- LLSD element;
- element["id"] = avatar_id; // value
- element["columns"][0]["column"] = "name";
- element["columns"][0]["value"] = avatar_name;
- search_results->addElement(element);
}
if (found_one)
@@ -624,52 +702,63 @@ void LLFloaterAvatarPicker::processAvatarPickerReply(LLMessageSystem* msg, void*
void LLFloaterAvatarPicker::processResponse(const LLUUID& query_id, const LLSD& content)
{
// Check for out-of-date query
- if (query_id != mQueryID) return;
+ if (query_id == mQueryID)
+ {
+ LLScrollListCtrl* search_results = getChild<LLScrollListCtrl>("SearchResults");
- LLScrollListCtrl* search_results = getChild<LLScrollListCtrl>("SearchResults");
+ LLSD agents = content["agents"];
+
+ // clear "Searching" label on first results
+ search_results->deleteAllItems();
- LLSD agents = content["agents"];
- if (agents.size() == 0)
- {
- LLStringUtil::format_map_t map;
- map["[TEXT]"] = childGetText("Edit");
LLSD item;
- item["id"] = LLUUID::null;
- item["columns"][0]["column"] = "name";
- item["columns"][0]["value"] = getString("not_found", map);
- search_results->addElement(item);
- search_results->setEnabled(false);
- getChildView("ok_btn")->setEnabled(false);
- return;
- }
+ LLSD::array_const_iterator it = agents.beginArray();
+ for ( ; it != agents.endArray(); ++it)
+ {
+ const LLSD& row = *it;
+ if (row["id"].asUUID() != gAgent.getID() || !mExcludeAgentFromSearchResults)
+ {
+ item["id"] = row["id"];
+ LLSD& columns = item["columns"];
+ columns[0]["column"] = "name";
+ columns[0]["value"] = row["display_name"];
+ columns[1]["column"] = "username";
+ columns[1]["value"] = row["username"];
+ search_results->addElement(item);
+
+ // add the avatar name to our list
+ LLAvatarName avatar_name;
+ avatar_name.fromLLSD(row);
+ sAvatarNameMap[row["id"].asUUID()] = avatar_name;
+ }
+ }
- // clear "Searching" label on first results
- search_results->deleteAllItems();
-
- LLSD item;
- LLSD::array_const_iterator it = agents.beginArray();
- for ( ; it != agents.endArray(); ++it)
- {
- const LLSD& row = *it;
- item["id"] = row["id"];
- LLSD& columns = item["columns"];
- columns[0]["column"] = "name";
- columns[0]["value"] = row["display_name"];
- columns[1]["column"] = "username";
- columns[1]["value"] = row["username"];
- search_results->addElement(item);
-
- // add the avatar name to our list
- LLAvatarName avatar_name;
- avatar_name.fromLLSD(row);
- sAvatarNameMap[row["id"].asUUID()] = avatar_name;
- }
-
- getChildView("ok_btn")->setEnabled(true);
- search_results->setEnabled(true);
- search_results->selectFirstItem();
- onList();
- search_results->setFocus(TRUE);
+ if (search_results->isEmpty())
+ {
+ LLStringUtil::format_map_t map;
+ map["[TEXT]"] = childGetText("Edit");
+ LLSD item;
+ item["id"] = LLUUID::null;
+ item["columns"][0]["column"] = "name";
+ item["columns"][0]["value"] = getString("not_found", map);
+ search_results->addElement(item);
+ search_results->setEnabled(false);
+ getChildView("ok_btn")->setEnabled(false);
+ }
+ else
+ {
+ getChildView("ok_btn")->setEnabled(true);
+ search_results->setEnabled(true);
+ search_results->sortByColumnIndex(1, TRUE);
+ std::string text = getChild<LLUICtrl>("Edit")->getValue().asString();
+ if (!search_results->selectItemByLabel(text, TRUE, 1))
+ {
+ search_results->selectFirstItem();
+ }
+ onList();
+ search_results->setFocus(TRUE);
+ }
+ }
}
//static
@@ -735,7 +824,14 @@ bool LLFloaterAvatarPicker::isSelectBtnEnabled()
uuid_vec_t avatar_ids;
std::vector<LLAvatarName> avatar_names;
getSelectedAvatarData(list, avatar_ids, avatar_names);
- return mOkButtonValidateSignal(avatar_ids);
+ if (avatar_ids.size() >= 1)
+ {
+ ret_val = mOkButtonValidateSignal(avatar_ids);
+ }
+ else
+ {
+ ret_val = false;
+ }
}
}
diff --git a/indra/newview/llfloateravatarpicker.h b/indra/newview/llfloateravatarpicker.h
index 96c039443a..ed3e51c56f 100644..100755
--- a/indra/newview/llfloateravatarpicker.h
+++ b/indra/newview/llfloateravatarpicker.h
@@ -34,7 +34,7 @@
class LLAvatarName;
class LLScrollListCtrl;
-class LLFloaterAvatarPicker : public LLFloater
+class LLFloaterAvatarPicker :public LLFloater
{
public:
typedef boost::signals2::signal<bool(const uuid_vec_t&), boost_boolean_combiner> validate_signal_t;
@@ -45,7 +45,10 @@ public:
// Call this to select an avatar.
static LLFloaterAvatarPicker* show(select_callback_t callback,
BOOL allow_multiple = FALSE,
- BOOL closeOnSelect = FALSE);
+ BOOL closeOnSelect = FALSE,
+ BOOL skip_agent = FALSE,
+ const std::string& name = "",
+ LLView * frustumOrigin = NULL);
LLFloaterAvatarPicker(const LLSD& key);
virtual ~LLFloaterAvatarPicker();
@@ -63,6 +66,7 @@ public:
std::string& tooltip_msg);
void openFriendsTab();
+ BOOL isExcludeAgentFromSearchResults() {return mExcludeAgentFromSearchResults;}
private:
void editKeystroke(class LLLineEditor* caller, void* user_data);
@@ -84,13 +88,20 @@ private:
void setAllowMultiple(BOOL allow_multiple);
LLScrollListCtrl* getActiveList();
+ void drawFrustum();
virtual void draw();
virtual BOOL handleKeyHere(KEY key, MASK mask);
LLUUID mQueryID;
- int mNumResultsReturned;
+ int mNumResultsReturned;
BOOL mNearMeListComplete;
BOOL mCloseOnSelect;
+ BOOL mExcludeAgentFromSearchResults;
+ LLHandle <LLView> mFrustumOrigin;
+ F32 mContextConeOpacity;
+ F32 mContextConeInAlpha;
+ F32 mContextConeOutAlpha;
+ F32 mContextConeFadeTime;
validate_signal_t mOkButtonValidateSignal;
select_callback_t mSelectionCallback;
diff --git a/indra/newview/llfloateravatartextures.cpp b/indra/newview/llfloateravatartextures.cpp
index 4e10b4fc2c..048837acfe 100644..100755
--- a/indra/newview/llfloateravatartextures.cpp
+++ b/indra/newview/llfloateravatartextures.cpp
@@ -32,12 +32,13 @@
#include "llagent.h"
#include "llagentwearables.h"
+#include "llviewerwearable.h"
#include "lltexturectrl.h"
#include "lluictrlfactory.h"
#include "llviewerobjectlist.h"
#include "llvoavatarself.h"
-using namespace LLVOAvatarDefines;
+using namespace LLAvatarAppearanceDefines;
LLFloaterAvatarTextures::LLFloaterAvatarTextures(const LLSD& id)
: LLFloater(id),
@@ -53,7 +54,7 @@ BOOL LLFloaterAvatarTextures::postBuild()
{
for (U32 i=0; i < TEX_NUM_INDICES; i++)
{
- const std::string tex_name = LLVOAvatarDictionary::getInstance()->getTexture(ETextureIndex(i))->mName;
+ const std::string tex_name = LLAvatarAppearanceDictionary::getInstance()->getTexture(ETextureIndex(i))->mName;
mTextures[i] = getChild<LLTextureCtrl>(tex_name);
}
mTitle = getTitle();
@@ -75,13 +76,13 @@ static void update_texture_ctrl(LLVOAvatar* avatarp,
ETextureIndex te)
{
LLUUID id = IMG_DEFAULT_AVATAR;
- const LLVOAvatarDictionary::TextureEntry* tex_entry = LLVOAvatarDictionary::getInstance()->getTexture(te);
+ const LLAvatarAppearanceDictionary::TextureEntry* tex_entry = LLAvatarAppearanceDictionary::getInstance()->getTexture(te);
if (tex_entry->mIsLocalTexture)
{
if (avatarp->isSelf())
{
const LLWearableType::EType wearable_type = tex_entry->mWearableType;
- LLWearable *wearable = gAgentWearables.getWearable(wearable_type, 0);
+ LLViewerWearable *wearable = gAgentWearables.getViewerWearable(wearable_type, 0);
if (wearable)
{
LLLocalTextureObject *lto = wearable->getLocalTextureObject(te);
@@ -163,17 +164,17 @@ void LLFloaterAvatarTextures::onClickDump(void* data)
const LLTextureEntry* te = avatarp->getTE(i);
if (!te) continue;
- const LLVOAvatarDictionary::TextureEntry* tex_entry = LLVOAvatarDictionary::getInstance()->getTexture((ETextureIndex)(i));
+ const LLAvatarAppearanceDictionary::TextureEntry* tex_entry = LLAvatarAppearanceDictionary::getInstance()->getTexture((ETextureIndex)(i));
if (!tex_entry)
continue;
if (LLVOAvatar::isIndexLocalTexture((ETextureIndex)i))
{
LLUUID id = IMG_DEFAULT_AVATAR;
- LLWearableType::EType wearable_type = LLVOAvatarDictionary::getInstance()->getTEWearableType((ETextureIndex)i);
+ LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getInstance()->getTEWearableType((ETextureIndex)i);
if (avatarp->isSelf())
{
- LLWearable *wearable = gAgentWearables.getWearable(wearable_type, 0);
+ LLViewerWearable *wearable = gAgentWearables.getViewerWearable(wearable_type, 0);
if (wearable)
{
LLLocalTextureObject *lto = wearable->getLocalTextureObject(i);
diff --git a/indra/newview/llfloateravatartextures.h b/indra/newview/llfloateravatartextures.h
index 85ff545855..02474a10e1 100644..100755
--- a/indra/newview/llfloateravatartextures.h
+++ b/indra/newview/llfloateravatartextures.h
@@ -30,7 +30,7 @@
#include "llfloater.h"
#include "lluuid.h"
#include "llstring.h"
-#include "llvoavatardefines.h"
+#include "llavatarappearancedefines.h"
class LLTextureCtrl;
@@ -51,7 +51,7 @@ private:
private:
LLUUID mID;
std::string mTitle;
- LLTextureCtrl* mTextures[LLVOAvatarDefines::TEX_NUM_INDICES];
+ LLTextureCtrl* mTextures[LLAvatarAppearanceDefines::TEX_NUM_INDICES];
};
#endif
diff --git a/indra/newview/llfloaterbeacons.cpp b/indra/newview/llfloaterbeacons.cpp
index 316294a477..316294a477 100644..100755
--- a/indra/newview/llfloaterbeacons.cpp
+++ b/indra/newview/llfloaterbeacons.cpp
diff --git a/indra/newview/llfloaterbeacons.h b/indra/newview/llfloaterbeacons.h
index 47d0696296..47d0696296 100644..100755
--- a/indra/newview/llfloaterbeacons.h
+++ b/indra/newview/llfloaterbeacons.h
diff --git a/indra/newview/llfloaterbuildoptions.cpp b/indra/newview/llfloaterbuildoptions.cpp
index 1b65d8d683..1b65d8d683 100644..100755
--- a/indra/newview/llfloaterbuildoptions.cpp
+++ b/indra/newview/llfloaterbuildoptions.cpp
diff --git a/indra/newview/llfloaterbuildoptions.h b/indra/newview/llfloaterbuildoptions.h
index 02c56cb6a9..02c56cb6a9 100644..100755
--- a/indra/newview/llfloaterbuildoptions.h
+++ b/indra/newview/llfloaterbuildoptions.h
diff --git a/indra/newview/llfloaterbulkpermission.cpp b/indra/newview/llfloaterbulkpermission.cpp
index 90f40628a8..76f62a7880 100644..100755
--- a/indra/newview/llfloaterbulkpermission.cpp
+++ b/indra/newview/llfloaterbulkpermission.cpp
@@ -57,6 +57,7 @@ LLFloaterBulkPermission::LLFloaterBulkPermission(const LLSD& seed)
mDone(FALSE)
{
mID.generate();
+ mCommitCallbackRegistrar.add("BulkPermission.Ok", boost::bind(&LLFloaterBulkPermission::onOkBtn, this));
mCommitCallbackRegistrar.add("BulkPermission.Apply", boost::bind(&LLFloaterBulkPermission::onApplyBtn, this));
mCommitCallbackRegistrar.add("BulkPermission.Close", boost::bind(&LLFloaterBulkPermission::onCloseBtn, this));
mCommitCallbackRegistrar.add("BulkPermission.CheckAll", boost::bind(&LLFloaterBulkPermission::onCheckAll, this));
@@ -66,6 +67,21 @@ LLFloaterBulkPermission::LLFloaterBulkPermission(const LLSD& seed)
BOOL LLFloaterBulkPermission::postBuild()
{
+ mBulkChangeIncludeAnimations = gSavedSettings.getBOOL("BulkChangeIncludeAnimations");
+ mBulkChangeIncludeBodyParts = gSavedSettings.getBOOL("BulkChangeIncludeBodyParts");
+ mBulkChangeIncludeClothing = gSavedSettings.getBOOL("BulkChangeIncludeClothing");
+ mBulkChangeIncludeGestures = gSavedSettings.getBOOL("BulkChangeIncludeGestures");
+ mBulkChangeIncludeNotecards = gSavedSettings.getBOOL("BulkChangeIncludeNotecards");
+ mBulkChangeIncludeObjects = gSavedSettings.getBOOL("BulkChangeIncludeObjects");
+ mBulkChangeIncludeScripts = gSavedSettings.getBOOL("BulkChangeIncludeScripts");
+ mBulkChangeIncludeSounds = gSavedSettings.getBOOL("BulkChangeIncludeSounds");
+ mBulkChangeIncludeTextures = gSavedSettings.getBOOL("BulkChangeIncludeTextures");
+ mBulkChangeShareWithGroup = gSavedSettings.getBOOL("BulkChangeShareWithGroup");
+ mBulkChangeEveryoneCopy = gSavedSettings.getBOOL("BulkChangeEveryoneCopy");
+ mBulkChangeNextOwnerModify = gSavedSettings.getBOOL("BulkChangeNextOwnerModify");
+ mBulkChangeNextOwnerCopy = gSavedSettings.getBOOL("BulkChangeNextOwnerCopy");
+ mBulkChangeNextOwnerTransfer = gSavedSettings.getBOOL("BulkChangeNextOwnerTransfer");
+
return TRUE;
}
@@ -144,6 +160,12 @@ void LLFloaterBulkPermission::inventoryChanged(LLViewerObject* viewer_object,
}
}
+void LLFloaterBulkPermission::onOkBtn()
+{
+ doApply();
+ closeFloater();
+}
+
void LLFloaterBulkPermission::onApplyBtn()
{
doApply();
@@ -151,6 +173,20 @@ void LLFloaterBulkPermission::onApplyBtn()
void LLFloaterBulkPermission::onCloseBtn()
{
+ gSavedSettings.setBOOL("BulkChangeIncludeAnimations", mBulkChangeIncludeAnimations);
+ gSavedSettings.setBOOL("BulkChangeIncludeBodyParts", mBulkChangeIncludeBodyParts);
+ gSavedSettings.setBOOL("BulkChangeIncludeClothing", mBulkChangeIncludeClothing);
+ gSavedSettings.setBOOL("BulkChangeIncludeGestures", mBulkChangeIncludeGestures);
+ gSavedSettings.setBOOL("BulkChangeIncludeNotecards", mBulkChangeIncludeNotecards);
+ gSavedSettings.setBOOL("BulkChangeIncludeObjects", mBulkChangeIncludeObjects);
+ gSavedSettings.setBOOL("BulkChangeIncludeScripts", mBulkChangeIncludeScripts);
+ gSavedSettings.setBOOL("BulkChangeIncludeSounds", mBulkChangeIncludeSounds);
+ gSavedSettings.setBOOL("BulkChangeIncludeTextures", mBulkChangeIncludeTextures);
+ gSavedSettings.setBOOL("BulkChangeShareWithGroup", mBulkChangeShareWithGroup);
+ gSavedSettings.setBOOL("BulkChangeEveryoneCopy", mBulkChangeEveryoneCopy);
+ gSavedSettings.setBOOL("BulkChangeNextOwnerModify", mBulkChangeNextOwnerModify);
+ gSavedSettings.setBOOL("BulkChangeNextOwnerCopy", mBulkChangeNextOwnerCopy);
+ gSavedSettings.setBOOL("BulkChangeNextOwnerTransfer", mBulkChangeNextOwnerTransfer);
closeFloater();
}
@@ -336,8 +372,6 @@ void LLFloaterBulkPermission::handleInventory(LLViewerObject* viewer_obj, LLInve
void LLFloaterBulkPermission::updateInventory(LLViewerObject* object, LLViewerInventoryItem* item, U8 key, bool is_new)
{
- LLMemType mt(LLMemType::MTYPE_OBJECT);
-
// This slices the object into what we're concerned about on the viewer.
// The simulator will take the permissions and transfer ownership.
LLPointer<LLViewerInventoryItem> task_item =
diff --git a/indra/newview/llfloaterbulkpermission.h b/indra/newview/llfloaterbulkpermission.h
index 7dd05df7ee..25e76eca65 100644..100755
--- a/indra/newview/llfloaterbulkpermission.h
+++ b/indra/newview/llfloaterbulkpermission.h
@@ -72,6 +72,7 @@ private:
bool is_new);
void onCloseBtn();
+ void onOkBtn();
void onApplyBtn();
void onCommitCopy();
void onCheckAll() { doCheckUncheckAll(TRUE); }
@@ -94,6 +95,21 @@ private:
LLUUID mCurrentObjectID;
BOOL mDone;
+ bool mBulkChangeIncludeAnimations;
+ bool mBulkChangeIncludeBodyParts;
+ bool mBulkChangeIncludeClothing;
+ bool mBulkChangeIncludeGestures;
+ bool mBulkChangeIncludeNotecards;
+ bool mBulkChangeIncludeObjects;
+ bool mBulkChangeIncludeScripts;
+ bool mBulkChangeIncludeSounds;
+ bool mBulkChangeIncludeTextures;
+ bool mBulkChangeShareWithGroup;
+ bool mBulkChangeEveryoneCopy;
+ bool mBulkChangeNextOwnerModify;
+ bool mBulkChangeNextOwnerCopy;
+ bool mBulkChangeNextOwnerTransfer;
+
LLUUID mID;
const char* mStartString;
diff --git a/indra/newview/llfloaterbump.cpp b/indra/newview/llfloaterbump.cpp
index eeb81085bb..eeb81085bb 100644..100755
--- a/indra/newview/llfloaterbump.cpp
+++ b/indra/newview/llfloaterbump.cpp
diff --git a/indra/newview/llfloaterbump.h b/indra/newview/llfloaterbump.h
index 5acab6da8c..5acab6da8c 100644..100755
--- a/indra/newview/llfloaterbump.h
+++ b/indra/newview/llfloaterbump.h
diff --git a/indra/newview/llfloaterbuy.cpp b/indra/newview/llfloaterbuy.cpp
index 087b0007e1..087b0007e1 100644..100755
--- a/indra/newview/llfloaterbuy.cpp
+++ b/indra/newview/llfloaterbuy.cpp
diff --git a/indra/newview/llfloaterbuy.h b/indra/newview/llfloaterbuy.h
index 3ec642dee1..3ec642dee1 100644..100755
--- a/indra/newview/llfloaterbuy.h
+++ b/indra/newview/llfloaterbuy.h
diff --git a/indra/newview/llfloaterbuycontents.cpp b/indra/newview/llfloaterbuycontents.cpp
index bca4b5e447..aa6ace2a61 100644..100755
--- a/indra/newview/llfloaterbuycontents.cpp
+++ b/indra/newview/llfloaterbuycontents.cpp
@@ -40,6 +40,7 @@
#include "llcheckboxctrl.h"
#include "llinventorydefines.h"
#include "llinventoryfunctions.h"
+#include "llinventoryicon.h"
#include "llinventorymodel.h" // for gInventory
#include "llfirstuse.h"
#include "llfloaterreg.h"
@@ -80,6 +81,7 @@ BOOL LLFloaterBuyContents::postBuild()
LLFloaterBuyContents::~LLFloaterBuyContents()
{
+ removeVOInventoryListener();
}
@@ -147,23 +149,26 @@ void LLFloaterBuyContents::inventoryChanged(LLViewerObject* obj,
return;
}
- if (!inv)
+ LLScrollListCtrl* item_list = getChild<LLScrollListCtrl>("item_list");
+ if (!item_list)
{
- llwarns << "No inventory in LLFloaterBuyContents::inventoryChanged"
- << llendl;
removeVOInventoryListener();
return;
}
- LLCtrlListInterface *item_list = childGetListInterface("item_list");
- if (!item_list)
+ item_list->deleteAllItems();
+
+ if (!inv)
{
- removeVOInventoryListener();
+ llwarns << "No inventory in LLFloaterBuyContents::inventoryChanged"
+ << llendl;
+
return;
}
// default to turning off the buy button.
- getChildView("buy_btn")->setEnabled(FALSE);
+ LLView* buy_btn = getChildView("buy_btn");
+ buy_btn->setEnabled(FALSE);
LLUUID owner_id;
BOOL is_group_owned;
@@ -204,7 +209,7 @@ void LLFloaterBuyContents::inventoryChanged(LLViewerObject* obj,
// There will be at least one item shown in the display, so go
// ahead and enable the buy button.
- getChildView("buy_btn")->setEnabled(TRUE);
+ buy_btn->setEnabled(TRUE);
// Create the line in the list
LLSD row;
@@ -255,8 +260,6 @@ void LLFloaterBuyContents::inventoryChanged(LLViewerObject* obj,
getChildView("wear_check")->setEnabled(TRUE);
getChild<LLUICtrl>("wear_check")->setValue(LLSD(false) );
}
-
- removeVOInventoryListener();
}
diff --git a/indra/newview/llfloaterbuycontents.h b/indra/newview/llfloaterbuycontents.h
index 19393fb6af..19393fb6af 100644..100755
--- a/indra/newview/llfloaterbuycontents.h
+++ b/indra/newview/llfloaterbuycontents.h
diff --git a/indra/newview/llfloaterbuycurrency.cpp b/indra/newview/llfloaterbuycurrency.cpp
index e21a8594bc..e21a8594bc 100644..100755
--- a/indra/newview/llfloaterbuycurrency.cpp
+++ b/indra/newview/llfloaterbuycurrency.cpp
diff --git a/indra/newview/llfloaterbuycurrency.h b/indra/newview/llfloaterbuycurrency.h
index 7ff6c42384..7ff6c42384 100644..100755
--- a/indra/newview/llfloaterbuycurrency.h
+++ b/indra/newview/llfloaterbuycurrency.h
diff --git a/indra/newview/llfloaterbuycurrencyhtml.cpp b/indra/newview/llfloaterbuycurrencyhtml.cpp
index 013cf74c7b..013cf74c7b 100644..100755
--- a/indra/newview/llfloaterbuycurrencyhtml.cpp
+++ b/indra/newview/llfloaterbuycurrencyhtml.cpp
diff --git a/indra/newview/llfloaterbuycurrencyhtml.h b/indra/newview/llfloaterbuycurrencyhtml.h
index 6b1fc53f1f..6b1fc53f1f 100644..100755
--- a/indra/newview/llfloaterbuycurrencyhtml.h
+++ b/indra/newview/llfloaterbuycurrencyhtml.h
diff --git a/indra/newview/llfloaterbuyland.cpp b/indra/newview/llfloaterbuyland.cpp
index 8223e89b64..42857b2aa2 100644..100755
--- a/indra/newview/llfloaterbuyland.cpp
+++ b/indra/newview/llfloaterbuyland.cpp
@@ -538,7 +538,7 @@ void LLFloaterBuyLandUI::updateCovenantInfo()
LLTextBox* resellable_clause = getChild<LLTextBox>("resellable_clause");
if (resellable_clause)
{
- if (region->getRegionFlags() & REGION_FLAGS_BLOCK_LAND_RESELL)
+ if (region->getRegionFlag(REGION_FLAGS_BLOCK_LAND_RESELL))
{
resellable_clause->setText(getString("can_not_resell"));
}
@@ -551,7 +551,7 @@ void LLFloaterBuyLandUI::updateCovenantInfo()
LLTextBox* changeable_clause = getChild<LLTextBox>("changeable_clause");
if (changeable_clause)
{
- if (region->getRegionFlags() & REGION_FLAGS_ALLOW_PARCEL_CHANGES)
+ if (region->getRegionFlag(REGION_FLAGS_ALLOW_PARCEL_CHANGES))
{
changeable_clause->setText(getString("can_change"));
}
diff --git a/indra/newview/llfloaterbuyland.h b/indra/newview/llfloaterbuyland.h
index 424f6f6616..424f6f6616 100644..100755
--- a/indra/newview/llfloaterbuyland.h
+++ b/indra/newview/llfloaterbuyland.h
diff --git a/indra/newview/llfloaterbvhpreview.cpp b/indra/newview/llfloaterbvhpreview.cpp
index 720c2cbeea..a992443ce1 100644..100755
--- a/indra/newview/llfloaterbvhpreview.cpp
+++ b/indra/newview/llfloaterbvhpreview.cpp
@@ -416,16 +416,20 @@ void LLFloaterBvhPreview::draw()
//-----------------------------------------------------------------------------
void LLFloaterBvhPreview::resetMotion()
{
+ if (!mAnimPreview)
+ return;
+
LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar();
BOOL paused = avatarp->areAnimationsPaused();
- // *TODO: Fix awful casting hack
- LLKeyframeMotion* motionp = (LLKeyframeMotion*)avatarp->findMotion(mMotionID);
-
- // Set emotion
- std::string emote = getChild<LLUICtrl>("emote_combo")->getValue().asString();
- motionp->setEmote(mIDList[emote]);
-
+ LLKeyframeMotion* motionp = dynamic_cast<LLKeyframeMotion*>(avatarp->findMotion(mMotionID));
+ if( motionp )
+ {
+ // Set emotion
+ std::string emote = getChild<LLUICtrl>("emote_combo")->getValue().asString();
+ motionp->setEmote(mIDList[emote]);
+ }
+
LLUUID base_id = mIDList[getChild<LLUICtrl>("preview_base_anim")->getValue().asString()];
avatarp->deactivateAllMotions();
avatarp->startMotion(mMotionID, 0.0f);
@@ -435,8 +439,12 @@ void LLFloaterBvhPreview::resetMotion()
// Set pose
std::string handpose = getChild<LLUICtrl>("hand_pose_combo")->getValue().asString();
avatarp->startMotion( ANIM_AGENT_HAND_MOTION, 0.0f );
- motionp->setHandPose(LLHandMotion::getHandPose(handpose));
+ if( motionp )
+ {
+ motionp->setHandPose(LLHandMotion::getHandPose(handpose));
+ }
+
if (paused)
{
mPauseRequest = avatarp->requestPause();
@@ -535,6 +543,9 @@ BOOL LLFloaterBvhPreview::handleHover(S32 x, S32 y, MASK mask)
//-----------------------------------------------------------------------------
BOOL LLFloaterBvhPreview::handleScrollWheel(S32 x, S32 y, S32 clicks)
{
+ if (!mAnimPreview)
+ return false;
+
mAnimPreview->zoom((F32)clicks * -0.2f);
mAnimPreview->requestUpdate();
@@ -670,7 +681,7 @@ void LLFloaterBvhPreview::onCommitBaseAnim()
//-----------------------------------------------------------------------------
void LLFloaterBvhPreview::onCommitLoop()
{
- if (!getEnabled())
+ if (!getEnabled() || !mAnimPreview)
return;
LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar();
@@ -689,7 +700,7 @@ void LLFloaterBvhPreview::onCommitLoop()
//-----------------------------------------------------------------------------
void LLFloaterBvhPreview::onCommitLoopIn()
{
- if (!getEnabled())
+ if (!getEnabled() || !mAnimPreview)
return;
LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar();
@@ -709,7 +720,7 @@ void LLFloaterBvhPreview::onCommitLoopIn()
//-----------------------------------------------------------------------------
void LLFloaterBvhPreview::onCommitLoopOut()
{
- if (!getEnabled())
+ if (!getEnabled() || !mAnimPreview)
return;
LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar();
@@ -729,7 +740,7 @@ void LLFloaterBvhPreview::onCommitLoopOut()
//-----------------------------------------------------------------------------
void LLFloaterBvhPreview::onCommitName()
{
- if (!getEnabled())
+ if (!getEnabled() || !mAnimPreview)
return;
LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar();
@@ -770,7 +781,7 @@ void LLFloaterBvhPreview::onCommitEmote()
//-----------------------------------------------------------------------------
void LLFloaterBvhPreview::onCommitPriority()
{
- if (!getEnabled())
+ if (!getEnabled() || !mAnimPreview)
return;
LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar();
@@ -784,7 +795,7 @@ void LLFloaterBvhPreview::onCommitPriority()
//-----------------------------------------------------------------------------
void LLFloaterBvhPreview::onCommitEaseIn()
{
- if (!getEnabled())
+ if (!getEnabled() || !mAnimPreview)
return;
LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar();
@@ -799,7 +810,7 @@ void LLFloaterBvhPreview::onCommitEaseIn()
//-----------------------------------------------------------------------------
void LLFloaterBvhPreview::onCommitEaseOut()
{
- if (!getEnabled())
+ if (!getEnabled() || !mAnimPreview)
return;
LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar();
@@ -814,7 +825,7 @@ void LLFloaterBvhPreview::onCommitEaseOut()
//-----------------------------------------------------------------------------
bool LLFloaterBvhPreview::validateEaseIn(const LLSD& data)
{
- if (!getEnabled())
+ if (!getEnabled() || !mAnimPreview)
return false;
LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar();
@@ -834,7 +845,7 @@ bool LLFloaterBvhPreview::validateEaseIn(const LLSD& data)
//-----------------------------------------------------------------------------
bool LLFloaterBvhPreview::validateEaseOut(const LLSD& data)
{
- if (!getEnabled())
+ if (!getEnabled() || !mAnimPreview)
return false;
LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar();
@@ -1091,12 +1102,12 @@ BOOL LLPreviewAnimation::render()
gGL.flush();
- LLVector3 target_pos = avatarp->mRoot.getWorldPosition();
+ LLVector3 target_pos = avatarp->mRoot->getWorldPosition();
LLQuaternion camera_rot = LLQuaternion(mCameraPitch, LLVector3::y_axis) *
LLQuaternion(mCameraYaw, LLVector3::z_axis);
- LLQuaternion av_rot = avatarp->mRoot.getWorldRotation() * camera_rot;
+ LLQuaternion av_rot = avatarp->mRoot->getWorldRotation() * camera_rot;
LLViewerCamera::getInstance()->setOriginAndLookAt(
target_pos + ((LLVector3(mCameraDistance, 0.f, 0.f) + mCameraOffset) * av_rot), // camera
LLVector3::z_axis, // up
@@ -1118,9 +1129,13 @@ BOOL LLPreviewAnimation::render()
LLVertexBuffer::unbind();
LLGLDepthTest gls_depth(GL_TRUE);
- LLDrawPoolAvatar *avatarPoolp = (LLDrawPoolAvatar *)avatarp->mDrawable->getFace(0)->getPool();
- avatarp->dirtyMesh();
- avatarPoolp->renderAvatars(avatarp); // renders only one avatar
+ LLFace* face = avatarp->mDrawable->getFace(0);
+ if (face)
+ {
+ LLDrawPoolAvatar *avatarPoolp = (LLDrawPoolAvatar *)face->getPool();
+ avatarp->dirtyMesh();
+ avatarPoolp->renderAvatars(avatarp); // renders only one avatar
+ }
}
gGL.color4f(1,1,1,1);
diff --git a/indra/newview/llfloaterbvhpreview.h b/indra/newview/llfloaterbvhpreview.h
index b81cc6e3a5..b81cc6e3a5 100644..100755
--- a/indra/newview/llfloaterbvhpreview.h
+++ b/indra/newview/llfloaterbvhpreview.h
diff --git a/indra/newview/llfloatercamera.cpp b/indra/newview/llfloatercamera.cpp
index 21b58d3e3d..c85d048c5a 100644..100755
--- a/indra/newview/llfloatercamera.cpp
+++ b/indra/newview/llfloatercamera.cpp
@@ -330,6 +330,10 @@ void LLFloaterCamera::onClose(bool app_quitting)
//We don't care of camera mode if app is quitting
if(app_quitting)
return;
+ // It is necessary to reset mCurrMode to CAMERA_CTRL_MODE_PAN so
+ // to avoid seeing an empty floater when reopening the control.
+ if (mCurrMode == CAMERA_CTRL_MODE_FREE_CAMERA)
+ mCurrMode = CAMERA_CTRL_MODE_PAN;
// When mCurrMode is in CAMERA_CTRL_MODE_PAN
// switchMode won't modify mPrevMode, so force it here.
// It is needed to correctly return to previous mode on open, see EXT-2727.
diff --git a/indra/newview/llfloatercamera.h b/indra/newview/llfloatercamera.h
index 4d6d03f22d..4d6d03f22d 100644..100755
--- a/indra/newview/llfloatercamera.h
+++ b/indra/newview/llfloatercamera.h
diff --git a/indra/newview/llfloaterchatvoicevolume.cpp b/indra/newview/llfloaterchatvoicevolume.cpp
new file mode 100755
index 0000000000..3c76a3a43c
--- /dev/null
+++ b/indra/newview/llfloaterchatvoicevolume.cpp
@@ -0,0 +1,44 @@
+/**
+ * @file llfloaterchatvoicevolume.cpp
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 "llfloaterchatvoicevolume.h"
+
+LLFloaterChatVoiceVolume::LLFloaterChatVoiceVolume(const LLSD& key)
+: LLInspect(key)
+{
+}
+
+void LLFloaterChatVoiceVolume::onOpen(const LLSD& key)
+{
+ LLInspect::onOpen(key);
+ LLUI::positionViewNearMouse(this);
+}
+
+LLFloaterChatVoiceVolume::~LLFloaterChatVoiceVolume()
+{
+ LLTransientFloaterMgr::getInstance()->removeControlView(this);
+};
diff --git a/indra/newview/llfloaterchatvoicevolume.h b/indra/newview/llfloaterchatvoicevolume.h
new file mode 100755
index 0000000000..61ad92b6da
--- /dev/null
+++ b/indra/newview/llfloaterchatvoicevolume.h
@@ -0,0 +1,44 @@
+/**
+ * @file llfloaterchatvoicevolume.h
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 LLFLOATERCHATVOICEVOLUME_H_
+#define LLFLOATERCHATVOICEVOLUME_H_
+
+#include "llinspect.h"
+#include "lltransientfloatermgr.h"
+
+class LLFloaterChatVoiceVolume : public LLInspect, LLTransientFloater
+{
+public:
+
+ LLFloaterChatVoiceVolume(const LLSD& key);
+ virtual ~LLFloaterChatVoiceVolume();
+
+ virtual void onOpen(const LLSD& key);
+
+ /*virtual*/ LLTransientFloaterMgr::ETransientGroup getGroup() { return LLTransientFloaterMgr::GLOBAL; }
+};
+
+#endif /* LLFLOATERCHATVOICEVOLUME_H_ */
diff --git a/indra/newview/llfloatercolorpicker.cpp b/indra/newview/llfloatercolorpicker.cpp
index 05d73c2416..a03425649f 100644..100755
--- a/indra/newview/llfloatercolorpicker.cpp
+++ b/indra/newview/llfloatercolorpicker.cpp
@@ -62,10 +62,6 @@
#include <sstream>
#include <iomanip>
-const F32 CONTEXT_CONE_IN_ALPHA = 0.0f;
-const F32 CONTEXT_CONE_OUT_ALPHA = 1.f;
-const F32 CONTEXT_FADE_TIME = 0.08f;
-
//////////////////////////////////////////////////////////////////////////////
//
// Class LLFloaterColorPicker
@@ -105,7 +101,10 @@ LLFloaterColorPicker::LLFloaterColorPicker (LLColorSwatchCtrl* swatch, BOOL show
mSwatch ( swatch ),
mActive ( TRUE ),
mCanApplyImmediately ( show_apply_immediate ),
- mContextConeOpacity ( 0.f )
+ mContextConeOpacity ( 0.f ),
+ mContextConeInAlpha ( 0.f ),
+ mContextConeOutAlpha ( 0.f ),
+ mContextConeFadeTime ( 0.f )
{
buildFromFile ( "floater_color_picker.xml");
@@ -117,6 +116,10 @@ LLFloaterColorPicker::LLFloaterColorPicker (LLColorSwatchCtrl* swatch, BOOL show
mApplyImmediateCheck->setEnabled(FALSE);
mApplyImmediateCheck->set(FALSE);
}
+
+ mContextConeInAlpha = gSavedSettings.getF32("ContextConeInAlpha");
+ mContextConeOutAlpha = gSavedSettings.getF32("ContextConeOutAlpha");
+ mContextConeFadeTime = gSavedSettings.getF32("ContextConeFadeTime");
}
LLFloaterColorPicker::~LLFloaterColorPicker()
@@ -172,9 +175,9 @@ void LLFloaterColorPicker::createUI ()
//
void LLFloaterColorPicker::showUI ()
{
+ openFloater(getKey());
setVisible ( TRUE );
setFocus ( TRUE );
- openFloater(getKey());
// HACK: if system color picker is required - close the SL one we made and use default system dialog
if ( gSavedSettings.getBOOL ( "UseDefaultColorPicker" ) )
@@ -486,37 +489,37 @@ void LLFloaterColorPicker::draw()
mSwatch->localRectToOtherView(mSwatch->getLocalRect(), &swatch_rect, this);
// draw context cone connecting color picker with color swatch in parent floater
LLRect local_rect = getLocalRect();
- if (gFocusMgr.childHasKeyboardFocus(this) && mSwatch->isInVisibleChain() && mContextConeOpacity > 0.001f)
+ if (hasFocus() && mSwatch->isInVisibleChain() && mContextConeOpacity > 0.001f)
{
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
LLGLEnable(GL_CULL_FACE);
gGL.begin(LLRender::QUADS);
{
- gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity);
+ gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
gGL.vertex2i(swatch_rect.mLeft, swatch_rect.mTop);
gGL.vertex2i(swatch_rect.mRight, swatch_rect.mTop);
- gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * mContextConeOpacity);
+ gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
gGL.vertex2i(local_rect.mRight, local_rect.mTop);
gGL.vertex2i(local_rect.mLeft, local_rect.mTop);
- gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * mContextConeOpacity);
+ gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
gGL.vertex2i(local_rect.mLeft, local_rect.mTop);
gGL.vertex2i(local_rect.mLeft, local_rect.mBottom);
- gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity);
+ gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
gGL.vertex2i(swatch_rect.mLeft, swatch_rect.mBottom);
gGL.vertex2i(swatch_rect.mLeft, swatch_rect.mTop);
- gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * mContextConeOpacity);
+ gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
gGL.vertex2i(local_rect.mRight, local_rect.mBottom);
gGL.vertex2i(local_rect.mRight, local_rect.mTop);
- gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity);
+ gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
gGL.vertex2i(swatch_rect.mRight, swatch_rect.mTop);
gGL.vertex2i(swatch_rect.mRight, swatch_rect.mBottom);
- gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * mContextConeOpacity);
+ gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
gGL.vertex2i(local_rect.mLeft, local_rect.mBottom);
gGL.vertex2i(local_rect.mRight, local_rect.mBottom);
- gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity);
+ gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
gGL.vertex2i(swatch_rect.mRight, swatch_rect.mBottom);
gGL.vertex2i(swatch_rect.mLeft, swatch_rect.mBottom);
}
@@ -525,11 +528,12 @@ void LLFloaterColorPicker::draw()
if (gFocusMgr.childHasMouseCapture(getDragHandle()))
{
- mContextConeOpacity = lerp(mContextConeOpacity, gSavedSettings.getF32("PickerContextOpacity"), LLCriticalDamp::getInterpolant(CONTEXT_FADE_TIME));
+ mContextConeOpacity = lerp(mContextConeOpacity, gSavedSettings.getF32("PickerContextOpacity"),
+ LLCriticalDamp::getInterpolant(mContextConeFadeTime));
}
else
{
- mContextConeOpacity = lerp(mContextConeOpacity, 0.f, LLCriticalDamp::getInterpolant(CONTEXT_FADE_TIME));
+ mContextConeOpacity = lerp(mContextConeOpacity, 0.f, LLCriticalDamp::getInterpolant(mContextConeFadeTime));
}
mPipetteBtn->setToggleState(LLToolMgr::getInstance()->getCurrentTool() == LLToolPipette::getInstance());
diff --git a/indra/newview/llfloatercolorpicker.h b/indra/newview/llfloatercolorpicker.h
index 8e387c4f7c..bab0617712 100644..100755
--- a/indra/newview/llfloatercolorpicker.h
+++ b/indra/newview/llfloatercolorpicker.h
@@ -189,6 +189,10 @@ class LLFloaterColorPicker
LLButton* mPipetteBtn;
F32 mContextConeOpacity;
+ F32 mContextConeInAlpha;
+ F32 mContextConeOutAlpha;
+ F32 mContextConeFadeTime;
+
};
#endif // LL_LLFLOATERCOLORPICKER_H
diff --git a/indra/newview/llfloaterconversationlog.cpp b/indra/newview/llfloaterconversationlog.cpp
new file mode 100755
index 0000000000..4c910c5655
--- /dev/null
+++ b/indra/newview/llfloaterconversationlog.cpp
@@ -0,0 +1,134 @@
+/**
+ * @file llfloaterconversationlog.cpp
+ * @brief Functionality of the "conversation log" floater
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 "llconversationloglist.h"
+#include "llfiltereditor.h"
+#include "llfloaterconversationlog.h"
+#include "llfloaterreg.h"
+#include "llmenubutton.h"
+
+LLFloaterConversationLog::LLFloaterConversationLog(const LLSD& key)
+: LLFloater(key),
+ mConversationLogList(NULL)
+{
+ mCommitCallbackRegistrar.add("CallLog.Action", boost::bind(&LLFloaterConversationLog::onCustomAction, this, _2));
+ mEnableCallbackRegistrar.add("CallLog.Check", boost::bind(&LLFloaterConversationLog::isActionChecked, this, _2));
+}
+
+BOOL LLFloaterConversationLog::postBuild()
+{
+ mConversationLogList = getChild<LLConversationLogList>("conversation_log_list");
+
+ switch (gSavedSettings.getU32("CallLogSortOrder"))
+ {
+ case LLConversationLogList::E_SORT_BY_NAME:
+ mConversationLogList->sortByName();
+ break;
+
+ case LLConversationLogList::E_SORT_BY_DATE:
+ mConversationLogList->sortByDate();
+ break;
+ }
+
+ // Use the context menu of the Conversation list for the Conversation tab gear menu.
+ LLToggleableMenu* conversations_gear_menu = mConversationLogList->getContextMenu();
+ if (conversations_gear_menu)
+ {
+ getChild<LLMenuButton>("conversations_gear_btn")->setMenu(conversations_gear_menu, LLMenuButton::MP_BOTTOM_LEFT);
+ }
+
+ getChild<LLFilterEditor>("people_filter_input")->setCommitCallback(boost::bind(&LLFloaterConversationLog::onFilterEdit, this, _2));
+
+ return LLFloater::postBuild();
+}
+
+void LLFloaterConversationLog::draw()
+{
+ getChild<LLMenuButton>("conversations_gear_btn")->setEnabled(mConversationLogList->getSelectedItem() != NULL);
+ LLFloater::draw();
+}
+
+void LLFloaterConversationLog::onFilterEdit(const std::string& search_string)
+{
+ std::string filter = search_string;
+ LLStringUtil::trimHead(filter);
+
+ mConversationLogList->setNameFilter(filter);
+}
+
+
+void LLFloaterConversationLog::onCustomAction (const LLSD& userdata)
+{
+ const std::string command_name = userdata.asString();
+
+ if ("sort_by_name" == command_name)
+ {
+ mConversationLogList->sortByName();
+ gSavedSettings.setU32("CallLogSortOrder", LLConversationLogList::E_SORT_BY_NAME);
+ }
+ else if ("sort_by_date" == command_name)
+ {
+ mConversationLogList->sortByDate();
+ gSavedSettings.setU32("CallLogSortOrder", LLConversationLogList::E_SORT_BY_DATE);
+ }
+ else if ("sort_friends_on_top" == command_name)
+ {
+ mConversationLogList->toggleSortFriendsOnTop();
+ }
+ else if ("view_nearby_chat_history" == command_name)
+ {
+ LLFloaterReg::showInstance("preview_conversation", LLSD(LLUUID::null), true);
+ }
+}
+
+bool LLFloaterConversationLog::isActionEnabled(const LLSD& userdata)
+{
+ return true;
+}
+
+bool LLFloaterConversationLog::isActionChecked(const LLSD& userdata)
+{
+ const std::string command_name = userdata.asString();
+
+ U32 sort_order = gSavedSettings.getU32("CallLogSortOrder");
+
+ if ("sort_by_name" == command_name)
+ {
+ return sort_order == LLConversationLogList::E_SORT_BY_NAME;
+ }
+ else if ("sort_by_date" == command_name)
+ {
+ return sort_order == LLConversationLogList::E_SORT_BY_DATE;
+ }
+ else if ("sort_friends_on_top" == command_name)
+ {
+ return gSavedSettings.getBOOL("SortFriendsFirst");
+ }
+
+ return false;
+}
+
diff --git a/indra/newview/llfloaterconversationlog.h b/indra/newview/llfloaterconversationlog.h
new file mode 100755
index 0000000000..e971330f3d
--- /dev/null
+++ b/indra/newview/llfloaterconversationlog.h
@@ -0,0 +1,56 @@
+/**
+ * @file llfloaterconversationlog.h
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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_LLFLOATERCONVERSATIONLOG_H_
+#define LL_LLFLOATERCONVERSATIONLOG_H_
+
+#include "llfloater.h"
+
+class LLConversationLogList;
+
+class LLFloaterConversationLog : public LLFloater
+{
+public:
+
+ LLFloaterConversationLog(const LLSD& key);
+ virtual ~LLFloaterConversationLog(){};
+
+ virtual BOOL postBuild();
+
+ virtual void draw();
+
+ void onFilterEdit(const std::string& search_string);
+
+private:
+
+ void onCustomAction (const LLSD& userdata);
+ bool isActionEnabled(const LLSD& userdata);
+ bool isActionChecked(const LLSD& userdata);
+
+ LLConversationLogList* mConversationLogList;
+};
+
+
+#endif /* LLFLOATERCONVERSATIONLOG_H_ */
diff --git a/indra/newview/llfloaterconversationpreview.cpp b/indra/newview/llfloaterconversationpreview.cpp
new file mode 100755
index 0000000000..5041f4689d
--- /dev/null
+++ b/indra/newview/llfloaterconversationpreview.cpp
@@ -0,0 +1,204 @@
+/**
+ * @file llfloaterconversationpreview.cpp
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 "llconversationlog.h"
+#include "llfloaterconversationpreview.h"
+#include "llimview.h"
+#include "lllineeditor.h"
+#include "llfloaterimnearbychat.h"
+#include "llspinctrl.h"
+#include "lltrans.h"
+
+const std::string LL_FCP_COMPLETE_NAME("complete_name");
+const std::string LL_FCP_ACCOUNT_NAME("user_name");
+
+LLFloaterConversationPreview::LLFloaterConversationPreview(const LLSD& session_id)
+: LLFloater(session_id),
+ mChatHistory(NULL),
+ mSessionID(session_id.asUUID()),
+ mCurrentPage(0),
+ mPageSize(gSavedSettings.getS32("ConversationHistoryPageSize")),
+ mAccountName(session_id[LL_FCP_ACCOUNT_NAME]),
+ mCompleteName(session_id[LL_FCP_COMPLETE_NAME]),
+ mMutex(NULL),
+ mShowHistory(false)
+{
+}
+
+BOOL LLFloaterConversationPreview::postBuild()
+{
+ mChatHistory = getChild<LLChatHistory>("chat_history");
+ LLLoadHistoryThread::setLoadEndSignal(boost::bind(&LLFloaterConversationPreview::setPages, this, _1, _2));
+
+ const LLConversation* conv = LLConversationLog::instance().getConversation(mSessionID);
+ std::string name;
+ std::string file;
+
+ if (mAccountName != "")
+ {
+ name = mCompleteName;
+ file = mAccountName;
+ }
+ else if (mSessionID != LLUUID::null && conv)
+ {
+ name = conv->getConversationName();
+ file = conv->getHistoryFileName();
+ }
+ else
+ {
+ name = LLTrans::getString("NearbyChatTitle");
+ file = "chat";
+ }
+ mChatHistoryFileName = file;
+ LLStringUtil::format_map_t args;
+ args["[NAME]"] = name;
+ std::string title = getString("Title", args);
+ setTitle(title);
+
+ LLSD load_params;
+ load_params["load_all_history"] = true;
+ load_params["cut_off_todays_date"] = false;
+
+
+ LLSD loading;
+ loading[LL_IM_TEXT] = LLTrans::getString("loading_chat_logs");
+ mMessages.push_back(loading);
+ mPageSpinner = getChild<LLSpinCtrl>("history_page_spin");
+ mPageSpinner->setCommitCallback(boost::bind(&LLFloaterConversationPreview::onMoreHistoryBtnClick, this));
+ mPageSpinner->setMinValue(1);
+ mPageSpinner->set(1);
+ mPageSpinner->setEnabled(false);
+ LLLogChat::startChatHistoryThread(file, load_params);
+ return LLFloater::postBuild();
+}
+
+void LLFloaterConversationPreview::setPages(std::list<LLSD>& messages, const std::string& file_name)
+{
+ if(file_name == mChatHistoryFileName)
+ {
+ // additional protection to avoid changes of mMessages in setPages()
+ LLMutexLock lock(&mMutex);
+ mMessages = messages;
+ mCurrentPage = (mMessages.size() ? (mMessages.size() - 1) / mPageSize : 0);
+
+ mPageSpinner->setEnabled(true);
+ mPageSpinner->setMaxValue(mCurrentPage+1);
+ mPageSpinner->set(mCurrentPage+1);
+
+ std::string total_page_num = llformat("/ %d", mCurrentPage+1);
+ getChild<LLTextBox>("page_num_label")->setValue(total_page_num);
+ mShowHistory = true;
+ }
+}
+
+void LLFloaterConversationPreview::draw()
+{
+ if(mShowHistory)
+ {
+ showHistory();
+ mShowHistory = false;
+ }
+ LLFloater::draw();
+}
+
+void LLFloaterConversationPreview::onOpen(const LLSD& key)
+{
+ mShowHistory = true;
+}
+
+void LLFloaterConversationPreview::showHistory()
+{
+ // additional protection to avoid changes of mMessages in setPages
+ LLMutexLock lock(&mMutex);
+ if(!mMessages.size() || mCurrentPage * mPageSize >= mMessages.size())
+ {
+ return;
+ }
+
+ mChatHistory->clear();
+ std::ostringstream message;
+ std::list<LLSD>::const_iterator iter = mMessages.begin();
+ std::advance(iter, mCurrentPage * mPageSize);
+
+ for (int msg_num = 0; iter != mMessages.end() && msg_num < mPageSize; ++iter, ++msg_num)
+ {
+ LLSD msg = *iter;
+
+ LLUUID from_id = LLUUID::null;
+ std::string time = msg["time"].asString();
+ std::string from = msg["from"].asString();
+ std::string message = msg["message"].asString();
+
+ if (msg["from_id"].isDefined())
+ {
+ from_id = msg["from_id"].asUUID();
+ }
+ else
+ {
+ std::string legacy_name = gCacheName->buildLegacyName(from);
+ gCacheName->getUUID(legacy_name, from_id);
+ }
+
+ LLChat chat;
+ chat.mFromID = from_id;
+ chat.mSessionID = mSessionID;
+ chat.mFromName = from;
+ chat.mTimeStr = time;
+ chat.mChatStyle = CHAT_STYLE_HISTORY;
+ chat.mText = message;
+
+ if (from_id.isNull() && SYSTEM_FROM == from)
+ {
+ chat.mSourceType = CHAT_SOURCE_SYSTEM;
+
+ }
+ else if (from_id.isNull())
+ {
+ chat.mSourceType = LLFloaterIMNearbyChat::isWordsName(from) ? CHAT_SOURCE_UNKNOWN : CHAT_SOURCE_OBJECT;
+ }
+
+ LLSD chat_args;
+ chat_args["use_plain_text_chat_history"] =
+ gSavedSettings.getBOOL("PlainTextChatHistory");
+ chat_args["show_time"] = gSavedSettings.getBOOL("IMShowTime");
+ chat_args["show_names_for_p2p_conv"] = gSavedSettings.getBOOL("IMShowNamesForP2PConv");
+
+ mChatHistory->appendMessage(chat,chat_args);
+ }
+}
+
+void LLFloaterConversationPreview::onMoreHistoryBtnClick()
+{
+ mCurrentPage = (int)(mPageSpinner->getValueF32());
+ if (!mCurrentPage)
+ {
+ return;
+ }
+
+ mCurrentPage--;
+ mShowHistory = true;
+}
diff --git a/indra/newview/llfloaterconversationpreview.h b/indra/newview/llfloaterconversationpreview.h
new file mode 100755
index 0000000000..b0488f4ff1
--- /dev/null
+++ b/indra/newview/llfloaterconversationpreview.h
@@ -0,0 +1,68 @@
+/**
+ * @file llfloaterconversationpreview.h
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 LLFLOATERCONVERSATIONPREVIEW_H_
+#define LLFLOATERCONVERSATIONPREVIEW_H_
+
+#include "llchathistory.h"
+#include "llfloater.h"
+
+extern const std::string LL_FCP_COMPLETE_NAME; //"complete_name"
+extern const std::string LL_FCP_ACCOUNT_NAME; //"user_name"
+
+class LLSpinCtrl;
+
+class LLFloaterConversationPreview : public LLFloater
+{
+public:
+
+ LLFloaterConversationPreview(const LLSD& session_id);
+ virtual ~LLFloaterConversationPreview(){};
+
+ virtual BOOL postBuild();
+ void setPages(std::list<LLSD>& messages,const std::string& file_name);
+
+ virtual void draw();
+ virtual void onOpen(const LLSD& key);
+
+private:
+ void onMoreHistoryBtnClick();
+ void showHistory();
+
+ LLMutex mMutex;
+ LLSpinCtrl* mPageSpinner;
+ LLChatHistory* mChatHistory;
+ LLUUID mSessionID;
+ int mCurrentPage;
+ int mPageSize;
+
+ std::list<LLSD> mMessages;
+ std::string mAccountName;
+ std::string mCompleteName;
+ std::string mChatHistoryFileName;
+ bool mShowHistory;
+};
+
+#endif /* LLFLOATERCONVERSATIONPREVIEW_H_ */
diff --git a/indra/newview/llfloaterdeleteenvpreset.cpp b/indra/newview/llfloaterdeleteenvpreset.cpp
index d08aa81cfe..d08aa81cfe 100644..100755
--- a/indra/newview/llfloaterdeleteenvpreset.cpp
+++ b/indra/newview/llfloaterdeleteenvpreset.cpp
diff --git a/indra/newview/llfloaterdeleteenvpreset.h b/indra/newview/llfloaterdeleteenvpreset.h
index 1211505273..1211505273 100644..100755
--- a/indra/newview/llfloaterdeleteenvpreset.h
+++ b/indra/newview/llfloaterdeleteenvpreset.h
diff --git a/indra/newview/llfloaterdestinations.cpp b/indra/newview/llfloaterdestinations.cpp
index af21cb593f..af21cb593f 100644..100755
--- a/indra/newview/llfloaterdestinations.cpp
+++ b/indra/newview/llfloaterdestinations.cpp
diff --git a/indra/newview/llfloaterdestinations.h b/indra/newview/llfloaterdestinations.h
index 85d9b3391e..85d9b3391e 100644..100755
--- a/indra/newview/llfloaterdestinations.h
+++ b/indra/newview/llfloaterdestinations.h
diff --git a/indra/newview/llfloaterdisplayname.cpp b/indra/newview/llfloaterdisplayname.cpp
index ac8f107928..e2cef5630b 100644..100755
--- a/indra/newview/llfloaterdisplayname.cpp
+++ b/indra/newview/llfloaterdisplayname.cpp
@@ -44,7 +44,7 @@ class LLFloaterDisplayName : public LLFloater
{
public:
LLFloaterDisplayName(const LLSD& key);
- virtual ~LLFloaterDisplayName() {};
+ virtual ~LLFloaterDisplayName() { }
/*virtual*/ BOOL postBuild();
void onSave();
void onReset();
@@ -58,8 +58,8 @@ private:
const LLSD& content);
};
-LLFloaterDisplayName::LLFloaterDisplayName(const LLSD& key)
- : LLFloater(key)
+LLFloaterDisplayName::LLFloaterDisplayName(const LLSD& key) :
+ LLFloater(key)
{
}
@@ -122,10 +122,6 @@ void LLFloaterDisplayName::onCacheSetName(bool success,
LLSD args;
args["DISPLAY_NAME"] = content["display_name"];
LLNotificationsUtil::add("SetDisplayNameSuccess", args);
-
- // Re-fetch my name, as it may have been sanitized by the service
- //LLAvatarNameCache::get(getAvatarId(),
- // boost::bind(&LLPanelMyProfileEdit::onNameCache, this, _1, _2));
return;
}
@@ -164,10 +160,9 @@ void LLFloaterDisplayName::onCancel()
void LLFloaterDisplayName::onReset()
{
- if (LLAvatarNameCache::useDisplayNames())
+ if (LLAvatarNameCache::hasNameLookupURL())
{
- LLViewerDisplayName::set("",
- boost::bind(&LLFloaterDisplayName::onCacheSetName, this, _1, _2, _3));
+ LLViewerDisplayName::set("",boost::bind(&LLFloaterDisplayName::onCacheSetName, this, _1, _2, _3));
}
else
{
@@ -199,10 +194,9 @@ void LLFloaterDisplayName::onSave()
return;
}
- if (LLAvatarNameCache::useDisplayNames())
+ if (LLAvatarNameCache::hasNameLookupURL())
{
- LLViewerDisplayName::set(display_name_utf8,
- boost::bind(&LLFloaterDisplayName::onCacheSetName, this, _1, _2, _3));
+ LLViewerDisplayName::set(display_name_utf8,boost::bind(&LLFloaterDisplayName::onCacheSetName, this, _1, _2, _3));
}
else
{
diff --git a/indra/newview/llfloaterdisplayname.h b/indra/newview/llfloaterdisplayname.h
index a00bf56712..a00bf56712 100644..100755
--- a/indra/newview/llfloaterdisplayname.h
+++ b/indra/newview/llfloaterdisplayname.h
diff --git a/indra/newview/llfloatereditdaycycle.cpp b/indra/newview/llfloatereditdaycycle.cpp
index b63677b258..b63677b258 100644..100755
--- a/indra/newview/llfloatereditdaycycle.cpp
+++ b/indra/newview/llfloatereditdaycycle.cpp
diff --git a/indra/newview/llfloatereditdaycycle.h b/indra/newview/llfloatereditdaycycle.h
index e6e4fe39c1..e6e4fe39c1 100644..100755
--- a/indra/newview/llfloatereditdaycycle.h
+++ b/indra/newview/llfloatereditdaycycle.h
diff --git a/indra/newview/llfloatereditsky.cpp b/indra/newview/llfloatereditsky.cpp
index 352361ce9e..352361ce9e 100644..100755
--- a/indra/newview/llfloatereditsky.cpp
+++ b/indra/newview/llfloatereditsky.cpp
diff --git a/indra/newview/llfloatereditsky.h b/indra/newview/llfloatereditsky.h
index a06c4fc5fa..a06c4fc5fa 100644..100755
--- a/indra/newview/llfloatereditsky.h
+++ b/indra/newview/llfloatereditsky.h
diff --git a/indra/newview/llfloatereditwater.cpp b/indra/newview/llfloatereditwater.cpp
index 64cfc4054f..64cfc4054f 100644..100755
--- a/indra/newview/llfloatereditwater.cpp
+++ b/indra/newview/llfloatereditwater.cpp
diff --git a/indra/newview/llfloatereditwater.h b/indra/newview/llfloatereditwater.h
index 2211bca59f..2211bca59f 100644..100755
--- a/indra/newview/llfloatereditwater.h
+++ b/indra/newview/llfloatereditwater.h
diff --git a/indra/newview/llfloaterenvironmentsettings.cpp b/indra/newview/llfloaterenvironmentsettings.cpp
index 4dbc8cdee0..4dbc8cdee0 100644..100755
--- a/indra/newview/llfloaterenvironmentsettings.cpp
+++ b/indra/newview/llfloaterenvironmentsettings.cpp
diff --git a/indra/newview/llfloaterenvironmentsettings.h b/indra/newview/llfloaterenvironmentsettings.h
index 0ab458a0f6..0ab458a0f6 100644..100755
--- a/indra/newview/llfloaterenvironmentsettings.h
+++ b/indra/newview/llfloaterenvironmentsettings.h
diff --git a/indra/newview/llfloaterevent.cpp b/indra/newview/llfloaterevent.cpp
index a6dafda3e6..a6dafda3e6 100644..100755
--- a/indra/newview/llfloaterevent.cpp
+++ b/indra/newview/llfloaterevent.cpp
diff --git a/indra/newview/llfloaterevent.h b/indra/newview/llfloaterevent.h
index ed90055d95..ed90055d95 100644..100755
--- a/indra/newview/llfloaterevent.h
+++ b/indra/newview/llfloaterevent.h
diff --git a/indra/newview/llfloaterfonttest.cpp b/indra/newview/llfloaterfonttest.cpp
index ff27b683b7..ff27b683b7 100644..100755
--- a/indra/newview/llfloaterfonttest.cpp
+++ b/indra/newview/llfloaterfonttest.cpp
diff --git a/indra/newview/llfloaterfonttest.h b/indra/newview/llfloaterfonttest.h
index fc82d7ef51..fc82d7ef51 100644..100755
--- a/indra/newview/llfloaterfonttest.h
+++ b/indra/newview/llfloaterfonttest.h
diff --git a/indra/newview/llfloatergesture.cpp b/indra/newview/llfloatergesture.cpp
index 59f5b2b346..59f5b2b346 100644..100755
--- a/indra/newview/llfloatergesture.cpp
+++ b/indra/newview/llfloatergesture.cpp
diff --git a/indra/newview/llfloatergesture.h b/indra/newview/llfloatergesture.h
index 8efb3e6461..8efb3e6461 100644..100755
--- a/indra/newview/llfloatergesture.h
+++ b/indra/newview/llfloatergesture.h
diff --git a/indra/newview/llfloatergodtools.cpp b/indra/newview/llfloatergodtools.cpp
index fb905eae11..fe6223fbf5 100644..100755
--- a/indra/newview/llfloatergodtools.cpp
+++ b/indra/newview/llfloatergodtools.cpp
@@ -164,9 +164,9 @@ LLFloaterGodTools::~LLFloaterGodTools()
}
-U32 LLFloaterGodTools::computeRegionFlags() const
+U64 LLFloaterGodTools::computeRegionFlags() const
{
- U32 flags = gAgent.getRegion()->getRegionFlags();
+ U64 flags = gAgent.getRegion()->getRegionFlags();
if (mPanelRegionTools) flags = mPanelRegionTools->computeRegionFlags(flags);
if (mPanelObjectTools) flags = mPanelObjectTools->computeRegionFlags(flags);
return flags;
@@ -210,7 +210,7 @@ void LLFloaterGodTools::processRegionInfo(LLMessageSystem* msg)
if (!msg) return;
//const S32 SIM_NAME_BUF = 256;
- U32 region_flags;
+ U64 region_flags;
U8 sim_access;
U8 agent_limit;
std::string sim_name;
@@ -231,13 +231,23 @@ void LLFloaterGodTools::processRegionInfo(LLMessageSystem* msg)
msg->getStringFast(_PREHASH_RegionInfo, _PREHASH_SimName, sim_name);
msg->getU32Fast(_PREHASH_RegionInfo, _PREHASH_EstateID, estate_id);
msg->getU32Fast(_PREHASH_RegionInfo, _PREHASH_ParentEstateID, parent_estate_id);
- msg->getU32Fast(_PREHASH_RegionInfo, _PREHASH_RegionFlags, region_flags);
msg->getU8Fast(_PREHASH_RegionInfo, _PREHASH_SimAccess, sim_access);
msg->getU8Fast(_PREHASH_RegionInfo, _PREHASH_MaxAgents, agent_limit);
msg->getF32Fast(_PREHASH_RegionInfo, _PREHASH_ObjectBonusFactor, object_bonus_factor);
msg->getF32Fast(_PREHASH_RegionInfo, _PREHASH_BillableFactor, billable_factor);
msg->getF32Fast(_PREHASH_RegionInfo, _PREHASH_WaterHeight, water_height);
+ if (msg->has(_PREHASH_RegionInfo3))
+ {
+ msg->getU64Fast(_PREHASH_RegionInfo3, _PREHASH_RegionFlagsExtended, region_flags);
+ }
+ else
+ {
+ U32 flags = 0;
+ msg->getU32Fast(_PREHASH_RegionInfo, _PREHASH_RegionFlags, flags);
+ region_flags = flags;
+ }
+
if (host != gAgent.getRegionHost())
{
// Update is for a different region than the one we're in.
@@ -341,6 +351,7 @@ void LLFloaterGodTools::sendGodUpdateRegionInfo()
LLMessageSystem *msg = gMessageSystem;
LLPanelRegionTools *rtool = god_tools->mPanelRegionTools;
+ U64 region_flags = computeRegionFlags();
msg->newMessage("GodUpdateRegionInfo");
msg->nextBlockFast(_PREHASH_AgentData);
msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
@@ -349,11 +360,14 @@ void LLFloaterGodTools::sendGodUpdateRegionInfo()
msg->addStringFast(_PREHASH_SimName, rtool->getSimName());
msg->addU32Fast(_PREHASH_EstateID, rtool->getEstateID());
msg->addU32Fast(_PREHASH_ParentEstateID, rtool->getParentEstateID());
- msg->addU32Fast(_PREHASH_RegionFlags, computeRegionFlags());
+ // Legacy flags
+ msg->addU32Fast(_PREHASH_RegionFlags, U32(region_flags));
msg->addF32Fast(_PREHASH_BillableFactor, rtool->getBillableFactor());
msg->addS32Fast(_PREHASH_PricePerMeter, rtool->getPricePerMeter());
msg->addS32Fast(_PREHASH_RedirectGridX, rtool->getRedirectGridX());
msg->addS32Fast(_PREHASH_RedirectGridY, rtool->getRedirectGridY());
+ msg->nextBlockFast(_PREHASH_RegionInfo2);
+ msg->addU64Fast(_PREHASH_RegionFlagsExtended, region_flags);
gAgent.sendReliableMessage();
}
@@ -434,7 +448,7 @@ LLPanelRegionTools::~LLPanelRegionTools()
// base class will take care of everything
}
-U32 LLPanelRegionTools::computeRegionFlags(U32 flags) const
+U64 LLPanelRegionTools::computeRegionFlags(U64 flags) const
{
flags &= getRegionFlagsMask();
flags |= getRegionFlags();
@@ -562,9 +576,9 @@ S32 LLPanelRegionTools::getGridPosY() const
return getChild<LLUICtrl>("gridposy")->getValue().asInteger();
}
-U32 LLPanelRegionTools::getRegionFlags() const
+U64 LLPanelRegionTools::getRegionFlags() const
{
- U32 flags = 0x0;
+ U64 flags = 0x0;
flags = getChild<LLUICtrl>("check prelude")->getValue().asBoolean()
? set_prelude_flags(flags)
: unset_prelude_flags(flags);
@@ -601,9 +615,9 @@ U32 LLPanelRegionTools::getRegionFlags() const
return flags;
}
-U32 LLPanelRegionTools::getRegionFlagsMask() const
+U64 LLPanelRegionTools::getRegionFlagsMask() const
{
- U32 flags = 0xffffffff;
+ U64 flags = 0xFFFFFFFFFFFFFFFFULL;
flags = getChild<LLUICtrl>("check prelude")->getValue().asBoolean()
? set_prelude_flags(flags)
: unset_prelude_flags(flags);
@@ -684,7 +698,7 @@ void LLPanelRegionTools::setParentEstateID(U32 id)
getChild<LLUICtrl>("parentestate")->setValue((S32)id);
}
-void LLPanelRegionTools::setCheckFlags(U32 flags)
+void LLPanelRegionTools::setCheckFlags(U64 flags)
{
getChild<LLUICtrl>("check prelude")->setValue(is_prelude(flags) ? TRUE : FALSE);
getChild<LLUICtrl>("check fixed sun")->setValue(flags & REGION_FLAGS_SUN_FIXED ? TRUE : FALSE);
@@ -943,7 +957,7 @@ void LLPanelObjectTools::refresh()
}
-U32 LLPanelObjectTools::computeRegionFlags(U32 flags) const
+U64 LLPanelObjectTools::computeRegionFlags(U64 flags) const
{
if (getChild<LLUICtrl>("disable scripts")->getValue().asBoolean())
{
@@ -973,7 +987,7 @@ U32 LLPanelObjectTools::computeRegionFlags(U32 flags) const
}
-void LLPanelObjectTools::setCheckFlags(U32 flags)
+void LLPanelObjectTools::setCheckFlags(U64 flags)
{
getChild<LLUICtrl>("disable scripts")->setValue(flags & REGION_FLAGS_SKIP_SCRIPTS ? TRUE : FALSE);
getChild<LLUICtrl>("disable collisions")->setValue(flags & REGION_FLAGS_SKIP_COLLISIONS ? TRUE : FALSE);
@@ -1123,11 +1137,13 @@ bool LLPanelObjectTools::callbackSimWideDeletes( const LLSD& notification, const
void LLPanelObjectTools::onClickSet()
{
- LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(boost::bind(&LLPanelObjectTools::callbackAvatarID, this, _1,_2));
+ LLView * button = findChild<LLButton>("Set Target");
+ LLFloater * root_floater = gFloaterView->getParentFloater(this);
+ LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(boost::bind(&LLPanelObjectTools::callbackAvatarID, this, _1,_2), FALSE, FALSE, FALSE, root_floater->getName(), button);
// grandparent is a floater, which can have a dependent
if (picker)
{
- gFloaterView->getParentFloater(this)->addDependentFloater(picker);
+ root_floater->addDependentFloater(picker);
}
}
diff --git a/indra/newview/llfloatergodtools.h b/indra/newview/llfloatergodtools.h
index 1aa8b838fb..cbaeee7051 100644..100755
--- a/indra/newview/llfloatergodtools.h
+++ b/indra/newview/llfloatergodtools.h
@@ -98,7 +98,7 @@ private:
~LLFloaterGodTools();
protected:
- U32 computeRegionFlags() const;
+ U64 computeRegionFlags() const;
protected:
@@ -147,8 +147,8 @@ public:
const std::string getSimName() const;
U32 getEstateID() const;
U32 getParentEstateID() const;
- U32 getRegionFlags() const;
- U32 getRegionFlagsMask() const;
+ U64 getRegionFlags() const;
+ U64 getRegionFlagsMask() const;
F32 getBillableFactor() const;
S32 getPricePerMeter() const;
S32 getGridPosX() const;
@@ -160,7 +160,7 @@ public:
void setSimName(const std::string& name);
void setEstateID(U32 id);
void setParentEstateID(U32 id);
- void setCheckFlags(U32 flags);
+ void setCheckFlags(U64 flags);
void setBillableFactor(F32 billable_factor);
void setPricePerMeter(S32 price);
void setGridPosX(S32 pos);
@@ -168,7 +168,7 @@ public:
void setRedirectGridX(S32 pos);
void setRedirectGridY(S32 pos);
- U32 computeRegionFlags(U32 initial_flags) const;
+ U64 computeRegionFlags(U64 initial_flags) const;
void clearAllWidgets();
void enableAllWidgets();
@@ -218,10 +218,10 @@ public:
/*virtual*/ void refresh();
void setTargetAvatar(const LLUUID& target_id);
- U32 computeRegionFlags(U32 initial_flags) const;
+ U64 computeRegionFlags(U64 initial_flags) const;
void clearAllWidgets();
void enableAllWidgets();
- void setCheckFlags(U32 flags);
+ void setCheckFlags(U64 flags);
void onChangeAnything();
void onApplyChanges();
diff --git a/indra/newview/llfloatergotoline.cpp b/indra/newview/llfloatergotoline.cpp
new file mode 100644
index 0000000000..d66e418926
--- /dev/null
+++ b/indra/newview/llfloatergotoline.cpp
@@ -0,0 +1,160 @@
+/**
+ * @file llfloatergotoline.h
+ * @author MartinRJ
+ * @brief LLFloaterGotoLine class implementation
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 "llfloatergotoline.h"
+#include "llpreviewscript.h"
+#include "llfloaterreg.h"
+#include "lllineeditor.h"
+#include "llviewertexteditor.h"
+#include "llviewerwindow.h"
+
+LLFloaterGotoLine* LLFloaterGotoLine::sInstance = NULL;
+
+LLFloaterGotoLine::LLFloaterGotoLine(LLScriptEdCore* editor_core)
+: LLFloater(LLSD()),
+ mGotoBox(NULL),
+ mEditorCore(editor_core)
+{
+ buildFromFile("floater_goto_line.xml");
+
+ sInstance = this;
+
+ // find floater in which script panel is embedded
+ LLView* viewp = (LLView*)editor_core;
+ while(viewp)
+ {
+ LLFloater* floaterp = dynamic_cast<LLFloater*>(viewp);
+ if (floaterp)
+ {
+ floaterp->addDependentFloater(this);
+ break;
+ }
+ viewp = viewp->getParent();
+ }
+}
+
+BOOL LLFloaterGotoLine::postBuild()
+{
+ mGotoBox = getChild<LLLineEditor>("goto_line");
+ mGotoBox->setCommitCallback(boost::bind(&LLFloaterGotoLine::onGotoBoxCommit, this));
+ mGotoBox->setCommitOnFocusLost(FALSE);
+ getChild<LLLineEditor>("goto_line")->setPrevalidate(LLTextValidate::validateNonNegativeS32);
+ childSetAction("goto_btn", onBtnGoto,this);
+ setDefaultBtn("goto_btn");
+
+ return TRUE;
+}
+
+//static
+void LLFloaterGotoLine::show(LLScriptEdCore* editor_core)
+{
+ if (sInstance && sInstance->mEditorCore && sInstance->mEditorCore != editor_core)
+ {
+ sInstance->closeFloater();
+ delete sInstance;
+ }
+
+ if (!sInstance)
+ {
+ // sInstance will be assigned in the constructor.
+ new LLFloaterGotoLine(editor_core);
+ }
+
+ sInstance->openFloater();
+}
+
+LLFloaterGotoLine::~LLFloaterGotoLine()
+{
+ sInstance = NULL;
+}
+
+// static
+void LLFloaterGotoLine::onBtnGoto(void *userdata)
+{
+ LLFloaterGotoLine* self = (LLFloaterGotoLine*)userdata;
+ self->handleBtnGoto();
+}
+
+void LLFloaterGotoLine::handleBtnGoto()
+{
+ S32 row = 0;
+ S32 column = 0;
+ row = getChild<LLUICtrl>("goto_line")->getValue().asInteger();
+ if (row >= 0)
+ {
+ if (mEditorCore && mEditorCore->mEditor)
+ {
+ mEditorCore->mEditor->deselect();
+ mEditorCore->mEditor->setCursor(row, column);
+ mEditorCore->mEditor->setFocus(TRUE);
+ }
+ }
+}
+
+bool LLFloaterGotoLine::hasAccelerators() const
+{
+ if (mEditorCore)
+ {
+ return mEditorCore->hasAccelerators();
+ }
+ return FALSE;
+}
+
+BOOL LLFloaterGotoLine::handleKeyHere(KEY key, MASK mask)
+{
+ if (mEditorCore)
+ {
+ return mEditorCore->handleKeyHere(key, mask);
+ }
+
+ return FALSE;
+}
+
+void LLFloaterGotoLine::onGotoBoxCommit()
+{
+ S32 row = 0;
+ S32 column = 0;
+ row = getChild<LLUICtrl>("goto_line")->getValue().asInteger();
+ if (row >= 0)
+ {
+ if (mEditorCore && mEditorCore->mEditor)
+ {
+ mEditorCore->mEditor->setCursor(row, column);
+
+ S32 rownew = 0;
+ S32 columnnew = 0;
+ mEditorCore->mEditor->getCurrentLineAndColumn( &rownew, &columnnew, FALSE ); // don't include wordwrap
+ if (rownew == row && columnnew == column)
+ {
+ mEditorCore->mEditor->deselect();
+ mEditorCore->mEditor->setFocus(TRUE);
+ sInstance->closeFloater();
+ } //else do nothing (if the cursor-position didn't change)
+ }
+ }
+}
diff --git a/indra/newview/llfloatergotoline.h b/indra/newview/llfloatergotoline.h
new file mode 100644
index 0000000000..058d601752
--- /dev/null
+++ b/indra/newview/llfloatergotoline.h
@@ -0,0 +1,66 @@
+/**
+ * @file llfloatergotoline.h
+ * @author MartinRJ
+ * @brief LLFloaterGotoLine class definition
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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_LLFLOATERGOTOLINE_H
+#define LL_LLFLOATERGOTOLINE_H
+
+#include "llfloater.h"
+#include "lllineeditor.h"
+#include "llpreviewscript.h"
+
+class LLScriptEdCore;
+
+class LLFloaterGotoLine : public LLFloater
+{
+public:
+ LLFloaterGotoLine(LLScriptEdCore* editor_core);
+ ~LLFloaterGotoLine();
+
+ /*virtual*/ BOOL postBuild();
+ static void show(LLScriptEdCore* editor_core);
+
+ static void onBtnGoto(void* userdata);
+ void handleBtnGoto();
+
+ LLScriptEdCore* getEditorCore() { return mEditorCore; }
+ static LLFloaterGotoLine* getInstance() { return sInstance; }
+
+ virtual bool hasAccelerators() const;
+ virtual BOOL handleKeyHere(KEY key, MASK mask);
+
+private:
+
+ LLScriptEdCore* mEditorCore;
+
+ static LLFloaterGotoLine* sInstance;
+
+protected:
+ LLLineEditor* mGotoBox;
+ void onGotoBoxCommit();
+};
+
+#endif // LL_LLFLOATERGOTOLINE_H
diff --git a/indra/newview/llfloatergroupinvite.cpp b/indra/newview/llfloatergroupinvite.cpp
index 49da4e64b3..d0f3289769 100644..100755
--- a/indra/newview/llfloatergroupinvite.cpp
+++ b/indra/newview/llfloatergroupinvite.cpp
@@ -30,6 +30,8 @@
#include "llpanelgroupinvite.h"
#include "lltrans.h"
#include "lldraghandle.h"
+#include "llagent.h"
+#include "llgroupmgr.h"
class LLFloaterGroupInvite::impl
{
@@ -123,6 +125,12 @@ void LLFloaterGroupInvite::showForGroup(const LLUUID& group_id, uuid_vec_t *agen
LLFloaterGroupInvite *fgi = get_if_there(impl::sInstances,
group_id,
(LLFloaterGroupInvite*)NULL);
+
+ // refresh group information
+ gAgent.sendAgentDataUpdateRequest();
+ LLGroupMgr::getInstance()->clearGroupData(group_id);
+
+
if (!fgi)
{
fgi = new LLFloaterGroupInvite(group_id);
diff --git a/indra/newview/llfloatergroupinvite.h b/indra/newview/llfloatergroupinvite.h
index f6a3ca5550..f6a3ca5550 100644..100755
--- a/indra/newview/llfloatergroupinvite.h
+++ b/indra/newview/llfloatergroupinvite.h
diff --git a/indra/newview/llfloatergroups.cpp b/indra/newview/llfloatergroups.cpp
index d84364a68a..d84364a68a 100644..100755
--- a/indra/newview/llfloatergroups.cpp
+++ b/indra/newview/llfloatergroups.cpp
diff --git a/indra/newview/llfloatergroups.h b/indra/newview/llfloatergroups.h
index 1ad27cea19..1ad27cea19 100644..100755
--- a/indra/newview/llfloatergroups.h
+++ b/indra/newview/llfloatergroups.h
diff --git a/indra/newview/llfloaterhandler.cpp b/indra/newview/llfloaterhandler.cpp
index e2160498e9..e2160498e9 100644..100755
--- a/indra/newview/llfloaterhandler.cpp
+++ b/indra/newview/llfloaterhandler.cpp
diff --git a/indra/newview/llfloaterhandler.h b/indra/newview/llfloaterhandler.h
index 5915642d66..5915642d66 100644..100755
--- a/indra/newview/llfloaterhandler.h
+++ b/indra/newview/llfloaterhandler.h
diff --git a/indra/newview/llfloaterhardwaresettings.cpp b/indra/newview/llfloaterhardwaresettings.cpp
index f9a403cf9f..792a2a5d25 100644..100755
--- a/indra/newview/llfloaterhardwaresettings.cpp
+++ b/indra/newview/llfloaterhardwaresettings.cpp
@@ -37,6 +37,7 @@
#include "llspinctrl.h"
#include "llstartup.h"
#include "lltextbox.h"
+#include "llcombobox.h"
#include "pipeline.h"
// Linden library includes
@@ -88,8 +89,10 @@ void LLFloaterHardwareSettings::refresh()
void LLFloaterHardwareSettings::refreshEnabledState()
{
+ F32 mem_multiplier = gSavedSettings.getF32("RenderTextureMemoryMultiple");
+
S32 min_tex_mem = LLViewerTextureList::getMinVideoRamSetting();
- S32 max_tex_mem = LLViewerTextureList::getMaxVideoRamSetting();
+ S32 max_tex_mem = LLViewerTextureList::getMaxVideoRamSetting(false, mem_multiplier);
getChild<LLSliderCtrl>("GraphicsCardTextureMemory")->setMinValue(min_tex_mem);
getChild<LLSliderCtrl>("GraphicsCardTextureMemory")->setMaxValue(max_tex_mem);
@@ -99,6 +102,12 @@ void LLFloaterHardwareSettings::refreshEnabledState()
getChildView("vbo")->setEnabled(FALSE);
}
+ if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderCompressTextures") ||
+ !gGLManager.mHasVertexBufferObject)
+ {
+ getChildView("texture compression")->setEnabled(FALSE);
+ }
+
// if no windlight shaders, turn off nighttime brightness, gamma, and fog distance
LLSpinCtrl* gamma_ctrl = getChild<LLSpinCtrl>("gamma");
gamma_ctrl->setEnabled(!gPipeline.canUseWindLightShaders());
@@ -142,6 +151,18 @@ BOOL LLFloaterHardwareSettings::postBuild()
{
childSetAction("OK", onBtnOK, this);
+// Don't do this on Mac as their braindead GL versioning
+// sets this when 8x and 16x are indeed available
+//
+#if !LL_DARWIN
+ if (gGLManager.mIsIntel || gGLManager.mGLVersion < 3.f)
+ { //remove FSAA settings above "4x"
+ LLComboBox* combo = getChild<LLComboBox>("fsaa");
+ combo->remove("8x");
+ combo->remove("16x");
+ }
+#endif
+
refresh();
center();
diff --git a/indra/newview/llfloaterhardwaresettings.h b/indra/newview/llfloaterhardwaresettings.h
index 626771b1d2..626771b1d2 100644..100755
--- a/indra/newview/llfloaterhardwaresettings.h
+++ b/indra/newview/llfloaterhardwaresettings.h
diff --git a/indra/newview/llfloaterhelpbrowser.cpp b/indra/newview/llfloaterhelpbrowser.cpp
index fd9c37ae73..4cb632bd6a 100644..100755
--- a/indra/newview/llfloaterhelpbrowser.cpp
+++ b/indra/newview/llfloaterhelpbrowser.cpp
@@ -77,15 +77,7 @@ void LLFloaterHelpBrowser::onOpen(const LLSD& key)
gSavedSettings.setBOOL("HelpFloaterOpen", TRUE);
std::string topic = key.asString();
-
- if (topic == "__local")
- {
- mBrowser->navigateToLocalPage( "help-offline" , "index.html" );
- }
- else
- {
- mBrowser->navigateTo(LLViewerHelp::instance().getURL(topic));
- }
+ mBrowser->navigateTo(LLViewerHelp::instance().getURL(topic));
}
//virtual
diff --git a/indra/newview/llfloaterhelpbrowser.h b/indra/newview/llfloaterhelpbrowser.h
index bf4f544a14..bf4f544a14 100644..100755
--- a/indra/newview/llfloaterhelpbrowser.h
+++ b/indra/newview/llfloaterhelpbrowser.h
diff --git a/indra/newview/llfloaterhud.cpp b/indra/newview/llfloaterhud.cpp
index 58c76a0b85..58c76a0b85 100644..100755
--- a/indra/newview/llfloaterhud.cpp
+++ b/indra/newview/llfloaterhud.cpp
diff --git a/indra/newview/llfloaterhud.h b/indra/newview/llfloaterhud.h
index e560d6320b..e560d6320b 100644..100755
--- a/indra/newview/llfloaterhud.h
+++ b/indra/newview/llfloaterhud.h
diff --git a/indra/newview/llfloaterimagepreview.cpp b/indra/newview/llfloaterimagepreview.cpp
index 92ee8ddac6..52e678ce24 100644..100755
--- a/indra/newview/llfloaterimagepreview.cpp
+++ b/indra/newview/llfloaterimagepreview.cpp
@@ -593,7 +593,7 @@ S8 LLImagePreviewAvatar::getType() const
void LLImagePreviewAvatar::setPreviewTarget(const std::string& joint_name, const std::string& mesh_name, LLImageRaw* imagep, F32 distance, BOOL male)
{
- mTargetJoint = mDummyAvatar->mRoot.findJoint(joint_name);
+ mTargetJoint = mDummyAvatar->mRoot->findJoint(joint_name);
// clear out existing test mesh
if (mTargetMesh)
{
@@ -612,9 +612,9 @@ void LLImagePreviewAvatar::setPreviewTarget(const std::string& joint_name, const
mDummyAvatar->updateVisualParams();
mDummyAvatar->updateGeometry(mDummyAvatar->mDrawable);
}
- mDummyAvatar->mRoot.setVisible(FALSE, TRUE);
+ mDummyAvatar->mRoot->setVisible(FALSE, TRUE);
- mTargetMesh = (LLViewerJointMesh*)mDummyAvatar->mRoot.findJoint(mesh_name);
+ mTargetMesh = dynamic_cast<LLViewerJointMesh*>(mDummyAvatar->mRoot->findJoint(mesh_name));
mTargetMesh->setTestTexture(mTextureName);
mTargetMesh->setVisible(TRUE, FALSE);
mCameraDistance = distance;
@@ -631,7 +631,7 @@ void LLImagePreviewAvatar::clearPreviewTexture(const std::string& mesh_name)
{
if (mDummyAvatar)
{
- LLViewerJointMesh *mesh = (LLViewerJointMesh*)mDummyAvatar->mRoot.findJoint(mesh_name);
+ LLViewerJointMesh *mesh = dynamic_cast<LLViewerJointMesh*>(mDummyAvatar->mRoot->findJoint(mesh_name));
// clear out existing test mesh
if (mesh)
{
@@ -704,9 +704,13 @@ BOOL LLImagePreviewAvatar::render()
// make sure alpha=0 shows avatar material color
LLGLDisable no_blend(GL_BLEND);
- LLDrawPoolAvatar *avatarPoolp = (LLDrawPoolAvatar *)avatarp->mDrawable->getFace(0)->getPool();
- gPipeline.enableLightsPreview();
- avatarPoolp->renderAvatars(avatarp); // renders only one avatar
+ LLFace* face = avatarp->mDrawable->getFace(0);
+ if (face)
+ {
+ LLDrawPoolAvatar *avatarPoolp = (LLDrawPoolAvatar *)face->getPool();
+ gPipeline.enableLightsPreview();
+ avatarPoolp->renderAvatars(avatarp); // renders only one avatar
+ }
}
gGL.popUIMatrix();
@@ -897,11 +901,13 @@ BOOL LLImagePreviewSculpted::render()
{
gObjectPreviewProgram.bind();
}
+ gPipeline.enableLightsPreview();
+
gGL.pushMatrix();
const F32 SCALE = 1.25f;
gGL.scalef(SCALE, SCALE, SCALE);
const F32 BRIGHTNESS = 0.9f;
- gGL.color3f(BRIGHTNESS, BRIGHTNESS, BRIGHTNESS);
+ gGL.diffuseColor3f(BRIGHTNESS, BRIGHTNESS, BRIGHTNESS);
mVertexBuffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0);
mVertexBuffer->draw(LLRender::TRIANGLES, num_indices, 0);
diff --git a/indra/newview/llfloaterimagepreview.h b/indra/newview/llfloaterimagepreview.h
index d034622c35..d034622c35 100644..100755
--- a/indra/newview/llfloaterimagepreview.h
+++ b/indra/newview/llfloaterimagepreview.h
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
new file mode 100755
index 0000000000..b5aa309066
--- /dev/null
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -0,0 +1,2219 @@
+/**
+ * @file llfloaterimcontainer.cpp
+ * @brief Multifloater containing active IM sessions in separate tab container tabs
+ *
+ * $LicenseInfo:firstyear=2009&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 "llviewerprecompiledheaders.h"
+
+#include "llfloaterimsession.h"
+#include "llfloaterimcontainer.h"
+
+#include "llfloaterreg.h"
+#include "lllayoutstack.h"
+#include "llfloaterimnearbychat.h"
+
+#include "llagent.h"
+#include "llavataractions.h"
+#include "llavatariconctrl.h"
+#include "llavatarnamecache.h"
+#include "llcallbacklist.h"
+#include "lldonotdisturbnotificationstorage.h"
+#include "llgroupactions.h"
+#include "llgroupiconctrl.h"
+#include "llflashtimer.h"
+#include "llfloateravatarpicker.h"
+#include "llfloaterpreference.h"
+#include "llimview.h"
+#include "llnotificationsutil.h"
+#include "lltoolbarview.h"
+#include "lltransientfloatermgr.h"
+#include "llviewercontrol.h"
+#include "llconversationview.h"
+#include "llcallbacklist.h"
+#include "llworld.h"
+#include "llsdserialize.h"
+#include "llviewerobjectlist.h"
+#include "boost/foreach.hpp"
+
+//
+// LLFloaterIMContainer
+//
+LLFloaterIMContainer::LLFloaterIMContainer(const LLSD& seed, const Params& params /*= getDefaultParams()*/)
+: LLMultiFloater(seed, params),
+ mExpandCollapseBtn(NULL),
+ mConversationsRoot(NULL),
+ mConversationsEventStream("ConversationsEvents"),
+ mInitialized(false),
+ mIsFirstLaunch(true)
+{
+ mEnableCallbackRegistrar.add("IMFloaterContainer.Check", boost::bind(&LLFloaterIMContainer::isActionChecked, this, _2));
+ mCommitCallbackRegistrar.add("IMFloaterContainer.Action", boost::bind(&LLFloaterIMContainer::onCustomAction, this, _2));
+
+ mEnableCallbackRegistrar.add("Avatar.CheckItem", boost::bind(&LLFloaterIMContainer::checkContextMenuItem, this, _2));
+ mEnableCallbackRegistrar.add("Avatar.EnableItem", boost::bind(&LLFloaterIMContainer::enableContextMenuItem, this, _2));
+ mEnableCallbackRegistrar.add("Avatar.VisibleItem", boost::bind(&LLFloaterIMContainer::visibleContextMenuItem, this, _2));
+ mCommitCallbackRegistrar.add("Avatar.DoToSelected", boost::bind(&LLFloaterIMContainer::doToSelected, this, _2));
+
+ mCommitCallbackRegistrar.add("Group.DoToSelected", boost::bind(&LLFloaterIMContainer::doToSelectedGroup, this, _2));
+
+ // Firstly add our self to IMSession observers, so we catch session events
+ LLIMMgr::getInstance()->addSessionObserver(this);
+
+ mAutoResize = FALSE;
+ LLTransientFloaterMgr::getInstance()->addControlView(LLTransientFloaterMgr::IM, this);
+}
+
+LLFloaterIMContainer::~LLFloaterIMContainer()
+{
+ mConversationsEventStream.stopListening("ConversationsRefresh");
+
+ gIdleCallbacks.deleteFunction(idle, this);
+
+ mNewMessageConnection.disconnect();
+ LLTransientFloaterMgr::getInstance()->removeControlView(LLTransientFloaterMgr::IM, this);
+
+ if (mMicroChangedSignal.connected())
+ {
+ mMicroChangedSignal.disconnect();
+ }
+
+ gSavedPerAccountSettings.setBOOL("ConversationsListPaneCollapsed", mConversationsPane->isCollapsed());
+ gSavedPerAccountSettings.setBOOL("ConversationsMessagePaneCollapsed", mMessagesPane->isCollapsed());
+ gSavedPerAccountSettings.setBOOL("ConversationsParticipantListCollapsed", !isParticipantListExpanded());
+
+ if (!LLSingleton<LLIMMgr>::destroyed())
+ {
+ LLIMMgr::getInstance()->removeSessionObserver(this);
+ }
+}
+
+void LLFloaterIMContainer::sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id, BOOL has_offline_msg)
+{
+ addConversationListItem(session_id);
+ LLFloaterIMSessionTab::addToHost(session_id);
+}
+
+void LLFloaterIMContainer::sessionActivated(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id)
+{
+ if(!isInVisibleChain())
+ {
+ setVisibleAndFrontmost(false);
+ }
+ selectConversationPair(session_id, true);
+ collapseMessagesPane(false);
+}
+
+void LLFloaterIMContainer::sessionVoiceOrIMStarted(const LLUUID& session_id)
+{
+ addConversationListItem(session_id);
+ LLFloaterIMSessionTab::addToHost(session_id);
+}
+
+void LLFloaterIMContainer::sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id)
+{
+ // The general strategy when a session id is modified is to delete all related objects and create them anew.
+
+ // Note however that the LLFloaterIMSession has its session id updated through a call to sessionInitReplyReceived()
+ // and do not need to be deleted and recreated (trying this creates loads of problems). We do need however to suppress
+ // its related mSessions record as it's indexed with the wrong id.
+ // Grabbing the updated LLFloaterIMSession and readding it in mSessions will eventually be done by addConversationListItem().
+ mSessions.erase(old_session_id);
+
+ // Delete the model and participants related to the old session
+ bool change_focus = removeConversationListItem(old_session_id);
+
+ // Create a new conversation with the new id
+ addConversationListItem(new_session_id, change_focus);
+ LLFloaterIMSessionTab::addToHost(new_session_id);
+}
+
+void LLFloaterIMContainer::sessionRemoved(const LLUUID& session_id)
+{
+ removeConversationListItem(session_id);
+}
+
+// static
+void LLFloaterIMContainer::onCurrentChannelChanged(const LLUUID& session_id)
+{
+ if (session_id != LLUUID::null)
+ {
+ LLFloaterIMContainer::getInstance()->showConversation(session_id);
+ }
+}
+
+BOOL LLFloaterIMContainer::postBuild()
+{
+ mOrigMinWidth = getMinWidth();
+ mOrigMinHeight = getMinHeight();
+
+ mNewMessageConnection = LLIMModel::instance().mNewMsgSignal.connect(boost::bind(&LLFloaterIMContainer::onNewMessageReceived, this, _1));
+ // Do not call base postBuild to not connect to mCloseSignal to not close all floaters via Close button
+ // mTabContainer will be initialized in LLMultiFloater::addChild()
+
+ setTabContainer(getChild<LLTabContainer>("im_box_tab_container"));
+ mStubPanel = getChild<LLPanel>("stub_panel");
+ mStubTextBox = getChild<LLTextBox>("stub_textbox");
+ mStubTextBox->setURLClickedCallback(boost::bind(&LLFloaterIMContainer::returnFloaterToHost, this));
+
+ mConversationsStack = getChild<LLLayoutStack>("conversations_stack");
+ mConversationsPane = getChild<LLLayoutPanel>("conversations_layout_panel");
+ mMessagesPane = getChild<LLLayoutPanel>("messages_layout_panel");
+
+ mConversationsListPanel = getChild<LLPanel>("conversations_list_panel");
+
+ // Open IM session with selected participant on double click event
+ mConversationsListPanel->setDoubleClickCallback(boost::bind(&LLFloaterIMContainer::doToSelected, this, LLSD("im")));
+
+ // The resize limits for LLFloaterIMContainer should be updated, based on current values of width of conversation and message panels
+ mConversationsPane->getResizeBar()->setResizeListener(boost::bind(&LLFloaterIMContainer::assignResizeLimits, this));
+
+ // Create the root model and view for all conversation sessions
+ LLConversationItem* base_item = new LLConversationItem(getRootViewModel());
+
+ LLFolderView::Params p(LLUICtrlFactory::getDefaultParams<LLFolderView>());
+ p.name = getName();
+ p.title = getLabel();
+ p.rect = LLRect(0, 0, getRect().getWidth(), 0);
+ p.parent_panel = mConversationsListPanel;
+ p.tool_tip = p.name;
+ p.listener = base_item;
+ p.view_model = &mConversationViewModel;
+ p.root = NULL;
+ p.use_ellipses = true;
+ p.options_menu = "menu_conversation.xml";
+ mConversationsRoot = LLUICtrlFactory::create<LLFolderView>(p);
+ mConversationsRoot->setCallbackRegistrar(&mCommitCallbackRegistrar);
+
+ // Add listener to conversation model events
+ mConversationsEventStream.listen("ConversationsRefresh", boost::bind(&LLFloaterIMContainer::onConversationModelEvent, this, _1));
+
+ // a scroller for folder view
+ LLRect scroller_view_rect = mConversationsListPanel->getRect();
+ scroller_view_rect.translate(-scroller_view_rect.mLeft, -scroller_view_rect.mBottom);
+ scroller_view_rect.mBottom += getChild<LLLayoutStack>("conversations_pane_buttons_stack")->getRect().getHeight();
+ LLScrollContainer::Params scroller_params(LLUICtrlFactory::getDefaultParams<LLFolderViewScrollContainer>());
+ scroller_params.rect(scroller_view_rect);
+
+ LLScrollContainer* scroller = LLUICtrlFactory::create<LLFolderViewScrollContainer>(scroller_params);
+ scroller->setFollowsAll();
+ mConversationsListPanel->addChild(scroller);
+ scroller->addChild(mConversationsRoot);
+ mConversationsRoot->setScrollContainer(scroller);
+ mConversationsRoot->setFollowsAll();
+ mConversationsRoot->addChild(mConversationsRoot->mStatusTextBox);
+
+ addConversationListItem(LLUUID()); // manually add nearby chat
+
+ mExpandCollapseBtn = getChild<LLButton>("expand_collapse_btn");
+ mExpandCollapseBtn->setClickedCallback(boost::bind(&LLFloaterIMContainer::onExpandCollapseButtonClicked, this));
+ mStubCollapseBtn = getChild<LLButton>("stub_collapse_btn");
+ mStubCollapseBtn->setClickedCallback(boost::bind(&LLFloaterIMContainer::onStubCollapseButtonClicked, this));
+ mSpeakBtn = getChild<LLButton>("speak_btn");
+ mSpeakBtn->setClickedCallback(boost::bind(&LLFloaterIMContainer::onSpeakButtonClicked, this));
+
+ childSetAction("add_btn", boost::bind(&LLFloaterIMContainer::onAddButtonClicked, this));
+
+ collapseMessagesPane(gSavedPerAccountSettings.getBOOL("ConversationsMessagePaneCollapsed"));
+ collapseConversationsPane(gSavedPerAccountSettings.getBOOL("ConversationsListPaneCollapsed"), false);
+ LLAvatarNameCache::addUseDisplayNamesCallback(boost::bind(&LLFloaterIMSessionTab::processChatHistoryStyleUpdate, false));
+ mMicroChangedSignal = LLVoiceClient::getInstance()->MicroChangedCallback(boost::bind(&LLFloaterIMContainer::updateSpeakBtnState, this));
+
+ if (! mMessagesPane->isCollapsed() && ! mConversationsPane->isCollapsed())
+ {
+ S32 conversations_panel_width = gSavedPerAccountSettings.getS32("ConversationsListPaneWidth");
+ LLRect conversations_panel_rect = mConversationsPane->getRect();
+ conversations_panel_rect.mRight = conversations_panel_rect.mLeft + conversations_panel_width;
+ mConversationsPane->handleReshape(conversations_panel_rect, TRUE);
+ }
+
+ // Init the sort order now that the root had been created
+ setSortOrder(LLConversationSort(gSavedSettings.getU32("ConversationSortOrder")));
+
+ //We should expand nearby chat participants list for the new user
+ if(gAgent.isFirstLogin() || !gSavedPerAccountSettings.getBOOL("ConversationsParticipantListCollapsed"))
+ {
+ expandConversation();
+ }
+ // Keep the xml set title around for when we have to overwrite it
+ mGeneralTitle = getTitle();
+
+ mInitialized = true;
+
+ // Add callbacks:
+ // We'll take care of view updates on idle
+ gIdleCallbacks.addFunction(idle, this);
+ // When display name option change, we need to reload all participant names
+ LLAvatarNameCache::addUseDisplayNamesCallback(boost::bind(&LLFloaterIMContainer::processParticipantsStyleUpdate, this));
+
+ return TRUE;
+}
+
+void LLFloaterIMContainer::onOpen(const LLSD& key)
+{
+ LLMultiFloater::onOpen(key);
+ reSelectConversation();
+ assignResizeLimits();
+}
+
+// virtual
+void LLFloaterIMContainer::addFloater(LLFloater* floaterp,
+ BOOL select_added_floater,
+ LLTabContainer::eInsertionPoint insertion_point)
+{
+ if(!floaterp) return;
+
+ // already here
+ if (floaterp->getHost() == this)
+ {
+ openFloater(floaterp->getKey());
+ return;
+ }
+
+ LLUUID session_id = floaterp->getKey();
+
+ // Add the floater
+ LLMultiFloater::addFloater(floaterp, select_added_floater, insertion_point);
+
+
+
+ LLIconCtrl* icon = 0;
+
+ if(gAgent.isInGroup(session_id, TRUE))
+ {
+ LLGroupIconCtrl::Params icon_params;
+ icon_params.group_id = session_id;
+ icon = LLUICtrlFactory::instance().create<LLGroupIconCtrl>(icon_params);
+
+ mSessions[session_id] = floaterp;
+ floaterp->mCloseSignal.connect(boost::bind(&LLFloaterIMContainer::onCloseFloater, this, session_id));
+ }
+ else
+ { LLUUID avatar_id = session_id.notNull()?
+ LLIMModel::getInstance()->getOtherParticipantID(session_id) : LLUUID();
+
+ LLAvatarIconCtrl::Params icon_params;
+ icon_params.avatar_id = avatar_id;
+ icon = LLUICtrlFactory::instance().create<LLAvatarIconCtrl>(icon_params);
+
+ mSessions[session_id] = floaterp;
+ floaterp->mCloseSignal.connect(boost::bind(&LLFloaterIMContainer::onCloseFloater, this, session_id));
+ }
+
+ // forced resize of the floater
+ LLRect wrapper_rect = this->mTabContainer->getLocalRect();
+ floaterp->setRect(wrapper_rect);
+
+ mTabContainer->setTabImage(floaterp, icon);
+}
+
+
+void LLFloaterIMContainer::onCloseFloater(LLUUID& id)
+{
+ mSessions.erase(id);
+ setFocus(TRUE);
+}
+
+void LLFloaterIMContainer::onNewMessageReceived(const LLSD& data)
+{
+ LLUUID session_id = data["session_id"].asUUID();
+ LLFloater* floaterp = get_ptr_in_map(mSessions, session_id);
+ LLFloater* current_floater = LLMultiFloater::getActiveFloater();
+
+ if(floaterp && current_floater && floaterp != current_floater)
+ {
+ if(LLMultiFloater::isFloaterFlashing(floaterp))
+ LLMultiFloater::setFloaterFlashing(floaterp, FALSE);
+ LLMultiFloater::setFloaterFlashing(floaterp, TRUE);
+ }
+}
+
+void LLFloaterIMContainer::onStubCollapseButtonClicked()
+{
+ collapseMessagesPane(true);
+}
+
+void LLFloaterIMContainer::onSpeakButtonClicked()
+{
+ LLAgent::toggleMicrophone("speak");
+ updateSpeakBtnState();
+}
+void LLFloaterIMContainer::onExpandCollapseButtonClicked()
+{
+ if (mConversationsPane->isCollapsed() && mMessagesPane->isCollapsed()
+ && gSavedPerAccountSettings.getBOOL("ConversationsExpandMessagePaneFirst"))
+ {
+ // Expand the messages pane from ultra minimized state
+ // if it was collapsed last in order.
+ collapseMessagesPane(false);
+ }
+ else
+ {
+ collapseConversationsPane(!mConversationsPane->isCollapsed());
+ }
+ reSelectConversation();
+}
+
+LLFloaterIMContainer* LLFloaterIMContainer::findInstance()
+{
+ return LLFloaterReg::findTypedInstance<LLFloaterIMContainer>("im_container");
+}
+
+LLFloaterIMContainer* LLFloaterIMContainer::getInstance()
+{
+ return LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container");
+}
+
+// Update all participants in the conversation lists
+void LLFloaterIMContainer::processParticipantsStyleUpdate()
+{
+ // On each session in mConversationsItems
+ for (conversations_items_map::iterator it_session = mConversationsItems.begin(); it_session != mConversationsItems.end(); it_session++)
+ {
+ // Get the current session descriptors
+ LLConversationItem* session_model = it_session->second;
+ // Iterate through each model participant child
+ LLFolderViewModelItemCommon::child_list_t::const_iterator current_participant_model = session_model->getChildrenBegin();
+ LLFolderViewModelItemCommon::child_list_t::const_iterator end_participant_model = session_model->getChildrenEnd();
+ while (current_participant_model != end_participant_model)
+ {
+ LLConversationItemParticipant* participant_model = dynamic_cast<LLConversationItemParticipant*>(*current_participant_model);
+ // Get the avatar name for this participant id from the cache and update the model
+ participant_model->updateName();
+ // Next participant
+ current_participant_model++;
+ }
+ }
+}
+
+// static
+void LLFloaterIMContainer::idle(void* user_data)
+{
+ LLFloaterIMContainer* self = static_cast<LLFloaterIMContainer*>(user_data);
+
+ // Update the distance to agent in the nearby chat session if required
+ // Note: it makes no sense of course to update the distance in other session
+ if (self->mConversationViewModel.getSorter().getSortOrderParticipants() == LLConversationFilter::SO_DISTANCE)
+ {
+ self->setNearbyDistances();
+ }
+ self->mConversationsRoot->update();
+}
+
+bool LLFloaterIMContainer::onConversationModelEvent(const LLSD& event)
+{
+ // For debug only
+ //std::ostringstream llsd_value;
+ //llsd_value << LLSDOStreamer<LLSDNotationFormatter>(event) << std::endl;
+ //llinfos << "LLFloaterIMContainer::onConversationModelEvent, event = " << llsd_value.str() << llendl;
+ // end debug
+
+ // Note: In conversations, the model is not responsible for creating the view, which is a good thing. This means that
+ // the model could change substantially and the view could echo only a portion of this model (though currently the
+ // conversation view does echo the conversation model 1 to 1).
+ // Consequently, the participant views need to be created either by the session view or by the container panel.
+ // For the moment, we create them here, at the container level, to conform to the pattern implemented in llinventorypanel.cpp
+ // (see LLInventoryPanel::buildNewViews()).
+
+ std::string type = event.get("type").asString();
+ LLUUID session_id = event.get("session_uuid").asUUID();
+ LLUUID participant_id = event.get("participant_uuid").asUUID();
+
+ LLConversationViewSession* session_view = dynamic_cast<LLConversationViewSession*>(get_ptr_in_map(mConversationsWidgets,session_id));
+ if (!session_view)
+ {
+ // We skip events that are not associated with a session
+ return false;
+ }
+ LLConversationViewParticipant* participant_view = session_view->findParticipant(participant_id);
+ LLFloaterIMSessionTab *conversation_floater = (session_id.isNull() ?
+ (LLFloaterIMSessionTab*)(LLFloaterReg::findTypedInstance<LLFloaterIMNearbyChat>("nearby_chat"))
+ : (LLFloaterIMSessionTab*)(LLFloaterIMSession::findInstance(session_id)));
+
+ if (type == "remove_participant")
+ {
+ // Remove a participant view from the hierarchical conversation list
+ if (participant_view)
+ {
+ session_view->extractItem(participant_view);
+ delete participant_view;
+ session_view->refresh();
+ mConversationsRoot->arrangeAll();
+ }
+ // Remove a participant view from the conversation floater
+ if (conversation_floater)
+ {
+ conversation_floater->removeConversationViewParticipant(participant_id);
+ }
+ }
+ else if (type == "add_participant")
+ {
+ LLConversationItemSession* session_model = dynamic_cast<LLConversationItemSession*>(mConversationsItems[session_id]);
+ LLConversationItemParticipant* participant_model = (session_model ? session_model->findParticipant(participant_id) : NULL);
+ if (!participant_view && session_model && participant_model)
+ {
+ LLIMModel::LLIMSession * im_sessionp = LLIMModel::getInstance()->findIMSession(session_id);
+ if (session_id.isNull() || (im_sessionp && !im_sessionp->isP2PSessionType()))
+ {
+ participant_view = createConversationViewParticipant(participant_model);
+ participant_view->addToFolder(session_view);
+ participant_view->setVisible(TRUE);
+ }
+ }
+ // Add a participant view to the conversation floater
+ if (conversation_floater && participant_model)
+ {
+ conversation_floater->addConversationViewParticipant(participant_model);
+ }
+ }
+ else if (type == "update_participant")
+ {
+ // Update the participant view in the hierarchical conversation list
+ if (participant_view)
+ {
+ participant_view->refresh();
+ }
+ // Update the participant view in the conversation floater
+ if (conversation_floater)
+ {
+ conversation_floater->updateConversationViewParticipant(participant_id);
+ }
+ }
+ else if (type == "update_session")
+ {
+ session_view->refresh();
+ }
+
+ mConversationViewModel.requestSortAll();
+ mConversationsRoot->arrangeAll();
+ if (conversation_floater)
+ {
+ conversation_floater->refreshConversation();
+ }
+
+ return false;
+}
+
+void LLFloaterIMContainer::draw()
+{
+ if (mTabContainer->getTabCount() == 0)
+ {
+ // Do not close the container when every conversation is torn off because the user
+ // still needs the conversation list. Simply collapse the message pane in that case.
+ collapseMessagesPane(true);
+ }
+
+ const LLConversationItem *current_session = getCurSelectedViewModelItem();
+ if (current_session)
+ {
+ // Update moderator options visibility
+ LLFolderViewModelItemCommon::child_list_t::const_iterator current_participant_model = current_session->getChildrenBegin();
+ LLFolderViewModelItemCommon::child_list_t::const_iterator end_participant_model = current_session->getChildrenEnd();
+ while (current_participant_model != end_participant_model)
+ {
+ LLConversationItemParticipant* participant_model = dynamic_cast<LLConversationItemParticipant*>(*current_participant_model);
+ participant_model->setModeratorOptionsVisible(isGroupModerator() && participant_model->getUUID() != gAgentID);
+
+ current_participant_model++;
+ }
+ // Update floater's title as required by the currently selected session or use the default title
+ LLFloaterIMSession * conversation_floaterp = LLFloaterIMSession::findInstance(current_session->getUUID());
+ setTitle(conversation_floaterp && conversation_floaterp->needsTitleOverwrite() ? conversation_floaterp->getTitle() : mGeneralTitle);
+ }
+
+ // "Manually" resize of mConversationsPane: same as temporarity cancellation of the flag "auto_resize=false" for it
+ if (!mConversationsPane->isCollapsed() && mMessagesPane->isCollapsed())
+ {
+ LLRect stack_rect = mConversationsStack->getRect();
+ mConversationsPane->reshape(stack_rect.getWidth(), stack_rect.getHeight(), true);
+ }
+
+ LLFloater::draw();
+}
+
+void LLFloaterIMContainer::tabClose()
+{
+ if (mTabContainer->getTabCount() == 0)
+ {
+ // Do not close the container when every conversation is torn off because the user
+ // still needs the conversation list. Simply collapse the message pane in that case.
+ collapseMessagesPane(true);
+ }
+}
+
+//Shows/hides the stub panel when a conversation floater is torn off
+void LLFloaterIMContainer::showStub(bool stub_is_visible)
+{
+ S32 tabCount = 0;
+ LLPanel * tabPanel = NULL;
+
+ if(stub_is_visible)
+ {
+ tabCount = mTabContainer->getTabCount();
+
+ //Hide all tabs even stub
+ for(S32 i = 0; i < tabCount; ++i)
+ {
+ tabPanel = mTabContainer->getPanelByIndex(i);
+
+ if(tabPanel)
+ {
+ tabPanel->setVisible(false);
+ }
+ }
+
+ //Set the index to the stub panel since we will be showing the stub
+ mTabContainer->setCurrentPanelIndex(0);
+ }
+
+ //Now show/hide the stub
+ mStubPanel->setVisible(stub_is_visible);
+}
+
+// listener for click on mStubTextBox2
+void LLFloaterIMContainer::returnFloaterToHost()
+{
+ LLUUID session_id = this->getSelectedSession();
+ LLFloaterIMSessionTab* floater = LLFloaterIMSessionTab::getConversation(session_id);
+ floater->onTearOffClicked();
+}
+
+void LLFloaterIMContainer::setMinimized(BOOL b)
+{
+ bool was_minimized = isMinimized();
+ LLMultiFloater::setMinimized(b);
+
+ //Switching from minimized to un-minimized
+ if(was_minimized && !b)
+ {
+ gToolBarView->flashCommand(LLCommandId("chat"), false);
+ LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::findConversation(mSelectedSession);
+
+ if(session_floater && !session_floater->isTornOff())
+ {
+ //When in DND mode, remove stored IM notifications
+ //Nearby chat (Null) IMs are not stored while in DND mode, so can ignore removal
+ if(gAgent.isDoNotDisturb() && mSelectedSession.notNull())
+ {
+ LLDoNotDisturbNotificationStorage::getInstance()->removeNotification(LLDoNotDisturbNotificationStorage::toastName, mSelectedSession);
+ }
+ }
+ }
+}
+
+void LLFloaterIMContainer::setVisible(BOOL visible)
+{ LLFloaterIMNearbyChat* nearby_chat;
+ if (visible)
+ {
+ // Make sure we have the Nearby Chat present when showing the conversation container
+ nearby_chat = LLFloaterReg::findTypedInstance<LLFloaterIMNearbyChat>("nearby_chat");
+ if (nearby_chat == NULL)
+ {
+ // If not found, force the creation of the nearby chat conversation panel
+ // *TODO: find a way to move this to XML as a default panel or something like that
+ LLSD name("nearby_chat");
+ LLFloaterReg::toggleInstanceOrBringToFront(name);
+ selectConversationPair(LLUUID(NULL), false, false);
+ }
+ flashConversationItemWidget(mSelectedSession,false);
+
+ LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::findConversation(mSelectedSession);
+ if(session_floater && !session_floater->isMinimized())
+ {
+ //When in DND mode, remove stored IM notifications
+ //Nearby chat (Null) IMs are not stored while in DND mode, so can ignore removal
+ if(gAgent.isDoNotDisturb() && mSelectedSession.notNull())
+ {
+ LLDoNotDisturbNotificationStorage::getInstance()->removeNotification(LLDoNotDisturbNotificationStorage::toastName, mSelectedSession);
+ }
+ }
+ }
+
+ nearby_chat = LLFloaterReg::findTypedInstance<LLFloaterIMNearbyChat>("nearby_chat");
+ if (nearby_chat)
+ {
+ LLFloaterIMSessionTab::addToHost(LLUUID());
+ }
+
+ // We need to show/hide all the associated conversations that have been torn off
+ // (and therefore, are not longer managed by the multifloater),
+ // so that they show/hide with the conversations manager.
+ conversations_widgets_map::iterator widget_it = mConversationsWidgets.begin();
+ for (;widget_it != mConversationsWidgets.end(); ++widget_it)
+ {
+ LLConversationViewSession* widget = dynamic_cast<LLConversationViewSession*>(widget_it->second);
+ if (widget)
+ {
+ LLFloater* session_floater = widget->getSessionFloater();
+ if (session_floater != nearby_chat)
+ {
+ widget->setVisibleIfDetached(visible);
+ }
+ }
+ }
+
+ // Now, do the normal multifloater show/hide
+ LLMultiFloater::setVisible(visible);
+}
+
+void LLFloaterIMContainer::getDetachedConversationFloaters(floater_list_t& floaters)
+{
+ typedef conversations_widgets_map::value_type conv_pair;
+ LLFloaterIMNearbyChat *nearby_chat = LLFloaterReg::findTypedInstance<LLFloaterIMNearbyChat>("nearby_chat");
+
+ BOOST_FOREACH(conv_pair item, mConversationsWidgets)
+ {
+ LLConversationViewSession* widget = dynamic_cast<LLConversationViewSession*>(item.second);
+ if (widget)
+ {
+ LLFloater* session_floater = widget->getSessionFloater();
+
+ // Exclude nearby chat from output, as it should be handled separately
+ if (session_floater && session_floater->isDetachedAndNotMinimized()
+ && session_floater != nearby_chat)
+ {
+ floaters.push_back(session_floater);
+ }
+ }
+ }
+}
+
+void LLFloaterIMContainer::setVisibleAndFrontmost(BOOL take_focus, const LLSD& key)
+{
+ LLMultiFloater::setVisibleAndFrontmost(take_focus, key);
+ // Do not select "Nearby Chat" conversation, since it will bring its window to front
+ // Only select other sessions
+ if (!getSelectedSession().isNull())
+ {
+ selectConversationPair(getSelectedSession(), false, take_focus);
+ }
+ if (mInitialized && mIsFirstLaunch)
+ {
+ collapseMessagesPane(gSavedPerAccountSettings.getBOOL("ConversationsMessagePaneCollapsed"));
+ mIsFirstLaunch = false;
+}
+}
+
+void LLFloaterIMContainer::updateResizeLimits()
+{
+ LLMultiFloater::updateResizeLimits();
+ assignResizeLimits();
+}
+
+bool LLFloaterIMContainer::isMessagesPaneCollapsed()
+{
+ return mMessagesPane->isCollapsed();
+}
+
+bool LLFloaterIMContainer::isConversationsPaneCollapsed()
+{
+ return mConversationsPane->isCollapsed();
+}
+
+void LLFloaterIMContainer::collapseMessagesPane(bool collapse)
+{
+ if (mMessagesPane->isCollapsed() == collapse)
+ {
+ return;
+ }
+
+ // Save current width of panels before collapsing/expanding right pane.
+ S32 conv_pane_width = mConversationsPane->getRect().getWidth();
+ S32 msg_pane_width = mMessagesPane->getRect().getWidth();
+
+ if (collapse)
+ {
+ // Save the messages pane width before collapsing it.
+ gSavedPerAccountSettings.setS32("ConversationsMessagePaneWidth", msg_pane_width);
+
+ // Save the order in which the panels are closed to reverse user's last action.
+ gSavedPerAccountSettings.setBOOL("ConversationsExpandMessagePaneFirst", mConversationsPane->isCollapsed());
+ }
+
+ mConversationsPane->setIgnoreReshape(collapse);
+
+ // Show/hide the messages pane.
+ mConversationsStack->collapsePanel(mMessagesPane, collapse);
+
+ // Make sure layout is updated before resizing conversation pane.
+ mConversationsStack->updateLayout();
+
+ reshapeFloaterAndSetResizeLimits(collapse, gSavedPerAccountSettings.getS32("ConversationsMessagePaneWidth"));
+
+ if (!collapse)
+ {
+ // Restore conversation's pane previous width after expanding messages pane.
+ mConversationsPane->setTargetDim(conv_pane_width);
+ }
+}
+
+void LLFloaterIMContainer::collapseConversationsPane(bool collapse, bool save_is_allowed /*=true*/)
+{
+ if (mConversationsPane->isCollapsed() == collapse)
+ {
+ return;
+ }
+
+ LLView* button_panel = getChild<LLView>("conversations_pane_buttons_expanded");
+ button_panel->setVisible(!collapse);
+ mExpandCollapseBtn->setImageOverlay(getString(collapse ? "expand_icon" : "collapse_icon"));
+
+ // Save current width of Conversation panel before collapsing/expanding right pane.
+ S32 conv_pane_width = mConversationsPane->getRect().getWidth();
+
+ if (collapse && save_is_allowed)
+ {
+ // Save the conversations pane width before collapsing it.
+ gSavedPerAccountSettings.setS32("ConversationsListPaneWidth", conv_pane_width);
+
+ // Save the order in which the panels are closed to reverse user's last action.
+ gSavedPerAccountSettings.setBOOL("ConversationsExpandMessagePaneFirst", !mMessagesPane->isCollapsed());
+ }
+
+ mConversationsStack->collapsePanel(mConversationsPane, collapse);
+ if (!collapse)
+ {
+ // Make sure layout is updated before resizing conversation pane.
+ mConversationsStack->updateLayout();
+ // Restore conversation's pane previous width.
+ mConversationsPane->setTargetDim(gSavedPerAccountSettings.getS32("ConversationsListPaneWidth"));
+ }
+
+ S32 delta_width = gSavedPerAccountSettings.getS32("ConversationsListPaneWidth")
+ - mConversationsPane->getMinDim() - mConversationsStack->getPanelSpacing() + 1;
+
+ reshapeFloaterAndSetResizeLimits(collapse, delta_width);
+
+ for (conversations_widgets_map::iterator widget_it = mConversationsWidgets.begin();
+ widget_it != mConversationsWidgets.end(); ++widget_it)
+ {
+ LLConversationViewSession* widget = dynamic_cast<LLConversationViewSession*>(widget_it->second);
+ if (widget)
+ {
+ widget->toggleCollapsedMode(collapse);
+
+ // force closing all open conversations when collapsing to minimized state
+ if (collapse)
+ {
+ widget->setOpen(false);
+ }
+ widget->requestArrange();
+ }
+ }
+}
+
+void LLFloaterIMContainer::reshapeFloaterAndSetResizeLimits(bool collapse, S32 delta_width)
+{
+ LLRect floater_rect = getRect();
+ floater_rect.mRight += ((collapse ? -1 : 1) * delta_width);
+
+ // Set by_user = true so that reshaped rect is saved in user_settings.
+ setShape(floater_rect, true);
+ updateResizeLimits();
+
+ bool at_least_one_panel_is_expanded =
+ ! (mConversationsPane->isCollapsed() && mMessagesPane->isCollapsed());
+
+ setCanResize(at_least_one_panel_is_expanded);
+ setCanMinimize(at_least_one_panel_is_expanded);
+
+ assignResizeLimits();
+}
+
+void LLFloaterIMContainer::assignResizeLimits()
+{
+ bool is_conv_pane_expanded = !mConversationsPane->isCollapsed();
+ bool is_msg_pane_expanded = !mMessagesPane->isCollapsed();
+
+ S32 summary_width_of_visible_borders = (is_msg_pane_expanded ? mConversationsStack->getPanelSpacing() : 0) + 1;
+
+ S32 conv_pane_target_width = is_conv_pane_expanded
+ ? ( is_msg_pane_expanded?mConversationsPane->getRect().getWidth():mConversationsPane->getExpandedMinDim() )
+ : mConversationsPane->getMinDim();
+
+ S32 msg_pane_min_width = is_msg_pane_expanded ? mMessagesPane->getExpandedMinDim() : 0;
+ S32 new_min_width = conv_pane_target_width + msg_pane_min_width + summary_width_of_visible_borders;
+
+ setResizeLimits(new_min_width, getMinHeight());
+
+ mConversationsStack->updateLayout();
+}
+
+void LLFloaterIMContainer::onAddButtonClicked()
+{
+ LLView * button = findChild<LLView>("conversations_pane_buttons_expanded")->findChild<LLButton>("add_btn");
+ LLFloater* root_floater = gFloaterView->getParentFloater(this);
+ LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(boost::bind(&LLFloaterIMContainer::onAvatarPicked, this, _1), TRUE, TRUE, TRUE, root_floater->getName(), button);
+
+ if (picker && root_floater)
+ {
+ root_floater->addDependentFloater(picker);
+ }
+}
+
+void LLFloaterIMContainer::onAvatarPicked(const uuid_vec_t& ids)
+{
+ if (ids.size() == 1)
+ {
+ LLAvatarActions::startIM(ids.back());
+ }
+ else
+ {
+ LLAvatarActions::startConference(ids);
+ }
+}
+
+void LLFloaterIMContainer::onCustomAction(const LLSD& userdata)
+{
+ std::string command = userdata.asString();
+
+ if ("sort_sessions_by_type" == command)
+ {
+ setSortOrderSessions(LLConversationFilter::SO_SESSION_TYPE);
+ }
+ if ("sort_sessions_by_name" == command)
+ {
+ setSortOrderSessions(LLConversationFilter::SO_NAME);
+ }
+ if ("sort_sessions_by_recent" == command)
+ {
+ setSortOrderSessions(LLConversationFilter::SO_DATE);
+ }
+ if ("sort_participants_by_name" == command)
+ {
+ setSortOrderParticipants(LLConversationFilter::SO_NAME);
+ }
+ if ("sort_participants_by_recent" == command)
+ {
+ setSortOrderParticipants(LLConversationFilter::SO_DATE);
+ }
+ if ("sort_participants_by_distance" == command)
+ {
+ setSortOrderParticipants(LLConversationFilter::SO_DISTANCE);
+ }
+ if ("chat_preferences" == command)
+ {
+ LLFloaterPreference * floater_prefp = LLFloaterReg::showTypedInstance<LLFloaterPreference>("preferences");
+ if (floater_prefp)
+ {
+ floater_prefp->selectChatPanel();
+ }
+ }
+ if ("privacy_preferences" == command)
+ {
+ LLFloaterPreference * floater_prefp = LLFloaterReg::showTypedInstance<LLFloaterPreference>("preferences");
+ if (floater_prefp)
+ {
+ floater_prefp->selectPrivacyPanel();
+ }
+ }
+ if ("Translating.Toggle" == command)
+ {
+ gSavedSettings.setBOOL("TranslateChat", !gSavedSettings.getBOOL("TranslateChat"));
+ }
+}
+
+BOOL LLFloaterIMContainer::isActionChecked(const LLSD& userdata)
+{
+ LLConversationSort order = mConversationViewModel.getSorter();
+ std::string command = userdata.asString();
+ if ("sort_sessions_by_type" == command)
+ {
+ return (order.getSortOrderSessions() == LLConversationFilter::SO_SESSION_TYPE);
+ }
+ if ("sort_sessions_by_name" == command)
+ {
+ return (order.getSortOrderSessions() == LLConversationFilter::SO_NAME);
+ }
+ if ("sort_sessions_by_recent" == command)
+ {
+ return (order.getSortOrderSessions() == LLConversationFilter::SO_DATE);
+ }
+ if ("sort_participants_by_name" == command)
+ {
+ return (order.getSortOrderParticipants() == LLConversationFilter::SO_NAME);
+ }
+ if ("sort_participants_by_recent" == command)
+ {
+ return (order.getSortOrderParticipants() == LLConversationFilter::SO_DATE);
+ }
+ if ("sort_participants_by_distance" == command)
+ {
+ return (order.getSortOrderParticipants() == LLConversationFilter::SO_DISTANCE);
+ }
+ if ("Translating.Enabled" == command)
+ {
+ return gSavedPerAccountSettings.getBOOL("TranslatingEnabled");
+ }
+ if ("Translating.On" == command)
+ {
+ return gSavedSettings.getBOOL("TranslateChat");
+ }
+ return FALSE;
+}
+
+void LLFloaterIMContainer::setSortOrderSessions(const LLConversationFilter::ESortOrderType order)
+{
+ LLConversationSort old_order = mConversationViewModel.getSorter();
+ if (order != old_order.getSortOrderSessions())
+ {
+ old_order.setSortOrderSessions(order);
+ setSortOrder(old_order);
+ }
+}
+
+void LLFloaterIMContainer::setSortOrderParticipants(const LLConversationFilter::ESortOrderType order)
+{
+ LLConversationSort old_order = mConversationViewModel.getSorter();
+ if (order != old_order.getSortOrderParticipants())
+ {
+ old_order.setSortOrderParticipants(order);
+ setSortOrder(old_order);
+ }
+}
+
+void LLFloaterIMContainer::setSortOrder(const LLConversationSort& order)
+{
+ mConversationViewModel.setSorter(order);
+ mConversationsRoot->arrangeAll();
+ // try to keep selection onscreen, even if it wasn't to start with
+ mConversationsRoot->scrollToShowSelection();
+
+ // Notify all conversation (torn off or not) of the change to the sort order
+ // Note: For the moment, the sort order is *unique* across all conversations. That might change in the future.
+ for (conversations_items_map::iterator it_session = mConversationsItems.begin(); it_session != mConversationsItems.end(); it_session++)
+ {
+ LLUUID session_id = it_session->first;
+ LLFloaterIMSessionTab *conversation_floater = (session_id.isNull() ? (LLFloaterIMSessionTab*)(LLFloaterReg::findTypedInstance<LLFloaterIMNearbyChat>("nearby_chat")) : (LLFloaterIMSessionTab*)(LLFloaterIMSession::findInstance(session_id)));
+ if (conversation_floater)
+ {
+ conversation_floater->setSortOrder(order);
+ }
+ }
+
+ gSavedSettings.setU32("ConversationSortOrder", (U32)order);
+}
+
+void LLFloaterIMContainer::getSelectedUUIDs(uuid_vec_t& selected_uuids, bool participant_uuids/* = true*/)
+{
+ const std::set<LLFolderViewItem*> selectedItems = mConversationsRoot->getSelectionList();
+
+ std::set<LLFolderViewItem*>::const_iterator it = selectedItems.begin();
+ const std::set<LLFolderViewItem*>::const_iterator it_end = selectedItems.end();
+ LLConversationItem * conversationItem;
+
+ for (; it != it_end; ++it)
+ {
+ conversationItem = static_cast<LLConversationItem *>((*it)->getViewModelItem());
+
+ //When a one-on-one conversation exists, retrieve the participant id from the conversation floater
+ if(conversationItem->getType() == LLConversationItem::CONV_SESSION_1_ON_1 && participant_uuids)
+ {
+ LLFloaterIMSession * conversation_floaterp = LLFloaterIMSession::findInstance(conversationItem->getUUID());
+ LLUUID participant_id = conversation_floaterp->getOtherParticipantUUID();
+ selected_uuids.push_back(participant_id);
+ }
+ else
+ {
+ selected_uuids.push_back(conversationItem->getUUID());
+ }
+ }
+}
+
+const LLConversationItem * LLFloaterIMContainer::getCurSelectedViewModelItem()
+{
+ LLConversationItem * conversation_item = NULL;
+
+ if(mConversationsRoot &&
+ mConversationsRoot->getCurSelectedItem() &&
+ mConversationsRoot->getCurSelectedItem()->getViewModelItem())
+ {
+ LLFloaterIMSessionTab *selected_session_floater = LLFloaterIMSessionTab::getConversation(mSelectedSession);
+ if (selected_session_floater && !selected_session_floater->getHost() && selected_session_floater->getCurSelectedViewModelItem())
+ {
+ conversation_item = selected_session_floater->getCurSelectedViewModelItem();
+ }
+ else
+ {
+ conversation_item = static_cast<LLConversationItem *>(mConversationsRoot->getCurSelectedItem()->getViewModelItem());
+ }
+ }
+
+ return conversation_item;
+}
+
+void LLFloaterIMContainer::getParticipantUUIDs(uuid_vec_t& selected_uuids)
+{
+ //Find the conversation floater associated with the selected id
+ const LLConversationItem * conversation_item = getCurSelectedViewModelItem();
+
+ if (NULL == conversation_item)
+ {
+ return;
+ }
+
+ getSelectedUUIDs(selected_uuids);
+}
+
+void LLFloaterIMContainer::doToParticipants(const std::string& command, uuid_vec_t& selectedIDS)
+{
+ if (selectedIDS.size() == 1)
+ {
+ const LLUUID& userID = selectedIDS.front();
+ if ("view_profile" == command)
+ {
+ LLAvatarActions::showProfile(userID);
+ }
+ else if ("im" == command)
+ {
+ if (gAgent.getID() != userID)
+ {
+ LLAvatarActions::startIM(userID);
+ }
+ }
+ else if ("offer_teleport" == command)
+ {
+ LLAvatarActions::offerTeleport(selectedIDS);
+ }
+ else if ("request_teleport" == command)
+ {
+ LLAvatarActions::teleportRequest(selectedIDS.front());
+ }
+ else if ("voice_call" == command)
+ {
+ LLAvatarActions::startCall(userID);
+ }
+ else if ("chat_history" == command)
+ {
+ LLAvatarActions::viewChatHistory(userID);
+ }
+ else if ("add_friend" == command)
+ {
+ LLAvatarActions::requestFriendshipDialog(userID);
+ }
+ else if ("remove_friend" == command)
+ {
+ LLAvatarActions::removeFriendDialog(userID);
+ }
+ else if ("invite_to_group" == command)
+ {
+ LLAvatarActions::inviteToGroup(userID);
+ }
+ else if ("zoom_in" == command)
+ {
+ handle_zoom_to_object(userID);
+ }
+ else if ("map" == command)
+ {
+ LLAvatarActions::showOnMap(userID);
+ }
+ else if ("share" == command)
+ {
+ LLAvatarActions::share(userID);
+ }
+ else if ("pay" == command)
+ {
+ LLAvatarActions::pay(userID);
+ }
+ else if ("block_unblock" == command)
+ {
+ toggleMute(userID, LLMute::flagVoiceChat);
+ }
+ else if ("mute_unmute" == command)
+ {
+ toggleMute(userID, LLMute::flagTextChat);
+ }
+ else if ("selected" == command || "mute_all" == command || "unmute_all" == command)
+ {
+ moderateVoice(command, userID);
+ }
+ else if ("toggle_allow_text_chat" == command)
+ {
+ toggleAllowTextChat(userID);
+ }
+ }
+ else if (selectedIDS.size() > 1)
+ {
+ if ("im" == command)
+ {
+ LLAvatarActions::startConference(selectedIDS);
+ }
+ else if ("offer_teleport" == command)
+ {
+ LLAvatarActions::offerTeleport(selectedIDS);
+ }
+ else if ("voice_call" == command)
+ {
+ LLAvatarActions::startAdhocCall(selectedIDS);
+ }
+ else if ("remove_friend" == command)
+ {
+ LLAvatarActions::removeFriendsDialog(selectedIDS);
+ }
+ }
+}
+
+void LLFloaterIMContainer::doToSelectedConversation(const std::string& command, uuid_vec_t& selectedIDS)
+{
+ //Find the conversation floater associated with the selected id
+ const LLConversationItem * conversationItem = getCurSelectedViewModelItem();
+ LLFloaterIMSession *conversationFloater = LLFloaterIMSession::findInstance(conversationItem->getUUID());
+
+ if(conversationFloater)
+ {
+ //Close the selected conversation
+ if("close_conversation" == command)
+ {
+ LLFloater::onClickClose(conversationFloater);
+ }
+ else if("close_selected_conversations" == command)
+ {
+ getSelectedUUIDs(selectedIDS,false);
+ closeSelectedConversations(selectedIDS);
+ }
+ else if("open_voice_conversation" == command)
+ {
+ gIMMgr->startCall(conversationItem->getUUID());
+ }
+ else if("disconnect_from_voice" == command)
+ {
+ gIMMgr->endCall(conversationItem->getUUID());
+ }
+ else if("chat_history" == command)
+ {
+ if (selectedIDS.size() > 0)
+ {
+ LLAvatarActions::viewChatHistory(selectedIDS.front());
+ }
+ }
+ else
+ {
+ if(conversationItem->getType() == LLConversationItem::CONV_SESSION_1_ON_1)
+ {
+ doToParticipants(command, selectedIDS);
+ }
+ }
+ }
+ //if there is no LLFloaterIMSession* instance for selected conversation it might be Nearby chat
+ else
+ {
+ if(conversationItem->getType() == LLConversationItem::CONV_SESSION_NEARBY)
+ {
+ if("chat_history" == command)
+ {
+ LLFloaterReg::showInstance("preview_conversation", LLSD(LLUUID::null), true);
+ }
+}
+ }
+}
+
+void LLFloaterIMContainer::doToSelected(const LLSD& userdata)
+{
+ std::string command = userdata.asString();
+ const LLConversationItem * conversationItem = getCurSelectedViewModelItem();
+ uuid_vec_t selected_uuids;
+
+ if(conversationItem != NULL)
+ {
+ getParticipantUUIDs(selected_uuids);
+
+ if(conversationItem->getType() == LLConversationItem::CONV_PARTICIPANT)
+ {
+ doToParticipants(command, selected_uuids);
+ }
+ else
+ {
+ doToSelectedConversation(command, selected_uuids);
+ }
+ }
+}
+
+void LLFloaterIMContainer::doToSelectedGroup(const LLSD& userdata)
+{
+ std::string action = userdata.asString();
+
+ if (action == "group_profile")
+ {
+ LLGroupActions::show(mSelectedSession);
+ }
+ else if (action == "activate_group")
+ {
+ LLGroupActions::activate(mSelectedSession);
+ }
+ else if (action == "leave_group")
+ {
+ LLGroupActions::leave(mSelectedSession);
+ }
+}
+
+bool LLFloaterIMContainer::enableContextMenuItem(const LLSD& userdata)
+{
+ const std::string& item = userdata.asString();
+ uuid_vec_t uuids;
+ getParticipantUUIDs(uuids);
+
+ if ("conversation_log" == item)
+ {
+ return gSavedPerAccountSettings.getS32("KeepConversationLogTranscripts") > 0;
+ }
+
+ //Enable Chat history item for ad-hoc and group conversations
+ if ("can_chat_history" == item && uuids.size() > 0)
+ {
+ //Disable menu item if selected participant is user agent
+ if(uuids.front() != gAgentID)
+ {
+ if (getCurSelectedViewModelItem()->getType() == LLConversationItem::CONV_SESSION_NEARBY)
+ {
+ return LLLogChat::isNearbyTranscriptExist();
+ }
+ else
+ {
+ bool is_group = (getCurSelectedViewModelItem()->getType() == LLConversationItem::CONV_SESSION_GROUP);
+ return LLLogChat::isTranscriptExist(uuids.front(),is_group);
+ }
+ }
+ }
+
+ // If nothing is selected(and selected item is not group chat), everything needs to be disabled
+ if (uuids.size() <= 0)
+ {
+ if(getCurSelectedViewModelItem())
+ {
+ return getCurSelectedViewModelItem()->getType() == LLConversationItem::CONV_SESSION_GROUP;
+ }
+ return false;
+ }
+
+ if("can_activate_group" == item)
+ {
+ LLUUID selected_group_id = getCurSelectedViewModelItem()->getUUID();
+ return gAgent.getGroupID() != selected_group_id;
+ }
+
+ return enableContextMenuItem(item, uuids);
+}
+
+bool LLFloaterIMContainer::enableContextMenuItem(const std::string& item, uuid_vec_t& uuids)
+{
+ // Extract the single select info
+ bool is_single_select = (uuids.size() == 1);
+ const LLUUID& single_id = uuids.front();
+
+ // Handle options that are applicable to all including the user agent
+ if ("can_view_profile" == item)
+ {
+ return is_single_select;
+ }
+
+ // Beyond that point, if only the user agent is selected, everything is disabled
+ if (is_single_select && (single_id == gAgentID))
+ {
+ return false;
+ }
+
+ // If the user agent is selected with others, everything is disabled
+ for (uuid_vec_t::const_iterator id = uuids.begin(); id != uuids.end(); ++id)
+ {
+ if (gAgent.getID() == *id)
+ {
+ return false;
+ }
+ }
+
+ // Handle all other options
+ if (("can_invite" == item) || ("can_chat_history" == item) || ("can_share" == item) || ("can_pay" == item))
+ {
+ // Those menu items are enable only if a single avatar is selected
+ return is_single_select;
+ }
+ else if ("can_block" == item)
+ {
+ return (is_single_select ? LLAvatarActions::canBlock(single_id) : false);
+ }
+ else if ("can_add" == item)
+ {
+ // We can add friends if:
+ // - there is only 1 selected avatar (EXT-7389)
+ // - this avatar is not already a friend
+ return (is_single_select ? !LLAvatarActions::isFriend(single_id) : false);
+ }
+ else if ("can_delete" == item)
+ {
+ // We can remove friends if there are only friends among the selection
+ bool result = true;
+ for (uuid_vec_t::const_iterator id = uuids.begin(); id != uuids.end(); ++id)
+ {
+ result &= LLAvatarActions::isFriend(*id);
+ }
+ return result;
+ }
+ else if ("can_call" == item)
+ {
+ return LLAvatarActions::canCall();
+ }
+ else if ("can_zoom_in" == item)
+ {
+ return is_single_select && gObjectList.findObject(single_id);
+ }
+ else if ("can_show_on_map" == item)
+ {
+ return (is_single_select ? (LLAvatarTracker::instance().isBuddyOnline(single_id) && is_agent_mappable(single_id)) || gAgent.isGodlike() : false);
+ }
+ else if ("can_offer_teleport" == item)
+ {
+ return LLAvatarActions::canOfferTeleport(uuids);
+ }
+ else if (("can_moderate_voice" == item) || ("can_allow_text_chat" == item) || ("can_mute" == item) || ("can_unmute" == item))
+ {
+ // *TODO : get that out of here...
+ return enableModerateContextMenuItem(item);
+ }
+
+ // By default, options that not explicitely disabled are enabled
+ return true;
+}
+
+bool LLFloaterIMContainer::checkContextMenuItem(const LLSD& userdata)
+{
+ std::string item = userdata.asString();
+ uuid_vec_t uuids;
+ getParticipantUUIDs(uuids);
+
+ return checkContextMenuItem(item, uuids);
+}
+
+bool LLFloaterIMContainer::checkContextMenuItem(const std::string& item, uuid_vec_t& uuids)
+{
+ if (uuids.size() == 1)
+ {
+ if ("is_blocked" == item)
+ {
+ return LLMuteList::getInstance()->isMuted(uuids.front(), LLMute::flagVoiceChat);
+ }
+ else if (item == "is_muted")
+ {
+ return LLMuteList::getInstance()->isMuted(uuids.front(), LLMute::flagTextChat);
+ }
+ else if ("is_allowed_text_chat" == item)
+ {
+ const LLSpeaker * speakerp = getSpeakerOfSelectedParticipant(getSpeakerMgrForSelectedParticipant());
+
+ if (NULL != speakerp)
+ {
+ return !speakerp->mModeratorMutedText;
+ }
+ }
+ }
+
+ return false;
+}
+
+bool LLFloaterIMContainer::visibleContextMenuItem(const LLSD& userdata)
+{
+ const std::string& item = userdata.asString();
+
+ if ("show_mute" == item)
+ {
+ return !isMuted(getCurSelectedViewModelItem()->getUUID());
+ }
+ else if ("show_unmute" == item)
+ {
+ return isMuted(getCurSelectedViewModelItem()->getUUID());
+ }
+
+ return true;
+}
+
+void LLFloaterIMContainer::showConversation(const LLUUID& session_id)
+{
+ setVisibleAndFrontmost(false);
+ selectConversationPair(session_id, true);
+
+ LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::findConversation(session_id);
+ if (session_floater)
+ {
+ session_floater->restoreFloater();
+ }
+}
+
+void LLFloaterIMContainer::clearAllFlashStates()
+{
+ conversations_widgets_map::iterator widget_it = mConversationsWidgets.begin();
+ for (;widget_it != mConversationsWidgets.end(); ++widget_it)
+ {
+ LLConversationViewSession* widget = dynamic_cast<LLConversationViewSession*>(widget_it->second);
+ if (widget)
+ {
+ widget->setFlashState(false);
+ }
+ }
+}
+
+void LLFloaterIMContainer::selectConversation(const LLUUID& session_id)
+{
+ selectConversationPair(session_id, true);
+}
+
+// Select the conversation *after* (or before if none after) the passed uuid conversation
+// Used to change the selection on key hits
+void LLFloaterIMContainer::selectNextConversationByID(const LLUUID& uuid)
+{
+ bool new_selection = false;
+ selectConversation(uuid);
+ new_selection = selectNextorPreviousConversation(true);
+ if (!new_selection)
+ {
+ selectNextorPreviousConversation(false);
+ }
+}
+
+// Synchronous select the conversation item and the conversation floater
+BOOL LLFloaterIMContainer::selectConversationPair(const LLUUID& session_id, bool select_widget, bool focus_floater/*=true*/)
+{
+ BOOL handled = TRUE;
+ LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::findConversation(session_id);
+
+ /* widget processing */
+ if (select_widget && mConversationsRoot->getSelectedCount() <= 1)
+ {
+ LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,session_id);
+ if (widget && widget->getParentFolder())
+ {
+ widget->getParentFolder()->setSelection(widget, FALSE, FALSE);
+ mConversationsRoot->scrollToShowSelection();
+ }
+ }
+
+ /* floater processing */
+
+ if (NULL != session_floater)
+ {
+ if (session_id != getSelectedSession())
+ {
+ // Store the active session
+ setSelectedSession(session_id);
+
+
+
+ if (session_floater->getHost())
+ {
+ // Always expand the message pane if the panel is hosted by the container
+ collapseMessagesPane(false);
+ // Switch to the conversation floater that is being selected
+ selectFloater(session_floater);
+ }
+ else
+ {
+ showStub(true);
+ }
+
+ //When in DND mode, remove stored IM notifications
+ //Nearby chat (Null) IMs are not stored while in DND mode, so can ignore removal
+ if(gAgent.isDoNotDisturb() && session_id.notNull())
+ {
+ LLDoNotDisturbNotificationStorage::getInstance()->removeNotification(LLDoNotDisturbNotificationStorage::toastName, session_id);
+ }
+ }
+
+ // Set the focus on the selected floater
+ if (!session_floater->hasFocus() && !session_floater->isMinimized())
+ {
+ session_floater->setFocus(focus_floater);
+ }
+ }
+ flashConversationItemWidget(session_id,false);
+ return handled;
+}
+
+void LLFloaterIMContainer::setTimeNow(const LLUUID& session_id, const LLUUID& participant_id)
+{
+ LLConversationItemSession* item = dynamic_cast<LLConversationItemSession*>(get_ptr_in_map(mConversationsItems,session_id));
+ if (item)
+ {
+ item->setTimeNow(participant_id);
+ mConversationViewModel.requestSortAll();
+ mConversationsRoot->arrangeAll();
+ }
+}
+
+void LLFloaterIMContainer::setNearbyDistances()
+{
+ // Get the nearby chat session: that's the one with uuid nul
+ LLConversationItemSession* item = dynamic_cast<LLConversationItemSession*>(get_ptr_in_map(mConversationsItems,LLUUID()));
+ if (item)
+ {
+ // Get the positions of the nearby avatars and their ids
+ std::vector<LLVector3d> positions;
+ uuid_vec_t avatar_ids;
+ LLWorld::getInstance()->getAvatars(&avatar_ids, &positions, gAgent.getPositionGlobal(), gSavedSettings.getF32("NearMeRange"));
+ // Get the position of the agent
+ const LLVector3d& me_pos = gAgent.getPositionGlobal();
+ // For each nearby avatar, compute and update the distance
+ int avatar_count = positions.size();
+ for (int i = 0; i < avatar_count; i++)
+ {
+ F64 dist = dist_vec_squared(positions[i], me_pos);
+ item->setDistance(avatar_ids[i],dist);
+ }
+ // Also does it for the agent itself
+ item->setDistance(gAgent.getID(),0.0f);
+ // Request resort
+ mConversationViewModel.requestSortAll();
+ mConversationsRoot->arrangeAll();
+ }
+}
+
+LLConversationItem* LLFloaterIMContainer::addConversationListItem(const LLUUID& uuid, bool isWidgetSelected /*= false*/)
+{
+ bool is_nearby_chat = uuid.isNull();
+
+ // Stores the display name for the conversation line item
+ std::string display_name = is_nearby_chat ? LLTrans::getString("NearbyChatLabel") : LLIMModel::instance().getName(uuid);
+
+ // Check if the item is not already in the list, exit (nothing to do)
+ // Note: this happens often, when reattaching a torn off conversation for instance
+ conversations_items_map::iterator item_it = mConversationsItems.find(uuid);
+ if (item_it != mConversationsItems.end())
+ {
+ return item_it->second;
+ }
+
+ // Create a conversation session model
+ LLConversationItemSession* item = NULL;
+ LLSpeakerMgr* speaker_manager = (is_nearby_chat ? (LLSpeakerMgr*)(LLLocalSpeakerMgr::getInstance()) : LLIMModel::getInstance()->getSpeakerManager(uuid));
+ if (speaker_manager)
+ {
+ item = new LLParticipantList(speaker_manager, getRootViewModel());
+ }
+ if (!item)
+ {
+ llwarns << "Couldn't create conversation session item : " << display_name << llendl;
+ return NULL;
+ }
+ item->renameItem(display_name);
+ item->updateName(NULL);
+
+ mConversationsItems[uuid] = item;
+
+ // Create a widget from it
+ LLConversationViewSession* widget = createConversationItemWidget(item);
+ mConversationsWidgets[uuid] = widget;
+
+ // Add a new conversation widget to the root folder of the folder view
+ widget->addToFolder(mConversationsRoot);
+ widget->requestArrange();
+
+ LLIMModel::LLIMSession * im_sessionp = LLIMModel::getInstance()->findIMSession(uuid);
+
+ // Create the participants widgets now
+ // Note: usually, we do not get an updated avatar list at that point
+ if (uuid.isNull() || (im_sessionp && !im_sessionp->isP2PSessionType()))
+ {
+ LLFolderViewModelItemCommon::child_list_t::const_iterator current_participant_model = item->getChildrenBegin();
+ LLFolderViewModelItemCommon::child_list_t::const_iterator end_participant_model = item->getChildrenEnd();
+ while (current_participant_model != end_participant_model)
+ {
+ LLConversationItem* participant_model = dynamic_cast<LLConversationItem*>(*current_participant_model);
+ LLConversationViewParticipant* participant_view = createConversationViewParticipant(participant_model);
+ participant_view->addToFolder(widget);
+ current_participant_model++;
+ }
+ }
+
+ if (uuid.notNull() && im_sessionp->isP2PSessionType())
+ {
+ item->fetchAvatarName(false);
+ }
+
+ // Do that too for the conversation dialog
+ LLFloaterIMSessionTab *conversation_floater = (uuid.isNull() ? (LLFloaterIMSessionTab*)(LLFloaterReg::findTypedInstance<LLFloaterIMNearbyChat>("nearby_chat")) : (LLFloaterIMSessionTab*)(LLFloaterIMSession::findInstance(uuid)));
+ if (conversation_floater)
+ {
+ conversation_floater->buildConversationViewParticipant();
+ }
+
+ // set the widget to minimized mode if conversations pane is collapsed
+ widget->toggleCollapsedMode(mConversationsPane->isCollapsed());
+
+ if (isWidgetSelected || 0 == mConversationsRoot->getSelectedCount())
+ {
+ selectConversationPair(uuid, true);
+ widget->requestArrange();
+
+ // scroll to newly added item
+ mConversationsRoot->scrollToShowSelection();
+ }
+
+ return item;
+}
+
+bool LLFloaterIMContainer::removeConversationListItem(const LLUUID& uuid, bool change_focus)
+{
+ // Delete the widget and the associated conversation item
+ // Note : since the mConversationsItems is also the listener to the widget, deleting
+ // the widget will also delete its listener
+ bool is_widget_selected = false;
+ LLFolderViewItem* new_selection = NULL;
+ LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,uuid);
+ if (widget)
+ {
+ is_widget_selected = widget->isSelected();
+ new_selection = mConversationsRoot->getNextFromChild(widget, FALSE);
+ if (!new_selection)
+ {
+ new_selection = mConversationsRoot->getPreviousFromChild(widget, FALSE);
+ }
+ widget->destroyView();
+ }
+
+ // Suppress the conversation items and widgets from their respective maps
+ mConversationsItems.erase(uuid);
+ mConversationsWidgets.erase(uuid);
+
+ // Don't let the focus fall IW, select and refocus on the first conversation in the list
+ if (change_focus)
+ {
+ setFocus(TRUE);
+ if (new_selection)
+ {
+ if (mConversationsWidgets.size() == 1)
+ {
+ // If only one widget is left, it has to be the Nearby Chat. Select it directly.
+ selectConversationPair(LLUUID(NULL), true);
+ }
+ else
+ {
+ LLConversationItem* vmi = dynamic_cast<LLConversationItem*>(new_selection->getViewModelItem());
+ if (vmi)
+ {
+ selectConversationPair(vmi->getUUID(), true);
+ }
+ }
+ }
+ }
+ return is_widget_selected;
+}
+
+LLConversationViewSession* LLFloaterIMContainer::createConversationItemWidget(LLConversationItem* item)
+{
+ LLConversationViewSession::Params params;
+
+ params.name = item->getDisplayName();
+ params.root = mConversationsRoot;
+ params.listener = item;
+ params.tool_tip = params.name;
+ params.container = this;
+
+ //Indentation for aligning the p2p converstation image with the nearby chat arrow
+ if(item->getType() == LLConversationItem::CONV_SESSION_1_ON_1)
+ {
+ params.folder_indentation = 3;
+ }
+
+ return LLUICtrlFactory::create<LLConversationViewSession>(params);
+}
+
+LLConversationViewParticipant* LLFloaterIMContainer::createConversationViewParticipant(LLConversationItem* item)
+{
+ LLConversationViewParticipant::Params params;
+ LLRect panel_rect = mConversationsListPanel->getRect();
+
+ params.name = item->getDisplayName();
+ params.root = mConversationsRoot;
+ params.listener = item;
+
+ //24 is the the current hight of an item (itemHeight) loaded from conversation_view_participant.xml.
+ params.rect = LLRect (0, 24, panel_rect.getWidth(), 0);
+ params.tool_tip = params.name;
+ params.participant_id = item->getUUID();
+ params.folder_indentation = 27;
+
+ return LLUICtrlFactory::create<LLConversationViewParticipant>(params);
+}
+
+bool LLFloaterIMContainer::enableModerateContextMenuItem(const std::string& userdata)
+{
+ // only group moderators can perform actions related to this "enable callback"
+ if (!isGroupModerator())
+ {
+ return false;
+ }
+
+ LLSpeaker * speakerp = getSpeakerOfSelectedParticipant(getSpeakerMgrForSelectedParticipant());
+ if (NULL == speakerp)
+ {
+ return false;
+ }
+
+ bool voice_channel = speakerp->isInVoiceChannel();
+
+ if ("can_moderate_voice" == userdata)
+ {
+ return voice_channel;
+ }
+ else if ("can_mute" == userdata)
+ {
+ return voice_channel && !isMuted(getCurSelectedViewModelItem()->getUUID());
+ }
+ else if ("can_unmute" == userdata)
+ {
+ return voice_channel && isMuted(getCurSelectedViewModelItem()->getUUID());
+ }
+
+ // The last invoke is used to check whether the "can_allow_text_chat" will enabled
+ return LLVoiceClient::getInstance()->isParticipantAvatar(getCurSelectedViewModelItem()->getUUID());
+}
+
+bool LLFloaterIMContainer::isGroupModerator()
+{
+ LLSpeakerMgr * speaker_manager = getSpeakerMgrForSelectedParticipant();
+ if (NULL == speaker_manager)
+ {
+ llwarns << "Speaker manager is missing" << llendl;
+ return false;
+ }
+
+ // Is session a group call/chat?
+ if(gAgent.isInGroup(speaker_manager->getSessionID()))
+ {
+ LLSpeaker * speaker = speaker_manager->findSpeaker(gAgentID).get();
+
+ // Is agent a moderator?
+ return speaker && speaker->mIsModerator;
+ }
+
+ return false;
+}
+
+void LLFloaterIMContainer::moderateVoice(const std::string& command, const LLUUID& userID)
+{
+ if (!gAgent.getRegion()) return;
+
+ if (command.compare("selected"))
+ {
+ moderateVoiceAllParticipants(command.compare("mute_all"));
+ }
+ else
+ {
+ moderateVoiceParticipant(userID, isMuted(userID));
+ }
+}
+
+bool LLFloaterIMContainer::isMuted(const LLUUID& avatar_id)
+{
+ const LLSpeaker * speakerp = getSpeakerOfSelectedParticipant(getSpeakerMgrForSelectedParticipant());
+ return NULL == speakerp ? true : speakerp->mStatus == LLSpeaker::STATUS_MUTED;
+}
+
+void LLFloaterIMContainer::moderateVoiceAllParticipants(bool unmute)
+{
+ LLIMSpeakerMgr * speaker_managerp = dynamic_cast<LLIMSpeakerMgr*>(getSpeakerMgrForSelectedParticipant());
+
+ if (NULL != speaker_managerp)
+ {
+ if (!unmute)
+ {
+ LLSD payload;
+ payload["session_id"] = speaker_managerp->getSessionID();
+ LLNotificationsUtil::add("ConfirmMuteAll", LLSD(), payload, confirmMuteAllCallback);
+ return;
+ }
+
+ speaker_managerp->moderateVoiceAllParticipants(unmute);
+ }
+}
+
+// static
+void LLFloaterIMContainer::confirmMuteAllCallback(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ // if Cancel pressed
+ if (option == 1)
+ {
+ return;
+ }
+
+ const LLSD& payload = notification["payload"];
+ const LLUUID& session_id = payload["session_id"];
+
+ LLIMSpeakerMgr * speaker_manager = dynamic_cast<LLIMSpeakerMgr*> (
+ LLIMModel::getInstance()->getSpeakerManager(session_id));
+ if (speaker_manager)
+ {
+ speaker_manager->moderateVoiceAllParticipants(false);
+ }
+
+ return;
+}
+
+void LLFloaterIMContainer::moderateVoiceParticipant(const LLUUID& avatar_id, bool unmute)
+{
+ LLIMSpeakerMgr * speaker_managerp = dynamic_cast<LLIMSpeakerMgr *>(getSpeakerMgrForSelectedParticipant());
+
+ if (NULL != speaker_managerp)
+ {
+ speaker_managerp->moderateVoiceParticipant(avatar_id, unmute);
+ }
+}
+
+LLSpeakerMgr * LLFloaterIMContainer::getSpeakerMgrForSelectedParticipant()
+{
+ LLFolderViewItem *selectedItem = mConversationsRoot->getCurSelectedItem();
+ if (NULL == selectedItem)
+ {
+ llwarns << "Current selected item is null" << llendl;
+ return NULL;
+ }
+
+ conversations_widgets_map::const_iterator iter = mConversationsWidgets.begin();
+ conversations_widgets_map::const_iterator end = mConversationsWidgets.end();
+ const LLUUID * conversation_uuidp = NULL;
+ while(iter != end)
+ {
+ if (iter->second == selectedItem || iter->second == selectedItem->getParentFolder())
+ {
+ conversation_uuidp = &iter->first;
+ break;
+ }
+ ++iter;
+ }
+ if (NULL == conversation_uuidp)
+ {
+ llwarns << "Cannot find conversation item widget" << llendl;
+ return NULL;
+ }
+
+ return conversation_uuidp->isNull() ? (LLSpeakerMgr *)LLLocalSpeakerMgr::getInstance()
+ : LLIMModel::getInstance()->getSpeakerManager(*conversation_uuidp);
+}
+
+LLSpeaker * LLFloaterIMContainer::getSpeakerOfSelectedParticipant(LLSpeakerMgr * speaker_managerp)
+{
+ if (NULL == speaker_managerp)
+ {
+ llwarns << "Speaker manager is missing" << llendl;
+ return NULL;
+ }
+
+ const LLConversationItem * participant_itemp = getCurSelectedViewModelItem();
+ if (NULL == participant_itemp)
+ {
+ llwarns << "Cannot evaluate current selected view model item" << llendl;
+ return NULL;
+ }
+
+ return speaker_managerp->findSpeaker(participant_itemp->getUUID());
+}
+
+void LLFloaterIMContainer::toggleAllowTextChat(const LLUUID& participant_uuid)
+{
+ LLIMSpeakerMgr * speaker_managerp = dynamic_cast<LLIMSpeakerMgr*>(getSpeakerMgrForSelectedParticipant());
+ if (NULL != speaker_managerp)
+ {
+ speaker_managerp->toggleAllowTextChat(participant_uuid);
+ }
+}
+
+void LLFloaterIMContainer::toggleMute(const LLUUID& participant_id, U32 flags)
+{
+ BOOL is_muted = LLMuteList::getInstance()->isMuted(participant_id, flags);
+ std::string name;
+ gCacheName->getFullName(participant_id, name);
+ LLMute mute(participant_id, name, LLMute::AGENT);
+
+ if (!is_muted)
+ {
+ LLMuteList::getInstance()->add(mute, flags);
+ }
+ else
+ {
+ LLMuteList::getInstance()->remove(mute, flags);
+ }
+}
+
+void LLFloaterIMContainer::openNearbyChat()
+{
+ // If there's only one conversation in the container and that conversation is the nearby chat
+ //(which it should be...), open it so to make the list of participants visible. This happens to be the most common case when opening the Chat floater.
+ if((mConversationsItems.size() == 1)&&(!mConversationsPane->isCollapsed()))
+ {
+ LLConversationViewSession* nearby_chat = dynamic_cast<LLConversationViewSession*>(get_ptr_in_map(mConversationsWidgets,LLUUID()));
+ if (nearby_chat)
+ {
+ reSelectConversation();
+ nearby_chat->setOpen(TRUE);
+ }
+ }
+}
+
+void LLFloaterIMContainer::reSelectConversation()
+{
+ LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::getConversation(mSelectedSession);
+ if (session_floater->getHost())
+ {
+ selectFloater(session_floater);
+ }
+}
+
+void LLFloaterIMContainer::updateSpeakBtnState()
+{
+ mSpeakBtn->setToggleState(LLVoiceClient::getInstance()->getUserPTTState());
+ mSpeakBtn->setEnabled(LLAgent::isActionAllowed("speak"));
+}
+
+bool LLFloaterIMContainer::isConversationLoggingAllowed()
+{
+ return gSavedPerAccountSettings.getS32("KeepConversationLogTranscripts") > 0;
+}
+
+void LLFloaterIMContainer::flashConversationItemWidget(const LLUUID& session_id, bool is_flashes)
+{
+ //Finds the conversation line item to flash using the session_id
+ LLConversationViewSession * widget = dynamic_cast<LLConversationViewSession *>(get_ptr_in_map(mConversationsWidgets,session_id));
+
+ if (widget)
+ {
+ widget->setFlashState(is_flashes);
+ }
+}
+
+void LLFloaterIMContainer::highlightConversationItemWidget(const LLUUID& session_id, bool is_highlighted)
+{
+ //Finds the conversation line item to highlight using the session_id
+ LLConversationViewSession * widget = dynamic_cast<LLConversationViewSession *>(get_ptr_in_map(mConversationsWidgets,session_id));
+
+ if (widget)
+ {
+ widget->setHighlightState(is_highlighted);
+ }
+}
+
+bool LLFloaterIMContainer::isScrolledOutOfSight(LLConversationViewSession* conversation_item_widget)
+{
+ llassert(conversation_item_widget != NULL);
+
+ // make sure the widget is actually in the right spot first
+ mConversationsRoot->arrange(NULL, NULL);
+
+ // check whether the widget is in the visible portion of the scroll container
+ LLRect widget_rect;
+ conversation_item_widget->localRectToOtherView(conversation_item_widget->getLocalRect(), &widget_rect, mConversationsRoot);
+ return !mConversationsRoot->getVisibleRect().overlaps(widget_rect);
+}
+
+BOOL LLFloaterIMContainer::handleKeyHere(KEY key, MASK mask )
+{
+ BOOL handled = FALSE;
+
+ if(mask == MASK_ALT)
+ {
+ if (KEY_RETURN == key )
+ {
+ expandConversation();
+ handled = TRUE;
+ }
+
+ if ((KEY_DOWN == key ) || (KEY_RIGHT == key))
+ {
+ selectNextorPreviousConversation(true);
+ handled = TRUE;
+ }
+ if ((KEY_UP == key) || (KEY_LEFT == key))
+ {
+ selectNextorPreviousConversation(false);
+ handled = TRUE;
+ }
+ }
+ return handled;
+}
+
+bool LLFloaterIMContainer::selectAdjacentConversation(bool focus_selected)
+{
+ bool selectedAdjacentConversation = selectNextorPreviousConversation(true, focus_selected);
+
+ if(!selectedAdjacentConversation)
+ {
+ selectedAdjacentConversation = selectNextorPreviousConversation(false, focus_selected);
+ }
+
+ return selectedAdjacentConversation;
+}
+
+bool LLFloaterIMContainer::selectNextorPreviousConversation(bool select_next, bool focus_selected)
+{
+ if (mConversationsWidgets.size() > 1)
+ {
+ LLFolderViewItem* new_selection = NULL;
+ LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,getSelectedSession());
+ if (widget)
+ {
+ if(select_next)
+ {
+ new_selection = mConversationsRoot->getNextFromChild(widget, FALSE);
+ }
+ else
+ {
+ new_selection = mConversationsRoot->getPreviousFromChild(widget, FALSE);
+ }
+ if (new_selection)
+ {
+ LLConversationItem* vmi = dynamic_cast<LLConversationItem*>(new_selection->getViewModelItem());
+ if (vmi)
+ {
+ selectConversationPair(vmi->getUUID(), true, focus_selected);
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+}
+
+void LLFloaterIMContainer::expandConversation()
+{
+ if(!mConversationsPane->isCollapsed())
+ {
+ LLConversationViewSession* widget = dynamic_cast<LLConversationViewSession*>(get_ptr_in_map(mConversationsWidgets,getSelectedSession()));
+ if (widget)
+ {
+ widget->setOpen(!widget->isOpen());
+ }
+ }
+}
+bool LLFloaterIMContainer::isParticipantListExpanded()
+{
+ bool is_expanded = false;
+ if(!mConversationsPane->isCollapsed())
+ {
+ LLConversationViewSession* widget = dynamic_cast<LLConversationViewSession*>(get_ptr_in_map(mConversationsWidgets,getSelectedSession()));
+ if (widget)
+ {
+ is_expanded = widget->isOpen();
+ }
+ }
+ return is_expanded;
+}
+
+// By default, if torn off session is currently frontmost, LLFloater::isFrontmost() will return FALSE, which can lead to some bugs
+// So LLFloater::isFrontmost() is overriden here to check both selected session and the IM floater itself
+// Exclude "Nearby Chat" session from the check, as "Nearby Chat" window and "Conversations" floater can be brought
+// to front independently
+/*virtual*/
+BOOL LLFloaterIMContainer::isFrontmost()
+{
+ LLFloaterIMSessionTab* selected_session = LLFloaterIMSessionTab::getConversation(mSelectedSession);
+ LLFloaterIMNearbyChat* nearby_chat = LLFloaterReg::findTypedInstance<LLFloaterIMNearbyChat>("nearby_chat");
+ return (selected_session && selected_session->isFrontmost() && (selected_session != nearby_chat))
+ || LLFloater::isFrontmost();
+}
+
+// For conversations, closeFloater() (linked to Ctrl-W) does not actually close the floater but the active conversation.
+// This is intentional so it doesn't confuse the user. onClickCloseBtn() closes the whole floater.
+void LLFloaterIMContainer::onClickCloseBtn(bool app_quitting/* = false*/)
+{
+ // Always unminimize before trying to close.
+ // Most of the time the user will never see this state.
+ if(isMinimized())
+ {
+ LLMultiFloater::setMinimized(FALSE);
+ }
+
+ LLFloater::closeFloater(app_quitting);
+}
+
+void LLFloaterIMContainer::closeHostedFloater()
+{
+ onClickCloseBtn();
+}
+
+void LLFloaterIMContainer::closeAllConversations()
+{
+ LLDynamicArray<LLUUID> ids;
+ for (conversations_items_map::iterator it_session = mConversationsItems.begin(); it_session != mConversationsItems.end(); it_session++)
+ {
+ LLUUID session_id = it_session->first;
+ if (session_id != LLUUID())
+ {
+ ids.push_back(session_id);
+ }
+ }
+
+ for (LLDynamicArray<LLUUID>::const_iterator it = ids.begin(); it != ids.end(); ++it)
+ {
+ LLFloaterIMSession *conversationFloater = LLFloaterIMSession::findInstance(*it);
+ LLFloater::onClickClose(conversationFloater);
+ }
+}
+
+void LLFloaterIMContainer::closeSelectedConversations(const uuid_vec_t& ids)
+{
+ for (uuid_vec_t::const_iterator it = ids.begin(); it != ids.end(); ++it)
+ {
+ //We don't need to close Nearby chat, so skip it
+ if (*it != LLUUID())
+ {
+ LLFloaterIMSession *conversationFloater = LLFloaterIMSession::findInstance(*it);
+ if(conversationFloater)
+ {
+ LLFloater::onClickClose(conversationFloater);
+ }
+ }
+ }
+}
+void LLFloaterIMContainer::closeFloater(bool app_quitting/* = false*/)
+{
+ if(app_quitting)
+ {
+ closeAllConversations();
+ onClickCloseBtn(app_quitting);
+ }
+ else
+ {
+ // Check for currently active session
+ LLUUID session_id = getSelectedSession();
+ // If current session is Nearby Chat or there is only one session remaining, close the floater
+ if (mConversationsItems.size() == 1 || session_id == LLUUID() || app_quitting)
+ {
+ onClickCloseBtn();
+ }
+ else
+ {
+ // Otherwise, close current conversation
+ LLFloaterIMSessionTab* active_conversation = LLFloaterIMSessionTab::getConversation(session_id);
+ if (active_conversation)
+ {
+ active_conversation->closeFloater();
+ }
+ }
+ }
+}
+
+void LLFloaterIMContainer::handleReshape(const LLRect& rect, bool by_user)
+{
+ LLMultiFloater::handleReshape(rect, by_user);
+ storeRectControl();
+}
+
+// EOF
diff --git a/indra/newview/llfloaterimcontainer.h b/indra/newview/llfloaterimcontainer.h
new file mode 100755
index 0000000000..f6d973b9b3
--- /dev/null
+++ b/indra/newview/llfloaterimcontainer.h
@@ -0,0 +1,225 @@
+/**
+ * @file llfloaterimcontainer.h
+ * @brief Multifloater containing active IM sessions in separate tab container tabs
+ *
+ * $LicenseInfo:firstyear=2009&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$
+ */
+
+#ifndef LL_LLFLOATERIMCONTAINER_H
+#define LL_LLFLOATERIMCONTAINER_H
+
+#include <map>
+#include <vector>
+
+#include "llimview.h"
+#include "llevents.h"
+#include "../llui/llfloater.h"
+#include "../llui/llmultifloater.h"
+#include "llavatarpropertiesprocessor.h"
+#include "llgroupmgr.h"
+#include "../llui/lltrans.h"
+#include "llconversationmodel.h"
+#include "llconversationview.h"
+
+class LLButton;
+class LLLayoutPanel;
+class LLLayoutStack;
+class LLTabContainer;
+class LLFloaterIMContainer;
+class LLSpeaker;
+class LLSpeakerMgr;
+
+class LLFloaterIMContainer
+ : public LLMultiFloater
+ , public LLIMSessionObserver
+{
+public:
+ LLFloaterIMContainer(const LLSD& seed, const Params& params = getDefaultParams());
+ virtual ~LLFloaterIMContainer();
+
+ /*virtual*/ BOOL postBuild();
+ /*virtual*/ void onOpen(const LLSD& key);
+ /*virtual*/ void draw();
+ /*virtual*/ void setMinimized(BOOL b);
+ /*virtual*/ void setVisible(BOOL visible);
+ /*virtual*/ void setVisibleAndFrontmost(BOOL take_focus=TRUE, const LLSD& key = LLSD());
+ /*virtual*/ void updateResizeLimits();
+ /*virtual*/ void handleReshape(const LLRect& rect, bool by_user);
+
+ void onCloseFloater(LLUUID& id);
+
+ /*virtual*/ void addFloater(LLFloater* floaterp,
+ BOOL select_added_floater,
+ LLTabContainer::eInsertionPoint insertion_point = LLTabContainer::END);
+ void returnFloaterToHost();
+ void showConversation(const LLUUID& session_id);
+ void selectConversation(const LLUUID& session_id);
+ void selectNextConversationByID(const LLUUID& session_id);
+ BOOL selectConversationPair(const LLUUID& session_id, bool select_widget, bool focus_floater = true);
+ void clearAllFlashStates();
+ bool selectAdjacentConversation(bool focus_selected);
+ bool selectNextorPreviousConversation(bool select_next, bool focus_selected = true);
+ void expandConversation();
+
+ /*virtual*/ void tabClose();
+ void showStub(bool visible);
+
+ static LLFloater* getCurrentVoiceFloater();
+ static LLFloaterIMContainer* findInstance();
+ static LLFloaterIMContainer* getInstance();
+
+ static void onCurrentChannelChanged(const LLUUID& session_id);
+
+ void collapseMessagesPane(bool collapse);
+ bool isMessagesPaneCollapsed();
+ bool isConversationsPaneCollapsed();
+
+ // Callbacks
+ static void idle(void* user_data);
+
+ // LLIMSessionObserver observe triggers
+ /*virtual*/ void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id, BOOL has_offline_msg);
+ /*virtual*/ void sessionActivated(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id);
+ /*virtual*/ void sessionVoiceOrIMStarted(const LLUUID& session_id);
+ /*virtual*/ void sessionRemoved(const LLUUID& session_id);
+ /*virtual*/ void sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id);
+
+ LLConversationViewModel& getRootViewModel() { return mConversationViewModel; }
+ LLUUID getSelectedSession() { return mSelectedSession; }
+ void setSelectedSession(LLUUID sessionID) { mSelectedSession = sessionID; }
+ LLConversationItem* getSessionModel(const LLUUID& session_id) { return get_ptr_in_map(mConversationsItems,session_id); }
+ LLConversationSort& getSortOrder() { return mConversationViewModel.getSorter(); }
+
+ // Handling of lists of participants is public so to be common with llfloatersessiontab
+ // *TODO : Find a better place for this.
+ bool checkContextMenuItem(const std::string& item, uuid_vec_t& selectedIDS);
+ bool enableContextMenuItem(const std::string& item, uuid_vec_t& selectedIDS);
+ void doToParticipants(const std::string& item, uuid_vec_t& selectedIDS);
+
+ void assignResizeLimits();
+ virtual BOOL handleKeyHere(KEY key, MASK mask );
+ /*virtual*/ void closeFloater(bool app_quitting = false);
+ void closeAllConversations();
+ void closeSelectedConversations(const uuid_vec_t& ids);
+ /*virtual*/ BOOL isFrontmost();
+
+
+private:
+ typedef std::map<LLUUID,LLFloater*> avatarID_panel_map_t;
+ avatarID_panel_map_t mSessions;
+ boost::signals2::connection mNewMessageConnection;
+
+ /*virtual*/ void computeResizeLimits(S32& new_min_width, S32& new_min_height) {}
+
+ void onNewMessageReceived(const LLSD& data);
+
+ void onExpandCollapseButtonClicked();
+ void onStubCollapseButtonClicked();
+ void processParticipantsStyleUpdate();
+ void onSpeakButtonClicked();
+ /*virtual*/ void onClickCloseBtn(bool app_quitting = false);
+ /*virtual*/ void closeHostedFloater();
+
+ void collapseConversationsPane(bool collapse, bool save_is_allowed=true);
+
+ void reshapeFloaterAndSetResizeLimits(bool collapse, S32 delta_width);
+
+ void onAddButtonClicked();
+ void onAvatarPicked(const uuid_vec_t& ids);
+
+ BOOL isActionChecked(const LLSD& userdata);
+ void onCustomAction (const LLSD& userdata);
+ void setSortOrderSessions(const LLConversationFilter::ESortOrderType order);
+ void setSortOrderParticipants(const LLConversationFilter::ESortOrderType order);
+ void setSortOrder(const LLConversationSort& order);
+
+ void getSelectedUUIDs(uuid_vec_t& selected_uuids, bool participant_uuids = true);
+ const LLConversationItem * getCurSelectedViewModelItem();
+ void getParticipantUUIDs(uuid_vec_t& selected_uuids);
+ void doToSelected(const LLSD& userdata);
+ bool checkContextMenuItem(const LLSD& userdata);
+ bool enableContextMenuItem(const LLSD& userdata);
+ bool visibleContextMenuItem(const LLSD& userdata);
+ void doToSelectedConversation(const std::string& command, uuid_vec_t& selectedIDS);
+ void doToSelectedGroup(const LLSD& userdata);
+
+ static void confirmMuteAllCallback(const LLSD& notification, const LLSD& response);
+ bool enableModerateContextMenuItem(const std::string& userdata);
+ LLSpeaker * getSpeakerOfSelectedParticipant(LLSpeakerMgr * speaker_managerp);
+ LLSpeakerMgr * getSpeakerMgrForSelectedParticipant();
+ bool isGroupModerator();
+ bool isMuted(const LLUUID& avatar_id);
+ void moderateVoice(const std::string& command, const LLUUID& userID);
+ void moderateVoiceAllParticipants(bool unmute);
+ void moderateVoiceParticipant(const LLUUID& avatar_id, bool unmute);
+ void toggleAllowTextChat(const LLUUID& participant_uuid);
+ void toggleMute(const LLUUID& participant_id, U32 flags);
+ void openNearbyChat();
+ bool isParticipantListExpanded();
+
+ LLButton* mExpandCollapseBtn;
+ LLButton* mStubCollapseBtn;
+ LLButton* mSpeakBtn;
+ LLPanel* mStubPanel;
+ LLTextBox* mStubTextBox;
+ LLLayoutPanel* mMessagesPane;
+ LLLayoutPanel* mConversationsPane;
+ LLLayoutStack* mConversationsStack;
+
+ bool mInitialized;
+ bool mIsFirstLaunch;
+
+ LLUUID mSelectedSession;
+ std::string mGeneralTitle;
+
+ // Conversation list implementation
+public:
+ bool removeConversationListItem(const LLUUID& uuid, bool change_focus = true);
+ LLConversationItem* addConversationListItem(const LLUUID& uuid, bool isWidgetSelected = false);
+ void setTimeNow(const LLUUID& session_id, const LLUUID& participant_id);
+ void setNearbyDistances();
+ void reSelectConversation();
+ void updateSpeakBtnState();
+ static bool isConversationLoggingAllowed();
+ void flashConversationItemWidget(const LLUUID& session_id, bool is_flashes);
+ void highlightConversationItemWidget(const LLUUID& session_id, bool is_highlighted);
+ bool isScrolledOutOfSight(LLConversationViewSession* conversation_item_widget);
+ boost::signals2::connection mMicroChangedSignal;
+ S32 getConversationListItemSize() { return mConversationsWidgets.size(); }
+ typedef std::list<LLFloater*> floater_list_t;
+ void getDetachedConversationFloaters(floater_list_t& floaters);
+
+private:
+ LLConversationViewSession* createConversationItemWidget(LLConversationItem* item);
+ LLConversationViewParticipant* createConversationViewParticipant(LLConversationItem* item);
+ bool onConversationModelEvent(const LLSD& event);
+
+ // Conversation list data
+ LLPanel* mConversationsListPanel; // This is the main widget we add conversation widget to
+ conversations_items_map mConversationsItems;
+ conversations_widgets_map mConversationsWidgets;
+ LLConversationViewModel mConversationViewModel;
+ LLFolderView* mConversationsRoot;
+ LLEventStream mConversationsEventStream;
+};
+
+#endif // LL_LLFLOATERIMCONTAINER_H
diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp
new file mode 100755
index 0000000000..323e84751f
--- /dev/null
+++ b/indra/newview/llfloaterimnearbychat.cpp
@@ -0,0 +1,894 @@
+/**
+ * @file LLFloaterIMNearbyChat.cpp
+ * @brief LLFloaterIMNearbyChat class implementation
+ *
+ * $LicenseInfo:firstyear=2002&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 "llviewerprecompiledheaders.h"
+
+#include "message.h"
+
+#include "lliconctrl.h"
+#include "llappviewer.h"
+#include "llchatentry.h"
+#include "llfloaterreg.h"
+#include "lltrans.h"
+#include "llfloaterimcontainer.h"
+#include "llfloatersidepanelcontainer.h"
+#include "llfocusmgr.h"
+#include "lllogchat.h"
+#include "llresizebar.h"
+#include "llresizehandle.h"
+#include "lldraghandle.h"
+#include "llmenugl.h"
+#include "llviewermenu.h" // for gMenuHolder
+#include "llfloaterimnearbychathandler.h"
+#include "llchannelmanager.h"
+#include "llchathistory.h"
+#include "llstylemap.h"
+#include "llavatarnamecache.h"
+#include "llfloaterreg.h"
+#include "lltrans.h"
+
+#include "llfirstuse.h"
+#include "llfloaterimnearbychat.h"
+#include "llagent.h" // gAgent
+#include "llgesturemgr.h"
+#include "llmultigesture.h"
+#include "llkeyboard.h"
+#include "llanimationstates.h"
+#include "llviewerstats.h"
+#include "llcommandhandler.h"
+#include "llviewercontrol.h"
+#include "llnavigationbar.h"
+#include "llwindow.h"
+#include "llviewerwindow.h"
+#include "llrootview.h"
+#include "llviewerchat.h"
+#include "lltranslate.h"
+#include "llautoreplace.h"
+
+S32 LLFloaterIMNearbyChat::sLastSpecialChatChannel = 0;
+
+const S32 EXPANDED_HEIGHT = 266;
+const S32 COLLAPSED_HEIGHT = 60;
+const S32 EXPANDED_MIN_HEIGHT = 150;
+
+// legacy callback glue
+void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 channel);
+
+struct LLChatTypeTrigger {
+ std::string name;
+ EChatType type;
+};
+
+static LLChatTypeTrigger sChatTypeTriggers[] = {
+ { "/whisper" , CHAT_TYPE_WHISPER},
+ { "/shout" , CHAT_TYPE_SHOUT}
+};
+
+
+LLFloaterIMNearbyChat::LLFloaterIMNearbyChat(const LLSD& llsd)
+: LLFloaterIMSessionTab(llsd),
+ //mOutputMonitor(NULL),
+ mSpeakerMgr(NULL),
+ mExpandedHeight(COLLAPSED_HEIGHT + EXPANDED_HEIGHT)
+{
+ mIsP2PChat = false;
+ mIsNearbyChat = true;
+ mSpeakerMgr = LLLocalSpeakerMgr::getInstance();
+ mSessionID = LLUUID();
+}
+
+//static
+LLFloaterIMNearbyChat* LLFloaterIMNearbyChat::buildFloater(const LLSD& key)
+{
+ LLFloaterReg::getInstance("im_container");
+ return new LLFloaterIMNearbyChat(key);
+}
+
+//virtual
+BOOL LLFloaterIMNearbyChat::postBuild()
+{
+ setIsSingleInstance(TRUE);
+ BOOL result = LLFloaterIMSessionTab::postBuild();
+
+ mInputEditor->setAutoreplaceCallback(boost::bind(&LLAutoReplace::autoreplaceCallback, LLAutoReplace::getInstance(), _1, _2, _3, _4, _5));
+ mInputEditor->setCommitCallback(boost::bind(&LLFloaterIMNearbyChat::onChatBoxCommit, this));
+ mInputEditor->setKeystrokeCallback(boost::bind(&LLFloaterIMNearbyChat::onChatBoxKeystroke, this));
+ mInputEditor->setFocusLostCallback(boost::bind(&LLFloaterIMNearbyChat::onChatBoxFocusLost, this));
+ mInputEditor->setFocusReceivedCallback(boost::bind(&LLFloaterIMNearbyChat::onChatBoxFocusReceived, this));
+ mInputEditor->setLabel(LLTrans::getString("NearbyChatTitle"));
+
+ // Title must be defined BEFORE call to addConversationListItem() because
+ // it is used to show the item's name in the conversations list
+ setTitle(LLTrans::getString("NearbyChatTitle"));
+
+ // obsolete, but may be needed for backward compatibility?
+ gSavedSettings.declareS32("nearbychat_showicons_and_names", 2, "NearByChat header settings", LLControlVariable::PERSIST_NONDFT);
+
+ if (gSavedPerAccountSettings.getBOOL("LogShowHistory"))
+ {
+ loadHistory();
+ }
+
+ return result;
+}
+
+// virtual
+void LLFloaterIMNearbyChat::closeHostedFloater()
+{
+ // If detached from conversations window close anyway
+ if (!getHost())
+ {
+ setVisible(FALSE);
+ }
+
+ // Should check how many conversations are ongoing. Select next to "Nearby Chat" in case there are some other besides.
+ // Close conversations window in case "Nearby Chat" is attached and the only conversation
+ LLFloaterIMContainer* floater_container = LLFloaterIMContainer::getInstance();
+ if (floater_container->getConversationListItemSize() == 1)
+ {
+ if (getHost())
+ {
+ floater_container->closeFloater();
+ }
+ }
+ else
+ {
+ if (!getHost())
+ {
+ floater_container->selectNextConversationByID(LLUUID());
+ }
+ }
+}
+
+// virtual
+void LLFloaterIMNearbyChat::refresh()
+{
+ displaySpeakingIndicator();
+ updateCallBtnState(LLVoiceClient::getInstance()->getUserPTTState());
+
+ // *HACK: Update transparency type depending on whether our children have focus.
+ // This is needed because this floater is chrome and thus cannot accept focus, so
+ // the transparency type setting code from LLFloater::setFocus() isn't reached.
+ if (getTransparencyType() != TT_DEFAULT)
+ {
+ setTransparencyType(hasFocus() ? TT_ACTIVE : TT_INACTIVE);
+ }
+}
+
+void LLFloaterIMNearbyChat::reloadMessages(bool clean_messages/* = false*/)
+{
+ if (clean_messages)
+ {
+ mMessageArchive.clear();
+ loadHistory();
+ }
+
+ mChatHistory->clear();
+
+ LLSD do_not_log;
+ do_not_log["do_not_log"] = true;
+ for(std::vector<LLChat>::iterator it = mMessageArchive.begin();it!=mMessageArchive.end();++it)
+ {
+ // Update the messages without re-writing them to a log file.
+ addMessage(*it,false, do_not_log);
+ }
+}
+
+void LLFloaterIMNearbyChat::loadHistory()
+{
+ LLSD do_not_log;
+ do_not_log["do_not_log"] = true;
+
+ std::list<LLSD> history;
+ LLLogChat::loadChatHistory("chat", history);
+
+ std::list<LLSD>::const_iterator it = history.begin();
+ while (it != history.end())
+ {
+ const LLSD& msg = *it;
+
+ std::string from = msg[LL_IM_FROM];
+ LLUUID from_id;
+ if (msg[LL_IM_FROM_ID].isDefined())
+ {
+ from_id = msg[LL_IM_FROM_ID].asUUID();
+ }
+ else
+ {
+ std::string legacy_name = gCacheName->buildLegacyName(from);
+ gCacheName->getUUID(legacy_name, from_id);
+ }
+
+ LLChat chat;
+ chat.mFromName = from;
+ chat.mFromID = from_id;
+ chat.mText = msg[LL_IM_TEXT].asString();
+ chat.mTimeStr = msg[LL_IM_TIME].asString();
+ chat.mChatStyle = CHAT_STYLE_HISTORY;
+
+ chat.mSourceType = CHAT_SOURCE_AGENT;
+ if (from_id.isNull() && SYSTEM_FROM == from)
+ {
+ chat.mSourceType = CHAT_SOURCE_SYSTEM;
+
+ }
+ else if (from_id.isNull())
+ {
+ chat.mSourceType = isWordsName(from) ? CHAT_SOURCE_UNKNOWN : CHAT_SOURCE_OBJECT;
+ }
+
+ addMessage(chat, true, do_not_log);
+
+ it++;
+ }
+}
+
+void LLFloaterIMNearbyChat::removeScreenChat()
+{
+ LLNotificationsUI::LLScreenChannelBase* chat_channel = LLNotificationsUI::LLChannelManager::getInstance()->findChannelByID(LLUUID(gSavedSettings.getString("NearByChatChannelUUID")));
+ if(chat_channel)
+ {
+ chat_channel->removeToastsFromChannel();
+ }
+}
+
+
+void LLFloaterIMNearbyChat::setVisible(BOOL visible)
+{
+ LLFloaterIMSessionTab::setVisible(visible);
+
+ if(visible)
+ {
+ removeScreenChat();
+ }
+}
+
+
+void LLFloaterIMNearbyChat::setVisibleAndFrontmost(BOOL take_focus, const LLSD& key)
+{
+ LLFloaterIMSessionTab::setVisibleAndFrontmost(take_focus, key);
+
+ if(matchesKey(key))
+ {
+ LLFloaterIMContainer::getInstance()->selectConversationPair(mSessionID, true, take_focus);
+ }
+}
+
+// virtual
+void LLFloaterIMNearbyChat::onTearOffClicked()
+{
+ LLFloaterIMSessionTab::onTearOffClicked();
+
+ // see CHUI-170: Save torn-off state of the nearby chat between sessions
+ BOOL in_the_multifloater = (BOOL)getHost();
+ gSavedPerAccountSettings.setBOOL("NearbyChatIsNotTornOff", in_the_multifloater);
+}
+
+
+// virtual
+void LLFloaterIMNearbyChat::onOpen(const LLSD& key)
+{
+ LLFloaterIMSessionTab::onOpen(key);
+ if(!isMessagePaneExpanded())
+ {
+ restoreFloater();
+ onCollapseToLine(this);
+ }
+ showTranslationCheckbox(LLTranslate::isTranslationConfigured());
+}
+
+// virtual
+void LLFloaterIMNearbyChat::onClose(bool app_quitting)
+{
+ // Override LLFloaterIMSessionTab::onClose() so that Nearby Chat is not removed from the conversation floater
+ LLFloaterIMSessionTab::restoreFloater();
+}
+
+// virtual
+void LLFloaterIMNearbyChat::onClickCloseBtn(bool)
+
+{
+ if (!isTornOff())
+ {
+ return;
+ }
+ closeHostedFloater();
+}
+
+void LLFloaterIMNearbyChat::onChatFontChange(LLFontGL* fontp)
+{
+ // Update things with the new font whohoo
+ if (mInputEditor)
+ {
+ mInputEditor->setFont(fontp);
+ }
+}
+
+
+void LLFloaterIMNearbyChat::show()
+{
+ openFloater(getKey());
+ }
+
+bool LLFloaterIMNearbyChat::isChatVisible() const
+{
+ bool isVisible = false;
+ LLFloaterIMContainer* im_box = LLFloaterIMContainer::getInstance();
+ // Is the IM floater container ever null?
+ llassert(im_box != NULL);
+ if (im_box != NULL)
+ {
+ isVisible =
+ isChatMultiTab() && gSavedPerAccountSettings.getBOOL("NearbyChatIsNotTornOff")?
+ im_box->getVisible() && !im_box->isMinimized() :
+ getVisible() && !isMinimized();
+ }
+
+ return isVisible;
+}
+
+void LLFloaterIMNearbyChat::showHistory()
+{
+ openFloater();
+ LLFloaterIMContainer::getInstance()->selectConversation(LLUUID(NULL));
+
+ if(!isMessagePaneExpanded())
+ {
+ restoreFloater();
+ setFocus(true);
+ }
+ else
+ {
+ LLFloaterIMContainer::getInstance()->setFocus(TRUE);
+ }
+ setResizeLimits(getMinWidth(), EXPANDED_MIN_HEIGHT);
+}
+
+std::string LLFloaterIMNearbyChat::getCurrentChat()
+{
+ return mInputEditor ? mInputEditor->getText() : LLStringUtil::null;
+}
+
+// virtual
+BOOL LLFloaterIMNearbyChat::handleKeyHere( KEY key, MASK mask )
+{
+ BOOL handled = FALSE;
+
+ if( KEY_RETURN == key && mask == MASK_CONTROL)
+ {
+ // shout
+ sendChat(CHAT_TYPE_SHOUT);
+ handled = TRUE;
+ }
+ else if (KEY_RETURN == key && mask == MASK_SHIFT)
+ {
+ // whisper
+ sendChat(CHAT_TYPE_WHISPER);
+ handled = TRUE;
+ }
+
+
+ if((mask == MASK_ALT) && isTornOff())
+ {
+ LLFloaterIMContainer* floater_container = LLFloaterIMContainer::getInstance();
+ if ((KEY_UP == key) || (KEY_LEFT == key))
+ {
+ floater_container->selectNextorPreviousConversation(false);
+ handled = TRUE;
+ }
+ if ((KEY_DOWN == key ) || (KEY_RIGHT == key))
+ {
+ floater_container->selectNextorPreviousConversation(true);
+ handled = TRUE;
+ }
+ }
+
+ return handled;
+}
+
+BOOL LLFloaterIMNearbyChat::matchChatTypeTrigger(const std::string& in_str, std::string* out_str)
+{
+ U32 in_len = in_str.length();
+ S32 cnt = sizeof(sChatTypeTriggers) / sizeof(*sChatTypeTriggers);
+
+ bool string_was_found = false;
+
+ for (S32 n = 0; n < cnt && !string_was_found; n++)
+ {
+ if (in_len <= sChatTypeTriggers[n].name.length())
+ {
+ std::string trigger_trunc = sChatTypeTriggers[n].name;
+ LLStringUtil::truncate(trigger_trunc, in_len);
+
+ if (!LLStringUtil::compareInsensitive(in_str, trigger_trunc))
+ {
+ *out_str = sChatTypeTriggers[n].name;
+ string_was_found = true;
+ }
+ }
+ }
+
+ return string_was_found;
+}
+
+void LLFloaterIMNearbyChat::onChatBoxKeystroke()
+{
+ LLFloaterIMContainer* im_box = LLFloaterIMContainer::findInstance();
+ if (im_box)
+ {
+ im_box->flashConversationItemWidget(mSessionID,false);
+ }
+
+ LLFirstUse::otherAvatarChatFirst(false);
+
+ LLWString raw_text = mInputEditor->getWText();
+
+ // Can't trim the end, because that will cause autocompletion
+ // to eat trailing spaces that might be part of a gesture.
+ LLWStringUtil::trimHead(raw_text);
+
+ S32 length = raw_text.length();
+
+ if( (length > 0) && (raw_text[0] != '/') ) // forward slash is used for escape (eg. emote) sequences
+ {
+ gAgent.startTyping();
+ }
+ else
+ {
+ gAgent.stopTyping();
+ }
+
+ /* Doesn't work -- can't tell the difference between a backspace
+ that killed the selection vs. backspace at the end of line.
+ if (length > 1
+ && text[0] == '/'
+ && key == KEY_BACKSPACE)
+ {
+ // the selection will already be deleted, but we need to trim
+ // off the character before
+ std::string new_text = raw_text.substr(0, length-1);
+ mInputEditor->setText( new_text );
+ mInputEditor->setCursorToEnd();
+ length = length - 1;
+ }
+ */
+
+ KEY key = gKeyboard->currentKey();
+
+ // Ignore "special" keys, like backspace, arrows, etc.
+ if (length > 1
+ && raw_text[0] == '/'
+ && key < KEY_SPECIAL)
+ {
+ // we're starting a gesture, attempt to autocomplete
+
+ std::string utf8_trigger = wstring_to_utf8str(raw_text);
+ std::string utf8_out_str(utf8_trigger);
+
+ if (LLGestureMgr::instance().matchPrefix(utf8_trigger, &utf8_out_str))
+ {
+ std::string rest_of_match = utf8_out_str.substr(utf8_trigger.size());
+ if (!rest_of_match.empty())
+ {
+ mInputEditor->setText(utf8_trigger + rest_of_match); // keep original capitalization for user-entered part
+ // Select to end of line, starting from the character
+ // after the last one the user typed.
+ mInputEditor->selectByCursorPosition(utf8_out_str.size()-rest_of_match.size(),utf8_out_str.size());
+ }
+
+ }
+ else if (matchChatTypeTrigger(utf8_trigger, &utf8_out_str))
+ {
+ std::string rest_of_match = utf8_out_str.substr(utf8_trigger.size());
+ mInputEditor->setText(utf8_trigger + rest_of_match + " "); // keep original capitalization for user-entered part
+ mInputEditor->endOfDoc();
+ }
+
+ //llinfos << "GESTUREDEBUG " << trigger
+ // << " len " << length
+ // << " outlen " << out_str.getLength()
+ // << llendl;
+ }
+}
+
+// static
+void LLFloaterIMNearbyChat::onChatBoxFocusLost()
+{
+ // stop typing animation
+ gAgent.stopTyping();
+}
+
+void LLFloaterIMNearbyChat::onChatBoxFocusReceived()
+{
+ mInputEditor->setEnabled(!gDisconnected);
+}
+
+EChatType LLFloaterIMNearbyChat::processChatTypeTriggers(EChatType type, std::string &str)
+{
+ U32 length = str.length();
+ S32 cnt = sizeof(sChatTypeTriggers) / sizeof(*sChatTypeTriggers);
+
+ for (S32 n = 0; n < cnt; n++)
+ {
+ if (length >= sChatTypeTriggers[n].name.length())
+ {
+ std::string trigger = str.substr(0, sChatTypeTriggers[n].name.length());
+
+ if (!LLStringUtil::compareInsensitive(trigger, sChatTypeTriggers[n].name))
+ {
+ U32 trigger_length = sChatTypeTriggers[n].name.length();
+
+ // It's to remove space after trigger name
+ if (length > trigger_length && str[trigger_length] == ' ')
+ trigger_length++;
+
+ str = str.substr(trigger_length, length);
+
+ if (CHAT_TYPE_NORMAL == type)
+ return sChatTypeTriggers[n].type;
+ else
+ break;
+ }
+ }
+ }
+
+ return type;
+}
+
+void LLFloaterIMNearbyChat::sendChat( EChatType type )
+{
+ if (mInputEditor)
+ {
+ LLWString text = mInputEditor->getWText();
+ LLWStringUtil::trim(text);
+ LLWStringUtil::replaceChar(text,182,'\n'); // Convert paragraph symbols back into newlines.
+ if (!text.empty())
+ {
+ // Check if this is destined for another channel
+ S32 channel = 0;
+ stripChannelNumber(text, &channel);
+
+ std::string utf8text = wstring_to_utf8str(text);
+ // Try to trigger a gesture, if not chat to a script.
+ std::string utf8_revised_text;
+ if (0 == channel)
+ {
+ // discard returned "found" boolean
+ if(!LLGestureMgr::instance().triggerAndReviseString(utf8text, &utf8_revised_text))
+ {
+ utf8_revised_text = utf8text;
+ }
+ }
+ else
+ {
+ utf8_revised_text = utf8text;
+ }
+
+ utf8_revised_text = utf8str_trim(utf8_revised_text);
+
+ type = processChatTypeTriggers(type, utf8_revised_text);
+
+ if (!utf8_revised_text.empty())
+ {
+ // Chat with animation
+ sendChatFromViewer(utf8_revised_text, type, gSavedSettings.getBOOL("PlayChatAnim"));
+ }
+ }
+
+ mInputEditor->setText(LLStringExplicit(""));
+ }
+
+ gAgent.stopTyping();
+
+ // If the user wants to stop chatting on hitting return, lose focus
+ // and go out of chat mode.
+ if (gSavedSettings.getBOOL("CloseChatOnReturn"))
+ {
+ stopChat();
+ }
+}
+
+void LLFloaterIMNearbyChat::addMessage(const LLChat& chat,bool archive,const LLSD &args)
+{
+ appendMessage(chat, args);
+
+ if(archive)
+ {
+ mMessageArchive.push_back(chat);
+ if(mMessageArchive.size() > 200)
+ {
+ mMessageArchive.erase(mMessageArchive.begin());
+ }
+ }
+
+ // logging
+ if (!args["do_not_log"].asBoolean() && gSavedPerAccountSettings.getS32("KeepConversationLogTranscripts") > 1)
+ {
+ std::string from_name = chat.mFromName;
+
+ if (chat.mSourceType == CHAT_SOURCE_AGENT)
+ {
+ // if the chat is coming from an agent, log the complete name
+ LLAvatarName av_name;
+ LLAvatarNameCache::get(chat.mFromID, &av_name);
+
+ if (!av_name.isDisplayNameDefault())
+ {
+ from_name = av_name.getCompleteName();
+ }
+ }
+
+ LLLogChat::saveHistory("chat", from_name, chat.mFromID, chat.mText);
+ }
+}
+
+
+void LLFloaterIMNearbyChat::onChatBoxCommit()
+{
+ sendChat(CHAT_TYPE_NORMAL);
+
+ gAgent.stopTyping();
+}
+
+void LLFloaterIMNearbyChat::displaySpeakingIndicator()
+{
+ LLSpeakerMgr::speaker_list_t speaker_list;
+ LLUUID id;
+
+ id.setNull();
+ mSpeakerMgr->update(FALSE);
+ mSpeakerMgr->getSpeakerList(&speaker_list, FALSE);
+
+ for (LLSpeakerMgr::speaker_list_t::iterator i = speaker_list.begin(); i != speaker_list.end(); ++i)
+ {
+ LLPointer<LLSpeaker> s = *i;
+ if (s->mSpeechVolume > 0 || s->mStatus == LLSpeaker::STATUS_SPEAKING)
+ {
+ id = s->mID;
+ break;
+ }
+ }
+}
+
+void LLFloaterIMNearbyChat::sendChatFromViewer(const std::string &utf8text, EChatType type, BOOL animate)
+{
+ sendChatFromViewer(utf8str_to_wstring(utf8text), type, animate);
+}
+
+void LLFloaterIMNearbyChat::sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL animate)
+{
+ // Look for "/20 foo" channel chats.
+ S32 channel = 0;
+ LLWString out_text = stripChannelNumber(wtext, &channel);
+ std::string utf8_out_text = wstring_to_utf8str(out_text);
+ std::string utf8_text = wstring_to_utf8str(wtext);
+
+ utf8_text = utf8str_trim(utf8_text);
+ if (!utf8_text.empty())
+ {
+ utf8_text = utf8str_truncate(utf8_text, MAX_STRING - 1);
+ }
+
+ // Don't animate for chats people can't hear (chat to scripts)
+ if (animate && (channel == 0))
+ {
+ if (type == CHAT_TYPE_WHISPER)
+ {
+ lldebugs << "You whisper " << utf8_text << llendl;
+ gAgent.sendAnimationRequest(ANIM_AGENT_WHISPER, ANIM_REQUEST_START);
+ }
+ else if (type == CHAT_TYPE_NORMAL)
+ {
+ lldebugs << "You say " << utf8_text << llendl;
+ gAgent.sendAnimationRequest(ANIM_AGENT_TALK, ANIM_REQUEST_START);
+ }
+ else if (type == CHAT_TYPE_SHOUT)
+ {
+ lldebugs << "You shout " << utf8_text << llendl;
+ gAgent.sendAnimationRequest(ANIM_AGENT_SHOUT, ANIM_REQUEST_START);
+ }
+ else
+ {
+ llinfos << "send_chat_from_viewer() - invalid volume" << llendl;
+ return;
+ }
+ }
+ else
+ {
+ if (type != CHAT_TYPE_START && type != CHAT_TYPE_STOP)
+ {
+ lldebugs << "Channel chat: " << utf8_text << llendl;
+ }
+ }
+
+ send_chat_from_viewer(utf8_out_text, type, channel);
+}
+
+// static
+bool LLFloaterIMNearbyChat::isWordsName(const std::string& name)
+{
+ // checking to see if it's display name plus username in parentheses
+ S32 open_paren = name.find(" (", 0);
+ S32 close_paren = name.find(')', 0);
+
+ if (open_paren != std::string::npos &&
+ close_paren == name.length()-1)
+ {
+ return true;
+ }
+ else
+ {
+ //checking for a single space
+ S32 pos = name.find(' ', 0);
+ return std::string::npos != pos && name.rfind(' ', name.length()) == pos && 0 != pos && name.length()-1 != pos;
+ }
+}
+
+// static
+void LLFloaterIMNearbyChat::startChat(const char* line)
+{
+ LLFloaterIMNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat");
+ if (nearby_chat)
+ {
+ if(!nearby_chat->isTornOff())
+ {
+ LLFloaterIMContainer::getInstance()->selectConversation(LLUUID(NULL));
+ }
+ if(nearby_chat->isMinimized())
+ {
+ nearby_chat->setMinimized(false);
+ }
+ nearby_chat->show();
+ nearby_chat->setFocus(TRUE);
+
+ if (line)
+ {
+ std::string line_string(line);
+ nearby_chat->mInputEditor->setText(line_string);
+ }
+
+ nearby_chat->mInputEditor->endOfDoc();
+ }
+}
+
+// Exit "chat mode" and do the appropriate focus changes
+// static
+void LLFloaterIMNearbyChat::stopChat()
+{
+ LLFloaterIMNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat");
+ if (nearby_chat)
+ {
+ nearby_chat->mInputEditor->setFocus(FALSE);
+ gAgent.stopTyping();
+ }
+}
+
+// If input of the form "/20foo" or "/20 foo", returns "foo" and channel 20.
+// Otherwise returns input and channel 0.
+LLWString LLFloaterIMNearbyChat::stripChannelNumber(const LLWString &mesg, S32* channel)
+{
+ if (mesg[0] == '/'
+ && mesg[1] == '/')
+ {
+ // This is a "repeat channel send"
+ *channel = sLastSpecialChatChannel;
+ return mesg.substr(2, mesg.length() - 2);
+ }
+ else if (mesg[0] == '/'
+ && mesg[1]
+ && LLStringOps::isDigit(mesg[1]))
+ {
+ // This a special "/20" speak on a channel
+ S32 pos = 0;
+
+ // Copy the channel number into a string
+ LLWString channel_string;
+ llwchar c;
+ do
+ {
+ c = mesg[pos+1];
+ channel_string.push_back(c);
+ pos++;
+ }
+ while(c && pos < 64 && LLStringOps::isDigit(c));
+
+ // Move the pointer forward to the first non-whitespace char
+ // Check isspace before looping, so we can handle "/33foo"
+ // as well as "/33 foo"
+ while(c && iswspace(c))
+ {
+ c = mesg[pos+1];
+ pos++;
+ }
+
+ sLastSpecialChatChannel = strtol(wstring_to_utf8str(channel_string).c_str(), NULL, 10);
+ *channel = sLastSpecialChatChannel;
+ return mesg.substr(pos, mesg.length() - pos);
+ }
+ else
+ {
+ // This is normal chat.
+ *channel = 0;
+ return mesg;
+ }
+}
+
+void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 channel)
+{
+ LLMessageSystem* msg = gMessageSystem;
+ msg->newMessageFast(_PREHASH_ChatFromViewer);
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ msg->nextBlockFast(_PREHASH_ChatData);
+ msg->addStringFast(_PREHASH_Message, utf8_out_text);
+ msg->addU8Fast(_PREHASH_Type, type);
+ msg->addS32("Channel", channel);
+
+ gAgent.sendReliableMessage();
+
+ LLViewerStats::getInstance()->incStat(LLViewerStats::ST_CHAT_COUNT);
+}
+
+class LLChatCommandHandler : public LLCommandHandler
+{
+public:
+ // not allowed from outside the app
+ LLChatCommandHandler() : LLCommandHandler("chat", UNTRUSTED_BLOCK) { }
+
+ // Your code here
+ bool handle(const LLSD& tokens, const LLSD& query_map,
+ LLMediaCtrl* web)
+ {
+ bool retval = false;
+ // Need at least 2 tokens to have a valid message.
+ if (tokens.size() < 2)
+ {
+ retval = false;
+ }
+ else
+ {
+ S32 channel = tokens[0].asInteger();
+ // VWR-19499 Restrict function to chat channels greater than 0.
+ if ((channel > 0) && (channel < CHAT_CHANNEL_DEBUG))
+ {
+ retval = true;
+ // Send unescaped message, see EXT-6353.
+ std::string unescaped_mesg (LLURI::unescape(tokens[1].asString()));
+ send_chat_from_viewer(unescaped_mesg, CHAT_TYPE_NORMAL, channel);
+ }
+ else
+ {
+ retval = false;
+ // Tell us this is an unsupported SLurl.
+ }
+ }
+ return retval;
+ }
+};
+
+// Creating the object registers with the dispatcher.
+LLChatCommandHandler gChatHandler;
diff --git a/indra/newview/llfloaterimnearbychat.h b/indra/newview/llfloaterimnearbychat.h
new file mode 100755
index 0000000000..f0daacd6a9
--- /dev/null
+++ b/indra/newview/llfloaterimnearbychat.h
@@ -0,0 +1,119 @@
+/**
+ * @file llfloaterimnearbychat.h
+ * @brief LLFloaterIMNearbyChat class definition
+ *
+ * $LicenseInfo:firstyear=2002&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$
+ */
+
+#ifndef LL_LLFLOATERIMNEARBYCHAT_H
+#define LL_LLFLOATERIMNEARBYCHAT_H
+
+#include "llfloaterimsessiontab.h"
+#include "llcombobox.h"
+#include "llgesturemgr.h"
+#include "llchat.h"
+#include "llvoiceclient.h"
+#include "lloutputmonitorctrl.h"
+#include "llspeakers.h"
+#include "llscrollbar.h"
+#include "llviewerchat.h"
+#include "llpanel.h"
+
+class LLResizeBar;
+
+class LLFloaterIMNearbyChat
+ : public LLFloaterIMSessionTab
+{
+public:
+ // constructor for inline chat-bars (e.g. hosted in chat history window)
+ LLFloaterIMNearbyChat(const LLSD& key = LLSD(LLUUID()));
+ ~LLFloaterIMNearbyChat() {}
+
+ static LLFloaterIMNearbyChat* buildFloater(const LLSD& key);
+
+ /*virtual*/ BOOL postBuild();
+ /*virtual*/ void onOpen(const LLSD& key);
+ /*virtual*/ void onClose(bool app_quitting);
+ /*virtual*/ void setVisible(BOOL visible);
+ /*virtual*/ void setVisibleAndFrontmost(BOOL take_focus=TRUE, const LLSD& key = LLSD());
+ /*virtual*/ void closeHostedFloater();
+
+ void loadHistory();
+ void reloadMessages(bool clean_messages = false);
+ void removeScreenChat();
+
+ void show();
+ bool isChatVisible() const;
+
+ /** @param archive true - to save a message to the chat history log */
+ void addMessage (const LLChat& message,bool archive = true, const LLSD &args = LLSD());
+
+ LLChatEntry* getChatBox() { return mInputEditor; }
+
+ std::string getCurrentChat();
+ S32 getMessageArchiveLength() {return mMessageArchive.size();}
+
+ virtual BOOL handleKeyHere( KEY key, MASK mask );
+
+ static void startChat(const char* line);
+ static void stopChat();
+
+ static void sendChatFromViewer(const std::string &utf8text, EChatType type, BOOL animate);
+ static void sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL animate);
+
+ static bool isWordsName(const std::string& name);
+
+ void showHistory();
+
+protected:
+ static BOOL matchChatTypeTrigger(const std::string& in_str, std::string* out_str);
+ void onChatBoxKeystroke();
+ void onChatBoxFocusLost();
+ void onChatBoxFocusReceived();
+
+ void sendChat( EChatType type );
+ void onChatBoxCommit();
+ void onChatFontChange(LLFontGL* fontp);
+
+ /*virtual*/ void onTearOffClicked();
+ /*virtual*/ void onClickCloseBtn(bool app_qutting = false);
+
+ static LLWString stripChannelNumber(const LLWString &mesg, S32* channel);
+ EChatType processChatTypeTriggers(EChatType type, std::string &str);
+
+ void displaySpeakingIndicator();
+
+ // Which non-zero channel did we last chat on?
+ static S32 sLastSpecialChatChannel;
+
+ LLOutputMonitorCtrl* mOutputMonitor;
+ LLLocalSpeakerMgr* mSpeakerMgr;
+
+ S32 mExpandedHeight;
+
+private:
+ /*virtual*/ void refresh();
+
+ std::vector<LLChat> mMessageArchive;
+};
+
+#endif // LL_LLFLOATERIMNEARBYCHAT_H
diff --git a/indra/newview/llfloaterimnearbychathandler.cpp b/indra/newview/llfloaterimnearbychathandler.cpp
new file mode 100755
index 0000000000..a8f815c389
--- /dev/null
+++ b/indra/newview/llfloaterimnearbychathandler.cpp
@@ -0,0 +1,649 @@
+/**
+ * @file LLFloaterIMNearbyChatHandler.cpp
+ * @brief Nearby chat chat managment
+ *
+ * $LicenseInfo:firstyear=2009&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 "llviewerprecompiledheaders.h"
+
+#include "llagentdata.h" // for gAgentID
+#include "llfloaterimnearbychathandler.h"
+
+#include "llchatitemscontainerctrl.h"
+#include "llfirstuse.h"
+#include "llfloaterscriptdebug.h"
+#include "llhints.h"
+#include "llfloaterimnearbychat.h"
+#include "llrecentpeople.h"
+
+#include "llviewercontrol.h"
+
+#include "llfloaterreg.h"//for LLFloaterReg::getTypedInstance
+#include "llviewerwindow.h"//for screen channel position
+#include "llfloaterimnearbychat.h"
+#include "llfloaterimcontainer.h"
+#include "llrootview.h"
+#include "lllayoutstack.h"
+
+//add LLFloaterIMNearbyChatHandler to LLNotificationsUI namespace
+using namespace LLNotificationsUI;
+
+static LLFloaterIMNearbyChatToastPanel* createToastPanel()
+{
+ LLFloaterIMNearbyChatToastPanel* item = LLFloaterIMNearbyChatToastPanel::createInstance();
+ return item;
+}
+
+
+//-----------------------------------------------------------------------------------------------
+//LLFloaterIMNearbyChatScreenChannel
+//-----------------------------------------------------------------------------------------------
+
+class LLFloaterIMNearbyChatScreenChannel: public LLScreenChannelBase
+{
+ LOG_CLASS(LLFloaterIMNearbyChatScreenChannel);
+public:
+ typedef std::vector<LLHandle<LLToast> > toast_vec_t;
+ typedef std::list<LLHandle<LLToast> > toast_list_t;
+
+ LLFloaterIMNearbyChatScreenChannel(const Params& p)
+ : LLScreenChannelBase(p)
+ {
+ mStopProcessing = false;
+
+ LLControlVariable* ctrl = gSavedSettings.getControl("NearbyToastLifeTime").get();
+ if (ctrl)
+ {
+ ctrl->getSignal()->connect(boost::bind(&LLFloaterIMNearbyChatScreenChannel::updateToastsLifetime, this));
+ }
+
+ ctrl = gSavedSettings.getControl("NearbyToastFadingTime").get();
+ if (ctrl)
+ {
+ ctrl->getSignal()->connect(boost::bind(&LLFloaterIMNearbyChatScreenChannel::updateToastFadingTime, this));
+ }
+ }
+
+ void addChat (LLSD& chat);
+ void arrangeToasts ();
+
+ typedef boost::function<LLFloaterIMNearbyChatToastPanel* (void )> create_toast_panel_callback_t;
+ void setCreatePanelCallback(create_toast_panel_callback_t value) { m_create_toast_panel_callback_t = value;}
+
+ void onToastDestroyed (LLToast* toast, bool app_quitting);
+ void onToastFade (LLToast* toast);
+
+ void redrawToasts()
+ {
+ arrangeToasts();
+ }
+
+ // hide all toasts from screen, but not remove them from a channel
+ // removes all toasts from a channel
+ virtual void removeToastsFromChannel()
+ {
+ for(toast_vec_t::iterator it = m_active_toasts.begin(); it != m_active_toasts.end(); ++it)
+ {
+ addToToastPool(it->get());
+ }
+ m_active_toasts.clear();
+ };
+
+ virtual void deleteAllChildren()
+ {
+ LL_DEBUGS("NearbyChat") << "Clearing toast pool" << llendl;
+ m_toast_pool.clear();
+ m_active_toasts.clear();
+ LLScreenChannelBase::deleteAllChildren();
+ }
+
+protected:
+ void deactivateToast(LLToast* toast);
+ void addToToastPool(LLToast* toast)
+ {
+ if (!toast) return;
+ LL_DEBUGS("NearbyChat") << "Pooling toast" << llendl;
+ toast->setVisible(FALSE);
+ toast->stopTimer();
+ toast->setIsHidden(true);
+
+ // Nearby chat toasts that are hidden, not destroyed. They are collected to the toast pool, so that
+ // they can be used next time, this is done for performance. But if the toast lifetime was changed
+ // (from preferences floater (STORY-36)) while it was shown (at this moment toast isn't in the pool yet)
+ // changes don't take affect.
+ // So toast's lifetime should be updated each time it's added to the pool. Otherwise viewer would have
+ // to be restarted so that changes take effect.
+ toast->setLifetime(gSavedSettings.getS32("NearbyToastLifeTime"));
+ toast->setFadingTime(gSavedSettings.getS32("NearbyToastFadingTime"));
+ m_toast_pool.push_back(toast->getHandle());
+ }
+
+ void createOverflowToast(S32 bottom, F32 timer);
+
+ void updateToastsLifetime();
+
+ void updateToastFadingTime();
+
+ create_toast_panel_callback_t m_create_toast_panel_callback_t;
+
+ bool createPoolToast();
+
+ toast_vec_t m_active_toasts;
+ toast_list_t m_toast_pool;
+
+ bool mStopProcessing;
+ bool mChannelRect;
+};
+
+
+
+//-----------------------------------------------------------------------------------------------
+// LLFloaterIMNearbyChatToast
+//-----------------------------------------------------------------------------------------------
+
+// We're deriving from LLToast to be able to override onClose()
+// in order to handle closing nearby chat toasts properly.
+class LLFloaterIMNearbyChatToast : public LLToast
+{
+ LOG_CLASS(LLFloaterIMNearbyChatToast);
+public:
+ LLFloaterIMNearbyChatToast(const LLToast::Params& p, LLFloaterIMNearbyChatScreenChannel* nc_channelp)
+ : LLToast(p),
+ mNearbyChatScreenChannelp(nc_channelp)
+ {
+ }
+
+ /*virtual*/ void onClose(bool app_quitting);
+
+private:
+ LLFloaterIMNearbyChatScreenChannel* mNearbyChatScreenChannelp;
+};
+
+//-----------------------------------------------------------------------------------------------
+// LLFloaterIMNearbyChatScreenChannel
+//-----------------------------------------------------------------------------------------------
+
+void LLFloaterIMNearbyChatScreenChannel::deactivateToast(LLToast* toast)
+{
+ toast_vec_t::iterator pos = std::find(m_active_toasts.begin(), m_active_toasts.end(), toast->getHandle());
+
+ if (pos != m_active_toasts.end())
+ {
+ LL_DEBUGS("NearbyChat") << "Deactivating toast" << llendl;
+ m_active_toasts.erase(pos);
+ }
+}
+
+void LLFloaterIMNearbyChatScreenChannel::createOverflowToast(S32 bottom, F32 timer)
+{
+ //we don't need overflow toast in nearby chat
+}
+
+void LLFloaterIMNearbyChatScreenChannel::onToastDestroyed(LLToast* toast, bool app_quitting)
+{
+ LL_DEBUGS("NearbyChat") << "Toast destroyed (app_quitting=" << app_quitting << ")" << llendl;
+
+ if (app_quitting)
+ {
+ // Viewer is quitting.
+ // Immediately stop processing chat messages (EXT-1419).
+ mStopProcessing = true;
+ }
+ else
+ {
+ // The toast is being closed by user (STORM-192).
+ // Remove it from the list of active toasts to prevent
+ // further references to the invalid pointer.
+ deactivateToast(toast);
+ }
+}
+
+void LLFloaterIMNearbyChatScreenChannel::onToastFade(LLToast* toast)
+{
+ LL_DEBUGS("NearbyChat") << "Toast fading" << llendl;
+
+ //fade mean we put toast to toast pool
+ if(!toast)
+ return;
+
+ deactivateToast(toast);
+
+ addToToastPool(toast);
+
+ arrangeToasts();
+}
+
+void LLFloaterIMNearbyChatScreenChannel::updateToastsLifetime()
+{
+ S32 seconds = gSavedSettings.getS32("NearbyToastLifeTime");
+ toast_list_t::iterator it;
+
+ for(it = m_toast_pool.begin(); it != m_toast_pool.end(); ++it)
+ {
+ (*it).get()->setLifetime(seconds);
+ }
+}
+
+void LLFloaterIMNearbyChatScreenChannel::updateToastFadingTime()
+{
+ S32 seconds = gSavedSettings.getS32("NearbyToastFadingTime");
+ toast_list_t::iterator it;
+
+ for(it = m_toast_pool.begin(); it != m_toast_pool.end(); ++it)
+ {
+ (*it).get()->setFadingTime(seconds);
+ }
+}
+
+bool LLFloaterIMNearbyChatScreenChannel::createPoolToast()
+{
+ LLFloaterIMNearbyChatToastPanel* panel= m_create_toast_panel_callback_t();
+ if(!panel)
+ return false;
+
+ LLToast::Params p;
+ p.panel = panel;
+ p.lifetime_secs = gSavedSettings.getS32("NearbyToastLifeTime");
+ p.fading_time_secs = gSavedSettings.getS32("NearbyToastFadingTime");
+
+ LLToast* toast = new LLFloaterIMNearbyChatToast(p, this);
+
+
+ toast->setOnFadeCallback(boost::bind(&LLFloaterIMNearbyChatScreenChannel::onToastFade, this, _1));
+
+ // If the toast gets somehow prematurely destroyed, deactivate it to prevent crash (STORM-1352).
+ toast->setOnToastDestroyedCallback(boost::bind(&LLFloaterIMNearbyChatScreenChannel::onToastDestroyed, this, _1, false));
+
+ LL_DEBUGS("NearbyChat") << "Creating and pooling toast" << llendl;
+ m_toast_pool.push_back(toast->getHandle());
+ return true;
+}
+
+void LLFloaterIMNearbyChatScreenChannel::addChat(LLSD& chat)
+{
+ //look in pool. if there is any message
+ if(mStopProcessing)
+ return;
+
+ /*
+ find last toast and check ID
+ */
+
+ if(m_active_toasts.size())
+ {
+ LLUUID fromID = chat["from_id"].asUUID(); // agent id or object id
+ std::string from = chat["from"].asString();
+ LLToast* toast = m_active_toasts[0].get();
+ if (toast)
+ {
+ LLFloaterIMNearbyChatToastPanel* panel = dynamic_cast<LLFloaterIMNearbyChatToastPanel*>(toast->getPanel());
+
+ if(panel && panel->messageID() == fromID && panel->getFromName() == from && panel->canAddText())
+ {
+ panel->addMessage(chat);
+ toast->reshapeToPanel();
+ toast->startTimer();
+
+ arrangeToasts();
+ return;
+ }
+ }
+ }
+
+
+
+ if(m_toast_pool.empty())
+ {
+ //"pool" is empty - create one more panel
+ LL_DEBUGS("NearbyChat") << "Empty pool" << llendl;
+ if(!createPoolToast())//created toast will go to pool. so next call will find it
+ return;
+ addChat(chat);
+ return;
+ }
+
+ int chat_type = chat["chat_type"].asInteger();
+
+ if( ((EChatType)chat_type == CHAT_TYPE_DEBUG_MSG))
+ {
+ if(gSavedSettings.getBOOL("ShowScriptErrors") == FALSE)
+ return;
+ if(gSavedSettings.getS32("ShowScriptErrorsLocation")== 1)
+ return;
+ }
+
+
+ //take 1st element from pool, (re)initialize it, put it in active toasts
+
+ LL_DEBUGS("NearbyChat") << "Getting toast from pool" << llendl;
+ LLToast* toast = m_toast_pool.back().get();
+
+ m_toast_pool.pop_back();
+
+
+ LLFloaterIMNearbyChatToastPanel* panel = dynamic_cast<LLFloaterIMNearbyChatToastPanel*>(toast->getPanel());
+ if(!panel)
+ return;
+ panel->init(chat);
+
+ toast->reshapeToPanel();
+ toast->startTimer();
+
+ m_active_toasts.push_back(toast->getHandle());
+
+ arrangeToasts();
+}
+
+static bool sort_toasts_predicate(LLHandle<LLToast> first, LLHandle<LLToast> second)
+{
+ if (!first.get() || !second.get()) return false; // STORM-1352
+
+ F32 v1 = first.get()->getTimeLeftToLive();
+ F32 v2 = second.get()->getTimeLeftToLive();
+ return v1 > v2;
+}
+
+void LLFloaterIMNearbyChatScreenChannel::arrangeToasts()
+{
+ if(mStopProcessing || isHovering())
+ return;
+
+ if (mFloaterSnapRegion == NULL)
+ {
+ mFloaterSnapRegion = gViewerWindow->getRootView()->getChildView("floater_snap_region");
+ }
+
+ if (!getParent())
+ {
+ // connect to floater snap region just to get resize events, we don't care about being a proper widget
+ mFloaterSnapRegion->addChild(this);
+ setFollows(FOLLOWS_ALL);
+ }
+
+ LLRect toast_rect;
+ updateRect();
+
+ LLRect channel_rect;
+ mFloaterSnapRegion->localRectToOtherView(mFloaterSnapRegion->getLocalRect(), &channel_rect, gFloaterView);
+ channel_rect.mLeft += 10;
+ channel_rect.mRight = channel_rect.mLeft + 300;
+
+ S32 channel_bottom = channel_rect.mBottom;
+
+ S32 bottom = channel_bottom + 80;
+ S32 margin = gSavedSettings.getS32("ToastGap");
+
+ //sort active toasts
+ std::sort(m_active_toasts.begin(),m_active_toasts.end(),sort_toasts_predicate);
+
+ //calc max visible item and hide other toasts.
+
+ for(toast_vec_t::iterator it = m_active_toasts.begin(); it != m_active_toasts.end(); ++it)
+ {
+ LLToast* toast = it->get();
+ if (!toast)
+ {
+ llwarns << "NULL found in the active chat toasts list!" << llendl;
+ continue;
+ }
+
+ S32 toast_top = bottom + toast->getRect().getHeight() + margin;
+
+ if(toast_top > channel_rect.getHeight())
+ {
+ while(it!=m_active_toasts.end())
+ {
+ addToToastPool(it->get());
+ it=m_active_toasts.erase(it);
+ }
+ break;
+ }
+
+ toast_rect = toast->getRect();
+ toast_rect.setLeftTopAndSize(channel_rect.mLeft , bottom + toast_rect.getHeight(), toast_rect.getWidth() ,toast_rect.getHeight());
+
+ toast->setRect(toast_rect);
+ bottom += toast_rect.getHeight() - toast->getTopPad() + margin;
+ }
+
+ // use reverse order to provide correct z-order and avoid toast blinking
+
+ for(toast_vec_t::reverse_iterator it = m_active_toasts.rbegin(); it != m_active_toasts.rend(); ++it)
+ {
+ LLToast* toast = it->get();
+ if (toast)
+ {
+ toast->setIsHidden(false);
+ toast->setVisible(TRUE);
+ }
+ }
+
+}
+
+
+
+//-----------------------------------------------------------------------------------------------
+//LLFloaterIMNearbyChatHandler
+//-----------------------------------------------------------------------------------------------
+boost::scoped_ptr<LLEventPump> LLFloaterIMNearbyChatHandler::sChatWatcher(new LLEventStream("LLChat"));
+
+LLFloaterIMNearbyChatHandler::LLFloaterIMNearbyChatHandler()
+{
+ // Getting a Channel for our notifications
+ LLFloaterIMNearbyChatScreenChannel::Params p;
+ p.id = LLUUID(gSavedSettings.getString("NearByChatChannelUUID"));
+ LLFloaterIMNearbyChatScreenChannel* channel = new LLFloaterIMNearbyChatScreenChannel(p);
+
+ LLFloaterIMNearbyChatScreenChannel::create_toast_panel_callback_t callback = createToastPanel;
+
+ channel->setCreatePanelCallback(callback);
+
+ LLChannelManager::getInstance()->addChannel(channel);
+
+ mChannel = channel->getHandle();
+}
+
+LLFloaterIMNearbyChatHandler::~LLFloaterIMNearbyChatHandler()
+{
+}
+
+
+void LLFloaterIMNearbyChatHandler::initChannel()
+{
+ //LLRect snap_rect = gFloaterView->getSnapRect();
+ //mChannel->init(snap_rect.mLeft, snap_rect.mLeft + 200);
+}
+
+
+
+void LLFloaterIMNearbyChatHandler::processChat(const LLChat& chat_msg,
+ const LLSD &args)
+{
+ if(chat_msg.mMuted == TRUE)
+ return;
+
+ if(chat_msg.mText.empty())
+ return;//don't process empty messages
+
+ LLFloaterReg::getInstance("im_container");
+ LLFloaterIMNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat");
+
+ // Build notification data
+ LLSD chat;
+ chat["message"] = chat_msg.mText;
+ chat["from"] = chat_msg.mFromName;
+ chat["from_id"] = chat_msg.mFromID;
+ chat["time"] = chat_msg.mTime;
+ chat["source"] = (S32)chat_msg.mSourceType;
+ chat["chat_type"] = (S32)chat_msg.mChatType;
+ chat["chat_style"] = (S32)chat_msg.mChatStyle;
+ // Pass sender info so that it can be rendered properly (STORM-1021).
+ chat["sender_slurl"] = LLViewerChat::getSenderSLURL(chat_msg, args);
+
+ if (chat_msg.mChatType == CHAT_TYPE_DIRECT &&
+ chat_msg.mText.length() > 0 &&
+ chat_msg.mText[0] == '@')
+ {
+ // Send event on to LLEventStream and exit
+ sChatWatcher->post(chat);
+ return;
+ }
+
+ // don't show toast and add message to chat history on receive debug message
+ // with disabled setting showing script errors or enabled setting to show script
+ // errors in separate window.
+ if (chat_msg.mChatType == CHAT_TYPE_DEBUG_MSG)
+ {
+ if(gSavedSettings.getBOOL("ShowScriptErrors") == FALSE)
+ return;
+
+ // don't process debug messages from not owned objects, see EXT-7762
+ if (gAgentID != chat_msg.mOwnerID)
+ {
+ return;
+ }
+
+ if (gSavedSettings.getS32("ShowScriptErrorsLocation")== 1)// show error in window //("ScriptErrorsAsChat"))
+ {
+
+ LLColor4 txt_color;
+
+ LLViewerChat::getChatColor(chat_msg,txt_color);
+
+ LLFloaterScriptDebug::addScriptLine(chat_msg.mText,
+ chat_msg.mFromName,
+ txt_color,
+ chat_msg.mFromID);
+ return;
+ }
+ }
+
+ nearby_chat->addMessage(chat_msg, true, args);
+
+ if(chat_msg.mSourceType == CHAT_SOURCE_AGENT
+ && chat_msg.mFromID.notNull()
+ && chat_msg.mFromID != gAgentID)
+ {
+ LLFirstUse::otherAvatarChatFirst();
+
+ // Add sender to the recent people list.
+ LLRecentPeople::instance().add(chat_msg.mFromID);
+
+ }
+
+ // Send event on to LLEventStream
+ sChatWatcher->post(chat);
+
+ LLFloaterIMContainer* im_box = LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container");
+
+ if(( ( chat_msg.mSourceType == CHAT_SOURCE_AGENT
+ && gSavedSettings.getBOOL("UseChatBubbles") )
+ || mChannel.isDead()
+ || !mChannel.get()->getShowToasts() )
+ && nearby_chat->isMessagePaneExpanded())
+ // to prevent toasts in Do Not Disturb mode
+ return;//no need in toast if chat is visible or if bubble chat is enabled
+
+ // arrange a channel on a screen
+ if(!mChannel.get()->getVisible())
+ {
+ initChannel();
+ }
+
+ /*
+ //comment all this due to EXT-4432
+ ..may clean up after some time...
+
+ //only messages from AGENTS
+ if(CHAT_SOURCE_OBJECT == chat_msg.mSourceType)
+ {
+ if(chat_msg.mChatType == CHAT_TYPE_DEBUG_MSG)
+ return;//ok for now we don't skip messeges from object, so skip only debug messages
+ }
+ */
+
+ LLFloaterIMNearbyChatScreenChannel* channel = dynamic_cast<LLFloaterIMNearbyChatScreenChannel*>(mChannel.get());
+
+ if(channel)
+ {
+ // Handle IRC styled messages.
+ std::string toast_msg;
+ if (chat_msg.mChatStyle == CHAT_STYLE_IRC)
+ {
+ if (!chat_msg.mFromName.empty())
+ {
+ toast_msg += chat_msg.mFromName;
+ }
+ toast_msg += chat_msg.mText.substr(3);
+ }
+ else
+ {
+ toast_msg = chat_msg.mText;
+ }
+
+ //Don't show nearby toast, if conversation is visible and selected
+ if ((nearby_chat->hasFocus()) ||
+ (LLFloater::isVisible(nearby_chat) && nearby_chat->isTornOff() && !nearby_chat->isMinimized()) ||
+ ((im_box->getSelectedSession().isNull() &&
+ ((LLFloater::isVisible(im_box) && !im_box->isMinimized() && im_box->isFrontmost())
+ || (LLFloater::isVisible(nearby_chat) && !nearby_chat->isMinimized() && nearby_chat->isFrontmost())))))
+ {
+ if(nearby_chat->isMessagePaneExpanded())
+ {
+ return;
+ }
+ }
+
+ //Will show toast when chat preference is set
+ if((gSavedSettings.getString("NotificationNearbyChatOptions") == "toast") || !nearby_chat->isMessagePaneExpanded())
+ {
+ // Add a nearby chat toast.
+ LLUUID id;
+ id.generate();
+ chat["id"] = id;
+ std::string r_color_name = "White";
+ F32 r_color_alpha = 1.0f;
+ LLViewerChat::getChatColor( chat_msg, r_color_name, r_color_alpha);
+
+ chat["text_color"] = r_color_name;
+ chat["color_alpha"] = r_color_alpha;
+ chat["font_size"] = (S32)LLViewerChat::getChatFontSize() ;
+ chat["message"] = toast_msg;
+ channel->addChat(chat);
+ }
+
+ }
+}
+
+
+//-----------------------------------------------------------------------------------------------
+// LLFloaterIMNearbyChatToast
+//-----------------------------------------------------------------------------------------------
+
+// virtual
+void LLFloaterIMNearbyChatToast::onClose(bool app_quitting)
+{
+ mNearbyChatScreenChannelp->onToastDestroyed(this, app_quitting);
+}
+
+// EOF
diff --git a/indra/newview/llfloaterimnearbychathandler.h b/indra/newview/llfloaterimnearbychathandler.h
new file mode 100755
index 0000000000..5e6f8cde30
--- /dev/null
+++ b/indra/newview/llfloaterimnearbychathandler.h
@@ -0,0 +1,54 @@
+/**
+ * @file llfloaterimnearbychathandler.h
+ * @brief nearby chat notify
+ *
+ * $LicenseInfo:firstyear=2004&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$
+ */
+
+#ifndef LL_LLFLOATERIMNEARBYCHATHANDLER_H
+#define LL_LLFLOATERIMNEARBYCHATHANDLER_H
+
+#include "llnotificationhandler.h"
+
+class LLEventPump;
+
+//add LLFloaterIMNearbyChatHandler to LLNotificationsUI namespace
+namespace LLNotificationsUI{
+
+class LLFloaterIMNearbyChatHandler : public LLChatHandler
+{
+public:
+ LLFloaterIMNearbyChatHandler();
+ virtual ~LLFloaterIMNearbyChatHandler();
+
+
+ virtual void processChat(const LLChat& chat_msg, const LLSD &args);
+
+protected:
+ virtual void initChannel();
+
+ static boost::scoped_ptr<LLEventPump> sChatWatcher;
+};
+
+}
+
+#endif /* LL_LLFLOATERIMNEARBYCHATHANDLER_H */
diff --git a/indra/newview/llfloaterimnearbychatlistener.cpp b/indra/newview/llfloaterimnearbychatlistener.cpp
new file mode 100755
index 0000000000..5a5f6c72c8
--- /dev/null
+++ b/indra/newview/llfloaterimnearbychatlistener.cpp
@@ -0,0 +1,100 @@
+/**
+ * @file llfloaterimnearbychatlistener.cpp
+ * @author Dave Simmons
+ * @date 2011-03-15
+ * @brief Implementation for LLFloaterIMNearbyChatListener.
+ *
+ * $LicenseInfo:firstyear=2011&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llfloaterimnearbychatlistener.h"
+#include "llfloaterimnearbychat.h"
+
+#include "llagent.h"
+#include "llchat.h"
+#include "llviewercontrol.h"
+
+
+LLFloaterIMNearbyChatListener::LLFloaterIMNearbyChatListener(LLFloaterIMNearbyChat & chatbar)
+ : LLEventAPI("LLChatBar",
+ "LLChatBar listener to (e.g.) sendChat, etc."),
+ mChatbar(chatbar)
+{
+ add("sendChat",
+ "Send chat to the simulator:\n"
+ "[\"message\"] chat message text [required]\n"
+ "[\"channel\"] chat channel number [default = 0]\n"
+ "[\"type\"] chat type \"whisper\", \"normal\", \"shout\" [default = \"normal\"]",
+ &LLFloaterIMNearbyChatListener::sendChat);
+}
+
+
+// "sendChat" command
+void LLFloaterIMNearbyChatListener::sendChat(LLSD const & chat_data) const
+{
+ // Extract the data
+ std::string chat_text = chat_data["message"].asString();
+
+ S32 channel = 0;
+ if (chat_data.has("channel"))
+ {
+ channel = chat_data["channel"].asInteger();
+ if (channel < 0 || channel >= CHAT_CHANNEL_DEBUG)
+ { // Use 0 up to (but not including) CHAT_CHANNEL_DEBUG
+ channel = 0;
+ }
+ }
+
+ EChatType type_o_chat = CHAT_TYPE_NORMAL;
+ if (chat_data.has("type"))
+ {
+ std::string type_string = chat_data["type"].asString();
+ if (type_string == "whisper")
+ {
+ type_o_chat = CHAT_TYPE_WHISPER;
+ }
+ else if (type_string == "shout")
+ {
+ type_o_chat = CHAT_TYPE_SHOUT;
+ }
+ }
+
+ // Have to prepend /42 style channel numbers
+ std::string chat_to_send;
+ if (channel == 0)
+ {
+ chat_to_send = chat_text;
+ }
+ else
+ {
+ chat_to_send += "/";
+ chat_to_send += chat_data["channel"].asString();
+ chat_to_send += " ";
+ chat_to_send += chat_text;
+ }
+
+ // Send it as if it was typed in
+ mChatbar.sendChatFromViewer(chat_to_send, type_o_chat, ((BOOL)(channel == 0)) && gSavedSettings.getBOOL("PlayChatAnim"));
+}
+
diff --git a/indra/newview/llfloaterimnearbychatlistener.h b/indra/newview/llfloaterimnearbychatlistener.h
new file mode 100755
index 0000000000..1470a6dc1e
--- /dev/null
+++ b/indra/newview/llfloaterimnearbychatlistener.h
@@ -0,0 +1,50 @@
+/**
+ * @file llfloaterimnearbychatlistener.h
+ * @author Dave Simmons
+ * @date 2011-03-15
+ * @brief Class definition for LLFloaterIMNearbyChatListener.
+ *
+ * $LicenseInfo:firstyear=2011&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+
+#ifndef LL_LLFLOATERIMNEARBYCHATLISTENER_H
+#define LL_LLFLOATERIMNEARBYCHATLISTENER_H
+
+#include "lleventapi.h"
+
+class LLSD;
+class LLFloaterIMNearbyChat;
+
+class LLFloaterIMNearbyChatListener : public LLEventAPI
+{
+public:
+ LLFloaterIMNearbyChatListener(LLFloaterIMNearbyChat & chatbar);
+
+private:
+ void sendChat(LLSD const & chat_data) const;
+
+ LLFloaterIMNearbyChat & mChatbar;
+};
+
+#endif // LL_LLFLOATERIMNEARBYCHATLISTENER_H
+
diff --git a/indra/newview/llfloaterimsession.cpp b/indra/newview/llfloaterimsession.cpp
new file mode 100755
index 0000000000..14e1a486d3
--- /dev/null
+++ b/indra/newview/llfloaterimsession.cpp
@@ -0,0 +1,1303 @@
+/**
+ * @file llfloaterimsession.cpp
+ * @brief LLFloaterIMSession class definition
+ *
+ * $LicenseInfo:firstyear=2009&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 "llviewerprecompiledheaders.h"
+
+#include "llfloaterimsession.h"
+
+#include "lldraghandle.h"
+#include "llnotificationsutil.h"
+
+#include "llagent.h"
+#include "llappviewer.h"
+#include "llavataractions.h"
+#include "llavatarnamecache.h"
+#include "llbutton.h"
+#include "llchannelmanager.h"
+#include "llchiclet.h"
+#include "llchicletbar.h"
+#include "lldonotdisturbnotificationstorage.h"
+#include "llfloaterreg.h"
+#include "llfloateravatarpicker.h"
+#include "llfloaterimcontainer.h" // to replace separate IM Floaters with multifloater container
+#include "llinventoryfunctions.h"
+//#include "lllayoutstack.h"
+#include "llchatentry.h"
+#include "lllogchat.h"
+#include "llscreenchannel.h"
+#include "llsyswellwindow.h"
+#include "lltrans.h"
+#include "llchathistory.h"
+#include "llnotifications.h"
+#include "llviewerwindow.h"
+#include "lltransientfloatermgr.h"
+#include "llinventorymodel.h"
+#include "llrootview.h"
+#include "llspeakers.h"
+#include "llviewerchat.h"
+#include "llnotificationmanager.h"
+#include "llautoreplace.h"
+
+floater_showed_signal_t LLFloaterIMSession::sIMFloaterShowedSignal;
+
+LLFloaterIMSession::LLFloaterIMSession(const LLUUID& session_id)
+ : LLFloaterIMSessionTab(session_id),
+ mLastMessageIndex(-1),
+ mDialog(IM_NOTHING_SPECIAL),
+ mTypingStart(),
+ mShouldSendTypingState(false),
+ mMeTyping(false),
+ mOtherTyping(false),
+ mSessionNameUpdatedForTyping(false),
+ mTypingTimer(),
+ mTypingTimeoutTimer(),
+ mPositioned(false),
+ mSessionInitialized(false)
+{
+ mIsNearbyChat = false;
+
+ initIMSession(session_id);
+
+ setOverlapsScreenChannel(true);
+
+ LLTransientFloaterMgr::getInstance()->addControlView(LLTransientFloaterMgr::IM, this);
+ mEnableCallbackRegistrar.add("Avatar.EnableGearItem", boost::bind(&LLFloaterIMSession::enableGearMenuItem, this, _2));
+ mCommitCallbackRegistrar.add("Avatar.GearDoToSelected", boost::bind(&LLFloaterIMSession::GearDoToSelected, this, _2));
+ mEnableCallbackRegistrar.add("Avatar.CheckGearItem", boost::bind(&LLFloaterIMSession::checkGearMenuItem, this, _2));
+
+ setDocked(true);
+}
+
+
+// virtual
+void LLFloaterIMSession::refresh()
+{
+ if (mMeTyping)
+{
+ // Time out if user hasn't typed for a while.
+ if (mTypingTimeoutTimer.getElapsedTimeF32() > LLAgent::TYPING_TIMEOUT_SECS)
+ {
+ setTyping(false);
+ }
+ }
+}
+
+// virtual
+void LLFloaterIMSession::onTearOffClicked()
+{
+ LLFloaterIMSessionTab::onTearOffClicked();
+}
+
+// virtual
+void LLFloaterIMSession::onClickCloseBtn(bool)
+{
+ LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(mSessionID);
+
+ if (session != NULL)
+ {
+ bool is_call_with_chat = session->isGroupSessionType()
+ || session->isAdHocSessionType() || session->isP2PSessionType();
+
+ LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionID);
+
+ if (is_call_with_chat && voice_channel != NULL
+ && voice_channel->isActive())
+ {
+ LLSD payload;
+ payload["session_id"] = mSessionID;
+ LLNotificationsUtil::add("ConfirmLeaveCall", LLSD(), payload, confirmLeaveCallCallback);
+ return;
+ }
+ }
+ else
+ {
+ llwarns << "Empty session with id: " << (mSessionID.asString()) << llendl;
+ return;
+ }
+
+ LLFloaterIMSessionTab::onClickCloseBtn();
+}
+
+/* static */
+void LLFloaterIMSession::newIMCallback(const LLSD& data)
+{
+ if (data["num_unread"].asInteger() > 0 || data["from_id"].asUUID().isNull())
+ {
+ LLUUID session_id = data["session_id"].asUUID();
+
+ LLFloaterIMSession* floater = LLFloaterReg::findTypedInstance<LLFloaterIMSession>("impanel", session_id);
+
+ // update if visible, otherwise will be updated when opened
+ if (floater && floater->isInVisibleChain())
+ {
+ floater->updateMessages();
+ }
+ }
+}
+
+void LLFloaterIMSession::onVisibilityChange(const LLSD& new_visibility)
+{
+ bool visible = new_visibility.asBoolean();
+
+ LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionID);
+
+ if (visible && voice_channel &&
+ voice_channel->getState() == LLVoiceChannel::STATE_CONNECTED)
+ {
+ LLFloaterReg::showInstance("voice_call", mSessionID);
+ }
+ else
+ {
+ LLFloaterReg::hideInstance("voice_call", mSessionID);
+ }
+}
+
+void LLFloaterIMSession::onSendMsg( LLUICtrl* ctrl, void* userdata )
+{
+ LLFloaterIMSession* self = (LLFloaterIMSession*) userdata;
+ self->sendMsgFromInputEditor();
+ self->setTyping(false);
+}
+
+bool LLFloaterIMSession::enableGearMenuItem(const LLSD& userdata)
+{
+ std::string command = userdata.asString();
+ uuid_vec_t selected_uuids;
+ selected_uuids.push_back(mOtherParticipantUUID);
+
+ LLFloaterIMContainer* floater_container = LLFloaterIMContainer::getInstance();
+ return floater_container->enableContextMenuItem(command, selected_uuids);
+}
+
+void LLFloaterIMSession::GearDoToSelected(const LLSD& userdata)
+{
+ std::string command = userdata.asString();
+ uuid_vec_t selected_uuids;
+ selected_uuids.push_back(mOtherParticipantUUID);
+
+ LLFloaterIMContainer* floater_container = LLFloaterIMContainer::getInstance();
+ floater_container->doToParticipants(command, selected_uuids);
+}
+
+bool LLFloaterIMSession::checkGearMenuItem(const LLSD& userdata)
+{
+ std::string command = userdata.asString();
+ uuid_vec_t selected_uuids;
+ selected_uuids.push_back(mOtherParticipantUUID);
+
+ LLFloaterIMContainer* floater_container = LLFloaterIMContainer::getInstance();
+ return floater_container->checkContextMenuItem(command, selected_uuids);
+}
+
+void LLFloaterIMSession::sendMsgFromInputEditor()
+{
+ if (gAgent.isGodlike()
+ || (mDialog != IM_NOTHING_SPECIAL)
+ || !mOtherParticipantUUID.isNull())
+ {
+ if (mInputEditor)
+ {
+ LLWString text = mInputEditor->getWText();
+ LLWStringUtil::trim(text);
+ LLWStringUtil::replaceChar(text,182,'\n'); // Convert paragraph symbols back into newlines.
+ if(!text.empty())
+ {
+ // Truncate and convert to UTF8 for transport
+ std::string utf8_text = wstring_to_utf8str(text);
+
+ sendMsg(utf8_text);
+
+ mInputEditor->setText(LLStringUtil::null);
+ }
+ }
+ }
+ else
+ {
+ llinfos << "Cannot send IM to everyone unless you're a god." << llendl;
+ }
+}
+
+void LLFloaterIMSession::sendMsg(const std::string& msg)
+{
+ const std::string utf8_text = utf8str_truncate(msg, MAX_MSG_BUF_SIZE - 1);
+
+ if (mSessionInitialized)
+ {
+ LLIMModel::sendMessage(utf8_text, mSessionID, mOtherParticipantUUID, mDialog);
+ }
+ else
+ {
+ //queue up the message to send once the session is initialized
+ mQueuedMsgsForInit.append(utf8_text);
+ }
+
+ updateMessages();
+}
+
+LLFloaterIMSession::~LLFloaterIMSession()
+{
+ mVoiceChannelStateChangeConnection.disconnect();
+ if(LLVoiceClient::instanceExists())
+ {
+ LLVoiceClient::getInstance()->removeObserver(this);
+ }
+
+ LLTransientFloaterMgr::getInstance()->removeControlView(LLTransientFloaterMgr::IM, this);
+}
+
+
+void LLFloaterIMSession::initIMSession(const LLUUID& session_id)
+{
+ // Change the floater key to bind it to a new session.
+ setKey(session_id);
+
+ mSessionID = session_id;
+ mSession = LLIMModel::getInstance()->findIMSession(mSessionID);
+
+ if (mSession)
+ {
+ mIsP2PChat = mSession->isP2PSessionType();
+ mSessionInitialized = mSession->mSessionInitialized;
+ mDialog = mSession->mType;
+ }
+}
+
+void LLFloaterIMSession::initIMFloater()
+{
+ const LLUUID& other_party_id =
+ LLIMModel::getInstance()->getOtherParticipantID(mSessionID);
+ if (other_party_id.notNull())
+ {
+ mOtherParticipantUUID = other_party_id;
+ }
+
+ boundVoiceChannel();
+
+ mTypingStart = LLTrans::getString("IM_typing_start_string");
+
+ // Show control panel in torn off floaters only.
+ mParticipantListPanel->setVisible(!getHost() && gSavedSettings.getBOOL("IMShowControlPanel"));
+
+ // Disable input editor if session cannot accept text
+ if ( mSession && !mSession->mTextIMPossible )
+ {
+ mInputEditor->setEnabled(FALSE);
+ mInputEditor->setLabel(LLTrans::getString("IM_unavailable_text_label"));
+ }
+
+ if (!mIsP2PChat)
+ {
+ std::string session_name(LLIMModel::instance().getName(mSessionID));
+ updateSessionName(session_name);
+ }
+}
+
+//virtual
+BOOL LLFloaterIMSession::postBuild()
+{
+ BOOL result = LLFloaterIMSessionTab::postBuild();
+
+ mInputEditor->setMaxTextLength(1023);
+ mInputEditor->setAutoreplaceCallback(boost::bind(&LLAutoReplace::autoreplaceCallback, LLAutoReplace::getInstance(), _1, _2, _3, _4, _5));
+ mInputEditor->setFocusReceivedCallback( boost::bind(onInputEditorFocusReceived, _1, this) );
+ mInputEditor->setFocusLostCallback( boost::bind(onInputEditorFocusLost, _1, this) );
+ mInputEditor->setKeystrokeCallback( boost::bind(onInputEditorKeystroke, _1, this) );
+ mInputEditor->setCommitCallback(boost::bind(onSendMsg, _1, this));
+
+ setDocked(true);
+
+ LLButton* add_btn = getChild<LLButton>("add_btn");
+
+ // Allow to add chat participants depending on the session type
+ add_btn->setEnabled(isInviteAllowed());
+ add_btn->setClickedCallback(boost::bind(&LLFloaterIMSession::onAddButtonClicked, this));
+
+ childSetAction("voice_call_btn", boost::bind(&LLFloaterIMSession::onCallButtonClicked, this));
+
+ LLVoiceClient::getInstance()->addObserver(this);
+
+ //*TODO if session is not initialized yet, add some sort of a warning message like "starting session...blablabla"
+ //see LLFloaterIMPanel for how it is done (IB)
+
+ initIMFloater();
+
+ return result;
+}
+
+void LLFloaterIMSession::onAddButtonClicked()
+{
+ LLView * button = findChild<LLView>("toolbar_panel")->findChild<LLButton>("add_btn");
+ LLFloater* root_floater = gFloaterView->getParentFloater(this);
+ LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(boost::bind(&LLFloaterIMSession::addSessionParticipants, this, _1), TRUE, TRUE, FALSE, root_floater->getName(), button);
+ if (!picker)
+ {
+ return;
+ }
+
+ // Need to disable 'ok' button when selected users are already in conversation.
+ picker->setOkBtnEnableCb(boost::bind(&LLFloaterIMSession::canAddSelectedToChat, this, _1));
+
+ if (root_floater)
+ {
+ root_floater->addDependentFloater(picker);
+ }
+}
+
+bool LLFloaterIMSession::canAddSelectedToChat(const uuid_vec_t& uuids)
+{
+ if (!mSession
+ || mDialog == IM_SESSION_GROUP_START
+ || mDialog == IM_SESSION_INVITE && gAgent.isInGroup(mSessionID))
+ {
+ return false;
+ }
+
+ if (mIsP2PChat)
+ {
+ // For a P2P session just check if we are not adding the other participant.
+
+ for (uuid_vec_t::const_iterator id = uuids.begin();
+ id != uuids.end(); ++id)
+ {
+ if (*id == mOtherParticipantUUID)
+ {
+ return false;
+ }
+ }
+ }
+ else
+ {
+ // For a conference session we need to check against the list from LLSpeakerMgr,
+ // because this list may change when participants join or leave the session.
+
+ LLSpeakerMgr::speaker_list_t speaker_list;
+ LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID);
+ if (speaker_mgr)
+ {
+ speaker_mgr->getSpeakerList(&speaker_list, true);
+ }
+
+ for (uuid_vec_t::const_iterator id = uuids.begin();
+ id != uuids.end(); ++id)
+ {
+ for (LLSpeakerMgr::speaker_list_t::const_iterator it = speaker_list.begin();
+ it != speaker_list.end(); ++it)
+ {
+ const LLPointer<LLSpeaker>& speaker = *it;
+ if (*id == speaker->mID)
+ {
+ return false;
+ }
+ }
+ }
+ }
+
+ return true;
+}
+
+void LLFloaterIMSession::addSessionParticipants(const uuid_vec_t& uuids)
+{
+ if (mIsP2PChat)
+ {
+ LLSD payload;
+ LLSD args;
+
+ LLNotificationsUtil::add("ConfirmAddingChatParticipants", args, payload,
+ boost::bind(&LLFloaterIMSession::addP2PSessionParticipants, this, _1, _2, uuids));
+ }
+ else
+ {
+ if(findInstance(mSessionID))
+ {
+ // remember whom we have invited, to notify others later, when the invited ones actually join
+ mInvitedParticipants.insert(mInvitedParticipants.end(), uuids.begin(), uuids.end());
+ }
+
+ inviteToSession(uuids);
+ }
+}
+
+void LLFloaterIMSession::addP2PSessionParticipants(const LLSD& notification, const LLSD& response, const uuid_vec_t& uuids)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ if (option != 0)
+ {
+ return;
+ }
+
+ LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionID);
+
+ // first check whether this is a voice session
+ bool is_voice_call = voice_channel != NULL && voice_channel->isActive();
+
+ uuid_vec_t temp_ids;
+
+ // Add the initial participant of a P2P session
+ temp_ids.push_back(mOtherParticipantUUID);
+ temp_ids.insert(temp_ids.end(), uuids.begin(), uuids.end());
+
+ // then we can close the current session
+ if(findInstance(mSessionID))
+ {
+ onClose(false);
+
+ // remember whom we have invited, to notify others later, when the invited ones actually join
+ mInvitedParticipants.insert(mInvitedParticipants.end(), uuids.begin(), uuids.end());
+ }
+
+ // we start a new session so reset the initialization flag
+ mSessionInitialized = false;
+
+
+
+ // Start a new ad hoc voice call if we invite new participants to a P2P call,
+ // or start a text chat otherwise.
+ if (is_voice_call)
+ {
+ LLAvatarActions::startAdhocCall(temp_ids, mSessionID);
+ }
+ else
+ {
+ LLAvatarActions::startConference(temp_ids, mSessionID);
+ }
+}
+
+void LLFloaterIMSession::sendParticipantsAddedNotification(const uuid_vec_t& uuids)
+{
+ std::string names_string;
+ LLAvatarActions::buildResidentsString(uuids, names_string);
+ LLStringUtil::format_map_t args;
+ args["[NAME]"] = names_string;
+
+ sendMsg(getString(uuids.size() > 1 ? "multiple_participants_added" : "participant_added", args));
+}
+
+void LLFloaterIMSession::boundVoiceChannel()
+{
+ LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionID);
+ if(voice_channel)
+ {
+ mVoiceChannelStateChangeConnection = voice_channel->setStateChangedCallback(
+ boost::bind(&LLFloaterIMSession::onVoiceChannelStateChanged, this, _1, _2));
+
+ //call (either p2p, group or ad-hoc) can be already in started state
+ bool callIsActive = voice_channel->getState() >= LLVoiceChannel::STATE_CALL_STARTED;
+ updateCallBtnState(callIsActive);
+ }
+}
+
+void LLFloaterIMSession::onCallButtonClicked()
+{
+ LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionID);
+ if (voice_channel)
+ {
+ bool is_call_active = voice_channel->getState() >= LLVoiceChannel::STATE_CALL_STARTED;
+ if (is_call_active)
+ {
+ gIMMgr->endCall(mSessionID);
+ }
+ else
+ {
+ gIMMgr->startCall(mSessionID);
+ }
+ }
+}
+
+void LLFloaterIMSession::onChange(EStatusType status, const std::string &channelURI, bool proximal)
+{
+ if(status != STATUS_JOINING && status != STATUS_LEFT_CHANNEL)
+ {
+ enableDisableCallBtn();
+ }
+}
+
+void LLFloaterIMSession::onVoiceChannelStateChanged(
+ const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state)
+{
+ bool callIsActive = new_state >= LLVoiceChannel::STATE_CALL_STARTED;
+ updateCallBtnState(callIsActive);
+}
+
+void LLFloaterIMSession::updateSessionName(const std::string& name)
+{
+ if (!name.empty())
+ {
+ LLFloaterIMSessionTab::updateSessionName(name);
+ mTypingStart.setArg("[NAME]", name);
+ setTitle (mOtherTyping ? mTypingStart.getString() : name);
+ mSessionNameUpdatedForTyping = mOtherTyping;
+ }
+}
+
+//static
+LLFloaterIMSession* LLFloaterIMSession::show(const LLUUID& session_id)
+{
+ closeHiddenIMToasts();
+
+ if (!gIMMgr->hasSession(session_id))
+ return NULL;
+
+ // Test the existence of the floater before we try to create it
+ bool exist = findInstance(session_id);
+
+ // Get the floater: this will create the instance if it didn't exist
+ LLFloaterIMSession* floater = getInstance(session_id);
+ if (!floater)
+ return NULL;
+
+ LLFloaterIMContainer* floater_container = LLFloaterIMContainer::getInstance();
+
+ // Do not add again existing floaters
+ if (!exist)
+ {
+ // LLTabContainer::eInsertionPoint i_pt = user_initiated ? LLTabContainer::RIGHT_OF_CURRENT : LLTabContainer::END;
+ // TODO: mantipov: use LLTabContainer::RIGHT_OF_CURRENT if it exists
+ LLTabContainer::eInsertionPoint i_pt = LLTabContainer::END;
+ if (floater_container)
+ {
+ floater_container->addFloater(floater, TRUE, i_pt);
+ }
+ }
+
+ floater->openFloater(floater->getKey());
+
+ floater->setVisible(TRUE);
+
+ return floater;
+}
+//static
+LLFloaterIMSession* LLFloaterIMSession::findInstance(const LLUUID& session_id)
+{
+ LLFloaterIMSession* conversation =
+ LLFloaterReg::findTypedInstance<LLFloaterIMSession>("impanel", session_id);
+
+ return conversation;
+}
+
+LLFloaterIMSession* LLFloaterIMSession::getInstance(const LLUUID& session_id)
+{
+ LLFloaterIMSession* conversation =
+ LLFloaterReg::getTypedInstance<LLFloaterIMSession>("impanel", session_id);
+
+ return conversation;
+}
+
+void LLFloaterIMSession::onClose(bool app_quitting)
+{
+ setTyping(false);
+
+ // The source of much argument and design thrashing
+ // Should the window hide or the session close when the X is clicked?
+ //
+ // Last change:
+ // EXT-3516 X Button should end IM session, _ button should hide
+ gIMMgr->leaveSession(mSessionID);
+ // *TODO: Study why we need to restore the floater before we close it.
+ // Might be because we want to save some state data in some clean open state.
+ LLFloaterIMSessionTab::restoreFloater();
+ // Clean up the conversation *after* the session has been ended
+ LLFloaterIMSessionTab::onClose(app_quitting);
+}
+
+void LLFloaterIMSession::setDocked(bool docked, bool pop_on_undock)
+{
+ // update notification channel state
+ LLNotificationsUI::LLScreenChannel* channel = static_cast<LLNotificationsUI::LLScreenChannel*>
+ (LLNotificationsUI::LLChannelManager::getInstance()->
+ findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID"))));
+
+ if(!isChatMultiTab())
+ {
+ LLTransientDockableFloater::setDocked(docked, pop_on_undock);
+ }
+
+ // update notification channel state
+ if(channel)
+ {
+ channel->updateShowToastsState();
+ channel->redrawToasts();
+ }
+}
+
+void LLFloaterIMSession::setMinimized(BOOL b)
+{
+ bool wasMinimized = isMinimized();
+ LLFloaterIMSessionTab::setMinimized(b);
+
+ //Switching from minimized state to un-minimized state
+ if(wasMinimized && !b)
+ {
+ //When in DND mode, remove stored IM notifications
+ //Nearby chat (Null) IMs are not stored while in DND mode, so can ignore removal
+ if(gAgent.isDoNotDisturb())
+ {
+ LLDoNotDisturbNotificationStorage::getInstance()->removeNotification(LLDoNotDisturbNotificationStorage::toastName, mSessionID);
+ }
+ }
+}
+
+void LLFloaterIMSession::setVisible(BOOL visible)
+{
+ LLNotificationsUI::LLScreenChannel* channel = static_cast<LLNotificationsUI::LLScreenChannel*>
+ (LLNotificationsUI::LLChannelManager::getInstance()->
+ findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID"))));
+
+ LLFloaterIMSessionTab::setVisible(visible);
+
+ // update notification channel state
+ if(channel)
+ {
+ channel->updateShowToastsState();
+ channel->redrawToasts();
+ }
+
+ if(!visible)
+ {
+ LLChicletPanel * chiclet_panelp = LLChicletBar::getInstance()->getChicletPanel();
+ if (NULL != chiclet_panelp)
+ {
+ LLIMChiclet * chicletp = chiclet_panelp->findChiclet<LLIMChiclet>(mSessionID);
+ if(NULL != chicletp)
+ {
+ chicletp->setToggleState(false);
+ }
+ }
+ }
+
+ if (visible && isInVisibleChain())
+ {
+ sIMFloaterShowedSignal(mSessionID);
+
+ }
+
+}
+
+BOOL LLFloaterIMSession::getVisible()
+{
+ bool visible;
+
+ if(isChatMultiTab())
+ {
+ LLFloaterIMContainer* im_container =
+ LLFloaterIMContainer::getInstance();
+
+ // Treat inactive floater as invisible.
+ bool is_active = im_container->getActiveFloater() == this;
+
+ //torn off floater is always inactive
+ if (!is_active && getHost() != im_container)
+ {
+ visible = LLTransientDockableFloater::getVisible();
+ }
+ else
+ {
+ // getVisible() returns TRUE when Tabbed IM window is minimized.
+ visible = is_active && !im_container->isMinimized()
+ && im_container->getVisible();
+ }
+ }
+ else
+ {
+ visible = LLTransientDockableFloater::getVisible();
+ }
+
+ return visible;
+}
+
+void LLFloaterIMSession::setFocus(BOOL focus)
+{
+ LLFloaterIMSessionTab::setFocus(focus);
+
+ //When in DND mode, remove stored IM notifications
+ //Nearby chat (Null) IMs are not stored while in DND mode, so can ignore removal
+ if(focus && gAgent.isDoNotDisturb())
+ {
+ LLDoNotDisturbNotificationStorage::getInstance()->removeNotification(LLDoNotDisturbNotificationStorage::toastName, mSessionID);
+ }
+}
+
+//static
+bool LLFloaterIMSession::toggle(const LLUUID& session_id)
+{
+ if(!isChatMultiTab())
+ {
+ LLFloaterIMSession* floater = LLFloaterReg::findTypedInstance<LLFloaterIMSession>(
+ "impanel", session_id);
+ if (floater && floater->getVisible() && floater->hasFocus())
+ {
+ // clicking on chiclet to close floater just hides it to maintain existing
+ // scroll/text entry state
+ floater->setVisible(false);
+ return false;
+ }
+ else if(floater && (!floater->isDocked() || floater->getVisible() && !floater->hasFocus()))
+ {
+ floater->setVisible(TRUE);
+ floater->setFocus(TRUE);
+ return true;
+ }
+ }
+
+ // ensure the list of messages is updated when floater is made visible
+ show(session_id);
+ return true;
+}
+
+void LLFloaterIMSession::sessionInitReplyReceived(const LLUUID& im_session_id)
+{
+ mSessionInitialized = true;
+
+ //will be different only for an ad-hoc im session
+ if (mSessionID != im_session_id)
+ {
+ initIMSession(im_session_id);
+ buildConversationViewParticipant();
+ }
+
+ initIMFloater();
+ LLFloaterIMSessionTab::updateGearBtn();
+ //*TODO here we should remove "starting session..." warning message if we added it in postBuild() (IB)
+
+ //need to send delayed messages collected while waiting for session initialization
+ if (mQueuedMsgsForInit.size())
+ {
+ LLSD::array_iterator iter;
+ for ( iter = mQueuedMsgsForInit.beginArray();
+ iter != mQueuedMsgsForInit.endArray(); ++iter)
+ {
+ LLIMModel::sendMessage(iter->asString(), mSessionID,
+ mOtherParticipantUUID, mDialog);
+ }
+
+ mQueuedMsgsForInit.clear();
+ }
+}
+
+void LLFloaterIMSession::updateMessages()
+{
+ std::list<LLSD> messages;
+
+ // we shouldn't reset unread message counters if IM floater doesn't have focus
+ LLIMModel::instance().getMessages(
+ mSessionID, messages, mLastMessageIndex + 1, hasFocus());
+
+ if (messages.size())
+ {
+ std::ostringstream message;
+ std::list<LLSD>::const_reverse_iterator iter = messages.rbegin();
+ std::list<LLSD>::const_reverse_iterator iter_end = messages.rend();
+ for (; iter != iter_end; ++iter)
+ {
+ LLSD msg = *iter;
+
+ std::string time = msg["time"].asString();
+ LLUUID from_id = msg["from_id"].asUUID();
+ std::string from = msg["from"].asString();
+ std::string message = msg["message"].asString();
+ bool is_history = msg["is_history"].asBoolean();
+
+ LLChat chat;
+ chat.mFromID = from_id;
+ chat.mSessionID = mSessionID;
+ chat.mFromName = from;
+ chat.mTimeStr = time;
+ chat.mChatStyle = is_history ? CHAT_STYLE_HISTORY : chat.mChatStyle;
+
+ // process offer notification
+ if (msg.has("notification_id"))
+ {
+ chat.mNotifId = msg["notification_id"].asUUID();
+ // if notification exists - embed it
+ if (LLNotificationsUtil::find(chat.mNotifId) != NULL)
+ {
+ // remove embedded notification from channel
+ LLNotificationsUI::LLScreenChannel* channel = static_cast<LLNotificationsUI::LLScreenChannel*>
+ (LLNotificationsUI::LLChannelManager::getInstance()->
+ findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID"))));
+ if (getVisible())
+ {
+ // toast will be automatically closed since it is not storable toast
+ channel->hideToast(chat.mNotifId);
+ }
+ }
+ // if notification doesn't exist - try to use next message which should be log entry
+ else
+ {
+ continue;
+ }
+ }
+ //process text message
+ else
+ {
+ chat.mText = message;
+ }
+
+ // Add the message to the chat log
+ appendMessage(chat);
+ mLastMessageIndex = msg["index"].asInteger();
+
+ // if it is a notification - next message is a notification history log, so skip it
+ if (chat.mNotifId.notNull() && LLNotificationsUtil::find(chat.mNotifId) != NULL)
+ {
+ if (++iter == iter_end)
+ {
+ break;
+ }
+ else
+ {
+ mLastMessageIndex++;
+ }
+ }
+ }
+ }
+}
+
+void LLFloaterIMSession::reloadMessages(bool clean_messages/* = false*/)
+{
+ if (clean_messages)
+ {
+ LLIMModel::LLIMSession * sessionp = LLIMModel::instance().findIMSession(mSessionID);
+
+ if (NULL != sessionp)
+ {
+ sessionp->loadHistory();
+ }
+ }
+
+ mChatHistory->clear();
+ mLastMessageIndex = -1;
+ updateMessages();
+ mInputEditor->setFont(LLViewerChat::getChatFont());
+}
+
+// static
+void LLFloaterIMSession::onInputEditorFocusReceived( LLFocusableElement* caller, void* userdata )
+{
+ LLFloaterIMSession* self= (LLFloaterIMSession*) userdata;
+
+ // Allow enabling the LLFloaterIMSession input editor only if session can accept text
+ LLIMModel::LLIMSession* im_session =
+ LLIMModel::instance().findIMSession(self->mSessionID);
+ //TODO: While disabled lllineeditor can receive focus we need to check if it is enabled (EK)
+ if( im_session && im_session->mTextIMPossible && self->mInputEditor->getEnabled())
+ {
+ //in disconnected state IM input editor should be disabled
+ self->mInputEditor->setEnabled(!gDisconnected);
+ }
+}
+
+// static
+void LLFloaterIMSession::onInputEditorFocusLost(LLFocusableElement* caller, void* userdata)
+{
+ LLFloaterIMSession* self = (LLFloaterIMSession*) userdata;
+ self->setTyping(false);
+}
+
+// static
+void LLFloaterIMSession::onInputEditorKeystroke(LLTextEditor* caller, void* userdata)
+{
+ LLFloaterIMSession* self = (LLFloaterIMSession*)userdata;
+ LLFloaterIMContainer* im_box = LLFloaterIMContainer::findInstance();
+ if (im_box)
+ {
+ im_box->flashConversationItemWidget(self->mSessionID,false);
+ }
+ std::string text = self->mInputEditor->getText();
+
+ // Deleting all text counts as stopping typing.
+ self->setTyping(!text.empty());
+}
+
+void LLFloaterIMSession::setTyping(bool typing)
+{
+ if ( typing )
+ {
+ // Started or proceeded typing, reset the typing timeout timer
+ mTypingTimeoutTimer.reset();
+ }
+
+ if ( mMeTyping != typing )
+ {
+ // Typing state is changed
+ mMeTyping = typing;
+ // So, should send current state
+ mShouldSendTypingState = true;
+ // In case typing is started, send state after some delay
+ mTypingTimer.reset();
+ }
+
+ // Don't want to send typing indicators to multiple people, potentially too
+ // much network traffic. Only send in person-to-person IMs.
+ if ( mShouldSendTypingState && mDialog == IM_NOTHING_SPECIAL )
+ {
+ // Still typing, send 'start typing' notification or
+ // send 'stop typing' notification immediately
+ if (!mMeTyping || mTypingTimer.getElapsedTimeF32() > 1.f)
+ {
+ LLIMModel::instance().sendTypingState(mSessionID,
+ mOtherParticipantUUID, mMeTyping);
+ mShouldSendTypingState = false;
+ }
+ }
+
+ if (!mIsNearbyChat)
+ {
+ LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID);
+ if (speaker_mgr)
+ {
+ speaker_mgr->setSpeakerTyping(gAgent.getID(), FALSE);
+ }
+ }
+}
+
+void LLFloaterIMSession::processIMTyping(const LLIMInfo* im_info, BOOL typing)
+{
+ if ( typing )
+ {
+ // other user started typing
+ addTypingIndicator(im_info);
+ }
+ else
+ {
+ // other user stopped typing
+ removeTypingIndicator(im_info);
+ }
+}
+
+void LLFloaterIMSession::processAgentListUpdates(const LLSD& body)
+{
+ uuid_vec_t joined_uuids;
+
+ if (body.isMap() && body.has("agent_updates") && body["agent_updates"].isMap())
+ {
+ LLSD::map_const_iterator update_it;
+ for(update_it = body["agent_updates"].beginMap();
+ update_it != body["agent_updates"].endMap();
+ ++update_it)
+ {
+ LLUUID agent_id(update_it->first);
+ LLSD agent_data = update_it->second;
+
+ if (agent_data.isMap())
+ {
+ // store the new participants in joined_uuids
+ if (agent_data.has("transition") && agent_data["transition"].asString() == "ENTER")
+ {
+ joined_uuids.push_back(agent_id);
+ }
+
+ // process the moderator mutes
+ if (agent_id == gAgentID && agent_data.has("info") && agent_data["info"].has("mutes"))
+ {
+ BOOL moderator_muted_text = agent_data["info"]["mutes"]["text"].asBoolean();
+ mInputEditor->setEnabled(!moderator_muted_text);
+ std::string label;
+ if (moderator_muted_text)
+ label = LLTrans::getString("IM_muted_text_label");
+ else
+ label = LLTrans::getString("IM_to_label") + " " + LLIMModel::instance().getName(mSessionID);
+ mInputEditor->setLabel(label);
+
+ if (moderator_muted_text)
+ LLNotificationsUtil::add("TextChatIsMutedByModerator");
+ }
+ }
+ }
+ }
+
+ // the vectors need to be sorted for computing the intersection and difference
+ std::sort(mInvitedParticipants.begin(), mInvitedParticipants.end());
+ std::sort(joined_uuids.begin(), joined_uuids.end());
+
+ uuid_vec_t intersection; // uuids of invited residents who have joined the conversation
+ std::set_intersection(mInvitedParticipants.begin(), mInvitedParticipants.end(),
+ joined_uuids.begin(), joined_uuids.end(),
+ std::back_inserter(intersection));
+
+ if (intersection.size() > 0)
+ {
+ sendParticipantsAddedNotification(intersection);
+ }
+
+ // Remove all joined participants from invited array.
+ // The difference between the two vectors (the elements in mInvitedParticipants which are not in joined_uuids)
+ // is placed at the beginning of mInvitedParticipants, then all other elements are erased.
+ mInvitedParticipants.erase(std::set_difference(mInvitedParticipants.begin(), mInvitedParticipants.end(),
+ joined_uuids.begin(), joined_uuids.end(),
+ mInvitedParticipants.begin()),
+ mInvitedParticipants.end());
+}
+
+void LLFloaterIMSession::processSessionUpdate(const LLSD& session_update)
+{
+ // *TODO : verify following code when moderated mode will be implemented
+ if ( false && session_update.has("moderated_mode") &&
+ session_update["moderated_mode"].has("voice") )
+ {
+ BOOL voice_moderated = session_update["moderated_mode"]["voice"];
+ const std::string session_label = LLIMModel::instance().getName(mSessionID);
+
+ if (voice_moderated)
+ {
+ setTitle(session_label + std::string(" ")
+ + LLTrans::getString("IM_moderated_chat_label"));
+ }
+ else
+ {
+ setTitle(session_label);
+ }
+
+ // *TODO : uncomment this when/if LLPanelActiveSpeakers panel will be added
+ //update the speakers dropdown too
+ //mSpeakerPanel->setVoiceModerationCtrlMode(voice_moderated);
+ }
+}
+
+// virtual
+void LLFloaterIMSession::draw()
+{
+ // add people who were added via dropPerson()
+ if (!mPendingParticipants.empty())
+ {
+ addSessionParticipants(mPendingParticipants);
+ mPendingParticipants.clear();
+ }
+
+ LLFloaterIMSessionTab::draw();
+}
+
+// virtual
+BOOL LLFloaterIMSession::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
+ EDragAndDropType cargo_type,
+ void* cargo_data,
+ EAcceptance* accept,
+ std::string& tooltip_msg)
+{
+ if (cargo_type == DAD_PERSON)
+ {
+ if (dropPerson(static_cast<LLUUID*>(cargo_data), drop))
+ {
+ *accept = ACCEPT_YES_MULTI;
+ }
+ else
+ {
+ *accept = ACCEPT_NO;
+ }
+ }
+ else if (mDialog == IM_NOTHING_SPECIAL)
+ {
+ LLToolDragAndDrop::handleGiveDragAndDrop(mOtherParticipantUUID, mSessionID, drop,
+ cargo_type, cargo_data, accept);
+ }
+
+ return TRUE;
+}
+
+bool LLFloaterIMSession::dropPerson(LLUUID* person_id, bool drop)
+{
+ bool res = person_id && person_id->notNull();
+ if(res)
+ {
+ uuid_vec_t ids;
+ ids.push_back(*person_id);
+
+ res = canAddSelectedToChat(ids);
+ if(res && drop)
+ {
+ // these people will be added during the next draw() call
+ // (so they can be added all at once)
+ mPendingParticipants.push_back(*person_id);
+ }
+ }
+
+ return res;
+}
+
+BOOL LLFloaterIMSession::isInviteAllowed() const
+{
+ return ( (IM_SESSION_CONFERENCE_START == mDialog)
+ || (IM_SESSION_INVITE == mDialog && !gAgent.isInGroup(mSessionID))
+ || mIsP2PChat);
+}
+
+class LLSessionInviteResponder : public LLHTTPClient::Responder
+{
+public:
+ LLSessionInviteResponder(const LLUUID& session_id)
+ {
+ mSessionID = session_id;
+ }
+
+ void errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content)
+ {
+ llwarns << "Error inviting all agents to session [status:"
+ << statusNum << "]: " << content << llendl;
+ //throw something back to the viewer here?
+ }
+
+private:
+ LLUUID mSessionID;
+};
+
+BOOL LLFloaterIMSession::inviteToSession(const uuid_vec_t& ids)
+{
+ LLViewerRegion* region = gAgent.getRegion();
+ bool is_region_exist = region != NULL;
+
+ if (is_region_exist)
+ {
+ S32 count = ids.size();
+
+ if( isInviteAllowed() && (count > 0) )
+ {
+ llinfos << "LLFloaterIMSession::inviteToSession() - inviting participants" << llendl;
+
+ std::string url = region->getCapability("ChatSessionRequest");
+
+ LLSD data;
+ data["params"] = LLSD::emptyArray();
+ for (int i = 0; i < count; i++)
+ {
+ data["params"].append(ids[i]);
+ }
+ data["method"] = "invite";
+ data["session-id"] = mSessionID;
+ LLHTTPClient::post(url, data,new LLSessionInviteResponder(mSessionID));
+ }
+ else
+ {
+ llinfos << "LLFloaterIMSession::inviteToSession -"
+ << " no need to invite agents for "
+ << mDialog << llendl;
+ // successful add, because everyone that needed to get added
+ // was added.
+ }
+ }
+
+ return is_region_exist;
+}
+
+void LLFloaterIMSession::addTypingIndicator(const LLIMInfo* im_info)
+{
+ // We may have lost a "stop-typing" packet, don't add it twice
+ if (im_info && !mOtherTyping)
+ {
+ mOtherTyping = true;
+
+ // Update speaker
+ LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID);
+ if ( speaker_mgr )
+ {
+ speaker_mgr->setSpeakerTyping(im_info->mFromID, TRUE);
+ }
+ }
+}
+
+void LLFloaterIMSession::removeTypingIndicator(const LLIMInfo* im_info)
+{
+ if (mOtherTyping)
+ {
+ mOtherTyping = false;
+
+ if (im_info)
+ {
+ // Update speaker
+ LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID);
+ if (speaker_mgr)
+ {
+ speaker_mgr->setSpeakerTyping(im_info->mFromID, FALSE);
+ }
+ }
+ }
+}
+
+// static
+void LLFloaterIMSession::closeHiddenIMToasts()
+{
+ class IMToastMatcher: public LLNotificationsUI::LLScreenChannel::Matcher
+ {
+ public:
+ bool matches(const LLNotificationPtr notification) const
+ {
+ // "notifytoast" type of notifications is reserved for IM notifications
+ return "notifytoast" == notification->getType();
+ }
+ };
+
+ LLNotificationsUI::LLScreenChannel* channel =
+ LLNotificationsUI::LLChannelManager::getNotificationScreenChannel();
+ if (channel != NULL)
+ {
+ channel->closeHiddenToasts(IMToastMatcher());
+ }
+}
+// static
+void LLFloaterIMSession::confirmLeaveCallCallback(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ const LLSD& payload = notification["payload"];
+ LLUUID session_id = payload["session_id"];
+
+ LLFloater* im_floater = findInstance(session_id);
+ if (option == 0 && im_floater != NULL)
+ {
+ im_floater->closeFloater();
+ }
+
+ return;
+}
+
+// static
+void LLFloaterIMSession::sRemoveTypingIndicator(const LLSD& data)
+{
+ LLUUID session_id = data["session_id"];
+ if (session_id.isNull())
+ return;
+
+ LLUUID from_id = data["from_id"];
+ if (gAgentID == from_id || LLUUID::null == from_id)
+ return;
+
+ LLFloaterIMSession* floater = LLFloaterIMSession::findInstance(session_id);
+ if (!floater)
+ return;
+
+ if (IM_NOTHING_SPECIAL != floater->mDialog)
+ return;
+
+ floater->removeTypingIndicator();
+}
+
+// static
+void LLFloaterIMSession::onIMChicletCreated( const LLUUID& session_id )
+{
+ LLFloaterIMSession::addToHost(session_id);
+}
+
+boost::signals2::connection LLFloaterIMSession::setIMFloaterShowedCallback(const floater_showed_signal_t::slot_type& cb)
+{
+ return LLFloaterIMSession::sIMFloaterShowedSignal.connect(cb);
+}
diff --git a/indra/newview/llfloaterimsession.h b/indra/newview/llfloaterimsession.h
new file mode 100755
index 0000000000..d6718843ca
--- /dev/null
+++ b/indra/newview/llfloaterimsession.h
@@ -0,0 +1,201 @@
+/**
+ * @file llfloaterimsession.h
+ * @brief LLFloaterIMSession class definition
+ *
+ * $LicenseInfo:firstyear=2009&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$
+ */
+
+#ifndef LL_FLOATERIMSESSION_H
+#define LL_FLOATERIMSESSION_H
+
+#include "llimview.h"
+#include "llfloaterimsessiontab.h"
+#include "llinstantmessage.h"
+#include "lllogchat.h"
+#include "lltooldraganddrop.h"
+#include "llvoicechannel.h"
+#include "llvoiceclient.h"
+
+class LLAvatarName;
+class LLButton;
+class LLChatEntry;
+class LLTextEditor;
+class LLPanelChatControlPanel;
+class LLChatHistory;
+class LLInventoryItem;
+class LLInventoryCategory;
+
+typedef boost::signals2::signal<void(const LLUUID& session_id)> floater_showed_signal_t;
+
+/**
+ * Individual IM window that appears at the bottom of the screen,
+ * optionally "docked" to the bottom tray.
+ */
+class LLFloaterIMSession
+ : public LLVoiceClientStatusObserver
+ , public LLFloaterIMSessionTab
+{
+ LOG_CLASS(LLFloaterIMSession);
+public:
+ LLFloaterIMSession(const LLUUID& session_id);
+
+ virtual ~LLFloaterIMSession();
+
+ void initIMSession(const LLUUID& session_id);
+ void initIMFloater();
+
+ // LLView overrides
+ /*virtual*/ BOOL postBuild();
+ /*virtual*/ void setMinimized(BOOL b);
+ /*virtual*/ void setVisible(BOOL visible);
+ /*virtual*/ BOOL getVisible();
+ /*virtual*/ void setFocus(BOOL focus);
+ // Check typing timeout timer.
+
+ /*virtual*/ void draw();
+ /*virtual*/ BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
+ EDragAndDropType cargo_type,
+ void* cargo_data,
+ EAcceptance* accept,
+ std::string& tooltip_msg);
+
+ static LLFloaterIMSession* findInstance(const LLUUID& session_id);
+ static LLFloaterIMSession* getInstance(const LLUUID& session_id);
+
+ // LLFloater overrides
+ /*virtual*/ void onClose(bool app_quitting);
+ /*virtual*/ void setDocked(bool docked, bool pop_on_undock = true);
+ // Make IM conversion visible and update the message history
+ static LLFloaterIMSession* show(const LLUUID& session_id);
+
+ // Toggle panel specified by session_id
+ // Returns true iff panel became visible
+ static bool toggle(const LLUUID& session_id);
+
+ void sessionInitReplyReceived(const LLUUID& im_session_id);
+
+ // get new messages from LLIMModel
+ /*virtual*/ void updateMessages();
+ void reloadMessages(bool clean_messages = false);
+ static void onSendMsg(LLUICtrl*, void*);
+ void sendMsgFromInputEditor();
+ void sendMsg(const std::string& msg);
+
+ // callback for LLIMModel on new messages
+ // route to specific floater if it is visible
+ static void newIMCallback(const LLSD& data);
+
+ // called when docked floater's position has been set by chiclet
+ void setPositioned(bool b) { mPositioned = b; };
+
+ void onVisibilityChange(const LLSD& new_visibility);
+ bool enableGearMenuItem(const LLSD& userdata);
+ void GearDoToSelected(const LLSD& userdata);
+ bool checkGearMenuItem(const LLSD& userdata);
+
+ // Implements LLVoiceClientStatusObserver::onChange() to enable the call
+ // button when voice is available
+ void onChange(EStatusType status, const std::string &channelURI,
+ bool proximal);
+
+ virtual LLTransientFloaterMgr::ETransientGroup getGroup() { return LLTransientFloaterMgr::IM; }
+ virtual void onVoiceChannelStateChanged(
+ const LLVoiceChannel::EState& old_state,
+ const LLVoiceChannel::EState& new_state);
+
+ void processIMTyping(const LLIMInfo* im_info, BOOL typing);
+ void processAgentListUpdates(const LLSD& body);
+ void processSessionUpdate(const LLSD& session_update);
+
+ //used as a callback on receiving new IM message
+ static void sRemoveTypingIndicator(const LLSD& data);
+ static void onIMChicletCreated(const LLUUID& session_id);
+ const LLUUID& getOtherParticipantUUID() {return mOtherParticipantUUID;}
+
+ static boost::signals2::connection setIMFloaterShowedCallback(const floater_showed_signal_t::slot_type& cb);
+ static floater_showed_signal_t sIMFloaterShowedSignal;
+
+ bool needsTitleOverwrite() { return mSessionNameUpdatedForTyping && mOtherTyping; }
+ S32 getLastChatMessageIndex() {return mLastMessageIndex;}
+private:
+
+ /*virtual*/ void refresh();
+
+ /*virtual*/ void onTearOffClicked();
+ /*virtual*/ void onClickCloseBtn(bool app_qutting);
+
+ // Update the window title and input field help text
+ /*virtual*/ void updateSessionName(const std::string& name);
+
+ bool dropPerson(LLUUID* person_id, bool drop);
+
+ BOOL isInviteAllowed() const;
+ BOOL inviteToSession(const uuid_vec_t& agent_ids);
+ static void onInputEditorFocusReceived( LLFocusableElement* caller,void* userdata );
+ static void onInputEditorFocusLost(LLFocusableElement* caller, void* userdata);
+ static void onInputEditorKeystroke(LLTextEditor* caller, void* userdata);
+ void setTyping(bool typing);
+ void onAddButtonClicked();
+ void addSessionParticipants(const uuid_vec_t& uuids);
+ void addP2PSessionParticipants(const LLSD& notification, const LLSD& response, const uuid_vec_t& uuids);
+ void sendParticipantsAddedNotification(const uuid_vec_t& uuids);
+ bool canAddSelectedToChat(const uuid_vec_t& uuids);
+
+ void onCallButtonClicked();
+
+ void boundVoiceChannel();
+
+ // Add the "User is typing..." indicator.
+ void addTypingIndicator(const LLIMInfo* im_info);
+
+ // Remove the "User is typing..." indicator.
+ void removeTypingIndicator(const LLIMInfo* im_info = NULL);
+
+ static void closeHiddenIMToasts();
+
+ static void confirmLeaveCallCallback(const LLSD& notification, const LLSD& response);
+
+ S32 mLastMessageIndex;
+
+ EInstantMessage mDialog;
+ LLUUID mOtherParticipantUUID;
+ bool mPositioned;
+
+ LLUIString mTypingStart;
+ bool mMeTyping;
+ bool mOtherTyping;
+ bool mShouldSendTypingState;
+ LLFrameTimer mTypingTimer;
+ LLFrameTimer mTypingTimeoutTimer;
+ bool mSessionNameUpdatedForTyping;
+
+ bool mSessionInitialized;
+ LLSD mQueuedMsgsForInit;
+
+ uuid_vec_t mInvitedParticipants;
+ uuid_vec_t mPendingParticipants;
+
+ // connection to voice channel state change signal
+ boost::signals2::connection mVoiceChannelStateChangeConnection;
+};
+
+#endif // LL_FLOATERIMSESSION_H
diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
new file mode 100755
index 0000000000..0ccfdb9a7b
--- /dev/null
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -0,0 +1,1115 @@
+/**
+ * @file llfloaterimsessiontab.cpp
+ * @brief LLFloaterIMSessionTab class implements the common behavior of LNearbyChatBar
+ * @brief and LLFloaterIMSession for hosting both in LLIMContainer
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 "llfloaterimsessiontab.h"
+
+#include "llagent.h"
+#include "llagentcamera.h"
+#include "llavataractions.h"
+#include "llchatentry.h"
+#include "llchathistory.h"
+#include "llchiclet.h"
+#include "llchicletbar.h"
+#include "lldraghandle.h"
+#include "llfloaterreg.h"
+#include "llfloaterimsession.h"
+#include "llfloaterimcontainer.h" // to replace separate IM Floaters with multifloater container
+#include "lllayoutstack.h"
+#include "lltoolbarview.h"
+#include "llfloaterimnearbychat.h"
+
+const F32 REFRESH_INTERVAL = 1.0f;
+
+LLFloaterIMSessionTab::LLFloaterIMSessionTab(const LLSD& session_id)
+ : LLTransientDockableFloater(NULL, true, session_id)
+ , mIsP2PChat(false)
+ , mExpandCollapseBtn(NULL)
+ , mTearOffBtn(NULL)
+ , mCloseBtn(NULL)
+ , mSessionID(session_id.asUUID())
+ , mConversationsRoot(NULL)
+ , mScroller(NULL)
+ , mChatHistory(NULL)
+ , mInputEditor(NULL)
+ , mInputEditorPad(0)
+ , mRefreshTimer(new LLTimer())
+ , mIsHostAttached(false)
+ , mHasVisibleBeenInitialized(false)
+ , mIsParticipantListExpanded(true)
+ , mChatLayoutPanel(NULL)
+ , mInputPanels(NULL)
+ , mChatLayoutPanelHeight(0)
+{
+ setAutoFocus(FALSE);
+ mSession = LLIMModel::getInstance()->findIMSession(mSessionID);
+
+ mCommitCallbackRegistrar.add("IMSession.Menu.Action",
+ boost::bind(&LLFloaterIMSessionTab::onIMSessionMenuItemClicked, this, _2));
+ mEnableCallbackRegistrar.add("IMSession.Menu.CompactExpandedModes.CheckItem",
+ boost::bind(&LLFloaterIMSessionTab::onIMCompactExpandedMenuItemCheck, this, _2));
+ mEnableCallbackRegistrar.add("IMSession.Menu.ShowModes.CheckItem",
+ boost::bind(&LLFloaterIMSessionTab::onIMShowModesMenuItemCheck, this, _2));
+ mEnableCallbackRegistrar.add("IMSession.Menu.ShowModes.Enable",
+ boost::bind(&LLFloaterIMSessionTab::onIMShowModesMenuItemEnable, this, _2));
+
+ // Right click menu handling
+ mEnableCallbackRegistrar.add("Avatar.CheckItem", boost::bind(&LLFloaterIMSessionTab::checkContextMenuItem, this, _2));
+ mEnableCallbackRegistrar.add("Avatar.EnableItem", boost::bind(&LLFloaterIMSessionTab::enableContextMenuItem, this, _2));
+ mCommitCallbackRegistrar.add("Avatar.DoToSelected", boost::bind(&LLFloaterIMSessionTab::doToSelected, this, _2));
+}
+
+LLFloaterIMSessionTab::~LLFloaterIMSessionTab()
+{
+ delete mRefreshTimer;
+}
+
+//static
+LLFloaterIMSessionTab* LLFloaterIMSessionTab::findConversation(const LLUUID& uuid)
+{
+ LLFloaterIMSessionTab* conv;
+
+ if (uuid.isNull())
+ {
+ conv = LLFloaterReg::findTypedInstance<LLFloaterIMSessionTab>("nearby_chat");
+ }
+ else
+ {
+ conv = LLFloaterReg::findTypedInstance<LLFloaterIMSessionTab>("impanel", LLSD(uuid));
+ }
+
+ return conv;
+};
+
+//static
+LLFloaterIMSessionTab* LLFloaterIMSessionTab::getConversation(const LLUUID& uuid)
+{
+ LLFloaterIMSessionTab* conv;
+
+ if (uuid.isNull())
+ {
+ conv = LLFloaterReg::getTypedInstance<LLFloaterIMSessionTab>("nearby_chat");
+ }
+ else
+ {
+ conv = LLFloaterReg::getTypedInstance<LLFloaterIMSessionTab>("impanel", LLSD(uuid));
+ }
+
+ return conv;
+};
+
+void LLFloaterIMSessionTab::setVisible(BOOL visible)
+{
+ if(visible && !mHasVisibleBeenInitialized)
+ {
+ mHasVisibleBeenInitialized = true;
+ if(!gAgentCamera.cameraMouselook())
+ {
+ LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container")->setVisible(true);
+ }
+ LLFloaterIMSessionTab::addToHost(mSessionID);
+ LLFloaterIMSessionTab* conversp = LLFloaterIMSessionTab::getConversation(mSessionID);
+
+ if (conversp && conversp->isNearbyChat() && gSavedPerAccountSettings.getBOOL("NearbyChatIsNotCollapsed"))
+ {
+ onCollapseToLine(this);
+ }
+ mInputButtonPanel->setVisible(isTornOff());
+ }
+
+ LLTransientDockableFloater::setVisible(visible);
+}
+
+/*virtual*/
+void LLFloaterIMSessionTab::setFocus(BOOL focus)
+{
+ LLTransientDockableFloater::setFocus(focus);
+
+ //Redirect focus to input editor
+ if (focus)
+ {
+ updateMessages();
+
+ if (mInputEditor)
+ {
+ mInputEditor->setFocus(TRUE);
+ }
+ }
+}
+
+
+void LLFloaterIMSessionTab::addToHost(const LLUUID& session_id)
+{
+ if ((session_id.notNull() && !gIMMgr->hasSession(session_id))
+ || !LLFloaterIMSessionTab::isChatMultiTab())
+ {
+ return;
+ }
+
+ // Get the floater: this will create the instance if it didn't exist
+ LLFloaterIMSessionTab* conversp = LLFloaterIMSessionTab::getConversation(session_id);
+ if (conversp)
+ {
+ LLFloaterIMContainer* floater_container = LLFloaterIMContainer::getInstance();
+
+ // Do not add again existing floaters
+ if (floater_container && !conversp->isHostAttached())
+ {
+ conversp->setHostAttached(true);
+
+ if (!conversp->isNearbyChat()
+ || gSavedPerAccountSettings.getBOOL("NearbyChatIsNotTornOff"))
+ {
+ floater_container->addFloater(conversp, false, LLTabContainer::RIGHT_OF_CURRENT);
+ }
+ else
+ {
+ // setting of the "potential" host for Nearby Chat: this sequence sets
+ // LLFloater::mHostHandle = NULL (a current host), but
+ // LLFloater::mLastHostHandle = floater_container (a "future" host)
+ conversp->setHost(floater_container);
+ conversp->setHost(NULL);
+
+ conversp->forceReshape();
+ }
+ // Added floaters share some state (like sort order) with their host
+ conversp->setSortOrder(floater_container->getSortOrder());
+ }
+ }
+}
+
+void LLFloaterIMSessionTab::assignResizeLimits()
+{
+ bool is_participants_pane_collapsed = mParticipantListPanel->isCollapsed();
+
+ // disable a layoutstack's functionality when participant list panel is collapsed
+ mRightPartPanel->setIgnoreReshape(is_participants_pane_collapsed);
+
+ S32 participants_pane_target_width = is_participants_pane_collapsed?
+ 0 : (mParticipantListPanel->getRect().getWidth() + mParticipantListAndHistoryStack->getPanelSpacing());
+
+ S32 new_min_width = participants_pane_target_width + mRightPartPanel->getExpandedMinDim() + mFloaterExtraWidth;
+
+ setResizeLimits(new_min_width, getMinHeight());
+
+ this->mParticipantListAndHistoryStack->updateLayout();
+}
+
+BOOL LLFloaterIMSessionTab::postBuild()
+{
+ BOOL result;
+
+ mBodyStack = getChild<LLLayoutStack>("main_stack");
+ mParticipantListAndHistoryStack = getChild<LLLayoutStack>("im_panels");
+
+ mCloseBtn = getChild<LLButton>("close_btn");
+ mCloseBtn->setCommitCallback(boost::bind(&LLFloater::onClickClose, this));
+
+ mExpandCollapseBtn = getChild<LLButton>("expand_collapse_btn");
+ mExpandCollapseBtn->setClickedCallback(boost::bind(&LLFloaterIMSessionTab::onSlide, this));
+
+ mExpandCollapseLineBtn = getChild<LLButton>("minz_btn");
+ mExpandCollapseLineBtn->setClickedCallback(boost::bind(&LLFloaterIMSessionTab::onCollapseToLine, this));
+
+ mTearOffBtn = getChild<LLButton>("tear_off_btn");
+ mTearOffBtn->setCommitCallback(boost::bind(&LLFloaterIMSessionTab::onTearOffClicked, this));
+
+ 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");
+
+ mToolbarPanel = getChild<LLLayoutPanel>("toolbar_panel");
+ mContentPanel = getChild<LLLayoutPanel>("body_panel");
+ mInputButtonPanel = getChild<LLLayoutPanel>("input_button_layout_panel");
+ mInputButtonPanel->setVisible(false);
+ // Add a scroller for the folder (participant) view
+ LLRect scroller_view_rect = mParticipantListPanel->getRect();
+ scroller_view_rect.translate(-scroller_view_rect.mLeft, -scroller_view_rect.mBottom);
+ LLScrollContainer::Params scroller_params(LLUICtrlFactory::getDefaultParams<LLFolderViewScrollContainer>());
+ scroller_params.rect(scroller_view_rect);
+ mScroller = LLUICtrlFactory::create<LLFolderViewScrollContainer>(scroller_params);
+ mScroller->setFollowsAll();
+
+ // Insert that scroller into the panel widgets hierarchy
+ mParticipantListPanel->addChild(mScroller);
+
+ mChatHistory = getChild<LLChatHistory>("chat_history");
+
+ mInputEditor = getChild<LLChatEntry>("chat_editor");
+
+ mChatLayoutPanel = getChild<LLLayoutPanel>("chat_layout_panel");
+ mInputPanels = getChild<LLLayoutStack>("input_panels");
+
+ mInputEditor->setTextExpandedCallback(boost::bind(&LLFloaterIMSessionTab::reshapeChatLayoutPanel, this));
+ mInputEditor->setMouseUpCallback(boost::bind(&LLFloaterIMSessionTab::onInputEditorClicked, this));
+ mInputEditor->setCommitOnFocusLost( FALSE );
+ mInputEditor->setPassDelete(TRUE);
+ mInputEditor->setFont(LLViewerChat::getChatFont());
+
+ mChatLayoutPanelHeight = mChatLayoutPanel->getRect().getHeight();
+ mInputEditorPad = mChatLayoutPanelHeight - mInputEditor->getRect().getHeight();
+
+ setOpenPositioning(LLFloaterEnums::POSITIONING_RELATIVE);
+
+ mSaveRect = isNearbyChat()
+ && !gSavedPerAccountSettings.getBOOL("NearbyChatIsNotTornOff");
+ initRectControl();
+
+ if (isChatMultiTab())
+ {
+ result = LLFloater::postBuild();
+ }
+ else
+ {
+ result = LLDockableFloater::postBuild();
+ }
+
+ // Create the root using an ad-hoc base item
+ LLConversationItem* base_item = new LLConversationItem(mSessionID, mConversationViewModel);
+ LLFolderView::Params p(LLUICtrlFactory::getDefaultParams<LLFolderView>());
+ p.rect = LLRect(0, 0, getRect().getWidth(), 0);
+ p.parent_panel = mParticipantListPanel;
+ p.listener = base_item;
+ p.view_model = &mConversationViewModel;
+ p.root = NULL;
+ p.use_ellipses = true;
+ p.options_menu = "menu_conversation.xml";
+ p.name = "root";
+ mConversationsRoot = LLUICtrlFactory::create<LLFolderView>(p);
+ mConversationsRoot->setCallbackRegistrar(&mCommitCallbackRegistrar);
+ // Attach that root to the scroller
+ mScroller->addChild(mConversationsRoot);
+ mConversationsRoot->setScrollContainer(mScroller);
+ mConversationsRoot->setFollowsAll();
+ mConversationsRoot->addChild(mConversationsRoot->mStatusTextBox);
+
+ setMessagePaneExpanded(true);
+
+ buildConversationViewParticipant();
+ refreshConversation();
+
+ // Zero expiry time is set only once to allow initial update.
+ mRefreshTimer->setTimerExpirySec(0);
+ mRefreshTimer->start();
+ initBtns();
+
+ if (mIsParticipantListExpanded != (bool)gSavedSettings.getBOOL("IMShowControlPanel"))
+ {
+ LLFloaterIMSessionTab::onSlide(this);
+ }
+
+ // The resize limits for LLFloaterIMSessionTab should be updated, based on current values of width of conversation and message panels
+ mParticipantListPanel->getResizeBar()->setResizeListener(boost::bind(&LLFloaterIMSessionTab::assignResizeLimits, this));
+ mFloaterExtraWidth =
+ getRect().getWidth()
+ - mParticipantListAndHistoryStack->getRect().getWidth()
+ - (mParticipantListPanel->isCollapsed()? 0 : LLPANEL_BORDER_WIDTH);
+
+ assignResizeLimits();
+
+ return result;
+}
+
+LLParticipantList* LLFloaterIMSessionTab::getParticipantList()
+{
+ return dynamic_cast<LLParticipantList*>(LLFloaterIMContainer::getInstance()->getSessionModel(mSessionID));
+}
+
+void LLFloaterIMSessionTab::draw()
+{
+ if (mRefreshTimer->hasExpired())
+ {
+ LLParticipantList* item = getParticipantList();
+ if (item)
+ {
+ // Update all model items
+ item->update();
+ // If the model and view list diverge in count, rebuild
+ // Note: this happens sometimes right around init (add participant events fire but get dropped) and is the cause
+ // of missing participants, often, the user agent itself. As there will be no other event fired, there's
+ // no other choice but get those inconsistencies regularly (and lightly) checked and scrubbed.
+ if (item->getChildrenCount() != mConversationsWidgets.size())
+ {
+ buildConversationViewParticipant();
+ }
+ refreshConversation();
+ }
+
+ // Restart the refresh timer
+ mRefreshTimer->setTimerExpirySec(REFRESH_INTERVAL);
+ }
+
+ LLTransientDockableFloater::draw();
+}
+
+void LLFloaterIMSessionTab::enableDisableCallBtn()
+{
+ mVoiceButton->setEnabled(
+ mSessionID.notNull()
+ && mSession
+ && mSession->mSessionInitialized
+ && LLVoiceClient::getInstance()->voiceEnabled()
+ && LLVoiceClient::getInstance()->isVoiceWorking()
+ && mSession->mCallBackEnabled);
+}
+
+void LLFloaterIMSessionTab::onFocusReceived()
+{
+ setBackgroundOpaque(true);
+
+ if (mSessionID.notNull() && isInVisibleChain())
+ {
+ LLIMModel::instance().sendNoUnreadMessages(mSessionID);
+ }
+
+ LLTransientDockableFloater::onFocusReceived();
+}
+
+void LLFloaterIMSessionTab::onFocusLost()
+{
+ setBackgroundOpaque(false);
+ LLTransientDockableFloater::onFocusLost();
+}
+
+void LLFloaterIMSessionTab::onInputEditorClicked()
+{
+ LLFloaterIMContainer* im_box = LLFloaterIMContainer::findInstance();
+ if (im_box)
+ {
+ im_box->flashConversationItemWidget(mSessionID,false);
+ }
+ gToolBarView->flashCommand(LLCommandId("chat"), false);
+}
+
+std::string LLFloaterIMSessionTab::appendTime()
+{
+ time_t utc_time;
+ utc_time = time_corrected();
+ std::string timeStr ="["+ LLTrans::getString("TimeHour")+"]:["
+ +LLTrans::getString("TimeMin")+"]";
+
+ LLSD substitution;
+
+ substitution["datetime"] = (S32) utc_time;
+ LLStringUtil::format (timeStr, substitution);
+
+ return timeStr;
+}
+
+void LLFloaterIMSessionTab::appendMessage(const LLChat& chat, const LLSD &args)
+{
+
+ // Update the participant activity time
+ LLFloaterIMContainer* im_box = LLFloaterIMContainer::findInstance();
+ if (im_box)
+ {
+ im_box->setTimeNow(mSessionID,chat.mFromID);
+ }
+
+
+ LLChat& tmp_chat = const_cast<LLChat&>(chat);
+
+ if(tmp_chat.mTimeStr.empty())
+ tmp_chat.mTimeStr = appendTime();
+
+ if (!chat.mMuted)
+ {
+ tmp_chat.mFromName = chat.mFromName;
+ LLSD chat_args;
+ if (args) chat_args = args;
+ chat_args["use_plain_text_chat_history"] =
+ gSavedSettings.getBOOL("PlainTextChatHistory");
+ chat_args["show_time"] = gSavedSettings.getBOOL("IMShowTime");
+ chat_args["show_names_for_p2p_conv"] =
+ !mIsP2PChat || gSavedSettings.getBOOL("IMShowNamesForP2PConv");
+
+ if (mChatHistory)
+ {
+ mChatHistory->appendMessage(chat, chat_args);
+ }
+ }
+}
+
+
+void LLFloaterIMSessionTab::buildConversationViewParticipant()
+{
+ // Clear the widget list since we are rebuilding afresh from the model
+ conversations_widgets_map::iterator widget_it = mConversationsWidgets.begin();
+ while (widget_it != mConversationsWidgets.end())
+ {
+ removeConversationViewParticipant(widget_it->first);
+ // Iterators are invalidated by erase so we need to pick begin again
+ widget_it = mConversationsWidgets.begin();
+ }
+
+ // Get the model list
+ LLParticipantList* item = getParticipantList();
+ if (!item)
+ {
+ // Nothing to do if the model list is inexistent
+ return;
+ }
+
+ // Create the participants widgets now
+ LLFolderViewModelItemCommon::child_list_t::const_iterator current_participant_model = item->getChildrenBegin();
+ LLFolderViewModelItemCommon::child_list_t::const_iterator end_participant_model = item->getChildrenEnd();
+ while (current_participant_model != end_participant_model)
+ {
+ LLConversationItem* participant_model = dynamic_cast<LLConversationItem*>(*current_participant_model);
+ addConversationViewParticipant(participant_model);
+ current_participant_model++;
+ }
+}
+
+void LLFloaterIMSessionTab::addConversationViewParticipant(LLConversationItem* participant_model)
+{
+ // Check if the model already has an associated view
+ LLUUID uuid = participant_model->getUUID();
+ LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,uuid);
+
+ // If not already present, create the participant view and attach it to the root, otherwise, just refresh it
+ if (widget)
+ {
+ updateConversationViewParticipant(uuid); // overkill?
+ }
+ else
+ {
+ LLConversationViewParticipant* participant_view = createConversationViewParticipant(participant_model);
+ mConversationsWidgets[uuid] = participant_view;
+ participant_view->addToFolder(mConversationsRoot);
+ participant_view->addToSession(mSessionID);
+ participant_view->setVisible(TRUE);
+ }
+}
+
+void LLFloaterIMSessionTab::removeConversationViewParticipant(const LLUUID& participant_id)
+{
+ LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,participant_id);
+ if (widget)
+ {
+ mConversationsRoot->extractItem(widget);
+ delete widget;
+ mConversationsWidgets.erase(participant_id);
+ }
+}
+
+void LLFloaterIMSessionTab::updateConversationViewParticipant(const LLUUID& participant_id)
+{
+ LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,participant_id);
+ if (widget)
+ {
+ widget->refresh();
+ }
+}
+
+void LLFloaterIMSessionTab::refreshConversation()
+{
+ // Note: We collect participants names to change the session name only in the case of ad-hoc conversations
+ bool is_ad_hoc = (mSession ? mSession->isAdHocSessionType() : false);
+ uuid_vec_t participants_uuids; // uuids vector for building the added participants name string
+ // For P2P chat, we still need to update the session name who may have changed (switch display name for instance)
+ if (mIsP2PChat && mSession)
+ {
+ participants_uuids.push_back(mSession->mOtherParticipantID);
+ }
+
+ conversations_widgets_map::iterator widget_it = mConversationsWidgets.begin();
+ while (widget_it != mConversationsWidgets.end())
+ {
+ // Add the participant to the list except if it's the agent itself (redundant)
+ if (is_ad_hoc && (widget_it->first != gAgentID))
+ {
+ participants_uuids.push_back(widget_it->first);
+ }
+ widget_it->second->refresh();
+ widget_it->second->setVisible(TRUE);
+ ++widget_it;
+ }
+ if (is_ad_hoc || mIsP2PChat)
+ {
+ // Build the session name and update it
+ std::string session_name;
+ if (participants_uuids.size() != 0)
+ {
+ LLAvatarActions::buildResidentsString(participants_uuids, session_name);
+ }
+ else
+ {
+ session_name = LLIMModel::instance().getName(mSessionID);
+ }
+ updateSessionName(session_name);
+ }
+
+ if (mSessionID.notNull())
+ {
+ LLParticipantList* participant_list = getParticipantList();
+ if (participant_list)
+ {
+ LLFolderViewModelItemCommon::child_list_t::const_iterator current_participant_model = participant_list->getChildrenBegin();
+ LLFolderViewModelItemCommon::child_list_t::const_iterator end_participant_model = participant_list->getChildrenEnd();
+ LLIMSpeakerMgr *speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID);
+ while (current_participant_model != end_participant_model)
+ {
+ LLConversationItemParticipant* participant_model = dynamic_cast<LLConversationItemParticipant*>(*current_participant_model);
+ if (speaker_mgr && participant_model)
+ {
+ LLSpeaker *participant_speaker = speaker_mgr->findSpeaker(participant_model->getUUID());
+ LLSpeaker *agent_speaker = speaker_mgr->findSpeaker(gAgentID);
+ if (participant_speaker && agent_speaker)
+ {
+ participant_model->setDisplayModeratorRole(agent_speaker->mIsModerator && participant_speaker->mIsModerator);
+ }
+ }
+ current_participant_model++;
+ }
+ }
+ }
+
+ mConversationViewModel.requestSortAll();
+ if(mConversationsRoot != NULL)
+ {
+ mConversationsRoot->arrangeAll();
+ mConversationsRoot->update();
+ }
+ updateHeaderAndToolbar();
+ refresh();
+}
+
+// Copied from LLFloaterIMContainer::createConversationViewParticipant(). Refactor opportunity!
+LLConversationViewParticipant* LLFloaterIMSessionTab::createConversationViewParticipant(LLConversationItem* item)
+{
+ LLRect panel_rect = mParticipantListPanel->getRect();
+
+ LLConversationViewParticipant::Params params;
+ params.name = item->getDisplayName();
+ params.root = mConversationsRoot;
+ params.listener = item;
+ params.rect = LLRect (0, 24, panel_rect.getWidth(), 0); // *TODO: use conversation_view_participant.xml itemHeight value in lieu of 24
+ params.tool_tip = params.name;
+ params.participant_id = item->getUUID();
+
+ return LLUICtrlFactory::create<LLConversationViewParticipant>(params);
+}
+
+void LLFloaterIMSessionTab::setSortOrder(const LLConversationSort& order)
+{
+ mConversationViewModel.setSorter(order);
+ mConversationsRoot->arrangeAll();
+ refreshConversation();
+}
+
+void LLFloaterIMSessionTab::onIMSessionMenuItemClicked(const LLSD& userdata)
+{
+ std::string item = userdata.asString();
+
+ if (item == "compact_view" || item == "expanded_view")
+ {
+ gSavedSettings.setBOOL("PlainTextChatHistory", item == "compact_view");
+ }
+ else
+ {
+ bool prev_value = gSavedSettings.getBOOL(item);
+ gSavedSettings.setBOOL(item, !prev_value);
+ }
+
+ LLFloaterIMSessionTab::processChatHistoryStyleUpdate();
+}
+
+bool LLFloaterIMSessionTab::onIMCompactExpandedMenuItemCheck(const LLSD& userdata)
+{
+ std::string item = userdata.asString();
+ bool is_plain_text_mode = gSavedSettings.getBOOL("PlainTextChatHistory");
+
+ return is_plain_text_mode? item == "compact_view" : item == "expanded_view";
+}
+
+
+bool LLFloaterIMSessionTab::onIMShowModesMenuItemCheck(const LLSD& userdata)
+{
+ return gSavedSettings.getBOOL(userdata.asString());
+}
+
+// enable/disable states for the "show time" and "show names" items of the show-modes menu
+bool LLFloaterIMSessionTab::onIMShowModesMenuItemEnable(const LLSD& userdata)
+{
+ std::string item = userdata.asString();
+ bool plain_text = gSavedSettings.getBOOL("PlainTextChatHistory");
+ bool is_not_names = (item != "IMShowNamesForP2PConv");
+ return (plain_text && (is_not_names || mIsP2PChat));
+}
+
+void LLFloaterIMSessionTab::hideOrShowTitle()
+{
+ const LLFloater::Params& default_params = LLFloater::getDefaultParams();
+ S32 floater_header_size = default_params.header_height;
+ LLView* floater_contents = getChild<LLView>("contents_view");
+
+ LLRect floater_rect = getLocalRect();
+ S32 top_border_of_contents = floater_rect.mTop - (isTornOff()? floater_header_size : 0);
+ LLRect handle_rect (0, floater_rect.mTop, floater_rect.mRight, top_border_of_contents);
+ LLRect contents_rect (0, top_border_of_contents, floater_rect.mRight, floater_rect.mBottom);
+ mDragHandle->setShape(handle_rect);
+ mDragHandle->setVisible(isTornOff());
+ floater_contents->setShape(contents_rect);
+}
+
+void LLFloaterIMSessionTab::updateSessionName(const std::string& name)
+{
+ mInputEditor->setLabel(LLTrans::getString("IM_to_label") + " " + name);
+}
+
+void LLFloaterIMSessionTab::hideAllStandardButtons()
+{
+ for (S32 i = 0; i < BUTTON_COUNT; i++)
+ {
+ if (mButtons[i])
+ {
+ // Hide the standard header buttons in a docked IM floater.
+ mButtons[i]->setVisible(false);
+ }
+ }
+}
+
+void LLFloaterIMSessionTab::updateHeaderAndToolbar()
+{
+ // prevent start conversation before its container
+ LLFloaterIMContainer::getInstance();
+
+ bool is_not_torn_off = !checkIfTornOff();
+ if (is_not_torn_off)
+ {
+ hideAllStandardButtons();
+ }
+
+ hideOrShowTitle();
+
+ // Participant list should be visible only in torn off floaters.
+ bool is_participant_list_visible =
+ !is_not_torn_off
+ && mIsParticipantListExpanded
+ && !mIsP2PChat;
+
+ mParticipantListAndHistoryStack->collapsePanel(mParticipantListPanel, !is_participant_list_visible);
+ mParticipantListPanel->setVisible(is_participant_list_visible);
+
+ // Display collapse image (<<) if the floater is hosted
+ // or if it is torn off but has an open control panel.
+ bool is_expanded = is_not_torn_off || is_participant_list_visible;
+
+ mExpandCollapseBtn->setImageOverlay(getString(is_expanded ? "collapse_icon" : "expand_icon"));
+ mExpandCollapseBtn->setToolTip(
+ is_not_torn_off?
+ getString("expcol_button_not_tearoff_tooltip") :
+ (is_expanded?
+ getString("expcol_button_tearoff_and_expanded_tooltip") :
+ getString("expcol_button_tearoff_and_collapsed_tooltip")));
+
+ // toggle floater's drag handle and title visibility
+ if (mDragHandle)
+ {
+ mDragHandle->setTitleVisible(!is_not_torn_off);
+ }
+
+ // The button (>>) should be disabled for torn off P2P conversations.
+ mExpandCollapseBtn->setEnabled(is_not_torn_off || !mIsP2PChat);
+
+ mTearOffBtn->setImageOverlay(getString(is_not_torn_off? "tear_off_icon" : "return_icon"));
+ mTearOffBtn->setToolTip(getString(is_not_torn_off? "tooltip_to_separate_window" : "tooltip_to_main_window"));
+
+
+ mCloseBtn->setVisible(is_not_torn_off && !mIsNearbyChat);
+
+ enableDisableCallBtn();
+
+ showTranslationCheckbox();
+}
+
+void LLFloaterIMSessionTab::forceReshape()
+{
+ LLRect floater_rect = getRect();
+ reshape(llmax(floater_rect.getWidth(), this->getMinWidth()),
+ llmax(floater_rect.getHeight(), this->getMinHeight()),
+ true);
+}
+
+
+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*/)
+{
+ LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("impanel");
+ for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin();
+ iter != inst_list.end(); ++iter)
+ {
+ LLFloaterIMSession* floater = dynamic_cast<LLFloaterIMSession*>(*iter);
+ if (floater)
+ {
+ floater->reloadMessages(clean_messages);
+ }
+ }
+
+ LLFloaterIMNearbyChat* nearby_chat = LLFloaterReg::findTypedInstance<LLFloaterIMNearbyChat>("nearby_chat");
+ if (nearby_chat)
+ {
+ nearby_chat->reloadMessages(clean_messages);
+ }
+}
+
+// static
+void LLFloaterIMSessionTab::reloadEmptyFloaters()
+{
+ LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("impanel");
+ for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin();
+ iter != inst_list.end(); ++iter)
+ {
+ LLFloaterIMSession* floater = dynamic_cast<LLFloaterIMSession*>(*iter);
+ if (floater && floater->getLastChatMessageIndex() == -1)
+ {
+ floater->reloadMessages(true);
+ }
+ }
+
+ LLFloaterIMNearbyChat* nearby_chat = LLFloaterReg::findTypedInstance<LLFloaterIMNearbyChat>("nearby_chat");
+ if (nearby_chat && nearby_chat->getMessageArchiveLength() == 0)
+ {
+ nearby_chat->reloadMessages(true);
+ }
+}
+
+void LLFloaterIMSessionTab::updateCallBtnState(bool callIsActive)
+{
+ mVoiceButton->setImageOverlay(callIsActive? getString("call_btn_stop") : getString("call_btn_start"));
+ mVoiceButton->setToolTip(callIsActive? getString("end_call_button_tooltip") : getString("start_call_button_tooltip"));
+
+ enableDisableCallBtn();
+}
+
+void LLFloaterIMSessionTab::onSlide(LLFloaterIMSessionTab* self)
+{
+ LLFloaterIMContainer* host_floater = dynamic_cast<LLFloaterIMContainer*>(self->getHost());
+ if (host_floater)
+ {
+ // Hide the messages pane if a floater is hosted in the Conversations
+ host_floater->collapseMessagesPane(true);
+ }
+ else ///< floater is torn off
+ {
+ if (!self->mIsP2PChat)
+ {
+ // The state must toggle the collapsed state of the panel
+ bool should_be_expanded = self->mParticipantListPanel->isCollapsed();
+
+ // Update the expand/collapse flag of the participant list panel and save it
+ gSavedSettings.setBOOL("IMShowControlPanel", should_be_expanded);
+ self->mIsParticipantListExpanded = should_be_expanded;
+
+ // Refresh for immediate feedback
+ self->refreshConversation();
+ }
+ }
+
+ self->assignResizeLimits();
+}
+
+void LLFloaterIMSessionTab::onCollapseToLine(LLFloaterIMSessionTab* self)
+{
+ LLFloaterIMContainer* host_floater = dynamic_cast<LLFloaterIMContainer*>(self->getHost());
+ if (!host_floater)
+ {
+ bool expand = self->isMessagePaneExpanded();
+ self->mExpandCollapseLineBtn->setImageOverlay(self->getString(expand ? "collapseline_icon" : "expandline_icon"));
+ self->mContentPanel->setVisible(!expand);
+ self->mToolbarPanel->setVisible(!expand);
+ self->mInputEditor->enableSingleLineMode(expand);
+ self->reshapeFloater(expand);
+ self->setMessagePaneExpanded(!expand);
+ }
+}
+
+void LLFloaterIMSessionTab::reshapeFloater(bool collapse)
+{
+ LLRect floater_rect = getRect();
+
+ if(collapse)
+ {
+ mFloaterHeight = floater_rect.getHeight();
+ S32 height = mContentPanel->getRect().getHeight() + mToolbarPanel->getRect().getHeight()
+ + mChatLayoutPanel->getRect().getHeight() - mChatLayoutPanelHeight + 2;
+ floater_rect.mTop -= height;
+ }
+ else
+ {
+ floater_rect.mTop = floater_rect.mBottom + mFloaterHeight;
+ }
+
+ enableResizeCtrls(true, true, !collapse);
+
+ saveCollapsedState();
+ setShape(floater_rect, true);
+ mBodyStack->updateLayout();
+}
+
+void LLFloaterIMSessionTab::restoreFloater()
+{
+ if(!isMessagePaneExpanded())
+ {
+ if(isMinimized())
+ {
+ setMinimized(false);
+ }
+ mContentPanel->setVisible(true);
+ mToolbarPanel->setVisible(true);
+ LLRect floater_rect = getRect();
+ floater_rect.mTop = floater_rect.mBottom + mFloaterHeight;
+ setShape(floater_rect, true);
+ mBodyStack->updateLayout();
+ mExpandCollapseLineBtn->setImageOverlay(getString("expandline_icon"));
+ setMessagePaneExpanded(true);
+ saveCollapsedState();
+ mInputEditor->enableSingleLineMode(false);
+ enableResizeCtrls(true, true, true);
+ }
+}
+
+/*virtual*/
+void LLFloaterIMSessionTab::onOpen(const LLSD& key)
+{
+ if (!checkIfTornOff())
+ {
+ LLFloaterIMContainer* host_floater = dynamic_cast<LLFloaterIMContainer*>(getHost());
+ // Show the messages pane when opening a floater hosted in the Conversations
+ host_floater->collapseMessagesPane(false);
+ }
+
+ mInputButtonPanel->setVisible(isTornOff());
+}
+
+
+void LLFloaterIMSessionTab::onTearOffClicked()
+{
+ restoreFloater();
+ setFollows(isTornOff()? FOLLOWS_ALL : FOLLOWS_NONE);
+ mSaveRect = isTornOff();
+ initRectControl();
+ LLFloater::onClickTearOff(this);
+ LLFloaterIMContainer* container = LLFloaterReg::findTypedInstance<LLFloaterIMContainer>("im_container");
+
+ if (isTornOff())
+ {
+ container->selectAdjacentConversation(false);
+ forceReshape();
+ }
+ //Upon re-docking the torn off floater, select the corresponding conversation line item
+ else
+ {
+ container->selectConversation(mSessionID);
+
+ }
+ mInputButtonPanel->setVisible(isTornOff());
+
+ refreshConversation();
+ updateGearBtn();
+}
+
+void LLFloaterIMSessionTab::updateGearBtn()
+{
+
+ BOOL prevVisibility = mGearBtn->getVisible();
+ mGearBtn->setVisible(checkIfTornOff() && mIsP2PChat);
+
+
+ // Move buttons if Gear button changed visibility
+ if(prevVisibility != mGearBtn->getVisible())
+ {
+ LLRect gear_btn_rect = mGearBtn->getRect();
+ LLRect add_btn_rect = mAddBtn->getRect();
+ LLRect call_btn_rect = mVoiceButton->getRect();
+ S32 gap_width = call_btn_rect.mLeft - add_btn_rect.mRight;
+ S32 right_shift = gear_btn_rect.getWidth() + gap_width;
+ if(mGearBtn->getVisible())
+ {
+ // Move buttons to the right to give space for Gear button
+ add_btn_rect.translate(right_shift,0);
+ call_btn_rect.translate(right_shift,0);
+ }
+ else
+ {
+ add_btn_rect.translate(-right_shift,0);
+ call_btn_rect.translate(-right_shift,0);
+ }
+ mAddBtn->setRect(add_btn_rect);
+ mVoiceButton->setRect(call_btn_rect);
+ }
+}
+
+void LLFloaterIMSessionTab::initBtns()
+{
+ LLRect gear_btn_rect = mGearBtn->getRect();
+ LLRect add_btn_rect = mAddBtn->getRect();
+ LLRect call_btn_rect = mVoiceButton->getRect();
+ S32 gap_width = call_btn_rect.mLeft - add_btn_rect.mRight;
+ S32 right_shift = gear_btn_rect.getWidth() + gap_width;
+
+ add_btn_rect.translate(-right_shift,0);
+ call_btn_rect.translate(-right_shift,0);
+
+ mAddBtn->setRect(add_btn_rect);
+ mVoiceButton->setRect(call_btn_rect);
+}
+
+// static
+bool LLFloaterIMSessionTab::isChatMultiTab()
+{
+ // Restart is required in order to change chat window type.
+ return true;
+}
+
+bool LLFloaterIMSessionTab::checkIfTornOff()
+{
+ bool isTorn = !getHost();
+
+ if (isTorn != isTornOff())
+ {
+ setTornOff(isTorn);
+ refreshConversation();
+ }
+
+ return isTorn;
+}
+
+void LLFloaterIMSessionTab::doToSelected(const LLSD& userdata)
+{
+ // Get the list of selected items in the tab
+ std::string command = userdata.asString();
+ uuid_vec_t selected_uuids;
+ getSelectedUUIDs(selected_uuids);
+
+ // Perform the command (IM, profile, etc...) on the list using the general conversation container method
+ LLFloaterIMContainer* floater_container = LLFloaterIMContainer::getInstance();
+ // Note: By construction, those can only be participants so we can call doToParticipants() directly
+ floater_container->doToParticipants(command, selected_uuids);
+}
+
+bool LLFloaterIMSessionTab::enableContextMenuItem(const LLSD& userdata)
+{
+ // Get the list of selected items in the tab
+ std::string command = userdata.asString();
+ uuid_vec_t selected_uuids;
+ getSelectedUUIDs(selected_uuids);
+
+ // Perform the item enable test on the list using the general conversation container method
+ LLFloaterIMContainer* floater_container = LLFloaterIMContainer::getInstance();
+ return floater_container->enableContextMenuItem(command, selected_uuids);
+}
+
+bool LLFloaterIMSessionTab::checkContextMenuItem(const LLSD& userdata)
+{
+ // Get the list of selected items in the tab
+ std::string command = userdata.asString();
+ uuid_vec_t selected_uuids;
+ getSelectedUUIDs(selected_uuids);
+
+ // Perform the item check on the list using the general conversation container method
+ LLFloaterIMContainer* floater_container = LLFloaterIMContainer::getInstance();
+ return floater_container->checkContextMenuItem(command, selected_uuids);
+}
+
+void LLFloaterIMSessionTab::getSelectedUUIDs(uuid_vec_t& selected_uuids)
+{
+ const std::set<LLFolderViewItem*> selected_items = mConversationsRoot->getSelectionList();
+
+ std::set<LLFolderViewItem*>::const_iterator it = selected_items.begin();
+ const std::set<LLFolderViewItem*>::const_iterator it_end = selected_items.end();
+
+ for (; it != it_end; ++it)
+ {
+ LLConversationItem* conversation_item = static_cast<LLConversationItem *>((*it)->getViewModelItem());
+ selected_uuids.push_back(conversation_item->getUUID());
+ }
+}
+
+LLConversationItem* LLFloaterIMSessionTab::getCurSelectedViewModelItem()
+{
+ LLConversationItem *conversationItem = NULL;
+
+ if(mConversationsRoot &&
+ mConversationsRoot->getCurSelectedItem() &&
+ mConversationsRoot->getCurSelectedItem()->getViewModelItem())
+ {
+ conversationItem = static_cast<LLConversationItem *>(mConversationsRoot->getCurSelectedItem()->getViewModelItem()) ;
+ }
+
+ return conversationItem;
+}
+
+void LLFloaterIMSessionTab::saveCollapsedState()
+{
+ LLFloaterIMSessionTab* conversp = LLFloaterIMSessionTab::getConversation(mSessionID);
+ if(conversp->isNearbyChat())
+ {
+ gSavedPerAccountSettings.setBOOL("NearbyChatIsNotCollapsed", isMessagePaneExpanded());
+ }
+}
+BOOL LLFloaterIMSessionTab::handleKeyHere(KEY key, MASK mask )
+{
+ BOOL handled = FALSE;
+
+ if(mask == MASK_ALT)
+ {
+ LLFloaterIMContainer* floater_container = LLFloaterIMContainer::getInstance();
+ if (KEY_RETURN == key && !isTornOff())
+ {
+ floater_container->expandConversation();
+ handled = TRUE;
+ }
+ if ((KEY_UP == key) || (KEY_LEFT == key))
+ {
+ floater_container->selectNextorPreviousConversation(false);
+ handled = TRUE;
+ }
+ if ((KEY_DOWN == key ) || (KEY_RIGHT == key))
+ {
+ floater_container->selectNextorPreviousConversation(true);
+ handled = TRUE;
+ }
+ }
+ return handled;
+}
diff --git a/indra/newview/llfloaterimsessiontab.h b/indra/newview/llfloaterimsessiontab.h
new file mode 100755
index 0000000000..e7b05a584b
--- /dev/null
+++ b/indra/newview/llfloaterimsessiontab.h
@@ -0,0 +1,220 @@
+/**
+ * @file llfloaterimsessiontab.h
+ * @brief LLFloaterIMSessionTab class implements the common behavior of LNearbyChatBar
+ * @brief and LLFloaterIMSession for hosting both in LLIMContainer
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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_FLOATERIMSESSIONTAB_H
+#define LL_FLOATERIMSESSIONTAB_H
+
+#include "lllayoutstack.h"
+#include "llparticipantlist.h"
+#include "lltransientdockablefloater.h"
+#include "llviewercontrol.h"
+#include "lleventtimer.h"
+#include "llimview.h"
+#include "llconversationmodel.h"
+#include "llconversationview.h"
+#include "lltexteditor.h"
+
+class LLPanelChatControlPanel;
+class LLChatEntry;
+class LLChatHistory;
+
+class LLFloaterIMSessionTab
+ : public LLTransientDockableFloater
+{
+
+public:
+ LOG_CLASS(LLFloaterIMSessionTab);
+
+ LLFloaterIMSessionTab(const LLSD& session_id);
+ ~LLFloaterIMSessionTab();
+
+ // reload all message with new settings of visual modes
+ static void processChatHistoryStyleUpdate(bool clean_messages = false);
+ static void reloadEmptyFloaters();
+
+ /**
+ * Returns true if chat is displayed in multi tabbed floater
+ * false if chat is displayed in multiple windows
+ */
+ static bool isChatMultiTab();
+
+ // add conversation to container
+ static void addToHost(const LLUUID& session_id);
+
+ bool isHostAttached() {return mIsHostAttached;}
+ void setHostAttached(bool is_attached) {mIsHostAttached = is_attached;}
+
+ 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;}
+
+ // LLFloater overrides
+ /*virtual*/ void onOpen(const LLSD& key);
+ /*virtual*/ BOOL postBuild();
+ /*virtual*/ void draw();
+ /*virtual*/ void setVisible(BOOL visible);
+ /*virtual*/ void setFocus(BOOL focus);
+
+ // Handle the left hand participant list widgets
+ void addConversationViewParticipant(LLConversationItem* item);
+ void removeConversationViewParticipant(const LLUUID& participant_id);
+ void updateConversationViewParticipant(const LLUUID& participant_id);
+ void refreshConversation();
+ void buildConversationViewParticipant();
+
+ void setSortOrder(const LLConversationSort& order);
+ virtual void onTearOffClicked();
+ void updateGearBtn();
+ void initBtns();
+ virtual void updateMessages() {}
+ LLConversationItem* getCurSelectedViewModelItem();
+ void forceReshape();
+ virtual BOOL handleKeyHere( KEY key, MASK mask );
+ bool isMessagePaneExpanded(){return mMessagePaneExpanded;}
+ void setMessagePaneExpanded(bool expanded){mMessagePaneExpanded = expanded;}
+ void restoreFloater();
+ void saveCollapsedState();
+
+protected:
+
+ // callback for click on any items of the visual states menu
+ void onIMSessionMenuItemClicked(const LLSD& userdata);
+
+ // callback for check/uncheck of the expanded/collapse mode's switcher
+ bool onIMCompactExpandedMenuItemCheck(const LLSD& userdata);
+
+ //
+ bool onIMShowModesMenuItemCheck(const LLSD& userdata);
+ bool onIMShowModesMenuItemEnable(const LLSD& userdata);
+ static void onSlide(LLFloaterIMSessionTab *self);
+ static void onCollapseToLine(LLFloaterIMSessionTab *self);
+ void reshapeFloater(bool collapse);
+
+ // refresh a visual state of the Call button
+ void updateCallBtnState(bool callIsActive);
+
+ void hideOrShowTitle(); // toggle the floater's drag handle
+ void hideAllStandardButtons();
+
+ /// Update floater header and toolbar buttons when hosted/torn off state is toggled.
+ void updateHeaderAndToolbar();
+
+ // Update the input field help text and other places that need the session name
+ virtual void updateSessionName(const std::string& name);
+
+ // set the enable/disable state for the Call button
+ virtual void enableDisableCallBtn();
+
+ // process focus events to set a currently active session
+ /* virtual */ void onFocusLost();
+ /* virtual */ void onFocusReceived();
+
+ // prepare chat's params and out one message to chatHistory
+ void appendMessage(const LLChat& chat, const LLSD &args = 0);
+
+ std::string appendTime();
+ void assignResizeLimits();
+
+ S32 mFloaterExtraWidth;
+
+ bool mIsNearbyChat;
+ bool mIsP2PChat;
+
+ bool mMessagePaneExpanded;
+ bool mIsParticipantListExpanded;
+
+
+ LLIMModel::LLIMSession* mSession;
+
+ // Participants list: model and view
+ LLConversationViewParticipant* createConversationViewParticipant(LLConversationItem* item);
+
+ LLUUID mSessionID;
+ LLLayoutStack* mBodyStack;
+ LLLayoutStack* mParticipantListAndHistoryStack;
+ LLLayoutPanel* mParticipantListPanel; // add the widgets to that see mConversationsListPanel
+ LLLayoutPanel* mRightPartPanel;
+ LLLayoutPanel* mContentPanel;
+ LLLayoutPanel* mToolbarPanel;
+ LLLayoutPanel* mInputButtonPanel;
+ LLParticipantList* getParticipantList();
+ conversations_widgets_map mConversationsWidgets;
+ LLConversationViewModel mConversationViewModel;
+ LLFolderView* mConversationsRoot;
+ LLScrollContainer* mScroller;
+
+ LLChatHistory* mChatHistory;
+ LLChatEntry* mInputEditor;
+ LLLayoutPanel * mChatLayoutPanel;
+ LLLayoutStack * mInputPanels;
+
+ LLButton* mExpandCollapseLineBtn;
+ LLButton* mExpandCollapseBtn;
+ LLButton* mTearOffBtn;
+ LLButton* mCloseBtn;
+ LLButton* mGearBtn;
+ LLButton* mAddBtn;
+ LLButton* mVoiceButton;
+ LLUICtrl* mTranslationCheckBox;
+
+private:
+ // Handling selection and contextual menu
+ void doToSelected(const LLSD& userdata);
+ bool enableContextMenuItem(const LLSD& userdata);
+ bool checkContextMenuItem(const LLSD& userdata);
+
+ void getSelectedUUIDs(uuid_vec_t& selected_uuids);
+
+ /// Refreshes the floater at a constant rate.
+ virtual void refresh() = 0;
+
+ /**
+ * Adjusts chat history height to fit vertically with input chat field
+ * and avoid overlapping, since input chat field can be vertically expanded.
+ * Implementation: chat history bottom "follows" top+top_pad of input chat field
+ */
+ void reshapeChatLayoutPanel();
+
+ void onInputEditorClicked();
+
+ bool checkIfTornOff();
+ bool mIsHostAttached;
+ bool mHasVisibleBeenInitialized;
+
+ LLTimer* mRefreshTimer; ///< Defines the rate at which refresh() is called.
+
+ S32 mInputEditorPad;
+ S32 mChatLayoutPanelHeight;
+ S32 mFloaterHeight;
+};
+
+
+#endif /* LL_FLOATERIMSESSIONTAB_H */
diff --git a/indra/newview/llfloaterinspect.cpp b/indra/newview/llfloaterinspect.cpp
index cece8d299c..5a1dfc99ab 100644..100755
--- a/indra/newview/llfloaterinspect.cpp
+++ b/indra/newview/llfloaterinspect.cpp
@@ -46,7 +46,9 @@
LLFloaterInspect::LLFloaterInspect(const LLSD& key)
: LLFloater(key),
- mDirty(FALSE)
+ mDirty(FALSE),
+ mOwnerNameCacheConnection(),
+ mCreatorNameCacheConnection()
{
mCommitCallbackRegistrar.add("Inspect.OwnerProfile", boost::bind(&LLFloaterInspect::onClickOwnerProfile, this));
mCommitCallbackRegistrar.add("Inspect.CreatorProfile", boost::bind(&LLFloaterInspect::onClickCreatorProfile, this));
@@ -67,6 +69,14 @@ BOOL LLFloaterInspect::postBuild()
LLFloaterInspect::~LLFloaterInspect(void)
{
+ if (mOwnerNameCacheConnection.connected())
+ {
+ mOwnerNameCacheConnection.disconnect();
+ }
+ if (mCreatorNameCacheConnection.connected())
+ {
+ mCreatorNameCacheConnection.disconnect();
+ }
if(!LLFloaterReg::instanceVisible("build"))
{
if(LLToolMgr::getInstance()->getBaseTool() == LLToolCompInspect::getInstance())
@@ -80,7 +90,6 @@ LLFloaterInspect::~LLFloaterInspect(void)
{
LLFloaterReg::showInstance("build", LLSD(), TRUE);
}
- //sInstance = NULL;
}
void LLFloaterInspect::onOpen(const LLSD& key)
@@ -167,15 +176,6 @@ LLUUID LLFloaterInspect::getSelectedUUID()
return LLUUID::null;
}
-void LLFloaterInspect::onGetAvNameCallback(const LLUUID& idCreator, const LLAvatarName& av_name, void* FloaterPtr)
-{
- if (FloaterPtr)
- {
- LLFloaterInspect* floater = (LLFloaterInspect*)FloaterPtr;
- floater->dirty();
- }
-}
-
void LLFloaterInspect::refresh()
{
LLUUID creator_id;
@@ -229,7 +229,11 @@ void LLFloaterInspect::refresh()
else
{
owner_name = LLTrans::getString("RetrievingData");
- LLAvatarNameCache::get(idOwner, boost::bind(&LLFloaterInspect::onGetAvNameCallback, _1, _2, this));
+ if (mOwnerNameCacheConnection.connected())
+ {
+ mOwnerNameCacheConnection.disconnect();
+ }
+ mOwnerNameCacheConnection = LLAvatarNameCache::get(idOwner, boost::bind(&LLFloaterInspect::onGetOwnerNameCallback, this));
}
if (LLAvatarNameCache::get(idCreator, &av_name))
@@ -239,7 +243,11 @@ void LLFloaterInspect::refresh()
else
{
creator_name = LLTrans::getString("RetrievingData");
- LLAvatarNameCache::get(idCreator, boost::bind(&LLFloaterInspect::onGetAvNameCallback, _1, _2, this));
+ if (mCreatorNameCacheConnection.connected())
+ {
+ mCreatorNameCacheConnection.disconnect();
+ }
+ mCreatorNameCacheConnection = LLAvatarNameCache::get(idCreator, boost::bind(&LLFloaterInspect::onGetCreatorNameCallback, this));
}
row["id"] = obj->getObject()->getID();
@@ -289,6 +297,18 @@ void LLFloaterInspect::dirty()
setDirty();
}
+void LLFloaterInspect::onGetOwnerNameCallback()
+{
+ mOwnerNameCacheConnection.disconnect();
+ setDirty();
+}
+
+void LLFloaterInspect::onGetCreatorNameCallback()
+{
+ mCreatorNameCacheConnection.disconnect();
+ setDirty();
+}
+
void LLFloaterInspect::draw()
{
if (mDirty)
diff --git a/indra/newview/llfloaterinspect.h b/indra/newview/llfloaterinspect.h
index 7ee83ccdb4..44381eac96 100644..100755
--- a/indra/newview/llfloaterinspect.h
+++ b/indra/newview/llfloaterinspect.h
@@ -55,8 +55,6 @@ public:
void onClickOwnerProfile();
void onSelectObject();
- static void onGetAvNameCallback(const LLUUID& idCreator, const LLAvatarName& av_name, void* FloaterPtr);
-
LLScrollListCtrl* mObjectList;
protected:
// protected members
@@ -64,13 +62,15 @@ protected:
bool mDirty;
private:
+ void onGetOwnerNameCallback();
+ void onGetCreatorNameCallback();
LLFloaterInspect(const LLSD& key);
virtual ~LLFloaterInspect(void);
- // static data
-// static LLFloaterInspect* sInstance;
LLSafeHandle<LLObjectSelection> mObjectSelection;
+ boost::signals2::connection mOwnerNameCacheConnection;
+ boost::signals2::connection mCreatorNameCacheConnection;
};
#endif //LL_LLFLOATERINSPECT_H
diff --git a/indra/newview/llfloaterinventory.cpp b/indra/newview/llfloaterinventory.cpp
index 9b9b90e521..9b9b90e521 100644..100755
--- a/indra/newview/llfloaterinventory.cpp
+++ b/indra/newview/llfloaterinventory.cpp
diff --git a/indra/newview/llfloaterinventory.h b/indra/newview/llfloaterinventory.h
index 823c4903b4..823c4903b4 100644..100755
--- a/indra/newview/llfloaterinventory.h
+++ b/indra/newview/llfloaterinventory.h
diff --git a/indra/newview/llfloaterjoystick.cpp b/indra/newview/llfloaterjoystick.cpp
index c37798c330..d0c22d25f2 100644..100755
--- a/indra/newview/llfloaterjoystick.cpp
+++ b/indra/newview/llfloaterjoystick.cpp
@@ -33,6 +33,7 @@
#include "llerror.h"
#include "llrect.h"
#include "llstring.h"
+#include "llstat.h"
// project includes
#include "lluictrlfactory.h"
@@ -83,7 +84,8 @@ BOOL LLFloaterJoystick::postBuild()
for (U32 i = 0; i < 6; i++)
{
- mAxisStats[i] = new LLStat(4);
+ std::string stat_name(llformat("Joystick axis %d", i));
+ mAxisStats[i] = new LLStat(stat_name, 4);
std::string axisname = llformat("axis%d", i);
mAxisStatsBar[i] = getChild<LLStatBar>(axisname);
if (mAxisStatsBar[i])
diff --git a/indra/newview/llfloaterjoystick.h b/indra/newview/llfloaterjoystick.h
index dfdb108ff8..dfdb108ff8 100644..100755
--- a/indra/newview/llfloaterjoystick.h
+++ b/indra/newview/llfloaterjoystick.h
diff --git a/indra/newview/llfloaterlagmeter.cpp b/indra/newview/llfloaterlagmeter.cpp
index 68b1770bb2..68b1770bb2 100644..100755
--- a/indra/newview/llfloaterlagmeter.cpp
+++ b/indra/newview/llfloaterlagmeter.cpp
diff --git a/indra/newview/llfloaterlagmeter.h b/indra/newview/llfloaterlagmeter.h
index eef6955601..eef6955601 100644..100755
--- a/indra/newview/llfloaterlagmeter.h
+++ b/indra/newview/llfloaterlagmeter.h
diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp
index ee18c95b34..2b9c216e54 100644..100755
--- a/indra/newview/llfloaterland.cpp
+++ b/indra/newview/llfloaterland.cpp
@@ -557,7 +557,7 @@ void LLPanelLandGeneral::refresh()
BOOL is_leased = (LLParcel::OS_LEASED == parcel->getOwnershipStatus());
BOOL region_xfer = FALSE;
if(regionp
- && !(regionp->getRegionFlags() & REGION_FLAGS_BLOCK_LAND_RESELL))
+ && !(regionp->getRegionFlag(REGION_FLAGS_BLOCK_LAND_RESELL)))
{
region_xfer = TRUE;
}
@@ -783,8 +783,9 @@ void LLPanelLandGeneral::refresh()
mBtnReleaseLand->setEnabled( can_release );
}
- BOOL use_pass = parcel->getParcelFlag(PF_USE_PASS_LIST) && !LLViewerParcelMgr::getInstance()->isCollisionBanned();;
+ BOOL use_pass = parcel->getOwnerID()!= gAgent.getID() && parcel->getParcelFlag(PF_USE_PASS_LIST) && !LLViewerParcelMgr::getInstance()->isCollisionBanned();;
mBtnBuyPass->setEnabled(use_pass);
+
}
}
@@ -1045,6 +1046,8 @@ void LLPanelLandGeneral::onCommitAny(LLUICtrl *ctrl, void *userdata)
void LLPanelLandGeneral::onClickSellLand(void* data)
{
LLViewerParcelMgr::getInstance()->startSellLand();
+ LLPanelLandGeneral *panelp = (LLPanelLandGeneral *)data;
+ panelp->refresh();
}
// static
@@ -1865,23 +1868,8 @@ BOOL LLPanelLandOptions::postBuild()
childSetCommitCallback("ShowDirectoryCheck", onCommitAny, this);
- if (gAgent.getAgentAccess().isInTransition())
- {
- // during the AO transition, this combo has an Adult item.
- // Post-transition, it goes away. We can remove this conditional
- // after the transition and just use the "else" clause.
- mCategoryCombo = getChild<LLComboBox>( "land category with adult");
- childSetCommitCallback("land category with adult", onCommitAny, this);
- }
- else
- {
- // this is the code that should be preserved post-transition
- // you could also change the XML to set visibility and enabled true.
- mCategoryCombo = getChild<LLComboBox>( "land category");
- childSetCommitCallback("land category", onCommitAny, this);
- }
- mCategoryCombo->setVisible(true);
- mCategoryCombo->setEnabled(true);
+ mCategoryCombo = getChild<LLComboBox>( "land category");
+ childSetCommitCallback("land category", onCommitAny, this);
mMatureCtrl = getChild<LLCheckBoxCtrl>( "MatureCheck");
@@ -1901,6 +1889,7 @@ BOOL LLPanelLandOptions::postBuild()
mSnapshotCtrl->setCommitCallback( onCommitAny, this );
mSnapshotCtrl->setAllowNoTexture ( TRUE );
mSnapshotCtrl->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER);
+ mSnapshotCtrl->setDnDFilterPermMask(PERM_COPY | PERM_TRANSFER);
mSnapshotCtrl->setNonImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER);
}
else
@@ -2038,6 +2027,10 @@ void LLPanelLandOptions::refresh()
mSnapshotCtrl->setImageAssetID(parcel->getSnapshotID());
mSnapshotCtrl->setEnabled( can_change_identity );
+ // find out where we're looking and convert that to an angle in degrees on a regular compass (not the internal representation)
+ LLVector3 user_look_at = parcel->getUserLookAt();
+ U32 user_look_at_angle = ( (U32)( ( atan2(user_look_at[1], -user_look_at[0]) + F_PI * 2 ) * RAD_TO_DEG + 0.5) - 90) % 360;
+
LLVector3 pos = parcel->getUserLocation();
if (pos.isExactlyZero())
{
@@ -2045,10 +2038,11 @@ void LLPanelLandOptions::refresh()
}
else
{
- mLocationText->setTextArg("[LANDING]",llformat("%d, %d, %d",
+ mLocationText->setTextArg("[LANDING]",llformat("%d, %d, %d (%d\xC2\xB0)",
llround(pos.mV[VX]),
llround(pos.mV[VY]),
- llround(pos.mV[VZ])));
+ llround(pos.mV[VZ]),
+ user_look_at_angle));
}
mSetBtn->setEnabled( can_change_landing_point );
@@ -2103,7 +2097,6 @@ void LLPanelLandOptions::refresh()
// virtual
void LLPanelLandOptions::draw()
{
- refreshSearch(); // Is this necessary? JC
LLPanel::draw();
}
@@ -2117,9 +2110,8 @@ void LLPanelLandOptions::refreshSearch()
mCheckShowDirectory->set(FALSE);
mCheckShowDirectory->setEnabled(FALSE);
- // *TODO:Translate
- const std::string& none_string = LLParcel::getCategoryUIString(LLParcel::C_NONE);
- mCategoryCombo->setSimple(none_string);
+ const std::string& none_string = LLParcel::getCategoryString(LLParcel::C_NONE);
+ mCategoryCombo->setValue(none_string);
mCategoryCombo->setEnabled(FALSE);
return;
}
@@ -2129,9 +2121,9 @@ void LLPanelLandOptions::refreshSearch()
bool can_change =
LLViewerParcelMgr::isParcelModifiableByAgent(
- parcel, GP_LAND_CHANGE_IDENTITY)
+ parcel, GP_LAND_FIND_PLACES)
&& region
- && !(region->getRegionFlags() & REGION_FLAGS_BLOCK_PARCEL_SEARCH);
+ && !(region->getRegionFlag(REGION_FLAGS_BLOCK_PARCEL_SEARCH));
// There is a bug with this panel whereby the Show Directory bit can be
// slammed off by the Region based on an override. Since this data is cached
@@ -2146,10 +2138,9 @@ void LLPanelLandOptions::refreshSearch()
mCheckShowDirectory ->set(show_directory);
// Set by string in case the order in UI doesn't match the order by index.
- // *TODO:Translate
LLParcel::ECategory cat = parcel->getCategory();
- const std::string& category_string = LLParcel::getCategoryUIString(cat);
- mCategoryCombo->setSimple(category_string);
+ const std::string& category_string = LLParcel::getCategoryString(cat);
+ mCategoryCombo->setValue(category_string);
std::string tooltip;
bool enable_show_directory = false;
@@ -2226,8 +2217,8 @@ void LLPanelLandOptions::onCommitAny(LLUICtrl *ctrl, void *userdata)
BOOL allow_damage = !self->mCheckSafe->get();
BOOL allow_fly = self->mCheckFly->get();
BOOL allow_landmark = TRUE; // cannot restrict landmark creation
- BOOL allow_group_scripts = self->mCheckGroupScripts->get() || self->mCheckOtherScripts->get();
BOOL allow_other_scripts = self->mCheckOtherScripts->get();
+ BOOL allow_group_scripts = self->mCheckGroupScripts->get() || allow_other_scripts;
BOOL allow_publish = FALSE;
BOOL mature_publish = self->mMatureCtrl->get();
BOOL push_restriction = self->mPushRestrictionCtrl->get();
@@ -2240,11 +2231,16 @@ void LLPanelLandOptions::onCommitAny(LLUICtrl *ctrl, void *userdata)
LLViewerRegion* region;
region = LLViewerParcelMgr::getInstance()->getSelectionRegion();
- if (!allow_other_scripts && region && region->getAllowDamage())
- {
-
- LLNotificationsUtil::add("UnableToDisableOutsideScripts");
- return;
+ if (region && region->getAllowDamage())
+ { // Damage is allowed on the region - server will always allow scripts
+ if ( (!allow_other_scripts && parcel->getParcelFlag(PF_ALLOW_OTHER_SCRIPTS)) ||
+ (!allow_group_scripts && parcel->getParcelFlag(PF_ALLOW_GROUP_SCRIPTS)) )
+ { // Don't allow turning off "Run Scripts" if damage is allowed in the region
+ self->mCheckOtherScripts->set(parcel->getParcelFlag(PF_ALLOW_OTHER_SCRIPTS)); // Restore UI to actual settings
+ self->mCheckGroupScripts->set(parcel->getParcelFlag(PF_ALLOW_GROUP_SCRIPTS));
+ LLNotificationsUtil::add("UnableToDisableOutsideScripts");
+ return;
+ }
}
// Push data into current parcel
@@ -2371,12 +2367,6 @@ LLPanelLandAccess::~LLPanelLandAccess()
void LLPanelLandAccess::refresh()
{
LLFloater* parent_floater = gFloaterView->getParentFloater(this);
-
- if (mListAccess)
- mListAccess->deleteAllItems();
- if (mListBanned)
- mListBanned->deleteAllItems();
-
LLParcel *parcel = mParcel->getParcel();
// Display options
@@ -2384,7 +2374,7 @@ void LLPanelLandAccess::refresh()
{
BOOL use_access_list = parcel->getParcelFlag(PF_USE_ACCESS_LIST);
BOOL use_group = parcel->getParcelFlag(PF_USE_ACCESS_GROUP);
- BOOL public_access = !use_access_list && !use_group;
+ BOOL public_access = !use_access_list;
getChild<LLUICtrl>("public_access")->setValue(public_access );
getChild<LLUICtrl>("GroupCheck")->setValue(use_group );
@@ -2394,7 +2384,11 @@ void LLPanelLandAccess::refresh()
getChild<LLUICtrl>("GroupCheck")->setLabelArg("[GROUP]", group_name );
// Allow list
+ if (mListAccess)
{
+ // Clear the sort order so we don't re-sort on every add.
+ mListAccess->clearSortOrder();
+ mListAccess->deleteAllItems();
S32 count = parcel->mAccessList.size();
getChild<LLUICtrl>("AccessList")->setToolTipArg(LLStringExplicit("[LISTED]"), llformat("%d",count));
getChild<LLUICtrl>("AccessList")->setToolTipArg(LLStringExplicit("[MAX]"), llformat("%d",PARCEL_MAX_ACCESS_LIST));
@@ -2429,13 +2423,17 @@ void LLPanelLandAccess::refresh()
}
suffix.append(" " + parent_floater->getString("Remaining") + ")");
}
- if (mListAccess)
- mListAccess->addNameItem(entry.mID, ADD_DEFAULT, TRUE, suffix);
+ mListAccess->addNameItem(entry.mID, ADD_DEFAULT, TRUE, suffix);
}
+ mListAccess->sortByName(TRUE);
}
// Ban List
+ if(mListBanned)
{
+ // Clear the sort order so we don't re-sort on every add.
+ mListBanned->clearSortOrder();
+ mListBanned->deleteAllItems();
S32 count = parcel->mBanList.size();
getChild<LLUICtrl>("BannedList")->setToolTipArg(LLStringExplicit("[LISTED]"), llformat("%d",count));
@@ -2473,6 +2471,7 @@ void LLPanelLandAccess::refresh()
}
mListBanned->addNameItem(entry.mID, ADD_DEFAULT, TRUE, suffix);
}
+ mListBanned->sortByName(TRUE);
}
if(parcel->getRegionDenyAnonymousOverride())
@@ -2542,7 +2541,11 @@ void LLPanelLandAccess::refresh_ui()
getChildView("HoursSpin")->setEnabled(FALSE);
getChildView("AccessList")->setEnabled(FALSE);
getChildView("BannedList")->setEnabled(FALSE);
-
+ getChildView("add_allowed")->setEnabled(FALSE);
+ getChildView("remove_allowed")->setEnabled(FALSE);
+ getChildView("add_banned")->setEnabled(FALSE);
+ getChildView("remove_banned")->setEnabled(FALSE);
+
LLParcel *parcel = mParcel->getParcel();
if (parcel)
{
@@ -2580,7 +2583,6 @@ void LLPanelLandAccess::refresh_ui()
{
getChildView("Only Allow")->setToolTip(std::string());
}
- getChildView("GroupCheck")->setEnabled(FALSE);
getChildView("PassCheck")->setEnabled(FALSE);
getChildView("pass_combo")->setEnabled(FALSE);
getChildView("AccessList")->setEnabled(FALSE);
@@ -2590,11 +2592,7 @@ void LLPanelLandAccess::refresh_ui()
getChildView("limit_payment")->setEnabled(FALSE);
getChildView("limit_age_verified")->setEnabled(FALSE);
- std::string group_name;
- if (gCacheName->getGroupName(parcel->getGroupID(), group_name))
- {
- getChildView("GroupCheck")->setEnabled(can_manage_allowed);
- }
+
BOOL group_access = getChild<LLUICtrl>("GroupCheck")->getValue().asBoolean();
BOOL sell_passes = getChild<LLUICtrl>("PassCheck")->getValue().asBoolean();
getChildView("PassCheck")->setEnabled(can_manage_allowed);
@@ -2605,16 +2603,21 @@ void LLPanelLandAccess::refresh_ui()
getChildView("HoursSpin")->setEnabled(can_manage_allowed);
}
}
+ std::string group_name;
+ if (gCacheName->getGroupName(parcel->getGroupID(), group_name))
+ {
+ getChildView("GroupCheck")->setEnabled(can_manage_allowed);
+ }
getChildView("AccessList")->setEnabled(can_manage_allowed);
S32 allowed_list_count = parcel->mAccessList.size();
getChildView("add_allowed")->setEnabled(can_manage_allowed && allowed_list_count < PARCEL_MAX_ACCESS_LIST);
- BOOL has_selected = mListAccess->getSelectionInterface()->getFirstSelectedIndex() >= 0;
+ BOOL has_selected = (mListAccess && mListAccess->getSelectionInterface()->getFirstSelectedIndex() >= 0);
getChildView("remove_allowed")->setEnabled(can_manage_allowed && has_selected);
getChildView("BannedList")->setEnabled(can_manage_banned);
S32 banned_list_count = parcel->mBanList.size();
getChildView("add_banned")->setEnabled(can_manage_banned && banned_list_count < PARCEL_MAX_ACCESS_LIST);
- has_selected = mListBanned->getSelectionInterface()->getFirstSelectedIndex() >= 0;
+ has_selected = (mListBanned && mListBanned->getSelectionInterface()->getFirstSelectedIndex() >= 0);
getChildView("remove_banned")->setEnabled(can_manage_banned && has_selected);
}
}
@@ -2650,17 +2653,6 @@ void LLPanelLandAccess::onCommitPublicAccess(LLUICtrl *ctrl, void *userdata)
{
return;
}
-
- // If we disabled public access, enable group access by default (if applicable)
- BOOL public_access = self->getChild<LLUICtrl>("public_access")->getValue().asBoolean();
- if (public_access == FALSE)
- {
- std::string group_name;
- if (gCacheName->getGroupName(parcel->getGroupID(), group_name))
- {
- self->getChild<LLUICtrl>("GroupCheck")->setValue(public_access ? FALSE : TRUE);
- }
- }
onCommitAny(ctrl, userdata);
}
@@ -2695,7 +2687,6 @@ void LLPanelLandAccess::onCommitAny(LLUICtrl *ctrl, void *userdata)
if (public_access)
{
use_access_list = FALSE;
- use_access_group = FALSE;
limit_payment = self->getChild<LLUICtrl>("limit_payment")->getValue().asBoolean();
limit_age_verified = self->getChild<LLUICtrl>("limit_age_verified")->getValue().asBoolean();
}
@@ -2739,11 +2730,13 @@ void LLPanelLandAccess::onCommitAny(LLUICtrl *ctrl, void *userdata)
void LLPanelLandAccess::onClickAddAccess()
{
+ LLView * button = findChild<LLButton>("add_allowed");
+ LLFloater * root_floater = gFloaterView->getParentFloater(this);
LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(
- boost::bind(&LLPanelLandAccess::callbackAvatarCBAccess, this, _1));
+ boost::bind(&LLPanelLandAccess::callbackAvatarCBAccess, this, _1), FALSE, FALSE, FALSE, root_floater->getName(), button);
if (picker)
{
- gFloaterView->getParentFloater(this)->addDependentFloater(picker);
+ root_floater->addDependentFloater(picker);
}
}
@@ -2788,11 +2781,13 @@ void LLPanelLandAccess::onClickRemoveAccess(void* data)
// static
void LLPanelLandAccess::onClickAddBanned()
{
+ LLView * button = findChild<LLButton>("add_banned");
+ LLFloater * root_floater = gFloaterView->getParentFloater(this);
LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(
- boost::bind(&LLPanelLandAccess::callbackAvatarCBBanned, this, _1));
+ boost::bind(&LLPanelLandAccess::callbackAvatarCBBanned, this, _1), FALSE, FALSE, FALSE, root_floater->getName(), button);
if (picker)
{
- gFloaterView->getParentFloater(this)->addDependentFloater(picker);
+ root_floater->addDependentFloater(picker);
}
}
@@ -2872,7 +2867,7 @@ void LLPanelLandCovenant::refresh()
LLTextBox* resellable_clause = getChild<LLTextBox>("resellable_clause");
if (resellable_clause)
{
- if (region->getRegionFlags() & REGION_FLAGS_BLOCK_LAND_RESELL)
+ if (region->getRegionFlag(REGION_FLAGS_BLOCK_LAND_RESELL))
{
resellable_clause->setText(getString("can_not_resell"));
}
@@ -2885,7 +2880,7 @@ void LLPanelLandCovenant::refresh()
LLTextBox* changeable_clause = getChild<LLTextBox>("changeable_clause");
if (changeable_clause)
{
- if (region->getRegionFlags() & REGION_FLAGS_ALLOW_PARCEL_CHANGES)
+ if (region->getRegionFlag(REGION_FLAGS_ALLOW_PARCEL_CHANGES))
{
changeable_clause->setText(getString("can_change"));
}
diff --git a/indra/newview/llfloaterland.h b/indra/newview/llfloaterland.h
index 4f1c10274a..4f1c10274a 100644..100755
--- a/indra/newview/llfloaterland.h
+++ b/indra/newview/llfloaterland.h
diff --git a/indra/newview/llfloaterlandholdings.cpp b/indra/newview/llfloaterlandholdings.cpp
index 98e9b74278..98e9b74278 100644..100755
--- a/indra/newview/llfloaterlandholdings.cpp
+++ b/indra/newview/llfloaterlandholdings.cpp
diff --git a/indra/newview/llfloaterlandholdings.h b/indra/newview/llfloaterlandholdings.h
index d1d510bb40..d1d510bb40 100644..100755
--- a/indra/newview/llfloaterlandholdings.h
+++ b/indra/newview/llfloaterlandholdings.h
diff --git a/indra/newview/llfloatermap.cpp b/indra/newview/llfloatermap.cpp
index a65e9e911a..473e2938be 100644..100755
--- a/indra/newview/llfloatermap.cpp
+++ b/indra/newview/llfloatermap.cpp
@@ -122,16 +122,13 @@ BOOL LLFloaterMap::handleDoubleClick(S32 x, S32 y, MASK mask)
LLVector3d pos_global = mMap->viewPosToGlobal(x, y);
- // If we're not tracking a beacon already, double-click will set one
- if (!LLTracker::isTracking(NULL))
+ LLTracker::stopTracking(NULL);
+ LLFloaterWorldMap* world_map = LLFloaterWorldMap::getInstance();
+ if (world_map)
{
- LLFloaterWorldMap* world_map = LLFloaterWorldMap::getInstance();
- if (world_map)
- {
- world_map->trackLocation(pos_global);
- }
+ world_map->trackLocation(pos_global);
}
-
+
if (gSavedSettings.getBOOL("DoubleClickTeleport"))
{
// If DoubleClickTeleport is on, double clicking the minimap will teleport there
@@ -249,3 +246,8 @@ void LLFloaterMap::handleZoom(const LLSD& userdata)
mMap->setScale(scale);
}
}
+
+LLFloaterMap* LLFloaterMap::getInstance()
+{
+ return LLFloaterReg::getTypedInstance<LLFloaterMap>("mini_map");
+}
diff --git a/indra/newview/llfloatermap.h b/indra/newview/llfloatermap.h
index 8a1b965e62..ff2fb20535 100644..100755
--- a/indra/newview/llfloatermap.h
+++ b/indra/newview/llfloatermap.h
@@ -39,6 +39,7 @@ class LLFloaterMap : public LLFloater
{
public:
LLFloaterMap(const LLSD& key);
+ static LLFloaterMap* getInstance();
virtual ~LLFloaterMap();
/*virtual*/ BOOL postBuild();
diff --git a/indra/newview/llfloatermediasettings.cpp b/indra/newview/llfloatermediasettings.cpp
index 4f2a6ec1b7..4f2a6ec1b7 100644..100755
--- a/indra/newview/llfloatermediasettings.cpp
+++ b/indra/newview/llfloatermediasettings.cpp
diff --git a/indra/newview/llfloatermediasettings.h b/indra/newview/llfloatermediasettings.h
index 1d25530986..1d25530986 100644..100755
--- a/indra/newview/llfloatermediasettings.h
+++ b/indra/newview/llfloatermediasettings.h
diff --git a/indra/newview/llfloatermemleak.cpp b/indra/newview/llfloatermemleak.cpp
index 9edfe1e354..9edfe1e354 100644..100755
--- a/indra/newview/llfloatermemleak.cpp
+++ b/indra/newview/llfloatermemleak.cpp
diff --git a/indra/newview/llfloatermemleak.h b/indra/newview/llfloatermemleak.h
index 86416eaa07..86416eaa07 100644..100755
--- a/indra/newview/llfloatermemleak.h
+++ b/indra/newview/llfloatermemleak.h
diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp
index 7448f2bb2a..19cec55837 100755
--- a/indra/newview/llfloatermodelpreview.cpp
+++ b/indra/newview/llfloatermodelpreview.cpp
@@ -290,6 +290,22 @@ bool ll_is_degenerate(const LLVector4a& a, const LLVector4a& b, const LLVector4a
bool validate_face(const LLVolumeFace& face)
{
+
+ for (U32 v = 0; v < face.mNumVertices; v++)
+ {
+ if(face.mPositions && !face.mPositions[v].isFinite3())
+ {
+ llwarns << "NaN position data in face found!" << llendl;
+ return false;
+ }
+
+ if(face.mNormals && !face.mNormals[v].isFinite3())
+ {
+ llwarns << "NaN normal data in face found!" << llendl;
+ return false;
+ }
+ }
+
for (U32 i = 0; i < face.mNumIndices; ++i)
{
if (face.mIndices[i] >= face.mNumVertices)
@@ -305,8 +321,10 @@ bool validate_face(const LLVolumeFace& face)
return false;
}
+
/*const LLVector4a scale(0.5f);
+
for (U32 i = 0; i < face.mNumIndices; i+=3)
{
U16 idx1 = face.mIndices[i];
@@ -323,7 +341,6 @@ bool validate_face(const LLVolumeFace& face)
return false;
}
}*/
-
return true;
}
@@ -396,7 +413,6 @@ mCalculateBtn(NULL)
sInstance = this;
mLastMouseX = 0;
mLastMouseY = 0;
- mGLName = 0;
mStatusLock = new LLMutex(NULL);
mModelPreview = NULL;
@@ -498,7 +514,7 @@ BOOL LLFloaterModelPreview::postBuild()
text->setMouseDownCallback(boost::bind(&LLModelPreview::setPreviewLOD, mModelPreview, i));
}
}
- std::string current_grid = LLGridManager::getInstance()->getGridLabel();
+ std::string current_grid = LLGridManager::getInstance()->getGridId();
std::transform(current_grid.begin(),current_grid.end(),current_grid.begin(),::tolower);
std::string validate_url;
if (current_grid == "agni")
@@ -538,11 +554,6 @@ LLFloaterModelPreview::~LLFloaterModelPreview()
delete mModelPreview;
}
- if (mGLName)
- {
- LLImageGL::deleteTextures(1, &mGLName );
- }
-
delete mStatusLock;
mStatusLock = NULL;
}
@@ -743,6 +754,20 @@ void LLFloaterModelPreview::onAutoFillCommit(LLUICtrl* ctrl, void* userdata)
void LLFloaterModelPreview::onLODParamCommit(S32 lod, bool enforce_tri_limit)
{
mModelPreview->onLODParamCommit(lod, enforce_tri_limit);
+
+ //refresh LoDs that reference this one
+ for (S32 i = lod - 1; i >= 0; --i)
+ {
+ LLComboBox* lod_source_combo = getChild<LLComboBox>("lod_source_" + lod_name[i]);
+ if (lod_source_combo->getCurrentIndex() == LLModelPreview::USE_LOD_ABOVE)
+ {
+ onLoDSourceCommit(i);
+ }
+ else
+ {
+ break;
+ }
+ }
}
@@ -752,7 +777,6 @@ void LLFloaterModelPreview::onLODParamCommit(S32 lod, bool enforce_tri_limit)
void LLFloaterModelPreview::draw()
{
LLFloater::draw();
- LLRect r = getRect();
mModelPreview->update();
@@ -1676,7 +1700,6 @@ bool LLModelLoader::doLoadModel()
//If no skeleton, do a breadth-first search to get at specific joints
bool rootNode = false;
- bool skeletonWithNoRootNode = false;
//Need to test for a skeleton that does not have a root node
//This occurs when your instance controller does not have an associated scene
@@ -1687,10 +1710,6 @@ bool LLModelLoader::doLoadModel()
{
rootNode = true;
}
- else
- {
- skeletonWithNoRootNode = true;
- }
}
if ( !pSkeleton || !rootNode )
@@ -2494,7 +2513,7 @@ void LLModelLoader::loadTextures()
if(!material.mDiffuseMapFilename.empty())
{
material.mDiffuseMap =
- LLViewerTextureManager::getFetchedTextureFromUrl("file://" + material.mDiffuseMapFilename, TRUE, LLViewerTexture::BOOST_PREVIEW);
+ LLViewerTextureManager::getFetchedTextureFromUrl("file://" + material.mDiffuseMapFilename, FTT_LOCAL_FILE, TRUE, LLGLTexture::BOOST_PREVIEW);
material.mDiffuseMap->setLoadedCallback(LLModelPreview::textureLoadedCallback, 0, TRUE, FALSE, mPreview, NULL, FALSE);
material.mDiffuseMap->forceToSaveRawImage(0, F32_MAX);
mNumOfFetchingTextures++ ;
@@ -3876,15 +3895,30 @@ void LLModelPreview::genLODs(S32 which_lod, U32 decimation, bool enforce_tri_lim
U32 triangle_count = 0;
- for (LLModelLoader::model_list::iterator iter = mBaseModel.begin(); iter != mBaseModel.end(); ++iter)
+ U32 instanced_triangle_count = 0;
+
+ //get the triangle count for the whole scene
+ for (LLModelLoader::scene::iterator iter = mBaseScene.begin(), endIter = mBaseScene.end(); iter != endIter; ++iter)
{
- LLModel* mdl = *iter;
- for (S32 i = 0; i < mdl->getNumVolumeFaces(); ++i)
+ for (LLModelLoader::model_instance_list::iterator instance = iter->second.begin(), end_instance = iter->second.end(); instance != end_instance; ++instance)
{
- triangle_count += mdl->getVolumeFace(i).mNumIndices/3;
+ LLModel* mdl = instance->mModel;
+ if (mdl)
+ {
+ instanced_triangle_count += mdl->getNumTriangles();
+ }
}
}
+ //get the triangle count for the non-instanced set of models
+ for (U32 i = 0; i < mBaseModel.size(); ++i)
+ {
+ triangle_count += mBaseModel[i]->getNumTriangles();
+ }
+
+ //get ratio of uninstanced triangles to instanced triangles
+ F32 triangle_ratio = (F32) triangle_count / (F32) instanced_triangle_count;
+
U32 base_triangle_count = triangle_count;
U32 type_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0;
@@ -3918,6 +3952,8 @@ void LLModelPreview::genLODs(S32 which_lod, U32 decimation, bool enforce_tri_lim
if (which_lod > -1 && which_lod < NUM_LOD)
{
limit = mFMP->childGetValue("lod_triangle_limit_" + lod_name[which_lod]).asInteger();
+ //convert from "scene wide" to "non-instanced" triangle limit
+ limit = (S32) ( (F32) limit*triangle_ratio );
}
}
else
@@ -4023,7 +4059,7 @@ void LLModelPreview::genLODs(S32 which_lod, U32 decimation, bool enforce_tri_lim
U32 actual_verts = 0;
U32 submeshes = 0;
- mRequestedTriangleCount[lod] = triangle_count;
+ mRequestedTriangleCount[lod] = (S32) ( (F32) triangle_count / triangle_ratio );
mRequestedErrorThreshold[lod] = lod_error_threshold;
glodGroupParameteri(mGroup, GLOD_ADAPT_MODE, lod_mode);
@@ -4205,28 +4241,36 @@ void LLModelPreview::updateStatusMessages()
//initialize total for this lod to 0
total_tris[lod] = total_verts[lod] = total_submeshes[lod] = 0;
- for (U32 i = 0; i < mModel[lod].size(); ++i)
- { //for each model in the lod
- S32 cur_tris = 0;
- S32 cur_verts = 0;
- S32 cur_submeshes = mModel[lod][i]->getNumVolumeFaces();
-
- for (S32 j = 0; j < cur_submeshes; ++j)
- { //for each submesh (face), add triangles and vertices to current total
- const LLVolumeFace& face = mModel[lod][i]->getVolumeFace(j);
- cur_tris += face.mNumIndices/3;
- cur_verts += face.mNumVertices;
- }
+ for (LLModelLoader::scene::iterator iter = mScene[lod].begin(), endIter = mScene[lod].end(); iter != endIter; ++iter)
+ {
+ for (LLModelLoader::model_instance_list::iterator instance = iter->second.begin(), end_instance = iter->second.end(); instance != end_instance; ++instance)
+ {
+ LLModel* model = instance->mModel;
+ if (model)
+ {
+ //for each model in the lod
+ S32 cur_tris = 0;
+ S32 cur_verts = 0;
+ S32 cur_submeshes = model->getNumVolumeFaces();
+
+ for (S32 j = 0; j < cur_submeshes; ++j)
+ { //for each submesh (face), add triangles and vertices to current total
+ const LLVolumeFace& face = model->getVolumeFace(j);
+ cur_tris += face.mNumIndices/3;
+ cur_verts += face.mNumVertices;
+ }
- //add this model to the lod total
- total_tris[lod] += cur_tris;
- total_verts[lod] += cur_verts;
- total_submeshes[lod] += cur_submeshes;
+ //add this model to the lod total
+ total_tris[lod] += cur_tris;
+ total_verts[lod] += cur_verts;
+ total_submeshes[lod] += cur_submeshes;
- //store this model's counts to asset data
- tris[lod].push_back(cur_tris);
- verts[lod].push_back(cur_verts);
- submeshes[lod].push_back(cur_submeshes);
+ //store this model's counts to asset data
+ tris[lod].push_back(cur_tris);
+ verts[lod].push_back(cur_verts);
+ submeshes[lod].push_back(cur_submeshes);
+ }
+ }
}
}
@@ -4403,34 +4447,38 @@ void LLModelPreview::updateStatusMessages()
}
//add up physics triangles etc
- S32 start = 0;
- S32 end = mModel[LLModel::LOD_PHYSICS].size();
-
S32 phys_tris = 0;
S32 phys_hulls = 0;
S32 phys_points = 0;
- for (S32 i = start; i < end; ++i)
- { //add up hulls and points and triangles for selected mesh(es)
- LLModel* model = mModel[LLModel::LOD_PHYSICS][i];
- S32 cur_submeshes = model->getNumVolumeFaces();
-
- LLModel::convex_hull_decomposition& decomp = model->mPhysics.mHull;
-
- if (!decomp.empty())
+ //get the triangle count for the whole scene
+ for (LLModelLoader::scene::iterator iter = mScene[LLModel::LOD_PHYSICS].begin(), endIter = mScene[LLModel::LOD_PHYSICS].end(); iter != endIter; ++iter)
+ {
+ for (LLModelLoader::model_instance_list::iterator instance = iter->second.begin(), end_instance = iter->second.end(); instance != end_instance; ++instance)
{
- phys_hulls += decomp.size();
- for (U32 i = 0; i < decomp.size(); ++i)
+ LLModel* model = instance->mModel;
+ if (model)
{
- phys_points += decomp[i].size();
- }
- }
- else
- { //choose physics shape OR decomposition, can't use both
- for (S32 j = 0; j < cur_submeshes; ++j)
- { //for each submesh (face), add triangles and vertices to current total
- const LLVolumeFace& face = model->getVolumeFace(j);
- phys_tris += face.mNumIndices/3;
+ S32 cur_submeshes = model->getNumVolumeFaces();
+
+ LLModel::convex_hull_decomposition& decomp = model->mPhysics.mHull;
+
+ if (!decomp.empty())
+ {
+ phys_hulls += decomp.size();
+ for (U32 i = 0; i < decomp.size(); ++i)
+ {
+ phys_points += decomp[i].size();
+ }
+ }
+ else
+ { //choose physics shape OR decomposition, can't use both
+ for (S32 j = 0; j < cur_submeshes; ++j)
+ { //for each submesh (face), add triangles and vertices to current total
+ const LLVolumeFace& face = model->getVolumeFace(j);
+ phys_tris += face.mNumIndices/3;
+ }
+ }
}
}
}
@@ -4594,7 +4642,7 @@ void LLModelPreview::updateLodControls(S32 lod)
if (!lod_combo) return;
S32 lod_mode = lod_combo->getCurrentIndex();
- if (lod_mode == 0) // LoD from file
+ if (lod_mode == LOD_FROM_FILE) // LoD from file
{
fmp->mLODMode[lod] = 0;
for (U32 i = 0; i < num_file_controls; ++i)
@@ -4607,7 +4655,7 @@ void LLModelPreview::updateLodControls(S32 lod)
mFMP->childHide(lod_controls[i] + lod_name[lod]);
}
}
- else if (lod_mode == 2) // use LoD above
+ else if (lod_mode == USE_LOD_ABOVE) // use LoD above
{
fmp->mLODMode[lod] = 2;
for (U32 i = 0; i < num_file_controls; ++i)
@@ -4780,7 +4828,8 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights)
if (vf.mTexCoords)
{
vb->getTexCoord0Strider(tc_strider);
- LLVector4a::memcpyNonAliased16((F32*) tc_strider.get(), (F32*) vf.mTexCoords, num_vertices*2*sizeof(F32));
+ S32 tex_size = (num_vertices*2*sizeof(F32)+0xF) & ~0xF;
+ LLVector4a::memcpyNonAliased16((F32*) tc_strider.get(), (F32*) vf.mTexCoords, tex_size);
}
if (vf.mNormals)
@@ -4982,16 +5031,9 @@ BOOL LLModelPreview::render()
bool upload_skin = mFMP->childGetValue("upload_skin").asBoolean();
bool upload_joints = mFMP->childGetValue("upload_joints").asBoolean();
- bool resetJoints = false;
if ( upload_joints != mLastJointUpdate )
{
- if ( mLastJointUpdate )
- {
- resetJoints = true;
- }
-
mLastJointUpdate = upload_joints;
-
}
for (LLModelLoader::scene::iterator iter = mScene[mPreviewLOD].begin(); iter != mScene[mPreviewLOD].end(); ++iter)
@@ -5053,15 +5095,7 @@ BOOL LLModelPreview::render()
LLRect preview_rect;
- LLFloaterModelWizard* floater_wizard = dynamic_cast<LLFloaterModelWizard*>(mFMP);
- if (floater_wizard)
- {
- preview_rect = floater_wizard->getPreviewRect();
- }
- else
- {
- preview_rect = mFMP->getChildView("preview_panel")->getRect();
- }
+ preview_rect = mFMP->getChildView("preview_panel")->getRect();
F32 aspect = (F32) preview_rect.getWidth()/preview_rect.getHeight();
@@ -5086,6 +5120,11 @@ BOOL LLModelPreview::render()
refresh();
}
+ if (use_shaders)
+ {
+ gObjectPreviewProgram.bind();
+ }
+
gGL.loadIdentity();
gPipeline.enableLightsPreview();
@@ -5111,11 +5150,6 @@ BOOL LLModelPreview::render()
const U32 type_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0;
- if (use_shaders)
- {
- gObjectPreviewProgram.bind();
- }
-
LLGLEnable normalize(GL_NORMALIZE);
if (!mBaseModel.empty() && mVertexBuffer[5].empty())
@@ -5304,7 +5338,7 @@ BOOL LLModelPreview::render()
hull_colors.push_back(LLColor4U(rand()%128+127, rand()%128+127, rand()%128+127, 128));
}
- glColor4ubv(hull_colors[i].mV);
+ gGL.diffuseColor4ubv(hull_colors[i].mV);
LLVertexBuffer::drawArrays(LLRender::TRIANGLES, physics.mMesh[i].mPositions, physics.mMesh[i].mNormals);
if (explode > 0.f)
@@ -5531,6 +5565,15 @@ BOOL LLModelPreview::render()
buffer->setBuffer(type_mask & buffer->getTypeMask());
gGL.diffuseColor4fv(material.mDiffuseColor.mV);
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ if (material.mDiffuseMap.notNull())
+ {
+ if (material.mDiffuseMap->getDiscardLevel() > -1)
+ {
+ gGL.getTexUnit(0)->bind(material.mDiffuseMap, true);
+ mTextureSet.insert(material.mDiffuseMap.get());
+ }
+ }
+
buffer->draw(LLRender::TRIANGLES, buffer->getNumIndices(), 0);
gGL.diffuseColor3f(0.4f, 0.4f, 0.4f);
@@ -5605,7 +5648,6 @@ void LLModelPreview::setPreviewLOD(S32 lod)
combo_box->setCurrentByIndex((NUM_LOD-1)-mPreviewLOD); // combo box list of lods is in reverse order
mFMP->childSetText("lod_file_" + lod_name[mPreviewLOD], mLODFile[mPreviewLOD]);
- // the wizard has three lod drop downs
LLComboBox* combo_box2 = mFMP->getChild<LLComboBox>("preview_lod_combo2");
combo_box2->setCurrentByIndex((NUM_LOD-1)-mPreviewLOD); // combo box list of lods is in reverse order
@@ -5767,6 +5809,12 @@ void LLFloaterModelPreview::onLoDSourceCommit(S32 lod)
{
mModelPreview->updateLodControls(lod);
refresh();
+
+ LLComboBox* lod_source_combo = getChild<LLComboBox>("lod_source_" + lod_name[lod]);
+ if (lod_source_combo->getCurrentIndex() == LLModelPreview::GENERATE)
+ { //rebuild LoD to update triangle counts
+ onLODParamCommit(lod, true);
+ }
}
void LLFloaterModelPreview::resetDisplayOptions()
@@ -5890,3 +5938,5 @@ void LLFloaterModelPreview::setPermissonsErrorStatus(U32 status, const std::stri
LLNotificationsUtil::add("MeshUploadPermError");
}
+
+
diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h
index 64324854a5..e588418f7b 100644..100755
--- a/indra/newview/llfloatermodelpreview.h
+++ b/indra/newview/llfloatermodelpreview.h
@@ -30,12 +30,12 @@
#include "llfloaternamedesc.h"
#include "lldynamictexture.h"
-#include "llfloatermodelwizard.h"
#include "llquaternion.h"
#include "llmeshrepository.h"
#include "llmodel.h"
#include "llthread.h"
#include "llviewermenufile.h"
+#include "llfloatermodeluploadbase.h"
class LLComboBox;
class LLJoint;
@@ -256,7 +256,6 @@ protected:
S32 mLastMouseX;
S32 mLastMouseY;
LLRect mPreviewRect;
- U32 mGLName;
static S32 sUploadAmount;
std::set<LLPointer<DecompRequest> > mCurRequest;
@@ -312,6 +311,15 @@ class LLModelPreview : public LLViewerDynamicTexture, public LLMutex
typedef boost::signals2::signal<void (bool)> model_updated_signal_t;
public:
+
+ typedef enum
+ {
+ LOD_FROM_FILE = 0,
+ GENERATE,
+ USE_LOD_ABOVE,
+ } eLoDMode;
+
+public:
LLModelPreview(S32 width, S32 height, LLFloater* fmp);
virtual ~LLModelPreview();
@@ -390,9 +398,7 @@ private:
protected:
friend class LLModelLoader;
friend class LLFloaterModelPreview;
- friend class LLFloaterModelWizard;
friend class LLFloaterModelPreview::DecompRequest;
- friend class LLFloaterModelWizard::DecompRequest;
friend class LLPhysicsDecomp;
LLFloater* mFMP;
diff --git a/indra/newview/llfloatermodeluploadbase.cpp b/indra/newview/llfloatermodeluploadbase.cpp
index 6d3800bfa4..6d3800bfa4 100644..100755
--- a/indra/newview/llfloatermodeluploadbase.cpp
+++ b/indra/newview/llfloatermodeluploadbase.cpp
diff --git a/indra/newview/llfloatermodeluploadbase.h b/indra/newview/llfloatermodeluploadbase.h
index a52bc28687..a52bc28687 100644..100755
--- a/indra/newview/llfloatermodeluploadbase.h
+++ b/indra/newview/llfloatermodeluploadbase.h
diff --git a/indra/newview/llfloatermodelwizard.cpp b/indra/newview/llfloatermodelwizard.cpp
deleted file mode 100644
index b517b78e5a..0000000000
--- a/indra/newview/llfloatermodelwizard.cpp
+++ /dev/null
@@ -1,795 +0,0 @@
-/**
- * @file llfloatermodelwizard.cpp
- * @author Leyla Farazha
- * @brief Implementation of the LLFloaterModelWizard class.
- *
- * $LicenseInfo:firstyear=2002&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 "llviewerprecompiledheaders.h"
-
-#include "llbutton.h"
-#include "lldrawable.h"
-#include "llcheckboxctrl.h"
-#include "llcombobox.h"
-#include "llfloater.h"
-#include "llfloatermodelwizard.h"
-#include "llfloatermodelpreview.h"
-#include "llfloaterreg.h"
-#include "llsliderctrl.h"
-#include "lltoolmgr.h"
-#include "llviewerwindow.h"
-
-LLFloaterModelWizard* LLFloaterModelWizard::sInstance = NULL;
-
-static const std::string stateNames[]={
- "choose_file",
- "optimize",
- "physics",
- "review",
- "upload"};
-
-static void swap_controls(LLUICtrl* first_ctrl, LLUICtrl* second_ctrl, bool first_ctr_visible);
-
-LLFloaterModelWizard::LLFloaterModelWizard(const LLSD& key)
- : LLFloaterModelUploadBase(key)
- ,mRecalculateGeometryBtn(NULL)
- ,mRecalculatePhysicsBtn(NULL)
- ,mRecalculatingPhysicsBtn(NULL)
- ,mCalculateWeightsBtn(NULL)
- ,mCalculatingWeightsBtn(NULL)
- ,mChooseFilePreviewPanel(NULL)
- ,mOptimizePreviewPanel(NULL)
- ,mPhysicsPreviewPanel(NULL)
-{
- mLastEnabledState = CHOOSE_FILE;
- sInstance = this;
-
- mCommitCallbackRegistrar.add("Wizard.Choose", boost::bind(&LLFloaterModelWizard::setState, this, CHOOSE_FILE));
- mCommitCallbackRegistrar.add("Wizard.Optimize", boost::bind(&LLFloaterModelWizard::setState, this, OPTIMIZE));
- mCommitCallbackRegistrar.add("Wizard.Physics", boost::bind(&LLFloaterModelWizard::setState, this, PHYSICS));
- mCommitCallbackRegistrar.add("Wizard.Review", boost::bind(&LLFloaterModelWizard::setState, this, REVIEW));
- mCommitCallbackRegistrar.add("Wizard.Upload", boost::bind(&LLFloaterModelWizard::setState, this, UPLOAD));
-}
-LLFloaterModelWizard::~LLFloaterModelWizard()
-{
- sInstance = NULL;
-}
-void LLFloaterModelWizard::setState(int state)
-{
-
- mState = state;
-
- for(size_t t=0; t<LL_ARRAY_SIZE(stateNames); ++t)
- {
- LLView *view = getChildView(stateNames[t]+"_panel");
- if (view)
- {
- view->setVisible(state == (int) t ? TRUE : FALSE);
- }
- }
-
- LLView* current_preview_panel = NULL;
-
- if (state == CHOOSE_FILE)
- {
- mModelPreview->mViewOption["show_physics"] = false;
-
- current_preview_panel = mChooseFilePreviewPanel;
-
- getChildView("close")->setVisible(false);
- getChildView("back")->setVisible(true);
- getChildView("back")->setEnabled(false);
- getChildView("next")->setVisible(true);
- getChildView("upload")->setVisible(false);
- getChildView("cancel")->setVisible(true);
- mCalculateWeightsBtn->setVisible(false);
- mCalculatingWeightsBtn->setVisible(false);
- }
-
- if (state == OPTIMIZE)
- {
- if (mLastEnabledState < state)
- {
- mModelPreview->genLODs(-1);
- }
-
- mModelPreview->mViewOption["show_physics"] = false;
-
- current_preview_panel = mOptimizePreviewPanel;
-
- getChildView("back")->setVisible(true);
- getChildView("back")->setEnabled(true);
- getChildView("close")->setVisible(false);
- getChildView("next")->setVisible(true);
- getChildView("upload")->setVisible(false);
- getChildView("cancel")->setVisible(true);
- mCalculateWeightsBtn->setVisible(false);
- mCalculatingWeightsBtn->setVisible(false);
- }
-
- if (state == PHYSICS)
- {
- if (mLastEnabledState < state)
- {
- mModelPreview->setPhysicsFromLOD(1);
-
- // Trigger the recalculate physics when first entering
- // the Physics step.
- onClickRecalculatePhysics();
- }
-
- mModelPreview->mViewOption["show_physics"] = true;
-
- current_preview_panel = mPhysicsPreviewPanel;
-
- getChildView("next")->setVisible(false);
- getChildView("upload")->setVisible(false);
- getChildView("close")->setVisible(false);
- getChildView("back")->setVisible(true);
- getChildView("back")->setEnabled(true);
- getChildView("cancel")->setVisible(true);
- mCalculateWeightsBtn->setVisible(true);
- mCalculatingWeightsBtn->setVisible(false);
- }
-
- if (state == REVIEW)
- {
-
- mModelPreview->mViewOption["show_physics"] = false;
-
- getChildView("close")->setVisible(false);
- getChildView("next")->setVisible(false);
- getChildView("back")->setVisible(true);
- getChildView("back")->setEnabled(true);
- getChildView("upload")->setVisible(true);
- getChildView("cancel")->setVisible(true);
- mCalculateWeightsBtn->setVisible(false);
- mCalculatingWeightsBtn->setVisible(false);
- }
-
- if (state == UPLOAD)
- {
- getChildView("close")->setVisible(true);
- getChildView("next")->setVisible(false);
- getChildView("back")->setVisible(false);
- getChildView("upload")->setVisible(false);
- getChildView("cancel")->setVisible(false);
- mCalculateWeightsBtn->setVisible(false);
- mCalculatingWeightsBtn->setVisible(false);
- }
-
- if (current_preview_panel)
- {
- LLRect rect;
- current_preview_panel->localRectToOtherView(current_preview_panel->getLocalRect(), &rect, this);
-
- // Reduce the preview rect by 1 px to fit the borders
- rect.stretch(-1);
-
- if (rect != mPreviewRect)
- {
- mPreviewRect = rect;
- mModelPreview->refresh();
- }
- }
- updateButtons();
-}
-
-
-
-void LLFloaterModelWizard::updateButtons()
-{
- if (mLastEnabledState < mState)
- {
- mLastEnabledState = mState;
- }
-
- for(size_t i=0; i<LL_ARRAY_SIZE(stateNames); ++i)
- {
- LLButton *button = getChild<LLButton>(stateNames[i]+"_btn");
-
- if (i == mState)
- {
- button->setEnabled(TRUE);
- button->setToggleState(TRUE);
- }
- else if (i <= mLastEnabledState)
- {
- button->setEnabled(TRUE);
- button->setToggleState(FALSE);
- }
- else
- {
- button->setEnabled(FALSE);
- }
- }
-}
-
-void LLFloaterModelWizard::onClickSwitchToAdvanced()
-{
- LLFloaterModelPreview* floater_preview = LLFloaterReg::getTypedInstance<LLFloaterModelPreview>("upload_model");
- if (!floater_preview)
- {
- llwarns << "FLoater model preview not found." << llendl;
- return;
- }
-
- // Open floater model preview
- floater_preview->openFloater();
-
- // Close the wizard
- closeFloater();
-
- std::string filename = getChild<LLUICtrl>("lod_file")->getValue().asString();
- if (!filename.empty())
- {
- // Re-load the model to the floater model preview if it has been loaded
- // into the wizard.
- floater_preview->loadModel(3, filename);
- }
-}
-
-void LLFloaterModelWizard::onClickRecalculateGeometry()
-{
- S32 val = getChild<LLUICtrl>("accuracy_slider")->getValue().asInteger();
-
- mModelPreview->genLODs(-1, NUM_LOD - val);
-
- mModelPreview->refresh();
-}
-
-void LLFloaterModelWizard::onClickRecalculatePhysics()
-{
- // Hide the "Recalculate physics" button and show the "Recalculating..."
- // button instead.
- swap_controls(mRecalculatePhysicsBtn, mRecalculatingPhysicsBtn, false);
-
- executePhysicsStage("Decompose");
-}
-
-void LLFloaterModelWizard::onClickCalculateUploadFee()
-{
- swap_controls(mCalculateWeightsBtn, mCalculatingWeightsBtn, false);
-
- mModelPreview->rebuildUploadData();
-
- mUploadModelUrl.clear();
-
- gMeshRepo.uploadModel(mModelPreview->mUploadData, mModelPreview->mPreviewScale,
- true, false, false, mUploadModelUrl, false, getWholeModelFeeObserverHandle());
-}
-
-void LLFloaterModelWizard::loadModel()
-{
- mModelPreview->mLoading = TRUE;
-
- (new LLMeshFilePicker(mModelPreview, 3))->getFile();
-}
-
-void LLFloaterModelWizard::onClickCancel()
-{
- closeFloater();
-}
-
-void LLFloaterModelWizard::onClickBack()
-{
- setState(llmax((int) CHOOSE_FILE, mState-1));
-}
-
-void LLFloaterModelWizard::onClickNext()
-{
- setState(llmin((int) UPLOAD, mState+1));
-}
-
-bool LLFloaterModelWizard::onEnableNext()
-{
- return true;
-}
-
-bool LLFloaterModelWizard::onEnableBack()
-{
- return true;
-}
-
-
-//-----------------------------------------------------------------------------
-// handleMouseDown()
-//-----------------------------------------------------------------------------
-BOOL LLFloaterModelWizard::handleMouseDown(S32 x, S32 y, MASK mask)
-{
- if (mPreviewRect.pointInRect(x, y))
- {
- bringToFront( x, y );
- gFocusMgr.setMouseCapture(this);
- gViewerWindow->hideCursor();
- mLastMouseX = x;
- mLastMouseY = y;
- return TRUE;
- }
-
- return LLFloater::handleMouseDown(x, y, mask);
-}
-
-//-----------------------------------------------------------------------------
-// handleMouseUp()
-//-----------------------------------------------------------------------------
-BOOL LLFloaterModelWizard::handleMouseUp(S32 x, S32 y, MASK mask)
-{
- gFocusMgr.setMouseCapture(FALSE);
- gViewerWindow->showCursor();
- return LLFloater::handleMouseUp(x, y, mask);
-}
-
-//-----------------------------------------------------------------------------
-// handleHover()
-//-----------------------------------------------------------------------------
-BOOL LLFloaterModelWizard::handleHover (S32 x, S32 y, MASK mask)
-{
- MASK local_mask = mask & ~MASK_ALT;
-
- if (mModelPreview && hasMouseCapture())
- {
- if (local_mask == MASK_PAN)
- {
- // pan here
- mModelPreview->pan((F32)(x - mLastMouseX) * -0.005f, (F32)(y - mLastMouseY) * -0.005f);
- }
- else if (local_mask == MASK_ORBIT)
- {
- F32 yaw_radians = (F32)(x - mLastMouseX) * -0.01f;
- F32 pitch_radians = (F32)(y - mLastMouseY) * 0.02f;
-
- mModelPreview->rotate(yaw_radians, pitch_radians);
- }
- else
- {
-
- F32 yaw_radians = (F32)(x - mLastMouseX) * -0.01f;
- F32 zoom_amt = (F32)(y - mLastMouseY) * 0.02f;
-
- mModelPreview->rotate(yaw_radians, 0.f);
- mModelPreview->zoom(zoom_amt);
- }
-
-
- mModelPreview->refresh();
-
- LLUI::setMousePositionLocal(this, mLastMouseX, mLastMouseY);
- }
-
- if (!mPreviewRect.pointInRect(x, y) || !mModelPreview)
- {
- return LLFloater::handleHover(x, y, mask);
- }
- else if (local_mask == MASK_ORBIT)
- {
- gViewerWindow->setCursor(UI_CURSOR_TOOLCAMERA);
- }
- else if (local_mask == MASK_PAN)
- {
- gViewerWindow->setCursor(UI_CURSOR_TOOLPAN);
- }
- else
- {
- gViewerWindow->setCursor(UI_CURSOR_TOOLZOOMIN);
- }
-
- return TRUE;
-}
-
-//-----------------------------------------------------------------------------
-// handleScrollWheel()
-//-----------------------------------------------------------------------------
-BOOL LLFloaterModelWizard::handleScrollWheel(S32 x, S32 y, S32 clicks)
-{
- if (mPreviewRect.pointInRect(x, y) && mModelPreview)
- {
- mModelPreview->zoom((F32)clicks * -0.2f);
- mModelPreview->refresh();
- }
-
- return TRUE;
-}
-
-
-void LLFloaterModelWizard::initDecompControls()
-{
- LLSD key;
-
- static const LLCDStageData* stage = NULL;
- static S32 stage_count = 0;
-
- if (!stage && LLConvexDecomposition::getInstance() != NULL)
- {
- stage_count = LLConvexDecomposition::getInstance()->getStages(&stage);
- }
-
- static const LLCDParam* param = NULL;
- static S32 param_count = 0;
- if (!param && LLConvexDecomposition::getInstance() != NULL)
- {
- param_count = LLConvexDecomposition::getInstance()->getParameters(&param);
- }
-
- for (S32 j = stage_count-1; j >= 0; --j)
- {
- gMeshRepo.mDecompThread->mStageID[stage[j].mName] = j;
- // protected against stub by stage_count being 0 for stub above
- LLConvexDecomposition::getInstance()->registerCallback(j, LLPhysicsDecomp::llcdCallback);
-
- for (S32 i = 0; i < param_count; ++i)
- {
- if (param[i].mStage != j)
- {
- continue;
- }
-
- std::string name(param[i].mName ? param[i].mName : "");
- std::string description(param[i].mDescription ? param[i].mDescription : "");
-
- if (param[i].mType == LLCDParam::LLCD_FLOAT)
- {
- mDecompParams[param[i].mName] = LLSD(param[i].mDefault.mFloat);
- }
- else if (param[i].mType == LLCDParam::LLCD_INTEGER)
- {
- mDecompParams[param[i].mName] = LLSD(param[i].mDefault.mIntOrEnumValue);
- }
- else if (param[i].mType == LLCDParam::LLCD_BOOLEAN)
- {
- mDecompParams[param[i].mName] = LLSD(param[i].mDefault.mBool);
- }
- else if (param[i].mType == LLCDParam::LLCD_ENUM)
- {
- mDecompParams[param[i].mName] = LLSD(param[i].mDefault.mIntOrEnumValue);
- }
- }
- }
-
- mDecompParams["Simplify Method"] = 0; // set it to retain %
-}
-
-/*virtual*/
-void LLFloaterModelWizard::onPermissionsReceived(const LLSD& result)
-{
- std::string upload_status = result["mesh_upload_status"].asString();
- // BAP HACK: handle "" for case that MeshUploadFlag cap is broken.
- mHasUploadPerm = (("" == upload_status) || ("valid" == upload_status));
-
- getChildView("warning_label")->setVisible(!mHasUploadPerm);
- getChildView("warning_text")->setVisible(!mHasUploadPerm);
-}
-
-/*virtual*/
-void LLFloaterModelWizard::setPermissonsErrorStatus(U32 status, const std::string& reason)
-{
- llwarns << "LLFloaterModelWizard::setPermissonsErrorStatus(" << status << " : " << reason << ")" << llendl;
-}
-
-/*virtual*/
-void LLFloaterModelWizard::onModelPhysicsFeeReceived(const LLSD& result, std::string upload_url)
-{
- swap_controls(mCalculateWeightsBtn, mCalculatingWeightsBtn, true);
-
- // Enable the "Upload" buton if we have calculated the upload fee
- // and have the permission to upload.
- getChildView("upload")->setEnabled(mHasUploadPerm);
-
- mUploadModelUrl = upload_url;
-
- S32 fee = result["upload_price"].asInteger();
- childSetTextArg("review_fee", "[FEE]", llformat("%d", fee));
- childSetTextArg("charged_fee", "[FEE]", llformat("%d", fee));
-
- setState(REVIEW);
-}
-
-/*virtual*/
-void LLFloaterModelWizard::setModelPhysicsFeeErrorStatus(U32 status, const std::string& reason)
-{
- swap_controls(mCalculateWeightsBtn, mCalculatingWeightsBtn, true);
-
- // Disable the "Review" step if it has been previously enabled.
- modelChangedCallback();
-
- llwarns << "LLFloaterModelWizard::setModelPhysicsFeeErrorStatus(" << status << " : " << reason << ")" << llendl;
-
- setState(PHYSICS);
-}
-
-/*virtual*/
-void LLFloaterModelWizard::onModelUploadSuccess()
-{
- // success!
- setState(UPLOAD);
-}
-
-/*virtual*/
-void LLFloaterModelWizard::onModelUploadFailure()
-{
- // Failure. Make the user recalculate fees
- setState(PHYSICS);
- // Disable the "Review" step if it has been previously enabled.
- if (mLastEnabledState > PHYSICS)
- {
- mLastEnabledState = PHYSICS;
- }
-
- updateButtons();
-}
-
-//static
-void LLFloaterModelWizard::executePhysicsStage(std::string stage_name)
-{
- if (sInstance)
- {
- // Invert the slider value so that "performance" end is giving the least detailed physics,
- // and the "accuracy" end is giving the most detailed physics
- F64 physics_accuracy = 1 - sInstance->getChild<LLSliderCtrl>("physics_slider")->getValue().asReal();
-
- sInstance->mDecompParams["Retain%"] = physics_accuracy;
-
- if (!sInstance->mCurRequest.empty())
- {
- llinfos << "Decomposition request still pending." << llendl;
- return;
- }
-
- if (sInstance->mModelPreview)
- {
- for (S32 i = 0; i < sInstance->mModelPreview->mModel[LLModel::LOD_PHYSICS].size(); ++i)
- {
- LLModel* mdl = sInstance->mModelPreview->mModel[LLModel::LOD_PHYSICS][i];
- DecompRequest* request = new DecompRequest(stage_name, mdl);
- if(request->isValid())
- {
- sInstance->mCurRequest.insert(request);
- gMeshRepo.mDecompThread->submitRequest(request);
- }
- }
- }
- }
-}
-
-LLFloaterModelWizard::DecompRequest::DecompRequest(const std::string& stage, LLModel* mdl)
-{
- mStage = stage;
- mContinue = 1;
- mModel = mdl;
- mDecompID = &mdl->mDecompID;
- mParams = sInstance->mDecompParams;
-
- //copy out positions and indices
- assignData(mdl) ;
-}
-
-
-S32 LLFloaterModelWizard::DecompRequest::statusCallback(const char* status, S32 p1, S32 p2)
-{
- setStatusMessage(llformat("%s: %d/%d", status, p1, p2));
-
- return mContinue;
-}
-
-void LLFloaterModelWizard::DecompRequest::completed()
-{ //called from the main thread
- mModel->setConvexHullDecomposition(mHull);
-
- if (sInstance)
- {
- if (sInstance->mModelPreview)
- {
- sInstance->mModelPreview->mDirty = true;
- LLFloaterModelWizard::sInstance->mModelPreview->refresh();
- }
-
- sInstance->mCurRequest.erase(this);
- }
-
- if (mStage == "Decompose")
- {
- executePhysicsStage("Simplify");
- }
- else
- {
- // Decomp request is complete so we can enable the "Recalculate physics" button again.
- swap_controls(sInstance->mRecalculatePhysicsBtn, sInstance->mRecalculatingPhysicsBtn, true);
- }
-}
-
-
-BOOL LLFloaterModelWizard::postBuild()
-{
- childSetValue("import_scale", (F32) 0.67335826);
-
- getChild<LLUICtrl>("browse")->setCommitCallback(boost::bind(&LLFloaterModelWizard::loadModel, this));
- //getChild<LLUICtrl>("lod_file")->setCommitCallback(boost::bind(&LLFloaterModelWizard::loadModel, this));
- getChild<LLUICtrl>("cancel")->setCommitCallback(boost::bind(&LLFloaterModelWizard::onClickCancel, this));
- getChild<LLUICtrl>("close")->setCommitCallback(boost::bind(&LLFloaterModelWizard::onClickCancel, this));
- getChild<LLUICtrl>("back")->setCommitCallback(boost::bind(&LLFloaterModelWizard::onClickBack, this));
- getChild<LLUICtrl>("next")->setCommitCallback(boost::bind(&LLFloaterModelWizard::onClickNext, this));
- getChild<LLUICtrl>("preview_lod_combo")->setCommitCallback(boost::bind(&LLFloaterModelWizard::onPreviewLODCommit, this, _1));
- getChild<LLUICtrl>("preview_lod_combo2")->setCommitCallback(boost::bind(&LLFloaterModelWizard::onPreviewLODCommit, this, _1));
- getChild<LLUICtrl>("upload")->setCommitCallback(boost::bind(&LLFloaterModelWizard::onUpload, this));
- getChild<LLUICtrl>("switch_to_advanced")->setCommitCallback(boost::bind(&LLFloaterModelWizard::onClickSwitchToAdvanced, this));
-
- mRecalculateGeometryBtn = getChild<LLButton>("recalculate_geometry_btn");
- mRecalculateGeometryBtn->setCommitCallback(boost::bind(&LLFloaterModelWizard::onClickRecalculateGeometry, this));
-
- mRecalculatePhysicsBtn = getChild<LLButton>("recalculate_physics_btn");
- mRecalculatePhysicsBtn->setCommitCallback(boost::bind(&LLFloaterModelWizard::onClickRecalculatePhysics, this));
-
- mRecalculatingPhysicsBtn = getChild<LLButton>("recalculating_physics_btn");
-
- mCalculateWeightsBtn = getChild<LLButton>("calculate");
- mCalculateWeightsBtn->setCommitCallback(boost::bind(&LLFloaterModelWizard::onClickCalculateUploadFee, this));
-
- mCalculatingWeightsBtn = getChild<LLButton>("calculating");
-
- mChooseFilePreviewPanel = getChild<LLView>("choose_file_preview_panel");
- mOptimizePreviewPanel = getChild<LLView>("optimize_preview_panel");
- mPhysicsPreviewPanel = getChild<LLView>("physics_preview_panel");
-
- LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
-
- enable_registrar.add("Next.OnEnable", boost::bind(&LLFloaterModelWizard::onEnableNext, this));
- enable_registrar.add("Back.OnEnable", boost::bind(&LLFloaterModelWizard::onEnableBack, this));
-
- mModelPreview = new LLModelPreview(512, 512, this);
- mModelPreview->setPreviewTarget(16.f);
- mModelPreview->setDetailsCallback(boost::bind(&LLFloaterModelWizard::setDetails, this, _1, _2, _3, _4, _5));
- mModelPreview->setModelLoadedCallback(boost::bind(&LLFloaterModelWizard::modelLoadedCallback, this));
- mModelPreview->setModelUpdatedCallback(boost::bind(&LLFloaterModelWizard::modelChangedCallback, this));
- mModelPreview->mViewOption["show_textures"] = true;
-
- center();
-
- setState(CHOOSE_FILE);
-
- childSetTextArg("import_dimensions", "[X]", LLStringUtil::null);
- childSetTextArg("import_dimensions", "[Y]", LLStringUtil::null);
- childSetTextArg("import_dimensions", "[Z]", LLStringUtil::null);
-
- initDecompControls();
-
- requestAgentUploadPermissions();
-
- return TRUE;
-}
-
-
-void LLFloaterModelWizard::setDetails(F32 x, F32 y, F32 z, F32 streaming_cost, F32 physics_cost)
-{
- // iterate through all the panels, setting the dimensions
- for(size_t t=0; t<LL_ARRAY_SIZE(stateNames); ++t)
- {
- LLPanel *panel = getChild<LLPanel>(stateNames[t]+"_panel");
- if (panel)
- {
- panel->childSetText("dimension_x", llformat("%.1f", x));
- panel->childSetText("dimension_y", llformat("%.1f", y));
- panel->childSetText("dimension_z", llformat("%.1f", z));
- }
- }
-
- childSetTextArg("review_prim_equiv", "[EQUIV]", llformat("%d", mModelPreview->mResourceCost));
-}
-
-void LLFloaterModelWizard::modelLoadedCallback()
-{
- mLastEnabledState = CHOOSE_FILE;
- updateButtons();
-}
-
-void LLFloaterModelWizard::modelChangedCallback()
-{
- // Don't allow to proceed to the "Review" step if the model has changed
- // but the new upload fee hasn't been calculated yet.
- if (mLastEnabledState > PHYSICS)
- {
- mLastEnabledState = PHYSICS;
- }
-
- getChildView("upload")->setEnabled(false);
-
- updateButtons();
-}
-
-void LLFloaterModelWizard::onUpload()
-{
- mModelPreview->rebuildUploadData();
-
- gMeshRepo.uploadModel(mModelPreview->mUploadData, mModelPreview->mPreviewScale,
- true, false, false, mUploadModelUrl, true,
- LLHandle<LLWholeModelFeeObserver>(), getWholeModelUploadObserverHandle());
-}
-
-void LLFloaterModelWizard::onPreviewLODCommit(LLUICtrl* ctrl)
-{
- if (!mModelPreview)
- {
- return;
- }
-
- S32 which_mode = 0;
-
- LLComboBox* combo = (LLComboBox*) ctrl;
-
- which_mode = (NUM_LOD-1)-combo->getFirstSelectedIndex(); // combo box list of lods is in reverse order
-
- mModelPreview->setPreviewLOD(which_mode);
-}
-
-void LLFloaterModelWizard::refresh()
-{
- if (mState == CHOOSE_FILE)
- {
- bool model_loaded = false;
-
- if (mModelPreview && mModelPreview->getLoadState() == LLModelLoader::DONE)
- {
- model_loaded = true;
- }
-
- getChildView("next")->setEnabled(model_loaded);
- }
-}
-
-void LLFloaterModelWizard::draw()
-{
- refresh();
-
- LLFloater::draw();
-
- if (mModelPreview && mState < REVIEW)
- {
- mModelPreview->update();
-
- gGL.color3f(1.f, 1.f, 1.f);
-
- gGL.getTexUnit(0)->bind(mModelPreview);
-
- gGL.begin( LLRender::QUADS );
- {
- gGL.texCoord2f(0.f, 1.f);
- gGL.vertex2i(mPreviewRect.mLeft, mPreviewRect.mTop);
- gGL.texCoord2f(0.f, 0.f);
- gGL.vertex2i(mPreviewRect.mLeft, mPreviewRect.mBottom);
- gGL.texCoord2f(1.f, 0.f);
- gGL.vertex2i(mPreviewRect.mRight, mPreviewRect.mBottom);
- gGL.texCoord2f(1.f, 1.f);
- gGL.vertex2i(mPreviewRect.mRight, mPreviewRect.mTop);
- }
- gGL.end();
-
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- }
-}
-
-// static
-void swap_controls(LLUICtrl* first_ctrl, LLUICtrl* second_ctrl, bool first_ctr_visible)
-{
- first_ctrl->setVisible(first_ctr_visible);
- second_ctrl->setVisible(!first_ctr_visible);
-}
diff --git a/indra/newview/llfloatermodelwizard.h b/indra/newview/llfloatermodelwizard.h
deleted file mode 100644
index db9b605777..0000000000
--- a/indra/newview/llfloatermodelwizard.h
+++ /dev/null
@@ -1,140 +0,0 @@
-/**
- * @file llfloatermodelwizard.h
- *
- * $LicenseInfo:firstyear=2009&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$
- */
-
-#ifndef LLFLOATERMODELWIZARD_H
-#define LLFLOATERMODELWIZARD_H
-
-
-#include "llmeshrepository.h"
-#include "llmodel.h"
-#include "llthread.h"
-#include "llfloatermodeluploadbase.h"
-
-
-class LLModelPreview;
-
-
-class LLFloaterModelWizard : public LLFloaterModelUploadBase
-{
-public:
-
- class DecompRequest : public LLPhysicsDecomp::Request
- {
- public:
- S32 mContinue;
- LLPointer<LLModel> mModel;
-
- DecompRequest(const std::string& stage, LLModel* mdl);
- virtual S32 statusCallback(const char* status, S32 p1, S32 p2);
- virtual void completed();
-
- };
-
- static LLFloaterModelWizard* sInstance;
-
- LLFloaterModelWizard(const LLSD& key);
- virtual ~LLFloaterModelWizard();
- /*virtual*/ BOOL postBuild();
- void draw();
- void refresh();
-
- BOOL handleMouseDown(S32 x, S32 y, MASK mask);
- BOOL handleMouseUp(S32 x, S32 y, MASK mask);
- BOOL handleHover(S32 x, S32 y, MASK mask);
- BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
-
- void setDetails(F32 x, F32 y, F32 z, F32 streaming_cost, F32 physics_cost);
- void modelLoadedCallback();
- void modelChangedCallback();
- void initDecompControls();
-
- // shows warning message if agent has no permissions to upload model
- /*virtual*/ void onPermissionsReceived(const LLSD& result);
-
- // called when error occurs during permissions request
- /*virtual*/ void setPermissonsErrorStatus(U32 status, const std::string& reason);
-
- /*virtual*/ void onModelPhysicsFeeReceived(const LLSD& result, std::string upload_url);
-
- /*virtual*/ void setModelPhysicsFeeErrorStatus(U32 status, const std::string& reason);
-
- /*virtual*/ void onModelUploadSuccess();
-
- /*virtual*/ void onModelUploadFailure();
-
- const LLRect& getPreviewRect() const { return mPreviewRect; }
-
- LLPhysicsDecomp::decomp_params mDecompParams;
- std::set<LLPointer<DecompRequest> > mCurRequest;
- std::string mStatusMessage;
- static void executePhysicsStage(std::string stage_name);
-
-private:
- enum EWizardState
- {
- CHOOSE_FILE = 0,
- OPTIMIZE,
- PHYSICS,
- REVIEW,
- UPLOAD
- };
-
- void setState(int state);
- void updateButtons();
- void onClickSwitchToAdvanced();
- void onClickRecalculateGeometry();
- void onClickRecalculatePhysics();
- void onClickCalculateUploadFee();
- void onClickCancel();
- void onClickBack();
- void onClickNext();
- bool onEnableNext();
- bool onEnableBack();
- void loadModel();
- void onPreviewLODCommit(LLUICtrl*);
- void onUpload();
-
- LLModelPreview* mModelPreview;
- LLRect mPreviewRect;
- int mState;
-
- S32 mLastMouseX;
- S32 mLastMouseY;
-
- U32 mLastEnabledState;
-
- LLButton* mRecalculateGeometryBtn;
- LLButton* mRecalculatePhysicsBtn;
- LLButton* mRecalculatingPhysicsBtn;
- LLButton* mCalculateWeightsBtn;
- LLButton* mCalculatingWeightsBtn;
-
- LLView* mChooseFilePreviewPanel;
- LLView* mOptimizePreviewPanel;
- LLView* mPhysicsPreviewPanel;
-};
-
-
-#endif
diff --git a/indra/newview/llfloaternamedesc.cpp b/indra/newview/llfloaternamedesc.cpp
index ee7f413a59..ee7f413a59 100644..100755
--- a/indra/newview/llfloaternamedesc.cpp
+++ b/indra/newview/llfloaternamedesc.cpp
diff --git a/indra/newview/llfloaternamedesc.h b/indra/newview/llfloaternamedesc.h
index 41643681ac..41643681ac 100644..100755
--- a/indra/newview/llfloaternamedesc.h
+++ b/indra/newview/llfloaternamedesc.h
diff --git a/indra/newview/llfloaternotificationsconsole.cpp b/indra/newview/llfloaternotificationsconsole.cpp
index 2681d4b34d..4f35c325a8 100644..100755
--- a/indra/newview/llfloaternotificationsconsole.cpp
+++ b/indra/newview/llfloaternotificationsconsole.cpp
@@ -44,21 +44,16 @@ public:
BOOL postBuild();
private:
- bool update(const LLSD& payload, bool passed_filter);
+ bool update(const LLSD& payload);
static void toggleClick(void* user_data);
static void onClickNotification(void* user_data);
- static void onClickNotificationReject(void* user_data);
LLNotificationChannelPtr mChannelPtr;
- LLNotificationChannelPtr mChannelRejectsPtr;
};
LLNotificationChannelPanel::LLNotificationChannelPanel(const LLNotificationChannelPanel::Params& p)
: LLLayoutPanel(p)
{
mChannelPtr = LLNotifications::instance().getChannel(p.name);
- mChannelRejectsPtr = LLNotificationChannelPtr(
- LLNotificationChannel::buildChannel(p.name() + "rejects", mChannelPtr->getParentChannelName(),
- !boost::bind(mChannelPtr->getFilter(), _1)));
buildFromFile( "panel_notifications_channel.xml");
}
@@ -68,15 +63,11 @@ BOOL LLNotificationChannelPanel::postBuild()
header_button->setLabel(mChannelPtr->getName());
header_button->setClickedCallback(toggleClick, this);
- mChannelPtr->connectChanged(boost::bind(&LLNotificationChannelPanel::update, this, _1, true));
- mChannelRejectsPtr->connectChanged(boost::bind(&LLNotificationChannelPanel::update, this, _1, false));
+ mChannelPtr->connectChanged(boost::bind(&LLNotificationChannelPanel::update, this, _1));
LLScrollListCtrl* scroll = getChild<LLScrollListCtrl>("notifications_list");
scroll->setDoubleClickCallback(onClickNotification, this);
scroll->setRect(LLRect( getRect().mLeft, getRect().mTop, getRect().mRight, 0));
- scroll = getChild<LLScrollListCtrl>("notification_rejects_list");
- scroll->setDoubleClickCallback(onClickNotificationReject, this);
- scroll->setRect(LLRect( getRect().mLeft, getRect().mTop, getRect().mRight, 0));
return TRUE;
}
@@ -97,8 +88,6 @@ void LLNotificationChannelPanel::toggleClick(void *user_data)
// turn off tab stop for collapsed panel
self->getChild<LLScrollListCtrl>("notifications_list")->setTabStop(!header_button->getToggleState());
self->getChild<LLScrollListCtrl>("notifications_list")->setVisible(!header_button->getToggleState());
- self->getChild<LLScrollListCtrl>("notification_rejects_list")->setTabStop(!header_button->getToggleState());
- self->getChild<LLScrollListCtrl>("notification_rejects_list")->setVisible(!header_button->getToggleState());
}
/*static*/
@@ -118,24 +107,7 @@ void LLNotificationChannelPanel::onClickNotification(void* user_data)
}
}
-/*static*/
-void LLNotificationChannelPanel::onClickNotificationReject(void* user_data)
-{
- LLNotificationChannelPanel* self = (LLNotificationChannelPanel*)user_data;
- if (!self) return;
- LLScrollListItem* firstselected = self->getChild<LLScrollListCtrl>("notification_rejects_list")->getFirstSelected();
- llassert(firstselected);
- if (firstselected)
- {
- void* data = firstselected->getUserdata();
- if (data)
- {
- gFloaterView->getParentFloater(self)->addDependentFloater(new LLFloaterNotification((LLNotification*)data), TRUE);
- }
- }
-}
-
-bool LLNotificationChannelPanel::update(const LLSD& payload, bool passed_filter)
+bool LLNotificationChannelPanel::update(const LLSD& payload)
{
LLNotificationPtr notification = LLNotifications::instance().find(payload["id"].asUUID());
if (notification)
@@ -151,9 +123,7 @@ bool LLNotificationChannelPanel::update(const LLSD& payload, bool passed_filter)
row["columns"][2]["column"] = "date";
row["columns"][2]["type"] = "date";
- LLScrollListItem* sli = passed_filter ?
- getChild<LLScrollListCtrl>("notifications_list")->addElement(row) :
- getChild<LLScrollListCtrl>("notification_rejects_list")->addElement(row);
+ LLScrollListItem* sli = getChild<LLScrollListCtrl>("notifications_list")->addElement(row);
sli->setUserdata(&(*notification));
}
diff --git a/indra/newview/llfloaternotificationsconsole.h b/indra/newview/llfloaternotificationsconsole.h
index 4e92b7d857..4e92b7d857 100644..100755
--- a/indra/newview/llfloaternotificationsconsole.h
+++ b/indra/newview/llfloaternotificationsconsole.h
diff --git a/indra/newview/llfloaterobjectweights.cpp b/indra/newview/llfloaterobjectweights.cpp
index 0862cd2897..0862cd2897 100644..100755
--- a/indra/newview/llfloaterobjectweights.cpp
+++ b/indra/newview/llfloaterobjectweights.cpp
diff --git a/indra/newview/llfloaterobjectweights.h b/indra/newview/llfloaterobjectweights.h
index 9a244573be..9a244573be 100644..100755
--- a/indra/newview/llfloaterobjectweights.h
+++ b/indra/newview/llfloaterobjectweights.h
diff --git a/indra/newview/llfloateropenobject.cpp b/indra/newview/llfloateropenobject.cpp
index 4bfef8b45f..4bfef8b45f 100644..100755
--- a/indra/newview/llfloateropenobject.cpp
+++ b/indra/newview/llfloateropenobject.cpp
diff --git a/indra/newview/llfloateropenobject.h b/indra/newview/llfloateropenobject.h
index bf7fe69c65..bf7fe69c65 100644..100755
--- a/indra/newview/llfloateropenobject.h
+++ b/indra/newview/llfloateropenobject.h
diff --git a/indra/newview/llfloateroutbox.cpp b/indra/newview/llfloateroutbox.cpp
index 540f977305..29a3e6ac3a 100644..100755
--- a/indra/newview/llfloateroutbox.cpp
+++ b/indra/newview/llfloateroutbox.cpp
@@ -44,14 +44,17 @@
#include "llviewernetwork.h"
#include "llwindowshade.h"
-#define USE_WINDOWSHADE_DIALOGS 0
-
///----------------------------------------------------------------------------
/// LLOutboxNotification class
///----------------------------------------------------------------------------
-bool LLNotificationsUI::LLOutboxNotification::processNotification(const LLSD& notify)
+LLNotificationsUI::LLOutboxNotification::LLOutboxNotification()
+ : LLSystemNotificationHandler("Outbox", "outbox")
+{
+}
+
+bool LLNotificationsUI::LLOutboxNotification::processNotification(const LLNotificationPtr& notify)
{
LLFloaterOutbox* outbox_floater = LLFloaterReg::getTypedInstance<LLFloaterOutbox>("outbox");
@@ -60,6 +63,14 @@ bool LLNotificationsUI::LLOutboxNotification::processNotification(const LLSD& no
return false;
}
+void LLNotificationsUI::LLOutboxNotification::onDelete(LLNotificationPtr p)
+{
+ LLNotificationsUI::LLNotificationHandler * notification_handler = dynamic_cast<LLNotificationsUI::LLNotificationHandler*>(LLNotifications::instance().getChannel("AlertModal").get());
+ if (notification_handler)
+ {
+ notification_handler->onDelete(p);
+ }
+}
///----------------------------------------------------------------------------
/// LLOutboxAddedObserver helper class
@@ -168,9 +179,8 @@ void LLFloaterOutbox::onOpen(const LLSD& key)
if (mOutboxId.isNull())
{
const bool do_not_create_folder = false;
- const bool do_not_find_in_library = false;
- const LLUUID outbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, do_not_create_folder, do_not_find_in_library);
+ const LLUUID outbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, do_not_create_folder);
if (outbox_id.isNull())
{
@@ -244,8 +254,9 @@ void LLFloaterOutbox::setupOutbox(const LLUUID& outboxId)
mOutboxInventoryPanel->setShape(inventory_placeholder_rect);
// Set the sort order newest to oldest
- mOutboxInventoryPanel->setSortOrder(LLInventoryFilter::SO_FOLDERS_BY_NAME);
- mOutboxInventoryPanel->getFilter()->markDefault();
+
+ mOutboxInventoryPanel->getFolderViewModel()->setSorter(LLInventoryFilter::SO_FOLDERS_BY_NAME);
+ mOutboxInventoryPanel->getFilter().markDefault();
fetchOutboxContents();
@@ -380,7 +391,7 @@ BOOL LLFloaterOutbox::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
// Determine if the mouse is inside the inventory panel itself or just within the floater
bool pointInInventoryPanel = false;
bool pointInInventoryPanelChild = false;
- LLFolderView * root_folder = mOutboxInventoryPanel->getRootFolder();
+ LLFolderView* root_folder = mOutboxInventoryPanel->getRootFolder();
if (mOutboxInventoryPanel->getVisible())
{
S32 inv_x, inv_y;
@@ -437,10 +448,10 @@ void LLFloaterOutbox::onOutboxChanged()
{
llassert(!mOutboxId.isNull());
- if (mOutboxInventoryPanel)
- {
- mOutboxInventoryPanel->requestSort();
- }
+ //if (mOutboxInventoryPanel)
+ //{
+ // mOutboxInventoryPanel->requestSort();
+ //}
fetchOutboxContents();
@@ -516,52 +527,11 @@ void LLFloaterOutbox::initializationReportError(U32 status, const LLSD& content)
updateView();
}
-void LLFloaterOutbox::showNotification(const LLSD& notify)
+void LLFloaterOutbox::showNotification(const LLNotificationPtr& notification)
{
- LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID());
-
- if (!notification)
- {
- llerrs << "Unable to find outbox notification!" << notify.asString() << llendl;
-
- return;
- }
-
-#if USE_WINDOWSHADE_DIALOGS
-
- if (mWindowShade)
- {
- delete mWindowShade;
- }
-
- LLRect floater_rect = getLocalRect();
- floater_rect.mTop -= getHeaderHeight();
- floater_rect.stretch(-5, 0);
-
- LLWindowShade::Params params;
- params.name = "notification_shade";
- params.rect = floater_rect;
- params.follows.flags = FOLLOWS_ALL;
- params.modal = true;
- params.can_close = false;
- params.shade_color = LLColor4::white % 0.25f;
- params.text_color = LLColor4::white;
-
- mWindowShade = LLUICtrlFactory::create<LLWindowShade>(params);
-
- addChild(mWindowShade);
- mWindowShade->show(notification);
-
-#else
-
- LLNotificationsUI::LLEventHandler * handler =
- LLNotificationsUI::LLNotificationManager::instance().getHandlerForNotification("alertmodal");
-
- LLNotificationsUI::LLSysHandler * sys_handler = dynamic_cast<LLNotificationsUI::LLSysHandler *>(handler);
- llassert(sys_handler);
-
- sys_handler->processNotification(notify);
+ LLNotificationsUI::LLNotificationHandler * notification_handler = dynamic_cast<LLNotificationsUI::LLNotificationHandler*>(LLNotifications::instance().getChannel("AlertModal").get());
+ llassert(notification_handler);
-#endif
+ notification_handler->processNotification(notification);
}
diff --git a/indra/newview/llfloateroutbox.h b/indra/newview/llfloateroutbox.h
index 18baccf1c9..a91d8c1139 100644..100755
--- a/indra/newview/llfloateroutbox.h
+++ b/indra/newview/llfloateroutbox.h
@@ -64,7 +64,7 @@ public:
EAcceptance* accept,
std::string& tooltip_msg);
- void showNotification(const LLSD& notify);
+ void showNotification(const LLNotificationPtr& notification);
BOOL handleHover(S32 x, S32 y, MASK mask);
void onMouseLeave(S32 x, S32 y, MASK mask);
diff --git a/indra/newview/llfloaterpathfindingcharacters.cpp b/indra/newview/llfloaterpathfindingcharacters.cpp
new file mode 100755
index 0000000000..69c9d94dfa
--- /dev/null
+++ b/indra/newview/llfloaterpathfindingcharacters.cpp
@@ -0,0 +1,326 @@
+/**
+* @file llfloaterpathfindingcharacters.cpp
+* @brief "Pathfinding characters" floater, allowing for identification of pathfinding characters and their cpu usage.
+* @author Stinson@lindenlab.com
+*
+* $LicenseInfo:firstyear=2012&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2012, 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 "llfloaterpathfindingcharacters.h"
+
+#include <string>
+
+#include "llcheckboxctrl.h"
+#include "llfloaterreg.h"
+#include "llfloaterpathfindingobjects.h"
+#include "llhandle.h"
+#include "llpathfindingcharacter.h"
+#include "llpathfindingcharacterlist.h"
+#include "llpathfindingmanager.h"
+#include "llpathfindingobject.h"
+#include "llpathfindingobjectlist.h"
+#include "llpathinglib.h"
+#include "llquaternion.h"
+#include "llsd.h"
+#include "lluicolortable.h"
+#include "lluuid.h"
+#include "llviewerobject.h"
+#include "llviewerobjectlist.h"
+#include "pipeline.h"
+#include "v3math.h"
+#include "v4color.h"
+
+LLHandle<LLFloaterPathfindingCharacters> LLFloaterPathfindingCharacters::sInstanceHandle;
+
+//---------------------------------------------------------------------------
+// LLFloaterPathfindingCharacters
+//---------------------------------------------------------------------------
+
+void LLFloaterPathfindingCharacters::onClose(bool pIsAppQuitting)
+{
+ // Hide any capsule that might be showing on floater close
+ hideCapsule();
+ LLFloaterPathfindingObjects::onClose( pIsAppQuitting );
+}
+
+BOOL LLFloaterPathfindingCharacters::isShowPhysicsCapsule() const
+{
+ return mShowPhysicsCapsuleCheckBox->get();
+}
+
+void LLFloaterPathfindingCharacters::setShowPhysicsCapsule(BOOL pIsShowPhysicsCapsule)
+{
+ mShowPhysicsCapsuleCheckBox->set(pIsShowPhysicsCapsule && (LLPathingLib::getInstance() != NULL));
+}
+
+BOOL LLFloaterPathfindingCharacters::isPhysicsCapsuleEnabled(LLUUID& id, LLVector3& pos, LLQuaternion& rot) const
+{
+ id = mSelectedCharacterId;
+ // Physics capsule is enable if the checkbox is enabled and if we can get the required render
+ // parameters for any selected object
+ return (isShowPhysicsCapsule() && getCapsuleRenderData(pos, rot ));
+}
+
+void LLFloaterPathfindingCharacters::openCharactersWithSelectedObjects()
+{
+ LLFloaterPathfindingCharacters *charactersFloater = LLFloaterReg::getTypedInstance<LLFloaterPathfindingCharacters>("pathfinding_characters");
+ charactersFloater->showFloaterWithSelectionObjects();
+}
+
+LLHandle<LLFloaterPathfindingCharacters> LLFloaterPathfindingCharacters::getInstanceHandle()
+{
+ if ( sInstanceHandle.isDead() )
+ {
+ LLFloaterPathfindingCharacters *floaterInstance = LLFloaterReg::findTypedInstance<LLFloaterPathfindingCharacters>("pathfinding_characters");
+ if (floaterInstance != NULL)
+ {
+ sInstanceHandle = floaterInstance->mSelfHandle;
+ }
+ }
+
+ return sInstanceHandle;
+}
+
+LLFloaterPathfindingCharacters::LLFloaterPathfindingCharacters(const LLSD& pSeed)
+ : LLFloaterPathfindingObjects(pSeed),
+ mShowPhysicsCapsuleCheckBox(NULL),
+ mSelectedCharacterId(),
+ mBeaconColor(),
+ mSelfHandle()
+{
+ mSelfHandle.bind(this);
+}
+
+LLFloaterPathfindingCharacters::~LLFloaterPathfindingCharacters()
+{
+}
+
+BOOL LLFloaterPathfindingCharacters::postBuild()
+{
+ mBeaconColor = LLUIColorTable::getInstance()->getColor("PathfindingCharacterBeaconColor");
+
+ mShowPhysicsCapsuleCheckBox = findChild<LLCheckBoxCtrl>("show_physics_capsule");
+ llassert(mShowPhysicsCapsuleCheckBox != NULL);
+ mShowPhysicsCapsuleCheckBox->setCommitCallback(boost::bind(&LLFloaterPathfindingCharacters::onShowPhysicsCapsuleClicked, this));
+ mShowPhysicsCapsuleCheckBox->setEnabled(LLPathingLib::getInstance() != NULL);
+
+ return LLFloaterPathfindingObjects::postBuild();
+}
+
+void LLFloaterPathfindingCharacters::requestGetObjects()
+{
+ LLPathfindingManager::getInstance()->requestGetCharacters(getNewRequestId(), boost::bind(&LLFloaterPathfindingCharacters::handleNewObjectList, this, _1, _2, _3));
+}
+
+void LLFloaterPathfindingCharacters::buildObjectsScrollList(const LLPathfindingObjectListPtr pObjectListPtr)
+{
+ llassert(pObjectListPtr != NULL);
+ llassert(!pObjectListPtr->isEmpty());
+
+ for (LLPathfindingObjectList::const_iterator objectIter = pObjectListPtr->begin(); objectIter != pObjectListPtr->end(); ++objectIter)
+ {
+ const LLPathfindingObjectPtr objectPtr = objectIter->second;
+ const LLPathfindingCharacter *characterPtr = dynamic_cast<const LLPathfindingCharacter *>(objectPtr.get());
+ llassert(characterPtr != NULL);
+
+ LLSD scrollListItemData = buildCharacterScrollListItemData(characterPtr);
+ addObjectToScrollList(objectPtr, scrollListItemData);
+ }
+}
+
+void LLFloaterPathfindingCharacters::updateControlsOnScrollListChange()
+{
+ LLFloaterPathfindingObjects::updateControlsOnScrollListChange();
+ updateStateOnDisplayControls();
+ showSelectedCharacterCapsules();
+}
+
+S32 LLFloaterPathfindingCharacters::getNameColumnIndex() const
+{
+ return 0;
+}
+
+S32 LLFloaterPathfindingCharacters::getOwnerNameColumnIndex() const
+{
+ return 2;
+}
+
+std::string LLFloaterPathfindingCharacters::getOwnerName(const LLPathfindingObject *pObject) const
+{
+ return (pObject->hasOwner()
+ ? (pObject->hasOwnerName()
+ ? (pObject->isGroupOwned()
+ ? (pObject->getOwnerName() + " " + getString("character_owner_group"))
+ : pObject->getOwnerName())
+ : getString("character_owner_loading"))
+ : getString("character_owner_unknown"));
+}
+
+const LLColor4 &LLFloaterPathfindingCharacters::getBeaconColor() const
+{
+ return mBeaconColor;
+}
+
+LLPathfindingObjectListPtr LLFloaterPathfindingCharacters::getEmptyObjectList() const
+{
+ LLPathfindingObjectListPtr objectListPtr(new LLPathfindingCharacterList());
+ return objectListPtr;
+}
+
+void LLFloaterPathfindingCharacters::onShowPhysicsCapsuleClicked()
+{
+ if (LLPathingLib::getInstance() == NULL)
+ {
+ if (isShowPhysicsCapsule())
+ {
+ setShowPhysicsCapsule(FALSE);
+ }
+ }
+ else
+ {
+ if (mSelectedCharacterId.notNull() && isShowPhysicsCapsule())
+ {
+ showCapsule();
+ }
+ else
+ {
+ hideCapsule();
+ }
+ }
+}
+
+LLSD LLFloaterPathfindingCharacters::buildCharacterScrollListItemData(const LLPathfindingCharacter *pCharacterPtr) const
+{
+ LLSD columns = LLSD::emptyArray();
+
+ columns[0]["column"] = "name";
+ columns[0]["value"] = pCharacterPtr->getName();
+
+ columns[1]["column"] = "description";
+ columns[1]["value"] = pCharacterPtr->getDescription();
+
+ columns[2]["column"] = "owner";
+ columns[2]["value"] = getOwnerName(pCharacterPtr);
+
+ S32 cpuTime = llround(pCharacterPtr->getCPUTime());
+ std::string cpuTimeString = llformat("%d", cpuTime);
+ LLStringUtil::format_map_t string_args;
+ string_args["[CPU_TIME]"] = cpuTimeString;
+
+ columns[3]["column"] = "cpu_time";
+ columns[3]["value"] = getString("character_cpu_time", string_args);
+
+ columns[4]["column"] = "altitude";
+ columns[4]["value"] = llformat("%1.0f m", pCharacterPtr->getLocation()[2]);
+
+ return columns;
+}
+
+void LLFloaterPathfindingCharacters::updateStateOnDisplayControls()
+{
+ int numSelectedItems = getNumSelectedObjects();;
+ bool isEditEnabled = ((numSelectedItems == 1) && (LLPathingLib::getInstance() != NULL));
+
+ mShowPhysicsCapsuleCheckBox->setEnabled(isEditEnabled);
+ if (!isEditEnabled)
+ {
+ setShowPhysicsCapsule(FALSE);
+ }
+}
+
+void LLFloaterPathfindingCharacters::showSelectedCharacterCapsules()
+{
+ // Hide any previous capsule
+ hideCapsule();
+
+ // Get the only selected object, or set the selected object to null if we do not have exactly
+ // one object selected
+ if (getNumSelectedObjects() == 1)
+ {
+ LLPathfindingObjectPtr selectedObjectPtr = getFirstSelectedObject();
+ mSelectedCharacterId = selectedObjectPtr->getUUID();
+ }
+ else
+ {
+ mSelectedCharacterId.setNull();
+ }
+
+ // Show any capsule if enabled
+ showCapsule();
+}
+
+void LLFloaterPathfindingCharacters::showCapsule() const
+{
+ if (mSelectedCharacterId.notNull() && isShowPhysicsCapsule())
+ {
+ LLPathfindingObjectPtr objectPtr = getFirstSelectedObject();
+ llassert(objectPtr != NULL);
+ if (objectPtr != NULL)
+ {
+ const LLPathfindingCharacter *character = dynamic_cast<const LLPathfindingCharacter *>(objectPtr.get());
+ llassert(mSelectedCharacterId == character->getUUID());
+ if (LLPathingLib::getInstance() != NULL)
+ {
+ LLPathingLib::getInstance()->createPhysicsCapsuleRep(character->getLength(), character->getRadius(),
+ character->isHorizontal(), character->getUUID());
+ }
+ }
+
+ gPipeline.hideObject(mSelectedCharacterId);
+ }
+}
+
+void LLFloaterPathfindingCharacters::hideCapsule() const
+{
+ if (mSelectedCharacterId.notNull())
+ {
+ gPipeline.restoreHiddenObject(mSelectedCharacterId);
+ }
+ if (LLPathingLib::getInstance() != NULL)
+ {
+ LLPathingLib::getInstance()->cleanupPhysicsCapsuleRepResiduals();
+ }
+}
+
+bool LLFloaterPathfindingCharacters::getCapsuleRenderData(LLVector3& pPosition, LLQuaternion& rot) const
+{
+ bool result = false;
+
+ // If we have a selected object, find the object on the viewer object list and return its
+ // position. Else, return false indicating that we either do not have a selected object
+ // or we cannot find the selected object on the viewer object list
+ if (mSelectedCharacterId.notNull())
+ {
+ LLViewerObject *viewerObject = gObjectList.findObject(mSelectedCharacterId);
+ if ( viewerObject != NULL )
+ {
+ rot = viewerObject->getRotation() ;
+ pPosition = viewerObject->getRenderPosition();
+ result = true;
+ }
+ }
+
+ return result;
+}
diff --git a/indra/newview/llfloaterpathfindingcharacters.h b/indra/newview/llfloaterpathfindingcharacters.h
new file mode 100755
index 0000000000..4021f4f119
--- /dev/null
+++ b/indra/newview/llfloaterpathfindingcharacters.h
@@ -0,0 +1,99 @@
+/**
+* @file llfloaterpathfindingcharacters.h
+* @brief "Pathfinding characters" floater, allowing for identification of pathfinding characters and their cpu usage.
+* @author Stinson@lindenlab.com
+*
+* $LicenseInfo:firstyear=2012&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2012, 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_LLFLOATERPATHFINDINGCHARACTERS_H
+#define LL_LLFLOATERPATHFINDINGCHARACTERS_H
+
+#include "llfloaterpathfindingobjects.h"
+#include "llhandle.h"
+#include "llpathfindingobjectlist.h"
+#include "lluuid.h"
+#include "v4color.h"
+
+class LLCheckBoxCtrl;
+class LLPathfindingCharacter;
+class LLQuaternion;
+class LLSD;
+class LLVector3;
+
+class LLFloaterPathfindingCharacters : public LLFloaterPathfindingObjects
+{
+public:
+ virtual void onClose(bool pIsAppQuitting);
+
+ BOOL isShowPhysicsCapsule() const;
+ void setShowPhysicsCapsule(BOOL pIsShowPhysicsCapsule);
+
+ BOOL isPhysicsCapsuleEnabled(LLUUID& id, LLVector3& pos, LLQuaternion& rot) const;
+
+ static void openCharactersWithSelectedObjects();
+ static LLHandle<LLFloaterPathfindingCharacters> getInstanceHandle();
+
+protected:
+ friend class LLFloaterReg;
+
+ LLFloaterPathfindingCharacters(const LLSD& pSeed);
+ virtual ~LLFloaterPathfindingCharacters();
+
+ virtual BOOL postBuild();
+
+ virtual void requestGetObjects();
+
+ virtual void buildObjectsScrollList(const LLPathfindingObjectListPtr pObjectListPtr);
+
+ virtual void updateControlsOnScrollListChange();
+
+ virtual S32 getNameColumnIndex() const;
+ virtual S32 getOwnerNameColumnIndex() const;
+ virtual std::string getOwnerName(const LLPathfindingObject *pObject) const;
+ virtual const LLColor4 &getBeaconColor() const;
+
+ virtual LLPathfindingObjectListPtr getEmptyObjectList() const;
+
+private:
+ void onShowPhysicsCapsuleClicked();
+
+ LLSD buildCharacterScrollListItemData(const LLPathfindingCharacter *pCharacterPtr) const;
+
+ void updateStateOnDisplayControls();
+ void showSelectedCharacterCapsules();
+
+ void showCapsule() const;
+ void hideCapsule() const;
+
+ bool getCapsuleRenderData(LLVector3& pPosition, LLQuaternion& rot) const;
+
+ LLCheckBoxCtrl *mShowPhysicsCapsuleCheckBox;
+
+ LLUUID mSelectedCharacterId;
+
+ LLColor4 mBeaconColor;
+
+ LLRootHandle<LLFloaterPathfindingCharacters> mSelfHandle;
+ static LLHandle<LLFloaterPathfindingCharacters> sInstanceHandle;
+};
+
+#endif // LL_LLFLOATERPATHFINDINGCHARACTERS_H
diff --git a/indra/newview/llfloaterpathfindingconsole.cpp b/indra/newview/llfloaterpathfindingconsole.cpp
new file mode 100755
index 0000000000..298454724b
--- /dev/null
+++ b/indra/newview/llfloaterpathfindingconsole.cpp
@@ -0,0 +1,1273 @@
+/**
+* @file llfloaterpathfindingconsole.cpp
+* @brief "Pathfinding console" floater, allowing for viewing and testing of the pathfinding navmesh through Havok AI utilities.
+* @author Stinson@lindenlab.com
+*
+* $LicenseInfo:firstyear=2012&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2012, 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 "llfloaterpathfindingconsole.h"
+
+#include <vector>
+
+#include <boost/signals2.hpp>
+
+#include "llbutton.h"
+#include "llcheckboxctrl.h"
+#include "llcombobox.h"
+#include "llcontrol.h"
+#include "llenvmanager.h"
+#include "llfloaterpathfindingcharacters.h"
+#include "llfloaterpathfindinglinksets.h"
+#include "llfloaterreg.h"
+#include "llhandle.h"
+#include "llpanel.h"
+#include "llpathfindingnavmeshzone.h"
+#include "llpathfindingpathtool.h"
+#include "llpathinglib.h"
+#include "llsliderctrl.h"
+#include "llsd.h"
+#include "lltabcontainer.h"
+#include "lltextbase.h"
+#include "lltoolmgr.h"
+#include "lltoolfocus.h"
+#include "llviewercontrol.h"
+#include "llviewerparcelmgr.h"
+#include "pipeline.h"
+
+#define XUI_RENDER_HEATMAP_NONE 0
+#define XUI_RENDER_HEATMAP_A 1
+#define XUI_RENDER_HEATMAP_B 2
+#define XUI_RENDER_HEATMAP_C 3
+#define XUI_RENDER_HEATMAP_D 4
+
+#define XUI_CHARACTER_TYPE_NONE 0
+#define XUI_CHARACTER_TYPE_A 1
+#define XUI_CHARACTER_TYPE_B 2
+#define XUI_CHARACTER_TYPE_C 3
+#define XUI_CHARACTER_TYPE_D 4
+
+#define XUI_VIEW_TAB_INDEX 0
+#define XUI_TEST_TAB_INDEX 1
+
+#define SET_SHAPE_RENDER_FLAG(_flag,_type) _flag |= (1U << _type)
+
+#define CONTROL_NAME_RETRIEVE_NEIGHBOR "PathfindingRetrieveNeighboringRegion"
+#define CONTROL_NAME_WALKABLE_OBJECTS "PathfindingWalkable"
+#define CONTROL_NAME_STATIC_OBSTACLE_OBJECTS "PathfindingObstacle"
+#define CONTROL_NAME_MATERIAL_VOLUMES "PathfindingMaterial"
+#define CONTROL_NAME_EXCLUSION_VOLUMES "PathfindingExclusion"
+#define CONTROL_NAME_INTERIOR_EDGE "PathfindingConnectedEdge"
+#define CONTROL_NAME_EXTERIOR_EDGE "PathfindingBoundaryEdge"
+#define CONTROL_NAME_HEATMAP_MIN "PathfindingHeatColorBase"
+#define CONTROL_NAME_HEATMAP_MAX "PathfindingHeatColorMax"
+#define CONTROL_NAME_NAVMESH_FACE "PathfindingFaceColor"
+#define CONTROL_NAME_TEST_PATH_VALID_END "PathfindingTestPathValidEndColor"
+#define CONTROL_NAME_TEST_PATH_INVALID_END "PathfindingTestPathInvalidEndColor"
+#define CONTROL_NAME_TEST_PATH "PathfindingTestPathColor"
+#define CONTROL_NAME_WATER "PathfindingWaterColor"
+
+LLHandle<LLFloaterPathfindingConsole> LLFloaterPathfindingConsole::sInstanceHandle;
+
+//---------------------------------------------------------------------------
+// LLFloaterPathfindingConsole
+//---------------------------------------------------------------------------
+
+BOOL LLFloaterPathfindingConsole::postBuild()
+{
+ mViewTestTabContainer = findChild<LLTabContainer>("view_test_tab_container");
+ llassert(mViewTestTabContainer != NULL);
+ mViewTestTabContainer->setCommitCallback(boost::bind(&LLFloaterPathfindingConsole::onTabSwitch, this));
+
+ mViewTab = findChild<LLPanel>("view_panel");
+ llassert(mViewTab != NULL);
+
+ mShowLabel = findChild<LLTextBase>("show_label");
+ llassert(mShowLabel != NULL);
+
+ mShowWorldCheckBox = findChild<LLCheckBoxCtrl>("show_world");
+ llassert(mShowWorldCheckBox != NULL);
+ mShowWorldCheckBox->setCommitCallback(boost::bind(&LLFloaterPathfindingConsole::onShowWorldSet, this));
+
+ mShowWorldMovablesOnlyCheckBox = findChild<LLCheckBoxCtrl>("show_world_movables_only");
+ llassert(mShowWorldMovablesOnlyCheckBox != NULL);
+ mShowWorldMovablesOnlyCheckBox->setCommitCallback(boost::bind(&LLFloaterPathfindingConsole::onShowWorldMovablesOnlySet, this));
+
+ mShowNavMeshCheckBox = findChild<LLCheckBoxCtrl>("show_navmesh");
+ llassert(mShowNavMeshCheckBox != NULL);
+ mShowNavMeshCheckBox->setCommitCallback(boost::bind(&LLFloaterPathfindingConsole::onShowNavMeshSet, this));
+
+ mShowNavMeshWalkabilityLabel = findChild<LLTextBase>("show_walkability_label");
+ llassert(mShowNavMeshWalkabilityLabel != NULL);
+
+ mShowNavMeshWalkabilityComboBox = findChild<LLComboBox>("show_heatmap_mode");
+ llassert(mShowNavMeshWalkabilityComboBox != NULL);
+ mShowNavMeshWalkabilityComboBox->setCommitCallback(boost::bind(&LLFloaterPathfindingConsole::onShowWalkabilitySet, this));
+
+ mShowWalkablesCheckBox = findChild<LLCheckBoxCtrl>("show_walkables");
+ llassert(mShowWalkablesCheckBox != NULL);
+
+ mShowStaticObstaclesCheckBox = findChild<LLCheckBoxCtrl>("show_static_obstacles");
+ llassert(mShowStaticObstaclesCheckBox != NULL);
+
+ mShowMaterialVolumesCheckBox = findChild<LLCheckBoxCtrl>("show_material_volumes");
+ llassert(mShowMaterialVolumesCheckBox != NULL);
+
+ mShowExclusionVolumesCheckBox = findChild<LLCheckBoxCtrl>("show_exclusion_volumes");
+ llassert(mShowExclusionVolumesCheckBox != NULL);
+
+ mShowRenderWaterPlaneCheckBox = findChild<LLCheckBoxCtrl>("show_water_plane");
+ llassert(mShowRenderWaterPlaneCheckBox != NULL);
+
+ mShowXRayCheckBox = findChild<LLCheckBoxCtrl>("show_xray");
+ llassert(mShowXRayCheckBox != NULL);
+
+ mTestTab = findChild<LLPanel>("test_panel");
+ llassert(mTestTab != NULL);
+
+ mPathfindingViewerStatus = findChild<LLTextBase>("pathfinding_viewer_status");
+ llassert(mPathfindingViewerStatus != NULL);
+
+ mPathfindingSimulatorStatus = findChild<LLTextBase>("pathfinding_simulator_status");
+ llassert(mPathfindingSimulatorStatus != NULL);
+
+ mCtrlClickLabel = findChild<LLTextBase>("ctrl_click_label");
+ llassert(mCtrlClickLabel != NULL);
+
+ mShiftClickLabel = findChild<LLTextBase>("shift_click_label");
+ llassert(mShiftClickLabel != NULL);
+
+ mCharacterWidthLabel = findChild<LLTextBase>("character_width_label");
+ llassert(mCharacterWidthLabel != NULL);
+
+ mCharacterWidthSlider = findChild<LLSliderCtrl>("character_width");
+ llassert(mCharacterWidthSlider != NULL);
+ mCharacterWidthSlider->setCommitCallback(boost::bind(&LLFloaterPathfindingConsole::onCharacterWidthSet, this));
+
+ mCharacterWidthUnitLabel = findChild<LLTextBase>("character_width_unit_label");
+ llassert(mCharacterWidthUnitLabel != NULL);
+
+ mCharacterTypeLabel = findChild<LLTextBase>("character_type_label");
+ llassert(mCharacterTypeLabel != NULL);
+
+ mCharacterTypeComboBox = findChild<LLComboBox>("path_character_type");
+ llassert(mCharacterTypeComboBox != NULL);
+ mCharacterTypeComboBox->setCommitCallback(boost::bind(&LLFloaterPathfindingConsole::onCharacterTypeSwitch, this));
+
+ mPathTestingStatus = findChild<LLTextBase>("path_test_status");
+ llassert(mPathTestingStatus != NULL);
+
+ mClearPathButton = findChild<LLButton>("clear_path");
+ llassert(mClearPathButton != NULL);
+ mClearPathButton->setCommitCallback(boost::bind(&LLFloaterPathfindingConsole::onClearPathClicked, this));
+
+ mErrorColor = LLUIColorTable::instance().getColor("PathfindingErrorColor");
+ mWarningColor = LLUIColorTable::instance().getColor("PathfindingWarningColor");
+
+ if (LLPathingLib::getInstance() != NULL)
+ {
+ mPathfindingToolset = new LLToolset();
+ mPathfindingToolset->addTool(LLPathfindingPathTool::getInstance());
+ mPathfindingToolset->addTool(LLToolCamera::getInstance());
+ mPathfindingToolset->setShowFloaterTools(false);
+ }
+
+ updateCharacterWidth();
+ updateCharacterType();
+
+ return LLFloater::postBuild();
+}
+
+void LLFloaterPathfindingConsole::onOpen(const LLSD& pKey)
+{
+ LLFloater::onOpen(pKey);
+ //make sure we have a pathing system
+ if ( LLPathingLib::getInstance() == NULL )
+ {
+ setConsoleState(kConsoleStateLibraryNotImplemented);
+ llwarns <<"Errror: cannot find pathing library implementation."<<llendl;
+ }
+ else
+ {
+ if (!mNavMeshZoneSlot.connected())
+ {
+ mNavMeshZoneSlot = mNavMeshZone.registerNavMeshZoneListener(boost::bind(&LLFloaterPathfindingConsole::handleNavMeshZoneStatus, this, _1));
+ }
+
+ mIsNavMeshUpdating = false;
+ initializeNavMeshZoneForCurrentRegion();
+ registerSavedSettingsListeners();
+ fillInColorsForNavMeshVisualization();
+ }
+
+ if (!mRegionBoundarySlot.connected())
+ {
+ mRegionBoundarySlot = LLEnvManagerNew::instance().setRegionChangeCallback(boost::bind(&LLFloaterPathfindingConsole::onRegionBoundaryCross, this));
+ }
+
+ if (!mTeleportFailedSlot.connected())
+ {
+ mTeleportFailedSlot = LLViewerParcelMgr::getInstance()->setTeleportFailedCallback(boost::bind(&LLFloaterPathfindingConsole::onRegionBoundaryCross, this));
+ }
+
+ if (!mPathEventSlot.connected())
+ {
+ mPathEventSlot = LLPathfindingPathTool::getInstance()->registerPathEventListener(boost::bind(&LLFloaterPathfindingConsole::onPathEvent, this));
+ }
+
+ setDefaultInputs();
+ updatePathTestStatus();
+
+ if (mViewTestTabContainer->getCurrentPanelIndex() == XUI_TEST_TAB_INDEX)
+ {
+ switchIntoTestPathMode();
+ }
+}
+
+void LLFloaterPathfindingConsole::onClose(bool pIsAppQuitting)
+{
+ switchOutOfTestPathMode();
+
+ if (mPathEventSlot.connected())
+ {
+ mPathEventSlot.disconnect();
+ }
+
+ if (mTeleportFailedSlot.connected())
+ {
+ mTeleportFailedSlot.disconnect();
+ }
+
+ if (mRegionBoundarySlot.connected())
+ {
+ mRegionBoundarySlot.disconnect();
+ }
+
+ if (mNavMeshZoneSlot.connected())
+ {
+ mNavMeshZoneSlot.disconnect();
+ }
+
+ if (LLPathingLib::getInstance() != NULL)
+ {
+ mNavMeshZone.disable();
+ }
+ deregisterSavedSettingsListeners();
+
+ setDefaultInputs();
+ setConsoleState(kConsoleStateUnknown);
+ cleanupRenderableRestoreItems();
+
+ LLFloater::onClose(pIsAppQuitting);
+}
+
+LLHandle<LLFloaterPathfindingConsole> LLFloaterPathfindingConsole::getInstanceHandle()
+{
+ if (sInstanceHandle.isDead())
+ {
+ LLFloaterPathfindingConsole *floaterInstance = LLFloaterReg::findTypedInstance<LLFloaterPathfindingConsole>("pathfinding_console");
+ if (floaterInstance != NULL)
+ {
+ sInstanceHandle = floaterInstance->mSelfHandle;
+ }
+ }
+
+ return sInstanceHandle;
+}
+
+BOOL LLFloaterPathfindingConsole::isRenderNavMesh() const
+{
+ return mShowNavMeshCheckBox->get();
+}
+
+void LLFloaterPathfindingConsole::setRenderNavMesh(BOOL pIsRenderNavMesh)
+{
+ mShowNavMeshCheckBox->set(pIsRenderNavMesh);
+ setNavMeshRenderState();
+}
+
+BOOL LLFloaterPathfindingConsole::isRenderWalkables() const
+{
+ return mShowWalkablesCheckBox->get();
+}
+
+void LLFloaterPathfindingConsole::setRenderWalkables(BOOL pIsRenderWalkables)
+{
+ mShowWalkablesCheckBox->set(pIsRenderWalkables);
+}
+
+BOOL LLFloaterPathfindingConsole::isRenderStaticObstacles() const
+{
+ return mShowStaticObstaclesCheckBox->get();
+}
+
+void LLFloaterPathfindingConsole::setRenderStaticObstacles(BOOL pIsRenderStaticObstacles)
+{
+ mShowStaticObstaclesCheckBox->set(pIsRenderStaticObstacles);
+}
+
+BOOL LLFloaterPathfindingConsole::isRenderMaterialVolumes() const
+{
+ return mShowMaterialVolumesCheckBox->get();
+}
+
+void LLFloaterPathfindingConsole::setRenderMaterialVolumes(BOOL pIsRenderMaterialVolumes)
+{
+ mShowMaterialVolumesCheckBox->set(pIsRenderMaterialVolumes);
+}
+
+BOOL LLFloaterPathfindingConsole::isRenderExclusionVolumes() const
+{
+ return mShowExclusionVolumesCheckBox->get();
+}
+
+void LLFloaterPathfindingConsole::setRenderExclusionVolumes(BOOL pIsRenderExclusionVolumes)
+{
+ mShowExclusionVolumesCheckBox->set(pIsRenderExclusionVolumes);
+}
+
+BOOL LLFloaterPathfindingConsole::isRenderWorld() const
+{
+ return mShowWorldCheckBox->get();
+}
+
+void LLFloaterPathfindingConsole::setRenderWorld(BOOL pIsRenderWorld)
+{
+ mShowWorldCheckBox->set(pIsRenderWorld);
+ setWorldRenderState();
+}
+
+BOOL LLFloaterPathfindingConsole::isRenderWorldMovablesOnly() const
+{
+ return (mShowWorldCheckBox->get() && mShowWorldMovablesOnlyCheckBox->get());
+}
+
+void LLFloaterPathfindingConsole::setRenderWorldMovablesOnly(BOOL pIsRenderWorldMovablesOnly)
+{
+ mShowWorldMovablesOnlyCheckBox->set(pIsRenderWorldMovablesOnly);
+}
+
+BOOL LLFloaterPathfindingConsole::isRenderWaterPlane() const
+{
+ return mShowRenderWaterPlaneCheckBox->get();
+}
+
+void LLFloaterPathfindingConsole::setRenderWaterPlane(BOOL pIsRenderWaterPlane)
+{
+ mShowRenderWaterPlaneCheckBox->set(pIsRenderWaterPlane);
+}
+
+BOOL LLFloaterPathfindingConsole::isRenderXRay() const
+{
+ return mShowXRayCheckBox->get();
+}
+
+void LLFloaterPathfindingConsole::setRenderXRay(BOOL pIsRenderXRay)
+{
+ mShowXRayCheckBox->set(pIsRenderXRay);
+}
+
+LLPathingLib::LLPLCharacterType LLFloaterPathfindingConsole::getRenderHeatmapType() const
+{
+ LLPathingLib::LLPLCharacterType renderHeatmapType;
+
+ switch (mShowNavMeshWalkabilityComboBox->getValue().asInteger())
+ {
+ case XUI_RENDER_HEATMAP_NONE :
+ renderHeatmapType = LLPathingLib::LLPL_CHARACTER_TYPE_NONE;
+ break;
+ case XUI_RENDER_HEATMAP_A :
+ renderHeatmapType = LLPathingLib::LLPL_CHARACTER_TYPE_A;
+ break;
+ case XUI_RENDER_HEATMAP_B :
+ renderHeatmapType = LLPathingLib::LLPL_CHARACTER_TYPE_B;
+ break;
+ case XUI_RENDER_HEATMAP_C :
+ renderHeatmapType = LLPathingLib::LLPL_CHARACTER_TYPE_C;
+ break;
+ case XUI_RENDER_HEATMAP_D :
+ renderHeatmapType = LLPathingLib::LLPL_CHARACTER_TYPE_D;
+ break;
+ default :
+ renderHeatmapType = LLPathingLib::LLPL_CHARACTER_TYPE_NONE;
+ llassert(0);
+ break;
+ }
+
+ return renderHeatmapType;
+}
+
+void LLFloaterPathfindingConsole::setRenderHeatmapType(LLPathingLib::LLPLCharacterType pRenderHeatmapType)
+{
+ LLSD comboBoxValue;
+
+ switch (pRenderHeatmapType)
+ {
+ case LLPathingLib::LLPL_CHARACTER_TYPE_NONE :
+ comboBoxValue = XUI_RENDER_HEATMAP_NONE;
+ break;
+ case LLPathingLib::LLPL_CHARACTER_TYPE_A :
+ comboBoxValue = XUI_RENDER_HEATMAP_A;
+ break;
+ case LLPathingLib::LLPL_CHARACTER_TYPE_B :
+ comboBoxValue = XUI_RENDER_HEATMAP_B;
+ break;
+ case LLPathingLib::LLPL_CHARACTER_TYPE_C :
+ comboBoxValue = XUI_RENDER_HEATMAP_C;
+ break;
+ case LLPathingLib::LLPL_CHARACTER_TYPE_D :
+ comboBoxValue = XUI_RENDER_HEATMAP_D;
+ break;
+ default :
+ comboBoxValue = XUI_RENDER_HEATMAP_NONE;
+ llassert(0);
+ break;
+ }
+
+ mShowNavMeshWalkabilityComboBox->setValue(comboBoxValue);
+}
+
+LLFloaterPathfindingConsole::LLFloaterPathfindingConsole(const LLSD& pSeed)
+ : LLFloater(pSeed),
+ mSelfHandle(),
+ mViewTestTabContainer(NULL),
+ mViewTab(NULL),
+ mShowLabel(NULL),
+ mShowWorldCheckBox(NULL),
+ mShowWorldMovablesOnlyCheckBox(NULL),
+ mShowNavMeshCheckBox(NULL),
+ mShowNavMeshWalkabilityLabel(NULL),
+ mShowNavMeshWalkabilityComboBox(NULL),
+ mShowWalkablesCheckBox(NULL),
+ mShowStaticObstaclesCheckBox(NULL),
+ mShowMaterialVolumesCheckBox(NULL),
+ mShowExclusionVolumesCheckBox(NULL),
+ mShowRenderWaterPlaneCheckBox(NULL),
+ mShowXRayCheckBox(NULL),
+ mPathfindingViewerStatus(NULL),
+ mPathfindingSimulatorStatus(NULL),
+ mTestTab(NULL),
+ mCtrlClickLabel(),
+ mShiftClickLabel(),
+ mCharacterWidthLabel(),
+ mCharacterWidthUnitLabel(),
+ mCharacterWidthSlider(NULL),
+ mCharacterTypeLabel(),
+ mCharacterTypeComboBox(NULL),
+ mPathTestingStatus(NULL),
+ mClearPathButton(NULL),
+ mErrorColor(),
+ mWarningColor(),
+ mNavMeshZoneSlot(),
+ mNavMeshZone(),
+ mIsNavMeshUpdating(false),
+ mRegionBoundarySlot(),
+ mTeleportFailedSlot(),
+ mPathEventSlot(),
+ mPathfindingToolset(NULL),
+ mSavedToolset(NULL),
+ mSavedSettingRetrieveNeighborSlot(),
+ mSavedSettingWalkableSlot(),
+ mSavedSettingStaticObstacleSlot(),
+ mSavedSettingMaterialVolumeSlot(),
+ mSavedSettingExclusionVolumeSlot(),
+ mSavedSettingInteriorEdgeSlot(),
+ mSavedSettingExteriorEdgeSlot(),
+ mSavedSettingHeatmapMinSlot(),
+ mSavedSettingHeatmapMaxSlot(),
+ mSavedSettingNavMeshFaceSlot(),
+ mSavedSettingTestPathValidEndSlot(),
+ mSavedSettingTestPathInvalidEndSlot(),
+ mSavedSettingTestPathSlot(),
+ mSavedSettingWaterSlot(),
+ mConsoleState(kConsoleStateUnknown),
+ mRenderableRestoreList()
+{
+ mSelfHandle.bind(this);
+}
+
+LLFloaterPathfindingConsole::~LLFloaterPathfindingConsole()
+{
+}
+
+void LLFloaterPathfindingConsole::onTabSwitch()
+{
+ if (mViewTestTabContainer->getCurrentPanelIndex() == XUI_TEST_TAB_INDEX)
+ {
+ switchIntoTestPathMode();
+ }
+ else
+ {
+ switchOutOfTestPathMode();
+ }
+}
+
+void LLFloaterPathfindingConsole::onShowWorldSet()
+{
+ setWorldRenderState();
+ updateRenderablesObjects();
+}
+
+void LLFloaterPathfindingConsole::onShowWorldMovablesOnlySet()
+{
+ updateRenderablesObjects();
+}
+
+void LLFloaterPathfindingConsole::onShowNavMeshSet()
+{
+ setNavMeshRenderState();
+}
+
+void LLFloaterPathfindingConsole::onShowWalkabilitySet()
+{
+ if (LLPathingLib::getInstance() != NULL)
+ {
+ LLPathingLib::getInstance()->setNavMeshMaterialType(getRenderHeatmapType());
+ }
+}
+
+void LLFloaterPathfindingConsole::onCharacterWidthSet()
+{
+ updateCharacterWidth();
+}
+
+void LLFloaterPathfindingConsole::onCharacterTypeSwitch()
+{
+ updateCharacterType();
+}
+
+void LLFloaterPathfindingConsole::onClearPathClicked()
+{
+ clearPath();
+}
+
+void LLFloaterPathfindingConsole::handleNavMeshZoneStatus(LLPathfindingNavMeshZone::ENavMeshZoneRequestStatus pNavMeshZoneRequestStatus)
+{
+ switch (pNavMeshZoneRequestStatus)
+ {
+ case LLPathfindingNavMeshZone::kNavMeshZoneRequestUnknown :
+ setConsoleState(kConsoleStateUnknown);
+ break;
+ case LLPathfindingNavMeshZone::kNavMeshZoneRequestWaiting :
+ setConsoleState(kConsoleStateRegionLoading);
+ break;
+ case LLPathfindingNavMeshZone::kNavMeshZoneRequestChecking :
+ setConsoleState(kConsoleStateCheckingVersion);
+ break;
+ case LLPathfindingNavMeshZone::kNavMeshZoneRequestNeedsUpdate :
+ mIsNavMeshUpdating = true;
+ mNavMeshZone.refresh();
+ break;
+ case LLPathfindingNavMeshZone::kNavMeshZoneRequestStarted :
+ setConsoleState(kConsoleStateDownloading);
+ break;
+ case LLPathfindingNavMeshZone::kNavMeshZoneRequestCompleted :
+ mIsNavMeshUpdating = false;
+ setConsoleState(kConsoleStateHasNavMesh);
+ break;
+ case LLPathfindingNavMeshZone::kNavMeshZoneRequestNotEnabled :
+ setConsoleState(kConsoleStateRegionNotEnabled);
+ break;
+ case LLPathfindingNavMeshZone::kNavMeshZoneRequestError :
+ setConsoleState(kConsoleStateError);
+ break;
+ default:
+ setConsoleState(kConsoleStateUnknown);
+ llassert(0);
+ break;
+ }
+}
+
+void LLFloaterPathfindingConsole::onRegionBoundaryCross()
+{
+ initializeNavMeshZoneForCurrentRegion();
+ setRenderWorld(TRUE);
+ setRenderWorldMovablesOnly(FALSE);
+}
+
+void LLFloaterPathfindingConsole::onPathEvent()
+{
+ const LLPathfindingPathTool *pathToolInstance = LLPathfindingPathTool::getInstance();
+
+ mCharacterWidthSlider->setValue(LLSD(pathToolInstance->getCharacterWidth()));
+
+ LLSD characterType;
+ switch (pathToolInstance->getCharacterType())
+ {
+ case LLPathfindingPathTool::kCharacterTypeNone :
+ characterType = XUI_CHARACTER_TYPE_NONE;
+ break;
+ case LLPathfindingPathTool::kCharacterTypeA :
+ characterType = XUI_CHARACTER_TYPE_A;
+ break;
+ case LLPathfindingPathTool::kCharacterTypeB :
+ characterType = XUI_CHARACTER_TYPE_B;
+ break;
+ case LLPathfindingPathTool::kCharacterTypeC :
+ characterType = XUI_CHARACTER_TYPE_C;
+ break;
+ case LLPathfindingPathTool::kCharacterTypeD :
+ characterType = XUI_CHARACTER_TYPE_D;
+ break;
+ default :
+ characterType = XUI_CHARACTER_TYPE_NONE;
+ llassert(0);
+ break;
+ }
+ mCharacterTypeComboBox->setValue(characterType);
+
+ updatePathTestStatus();
+}
+
+void LLFloaterPathfindingConsole::setDefaultInputs()
+{
+ mViewTestTabContainer->selectTab(XUI_VIEW_TAB_INDEX);
+ setRenderWorld(TRUE);
+ setRenderWorldMovablesOnly(FALSE);
+ setRenderNavMesh(FALSE);
+ setRenderWalkables(FALSE);
+ setRenderMaterialVolumes(FALSE);
+ setRenderStaticObstacles(FALSE);
+ setRenderExclusionVolumes(FALSE);
+ setRenderWaterPlane(FALSE);
+ setRenderXRay(FALSE);
+}
+
+void LLFloaterPathfindingConsole::setConsoleState(EConsoleState pConsoleState)
+{
+ mConsoleState = pConsoleState;
+ updateControlsOnConsoleState();
+ updateViewerStatusOnConsoleState();
+ updateSimulatorStatusOnConsoleState();
+}
+
+void LLFloaterPathfindingConsole::setWorldRenderState()
+{
+ BOOL renderWorld = isRenderWorld();
+
+ mShowWorldMovablesOnlyCheckBox->setEnabled(renderWorld && mShowWorldCheckBox->getEnabled());
+ if (!renderWorld)
+ {
+ mShowWorldMovablesOnlyCheckBox->set(FALSE);
+ }
+}
+
+void LLFloaterPathfindingConsole::setNavMeshRenderState()
+{
+ BOOL renderNavMesh = isRenderNavMesh();
+
+ mShowNavMeshWalkabilityLabel->setEnabled(renderNavMesh);
+ mShowNavMeshWalkabilityComboBox->setEnabled(renderNavMesh);
+}
+
+void LLFloaterPathfindingConsole::updateRenderablesObjects()
+{
+ if ( isRenderWorldMovablesOnly() )
+ {
+ gPipeline.hidePermanentObjects( mRenderableRestoreList );
+ }
+ else
+ {
+ cleanupRenderableRestoreItems();
+ }
+}
+
+void LLFloaterPathfindingConsole::updateControlsOnConsoleState()
+{
+ switch (mConsoleState)
+ {
+ case kConsoleStateUnknown :
+ case kConsoleStateRegionNotEnabled :
+ case kConsoleStateRegionLoading :
+ mViewTestTabContainer->selectTab(XUI_VIEW_TAB_INDEX);
+ mViewTab->setEnabled(FALSE);
+ mShowLabel->setEnabled(FALSE);
+ mShowWorldCheckBox->setEnabled(FALSE);
+ mShowWorldMovablesOnlyCheckBox->setEnabled(FALSE);
+ mShowNavMeshCheckBox->setEnabled(FALSE);
+ mShowNavMeshWalkabilityLabel->setEnabled(FALSE);
+ mShowNavMeshWalkabilityComboBox->setEnabled(FALSE);
+ mShowWalkablesCheckBox->setEnabled(FALSE);
+ mShowStaticObstaclesCheckBox->setEnabled(FALSE);
+ mShowMaterialVolumesCheckBox->setEnabled(FALSE);
+ mShowExclusionVolumesCheckBox->setEnabled(FALSE);
+ mShowRenderWaterPlaneCheckBox->setEnabled(FALSE);
+ mShowXRayCheckBox->setEnabled(FALSE);
+ mTestTab->setEnabled(FALSE);
+ mCtrlClickLabel->setEnabled(FALSE);
+ mShiftClickLabel->setEnabled(FALSE);
+ mCharacterWidthLabel->setEnabled(FALSE);
+ mCharacterWidthUnitLabel->setEnabled(FALSE);
+ mCharacterWidthSlider->setEnabled(FALSE);
+ mCharacterTypeLabel->setEnabled(FALSE);
+ mCharacterTypeComboBox->setEnabled(FALSE);
+ mClearPathButton->setEnabled(FALSE);
+ clearPath();
+ break;
+ case kConsoleStateLibraryNotImplemented :
+ mViewTestTabContainer->selectTab(XUI_VIEW_TAB_INDEX);
+ mViewTab->setEnabled(FALSE);
+ mShowLabel->setEnabled(FALSE);
+ mShowWorldCheckBox->setEnabled(FALSE);
+ mShowWorldMovablesOnlyCheckBox->setEnabled(FALSE);
+ mShowNavMeshCheckBox->setEnabled(FALSE);
+ mShowNavMeshWalkabilityLabel->setEnabled(FALSE);
+ mShowNavMeshWalkabilityComboBox->setEnabled(FALSE);
+ mShowWalkablesCheckBox->setEnabled(FALSE);
+ mShowStaticObstaclesCheckBox->setEnabled(FALSE);
+ mShowMaterialVolumesCheckBox->setEnabled(FALSE);
+ mShowExclusionVolumesCheckBox->setEnabled(FALSE);
+ mShowRenderWaterPlaneCheckBox->setEnabled(FALSE);
+ mShowXRayCheckBox->setEnabled(FALSE);
+ mTestTab->setEnabled(FALSE);
+ mCtrlClickLabel->setEnabled(FALSE);
+ mShiftClickLabel->setEnabled(FALSE);
+ mCharacterWidthLabel->setEnabled(FALSE);
+ mCharacterWidthUnitLabel->setEnabled(FALSE);
+ mCharacterWidthSlider->setEnabled(FALSE);
+ mCharacterTypeLabel->setEnabled(FALSE);
+ mCharacterTypeComboBox->setEnabled(FALSE);
+ mClearPathButton->setEnabled(FALSE);
+ clearPath();
+ break;
+ case kConsoleStateCheckingVersion :
+ case kConsoleStateDownloading :
+ case kConsoleStateError :
+ mViewTestTabContainer->selectTab(XUI_VIEW_TAB_INDEX);
+ mViewTab->setEnabled(FALSE);
+ mShowLabel->setEnabled(FALSE);
+ mShowWorldCheckBox->setEnabled(FALSE);
+ mShowWorldMovablesOnlyCheckBox->setEnabled(FALSE);
+ mShowNavMeshCheckBox->setEnabled(FALSE);
+ mShowNavMeshWalkabilityLabel->setEnabled(FALSE);
+ mShowNavMeshWalkabilityComboBox->setEnabled(FALSE);
+ mShowWalkablesCheckBox->setEnabled(FALSE);
+ mShowStaticObstaclesCheckBox->setEnabled(FALSE);
+ mShowMaterialVolumesCheckBox->setEnabled(FALSE);
+ mShowExclusionVolumesCheckBox->setEnabled(FALSE);
+ mShowRenderWaterPlaneCheckBox->setEnabled(FALSE);
+ mShowXRayCheckBox->setEnabled(FALSE);
+ mTestTab->setEnabled(FALSE);
+ mCtrlClickLabel->setEnabled(FALSE);
+ mShiftClickLabel->setEnabled(FALSE);
+ mCharacterWidthLabel->setEnabled(FALSE);
+ mCharacterWidthUnitLabel->setEnabled(FALSE);
+ mCharacterWidthSlider->setEnabled(FALSE);
+ mCharacterTypeLabel->setEnabled(FALSE);
+ mCharacterTypeComboBox->setEnabled(FALSE);
+ mClearPathButton->setEnabled(FALSE);
+ clearPath();
+ break;
+ case kConsoleStateHasNavMesh :
+ mViewTab->setEnabled(TRUE);
+ mShowLabel->setEnabled(TRUE);
+ mShowWorldCheckBox->setEnabled(TRUE);
+ setWorldRenderState();
+ mShowNavMeshCheckBox->setEnabled(TRUE);
+ setNavMeshRenderState();
+ mShowWalkablesCheckBox->setEnabled(TRUE);
+ mShowStaticObstaclesCheckBox->setEnabled(TRUE);
+ mShowMaterialVolumesCheckBox->setEnabled(TRUE);
+ mShowExclusionVolumesCheckBox->setEnabled(TRUE);
+ mShowRenderWaterPlaneCheckBox->setEnabled(TRUE);
+ mShowXRayCheckBox->setEnabled(TRUE);
+ mTestTab->setEnabled(TRUE);
+ mCtrlClickLabel->setEnabled(TRUE);
+ mShiftClickLabel->setEnabled(TRUE);
+ mCharacterWidthLabel->setEnabled(TRUE);
+ mCharacterWidthUnitLabel->setEnabled(TRUE);
+ mCharacterWidthSlider->setEnabled(TRUE);
+ mCharacterTypeLabel->setEnabled(TRUE);
+ mCharacterTypeComboBox->setEnabled(TRUE);
+ mClearPathButton->setEnabled(TRUE);
+ break;
+ default :
+ llassert(0);
+ break;
+ }
+}
+
+void LLFloaterPathfindingConsole::updateViewerStatusOnConsoleState()
+{
+ std::string viewerStatusText("");
+ LLStyle::Params viewerStyleParams;
+
+ switch (mConsoleState)
+ {
+ case kConsoleStateUnknown :
+ viewerStatusText = getString("navmesh_viewer_status_unknown");
+ viewerStyleParams.color = mErrorColor;
+ break;
+ case kConsoleStateLibraryNotImplemented :
+ viewerStatusText = getString("navmesh_viewer_status_library_not_implemented");
+ viewerStyleParams.color = mErrorColor;
+ break;
+ case kConsoleStateRegionNotEnabled :
+ viewerStatusText = getString("navmesh_viewer_status_region_not_enabled");
+ viewerStyleParams.color = mErrorColor;
+ break;
+ case kConsoleStateRegionLoading :
+ viewerStatusText = getString("navmesh_viewer_status_region_loading");
+ viewerStyleParams.color = mWarningColor;
+ break;
+ case kConsoleStateCheckingVersion :
+ viewerStatusText = getString("navmesh_viewer_status_checking_version");
+ viewerStyleParams.color = mWarningColor;
+ break;
+ case kConsoleStateDownloading :
+ if (mIsNavMeshUpdating)
+ {
+ viewerStatusText = getString("navmesh_viewer_status_updating");
+ }
+ else
+ {
+ viewerStatusText = getString("navmesh_viewer_status_downloading");
+ }
+ viewerStyleParams.color = mWarningColor;
+ break;
+ case kConsoleStateHasNavMesh :
+ viewerStatusText = getString("navmesh_viewer_status_has_navmesh");
+ break;
+ case kConsoleStateError :
+ viewerStatusText = getString("navmesh_viewer_status_error");
+ viewerStyleParams.color = mErrorColor;
+ break;
+ default :
+ viewerStatusText = getString("navmesh_viewer_status_unknown");
+ viewerStyleParams.color = mErrorColor;
+ llassert(0);
+ break;
+ }
+
+ mPathfindingViewerStatus->setText((LLStringExplicit)viewerStatusText, viewerStyleParams);
+}
+
+void LLFloaterPathfindingConsole::updateSimulatorStatusOnConsoleState()
+{
+ std::string simulatorStatusText("");
+ LLStyle::Params simulatorStyleParams;
+
+ switch (mConsoleState)
+ {
+ case kConsoleStateUnknown :
+ case kConsoleStateLibraryNotImplemented :
+ case kConsoleStateRegionNotEnabled :
+ case kConsoleStateRegionLoading :
+ case kConsoleStateCheckingVersion :
+ case kConsoleStateError :
+ simulatorStatusText = getString("navmesh_simulator_status_unknown");
+ simulatorStyleParams.color = mErrorColor;
+ break;
+ case kConsoleStateDownloading :
+ case kConsoleStateHasNavMesh :
+ switch (mNavMeshZone.getNavMeshZoneStatus())
+ {
+ case LLPathfindingNavMeshZone::kNavMeshZonePending :
+ simulatorStatusText = getString("navmesh_simulator_status_pending");
+ simulatorStyleParams.color = mWarningColor;
+ break;
+ case LLPathfindingNavMeshZone::kNavMeshZoneBuilding :
+ simulatorStatusText = getString("navmesh_simulator_status_building");
+ simulatorStyleParams.color = mWarningColor;
+ break;
+ case LLPathfindingNavMeshZone::kNavMeshZoneSomePending :
+ simulatorStatusText = getString("navmesh_simulator_status_some_pending");
+ simulatorStyleParams.color = mWarningColor;
+ break;
+ case LLPathfindingNavMeshZone::kNavMeshZoneSomeBuilding :
+ simulatorStatusText = getString("navmesh_simulator_status_some_building");
+ simulatorStyleParams.color = mWarningColor;
+ break;
+ case LLPathfindingNavMeshZone::kNavMeshZonePendingAndBuilding :
+ simulatorStatusText = getString("navmesh_simulator_status_pending_and_building");
+ simulatorStyleParams.color = mWarningColor;
+ break;
+ case LLPathfindingNavMeshZone::kNavMeshZoneComplete :
+ simulatorStatusText = getString("navmesh_simulator_status_complete");
+ break;
+ default :
+ simulatorStatusText = getString("navmesh_simulator_status_unknown");
+ simulatorStyleParams.color = mErrorColor;
+ break;
+ }
+ break;
+ default :
+ simulatorStatusText = getString("navmesh_simulator_status_unknown");
+ simulatorStyleParams.color = mErrorColor;
+ llassert(0);
+ break;
+ }
+
+ mPathfindingSimulatorStatus->setText((LLStringExplicit)simulatorStatusText, simulatorStyleParams);
+}
+
+void LLFloaterPathfindingConsole::initializeNavMeshZoneForCurrentRegion()
+{
+ mNavMeshZone.disable();
+ mNavMeshZone.initialize();
+ mNavMeshZone.enable();
+ mNavMeshZone.refresh();
+ cleanupRenderableRestoreItems();
+}
+
+void LLFloaterPathfindingConsole::cleanupRenderableRestoreItems()
+{
+ if ( !mRenderableRestoreList.empty() )
+ {
+ gPipeline.restorePermanentObjects( mRenderableRestoreList );
+ mRenderableRestoreList.clear();
+ }
+ else
+ {
+ gPipeline.skipRenderingOfTerrain( false );
+ }
+}
+
+void LLFloaterPathfindingConsole::switchIntoTestPathMode()
+{
+ if (LLPathingLib::getInstance() != NULL)
+ {
+ llassert(mPathfindingToolset != NULL);
+ LLToolMgr *toolMgrInstance = LLToolMgr::getInstance();
+ if (toolMgrInstance->getCurrentToolset() != mPathfindingToolset)
+ {
+ mSavedToolset = toolMgrInstance->getCurrentToolset();
+ toolMgrInstance->setCurrentToolset(mPathfindingToolset);
+ }
+ }
+}
+
+void LLFloaterPathfindingConsole::switchOutOfTestPathMode()
+{
+ if (LLPathingLib::getInstance() != NULL)
+ {
+ llassert(mPathfindingToolset != NULL);
+ LLToolMgr *toolMgrInstance = LLToolMgr::getInstance();
+ if (toolMgrInstance->getCurrentToolset() == mPathfindingToolset)
+ {
+ toolMgrInstance->setCurrentToolset(mSavedToolset);
+ mSavedToolset = NULL;
+ }
+ }
+}
+
+void LLFloaterPathfindingConsole::updateCharacterWidth()
+{
+ LLPathfindingPathTool::getInstance()->setCharacterWidth(mCharacterWidthSlider->getValueF32());
+}
+
+void LLFloaterPathfindingConsole::updateCharacterType()
+{
+ LLPathfindingPathTool::ECharacterType characterType;
+
+ switch (mCharacterTypeComboBox->getValue().asInteger())
+ {
+ case XUI_CHARACTER_TYPE_NONE :
+ characterType = LLPathfindingPathTool::kCharacterTypeNone;
+ break;
+ case XUI_CHARACTER_TYPE_A :
+ characterType = LLPathfindingPathTool::kCharacterTypeA;
+ break;
+ case XUI_CHARACTER_TYPE_B :
+ characterType = LLPathfindingPathTool::kCharacterTypeB;
+ break;
+ case XUI_CHARACTER_TYPE_C :
+ characterType = LLPathfindingPathTool::kCharacterTypeC;
+ break;
+ case XUI_CHARACTER_TYPE_D :
+ characterType = LLPathfindingPathTool::kCharacterTypeD;
+ break;
+ default :
+ characterType = LLPathfindingPathTool::kCharacterTypeNone;
+ llassert(0);
+ break;
+ }
+
+ LLPathfindingPathTool::getInstance()->setCharacterType(characterType);
+}
+
+void LLFloaterPathfindingConsole::clearPath()
+{
+ LLPathfindingPathTool::getInstance()->clearPath();
+}
+
+void LLFloaterPathfindingConsole::updatePathTestStatus()
+{
+ std::string statusText("");
+ LLStyle::Params styleParams;
+
+ switch (LLPathfindingPathTool::getInstance()->getPathStatus())
+ {
+ case LLPathfindingPathTool::kPathStatusUnknown :
+ statusText = getString("pathing_unknown");
+ styleParams.color = mErrorColor;
+ break;
+ case LLPathfindingPathTool::kPathStatusChooseStartAndEndPoints :
+ statusText = getString("pathing_choose_start_and_end_points");
+ styleParams.color = mWarningColor;
+ break;
+ case LLPathfindingPathTool::kPathStatusChooseStartPoint :
+ statusText = getString("pathing_choose_start_point");
+ styleParams.color = mWarningColor;
+ break;
+ case LLPathfindingPathTool::kPathStatusChooseEndPoint :
+ statusText = getString("pathing_choose_end_point");
+ styleParams.color = mWarningColor;
+ break;
+ case LLPathfindingPathTool::kPathStatusHasValidPath :
+ statusText = getString("pathing_path_valid");
+ break;
+ case LLPathfindingPathTool::kPathStatusHasInvalidPath :
+ statusText = getString("pathing_path_invalid");
+ styleParams.color = mErrorColor;
+ break;
+ case LLPathfindingPathTool::kPathStatusNotEnabled :
+ statusText = getString("pathing_region_not_enabled");
+ styleParams.color = mErrorColor;
+ break;
+ case LLPathfindingPathTool::kPathStatusNotImplemented :
+ statusText = getString("pathing_library_not_implemented");
+ styleParams.color = mErrorColor;
+ break;
+ case LLPathfindingPathTool::kPathStatusError :
+ statusText = getString("pathing_error");
+ styleParams.color = mErrorColor;
+ break;
+ default :
+ statusText = getString("pathing_unknown");
+ styleParams.color = mErrorColor;
+ break;
+ }
+
+ mPathTestingStatus->setText((LLStringExplicit)statusText, styleParams);
+}
+
+
+BOOL LLFloaterPathfindingConsole::isRenderAnyShapes() const
+{
+ return (isRenderWalkables() || isRenderStaticObstacles() ||
+ isRenderMaterialVolumes() || isRenderExclusionVolumes());
+}
+
+U32 LLFloaterPathfindingConsole::getRenderShapeFlags()
+{
+ U32 shapeRenderFlag = 0U;
+
+ if (isRenderWalkables())
+ {
+ SET_SHAPE_RENDER_FLAG(shapeRenderFlag, LLPathingLib::LLST_WalkableObjects);
+ }
+ if (isRenderStaticObstacles())
+ {
+ SET_SHAPE_RENDER_FLAG(shapeRenderFlag, LLPathingLib::LLST_ObstacleObjects);
+ }
+ if (isRenderMaterialVolumes())
+ {
+ SET_SHAPE_RENDER_FLAG(shapeRenderFlag, LLPathingLib::LLST_MaterialPhantoms);
+ }
+ if (isRenderExclusionVolumes())
+ {
+ SET_SHAPE_RENDER_FLAG(shapeRenderFlag, LLPathingLib::LLST_ExclusionPhantoms);
+ }
+
+ return shapeRenderFlag;
+}
+
+void LLFloaterPathfindingConsole::registerSavedSettingsListeners()
+{
+ if (!mSavedSettingRetrieveNeighborSlot.connected())
+ {
+ mSavedSettingRetrieveNeighborSlot = gSavedSettings.getControl(CONTROL_NAME_RETRIEVE_NEIGHBOR)->getSignal()->connect(boost::bind(&LLFloaterPathfindingConsole::handleRetrieveNeighborChange, this, _1, _2));
+ }
+ if (!mSavedSettingWalkableSlot.connected())
+ {
+ mSavedSettingWalkableSlot = gSavedSettings.getControl(CONTROL_NAME_WALKABLE_OBJECTS)->getSignal()->connect(boost::bind(&LLFloaterPathfindingConsole::handleNavMeshColorChange, this, _1, _2));
+ }
+ if (!mSavedSettingStaticObstacleSlot.connected())
+ {
+ mSavedSettingStaticObstacleSlot = gSavedSettings.getControl(CONTROL_NAME_STATIC_OBSTACLE_OBJECTS)->getSignal()->connect(boost::bind(&LLFloaterPathfindingConsole::handleNavMeshColorChange, this, _1, _2));
+ }
+ if (!mSavedSettingMaterialVolumeSlot.connected())
+ {
+ mSavedSettingMaterialVolumeSlot = gSavedSettings.getControl(CONTROL_NAME_MATERIAL_VOLUMES)->getSignal()->connect(boost::bind(&LLFloaterPathfindingConsole::handleNavMeshColorChange, this, _1, _2));
+ }
+ if (!mSavedSettingExclusionVolumeSlot.connected())
+ {
+ mSavedSettingExclusionVolumeSlot = gSavedSettings.getControl(CONTROL_NAME_EXCLUSION_VOLUMES)->getSignal()->connect(boost::bind(&LLFloaterPathfindingConsole::handleNavMeshColorChange, this, _1, _2));
+ }
+ if (!mSavedSettingInteriorEdgeSlot.connected())
+ {
+ mSavedSettingInteriorEdgeSlot = gSavedSettings.getControl(CONTROL_NAME_INTERIOR_EDGE)->getSignal()->connect(boost::bind(&LLFloaterPathfindingConsole::handleNavMeshColorChange, this, _1, _2));
+ }
+ if (!mSavedSettingExteriorEdgeSlot.connected())
+ {
+ mSavedSettingExteriorEdgeSlot = gSavedSettings.getControl(CONTROL_NAME_EXTERIOR_EDGE)->getSignal()->connect(boost::bind(&LLFloaterPathfindingConsole::handleNavMeshColorChange, this, _1, _2));
+ }
+ if (!mSavedSettingHeatmapMinSlot.connected())
+ {
+ mSavedSettingHeatmapMinSlot = gSavedSettings.getControl(CONTROL_NAME_HEATMAP_MIN)->getSignal()->connect(boost::bind(&LLFloaterPathfindingConsole::handleNavMeshColorChange, this, _1, _2));
+ }
+ if (!mSavedSettingHeatmapMaxSlot.connected())
+ {
+ mSavedSettingHeatmapMaxSlot = gSavedSettings.getControl(CONTROL_NAME_HEATMAP_MAX)->getSignal()->connect(boost::bind(&LLFloaterPathfindingConsole::handleNavMeshColorChange, this, _1, _2));
+ }
+ if (!mSavedSettingNavMeshFaceSlot.connected())
+ {
+ mSavedSettingNavMeshFaceSlot = gSavedSettings.getControl(CONTROL_NAME_NAVMESH_FACE)->getSignal()->connect(boost::bind(&LLFloaterPathfindingConsole::handleNavMeshColorChange, this, _1, _2));
+ }
+ if (!mSavedSettingTestPathValidEndSlot.connected())
+ {
+ mSavedSettingTestPathValidEndSlot = gSavedSettings.getControl(CONTROL_NAME_TEST_PATH_VALID_END)->getSignal()->connect(boost::bind(&LLFloaterPathfindingConsole::handleNavMeshColorChange, this, _1, _2));
+ }
+ if (!mSavedSettingTestPathInvalidEndSlot.connected())
+ {
+ mSavedSettingTestPathInvalidEndSlot = gSavedSettings.getControl(CONTROL_NAME_TEST_PATH_INVALID_END)->getSignal()->connect(boost::bind(&LLFloaterPathfindingConsole::handleNavMeshColorChange, this, _1, _2));
+ }
+ if (!mSavedSettingTestPathSlot.connected())
+ {
+ mSavedSettingTestPathSlot = gSavedSettings.getControl(CONTROL_NAME_TEST_PATH)->getSignal()->connect(boost::bind(&LLFloaterPathfindingConsole::handleNavMeshColorChange, this, _1, _2));
+ }
+ if (!mSavedSettingWaterSlot.connected())
+ {
+ mSavedSettingWaterSlot = gSavedSettings.getControl(CONTROL_NAME_WATER)->getSignal()->connect(boost::bind(&LLFloaterPathfindingConsole::handleNavMeshColorChange, this, _1, _2));
+ }
+}
+
+void LLFloaterPathfindingConsole::deregisterSavedSettingsListeners()
+{
+ if (mSavedSettingRetrieveNeighborSlot.connected())
+ {
+ mSavedSettingRetrieveNeighborSlot.disconnect();
+ }
+ if (mSavedSettingWalkableSlot.connected())
+ {
+ mSavedSettingWalkableSlot.disconnect();
+ }
+ if (mSavedSettingStaticObstacleSlot.connected())
+ {
+ mSavedSettingStaticObstacleSlot.disconnect();
+ }
+ if (mSavedSettingMaterialVolumeSlot.connected())
+ {
+ mSavedSettingMaterialVolumeSlot.disconnect();
+ }
+ if (mSavedSettingExclusionVolumeSlot.connected())
+ {
+ mSavedSettingExclusionVolumeSlot.disconnect();
+ }
+ if (mSavedSettingInteriorEdgeSlot.connected())
+ {
+ mSavedSettingInteriorEdgeSlot.disconnect();
+ }
+ if (mSavedSettingExteriorEdgeSlot.connected())
+ {
+ mSavedSettingExteriorEdgeSlot.disconnect();
+ }
+ if (mSavedSettingHeatmapMinSlot.connected())
+ {
+ mSavedSettingHeatmapMinSlot.disconnect();
+ }
+ if (mSavedSettingHeatmapMaxSlot.connected())
+ {
+ mSavedSettingHeatmapMaxSlot.disconnect();
+ }
+ if (mSavedSettingNavMeshFaceSlot.connected())
+ {
+ mSavedSettingNavMeshFaceSlot.disconnect();
+ }
+ if (mSavedSettingTestPathValidEndSlot.connected())
+ {
+ mSavedSettingTestPathValidEndSlot.disconnect();
+ }
+ if (mSavedSettingTestPathInvalidEndSlot.connected())
+ {
+ mSavedSettingTestPathInvalidEndSlot.disconnect();
+ }
+ if (mSavedSettingTestPathSlot.connected())
+ {
+ mSavedSettingTestPathSlot.disconnect();
+ }
+ if (mSavedSettingWaterSlot.connected())
+ {
+ mSavedSettingWaterSlot.disconnect();
+ }
+}
+
+void LLFloaterPathfindingConsole::handleRetrieveNeighborChange(LLControlVariable *pControl, const LLSD &pNewValue)
+{
+ initializeNavMeshZoneForCurrentRegion();
+}
+
+void LLFloaterPathfindingConsole::handleNavMeshColorChange(LLControlVariable *pControl, const LLSD &pNewValue)
+{
+ fillInColorsForNavMeshVisualization();
+}
+
+void LLFloaterPathfindingConsole::fillInColorsForNavMeshVisualization()
+{
+ if (LLPathingLib::getInstance() != NULL)
+ {
+ LLPathingLib::NavMeshColors navMeshColors;
+
+ LLColor4 in = gSavedSettings.getColor4(CONTROL_NAME_WALKABLE_OBJECTS);
+ navMeshColors.mWalkable= LLColor4U(in);
+
+ in = gSavedSettings.getColor4(CONTROL_NAME_STATIC_OBSTACLE_OBJECTS);
+ navMeshColors.mObstacle= LLColor4U(in);
+
+ in = gSavedSettings.getColor4(CONTROL_NAME_MATERIAL_VOLUMES);
+ navMeshColors.mMaterial= LLColor4U(in);
+
+ in = gSavedSettings.getColor4(CONTROL_NAME_EXCLUSION_VOLUMES);
+ navMeshColors.mExclusion= LLColor4U(in);
+
+ in = gSavedSettings.getColor4(CONTROL_NAME_INTERIOR_EDGE);
+ navMeshColors.mConnectedEdge= LLColor4U(in);
+
+ in = gSavedSettings.getColor4(CONTROL_NAME_EXTERIOR_EDGE);
+ navMeshColors.mBoundaryEdge= LLColor4U(in);
+
+ navMeshColors.mHeatColorBase = gSavedSettings.getColor4(CONTROL_NAME_HEATMAP_MIN);
+
+ navMeshColors.mHeatColorMax = gSavedSettings.getColor4(CONTROL_NAME_HEATMAP_MAX);
+
+ in = gSavedSettings.getColor4(CONTROL_NAME_NAVMESH_FACE);
+ navMeshColors.mFaceColor= LLColor4U(in);
+
+ in = gSavedSettings.getColor4(CONTROL_NAME_TEST_PATH_VALID_END);
+ navMeshColors.mStarValid= LLColor4U(in);
+
+ in = gSavedSettings.getColor4(CONTROL_NAME_TEST_PATH_INVALID_END);
+ navMeshColors.mStarInvalid= LLColor4U(in);
+
+ in = gSavedSettings.getColor4(CONTROL_NAME_TEST_PATH);
+ navMeshColors.mTestPath= LLColor4U(in);
+
+ in = gSavedSettings.getColor4(CONTROL_NAME_WATER);
+ navMeshColors.mWaterColor= LLColor4U(in);
+
+ LLPathingLib::getInstance()->setNavMeshColors(navMeshColors);
+ }
+}
diff --git a/indra/newview/llfloaterpathfindingconsole.h b/indra/newview/llfloaterpathfindingconsole.h
new file mode 100755
index 0000000000..e999e57741
--- /dev/null
+++ b/indra/newview/llfloaterpathfindingconsole.h
@@ -0,0 +1,220 @@
+/**
+* @file llfloaterpathfindingconsole.h
+* @brief "Pathfinding console" floater, allowing for viewing and testing of the pathfinding navmesh through Havok AI utilities.
+* @author Stinson@lindenlab.com
+*
+* $LicenseInfo:firstyear=2012&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2012, 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_LLFLOATERPATHFINDINGCONSOLE_H
+#define LL_LLFLOATERPATHFINDINGCONSOLE_H
+
+#include <vector>
+
+#include <boost/signals2.hpp>
+
+#include "llfloater.h"
+#include "llhandle.h"
+#include "llpathfindingnavmeshzone.h"
+#include "llpathfindingpathtool.h"
+#include "llpathinglib.h"
+#include "v4color.h"
+
+class LLButton;
+class LLCheckBoxCtrl;
+class LLComboBox;
+class LLControlVariable;
+class LLPanel;
+class LLSD;
+class LLSliderCtrl;
+class LLTabContainer;
+class LLTextBase;
+class LLToolset;
+
+class LLFloaterPathfindingConsole
+: public LLFloater
+{
+ friend class LLFloaterReg;
+
+public:
+ virtual BOOL postBuild();
+ virtual void onOpen(const LLSD& pKey);
+ virtual void onClose(bool pIsAppQuitting);
+
+ static LLHandle<LLFloaterPathfindingConsole> getInstanceHandle();
+
+ BOOL isRenderNavMesh() const;
+ void setRenderNavMesh(BOOL pIsRenderNavMesh);
+
+ BOOL isRenderWalkables() const;
+ void setRenderWalkables(BOOL pIsRenderWalkables);
+
+ BOOL isRenderStaticObstacles() const;
+ void setRenderStaticObstacles(BOOL pIsRenderStaticObstacles);
+
+ BOOL isRenderMaterialVolumes() const;
+ void setRenderMaterialVolumes(BOOL pIsRenderMaterialVolumes);
+
+ BOOL isRenderExclusionVolumes() const;
+ void setRenderExclusionVolumes(BOOL pIsRenderExclusionVolumes);
+
+ BOOL isRenderWorld() const;
+ void setRenderWorld(BOOL pIsRenderWorld);
+
+ BOOL isRenderWorldMovablesOnly() const;
+ void setRenderWorldMovablesOnly(BOOL pIsRenderWorldMovablesOnly);
+
+ BOOL isRenderWaterPlane() const;
+ void setRenderWaterPlane(BOOL pIsRenderWaterPlane);
+
+ BOOL isRenderXRay() const;
+ void setRenderXRay(BOOL pIsRenderXRay);
+
+ BOOL isRenderAnyShapes() const;
+ U32 getRenderShapeFlags();
+
+ LLPathingLib::LLPLCharacterType getRenderHeatmapType() const;
+ void setRenderHeatmapType(LLPathingLib::LLPLCharacterType pRenderHeatmapType);
+ void onRegionBoundaryCross();
+protected:
+
+private:
+ typedef enum
+ {
+ kConsoleStateUnknown,
+ kConsoleStateLibraryNotImplemented,
+ kConsoleStateRegionNotEnabled,
+ kConsoleStateRegionLoading,
+ kConsoleStateCheckingVersion,
+ kConsoleStateDownloading,
+ kConsoleStateHasNavMesh,
+ kConsoleStateError
+ } EConsoleState;
+
+ // Does its own instance management, so clients not allowed
+ // to allocate or destroy.
+ LLFloaterPathfindingConsole(const LLSD& pSeed);
+ virtual ~LLFloaterPathfindingConsole();
+
+ void onTabSwitch();
+ void onShowWorldSet();
+ void onShowWorldMovablesOnlySet();
+ void onShowNavMeshSet();
+ void onShowWalkabilitySet();
+ void onCharacterWidthSet();
+ void onCharacterTypeSwitch();
+ void onClearPathClicked();
+
+ void handleNavMeshZoneStatus(LLPathfindingNavMeshZone::ENavMeshZoneRequestStatus pNavMeshZoneRequestStatus);
+
+ void onPathEvent();
+
+ void setDefaultInputs();
+ void setConsoleState(EConsoleState pConsoleState);
+ void setWorldRenderState();
+ void setNavMeshRenderState();
+ void updateRenderablesObjects();
+
+ void updateControlsOnConsoleState();
+ void updateViewerStatusOnConsoleState();
+ void updateSimulatorStatusOnConsoleState();
+
+ void initializeNavMeshZoneForCurrentRegion();
+
+ void switchIntoTestPathMode();
+ void switchOutOfTestPathMode();
+ void updateCharacterWidth();
+ void updateCharacterType();
+ void clearPath();
+ void updatePathTestStatus();
+
+ void registerSavedSettingsListeners();
+ void deregisterSavedSettingsListeners();
+ void handleRetrieveNeighborChange(LLControlVariable *pControl, const LLSD &pNewValue);
+ void handleNavMeshColorChange(LLControlVariable *pControl, const LLSD &pNewValue);
+ void fillInColorsForNavMeshVisualization();
+ void cleanupRenderableRestoreItems();
+
+ LLRootHandle<LLFloaterPathfindingConsole> mSelfHandle;
+ LLTabContainer *mViewTestTabContainer;
+ LLPanel *mViewTab;
+ LLTextBase *mShowLabel;
+ LLCheckBoxCtrl *mShowWorldCheckBox;
+ LLCheckBoxCtrl *mShowWorldMovablesOnlyCheckBox;
+ LLCheckBoxCtrl *mShowNavMeshCheckBox;
+ LLTextBase *mShowNavMeshWalkabilityLabel;
+ LLComboBox *mShowNavMeshWalkabilityComboBox;
+ LLCheckBoxCtrl *mShowWalkablesCheckBox;
+ LLCheckBoxCtrl *mShowStaticObstaclesCheckBox;
+ LLCheckBoxCtrl *mShowMaterialVolumesCheckBox;
+ LLCheckBoxCtrl *mShowExclusionVolumesCheckBox;
+ LLCheckBoxCtrl *mShowRenderWaterPlaneCheckBox;
+ LLCheckBoxCtrl *mShowXRayCheckBox;
+ LLTextBase *mPathfindingViewerStatus;
+ LLTextBase *mPathfindingSimulatorStatus;
+ LLPanel *mTestTab;
+ LLTextBase *mCtrlClickLabel;
+ LLTextBase *mShiftClickLabel;
+ LLTextBase *mCharacterWidthLabel;
+ LLTextBase *mCharacterWidthUnitLabel;
+ LLSliderCtrl *mCharacterWidthSlider;
+ LLTextBase *mCharacterTypeLabel;
+ LLComboBox *mCharacterTypeComboBox;
+ LLTextBase *mPathTestingStatus;
+ LLButton *mClearPathButton;
+
+ LLColor4 mErrorColor;
+ LLColor4 mWarningColor;
+
+ LLPathfindingNavMeshZone::navmesh_zone_slot_t mNavMeshZoneSlot;
+ LLPathfindingNavMeshZone mNavMeshZone;
+ bool mIsNavMeshUpdating;
+
+ boost::signals2::connection mRegionBoundarySlot;
+ boost::signals2::connection mTeleportFailedSlot;
+ LLPathfindingPathTool::path_event_slot_t mPathEventSlot;
+
+ LLToolset *mPathfindingToolset;
+ LLToolset *mSavedToolset;
+
+ boost::signals2::connection mSavedSettingRetrieveNeighborSlot;
+ boost::signals2::connection mSavedSettingWalkableSlot;
+ boost::signals2::connection mSavedSettingStaticObstacleSlot;
+ boost::signals2::connection mSavedSettingMaterialVolumeSlot;
+ boost::signals2::connection mSavedSettingExclusionVolumeSlot;
+ boost::signals2::connection mSavedSettingInteriorEdgeSlot;
+ boost::signals2::connection mSavedSettingExteriorEdgeSlot;
+ boost::signals2::connection mSavedSettingHeatmapMinSlot;
+ boost::signals2::connection mSavedSettingHeatmapMaxSlot;
+ boost::signals2::connection mSavedSettingNavMeshFaceSlot;
+ boost::signals2::connection mSavedSettingTestPathValidEndSlot;
+ boost::signals2::connection mSavedSettingTestPathInvalidEndSlot;
+ boost::signals2::connection mSavedSettingTestPathSlot;
+ boost::signals2::connection mSavedSettingWaterSlot;
+
+ EConsoleState mConsoleState;
+
+ std::vector<U32> mRenderableRestoreList;
+
+ static LLHandle<LLFloaterPathfindingConsole> sInstanceHandle;
+};
+
+#endif // LL_LLFLOATERPATHFINDINGCONSOLE_H
diff --git a/indra/newview/llfloaterpathfindinglinksets.cpp b/indra/newview/llfloaterpathfindinglinksets.cpp
new file mode 100755
index 0000000000..1e46d7a402
--- /dev/null
+++ b/indra/newview/llfloaterpathfindinglinksets.cpp
@@ -0,0 +1,804 @@
+/**
+* @file llfloaterpathfindinglinksets.cpp
+* @brief "Pathfinding linksets" floater, allowing manipulation of the linksets on the current region.
+* @author Stinson@lindenlab.com
+*
+* $LicenseInfo:firstyear=2012&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2012, 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 "llfloaterpathfindinglinksets.h"
+
+#include <string>
+
+#include <boost/bind.hpp>
+
+#include "llagent.h"
+#include "llbutton.h"
+#include "llcombobox.h"
+#include "llfloaterpathfindingobjects.h"
+#include "llfloaterreg.h"
+#include "lllineeditor.h"
+#include "llnotificationsutil.h"
+#include "llpathfindinglinkset.h"
+#include "llpathfindinglinksetlist.h"
+#include "llpathfindingmanager.h"
+#include "llscrolllistitem.h"
+#include "llsd.h"
+#include "lltextbase.h"
+#include "lltextvalidate.h"
+#include "lluicolortable.h"
+#include "lluictrl.h"
+#include "v3math.h"
+#include "v4color.h"
+
+#define XUI_LINKSET_USE_NONE 0
+#define XUI_LINKSET_USE_WALKABLE 1
+#define XUI_LINKSET_USE_STATIC_OBSTACLE 2
+#define XUI_LINKSET_USE_DYNAMIC_OBSTACLE 3
+#define XUI_LINKSET_USE_MATERIAL_VOLUME 4
+#define XUI_LINKSET_USE_EXCLUSION_VOLUME 5
+#define XUI_LINKSET_USE_DYNAMIC_PHANTOM 6
+
+//---------------------------------------------------------------------------
+// LLFloaterPathfindingLinksets
+//---------------------------------------------------------------------------
+
+void LLFloaterPathfindingLinksets::openLinksetsWithSelectedObjects()
+{
+ LLFloaterPathfindingLinksets *linksetsFloater = LLFloaterReg::getTypedInstance<LLFloaterPathfindingLinksets>("pathfinding_linksets");
+ linksetsFloater->clearFilters();
+ linksetsFloater->showFloaterWithSelectionObjects();
+}
+
+LLFloaterPathfindingLinksets::LLFloaterPathfindingLinksets(const LLSD& pSeed)
+ : LLFloaterPathfindingObjects(pSeed),
+ mFilterByName(NULL),
+ mFilterByDescription(NULL),
+ mFilterByLinksetUse(NULL),
+ mEditLinksetUse(NULL),
+ mEditLinksetUseWalkable(NULL),
+ mEditLinksetUseStaticObstacle(NULL),
+ mEditLinksetUseDynamicObstacle(NULL),
+ mEditLinksetUseMaterialVolume(NULL),
+ mEditLinksetUseExclusionVolume(NULL),
+ mEditLinksetUseDynamicPhantom(NULL),
+ mLabelWalkabilityCoefficients(NULL),
+ mLabelEditA(NULL),
+ mLabelSuggestedUseA(NULL),
+ mEditA(NULL),
+ mLabelEditB(NULL),
+ mLabelSuggestedUseB(NULL),
+ mEditB(NULL),
+ mLabelEditC(NULL),
+ mLabelSuggestedUseC(NULL),
+ mEditC(NULL),
+ mLabelEditD(NULL),
+ mLabelSuggestedUseD(NULL),
+ mEditD(NULL),
+ mApplyEditsButton(NULL),
+ mBeaconColor(),
+ mPreviousValueA(LLPathfindingLinkset::MAX_WALKABILITY_VALUE),
+ mPreviousValueB(LLPathfindingLinkset::MAX_WALKABILITY_VALUE),
+ mPreviousValueC(LLPathfindingLinkset::MAX_WALKABILITY_VALUE),
+ mPreviousValueD(LLPathfindingLinkset::MAX_WALKABILITY_VALUE)
+{
+}
+
+LLFloaterPathfindingLinksets::~LLFloaterPathfindingLinksets()
+{
+}
+
+BOOL LLFloaterPathfindingLinksets::postBuild()
+{
+ mBeaconColor = LLUIColorTable::getInstance()->getColor("PathfindingLinksetBeaconColor");
+
+ mFilterByName = findChild<LLLineEditor>("filter_by_name");
+ llassert(mFilterByName != NULL);
+ mFilterByName->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onApplyAllFilters, this));
+ mFilterByName->setSelectAllonFocusReceived(true);
+ mFilterByName->setCommitOnFocusLost(true);
+
+ mFilterByDescription = findChild<LLLineEditor>("filter_by_description");
+ llassert(mFilterByDescription != NULL);
+ mFilterByDescription->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onApplyAllFilters, this));
+ mFilterByDescription->setSelectAllonFocusReceived(true);
+ mFilterByDescription->setCommitOnFocusLost(true);
+
+ mFilterByLinksetUse = findChild<LLComboBox>("filter_by_linkset_use");
+ llassert(mFilterByLinksetUse != NULL);
+ mFilterByLinksetUse->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onApplyAllFilters, this));
+
+ childSetAction("apply_filters", boost::bind(&LLFloaterPathfindingLinksets::onApplyAllFilters, this));
+ childSetAction("clear_filters", boost::bind(&LLFloaterPathfindingLinksets::onClearFiltersClicked, this));
+
+ mEditLinksetUse = findChild<LLComboBox>("edit_linkset_use");
+ llassert(mEditLinksetUse != NULL);
+ mEditLinksetUse->clearRows();
+
+ mEditLinksetUseUnset = mEditLinksetUse->addElement(buildLinksetUseScrollListData(getString("linkset_choose_use"), XUI_LINKSET_USE_NONE));
+ llassert(mEditLinksetUseUnset != NULL);
+
+ mEditLinksetUseWalkable = mEditLinksetUse->addElement(buildLinksetUseScrollListData(getLinksetUseString(LLPathfindingLinkset::kWalkable), XUI_LINKSET_USE_WALKABLE));
+ llassert(mEditLinksetUseWalkable != NULL);
+
+ mEditLinksetUseStaticObstacle = mEditLinksetUse->addElement(buildLinksetUseScrollListData(getLinksetUseString(LLPathfindingLinkset::kStaticObstacle), XUI_LINKSET_USE_STATIC_OBSTACLE));
+ llassert(mEditLinksetUseStaticObstacle != NULL);
+
+ mEditLinksetUseDynamicObstacle = mEditLinksetUse->addElement(buildLinksetUseScrollListData(getLinksetUseString(LLPathfindingLinkset::kDynamicObstacle), XUI_LINKSET_USE_DYNAMIC_OBSTACLE));
+ llassert(mEditLinksetUseDynamicObstacle != NULL);
+
+ mEditLinksetUseMaterialVolume = mEditLinksetUse->addElement(buildLinksetUseScrollListData(getLinksetUseString(LLPathfindingLinkset::kMaterialVolume), XUI_LINKSET_USE_MATERIAL_VOLUME));
+ llassert(mEditLinksetUseMaterialVolume != NULL);
+
+ mEditLinksetUseExclusionVolume = mEditLinksetUse->addElement(buildLinksetUseScrollListData(getLinksetUseString(LLPathfindingLinkset::kExclusionVolume), XUI_LINKSET_USE_EXCLUSION_VOLUME));
+ llassert(mEditLinksetUseExclusionVolume != NULL);
+
+ mEditLinksetUseDynamicPhantom = mEditLinksetUse->addElement(buildLinksetUseScrollListData(getLinksetUseString(LLPathfindingLinkset::kDynamicPhantom), XUI_LINKSET_USE_DYNAMIC_PHANTOM));
+ llassert(mEditLinksetUseDynamicPhantom != NULL);
+
+ mEditLinksetUse->selectFirstItem();
+
+ mLabelWalkabilityCoefficients = findChild<LLTextBase>("walkability_coefficients_label");
+ llassert(mLabelWalkabilityCoefficients != NULL);
+
+ mLabelEditA = findChild<LLTextBase>("edit_a_label");
+ llassert(mLabelEditA != NULL);
+
+ mLabelSuggestedUseA = findChild<LLTextBase>("suggested_use_a_label");
+ llassert(mLabelSuggestedUseA != NULL);
+
+ mEditA = findChild<LLLineEditor>("edit_a_value");
+ llassert(mEditA != NULL);
+ mEditA->setPrevalidate(LLTextValidate::validateNonNegativeS32);
+ mEditA->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onWalkabilityCoefficientEntered, this, _1, mPreviousValueA));
+
+ mLabelEditB = findChild<LLTextBase>("edit_b_label");
+ llassert(mLabelEditB != NULL);
+
+ mLabelSuggestedUseB = findChild<LLTextBase>("suggested_use_b_label");
+ llassert(mLabelSuggestedUseB != NULL);
+
+ mEditB = findChild<LLLineEditor>("edit_b_value");
+ llassert(mEditB != NULL);
+ mEditB->setPrevalidate(LLTextValidate::validateNonNegativeS32);
+ mEditB->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onWalkabilityCoefficientEntered, this, _1, mPreviousValueB));
+
+ mLabelEditC = findChild<LLTextBase>("edit_c_label");
+ llassert(mLabelEditC != NULL);
+
+ mLabelSuggestedUseC = findChild<LLTextBase>("suggested_use_c_label");
+ llassert(mLabelSuggestedUseC != NULL);
+
+ mEditC = findChild<LLLineEditor>("edit_c_value");
+ llassert(mEditC != NULL);
+ mEditC->setPrevalidate(LLTextValidate::validateNonNegativeS32);
+ mEditC->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onWalkabilityCoefficientEntered, this, _1, mPreviousValueC));
+
+ mLabelEditD = findChild<LLTextBase>("edit_d_label");
+ llassert(mLabelEditD != NULL);
+
+ mLabelSuggestedUseD = findChild<LLTextBase>("suggested_use_d_label");
+ llassert(mLabelSuggestedUseD != NULL);
+
+ mEditD = findChild<LLLineEditor>("edit_d_value");
+ llassert(mEditD != NULL);
+ mEditD->setPrevalidate(LLTextValidate::validateNonNegativeS32);
+ mEditD->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onWalkabilityCoefficientEntered, this, _1, mPreviousValueD));
+
+ mApplyEditsButton = findChild<LLButton>("apply_edit_values");
+ llassert(mApplyEditsButton != NULL);
+ mApplyEditsButton->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onApplyChangesClicked, this));
+
+ return LLFloaterPathfindingObjects::postBuild();
+}
+
+void LLFloaterPathfindingLinksets::requestGetObjects()
+{
+ LLPathfindingManager::getInstance()->requestGetLinksets(getNewRequestId(), boost::bind(&LLFloaterPathfindingLinksets::handleNewObjectList, this, _1, _2, _3));
+}
+
+void LLFloaterPathfindingLinksets::buildObjectsScrollList(const LLPathfindingObjectListPtr pObjectListPtr)
+{
+ llassert(pObjectListPtr != NULL);
+ llassert(!pObjectListPtr->isEmpty());
+
+ std::string nameFilter = mFilterByName->getText();
+ std::string descriptionFilter = mFilterByDescription->getText();
+ LLPathfindingLinkset::ELinksetUse linksetUseFilter = getFilterLinksetUse();
+ bool isFilteringName = !nameFilter.empty();
+ bool isFilteringDescription = !descriptionFilter.empty();
+ bool isFilteringLinksetUse = (linksetUseFilter != LLPathfindingLinkset::kUnknown);
+
+ const LLVector3& avatarPosition = gAgent.getPositionAgent();
+
+ if (isFilteringName || isFilteringDescription || isFilteringLinksetUse)
+ {
+ LLStringUtil::toUpper(nameFilter);
+ LLStringUtil::toUpper(descriptionFilter);
+ for (LLPathfindingObjectList::const_iterator objectIter = pObjectListPtr->begin(); objectIter != pObjectListPtr->end(); ++objectIter)
+ {
+ const LLPathfindingObjectPtr objectPtr = objectIter->second;
+ const LLPathfindingLinkset *linksetPtr = dynamic_cast<const LLPathfindingLinkset *>(objectPtr.get());
+ llassert(linksetPtr != NULL);
+
+ std::string linksetName = (linksetPtr->isTerrain() ? getString("linkset_terrain_name") : linksetPtr->getName());
+ std::string linksetDescription = linksetPtr->getDescription();
+ LLStringUtil::toUpper(linksetName);
+ LLStringUtil::toUpper(linksetDescription);
+
+ if ((!isFilteringName || (linksetName.find(nameFilter) != std::string::npos)) &&
+ (!isFilteringDescription || (linksetDescription.find(descriptionFilter) != std::string::npos)) &&
+ (!isFilteringLinksetUse || (linksetPtr->getLinksetUse() == linksetUseFilter)))
+ {
+ LLSD scrollListItemData = buildLinksetScrollListItemData(linksetPtr, avatarPosition);
+ addObjectToScrollList(objectPtr, scrollListItemData);
+ }
+ }
+ }
+ else
+ {
+ for (LLPathfindingObjectList::const_iterator objectIter = pObjectListPtr->begin(); objectIter != pObjectListPtr->end(); ++objectIter)
+ {
+ const LLPathfindingObjectPtr objectPtr = objectIter->second;
+ const LLPathfindingLinkset *linksetPtr = dynamic_cast<const LLPathfindingLinkset *>(objectPtr.get());
+ llassert(linksetPtr != NULL);
+
+ LLSD scrollListItemData = buildLinksetScrollListItemData(linksetPtr, avatarPosition);
+ addObjectToScrollList(objectPtr, scrollListItemData);
+ }
+ }
+}
+
+void LLFloaterPathfindingLinksets::updateControlsOnScrollListChange()
+{
+ LLFloaterPathfindingObjects::updateControlsOnScrollListChange();
+ updateEditFieldValues();
+ updateStateOnEditFields();
+ updateStateOnEditLinksetUse();
+}
+
+S32 LLFloaterPathfindingLinksets::getNameColumnIndex() const
+{
+ return 0;
+}
+
+S32 LLFloaterPathfindingLinksets::getOwnerNameColumnIndex() const
+{
+ return 2;
+}
+
+std::string LLFloaterPathfindingLinksets::getOwnerName(const LLPathfindingObject *pObject) const
+{
+ return (pObject->hasOwner()
+ ? (pObject->hasOwnerName()
+ ? (pObject->isGroupOwned()
+ ? (pObject->getOwnerName() + " " + getString("linkset_owner_group"))
+ : pObject->getOwnerName())
+ : getString("linkset_owner_loading"))
+ : getString("linkset_owner_unknown"));
+}
+
+const LLColor4 &LLFloaterPathfindingLinksets::getBeaconColor() const
+{
+ return mBeaconColor;
+}
+
+LLPathfindingObjectListPtr LLFloaterPathfindingLinksets::getEmptyObjectList() const
+{
+ LLPathfindingObjectListPtr objectListPtr(new LLPathfindingLinksetList());
+ return objectListPtr;
+}
+
+void LLFloaterPathfindingLinksets::requestSetLinksets(LLPathfindingObjectListPtr pLinksetList, LLPathfindingLinkset::ELinksetUse pLinksetUse, S32 pA, S32 pB, S32 pC, S32 pD)
+{
+ LLPathfindingManager::getInstance()->requestSetLinksets(getNewRequestId(), pLinksetList, pLinksetUse, pA, pB, pC, pD, boost::bind(&LLFloaterPathfindingLinksets::handleUpdateObjectList, this, _1, _2, _3));
+}
+
+void LLFloaterPathfindingLinksets::onApplyAllFilters()
+{
+ rebuildObjectsScrollList();
+}
+
+void LLFloaterPathfindingLinksets::onClearFiltersClicked()
+{
+ clearFilters();
+ rebuildObjectsScrollList();
+}
+
+void LLFloaterPathfindingLinksets::onWalkabilityCoefficientEntered(LLUICtrl *pUICtrl, LLSD &pPreviousValue)
+{
+ LLLineEditor *pLineEditor = static_cast<LLLineEditor *>(pUICtrl);
+ llassert(pLineEditor != NULL);
+
+ const std::string &valueString = pLineEditor->getText();
+
+ S32 intValue;
+ LLSD value;
+ bool doResetValue = false;
+
+ if (valueString.empty())
+ {
+ value = pPreviousValue;
+ doResetValue = true;
+ }
+ else if (LLStringUtil::convertToS32(valueString, intValue))
+ {
+ doResetValue = ((intValue < LLPathfindingLinkset::MIN_WALKABILITY_VALUE) || (intValue > LLPathfindingLinkset::MAX_WALKABILITY_VALUE));
+ value = LLSD(llclamp(intValue, LLPathfindingLinkset::MIN_WALKABILITY_VALUE, LLPathfindingLinkset::MAX_WALKABILITY_VALUE));
+ }
+ else
+ {
+ value = LLSD(LLPathfindingLinkset::MAX_WALKABILITY_VALUE);
+ doResetValue = true;
+ }
+
+ if (doResetValue)
+ {
+ pLineEditor->setValue(value);
+ }
+ pPreviousValue = value;
+}
+
+void LLFloaterPathfindingLinksets::onApplyChangesClicked()
+{
+ applyEdit();
+}
+
+void LLFloaterPathfindingLinksets::clearFilters()
+{
+ mFilterByName->clear();
+ mFilterByDescription->clear();
+ setFilterLinksetUse(LLPathfindingLinkset::kUnknown);
+}
+
+void LLFloaterPathfindingLinksets::updateEditFieldValues()
+{
+ int numSelectedObjects = getNumSelectedObjects();
+ if (numSelectedObjects <= 0)
+ {
+ mEditLinksetUse->selectFirstItem();
+ mEditA->clear();
+ mEditB->clear();
+ mEditC->clear();
+ mEditD->clear();
+ }
+ else
+ {
+ LLPathfindingObjectPtr firstSelectedObjectPtr = getFirstSelectedObject();
+ llassert(firstSelectedObjectPtr != NULL);
+
+ const LLPathfindingLinkset *linkset = dynamic_cast<const LLPathfindingLinkset *>(firstSelectedObjectPtr.get());
+
+ setEditLinksetUse(linkset->getLinksetUse());
+ mPreviousValueA = LLSD(linkset->getWalkabilityCoefficientA());
+ mPreviousValueB = LLSD(linkset->getWalkabilityCoefficientB());
+ mPreviousValueC = LLSD(linkset->getWalkabilityCoefficientC());
+ mPreviousValueD = LLSD(linkset->getWalkabilityCoefficientD());
+ mEditA->setValue(mPreviousValueA);
+ mEditB->setValue(mPreviousValueB);
+ mEditC->setValue(mPreviousValueC);
+ mEditD->setValue(mPreviousValueD);
+ }
+}
+
+LLSD LLFloaterPathfindingLinksets::buildLinksetScrollListItemData(const LLPathfindingLinkset *pLinksetPtr, const LLVector3 &pAvatarPosition) const
+{
+ llassert(pLinksetPtr != NULL);
+ LLSD columns = LLSD::emptyArray();
+
+ if (pLinksetPtr->isTerrain())
+ {
+ columns[0]["column"] = "name";
+ columns[0]["value"] = getString("linkset_terrain_name");
+
+ columns[1]["column"] = "description";
+ columns[1]["value"] = getString("linkset_terrain_description");
+
+ columns[2]["column"] = "owner";
+ columns[2]["value"] = getString("linkset_terrain_owner");
+
+ columns[3]["column"] = "scripted";
+ columns[3]["value"] = getString("linkset_terrain_scripted");
+
+ columns[4]["column"] = "land_impact";
+ columns[4]["value"] = getString("linkset_terrain_land_impact");
+
+ columns[5]["column"] = "dist_from_you";
+ columns[5]["value"] = getString("linkset_terrain_dist_from_you");
+ }
+ else
+ {
+ columns[0]["column"] = "name";
+ columns[0]["value"] = pLinksetPtr->getName();
+
+ columns[1]["column"] = "description";
+ columns[1]["value"] = pLinksetPtr->getDescription();
+
+ columns[2]["column"] = "owner";
+ columns[2]["value"] = getOwnerName(pLinksetPtr);
+
+ columns[3]["column"] = "scripted";
+ columns[3]["value"] = (pLinksetPtr->hasIsScripted()
+ ? (pLinksetPtr->isScripted()
+ ? getString("linkset_is_scripted")
+ : getString("linkset_is_not_scripted"))
+ : getString("linkset_is_unknown_scripted"));
+
+ columns[4]["column"] = "land_impact";
+ columns[4]["value"] = llformat("%1d", pLinksetPtr->getLandImpact());
+
+ columns[5]["column"] = "dist_from_you";
+ columns[5]["value"] = llformat("%1.0f m", dist_vec(pAvatarPosition, pLinksetPtr->getLocation()));
+ }
+
+ columns[6]["column"] = "linkset_use";
+ std::string linksetUse = getLinksetUseString(pLinksetPtr->getLinksetUse());
+ if (pLinksetPtr->isTerrain())
+ {
+ linksetUse += (" " + getString("linkset_is_terrain"));
+ }
+ else if (!pLinksetPtr->isModifiable() && pLinksetPtr->canBeVolume())
+ {
+ linksetUse += (" " + getString("linkset_is_restricted_state"));
+ }
+ else if (pLinksetPtr->isModifiable() && !pLinksetPtr->canBeVolume())
+ {
+ linksetUse += (" " + getString("linkset_is_non_volume_state"));
+ }
+ else if (!pLinksetPtr->isModifiable() && !pLinksetPtr->canBeVolume())
+ {
+ linksetUse += (" " + getString("linkset_is_restricted_non_volume_state"));
+ }
+ columns[6]["value"] = linksetUse;
+
+ columns[7]["column"] = "a_percent";
+ columns[7]["value"] = llformat("%3d", pLinksetPtr->getWalkabilityCoefficientA());
+
+ columns[8]["column"] = "b_percent";
+ columns[8]["value"] = llformat("%3d", pLinksetPtr->getWalkabilityCoefficientB());
+
+ columns[9]["column"] = "c_percent";
+ columns[9]["value"] = llformat("%3d", pLinksetPtr->getWalkabilityCoefficientC());
+
+ columns[10]["column"] = "d_percent";
+ columns[10]["value"] = llformat("%3d", pLinksetPtr->getWalkabilityCoefficientD());
+
+ return columns;
+}
+
+LLSD LLFloaterPathfindingLinksets::buildLinksetUseScrollListData(const std::string &pLabel, S32 pValue) const
+{
+ LLSD columns;
+
+ columns[0]["column"] = "name";
+ columns[0]["value"] = pLabel;
+ columns[0]["font"] = "SANSSERIF";
+
+ LLSD element;
+ element["value"] = pValue;
+ element["column"] = columns;
+
+ return element;
+}
+
+bool LLFloaterPathfindingLinksets::isShowUnmodifiablePhantomWarning(LLPathfindingLinkset::ELinksetUse pLinksetUse) const
+{
+ bool isShowWarning = false;
+
+ if (pLinksetUse != LLPathfindingLinkset::kUnknown)
+ {
+ LLPathfindingObjectListPtr selectedObjects = getSelectedObjects();
+ if ((selectedObjects != NULL) && !selectedObjects->isEmpty())
+ {
+ const LLPathfindingLinksetList *linksetList = dynamic_cast<const LLPathfindingLinksetList *>(selectedObjects.get());
+ isShowWarning = linksetList->isShowUnmodifiablePhantomWarning(pLinksetUse);
+ }
+ }
+
+ return isShowWarning;
+}
+
+bool LLFloaterPathfindingLinksets::isShowPhantomToggleWarning(LLPathfindingLinkset::ELinksetUse pLinksetUse) const
+{
+ bool isShowWarning = false;
+
+ if (pLinksetUse != LLPathfindingLinkset::kUnknown)
+ {
+ LLPathfindingObjectListPtr selectedObjects = getSelectedObjects();
+ if ((selectedObjects != NULL) && !selectedObjects->isEmpty())
+ {
+ const LLPathfindingLinksetList *linksetList = dynamic_cast<const LLPathfindingLinksetList *>(selectedObjects.get());
+ isShowWarning = linksetList->isShowPhantomToggleWarning(pLinksetUse);
+ }
+ }
+
+ return isShowWarning;
+}
+
+bool LLFloaterPathfindingLinksets::isShowCannotBeVolumeWarning(LLPathfindingLinkset::ELinksetUse pLinksetUse) const
+{
+ bool isShowWarning = false;
+
+ if (pLinksetUse != LLPathfindingLinkset::kUnknown)
+ {
+ LLPathfindingObjectListPtr selectedObjects = getSelectedObjects();
+ if ((selectedObjects != NULL) && !selectedObjects->isEmpty())
+ {
+ const LLPathfindingLinksetList *linksetList = dynamic_cast<const LLPathfindingLinksetList *>(selectedObjects.get());
+ isShowWarning = linksetList->isShowCannotBeVolumeWarning(pLinksetUse);
+ }
+ }
+
+ return isShowWarning;
+}
+
+void LLFloaterPathfindingLinksets::updateStateOnEditFields()
+{
+ int numSelectedItems = getNumSelectedObjects();
+ bool isEditEnabled = (numSelectedItems > 0);
+
+ mEditLinksetUse->setEnabled(isEditEnabled);
+
+ mLabelWalkabilityCoefficients->setEnabled(isEditEnabled);
+ mLabelEditA->setEnabled(isEditEnabled);
+ mLabelEditB->setEnabled(isEditEnabled);
+ mLabelEditC->setEnabled(isEditEnabled);
+ mLabelEditD->setEnabled(isEditEnabled);
+ mLabelSuggestedUseA->setEnabled(isEditEnabled);
+ mLabelSuggestedUseB->setEnabled(isEditEnabled);
+ mLabelSuggestedUseC->setEnabled(isEditEnabled);
+ mLabelSuggestedUseD->setEnabled(isEditEnabled);
+ mEditA->setEnabled(isEditEnabled);
+ mEditB->setEnabled(isEditEnabled);
+ mEditC->setEnabled(isEditEnabled);
+ mEditD->setEnabled(isEditEnabled);
+
+ mApplyEditsButton->setEnabled(isEditEnabled && (getMessagingState() == kMessagingComplete));
+}
+
+void LLFloaterPathfindingLinksets::updateStateOnEditLinksetUse()
+{
+ BOOL useWalkable = FALSE;
+ BOOL useStaticObstacle = FALSE;
+ BOOL useDynamicObstacle = FALSE;
+ BOOL useMaterialVolume = FALSE;
+ BOOL useExclusionVolume = FALSE;
+ BOOL useDynamicPhantom = FALSE;
+
+ LLPathfindingObjectListPtr selectedObjects = getSelectedObjects();
+ if ((selectedObjects != NULL) && !selectedObjects->isEmpty())
+ {
+ const LLPathfindingLinksetList *linksetList = dynamic_cast<const LLPathfindingLinksetList *>(selectedObjects.get());
+ linksetList->determinePossibleStates(useWalkable, useStaticObstacle, useDynamicObstacle, useMaterialVolume, useExclusionVolume, useDynamicPhantom);
+ }
+
+ mEditLinksetUseWalkable->setEnabled(useWalkable);
+ mEditLinksetUseStaticObstacle->setEnabled(useStaticObstacle);
+ mEditLinksetUseDynamicObstacle->setEnabled(useDynamicObstacle);
+ mEditLinksetUseMaterialVolume->setEnabled(useMaterialVolume);
+ mEditLinksetUseExclusionVolume->setEnabled(useExclusionVolume);
+ mEditLinksetUseDynamicPhantom->setEnabled(useDynamicPhantom);
+}
+
+void LLFloaterPathfindingLinksets::applyEdit()
+{
+ LLPathfindingLinkset::ELinksetUse linksetUse = getEditLinksetUse();
+
+ bool showPhantomToggleWarning = isShowPhantomToggleWarning(linksetUse);
+ bool showUnmodifiablePhantomWarning = isShowUnmodifiablePhantomWarning(linksetUse);
+ bool showCannotBeVolumeWarning = isShowCannotBeVolumeWarning(linksetUse);
+
+ if (showPhantomToggleWarning || showUnmodifiablePhantomWarning || showCannotBeVolumeWarning)
+ {
+ LLPathfindingLinkset::ELinksetUse restrictedLinksetUse = LLPathfindingLinkset::getLinksetUseWithToggledPhantom(linksetUse);
+ LLSD substitutions;
+ substitutions["REQUESTED_TYPE"] = getLinksetUseString(linksetUse);
+ substitutions["RESTRICTED_TYPE"] = getLinksetUseString(restrictedLinksetUse);
+
+ // Build one of the following notifications names
+ // - PathfindingLinksets_WarnOnPhantom
+ // - PathfindingLinksets_WarnOnPhantom_MismatchOnRestricted
+ // - PathfindingLinksets_WarnOnPhantom_MismatchOnVolume
+ // - PathfindingLinksets_WarnOnPhantom_MismatchOnRestricted_MismatchOnVolume
+ // - PathfindingLinksets_MismatchOnRestricted
+ // - PathfindingLinksets_MismatchOnVolume
+ // - PathfindingLinksets_MismatchOnRestricted_MismatchOnVolume
+
+ std::string notificationName = "PathfindingLinksets";
+
+ if (showPhantomToggleWarning)
+ {
+ notificationName += "_WarnOnPhantom";
+ }
+ if (showUnmodifiablePhantomWarning)
+ {
+ notificationName += "_MismatchOnRestricted";
+ }
+ if (showCannotBeVolumeWarning)
+ {
+ notificationName += "_MismatchOnVolume";
+ }
+
+ LLNotificationsUtil::add(notificationName, substitutions, LLSD(), boost::bind(&LLFloaterPathfindingLinksets::handleApplyEdit, this, _1, _2));
+ }
+ else
+ {
+ doApplyEdit();
+ }
+}
+
+void LLFloaterPathfindingLinksets::handleApplyEdit(const LLSD &pNotification, const LLSD &pResponse)
+{
+ if (LLNotificationsUtil::getSelectedOption(pNotification, pResponse) == 0)
+ {
+ doApplyEdit();
+ }
+}
+
+void LLFloaterPathfindingLinksets::doApplyEdit()
+{
+ LLPathfindingObjectListPtr selectedObjects = getSelectedObjects();
+ if ((selectedObjects != NULL) && !selectedObjects->isEmpty())
+ {
+ LLPathfindingLinkset::ELinksetUse linksetUse = getEditLinksetUse();
+ const std::string &aString = mEditA->getText();
+ const std::string &bString = mEditB->getText();
+ const std::string &cString = mEditC->getText();
+ const std::string &dString = mEditD->getText();
+ S32 aValue = static_cast<S32>(atoi(aString.c_str()));
+ S32 bValue = static_cast<S32>(atoi(bString.c_str()));
+ S32 cValue = static_cast<S32>(atoi(cString.c_str()));
+ S32 dValue = static_cast<S32>(atoi(dString.c_str()));
+
+
+ requestSetLinksets(selectedObjects, linksetUse, aValue, bValue, cValue, dValue);
+ }
+}
+
+std::string LLFloaterPathfindingLinksets::getLinksetUseString(LLPathfindingLinkset::ELinksetUse pLinksetUse) const
+{
+ std::string linksetUse;
+
+ switch (pLinksetUse)
+ {
+ case LLPathfindingLinkset::kWalkable :
+ linksetUse = getString("linkset_use_walkable");
+ break;
+ case LLPathfindingLinkset::kStaticObstacle :
+ linksetUse = getString("linkset_use_static_obstacle");
+ break;
+ case LLPathfindingLinkset::kDynamicObstacle :
+ linksetUse = getString("linkset_use_dynamic_obstacle");
+ break;
+ case LLPathfindingLinkset::kMaterialVolume :
+ linksetUse = getString("linkset_use_material_volume");
+ break;
+ case LLPathfindingLinkset::kExclusionVolume :
+ linksetUse = getString("linkset_use_exclusion_volume");
+ break;
+ case LLPathfindingLinkset::kDynamicPhantom :
+ linksetUse = getString("linkset_use_dynamic_phantom");
+ break;
+ case LLPathfindingLinkset::kUnknown :
+ default :
+ linksetUse = getString("linkset_use_dynamic_obstacle");
+ llassert(0);
+ break;
+ }
+
+ return linksetUse;
+}
+
+LLPathfindingLinkset::ELinksetUse LLFloaterPathfindingLinksets::getFilterLinksetUse() const
+{
+ return convertToLinksetUse(mFilterByLinksetUse->getValue());
+}
+
+void LLFloaterPathfindingLinksets::setFilterLinksetUse(LLPathfindingLinkset::ELinksetUse pLinksetUse)
+{
+ mFilterByLinksetUse->setValue(convertToXuiValue(pLinksetUse));
+}
+
+LLPathfindingLinkset::ELinksetUse LLFloaterPathfindingLinksets::getEditLinksetUse() const
+{
+ return convertToLinksetUse(mEditLinksetUse->getValue());
+}
+
+void LLFloaterPathfindingLinksets::setEditLinksetUse(LLPathfindingLinkset::ELinksetUse pLinksetUse)
+{
+ mEditLinksetUse->setValue(convertToXuiValue(pLinksetUse));
+}
+
+LLPathfindingLinkset::ELinksetUse LLFloaterPathfindingLinksets::convertToLinksetUse(LLSD pXuiValue) const
+{
+ LLPathfindingLinkset::ELinksetUse linkUse;
+
+ switch (pXuiValue.asInteger())
+ {
+ case XUI_LINKSET_USE_NONE :
+ linkUse = LLPathfindingLinkset::kUnknown;
+ break;
+ case XUI_LINKSET_USE_WALKABLE :
+ linkUse = LLPathfindingLinkset::kWalkable;
+ break;
+ case XUI_LINKSET_USE_STATIC_OBSTACLE :
+ linkUse = LLPathfindingLinkset::kStaticObstacle;
+ break;
+ case XUI_LINKSET_USE_DYNAMIC_OBSTACLE :
+ linkUse = LLPathfindingLinkset::kDynamicObstacle;
+ break;
+ case XUI_LINKSET_USE_MATERIAL_VOLUME :
+ linkUse = LLPathfindingLinkset::kMaterialVolume;
+ break;
+ case XUI_LINKSET_USE_EXCLUSION_VOLUME :
+ linkUse = LLPathfindingLinkset::kExclusionVolume;
+ break;
+ case XUI_LINKSET_USE_DYNAMIC_PHANTOM :
+ linkUse = LLPathfindingLinkset::kDynamicPhantom;
+ break;
+ default :
+ linkUse = LLPathfindingLinkset::kUnknown;
+ llassert(0);
+ break;
+ }
+
+ return linkUse;
+}
+
+LLSD LLFloaterPathfindingLinksets::convertToXuiValue(LLPathfindingLinkset::ELinksetUse pLinksetUse) const
+{
+ LLSD xuiValue;
+
+ switch (pLinksetUse)
+ {
+ case LLPathfindingLinkset::kUnknown :
+ xuiValue = XUI_LINKSET_USE_NONE;
+ break;
+ case LLPathfindingLinkset::kWalkable :
+ xuiValue = XUI_LINKSET_USE_WALKABLE;
+ break;
+ case LLPathfindingLinkset::kStaticObstacle :
+ xuiValue = XUI_LINKSET_USE_STATIC_OBSTACLE;
+ break;
+ case LLPathfindingLinkset::kDynamicObstacle :
+ xuiValue = XUI_LINKSET_USE_DYNAMIC_OBSTACLE;
+ break;
+ case LLPathfindingLinkset::kMaterialVolume :
+ xuiValue = XUI_LINKSET_USE_MATERIAL_VOLUME;
+ break;
+ case LLPathfindingLinkset::kExclusionVolume :
+ xuiValue = XUI_LINKSET_USE_EXCLUSION_VOLUME;
+ break;
+ case LLPathfindingLinkset::kDynamicPhantom :
+ xuiValue = XUI_LINKSET_USE_DYNAMIC_PHANTOM;
+ break;
+ default :
+ xuiValue = XUI_LINKSET_USE_NONE;
+ llassert(0);
+ break;
+ }
+
+ return xuiValue;
+}
diff --git a/indra/newview/llfloaterpathfindinglinksets.h b/indra/newview/llfloaterpathfindinglinksets.h
new file mode 100755
index 0000000000..7149da9215
--- /dev/null
+++ b/indra/newview/llfloaterpathfindinglinksets.h
@@ -0,0 +1,142 @@
+/**
+* @file llfloaterpathfindinglinksets.h
+* @brief "Pathfinding linksets" floater, allowing manipulation of the linksets on the current region.
+* @author Stinson@lindenlab.com
+*
+* $LicenseInfo:firstyear=2012&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2012, 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_LLFLOATERPATHFINDINGLINKSETS_H
+#define LL_LLFLOATERPATHFINDINGLINKSETS_H
+
+#include <string>
+
+#include "llfloaterpathfindingobjects.h"
+#include "llpathfindinglinkset.h"
+#include "llpathfindingobjectlist.h"
+#include "v4color.h"
+
+class LLButton;
+class LLComboBox;
+class LLLineEditor;
+class LLScrollListItem;
+class LLSD;
+class LLTextBase;
+class LLUICtrl;
+class LLVector3;
+
+class LLFloaterPathfindingLinksets : public LLFloaterPathfindingObjects
+{
+public:
+ static void openLinksetsWithSelectedObjects();
+
+protected:
+ friend class LLFloaterReg;
+
+ LLFloaterPathfindingLinksets(const LLSD& pSeed);
+ virtual ~LLFloaterPathfindingLinksets();
+
+ virtual BOOL postBuild();
+
+ virtual void requestGetObjects();
+
+ virtual void buildObjectsScrollList(const LLPathfindingObjectListPtr pObjectListPtr);
+
+ virtual void updateControlsOnScrollListChange();
+
+ virtual S32 getNameColumnIndex() const;
+ virtual S32 getOwnerNameColumnIndex() const;
+ virtual std::string getOwnerName(const LLPathfindingObject *pObject) const;
+ virtual const LLColor4 &getBeaconColor() const;
+
+ virtual LLPathfindingObjectListPtr getEmptyObjectList() const;
+
+private:
+ void requestSetLinksets(LLPathfindingObjectListPtr pLinksetList, LLPathfindingLinkset::ELinksetUse pLinksetUse, S32 pA, S32 pB, S32 pC, S32 pD);
+
+ void onApplyAllFilters();
+ void onClearFiltersClicked();
+ void onWalkabilityCoefficientEntered(LLUICtrl *pUICtrl, LLSD &pPreviousValue);
+ void onApplyChangesClicked();
+
+ void clearFilters();
+
+ void updateEditFieldValues();
+ LLSD buildLinksetScrollListItemData(const LLPathfindingLinkset *pLinksetPtr, const LLVector3 &pAvatarPosition) const;
+ LLSD buildLinksetUseScrollListData(const std::string &pLabel, S32 pValue) const;
+
+ bool isShowUnmodifiablePhantomWarning(LLPathfindingLinkset::ELinksetUse pLinksetUse) const;
+ bool isShowPhantomToggleWarning(LLPathfindingLinkset::ELinksetUse pLinksetUse) const;
+ bool isShowCannotBeVolumeWarning(LLPathfindingLinkset::ELinksetUse pLinksetUse) const;
+
+ void updateStateOnEditFields();
+ void updateStateOnEditLinksetUse();
+
+ void applyEdit();
+ void handleApplyEdit(const LLSD &pNotification, const LLSD &pResponse);
+ void doApplyEdit();
+
+ std::string getLinksetUseString(LLPathfindingLinkset::ELinksetUse pLinksetUse) const;
+
+ LLPathfindingLinkset::ELinksetUse getFilterLinksetUse() const;
+ void setFilterLinksetUse(LLPathfindingLinkset::ELinksetUse pLinksetUse);
+
+ LLPathfindingLinkset::ELinksetUse getEditLinksetUse() const;
+ void setEditLinksetUse(LLPathfindingLinkset::ELinksetUse pLinksetUse);
+
+ LLPathfindingLinkset::ELinksetUse convertToLinksetUse(LLSD pXuiValue) const;
+ LLSD convertToXuiValue(LLPathfindingLinkset::ELinksetUse pLinksetUse) const;
+
+ LLLineEditor *mFilterByName;
+ LLLineEditor *mFilterByDescription;
+ LLComboBox *mFilterByLinksetUse;
+ LLComboBox *mEditLinksetUse;
+ LLScrollListItem *mEditLinksetUseUnset;
+ LLScrollListItem *mEditLinksetUseWalkable;
+ LLScrollListItem *mEditLinksetUseStaticObstacle;
+ LLScrollListItem *mEditLinksetUseDynamicObstacle;
+ LLScrollListItem *mEditLinksetUseMaterialVolume;
+ LLScrollListItem *mEditLinksetUseExclusionVolume;
+ LLScrollListItem *mEditLinksetUseDynamicPhantom;
+ LLTextBase *mLabelWalkabilityCoefficients;
+ LLTextBase *mLabelEditA;
+ LLTextBase *mLabelSuggestedUseA;
+ LLLineEditor *mEditA;
+ LLTextBase *mLabelEditB;
+ LLTextBase *mLabelSuggestedUseB;
+ LLLineEditor *mEditB;
+ LLTextBase *mLabelEditC;
+ LLTextBase *mLabelSuggestedUseC;
+ LLLineEditor *mEditC;
+ LLTextBase *mLabelEditD;
+ LLTextBase *mLabelSuggestedUseD;
+ LLLineEditor *mEditD;
+ LLButton *mApplyEditsButton;
+
+ LLColor4 mBeaconColor;
+
+ LLSD mPreviousValueA;
+ LLSD mPreviousValueB;
+ LLSD mPreviousValueC;
+ LLSD mPreviousValueD;
+};
+
+#endif // LL_LLFLOATERPATHFINDINGLINKSETS_H
diff --git a/indra/newview/llfloaterpathfindingobjects.cpp b/indra/newview/llfloaterpathfindingobjects.cpp
new file mode 100755
index 0000000000..20c1215bcb
--- /dev/null
+++ b/indra/newview/llfloaterpathfindingobjects.cpp
@@ -0,0 +1,884 @@
+/**
+* @file llfloaterpathfindingobjects.cpp
+* @brief Base class for both the pathfinding linksets and characters floater.
+* @author Stinson@lindenlab.com
+*
+* $LicenseInfo:firstyear=2012&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2012, 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 "llfloaterpathfindingobjects.h"
+
+#include <string>
+#include <map>
+#include <vector>
+
+#include <boost/bind.hpp>
+#include <boost/signals2.hpp>
+
+#include "llagent.h"
+#include "llavatarname.h"
+#include "llavatarnamecache.h"
+#include "llbutton.h"
+#include "llcheckboxctrl.h"
+#include "llenvmanager.h"
+#include "llfloater.h"
+#include "llfontgl.h"
+#include "llnotifications.h"
+#include "llnotificationsutil.h"
+#include "llpathfindingmanager.h"
+#include "llresmgr.h"
+#include "llscrolllistcell.h"
+#include "llscrolllistctrl.h"
+#include "llscrolllistitem.h"
+#include "llselectmgr.h"
+#include "llsd.h"
+#include "llstring.h"
+#include "llstyle.h"
+#include "lltextbase.h"
+#include "lluicolortable.h"
+#include "llviewermenu.h"
+#include "llviewerobject.h"
+#include "llviewerobjectlist.h"
+#include "llviewerregion.h"
+#include "v3dmath.h"
+#include "v3math.h"
+#include "v4color.h"
+
+#define DEFAULT_BEACON_WIDTH 6
+
+//---------------------------------------------------------------------------
+// LLFloaterPathfindingObjects
+//---------------------------------------------------------------------------
+
+void LLFloaterPathfindingObjects::onOpen(const LLSD &pKey)
+{
+ LLFloater::onOpen(pKey);
+
+ selectNoneObjects();
+ mObjectsScrollList->setCommitOnSelectionChange(TRUE);
+
+ if (!mSelectionUpdateSlot.connected())
+ {
+ mSelectionUpdateSlot = LLSelectMgr::getInstance()->mUpdateSignal.connect(boost::bind(&LLFloaterPathfindingObjects::onInWorldSelectionListChanged, this));
+ }
+
+ if (!mRegionBoundaryCrossingSlot.connected())
+ {
+ mRegionBoundaryCrossingSlot = LLEnvManagerNew::getInstance()->setRegionChangeCallback(boost::bind(&LLFloaterPathfindingObjects::onRegionBoundaryCrossed, this));
+ }
+
+ if (!mGodLevelChangeSlot.connected())
+ {
+ mGodLevelChangeSlot = gAgent.registerGodLevelChanageListener(boost::bind(&LLFloaterPathfindingObjects::onGodLevelChange, this, _1));
+ }
+
+ requestGetObjects();
+}
+
+void LLFloaterPathfindingObjects::onClose(bool pIsAppQuitting)
+{
+ if (mGodLevelChangeSlot.connected())
+ {
+ mGodLevelChangeSlot.disconnect();
+ }
+
+ if (mRegionBoundaryCrossingSlot.connected())
+ {
+ mRegionBoundaryCrossingSlot.disconnect();
+ }
+
+ if (mSelectionUpdateSlot.connected())
+ {
+ mSelectionUpdateSlot.disconnect();
+ }
+
+ mObjectsScrollList->setCommitOnSelectionChange(FALSE);
+ selectNoneObjects();
+
+ if (mObjectsSelection.notNull())
+ {
+ mObjectsSelection.clear();
+ }
+
+ if (pIsAppQuitting)
+ {
+ clearAllObjects();
+ }
+}
+
+void LLFloaterPathfindingObjects::draw()
+{
+ LLFloater::draw();
+
+ if (isShowBeacons())
+ {
+ std::vector<LLScrollListItem *> selectedItems = mObjectsScrollList->getAllSelected();
+ if (!selectedItems.empty())
+ {
+ int numSelectedItems = selectedItems.size();
+ S32 nameColumnIndex = getNameColumnIndex();
+ const LLColor4 &beaconColor = getBeaconColor();
+ const LLColor4 &beaconTextColor = getBeaconTextColor();
+ S32 beaconWidth = getBeaconWidth();
+
+ std::vector<LLViewerObject *> viewerObjects;
+ viewerObjects.reserve(numSelectedItems);
+
+ for (std::vector<LLScrollListItem *>::const_iterator selectedItemIter = selectedItems.begin();
+ selectedItemIter != selectedItems.end(); ++selectedItemIter)
+ {
+ const LLScrollListItem *selectedItem = *selectedItemIter;
+
+ LLViewerObject *viewerObject = gObjectList.findObject(selectedItem->getUUID());
+ if (viewerObject != NULL)
+ {
+ const std::string &objectName = selectedItem->getColumn(nameColumnIndex)->getValue().asString();
+ gObjectList.addDebugBeacon(viewerObject->getPositionAgent(), objectName, beaconColor, beaconTextColor, beaconWidth);
+ }
+ }
+ }
+ }
+}
+
+LLFloaterPathfindingObjects::LLFloaterPathfindingObjects(const LLSD &pSeed)
+ : LLFloater(pSeed),
+ mObjectsScrollList(NULL),
+ mMessagingStatus(NULL),
+ mRefreshListButton(NULL),
+ mSelectAllButton(NULL),
+ mSelectNoneButton(NULL),
+ mShowBeaconCheckBox(NULL),
+ mTakeButton(NULL),
+ mTakeCopyButton(NULL),
+ mReturnButton(NULL),
+ mDeleteButton(NULL),
+ mTeleportButton(NULL),
+ mDefaultBeaconColor(),
+ mDefaultBeaconTextColor(),
+ mErrorTextColor(),
+ mWarningTextColor(),
+ mMessagingState(kMessagingUnknown),
+ mMessagingRequestId(0U),
+ mMissingNameObjectsScrollListItems(),
+ mObjectList(),
+ mObjectsSelection(),
+ mHasObjectsToBeSelected(false),
+ mObjectsToBeSelected(),
+ mSelectionUpdateSlot(),
+ mRegionBoundaryCrossingSlot()
+{
+}
+
+LLFloaterPathfindingObjects::~LLFloaterPathfindingObjects()
+{
+ clearAllObjects();
+}
+
+BOOL LLFloaterPathfindingObjects::postBuild()
+{
+ mDefaultBeaconColor = LLUIColorTable::getInstance()->getColor("PathfindingDefaultBeaconColor");
+ mDefaultBeaconTextColor = LLUIColorTable::getInstance()->getColor("PathfindingDefaultBeaconTextColor");
+ mErrorTextColor = LLUIColorTable::getInstance()->getColor("PathfindingErrorColor");
+ mWarningTextColor = LLUIColorTable::getInstance()->getColor("PathfindingWarningColor");
+
+ mObjectsScrollList = findChild<LLScrollListCtrl>("objects_scroll_list");
+ llassert(mObjectsScrollList != NULL);
+ mObjectsScrollList->setCommitCallback(boost::bind(&LLFloaterPathfindingObjects::onScrollListSelectionChanged, this));
+ mObjectsScrollList->sortByColumnIndex(static_cast<U32>(getNameColumnIndex()), TRUE);
+
+ mMessagingStatus = findChild<LLTextBase>("messaging_status");
+ llassert(mMessagingStatus != NULL);
+
+ mRefreshListButton = findChild<LLButton>("refresh_objects_list");
+ llassert(mRefreshListButton != NULL);
+ mRefreshListButton->setCommitCallback(boost::bind(&LLFloaterPathfindingObjects::onRefreshObjectsClicked, this));
+
+ mSelectAllButton = findChild<LLButton>("select_all_objects");
+ llassert(mSelectAllButton != NULL);
+ mSelectAllButton->setCommitCallback(boost::bind(&LLFloaterPathfindingObjects::onSelectAllObjectsClicked, this));
+
+ mSelectNoneButton = findChild<LLButton>("select_none_objects");
+ llassert(mSelectNoneButton != NULL);
+ mSelectNoneButton->setCommitCallback(boost::bind(&LLFloaterPathfindingObjects::onSelectNoneObjectsClicked, this));
+
+ mShowBeaconCheckBox = findChild<LLCheckBoxCtrl>("show_beacon");
+ llassert(mShowBeaconCheckBox != NULL);
+
+ mTakeButton = findChild<LLButton>("take_objects");
+ llassert(mTakeButton != NULL);
+ mTakeButton->setCommitCallback(boost::bind(&LLFloaterPathfindingObjects::onTakeClicked, this));
+
+ mTakeCopyButton = findChild<LLButton>("take_copy_objects");
+ llassert(mTakeCopyButton != NULL);
+ mTakeCopyButton->setCommitCallback(boost::bind(&LLFloaterPathfindingObjects::onTakeCopyClicked, this));
+
+ mReturnButton = findChild<LLButton>("return_objects");
+ llassert(mReturnButton != NULL);
+ mReturnButton->setCommitCallback(boost::bind(&LLFloaterPathfindingObjects::onReturnClicked, this));
+
+ mDeleteButton = findChild<LLButton>("delete_objects");
+ llassert(mDeleteButton != NULL);
+ mDeleteButton->setCommitCallback(boost::bind(&LLFloaterPathfindingObjects::onDeleteClicked, this));
+
+ mTeleportButton = findChild<LLButton>("teleport_me_to_object");
+ llassert(mTeleportButton != NULL);
+ mTeleportButton->setCommitCallback(boost::bind(&LLFloaterPathfindingObjects::onTeleportClicked, this));
+
+ return LLFloater::postBuild();
+}
+
+void LLFloaterPathfindingObjects::requestGetObjects()
+{
+ llassert(0);
+}
+
+LLPathfindingManager::request_id_t LLFloaterPathfindingObjects::getNewRequestId()
+{
+ return ++mMessagingRequestId;
+}
+
+void LLFloaterPathfindingObjects::handleNewObjectList(LLPathfindingManager::request_id_t pRequestId, LLPathfindingManager::ERequestStatus pRequestStatus, LLPathfindingObjectListPtr pObjectList)
+{
+ llassert(pRequestId <= mMessagingRequestId);
+ if (pRequestId == mMessagingRequestId)
+ {
+ switch (pRequestStatus)
+ {
+ case LLPathfindingManager::kRequestStarted :
+ setMessagingState(kMessagingGetRequestSent);
+ break;
+ case LLPathfindingManager::kRequestCompleted :
+ mObjectList = pObjectList;
+ rebuildObjectsScrollList();
+ setMessagingState(kMessagingComplete);
+ break;
+ case LLPathfindingManager::kRequestNotEnabled :
+ clearAllObjects();
+ setMessagingState(kMessagingNotEnabled);
+ break;
+ case LLPathfindingManager::kRequestError :
+ clearAllObjects();
+ setMessagingState(kMessagingGetError);
+ break;
+ default :
+ clearAllObjects();
+ setMessagingState(kMessagingGetError);
+ llassert(0);
+ break;
+ }
+ }
+}
+
+void LLFloaterPathfindingObjects::handleUpdateObjectList(LLPathfindingManager::request_id_t pRequestId, LLPathfindingManager::ERequestStatus pRequestStatus, LLPathfindingObjectListPtr pObjectList)
+{
+ // We current assume that handleUpdateObjectList is called only when objects are being SET
+ llassert(pRequestId <= mMessagingRequestId);
+ if (pRequestId == mMessagingRequestId)
+ {
+ switch (pRequestStatus)
+ {
+ case LLPathfindingManager::kRequestStarted :
+ setMessagingState(kMessagingSetRequestSent);
+ break;
+ case LLPathfindingManager::kRequestCompleted :
+ if (mObjectList == NULL)
+ {
+ mObjectList = pObjectList;
+ }
+ else
+ {
+ mObjectList->update(pObjectList);
+ }
+ rebuildObjectsScrollList();
+ setMessagingState(kMessagingComplete);
+ break;
+ case LLPathfindingManager::kRequestNotEnabled :
+ clearAllObjects();
+ setMessagingState(kMessagingNotEnabled);
+ break;
+ case LLPathfindingManager::kRequestError :
+ clearAllObjects();
+ setMessagingState(kMessagingSetError);
+ break;
+ default :
+ clearAllObjects();
+ setMessagingState(kMessagingSetError);
+ llassert(0);
+ break;
+ }
+ }
+}
+
+void LLFloaterPathfindingObjects::rebuildObjectsScrollList()
+{
+ if (!mHasObjectsToBeSelected)
+ {
+ std::vector<LLScrollListItem*> selectedItems = mObjectsScrollList->getAllSelected();
+ int numSelectedItems = selectedItems.size();
+ if (numSelectedItems > 0)
+ {
+ mObjectsToBeSelected.reserve(selectedItems.size());
+ for (std::vector<LLScrollListItem*>::const_iterator itemIter = selectedItems.begin();
+ itemIter != selectedItems.end(); ++itemIter)
+ {
+ const LLScrollListItem *listItem = *itemIter;
+ mObjectsToBeSelected.push_back(listItem->getUUID());
+ }
+ }
+ }
+
+ S32 origScrollPosition = mObjectsScrollList->getScrollPos();
+ mObjectsScrollList->deleteAllItems();
+ mMissingNameObjectsScrollListItems.clear();
+
+ if ((mObjectList != NULL) && !mObjectList->isEmpty())
+ {
+ buildObjectsScrollList(mObjectList);
+
+ mObjectsScrollList->selectMultiple(mObjectsToBeSelected);
+ if (mHasObjectsToBeSelected)
+ {
+ mObjectsScrollList->scrollToShowSelected();
+ }
+ else
+ {
+ mObjectsScrollList->setScrollPos(origScrollPosition);
+ }
+ }
+
+ mObjectsToBeSelected.clear();
+ mHasObjectsToBeSelected = false;
+
+ updateControlsOnScrollListChange();
+}
+
+void LLFloaterPathfindingObjects::buildObjectsScrollList(const LLPathfindingObjectListPtr pObjectListPtr)
+{
+ llassert(0);
+}
+
+void LLFloaterPathfindingObjects::addObjectToScrollList(const LLPathfindingObjectPtr pObjectPtr, const LLSD &pScrollListItemData)
+{
+ LLScrollListCell::Params cellParams;
+ cellParams.font = LLFontGL::getFontSansSerif();
+
+ LLScrollListItem::Params rowParams;
+ rowParams.value = pObjectPtr->getUUID().asString();
+
+ llassert(pScrollListItemData.isArray());
+ for (LLSD::array_const_iterator cellIter = pScrollListItemData.beginArray();
+ cellIter != pScrollListItemData.endArray(); ++cellIter)
+ {
+ const LLSD &cellElement = *cellIter;
+
+ llassert(cellElement.has("column"));
+ llassert(cellElement.get("column").isString());
+ cellParams.column = cellElement.get("column").asString();
+
+ llassert(cellElement.has("value"));
+ llassert(cellElement.get("value").isString());
+ cellParams.value = cellElement.get("value").asString();
+
+ rowParams.columns.add(cellParams);
+ }
+
+ LLScrollListItem *scrollListItem = mObjectsScrollList->addRow(rowParams);
+
+ if (pObjectPtr->hasOwner() && !pObjectPtr->hasOwnerName())
+ {
+ mMissingNameObjectsScrollListItems.insert(std::make_pair<std::string, LLScrollListItem *>(pObjectPtr->getUUID().asString(), scrollListItem));
+ pObjectPtr->registerOwnerNameListener(boost::bind(&LLFloaterPathfindingObjects::handleObjectNameResponse, this, _1));
+ }
+}
+
+void LLFloaterPathfindingObjects::updateControlsOnScrollListChange()
+{
+ updateMessagingStatus();
+ updateStateOnListControls();
+ selectScrollListItemsInWorld();
+ updateStateOnActionControls();
+}
+
+void LLFloaterPathfindingObjects::updateControlsOnInWorldSelectionChange()
+{
+ updateStateOnActionControls();
+}
+
+S32 LLFloaterPathfindingObjects::getNameColumnIndex() const
+{
+ return 0;
+}
+
+S32 LLFloaterPathfindingObjects::getOwnerNameColumnIndex() const
+{
+ return 2;
+}
+
+std::string LLFloaterPathfindingObjects::getOwnerName(const LLPathfindingObject *pObject) const
+{
+ llassert(0);
+ std::string returnVal;
+ return returnVal;
+}
+
+const LLColor4 &LLFloaterPathfindingObjects::getBeaconColor() const
+{
+ return mDefaultBeaconColor;
+}
+
+const LLColor4 &LLFloaterPathfindingObjects::getBeaconTextColor() const
+{
+ return mDefaultBeaconTextColor;
+}
+
+S32 LLFloaterPathfindingObjects::getBeaconWidth() const
+{
+ return DEFAULT_BEACON_WIDTH;
+}
+
+void LLFloaterPathfindingObjects::showFloaterWithSelectionObjects()
+{
+ mObjectsToBeSelected.clear();
+
+ LLObjectSelectionHandle selectedObjectsHandle = LLSelectMgr::getInstance()->getSelection();
+ if (selectedObjectsHandle.notNull())
+ {
+ LLObjectSelection *selectedObjects = selectedObjectsHandle.get();
+ if (!selectedObjects->isEmpty())
+ {
+ for (LLObjectSelection::valid_iterator objectIter = selectedObjects->valid_begin();
+ objectIter != selectedObjects->valid_end(); ++objectIter)
+ {
+ LLSelectNode *object = *objectIter;
+ LLViewerObject *viewerObject = object->getObject();
+ mObjectsToBeSelected.push_back(viewerObject->getID());
+ }
+ }
+ }
+ mHasObjectsToBeSelected = true;
+
+ if (!isShown())
+ {
+ openFloater();
+ setVisibleAndFrontmost();
+ }
+ else
+ {
+ rebuildObjectsScrollList();
+ if (isMinimized())
+ {
+ setMinimized(FALSE);
+ }
+ setVisibleAndFrontmost();
+ }
+ setFocus(TRUE);
+}
+
+BOOL LLFloaterPathfindingObjects::isShowBeacons() const
+{
+ return mShowBeaconCheckBox->get();
+}
+
+void LLFloaterPathfindingObjects::clearAllObjects()
+{
+ selectNoneObjects();
+ mObjectsScrollList->deleteAllItems();
+ mMissingNameObjectsScrollListItems.clear();
+ mObjectList.reset();
+}
+
+void LLFloaterPathfindingObjects::selectAllObjects()
+{
+ mObjectsScrollList->selectAll();
+}
+
+void LLFloaterPathfindingObjects::selectNoneObjects()
+{
+ mObjectsScrollList->deselectAllItems();
+}
+
+void LLFloaterPathfindingObjects::teleportToSelectedObject()
+{
+ std::vector<LLScrollListItem*> selectedItems = mObjectsScrollList->getAllSelected();
+ llassert(selectedItems.size() == 1);
+ if (selectedItems.size() == 1)
+ {
+ std::vector<LLScrollListItem*>::const_reference selectedItemRef = selectedItems.front();
+ const LLScrollListItem *selectedItem = selectedItemRef;
+ llassert(mObjectList != NULL);
+ LLVector3d teleportLocation;
+ LLViewerObject *viewerObject = gObjectList.findObject(selectedItem->getUUID());
+ if (viewerObject == NULL)
+ {
+ // If we cannot find the object in the viewer list, teleport to the last reported position
+ const LLPathfindingObjectPtr objectPtr = mObjectList->find(selectedItem->getUUID().asString());
+ teleportLocation = gAgent.getPosGlobalFromAgent(objectPtr->getLocation());
+ }
+ else
+ {
+ // If we can find the object in the viewer list, teleport to the known current position
+ teleportLocation = viewerObject->getPositionGlobal();
+ }
+ gAgent.teleportViaLocationLookAt(teleportLocation);
+ }
+}
+
+LLPathfindingObjectListPtr LLFloaterPathfindingObjects::getEmptyObjectList() const
+{
+ llassert(0);
+ LLPathfindingObjectListPtr objectListPtr(new LLPathfindingObjectList());
+ return objectListPtr;
+}
+
+int LLFloaterPathfindingObjects::getNumSelectedObjects() const
+{
+ return mObjectsScrollList->getNumSelected();
+}
+
+LLPathfindingObjectListPtr LLFloaterPathfindingObjects::getSelectedObjects() const
+{
+ LLPathfindingObjectListPtr selectedObjects = getEmptyObjectList();
+
+ std::vector<LLScrollListItem*> selectedItems = mObjectsScrollList->getAllSelected();
+ if (!selectedItems.empty())
+ {
+ for (std::vector<LLScrollListItem*>::const_iterator itemIter = selectedItems.begin();
+ itemIter != selectedItems.end(); ++itemIter)
+ {
+ LLPathfindingObjectPtr objectPtr = findObject(*itemIter);
+ if (objectPtr != NULL)
+ {
+ selectedObjects->update(objectPtr);
+ }
+ }
+ }
+
+ return selectedObjects;
+}
+
+LLPathfindingObjectPtr LLFloaterPathfindingObjects::getFirstSelectedObject() const
+{
+ LLPathfindingObjectPtr objectPtr;
+
+ std::vector<LLScrollListItem*> selectedItems = mObjectsScrollList->getAllSelected();
+ if (!selectedItems.empty())
+ {
+ objectPtr = findObject(selectedItems.front());
+ }
+
+ return objectPtr;
+}
+
+LLFloaterPathfindingObjects::EMessagingState LLFloaterPathfindingObjects::getMessagingState() const
+{
+ return mMessagingState;
+}
+
+void LLFloaterPathfindingObjects::setMessagingState(EMessagingState pMessagingState)
+{
+ mMessagingState = pMessagingState;
+ updateControlsOnScrollListChange();
+}
+
+void LLFloaterPathfindingObjects::onRefreshObjectsClicked()
+{
+ requestGetObjects();
+}
+
+void LLFloaterPathfindingObjects::onSelectAllObjectsClicked()
+{
+ selectAllObjects();
+}
+
+void LLFloaterPathfindingObjects::onSelectNoneObjectsClicked()
+{
+ selectNoneObjects();
+}
+
+void LLFloaterPathfindingObjects::onTakeClicked()
+{
+ handle_take();
+ requestGetObjects();
+}
+
+void LLFloaterPathfindingObjects::onTakeCopyClicked()
+{
+ handle_take_copy();
+}
+
+void LLFloaterPathfindingObjects::onReturnClicked()
+{
+ LLNotification::Params params("PathfindingReturnMultipleItems");
+ params.functor.function(boost::bind(&LLFloaterPathfindingObjects::handleReturnItemsResponse, this, _1, _2));
+
+ LLSD substitutions;
+ int numItems = getNumSelectedObjects();
+ substitutions["NUM_ITEMS"] = static_cast<LLSD::Integer>(numItems);
+ params.substitutions = substitutions;
+
+ if (numItems == 1)
+ {
+ LLNotifications::getInstance()->forceResponse(params, 0);
+ }
+ else if (numItems > 1)
+ {
+ LLNotifications::getInstance()->add(params);
+ }
+}
+
+void LLFloaterPathfindingObjects::onDeleteClicked()
+{
+ LLNotification::Params params("PathfindingDeleteMultipleItems");
+ params.functor.function(boost::bind(&LLFloaterPathfindingObjects::handleDeleteItemsResponse, this, _1, _2));
+
+ LLSD substitutions;
+ int numItems = getNumSelectedObjects();
+ substitutions["NUM_ITEMS"] = static_cast<LLSD::Integer>(numItems);
+ params.substitutions = substitutions;
+
+ if (numItems == 1)
+ {
+ LLNotifications::getInstance()->forceResponse(params, 0);
+ }
+ else if (numItems > 1)
+ {
+ LLNotifications::getInstance()->add(params);
+ }
+}
+
+void LLFloaterPathfindingObjects::onTeleportClicked()
+{
+ teleportToSelectedObject();
+}
+
+void LLFloaterPathfindingObjects::onScrollListSelectionChanged()
+{
+ updateControlsOnScrollListChange();
+}
+
+void LLFloaterPathfindingObjects::onInWorldSelectionListChanged()
+{
+ updateControlsOnInWorldSelectionChange();
+}
+
+void LLFloaterPathfindingObjects::onRegionBoundaryCrossed()
+{
+ requestGetObjects();
+}
+
+void LLFloaterPathfindingObjects::onGodLevelChange(U8 pGodLevel)
+{
+ requestGetObjects();
+}
+
+void LLFloaterPathfindingObjects::handleObjectNameResponse(const LLPathfindingObject *pObject)
+{
+ llassert(pObject != NULL);
+ const std::string uuid = pObject->getUUID().asString();
+ scroll_list_item_map::iterator scrollListItemIter = mMissingNameObjectsScrollListItems.find(uuid);
+ if (scrollListItemIter != mMissingNameObjectsScrollListItems.end())
+ {
+ LLScrollListItem *scrollListItem = scrollListItemIter->second;
+ llassert(scrollListItem != NULL);
+
+ LLScrollListCell *scrollListCell = scrollListItem->getColumn(getOwnerNameColumnIndex());
+ LLSD ownerName = getOwnerName(pObject);
+
+ scrollListCell->setValue(ownerName);
+
+ mMissingNameObjectsScrollListItems.erase(scrollListItemIter);
+ }
+}
+
+void LLFloaterPathfindingObjects::updateMessagingStatus()
+{
+ std::string statusText("");
+ LLStyle::Params styleParams;
+
+ switch (getMessagingState())
+ {
+ case kMessagingUnknown:
+ statusText = getString("messaging_initial");
+ styleParams.color = mErrorTextColor;
+ break;
+ case kMessagingGetRequestSent :
+ statusText = getString("messaging_get_inprogress");
+ styleParams.color = mWarningTextColor;
+ break;
+ case kMessagingGetError :
+ statusText = getString("messaging_get_error");
+ styleParams.color = mErrorTextColor;
+ break;
+ case kMessagingSetRequestSent :
+ statusText = getString("messaging_set_inprogress");
+ styleParams.color = mWarningTextColor;
+ break;
+ case kMessagingSetError :
+ statusText = getString("messaging_set_error");
+ styleParams.color = mErrorTextColor;
+ break;
+ case kMessagingComplete :
+ if (mObjectsScrollList->isEmpty())
+ {
+ statusText = getString("messaging_complete_none_found");
+ }
+ else
+ {
+ S32 numItems = mObjectsScrollList->getItemCount();
+ S32 numSelectedItems = mObjectsScrollList->getNumSelected();
+
+ LLLocale locale(LLStringUtil::getLocale());
+ std::string numItemsString;
+ LLResMgr::getInstance()->getIntegerString(numItemsString, numItems);
+
+ std::string numSelectedItemsString;
+ LLResMgr::getInstance()->getIntegerString(numSelectedItemsString, numSelectedItems);
+
+ LLStringUtil::format_map_t string_args;
+ string_args["[NUM_SELECTED]"] = numSelectedItemsString;
+ string_args["[NUM_TOTAL]"] = numItemsString;
+ statusText = getString("messaging_complete_available", string_args);
+ }
+ break;
+ case kMessagingNotEnabled :
+ statusText = getString("messaging_not_enabled");
+ styleParams.color = mErrorTextColor;
+ break;
+ default:
+ statusText = getString("messaging_initial");
+ styleParams.color = mErrorTextColor;
+ llassert(0);
+ break;
+ }
+
+ mMessagingStatus->setText((LLStringExplicit)statusText, styleParams);
+}
+
+void LLFloaterPathfindingObjects::updateStateOnListControls()
+{
+ switch (getMessagingState())
+ {
+ case kMessagingUnknown:
+ case kMessagingGetRequestSent :
+ case kMessagingSetRequestSent :
+ mRefreshListButton->setEnabled(FALSE);
+ mSelectAllButton->setEnabled(FALSE);
+ mSelectNoneButton->setEnabled(FALSE);
+ break;
+ case kMessagingGetError :
+ case kMessagingSetError :
+ case kMessagingNotEnabled :
+ mRefreshListButton->setEnabled(TRUE);
+ mSelectAllButton->setEnabled(FALSE);
+ mSelectNoneButton->setEnabled(FALSE);
+ break;
+ case kMessagingComplete :
+ {
+ int numItems = mObjectsScrollList->getItemCount();
+ int numSelectedItems = mObjectsScrollList->getNumSelected();
+ mRefreshListButton->setEnabled(TRUE);
+ mSelectAllButton->setEnabled(numSelectedItems < numItems);
+ mSelectNoneButton->setEnabled(numSelectedItems > 0);
+ }
+ break;
+ default:
+ llassert(0);
+ break;
+ }
+}
+
+void LLFloaterPathfindingObjects::updateStateOnActionControls()
+{
+ int numSelectedItems = mObjectsScrollList->getNumSelected();
+ bool isEditEnabled = (numSelectedItems > 0);
+
+ mShowBeaconCheckBox->setEnabled(isEditEnabled);
+ mTakeButton->setEnabled(isEditEnabled && visible_take_object());
+ mTakeCopyButton->setEnabled(isEditEnabled && enable_object_take_copy());
+ mReturnButton->setEnabled(isEditEnabled && enable_object_return());
+ mDeleteButton->setEnabled(isEditEnabled && enable_object_delete());
+ mTeleportButton->setEnabled(numSelectedItems == 1);
+}
+
+void LLFloaterPathfindingObjects::selectScrollListItemsInWorld()
+{
+ mObjectsSelection.clear();
+ LLSelectMgr::getInstance()->deselectAll();
+
+ std::vector<LLScrollListItem *> selectedItems = mObjectsScrollList->getAllSelected();
+ if (!selectedItems.empty())
+ {
+ int numSelectedItems = selectedItems.size();
+
+ std::vector<LLViewerObject *>viewerObjects;
+ viewerObjects.reserve(numSelectedItems);
+
+ for (std::vector<LLScrollListItem *>::const_iterator selectedItemIter = selectedItems.begin();
+ selectedItemIter != selectedItems.end(); ++selectedItemIter)
+ {
+ const LLScrollListItem *selectedItem = *selectedItemIter;
+
+ LLViewerObject *viewerObject = gObjectList.findObject(selectedItem->getUUID());
+ if (viewerObject != NULL)
+ {
+ viewerObjects.push_back(viewerObject);
+ }
+ }
+
+ if (!viewerObjects.empty())
+ {
+ mObjectsSelection = LLSelectMgr::getInstance()->selectObjectAndFamily(viewerObjects);
+ }
+ }
+}
+
+void LLFloaterPathfindingObjects::handleReturnItemsResponse(const LLSD &pNotification, const LLSD &pResponse)
+{
+ if (LLNotificationsUtil::getSelectedOption(pNotification, pResponse) == 0)
+ {
+ handle_object_return();
+ requestGetObjects();
+ }
+}
+
+void LLFloaterPathfindingObjects::handleDeleteItemsResponse(const LLSD &pNotification, const LLSD &pResponse)
+{
+ if (LLNotificationsUtil::getSelectedOption(pNotification, pResponse) == 0)
+ {
+ handle_object_delete();
+ requestGetObjects();
+ }
+}
+
+LLPathfindingObjectPtr LLFloaterPathfindingObjects::findObject(const LLScrollListItem *pListItem) const
+{
+ LLPathfindingObjectPtr objectPtr;
+
+ LLUUID uuid = pListItem->getUUID();
+ const std::string &uuidString = uuid.asString();
+ llassert(mObjectList != NULL);
+ objectPtr = mObjectList->find(uuidString);
+
+ return objectPtr;
+}
diff --git a/indra/newview/llfloaterpathfindingobjects.h b/indra/newview/llfloaterpathfindingobjects.h
new file mode 100755
index 0000000000..4024e15fd6
--- /dev/null
+++ b/indra/newview/llfloaterpathfindingobjects.h
@@ -0,0 +1,179 @@
+/**
+* @file llfloaterpathfindingobjects.h
+* @brief Base class for both the pathfinding linksets and characters floater.
+* @author Stinson@lindenlab.com
+*
+* $LicenseInfo:firstyear=2012&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2012, 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_LLFLOATERPATHFINDINGOBJECTS_H
+#define LL_LLFLOATERPATHFINDINGOBJECTS_H
+
+#include <string>
+#include <map>
+
+#include <boost/signals2.hpp>
+
+#include "llagent.h"
+#include "llfloater.h"
+#include "llpathfindingmanager.h"
+#include "llpathfindingobject.h"
+#include "llpathfindingobjectlist.h"
+#include "llselectmgr.h"
+#include "lluuid.h"
+#include "v4color.h"
+
+class LLAvatarName;
+class LLButton;
+class LLCheckBoxCtrl;
+class LLScrollListCtrl;
+class LLScrollListItem;
+class LLSD;
+class LLTextBase;
+
+class LLFloaterPathfindingObjects : public LLFloater
+{
+public:
+ virtual void onOpen(const LLSD &pKey);
+ virtual void onClose(bool pIsAppQuitting);
+ virtual void draw();
+
+protected:
+ friend class LLFloaterReg;
+
+ typedef enum
+ {
+ kMessagingUnknown,
+ kMessagingGetRequestSent,
+ kMessagingGetError,
+ kMessagingSetRequestSent,
+ kMessagingSetError,
+ kMessagingComplete,
+ kMessagingNotEnabled
+ } EMessagingState;
+
+ LLFloaterPathfindingObjects(const LLSD &pSeed);
+ virtual ~LLFloaterPathfindingObjects();
+
+ virtual BOOL postBuild();
+
+ virtual void requestGetObjects();
+ LLPathfindingManager::request_id_t getNewRequestId();
+ void handleNewObjectList(LLPathfindingManager::request_id_t pRequestId, LLPathfindingManager::ERequestStatus pRequestStatus, LLPathfindingObjectListPtr pObjectList);
+ void handleUpdateObjectList(LLPathfindingManager::request_id_t pRequestId, LLPathfindingManager::ERequestStatus pRequestStatus, LLPathfindingObjectListPtr pObjectList);
+
+ void rebuildObjectsScrollList();
+ virtual void buildObjectsScrollList(const LLPathfindingObjectListPtr pObjectListPtr);
+ void addObjectToScrollList(const LLPathfindingObjectPtr pObjectPr, const LLSD &pScrollListItemData);
+
+ virtual void updateControlsOnScrollListChange();
+ virtual void updateControlsOnInWorldSelectionChange();
+
+ virtual S32 getNameColumnIndex() const;
+ virtual S32 getOwnerNameColumnIndex() const;
+ virtual std::string getOwnerName(const LLPathfindingObject *pObject) const;
+ virtual const LLColor4 &getBeaconColor() const;
+ virtual const LLColor4 &getBeaconTextColor() const;
+ virtual S32 getBeaconWidth() const;
+
+ void showFloaterWithSelectionObjects();
+
+ BOOL isShowBeacons() const;
+ void clearAllObjects();
+ void selectAllObjects();
+ void selectNoneObjects();
+ void teleportToSelectedObject();
+
+ virtual LLPathfindingObjectListPtr getEmptyObjectList() const;
+ int getNumSelectedObjects() const;
+ LLPathfindingObjectListPtr getSelectedObjects() const;
+ LLPathfindingObjectPtr getFirstSelectedObject() const;
+
+ EMessagingState getMessagingState() const;
+
+private:
+ LLFloaterPathfindingObjects(const LLFloaterPathfindingObjects &pOther);
+
+ void setMessagingState(EMessagingState pMessagingState);
+
+ void onRefreshObjectsClicked();
+ void onSelectAllObjectsClicked();
+ void onSelectNoneObjectsClicked();
+ void onTakeClicked();
+ void onTakeCopyClicked();
+ void onReturnClicked();
+ void onDeleteClicked();
+ void onTeleportClicked();
+
+ void onScrollListSelectionChanged();
+ void onInWorldSelectionListChanged();
+ void onRegionBoundaryCrossed();
+ void onGodLevelChange(U8 pGodLevel);
+
+ void handleObjectNameResponse(const LLPathfindingObject *pObject);
+
+ void updateMessagingStatus();
+ void updateStateOnListControls();
+ void updateStateOnActionControls();
+ void selectScrollListItemsInWorld();
+
+ void handleReturnItemsResponse(const LLSD &pNotification, const LLSD &pResponse);
+ void handleDeleteItemsResponse(const LLSD &pNotification, const LLSD &pResponse);
+
+ LLPathfindingObjectPtr findObject(const LLScrollListItem *pListItem) const;
+
+ LLScrollListCtrl *mObjectsScrollList;
+ LLTextBase *mMessagingStatus;
+ LLButton *mRefreshListButton;
+ LLButton *mSelectAllButton;
+ LLButton *mSelectNoneButton;
+ LLCheckBoxCtrl *mShowBeaconCheckBox;
+
+ LLButton *mTakeButton;
+ LLButton *mTakeCopyButton;
+ LLButton *mReturnButton;
+ LLButton *mDeleteButton;
+ LLButton *mTeleportButton;
+
+ LLColor4 mDefaultBeaconColor;
+ LLColor4 mDefaultBeaconTextColor;
+ LLColor4 mErrorTextColor;
+ LLColor4 mWarningTextColor;
+
+ EMessagingState mMessagingState;
+ LLPathfindingManager::request_id_t mMessagingRequestId;
+
+ typedef std::map<std::string, LLScrollListItem *> scroll_list_item_map;
+ scroll_list_item_map mMissingNameObjectsScrollListItems;
+
+ LLPathfindingObjectListPtr mObjectList;
+
+ LLObjectSelectionHandle mObjectsSelection;
+
+ bool mHasObjectsToBeSelected;
+ uuid_vec_t mObjectsToBeSelected;
+
+ boost::signals2::connection mSelectionUpdateSlot;
+ boost::signals2::connection mRegionBoundaryCrossingSlot;
+ LLAgent::god_level_change_slot_t mGodLevelChangeSlot;
+};
+
+#endif // LL_LLFLOATERPATHFINDINGOBJECTS_H
diff --git a/indra/newview/llfloaterpay.cpp b/indra/newview/llfloaterpay.cpp
index b0009fd94f..b0009fd94f 100644..100755
--- a/indra/newview/llfloaterpay.cpp
+++ b/indra/newview/llfloaterpay.cpp
diff --git a/indra/newview/llfloaterpay.h b/indra/newview/llfloaterpay.h
index f322e5ef04..f322e5ef04 100644..100755
--- a/indra/newview/llfloaterpay.h
+++ b/indra/newview/llfloaterpay.h
diff --git a/indra/newview/llfloaterperms.cpp b/indra/newview/llfloaterperms.cpp
index dc4969f5e6..dc4969f5e6 100644..100755
--- a/indra/newview/llfloaterperms.cpp
+++ b/indra/newview/llfloaterperms.cpp
diff --git a/indra/newview/llfloaterperms.h b/indra/newview/llfloaterperms.h
index b4b5d58aa5..b4b5d58aa5 100644..100755
--- a/indra/newview/llfloaterperms.h
+++ b/indra/newview/llfloaterperms.h
diff --git a/indra/newview/llfloaterpostprocess.cpp b/indra/newview/llfloaterpostprocess.cpp
index 2d61109e17..2d61109e17 100644..100755
--- a/indra/newview/llfloaterpostprocess.cpp
+++ b/indra/newview/llfloaterpostprocess.cpp
diff --git a/indra/newview/llfloaterpostprocess.h b/indra/newview/llfloaterpostprocess.h
index 424a5fc8f0..424a5fc8f0 100644..100755
--- a/indra/newview/llfloaterpostprocess.h
+++ b/indra/newview/llfloaterpostprocess.h
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 596c73870d..b5976cbc99 100755
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -35,7 +35,7 @@
#include "llfloaterpreference.h"
#include "message.h"
-
+#include "llfloaterautoreplacesettings.h"
#include "llagent.h"
#include "llavatarconstants.h"
#include "llcheckboxctrl.h"
@@ -51,11 +51,11 @@
#include "llfloaterabout.h"
#include "llfloaterhardwaresettings.h"
#include "llfloatersidepanelcontainer.h"
-#include "llimfloater.h"
+#include "llfloaterimsession.h"
#include "llkeyboard.h"
#include "llmodaldialog.h"
#include "llnavigationbar.h"
-#include "llnearbychat.h"
+#include "llfloaterimnearbychat.h"
#include "llnotifications.h"
#include "llnotificationsutil.h"
#include "llnotificationtemplate.h"
@@ -77,7 +77,7 @@
#include "llviewerthrottle.h"
#include "llvotree.h"
#include "llvosky.h"
-
+#include "llfloaterpathfindingconsole.h"
// linden library includes
#include "llavatarnamecache.h"
#include "llerror.h"
@@ -306,7 +306,8 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)
mAvatarDataInitialized(false),
mClickActionDirty(false)
{
-
+ LLConversationLog::instance().addObserver(this);
+
//Build Floater is now Called from LLFloaterReg::add("preferences", "floater_preferences.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPreference>);
static bool registered_dialog = false;
@@ -329,8 +330,6 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)
mCommitCallbackRegistrar.add("Pref.VoiceSetKey", boost::bind(&LLFloaterPreference::onClickSetKey, this));
mCommitCallbackRegistrar.add("Pref.VoiceSetMiddleMouse", boost::bind(&LLFloaterPreference::onClickSetMiddleMouse, this));
mCommitCallbackRegistrar.add("Pref.SetSounds", boost::bind(&LLFloaterPreference::onClickSetSounds, this));
-// mCommitCallbackRegistrar.add("Pref.ClickSkipDialogs", boost::bind(&LLFloaterPreference::onClickSkipDialogs, this));
-// mCommitCallbackRegistrar.add("Pref.ClickResetDialogs", boost::bind(&LLFloaterPreference::onClickResetDialogs, this));
mCommitCallbackRegistrar.add("Pref.ClickEnablePopup", boost::bind(&LLFloaterPreference::onClickEnablePopup, this));
mCommitCallbackRegistrar.add("Pref.ClickDisablePopup", boost::bind(&LLFloaterPreference::onClickDisablePopup, this));
mCommitCallbackRegistrar.add("Pref.LogPath", boost::bind(&LLFloaterPreference::onClickLogPath, this));
@@ -338,7 +337,7 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)
mCommitCallbackRegistrar.add("Pref.HardwareDefaults", boost::bind(&LLFloaterPreference::setHardwareDefaults, this));
mCommitCallbackRegistrar.add("Pref.VertexShaderEnable", boost::bind(&LLFloaterPreference::onVertexShaderEnable, this));
mCommitCallbackRegistrar.add("Pref.WindowedMod", boost::bind(&LLFloaterPreference::onCommitWindowedMode, this));
- mCommitCallbackRegistrar.add("Pref.UpdateSliderText", boost::bind(&LLFloaterPreference::onUpdateSliderText,this, _1,_2));
+ mCommitCallbackRegistrar.add("Pref.UpdateSliderText", boost::bind(&LLFloaterPreference::refreshUI,this));
mCommitCallbackRegistrar.add("Pref.QualityPerformance", boost::bind(&LLFloaterPreference::onChangeQuality, this, _2));
mCommitCallbackRegistrar.add("Pref.applyUIColor", boost::bind(&LLFloaterPreference::applyUIColor, this ,_1, _2));
mCommitCallbackRegistrar.add("Pref.getUIColor", boost::bind(&LLFloaterPreference::getUIColor, this ,_1, _2));
@@ -346,17 +345,22 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)
mCommitCallbackRegistrar.add("Pref.BlockList", boost::bind(&LLFloaterPreference::onClickBlockList, this));
mCommitCallbackRegistrar.add("Pref.Proxy", boost::bind(&LLFloaterPreference::onClickProxySettings, this));
mCommitCallbackRegistrar.add("Pref.TranslationSettings", boost::bind(&LLFloaterPreference::onClickTranslationSettings, this));
- mCommitCallbackRegistrar.add("Pref.PermsDefault", boost::bind(&LLFloaterPreference::onClickPermsDefault, this));
+ mCommitCallbackRegistrar.add("Pref.AutoReplace", boost::bind(&LLFloaterPreference::onClickAutoReplace, this));
+ mCommitCallbackRegistrar.add("Pref.PermsDefault", boost::bind(&LLFloaterPreference::onClickPermsDefault, this));
+ mCommitCallbackRegistrar.add("Pref.SpellChecker", boost::bind(&LLFloaterPreference::onClickSpellChecker, this));
sSkin = gSavedSettings.getString("SkinCurrent");
- mCommitCallbackRegistrar.add("Pref.ClickActionChange", boost::bind(&LLFloaterPreference::onClickActionChange, this));
+ mCommitCallbackRegistrar.add("Pref.ClickActionChange", boost::bind(&LLFloaterPreference::onClickActionChange, this));
gSavedSettings.getControl("NameTagShowUsernames")->getCommitSignal()->connect(boost::bind(&handleNameTagOptionChanged, _2));
gSavedSettings.getControl("NameTagShowFriends")->getCommitSignal()->connect(boost::bind(&handleNameTagOptionChanged, _2));
gSavedSettings.getControl("UseDisplayNames")->getCommitSignal()->connect(boost::bind(&handleDisplayNamesOptionChanged, _2));
-
+
LLAvatarPropertiesProcessor::getInstance()->addObserver( gAgent.getID(), this );
+
+ mCommitCallbackRegistrar.add("Pref.ClearLog", boost::bind(&LLConversationLog::onClearLog, &LLConversationLog::instance()));
+ mCommitCallbackRegistrar.add("Pref.DeleteTranscripts", boost::bind(&LLFloaterPreference::onDeleteTranscripts, this));
}
void LLFloaterPreference::processProperties( void* pData, EAvatarProcessorType type )
@@ -424,18 +428,14 @@ void LLFloaterPreference::saveAvatarProperties( void )
BOOL LLFloaterPreference::postBuild()
{
- gSavedSettings.getControl("PlainTextChatHistory")->getSignal()->connect(boost::bind(&LLIMFloater::processChatHistoryStyleUpdate, _2));
-
- gSavedSettings.getControl("PlainTextChatHistory")->getSignal()->connect(boost::bind(&LLNearbyChat::processChatHistoryStyleUpdate, _2));
-
- gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&LLIMFloater::processChatHistoryStyleUpdate, _2));
-
- gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&LLNearbyChat::processChatHistoryStyleUpdate, _2));
+ gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&LLFloaterIMSessionTab::processChatHistoryStyleUpdate, false));
gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&LLViewerChat::signalChatFontChanged));
gSavedSettings.getControl("ChatBubbleOpacity")->getSignal()->connect(boost::bind(&LLFloaterPreference::onNameTagOpacityChange, this, _2));
+ gSavedSettings.getControl("PreferredMaturity")->getSignal()->connect(boost::bind(&LLFloaterPreference::onChangeMaturity, this));
+
LLTabContainer* tabcontainer = getChild<LLTabContainer>("pref core");
if (!tabcontainer->selectTab(gSavedSettings.getS32("LastPrefTab")))
tabcontainer->selectFirstTab();
@@ -444,28 +444,46 @@ BOOL LLFloaterPreference::postBuild()
std::string cache_location = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "");
setCacheLocation(cache_location);
+ getChild<LLUICtrl>("log_path_string")->setEnabled(FALSE); // make it read-only but selectable
+
getChild<LLComboBox>("language_combobox")->setCommitCallback(boost::bind(&LLFloaterPreference::onLanguageChange, this));
- // if floater is opened before login set default localized busy message
+ getChild<LLComboBox>("FriendIMOptions")->setCommitCallback(boost::bind(&LLFloaterPreference::onNotificationsChange, this,"FriendIMOptions"));
+ getChild<LLComboBox>("NonFriendIMOptions")->setCommitCallback(boost::bind(&LLFloaterPreference::onNotificationsChange, this,"NonFriendIMOptions"));
+ getChild<LLComboBox>("ConferenceIMOptions")->setCommitCallback(boost::bind(&LLFloaterPreference::onNotificationsChange, this,"ConferenceIMOptions"));
+ getChild<LLComboBox>("GroupChatOptions")->setCommitCallback(boost::bind(&LLFloaterPreference::onNotificationsChange, this,"GroupChatOptions"));
+ getChild<LLComboBox>("NearbyChatOptions")->setCommitCallback(boost::bind(&LLFloaterPreference::onNotificationsChange, this,"NearbyChatOptions"));
+ getChild<LLComboBox>("ObjectIMOptions")->setCommitCallback(boost::bind(&LLFloaterPreference::onNotificationsChange, this,"ObjectIMOptions"));
+
+ // if floater is opened before login set default localized do not disturb message
if (LLStartUp::getStartupState() < STATE_STARTED)
{
- gSavedPerAccountSettings.setString("BusyModeResponse", LLTrans::getString("BusyModeResponseDefault"));
+ gSavedPerAccountSettings.setString("DoNotDisturbModeResponse", LLTrans::getString("DoNotDisturbModeResponseDefault"));
}
+ // set 'enable' property for 'Clear log...' button
+ changed();
+
+ LLLogChat::setSaveHistorySignal(boost::bind(&LLFloaterPreference::onLogChatHistorySaved, this));
+
return TRUE;
}
-void LLFloaterPreference::onBusyResponseChanged()
+void LLFloaterPreference::updateDeleteTranscriptsButton()
{
- // set "BusyResponseChanged" TRUE if user edited message differs from default, FALSE otherwise
- if (LLTrans::getString("BusyModeResponseDefault") != getChild<LLUICtrl>("busy_response")->getValue().asString())
- {
- gSavedPerAccountSettings.setBOOL("BusyResponseChanged", TRUE );
- }
- else
- {
- gSavedPerAccountSettings.setBOOL("BusyResponseChanged", FALSE );
- }
+ std::vector<std::string> list_of_transcriptions_file_names;
+ LLLogChat::getListOfTranscriptFiles(list_of_transcriptions_file_names);
+ getChild<LLButton>("delete_transcripts")->setEnabled(list_of_transcriptions_file_names.size() > 0);
+}
+
+void LLFloaterPreference::onDoNotDisturbResponseChanged()
+{
+ // set "DoNotDisturbResponseChanged" TRUE if user edited message differs from default, FALSE otherwise
+ bool response_changed_flag =
+ LLTrans::getString("DoNotDisturbModeResponseDefault")
+ != getChild<LLUICtrl>("do_not_disturb_response")->getValue().asString();
+
+ gSavedPerAccountSettings.setBOOL("DoNotDisturbResponseChanged", response_changed_flag );
}
LLFloaterPreference::~LLFloaterPreference()
@@ -476,6 +494,8 @@ LLFloaterPreference::~LLFloaterPreference()
{
ctrl_window_size->setCurrentByIndex(i);
}
+
+ LLConversationLog::instance().removeObserver(this);
}
void LLFloaterPreference::draw()
@@ -540,7 +560,7 @@ void LLFloaterPreference::apply()
LLViewerMedia::setCookiesEnabled(getChild<LLUICtrl>("cookies_enabled")->getValue());
- if (hasChild("web_proxy_enabled") &&hasChild("web_proxy_editor") && hasChild("web_proxy_port"))
+ if (hasChild("web_proxy_enabled", TRUE) &&hasChild("web_proxy_editor", TRUE) && hasChild("web_proxy_port", TRUE))
{
bool proxy_enable = getChild<LLUICtrl>("web_proxy_enabled")->getValue();
std::string proxy_address = getChild<LLUICtrl>("web_proxy_editor")->getValue();
@@ -548,14 +568,8 @@ void LLFloaterPreference::apply()
LLViewerMedia::setProxyConfig(proxy_enable, proxy_address, proxy_port);
}
-// LLWString busy_response = utf8str_to_wstring(getChild<LLUICtrl>("busy_response")->getValue().asString());
-// LLWStringUtil::replaceTabsWithSpaces(busy_response, 4);
-
- gSavedSettings.setBOOL("PlainTextChatHistory", getChild<LLUICtrl>("plain_text_chat_history")->getValue().asBoolean());
-
if (mGotPersonalInfo)
{
-// gSavedSettings.setString("BusyModeResponse2", std::string(wstring_to_utf8str(busy_response)));
bool new_im_via_email = getChild<LLUICtrl>("send_im_to_email")->getValue().asBoolean();
bool new_hide_online = getChild<LLUICtrl>("online_visibility")->getValue().asBoolean();
@@ -605,6 +619,12 @@ void LLFloaterPreference::cancel()
// hide translation settings floater
LLFloaterReg::hideInstance("prefs_translation");
+ // hide autoreplace settings floater
+ LLFloaterReg::hideInstance("prefs_autoreplace");
+
+ // hide spellchecker settings folder
+ LLFloaterReg::hideInstance("prefs_spellchecker");
+
// cancel hardware menu
LLFloaterHardwareSettings* hardware_settings = LLFloaterReg::getTypedInstance<LLFloaterHardwareSettings>("prefs_hardware_settings");
if (hardware_settings)
@@ -626,26 +646,33 @@ void LLFloaterPreference::cancel()
{
advanced_proxy_settings->cancel();
}
+ //Need to reload the navmesh if the pathing console is up
+ LLHandle<LLFloaterPathfindingConsole> pathfindingConsoleHandle = LLFloaterPathfindingConsole::getInstanceHandle();
+ if ( !pathfindingConsoleHandle.isDead() )
+ {
+ LLFloaterPathfindingConsole* pPathfindingConsole = pathfindingConsoleHandle.get();
+ pPathfindingConsole->onRegionBoundaryCross();
+ }
}
void LLFloaterPreference::onOpen(const LLSD& key)
{
- // this variable and if that follows it are used to properly handle busy mode response message
+ // this variable and if that follows it are used to properly handle do not disturb mode response message
static bool initialized = FALSE;
- // if user is logged in and we haven't initialized busy_response yet, do it
+ // if user is logged in and we haven't initialized do not disturb mode response yet, do it
if (!initialized && LLStartUp::getStartupState() == STATE_STARTED)
{
- // Special approach is used for busy response localization, because "BusyModeResponse" is
+ // Special approach is used for do not disturb response localization, because "DoNotDisturbModeResponse" is
// in non-localizable xml, and also because it may be changed by user and in this case it shouldn't be localized.
- // To keep track of whether busy response is default or changed by user additional setting BusyResponseChanged
+ // To keep track of whether do not disturb response is default or changed by user additional setting DoNotDisturbResponseChanged
// was added into per account settings.
// initialization should happen once,so setting variable to TRUE
initialized = TRUE;
- // this connection is needed to properly set "BusyResponseChanged" setting when user makes changes in
- // busy response message.
- gSavedPerAccountSettings.getControl("BusyModeResponse")->getSignal()->connect(boost::bind(&LLFloaterPreference::onBusyResponseChanged, this));
+ // this connection is needed to properly set "DoNotDisturbResponseChanged" setting when user makes changes in
+ // do not disturb response message.
+ gSavedPerAccountSettings.getControl("DoNotDisturbModeResponse")->getSignal()->connect(boost::bind(&LLFloaterPreference::onDoNotDisturbResponseChanged, this));
}
gAgent.sendAgentUserInfoRequest();
@@ -692,6 +719,15 @@ void LLFloaterPreference::onOpen(const LLSD& key)
// while preferences floater was closed.
buildPopupLists();
+
+ //get the options that were checked
+ onNotificationsChange("FriendIMOptions");
+ onNotificationsChange("NonFriendIMOptions");
+ onNotificationsChange("ConferenceIMOptions");
+ onNotificationsChange("GroupChatOptions");
+ onNotificationsChange("NearbyChatOptions");
+ onNotificationsChange("ObjectIMOptions");
+
LLPanelLogin::setAlwaysRefresh(true);
refresh();
@@ -707,12 +743,12 @@ void LLFloaterPreference::onVertexShaderEnable()
}
//static
-void LLFloaterPreference::initBusyResponse()
+void LLFloaterPreference::initDoNotDisturbResponse()
{
- if (!gSavedPerAccountSettings.getBOOL("BusyResponseChanged"))
+ if (!gSavedPerAccountSettings.getBOOL("DoNotDisturbResponseChanged"))
{
- //LLTrans::getString("BusyModeResponseDefault") is used here for localization (EXT-5885)
- gSavedPerAccountSettings.setString("BusyModeResponse", LLTrans::getString("BusyModeResponseDefault"));
+ //LLTrans::getString("DoNotDisturbModeResponseDefault") is used here for localization (EXT-5885)
+ gSavedPerAccountSettings.setString("DoNotDisturbModeResponse", LLTrans::getString("DoNotDisturbModeResponseDefault"));
}
}
@@ -737,7 +773,10 @@ void LLFloaterPreference::onClose(bool app_quitting)
{
gSavedSettings.setS32("LastPrefTab", getChild<LLTabContainer>("pref core")->getCurrentPanelIndex());
LLPanelLogin::setAlwaysRefresh(false);
- cancel();
+ if (!app_quitting)
+ {
+ cancel();
+ }
}
void LLFloaterPreference::onOpenHardwareSettings()
@@ -764,8 +803,31 @@ void LLFloaterPreference::onBtnOK()
apply();
closeFloater(false);
+ //Conversation transcript and log path changed so reload conversations based on new location
+ if(mPriorInstantMessageLogPath.length())
+ {
+ if(moveTranscriptsAndLog())
+ {
+ //When floaters are empty but have a chat history files, reload chat history into them
+ LLFloaterIMSessionTab::reloadEmptyFloaters();
+ }
+ //Couldn't move files so restore the old path and show a notification
+ else
+ {
+ gSavedPerAccountSettings.setString("InstantMessageLogPath", mPriorInstantMessageLogPath);
+ LLNotificationsUtil::add("PreferenceChatPathChanged");
+ }
+ mPriorInstantMessageLogPath.clear();
+ }
+
LLUIColorTable::instance().saveUserSettings();
gSavedSettings.saveToFile(gSavedSettings.getString("ClientSettingsFile"), TRUE);
+
+ //Only save once logged in and loaded per account settings
+ if(mGotPersonalInfo)
+ {
+ gSavedPerAccountSettings.saveToFile(gSavedSettings.getString("PerAccountSettingsFile"), TRUE);
+ }
}
else
{
@@ -773,7 +835,15 @@ void LLFloaterPreference::onBtnOK()
llinfos << "Can't close preferences!" << llendl;
}
- LLPanelLogin::updateLocationCombo( false );
+ LLPanelLogin::updateLocationSelectorsVisibility();
+ //Need to reload the navmesh if the pathing console is up
+ LLHandle<LLFloaterPathfindingConsole> pathfindingConsoleHandle = LLFloaterPathfindingConsole::getInstanceHandle();
+ if ( !pathfindingConsoleHandle.isDead() )
+ {
+ LLFloaterPathfindingConsole* pPathfindingConsole = pathfindingConsoleHandle.get();
+ pPathfindingConsole->onRegionBoundaryCross();
+ }
+
}
// static
@@ -790,7 +860,7 @@ void LLFloaterPreference::onBtnApply( )
apply();
saveSettings();
- LLPanelLogin::updateLocationCombo( false );
+ LLPanelLogin::updateLocationSelectorsVisibility();
}
// static
@@ -810,12 +880,12 @@ void LLFloaterPreference::onBtnCancel()
}
// static
-void LLFloaterPreference::updateUserInfo(const std::string& visibility, bool im_via_email, const std::string& email)
+void LLFloaterPreference::updateUserInfo(const std::string& visibility, bool im_via_email)
{
LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
if (instance)
{
- instance->setPersonalInfo(visibility, im_via_email, email);
+ instance->setPersonalInfo(visibility, im_via_email);
}
}
@@ -857,6 +927,23 @@ void LLFloaterPreference::onLanguageChange()
}
}
+void LLFloaterPreference::onNotificationsChange(const std::string& OptionName)
+{
+ mNotificationOptions[OptionName] = getChild<LLComboBox>(OptionName)->getSelectedItemLabel();
+
+ bool show_notifications_alert = true;
+ for (notifications_map::iterator it_notification = mNotificationOptions.begin(); it_notification != mNotificationOptions.end(); it_notification++)
+ {
+ if(it_notification->second != "No action")
+ {
+ show_notifications_alert = false;
+ break;
+ }
+ }
+
+ getChild<LLTextBox>("notifications_alert")->setVisible(show_notifications_alert);
+}
+
void LLFloaterPreference::onNameTagOpacityChange(const LLSD& newvalue)
{
LLColorSwatchCtrl* color_swatch = findChild<LLColorSwatchCtrl>("background");
@@ -932,7 +1019,6 @@ void LLFloaterPreference::refreshSkin(void* data)
self->getChild<LLRadioGroup>("skin_selection", true)->setValue(sSkin);
}
-
void LLFloaterPreference::buildPopupLists()
{
LLScrollListCtrl& disabled_popups =
@@ -1009,8 +1095,9 @@ void LLFloaterPreference::refreshEnabledState()
ctrl_reflections->setEnabled(reflections);
// Bump & Shiny
+ LLCheckBoxCtrl* bumpshiny_ctrl = getChild<LLCheckBoxCtrl>("BumpShiny");
bool bumpshiny = gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps && LLFeatureManager::getInstance()->isFeatureAvailable("RenderObjectBump");
- getChild<LLCheckBoxCtrl>("BumpShiny")->setEnabled(bumpshiny ? TRUE : FALSE);
+ bumpshiny_ctrl->setEnabled(bumpshiny ? TRUE : FALSE);
radio_reflection_detail->setEnabled(reflections);
@@ -1067,21 +1154,28 @@ void LLFloaterPreference::refreshEnabledState()
//Deferred/SSAO/Shadows
LLCheckBoxCtrl* ctrl_deferred = getChild<LLCheckBoxCtrl>("UseLightShaders");
+ LLCheckBoxCtrl* ctrl_deferred2 = getChild<LLCheckBoxCtrl>("UseLightShaders2");
+
- BOOL enabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&
+ BOOL enabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&
+ ((bumpshiny_ctrl && bumpshiny_ctrl->get()) ? TRUE : FALSE) &&
shaders &&
gGLManager.mHasFramebufferObject &&
gSavedSettings.getBOOL("RenderAvatarVP") &&
(ctrl_wind_light->get()) ? TRUE : FALSE;
ctrl_deferred->setEnabled(enabled);
-
+ ctrl_deferred2->setEnabled(enabled);
+
LLCheckBoxCtrl* ctrl_ssao = getChild<LLCheckBoxCtrl>("UseSSAO");
LLCheckBoxCtrl* ctrl_dof = getChild<LLCheckBoxCtrl>("UseDoF");
LLComboBox* ctrl_shadow = getChild<LLComboBox>("ShadowDetail");
+ // note, okay here to get from ctrl_deferred as it's twin, ctrl_deferred2 will alway match it
enabled = enabled && LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferredSSAO") && (ctrl_deferred->get() ? TRUE : FALSE);
-
+
+ ctrl_deferred->set(gSavedSettings.getBOOL("RenderDeferred"));
+
ctrl_ssao->setEnabled(enabled);
ctrl_dof->setEnabled(enabled);
@@ -1105,6 +1199,7 @@ void LLFloaterPreference::disableUnavailableSettings()
LLCheckBoxCtrl* ctrl_wind_light = getChild<LLCheckBoxCtrl>("WindLightUseAtmosShaders");
LLCheckBoxCtrl* ctrl_avatar_impostors = getChild<LLCheckBoxCtrl>("AvatarImpostors");
LLCheckBoxCtrl* ctrl_deferred = getChild<LLCheckBoxCtrl>("UseLightShaders");
+ LLCheckBoxCtrl* ctrl_deferred2 = getChild<LLCheckBoxCtrl>("UseLightShaders2");
LLComboBox* ctrl_shadows = getChild<LLComboBox>("ShadowDetail");
LLCheckBoxCtrl* ctrl_ssao = getChild<LLCheckBoxCtrl>("UseSSAO");
LLCheckBoxCtrl* ctrl_dof = getChild<LLCheckBoxCtrl>("UseDoF");
@@ -1138,6 +1233,8 @@ void LLFloaterPreference::disableUnavailableSettings()
ctrl_deferred->setEnabled(FALSE);
ctrl_deferred->setValue(FALSE);
+ ctrl_deferred2->setEnabled(FALSE);
+ ctrl_deferred2->setValue(FALSE);
}
// disabled windlight
@@ -1158,6 +1255,8 @@ void LLFloaterPreference::disableUnavailableSettings()
ctrl_deferred->setEnabled(FALSE);
ctrl_deferred->setValue(FALSE);
+ ctrl_deferred2->setEnabled(FALSE);
+ ctrl_deferred2->setValue(FALSE);
}
// disabled deferred
@@ -1175,6 +1274,8 @@ void LLFloaterPreference::disableUnavailableSettings()
ctrl_deferred->setEnabled(FALSE);
ctrl_deferred->setValue(FALSE);
+ ctrl_deferred2->setEnabled(FALSE);
+ ctrl_deferred2->setValue(FALSE);
}
// disabled deferred SSAO
@@ -1219,6 +1320,8 @@ void LLFloaterPreference::disableUnavailableSettings()
ctrl_deferred->setEnabled(FALSE);
ctrl_deferred->setValue(FALSE);
+ ctrl_deferred2->setEnabled(FALSE);
+ ctrl_deferred2->setValue(FALSE);
}
// disabled cloth
@@ -1247,6 +1350,7 @@ void LLFloaterPreference::refresh()
updateSliderText(getChild<LLSliderCtrl>("FlexibleMeshDetail", true), getChild<LLTextBox>("FlexibleMeshDetailText", true));
updateSliderText(getChild<LLSliderCtrl>("TreeMeshDetail", true), getChild<LLTextBox>("TreeMeshDetailText", true));
updateSliderText(getChild<LLSliderCtrl>("AvatarMeshDetail", true), getChild<LLTextBox>("AvatarMeshDetailText", true));
+ updateSliderText(getChild<LLSliderCtrl>("AvatarMeshDetail2", true), getChild<LLTextBox>("AvatarMeshDetailText2", true));
updateSliderText(getChild<LLSliderCtrl>("AvatarPhysicsDetail", true), getChild<LLTextBox>("AvatarPhysicsDetailText", true));
updateSliderText(getChild<LLSliderCtrl>("TerrainMeshDetail", true), getChild<LLTextBox>("TerrainMeshDetailText", true));
updateSliderText(getChild<LLSliderCtrl>("RenderPostProcess", true), getChild<LLTextBox>("PostProcessText", true));
@@ -1379,17 +1483,94 @@ void LLFloaterPreference::setAllIgnored()
void LLFloaterPreference::onClickLogPath()
{
std::string proposed_name(gSavedPerAccountSettings.getString("InstantMessageLogPath"));
+ mPriorInstantMessageLogPath.clear();
LLDirPicker& picker = LLDirPicker::instance();
+ //Launches a directory picker and waits for feedback
if (!picker.getDir(&proposed_name ) )
{
return; //Canceled!
}
- gSavedPerAccountSettings.setString("InstantMessageLogPath", picker.getDirName());
+ //Gets the path from the directory picker
+ std::string dir_name = picker.getDirName();
+
+ //Path changed
+ if(proposed_name != dir_name)
+ {
+ gSavedPerAccountSettings.setString("InstantMessageLogPath", dir_name);
+ mPriorInstantMessageLogPath = proposed_name;
+
+ // enable/disable 'Delete transcripts button
+ updateDeleteTranscriptsButton();
+}
}
-void LLFloaterPreference::setPersonalInfo(const std::string& visibility, bool im_via_email, const std::string& email)
+bool LLFloaterPreference::moveTranscriptsAndLog()
+{
+ std::string instantMessageLogPath(gSavedPerAccountSettings.getString("InstantMessageLogPath"));
+ std::string chatLogPath = gDirUtilp->add(instantMessageLogPath, gDirUtilp->getUserName());
+
+ bool madeDirectory = false;
+
+ //Does the directory really exist, if not then make it
+ if(!LLFile::isdir(chatLogPath))
+ {
+ //mkdir success is defined as zero
+ if(LLFile::mkdir(chatLogPath) != 0)
+ {
+ return false;
+ }
+ madeDirectory = true;
+ }
+
+ std::string originalConversationLogDir = LLConversationLog::instance().getFileName();
+ std::string targetConversationLogDir = gDirUtilp->add(chatLogPath, "conversation.log");
+ //Try to move the conversation log
+ if(!LLConversationLog::instance().moveLog(originalConversationLogDir, targetConversationLogDir))
+ {
+ //Couldn't move the log and created a new directory so remove the new directory
+ if(madeDirectory)
+ {
+ LLFile::rmdir(chatLogPath);
+ }
+ return false;
+ }
+
+ //Attempt to move transcripts
+ std::vector<std::string> listOfTranscripts;
+ std::vector<std::string> listOfFilesMoved;
+
+ LLLogChat::getListOfTranscriptFiles(listOfTranscripts);
+
+ if(!LLLogChat::moveTranscripts(gDirUtilp->getChatLogsDir(),
+ instantMessageLogPath,
+ listOfTranscripts,
+ listOfFilesMoved))
+ {
+ //Couldn't move all the transcripts so restore those that moved back to their old location
+ LLLogChat::moveTranscripts(instantMessageLogPath,
+ gDirUtilp->getChatLogsDir(),
+ listOfFilesMoved);
+
+ //Move the conversation log back
+ LLConversationLog::instance().moveLog(targetConversationLogDir, originalConversationLogDir);
+
+ if(madeDirectory)
+ {
+ LLFile::rmdir(chatLogPath);
+ }
+
+ return false;
+ }
+
+ gDirUtilp->setChatLogsDir(instantMessageLogPath);
+ gDirUtilp->updatePerAccountChatLogsDir();
+
+ return true;
+}
+
+void LLFloaterPreference::setPersonalInfo(const std::string& visibility, bool im_via_email)
{
mGotPersonalInfo = true;
mOriginalIMViaEmail = im_via_email;
@@ -1411,49 +1592,19 @@ void LLFloaterPreference::setPersonalInfo(const std::string& visibility, bool im
}
getChild<LLUICtrl>("online_searchresults")->setEnabled(TRUE);
-
- getChildView("include_im_in_chat_history")->setEnabled(TRUE);
- getChildView("show_timestamps_check_im")->setEnabled(TRUE);
getChildView("friends_online_notify_checkbox")->setEnabled(TRUE);
-
getChild<LLUICtrl>("online_visibility")->setValue(mOriginalHideOnlineStatus);
getChild<LLUICtrl>("online_visibility")->setLabelArg("[DIR_VIS]", mDirectoryVisibility);
getChildView("send_im_to_email")->setEnabled(TRUE);
getChild<LLUICtrl>("send_im_to_email")->setValue(im_via_email);
- getChildView("plain_text_chat_history")->setEnabled(TRUE);
- getChild<LLUICtrl>("plain_text_chat_history")->setValue(gSavedSettings.getBOOL("PlainTextChatHistory"));
- getChildView("log_instant_messages")->setEnabled(TRUE);
-// getChildView("log_chat")->setEnabled(TRUE);
-// getChildView("busy_response")->setEnabled(TRUE);
-// getChildView("log_instant_messages_timestamp")->setEnabled(TRUE);
-// getChildView("log_chat_timestamp")->setEnabled(TRUE);
- getChildView("log_chat_IM")->setEnabled(TRUE);
- getChildView("log_date_timestamp")->setEnabled(TRUE);
-
-// getChild<LLUICtrl>("busy_response")->setValue(gSavedSettings.getString("BusyModeResponse2"));
-
getChildView("favorites_on_login_check")->setEnabled(TRUE);
- getChildView("log_nearby_chat")->setEnabled(TRUE);
- getChildView("log_instant_messages")->setEnabled(TRUE);
- getChildView("show_timestamps_check_im")->setEnabled(TRUE);
- getChildView("log_path_string")->setEnabled(FALSE);// LineEditor becomes readonly in this case.
getChildView("log_path_button")->setEnabled(TRUE);
- childEnable("logfile_name_datestamp");
- std::string display_email(email);
- getChild<LLUICtrl>("email_address")->setValue(display_email);
-
+ getChildView("chat_font_size")->setEnabled(TRUE);
}
-void LLFloaterPreference::onUpdateSliderText(LLUICtrl* ctrl, const LLSD& name)
+void LLFloaterPreference::refreshUI()
{
- std::string ctrl_name = name.asString();
-
- if ((ctrl_name =="" )|| !hasChild(ctrl_name, true))
- return;
-
- LLTextBox* text_box = getChild<LLTextBox>(name.asString());
- LLSliderCtrl* slider = dynamic_cast<LLSliderCtrl*>(ctrl);
- updateSliderText(slider, text_box);
+ refresh();
}
void LLFloaterPreference::updateSliderText(LLSliderCtrl* ctrl, LLTextBox* text_box)
@@ -1503,7 +1654,8 @@ void LLFloaterPreference::onChangeMaturity()
// but the UI for this will still be enabled
void LLFloaterPreference::onClickBlockList()
{
- LLFloaterSidePanelContainer::showPanel("people", "panel_block_list_sidetray", LLSD());
+ LLFloaterSidePanelContainer::showPanel("people", "panel_people",
+ LLSD().with("people_panel_tab_name", "blocked_panel"));
}
void LLFloaterPreference::onClickProxySettings()
@@ -1516,6 +1668,16 @@ void LLFloaterPreference::onClickTranslationSettings()
LLFloaterReg::showInstance("prefs_translation");
}
+void LLFloaterPreference::onClickAutoReplace()
+{
+ LLFloaterReg::showInstance("prefs_autoreplace");
+}
+
+void LLFloaterPreference::onClickSpellChecker()
+{
+ LLFloaterReg::showInstance("prefs_spellchecker");
+}
+
void LLFloaterPreference::onClickActionChange()
{
mClickActionDirty = true;
@@ -1526,6 +1688,33 @@ void LLFloaterPreference::onClickPermsDefault()
LLFloaterReg::showInstance("perms_default");
}
+void LLFloaterPreference::onDeleteTranscripts()
+{
+ LLSD args;
+ args["FOLDER"] = gDirUtilp->getUserName();
+
+ LLNotificationsUtil::add("PreferenceChatDeleteTranscripts", args, LLSD(), boost::bind(&LLFloaterPreference::onDeleteTranscriptsResponse, this, _1, _2));
+}
+
+void LLFloaterPreference::onDeleteTranscriptsResponse(const LLSD& notification, const LLSD& response)
+{
+ if (0 == LLNotificationsUtil::getSelectedOption(notification, response))
+ {
+ LLLogChat::deleteTranscripts();
+ updateDeleteTranscriptsButton();
+ }
+}
+
+void LLFloaterPreference::onLogChatHistorySaved()
+{
+ LLButton * delete_transcripts_buttonp = getChild<LLButton>("delete_transcripts");
+
+ if (!delete_transcripts_buttonp->getEnabled())
+ {
+ delete_transcripts_buttonp->setEnabled(true);
+ }
+}
+
void LLFloaterPreference::updateClickActionSettings()
{
const int single_clk_action = getChild<LLComboBox>("single_click_action_combo")->getValue().asInteger();
@@ -1564,6 +1753,35 @@ void LLFloaterPreference::setCacheLocation(const LLStringExplicit& location)
cache_location_editor->setToolTip(location);
}
+void LLFloaterPreference::selectPanel(const LLSD& name)
+{
+ LLTabContainer * tab_containerp = getChild<LLTabContainer>("pref core");
+ LLPanel * panel = tab_containerp->getPanelByName(name);
+ if (NULL != panel)
+ {
+ tab_containerp->selectTabPanel(panel);
+ }
+}
+
+void LLFloaterPreference::selectPrivacyPanel()
+{
+ selectPanel("im");
+}
+
+void LLFloaterPreference::selectChatPanel()
+{
+ selectPanel("chat");
+}
+
+void LLFloaterPreference::changed()
+{
+ getChild<LLButton>("clear_log")->setEnabled(LLConversationLog::instance().getConversations().size() > 0);
+
+ // set 'enable' property for 'Delete transcripts...' button
+ updateDeleteTranscriptsButton();
+
+}
+
//------------------------------Updater---------------------------------------
static bool handleBandwidthChanged(const LLSD& newvalue)
@@ -1622,9 +1840,20 @@ LLPanelPreference::LLPanelPreference()
//virtual
BOOL LLPanelPreference::postBuild()
{
+ ////////////////////// PanelGeneral ///////////////////
+ if (hasChild("display_names_check", TRUE))
+ {
+ BOOL use_people_api = gSavedSettings.getBOOL("UsePeopleAPI");
+ LLCheckBoxCtrl* ctrl_display_name = getChild<LLCheckBoxCtrl>("display_names_check");
+ ctrl_display_name->setEnabled(use_people_api);
+ if (!use_people_api)
+ {
+ ctrl_display_name->setValue(FALSE);
+ }
+ }
////////////////////// PanelVoice ///////////////////
- if (hasChild("voice_unavailable"))
+ if (hasChild("voice_unavailable", TRUE))
{
BOOL voice_disabled = gSavedSettings.getBOOL("CmdLineDisableVoice");
getChildView("voice_unavailable")->setVisible( voice_disabled);
@@ -1633,7 +1862,7 @@ BOOL LLPanelPreference::postBuild()
//////////////////////PanelSkins ///////////////////
- if (hasChild("skin_selection"))
+ if (hasChild("skin_selection", TRUE))
{
LLFloaterPreference::refreshSkin(this);
@@ -1646,35 +1875,29 @@ BOOL LLPanelPreference::postBuild()
}
- if (hasChild("online_visibility") && hasChild("send_im_to_email"))
- {
- getChild<LLUICtrl>("email_address")->setValue(getString("log_in_to_change") );
-// getChild<LLUICtrl>("busy_response")->setValue(getString("log_in_to_change"));
- }
-
//////////////////////PanelPrivacy ///////////////////
- if (hasChild("media_enabled"))
+ if (hasChild("media_enabled", TRUE))
{
bool media_enabled = gSavedSettings.getBOOL("AudioStreamingMedia");
getChild<LLCheckBoxCtrl>("media_enabled")->set(media_enabled);
getChild<LLCheckBoxCtrl>("autoplay_enabled")->setEnabled(media_enabled);
}
- if (hasChild("music_enabled"))
+ if (hasChild("music_enabled", TRUE))
{
getChild<LLCheckBoxCtrl>("music_enabled")->set(gSavedSettings.getBOOL("AudioStreamingMusic"));
}
- if (hasChild("voice_call_friends_only_check"))
+ if (hasChild("voice_call_friends_only_check", TRUE))
{
getChild<LLCheckBoxCtrl>("voice_call_friends_only_check")->setCommitCallback(boost::bind(&showFriendsOnlyWarning, _1, _2));
}
- if (hasChild("favorites_on_login_check"))
+ if (hasChild("favorites_on_login_check", TRUE))
{
getChild<LLCheckBoxCtrl>("favorites_on_login_check")->setCommitCallback(boost::bind(&showFavoritesOnLoginWarning, _1, _2));
}
- // Panel Advanced
- if (hasChild("modifier_combo"))
+ //////////////////////PanelAdvanced ///////////////////
+ if (hasChild("modifier_combo", TRUE))
{
//localizing if push2talk button is set to middle mouse
if (MIDDLE_MOUSE_CV == getChild<LLUICtrl>("modifier_combo")->getValue().asString())
@@ -1684,7 +1907,7 @@ BOOL LLPanelPreference::postBuild()
}
//////////////////////PanelSetup ///////////////////
- if (hasChild("max_bandwidth"))
+ if (hasChild("max_bandwidth"), TRUE)
{
mBandWidthUpdater = new LLPanelPreference::Updater(boost::bind(&handleBandwidthChanged, _1), BANDWIDTH_UPDATER_TIMEOUT);
gSavedSettings.getControl("ThrottleBandwidthKBPS")->getSignal()->connect(boost::bind(&LLPanelPreference::Updater::update, mBandWidthUpdater, _2));
@@ -1828,7 +2051,7 @@ public:
for (control_values_map_t::iterator it = mSavedValues.begin(); it != mSavedValues.end(); )
{
const std::string setting = it->first->getName();
- if (std::find(mAccountIndependentSettings.begin(),
+ if (find(mAccountIndependentSettings.begin(),
mAccountIndependentSettings.end(), setting) == mAccountIndependentSettings.end())
{
mSavedValues.erase(it++);
@@ -2117,4 +2340,5 @@ void LLFloaterPreferenceProxy::onChangeSocksSettings()
otherHttpProxy->selectFirstItem();
}
-};
+}
+
diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h
index bc6e74b0c7..e287631b1a 100644..100755
--- a/indra/newview/llfloaterpreference.h
+++ b/indra/newview/llfloaterpreference.h
@@ -35,7 +35,9 @@
#include "llfloater.h"
#include "llavatarpropertiesprocessor.h"
+#include "llconversationlog.h"
+class LLConversationLogObserver;
class LLPanelPreference;
class LLPanelLCD;
class LLPanelDebug;
@@ -45,6 +47,8 @@ class LLSliderCtrl;
class LLSD;
class LLTextBox;
+typedef std::map<std::string, std::string> notifications_map;
+
typedef enum
{
GS_LOW_GRAPHICS,
@@ -56,7 +60,7 @@ typedef enum
// Floater to control preferences (display, audio, bandwidth, general.
-class LLFloaterPreference : public LLFloater, public LLAvatarPropertiesObserver
+class LLFloaterPreference : public LLFloater, public LLAvatarPropertiesObserver, public LLConversationLogObserver
{
public:
LLFloaterPreference(const LLSD& key);
@@ -68,20 +72,24 @@ public:
/*virtual*/ BOOL postBuild();
/*virtual*/ void onOpen(const LLSD& key);
/*virtual*/ void onClose(bool app_quitting);
+ /*virtual*/ void changed();
+ /*virtual*/ void changed(const LLUUID& session_id, U32 mask) {};
// static data update, called from message handler
- static void updateUserInfo(const std::string& visibility, bool im_via_email, const std::string& email);
+ static void updateUserInfo(const std::string& visibility, bool im_via_email);
// refresh all the graphics preferences menus
static void refreshEnabledGraphics();
- // translate user's busy response message according to current locale if message is default, otherwise do nothing
- static void initBusyResponse();
+ // translate user's do not disturb response message according to current locale if message is default, otherwise do nothing
+ static void initDoNotDisturbResponse();
void processProperties( void* pData, EAvatarProcessorType type );
void processProfileProperties(const LLAvatarData* pAvatarData );
void storeAvatarProperties( const LLAvatarData* pAvatarData );
void saveAvatarProperties( void );
+ void selectPrivacyPanel();
+ void selectChatPanel();
protected:
void onBtnOK();
@@ -91,11 +99,12 @@ protected:
void onClickClearCache(); // Clear viewer texture cache, vfs, and VO cache on next startup
void onClickBrowserClearCache(); // Clear web history and caches as well as viewer caches above
void onLanguageChange();
+ void onNotificationsChange(const std::string& OptionName);
void onNameTagOpacityChange(const LLSD& newvalue);
- // set value of "BusyResponseChanged" in account settings depending on whether busy response
+ // set value of "DoNotDisturbResponseChanged" in account settings depending on whether do not disturb response
// string differs from default after user changes.
- void onBusyResponseChanged();
+ void onDoNotDisturbResponseChanged();
// if the custom settings box is clicked
void onChangeCustom();
void updateMeterText(LLUICtrl* ctrl);
@@ -129,15 +138,14 @@ public:
void setKey(KEY key);
void onClickSetMiddleMouse();
void onClickSetSounds();
-// void onClickSkipDialogs();
-// void onClickResetDialogs();
void onClickEnablePopup();
void onClickDisablePopup();
void resetAllIgnored();
void setAllIgnored();
- void onClickLogPath();
+ void onClickLogPath();
+ bool moveTranscriptsAndLog();
void enableHistory();
- void setPersonalInfo(const std::string& visibility, bool im_via_email, const std::string& email);
+ void setPersonalInfo(const std::string& visibility, bool im_via_email);
void refreshEnabledState();
void disableUnavailableSettings();
void onCommitWindowedMode();
@@ -146,8 +154,7 @@ public:
void onChangeQuality(const LLSD& data);
void updateSliderText(LLSliderCtrl* ctrl, LLTextBox* text_box);
- void onUpdateSliderText(LLUICtrl* ctrl, const LLSD& name);
-// void fractionFromDecimal(F32 decimal_val, S32& numerator, S32& denominator);
+ void refreshUI();
void onCommitParcelMediaAutoPlayEnable();
void onCommitMediaEnabled();
@@ -158,18 +165,29 @@ public:
void onClickProxySettings();
void onClickTranslationSettings();
void onClickPermsDefault();
+ void onClickAutoReplace();
+ void onClickSpellChecker();
void applyUIColor(LLUICtrl* ctrl, const LLSD& param);
void getUIColor(LLUICtrl* ctrl, const LLSD& param);
-
+ void onLogChatHistorySaved();
void buildPopupLists();
static void refreshSkin(void* data);
+ void selectPanel(const LLSD& name);
+
private:
+
+ void onDeleteTranscripts();
+ void onDeleteTranscriptsResponse(const LLSD& notification, const LLSD& response);
+ void updateDeleteTranscriptsButton();
+
static std::string sSkin;
+ notifications_map mNotificationOptions;
bool mClickActionDirty; ///< Set to true when the click/double-click options get changed by user.
bool mGotPersonalInfo;
bool mOriginalIMViaEmail;
bool mLanguageChanged;
bool mAvatarDataInitialized;
+ std::string mPriorInstantMessageLogPath;
bool mOriginalHideOnlineStatus;
std::string mDirectoryVisibility;
diff --git a/indra/newview/llfloaterproperties.cpp b/indra/newview/llfloaterproperties.cpp
index 3f00ba39c7..3f00ba39c7 100644..100755
--- a/indra/newview/llfloaterproperties.cpp
+++ b/indra/newview/llfloaterproperties.cpp
diff --git a/indra/newview/llfloaterproperties.h b/indra/newview/llfloaterproperties.h
index aa3fcec337..aa3fcec337 100644..100755
--- a/indra/newview/llfloaterproperties.h
+++ b/indra/newview/llfloaterproperties.h
diff --git a/indra/newview/llfloaterregiondebugconsole.cpp b/indra/newview/llfloaterregiondebugconsole.cpp
index c7fab2573f..3a7ca17b73 100644..100755
--- a/indra/newview/llfloaterregiondebugconsole.cpp
+++ b/indra/newview/llfloaterregiondebugconsole.cpp
@@ -75,7 +75,7 @@ namespace
{
public:
/* virtual */
- void error(U32 status, const std::string& reason)
+ void errorWithContent(U32 status, const std::string& reason, const LLSD& content)
{
sConsoleReplySignal(UNABLE_TO_SEND_COMMAND);
}
diff --git a/indra/newview/llfloaterregiondebugconsole.h b/indra/newview/llfloaterregiondebugconsole.h
index fd3af4152e..fd3af4152e 100644..100755
--- a/indra/newview/llfloaterregiondebugconsole.h
+++ b/indra/newview/llfloaterregiondebugconsole.h
diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp
index 17850ff35d..66bf49331b 100644..100755
--- a/indra/newview/llfloaterregioninfo.cpp
+++ b/indra/newview/llfloaterregioninfo.cpp
@@ -287,8 +287,7 @@ void LLFloaterRegionInfo::processEstateOwnerRequest(LLMessageSystem* msg,void**)
//dispatch the message
dispatch.dispatch(request, invoice, strings);
- LLViewerRegion* region = gAgent.getRegion();
- panel->updateControls(region);
+ panel->updateControls(gAgent.getRegion());
}
@@ -319,7 +318,7 @@ void LLFloaterRegionInfo::processRegionInfo(LLMessageSystem* msg)
// extract message
std::string sim_name;
std::string sim_type = LLTrans::getString("land_type_unknown");
- U32 region_flags;
+ U64 region_flags;
U8 agent_limit;
F32 object_bonus_factor;
U8 sim_access;
@@ -329,7 +328,6 @@ void LLFloaterRegionInfo::processRegionInfo(LLMessageSystem* msg)
BOOL use_estate_sun;
F32 sun_hour;
msg->getString("RegionInfo", "SimName", sim_name);
- msg->getU32("RegionInfo", "RegionFlags", region_flags);
msg->getU8("RegionInfo", "MaxAgents", agent_limit);
msg->getF32("RegionInfo", "ObjectBonusFactor", object_bonus_factor);
msg->getU8("RegionInfo", "SimAccess", sim_access);
@@ -348,6 +346,17 @@ void LLFloaterRegionInfo::processRegionInfo(LLMessageSystem* msg)
LLTrans::findString(sim_type, sim_type); // try localizing sim product name
}
+ if (msg->has(_PREHASH_RegionInfo3))
+ {
+ msg->getU64("RegionInfo3", "RegionFlagsExtended", region_flags);
+ }
+ else
+ {
+ U32 flags = 0;
+ msg->getU32("RegionInfo", "RegionFlags", flags);
+ region_flags = flags;
+ }
+
// GENERAL PANEL
panel = tab->getChild<LLPanel>("General");
panel->getChild<LLUICtrl>("region_text")->setValue(LLSD(sim_name));
@@ -379,9 +388,9 @@ void LLFloaterRegionInfo::processRegionInfo(LLMessageSystem* msg)
panel = tab->getChild<LLPanel>("Debug");
panel->getChild<LLUICtrl>("region_text")->setValue(LLSD(sim_name) );
- panel->getChild<LLUICtrl>("disable_scripts_check")->setValue(LLSD((BOOL)(region_flags & REGION_FLAGS_SKIP_SCRIPTS)) );
- panel->getChild<LLUICtrl>("disable_collisions_check")->setValue(LLSD((BOOL)(region_flags & REGION_FLAGS_SKIP_COLLISIONS)) );
- panel->getChild<LLUICtrl>("disable_physics_check")->setValue(LLSD((BOOL)(region_flags & REGION_FLAGS_SKIP_PHYSICS)) );
+ panel->getChild<LLUICtrl>("disable_scripts_check")->setValue(LLSD((BOOL)((region_flags & REGION_FLAGS_SKIP_SCRIPTS) ? TRUE : FALSE )) );
+ panel->getChild<LLUICtrl>("disable_collisions_check")->setValue(LLSD((BOOL)((region_flags & REGION_FLAGS_SKIP_COLLISIONS) ? TRUE : FALSE )) );
+ panel->getChild<LLUICtrl>("disable_physics_check")->setValue(LLSD((BOOL)((region_flags & REGION_FLAGS_SKIP_PHYSICS) ? TRUE : FALSE )) );
panel->setCtrlsEnabled(allow_modify);
// TERRAIN PANEL
@@ -648,8 +657,10 @@ void LLPanelRegionGeneralInfo::onClickKick()
// this depends on the grandparent view being a floater
// in order to set up floater dependency
+ LLView * button = findChild<LLButton>("kick_btn");
LLFloater* parent_floater = gFloaterView->getParentFloater(this);
- LLFloater* child_floater = LLFloaterAvatarPicker::show(boost::bind(&LLPanelRegionGeneralInfo::onKickCommit, this, _1), FALSE, TRUE);
+ LLFloater* child_floater = LLFloaterAvatarPicker::show(boost::bind(&LLPanelRegionGeneralInfo::onKickCommit, this, _1),
+ FALSE, TRUE, FALSE, parent_floater->getName(), button);
if (child_floater)
{
parent_floater->addDependentFloater(child_floater);
@@ -747,9 +758,10 @@ class ConsoleRequestResponder : public LLHTTPClient::Responder
{
public:
/*virtual*/
- void error(U32 status, const std::string& reason)
+ void errorWithContent(U32 status, const std::string& reason, const LLSD& content)
{
- llwarns << "requesting mesh_rez_enabled failed" << llendl;
+ llwarns << "ConsoleRequestResponder error requesting mesh_rez_enabled [status:"
+ << status << "]: " << content << llendl;
}
};
@@ -759,9 +771,10 @@ class ConsoleUpdateResponder : public LLHTTPClient::Responder
{
public:
/* virtual */
- void error(U32 status, const std::string& reason)
+ void errorWithContent(U32 status, const std::string& reason, const LLSD& content)
{
- llwarns << "Updating mesh enabled region setting failed" << llendl;
+ llwarns << "ConsoleRequestResponder error updating mesh enabled region setting [status:"
+ << status << "]: " << content << llendl;
}
};
@@ -925,7 +938,14 @@ BOOL LLPanelRegionDebugInfo::sendUpdate()
void LLPanelRegionDebugInfo::onClickChooseAvatar()
{
- LLFloaterAvatarPicker::show(boost::bind(&LLPanelRegionDebugInfo::callbackAvatarID, this, _1, _2), FALSE, TRUE);
+ LLView * button = findChild<LLButton>("choose_avatar_btn");
+ LLFloater* parent_floater = gFloaterView->getParentFloater(this);
+ LLFloater * child_floater = LLFloaterAvatarPicker::show(boost::bind(&LLPanelRegionDebugInfo::callbackAvatarID, this, _1, _2),
+ FALSE, TRUE, FALSE, parent_floater->getName(), button);
+ if (child_floater)
+ {
+ parent_floater->addDependentFloater(child_floater);
+ }
}
@@ -1471,8 +1491,10 @@ void LLPanelEstateInfo::onClickKickUser()
{
// this depends on the grandparent view being a floater
// in order to set up floater dependency
+ LLView * button = findChild<LLButton>("kick_user_from_estate_btn");
LLFloater* parent_floater = gFloaterView->getParentFloater(this);
- LLFloater* child_floater = LLFloaterAvatarPicker::show(boost::bind(&LLPanelEstateInfo::onKickUserCommit, this, _1), FALSE, TRUE);
+ LLFloater* child_floater = LLFloaterAvatarPicker::show(boost::bind(&LLPanelEstateInfo::onKickUserCommit, this, _1),
+ FALSE, TRUE, FALSE, parent_floater->getName(), button);
if (child_floater)
{
parent_floater->addDependentFloater(child_floater);
@@ -1647,8 +1669,39 @@ bool LLPanelEstateInfo::accessAddCore2(const LLSD& notification, const LLSD& res
}
LLEstateAccessChangeInfo* change_info = new LLEstateAccessChangeInfo(notification["payload"]);
+ //Get parent floater name
+ LLPanelEstateInfo* panel = LLFloaterRegionInfo::getPanelEstate();
+ LLFloater* parent_floater = panel ? gFloaterView->getParentFloater(panel) : NULL;
+ const std::string& parent_floater_name = parent_floater ? parent_floater->getName() : "";
+
+ //Determine the button that triggered opening of the avatar picker
+ //(so that a shadow frustum from the button to the avatar picker can be created)
+ LLView * button = NULL;
+ switch(change_info->mOperationFlag)
+ {
+ case ESTATE_ACCESS_ALLOWED_AGENT_ADD:
+ button = panel->findChild<LLButton>("add_allowed_avatar_btn");
+ break;
+
+ case ESTATE_ACCESS_BANNED_AGENT_ADD:
+ button = panel->findChild<LLButton>("add_banned_avatar_btn");
+ break;
+
+ case ESTATE_ACCESS_MANAGER_ADD:
+ button = panel->findChild<LLButton>("add_estate_manager_btn");
+ break;
+ }
+
// avatar picker yes multi-select, yes close-on-select
- LLFloaterAvatarPicker::show(boost::bind(&LLPanelEstateInfo::accessAddCore3, _1, (void*)change_info), TRUE, TRUE);
+ LLFloater* child_floater = LLFloaterAvatarPicker::show(boost::bind(&LLPanelEstateInfo::accessAddCore3, _1, (void*)change_info),
+ TRUE, TRUE, FALSE, parent_floater_name, button);
+
+ //Allows the closed parent floater to close the child floater (avatar picker)
+ if (child_floater)
+ {
+ parent_floater->addDependentFloater(child_floater);
+ }
+
return false;
}
@@ -1681,7 +1734,7 @@ void LLPanelEstateInfo::accessAddCore3(const uuid_vec_t& ids, void* data)
LLSD args;
args["NUM_ADDED"] = llformat("%d",ids.size());
args["MAX_AGENTS"] = llformat("%d",ESTATE_MAX_ACCESS_IDS);
- args["LIST_TYPE"] = "Allowed Residents";
+ args["LIST_TYPE"] = LLTrans::getString("RegionInfoListTypeAllowedAgents");
args["NUM_EXCESS"] = llformat("%d",(ids.size()+currentCount)-ESTATE_MAX_ACCESS_IDS);
LLNotificationsUtil::add("MaxAgentOnRegionBatch", args);
delete change_info;
@@ -1697,7 +1750,7 @@ void LLPanelEstateInfo::accessAddCore3(const uuid_vec_t& ids, void* data)
LLSD args;
args["NUM_ADDED"] = llformat("%d",ids.size());
args["MAX_AGENTS"] = llformat("%d",ESTATE_MAX_ACCESS_IDS);
- args["LIST_TYPE"] = "Banned Residents";
+ args["LIST_TYPE"] = LLTrans::getString("RegionInfoListTypeBannedAgents");
args["NUM_EXCESS"] = llformat("%d",(ids.size()+currentCount)-ESTATE_MAX_ACCESS_IDS);
LLNotificationsUtil::add("MaxAgentOnRegionBatch", args);
delete change_info;
@@ -1924,10 +1977,18 @@ void LLPanelEstateInfo::updateControls(LLViewerRegion* region)
BOOL manager = (region && region->isEstateManager());
setCtrlsEnabled(god || owner || manager);
+ BOOL has_allowed_avatar = getChild<LLNameListCtrl>("allowed_avatar_name_list")->getFirstSelected() ? TRUE : FALSE;
+ BOOL has_allowed_group = getChild<LLNameListCtrl>("allowed_group_name_list")->getFirstSelected() ? TRUE : FALSE;
+ BOOL has_banned_agent = getChild<LLNameListCtrl>("banned_avatar_name_list")->getFirstSelected() ? TRUE : FALSE;
+ BOOL has_estate_manager = getChild<LLNameListCtrl>("estate_manager_name_list")->getFirstSelected() ? TRUE : FALSE;
+
getChildView("add_allowed_avatar_btn")->setEnabled(god || owner || manager);
- getChildView("remove_allowed_avatar_btn")->setEnabled(god || owner || manager);
+ getChildView("remove_allowed_avatar_btn")->setEnabled(has_allowed_avatar && (god || owner || manager));
+ getChildView("allowed_avatar_name_list")->setEnabled(god || owner || manager);
+
getChildView("add_allowed_group_btn")->setEnabled(god || owner || manager);
- getChildView("remove_allowed_group_btn")->setEnabled(god || owner || manager);
+ getChildView("remove_allowed_group_btn")->setEnabled(has_allowed_group && (god || owner || manager) );
+ getChildView("allowed_group_name_list")->setEnabled(god || owner || manager);
// Can't ban people from mainland, orientation islands, etc. because this
// creates much network traffic and server load.
@@ -1935,14 +1996,15 @@ void LLPanelEstateInfo::updateControls(LLViewerRegion* region)
bool linden_estate = isLindenEstate();
bool enable_ban = (god || owner || manager) && !linden_estate;
getChildView("add_banned_avatar_btn")->setEnabled(enable_ban);
- getChildView("remove_banned_avatar_btn")->setEnabled(enable_ban);
+ getChildView("remove_banned_avatar_btn")->setEnabled(has_banned_agent && enable_ban);
+ getChildView("banned_avatar_name_list")->setEnabled(god || owner || manager);
getChildView("message_estate_btn")->setEnabled(god || owner || manager);
getChildView("kick_user_from_estate_btn")->setEnabled(god || owner || manager);
// estate managers can't add estate managers
getChildView("add_estate_manager_btn")->setEnabled(god || owner);
- getChildView("remove_estate_manager_btn")->setEnabled(god || owner);
+ getChildView("remove_estate_manager_btn")->setEnabled(has_estate_manager && (god || owner));
getChildView("estate_manager_name_list")->setEnabled(god || owner);
refresh();
@@ -1979,10 +2041,8 @@ bool LLPanelEstateInfo::refreshFromRegion(LLViewerRegion* region)
void LLPanelEstateInfo::updateChild(LLUICtrl* child_ctrl)
{
- if (checkRemovalButton(child_ctrl->getName()))
- {
- // do nothing
- }
+ // Ensure appropriate state of the management ui.
+ updateControls(gAgent.getRegion());
}
bool LLPanelEstateInfo::estateUpdate(LLMessageSystem* msg)
@@ -2080,23 +2140,8 @@ void LLPanelEstateInfo::refreshFromEstate()
getChild<LLUICtrl>("limit_payment")->setValue(estate_info.getDenyAnonymous());
getChild<LLUICtrl>("limit_age_verified")->setValue(estate_info.getDenyAgeUnverified());
- // If visible from mainland, disable the access allowed
- // UI, as anyone can teleport there.
- // However, gods need to be able to edit the access list for
- // linden estates, regardless of visibility, to allow object
- // and L$ transfers.
- {
- bool visible_from_mainland = estate_info.getIsExternallyVisible();
- bool god = gAgent.isGodlike();
- bool linden_estate = isLindenEstate();
-
- bool enable_agent = (!visible_from_mainland || (god && linden_estate));
- bool enable_group = enable_agent;
- bool enable_ban = !linden_estate;
-
- setAccessAllowedEnabled(enable_agent, enable_group, enable_ban);
- }
-
+ // Ensure appriopriate state of the management UI
+ updateControls(gAgent.getRegion());
refresh();
}
@@ -2206,10 +2251,10 @@ public:
}
// if we get an error response
- virtual void error(U32 status, const std::string& reason)
+ virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content)
{
- llinfos << "LLEstateChangeInfoResponder::error "
- << status << ": " << reason << llendl;
+ llinfos << "LLEstateChangeInfoResponder::error [status:"
+ << status << "]: " << content << llendl;
}
private:
LLHandle<LLPanel> mpPanel;
@@ -2225,47 +2270,6 @@ void LLPanelEstateInfo::setOwnerName(const std::string& name)
getChild<LLUICtrl>("estate_owner")->setValue(LLSD(name));
}
-void LLPanelEstateInfo::setAccessAllowedEnabled(bool enable_agent,
- bool enable_group,
- bool enable_ban)
-{
- getChildView("allow_resident_label")->setEnabled(enable_agent);
- getChildView("allowed_avatar_name_list")->setEnabled(enable_agent);
- getChildView("allowed_avatar_name_list")->setVisible( enable_agent);
- getChildView("add_allowed_avatar_btn")->setEnabled(enable_agent);
- getChildView("remove_allowed_avatar_btn")->setEnabled(enable_agent);
-
- // Groups
- getChildView("allow_group_label")->setEnabled(enable_group);
- getChildView("allowed_group_name_list")->setEnabled(enable_group);
- getChildView("allowed_group_name_list")->setVisible( enable_group);
- getChildView("add_allowed_group_btn")->setEnabled(enable_group);
- getChildView("remove_allowed_group_btn")->setEnabled(enable_group);
-
- // Ban
- getChildView("ban_resident_label")->setEnabled(enable_ban);
- getChildView("banned_avatar_name_list")->setEnabled(enable_ban);
- getChildView("banned_avatar_name_list")->setVisible( enable_ban);
- getChildView("add_banned_avatar_btn")->setEnabled(enable_ban);
- getChildView("remove_banned_avatar_btn")->setEnabled(enable_ban);
-
- // Update removal buttons if needed
- if (enable_agent)
- {
- checkRemovalButton("allowed_avatar_name_list");
- }
-
- if (enable_group)
- {
- checkRemovalButton("allowed_group_name_list");
- }
-
- if (enable_ban)
- {
- checkRemovalButton("banned_avatar_name_list");
- }
-}
-
void LLPanelEstateInfo::clearAccessLists()
{
LLNameListCtrl* name_list = getChild<LLNameListCtrl>("allowed_avatar_name_list");
@@ -2279,39 +2283,7 @@ void LLPanelEstateInfo::clearAccessLists()
{
name_list->deleteAllItems();
}
-}
-
-// enables/disables the "remove" button for the various allow/ban lists
-BOOL LLPanelEstateInfo::checkRemovalButton(std::string name)
-{
- std::string btn_name = "";
- if (name == "allowed_avatar_name_list")
- {
- btn_name = "remove_allowed_avatar_btn";
- }
- else if (name == "allowed_group_name_list")
- {
- btn_name = "remove_allowed_group_btn";
- }
- else if (name == "banned_avatar_name_list")
- {
- btn_name = "remove_banned_avatar_btn";
- }
- else if (name == "estate_manager_name_list")
- {
- //ONLY OWNER CAN ADD /DELET ESTATE MANAGER
- LLViewerRegion* region = gAgent.getRegion();
- if (region && (region->getOwner() == gAgent.getID()))
- {
- btn_name = "remove_estate_manager_btn";
- }
- }
-
- // enable the remove button if something is selected
- LLNameListCtrl* name_list = getChild<LLNameListCtrl>(name);
- getChildView(btn_name)->setEnabled(name_list && name_list->getFirstSelected() ? TRUE : FALSE);
-
- return (btn_name != "");
+ updateControls(gAgent.getRegion());
}
// static
@@ -2358,7 +2330,7 @@ bool LLPanelEstateCovenant::refreshFromRegion(LLViewerRegion* region)
LLTextBox* resellable_clause = getChild<LLTextBox>("resellable_clause");
if (resellable_clause)
{
- if (region->getRegionFlags() & REGION_FLAGS_BLOCK_LAND_RESELL)
+ if (region->getRegionFlag(REGION_FLAGS_BLOCK_LAND_RESELL))
{
resellable_clause->setText(getString("can_not_resell"));
}
@@ -2371,7 +2343,7 @@ bool LLPanelEstateCovenant::refreshFromRegion(LLViewerRegion* region)
LLTextBox* changeable_clause = getChild<LLTextBox>("changeable_clause");
if (changeable_clause)
{
- if (region->getRegionFlags() & REGION_FLAGS_ALLOW_PARCEL_CHANGES)
+ if (region->getRegionFlag(REGION_FLAGS_ALLOW_PARCEL_CHANGES))
{
changeable_clause->setText(getString("can_change"));
}
@@ -2792,15 +2764,15 @@ bool LLDispatchSetEstateAccess::operator()(
if (allowed_agent_name_list)
{
- //allowed_agent_name_list->deleteAllItems();
+ // Don't sort these as we add them, sort them when we are done.
+ allowed_agent_name_list->clearSortOrder();
for (S32 i = 0; i < num_allowed_agents && i < ESTATE_MAX_ACCESS_IDS; i++)
{
LLUUID id;
memcpy(id.mData, strings[index++].data(), UUID_BYTES); /* Flawfinder: ignore */
allowed_agent_name_list->addNameItem(id);
}
- panel->getChildView("remove_allowed_avatar_btn")->setEnabled(allowed_agent_name_list->getFirstSelected() ? TRUE : FALSE);
- allowed_agent_name_list->sortByColumnIndex(0, TRUE);
+ allowed_agent_name_list->sortByName(TRUE);
}
}
@@ -2817,6 +2789,8 @@ bool LLDispatchSetEstateAccess::operator()(
if (allowed_group_name_list)
{
+ // Don't sort these as we add them, sort them when we are done.
+ allowed_group_name_list->clearSortOrder();
allowed_group_name_list->deleteAllItems();
for (S32 i = 0; i < num_allowed_groups && i < ESTATE_MAX_GROUP_IDS; i++)
{
@@ -2824,8 +2798,7 @@ bool LLDispatchSetEstateAccess::operator()(
memcpy(id.mData, strings[index++].data(), UUID_BYTES); /* Flawfinder: ignore */
allowed_group_name_list->addGroupNameItem(id);
}
- panel->getChildView("remove_allowed_group_btn")->setEnabled(allowed_group_name_list->getFirstSelected() ? TRUE : FALSE);
- allowed_group_name_list->sortByColumnIndex(0, TRUE);
+ allowed_group_name_list->sortByName(TRUE);
}
}
@@ -2842,36 +2815,42 @@ bool LLDispatchSetEstateAccess::operator()(
}
- std::string msg = llformat("Banned residents: (%d, max %d)",
- totalBannedAgents,
- ESTATE_MAX_ACCESS_IDS);
+ LLStringUtil::format_map_t args;
+ args["[BANNEDAGENTS]"] = llformat("%d", totalBannedAgents);
+ args["[MAXBANNED]"] = llformat("%d", ESTATE_MAX_ACCESS_IDS);
+ std::string msg = LLTrans::getString("RegionInfoBannedResidents", args);
panel->getChild<LLUICtrl>("ban_resident_label")->setValue(LLSD(msg));
if (banned_agent_name_list)
{
- //banned_agent_name_list->deleteAllItems();
+ // Don't sort these as we add them, sort them when we are done.
+ banned_agent_name_list->clearSortOrder();
+
for (S32 i = 0; i < num_banned_agents && i < ESTATE_MAX_ACCESS_IDS; i++)
{
LLUUID id;
memcpy(id.mData, strings[index++].data(), UUID_BYTES); /* Flawfinder: ignore */
banned_agent_name_list->addNameItem(id);
}
- panel->getChildView("remove_banned_avatar_btn")->setEnabled(banned_agent_name_list->getFirstSelected() ? TRUE : FALSE);
- banned_agent_name_list->sortByColumnIndex(0, TRUE);
+ banned_agent_name_list->sortByName(TRUE);
}
}
if (access_flags & ESTATE_ACCESS_MANAGERS)
{
- std::string msg = llformat("Estate Managers: (%d, max %d)",
- num_estate_managers,
- ESTATE_MAX_MANAGERS);
+ LLStringUtil::format_map_t args;
+ args["[ESTATEMANAGERS]"] = llformat("%d", num_estate_managers);
+ args["[MAXMANAGERS]"] = llformat("%d", ESTATE_MAX_MANAGERS);
+ std::string msg = LLTrans::getString("RegionInfoEstateManagers", args);
panel->getChild<LLUICtrl>("estate_manager_label")->setValue(LLSD(msg));
LLNameListCtrl* estate_manager_name_list =
panel->getChild<LLNameListCtrl>("estate_manager_name_list");
if (estate_manager_name_list)
{
+ // Don't sort these as we add them, sort them when we are done.
+ estate_manager_name_list->clearSortOrder();
+
estate_manager_name_list->deleteAllItems(); // Clear existing entries
// There should be only ESTATE_MAX_MANAGERS people in the list, but if the database gets more (SL-46107) don't
@@ -2883,11 +2862,13 @@ bool LLDispatchSetEstateAccess::operator()(
memcpy(id.mData, strings[index++].data(), UUID_BYTES); /* Flawfinder: ignore */
estate_manager_name_list->addNameItem(id);
}
- panel->getChildView("remove_estate_manager_btn")->setEnabled(estate_manager_name_list->getFirstSelected() ? TRUE : FALSE);
- estate_manager_name_list->sortByColumnIndex(0, TRUE);
+ estate_manager_name_list->sortByName(TRUE);
}
}
+ // Update the buttons which may change based on the list contents but also needs to account for general access features.
+ panel->updateControls(gAgent.getRegion());
+
return true;
}
diff --git a/indra/newview/llfloaterregioninfo.h b/indra/newview/llfloaterregioninfo.h
index e36ef4604b..f0499f1903 100644..100755
--- a/indra/newview/llfloaterregioninfo.h
+++ b/indra/newview/llfloaterregioninfo.h
@@ -312,9 +312,6 @@ public:
const std::string getOwnerName() const;
void setOwnerName(const std::string& name);
- // If visible from mainland, allowed agent and allowed groups
- // are ignored, so must disable UI.
- void setAccessAllowedEnabled(bool enable_agent, bool enable_group, bool enable_ban);
protected:
virtual BOOL sendUpdate();
// confirmation dialog callback
@@ -324,7 +321,6 @@ protected:
void commitEstateManagers();
void clearAccessLists();
- BOOL checkRemovalButton(std::string name);
BOOL checkSunHourSlider(LLUICtrl* child_ctrl);
U32 mEstateID;
diff --git a/indra/newview/llfloaterreporter.cpp b/indra/newview/llfloaterreporter.cpp
index 3ec1e372eb..35b63c5480 100644..100755
--- a/indra/newview/llfloaterreporter.cpp
+++ b/indra/newview/llfloaterreporter.cpp
@@ -103,16 +103,14 @@ LLFloaterReporter::LLFloaterReporter(const LLSD& key)
mPicking( FALSE),
mPosition(),
mCopyrightWarningSeen( FALSE ),
- mResourceDatap(new LLResourceData())
+ mResourceDatap(new LLResourceData()),
+ mAvatarNameCacheConnection()
{
}
// static
void LLFloaterReporter::processRegionInfo(LLMessageSystem* msg)
{
- U32 region_flags;
- msg->getU32("RegionInfo", "RegionFlags", region_flags);
-
if ( LLFloaterReg::instanceVisible("reporter") )
{
LLNotificationsUtil::add("HelpReportAbuseEmailLL");
@@ -187,6 +185,11 @@ BOOL LLFloaterReporter::postBuild()
// virtual
LLFloaterReporter::~LLFloaterReporter()
{
+ if (mAvatarNameCacheConnection.connected())
+ {
+ mAvatarNameCacheConnection.disconnect();
+ }
+
// child views automatically deleted
mObjectID = LLUUID::null;
@@ -285,10 +288,13 @@ void LLFloaterReporter::getObjectInfo(const LLUUID& object_id)
void LLFloaterReporter::onClickSelectAbuser()
{
- LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(boost::bind(&LLFloaterReporter::callbackAvatarID, this, _1, _2), FALSE, TRUE );
+ LLView * button = findChild<LLButton>("select_abuser", TRUE);
+
+ LLFloater * root_floater = gFloaterView->getParentFloater(this);
+ LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(boost::bind(&LLFloaterReporter::callbackAvatarID, this, _1, _2), FALSE, TRUE, FALSE, root_floater->getName(), button);
if (picker)
{
- gFloaterView->getParentFloater(this)->addDependentFloater(picker);
+ root_floater->addDependentFloater(picker);
}
}
@@ -310,11 +316,17 @@ void LLFloaterReporter::setFromAvatarID(const LLUUID& avatar_id)
std::string avatar_link = LLSLURL("agent", mObjectID, "inspect").getSLURLString();
getChild<LLUICtrl>("owner_name")->setValue(avatar_link);
- LLAvatarNameCache::get(avatar_id, boost::bind(&LLFloaterReporter::onAvatarNameCache, this, _1, _2));
+ if (mAvatarNameCacheConnection.connected())
+ {
+ mAvatarNameCacheConnection.disconnect();
+ }
+ mAvatarNameCacheConnection = LLAvatarNameCache::get(avatar_id, boost::bind(&LLFloaterReporter::onAvatarNameCache, this, _1, _2));
}
void LLFloaterReporter::onAvatarNameCache(const LLUUID& avatar_id, const LLAvatarName& av_name)
{
+ mAvatarNameCacheConnection.disconnect();
+
if (mObjectID == avatar_id)
{
mOwnerName = av_name.getCompleteName();
@@ -698,7 +710,7 @@ class LLUserReportResponder : public LLHTTPClient::Responder
public:
LLUserReportResponder(): LLHTTPClient::Responder() {}
- void error(U32 status, const std::string& reason)
+ void errorWithContent(U32 status, const std::string& reason, const LLSD& content)
{
// *TODO do some user messaging here
LLUploadDialog::modalUploadFinished();
@@ -768,8 +780,8 @@ void LLFloaterReporter::takeScreenshot()
// store in the image list so it doesn't try to fetch from the server
LLPointer<LLViewerFetchedTexture> image_in_list =
- LLViewerTextureManager::getFetchedTexture(mResourceDatap->mAssetInfo.mUuid, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::FETCHED_TEXTURE);
- image_in_list->createGLTexture(0, raw, 0, TRUE, LLViewerTexture::OTHER);
+ LLViewerTextureManager::getFetchedTexture(mResourceDatap->mAssetInfo.mUuid);
+ image_in_list->createGLTexture(0, raw, 0, TRUE, LLGLTexture::OTHER);
// the texture picker then uses that texture
LLTexturePicker* texture = getChild<LLTextureCtrl>("screenshot");
@@ -816,12 +828,7 @@ void LLFloaterReporter::uploadDoneCallback(const LLUUID &uuid, void *user_data,
return;
}
- EReportType report_type = UNKNOWN_REPORT;
- if (data->mPreferredLocation == LLResourceData::INVALID_LOCATION)
- {
- report_type = COMPLAINT_REPORT;
- }
- else
+ if (data->mPreferredLocation != LLResourceData::INVALID_LOCATION)
{
llwarns << "Unknown report type : " << data->mPreferredLocation << llendl;
}
diff --git a/indra/newview/llfloaterreporter.h b/indra/newview/llfloaterreporter.h
index 7d68431710..d54e7f6ab0 100644..100755
--- a/indra/newview/llfloaterreporter.h
+++ b/indra/newview/llfloaterreporter.h
@@ -137,6 +137,7 @@ private:
std::list<LLMeanCollisionData*> mMCDList;
std::string mDefaultSummary;
LLResourceData* mResourceDatap;
+ boost::signals2::connection mAvatarNameCacheConnection;
};
#endif
diff --git a/indra/newview/llfloaterscriptdebug.cpp b/indra/newview/llfloaterscriptdebug.cpp
index b691db1049..6c17f62c1e 100644..100755
--- a/indra/newview/llfloaterscriptdebug.cpp
+++ b/indra/newview/llfloaterscriptdebug.cpp
@@ -105,7 +105,7 @@ void LLFloaterScriptDebug::addScriptLine(const std::string &utf8mesg, const std:
if (objectp)
{
- objectp->setIcon(LLViewerTextureManager::getFetchedTextureFromFile("script_error.j2c", TRUE, LLViewerTexture::BOOST_UI));
+ objectp->setIcon(LLViewerTextureManager::getFetchedTextureFromFile("script_error.j2c", FTT_LOCAL_FILE, TRUE, LLGLTexture::BOOST_UI));
floater_label = llformat("%s(%.0f, %.0f, %.0f)",
user_name.c_str(),
objectp->getPositionRegion().mV[VX],
diff --git a/indra/newview/llfloaterscriptdebug.h b/indra/newview/llfloaterscriptdebug.h
index 6d9d1eb500..6d9d1eb500 100644..100755
--- a/indra/newview/llfloaterscriptdebug.h
+++ b/indra/newview/llfloaterscriptdebug.h
diff --git a/indra/newview/llfloaterscriptlimits.cpp b/indra/newview/llfloaterscriptlimits.cpp
index a50907601c..13cb3c2eb0 100644..100755
--- a/indra/newview/llfloaterscriptlimits.cpp
+++ b/indra/newview/llfloaterscriptlimits.cpp
@@ -221,9 +221,9 @@ void fetchScriptLimitsRegionInfoResponder::result(const LLSD& content)
}
}
-void fetchScriptLimitsRegionInfoResponder::error(U32 status, const std::string& reason)
+void fetchScriptLimitsRegionInfoResponder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)
{
- llwarns << "Error from responder " << reason << llendl;
+ llwarns << "fetchScriptLimitsRegionInfoResponder error [status:" << status << "]: " << content << llendl;
}
void fetchScriptLimitsRegionSummaryResponder::result(const LLSD& content_ref)
@@ -308,9 +308,9 @@ void fetchScriptLimitsRegionSummaryResponder::result(const LLSD& content_ref)
}
}
-void fetchScriptLimitsRegionSummaryResponder::error(U32 status, const std::string& reason)
+void fetchScriptLimitsRegionSummaryResponder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)
{
- llwarns << "Error from responder " << reason << llendl;
+ llwarns << "fetchScriptLimitsRegionSummaryResponder error [status:" << status << "]: " << content << llendl;
}
void fetchScriptLimitsRegionDetailsResponder::result(const LLSD& content_ref)
@@ -417,9 +417,9 @@ result (map)
}
}
-void fetchScriptLimitsRegionDetailsResponder::error(U32 status, const std::string& reason)
+void fetchScriptLimitsRegionDetailsResponder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)
{
- llwarns << "Error from responder " << reason << llendl;
+ llwarns << "fetchScriptLimitsRegionDetailsResponder error [status:" << status << "]: " << content << llendl;
}
void fetchScriptLimitsAttachmentInfoResponder::result(const LLSD& content_ref)
@@ -513,9 +513,9 @@ void fetchScriptLimitsAttachmentInfoResponder::result(const LLSD& content_ref)
}
}
-void fetchScriptLimitsAttachmentInfoResponder::error(U32 status, const std::string& reason)
+void fetchScriptLimitsAttachmentInfoResponder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)
{
- llwarns << "Error from responder " << reason << llendl;
+ llwarns << "fetchScriptLimitsAttachmentInfoResponder error [status:" << status << "]: " << content << llendl;
}
///----------------------------------------------------------------------------
@@ -602,15 +602,7 @@ void LLPanelScriptLimitsRegionMemory::onNameCache(
return;
}
- std::string name;
- if (LLAvatarNameCache::useDisplayNames())
- {
- name = LLCacheName::buildUsername(full_name);
- }
- else
- {
- name = full_name;
- }
+ std::string name = LLCacheName::buildUsername(full_name);
std::vector<LLSD>::iterator id_itor;
for (id_itor = mObjectListItems.begin(); id_itor != mObjectListItems.end(); ++id_itor)
@@ -713,10 +705,7 @@ void LLPanelScriptLimitsRegionMemory::setRegionDetails(LLSD content)
else
{
name_is_cached = gCacheName->getFullName(owner_id, owner_buf); // username
- if (LLAvatarNameCache::useDisplayNames())
- {
- owner_buf = LLCacheName::buildUsername(owner_buf);
- }
+ owner_buf = LLCacheName::buildUsername(owner_buf);
}
if(!name_is_cached)
{
diff --git a/indra/newview/llfloaterscriptlimits.h b/indra/newview/llfloaterscriptlimits.h
index 9bcfa5fe14..f8732ef94b 100644..100755
--- a/indra/newview/llfloaterscriptlimits.h
+++ b/indra/newview/llfloaterscriptlimits.h
@@ -89,7 +89,7 @@ class fetchScriptLimitsRegionInfoResponder: public LLHTTPClient::Responder
fetchScriptLimitsRegionInfoResponder(const LLSD& info) : mInfo(info) {};
void result(const LLSD& content);
- void error(U32 status, const std::string& reason);
+ void errorWithContent(U32 status, const std::string& reason, const LLSD& content);
public:
protected:
LLSD mInfo;
@@ -101,7 +101,7 @@ class fetchScriptLimitsRegionSummaryResponder: public LLHTTPClient::Responder
fetchScriptLimitsRegionSummaryResponder(const LLSD& info) : mInfo(info) {};
void result(const LLSD& content);
- void error(U32 status, const std::string& reason);
+ void errorWithContent(U32 status, const std::string& reason, const LLSD& content);
public:
protected:
LLSD mInfo;
@@ -113,7 +113,7 @@ class fetchScriptLimitsRegionDetailsResponder: public LLHTTPClient::Responder
fetchScriptLimitsRegionDetailsResponder(const LLSD& info) : mInfo(info) {};
void result(const LLSD& content);
- void error(U32 status, const std::string& reason);
+ void errorWithContent(U32 status, const std::string& reason, const LLSD& content);
public:
protected:
LLSD mInfo;
@@ -125,7 +125,7 @@ class fetchScriptLimitsAttachmentInfoResponder: public LLHTTPClient::Responder
fetchScriptLimitsAttachmentInfoResponder() {};
void result(const LLSD& content);
- void error(U32 status, const std::string& reason);
+ void errorWithContent(U32 status, const std::string& reason, const LLSD& content);
public:
protected:
};
diff --git a/indra/newview/llfloatersearch.cpp b/indra/newview/llfloatersearch.cpp
index 2a946b1edf..2a946b1edf 100644..100755
--- a/indra/newview/llfloatersearch.cpp
+++ b/indra/newview/llfloatersearch.cpp
diff --git a/indra/newview/llfloatersearch.h b/indra/newview/llfloatersearch.h
index 35b268e1b2..35b268e1b2 100644..100755
--- a/indra/newview/llfloatersearch.h
+++ b/indra/newview/llfloatersearch.h
diff --git a/indra/newview/llfloatersellland.cpp b/indra/newview/llfloatersellland.cpp
index 64c0dfa023..0cb37dabe7 100644..100755
--- a/indra/newview/llfloatersellland.cpp
+++ b/indra/newview/llfloatersellland.cpp
@@ -81,6 +81,7 @@ private:
LLUUID mAuthorizedBuyer;
bool mParcelSoldWithObjects;
SelectionObserver mParcelSelectionObserver;
+ boost::signals2::connection mAvatarNameCacheConnection;
void updateParcelInfo();
void refreshUI();
@@ -129,13 +130,18 @@ LLFloater* LLFloaterSellLand::buildFloater(const LLSD& key)
LLFloaterSellLandUI::LLFloaterSellLandUI(const LLSD& key)
: LLFloater(key),
mParcelSelectionObserver(this),
- mRegion(0)
+ mRegion(0),
+ mAvatarNameCacheConnection()
{
LLViewerParcelMgr::getInstance()->addObserver(&mParcelSelectionObserver);
}
LLFloaterSellLandUI::~LLFloaterSellLandUI()
{
+ if (mAvatarNameCacheConnection.connected())
+ {
+ mAvatarNameCacheConnection.disconnect();
+ }
LLViewerParcelMgr::getInstance()->removeObserver(&mParcelSelectionObserver);
}
@@ -230,15 +236,20 @@ void LLFloaterSellLandUI::updateParcelInfo()
if(mSellToBuyer)
{
- LLAvatarNameCache::get(mAuthorizedBuyer,
- boost::bind(&LLFloaterSellLandUI::onBuyerNameCache, this, _2));
+ if (mAvatarNameCacheConnection.connected())
+ {
+ mAvatarNameCacheConnection.disconnect();
+ }
+ mAvatarNameCacheConnection = LLAvatarNameCache::get(mAuthorizedBuyer, boost::bind(&LLFloaterSellLandUI::onBuyerNameCache, this, _2));
}
}
void LLFloaterSellLandUI::onBuyerNameCache(const LLAvatarName& av_name)
{
+ mAvatarNameCacheConnection.disconnect();
+
getChild<LLUICtrl>("sell_to_agent")->setValue(av_name.getCompleteName());
- getChild<LLUICtrl>("sell_to_agent")->setToolTip(av_name.mUsername);
+ getChild<LLUICtrl>("sell_to_agent")->setToolTip(av_name.getUserName());
}
void LLFloaterSellLandUI::setBadge(const char* id, Badge badge)
@@ -392,7 +403,8 @@ void LLFloaterSellLandUI::onChangeValue(LLUICtrl *ctrl, void *userdata)
void LLFloaterSellLandUI::doSelectAgent()
{
- LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(boost::bind(&LLFloaterSellLandUI::callbackAvatarPick, this, _1, _2), FALSE, TRUE);
+ LLView * button = findChild<LLView>("sell_to_select_agent");
+ LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(boost::bind(&LLFloaterSellLandUI::callbackAvatarPick, this, _1, _2), FALSE, TRUE, FALSE, this->getName(), button);
// grandparent is a floater, in order to set up dependency
if (picker)
{
diff --git a/indra/newview/llfloatersellland.h b/indra/newview/llfloatersellland.h
index 808e2ce4b0..808e2ce4b0 100644..100755
--- a/indra/newview/llfloatersellland.h
+++ b/indra/newview/llfloatersellland.h
diff --git a/indra/newview/llfloatersettingsdebug.cpp b/indra/newview/llfloatersettingsdebug.cpp
index 07f5220ab7..07f5220ab7 100644..100755
--- a/indra/newview/llfloatersettingsdebug.cpp
+++ b/indra/newview/llfloatersettingsdebug.cpp
diff --git a/indra/newview/llfloatersettingsdebug.h b/indra/newview/llfloatersettingsdebug.h
index f07e0557e3..f07e0557e3 100644..100755
--- a/indra/newview/llfloatersettingsdebug.h
+++ b/indra/newview/llfloatersettingsdebug.h
diff --git a/indra/newview/llfloatersidepanelcontainer.cpp b/indra/newview/llfloatersidepanelcontainer.cpp
index 5385977d95..c5248719e9 100644..100755
--- a/indra/newview/llfloatersidepanelcontainer.cpp
+++ b/indra/newview/llfloatersidepanelcontainer.cpp
@@ -28,10 +28,13 @@
#include "llfloaterreg.h"
#include "llfloatersidepanelcontainer.h"
+#include "llpaneleditwearable.h"
// newview includes
#include "llsidetraypanelcontainer.h"
#include "lltransientfloatermgr.h"
+#include "llpaneloutfitedit.h"
+#include "llsidepanelappearance.h"
//static
const std::string LLFloaterSidePanelContainer::sMainPanelName("main_panel");
@@ -54,6 +57,27 @@ void LLFloaterSidePanelContainer::onOpen(const LLSD& key)
getChild<LLPanel>(sMainPanelName)->onOpen(key);
}
+void LLFloaterSidePanelContainer::onClickCloseBtn(bool)
+{
+ LLPanelOutfitEdit* panel_outfit_edit =
+ dynamic_cast<LLPanelOutfitEdit*>(LLFloaterSidePanelContainer::getPanel("appearance", "panel_outfit_edit"));
+ if (panel_outfit_edit)
+ {
+ LLFloater *parent = gFloaterView->getParentFloater(panel_outfit_edit);
+ if (parent == this )
+ {
+ LLSidepanelAppearance* panel_appearance = dynamic_cast<LLSidepanelAppearance*>(getPanel("appearance"));
+ if ( panel_appearance )
+ {
+ panel_appearance->getWearable()->onClose();
+ panel_appearance->showOutfitsInventoryPanel();
+ }
+ }
+ }
+
+ LLFloater::onClickCloseBtn();
+}
+
LLPanel* LLFloaterSidePanelContainer::openChildPanel(const std::string& panel_name, const LLSD& params)
{
LLView* view = findChildView(panel_name, true);
@@ -61,7 +85,7 @@ LLPanel* LLFloaterSidePanelContainer::openChildPanel(const std::string& panel_na
if (!getVisible())
{
- openFloater();
+ openFloater();
}
LLPanel* panel = NULL;
@@ -69,10 +93,7 @@ LLPanel* LLFloaterSidePanelContainer::openChildPanel(const std::string& panel_na
LLSideTrayPanelContainer* container = dynamic_cast<LLSideTrayPanelContainer*>(view->getParent());
if (container)
{
- LLSD new_params = params;
- new_params[LLSideTrayPanelContainer::PARAM_SUB_PANEL_NAME] = panel_name;
- container->onOpen(new_params);
-
+ container->openPanel(panel_name, params);
panel = container->getCurrentPanel();
}
else if ((panel = dynamic_cast<LLPanel*>(view)) != NULL)
diff --git a/indra/newview/llfloatersidepanelcontainer.h b/indra/newview/llfloatersidepanelcontainer.h
index 10d85867ce..65ec8f604e 100644..100755
--- a/indra/newview/llfloatersidepanelcontainer.h
+++ b/indra/newview/llfloatersidepanelcontainer.h
@@ -51,6 +51,8 @@ public:
/*virtual*/ void onOpen(const LLSD& key);
+ /*virtual*/ void onClickCloseBtn(bool app_quitting = false);
+
LLPanel* openChildPanel(const std::string& panel_name, const LLSD& params);
static void showPanel(const std::string& floater_name, const LLSD& key);
diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp
index 1d429c5963..ea385d7baf 100644..100755
--- a/indra/newview/llfloatersnapshot.cpp
+++ b/indra/newview/llfloatersnapshot.cpp
@@ -28,60 +28,23 @@
#include "llfloatersnapshot.h"
-#include "llfloaterreg.h"
-
-// Viewer includes
#include "llagent.h"
-#include "llagentcamera.h"
-#include "llcallbacklist.h"
-#include "llcriticaldamp.h"
-#include "llfloaterperms.h"
-#include "llui.h"
-#include "llfocusmgr.h"
-#include "llbutton.h"
+#include "llfacebookconnect.h"
+#include "llfloaterreg.h"
+#include "llfloatersocial.h"
+#include "llcheckboxctrl.h"
#include "llcombobox.h"
-#include "lleconomy.h"
-#include "lllandmarkactions.h"
-#include "llpanelsnapshot.h"
+#include "llpostcard.h"
+#include "llresmgr.h" // LLLocale
+#include "llsdserialize.h"
#include "llsidetraypanelcontainer.h"
-#include "llsliderctrl.h"
+#include "llsnapshotlivepreview.h"
#include "llspinctrl.h"
#include "llviewercontrol.h"
-#include "lluictrlfactory.h"
-#include "llviewerstats.h"
-#include "llviewercamera.h"
-#include "llviewerwindow.h"
-#include "llviewermenufile.h" // upload_new_resource()
-#include "llcheckboxctrl.h"
-#include "llslurl.h"
#include "lltoolfocus.h"
#include "lltoolmgr.h"
-#include "llwebsharing.h"
-#include "llworld.h"
-#include "llagentui.h"
-
-// Linden library includes
-#include "llfontgl.h"
-#include "llsys.h"
-#include "llrender.h"
-#include "v3dmath.h"
-#include "llmath.h"
-#include "lldir.h"
-#include "llsdserialize.h"
-#include "llgl.h"
-#include "llglheaders.h"
-#include "llimagejpeg.h"
-#include "llimagepng.h"
-#include "llimagebmp.h"
-#include "llimagej2c.h"
-#include "lllocalcliprect.h"
-#include "llnotificationsutil.h"
-#include "llpostcard.h"
-#include "llresmgr.h" // LLLocale
-#include "llvfile.h"
-#include "llvfs.h"
#include "llwebprofile.h"
-#include "llwindow.h"
+#include "llwebsharing.h"
///----------------------------------------------------------------------------
/// Local function declarations, constants, enums, and typedefs
@@ -91,949 +54,12 @@ LLSnapshotFloaterView* gSnapshotFloaterView = NULL;
const F32 AUTO_SNAPSHOT_TIME_DELAY = 1.f;
-F32 SHINE_TIME = 0.5f;
-F32 SHINE_WIDTH = 0.6f;
-F32 SHINE_OPACITY = 0.3f;
-F32 FALL_TIME = 0.6f;
-S32 BORDER_WIDTH = 6;
-
const S32 MAX_POSTCARD_DATASIZE = 1024 * 1024; // one megabyte
const S32 MAX_TEXTURE_SIZE = 512 ; //max upload texture size 512 * 512
static LLDefaultChildRegistry::Register<LLSnapshotFloaterView> r("snapshot_floater_view");
-///----------------------------------------------------------------------------
-/// Class LLSnapshotLivePreview
-///----------------------------------------------------------------------------
-class LLSnapshotLivePreview : public LLView
-{
- LOG_CLASS(LLSnapshotLivePreview);
-public:
- enum ESnapshotType
- {
- SNAPSHOT_POSTCARD,
- SNAPSHOT_TEXTURE,
- SNAPSHOT_LOCAL,
- SNAPSHOT_WEB
- };
-
-
- struct Params : public LLInitParam::Block<Params, LLView::Params>
- {
- Params()
- {
- name = "snapshot_live_preview";
- mouse_opaque = false;
- }
- };
-
-
- LLSnapshotLivePreview(const LLSnapshotLivePreview::Params& p);
- ~LLSnapshotLivePreview();
-
- /*virtual*/ void draw();
- /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent);
-
- void setSize(S32 w, S32 h);
- void setWidth(S32 w) { mWidth[mCurImageIndex] = w; }
- void setHeight(S32 h) { mHeight[mCurImageIndex] = h; }
- void getSize(S32& w, S32& h) const;
- S32 getWidth() const { return mWidth[mCurImageIndex]; }
- S32 getHeight() const { return mHeight[mCurImageIndex]; }
- S32 getDataSize() const { return mDataSize; }
- void setMaxImageSize(S32 size) ;
- S32 getMaxImageSize() {return mMaxImageSize ;}
-
- ESnapshotType getSnapshotType() const { return mSnapshotType; }
- LLFloaterSnapshot::ESnapshotFormat getSnapshotFormat() const { return mSnapshotFormat; }
- BOOL getSnapshotUpToDate() const { return mSnapshotUpToDate; }
- BOOL isSnapshotActive() { return mSnapshotActive; }
- LLViewerTexture* getThumbnailImage() const { return mThumbnailImage ; }
- S32 getThumbnailWidth() const { return mThumbnailWidth ; }
- S32 getThumbnailHeight() const { return mThumbnailHeight ; }
- BOOL getThumbnailLock() const { return mThumbnailUpdateLock ; }
- BOOL getThumbnailUpToDate() const { return mThumbnailUpToDate ;}
- LLViewerTexture* getCurrentImage();
- F32 getImageAspect();
- F32 getAspect() ;
- const LLRect& getImageRect() const { return mImageRect[mCurImageIndex]; }
- BOOL isImageScaled() const { return mImageScaled[mCurImageIndex]; }
- void setImageScaled(BOOL scaled) { mImageScaled[mCurImageIndex] = scaled; }
- const LLVector3d& getPosTakenGlobal() const { return mPosTakenGlobal; }
-
- void setSnapshotType(ESnapshotType type) { mSnapshotType = type; }
- void setSnapshotFormat(LLFloaterSnapshot::ESnapshotFormat type) { mSnapshotFormat = type; }
- void setSnapshotQuality(S32 quality);
- void setSnapshotBufferType(LLViewerWindow::ESnapshotType type) { mSnapshotBufferType = type; }
- void updateSnapshot(BOOL new_snapshot, BOOL new_thumbnail = FALSE, F32 delay = 0.f);
- void saveWeb();
- void saveTexture();
- BOOL saveLocal();
-
- LLPointer<LLImageFormatted> getFormattedImage() const { return mFormattedImage; }
- LLPointer<LLImageRaw> getEncodedImage() const { return mPreviewImageEncoded; }
-
- /// Sets size of preview thumbnail image and thhe surrounding rect.
- BOOL setThumbnailImageSize() ;
- void generateThumbnailImage(BOOL force_update = FALSE) ;
- void resetThumbnailImage() { mThumbnailImage = NULL ; }
- void drawPreviewRect(S32 offset_x, S32 offset_y) ;
-
- // Returns TRUE when snapshot generated, FALSE otherwise.
- static BOOL onIdle( void* snapshot_preview );
-
- // callback for region name resolve
- void regionNameCallback(LLImageJPEG* snapshot, LLSD& metadata, const std::string& name, S32 x, S32 y, S32 z);
-
-private:
- LLColor4 mColor;
- LLPointer<LLViewerTexture> mViewerImage[2]; //used to represent the scene when the frame is frozen.
- LLRect mImageRect[2];
- S32 mWidth[2];
- S32 mHeight[2];
- BOOL mImageScaled[2];
- S32 mMaxImageSize ;
-
- //thumbnail image
- LLPointer<LLViewerTexture> mThumbnailImage ;
- S32 mThumbnailWidth ;
- S32 mThumbnailHeight ;
- LLRect mPreviewRect ;
- BOOL mThumbnailUpdateLock ;
- BOOL mThumbnailUpToDate ;
-
- S32 mCurImageIndex;
- LLPointer<LLImageRaw> mPreviewImage;
- LLPointer<LLImageRaw> mPreviewImageEncoded;
- LLPointer<LLImageFormatted> mFormattedImage;
- LLFrameTimer mSnapshotDelayTimer;
- S32 mShineCountdown;
- LLFrameTimer mShineAnimTimer;
- F32 mFlashAlpha;
- BOOL mNeedsFlash;
- LLVector3d mPosTakenGlobal;
- S32 mSnapshotQuality;
- S32 mDataSize;
- ESnapshotType mSnapshotType;
- LLFloaterSnapshot::ESnapshotFormat mSnapshotFormat;
- BOOL mSnapshotUpToDate;
- LLFrameTimer mFallAnimTimer;
- LLVector3 mCameraPos;
- LLQuaternion mCameraRot;
- BOOL mSnapshotActive;
- LLViewerWindow::ESnapshotType mSnapshotBufferType;
-
-public:
- static std::set<LLSnapshotLivePreview*> sList;
- BOOL mKeepAspectRatio ;
-};
-
-std::set<LLSnapshotLivePreview*> LLSnapshotLivePreview::sList;
-
-LLSnapshotLivePreview::LLSnapshotLivePreview (const LLSnapshotLivePreview::Params& p)
-: LLView(p),
- mColor(1.f, 0.f, 0.f, 0.5f),
- mCurImageIndex(0),
- mPreviewImage(NULL),
- mThumbnailImage(NULL) ,
- mThumbnailWidth(0),
- mThumbnailHeight(0),
- mPreviewImageEncoded(NULL),
- mFormattedImage(NULL),
- mShineCountdown(0),
- mFlashAlpha(0.f),
- mNeedsFlash(TRUE),
- mSnapshotQuality(gSavedSettings.getS32("SnapshotQuality")),
- mDataSize(0),
- mSnapshotType(SNAPSHOT_POSTCARD),
- mSnapshotFormat(LLFloaterSnapshot::ESnapshotFormat(gSavedSettings.getS32("SnapshotFormat"))),
- mSnapshotUpToDate(FALSE),
- mCameraPos(LLViewerCamera::getInstance()->getOrigin()),
- mCameraRot(LLViewerCamera::getInstance()->getQuaternion()),
- mSnapshotActive(FALSE),
- mSnapshotBufferType(LLViewerWindow::SNAPSHOT_TYPE_COLOR)
-{
- setSnapshotQuality(gSavedSettings.getS32("SnapshotQuality"));
- mSnapshotDelayTimer.setTimerExpirySec(0.0f);
- mSnapshotDelayTimer.start();
-// gIdleCallbacks.addFunction( &LLSnapshotLivePreview::onIdle, (void*)this );
- sList.insert(this);
- setFollowsAll();
- mWidth[0] = gViewerWindow->getWindowWidthRaw();
- mWidth[1] = gViewerWindow->getWindowWidthRaw();
- mHeight[0] = gViewerWindow->getWindowHeightRaw();
- mHeight[1] = gViewerWindow->getWindowHeightRaw();
- mImageScaled[0] = FALSE;
- mImageScaled[1] = FALSE;
-
- mMaxImageSize = MAX_SNAPSHOT_IMAGE_SIZE ;
- mKeepAspectRatio = gSavedSettings.getBOOL("KeepAspectForSnapshot") ;
- mThumbnailUpdateLock = FALSE ;
- mThumbnailUpToDate = FALSE ;
-}
-
-LLSnapshotLivePreview::~LLSnapshotLivePreview()
-{
- // delete images
- mPreviewImage = NULL;
- mPreviewImageEncoded = NULL;
- mFormattedImage = NULL;
-
-// gIdleCallbacks.deleteFunction( &LLSnapshotLivePreview::onIdle, (void*)this );
- sList.erase(this);
-}
-
-void LLSnapshotLivePreview::setMaxImageSize(S32 size)
-{
- if(size < MAX_SNAPSHOT_IMAGE_SIZE)
- {
- mMaxImageSize = size;
- }
- else
- {
- mMaxImageSize = MAX_SNAPSHOT_IMAGE_SIZE ;
- }
-}
-
-LLViewerTexture* LLSnapshotLivePreview::getCurrentImage()
-{
- return mViewerImage[mCurImageIndex];
-}
-
-F32 LLSnapshotLivePreview::getAspect()
-{
- F32 image_aspect_ratio = ((F32)getWidth()) / ((F32)getHeight());
- F32 window_aspect_ratio = ((F32)getRect().getWidth()) / ((F32)getRect().getHeight());
-
- if (!mKeepAspectRatio)//gSavedSettings.getBOOL("KeepAspectForSnapshot"))
- {
- return image_aspect_ratio;
- }
- else
- {
- return window_aspect_ratio;
- }
-}
-
-F32 LLSnapshotLivePreview::getImageAspect()
-{
- if (!getCurrentImage())
- {
- return 0.f;
- }
-
- return getAspect() ;
-}
-
-void LLSnapshotLivePreview::updateSnapshot(BOOL new_snapshot, BOOL new_thumbnail, F32 delay)
-{
- // Invalidate current image.
- lldebugs << "updateSnapshot: mSnapshotUpToDate = " << getSnapshotUpToDate() << llendl;
- if (getSnapshotUpToDate())
- {
- S32 old_image_index = mCurImageIndex;
- mCurImageIndex = (mCurImageIndex + 1) % 2;
- setSize(mWidth[old_image_index], mHeight[old_image_index]);
- mFallAnimTimer.start();
- }
- mSnapshotUpToDate = FALSE;
-
- // Update snapshot source rect depending on whether we keep the aspect ratio.
- LLRect& rect = mImageRect[mCurImageIndex];
- rect.set(0, getRect().getHeight(), getRect().getWidth(), 0);
-
- F32 image_aspect_ratio = ((F32)getWidth()) / ((F32)getHeight());
- F32 window_aspect_ratio = ((F32)getRect().getWidth()) / ((F32)getRect().getHeight());
-
- if (mKeepAspectRatio)//gSavedSettings.getBOOL("KeepAspectForSnapshot"))
- {
- if (image_aspect_ratio > window_aspect_ratio)
- {
- // trim off top and bottom
- S32 new_height = llround((F32)getRect().getWidth() / image_aspect_ratio);
- rect.mBottom += (getRect().getHeight() - new_height) / 2;
- rect.mTop -= (getRect().getHeight() - new_height) / 2;
- }
- else if (image_aspect_ratio < window_aspect_ratio)
- {
- // trim off left and right
- S32 new_width = llround((F32)getRect().getHeight() * image_aspect_ratio);
- rect.mLeft += (getRect().getWidth() - new_width) / 2;
- rect.mRight -= (getRect().getWidth() - new_width) / 2;
- }
- }
-
- // Stop shining animation.
- mShineAnimTimer.stop();
-
- // Update snapshot if requested.
- if (new_snapshot)
- {
- mSnapshotDelayTimer.start();
- mSnapshotDelayTimer.setTimerExpirySec(delay);
- LLFloaterSnapshot::preUpdate();
- }
-
- // Update thumbnail if requested.
- if(new_thumbnail)
- {
- mThumbnailUpToDate = FALSE ;
- }
-}
-
-void LLSnapshotLivePreview::setSnapshotQuality(S32 quality)
-{
- llclamp(quality, 0, 100);
- if (quality != mSnapshotQuality)
- {
- mSnapshotQuality = quality;
- gSavedSettings.setS32("SnapshotQuality", quality);
- mSnapshotUpToDate = FALSE;
- }
-}
-
-void LLSnapshotLivePreview::drawPreviewRect(S32 offset_x, S32 offset_y)
-{
- F32 line_width ;
- glGetFloatv(GL_LINE_WIDTH, &line_width) ;
- glLineWidth(2.0f * line_width) ;
- LLColor4 color(0.0f, 0.0f, 0.0f, 1.0f) ;
- gl_rect_2d( mPreviewRect.mLeft + offset_x, mPreviewRect.mTop + offset_y,
- mPreviewRect.mRight + offset_x, mPreviewRect.mBottom + offset_y, color, FALSE ) ;
- glLineWidth(line_width) ;
-
- //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())
- {
- dwl = (mThumbnailWidth - mPreviewRect.getWidth()) >> 1 ;
- dwr = mThumbnailWidth - mPreviewRect.getWidth() - dwl ;
-
- gl_rect_2d(mPreviewRect.mLeft + offset_x - dwl, mPreviewRect.mTop + offset_y,
- mPreviewRect.mLeft + offset_x, mPreviewRect.mBottom + offset_y, alpha_color, TRUE ) ;
- gl_rect_2d( mPreviewRect.mRight + offset_x, mPreviewRect.mTop + offset_y,
- mPreviewRect.mRight + offset_x + dwr, mPreviewRect.mBottom + offset_y, alpha_color, TRUE ) ;
- }
-
- if(mThumbnailHeight > mPreviewRect.getHeight())
- {
- S32 dh = (mThumbnailHeight - mPreviewRect.getHeight()) >> 1 ;
- gl_rect_2d(mPreviewRect.mLeft + offset_x - dwl, mPreviewRect.mBottom + offset_y ,
- mPreviewRect.mRight + offset_x + dwr, mPreviewRect.mBottom + offset_y - dh, alpha_color, TRUE ) ;
-
- dh = mThumbnailHeight - mPreviewRect.getHeight() - dh ;
- gl_rect_2d( mPreviewRect.mLeft + offset_x - dwl, mPreviewRect.mTop + offset_y + dh,
- mPreviewRect.mRight + offset_x + dwr, mPreviewRect.mTop + offset_y, alpha_color, TRUE ) ;
- }
- }
-}
-
-//called when the frame is frozen.
-void LLSnapshotLivePreview::draw()
-{
- if (getCurrentImage() &&
- mPreviewImageEncoded.notNull() &&
- getSnapshotUpToDate())
- {
- LLColor4 bg_color(0.f, 0.f, 0.3f, 0.4f);
- gl_rect_2d(getRect(), bg_color);
- const LLRect& rect = getImageRect();
- LLRect shadow_rect = rect;
- shadow_rect.stretch(BORDER_WIDTH);
- gl_drop_shadow(shadow_rect.mLeft, shadow_rect.mTop, shadow_rect.mRight, shadow_rect.mBottom, LLColor4(0.f, 0.f, 0.f, mNeedsFlash ? 0.f :0.5f), 10);
-
- LLColor4 image_color(1.f, 1.f, 1.f, 1.f);
- gGL.color4fv(image_color.mV);
- gGL.getTexUnit(0)->bind(getCurrentImage());
- // calculate UV scale
- F32 uv_width = isImageScaled() ? 1.f : llmin((F32)getWidth() / (F32)getCurrentImage()->getWidth(), 1.f);
- F32 uv_height = isImageScaled() ? 1.f : llmin((F32)getHeight() / (F32)getCurrentImage()->getHeight(), 1.f);
- gGL.pushMatrix();
- {
- gGL.translatef((F32)rect.mLeft, (F32)rect.mBottom, 0.f);
- gGL.begin(LLRender::QUADS);
- {
- gGL.texCoord2f(uv_width, uv_height);
- gGL.vertex2i(rect.getWidth(), rect.getHeight() );
-
- gGL.texCoord2f(0.f, uv_height);
- gGL.vertex2i(0, rect.getHeight() );
-
- gGL.texCoord2f(0.f, 0.f);
- gGL.vertex2i(0, 0);
-
- gGL.texCoord2f(uv_width, 0.f);
- gGL.vertex2i(rect.getWidth(), 0);
- }
- gGL.end();
- }
- gGL.popMatrix();
-
- gGL.color4f(1.f, 1.f, 1.f, mFlashAlpha);
- gl_rect_2d(getRect());
- if (mNeedsFlash)
- {
- if (mFlashAlpha < 1.f)
- {
- mFlashAlpha = lerp(mFlashAlpha, 1.f, LLCriticalDamp::getInterpolant(0.02f));
- }
- else
- {
- mNeedsFlash = FALSE;
- }
- }
- else
- {
- mFlashAlpha = lerp(mFlashAlpha, 0.f, LLCriticalDamp::getInterpolant(0.15f));
- }
-
- // Draw shining animation if appropriate.
- if (mShineCountdown > 0)
- {
- mShineCountdown--;
- if (mShineCountdown == 0)
- {
- mShineAnimTimer.start();
- }
- }
- else if (mShineAnimTimer.getStarted())
- {
- lldebugs << "Drawing shining animation" << llendl;
- F32 shine_interp = llmin(1.f, mShineAnimTimer.getElapsedTimeF32() / SHINE_TIME);
-
- // draw "shine" effect
- LLLocalClipRect clip(getLocalRect());
- {
- // draw diagonal stripe with gradient that passes over screen
- S32 x1 = gViewerWindow->getWindowWidthScaled() * llround((clamp_rescale(shine_interp, 0.f, 1.f, -1.f - SHINE_WIDTH, 1.f)));
- S32 x2 = x1 + llround(gViewerWindow->getWindowWidthScaled() * SHINE_WIDTH);
- S32 x3 = x2 + llround(gViewerWindow->getWindowWidthScaled() * SHINE_WIDTH);
- S32 y1 = 0;
- S32 y2 = gViewerWindow->getWindowHeightScaled();
-
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.begin(LLRender::QUADS);
- {
- gGL.color4f(1.f, 1.f, 1.f, 0.f);
- gGL.vertex2i(x1, y1);
- gGL.vertex2i(x1 + gViewerWindow->getWindowWidthScaled(), y2);
- gGL.color4f(1.f, 1.f, 1.f, SHINE_OPACITY);
- gGL.vertex2i(x2 + gViewerWindow->getWindowWidthScaled(), y2);
- gGL.vertex2i(x2, y1);
-
- gGL.color4f(1.f, 1.f, 1.f, SHINE_OPACITY);
- gGL.vertex2i(x2, y1);
- gGL.vertex2i(x2 + gViewerWindow->getWindowWidthScaled(), y2);
- gGL.color4f(1.f, 1.f, 1.f, 0.f);
- gGL.vertex2i(x3 + gViewerWindow->getWindowWidthScaled(), y2);
- gGL.vertex2i(x3, y1);
- }
- gGL.end();
- }
-
- // if we're at the end of the animation, stop
- if (shine_interp >= 1.f)
- {
- mShineAnimTimer.stop();
- }
- }
- }
-
- // draw framing rectangle
- {
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.color4f(1.f, 1.f, 1.f, 1.f);
- const LLRect& outline_rect = getImageRect();
- gGL.begin(LLRender::QUADS);
- {
- gGL.vertex2i(outline_rect.mLeft - BORDER_WIDTH, outline_rect.mTop + BORDER_WIDTH);
- gGL.vertex2i(outline_rect.mRight + BORDER_WIDTH, outline_rect.mTop + BORDER_WIDTH);
- gGL.vertex2i(outline_rect.mRight, outline_rect.mTop);
- gGL.vertex2i(outline_rect.mLeft, outline_rect.mTop);
-
- gGL.vertex2i(outline_rect.mLeft, outline_rect.mBottom);
- gGL.vertex2i(outline_rect.mRight, outline_rect.mBottom);
- gGL.vertex2i(outline_rect.mRight + BORDER_WIDTH, outline_rect.mBottom - BORDER_WIDTH);
- gGL.vertex2i(outline_rect.mLeft - BORDER_WIDTH, outline_rect.mBottom - BORDER_WIDTH);
-
- gGL.vertex2i(outline_rect.mLeft, outline_rect.mTop);
- gGL.vertex2i(outline_rect.mLeft, outline_rect.mBottom);
- gGL.vertex2i(outline_rect.mLeft - BORDER_WIDTH, outline_rect.mBottom - BORDER_WIDTH);
- gGL.vertex2i(outline_rect.mLeft - BORDER_WIDTH, outline_rect.mTop + BORDER_WIDTH);
-
- gGL.vertex2i(outline_rect.mRight, outline_rect.mBottom);
- gGL.vertex2i(outline_rect.mRight, outline_rect.mTop);
- gGL.vertex2i(outline_rect.mRight + BORDER_WIDTH, outline_rect.mTop + BORDER_WIDTH);
- gGL.vertex2i(outline_rect.mRight + BORDER_WIDTH, outline_rect.mBottom - BORDER_WIDTH);
- }
- gGL.end();
- }
-
- // draw old image dropping away
- if (mFallAnimTimer.getStarted())
- {
- S32 old_image_index = (mCurImageIndex + 1) % 2;
- if (mViewerImage[old_image_index].notNull() && mFallAnimTimer.getElapsedTimeF32() < FALL_TIME)
- {
- lldebugs << "Drawing fall animation" << llendl;
- F32 fall_interp = mFallAnimTimer.getElapsedTimeF32() / FALL_TIME;
- F32 alpha = clamp_rescale(fall_interp, 0.f, 1.f, 0.8f, 0.4f);
- LLColor4 image_color(1.f, 1.f, 1.f, alpha);
- gGL.color4fv(image_color.mV);
- gGL.getTexUnit(0)->bind(mViewerImage[old_image_index]);
- // calculate UV scale
- // *FIX get this to work with old image
- BOOL rescale = !mImageScaled[old_image_index] && mViewerImage[mCurImageIndex].notNull();
- F32 uv_width = rescale ? llmin((F32)mWidth[old_image_index] / (F32)mViewerImage[mCurImageIndex]->getWidth(), 1.f) : 1.f;
- F32 uv_height = rescale ? llmin((F32)mHeight[old_image_index] / (F32)mViewerImage[mCurImageIndex]->getHeight(), 1.f) : 1.f;
- gGL.pushMatrix();
- {
- LLRect& rect = mImageRect[old_image_index];
- gGL.translatef((F32)rect.mLeft, (F32)rect.mBottom - llround(getRect().getHeight() * 2.f * (fall_interp * fall_interp)), 0.f);
- gGL.rotatef(-45.f * fall_interp, 0.f, 0.f, 1.f);
- gGL.begin(LLRender::QUADS);
- {
- gGL.texCoord2f(uv_width, uv_height);
- gGL.vertex2i(rect.getWidth(), rect.getHeight() );
-
- gGL.texCoord2f(0.f, uv_height);
- gGL.vertex2i(0, rect.getHeight() );
-
- gGL.texCoord2f(0.f, 0.f);
- gGL.vertex2i(0, 0);
- gGL.texCoord2f(uv_width, 0.f);
- gGL.vertex2i(rect.getWidth(), 0);
- }
- gGL.end();
- }
- gGL.popMatrix();
- }
- }
-}
-
-/*virtual*/
-void LLSnapshotLivePreview::reshape(S32 width, S32 height, BOOL called_from_parent)
-{
- LLRect old_rect = getRect();
- LLView::reshape(width, height, called_from_parent);
- if (old_rect.getWidth() != width || old_rect.getHeight() != height)
- {
- lldebugs << "window reshaped, updating thumbnail" << llendl;
- updateSnapshot(FALSE, TRUE);
- }
-}
-
-BOOL LLSnapshotLivePreview::setThumbnailImageSize()
-{
- if(getWidth() < 10 || getHeight() < 10)
- {
- return FALSE ;
- }
- S32 window_width = gViewerWindow->getWindowWidthRaw() ;
- S32 window_height = gViewerWindow->getWindowHeightRaw() ;
-
- F32 window_aspect_ratio = ((F32)window_width) / ((F32)window_height);
-
- // UI size for thumbnail
- // *FIXME: the rect does not change, so maybe there's no need to recalculate max w/h.
- const LLRect& thumbnail_rect = LLFloaterSnapshot::getThumbnailPlaceholderRect();
- S32 max_width = thumbnail_rect.getWidth();
- S32 max_height = thumbnail_rect.getHeight();
-
- if (window_aspect_ratio > (F32)max_width / max_height)
- {
- // image too wide, shrink to width
- mThumbnailWidth = max_width;
- mThumbnailHeight = llround((F32)max_width / window_aspect_ratio);
- }
- else
- {
- // image too tall, shrink to height
- mThumbnailHeight = max_height;
- mThumbnailWidth = llround((F32)max_height * window_aspect_ratio);
- }
-
- if(mThumbnailWidth > window_width || mThumbnailHeight > window_height)
- {
- return FALSE ;//if the window is too small, ignore thumbnail updating.
- }
-
- S32 left = 0 , top = mThumbnailHeight, right = mThumbnailWidth, bottom = 0 ;
- if(!mKeepAspectRatio)
- {
- F32 ratio_x = (F32)getWidth() / window_width ;
- F32 ratio_y = (F32)getHeight() / window_height ;
-
- //if(getWidth() > window_width ||
- // getHeight() > window_height )
- {
- if(ratio_x > ratio_y)
- {
- top = (S32)(top * ratio_y / ratio_x) ;
- }
- else
- {
- right = (S32)(right * ratio_x / ratio_y) ;
- }
- }
- //else
- //{
- // right = (S32)(right * ratio_x) ;
- // top = (S32)(top * ratio_y) ;
- //}
- left = (S32)((mThumbnailWidth - right) * 0.5f) ;
- bottom = (S32)((mThumbnailHeight - top) * 0.5f) ;
- top += bottom ;
- right += left ;
- }
- mPreviewRect.set(left - 1, top + 1, right + 1, bottom - 1) ;
-
- return TRUE ;
-}
-
-void LLSnapshotLivePreview::generateThumbnailImage(BOOL force_update)
-{
- if(mThumbnailUpdateLock) //in the process of updating
- {
- return ;
- }
- if(getThumbnailUpToDate() && !force_update)//already updated
- {
- return ;
- }
- if(getWidth() < 10 || getHeight() < 10)
- {
- return ;
- }
-
- ////lock updating
- mThumbnailUpdateLock = TRUE ;
-
- if(!setThumbnailImageSize())
- {
- mThumbnailUpdateLock = FALSE ;
- mThumbnailUpToDate = TRUE ;
- return ;
- }
-
- if(mThumbnailImage)
- {
- resetThumbnailImage() ;
- }
-
- LLPointer<LLImageRaw> raw = new LLImageRaw;
- if(!gViewerWindow->thumbnailSnapshot(raw,
- mThumbnailWidth, mThumbnailHeight,
- gSavedSettings.getBOOL("RenderUIInSnapshot"),
- FALSE,
- mSnapshotBufferType) )
- {
- raw = NULL ;
- }
-
- if(raw)
- {
- raw->expandToPowerOfTwo();
- mThumbnailImage = LLViewerTextureManager::getLocalTexture(raw.get(), FALSE);
- mThumbnailUpToDate = TRUE ;
- }
-
- //unlock updating
- mThumbnailUpdateLock = FALSE ;
-}
-
-
-// Called often. Checks whether it's time to grab a new snapshot and if so, does it.
-// Returns TRUE if new snapshot generated, FALSE otherwise.
-//static
-BOOL LLSnapshotLivePreview::onIdle( void* snapshot_preview )
-{
- LLSnapshotLivePreview* previewp = (LLSnapshotLivePreview*)snapshot_preview;
- if (previewp->getWidth() == 0 || previewp->getHeight() == 0)
- {
- llwarns << "Incorrect dimensions: " << previewp->getWidth() << "x" << previewp->getHeight() << llendl;
- return FALSE;
- }
-
- // If we're in freeze-frame mode and camera has moved, update snapshot.
- LLVector3 new_camera_pos = LLViewerCamera::getInstance()->getOrigin();
- LLQuaternion new_camera_rot = LLViewerCamera::getInstance()->getQuaternion();
- if (gSavedSettings.getBOOL("FreezeTime") &&
- (new_camera_pos != previewp->mCameraPos || dot(new_camera_rot, previewp->mCameraRot) < 0.995f))
- {
- previewp->mCameraPos = new_camera_pos;
- previewp->mCameraRot = new_camera_rot;
- // request a new snapshot whenever the camera moves, with a time delay
- BOOL autosnap = gSavedSettings.getBOOL("AutoSnapshot");
- lldebugs << "camera moved, updating thumbnail" << llendl;
- previewp->updateSnapshot(
- autosnap, // whether a new snapshot is needed or merely invalidate the existing one
- FALSE, // or if 1st arg is false, whether to produce a new thumbnail image.
- autosnap ? AUTO_SNAPSHOT_TIME_DELAY : 0.f); // shutter delay if 1st arg is true.
- }
-
- // see if it's time yet to snap the shot and bomb out otherwise.
- previewp->mSnapshotActive =
- (previewp->mSnapshotDelayTimer.getStarted() && previewp->mSnapshotDelayTimer.hasExpired())
- && !LLToolCamera::getInstance()->hasMouseCapture(); // don't take snapshots while ALT-zoom active
- if ( ! previewp->mSnapshotActive)
- {
- return FALSE;
- }
-
- // time to produce a snapshot
- previewp->setThumbnailImageSize();
-
- lldebugs << "producing snapshot" << llendl;
- if (!previewp->mPreviewImage)
- {
- previewp->mPreviewImage = new LLImageRaw;
- }
-
- if (!previewp->mPreviewImageEncoded)
- {
- previewp->mPreviewImageEncoded = new LLImageRaw;
- }
-
- previewp->setVisible(FALSE);
- previewp->setEnabled(FALSE);
-
- previewp->getWindow()->incBusyCount();
- previewp->setImageScaled(FALSE);
-
- // grab the raw image and encode it into desired format
- if(gViewerWindow->rawSnapshot(
- previewp->mPreviewImage,
- previewp->getWidth(),
- previewp->getHeight(),
- previewp->mKeepAspectRatio,//gSavedSettings.getBOOL("KeepAspectForSnapshot"),
- previewp->getSnapshotType() == LLSnapshotLivePreview::SNAPSHOT_TEXTURE,
- gSavedSettings.getBOOL("RenderUIInSnapshot"),
- FALSE,
- previewp->mSnapshotBufferType,
- previewp->getMaxImageSize()))
- {
- previewp->mPreviewImageEncoded->resize(
- previewp->mPreviewImage->getWidth(),
- previewp->mPreviewImage->getHeight(),
- previewp->mPreviewImage->getComponents());
-
- if(previewp->getSnapshotType() == SNAPSHOT_TEXTURE)
- {
- lldebugs << "Encoding new image of format J2C" << llendl;
- LLPointer<LLImageJ2C> formatted = new LLImageJ2C;
- LLPointer<LLImageRaw> scaled = new LLImageRaw(
- previewp->mPreviewImage->getData(),
- previewp->mPreviewImage->getWidth(),
- previewp->mPreviewImage->getHeight(),
- previewp->mPreviewImage->getComponents());
-
- scaled->biasedScaleToPowerOfTwo(MAX_TEXTURE_SIZE);
- previewp->setImageScaled(TRUE);
- if (formatted->encode(scaled, 0.f))
- {
- previewp->mDataSize = formatted->getDataSize();
- formatted->decode(previewp->mPreviewImageEncoded, 0);
- }
- }
- else
- {
- // delete any existing image
- previewp->mFormattedImage = NULL;
- // now create the new one of the appropriate format.
- LLFloaterSnapshot::ESnapshotFormat format = previewp->getSnapshotFormat();
- lldebugs << "Encoding new image of format " << format << llendl;
-
- switch(format)
- {
- case LLFloaterSnapshot::SNAPSHOT_FORMAT_PNG:
- previewp->mFormattedImage = new LLImagePNG();
- break;
- case LLFloaterSnapshot::SNAPSHOT_FORMAT_JPEG:
- previewp->mFormattedImage = new LLImageJPEG(previewp->mSnapshotQuality);
- break;
- case LLFloaterSnapshot::SNAPSHOT_FORMAT_BMP:
- previewp->mFormattedImage = new LLImageBMP();
- break;
- }
- if (previewp->mFormattedImage->encode(previewp->mPreviewImage, 0))
- {
- previewp->mDataSize = previewp->mFormattedImage->getDataSize();
- // special case BMP to copy instead of decode otherwise decode will crash.
- if(format == LLFloaterSnapshot::SNAPSHOT_FORMAT_BMP)
- {
- previewp->mPreviewImageEncoded->copy(previewp->mPreviewImage);
- }
- else
- {
- previewp->mFormattedImage->decode(previewp->mPreviewImageEncoded, 0);
- }
- }
- }
-
- LLPointer<LLImageRaw> scaled = new LLImageRaw(
- previewp->mPreviewImageEncoded->getData(),
- previewp->mPreviewImageEncoded->getWidth(),
- previewp->mPreviewImageEncoded->getHeight(),
- previewp->mPreviewImageEncoded->getComponents());
-
- if(!scaled->isBufferInvalid())
- {
- // leave original image dimensions, just scale up texture buffer
- if (previewp->mPreviewImageEncoded->getWidth() > 1024 || previewp->mPreviewImageEncoded->getHeight() > 1024)
- {
- // go ahead and shrink image to appropriate power of 2 for display
- scaled->biasedScaleToPowerOfTwo(1024);
- previewp->setImageScaled(TRUE);
- }
- else
- {
- // expand image but keep original image data intact
- scaled->expandToPowerOfTwo(1024, FALSE);
- }
-
- previewp->mViewerImage[previewp->mCurImageIndex] = LLViewerTextureManager::getLocalTexture(scaled.get(), FALSE);
- LLPointer<LLViewerTexture> curr_preview_image = previewp->mViewerImage[previewp->mCurImageIndex];
- gGL.getTexUnit(0)->bind(curr_preview_image);
- if (previewp->getSnapshotType() != SNAPSHOT_TEXTURE)
- {
- curr_preview_image->setFilteringOption(LLTexUnit::TFO_POINT);
- }
- else
- {
- curr_preview_image->setFilteringOption(LLTexUnit::TFO_ANISOTROPIC);
- }
- curr_preview_image->setAddressMode(LLTexUnit::TAM_CLAMP);
-
- previewp->mSnapshotUpToDate = TRUE;
- previewp->generateThumbnailImage(TRUE) ;
-
- previewp->mPosTakenGlobal = gAgentCamera.getCameraPositionGlobal();
- previewp->mShineCountdown = 4; // wait a few frames to avoid animation glitch due to readback this frame
- }
- }
- previewp->getWindow()->decBusyCount();
- // only show fullscreen preview when in freeze frame mode
- previewp->setVisible(gSavedSettings.getBOOL("UseFreezeFrame"));
- previewp->mSnapshotDelayTimer.stop();
- previewp->mSnapshotActive = FALSE;
-
- if(!previewp->getThumbnailUpToDate())
- {
- previewp->generateThumbnailImage() ;
- }
- lldebugs << "done creating snapshot" << llendl;
- LLFloaterSnapshot::postUpdate();
-
- return TRUE;
-}
-
-void LLSnapshotLivePreview::setSize(S32 w, S32 h)
-{
- lldebugs << "setSize(" << w << ", " << h << ")" << llendl;
- setWidth(w);
- setHeight(h);
-}
-
-void LLSnapshotLivePreview::getSize(S32& w, S32& h) const
-{
- w = getWidth();
- h = getHeight();
-}
-
-void LLSnapshotLivePreview::saveTexture()
-{
- lldebugs << "saving texture: " << mPreviewImage->getWidth() << "x" << mPreviewImage->getHeight() << llendl;
- // gen a new uuid for this asset
- LLTransactionID tid;
- tid.generate();
- LLAssetID new_asset_id = tid.makeAssetID(gAgent.getSecureSessionID());
-
- LLPointer<LLImageJ2C> formatted = new LLImageJ2C;
- LLPointer<LLImageRaw> scaled = new LLImageRaw(mPreviewImage->getData(),
- mPreviewImage->getWidth(),
- mPreviewImage->getHeight(),
- mPreviewImage->getComponents());
-
- scaled->biasedScaleToPowerOfTwo(MAX_TEXTURE_SIZE);
- lldebugs << "scaled texture to " << scaled->getWidth() << "x" << scaled->getHeight() << llendl;
-
- if (formatted->encode(scaled, 0.0f))
- {
- LLVFile::writeFile(formatted->getData(), formatted->getDataSize(), gVFS, new_asset_id, LLAssetType::AT_TEXTURE);
- std::string pos_string;
- LLAgentUI::buildLocationString(pos_string, LLAgentUI::LOCATION_FORMAT_FULL);
- std::string who_took_it;
- LLAgentUI::buildFullname(who_took_it);
- LLAssetStorage::LLStoreAssetCallback callback = NULL;
- S32 expected_upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload();
- void *userdata = NULL;
- upload_new_resource(tid, // tid
- LLAssetType::AT_TEXTURE,
- "Snapshot : " + pos_string,
- "Taken by " + who_took_it + " at " + pos_string,
- 0,
- LLFolderType::FT_SNAPSHOT_CATEGORY,
- LLInventoryType::IT_SNAPSHOT,
- PERM_ALL, // Note: Snapshots to inventory is a special case of content upload
- LLFloaterPerms::getGroupPerms("Uploads"), // that is more permissive than other uploads
- LLFloaterPerms::getEveryonePerms("Uploads"),
- "Snapshot : " + pos_string,
- callback, expected_upload_cost, userdata);
- gViewerWindow->playSnapshotAnimAndSound();
- }
- else
- {
- LLNotificationsUtil::add("ErrorEncodingSnapshot");
- llwarns << "Error encoding snapshot" << llendl;
- }
-
- LLViewerStats::getInstance()->incStat(LLViewerStats::ST_SNAPSHOT_COUNT );
-
- mDataSize = 0;
-}
-
-BOOL LLSnapshotLivePreview::saveLocal()
-{
- BOOL success = gViewerWindow->saveImageNumbered(mFormattedImage);
-
- if(success)
- {
- gViewerWindow->playSnapshotAnimAndSound();
- }
- return success;
-}
-
-void LLSnapshotLivePreview::saveWeb()
-{
- // *FIX: Will break if the window closes because of CloseSnapshotOnKeep!
- // Needs to pass on ownership of the image.
- LLImageJPEG* jpg = dynamic_cast<LLImageJPEG*>(mFormattedImage.get());
- if(!jpg)
- {
- llwarns << "Formatted image not a JPEG" << llendl;
- return;
- }
-
- LLSD metadata;
- metadata["description"] = getChild<LLLineEditor>("description")->getText();
-
- LLLandmarkActions::getRegionNameAndCoordsFromPosGlobal(gAgentCamera.getCameraPositionGlobal(),
- boost::bind(&LLSnapshotLivePreview::regionNameCallback, this, jpg, metadata, _1, _2, _3, _4));
-
- gViewerWindow->playSnapshotAnimAndSound();
-}
-
-void LLSnapshotLivePreview::regionNameCallback(LLImageJPEG* snapshot, LLSD& metadata, const std::string& name, S32 x, S32 y, S32 z)
-{
- metadata["slurl"] = LLSLURL(name, LLVector3d(x, y, z)).getSLURLString();
-
- LLWebSharing::instance().shareSnapshot(snapshot, metadata);
-}
///----------------------------------------------------------------------------
/// Class LLFloaterSnapshot::Impl
@@ -2037,7 +1063,7 @@ BOOL LLFloaterSnapshot::postBuild()
getChild<LLUICtrl>("auto_snapshot_check")->setValue(gSavedSettings.getBOOL("AutoSnapshot"));
childSetCommitCallback("auto_snapshot_check", Impl::onClickAutoSnap, this);
-
+
LLWebProfile::setImageUploadResultCallback(boost::bind(&LLFloaterSnapshot::Impl::onSnapshotUploadFinished, _1));
LLPostCard::setPostResultCallback(boost::bind(&LLFloaterSnapshot::Impl::onSendingPostcardFinished, _1));
@@ -2070,6 +1096,9 @@ BOOL LLFloaterSnapshot::postBuild()
impl.updateControls(this);
impl.updateLayout(this);
+
+ previewp->setThumbnailPlaceholderRect(getThumbnailPlaceholderRect());
+
return TRUE;
}
@@ -2235,7 +1264,9 @@ S32 LLFloaterSnapshot::notify(const LLSD& info)
void LLFloaterSnapshot::update()
{
LLFloaterSnapshot* inst = LLFloaterReg::findTypedInstance<LLFloaterSnapshot>("snapshot");
- if (!inst)
+ LLFloaterSocial* floater_social = LLFloaterReg::findTypedInstance<LLFloaterSocial>("social");
+
+ if (!inst && !floater_social)
return;
BOOL changed = FALSE;
@@ -2245,7 +1276,8 @@ void LLFloaterSnapshot::update()
{
changed |= LLSnapshotLivePreview::onIdle(*iter);
}
- if(changed)
+
+ if (inst && changed)
{
lldebugs << "changed" << llendl;
inst->impl.updateControls(inst);
diff --git a/indra/newview/llfloatersnapshot.h b/indra/newview/llfloatersnapshot.h
index afe135fa40..82af8c7a9d 100644..100755
--- a/indra/newview/llfloatersnapshot.h
+++ b/indra/newview/llfloatersnapshot.h
@@ -27,7 +27,6 @@
#ifndef LL_LLFLOATERSNAPSHOT_H
#define LL_LLFLOATERSNAPSHOT_H
-#include "llimage.h"
#include "llfloater.h"
class LLSpinCtrl;
diff --git a/indra/newview/llfloatersocial.cpp b/indra/newview/llfloatersocial.cpp
new file mode 100644
index 0000000000..2a74c8e3ea
--- /dev/null
+++ b/indra/newview/llfloatersocial.cpp
@@ -0,0 +1,920 @@
+/**
+* @file llfloatersocial.cpp
+* @brief Implementation of llfloatersocial
+* @author Gilbert@lindenlab.com
+*
+* $LicenseInfo:firstyear=2013&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2013, 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 "llfloatersocial.h"
+
+#include "llagent.h"
+#include "llagentui.h"
+#include "llcheckboxctrl.h"
+#include "llcombobox.h"
+#include "llfacebookconnect.h"
+#include "llfloaterreg.h"
+#include "lliconctrl.h"
+#include "llresmgr.h" // LLLocale
+#include "llsdserialize.h"
+#include "llloadingindicator.h"
+#include "llplugincookiestore.h"
+#include "llslurl.h"
+#include "lltrans.h"
+#include "llsnapshotlivepreview.h"
+#include "llviewerregion.h"
+#include "llviewercontrol.h"
+#include "llviewermedia.h"
+
+static LLRegisterPanelClassWrapper<LLSocialStatusPanel> t_panel_status("llsocialstatuspanel");
+static LLRegisterPanelClassWrapper<LLSocialPhotoPanel> t_panel_photo("llsocialphotopanel");
+static LLRegisterPanelClassWrapper<LLSocialCheckinPanel> t_panel_checkin("llsocialcheckinpanel");
+static LLRegisterPanelClassWrapper<LLSocialAccountPanel> t_panel_account("llsocialaccountpanel");
+
+const S32 MAX_POSTCARD_DATASIZE = 1024 * 1024; // one megabyte
+const std::string DEFAULT_CHECKIN_LOCATION_URL = "http://maps.secondlife.com/";
+const std::string DEFAULT_CHECKIN_ICON_URL = "http://map.secondlife.com.s3.amazonaws.com/map_placeholder.png";
+const std::string DEFAULT_CHECKIN_QUERY_PARAMETERS = "?sourceid=slshare_checkin&utm_source=facebook&utm_medium=checkin&utm_campaign=slshare";
+const std::string DEFAULT_PHOTO_QUERY_PARAMETERS = "?sourceid=slshare_photo&utm_source=facebook&utm_medium=photo&utm_campaign=slshare";
+
+std::string get_map_url()
+{
+ LLVector3d center_agent;
+ if (gAgent.getRegion())
+ {
+ center_agent = gAgent.getRegion()->getCenterGlobal();
+ }
+ int x_pos = center_agent[0] / 256.0;
+ int y_pos = center_agent[1] / 256.0;
+ std::string map_url = gSavedSettings.getString("CurrentMapServerURL") + llformat("map-1-%d-%d-objects.jpg", x_pos, y_pos);
+ return map_url;
+}
+
+///////////////////////////
+//LLSocialStatusPanel//////
+///////////////////////////
+
+LLSocialStatusPanel::LLSocialStatusPanel() :
+ mMessageTextEditor(NULL),
+ mPostButton(NULL),
+ mCancelButton(NULL)
+{
+ mCommitCallbackRegistrar.add("SocialSharing.SendStatus", boost::bind(&LLSocialStatusPanel::onSend, this));
+}
+
+BOOL LLSocialStatusPanel::postBuild()
+{
+ mMessageTextEditor = getChild<LLUICtrl>("status_message");
+ mPostButton = getChild<LLUICtrl>("post_status_btn");
+ mCancelButton = getChild<LLUICtrl>("cancel_status_btn");
+
+ return LLPanel::postBuild();
+}
+
+void LLSocialStatusPanel::draw()
+{
+ if (mMessageTextEditor && mPostButton && mCancelButton)
+ {
+ bool no_ongoing_connection = !(LLFacebookConnect::instance().isTransactionOngoing());
+ std::string message = mMessageTextEditor->getValue().asString();
+ mMessageTextEditor->setEnabled(no_ongoing_connection);
+ mCancelButton->setEnabled(no_ongoing_connection);
+ mPostButton->setEnabled(no_ongoing_connection && !message.empty());
+ }
+
+ LLPanel::draw();
+}
+
+void LLSocialStatusPanel::onSend()
+{
+ LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLSocialStatusPanel"); // just in case it is already listening
+ LLEventPumps::instance().obtain("FacebookConnectState").listen("LLSocialStatusPanel", boost::bind(&LLSocialStatusPanel::onFacebookConnectStateChange, this, _1));
+
+ // Connect to Facebook if necessary and then post
+ if (LLFacebookConnect::instance().isConnected())
+ {
+ sendStatus();
+ }
+ else
+ {
+ LLFacebookConnect::instance().checkConnectionToFacebook(true);
+ }
+}
+
+bool LLSocialStatusPanel::onFacebookConnectStateChange(const LLSD& data)
+{
+ switch (data.get("enum").asInteger())
+ {
+ case LLFacebookConnect::FB_CONNECTED:
+ sendStatus();
+ break;
+
+ case LLFacebookConnect::FB_POSTED:
+ LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLSocialStatusPanel");
+ clearAndClose();
+ break;
+ }
+
+ return false;
+}
+
+void LLSocialStatusPanel::sendStatus()
+{
+ std::string message = mMessageTextEditor->getValue().asString();
+ if (!message.empty())
+ {
+ LLFacebookConnect::instance().updateStatus(message);
+ }
+}
+
+void LLSocialStatusPanel::clearAndClose()
+{
+ mMessageTextEditor->setValue("");
+
+ LLFloater* floater = getParentByType<LLFloater>();
+ if (floater)
+ {
+ floater->closeFloater();
+ }
+}
+
+///////////////////////////
+//LLSocialPhotoPanel///////
+///////////////////////////
+
+LLSocialPhotoPanel::LLSocialPhotoPanel() :
+mSnapshotPanel(NULL),
+mResolutionComboBox(NULL),
+mRefreshBtn(NULL),
+mWorkingLabel(NULL),
+mThumbnailPlaceholder(NULL),
+mCaptionTextBox(NULL),
+mLocationCheckbox(NULL),
+mPostButton(NULL)
+{
+ mCommitCallbackRegistrar.add("SocialSharing.SendPhoto", boost::bind(&LLSocialPhotoPanel::onSend, this));
+ mCommitCallbackRegistrar.add("SocialSharing.RefreshPhoto", boost::bind(&LLSocialPhotoPanel::onClickNewSnapshot, this));
+}
+
+LLSocialPhotoPanel::~LLSocialPhotoPanel()
+{
+ if(mPreviewHandle.get())
+ {
+ mPreviewHandle.get()->die();
+ }
+}
+
+BOOL LLSocialPhotoPanel::postBuild()
+{
+ setVisibleCallback(boost::bind(&LLSocialPhotoPanel::onVisibilityChange, this, _2));
+
+ mSnapshotPanel = getChild<LLUICtrl>("snapshot_panel");
+ mResolutionComboBox = getChild<LLUICtrl>("resolution_combobox");
+ mResolutionComboBox->setCommitCallback(boost::bind(&LLSocialPhotoPanel::updateResolution, this, TRUE));
+ mRefreshBtn = getChild<LLUICtrl>("new_snapshot_btn");
+ mWorkingLabel = getChild<LLUICtrl>("working_lbl");
+ mThumbnailPlaceholder = getChild<LLUICtrl>("thumbnail_placeholder");
+ mCaptionTextBox = getChild<LLUICtrl>("photo_caption");
+ mLocationCheckbox = getChild<LLUICtrl>("add_location_cb");
+ mPostButton = getChild<LLUICtrl>("post_photo_btn");
+ mCancelButton = getChild<LLUICtrl>("cancel_photo_btn");
+
+ return LLPanel::postBuild();
+}
+
+void LLSocialPhotoPanel::draw()
+{
+ LLSnapshotLivePreview * previewp = static_cast<LLSnapshotLivePreview *>(mPreviewHandle.get());
+
+ // Enable interaction only if no transaction with the service is on-going (prevent duplicated posts)
+ bool no_ongoing_connection = !(LLFacebookConnect::instance().isTransactionOngoing());
+ mCancelButton->setEnabled(no_ongoing_connection);
+ mCaptionTextBox->setEnabled(no_ongoing_connection);
+ mResolutionComboBox->setEnabled(no_ongoing_connection);
+ mRefreshBtn->setEnabled(no_ongoing_connection);
+ mLocationCheckbox->setEnabled(no_ongoing_connection);
+
+ // Display the preview if one is available
+ if (previewp && previewp->getThumbnailImage())
+ {
+ const LLRect& thumbnail_rect = mThumbnailPlaceholder->getRect();
+ const S32 thumbnail_w = previewp->getThumbnailWidth();
+ const S32 thumbnail_h = previewp->getThumbnailHeight();
+
+ // calc preview offset within the preview rect
+ const S32 local_offset_x = (thumbnail_rect.getWidth() - thumbnail_w) / 2 ;
+ const S32 local_offset_y = (thumbnail_rect.getHeight() - thumbnail_h) / 2 ;
+
+ // calc preview offset within the floater rect
+ // Hack : To get the full offset, we need to take into account each and every offset of each widgets up to the floater.
+ // This is almost as arbitrary as using a fixed offset so that's what we do here for the sake of simplicity.
+ // *TODO : Get the offset looking through the hierarchy of widgets, should be done in postBuild() so to avoid traversing the hierarchy each time.
+ S32 offset_x = thumbnail_rect.mLeft + local_offset_x - 1;
+ S32 offset_y = thumbnail_rect.mBottom + local_offset_y - 39;
+
+ mSnapshotPanel->localPointToOtherView(offset_x, offset_y, &offset_x, &offset_y, getParentByType<LLFloater>());
+
+ 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 = LLColor4::white;
+ gl_draw_scaled_image(offset_x, offset_y,
+ thumbnail_w, thumbnail_h,
+ previewp->getThumbnailImage(), color % alpha);
+
+ previewp->drawPreviewRect(offset_x, offset_y) ;
+ }
+
+ // Update the visibility of the working (computing preview) label
+ mWorkingLabel->setVisible(!(previewp && previewp->getSnapshotUpToDate()));
+
+ // Enable Post if we have a preview to send and no on going connection being processed
+ mPostButton->setEnabled(no_ongoing_connection && (previewp && previewp->getSnapshotUpToDate()));
+
+ // Draw the rest of the panel on top of it
+ LLPanel::draw();
+}
+
+LLSnapshotLivePreview* LLSocialPhotoPanel::getPreviewView()
+{
+ LLSnapshotLivePreview* previewp = (LLSnapshotLivePreview*)mPreviewHandle.get();
+ return previewp;
+}
+
+void LLSocialPhotoPanel::onVisibilityChange(const LLSD& new_visibility)
+{
+ bool visible = new_visibility.asBoolean();
+ if (visible)
+ {
+ if (mPreviewHandle.get())
+ {
+ LLSnapshotLivePreview* preview = getPreviewView();
+ if(preview)
+ {
+ lldebugs << "opened, updating snapshot" << llendl;
+ preview->updateSnapshot(TRUE);
+ }
+ }
+ else
+ {
+ LLRect full_screen_rect = getRootView()->getRect();
+ LLSnapshotLivePreview::Params p;
+ p.rect(full_screen_rect);
+ LLSnapshotLivePreview* previewp = new LLSnapshotLivePreview(p);
+ mPreviewHandle = previewp->getHandle();
+
+ previewp->setSnapshotType(previewp->SNAPSHOT_WEB);
+ previewp->setSnapshotFormat(LLFloaterSnapshot::SNAPSHOT_FORMAT_JPEG);
+ //previewp->setSnapshotQuality(98);
+ previewp->setThumbnailPlaceholderRect(mThumbnailPlaceholder->getRect());
+
+ updateControls();
+ }
+ }
+}
+
+void LLSocialPhotoPanel::onClickNewSnapshot()
+{
+ LLSnapshotLivePreview* previewp = getPreviewView();
+ if (previewp)
+ {
+ //setStatus(Impl::STATUS_READY);
+ lldebugs << "updating snapshot" << llendl;
+ previewp->updateSnapshot(TRUE);
+ }
+}
+
+void LLSocialPhotoPanel::onSend()
+{
+ LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLSocialPhotoPanel"); // just in case it is already listening
+ LLEventPumps::instance().obtain("FacebookConnectState").listen("LLSocialPhotoPanel", boost::bind(&LLSocialPhotoPanel::onFacebookConnectStateChange, this, _1));
+
+ // Connect to Facebook if necessary and then post
+ if (LLFacebookConnect::instance().isConnected())
+ {
+ sendPhoto();
+ }
+ else
+ {
+ LLFacebookConnect::instance().checkConnectionToFacebook(true);
+ }
+}
+
+bool LLSocialPhotoPanel::onFacebookConnectStateChange(const LLSD& data)
+{
+ switch (data.get("enum").asInteger())
+ {
+ case LLFacebookConnect::FB_CONNECTED:
+ sendPhoto();
+ break;
+
+ case LLFacebookConnect::FB_POSTED:
+ LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLSocialPhotoPanel");
+ clearAndClose();
+ break;
+ }
+
+ return false;
+}
+
+void LLSocialPhotoPanel::sendPhoto()
+{
+ // Get the caption
+ std::string caption = mCaptionTextBox->getValue().asString();
+
+ // Add the location if required
+ bool add_location = mLocationCheckbox->getValue().asBoolean();
+ if (add_location)
+ {
+ // Get the SLURL for the location
+ LLSLURL slurl;
+ LLAgentUI::buildSLURL(slurl);
+ std::string slurl_string = slurl.getSLURLString();
+
+ // Add query parameters so Google Analytics can track incoming clicks!
+ slurl_string += DEFAULT_PHOTO_QUERY_PARAMETERS;
+
+ // Add it to the caption (pretty crude, but we don't have a better option with photos)
+ if (caption.empty())
+ caption = slurl_string;
+ else
+ caption = caption + " " + slurl_string;
+ }
+
+ // Get the image
+ LLSnapshotLivePreview* previewp = getPreviewView();
+
+ // Post to Facebook
+ LLFacebookConnect::instance().sharePhoto(previewp->getFormattedImage(), caption);
+
+ updateControls();
+}
+
+void LLSocialPhotoPanel::clearAndClose()
+{
+ mCaptionTextBox->setValue("");
+
+ LLFloater* floater = getParentByType<LLFloater>();
+ if (floater)
+ {
+ floater->closeFloater();
+ }
+}
+
+void LLSocialPhotoPanel::updateControls()
+{
+ LLSnapshotLivePreview* previewp = getPreviewView();
+ BOOL got_bytes = previewp && previewp->getDataSize() > 0;
+ BOOL got_snap = previewp && previewp->getSnapshotUpToDate();
+ LLSnapshotLivePreview::ESnapshotType shot_type = (previewp ? previewp->getSnapshotType() : LLSnapshotLivePreview::SNAPSHOT_POSTCARD);
+
+ // *TODO: Separate maximum size for Web images from postcards
+ lldebugs << "Is snapshot up-to-date? " << got_snap << llendl;
+
+ LLLocale locale(LLLocale::USER_LOCALE);
+ std::string bytes_string;
+ if (got_snap)
+ {
+ LLResMgr::getInstance()->getIntegerString(bytes_string, (previewp->getDataSize()) >> 10 );
+ }
+
+ //getChild<LLUICtrl>("file_size_label")->setTextArg("[SIZE]", got_snap ? bytes_string : getString("unknown")); <---uses localized string
+ getChild<LLUICtrl>("file_size_label")->setTextArg("[SIZE]", got_snap ? bytes_string : "unknown");
+ getChild<LLUICtrl>("file_size_label")->setColor(
+ shot_type == LLSnapshotLivePreview::SNAPSHOT_POSTCARD
+ && got_bytes
+ && previewp->getDataSize() > MAX_POSTCARD_DATASIZE ? LLUIColor(LLColor4::red) : LLUIColorTable::instance().getColor( "LabelTextColor" ));
+
+ updateResolution(FALSE);
+}
+
+void LLSocialPhotoPanel::updateResolution(BOOL do_update)
+{
+ LLComboBox* combobox = static_cast<LLComboBox *>(mResolutionComboBox);
+
+ std::string sdstring = combobox->getSelectedValue();
+ LLSD sdres;
+ std::stringstream sstream(sdstring);
+ LLSDSerialize::fromNotation(sdres, sstream, sdstring.size());
+
+ S32 width = sdres[0];
+ S32 height = sdres[1];
+
+ LLSnapshotLivePreview * previewp = static_cast<LLSnapshotLivePreview *>(mPreviewHandle.get());
+ if (previewp && combobox->getCurrentIndex() >= 0)
+ {
+ S32 original_width = 0 , original_height = 0 ;
+ previewp->getSize(original_width, original_height) ;
+
+ if (width == 0 || height == 0)
+ {
+ // take resolution from current window size
+ lldebugs << "Setting preview res from window: " << gViewerWindow->getWindowWidthRaw() << "x" << gViewerWindow->getWindowHeightRaw() << llendl;
+ previewp->setSize(gViewerWindow->getWindowWidthRaw(), gViewerWindow->getWindowHeightRaw());
+ }
+ else
+ {
+ // use the resolution from the selected pre-canned drop-down choice
+ lldebugs << "Setting preview res selected from combo: " << width << "x" << height << llendl;
+ previewp->setSize(width, height);
+ }
+
+ checkAspectRatio(width);
+
+ previewp->getSize(width, height);
+
+ if(original_width != width || original_height != height)
+ {
+ previewp->setSize(width, height);
+
+ // hide old preview as the aspect ratio could be wrong
+ lldebugs << "updating thumbnail" << llendl;
+
+ previewp->updateSnapshot(FALSE, TRUE);
+ if(do_update)
+ {
+ lldebugs << "Will update controls" << llendl;
+ updateControls();
+ LLSocialPhotoPanel::onClickNewSnapshot();
+ }
+ }
+
+ }
+}
+
+void LLSocialPhotoPanel::checkAspectRatio(S32 index)
+{
+ LLSnapshotLivePreview *previewp = getPreviewView() ;
+
+ BOOL keep_aspect = FALSE;
+
+ if (0 == index) // current window size
+ {
+ keep_aspect = TRUE;
+ }
+ else // predefined resolution
+ {
+ keep_aspect = FALSE;
+ }
+
+ if (previewp)
+ {
+ previewp->mKeepAspectRatio = keep_aspect;
+ }
+}
+
+LLUICtrl* LLSocialPhotoPanel::getRefreshBtn()
+{
+ return mRefreshBtn;
+}
+
+////////////////////////
+//LLSocialCheckinPanel//
+////////////////////////
+
+LLSocialCheckinPanel::LLSocialCheckinPanel() :
+ mMapUrl(""),
+ mReloadingMapTexture(false)
+{
+ mCommitCallbackRegistrar.add("SocialSharing.SendCheckin", boost::bind(&LLSocialCheckinPanel::onSend, this));
+}
+
+BOOL LLSocialCheckinPanel::postBuild()
+{
+ // Keep pointers to widgets so we don't traverse the UI hierarchy too often
+ mPostButton = getChild<LLUICtrl>("post_place_btn");
+ mCancelButton = getChild<LLUICtrl>("cancel_place_btn");
+ mMessageTextEditor = getChild<LLUICtrl>("place_caption");
+ mMapLoadingIndicator = getChild<LLUICtrl>("map_loading_indicator");
+ mMapPlaceholder = getChild<LLIconCtrl>("map_placeholder");
+ mMapDefault = getChild<LLIconCtrl>("map_default");
+ mMapCheckBox = getChild<LLCheckBoxCtrl>("add_place_view_cb");
+
+ return LLPanel::postBuild();
+}
+
+void LLSocialCheckinPanel::draw()
+{
+ bool no_ongoing_connection = !(LLFacebookConnect::instance().isTransactionOngoing());
+ mPostButton->setEnabled(no_ongoing_connection);
+ mCancelButton->setEnabled(no_ongoing_connection);
+ mMessageTextEditor->setEnabled(no_ongoing_connection);
+ mMapCheckBox->setEnabled(no_ongoing_connection);
+
+ std::string map_url = get_map_url();
+ // Did we change location?
+ if (map_url != mMapUrl)
+ {
+ mMapUrl = map_url;
+ // Load the map tile
+ mMapTexture = LLViewerTextureManager::getFetchedTextureFromUrl(mMapUrl, FTT_MAP_TILE, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
+ mMapTexture->setBoostLevel(LLGLTexture::BOOST_MAP);
+ mReloadingMapTexture = true;
+ // In the meantime, put the "loading" indicator on, hide the tile map and disable the checkbox
+ mMapLoadingIndicator->setVisible(true);
+ mMapPlaceholder->setVisible(false);
+ }
+ // Are we done loading the map tile?
+ if (mReloadingMapTexture && mMapTexture->isFullyLoaded())
+ {
+ // Don't do it again next time around
+ mReloadingMapTexture = false;
+ // Convert the map texture to the appropriate image object
+ LLPointer<LLUIImage> ui_image = new LLUIImage(mMapUrl, mMapTexture);
+ // Load the map widget with the correct map tile image
+ mMapPlaceholder->setImage(ui_image);
+ // Now hide the loading indicator, bring the tile in view and reenable the checkbox with its previous value
+ mMapLoadingIndicator->setVisible(false);
+ mMapPlaceholder->setVisible(true);
+ }
+ // Show the default icon if that's the checkbox value (the real one...)
+ // This will hide/show the loading indicator and/or tile underneath
+ mMapDefault->setVisible(!(mMapCheckBox->get()));
+
+ LLPanel::draw();
+}
+
+void LLSocialCheckinPanel::onSend()
+{
+ LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLSocialCheckinPanel"); // just in case it is already listening
+ LLEventPumps::instance().obtain("FacebookConnectState").listen("LLSocialCheckinPanel", boost::bind(&LLSocialCheckinPanel::onFacebookConnectStateChange, this, _1));
+
+ // Connect to Facebook if necessary and then post
+ if (LLFacebookConnect::instance().isConnected())
+ {
+ sendCheckin();
+ }
+ else
+ {
+ LLFacebookConnect::instance().checkConnectionToFacebook(true);
+ }
+}
+
+bool LLSocialCheckinPanel::onFacebookConnectStateChange(const LLSD& data)
+{
+ switch (data.get("enum").asInteger())
+ {
+ case LLFacebookConnect::FB_CONNECTED:
+ sendCheckin();
+ break;
+
+ case LLFacebookConnect::FB_POSTED:
+ LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLSocialCheckinPanel");
+ clearAndClose();
+ break;
+ }
+
+ return false;
+}
+
+void LLSocialCheckinPanel::sendCheckin()
+{
+ // Get the location SLURL
+ LLSLURL slurl;
+ LLAgentUI::buildSLURL(slurl);
+ std::string slurl_string = slurl.getSLURLString();
+
+ // Use a valid http:// URL if the scheme is secondlife://
+ LLURI slurl_uri(slurl_string);
+ if (slurl_uri.scheme() == LLSLURL::SLURL_SECONDLIFE_SCHEME)
+ {
+ slurl_string = DEFAULT_CHECKIN_LOCATION_URL;
+ }
+
+ // Add query parameters so Google Analytics can track incoming clicks!
+ slurl_string += DEFAULT_CHECKIN_QUERY_PARAMETERS;
+
+ // Get the region name
+ std::string region_name = gAgent.getRegion()->getName();
+
+ // Get the region description
+ std::string description;
+ LLAgentUI::buildLocationString(description, LLAgentUI::LOCATION_FORMAT_NORMAL_COORDS, gAgent.getPositionAgent());
+
+ // Optionally add the region map view
+ bool add_map_view = mMapCheckBox->getValue().asBoolean();
+ std::string map_url = (add_map_view ? get_map_url() : DEFAULT_CHECKIN_ICON_URL);
+
+ // Get the caption
+ std::string caption = mMessageTextEditor->getValue().asString();
+
+ // Post to Facebook
+ LLFacebookConnect::instance().postCheckin(slurl_string, region_name, description, map_url, caption);
+}
+
+void LLSocialCheckinPanel::clearAndClose()
+{
+ mMessageTextEditor->setValue("");
+
+ LLFloater* floater = getParentByType<LLFloater>();
+ if (floater)
+ {
+ floater->closeFloater();
+ }
+}
+
+///////////////////////////
+//LLSocialAccountPanel//////
+///////////////////////////
+
+LLSocialAccountPanel::LLSocialAccountPanel() :
+mAccountCaptionLabel(NULL),
+mAccountNameLabel(NULL),
+mPanelButtons(NULL),
+mConnectButton(NULL),
+mDisconnectButton(NULL)
+{
+ mCommitCallbackRegistrar.add("SocialSharing.Connect", boost::bind(&LLSocialAccountPanel::onConnect, this));
+ mCommitCallbackRegistrar.add("SocialSharing.Disconnect", boost::bind(&LLSocialAccountPanel::onDisconnect, this));
+
+ setVisibleCallback(boost::bind(&LLSocialAccountPanel::onVisibilityChange, this, _2));
+}
+
+BOOL LLSocialAccountPanel::postBuild()
+{
+ mAccountCaptionLabel = getChild<LLTextBox>("account_caption_label");
+ mAccountNameLabel = getChild<LLTextBox>("account_name_label");
+ mPanelButtons = getChild<LLUICtrl>("panel_buttons");
+ mConnectButton = getChild<LLUICtrl>("connect_btn");
+ mDisconnectButton = getChild<LLUICtrl>("disconnect_btn");
+
+ return LLPanel::postBuild();
+}
+
+void LLSocialAccountPanel::draw()
+{
+ LLFacebookConnect::EConnectionState connection_state = LLFacebookConnect::instance().getConnectionState();
+
+ //Disable the 'disconnect' button and the 'use another account' button when disconnecting in progress
+ bool disconnecting = connection_state == LLFacebookConnect::FB_DISCONNECTING;
+ mDisconnectButton->setEnabled(!disconnecting);
+
+ //Disable the 'connect' button when a connection is in progress
+ bool connecting = connection_state == LLFacebookConnect::FB_CONNECTION_IN_PROGRESS;
+ mConnectButton->setEnabled(!connecting);
+
+ LLPanel::draw();
+}
+
+void LLSocialAccountPanel::onVisibilityChange(const LLSD& new_visibility)
+{
+ bool visible = new_visibility.asBoolean();
+
+ if(visible)
+ {
+ LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLSocialAccountPanel");
+ LLEventPumps::instance().obtain("FacebookConnectState").listen("LLSocialAccountPanel", boost::bind(&LLSocialAccountPanel::onFacebookConnectStateChange, this, _1));
+
+ LLEventPumps::instance().obtain("FacebookConnectInfo").stopListening("LLSocialAccountPanel");
+ LLEventPumps::instance().obtain("FacebookConnectInfo").listen("LLSocialAccountPanel", boost::bind(&LLSocialAccountPanel::onFacebookConnectInfoChange, this));
+
+ //Connected
+ if(LLFacebookConnect::instance().isConnected())
+ {
+ showConnectedLayout();
+ }
+ //Check if connected (show disconnected layout in meantime)
+ else
+ {
+ showDisconnectedLayout();
+ }
+ if ((LLFacebookConnect::instance().getConnectionState() == LLFacebookConnect::FB_NOT_CONNECTED) ||
+ (LLFacebookConnect::instance().getConnectionState() == LLFacebookConnect::FB_CONNECTION_FAILED))
+ {
+ LLFacebookConnect::instance().checkConnectionToFacebook();
+ }
+ }
+ else
+ {
+ LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLSocialAccountPanel");
+ LLEventPumps::instance().obtain("FacebookConnectInfo").stopListening("LLSocialAccountPanel");
+ }
+}
+
+bool LLSocialAccountPanel::onFacebookConnectStateChange(const LLSD& data)
+{
+ if(LLFacebookConnect::instance().isConnected())
+ {
+ //In process of disconnecting so leave the layout as is
+ if(data.get("enum").asInteger() != LLFacebookConnect::FB_DISCONNECTING)
+ {
+ showConnectedLayout();
+ }
+ }
+ else
+ {
+ showDisconnectedLayout();
+ }
+
+ return false;
+}
+
+bool LLSocialAccountPanel::onFacebookConnectInfoChange()
+{
+ LLSD info = LLFacebookConnect::instance().getInfo();
+ std::string clickable_name;
+
+ //Strings of format [http://www.somewebsite.com Click Me] become clickable text
+ if(info.has("link") && info.has("name"))
+ {
+ clickable_name = "[" + info["link"].asString() + " " + info["name"].asString() + "]";
+ }
+
+ mAccountNameLabel->setText(clickable_name);
+
+ return false;
+}
+
+void LLSocialAccountPanel::showConnectButton()
+{
+ if(!mConnectButton->getVisible())
+ {
+ mConnectButton->setVisible(TRUE);
+ mDisconnectButton->setVisible(FALSE);
+ }
+}
+
+void LLSocialAccountPanel::hideConnectButton()
+{
+ if(mConnectButton->getVisible())
+ {
+ mConnectButton->setVisible(FALSE);
+ mDisconnectButton->setVisible(TRUE);
+ }
+}
+
+void LLSocialAccountPanel::showDisconnectedLayout()
+{
+ mAccountCaptionLabel->setText(getString("facebook_disconnected"));
+ mAccountNameLabel->setText(std::string(""));
+ showConnectButton();
+}
+
+void LLSocialAccountPanel::showConnectedLayout()
+{
+ LLFacebookConnect::instance().loadFacebookInfo();
+
+ mAccountCaptionLabel->setText(getString("facebook_connected"));
+ hideConnectButton();
+}
+
+void LLSocialAccountPanel::onConnect()
+{
+ LLFacebookConnect::instance().checkConnectionToFacebook(true);
+
+ //Clear only the facebook browser cookies so that the facebook login screen appears
+ LLViewerMedia::getCookieStore()->removeCookiesByDomain(".facebook.com");
+}
+
+void LLSocialAccountPanel::onDisconnect()
+{
+ LLFacebookConnect::instance().disconnectFromFacebook();
+
+ LLViewerMedia::getCookieStore()->removeCookiesByDomain(".facebook.com");
+}
+
+////////////////////////
+//LLFloaterSocial///////
+////////////////////////
+
+LLFloaterSocial::LLFloaterSocial(const LLSD& key) : LLFloater(key),
+ mSocialPhotoPanel(NULL),
+ mStatusErrorText(NULL),
+ mStatusLoadingText(NULL),
+ mStatusLoadingIndicator(NULL)
+{
+ mCommitCallbackRegistrar.add("SocialSharing.Cancel", boost::bind(&LLFloaterSocial::onCancel, this));
+}
+
+void LLFloaterSocial::onCancel()
+{
+ closeFloater();
+}
+
+BOOL LLFloaterSocial::postBuild()
+{
+ // Keep tab of the Photo Panel
+ mSocialPhotoPanel = static_cast<LLSocialPhotoPanel*>(getChild<LLUICtrl>("panel_social_photo"));
+ // Connection status widgets
+ mStatusErrorText = getChild<LLTextBox>("connection_error_text");
+ mStatusLoadingText = getChild<LLTextBox>("connection_loading_text");
+ mStatusLoadingIndicator = getChild<LLUICtrl>("connection_loading_indicator");
+ return LLFloater::postBuild();
+}
+
+// static
+void LLFloaterSocial::preUpdate()
+{
+ LLFloaterSocial* instance = LLFloaterReg::findTypedInstance<LLFloaterSocial>("social");
+ if (instance)
+ {
+ //Will set file size text to 'unknown'
+ instance->mSocialPhotoPanel->updateControls();
+ }
+}
+
+// static
+void LLFloaterSocial::postUpdate()
+{
+ LLFloaterSocial* instance = LLFloaterReg::findTypedInstance<LLFloaterSocial>("social");
+ if (instance)
+ {
+ //Will set the file size text
+ instance->mSocialPhotoPanel->updateControls();
+
+ // The refresh button is initially hidden. We show it after the first update,
+ // i.e. after snapshot is taken
+ LLUICtrl * refresh_button = instance->mSocialPhotoPanel->getRefreshBtn();
+
+ if (!refresh_button->getVisible())
+ {
+ refresh_button->setVisible(true);
+ }
+
+ }
+}
+
+void LLFloaterSocial::draw()
+{
+ if (mStatusErrorText && mStatusLoadingText && mStatusLoadingIndicator)
+ {
+ mStatusErrorText->setVisible(false);
+ mStatusLoadingText->setVisible(false);
+ mStatusLoadingIndicator->setVisible(false);
+ LLFacebookConnect::EConnectionState connection_state = LLFacebookConnect::instance().getConnectionState();
+ std::string status_text;
+
+ switch (connection_state)
+ {
+ case LLFacebookConnect::FB_NOT_CONNECTED:
+ // No status displayed when first opening the panel and no connection done
+ case LLFacebookConnect::FB_CONNECTED:
+ // When successfully connected, no message is displayed
+ case LLFacebookConnect::FB_POSTED:
+ // No success message to show since we actually close the floater after successful posting completion
+ break;
+ case LLFacebookConnect::FB_CONNECTION_IN_PROGRESS:
+ // Connection loading indicator
+ mStatusLoadingText->setVisible(true);
+ status_text = LLTrans::getString("SocialFacebookConnecting");
+ mStatusLoadingText->setValue(status_text);
+ mStatusLoadingIndicator->setVisible(true);
+ break;
+ case LLFacebookConnect::FB_POSTING:
+ // Posting indicator
+ mStatusLoadingText->setVisible(true);
+ status_text = LLTrans::getString("SocialFacebookPosting");
+ mStatusLoadingText->setValue(status_text);
+ mStatusLoadingIndicator->setVisible(true);
+ break;
+ case LLFacebookConnect::FB_CONNECTION_FAILED:
+ // Error connecting to the service
+ mStatusErrorText->setVisible(true);
+ status_text = LLTrans::getString("SocialFacebookErrorConnecting");
+ mStatusErrorText->setValue(status_text);
+ break;
+ case LLFacebookConnect::FB_POST_FAILED:
+ // Error posting to the service
+ mStatusErrorText->setVisible(true);
+ status_text = LLTrans::getString("SocialFacebookErrorPosting");
+ mStatusErrorText->setValue(status_text);
+ break;
+ case LLFacebookConnect::FB_DISCONNECTING:
+ // Disconnecting loading indicator
+ mStatusLoadingText->setVisible(true);
+ status_text = LLTrans::getString("SocialFacebookDisconnecting");
+ mStatusLoadingText->setValue(status_text);
+ mStatusLoadingIndicator->setVisible(true);
+ break;
+ case LLFacebookConnect::FB_DISCONNECT_FAILED:
+ // Error disconnecting from the service
+ mStatusErrorText->setVisible(true);
+ status_text = LLTrans::getString("SocialFacebookErrorDisconnecting");
+ mStatusErrorText->setValue(status_text);
+ break;
+ }
+ }
+ LLFloater::draw();
+}
+
diff --git a/indra/newview/llfloatersocial.h b/indra/newview/llfloatersocial.h
new file mode 100644
index 0000000000..bbe07c9704
--- /dev/null
+++ b/indra/newview/llfloatersocial.h
@@ -0,0 +1,165 @@
+/**
+* @file llfloatersocial.h
+* @brief Header file for llfloatersocial
+* @author Gilbert@lindenlab.com
+*
+* $LicenseInfo:firstyear=2013&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2013, 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_LLFLOATERSOCIAL_H
+#define LL_LLFLOATERSOCIAL_H
+
+#include "llfloater.h"
+#include "lltextbox.h"
+#include "llviewertexture.h"
+
+class LLIconCtrl;
+class LLCheckBoxCtrl;
+class LLSnapshotLivePreview;
+
+class LLSocialStatusPanel : public LLPanel
+{
+public:
+ LLSocialStatusPanel();
+ BOOL postBuild();
+ void draw();
+ void onSend();
+ bool onFacebookConnectStateChange(const LLSD& data);
+
+ void sendStatus();
+ void clearAndClose();
+
+private:
+ LLUICtrl* mMessageTextEditor;
+ LLUICtrl* mPostButton;
+ LLUICtrl* mCancelButton;
+};
+
+class LLSocialPhotoPanel : public LLPanel
+{
+public:
+ LLSocialPhotoPanel();
+ ~LLSocialPhotoPanel();
+
+ BOOL postBuild();
+ void draw();
+
+ LLSnapshotLivePreview* getPreviewView();
+ void onVisibilityChange(const LLSD& new_visibility);
+ void onClickNewSnapshot();
+ void onSend();
+ bool onFacebookConnectStateChange(const LLSD& data);
+
+ void sendPhoto();
+ void clearAndClose();
+
+ void updateControls();
+ void updateResolution(BOOL do_update);
+ void checkAspectRatio(S32 index);
+ LLUICtrl* getRefreshBtn();
+
+private:
+ LLHandle<LLView> mPreviewHandle;
+
+ LLUICtrl * mSnapshotPanel;
+ LLUICtrl * mResolutionComboBox;
+ LLUICtrl * mRefreshBtn;
+ LLUICtrl * mWorkingLabel;
+ LLUICtrl * mThumbnailPlaceholder;
+ LLUICtrl * mCaptionTextBox;
+ LLUICtrl * mLocationCheckbox;
+ LLUICtrl * mPostButton;
+ LLUICtrl* mCancelButton;
+};
+
+class LLSocialCheckinPanel : public LLPanel
+{
+public:
+ LLSocialCheckinPanel();
+ BOOL postBuild();
+ void draw();
+ void onSend();
+ bool onFacebookConnectStateChange(const LLSD& data);
+
+ void sendCheckin();
+ void clearAndClose();
+
+private:
+ std::string mMapUrl;
+ LLPointer<LLViewerFetchedTexture> mMapTexture;
+ LLUICtrl* mPostButton;
+ LLUICtrl* mCancelButton;
+ LLUICtrl* mMessageTextEditor;
+ LLUICtrl* mMapLoadingIndicator;
+ LLIconCtrl* mMapPlaceholder;
+ LLIconCtrl* mMapDefault;
+ LLCheckBoxCtrl* mMapCheckBox;
+ bool mReloadingMapTexture;
+};
+
+class LLSocialAccountPanel : public LLPanel
+{
+public:
+ LLSocialAccountPanel();
+ BOOL postBuild();
+ void draw();
+
+private:
+ void onVisibilityChange(const LLSD& new_visibility);
+ bool onFacebookConnectStateChange(const LLSD& data);
+ bool onFacebookConnectInfoChange();
+ void onConnect();
+ void onUseAnotherAccount();
+ void onDisconnect();
+
+ void showConnectButton();
+ void hideConnectButton();
+ void showDisconnectedLayout();
+ void showConnectedLayout();
+
+ LLTextBox * mAccountCaptionLabel;
+ LLTextBox * mAccountNameLabel;
+ LLUICtrl * mPanelButtons;
+ LLUICtrl * mConnectButton;
+ LLUICtrl * mDisconnectButton;
+};
+
+
+class LLFloaterSocial : public LLFloater
+{
+public:
+ LLFloaterSocial(const LLSD& key);
+ BOOL postBuild();
+ void draw();
+ void onCancel();
+
+ static void preUpdate();
+ static void postUpdate();
+
+private:
+ LLSocialPhotoPanel* mSocialPhotoPanel;
+ LLTextBox* mStatusErrorText;
+ LLTextBox* mStatusLoadingText;
+ LLUICtrl* mStatusLoadingIndicator;
+};
+
+#endif // LL_LLFLOATERSOCIAL_H
+
diff --git a/indra/newview/llfloatersounddevices.cpp b/indra/newview/llfloatersounddevices.cpp
index 72c077d215..72c077d215 100644..100755
--- a/indra/newview/llfloatersounddevices.cpp
+++ b/indra/newview/llfloatersounddevices.cpp
diff --git a/indra/newview/llfloatersounddevices.h b/indra/newview/llfloatersounddevices.h
index f09ee3b069..f09ee3b069 100644..100755
--- a/indra/newview/llfloatersounddevices.h
+++ b/indra/newview/llfloatersounddevices.h
diff --git a/indra/newview/llfloaterspellchecksettings.cpp b/indra/newview/llfloaterspellchecksettings.cpp
new file mode 100755
index 0000000000..5ecdd11918
--- /dev/null
+++ b/indra/newview/llfloaterspellchecksettings.cpp
@@ -0,0 +1,491 @@
+/**
+ * @file llfloaterspellchecksettings.h
+ * @brief Spell checker settings floater
+ *
+* $LicenseInfo:firstyear=2011&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 "llviewerprecompiledheaders.h"
+
+#include "llcombobox.h"
+#include "llfilepicker.h"
+#include "llfloaterreg.h"
+#include "llfloaterspellchecksettings.h"
+#include "llscrolllistctrl.h"
+#include "llsdserialize.h"
+#include "llspellcheck.h"
+#include "lltrans.h"
+#include "llviewercontrol.h"
+#include "llnotificationsutil.h"
+
+#include <boost/algorithm/string.hpp>
+
+///----------------------------------------------------------------------------
+/// Class LLFloaterSpellCheckerSettings
+///----------------------------------------------------------------------------
+LLFloaterSpellCheckerSettings::LLFloaterSpellCheckerSettings(const LLSD& key)
+ : LLFloater(key)
+{
+}
+
+void LLFloaterSpellCheckerSettings::draw()
+{
+ LLFloater::draw();
+
+ std::vector<LLScrollListItem*> sel_items = getChild<LLScrollListCtrl>("spellcheck_available_list")->getAllSelected();
+ bool enable_remove = !sel_items.empty();
+ for (std::vector<LLScrollListItem*>::const_iterator sel_it = sel_items.begin(); sel_it != sel_items.end(); ++sel_it)
+ {
+ enable_remove &= LLSpellChecker::canRemoveDictionary((*sel_it)->getValue().asString());
+ }
+ getChild<LLUICtrl>("spellcheck_remove_btn")->setEnabled(enable_remove);
+}
+
+BOOL LLFloaterSpellCheckerSettings::postBuild(void)
+{
+ gSavedSettings.getControl("SpellCheck")->getSignal()->connect(boost::bind(&LLFloaterSpellCheckerSettings::refreshDictionaries, this, false));
+ LLSpellChecker::setSettingsChangeCallback(boost::bind(&LLFloaterSpellCheckerSettings::onSpellCheckSettingsChange, this));
+ getChild<LLUICtrl>("spellcheck_remove_btn")->setCommitCallback(boost::bind(&LLFloaterSpellCheckerSettings::onBtnRemove, this));
+ getChild<LLUICtrl>("spellcheck_import_btn")->setCommitCallback(boost::bind(&LLFloaterSpellCheckerSettings::onBtnImport, this));
+ getChild<LLUICtrl>("spellcheck_main_combo")->setCommitCallback(boost::bind(&LLFloaterSpellCheckerSettings::refreshDictionaries, this, false));
+ getChild<LLUICtrl>("spellcheck_moveleft_btn")->setCommitCallback(boost::bind(&LLFloaterSpellCheckerSettings::onBtnMove, this, "spellcheck_active_list", "spellcheck_available_list"));
+ getChild<LLUICtrl>("spellcheck_moveright_btn")->setCommitCallback(boost::bind(&LLFloaterSpellCheckerSettings::onBtnMove, this, "spellcheck_available_list", "spellcheck_active_list"));
+ center();
+ return true;
+}
+
+void LLFloaterSpellCheckerSettings::onBtnImport()
+{
+ LLFloaterReg::showInstance("prefs_spellchecker_import");
+}
+
+void LLFloaterSpellCheckerSettings::onBtnMove(const std::string& from, const std::string& to)
+{
+ LLScrollListCtrl* from_ctrl = findChild<LLScrollListCtrl>(from);
+ LLScrollListCtrl* to_ctrl = findChild<LLScrollListCtrl>(to);
+
+ LLSD row;
+ row["columns"][0]["column"] = "name";
+
+ std::vector<LLScrollListItem*> sel_items = from_ctrl->getAllSelected();
+ std::vector<LLScrollListItem*>::const_iterator sel_it;
+ for ( sel_it = sel_items.begin(); sel_it != sel_items.end(); ++sel_it)
+ {
+ row["value"] = (*sel_it)->getValue();
+ row["columns"][0]["value"] = (*sel_it)->getColumn(0)->getValue();
+ to_ctrl->addElement(row);
+ to_ctrl->setSelectedByValue( (*sel_it)->getValue(), true );
+ }
+ from_ctrl->deleteSelectedItems();
+}
+
+void LLFloaterSpellCheckerSettings::onClose(bool app_quitting)
+{
+ if (app_quitting)
+ {
+ // don't save anything
+ return;
+ }
+ LLFloaterReg::hideInstance("prefs_spellchecker_import");
+
+ std::list<std::string> list_dict;
+
+ LLComboBox* dict_combo = findChild<LLComboBox>("spellcheck_main_combo");
+ const std::string dict_name = dict_combo->getSelectedItemLabel();
+ if (!dict_name.empty())
+ {
+ list_dict.push_back(dict_name);
+
+ LLScrollListCtrl* list_ctrl = findChild<LLScrollListCtrl>("spellcheck_active_list");
+ std::vector<LLScrollListItem*> list_items = list_ctrl->getAllData();
+ for (std::vector<LLScrollListItem*>::const_iterator item_it = list_items.begin(); item_it != list_items.end(); ++item_it)
+ {
+ const std::string language = (*item_it)->getValue().asString();
+ if (LLSpellChecker::hasDictionary(language, true))
+ {
+ list_dict.push_back(language);
+ }
+ }
+ }
+ gSavedSettings.setString("SpellCheckDictionary", boost::join(list_dict, ","));
+}
+
+void LLFloaterSpellCheckerSettings::onOpen(const LLSD& key)
+{
+ refreshDictionaries(true);
+}
+
+void LLFloaterSpellCheckerSettings::onBtnRemove()
+{
+ std::vector<LLScrollListItem*> sel_items = getChild<LLScrollListCtrl>("spellcheck_available_list")->getAllSelected();
+ for (std::vector<LLScrollListItem*>::const_iterator sel_it = sel_items.begin(); sel_it != sel_items.end(); ++sel_it)
+ {
+ LLSpellChecker::instance().removeDictionary((*sel_it)->getValue().asString());
+ }
+}
+
+void LLFloaterSpellCheckerSettings::onSpellCheckSettingsChange()
+{
+ refreshDictionaries(true);
+}
+
+void LLFloaterSpellCheckerSettings::refreshDictionaries(bool from_settings)
+{
+ bool enabled = gSavedSettings.getBOOL("SpellCheck");
+ getChild<LLUICtrl>("spellcheck_moveleft_btn")->setEnabled(enabled);
+ getChild<LLUICtrl>("spellcheck_moveright_btn")->setEnabled(enabled);
+
+ // Populate the dictionary combobox
+ LLComboBox* dict_combo = findChild<LLComboBox>("spellcheck_main_combo");
+ std::string dict_cur = dict_combo->getSelectedItemLabel();
+ if ((dict_cur.empty() || from_settings) && (LLSpellChecker::getUseSpellCheck()))
+ {
+ dict_cur = LLSpellChecker::instance().getPrimaryDictionary();
+ }
+ dict_combo->clearRows();
+
+ const LLSD& dict_map = LLSpellChecker::getDictionaryMap();
+ if (dict_map.size())
+ {
+ for (LLSD::array_const_iterator dict_it = dict_map.beginArray(); dict_it != dict_map.endArray(); ++dict_it)
+ {
+ const LLSD& dict = *dict_it;
+ if ( (dict["installed"].asBoolean()) && (dict["is_primary"].asBoolean()) && (dict.has("language")) )
+ {
+ dict_combo->add(dict["language"].asString());
+ }
+ }
+ if (!dict_combo->selectByValue(dict_cur))
+ {
+ dict_combo->clear();
+ }
+ }
+ dict_combo->sortByName();
+ dict_combo->setEnabled(enabled);
+
+ // Populate the available and active dictionary list
+ LLScrollListCtrl* avail_ctrl = findChild<LLScrollListCtrl>("spellcheck_available_list");
+ LLScrollListCtrl* active_ctrl = findChild<LLScrollListCtrl>("spellcheck_active_list");
+
+ LLSpellChecker::dict_list_t active_list;
+ if ( ((!avail_ctrl->getItemCount()) && (!active_ctrl->getItemCount())) || (from_settings) )
+ {
+ if (LLSpellChecker::getUseSpellCheck())
+ {
+ active_list = LLSpellChecker::instance().getSecondaryDictionaries();
+ }
+ }
+ else
+ {
+ std::vector<LLScrollListItem*> active_items = active_ctrl->getAllData();
+ for (std::vector<LLScrollListItem*>::const_iterator item_it = active_items.begin(); item_it != active_items.end(); ++item_it)
+ {
+ std::string dict = (*item_it)->getValue().asString();
+ if (dict_cur != dict)
+ {
+ active_list.push_back(dict);
+ }
+ }
+ }
+
+ LLSD row;
+ row["columns"][0]["column"] = "name";
+
+ active_ctrl->clearRows();
+ active_ctrl->setEnabled(enabled);
+ for (LLSpellChecker::dict_list_t::const_iterator it = active_list.begin(); it != active_list.end(); ++it)
+ {
+ const std::string language = *it;
+ const LLSD dict = LLSpellChecker::getDictionaryData(language);
+ row["value"] = language;
+ row["columns"][0]["value"] = (!dict["user_installed"].asBoolean()) ? language : language + " " + LLTrans::getString("UserDictionary");
+ active_ctrl->addElement(row);
+ }
+ active_ctrl->sortByColumnIndex(0, true);
+ active_list.push_back(dict_cur);
+
+ avail_ctrl->clearRows();
+ avail_ctrl->setEnabled(enabled);
+ for (LLSD::array_const_iterator dict_it = dict_map.beginArray(); dict_it != dict_map.endArray(); ++dict_it)
+ {
+ const LLSD& dict = *dict_it;
+ const std::string language = dict["language"].asString();
+ if ( (dict["installed"].asBoolean()) && (active_list.end() == std::find(active_list.begin(), active_list.end(), language)) )
+ {
+ row["value"] = language;
+ row["columns"][0]["value"] = (!dict["user_installed"].asBoolean()) ? language : language + " " + LLTrans::getString("UserDictionary");
+ avail_ctrl->addElement(row);
+ }
+ }
+ avail_ctrl->sortByColumnIndex(0, true);
+}
+
+///----------------------------------------------------------------------------
+/// Class LLFloaterSpellCheckerImport
+///----------------------------------------------------------------------------
+LLFloaterSpellCheckerImport::LLFloaterSpellCheckerImport(const LLSD& key)
+ : LLFloater(key)
+{
+}
+
+BOOL LLFloaterSpellCheckerImport::postBuild(void)
+{
+ getChild<LLUICtrl>("dictionary_path_browse")->setCommitCallback(boost::bind(&LLFloaterSpellCheckerImport::onBtnBrowse, this));
+ getChild<LLUICtrl>("ok_btn")->setCommitCallback(boost::bind(&LLFloaterSpellCheckerImport::onBtnOK, this));
+ getChild<LLUICtrl>("cancel_btn")->setCommitCallback(boost::bind(&LLFloaterSpellCheckerImport::onBtnCancel, this));
+ center();
+ return true;
+}
+
+void LLFloaterSpellCheckerImport::onBtnBrowse()
+{
+ LLFilePicker& file_picker = LLFilePicker::instance();
+ if (!file_picker.getOpenFile(LLFilePicker::FFLOAD_DICTIONARY))
+ {
+ return;
+ }
+
+ std::string filepath = file_picker.getFirstFile();
+
+ const std::string extension = gDirUtilp->getExtension(filepath);
+ if ("xcu" == extension)
+ {
+ filepath = parseXcuFile(filepath);
+ if (filepath.empty())
+ {
+ return;
+ }
+ }
+
+ getChild<LLUICtrl>("dictionary_path")->setValue(filepath);
+
+ mDictionaryDir = gDirUtilp->getDirName(filepath);
+ mDictionaryBasename = gDirUtilp->getBaseFileName(filepath, true);
+ getChild<LLUICtrl>("dictionary_name")->setValue(mDictionaryBasename);
+}
+
+void LLFloaterSpellCheckerImport::onBtnCancel()
+{
+ closeFloater(false);
+}
+
+void LLFloaterSpellCheckerImport::onBtnOK()
+{
+ const std::string dict_dic = mDictionaryDir + gDirUtilp->getDirDelimiter() + mDictionaryBasename + ".dic";
+ const std::string dict_aff = mDictionaryDir + gDirUtilp->getDirDelimiter() + mDictionaryBasename + ".aff";
+ std::string dict_language = getChild<LLUICtrl>("dictionary_language")->getValue().asString();
+ LLStringUtil::trim(dict_language);
+
+ bool imported = false;
+ if ( dict_language.empty()
+ || mDictionaryDir.empty()
+ || mDictionaryBasename.empty()
+ || ! gDirUtilp->fileExists(dict_dic)
+ )
+ {
+ LLNotificationsUtil::add("SpellingDictImportRequired");
+ }
+ else
+ {
+ std::string settings_dic = LLSpellChecker::getDictionaryUserPath() + mDictionaryBasename + ".dic";
+ if ( copyFile( dict_dic, settings_dic ) )
+ {
+ if (gDirUtilp->fileExists(dict_aff))
+ {
+ std::string settings_aff = LLSpellChecker::getDictionaryUserPath() + mDictionaryBasename + ".aff";
+ if (copyFile( dict_aff, settings_aff ))
+ {
+ imported = true;
+ }
+ else
+ {
+ LLSD args = LLSD::emptyMap();
+ args["FROM_NAME"] = dict_aff;
+ args["TO_NAME"] = settings_aff;
+ LLNotificationsUtil::add("SpellingDictImportFailed", args);
+ }
+ }
+ else
+ {
+ LLSD args = LLSD::emptyMap();
+ args["DIC_NAME"] = dict_dic;
+ LLNotificationsUtil::add("SpellingDictIsSecondary", args);
+
+ imported = true;
+ }
+ }
+ else
+ {
+ LLSD args = LLSD::emptyMap();
+ args["FROM_NAME"] = dict_dic;
+ args["TO_NAME"] = settings_dic;
+ LLNotificationsUtil::add("SpellingDictImportFailed", args);
+ }
+ }
+
+ if ( imported )
+ {
+ LLSD custom_dict_info;
+ custom_dict_info["is_primary"] = (bool)gDirUtilp->fileExists(dict_aff);
+ custom_dict_info["name"] = mDictionaryBasename;
+ custom_dict_info["language"] = dict_language;
+
+ LLSD custom_dict_map;
+ llifstream custom_file_in(LLSpellChecker::getDictionaryUserPath() + "user_dictionaries.xml");
+ if (custom_file_in.is_open())
+ {
+ LLSDSerialize::fromXMLDocument(custom_dict_map, custom_file_in);
+ custom_file_in.close();
+ }
+
+ LLSD::array_iterator it = custom_dict_map.beginArray();
+ for (; it != custom_dict_map.endArray(); ++it)
+ {
+ LLSD& dict_info = *it;
+ if (dict_info["name"].asString() == mDictionaryBasename)
+ {
+ dict_info = custom_dict_info;
+ break;
+ }
+ }
+ if (custom_dict_map.endArray() == it)
+ {
+ custom_dict_map.append(custom_dict_info);
+ }
+
+ llofstream custom_file_out(LLSpellChecker::getDictionaryUserPath() + "user_dictionaries.xml", std::ios::trunc);
+ if (custom_file_out.is_open())
+ {
+ LLSDSerialize::toPrettyXML(custom_dict_map, custom_file_out);
+ custom_file_out.close();
+ }
+
+ LLSpellChecker::refreshDictionaryMap();
+ }
+
+ closeFloater(false);
+}
+
+bool LLFloaterSpellCheckerImport::copyFile(const std::string from, const std::string to)
+{
+ bool copied = false;
+ LLFILE* in = LLFile::fopen(from, "rb"); /* Flawfinder: ignore */
+ if (in)
+ {
+ LLFILE* out = LLFile::fopen(to, "wb"); /* Flawfinder: ignore */
+ if (out)
+ {
+ char buf[16384]; /* Flawfinder: ignore */
+ size_t readbytes;
+ bool write_ok = true;
+ while(write_ok && (readbytes = fread(buf, 1, 16384, in))) /* Flawfinder: ignore */
+ {
+ if (fwrite(buf, 1, readbytes, out) != readbytes)
+ {
+ LL_WARNS("SpellCheck") << "Short write" << LL_ENDL;
+ write_ok = false;
+ }
+ }
+ if ( write_ok )
+ {
+ copied = true;
+ }
+ fclose(out);
+ }
+ }
+ fclose(in);
+ return copied;
+}
+
+std::string LLFloaterSpellCheckerImport::parseXcuFile(const std::string& file_path) const
+{
+ LLXMLNodePtr xml_root;
+ if ( (!LLUICtrlFactory::getLayeredXMLNode(file_path, xml_root)) || (xml_root.isNull()) )
+ {
+ return LLStringUtil::null;
+ }
+
+ // Bury down to the "Dictionaries" parent node
+ LLXMLNode* dict_node = NULL;
+ for (LLXMLNode* outer_node = xml_root->getFirstChild(); outer_node && !dict_node; outer_node = outer_node->getNextSibling())
+ {
+ std::string temp;
+ if ( (outer_node->getAttributeString("oor:name", temp)) && ("ServiceManager" == temp) )
+ {
+ for (LLXMLNode* inner_node = outer_node->getFirstChild(); inner_node && !dict_node; inner_node = inner_node->getNextSibling())
+ {
+ if ( (inner_node->getAttributeString("oor:name", temp)) && ("Dictionaries" == temp) )
+ {
+ dict_node = inner_node;
+ break;
+ }
+ }
+ }
+ }
+
+ if (dict_node)
+ {
+ // Iterate over all child nodes until we find one that has a <value>DICT_SPELL</value> node
+ for (LLXMLNode* outer_node = dict_node->getFirstChild(); outer_node; outer_node = outer_node->getNextSibling())
+ {
+ std::string temp;
+ LLXMLNodePtr location_node, format_node;
+ for (LLXMLNode* inner_node = outer_node->getFirstChild(); inner_node; inner_node = inner_node->getNextSibling())
+ {
+ if (inner_node->getAttributeString("oor:name", temp))
+ {
+ if ("Locations" == temp)
+ {
+ inner_node->getChild("value", location_node, false);
+ }
+ else if ("Format" == temp)
+ {
+ inner_node->getChild("value", format_node, false);
+ }
+ }
+ }
+ if ( (format_node.isNull()) || ("DICT_SPELL" != format_node->getValue()) || (location_node.isNull()) )
+ {
+ continue;
+ }
+
+ // Found a list of file locations, return the .dic (if present)
+ std::list<std::string> location_list;
+ boost::split(location_list, location_node->getValue(), boost::is_any_of(std::string(" ")));
+ for (std::list<std::string>::iterator it = location_list.begin(); it != location_list.end(); ++it)
+ {
+ std::string& location = *it;
+ if ("\\" != gDirUtilp->getDirDelimiter())
+ LLStringUtil::replaceString(location, "\\", gDirUtilp->getDirDelimiter());
+ else
+ LLStringUtil::replaceString(location, "/", gDirUtilp->getDirDelimiter());
+ LLStringUtil::replaceString(location, "%origin%", gDirUtilp->getDirName(file_path));
+ if ("dic" == gDirUtilp->getExtension(location))
+ {
+ return location;
+ }
+ }
+ }
+ }
+
+ return LLStringUtil::null;
+}
diff --git a/indra/newview/llfloaterspellchecksettings.h b/indra/newview/llfloaterspellchecksettings.h
new file mode 100755
index 0000000000..eded3a9133
--- /dev/null
+++ b/indra/newview/llfloaterspellchecksettings.h
@@ -0,0 +1,68 @@
+/**
+ * @file llfloaterspellchecksettings.h
+ * @brief Spell checker settings floater
+ *
+* $LicenseInfo:firstyear=2011&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$
+ */
+
+#ifndef LLFLOATERSPELLCHECKERSETTINGS_H
+#define LLFLOATERSPELLCHECKERSETTINGS_H
+
+#include "llfloater.h"
+
+class LLFloaterSpellCheckerSettings : public LLFloater
+{
+public:
+ LLFloaterSpellCheckerSettings(const LLSD& key);
+
+ /*virtual*/ void draw();
+ /*virtual*/ BOOL postBuild();
+ /*virtual*/ void onOpen(const LLSD& key);
+ /*virtual*/ void onClose(bool app_quitting);
+
+protected:
+ void onBtnImport();
+ void onBtnMove(const std::string& from, const std::string& to);
+ void onBtnRemove();
+ void onSpellCheckSettingsChange();
+ void refreshDictionaries(bool from_settings);
+};
+
+class LLFloaterSpellCheckerImport : public LLFloater
+{
+public:
+ LLFloaterSpellCheckerImport(const LLSD& key);
+
+ /*virtual*/ BOOL postBuild();
+
+protected:
+ void onBtnBrowse();
+ void onBtnCancel();
+ void onBtnOK();
+ bool copyFile(const std::string from, const std::string to);
+ std::string parseXcuFile(const std::string& file_path) const;
+
+ std::string mDictionaryDir;
+ std::string mDictionaryBasename;
+};
+
+#endif // LLFLOATERSPELLCHECKERSETTINGS_H
diff --git a/indra/newview/llfloatertelehub.cpp b/indra/newview/llfloatertelehub.cpp
index b845fd132d..b845fd132d 100644..100755
--- a/indra/newview/llfloatertelehub.cpp
+++ b/indra/newview/llfloatertelehub.cpp
diff --git a/indra/newview/llfloatertelehub.h b/indra/newview/llfloatertelehub.h
index 9b9b11fb29..9b9b11fb29 100644..100755
--- a/indra/newview/llfloatertelehub.h
+++ b/indra/newview/llfloatertelehub.h
diff --git a/indra/newview/llfloatertestinspectors.cpp b/indra/newview/llfloatertestinspectors.cpp
index 8a1582569b..8a1582569b 100644..100755
--- a/indra/newview/llfloatertestinspectors.cpp
+++ b/indra/newview/llfloatertestinspectors.cpp
diff --git a/indra/newview/llfloatertestinspectors.h b/indra/newview/llfloatertestinspectors.h
index 1724a2e076..1724a2e076 100644..100755
--- a/indra/newview/llfloatertestinspectors.h
+++ b/indra/newview/llfloatertestinspectors.h
diff --git a/indra/newview/llfloatertestlistview.cpp b/indra/newview/llfloatertestlistview.cpp
index 97cf95baed..97cf95baed 100644..100755
--- a/indra/newview/llfloatertestlistview.cpp
+++ b/indra/newview/llfloatertestlistview.cpp
diff --git a/indra/newview/llfloatertestlistview.h b/indra/newview/llfloatertestlistview.h
index 0d4c7eb793..0d4c7eb793 100644..100755
--- a/indra/newview/llfloatertestlistview.h
+++ b/indra/newview/llfloatertestlistview.h
diff --git a/indra/newview/llfloatertexturefetchdebugger.cpp b/indra/newview/llfloatertexturefetchdebugger.cpp
new file mode 100755
index 0000000000..9a23d99802
--- /dev/null
+++ b/indra/newview/llfloatertexturefetchdebugger.cpp
@@ -0,0 +1,472 @@
+/**
+ * @file llfloatertexturefetchdebugger.cpp
+ * @brief LLFloaterTextureFetchDebugger class definition
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 "llfloatertexturefetchdebugger.h"
+
+#include "lluictrlfactory.h"
+#include "llbutton.h"
+#include "llspinctrl.h"
+#include "llresmgr.h"
+
+#include "llmath.h"
+#include "llviewerwindow.h"
+#include "llappviewer.h"
+#include "lltexturefetch.h"
+#include "llviewercontrol.h"
+
+LLFloaterTextureFetchDebugger::LLFloaterTextureFetchDebugger(const LLSD& key)
+ : LLFloater(key),
+ mDebugger(NULL)
+{
+ setTitle("Texture Fetching Debugger Floater");
+
+ mCommitCallbackRegistrar.add("TexFetchDebugger.ChangeTexelPixelRatio", boost::bind(&LLFloaterTextureFetchDebugger::onChangeTexelPixelRatio, this));
+
+ mCommitCallbackRegistrar.add("TexFetchDebugger.Start", boost::bind(&LLFloaterTextureFetchDebugger::onClickStart, this));
+ mCommitCallbackRegistrar.add("TexFetchDebugger.Clear", boost::bind(&LLFloaterTextureFetchDebugger::onClickClear, this));
+ mCommitCallbackRegistrar.add("TexFetchDebugger.Close", boost::bind(&LLFloaterTextureFetchDebugger::onClickClose, this));
+
+ mCommitCallbackRegistrar.add("TexFetchDebugger.CacheRead", boost::bind(&LLFloaterTextureFetchDebugger::onClickCacheRead, this));
+ mCommitCallbackRegistrar.add("TexFetchDebugger.CacheWrite", boost::bind(&LLFloaterTextureFetchDebugger::onClickCacheWrite, this));
+ mCommitCallbackRegistrar.add("TexFetchDebugger.HTTPLoad", boost::bind(&LLFloaterTextureFetchDebugger::onClickHTTPLoad, this));
+ mCommitCallbackRegistrar.add("TexFetchDebugger.Decode", boost::bind(&LLFloaterTextureFetchDebugger::onClickDecode, this));
+ mCommitCallbackRegistrar.add("TexFetchDebugger.GLTexture", boost::bind(&LLFloaterTextureFetchDebugger::onClickGLTexture, this));
+
+ mCommitCallbackRegistrar.add("TexFetchDebugger.RefetchVisCache", boost::bind(&LLFloaterTextureFetchDebugger::onClickRefetchVisCache, this));
+ mCommitCallbackRegistrar.add("TexFetchDebugger.RefetchVisHTTP", boost::bind(&LLFloaterTextureFetchDebugger::onClickRefetchVisHTTP, this));
+ mCommitCallbackRegistrar.add("TexFetchDebugger.RefetchAllCache", boost::bind(&LLFloaterTextureFetchDebugger::onClickRefetchAllCache, this));
+ mCommitCallbackRegistrar.add("TexFetchDebugger.RefetchAllHTTP", boost::bind(&LLFloaterTextureFetchDebugger::onClickRefetchAllHTTP, this));
+}
+//----------------------------------------------
+
+BOOL LLFloaterTextureFetchDebugger::postBuild(void)
+{
+ mDebugger = LLAppViewer::getTextureFetch()->getFetchDebugger();
+ mStartStatus = (S32)LLTextureFetchDebugger::IDLE;
+
+ //set states for buttons
+ mButtonStateMap["start_btn"] = true;
+ mButtonStateMap["close_btn"] = true;
+ mButtonStateMap["clear_btn"] = true;
+ mButtonStateMap["cacheread_btn"] = false;
+ mButtonStateMap["cachewrite_btn"] = false;
+ mButtonStateMap["http_btn"] = false;
+ mButtonStateMap["decode_btn"] = false;
+ mButtonStateMap["gl_btn"] = false;
+
+ mButtonStateMap["refetchviscache_btn"] = false;
+ mButtonStateMap["refetchvishttp_btn"] = false;
+ mButtonStateMap["refetchallcache_btn"] = false;
+ mButtonStateMap["refetchallhttp_btn"] = false;
+
+ updateButtons();
+
+ getChild<LLUICtrl>("texel_pixel_ratio")->setValue(gSavedSettings.getF32("TexelPixelRatio"));
+
+ return TRUE ;
+}
+
+LLFloaterTextureFetchDebugger::~LLFloaterTextureFetchDebugger()
+{
+ //stop everything
+ mDebugger->setStopDebug();
+}
+
+void LLFloaterTextureFetchDebugger::updateButtons()
+{
+ for(std::map<std::string, bool>::iterator iter = mButtonStateMap.begin(); iter != mButtonStateMap.end(); ++iter)
+ {
+ if(iter->second)
+ {
+ childEnable(iter->first.c_str());
+ }
+ else
+ {
+ childDisable(iter->first.c_str());
+ }
+ }
+}
+
+void LLFloaterTextureFetchDebugger::disableButtons()
+{
+ childDisable("start_btn");
+ childDisable("clear_btn");
+ childDisable("cacheread_btn");
+ childDisable("cachewrite_btn");
+ childDisable("http_btn");
+ childDisable("decode_btn");
+ childDisable("gl_btn");
+ childDisable("refetchviscache_btn");
+ childDisable("refetchvishttp_btn");
+ childDisable("refetchallcache_btn");
+ childDisable("refetchallhttp_btn");
+}
+void LLFloaterTextureFetchDebugger::setStartStatus(S32 status)
+{
+ llassert_always(LLTextureFetchDebugger::IDLE == (LLTextureFetchDebugger::e_debug_state)mStartStatus) ;
+ mStartStatus = status;
+}
+
+bool LLFloaterTextureFetchDebugger::idleStart()
+{
+ if(mStartStatus != (S32)LLTextureFetchDebugger::IDLE)
+ {
+ mDebugger->startWork((LLTextureFetchDebugger::e_debug_state)mStartStatus);
+ mStartStatus = (S32)LLTextureFetchDebugger::IDLE;
+ return true;
+ }
+
+ return false;
+}
+
+void LLFloaterTextureFetchDebugger::idle()
+{
+ if(idleStart())
+ {
+ return;
+ }
+
+ const F32 max_time = 0.005f; //5ms
+ LLTextureFetchDebugger::e_debug_state state = mDebugger->getState();
+ if(mDebugger->update(max_time))
+ {
+ switch(state)
+ {
+ case LLTextureFetchDebugger::IDLE:
+ break;
+ case LLTextureFetchDebugger::START_DEBUG:
+ mButtonStateMap["cacheread_btn"] = true;
+ mButtonStateMap["http_btn"] = true;
+ mButtonStateMap["refetchviscache_btn"] = true;
+ mButtonStateMap["refetchvishttp_btn"] = true;
+ mButtonStateMap["refetchallcache_btn"] = true;
+ mButtonStateMap["refetchallhttp_btn"] = true;
+ break;
+ case LLTextureFetchDebugger::READ_CACHE:
+ mButtonStateMap["decode_btn"] = true;
+ break;
+ case LLTextureFetchDebugger::WRITE_CACHE:
+ break;
+ case LLTextureFetchDebugger::DECODING:
+ mButtonStateMap["gl_btn"] = true;
+ break;
+ case LLTextureFetchDebugger::HTTP_FETCHING:
+ mButtonStateMap["cacheread_btn"] = true;
+ mButtonStateMap["cachewrite_btn"] = true;
+ mButtonStateMap["decode_btn"] = true;
+ break;
+ case LLTextureFetchDebugger::GL_TEX:
+ break;
+ case LLTextureFetchDebugger::REFETCH_VIS_CACHE:
+ break;
+ case LLTextureFetchDebugger::REFETCH_VIS_HTTP:
+ break;
+ case LLTextureFetchDebugger::REFETCH_ALL_CACHE:
+ break;
+ case LLTextureFetchDebugger::REFETCH_ALL_HTTP:
+ break;
+ default:
+ break;
+ }
+
+ if(state != LLTextureFetchDebugger::IDLE)
+ {
+ updateButtons();
+ }
+ }
+}
+
+//----------------------
+void LLFloaterTextureFetchDebugger::onChangeTexelPixelRatio()
+{
+ gSavedSettings.setF32("TexelPixelRatio", getChild<LLUICtrl>("texel_pixel_ratio")->getValue().asReal());
+}
+
+void LLFloaterTextureFetchDebugger::onClickStart()
+{
+ disableButtons();
+
+ setStartStatus((S32)LLTextureFetchDebugger::START_DEBUG);
+
+ mButtonStateMap["start_btn"] = false;
+
+ updateButtons();
+}
+
+void LLFloaterTextureFetchDebugger::onClickClose()
+{
+ setVisible(FALSE);
+
+ //stop everything
+ mDebugger->setStopDebug();
+
+ delete this;
+}
+
+void LLFloaterTextureFetchDebugger::onClickClear()
+{
+ mButtonStateMap["start_btn"] = true;
+ mButtonStateMap["close_btn"] = true;
+ mButtonStateMap["clear_btn"] = true;
+ mButtonStateMap["cacheread_btn"] = false;
+ mButtonStateMap["cachewrite_btn"] = false;
+ mButtonStateMap["http_btn"] = false;
+ mButtonStateMap["decode_btn"] = false;
+ mButtonStateMap["gl_btn"] = false;
+ mButtonStateMap["refetchviscache_btn"] = true;
+ mButtonStateMap["refetchvishttp_btn"] = true;
+ updateButtons();
+
+ //stop everything
+ mDebugger->setStopDebug();
+ mDebugger->clearHistory();
+}
+
+void LLFloaterTextureFetchDebugger::onClickCacheRead()
+{
+ disableButtons();
+
+ setStartStatus((S32)LLTextureFetchDebugger::READ_CACHE);
+}
+
+void LLFloaterTextureFetchDebugger::onClickCacheWrite()
+{
+ disableButtons();
+
+ setStartStatus((S32)LLTextureFetchDebugger::WRITE_CACHE);
+}
+
+void LLFloaterTextureFetchDebugger::onClickHTTPLoad()
+{
+ disableButtons();
+
+ setStartStatus((S32)LLTextureFetchDebugger::HTTP_FETCHING);
+}
+
+void LLFloaterTextureFetchDebugger::onClickDecode()
+{
+ disableButtons();
+
+ setStartStatus((S32)LLTextureFetchDebugger::DECODING);
+}
+
+void LLFloaterTextureFetchDebugger::onClickGLTexture()
+{
+ disableButtons();
+
+ setStartStatus((S32)LLTextureFetchDebugger::GL_TEX);
+}
+
+void LLFloaterTextureFetchDebugger::onClickRefetchVisCache()
+{
+ disableButtons();
+
+ setStartStatus((S32)LLTextureFetchDebugger::REFETCH_VIS_CACHE);
+}
+
+void LLFloaterTextureFetchDebugger::onClickRefetchVisHTTP()
+{
+ disableButtons();
+
+ setStartStatus((S32)LLTextureFetchDebugger::REFETCH_VIS_HTTP);
+}
+
+void LLFloaterTextureFetchDebugger::onClickRefetchAllCache()
+{
+ disableButtons();
+
+ setStartStatus((S32)LLTextureFetchDebugger::REFETCH_ALL_CACHE);
+}
+
+void LLFloaterTextureFetchDebugger::onClickRefetchAllHTTP()
+{
+ disableButtons();
+
+ setStartStatus((S32)LLTextureFetchDebugger::REFETCH_ALL_HTTP);
+}
+
+void LLFloaterTextureFetchDebugger::draw()
+{
+ //total number of fetched textures
+ {
+ getChild<LLUICtrl>("total_num_fetched_label")->setTextArg("[NUM]", llformat("%d", mDebugger->getNumFetchedTextures()));
+ }
+
+ //total number of fetching requests
+ {
+ getChild<LLUICtrl>("total_num_fetching_requests_label")->setTextArg("[NUM]", llformat("%d", mDebugger->getNumFetchingRequests()));
+ }
+
+ //total number of cache hits
+ {
+ getChild<LLUICtrl>("total_num_cache_hits_label")->setTextArg("[NUM]", llformat("%d", mDebugger->getNumCacheHits()));
+ }
+
+ //total number of visible textures
+ {
+ getChild<LLUICtrl>("total_num_visible_tex_label")->setTextArg("[NUM]", llformat("%d", mDebugger->getNumVisibleFetchedTextures()));
+ }
+
+ //total number of visible texture fetching requests
+ {
+ getChild<LLUICtrl>("total_num_visible_tex_fetch_req_label")->setTextArg("[NUM]", llformat("%d", mDebugger->getNumVisibleFetchingRequests()));
+ }
+
+ //total number of fetched data
+ {
+ getChild<LLUICtrl>("total_fetched_data_label")->setTextArg("[SIZE1]", llformat("%d", mDebugger->getFetchedData() >> 10));
+ getChild<LLUICtrl>("total_fetched_data_label")->setTextArg("[SIZE2]", llformat("%d", mDebugger->getDecodedData() >> 10));
+ getChild<LLUICtrl>("total_fetched_data_label")->setTextArg("[PIXEL]", llformat("%.3f", mDebugger->getFetchedPixels() / 1000000.f));
+ }
+
+ //total number of visible fetched data
+ {
+ getChild<LLUICtrl>("total_fetched_vis_data_label")->setTextArg("[SIZE1]", llformat("%d", mDebugger->getVisibleFetchedData() >> 10));
+ getChild<LLUICtrl>("total_fetched_vis_data_label")->setTextArg("[SIZE2]", llformat("%d", mDebugger->getVisibleDecodedData() >> 10));
+ }
+
+ //total number of rendered fetched data
+ {
+ getChild<LLUICtrl>("total_fetched_rendered_data_label")->setTextArg("[SIZE1]", llformat("%d", mDebugger->getRenderedData() >> 10));
+ getChild<LLUICtrl>("total_fetched_rendered_data_label")->setTextArg("[SIZE2]", llformat("%d", mDebugger->getRenderedDecodedData() >> 10));
+ getChild<LLUICtrl>("total_fetched_rendered_data_label")->setTextArg("[PIXEL]", llformat("%.3f", mDebugger->getRenderedPixels() / 1000000.f));
+ }
+
+ //total time on cache readings
+ if(mDebugger->getCacheReadTime() < 0.f)
+ {
+ getChild<LLUICtrl>("total_time_cache_read_label")->setTextArg("[TIME]", std::string("----"));
+ }
+ else
+ {
+ getChild<LLUICtrl>("total_time_cache_read_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getCacheReadTime()));
+ }
+
+ //total time on cache writings
+ if(mDebugger->getCacheWriteTime() < 0.f)
+ {
+ getChild<LLUICtrl>("total_time_cache_write_label")->setTextArg("[TIME]", std::string("----"));
+ }
+ else
+ {
+ getChild<LLUICtrl>("total_time_cache_write_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getCacheWriteTime()));
+ }
+
+ //total time on decoding
+ if(mDebugger->getDecodeTime() < 0.f)
+ {
+ getChild<LLUICtrl>("total_time_decode_label")->setTextArg("[TIME]", std::string("----"));
+ }
+ else
+ {
+ getChild<LLUICtrl>("total_time_decode_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getDecodeTime()));
+ }
+
+ //total time on gl texture creation
+ if(mDebugger->getGLCreationTime() < 0.f)
+ {
+ getChild<LLUICtrl>("total_time_gl_label")->setTextArg("[TIME]", std::string("----"));
+ }
+ else
+ {
+ getChild<LLUICtrl>("total_time_gl_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getGLCreationTime()));
+ }
+
+ //total time on HTTP fetching
+ if(mDebugger->getHTTPTime() < 0.f)
+ {
+ getChild<LLUICtrl>("total_time_http_label")->setTextArg("[TIME]", std::string("----"));
+ }
+ else
+ {
+ getChild<LLUICtrl>("total_time_http_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getHTTPTime()));
+ }
+
+ //total time on entire fetching
+ {
+ getChild<LLUICtrl>("total_time_fetch_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getTotalFetchingTime()));
+ }
+
+ //total time on refetching visible textures from cache
+ if(mDebugger->getRefetchVisCacheTime() < 0.f)
+ {
+ getChild<LLUICtrl>("total_time_refetch_vis_cache_label")->setTextArg("[TIME]", std::string("----"));
+ getChild<LLUICtrl>("total_time_refetch_vis_cache_label")->setTextArg("[SIZE]", std::string("----"));
+ getChild<LLUICtrl>("total_time_refetch_vis_cache_label")->setTextArg("[PIXEL]", std::string("----"));
+ }
+ else
+ {
+ getChild<LLUICtrl>("total_time_refetch_vis_cache_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getRefetchVisCacheTime()));
+ getChild<LLUICtrl>("total_time_refetch_vis_cache_label")->setTextArg("[SIZE]", llformat("%d", mDebugger->getRefetchedVisData() >> 10));
+ getChild<LLUICtrl>("total_time_refetch_vis_cache_label")->setTextArg("[PIXEL]", llformat("%.3f", mDebugger->getRefetchedVisPixels() / 1000000.f));
+ }
+
+ //total time on refetching all textures from cache
+ if(mDebugger->getRefetchAllCacheTime() < 0.f)
+ {
+ getChild<LLUICtrl>("total_time_refetch_all_cache_label")->setTextArg("[TIME]", std::string("----"));
+ getChild<LLUICtrl>("total_time_refetch_all_cache_label")->setTextArg("[SIZE]", std::string("----"));
+ getChild<LLUICtrl>("total_time_refetch_all_cache_label")->setTextArg("[PIXEL]", std::string("----"));
+ }
+ else
+ {
+ getChild<LLUICtrl>("total_time_refetch_all_cache_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getRefetchAllCacheTime()));
+ getChild<LLUICtrl>("total_time_refetch_all_cache_label")->setTextArg("[SIZE]", llformat("%d", mDebugger->getRefetchedAllData() >> 10));
+ getChild<LLUICtrl>("total_time_refetch_all_cache_label")->setTextArg("[PIXEL]", llformat("%.3f", mDebugger->getRefetchedAllPixels() / 1000000.f));
+ }
+
+ //total time on refetching visible textures from http
+ if(mDebugger->getRefetchVisHTTPTime() < 0.f)
+ {
+ getChild<LLUICtrl>("total_time_refetch_vis_http_label")->setTextArg("[TIME]", std::string("----"));
+ getChild<LLUICtrl>("total_time_refetch_vis_http_label")->setTextArg("[SIZE]", std::string("----"));
+ getChild<LLUICtrl>("total_time_refetch_vis_http_label")->setTextArg("[PIXEL]", std::string("----"));
+ }
+ else
+ {
+ getChild<LLUICtrl>("total_time_refetch_vis_http_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getRefetchVisHTTPTime()));
+ getChild<LLUICtrl>("total_time_refetch_vis_http_label")->setTextArg("[SIZE]", llformat("%d", mDebugger->getRefetchedVisData() >> 10));
+ getChild<LLUICtrl>("total_time_refetch_vis_http_label")->setTextArg("[PIXEL]", llformat("%.3f", mDebugger->getRefetchedVisPixels() / 1000000.f));
+ }
+
+ //total time on refetching all textures from http
+ if(mDebugger->getRefetchAllHTTPTime() < 0.f)
+ {
+ getChild<LLUICtrl>("total_time_refetch_all_http_label")->setTextArg("[TIME]", std::string("----"));
+ getChild<LLUICtrl>("total_time_refetch_all_http_label")->setTextArg("[SIZE]", std::string("----"));
+ getChild<LLUICtrl>("total_time_refetch_all_http_label")->setTextArg("[PIXEL]", std::string("----"));
+ }
+ else
+ {
+ getChild<LLUICtrl>("total_time_refetch_all_http_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getRefetchAllHTTPTime()));
+ getChild<LLUICtrl>("total_time_refetch_all_http_label")->setTextArg("[SIZE]", llformat("%d", mDebugger->getRefetchedAllData() >> 10));
+ getChild<LLUICtrl>("total_time_refetch_all_http_label")->setTextArg("[PIXEL]", llformat("%.3f", mDebugger->getRefetchedAllPixels() / 1000000.f));
+ }
+
+ LLFloater::draw();
+}
diff --git a/indra/newview/llfloatertexturefetchdebugger.h b/indra/newview/llfloatertexturefetchdebugger.h
new file mode 100755
index 0000000000..096ad88e07
--- /dev/null
+++ b/indra/newview/llfloatertexturefetchdebugger.h
@@ -0,0 +1,76 @@
+/**
+ * @file llfloatertexturefetchdebugger.h
+ * @brief texture fetching debugger window, debug use only
+ *
+ * $LicenseInfo:firstyear=2004&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$
+ */
+
+#ifndef LL_FLOATER_TEXTURE_FETCH_DEBUGGER__H
+#define LL_FLOATER_TEXTURE_FETCH_DEBUGGER__H
+
+#include "llfloater.h"
+class LLTextureFetchDebugger;
+
+class LLFloaterTextureFetchDebugger : public LLFloater
+{
+ friend class LLFloaterReg;
+public:
+ /// initialize all the callbacks for the menu
+
+ virtual BOOL postBuild() ;
+ virtual void draw() ;
+
+ void onChangeTexelPixelRatio();
+
+ void onClickStart();
+ void onClickClear();
+ void onClickClose();
+
+ void onClickCacheRead();
+ void onClickCacheWrite();
+ void onClickHTTPLoad();
+ void onClickDecode();
+ void onClickGLTexture();
+
+ void onClickRefetchVisCache();
+ void onClickRefetchVisHTTP();
+ void onClickRefetchAllCache();
+ void onClickRefetchAllHTTP();
+public:
+ void idle() ;
+
+private:
+ LLFloaterTextureFetchDebugger(const LLSD& key);
+ virtual ~LLFloaterTextureFetchDebugger();
+
+ void updateButtons();
+ void disableButtons();
+
+ void setStartStatus(S32 status);
+ bool idleStart();
+private:
+ LLTextureFetchDebugger* mDebugger;
+ std::map<std::string, bool> mButtonStateMap;
+ S32 mStartStatus;
+};
+
+#endif // LL_FLOATER_TEXTURE_FETCH_DEBUGGER__H
diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp
index 6978e6a430..7b25291da7 100644..100755
--- a/indra/newview/llfloatertools.cpp
+++ b/indra/newview/llfloatertools.cpp
@@ -110,9 +110,6 @@ void click_show_more(void*);
void click_popup_info(void*);
void click_popup_done(void*);
void click_popup_minimize(void*);
-void click_popup_rotate_left(void*);
-void click_popup_rotate_reset(void*);
-void click_popup_rotate_right(void*);
void commit_slider_dozer_force(LLUICtrl *);
void click_apply_to_selection(void*);
void commit_radio_group_focus(LLUICtrl* ctrl);
@@ -660,8 +657,8 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask)
mBtnEdit ->setToggleState( edit_visible );
mRadioGroupEdit->setVisible( edit_visible );
- bool linked_parts = gSavedSettings.getBOOL("EditLinkedParts");
- getChildView("RenderingCost")->setVisible( !linked_parts && (edit_visible || focus_visible || move_visible) && sShowObjectCost);
+ //bool linked_parts = gSavedSettings.getBOOL("EditLinkedParts");
+ //getChildView("RenderingCost")->setVisible( !linked_parts && (edit_visible || focus_visible || move_visible) && sShowObjectCost);
mBtnLink->setVisible(edit_visible);
mBtnUnlink->setVisible(edit_visible);
@@ -954,24 +951,6 @@ void commit_slider_zoom(LLUICtrl *ctrl)
gAgentCamera.setCameraZoomFraction(zoom_level);
}
-void click_popup_rotate_left(void*)
-{
- LLSelectMgr::getInstance()->selectionRotateAroundZ( 45.f );
- dialog_refresh_all();
-}
-
-void click_popup_rotate_reset(void*)
-{
- LLSelectMgr::getInstance()->selectionResetRotation();
- dialog_refresh_all();
-}
-
-void click_popup_rotate_right(void*)
-{
- LLSelectMgr::getInstance()->selectionRotateAroundZ( -45.f );
- dialog_refresh_all();
-}
-
void commit_slider_dozer_force(LLUICtrl *ctrl)
{
// the slider is logarithmic, so we exponentiate to get the actual force multiplier
@@ -1076,6 +1055,17 @@ void commit_grid_mode(LLUICtrl *ctrl)
LLSelectMgr::getInstance()->setGridMode((EGridMode)combo->getCurrentIndex());
}
+// static
+void LLFloaterTools::setGridMode(S32 mode)
+{
+ LLFloaterTools* tools_floater = LLFloaterReg::getTypedInstance<LLFloaterTools>("build");
+ if (!tools_floater || !tools_floater->mComboGridMode)
+ {
+ return;
+ }
+
+ tools_floater->mComboGridMode->setCurrentByIndex(mode);
+}
void LLFloaterTools::onClickGridOptions()
{
@@ -1218,7 +1208,10 @@ void LLFloaterTools::getMediaState()
return;
}
- bool editable = (first_object->permModify() || selectedMediaEditable());
+ BOOL is_nonpermanent_enforced = (LLSelectMgr::getInstance()->getSelection()->getFirstRootNode()
+ && LLSelectMgr::getInstance()->selectGetRootsNonPermanentEnforced())
+ || LLSelectMgr::getInstance()->selectGetNonPermanentEnforced();
+ bool editable = is_nonpermanent_enforced && (first_object->permModify() || selectedMediaEditable());
// Check modify permissions and whether any selected objects are in
// the process of being fetched. If they are, then we're not editable
@@ -1335,7 +1328,7 @@ void LLFloaterTools::getMediaState()
getChildView("media_tex")->setEnabled(bool_has_media && editable);
getChildView("edit_media")->setEnabled(bool_has_media && LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo && editable );
getChildView("delete_media")->setEnabled(bool_has_media && editable );
- getChildView("add_media")->setEnabled(( ! bool_has_media ) && editable );
+ getChildView("add_media")->setEnabled(editable);
// TODO: display a list of all media on the face - use 'identical' flag
}
else // not all face has media but at least one does.
@@ -1365,7 +1358,7 @@ void LLFloaterTools::getMediaState()
getChildView("media_tex")->setEnabled(TRUE);
getChildView("edit_media")->setEnabled(LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo);
getChildView("delete_media")->setEnabled(TRUE);
- getChildView("add_media")->setEnabled(FALSE );
+ getChildView("add_media")->setEnabled(editable);
}
media_info->setText(media_title);
diff --git a/indra/newview/llfloatertools.h b/indra/newview/llfloatertools.h
index 7a19d093a4..189bae46c2 100644..100755
--- a/indra/newview/llfloatertools.h
+++ b/indra/newview/llfloatertools.h
@@ -107,6 +107,10 @@ public:
bool selectedMediaEditable();
void updateLandImpacts();
+ static void setGridMode(S32 mode);
+
+ LLPanelFace* getPanelFace() { return mPanelFace; }
+
private:
void refresh();
void refreshMedia();
diff --git a/indra/newview/llfloatertopobjects.cpp b/indra/newview/llfloatertopobjects.cpp
index 87d048c15b..7530c72dd2 100644..100755
--- a/indra/newview/llfloatertopobjects.cpp
+++ b/indra/newview/llfloatertopobjects.cpp
@@ -82,6 +82,7 @@ LLFloaterTopObjects::LLFloaterTopObjects(const LLSD& key)
mCommitCallbackRegistrar.add("TopObjects.Refresh", boost::bind(&LLFloaterTopObjects::onRefresh, this));
mCommitCallbackRegistrar.add("TopObjects.GetByObjectName", boost::bind(&LLFloaterTopObjects::onGetByObjectName, this));
mCommitCallbackRegistrar.add("TopObjects.GetByOwnerName", boost::bind(&LLFloaterTopObjects::onGetByOwnerName, this));
+ mCommitCallbackRegistrar.add("TopObjects.GetByParcelName", boost::bind(&LLFloaterTopObjects::onGetByParcelName, this));
mCommitCallbackRegistrar.add("TopObjects.CommitObjectsList",boost::bind(&LLFloaterTopObjects::onCommitObjectsList, this));
}
@@ -99,21 +100,6 @@ BOOL LLFloaterTopObjects::postBuild()
setDefaultBtn("show_beacon_btn");
- /*
- LLLineEditor* line_editor = getChild<LLLineEditor>("owner_name_editor");
- if (line_editor)
- {
- line_editor->setCommitOnFocusLost(FALSE);
- line_editor->setCommitCallback(onGetByOwnerName, this);
- }
-
- line_editor = getChild<LLLineEditor>("object_name_editor");
- if (line_editor)
- {
- line_editor->setCommitOnFocusLost(FALSE);
- line_editor->setCommitCallback(onGetByObjectName, this);
- }*/
-
mCurrentMode = STAT_REPORT_TOP_SCRIPTS;
mFlags = 0;
mFilter.clear();
@@ -168,9 +154,11 @@ void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data)
F32 score;
std::string name_buf;
std::string owner_buf;
+ std::string parcel_buf("unknown");
F32 mono_score = 0.f;
bool have_extended_data = false;
S32 public_urls = 0;
+ F32 script_memory = 0.f;
msg->getU32Fast(_PREHASH_ReportData, _PREHASH_TaskLocalID, task_local_id, block);
msg->getUUIDFast(_PREHASH_ReportData, _PREHASH_TaskID, task_id, block);
@@ -180,12 +168,18 @@ void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data)
msg->getF32Fast(_PREHASH_ReportData, _PREHASH_Score, score, block);
msg->getStringFast(_PREHASH_ReportData, _PREHASH_TaskName, name_buf, block);
msg->getStringFast(_PREHASH_ReportData, _PREHASH_OwnerName, owner_buf, block);
+
if(msg->has("DataExtended"))
{
have_extended_data = true;
msg->getU32("DataExtended", "TimeStamp", time_stamp, block);
msg->getF32("DataExtended", "MonoScore", mono_score, block);
msg->getS32("DataExtended", "PublicURLs", public_urls, block);
+ if (msg->getSize("DataExtended", "ParcelName") > 0)
+ {
+ msg->getString("DataExtended", "ParcelName", parcel_buf, block);
+ msg->getF32("DataExtended", "Size", script_memory, block);
+ }
}
LLSD element;
@@ -193,50 +187,48 @@ void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data)
element["id"] = task_id;
LLSD columns;
- columns[0]["column"] = "score";
- columns[0]["value"] = llformat("%0.3f", score);
- columns[0]["font"] = "SANSSERIF";
+ S32 column_num = 0;
+ columns[column_num]["column"] = "score";
+ columns[column_num]["value"] = llformat("%0.3f", score);
+ columns[column_num++]["font"] = "SANSSERIF";
- columns[1]["column"] = "name";
- columns[1]["value"] = name_buf;
- columns[1]["font"] = "SANSSERIF";
+ columns[column_num]["column"] = "name";
+ columns[column_num]["value"] = name_buf;
+ columns[column_num++]["font"] = "SANSSERIF";
// Owner names can have trailing spaces sent from server
LLStringUtil::trim(owner_buf);
- if (LLAvatarNameCache::useDisplayNames())
- {
- // ...convert hard-coded name from server to a username
- // *TODO: Send owner_id from server and look up display name
- owner_buf = LLCacheName::buildUsername(owner_buf);
- }
- else
- {
- // ...just strip out legacy "Resident" name
- owner_buf = LLCacheName::cleanFullName(owner_buf);
- }
- columns[2]["column"] = "owner";
- columns[2]["value"] = owner_buf;
- columns[2]["font"] = "SANSSERIF";
-
- columns[3]["column"] = "location";
- columns[3]["value"] = llformat("<%0.1f,%0.1f,%0.1f>", location_x, location_y, location_z);
- columns[3]["font"] = "SANSSERIF";
- columns[4]["column"] = "time";
- columns[4]["type"] = "date";
- columns[4]["value"] = LLDate((time_t)time_stamp);
- columns[4]["font"] = "SANSSERIF";
+ // *TODO: Send owner_id from server and look up display name
+ owner_buf = LLCacheName::buildUsername(owner_buf);
+
+ columns[column_num]["column"] = "owner";
+ columns[column_num]["value"] = owner_buf;
+ columns[column_num++]["font"] = "SANSSERIF";
+
+ columns[column_num]["column"] = "location";
+ columns[column_num]["value"] = llformat("<%0.1f,%0.1f,%0.1f>", location_x, location_y, location_z);
+ columns[column_num++]["font"] = "SANSSERIF";
+
+ columns[column_num]["column"] = "parcel";
+ columns[column_num]["value"] = parcel_buf;
+ columns[column_num++]["font"] = "SANSSERIF";
+
+ columns[column_num]["column"] = "time";
+ columns[column_num]["type"] = "date";
+ columns[column_num]["value"] = LLDate((time_t)time_stamp);
+ columns[column_num++]["font"] = "SANSSERIF";
if (mCurrentMode == STAT_REPORT_TOP_SCRIPTS
&& have_extended_data)
{
- columns[5]["column"] = "mono_time";
- columns[5]["value"] = llformat("%0.3f", mono_score);
- columns[5]["font"] = "SANSSERIF";
+ columns[column_num]["column"] = "memory";
+ columns[column_num]["value"] = llformat("%0.0f", (script_memory / 1000.f));
+ columns[column_num++]["font"] = "SANSSERIF";
- columns[6]["column"] = "URLs";
- columns[6]["value"] = llformat("%d", public_urls);
- columns[6]["font"] = "SANSSERIF";
+ columns[column_num]["column"] = "URLs";
+ columns[column_num]["value"] = llformat("%d", public_urls);
+ columns[column_num++]["font"] = "SANSSERIF";
}
element["columns"] = columns;
list->addElement(element);
@@ -260,18 +252,18 @@ void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data)
{
setTitle(getString("top_scripts_title"));
list->setColumnLabel("score", getString("scripts_score_label"));
- list->setColumnLabel("mono_time", getString("scripts_mono_time_label"));
LLUIString format = getString("top_scripts_text");
format.setArg("[COUNT]", llformat("%d", total_count));
- format.setArg("[TIME]", llformat("%0.1f", mtotalScore));
+ format.setArg("[TIME]", llformat("%0.3f", mtotalScore));
getChild<LLUICtrl>("title_text")->setValue(LLSD(format));
}
else
{
setTitle(getString("top_colliders_title"));
list->setColumnLabel("score", getString("colliders_score_label"));
- list->setColumnLabel("mono_time", "");
+ list->setColumnLabel("URLs", "");
+ list->setColumnLabel("memory", "");
LLUIString format = getString("top_colliders_text");
format.setArg("[COUNT]", llformat("%d", total_count));
getChild<LLUICtrl>("title_text")->setValue(LLSD(format));
@@ -301,6 +293,7 @@ void LLFloaterTopObjects::updateSelectionInfo()
{
getChild<LLUICtrl>("object_name_editor")->setValue(sli->getColumn(1)->getValue().asString());
getChild<LLUICtrl>("owner_name_editor")->setValue(sli->getColumn(2)->getValue().asString());
+ getChild<LLUICtrl>("parcel_name_editor")->setValue(sli->getColumn(4)->getValue().asString());
}
}
@@ -480,6 +473,15 @@ void LLFloaterTopObjects::onGetByOwnerName()
onRefresh();
}
+
+void LLFloaterTopObjects::onGetByParcelName()
+{
+ mFlags = STAT_FILTER_BY_PARCEL_NAME;
+ mFilter = getChild<LLUICtrl>("parcel_name_editor")->getValue().asString();
+ onRefresh();
+}
+
+
void LLFloaterTopObjects::showBeacon()
{
LLScrollListCtrl* list = getChild<LLScrollListCtrl>("objects_list");
diff --git a/indra/newview/llfloatertopobjects.h b/indra/newview/llfloatertopobjects.h
index a608ca20f1..6edc46cf79 100644..100755
--- a/indra/newview/llfloatertopobjects.h
+++ b/indra/newview/llfloatertopobjects.h
@@ -73,9 +73,7 @@ private:
void onGetByOwnerName();
void onGetByObjectName();
-
-// static void onGetByOwnerNameClicked(void* data) { onGetByOwnerName(NULL, data); };
-// static void onGetByObjectNameClicked(void* data) { onGetByObjectName(NULL, data); };
+ void onGetByParcelName();
void showBeacon();
diff --git a/indra/newview/llfloatertos.cpp b/indra/newview/llfloatertos.cpp
index c5df7e16e9..a242b224cd 100644..100755
--- a/indra/newview/llfloatertos.cpp
+++ b/indra/newview/llfloatertos.cpp
@@ -71,9 +71,9 @@ class LLIamHere : public LLHTTPClient::Responder
public:
- static boost::intrusive_ptr< LLIamHere > build( LLFloaterTOS* parent )
+ static LLIamHere* build( LLFloaterTOS* parent )
{
- return boost::intrusive_ptr< LLIamHere >( new LLIamHere( parent ) );
+ return new LLIamHere( parent );
};
virtual void setParent( LLFloaterTOS* parentIn )
@@ -102,7 +102,7 @@ class LLIamHere : public LLHTTPClient::Responder
// this is global and not a class member to keep crud out of the header file
namespace {
- boost::intrusive_ptr< LLIamHere > gResponsePtr = 0;
+ LLPointer< LLIamHere > gResponsePtr = 0;
};
BOOL LLFloaterTOS::postBuild()
diff --git a/indra/newview/llfloatertos.h b/indra/newview/llfloatertos.h
index 8921d11489..8921d11489 100644..100755
--- a/indra/newview/llfloatertos.h
+++ b/indra/newview/llfloatertos.h
diff --git a/indra/newview/llfloatertoybox.cpp b/indra/newview/llfloatertoybox.cpp
index 324afe661f..324afe661f 100644..100755
--- a/indra/newview/llfloatertoybox.cpp
+++ b/indra/newview/llfloatertoybox.cpp
diff --git a/indra/newview/llfloatertoybox.h b/indra/newview/llfloatertoybox.h
index 10aee0e6f5..10aee0e6f5 100644..100755
--- a/indra/newview/llfloatertoybox.h
+++ b/indra/newview/llfloatertoybox.h
diff --git a/indra/newview/llfloatertranslationsettings.cpp b/indra/newview/llfloatertranslationsettings.cpp
index 1a17183efd..33f2c35239 100644..100755
--- a/indra/newview/llfloatertranslationsettings.cpp
+++ b/indra/newview/llfloatertranslationsettings.cpp
@@ -29,7 +29,7 @@
#include "llfloatertranslationsettings.h"
// Viewer includes
-#include "llnearbychatbar.h"
+#include "llfloaterimnearbychat.h"
#include "lltranslate.h"
#include "llviewercontrol.h" // for gSavedSettings
@@ -225,11 +225,10 @@ void LLFloaterTranslationSettings::updateControlsEnabledState()
mGoogleVerifyBtn->setEnabled(on && google_selected &&
!mGoogleKeyVerified && !getEnteredGoogleKey().empty());
- mOKBtn->setEnabled(
- !on || (
- (bing_selected && mBingKeyVerified) ||
- (google_selected && mGoogleKeyVerified)
- ));
+ bool service_verified = (bing_selected && mBingKeyVerified) || (google_selected && mGoogleKeyVerified);
+ gSavedPerAccountSettings.setBOOL("TranslatingEnabled", service_verified);
+
+ mOKBtn->setEnabled(!on || service_verified);
}
void LLFloaterTranslationSettings::verifyKey(int service, const std::string& key, bool alert)
@@ -285,7 +284,16 @@ void LLFloaterTranslationSettings::onBtnGoogleVerify()
verifyKey(LLTranslate::SERVICE_GOOGLE, key);
}
}
+void LLFloaterTranslationSettings::onClose(bool app_quitting)
+{
+ std::string service = gSavedSettings.getString("TranslationService");
+ bool bing_selected = service == "bing";
+ bool google_selected = service == "google";
+
+ bool service_verified = (bing_selected && mBingKeyVerified) || (google_selected && mGoogleKeyVerified);
+ gSavedPerAccountSettings.setBOOL("TranslatingEnabled", service_verified);
+}
void LLFloaterTranslationSettings::onBtnOK()
{
gSavedSettings.setBOOL("TranslateChat", mMachineTranslationCB->getValue().asBoolean());
@@ -293,6 +301,7 @@ void LLFloaterTranslationSettings::onBtnOK()
gSavedSettings.setString("TranslationService", getSelectedService());
gSavedSettings.setString("BingTranslateAPIKey", getEnteredBingKey());
gSavedSettings.setString("GoogleTranslateAPIKey", getEnteredGoogleKey());
- LLNearbyChatBar::getInstance()->showTranslationCheckbox(LLTranslate::isTranslationConfigured());
+ (LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat"))->
+ showTranslationCheckbox(LLTranslate::isTranslationConfigured());
closeFloater(false);
}
diff --git a/indra/newview/llfloatertranslationsettings.h b/indra/newview/llfloatertranslationsettings.h
index 9b47ad72ed..b9bfd6265a 100644..100755
--- a/indra/newview/llfloatertranslationsettings.h
+++ b/indra/newview/llfloatertranslationsettings.h
@@ -44,6 +44,7 @@ public:
void setBingVerified(bool ok, bool alert);
void setGoogleVerified(bool ok, bool alert);
+ void onClose(bool app_quitting);
private:
std::string getSelectedService() const;
diff --git a/indra/newview/llfloateruipreview.cpp b/indra/newview/llfloateruipreview.cpp
index d741b5b133..0106a1615d 100644..100755
--- a/indra/newview/llfloateruipreview.cpp
+++ b/indra/newview/llfloateruipreview.cpp
@@ -137,7 +137,7 @@ public:
virtual ~LLFloaterUIPreview();
std::string getLocStr(S32 ID); // fetches the localization string based on what is selected in the drop-down menu
- void displayFloater(BOOL click, S32 ID, bool save = false); // needs to be public so live file can call it when it finds an update
+ void displayFloater(BOOL click, S32 ID); // needs to be public so live file can call it when it finds an update
/*virtual*/ BOOL postBuild();
/*virtual*/ void onClose(bool app_quitting);
@@ -291,7 +291,8 @@ LLLocalizationResetForcer::LLLocalizationResetForcer(LLFloaterUIPreview* floater
{
mSavedLocalization = LLUI::sSettingGroups["config"]->getString("Language"); // save current localization setting
LLUI::sSettingGroups["config"]->setString("Language", floater->getLocStr(ID));// hack language to be the one we want to preview floaters in
- LLUI::setupPaths(); // forcibly reset XUI paths with this new language
+ // forcibly reset XUI paths with this new language
+ gDirUtilp->setSkinFolder(gDirUtilp->getSkinFolder(), floater->getLocStr(ID));
}
// Actually reset in destructor
@@ -299,7 +300,8 @@ LLLocalizationResetForcer::LLLocalizationResetForcer(LLFloaterUIPreview* floater
LLLocalizationResetForcer::~LLLocalizationResetForcer()
{
LLUI::sSettingGroups["config"]->setString("Language", mSavedLocalization); // reset language to what it was before we changed it
- LLUI::setupPaths(); // forcibly reset XUI paths with this new language
+ // forcibly reset XUI paths with this new language
+ gDirUtilp->setSkinFolder(gDirUtilp->getSkinFolder(), mSavedLocalization);
}
// Live file constructor
@@ -488,7 +490,7 @@ BOOL LLFloaterUIPreview::postBuild()
{
if((found = iter.next(language_directory))) // get next directory
{
- std::string full_path = xui_dir + language_directory;
+ std::string full_path = gDirUtilp->add(xui_dir, language_directory);
if(LLFile::isfile(full_path.c_str())) // if it's not a directory, skip it
{
continue;
@@ -773,7 +775,8 @@ void LLFloaterUIPreview::onClickDisplayFloater(S32 caller_id)
// Saves the current floater/panel
void LLFloaterUIPreview::onClickSaveFloater(S32 caller_id)
{
- displayFloater(TRUE, caller_id, true);
+ displayFloater(TRUE, caller_id);
+ popupAndPrintWarning("Save-floater functionality removed, use XML schema to clean up XUI files");
}
// Saves all floater/panels
@@ -784,25 +787,15 @@ void LLFloaterUIPreview::onClickSaveAll(S32 caller_id)
for (int index = 0; index < listSize; index++)
{
mFileList->selectNthItem(index);
- displayFloater(TRUE, caller_id, true);
+ displayFloater(TRUE, caller_id);
}
-}
-
-// Given path to floater or panel XML file "filename.xml",
-// returns "filename_new.xml"
-static std::string append_new_to_xml_filename(const std::string& path)
-{
- std::string full_filename = gDirUtilp->findSkinnedFilename(LLUI::getLocalizedSkinPath(), path);
- std::string::size_type extension_pos = full_filename.rfind(".xml");
- full_filename.resize(extension_pos);
- full_filename += "_new.xml";
- return full_filename;
+ popupAndPrintWarning("Save-floater functionality removed, use XML schema to clean up XUI files");
}
// Actually display the floater
// Only set up a new live file if this came from a click (at which point there should be no existing live file), rather than from the live file's update itself;
// otherwise, we get an infinite loop as the live file keeps recreating itself. That means this function is generally called twice.
-void LLFloaterUIPreview::displayFloater(BOOL click, S32 ID, bool save)
+void LLFloaterUIPreview::displayFloater(BOOL click, S32 ID)
{
// Convince UI that we're in a different language (the one selected on the drop-down menu)
LLLocalizationResetForcer reset_forcer(this, ID); // save old language in reset forcer object (to be reset upon destruction when it falls out of scope)
@@ -843,48 +836,13 @@ void LLFloaterUIPreview::displayFloater(BOOL click, S32 ID, bool save)
if(!strncmp(path.c_str(),"floater_",8)
|| !strncmp(path.c_str(), "inspect_", 8)) // if it's a floater
{
- if (save)
- {
- LLXMLNodePtr floater_write = new LLXMLNode();
- (*floaterp)->buildFromFile(path, floater_write); // just build it
-
- if (!floater_write->isNull())
- {
- std::string full_filename = append_new_to_xml_filename(path);
- LLFILE* floater_temp = LLFile::fopen(full_filename.c_str(), "w");
- LLXMLNode::writeHeaderToFile(floater_temp);
- const bool use_type_decorations = false;
- floater_write->writeToFile(floater_temp, std::string(), use_type_decorations);
- fclose(floater_temp);
- }
- }
- else
- {
- (*floaterp)->buildFromFile(path); // just build it
- (*floaterp)->openFloater((*floaterp)->getKey());
- (*floaterp)->setCanResize((*floaterp)->isResizable());
- }
-
+ (*floaterp)->buildFromFile(path); // just build it
+ (*floaterp)->openFloater((*floaterp)->getKey());
+ (*floaterp)->setCanResize((*floaterp)->isResizable());
}
else if (!strncmp(path.c_str(),"menu_",5)) // if it's a menu
{
- if (save)
- {
- LLXMLNodePtr menu_write = new LLXMLNode();
- LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>(path, gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance(), menu_write);
-
- if (!menu_write->isNull())
- {
- std::string full_filename = append_new_to_xml_filename(path);
- LLFILE* menu_temp = LLFile::fopen(full_filename.c_str(), "w");
- LLXMLNode::writeHeaderToFile(menu_temp);
- const bool use_type_decorations = false;
- menu_write->writeToFile(menu_temp, std::string(), use_type_decorations);
- fclose(menu_temp);
- }
-
- delete menu;
- }
+ // former 'save' processing excised
}
else // if it is a panel...
{
@@ -896,39 +854,20 @@ void LLFloaterUIPreview::displayFloater(BOOL click, S32 ID, bool save)
LLPanel::Params panel_params;
LLPanel* panel = LLUICtrlFactory::create<LLPanel>(panel_params); // create a new panel
- if (save)
- {
- LLXMLNodePtr panel_write = new LLXMLNode();
- panel->buildFromFile(path, panel_write); // build it
-
- if (!panel_write->isNull())
- {
- std::string full_filename = append_new_to_xml_filename(path);
- LLFILE* panel_temp = LLFile::fopen(full_filename.c_str(), "w");
- LLXMLNode::writeHeaderToFile(panel_temp);
- const bool use_type_decorations = false;
- panel_write->writeToFile(panel_temp, std::string(), use_type_decorations);
- fclose(panel_temp);
- }
- }
- else
- {
- panel->buildFromFile(path); // build it
- LLRect new_size = panel->getRect(); // get its rectangle
- panel->setOrigin(2,2); // reset its origin point so it's not offset by -left or other XUI attributes
- (*floaterp)->setTitle(path); // use the file name as its title, since panels have no guaranteed meaningful name attribute
- panel->setUseBoundingRect(TRUE); // enable the use of its outer bounding rect (normally disabled because it's O(n) on the number of sub-elements)
- panel->updateBoundingRect(); // update bounding rect
- LLRect bounding_rect = panel->getBoundingRect(); // get the bounding rect
- LLRect new_rect = panel->getRect(); // get the panel's rect
- new_rect.unionWith(bounding_rect); // union them to make sure we get the biggest one possible
- LLRect floater_rect = new_rect;
- floater_rect.stretch(4, 4);
- (*floaterp)->reshape(floater_rect.getWidth(), floater_rect.getHeight() + floater_header_size); // reshape floater to match the union rect's dimensions
- panel->reshape(new_rect.getWidth(), new_rect.getHeight()); // reshape panel to match the union rect's dimensions as well (both are needed)
- (*floaterp)->addChild(panel); // add panel as child
- (*floaterp)->openFloater(); // open floater (needed?)
- }
+ panel->buildFromFile(path); // build it
+ panel->setOrigin(2,2); // reset its origin point so it's not offset by -left or other XUI attributes
+ (*floaterp)->setTitle(path); // use the file name as its title, since panels have no guaranteed meaningful name attribute
+ panel->setUseBoundingRect(TRUE); // enable the use of its outer bounding rect (normally disabled because it's O(n) on the number of sub-elements)
+ panel->updateBoundingRect(); // update bounding rect
+ LLRect bounding_rect = panel->getBoundingRect(); // get the bounding rect
+ LLRect new_rect = panel->getRect(); // get the panel's rect
+ new_rect.unionWith(bounding_rect); // union them to make sure we get the biggest one possible
+ LLRect floater_rect = new_rect;
+ floater_rect.stretch(4, 4);
+ (*floaterp)->reshape(floater_rect.getWidth(), floater_rect.getHeight() + floater_header_size); // reshape floater to match the union rect's dimensions
+ panel->reshape(new_rect.getWidth(), new_rect.getHeight()); // reshape panel to match the union rect's dimensions as well (both are needed)
+ (*floaterp)->addChild(panel); // add panel as child
+ (*floaterp)->openFloater(); // open floater (needed?)
}
if(ID == 1)
@@ -964,7 +903,7 @@ void LLFloaterUIPreview::displayFloater(BOOL click, S32 ID, bool save)
(*floaterp)->center();
addDependentFloater(*floaterp);
- if(click && ID == 1 && !save)
+ if(click && ID == 1)
{
// set up live file to track it
if(mLiveFile)
diff --git a/indra/newview/llfloateruipreview.h b/indra/newview/llfloateruipreview.h
index 910ab7ebc9..910ab7ebc9 100644..100755
--- a/indra/newview/llfloateruipreview.h
+++ b/indra/newview/llfloateruipreview.h
diff --git a/indra/newview/llfloaterurlentry.cpp b/indra/newview/llfloaterurlentry.cpp
index 151cd2a1cd..e85d849c9a 100644..100755
--- a/indra/newview/llfloaterurlentry.cpp
+++ b/indra/newview/llfloaterurlentry.cpp
@@ -219,7 +219,8 @@ void LLFloaterURLEntry::onBtnOK( void* userdata )
}
// Discover the MIME type only for "http" scheme.
- if(scheme == "http" || scheme == "https")
+ if(!media_url.empty() &&
+ (scheme == "http" || scheme == "https"))
{
LLHTTPClient::getHeaderOnly( media_url,
new LLMediaTypeResponder(self->getHandle()));
diff --git a/indra/newview/llfloaterurlentry.h b/indra/newview/llfloaterurlentry.h
index dfb49fe5ac..dfb49fe5ac 100644..100755
--- a/indra/newview/llfloaterurlentry.h
+++ b/indra/newview/llfloaterurlentry.h
diff --git a/indra/newview/llfloatervoiceeffect.cpp b/indra/newview/llfloatervoiceeffect.cpp
index 227720bee3..227720bee3 100644..100755
--- a/indra/newview/llfloatervoiceeffect.cpp
+++ b/indra/newview/llfloatervoiceeffect.cpp
diff --git a/indra/newview/llfloatervoiceeffect.h b/indra/newview/llfloatervoiceeffect.h
index 4d432c46cc..4d432c46cc 100644..100755
--- a/indra/newview/llfloatervoiceeffect.h
+++ b/indra/newview/llfloatervoiceeffect.h
diff --git a/indra/newview/llfloatervoicevolume.cpp b/indra/newview/llfloatervoicevolume.cpp
new file mode 100755
index 0000000000..38446e46df
--- /dev/null
+++ b/indra/newview/llfloatervoicevolume.cpp
@@ -0,0 +1,220 @@
+/**
+ * @file llfloatervoicevolume.cpp
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 "llfloatervoicevolume.h"
+
+// Linden libraries
+#include "llavatarname.h"
+#include "llavatarnamecache.h"
+#include "llfloater.h"
+#include "llfloaterreg.h"
+#include "lltextbox.h"
+
+// viewer files
+#include "llagent.h"
+#include "llavataractions.h"
+#include "llinspect.h"
+#include "lltransientfloatermgr.h"
+#include "llvoiceclient.h"
+
+class LLAvatarName;
+
+//////////////////////////////////////////////////////////////////////////////
+// LLFloaterVoiceVolume
+//////////////////////////////////////////////////////////////////////////////
+
+// Avatar Inspector, a small information window used when clicking
+// on avatar names in the 2D UI and in the ambient inspector widget for
+// the 3D world.
+class LLFloaterVoiceVolume : public LLInspect, LLTransientFloater
+{
+ friend class LLFloaterReg;
+
+public:
+ // avatar_id - Avatar ID for which to show information
+ // Inspector will be positioned relative to current mouse position
+ LLFloaterVoiceVolume(const LLSD& avatar_id);
+ virtual ~LLFloaterVoiceVolume();
+
+ /*virtual*/ BOOL postBuild(void);
+
+ // Because floater is single instance, need to re-parse data on each spawn
+ // (for example, inspector about same avatar but in different position)
+ /*virtual*/ void onOpen(const LLSD& avatar_id);
+
+ /*virtual*/ LLTransientFloaterMgr::ETransientGroup getGroup() { return LLTransientFloaterMgr::GLOBAL; }
+
+private:
+ // Set the volume slider to this user's current client-side volume setting,
+ // hiding/disabling if the user is not nearby.
+ void updateVolumeControls();
+
+ void onClickMuteVolume();
+ void onVolumeChange(const LLSD& data);
+ void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name);
+
+private:
+ LLUUID mAvatarID;
+ // Need avatar name information to spawn friend add request
+ LLAvatarName mAvatarName;
+ boost::signals2::connection mAvatarNameCacheConnection;
+};
+
+LLFloaterVoiceVolume::LLFloaterVoiceVolume(const LLSD& sd)
+: LLInspect(LLSD()) // single_instance, doesn't really need key
+, mAvatarID() // set in onOpen() *Note: we used to show partner's name but we dont anymore --angela 3rd Dec*
+, mAvatarName()
+, mAvatarNameCacheConnection()
+{
+ LLTransientFloaterMgr::getInstance()->addControlView(LLTransientFloaterMgr::GLOBAL, this);
+ LLTransientFloater::init(this);
+}
+
+LLFloaterVoiceVolume::~LLFloaterVoiceVolume()
+{
+ if (mAvatarNameCacheConnection.connected())
+ {
+ mAvatarNameCacheConnection.disconnect();
+ }
+ LLTransientFloaterMgr::getInstance()->removeControlView(this);
+}
+
+/*virtual*/
+BOOL LLFloaterVoiceVolume::postBuild(void)
+{
+ getChild<LLUICtrl>("mute_btn")->setCommitCallback(
+ boost::bind(&LLFloaterVoiceVolume::onClickMuteVolume, this) );
+
+ getChild<LLUICtrl>("volume_slider")->setCommitCallback(
+ boost::bind(&LLFloaterVoiceVolume::onVolumeChange, this, _2));
+
+ return TRUE;
+}
+
+
+// Multiple calls to showInstance("floater_voice_volume", foo) will provide different
+// LLSD for foo, which we will catch here.
+//virtual
+void LLFloaterVoiceVolume::onOpen(const LLSD& data)
+{
+ // Start open animation
+ LLInspect::onOpen(data);
+
+ // Extract appropriate avatar id
+ mAvatarID = data["avatar_id"];
+
+ LLUI::positionViewNearMouse(this);
+
+ getChild<LLUICtrl>("avatar_name")->setValue("");
+ updateVolumeControls();
+
+ if (mAvatarNameCacheConnection.connected())
+ {
+ mAvatarNameCacheConnection.disconnect();
+ }
+ mAvatarNameCacheConnection = LLAvatarNameCache::get(mAvatarID, boost::bind(&LLFloaterVoiceVolume::onAvatarNameCache, this, _1, _2));
+}
+
+void LLFloaterVoiceVolume::updateVolumeControls()
+{
+ bool voice_enabled = LLVoiceClient::getInstance()->getVoiceEnabled(mAvatarID);
+
+ LLUICtrl* mute_btn = getChild<LLUICtrl>("mute_btn");
+ LLUICtrl* volume_slider = getChild<LLUICtrl>("volume_slider");
+
+ // Do not display volume slider and mute button if it
+ // is ourself or we are not in a voice channel together
+ if (!voice_enabled || (mAvatarID == gAgent.getID()))
+ {
+ mute_btn->setVisible(false);
+ volume_slider->setVisible(false);
+ }
+ else
+ {
+ mute_btn->setVisible(true);
+ volume_slider->setVisible(true);
+
+ // By convention, we only display and toggle voice mutes, not all mutes
+ bool is_muted = LLAvatarActions::isVoiceMuted(mAvatarID);
+ bool is_linden = LLStringUtil::endsWith(mAvatarName.getUserName(), " Linden");
+
+ mute_btn->setEnabled(!is_linden);
+ mute_btn->setValue(is_muted);
+
+ volume_slider->setEnabled(!is_muted);
+
+ F32 volume;
+ if (is_muted)
+ {
+ // it's clearer to display their volume as zero
+ volume = 0.f;
+ }
+ else
+ {
+ // actual volume
+ volume = LLVoiceClient::getInstance()->getUserVolume(mAvatarID);
+ }
+ volume_slider->setValue((F64)volume);
+ }
+
+}
+
+void LLFloaterVoiceVolume::onClickMuteVolume()
+{
+ LLAvatarActions::toggleMuteVoice(mAvatarID);
+ updateVolumeControls();
+}
+
+void LLFloaterVoiceVolume::onVolumeChange(const LLSD& data)
+{
+ F32 volume = (F32)data.asReal();
+ LLVoiceClient::getInstance()->setUserVolume(mAvatarID, volume);
+}
+
+void LLFloaterVoiceVolume::onAvatarNameCache(
+ const LLUUID& agent_id,
+ const LLAvatarName& av_name)
+{
+ mAvatarNameCacheConnection.disconnect();
+
+ if (agent_id != mAvatarID)
+ {
+ return;
+ }
+
+ getChild<LLUICtrl>("avatar_name")->setValue(av_name.getCompleteName());
+ mAvatarName = av_name;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// LLFloaterVoiceVolumeUtil
+//////////////////////////////////////////////////////////////////////////////
+void LLFloaterVoiceVolumeUtil::registerFloater()
+{
+ LLFloaterReg::add("floater_voice_volume", "floater_voice_volume.xml",
+ &LLFloaterReg::build<LLFloaterVoiceVolume>);
+}
diff --git a/indra/newview/llfloatervoicevolume.h b/indra/newview/llfloatervoicevolume.h
new file mode 100755
index 0000000000..8fcf7f250b
--- /dev/null
+++ b/indra/newview/llfloatervoicevolume.h
@@ -0,0 +1,35 @@
+/**
+ * @file llfloatervoicevolume.h
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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_LLFLOATERVOICEVOLUME_H
+#define LL_LLFLOATERVOICEVOLUME_H
+
+namespace LLFloaterVoiceVolumeUtil
+{
+ // Register with LLFloaterReg
+ void registerFloater();
+}
+
+#endif // LL_LLFLOATERVOICEVOLUME_H
diff --git a/indra/newview/llfloaterwebcontent.cpp b/indra/newview/llfloaterwebcontent.cpp
index 3fe2518de6..76b73fcf29 100644..100755
--- a/indra/newview/llfloaterwebcontent.cpp
+++ b/indra/newview/llfloaterwebcontent.cpp
@@ -29,6 +29,7 @@
#include "llcombobox.h"
#include "lliconctrl.h"
#include "llfloaterreg.h"
+#include "llfacebookconnect.h"
#include "lllayoutstack.h"
#include "llpluginclassmedia.h"
#include "llprogressbar.h"
@@ -46,7 +47,8 @@ LLFloaterWebContent::_Params::_Params()
id("id"),
window_class("window_class", "web_content"),
show_chrome("show_chrome", true),
- allow_address_entry("allow_address_entry", true),
+ allow_address_entry("allow_address_entry", true),
+ allow_back_forward_navigation("allow_back_forward_navigation", true),
preferred_media_size("preferred_media_size"),
trusted_content("trusted_content", false),
show_page_title("show_page_title", true)
@@ -65,7 +67,11 @@ LLFloaterWebContent::LLFloaterWebContent( const Params& params )
mBtnReload(NULL),
mBtnStop(NULL),
mUUID(params.id()),
- mShowPageTitle(params.show_page_title)
+ mShowPageTitle(params.show_page_title),
+ mAllowNavigation(true),
+ mCurrentURL(""),
+ mDisplayURL(""),
+ mSecureURL(false)
{
mCommitCallbackRegistrar.add( "WebContent.Back", boost::bind( &LLFloaterWebContent::onClickBack, this ));
mCommitCallbackRegistrar.add( "WebContent.Forward", boost::bind( &LLFloaterWebContent::onClickForward, this ));
@@ -97,7 +103,7 @@ BOOL LLFloaterWebContent::postBuild()
// cache image for secure browsing
mSecureLockIcon = getChild< LLIconCtrl >("media_secure_lock_flag");
-
+
// initialize the URL history using the system URL History manager
initializeURLHistory();
@@ -243,6 +249,7 @@ void LLFloaterWebContent::open_media(const Params& p)
getChild<LLLayoutPanel>("status_bar")->setVisible(p.show_chrome);
getChild<LLLayoutPanel>("nav_controls")->setVisible(p.show_chrome);
bool address_entry_enabled = p.allow_address_entry && !p.trusted_content;
+ mAllowNavigation = p.allow_back_forward_navigation;
getChildView("address")->setEnabled(address_entry_enabled);
getChildView("popexternal")->setEnabled(address_entry_enabled);
@@ -287,6 +294,16 @@ void LLFloaterWebContent::onOpen(const LLSD& key)
//virtual
void LLFloaterWebContent::onClose(bool app_quitting)
{
+ // If we close the web browsing window showing the facebook login, we need to signal to this object that the connection will not happen
+ LLFloater* fbc_web = LLFloaterReg::getInstance("fbc_web");
+ if (fbc_web == this)
+ {
+ if (!LLFacebookConnect::instance().isConnected())
+ {
+ LLFacebookConnect::instance().setConnectionState(LLFacebookConnect::FB_CONNECTION_FAILED);
+ }
+ }
+
LLViewerMedia::proxyWindowClosed(mUUID);
destroy();
}
@@ -295,8 +312,11 @@ void LLFloaterWebContent::onClose(bool app_quitting)
void LLFloaterWebContent::draw()
{
// this is asynchronous so we need to keep checking
- mBtnBack->setEnabled( mWebBrowser->canNavigateBack() );
- mBtnForward->setEnabled( mWebBrowser->canNavigateForward() );
+ mBtnBack->setEnabled( mWebBrowser->canNavigateBack() && mAllowNavigation);
+ mBtnForward->setEnabled( mWebBrowser->canNavigateForward() && mAllowNavigation);
+
+ // Show/hide the lock icon
+ mSecureLockIcon->setVisible(mSecureURL && !mAddressCombo->hasFocus());
LLFloater::draw();
}
@@ -342,19 +362,8 @@ void LLFloaterWebContent::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent
// we populate the status bar with URLs as they change so clear it now we're done
const std::string end_str = "";
mStatusBarText->setText( end_str );
-
- // decide if secure browsing icon should be displayed
- std::string prefix = std::string("https://");
- std::string test_prefix = mCurrentURL.substr(0, prefix.length());
- LLStringUtil::toLower(test_prefix);
- if(test_prefix == prefix)
- {
- mSecureLockIcon->setVisible(true);
- }
- else
- {
- mSecureLockIcon->setVisible(false);
- }
+ mAddressCombo->setLeftTextPadding(22);
+ mAddressCombo->setLeftTextPadding(2);
}
else if(event == MEDIA_EVENT_CLOSE_REQUEST)
{
@@ -397,15 +406,40 @@ void LLFloaterWebContent::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent
void LLFloaterWebContent::set_current_url(const std::string& url)
{
- mCurrentURL = url;
-
- // serialize url history into the system URL History manager
- LLURLHistory::removeURL("browser", mCurrentURL);
- LLURLHistory::addURL("browser", mCurrentURL);
-
- mAddressCombo->remove( mCurrentURL );
- mAddressCombo->add( mCurrentURL );
- mAddressCombo->selectByValue( mCurrentURL );
+ if (!url.empty())
+ {
+ if (!mCurrentURL.empty())
+ {
+ // Clean up the current browsing list to show true URL
+ mAddressCombo->remove(mDisplayURL);
+ mAddressCombo->add(mCurrentURL);
+ }
+
+ // Update current URL
+ mCurrentURL = url;
+ LLStringUtil::trim(mCurrentURL);
+
+ // Serialize url history into the system URL History manager
+ LLURLHistory::removeURL("browser", mCurrentURL);
+ LLURLHistory::addURL("browser", mCurrentURL);
+
+ // Check if this is a secure URL
+ static const std::string secure_prefix = std::string("https://");
+ std::string prefix = mCurrentURL.substr(0, secure_prefix.length());
+ LLStringUtil::toLower(prefix);
+ mSecureURL = (prefix == secure_prefix);
+
+ // Hack : we move the text a bit to make space for the lock icon in the secure URL case
+ mDisplayURL = (mSecureURL ? " " + mCurrentURL : mCurrentURL);
+
+ // Clean up browsing list (prevent dupes) and add/select the new URL to it
+ mAddressCombo->remove(mCurrentURL);
+ mAddressCombo->add(mDisplayURL);
+ mAddressCombo->selectByValue(mDisplayURL);
+
+ // Set the focus back to the web page. When setting the url, there's no point to leave the focus anywhere else.
+ mWebBrowser->setFocus(TRUE);
+ }
}
void LLFloaterWebContent::onClickForward()
@@ -449,6 +483,7 @@ void LLFloaterWebContent::onEnterAddress()
// make sure there is at least something there.
// (perhaps this test should be for minimum length of a URL)
std::string url = mAddressCombo->getValue().asString();
+ LLStringUtil::trim(url);
if ( url.length() > 0 )
{
mWebBrowser->navigateTo( url, "text/html");
@@ -460,6 +495,7 @@ void LLFloaterWebContent::onPopExternal()
// make sure there is at least something there.
// (perhaps this test should be for minimum length of a URL)
std::string url = mAddressCombo->getValue().asString();
+ LLStringUtil::trim(url);
if ( url.length() > 0 )
{
LLWeb::loadURLExternal( url );
diff --git a/indra/newview/llfloaterwebcontent.h b/indra/newview/llfloaterwebcontent.h
index cfc87e9015..f22940cd07 100644..100755
--- a/indra/newview/llfloaterwebcontent.h
+++ b/indra/newview/llfloaterwebcontent.h
@@ -43,6 +43,7 @@ class LLFloaterWebContent :
public LLInstanceTracker<LLFloaterWebContent, std::string>
{
public:
+
typedef LLInstanceTracker<LLFloaterWebContent, std::string> instance_tracker_t;
LOG_CLASS(LLFloaterWebContent);
@@ -54,6 +55,7 @@ public:
id;
Optional<bool> show_chrome,
allow_address_entry,
+ allow_back_forward_navigation,
trusted_content,
show_page_title;
Optional<LLRect> preferred_media_size;
@@ -105,9 +107,12 @@ protected:
LLView* mBtnReload;
LLView* mBtnStop;
- std::string mCurrentURL;
+ std::string mCurrentURL; // Current URL
+ std::string mDisplayURL; // URL being displayed in the address bar (can differ by trailing / leading space)
std::string mUUID;
bool mShowPageTitle;
+ bool mAllowNavigation;
+ bool mSecureURL; // true when the current url is prefixed "https://"
};
#endif // LL_LLFLOATERWEBCONTENT_H
diff --git a/indra/newview/llfloaterwebprofile.cpp b/indra/newview/llfloaterwebprofile.cpp
index c41f6f148f..c41f6f148f 100644..100755
--- a/indra/newview/llfloaterwebprofile.cpp
+++ b/indra/newview/llfloaterwebprofile.cpp
diff --git a/indra/newview/llfloaterwebprofile.h b/indra/newview/llfloaterwebprofile.h
index 4c355e401b..4c355e401b 100644..100755
--- a/indra/newview/llfloaterwebprofile.h
+++ b/indra/newview/llfloaterwebprofile.h
diff --git a/indra/newview/llfloaterwhitelistentry.cpp b/indra/newview/llfloaterwhitelistentry.cpp
index 2a499f681b..2a499f681b 100644..100755
--- a/indra/newview/llfloaterwhitelistentry.cpp
+++ b/indra/newview/llfloaterwhitelistentry.cpp
diff --git a/indra/newview/llfloaterwhitelistentry.h b/indra/newview/llfloaterwhitelistentry.h
index deab49c523..deab49c523 100644..100755
--- a/indra/newview/llfloaterwhitelistentry.h
+++ b/indra/newview/llfloaterwhitelistentry.h
diff --git a/indra/newview/llfloaterwindowsize.cpp b/indra/newview/llfloaterwindowsize.cpp
index ec161018b8..ec161018b8 100644..100755
--- a/indra/newview/llfloaterwindowsize.cpp
+++ b/indra/newview/llfloaterwindowsize.cpp
diff --git a/indra/newview/llfloaterwindowsize.h b/indra/newview/llfloaterwindowsize.h
index a71e5e273c..a71e5e273c 100644..100755
--- a/indra/newview/llfloaterwindowsize.h
+++ b/indra/newview/llfloaterwindowsize.h
diff --git a/indra/newview/llfloaterworldmap.h b/indra/newview/llfloaterworldmap.h
index e3b83b2579..e3b83b2579 100644..100755
--- a/indra/newview/llfloaterworldmap.h
+++ b/indra/newview/llfloaterworldmap.h
diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp
deleted file mode 100644
index 1fa194ab19..0000000000
--- a/indra/newview/llfolderview.cpp
+++ /dev/null
@@ -1,2624 +0,0 @@
-/**
- * @file llfolderview.cpp
- * @brief Implementation of the folder view collection of classes.
- *
- * $LicenseInfo:firstyear=2001&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 "llviewerprecompiledheaders.h"
-
-#include "llfolderview.h"
-
-#include "llcallbacklist.h"
-#include "llinventorybridge.h"
-#include "llclipboard.h" // *TODO: remove this once hack below gone.
-#include "llinventoryfilter.h"
-#include "llinventoryfunctions.h"
-#include "llinventorymodelbackgroundfetch.h"
-#include "llinventorypanel.h"
-#include "llfoldertype.h"
-#include "llfloaterinventory.h"// hacked in for the bonus context menu items.
-#include "llkeyboard.h"
-#include "lllineeditor.h"
-#include "llmenugl.h"
-#include "llpanel.h"
-#include "llpreview.h"
-#include "llscrollcontainer.h" // hack to allow scrolling
-#include "lltooldraganddrop.h"
-#include "lltrans.h"
-#include "llui.h"
-#include "llviewertexture.h"
-#include "llviewertexturelist.h"
-#include "llviewerjointattachment.h"
-#include "llviewermenu.h"
-#include "lluictrlfactory.h"
-#include "llviewercontrol.h"
-#include "llviewerfoldertype.h"
-#include "llviewerwindow.h"
-#include "llvoavatar.h"
-#include "llfloaterproperties.h"
-#include "llnotificationsutil.h"
-
-// Linden library includes
-#include "lldbstrings.h"
-#include "llfocusmgr.h"
-#include "llfontgl.h"
-#include "llgl.h"
-#include "llrender.h"
-#include "llinventory.h"
-
-// Third-party library includes
-#include <algorithm>
-
-///----------------------------------------------------------------------------
-/// Local function declarations, constants, enums, and typedefs
-///----------------------------------------------------------------------------
-
-const S32 RENAME_WIDTH_PAD = 4;
-const S32 RENAME_HEIGHT_PAD = 1;
-const S32 AUTO_OPEN_STACK_DEPTH = 16;
-const S32 MIN_ITEM_WIDTH_VISIBLE = LLFolderViewItem::ICON_WIDTH
- + LLFolderViewItem::ICON_PAD
- + LLFolderViewItem::ARROW_SIZE
- + LLFolderViewItem::TEXT_PAD
- + /*first few characters*/ 40;
-const S32 MINIMUM_RENAMER_WIDTH = 80;
-
-// *TODO: move in params in xml if necessary. Requires modification of LLFolderView & LLInventoryPanel Params.
-const S32 STATUS_TEXT_HPAD = 6;
-const S32 STATUS_TEXT_VPAD = 8;
-
-enum {
- SIGNAL_NO_KEYBOARD_FOCUS = 1,
- SIGNAL_KEYBOARD_FOCUS = 2
-};
-
-F32 LLFolderView::sAutoOpenTime = 1.f;
-
-void delete_selected_item(void* user_data);
-void copy_selected_item(void* user_data);
-void open_selected_items(void* user_data);
-void properties_selected_items(void* user_data);
-void paste_items(void* user_data);
-
-
-//---------------------------------------------------------------------------
-
-// Tells all folders in a folderview to sort their items
-// (and only their items, not folders) by a certain function.
-class LLSetItemSortFunction : public LLFolderViewFunctor
-{
-public:
- LLSetItemSortFunction(U32 ordering)
- : mSortOrder(ordering) {}
- virtual ~LLSetItemSortFunction() {}
- virtual void doFolder(LLFolderViewFolder* folder);
- virtual void doItem(LLFolderViewItem* item);
-
- U32 mSortOrder;
-};
-
-
-// Set the sort order.
-void LLSetItemSortFunction::doFolder(LLFolderViewFolder* folder)
-{
- folder->setItemSortOrder(mSortOrder);
-}
-
-// Do nothing.
-void LLSetItemSortFunction::doItem(LLFolderViewItem* item)
-{
- return;
-}
-
-//---------------------------------------------------------------------------
-
-// Tells all folders in a folderview to close themselves
-// For efficiency, calls setOpenArrangeRecursively().
-// The calling function must then call:
-// LLFolderView* root = getRoot();
-// if( root )
-// {
-// root->arrange( NULL, NULL );
-// root->scrollToShowSelection();
-// }
-// to patch things up.
-class LLCloseAllFoldersFunctor : public LLFolderViewFunctor
-{
-public:
- LLCloseAllFoldersFunctor(BOOL close) { mOpen = !close; }
- virtual ~LLCloseAllFoldersFunctor() {}
- virtual void doFolder(LLFolderViewFolder* folder);
- virtual void doItem(LLFolderViewItem* item);
-
- BOOL mOpen;
-};
-
-
-// Set the sort order.
-void LLCloseAllFoldersFunctor::doFolder(LLFolderViewFolder* folder)
-{
- folder->setOpenArrangeRecursively(mOpen);
-}
-
-// Do nothing.
-void LLCloseAllFoldersFunctor::doItem(LLFolderViewItem* item)
-{ }
-
-///----------------------------------------------------------------------------
-/// Class LLFolderViewScrollContainer
-///----------------------------------------------------------------------------
-
-// virtual
-const LLRect LLFolderViewScrollContainer::getScrolledViewRect() const
-{
- LLRect rect = LLRect::null;
- if (mScrolledView)
- {
- LLFolderView* folder_view = dynamic_cast<LLFolderView*>(mScrolledView);
- if (folder_view)
- {
- S32 height = folder_view->mRunningHeight;
-
- rect = mScrolledView->getRect();
- rect.setLeftTopAndSize(rect.mLeft, rect.mTop, rect.getWidth(), height);
- }
- }
-
- return rect;
-}
-
-LLFolderViewScrollContainer::LLFolderViewScrollContainer(const LLScrollContainer::Params& p)
-: LLScrollContainer(p)
-{}
-
-///----------------------------------------------------------------------------
-/// Class LLFolderView
-///----------------------------------------------------------------------------
-LLFolderView::Params::Params()
-: task_id("task_id"),
- title("title"),
- use_label_suffix("use_label_suffix"),
- allow_multiselect("allow_multiselect", true),
- show_empty_message("show_empty_message", true),
- show_load_status("show_load_status", true),
- use_ellipses("use_ellipses", false)
-{
-}
-
-
-// Default constructor
-LLFolderView::LLFolderView(const Params& p)
-: LLFolderViewFolder(p),
- mRunningHeight(0),
- mScrollContainer( NULL ),
- mPopupMenuHandle(),
- mAllowMultiSelect(p.allow_multiselect),
- mShowEmptyMessage(p.show_empty_message),
- mShowFolderHierarchy(FALSE),
- mSourceID(p.task_id),
- mRenameItem( NULL ),
- mNeedsScroll( FALSE ),
- mUseLabelSuffix(p.use_label_suffix),
- mPinningSelectedItem(FALSE),
- mNeedsAutoSelect( FALSE ),
- mAutoSelectOverride(FALSE),
- mNeedsAutoRename(FALSE),
- mDebugFilters(FALSE),
- mSortOrder(LLInventoryFilter::SO_FOLDERS_BY_NAME), // This gets overridden by a pref immediately
- mFilter( new LLInventoryFilter(p.title) ),
- mShowSelectionContext(FALSE),
- mShowSingleSelection(FALSE),
- mArrangeGeneration(0),
- mSignalSelectCallback(0),
- mMinWidth(0),
- mDragAndDropThisFrame(FALSE),
- mCallbackRegistrar(NULL),
- mParentPanel(p.parent_panel),
- mUseEllipses(p.use_ellipses),
- mDraggingOverItem(NULL),
- mStatusTextBox(NULL)
-{
- mRoot = this;
-
- mShowLoadStatus = p.show_load_status();
-
- LLRect rect = p.rect;
- LLRect new_rect(rect.mLeft, rect.mBottom + getRect().getHeight(), rect.mLeft + getRect().getWidth(), rect.mBottom);
- setRect( rect );
- reshape(rect.getWidth(), rect.getHeight());
- mIsOpen = TRUE; // this view is always open.
- mAutoOpenItems.setDepth(AUTO_OPEN_STACK_DEPTH);
- mAutoOpenCandidate = NULL;
- mAutoOpenTimer.stop();
- mKeyboardSelection = FALSE;
- const LLFolderViewItem::Params& item_params =
- LLUICtrlFactory::getDefaultParams<LLFolderViewItem>();
- S32 indentation = item_params.folder_indentation();
- mIndentation = -indentation; // children start at indentation 0
- gIdleCallbacks.addFunction(idle, this);
-
- //clear label
- // go ahead and render root folder as usual
- // just make sure the label ("Inventory Folder") never shows up
- mLabel = LLStringUtil::null;
-
- //mRenamer->setWriteableBgColor(LLColor4::white);
- // Escape is handled by reverting the rename, not commiting it (default behavior)
- LLLineEditor::Params params;
- params.name("ren");
- params.rect(rect);
- params.font(getLabelFontForStyle(LLFontGL::NORMAL));
- params.max_length.bytes(DB_INV_ITEM_NAME_STR_LEN);
- params.commit_callback.function(boost::bind(&LLFolderView::commitRename, this, _2));
- params.prevalidate_callback(&LLTextValidate::validateASCIIPrintableNoPipe);
- params.commit_on_focus_lost(true);
- params.visible(false);
- mRenamer = LLUICtrlFactory::create<LLLineEditor> (params);
- addChild(mRenamer);
-
- // Textbox
- LLTextBox::Params text_p;
- LLFontGL* font = getLabelFontForStyle(mLabelStyle);
- LLRect new_r = LLRect(rect.mLeft + ICON_PAD,
- rect.mTop - TEXT_PAD,
- rect.mRight,
- rect.mTop - TEXT_PAD - font->getLineHeight());
- text_p.rect(new_r);
- text_p.name(std::string(p.name));
- text_p.font(font);
- text_p.visible(false);
- text_p.parse_urls(true);
- text_p.wrap(true); // allow multiline text. See EXT-7564, EXT-7047
- // set text padding the same as in People panel. EXT-7047, EXT-4837
- text_p.h_pad(STATUS_TEXT_HPAD);
- text_p.v_pad(STATUS_TEXT_VPAD);
- mStatusTextBox = LLUICtrlFactory::create<LLTextBox> (text_p);
- mStatusTextBox->setFollowsLeft();
- mStatusTextBox->setFollowsTop();
- //addChild(mStatusTextBox);
-
-
- // make the popup menu available
- LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_inventory.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
- if (!menu)
- {
- menu = LLUICtrlFactory::getDefaultWidget<LLMenuGL>("inventory_menu");
- }
- menu->setBackgroundColor(LLUIColorTable::instance().getColor("MenuPopupBgColor"));
- mPopupMenuHandle = menu->getHandle();
-
- mListener->openItem();
-}
-
-// Destroys the object
-LLFolderView::~LLFolderView( void )
-{
- closeRenamer();
-
- // The release focus call can potentially call the
- // scrollcontainer, which can potentially be called with a partly
- // destroyed scollcontainer. Just null it out here, and no worries
- // about calling into the invalid scroll container.
- // Same with the renamer.
- mScrollContainer = NULL;
- mRenameItem = NULL;
- mRenamer = NULL;
- mStatusTextBox = NULL;
-
- mAutoOpenItems.removeAllNodes();
- gIdleCallbacks.deleteFunction(idle, this);
-
- if (mPopupMenuHandle.get()) mPopupMenuHandle.get()->die();
-
- mAutoOpenItems.removeAllNodes();
- clearSelection();
- mItems.clear();
- mFolders.clear();
-
- mItemMap.clear();
-
- delete mFilter;
- mFilter = NULL;
-}
-
-BOOL LLFolderView::canFocusChildren() const
-{
- return FALSE;
-}
-
-static LLFastTimer::DeclareTimer FTM_SORT("Sort Inventory");
-
-void LLFolderView::setSortOrder(U32 order)
-{
- if (order != mSortOrder)
- {
- LLFastTimer t(FTM_SORT);
-
- mSortOrder = order;
-
- sortBy(order);
- arrangeAll();
- }
-}
-
-
-U32 LLFolderView::getSortOrder() const
-{
- return mSortOrder;
-}
-
-BOOL LLFolderView::addFolder( LLFolderViewFolder* folder)
-{
- // enforce sort order of My Inventory followed by Library
- if (folder->getListener()->getUUID() == gInventory.getLibraryRootFolderID())
- {
- mFolders.push_back(folder);
- }
- else
- {
- mFolders.insert(mFolders.begin(), folder);
- }
- folder->setShowLoadStatus(mShowLoadStatus);
- folder->setOrigin(0, 0);
- folder->reshape(getRect().getWidth(), 0);
- folder->setVisible(FALSE);
- addChild( folder );
- folder->dirtyFilter();
- folder->requestArrange();
- return TRUE;
-}
-
-void LLFolderView::closeAllFolders()
-{
- // Close all the folders
- setOpenArrangeRecursively(FALSE, LLFolderViewFolder::RECURSE_DOWN);
- arrangeAll();
-}
-
-void LLFolderView::openTopLevelFolders()
-{
- for (folders_t::iterator iter = mFolders.begin();
- iter != mFolders.end();)
- {
- folders_t::iterator fit = iter++;
- (*fit)->setOpen(TRUE);
- }
-}
-
-void LLFolderView::setOpenArrangeRecursively(BOOL openitem, ERecurseType recurse)
-{
- // call base class to do proper recursion
- LLFolderViewFolder::setOpenArrangeRecursively(openitem, recurse);
- // make sure root folder is always open
- mIsOpen = TRUE;
-}
-
-static LLFastTimer::DeclareTimer FTM_ARRANGE("Arrange");
-
-// This view grows and shrinks to enclose all of its children items and folders.
-S32 LLFolderView::arrange( S32* unused_width, S32* unused_height, S32 filter_generation )
-{
- if (getListener()->getUUID().notNull())
- {
- if (mNeedsSort)
- {
- mFolders.sort(mSortFunction);
- mItems.sort(mSortFunction);
- mNeedsSort = false;
- }
- }
-
- LLFastTimer t2(FTM_ARRANGE);
-
- filter_generation = mFilter->getMinRequiredGeneration();
- mMinWidth = 0;
-
- mHasVisibleChildren = hasFilteredDescendants(filter_generation);
- // arrange always finishes, so optimistically set the arrange generation to the most current
- mLastArrangeGeneration = getRoot()->getArrangeGeneration();
-
- LLInventoryFilter::EFolderShow show_folder_state =
- getRoot()->getFilter()->getShowFolderState();
-
- S32 total_width = LEFT_PAD;
- S32 running_height = mDebugFilters ? LLFontGL::getFontMonospace()->getLineHeight() : 0;
- S32 target_height = running_height;
- S32 parent_item_height = getRect().getHeight();
-
- for (folders_t::iterator iter = mFolders.begin();
- iter != mFolders.end();)
- {
- folders_t::iterator fit = iter++;
- LLFolderViewFolder* folderp = (*fit);
- if (getDebugFilters())
- {
- folderp->setVisible(TRUE);
- }
- else
- {
- folderp->setVisible((show_folder_state == LLInventoryFilter::SHOW_ALL_FOLDERS || // always show folders?
- (folderp->getFiltered(filter_generation) || folderp->hasFilteredDescendants(filter_generation))));
- }
-
- if (folderp->getVisible())
- {
- S32 child_height = 0;
- S32 child_width = 0;
- S32 child_top = parent_item_height - running_height;
-
- target_height += folderp->arrange( &child_width, &child_height, filter_generation );
-
- mMinWidth = llmax(mMinWidth, child_width);
- total_width = llmax( total_width, child_width );
- running_height += child_height;
- folderp->setOrigin( ICON_PAD, child_top - (*fit)->getRect().getHeight() );
- }
- }
-
- for (items_t::iterator iter = mItems.begin();
- iter != mItems.end();)
- {
- items_t::iterator iit = iter++;
- LLFolderViewItem* itemp = (*iit);
- itemp->setVisible(itemp->getFiltered(filter_generation));
-
- if (itemp->getVisible())
- {
- S32 child_width = 0;
- S32 child_height = 0;
- S32 child_top = parent_item_height - running_height;
-
- target_height += itemp->arrange( &child_width, &child_height, filter_generation );
- itemp->reshape(itemp->getRect().getWidth(), child_height);
-
- mMinWidth = llmax(mMinWidth, child_width);
- total_width = llmax( total_width, child_width );
- running_height += child_height;
- itemp->setOrigin( ICON_PAD, child_top - itemp->getRect().getHeight() );
- }
- }
-
- if(!mHasVisibleChildren)// is there any filtered items ?
- {
- //Nope. We need to display status textbox, let's reserve some place for it
- running_height = mStatusTextBox->getTextPixelHeight();
- target_height = running_height;
- }
-
- mRunningHeight = running_height;
- LLRect scroll_rect = mScrollContainer->getContentWindowRect();
- reshape( llmax(scroll_rect.getWidth(), total_width), running_height );
-
- LLRect new_scroll_rect = mScrollContainer->getContentWindowRect();
- if (new_scroll_rect.getWidth() != scroll_rect.getWidth())
- {
- reshape( llmax(scroll_rect.getWidth(), total_width), running_height );
- }
-
- // move item renamer text field to item's new position
- updateRenamerPosition();
-
- mTargetHeight = (F32)target_height;
- return llround(mTargetHeight);
-}
-
-const std::string LLFolderView::getFilterSubString(BOOL trim)
-{
- return mFilter->getFilterSubString(trim);
-}
-
-static LLFastTimer::DeclareTimer FTM_FILTER("Filter Inventory");
-
-void LLFolderView::filter( LLInventoryFilter& filter )
-{
- LLFastTimer t2(FTM_FILTER);
- filter.setFilterCount(llclamp(gSavedSettings.getS32("FilterItemsPerFrame"), 1, 5000));
-
- if (getCompletedFilterGeneration() < filter.getCurrentGeneration())
- {
- mPassedFilter = FALSE;
- mMinWidth = 0;
- LLFolderViewFolder::filter(filter);
- }
- else
- {
- mPassedFilter = TRUE;
- }
-}
-
-void LLFolderView::reshape(S32 width, S32 height, BOOL called_from_parent)
-{
- LLRect scroll_rect;
- if (mScrollContainer)
- {
- LLView::reshape(width, height, called_from_parent);
- scroll_rect = mScrollContainer->getContentWindowRect();
- }
- width = llmax(mMinWidth, scroll_rect.getWidth());
- height = llmax(mRunningHeight, scroll_rect.getHeight());
-
- // Restrict width within scroll container's width
- if (mUseEllipses && mScrollContainer)
- {
- width = scroll_rect.getWidth();
- }
-
- LLView::reshape(width, height, called_from_parent);
- mReshapeSignal(mSelectedItems, FALSE);
-}
-
-void LLFolderView::addToSelectionList(LLFolderViewItem* item)
-{
- if (item->isSelected())
- {
- removeFromSelectionList(item);
- }
- if (mSelectedItems.size())
- {
- mSelectedItems.back()->setIsCurSelection(FALSE);
- }
- item->setIsCurSelection(TRUE);
- mSelectedItems.push_back(item);
-}
-
-void LLFolderView::removeFromSelectionList(LLFolderViewItem* item)
-{
- if (mSelectedItems.size())
- {
- mSelectedItems.back()->setIsCurSelection(FALSE);
- }
-
- selected_items_t::iterator item_iter;
- for (item_iter = mSelectedItems.begin(); item_iter != mSelectedItems.end();)
- {
- if (*item_iter == item)
- {
- item_iter = mSelectedItems.erase(item_iter);
- }
- else
- {
- ++item_iter;
- }
- }
- if (mSelectedItems.size())
- {
- mSelectedItems.back()->setIsCurSelection(TRUE);
- }
-}
-
-LLFolderViewItem* LLFolderView::getCurSelectedItem( void )
-{
- if(mSelectedItems.size())
- {
- LLFolderViewItem* itemp = mSelectedItems.back();
- llassert(itemp->getIsCurSelection());
- return itemp;
- }
- return NULL;
-}
-
-
-// Record the selected item and pass it down the hierachy.
-BOOL LLFolderView::setSelection(LLFolderViewItem* selection, BOOL openitem,
- BOOL take_keyboard_focus)
-{
- mSignalSelectCallback = take_keyboard_focus ? SIGNAL_KEYBOARD_FOCUS : SIGNAL_NO_KEYBOARD_FOCUS;
-
- if( selection == this )
- {
- return FALSE;
- }
-
- if( selection && take_keyboard_focus)
- {
- mParentPanel->setFocus(TRUE);
- }
-
- // clear selection down here because change of keyboard focus can potentially
- // affect selection
- clearSelection();
-
- if(selection)
- {
- addToSelectionList(selection);
- }
-
- BOOL rv = LLFolderViewFolder::setSelection(selection, openitem, take_keyboard_focus);
- if(openitem && selection)
- {
- selection->getParentFolder()->requestArrange();
- }
-
- llassert(mSelectedItems.size() <= 1);
-
- return rv;
-}
-
-void LLFolderView::setSelectionByID(const LLUUID& obj_id, BOOL take_keyboard_focus)
-{
- LLFolderViewItem* itemp = getItemByID(obj_id);
- if(itemp && itemp->getListener())
- {
- itemp->arrangeAndSet(TRUE, take_keyboard_focus);
- mSelectThisID.setNull();
- return;
- }
- else
- {
- // save the desired item to be selected later (if/when ready)
- mSelectThisID = obj_id;
- }
-}
-
-void LLFolderView::updateSelection()
-{
- if (mSelectThisID.notNull())
- {
- setSelectionByID(mSelectThisID, false);
- }
-}
-
-BOOL LLFolderView::changeSelection(LLFolderViewItem* selection, BOOL selected)
-{
- BOOL rv = FALSE;
-
- // can't select root folder
- if(!selection || selection == this)
- {
- return FALSE;
- }
-
- if (!mAllowMultiSelect)
- {
- clearSelection();
- }
-
- selected_items_t::iterator item_iter;
- for (item_iter = mSelectedItems.begin(); item_iter != mSelectedItems.end(); ++item_iter)
- {
- if (*item_iter == selection)
- {
- break;
- }
- }
-
- BOOL on_list = (item_iter != mSelectedItems.end());
-
- if(selected && !on_list)
- {
- addToSelectionList(selection);
- }
- if(!selected && on_list)
- {
- removeFromSelectionList(selection);
- }
-
- rv = LLFolderViewFolder::changeSelection(selection, selected);
-
- mSignalSelectCallback = SIGNAL_KEYBOARD_FOCUS;
-
- return rv;
-}
-
-static LLFastTimer::DeclareTimer FTM_SANITIZE_SELECTION("Sanitize Selection");
-void LLFolderView::sanitizeSelection()
-{
- LLFastTimer _(FTM_SANITIZE_SELECTION);
- // store off current item in case it is automatically deselected
- // and we want to preserve context
- LLFolderViewItem* original_selected_item = getCurSelectedItem();
-
- // Cache "Show all folders" filter setting
- BOOL show_all_folders = (getRoot()->getFilter()->getShowFolderState() == LLInventoryFilter::SHOW_ALL_FOLDERS);
-
- std::vector<LLFolderViewItem*> items_to_remove;
- selected_items_t::iterator item_iter;
- for (item_iter = mSelectedItems.begin(); item_iter != mSelectedItems.end(); ++item_iter)
- {
- LLFolderViewItem* item = *item_iter;
-
- // ensure that each ancestor is open and potentially passes filtering
- BOOL visible = item->potentiallyVisible(); // initialize from filter state for this item
- // modify with parent open and filters states
- LLFolderViewFolder* parent_folder = item->getParentFolder();
- if ( parent_folder )
- {
- if ( show_all_folders )
- { // "Show all folders" is on, so this folder is visible
- visible = TRUE;
- }
- else
- { // Move up through parent folders and see what's visible
- while(parent_folder)
- {
- visible = visible && parent_folder->isOpen() && parent_folder->potentiallyVisible();
- parent_folder = parent_folder->getParentFolder();
- }
- }
- }
-
- // deselect item if any ancestor is closed or didn't pass filter requirements.
- if (!visible)
- {
- items_to_remove.push_back(item);
- }
-
- // disallow nested selections (i.e. folder items plus one or more ancestors)
- // could check cached mum selections count and only iterate if there are any
- // but that may be a premature optimization.
- selected_items_t::iterator other_item_iter;
- for (other_item_iter = mSelectedItems.begin(); other_item_iter != mSelectedItems.end(); ++other_item_iter)
- {
- LLFolderViewItem* other_item = *other_item_iter;
- for( parent_folder = other_item->getParentFolder(); parent_folder; parent_folder = parent_folder->getParentFolder())
- {
- if (parent_folder == item)
- {
- // this is a descendent of the current folder, remove from list
- items_to_remove.push_back(other_item);
- break;
- }
- }
- }
-
- // Don't allow invisible items (such as root folders) to be selected.
- if (item == getRoot())
- {
- items_to_remove.push_back(item);
- }
- }
-
- std::vector<LLFolderViewItem*>::iterator item_it;
- for (item_it = items_to_remove.begin(); item_it != items_to_remove.end(); ++item_it )
- {
- changeSelection(*item_it, FALSE); // toggle selection (also removes from list)
- }
-
- // if nothing selected after prior constraints...
- if (mSelectedItems.empty())
- {
- // ...select first available parent of original selection
- LLFolderViewItem* new_selection = NULL;
- if (original_selected_item)
- {
- for(LLFolderViewFolder* parent_folder = original_selected_item->getParentFolder();
- parent_folder;
- parent_folder = parent_folder->getParentFolder())
- {
- if (parent_folder->potentiallyVisible())
- {
- // give initial selection to first ancestor folder that potentially passes the filter
- if (!new_selection)
- {
- new_selection = parent_folder;
- }
-
- // if any ancestor folder of original item is closed, move the selection up
- // to the highest closed
- if (!parent_folder->isOpen())
- {
- new_selection = parent_folder;
- }
- }
- }
- }
- else
- {
- new_selection = NULL;
- }
-
- if (new_selection)
- {
- setSelection(new_selection, FALSE, FALSE);
- }
- }
-}
-
-void LLFolderView::clearSelection()
-{
- for (selected_items_t::const_iterator item_it = mSelectedItems.begin();
- item_it != mSelectedItems.end();
- ++item_it)
- {
- (*item_it)->setUnselected();
- }
-
- mSelectedItems.clear();
- mSelectThisID.setNull();
-}
-
-std::set<LLUUID> LLFolderView::getSelectionList() const
-{
- std::set<LLUUID> selection;
- for (selected_items_t::const_iterator item_it = mSelectedItems.begin();
- item_it != mSelectedItems.end();
- ++item_it)
- {
- selection.insert((*item_it)->getListener()->getUUID());
- }
- return selection;
-}
-
-BOOL LLFolderView::startDrag(LLToolDragAndDrop::ESource source)
-{
- std::vector<EDragAndDropType> types;
- uuid_vec_t cargo_ids;
- selected_items_t::iterator item_it;
- BOOL can_drag = TRUE;
- if (!mSelectedItems.empty())
- {
- for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it)
- {
- EDragAndDropType type = DAD_NONE;
- LLUUID id = LLUUID::null;
- can_drag = can_drag && (*item_it)->getListener()->startDrag(&type, &id);
-
- types.push_back(type);
- cargo_ids.push_back(id);
- }
-
- LLToolDragAndDrop::getInstance()->beginMultiDrag(types, cargo_ids, source, mSourceID);
- }
- return can_drag;
-}
-
-void LLFolderView::commitRename( const LLSD& data )
-{
- finishRenamingItem();
-}
-
-void LLFolderView::draw()
-{
- static LLUIColor sSearchStatusColor = LLUIColorTable::instance().getColor("InventorySearchStatusColor", LLColor4::white);
- if (mDebugFilters)
- {
- std::string current_filter_string = llformat("Current Filter: %d, Least Filter: %d, Auto-accept Filter: %d",
- mFilter->getCurrentGeneration(), mFilter->getMinRequiredGeneration(), mFilter->getMustPassGeneration());
- LLFontGL::getFontMonospace()->renderUTF8(current_filter_string, 0, 2,
- getRect().getHeight() - LLFontGL::getFontMonospace()->getLineHeight(), LLColor4(0.5f, 0.5f, 0.8f, 1.f),
- LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, S32_MAX, NULL, FALSE );
- }
-
- //LLFontGL* font = getLabelFontForStyle(mLabelStyle);
-
- // if cursor has moved off of me during drag and drop
- // close all auto opened folders
- if (!mDragAndDropThisFrame)
- {
- closeAutoOpenedFolders();
- }
-
- // while dragging, update selection rendering to reflect single/multi drag status
- if (LLToolDragAndDrop::getInstance()->hasMouseCapture())
- {
- EAcceptance last_accept = LLToolDragAndDrop::getInstance()->getLastAccept();
- if (last_accept == ACCEPT_YES_SINGLE || last_accept == ACCEPT_YES_COPY_SINGLE)
- {
- setShowSingleSelection(TRUE);
- }
- else
- {
- setShowSingleSelection(FALSE);
- }
- }
- else
- {
- setShowSingleSelection(FALSE);
- }
-
-
- if (mSearchTimer.getElapsedTimeF32() > gSavedSettings.getF32("TypeAheadTimeout") || !mSearchString.size())
- {
- mSearchString.clear();
- }
-
- if (hasVisibleChildren()
- || mFilter->getShowFolderState() == LLInventoryFilter::SHOW_ALL_FOLDERS)
- {
- mStatusText.clear();
- mStatusTextBox->setVisible( FALSE );
- }
- else if (mShowEmptyMessage)
- {
- if (LLInventoryModelBackgroundFetch::instance().folderFetchActive() || mCompletedFilterGeneration < mFilter->getMinRequiredGeneration())
- {
- mStatusText = LLTrans::getString("Searching");
- }
- else
- {
- if (getFilter())
- {
- LLStringUtil::format_map_t args;
- args["[SEARCH_TERM]"] = LLURI::escape(getFilter()->getFilterSubStringOrig());
- mStatusText = LLTrans::getString(getFilter()->getEmptyLookupMessage(), args);
- }
- }
- mStatusTextBox->setValue(mStatusText);
- mStatusTextBox->setVisible( TRUE );
-
- // firstly reshape message textbox with current size. This is necessary to
- // LLTextBox::getTextPixelHeight works properly
- const LLRect local_rect = getLocalRect();
- mStatusTextBox->setShape(local_rect);
-
- // get preferable text height...
- S32 pixel_height = mStatusTextBox->getTextPixelHeight();
- bool height_changed = local_rect.getHeight() != pixel_height;
- if (height_changed)
- {
- // ... if it does not match current height, lets rearrange current view.
- // This will indirectly call ::arrange and reshape of the status textbox.
- // We should call this method to also notify parent about required rect.
- // See EXT-7564, EXT-7047.
- arrangeFromRoot();
- LLUI::popMatrix();
- LLUI::pushMatrix();
- LLUI::translate((F32)getRect().mLeft, (F32)getRect().mBottom);
- }
- }
-
- // skip over LLFolderViewFolder::draw since we don't want the folder icon, label,
- // and arrow for the root folder
- LLView::draw();
-
- mDragAndDropThisFrame = FALSE;
-}
-
-void LLFolderView::finishRenamingItem( void )
-{
- if(!mRenamer)
- {
- return;
- }
- if( mRenameItem )
- {
- mRenameItem->rename( mRenamer->getText() );
- }
-
- closeRenamer();
-
- // List is re-sorted alphabeticly, so scroll to make sure the selected item is visible.
- scrollToShowSelection();
-}
-
-void LLFolderView::closeRenamer( void )
-{
- if (mRenamer && mRenamer->getVisible())
- {
- // Triggers onRenamerLost() that actually closes the renamer.
- gViewerWindow->removePopup(mRenamer);
- }
-}
-
-void LLFolderView::removeSelectedItems( void )
-{
- if (mSelectedItems.empty()) return;
- LLSD args;
- args["QUESTION"] = LLTrans::getString(mSelectedItems.size() > 1 ? "DeleteItems" : "DeleteItem");
- LLNotificationsUtil::add("DeleteItems", args, LLSD(), boost::bind(&LLFolderView::onItemsRemovalConfirmation, this, _1, _2));
-}
-
-bool isDescendantOfASelectedItem(LLFolderViewItem* item, const std::vector<LLFolderViewItem*>& selectedItems)
-{
- LLFolderViewItem* item_parent = dynamic_cast<LLFolderViewItem*>(item->getParent());
-
- if (item_parent)
- {
- for(std::vector<LLFolderViewItem*>::const_iterator it = selectedItems.begin(); it != selectedItems.end(); ++it)
- {
- const LLFolderViewItem* const selected_item = (*it);
-
- LLFolderViewItem* parent = item_parent;
-
- while (parent)
- {
- if (selected_item == parent)
- {
- return true;
- }
-
- parent = dynamic_cast<LLFolderViewItem*>(parent->getParent());
- }
- }
- }
-
- return false;
-}
-
-// static
-void LLFolderView::removeCutItems()
-{
- // There's no item in "cut" mode on the clipboard -> exit
- if (!LLClipboard::instance().isCutMode())
- return;
-
- // Get the list of clipboard item uuids and iterate through them
- LLDynamicArray<LLUUID> objects;
- LLClipboard::instance().pasteFromClipboard(objects);
- for (LLDynamicArray<LLUUID>::const_iterator iter = objects.begin();
- iter != objects.end();
- ++iter)
- {
- gInventory.removeObject(*iter);
- }
-}
-
-void LLFolderView::onItemsRemovalConfirmation(const LLSD& notification, const LLSD& response)
-{
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
- if (option != 0) return; // canceled
-
- if(getVisible() && getEnabled())
- {
- // just in case we're removing the renaming item.
- mRenameItem = NULL;
-
- // create a temporary structure which we will use to remove
- // items, since the removal will futz with internal data
- // structures.
- std::vector<LLFolderViewItem*> items;
- S32 count = mSelectedItems.size();
- if(count == 0) return;
- LLFolderViewItem* item = NULL;
- selected_items_t::iterator item_it;
- for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it)
- {
- item = *item_it;
- if (item && item->isRemovable())
- {
- items.push_back(item);
- }
- else
- {
- llinfos << "Cannot delete " << item->getName() << llendl;
- return;
- }
- }
-
- // iterate through the new container.
- count = items.size();
- LLUUID new_selection_id;
- if(count == 1)
- {
- LLFolderViewItem* item_to_delete = items[0];
- LLFolderViewFolder* parent = item_to_delete->getParentFolder();
- LLFolderViewItem* new_selection = item_to_delete->getNextOpenNode(FALSE);
- if (!new_selection)
- {
- new_selection = item_to_delete->getPreviousOpenNode(FALSE);
- }
- if(parent)
- {
- if (parent->removeItem(item_to_delete))
- {
- // change selection on successful delete
- if (new_selection)
- {
- setSelectionFromRoot(new_selection, new_selection->isOpen(), mParentPanel->hasFocus());
- }
- else
- {
- setSelectionFromRoot(NULL, mParentPanel->hasFocus());
- }
- }
- }
- arrangeAll();
- }
- else if (count > 1)
- {
- LLDynamicArray<LLFolderViewEventListener*> listeners;
- LLFolderViewEventListener* listener;
- LLFolderViewItem* last_item = items[count - 1];
- LLFolderViewItem* new_selection = last_item->getNextOpenNode(FALSE);
- while(new_selection && new_selection->isSelected())
- {
- new_selection = new_selection->getNextOpenNode(FALSE);
- }
- if (!new_selection)
- {
- new_selection = last_item->getPreviousOpenNode(FALSE);
- while (new_selection && (new_selection->isSelected() || isDescendantOfASelectedItem(new_selection, items)))
- {
- new_selection = new_selection->getPreviousOpenNode(FALSE);
- }
- }
- if (new_selection)
- {
- setSelectionFromRoot(new_selection, new_selection->isOpen(), mParentPanel->hasFocus());
- }
- else
- {
- setSelectionFromRoot(NULL, mParentPanel->hasFocus());
- }
-
- for(S32 i = 0; i < count; ++i)
- {
- listener = items[i]->getListener();
- if(listener && (listeners.find(listener) == LLDynamicArray<LLFolderViewEventListener*>::FAIL))
- {
- listeners.put(listener);
- }
- }
- listener = listeners.get(0);
- if(listener)
- {
- listener->removeBatch(listeners);
- }
- }
- arrangeAll();
- scrollToShowSelection();
- }
-}
-
-// open the selected item.
-void LLFolderView::openSelectedItems( void )
-{
- if(getVisible() && getEnabled())
- {
- if (mSelectedItems.size() == 1)
- {
- mSelectedItems.front()->openItem();
- }
- else
- {
- LLMultiPreview* multi_previewp = new LLMultiPreview();
- LLMultiProperties* multi_propertiesp = new LLMultiProperties();
-
- selected_items_t::iterator item_it;
- for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it)
- {
- // IT_{OBJECT,ATTACHMENT} creates LLProperties
- // floaters; others create LLPreviews. Put
- // each one in the right type of container.
- LLFolderViewEventListener* listener = (*item_it)->getListener();
- bool is_prop = listener && (listener->getInventoryType() == LLInventoryType::IT_OBJECT || listener->getInventoryType() == LLInventoryType::IT_ATTACHMENT);
- if (is_prop)
- LLFloater::setFloaterHost(multi_propertiesp);
- else
- LLFloater::setFloaterHost(multi_previewp);
- (*item_it)->openItem();
- }
-
- LLFloater::setFloaterHost(NULL);
- // *NOTE: LLMulti* will safely auto-delete when open'd
- // without any children.
- multi_previewp->openFloater(LLSD());
- multi_propertiesp->openFloater(LLSD());
- }
- }
-}
-
-void LLFolderView::propertiesSelectedItems( void )
-{
- if(getVisible() && getEnabled())
- {
- if (mSelectedItems.size() == 1)
- {
- LLFolderViewItem* folder_item = mSelectedItems.front();
- if(!folder_item) return;
- folder_item->getListener()->showProperties();
- }
- else
- {
- LLMultiProperties* multi_propertiesp = new LLMultiProperties();
-
- LLFloater::setFloaterHost(multi_propertiesp);
-
- selected_items_t::iterator item_it;
- for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it)
- {
- (*item_it)->getListener()->showProperties();
- }
-
- LLFloater::setFloaterHost(NULL);
- multi_propertiesp->openFloater(LLSD());
- }
- }
-}
-
-void LLFolderView::changeType(LLInventoryModel *model, LLFolderType::EType new_folder_type)
-{
- LLFolderBridge *folder_bridge = LLFolderBridge::sSelf.get();
-
- if (!folder_bridge) return;
- LLViewerInventoryCategory *cat = folder_bridge->getCategory();
- if (!cat) return;
- cat->changeType(new_folder_type);
-}
-
-void LLFolderView::autoOpenItem( LLFolderViewFolder* item )
-{
- if ((mAutoOpenItems.check() == item) ||
- (mAutoOpenItems.getDepth() >= (U32)AUTO_OPEN_STACK_DEPTH) ||
- item->isOpen())
- {
- return;
- }
-
- // close auto-opened folders
- LLFolderViewFolder* close_item = mAutoOpenItems.check();
- while (close_item && close_item != item->getParentFolder())
- {
- mAutoOpenItems.pop();
- close_item->setOpenArrangeRecursively(FALSE);
- close_item = mAutoOpenItems.check();
- }
-
- item->requestArrange();
-
- mAutoOpenItems.push(item);
-
- item->setOpen(TRUE);
- LLRect content_rect = mScrollContainer->getContentWindowRect();
- LLRect constraint_rect(0,content_rect.getHeight(), content_rect.getWidth(), 0);
- scrollToShowItem(item, constraint_rect);
-}
-
-void LLFolderView::closeAutoOpenedFolders()
-{
- while (mAutoOpenItems.check())
- {
- LLFolderViewFolder* close_item = mAutoOpenItems.pop();
- close_item->setOpen(FALSE);
- }
-
- if (mAutoOpenCandidate)
- {
- mAutoOpenCandidate->setAutoOpenCountdown(0.f);
- }
- mAutoOpenCandidate = NULL;
- mAutoOpenTimer.stop();
-}
-
-BOOL LLFolderView::autoOpenTest(LLFolderViewFolder* folder)
-{
- if (folder && mAutoOpenCandidate == folder)
- {
- if (mAutoOpenTimer.getStarted())
- {
- if (!mAutoOpenCandidate->isOpen())
- {
- mAutoOpenCandidate->setAutoOpenCountdown(clamp_rescale(mAutoOpenTimer.getElapsedTimeF32(), 0.f, sAutoOpenTime, 0.f, 1.f));
- }
- if (mAutoOpenTimer.getElapsedTimeF32() > sAutoOpenTime)
- {
- autoOpenItem(folder);
- mAutoOpenTimer.stop();
- return TRUE;
- }
- }
- return FALSE;
- }
-
- // otherwise new candidate, restart timer
- if (mAutoOpenCandidate)
- {
- mAutoOpenCandidate->setAutoOpenCountdown(0.f);
- }
- mAutoOpenCandidate = folder;
- mAutoOpenTimer.start();
- return FALSE;
-}
-
-BOOL LLFolderView::canCopy() const
-{
- if (!(getVisible() && getEnabled() && (mSelectedItems.size() > 0)))
- {
- return FALSE;
- }
-
- for (selected_items_t::const_iterator selected_it = mSelectedItems.begin(); selected_it != mSelectedItems.end(); ++selected_it)
- {
- const LLFolderViewItem* item = *selected_it;
- if (!item->getListener()->isItemCopyable())
- {
- return FALSE;
- }
- }
- return TRUE;
-}
-
-// copy selected item
-void LLFolderView::copy()
-{
- // *NOTE: total hack to clear the inventory clipboard
- LLClipboard::instance().reset();
- S32 count = mSelectedItems.size();
- if(getVisible() && getEnabled() && (count > 0))
- {
- LLFolderViewEventListener* listener = NULL;
- selected_items_t::iterator item_it;
- for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it)
- {
- listener = (*item_it)->getListener();
- if(listener)
- {
- listener->copyToClipboard();
- }
- }
- }
- mSearchString.clear();
-}
-
-BOOL LLFolderView::canCut() const
-{
- if (!(getVisible() && getEnabled() && (mSelectedItems.size() > 0)))
- {
- return FALSE;
- }
-
- for (selected_items_t::const_iterator selected_it = mSelectedItems.begin(); selected_it != mSelectedItems.end(); ++selected_it)
- {
- const LLFolderViewItem* item = *selected_it;
- const LLFolderViewEventListener* listener = item->getListener();
-
- if (!listener || !listener->isItemRemovable())
- {
- return FALSE;
- }
- }
- return TRUE;
-}
-
-void LLFolderView::cut()
-{
- // clear the inventory clipboard
- LLClipboard::instance().reset();
- S32 count = mSelectedItems.size();
- if(getVisible() && getEnabled() && (count > 0))
- {
- LLFolderViewEventListener* listener = NULL;
- selected_items_t::iterator item_it;
- for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it)
- {
- listener = (*item_it)->getListener();
- if(listener)
- {
- listener->cutToClipboard();
- }
- }
- LLFolderView::removeCutItems();
- }
- mSearchString.clear();
-}
-
-BOOL LLFolderView::canPaste() const
-{
- if (mSelectedItems.empty())
- {
- return FALSE;
- }
-
- if(getVisible() && getEnabled())
- {
- for (selected_items_t::const_iterator item_it = mSelectedItems.begin();
- item_it != mSelectedItems.end(); ++item_it)
- {
- // *TODO: only check folders and parent folders of items
- const LLFolderViewItem* item = (*item_it);
- const LLFolderViewEventListener* listener = item->getListener();
- if(!listener || !listener->isClipboardPasteable())
- {
- const LLFolderViewFolder* folderp = item->getParentFolder();
- listener = folderp->getListener();
- if (!listener || !listener->isClipboardPasteable())
- {
- return FALSE;
- }
- }
- }
- return TRUE;
- }
- return FALSE;
-}
-
-// paste selected item
-void LLFolderView::paste()
-{
- if(getVisible() && getEnabled())
- {
- // find set of unique folders to paste into
- std::set<LLFolderViewItem*> folder_set;
-
- selected_items_t::iterator selected_it;
- for (selected_it = mSelectedItems.begin(); selected_it != mSelectedItems.end(); ++selected_it)
- {
- LLFolderViewItem* item = *selected_it;
- LLFolderViewEventListener* listener = item->getListener();
- if (listener->getInventoryType() != LLInventoryType::IT_CATEGORY)
- {
- item = item->getParentFolder();
- }
- folder_set.insert(item);
- }
-
- std::set<LLFolderViewItem*>::iterator set_iter;
- for(set_iter = folder_set.begin(); set_iter != folder_set.end(); ++set_iter)
- {
- LLFolderViewEventListener* listener = (*set_iter)->getListener();
- if(listener && listener->isClipboardPasteable())
- {
- listener->pasteFromClipboard();
- }
- }
- }
- mSearchString.clear();
-}
-
-// public rename functionality - can only start the process
-void LLFolderView::startRenamingSelectedItem( void )
-{
- // make sure selection is visible
- scrollToShowSelection();
-
- S32 count = mSelectedItems.size();
- LLFolderViewItem* item = NULL;
- if(count > 0)
- {
- item = mSelectedItems.front();
- }
- if(getVisible() && getEnabled() && (count == 1) && item && item->getListener() &&
- item->getListener()->isItemRenameable())
- {
- mRenameItem = item;
-
- updateRenamerPosition();
-
-
- mRenamer->setText(item->getName());
- mRenamer->selectAll();
- mRenamer->setVisible( TRUE );
- // set focus will fail unless item is visible
- mRenamer->setFocus( TRUE );
- mRenamer->setTopLostCallback(boost::bind(&LLFolderView::onRenamerLost, this));
- gViewerWindow->addPopup(mRenamer);
- }
-}
-
-BOOL LLFolderView::handleKeyHere( KEY key, MASK mask )
-{
- BOOL handled = FALSE;
-
- // SL-51858: Key presses are not being passed to the Popup menu.
- // A proper fix is non-trivial so instead just close the menu.
- LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get();
- if (menu && menu->isOpen())
- {
- LLMenuGL::sMenuContainer->hideMenus();
- }
-
- LLView *item = NULL;
- if (getChildCount() > 0)
- {
- item = *(getChildList()->begin());
- }
-
- switch( key )
- {
- case KEY_F2:
- mSearchString.clear();
- startRenamingSelectedItem();
- handled = TRUE;
- break;
-
- case KEY_RETURN:
- if (mask == MASK_NONE)
- {
- if( mRenameItem && mRenamer->getVisible() )
- {
- finishRenamingItem();
- mSearchString.clear();
- handled = TRUE;
- }
- else
- {
- LLFolderView::openSelectedItems();
- handled = TRUE;
- }
- }
- break;
-
- case KEY_ESCAPE:
- if( mRenameItem && mRenamer->getVisible() )
- {
- closeRenamer();
- handled = TRUE;
- }
- mSearchString.clear();
- break;
-
- case KEY_PAGE_UP:
- mSearchString.clear();
- mScrollContainer->pageUp(30);
- handled = TRUE;
- break;
-
- case KEY_PAGE_DOWN:
- mSearchString.clear();
- mScrollContainer->pageDown(30);
- handled = TRUE;
- break;
-
- case KEY_HOME:
- mSearchString.clear();
- mScrollContainer->goToTop();
- handled = TRUE;
- break;
-
- case KEY_END:
- mSearchString.clear();
- mScrollContainer->goToBottom();
- break;
-
- case KEY_DOWN:
- if((mSelectedItems.size() > 0) && mScrollContainer)
- {
- LLFolderViewItem* last_selected = getCurSelectedItem();
-
- if (!mKeyboardSelection)
- {
- setSelection(last_selected, FALSE, TRUE);
- mKeyboardSelection = TRUE;
- }
-
- LLFolderViewItem* next = NULL;
- if (mask & MASK_SHIFT)
- {
- // don't shift select down to children of folders (they are implicitly selected through parent)
- next = last_selected->getNextOpenNode(FALSE);
- if (next)
- {
- if (next->isSelected())
- {
- // shrink selection
- changeSelectionFromRoot(last_selected, FALSE);
- }
- else if (last_selected->getParentFolder() == next->getParentFolder())
- {
- // grow selection
- changeSelectionFromRoot(next, TRUE);
- }
- }
- }
- else
- {
- next = last_selected->getNextOpenNode();
- if( next )
- {
- if (next == last_selected)
- {
- //special case for LLAccordionCtrl
- if(notifyParent(LLSD().with("action","select_next")) > 0 )//message was processed
- {
- clearSelection();
- return TRUE;
- }
- return FALSE;
- }
- setSelection( next, FALSE, TRUE );
- }
- else
- {
- //special case for LLAccordionCtrl
- if(notifyParent(LLSD().with("action","select_next")) > 0 )//message was processed
- {
- clearSelection();
- return TRUE;
- }
- return FALSE;
- }
- }
- scrollToShowSelection();
- mSearchString.clear();
- handled = TRUE;
- }
- break;
-
- case KEY_UP:
- if((mSelectedItems.size() > 0) && mScrollContainer)
- {
- LLFolderViewItem* last_selected = mSelectedItems.back();
-
- if (!mKeyboardSelection)
- {
- setSelection(last_selected, FALSE, TRUE);
- mKeyboardSelection = TRUE;
- }
-
- LLFolderViewItem* prev = NULL;
- if (mask & MASK_SHIFT)
- {
- // don't shift select down to children of folders (they are implicitly selected through parent)
- prev = last_selected->getPreviousOpenNode(FALSE);
- if (prev)
- {
- if (prev->isSelected())
- {
- // shrink selection
- changeSelectionFromRoot(last_selected, FALSE);
- }
- else if (last_selected->getParentFolder() == prev->getParentFolder())
- {
- // grow selection
- changeSelectionFromRoot(prev, TRUE);
- }
- }
- }
- else
- {
- prev = last_selected->getPreviousOpenNode();
- if( prev )
- {
- if (prev == this)
- {
- // If case we are in accordion tab notify parent to go to the previous accordion
- if(notifyParent(LLSD().with("action","select_prev")) > 0 )//message was processed
- {
- clearSelection();
- return TRUE;
- }
-
- return FALSE;
- }
- setSelection( prev, FALSE, TRUE );
- }
- }
- scrollToShowSelection();
- mSearchString.clear();
-
- handled = TRUE;
- }
- break;
-
- case KEY_RIGHT:
- if(mSelectedItems.size())
- {
- LLFolderViewItem* last_selected = getCurSelectedItem();
- last_selected->setOpen( TRUE );
- mSearchString.clear();
- handled = TRUE;
- }
- break;
-
- case KEY_LEFT:
- if(mSelectedItems.size())
- {
- LLFolderViewItem* last_selected = getCurSelectedItem();
- LLFolderViewItem* parent_folder = last_selected->getParentFolder();
- if (!last_selected->isOpen() && parent_folder && parent_folder->getParentFolder())
- {
- setSelection(parent_folder, FALSE, TRUE);
- }
- else
- {
- last_selected->setOpen( FALSE );
- }
- mSearchString.clear();
- scrollToShowSelection();
- handled = TRUE;
- }
- break;
- }
-
- if (!handled && mParentPanel->hasFocus())
- {
- if (key == KEY_BACKSPACE)
- {
- mSearchTimer.reset();
- if (mSearchString.size())
- {
- mSearchString.erase(mSearchString.size() - 1, 1);
- }
- search(getCurSelectedItem(), mSearchString, FALSE);
- handled = TRUE;
- }
- }
-
- return handled;
-}
-
-
-BOOL LLFolderView::handleUnicodeCharHere(llwchar uni_char)
-{
- if ((uni_char < 0x20) || (uni_char == 0x7F)) // Control character or DEL
- {
- return FALSE;
- }
-
- if (uni_char > 0x7f)
- {
- llwarns << "LLFolderView::handleUnicodeCharHere - Don't handle non-ascii yet, aborting" << llendl;
- return FALSE;
- }
-
- BOOL handled = FALSE;
- if (mParentPanel->hasFocus())
- {
- // SL-51858: Key presses are not being passed to the Popup menu.
- // A proper fix is non-trivial so instead just close the menu.
- LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get();
- if (menu && menu->isOpen())
- {
- LLMenuGL::sMenuContainer->hideMenus();
- }
-
- //do text search
- if (mSearchTimer.getElapsedTimeF32() > gSavedSettings.getF32("TypeAheadTimeout"))
- {
- mSearchString.clear();
- }
- mSearchTimer.reset();
- if (mSearchString.size() < 128)
- {
- mSearchString += uni_char;
- }
- search(getCurSelectedItem(), mSearchString, FALSE);
-
- handled = TRUE;
- }
-
- return handled;
-}
-
-
-BOOL LLFolderView::canDoDelete() const
-{
- if (mSelectedItems.size() == 0) return FALSE;
-
- for (selected_items_t::const_iterator item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it)
- {
- if (!(*item_it)->getListener()->isItemRemovable())
- {
- return FALSE;
- }
- }
- return TRUE;
-}
-
-void LLFolderView::doDelete()
-{
- if(mSelectedItems.size() > 0)
- {
- removeSelectedItems();
- }
-}
-
-
-BOOL LLFolderView::handleMouseDown( S32 x, S32 y, MASK mask )
-{
- mKeyboardSelection = FALSE;
- mSearchString.clear();
-
- mParentPanel->setFocus(TRUE);
-
- LLEditMenuHandler::gEditMenuHandler = this;
-
- return LLView::handleMouseDown( x, y, mask );
-}
-
-BOOL LLFolderView::search(LLFolderViewItem* first_item, const std::string &search_string, BOOL backward)
-{
- // get first selected item
- LLFolderViewItem* search_item = first_item;
-
- // make sure search string is upper case
- std::string upper_case_string = search_string;
- LLStringUtil::toUpper(upper_case_string);
-
- // if nothing selected, select first item in folder
- if (!search_item)
- {
- // start from first item
- search_item = getNextFromChild(NULL);
- }
-
- // search over all open nodes for first substring match (with wrapping)
- BOOL found = FALSE;
- LLFolderViewItem* original_search_item = search_item;
- do
- {
- // wrap at end
- if (!search_item)
- {
- if (backward)
- {
- search_item = getPreviousFromChild(NULL);
- }
- else
- {
- search_item = getNextFromChild(NULL);
- }
- if (!search_item || search_item == original_search_item)
- {
- break;
- }
- }
-
- const std::string current_item_label(search_item->getSearchableLabel());
- S32 search_string_length = llmin(upper_case_string.size(), current_item_label.size());
- if (!current_item_label.compare(0, search_string_length, upper_case_string))
- {
- found = TRUE;
- break;
- }
- if (backward)
- {
- search_item = search_item->getPreviousOpenNode();
- }
- else
- {
- search_item = search_item->getNextOpenNode();
- }
-
- } while(search_item != original_search_item);
-
-
- if (found)
- {
- setSelection(search_item, FALSE, TRUE);
- scrollToShowSelection();
- }
-
- return found;
-}
-
-BOOL LLFolderView::handleDoubleClick( S32 x, S32 y, MASK mask )
-{
- // skip LLFolderViewFolder::handleDoubleClick()
- return LLView::handleDoubleClick( x, y, mask );
-}
-
-BOOL LLFolderView::handleRightMouseDown( S32 x, S32 y, MASK mask )
-{
- // all user operations move keyboard focus to inventory
- // this way, we know when to stop auto-updating a search
- mParentPanel->setFocus(TRUE);
-
- BOOL handled = childrenHandleRightMouseDown(x, y, mask) != NULL;
- S32 count = mSelectedItems.size();
- LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get();
- if ( handled
- && ( count > 0 && (hasVisibleChildren() || mFilter->getShowFolderState() == LLInventoryFilter::SHOW_ALL_FOLDERS) ) // show menu only if selected items are visible
- && menu )
- {
- if (mCallbackRegistrar)
- mCallbackRegistrar->pushScope();
-
- updateMenuOptions(menu);
-
- menu->updateParent(LLMenuGL::sMenuContainer);
- LLMenuGL::showPopup(this, menu, x, y);
- if (mCallbackRegistrar)
- mCallbackRegistrar->popScope();
- }
- else
- {
- if (menu && menu->getVisible())
- {
- menu->setVisible(FALSE);
- }
- setSelection(NULL, FALSE, TRUE);
- }
- return handled;
-}
-
-// Add "--no options--" if the menu is completely blank.
-BOOL LLFolderView::addNoOptions(LLMenuGL* menu) const
-{
- const std::string nooptions_str = "--no options--";
- LLView *nooptions_item = NULL;
-
- const LLView::child_list_t *list = menu->getChildList();
- for (LLView::child_list_t::const_iterator itor = list->begin();
- itor != list->end();
- ++itor)
- {
- LLView *menu_item = (*itor);
- if (menu_item->getVisible())
- {
- return FALSE;
- }
- std::string name = menu_item->getName();
- if (menu_item->getName() == nooptions_str)
- {
- nooptions_item = menu_item;
- }
- }
- if (nooptions_item)
- {
- nooptions_item->setVisible(TRUE);
- nooptions_item->setEnabled(FALSE);
- return TRUE;
- }
- return FALSE;
-}
-
-BOOL LLFolderView::handleHover( S32 x, S32 y, MASK mask )
-{
- return LLView::handleHover( x, y, mask );
-}
-
-BOOL LLFolderView::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
- EDragAndDropType cargo_type,
- void* cargo_data,
- EAcceptance* accept,
- std::string& tooltip_msg)
-{
- mDragAndDropThisFrame = TRUE;
- // have children handle it first
- BOOL handled = LLView::handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data,
- accept, tooltip_msg);
-
- // when drop is not handled by child, it should be handled
- // by the folder which is the hierarchy root.
- if (!handled)
- {
- if (getListener()->getUUID().notNull())
- {
- handled = LLFolderViewFolder::handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
- }
- else
- {
- if (!mFolders.empty())
- {
- // dispatch to last folder as a hack to support "Contents" folder in object inventory
- handled = mFolders.back()->handleDragAndDropFromChild(mask,drop,cargo_type,cargo_data,accept,tooltip_msg);
- }
- }
- }
-
- if (handled)
- {
- lldebugst(LLERR_USER_INPUT) << "dragAndDrop handled by LLFolderView" << llendl;
- }
-
- return handled;
-}
-
-void LLFolderView::deleteAllChildren()
-{
- closeRenamer();
- if (mPopupMenuHandle.get()) mPopupMenuHandle.get()->die();
- mPopupMenuHandle = LLHandle<LLView>();
- mScrollContainer = NULL;
- mRenameItem = NULL;
- mRenamer = NULL;
- mStatusTextBox = NULL;
-
- clearSelection();
- LLView::deleteAllChildren();
-}
-
-void LLFolderView::scrollToShowSelection()
-{
- if ( mSelectedItems.size() )
- {
- mNeedsScroll = TRUE;
- }
-}
-
-// If the parent is scroll container, scroll it to make the selection
-// is maximally visible.
-void LLFolderView::scrollToShowItem(LLFolderViewItem* item, const LLRect& constraint_rect)
-{
- if (!mScrollContainer) return;
-
- // don't scroll to items when mouse is being used to scroll/drag and drop
- if (gFocusMgr.childHasMouseCapture(mScrollContainer))
- {
- mNeedsScroll = FALSE;
- return;
- }
-
- // if item exists and is in visible portion of parent folder...
- if(item)
- {
- LLRect local_rect = item->getLocalRect();
- LLRect item_scrolled_rect; // item position relative to display area of scroller
- LLRect visible_doc_rect = mScrollContainer->getVisibleContentRect();
-
- S32 icon_height = mIcon.isNull() ? 0 : mIcon->getHeight();
- S32 label_height = getLabelFontForStyle(mLabelStyle)->getLineHeight();
- // when navigating with keyboard, only move top of opened folder on screen, otherwise show whole folder
- S32 max_height_to_show = item->isOpen() && mScrollContainer->hasFocus() ? (llmax( icon_height, label_height ) + ICON_PAD) : local_rect.getHeight();
-
- // get portion of item that we want to see...
- LLRect item_local_rect = LLRect(item->getIndentation(),
- local_rect.getHeight(),
- llmin(MIN_ITEM_WIDTH_VISIBLE, local_rect.getWidth()),
- llmax(0, local_rect.getHeight() - max_height_to_show));
-
- LLRect item_doc_rect;
-
- item->localRectToOtherView(item_local_rect, &item_doc_rect, this);
-
- mScrollContainer->scrollToShowRect( item_doc_rect, constraint_rect );
-
- }
-}
-
-LLRect LLFolderView::getVisibleRect()
-{
- S32 visible_height = mScrollContainer->getRect().getHeight();
- S32 visible_width = mScrollContainer->getRect().getWidth();
- LLRect visible_rect;
- visible_rect.setLeftTopAndSize(-getRect().mLeft, visible_height - getRect().mBottom, visible_width, visible_height);
- return visible_rect;
-}
-
-BOOL LLFolderView::getShowSelectionContext()
-{
- if (mShowSelectionContext)
- {
- return TRUE;
- }
- LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get();
- if (menu && menu->getVisible())
- {
- return TRUE;
- }
- return FALSE;
-}
-
-void LLFolderView::setShowSingleSelection(BOOL show)
-{
- if (show != mShowSingleSelection)
- {
- mMultiSelectionFadeTimer.reset();
- mShowSingleSelection = show;
- }
-}
-
-void LLFolderView::addItemID(const LLUUID& id, LLFolderViewItem* itemp)
-{
- mItemMap[id] = itemp;
-}
-
-void LLFolderView::removeItemID(const LLUUID& id)
-{
- mItemMap.erase(id);
-}
-
-LLFastTimer::DeclareTimer FTM_GET_ITEM_BY_ID("Get FolderViewItem by ID");
-LLFolderViewItem* LLFolderView::getItemByID(const LLUUID& id)
-{
- LLFastTimer _(FTM_GET_ITEM_BY_ID);
- if (id == getListener()->getUUID())
- {
- return this;
- }
-
- std::map<LLUUID, LLFolderViewItem*>::iterator map_it;
- map_it = mItemMap.find(id);
- if (map_it != mItemMap.end())
- {
- return map_it->second;
- }
-
- return NULL;
-}
-
-LLFolderViewFolder* LLFolderView::getFolderByID(const LLUUID& id)
-{
- if (id == getListener()->getUUID())
- {
- return this;
- }
-
- for (folders_t::iterator iter = mFolders.begin();
- iter != mFolders.end();
- ++iter)
- {
- LLFolderViewFolder *folder = (*iter);
- if (folder->getListener()->getUUID() == id)
- {
- return folder;
- }
- }
- return NULL;
-}
-
-bool LLFolderView::doToSelected(LLInventoryModel* model, const LLSD& userdata)
-{
- std::string action = userdata.asString();
-
- if ("rename" == action)
- {
- startRenamingSelectedItem();
- return true;
- }
- if ("delete" == action)
- {
- removeSelectedItems();
- return true;
- }
- if (("copy" == action) || ("cut" == action))
- {
- // Clear the clipboard before we start adding things on it
- LLClipboard::instance().reset();
- }
-
- static const std::string change_folder_string = "change_folder_type_";
- if (action.length() > change_folder_string.length() &&
- (action.compare(0,change_folder_string.length(),"change_folder_type_") == 0))
- {
- LLFolderType::EType new_folder_type = LLViewerFolderType::lookupTypeFromXUIName(action.substr(change_folder_string.length()));
- changeType(model, new_folder_type);
- return true;
- }
-
-
- std::set<LLUUID> selected_items = getSelectionList();
-
- LLMultiPreview* multi_previewp = NULL;
- LLMultiProperties* multi_propertiesp = NULL;
-
- if (("task_open" == action || "open" == action) && selected_items.size() > 1)
- {
- multi_previewp = new LLMultiPreview();
- gFloaterView->addChild(multi_previewp);
-
- LLFloater::setFloaterHost(multi_previewp);
-
- }
- else if (("task_properties" == action || "properties" == action) && selected_items.size() > 1)
- {
- multi_propertiesp = new LLMultiProperties();
- gFloaterView->addChild(multi_propertiesp);
-
- LLFloater::setFloaterHost(multi_propertiesp);
- }
-
- std::set<LLUUID>::iterator set_iter;
-
- for (set_iter = selected_items.begin(); set_iter != selected_items.end(); ++set_iter)
- {
- LLFolderViewItem* folder_item = getItemByID(*set_iter);
- if(!folder_item) continue;
- LLInvFVBridge* bridge = (LLInvFVBridge*)folder_item->getListener();
- if(!bridge) continue;
- bridge->performAction(model, action);
- }
-
- LLFloater::setFloaterHost(NULL);
- if (multi_previewp)
- {
- multi_previewp->openFloater(LLSD());
- }
- else if (multi_propertiesp)
- {
- multi_propertiesp->openFloater(LLSD());
- }
-
- return true;
-}
-
-static LLFastTimer::DeclareTimer FTM_AUTO_SELECT("Open and Select");
-static LLFastTimer::DeclareTimer FTM_INVENTORY("Inventory");
-
-// Main idle routine
-void LLFolderView::doIdle()
-{
- // If this is associated with the user's inventory, don't do anything
- // until that inventory is loaded up.
- const LLInventoryPanel *inventory_panel = dynamic_cast<LLInventoryPanel*>(mParentPanel);
- if (inventory_panel && !inventory_panel->getIsViewsInitialized())
- {
- return;
- }
-
- LLFastTimer t2(FTM_INVENTORY);
-
- BOOL debug_filters = gSavedSettings.getBOOL("DebugInventoryFilters");
- if (debug_filters != getDebugFilters())
- {
- mDebugFilters = debug_filters;
- arrangeAll();
- }
-
- if (mFilter->isModified() && mFilter->isNotDefault())
- {
- mNeedsAutoSelect = TRUE;
- }
- mFilter->clearModified();
-
- // filter to determine visibility before arranging
- filterFromRoot();
-
- // automatically show matching items, and select first one if we had a selection
- if (mNeedsAutoSelect)
- {
- LLFastTimer t3(FTM_AUTO_SELECT);
- // select new item only if a filtered item not currently selected
- LLFolderViewItem* selected_itemp = mSelectedItems.empty() ? NULL : mSelectedItems.back();
- if (!mAutoSelectOverride && (!selected_itemp || !selected_itemp->potentiallyFiltered()))
- {
- // these are named variables to get around gcc not binding non-const references to rvalues
- // and functor application is inherently non-const to allow for stateful functors
- LLSelectFirstFilteredItem functor;
- applyFunctorRecursively(functor);
- }
-
- // Open filtered folders for folder views with mAutoSelectOverride=TRUE.
- // Used by LLPlacesFolderView.
- if (mAutoSelectOverride && !mFilter->getFilterSubString().empty())
- {
- // these are named variables to get around gcc not binding non-const references to rvalues
- // and functor application is inherently non-const to allow for stateful functors
- LLOpenFilteredFolders functor;
- applyFunctorRecursively(functor);
- }
-
- scrollToShowSelection();
- }
-
- BOOL filter_finished = mCompletedFilterGeneration >= mFilter->getCurrentGeneration()
- && !LLInventoryModelBackgroundFetch::instance().folderFetchActive();
- if (filter_finished
- || gFocusMgr.childHasKeyboardFocus(inventory_panel)
- || gFocusMgr.childHasMouseCapture(inventory_panel))
- {
- // finishing the filter process, giving focus to the folder view, or dragging the scrollbar all stop the auto select process
- mNeedsAutoSelect = FALSE;
- }
-
-
- // during filtering process, try to pin selected item's location on screen
- // this will happen when searching your inventory and when new items arrive
- if (!filter_finished)
- {
- // calculate rectangle to pin item to at start of animated rearrange
- if (!mPinningSelectedItem && !mSelectedItems.empty())
- {
- // lets pin it!
- mPinningSelectedItem = TRUE;
-
- LLRect visible_content_rect = mScrollContainer->getVisibleContentRect();
- LLFolderViewItem* selected_item = mSelectedItems.back();
-
- LLRect item_rect;
- selected_item->localRectToOtherView(selected_item->getLocalRect(), &item_rect, this);
- // if item is visible in scrolled region
- if (visible_content_rect.overlaps(item_rect))
- {
- // then attempt to keep it in same place on screen
- mScrollConstraintRect = item_rect;
- mScrollConstraintRect.translate(-visible_content_rect.mLeft, -visible_content_rect.mBottom);
- }
- else
- {
- // otherwise we just want it onscreen somewhere
- LLRect content_rect = mScrollContainer->getContentWindowRect();
- mScrollConstraintRect.setOriginAndSize(0, 0, content_rect.getWidth(), content_rect.getHeight());
- }
- }
- }
- else
- {
- // stop pinning selected item after folders stop rearranging
- if (!needsArrange())
- {
- mPinningSelectedItem = FALSE;
- }
- }
-
- LLRect constraint_rect;
- if (mPinningSelectedItem)
- {
- // use last known constraint rect for pinned item
- constraint_rect = mScrollConstraintRect;
- }
- else
- {
- // during normal use (page up/page down, etc), just try to fit item on screen
- LLRect content_rect = mScrollContainer->getContentWindowRect();
- constraint_rect.setOriginAndSize(0, 0, content_rect.getWidth(), content_rect.getHeight());
- }
-
-
- BOOL is_visible = isInVisibleChain();
-
- if ( is_visible )
- {
- sanitizeSelection();
- if( needsArrange() )
- {
- arrangeFromRoot();
- }
- }
-
- if (mSelectedItems.size() && mNeedsScroll)
- {
- scrollToShowItem(mSelectedItems.back(), constraint_rect);
- // continue scrolling until animated layout change is done
- if (filter_finished
- && (!needsArrange() || !is_visible))
- {
- mNeedsScroll = FALSE;
- }
- }
-
- if (mSignalSelectCallback)
- {
- //RN: we use keyboard focus as a proxy for user-explicit actions
- BOOL take_keyboard_focus = (mSignalSelectCallback == SIGNAL_KEYBOARD_FOCUS);
- mSelectSignal(mSelectedItems, take_keyboard_focus);
- }
- mSignalSelectCallback = FALSE;
-}
-
-
-//static
-void LLFolderView::idle(void* user_data)
-{
- LLFolderView* self = (LLFolderView*)user_data;
- if ( self )
- { // Do the real idle
- self->doIdle();
- }
-}
-
-void LLFolderView::dumpSelectionInformation()
-{
- llinfos << "LLFolderView::dumpSelectionInformation()" << llendl;
- llinfos << "****************************************" << llendl;
- selected_items_t::iterator item_it;
- for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it)
- {
- llinfos << " " << (*item_it)->getName() << llendl;
- }
- llinfos << "****************************************" << llendl;
-}
-
-void LLFolderView::updateRenamerPosition()
-{
- if(mRenameItem)
- {
- // See also LLFolderViewItem::draw()
- S32 x = ARROW_SIZE + TEXT_PAD + ICON_WIDTH + ICON_PAD + mRenameItem->getIndentation();
- S32 y = mRenameItem->getRect().getHeight() - mRenameItem->getItemHeight() - RENAME_HEIGHT_PAD;
- mRenameItem->localPointToScreen( x, y, &x, &y );
- screenPointToLocal( x, y, &x, &y );
- mRenamer->setOrigin( x, y );
-
- LLRect scroller_rect(0, 0, gViewerWindow->getWindowWidthScaled(), 0);
- if (mScrollContainer)
- {
- scroller_rect = mScrollContainer->getContentWindowRect();
- }
-
- S32 width = llmax(llmin(mRenameItem->getRect().getWidth() - x, scroller_rect.getWidth() - x - getRect().mLeft), MINIMUM_RENAMER_WIDTH);
- S32 height = mRenameItem->getItemHeight() - RENAME_HEIGHT_PAD;
- mRenamer->reshape( width, height, TRUE );
- }
-}
-
-// Update visibility and availability (i.e. enabled/disabled) of context menu items.
-void LLFolderView::updateMenuOptions(LLMenuGL* menu)
-{
- const LLView::child_list_t *list = menu->getChildList();
-
- LLView::child_list_t::const_iterator menu_itor;
- for (menu_itor = list->begin(); menu_itor != list->end(); ++menu_itor)
- {
- (*menu_itor)->setVisible(FALSE);
- (*menu_itor)->pushVisible(TRUE);
- (*menu_itor)->setEnabled(TRUE);
- }
-
- // Successively filter out invalid options
-
- U32 flags = FIRST_SELECTED_ITEM;
- for (selected_items_t::iterator item_itor = mSelectedItems.begin();
- item_itor != mSelectedItems.end();
- ++item_itor)
- {
- LLFolderViewItem* selected_item = (*item_itor);
- selected_item->buildContextMenu(*menu, flags);
- flags = 0x0;
- }
-
- addNoOptions(menu);
-}
-
-// Refresh the context menu (that is already shown).
-void LLFolderView::updateMenu()
-{
- LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get();
- if (menu && menu->getVisible())
- {
- updateMenuOptions(menu);
- menu->needsArrange(); // update menu height if needed
- }
-}
-
-bool LLFolderView::selectFirstItem()
-{
- for (folders_t::iterator iter = mFolders.begin();
- iter != mFolders.end();++iter)
- {
- LLFolderViewFolder* folder = (*iter );
- if (folder->getVisible())
- {
- LLFolderViewItem* itemp = folder->getNextFromChild(0,true);
- if(itemp)
- setSelection(itemp,FALSE,TRUE);
- return true;
- }
-
- }
- for(items_t::iterator iit = mItems.begin();
- iit != mItems.end(); ++iit)
- {
- LLFolderViewItem* itemp = (*iit);
- if (itemp->getVisible())
- {
- setSelection(itemp,FALSE,TRUE);
- return true;
- }
- }
- return false;
-}
-bool LLFolderView::selectLastItem()
-{
- for(items_t::reverse_iterator iit = mItems.rbegin();
- iit != mItems.rend(); ++iit)
- {
- LLFolderViewItem* itemp = (*iit);
- if (itemp->getVisible())
- {
- setSelection(itemp,FALSE,TRUE);
- return true;
- }
- }
- for (folders_t::reverse_iterator iter = mFolders.rbegin();
- iter != mFolders.rend();++iter)
- {
- LLFolderViewFolder* folder = (*iter);
- if (folder->getVisible())
- {
- LLFolderViewItem* itemp = folder->getPreviousFromChild(0,true);
- if(itemp)
- setSelection(itemp,FALSE,TRUE);
- return true;
- }
- }
- return false;
-}
-
-
-S32 LLFolderView::notify(const LLSD& info)
-{
- if(info.has("action"))
- {
- std::string str_action = info["action"];
- if(str_action == "select_first")
- {
- setFocus(true);
- selectFirstItem();
- scrollToShowSelection();
- return 1;
-
- }
- else if(str_action == "select_last")
- {
- setFocus(true);
- selectLastItem();
- scrollToShowSelection();
- return 1;
- }
- }
- return 0;
-}
-
-
-///----------------------------------------------------------------------------
-/// Local function definitions
-///----------------------------------------------------------------------------
-
-void LLFolderView::onRenamerLost()
-{
- if (mRenamer && mRenamer->getVisible())
- {
- mRenamer->setVisible(FALSE);
-
- // will commit current name (which could be same as original name)
- mRenamer->setFocus(FALSE);
- }
-
- if( mRenameItem )
- {
- setSelectionFromRoot( mRenameItem, TRUE );
- mRenameItem = NULL;
- }
-}
-
-LLInventoryFilter* LLFolderView::getFilter()
-{
- return mFilter;
-}
-
-void LLFolderView::setFilterPermMask( PermissionMask filter_perm_mask )
-{
- mFilter->setFilterPermissions(filter_perm_mask);
-}
-
-U32 LLFolderView::getFilterObjectTypes() const
-{
- return mFilter->getFilterObjectTypes();
-}
-
-PermissionMask LLFolderView::getFilterPermissions() const
-{
- return mFilter->getFilterPermissions();
-}
-
-BOOL LLFolderView::isFilterModified()
-{
- return mFilter->isNotDefault();
-}
-
-void delete_selected_item(void* user_data)
-{
- if(user_data)
- {
- LLFolderView* fv = reinterpret_cast<LLFolderView*>(user_data);
- fv->removeSelectedItems();
- }
-}
-
-void copy_selected_item(void* user_data)
-{
- if(user_data)
- {
- LLFolderView* fv = reinterpret_cast<LLFolderView*>(user_data);
- fv->copy();
- }
-}
-
-void paste_items(void* user_data)
-{
- if(user_data)
- {
- LLFolderView* fv = reinterpret_cast<LLFolderView*>(user_data);
- fv->paste();
- }
-}
-
-void open_selected_items(void* user_data)
-{
- if(user_data)
- {
- LLFolderView* fv = reinterpret_cast<LLFolderView*>(user_data);
- fv->openSelectedItems();
- }
-}
-
-void properties_selected_items(void* user_data)
-{
- if(user_data)
- {
- LLFolderView* fv = reinterpret_cast<LLFolderView*>(user_data);
- fv->propertiesSelectedItems();
- }
-}
diff --git a/indra/newview/llfolderview.h b/indra/newview/llfolderview.h
deleted file mode 100644
index da8bb15f8e..0000000000
--- a/indra/newview/llfolderview.h
+++ /dev/null
@@ -1,375 +0,0 @@
-/**
- * @file llfolderview.h
- * @brief Definition of the folder view collection of classes.
- *
- * $LicenseInfo:firstyear=2001&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$
- */
-
-/**
- *
- * The folder view collection of classes provides an interface for
- * making a 'folder view' similar to the way the a single pane file
- * folder interface works.
- *
- */
-
-#ifndef LL_LLFOLDERVIEW_H
-#define LL_LLFOLDERVIEW_H
-
-#include "llfolderviewitem.h" // because LLFolderView is-a LLFolderViewFolder
-
-#include "lluictrl.h"
-#include "v4color.h"
-#include "lldarray.h"
-#include "stdenums.h"
-#include "lldepthstack.h"
-#include "lleditmenuhandler.h"
-#include "llfontgl.h"
-#include "llscrollcontainer.h"
-#include "lltooldraganddrop.h"
-#include "llviewertexture.h"
-
-class LLFolderViewEventListener;
-class LLFolderViewFolder;
-class LLFolderViewItem;
-class LLInventoryModel;
-class LLPanel;
-class LLLineEditor;
-class LLMenuGL;
-class LLUICtrl;
-class LLTextBox;
-
-/**
- * Class LLFolderViewScrollContainer
- *
- * A scroll container which provides the information about the height
- * of currently displayed folder view contents.
- * Used for updating vertical scroll bar visibility in inventory panel.
- * See LLScrollContainer::calcVisibleSize().
- */
-class LLFolderViewScrollContainer : public LLScrollContainer
-{
-public:
- /*virtual*/ ~LLFolderViewScrollContainer() {};
- /*virtual*/ const LLRect getScrolledViewRect() const;
-
-protected:
- LLFolderViewScrollContainer(const LLScrollContainer::Params& p);
- friend class LLUICtrlFactory;
-};
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Class LLFolderView
-//
-// The LLFolderView represents the root level folder view object.
-// It manages the screen region of the folder view.
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-class LLFolderView : public LLFolderViewFolder, public LLEditMenuHandler
-{
-public:
- struct Params : public LLInitParam::Block<Params, LLFolderViewFolder::Params>
- {
- Mandatory<LLPanel*> parent_panel;
- Optional<LLUUID> task_id;
- Optional<std::string> title;
- Optional<bool> use_label_suffix,
- allow_multiselect,
- show_empty_message,
- show_load_status,
- use_ellipses;
-
- Params();
- };
-
- friend class LLFolderViewScrollContainer;
-
- LLFolderView(const Params&);
- virtual ~LLFolderView( void );
-
- virtual BOOL canFocusChildren() const;
-
- virtual LLFolderView* getRoot() { return this; }
-
- // FolderViews default to sort by name. This will change that,
- // and resort the items if necessary.
- void setSortOrder(U32 order);
- void setFilterPermMask(PermissionMask filter_perm_mask);
-
- typedef boost::signals2::signal<void (const std::deque<LLFolderViewItem*>& items, BOOL user_action)> signal_t;
- void setSelectCallback(const signal_t::slot_type& cb) { mSelectSignal.connect(cb); }
- void setReshapeCallback(const signal_t::slot_type& cb) { mReshapeSignal.connect(cb); }
-
- // filter is never null
- LLInventoryFilter* getFilter();
- const std::string getFilterSubString(BOOL trim = FALSE);
- U32 getFilterObjectTypes() const;
- PermissionMask getFilterPermissions() const;
- // *NOTE: use getFilter()->getShowFolderState();
- //LLInventoryFilter::EFolderShow getShowFolderState();
- U32 getSortOrder() const;
- BOOL isFilterModified();
-
- bool getAllowMultiSelect() { return mAllowMultiSelect; }
-
- // Close all folders in the view
- void closeAllFolders();
- void openTopLevelFolders();
-
- virtual void toggleOpen() {};
- virtual void setOpenArrangeRecursively(BOOL openitem, ERecurseType recurse);
- virtual BOOL addFolder( LLFolderViewFolder* folder);
-
- // Find width and height of this object and its children. Also
- // makes sure that this view and its children are the right size.
- virtual S32 arrange( S32* width, S32* height, S32 filter_generation );
-
- void arrangeAll() { mArrangeGeneration++; }
- S32 getArrangeGeneration() { return mArrangeGeneration; }
-
- // Apply filters to control visibility of inventory items
- virtual void filter( LLInventoryFilter& filter);
-
- // Get the last selected item
- virtual LLFolderViewItem* getCurSelectedItem( void );
-
- // Record the selected item and pass it down the hierarchy.
- virtual BOOL setSelection(LLFolderViewItem* selection, BOOL openitem,
- BOOL take_keyboard_focus);
-
- // Used by menu callbacks
- void setSelectionByID(const LLUUID& obj_id, BOOL take_keyboard_focus);
-
- // Called once a frame to update the selection if mSelectThisID has been set
- void updateSelection();
-
- // This method is used to toggle the selection of an item.
- // Walks children and keeps track of selected objects.
- virtual BOOL changeSelection(LLFolderViewItem* selection, BOOL selected);
-
- virtual std::set<LLUUID> getSelectionList() const;
-
- // Make sure if ancestor is selected, descendents are not
- void sanitizeSelection();
- void clearSelection();
- void addToSelectionList(LLFolderViewItem* item);
- void removeFromSelectionList(LLFolderViewItem* item);
-
- BOOL startDrag(LLToolDragAndDrop::ESource source);
- void setDragAndDropThisFrame() { mDragAndDropThisFrame = TRUE; }
- void setDraggingOverItem(LLFolderViewItem* item) { mDraggingOverItem = item; }
- LLFolderViewItem* getDraggingOverItem() { return mDraggingOverItem; }
-
- // Deletion functionality
- void removeSelectedItems();
- static void removeCutItems();
-
- // Open the selected item
- void openSelectedItems( void );
- void propertiesSelectedItems( void );
-
- // Change the folder type
- void changeType(LLInventoryModel *model, LLFolderType::EType new_folder_type);
-
- void autoOpenItem(LLFolderViewFolder* item);
- void closeAutoOpenedFolders();
- BOOL autoOpenTest(LLFolderViewFolder* item);
-
- // Copy & paste
- virtual void copy();
- virtual BOOL canCopy() const;
-
- virtual void cut();
- virtual BOOL canCut() const;
-
- virtual void paste();
- virtual BOOL canPaste() const;
-
- virtual void doDelete();
- virtual BOOL canDoDelete() const;
-
- // Public rename functionality - can only start the process
- void startRenamingSelectedItem( void );
-
- // These functions were used when there was only one folderview,
- // and relied on that concept. This functionality is now handled
- // by the listeners and the lldraganddroptool.
- //LLFolderViewItem* getMovingItem() { return mMovingItem; }
- //void setMovingItem( LLFolderViewItem* item ) { mMovingItem = item; }
- //void dragItemIntoFolder( LLFolderViewItem* moving_item, LLFolderViewFolder* dst_folder, BOOL drop, BOOL* accept );
- //void dragFolderIntoFolder( LLFolderViewFolder* moving_folder, LLFolderViewFolder* dst_folder, BOOL drop, BOOL* accept );
-
- // LLView functionality
- ///*virtual*/ BOOL handleKey( KEY key, MASK mask, BOOL called_from_parent );
- /*virtual*/ BOOL handleKeyHere( KEY key, MASK mask );
- /*virtual*/ BOOL handleUnicodeCharHere(llwchar uni_char);
- /*virtual*/ BOOL handleMouseDown( S32 x, S32 y, MASK mask );
- /*virtual*/ BOOL handleDoubleClick( S32 x, S32 y, MASK mask );
- /*virtual*/ BOOL handleRightMouseDown( S32 x, S32 y, MASK mask );
- /*virtual*/ BOOL handleHover( S32 x, S32 y, MASK mask );
- /*virtual*/ BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
- EDragAndDropType cargo_type,
- void* cargo_data,
- EAcceptance* accept,
- std::string& tooltip_msg);
- /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
- /*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask) { setShowSelectionContext(FALSE); }
- virtual void draw();
- virtual void deleteAllChildren();
-
- void scrollToShowSelection();
- void scrollToShowItem(LLFolderViewItem* item, const LLRect& constraint_rect);
- void setScrollContainer( LLScrollContainer* parent ) { mScrollContainer = parent; }
- LLRect getVisibleRect();
-
- BOOL search(LLFolderViewItem* first_item, const std::string &search_string, BOOL backward);
- void setShowSelectionContext(BOOL show) { mShowSelectionContext = show; }
- BOOL getShowSelectionContext();
- void setShowSingleSelection(BOOL show);
- BOOL getShowSingleSelection() { return mShowSingleSelection; }
- F32 getSelectionFadeElapsedTime() { return mMultiSelectionFadeTimer.getElapsedTimeF32(); }
- bool getUseEllipses() { return mUseEllipses; }
-
- void addItemID(const LLUUID& id, LLFolderViewItem* itemp);
- void removeItemID(const LLUUID& id);
- LLFolderViewItem* getItemByID(const LLUUID& id);
- LLFolderViewFolder* getFolderByID(const LLUUID& id);
-
- bool doToSelected(LLInventoryModel* model, const LLSD& userdata);
-
- void doIdle(); // Real idle routine
- static void idle(void* user_data); // static glue to doIdle()
-
- BOOL needsAutoSelect() { return mNeedsAutoSelect && !mAutoSelectOverride; }
- BOOL needsAutoRename() { return mNeedsAutoRename; }
- void setNeedsAutoRename(BOOL val) { mNeedsAutoRename = val; }
- void setPinningSelectedItem(BOOL val) { mPinningSelectedItem = val; }
- void setAutoSelectOverride(BOOL val) { mAutoSelectOverride = val; }
-
- void setCallbackRegistrar(LLUICtrl::CommitCallbackRegistry::ScopedRegistrar* registrar) { mCallbackRegistrar = registrar; }
-
- BOOL getDebugFilters() { return mDebugFilters; }
-
- LLPanel* getParentPanel() { return mParentPanel; }
- // DEBUG only
- void dumpSelectionInformation();
-
- virtual S32 notify(const LLSD& info) ;
-
- bool useLabelSuffix() { return mUseLabelSuffix; }
- void updateMenu();
-
-private:
- void updateMenuOptions(LLMenuGL* menu);
- void updateRenamerPosition();
-
-protected:
- LLScrollContainer* mScrollContainer; // NULL if this is not a child of a scroll container.
-
- void commitRename( const LLSD& data );
- void onRenamerLost();
-
- void finishRenamingItem( void );
- void closeRenamer( void );
-
- bool selectFirstItem();
- bool selectLastItem();
-
- BOOL addNoOptions(LLMenuGL* menu) const;
-
- void onItemsRemovalConfirmation(const LLSD& notification, const LLSD& response);
-
-protected:
- LLHandle<LLView> mPopupMenuHandle;
-
- typedef std::deque<LLFolderViewItem*> selected_items_t;
- selected_items_t mSelectedItems;
- BOOL mKeyboardSelection;
- BOOL mAllowMultiSelect;
- BOOL mShowEmptyMessage;
- BOOL mShowFolderHierarchy;
- LLUUID mSourceID;
-
- // Renaming variables and methods
- LLFolderViewItem* mRenameItem; // The item currently being renamed
- LLLineEditor* mRenamer;
-
- BOOL mNeedsScroll;
- BOOL mPinningSelectedItem;
- LLRect mScrollConstraintRect;
- BOOL mNeedsAutoSelect;
- BOOL mAutoSelectOverride;
- BOOL mNeedsAutoRename;
- bool mUseLabelSuffix;
-
- BOOL mDebugFilters;
- U32 mSortOrder;
- LLDepthStack<LLFolderViewFolder> mAutoOpenItems;
- LLFolderViewFolder* mAutoOpenCandidate;
- LLFrameTimer mAutoOpenTimer;
- LLFrameTimer mSearchTimer;
- std::string mSearchString;
- LLInventoryFilter* mFilter;
- BOOL mShowSelectionContext;
- BOOL mShowSingleSelection;
- LLFrameTimer mMultiSelectionFadeTimer;
- S32 mArrangeGeneration;
-
- signal_t mSelectSignal;
- signal_t mReshapeSignal;
- S32 mSignalSelectCallback;
- S32 mMinWidth;
- S32 mRunningHeight;
- std::map<LLUUID, LLFolderViewItem*> mItemMap;
- BOOL mDragAndDropThisFrame;
-
- LLUUID mSelectThisID; // if non null, select this item
-
- LLPanel* mParentPanel;
-
- /**
- * Is used to determine if we need to cut text In LLFolderViewItem to avoid horizontal scroll.
- * NOTE: For now it's used only to cut LLFolderViewItem::mLabel text for Landmarks in Places Panel.
- */
- bool mUseEllipses; // See EXT-719
-
- /**
- * Contains item under mouse pointer while dragging
- */
- LLFolderViewItem* mDraggingOverItem; // See EXT-719
-
- LLUICtrl::CommitCallbackRegistry::ScopedRegistrar* mCallbackRegistrar;
-
-public:
- static F32 sAutoOpenTime;
- LLTextBox* mStatusTextBox;
-
-};
-
-bool sort_item_name(LLFolderViewItem* a, LLFolderViewItem* b);
-bool sort_item_date(LLFolderViewItem* a, LLFolderViewItem* b);
-
-// Flags for buildContextMenu()
-const U32 SUPPRESS_OPEN_ITEM = 0x1;
-const U32 FIRST_SELECTED_ITEM = 0x2;
-
-#endif // LL_LLFOLDERVIEW_H
diff --git a/indra/newview/llfoldervieweventlistener.h b/indra/newview/llfoldervieweventlistener.h
deleted file mode 100644
index 06682dcbf1..0000000000
--- a/indra/newview/llfoldervieweventlistener.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/**
- * @file llfoldervieweventlistener.h
- *
- * $LicenseInfo:firstyear=2001&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$
- */
-#ifndef LLFOLDERVIEWEVENTLISTENER_H
-#define LLFOLDERVIEWEVENTLISTENER_H
-
-#include "lldarray.h" // *TODO: convert to std::vector
-#include "llfoldertype.h"
-#include "llfontgl.h" // just for StyleFlags enum
-#include "llinventorytype.h"
-#include "llpermissionsflags.h"
-#include "llpointer.h"
-#include "llwearabletype.h"
-
-
-class LLFolderViewItem;
-class LLFolderView;
-class LLFontGL;
-class LLInventoryModel;
-class LLMenuGL;
-class LLScrollContainer;
-class LLUIImage;
-class LLUUID;
-
-// This is an abstract base class that users of the folderview classes
-// would use to catch the useful events emitted from the folder
-// views.
-class LLFolderViewEventListener
-{
-public:
- virtual ~LLFolderViewEventListener( void ) {}
- virtual const std::string& getName() const = 0;
- virtual const std::string& getDisplayName() const = 0;
- virtual const LLUUID& getUUID() const = 0;
- virtual time_t getCreationDate() const = 0; // UTC seconds
- virtual PermissionMask getPermissionMask() const = 0;
- virtual LLFolderType::EType getPreferredType() const = 0;
- virtual LLPointer<LLUIImage> getIcon() const = 0;
- virtual LLPointer<LLUIImage> getOpenIcon() const { return getIcon(); }
- virtual LLFontGL::StyleFlags getLabelStyle() const = 0;
- virtual std::string getLabelSuffix() const = 0;
- virtual void openItem( void ) = 0;
- virtual void closeItem( void ) = 0;
- virtual void previewItem( void ) = 0;
- virtual void selectItem(void) = 0;
- virtual void showProperties(void) = 0;
- virtual BOOL isItemRenameable() const = 0;
- virtual BOOL renameItem(const std::string& new_name) = 0;
- virtual BOOL isItemMovable( void ) const = 0; // Can be moved to another folder
- virtual BOOL isItemRemovable( void ) const = 0; // Can be destroyed
- virtual BOOL isItemInTrash( void) const { return FALSE; } // TODO: make into pure virtual.
- virtual BOOL removeItem() = 0;
- virtual void removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batch) = 0;
- virtual void move( LLFolderViewEventListener* parent_listener ) = 0;
- virtual BOOL isItemCopyable() const = 0;
- virtual BOOL copyToClipboard() const = 0;
- virtual BOOL cutToClipboard() const = 0;
- virtual BOOL isClipboardPasteable() const = 0;
- virtual void pasteFromClipboard() = 0;
- virtual void pasteLinkFromClipboard() = 0;
- virtual void buildContextMenu(LLMenuGL& menu, U32 flags) = 0;
- virtual BOOL isUpToDate() const = 0;
- virtual BOOL hasChildren() const = 0;
- virtual LLInventoryType::EType getInventoryType() const = 0;
- virtual void performAction(LLInventoryModel* model, std::string action) = 0;
- virtual LLWearableType::EType getWearableType() const = 0;
-
- // This method should be called when a drag begins. returns TRUE
- // if the drag can begin, otherwise FALSE.
- virtual BOOL startDrag(EDragAndDropType* type, LLUUID* id) const = 0;
-
- // This method will be called to determine if a drop can be
- // performed, and will set drop to TRUE if a drop is
- // requested. Returns TRUE if a drop is possible/happened,
- // otherwise FALSE.
- virtual BOOL dragOrDrop(MASK mask, BOOL drop,
- EDragAndDropType cargo_type,
- void* cargo_data,
- std::string& tooltip_msg) = 0;
-};
-
-#endif
diff --git a/indra/newview/llfolderviewitem.cpp b/indra/newview/llfolderviewitem.cpp
deleted file mode 100644
index d2b4866987..0000000000
--- a/indra/newview/llfolderviewitem.cpp
+++ /dev/null
@@ -1,2906 +0,0 @@
-/**
-* @file llfolderviewitem.cpp
-* @brief Items and folders that can appear in a hierarchical folder view
-*
-* $LicenseInfo:firstyear=2001&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 "llviewerprecompiledheaders.h"
-
-#include "llfolderviewitem.h"
-
-// viewer includes
-#include "llfolderview.h" // Items depend extensively on LLFolderViews
-#include "llfoldervieweventlistener.h"
-#include "llviewerfoldertype.h"
-#include "llinventorybridge.h" // for LLItemBridge in LLInventorySort::operator()
-#include "llinventoryfilter.h"
-#include "llinventoryfunctions.h"
-#include "llinventorymodelbackgroundfetch.h"
-#include "llpanel.h"
-#include "llviewercontrol.h" // gSavedSettings
-#include "llviewerwindow.h" // Argh, only for setCursor()
-
-// linden library includes
-#include "llclipboard.h"
-#include "llfocusmgr.h" // gFocusMgr
-#include "lltrans.h"
-
-///----------------------------------------------------------------------------
-/// Class LLFolderViewItem
-///----------------------------------------------------------------------------
-
-static LLDefaultChildRegistry::Register<LLFolderViewItem> r("folder_view_item");
-
-// statics
-std::map<U8, LLFontGL*> LLFolderViewItem::sFonts; // map of styles to fonts
-
-// only integers can be initialized in header
-const F32 LLFolderViewItem::FOLDER_CLOSE_TIME_CONSTANT = 0.02f;
-const F32 LLFolderViewItem::FOLDER_OPEN_TIME_CONSTANT = 0.03f;
-
-const LLColor4U DEFAULT_WHITE(255, 255, 255);
-
-
-//static
-LLFontGL* LLFolderViewItem::getLabelFontForStyle(U8 style)
-{
- LLFontGL* rtn = sFonts[style];
- if (!rtn) // grab label font with this style, lazily
- {
- LLFontDescriptor labelfontdesc("SansSerif", "Small", style);
- rtn = LLFontGL::getFont(labelfontdesc);
- if (!rtn)
- {
- rtn = LLFontGL::getFontDefault();
- }
- sFonts[style] = rtn;
- }
- return rtn;
-}
-
-//static
-void LLFolderViewItem::initClass()
-{
-}
-
-//static
-void LLFolderViewItem::cleanupClass()
-{
- sFonts.clear();
-}
-
-
-// NOTE: Optimize this, we call it a *lot* when opening a large inventory
-LLFolderViewItem::Params::Params()
-: icon(),
- icon_open(),
- icon_overlay(),
- root(),
- listener(),
- folder_arrow_image("folder_arrow_image"),
- folder_indentation("folder_indentation"),
- selection_image("selection_image"),
- item_height("item_height"),
- item_top_pad("item_top_pad"),
- creation_date()
-{}
-
-// Default constructor
-LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p)
-: LLView(p),
- mLabelWidth(0),
- mLabelWidthDirty(false),
- mParentFolder( NULL ),
- mIsSelected( FALSE ),
- mIsCurSelection( FALSE ),
- mSelectPending(FALSE),
- mLabelStyle( LLFontGL::NORMAL ),
- mHasVisibleChildren(FALSE),
- mIndentation(0),
- mItemHeight(p.item_height),
- mPassedFilter(FALSE),
- mLastFilterGeneration(-1),
- mStringMatchOffset(std::string::npos),
- mControlLabelRotation(0.f),
- mDragAndDropTarget(FALSE),
- mIsLoading(FALSE),
- mLabel(p.name),
- mRoot(p.root),
- mCreationDate(p.creation_date),
- mIcon(p.icon),
- mIconOpen(p.icon_open),
- mIconOverlay(p.icon_overlay),
- mListener(p.listener),
- mShowLoadStatus(false),
- mIsMouseOverTitle(false)
-{
-}
-
-BOOL LLFolderViewItem::postBuild()
-{
- refresh();
- return TRUE;
-}
-
-// Destroys the object
-LLFolderViewItem::~LLFolderViewItem( void )
-{
- delete mListener;
- mListener = NULL;
-}
-
-LLFolderView* LLFolderViewItem::getRoot()
-{
- return mRoot;
-}
-
-// Returns true if this object is a child (or grandchild, etc.) of potential_ancestor.
-BOOL LLFolderViewItem::isDescendantOf( const LLFolderViewFolder* potential_ancestor )
-{
- LLFolderViewItem* root = this;
- while( root->mParentFolder )
- {
- if( root->mParentFolder == potential_ancestor )
- {
- return TRUE;
- }
- root = root->mParentFolder;
- }
- return FALSE;
-}
-
-LLFolderViewItem* LLFolderViewItem::getNextOpenNode(BOOL include_children)
-{
- if (!mParentFolder)
- {
- return NULL;
- }
-
- LLFolderViewItem* itemp = mParentFolder->getNextFromChild( this, include_children );
- while(itemp && !itemp->getVisible())
- {
- LLFolderViewItem* next_itemp = itemp->mParentFolder->getNextFromChild( itemp, include_children );
- if (itemp == next_itemp)
- {
- // hit last item
- return itemp->getVisible() ? itemp : this;
- }
- itemp = next_itemp;
- }
-
- return itemp;
-}
-
-LLFolderViewItem* LLFolderViewItem::getPreviousOpenNode(BOOL include_children)
-{
- if (!mParentFolder)
- {
- return NULL;
- }
-
- LLFolderViewItem* itemp = mParentFolder->getPreviousFromChild( this, include_children );
-
- // Skip over items that are invisible or are hidden from the UI.
- while(itemp && !itemp->getVisible())
- {
- LLFolderViewItem* next_itemp = itemp->mParentFolder->getPreviousFromChild( itemp, include_children );
- if (itemp == next_itemp)
- {
- // hit first item
- return itemp->getVisible() ? itemp : this;
- }
- itemp = next_itemp;
- }
-
- return itemp;
-}
-
-// is this item something we think we should be showing?
-// for example, if we haven't gotten around to filtering it yet, then the answer is yes
-// until we find out otherwise
-BOOL LLFolderViewItem::potentiallyVisible()
-{
- // we haven't been checked against min required filter
- // or we have and we passed
- return potentiallyFiltered();
-}
-
-BOOL LLFolderViewItem::potentiallyFiltered()
-{
- return getLastFilterGeneration() < getRoot()->getFilter()->getMinRequiredGeneration() || getFiltered();
-}
-
-BOOL LLFolderViewItem::getFiltered()
-{
- return mPassedFilter && mLastFilterGeneration >= getRoot()->getFilter()->getMinRequiredGeneration();
-}
-
-BOOL LLFolderViewItem::getFiltered(S32 filter_generation)
-{
- return mPassedFilter && mLastFilterGeneration >= filter_generation;
-}
-
-void LLFolderViewItem::setFiltered(BOOL filtered, S32 filter_generation)
-{
- mPassedFilter = filtered;
- mLastFilterGeneration = filter_generation;
-}
-
-void LLFolderViewItem::setIcon(LLUIImagePtr icon)
-{
- mIcon = icon;
-}
-
-// refresh information from the listener
-void LLFolderViewItem::refreshFromListener()
-{
- if(mListener)
- {
- mLabel = mListener->getDisplayName();
- LLFolderType::EType preferred_type = mListener->getPreferredType();
-
- // *TODO: to be removed when database supports multi language. This is a
- // temporary attempt to display the inventory folder in the user locale.
- // mantipov: *NOTE: be sure this code is synchronized with LLFriendCardsManager::findChildFolderUUID
- // it uses the same way to find localized string
-
- // HACK: EXT - 6028 ([HARD CODED]? Inventory > Library > "Accessories" folder)
- // Translation of Accessories folder in Library inventory folder
- bool accessories = false;
- if(mLabel == std::string("Accessories"))
- {
- //To ensure that Accessories folder is in Library we have to check its parent folder.
- //Due to parent LLFolderViewFloder is not set to this item yet we have to check its parent via Inventory Model
- LLInventoryCategory* cat = gInventory.getCategory(mListener->getUUID());
- if(cat)
- {
- const LLUUID& parent_folder_id = cat->getParentUUID();
- accessories = (parent_folder_id == gInventory.getLibraryRootFolderID());
- }
- }
-
- //"Accessories" inventory category has folder type FT_NONE. So, this folder
- //can not be detected as protected with LLFolderType::lookupIsProtectedType
- if (accessories || LLFolderType::lookupIsProtectedType(preferred_type))
- {
- LLTrans::findString(mLabel, "InvFolder " + mLabel);
- };
-
- setToolTip(mLabel);
- setIcon(mListener->getIcon());
- time_t creation_date = mListener->getCreationDate();
- if ((creation_date > 0) && (mCreationDate != creation_date))
- {
- setCreationDate(creation_date);
- dirtyFilter();
- }
- if (mRoot->useLabelSuffix())
- {
- mLabelStyle = mListener->getLabelStyle();
- mLabelSuffix = mListener->getLabelSuffix();
- }
- }
-}
-
-void LLFolderViewItem::refresh()
-{
- refreshFromListener();
-
- std::string searchable_label(mLabel);
- searchable_label.append(mLabelSuffix);
- LLStringUtil::toUpper(searchable_label);
-
- if (mSearchableLabel.compare(searchable_label))
- {
- mSearchableLabel.assign(searchable_label);
- dirtyFilter();
- // some part of label has changed, so overall width has potentially changed, and sort order too
- if (mParentFolder)
- {
- mParentFolder->requestSort();
- mParentFolder->requestArrange();
- }
- }
-
- mLabelWidthDirty = true;
-}
-
-void LLFolderViewItem::applyListenerFunctorRecursively(LLFolderViewListenerFunctor& functor)
-{
- functor(mListener);
-}
-
-// This function is called when items are added or view filters change. It's
-// implemented here but called by derived classes when folding the
-// views.
-void LLFolderViewItem::filterFromRoot( void )
-{
- LLFolderViewItem* root = getRoot();
-
- root->filter(*((LLFolderView*)root)->getFilter());
-}
-
-// This function is called when the folder view is dirty. It's
-// implemented here but called by derived classes when folding the
-// views.
-void LLFolderViewItem::arrangeFromRoot()
-{
- LLFolderViewItem* root = getRoot();
-
- S32 height = 0;
- S32 width = 0;
- S32 total_height = root->arrange( &width, &height, 0 );
-
- LLSD params;
- params["action"] = "size_changes";
- params["height"] = total_height;
- getParent()->notifyParent(params);
-}
-
-// Utility function for LLFolderView
-void LLFolderViewItem::arrangeAndSet(BOOL set_selection,
- BOOL take_keyboard_focus)
-{
- LLFolderView* root = getRoot();
- if (getParentFolder())
- {
- getParentFolder()->requestArrange();
- }
- if(set_selection)
- {
- setSelectionFromRoot(this, TRUE, take_keyboard_focus);
- if(root)
- {
- root->scrollToShowSelection();
- }
- }
-}
-
-// This function clears the currently selected item, and records the
-// specified selected item appropriately for display and use in the
-// UI. If open is TRUE, then folders are opened up along the way to
-// the selection.
-void LLFolderViewItem::setSelectionFromRoot(LLFolderViewItem* selection,
- BOOL openitem,
- BOOL take_keyboard_focus)
-{
- getRoot()->setSelection(selection, openitem, take_keyboard_focus);
-}
-
-// helper function to change the selection from the root.
-void LLFolderViewItem::changeSelectionFromRoot(LLFolderViewItem* selection, BOOL selected)
-{
- getRoot()->changeSelection(selection, selected);
-}
-
-std::set<LLUUID> LLFolderViewItem::getSelectionList() const
-{
- std::set<LLUUID> selection;
- return selection;
-}
-
-EInventorySortGroup LLFolderViewItem::getSortGroup() const
-{
- return SG_ITEM;
-}
-
-// addToFolder() returns TRUE if it succeeds. FALSE otherwise
-BOOL LLFolderViewItem::addToFolder(LLFolderViewFolder* folder, LLFolderView* root)
-{
- if (!folder)
- {
- return FALSE;
- }
- mParentFolder = folder;
- root->addItemID(getListener()->getUUID(), this);
- return folder->addItem(this);
-}
-
-
-// Finds width and height of this object and its children. Also
-// makes sure that this view and its children are the right size.
-S32 LLFolderViewItem::arrange( S32* width, S32* height, S32 filter_generation)
-{
- const Params& p = LLUICtrlFactory::getDefaultParams<LLFolderViewItem>();
- S32 indentation = p.folder_indentation();
- // Only indent deeper items in hierarchy
- mIndentation = (getParentFolder()
- && getParentFolder()->getParentFolder() )
- ? mParentFolder->getIndentation() + indentation
- : 0;
- if (mLabelWidthDirty)
- {
- mLabelWidth = ARROW_SIZE + TEXT_PAD + ICON_WIDTH + ICON_PAD + getLabelFontForStyle(mLabelStyle)->getWidth(mLabel) + getLabelFontForStyle(mLabelStyle)->getWidth(mLabelSuffix) + TEXT_PAD_RIGHT;
- mLabelWidthDirty = false;
- }
-
- *width = llmax(*width, mLabelWidth + mIndentation);
-
- // determine if we need to use ellipses to avoid horizontal scroll. EXT-719
- bool use_ellipses = getRoot()->getUseEllipses();
- if (use_ellipses)
- {
- // limit to set rect to avoid horizontal scrollbar
- *width = llmin(*width, getRoot()->getRect().getWidth());
- }
- *height = getItemHeight();
- return *height;
-}
-
-S32 LLFolderViewItem::getItemHeight()
-{
- return mItemHeight;
-}
-
-void LLFolderViewItem::filter( LLInventoryFilter& filter)
-{
- const BOOL previous_passed_filter = mPassedFilter;
- const BOOL passed_filter = filter.check(this);
-
- // If our visibility will change as a result of this filter, then
- // we need to be rearranged in our parent folder
- if (mParentFolder)
- {
- if (getVisible() != passed_filter
- || previous_passed_filter != passed_filter )
- mParentFolder->requestArrange();
- }
-
- setFiltered(passed_filter, filter.getCurrentGeneration());
- mStringMatchOffset = filter.getStringMatchOffset();
- filter.decrementFilterCount();
-
- if (getRoot()->getDebugFilters())
- {
- mStatusText = llformat("%d", mLastFilterGeneration);
- }
-}
-
-void LLFolderViewItem::dirtyFilter()
-{
- mLastFilterGeneration = -1;
- // bubble up dirty flag all the way to root
- if (getParentFolder())
- {
- getParentFolder()->setCompletedFilterGeneration(-1, TRUE);
- }
-}
-
-// *TODO: This can be optimized a lot by simply recording that it is
-// selected in the appropriate places, and assuming that set selection
-// means 'deselect' for a leaf item. Do this optimization after
-// multiple selection is implemented to make sure it all plays nice
-// together.
-BOOL LLFolderViewItem::setSelection(LLFolderViewItem* selection, BOOL openitem, BOOL take_keyboard_focus)
-{
- if (selection == this && !mIsSelected)
- {
- selectItem();
- }
- else if (mIsSelected) // Deselect everything else.
- {
- deselectItem();
- }
- return mIsSelected;
-}
-
-BOOL LLFolderViewItem::changeSelection(LLFolderViewItem* selection, BOOL selected)
-{
- if (selection == this)
- {
- if (mIsSelected)
- {
- deselectItem();
- }
- else
- {
- selectItem();
- }
- return TRUE;
- }
- return FALSE;
-}
-
-void LLFolderViewItem::deselectItem(void)
-{
- mIsSelected = FALSE;
-}
-
-void LLFolderViewItem::selectItem(void)
-{
- if (mIsSelected == FALSE)
- {
- if (mListener)
- {
- mListener->selectItem();
- }
- mIsSelected = TRUE;
- }
-}
-
-BOOL LLFolderViewItem::isMovable()
-{
- if( mListener )
- {
- return mListener->isItemMovable();
- }
- else
- {
- return TRUE;
- }
-}
-
-BOOL LLFolderViewItem::isRemovable()
-{
- if( mListener )
- {
- return mListener->isItemRemovable();
- }
- else
- {
- return TRUE;
- }
-}
-
-void LLFolderViewItem::destroyView()
-{
- if (mParentFolder)
- {
- // removeView deletes me
- mParentFolder->removeView(this);
- }
-}
-
-// Call through to the viewed object and return true if it can be
-// removed.
-//BOOL LLFolderViewItem::removeRecursively(BOOL single_item)
-BOOL LLFolderViewItem::remove()
-{
- if(!isRemovable())
- {
- return FALSE;
- }
- if(mListener)
- {
- return mListener->removeItem();
- }
- return TRUE;
-}
-
-// Build an appropriate context menu for the item.
-void LLFolderViewItem::buildContextMenu(LLMenuGL& menu, U32 flags)
-{
- if(mListener)
- {
- mListener->buildContextMenu(menu, flags);
- }
-}
-
-void LLFolderViewItem::openItem( void )
-{
- if( mListener )
- {
- mListener->openItem();
- }
-}
-
-void LLFolderViewItem::preview( void )
-{
- if (mListener)
- {
- mListener->previewItem();
- }
-}
-
-void LLFolderViewItem::rename(const std::string& new_name)
-{
- if( !new_name.empty() )
- {
- if( mListener )
- {
- mListener->renameItem(new_name);
-
- if(mParentFolder)
- {
- mParentFolder->requestSort();
- }
- }
- }
-}
-
-const std::string& LLFolderViewItem::getSearchableLabel() const
-{
- return mSearchableLabel;
-}
-
-LLViewerInventoryItem * LLFolderViewItem::getInventoryItem(void)
-{
- if (!getListener()) return NULL;
- return gInventory.getItem(getListener()->getUUID());
-}
-
-const std::string& LLFolderViewItem::getName( void ) const
-{
- if(mListener)
- {
- return mListener->getName();
- }
- return mLabel;
-}
-
-// LLView functionality
-BOOL LLFolderViewItem::handleRightMouseDown( S32 x, S32 y, MASK mask )
-{
- if(!mIsSelected)
- {
- setSelectionFromRoot(this, FALSE);
- }
- make_ui_sound("UISndClick");
- return TRUE;
-}
-
-BOOL LLFolderViewItem::handleMouseDown( S32 x, S32 y, MASK mask )
-{
- if (LLView::childrenHandleMouseDown(x, y, mask))
- {
- return TRUE;
- }
-
- // No handler needed for focus lost since this class has no
- // state that depends on it.
- gFocusMgr.setMouseCapture( this );
-
- if (!mIsSelected)
- {
- if(mask & MASK_CONTROL)
- {
- changeSelectionFromRoot(this, !mIsSelected);
- }
- else if (mask & MASK_SHIFT)
- {
- getParentFolder()->extendSelectionTo(this);
- }
- else
- {
- setSelectionFromRoot(this, FALSE);
- }
- make_ui_sound("UISndClick");
- }
- else
- {
- mSelectPending = TRUE;
- }
-
- if( isMovable() )
- {
- S32 screen_x;
- S32 screen_y;
- localPointToScreen(x, y, &screen_x, &screen_y );
- LLToolDragAndDrop::getInstance()->setDragStart( screen_x, screen_y );
- }
- return TRUE;
-}
-
-BOOL LLFolderViewItem::handleHover( S32 x, S32 y, MASK mask )
-{
- mIsMouseOverTitle = (y > (getRect().getHeight() - mItemHeight));
-
- if( hasMouseCapture() && isMovable() )
- {
- S32 screen_x;
- S32 screen_y;
- localPointToScreen(x, y, &screen_x, &screen_y );
- BOOL can_drag = TRUE;
- if( LLToolDragAndDrop::getInstance()->isOverThreshold( screen_x, screen_y ) )
- {
- LLFolderView* root = getRoot();
-
- if(root->getCurSelectedItem())
- {
- LLToolDragAndDrop::ESource src = LLToolDragAndDrop::SOURCE_WORLD;
-
- // *TODO: push this into listener and remove
- // dependency on llagent
- if (mListener
- && gInventory.isObjectDescendentOf(mListener->getUUID(), gInventory.getRootFolderID()))
- {
- src = LLToolDragAndDrop::SOURCE_AGENT;
- }
- else if (mListener
- && gInventory.isObjectDescendentOf(mListener->getUUID(), gInventory.getLibraryRootFolderID()))
- {
- src = LLToolDragAndDrop::SOURCE_LIBRARY;
- }
-
- can_drag = root->startDrag(src);
- if (can_drag)
- {
- // if (mListener) mListener->startDrag();
- // RN: when starting drag and drop, clear out last auto-open
- root->autoOpenTest(NULL);
- root->setShowSelectionContext(TRUE);
-
- // Release keyboard focus, so that if stuff is dropped into the
- // world, pressing the delete key won't blow away the inventory
- // item.
- gFocusMgr.setKeyboardFocus(NULL);
-
- return LLToolDragAndDrop::getInstance()->handleHover( x, y, mask );
- }
- }
- }
-
- if (can_drag)
- {
- gViewerWindow->setCursor(UI_CURSOR_ARROW);
- }
- else
- {
- gViewerWindow->setCursor(UI_CURSOR_NOLOCKED);
- }
- return TRUE;
- }
- else
- {
- getRoot()->setShowSelectionContext(FALSE);
- gViewerWindow->setCursor(UI_CURSOR_ARROW);
- // let parent handle this then...
- return FALSE;
- }
-}
-
-
-BOOL LLFolderViewItem::handleDoubleClick( S32 x, S32 y, MASK mask )
-{
- preview();
- return TRUE;
-}
-
-BOOL LLFolderViewItem::handleMouseUp( S32 x, S32 y, MASK mask )
-{
- if (LLView::childrenHandleMouseUp(x, y, mask))
- {
- return TRUE;
- }
-
- // if mouse hasn't moved since mouse down...
- if ( pointInView(x, y) && mSelectPending )
- {
- //...then select
- if(mask & MASK_CONTROL)
- {
- changeSelectionFromRoot(this, !mIsSelected);
- }
- else if (mask & MASK_SHIFT)
- {
- getParentFolder()->extendSelectionTo(this);
- }
- else
- {
- setSelectionFromRoot(this, FALSE);
- }
- }
-
- mSelectPending = FALSE;
-
- if( hasMouseCapture() )
- {
- getRoot()->setShowSelectionContext(FALSE);
- gFocusMgr.setMouseCapture( NULL );
- }
- return TRUE;
-}
-
-void LLFolderViewItem::onMouseLeave(S32 x, S32 y, MASK mask)
-{
- mIsMouseOverTitle = false;
-}
-
-BOOL LLFolderViewItem::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
- EDragAndDropType cargo_type,
- void* cargo_data,
- EAcceptance* accept,
- std::string& tooltip_msg)
-{
- BOOL accepted = FALSE;
- BOOL handled = FALSE;
- if(mListener)
- {
- accepted = mListener->dragOrDrop(mask,drop,cargo_type,cargo_data, tooltip_msg);
- handled = accepted;
- if (accepted)
- {
- mDragAndDropTarget = TRUE;
- *accept = ACCEPT_YES_MULTI;
- }
- else
- {
- *accept = ACCEPT_NO;
- }
- }
- if(mParentFolder && !handled)
- {
- // store this item to get it in LLFolderBridge::dragItemIntoFolder on drop event.
- mRoot->setDraggingOverItem(this);
- handled = mParentFolder->handleDragAndDropFromChild(mask,drop,cargo_type,cargo_data,accept,tooltip_msg);
- mRoot->setDraggingOverItem(NULL);
- }
- if (handled)
- {
- lldebugst(LLERR_USER_INPUT) << "dragAndDrop handled by LLFolderViewItem" << llendl;
- }
-
- return handled;
-}
-
-void LLFolderViewItem::draw()
-{
- static LLUIColor sFgColor = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE);
- static LLUIColor sHighlightBgColor = LLUIColorTable::instance().getColor("MenuItemHighlightBgColor", DEFAULT_WHITE);
- static LLUIColor sHighlightFgColor = LLUIColorTable::instance().getColor("MenuItemHighlightFgColor", DEFAULT_WHITE);
- static LLUIColor sFocusOutlineColor = LLUIColorTable::instance().getColor("InventoryFocusOutlineColor", DEFAULT_WHITE);
- static LLUIColor sFilterBGColor = LLUIColorTable::instance().getColor("FilterBackgroundColor", DEFAULT_WHITE);
- static LLUIColor sFilterTextColor = LLUIColorTable::instance().getColor("FilterTextColor", DEFAULT_WHITE);
- static LLUIColor sSuffixColor = LLUIColorTable::instance().getColor("InventoryItemColor", DEFAULT_WHITE);
- static LLUIColor sLibraryColor = LLUIColorTable::instance().getColor("InventoryItemLibraryColor", DEFAULT_WHITE);
- static LLUIColor sLinkColor = LLUIColorTable::instance().getColor("InventoryItemLinkColor", DEFAULT_WHITE);
- static LLUIColor sSearchStatusColor = LLUIColorTable::instance().getColor("InventorySearchStatusColor", DEFAULT_WHITE);
- static LLUIColor sMouseOverColor = LLUIColorTable::instance().getColor("InventoryMouseOverColor", DEFAULT_WHITE);
-
- const Params& default_params = LLUICtrlFactory::getDefaultParams<LLFolderViewItem>();
- const S32 TOP_PAD = default_params.item_top_pad;
- const S32 FOCUS_LEFT = 1;
- const LLFontGL* font = getLabelFontForStyle(mLabelStyle);
-
- const BOOL in_inventory = getListener() && gInventory.isObjectDescendentOf(getListener()->getUUID(), gInventory.getRootFolderID());
- const BOOL in_library = getListener() && gInventory.isObjectDescendentOf(getListener()->getUUID(), gInventory.getLibraryRootFolderID());
-
- //--------------------------------------------------------------------------------//
- // Draw open folder arrow
- //
- const bool up_to_date = mListener && mListener->isUpToDate();
- const bool possibly_has_children = ((up_to_date && hasVisibleChildren()) // we fetched our children and some of them have passed the filter...
- || (!up_to_date && mListener && mListener->hasChildren())); // ...or we know we have children but haven't fetched them (doesn't obey filter)
- if (possibly_has_children)
- {
- LLUIImage* arrow_image = default_params.folder_arrow_image;
- gl_draw_scaled_rotated_image(
- mIndentation, getRect().getHeight() - ARROW_SIZE - TEXT_PAD - TOP_PAD,
- ARROW_SIZE, ARROW_SIZE, mControlLabelRotation, arrow_image->getImage(), sFgColor);
- }
-
-
- //--------------------------------------------------------------------------------//
- // Draw highlight for selected items
- //
- const BOOL show_context = getRoot()->getShowSelectionContext();
- const BOOL filled = show_context || (getRoot()->getParentPanel()->hasFocus()); // If we have keyboard focus, draw selection filled
- const S32 focus_top = getRect().getHeight();
- const S32 focus_bottom = getRect().getHeight() - mItemHeight;
- const bool folder_open = (getRect().getHeight() > mItemHeight + 4);
- if (mIsSelected) // always render "current" item. Only render other selected items if mShowSingleSelection is FALSE
- {
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- LLColor4 bg_color = sHighlightBgColor;
- if (!mIsCurSelection)
- {
- // do time-based fade of extra objects
- F32 fade_time = getRoot()->getSelectionFadeElapsedTime();
- if (getRoot()->getShowSingleSelection())
- {
- // fading out
- bg_color.mV[VALPHA] = clamp_rescale(fade_time, 0.f, 0.4f, bg_color.mV[VALPHA], 0.f);
- }
- else
- {
- // fading in
- bg_color.mV[VALPHA] = clamp_rescale(fade_time, 0.f, 0.4f, 0.f, bg_color.mV[VALPHA]);
- }
- }
- gl_rect_2d(FOCUS_LEFT,
- focus_top,
- getRect().getWidth() - 2,
- focus_bottom,
- bg_color, filled);
- if (mIsCurSelection)
- {
- gl_rect_2d(FOCUS_LEFT,
- focus_top,
- getRect().getWidth() - 2,
- focus_bottom,
- sFocusOutlineColor, FALSE);
- }
- if (folder_open)
- {
- gl_rect_2d(FOCUS_LEFT,
- focus_bottom + 1, // overlap with bottom edge of above rect
- getRect().getWidth() - 2,
- 0,
- sFocusOutlineColor, FALSE);
- if (show_context)
- {
- gl_rect_2d(FOCUS_LEFT,
- focus_bottom + 1,
- getRect().getWidth() - 2,
- 0,
- sHighlightBgColor, TRUE);
- }
- }
- }
- else if (mIsMouseOverTitle)
- {
- gl_rect_2d(FOCUS_LEFT,
- focus_top,
- getRect().getWidth() - 2,
- focus_bottom,
- sMouseOverColor, FALSE);
- }
-
- //--------------------------------------------------------------------------------//
- // Draw DragNDrop highlight
- //
- if (mDragAndDropTarget)
- {
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- gl_rect_2d(FOCUS_LEFT,
- focus_top,
- getRect().getWidth() - 2,
- focus_bottom,
- sHighlightBgColor, FALSE);
- if (folder_open)
- {
- gl_rect_2d(FOCUS_LEFT,
- focus_bottom + 1, // overlap with bottom edge of above rect
- getRect().getWidth() - 2,
- 0,
- sHighlightBgColor, FALSE);
- }
- mDragAndDropTarget = FALSE;
- }
-
- const LLViewerInventoryItem *item = getInventoryItem();
- const BOOL highlight_link = mIconOverlay && item && item->getIsLinkType();
- //--------------------------------------------------------------------------------//
- // Draw open icon
- //
- const S32 icon_x = mIndentation + ARROW_SIZE + TEXT_PAD;
- if (!mIconOpen.isNull() && (llabs(mControlLabelRotation) > 80)) // For open folders
- {
- mIconOpen->draw(icon_x, getRect().getHeight() - mIconOpen->getHeight() - TOP_PAD + 1);
- }
- else if (mIcon)
- {
- mIcon->draw(icon_x, getRect().getHeight() - mIcon->getHeight() - TOP_PAD + 1);
- }
-
- if (highlight_link)
- {
- mIconOverlay->draw(icon_x, getRect().getHeight() - mIcon->getHeight() - TOP_PAD + 1);
- }
-
- //--------------------------------------------------------------------------------//
- // Exit if no label to draw
- //
- if (mLabel.empty())
- {
- return;
- }
-
- LLColor4 color = (mIsSelected && filled) ? sHighlightFgColor : sFgColor;
- if (highlight_link) color = sLinkColor;
- if (in_library) color = sLibraryColor;
-
- F32 right_x = 0;
- F32 y = (F32)getRect().getHeight() - font->getLineHeight() - (F32)TEXT_PAD - (F32)TOP_PAD;
- F32 text_left = (F32)(ARROW_SIZE + TEXT_PAD + ICON_WIDTH + ICON_PAD + mIndentation);
-
- //--------------------------------------------------------------------------------//
- // Highlight filtered text
- //
- if (getRoot()->getDebugFilters())
- {
- if (!getFiltered() && !possibly_has_children)
- {
- color.mV[VALPHA] *= 0.5f;
- }
- LLColor4 filter_color = mLastFilterGeneration >= getRoot()->getFilter()->getCurrentGeneration() ?
- LLColor4(0.5f, 0.8f, 0.5f, 1.f) :
- LLColor4(0.8f, 0.5f, 0.5f, 1.f);
- LLFontGL::getFontMonospace()->renderUTF8(mStatusText, 0, text_left, y, filter_color,
- LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
- S32_MAX, S32_MAX, &right_x, FALSE );
- text_left = right_x;
- }
- //--------------------------------------------------------------------------------//
- // Draw the actual label text
- //
- font->renderUTF8(mLabel, 0, text_left, y, color,
- LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
- S32_MAX, getRect().getWidth() - (S32) text_left, &right_x, TRUE);
-
- //--------------------------------------------------------------------------------//
- // Draw "Loading..." text
- //
- bool root_is_loading = false;
- if (in_inventory)
- {
- root_is_loading = LLInventoryModelBackgroundFetch::instance().inventoryFetchInProgress();
- }
- if (in_library)
- {
- root_is_loading = LLInventoryModelBackgroundFetch::instance().libraryFetchInProgress();
- }
- if ((mIsLoading
- && mTimeSinceRequestStart.getElapsedTimeF32() >= gSavedSettings.getF32("FolderLoadingMessageWaitTime"))
- || (LLInventoryModelBackgroundFetch::instance().folderFetchActive()
- && root_is_loading
- && mShowLoadStatus))
- {
- std::string load_string = " ( " + LLTrans::getString("LoadingData") + " ) ";
- font->renderUTF8(load_string, 0, right_x, y, sSearchStatusColor,
- LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
- S32_MAX, S32_MAX, &right_x, FALSE);
- }
-
- //--------------------------------------------------------------------------------//
- // Draw label suffix
- //
- if (!mLabelSuffix.empty())
- {
- font->renderUTF8( mLabelSuffix, 0, right_x, y, sSuffixColor,
- LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
- S32_MAX, S32_MAX, &right_x, FALSE );
- }
-
- //--------------------------------------------------------------------------------//
- // Highlight string match
- //
- if (mStringMatchOffset != std::string::npos)
- {
- // don't draw backgrounds for zero-length strings
- S32 filter_string_length = getRoot()->getFilterSubString().size();
- if (filter_string_length > 0)
- {
- std::string combined_string = mLabel + mLabelSuffix;
- S32 left = llround(text_left) + font->getWidth(combined_string, 0, mStringMatchOffset) - 1;
- S32 right = left + font->getWidth(combined_string, mStringMatchOffset, filter_string_length) + 2;
- S32 bottom = llfloor(getRect().getHeight() - font->getLineHeight() - 3 - TOP_PAD);
- S32 top = getRect().getHeight() - TOP_PAD;
-
- LLUIImage* box_image = default_params.selection_image;
- LLRect box_rect(left, top, right, bottom);
- box_image->draw(box_rect, sFilterBGColor);
- F32 match_string_left = text_left + font->getWidthF32(combined_string, 0, mStringMatchOffset);
- F32 yy = (F32)getRect().getHeight() - font->getLineHeight() - (F32)TEXT_PAD - (F32)TOP_PAD;
- font->renderUTF8( combined_string, mStringMatchOffset, match_string_left, yy,
- sFilterTextColor, LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
- filter_string_length, S32_MAX, &right_x, FALSE );
- }
- }
-}
-
-
-///----------------------------------------------------------------------------
-/// Class LLFolderViewFolder
-///----------------------------------------------------------------------------
-
-LLFolderViewFolder::LLFolderViewFolder( const LLFolderViewItem::Params& p ):
- LLFolderViewItem( p ), // 0 = no create time
- mIsOpen(FALSE),
- mExpanderHighlighted(FALSE),
- mCurHeight(0.f),
- mTargetHeight(0.f),
- mAutoOpenCountdown(0.f),
- mSubtreeCreationDate(0),
- mAmTrash(LLFolderViewFolder::UNKNOWN),
- mLastArrangeGeneration( -1 ),
- mLastCalculatedWidth(0),
- mCompletedFilterGeneration(-1),
- mMostFilteredDescendantGeneration(-1),
- mNeedsSort(false),
- mPassedFolderFilter(FALSE)
-{
-}
-
-// Destroys the object
-LLFolderViewFolder::~LLFolderViewFolder( void )
-{
- // The LLView base class takes care of object destruction. make sure that we
- // don't have mouse or keyboard focus
- gFocusMgr.releaseFocusIfNeeded( this ); // calls onCommit()
-}
-
-void LLFolderViewFolder::setFilteredFolder(bool filtered, S32 filter_generation)
-{
- mPassedFolderFilter = filtered;
- mLastFilterGeneration = filter_generation;
-}
-
-bool LLFolderViewFolder::getFilteredFolder(S32 filter_generation)
-{
- return mPassedFolderFilter && mLastFilterGeneration >= getRoot()->getFilter()->getMinRequiredGeneration();
-}
-
-// addToFolder() returns TRUE if it succeeds. FALSE otherwise
-BOOL LLFolderViewFolder::addToFolder(LLFolderViewFolder* folder, LLFolderView* root)
-{
- if (!folder)
- {
- return FALSE;
- }
- mParentFolder = folder;
- root->addItemID(getListener()->getUUID(), this);
- return folder->addFolder(this);
-}
-
-// Finds width and height of this object and its children. Also
-// makes sure that this view and its children are the right size.
-S32 LLFolderViewFolder::arrange( S32* width, S32* height, S32 filter_generation)
-{
- // sort before laying out contents
- if (mNeedsSort)
- {
- mFolders.sort(mSortFunction);
- mItems.sort(mSortFunction);
- mNeedsSort = false;
- }
-
- // evaluate mHasVisibleChildren
- mHasVisibleChildren = false;
- if (hasFilteredDescendants(filter_generation))
- {
- // We have to verify that there's at least one child that's not filtered out
- bool found = false;
- // Try the items first
- for (items_t::iterator iit = mItems.begin(); iit != mItems.end(); ++iit)
- {
- LLFolderViewItem* itemp = (*iit);
- found = (itemp->getFiltered(filter_generation));
- if (found)
- break;
- }
- if (!found)
- {
- // If no item found, try the folders
- for (folders_t::iterator fit = mFolders.begin(); fit != mFolders.end(); ++fit)
- {
- LLFolderViewFolder* folderp = (*fit);
- found = ( folderp->getListener()
- && (folderp->getFiltered(filter_generation)
- || (folderp->getFilteredFolder(filter_generation)
- && folderp->hasFilteredDescendants(filter_generation))));
- if (found)
- break;
- }
- }
-
- mHasVisibleChildren = found;
- }
-
- // calculate height as a single item (without any children), and reshapes rectangle to match
- LLFolderViewItem::arrange( width, height, filter_generation );
-
- // clamp existing animated height so as to never get smaller than a single item
- mCurHeight = llmax((F32)*height, mCurHeight);
-
- // initialize running height value as height of single item in case we have no children
- *height = getItemHeight();
- F32 running_height = (F32)*height;
- F32 target_height = (F32)*height;
-
- // are my children visible?
- if (needsArrange())
- {
- // set last arrange generation first, in case children are animating
- // and need to be arranged again
- mLastArrangeGeneration = getRoot()->getArrangeGeneration();
- if (mIsOpen)
- {
- // Add sizes of children
- S32 parent_item_height = getRect().getHeight();
-
- for(folders_t::iterator fit = mFolders.begin(); fit != mFolders.end(); ++fit)
- {
- LLFolderViewFolder* folderp = (*fit);
- if (getRoot()->getDebugFilters())
- {
- folderp->setVisible(TRUE);
- }
- else
- {
- folderp->setVisible( folderp->getListener()
- && (folderp->getFiltered(filter_generation)
- || (folderp->getFilteredFolder(filter_generation)
- && folderp->hasFilteredDescendants(filter_generation)))); // passed filter or has descendants that passed filter
- }
-
- if (folderp->getVisible())
- {
- S32 child_width = *width;
- S32 child_height = 0;
- S32 child_top = parent_item_height - llround(running_height);
-
- target_height += folderp->arrange( &child_width, &child_height, filter_generation );
-
- running_height += (F32)child_height;
- *width = llmax(*width, child_width);
- folderp->setOrigin( 0, child_top - folderp->getRect().getHeight() );
- }
- }
- for(items_t::iterator iit = mItems.begin();
- iit != mItems.end(); ++iit)
- {
- LLFolderViewItem* itemp = (*iit);
- if (getRoot()->getDebugFilters())
- {
- itemp->setVisible(TRUE);
- }
- else
- {
- itemp->setVisible(itemp->getFiltered(filter_generation));
- }
-
- if (itemp->getVisible())
- {
- S32 child_width = *width;
- S32 child_height = 0;
- S32 child_top = parent_item_height - llround(running_height);
-
- target_height += itemp->arrange( &child_width, &child_height, filter_generation );
- // don't change width, as this item is as wide as its parent folder by construction
- itemp->reshape( itemp->getRect().getWidth(), child_height);
-
- running_height += (F32)child_height;
- *width = llmax(*width, child_width);
- itemp->setOrigin( 0, child_top - itemp->getRect().getHeight() );
- }
- }
- }
-
- mTargetHeight = target_height;
- // cache this width so next time we can just return it
- mLastCalculatedWidth = *width;
- }
- else
- {
- // just use existing width
- *width = mLastCalculatedWidth;
- }
-
- // animate current height towards target height
- if (llabs(mCurHeight - mTargetHeight) > 1.f)
- {
- mCurHeight = lerp(mCurHeight, mTargetHeight, LLCriticalDamp::getInterpolant(mIsOpen ? FOLDER_OPEN_TIME_CONSTANT : FOLDER_CLOSE_TIME_CONSTANT));
-
- requestArrange();
-
- // hide child elements that fall out of current animated height
- for (folders_t::iterator iter = mFolders.begin();
- iter != mFolders.end();)
- {
- folders_t::iterator fit = iter++;
- // number of pixels that bottom of folder label is from top of parent folder
- if (getRect().getHeight() - (*fit)->getRect().mTop + (*fit)->getItemHeight()
- > llround(mCurHeight) + MAX_FOLDER_ITEM_OVERLAP)
- {
- // hide if beyond current folder height
- (*fit)->setVisible(FALSE);
- }
- }
-
- for (items_t::iterator iter = mItems.begin();
- iter != mItems.end();)
- {
- items_t::iterator iit = iter++;
- // number of pixels that bottom of item label is from top of parent folder
- if (getRect().getHeight() - (*iit)->getRect().mBottom
- > llround(mCurHeight) + MAX_FOLDER_ITEM_OVERLAP)
- {
- (*iit)->setVisible(FALSE);
- }
- }
- }
- else
- {
- mCurHeight = mTargetHeight;
- }
-
- // don't change width as this item is already as wide as its parent folder
- reshape(getRect().getWidth(),llround(mCurHeight));
-
- // pass current height value back to parent
- *height = llround(mCurHeight);
-
- return llround(mTargetHeight);
-}
-
-BOOL LLFolderViewFolder::needsArrange()
-{
- return mLastArrangeGeneration < getRoot()->getArrangeGeneration();
-}
-
-void LLFolderViewFolder::requestSort()
-{
- mNeedsSort = true;
- // whenever item order changes, we need to lay things out again
- requestArrange();
-}
-
-void LLFolderViewFolder::setCompletedFilterGeneration(S32 generation, BOOL recurse_up)
-{
- //mMostFilteredDescendantGeneration = llmin(mMostFilteredDescendantGeneration, generation);
- mCompletedFilterGeneration = generation;
- // only aggregate up if we are a lower (older) value
- if (recurse_up
- && mParentFolder
- && generation < mParentFolder->getCompletedFilterGeneration())
- {
- mParentFolder->setCompletedFilterGeneration(generation, TRUE);
- }
-}
-
-void LLFolderViewFolder::filter( LLInventoryFilter& filter)
-{
- S32 filter_generation = filter.getCurrentGeneration();
- // if failed to pass filter newer than must_pass_generation
- // you will automatically fail this time, so we only
- // check against items that have passed the filter
- S32 must_pass_generation = filter.getMustPassGeneration();
-
- bool autoopen_folders = (filter.hasFilterString());
-
- // if we have already been filtered against this generation, skip out
- if (getCompletedFilterGeneration() >= filter_generation)
- {
- return;
- }
-
- // filter folder itself
- if (getLastFilterGeneration() < filter_generation)
- {
- if (getLastFilterGeneration() >= must_pass_generation // folder has been compared to a valid precursor filter
- && !mPassedFilter) // and did not pass the filter
- {
- // go ahead and flag this folder as done
- mLastFilterGeneration = filter_generation;
- mStringMatchOffset = std::string::npos;
- }
- else // filter self only on first pass through
- {
- // filter against folder rules
- filterFolder(filter);
- // and then item rules
- LLFolderViewItem::filter( filter );
- }
- }
-
- if (getRoot()->getDebugFilters())
- {
- mStatusText = llformat("%d", mLastFilterGeneration);
- mStatusText += llformat("(%d)", mCompletedFilterGeneration);
- mStatusText += llformat("+%d", mMostFilteredDescendantGeneration);
- }
-
- // all descendants have been filtered later than must pass generation
- // but none passed
- if(getCompletedFilterGeneration() >= must_pass_generation && !hasFilteredDescendants(must_pass_generation))
- {
- // don't traverse children if we've already filtered them since must_pass_generation
- // and came back with nothing
- return;
- }
-
- // we entered here with at least one filter iteration left
- // check to see if we have any more before continuing on to children
- if (filter.getFilterCount() < 0)
- {
- return;
- }
-
- // when applying a filter, matching folders get their contents downloaded first
- if (filter.isNotDefault()
- && getFiltered(filter.getMinRequiredGeneration())
- && (mListener
- && !gInventory.isCategoryComplete(mListener->getUUID())))
- {
- LLInventoryModelBackgroundFetch::instance().start(mListener->getUUID());
- }
-
- // now query children
- for (folders_t::iterator iter = mFolders.begin();
- iter != mFolders.end();
- ++iter)
- {
- LLFolderViewFolder* folder = (*iter);
- // have we run out of iterations this frame?
- if (filter.getFilterCount() < 0)
- {
- break;
- }
-
- // mMostFilteredDescendantGeneration might have been reset
- // in which case we need to update it even for folders that
- // don't need to be filtered anymore
- if (folder->getCompletedFilterGeneration() >= filter_generation)
- {
- // track latest generation to pass any child items
- if (folder->getFiltered() || folder->hasFilteredDescendants(filter.getMinRequiredGeneration()))
- {
- mMostFilteredDescendantGeneration = filter_generation;
- requestArrange();
- }
- // just skip it, it has already been filtered
- continue;
- }
-
- // update this folders filter status (and children)
- folder->filter( filter );
-
- // track latest generation to pass any child items
- if (folder->getFiltered() || folder->hasFilteredDescendants(filter_generation))
- {
- mMostFilteredDescendantGeneration = filter_generation;
- requestArrange();
- if (getRoot()->needsAutoSelect() && autoopen_folders)
- {
- folder->setOpenArrangeRecursively(TRUE);
- }
- }
- }
-
- for (items_t::iterator iter = mItems.begin();
- iter != mItems.end();
- ++iter)
- {
- LLFolderViewItem* item = (*iter);
- if (filter.getFilterCount() < 0)
- {
- break;
- }
- if (item->getLastFilterGeneration() >= filter_generation)
- {
- if (item->getFiltered())
- {
- mMostFilteredDescendantGeneration = filter_generation;
- requestArrange();
- }
- continue;
- }
-
- if (item->getLastFilterGeneration() >= must_pass_generation &&
- !item->getFiltered(must_pass_generation))
- {
- // failed to pass an earlier filter that was a subset of the current one
- // go ahead and flag this item as done
- item->setFiltered(FALSE, filter_generation);
- continue;
- }
-
- item->filter( filter );
-
- if (item->getFiltered(filter.getMinRequiredGeneration()))
- {
- mMostFilteredDescendantGeneration = filter_generation;
- requestArrange();
- }
- }
-
- // if we didn't use all filter iterations
- // that means we filtered all of our descendants
- // instead of exhausting the filter count for this frame
- if (filter.getFilterCount() > 0)
- {
- // flag this folder as having completed filter pass for all descendants
- setCompletedFilterGeneration(filter_generation, FALSE/*dont recurse up to root*/);
- }
-}
-
-void LLFolderViewFolder::filterFolder(LLInventoryFilter& filter)
-{
- const BOOL previous_passed_filter = mPassedFolderFilter;
- const BOOL passed_filter = filter.checkFolder(this);
-
- // If our visibility will change as a result of this filter, then
- // we need to be rearranged in our parent folder
- if (mParentFolder)
- {
- if (getVisible() != passed_filter
- || previous_passed_filter != passed_filter )
- {
- mParentFolder->requestArrange();
- }
- }
-
- setFilteredFolder(passed_filter, filter.getCurrentGeneration());
- filter.decrementFilterCount();
-
- if (getRoot()->getDebugFilters())
- {
- mStatusText = llformat("%d", mLastFilterGeneration);
- }
-}
-
-void LLFolderViewFolder::setFiltered(BOOL filtered, S32 filter_generation)
-{
- // if this folder is now filtered, but wasn't before
- // (it just passed)
- if (filtered && !mPassedFilter)
- {
- // reset current height, because last time we drew it
- // it might have had more visible items than now
- mCurHeight = 0.f;
- }
-
- LLFolderViewItem::setFiltered(filtered, filter_generation);
-}
-
-void LLFolderViewFolder::dirtyFilter()
-{
- // we're a folder, so invalidate our completed generation
- setCompletedFilterGeneration(-1, FALSE);
- LLFolderViewItem::dirtyFilter();
-}
-
-BOOL LLFolderViewFolder::getFiltered()
-{
- return getFilteredFolder(getRoot()->getFilter()->getMinRequiredGeneration())
- && LLFolderViewItem::getFiltered();
-}
-
-BOOL LLFolderViewFolder::getFiltered(S32 filter_generation)
-{
- return getFilteredFolder(filter_generation) && LLFolderViewItem::getFiltered(filter_generation);
-}
-
-BOOL LLFolderViewFolder::hasFilteredDescendants(S32 filter_generation)
-{
- return mMostFilteredDescendantGeneration >= filter_generation;
-}
-
-
-BOOL LLFolderViewFolder::hasFilteredDescendants()
-{
- return mMostFilteredDescendantGeneration >= getRoot()->getFilter()->getCurrentGeneration();
-}
-
-// Passes selection information on to children and record selection
-// information if necessary.
-BOOL LLFolderViewFolder::setSelection(LLFolderViewItem* selection, BOOL openitem,
- BOOL take_keyboard_focus)
-{
- BOOL rv = FALSE;
- if (selection == this)
- {
- if (!isSelected())
- {
- selectItem();
- }
- rv = TRUE;
- }
- else
- {
- if (isSelected())
- {
- deselectItem();
- }
- rv = FALSE;
- }
- BOOL child_selected = FALSE;
-
- for (folders_t::iterator iter = mFolders.begin();
- iter != mFolders.end();)
- {
- folders_t::iterator fit = iter++;
- if((*fit)->setSelection(selection, openitem, take_keyboard_focus))
- {
- rv = TRUE;
- child_selected = TRUE;
- }
- }
- for (items_t::iterator iter = mItems.begin();
- iter != mItems.end();)
- {
- items_t::iterator iit = iter++;
- if((*iit)->setSelection(selection, openitem, take_keyboard_focus))
- {
- rv = TRUE;
- child_selected = TRUE;
- }
- }
- if(openitem && child_selected)
- {
- setOpenArrangeRecursively(TRUE);
- }
- return rv;
-}
-
-// This method is used to change the selection of an item.
-// Recursively traverse all children; if 'selection' is 'this' then change
-// the select status if necessary.
-// Returns TRUE if the selection state of this folder, or of a child, was changed.
-BOOL LLFolderViewFolder::changeSelection(LLFolderViewItem* selection, BOOL selected)
-{
- BOOL rv = FALSE;
- if(selection == this)
- {
- if (isSelected() != selected)
- {
- rv = TRUE;
- if (selected)
- {
- selectItem();
- }
- else
- {
- deselectItem();
- }
- }
- }
-
- for (folders_t::iterator iter = mFolders.begin();
- iter != mFolders.end();)
- {
- folders_t::iterator fit = iter++;
- if((*fit)->changeSelection(selection, selected))
- {
- rv = TRUE;
- }
- }
- for (items_t::iterator iter = mItems.begin();
- iter != mItems.end();)
- {
- items_t::iterator iit = iter++;
- if((*iit)->changeSelection(selection, selected))
- {
- rv = TRUE;
- }
- }
- return rv;
-}
-
-LLFolderViewFolder* LLFolderViewFolder::getCommonAncestor(LLFolderViewItem* item_a, LLFolderViewItem* item_b, bool& reverse)
-{
- if (!item_a->getParentFolder() || !item_b->getParentFolder()) return NULL;
-
- std::deque<LLFolderViewFolder*> item_a_ancestors;
-
- LLFolderViewFolder* parent = item_a->getParentFolder();
- while(parent)
- {
- item_a_ancestors.push_back(parent);
- parent = parent->getParentFolder();
- }
-
- std::deque<LLFolderViewFolder*> item_b_ancestors;
-
- parent = item_b->getParentFolder();
- while(parent)
- {
- item_b_ancestors.push_back(parent);
- parent = parent->getParentFolder();
- }
-
- LLFolderViewFolder* common_ancestor = item_a->getRoot();
-
- while(item_a_ancestors.size() > item_b_ancestors.size())
- {
- item_a = item_a_ancestors.front();
- item_a_ancestors.pop_front();
- }
-
- while(item_b_ancestors.size() > item_a_ancestors.size())
- {
- item_b = item_b_ancestors.front();
- item_b_ancestors.pop_front();
- }
-
- while(item_a_ancestors.size())
- {
- common_ancestor = item_a_ancestors.front();
-
- if (item_a_ancestors.front() == item_b_ancestors.front())
- {
- // which came first, sibling a or sibling b?
- for (folders_t::iterator it = common_ancestor->mFolders.begin(), end_it = common_ancestor->mFolders.end();
- it != end_it;
- ++it)
- {
- LLFolderViewItem* item = *it;
-
- if (item == item_a)
- {
- reverse = false;
- return common_ancestor;
- }
- if (item == item_b)
- {
- reverse = true;
- return common_ancestor;
- }
- }
-
- for (items_t::iterator it = common_ancestor->mItems.begin(), end_it = common_ancestor->mItems.end();
- it != end_it;
- ++it)
- {
- LLFolderViewItem* item = *it;
-
- if (item == item_a)
- {
- reverse = false;
- return common_ancestor;
- }
- if (item == item_b)
- {
- reverse = true;
- return common_ancestor;
- }
- }
- break;
- }
-
- item_a = item_a_ancestors.front();
- item_a_ancestors.pop_front();
- item_b = item_b_ancestors.front();
- item_b_ancestors.pop_front();
- }
-
- return NULL;
-}
-
-void LLFolderViewFolder::gatherChildRangeExclusive(LLFolderViewItem* start, LLFolderViewItem* end, bool reverse, std::vector<LLFolderViewItem*>& items)
-{
- bool selecting = start == NULL;
- if (reverse)
- {
- for (items_t::reverse_iterator it = mItems.rbegin(), end_it = mItems.rend();
- it != end_it;
- ++it)
- {
- if (*it == end)
- {
- return;
- }
- if (selecting)
- {
- items.push_back(*it);
- }
-
- if (*it == start)
- {
- selecting = true;
- }
- }
- for (folders_t::reverse_iterator it = mFolders.rbegin(), end_it = mFolders.rend();
- it != end_it;
- ++it)
- {
- if (*it == end)
- {
- return;
- }
-
- if (selecting)
- {
- items.push_back(*it);
- }
-
- if (*it == start)
- {
- selecting = true;
- }
- }
- }
- else
- {
- for (folders_t::iterator it = mFolders.begin(), end_it = mFolders.end();
- it != end_it;
- ++it)
- {
- if (*it == end)
- {
- return;
- }
-
- if (selecting)
- {
- items.push_back(*it);
- }
-
- if (*it == start)
- {
- selecting = true;
- }
- }
- for (items_t::iterator it = mItems.begin(), end_it = mItems.end();
- it != end_it;
- ++it)
- {
- if (*it == end)
- {
- return;
- }
-
- if (selecting)
- {
- items.push_back(*it);
- }
-
- if (*it == start)
- {
- selecting = true;
- }
- }
- }
-}
-
-void LLFolderViewFolder::extendSelectionTo(LLFolderViewItem* new_selection)
-{
- if (getRoot()->getAllowMultiSelect() == FALSE) return;
-
- LLFolderViewItem* cur_selected_item = getRoot()->getCurSelectedItem();
- if (cur_selected_item == NULL)
- {
- cur_selected_item = new_selection;
- }
-
-
- bool reverse = false;
- LLFolderViewFolder* common_ancestor = getCommonAncestor(cur_selected_item, new_selection, reverse);
- if (!common_ancestor) return;
-
- LLFolderViewItem* last_selected_item_from_cur = cur_selected_item;
- LLFolderViewFolder* cur_folder = cur_selected_item->getParentFolder();
-
- std::vector<LLFolderViewItem*> items_to_select_forward;
-
- while(cur_folder != common_ancestor)
- {
- cur_folder->gatherChildRangeExclusive(last_selected_item_from_cur, NULL, reverse, items_to_select_forward);
-
- last_selected_item_from_cur = cur_folder;
- cur_folder = cur_folder->getParentFolder();
- }
-
- std::vector<LLFolderViewItem*> items_to_select_reverse;
-
- LLFolderViewItem* last_selected_item_from_new = new_selection;
- cur_folder = new_selection->getParentFolder();
- while(cur_folder != common_ancestor)
- {
- cur_folder->gatherChildRangeExclusive(last_selected_item_from_new, NULL, !reverse, items_to_select_reverse);
-
- last_selected_item_from_new = cur_folder;
- cur_folder = cur_folder->getParentFolder();
- }
-
- common_ancestor->gatherChildRangeExclusive(last_selected_item_from_cur, last_selected_item_from_new, reverse, items_to_select_forward);
-
- for (std::vector<LLFolderViewItem*>::reverse_iterator it = items_to_select_reverse.rbegin(), end_it = items_to_select_reverse.rend();
- it != end_it;
- ++it)
- {
- items_to_select_forward.push_back(*it);
- }
-
- LLFolderView* root = getRoot();
-
- for (std::vector<LLFolderViewItem*>::iterator it = items_to_select_forward.begin(), end_it = items_to_select_forward.end();
- it != end_it;
- ++it)
- {
- LLFolderViewItem* item = *it;
- if (item->isSelected())
- {
- root->removeFromSelectionList(item);
- }
- else
- {
- item->selectItem();
- }
- root->addToSelectionList(item);
- }
-
- if (new_selection->isSelected())
- {
- root->removeFromSelectionList(new_selection);
- }
- else
- {
- new_selection->selectItem();
- }
- root->addToSelectionList(new_selection);
-}
-
-
-void LLFolderViewFolder::destroyView()
-{
- for (items_t::iterator iter = mItems.begin();
- iter != mItems.end();)
- {
- items_t::iterator iit = iter++;
- LLFolderViewItem* item = (*iit);
- getRoot()->removeItemID(item->getListener()->getUUID());
- }
-
- std::for_each(mItems.begin(), mItems.end(), DeletePointer());
- mItems.clear();
-
- while (!mFolders.empty())
- {
- LLFolderViewFolder *folderp = mFolders.back();
- folderp->destroyView(); // removes entry from mFolders
- }
-
- //deleteAllChildren();
-
- if (mParentFolder)
- {
- mParentFolder->removeView(this);
- }
-}
-
-// remove the specified item (and any children) if possible. Return
-// TRUE if the item was deleted.
-BOOL LLFolderViewFolder::removeItem(LLFolderViewItem* item)
-{
- if(item->remove())
- {
- return TRUE;
- }
- return FALSE;
-}
-
-// simply remove the view (and any children) Don't bother telling the
-// listeners.
-void LLFolderViewFolder::removeView(LLFolderViewItem* item)
-{
- if (!item || item->getParentFolder() != this)
- {
- return;
- }
- // deselect without traversing hierarchy
- if (item->isSelected())
- {
- item->deselectItem();
- }
- getRoot()->removeFromSelectionList(item);
- extractItem(item);
- delete item;
-}
-
-// extractItem() removes the specified item from the folder, but
-// doesn't delete it.
-void LLFolderViewFolder::extractItem( LLFolderViewItem* item )
-{
- items_t::iterator it = std::find(mItems.begin(), mItems.end(), item);
- if(it == mItems.end())
- {
- // This is an evil downcast. However, it's only doing
- // pointer comparison to find if (which it should be ) the
- // item is in the container, so it's pretty safe.
- LLFolderViewFolder* f = static_cast<LLFolderViewFolder*>(item);
- folders_t::iterator ft;
- ft = std::find(mFolders.begin(), mFolders.end(), f);
- if (ft != mFolders.end())
- {
- mFolders.erase(ft);
- }
- }
- else
- {
- mItems.erase(it);
- }
- //item has been removed, need to update filter
- dirtyFilter();
- //because an item is going away regardless of filter status, force rearrange
- requestArrange();
- getRoot()->removeItemID(item->getListener()->getUUID());
- removeChild(item);
-}
-
-bool LLFolderViewFolder::isTrash() const
-{
- if (mAmTrash == LLFolderViewFolder::UNKNOWN)
- {
- mAmTrash = mListener->getUUID() == gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH, false) ? LLFolderViewFolder::TRASH : LLFolderViewFolder::NOT_TRASH;
- }
- return mAmTrash == LLFolderViewFolder::TRASH;
-}
-
-void LLFolderViewFolder::sortBy(U32 order)
-{
- if (!mSortFunction.updateSort(order))
- {
- // No changes.
- return;
- }
-
- // Propagate this change to sub folders
- for (folders_t::iterator iter = mFolders.begin();
- iter != mFolders.end();)
- {
- folders_t::iterator fit = iter++;
- (*fit)->sortBy(order);
- }
-
- // Don't sort the topmost folders (My Inventory and Library)
- if (mListener->getUUID().notNull())
- {
- mFolders.sort(mSortFunction);
- mItems.sort(mSortFunction);
- }
-
- if (order & LLInventoryFilter::SO_DATE)
- {
- time_t latest = 0;
-
- if (!mItems.empty())
- {
- LLFolderViewItem* item = *(mItems.begin());
- latest = item->getCreationDate();
- }
-
- if (!mFolders.empty())
- {
- LLFolderViewFolder* folder = *(mFolders.begin());
- if (folder->getCreationDate() > latest)
- {
- latest = folder->getCreationDate();
- }
- }
- mSubtreeCreationDate = latest;
- }
-}
-
-void LLFolderViewFolder::setItemSortOrder(U32 ordering)
-{
- if (mSortFunction.updateSort(ordering))
- {
- for (folders_t::iterator iter = mFolders.begin();
- iter != mFolders.end();)
- {
- folders_t::iterator fit = iter++;
- (*fit)->setItemSortOrder(ordering);
- }
-
- mFolders.sort(mSortFunction);
- mItems.sort(mSortFunction);
- }
-}
-
-EInventorySortGroup LLFolderViewFolder::getSortGroup() const
-{
- if (isTrash())
- {
- return SG_TRASH_FOLDER;
- }
-
- if( mListener )
- {
- if(LLFolderType::lookupIsProtectedType(mListener->getPreferredType()))
- {
- return SG_SYSTEM_FOLDER;
- }
- }
-
- return SG_NORMAL_FOLDER;
-}
-
-BOOL LLFolderViewFolder::isMovable()
-{
- if( mListener )
- {
- if( !(mListener->isItemMovable()) )
- {
- return FALSE;
- }
-
- for (items_t::iterator iter = mItems.begin();
- iter != mItems.end();)
- {
- items_t::iterator iit = iter++;
- if(!(*iit)->isMovable())
- {
- return FALSE;
- }
- }
-
- for (folders_t::iterator iter = mFolders.begin();
- iter != mFolders.end();)
- {
- folders_t::iterator fit = iter++;
- if(!(*fit)->isMovable())
- {
- return FALSE;
- }
- }
- }
- return TRUE;
-}
-
-
-BOOL LLFolderViewFolder::isRemovable()
-{
- if( mListener )
- {
- if( !(mListener->isItemRemovable()) )
- {
- return FALSE;
- }
-
- for (items_t::iterator iter = mItems.begin();
- iter != mItems.end();)
- {
- items_t::iterator iit = iter++;
- if(!(*iit)->isRemovable())
- {
- return FALSE;
- }
- }
-
- for (folders_t::iterator iter = mFolders.begin();
- iter != mFolders.end();)
- {
- folders_t::iterator fit = iter++;
- if(!(*fit)->isRemovable())
- {
- return FALSE;
- }
- }
- }
- return TRUE;
-}
-
-// this is an internal method used for adding items to folders.
-BOOL LLFolderViewFolder::addItem(LLFolderViewItem* item)
-{
- mItems.push_back(item);
-
- item->setRect(LLRect(0, 0, getRect().getWidth(), 0));
- item->setVisible(FALSE);
-
- addChild(item);
-
- item->dirtyFilter();
-
- // Update the folder creation date if the folder has no creation date
- bool setting_date = false;
- const time_t item_creation_date = item->getCreationDate();
- if ((item_creation_date > 0) && (mCreationDate == 0))
- {
- setCreationDate(item_creation_date);
- setting_date = true;
- }
-
- // Handle sorting
- requestArrange();
- requestSort();
-
- // Traverse parent folders and update creation date and resort, if necessary
- LLFolderViewFolder* parentp = getParentFolder();
- while (parentp)
- {
- // Update the parent folder creation date
- if (setting_date && (parentp->mCreationDate == 0))
- {
- parentp->setCreationDate(item_creation_date);
- }
-
- if (parentp->mSortFunction.isByDate())
- {
- // parent folder doesn't have a time stamp yet, so get it from us
- parentp->requestSort();
- }
-
- parentp = parentp->getParentFolder();
- }
-
- return TRUE;
-}
-
-// this is an internal method used for adding items to folders.
-BOOL LLFolderViewFolder::addFolder(LLFolderViewFolder* folder)
-{
- mFolders.push_back(folder);
- folder->setOrigin(0, 0);
- folder->reshape(getRect().getWidth(), 0);
- folder->setVisible(FALSE);
- addChild( folder );
- folder->dirtyFilter();
- // rearrange all descendants too, as our indentation level might have changed
- folder->requestArrange(TRUE);
- requestSort();
- LLFolderViewFolder* parentp = getParentFolder();
- while (parentp && !parentp->mSortFunction.isByDate())
- {
- // parent folder doesn't have a time stamp yet, so get it from us
- parentp->requestSort();
- parentp = parentp->getParentFolder();
- }
- return TRUE;
-}
-
-void LLFolderViewFolder::requestArrange(BOOL include_descendants)
-{
- mLastArrangeGeneration = -1;
- // flag all items up to root
- if (mParentFolder)
- {
- mParentFolder->requestArrange();
- }
-
- if (include_descendants)
- {
- for (folders_t::iterator iter = mFolders.begin();
- iter != mFolders.end();
- ++iter)
- {
- (*iter)->requestArrange(TRUE);
- }
- }
-}
-
-void LLFolderViewFolder::toggleOpen()
-{
- setOpen(!mIsOpen);
-}
-
-// Force a folder open or closed
-void LLFolderViewFolder::setOpen(BOOL openitem)
-{
- setOpenArrangeRecursively(openitem);
-}
-
-void LLFolderViewFolder::setOpenArrangeRecursively(BOOL openitem, ERecurseType recurse)
-{
- BOOL was_open = mIsOpen;
- mIsOpen = openitem;
- if (mListener)
- {
- if(!was_open && openitem)
- {
- mListener->openItem();
- }
- else if(was_open && !openitem)
- {
- mListener->closeItem();
- }
- }
-
- if (recurse == RECURSE_DOWN || recurse == RECURSE_UP_DOWN)
- {
- for (folders_t::iterator iter = mFolders.begin();
- iter != mFolders.end();)
- {
- folders_t::iterator fit = iter++;
- (*fit)->setOpenArrangeRecursively(openitem, RECURSE_DOWN); /* Flawfinder: ignore */
- }
- }
- if (mParentFolder
- && (recurse == RECURSE_UP
- || recurse == RECURSE_UP_DOWN))
- {
- mParentFolder->setOpenArrangeRecursively(openitem, RECURSE_UP);
- }
-
- if (was_open != mIsOpen)
- {
- requestArrange();
- }
-}
-
-BOOL LLFolderViewFolder::handleDragAndDropFromChild(MASK mask,
- BOOL drop,
- EDragAndDropType c_type,
- void* cargo_data,
- EAcceptance* accept,
- std::string& tooltip_msg)
-{
- BOOL accepted = mListener && mListener->dragOrDrop(mask,drop,c_type,cargo_data, tooltip_msg);
- if (accepted)
- {
- mDragAndDropTarget = TRUE;
- *accept = ACCEPT_YES_MULTI;
- }
- else
- {
- *accept = ACCEPT_NO;
- }
-
- // drag and drop to child item, so clear pending auto-opens
- getRoot()->autoOpenTest(NULL);
-
- return TRUE;
-}
-
-void LLFolderViewFolder::openItem( void )
-{
- toggleOpen();
-}
-
-void LLFolderViewFolder::applyFunctorToChildren(LLFolderViewFunctor& functor)
-{
- for (folders_t::iterator iter = mFolders.begin();
- iter != mFolders.end();)
- {
- folders_t::iterator fit = iter++;
- functor.doItem((*fit));
- }
- for (items_t::iterator iter = mItems.begin();
- iter != mItems.end();)
- {
- items_t::iterator iit = iter++;
- functor.doItem((*iit));
- }
-}
-
-void LLFolderViewFolder::applyFunctorRecursively(LLFolderViewFunctor& functor)
-{
- functor.doFolder(this);
-
- for (folders_t::iterator iter = mFolders.begin();
- iter != mFolders.end();)
- {
- folders_t::iterator fit = iter++;
- (*fit)->applyFunctorRecursively(functor);
- }
- for (items_t::iterator iter = mItems.begin();
- iter != mItems.end();)
- {
- items_t::iterator iit = iter++;
- functor.doItem((*iit));
- }
-}
-
-void LLFolderViewFolder::applyListenerFunctorRecursively(LLFolderViewListenerFunctor& functor)
-{
- functor(mListener);
- for (folders_t::iterator iter = mFolders.begin();
- iter != mFolders.end();)
- {
- folders_t::iterator fit = iter++;
- (*fit)->applyListenerFunctorRecursively(functor);
- }
- for (items_t::iterator iter = mItems.begin();
- iter != mItems.end();)
- {
- items_t::iterator iit = iter++;
- (*iit)->applyListenerFunctorRecursively(functor);
- }
-}
-
-// LLView functionality
-BOOL LLFolderViewFolder::handleDragAndDrop(S32 x, S32 y, MASK mask,
- BOOL drop,
- EDragAndDropType cargo_type,
- void* cargo_data,
- EAcceptance* accept,
- std::string& tooltip_msg)
-{
- BOOL handled = FALSE;
-
- if (mIsOpen)
- {
- handled = (childrenHandleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg) != NULL);
- }
-
- if (!handled)
- {
- handleDragAndDropToThisFolder(mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
-
- lldebugst(LLERR_USER_INPUT) << "dragAndDrop handled by LLFolderViewFolder" << llendl;
- }
-
- return TRUE;
-}
-
-BOOL LLFolderViewFolder::handleDragAndDropToThisFolder(MASK mask,
- BOOL drop,
- EDragAndDropType cargo_type,
- void* cargo_data,
- EAcceptance* accept,
- std::string& tooltip_msg)
-{
- BOOL accepted = mListener && mListener->dragOrDrop(mask, drop, cargo_type, cargo_data, tooltip_msg);
-
- if (accepted)
- {
- mDragAndDropTarget = TRUE;
- *accept = ACCEPT_YES_MULTI;
- }
- else
- {
- *accept = ACCEPT_NO;
- }
-
- if (!drop && accepted)
- {
- getRoot()->autoOpenTest(this);
- }
-
- return TRUE;
-}
-
-
-BOOL LLFolderViewFolder::handleRightMouseDown( S32 x, S32 y, MASK mask )
-{
- BOOL handled = FALSE;
- // fetch contents of this folder, as context menu can depend on contents
- // still, user would have to open context menu again to see the changes
- gInventory.fetchDescendentsOf(mListener->getUUID());
-
- if( mIsOpen )
- {
- handled = childrenHandleRightMouseDown( x, y, mask ) != NULL;
- }
- if (!handled)
- {
- handled = LLFolderViewItem::handleRightMouseDown( x, y, mask );
- }
- return handled;
-}
-
-
-BOOL LLFolderViewFolder::handleHover(S32 x, S32 y, MASK mask)
-{
- mIsMouseOverTitle = (y > (getRect().getHeight() - mItemHeight));
-
- BOOL handled = LLView::handleHover(x, y, mask);
-
- if (!handled)
- {
- // this doesn't do child processing
- handled = LLFolderViewItem::handleHover(x, y, mask);
- }
-
- return handled;
-}
-
-BOOL LLFolderViewFolder::handleMouseDown( S32 x, S32 y, MASK mask )
-{
- BOOL handled = FALSE;
- if( mIsOpen )
- {
- handled = childrenHandleMouseDown(x,y,mask) != NULL;
- }
- if( !handled )
- {
- if(mIndentation < x && x < mIndentation + ARROW_SIZE + TEXT_PAD)
- {
- toggleOpen();
- handled = TRUE;
- }
- else
- {
- // do normal selection logic
- handled = LLFolderViewItem::handleMouseDown(x, y, mask);
- }
- }
-
- return handled;
-}
-
-BOOL LLFolderViewFolder::handleDoubleClick( S32 x, S32 y, MASK mask )
-{
- /* Disable outfit double click to wear
- const LLUUID &cat_uuid = getListener()->getUUID();
- const LLViewerInventoryCategory *cat = gInventory.getCategory(cat_uuid);
- if (cat && cat->getPreferredType() == LLFolderType::FT_OUTFIT)
- {
- getListener()->performAction(NULL, NULL,"replaceoutfit");
- return TRUE;
- }
- */
-
- BOOL handled = FALSE;
- if( mIsOpen )
- {
- handled = childrenHandleDoubleClick( x, y, mask ) != NULL;
- }
- if( !handled )
- {
- if(mIndentation < x && x < mIndentation + ARROW_SIZE + TEXT_PAD)
- {
- // don't select when user double-clicks plus sign
- // so as not to contradict single-click behavior
- toggleOpen();
- }
- else
- {
- setSelectionFromRoot(this, FALSE);
- toggleOpen();
- }
- handled = TRUE;
- }
- return handled;
-}
-
-void LLFolderViewFolder::draw()
-{
- if (mAutoOpenCountdown != 0.f)
- {
- mControlLabelRotation = mAutoOpenCountdown * -90.f;
- }
- else if (mIsOpen)
- {
- mControlLabelRotation = lerp(mControlLabelRotation, -90.f, LLCriticalDamp::getInterpolant(0.04f));
- }
- else
- {
- mControlLabelRotation = lerp(mControlLabelRotation, 0.f, LLCriticalDamp::getInterpolant(0.025f));
- }
-
- bool possibly_has_children = false;
- bool up_to_date = mListener && mListener->isUpToDate();
- if(!up_to_date
- && mListener->hasChildren()) // we know we have children but haven't fetched them (doesn't obey filter)
- {
- possibly_has_children = true;
- }
-
-
- BOOL loading = (mIsOpen
- && possibly_has_children
- && !up_to_date );
-
- if ( loading && !mIsLoading )
- {
- // Measure how long we've been in the loading state
- mTimeSinceRequestStart.reset();
- }
-
- mIsLoading = loading;
-
- LLFolderViewItem::draw();
-
- // draw children if root folder, or any other folder that is open or animating to closed state
- if( getRoot() == this || (mIsOpen || mCurHeight != mTargetHeight ))
- {
- LLView::draw();
- }
-
- mExpanderHighlighted = FALSE;
-}
-
-time_t LLFolderViewFolder::getCreationDate() const
-{
- return llmax<time_t>(mCreationDate, mSubtreeCreationDate);
-}
-
-
-BOOL LLFolderViewFolder::potentiallyVisible()
-{
- // folder should be visible by it's own filter status
- return LLFolderViewItem::potentiallyVisible()
- // or one or more of its descendants have passed the minimum filter requirement
- || hasFilteredDescendants(getRoot()->getFilter()->getMinRequiredGeneration())
- // or not all of its descendants have been checked against minimum filter requirement
- || getCompletedFilterGeneration() < getRoot()->getFilter()->getMinRequiredGeneration();
-}
-
-// this does prefix traversal, as folders are listed above their contents
-LLFolderViewItem* LLFolderViewFolder::getNextFromChild( LLFolderViewItem* item, BOOL include_children )
-{
- BOOL found_item = FALSE;
-
- LLFolderViewItem* result = NULL;
- // when not starting from a given item, start at beginning
- if(item == NULL)
- {
- found_item = TRUE;
- }
-
- // find current item among children
- folders_t::iterator fit = mFolders.begin();
- folders_t::iterator fend = mFolders.end();
-
- items_t::iterator iit = mItems.begin();
- items_t::iterator iend = mItems.end();
-
- // if not trivially starting at the beginning, we have to find the current item
- if (!found_item)
- {
- // first, look among folders, since they are always above items
- for(; fit != fend; ++fit)
- {
- if(item == (*fit))
- {
- found_item = TRUE;
- // if we are on downwards traversal
- if (include_children && (*fit)->isOpen())
- {
- // look for first descendant
- return (*fit)->getNextFromChild(NULL, TRUE);
- }
- // otherwise advance to next folder
- ++fit;
- include_children = TRUE;
- break;
- }
- }
-
- // didn't find in folders? Check items...
- if (!found_item)
- {
- for(; iit != iend; ++iit)
- {
- if(item == (*iit))
- {
- found_item = TRUE;
- // point to next item
- ++iit;
- break;
- }
- }
- }
- }
-
- if (!found_item)
- {
- // you should never call this method with an item that isn't a child
- // so we should always find something
- llassert(FALSE);
- return NULL;
- }
-
- // at this point, either iit or fit point to a candidate "next" item
- // if both are out of range, we need to punt up to our parent
-
- // now, starting from found folder, continue through folders
- // searching for next visible folder
- while(fit != fend && !(*fit)->getVisible())
- {
- // turn on downwards traversal for next folder
- ++fit;
- }
-
- if (fit != fend)
- {
- result = (*fit);
- }
- else
- {
- // otherwise, scan for next visible item
- while(iit != iend && !(*iit)->getVisible())
- {
- ++iit;
- }
-
- // check to see if we have a valid item
- if (iit != iend)
- {
- result = (*iit);
- }
- }
-
- if( !result && mParentFolder )
- {
- // If there are no siblings or children to go to, recurse up one level in the tree
- // and skip children for this folder, as we've already discounted them
- result = mParentFolder->getNextFromChild(this, FALSE);
- }
-
- return result;
-}
-
-// this does postfix traversal, as folders are listed above their contents
-LLFolderViewItem* LLFolderViewFolder::getPreviousFromChild( LLFolderViewItem* item, BOOL include_children )
-{
- BOOL found_item = FALSE;
-
- LLFolderViewItem* result = NULL;
- // when not starting from a given item, start at end
- if(item == NULL)
- {
- found_item = TRUE;
- }
-
- // find current item among children
- folders_t::reverse_iterator fit = mFolders.rbegin();
- folders_t::reverse_iterator fend = mFolders.rend();
-
- items_t::reverse_iterator iit = mItems.rbegin();
- items_t::reverse_iterator iend = mItems.rend();
-
- // if not trivially starting at the end, we have to find the current item
- if (!found_item)
- {
- // first, look among items, since they are always below the folders
- for(; iit != iend; ++iit)
- {
- if(item == (*iit))
- {
- found_item = TRUE;
- // point to next item
- ++iit;
- break;
- }
- }
-
- // didn't find in items? Check folders...
- if (!found_item)
- {
- for(; fit != fend; ++fit)
- {
- if(item == (*fit))
- {
- found_item = TRUE;
- // point to next folder
- ++fit;
- break;
- }
- }
- }
- }
-
- if (!found_item)
- {
- // you should never call this method with an item that isn't a child
- // so we should always find something
- llassert(FALSE);
- return NULL;
- }
-
- // at this point, either iit or fit point to a candidate "next" item
- // if both are out of range, we need to punt up to our parent
-
- // now, starting from found item, continue through items
- // searching for next visible item
- while(iit != iend && !(*iit)->getVisible())
- {
- ++iit;
- }
-
- if (iit != iend)
- {
- // we found an appropriate item
- result = (*iit);
- }
- else
- {
- // otherwise, scan for next visible folder
- while(fit != fend && !(*fit)->getVisible())
- {
- ++fit;
- }
-
- // check to see if we have a valid folder
- if (fit != fend)
- {
- // try selecting child element of this folder
- if ((*fit)->isOpen())
- {
- result = (*fit)->getPreviousFromChild(NULL);
- }
- else
- {
- result = (*fit);
- }
- }
- }
-
- if( !result )
- {
- // If there are no siblings or children to go to, recurse up one level in the tree
- // which gets back to this folder, which will only be visited if it is a valid, visible item
- result = this;
- }
-
- return result;
-}
-
-
-bool LLInventorySort::updateSort(U32 order)
-{
- if (order != mSortOrder)
- {
- mSortOrder = order;
- mByDate = (order & LLInventoryFilter::SO_DATE);
- mSystemToTop = (order & LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP);
- mFoldersByName = (order & LLInventoryFilter::SO_FOLDERS_BY_NAME);
- return true;
- }
- return false;
-}
-
-bool LLInventorySort::operator()(const LLFolderViewItem* const& a, const LLFolderViewItem* const& b)
-{
- // ignore sort order for landmarks in the Favorites folder.
- // they should be always sorted as in Favorites bar. See EXT-719
- if (a->getSortGroup() == SG_ITEM
- && b->getSortGroup() == SG_ITEM
- && a->getListener()->getInventoryType() == LLInventoryType::IT_LANDMARK
- && b->getListener()->getInventoryType() == LLInventoryType::IT_LANDMARK)
- {
-
- static const LLUUID& favorites_folder_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
-
- LLUUID a_uuid = a->getParentFolder()->getListener()->getUUID();
- LLUUID b_uuid = b->getParentFolder()->getListener()->getUUID();
-
- if ((a_uuid == favorites_folder_id && b_uuid == favorites_folder_id))
- {
- // *TODO: mantipov: probably it is better to add an appropriate method to LLFolderViewItem
- // or to LLInvFVBridge
- LLViewerInventoryItem* aitem = (static_cast<const LLItemBridge*>(a->getListener()))->getItem();
- LLViewerInventoryItem* bitem = (static_cast<const LLItemBridge*>(b->getListener()))->getItem();
- if (!aitem || !bitem)
- return false;
- S32 a_sort = aitem->getSortField();
- S32 b_sort = bitem->getSortField();
- return a_sort < b_sort;
- }
- }
-
- // We sort by name if we aren't sorting by date
- // OR if these are folders and we are sorting folders by name.
- bool by_name = (!mByDate
- || (mFoldersByName
- && (a->getSortGroup() != SG_ITEM)));
-
- if (a->getSortGroup() != b->getSortGroup())
- {
- if (mSystemToTop)
- {
- // Group order is System Folders, Trash, Normal Folders, Items
- return (a->getSortGroup() < b->getSortGroup());
- }
- else if (mByDate)
- {
- // Trash needs to go to the bottom if we are sorting by date
- if ( (a->getSortGroup() == SG_TRASH_FOLDER)
- || (b->getSortGroup() == SG_TRASH_FOLDER))
- {
- return (b->getSortGroup() == SG_TRASH_FOLDER);
- }
- }
- }
-
- if (by_name)
- {
- S32 compare = LLStringUtil::compareDict(a->getLabel(), b->getLabel());
- if (0 == compare)
- {
- return (a->getCreationDate() > b->getCreationDate());
- }
- else
- {
- return (compare < 0);
- }
- }
- else
- {
- // BUG: This is very very slow. The getCreationDate() is log n in number
- // of inventory items.
- time_t first_create = a->getCreationDate();
- time_t second_create = b->getCreationDate();
- if (first_create == second_create)
- {
- return (LLStringUtil::compareDict(a->getLabel(), b->getLabel()) < 0);
- }
- else
- {
- return (first_create > second_create);
- }
- }
-}
diff --git a/indra/newview/llfolderviewitem.h b/indra/newview/llfolderviewitem.h
deleted file mode 100644
index 3c7592046a..0000000000
--- a/indra/newview/llfolderviewitem.h
+++ /dev/null
@@ -1,576 +0,0 @@
-/**
-* @file llfolderviewitem.h
-* @brief Items and folders that can appear in a hierarchical folder view
-*
-* $LicenseInfo:firstyear=2001&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$
-*/
-#ifndef LLFOLDERVIEWITEM_H
-#define LLFOLDERVIEWITEM_H
-
-#include "llview.h"
-#include "lldarray.h" // *TODO: Eliminate, forward declare
-#include "lluiimage.h"
-
-class LLFontGL;
-class LLFolderView;
-class LLFolderViewEventListener;
-class LLFolderViewFolder;
-class LLFolderViewFunctor;
-class LLFolderViewItem;
-class LLFolderViewListenerFunctor;
-class LLInventoryFilter;
-class LLMenuGL;
-class LLUIImage;
-class LLViewerInventoryItem;
-
-// These are grouping of inventory types.
-// Order matters when sorting system folders to the top.
-enum EInventorySortGroup
-{
- SG_SYSTEM_FOLDER,
- SG_TRASH_FOLDER,
- SG_NORMAL_FOLDER,
- SG_ITEM
-};
-
-// *TODO: do we really need one sort object per folder?
-// can we just have one of these per LLFolderView ?
-class LLInventorySort
-{
-public:
- LLInventorySort()
- : mSortOrder(0),
- mByDate(false),
- mSystemToTop(false),
- mFoldersByName(false) { }
-
- // Returns true if order has changed
- bool updateSort(U32 order);
- U32 getSort() { return mSortOrder; }
- bool isByDate() { return mByDate; }
-
- bool operator()(const LLFolderViewItem* const& a, const LLFolderViewItem* const& b);
-private:
- U32 mSortOrder;
- bool mByDate;
- bool mSystemToTop;
- bool mFoldersByName;
-};
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Class LLFolderViewItem
-//
-// An instance of this class represents a single item in a folder view
-// such as an inventory item or a file.
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-class LLFolderViewItem : public LLView
-{
-public:
- static void initClass();
- static void cleanupClass();
-
- struct Params : public LLInitParam::Block<Params, LLView::Params>
- {
- Optional<LLUIImage*> icon;
- Optional<LLUIImage*> icon_open; // used for folders
- Optional<LLUIImage*> icon_overlay; // for links
- Optional<LLFolderView*> root;
- Mandatory<LLFolderViewEventListener*> listener;
-
- Optional<LLUIImage*> folder_arrow_image;
- Optional<S32> folder_indentation; // pixels
- Optional<LLUIImage*> selection_image;
- Optional<S32> item_height; // pixels
- Optional<S32> item_top_pad; // pixels
-
- Optional<S32> creation_date; //UTC seconds
-
- Params();
- };
-
- // layout constants
- static const S32 LEFT_PAD = 5;
- // LEFT_INDENTATION is set via folder_indentation above
- static const S32 ICON_PAD = 2;
- static const S32 ICON_WIDTH = 16;
- static const S32 TEXT_PAD = 1;
- static const S32 TEXT_PAD_RIGHT = 4;
- static const S32 ARROW_SIZE = 12;
- static const S32 MAX_FOLDER_ITEM_OVERLAP = 2;
- // animation parameters
- static const F32 FOLDER_CLOSE_TIME_CONSTANT;
- static const F32 FOLDER_OPEN_TIME_CONSTANT;
-
- // Mostly for debugging printout purposes.
- const std::string& getSearchableLabel() { return mSearchableLabel; }
-
- BOOL isLoading() const { return mIsLoading; }
-
-private:
- BOOL mIsSelected;
-
-protected:
- friend class LLUICtrlFactory;
- friend class LLFolderViewEventListener;
-
- LLFolderViewItem(const Params& p);
-
- std::string mLabel;
- std::string mSearchableLabel;
- S32 mLabelWidth;
- bool mLabelWidthDirty;
- time_t mCreationDate;
- LLFolderViewFolder* mParentFolder;
- LLFolderViewEventListener* mListener;
- BOOL mIsCurSelection;
- BOOL mSelectPending;
- LLFontGL::StyleFlags mLabelStyle;
- std::string mLabelSuffix;
- LLUIImagePtr mIcon;
- std::string mStatusText;
- LLUIImagePtr mIconOpen;
- LLUIImagePtr mIconOverlay;
- BOOL mHasVisibleChildren;
- S32 mIndentation;
- S32 mItemHeight;
- BOOL mPassedFilter;
- S32 mLastFilterGeneration;
- std::string::size_type mStringMatchOffset;
- F32 mControlLabelRotation;
- LLFolderView* mRoot;
- BOOL mDragAndDropTarget;
- BOOL mIsLoading;
- LLTimer mTimeSinceRequestStart;
- bool mShowLoadStatus;
- bool mIsMouseOverTitle;
-
- // helper function to change the selection from the root.
- void changeSelectionFromRoot(LLFolderViewItem* selection, BOOL selected);
-
- // this is an internal method used for adding items to folders. A
- // no-op at this level, but reimplemented in derived classes.
- virtual BOOL addItem(LLFolderViewItem*) { return FALSE; }
- virtual BOOL addFolder(LLFolderViewFolder*) { return FALSE; }
-
- static LLFontGL* getLabelFontForStyle(U8 style);
-
- virtual void setCreationDate(time_t creation_date_utc) { mCreationDate = creation_date_utc; }
-
-public:
- BOOL postBuild();
-
- // This function clears the currently selected item, and records
- // the specified selected item appropriately for display and use
- // in the UI. If open is TRUE, then folders are opened up along
- // the way to the selection.
- void setSelectionFromRoot(LLFolderViewItem* selection, BOOL openitem,
- BOOL take_keyboard_focus = TRUE);
-
- // This function is called when the folder view is dirty. It's
- // implemented here but called by derived classes when folding the
- // views.
- void arrangeFromRoot();
- void filterFromRoot( void );
-
- void arrangeAndSet(BOOL set_selection, BOOL take_keyboard_focus);
-
- virtual ~LLFolderViewItem( void );
-
- // addToFolder() returns TRUE if it succeeds. FALSE otherwise
- enum { ARRANGE = TRUE, DO_NOT_ARRANGE = FALSE };
- virtual BOOL addToFolder(LLFolderViewFolder* folder, LLFolderView* root);
-
- virtual EInventorySortGroup getSortGroup() const;
-
- // Finds width and height of this object and it's children. Also
- // makes sure that this view and it's children are the right size.
- virtual S32 arrange( S32* width, S32* height, S32 filter_generation );
- virtual S32 getItemHeight();
-
- // applies filters to control visibility of inventory items
- virtual void filter( LLInventoryFilter& filter);
-
- // updates filter serial number and optionally propagated value up to root
- S32 getLastFilterGeneration() { return mLastFilterGeneration; }
-
- virtual void dirtyFilter();
-
- // If 'selection' is 'this' then note that otherwise ignore.
- // Returns TRUE if this item ends up being selected.
- virtual BOOL setSelection(LLFolderViewItem* selection, BOOL openitem, BOOL take_keyboard_focus);
-
- // This method is used to set the selection state of an item.
- // If 'selection' is 'this' then note selection.
- // Returns TRUE if the selection state of this item was changed.
- virtual BOOL changeSelection(LLFolderViewItem* selection, BOOL selected);
-
- // this method is used to deselect this element
- void deselectItem();
-
- // this method is used to select this element
- virtual void selectItem();
-
- // gets multiple-element selection
- virtual std::set<LLUUID> getSelectionList() const;
-
- // Returns true is this object and all of its children can be removed (deleted by user)
- virtual BOOL isRemovable();
-
- // Returns true is this object and all of its children can be moved
- virtual BOOL isMovable();
-
- // destroys this item recursively
- virtual void destroyView();
-
- BOOL isSelected() const { return mIsSelected; }
-
- void setUnselected() { mIsSelected = FALSE; }
-
- void setIsCurSelection(BOOL select) { mIsCurSelection = select; }
-
- BOOL getIsCurSelection() { return mIsCurSelection; }
-
- BOOL hasVisibleChildren() { return mHasVisibleChildren; }
-
- void setShowLoadStatus(bool status) { mShowLoadStatus = status; }
-
- // Call through to the viewed object and return true if it can be
- // removed. Returns true if it's removed.
- //virtual BOOL removeRecursively(BOOL single_item);
- BOOL remove();
-
- // Build an appropriate context menu for the item. Flags unused.
- void buildContextMenu(LLMenuGL& menu, U32 flags);
-
- // This method returns the actual name of the thing being
- // viewed. This method will ask the viewed object itself.
- const std::string& getName( void ) const;
-
- const std::string& getSearchableLabel( void ) const;
-
- // This method returns the label displayed on the view. This
- // method was primarily added to allow sorting on the folder
- // contents possible before the entire view has been constructed.
- const std::string& getLabel() const { return mLabel; }
-
- // Used for sorting, like getLabel() above.
- virtual time_t getCreationDate() const { return mCreationDate; }
-
- LLFolderViewFolder* getParentFolder( void ) { return mParentFolder; }
- const LLFolderViewFolder* getParentFolder( void ) const { return mParentFolder; }
-
- LLFolderViewItem* getNextOpenNode( BOOL include_children = TRUE );
- LLFolderViewItem* getPreviousOpenNode( BOOL include_children = TRUE );
-
- const LLFolderViewEventListener* getListener( void ) const { return mListener; }
- LLFolderViewEventListener* getListener( void ) { return mListener; }
-
- // Gets the inventory item if it exists (null otherwise)
- LLViewerInventoryItem * getInventoryItem(void);
-
- // just rename the object.
- void rename(const std::string& new_name);
-
- // open
- virtual void openItem( void );
- virtual void preview(void);
-
- // Show children (unfortunate that this is called "open")
- virtual void setOpen(BOOL open = TRUE) {};
-
- virtual BOOL isOpen() const { return FALSE; }
-
- virtual LLFolderView* getRoot();
- BOOL isDescendantOf( const LLFolderViewFolder* potential_ancestor );
- S32 getIndentation() { return mIndentation; }
-
- virtual BOOL potentiallyVisible(); // do we know for a fact that this item won't be displayed?
- virtual BOOL potentiallyFiltered(); // do we know for a fact that this item has been filtered out?
-
- virtual BOOL getFiltered();
- virtual BOOL getFiltered(S32 filter_generation);
- virtual void setFiltered(BOOL filtered, S32 filter_generation);
-
- // change the icon
- void setIcon(LLUIImagePtr icon);
-
- // refresh information from the object being viewed.
- void refreshFromListener();
- virtual void refresh();
-
- virtual void applyListenerFunctorRecursively(LLFolderViewListenerFunctor& functor);
-
- // LLView functionality
- virtual BOOL handleRightMouseDown( S32 x, S32 y, MASK mask );
- virtual BOOL handleMouseDown( S32 x, S32 y, MASK mask );
- virtual BOOL handleHover( S32 x, S32 y, MASK mask );
- virtual BOOL handleMouseUp( S32 x, S32 y, MASK mask );
- virtual BOOL handleDoubleClick( S32 x, S32 y, MASK mask );
-
- virtual void onMouseLeave(S32 x, S32 y, MASK mask);
-
- virtual LLView* findChildView(const std::string& name, BOOL recurse) const { return NULL; }
-
- // virtual void handleDropped();
- virtual void draw();
- virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
- EDragAndDropType cargo_type,
- void* cargo_data,
- EAcceptance* accept,
- std::string& tooltip_msg);
-
-private:
- static std::map<U8, LLFontGL*> sFonts; // map of styles to fonts
-};
-
-
-// function used for sorting.
-typedef bool (*sort_order_f)(LLFolderViewItem* a, LLFolderViewItem* b);
-
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Class LLFolderViewFolder
-//
-// An instance of an LLFolderViewFolder represents a collection of
-// more folders and items. This is used to build the hierarchy of
-// items found in the folder view.
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-class LLFolderViewFolder : public LLFolderViewItem
-{
-protected:
- LLFolderViewFolder( const LLFolderViewItem::Params& );
- friend class LLUICtrlFactory;
-
-public:
- typedef enum e_trash
- {
- UNKNOWN, TRASH, NOT_TRASH
- } ETrash;
-
- typedef std::list<LLFolderViewItem*> items_t;
- typedef std::list<LLFolderViewFolder*> folders_t;
-
-protected:
- items_t mItems;
- folders_t mFolders;
- LLInventorySort mSortFunction;
-
- BOOL mIsOpen;
- BOOL mExpanderHighlighted;
- F32 mCurHeight;
- F32 mTargetHeight;
- F32 mAutoOpenCountdown;
- time_t mSubtreeCreationDate;
- mutable ETrash mAmTrash;
- S32 mLastArrangeGeneration;
- S32 mLastCalculatedWidth;
- S32 mCompletedFilterGeneration;
- S32 mMostFilteredDescendantGeneration;
- bool mNeedsSort;
- bool mPassedFolderFilter;
-
-public:
- typedef enum e_recurse_type
- {
- RECURSE_NO,
- RECURSE_UP,
- RECURSE_DOWN,
- RECURSE_UP_DOWN
- } ERecurseType;
-
-
- virtual ~LLFolderViewFolder( void );
-
- virtual BOOL potentiallyVisible();
-
- LLFolderViewItem* getNextFromChild( LLFolderViewItem*, BOOL include_children = TRUE );
- LLFolderViewItem* getPreviousFromChild( LLFolderViewItem*, BOOL include_children = TRUE );
-
- // addToFolder() returns TRUE if it succeeds. FALSE otherwise
- virtual BOOL addToFolder(LLFolderViewFolder* folder, LLFolderView* root);
-
- // Finds width and height of this object and it's children. Also
- // makes sure that this view and it's children are the right size.
- virtual S32 arrange( S32* width, S32* height, S32 filter_generation );
-
- BOOL needsArrange();
- void requestSort();
-
- // Returns the sort group (system, trash, folder) for this folder.
- virtual EInventorySortGroup getSortGroup() const;
-
- virtual void setCompletedFilterGeneration(S32 generation, BOOL recurse_up);
- virtual S32 getCompletedFilterGeneration() { return mCompletedFilterGeneration; }
-
- BOOL hasFilteredDescendants(S32 filter_generation);
- BOOL hasFilteredDescendants();
-
- // applies filters to control visibility of inventory items
- virtual void filter( LLInventoryFilter& filter);
- virtual void setFiltered(BOOL filtered, S32 filter_generation);
- virtual BOOL getFiltered();
- virtual BOOL getFiltered(S32 filter_generation);
-
- virtual void dirtyFilter();
-
- // folder-specific filtering (filter status propagates top down instead of bottom up)
- void filterFolder(LLInventoryFilter& filter);
- void setFilteredFolder(bool filtered, S32 filter_generation);
- bool getFilteredFolder(S32 filter_generation);
-
- // Passes selection information on to children and record
- // selection information if necessary.
- // Returns TRUE if this object (or a child) ends up being selected.
- // If 'openitem' is TRUE then folders are opened up along the way to the selection.
- virtual BOOL setSelection(LLFolderViewItem* selection, BOOL openitem, BOOL take_keyboard_focus);
-
- // This method is used to change the selection of an item.
- // Recursively traverse all children; if 'selection' is 'this' then change
- // the select status if necessary.
- // Returns TRUE if the selection state of this folder, or of a child, was changed.
- virtual BOOL changeSelection(LLFolderViewItem* selection, BOOL selected);
-
- // this method is used to group select items
- void extendSelectionTo(LLFolderViewItem* selection);
-
- // Returns true is this object and all of its children can be removed.
- virtual BOOL isRemovable();
-
- // Returns true is this object and all of its children can be moved
- virtual BOOL isMovable();
-
- // destroys this folder, and all children
- virtual void destroyView();
-
- // If this folder can be removed, remove all children that can be
- // removed, return TRUE if this is empty after the operation and
- // it's viewed folder object can be removed.
- //virtual BOOL removeRecursively(BOOL single_item);
- //virtual BOOL remove();
-
- // remove the specified item (and any children) if
- // possible. Return TRUE if the item was deleted.
- BOOL removeItem(LLFolderViewItem* item);
-
- // simply remove the view (and any children) Don't bother telling
- // the listeners.
- void removeView(LLFolderViewItem* item);
-
- // extractItem() removes the specified item from the folder, but
- // doesn't delete it.
- void extractItem( LLFolderViewItem* item );
-
- // This function is called by a child that needs to be resorted.
- void resort(LLFolderViewItem* item);
-
- void setItemSortOrder(U32 ordering);
- void sortBy(U32);
- //BOOL (*func)(LLFolderViewItem* a, LLFolderViewItem* b));
-
- void setAutoOpenCountdown(F32 countdown) { mAutoOpenCountdown = countdown; }
-
- // folders can be opened. This will usually be called by internal
- // methods.
- virtual void toggleOpen();
-
- // Force a folder open or closed
- virtual void setOpen(BOOL openitem = TRUE);
-
- // Called when a child is refreshed.
- // don't rearrange child folder contents unless explicitly requested
- virtual void requestArrange(BOOL include_descendants = FALSE);
-
- // internal method which doesn't update the entire view. This
- // method was written because the list iterators destroy the state
- // of other iterations, thus, we can't arrange while iterating
- // through the children (such as when setting which is selected.
- virtual void setOpenArrangeRecursively(BOOL openitem, ERecurseType recurse = RECURSE_NO);
-
- // Get the current state of the folder.
- virtual BOOL isOpen() const { return mIsOpen; }
-
- // special case if an object is dropped on the child.
- BOOL handleDragAndDropFromChild(MASK mask,
- BOOL drop,
- EDragAndDropType cargo_type,
- void* cargo_data,
- EAcceptance* accept,
- std::string& tooltip_msg);
-
- void applyFunctorRecursively(LLFolderViewFunctor& functor);
- virtual void applyListenerFunctorRecursively(LLFolderViewListenerFunctor& functor);
-
- // Just apply this functor to the folder's immediate children.
- void applyFunctorToChildren(LLFolderViewFunctor& functor);
-
- virtual void openItem( void );
- virtual BOOL addItem(LLFolderViewItem* item);
- virtual BOOL addFolder( LLFolderViewFolder* folder);
-
- // LLView functionality
- virtual BOOL handleHover(S32 x, S32 y, MASK mask);
- virtual BOOL handleRightMouseDown( S32 x, S32 y, MASK mask );
- virtual BOOL handleMouseDown( S32 x, S32 y, MASK mask );
- virtual BOOL handleDoubleClick( S32 x, S32 y, MASK mask );
- virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
- EDragAndDropType cargo_type,
- void* cargo_data,
- EAcceptance* accept,
- std::string& tooltip_msg);
- BOOL handleDragAndDropToThisFolder(MASK mask, BOOL drop,
- EDragAndDropType cargo_type,
- void* cargo_data,
- EAcceptance* accept,
- std::string& tooltip_msg);
- virtual void draw();
-
- time_t getCreationDate() const;
- bool isTrash() const;
-
- folders_t::const_iterator getFoldersBegin() const { return mFolders.begin(); }
- folders_t::const_iterator getFoldersEnd() const { return mFolders.end(); }
- folders_t::size_type getFoldersCount() const { return mFolders.size(); }
-
- items_t::const_iterator getItemsBegin() const { return mItems.begin(); }
- items_t::const_iterator getItemsEnd() const { return mItems.end(); }
- items_t::size_type getItemsCount() const { return mItems.size(); }
- LLFolderViewFolder* getCommonAncestor(LLFolderViewItem* item_a, LLFolderViewItem* item_b, bool& reverse);
- void gatherChildRangeExclusive(LLFolderViewItem* start, LLFolderViewItem* end, bool reverse, std::vector<LLFolderViewItem*>& items);
-};
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Class LLFolderViewListenerFunctor
-//
-// This simple abstract base class can be used to applied to all
-// listeners in a hierarchy.
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-class LLFolderViewListenerFunctor
-{
-public:
- virtual ~LLFolderViewListenerFunctor() {}
- virtual void operator()(LLFolderViewEventListener* listener) = 0;
-};
-
-#endif // LLFOLDERVIEWITEM_H
diff --git a/indra/newview/llfolderviewmodelinventory.cpp b/indra/newview/llfolderviewmodelinventory.cpp
new file mode 100755
index 0000000000..c28657dbcd
--- /dev/null
+++ b/indra/newview/llfolderviewmodelinventory.cpp
@@ -0,0 +1,323 @@
+/*
+ * @file llfolderviewmodelinventory.cpp
+ * @brief Implementation of the inventory-specific view model
+ *
+ * $LicenseInfo:firstyear=2001&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 "llviewerprecompiledheaders.h"
+#include "llfolderviewmodelinventory.h"
+#include "llinventorymodelbackgroundfetch.h"
+#include "llinventorypanel.h"
+#include "lltooldraganddrop.h"
+#include "llfavoritesbar.h"
+
+//
+// class LLFolderViewModelInventory
+//
+static LLFastTimer::DeclareTimer FTM_INVENTORY_SORT("Sort");
+
+bool LLFolderViewModelInventory::startDrag(std::vector<LLFolderViewModelItem*>& items)
+{
+ std::vector<EDragAndDropType> types;
+ uuid_vec_t cargo_ids;
+ std::vector<LLFolderViewModelItem*>::iterator item_it;
+ bool can_drag = true;
+ if (!items.empty())
+ {
+ for (item_it = items.begin(); item_it != items.end(); ++item_it)
+ {
+ EDragAndDropType type = DAD_NONE;
+ LLUUID id = LLUUID::null;
+ can_drag = can_drag && static_cast<LLFolderViewModelItemInventory*>(*item_it)->startDrag(&type, &id);
+
+ types.push_back(type);
+ cargo_ids.push_back(id);
+ }
+
+ LLToolDragAndDrop::getInstance()->beginMultiDrag(types, cargo_ids,
+ static_cast<LLFolderViewModelItemInventory*>(items.front())->getDragSource(), mTaskID);
+ }
+ return can_drag;
+}
+
+
+void LLFolderViewModelInventory::sort( LLFolderViewFolder* folder )
+{
+ LLFastTimer _(FTM_INVENTORY_SORT);
+
+ if (!needsSort(folder->getViewModelItem())) return;
+
+ LLFolderViewModelItemInventory* modelp = static_cast<LLFolderViewModelItemInventory*>(folder->getViewModelItem());
+ if (modelp->getUUID().isNull()) return;
+
+ for (std::list<LLFolderViewFolder*>::iterator it = folder->getFoldersBegin(), end_it = folder->getFoldersEnd();
+ it != end_it;
+ ++it)
+ {
+ // Recursive call to sort() on child (CHUI-849)
+ LLFolderViewFolder* child_folderp = *it;
+ sort(child_folderp);
+
+ if (child_folderp->getFoldersCount() > 0)
+ {
+ time_t most_recent_folder_time =
+ static_cast<LLFolderViewModelItemInventory*>((*child_folderp->getFoldersBegin())->getViewModelItem())->getCreationDate();
+ LLFolderViewModelItemInventory* modelp = static_cast<LLFolderViewModelItemInventory*>(child_folderp->getViewModelItem());
+ if (most_recent_folder_time > modelp->getCreationDate())
+ {
+ modelp->setCreationDate(most_recent_folder_time);
+ }
+ }
+ if (child_folderp->getItemsCount() > 0)
+ {
+ time_t most_recent_item_time =
+ static_cast<LLFolderViewModelItemInventory*>((*child_folderp->getItemsBegin())->getViewModelItem())->getCreationDate();
+
+ LLFolderViewModelItemInventory* modelp = static_cast<LLFolderViewModelItemInventory*>(child_folderp->getViewModelItem());
+ if (most_recent_item_time > modelp->getCreationDate())
+ {
+ modelp->setCreationDate(most_recent_item_time);
+ }
+ }
+ }
+ base_t::sort(folder);
+}
+
+bool LLFolderViewModelInventory::contentsReady()
+{
+ return !LLInventoryModelBackgroundFetch::instance().folderFetchActive();
+}
+
+void LLFolderViewModelItemInventory::requestSort()
+{
+ LLFolderViewModelItemCommon::requestSort();
+ LLFolderViewFolder* folderp = dynamic_cast<LLFolderViewFolder*>(mFolderViewItem);
+ if (folderp)
+ {
+ folderp->requestArrange();
+ }
+ if (static_cast<LLFolderViewModelInventory&>(mRootViewModel).getSorter().isByDate())
+ {
+ // sort by date potentially affects parent folders which use a date
+ // derived from newest item in them
+ if (mParent)
+ {
+ mParent->requestSort();
+ }
+ }
+}
+
+void LLFolderViewModelItemInventory::setPassedFilter(bool passed, S32 filter_generation, std::string::size_type string_offset, std::string::size_type string_size)
+{
+ LLFolderViewModelItemCommon::setPassedFilter(passed, filter_generation, string_offset, string_size);
+ bool before = mPrevPassedAllFilters;
+ mPrevPassedAllFilters = passedFilter(filter_generation);
+
+ if (before != mPrevPassedAllFilters)
+ {
+ // Need to rearrange the folder if the filtered state of the item changed
+ LLFolderViewFolder* parent_folder = mFolderViewItem->getParentFolder();
+ if (parent_folder)
+ {
+ parent_folder->requestArrange();
+ }
+ }
+}
+
+bool LLFolderViewModelItemInventory::filterChildItem( LLFolderViewModelItem* item, LLFolderViewFilter& filter )
+{
+ S32 filter_generation = filter.getCurrentGeneration();
+
+ bool continue_filtering = true;
+ if (item->getLastFilterGeneration() < filter_generation)
+ {
+ // Recursive application of the filter for child items (CHUI-849)
+ continue_filtering = item->filter( filter );
+ }
+
+ // Update latest generation to pass filter in parent and propagate up to root
+ if (item->passedFilter())
+ {
+ LLFolderViewModelItemInventory* view_model = this;
+
+ while(view_model && view_model->mMostFilteredDescendantGeneration < filter_generation)
+ {
+ view_model->mMostFilteredDescendantGeneration = filter_generation;
+ view_model = static_cast<LLFolderViewModelItemInventory*>(view_model->mParent);
+ }
+ }
+
+ return continue_filtering;
+}
+
+bool LLFolderViewModelItemInventory::filter( LLFolderViewFilter& filter)
+{
+ const S32 filter_generation = filter.getCurrentGeneration();
+ const S32 must_pass_generation = filter.getFirstRequiredGeneration();
+
+ if (getLastFilterGeneration() >= must_pass_generation
+ && getLastFolderFilterGeneration() >= must_pass_generation
+ && !passedFilter(must_pass_generation))
+ {
+ // failed to pass an earlier filter that was a subset of the current one
+ // go ahead and flag this item as not pass
+ setPassedFilter(false, filter_generation);
+ setPassedFolderFilter(false, filter_generation);
+ return true;
+ }
+
+ // *TODO : Revise the logic for fast pass on less restrictive filter case
+ /*
+ const S32 sufficient_pass_generation = filter.getFirstSuccessGeneration();
+ if (getLastFilterGeneration() >= sufficient_pass_generation
+ && getLastFolderFilterGeneration() >= sufficient_pass_generation
+ && passedFilter(sufficient_pass_generation))
+ {
+ // passed an earlier filter that was a superset of the current one
+ // go ahead and flag this item as pass
+ setPassedFilter(true, filter_generation);
+ setPassedFolderFilter(true, filter_generation);
+ return true;
+ }
+ */
+
+ const bool passed_filter_folder = (getInventoryType() == LLInventoryType::IT_CATEGORY) ? filter.checkFolder(this) : true;
+ setPassedFolderFilter(passed_filter_folder, filter_generation);
+
+ bool continue_filtering = true;
+
+ if (!mChildren.empty()
+ && (getLastFilterGeneration() < must_pass_generation // haven't checked descendants against minimum required generation to pass
+ || descendantsPassedFilter(must_pass_generation))) // or at least one descendant has passed the minimum requirement
+ {
+ // now query children
+ for (child_list_t::iterator iter = mChildren.begin(), end_iter = mChildren.end(); iter != end_iter; ++iter)
+ {
+ continue_filtering = filterChildItem((*iter), filter);
+ if (!continue_filtering)
+ {
+ break;
+ }
+ }
+ }
+
+ // If we didn't use all the filter time that means we filtered all of our descendants so we can filter ourselves now
+ if (continue_filtering)
+ {
+ // This is where filter check on the item done (CHUI-849)
+ const bool passed_filter = filter.check(this);
+ setPassedFilter(passed_filter, filter_generation, filter.getStringMatchOffset(this), filter.getFilterStringSize());
+ continue_filtering = !filter.isTimedOut();
+ }
+ return continue_filtering;
+}
+
+LLFolderViewModelInventory* LLInventoryPanel::getFolderViewModel()
+{
+ return &mInventoryViewModel;
+}
+
+
+const LLFolderViewModelInventory* LLInventoryPanel::getFolderViewModel() const
+{
+ return &mInventoryViewModel;
+}
+
+bool LLInventorySort::operator()(const LLFolderViewModelItemInventory* const& a, const LLFolderViewModelItemInventory* const& b) const
+{
+ // Ignore sort order for landmarks in the Favorites folder.
+ // In that folder, landmarks should be always sorted as in the Favorites bar. See EXT-719
+ if (a->getSortGroup() == SG_ITEM
+ && b->getSortGroup() == SG_ITEM
+ && a->getInventoryType() == LLInventoryType::IT_LANDMARK
+ && b->getInventoryType() == LLInventoryType::IT_LANDMARK)
+ {
+ static const LLUUID& favorites_folder_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
+ // If both landmarks are in the Favorites folder...
+ if (gInventory.isObjectDescendentOf(a->getUUID(), favorites_folder_id) && gInventory.isObjectDescendentOf(b->getUUID(), favorites_folder_id))
+ {
+ // Get their index in that folder
+ S32 a_sort = LLFavoritesOrderStorage::instance().getSortIndex(a->getUUID());
+ S32 b_sort = LLFavoritesOrderStorage::instance().getSortIndex(b->getUUID());
+ // Note: this test is a bit overkill: since they are both in the Favorites folder, we shouldn't get negative index values...
+ if (!((a_sort < 0) && (b_sort < 0)))
+ {
+ return a_sort < b_sort;
+ }
+ }
+ }
+
+ // We sort by name if we aren't sorting by date
+ // OR if these are folders and we are sorting folders by name.
+ bool by_name = (!mByDate || (mFoldersByName && (a->getSortGroup() != SG_ITEM)));
+
+ if (a->getSortGroup() != b->getSortGroup())
+ {
+ if (mSystemToTop)
+ {
+ // Group order is System Folders, Trash, Normal Folders, Items
+ return (a->getSortGroup() < b->getSortGroup());
+ }
+ else if (mByDate)
+ {
+ // Trash needs to go to the bottom if we are sorting by date
+ if ( (a->getSortGroup() == SG_TRASH_FOLDER)
+ || (b->getSortGroup() == SG_TRASH_FOLDER))
+ {
+ return (b->getSortGroup() == SG_TRASH_FOLDER);
+ }
+ }
+ }
+
+ if (by_name)
+ {
+ S32 compare = LLStringUtil::compareDict(a->getDisplayName(), b->getDisplayName());
+ if (0 == compare)
+ {
+ return (a->getCreationDate() > b->getCreationDate());
+ }
+ else
+ {
+ return (compare < 0);
+ }
+ }
+ else
+ {
+ time_t first_create = a->getCreationDate();
+ time_t second_create = b->getCreationDate();
+ if (first_create == second_create)
+ {
+ return (LLStringUtil::compareDict(a->getDisplayName(), b->getDisplayName()) < 0);
+ }
+ else
+ {
+ return (first_create > second_create);
+ }
+ }
+}
+
+LLFolderViewModelItemInventory::LLFolderViewModelItemInventory( class LLFolderViewModelInventory& root_view_model ) :
+ LLFolderViewModelItemCommon(root_view_model),
+ mPrevPassedAllFilters(false)
+{
+}
diff --git a/indra/newview/llfolderviewmodelinventory.h b/indra/newview/llfolderviewmodelinventory.h
new file mode 100755
index 0000000000..9dcfdfa185
--- /dev/null
+++ b/indra/newview/llfolderviewmodelinventory.h
@@ -0,0 +1,117 @@
+/**
+ * @file llfolderviewmodelinventory.h
+ * @brief view model implementation specific to inventory
+ * class definition
+ *
+ * $LicenseInfo:firstyear=2001&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$
+ */
+
+#ifndef LL_LLFOLDERVIEWMODELINVENTORY_H
+#define LL_LLFOLDERVIEWMODELINVENTORY_H
+
+#include "llinventoryfilter.h"
+#include "llinventory.h"
+#include "llwearabletype.h"
+#include "lltooldraganddrop.h"
+
+class LLFolderViewModelItemInventory
+ : public LLFolderViewModelItemCommon
+{
+public:
+ LLFolderViewModelItemInventory(class LLFolderViewModelInventory& root_view_model);
+ virtual const LLUUID& getUUID() const = 0;
+ virtual time_t getCreationDate() const = 0; // UTC seconds
+ virtual void setCreationDate(time_t creation_date_utc) = 0;
+ virtual PermissionMask getPermissionMask() const = 0;
+ virtual LLFolderType::EType getPreferredType() const = 0;
+ virtual void showProperties(void) = 0;
+ virtual BOOL isItemInTrash( void) const { return FALSE; } // TODO: make into pure virtual.
+ virtual BOOL isUpToDate() const = 0;
+ virtual bool hasChildren() const = 0;
+ virtual LLInventoryType::EType getInventoryType() const = 0;
+ virtual void performAction(LLInventoryModel* model, std::string action) = 0;
+ virtual LLWearableType::EType getWearableType() const = 0;
+ virtual EInventorySortGroup getSortGroup() const = 0;
+ virtual LLInventoryObject* getInventoryObject() const = 0;
+ virtual void requestSort();
+ virtual void setPassedFilter(bool filtered, S32 filter_generation, std::string::size_type string_offset = std::string::npos, std::string::size_type string_size = 0);
+ virtual bool filter( LLFolderViewFilter& filter);
+ virtual bool filterChildItem( LLFolderViewModelItem* item, LLFolderViewFilter& filter);
+
+ virtual BOOL startDrag(EDragAndDropType* type, LLUUID* id) const = 0;
+ virtual LLToolDragAndDrop::ESource getDragSource() const = 0;
+protected:
+ bool mPrevPassedAllFilters;
+};
+
+class LLInventorySort
+{
+public:
+ struct Params : public LLInitParam::Block<Params>
+ {
+ Optional<S32> order;
+
+ Params()
+ : order("order", 0)
+ {}
+ };
+
+ LLInventorySort(S32 order = 0)
+ {
+ fromParams(Params().order(order));
+ }
+
+ bool isByDate() const { return mByDate; }
+ U32 getSortOrder() const { return mSortOrder; }
+ void toParams(Params& p) { p.order(mSortOrder);}
+ void fromParams(Params& p)
+ {
+ mSortOrder = p.order;
+ mByDate = (mSortOrder & LLInventoryFilter::SO_DATE);
+ mSystemToTop = (mSortOrder & LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP);
+ mFoldersByName = (mSortOrder & LLInventoryFilter::SO_FOLDERS_BY_NAME);
+ }
+
+ bool operator()(const LLFolderViewModelItemInventory* const& a, const LLFolderViewModelItemInventory* const& b) const;
+private:
+ U32 mSortOrder;
+ bool mByDate;
+ bool mSystemToTop;
+ bool mFoldersByName;
+};
+
+class LLFolderViewModelInventory
+ : public LLFolderViewModel<LLInventorySort, LLFolderViewModelItemInventory, LLFolderViewModelItemInventory, LLInventoryFilter>
+{
+public:
+ typedef LLFolderViewModel<LLInventorySort, LLFolderViewModelItemInventory, LLFolderViewModelItemInventory, LLInventoryFilter> base_t;
+
+ void setTaskID(const LLUUID& id) {mTaskID = id;}
+
+ void sort(LLFolderViewFolder* folder);
+ bool contentsReady();
+ bool startDrag(std::vector<LLFolderViewModelItem*>& items);
+
+private:
+ LLUUID mTaskID;
+};
+#endif // LL_LLFOLDERVIEWMODELINVENTORY_H
diff --git a/indra/newview/llfollowcam.cpp b/indra/newview/llfollowcam.cpp
index b670af1782..47612fe25c 100644..100755
--- a/indra/newview/llfollowcam.cpp
+++ b/indra/newview/llfollowcam.cpp
@@ -38,7 +38,6 @@ std::vector<LLFollowCamParams*> LLFollowCamMgr::sParamStack;
//-------------------------------------------------------
// constants
//-------------------------------------------------------
-const F32 ONE_HALF = 0.5;
const F32 FOLLOW_CAM_ZOOM_FACTOR = 0.1f;
const F32 FOLLOW_CAM_MIN_ZOOM_AMOUNT = 0.1f;
const F32 DISTANCE_EPSILON = 0.0001f;
diff --git a/indra/newview/llfollowcam.h b/indra/newview/llfollowcam.h
index f4b7b2723a..f4b7b2723a 100644..100755
--- a/indra/newview/llfollowcam.h
+++ b/indra/newview/llfollowcam.h
diff --git a/indra/newview/llfriendcard.cpp b/indra/newview/llfriendcard.cpp
index 11401d6c68..16ed3f990c 100644..100755
--- a/indra/newview/llfriendcard.cpp
+++ b/indra/newview/llfriendcard.cpp
@@ -47,13 +47,13 @@ static const std::string INVENTORY_STRING_FRIENDS_ALL_SUBFOLDER = "All";
// helper functions
// NOTE: For now Friends & All folders are created as protected folders of the LLFolderType::FT_CALLINGCARD type.
-// So, their names will be processed in the LLFolderViewItem::refreshFromListener() to be localized
+// So, their names will be processed in the LLFolderViewItem::refresh() to be localized
// using "InvFolder LABEL_NAME" as LLTrans::findString argument.
// We must use in this file their hard-coded names to ensure found them on different locales. EXT-5829.
// These hard-coded names will be stored in InventoryItems but shown localized in FolderViewItems
-// If hack in the LLFolderViewItem::refreshFromListener() to localize protected folder is removed
+// If hack in the LLFolderViewItem::refresh() to localize protected folder is removed
// or these folders are not protected these names should be localized in another place/way.
inline const std::string get_friend_folder_name()
{
@@ -533,7 +533,7 @@ void LLFriendCardsManager::addFriendCardToInventory(const LLUUID& avatarID)
bool shouldBeAdded = true;
LLAvatarName av_name;
LLAvatarNameCache::get(avatarID, &av_name);
- const std::string& name = av_name.mUsername;
+ const std::string& name = av_name.getAccountName();
lldebugs << "Processing buddy name: " << name
<< ", id: " << avatarID
@@ -557,7 +557,7 @@ void LLFriendCardsManager::addFriendCardToInventory(const LLUUID& avatarID)
lldebugs << "Sent create_inventory_item for " << avatarID << ", " << name << llendl;
// TODO: mantipov: Is CreateFriendCardCallback really needed? Probably not
- LLPointer<LLInventoryCallback> cb = new CreateFriendCardCallback();
+ LLPointer<LLInventoryCallback> cb = new CreateFriendCardCallback;
create_inventory_callingcard(avatarID, findFriendAllSubfolderUUIDImpl(), cb);
}
diff --git a/indra/newview/llfriendcard.h b/indra/newview/llfriendcard.h
index 48a9f70079..48a9f70079 100644..100755
--- a/indra/newview/llfriendcard.h
+++ b/indra/newview/llfriendcard.h
diff --git a/indra/newview/llgesturelistener.cpp b/indra/newview/llgesturelistener.cpp
index 2fff506681..2fff506681 100644..100755
--- a/indra/newview/llgesturelistener.cpp
+++ b/indra/newview/llgesturelistener.cpp
diff --git a/indra/newview/llgesturelistener.h b/indra/newview/llgesturelistener.h
index 6f59698ed1..6f59698ed1 100644..100755
--- a/indra/newview/llgesturelistener.h
+++ b/indra/newview/llgesturelistener.h
diff --git a/indra/newview/llgesturemgr.cpp b/indra/newview/llgesturemgr.cpp
index 66ca76bfb0..b56c34573d 100644..100755
--- a/indra/newview/llgesturemgr.cpp
+++ b/indra/newview/llgesturemgr.cpp
@@ -35,6 +35,7 @@
// library
#include "llaudioengine.h"
#include "lldatapacker.h"
+#include "llfloaterreg.h"
#include "llinventory.h"
#include "llkeyframemotion.h"
#include "llmultigesture.h"
@@ -51,7 +52,7 @@
#include "llviewermessage.h"
#include "llvoavatarself.h"
#include "llviewerstats.h"
-#include "llnearbychatbar.h"
+#include "llfloaterimnearbychat.h"
#include "llappearancemgr.h"
#include "llgesturelistener.h"
@@ -165,7 +166,7 @@ void LLGestureMgr::activateGestures(LLViewerInventoryItem::item_array_t& items)
continue;
}
else
- { // Make gesture active and persistent through login sessions. -spatters 07-12-06
+ { // Make gesture active and persistent through login sessions. -Aura 07-12-06
activateGesture(item->getUUID());
}
@@ -337,7 +338,7 @@ void LLGestureMgr::deactivateGesture(const LLUUID& item_id)
gAgent.sendReliableMessage();
- LLAppearanceMgr::instance().removeCOFItemLinks(base_item_id, false);
+ LLAppearanceMgr::instance().removeCOFItemLinks(base_item_id);
notifyObservers();
}
@@ -997,7 +998,8 @@ void LLGestureMgr::runStep(LLMultiGesture* gesture, LLGestureStep* step)
const BOOL animate = FALSE;
- LLNearbyChatBar::getInstance()->sendChatFromViewer(chat_text, CHAT_TYPE_NORMAL, animate);
+ (LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat"))->
+ sendChatFromViewer(chat_text, CHAT_TYPE_NORMAL, animate);
gesture->mCurrentStep++;
break;
diff --git a/indra/newview/llgesturemgr.h b/indra/newview/llgesturemgr.h
index 26a5924ec3..26a5924ec3 100644..100755
--- a/indra/newview/llgesturemgr.h
+++ b/indra/newview/llgesturemgr.h
diff --git a/indra/newview/llgiveinventory.cpp b/indra/newview/llgiveinventory.cpp
index 30858871ec..72bea8db10 100644..100755
--- a/indra/newview/llgiveinventory.cpp
+++ b/indra/newview/llgiveinventory.cpp
@@ -220,17 +220,25 @@ bool LLGiveInventory::doGiveInventoryItem(const LLUUID& to_agent,
return res;
}
-void LLGiveInventory::doGiveInventoryCategory(const LLUUID& to_agent,
+bool LLGiveInventory::doGiveInventoryCategory(const LLUUID& to_agent,
const LLInventoryCategory* cat,
- const LLUUID& im_session_id)
+ const LLUUID& im_session_id,
+ const std::string& notification_name)
{
- if (!cat) return;
+ if (!cat)
+ {
+ return false;
+ }
llinfos << "LLGiveInventory::giveInventoryCategory() - "
<< cat->getUUID() << llendl;
- if (!isAgentAvatarValid()) return;
+ if (!isAgentAvatarValid())
+ {
+ return false;
+ }
+ bool give_successful = true;
// Test out how many items are being given.
LLViewerInventoryCategory::cat_array_t cats;
LLViewerInventoryItem::item_array_t items;
@@ -253,24 +261,24 @@ void LLGiveInventory::doGiveInventoryCategory(const LLUUID& to_agent,
if (!complete)
{
LLNotificationsUtil::add("IncompleteInventory");
- return;
+ give_successful = false;
}
count = items.count() + cats.count();
if (count > MAX_ITEMS)
{
LLNotificationsUtil::add("TooManyItems");
- return;
+ give_successful = false;
}
else if (count == 0)
{
LLNotificationsUtil::add("NoItems");
- return;
+ give_successful = false;
}
- else
+ else if (give_successful)
{
if (0 == giveable.countNoCopy())
{
- LLGiveInventory::commitGiveInventoryCategory(to_agent, cat, im_session_id);
+ give_successful = LLGiveInventory::commitGiveInventoryCategory(to_agent, cat, im_session_id);
}
else
{
@@ -279,9 +287,16 @@ void LLGiveInventory::doGiveInventoryCategory(const LLUUID& to_agent,
LLSD payload;
payload["agent_id"] = to_agent;
payload["folder_id"] = cat->getUUID();
+ if (!notification_name.empty())
+ {
+ payload["success_notification"] = notification_name;
+ }
LLNotificationsUtil::add("CannotCopyCountItems", args, payload, &LLGiveInventory::handleCopyProtectedCategory);
+ give_successful = false;
}
}
+
+ return give_successful;
}
//////////////////////////////////////////////////////////////////////////
@@ -325,6 +340,7 @@ bool LLGiveInventory::handleCopyProtectedItem(const LLSD& notification, const LL
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
LLSD itmes = notification["payload"]["items"];
LLInventoryItem* item = NULL;
+ bool give_successful = true;
switch(option)
{
case 0: // "Yes"
@@ -343,15 +359,21 @@ bool LLGiveInventory::handleCopyProtectedItem(const LLSD& notification, const LL
else
{
LLNotificationsUtil::add("CannotGiveItem");
+ give_successful = false;
}
}
+ if (give_successful && notification["payload"]["success_notification"].isDefined())
+ {
+ LLNotificationsUtil::add(notification["payload"]["success_notification"].asString());
+ }
break;
default: // no, cancel, whatever, who cares, not yes.
LLNotificationsUtil::add("TransactionCancelled");
+ give_successful = false;
break;
}
- return false;
+ return give_successful;
}
// static
@@ -408,13 +430,14 @@ bool LLGiveInventory::handleCopyProtectedCategory(const LLSD& notification, cons
{
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
LLInventoryCategory* cat = NULL;
+ bool give_successful = true;
switch(option)
{
case 0: // "Yes"
cat = gInventory.getCategory(notification["payload"]["folder_id"].asUUID());
if (cat)
{
- LLGiveInventory::commitGiveInventoryCategory(notification["payload"]["agent_id"].asUUID(),
+ give_successful = LLGiveInventory::commitGiveInventoryCategory(notification["payload"]["agent_id"].asUUID(),
cat);
LLViewerInventoryCategory::cat_array_t cats;
LLViewerInventoryItem::item_array_t items;
@@ -430,27 +453,37 @@ bool LLGiveInventory::handleCopyProtectedCategory(const LLSD& notification, cons
gInventory.deleteObject(items.get(i)->getUUID());
}
gInventory.notifyObservers();
+
+ if (give_successful && notification["payload"]["success_notification"].isDefined())
+ {
+ LLNotificationsUtil::add(notification["payload"]["success_notification"].asString());
+ }
}
else
{
LLNotificationsUtil::add("CannotGiveCategory");
+ give_successful = false;
}
break;
default: // no, cancel, whatever, who cares, not yes.
LLNotificationsUtil::add("TransactionCancelled");
+ give_successful = false;
break;
}
- return false;
+ return give_successful;
}
// static
-void LLGiveInventory::commitGiveInventoryCategory(const LLUUID& to_agent,
+bool LLGiveInventory::commitGiveInventoryCategory(const LLUUID& to_agent,
const LLInventoryCategory* cat,
const LLUUID& im_session_id)
{
- if (!cat) return;
+ if (!cat)
+ {
+ return false;
+ }
llinfos << "LLGiveInventory::commitGiveInventoryCategory() - "
<< cat->getUUID() << llendl;
@@ -467,6 +500,7 @@ void LLGiveInventory::commitGiveInventoryCategory(const LLUUID& to_agent,
LLInventoryModel::EXCLUDE_TRASH,
giveable);
+ bool give_successful = true;
// MAX ITEMS is based on (sizeof(uuid)+2) * count must be <
// MTUBYTES or 18 * count < 1200 => count < 1200/18 =>
// 66. I've cut it down a bit from there to give some pad.
@@ -474,12 +508,12 @@ void LLGiveInventory::commitGiveInventoryCategory(const LLUUID& to_agent,
if (count > MAX_ITEMS)
{
LLNotificationsUtil::add("TooManyItems");
- return;
+ give_successful = false;
}
else if (count == 0)
{
LLNotificationsUtil::add("NoItems");
- return;
+ give_successful = false;
}
else
{
@@ -545,6 +579,8 @@ void LLGiveInventory::commitGiveInventoryCategory(const LLUUID& to_agent,
logInventoryOffer(to_agent, im_session_id);
}
+
+ return give_successful;
}
// EOF
diff --git a/indra/newview/llgiveinventory.h b/indra/newview/llgiveinventory.h
index e1e221c75b..85bc1ed49c 100644..100755
--- a/indra/newview/llgiveinventory.h
+++ b/indra/newview/llgiveinventory.h
@@ -62,9 +62,10 @@ public:
/**
* Gives passed inventory category to specified avatar in specified session.
*/
- static void doGiveInventoryCategory(const LLUUID& to_agent,
+ static bool doGiveInventoryCategory(const LLUUID& to_agent,
const LLInventoryCategory* item,
- const LLUUID &session_id = LLUUID::null);
+ const LLUUID &session_id = LLUUID::null,
+ const std::string& notification = std::string());
// give inventory item functionality
static bool handleCopyProtectedItem(const LLSD& notification, const LLSD& response);
@@ -85,7 +86,7 @@ private:
// give inventory category functionality
static bool handleCopyProtectedCategory(const LLSD& notification, const LLSD& response);
- static void commitGiveInventoryCategory(const LLUUID& to_agent,
+ static bool commitGiveInventoryCategory(const LLUUID& to_agent,
const LLInventoryCategory* cat,
const LLUUID &im_session_id = LLUUID::null);
diff --git a/indra/newview/llglsandbox.cpp b/indra/newview/llglsandbox.cpp
index 1208c9378e..60fa53f491 100644..100755
--- a/indra/newview/llglsandbox.cpp
+++ b/indra/newview/llglsandbox.cpp
@@ -79,10 +79,10 @@ void LLToolSelectRect::handleRectangleSelection(S32 x, S32 y, MASK mask)
S32 top = llmax(y, mDragStartY);
S32 bottom =llmin(y, mDragStartY);
- left = llround((F32) left * LLUI::sGLScaleFactor.mV[VX]);
- right = llround((F32) right * LLUI::sGLScaleFactor.mV[VX]);
- top = llround((F32) top * LLUI::sGLScaleFactor.mV[VY]);
- bottom = llround((F32) bottom * LLUI::sGLScaleFactor.mV[VY]);
+ left = llround((F32) left * LLUI::getScaleFactor().mV[VX]);
+ right = llround((F32) right * LLUI::getScaleFactor().mV[VX]);
+ top = llround((F32) top * LLUI::getScaleFactor().mV[VY]);
+ bottom = llround((F32) bottom * LLUI::getScaleFactor().mV[VY]);
F32 old_far_plane = LLViewerCamera::getInstance()->getFar();
F32 old_near_plane = LLViewerCamera::getInstance()->getNear();
diff --git a/indra/newview/llgroupactions.cpp b/indra/newview/llgroupactions.cpp
index 623ebb76f2..302d21c2e4 100644..100755
--- a/indra/newview/llgroupactions.cpp
+++ b/indra/newview/llgroupactions.cpp
@@ -36,10 +36,10 @@
#include "llfloaterreg.h"
#include "llfloatersidepanelcontainer.h"
#include "llgroupmgr.h"
+#include "llfloaterimcontainer.h"
#include "llimview.h" // for gIMMgr
#include "llnotificationsutil.h"
#include "llstatusbar.h" // can_afford_transaction()
-#include "llimfloater.h"
#include "groupchatlistener.h"
//
@@ -116,6 +116,80 @@ public:
};
LLGroupHandler gGroupHandler;
+// This object represents a pending request for specified group member information
+// which is needed to check whether avatar can leave group
+class LLFetchGroupMemberData : public LLGroupMgrObserver
+{
+public:
+ LLFetchGroupMemberData(const LLUUID& group_id) :
+ mGroupId(group_id),
+ mRequestProcessed(false),
+ LLGroupMgrObserver(group_id)
+ {
+ llinfos << "Sending new group member request for group_id: "<< group_id << llendl;
+ LLGroupMgr* mgr = LLGroupMgr::getInstance();
+ // register ourselves as an observer
+ mgr->addObserver(this);
+ // send a request
+ mgr->sendGroupPropertiesRequest(group_id);
+ mgr->sendCapGroupMembersRequest(group_id);
+ }
+
+ ~LLFetchGroupMemberData()
+ {
+ if (!mRequestProcessed)
+ {
+ // Request is pending
+ llwarns << "Destroying pending group member request for group_id: "
+ << mGroupId << llendl;
+ }
+ // Remove ourselves as an observer
+ LLGroupMgr::getInstance()->removeObserver(this);
+ }
+
+ void changed(LLGroupChange gc)
+ {
+ if (gc == GC_MEMBER_DATA && !mRequestProcessed)
+ {
+ LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupId);
+ if (!gdatap)
+ {
+ llwarns << "LLGroupMgr::getInstance()->getGroupData() was NULL" << llendl;
+ }
+ else if (!gdatap->isMemberDataComplete())
+ {
+ llwarns << "LLGroupMgr::getInstance()->getGroupData()->isMemberDataComplete() was FALSE" << llendl;
+ }
+ else
+ {
+ processGroupData();
+ mRequestProcessed = true;
+ }
+ }
+ }
+
+ LLUUID getGroupId() { return mGroupId; }
+ virtual void processGroupData() = 0;
+protected:
+ LLUUID mGroupId;
+private:
+ bool mRequestProcessed;
+};
+
+class LLFetchLeaveGroupData: public LLFetchGroupMemberData
+{
+public:
+ LLFetchLeaveGroupData(const LLUUID& group_id)
+ : LLFetchGroupMemberData(group_id)
+ {}
+ void processGroupData()
+ {
+ LLGroupActions::processLeaveGroupDataResponse(mGroupId);
+ }
+};
+
+LLFetchLeaveGroupData* gFetchLeaveGroupData = NULL;
+
// static
void LLGroupActions::search()
{
@@ -208,23 +282,52 @@ bool LLGroupActions::onJoinGroup(const LLSD& notification, const LLSD& response)
void LLGroupActions::leave(const LLUUID& group_id)
{
if (group_id.isNull())
+ {
return;
+ }
- S32 count = gAgent.mGroups.count();
- S32 i;
- for (i = 0; i < count; ++i)
+ LLGroupData group_data;
+ if (gAgent.getGroupData(group_id, group_data))
{
- if(gAgent.mGroups.get(i).mID == group_id)
- break;
+ LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(group_id);
+ if (!gdatap || !gdatap->isMemberDataComplete())
+ {
+ if (gFetchLeaveGroupData != NULL)
+ {
+ delete gFetchLeaveGroupData;
+ gFetchLeaveGroupData = NULL;
+ }
+ gFetchLeaveGroupData = new LLFetchLeaveGroupData(group_id);
+ }
+ else
+ {
+ processLeaveGroupDataResponse(group_id);
+ }
}
- if (i < count)
+}
+
+//static
+void LLGroupActions::processLeaveGroupDataResponse(const LLUUID group_id)
+{
+ LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(group_id);
+ LLUUID agent_id = gAgent.getID();
+ LLGroupMgrGroupData::member_list_t::iterator mit = gdatap->mMembers.find(agent_id);
+ //get the member data for the group
+ if ( mit != gdatap->mMembers.end() )
{
- LLSD args;
- args["GROUP"] = gAgent.mGroups.get(i).mName;
- LLSD payload;
- payload["group_id"] = group_id;
- LLNotificationsUtil::add("GroupLeaveConfirmMember", args, payload, onLeaveGroup);
+ LLGroupMemberData* member_data = (*mit).second;
+
+ if ( member_data && member_data->isOwner() && gdatap->mMemberCount == 1)
+ {
+ LLNotificationsUtil::add("OwnerCannotLeaveGroup");
+ return;
+ }
}
+ LLSD args;
+ args["GROUP"] = gdatap->mName;
+ LLSD payload;
+ payload["group_id"] = group_id;
+ LLNotificationsUtil::add("GroupLeaveConfirmMember", args, payload, onLeaveGroup);
}
// static
@@ -335,7 +438,7 @@ LLUUID LLGroupActions::startIM(const LLUUID& group_id)
group_id);
if (session_id != LLUUID::null)
{
- LLIMFloater::show(session_id);
+ LLFloaterIMContainer::getInstance()->showConversation(session_id);
}
make_ui_sound("UISndStartIM");
return session_id;
diff --git a/indra/newview/llgroupactions.h b/indra/newview/llgroupactions.h
index 3f9852f194..afc4686dd7 100644..100755
--- a/indra/newview/llgroupactions.h
+++ b/indra/newview/llgroupactions.h
@@ -114,6 +114,14 @@ public:
private:
static bool onJoinGroup(const LLSD& notification, const LLSD& response);
static bool onLeaveGroup(const LLSD& notification, const LLSD& response);
+
+ /**
+ * This function is called by LLFetchLeaveGroupData upon receiving a response to a group
+ * members data request.
+ */
+ static void processLeaveGroupDataResponse(const LLUUID group_id);
+
+ friend class LLFetchLeaveGroupData;
};
#endif // LL_LLGROUPACTIONS_H
diff --git a/indra/newview/llgroupiconctrl.cpp b/indra/newview/llgroupiconctrl.cpp
index 2f9810775b..2d0fc26c2a 100644..100755
--- a/indra/newview/llgroupiconctrl.cpp
+++ b/indra/newview/llgroupiconctrl.cpp
@@ -29,6 +29,7 @@
#include "llgroupiconctrl.h"
#include "llagent.h"
+#include "llviewertexture.h"
/*
#include "llavatarconstants.h"
#include "llcallingcard.h" // for LLAvatarTracker
@@ -38,7 +39,7 @@
#include "llcachename.h"
#include "llagentdata.h"
-#include "llimfloater.h"
+#include "llfloaterimsession.h"
*/
static LLDefaultChildRegistry::Register<LLGroupIconCtrl> g_i("group_icon");
diff --git a/indra/newview/llgroupiconctrl.h b/indra/newview/llgroupiconctrl.h
index f42593c9e1..f42593c9e1 100644..100755
--- a/indra/newview/llgroupiconctrl.h
+++ b/indra/newview/llgroupiconctrl.h
diff --git a/indra/newview/llgrouplist.cpp b/indra/newview/llgrouplist.cpp
index 129cddda45..aba3d74d87 100644..100755
--- a/indra/newview/llgrouplist.cpp
+++ b/indra/newview/llgrouplist.cpp
@@ -86,7 +86,7 @@ LLGroupList::LLGroupList(const Params& p)
registrar.add("People.Groups.Action", boost::bind(&LLGroupList::onContextMenuItemClick, this, _2));
enable_registrar.add("People.Groups.Enable", boost::bind(&LLGroupList::onContextMenuItemEnable, this, _2));
- LLMenuGL* context_menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_people_groups.xml",
+ LLToggleableMenu* context_menu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_people_groups.xml",
gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
if(context_menu)
mContextMenuHandle = context_menu->getHandle();
@@ -112,7 +112,7 @@ BOOL LLGroupList::handleRightMouseDown(S32 x, S32 y, MASK mask)
{
BOOL handled = LLUICtrl::handleRightMouseDown(x, y, mask);
- LLMenuGL* context_menu = (LLMenuGL*)mContextMenuHandle.get();
+ LLToggleableMenu* context_menu = mContextMenuHandle.get();
if (context_menu && size() > 0)
{
context_menu->buildDrawLabels();
@@ -406,7 +406,7 @@ void LLGroupListItem::setActive(bool active)
// *BUG: setName() overrides the style params.
// Active group should be bold.
- LLFontDescriptor new_desc(mGroupNameBox->getDefaultFont()->getFontDesc());
+ LLFontDescriptor new_desc(mGroupNameBox->getFont()->getFontDesc());
// *NOTE dzaporozhan
// On Windows LLFontGL::NORMAL will not remove LLFontGL::BOLD if font
diff --git a/indra/newview/llgrouplist.h b/indra/newview/llgrouplist.h
index 8abf14b3d0..e96a720886 100644..100755
--- a/indra/newview/llgrouplist.h
+++ b/indra/newview/llgrouplist.h
@@ -28,10 +28,13 @@
#define LL_LLGROUPLIST_H
#include "llevent.h"
+#include "llpointer.h"
+
#include "llflatlistview.h"
#include "llpanel.h"
-#include "llpointer.h"
#include "llstyle.h"
+#include "lltoggleablemenu.h"
+
#include "llgroupmgr.h"
/**
@@ -45,6 +48,10 @@ class LLGroupList: public LLFlatListViewEx, public LLOldEvents::LLSimpleListener
{
LOG_CLASS(LLGroupList);
public:
+ struct Params : public LLInitParam::Block<Params, LLFlatListViewEx::Params>
+ {
+ Params(){};
+ };
LLGroupList(const Params& p);
virtual ~LLGroupList();
@@ -57,6 +64,8 @@ public:
void toggleIcons();
bool getIconsVisible() const { return mShowIcons; }
+ LLToggleableMenu* getContextMenu() const { return mContextMenuHandle.get(); }
+
private:
void setDirty(bool val = true) { mDirty = val; }
void refresh();
@@ -66,7 +75,7 @@ private:
bool onContextMenuItemClick(const LLSD& userdata);
bool onContextMenuItemEnable(const LLSD& userdata);
- LLHandle<LLView> mContextMenuHandle;
+ LLHandle<LLToggleableMenu> mContextMenuHandle;
bool mShowIcons;
bool mDirty;
diff --git a/indra/newview/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp
index efffd0f98e..cbd844cdac 100644..100755
--- a/indra/newview/llgroupmgr.cpp
+++ b/indra/newview/llgroupmgr.cpp
@@ -36,6 +36,7 @@
#include <vector>
#include <algorithm>
+#include "llappviewer.h"
#include "llagent.h"
#include "llui.h"
#include "message.h"
@@ -63,7 +64,7 @@
#pragma warning(pop) // Restore all warnings to the previous state
#endif
-const U32 MAX_CACHED_GROUPS = 10;
+const U32 MAX_CACHED_GROUPS = 20;
//
// LLRoleActionSet
@@ -234,8 +235,15 @@ LLGroupMgrGroupData::LLGroupMgrGroupData(const LLUUID& id) :
mRoleDataComplete(FALSE),
mRoleMemberDataComplete(FALSE),
mGroupPropertiesDataComplete(FALSE),
- mPendingRoleMemberRequest(FALSE)
+ mPendingRoleMemberRequest(FALSE),
+ mAccessTime(0.0f)
{
+ mMemberVersion.generate();
+}
+
+void LLGroupMgrGroupData::setAccessed()
+{
+ mAccessTime = (F32)LLFrameTimer::getTotalSeconds();
}
BOOL LLGroupMgrGroupData::getRoleData(const LLUUID& role_id, LLRoleData& role_data)
@@ -311,14 +319,14 @@ void LLGroupMgrGroupData::setRoleData(const LLUUID& role_id, LLRoleData role_dat
role_data.mChangeType = RC_UPDATE_DATA;
}
else
- {
+ {
role_data.mChangeType = RC_UPDATE_POWERS;
}
mRoleChanges[role_id] = role_data;
}
else
- {
+ {
llwarns << "Change being made to non-existant role " << role_id << llendl;
}
}
@@ -417,6 +425,7 @@ void LLGroupMgrGroupData::removeMemberData()
}
mMembers.clear();
mMemberDataComplete = FALSE;
+ mMemberVersion.generate();
}
void LLGroupMgrGroupData::removeRoleData()
@@ -739,6 +748,7 @@ void LLGroupMgrGroupData::cancelRoleChanges()
LLGroupMgr::LLGroupMgr()
{
+ mLastGroupMembersRequestFrame = 0;
}
LLGroupMgr::~LLGroupMgr()
@@ -937,6 +947,8 @@ void LLGroupMgr::processGroupMembersReply(LLMessageSystem* msg, void** data)
}
}
+ group_datap->mMemberVersion.generate();
+
if (group_datap->mMembers.size() == (U32)group_datap->mMemberCount)
{
group_datap->mMemberDataComplete = TRUE;
@@ -1360,7 +1372,7 @@ void LLGroupMgr::processCreateGroupReply(LLMessageSystem* msg, void ** data)
LLGroupMgrGroupData* LLGroupMgr::createGroupData(const LLUUID& id)
{
- LLGroupMgrGroupData* group_datap;
+ LLGroupMgrGroupData* group_datap = NULL;
group_map_t::iterator existing_group = LLGroupMgr::getInstance()->mGroups.find(id);
if (existing_group == LLGroupMgr::getInstance()->mGroups.end())
@@ -1373,6 +1385,11 @@ LLGroupMgrGroupData* LLGroupMgr::createGroupData(const LLUUID& id)
group_datap = existing_group->second;
}
+ if (group_datap)
+ {
+ group_datap->setAccessed();
+ }
+
return group_datap;
}
@@ -1413,25 +1430,41 @@ void LLGroupMgr::notifyObservers(LLGroupChange gc)
void LLGroupMgr::addGroup(LLGroupMgrGroupData* group_datap)
{
- if (mGroups.size() > MAX_CACHED_GROUPS)
+ while (mGroups.size() >= MAX_CACHED_GROUPS)
{
- // get rid of groups that aren't observed
- for (group_map_t::iterator gi = mGroups.begin(); gi != mGroups.end() && mGroups.size() > MAX_CACHED_GROUPS / 2; )
+ // LRU: Remove the oldest un-observed group from cache until group size is small enough
+
+ F32 oldest_access = LLFrameTimer::getTotalSeconds();
+ group_map_t::iterator oldest_gi = mGroups.end();
+
+ for (group_map_t::iterator gi = mGroups.begin(); gi != mGroups.end(); ++gi )
{
observer_multimap_t::iterator oi = mObservers.find(gi->first);
if (oi == mObservers.end())
{
- // not observed
- LLGroupMgrGroupData* unobserved_groupp = gi->second;
- delete unobserved_groupp;
- mGroups.erase(gi++);
- }
- else
- {
- ++gi;
+ if (gi->second
+ && (gi->second->getAccessTime() < oldest_access))
+ {
+ oldest_access = gi->second->getAccessTime();
+ oldest_gi = gi;
+ }
}
}
+
+ if (oldest_gi != mGroups.end())
+ {
+ delete oldest_gi->second;
+ mGroups.erase(oldest_gi);
+ }
+ else
+ {
+ // All groups must be currently open, none to remove.
+ // Just add the new group anyway, but get out of this loop as it
+ // will never drop below max_cached_groups.
+ break;
+ }
}
+
mGroups[group_datap->getID()] = group_datap;
}
@@ -1473,6 +1506,7 @@ void LLGroupMgr::sendGroupMembersRequest(const LLUUID& group_id)
}
}
+
void LLGroupMgr::sendGroupRoleDataRequest(const LLUUID& group_id)
{
lldebugs << "LLGroupMgr::sendGroupRoleDataRequest" << llendl;
@@ -1741,8 +1775,6 @@ void LLGroupMgr::sendGroupMemberEjects(const LLUUID& group_id,
bool start_message = true;
LLMessageSystem* msg = gMessageSystem;
-
-
LLGroupMgrGroupData* group_datap = LLGroupMgr::getInstance()->getGroupData(group_id);
if (!group_datap) return;
@@ -1803,8 +1835,194 @@ void LLGroupMgr::sendGroupMemberEjects(const LLUUID& group_id,
{
gAgent.sendReliableMessage();
}
+
+ group_datap->mMemberVersion.generate();
+}
+
+
+// Responder class for capability group management
+class GroupMemberDataResponder : public LLHTTPClient::Responder
+{
+public:
+ GroupMemberDataResponder() {}
+ virtual ~GroupMemberDataResponder() {}
+ virtual void result(const LLSD& pContent);
+ virtual void errorWithContent(U32 pStatus, const std::string& pReason, const LLSD& pContent);
+private:
+ LLSD mMemberData;
+};
+
+void GroupMemberDataResponder::errorWithContent(U32 pStatus, const std::string& pReason, const LLSD& pContent)
+{
+ LL_WARNS("GrpMgr") << "Error receiving group member data [status:"
+ << pStatus << "]: " << pContent << LL_ENDL;
}
+void GroupMemberDataResponder::result(const LLSD& content)
+{
+ LLGroupMgr::processCapGroupMembersRequest(content);
+}
+
+
+// static
+void LLGroupMgr::sendCapGroupMembersRequest(const LLUUID& group_id)
+{
+ // Have we requested the information already this frame?
+ if(mLastGroupMembersRequestFrame == gFrameCount)
+ return;
+
+ LLViewerRegion* currentRegion = gAgent.getRegion();
+ // Thank you FS:Ansariel!
+ if(!currentRegion)
+ {
+ LL_WARNS("GrpMgr") << "Agent does not have a current region. Uh-oh!" << LL_ENDL;
+ return;
+ }
+
+ // Check to make sure we have our capabilities
+ if(!currentRegion->capabilitiesReceived())
+ {
+ LL_WARNS("GrpMgr") << " Capabilities not received!" << LL_ENDL;
+ return;
+ }
+
+ // Get our capability
+ std::string cap_url = currentRegion->getCapability("GroupMemberData");
+
+ // Thank you FS:Ansariel!
+ if(cap_url.empty())
+ {
+ LL_INFOS("GrpMgr") << "Region has no GroupMemberData capability. Falling back to UDP fetch." << LL_ENDL;
+ sendGroupMembersRequest(group_id);
+ return;
+ }
+
+ // Post to our service. Add a body containing the group_id.
+ LLSD body = LLSD::emptyMap();
+ body["group_id"] = group_id;
+
+ LLHTTPClient::ResponderPtr grp_data_responder = new GroupMemberDataResponder();
+
+ // This could take a while to finish, timeout after 5 minutes.
+ LLHTTPClient::post(cap_url, body, grp_data_responder, LLSD(), 300);
+
+ mLastGroupMembersRequestFrame = gFrameCount;
+}
+
+
+// static
+void LLGroupMgr::processCapGroupMembersRequest(const LLSD& content)
+{
+ // Did we get anything in content?
+ if(!content.size())
+ {
+ LL_DEBUGS("GrpMgr") << "No group member data received." << LL_ENDL;
+ return;
+ }
+
+ // If we have no members, there's no reason to do anything else
+ S32 num_members = content["member_count"];
+ if(num_members < 1)
+ return;
+
+ LLUUID group_id = content["group_id"].asUUID();
+
+ LLGroupMgrGroupData* group_datap = LLGroupMgr::getInstance()->getGroupData(group_id);
+ if(!group_datap)
+ {
+ LL_WARNS("GrpMgr") << "Received incorrect, possibly stale, group or request id" << LL_ENDL;
+ return;
+ }
+
+ group_datap->mMemberCount = num_members;
+
+ LLSD member_list = content["members"];
+ LLSD titles = content["titles"];
+ LLSD defaults = content["defaults"];
+
+ std::string online_status;
+ std::string title;
+ S32 contribution;
+ U64 member_powers;
+ // If this is changed to a bool, make sure to change the LLGroupMemberData constructor
+ BOOL is_owner;
+
+ // Compute this once, rather than every time.
+ U64 default_powers = llstrtou64(defaults["default_powers"].asString().c_str(), NULL, 16);
+
+ LLSD::map_const_iterator member_iter_start = member_list.beginMap();
+ LLSD::map_const_iterator member_iter_end = member_list.endMap();
+ for( ; member_iter_start != member_iter_end; ++member_iter_start)
+ {
+ // Reset defaults
+ online_status = "unknown";
+ title = titles[0].asString();
+ contribution = 0;
+ member_powers = default_powers;
+ is_owner = false;
+
+ const LLUUID member_id(member_iter_start->first);
+ LLSD member_info = member_iter_start->second;
+
+ if(member_info.has("last_login"))
+ {
+ online_status = member_info["last_login"].asString();
+ if(online_status == "Online")
+ online_status = LLTrans::getString("group_member_status_online");
+ else
+ formatDateString(online_status);
+ }
+
+ if(member_info.has("title"))
+ title = titles[member_info["title"].asInteger()].asString();
+
+ if(member_info.has("powers"))
+ member_powers = llstrtou64(member_info["powers"].asString().c_str(), NULL, 16);
+
+ if(member_info.has("donated_square_meters"))
+ contribution = member_info["donated_square_meters"];
+
+ if(member_info.has("owner"))
+ is_owner = true;
+
+ LLGroupMemberData* data = new LLGroupMemberData(member_id,
+ contribution,
+ member_powers,
+ title,
+ online_status,
+ is_owner);
+
+ group_datap->mMembers[member_id] = data;
+ }
+
+ group_datap->mMemberVersion.generate();
+
+ // Technically, we have this data, but to prevent completely overhauling
+ // this entire system (it would be nice, but I don't have the time),
+ // I'm going to be dumb and just call services I most likely don't need
+ // with the thought being that the system might need it to be done.
+ //
+ // TODO:
+ // Refactor to reduce multiple calls for data we already have.
+ if(group_datap->mTitles.size() < 1)
+ LLGroupMgr::getInstance()->sendGroupTitlesRequest(group_id);
+
+
+ group_datap->mMemberDataComplete = TRUE;
+ group_datap->mMemberRequestID.setNull();
+ // Make the role-member data request
+ if (group_datap->mPendingRoleMemberRequest)
+ {
+ group_datap->mPendingRoleMemberRequest = FALSE;
+ LLGroupMgr::getInstance()->sendGroupRoleMembersRequest(group_id);
+ }
+
+ group_datap->mChanged = TRUE;
+ LLGroupMgr::getInstance()->notifyObservers(GC_MEMBER_DATA);
+
+}
+
+
void LLGroupMgr::sendGroupRoleChanges(const LLUUID& group_id)
{
lldebugs << "LLGroupMgr::sendGroupRoleChanges" << llendl;
diff --git a/indra/newview/llgroupmgr.h b/indra/newview/llgroupmgr.h
index faf0531c10..d8c1ab7ef5 100644..100755
--- a/indra/newview/llgroupmgr.h
+++ b/indra/newview/llgroupmgr.h
@@ -86,7 +86,7 @@ public:
BOOL isInRole(const LLUUID& role_id) { return (mRolesList.find(role_id) != mRolesList.end()); }
-protected:
+private:
LLUUID mID;
S32 mContribution;
U64 mAgentPowers;
@@ -233,6 +233,11 @@ public:
BOOL isRoleMemberDataComplete() { return mRoleMemberDataComplete; }
BOOL isGroupPropertiesDataComplete() { return mGroupPropertiesDataComplete; }
+ F32 getAccessTime() const { return mAccessTime; }
+ void setAccessed();
+
+ const LLUUID& getMemberVersion() const { return mMemberVersion; }
+
public:
typedef std::map<LLUUID,LLGroupMemberData*> member_list_t;
typedef std::map<LLUUID,LLGroupRoleData*> role_list_t;
@@ -280,6 +285,10 @@ private:
BOOL mGroupPropertiesDataComplete;
BOOL mPendingRoleMemberRequest;
+ F32 mAccessTime;
+
+ // Generate a new ID every time mMembers
+ LLUUID mMemberVersion;
};
struct LLRoleAction
@@ -336,6 +345,10 @@ public:
static void sendGroupMemberEjects(const LLUUID& group_id,
uuid_vec_t& member_ids);
+ // BAKER
+ void sendCapGroupMembersRequest(const LLUUID& group_id);
+ static void processCapGroupMembersRequest(const LLSD& content);
+
void cancelGroupRoleChanges(const LLUUID& group_id);
static void processGroupPropertiesReply(LLMessageSystem* msg, void** data);
@@ -371,6 +384,8 @@ private:
typedef std::set<LLParticularGroupObserver*> observer_set_t;
typedef std::map<LLUUID,observer_set_t> observer_map_t;
observer_map_t mParticularObservers;
+
+ S32 mLastGroupMembersRequestFrame;
};
diff --git a/indra/newview/llhasheduniqueid.cpp b/indra/newview/llhasheduniqueid.cpp
new file mode 100644
index 0000000000..03192d3e61
--- /dev/null
+++ b/indra/newview/llhasheduniqueid.cpp
@@ -0,0 +1,55 @@
+/**
+ * @file llhasheduniqueid.cpp
+ * @brief retrieves an obfuscated unique id for the system
+ *
+ * $LicenseInfo:firstyear=2013&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2013, 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 "llhasheduniqueid.h"
+#include "llviewernetwork.h"
+#include "lluuid.h"
+#include "llmachineid.h"
+
+bool llHashedUniqueID(unsigned char id[MD5HEX_STR_SIZE])
+{
+ bool idIsUnique = true;
+ LLMD5 hashed_unique_id;
+ unsigned char unique_id[MAC_ADDRESS_BYTES];
+ if ( LLUUID::getNodeID(unique_id)
+ || LLMachineID::getUniqueID(unique_id, sizeof(unique_id))
+ )
+ {
+ hashed_unique_id.update(unique_id, MAC_ADDRESS_BYTES);
+ hashed_unique_id.finalize();
+ hashed_unique_id.hex_digest((char*)id);
+ LL_INFOS_ONCE("AppInit") << "System ID " << id << LL_ENDL;
+ }
+ else
+ {
+ idIsUnique = false;
+ memcpy(id,"00000000000000000000000000000000", MD5HEX_STR_SIZE);
+ LL_WARNS_ONCE("AppInit") << "Failed to get an id; cannot uniquely identify this machine." << LL_ENDL;
+ }
+ return idIsUnique;
+}
+
diff --git a/indra/newview/llhasheduniqueid.h b/indra/newview/llhasheduniqueid.h
new file mode 100644
index 0000000000..8ef706c1f3
--- /dev/null
+++ b/indra/newview/llhasheduniqueid.h
@@ -0,0 +1,34 @@
+/**
+ * @file llhasheduniqueid.h
+ * @brief retrieves obfuscated but unique id for the system
+ *
+ * $LicenseInfo:firstyear=2013&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2013, 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_LLHASHEDUNIQUEID_H
+#define LL_LLHASHEDUNIQUEID_H
+#include "llmd5.h"
+
+/// Get an obfuscated identifier for this system
+bool llHashedUniqueID(unsigned char id[MD5HEX_STR_SIZE]);
+///< @returns true if the id is considered valid (if false, the id is all zeros)
+
+#endif // LL_LLHASHEDUNIQUEID_H
diff --git a/indra/newview/llhints.cpp b/indra/newview/llhints.cpp
index e15862e2a4..197408b40e 100644..100755
--- a/indra/newview/llhints.cpp
+++ b/indra/newview/llhints.cpp
@@ -171,12 +171,12 @@ LLHintPopup::LLHintPopup(const LLHintPopup::Params& p)
}
if (p.hint_image.isProvided())
{
- buildFromFile("panel_hint_image.xml", NULL, p);
+ buildFromFile("panel_hint_image.xml", p);
getChild<LLIconCtrl>("hint_image")->setImage(p.hint_image());
}
else
{
- buildFromFile( "panel_hint.xml", NULL, p);
+ buildFromFile( "panel_hint.xml", p);
}
}
diff --git a/indra/newview/llhints.h b/indra/newview/llhints.h
index ebffe561b9..ebffe561b9 100644..100755
--- a/indra/newview/llhints.h
+++ b/indra/newview/llhints.h
diff --git a/indra/newview/llhomelocationresponder.cpp b/indra/newview/llhomelocationresponder.cpp
index 4850d18d99..37428c4a44 100644..100755
--- a/indra/newview/llhomelocationresponder.cpp
+++ b/indra/newview/llhomelocationresponder.cpp
@@ -97,7 +97,7 @@ void LLHomeLocationResponder::result( const LLSD& content )
}
}
-void LLHomeLocationResponder::error( U32 status, const std::string& reason )
+void LLHomeLocationResponder::errorWithContent( U32 status, const std::string& reason, const LLSD& content )
{
- llinfos << "received error(" << reason << ")" << llendl;
+ llwarns << "LLHomeLocationResponder error [status:" << status << "]: " << content << llendl;
}
diff --git a/indra/newview/llhomelocationresponder.h b/indra/newview/llhomelocationresponder.h
index d640b9c894..9bf4b12c4e 100644..100755
--- a/indra/newview/llhomelocationresponder.h
+++ b/indra/newview/llhomelocationresponder.h
@@ -36,7 +36,7 @@
class LLHomeLocationResponder : public LLHTTPClient::Responder
{
virtual void result( const LLSD& content );
- virtual void error( U32 status, const std::string& reason );
+ virtual void errorWithContent( U32 status, const std::string& reason, const LLSD& content );
};
#endif
diff --git a/indra/newview/llhudeffect.cpp b/indra/newview/llhudeffect.cpp
index 159ec6c803..159ec6c803 100644..100755
--- a/indra/newview/llhudeffect.cpp
+++ b/indra/newview/llhudeffect.cpp
diff --git a/indra/newview/llhudeffect.h b/indra/newview/llhudeffect.h
index 7c825e3f3d..7c825e3f3d 100644..100755
--- a/indra/newview/llhudeffect.h
+++ b/indra/newview/llhudeffect.h
diff --git a/indra/newview/llhudeffectbeam.cpp b/indra/newview/llhudeffectbeam.cpp
index 8abad3d292..8abad3d292 100644..100755
--- a/indra/newview/llhudeffectbeam.cpp
+++ b/indra/newview/llhudeffectbeam.cpp
diff --git a/indra/newview/llhudeffectbeam.h b/indra/newview/llhudeffectbeam.h
index fdee5178af..fdee5178af 100644..100755
--- a/indra/newview/llhudeffectbeam.h
+++ b/indra/newview/llhudeffectbeam.h
diff --git a/indra/newview/llhudeffectblob.cpp b/indra/newview/llhudeffectblob.cpp
index c909551b51..c909551b51 100644..100755
--- a/indra/newview/llhudeffectblob.cpp
+++ b/indra/newview/llhudeffectblob.cpp
diff --git a/indra/newview/llhudeffectblob.h b/indra/newview/llhudeffectblob.h
index ce3e8500fc..ce3e8500fc 100644..100755
--- a/indra/newview/llhudeffectblob.h
+++ b/indra/newview/llhudeffectblob.h
diff --git a/indra/newview/llhudeffectlookat.cpp b/indra/newview/llhudeffectlookat.cpp
index bc3b220dc0..9dde65ceb6 100644..100755
--- a/indra/newview/llhudeffectlookat.cpp
+++ b/indra/newview/llhudeffectlookat.cpp
@@ -636,7 +636,7 @@ bool LLHUDEffectLookAt::calcTargetPosition()
}
else
{
- target_rot = target_av->mRoot.getWorldRotation();
+ target_rot = target_av->mRoot->getWorldRotation();
}
}
else // target obj is not an avatar
diff --git a/indra/newview/llhudeffectlookat.h b/indra/newview/llhudeffectlookat.h
index fd057715b6..fd057715b6 100644..100755
--- a/indra/newview/llhudeffectlookat.h
+++ b/indra/newview/llhudeffectlookat.h
diff --git a/indra/newview/llhudeffectpointat.cpp b/indra/newview/llhudeffectpointat.cpp
index 114a633821..114a633821 100644..100755
--- a/indra/newview/llhudeffectpointat.cpp
+++ b/indra/newview/llhudeffectpointat.cpp
diff --git a/indra/newview/llhudeffectpointat.h b/indra/newview/llhudeffectpointat.h
index 6200b68cbc..6200b68cbc 100644..100755
--- a/indra/newview/llhudeffectpointat.h
+++ b/indra/newview/llhudeffectpointat.h
diff --git a/indra/newview/llhudeffecttrail.cpp b/indra/newview/llhudeffecttrail.cpp
index 39b526c1b5..39b526c1b5 100644..100755
--- a/indra/newview/llhudeffecttrail.cpp
+++ b/indra/newview/llhudeffecttrail.cpp
diff --git a/indra/newview/llhudeffecttrail.h b/indra/newview/llhudeffecttrail.h
index 6f5a328c63..6f5a328c63 100644..100755
--- a/indra/newview/llhudeffecttrail.h
+++ b/indra/newview/llhudeffecttrail.h
diff --git a/indra/newview/llhudicon.cpp b/indra/newview/llhudicon.cpp
index 7e1025c41b..825c2b31be 100644..100755
--- a/indra/newview/llhudicon.cpp
+++ b/indra/newview/llhudicon.cpp
@@ -202,7 +202,7 @@ void LLHUDIcon::render()
renderIcon(FALSE);
}
-BOOL LLHUDIcon::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, LLVector3* intersection)
+BOOL LLHUDIcon::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, LLVector4a* intersection)
{
if (mHidden)
return FALSE;
@@ -275,23 +275,18 @@ BOOL LLHUDIcon::lineSegmentIntersect(const LLVector3& start, const LLVector3& en
LLVector4a upper_right;
upper_right.setAdd(lower_right, y_scalea);
- LLVector4a enda;
- enda.load3(end.mV);
- LLVector4a starta;
- starta.load3(start.mV);
LLVector4a dir;
- dir.setSub(enda, starta);
+ dir.setSub(end, start);
F32 a,b,t;
- if (LLTriangleRayIntersect(upper_right, upper_left, lower_right, starta, dir, a,b,t) ||
- LLTriangleRayIntersect(upper_left, lower_left, lower_right, starta, dir, a,b,t))
+ if (LLTriangleRayIntersect(upper_right, upper_left, lower_right, start, dir, a,b,t) ||
+ LLTriangleRayIntersect(upper_left, lower_left, lower_right, start, dir, a,b,t))
{
if (intersection)
{
dir.mul(t);
- starta.add(dir);
- *intersection = LLVector3(starta.getF32ptr());
+ intersection->setAdd(start, dir);
}
return TRUE;
}
@@ -331,12 +326,12 @@ LLHUDIcon* LLHUDIcon::handlePick(S32 pick_id)
}
//static
-LLHUDIcon* LLHUDIcon::lineSegmentIntersectAll(const LLVector3& start, const LLVector3& end, LLVector3* intersection)
+LLHUDIcon* LLHUDIcon::lineSegmentIntersectAll(const LLVector4a& start, const LLVector4a& end, LLVector4a* intersection)
{
icon_instance_t::iterator icon_it;
- LLVector3 local_end = end;
- LLVector3 position;
+ LLVector4a local_end = end;
+ LLVector4a position;
LLHUDIcon* ret = NULL;
for(icon_it = sIconInstances.begin(); icon_it != sIconInstances.end(); ++icon_it)
diff --git a/indra/newview/llhudicon.h b/indra/newview/llhudicon.h
index 644daa0299..557252ab0b 100644..100755
--- a/indra/newview/llhudicon.h
+++ b/indra/newview/llhudicon.h
@@ -62,7 +62,7 @@ public:
static S32 generatePickIDs(S32 start_id, S32 step_size);
static LLHUDIcon* handlePick(S32 pick_id);
- static LLHUDIcon* lineSegmentIntersectAll(const LLVector3& start, const LLVector3& end, LLVector3* intersection);
+ static LLHUDIcon* lineSegmentIntersectAll(const LLVector4a& start, const LLVector4a& end, LLVector4a* intersection);
static void updateAll();
static void cleanupDeadIcons();
@@ -73,7 +73,7 @@ public:
BOOL getHidden() const { return mHidden; }
void setHidden( BOOL hide ) { mHidden = hide; }
- BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end, LLVector3* intersection);
+ BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, LLVector4a* intersection);
protected:
LLHUDIcon(const U8 type);
diff --git a/indra/newview/llhudmanager.cpp b/indra/newview/llhudmanager.cpp
index 8f14b53db0..8f14b53db0 100644..100755
--- a/indra/newview/llhudmanager.cpp
+++ b/indra/newview/llhudmanager.cpp
diff --git a/indra/newview/llhudmanager.h b/indra/newview/llhudmanager.h
index 09e79acbfc..09e79acbfc 100644..100755
--- a/indra/newview/llhudmanager.h
+++ b/indra/newview/llhudmanager.h
diff --git a/indra/newview/llhudnametag.cpp b/indra/newview/llhudnametag.cpp
index 482294c8a6..c3b49f739a 100644..100755
--- a/indra/newview/llhudnametag.cpp
+++ b/indra/newview/llhudnametag.cpp
@@ -116,7 +116,7 @@ LLHUDNameTag::~LLHUDNameTag()
}
-BOOL LLHUDNameTag::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, LLVector3& intersection, BOOL debug_render)
+BOOL LLHUDNameTag::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, LLVector4a& intersection, BOOL debug_render)
{
if (!mVisible || mHidden)
{
@@ -166,7 +166,6 @@ BOOL LLHUDNameTag::lineSegmentIntersect(const LLVector3& start, const LLVector3&
}
// scale screen size of borders down
- //RN: for now, text on hud objects is never occluded
LLVector3 x_pixel_vec;
LLVector3 y_pixel_vec;
@@ -187,45 +186,37 @@ BOOL LLHUDNameTag::lineSegmentIntersect(const LLVector3& start, const LLVector3&
+ (y_pixel_vec * screen_offset.mV[VY]);
- //if (mUseBubble)
- {
- LLVector3 bg_pos = render_position
- + (F32)mOffsetY * y_pixel_vec
- - (width_vec / 2.f)
- - (height_vec);
- //LLUI::translate(bg_pos.mV[VX], bg_pos.mV[VY], bg_pos.mV[VZ]);
+ LLVector3 bg_pos = render_position
+ + (F32)mOffsetY * y_pixel_vec
+ - (width_vec / 2.f)
+ - (height_vec);
- LLVector3 v[] =
- {
- bg_pos,
- bg_pos + width_vec,
- bg_pos + width_vec + height_vec,
- bg_pos + height_vec,
- };
+ LLVector3 v[] =
+ {
+ bg_pos,
+ bg_pos + width_vec,
+ bg_pos + width_vec + height_vec,
+ bg_pos + height_vec,
+ };
- if (debug_render)
- {
- gGL.begin(LLRender::LINE_STRIP);
- gGL.vertex3fv(v[0].mV);
- gGL.vertex3fv(v[1].mV);
- gGL.vertex3fv(v[2].mV);
- gGL.vertex3fv(v[3].mV);
- gGL.vertex3fv(v[0].mV);
- gGL.vertex3fv(v[2].mV);
- gGL.end();
- }
+ LLVector4a dir;
+ dir.setSub(end,start);
+ F32 a, b, t;
- LLVector3 dir = end-start;
- F32 a, b, t;
+ LLVector4a v0,v1,v2,v3;
+ v0.load3(v[0].mV);
+ v1.load3(v[1].mV);
+ v2.load3(v[2].mV);
+ v3.load3(v[3].mV);
- if (LLTriangleRayIntersect(v[0], v[1], v[2], start, dir, a, b, t, FALSE) ||
- LLTriangleRayIntersect(v[2], v[3], v[0], start, dir, a, b, t, FALSE) )
+ if (LLTriangleRayIntersect(v0, v1, v2, start, dir, a, b, t) ||
+ LLTriangleRayIntersect(v2, v3, v0, start, dir, a, b, t) )
+ {
+ if (t <= 1.f)
{
- if (t <= 1.f)
- {
- intersection = start + dir*t;
- return TRUE;
- }
+ dir.mul(t);
+ intersection.setAdd(start, dir);
+ return TRUE;
}
}
@@ -241,12 +232,6 @@ void LLHUDNameTag::render()
}
}
-void LLHUDNameTag::renderForSelect()
-{
- LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
- renderText(TRUE);
-}
-
void LLHUDNameTag::renderText(BOOL for_select)
{
if (!mVisible || mHidden)
@@ -299,24 +284,6 @@ void LLHUDNameTag::renderText(BOOL for_select)
LLColor4 bg_color = LLUIColorTable::instance().getColor("NameTagBackground");
bg_color.setAlpha(gSavedSettings.getF32("ChatBubbleOpacity") * alpha_factor);
- // maybe a no-op?
- //const S32 border_height = 16;
- //const S32 border_width = 16;
- const S32 border_height = 8;
- const S32 border_width = 8;
-
- // *TODO move this into helper function
- F32 border_scale = 1.f;
-
- if (border_height * 2 > mHeight)
- {
- border_scale = (F32)mHeight / ((F32)border_height * 2.f);
- }
- if (border_width * 2 > mWidth)
- {
- border_scale = llmin(border_scale, (F32)mWidth / ((F32)border_width * 2.f));
- }
-
// scale screen size of borders down
//RN: for now, text on hud objects is never occluded
@@ -325,152 +292,34 @@ void LLHUDNameTag::renderText(BOOL for_select)
LLViewerCamera::getInstance()->getPixelVectors(mPositionAgent, y_pixel_vec, x_pixel_vec);
- LLVector2 border_scale_vec((F32)border_width / (F32)imagep->getTextureWidth(), (F32)border_height / (F32)imagep->getTextureHeight());
LLVector3 width_vec = mWidth * x_pixel_vec;
LLVector3 height_vec = mHeight * y_pixel_vec;
- LLVector3 scaled_border_width = (F32)llfloor(border_scale * (F32)border_width) * x_pixel_vec;
- LLVector3 scaled_border_height = (F32)llfloor(border_scale * (F32)border_height) * y_pixel_vec;
mRadius = (width_vec + height_vec).magVec() * 0.5f;
LLCoordGL screen_pos;
LLViewerCamera::getInstance()->projectPosAgentToScreen(mPositionAgent, screen_pos, FALSE);
- LLVector2 screen_offset;
-// if (!mUseBubble)
-// {
-// screen_offset = mPositionOffset;
-// }
-// else
-// {
- screen_offset = updateScreenPos(mPositionOffset);
-// }
+ LLVector2 screen_offset = updateScreenPos(mPositionOffset);
LLVector3 render_position = mPositionAgent
+ (x_pixel_vec * screen_offset.mV[VX])
+ (y_pixel_vec * screen_offset.mV[VY]);
-// if (mUseBubble)
+ LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
+ LLRect screen_rect;
+ screen_rect.setCenterAndSize(0, static_cast<S32>(lltrunc(-mHeight / 2 + mOffsetY)), static_cast<S32>(lltrunc(mWidth)), static_cast<S32>(lltrunc(mHeight)));
+ imagep->draw3D(render_position, x_pixel_vec, y_pixel_vec, screen_rect, bg_color);
+ if (mLabelSegments.size())
{
- LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
- LLUI::pushMatrix();
- {
- LLVector3 bg_pos = render_position
- + (F32)mOffsetY * y_pixel_vec
- - (width_vec / 2.f)
- - (height_vec);
- LLUI::translate(bg_pos.mV[VX], bg_pos.mV[VY], bg_pos.mV[VZ]);
+ LLUIImagePtr rect_top_image = LLUI::getUIImage("Rounded_Rect_Top");
+ LLRect label_top_rect = screen_rect;
+ const S32 label_height = llround((mFontp->getLineHeight() * (F32)mLabelSegments.size() + (VERTICAL_PADDING / 3.f)));
+ label_top_rect.mBottom = label_top_rect.mTop - label_height;
+ LLColor4 label_top_color = text_color;
+ label_top_color.mV[VALPHA] = gSavedSettings.getF32("ChatBubbleOpacity") * alpha_factor;
- if (for_select)
- {
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- S32 name = mSourceObject->mGLName;
- LLColor4U coloru((U8)(name >> 16), (U8)(name >> 8), (U8)name);
- gGL.color4ubv(coloru.mV);
- gl_segmented_rect_3d_tex(border_scale_vec, scaled_border_width, scaled_border_height, width_vec, height_vec);
- LLUI::popMatrix();
- return;
- }
- else
- {
- gGL.getTexUnit(0)->bind(imagep->getImage());
-
- gGL.color4fv(bg_color.mV);
- gl_segmented_rect_3d_tex(border_scale_vec, scaled_border_width, scaled_border_height, width_vec, height_vec);
-
- if ( mLabelSegments.size())
- {
- LLUI::pushMatrix();
- {
- gGL.color4f(text_color.mV[VX], text_color.mV[VY], text_color.mV[VZ], gSavedSettings.getF32("ChatBubbleOpacity") * alpha_factor);
- LLVector3 label_height = (mFontp->getLineHeight() * mLabelSegments.size() + (VERTICAL_PADDING / 3.f)) * y_pixel_vec;
- LLVector3 label_offset = height_vec - label_height;
- LLUI::translate(label_offset.mV[VX], label_offset.mV[VY], label_offset.mV[VZ]);
- gl_segmented_rect_3d_tex_top(border_scale_vec, scaled_border_width, scaled_border_height, width_vec, label_height);
- }
- LLUI::popMatrix();
- }
- }
-
- BOOL outside_width = llabs(mPositionOffset.mV[VX]) > mWidth * 0.5f;
- BOOL outside_height = llabs(mPositionOffset.mV[VY] + (mVertAlignment == ALIGN_VERT_TOP ? mHeight * 0.5f : 0.f)) > mHeight * (mVertAlignment == ALIGN_VERT_TOP ? mHeight * 0.75f : 0.5f);
-
- // draw line segments pointing to parent object
- if (!mOffscreen && (outside_width || outside_height))
- {
- LLUI::pushMatrix();
- {
- gGL.color4fv(bg_color.mV);
- LLVector3 target_pos = -1.f * (mPositionOffset.mV[VX] * x_pixel_vec + mPositionOffset.mV[VY] * y_pixel_vec);
- target_pos += (width_vec / 2.f);
- target_pos += mVertAlignment == ALIGN_VERT_CENTER ? (height_vec * 0.5f) : LLVector3::zero;
- target_pos -= 3.f * x_pixel_vec;
- target_pos -= 6.f * y_pixel_vec;
- LLUI::translate(target_pos.mV[VX], target_pos.mV[VY], target_pos.mV[VZ]);
- gl_segmented_rect_3d_tex(border_scale_vec, 3.f * x_pixel_vec, 3.f * y_pixel_vec, 6.f * x_pixel_vec, 6.f * y_pixel_vec);
- }
- LLUI::popMatrix();
-
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- LLGLDepthTest gls_depth(mZCompare ? GL_TRUE : GL_FALSE, GL_FALSE);
-
- LLVector3 box_center_offset;
- box_center_offset = (width_vec * 0.5f) + (height_vec * 0.5f);
- LLUI::translate(box_center_offset.mV[VX], box_center_offset.mV[VY], box_center_offset.mV[VZ]);
- gGL.color4fv(bg_color.mV);
- LLUI::setLineWidth(2.0);
- gGL.begin(LLRender::LINES);
- {
- if (outside_width)
- {
- LLVector3 vert;
- // draw line in x then y
- if (mPositionOffset.mV[VX] < 0.f)
- {
- // start at right edge
- vert = width_vec * 0.5f;
- gGL.vertex3fv(vert.mV);
- }
- else
- {
- // start at left edge
- vert = width_vec * -0.5f;
- gGL.vertex3fv(vert.mV);
- }
- vert = -mPositionOffset.mV[VX] * x_pixel_vec;
- gGL.vertex3fv(vert.mV);
- gGL.vertex3fv(vert.mV);
- vert -= mPositionOffset.mV[VY] * y_pixel_vec;
- vert -= ((mVertAlignment == ALIGN_VERT_TOP) ? (height_vec * 0.5f) : LLVector3::zero);
- gGL.vertex3fv(vert.mV);
- }
- else
- {
- LLVector3 vert;
- // draw line in y then x
- if (mPositionOffset.mV[VY] < 0.f)
- {
- // start at top edge
- vert = (height_vec * 0.5f) - (mPositionOffset.mV[VX] * x_pixel_vec);
- gGL.vertex3fv(vert.mV);
- }
- else
- {
- // start at bottom edge
- vert = (height_vec * -0.5f) - (mPositionOffset.mV[VX] * x_pixel_vec);
- gGL.vertex3fv(vert.mV);
- }
- vert = -mPositionOffset.mV[VY] * y_pixel_vec - mPositionOffset.mV[VX] * x_pixel_vec;
- vert -= ((mVertAlignment == ALIGN_VERT_TOP) ? (height_vec * 0.5f) : LLVector3::zero);
- gGL.vertex3fv(vert.mV);
- }
- }
- gGL.end();
- LLUI::setLineWidth(1.0);
-
- }
- }
- LLUI::popMatrix();
+ rect_top_image->draw3D(render_position, x_pixel_vec, y_pixel_vec, label_top_rect, label_top_color);
}
F32 y_offset = (F32)mOffsetY;
@@ -874,29 +723,26 @@ void LLHUDNameTag::updateAll()
for (r_it = sVisibleTextObjects.rbegin(); r_it != sVisibleTextObjects.rend(); ++r_it)
{
LLHUDNameTag* textp = (*r_it);
-// if (textp->mUseBubble)
-// {
- if (current_screen_area / screen_area > LOD_2_SCREEN_COVERAGE)
- {
- textp->setLOD(3);
- }
- else if (current_screen_area / screen_area > LOD_1_SCREEN_COVERAGE)
- {
- textp->setLOD(2);
- }
- else if (current_screen_area / screen_area > LOD_0_SCREEN_COVERAGE)
- {
- textp->setLOD(1);
- }
- else
- {
- textp->setLOD(0);
- }
- textp->updateSize();
- // find on-screen position and initialize collision rectangle
- textp->mTargetPositionOffset = textp->updateScreenPos(LLVector2::zero);
- current_screen_area += (F32)(textp->mSoftScreenRect.getWidth() * textp->mSoftScreenRect.getHeight());
-// }
+ if (current_screen_area / screen_area > LOD_2_SCREEN_COVERAGE)
+ {
+ textp->setLOD(3);
+ }
+ else if (current_screen_area / screen_area > LOD_1_SCREEN_COVERAGE)
+ {
+ textp->setLOD(2);
+ }
+ else if (current_screen_area / screen_area > LOD_0_SCREEN_COVERAGE)
+ {
+ textp->setLOD(1);
+ }
+ else
+ {
+ textp->setLOD(0);
+ }
+ textp->updateSize();
+ // find on-screen position and initialize collision rectangle
+ textp->mTargetPositionOffset = textp->updateScreenPos(LLVector2::zero);
+ current_screen_area += (F32)(textp->mSoftScreenRect.getWidth() * textp->mSoftScreenRect.getHeight());
}
LLStat* camera_vel_stat = LLViewerCamera::getInstance()->getVelocityStat();
@@ -914,20 +760,12 @@ void LLHUDNameTag::updateAll()
{
LLHUDNameTag* src_textp = (*src_it);
-// if (!src_textp->mUseBubble)
-// {
-// continue;
-// }
VisibleTextObjectIterator dst_it = src_it;
++dst_it;
for (; dst_it != sVisibleTextObjects.end(); ++dst_it)
{
LLHUDNameTag* dst_textp = (*dst_it);
-// if (!dst_textp->mUseBubble)
-// {
-// continue;
-// }
if (src_textp->mSoftScreenRect.overlaps(dst_textp->mSoftScreenRect))
{
LLRectf intersect_rect = src_textp->mSoftScreenRect;
@@ -976,10 +814,6 @@ void LLHUDNameTag::updateAll()
VisibleTextObjectIterator this_object_it;
for (this_object_it = sVisibleTextObjects.begin(); this_object_it != sVisibleTextObjects.end(); ++this_object_it)
{
-// if (!(*this_object_it)->mUseBubble)
-// {
-// continue;
-// }
(*this_object_it)->mPositionOffset = lerp((*this_object_it)->mPositionOffset, (*this_object_it)->mTargetPositionOffset, LLCriticalDamp::getInterpolant(POSITION_DAMPING_TC));
}
}
@@ -1037,10 +871,6 @@ void LLHUDNameTag::addPickable(std::set<LLViewerObject*> &pick_list)
VisibleTextObjectIterator text_it;
for (text_it = sVisibleTextObjects.begin(); text_it != sVisibleTextObjects.end(); ++text_it)
{
-// if (!(*text_it)->mUseBubble)
-// {
-// continue;
-// }
pick_list.insert((*text_it)->mSourceObject);
}
}
diff --git a/indra/newview/llhudnametag.h b/indra/newview/llhudnametag.h
index 3325c22def..38a4f18415 100644..100755
--- a/indra/newview/llhudnametag.h
+++ b/indra/newview/llhudnametag.h
@@ -118,14 +118,13 @@ public:
/*virtual*/ void markDead();
friend class LLHUDObject;
/*virtual*/ F32 getDistance() const { return mLastDistance; }
- //void setUseBubble(BOOL use_bubble) { mUseBubble = use_bubble; }
S32 getLOD() { return mLOD; }
BOOL getVisible() { return mVisible; }
BOOL getHidden() const { return mHidden; }
void setHidden( BOOL hide ) { mHidden = hide; }
void shift(const LLVector3& offset);
- BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end, LLVector3& intersection, BOOL debug_render = FALSE);
+ BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, LLVector4a& intersection, BOOL debug_render = FALSE);
static void shiftAll(const LLVector3& offset);
static void addPickable(std::set<LLViewerObject*> &pick_list);
@@ -136,7 +135,6 @@ protected:
LLHUDNameTag(const U8 type);
/*virtual*/ void render();
- /*virtual*/ void renderForSelect();
void renderText(BOOL for_select);
static void updateAll();
void setLOD(S32 lod);
diff --git a/indra/newview/llhudobject.cpp b/indra/newview/llhudobject.cpp
index 95d57d08d8..95d57d08d8 100644..100755
--- a/indra/newview/llhudobject.cpp
+++ b/indra/newview/llhudobject.cpp
diff --git a/indra/newview/llhudobject.h b/indra/newview/llhudobject.h
index 2f7a98c86c..2f7a98c86c 100644..100755
--- a/indra/newview/llhudobject.h
+++ b/indra/newview/llhudobject.h
diff --git a/indra/newview/llhudrender.cpp b/indra/newview/llhudrender.cpp
index dff310ecf9..dff310ecf9 100644..100755
--- a/indra/newview/llhudrender.cpp
+++ b/indra/newview/llhudrender.cpp
diff --git a/indra/newview/llhudrender.h b/indra/newview/llhudrender.h
index b541cd5036..b541cd5036 100644..100755
--- a/indra/newview/llhudrender.h
+++ b/indra/newview/llhudrender.h
diff --git a/indra/newview/llhudtext.cpp b/indra/newview/llhudtext.cpp
index 579b6008ae..3c6bcd9829 100644..100755
--- a/indra/newview/llhudtext.cpp
+++ b/indra/newview/llhudtext.cpp
@@ -186,11 +186,8 @@ void LLHUDText::renderText()
LLViewerCamera::getInstance()->getPixelVectors(mPositionAgent, y_pixel_vec, x_pixel_vec);
}
- LLVector2 border_scale_vec((F32)border_width / (F32)imagep->getTextureWidth(), (F32)border_height / (F32)imagep->getTextureHeight());
LLVector3 width_vec = mWidth * x_pixel_vec;
LLVector3 height_vec = mHeight * y_pixel_vec;
- LLVector3 scaled_border_width = (F32)llfloor(border_scale * (F32)border_width) * x_pixel_vec;
- LLVector3 scaled_border_height = (F32)llfloor(border_scale * (F32)border_height) * y_pixel_vec;
mRadius = (width_vec + height_vec).magVec() * 0.5f;
@@ -440,7 +437,7 @@ LLVector2 LLHUDText::updateScreenPos(LLVector2 &offset)
LLVector3 x_pixel_vec;
LLVector3 y_pixel_vec;
LLViewerCamera::getInstance()->getPixelVectors(mPositionAgent, y_pixel_vec, x_pixel_vec);
- LLVector3 world_pos = mPositionAgent + (offset.mV[VX] * x_pixel_vec) + (offset.mV[VY] * y_pixel_vec);
+// LLVector3 world_pos = mPositionAgent + (offset.mV[VX] * x_pixel_vec) + (offset.mV[VY] * y_pixel_vec);
// if (!LLViewerCamera::getInstance()->projectPosAgentToScreen(world_pos, screen_pos, FALSE) && mVisibleOffScreen)
// {
// // bubble off-screen, so find a spot for it along screen edge
diff --git a/indra/newview/llhudtext.h b/indra/newview/llhudtext.h
index 36015d51f0..36015d51f0 100644..100755
--- a/indra/newview/llhudtext.h
+++ b/indra/newview/llhudtext.h
diff --git a/indra/newview/llhudview.cpp b/indra/newview/llhudview.cpp
index 9a63e99357..9a63e99357 100644..100755
--- a/indra/newview/llhudview.cpp
+++ b/indra/newview/llhudview.cpp
diff --git a/indra/newview/llhudview.h b/indra/newview/llhudview.h
index 6689554706..6689554706 100644..100755
--- a/indra/newview/llhudview.h
+++ b/indra/newview/llhudview.h
diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
deleted file mode 100644
index f67464078b..0000000000
--- a/indra/newview/llimfloater.cpp
+++ /dev/null
@@ -1,1193 +0,0 @@
-/**
- * @file llimfloater.cpp
- * @brief LLIMFloater class definition
- *
- * $LicenseInfo:firstyear=2009&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 "llviewerprecompiledheaders.h"
-
-#include "llimfloater.h"
-
-#include "llnotificationsutil.h"
-
-#include "llagent.h"
-#include "llappviewer.h"
-#include "llavatarnamecache.h"
-#include "llbutton.h"
-#include "llchannelmanager.h"
-#include "llchiclet.h"
-#include "llchicletbar.h"
-#include "llfloaterreg.h"
-#include "llimfloatercontainer.h" // to replace separate IM Floaters with multifloater container
-#include "llinventoryfunctions.h"
-#include "lllayoutstack.h"
-#include "lllineeditor.h"
-#include "lllogchat.h"
-#include "llpanelimcontrolpanel.h"
-#include "llscreenchannel.h"
-#include "llsyswellwindow.h"
-#include "lltrans.h"
-#include "llchathistory.h"
-#include "llnotifications.h"
-#include "llviewerwindow.h"
-#include "llvoicechannel.h"
-#include "lltransientfloatermgr.h"
-#include "llinventorymodel.h"
-#include "llrootview.h"
-#include "llspeakers.h"
-#include "llviewerchat.h"
-
-
-LLIMFloater::LLIMFloater(const LLUUID& session_id)
- : LLTransientDockableFloater(NULL, true, session_id),
- mControlPanel(NULL),
- mSessionID(session_id),
- mLastMessageIndex(-1),
- mDialog(IM_NOTHING_SPECIAL),
- mChatHistory(NULL),
- mInputEditor(NULL),
- mSavedTitle(),
- mTypingStart(),
- mShouldSendTypingState(false),
- mMeTyping(false),
- mOtherTyping(false),
- mTypingTimer(),
- mTypingTimeoutTimer(),
- mPositioned(false),
- mSessionInitialized(false)
-{
- LLIMModel::LLIMSession* im_session = LLIMModel::getInstance()->findIMSession(mSessionID);
- if (im_session)
- {
- mSessionInitialized = im_session->mSessionInitialized;
-
- mDialog = im_session->mType;
- switch(mDialog){
- case IM_NOTHING_SPECIAL:
- case IM_SESSION_P2P_INVITE:
- mFactoryMap["panel_im_control_panel"] = LLCallbackMap(createPanelIMControl, this);
- break;
- case IM_SESSION_CONFERENCE_START:
- mFactoryMap["panel_im_control_panel"] = LLCallbackMap(createPanelAdHocControl, this);
- break;
- case IM_SESSION_GROUP_START:
- mFactoryMap["panel_im_control_panel"] = LLCallbackMap(createPanelGroupControl, this);
- break;
- case IM_SESSION_INVITE:
- if (gAgent.isInGroup(mSessionID))
- {
- mFactoryMap["panel_im_control_panel"] = LLCallbackMap(createPanelGroupControl, this);
- }
- else
- {
- mFactoryMap["panel_im_control_panel"] = LLCallbackMap(createPanelAdHocControl, this);
- }
- break;
- default: break;
- }
- }
- setOverlapsScreenChannel(true);
-
- LLTransientFloaterMgr::getInstance()->addControlView(LLTransientFloaterMgr::IM, this);
-
- setDocked(true);
-}
-
-void LLIMFloater::onFocusLost()
-{
- LLIMModel::getInstance()->resetActiveSessionID();
-
- LLChicletBar::getInstance()->getChicletPanel()->setChicletToggleState(mSessionID, false);
-}
-
-void LLIMFloater::onFocusReceived()
-{
- LLIMModel::getInstance()->setActiveSessionID(mSessionID);
-
- LLChicletBar::getInstance()->getChicletPanel()->setChicletToggleState(mSessionID, true);
-
- if (getVisible())
- {
- LLIMModel::instance().sendNoUnreadMessages(mSessionID);
- }
-}
-
-// virtual
-void LLIMFloater::onClose(bool app_quitting)
-{
- setTyping(false);
-
- // The source of much argument and design thrashing
- // Should the window hide or the session close when the X is clicked?
- //
- // Last change:
- // EXT-3516 X Button should end IM session, _ button should hide
- gIMMgr->leaveSession(mSessionID);
-}
-
-/* static */
-void LLIMFloater::newIMCallback(const LLSD& data){
-
- if (data["num_unread"].asInteger() > 0 || data["from_id"].asUUID().isNull())
- {
- LLUUID session_id = data["session_id"].asUUID();
-
- LLIMFloater* floater = LLFloaterReg::findTypedInstance<LLIMFloater>("impanel", session_id);
- if (floater == NULL) return;
-
- // update if visible, otherwise will be updated when opened
- if (floater->getVisible())
- {
- floater->updateMessages();
- }
- }
-}
-
-void LLIMFloater::onVisibilityChange(const LLSD& new_visibility)
-{
- bool visible = new_visibility.asBoolean();
-
- LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionID);
-
- if (visible && voice_channel &&
- voice_channel->getState() == LLVoiceChannel::STATE_CONNECTED)
- {
- LLFloaterReg::showInstance("voice_call", mSessionID);
- }
- else
- {
- LLFloaterReg::hideInstance("voice_call", mSessionID);
- }
-}
-
-void LLIMFloater::onSendMsg( LLUICtrl* ctrl, void* userdata )
-{
- LLIMFloater* self = (LLIMFloater*) userdata;
- self->sendMsg();
- self->setTyping(false);
-}
-
-void LLIMFloater::sendMsg()
-{
- if (!gAgent.isGodlike()
- && (mDialog == IM_NOTHING_SPECIAL)
- && mOtherParticipantUUID.isNull())
- {
- llinfos << "Cannot send IM to everyone unless you're a god." << llendl;
- return;
- }
-
- if (mInputEditor)
- {
- LLWString text = mInputEditor->getConvertedText();
- if(!text.empty())
- {
- // Truncate and convert to UTF8 for transport
- std::string utf8_text = wstring_to_utf8str(text);
- utf8_text = utf8str_truncate(utf8_text, MAX_MSG_BUF_SIZE - 1);
-
- if (mSessionInitialized)
- {
- LLIMModel::sendMessage(utf8_text, mSessionID,
- mOtherParticipantUUID,mDialog);
- }
- else
- {
- //queue up the message to send once the session is initialized
- mQueuedMsgsForInit.append(utf8_text);
- }
-
- mInputEditor->setText(LLStringUtil::null);
-
- updateMessages();
- }
- }
-}
-
-
-
-LLIMFloater::~LLIMFloater()
-{
- LLTransientFloaterMgr::getInstance()->removeControlView(LLTransientFloaterMgr::IM, this);
-}
-
-//virtual
-BOOL LLIMFloater::postBuild()
-{
- const LLUUID& other_party_id = LLIMModel::getInstance()->getOtherParticipantID(mSessionID);
- if (other_party_id.notNull())
- {
- mOtherParticipantUUID = other_party_id;
- }
-
- mControlPanel->setSessionId(mSessionID);
- mControlPanel->getParent()->setVisible(gSavedSettings.getBOOL("IMShowControlPanel"));
-
- LLButton* slide_left = getChild<LLButton>("slide_left_btn");
- slide_left->setVisible(mControlPanel->getParent()->getVisible());
- slide_left->setClickedCallback(boost::bind(&LLIMFloater::onSlide, this));
-
- LLButton* slide_right = getChild<LLButton>("slide_right_btn");
- slide_right->setVisible(!mControlPanel->getParent()->getVisible());
- slide_right->setClickedCallback(boost::bind(&LLIMFloater::onSlide, this));
-
- mInputEditor = getChild<LLLineEditor>("chat_editor");
- mInputEditor->setMaxTextLength(1023);
- // enable line history support for instant message bar
- mInputEditor->setEnableLineHistory(TRUE);
-
- LLFontGL* font = LLViewerChat::getChatFont();
- mInputEditor->setFont(font);
-
- mInputEditor->setFocusReceivedCallback( boost::bind(onInputEditorFocusReceived, _1, this) );
- mInputEditor->setFocusLostCallback( boost::bind(onInputEditorFocusLost, _1, this) );
- mInputEditor->setKeystrokeCallback( onInputEditorKeystroke, this );
- mInputEditor->setCommitOnFocusLost( FALSE );
- mInputEditor->setRevertOnEsc( FALSE );
- mInputEditor->setReplaceNewlinesWithSpaces( FALSE );
- mInputEditor->setPassDelete( TRUE );
-
- childSetCommitCallback("chat_editor", onSendMsg, this);
-
- mChatHistory = getChild<LLChatHistory>("chat_history");
-
- setDocked(true);
-
- mTypingStart = LLTrans::getString("IM_typing_start_string");
-
- // Disable input editor if session cannot accept text
- LLIMModel::LLIMSession* im_session =
- LLIMModel::instance().findIMSession(mSessionID);
- if( im_session && !im_session->mTextIMPossible )
- {
- mInputEditor->setEnabled(FALSE);
- mInputEditor->setLabel(LLTrans::getString("IM_unavailable_text_label"));
- }
-
- if ( im_session && im_session->isP2PSessionType())
- {
- // look up display name for window title
- LLAvatarNameCache::get(im_session->mOtherParticipantID,
- boost::bind(&LLIMFloater::onAvatarNameCache,
- this, _1, _2));
- }
- else
- {
- std::string session_name(LLIMModel::instance().getName(mSessionID));
- updateSessionName(session_name, session_name);
- }
-
- //*TODO if session is not initialized yet, add some sort of a warning message like "starting session...blablabla"
- //see LLFloaterIMPanel for how it is done (IB)
-
- if(isChatMultiTab())
- {
- return LLFloater::postBuild();
- }
- else
- {
- return LLDockableFloater::postBuild();
- }
-}
-
-void LLIMFloater::updateSessionName(const std::string& ui_title,
- const std::string& ui_label)
-{
- mInputEditor->setLabel(LLTrans::getString("IM_to_label") + " " + ui_label);
- setTitle(ui_title);
-}
-
-void LLIMFloater::onAvatarNameCache(const LLUUID& agent_id,
- const LLAvatarName& av_name)
-{
- // Use display name only for labels, as the extended name will be in the
- // floater title
- std::string ui_title = av_name.getCompleteName();
- updateSessionName(ui_title, av_name.mDisplayName);
- mTypingStart.setArg("[NAME]", ui_title);
-}
-
-// virtual
-void LLIMFloater::draw()
-{
- if ( mMeTyping )
- {
- // Time out if user hasn't typed for a while.
- if ( mTypingTimeoutTimer.getElapsedTimeF32() > LLAgent::TYPING_TIMEOUT_SECS )
- {
- setTyping(false);
- }
- }
-
- LLTransientDockableFloater::draw();
-}
-
-
-// static
-void* LLIMFloater::createPanelIMControl(void* userdata)
-{
- LLIMFloater *self = (LLIMFloater*)userdata;
- self->mControlPanel = new LLPanelIMControlPanel();
- self->mControlPanel->setXMLFilename("panel_im_control_panel.xml");
- return self->mControlPanel;
-}
-
-
-// static
-void* LLIMFloater::createPanelGroupControl(void* userdata)
-{
- LLIMFloater *self = (LLIMFloater*)userdata;
- self->mControlPanel = new LLPanelGroupControlPanel(self->mSessionID);
- self->mControlPanel->setXMLFilename("panel_group_control_panel.xml");
- return self->mControlPanel;
-}
-
-// static
-void* LLIMFloater::createPanelAdHocControl(void* userdata)
-{
- LLIMFloater *self = (LLIMFloater*)userdata;
- self->mControlPanel = new LLPanelAdHocControlPanel(self->mSessionID);
- self->mControlPanel->setXMLFilename("panel_adhoc_control_panel.xml");
- return self->mControlPanel;
-}
-
-void LLIMFloater::onSlide()
-{
- mControlPanel->getParent()->setVisible(!mControlPanel->getParent()->getVisible());
-
- gSavedSettings.setBOOL("IMShowControlPanel", mControlPanel->getParent()->getVisible());
-
- getChild<LLButton>("slide_left_btn")->setVisible(mControlPanel->getParent()->getVisible());
- getChild<LLButton>("slide_right_btn")->setVisible(!mControlPanel->getParent()->getVisible());
-}
-
-//static
-LLIMFloater* LLIMFloater::show(const LLUUID& session_id)
-{
- closeHiddenIMToasts();
-
- if (!gIMMgr->hasSession(session_id)) return NULL;
-
- if(!isChatMultiTab())
- {
- //hide all
- LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("impanel");
- for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin();
- iter != inst_list.end(); ++iter)
- {
- LLIMFloater* floater = dynamic_cast<LLIMFloater*>(*iter);
- if (floater && floater->isDocked())
- {
- floater->setVisible(false);
- }
- }
- }
-
- bool exist = findInstance(session_id);
-
- LLIMFloater* floater = getInstance(session_id);
- if (!floater) return NULL;
-
- if(isChatMultiTab())
- {
- LLIMFloaterContainer* floater_container = LLIMFloaterContainer::getInstance();
-
- // do not add existed floaters to avoid adding torn off instances
- if (!exist)
- {
- // LLTabContainer::eInsertionPoint i_pt = user_initiated ? LLTabContainer::RIGHT_OF_CURRENT : LLTabContainer::END;
- // TODO: mantipov: use LLTabContainer::RIGHT_OF_CURRENT if it exists
- LLTabContainer::eInsertionPoint i_pt = LLTabContainer::END;
-
- if (floater_container)
- {
- floater_container->addFloater(floater, TRUE, i_pt);
- }
- }
-
- floater->openFloater(floater->getKey());
- }
- else
- {
- // Docking may move chat window, hide it before moving, or user will see how window "jumps"
- floater->setVisible(false);
-
- if (floater->getDockControl() == NULL)
- {
- LLChiclet* chiclet =
- LLChicletBar::getInstance()->getChicletPanel()->findChiclet<LLChiclet>(
- session_id);
- if (chiclet == NULL)
- {
- llerror("Dock chiclet for LLIMFloater doesn't exists", 0);
- }
- else
- {
- LLChicletBar::getInstance()->getChicletPanel()->scrollToChiclet(chiclet);
- }
-
- floater->setDockControl(new LLDockControl(chiclet, floater, floater->getDockTongue(),
- LLDockControl::BOTTOM));
- }
-
- // window is positioned, now we can show it.
- }
- floater->setVisible(TRUE);
-
- return floater;
-}
-
-void LLIMFloater::setDocked(bool docked, bool pop_on_undock)
-{
- // update notification channel state
- LLNotificationsUI::LLScreenChannel* channel = static_cast<LLNotificationsUI::LLScreenChannel*>
- (LLNotificationsUI::LLChannelManager::getInstance()->
- findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID"))));
-
- if(!isChatMultiTab())
- {
- LLTransientDockableFloater::setDocked(docked, pop_on_undock);
- }
-
- // update notification channel state
- if(channel)
- {
- channel->updateShowToastsState();
- channel->redrawToasts();
- }
-}
-
-void LLIMFloater::setVisible(BOOL visible)
-{
- LLNotificationsUI::LLScreenChannel* channel = static_cast<LLNotificationsUI::LLScreenChannel*>
- (LLNotificationsUI::LLChannelManager::getInstance()->
- findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID"))));
- LLTransientDockableFloater::setVisible(visible);
-
- // update notification channel state
- if(channel)
- {
- channel->updateShowToastsState();
- channel->redrawToasts();
- }
-
- BOOL is_minimized = visible && isChatMultiTab()
- ? LLIMFloaterContainer::getInstance()->isMinimized()
- : !visible;
-
- if (!is_minimized && mChatHistory && mInputEditor)
- {
- //only if floater was construced and initialized from xml
- updateMessages();
- //prevent stealing focus when opening a background IM tab (EXT-5387, checking focus for EXT-6781)
- if (!isChatMultiTab() || hasFocus())
- {
- mInputEditor->setFocus(TRUE);
- }
- }
-
- if(!visible)
- {
- LLIMChiclet* chiclet = LLChicletBar::getInstance()->getChicletPanel()->findChiclet<LLIMChiclet>(mSessionID);
- if(chiclet)
- {
- chiclet->setToggleState(false);
- }
- }
-}
-
-BOOL LLIMFloater::getVisible()
-{
- if(isChatMultiTab())
- {
- LLIMFloaterContainer* im_container = LLIMFloaterContainer::getInstance();
-
- // Treat inactive floater as invisible.
- bool is_active = im_container->getActiveFloater() == this;
-
- //torn off floater is always inactive
- if (!is_active && getHost() != im_container)
- {
- return LLTransientDockableFloater::getVisible();
- }
-
- // getVisible() returns TRUE when Tabbed IM window is minimized.
- return is_active && !im_container->isMinimized() && im_container->getVisible();
- }
- else
- {
- return LLTransientDockableFloater::getVisible();
- }
-}
-
-//static
-bool LLIMFloater::toggle(const LLUUID& session_id)
-{
- if(!isChatMultiTab())
- {
- LLIMFloater* floater = LLFloaterReg::findTypedInstance<LLIMFloater>("impanel", session_id);
- if (floater && floater->getVisible() && floater->hasFocus())
- {
- // clicking on chiclet to close floater just hides it to maintain existing
- // scroll/text entry state
- floater->setVisible(false);
- return false;
- }
- else if(floater && (!floater->isDocked() || floater->getVisible() && !floater->hasFocus()))
- {
- floater->setVisible(TRUE);
- floater->setFocus(TRUE);
- return true;
- }
- }
-
- // ensure the list of messages is updated when floater is made visible
- show(session_id);
- return true;
-}
-
-//static
-LLIMFloater* LLIMFloater::findInstance(const LLUUID& session_id)
-{
- return LLFloaterReg::findTypedInstance<LLIMFloater>("impanel", session_id);
-}
-
-LLIMFloater* LLIMFloater::getInstance(const LLUUID& session_id)
-{
- return LLFloaterReg::getTypedInstance<LLIMFloater>("impanel", session_id);
-}
-
-void LLIMFloater::sessionInitReplyReceived(const LLUUID& im_session_id)
-{
- mSessionInitialized = true;
-
- //will be different only for an ad-hoc im session
- if (mSessionID != im_session_id)
- {
- mSessionID = im_session_id;
- setKey(im_session_id);
- mControlPanel->setSessionId(im_session_id);
- }
-
- // updating "Call" button from group control panel here to enable it without placing into draw() (EXT-4796)
- if(gAgent.isInGroup(im_session_id))
- {
- mControlPanel->updateCallButton();
- }
-
- //*TODO here we should remove "starting session..." warning message if we added it in postBuild() (IB)
-
-
- //need to send delayed messaged collected while waiting for session initialization
- if (!mQueuedMsgsForInit.size()) return;
- LLSD::array_iterator iter;
- for ( iter = mQueuedMsgsForInit.beginArray();
- iter != mQueuedMsgsForInit.endArray();
- ++iter)
- {
- LLIMModel::sendMessage(iter->asString(), mSessionID,
- mOtherParticipantUUID, mDialog);
- }
-}
-
-void LLIMFloater::updateMessages()
-{
- bool use_plain_text_chat_history = gSavedSettings.getBOOL("PlainTextChatHistory");
-
- std::list<LLSD> messages;
-
- // we shouldn't reset unread message counters if IM floater doesn't have focus
- if (hasFocus())
- {
- LLIMModel::instance().getMessages(mSessionID, messages, mLastMessageIndex+1);
- }
- else
- {
- LLIMModel::instance().getMessagesSilently(mSessionID, messages, mLastMessageIndex+1);
- }
-
- if (messages.size())
- {
- LLSD chat_args;
- chat_args["use_plain_text_chat_history"] = use_plain_text_chat_history;
-
- std::ostringstream message;
- std::list<LLSD>::const_reverse_iterator iter = messages.rbegin();
- std::list<LLSD>::const_reverse_iterator iter_end = messages.rend();
- for (; iter != iter_end; ++iter)
- {
- LLSD msg = *iter;
-
- std::string time = msg["time"].asString();
- LLUUID from_id = msg["from_id"].asUUID();
- std::string from = msg["from"].asString();
- std::string message = msg["message"].asString();
- bool is_history = msg["is_history"].asBoolean();
-
- LLChat chat;
- chat.mFromID = from_id;
- chat.mSessionID = mSessionID;
- chat.mFromName = from;
- chat.mTimeStr = time;
- chat.mChatStyle = is_history ? CHAT_STYLE_HISTORY : chat.mChatStyle;
-
- // process offer notification
- if (msg.has("notification_id"))
- {
- chat.mNotifId = msg["notification_id"].asUUID();
- // if notification exists - embed it
- if (LLNotificationsUtil::find(chat.mNotifId) != NULL)
- {
- // remove embedded notification from channel
- LLNotificationsUI::LLScreenChannel* channel = static_cast<LLNotificationsUI::LLScreenChannel*>
- (LLNotificationsUI::LLChannelManager::getInstance()->
- findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID"))));
- if (getVisible())
- {
- // toast will be automatically closed since it is not storable toast
- channel->hideToast(chat.mNotifId);
- }
- }
- // if notification doesn't exist - try to use next message which should be log entry
- else
- {
- continue;
- }
- }
- //process text message
- else
- {
- chat.mText = message;
- }
-
- mChatHistory->appendMessage(chat, chat_args);
- mLastMessageIndex = msg["index"].asInteger();
-
- // if it is a notification - next message is a notification history log, so skip it
- if (chat.mNotifId.notNull() && LLNotificationsUtil::find(chat.mNotifId) != NULL)
- {
- if (++iter == iter_end)
- {
- break;
- }
- else
- {
- mLastMessageIndex++;
- }
- }
- }
- }
-}
-
-void LLIMFloater::reloadMessages()
-{
- mChatHistory->clear();
- mLastMessageIndex = -1;
- updateMessages();
-}
-
-// static
-void LLIMFloater::onInputEditorFocusReceived( LLFocusableElement* caller, void* userdata )
-{
- LLIMFloater* self= (LLIMFloater*) userdata;
-
- // Allow enabling the LLIMFloater input editor only if session can accept text
- LLIMModel::LLIMSession* im_session =
- LLIMModel::instance().findIMSession(self->mSessionID);
- //TODO: While disabled lllineeditor can receive focus we need to check if it is enabled (EK)
- if( im_session && im_session->mTextIMPossible && self->mInputEditor->getEnabled())
- {
- //in disconnected state IM input editor should be disabled
- self->mInputEditor->setEnabled(!gDisconnected);
- }
-}
-
-// static
-void LLIMFloater::onInputEditorFocusLost(LLFocusableElement* caller, void* userdata)
-{
- LLIMFloater* self = (LLIMFloater*) userdata;
- self->setTyping(false);
-}
-
-// static
-void LLIMFloater::onInputEditorKeystroke(LLLineEditor* caller, void* userdata)
-{
- LLIMFloater* self = (LLIMFloater*)userdata;
- std::string text = self->mInputEditor->getText();
- if (!text.empty())
- {
- self->setTyping(true);
- }
- else
- {
- // Deleting all text counts as stopping typing.
- self->setTyping(false);
- }
-}
-
-void LLIMFloater::setTyping(bool typing)
-{
- if ( typing )
- {
- // Started or proceeded typing, reset the typing timeout timer
- mTypingTimeoutTimer.reset();
- }
-
- if ( mMeTyping != typing )
- {
- // Typing state is changed
- mMeTyping = typing;
- // So, should send current state
- mShouldSendTypingState = true;
- // In case typing is started, send state after some delay
- mTypingTimer.reset();
- }
-
- // Don't want to send typing indicators to multiple people, potentially too
- // much network traffic. Only send in person-to-person IMs.
- if ( mShouldSendTypingState && mDialog == IM_NOTHING_SPECIAL )
- {
- if ( mMeTyping )
- {
- if ( mTypingTimer.getElapsedTimeF32() > 1.f )
- {
- // Still typing, send 'start typing' notification
- LLIMModel::instance().sendTypingState(mSessionID, mOtherParticipantUUID, TRUE);
- mShouldSendTypingState = false;
- }
- }
- else
- {
- // Send 'stop typing' notification immediately
- LLIMModel::instance().sendTypingState(mSessionID, mOtherParticipantUUID, FALSE);
- mShouldSendTypingState = false;
- }
- }
-
- LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID);
- if (speaker_mgr)
- speaker_mgr->setSpeakerTyping(gAgent.getID(), FALSE);
-
-}
-
-void LLIMFloater::processIMTyping(const LLIMInfo* im_info, BOOL typing)
-{
- if ( typing )
- {
- // other user started typing
- addTypingIndicator(im_info);
- }
- else
- {
- // other user stopped typing
- removeTypingIndicator(im_info);
- }
-}
-
-void LLIMFloater::processAgentListUpdates(const LLSD& body)
-{
- if ( !body.isMap() ) return;
-
- if ( body.has("agent_updates") && body["agent_updates"].isMap() )
- {
- LLSD agent_data = body["agent_updates"].get(gAgentID.asString());
- if (agent_data.isMap() && agent_data.has("info"))
- {
- LLSD agent_info = agent_data["info"];
-
- if (agent_info.has("mutes"))
- {
- BOOL moderator_muted_text = agent_info["mutes"]["text"].asBoolean();
- mInputEditor->setEnabled(!moderator_muted_text);
- std::string label;
- if (moderator_muted_text)
- label = LLTrans::getString("IM_muted_text_label");
- else
- label = LLTrans::getString("IM_to_label") + " " + LLIMModel::instance().getName(mSessionID);
- mInputEditor->setLabel(label);
-
- if (moderator_muted_text)
- LLNotificationsUtil::add("TextChatIsMutedByModerator");
- }
- }
- }
-}
-
-void LLIMFloater::updateChatHistoryStyle()
-{
- mChatHistory->clear();
- mLastMessageIndex = -1;
- updateMessages();
-}
-
-void LLIMFloater::processChatHistoryStyleUpdate(const LLSD& newvalue)
-{
- LLFontGL* font = LLViewerChat::getChatFont();
- LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("impanel");
- for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin();
- iter != inst_list.end(); ++iter)
- {
- LLIMFloater* floater = dynamic_cast<LLIMFloater*>(*iter);
- if (floater)
- {
- floater->updateChatHistoryStyle();
- floater->mInputEditor->setFont(font);
- }
- }
-
-}
-
-void LLIMFloater::processSessionUpdate(const LLSD& session_update)
-{
- // *TODO : verify following code when moderated mode will be implemented
- if ( false && session_update.has("moderated_mode") &&
- session_update["moderated_mode"].has("voice") )
- {
- BOOL voice_moderated = session_update["moderated_mode"]["voice"];
- const std::string session_label = LLIMModel::instance().getName(mSessionID);
-
- if (voice_moderated)
- {
- setTitle(session_label + std::string(" ") + LLTrans::getString("IM_moderated_chat_label"));
- }
- else
- {
- setTitle(session_label);
- }
-
- // *TODO : uncomment this when/if LLPanelActiveSpeakers panel will be added
- //update the speakers dropdown too
- //mSpeakerPanel->setVoiceModerationCtrlMode(voice_moderated);
- }
-}
-
-BOOL LLIMFloater::handleDragAndDrop(S32 x, S32 y, MASK mask,
- BOOL drop, EDragAndDropType cargo_type,
- void *cargo_data, EAcceptance *accept,
- std::string& tooltip_msg)
-{
-
- if (mDialog == IM_NOTHING_SPECIAL)
- {
- LLToolDragAndDrop::handleGiveDragAndDrop(mOtherParticipantUUID, mSessionID, drop,
- cargo_type, cargo_data, accept);
- }
-
- // handle case for dropping calling cards (and folders of calling cards) onto invitation panel for invites
- else if (isInviteAllowed())
- {
- *accept = ACCEPT_NO;
-
- if (cargo_type == DAD_CALLINGCARD)
- {
- if (dropCallingCard((LLInventoryItem*)cargo_data, drop))
- {
- *accept = ACCEPT_YES_MULTI;
- }
- }
- else if (cargo_type == DAD_CATEGORY)
- {
- if (dropCategory((LLInventoryCategory*)cargo_data, drop))
- {
- *accept = ACCEPT_YES_MULTI;
- }
- }
- }
- return TRUE;
-}
-
-BOOL LLIMFloater::dropCallingCard(LLInventoryItem* item, BOOL drop)
-{
- BOOL rv = isInviteAllowed();
- if(rv && item && item->getCreatorUUID().notNull())
- {
- if(drop)
- {
- uuid_vec_t ids;
- ids.push_back(item->getCreatorUUID());
- inviteToSession(ids);
- }
- }
- else
- {
- // set to false if creator uuid is null.
- rv = FALSE;
- }
- return rv;
-}
-
-BOOL LLIMFloater::dropCategory(LLInventoryCategory* category, BOOL drop)
-{
- BOOL rv = isInviteAllowed();
- if(rv && category)
- {
- LLInventoryModel::cat_array_t cats;
- LLInventoryModel::item_array_t items;
- LLUniqueBuddyCollector buddies;
- gInventory.collectDescendentsIf(category->getUUID(),
- cats,
- items,
- LLInventoryModel::EXCLUDE_TRASH,
- buddies);
- S32 count = items.count();
- if(count == 0)
- {
- rv = FALSE;
- }
- else if(drop)
- {
- uuid_vec_t ids;
- ids.reserve(count);
- for(S32 i = 0; i < count; ++i)
- {
- ids.push_back(items.get(i)->getCreatorUUID());
- }
- inviteToSession(ids);
- }
- }
- return rv;
-}
-
-BOOL LLIMFloater::isInviteAllowed() const
-{
-
- return ( (IM_SESSION_CONFERENCE_START == mDialog)
- || (IM_SESSION_INVITE == mDialog) );
-}
-
-class LLSessionInviteResponder : public LLHTTPClient::Responder
-{
-public:
- LLSessionInviteResponder(const LLUUID& session_id)
- {
- mSessionID = session_id;
- }
-
- void error(U32 statusNum, const std::string& reason)
- {
- llinfos << "Error inviting all agents to session" << llendl;
- //throw something back to the viewer here?
- }
-
-private:
- LLUUID mSessionID;
-};
-
-BOOL LLIMFloater::inviteToSession(const uuid_vec_t& ids)
-{
- LLViewerRegion* region = gAgent.getRegion();
- if (!region)
- {
- return FALSE;
- }
-
- S32 count = ids.size();
-
- if( isInviteAllowed() && (count > 0) )
- {
- llinfos << "LLIMFloater::inviteToSession() - inviting participants" << llendl;
-
- std::string url = region->getCapability("ChatSessionRequest");
-
- LLSD data;
-
- data["params"] = LLSD::emptyArray();
- for (int i = 0; i < count; i++)
- {
- data["params"].append(ids[i]);
- }
-
- data["method"] = "invite";
- data["session-id"] = mSessionID;
- LLHTTPClient::post(
- url,
- data,
- new LLSessionInviteResponder(
- mSessionID));
- }
- else
- {
- llinfos << "LLIMFloater::inviteToSession -"
- << " no need to invite agents for "
- << mDialog << llendl;
- // successful add, because everyone that needed to get added
- // was added.
- }
-
- return TRUE;
-}
-
-void LLIMFloater::addTypingIndicator(const LLIMInfo* im_info)
-{
- // We may have lost a "stop-typing" packet, don't add it twice
- if ( im_info && !mOtherTyping )
- {
- mOtherTyping = true;
-
- // Save and set new title
- mSavedTitle = getTitle();
- setTitle (mTypingStart);
-
- // Update speaker
- LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID);
- if ( speaker_mgr )
- {
- speaker_mgr->setSpeakerTyping(im_info->mFromID, TRUE);
- }
- }
-}
-
-void LLIMFloater::removeTypingIndicator(const LLIMInfo* im_info)
-{
- if ( mOtherTyping )
- {
- mOtherTyping = false;
-
- // Revert the title to saved one
- setTitle(mSavedTitle);
-
- if ( im_info )
- {
- // Update speaker
- LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID);
- if ( speaker_mgr )
- {
- speaker_mgr->setSpeakerTyping(im_info->mFromID, FALSE);
- }
- }
-
- }
-}
-
-// static
-void LLIMFloater::closeHiddenIMToasts()
-{
- class IMToastMatcher: public LLNotificationsUI::LLScreenChannel::Matcher
- {
- public:
- bool matches(const LLNotificationPtr notification) const
- {
- // "notifytoast" type of notifications is reserved for IM notifications
- return "notifytoast" == notification->getType();
- }
- };
-
- LLNotificationsUI::LLScreenChannel* channel = LLNotificationsUI::LLChannelManager::getNotificationScreenChannel();
- if (channel != NULL)
- {
- channel->closeHiddenToasts(IMToastMatcher());
- }
-}
-// static
-void LLIMFloater::confirmLeaveCallCallback(const LLSD& notification, const LLSD& response)
-{
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
- const LLSD& payload = notification["payload"];
- LLUUID session_id = payload["session_id"];
-
- LLFloater* im_floater = LLFloaterReg::findInstance("impanel", session_id);
- if (option == 0 && im_floater != NULL)
- {
- im_floater->closeFloater();
- }
-
- return;
-}
-
-// static
-bool LLIMFloater::isChatMultiTab()
-{
- // Restart is required in order to change chat window type.
- static bool is_single_window = gSavedSettings.getS32("ChatWindow") == 1;
- return is_single_window;
-}
-
-// static
-void LLIMFloater::initIMFloater()
-{
- // This is called on viewer start up
- // init chat window type before user changed it in preferences
- isChatMultiTab();
-}
-
-//static
-void LLIMFloater::sRemoveTypingIndicator(const LLSD& data)
-{
- LLUUID session_id = data["session_id"];
- if (session_id.isNull()) return;
-
- LLUUID from_id = data["from_id"];
- if (gAgentID == from_id || LLUUID::null == from_id) return;
-
- LLIMFloater* floater = LLIMFloater::findInstance(session_id);
- if (!floater) return;
-
- if (IM_NOTHING_SPECIAL != floater->mDialog) return;
-
- floater->removeTypingIndicator();
-}
-
-void LLIMFloater::onIMChicletCreated( const LLUUID& session_id )
-{
-
- if (isChatMultiTab())
- {
- LLIMFloaterContainer* im_box = LLIMFloaterContainer::getInstance();
- if (!im_box) return;
-
- if (LLIMFloater::findInstance(session_id)) return;
-
- LLIMFloater* new_tab = LLIMFloater::getInstance(session_id);
-
- im_box->addFloater(new_tab, FALSE, LLTabContainer::END);
- }
-
-}
-
-void LLIMFloater::onClickCloseBtn()
-{
-
- LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(
- mSessionID);
-
- if (session == NULL)
- {
- llwarns << "Empty session." << llendl;
- return;
- }
-
- bool is_call_with_chat = session->isGroupSessionType()
- || session->isAdHocSessionType() || session->isP2PSessionType();
-
- LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionID);
-
- if (is_call_with_chat && voice_channel != NULL && voice_channel->isActive())
- {
- LLSD payload;
- payload["session_id"] = mSessionID;
- LLNotificationsUtil::add("ConfirmLeaveCall", LLSD(), payload, confirmLeaveCallCallback);
- return;
- }
-
- LLFloater::onClickCloseBtn();
-}
diff --git a/indra/newview/llimfloater.h b/indra/newview/llimfloater.h
deleted file mode 100644
index f7cd35b5eb..0000000000
--- a/indra/newview/llimfloater.h
+++ /dev/null
@@ -1,182 +0,0 @@
-/**
- * @file llimfloater.h
- * @brief LLIMFloater class definition
- *
- * $LicenseInfo:firstyear=2009&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$
- */
-
-#ifndef LL_IMFLOATER_H
-#define LL_IMFLOATER_H
-
-#include "llinstantmessage.h"
-#include "lllogchat.h"
-#include "lltooldraganddrop.h"
-#include "lltransientdockablefloater.h"
-
-class LLAvatarName;
-class LLLineEditor;
-class LLPanelChatControlPanel;
-class LLChatHistory;
-class LLInventoryItem;
-class LLInventoryCategory;
-
-/**
- * Individual IM window that appears at the bottom of the screen,
- * optionally "docked" to the bottom tray.
- */
-class LLIMFloater : public LLTransientDockableFloater
-{
- LOG_CLASS(LLIMFloater);
-public:
- LLIMFloater(const LLUUID& session_id);
-
- virtual ~LLIMFloater();
-
- // LLView overrides
- /*virtual*/ BOOL postBuild();
- /*virtual*/ void setVisible(BOOL visible);
- /*virtual*/ BOOL getVisible();
- // Check typing timeout timer.
- /*virtual*/ void draw();
-
- // LLFloater overrides
- /*virtual*/ void onClose(bool app_quitting);
- /*virtual*/ void setDocked(bool docked, bool pop_on_undock = true);
-
- // Make IM conversion visible and update the message history
- static LLIMFloater* show(const LLUUID& session_id);
-
- // Toggle panel specified by session_id
- // Returns true iff panel became visible
- static bool toggle(const LLUUID& session_id);
-
- static LLIMFloater* findInstance(const LLUUID& session_id);
-
- static LLIMFloater* getInstance(const LLUUID& session_id);
-
- void sessionInitReplyReceived(const LLUUID& im_session_id);
-
- // get new messages from LLIMModel
- void updateMessages();
- void reloadMessages();
- static void onSendMsg( LLUICtrl*, void*);
- void sendMsg();
-
- // callback for LLIMModel on new messages
- // route to specific floater if it is visible
- static void newIMCallback(const LLSD& data);
-
- // called when docked floater's position has been set by chiclet
- void setPositioned(bool b) { mPositioned = b; };
-
- void onVisibilityChange(const LLSD& new_visibility);
- void processIMTyping(const LLIMInfo* im_info, BOOL typing);
- void processAgentListUpdates(const LLSD& body);
- void processSessionUpdate(const LLSD& session_update);
-
- void updateChatHistoryStyle();
- static void processChatHistoryStyleUpdate(const LLSD& newvalue);
-
- BOOL handleDragAndDrop(S32 x, S32 y, MASK mask,
- BOOL drop, EDragAndDropType cargo_type,
- void *cargo_data, EAcceptance *accept,
- std::string& tooltip_msg);
-
- /**
- * Returns true if chat is displayed in multi tabbed floater
- * false if chat is displayed in multiple windows
- */
- static bool isChatMultiTab();
-
- static void initIMFloater();
-
- //used as a callback on receiving new IM message
- static void sRemoveTypingIndicator(const LLSD& data);
-
- static void onIMChicletCreated(const LLUUID& session_id);
-
- virtual LLTransientFloaterMgr::ETransientGroup getGroup() { return LLTransientFloaterMgr::IM; }
-
-protected:
- /* virtual */
- void onClickCloseBtn();
-
-private:
- // process focus events to set a currently active session
- /* virtual */ void onFocusLost();
- /* virtual */ void onFocusReceived();
-
- // Update the window title, input field help text, etc.
- void updateSessionName(const std::string& ui_title, const std::string& ui_label);
-
- // For display name lookups for IM window titles
- void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name);
-
- BOOL dropCallingCard(LLInventoryItem* item, BOOL drop);
- BOOL dropCategory(LLInventoryCategory* category, BOOL drop);
-
- BOOL isInviteAllowed() const;
- BOOL inviteToSession(const uuid_vec_t& agent_ids);
-
- static void onInputEditorFocusReceived( LLFocusableElement* caller, void* userdata );
- static void onInputEditorFocusLost(LLFocusableElement* caller, void* userdata);
- static void onInputEditorKeystroke(LLLineEditor* caller, void* userdata);
- void setTyping(bool typing);
- void onSlide();
- static void* createPanelIMControl(void* userdata);
- static void* createPanelGroupControl(void* userdata);
- static void* createPanelAdHocControl(void* userdata);
-
- // Add the "User is typing..." indicator.
- void addTypingIndicator(const LLIMInfo* im_info);
-
- // Remove the "User is typing..." indicator.
- void removeTypingIndicator(const LLIMInfo* im_info = NULL);
-
- static void closeHiddenIMToasts();
-
- static void confirmLeaveCallCallback(const LLSD& notification, const LLSD& response);
-
- LLPanelChatControlPanel* mControlPanel;
- LLUUID mSessionID;
- S32 mLastMessageIndex;
-
- EInstantMessage mDialog;
- LLUUID mOtherParticipantUUID;
- LLChatHistory* mChatHistory;
- LLLineEditor* mInputEditor;
- bool mPositioned;
-
- std::string mSavedTitle;
- LLUIString mTypingStart;
- bool mMeTyping;
- bool mOtherTyping;
- bool mShouldSendTypingState;
- LLFrameTimer mTypingTimer;
- LLFrameTimer mTypingTimeoutTimer;
-
- bool mSessionInitialized;
- LLSD mQueuedMsgsForInit;
-};
-
-
-#endif // LL_IMFLOATER_H
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
deleted file mode 100644
index c8e48b0d42..0000000000
--- a/indra/newview/llimfloatercontainer.cpp
+++ /dev/null
@@ -1,164 +0,0 @@
-/**
- * @file llimfloatercontainer.cpp
- * @brief Multifloater containing active IM sessions in separate tab container tabs
- *
- * $LicenseInfo:firstyear=2009&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 "llviewerprecompiledheaders.h"
-
-#include "llimfloatercontainer.h"
-#include "llfloaterreg.h"
-#include "llimview.h"
-#include "llavatariconctrl.h"
-#include "llgroupiconctrl.h"
-#include "llagent.h"
-#include "lltransientfloatermgr.h"
-
-//
-// LLIMFloaterContainer
-//
-LLIMFloaterContainer::LLIMFloaterContainer(const LLSD& seed)
-: LLMultiFloater(seed)
-{
- mAutoResize = FALSE;
- LLTransientFloaterMgr::getInstance()->addControlView(LLTransientFloaterMgr::IM, this);
-}
-
-LLIMFloaterContainer::~LLIMFloaterContainer()
-{
- mNewMessageConnection.disconnect();
- LLTransientFloaterMgr::getInstance()->removeControlView(LLTransientFloaterMgr::IM, this);
-}
-
-BOOL LLIMFloaterContainer::postBuild()
-{
- mNewMessageConnection = LLIMModel::instance().mNewMsgSignal.connect(boost::bind(&LLIMFloaterContainer::onNewMessageReceived, this, _1));
- // Do not call base postBuild to not connect to mCloseSignal to not close all floaters via Close button
- // mTabContainer will be initialized in LLMultiFloater::addChild()
- return TRUE;
-}
-
-void LLIMFloaterContainer::onOpen(const LLSD& key)
-{
- LLMultiFloater::onOpen(key);
-/*
- if (key.isDefined())
- {
- LLIMFloater* im_floater = LLIMFloater::findInstance(key.asUUID());
- if (im_floater)
- {
- im_floater->openFloater();
- }
- }
-*/
-}
-
-void LLIMFloaterContainer::addFloater(LLFloater* floaterp,
- BOOL select_added_floater,
- LLTabContainer::eInsertionPoint insertion_point)
-{
- if(!floaterp) return;
-
- // already here
- if (floaterp->getHost() == this)
- {
- openFloater(floaterp->getKey());
- return;
- }
-
- LLMultiFloater::addFloater(floaterp, select_added_floater, insertion_point);
-
- LLUUID session_id = floaterp->getKey();
-
- LLIconCtrl* icon = 0;
-
- if(gAgent.isInGroup(session_id, TRUE))
- {
- LLGroupIconCtrl::Params icon_params;
- icon_params.group_id = session_id;
- icon = LLUICtrlFactory::instance().create<LLGroupIconCtrl>(icon_params);
-
- mSessions[session_id] = floaterp;
- floaterp->mCloseSignal.connect(boost::bind(&LLIMFloaterContainer::onCloseFloater, this, session_id));
- }
- else
- {
- LLUUID avatar_id = LLIMModel::getInstance()->getOtherParticipantID(session_id);
-
- LLAvatarIconCtrl::Params icon_params;
- icon_params.avatar_id = avatar_id;
- icon = LLUICtrlFactory::instance().create<LLAvatarIconCtrl>(icon_params);
-
- mSessions[session_id] = floaterp;
- floaterp->mCloseSignal.connect(boost::bind(&LLIMFloaterContainer::onCloseFloater, this, session_id));
- }
- mTabContainer->setTabImage(floaterp, icon);
-}
-
-void LLIMFloaterContainer::onCloseFloater(LLUUID& id)
-{
- mSessions.erase(id);
-}
-
-void LLIMFloaterContainer::onNewMessageReceived(const LLSD& data)
-{
- LLUUID session_id = data["session_id"].asUUID();
- LLFloater* floaterp = get_ptr_in_map(mSessions, session_id);
- LLFloater* current_floater = LLMultiFloater::getActiveFloater();
-
- if(floaterp && current_floater && floaterp != current_floater)
- {
- if(LLMultiFloater::isFloaterFlashing(floaterp))
- LLMultiFloater::setFloaterFlashing(floaterp, FALSE);
- LLMultiFloater::setFloaterFlashing(floaterp, TRUE);
- }
-}
-
-LLIMFloaterContainer* LLIMFloaterContainer::findInstance()
-{
- return LLFloaterReg::findTypedInstance<LLIMFloaterContainer>("im_container");
-}
-
-LLIMFloaterContainer* LLIMFloaterContainer::getInstance()
-{
- return LLFloaterReg::getTypedInstance<LLIMFloaterContainer>("im_container");
-}
-
-void LLIMFloaterContainer::setMinimized(BOOL b)
-{
- if (isMinimized() == b) return;
-
- LLMultiFloater::setMinimized(b);
- // Hide minimized floater (see EXT-5315)
- setVisible(!b);
-
- if (isMinimized()) return;
-
- if (getActiveFloater())
- {
- getActiveFloater()->setVisible(TRUE);
- }
-}
-
-// EOF
diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h
deleted file mode 100644
index 892ecef48d..0000000000
--- a/indra/newview/llimfloatercontainer.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/**
- * @file llimfloatercontainer.h
- * @brief Multifloater containing active IM sessions in separate tab container tabs
- *
- * $LicenseInfo:firstyear=2009&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$
- */
-
-#ifndef LL_LLIMFLOATERCONTAINER_H
-#define LL_LLIMFLOATERCONTAINER_H
-
-#include <map>
-#include <vector>
-
-#include "llfloater.h"
-#include "llmultifloater.h"
-#include "llavatarpropertiesprocessor.h"
-#include "llgroupmgr.h"
-
-class LLTabContainer;
-
-class LLIMFloaterContainer : public LLMultiFloater
-{
-public:
- LLIMFloaterContainer(const LLSD& seed);
- virtual ~LLIMFloaterContainer();
-
- /*virtual*/ BOOL postBuild();
- /*virtual*/ void onOpen(const LLSD& key);
- void onCloseFloater(LLUUID& id);
-
- /*virtual*/ void addFloater(LLFloater* floaterp,
- BOOL select_added_floater,
- LLTabContainer::eInsertionPoint insertion_point = LLTabContainer::END);
-
- static LLFloater* getCurrentVoiceFloater();
-
- static LLIMFloaterContainer* findInstance();
-
- static LLIMFloaterContainer* getInstance();
-
- virtual void setMinimized(BOOL b);
-
-private:
- typedef std::map<LLUUID,LLFloater*> avatarID_panel_map_t;
- avatarID_panel_map_t mSessions;
- boost::signals2::connection mNewMessageConnection;
-
- void onNewMessageReceived(const LLSD& data);
-};
-
-#endif // LL_LLIMFLOATERCONTAINER_H
diff --git a/indra/newview/llimhandler.cpp b/indra/newview/llimhandler.cpp
index 07d73c8c66..c2b29f36e8 100644..100755
--- a/indra/newview/llimhandler.cpp
+++ b/indra/newview/llimhandler.cpp
@@ -36,11 +36,12 @@
using namespace LLNotificationsUI;
+extern void process_dnd_im(const LLSD& notification);
+
//--------------------------------------------------------------------------
-LLIMHandler::LLIMHandler(e_notification_type type, const LLSD& id)
+LLIMHandler::LLIMHandler()
+: LLCommunicationNotificationHandler("IM Notifications", "notifytoast")
{
- mType = type;
-
// Getting a Channel for our notifications
mChannel = LLChannelManager::getInstance()->createNotificationChannel()->getHandle();
}
@@ -59,72 +60,57 @@ void LLIMHandler::initChannel()
}
//--------------------------------------------------------------------------
-bool LLIMHandler::processNotification(const LLSD& notify)
+bool LLIMHandler::processNotification(const LLNotificationPtr& notification)
{
- if(mChannel.isDead())
- {
- return false;
- }
-
- LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID());
-
- if(!notification)
- return false;
-
- // arrange a channel on a screen
- if(!mChannel.get()->getVisible())
- {
- initChannel();
- }
-
- if(notify["sigtype"].asString() == "add" || notify["sigtype"].asString() == "change")
- {
- LLSD substitutions = notification->getSubstitutions();
-
- // According to comments in LLIMMgr::addMessage(), if we get message
- // from ourselves, the sender id is set to null. This fixes EXT-875.
- LLUUID avatar_id = substitutions["FROM_ID"].asUUID();
- if (avatar_id.isNull())
- avatar_id = gAgentID;
-
- LLToastIMPanel::Params im_p;
- im_p.notification = notification;
- im_p.avatar_id = avatar_id;
- im_p.from = substitutions["FROM"].asString();
- im_p.time = substitutions["TIME"].asString();
- im_p.message = substitutions["MESSAGE"].asString();
- im_p.session_id = substitutions["SESSION_ID"].asUUID();
-
- LLToastIMPanel* im_box = new LLToastIMPanel(im_p);
-
- LLToast::Params p;
- p.notif_id = notification->getID();
- p.session_id = im_p.session_id;
- p.notification = notification;
- p.panel = im_box;
- p.can_be_stored = false;
- p.on_delete_toast = boost::bind(&LLIMHandler::onDeleteToast, this, _1);
- LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel.get());
- if(channel)
- channel->addToast(p);
-
- // send a signal to the counter manager;
- mNewNotificationSignal();
- }
- else if (notify["sigtype"].asString() == "delete")
- {
- mChannel.get()->killToastByNotificationID(notification->getID());
- }
- return false;
-}
+ if(notification->isDND())
+ {
+ LLSD data = notification->asLLSD(); //don't need this if retrieve needed data from notification getters
+ process_dnd_im(data);
+ }
+ else
+ {
+ if(mChannel.isDead())
+ {
+ return false;
+ }
+
+ // arrange a channel on a screen
+ if(!mChannel.get()->getVisible())
+ {
+ initChannel();
+ }
+
+ LLSD substitutions = notification->getSubstitutions();
+
+ // According to comments in LLIMMgr::addMessage(), if we get message
+ // from ourselves, the sender id is set to null. This fixes EXT-875.
+ LLUUID avatar_id = substitutions["FROM_ID"].asUUID();
+ if (avatar_id.isNull())
+ avatar_id = gAgentID;
+
+ LLToastIMPanel::Params im_p;
+ im_p.notification = notification;
+ im_p.avatar_id = avatar_id;
+ im_p.from = substitutions["FROM"].asString();
+ im_p.time = substitutions["TIME"].asString();
+ im_p.message = substitutions["MESSAGE"].asString();
+ im_p.session_id = substitutions["SESSION_ID"].asUUID();
+
+ LLToastIMPanel* im_box = new LLToastIMPanel(im_p);
+
+ LLToast::Params p;
+ p.notif_id = notification->getID();
+ p.session_id = im_p.session_id;
+ p.notification = notification;
+ p.panel = im_box;
+ p.can_be_stored = false;
+ LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel.get());
+ if(channel)
+ channel->addToast(p);
+ }
-//--------------------------------------------------------------------------
-void LLIMHandler::onDeleteToast(LLToast* toast)
-{
- // send a signal to the counter manager
- mDelNotificationSignal();
+ return false;
}
-//--------------------------------------------------------------------------
diff --git a/indra/newview/llimpanel.cpp b/indra/newview/llimpanel.cpp
index 0250af6a0e..59272d721f 100644..100755
--- a/indra/newview/llimpanel.cpp
+++ b/indra/newview/llimpanel.cpp
@@ -171,7 +171,7 @@ LLFloaterIMPanel::LLFloaterIMPanel(const std::string& session_label,
// enable line history support for instant message bar
mInputEditor->setEnableLineHistory(TRUE);
- //*TODO we probably need the same "awaiting message" thing in LLIMFloater
+ //*TODO we probably need the same "awaiting message" thing in LLFloaterIMSession
LLIMModel::LLIMSession* im_session = LLIMModel::getInstance()->findIMSession(mSessionUUID);
if (!im_session)
{
@@ -394,9 +394,10 @@ public:
mSessionID = session_id;
}
- void error(U32 statusNum, const std::string& reason)
+ void errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content)
{
- llinfos << "Error inviting all agents to session" << llendl;
+ llwarns << "Error inviting all agents to session [status:"
+ << statusNum << "]: " << content << llendl;
//throw something back to the viewer here?
}
diff --git a/indra/newview/llimpanel.h b/indra/newview/llimpanel.h
index c5930b56f7..c5930b56f7 100644..100755
--- a/indra/newview/llimpanel.h
+++ b/indra/newview/llimpanel.h
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index a7c4618fa4..9ffbd1a675 100644..100755
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -29,6 +29,8 @@
#include "llimview.h"
#include "llavatarnamecache.h" // IDEVO
+#include "llavataractions.h"
+#include "llfloaterconversationlog.h"
#include "llfloaterreg.h"
#include "llfontgl.h"
#include "llgl.h"
@@ -41,14 +43,15 @@
#include "lltextutil.h"
#include "lltrans.h"
#include "lluictrlfactory.h"
-
+#include "llfloaterimsessiontab.h"
#include "llagent.h"
#include "llagentui.h"
#include "llappviewer.h"
#include "llavatariconctrl.h"
#include "llcallingcard.h"
#include "llchat.h"
-#include "llimfloater.h"
+#include "llfloaterimsession.h"
+#include "llfloaterimcontainer.h"
#include "llgroupiconctrl.h"
#include "llmd5.h"
#include "llmutelist.h"
@@ -57,12 +60,14 @@
#include "llviewerwindow.h"
#include "llnotifications.h"
#include "llnotificationsutil.h"
-#include "llnearbychat.h"
+#include "llfloaterimnearbychat.h"
#include "llspeakers.h" //for LLIMSpeakerMgr
#include "lltextbox.h"
#include "lltoolbarview.h"
#include "llviewercontrol.h"
#include "llviewerparcelmgr.h"
+#include "llconversationlog.h"
+#include "message.h"
const static std::string ADHOC_NAME_SUFFIX(" Conference");
@@ -97,6 +102,42 @@ BOOL LLSessionTimeoutTimer::tick()
return TRUE;
}
+
+void notify_of_message(const LLSD& msg, bool is_dnd_msg);
+
+void process_dnd_im(const LLSD& notification)
+{
+ LLSD data = notification["substitutions"];
+ LLUUID sessionID = data["SESSION_ID"].asUUID();
+ LLUUID fromID = data["FROM_ID"].asUUID();
+
+ //re-create the IM session if needed
+ //(when coming out of DND mode upon app restart)
+ if(!gIMMgr->hasSession(sessionID))
+ {
+ //reconstruct session using data from the notification
+ std::string name = data["FROM"];
+ LLAvatarName av_name;
+ if (LLAvatarNameCache::get(data["FROM_ID"], &av_name))
+ {
+ name = av_name.getDisplayName();
+ }
+
+
+ LLIMModel::getInstance()->newSession(sessionID,
+ name,
+ IM_NOTHING_SPECIAL,
+ fromID,
+ false,
+ false); //will need slight refactor to retrieve whether offline message or not (assume online for now)
+ }
+
+ notify_of_message(data, true);
+ }
+
+
+
+
static void on_avatar_name_cache_toast(const LLUUID& agent_id,
const LLAvatarName& av_name,
LLSD msg)
@@ -108,77 +149,254 @@ static void on_avatar_name_cache_toast(const LLUUID& agent_id,
args["FROM"] = av_name.getCompleteName();
args["FROM_ID"] = msg["from_id"];
args["SESSION_ID"] = msg["session_id"];
- LLNotificationsUtil::add("IMToast", args, LLSD(), boost::bind(&LLIMFloater::show, msg["session_id"].asUUID()));
+ args["SESSION_TYPE"] = msg["session_type"];
+ LLNotificationsUtil::add("IMToast", args, args, boost::bind(&LLFloaterIMContainer::showConversation, LLFloaterIMContainer::getInstance(), msg["session_id"].asUUID()));
}
-void toast_callback(const LLSD& msg){
- // do not show toast in busy mode or it goes from agent
- if (gAgent.getBusy() || gAgent.getID() == msg["from_id"])
+void notify_of_message(const LLSD& msg, bool is_dnd_msg)
+{
+ std::string user_preferences;
+ LLUUID participant_id = msg[is_dnd_msg ? "FROM_ID" : "from_id"].asUUID();
+ LLUUID session_id = msg[is_dnd_msg ? "SESSION_ID" : "session_id"].asUUID();
+ LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(session_id);
+
+ // do not show notification which goes from agent
+ if (gAgent.getID() == participant_id)
+ {
+ return;
+ }
+
+ // determine state of conversations floater
+ enum {CLOSED, NOT_ON_TOP, ON_TOP, ON_TOP_AND_ITEM_IS_SELECTED} conversations_floater_status;
+
+
+ LLFloaterIMContainer* im_box = LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container");
+ LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::getConversation(session_id);
+ bool store_dnd_message = false; // flag storage of a dnd message
+ bool is_session_focused = session_floater->isTornOff() && session_floater->hasFocus();
+ if (!LLFloater::isVisible(im_box) || im_box->isMinimized())
{
- return;
+ conversations_floater_status = CLOSED;
}
-
- // check whether incoming IM belongs to an active session or not
- if (LLIMModel::getInstance()->getActiveSessionID().notNull()
- && LLIMModel::getInstance()->getActiveSessionID() == msg["session_id"])
+ else if (!im_box->hasFocus() &&
+ !(session_floater && LLFloater::isVisible(session_floater)
+ && !session_floater->isMinimized() && session_floater->hasFocus()))
{
- return;
+ conversations_floater_status = NOT_ON_TOP;
}
-
- // Skip toasting for system messages
- if (msg["from_id"].asUUID() == LLUUID::null)
+ else if (im_box->getSelectedSession() != session_id)
{
- return;
+ conversations_floater_status = ON_TOP;
+ }
+ else
+ {
+ conversations_floater_status = ON_TOP_AND_ITEM_IS_SELECTED;
}
- // *NOTE Skip toasting if the user disable it in preferences/debug settings ~Alexandrea
- LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(
- msg["session_id"]);
- if (!gSavedSettings.getBOOL("EnableGroupChatPopups")
- && session->isGroupSessionType())
- {
- return;
+ // determine user prefs for this session
+ if (session_id.isNull())
+ {
+ if (msg["source_type"].asInteger() == CHAT_SOURCE_OBJECT)
+ {
+ user_preferences = gSavedSettings.getString("NotificationObjectIMOptions");
+ if (!gAgent.isDoNotDisturb() && (gSavedSettings.getBOOL("PlaySoundObjectIM") == TRUE))
+ {
+ make_ui_sound("UISndNewIncomingIMSession");
+ }
+ }
+ else
+ {
+ user_preferences = gSavedSettings.getString("NotificationNearbyChatOptions");
+ if (!gAgent.isDoNotDisturb() && (gSavedSettings.getBOOL("PlaySoundNearbyChatIM") == TRUE))
+ {
+ make_ui_sound("UISndNewIncomingIMSession");
+ }
+ }
}
- if (!gSavedSettings.getBOOL("EnableIMChatPopups")
- && !session->isGroupSessionType())
- {
- return;
+ else if(session->isP2PSessionType())
+ {
+ if (LLAvatarTracker::instance().isBuddy(participant_id))
+ {
+ user_preferences = gSavedSettings.getString("NotificationFriendIMOptions");
+ if (!gAgent.isDoNotDisturb() && (gSavedSettings.getBOOL("PlaySoundFriendIM") == TRUE))
+ {
+ make_ui_sound("UISndNewIncomingIMSession");
+ }
+ }
+ else
+ {
+ user_preferences = gSavedSettings.getString("NotificationNonFriendIMOptions");
+ if (!gAgent.isDoNotDisturb() && (gSavedSettings.getBOOL("PlaySoundNonFriendIM") == TRUE))
+ {
+ make_ui_sound("UISndNewIncomingIMSession");
+ }
+ }
+ }
+ else if(session->isAdHocSessionType())
+ {
+ user_preferences = gSavedSettings.getString("NotificationConferenceIMOptions");
+ if (!gAgent.isDoNotDisturb() && (gSavedSettings.getBOOL("PlaySoundConferenceIM") == TRUE))
+ {
+ make_ui_sound("UISndNewIncomingIMSession");
+ }
+ }
+ else if(session->isGroupSessionType())
+ {
+ user_preferences = gSavedSettings.getString("NotificationGroupChatOptions");
+ if (!gAgent.isDoNotDisturb() && (gSavedSettings.getBOOL("PlaySoundGroupChatIM") == TRUE))
+ {
+ make_ui_sound("UISndNewIncomingIMSession");
+ }
+ }
+
+ // actions:
+
+ // 0. nothing - exit
+ if (("noaction" == user_preferences ||
+ ON_TOP_AND_ITEM_IS_SELECTED == conversations_floater_status)
+ && session_floater->isMessagePaneExpanded())
+ {
+ return;
+ }
+
+ // 1. open floater and [optional] surface it
+ if ("openconversations" == user_preferences &&
+ (CLOSED == conversations_floater_status
+ || NOT_ON_TOP == conversations_floater_status))
+ {
+ if(!gAgent.isDoNotDisturb())
+ {
+ // Open conversations floater
+ LLFloaterReg::showInstance("im_container");
+ im_box->collapseMessagesPane(false);
+ if (session_floater)
+ {
+ if (session_floater->getHost())
+ {
+ if (NULL != im_box && im_box->isMinimized())
+ {
+ LLFloater::onClickMinimize(im_box);
+ }
+ }
+ else
+ {
+ if (session_floater->isMinimized())
+ {
+ LLFloater::onClickMinimize(session_floater);
+ }
+ }
+ }
+ }
+ else
+ {
+ store_dnd_message = true;
+ }
+
+ }
+
+ // 2. Flash line item
+ if ("openconversations" == user_preferences
+ || ON_TOP == conversations_floater_status
+ || ("toast" == user_preferences && ON_TOP != conversations_floater_status)
+ || ("flash" == user_preferences && (CLOSED == conversations_floater_status
+ || NOT_ON_TOP == conversations_floater_status))
+ || is_dnd_msg)
+ {
+ if(!LLMuteList::getInstance()->isMuted(participant_id))
+ {
+ if(gAgent.isDoNotDisturb())
+ {
+ store_dnd_message = true;
+ }
+ else
+ {
+ if (is_dnd_msg && (ON_TOP == conversations_floater_status ||
+ NOT_ON_TOP == conversations_floater_status ||
+ CLOSED == conversations_floater_status))
+ {
+ im_box->highlightConversationItemWidget(session_id, true);
+ }
+ else
+ {
+ im_box->flashConversationItemWidget(session_id, true);
+ }
+ }
+ }
}
- // Skip toasting if we have open window of IM with this session id
- LLIMFloater* open_im_floater = LLIMFloater::findInstance(msg["session_id"]);
- if (open_im_floater && open_im_floater->getVisible())
+ // 3. Flash FUI button
+ if (("toast" == user_preferences || "flash" == user_preferences) &&
+ (CLOSED == conversations_floater_status
+ || NOT_ON_TOP == conversations_floater_status)
+ && !is_session_focused
+ && !is_dnd_msg) //prevent flashing FUI button because the conversation floater will have already opened
{
- return;
+ if(!LLMuteList::getInstance()->isMuted(participant_id))
+ {
+ if(!gAgent.isDoNotDisturb())
+ {
+ gToolBarView->flashCommand(LLCommandId("chat"), true, im_box->isMinimized());
+ }
+ else
+ {
+ store_dnd_message = true;
+ }
+ }
}
- LLAvatarNameCache::get(msg["from_id"].asUUID(),
- boost::bind(&on_avatar_name_cache_toast,
- _1, _2, msg));
-}
+ // 4. Toast
+ if ((("toast" == user_preferences) &&
+ (ON_TOP_AND_ITEM_IS_SELECTED != conversations_floater_status) &&
+ (!session_floater->isTornOff() || !LLFloater::isVisible(session_floater)))
+ || !session_floater->isMessagePaneExpanded())
-void LLIMModel::setActiveSessionID(const LLUUID& session_id)
-{
- // check if such an ID really exists
- if (!findIMSession(session_id))
+ {
+ //Show IM toasts (upper right toasts)
+ // Skip toasting for system messages and for nearby chat
+ if(session_id.notNull() && participant_id.notNull())
+ {
+ if(!is_dnd_msg)
+ {
+ if(gAgent.isDoNotDisturb())
+ {
+ store_dnd_message = true;
+ }
+ else
+ {
+ LLAvatarNameCache::get(participant_id, boost::bind(&on_avatar_name_cache_toast, _1, _2, msg));
+ }
+ }
+}
+ }
+ if (store_dnd_message)
{
- llwarns << "Trying to set as active a non-existent session!" << llendl;
- return;
+ // If in DND mode, allow notification to be stored so upon DND exit
+ // the user will be notified with some limitations (see 'is_dnd_msg' flag checks)
+ if(session_id.notNull()
+ && participant_id.notNull()
+ && !session_floater->isShown())
+ {
+ LLAvatarNameCache::get(participant_id, boost::bind(&on_avatar_name_cache_toast, _1, _2, msg));
+ }
}
+}
- mActiveSessionID = session_id;
+void on_new_message(const LLSD& msg)
+{
+ notify_of_message(msg, false);
}
LLIMModel::LLIMModel()
{
- addNewMsgCallback(boost::bind(&LLIMFloater::newIMCallback, _1));
- addNewMsgCallback(boost::bind(&toast_callback, _1));
+ addNewMsgCallback(boost::bind(&LLFloaterIMSession::newIMCallback, _1));
+ addNewMsgCallback(boost::bind(&on_new_message, _1));
}
-LLIMModel::LLIMSession::LLIMSession(const LLUUID& session_id, const std::string& name, const EInstantMessage& type, const LLUUID& other_participant_id, const uuid_vec_t& ids, bool voice)
+LLIMModel::LLIMSession::LLIMSession(const LLUUID& session_id, const std::string& name, const EInstantMessage& type, const LLUUID& other_participant_id, const uuid_vec_t& ids, bool voice, bool has_offline_msg)
: mSessionID(session_id),
mName(name),
mType(type),
+ mHasOfflineMessage(has_offline_msg),
mParticipantUnreadMessageCount(0),
mNumUnread(0),
mOtherParticipantID(other_participant_id),
@@ -190,7 +408,8 @@ LLIMModel::LLIMSession::LLIMSession(const LLUUID& session_id, const std::string&
mTextIMPossible(true),
mOtherParticipantIsAvatar(true),
mStartCallOnInitialize(false),
- mStartedAsIMCall(voice)
+ mStartedAsIMCall(voice),
+ mAvatarNameCacheConnection()
{
// set P2P type by default
mSessionType = P2P_SESSION;
@@ -256,30 +475,22 @@ LLIMModel::LLIMSession::LLIMSession(const LLUUID& session_id, const std::string&
}
buildHistoryFileName();
-
- if ( gSavedPerAccountSettings.getBOOL("LogShowHistory") )
- {
- std::list<LLSD> chat_history;
-
- //involves parsing of a chat history
- LLLogChat::loadAllHistory(mHistoryFileName, chat_history);
- addMessagesFromHistory(chat_history);
- }
+ loadHistory();
// Localizing name of ad-hoc session. STORM-153
// Changing name should happen here- after the history file was created, so that
// history files have consistent (English) names in different locales.
if (isAdHocSessionType() && IM_SESSION_INVITE == mType)
{
- LLAvatarNameCache::get(mOtherParticipantID,
- boost::bind(&LLIMModel::LLIMSession::onAdHocNameCache,
- this, _2));
+ mAvatarNameCacheConnection = LLAvatarNameCache::get(mOtherParticipantID,boost::bind(&LLIMModel::LLIMSession::onAdHocNameCache,this, _2));
}
}
void LLIMModel::LLIMSession::onAdHocNameCache(const LLAvatarName& av_name)
{
- if (av_name.mIsTemporaryName)
+ mAvatarNameCacheConnection.disconnect();
+
+ if (!av_name.isValidName())
{
S32 separator_index = mName.rfind(" ");
std::string name = mName.substr(0, separator_index);
@@ -375,6 +586,8 @@ void LLIMModel::LLIMSession::onVoiceChannelStateChanged(const LLVoiceChannel::ES
break;
}
}
+ default:
+ break;
}
// Update speakers list when connected
if (LLVoiceChannel::STATE_CONNECTED == new_state)
@@ -385,6 +598,11 @@ void LLIMModel::LLIMSession::onVoiceChannelStateChanged(const LLVoiceChannel::ES
LLIMModel::LLIMSession::~LLIMSession()
{
+ if (mAvatarNameCacheConnection.connected())
+ {
+ mAvatarNameCacheConnection.disconnect();
+ }
+
delete mSpeakers;
mSpeakers = NULL;
@@ -450,11 +668,11 @@ void LLIMModel::LLIMSession::addMessagesFromHistory(const std::list<LLSD>& histo
{
const LLSD& msg = *it;
- std::string from = msg[IM_FROM];
+ std::string from = msg[LL_IM_FROM];
LLUUID from_id;
- if (msg[IM_FROM_ID].isDefined())
+ if (msg[LL_IM_FROM_ID].isDefined())
{
- from_id = msg[IM_FROM_ID].asUUID();
+ from_id = msg[LL_IM_FROM_ID].asUUID();
}
else
{
@@ -463,8 +681,8 @@ void LLIMModel::LLIMSession::addMessagesFromHistory(const std::list<LLSD>& histo
gCacheName->getUUID(legacy_name, from_id);
}
- std::string timestamp = msg[IM_TIME];
- std::string text = msg[IM_TEXT];
+ std::string timestamp = msg[LL_IM_TIME];
+ std::string text = msg[LL_IM_TEXT];
addMessage(from, from_id, text, timestamp, true);
@@ -488,10 +706,23 @@ void LLIMModel::LLIMSession::chatFromLogFile(LLLogChat::ELogLineType type, const
}
}
+void LLIMModel::LLIMSession::loadHistory()
+{
+ mMsgs.clear();
+
+ if ( gSavedPerAccountSettings.getBOOL("LogShowHistory") )
+ {
+ std::list<LLSD> chat_history;
+
+ //involves parsing of a chat history
+ LLLogChat::loadChatHistory(mHistoryFileName, chat_history);
+ addMessagesFromHistory(chat_history);
+ }
+}
+
LLIMModel::LLIMSession* LLIMModel::findIMSession(const LLUUID& session_id) const
{
- return get_if_there(mId2SessionMap, session_id,
- (LLIMModel::LLIMSession*) NULL);
+ return get_if_there(mId2SessionMap, session_id, (LLIMModel::LLIMSession*) NULL);
}
//*TODO consider switching to using std::set instead of std::list for holding LLUUIDs across the whole code
@@ -533,7 +764,7 @@ LLIMModel::LLIMSession* LLIMModel::findAdHocIMSession(const uuid_vec_t& ids)
return NULL;
}
-bool LLIMModel::LLIMSession::isOutgoingAdHoc()
+bool LLIMModel::LLIMSession::isOutgoingAdHoc() const
{
return IM_SESSION_CONFERENCE_START == mType;
}
@@ -553,6 +784,19 @@ bool LLIMModel::LLIMSession::isOtherParticipantAvaline()
return !mOtherParticipantIsAvatar;
}
+LLUUID LLIMModel::LLIMSession::generateOutgouigAdHocHash() const
+{
+ LLUUID hash = LLUUID::null;
+
+ if (mInitialTargetIDs.size())
+ {
+ std::set<LLUUID> sorted_uuids(mInitialTargetIDs.begin(), mInitialTargetIDs.end());
+ hash = generateHash(sorted_uuids);
+ }
+
+ return hash;
+}
+
void LLIMModel::LLIMSession::buildHistoryFileName()
{
mHistoryFileName = mName;
@@ -569,7 +813,7 @@ void LLIMModel::LLIMSession::buildHistoryFileName()
if (mInitialTargetIDs.size())
{
std::set<LLUUID> sorted_uuids(mInitialTargetIDs.begin(), mInitialTargetIDs.end());
- mHistoryFileName = mName + " hash" + generateHash(sorted_uuids);
+ mHistoryFileName = mName + " hash" + generateHash(sorted_uuids).asString();
}
else
{
@@ -584,15 +828,7 @@ void LLIMModel::LLIMSession::buildHistoryFileName()
// so no need for a callback in LLAvatarNameCache::get()
if (LLAvatarNameCache::get(mOtherParticipantID, &av_name))
{
- if (av_name.mUsername.empty())
- {
- // Display names are off, use mDisplayName which will be the legacy name
- mHistoryFileName = LLCacheName::buildUsername(av_name.mDisplayName);
- }
- else
- {
- mHistoryFileName = av_name.mUsername;
- }
+ mHistoryFileName = LLCacheName::buildUsername(av_name.getUserName());
}
else
{
@@ -603,7 +839,7 @@ void LLIMModel::LLIMSession::buildHistoryFileName()
}
//static
-std::string LLIMModel::LLIMSession::generateHash(const std::set<LLUUID>& sorted_uuids)
+LLUUID LLIMModel::LLIMSession::generateHash(const std::set<LLUUID>& sorted_uuids)
{
LLMD5 md5_uuid;
@@ -617,7 +853,7 @@ std::string LLIMModel::LLIMSession::generateHash(const std::set<LLUUID>& sorted_
LLUUID participants_md5_hash;
md5_uuid.raw_digest((unsigned char*) participants_md5_hash.mData);
- return participants_md5_hash.asString();
+ return participants_md5_hash;
}
void LLIMModel::processSessionInitializedReply(const LLUUID& old_session_id, const LLUUID& new_session_id)
@@ -631,16 +867,19 @@ void LLIMModel::processSessionInitializedReply(const LLUUID& old_session_id, con
{
mId2SessionMap.erase(old_session_id);
mId2SessionMap[new_session_id] = session;
-
- gIMMgr->notifyObserverSessionIDUpdated(old_session_id, new_session_id);
}
- LLIMFloater* im_floater = LLIMFloater::findInstance(old_session_id);
+ LLFloaterIMSession* im_floater = LLFloaterIMSession::findInstance(old_session_id);
if (im_floater)
{
im_floater->sessionInitReplyReceived(new_session_id);
}
+ if (old_session_id != new_session_id)
+ {
+ gIMMgr->notifyObserverSessionIDUpdated(old_session_id, new_session_id);
+ }
+
// auto-start the call on session initialization?
if (session->mStartCallOnInitialize)
{
@@ -676,7 +915,7 @@ void LLIMModel::testMessages()
//session name should not be empty
bool LLIMModel::newSession(const LLUUID& session_id, const std::string& name, const EInstantMessage& type,
- const LLUUID& other_participant_id, const uuid_vec_t& ids, bool voice)
+ const LLUUID& other_participant_id, const uuid_vec_t& ids, bool voice, bool has_offline_msg)
{
if (name.empty())
{
@@ -690,22 +929,23 @@ bool LLIMModel::newSession(const LLUUID& session_id, const std::string& name, co
return false;
}
- LLIMSession* session = new LLIMSession(session_id, name, type, other_participant_id, ids, voice);
+ LLIMSession* session = new LLIMSession(session_id, name, type, other_participant_id, ids, voice, has_offline_msg);
mId2SessionMap[session_id] = session;
// When notifying observer, name of session is used instead of "name", because they may not be the
// same if it is an adhoc session (in this case name is localized in LLIMSession constructor).
std::string session_name = LLIMModel::getInstance()->getName(session_id);
- LLIMMgr::getInstance()->notifyObserverSessionAdded(session_id, session_name, other_participant_id);
+ LLIMMgr::getInstance()->notifyObserverSessionAdded(session_id, session_name, other_participant_id,has_offline_msg);
return true;
}
-bool LLIMModel::newSession(const LLUUID& session_id, const std::string& name, const EInstantMessage& type, const LLUUID& other_participant_id, bool voice)
+bool LLIMModel::newSession(const LLUUID& session_id, const std::string& name, const EInstantMessage& type, const LLUUID& other_participant_id, bool voice, bool has_offline_msg)
{
- uuid_vec_t no_ids;
- return newSession(session_id, name, type, other_participant_id, no_ids, voice);
+ uuid_vec_t ids;
+ ids.push_back(other_participant_id);
+ return newSession(session_id, name, type, other_participant_id, ids, voice, has_offline_msg);
}
bool LLIMModel::clearSession(const LLUUID& session_id)
@@ -716,6 +956,16 @@ bool LLIMModel::clearSession(const LLUUID& session_id)
return true;
}
+void LLIMModel::getMessages(const LLUUID& session_id, std::list<LLSD>& messages, int start_index, const bool sendNoUnreadMsgs)
+{
+ getMessagesSilently(session_id, messages, start_index);
+
+ if (sendNoUnreadMsgs)
+ {
+ sendNoUnreadMessages(session_id);
+ }
+}
+
void LLIMModel::getMessagesSilently(const LLUUID& session_id, std::list<LLSD>& messages, int start_index)
{
LLIMSession* session = findIMSession(session_id);
@@ -757,13 +1007,6 @@ void LLIMModel::sendNoUnreadMessages(const LLUUID& session_id)
mNoUnreadMsgsSignal(arg);
}
-void LLIMModel::getMessages(const LLUUID& session_id, std::list<LLSD>& messages, int start_index)
-{
- getMessagesSilently(session_id, messages, start_index);
-
- sendNoUnreadMessages(session_id);
-}
-
bool LLIMModel::addToHistory(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, const std::string& utf8_text) {
LLIMSession* session = findIMSession(session_id);
@@ -781,19 +1024,20 @@ bool LLIMModel::addToHistory(const LLUUID& session_id, const std::string& from,
bool LLIMModel::logToFile(const std::string& file_name, const std::string& from, const LLUUID& from_id, const std::string& utf8_text)
{
- if (gSavedPerAccountSettings.getBOOL("LogInstantMessages"))
+ if (gSavedPerAccountSettings.getS32("KeepConversationLogTranscripts") > 1)
{
std::string from_name = from;
LLAvatarName av_name;
if (!from_id.isNull() &&
LLAvatarNameCache::get(from_id, &av_name) &&
- !av_name.mIsDisplayNameDefault)
+ !av_name.isDisplayNameDefault())
{
from_name = av_name.getCompleteName();
}
LLLogChat::saveHistory(file_name, from_name, from_id, utf8_text);
+ LLConversationLog::instance().cache(); // update the conversation log too
return true;
}
else
@@ -831,6 +1075,7 @@ bool LLIMModel::addMessage(const LLUUID& session_id, const std::string& from, co
arg["from"] = from;
arg["from_id"] = from_id;
arg["time"] = LLLogChat::timestamp(false);
+ arg["session_type"] = session->mSessionType;
mNewMsgSignal(arg);
return true;
@@ -878,7 +1123,7 @@ const std::string LLIMModel::getName(const LLUUID& session_id) const
{
LLIMSession* session = findIMSession(session_id);
- if (!session)
+ if (!session)
{
llwarns << "session " << session_id << "does not exist " << llendl;
return LLTrans::getString("no_session_message");
@@ -904,7 +1149,7 @@ const LLUUID& LLIMModel::getOtherParticipantID(const LLUUID& session_id) const
LLIMSession* session = findIMSession(session_id);
if (!session)
{
- llwarns << "session " << session_id << "does not exist " << llendl;
+ llwarns << "session " << session_id << " does not exist " << llendl;
return LLUUID::null;
}
@@ -1227,7 +1472,7 @@ public:
mAgents = agents_to_invite;
}
- virtual void error(U32 statusNum, const std::string& reason)
+ virtual void errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content)
{
//try an "old school" way.
if ( statusNum == 400 )
@@ -1239,6 +1484,9 @@ public:
mAgents);
}
+ llwarns << "LLStartConferenceChatResponder error [status:"
+ << statusNum << "]: " << content << llendl;
+
//else throw an error back to the client?
//in theory we should have just have these error strings
//etc. set up in this file as opposed to the IMMgr,
@@ -1376,7 +1624,7 @@ public:
&& LLIMModel::getInstance()->findIMSession(mSessionID))
{
// TODO remove in 2010, for voice calls we do not open an IM window
- //LLIMFloater::show(mSessionID);
+ //LLFloaterIMSession::show(mSessionID);
}
gIMMgr->clearPendingAgentListUpdates(mSessionID);
@@ -1384,8 +1632,10 @@ public:
}
}
- void error(U32 statusNum, const std::string& reason)
+ void errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content)
{
+ llwarns << "LLViewerChatterBoxInvitationAcceptResponder error [status:"
+ << statusNum << "]: " << content << llendl;
//throw something back to the viewer here?
if ( gIMMgr )
{
@@ -1444,6 +1694,11 @@ LLUUID LLIMMgr::computeSessionID(
session_id = other_participant_id ^ agent_id;
}
}
+
+ if (gAgent.isInGroup(session_id) && (session_id != other_participant_id))
+ {
+ llwarns << "Group session id different from group id: IM type = " << dialog << ", session id = " << session_id << ", group id = " << other_participant_id << llendl;
+ }
return session_id;
}
@@ -1520,7 +1775,7 @@ LLIMMgr::onConfirmForceCloseError(
//only 1 option really
LLUUID session_id = notification["payload"]["session_id"];
- LLFloater* floater = LLIMFloater::findInstance(session_id);
+ LLFloater* floater = LLFloaterIMSession::findInstance(session_id);
if ( floater )
{
floater->closeFloater(FALSE);
@@ -1878,7 +2133,7 @@ void LLOutgoingCallDialog::show(const LLSD& key)
LLAvatarName av_name;
if (LLAvatarNameCache::get(callee_id, &av_name))
{
- final_callee_name = av_name.mDisplayName;
+ final_callee_name = av_name.getDisplayName();
title = av_name.getCompleteName();
}
}
@@ -1980,7 +2235,8 @@ BOOL LLOutgoingCallDialog::postBuild()
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
LLIncomingCallDialog::LLIncomingCallDialog(const LLSD& payload) :
-LLCallDialog(payload)
+LLCallDialog(payload),
+mAvatarNameCacheConnection()
{
}
@@ -2050,9 +2306,11 @@ BOOL LLIncomingCallDialog::postBuild()
else
{
// Get the full name information
- LLAvatarNameCache::get(caller_id,
- boost::bind(&LLIncomingCallDialog::onAvatarNameCache,
- this, _1, _2, call_type));
+ if (mAvatarNameCacheConnection.connected())
+ {
+ mAvatarNameCacheConnection.disconnect();
+ }
+ mAvatarNameCacheConnection = LLAvatarNameCache::get(caller_id, boost::bind(&LLIncomingCallDialog::onAvatarNameCache, this, _1, _2, call_type));
}
setIcon(session_id, caller_id);
@@ -2078,7 +2336,6 @@ BOOL LLIncomingCallDialog::postBuild()
getChildView("Start IM")->setVisible( is_avatar && notify_box_type != "VoiceInviteAdHoc" && notify_box_type != "VoiceInviteGroup");
setCanDrag(FALSE);
-
return TRUE;
}
@@ -2086,7 +2343,6 @@ void LLIncomingCallDialog::setCallerName(const std::string& ui_title,
const std::string& ui_label,
const std::string& call_type)
{
- setTitle(ui_title);
// call_type may be a string like " is calling."
LLUICtrl* caller_name_widget = getChild<LLUICtrl>("caller name");
@@ -2097,14 +2353,15 @@ void LLIncomingCallDialog::onAvatarNameCache(const LLUUID& agent_id,
const LLAvatarName& av_name,
const std::string& call_type)
{
+ mAvatarNameCacheConnection.disconnect();
std::string title = av_name.getCompleteName();
- setCallerName(title, av_name.mDisplayName, call_type);
+ setCallerName(title, av_name.getCompleteName(), call_type);
}
void LLIncomingCallDialog::onOpen(const LLSD& key)
{
LLCallDialog::onOpen(key);
-
+ make_ui_sound("UISndStartIM");
LLStringUtil::format_map_t args;
LLGroupData data;
// if it's a group call, retrieve group name to use it in question
@@ -2112,18 +2369,6 @@ void LLIncomingCallDialog::onOpen(const LLSD& key)
{
args["[GROUP]"] = data.mName;
}
- // tell the user which voice channel they would be leaving
- LLVoiceChannel *voice = LLVoiceChannel::getCurrentVoiceChannel();
- if (voice && !voice->getSessionName().empty())
- {
- args["[CURRENT_CHAT]"] = voice->getSessionName();
- getChild<LLUICtrl>("question")->setValue(getString(key["question_type"].asString(), args));
- }
- else
- {
- args["[CURRENT_CHAT]"] = getString("localchat");
- getChild<LLUICtrl>("question")->setValue(getString(key["question_type"].asString(), args));
- }
}
//static
@@ -2184,6 +2429,10 @@ void LLIncomingCallDialog::processCallResponse(S32 response, const LLSD &payload
{
gIMMgr->startCall(session_id, LLVoiceChannel::INCOMING_CALL);
}
+ else
+ {
+ LLAvatarActions::startIM(caller_id);
+ }
gIMMgr->clearPendingAgentListUpdates(session_id);
gIMMgr->clearPendingInvitation(session_id);
@@ -2386,7 +2635,7 @@ LLIMMgr::LLIMMgr()
mPendingInvitations = LLSD::emptyMap();
mPendingAgentListUpdates = LLSD::emptyMap();
- LLIMModel::getInstance()->addNewMsgCallback(boost::bind(&LLIMFloater::sRemoveTypingIndicator, _1));
+ LLIMModel::getInstance()->addNewMsgCallback(boost::bind(&LLFloaterIMSession::sRemoveTypingIndicator, _1));
}
// Add a message to a session.
@@ -2395,6 +2644,7 @@ void LLIMMgr::addMessage(
const LLUUID& target_id,
const std::string& from,
const std::string& msg,
+ bool is_offline_msg,
const std::string& session_name,
EInstantMessage dialog,
U32 parent_estate_id,
@@ -2403,6 +2653,7 @@ void LLIMMgr::addMessage(
bool link_name) // If this is true, then we insert the name and link it to a profile
{
LLUUID other_participant_id = target_id;
+
LLUUID new_session_id = session_id;
if (new_session_id.isNull())
{
@@ -2412,16 +2663,37 @@ void LLIMMgr::addMessage(
//*NOTE session_name is empty in case of incoming P2P sessions
std::string fixed_session_name = from;
+ bool name_is_setted = false;
if(!session_name.empty() && session_name.size()>1)
{
fixed_session_name = session_name;
+ name_is_setted = true;
+ }
+ bool skip_message = false;
+ bool from_linden = LLMuteList::getInstance()->isLinden(from);
+ if (gSavedSettings.getBOOL("VoiceCallsFriendsOnly") && !from_linden)
+ {
+ // Evaluate if we need to skip this message when that setting is true (default is false)
+ skip_message = (LLAvatarTracker::instance().getBuddyInfo(other_participant_id) == NULL); // Skip non friends...
+ skip_message &= !(other_participant_id == gAgentID); // You are your best friend... Don't skip yourself
}
bool new_session = !hasSession(new_session_id);
if (new_session)
{
- LLIMModel::getInstance()->newSession(new_session_id, fixed_session_name, dialog, other_participant_id);
+ LLAvatarName av_name;
+ if (LLAvatarNameCache::get(other_participant_id, &av_name) && !name_is_setted)
+ {
+ fixed_session_name = av_name.getDisplayName();
+ }
+ LLIMModel::getInstance()->newSession(new_session_id, fixed_session_name, dialog, other_participant_id, false, is_offline_msg);
+ LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(new_session_id);
+ skip_message &= !session->isGroupSessionType(); // Do not skip group chats...
+ if(skip_message)
+ {
+ gIMMgr->leaveSession(new_session_id);
+ }
// When we get a new IM, and if you are a god, display a bit
// of information about the source. This is to help liaisons
// when answering questions.
@@ -2445,7 +2717,7 @@ void LLIMMgr::addMessage(
// Logically it would make more sense to reject the session sooner, in another area of the
// code, but the session has to be established inside the server before it can be left.
- if (LLMuteList::getInstance()->isMuted(other_participant_id) && !LLMuteList::getInstance()->isLinden(from))
+ if (LLMuteList::getInstance()->isMuted(other_participant_id) && !from_linden)
{
llwarns << "Leaving IM session from initiating muted resident " << from << llendl;
if(!gIMMgr->leaveSession(new_session_id))
@@ -2455,16 +2727,25 @@ void LLIMMgr::addMessage(
return;
}
- make_ui_sound("UISndNewIncomingIMSession");
+ //Play sound for new conversations
+ if (!gAgent.isDoNotDisturb() && (gSavedSettings.getBOOL("PlaySoundNewConversation") == TRUE))
+ {
+ make_ui_sound("UISndNewIncomingIMSession");
+ }
}
- bool skip_message = (gSavedSettings.getBOOL("VoiceCallsFriendsOnly") &&
- LLAvatarTracker::instance().getBuddyInfo(other_participant_id) == NULL);
-
if (!LLMuteList::getInstance()->isMuted(other_participant_id, LLMute::flagTextChat) && !skip_message)
{
LLIMModel::instance().addMessage(new_session_id, from, other_participant_id, msg);
}
+
+ // Open conversation floater if offline messages are present
+ if (is_offline_msg && !skip_message)
+ {
+ LLFloaterReg::showInstance("im_container");
+ LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container")->
+ flashConversationItemWidget(new_session_id, true);
+ }
}
void LLIMMgr::addSystemMessage(const LLUUID& session_id, const std::string& message_name, const LLSD& args)
@@ -2479,11 +2760,9 @@ void LLIMMgr::addSystemMessage(const LLUUID& session_id, const std::string& mess
LLChat chat(message);
chat.mSourceType = CHAT_SOURCE_SYSTEM;
-
- LLFloater* chat_bar = LLFloaterReg::getInstance("chat_bar");
- LLNearbyChat* nearby_chat = chat_bar->findChild<LLNearbyChat>("nearby_chat");
- if(nearby_chat)
+ LLFloaterIMNearbyChat* nearby_chat = LLFloaterReg::findTypedInstance<LLFloaterIMNearbyChat>("nearby_chat");
+ if (nearby_chat)
{
nearby_chat->addMessage(chat);
}
@@ -2497,6 +2776,7 @@ void LLIMMgr::addSystemMessage(const LLUUID& session_id, const std::string& mess
gIMMgr->addMessage(session_id, LLUUID::null, SYSTEM_FROM, message.getString());
}
// log message to file
+
else
{
std::string session_name;
@@ -2579,7 +2859,8 @@ LLUUID LLIMMgr::addSession(
{
LLDynamicArray<LLUUID> ids;
ids.put(other_participant_id);
- return addSession(name, dialog, other_participant_id, ids, voice);
+ LLUUID session_id = addSession(name, dialog, other_participant_id, ids, voice);
+ return session_id;
}
// Adds a session using the given session_id. If the session already exists
@@ -2588,7 +2869,8 @@ LLUUID LLIMMgr::addSession(
const std::string& name,
EInstantMessage dialog,
const LLUUID& other_participant_id,
- const LLDynamicArray<LLUUID>& ids, bool voice)
+ const LLDynamicArray<LLUUID>& ids, bool voice,
+ const LLUUID& floater_id)
{
if (0 == ids.getLength())
{
@@ -2603,7 +2885,21 @@ LLUUID LLIMMgr::addSession(
LLUUID session_id = computeSessionID(dialog,other_participant_id);
- bool new_session = !LLIMModel::getInstance()->findIMSession(session_id);
+ if (floater_id.notNull())
+ {
+ LLFloaterIMSession* im_floater = LLFloaterIMSession::findInstance(floater_id);
+
+ if (im_floater)
+ {
+ // The IM floater should be initialized with a new session_id
+ // so that it is found by that id when creating a chiclet in LLFloaterIMSession::onIMChicletCreated,
+ // and a new floater is not created.
+ im_floater->initIMSession(session_id);
+ im_floater->reloadMessages();
+ }
+ }
+
+ bool new_session = (LLIMModel::getInstance()->findIMSession(session_id) == NULL);
//works only for outgoing ad-hoc sessions
if (new_session && IM_SESSION_CONFERENCE_START == dialog && ids.size())
@@ -2616,14 +2912,23 @@ LLUUID LLIMMgr::addSession(
}
}
+ //Notify observers that a session was added
if (new_session)
{
LLIMModel::getInstance()->newSession(session_id, name, dialog, other_participant_id, ids, voice);
}
+ //Notifies observers that the session was already added
+ else
+ {
+ std::string session_name = LLIMModel::getInstance()->getName(session_id);
+ LLIMMgr::getInstance()->notifyObserverSessionActivated(session_id, session_name, other_participant_id);
+ }
//we don't need to show notes about online/offline, mute/unmute users' statuses for existing sessions
if (!new_session) return session_id;
+ llinfos << "LLIMMgr::addSession, new session added, name = " << name << ", session id = " << session_id << llendl;
+
//Per Plan's suggestion commented "explicit offline status warning" out to make Dessie happier (see EXT-3609)
//*TODO After February 2010 remove this commented out line if no one will be missing that warning
//noteOfflineUsers(session_id, floater, ids);
@@ -2634,6 +2939,8 @@ LLUUID LLIMMgr::addSession(
noteMutedUsers(session_id, ids);
}
+ notifyObserverSessionVoiceOrIMStarted(session_id);
+
return session_id;
}
@@ -2657,6 +2964,8 @@ void LLIMMgr::removeSession(const LLUUID& session_id)
LLIMModel::getInstance()->clearSession(session_id);
+ llinfos << "LLIMMgr::removeSession, session removed, session id = " << session_id << llendl;
+
notifyObserverSessionRemoved(session_id);
}
@@ -2674,7 +2983,6 @@ void LLIMMgr::inviteToSession(
// voice invite question is different from default only for group call (EXT-7118)
std::string question_type = "VoiceInviteQuestionDefault";
- BOOL ad_hoc_invite = FALSE;
BOOL voice_invite = FALSE;
bool is_linden = LLMuteList::getInstance()->isLinden(caller_name);
@@ -2697,13 +3005,11 @@ void LLIMMgr::inviteToSession(
//else it's an ad-hoc
//and a voice ad-hoc
notify_box_type = "VoiceInviteAdHoc";
- ad_hoc_invite = TRUE;
voice_invite = TRUE;
}
else if ( inv_type == INVITATION_TYPE_IMMEDIATE )
{
notify_box_type = "InviteAdHoc";
- ad_hoc_invite = TRUE;
}
LLSD payload;
@@ -2739,12 +3045,16 @@ void LLIMMgr::inviteToSession(
if (voice_invite)
{
- if ( // if we are rejecting group calls
- (gSavedSettings.getBOOL("VoiceCallsRejectGroup") && notify_box_type == "VoiceInviteGroup") ||
- // or we're rejecting non-friend voice calls and this isn't a friend
- (gSavedSettings.getBOOL("VoiceCallsFriendsOnly") && (LLAvatarTracker::instance().getBuddyInfo(caller_id) == NULL))
- )
+ bool isRejectGroupCall = (gSavedSettings.getBOOL("VoiceCallsRejectGroup") && (notify_box_type == "VoiceInviteGroup"));
+ bool isRejectNonFriendCall = (gSavedSettings.getBOOL("VoiceCallsFriendsOnly") && (LLAvatarTracker::instance().getBuddyInfo(caller_id) == NULL));
+ if (isRejectGroupCall || isRejectNonFriendCall || gAgent.isDoNotDisturb())
{
+ if (gAgent.isDoNotDisturb() && !isRejectGroupCall && !isRejectNonFriendCall)
+ {
+ LLSD args;
+ addSystemMessage(session_id, "you_auto_rejected_call", args);
+ send_do_not_disturb_message(gMessageSystem, caller_id, session_id);
+ }
// silently decline the call
LLIncomingCallDialog::processCallResponse(1, payload);
return;
@@ -2806,7 +3116,7 @@ void LLIMMgr::clearPendingInvitation(const LLUUID& session_id)
void LLIMMgr::processAgentListUpdates(const LLUUID& session_id, const LLSD& body)
{
- LLIMFloater* im_floater = LLIMFloater::findInstance(session_id);
+ LLFloaterIMSession* im_floater = LLFloaterIMSession::findInstance(session_id);
if ( im_floater )
{
im_floater->processAgentListUpdates(body);
@@ -2912,11 +3222,27 @@ void LLIMMgr::clearPendingAgentListUpdates(const LLUUID& session_id)
}
}
-void LLIMMgr::notifyObserverSessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id)
+void LLIMMgr::notifyObserverSessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id, bool has_offline_msg)
{
for (session_observers_list_t::iterator it = mSessionObservers.begin(); it != mSessionObservers.end(); it++)
{
- (*it)->sessionAdded(session_id, name, other_participant_id);
+ (*it)->sessionAdded(session_id, name, other_participant_id, has_offline_msg);
+ }
+}
+
+void LLIMMgr::notifyObserverSessionActivated(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id)
+{
+ for (session_observers_list_t::iterator it = mSessionObservers.begin(); it != mSessionObservers.end(); it++)
+ {
+ (*it)->sessionActivated(session_id, name, other_participant_id);
+ }
+}
+
+void LLIMMgr::notifyObserverSessionVoiceOrIMStarted(const LLUUID& session_id)
+{
+ for (session_observers_list_t::iterator it = mSessionObservers.begin(); it != mSessionObservers.end(); it++)
+ {
+ (*it)->sessionVoiceOrIMStarted(session_id);
}
}
@@ -3016,7 +3342,7 @@ void LLIMMgr::noteOfflineUsers(
{
LLUIString offline = LLTrans::getString("offline_message");
// Use display name only because this user is your friend
- offline.setArg("[NAME]", av_name.mDisplayName);
+ offline.setArg("[NAME]", av_name.getDisplayName());
im_model.proccessOnlineOfflineNotification(session_id, offline);
}
}
@@ -3064,7 +3390,7 @@ void LLIMMgr::processIMTypingStop(const LLIMInfo* im_info)
void LLIMMgr::processIMTypingCore(const LLIMInfo* im_info, BOOL typing)
{
LLUUID session_id = computeSessionID(im_info->mIMType, im_info->mFromID);
- LLIMFloater* im_floater = LLIMFloater::findInstance(session_id);
+ LLFloaterIMSession* im_floater = LLFloaterIMSession::findInstance(session_id);
if ( im_floater )
{
im_floater->processIMTyping(im_info, typing);
@@ -3109,7 +3435,7 @@ public:
speaker_mgr->updateSpeakers(gIMMgr->getPendingAgentListUpdates(session_id));
}
- LLIMFloater* im_floater = LLIMFloater::findInstance(session_id);
+ LLFloaterIMSession* im_floater = LLFloaterIMSession::findInstance(session_id);
if ( im_floater )
{
if ( body.has("session_info") )
@@ -3203,7 +3529,7 @@ public:
const LLSD& input) const
{
LLUUID session_id = input["body"]["session_id"].asUUID();
- LLIMFloater* im_floater = LLIMFloater::findInstance(session_id);
+ LLFloaterIMSession* im_floater = LLFloaterIMSession::findInstance(session_id);
if ( im_floater )
{
im_floater->processSessionUpdate(input["body"]["info"]);
@@ -3237,7 +3563,6 @@ public:
//just like a normal IM
//this is just replicated code from process_improved_im
//and should really go in it's own function -jwolk
- LLChat chat;
std::string message = message_params["message"].asString();
std::string name = message_params["from_name"].asString();
@@ -3249,20 +3574,11 @@ public:
time_t timestamp =
(time_t) message_params["timestamp"].asInteger();
- BOOL is_busy = gAgent.getBusy();
- BOOL is_muted = LLMuteList::getInstance()->isMuted(
- from_id,
- name,
- LLMute::flagTextChat);
+ BOOL is_do_not_disturb = gAgent.isDoNotDisturb();
- BOOL is_linden = LLMuteList::getInstance()->isLinden(name);
- std::string separator_string(": ");
-
- chat.mMuted = is_muted && !is_linden;
- chat.mFromID = from_id;
- chat.mFromName = name;
-
- if (!is_linden && is_busy)
+ //don't return if user is muted b/c proper way to ignore a muted user who
+ //initiated an adhoc/group conference is to create then leave the session (see STORM-1731)
+ if (is_do_not_disturb)
{
return;
}
@@ -3277,16 +3593,16 @@ public:
}
std::string buffer = saved + message;
- BOOL is_this_agent = FALSE;
if(from_id == gAgentID)
{
- is_this_agent = TRUE;
+ return;
}
gIMMgr->addMessage(
session_id,
from_id,
name,
buffer,
+ IM_OFFLINE == offline,
std::string((char*)&bin_bucket[0]),
IM_SESSION_INVITE,
message_params["parent_estate_id"].asInteger(),
diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h
index 7c2cd03d97..da6039a3ae 100644..100755
--- a/indra/newview/llimview.h
+++ b/indra/newview/llimview.h
@@ -27,7 +27,7 @@
#ifndef LL_LLIMVIEW_H
#define LL_LLIMVIEW_H
-#include "lldockablefloater.h"
+#include "../llui/lldockablefloater.h"
#include "lleventtimer.h"
#include "llinstantmessage.h"
@@ -70,10 +70,11 @@ public:
GROUP_SESSION,
ADHOC_SESSION,
AVALINE_SESSION,
+ NONE_SESSION,
} SType;
LLIMSession(const LLUUID& session_id, const std::string& name,
- const EInstantMessage& type, const LLUUID& other_participant_id, const uuid_vec_t& ids, bool voice);
+ const EInstantMessage& type, const LLUUID& other_participant_id, const uuid_vec_t& ids, bool voice, bool has_offline_msg);
virtual ~LLIMSession();
void sessionInitReplyReceived(const LLUUID& new_session_id);
@@ -84,7 +85,7 @@ public:
/** @deprecated */
static void chatFromLogFile(LLLogChat::ELogLineType type, const LLSD& msg, void* userdata);
- bool isOutgoingAdHoc();
+ bool isOutgoingAdHoc() const;
bool isAdHoc();
bool isP2P();
bool isOtherParticipantAvaline();
@@ -94,10 +95,14 @@ public:
bool isGroupSessionType() const { return mSessionType == GROUP_SESSION;}
bool isAvalineSessionType() const { return mSessionType == AVALINE_SESSION;}
+ LLUUID generateOutgouigAdHocHash() const;
+
//*TODO make private
/** ad-hoc sessions involve sophisticated chat history file naming schemes */
void buildHistoryFileName();
+ void loadHistory();
+
LLUUID mSessionID;
std::string mName;
EInstantMessage mType;
@@ -133,22 +138,18 @@ public:
//if IM session is created for a voice call
bool mStartedAsIMCall;
+ bool mHasOfflineMessage;
+
private:
void onAdHocNameCache(const LLAvatarName& av_name);
- static std::string generateHash(const std::set<LLUUID>& sorted_uuids);
+ static LLUUID generateHash(const std::set<LLUUID>& sorted_uuids);
+ boost::signals2::connection mAvatarNameCacheConnection;
};
LLIMModel();
-
- //we should control the currently active session
- LLUUID mActiveSessionID;
- void setActiveSessionID(const LLUUID& session_id);
- void resetActiveSessionID() { mActiveSessionID.setNull(); }
- LLUUID getActiveSessionID() { return mActiveSessionID; }
-
/** Session id to session object */
std::map<LLUUID, LLIMSession*> mId2SessionMap;
@@ -181,10 +182,10 @@ public:
* @param name session name should not be empty, will return false if empty
*/
bool newSession(const LLUUID& session_id, const std::string& name, const EInstantMessage& type, const LLUUID& other_participant_id,
- const uuid_vec_t& ids, bool voice = false);
+ const uuid_vec_t& ids, bool voice = false, bool has_offline_msg = false);
bool newSession(const LLUUID& session_id, const std::string& name, const EInstantMessage& type,
- const LLUUID& other_participant_id, bool voice = false);
+ const LLUUID& other_participant_id, bool voice = false, bool has_offline_msg = false);
/**
* Remove all session data associated with a session specified by session_id
@@ -192,12 +193,6 @@ public:
bool clearSession(const LLUUID& session_id);
/**
- * Populate supplied std::list with messages starting from index specified by start_index without
- * emitting no unread messages signal.
- */
- void getMessagesSilently(const LLUUID& session_id, std::list<LLSD>& messages, int start_index = 0);
-
- /**
* Sends no unread messages signal.
*/
void sendNoUnreadMessages(const LLUUID& session_id);
@@ -205,7 +200,7 @@ public:
/**
* Populate supplied std::list with messages starting from index specified by start_index
*/
- void getMessages(const LLUUID& session_id, std::list<LLSD>& messages, int start_index = 0);
+ void getMessages(const LLUUID& session_id, std::list<LLSD>& messages, int start_index = 0, const bool sendNoUnreadMsgs = true);
/**
* Add a message to an IM Model - the message is saved in a message store associated with a session specified by session_id
@@ -288,6 +283,12 @@ public:
private:
/**
+ * Populate supplied std::list with messages starting from index specified by start_index without
+ * emitting no unread messages signal.
+ */
+ void getMessagesSilently(const LLUUID& session_id, std::list<LLSD>& messages, int start_index = 0);
+
+ /**
* Add message to a list of message associated with session specified by session_id
*/
bool addToHistory(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, const std::string& utf8_text);
@@ -297,7 +298,9 @@ class LLIMSessionObserver
{
public:
virtual ~LLIMSessionObserver() {}
- virtual void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id) = 0;
+ virtual void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id, BOOL has_offline_msg) = 0;
+ virtual void sessionActivated(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id) = 0;
+ virtual void sessionVoiceOrIMStarted(const LLUUID& session_id) = 0;
virtual void sessionRemoved(const LLUUID& session_id) = 0;
virtual void sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id) = 0;
};
@@ -324,6 +327,7 @@ public:
const LLUUID& target_id,
const std::string& from,
const std::string& msg,
+ bool is_offline_msg = false,
const std::string& session_name = LLStringUtil::null,
EInstantMessage dialog = IM_NOTHING_SPECIAL,
U32 parent_estate_id = 0,
@@ -347,10 +351,12 @@ public:
// Adds a session using a specific group of starting agents
// the dialog type is assumed correct. Returns the uuid of the session.
+ // A session can be added to a floater specified by floater_id.
LLUUID addSession(const std::string& name,
EInstantMessage dialog,
const LLUUID& other_participant_id,
- const LLDynamicArray<LLUUID>& ids, bool voice = false);
+ const LLDynamicArray<LLUUID>& ids, bool voice = false,
+ const LLUUID& floater_id = LLUUID::null);
/**
* Creates a P2P session with the requisite handle for responding to voice calls.
@@ -459,7 +465,10 @@ private:
static void onInviteNameLookup(LLSD payload, const LLUUID& id, const std::string& name, bool is_group);
- void notifyObserverSessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id);
+ void notifyObserverSessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id, bool has_offline_msg);
+ //Triggers when a session has already been added
+ void notifyObserverSessionActivated(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id);
+ void notifyObserverSessionVoiceOrIMStarted(const LLUUID& session_id);
void notifyObserverSessionRemoved(const LLUUID& session_id);
void notifyObserverSessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id);
@@ -541,7 +550,14 @@ class LLIncomingCallDialog : public LLCallDialog
{
public:
LLIncomingCallDialog(const LLSD& payload);
-
+ ~LLIncomingCallDialog()
+ {
+ if (mAvatarNameCacheConnection.connected())
+ {
+ mAvatarNameCacheConnection.disconnect();
+ }
+ }
+
/*virtual*/ BOOL postBuild();
/*virtual*/ void onOpen(const LLSD& key);
@@ -558,6 +574,8 @@ private:
const LLAvatarName& av_name,
const std::string& call_type);
+ boost::signals2::connection mAvatarNameCacheConnection;
+
/*virtual*/ void onLifetimeExpired();
};
diff --git a/indra/newview/llinspect.cpp b/indra/newview/llinspect.cpp
index 14382e82d7..14382e82d7 100644..100755
--- a/indra/newview/llinspect.cpp
+++ b/indra/newview/llinspect.cpp
diff --git a/indra/newview/llinspect.h b/indra/newview/llinspect.h
index 1f6aafc7bd..1f6aafc7bd 100644..100755
--- a/indra/newview/llinspect.h
+++ b/indra/newview/llinspect.h
diff --git a/indra/newview/llinspectavatar.cpp b/indra/newview/llinspectavatar.cpp
index 17d0b0ffbb..9c6db3676f 100644..100755
--- a/indra/newview/llinspectavatar.cpp
+++ b/indra/newview/llinspectavatar.cpp
@@ -29,37 +29,24 @@
// viewer files
#include "llagent.h"
-#include "llagentdata.h"
#include "llavataractions.h"
+#include "llavatariconctrl.h"
#include "llavatarnamecache.h"
#include "llavatarpropertiesprocessor.h"
-#include "llcallingcard.h"
#include "lldateutil.h"
-#include "llfloaterreporter.h"
-#include "llfloaterworldmap.h"
-#include "llimview.h"
#include "llinspect.h"
#include "llmutelist.h"
-#include "llpanelblockedlist.h"
+#include "llslurl.h"
#include "llstartup.h"
-#include "llspeakers.h"
-#include "llviewermenu.h"
#include "llvoiceclient.h"
-#include "llviewerobjectlist.h"
#include "lltransientfloatermgr.h"
-#include "llnotificationsutil.h"
// Linden libraries
#include "llfloater.h"
#include "llfloaterreg.h"
-#include "llmenubutton.h"
#include "lltextbox.h"
-#include "lltoggleablemenu.h"
#include "lltooltip.h" // positionViewNearMouse()
#include "lltrans.h"
-#include "lluictrl.h"
-
-#include "llavatariconctrl.h"
class LLFetchAvatarData;
@@ -80,70 +67,30 @@ public:
// Inspector will be positioned relative to current mouse position
LLInspectAvatar(const LLSD& avatar_id);
virtual ~LLInspectAvatar();
-
+
/*virtual*/ BOOL postBuild(void);
// Because floater is single instance, need to re-parse data on each spawn
// (for example, inspector about same avatar but in different position)
/*virtual*/ void onOpen(const LLSD& avatar_id);
- // When closing they should close their gear menu
- /*virtual*/ void onClose(bool app_quitting);
-
// Update view based on information from avatar properties processor
void processAvatarData(LLAvatarData* data);
- // override the inspector mouse leave so timer is only paused if
- // gear menu is not open
- /* virtual */ void onMouseLeave(S32 x, S32 y, MASK mask);
-
virtual LLTransientFloaterMgr::ETransientGroup getGroup() { return LLTransientFloaterMgr::GLOBAL; }
private:
// Make network requests for all the data to display in this view.
// Used on construction and if avatar id changes.
void requestUpdate();
-
+
// Set the volume slider to this user's current client-side volume setting,
// hiding/disabling if the user is not nearby.
void updateVolumeSlider();
- // Shows/hides moderator panel depending on voice state
- void updateModeratorPanel();
-
- // Moderator ability to enable/disable voice chat for avatar
- void toggleSelectedVoice(bool enabled);
-
// Button callbacks
- void onClickAddFriend();
- void onClickViewProfile();
- void onClickIM();
- void onClickCall();
- void onClickTeleport();
- void onClickInviteToGroup();
- void onClickPay();
- void onClickShare();
- void onToggleMute();
- void onClickReport();
- void onClickFreeze();
- void onClickEject();
- void onClickKick();
- void onClickCSR();
- void onClickZoomIn();
- void onClickFindOnMap();
- bool onVisibleFindOnMap();
- bool onVisibleEject();
- bool onVisibleFreeze();
- bool onVisibleZoomIn();
void onClickMuteVolume();
void onVolumeChange(const LLSD& data);
- bool enableMute();
- bool enableUnmute();
- bool enableTeleportOffer();
- bool godModeEnabled();
-
- // Is used to determine if "Add friend" option should be enabled in gear menu
- bool isNotFriend();
void onAvatarNameCache(const LLUUID& agent_id,
const LLAvatarName& av_name);
@@ -155,6 +102,7 @@ private:
// an in-flight request for avatar properties from LLAvatarPropertiesProcessor
// is represented by this object
LLFetchAvatarData* mPropertiesRequest;
+ boost::signals2::connection mAvatarNameCacheConnection;
};
//////////////////////////////////////////////////////////////////////////////
@@ -207,41 +155,11 @@ LLInspectAvatar::LLInspectAvatar(const LLSD& sd)
: LLInspect( LLSD() ), // single_instance, doesn't really need key
mAvatarID(), // set in onOpen() *Note: we used to show partner's name but we dont anymore --angela 3rd Dec*
mAvatarName(),
- mPropertiesRequest(NULL)
+ mPropertiesRequest(NULL),
+ mAvatarNameCacheConnection()
{
- mCommitCallbackRegistrar.add("InspectAvatar.ViewProfile", boost::bind(&LLInspectAvatar::onClickViewProfile, this));
- mCommitCallbackRegistrar.add("InspectAvatar.AddFriend", boost::bind(&LLInspectAvatar::onClickAddFriend, this));
- mCommitCallbackRegistrar.add("InspectAvatar.IM",
- boost::bind(&LLInspectAvatar::onClickIM, this));
- mCommitCallbackRegistrar.add("InspectAvatar.Call", boost::bind(&LLInspectAvatar::onClickCall, this));
- mCommitCallbackRegistrar.add("InspectAvatar.Teleport", boost::bind(&LLInspectAvatar::onClickTeleport, this));
- mCommitCallbackRegistrar.add("InspectAvatar.InviteToGroup", boost::bind(&LLInspectAvatar::onClickInviteToGroup, this));
- mCommitCallbackRegistrar.add("InspectAvatar.Pay", boost::bind(&LLInspectAvatar::onClickPay, this));
- mCommitCallbackRegistrar.add("InspectAvatar.Share", boost::bind(&LLInspectAvatar::onClickShare, this));
- mCommitCallbackRegistrar.add("InspectAvatar.ToggleMute", boost::bind(&LLInspectAvatar::onToggleMute, this));
- mCommitCallbackRegistrar.add("InspectAvatar.Freeze", boost::bind(&LLInspectAvatar::onClickFreeze, this));
- mCommitCallbackRegistrar.add("InspectAvatar.Eject", boost::bind(&LLInspectAvatar::onClickEject, this));
- mCommitCallbackRegistrar.add("InspectAvatar.Kick", boost::bind(&LLInspectAvatar::onClickKick, this));
- mCommitCallbackRegistrar.add("InspectAvatar.CSR", boost::bind(&LLInspectAvatar::onClickCSR, this));
- mCommitCallbackRegistrar.add("InspectAvatar.Report", boost::bind(&LLInspectAvatar::onClickReport, this));
- mCommitCallbackRegistrar.add("InspectAvatar.FindOnMap", boost::bind(&LLInspectAvatar::onClickFindOnMap, this));
- mCommitCallbackRegistrar.add("InspectAvatar.ZoomIn", boost::bind(&LLInspectAvatar::onClickZoomIn, this));
- mCommitCallbackRegistrar.add("InspectAvatar.DisableVoice", boost::bind(&LLInspectAvatar::toggleSelectedVoice, this, false));
- mCommitCallbackRegistrar.add("InspectAvatar.EnableVoice", boost::bind(&LLInspectAvatar::toggleSelectedVoice, this, true));
-
- mEnableCallbackRegistrar.add("InspectAvatar.EnableGod", boost::bind(&LLInspectAvatar::godModeEnabled, this));
- mEnableCallbackRegistrar.add("InspectAvatar.VisibleFindOnMap", boost::bind(&LLInspectAvatar::onVisibleFindOnMap, this));
- mEnableCallbackRegistrar.add("InspectAvatar.VisibleEject", boost::bind(&LLInspectAvatar::onVisibleEject, this));
- mEnableCallbackRegistrar.add("InspectAvatar.VisibleFreeze", boost::bind(&LLInspectAvatar::onVisibleFreeze, this));
- mEnableCallbackRegistrar.add("InspectAvatar.VisibleZoomIn", boost::bind(&LLInspectAvatar::onVisibleZoomIn, this));
- mEnableCallbackRegistrar.add("InspectAvatar.Gear.Enable", boost::bind(&LLInspectAvatar::isNotFriend, this));
- mEnableCallbackRegistrar.add("InspectAvatar.Gear.EnableCall", boost::bind(&LLAvatarActions::canCall));
- mEnableCallbackRegistrar.add("InspectAvatar.Gear.EnableTeleportOffer", boost::bind(&LLInspectAvatar::enableTeleportOffer, this));
- mEnableCallbackRegistrar.add("InspectAvatar.EnableMute", boost::bind(&LLInspectAvatar::enableMute, this));
- mEnableCallbackRegistrar.add("InspectAvatar.EnableUnmute", boost::bind(&LLInspectAvatar::enableUnmute, this));
-
// can't make the properties request until the widgets are constructed
- // as it might return immediately, so do it in postBuild.
+ // as it might return immediately, so do it in onOpen.
LLTransientFloaterMgr::getInstance()->addControlView(LLTransientFloaterMgr::GLOBAL, this);
LLTransientFloater::init(this);
@@ -249,6 +167,10 @@ LLInspectAvatar::LLInspectAvatar(const LLSD& sd)
LLInspectAvatar::~LLInspectAvatar()
{
+ if (mAvatarNameCacheConnection.connected())
+ {
+ mAvatarNameCacheConnection.disconnect();
+ }
// clean up any pending requests so they don't call back into a deleted
// view
delete mPropertiesRequest;
@@ -260,12 +182,6 @@ LLInspectAvatar::~LLInspectAvatar()
/*virtual*/
BOOL LLInspectAvatar::postBuild(void)
{
- getChild<LLUICtrl>("add_friend_btn")->setCommitCallback(
- boost::bind(&LLInspectAvatar::onClickAddFriend, this) );
-
- getChild<LLUICtrl>("view_profile_btn")->setCommitCallback(
- boost::bind(&LLInspectAvatar::onClickViewProfile, this) );
-
getChild<LLUICtrl>("mute_btn")->setCommitCallback(
boost::bind(&LLInspectAvatar::onClickMuteVolume, this) );
@@ -275,7 +191,6 @@ BOOL LLInspectAvatar::postBuild(void)
return TRUE;
}
-
// Multiple calls to showInstance("inspect_avatar", foo) will provide different
// LLSD for foo, which we will catch here.
//virtual
@@ -287,11 +202,6 @@ void LLInspectAvatar::onOpen(const LLSD& data)
// Extract appropriate avatar id
mAvatarID = data["avatar_id"];
- BOOL self = mAvatarID == gAgent.getID();
-
- getChild<LLUICtrl>("gear_self_btn")->setVisible(self);
- getChild<LLUICtrl>("gear_btn")->setVisible(!self);
-
// Position the inspector relative to the mouse cursor
// Similar to how tooltips are positioned
// See LLToolTipMgr::createToolTip
@@ -304,20 +214,15 @@ void LLInspectAvatar::onOpen(const LLSD& data)
LLUI::positionViewNearMouse(this);
}
+ // Generate link to avatar profile.
+ getChild<LLUICtrl>("avatar_profile_link")->setTextArg("[LINK]", LLSLURL("agent", mAvatarID, "about").getSLURLString());
+
// can't call from constructor as widgets are not built yet
requestUpdate();
updateVolumeSlider();
-
- updateModeratorPanel();
}
-// virtual
-void LLInspectAvatar::onClose(bool app_quitting)
-{
- getChild<LLMenuButton>("gear_btn")->hideMenu();
-}
-
void LLInspectAvatar::requestUpdate()
{
// Don't make network requests when spawning from the debug menu at the
@@ -344,25 +249,6 @@ void LLInspectAvatar::requestUpdate()
delete mPropertiesRequest;
mPropertiesRequest = new LLFetchAvatarData(mAvatarID, this);
- // You can't re-add someone as a friend if they are already your friend
- bool is_friend = LLAvatarTracker::instance().getBuddyInfo(mAvatarID) != NULL;
- bool is_self = (mAvatarID == gAgentID);
- if (is_self)
- {
- getChild<LLUICtrl>("add_friend_btn")->setVisible(false);
- getChild<LLUICtrl>("im_btn")->setVisible(false);
- }
- else if (is_friend)
- {
- getChild<LLUICtrl>("add_friend_btn")->setVisible(false);
- getChild<LLUICtrl>("im_btn")->setVisible(true);
- }
- else
- {
- getChild<LLUICtrl>("add_friend_btn")->setVisible(true);
- getChild<LLUICtrl>("im_btn")->setVisible(false);
- }
-
// Use an avatar_icon even though the image id will come down with the
// avatar properties because the avatar_icon code maintains a cache of icons
// and this may result in the image being visible sooner.
@@ -374,9 +260,11 @@ void LLInspectAvatar::requestUpdate()
getChild<LLUICtrl>("avatar_icon")->setValue(LLSD(mAvatarID) );
- LLAvatarNameCache::get(mAvatarID,
- boost::bind(&LLInspectAvatar::onAvatarNameCache,
- this, _1, _2));
+ if (mAvatarNameCacheConnection.connected())
+ {
+ mAvatarNameCacheConnection.disconnect();
+ }
+ mAvatarNameCacheConnection = LLAvatarNameCache::get(mAvatarID,boost::bind(&LLInspectAvatar::onAvatarNameCache,this, _1, _2));
}
void LLInspectAvatar::processAvatarData(LLAvatarData* data)
@@ -404,141 +292,11 @@ void LLInspectAvatar::processAvatarData(LLAvatarData* data)
delete mPropertiesRequest;
mPropertiesRequest = NULL;
}
-
-// For the avatar inspector, we only want to unpause the fade timer
-// if neither the gear menu or self gear menu are open
-void LLInspectAvatar::onMouseLeave(S32 x, S32 y, MASK mask)
-{
- LLToggleableMenu* gear_menu = getChild<LLMenuButton>("gear_btn")->getMenu();
- LLToggleableMenu* gear_menu_self = getChild<LLMenuButton>("gear_self_btn")->getMenu();
- if ( gear_menu && gear_menu->getVisible() &&
- gear_menu_self && gear_menu_self->getVisible() )
- {
- return;
- }
-
- if(childHasVisiblePopupMenu())
- {
- return;
- }
-
- mOpenTimer.unpause();
-}
-
-void LLInspectAvatar::updateModeratorPanel()
-{
- bool enable_moderator_panel = false;
-
- if (LLVoiceChannel::getCurrentVoiceChannel() &&
- mAvatarID != gAgent.getID())
- {
- LLUUID session_id = LLVoiceChannel::getCurrentVoiceChannel()->getSessionID();
-
- if (session_id != LLUUID::null)
- {
- LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(session_id);
-
- if (speaker_mgr)
- {
- LLPointer<LLSpeaker> self_speakerp = speaker_mgr->findSpeaker(gAgent.getID());
- LLPointer<LLSpeaker> selected_speakerp = speaker_mgr->findSpeaker(mAvatarID);
-
- if(speaker_mgr->isVoiceActive() && selected_speakerp &&
- selected_speakerp->isInVoiceChannel() &&
- ((self_speakerp && self_speakerp->mIsModerator) || gAgent.isGodlike()))
- {
- getChild<LLUICtrl>("enable_voice")->setVisible(selected_speakerp->mModeratorMutedVoice);
- getChild<LLUICtrl>("disable_voice")->setVisible(!selected_speakerp->mModeratorMutedVoice);
-
- enable_moderator_panel = true;
- }
- }
- }
- }
-
- if (enable_moderator_panel)
- {
- if (!getChild<LLUICtrl>("moderator_panel")->getVisible())
- {
- getChild<LLUICtrl>("moderator_panel")->setVisible(true);
- // stretch the floater so it can accommodate the moderator panel
- reshape(getRect().getWidth(), getRect().getHeight() + getChild<LLUICtrl>("moderator_panel")->getRect().getHeight());
- }
- }
- else if (getChild<LLUICtrl>("moderator_panel")->getVisible())
- {
- getChild<LLUICtrl>("moderator_panel")->setVisible(false);
- // shrink the inspector floater back to original size
- reshape(getRect().getWidth(), getRect().getHeight() - getChild<LLUICtrl>("moderator_panel")->getRect().getHeight());
- }
-}
-
-void LLInspectAvatar::toggleSelectedVoice(bool enabled)
-{
- LLUUID session_id = LLVoiceChannel::getCurrentVoiceChannel()->getSessionID();
- LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(session_id);
-
- if (speaker_mgr)
- {
- if (!gAgent.getRegion())
- return;
-
- std::string url = gAgent.getRegion()->getCapability("ChatSessionRequest");
- LLSD data;
- data["method"] = "mute update";
- data["session-id"] = session_id;
- data["params"] = LLSD::emptyMap();
- data["params"]["agent_id"] = mAvatarID;
- data["params"]["mute_info"] = LLSD::emptyMap();
- // ctrl value represents ability to type, so invert
- data["params"]["mute_info"]["voice"] = !enabled;
-
- class MuteVoiceResponder : public LLHTTPClient::Responder
- {
- public:
- MuteVoiceResponder(const LLUUID& session_id)
- {
- mSessionID = session_id;
- }
-
- virtual void error(U32 status, const std::string& reason)
- {
- llwarns << status << ": " << reason << llendl;
-
- if ( gIMMgr )
- {
- //403 == you're not a mod
- //should be disabled if you're not a moderator
- if ( 403 == status )
- {
- gIMMgr->showSessionEventError(
- "mute",
- "not_a_moderator",
- mSessionID);
- }
- else
- {
- gIMMgr->showSessionEventError(
- "mute",
- "generic",
- mSessionID);
- }
- }
- }
-
- private:
- LLUUID mSessionID;
- };
-
- LLHTTPClient::post(
- url,
- data,
- new MuteVoiceResponder(speaker_mgr->getSessionID()));
- }
-
- closeFloater();
-
-}
+/*
+prep#
+ virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content)
+ llwarns << "MuteVoiceResponder error [status:" << status << "]: " << content << llendl;
+ */
void LLInspectAvatar::updateVolumeSlider()
{
@@ -558,12 +316,11 @@ void LLInspectAvatar::updateVolumeSlider()
getChild<LLUICtrl>("volume_slider")->setVisible(true);
// By convention, we only display and toggle voice mutes, not all mutes
- bool is_muted = LLMuteList::getInstance()->
- isMuted(mAvatarID, LLMute::flagVoiceChat);
+ bool is_muted = LLAvatarActions::isVoiceMuted(mAvatarID);
LLUICtrl* mute_btn = getChild<LLUICtrl>("mute_btn");
- bool is_linden = LLStringUtil::endsWith(mAvatarName.getLegacyName(), " Linden");
+ bool is_linden = LLStringUtil::endsWith(mAvatarName.getDisplayName(), " Linden");
mute_btn->setEnabled( !is_linden);
mute_btn->setValue( is_muted );
@@ -594,7 +351,7 @@ void LLInspectAvatar::onClickMuteVolume()
LLMuteList* mute_list = LLMuteList::getInstance();
bool is_muted = mute_list->isMuted(mAvatarID, LLMute::flagVoiceChat);
- LLMute mute(mAvatarID, mAvatarName.getLegacyName(), LLMute::AGENT);
+ LLMute mute(mAvatarID, mAvatarName.getDisplayName(), LLMute::AGENT);
if (!is_muted)
{
mute_list->add(mute, LLMute::flagVoiceChat);
@@ -617,11 +374,13 @@ void LLInspectAvatar::onAvatarNameCache(
const LLUUID& agent_id,
const LLAvatarName& av_name)
{
+ mAvatarNameCacheConnection.disconnect();
+
if (agent_id == mAvatarID)
{
- getChild<LLUICtrl>("user_name")->setValue(av_name.mDisplayName);
- getChild<LLUICtrl>("user_name_small")->setValue(av_name.mDisplayName);
- getChild<LLUICtrl>("user_slid")->setValue(av_name.mUsername);
+ getChild<LLUICtrl>("user_name")->setValue(av_name.getDisplayName());
+ getChild<LLUICtrl>("user_name_small")->setValue(av_name.getDisplayName());
+ getChild<LLUICtrl>("user_slid")->setValue(av_name.getUserName());
mAvatarName = av_name;
// show smaller display name if too long to display in regular size
@@ -640,215 +399,6 @@ void LLInspectAvatar::onAvatarNameCache(
}
}
-void LLInspectAvatar::onClickAddFriend()
-{
- LLAvatarActions::requestFriendshipDialog(mAvatarID, mAvatarName.getLegacyName());
- closeFloater();
-}
-
-void LLInspectAvatar::onClickViewProfile()
-{
- LLAvatarActions::showProfile(mAvatarID);
- closeFloater();
-}
-
-bool LLInspectAvatar::isNotFriend()
-{
- return !LLAvatarActions::isFriend(mAvatarID);
-}
-
-bool LLInspectAvatar::onVisibleFindOnMap()
-{
- return gAgent.isGodlike() || is_agent_mappable(mAvatarID);
-}
-
-bool LLInspectAvatar::onVisibleEject()
-{
- return enable_freeze_eject( LLSD(mAvatarID) );
-}
-
-bool LLInspectAvatar::onVisibleFreeze()
-{
- // either user is a god and can do long distance freeze
- // or check for target proximity and permissions
- return gAgent.isGodlike() || enable_freeze_eject(LLSD(mAvatarID));
-}
-
-bool LLInspectAvatar::onVisibleZoomIn()
-{
- return gObjectList.findObject(mAvatarID);
-}
-
-void LLInspectAvatar::onClickIM()
-{
- LLAvatarActions::startIM(mAvatarID);
- closeFloater();
-}
-
-void LLInspectAvatar::onClickCall()
-{
- LLAvatarActions::startCall(mAvatarID);
- closeFloater();
-}
-
-void LLInspectAvatar::onClickTeleport()
-{
- LLAvatarActions::offerTeleport(mAvatarID);
- closeFloater();
-}
-
-void LLInspectAvatar::onClickInviteToGroup()
-{
- LLAvatarActions::inviteToGroup(mAvatarID);
- closeFloater();
-}
-
-void LLInspectAvatar::onClickPay()
-{
- LLAvatarActions::pay(mAvatarID);
- closeFloater();
-}
-
-void LLInspectAvatar::onClickShare()
-{
- LLAvatarActions::share(mAvatarID);
- closeFloater();
-}
-
-void LLInspectAvatar::onToggleMute()
-{
- LLMute mute(mAvatarID, mAvatarName.mDisplayName, LLMute::AGENT);
-
- if (LLMuteList::getInstance()->isMuted(mute.mID, mute.mName))
- {
- LLMuteList::getInstance()->remove(mute);
- }
- else
- {
- LLMuteList::getInstance()->add(mute);
- }
-
- LLPanelBlockedList::showPanelAndSelect(mute.mID);
- closeFloater();
-}
-
-void LLInspectAvatar::onClickReport()
-{
- LLFloaterReporter::showFromAvatar(mAvatarID, mAvatarName.getCompleteName());
- closeFloater();
-}
-
-bool godlike_freeze(const LLSD& notification, const LLSD& response)
-{
- LLUUID avatar_id = notification["payload"]["avatar_id"].asUUID();
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
-
- switch (option)
- {
- case 0:
- LLAvatarActions::freeze(avatar_id);
- break;
- case 1:
- LLAvatarActions::unfreeze(avatar_id);
- break;
- default:
- break;
- }
-
- return false;
-}
-
-void LLInspectAvatar::onClickFreeze()
-{
- if (gAgent.isGodlike())
- {
- // use godlike freeze-at-a-distance, with confirmation
- LLNotificationsUtil::add("FreezeAvatar",
- LLSD(),
- LLSD().with("avatar_id", mAvatarID),
- godlike_freeze);
- }
- else
- {
- // use default "local" version of freezing that requires avatar to be in range
- handle_avatar_freeze( LLSD(mAvatarID) );
- }
- closeFloater();
-}
-
-void LLInspectAvatar::onClickEject()
-{
- handle_avatar_eject( LLSD(mAvatarID) );
- closeFloater();
-}
-
-void LLInspectAvatar::onClickKick()
-{
- LLAvatarActions::kick(mAvatarID);
- closeFloater();
-}
-
-void LLInspectAvatar::onClickCSR()
-{
- std::string name;
- gCacheName->getFullName(mAvatarID, name);
- LLAvatarActions::csr(mAvatarID, name);
- closeFloater();
-}
-
-void LLInspectAvatar::onClickZoomIn()
-{
- handle_zoom_to_object(mAvatarID);
- closeFloater();
-}
-
-void LLInspectAvatar::onClickFindOnMap()
-{
- gFloaterWorldMap->trackAvatar(mAvatarID, mAvatarName.mDisplayName);
- LLFloaterReg::showInstance("world_map");
-}
-
-
-bool LLInspectAvatar::enableMute()
-{
- bool is_linden = LLStringUtil::endsWith(mAvatarName.getLegacyName(), " Linden");
- bool is_self = mAvatarID == gAgent.getID();
-
- if (!is_linden && !is_self && !LLMuteList::getInstance()->isMuted(mAvatarID, mAvatarName.getLegacyName()))
- {
- return true;
- }
- else
- {
- return false;
- }
-}
-
-bool LLInspectAvatar::enableUnmute()
-{
- bool is_linden = LLStringUtil::endsWith(mAvatarName.getLegacyName(), " Linden");
- bool is_self = mAvatarID == gAgent.getID();
-
- if (!is_linden && !is_self && LLMuteList::getInstance()->isMuted(mAvatarID, mAvatarName.getLegacyName()))
- {
- return true;
- }
- else
- {
- return false;
- }
-}
-
-bool LLInspectAvatar::enableTeleportOffer()
-{
- return LLAvatarActions::canOfferTeleport(mAvatarID);
-}
-
-bool LLInspectAvatar::godModeEnabled()
-{
- return gAgent.isGodlike();
-}
-
//////////////////////////////////////////////////////////////////////////////
// LLInspectAvatarUtil
//////////////////////////////////////////////////////////////////////////////
diff --git a/indra/newview/llinspectavatar.h b/indra/newview/llinspectavatar.h
index 4329504b62..4329504b62 100644..100755
--- a/indra/newview/llinspectavatar.h
+++ b/indra/newview/llinspectavatar.h
diff --git a/indra/newview/llinspectgroup.cpp b/indra/newview/llinspectgroup.cpp
index 76617b55bf..76617b55bf 100644..100755
--- a/indra/newview/llinspectgroup.cpp
+++ b/indra/newview/llinspectgroup.cpp
diff --git a/indra/newview/llinspectgroup.h b/indra/newview/llinspectgroup.h
index 8b135a465e..8b135a465e 100644..100755
--- a/indra/newview/llinspectgroup.h
+++ b/indra/newview/llinspectgroup.h
diff --git a/indra/newview/llinspectobject.cpp b/indra/newview/llinspectobject.cpp
index acc139c569..a7b93b8030 100644..100755
--- a/indra/newview/llinspectobject.cpp
+++ b/indra/newview/llinspectobject.cpp
@@ -111,6 +111,7 @@ private:
private:
LLUUID mObjectID;
+ LLUUID mPreviousObjectID;
S32 mObjectFace;
viewer_media_t mMediaImpl;
LLMediaEntry* mMediaEntry;
@@ -249,6 +250,7 @@ void LLInspectObject::onClose(bool app_quitting)
{
// Release selection to deselect
mObjectSelection = NULL;
+ mPreviousObjectID = mObjectID;
getChild<LLMenuButton>("gear_btn")->hideMenu();
}
@@ -266,6 +268,13 @@ void LLInspectObject::update()
LLSelectNode* nodep = selection->getFirstRootNode();
if (!nodep) return;
+ // If we don't have fresh object info yet and it's the object we inspected last time,
+ // keep showing the previously retrieved data until we get the update.
+ if (!nodep->mValid && nodep->getObject()->getID() == mPreviousObjectID)
+ {
+ return;
+ }
+
updateButtons(nodep);
updateName(nodep);
updateDescription(nodep);
diff --git a/indra/newview/llinspectobject.h b/indra/newview/llinspectobject.h
index 9362139458..9362139458 100644..100755
--- a/indra/newview/llinspectobject.h
+++ b/indra/newview/llinspectobject.h
diff --git a/indra/newview/llinspectremoteobject.cpp b/indra/newview/llinspectremoteobject.cpp
index a12ec390af..a12ec390af 100644..100755
--- a/indra/newview/llinspectremoteobject.cpp
+++ b/indra/newview/llinspectremoteobject.cpp
diff --git a/indra/newview/llinspectremoteobject.h b/indra/newview/llinspectremoteobject.h
index 173efd1c0c..173efd1c0c 100644..100755
--- a/indra/newview/llinspectremoteobject.h
+++ b/indra/newview/llinspectremoteobject.h
diff --git a/indra/newview/llinspecttoast.cpp b/indra/newview/llinspecttoast.cpp
index f4fe5dec01..f4fe5dec01 100644..100755
--- a/indra/newview/llinspecttoast.cpp
+++ b/indra/newview/llinspecttoast.cpp
diff --git a/indra/newview/llinspecttoast.h b/indra/newview/llinspecttoast.h
index 441dffdfde..441dffdfde 100644..100755
--- a/indra/newview/llinspecttoast.h
+++ b/indra/newview/llinspecttoast.h
diff --git a/indra/newview/llinventoryactions.h b/indra/newview/llinventoryactions.h
index 96e9f42ca4..96e9f42ca4 100644..100755
--- a/indra/newview/llinventoryactions.h
+++ b/indra/newview/llinventoryactions.h
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index b86c453d61..80ef506272 100644..100755
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -37,6 +37,7 @@
#include "llappearancemgr.h"
#include "llattachmentsmgr.h"
#include "llavataractions.h"
+#include "llfavoritesbar.h" // management of favorites folder
#include "llfloateropenobject.h"
#include "llfloaterreg.h"
#include "llfloatersidepanelcontainer.h"
@@ -45,11 +46,12 @@
#include "llfriendcard.h"
#include "llgesturemgr.h"
#include "llgiveinventory.h"
-#include "llimfloater.h"
+#include "llfloaterimcontainer.h"
#include "llimview.h"
#include "llclipboard.h"
#include "llinventorydefines.h"
#include "llinventoryfunctions.h"
+#include "llinventoryicon.h"
#include "llinventorymodel.h"
#include "llinventorymodelbackgroundfetch.h"
#include "llinventorypanel.h"
@@ -71,6 +73,9 @@
#include "llviewerwindow.h"
#include "llvoavatarself.h"
#include "llwearablelist.h"
+#include "lllandmarkactions.h"
+
+void copy_slurl_to_clipboard_callback_inv(const std::string& slurl);
// Marketplace outbox current disabled
#define ENABLE_MERCHANT_OUTBOX_CONTEXT_MENU 1
@@ -91,34 +96,17 @@ struct LLMoveInv
using namespace LLOldEvents;
-// Helpers
-// bug in busy count inc/dec right now, logic is complex... do we really need it?
-void inc_busy_count()
-{
-// gViewerWindow->getWindow()->incBusyCount();
-// check balance of these calls if this code is changed to ever actually
-// *do* something!
-}
-void dec_busy_count()
-{
-// gViewerWindow->getWindow()->decBusyCount();
-// check balance of these calls if this code is changed to ever actually
-// *do* something!
-}
-
// Function declarations
-void remove_inventory_category_from_avatar(LLInventoryCategory* category);
-void remove_inventory_category_from_avatar_step2( BOOL proceed, LLUUID category_id);
bool move_task_inventory_callback(const LLSD& notification, const LLSD& response, LLMoveInv*);
bool confirm_attachment_rez(const LLSD& notification, const LLSD& response);
void teleport_via_landmark(const LLUUID& asset_id);
static BOOL can_move_to_outfit(LLInventoryItem* inv_item, BOOL move_is_into_current_outfit);
static bool check_category(LLInventoryModel* model,
const LLUUID& cat_id,
- LLFolderView* active_folder_view,
+ LLInventoryPanel* active_panel,
LLInventoryFilter* filter);
static bool check_item(const LLUUID& item_id,
- LLFolderView* active_folder_view,
+ LLInventoryPanel* active_panel,
LLInventoryFilter* filter);
// Helper functions
@@ -166,7 +154,6 @@ public:
{
if (clear_observer)
{
- dec_busy_count();
gInventory.removeObserver(this);
delete this;
}
@@ -189,7 +176,8 @@ LLInvFVBridge::LLInvFVBridge(LLInventoryPanel* inventory,
mUUID(uuid),
mRoot(root),
mInvType(LLInventoryType::IT_NONE),
- mIsLink(FALSE)
+ mIsLink(FALSE),
+ LLFolderViewModelItemInventory(inventory->getRootViewModel())
{
mInventoryPanel = inventory->getInventoryPanelHandle();
const LLInventoryObject* obj = getInventoryObject();
@@ -208,7 +196,11 @@ const std::string& LLInvFVBridge::getName() const
const std::string& LLInvFVBridge::getDisplayName() const
{
- return getName();
+ if(mDisplayName.empty())
+ {
+ buildDisplayName();
+ }
+ return mDisplayName;
}
// Folders have full perms
@@ -227,9 +219,24 @@ LLFolderType::EType LLInvFVBridge::getPreferredType() const
// Folders don't have creation dates.
time_t LLInvFVBridge::getCreationDate() const
{
- return 0;
+ LLInventoryObject* objectp = getInventoryObject();
+ if (objectp)
+ {
+ return objectp->getCreationDate();
+ }
+ return (time_t)0;
+}
+
+void LLInvFVBridge::setCreationDate(time_t creation_date_utc)
+{
+ LLInventoryObject* objectp = getInventoryObject();
+ if (objectp)
+ {
+ objectp->setCreationDate(creation_date_utc);
+ }
}
+
// Can be destroyed (or moved to trash)
BOOL LLInvFVBridge::isItemRemovable() const
{
@@ -247,6 +254,11 @@ BOOL LLInvFVBridge::isLink() const
return mIsLink;
}
+BOOL LLInvFVBridge::isLibraryItem() const
+{
+ return gInventory.isObjectDescendentOf(getUUID(),gInventory.getLibraryRootFolderID());
+}
+
/*virtual*/
/**
* @brief Adds this item into clipboard storage
@@ -283,7 +295,7 @@ void LLInvFVBridge::showProperties()
*/
}
-void LLInvFVBridge::removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batch)
+void LLInvFVBridge::removeBatch(std::vector<LLFolderViewModelItem*>& batch)
{
// Deactivate gestures when moving them into Trash
LLInvFVBridge* bridge;
@@ -292,11 +304,11 @@ void LLInvFVBridge::removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batc
LLViewerInventoryCategory* cat = NULL;
LLInventoryModel::cat_array_t descendent_categories;
LLInventoryModel::item_array_t descendent_items;
- S32 count = batch.count();
+ S32 count = batch.size();
S32 i,j;
for(i = 0; i < count; ++i)
{
- bridge = (LLInvFVBridge*)(batch.get(i));
+ bridge = (LLInvFVBridge*)(batch[i]);
if(!bridge || !bridge->isItemRemovable()) continue;
item = (LLViewerInventoryItem*)model->getItem(bridge->getUUID());
if (item)
@@ -309,7 +321,7 @@ void LLInvFVBridge::removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batc
}
for(i = 0; i < count; ++i)
{
- bridge = (LLInvFVBridge*)(batch.get(i));
+ bridge = (LLInvFVBridge*)(batch[i]);
if(!bridge || !bridge->isItemRemovable()) continue;
cat = (LLViewerInventoryCategory*)model->getCategory(bridge->getUUID());
if (cat)
@@ -327,7 +339,7 @@ void LLInvFVBridge::removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batc
removeBatchNoCheck(batch);
}
-void LLInvFVBridge::removeBatchNoCheck(LLDynamicArray<LLFolderViewEventListener*>& batch)
+void LLInvFVBridge::removeBatchNoCheck(std::vector<LLFolderViewModelItem*>& batch)
{
// this method moves a bunch of items and folders to the trash. As
// per design guidelines for the inventory model, the message is
@@ -343,14 +355,14 @@ void LLInvFVBridge::removeBatchNoCheck(LLDynamicArray<LLFolderViewEventListener*
uuid_vec_t move_ids;
LLInventoryModel::update_map_t update;
bool start_new_message = true;
- S32 count = batch.count();
+ S32 count = batch.size();
S32 i;
// first, hide any 'preview' floaters that correspond to the items
// being deleted.
for(i = 0; i < count; ++i)
{
- bridge = (LLInvFVBridge*)(batch.get(i));
+ bridge = (LLInvFVBridge*)(batch[i]);
if(!bridge || !bridge->isItemRemovable()) continue;
item = (LLViewerInventoryItem*)model->getItem(bridge->getUUID());
if(item)
@@ -363,7 +375,7 @@ void LLInvFVBridge::removeBatchNoCheck(LLDynamicArray<LLFolderViewEventListener*
for(i = 0; i < count; ++i)
{
- bridge = (LLInvFVBridge*)(batch.get(i));
+ bridge = (LLInvFVBridge*)(batch[i]);
if(!bridge || !bridge->isItemRemovable()) continue;
item = (LLViewerInventoryItem*)model->getItem(bridge->getUUID());
if(item)
@@ -404,7 +416,7 @@ void LLInvFVBridge::removeBatchNoCheck(LLDynamicArray<LLFolderViewEventListener*
for(i = 0; i < count; ++i)
{
- bridge = (LLInvFVBridge*)(batch.get(i));
+ bridge = (LLInvFVBridge*)(batch[i]);
if(!bridge || !bridge->isItemRemovable()) continue;
LLViewerInventoryCategory* cat = (LLViewerInventoryCategory*)model->getCategory(bridge->getUUID());
if(cat)
@@ -498,8 +510,10 @@ BOOL LLInvFVBridge::isClipboardPasteable() const
// Each item must be copyable to be pastable
LLItemBridge item_br(mInventoryPanel.get(), mRoot, item_id);
if (!item_br.isItemCopyable())
- return FALSE;
- }
+ {
+ return FALSE;
+ }
+ }
return TRUE;
}
@@ -876,6 +890,12 @@ LLInventoryModel* LLInvFVBridge::getInventoryModel() const
return panel ? panel->getModel() : NULL;
}
+LLInventoryFilter* LLInvFVBridge::getInventoryFilter() const
+{
+ LLInventoryPanel* panel = mInventoryPanel.get();
+ return panel ? &(panel->getFilter()) : NULL;
+}
+
BOOL LLInvFVBridge::isItemInTrash() const
{
LLInventoryModel* model = getInventoryModel();
@@ -928,7 +948,7 @@ BOOL LLInvFVBridge::isCOFFolder() const
BOOL LLInvFVBridge::isInboxFolder() const
{
- const LLUUID inbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX, false, false);
+ const LLUUID inbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX, false);
if (inbox_id.isNull())
{
@@ -968,7 +988,7 @@ BOOL LLInvFVBridge::isOutboxFolderDirectParent() const
const LLUUID LLInvFVBridge::getOutboxFolder() const
{
- const LLUUID outbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false, false);
+ const LLUUID outbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false);
return outbox_id;
}
@@ -1000,6 +1020,7 @@ LLInvFVBridge* LLInvFVBridge::createBridge(LLAssetType::EType asset_type,
LLAssetType::EType actual_asset_type,
LLInventoryType::EType inv_type,
LLInventoryPanel* inventory,
+ LLFolderViewModelInventory* view_model,
LLFolderView* root,
const LLUUID& uuid,
U32 flags)
@@ -1250,10 +1271,10 @@ bool LLInvFVBridge::canListOnMarketplaceNow() const
if (can_list)
{
- LLFolderViewFolder * object_folderp = mRoot->getFolderByID(object_id);
+ LLFolderViewFolder * object_folderp = mInventoryPanel.get() ? mInventoryPanel.get()->getFolderByID(object_id) : NULL;
if (object_folderp)
{
- can_list = !object_folderp->isLoading();
+ can_list = !static_cast<LLFolderBridge*>(object_folderp->getViewModelItem())->isLoading();
}
}
@@ -1261,7 +1282,7 @@ bool LLInvFVBridge::canListOnMarketplaceNow() const
{
// Get outbox id
const LLUUID & outbox_id = getInventoryModel()->findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false);
- LLFolderViewItem * outbox_itemp = mRoot->getItemByID(outbox_id);
+ LLFolderViewItem * outbox_itemp = mInventoryPanel.get() ? mInventoryPanel.get()->getItemByID(outbox_id) : NULL;
if (outbox_itemp)
{
@@ -1271,7 +1292,7 @@ bool LLInvFVBridge::canListOnMarketplaceNow() const
void * cargo_data = (void *) obj;
std::string tooltip_msg;
- can_list = outbox_itemp->getListener()->dragOrDrop(mask, drop, cargo_type, cargo_data, tooltip_msg);
+ can_list = outbox_itemp->getViewModelItem()->dragOrDrop(mask, drop, cargo_type, cargo_data, tooltip_msg);
}
}
}
@@ -1283,14 +1304,30 @@ bool LLInvFVBridge::canListOnMarketplaceNow() const
#endif
}
+LLToolDragAndDrop::ESource LLInvFVBridge::getDragSource() const
+{
+ if (gInventory.isObjectDescendentOf(getUUID(), gInventory.getRootFolderID()))
+ {
+ return LLToolDragAndDrop::SOURCE_AGENT;
+ }
+ else if (gInventory.isObjectDescendentOf(getUUID(), gInventory.getLibraryRootFolderID()))
+ {
+ return LLToolDragAndDrop::SOURCE_LIBRARY;
+ }
+
+ return LLToolDragAndDrop::SOURCE_VIEWER;
+}
+
+
// +=================================================+
// | InventoryFVBridgeBuilder |
// +=================================================+
-LLInvFVBridge* LLInventoryFVBridgeBuilder::createBridge(LLAssetType::EType asset_type,
+LLInvFVBridge* LLInventoryFolderViewModelBuilder::createBridge(LLAssetType::EType asset_type,
LLAssetType::EType actual_asset_type,
LLInventoryType::EType inv_type,
LLInventoryPanel* inventory,
+ LLFolderViewModelInventory* view_model,
LLFolderView* root,
const LLUUID& uuid,
U32 flags /* = 0x00 */) const
@@ -1299,6 +1336,7 @@ LLInvFVBridge* LLInventoryFVBridgeBuilder::createBridge(LLAssetType::EType asset
actual_asset_type,
inv_type,
inventory,
+ view_model,
root,
uuid,
flags);
@@ -1355,7 +1393,7 @@ void LLItemBridge::performAction(LLInventoryModel* model, std::string action)
else if ("cut" == action)
{
cutToClipboard();
- LLFolderView::removeCutItems();
+ gInventory.removeObject(mUUID);
return;
}
else if ("copy" == action)
@@ -1368,10 +1406,10 @@ void LLItemBridge::performAction(LLInventoryModel* model, std::string action)
LLInventoryItem* itemp = model->getItem(mUUID);
if (!itemp) return;
- LLFolderViewItem* folder_view_itemp = mRoot->getItemByID(itemp->getParentUUID());
+ LLFolderViewItem* folder_view_itemp = mInventoryPanel.get()->getItemByID(itemp->getParentUUID());
if (!folder_view_itemp) return;
- folder_view_itemp->getListener()->pasteFromClipboard();
+ folder_view_itemp->getViewModelItem()->pasteFromClipboard();
return;
}
else if ("paste_link" == action)
@@ -1380,10 +1418,10 @@ void LLItemBridge::performAction(LLInventoryModel* model, std::string action)
LLInventoryItem* itemp = model->getItem(mUUID);
if (!itemp) return;
- LLFolderViewItem* folder_view_itemp = mRoot->getItemByID(itemp->getParentUUID());
+ LLFolderViewItem* folder_view_itemp = mInventoryPanel.get()->getItemByID(itemp->getParentUUID());
if (!folder_view_itemp) return;
- folder_view_itemp->getListener()->pasteLinkFromClipboard();
+ folder_view_itemp->getViewModelItem()->pasteLinkFromClipboard();
return;
}
else if (isMarketplaceCopyAction(action))
@@ -1393,9 +1431,32 @@ void LLItemBridge::performAction(LLInventoryModel* model, std::string action)
LLInventoryItem* itemp = model->getItem(mUUID);
if (!itemp) return;
- const LLUUID outbox_id = getInventoryModel()->findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false, false);
+ const LLUUID outbox_id = getInventoryModel()->findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false);
copy_item_to_outbox(itemp, outbox_id, LLUUID::null, LLToolDragAndDrop::getOperationId());
}
+ else if ("copy_slurl" == action)
+ {
+ LLViewerInventoryItem* item = static_cast<LLViewerInventoryItem*>(getItem());
+ if(item)
+ {
+ LLUUID asset_id = item->getAssetUUID();
+ LLLandmark* landmark = gLandmarkList.getAsset(asset_id);
+ if (landmark)
+ {
+ LLVector3d global_pos;
+ landmark->getGlobalPos(global_pos);
+ LLLandmarkActions::getSLURLfromPosGlobal(global_pos, &copy_slurl_to_clipboard_callback_inv, true);
+ }
+ }
+ }
+}
+
+void copy_slurl_to_clipboard_callback_inv(const std::string& slurl)
+{
+ gViewerWindow->getWindow()->copyTextToClipboard(utf8str_to_wstring(slurl));
+ LLSD args;
+ args["SLURL"] = slurl;
+ LLNotificationsUtil::add("CopySLURL", args);
}
void LLItemBridge::selectItem()
@@ -1483,7 +1544,16 @@ LLUIImagePtr LLItemBridge::getIcon() const
mIsLink);
}
- return LLInventoryIcon::getIcon(LLInventoryIcon::ICONNAME_OBJECT);
+ return LLInventoryIcon::getIcon(LLInventoryType::ICONNAME_OBJECT);
+}
+
+LLUIImagePtr LLItemBridge::getIconOverlay() const
+{
+ if (getItem() && getItem()->getIsLinkType())
+ {
+ return LLUI::getUIImage("Inv_Link");
+ }
+ return NULL;
}
PermissionMask LLItemBridge::getPermissionMask() const
@@ -1494,26 +1564,27 @@ PermissionMask LLItemBridge::getPermissionMask() const
return perm_mask;
}
-const std::string& LLItemBridge::getDisplayName() const
+void LLItemBridge::buildDisplayName() const
{
- if(mDisplayName.empty())
+ if(getItem())
{
- buildDisplayName(getItem(), mDisplayName);
+ mDisplayName.assign(getItem()->getName());
}
- return mDisplayName;
+ else
+ {
+ mDisplayName.assign(LLStringUtil::null);
}
-void LLItemBridge::buildDisplayName(LLInventoryItem* item, std::string& name)
+ mSearchableName.assign(mDisplayName);
+ mSearchableName.append(getLabelSuffix());
+ LLStringUtil::toUpper(mSearchableName);
+
+ //Name set, so trigger a sort
+ if(mParent)
{
- if(item)
- {
- name.assign(item->getName());
+ mParent->requestSort();
}
- else
- {
- name.assign(LLStringUtil::null);
}
-}
LLFontGL::StyleFlags LLItemBridge::getLabelStyle() const
{
@@ -1629,18 +1700,17 @@ BOOL LLItemBridge::renameItem(const std::string& new_name)
{
LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
new_item->rename(new_name);
- buildDisplayName(new_item, mDisplayName);
new_item->updateServer(FALSE);
model->updateItem(new_item);
model->notifyObservers();
+ buildDisplayName();
}
// return FALSE because we either notified observers (& therefore
// rebuilt) or we didn't update.
return FALSE;
}
-
BOOL LLItemBridge::removeItem()
{
if(!isItemRemovable())
@@ -1648,7 +1718,6 @@ BOOL LLItemBridge::removeItem()
return FALSE;
}
-
// move it to the trash
LLPreview::hide(mUUID, TRUE);
LLInventoryModel* model = getInventoryModel();
@@ -1786,6 +1855,99 @@ void LLFolderBridge::selectItem()
LLInventoryModelBackgroundFetch::instance().start(getUUID(), true);
}
+void LLFolderBridge::buildDisplayName() const
+{
+ LLFolderType::EType preferred_type = getPreferredType();
+
+ // *TODO: to be removed when database supports multi language. This is a
+ // temporary attempt to display the inventory folder in the user locale.
+ // mantipov: *NOTE: be sure this code is synchronized with LLFriendCardsManager::findChildFolderUUID
+ // it uses the same way to find localized string
+
+ // HACK: EXT - 6028 ([HARD CODED]? Inventory > Library > "Accessories" folder)
+ // Translation of Accessories folder in Library inventory folder
+ bool accessories = false;
+ if(getName() == "Accessories")
+ {
+ //To ensure that Accessories folder is in Library we have to check its parent folder.
+ //Due to parent LLFolderViewFloder is not set to this item yet we have to check its parent via Inventory Model
+ LLInventoryCategory* cat = gInventory.getCategory(getUUID());
+ if(cat)
+ {
+ const LLUUID& parent_folder_id = cat->getParentUUID();
+ accessories = (parent_folder_id == gInventory.getLibraryRootFolderID());
+ }
+ }
+
+ //"Accessories" inventory category has folder type FT_NONE. So, this folder
+ //can not be detected as protected with LLFolderType::lookupIsProtectedType
+ mDisplayName.assign(getName());
+ if (accessories || LLFolderType::lookupIsProtectedType(preferred_type))
+ {
+ LLTrans::findString(mDisplayName, std::string("InvFolder ") + getName(), LLSD());
+ }
+
+ mSearchableName.assign(mDisplayName);
+ mSearchableName.append(getLabelSuffix());
+ LLStringUtil::toUpper(mSearchableName);
+
+ //Name set, so trigger a sort
+ if(mParent)
+ {
+ mParent->requestSort();
+ }
+}
+
+
+void LLFolderBridge::update()
+{
+ bool possibly_has_children = false;
+ bool up_to_date = isUpToDate();
+ if(!up_to_date && hasChildren()) // we know we have children but haven't fetched them (doesn't obey filter)
+ {
+ possibly_has_children = true;
+ }
+
+ bool loading = (possibly_has_children
+ && !up_to_date );
+
+ if (loading != mIsLoading)
+ {
+ if ( loading && !mIsLoading )
+ {
+ // Measure how long we've been in the loading state
+ mTimeSinceRequestStart.reset();
+ }
+
+ const BOOL in_inventory = gInventory.isObjectDescendentOf(getUUID(), gInventory.getRootFolderID());
+ const BOOL in_library = gInventory.isObjectDescendentOf(getUUID(), gInventory.getLibraryRootFolderID());
+
+ bool root_is_loading = false;
+ if (in_inventory)
+ {
+ root_is_loading = LLInventoryModelBackgroundFetch::instance().inventoryFetchInProgress();
+ }
+ if (in_library)
+ {
+ root_is_loading = LLInventoryModelBackgroundFetch::instance().libraryFetchInProgress();
+ }
+ if ((mIsLoading
+ && mTimeSinceRequestStart.getElapsedTimeF32() >= gSavedSettings.getF32("FolderLoadingMessageWaitTime"))
+ || (LLInventoryModelBackgroundFetch::instance().folderFetchActive()
+ && root_is_loading))
+ {
+ mDisplayName = LLInvFVBridge::getDisplayName() + " ( " + LLTrans::getString("LoadingData") + " ) ";
+ mIsLoading = true;
+ }
+ else
+ {
+ mDisplayName = LLInvFVBridge::getDisplayName();
+ mIsLoading = false;
+ }
+ }
+}
+
+
// Iterate through a folder's children to determine if
// all the children are removable.
class LLIsItemRemovable : public LLFolderViewFunctor
@@ -1794,11 +1956,11 @@ public:
LLIsItemRemovable() : mPassed(TRUE) {}
virtual void doFolder(LLFolderViewFolder* folder)
{
- mPassed &= folder->getListener()->isItemRemovable();
+ mPassed &= folder->getViewModelItem()->isItemRemovable();
}
virtual void doItem(LLFolderViewItem* item)
{
- mPassed &= item->getListener()->isItemRemovable();
+ mPassed &= item->getViewModelItem()->isItemRemovable();
}
BOOL mPassed;
};
@@ -1812,7 +1974,7 @@ BOOL LLFolderBridge::isItemRemovable() const
}
LLInventoryPanel* panel = mInventoryPanel.get();
- LLFolderViewFolder* folderp = dynamic_cast<LLFolderViewFolder*>(panel ? panel->getRootFolder()->getItemByID(mUUID) : NULL);
+ LLFolderViewFolder* folderp = dynamic_cast<LLFolderViewFolder*>(panel ? panel->getItemByID(mUUID) : NULL);
if (folderp)
{
LLIsItemRemovable folder_test;
@@ -2051,7 +2213,7 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
LLInventoryPanel* destination_panel = mInventoryPanel.get();
if (!destination_panel) return false;
- LLInventoryFilter* filter = destination_panel->getFilter();
+ LLInventoryFilter* filter = getInventoryFilter();
if (!filter) return false;
const LLUUID &cat_id = inv_cat->getUUID();
@@ -2270,7 +2432,7 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
{
// Check whether the folder being dragged from active inventory panel
// passes the filter of the destination panel.
- is_movable = check_category(model, cat_id, active_folder_view, filter);
+ is_movable = check_category(model, cat_id, active_panel, filter);
}
}
}
@@ -2344,7 +2506,7 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
}
else
{
- if (model->isObjectDescendentOf(cat_id, model->findCategoryUUIDForType(LLFolderType::FT_INBOX, false, false)))
+ if (model->isObjectDescendentOf(cat_id, model->findCategoryUUIDForType(LLFolderType::FT_INBOX, false)))
{
set_dad_inbox_object(cat_id);
}
@@ -2486,7 +2648,6 @@ BOOL move_inv_category_world_to_agent(const LLUUID& object_id,
if(drop && accept)
{
it = inventory_objects.begin();
- LLInventoryObject::object_list_t::iterator first_it = inventory_objects.begin();
LLMoveInv* move_inv = new LLMoveInv;
move_inv->mObjectID = object_id;
move_inv->mCategoryID = category_id;
@@ -2522,7 +2683,6 @@ void LLRightClickInventoryFetchDescendentsObserver::execute(bool clear_observer)
llwarns << "LLRightClickInventoryFetchDescendentsObserver::done with empty mCompleteFolders" << llendl;
if (clear_observer)
{
- dec_busy_count();
gInventory.removeObserver(this);
delete this;
}
@@ -2536,7 +2696,6 @@ void LLRightClickInventoryFetchDescendentsObserver::execute(bool clear_observer)
// could notify observers and throw us into an infinite loop.
if (clear_observer)
{
- dec_busy_count();
gInventory.removeObserver(this);
delete this;
}
@@ -2548,14 +2707,23 @@ void LLRightClickInventoryFetchDescendentsObserver::execute(bool clear_observer)
LLInventoryModel::item_array_t* item_array;
gInventory.getDirectDescendentsOf(*current_folder, cat_array, item_array);
- S32 item_count = item_array->count();
- S32 cat_count = cat_array->count();
-
+ S32 item_count(0);
+ if( item_array )
+ {
+ item_count = item_array->count();
+ }
+
+ S32 cat_count(0);
+ if( cat_array )
+ {
+ cat_count = cat_array->count();
+ }
+
// Move to next if current folder empty
if ((item_count == 0) && (cat_count == 0))
- {
+ {
continue;
- }
+ }
uuid_vec_t ids;
LLRightClickInventoryFetchObserver* outfit = NULL;
@@ -2598,7 +2766,6 @@ void LLRightClickInventoryFetchDescendentsObserver::execute(bool clear_observer)
{
// it's all on its way - add an observer, and the inventory
// will call done for us when everything is here.
- inc_busy_count();
gInventory.addObserver(outfit);
}
*/
@@ -2617,7 +2784,6 @@ void LLRightClickInventoryFetchDescendentsObserver::execute(bool clear_observer)
{
// it's all on its way - add an observer, and the inventory
// will call done for us when everything is here.
- inc_busy_count();
gInventory.addObserver(categories);
}
}
@@ -2696,7 +2862,7 @@ void LLFolderBridge::performAction(LLInventoryModel* model, std::string action)
{
if ("open" == action)
{
- LLFolderViewFolder *f = dynamic_cast<LLFolderViewFolder *>(mRoot->getItemByID(mUUID));
+ LLFolderViewFolder *f = dynamic_cast<LLFolderViewFolder *>(mInventoryPanel.get()->getItemByID(mUUID));
if (f)
{
f->setOpen(TRUE);
@@ -2743,7 +2909,7 @@ void LLFolderBridge::performAction(LLInventoryModel* model, std::string action)
else if ("cut" == action)
{
cutToClipboard();
- LLFolderView::removeCutItems();
+ gInventory.removeObject(mUUID);
return;
}
else if ("copy" == action)
@@ -2758,7 +2924,7 @@ void LLFolderBridge::performAction(LLInventoryModel* model, std::string action)
LLViewerInventoryCategory* cat = getCategory();
if(!cat) return;
- remove_inventory_category_from_avatar ( cat );
+ LLAppearanceMgr::instance().takeOffOutfit( cat->getLinkedUUID() );
return;
}
else if ("purge" == action)
@@ -2784,7 +2950,7 @@ void LLFolderBridge::performAction(LLInventoryModel* model, std::string action)
LLInventoryCategory * cat = gInventory.getCategory(mUUID);
if (!cat) return;
- const LLUUID outbox_id = getInventoryModel()->findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false, false);
+ const LLUUID outbox_id = getInventoryModel()->findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false);
copy_folder_to_outbox(cat, outbox_id, cat->getUUID(), LLToolDragAndDrop::getOperationId());
}
#if ENABLE_MERCHANT_SEND_TO_MARKETPLACE_CONTEXT_MENU
@@ -2880,17 +3046,24 @@ LLUIImagePtr LLFolderBridge::getIcon() const
LLUIImagePtr LLFolderBridge::getIcon(LLFolderType::EType preferred_type)
{
return LLUI::getUIImage(LLViewerFolderType::lookupIconName(preferred_type, FALSE));
- /*case LLAssetType::AT_MESH:
- control = "inv_folder_mesh.tga";
- break;*/
}
-LLUIImagePtr LLFolderBridge::getOpenIcon() const
+LLUIImagePtr LLFolderBridge::getIconOpen() const
{
return LLUI::getUIImage(LLViewerFolderType::lookupIconName(getPreferredType(), TRUE));
}
+LLUIImagePtr LLFolderBridge::getIconOverlay() const
+{
+ if (getInventoryObject() && getInventoryObject()->getIsLinkType())
+ {
+ return LLUI::getUIImage("Inv_Link");
+ }
+ return NULL;
+}
+
+
BOOL LLFolderBridge::renameItem(const std::string& new_name)
{
rename_category(getInventoryModel(), mUUID, new_name);
@@ -2954,6 +3127,19 @@ bool LLFolderBridge::removeItemResponse(const LLSD& notification, const LLSD& re
return FALSE;
}
+//Recursively update the folder's creation date
+void LLFolderBridge::updateHierarchyCreationDate(time_t date)
+{
+ if(getCreationDate() < date)
+ {
+ setCreationDate(date);
+ if(mParent)
+ {
+ static_cast<LLFolderBridge *>(mParent)->updateHierarchyCreationDate(date);
+ }
+ }
+}
+
void LLFolderBridge::pasteFromClipboard()
{
LLInventoryModel* model = getInventoryModel();
@@ -2971,7 +3157,7 @@ void LLFolderBridge::pasteFromClipboard()
if (move_is_into_outbox)
{
- LLFolderViewItem * outbox_itemp = mRoot->getItemByID(mUUID);
+ LLFolderViewItem * outbox_itemp = mInventoryPanel.get()->getItemByID(mUUID);
if (outbox_itemp)
{
@@ -2994,7 +3180,7 @@ void LLFolderBridge::pasteFromClipboard()
void * cargo_data = (void *) item;
std::string tooltip_msg;
- can_list = outbox_itemp->getListener()->dragOrDrop(mask, drop, cargo_type, cargo_data, tooltip_msg);
+ can_list = outbox_itemp->getViewModelItem()->dragOrDrop(mask, drop, cargo_type, cargo_data, tooltip_msg);
}
}
@@ -3036,7 +3222,8 @@ void LLFolderBridge::pasteFromClipboard()
LLViewerInventoryCategory* vicat = (LLViewerInventoryCategory *) model->getCategory(item_id);
llassert(vicat);
if (vicat)
- {
+ {
+ //changeCategoryParent() implicity calls dirtyFilter
changeCategoryParent(model, vicat, parent_id, FALSE);
}
}
@@ -3046,6 +3233,7 @@ void LLFolderBridge::pasteFromClipboard()
llassert(viitem);
if (viitem)
{
+ //changeItemParent() implicity calls dirtyFilter
changeItemParent(model, viitem, parent_id, FALSE);
}
}
@@ -3166,41 +3354,45 @@ BOOL LLFolderBridge::checkFolderForContentsOfType(LLInventoryModel* model, LLInv
return ((item_array.count() > 0) ? TRUE : FALSE );
}
-void LLFolderBridge::buildContextMenuBaseOptions(U32 flags)
+void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items, menuentry_vec_t& disabled_items)
{
LLInventoryModel* model = getInventoryModel();
llassert(model != NULL);
const LLUUID trash_id = model->findCategoryUUIDForType(LLFolderType::FT_TRASH);
const LLUUID lost_and_found_id = model->findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND);
+ const LLUUID favorites = model->findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
if (lost_and_found_id == mUUID)
{
// This is the lost+found folder.
- mItems.push_back(std::string("Empty Lost And Found"));
+ items.push_back(std::string("Empty Lost And Found"));
- mDisabledItems.push_back(std::string("New Folder"));
- mDisabledItems.push_back(std::string("New Script"));
- mDisabledItems.push_back(std::string("New Note"));
- mDisabledItems.push_back(std::string("New Gesture"));
- mDisabledItems.push_back(std::string("New Clothes"));
- mDisabledItems.push_back(std::string("New Body Parts"));
+ disabled_items.push_back(std::string("New Folder"));
+ disabled_items.push_back(std::string("New Script"));
+ disabled_items.push_back(std::string("New Note"));
+ disabled_items.push_back(std::string("New Gesture"));
+ disabled_items.push_back(std::string("New Clothes"));
+ disabled_items.push_back(std::string("New Body Parts"));
+ }
+ if (favorites == mUUID)
+ {
+ disabled_items.push_back(std::string("New Folder"));
}
-
if(trash_id == mUUID)
{
// This is the trash.
- mItems.push_back(std::string("Empty Trash"));
+ items.push_back(std::string("Empty Trash"));
}
else if(isItemInTrash())
{
// This is a folder in the trash.
- mItems.clear(); // clear any items that used to exist
- addTrashContextMenuOptions(mItems, mDisabledItems);
+ items.clear(); // clear any items that used to exist
+ addTrashContextMenuOptions(items, disabled_items);
}
else if(isOutboxFolder())
{
- addOutboxContextMenuOptions(flags, mItems, mDisabledItems);
+ addOutboxContextMenuOptions(flags, items, disabled_items);
}
else if(isAgentInventory()) // do not allow creating in library
{
@@ -3214,45 +3406,45 @@ void LLFolderBridge::buildContextMenuBaseOptions(U32 flags)
// Do not allow to create 2-level subfolder in the Calling Card/Friends folder. EXT-694.
if (!LLFriendCardsManager::instance().isCategoryInFriendFolder(cat))
{
- mItems.push_back(std::string("New Folder"));
+ items.push_back(std::string("New Folder"));
}
- mItems.push_back(std::string("New Script"));
- mItems.push_back(std::string("New Note"));
- mItems.push_back(std::string("New Gesture"));
- mItems.push_back(std::string("New Clothes"));
- mItems.push_back(std::string("New Body Parts"));
+ items.push_back(std::string("New Script"));
+ items.push_back(std::string("New Note"));
+ items.push_back(std::string("New Gesture"));
+ items.push_back(std::string("New Clothes"));
+ items.push_back(std::string("New Body Parts"));
}
#if SUPPORT_ENSEMBLES
// Changing folder types is an unfinished unsupported feature
// and can lead to unexpected behavior if enabled.
- mItems.push_back(std::string("Change Type"));
+ items.push_back(std::string("Change Type"));
const LLViewerInventoryCategory *cat = getCategory();
if (cat && LLFolderType::lookupIsProtectedType(cat->getPreferredType()))
{
- mDisabledItems.push_back(std::string("Change Type"));
+ disabled_items.push_back(std::string("Change Type"));
}
#endif
- getClipboardEntries(false, mItems, mDisabledItems, flags);
+ getClipboardEntries(false, items, disabled_items, flags);
}
else
{
// Want some but not all of the items from getClipboardEntries for outfits.
if (cat && (cat->getPreferredType() == LLFolderType::FT_OUTFIT))
{
- mItems.push_back(std::string("Rename"));
+ items.push_back(std::string("Rename"));
- addDeleteContextMenuOptions(mItems, mDisabledItems);
+ addDeleteContextMenuOptions(items, disabled_items);
// EXT-4030: disallow deletion of currently worn outfit
const LLViewerInventoryItem *base_outfit_link = LLAppearanceMgr::instance().getBaseOutfitLink();
if (base_outfit_link && (cat == base_outfit_link->getLinkedCategory()))
{
- mDisabledItems.push_back(std::string("Delete"));
+ disabled_items.push_back(std::string("Delete"));
}
}
}
- //Added by spatters to force inventory pull on right-click to display folder options correctly. 07-17-06
+ //Added by aura to force inventory pull on right-click to display folder options correctly. 07-17-06
mCallingCards = mWearables = FALSE;
LLIsType is_callingcard(LLAssetType::AT_CALLINGCARD);
@@ -3276,20 +3468,43 @@ void LLFolderBridge::buildContextMenuBaseOptions(U32 flags)
// Preemptively disable system folder removal if more than one item selected.
if ((flags & FIRST_SELECTED_ITEM) == 0)
{
- mDisabledItems.push_back(std::string("Delete System Folder"));
+ disabled_items.push_back(std::string("Delete System Folder"));
}
if (!isOutboxFolder())
{
- mItems.push_back(std::string("Share"));
+ items.push_back(std::string("Share"));
if (!canShare())
{
- mDisabledItems.push_back(std::string("Share"));
+ disabled_items.push_back(std::string("Share"));
+ }
+ }
+ // Add menu items that are dependent on the contents of the folder.
+ LLViewerInventoryCategory* category = (LLViewerInventoryCategory *) model->getCategory(mUUID);
+ if (category)
+ {
+ uuid_vec_t folders;
+ folders.push_back(category->getUUID());
+
+ sSelf = getHandle();
+ LLRightClickInventoryFetchDescendentsObserver* fetch = new LLRightClickInventoryFetchDescendentsObserver(folders);
+ fetch->startFetch();
+ if (fetch->isFinished())
+ {
+ // Do not call execute() or done() here as if the folder is here, there's likely no point drilling down
+ // This saves lots of time as buildContextMenu() is called a lot
+ delete fetch;
+ buildContextMenuFolderOptions(flags, items, disabled_items);
}
+ else
+ {
+ // it's all on its way - add an observer, and the inventory will call done for us when everything is here.
+ gInventory.addObserver(fetch);
}
}
+}
-void LLFolderBridge::buildContextMenuFolderOptions(U32 flags)
+void LLFolderBridge::buildContextMenuFolderOptions(U32 flags, menuentry_vec_t& items, menuentry_vec_t& disabled_items)
{
// Build folder specific options back up
LLInventoryModel* model = getInventoryModel();
@@ -3316,21 +3531,21 @@ void LLFolderBridge::buildContextMenuFolderOptions(U32 flags)
LLIsType is_callingcard(LLAssetType::AT_CALLINGCARD);
if (mCallingCards || checkFolderForContentsOfType(model, is_callingcard))
{
- mItems.push_back(std::string("Calling Card Separator"));
- mItems.push_back(std::string("Conference Chat Folder"));
- mItems.push_back(std::string("IM All Contacts In Folder"));
+ items.push_back(std::string("Calling Card Separator"));
+ items.push_back(std::string("Conference Chat Folder"));
+ items.push_back(std::string("IM All Contacts In Folder"));
}
}
if (!isItemRemovable())
{
- mDisabledItems.push_back(std::string("Delete"));
+ disabled_items.push_back(std::string("Delete"));
}
#ifndef LL_RELEASE_FOR_DOWNLOAD
if (LLFolderType::lookupIsProtectedType(type))
{
- mItems.push_back(std::string("Delete System Folder"));
+ items.push_back(std::string("Delete System Folder"));
}
#endif
@@ -3345,7 +3560,7 @@ void LLFolderBridge::buildContextMenuFolderOptions(U32 flags)
checkFolderForContentsOfType(model, is_object) ||
checkFolderForContentsOfType(model, is_gesture) )
{
- mItems.push_back(std::string("Folder Wearables Separator"));
+ items.push_back(std::string("Folder Wearables Separator"));
// Only enable add/replace outfit for non-system folders.
if (!is_system_folder)
@@ -3353,25 +3568,25 @@ void LLFolderBridge::buildContextMenuFolderOptions(U32 flags)
// Adding an outfit onto another (versus replacing) doesn't make sense.
if (type != LLFolderType::FT_OUTFIT)
{
- mItems.push_back(std::string("Add To Outfit"));
+ items.push_back(std::string("Add To Outfit"));
}
- mItems.push_back(std::string("Replace Outfit"));
+ items.push_back(std::string("Replace Outfit"));
}
if (is_ensemble)
{
- mItems.push_back(std::string("Wear As Ensemble"));
+ items.push_back(std::string("Wear As Ensemble"));
}
- mItems.push_back(std::string("Remove From Outfit"));
+ items.push_back(std::string("Remove From Outfit"));
if (!LLAppearanceMgr::getCanRemoveFromCOF(mUUID))
{
- mDisabledItems.push_back(std::string("Remove From Outfit"));
+ disabled_items.push_back(std::string("Remove From Outfit"));
}
if (!LLAppearanceMgr::instance().getCanReplaceCOF(mUUID))
{
- mDisabledItems.push_back(std::string("Replace Outfit"));
+ disabled_items.push_back(std::string("Replace Outfit"));
}
- mItems.push_back(std::string("Outfit Separator"));
+ items.push_back(std::string("Outfit Separator"));
}
}
@@ -3380,49 +3595,28 @@ void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
{
sSelf.markDead();
- mItems.clear();
- mDisabledItems.clear();
+ // fetch contents of this folder, as context menu can depend on contents
+ // still, user would have to open context menu again to see the changes
+ gInventory.fetchDescendentsOf(getUUID());
+
+
+ menuentry_vec_t items;
+ menuentry_vec_t disabled_items;
lldebugs << "LLFolderBridge::buildContextMenu()" << llendl;
LLInventoryModel* model = getInventoryModel();
if(!model) return;
- buildContextMenuBaseOptions(flags);
-
- // Add menu items that are dependent on the contents of the folder.
- LLViewerInventoryCategory* category = (LLViewerInventoryCategory *) model->getCategory(mUUID);
- if (category)
- {
- uuid_vec_t folders;
- folders.push_back(category->getUUID());
-
- sSelf = getHandle();
- LLRightClickInventoryFetchDescendentsObserver* fetch = new LLRightClickInventoryFetchDescendentsObserver(folders);
- fetch->startFetch();
- if (fetch->isFinished())
- {
- // Do not call execute() or done() here as if the folder is here, there's likely no point drilling down
- // This saves lots of time as buildContextMenu() is called a lot
- delete fetch;
- buildContextMenuFolderOptions(flags);
- }
- else
- {
- // it's all on its way - add an observer, and the inventory will call done for us when everything is here.
- inc_busy_count();
- gInventory.addObserver(fetch);
- }
- }
-
- hide_context_entries(menu, mItems, mDisabledItems);
+ buildContextMenuOptions(flags, items, disabled_items);
+ hide_context_entries(menu, items, disabled_items);
// Reposition the menu, in case we're adding items to an existing menu.
menu.needsArrange();
menu.arrangeAndClear();
}
-BOOL LLFolderBridge::hasChildren() const
+bool LLFolderBridge::hasChildren() const
{
LLInventoryModel* model = getInventoryModel();
if(!model) return FALSE;
@@ -3512,25 +3706,6 @@ void LLFolderBridge::pasteClipboard(void* user_data)
if(self) self->pasteFromClipboard();
}
-void LLFolderBridge::createNewCategory(void* user_data)
-{
- LLFolderBridge* bridge = (LLFolderBridge*)user_data;
- if(!bridge) return;
- LLInventoryPanel* panel = bridge->mInventoryPanel.get();
- if (!panel) return;
- LLInventoryModel* model = panel->getModel();
- if(!model) return;
- LLUUID id;
- id = model->createNewCategory(bridge->getUUID(),
- LLFolderType::FT_NONE,
- LLStringUtil::null);
- model->notifyObservers();
-
- // At this point, the bridge has probably been deleted, but the
- // view is still there.
- panel->setSelection(id, TAKE_FOCUS_YES);
-}
-
void LLFolderBridge::createNewShirt(void* user_data)
{
LLFolderBridge::createWearable((LLFolderBridge*)user_data, LLWearableType::WT_SHIRT);
@@ -3596,6 +3771,24 @@ void LLFolderBridge::createNewEyes(void* user_data)
LLFolderBridge::createWearable((LLFolderBridge*)user_data, LLWearableType::WT_EYES);
}
+EInventorySortGroup LLFolderBridge::getSortGroup() const
+{
+ LLFolderType::EType preferred_type = getPreferredType();
+
+ if (preferred_type == LLFolderType::FT_TRASH)
+ {
+ return SG_TRASH_FOLDER;
+ }
+
+ if(LLFolderType::lookupIsProtectedType(preferred_type))
+ {
+ return SG_SYSTEM_FOLDER;
+ }
+
+ return SG_NORMAL_FOLDER;
+}
+
+
// static
void LLFolderBridge::createWearable(LLFolderBridge* bridge, LLWearableType::EType type)
{
@@ -3698,9 +3891,10 @@ void LLFolderBridge::dropToFavorites(LLInventoryItem* inv_item)
LLPointer<AddFavoriteLandmarkCallback> cb = new AddFavoriteLandmarkCallback();
LLInventoryPanel* panel = mInventoryPanel.get();
LLFolderViewItem* drag_over_item = panel ? panel->getRootFolder()->getDraggingOverItem() : NULL;
- if (drag_over_item && drag_over_item->getListener())
+ LLFolderViewModelItemInventory* view_model = drag_over_item ? static_cast<LLFolderViewModelItemInventory*>(drag_over_item->getViewModelItem()) : NULL;
+ if (view_model)
{
- cb.get()->setTargetLandmarkId(drag_over_item->getListener()->getUUID());
+ cb.get()->setTargetLandmarkId(view_model->getUUID());
}
copy_inventory_item(
@@ -3749,7 +3943,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
LLInventoryPanel* destination_panel = mInventoryPanel.get();
if (!destination_panel) return false;
- LLInventoryFilter* filter = destination_panel->getFilter();
+ LLInventoryFilter* filter = getInventoryFilter();
if (!filter) return false;
const LLUUID &current_outfit_id = model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT, false);
@@ -3866,13 +4060,10 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
// passes the filter of the destination panel.
if (accept && active_panel)
{
- LLFolderView* active_folder_view = active_panel->getRootFolder();
- if (!active_folder_view) return false;
-
- LLFolderViewItem* fv_item = active_folder_view->getItemByID(inv_item->getUUID());
+ LLFolderViewItem* fv_item = active_panel->getItemByID(inv_item->getUUID());
if (!fv_item) return false;
- accept = filter->check(fv_item);
+ accept = filter->check(fv_item->getViewModelItem());
}
if (accept && drop)
@@ -3884,6 +4075,8 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
}
// If an item is being dragged between windows, unselect everything in the active window
// so that we don't follow the selection to its new location (which is very annoying).
+ // RN: a better solution would be to deselect automatically when an item is moved
+ // and then select any item that is dropped only in the panel that it is dropped in
if (active_panel && (destination_panel != active_panel))
{
active_panel->unSelectAll();
@@ -3901,8 +4094,8 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
if (itemp)
{
LLUUID srcItemId = inv_item->getUUID();
- LLUUID destItemId = itemp->getListener()->getUUID();
- gInventory.rearrangeFavoriteLandmarks(srcItemId, destItemId);
+ LLUUID destItemId = static_cast<LLFolderViewModelItemInventory*>(itemp->getViewModelItem())->getUUID();
+ LLFavoritesOrderStorage::instance().rearrangeFavoriteLandmarks(srcItemId, destItemId);
}
}
@@ -3934,7 +4127,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
else
{
// set up observer to select item once drag and drop from inbox is complete
- if (gInventory.isObjectDescendentOf(inv_item->getUUID(), gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX, false, false)))
+ if (gInventory.isObjectDescendentOf(inv_item->getUUID(), gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX, false)))
{
set_dad_inbox_object(inv_item->getUUID());
}
@@ -4089,13 +4282,10 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
// passes the filter of the destination panel.
if (accept && active_panel)
{
- LLFolderView* active_folder_view = active_panel->getRootFolder();
- if (!active_folder_view) return false;
-
- LLFolderViewItem* fv_item = active_folder_view->getItemByID(inv_item->getUUID());
+ LLFolderViewItem* fv_item = active_panel->getItemByID(inv_item->getUUID());
if (!fv_item) return false;
- accept = filter->check(fv_item);
+ accept = filter->check(fv_item->getViewModelItem());
}
if (accept && drop)
@@ -4135,10 +4325,10 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
// static
bool check_category(LLInventoryModel* model,
const LLUUID& cat_id,
- LLFolderView* active_folder_view,
+ LLInventoryPanel* active_panel,
LLInventoryFilter* filter)
{
- if (!model || !active_folder_view || !filter)
+ if (!model || !active_panel || !filter)
return false;
if (!filter->checkFolder(cat_id))
@@ -4158,13 +4348,13 @@ bool check_category(LLInventoryModel* model,
// Empty folder should be checked as any other folder view item.
// If we are filtering by date the folder should not pass because
// it doesn't have its own creation date. See LLInvFVBridge::getCreationDate().
- return check_item(cat_id, active_folder_view, filter);
+ return check_item(cat_id, active_panel, filter);
}
for (S32 i = 0; i < num_descendent_categories; ++i)
{
LLInventoryCategory* category = descendent_categories[i];
- if(!check_category(model, category->getUUID(), active_folder_view, filter))
+ if(!check_category(model, category->getUUID(), active_panel, filter))
{
return false;
}
@@ -4173,7 +4363,7 @@ bool check_category(LLInventoryModel* model,
for (S32 i = 0; i < num_descendent_items; ++i)
{
LLViewerInventoryItem* item = descendent_items[i];
- if(!check_item(item->getUUID(), active_folder_view, filter))
+ if(!check_item(item->getUUID(), active_panel, filter))
{
return false;
}
@@ -4184,15 +4374,15 @@ bool check_category(LLInventoryModel* model,
// static
bool check_item(const LLUUID& item_id,
- LLFolderView* active_folder_view,
+ LLInventoryPanel* active_panel,
LLInventoryFilter* filter)
{
- if (!active_folder_view || !filter) return false;
+ if (!active_panel || !filter) return false;
- LLFolderViewItem* fv_item = active_folder_view->getItemByID(item_id);
+ LLFolderViewItem* fv_item = active_panel->getItemByID(item_id);
if (!fv_item) return false;
- return filter->check(fv_item);
+ return filter->check(fv_item->getViewModelItem());
}
// +=================================================+
@@ -4294,15 +4484,6 @@ void LLSoundBridge::openItem()
}
}
-void LLSoundBridge::previewItem()
-{
- LLViewerInventoryItem* item = getItem();
- if(item)
- {
- send_sound_trigger(item->getAssetUUID(), 1.0);
- }
-}
-
void LLSoundBridge::openSoundPreview(void* which)
{
LLSoundBridge *me = (LLSoundBridge *)which;
@@ -4397,6 +4578,7 @@ void LLLandmarkBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
}
items.push_back(std::string("Landmark Separator"));
+ items.push_back(std::string("url_copy"));
items.push_back(std::string("About Landmark"));
}
@@ -4405,6 +4587,7 @@ void LLLandmarkBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
// info panel can be shown at a time.
if ((flags & FIRST_SELECTED_ITEM) == 0)
{
+ disabled_items.push_back(std::string("url_copy"));
disabled_items.push_back(std::string("About Landmark"));
}
@@ -4518,7 +4701,7 @@ LLCallingCardBridge::~LLCallingCardBridge()
void LLCallingCardBridge::refreshFolderViewItem()
{
LLInventoryPanel* panel = mInventoryPanel.get();
- LLFolderViewItem* itemp = panel ? panel->getRootFolder()->getItemByID(mUUID) : NULL;
+ LLFolderViewItem* itemp = panel ? panel->getItemByID(mUUID) : NULL;
if (itemp)
{
itemp->refresh();
@@ -4534,19 +4717,16 @@ void LLCallingCardBridge::performAction(LLInventoryModel* model, std::string act
if (item && (item->getCreatorUUID() != gAgent.getID()) &&
(!item->getCreatorUUID().isNull()))
{
- std::string callingcard_name;
- gCacheName->getFullName(item->getCreatorUUID(), callingcard_name);
- // IDEVO
+ std::string callingcard_name = LLCacheName::getDefaultName();
LLAvatarName av_name;
- if (LLAvatarNameCache::useDisplayNames()
- && LLAvatarNameCache::get(item->getCreatorUUID(), &av_name))
+ if (LLAvatarNameCache::get(item->getCreatorUUID(), &av_name))
{
- callingcard_name = av_name.mDisplayName + " (" + av_name.mUsername + ")";
+ callingcard_name = av_name.getCompleteName();
}
LLUUID session_id = gIMMgr->addSession(callingcard_name, IM_NOTHING_SPECIAL, item->getCreatorUUID());
if (session_id != LLUUID::null)
{
- LLIMFloater::show(session_id);
+ LLFloaterIMContainer::getInstance()->showConversation(session_id);
}
}
}
@@ -4559,6 +4739,16 @@ void LLCallingCardBridge::performAction(LLInventoryModel* model, std::string act
LLAvatarActions::offerTeleport(item->getCreatorUUID());
}
}
+ else if ("request_lure" == action)
+ {
+ LLViewerInventoryItem *item = getItem();
+ if (item && (item->getCreatorUUID() != gAgent.getID()) &&
+ (!item->getCreatorUUID().isNull()))
+ {
+ LLAvatarActions::teleportRequest(item->getCreatorUUID());
+ }
+ }
+
else LLItemBridge::performAction(model, action);
}
@@ -4624,6 +4814,10 @@ void LLCallingCardBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
{
disabled_items.push_back(std::string("Share"));
}
+ if ((flags & FIRST_SELECTED_ITEM) == 0)
+ {
+ disabled_items.push_back(std::string("Open"));
+ }
addOpenRightClickMenuOption(items);
items.push_back(std::string("Properties"));
@@ -4641,6 +4835,7 @@ void LLCallingCardBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
items.push_back(std::string("Send Instant Message Separator"));
items.push_back(std::string("Send Instant Message"));
items.push_back(std::string("Offer Teleport..."));
+ items.push_back(std::string("Request Teleport..."));
items.push_back(std::string("Conference Chat"));
if (!good_card)
@@ -4650,6 +4845,7 @@ void LLCallingCardBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
if (!good_card || !user_online)
{
disabled_items.push_back(std::string("Offer Teleport..."));
+ disabled_items.push_back(std::string("Request Teleport..."));
disabled_items.push_back(std::string("Conference Chat"));
}
}
@@ -5050,7 +5246,7 @@ void LLObjectBridge::performAction(LLInventoryModel* model, std::string action)
else if(item && item->isFinished())
{
// must be in library. copy it to our inventory and put it on.
- LLPointer<LLInventoryCallback> cb = new RezAttachmentCallback(0);
+ LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(rez_attachment_cb, _1, (LLViewerJointAttachment*)0));
copy_inventory_item(
gAgent.getID(),
item->getPermissions().getOwner(),
@@ -5067,11 +5263,7 @@ void LLObjectBridge::performAction(LLInventoryModel* model, std::string action)
}
else if (isRemoveAction(action))
{
- LLInventoryItem* item = gInventory.getItem(mUUID);
- if(item)
- {
- LLVOAvatarSelf::detachAttachmentIntoInventory(item->getLinkedUUID());
- }
+ LLAppearanceMgr::instance().removeItemFromAvatar(mUUID);
}
else LLItemBridge::performAction(model, action);
}
@@ -5288,6 +5480,7 @@ void LLObjectBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
p.on_enable.parameter = cbparams;
LLView* parent = attachment->getIsHUDAttachment() ? attach_hud_menu : attach_menu;
LLUICtrlFactory::create<LLMenuItemCallGL>(p, parent);
+ items.push_back(p.name);
}
}
}
@@ -5309,11 +5502,10 @@ BOOL LLObjectBridge::renameItem(const std::string& new_name)
{
LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
new_item->rename(new_name);
- buildDisplayName(new_item, mDisplayName);
new_item->updateServer(FALSE);
model->updateItem(new_item);
-
model->notifyObservers();
+ buildDisplayName();
if (isAgentAvatarValid())
{
@@ -5363,120 +5555,6 @@ LLWearableBridge::LLWearableBridge(LLInventoryPanel* inventory,
mInvType = inv_type;
}
-void remove_inventory_category_from_avatar( LLInventoryCategory* category )
-{
- if(!category) return;
- lldebugs << "remove_inventory_category_from_avatar( " << category->getName()
- << " )" << llendl;
-
-
- if (gAgentCamera.cameraCustomizeAvatar())
- {
- // switching to outfit editor should automagically save any currently edited wearable
- LLFloaterSidePanelContainer::showPanel("appearance", LLSD().with("type", "edit_outfit"));
- }
-
- remove_inventory_category_from_avatar_step2(TRUE, category->getUUID() );
-}
-
-struct OnRemoveStruct
-{
- LLUUID mUUID;
- OnRemoveStruct(const LLUUID& uuid):
- mUUID(uuid)
- {
- }
-};
-
-void remove_inventory_category_from_avatar_step2( BOOL proceed, LLUUID category_id)
-{
-
- // Find all the wearables that are in the category's subtree.
- lldebugs << "remove_inventory_category_from_avatar_step2()" << llendl;
- if(proceed)
- {
- LLInventoryModel::cat_array_t cat_array;
- LLInventoryModel::item_array_t item_array;
- LLFindWearables is_wearable;
- gInventory.collectDescendentsIf(category_id,
- cat_array,
- item_array,
- LLInventoryModel::EXCLUDE_TRASH,
- is_wearable);
- S32 i;
- S32 wearable_count = item_array.count();
-
- LLInventoryModel::cat_array_t obj_cat_array;
- LLInventoryModel::item_array_t obj_item_array;
- LLIsType is_object( LLAssetType::AT_OBJECT );
- gInventory.collectDescendentsIf(category_id,
- obj_cat_array,
- obj_item_array,
- LLInventoryModel::EXCLUDE_TRASH,
- is_object);
- S32 obj_count = obj_item_array.count();
-
- // Find all gestures in this folder
- LLInventoryModel::cat_array_t gest_cat_array;
- LLInventoryModel::item_array_t gest_item_array;
- LLIsType is_gesture( LLAssetType::AT_GESTURE );
- gInventory.collectDescendentsIf(category_id,
- gest_cat_array,
- gest_item_array,
- LLInventoryModel::EXCLUDE_TRASH,
- is_gesture);
- S32 gest_count = gest_item_array.count();
-
- if (wearable_count > 0) //Loop through wearables. If worn, remove.
- {
- for(i = 0; i < wearable_count; ++i)
- {
- LLViewerInventoryItem *item = item_array.get(i);
- if (item->getType() == LLAssetType::AT_BODYPART)
- continue;
- if (gAgent.isTeen() && item->isWearableType() &&
- (item->getWearableType() == LLWearableType::WT_UNDERPANTS || item->getWearableType() == LLWearableType::WT_UNDERSHIRT))
- continue;
- if (get_is_item_worn(item->getUUID()))
- {
- LLWearableList::instance().getAsset(item->getAssetUUID(),
- item->getName(),
- item->getType(),
- LLWearableBridge::onRemoveFromAvatarArrived,
- new OnRemoveStruct(item->getLinkedUUID()));
- }
- }
- }
-
- if (obj_count > 0)
- {
- for(i = 0; i < obj_count; ++i)
- {
- LLViewerInventoryItem *obj_item = obj_item_array.get(i);
- if (get_is_item_worn(obj_item->getUUID()))
- {
- LLVOAvatarSelf::detachAttachmentIntoInventory(obj_item->getLinkedUUID());
- }
- }
- }
-
- if (gest_count > 0)
- {
- for(i = 0; i < gest_count; ++i)
- {
- LLViewerInventoryItem *gest_item = gest_item_array.get(i);
- if (get_is_item_worn(gest_item->getUUID()))
- {
- LLGestureMgr::instance().deactivateGesture( gest_item->getLinkedUUID() );
- gInventory.updateItem( gest_item );
- gInventory.notifyObservers();
- }
-
- }
- }
- }
-}
-
BOOL LLWearableBridge::renameItem(const std::string& new_name)
{
if (get_is_item_worn(mUUID))
@@ -5590,7 +5668,8 @@ void LLWearableBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
items.push_back(std::string("Wearable Edit"));
- if ((flags & FIRST_SELECTED_ITEM) == 0)
+ bool modifiable = !gAgentWearables.isWearableModifiable(item->getUUID());
+ if (((flags & FIRST_SELECTED_ITEM) == 0) || modifiable)
{
disabled_items.push_back(std::string("Wearable Edit"));
}
@@ -5686,7 +5765,7 @@ void LLWearableBridge::wearAddOnAvatar()
}
// static
-void LLWearableBridge::onWearOnAvatarArrived( LLWearable* wearable, void* userdata )
+void LLWearableBridge::onWearOnAvatarArrived( LLViewerWearable* wearable, void* userdata )
{
LLUUID* item_id = (LLUUID*) userdata;
if(wearable)
@@ -5712,7 +5791,7 @@ void LLWearableBridge::onWearOnAvatarArrived( LLWearable* wearable, void* userda
// static
// BAP remove the "add" code path once everything is fully COF-ified.
-void LLWearableBridge::onWearAddOnAvatarArrived( LLWearable* wearable, void* userdata )
+void LLWearableBridge::onWearAddOnAvatarArrived( LLViewerWearable* wearable, void* userdata )
{
LLUUID* item_id = (LLUUID*) userdata;
if(wearable)
@@ -5772,95 +5851,12 @@ BOOL LLWearableBridge::canRemoveFromAvatar(void* user_data)
return FALSE;
}
-// static
-void LLWearableBridge::onRemoveFromAvatar(void* user_data)
-{
- LLWearableBridge* self = (LLWearableBridge*)user_data;
- if(!self) return;
- if(get_is_item_worn(self->mUUID))
- {
- LLViewerInventoryItem* item = self->getItem();
- if (item)
- {
- LLUUID parent_id = item->getParentUUID();
- LLWearableList::instance().getAsset(item->getAssetUUID(),
- item->getName(),
- item->getType(),
- onRemoveFromAvatarArrived,
- new OnRemoveStruct(LLUUID(self->mUUID)));
- }
- }
-}
-
-// static
-void LLWearableBridge::onRemoveFromAvatarArrived(LLWearable* wearable,
- void* userdata)
-{
- OnRemoveStruct *on_remove_struct = (OnRemoveStruct*) userdata;
- const LLUUID &item_id = gInventory.getLinkedItemID(on_remove_struct->mUUID);
- if(wearable)
- {
- if( get_is_item_worn( item_id ) )
- {
- LLWearableType::EType type = wearable->getType();
-
- if( !(type==LLWearableType::WT_SHAPE || type==LLWearableType::WT_SKIN || type==LLWearableType::WT_HAIR || type==LLWearableType::WT_EYES ) ) //&&
- //!((!gAgent.isTeen()) && ( type==LLWearableType::WT_UNDERPANTS || type==LLWearableType::WT_UNDERSHIRT )) )
- {
- bool do_remove_all = false;
- U32 index = gAgentWearables.getWearableIndex(wearable);
- gAgentWearables.removeWearable( type, do_remove_all, index );
- }
- }
- }
-
- // Find and remove this item from the COF.
- LLAppearanceMgr::instance().removeCOFItemLinks(item_id,false);
- gInventory.notifyObservers();
-
- delete on_remove_struct;
-}
-
-// static
-void LLWearableBridge::removeAllClothesFromAvatar()
-{
- // Fetch worn clothes (i.e. the ones in COF).
- LLInventoryModel::item_array_t clothing_items;
- LLInventoryModel::cat_array_t dummy;
- LLIsType is_clothing(LLAssetType::AT_CLOTHING);
- gInventory.collectDescendentsIf(LLAppearanceMgr::instance().getCOF(),
- dummy,
- clothing_items,
- LLInventoryModel::EXCLUDE_TRASH,
- is_clothing,
- false);
-
- // Take them off by removing from COF.
- for (LLInventoryModel::item_array_t::const_iterator it = clothing_items.begin(); it != clothing_items.end(); ++it)
- {
- LLAppearanceMgr::instance().removeItemFromAvatar((*it)->getUUID());
- }
-}
-
-// static
-void LLWearableBridge::removeItemFromAvatar(LLViewerInventoryItem *item)
-{
- if (item)
- {
- LLWearableList::instance().getAsset(item->getAssetUUID(),
- item->getName(),
- item->getType(),
- LLWearableBridge::onRemoveFromAvatarArrived,
- new OnRemoveStruct(item->getUUID()));
- }
-}
-
void LLWearableBridge::removeFromAvatar()
{
+ llwarns << "safe to remove?" << llendl;
if (get_is_item_worn(mUUID))
{
- LLViewerInventoryItem* item = getItem();
- removeItemFromAvatar(item);
+ LLAppearanceMgr::instance().removeItemFromAvatar(mUUID);
}
}
@@ -5913,16 +5909,6 @@ void LLMeshBridge::openItem()
}
}
-void LLMeshBridge::previewItem()
-{
- LLViewerInventoryItem* item = getItem();
- if(item)
- {
- // preview mesh
- }
-}
-
-
void LLMeshBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
{
lldebugs << "LLMeshBridge::buildContextMenu()" << llendl;
@@ -6011,14 +5997,15 @@ void LLLinkFolderBridge::gotoItem()
const LLUUID &cat_uuid = getFolderID();
if (!cat_uuid.isNull())
{
- if (LLFolderViewItem *base_folder = mRoot->getItemByID(cat_uuid))
+ LLFolderViewItem *base_folder = mInventoryPanel.get()->getItemByID(cat_uuid);
+ if (base_folder)
{
if (LLInventoryModel* model = getInventoryModel())
{
model->fetchDescendentsOf(cat_uuid);
}
base_folder->setOpen(TRUE);
- mRoot->setSelectionFromRoot(base_folder,TRUE);
+ mRoot->setSelection(base_folder,TRUE);
mRoot->scrollToShowSelection();
}
}
@@ -6349,9 +6336,8 @@ LLInvFVBridgeAction* LLInvFVBridgeAction::createAction(LLAssetType::EType asset_
/************************************************************************/
void LLRecentItemsFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
{
- LLFolderBridge::buildContextMenu(menu, flags);
-
- menuentry_vec_t disabled_items, items = getMenuItems();
+ menuentry_vec_t disabled_items, items;
+ buildContextMenuOptions(flags, items, disabled_items);
items.erase(std::remove(items.begin(), items.end(), std::string("New Folder")), items.end());
@@ -6363,42 +6349,29 @@ LLInvFVBridge* LLRecentInventoryBridgeBuilder::createBridge(
LLAssetType::EType actual_asset_type,
LLInventoryType::EType inv_type,
LLInventoryPanel* inventory,
+ LLFolderViewModelInventory* view_model,
LLFolderView* root,
const LLUUID& uuid,
U32 flags /*= 0x00*/ ) const
{
LLInvFVBridge* new_listener = NULL;
- switch(asset_type)
+ if (asset_type == LLAssetType::AT_CATEGORY
+ && actual_asset_type != LLAssetType::AT_LINK_FOLDER)
{
- case LLAssetType::AT_CATEGORY:
- if (actual_asset_type == LLAssetType::AT_LINK_FOLDER)
+ new_listener = new LLRecentItemsFolderBridge(inv_type, inventory, root, uuid);
+ }
+ else
{
- // *TODO: Create a link folder handler instead if it is necessary
- new_listener = LLInventoryFVBridgeBuilder::createBridge(
- asset_type,
+ new_listener = LLInventoryFolderViewModelBuilder::createBridge(asset_type,
actual_asset_type,
inv_type,
inventory,
+ view_model,
root,
uuid,
flags);
- break;
}
- new_listener = new LLRecentItemsFolderBridge(inv_type, inventory, root, uuid);
- break;
- default:
- new_listener = LLInventoryFVBridgeBuilder::createBridge(
- asset_type,
- actual_asset_type,
- inv_type,
- inventory,
- root,
- uuid,
- flags);
- }
return new_listener;
-
}
-
// EOF
diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h
index dc9e88d54d..517153e171 100644..100755
--- a/indra/newview/llinventorybridge.h
+++ b/indra/newview/llinventorybridge.h
@@ -29,11 +29,13 @@
#include "llcallingcard.h"
#include "llfloaterproperties.h"
-#include "llfoldervieweventlistener.h"
+#include "llfolderviewmodel.h"
#include "llinventorymodel.h"
#include "llinventoryobserver.h"
+#include "llinventorypanel.h"
#include "llviewercontrol.h"
-#include "llwearable.h"
+#include "llviewerwearable.h"
+#include "lltooldraganddrop.h"
class LLInventoryFilter;
class LLInventoryPanel;
@@ -41,7 +43,7 @@ class LLInventoryModel;
class LLMenuGL;
class LLCallingCardObserver;
class LLViewerJointAttachment;
-
+class LLFolderView;
typedef std::vector<std::string> menuentry_vec_t;
@@ -56,7 +58,7 @@ typedef std::vector<std::string> menuentry_vec_t;
// functionality a bit. (except for folders, you can create those
// manually...)
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-class LLInvFVBridge : public LLFolderViewEventListener
+class LLInvFVBridge : public LLFolderViewModelItemInventory
{
public:
// This method is a convenience function which creates the correct
@@ -65,6 +67,7 @@ public:
LLAssetType::EType actual_asset_type,
LLInventoryType::EType inv_type,
LLInventoryPanel* inventory,
+ LLFolderViewModelInventory* view_model,
LLFolderView* root,
const LLUUID& uuid,
U32 flags = 0x00);
@@ -78,23 +81,25 @@ public:
// LLInvFVBridge functionality
//--------------------------------------------------------------------
virtual const LLUUID& getUUID() const { return mUUID; }
- virtual void clearDisplayName() {}
+ virtual void clearDisplayName() { mDisplayName.clear(); }
virtual void restoreItem() {}
virtual void restoreToWorld() {}
//--------------------------------------------------------------------
- // Inherited LLFolderViewEventListener functions
+ // Inherited LLFolderViewModelItemInventory functions
//--------------------------------------------------------------------
virtual const std::string& getName() const;
virtual const std::string& getDisplayName() const;
+ const std::string& getSearchableName() const { return mSearchableName; }
+
virtual PermissionMask getPermissionMask() const;
virtual LLFolderType::EType getPreferredType() const;
virtual time_t getCreationDate() const;
+ virtual void setCreationDate(time_t creation_date_utc);
virtual LLFontGL::StyleFlags getLabelStyle() const { return LLFontGL::NORMAL; }
virtual std::string getLabelSuffix() const { return LLStringUtil::null; }
virtual void openItem() {}
virtual void closeItem() {}
- virtual void previewItem() {openItem();}
virtual void showProperties();
virtual BOOL isItemRenameable() const { return TRUE; }
//virtual BOOL renameItem(const std::string& new_name) {}
@@ -102,9 +107,10 @@ public:
virtual BOOL isItemMovable() const;
virtual BOOL isItemInTrash() const;
virtual BOOL isLink() const;
+ virtual BOOL isLibraryItem() const;
//virtual BOOL removeItem() = 0;
- virtual void removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batch);
- virtual void move(LLFolderViewEventListener* new_parent_bridge) {}
+ virtual void removeBatch(std::vector<LLFolderViewModelItem*>& batch);
+ virtual void move(LLFolderViewModelItem* new_parent_bridge) {}
virtual BOOL isItemCopyable() const { return FALSE; }
virtual BOOL copyToClipboard() const;
virtual BOOL cutToClipboard() const;
@@ -115,6 +121,7 @@ public:
void getClipboardEntries(bool show_asset_id, menuentry_vec_t &items,
menuentry_vec_t &disabled_items, U32 flags);
virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
+ virtual LLToolDragAndDrop::ESource getDragSource() const;
virtual BOOL startDrag(EDragAndDropType* type, LLUUID* id) const;
virtual BOOL dragOrDrop(MASK mask, BOOL drop,
EDragAndDropType cargo_type,
@@ -122,6 +129,9 @@ public:
std::string& tooltip_msg) { return FALSE; }
virtual LLInventoryType::EType getInventoryType() const { return mInvType; }
virtual LLWearableType::EType getWearableType() const { return LLWearableType::WT_NONE; }
+ EInventorySortGroup getSortGroup() const { return SG_ITEM; }
+ virtual LLInventoryObject* getInventoryObject() const;
+
//--------------------------------------------------------------------
// Convenience functions for adding various common menu options.
@@ -138,16 +148,16 @@ protected:
protected:
LLInvFVBridge(LLInventoryPanel* inventory, LLFolderView* root, const LLUUID& uuid);
- LLInventoryObject* getInventoryObject() const;
LLInventoryModel* getInventoryModel() const;
+ LLInventoryFilter* getInventoryFilter() const;
BOOL isLinkedObjectInTrash() const; // Is this obj or its baseobj in the trash?
BOOL isLinkedObjectMissing() const; // Is this a linked obj whose baseobj is not in inventory?
BOOL isAgentInventory() const; // false if lost or in the inventory library
- BOOL isCOFFolder() const; // true if COF or descendent of
- BOOL isInboxFolder() const; // true if COF or descendent of marketplace inbox
- BOOL isOutboxFolder() const; // true if COF or descendent of marketplace outbox
+ BOOL isCOFFolder() const; // true if COF or descendant of
+ BOOL isInboxFolder() const; // true if COF or descendant of marketplace inbox
+ BOOL isOutboxFolder() const; // true if COF or descendant of marketplace outbox
BOOL isOutboxFolderDirectParent() const;
const LLUUID getOutboxFolder() const;
@@ -160,30 +170,36 @@ protected:
LLViewerInventoryCategory* item,
const LLUUID& new_parent,
BOOL restamp);
- void removeBatchNoCheck(LLDynamicArray<LLFolderViewEventListener*>& batch);
+ void removeBatchNoCheck(std::vector<LLFolderViewModelItem*>& batch);
protected:
LLHandle<LLInventoryPanel> mInventoryPanel;
LLFolderView* mRoot;
const LLUUID mUUID; // item id
LLInventoryType::EType mInvType;
- BOOL mIsLink;
+ bool mIsLink;
+ LLTimer mTimeSinceRequestStart;
+ mutable std::string mDisplayName;
+ mutable std::string mSearchableName;
+
void purgeItem(LLInventoryModel *model, const LLUUID &uuid);
+ virtual void buildDisplayName() const {}
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Class LLInvFVBridgeBuilder
+// Class LLInventoryFolderViewModelBuilder
//
-// This class intended to build Folder View Bridge via LLInvFVBridge::createBridge.
-// It can be overridden with another way of creation necessary Inventory-Folder-View-Bridge.
+// This class intended to build Folder View Model via LLInvFVBridge::createBridge.
+// It can be overridden with another way of creation necessary Inventory Folder View Models.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-class LLInventoryFVBridgeBuilder
+class LLInventoryFolderViewModelBuilder
{
public:
- virtual ~LLInventoryFVBridgeBuilder() {}
+ virtual ~LLInventoryFolderViewModelBuilder() {}
virtual LLInvFVBridge* createBridge(LLAssetType::EType asset_type,
LLAssetType::EType actual_asset_type,
LLInventoryType::EType inv_type,
LLInventoryPanel* inventory,
+ LLFolderViewModelInventory* view_model,
LLFolderView* root,
const LLUUID& uuid,
U32 flags = 0x00) const;
@@ -197,13 +213,14 @@ public:
const LLUUID& uuid) :
LLInvFVBridge(inventory, root, uuid) {}
+ typedef boost::function<void(std::string& slurl)> slurl_callback_t;
+
virtual void performAction(LLInventoryModel* model, std::string action);
virtual void selectItem();
virtual void restoreItem();
virtual void restoreToWorld();
virtual void gotoItem();
virtual LLUIImagePtr getIcon() const;
- virtual const std::string& getDisplayName() const;
virtual std::string getLabelSuffix() const;
virtual LLFontGL::StyleFlags getLabelStyle() const;
virtual PermissionMask getPermissionMask() const;
@@ -212,19 +229,17 @@ public:
virtual BOOL renameItem(const std::string& new_name);
virtual BOOL removeItem();
virtual BOOL isItemCopyable() const;
- virtual BOOL hasChildren() const { return FALSE; }
+ virtual bool hasChildren() const { return FALSE; }
virtual BOOL isUpToDate() const { return TRUE; }
-
- /*virtual*/ void clearDisplayName() { mDisplayName.clear(); }
+ virtual LLUIImagePtr getIconOverlay() const;
LLViewerInventoryItem* getItem() const;
protected:
BOOL confirmRemoveItem(const LLSD& notification, const LLSD& response);
virtual BOOL isItemPermissive() const;
- static void buildDisplayName(LLInventoryItem* item, std::string& name);
+ virtual void buildDisplayName() const;
- mutable std::string mDisplayName;
};
class LLFolderBridge : public LLInvFVBridge
@@ -232,15 +247,18 @@ class LLFolderBridge : public LLInvFVBridge
public:
LLFolderBridge(LLInventoryPanel* inventory,
LLFolderView* root,
- const LLUUID& uuid) :
- LLInvFVBridge(inventory, root, uuid),
+ const LLUUID& uuid)
+ : LLInvFVBridge(inventory, root, uuid),
mCallingCards(FALSE),
- mWearables(FALSE)
+ mWearables(FALSE),
+ mIsLoading(false)
{}
BOOL dragItemIntoFolder(LLInventoryItem* inv_item, BOOL drop, std::string& tooltip_msg);
BOOL dragCategoryIntoFolder(LLInventoryCategory* inv_category, BOOL drop, std::string& tooltip_msg);
+ virtual void buildDisplayName() const;
+
virtual void performAction(LLInventoryModel* model, std::string action);
virtual void openItem();
virtual void closeItem();
@@ -250,7 +268,9 @@ public:
virtual LLFolderType::EType getPreferredType() const;
virtual LLUIImagePtr getIcon() const;
- virtual LLUIImagePtr getOpenIcon() const;
+ virtual LLUIImagePtr getIconOpen() const;
+ virtual LLUIImagePtr getIconOverlay() const;
+
static LLUIImagePtr getIcon(LLFolderType::EType preferred_type);
virtual BOOL renameItem(const std::string& new_name);
@@ -258,11 +278,12 @@ public:
virtual BOOL removeItem();
BOOL removeSystemFolder();
bool removeItemResponse(const LLSD& notification, const LLSD& response);
+ void updateHierarchyCreationDate(time_t date);
virtual void pasteFromClipboard();
virtual void pasteLinkFromClipboard();
virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
- virtual BOOL hasChildren() const;
+ virtual bool hasChildren() const;
virtual BOOL dragOrDrop(MASK mask, BOOL drop,
EDragAndDropType cargo_type,
void* cargo_data,
@@ -275,20 +296,24 @@ public:
virtual BOOL isClipboardPasteable() const;
virtual BOOL isClipboardPasteableAsLink() const;
+ EInventorySortGroup getSortGroup() const;
+ virtual void update();
+
static void createWearable(LLFolderBridge* bridge, LLWearableType::EType type);
LLViewerInventoryCategory* getCategory() const;
LLHandle<LLFolderBridge> getHandle() { mHandle.bind(this); return mHandle; }
+ bool isLoading() { return mIsLoading; }
+
protected:
- void buildContextMenuBaseOptions(U32 flags);
- void buildContextMenuFolderOptions(U32 flags);
+ void buildContextMenuOptions(U32 flags, menuentry_vec_t& items, menuentry_vec_t& disabled_items);
+ void buildContextMenuFolderOptions(U32 flags, menuentry_vec_t& items, menuentry_vec_t& disabled_items);
//--------------------------------------------------------------------
// Menu callbacks
//--------------------------------------------------------------------
static void pasteClipboard(void* user_data);
- static void createNewCategory(void* user_data);
static void createNewShirt(void* user_data);
static void createNewPants(void* user_data);
static void createNewShoes(void* user_data);
@@ -308,8 +333,6 @@ protected:
void modifyOutfit(BOOL append);
void determineFolderType();
- menuentry_vec_t getMenuItems() { return mItems; } // returns a copy of current menu items
-
void dropToFavorites(LLInventoryItem* inv_item);
void dropToOutfit(LLInventoryItem* inv_item, BOOL move_is_into_current_outfit);
@@ -321,10 +344,11 @@ public:
static void staticFolderOptionsMenu();
private:
- BOOL mCallingCards;
- BOOL mWearables;
- menuentry_vec_t mItems;
- menuentry_vec_t mDisabledItems;
+
+ bool mCallingCards;
+ bool mWearables;
+ bool mIsLoading;
+ LLTimer mTimeSinceRequestStart;
LLRootHandle<LLFolderBridge> mHandle;
};
@@ -354,7 +378,6 @@ public:
const LLUUID& uuid) :
LLItemBridge(inventory, root, uuid) {}
virtual void openItem();
- virtual void previewItem();
virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
static void openSoundPreview(void*);
};
@@ -486,10 +509,10 @@ public:
static void onWearOnAvatar( void* userdata ); // Access to wearOnAvatar() from menu
static BOOL canWearOnAvatar( void* userdata );
- static void onWearOnAvatarArrived( LLWearable* wearable, void* userdata );
+ static void onWearOnAvatarArrived( LLViewerWearable* wearable, void* userdata );
void wearOnAvatar();
- static void onWearAddOnAvatarArrived( LLWearable* wearable, void* userdata );
+ static void onWearAddOnAvatarArrived( LLViewerWearable* wearable, void* userdata );
void wearAddOnAvatar();
static BOOL canEditOnAvatar( void* userdata ); // Access to editOnAvatar() from menu
@@ -497,9 +520,6 @@ public:
void editOnAvatar();
static BOOL canRemoveFromAvatar( void* userdata );
- static void onRemoveFromAvatar( void* userdata );
- static void onRemoveFromAvatarArrived( LLWearable* wearable, void* userdata );
- static void removeItemFromAvatar(LLViewerInventoryItem *item);
static void removeAllClothesFromAvatar();
void removeFromAvatar();
protected:
@@ -544,7 +564,6 @@ class LLMeshBridge : public LLItemBridge
public:
virtual LLUIImagePtr getIcon() const;
virtual void openItem();
- virtual void previewItem();
virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
protected:
@@ -620,7 +639,7 @@ public:
};
// Bridge builder to create Inventory-Folder-View-Bridge for Recent Inventory Panel
-class LLRecentInventoryBridgeBuilder : public LLInventoryFVBridgeBuilder
+class LLRecentInventoryBridgeBuilder : public LLInventoryFolderViewModelBuilder
{
public:
// Overrides FolderBridge for Recent Inventory Panel.
@@ -629,6 +648,7 @@ public:
LLAssetType::EType actual_asset_type,
LLInventoryType::EType inv_type,
LLInventoryPanel* inventory,
+ LLFolderViewModelInventory* view_model,
LLFolderView* root,
const LLUUID& uuid,
U32 flags = 0x00) const;
diff --git a/indra/newview/llinventoryclipboard.cpp b/indra/newview/llinventoryclipboard.cpp
index 53da34f448..53da34f448 100644..100755
--- a/indra/newview/llinventoryclipboard.cpp
+++ b/indra/newview/llinventoryclipboard.cpp
diff --git a/indra/newview/llinventoryclipboard.h b/indra/newview/llinventoryclipboard.h
index b9f1451e5c..b9f1451e5c 100644..100755
--- a/indra/newview/llinventoryclipboard.h
+++ b/indra/newview/llinventoryclipboard.h
diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp
index 4d0af94f9f..3c6974cf6d 100644..100755
--- a/indra/newview/llinventoryfilter.cpp
+++ b/indra/newview/llinventoryfilter.cpp
@@ -29,7 +29,7 @@
#include "llinventoryfilter.h"
// viewer includes
-#include "llfoldervieweventlistener.h"
+#include "llfolderviewmodel.h"
#include "llfolderviewitem.h"
#include "llinventorymodel.h"
#include "llinventorymodelbackgroundfetch.h"
@@ -44,107 +44,76 @@
LLFastTimer::DeclareTimer FT_FILTER_CLIPBOARD("Filter Clipboard");
-LLInventoryFilter::FilterOps::FilterOps() :
- mFilterObjectTypes(0xffffffffffffffffULL),
- mFilterCategoryTypes(0xffffffffffffffffULL),
- mFilterWearableTypes(0xffffffffffffffffULL),
- mMinDate(time_min()),
- mMaxDate(time_max()),
- mHoursAgo(0),
- mShowFolderState(SHOW_NON_EMPTY_FOLDERS),
- mPermissions(PERM_NONE),
- mFilterTypes(FILTERTYPE_OBJECT),
- mFilterUUID(LLUUID::null),
- mFilterLinks(FILTERLINK_INCLUDE_LINKS)
+LLInventoryFilter::FilterOps::FilterOps(const Params& p)
+: mFilterObjectTypes(p.object_types),
+ mFilterCategoryTypes(p.category_types),
+ mFilterWearableTypes(p.wearable_types),
+ mMinDate(p.date_range.min_date),
+ mMaxDate(p.date_range.max_date),
+ mHoursAgo(p.hours_ago),
+ mShowFolderState(p.show_folder_state),
+ mPermissions(p.permissions),
+ mFilterTypes(p.types),
+ mFilterUUID(p.uuid),
+ mFilterLinks(p.links)
{
}
///----------------------------------------------------------------------------
/// Class LLInventoryFilter
///----------------------------------------------------------------------------
-LLInventoryFilter::LLInventoryFilter(const std::string& name)
-: mName(name),
- mModified(FALSE),
- mNeedTextRebuild(TRUE),
- mEmptyLookupMessage("InventoryNoMatchingItems")
+LLInventoryFilter::LLInventoryFilter(const Params& p)
+: mName(p.name),
+ mFilterModified(FILTER_NONE),
+ mEmptyLookupMessage("InventoryNoMatchingItems"),
+ mFilterOps(p.filter_ops),
+ mFilterSubString(p.substring),
+ mCurrentGeneration(0),
+ mFirstRequiredGeneration(0),
+ mFirstSuccessGeneration(0)
{
- mOrder = SO_FOLDERS_BY_NAME; // This gets overridden by a pref immediately
-
- mSubStringMatchOffset = 0;
- mFilterSubString.clear();
- mFilterGeneration = 0;
- mMustPassGeneration = S32_MAX;
- mMinRequiredGeneration = 0;
- mFilterCount = 0;
- mNextFilterGeneration = mFilterGeneration + 1;
-
- mLastLogoff = gSavedPerAccountSettings.getU32("LastLogoff");
- mFilterBehavior = FILTER_NONE;
-
// copy mFilterOps into mDefaultFilterOps
markDefault();
}
-LLInventoryFilter::~LLInventoryFilter()
-{
-}
-
-BOOL LLInventoryFilter::check(const LLFolderViewItem* item)
+bool LLInventoryFilter::check(const LLFolderViewModelItem* item)
{
+ const LLFolderViewModelItemInventory* listener = dynamic_cast<const LLFolderViewModelItemInventory*>(item);
// Clipboard cut items are *always* filtered so we need this value upfront
- const LLFolderViewEventListener* listener = item->getListener();
const BOOL passed_clipboard = (listener ? checkAgainstClipboard(listener->getUUID()) : TRUE);
// If it's a folder and we're showing all folders, return automatically.
- const BOOL is_folder = (dynamic_cast<const LLFolderViewFolder*>(item) != NULL);
+ const BOOL is_folder = listener->getInventoryType() == LLInventoryType::IT_CATEGORY;
if (is_folder && (mFilterOps.mShowFolderState == LLInventoryFilter::SHOW_ALL_FOLDERS))
{
return passed_clipboard;
}
- mSubStringMatchOffset = mFilterSubString.size() ? item->getSearchableLabel().find(mFilterSubString) : std::string::npos;
-
- const BOOL passed_filtertype = checkAgainstFilterType(item);
- const BOOL passed_permissions = checkAgainstPermissions(item);
- const BOOL passed_filterlink = checkAgainstFilterLinks(item);
- const BOOL passed = (passed_filtertype &&
- passed_permissions &&
- passed_filterlink &&
- passed_clipboard &&
- (mFilterSubString.size() == 0 || mSubStringMatchOffset != std::string::npos));
+ bool passed = (mFilterSubString.size() ? listener->getSearchableName().find(mFilterSubString) != std::string::npos : true);
+ passed = passed && checkAgainstFilterType(listener);
+ passed = passed && checkAgainstPermissions(listener);
+ passed = passed && checkAgainstFilterLinks(listener);
+ passed = passed && passed_clipboard;
return passed;
}
bool LLInventoryFilter::check(const LLInventoryItem* item)
{
- mSubStringMatchOffset = mFilterSubString.size() ? item->getName().find(mFilterSubString) : std::string::npos;
-
+ const bool passed_string = (mFilterSubString.size() ? item->getName().find(mFilterSubString) != std::string::npos : true);
const bool passed_filtertype = checkAgainstFilterType(item);
const bool passed_permissions = checkAgainstPermissions(item);
- const BOOL passed_clipboard = checkAgainstClipboard(item->getUUID());
- const bool passed = (passed_filtertype &&
- passed_permissions &&
- passed_clipboard &&
- (mFilterSubString.size() == 0 || mSubStringMatchOffset != std::string::npos));
+ const bool passed_clipboard = checkAgainstClipboard(item->getUUID());
- return passed;
+ return passed_filtertype && passed_permissions && passed_clipboard && passed_string;
}
-bool LLInventoryFilter::checkFolder(const LLFolderViewFolder* folder) const
+bool LLInventoryFilter::checkFolder(const LLFolderViewModelItem* item) const
{
- if (!folder)
- {
- llwarns << "The filter can not be checked on an invalid folder." << llendl;
- llassert(false); // crash in development builds
- return false;
- }
-
- const LLFolderViewEventListener* listener = folder->getListener();
+ const LLFolderViewModelItemInventory* listener = dynamic_cast<const LLFolderViewModelItemInventory*>(item);
if (!listener)
{
- llwarns << "Folder view event listener not found." << llendl;
- llassert(false); // crash in development builds
+ llerrs << "Folder view event listener not found." << llendl;
return false;
}
@@ -155,6 +124,13 @@ bool LLInventoryFilter::checkFolder(const LLFolderViewFolder* folder) const
bool LLInventoryFilter::checkFolder(const LLUUID& folder_id) const
{
+ // when applying a filter, matching folders get their contents downloaded first
+ if (isNotDefault()
+ && !gInventory.isCategoryComplete(folder_id))
+ {
+ LLInventoryModelBackgroundFetch::instance().start(folder_id);
+ }
+
// Always check against the clipboard
const BOOL passed_clipboard = checkAgainstClipboard(folder_id);
@@ -163,14 +139,14 @@ bool LLInventoryFilter::checkFolder(const LLUUID& folder_id) const
{
return passed_clipboard;
}
-
+
if (mFilterOps.mFilterTypes & FILTERTYPE_CATEGORY)
{
// Can only filter categories for items in your inventory
// (e.g. versus in-world object contents).
const LLViewerInventoryCategory *cat = gInventory.getCategory(folder_id);
if (!cat)
- return false;
+ return folder_id.isNull();
LLFolderType::EType cat_type = cat->getPreferredType();
if (cat_type != LLFolderType::FT_NONE && (1LL << cat_type & mFilterOps.mFilterCategoryTypes) == U64(0))
return false;
@@ -179,9 +155,8 @@ bool LLInventoryFilter::checkFolder(const LLUUID& folder_id) const
return passed_clipboard;
}
-BOOL LLInventoryFilter::checkAgainstFilterType(const LLFolderViewItem* item) const
+bool LLInventoryFilter::checkAgainstFilterType(const LLFolderViewModelItemInventory* listener) const
{
- const LLFolderViewEventListener* listener = item->getListener();
if (!listener) return FALSE;
LLInventoryType::EType object_type = listener->getInventoryType();
@@ -268,7 +243,7 @@ BOOL LLInventoryFilter::checkAgainstFilterType(const LLFolderViewItem* item) con
}
}
}
-
+
return TRUE;
}
@@ -347,13 +322,12 @@ bool LLInventoryFilter::checkAgainstClipboard(const LLUUID& object_id) const
return true;
}
-BOOL LLInventoryFilter::checkAgainstPermissions(const LLFolderViewItem* item) const
+bool LLInventoryFilter::checkAgainstPermissions(const LLFolderViewModelItemInventory* listener) const
{
- const LLFolderViewEventListener* listener = item->getListener();
if (!listener) return FALSE;
PermissionMask perm = listener->getPermissionMask();
- const LLInvFVBridge *bridge = dynamic_cast<const LLInvFVBridge *>(item->getListener());
+ const LLInvFVBridge *bridge = dynamic_cast<const LLInvFVBridge *>(listener);
if (bridge && bridge->isLink())
{
const LLUUID& linked_uuid = gInventory.getLinkedItemID(bridge->getUUID());
@@ -375,9 +349,8 @@ bool LLInventoryFilter::checkAgainstPermissions(const LLInventoryItem* item) con
return (perm & mFilterOps.mPermissions) == mFilterOps.mPermissions;
}
-BOOL LLInventoryFilter::checkAgainstFilterLinks(const LLFolderViewItem* item) const
+bool LLInventoryFilter::checkAgainstFilterLinks(const LLFolderViewModelItemInventory* listener) const
{
- const LLFolderViewEventListener* listener = item->getListener();
if (!listener) return TRUE;
const LLUUID object_id = listener->getUUID();
@@ -397,20 +370,20 @@ const std::string& LLInventoryFilter::getFilterSubString(BOOL trim) const
return mFilterSubString;
}
-std::string::size_type LLInventoryFilter::getStringMatchOffset() const
+std::string::size_type LLInventoryFilter::getStringMatchOffset(LLFolderViewModelItem* item) const
{
- return mSubStringMatchOffset;
+ return mFilterSubString.size() ? item->getSearchableName().find(mFilterSubString) : std::string::npos;
}
-BOOL LLInventoryFilter::isDefault() const
+bool LLInventoryFilter::isDefault() const
{
return !isNotDefault();
}
// has user modified default filter params?
-BOOL LLInventoryFilter::isNotDefault() const
+bool LLInventoryFilter::isNotDefault() const
{
- BOOL not_default = FALSE;
+ S32 not_default = 0;
not_default |= (mFilterOps.mFilterObjectTypes != mDefaultFilterOps.mFilterObjectTypes);
not_default |= (mFilterOps.mFilterCategoryTypes != mDefaultFilterOps.mFilterCategoryTypes);
@@ -422,11 +395,11 @@ BOOL LLInventoryFilter::isNotDefault() const
not_default |= (mFilterOps.mMinDate != mDefaultFilterOps.mMinDate);
not_default |= (mFilterOps.mMaxDate != mDefaultFilterOps.mMaxDate);
not_default |= (mFilterOps.mHoursAgo != mDefaultFilterOps.mHoursAgo);
-
- return not_default;
+
+ return not_default != 0;
}
-BOOL LLInventoryFilter::isActive() const
+bool LLInventoryFilter::isActive() const
{
return mFilterOps.mFilterObjectTypes != 0xffffffffffffffffULL
|| mFilterOps.mFilterCategoryTypes != 0xffffffffffffffffULL
@@ -440,16 +413,9 @@ BOOL LLInventoryFilter::isActive() const
|| mFilterOps.mHoursAgo != 0;
}
-BOOL LLInventoryFilter::isModified() const
+bool LLInventoryFilter::isModified() const
{
- return mModified;
-}
-
-BOOL LLInventoryFilter::isModifiedAndClear()
-{
- BOOL ret = mModified;
- mModified = FALSE;
- return ret;
+ return mFilterModified != FILTER_NONE;
}
void LLInventoryFilter::updateFilterTypes(U64 types, U64& current_types)
@@ -463,7 +429,7 @@ void LLInventoryFilter::updateFilterTypes(U64 types, U64& current_types)
current_types = types;
if (more_bits_set && fewer_bits_set)
{
- // neither less or more restrive, both simultaneously
+ // neither less or more restrictive, both simultaneously
// so we need to filter from scratch
setModified(FILTER_RESTART);
}
@@ -613,9 +579,10 @@ void LLInventoryFilter::setDateRange(time_t min_date, time_t max_date)
void LLInventoryFilter::setDateRangeLastLogoff(BOOL sl)
{
+ static LLCachedControl<U32> s_last_logoff(gSavedPerAccountSettings, "LastLogoff", 0);
if (sl && !isSinceLogoff())
{
- setDateRange(mLastLogoff, time_max());
+ setDateRange(s_last_logoff(), time_max());
setModified();
}
if (!sl && isSinceLogoff())
@@ -634,17 +601,18 @@ void LLInventoryFilter::setDateRangeLastLogoff(BOOL sl)
}
}
-BOOL LLInventoryFilter::isSinceLogoff() const
+bool LLInventoryFilter::isSinceLogoff() const
{
- return (mFilterOps.mMinDate == (time_t)mLastLogoff) &&
+ static LLCachedControl<U32> s_last_logoff(gSavedSettings, "LastLogoff", 0);
+
+ return (mFilterOps.mMinDate == (time_t)s_last_logoff()) &&
(mFilterOps.mMaxDate == time_max()) &&
(mFilterOps.mFilterTypes & FILTERTYPE_DATE);
}
void LLInventoryFilter::clearModified()
{
- mModified = FALSE;
- mFilterBehavior = FILTER_NONE;
+ mFilterModified = FILTER_NONE;
}
void LLInventoryFilter::setHoursAgo(U32 hours)
@@ -654,7 +622,7 @@ void LLInventoryFilter::setHoursAgo(U32 hours)
bool are_date_limits_valid = mFilterOps.mMinDate == time_min() && mFilterOps.mMaxDate == time_max();
bool is_increasing = hours > mFilterOps.mHoursAgo;
- bool is_increasing_from_zero = is_increasing && !mFilterOps.mHoursAgo;
+ bool is_increasing_from_zero = is_increasing && !mFilterOps.mHoursAgo && !isSinceLogoff();
// *NOTE: need to cache last filter time, in case filter goes stale
BOOL less_restrictive = (are_date_limits_valid && ((is_increasing && mFilterOps.mHoursAgo)) || !hours);
@@ -722,15 +690,6 @@ void LLInventoryFilter::setShowFolderState(EFolderShow state)
}
}
-void LLInventoryFilter::setSortOrder(U32 order)
-{
- if (mOrder != order)
- {
- mOrder = order;
- setModified();
- }
-}
-
void LLInventoryFilter::markDefault()
{
mDefaultFilterOps = mFilterOps;
@@ -742,83 +701,68 @@ void LLInventoryFilter::resetDefault()
setModified();
}
-void LLInventoryFilter::setModified(EFilterBehavior behavior)
+void LLInventoryFilter::setModified(EFilterModified behavior)
{
- mModified = TRUE;
- mNeedTextRebuild = TRUE;
- mFilterGeneration = mNextFilterGeneration++;
+ mFilterText.clear();
+ mCurrentGeneration++;
- if (mFilterBehavior == FILTER_NONE)
+ if (mFilterModified == FILTER_NONE)
{
- mFilterBehavior = behavior;
+ mFilterModified = behavior;
}
- else if (mFilterBehavior != behavior)
+ else if (mFilterModified != behavior)
{
// trying to do both less restrictive and more restrictive filter
// basically means restart from scratch
- mFilterBehavior = FILTER_RESTART;
+ mFilterModified = FILTER_RESTART;
}
- if (isNotDefault())
+ // if not keeping current filter results, update last valid as well
+ switch(mFilterModified)
{
- // if not keeping current filter results, update last valid as well
- switch(mFilterBehavior)
- {
- case FILTER_RESTART:
- mMustPassGeneration = mFilterGeneration;
- mMinRequiredGeneration = mFilterGeneration;
- break;
- case FILTER_LESS_RESTRICTIVE:
- mMustPassGeneration = mFilterGeneration;
- break;
- case FILTER_MORE_RESTRICTIVE:
- mMinRequiredGeneration = mFilterGeneration;
- // must have passed either current filter generation (meaningless, as it hasn't been run yet)
- // or some older generation, so keep the value
- mMustPassGeneration = llmin(mMustPassGeneration, mFilterGeneration);
- break;
- default:
- llerrs << "Bad filter behavior specified" << llendl;
- }
- }
- else
- {
- // shortcut disabled filters to show everything immediately
- mMinRequiredGeneration = 0;
- mMustPassGeneration = S32_MAX;
+ case FILTER_RESTART:
+ mFirstRequiredGeneration = mCurrentGeneration;
+ mFirstSuccessGeneration = mCurrentGeneration;
+ break;
+ case FILTER_LESS_RESTRICTIVE:
+ mFirstRequiredGeneration = mCurrentGeneration;
+ break;
+ case FILTER_MORE_RESTRICTIVE:
+ mFirstSuccessGeneration = mCurrentGeneration;
+ break;
+ default:
+ llerrs << "Bad filter behavior specified" << llendl;
}
}
-BOOL LLInventoryFilter::isFilterObjectTypesWith(LLInventoryType::EType t) const
+bool LLInventoryFilter::isFilterObjectTypesWith(LLInventoryType::EType t) const
{
return mFilterOps.mFilterObjectTypes & (1LL << t);
}
const std::string& LLInventoryFilter::getFilterText()
{
- if (!mNeedTextRebuild)
+ if (!mFilterText.empty())
{
return mFilterText;
}
- mNeedTextRebuild = FALSE;
std::string filtered_types;
std::string not_filtered_types;
BOOL filtered_by_type = FALSE;
BOOL filtered_by_all_types = TRUE;
S32 num_filter_types = 0;
+
mFilterText.clear();
if (isFilterObjectTypesWith(LLInventoryType::IT_ANIMATION))
{
- //filtered_types += " Animations,";
filtered_types += LLTrans::getString("Animations");
filtered_by_type = TRUE;
num_filter_types++;
}
else
{
- //not_filtered_types += " Animations,";
not_filtered_types += LLTrans::getString("Animations");
filtered_by_all_types = FALSE;
@@ -826,140 +770,120 @@ const std::string& LLInventoryFilter::getFilterText()
if (isFilterObjectTypesWith(LLInventoryType::IT_CALLINGCARD))
{
- //filtered_types += " Calling Cards,";
filtered_types += LLTrans::getString("Calling Cards");
filtered_by_type = TRUE;
num_filter_types++;
}
else
{
- //not_filtered_types += " Calling Cards,";
not_filtered_types += LLTrans::getString("Calling Cards");
filtered_by_all_types = FALSE;
}
if (isFilterObjectTypesWith(LLInventoryType::IT_WEARABLE))
{
- //filtered_types += " Clothing,";
filtered_types += LLTrans::getString("Clothing");
filtered_by_type = TRUE;
num_filter_types++;
}
else
{
- //not_filtered_types += " Clothing,";
not_filtered_types += LLTrans::getString("Clothing");
filtered_by_all_types = FALSE;
}
if (isFilterObjectTypesWith(LLInventoryType::IT_GESTURE))
{
- //filtered_types += " Gestures,";
filtered_types += LLTrans::getString("Gestures");
filtered_by_type = TRUE;
num_filter_types++;
}
else
{
- //not_filtered_types += " Gestures,";
not_filtered_types += LLTrans::getString("Gestures");
filtered_by_all_types = FALSE;
}
if (isFilterObjectTypesWith(LLInventoryType::IT_LANDMARK))
{
- //filtered_types += " Landmarks,";
filtered_types += LLTrans::getString("Landmarks");
filtered_by_type = TRUE;
num_filter_types++;
}
else
{
- //not_filtered_types += " Landmarks,";
not_filtered_types += LLTrans::getString("Landmarks");
filtered_by_all_types = FALSE;
}
if (isFilterObjectTypesWith(LLInventoryType::IT_NOTECARD))
{
- //filtered_types += " Notecards,";
filtered_types += LLTrans::getString("Notecards");
filtered_by_type = TRUE;
num_filter_types++;
}
else
{
- //not_filtered_types += " Notecards,";
not_filtered_types += LLTrans::getString("Notecards");
filtered_by_all_types = FALSE;
}
if (isFilterObjectTypesWith(LLInventoryType::IT_OBJECT) && isFilterObjectTypesWith(LLInventoryType::IT_ATTACHMENT))
{
- //filtered_types += " Objects,";
filtered_types += LLTrans::getString("Objects");
filtered_by_type = TRUE;
num_filter_types++;
}
else
{
- //not_filtered_types += " Objects,";
not_filtered_types += LLTrans::getString("Objects");
filtered_by_all_types = FALSE;
}
if (isFilterObjectTypesWith(LLInventoryType::IT_LSL))
{
- //filtered_types += " Scripts,";
filtered_types += LLTrans::getString("Scripts");
filtered_by_type = TRUE;
num_filter_types++;
}
else
{
- //not_filtered_types += " Scripts,";
not_filtered_types += LLTrans::getString("Scripts");
filtered_by_all_types = FALSE;
}
if (isFilterObjectTypesWith(LLInventoryType::IT_SOUND))
{
- //filtered_types += " Sounds,";
filtered_types += LLTrans::getString("Sounds");
filtered_by_type = TRUE;
num_filter_types++;
}
else
{
- //not_filtered_types += " Sounds,";
not_filtered_types += LLTrans::getString("Sounds");
filtered_by_all_types = FALSE;
}
if (isFilterObjectTypesWith(LLInventoryType::IT_TEXTURE))
{
- //filtered_types += " Textures,";
filtered_types += LLTrans::getString("Textures");
filtered_by_type = TRUE;
num_filter_types++;
}
else
{
- //not_filtered_types += " Textures,";
not_filtered_types += LLTrans::getString("Textures");
filtered_by_all_types = FALSE;
}
if (isFilterObjectTypesWith(LLInventoryType::IT_SNAPSHOT))
{
- //filtered_types += " Snapshots,";
filtered_types += LLTrans::getString("Snapshots");
filtered_by_type = TRUE;
num_filter_types++;
}
else
{
- //not_filtered_types += " Snapshots,";
not_filtered_types += LLTrans::getString("Snapshots");
filtered_by_all_types = FALSE;
}
@@ -975,7 +899,6 @@ const std::string& LLInventoryFilter::getFilterText()
}
else
{
- //mFilterText += "No ";
mFilterText += LLTrans::getString("No Filters");
mFilterText += not_filtered_types;
}
@@ -985,66 +908,55 @@ const std::string& LLInventoryFilter::getFilterText()
if (isSinceLogoff())
{
- //mFilterText += " - Since Logoff";
mFilterText += LLTrans::getString("Since Logoff");
}
return mFilterText;
}
-void LLInventoryFilter::toLLSD(LLSD& data) const
-{
- data["filter_types"] = (LLSD::Integer)getFilterObjectTypes();
- data["min_date"] = (LLSD::Integer)getMinDate();
- data["max_date"] = (LLSD::Integer)getMaxDate();
- data["hours_ago"] = (LLSD::Integer)getHoursAgo();
- data["show_folder_state"] = (LLSD::Integer)getShowFolderState();
- data["permissions"] = (LLSD::Integer)getFilterPermissions();
- data["substring"] = (LLSD::String)getFilterSubString();
- data["sort_order"] = (LLSD::Integer)getSortOrder();
- data["since_logoff"] = (LLSD::Boolean)isSinceLogoff();
-}
-void LLInventoryFilter::fromLLSD(LLSD& data)
+LLInventoryFilter& LLInventoryFilter::operator=( const LLInventoryFilter& other )
{
- if(data.has("filter_types"))
- {
- setFilterObjectTypes((U64)data["filter_types"].asInteger());
- }
-
- if(data.has("min_date") && data.has("max_date"))
- {
- setDateRange(data["min_date"].asInteger(), data["max_date"].asInteger());
- }
-
- if(data.has("hours_ago"))
- {
- setHoursAgo((U32)data["hours_ago"].asInteger());
- }
-
- if(data.has("show_folder_state"))
- {
- setShowFolderState((EFolderShow)data["show_folder_state"].asInteger());
- }
+ setFilterObjectTypes(other.getFilterObjectTypes());
+ setDateRange(other.getMinDate(), other.getMaxDate());
+ setHoursAgo(other.getHoursAgo());
+ setShowFolderState(other.getShowFolderState());
+ setFilterPermissions(other.getFilterPermissions());
+ setFilterSubString(other.getFilterSubString());
+ setDateRangeLastLogoff(other.isSinceLogoff());
+ return *this;
+}
- if(data.has("permissions"))
- {
- setFilterPermissions((PermissionMask)data["permissions"].asInteger());
- }
- if(data.has("substring"))
- {
- setFilterSubString(std::string(data["substring"].asString()));
- }
+void LLInventoryFilter::toParams(Params& params) const
+{
+ params.filter_ops.types = getFilterObjectTypes();
+ params.filter_ops.category_types = getFilterCategoryTypes();
+ params.filter_ops.wearable_types = getFilterWearableTypes();
+ params.filter_ops.date_range.min_date = getMinDate();
+ params.filter_ops.date_range.max_date = getMaxDate();
+ params.filter_ops.hours_ago = getHoursAgo();
+ params.filter_ops.show_folder_state = getShowFolderState();
+ params.filter_ops.permissions = getFilterPermissions();
+ params.substring = getFilterSubString();
+ params.since_logoff = isSinceLogoff();
+}
- if(data.has("sort_order"))
+void LLInventoryFilter::fromParams(const Params& params)
+{
+ if (!params.validateBlock())
{
- setSortOrder((U32)data["sort_order"].asInteger());
+ return;
}
- if(data.has("since_logoff"))
- {
- setDateRangeLastLogoff((bool)data["since_logoff"].asBoolean());
- }
+ setFilterObjectTypes(params.filter_ops.types);
+ setFilterCategoryTypes(params.filter_ops.category_types);
+ setFilterWearableTypes(params.filter_ops.wearable_types);
+ setDateRange(params.filter_ops.date_range.min_date, params.filter_ops.date_range.max_date);
+ setHoursAgo(params.filter_ops.hours_ago);
+ setShowFolderState(params.filter_ops.show_folder_state);
+ setFilterPermissions(params.filter_ops.permissions);
+ setFilterSubString(params.substring);
+ setDateRangeLastLogoff(params.since_logoff);
}
U64 LLInventoryFilter::getFilterObjectTypes() const
@@ -1057,11 +969,21 @@ U64 LLInventoryFilter::getFilterCategoryTypes() const
return mFilterOps.mFilterCategoryTypes;
}
-BOOL LLInventoryFilter::hasFilterString() const
+U64 LLInventoryFilter::getFilterWearableTypes() const
+{
+ return mFilterOps.mFilterWearableTypes;
+}
+
+bool LLInventoryFilter::hasFilterString() const
{
return mFilterSubString.size() > 0;
}
+std::string::size_type LLInventoryFilter::getFilterStringSize() const
+{
+ return mFilterSubString.size();
+}
+
PermissionMask LLInventoryFilter::getFilterPermissions() const
{
return mFilterOps.mPermissions;
@@ -1088,40 +1010,30 @@ LLInventoryFilter::EFolderShow LLInventoryFilter::getShowFolderState() const
{
return mFilterOps.mShowFolderState;
}
-U32 LLInventoryFilter::getSortOrder() const
-{
- return mOrder;
-}
-const std::string& LLInventoryFilter::getName() const
-{
- return mName;
-}
-void LLInventoryFilter::setFilterCount(S32 count)
-{
- mFilterCount = count;
-}
-S32 LLInventoryFilter::getFilterCount() const
+bool LLInventoryFilter::isTimedOut()
{
- return mFilterCount;
+ return mFilterTime.hasExpired();
}
-void LLInventoryFilter::decrementFilterCount()
-{
- mFilterCount--;
+void LLInventoryFilter::resetTime(S32 timeout)
+{
+ mFilterTime.reset();
+ F32 time_in_sec = (F32)(timeout)/1000.0;
+ mFilterTime.setTimerExpirySec(time_in_sec);
}
-S32 LLInventoryFilter::getCurrentGeneration() const
+S32 LLInventoryFilter::getCurrentGeneration() const
{
- return mFilterGeneration;
+ return mCurrentGeneration;
}
-S32 LLInventoryFilter::getMinRequiredGeneration() const
+S32 LLInventoryFilter::getFirstSuccessGeneration() const
{
- return mMinRequiredGeneration;
+ return mFirstSuccessGeneration;
}
-S32 LLInventoryFilter::getMustPassGeneration() const
+S32 LLInventoryFilter::getFirstRequiredGeneration() const
{
- return mMustPassGeneration;
+ return mFirstRequiredGeneration;
}
void LLInventoryFilter::setEmptyLookupMessage(const std::string& message)
@@ -1129,9 +1041,12 @@ void LLInventoryFilter::setEmptyLookupMessage(const std::string& message)
mEmptyLookupMessage = message;
}
-const std::string& LLInventoryFilter::getEmptyLookupMessage() const
+std::string LLInventoryFilter::getEmptyLookupMessage() const
{
- return mEmptyLookupMessage;
+ LLStringUtil::format_map_t args;
+ args["[SEARCH_TERM]"] = LLURI::escape(getFilterSubStringOrig());
+
+ return LLTrans::getString(mEmptyLookupMessage, args);
}
@@ -1141,3 +1056,27 @@ bool LLInventoryFilter::areDateLimitsSet()
|| mFilterOps.mMaxDate != time_max()
|| mFilterOps.mHoursAgo != 0;
}
+
+bool LLInventoryFilter::showAllResults() const
+{
+ return hasFilterString();
+}
+
+
+
+bool LLInventoryFilter::FilterOps::DateRange::validateBlock( bool emit_errors /*= true*/ ) const
+{
+ bool valid = LLInitParam::Block<DateRange>::validateBlock(emit_errors);
+ if (valid)
+ {
+ if (max_date() < min_date())
+ {
+ if (emit_errors)
+ {
+ llwarns << "max_date should be greater or equal to min_date" << llendl;
+ }
+ valid = false;
+ }
+ }
+ return valid;
+}
diff --git a/indra/newview/llinventoryfilter.h b/indra/newview/llinventoryfilter.h
index 9e600c036f..ce516af0b9 100644..100755
--- a/indra/newview/llinventoryfilter.h
+++ b/indra/newview/llinventoryfilter.h
@@ -29,12 +29,13 @@
#include "llinventorytype.h"
#include "llpermissionsflags.h"
+#include "llfolderviewmodel.h"
class LLFolderViewItem;
class LLFolderViewFolder;
class LLInventoryItem;
-class LLInventoryFilter
+class LLInventoryFilter : public LLFolderViewFilter
{
public:
enum EFolderShow
@@ -44,14 +45,6 @@ public:
SHOW_NO_FOLDERS
};
- enum EFilterBehavior
- {
- FILTER_NONE, // nothing to do, already filtered
- FILTER_RESTART, // restart filtering from scratch
- FILTER_LESS_RESTRICTIVE, // existing filtered items will certainly pass this filter
- FILTER_MORE_RESTRICTIVE // if you didn't pass the previous filter, you definitely won't pass this one
- };
-
enum EFilterType {
FILTERTYPE_NONE = 0,
FILTERTYPE_OBJECT = 0x1 << 0, // normal default search-by-object-type
@@ -59,7 +52,7 @@ public:
FILTERTYPE_UUID = 0x1 << 2, // find the object with UUID and any links to it
FILTERTYPE_DATE = 0x1 << 3, // search by date range
FILTERTYPE_WEARABLE = 0x1 << 4, // search by wearable type
- FILTERTYPE_EMPTYFOLDERS = 0x1 << 5 // pass if folder is not a system folder to be hidden if empty
+ FILTERTYPE_EMPTYFOLDERS = 0x1 << 5 // pass if folder is not a system folder to be hidden if
};
enum EFilterLink
@@ -77,16 +70,92 @@ public:
SO_SYSTEM_FOLDERS_TO_TOP = 0x1 << 2 // Force system folders to be on top
};
- LLInventoryFilter(const std::string& name);
- virtual ~LLInventoryFilter();
+ struct FilterOps
+ {
+ struct DateRange : public LLInitParam::Block<DateRange>
+ {
+ Optional<time_t> min_date,
+ max_date;
+
+ DateRange()
+ : min_date("min_date", time_min()),
+ max_date("max_date", time_max())
+ {}
+
+ bool validateBlock(bool emit_errors = true) const;
+ };
+
+ struct Params : public LLInitParam::Block<Params>
+ {
+ Optional<U32> types;
+ Optional<U64> object_types,
+ wearable_types,
+ category_types;
+ Optional<EFilterLink> links;
+ Optional<LLUUID> uuid;
+ Optional<DateRange> date_range;
+ Optional<S32> hours_ago;
+ Optional<EFolderShow> show_folder_state;
+ Optional<PermissionMask> permissions;
+
+ Params()
+ : types("filter_types", FILTERTYPE_OBJECT),
+ object_types("object_types", 0xffffFFFFffffFFFFULL),
+ wearable_types("wearable_types", 0xffffFFFFffffFFFFULL),
+ category_types("category_types", 0xffffFFFFffffFFFFULL),
+ links("links", FILTERLINK_INCLUDE_LINKS),
+ uuid("uuid"),
+ date_range("date_range"),
+ hours_ago("hours_ago", 0),
+ show_folder_state("show_folder_state", SHOW_NON_EMPTY_FOLDERS),
+ permissions("permissions", PERM_NONE)
+ {}
+ };
+
+ FilterOps(const Params& = Params());
+
+ U32 mFilterTypes;
+ U64 mFilterObjectTypes, // For _OBJECT
+ mFilterWearableTypes,
+ mFilterLinks,
+ mFilterCategoryTypes; // For _CATEGORY
+ LLUUID mFilterUUID; // for UUID
+
+ time_t mMinDate,
+ mMaxDate;
+ U32 mHoursAgo;
+
+ EFolderShow mShowFolderState;
+ PermissionMask mPermissions;
+ };
+
+ struct Params : public LLInitParam::Block<Params>
+ {
+ Optional<std::string> name;
+ Optional<FilterOps::Params> filter_ops;
+ Optional<std::string> substring;
+ Optional<bool> since_logoff;
+
+ Params()
+ : name("name"),
+ filter_ops(""),
+ substring("substring"),
+ since_logoff("since_logoff")
+ {}
+ };
+
+ LLInventoryFilter(const Params& p = Params());
+ LLInventoryFilter(const LLInventoryFilter& other) { *this = other; }
+ virtual ~LLInventoryFilter() {}
// +-------------------------------------------------------------------+
// + Parameters
// +-------------------------------------------------------------------+
- void setFilterObjectTypes(U64 types);
U64 getFilterObjectTypes() const;
U64 getFilterCategoryTypes() const;
- BOOL isFilterObjectTypesWith(LLInventoryType::EType t) const;
+ U64 getFilterWearableTypes() const;
+ bool isFilterObjectTypesWith(LLInventoryType::EType t) const;
+ void setFilterObjectTypes(U64 types);
void setFilterCategoryTypes(U64 types);
void setFilterUUID(const LLUUID &object_id);
void setFilterWearableTypes(U64 types);
@@ -96,7 +165,7 @@ public:
void setFilterSubString(const std::string& string);
const std::string& getFilterSubString(BOOL trim = FALSE) const;
const std::string& getFilterSubStringOrig() const { return mFilterSubStringOrig; }
- BOOL hasFilterString() const;
+ bool hasFilterString() const;
void setFilterPermissions(PermissionMask perms);
PermissionMask getFilterPermissions() const;
@@ -115,56 +184,47 @@ public:
// +-------------------------------------------------------------------+
// + Execution And Results
// +-------------------------------------------------------------------+
- BOOL check(const LLFolderViewItem* item);
+ bool check(const LLFolderViewModelItem* listener);
bool check(const LLInventoryItem* item);
- bool checkFolder(const LLFolderViewFolder* folder) const;
+ bool checkFolder(const LLFolderViewModelItem* listener) const;
bool checkFolder(const LLUUID& folder_id) const;
- BOOL checkAgainstFilterType(const LLFolderViewItem* item) const;
- bool checkAgainstFilterType(const LLInventoryItem* item) const;
- BOOL checkAgainstPermissions(const LLFolderViewItem* item) const;
- bool checkAgainstPermissions(const LLInventoryItem* item) const;
- BOOL checkAgainstFilterLinks(const LLFolderViewItem* item) const;
- bool checkAgainstClipboard(const LLUUID& object_id) const;
- std::string::size_type getStringMatchOffset() const;
+ bool showAllResults() const;
+ std::string::size_type getStringMatchOffset(LLFolderViewModelItem* item) const;
+ std::string::size_type getFilterStringSize() const;
// +-------------------------------------------------------------------+
// + Presentation
// +-------------------------------------------------------------------+
void setShowFolderState( EFolderShow state);
EFolderShow getShowFolderState() const;
- void setSortOrder(U32 order);
- U32 getSortOrder() const;
-
void setEmptyLookupMessage(const std::string& message);
- const std::string& getEmptyLookupMessage() const;
+ std::string getEmptyLookupMessage() const;
// +-------------------------------------------------------------------+
// + Status
// +-------------------------------------------------------------------+
- BOOL isActive() const;
- BOOL isModified() const;
- BOOL isModifiedAndClear();
- BOOL isSinceLogoff() const;
+ bool isActive() const;
+ bool isModified() const;
+ bool isSinceLogoff() const;
void clearModified();
- const std::string& getName() const;
+ const std::string& getName() const { return mName; }
const std::string& getFilterText();
//RN: this is public to allow system to externally force a global refilter
- void setModified(EFilterBehavior behavior = FILTER_RESTART);
+ void setModified(EFilterModified behavior = FILTER_RESTART);
// +-------------------------------------------------------------------+
- // + Count
+ // + Time
// +-------------------------------------------------------------------+
- void setFilterCount(S32 count);
- S32 getFilterCount() const;
- void decrementFilterCount();
-
+ void resetTime(S32 timeout);
+ bool isTimedOut();
+
// +-------------------------------------------------------------------+
// + Default
// +-------------------------------------------------------------------+
- BOOL isDefault() const;
- BOOL isNotDefault() const;
+ bool isDefault() const;
+ bool isNotDefault() const;
void markDefault();
void resetDefault();
@@ -172,57 +232,44 @@ public:
// + Generation
// +-------------------------------------------------------------------+
S32 getCurrentGeneration() const;
- S32 getMinRequiredGeneration() const;
- S32 getMustPassGeneration() const;
+ S32 getFirstSuccessGeneration() const;
+ S32 getFirstRequiredGeneration() const;
+
// +-------------------------------------------------------------------+
// + Conversion
// +-------------------------------------------------------------------+
- void toLLSD(LLSD& data) const;
- void fromLLSD(LLSD& data);
+ void toParams(Params& params) const;
+ void fromParams(const Params& p);
+
+ LLInventoryFilter& operator =(const LLInventoryFilter& other);
private:
bool areDateLimitsSet();
-
- struct FilterOps
- {
- FilterOps();
- U32 mFilterTypes;
-
- U64 mFilterObjectTypes; // For _OBJECT
- U64 mFilterWearableTypes;
- U64 mFilterCategoryTypes; // For _CATEGORY
- LLUUID mFilterUUID; // for UUID
-
- time_t mMinDate;
- time_t mMaxDate;
- U32 mHoursAgo;
- EFolderShow mShowFolderState;
- PermissionMask mPermissions;
- U64 mFilterLinks;
- };
-
- U32 mOrder;
- U32 mLastLogoff;
+ bool checkAgainstFilterType(const class LLFolderViewModelItemInventory* listener) const;
+ bool checkAgainstFilterType(const LLInventoryItem* item) const;
+ bool checkAgainstPermissions(const class LLFolderViewModelItemInventory* listener) const;
+ bool checkAgainstPermissions(const LLInventoryItem* item) const;
+ bool checkAgainstFilterLinks(const class LLFolderViewModelItemInventory* listener) const;
+ bool checkAgainstClipboard(const LLUUID& object_id) const;
FilterOps mFilterOps;
FilterOps mDefaultFilterOps;
- std::string::size_type mSubStringMatchOffset;
std::string mFilterSubString;
std::string mFilterSubStringOrig;
const std::string mName;
- S32 mFilterGeneration;
- S32 mMustPassGeneration;
- S32 mMinRequiredGeneration;
- S32 mNextFilterGeneration;
-
- S32 mFilterCount;
- EFilterBehavior mFilterBehavior;
+ S32 mCurrentGeneration;
+ // The following makes checking for pass/no pass possible even if the item is not checked against the current generation
+ // Any item that *did not pass* the "required generation" will *not pass* the current one
+ // Any item that *passes* the "success generation" will *pass* the current one
+ S32 mFirstRequiredGeneration;
+ S32 mFirstSuccessGeneration;
- BOOL mModified;
- BOOL mNeedTextRebuild;
+ EFilterModified mFilterModified;
+ LLTimer mFilterTime;
+
std::string mFilterText;
std::string mEmptyLookupMessage;
};
diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp
index ab5b082915..f1a4889f5a 100644..100755
--- a/indra/newview/llinventoryfunctions.cpp
+++ b/indra/newview/llinventoryfunctions.cpp
@@ -45,7 +45,8 @@
// newview includes
#include "llappearancemgr.h"
#include "llappviewer.h"
-//#include "llfirstuse.h"
+#include "llclipboard.h"
+#include "lldonotdisturbnotificationstorage.h"
#include "llfloaterinventory.h"
#include "llfloatersidepanelcontainer.h"
#include "llfocusmgr.h"
@@ -74,8 +75,10 @@
#include "llsidepanelinventory.h"
#include "lltabcontainer.h"
#include "lltooldraganddrop.h"
+#include "lltrans.h"
#include "lluictrlfactory.h"
#include "llviewermessage.h"
+#include "llviewerfoldertype.h"
#include "llviewerobjectlist.h"
#include "llviewerregion.h"
#include "llviewerwindow.h"
@@ -440,7 +443,7 @@ void show_item_original(const LLUUID& item_uuid)
//sidetray inventory panel
LLSidepanelInventory *sidepanel_inventory = LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory");
- bool reset_inventory_filter = !floater_inventory->isInVisibleChain();
+ bool do_reset_inventory_filter = !floater_inventory->isInVisibleChain();
LLInventoryPanel* active_panel = LLInventoryPanel::getActiveInventoryPanel();
if (!active_panel)
@@ -460,37 +463,49 @@ void show_item_original(const LLUUID& item_uuid)
}
active_panel->setSelection(gInventory.getLinkedItemID(item_uuid), TAKE_FOCUS_NO);
- if(reset_inventory_filter)
+ if(do_reset_inventory_filter)
{
- //inventory floater
- bool floater_inventory_visible = false;
+ reset_inventory_filter();
+ }
+}
+
+
+void reset_inventory_filter()
+{
+ //inventory floater
+ bool floater_inventory_visible = false;
- LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("inventory");
- for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin(); iter != inst_list.end(); ++iter)
+ LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("inventory");
+ for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin(); iter != inst_list.end(); ++iter)
+ {
+ LLFloaterInventory* floater_inventory = dynamic_cast<LLFloaterInventory*>(*iter);
+ if (floater_inventory)
{
- LLFloaterInventory* floater_inventory = dynamic_cast<LLFloaterInventory*>(*iter);
- if (floater_inventory)
- {
- LLPanelMainInventory* main_inventory = floater_inventory->getMainInventoryPanel();
+ LLPanelMainInventory* main_inventory = floater_inventory->getMainInventoryPanel();
- main_inventory->onFilterEdit("");
+ main_inventory->onFilterEdit("");
- if(floater_inventory->getVisible())
- {
- floater_inventory_visible = true;
- }
+ if(floater_inventory->getVisible())
+ {
+ floater_inventory_visible = true;
}
}
- if(sidepanel_inventory && !floater_inventory_visible)
+ }
+
+ if(!floater_inventory_visible)
+ {
+ LLSidepanelInventory *sidepanel_inventory = LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory");
+ if (sidepanel_inventory)
{
LLPanelMainInventory* main_inventory = sidepanel_inventory->getMainInventoryPanel();
-
- main_inventory->onFilterEdit("");
+ if (main_inventory)
+ {
+ main_inventory->onFilterEdit("");
+ }
}
}
}
-
void open_outbox()
{
LLFloaterReg::showInstance("outbox");
@@ -947,8 +962,7 @@ void LLSaveFolderState::setApply(BOOL apply)
void LLSaveFolderState::doFolder(LLFolderViewFolder* folder)
{
- LLMemType mt(LLMemType::MTYPE_INVENTORY_DO_FOLDER);
- LLInvFVBridge* bridge = (LLInvFVBridge*)folder->getListener();
+ LLInvFVBridge* bridge = (LLInvFVBridge*)folder->getViewModelItem();
if(!bridge) return;
if(mApply)
@@ -983,7 +997,7 @@ void LLSaveFolderState::doFolder(LLFolderViewFolder* folder)
void LLOpenFilteredFolders::doItem(LLFolderViewItem *item)
{
- if (item->getFiltered())
+ if (item->passedFilter())
{
item->getParentFolder()->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_UP);
}
@@ -991,12 +1005,12 @@ void LLOpenFilteredFolders::doItem(LLFolderViewItem *item)
void LLOpenFilteredFolders::doFolder(LLFolderViewFolder* folder)
{
- if (folder->getFiltered() && folder->getParentFolder())
+ if (folder->LLFolderViewItem::passedFilter() && folder->getParentFolder())
{
folder->getParentFolder()->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_UP);
}
// if this folder didn't pass the filter, and none of its descendants did
- else if (!folder->getFiltered() && !folder->hasFilteredDescendants())
+ else if (!folder->getViewModelItem()->passedFilter() && !folder->getViewModelItem()->descendantsPassedFilter())
{
folder->setOpenArrangeRecursively(FALSE, LLFolderViewFolder::RECURSE_NO);
}
@@ -1004,7 +1018,7 @@ void LLOpenFilteredFolders::doFolder(LLFolderViewFolder* folder)
void LLSelectFirstFilteredItem::doItem(LLFolderViewItem *item)
{
- if (item->getFiltered() && !mItemSelected)
+ if (item->passedFilter() && !mItemSelected)
{
item->getRoot()->setSelection(item, FALSE, FALSE);
if (item->getParentFolder())
@@ -1017,14 +1031,12 @@ void LLSelectFirstFilteredItem::doItem(LLFolderViewItem *item)
void LLSelectFirstFilteredItem::doFolder(LLFolderViewFolder* folder)
{
- if (folder->getFiltered() && !mItemSelected)
+ // Skip if folder or item already found, if not filtered or if no parent (root folder is not selectable)
+ if (!mFolderSelected && !mItemSelected && folder->LLFolderViewItem::passedFilter() && folder->getParentFolder())
{
folder->getRoot()->setSelection(folder, FALSE, FALSE);
- if (folder->getParentFolder())
- {
- folder->getParentFolder()->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_UP);
- }
- mItemSelected = TRUE;
+ folder->getParentFolder()->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_UP);
+ mFolderSelected = TRUE;
}
}
@@ -1044,3 +1056,113 @@ void LLOpenFoldersWithSelection::doFolder(LLFolderViewFolder* folder)
}
}
+void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root, const std::string& action)
+{
+ if ("rename" == action)
+ {
+ root->startRenamingSelectedItem();
+ return;
+ }
+ if ("delete" == action)
+ {
+ LLSD args;
+ args["QUESTION"] = LLTrans::getString(root->getSelectedCount() > 1 ? "DeleteItems" : "DeleteItem");
+ LLNotificationsUtil::add("DeleteItems", args, LLSD(), boost::bind(&LLInventoryAction::onItemsRemovalConfirmation, _1, _2, root));
+ return;
+ }
+ if (("copy" == action) || ("cut" == action))
+ {
+ // Clear the clipboard before we start adding things on it
+ LLClipboard::instance().reset();
+ }
+
+ static const std::string change_folder_string = "change_folder_type_";
+ if (action.length() > change_folder_string.length() &&
+ (action.compare(0,change_folder_string.length(),"change_folder_type_") == 0))
+ {
+ LLFolderType::EType new_folder_type = LLViewerFolderType::lookupTypeFromXUIName(action.substr(change_folder_string.length()));
+ LLFolderViewModelItemInventory* inventory_item = static_cast<LLFolderViewModelItemInventory*>(root->getViewModelItem());
+ LLViewerInventoryCategory *cat = model->getCategory(inventory_item->getUUID());
+ if (!cat) return;
+ cat->changeType(new_folder_type);
+ return;
+ }
+
+
+ std::set<LLFolderViewItem*> selected_items = root->getSelectionList();
+
+ LLMultiPreview* multi_previewp = NULL;
+ LLMultiProperties* multi_propertiesp = NULL;
+
+ if (("task_open" == action || "open" == action) && selected_items.size() > 1)
+ {
+ multi_previewp = new LLMultiPreview();
+ gFloaterView->addChild(multi_previewp);
+
+ LLFloater::setFloaterHost(multi_previewp);
+
+ }
+ else if (("task_properties" == action || "properties" == action) && selected_items.size() > 1)
+ {
+ multi_propertiesp = new LLMultiProperties();
+ gFloaterView->addChild(multi_propertiesp);
+
+ LLFloater::setFloaterHost(multi_propertiesp);
+ }
+
+ std::set<LLFolderViewItem*>::iterator set_iter;
+
+ for (set_iter = selected_items.begin(); set_iter != selected_items.end(); ++set_iter)
+ {
+ LLFolderViewItem* folder_item = *set_iter;
+ if(!folder_item) continue;
+ LLInvFVBridge* bridge = (LLInvFVBridge*)folder_item->getViewModelItem();
+ if(!bridge) continue;
+ bridge->performAction(model, action);
+ }
+
+ LLFloater::setFloaterHost(NULL);
+ if (multi_previewp)
+ {
+ multi_previewp->openFloater(LLSD());
+ }
+ else if (multi_propertiesp)
+ {
+ multi_propertiesp->openFloater(LLSD());
+ }
+}
+
+void LLInventoryAction::removeItemFromDND(LLFolderView* root)
+{
+ if(gAgent.isDoNotDisturb())
+ {
+ //Get selected items
+ LLFolderView::selected_items_t selectedItems = root->getSelectedItems();
+ LLFolderViewModelItemInventory * viewModel = NULL;
+
+ //If user is in DND and deletes item, make sure the notification is not displayed by removing the notification
+ //from DND history and .xml file. Once this is done, upon exit of DND mode the item deleted will not show a notification.
+ for(LLFolderView::selected_items_t::iterator it = selectedItems.begin(); it != selectedItems.end(); ++it)
+ {
+ viewModel = dynamic_cast<LLFolderViewModelItemInventory *>((*it)->getViewModelItem());
+
+ if(viewModel && viewModel->getUUID().notNull())
+ {
+ //Will remove the item offer notification
+ LLDoNotDisturbNotificationStorage::instance().removeNotification(LLDoNotDisturbNotificationStorage::offerName, viewModel->getUUID());
+ }
+ }
+ }
+}
+
+void LLInventoryAction::onItemsRemovalConfirmation( const LLSD& notification, const LLSD& response, LLFolderView* root )
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ if (option == 0)
+ {
+ //Need to remove item from DND before item is removed from root folder view
+ //because once removed from root folder view the item is no longer a selected item
+ removeItemFromDND(root);
+ root->removeSelectedItems();
+ }
+}
diff --git a/indra/newview/llinventoryfunctions.h b/indra/newview/llinventoryfunctions.h
index 5cf9c528b0..f1066a4dc9 100644..100755
--- a/indra/newview/llinventoryfunctions.h
+++ b/indra/newview/llinventoryfunctions.h
@@ -56,6 +56,7 @@ void show_item_profile(const LLUUID& item_uuid);
void show_task_item_profile(const LLUUID& item_uuid, const LLUUID& object_id);
void show_item_original(const LLUUID& item_uuid);
+void reset_inventory_filter();
void rename_category(LLInventoryModel* model, const LLUUID& cat_id, const std::string& new_name);
@@ -418,21 +419,6 @@ public:
class LLFolderViewItem;
class LLFolderViewFolder;
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Class LLFolderViewFunctor
-//
-// Simple abstract base class for applying a functor to folders and
-// items in a folder view hierarchy. This is suboptimal for algorithms
-// that only work folders or only work on items, but I'll worry about
-// that later when it's determined to be too slow.
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-class LLFolderViewFunctor
-{
-public:
- virtual ~LLFolderViewFunctor() {}
- virtual void doFolder(LLFolderViewFolder* folder) = 0;
- virtual void doItem(LLFolderViewItem* item) = 0;
-};
class LLInventoryState
{
@@ -442,49 +428,14 @@ public:
static LLUUID sWearNewClothingTransactionID; // wear all clothing in this transaction
};
-class LLSelectFirstFilteredItem : public LLFolderViewFunctor
+struct LLInventoryAction
{
-public:
- LLSelectFirstFilteredItem() : mItemSelected(FALSE) {}
- virtual ~LLSelectFirstFilteredItem() {}
- virtual void doFolder(LLFolderViewFolder* folder);
- virtual void doItem(LLFolderViewItem* item);
- BOOL wasItemSelected() { return mItemSelected; }
-protected:
- BOOL mItemSelected;
-};
+ static void doToSelected(class LLInventoryModel* model, class LLFolderView* root, const std::string& action);
-class LLOpenFilteredFolders : public LLFolderViewFunctor
-{
-public:
- LLOpenFilteredFolders() {}
- virtual ~LLOpenFilteredFolders() {}
- virtual void doFolder(LLFolderViewFolder* folder);
- virtual void doItem(LLFolderViewItem* item);
+ static void onItemsRemovalConfirmation(const LLSD& notification, const LLSD& response, LLFolderView* root);
+ static void removeItemFromDND(LLFolderView* root);
};
-class LLSaveFolderState : public LLFolderViewFunctor
-{
-public:
- LLSaveFolderState() : mApply(FALSE) {}
- virtual ~LLSaveFolderState() {}
- virtual void doFolder(LLFolderViewFolder* folder);
- virtual void doItem(LLFolderViewItem* item) {}
- void setApply(BOOL apply);
- void clearOpenFolders() { mOpenFolders.clear(); }
-protected:
- std::set<LLUUID> mOpenFolders;
- BOOL mApply;
-};
-
-class LLOpenFoldersWithSelection : public LLFolderViewFunctor
-{
-public:
- LLOpenFoldersWithSelection() {}
- virtual ~LLOpenFoldersWithSelection() {}
- virtual void doFolder(LLFolderViewFolder* folder);
- virtual void doItem(LLFolderViewItem* item);
-};
#endif // LL_LLINVENTORYFUNCTIONS_H
diff --git a/indra/newview/llinventoryicon.cpp b/indra/newview/llinventoryicon.cpp
index 34734d57c5..02a2475cfd 100644..100755
--- a/indra/newview/llinventoryicon.cpp
+++ b/indra/newview/llinventoryicon.cpp
@@ -25,6 +25,8 @@
*/
#include "llviewerprecompiledheaders.h"
+
+#include "linden_common.h"
#include "llinventoryicon.h"
#include "lldictionary.h"
@@ -41,7 +43,7 @@ struct IconEntry : public LLDictionaryEntry
};
class LLIconDictionary : public LLSingleton<LLIconDictionary>,
- public LLDictionary<LLInventoryIcon::EIconName, IconEntry>
+ public LLDictionary<LLInventoryType::EIconName, IconEntry>
{
public:
LLIconDictionary();
@@ -49,48 +51,48 @@ public:
LLIconDictionary::LLIconDictionary()
{
- addEntry(LLInventoryIcon::ICONNAME_TEXTURE, new IconEntry("Inv_Texture"));
- addEntry(LLInventoryIcon::ICONNAME_SOUND, new IconEntry("Inv_Sound"));
- addEntry(LLInventoryIcon::ICONNAME_CALLINGCARD_ONLINE, new IconEntry("Inv_CallingCard"));
- addEntry(LLInventoryIcon::ICONNAME_CALLINGCARD_OFFLINE, new IconEntry("Inv_CallingCard"));
- addEntry(LLInventoryIcon::ICONNAME_LANDMARK, new IconEntry("Inv_Landmark"));
- addEntry(LLInventoryIcon::ICONNAME_LANDMARK_VISITED, new IconEntry("Inv_Landmark"));
- addEntry(LLInventoryIcon::ICONNAME_SCRIPT, new IconEntry("Inv_Script"));
- addEntry(LLInventoryIcon::ICONNAME_CLOTHING, new IconEntry("Inv_Clothing"));
- addEntry(LLInventoryIcon::ICONNAME_OBJECT, new IconEntry("Inv_Object"));
- addEntry(LLInventoryIcon::ICONNAME_OBJECT_MULTI, new IconEntry("Inv_Object_Multi"));
- addEntry(LLInventoryIcon::ICONNAME_NOTECARD, new IconEntry("Inv_Notecard"));
- addEntry(LLInventoryIcon::ICONNAME_BODYPART, new IconEntry("Inv_Skin"));
- addEntry(LLInventoryIcon::ICONNAME_SNAPSHOT, new IconEntry("Inv_Snapshot"));
-
- addEntry(LLInventoryIcon::ICONNAME_BODYPART_SHAPE, new IconEntry("Inv_BodyShape"));
- addEntry(LLInventoryIcon::ICONNAME_BODYPART_SKIN, new IconEntry("Inv_Skin"));
- addEntry(LLInventoryIcon::ICONNAME_BODYPART_HAIR, new IconEntry("Inv_Hair"));
- addEntry(LLInventoryIcon::ICONNAME_BODYPART_EYES, new IconEntry("Inv_Eye"));
-
- addEntry(LLInventoryIcon::ICONNAME_CLOTHING_SHIRT, new IconEntry("Inv_Shirt"));
- addEntry(LLInventoryIcon::ICONNAME_CLOTHING_PANTS, new IconEntry("Inv_Pants"));
- addEntry(LLInventoryIcon::ICONNAME_CLOTHING_SHOES, new IconEntry("Inv_Shoe"));
- addEntry(LLInventoryIcon::ICONNAME_CLOTHING_SOCKS, new IconEntry("Inv_Socks"));
- addEntry(LLInventoryIcon::ICONNAME_CLOTHING_JACKET, new IconEntry("Inv_Jacket"));
- addEntry(LLInventoryIcon::ICONNAME_CLOTHING_GLOVES, new IconEntry("Inv_Gloves"));
- addEntry(LLInventoryIcon::ICONNAME_CLOTHING_UNDERSHIRT, new IconEntry("Inv_Undershirt"));
- addEntry(LLInventoryIcon::ICONNAME_CLOTHING_UNDERPANTS, new IconEntry("Inv_Underpants"));
- addEntry(LLInventoryIcon::ICONNAME_CLOTHING_SKIRT, new IconEntry("Inv_Skirt"));
- addEntry(LLInventoryIcon::ICONNAME_CLOTHING_ALPHA, new IconEntry("Inv_Alpha"));
- addEntry(LLInventoryIcon::ICONNAME_CLOTHING_TATTOO, new IconEntry("Inv_Tattoo"));
- addEntry(LLInventoryIcon::ICONNAME_ANIMATION, new IconEntry("Inv_Animation"));
- addEntry(LLInventoryIcon::ICONNAME_GESTURE, new IconEntry("Inv_Gesture"));
-
- addEntry(LLInventoryIcon::ICONNAME_CLOTHING_PHYSICS, new IconEntry("Inv_Physics"));
-
- addEntry(LLInventoryIcon::ICONNAME_LINKITEM, new IconEntry("Inv_LinkItem"));
- addEntry(LLInventoryIcon::ICONNAME_LINKFOLDER, new IconEntry("Inv_LinkFolder"));
- addEntry(LLInventoryIcon::ICONNAME_MESH, new IconEntry("Inv_Mesh"));
-
- addEntry(LLInventoryIcon::ICONNAME_INVALID, new IconEntry("Inv_Invalid"));
-
- addEntry(LLInventoryIcon::ICONNAME_NONE, new IconEntry("NONE"));
+ addEntry(LLInventoryType::ICONNAME_TEXTURE, new IconEntry("Inv_Texture"));
+ addEntry(LLInventoryType::ICONNAME_SOUND, new IconEntry("Inv_Sound"));
+ addEntry(LLInventoryType::ICONNAME_CALLINGCARD_ONLINE, new IconEntry("Inv_CallingCard"));
+ addEntry(LLInventoryType::ICONNAME_CALLINGCARD_OFFLINE, new IconEntry("Inv_CallingCard"));
+ addEntry(LLInventoryType::ICONNAME_LANDMARK, new IconEntry("Inv_Landmark"));
+ addEntry(LLInventoryType::ICONNAME_LANDMARK_VISITED, new IconEntry("Inv_Landmark"));
+ addEntry(LLInventoryType::ICONNAME_SCRIPT, new IconEntry("Inv_Script"));
+ addEntry(LLInventoryType::ICONNAME_CLOTHING, new IconEntry("Inv_Clothing"));
+ addEntry(LLInventoryType::ICONNAME_OBJECT, new IconEntry("Inv_Object"));
+ addEntry(LLInventoryType::ICONNAME_OBJECT_MULTI, new IconEntry("Inv_Object_Multi"));
+ addEntry(LLInventoryType::ICONNAME_NOTECARD, new IconEntry("Inv_Notecard"));
+ addEntry(LLInventoryType::ICONNAME_BODYPART, new IconEntry("Inv_Skin"));
+ addEntry(LLInventoryType::ICONNAME_SNAPSHOT, new IconEntry("Inv_Snapshot"));
+
+ addEntry(LLInventoryType::ICONNAME_BODYPART_SHAPE, new IconEntry("Inv_BodyShape"));
+ addEntry(LLInventoryType::ICONNAME_BODYPART_SKIN, new IconEntry("Inv_Skin"));
+ addEntry(LLInventoryType::ICONNAME_BODYPART_HAIR, new IconEntry("Inv_Hair"));
+ addEntry(LLInventoryType::ICONNAME_BODYPART_EYES, new IconEntry("Inv_Eye"));
+
+ addEntry(LLInventoryType::ICONNAME_CLOTHING_SHIRT, new IconEntry("Inv_Shirt"));
+ addEntry(LLInventoryType::ICONNAME_CLOTHING_PANTS, new IconEntry("Inv_Pants"));
+ addEntry(LLInventoryType::ICONNAME_CLOTHING_SHOES, new IconEntry("Inv_Shoe"));
+ addEntry(LLInventoryType::ICONNAME_CLOTHING_SOCKS, new IconEntry("Inv_Socks"));
+ addEntry(LLInventoryType::ICONNAME_CLOTHING_JACKET, new IconEntry("Inv_Jacket"));
+ addEntry(LLInventoryType::ICONNAME_CLOTHING_GLOVES, new IconEntry("Inv_Gloves"));
+ addEntry(LLInventoryType::ICONNAME_CLOTHING_UNDERSHIRT, new IconEntry("Inv_Undershirt"));
+ addEntry(LLInventoryType::ICONNAME_CLOTHING_UNDERPANTS, new IconEntry("Inv_Underpants"));
+ addEntry(LLInventoryType::ICONNAME_CLOTHING_SKIRT, new IconEntry("Inv_Skirt"));
+ addEntry(LLInventoryType::ICONNAME_CLOTHING_ALPHA, new IconEntry("Inv_Alpha"));
+ addEntry(LLInventoryType::ICONNAME_CLOTHING_TATTOO, new IconEntry("Inv_Tattoo"));
+ addEntry(LLInventoryType::ICONNAME_ANIMATION, new IconEntry("Inv_Animation"));
+ addEntry(LLInventoryType::ICONNAME_GESTURE, new IconEntry("Inv_Gesture"));
+
+ addEntry(LLInventoryType::ICONNAME_CLOTHING_PHYSICS, new IconEntry("Inv_Physics"));
+
+ addEntry(LLInventoryType::ICONNAME_LINKITEM, new IconEntry("Inv_LinkItem"));
+ addEntry(LLInventoryType::ICONNAME_LINKFOLDER, new IconEntry("Inv_LinkFolder"));
+ addEntry(LLInventoryType::ICONNAME_MESH, new IconEntry("Inv_Mesh"));
+
+ addEntry(LLInventoryType::ICONNAME_INVALID, new IconEntry("Inv_Invalid"));
+
+ addEntry(LLInventoryType::ICONNAME_NONE, new IconEntry("NONE"));
}
LLUIImagePtr LLInventoryIcon::getIcon(LLAssetType::EType asset_type,
@@ -102,7 +104,7 @@ LLUIImagePtr LLInventoryIcon::getIcon(LLAssetType::EType asset_type,
return LLUI::getUIImage(icon_name);
}
-LLUIImagePtr LLInventoryIcon::getIcon(EIconName idx)
+LLUIImagePtr LLInventoryIcon::getIcon(LLInventoryType::EIconName idx)
{
return LLUI::getUIImage(getIconName(idx));
}
@@ -112,56 +114,56 @@ const std::string& LLInventoryIcon::getIconName(LLAssetType::EType asset_type,
U32 misc_flag,
BOOL item_is_multi)
{
- EIconName idx = ICONNAME_OBJECT;
+ LLInventoryType::EIconName idx = LLInventoryType::ICONNAME_OBJECT;
if (item_is_multi)
{
- idx = ICONNAME_OBJECT_MULTI;
+ idx = LLInventoryType::ICONNAME_OBJECT_MULTI;
return getIconName(idx);
}
switch(asset_type)
{
case LLAssetType::AT_TEXTURE:
- idx = (inventory_type == LLInventoryType::IT_SNAPSHOT) ? ICONNAME_SNAPSHOT : ICONNAME_TEXTURE;
+ idx = (inventory_type == LLInventoryType::IT_SNAPSHOT) ? LLInventoryType::ICONNAME_SNAPSHOT : LLInventoryType::ICONNAME_TEXTURE;
break;
case LLAssetType::AT_SOUND:
- idx = ICONNAME_SOUND;
+ idx = LLInventoryType::ICONNAME_SOUND;
break;
case LLAssetType::AT_CALLINGCARD:
- idx = (misc_flag != 0) ? ICONNAME_CALLINGCARD_ONLINE : ICONNAME_CALLINGCARD_OFFLINE;
+ idx = (misc_flag != 0) ? LLInventoryType::ICONNAME_CALLINGCARD_ONLINE : LLInventoryType::ICONNAME_CALLINGCARD_OFFLINE;
break;
case LLAssetType::AT_LANDMARK:
- idx = (misc_flag != 0) ? ICONNAME_LANDMARK_VISITED : ICONNAME_LANDMARK;
+ idx = (misc_flag != 0) ? LLInventoryType::ICONNAME_LANDMARK_VISITED : LLInventoryType::ICONNAME_LANDMARK;
break;
case LLAssetType::AT_SCRIPT:
case LLAssetType::AT_LSL_TEXT:
case LLAssetType::AT_LSL_BYTECODE:
- idx = ICONNAME_SCRIPT;
+ idx = LLInventoryType::ICONNAME_SCRIPT;
break;
case LLAssetType::AT_CLOTHING:
case LLAssetType::AT_BODYPART:
idx = assignWearableIcon(misc_flag);
break;
case LLAssetType::AT_NOTECARD:
- idx = ICONNAME_NOTECARD;
+ idx = LLInventoryType::ICONNAME_NOTECARD;
break;
case LLAssetType::AT_ANIMATION:
- idx = ICONNAME_ANIMATION;
+ idx = LLInventoryType::ICONNAME_ANIMATION;
break;
case LLAssetType::AT_GESTURE:
- idx = ICONNAME_GESTURE;
+ idx = LLInventoryType::ICONNAME_GESTURE;
break;
case LLAssetType::AT_LINK:
- idx = ICONNAME_LINKITEM;
+ idx = LLInventoryType::ICONNAME_LINKITEM;
break;
case LLAssetType::AT_LINK_FOLDER:
- idx = ICONNAME_LINKFOLDER;
+ idx = LLInventoryType::ICONNAME_LINKFOLDER;
break;
case LLAssetType::AT_OBJECT:
- idx = ICONNAME_OBJECT;
+ idx = LLInventoryType::ICONNAME_OBJECT;
break;
case LLAssetType::AT_MESH:
- idx = ICONNAME_MESH;
+ idx = LLInventoryType::ICONNAME_MESH;
default:
break;
}
@@ -170,13 +172,13 @@ const std::string& LLInventoryIcon::getIconName(LLAssetType::EType asset_type,
}
-const std::string& LLInventoryIcon::getIconName(EIconName idx)
+const std::string& LLInventoryIcon::getIconName(LLInventoryType::EIconName idx)
{
const IconEntry *entry = LLIconDictionary::instance().lookup(idx);
return entry->mName;
}
-LLInventoryIcon::EIconName LLInventoryIcon::assignWearableIcon(U32 misc_flag)
+LLInventoryType::EIconName LLInventoryIcon::assignWearableIcon(U32 misc_flag)
{
const LLWearableType::EType wearable_type = LLWearableType::EType(LLInventoryItemFlags::II_FLAGS_WEARABLES_MASK & misc_flag);
return LLWearableType::getIconName(wearable_type);
diff --git a/indra/newview/llinventoryicon.h b/indra/newview/llinventoryicon.h
index c7e2998a20..2197c53bb8 100644..100755
--- a/indra/newview/llinventoryicon.h
+++ b/indra/newview/llinventoryicon.h
@@ -1,5 +1,5 @@
/**
- * @file llinventoryfunctions.h
+ * @file llinventoryicon.h
* @brief Miscellaneous inventory-related functions and classes
* class definition
*
@@ -35,66 +35,20 @@
class LLInventoryIcon
{
public:
- enum EIconName
- {
- ICONNAME_TEXTURE,
- ICONNAME_SOUND,
- ICONNAME_CALLINGCARD_ONLINE,
- ICONNAME_CALLINGCARD_OFFLINE,
- ICONNAME_LANDMARK,
- ICONNAME_LANDMARK_VISITED,
- ICONNAME_SCRIPT,
- ICONNAME_CLOTHING,
- ICONNAME_OBJECT,
- ICONNAME_OBJECT_MULTI,
- ICONNAME_NOTECARD,
- ICONNAME_BODYPART,
- ICONNAME_SNAPSHOT,
-
- ICONNAME_BODYPART_SHAPE,
- ICONNAME_BODYPART_SKIN,
- ICONNAME_BODYPART_HAIR,
- ICONNAME_BODYPART_EYES,
- ICONNAME_CLOTHING_SHIRT,
- ICONNAME_CLOTHING_PANTS,
- ICONNAME_CLOTHING_SHOES,
- ICONNAME_CLOTHING_SOCKS,
- ICONNAME_CLOTHING_JACKET,
- ICONNAME_CLOTHING_GLOVES,
- ICONNAME_CLOTHING_UNDERSHIRT,
- ICONNAME_CLOTHING_UNDERPANTS,
- ICONNAME_CLOTHING_SKIRT,
- ICONNAME_CLOTHING_ALPHA,
- ICONNAME_CLOTHING_TATTOO,
-
- ICONNAME_ANIMATION,
- ICONNAME_GESTURE,
-
- ICONNAME_CLOTHING_PHYSICS,
-
- ICONNAME_LINKITEM,
- ICONNAME_LINKFOLDER,
- ICONNAME_MESH,
-
- ICONNAME_INVALID,
- ICONNAME_COUNT,
- ICONNAME_NONE = -1
- };
-
static const std::string& getIconName(LLAssetType::EType asset_type,
LLInventoryType::EType inventory_type = LLInventoryType::IT_NONE,
U32 misc_flag = 0, // different meanings depending on item type
BOOL item_is_multi = FALSE);
- static const std::string& getIconName(EIconName idx);
+ static const std::string& getIconName(LLInventoryType::EIconName idx);
static LLUIImagePtr getIcon(LLAssetType::EType asset_type,
LLInventoryType::EType inventory_type = LLInventoryType::IT_NONE,
U32 misc_flag = 0, // different meanings depending on item type
BOOL item_is_multi = FALSE);
- static LLUIImagePtr getIcon(EIconName idx);
+ static LLUIImagePtr getIcon(LLInventoryType::EIconName idx);
protected:
- static EIconName assignWearableIcon(U32 misc_flag);
+ static LLInventoryType::EIconName assignWearableIcon(U32 misc_flag);
};
#endif // LL_LLINVENTORYICON_H
diff --git a/indra/newview/llinventoryitemslist.cpp b/indra/newview/llinventoryitemslist.cpp
index 348d7ebcec..348d7ebcec 100644..100755
--- a/indra/newview/llinventoryitemslist.cpp
+++ b/indra/newview/llinventoryitemslist.cpp
diff --git a/indra/newview/llinventoryitemslist.h b/indra/newview/llinventoryitemslist.h
index b183a2052d..b183a2052d 100644..100755
--- a/indra/newview/llinventoryitemslist.h
+++ b/indra/newview/llinventoryitemslist.h
diff --git a/indra/newview/llinventorylistitem.cpp b/indra/newview/llinventorylistitem.cpp
index 3e0849a795..0601796436 100644..100755
--- a/indra/newview/llinventorylistitem.cpp
+++ b/indra/newview/llinventorylistitem.cpp
@@ -37,6 +37,7 @@
#include "lltextutil.h"
// newview
+#include "llinventoryicon.h"
#include "llinventorymodel.h"
#include "llviewerinventory.h"
@@ -230,7 +231,7 @@ const std::string& LLPanelInventoryListItemBase::getDescription() const
{
return LLStringUtil::null;
}
- return inv_item->getDescription();
+ return inv_item->getActualDescription();
}
time_t LLPanelInventoryListItemBase::getCreationDate() const
diff --git a/indra/newview/llinventorylistitem.h b/indra/newview/llinventorylistitem.h
index b1ef6c74ee..b1ef6c74ee 100644..100755
--- a/indra/newview/llinventorylistitem.h
+++ b/indra/newview/llinventorylistitem.h
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index bca2a28dfd..935fe2b4d0 100644..100755
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -373,13 +373,12 @@ void LLInventoryModel::unlockDirectDescendentArrays(const LLUUID& cat_id)
// specifies 'type' as what it defaults to containing. The category is
// not necessarily only for that type. *NOTE: This will create a new
// inventory category on the fly if one does not exist.
-const LLUUID LLInventoryModel::findCategoryUUIDForType(LLFolderType::EType preferred_type,
- bool create_folder,
- bool find_in_library)
+const LLUUID LLInventoryModel::findCategoryUUIDForType(LLFolderType::EType preferred_type, bool create_folder/*,
+ bool find_in_library*/)
{
LLUUID rv = LLUUID::null;
- const LLUUID &root_id = (find_in_library) ? gInventory.getLibraryRootFolderID() : gInventory.getRootFolderID();
+ const LLUUID &root_id = /*(find_in_library) ? gInventory.getLibraryRootFolderID() :*/ gInventory.getRootFolderID();
if(LLFolderType::FT_ROOT_INVENTORY == preferred_type)
{
rv = root_id;
@@ -402,7 +401,44 @@ const LLUUID LLInventoryModel::findCategoryUUIDForType(LLFolderType::EType prefe
}
}
- if(rv.isNull() && isInventoryUsable() && (create_folder && !find_in_library))
+ if(rv.isNull() && isInventoryUsable() && (create_folder && true/*!find_in_library*/))
+ {
+ if(root_id.notNull())
+ {
+ return createNewCategory(root_id, preferred_type, LLStringUtil::null);
+ }
+ }
+ return rv;
+}
+
+const LLUUID LLInventoryModel::findLibraryCategoryUUIDForType(LLFolderType::EType preferred_type, bool create_folder)
+{
+ LLUUID rv = LLUUID::null;
+
+ const LLUUID &root_id = gInventory.getLibraryRootFolderID();
+ if(LLFolderType::FT_ROOT_INVENTORY == preferred_type)
+ {
+ rv = root_id;
+ }
+ else if (root_id.notNull())
+ {
+ cat_array_t* cats = NULL;
+ cats = get_ptr_in_map(mParentChildCategoryTree, root_id);
+ if(cats)
+ {
+ S32 count = cats->count();
+ for(S32 i = 0; i < count; ++i)
+ {
+ if(cats->get(i)->getPreferredType() == preferred_type)
+ {
+ rv = cats->get(i)->getUUID();
+ break;
+ }
+ }
+ }
+ }
+
+ if(rv.isNull() && isInventoryUsable() && (create_folder && true/*!find_in_library*/))
{
if(root_id.notNull())
{
@@ -424,9 +460,10 @@ public:
{
}
- virtual void error(U32 status, const std::string& reason)
+ virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content)
{
- LL_WARNS("InvAPI") << "CreateInventoryCategory failed. status = " << status << ", reasion = \"" << reason << "\"" << LL_ENDL;
+ LL_WARNS("InvAPI") << "CreateInventoryCategory failed [status:"
+ << status << "]: " << content << LL_ENDL;
}
virtual void result(const LLSD& content)
@@ -822,6 +859,11 @@ U32 LLInventoryModel::updateItem(const LLViewerInventoryItem* item)
{
parent_id = findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND);
new_item->setParent(parent_id);
+ LLInventoryModel::update_list_t update;
+ LLInventoryModel::LLCategoryUpdate new_folder(parent_id, 1);
+ update.push_back(new_folder);
+ accountForUpdate(update);
+
}
item_array_t* item_array = get_ptr_in_map(mParentChildItemTree, parent_id);
if(item_array)
@@ -945,6 +987,7 @@ void LLInventoryModel::updateCategory(const LLViewerInventoryCategory* cat)
cat_array->put(old_cat);
}
mask |= LLInventoryObserver::STRUCTURE;
+ mask |= LLInventoryObserver::INTERNAL;
}
if(old_cat->getName() != cat->getName())
{
@@ -1240,14 +1283,33 @@ void LLInventoryModel::purgeDescendentsOf(const LLUUID& id)
items,
INCLUDE_TRASH);
S32 count = items.count();
+
+ item_map_t::iterator item_map_end = mItemMap.end();
+ cat_map_t::iterator cat_map_end = mCategoryMap.end();
+ LLUUID uu_id;
+
for(S32 i = 0; i < count; ++i)
{
- deleteObject(items.get(i)->getUUID());
+ uu_id = items.get(i)->getUUID();
+
+ // This check prevents the deletion of a previously deleted item.
+ // This is necessary because deletion is not done in a hierarchical
+ // order. The current item may have been already deleted as a child
+ // of its deleted parent.
+ if (mItemMap.find(uu_id) != item_map_end)
+ {
+ deleteObject(uu_id);
+ }
}
+
count = categories.count();
for(S32 i = 0; i < count; ++i)
{
- deleteObject(categories.get(i)->getUUID());
+ uu_id = categories.get(i)->getUUID();
+ if (mCategoryMap.find(uu_id) != cat_map_end)
+ {
+ deleteObject(uu_id);
+ }
}
}
}
@@ -1349,7 +1411,6 @@ void LLInventoryModel::fetchInventoryResponder::result(const LLSD& content)
item_array_t items;
update_map_t update;
S32 count = content["items"].size();
- bool all_one_folder = true;
LLUUID folder_id;
// Does this loop ever execute more than once?
for(S32 i = 0; i < count; ++i)
@@ -1382,10 +1443,6 @@ void LLInventoryModel::fetchInventoryResponder::result(const LLSD& content)
{
folder_id = titem->getParentUUID();
}
- else
- {
- all_one_folder = false;
- }
}
U32 changes = 0x0;
@@ -1399,10 +1456,9 @@ void LLInventoryModel::fetchInventoryResponder::result(const LLSD& content)
}
//If we get back an error (not found, etc...), handle it here
-void LLInventoryModel::fetchInventoryResponder::error(U32 status, const std::string& reason)
+void LLInventoryModel::fetchInventoryResponder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)
{
- llinfos << "fetchInventory::error "
- << status << ": " << reason << llendl;
+ llwarns << "fetchInventory error [status:" << status << "]: " << content << llendl;
gInventory.notifyObservers();
}
@@ -1759,6 +1815,7 @@ bool LLInventoryModel::loadSkeleton(
update_map_t child_counts;
cat_array_t categories;
item_array_t items;
+ item_array_t possible_broken_links;
cat_set_t invalid_categories; // Used to mark categories that weren't successfully loaded.
std::string owner_id_str;
owner_id.toString(owner_id_str);
@@ -1807,7 +1864,7 @@ bool LLInventoryModel::loadSkeleton(
LLViewerInventoryCategory* tcat = *cit;
// we can safely ignore anything loaded from file, but
- // not sent down in the skeleton.
+ // not sent down in the skeleton. Must have been removed from inventory.
if(cit == not_cached)
{
continue;
@@ -1845,6 +1902,8 @@ bool LLInventoryModel::loadSkeleton(
// Add all the items loaded which are parented to a
// category with a correctly cached parent
S32 bad_link_count = 0;
+ S32 good_link_count = 0;
+ S32 recovered_link_count = 0;
cat_map_t::iterator unparented = mCategoryMap.end();
for(item_array_t::const_iterator item_iter = items.begin();
item_iter != items.end();
@@ -1861,26 +1920,56 @@ bool LLInventoryModel::loadSkeleton(
// This can happen if the linked object's baseobj is removed from the cache but the linked object is still in the cache.
if (item->getIsBrokenLink())
{
- bad_link_count++;
+ //bad_link_count++;
lldebugs << "Attempted to add cached link item without baseobj present ( name: "
<< item->getName() << " itemID: " << item->getUUID()
<< " assetID: " << item->getAssetUUID()
<< " ). Ignoring and invalidating " << cat->getName() << " . " << llendl;
- invalid_categories.insert(cit->second);
+ possible_broken_links.push_back(item);
continue;
}
+ else if (item->getIsLinkType())
+ {
+ good_link_count++;
+ }
addItem(item);
cached_item_count += 1;
++child_counts[cat->getUUID()];
}
}
}
- if (bad_link_count > 0)
+ if (possible_broken_links.size() > 0)
{
- llinfos << "Attempted to add " << bad_link_count
- << " cached link items without baseobj present. "
- << "The corresponding categories were invalidated." << llendl;
+ for(item_array_t::const_iterator item_iter = possible_broken_links.begin();
+ item_iter != possible_broken_links.end();
+ ++item_iter)
+ {
+ LLViewerInventoryItem *item = (*item_iter).get();
+ const cat_map_t::iterator cit = mCategoryMap.find(item->getParentUUID());
+ const LLViewerInventoryCategory* cat = cit->second.get();
+ if (item->getIsBrokenLink())
+ {
+ bad_link_count++;
+ invalid_categories.insert(cit->second);
+ //llinfos << "link still broken: " << item->getName() << " in folder " << cat->getName() << llendl;
+ }
+ else
+ {
+ // was marked as broken because of loading order, its actually fine to load
+ addItem(item);
+ cached_item_count += 1;
+ ++child_counts[cat->getUUID()];
+ recovered_link_count++;
+ }
+ }
+
+ llinfos << "Attempted to add " << bad_link_count
+ << " cached link items without baseobj present. "
+ << good_link_count << " link items were successfully added. "
+ << recovered_link_count << " links added in recovery. "
+ << "The corresponding categories were invalidated." << llendl;
}
+
}
else
{
@@ -1902,8 +1991,9 @@ bool LLInventoryModel::loadSkeleton(
{
LLViewerInventoryCategory* cat = (*invalid_cat_it).get();
cat->setVersion(NO_VERSION);
- llinfos << "Invalidating category name: " << cat->getName() << " UUID: " << cat->getUUID() << " due to invalid descendents cache" << llendl;
+ LL_DEBUGS("Inventory") << "Invalidating category name: " << cat->getName() << " UUID: " << cat->getUUID() << " due to invalid descendents cache" << llendl;
}
+ LL_INFOS("Inventory") << "Invalidated " << invalid_categories.size() << " categories due to invalid descendents cache" << llendl;
// At this point, we need to set the known descendents for each
// category which successfully cached so that we do not
@@ -2440,7 +2530,6 @@ bool LLInventoryModel::messageUpdateCore(LLMessageSystem* msg, bool account)
item_array_t items;
update_map_t update;
S32 count = msg->getNumberOfBlocksFast(_PREHASH_InventoryData);
- bool all_one_folder = true;
LLUUID folder_id;
// Does this loop ever execute more than once?
for(S32 i = 0; i < count; ++i)
@@ -2472,10 +2561,6 @@ bool LLInventoryModel::messageUpdateCore(LLMessageSystem* msg, bool account)
{
folder_id = titem->getParentUUID();
}
- else
- {
- all_one_folder = false;
- }
}
if(account)
{
@@ -3202,6 +3287,7 @@ void LLInventoryModel::updateItemsOrder(LLInventoryModel::item_array_t& items, c
}
//* @param[in] items vector of items in order to be saved.
+/*
void LLInventoryModel::saveItemsOrder(const LLInventoryModel::item_array_t& items)
{
int sortField = 0;
@@ -3223,7 +3309,7 @@ void LLInventoryModel::saveItemsOrder(const LLInventoryModel::item_array_t& item
notifyObservers();
}
-
+*/
// See also LLInventorySort where landmarks in the Favorites folder are sorted.
class LLViewerInventoryItemSort
{
@@ -3239,14 +3325,15 @@ public:
*
* @param[in, out] items - array of items, not sorted.
*/
-static void rearrange_item_order_by_sort_field(LLInventoryModel::item_array_t& items)
-{
- static LLViewerInventoryItemSort sort_functor;
- std::sort(items.begin(), items.end(), sort_functor);
-}
+//static void rearrange_item_order_by_sort_field(LLInventoryModel::item_array_t& items)
+//{
+// static LLViewerInventoryItemSort sort_functor;
+// std::sort(items.begin(), items.end(), sort_functor);
+//}
// * @param source_item_id - LLUUID of the source item to be moved into new position
// * @param target_item_id - LLUUID of the target item before which source item should be placed.
+/*
void LLInventoryModel::rearrangeFavoriteLandmarks(const LLUUID& source_item_id, const LLUUID& target_item_id)
{
LLInventoryModel::cat_array_t cats;
@@ -3263,7 +3350,7 @@ void LLInventoryModel::rearrangeFavoriteLandmarks(const LLUUID& source_item_id,
saveItemsOrder(items);
}
-
+*/
//----------------------------------------------------------------------------
// *NOTE: DEBUG functionality
diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h
index 8382e875b4..8aac879a93 100644..100755
--- a/indra/newview/llinventorymodel.h
+++ b/indra/newview/llinventorymodel.h
@@ -84,7 +84,7 @@ public:
public:
fetchInventoryResponder(const LLSD& request_sd) : mRequestSD(request_sd) {};
void result(const LLSD& content);
- void error(U32 status, const std::string& reason);
+ void errorWithContent(U32 status, const std::string& reason, const LLSD& content);
protected:
LLSD mRequestSD;
};
@@ -234,8 +234,10 @@ public:
// on the fly if one does not exist. *NOTE: if find_in_library is true it
// will search in the user's library folder instead of "My Inventory"
const LLUUID findCategoryUUIDForType(LLFolderType::EType preferred_type,
- bool create_folder = true,
- bool find_in_library = false);
+ bool create_folder = true);
+ // will search in the user's library folder instead of "My Inventory"
+ const LLUUID findLibraryCategoryUUIDForType(LLFolderType::EType preferred_type,
+ bool create_folder = true);
// Get whatever special folder this object is a child of, if any.
const LLViewerInventoryCategory *getFirstNondefaultParent(const LLUUID& obj_id) const;
@@ -362,14 +364,11 @@ public:
// Returns end() of the vector if not found.
static LLInventoryModel::item_array_t::iterator findItemIterByUUID(LLInventoryModel::item_array_t& items, const LLUUID& id);
- // Saves current order of the passed items using inventory item sort field.
- // Resets 'items' sort fields and saves them on server.
- // Is used to save order for Favorites folder.
- void saveItemsOrder(const LLInventoryModel::item_array_t& items);
// Rearranges Landmarks inside Favorites folder.
// Moves source landmark before target one.
void rearrangeFavoriteLandmarks(const LLUUID& source_item_id, const LLUUID& target_item_id);
+ //void saveItemsOrder(const LLInventoryModel::item_array_t& items);
//--------------------------------------------------------------------
// Creation
diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp
index f4d0110b0f..d88e0c3192 100644..100755
--- a/indra/newview/llinventorymodelbackgroundfetch.cpp
+++ b/indra/newview/llinventorymodelbackgroundfetch.cpp
@@ -183,7 +183,7 @@ void LLInventoryModelBackgroundFetch::backgroundFetchCB(void *)
void LLInventoryModelBackgroundFetch::backgroundFetch()
{
- if (mBackgroundFetchActive && gAgent.getRegion())
+ if (mBackgroundFetchActive && gAgent.getRegion() && gAgent.getRegion()->capabilitiesReceived())
{
// If we'll be using the capability, we'll be sending batches and the background thing isn't as important.
if (gSavedSettings.getBOOL("UseHTTPInventory"))
@@ -366,7 +366,7 @@ class LLInventoryModelFetchItemResponder : public LLInventoryModel::fetchInvento
public:
LLInventoryModelFetchItemResponder(const LLSD& request_sd) : LLInventoryModel::fetchInventoryResponder(request_sd) {};
void result(const LLSD& content);
- void error(U32 status, const std::string& reason);
+ void errorWithContent(U32 status, const std::string& reason, const LLSD& content);
};
void LLInventoryModelFetchItemResponder::result( const LLSD& content )
@@ -375,9 +375,9 @@ void LLInventoryModelFetchItemResponder::result( const LLSD& content )
LLInventoryModelBackgroundFetch::instance().incrFetchCount(-1);
}
-void LLInventoryModelFetchItemResponder::error( U32 status, const std::string& reason )
+void LLInventoryModelFetchItemResponder::errorWithContent( U32 status, const std::string& reason, const LLSD& content )
{
- LLInventoryModel::fetchInventoryResponder::error(status, reason);
+ LLInventoryModel::fetchInventoryResponder::errorWithContent(status, reason, content);
LLInventoryModelBackgroundFetch::instance().incrFetchCount(-1);
}
@@ -391,7 +391,7 @@ public:
{};
//LLInventoryModelFetchDescendentsResponder() {};
void result(const LLSD& content);
- void error(U32 status, const std::string& reason);
+ void errorWithContent(U32 status, const std::string& reason, const LLSD& content);
protected:
BOOL getIsRecursive(const LLUUID& cat_id) const;
private:
@@ -529,12 +529,12 @@ void LLInventoryModelFetchDescendentsResponder::result(const LLSD& content)
}
// If we get back an error (not found, etc...), handle it here.
-void LLInventoryModelFetchDescendentsResponder::error(U32 status, const std::string& reason)
+void LLInventoryModelFetchDescendentsResponder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)
{
LLInventoryModelBackgroundFetch *fetcher = LLInventoryModelBackgroundFetch::getInstance();
- llinfos << "LLInventoryModelFetchDescendentsResponder::error "
- << status << ": " << reason << llendl;
+ llinfos << "LLInventoryModelFetchDescendentsResponder::error [status:"
+ << status << "]: " << content << llendl;
fetcher->incrFetchCount(-1);
@@ -564,7 +564,6 @@ BOOL LLInventoryModelFetchDescendentsResponder::getIsRecursive(const LLUUID& cat
{
return (std::find(mRecursiveCatUUIDs.begin(),mRecursiveCatUUIDs.end(), cat_id) != mRecursiveCatUUIDs.end());
}
-
// Bundle up a bunch of requests to send all at once.
// static
void LLInventoryModelBackgroundFetch::bulkFetch()
@@ -688,6 +687,8 @@ void LLInventoryModelBackgroundFetch::bulkFetch()
if (folder_count)
{
std::string url = region->getCapability("FetchInventoryDescendents2");
+ if ( !url.empty() )
+ {
mFetchCount++;
if (folder_request_body["folders"].size())
{
@@ -702,6 +703,7 @@ void LLInventoryModelBackgroundFetch::bulkFetch()
LLHTTPClient::post(url_lib, folder_request_body_lib, fetcher, 300.0);
}
}
+ }
if (item_count)
{
std::string url;
diff --git a/indra/newview/llinventorymodelbackgroundfetch.h b/indra/newview/llinventorymodelbackgroundfetch.h
index 9dfedddd6d..9dfedddd6d 100644..100755
--- a/indra/newview/llinventorymodelbackgroundfetch.h
+++ b/indra/newview/llinventorymodelbackgroundfetch.h
diff --git a/indra/newview/llinventoryobserver.cpp b/indra/newview/llinventoryobserver.cpp
index 9db175ec2e..9db175ec2e 100644..100755
--- a/indra/newview/llinventoryobserver.cpp
+++ b/indra/newview/llinventoryobserver.cpp
diff --git a/indra/newview/llinventoryobserver.h b/indra/newview/llinventoryobserver.h
index aa1eae84d7..aa1eae84d7 100644..100755
--- a/indra/newview/llinventoryobserver.h
+++ b/indra/newview/llinventoryobserver.h
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index 71dd963f28..e5b9e11d48 100644..100755
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -38,12 +38,15 @@
#include "llfloaterreg.h"
#include "llfloatersidepanelcontainer.h"
#include "llfolderview.h"
-#include "llimfloater.h"
+#include "llfolderviewitem.h"
+#include "llfloaterimcontainer.h"
#include "llimview.h"
#include "llinventorybridge.h"
#include "llinventoryfunctions.h"
#include "llinventorymodelbackgroundfetch.h"
+#include "llpreview.h"
#include "llsidepanelinventory.h"
+#include "lltrans.h"
#include "llviewerattachmenu.h"
#include "llviewerfoldertype.h"
#include "llvoavatarself.h"
@@ -53,8 +56,16 @@ static LLDefaultChildRegistry::Register<LLInventoryPanel> r("inventory_panel");
const std::string LLInventoryPanel::DEFAULT_SORT_ORDER = std::string("InventorySortOrder");
const std::string LLInventoryPanel::RECENTITEMS_SORT_ORDER = std::string("RecentItemsSortOrder");
const std::string LLInventoryPanel::INHERIT_SORT_ORDER = std::string("");
-static const LLInventoryFVBridgeBuilder INVENTORY_BRIDGE_BUILDER;
+static const LLInventoryFolderViewModelBuilder INVENTORY_BRIDGE_BUILDER;
+// statics
+bool LLInventoryPanel::sColorSetInitialized = false;
+LLUIColor LLInventoryPanel::sDefaultColor;
+LLUIColor LLInventoryPanel::sDefaultHighlightColor;
+LLUIColor LLInventoryPanel::sLibraryColor;
+LLUIColor LLInventoryPanel::sLinkColor;
+
+const LLColor4U DEFAULT_WHITE(255, 255, 255);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class LLInventoryPanelObserver
@@ -134,78 +145,86 @@ LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p) :
mAllowMultiSelect(p.allow_multi_select),
mShowItemLinkOverlays(p.show_item_link_overlays),
mShowEmptyMessage(p.show_empty_message),
- mShowLoadStatus(p.show_load_status),
mViewsInitialized(false),
mInvFVBridgeBuilder(NULL)
{
mInvFVBridgeBuilder = &INVENTORY_BRIDGE_BUILDER;
- // contex menu callbacks
+ if (!sColorSetInitialized)
+ {
+ sDefaultColor = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE);
+ sDefaultHighlightColor = LLUIColorTable::instance().getColor("MenuItemHighlightFgColor", DEFAULT_WHITE);
+ sLibraryColor = LLUIColorTable::instance().getColor("InventoryItemLibraryColor", DEFAULT_WHITE);
+ sLinkColor = LLUIColorTable::instance().getColor("InventoryItemLinkColor", DEFAULT_WHITE);
+ sColorSetInitialized = true;
+ }
+
+ // context menu callbacks
mCommitCallbackRegistrar.add("Inventory.DoToSelected", boost::bind(&LLInventoryPanel::doToSelected, this, _2));
mCommitCallbackRegistrar.add("Inventory.EmptyTrash", boost::bind(&LLInventoryModel::emptyFolderType, &gInventory, "ConfirmEmptyTrash", LLFolderType::FT_TRASH));
mCommitCallbackRegistrar.add("Inventory.EmptyLostAndFound", boost::bind(&LLInventoryModel::emptyFolderType, &gInventory, "ConfirmEmptyLostAndFound", LLFolderType::FT_LOST_AND_FOUND));
mCommitCallbackRegistrar.add("Inventory.DoCreate", boost::bind(&LLInventoryPanel::doCreate, this, _2));
mCommitCallbackRegistrar.add("Inventory.AttachObject", boost::bind(&LLInventoryPanel::attachObject, this, _2));
mCommitCallbackRegistrar.add("Inventory.BeginIMSession", boost::bind(&LLInventoryPanel::beginIMSession, this));
- mCommitCallbackRegistrar.add("Inventory.Share", boost::bind(&LLAvatarActions::shareWithAvatars));
+ mCommitCallbackRegistrar.add("Inventory.Share", boost::bind(&LLAvatarActions::shareWithAvatars, this));
}
-void LLInventoryPanel::buildFolderView(const LLInventoryPanel::Params& params)
+LLFolderView * LLInventoryPanel::createFolderRoot(LLUUID root_id )
{
- // Determine the root folder in case specified, and
- // build the views starting with that folder.
-
- std::string start_folder_name(params.start_folder());
-
- const LLFolderType::EType preferred_type = LLViewerFolderType::lookupTypeFromNewCategoryName(start_folder_name);
-
- LLUUID root_id;
-
- if ("LIBRARY" == params.start_folder())
- {
- root_id = gInventory.getLibraryRootFolderID();
- }
- else
- {
- root_id = (preferred_type != LLFolderType::FT_NONE)
- ? gInventory.findCategoryUUIDForType(preferred_type, false, false)
- : LLUUID::null;
- }
-
- if ((root_id == LLUUID::null) && !start_folder_name.empty())
- {
- llwarns << "No category found that matches start_folder: " << start_folder_name << llendl;
- root_id = LLUUID::generateNewID();
- }
-
- LLInvFVBridge* new_listener = mInvFVBridgeBuilder->createBridge(LLAssetType::AT_CATEGORY,
+ LLFolderView::Params p(mParams.folder_view);
+ p.name = getName();
+ p.title = getLabel();
+ p.rect = LLRect(0, 0, getRect().getWidth(), 0);
+ p.parent_panel = this;
+ p.tool_tip = p.name;
+ p.listener = mInvFVBridgeBuilder->createBridge( LLAssetType::AT_CATEGORY,
LLAssetType::AT_CATEGORY,
LLInventoryType::IT_CATEGORY,
this,
+ &mInventoryViewModel,
NULL,
root_id);
-
- mFolderRoot = createFolderView(new_listener, params.use_label_suffix());
+ p.view_model = &mInventoryViewModel;
+ p.use_label_suffix = mParams.use_label_suffix;
+ p.allow_multiselect = mAllowMultiSelect;
+ p.show_empty_message = mShowEmptyMessage;
+ p.show_item_link_overlays = mShowItemLinkOverlays;
+ p.root = NULL;
+ p.options_menu = "menu_inventory.xml";
+
+ return LLUICtrlFactory::create<LLFolderView>(p);
}
void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)
{
- LLMemType mt(LLMemType::MTYPE_INVENTORY_POST_BUILD);
+ // save off copy of params
+ mParams = params;
+ // Clear up the root view
+ // Note: This needs to be done *before* we build the new folder view
+ LLUUID root_id = getRootFolderID();
+ if (mFolderRoot)
+ {
+ removeItemID(root_id);
+ mFolderRoot->destroyView();
+ mFolderRoot = NULL;
+ }
mCommitCallbackRegistrar.pushScope(); // registered as a widget; need to push callback scope ourselves
+ {
+ // Determine the root folder in case specified, and
+ // build the views starting with that folder.
+ mFolderRoot = createFolderRoot(root_id);
- buildFolderView(params);
-
+ addItemID(root_id, mFolderRoot);
+ }
mCommitCallbackRegistrar.popScope();
-
mFolderRoot->setCallbackRegistrar(&mCommitCallbackRegistrar);
// Scroller
- {
LLRect scroller_view_rect = getRect();
scroller_view_rect.translate(-scroller_view_rect.mLeft, -scroller_view_rect.mBottom);
- LLScrollContainer::Params scroller_params(params.scroll());
+ LLScrollContainer::Params scroller_params(mParams.scroll());
scroller_params.rect(scroller_view_rect);
mScroller = LLUICtrlFactory::create<LLFolderViewScrollContainer>(scroller_params);
addChild(mScroller);
@@ -213,7 +232,6 @@ void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)
mFolderRoot->setScrollContainer(mScroller);
mFolderRoot->setFollowsAll();
mFolderRoot->addChild(mFolderRoot->mStatusTextBox);
- }
// Set up the callbacks from the inventory we're viewing, and then build everything.
mInventoryObserver = new LLInventoryPanelObserver(this);
@@ -228,6 +246,7 @@ void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)
{
initializeViews();
}
+
gIdleCallbacks.addFunction(onIdle, (void*)this);
if (mSortOrderSetting != INHERIT_SORT_ORDER)
@@ -240,32 +259,31 @@ void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)
}
// hide inbox
- getFilter()->setFilterCategoryTypes(getFilter()->getFilterCategoryTypes() & ~(1ULL << LLFolderType::FT_INBOX));
- getFilter()->setFilterCategoryTypes(getFilter()->getFilterCategoryTypes() & ~(1ULL << LLFolderType::FT_OUTBOX));
+ getFilter().setFilterCategoryTypes(getFilter().getFilterCategoryTypes() & ~(1ULL << LLFolderType::FT_INBOX));
+ getFilter().setFilterCategoryTypes(getFilter().getFilterCategoryTypes() & ~(1ULL << LLFolderType::FT_OUTBOX));
// set the filter for the empty folder if the debug setting is on
if (gSavedSettings.getBOOL("DebugHideEmptySystemFolders"))
{
- getFilter()->setFilterEmptySystemFolders();
+ getFilter().setFilterEmptySystemFolders();
}
// keep track of the clipboard state so that we avoid filtering too much
mClipboardState = LLClipboard::instance().getGeneration();
// Initialize base class params.
- LLPanel::initFromParams(params);
+ LLPanel::initFromParams(mParams);
}
LLInventoryPanel::~LLInventoryPanel()
{
- if (mFolderRoot)
- {
- U32 sort_order = mFolderRoot->getSortOrder();
+ gIdleCallbacks.deleteFunction(idle, this);
+
+ U32 sort_order = getFolderViewModel()->getSorter().getSortOrder();
if (mSortOrderSetting != INHERIT_SORT_ORDER)
{
gSavedSettings.setU32(mSortOrderSetting, sort_order);
}
- }
gIdleCallbacks.deleteFunction(onIdle, this);
@@ -281,82 +299,68 @@ LLInventoryPanel::~LLInventoryPanel()
void LLInventoryPanel::draw()
{
// Select the desired item (in case it wasn't loaded when the selection was requested)
- mFolderRoot->updateSelection();
-
- // Nudge the filter if the clipboard state changed
- if (mClipboardState != LLClipboard::instance().getGeneration())
- {
- mClipboardState = LLClipboard::instance().getGeneration();
- getFilter()->setModified(LLClipboard::instance().isCutMode() ? LLInventoryFilter::FILTER_MORE_RESTRICTIVE : LLInventoryFilter::FILTER_LESS_RESTRICTIVE);
- }
+ updateSelection();
LLPanel::draw();
}
-LLInventoryFilter* LLInventoryPanel::getFilter()
+const LLInventoryFilter& LLInventoryPanel::getFilter() const
{
- if (mFolderRoot)
- {
- return mFolderRoot->getFilter();
- }
- return NULL;
+ return getFolderViewModel()->getFilter();
}
-const LLInventoryFilter* LLInventoryPanel::getFilter() const
+LLInventoryFilter& LLInventoryPanel::getFilter()
{
- if (mFolderRoot)
- {
- return mFolderRoot->getFilter();
- }
- return NULL;
+ return getFolderViewModel()->getFilter();
}
void LLInventoryPanel::setFilterTypes(U64 types, LLInventoryFilter::EFilterType filter_type)
{
if (filter_type == LLInventoryFilter::FILTERTYPE_OBJECT)
- getFilter()->setFilterObjectTypes(types);
+ getFilter().setFilterObjectTypes(types);
if (filter_type == LLInventoryFilter::FILTERTYPE_CATEGORY)
- getFilter()->setFilterCategoryTypes(types);
+ getFilter().setFilterCategoryTypes(types);
}
U32 LLInventoryPanel::getFilterObjectTypes() const
{
- return mFolderRoot->getFilterObjectTypes();
+ return getFilter().getFilterObjectTypes();
}
U32 LLInventoryPanel::getFilterPermMask() const
{
- return mFolderRoot->getFilterPermissions();
+ return getFilter().getFilterPermissions();
}
void LLInventoryPanel::setFilterPermMask(PermissionMask filter_perm_mask)
{
- getFilter()->setFilterPermissions(filter_perm_mask);
+ getFilter().setFilterPermissions(filter_perm_mask);
}
void LLInventoryPanel::setFilterWearableTypes(U64 types)
{
- getFilter()->setFilterWearableTypes(types);
+ getFilter().setFilterWearableTypes(types);
}
void LLInventoryPanel::setFilterSubString(const std::string& string)
{
- getFilter()->setFilterSubString(string);
+ getFilter().setFilterSubString(string);
}
const std::string LLInventoryPanel::getFilterSubString()
{
- return mFolderRoot->getFilterSubString();
+ return getFilter().getFilterSubString();
}
void LLInventoryPanel::setSortOrder(U32 order)
{
- getFilter()->setSortOrder(order);
- if (getFilter()->isModified())
+ LLInventorySort sorter(order);
+ if (order != getFolderViewModel()->getSorter().getSortOrder())
{
- mFolderRoot->setSortOrder(order);
+ getFolderViewModel()->setSorter(sorter);
+ mFolderRoot->arrangeAll();
// try to keep selection onscreen, even if it wasn't to start with
mFolderRoot->scrollToShowSelection();
}
@@ -364,46 +368,40 @@ void LLInventoryPanel::setSortOrder(U32 order)
U32 LLInventoryPanel::getSortOrder() const
{
- return mFolderRoot->getSortOrder();
-}
-
-void LLInventoryPanel::requestSort()
-{
- mFolderRoot->requestSort();
+ return getFolderViewModel()->getSorter().getSortOrder();
}
void LLInventoryPanel::setSinceLogoff(BOOL sl)
{
- getFilter()->setDateRangeLastLogoff(sl);
+ getFilter().setDateRangeLastLogoff(sl);
}
void LLInventoryPanel::setHoursAgo(U32 hours)
{
- getFilter()->setHoursAgo(hours);
+ getFilter().setHoursAgo(hours);
}
void LLInventoryPanel::setFilterLinks(U64 filter_links)
{
- getFilter()->setFilterLinks(filter_links);
+ getFilter().setFilterLinks(filter_links);
}
void LLInventoryPanel::setShowFolderState(LLInventoryFilter::EFolderShow show)
{
- getFilter()->setShowFolderState(show);
+ getFilter().setShowFolderState(show);
}
LLInventoryFilter::EFolderShow LLInventoryPanel::getShowFolderState()
{
- return getFilter()->getShowFolderState();
+ return getFilter().getShowFolderState();
}
+// Called when something changed in the global model (new item, item coming through the wire, rename, move, etc...) (CHUI-849)
void LLInventoryPanel::modelChanged(U32 mask)
{
static LLFastTimer::DeclareTimer FTM_REFRESH("Inventory Refresh");
LLFastTimer t2(FTM_REFRESH);
- bool handled = false;
-
if (!mViewsInitialized) return;
const LLInventoryModel* model = getModel();
@@ -418,22 +416,30 @@ void LLInventoryPanel::modelChanged(U32 mask)
{
const LLUUID& item_id = (*items_iter);
const LLInventoryObject* model_item = model->getObject(item_id);
- LLFolderViewItem* view_item = mFolderRoot->getItemByID(item_id);
+ LLFolderViewItem* view_item = getItemByID(item_id);
+ LLFolderViewModelItemInventory* viewmodel_item =
+ static_cast<LLFolderViewModelItemInventory*>(view_item ? view_item->getViewModelItem() : NULL);
// LLFolderViewFolder is derived from LLFolderViewItem so dynamic_cast from item
// to folder is the fast way to get a folder without searching through folders tree.
- LLFolderViewFolder* view_folder = dynamic_cast<LLFolderViewFolder*>(view_item);
+ LLFolderViewFolder* view_folder = NULL;
+
+ // Check requires as this item might have already been deleted
+ // as a child of its deleted parent.
+ if (model_item && view_item)
+ {
+ view_folder = dynamic_cast<LLFolderViewFolder*>(view_item);
+ }
//////////////////////////////
// LABEL Operation
// Empty out the display name for relabel.
if (mask & LLInventoryObserver::LABEL)
{
- handled = true;
if (view_item)
{
// Request refresh on this item (also flags for filtering)
- LLInvFVBridge* bridge = (LLInvFVBridge*)view_item->getListener();
+ LLInvFVBridge* bridge = (LLInvFVBridge*)view_item->getViewModelItem();
if(bridge)
{ // Clear the display name first, so it gets properly re-built during refresh()
bridge->clearDisplayName();
@@ -448,12 +454,15 @@ void LLInventoryPanel::modelChanged(U32 mask)
// Destroy and regenerate the UI.
if (mask & LLInventoryObserver::REBUILD)
{
- handled = true;
- if (model_item && view_item)
+ if (model_item && view_item && viewmodel_item)
{
+ const LLUUID& idp = viewmodel_item->getUUID();
view_item->destroyView();
+ removeItemID(idp);
}
view_item = buildNewViews(item_id);
+ viewmodel_item =
+ static_cast<LLFolderViewModelItemInventory*>(view_item ? view_item->getViewModelItem() : NULL);
view_folder = dynamic_cast<LLFolderViewFolder *>(view_item);
}
@@ -475,7 +484,7 @@ void LLInventoryPanel::modelChanged(U32 mask)
{
if (view_folder)
{
- view_folder->requestSort();
+ view_folder->getViewModelItem()->requestSort();
}
}
@@ -488,8 +497,6 @@ void LLInventoryPanel::modelChanged(U32 mask)
LLInventoryObserver::ADD |
LLInventoryObserver::REMOVE))
{
- handled = true;
-
//////////////////////////////
// ADD Operation
// Item exists in memory but a UI element hasn't been created for it.
@@ -510,20 +517,24 @@ void LLInventoryPanel::modelChanged(U32 mask)
else if (model_item && view_item)
{
// Don't process the item if it is the root
- if (view_item->getRoot() != view_item)
+ if (view_item->getParentFolder())
{
- LLFolderViewFolder* new_parent = (LLFolderViewFolder*)mFolderRoot->getItemByID(model_item->getParentUUID());
+ LLFolderViewFolder* new_parent = (LLFolderViewFolder*)getItemByID(model_item->getParentUUID());
// Item has been moved.
if (view_item->getParentFolder() != new_parent)
{
if (new_parent != NULL)
{
// Item is to be moved and we found its new parent in the panel's directory, so move the item's UI.
- view_item->getParentFolder()->extractItem(view_item);
- view_item->addToFolder(new_parent, mFolderRoot);
+ view_item->addToFolder(new_parent);
+ addItemID(viewmodel_item->getUUID(), view_item);
}
else
{
+ // Remove the item ID before destroying the view because the view-model-item gets
+ // destroyed when the view is destroyed
+ removeItemID(viewmodel_item->getUUID());
+
// Item is to be moved outside the panel's directory (e.g. moved to trash for a panel that
// doesn't include trash). Just remove the item's UI.
view_item->destroyView();
@@ -535,9 +546,10 @@ void LLInventoryPanel::modelChanged(U32 mask)
//////////////////////////////
// REMOVE Operation
// This item has been removed from memory, but its associated UI element still exists.
- else if (!model_item && view_item)
+ else if (!model_item && view_item && viewmodel_item)
{
// Remove the item's UI.
+ removeItemID(viewmodel_item->getUUID());
view_item->destroyView();
}
}
@@ -549,6 +561,43 @@ LLFolderView* LLInventoryPanel::getRootFolder()
return mFolderRoot;
}
+LLUUID LLInventoryPanel::getRootFolderID()
+{
+ if (mFolderRoot && mFolderRoot->getViewModelItem())
+ {
+ return static_cast<LLFolderViewModelItemInventory*>(mFolderRoot->getViewModelItem())->getUUID();
+
+ }
+ else
+ {
+ LLUUID root_id;
+ if (mParams.start_folder.id.isChosen())
+ {
+ root_id = mParams.start_folder.id;
+ }
+ else
+ {
+ const LLFolderType::EType preferred_type = mParams.start_folder.type.isChosen()
+ ? mParams.start_folder.type
+ : LLViewerFolderType::lookupTypeFromNewCategoryName(mParams.start_folder.name);
+
+ if ("LIBRARY" == mParams.start_folder.name())
+ {
+ root_id = gInventory.getLibraryRootFolderID();
+ }
+ else if (preferred_type != LLFolderType::FT_NONE)
+ {
+ root_id = gInventory.findCategoryUUIDForType(preferred_type, false);
+ if (root_id.isNull())
+ {
+ llwarns << "Could not find folder of type " << preferred_type << llendl;
+ root_id.generateNewID();
+ }
+ }
+ }
+ return root_id;
+ }
+}
// static
void LLInventoryPanel::onIdle(void *userdata)
@@ -568,16 +617,73 @@ void LLInventoryPanel::onIdle(void *userdata)
}
}
-const LLUUID& LLInventoryPanel::getRootFolderID() const
+struct DirtyFilterFunctor : public LLFolderViewFunctor
{
- return mFolderRoot->getListener()->getUUID();
+ /*virtual*/ void doFolder(LLFolderViewFolder* folder)
+ {
+ folder->getViewModelItem()->dirtyFilter();
+ }
+ /*virtual*/ void doItem(LLFolderViewItem* item)
+ {
+ item->getViewModelItem()->dirtyFilter();
+ }
+};
+
+void LLInventoryPanel::idle(void* user_data)
+{
+ LLInventoryPanel* panel = (LLInventoryPanel*)user_data;
+ // Nudge the filter if the clipboard state changed
+ if (panel->mClipboardState != LLClipboard::instance().getGeneration())
+ {
+ panel->mClipboardState = LLClipboard::instance().getGeneration();
+ const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH);
+ LLFolderViewFolder* trash_folder = panel->getFolderByID(trash_id);
+ if (trash_folder)
+ {
+ DirtyFilterFunctor dirtyFilterFunctor;
+ trash_folder->applyFunctorToChildren(dirtyFilterFunctor);
+ }
+
+ }
+
+ panel->mFolderRoot->update();
+ // while dragging, update selection rendering to reflect single/multi drag status
+ if (LLToolDragAndDrop::getInstance()->hasMouseCapture())
+ {
+ EAcceptance last_accept = LLToolDragAndDrop::getInstance()->getLastAccept();
+ if (last_accept == ACCEPT_YES_SINGLE || last_accept == ACCEPT_YES_COPY_SINGLE)
+ {
+ panel->mFolderRoot->setShowSingleSelection(TRUE);
+ }
+ else
+ {
+ panel->mFolderRoot->setShowSingleSelection(FALSE);
+ }
+}
+ else
+ {
+ panel->mFolderRoot->setShowSingleSelection(FALSE);
+ }
}
+
void LLInventoryPanel::initializeViews()
{
if (!gInventory.isInventoryUsable()) return;
- rebuildViewsFor(getRootFolderID());
+ LLUUID root_id = getRootFolderID();
+ if (root_id.notNull())
+ {
+ buildNewViews(getRootFolderID());
+ }
+ else
+ {
+ // Default case: always add "My Inventory" first, "Library" second
+ buildNewViews(gInventory.getRootFolderID()); // My Inventory
+ buildNewViews(gInventory.getLibraryRootFolderID()); // Library
+ }
+
+ gIdleCallbacks.addFunction(idle, this);
mViewsInitialized = true;
@@ -587,14 +693,14 @@ void LLInventoryPanel::initializeViews()
if (gAgent.isFirstLogin())
{
// Auto open the user's library
- LLFolderViewFolder* lib_folder = mFolderRoot->getFolderByID(gInventory.getLibraryRootFolderID());
+ LLFolderViewFolder* lib_folder = getFolderByID(gInventory.getLibraryRootFolderID());
if (lib_folder)
{
lib_folder->setOpen(TRUE);
}
// Auto close the user's my inventory folder
- LLFolderViewFolder* my_inv_folder = mFolderRoot->getFolderByID(gInventory.getRootFolderID());
+ LLFolderViewFolder* my_inv_folder = getFolderByID(gInventory.getRootFolderID());
if (my_inv_folder)
{
my_inv_folder->setOpenArrangeRecursively(FALSE, LLFolderViewFolder::RECURSE_DOWN);
@@ -602,79 +708,35 @@ void LLInventoryPanel::initializeViews()
}
}
-LLFolderViewItem* LLInventoryPanel::rebuildViewsFor(const LLUUID& id)
-{
- // Destroy the old view for this ID so we can rebuild it.
- LLFolderViewItem* old_view = mFolderRoot->getItemByID(id);
- if (old_view)
- {
- old_view->destroyView();
- }
-
- return buildNewViews(id);
-}
-
-LLFolderView * LLInventoryPanel::createFolderView(LLInvFVBridge * bridge, bool useLabelSuffix)
-{
- LLRect folder_rect(0,
- 0,
- getRect().getWidth(),
- 0);
-
- LLFolderView::Params p;
-
- p.name = getName();
- p.title = getLabel();
- p.rect = folder_rect;
- p.parent_panel = this;
- p.tool_tip = p.name;
- p.listener = bridge;
- p.use_label_suffix = useLabelSuffix;
- p.allow_multiselect = mAllowMultiSelect;
- p.show_empty_message = mShowEmptyMessage;
- p.show_load_status = mShowLoadStatus;
-
- return LLUICtrlFactory::create<LLFolderView>(p);
-}
LLFolderViewFolder * LLInventoryPanel::createFolderViewFolder(LLInvFVBridge * bridge)
{
- LLFolderViewFolder::Params params;
+ LLFolderViewFolder::Params params(mParams.folder);
params.name = bridge->getDisplayName();
- params.icon = bridge->getIcon();
- params.icon_open = bridge->getOpenIcon();
-
- if (mShowItemLinkOverlays) // if false, then links show up just like normal items
- {
- params.icon_overlay = LLUI::getUIImage("Inv_Link");
- }
-
params.root = mFolderRoot;
params.listener = bridge;
params.tool_tip = params.name;
+ params.font_color = (bridge->isLibraryItem() ? sLibraryColor : (bridge->isLink() ? sLinkColor : sDefaultColor));
+ params.font_highlight_color = (bridge->isLibraryItem() ? sLibraryColor : (bridge->isLink() ? sLinkColor : sDefaultHighlightColor));
+
return LLUICtrlFactory::create<LLFolderViewFolder>(params);
}
LLFolderViewItem * LLInventoryPanel::createFolderViewItem(LLInvFVBridge * bridge)
{
- LLFolderViewItem::Params params;
+ LLFolderViewItem::Params params(mParams.item);
params.name = bridge->getDisplayName();
- params.icon = bridge->getIcon();
- params.icon_open = bridge->getOpenIcon();
-
- if (mShowItemLinkOverlays) // if false, then links show up just like normal items
- {
- params.icon_overlay = LLUI::getUIImage("Inv_Link");
- }
-
params.creation_date = bridge->getCreationDate();
params.root = mFolderRoot;
params.listener = bridge;
params.rect = LLRect (0, 0, 0, 0);
params.tool_tip = params.name;
+
+ params.font_color = (bridge->isLibraryItem() ? sLibraryColor : (bridge->isLink() ? sLinkColor : sDefaultColor));
+ params.font_highlight_color = (bridge->isLibraryItem() ? sLibraryColor : (bridge->isLink() ? sLinkColor : sDefaultHighlightColor));
return LLUICtrlFactory::create<LLFolderViewItem>(params);
}
@@ -682,20 +744,15 @@ LLFolderViewItem * LLInventoryPanel::createFolderViewItem(LLInvFVBridge * bridge
LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id)
{
LLInventoryObject const* objectp = gInventory.getObject(id);
- LLUUID root_id = mFolderRoot->getListener()->getUUID();
- LLFolderViewFolder* parent_folder = NULL;
- LLFolderViewItem* itemp = NULL;
- if (id == root_id)
- {
- parent_folder = mFolderRoot;
- }
- else if (objectp)
- {
+ if (!objectp) return NULL;
+
+ LLFolderViewItem* folder_view_item = getItemByID(id);
+
const LLUUID &parent_id = objectp->getParentUUID();
- parent_folder = (LLFolderViewFolder*)mFolderRoot->getItemByID(parent_id);
+ LLFolderViewFolder* parent_folder = (LLFolderViewFolder*)getItemByID(parent_id);
- if (parent_folder)
+ if (!folder_view_item && parent_folder)
{
if (objectp->getType() <= LLAssetType::AT_NONE ||
objectp->getType() >= LLAssetType::AT_COUNT)
@@ -713,16 +770,12 @@ LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id)
objectp->getType(),
LLInventoryType::IT_CATEGORY,
this,
+ &mInventoryViewModel,
mFolderRoot,
objectp->getUUID());
if (new_listener)
{
- LLFolderViewFolder* folderp = createFolderViewFolder(new_listener);
- if (folderp)
- {
- folderp->setItemSortOrder(mFolderRoot->getSortOrder());
- }
- itemp = folderp;
+ folder_view_item = createFolderViewFolder(new_listener);
}
}
else
@@ -733,28 +786,28 @@ LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id)
item->getActualType(),
item->getInventoryType(),
this,
+ &mInventoryViewModel,
mFolderRoot,
item->getUUID(),
item->getFlags());
if (new_listener)
{
- itemp = createFolderViewItem(new_listener);
+ folder_view_item = createFolderViewItem(new_listener);
}
}
- if (itemp)
+ if (folder_view_item)
{
- itemp->addToFolder(parent_folder, mFolderRoot);
- }
+ llassert(parent_folder != NULL);
+ folder_view_item->addToFolder(parent_folder);
+ addItemID(id, folder_view_item);
}
}
// If this is a folder, add the children of the folder and recursively add any
// child folders.
- if (id.isNull()
- || (objectp
- && objectp->getType() == LLAssetType::AT_CATEGORY))
+ if (folder_view_item && objectp->getType() == LLAssetType::AT_CATEGORY)
{
LLViewerInventoryCategory::cat_array_t* categories;
LLViewerInventoryItem::item_array_t* items;
@@ -771,7 +824,7 @@ LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id)
}
}
- if(items && parent_folder)
+ if(items)
{
for (LLViewerInventoryItem::item_array_t::const_iterator item_iter = items->begin();
item_iter != items->end();
@@ -784,7 +837,7 @@ LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id)
mInventory->unlockDirectDescendentArrays(id);
}
- return itemp;
+ return folder_view_item;
}
// bit of a hack to make sure the inventory is open.
@@ -795,8 +848,8 @@ void LLInventoryPanel::openStartFolderOrMyInventory()
{
LLFolderViewFolder *fchild = dynamic_cast<LLFolderViewFolder*>(child);
if (fchild
- && fchild->getListener()
- && fchild->getListener()->getUUID() == gInventory.getRootFolderID())
+ && fchild->getViewModelItem()
+ && fchild->getViewModelItem()->getName() == "My Inventory")
{
fchild->setOpen(TRUE);
break;
@@ -813,7 +866,7 @@ void LLInventoryPanel::openSelected()
{
LLFolderViewItem* folder_item = mFolderRoot->getCurSelectedItem();
if(!folder_item) return;
- LLInvFVBridge* bridge = (LLInvFVBridge*)folder_item->getListener();
+ LLInvFVBridge* bridge = (LLInvFVBridge*)folder_item->getViewModelItem();
if(!bridge) return;
bridge->openItem();
}
@@ -917,7 +970,7 @@ void LLInventoryPanel::setSelection(const LLUUID& obj_id, BOOL take_keyboard_foc
{
return;
}
- mFolderRoot->setSelectionByID(obj_id, take_keyboard_focus);
+ setSelectionByID(obj_id, take_keyboard_focus);
}
void LLInventoryPanel::setSelectCallback(const boost::function<void (const std::deque<LLFolderViewItem*>& items, BOOL user_action)>& cb)
@@ -930,7 +983,7 @@ void LLInventoryPanel::setSelectCallback(const boost::function<void (const std::
void LLInventoryPanel::clearSelection()
{
- mFolderRoot->clearSelection();
+ mSelectThisID.setNull();
}
void LLInventoryPanel::onSelectionChange(const std::deque<LLFolderViewItem*>& items, BOOL user_action)
@@ -939,7 +992,7 @@ void LLInventoryPanel::onSelectionChange(const std::deque<LLFolderViewItem*>& it
mCompletionObserver->reset();
for (std::deque<LLFolderViewItem*>::const_iterator it = items.begin(); it != items.end(); ++it)
{
- LLUUID id = (*it)->getListener()->getUUID();
+ LLUUID id = static_cast<LLFolderViewModelItemInventory*>((*it)->getViewModelItem())->getUUID();
LLViewerInventoryItem* inv_item = mInventory->getItem(id);
if (inv_item && !inv_item->isFinished())
@@ -959,40 +1012,34 @@ void LLInventoryPanel::onSelectionChange(const std::deque<LLFolderViewItem*>& it
}
}
-void LLInventoryPanel::doToSelected(const LLSD& userdata)
-{
- mFolderRoot->doToSelected(&gInventory, userdata);
-}
-
void LLInventoryPanel::doCreate(const LLSD& userdata)
{
- menu_create_inventory_item(mFolderRoot, LLFolderBridge::sSelf.get(), userdata);
+ reset_inventory_filter();
+ menu_create_inventory_item(this, LLFolderBridge::sSelf.get(), userdata);
}
bool LLInventoryPanel::beginIMSession()
{
- std::set<LLUUID> selected_items = mFolderRoot->getSelectionList();
+ std::set<LLFolderViewItem*> selected_items = mFolderRoot->getSelectionList();
std::string name;
- static int session_num = 1;
LLDynamicArray<LLUUID> members;
EInstantMessage type = IM_SESSION_CONFERENCE_START;
- std::set<LLUUID>::const_iterator iter;
+ std::set<LLFolderViewItem*>::const_iterator iter;
for (iter = selected_items.begin(); iter != selected_items.end(); iter++)
{
- LLUUID item = *iter;
- LLFolderViewItem* folder_item = mFolderRoot->getItemByID(item);
+ LLFolderViewItem* folder_item = (*iter);
if(folder_item)
{
- LLFolderViewEventListener* fve_listener = folder_item->getListener();
+ LLFolderViewModelItemInventory* fve_listener = static_cast<LLFolderViewModelItemInventory*>(folder_item->getViewModelItem());
if (fve_listener && (fve_listener->getInventoryType() == LLInventoryType::IT_CATEGORY))
{
- LLFolderBridge* bridge = (LLFolderBridge*)folder_item->getListener();
+ LLFolderBridge* bridge = (LLFolderBridge*)folder_item->getViewModelItem();
if(!bridge) return true;
LLViewerInventoryCategory* cat = bridge->getCategory();
if(!cat) return true;
@@ -1026,9 +1073,7 @@ bool LLInventoryPanel::beginIMSession()
}
else
{
- LLFolderViewItem* folder_item = mFolderRoot->getItemByID(item);
- if(!folder_item) return true;
- LLInvFVBridge* listenerp = (LLInvFVBridge*)folder_item->getListener();
+ LLInvFVBridge* listenerp = (LLInvFVBridge*)folder_item->getViewModelItem();
if (listenerp->getInventoryType() == LLInventoryType::IT_CALLINGCARD)
{
@@ -1054,13 +1099,13 @@ bool LLInventoryPanel::beginIMSession()
if (name.empty())
{
- name = llformat("Session %d", session_num++);
+ name = LLTrans::getString("conference-title");
}
LLUUID session_id = gIMMgr->addSession(name, type, members[0], members);
if (session_id != LLUUID::null)
{
- LLIMFloater::show(session_id);
+ LLFloaterIMContainer::getInstance()->showConversation(session_id);
}
return true;
@@ -1069,13 +1114,13 @@ bool LLInventoryPanel::beginIMSession()
bool LLInventoryPanel::attachObject(const LLSD& userdata)
{
// Copy selected item UUIDs to a vector.
- std::set<LLUUID> selected_items = mFolderRoot->getSelectionList();
+ std::set<LLFolderViewItem*> selected_items = mFolderRoot->getSelectionList();
uuid_vec_t items;
- for (std::set<LLUUID>::const_iterator set_iter = selected_items.begin();
+ for (std::set<LLFolderViewItem*>::const_iterator set_iter = selected_items.begin();
set_iter != selected_items.end();
++set_iter)
{
- items.push_back(*set_iter);
+ items.push_back(static_cast<LLFolderViewModelItemInventory*>((*set_iter)->getViewModelItem())->getUUID());
}
// Attach selected items.
@@ -1088,7 +1133,7 @@ bool LLInventoryPanel::attachObject(const LLSD& userdata)
BOOL LLInventoryPanel::getSinceLogoff()
{
- return getFilter()->isSinceLogoff();
+ return getFilter().isSinceLogoff();
}
// DEBUG ONLY
@@ -1214,14 +1259,150 @@ void LLInventoryPanel::openInventoryPanelAndSetSelection(BOOL auto_open, const L
void LLInventoryPanel::addHideFolderType(LLFolderType::EType folder_type)
{
- getFilter()->setFilterCategoryTypes(getFilter()->getFilterCategoryTypes() & ~(1ULL << folder_type));
+ getFilter().setFilterCategoryTypes(getFilter().getFilterCategoryTypes() & ~(1ULL << folder_type));
}
BOOL LLInventoryPanel::getIsHiddenFolderType(LLFolderType::EType folder_type) const
{
- return !(getFilter()->getFilterCategoryTypes() & (1ULL << folder_type));
+ return !(getFilter().getFilterCategoryTypes() & (1ULL << folder_type));
+}
+
+void LLInventoryPanel::addItemID( const LLUUID& id, LLFolderViewItem* itemp )
+{
+ mItemMap[id] = itemp;
+}
+
+void LLInventoryPanel::removeItemID(const LLUUID& id)
+{
+ LLInventoryModel::cat_array_t categories;
+ LLInventoryModel::item_array_t items;
+ gInventory.collectDescendents(id, categories, items, TRUE);
+
+ mItemMap.erase(id);
+
+ for (LLInventoryModel::cat_array_t::iterator it = categories.begin(), end_it = categories.end();
+ it != end_it;
+ ++it)
+ {
+ mItemMap.erase((*it)->getUUID());
+}
+
+ for (LLInventoryModel::item_array_t::iterator it = items.begin(), end_it = items.end();
+ it != end_it;
+ ++it)
+ {
+ mItemMap.erase((*it)->getUUID());
+ }
+}
+
+LLFastTimer::DeclareTimer FTM_GET_ITEM_BY_ID("Get FolderViewItem by ID");
+LLFolderViewItem* LLInventoryPanel::getItemByID(const LLUUID& id)
+{
+ LLFastTimer _(FTM_GET_ITEM_BY_ID);
+
+ std::map<LLUUID, LLFolderViewItem*>::iterator map_it;
+ map_it = mItemMap.find(id);
+ if (map_it != mItemMap.end())
+ {
+ return map_it->second;
+ }
+
+ return NULL;
+}
+
+LLFolderViewFolder* LLInventoryPanel::getFolderByID(const LLUUID& id)
+{
+ LLFolderViewItem* item = getItemByID(id);
+ return dynamic_cast<LLFolderViewFolder*>(item);
+}
+
+
+void LLInventoryPanel::setSelectionByID( const LLUUID& obj_id, BOOL take_keyboard_focus )
+{
+ LLFolderViewItem* itemp = getItemByID(obj_id);
+ if(itemp && itemp->getViewModelItem())
+ {
+ itemp->arrangeAndSet(TRUE, take_keyboard_focus);
+ mSelectThisID.setNull();
+ return;
+ }
+ else
+ {
+ // save the desired item to be selected later (if/when ready)
+ mSelectThisID = obj_id;
+ }
+}
+
+void LLInventoryPanel::updateSelection()
+{
+ if (mSelectThisID.notNull())
+ {
+ setSelectionByID(mSelectThisID, false);
+ }
}
+void LLInventoryPanel::doToSelected(const LLSD& userdata)
+{
+ LLInventoryAction::doToSelected(mInventory, mFolderRoot, userdata.asString());
+
+ return;
+}
+
+BOOL LLInventoryPanel::handleKeyHere( KEY key, MASK mask )
+{
+ BOOL handled = FALSE;
+ switch (key)
+ {
+ case KEY_RETURN:
+ // Open selected items if enter key hit on the inventory panel
+ if (mask == MASK_NONE)
+ {
+ LLInventoryAction::doToSelected(mInventory, mFolderRoot, "open");
+ handled = TRUE;
+ }
+ break;
+ case KEY_DELETE:
+ case KEY_BACKSPACE:
+ // Delete selected items if delete or backspace key hit on the inventory panel
+ // Note: on Mac laptop keyboards, backspace and delete are one and the same
+ if (isSelectionRemovable() && (mask == MASK_NONE))
+ {
+ LLInventoryAction::doToSelected(mInventory, mFolderRoot, "delete");
+ handled = TRUE;
+ }
+ break;
+ }
+ return handled;
+}
+
+bool LLInventoryPanel::isSelectionRemovable()
+{
+ bool can_delete = false;
+ if (mFolderRoot)
+ {
+ std::set<LLFolderViewItem*> selection_set = mFolderRoot->getSelectionList();
+ if (!selection_set.empty())
+ {
+ can_delete = true;
+ for (std::set<LLFolderViewItem*>::iterator iter = selection_set.begin();
+ iter != selection_set.end();
+ ++iter)
+ {
+ LLFolderViewItem *item = *iter;
+ const LLFolderViewModelItemInventory *listener = static_cast<const LLFolderViewModelItemInventory*>(item->getViewModelItem());
+ if (!listener)
+ {
+ can_delete = false;
+ }
+ else
+ {
+ can_delete &= listener->isItemRemovable() && !listener->isItemInTrash();
+ }
+ }
+ }
+ }
+ return can_delete;
+}
/************************************************************************/
/* Recent Inventory Panel related class */
@@ -1240,7 +1421,7 @@ public:
{
LLInventoryPanel::initFromParams(p);
// turn on inbox for recent items
- getFilter()->setFilterCategoryTypes(getFilter()->getFilterCategoryTypes() | (1ULL << LLFolderType::FT_INBOX));
+ getFilter().setFilterCategoryTypes(getFilter().getFilterCategoryTypes() | (1ULL << LLFolderType::FT_INBOX));
}
protected:
@@ -1255,3 +1436,34 @@ LLInventoryRecentItemsPanel::LLInventoryRecentItemsPanel( const Params& params)
mInvFVBridgeBuilder = &RECENT_ITEMS_BUILDER;
}
+namespace LLInitParam
+{
+ void TypeValues<LLFolderType::EType>::declareValues()
+ {
+ declare(LLFolderType::lookup(LLFolderType::FT_TEXTURE) , LLFolderType::FT_TEXTURE);
+ declare(LLFolderType::lookup(LLFolderType::FT_SOUND) , LLFolderType::FT_SOUND);
+ declare(LLFolderType::lookup(LLFolderType::FT_CALLINGCARD) , LLFolderType::FT_CALLINGCARD);
+ declare(LLFolderType::lookup(LLFolderType::FT_LANDMARK) , LLFolderType::FT_LANDMARK);
+ declare(LLFolderType::lookup(LLFolderType::FT_CLOTHING) , LLFolderType::FT_CLOTHING);
+ declare(LLFolderType::lookup(LLFolderType::FT_OBJECT) , LLFolderType::FT_OBJECT);
+ declare(LLFolderType::lookup(LLFolderType::FT_NOTECARD) , LLFolderType::FT_NOTECARD);
+ declare(LLFolderType::lookup(LLFolderType::FT_ROOT_INVENTORY) , LLFolderType::FT_ROOT_INVENTORY);
+ declare(LLFolderType::lookup(LLFolderType::FT_LSL_TEXT) , LLFolderType::FT_LSL_TEXT);
+ declare(LLFolderType::lookup(LLFolderType::FT_BODYPART) , LLFolderType::FT_BODYPART);
+ declare(LLFolderType::lookup(LLFolderType::FT_TRASH) , LLFolderType::FT_TRASH);
+ declare(LLFolderType::lookup(LLFolderType::FT_SNAPSHOT_CATEGORY), LLFolderType::FT_SNAPSHOT_CATEGORY);
+ declare(LLFolderType::lookup(LLFolderType::FT_LOST_AND_FOUND) , LLFolderType::FT_LOST_AND_FOUND);
+ declare(LLFolderType::lookup(LLFolderType::FT_ANIMATION) , LLFolderType::FT_ANIMATION);
+ declare(LLFolderType::lookup(LLFolderType::FT_GESTURE) , LLFolderType::FT_GESTURE);
+ declare(LLFolderType::lookup(LLFolderType::FT_FAVORITE) , LLFolderType::FT_FAVORITE);
+ declare(LLFolderType::lookup(LLFolderType::FT_ENSEMBLE_START) , LLFolderType::FT_ENSEMBLE_START);
+ declare(LLFolderType::lookup(LLFolderType::FT_ENSEMBLE_END) , LLFolderType::FT_ENSEMBLE_END);
+ declare(LLFolderType::lookup(LLFolderType::FT_CURRENT_OUTFIT) , LLFolderType::FT_CURRENT_OUTFIT);
+ declare(LLFolderType::lookup(LLFolderType::FT_OUTFIT) , LLFolderType::FT_OUTFIT);
+ declare(LLFolderType::lookup(LLFolderType::FT_MY_OUTFITS) , LLFolderType::FT_MY_OUTFITS);
+ declare(LLFolderType::lookup(LLFolderType::FT_MESH ) , LLFolderType::FT_MESH );
+ declare(LLFolderType::lookup(LLFolderType::FT_INBOX) , LLFolderType::FT_INBOX);
+ declare(LLFolderType::lookup(LLFolderType::FT_OUTBOX) , LLFolderType::FT_OUTBOX);
+ declare(LLFolderType::lookup(LLFolderType::FT_BASIC_ROOT) , LLFolderType::FT_BASIC_ROOT);
+ }
+}
diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h
index 6db59afb9b..00a90325ad 100644..100755
--- a/indra/newview/llinventorypanel.h
+++ b/indra/newview/llinventorypanel.h
@@ -30,6 +30,8 @@
#include "llassetstorage.h"
#include "lldarray.h"
+#include "llfolderviewitem.h"
+#include "llfolderviewmodelinventory.h"
#include "llfloater.h"
#include "llinventory.h"
#include "llinventoryfilter.h"
@@ -38,22 +40,19 @@
#include "lluictrlfactory.h"
#include <set>
-class LLFolderView;
-class LLFolderViewFolder;
-class LLFolderViewItem;
-class LLInventoryFilter;
-class LLInventoryModel;
class LLInvFVBridge;
-class LLInventoryFVBridgeBuilder;
-class LLMenuBarGL;
-class LLCheckBoxCtrl;
-class LLSpinCtrl;
-class LLTextBox;
-class LLIconCtrl;
-class LLSaveFolderState;
-class LLFilterEditor;
-class LLTabContainer;
+class LLInventoryFolderViewModelBuilder;
class LLInvPanelComplObserver;
+class LLFolderViewModelInventory;
+
+namespace LLInitParam
+{
+ template<>
+ struct TypeValues<LLFolderType::EType> : public TypeValuesHelper<LLFolderType::EType>
+ {
+ static void declareValues();
+ };
+}
class LLInventoryPanel : public LLPanel
{
@@ -74,6 +73,19 @@ public:
{}
};
+ struct StartFolder : public LLInitParam::ChoiceBlock<StartFolder>
+ {
+ Alternative<std::string> name;
+ Alternative<LLUUID> id;
+ Alternative<LLFolderType::EType> type;
+
+ StartFolder()
+ : name("name"),
+ id("id"),
+ type("type")
+ {}
+ };
+
struct Params
: public LLInitParam::Block<Params, LLPanel::Params>
{
@@ -82,12 +94,14 @@ public:
Optional<bool> allow_multi_select;
Optional<bool> show_item_link_overlays;
Optional<Filter> filter;
- Optional<std::string> start_folder;
+ Optional<StartFolder> start_folder;
Optional<bool> use_label_suffix;
Optional<bool> show_empty_message;
- Optional<bool> show_load_status;
Optional<LLScrollContainer::Params> scroll;
Optional<bool> accepts_drag_and_drop;
+ Optional<LLFolderView::Params> folder_view;
+ Optional<LLFolderViewFolder::Params> folder;
+ Optional<LLFolderViewItem::Params> item;
Params()
: sort_order_setting("sort_order_setting"),
@@ -98,27 +112,38 @@ public:
start_folder("start_folder"),
use_label_suffix("use_label_suffix", true),
show_empty_message("show_empty_message", true),
- show_load_status("show_load_status"),
scroll("scroll"),
- accepts_drag_and_drop("accepts_drag_and_drop")
+ accepts_drag_and_drop("accepts_drag_and_drop"),
+ folder_view("folder_view"),
+ folder("folder"),
+ item("item")
{}
};
+ struct InventoryState : public LLInitParam::Block<InventoryState>
+ {
+ Mandatory<LLInventoryFilter::Params> filter;
+ Mandatory<LLInventorySort::Params> sort;
+ };
+
//--------------------------------------------------------------------
// Initialization
//--------------------------------------------------------------------
protected:
LLInventoryPanel(const Params&);
void initFromParams(const Params&);
+
friend class LLUICtrlFactory;
public:
virtual ~LLInventoryPanel();
public:
LLInventoryModel* getModel() { return mInventory; }
+ LLFolderViewModelInventory& getRootViewModel() { return mInventoryViewModel; }
// LLView methods
void draw();
+ /*virtual*/ BOOL handleKeyHere( KEY key, MASK mask );
BOOL handleHover(S32 x, S32 y, MASK mask);
BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
EDragAndDropType cargo_type,
@@ -137,8 +162,9 @@ public:
void setSelection(const LLUUID& obj_id, BOOL take_keyboard_focus);
void setSelectCallback(const boost::function<void (const std::deque<LLFolderViewItem*>& items, BOOL user_action)>& cb);
void clearSelection();
- LLInventoryFilter* getFilter();
- const LLInventoryFilter* getFilter() const;
+ bool isSelectionRemovable();
+ LLInventoryFilter& getFilter();
+ const LLInventoryFilter& getFilter() const;
void setFilterTypes(U64 filter, LLInventoryFilter::EFilterType = LLInventoryFilter::FILTERTYPE_OBJECT);
U32 getFilterObjectTypes() const;
void setFilterPermMask(PermissionMask filter_perm_mask);
@@ -156,6 +182,7 @@ public:
// This method is called when something has changed about the inventory.
void modelChanged(U32 mask);
LLFolderView* getRootFolder();
+ LLUUID getRootFolderID();
LLScrollContainer* getScrollableContainer() { return mScroller; }
void onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action);
@@ -167,7 +194,8 @@ public:
void doCreate(const LLSD& userdata);
bool beginIMSession();
bool attachObject(const LLSD& userdata);
-
+ static void idle(void* user_data);
+
// DEBUG ONLY:
static void dumpSelectionInformation(void* user_data);
@@ -182,30 +210,44 @@ public:
static void openInventoryPanelAndSetSelection(BOOL auto_open, const LLUUID& obj_id);
+ void addItemID(const LLUUID& id, LLFolderViewItem* itemp);
+ void removeItemID(const LLUUID& id);
+ LLFolderViewItem* getItemByID(const LLUUID& id);
+ LLFolderViewFolder* getFolderByID(const LLUUID& id);
+ void setSelectionByID(const LLUUID& obj_id, BOOL take_keyboard_focus);
+ void updateSelection();
+
+ LLFolderViewModelInventory* getFolderViewModel();
+ const LLFolderViewModelInventory* getFolderViewModel() const;
+
protected:
void openStartFolderOrMyInventory(); // open the first level of inventory
void onItemsCompletion(); // called when selected items are complete
+ LLUUID mSelectThisID;
LLInventoryModel* mInventory;
LLInventoryObserver* mInventoryObserver;
LLInvPanelComplObserver* mCompletionObserver;
- BOOL mAcceptsDragAndDrop;
- BOOL mAllowMultiSelect;
- BOOL mShowItemLinkOverlays; // Shows link graphic over inventory item icons
- BOOL mShowEmptyMessage;
- BOOL mShowLoadStatus;
+ bool mAcceptsDragAndDrop;
+ bool mAllowMultiSelect;
+ bool mShowItemLinkOverlays; // Shows link graphic over inventory item icons
+ bool mShowEmptyMessage;
LLFolderView* mFolderRoot;
LLScrollContainer* mScroller;
+ LLFolderViewModelInventory mInventoryViewModel;
+ Params mParams; // stored copy of parameter block
+
+ std::map<LLUUID, LLFolderViewItem*> mItemMap;
/**
- * Pointer to LLInventoryFVBridgeBuilder.
+ * Pointer to LLInventoryFolderViewModelBuilder.
*
* It is set in LLInventoryPanel's constructor and can be overridden in derived classes with
* another implementation.
* Take into account it will not be deleted by LLInventoryPanel itself.
*/
- const LLInventoryFVBridgeBuilder* mInvFVBridgeBuilder;
+ const LLInventoryFolderViewModelBuilder* mInvFVBridgeBuilder;
//--------------------------------------------------------------------
@@ -218,7 +260,6 @@ public:
void setSortOrder(U32 order);
U32 getSortOrder() const;
- void requestSort();
private:
std::string mSortOrderSetting;
@@ -231,26 +272,27 @@ public:
void addHideFolderType(LLFolderType::EType folder_type);
public:
- BOOL getIsViewsInitialized() const { return mViewsInitialized; }
- const LLUUID& getRootFolderID() const;
+ BOOL getIsViewsInitialized() const { return mViewsInitialized; }
protected:
// Builds the UI. Call this once the inventory is usable.
void initializeViews();
- LLFolderViewItem* rebuildViewsFor(const LLUUID& id); // Given the id and the parent, build all of the folder views.
- virtual void buildFolderView(const LLInventoryPanel::Params& params);
+ // Specific inventory colors
+ static bool sColorSetInitialized;
+ static LLUIColor sDefaultColor;
+ static LLUIColor sDefaultHighlightColor;
+ static LLUIColor sLibraryColor;
+ static LLUIColor sLinkColor;
+
LLFolderViewItem* buildNewViews(const LLUUID& id);
BOOL getIsHiddenFolderType(LLFolderType::EType folder_type) const;
- virtual LLFolderView* createFolderView(LLInvFVBridge * bridge, bool useLabelSuffix);
+ virtual LLFolderView * createFolderRoot(LLUUID root_id );
virtual LLFolderViewFolder* createFolderViewFolder(LLInvFVBridge * bridge);
virtual LLFolderViewItem* createFolderViewItem(LLInvFVBridge * bridge);
private:
- BOOL mBuildDefaultHierarchy; // default inventory hierarchy should be created in postBuild()
- BOOL mViewsInitialized; // Views have been generated
- // UUID of category from which hierarchy should be built. Set with the
- // "start_folder" xml property. Default is LLUUID::null that means total Inventory hierarchy.
- LLUUID mStartFolderID;
+ bool mBuildDefaultHierarchy; // default inventory hierarchy should be created in postBuild()
+ bool mViewsInitialized; // Views have been generated
};
#endif // LL_LLINVENTORYPANEL_H
diff --git a/indra/newview/lljoystickbutton.cpp b/indra/newview/lljoystickbutton.cpp
index 3d1f186bba..3d1f186bba 100644..100755
--- a/indra/newview/lljoystickbutton.cpp
+++ b/indra/newview/lljoystickbutton.cpp
diff --git a/indra/newview/lljoystickbutton.h b/indra/newview/lljoystickbutton.h
index 8d76aa9531..8d76aa9531 100644..100755
--- a/indra/newview/lljoystickbutton.h
+++ b/indra/newview/lljoystickbutton.h
diff --git a/indra/newview/lllandmarkactions.cpp b/indra/newview/lllandmarkactions.cpp
index 6625a194fb..6625a194fb 100644..100755
--- a/indra/newview/lllandmarkactions.cpp
+++ b/indra/newview/lllandmarkactions.cpp
diff --git a/indra/newview/lllandmarkactions.h b/indra/newview/lllandmarkactions.h
index 870d92811e..870d92811e 100644..100755
--- a/indra/newview/lllandmarkactions.h
+++ b/indra/newview/lllandmarkactions.h
diff --git a/indra/newview/lllandmarklist.cpp b/indra/newview/lllandmarklist.cpp
index dd402de394..dd402de394 100644..100755
--- a/indra/newview/lllandmarklist.cpp
+++ b/indra/newview/lllandmarklist.cpp
diff --git a/indra/newview/lllandmarklist.h b/indra/newview/lllandmarklist.h
index 3356f866ce..3356f866ce 100644..100755
--- a/indra/newview/lllandmarklist.h
+++ b/indra/newview/lllandmarklist.h
diff --git a/indra/newview/lllightconstants.h b/indra/newview/lllightconstants.h
index 216fd4ded5..216fd4ded5 100644..100755
--- a/indra/newview/lllightconstants.h
+++ b/indra/newview/lllightconstants.h
diff --git a/indra/newview/lllistbrowser.cpp b/indra/newview/lllistbrowser.cpp
index 956f457730..956f457730 100644..100755
--- a/indra/newview/lllistbrowser.cpp
+++ b/indra/newview/lllistbrowser.cpp
diff --git a/indra/newview/lllistbrowser.h b/indra/newview/lllistbrowser.h
index 22e8755f08..22e8755f08 100644..100755
--- a/indra/newview/lllistbrowser.h
+++ b/indra/newview/lllistbrowser.h
diff --git a/indra/newview/lllistcontextmenu.cpp b/indra/newview/lllistcontextmenu.cpp
index 6421ab42bf..6421ab42bf 100644..100755
--- a/indra/newview/lllistcontextmenu.cpp
+++ b/indra/newview/lllistcontextmenu.cpp
diff --git a/indra/newview/lllistcontextmenu.h b/indra/newview/lllistcontextmenu.h
index fabd68ee20..04d3314829 100644..100755
--- a/indra/newview/lllistcontextmenu.h
+++ b/indra/newview/lllistcontextmenu.h
@@ -37,7 +37,7 @@ class LLContextMenu;
/**
* Context menu for single or multiple list items.
*
- * Derived classes must implement contextMenu().
+ * Derived classes must implement createMenu().
*
* Typical usage:
* <code>
diff --git a/indra/newview/lllistview.cpp b/indra/newview/lllistview.cpp
index 8fc3ad63bd..8fc3ad63bd 100644..100755
--- a/indra/newview/lllistview.cpp
+++ b/indra/newview/lllistview.cpp
diff --git a/indra/newview/lllistview.h b/indra/newview/lllistview.h
index 4303672b9f..4303672b9f 100644..100755
--- a/indra/newview/lllistview.h
+++ b/indra/newview/lllistview.h
diff --git a/indra/newview/lllocalbitmaps.cpp b/indra/newview/lllocalbitmaps.cpp
index 459e52c4f4..2d9385390b 100644..100755
--- a/indra/newview/lllocalbitmaps.cpp
+++ b/indra/newview/lllocalbitmaps.cpp
@@ -32,9 +32,7 @@
#include "lllocalbitmaps.h"
/* boost: will not compile unless equivalent is undef'd, beware. */
-#ifdef equivalent
-#undef equivalent
-#endif
+#include "fix_macros.h"
#include <boost/filesystem.hpp>
/* image compression headers. */
@@ -55,11 +53,13 @@
#include "llviewerobject.h"
#include "llface.h"
#include "llvoavatarself.h"
-#include "llwearable.h"
+#include "llviewerwearable.h"
#include "llagentwearables.h"
#include "lltexlayerparams.h"
#include "llvovolume.h"
#include "llnotificationsutil.h"
+#include "pipeline.h"
+#include "llmaterialmgr.h"
/*=======================================*/
/* Formal declarations, constants, etc. */
@@ -197,7 +197,7 @@ bool LLLocalBitmap::updateSelf(EUpdateType optional_firstupdate)
mLastModified = new_last_modified;
LLPointer<LLViewerFetchedTexture> texture = new LLViewerFetchedTexture
- ("file://"+mFilename, mWorldID, LL_LOCAL_USE_MIPMAPS);
+ ("file://"+mFilename, FTT_LOCAL_FILE, mWorldID, LL_LOCAL_USE_MIPMAPS);
texture->createGLTexture(LL_LOCAL_DISCARD_LEVEL, raw_image);
texture->setCachedRawImage(LL_LOCAL_DISCARD_LEVEL, raw_image);
@@ -341,7 +341,12 @@ void LLLocalBitmap::replaceIDs(LLUUID old_id, LLUUID new_id)
return;
}
- updateUserPrims(old_id, new_id);
+ // processing updates per channel; makes the process scalable.
+ // the only actual difference is in SetTE* call i.e. SetTETexture, SetTENormal, etc.
+ updateUserPrims(old_id, new_id, LLRender::DIFFUSE_MAP);
+ updateUserPrims(old_id, new_id, LLRender::NORMAL_MAP);
+ updateUserPrims(old_id, new_id, LLRender::SPECULAR_MAP);
+
updateUserSculpts(old_id, new_id); // isn't there supposed to be an IMG_DEFAULT_SCULPT or something?
// default safeguard image for layers
@@ -369,15 +374,15 @@ void LLLocalBitmap::replaceIDs(LLUUID old_id, LLUUID new_id)
// this function sorts the faces from a getFaceList[getNumFaces] into a list of objects
// in order to prevent multiple sendTEUpdate calls per object during updateUserPrims
-std::vector<LLViewerObject*> LLLocalBitmap::prepUpdateObjects(LLUUID old_id)
+std::vector<LLViewerObject*> LLLocalBitmap::prepUpdateObjects(LLUUID old_id, U32 channel)
{
std::vector<LLViewerObject*> obj_list;
LLViewerFetchedTexture* old_texture = gTextureList.findImage(old_id);
-
- for(U32 face_iterator = 0; face_iterator < old_texture->getNumFaces(); face_iterator++)
+
+ for(U32 face_iterator = 0; face_iterator < old_texture->getNumFaces(channel); face_iterator++)
{
// getting an object from a face
- LLFace* face_to_object = (*old_texture->getFaceList())[face_iterator];
+ LLFace* face_to_object = (*old_texture->getFaceList(channel))[face_iterator];
if(face_to_object)
{
@@ -418,9 +423,9 @@ std::vector<LLViewerObject*> LLLocalBitmap::prepUpdateObjects(LLUUID old_id)
return obj_list;
}
-void LLLocalBitmap::updateUserPrims(LLUUID old_id, LLUUID new_id)
+void LLLocalBitmap::updateUserPrims(LLUUID old_id, LLUUID new_id, U32 channel)
{
- std::vector<LLViewerObject*> objectlist = prepUpdateObjects(old_id);
+ std::vector<LLViewerObject*> objectlist = prepUpdateObjects(old_id, channel);
for(std::vector<LLViewerObject*>::iterator object_iterator = objectlist.begin();
object_iterator != objectlist.end(); object_iterator++)
@@ -429,7 +434,8 @@ void LLLocalBitmap::updateUserPrims(LLUUID old_id, LLUUID new_id)
if(object)
{
- bool update_obj = false;
+ bool update_tex = false;
+ bool update_mat = false;
S32 num_faces = object->getNumFaces();
for (U8 face_iter = 0; face_iter < num_faces; face_iter++)
@@ -437,20 +443,51 @@ void LLLocalBitmap::updateUserPrims(LLUUID old_id, LLUUID new_id)
if (object->mDrawable)
{
LLFace* face = object->mDrawable->getFace(face_iter);
- if (face && face->getTexture() && face->getTexture()->getID() == old_id)
+ if (face && face->getTexture(channel) && face->getTexture(channel)->getID() == old_id)
{
- object->setTEImage(face_iter, LLViewerTextureManager::getFetchedTexture
- (new_id, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE));
+ // these things differ per channel, unless there already is a universal
+ // texture setting function to setTE that takes channel as a param?
+ // p.s.: switch for now, might become if - if an extra test is needed to verify before touching normalmap/specmap
+ switch(channel)
+ {
+ case LLRender::DIFFUSE_MAP:
+ {
+ object->setTETexture(face_iter, new_id);
+ update_tex = true;
+ break;
+ }
+
+ case LLRender::NORMAL_MAP:
+ {
+ object->setTENormalMap(face_iter, new_id);
+ update_mat = true;
+ update_tex = true;
+ break;
+ }
+
+ case LLRender::SPECULAR_MAP:
+ {
+ object->setTESpecularMap(face_iter, new_id);
+ update_mat = true;
+ update_tex = true;
+ break;
+ }
+ }
+ // end switch
- update_obj = true;
}
}
}
- if (update_obj)
+ if (update_tex)
{
object->sendTEUpdate();
}
+
+ if (update_mat)
+ {
+ object->mDrawable->getVOVolume()->faceMappingChanged();
+ }
}
}
@@ -483,7 +520,7 @@ void LLLocalBitmap::updateUserLayers(LLUUID old_id, LLUUID new_id, LLWearableTyp
U32 count = gAgentWearables.getWearableCount(type);
for(U32 wearable_iter = 0; wearable_iter < count; wearable_iter++)
{
- LLWearable* wearable = gAgentWearables.getWearable(type, wearable_iter);
+ LLViewerWearable* wearable = gAgentWearables.getViewerWearable(type, wearable_iter);
if (wearable)
{
std::vector<LLLocalTextureObject*> texture_list = wearable->getLocalTextureListSeq();
@@ -495,11 +532,11 @@ void LLLocalBitmap::updateUserLayers(LLUUID old_id, LLUUID new_id, LLWearableTyp
if (lto && lto->getID() == old_id)
{
U32 local_texlayer_index = 0; /* can't keep that as static const, gives errors, so i'm leaving this var here */
- LLVOAvatarDefines::EBakedTextureIndex baked_texind =
+ LLAvatarAppearanceDefines::EBakedTextureIndex baked_texind =
lto->getTexLayer(local_texlayer_index)->getTexLayerSet()->getBakedTexIndex();
- LLVOAvatarDefines::ETextureIndex reg_texind = getTexIndex(type, baked_texind);
- if (reg_texind != LLVOAvatarDefines::TEX_NUM_INDICES)
+ LLAvatarAppearanceDefines::ETextureIndex reg_texind = getTexIndex(type, baked_texind);
+ if (reg_texind != LLAvatarAppearanceDefines::TEX_NUM_INDICES)
{
U32 index = gAgentWearables.getWearableIndex(wearable);
gAgentAvatarp->setLocalTexture(reg_texind, gTextureList.getImage(new_id), FALSE, index);
@@ -515,10 +552,10 @@ void LLLocalBitmap::updateUserLayers(LLUUID old_id, LLUUID new_id, LLWearableTyp
}
}
-LLVOAvatarDefines::ETextureIndex LLLocalBitmap::getTexIndex(
- LLWearableType::EType type, LLVOAvatarDefines::EBakedTextureIndex baked_texind)
+LLAvatarAppearanceDefines::ETextureIndex LLLocalBitmap::getTexIndex(
+ LLWearableType::EType type, LLAvatarAppearanceDefines::EBakedTextureIndex baked_texind)
{
- LLVOAvatarDefines::ETextureIndex result = LLVOAvatarDefines::TEX_NUM_INDICES; // using as a default/fail return.
+ LLAvatarAppearanceDefines::ETextureIndex result = LLAvatarAppearanceDefines::TEX_NUM_INDICES; // using as a default/fail return.
switch(type)
{
@@ -526,32 +563,32 @@ LLVOAvatarDefines::ETextureIndex LLLocalBitmap::getTexIndex(
{
switch(baked_texind)
{
- case LLVOAvatarDefines::BAKED_EYES:
+ case LLAvatarAppearanceDefines::BAKED_EYES:
{
- result = LLVOAvatarDefines::TEX_EYES_ALPHA;
+ result = LLAvatarAppearanceDefines::TEX_EYES_ALPHA;
break;
}
- case LLVOAvatarDefines::BAKED_HAIR:
+ case LLAvatarAppearanceDefines::BAKED_HAIR:
{
- result = LLVOAvatarDefines::TEX_HAIR_ALPHA;
+ result = LLAvatarAppearanceDefines::TEX_HAIR_ALPHA;
break;
}
- case LLVOAvatarDefines::BAKED_HEAD:
+ case LLAvatarAppearanceDefines::BAKED_HEAD:
{
- result = LLVOAvatarDefines::TEX_HEAD_ALPHA;
+ result = LLAvatarAppearanceDefines::TEX_HEAD_ALPHA;
break;
}
- case LLVOAvatarDefines::BAKED_LOWER:
+ case LLAvatarAppearanceDefines::BAKED_LOWER:
{
- result = LLVOAvatarDefines::TEX_LOWER_ALPHA;
+ result = LLAvatarAppearanceDefines::TEX_LOWER_ALPHA;
break;
}
- case LLVOAvatarDefines::BAKED_UPPER:
+ case LLAvatarAppearanceDefines::BAKED_UPPER:
{
- result = LLVOAvatarDefines::TEX_UPPER_ALPHA;
+ result = LLAvatarAppearanceDefines::TEX_UPPER_ALPHA;
break;
}
@@ -567,9 +604,9 @@ LLVOAvatarDefines::ETextureIndex LLLocalBitmap::getTexIndex(
case LLWearableType::WT_EYES:
{
- if (baked_texind == LLVOAvatarDefines::BAKED_EYES)
+ if (baked_texind == LLAvatarAppearanceDefines::BAKED_EYES)
{
- result = LLVOAvatarDefines::TEX_EYES_IRIS;
+ result = LLAvatarAppearanceDefines::TEX_EYES_IRIS;
}
break;
@@ -577,9 +614,9 @@ LLVOAvatarDefines::ETextureIndex LLLocalBitmap::getTexIndex(
case LLWearableType::WT_GLOVES:
{
- if (baked_texind == LLVOAvatarDefines::BAKED_UPPER)
+ if (baked_texind == LLAvatarAppearanceDefines::BAKED_UPPER)
{
- result = LLVOAvatarDefines::TEX_UPPER_GLOVES;
+ result = LLAvatarAppearanceDefines::TEX_UPPER_GLOVES;
}
break;
@@ -587,13 +624,13 @@ LLVOAvatarDefines::ETextureIndex LLLocalBitmap::getTexIndex(
case LLWearableType::WT_JACKET:
{
- if (baked_texind == LLVOAvatarDefines::BAKED_LOWER)
+ if (baked_texind == LLAvatarAppearanceDefines::BAKED_LOWER)
{
- result = LLVOAvatarDefines::TEX_LOWER_JACKET;
+ result = LLAvatarAppearanceDefines::TEX_LOWER_JACKET;
}
- else if (baked_texind == LLVOAvatarDefines::BAKED_UPPER)
+ else if (baked_texind == LLAvatarAppearanceDefines::BAKED_UPPER)
{
- result = LLVOAvatarDefines::TEX_UPPER_JACKET;
+ result = LLAvatarAppearanceDefines::TEX_UPPER_JACKET;
}
break;
@@ -601,9 +638,9 @@ LLVOAvatarDefines::ETextureIndex LLLocalBitmap::getTexIndex(
case LLWearableType::WT_PANTS:
{
- if (baked_texind == LLVOAvatarDefines::BAKED_LOWER)
+ if (baked_texind == LLAvatarAppearanceDefines::BAKED_LOWER)
{
- result = LLVOAvatarDefines::TEX_LOWER_PANTS;
+ result = LLAvatarAppearanceDefines::TEX_LOWER_PANTS;
}
break;
@@ -611,9 +648,9 @@ LLVOAvatarDefines::ETextureIndex LLLocalBitmap::getTexIndex(
case LLWearableType::WT_SHIRT:
{
- if (baked_texind == LLVOAvatarDefines::BAKED_UPPER)
+ if (baked_texind == LLAvatarAppearanceDefines::BAKED_UPPER)
{
- result = LLVOAvatarDefines::TEX_UPPER_SHIRT;
+ result = LLAvatarAppearanceDefines::TEX_UPPER_SHIRT;
}
break;
@@ -621,9 +658,9 @@ LLVOAvatarDefines::ETextureIndex LLLocalBitmap::getTexIndex(
case LLWearableType::WT_SHOES:
{
- if (baked_texind == LLVOAvatarDefines::BAKED_LOWER)
+ if (baked_texind == LLAvatarAppearanceDefines::BAKED_LOWER)
{
- result = LLVOAvatarDefines::TEX_LOWER_SHOES;
+ result = LLAvatarAppearanceDefines::TEX_LOWER_SHOES;
}
break;
@@ -633,20 +670,20 @@ LLVOAvatarDefines::ETextureIndex LLLocalBitmap::getTexIndex(
{
switch(baked_texind)
{
- case LLVOAvatarDefines::BAKED_HEAD:
+ case LLAvatarAppearanceDefines::BAKED_HEAD:
{
- result = LLVOAvatarDefines::TEX_HEAD_BODYPAINT;
+ result = LLAvatarAppearanceDefines::TEX_HEAD_BODYPAINT;
break;
}
- case LLVOAvatarDefines::BAKED_LOWER:
+ case LLAvatarAppearanceDefines::BAKED_LOWER:
{
- result = LLVOAvatarDefines::TEX_LOWER_BODYPAINT;
+ result = LLAvatarAppearanceDefines::TEX_LOWER_BODYPAINT;
break;
}
- case LLVOAvatarDefines::BAKED_UPPER:
+ case LLAvatarAppearanceDefines::BAKED_UPPER:
{
- result = LLVOAvatarDefines::TEX_UPPER_BODYPAINT;
+ result = LLAvatarAppearanceDefines::TEX_UPPER_BODYPAINT;
break;
}
@@ -661,9 +698,9 @@ LLVOAvatarDefines::ETextureIndex LLLocalBitmap::getTexIndex(
case LLWearableType::WT_SKIRT:
{
- if (baked_texind == LLVOAvatarDefines::BAKED_SKIRT)
+ if (baked_texind == LLAvatarAppearanceDefines::BAKED_SKIRT)
{
- result = LLVOAvatarDefines::TEX_SKIRT;
+ result = LLAvatarAppearanceDefines::TEX_SKIRT;
}
break;
@@ -671,9 +708,9 @@ LLVOAvatarDefines::ETextureIndex LLLocalBitmap::getTexIndex(
case LLWearableType::WT_SOCKS:
{
- if (baked_texind == LLVOAvatarDefines::BAKED_LOWER)
+ if (baked_texind == LLAvatarAppearanceDefines::BAKED_LOWER)
{
- result = LLVOAvatarDefines::TEX_LOWER_SOCKS;
+ result = LLAvatarAppearanceDefines::TEX_LOWER_SOCKS;
}
break;
@@ -683,20 +720,20 @@ LLVOAvatarDefines::ETextureIndex LLLocalBitmap::getTexIndex(
{
switch(baked_texind)
{
- case LLVOAvatarDefines::BAKED_HEAD:
+ case LLAvatarAppearanceDefines::BAKED_HEAD:
{
- result = LLVOAvatarDefines::TEX_HEAD_TATTOO;
+ result = LLAvatarAppearanceDefines::TEX_HEAD_TATTOO;
break;
}
- case LLVOAvatarDefines::BAKED_LOWER:
+ case LLAvatarAppearanceDefines::BAKED_LOWER:
{
- result = LLVOAvatarDefines::TEX_LOWER_TATTOO;
+ result = LLAvatarAppearanceDefines::TEX_LOWER_TATTOO;
break;
}
- case LLVOAvatarDefines::BAKED_UPPER:
+ case LLAvatarAppearanceDefines::BAKED_UPPER:
{
- result = LLVOAvatarDefines::TEX_UPPER_TATTOO;
+ result = LLAvatarAppearanceDefines::TEX_UPPER_TATTOO;
break;
}
@@ -711,9 +748,9 @@ LLVOAvatarDefines::ETextureIndex LLLocalBitmap::getTexIndex(
case LLWearableType::WT_UNDERPANTS:
{
- if (baked_texind == LLVOAvatarDefines::BAKED_LOWER)
+ if (baked_texind == LLAvatarAppearanceDefines::BAKED_LOWER)
{
- result = LLVOAvatarDefines::TEX_LOWER_UNDERPANTS;
+ result = LLAvatarAppearanceDefines::TEX_LOWER_UNDERPANTS;
}
break;
@@ -721,9 +758,9 @@ LLVOAvatarDefines::ETextureIndex LLLocalBitmap::getTexIndex(
case LLWearableType::WT_UNDERSHIRT:
{
- if (baked_texind == LLVOAvatarDefines::BAKED_UPPER)
+ if (baked_texind == LLAvatarAppearanceDefines::BAKED_UPPER)
{
- result = LLVOAvatarDefines::TEX_UPPER_UNDERSHIRT;
+ result = LLAvatarAppearanceDefines::TEX_UPPER_UNDERSHIRT;
}
break;
diff --git a/indra/newview/lllocalbitmaps.h b/indra/newview/lllocalbitmaps.h
index 7a23c7ef6e..2ee84bf46e 100644..100755
--- a/indra/newview/lllocalbitmaps.h
+++ b/indra/newview/lllocalbitmaps.h
@@ -28,11 +28,14 @@
#ifndef LL_LOCALBITMAPS_H
#define LL_LOCALBITMAPS_H
+#include "llavatarappearancedefines.h"
#include "lleventtimer.h"
+#include "llimage.h"
+#include "llpointer.h"
#include "llwearabletype.h"
-#include "llvoavatardefines.h"
class LLScrollListCtrl;
+class LLViewerObject;
class LLLocalBitmap
{
@@ -59,11 +62,11 @@ class LLLocalBitmap
private: /* self update private section */
bool decodeBitmap(LLPointer<LLImageRaw> raw);
void replaceIDs(LLUUID old_id, LLUUID new_id);
- std::vector<LLViewerObject*> prepUpdateObjects(LLUUID old_id);
- void updateUserPrims(LLUUID old_id, LLUUID new_id);
+ std::vector<LLViewerObject*> prepUpdateObjects(LLUUID old_id, U32 channel);
+ void updateUserPrims(LLUUID old_id, LLUUID new_id, U32 channel);
void updateUserSculpts(LLUUID old_id, LLUUID new_id);
void updateUserLayers(LLUUID old_id, LLUUID new_id, LLWearableType::EType type);
- LLVOAvatarDefines::ETextureIndex getTexIndex(LLWearableType::EType type, LLVOAvatarDefines::EBakedTextureIndex baked_texind);
+ LLAvatarAppearanceDefines::ETextureIndex getTexIndex(LLWearableType::EType type, LLAvatarAppearanceDefines::EBakedTextureIndex baked_texind);
private: /* private enums */
enum ELinkStatus
diff --git a/indra/newview/lllocaltextureobject.cpp b/indra/newview/lllocaltextureobject.cpp
deleted file mode 100644
index 07ec0fab95..0000000000
--- a/indra/newview/lllocaltextureobject.cpp
+++ /dev/null
@@ -1,212 +0,0 @@
-/**
- * @file lllocaltextureobject.cpp
- *
- * $LicenseInfo:firstyear=2009&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 "llviewerprecompiledheaders.h"
-
-#include "lllocaltextureobject.h"
-
-#include "lltexlayer.h"
-#include "llviewertexture.h"
-#include "lltextureentry.h"
-#include "lluuid.h"
-#include "llwearable.h"
-
-
-LLLocalTextureObject::LLLocalTextureObject() :
- mIsBakedReady(FALSE),
- mDiscard(MAX_DISCARD_LEVEL+1)
-{
- mImage = NULL;
-}
-
-LLLocalTextureObject::LLLocalTextureObject(LLViewerFetchedTexture* image, const LLUUID& id) :
- mIsBakedReady(FALSE),
- mDiscard(MAX_DISCARD_LEVEL+1)
-{
- mImage = image;
- gGL.getTexUnit(0)->bind(mImage);
- mID = id;
-}
-
-LLLocalTextureObject::LLLocalTextureObject(const LLLocalTextureObject& lto) :
- mImage(lto.mImage),
- mID(lto.mID),
- mIsBakedReady(lto.mIsBakedReady),
- mDiscard(lto.mDiscard)
-{
- U32 num_layers = lto.getNumTexLayers();
- mTexLayers.reserve(num_layers);
- for (U32 index = 0; index < num_layers; index++)
- {
- LLTexLayer* original_layer = lto.getTexLayer(index);
- if (!original_layer)
- {
- llerrs << "could not clone Local Texture Object: unable to extract texlayer!" << llendl;
- continue;
- }
-
- LLTexLayer* new_layer = new LLTexLayer(*original_layer);
- new_layer->setLTO(this);
- mTexLayers.push_back(new_layer);
- }
-}
-
-LLLocalTextureObject::~LLLocalTextureObject()
-{
-}
-
-LLViewerFetchedTexture* LLLocalTextureObject::getImage() const
-{
- return mImage;
-}
-
-LLTexLayer* LLLocalTextureObject::getTexLayer(U32 index) const
-{
- if (index >= getNumTexLayers())
- {
- return NULL;
- }
-
- return mTexLayers[index];
-}
-
-LLTexLayer* LLLocalTextureObject::getTexLayer(const std::string &name)
-{
- for( tex_layer_vec_t::iterator iter = mTexLayers.begin(); iter != mTexLayers.end(); iter++)
- {
- LLTexLayer *layer = *iter;
- if (layer->getName().compare(name) == 0)
- {
- return layer;
- }
- }
-
- return NULL;
-}
-
-U32 LLLocalTextureObject::getNumTexLayers() const
-{
- return mTexLayers.size();
-}
-
-LLUUID LLLocalTextureObject::getID() const
-{
- return mID;
-}
-
-S32 LLLocalTextureObject::getDiscard() const
-{
- return mDiscard;
-}
-
-BOOL LLLocalTextureObject::getBakedReady() const
-{
- return mIsBakedReady;
-}
-
-void LLLocalTextureObject::setImage(LLViewerFetchedTexture* new_image)
-{
- mImage = new_image;
-}
-
-BOOL LLLocalTextureObject::setTexLayer(LLTexLayer *new_tex_layer, U32 index)
-{
- if (index >= getNumTexLayers() )
- {
- return FALSE;
- }
-
- if (new_tex_layer == NULL)
- {
- return removeTexLayer(index);
- }
-
- LLTexLayer *layer = new LLTexLayer(*new_tex_layer);
- layer->setLTO(this);
-
- if (mTexLayers[index])
- {
- delete mTexLayers[index];
- }
- mTexLayers[index] = layer;
-
- return TRUE;
-}
-
-BOOL LLLocalTextureObject::addTexLayer(LLTexLayer *new_tex_layer, LLWearable *wearable)
-{
- if (new_tex_layer == NULL)
- {
- return FALSE;
- }
-
- LLTexLayer *layer = new LLTexLayer(*new_tex_layer, wearable);
- layer->setLTO(this);
- mTexLayers.push_back(layer);
- return TRUE;
-}
-
-BOOL LLLocalTextureObject::addTexLayer(LLTexLayerTemplate *new_tex_layer, LLWearable *wearable)
-{
- if (new_tex_layer == NULL)
- {
- return FALSE;
- }
-
- LLTexLayer *layer = new LLTexLayer(*new_tex_layer, this, wearable);
- layer->setLTO(this);
- mTexLayers.push_back(layer);
- return TRUE;
-}
-
-BOOL LLLocalTextureObject::removeTexLayer(U32 index)
-{
- if (index >= getNumTexLayers())
- {
- return FALSE;
- }
- tex_layer_vec_t::iterator iter = mTexLayers.begin();
- iter += index;
-
- delete *iter;
- mTexLayers.erase(iter);
- return TRUE;
-}
-
-void LLLocalTextureObject::setID(LLUUID new_id)
-{
- mID = new_id;
-}
-
-void LLLocalTextureObject::setDiscard(S32 new_discard)
-{
- mDiscard = new_discard;
-}
-
-void LLLocalTextureObject::setBakedReady(BOOL ready)
-{
- mIsBakedReady = ready;
-}
-
diff --git a/indra/newview/lllocaltextureobject.h b/indra/newview/lllocaltextureobject.h
deleted file mode 100644
index b9bfc5472f..0000000000
--- a/indra/newview/lllocaltextureobject.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/**
- * @file lllocaltextureobject.h
- * @brief LLLocalTextureObject class header file
- *
- * $LicenseInfo:firstyear=2009&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$
- */
-
-#ifndef LL_LOCALTEXTUREOBJECT_H
-#define LL_LOCALTEXTUREOBJECT_H
-
-#include <boost/shared_ptr.hpp>
-
-#include "llviewertexture.h"
-
-class LLUUID;
-class LLTexLayer;
-class LLTextureEntry;
-class LLTexLayerTemplate;
-class LLWearable;
-
-// Stores all relevant information for a single texture
-// assumed to have ownership of all objects referred to -
-// will delete objects when being replaced or if object is destroyed.
-class LLLocalTextureObject
-{
-public:
- LLLocalTextureObject();
- LLLocalTextureObject(LLViewerFetchedTexture* image, const LLUUID& id);
- LLLocalTextureObject(const LLLocalTextureObject& lto);
- ~LLLocalTextureObject();
-
- LLViewerFetchedTexture* getImage() const;
- LLTexLayer* getTexLayer(U32 index) const;
- LLTexLayer* getTexLayer(const std::string &name);
- U32 getNumTexLayers() const;
- LLUUID getID() const;
- S32 getDiscard() const;
- BOOL getBakedReady() const;
-
- void setImage(LLViewerFetchedTexture* new_image);
- BOOL setTexLayer(LLTexLayer *new_tex_layer, U32 index);
- BOOL addTexLayer(LLTexLayer *new_tex_layer, LLWearable *wearable);
- BOOL addTexLayer(LLTexLayerTemplate *new_tex_layer, LLWearable *wearable);
- BOOL removeTexLayer(U32 index);
-
- void setID(LLUUID new_id);
- void setDiscard(S32 new_discard);
- void setBakedReady(BOOL ready);
-
-protected:
-
-private:
-
- LLPointer<LLViewerFetchedTexture> mImage;
- // NOTE: LLLocalTextureObject should be the exclusive owner of mTexEntry and mTexLayer
- // using shared pointers here only for smart assignment & cleanup
- // do NOT create new shared pointers to these objects, or keep pointers to them around
- typedef std::vector<LLTexLayer*> tex_layer_vec_t;
- tex_layer_vec_t mTexLayers;
-
- LLUUID mID;
-
- BOOL mIsBakedReady;
- S32 mDiscard;
-};
-
- #endif // LL_LOCALTEXTUREOBJECT_H
-
diff --git a/indra/newview/lllocationhistory.cpp b/indra/newview/lllocationhistory.cpp
index 5138c5e620..5138c5e620 100644..100755
--- a/indra/newview/lllocationhistory.cpp
+++ b/indra/newview/lllocationhistory.cpp
diff --git a/indra/newview/lllocationhistory.h b/indra/newview/lllocationhistory.h
index 9fef42c5df..9fef42c5df 100644..100755
--- a/indra/newview/lllocationhistory.h
+++ b/indra/newview/lllocationhistory.h
diff --git a/indra/newview/lllocationinputctrl.cpp b/indra/newview/lllocationinputctrl.cpp
index 025181ead5..5022dba934 100644..100755
--- a/indra/newview/lllocationinputctrl.cpp
+++ b/indra/newview/lllocationinputctrl.cpp
@@ -44,10 +44,14 @@
// newview includes
#include "llagent.h"
+#include "llenvmanager.h"
#include "llfloatersidepanelcontainer.h"
#include "llinventoryobserver.h"
#include "lllandmarkactions.h"
#include "lllandmarklist.h"
+#include "llpathfindingmanager.h"
+#include "llpathfindingnavmesh.h"
+#include "llpathfindingnavmeshstatus.h"
#include "llteleporthistory.h"
#include "llslurl.h"
#include "llstatusbar.h" // getHealth()
@@ -191,7 +195,9 @@ LLLocationInputCtrl::Params::Params()
damage_icon("damage_icon"),
damage_text("damage_text"),
see_avatars_icon("see_avatars_icon"),
- maturity_help_topic("maturity_help_topic")
+ maturity_help_topic("maturity_help_topic"),
+ pathfinding_dirty_icon("pathfinding_dirty_icon"),
+ pathfinding_disabled_icon("pathfinding_disabled_icon")
{
}
@@ -203,6 +209,9 @@ LLLocationInputCtrl::LLLocationInputCtrl(const LLLocationInputCtrl::Params& p)
mAddLandmarkBtn(NULL),
mForSaleBtn(NULL),
mInfoBtn(NULL),
+ mRegionCrossingSlot(),
+ mNavMeshSlot(),
+ mIsNavMeshDirty(false),
mLandmarkImageOn(NULL),
mLandmarkImageOff(NULL),
mIconMaturityGeneral(NULL),
@@ -270,7 +279,7 @@ LLLocationInputCtrl::LLLocationInputCtrl(const LLLocationInputCtrl::Params& p)
if (p.icon_maturity_general())
{
mIconMaturityGeneral = p.icon_maturity_general;
- }
+ }
if (p.icon_maturity_adult())
{
mIconMaturityAdult = p.icon_maturity_adult;
@@ -279,7 +288,7 @@ LLLocationInputCtrl::LLLocationInputCtrl(const LLLocationInputCtrl::Params& p)
{
mIconMaturityModerate = p.icon_maturity_moderate;
}
-
+
LLButton::Params maturity_button = p.maturity_button;
mMaturityButton = LLUICtrlFactory::create<LLButton>(maturity_button);
addChild(mMaturityButton);
@@ -336,7 +345,21 @@ LLLocationInputCtrl::LLLocationInputCtrl(const LLLocationInputCtrl::Params& p)
mParcelIcon[DAMAGE_ICON] = LLUICtrlFactory::create<LLIconCtrl>(damage_icon);
mParcelIcon[DAMAGE_ICON]->setMouseDownCallback(boost::bind(&LLLocationInputCtrl::onParcelIconClick, this, DAMAGE_ICON));
addChild(mParcelIcon[DAMAGE_ICON]);
-
+
+ LLIconCtrl::Params pathfinding_dirty_icon = p.pathfinding_dirty_icon;
+ pathfinding_dirty_icon.tool_tip = LLTrans::getString("LocationCtrlPathfindingDirtyTooltip");
+ pathfinding_dirty_icon.mouse_opaque = true;
+ mParcelIcon[PATHFINDING_DIRTY_ICON] = LLUICtrlFactory::create<LLIconCtrl>(pathfinding_dirty_icon);
+ mParcelIcon[PATHFINDING_DIRTY_ICON]->setMouseDownCallback(boost::bind(&LLLocationInputCtrl::onParcelIconClick, this, PATHFINDING_DIRTY_ICON));
+ addChild(mParcelIcon[PATHFINDING_DIRTY_ICON]);
+
+ LLIconCtrl::Params pathfinding_disabled_icon = p.pathfinding_disabled_icon;
+ pathfinding_disabled_icon.tool_tip = LLTrans::getString("LocationCtrlPathfindingDisabledTooltip");
+ pathfinding_disabled_icon.mouse_opaque = true;
+ mParcelIcon[PATHFINDING_DISABLED_ICON] = LLUICtrlFactory::create<LLIconCtrl>(pathfinding_disabled_icon);
+ mParcelIcon[PATHFINDING_DISABLED_ICON]->setMouseDownCallback(boost::bind(&LLLocationInputCtrl::onParcelIconClick, this, PATHFINDING_DISABLED_ICON));
+ addChild(mParcelIcon[PATHFINDING_DISABLED_ICON]);
+
LLTextBox::Params damage_text = p.damage_text;
damage_text.tool_tip = LLTrans::getString("LocationCtrlDamageTooltip");
damage_text.mouse_opaque = true;
@@ -391,6 +414,9 @@ LLLocationInputCtrl::LLLocationInputCtrl(const LLLocationInputCtrl::Params& p)
mLocationHistoryConnection = LLLocationHistory::getInstance()->setChangedCallback(
boost::bind(&LLLocationInputCtrl::onLocationHistoryChanged, this,_1));
+ mRegionCrossingSlot = LLEnvManagerNew::getInstance()->setRegionChangeCallback(boost::bind(&LLLocationInputCtrl::onRegionBoundaryCrossed, this));
+ createNavMeshStatusListenerForCurrentRegion();
+
mRemoveLandmarkObserver = new LLRemoveLandmarkObserver(this);
mAddLandmarkObserver = new LLAddLandmarkObserver(this);
gInventory.addObserver(mRemoveLandmarkObserver);
@@ -415,6 +441,8 @@ LLLocationInputCtrl::~LLLocationInputCtrl()
LLViewerParcelMgr::getInstance()->removeObserver(mParcelChangeObserver);
delete mParcelChangeObserver;
+ mRegionCrossingSlot.disconnect();
+ mNavMeshSlot.disconnect();
mCoordinatesControlConnection.disconnect();
mParcelPropertiesControlConnection.disconnect();
mParcelMgrConnection.disconnect();
@@ -636,6 +664,17 @@ void LLLocationInputCtrl::onMaturityButtonClicked()
LLUI::sHelpImpl->showTopic(mMaturityHelpTopic);
}
+void LLLocationInputCtrl::onRegionBoundaryCrossed()
+{
+ createNavMeshStatusListenerForCurrentRegion();
+}
+
+void LLLocationInputCtrl::onNavMeshStatusChange(const LLPathfindingNavMeshStatus &pNavMeshStatus)
+{
+ mIsNavMeshDirty = pNavMeshStatus.isValid() && (pNavMeshStatus.getStatus() != LLPathfindingNavMeshStatus::kComplete);
+ refreshParcelIcons();
+}
+
void LLLocationInputCtrl::onLandmarkLoaded(LLLandmark* lm)
{
(void) lm;
@@ -819,6 +858,7 @@ void LLLocationInputCtrl::refreshParcelIcons()
bool allow_scripts = vpm->allowAgentScripts(agent_region, current_parcel);
bool allow_damage = vpm->allowAgentDamage(agent_region, current_parcel);
bool see_avs = current_parcel->getSeeAVs();
+ bool pathfinding_dynamic_enabled = agent_region->dynamicPathfindingEnabled();
// Most icons are "block this ability"
mParcelIcon[VOICE_ICON]->setVisible( !allow_voice );
@@ -827,6 +867,9 @@ void LLLocationInputCtrl::refreshParcelIcons()
mParcelIcon[BUILD_ICON]->setVisible( !allow_build );
mParcelIcon[SCRIPTS_ICON]->setVisible( !allow_scripts );
mParcelIcon[DAMAGE_ICON]->setVisible( allow_damage );
+ mParcelIcon[PATHFINDING_DIRTY_ICON]->setVisible(mIsNavMeshDirty);
+ mParcelIcon[PATHFINDING_DISABLED_ICON]->setVisible(!mIsNavMeshDirty && !pathfinding_dynamic_enabled);
+
mDamageText->setVisible(allow_damage);
mParcelIcon[SEE_AVATARS_ICON]->setVisible( !see_avs );
@@ -1165,14 +1208,20 @@ void LLLocationInputCtrl::onParcelIconClick(EParcelIcon icon)
case BUILD_ICON:
LLNotificationsUtil::add("NoBuild");
break;
+ case PATHFINDING_DIRTY_ICON:
+ LLNotificationsUtil::add("PathfindingDirty");
+ break;
+ case PATHFINDING_DISABLED_ICON:
+ LLNotificationsUtil::add("DynamicPathfindingDisabled");
+ break;
case SCRIPTS_ICON:
{
LLViewerRegion* region = gAgent.getRegion();
- if(region && region->getRegionFlags() & REGION_FLAGS_ESTATE_SKIP_SCRIPTS)
+ if(region && region->getRegionFlag(REGION_FLAGS_ESTATE_SKIP_SCRIPTS))
{
LLNotificationsUtil::add("ScriptsStopped");
}
- else if(region && region->getRegionFlags() & REGION_FLAGS_SKIP_SCRIPTS)
+ else if(region && region->getRegionFlag(REGION_FLAGS_SKIP_SCRIPTS))
{
LLNotificationsUtil::add("ScriptsNotRunning");
}
@@ -1193,3 +1242,18 @@ void LLLocationInputCtrl::onParcelIconClick(EParcelIcon icon)
// no default to get compiler warning when a new icon gets added
}
}
+
+void LLLocationInputCtrl::createNavMeshStatusListenerForCurrentRegion()
+{
+ if (mNavMeshSlot.connected())
+ {
+ mNavMeshSlot.disconnect();
+ }
+
+ LLViewerRegion *currentRegion = gAgent.getRegion();
+ if (currentRegion != NULL)
+ {
+ mNavMeshSlot = LLPathfindingManager::getInstance()->registerNavMeshListenerForRegion(currentRegion, boost::bind(&LLLocationInputCtrl::onNavMeshStatusChange, this, _2));
+ LLPathfindingManager::getInstance()->requestGetNavMeshForRegion(currentRegion, true);
+ }
+}
diff --git a/indra/newview/lllocationinputctrl.h b/indra/newview/lllocationinputctrl.h
index ed47ba73e3..cd6fd24077 100644..100755
--- a/indra/newview/lllocationinputctrl.h
+++ b/indra/newview/lllocationinputctrl.h
@@ -31,6 +31,7 @@
#include "lliconctrl.h" // Params
#include "lltextbox.h" // Params
#include "lllocationhistory.h"
+#include "llpathfindingnavmesh.h"
class LLLandmark;
@@ -40,6 +41,7 @@ class LLRemoveLandmarkObserver;
class LLParcelChangeObserver;
class LLMenuGL;
class LLTeleportHistoryItem;
+class LLPathfindingNavMeshStatus;
/**
* Location input control.
@@ -78,7 +80,9 @@ public:
build_icon,
scripts_icon,
damage_icon,
- see_avatars_icon;
+ see_avatars_icon,
+ pathfinding_dirty_icon,
+ pathfinding_disabled_icon;
Optional<LLTextBox::Params> damage_text;
Params();
};
@@ -110,13 +114,15 @@ private:
enum EParcelIcon
{
VOICE_ICON = 0,
- FLY_ICON, // 1
- PUSH_ICON, // 2
- BUILD_ICON, // 3
- SCRIPTS_ICON, // 4
- DAMAGE_ICON, // 5
- SEE_AVATARS_ICON, // 6
- ICON_COUNT // 7 total
+ FLY_ICON, // 1
+ PUSH_ICON, // 2
+ BUILD_ICON, // 3
+ SCRIPTS_ICON, // 4
+ DAMAGE_ICON, // 5
+ SEE_AVATARS_ICON, // 6
+ PATHFINDING_DIRTY_ICON, // 7
+ PATHFINDING_DISABLED_ICON,// 8
+ ICON_COUNT // 9 total
};
friend class LLUICtrlFactory;
@@ -155,11 +161,15 @@ private:
void onAddLandmarkButtonClicked();
void onAgentParcelChange();
void onMaturityButtonClicked();
+ void onRegionBoundaryCrossed();
+ void onNavMeshStatusChange(const LLPathfindingNavMeshStatus &pNavMeshStatus);
// callbacks
bool onLocationContextMenuItemEnabled(const LLSD& userdata);
void onLocationContextMenuItemClicked(const LLSD& userdata);
void onParcelIconClick(EParcelIcon icon);
+ void createNavMeshStatusListenerForCurrentRegion();
+
LLMenuGL* mLocationContextMenu;
LLButton* mAddLandmarkBtn;
LLButton* mForSaleBtn;
@@ -179,11 +189,15 @@ private:
boost::signals2::connection mParcelPropertiesControlConnection;
boost::signals2::connection mParcelMgrConnection;
boost::signals2::connection mLocationHistoryConnection;
+ boost::signals2::connection mRegionCrossingSlot;
+ LLPathfindingNavMesh::navmesh_slot_t mNavMeshSlot;
+ bool mIsNavMeshDirty;
LLUIImage* mLandmarkImageOn;
LLUIImage* mLandmarkImageOff;
LLPointer<LLUIImage> mIconMaturityGeneral;
LLPointer<LLUIImage> mIconMaturityAdult;
LLPointer<LLUIImage> mIconMaturityModerate;
+ LLPointer<LLUIImage> mIconPathfindingDynamic;
std::string mAddLandmarkTooltip;
std::string mEditLandmarkTooltip;
diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp
index ebb5912ace..90b169ecd3 100644..100755
--- a/indra/newview/lllogchat.cpp
+++ b/indra/newview/lllogchat.cpp
@@ -25,14 +25,16 @@
*/
#include "llviewerprecompiledheaders.h"
-
+#include "llfloaterconversationpreview.h"
#include "llagent.h"
#include "llagentui.h"
+#include "llavatarnamecache.h"
#include "lllogchat.h"
#include "lltrans.h"
#include "llviewercontrol.h"
#include "lldiriterator.h"
+#include "llfloaterimsessiontab.h"
#include "llinstantmessage.h"
#include "llsingleton.h" // for LLSingleton
@@ -40,6 +42,7 @@
#include <boost/algorithm/string/replace.hpp>
#include <boost/regex.hpp>
#include <boost/regex/v4/match_results.hpp>
+#include <boost/foreach.hpp>
#if LL_MSVC
#pragma warning(push)
@@ -58,10 +61,11 @@
const S32 LOG_RECALL_SIZE = 2048;
-const std::string IM_TIME("time");
-const std::string IM_TEXT("message");
-const std::string IM_FROM("from");
-const std::string IM_FROM_ID("from_id");
+const std::string LL_IM_TIME("time");
+const std::string LL_IM_TEXT("message");
+const std::string LL_IM_FROM("from");
+const std::string LL_IM_FROM_ID("from_id");
+const std::string LL_TRANSCRIPT_FILE_EXTENSION("txt");
const static std::string IM_SEPARATOR(": ");
const static std::string NEW_LINE("\n");
@@ -84,6 +88,7 @@ const static std::string MULTI_LINE_PREFIX(" ");
* Note: "You" was used as an avatar names in viewers of previous versions
*/
const static boost::regex TIMESTAMP_AND_STUFF("^(\\[\\d{4}/\\d{1,2}/\\d{1,2}\\s+\\d{1,2}:\\d{2}\\]\\s+|\\[\\d{1,2}:\\d{2}\\]\\s+)?(.*)$");
+const static boost::regex TIMESTAMP("^(\\[\\d{4}/\\d{1,2}/\\d{1,2}\\s+\\d{1,2}:\\d{2}\\]|\\[\\d{1,2}:\\d{2}\\]).*");
/**
* Regular expression suitable to match names like
@@ -116,6 +121,15 @@ const static int IDX_TEXT = 3;
using namespace boost::posix_time;
using namespace boost::gregorian;
+void append_to_last_message(std::list<LLSD>& messages, const std::string& line)
+{
+ if (!messages.size()) return;
+
+ std::string im_text = messages.back()[LL_IM_TEXT].asString();
+ im_text.append(line);
+ messages.back()[LL_IM_TEXT] = im_text;
+}
+
class LLLogChatTimeScanner: public LLSingleton<LLLogChatTimeScanner>
{
public:
@@ -191,15 +205,18 @@ private:
std::stringstream mTimeStream;
};
+LLLogChat::save_history_signal_t * LLLogChat::sSaveHistorySignal = NULL;
+LLLoadHistoryThread::load_end_signal_t * LLLoadHistoryThread::mLoadEndSignal = NULL;
+
//static
std::string LLLogChat::makeLogFileName(std::string filename)
{
/**
- * Testing for in bound and out bound ad-hoc file names
- * if it is then skip date stamping.
- **/
- //LL_INFOS("") << "Befor:" << filename << LL_ENDL;/* uncomment if you want to verify step, delete on commit */
- boost::match_results<std::string::const_iterator> matches;
+ * Testing for in bound and out bound ad-hoc file names
+ * if it is then skip date stamping.
+ **/
+
+ boost::match_results<std::string::const_iterator> matches;
bool inboundConf = boost::regex_match(filename, matches, INBOUND_CONFERENCE);
bool outboundConf = boost::regex_match(filename, matches, OUTBOUND_CONFERENCE);
if (!(inboundConf || outboundConf))
@@ -220,17 +237,17 @@ std::string LLLogChat::makeLogFileName(std::string filename)
filename += dbuffer;
}
}
- //LL_INFOS("") << "After:" << filename << LL_ENDL;/* uncomment if you want to verify step, delete on commit */
+
filename = cleanFileName(filename);
- filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_ACCOUNT_CHAT_LOGS,filename);
- filename += ".txt";
- //LL_INFOS("") << "Full:" << filename << LL_ENDL;/* uncomment if you want to verify step, delete on commit */
+ filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_ACCOUNT_CHAT_LOGS, filename);
+ filename += '.' + LL_TRANSCRIPT_FILE_EXTENSION;
+
return filename;
}
std::string LLLogChat::cleanFileName(std::string filename)
{
- std::string invalidChars = "\"\'\\/?*:.<>|[]{}~"; // Cannot match glob or illegal filename chars
+ std::string invalidChars = "\"\'\\/?*:.<>|[]{}~"; // Cannot match glob or illegal filename chars
std::string::size_type position = filename.find_first_of(invalidChars);
while (position != filename.npos)
{
@@ -242,27 +259,24 @@ std::string LLLogChat::cleanFileName(std::string filename)
std::string LLLogChat::timestamp(bool withdate)
{
- time_t utc_time;
- utc_time = time_corrected();
-
std::string timeStr;
- LLSD substitution;
- substitution["datetime"] = (S32) utc_time;
-
if (withdate)
{
- timeStr = "["+LLTrans::getString ("TimeYear")+"]/["
- +LLTrans::getString ("TimeMonth")+"]/["
- +LLTrans::getString ("TimeDay")+"] ["
- +LLTrans::getString ("TimeHour")+"]:["
- +LLTrans::getString ("TimeMin")+"]";
+ timeStr = "[" + LLTrans::getString ("TimeYear") + "]/["
+ + LLTrans::getString ("TimeMonth") + "]/["
+ + LLTrans::getString ("TimeDay") + "] ["
+ + LLTrans::getString ("TimeHour") + "]:["
+ + LLTrans::getString ("TimeMin") + "]";
}
else
{
timeStr = "[" + LLTrans::getString("TimeHour") + "]:["
- + LLTrans::getString ("TimeMin")+"]";
+ + LLTrans::getString ("TimeMin")+"]";
}
+ LLSD substitution;
+ substitution["datetime"] = (S32)time_corrected();
+
LLStringUtil::format (timeStr, substitution);
return timeStr;
}
@@ -270,9 +284,9 @@ std::string LLLogChat::timestamp(bool withdate)
//static
void LLLogChat::saveHistory(const std::string& filename,
- const std::string& from,
- const LLUUID& from_id,
- const std::string& line)
+ const std::string& from,
+ const LLUUID& from_id,
+ const std::string& line)
{
std::string tmp_filename = filename;
LLStringUtil::trim(tmp_filename);
@@ -312,156 +326,387 @@ void LLLogChat::saveHistory(const std::string& filename,
file << LLChatLogFormatter(item) << std::endl;
file.close();
+
+ if (NULL != sSaveHistorySignal)
+ {
+ (*sSaveHistorySignal)();
+ }
}
-void LLLogChat::loadHistory(const std::string& filename, void (*callback)(ELogLineType, const LLSD&, void*), void* userdata)
+// static
+void LLLogChat::loadChatHistory(const std::string& file_name, std::list<LLSD>& messages, const LLSD& load_params)
{
- if(!filename.size())
+ if (file_name.empty())
+ {
+ LL_WARNS("LLLogChat::loadChatHistory") << "Session name is Empty!" << LL_ENDL;
+ return ;
+ }
+
+ bool load_all_history = load_params.has("load_all_history") ? load_params["load_all_history"].asBoolean() : false;
+
+ LLFILE* fptr = LLFile::fopen(LLLogChat::makeLogFileName(file_name), "r");/*Flawfinder: ignore*/
+ if (!fptr)
+ {
+ fptr = LLFile::fopen(LLLogChat::oldLogFileName(file_name), "r");/*Flawfinder: ignore*/
+ if (!fptr)
+ {
+ return; //No previous conversation with this name.
+ }
+ }
+
+ char buffer[LOG_RECALL_SIZE]; /*Flawfinder: ignore*/
+ char *bptr;
+ S32 len;
+ bool firstline = TRUE;
+
+ if (load_all_history || fseek(fptr, (LOG_RECALL_SIZE - 1) * -1 , SEEK_END))
+ { //We need to load the whole historyFile or it's smaller than recall size, so get it all.
+ firstline = FALSE;
+ if (fseek(fptr, 0, SEEK_SET))
+ {
+ fclose(fptr);
+ return;
+ }
+ }
+ while (fgets(buffer, LOG_RECALL_SIZE, fptr) && !feof(fptr))
+ {
+ len = strlen(buffer) - 1; /*Flawfinder: ignore*/
+ for (bptr = (buffer + len); (*bptr == '\n' || *bptr == '\r') && bptr>buffer; bptr--) *bptr='\0';
+
+ if (firstline)
+ {
+ firstline = FALSE;
+ continue;
+ }
+
+ std::string line(buffer);
+
+ //updated 1.23 plain text log format requires a space added before subsequent lines in a multilined message
+ if (' ' == line[0])
+ {
+ line.erase(0, MULTI_LINE_PREFIX.length());
+ append_to_last_message(messages, '\n' + line);
+ }
+ else if (0 == len && ('\n' == line[0] || '\r' == line[0]))
+ {
+ //to support old format's multilined messages with new lines used to divide paragraphs
+ append_to_last_message(messages, line);
+ }
+ else
+ {
+ LLSD item;
+ if (!LLChatLogParser::parse(line, item, load_params))
+ {
+ item[LL_IM_TEXT] = line;
+ }
+ messages.push_back(item);
+ }
+ }
+ fclose(fptr);
+
+
+}
+
+void LLLogChat::startChatHistoryThread(const std::string& file_name, const LLSD& load_params)
+{
+
+ LLLoadHistoryThread* mThread = new LLLoadHistoryThread();
+ mThread->start();
+ mThread->setHistoryParams(file_name, load_params);
+}
+// static
+std::string LLLogChat::oldLogFileName(std::string filename)
+{
+ // get Users log directory
+ std::string directory = gDirUtilp->getPerAccountChatLogsDir();
+
+ // add final OS dependent delimiter
+ directory += gDirUtilp->getDirDelimiter();
+
+ // lest make sure the file name has no invalid characters before making the pattern
+ filename = cleanFileName(filename);
+
+ // create search pattern
+ std::string pattern = filename + ( filename == "chat" ? "-???\?-?\?-??.txt" : "-???\?-??.txt");
+
+ std::vector<std::string> allfiles;
+ LLDirIterator iter(directory, pattern);
+ std::string scanResult;
+
+ while (iter.next(scanResult))
{
- llwarns << "Filename is Empty!" << llendl;
- return ;
+ allfiles.push_back(scanResult);
}
-
- LLFILE* fptr = LLFile::fopen(makeLogFileName(filename), "r"); /*Flawfinder: ignore*/
- if (!fptr)
+
+ if (allfiles.size() == 0) // if no result from date search, return generic filename
{
- callback(LOG_EMPTY, LLSD(), userdata);
- return; //No previous conversation with this name.
+ scanResult = directory + filename + '.' + LL_TRANSCRIPT_FILE_EXTENSION;
}
- else
+ else
{
- char buffer[LOG_RECALL_SIZE]; /*Flawfinder: ignore*/
- char *bptr;
- S32 len;
- bool firstline=TRUE;
+ sort(allfiles.begin(), allfiles.end());
+ scanResult = directory + allfiles.back();
+ // this file is now the most recent version of the file.
+ }
+
+ return scanResult;
+}
+
+// static
+void LLLogChat::findTranscriptFiles(std::string pattern, std::vector<std::string>& list_of_transcriptions)
+{
+ // get Users log directory
+ std::string dirname = gDirUtilp->getPerAccountChatLogsDir();
+
+ // add final OS dependent delimiter
+ dirname += gDirUtilp->getDirDelimiter();
- if ( fseek(fptr, (LOG_RECALL_SIZE - 1) * -1 , SEEK_END) )
- { //File is smaller than recall size. Get it all.
- firstline = FALSE;
- if ( fseek(fptr, 0, SEEK_SET) )
+ LLDirIterator iter(dirname, pattern);
+ std::string filename;
+ while (iter.next(filename))
+ {
+ std::string fullname = gDirUtilp->add(dirname, filename);
+
+ LLFILE * filep = LLFile::fopen(fullname, "rb");
+ if (NULL != filep)
+ {
+ if(makeLogFileName("chat")== fullname)
{
- fclose(fptr);
+ //Add Nearby chat history to the list of transcriptions
+ list_of_transcriptions.push_back(gDirUtilp->add(dirname, filename));
+ LLFile::close(filep);
return;
}
- }
+ char buffer[LOG_RECALL_SIZE];
- while ( fgets(buffer, LOG_RECALL_SIZE, fptr) && !feof(fptr) )
- {
- len = strlen(buffer) - 1; /*Flawfinder: ignore*/
- for ( bptr = (buffer + len); (*bptr == '\n' || *bptr == '\r') && bptr>buffer; bptr--) *bptr='\0';
-
- if (!firstline)
+ fseek(filep, 0, SEEK_END); // seek to end of file
+ S32 bytes_to_read = ftell(filep); // get current file pointer
+ fseek(filep, 0, SEEK_SET); // seek back to beginning of file
+
+ // limit the number characters to read from file
+ if (bytes_to_read >= LOG_RECALL_SIZE)
{
- LLSD item;
- std::string line(buffer);
- std::istringstream iss(line);
-
- if (!LLChatLogParser::parse(line, item))
- {
- item["message"] = line;
- callback(LOG_LINE, item, userdata);
- }
- else
- {
- callback(LOG_LLSD, item, userdata);
- }
+ bytes_to_read = LOG_RECALL_SIZE - 1;
}
- else
+
+ if (bytes_to_read > 0 && NULL != fgets(buffer, bytes_to_read, filep))
{
- firstline = FALSE;
+ //matching a timestamp
+ boost::match_results<std::string::const_iterator> matches;
+ if (boost::regex_match(std::string(buffer), matches, TIMESTAMP))
+ {
+ list_of_transcriptions.push_back(gDirUtilp->add(dirname, filename));
+ }
}
+ LLFile::close(filep);
}
- callback(LOG_END, LLSD(), userdata);
-
- fclose(fptr);
}
}
-void append_to_last_message(std::list<LLSD>& messages, const std::string& line)
+// static
+void LLLogChat::getListOfTranscriptFiles(std::vector<std::string>& list_of_transcriptions)
{
- if (!messages.size()) return;
-
- std::string im_text = messages.back()[IM_TEXT].asString();
- im_text.append(line);
- messages.back()[IM_TEXT] = im_text;
+ // create search pattern
+ std::string pattern = "*." + LL_TRANSCRIPT_FILE_EXTENSION;
+ findTranscriptFiles(pattern, list_of_transcriptions);
}
// static
-void LLLogChat::loadAllHistory(const std::string& file_name, std::list<LLSD>& messages)
+void LLLogChat::getListOfTranscriptBackupFiles(std::vector<std::string>& list_of_transcriptions)
{
- if (file_name.empty())
+ // create search pattern
+ std::string pattern = "*." + LL_TRANSCRIPT_FILE_EXTENSION + ".backup*";
+ findTranscriptFiles(pattern, list_of_transcriptions);
+}
+
+//static
+boost::signals2::connection LLLogChat::setSaveHistorySignal(const save_history_signal_t::slot_type& cb)
+{
+ if (NULL == sSaveHistorySignal)
{
- llwarns << "Session name is Empty!" << llendl;
- return ;
- }
- //LL_INFOS("") << "Loading:" << file_name << LL_ENDL;/* uncomment if you want to verify step, delete on commit */
- //LL_INFOS("") << "Current:" << makeLogFileName(file_name) << LL_ENDL;/* uncomment if you want to verify step, delete on commit */
- LLFILE* fptr = LLFile::fopen(makeLogFileName(file_name), "r");/*Flawfinder: ignore*/
- if (!fptr)
- {
- fptr = LLFile::fopen(oldLogFileName(file_name), "r");/*Flawfinder: ignore*/
- if (!fptr)
- {
- if (!fptr) return; //No previous conversation with this name.
- }
- }
-
- //LL_INFOS("") << "Reading:" << file_name << LL_ENDL;
- char buffer[LOG_RECALL_SIZE]; /*Flawfinder: ignore*/
- char *bptr;
- S32 len;
- bool firstline = TRUE;
-
- if (fseek(fptr, (LOG_RECALL_SIZE - 1) * -1 , SEEK_END))
- { //File is smaller than recall size. Get it all.
- firstline = FALSE;
- if (fseek(fptr, 0, SEEK_SET))
- {
- fclose(fptr);
- return;
- }
+ sSaveHistorySignal = new save_history_signal_t();
}
- while (fgets(buffer, LOG_RECALL_SIZE, fptr) && !feof(fptr))
+ return sSaveHistorySignal->connect(cb);
+}
+
+//static
+bool LLLogChat::moveTranscripts(const std::string originDirectory,
+ const std::string targetDirectory,
+ std::vector<std::string>& listOfFilesToMove,
+ std::vector<std::string>& listOfFilesMoved)
+{
+ std::string newFullPath;
+ bool movedAllTranscripts = true;
+ std::string backupFileName;
+ unsigned backupFileCount;
+
+ BOOST_FOREACH(const std::string& fullpath, listOfFilesToMove)
{
- len = strlen(buffer) - 1; /*Flawfinder: ignore*/
- for (bptr = (buffer + len); (*bptr == '\n' || *bptr == '\r') && bptr>buffer; bptr--) *bptr='\0';
-
- if (firstline)
+ backupFileCount = 0;
+ newFullPath = targetDirectory + fullpath.substr(originDirectory.length(), std::string::npos);
+
+ //The target directory contains that file already, so lets store it
+ if(LLFile::isfile(newFullPath))
{
- firstline = FALSE;
- continue;
+ backupFileName = newFullPath + ".backup";
+
+ //If needed store backup file as .backup1 etc.
+ while(LLFile::isfile(backupFileName))
+ {
+ ++backupFileCount;
+ backupFileName = newFullPath + ".backup" + boost::lexical_cast<std::string>(backupFileCount);
+ }
+
+ //Rename the file to its backup name so it is not overwritten
+ LLFile::rename(newFullPath, backupFileName);
+ }
+
+ S32 retry_count = 0;
+ while (retry_count < 5)
+ {
+ //success is zero
+ if (LLFile::rename(fullpath, newFullPath) != 0)
+ {
+ retry_count++;
+ S32 result = errno;
+ LL_WARNS("LLLogChat::moveTranscripts") << "Problem renaming " << fullpath << " - errorcode: "
+ << result << " attempt " << retry_count << LL_ENDL;
+
+ ms_sleep(100);
+ }
+ else
+ {
+ listOfFilesMoved.push_back(newFullPath);
+
+ if (retry_count)
+ {
+ LL_WARNS("LLLogChat::moveTranscripts") << "Successfully renamed " << fullpath << LL_ENDL;
+ }
+ break;
+ }
}
+ }
+
+ if(listOfFilesMoved.size() != listOfFilesToMove.size())
+ {
+ movedAllTranscripts = false;
+ }
- std::string line(buffer);
+ return movedAllTranscripts;
+}
+
+//static
+bool LLLogChat::moveTranscripts(const std::string currentDirectory,
+ const std::string newDirectory,
+ std::vector<std::string>& listOfFilesToMove)
+{
+ std::vector<std::string> listOfFilesMoved;
+ return moveTranscripts(currentDirectory, newDirectory, listOfFilesToMove, listOfFilesMoved);
+}
+
+//static
+void LLLogChat::deleteTranscripts()
+{
+ std::vector<std::string> list_of_transcriptions;
+ getListOfTranscriptFiles(list_of_transcriptions);
+ getListOfTranscriptBackupFiles(list_of_transcriptions);
- //updated 1.23 plaint text log format requires a space added before subsequent lines in a multilined message
- if (' ' == line[0])
+ BOOST_FOREACH(const std::string& fullpath, list_of_transcriptions)
+ {
+ S32 retry_count = 0;
+ while (retry_count < 5)
{
- line.erase(0, MULTI_LINE_PREFIX.length());
- append_to_last_message(messages, '\n' + line);
+ if (0 != LLFile::remove(fullpath))
+ {
+ retry_count++;
+ S32 result = errno;
+ LL_WARNS("LLLogChat::deleteTranscripts") << "Problem removing " << fullpath << " - errorcode: "
+ << result << " attempt " << retry_count << LL_ENDL;
+
+ if(retry_count >= 5)
+ {
+ LL_WARNS("LLLogChat::deleteTranscripts") << "Failed to remove " << fullpath << LL_ENDL;
+ return;
+ }
+
+ ms_sleep(100);
+ }
+ else
+ {
+ if (retry_count)
+ {
+ LL_WARNS("LLLogChat::deleteTranscripts") << "Successfully removed " << fullpath << LL_ENDL;
+ }
+ break;
+ }
}
- else if (0 == len && ('\n' == line[0] || '\r' == line[0]))
+ }
+
+ LLFloaterIMSessionTab::processChatHistoryStyleUpdate(true);
+}
+
+// static
+bool LLLogChat::isTranscriptExist(const LLUUID& avatar_id, bool is_group)
+{
+ std::vector<std::string> list_of_transcriptions;
+ LLLogChat::getListOfTranscriptFiles(list_of_transcriptions);
+
+ if (list_of_transcriptions.size() > 0)
+ {
+ LLAvatarName avatar_name;
+ LLAvatarNameCache::get(avatar_id, &avatar_name);
+ std::string avatar_user_name = avatar_name.getAccountName();
+ if(!is_group)
{
- //to support old format's multilined messages with new lines used to divide paragraphs
- append_to_last_message(messages, line);
+ std::replace(avatar_user_name.begin(), avatar_user_name.end(), '.', '_');
+ BOOST_FOREACH(std::string& transcript_file_name, list_of_transcriptions)
+ {
+ if (std::string::npos != transcript_file_name.find(avatar_user_name))
+ {
+ return true;
+ }
+ }
}
else
{
- LLSD item;
- if (!LLChatLogParser::parse(line, item))
+ std::string file_name;
+ gCacheName->getGroupName(avatar_id, file_name);
+ file_name = makeLogFileName(file_name);
+ BOOST_FOREACH(std::string& transcript_file_name, list_of_transcriptions)
{
- item[IM_TEXT] = line;
+ if (transcript_file_name == file_name)
+ {
+ return true;
+ }
}
- messages.push_back(item);
}
+
}
- fclose(fptr);
+
+ return false;
+}
+
+bool LLLogChat::isNearbyTranscriptExist()
+{
+ std::vector<std::string> list_of_transcriptions;
+ LLLogChat::getListOfTranscriptFiles(list_of_transcriptions);
+
+ std::string file_name;
+ file_name = makeLogFileName("chat");
+ BOOST_FOREACH(std::string& transcript_file_name, list_of_transcriptions)
+ {
+ if (transcript_file_name == file_name)
+ {
+ return true;
+ }
+ }
+ return false;
}
//*TODO mark object's names in a special way so that they will be distinguishable form avatar name
//which are more strict by its nature (only firstname and secondname)
-//Example, an object's name can be writen like "Object <actual_object's_name>"
+//Example, an object's name can be written like "Object <actual_object's_name>"
void LLChatLogFormatter::format(const LLSD& im, std::ostream& ostr) const
{
if (!im.isMap())
@@ -470,19 +715,19 @@ void LLChatLogFormatter::format(const LLSD& im, std::ostream& ostr) const
return;
}
- if (im[IM_TIME].isDefined())
+ if (im[LL_IM_TIME].isDefined())
{
- std::string timestamp = im[IM_TIME].asString();
+ std::string timestamp = im[LL_IM_TIME].asString();
boost::trim(timestamp);
ostr << '[' << timestamp << ']' << TWO_SPACES;
}
//*TODO mark object's names in a special way so that they will be distinguishable form avatar name
//which are more strict by its nature (only firstname and secondname)
- //Example, an object's name can be writen like "Object <actual_object's_name>"
- if (im[IM_FROM].isDefined())
+ //Example, an object's name can be written like "Object <actual_object's_name>"
+ if (im[LL_IM_FROM].isDefined())
{
- std::string from = im[IM_FROM].asString();
+ std::string from = im[LL_IM_FROM].asString();
boost::trim(from);
if (from.size())
{
@@ -490,9 +735,9 @@ void LLChatLogFormatter::format(const LLSD& im, std::ostream& ostr) const
}
}
- if (im[IM_TEXT].isDefined())
+ if (im[LL_IM_TEXT].isDefined())
{
- std::string im_text = im[IM_TEXT].asString();
+ std::string im_text = im[LL_IM_TEXT].asString();
//multilined text will be saved with prepended spaces
boost::replace_all(im_text, NEW_LINE, NEW_LINE_SPACE_PREFIX);
@@ -500,10 +745,11 @@ void LLChatLogFormatter::format(const LLSD& im, std::ostream& ostr) const
}
}
-bool LLChatLogParser::parse(std::string& raw, LLSD& im)
+bool LLChatLogParser::parse(std::string& raw, LLSD& im, const LLSD& parse_params)
{
if (!raw.length()) return false;
+ bool cut_off_todays_date = parse_params.has("cut_off_todays_date") ? parse_params["cut_off_todays_date"].asBoolean() : true;
im = LLSD::emptyMap();
//matching a timestamp
@@ -518,13 +764,18 @@ bool LLChatLogParser::parse(std::string& raw, LLSD& im)
boost::trim(timestamp);
timestamp.erase(0, 1);
timestamp.erase(timestamp.length()-1, 1);
- LLLogChatTimeScanner::instance().checkAndCutOffDate(timestamp);
- im[IM_TIME] = timestamp;
+
+ if (cut_off_todays_date)
+ {
+ LLLogChatTimeScanner::instance().checkAndCutOffDate(timestamp);
+ }
+
+ im[LL_IM_TIME] = timestamp;
}
else
{
//timestamp is optional
- im[IM_TIME] = "";
+ im[LL_IM_TIME] = "";
}
bool has_stuff = matches[IDX_STUFF].matched;
@@ -550,8 +801,8 @@ bool LLChatLogParser::parse(std::string& raw, LLSD& im)
if (!has_name || name == SYSTEM_FROM)
{
//name is optional too
- im[IM_FROM] = SYSTEM_FROM;
- im[IM_FROM_ID] = LLUUID::null;
+ im[LL_IM_FROM] = SYSTEM_FROM;
+ im[LL_IM_FROM_ID] = LLUUID::null;
}
//possibly a case of complex object names consisting of 3+ words
@@ -560,8 +811,8 @@ bool LLChatLogParser::parse(std::string& raw, LLSD& im)
U32 divider_pos = stuff.find(NAME_TEXT_DIVIDER);
if (divider_pos != std::string::npos && divider_pos < (stuff.length() - NAME_TEXT_DIVIDER.length()))
{
- im[IM_FROM] = stuff.substr(0, divider_pos);
- im[IM_TEXT] = stuff.substr(divider_pos + NAME_TEXT_DIVIDER.length());
+ im[LL_IM_FROM] = stuff.substr(0, divider_pos);
+ im[LL_IM_TEXT] = stuff.substr(divider_pos + NAME_TEXT_DIVIDER.length());
return true;
}
}
@@ -569,7 +820,7 @@ bool LLChatLogParser::parse(std::string& raw, LLSD& im)
if (!has_name)
{
//text is mandatory
- im[IM_TEXT] = stuff;
+ im[LL_IM_TEXT] = stuff;
return true; //parse as a message from Second Life
}
@@ -581,45 +832,128 @@ bool LLChatLogParser::parse(std::string& raw, LLSD& im)
{
std::string agent_name;
LLAgentUI::buildFullname(agent_name);
- im[IM_FROM] = agent_name;
- im[IM_FROM_ID] = gAgentID;
+ im[LL_IM_FROM] = agent_name;
+ im[LL_IM_FROM_ID] = gAgentID;
}
else
{
- im[IM_FROM] = name;
+ im[LL_IM_FROM] = name;
}
- im[IM_TEXT] = name_and_text[IDX_TEXT];
+ im[LL_IM_TEXT] = name_and_text[IDX_TEXT];
return true; //parsed name and message text, maybe have a timestamp too
}
-std::string LLLogChat::oldLogFileName(std::string filename)
-{
- std::string scanResult;
- std::string directory = gDirUtilp->getPerAccountChatLogsDir();/* get Users log directory */
- directory += gDirUtilp->getDirDelimiter();/* add final OS dependent delimiter */
- filename=cleanFileName(filename);/* lest make shure the file name has no invalad charecters befor making the pattern */
- std::string pattern = (filename+(( filename == "chat" ) ? "-???\?-?\?-??.txt" : "-???\?-??.txt"));/* create search pattern*/
- //LL_INFOS("") << "Checking:" << directory << " for " << pattern << LL_ENDL;/* uncomment if you want to verify step, delete on commit */
- std::vector<std::string> allfiles;
- LLDirIterator iter(directory, pattern);
- while (iter.next(scanResult))
- {
- //LL_INFOS("") << "Found :" << scanResult << LL_ENDL;
- allfiles.push_back(scanResult);
- }
-
- if (allfiles.size() == 0) // if no result from date search, return generic filename
- {
- scanResult = directory + filename + ".txt";
- }
- else
- {
- std::sort(allfiles.begin(), allfiles.end());
- scanResult = directory + allfiles.back();
- // thisfile is now the most recent version of the file.
- }
- //LL_INFOS("") << "Reading:" << scanResult << LL_ENDL;/* uncomment if you want to verify step, delete on commit */
- return scanResult;
-}
+
+
+ LLLoadHistoryThread::LLLoadHistoryThread() : LLThread("load chat history")
+ {
+ mNewLoad = false;
+ }
+
+ void LLLoadHistoryThread::run()
+ {
+ while (!LLApp::isQuitting())
+ {
+ if(mNewLoad)
+ {
+ loadHistory(mFileName,mMessages,mLoadParams);
+ shutdown();
+ }
+ }
+ }
+ void LLLoadHistoryThread::setHistoryParams(const std::string& file_name, const LLSD& load_params)
+ {
+ mFileName = file_name;
+ mLoadParams = load_params;
+ mNewLoad = true;
+ }
+ void LLLoadHistoryThread::loadHistory(const std::string& file_name, std::list<LLSD>& messages, const LLSD& load_params)
+ {
+
+ if (file_name.empty())
+ {
+ LL_WARNS("LLLogChat::loadHistory") << "Session name is Empty!" << LL_ENDL;
+ return ;
+ }
+
+ bool load_all_history = load_params.has("load_all_history") ? load_params["load_all_history"].asBoolean() : false;
+
+ LLFILE* fptr = LLFile::fopen(LLLogChat::makeLogFileName(file_name), "r");/*Flawfinder: ignore*/
+ if (!fptr)
+ {
+ fptr = LLFile::fopen(LLLogChat::oldLogFileName(file_name), "r");/*Flawfinder: ignore*/
+ if (!fptr)
+ {
+ mNewLoad = false;
+ (*mLoadEndSignal)(messages, file_name);
+ return; //No previous conversation with this name.
+ }
+ }
+
+ char buffer[LOG_RECALL_SIZE]; /*Flawfinder: ignore*/
+ char *bptr;
+ S32 len;
+ bool firstline = TRUE;
+
+ if (load_all_history || fseek(fptr, (LOG_RECALL_SIZE - 1) * -1 , SEEK_END))
+ { //We need to load the whole historyFile or it's smaller than recall size, so get it all.
+ firstline = FALSE;
+ if (fseek(fptr, 0, SEEK_SET))
+ {
+ fclose(fptr);
+ mNewLoad = false;
+ (*mLoadEndSignal)(messages, file_name);
+ return;
+ }
+ }
+ while (fgets(buffer, LOG_RECALL_SIZE, fptr) && !feof(fptr))
+ {
+ len = strlen(buffer) - 1; /*Flawfinder: ignore*/
+ for (bptr = (buffer + len); (*bptr == '\n' || *bptr == '\r') && bptr>buffer; bptr--) *bptr='\0';
+
+ if (firstline)
+ {
+ firstline = FALSE;
+ continue;
+ }
+
+ std::string line(buffer);
+
+ //updated 1.23 plaint text log format requires a space added before subsequent lines in a multilined message
+ if (' ' == line[0])
+ {
+ line.erase(0, MULTI_LINE_PREFIX.length());
+ append_to_last_message(messages, '\n' + line);
+ }
+ else if (0 == len && ('\n' == line[0] || '\r' == line[0]))
+ {
+ //to support old format's multilined messages with new lines used to divide paragraphs
+ append_to_last_message(messages, line);
+ }
+ else
+ {
+ LLSD item;
+ if (!LLChatLogParser::parse(line, item, load_params))
+ {
+ item[LL_IM_TEXT] = line;
+ }
+ messages.push_back(item);
+ }
+ }
+ fclose(fptr);
+ mNewLoad = false;
+ (*mLoadEndSignal)(messages, file_name);
+ }
+
+ //static
+ boost::signals2::connection LLLoadHistoryThread::setLoadEndSignal(const load_end_signal_t::slot_type& cb)
+ {
+ if (NULL == mLoadEndSignal)
+ {
+ mLoadEndSignal = new load_end_signal_t();
+ }
+
+ return mLoadEndSignal->connect(cb);
+ }
diff --git a/indra/newview/lllogchat.h b/indra/newview/lllogchat.h
index 27752452c9..acee99afa2 100644..100755
--- a/indra/newview/lllogchat.h
+++ b/indra/newview/lllogchat.h
@@ -28,6 +28,24 @@
#define LL_LLLOGCHAT_H
class LLChat;
+class LLLoadHistoryThread : public LLThread
+{
+private:
+ std::string mFileName;
+ std::list<LLSD> mMessages;
+ LLSD mLoadParams;
+ bool mNewLoad;
+public:
+ LLLoadHistoryThread();
+
+ void setHistoryParams(const std::string& file_name, const LLSD& load_params);
+ virtual void loadHistory(const std::string& file_name, std::list<LLSD>& messages, const LLSD& load_params);
+ virtual void run();
+
+ typedef boost::signals2::signal<void (std::list<LLSD>& messages,const std::string& file_name)> load_end_signal_t;
+ static load_end_signal_t * mLoadEndSignal;
+ static boost::signals2::connection setLoadEndSignal(const load_end_signal_t::slot_type& cb);
+};
class LLLogChat
{
@@ -39,6 +57,7 @@ public:
LOG_LLSD,
LOG_END
};
+
static std::string timestamp(bool withdate = false);
static std::string makeLogFileName(std::string(filename));
/**
@@ -49,15 +68,31 @@ public:
const std::string& from,
const LLUUID& from_id,
const std::string& line);
+ static void findTranscriptFiles(std::string pattern, std::vector<std::string>& list_of_transcriptions);
+ static void getListOfTranscriptFiles(std::vector<std::string>& list);
+ static void getListOfTranscriptBackupFiles(std::vector<std::string>& list_of_transcriptions);
+
+ static void loadChatHistory(const std::string& file_name, std::list<LLSD>& messages, const LLSD& load_params = LLSD());
+ static void startChatHistoryThread(const std::string& file_name, const LLSD& load_params);
+
+ typedef boost::signals2::signal<void ()> save_history_signal_t;
+ static boost::signals2::connection setSaveHistorySignal(const save_history_signal_t::slot_type& cb);
- /** @deprecated @see loadAllHistory() */
- static void loadHistory(const std::string& filename,
- void (*callback)(ELogLineType, const LLSD&, void*),
- void* userdata);
+ static bool moveTranscripts(const std::string currentDirectory,
+ const std::string newDirectory,
+ std::vector<std::string>& listOfFilesToMove,
+ std::vector<std::string>& listOfFilesMoved);
+ static bool moveTranscripts(const std::string currentDirectory,
+ const std::string newDirectory,
+ std::vector<std::string>& listOfFilesToMove);
+
+ static void deleteTranscripts();
+ static bool isTranscriptExist(const LLUUID& avatar_id, bool is_group=false);
+ static bool isNearbyTranscriptExist();
- static void loadAllHistory(const std::string& file_name, std::list<LLSD>& messages);
private:
static std::string cleanFileName(std::string filename);
+ static save_history_signal_t * sSaveHistorySignal;
};
/**
@@ -105,17 +140,19 @@ public:
*
* @return false if failed to parse mandatory data - message text
*/
- static bool parse(std::string& raw, LLSD& im);
+ static bool parse(std::string& raw, LLSD& im, const LLSD& parse_params = LLSD());
protected:
LLChatLogParser();
virtual ~LLChatLogParser() {};
};
+
// LLSD map lookup constants
-extern const std::string IM_TIME; //("time");
-extern const std::string IM_TEXT; //("message");
-extern const std::string IM_FROM; //("from");
-extern const std::string IM_FROM_ID; //("from_id");
+extern const std::string LL_IM_TIME; //("time");
+extern const std::string LL_IM_TEXT; //("message");
+extern const std::string LL_IM_FROM; //("from");
+extern const std::string LL_IM_FROM_ID; //("from_id");
+extern const std::string LL_TRANSCRIPT_FILE_EXTENSION; //("txt");
#endif
diff --git a/indra/newview/llloginhandler.cpp b/indra/newview/llloginhandler.cpp
index 9b4f146332..9b4f146332 100644..100755
--- a/indra/newview/llloginhandler.cpp
+++ b/indra/newview/llloginhandler.cpp
diff --git a/indra/newview/llloginhandler.h b/indra/newview/llloginhandler.h
index 1f2eacd094..1f2eacd094 100644..100755
--- a/indra/newview/llloginhandler.h
+++ b/indra/newview/llloginhandler.h
diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp
index 419641d23c..f681c12747 100644..100755
--- a/indra/newview/lllogininstance.cpp
+++ b/indra/newview/lllogininstance.cpp
@@ -30,7 +30,6 @@
// llcommon
#include "llevents.h"
-#include "llmd5.h"
#include "stringize.h"
// llmessage (!)
@@ -40,6 +39,7 @@
#include "lllogin.h"
// newview
+#include "llhasheduniqueid.h"
#include "llviewernetwork.h"
#include "llviewercontrol.h"
#include "llversioninfo.h"
@@ -202,7 +202,7 @@ MandatoryUpdateMachine::MandatoryUpdateMachine(LLLoginInstance & loginInstance,
void MandatoryUpdateMachine::start(void)
{
- llinfos << "starting manditory update machine" << llendl;
+ llinfos << "starting mandatory update machine" << llendl;
if(mUpdaterService.isChecking()) {
switch(mUpdaterService.getState()) {
@@ -488,6 +488,13 @@ LLLoginInstance::LLLoginInstance() :
mDispatcher.add("indeterminate", "", boost::bind(&LLLoginInstance::handleIndeterminate, this, _1));
}
+void LLLoginInstance::setPlatformInfo(const std::string platform,
+ const std::string platform_version)
+{
+ mPlatform = platform;
+ mPlatformVersion = platform_version;
+}
+
LLLoginInstance::~LLLoginInstance()
{
}
@@ -579,26 +586,22 @@ void LLLoginInstance::constructAuthParams(LLPointer<LLCredential> user_credentia
// (re)initialize the request params with creds.
LLSD request_params = user_credential->getLoginParams();
- char hashed_unique_id_string[MD5HEX_STR_SIZE]; /* Flawfinder: ignore */
- LLMD5 hashed_unique_id;
- unsigned char unique_id[MAC_ADDRESS_BYTES];
- if(LLUUID::getNodeID(unique_id) == 0) {
- if(LLMachineID::getUniqueID(unique_id, sizeof(unique_id)) == 0) {
- llerrs << "Failed to get an id; cannot uniquely identify this machine." << llendl;
- }
+ unsigned char hashed_unique_id_string[MD5HEX_STR_SIZE];
+ if ( ! llHashedUniqueID(hashed_unique_id_string) )
+ {
+ llwarns << "Not providing a unique id in request params" << llendl;
}
- hashed_unique_id.update(unique_id, MAC_ADDRESS_BYTES);
- hashed_unique_id.finalize();
- hashed_unique_id.hex_digest(hashed_unique_id_string);
-
request_params["start"] = construct_start_string();
request_params["skipoptional"] = mSkipOptionalUpdate;
request_params["agree_to_tos"] = false; // Always false here. Set true in
request_params["read_critical"] = false; // handleTOSResponse
request_params["last_exec_event"] = mLastExecEvent;
- request_params["mac"] = hashed_unique_id_string;
- request_params["version"] = LLVersionInfo::getChannelAndVersion(); // Includes channel name
+ request_params["last_exec_duration"] = mLastExecDuration;
+ request_params["mac"] = (char*)hashed_unique_id_string;
+ request_params["version"] = LLVersionInfo::getVersion();
request_params["channel"] = LLVersionInfo::getChannel();
+ request_params["platform"] = mPlatform;
+ request_params["platform_version"] = mPlatformVersion;
request_params["id0"] = mSerialNumber;
request_params["host_id"] = gSavedSettings.getString("HostID");
request_params["extended_errors"] = true; // request message_id and message_args
@@ -639,6 +642,8 @@ bool LLLoginInstance::handleLoginEvent(const LLSD& event)
void LLLoginInstance::handleLoginFailure(const LLSD& event)
{
+
+
// Login has failed.
// Figure out why and respond...
LLSD response = event["data"];
@@ -651,10 +656,13 @@ void LLLoginInstance::handleLoginFailure(const LLSD& event)
// to reconnect or to end the attempt in failure.
if(reason_response == "tos")
{
+ llinfos << "LLLoginInstance::handleLoginFailure ToS" << llendl;
+
LLSD data(LLSD::emptyMap());
data["message"] = message_response;
data["reply_pump"] = TOS_REPLY_PUMP;
- gViewerWindow->setShowProgress(FALSE);
+ if (gViewerWindow)
+ gViewerWindow->setShowProgress(FALSE);
LLFloaterReg::showInstance("message_tos", data);
LLEventPumps::instance().obtain(TOS_REPLY_PUMP)
.listen(TOS_LISTENER_NAME,
@@ -663,6 +671,8 @@ void LLLoginInstance::handleLoginFailure(const LLSD& event)
}
else if(reason_response == "critical")
{
+ llinfos << "LLLoginInstance::handleLoginFailure Crit" << llendl;
+
LLSD data(LLSD::emptyMap());
data["message"] = message_response;
data["reply_pump"] = TOS_REPLY_PUMP;
@@ -675,7 +685,9 @@ void LLLoginInstance::handleLoginFailure(const LLSD& event)
data["certificate"] = response["certificate"];
}
- gViewerWindow->setShowProgress(FALSE);
+ if (gViewerWindow)
+ gViewerWindow->setShowProgress(FALSE);
+
LLFloaterReg::showInstance("message_critical", data);
LLEventPumps::instance().obtain(TOS_REPLY_PUMP)
.listen(TOS_LISTENER_NAME,
@@ -684,21 +696,28 @@ void LLLoginInstance::handleLoginFailure(const LLSD& event)
}
else if(reason_response == "update" || gSavedSettings.getBOOL("ForceMandatoryUpdate"))
{
+ llinfos << "LLLoginInstance::handleLoginFailure update" << llendl;
+
gSavedSettings.setBOOL("ForceMandatoryUpdate", FALSE);
updateApp(true, message_response);
}
else if(reason_response == "optional")
{
+ llinfos << "LLLoginInstance::handleLoginFailure optional" << llendl;
+
updateApp(false, message_response);
}
else
{
+ llinfos << "LLLoginInstance::handleLoginFailure attemptComplete" << llendl;
attemptComplete();
}
}
void LLLoginInstance::handleLoginSuccess(const LLSD& event)
{
+ llinfos << "LLLoginInstance::handleLoginSuccess" << llendl;
+
if(gSavedSettings.getBOOL("ForceMandatoryUpdate"))
{
LLSD response = event["data"];
@@ -720,6 +739,8 @@ void LLLoginInstance::handleLoginSuccess(const LLSD& event)
void LLLoginInstance::handleDisconnect(const LLSD& event)
{
// placeholder
+
+ llinfos << "LLLoginInstance::handleDisconnect placeholder " << llendl;
}
void LLLoginInstance::handleIndeterminate(const LLSD& event)
@@ -728,10 +749,13 @@ void LLLoginInstance::handleIndeterminate(const LLSD& event)
// gave the viewer a new url and params to try.
// The login module handles the retry, but it gives us the
// server response so that we may show
- // the user some status.
+ // the user some status.
+
LLSD message = event.get("data").get("message");
if(message.isDefined())
{
+ llinfos << "LLLoginInstance::handleIndeterminate " << message.asString() << llendl;
+
LLSD progress_update;
progress_update["desc"] = message;
LLEventPumps::getInstance()->obtain("LLProgressView").post(progress_update);
@@ -742,12 +766,16 @@ bool LLLoginInstance::handleTOSResponse(bool accepted, const std::string& key)
{
if(accepted)
{
+ llinfos << "LLLoginInstance::handleTOSResponse: accepted" << llendl;
+
// Set the request data to true and retry login.
mRequestData["params"][key] = true;
reconnect();
}
else
{
+ llinfos << "LLLoginInstance::handleTOSResponse: attemptComplete" << llendl;
+
attemptComplete();
}
@@ -784,20 +812,20 @@ void LLLoginInstance::updateApp(bool mandatory, const std::string& auth_msg)
LLSD payload;
payload["mandatory"] = mandatory;
-/*
- We're constructing one of the following 9 strings here:
- "DownloadWindowsMandatory"
- "DownloadWindowsReleaseForDownload"
- "DownloadWindows"
- "DownloadMacMandatory"
- "DownloadMacReleaseForDownload"
- "DownloadMac"
- "DownloadLinuxMandatory"
- "DownloadLinuxReleaseForDownload"
- "DownloadLinux"
-
- I've called them out explicitly in this comment so that they can be grepped for.
- */
+ /*
+ * We're constructing one of the following 9 strings here:
+ * "DownloadWindowsMandatory"
+ * "DownloadWindowsReleaseForDownload"
+ * "DownloadWindows"
+ * "DownloadMacMandatory"
+ * "DownloadMacReleaseForDownload"
+ * "DownloadMac"
+ * "DownloadLinuxMandatory"
+ * "DownloadLinuxReleaseForDownload"
+ * "DownloadLinux"
+ *
+ * I've called them out explicitly in this comment so that they can be grepped for.
+ */
std::string notification_name = "Download";
#if LL_WINDOWS
diff --git a/indra/newview/lllogininstance.h b/indra/newview/lllogininstance.h
index 8b53431219..b0247da7c8 100644..100755
--- a/indra/newview/lllogininstance.h
+++ b/indra/newview/lllogininstance.h
@@ -66,6 +66,8 @@ public:
void setSkipOptionalUpdate(bool state) { mSkipOptionalUpdate = state; }
void setSerialNumber(const std::string& sn) { mSerialNumber = sn; }
void setLastExecEvent(int lee) { mLastExecEvent = lee; }
+ void setLastExecDuration(S32 duration) { mLastExecDuration = duration; }
+ void setPlatformInfo(const std::string platform, const std::string platform_version);
void setNotificationsInterface(LLNotificationsInterface* ni) { mNotifications = ni; }
@@ -99,6 +101,9 @@ private:
F64 mTransferRate;
std::string mSerialNumber;
int mLastExecEvent;
+ S32 mLastExecDuration;
+ std::string mPlatform;
+ std::string mPlatformVersion;
UpdaterLauncherCallback mUpdaterLauncher;
LLEventDispatcher mDispatcher;
LLUpdaterService * mUpdaterService;
diff --git a/indra/newview/lllookshistorypanel.h b/indra/newview/lllookshistorypanel.h
index 965b4d8416..965b4d8416 100644..100755
--- a/indra/newview/lllookshistorypanel.h
+++ b/indra/newview/lllookshistorypanel.h
diff --git a/indra/newview/llmachineid.cpp b/indra/newview/llmachineid.cpp
index 778693876e..cd6473921d 100644..100755
--- a/indra/newview/llmachineid.cpp
+++ b/indra/newview/llmachineid.cpp
@@ -252,12 +252,20 @@ S32 LLMachineID::getUniqueID(unsigned char *unique_id, size_t len)
if (has_static_unique_id)
{
memcpy ( unique_id, &static_unique_id, len);
- LL_DEBUGS("AppInit") << "UniqueID: " << unique_id[0] << unique_id[1]<< unique_id[2] << unique_id[3] << unique_id[4] << unique_id [5] << LL_ENDL;
+ LL_DEBUGS("AppInit") << "UniqueID: 0x";
+ // Code between here and LL_ENDL is not executed unless the LL_DEBUGS
+ // actually produces output
+ for (size_t i = 0; i < len; ++i)
+ {
+ // Copy each char to unsigned int to hexify. Sending an unsigned
+ // char to a std::ostream tries to represent it as a char, not
+ // what we want here.
+ unsigned byte = unique_id[i];
+ LL_CONT << std::hex << std::setw(2) << std::setfill('0') << byte;
+ }
+ // Reset default output formatting to avoid nasty surprises!
+ LL_CONT << std::dec << std::setw(0) << std::setfill(' ') << LL_ENDL;
return 1;
}
return 0;
}
-
-
-
-
diff --git a/indra/newview/llmachineid.h b/indra/newview/llmachineid.h
index 6ef8c36fdb..6ef8c36fdb 100644..100755
--- a/indra/newview/llmachineid.h
+++ b/indra/newview/llmachineid.h
diff --git a/indra/newview/llmainlooprepeater.cpp b/indra/newview/llmainlooprepeater.cpp
index 5c020e6d98..5c020e6d98 100644..100755
--- a/indra/newview/llmainlooprepeater.cpp
+++ b/indra/newview/llmainlooprepeater.cpp
diff --git a/indra/newview/llmainlooprepeater.h b/indra/newview/llmainlooprepeater.h
index f84c0ca94c..f84c0ca94c 100644..100755
--- a/indra/newview/llmainlooprepeater.h
+++ b/indra/newview/llmainlooprepeater.h
diff --git a/indra/newview/llmanip.cpp b/indra/newview/llmanip.cpp
index 6e0f360cbc..a7d6cb5eac 100644..100755
--- a/indra/newview/llmanip.cpp
+++ b/indra/newview/llmanip.cpp
@@ -53,7 +53,7 @@
#include "llresmgr.h"
#include "pipeline.h"
#include "llglheaders.h"
-
+#include "lluiimage.h"
// Local constants...
const S32 VERTICAL_OFFSET = 50;
@@ -72,7 +72,6 @@ void LLManip::rebuild(LLViewerObject* vobj)
LLDrawable* drawablep = vobj->mDrawable;
if (drawablep && drawablep->getVOVolume())
{
-
gPipeline.markRebuild(drawablep,LLDrawable::REBUILD_VOLUME, TRUE);
drawablep->setState(LLDrawable::MOVE_UNDAMPED); // force to UNDAMPED
drawablep->updateMove();
@@ -82,6 +81,14 @@ void LLManip::rebuild(LLViewerObject* vobj)
group->dirtyGeom();
gPipeline.markRebuild(group, TRUE);
}
+
+ LLViewerObject::const_child_list_t& child_list = vobj->getChildren();
+ for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(), endIter = child_list.end();
+ iter != endIter; ++iter)
+ {
+ LLViewerObject* child = *iter;
+ rebuild(child);
+ }
}
}
diff --git a/indra/newview/llmanip.h b/indra/newview/llmanip.h
index 6263e4244f..6263e4244f 100644..100755
--- a/indra/newview/llmanip.h
+++ b/indra/newview/llmanip.h
diff --git a/indra/newview/llmaniprotate.cpp b/indra/newview/llmaniprotate.cpp
index a8da94f75e..4cbdfde868 100644..100755
--- a/indra/newview/llmaniprotate.cpp
+++ b/indra/newview/llmaniprotate.cpp
@@ -479,9 +479,12 @@ BOOL LLManipRotate::handleMouseUp(S32 x, S32 y, MASK mask)
{
LLSelectNode* selectNode = *iter;
LLViewerObject* object = selectNode->getObject();
+ LLViewerObject* root_object = (object == NULL) ? NULL : object->getRootEdit();
// have permission to move and object is root of selection or individually selected
- if (object->permMove() && (object->isRootEdit() || selectNode->mIndividualSelection))
+ if (object->permMove() && !object->isPermanentEnforced() &&
+ ((root_object == NULL) || !root_object->isPermanentEnforced()) &&
+ (object->isRootEdit() || selectNode->mIndividualSelection))
{
object->mUnselectedChildrenPositions.clear() ;
}
@@ -567,9 +570,12 @@ void LLManipRotate::drag( S32 x, S32 y )
{
LLSelectNode* selectNode = *iter;
LLViewerObject* object = selectNode->getObject();
+ LLViewerObject* root_object = (object == NULL) ? NULL : object->getRootEdit();
// have permission to move and object is root of selection or individually selected
- if (object->permMove() && (object->isRootEdit() || selectNode->mIndividualSelection))
+ if (object->permMove() && !object->isPermanentEnforced() &&
+ ((root_object == NULL) || !root_object->isPermanentEnforced()) &&
+ (object->isRootEdit() || selectNode->mIndividualSelection))
{
if (!object->isRootEdit())
{
@@ -621,9 +627,11 @@ void LLManipRotate::drag( S32 x, S32 y )
{
LLSelectNode* selectNode = *iter;
LLViewerObject* object = selectNode->getObject();
+ LLViewerObject* root_object = (object == NULL) ? NULL : object->getRootEdit();
// to avoid cumulative position changes we calculate the objects new position using its saved position
- if (object && object->permMove())
+ if (object && object->permMove() && !object->isPermanentEnforced() &&
+ ((root_object == NULL) || !root_object->isPermanentEnforced()))
{
LLVector3 center = gAgent.getPosAgentFromGlobal( mRotationCenter );
@@ -704,7 +712,10 @@ void LLManipRotate::drag( S32 x, S32 y )
{
LLSelectNode* selectNode = *iter;
LLViewerObject*cur = selectNode->getObject();
- if( cur->permModify() && cur->permMove() && !cur->isAvatar())
+ LLViewerObject *root_object = (cur == NULL) ? NULL : cur->getRootEdit();
+ if( cur->permModify() && cur->permMove() && !cur->isPermanentEnforced() &&
+ ((root_object == NULL) || !root_object->isPermanentEnforced()) &&
+ !cur->isAvatar())
{
selectNode->mLastRotation = cur->getRotation();
selectNode->mLastPositionLocal = cur->getPosition();
@@ -1365,74 +1376,28 @@ LLQuaternion LLManipRotate::dragConstrained( S32 x, S32 y )
BOOL hit = getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, constraint_axis);
projected_mouse -= snap_plane_center;
- S32 snap_plane = 0;
-
- F32 dot = cam_to_snap_plane * constraint_axis;
- if (llabs(dot) < 0.01f)
- {
- // looking at ring edge on, project onto view plane and check if mouse is past ring
- getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, cam_to_snap_plane);
- projected_mouse -= snap_plane_center;
- dot = projected_mouse * constraint_axis;
- if (projected_mouse * constraint_axis > 0)
- {
- snap_plane = 1;
- }
- projected_mouse -= dot * constraint_axis;
- }
- else if (dot > 0.f)
- {
- // look for mouse position outside and in front of snap circle
- if (hit && projected_mouse.magVec() > SNAP_GUIDE_INNER_RADIUS * mRadiusMeters && projected_mouse * cam_to_snap_plane < 0.f)
- {
- snap_plane = 1;
- }
- }
- else
- {
- // look for mouse position inside or in back of snap circle
- if (projected_mouse.magVec() < SNAP_GUIDE_INNER_RADIUS * mRadiusMeters || projected_mouse * cam_to_snap_plane > 0.f || !hit)
- {
- snap_plane = 1;
- }
- }
-
- if (snap_plane == 0)
- {
- // try other plane
- snap_plane_center = (center - (constraint_axis * mRadiusMeters * 0.5f));
- if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
- {
- cam_to_snap_plane.setVec(1.f, 0.f, 0.f);
- }
- else
- {
- cam_to_snap_plane = snap_plane_center - gAgentCamera.getCameraPositionAgent();
- cam_to_snap_plane.normVec();
- }
-
- hit = getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, constraint_axis);
- projected_mouse -= snap_plane_center;
-
- dot = cam_to_snap_plane * constraint_axis;
+ if (gSavedSettings.getBOOL("SnapEnabled")) {
+ S32 snap_plane = 0;
+
+ F32 dot = cam_to_snap_plane * constraint_axis;
if (llabs(dot) < 0.01f)
{
// looking at ring edge on, project onto view plane and check if mouse is past ring
getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, cam_to_snap_plane);
projected_mouse -= snap_plane_center;
dot = projected_mouse * constraint_axis;
- if (projected_mouse * constraint_axis < 0)
+ if (projected_mouse * constraint_axis > 0)
{
- snap_plane = 2;
+ snap_plane = 1;
}
projected_mouse -= dot * constraint_axis;
}
- else if (dot < 0.f)
+ else if (dot > 0.f)
{
// look for mouse position outside and in front of snap circle
if (hit && projected_mouse.magVec() > SNAP_GUIDE_INNER_RADIUS * mRadiusMeters && projected_mouse * cam_to_snap_plane < 0.f)
{
- snap_plane = 2;
+ snap_plane = 1;
}
}
else
@@ -1440,78 +1405,136 @@ LLQuaternion LLManipRotate::dragConstrained( S32 x, S32 y )
// look for mouse position inside or in back of snap circle
if (projected_mouse.magVec() < SNAP_GUIDE_INNER_RADIUS * mRadiusMeters || projected_mouse * cam_to_snap_plane > 0.f || !hit)
{
- snap_plane = 2;
+ snap_plane = 1;
}
}
- }
-
- if (snap_plane > 0)
- {
- LLVector3 cam_at_axis;
- if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
- {
- cam_at_axis.setVec(1.f, 0.f, 0.f);
- }
- else
- {
- cam_at_axis = snap_plane_center - gAgentCamera.getCameraPositionAgent();
- cam_at_axis.normVec();
- }
-
- // first, project mouse onto screen plane at point tangent to rotation radius.
- getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, cam_at_axis);
- // project that point onto rotation plane
- projected_mouse -= snap_plane_center;
- projected_mouse -= projected_vec(projected_mouse, constraint_axis);
-
- F32 mouse_lateral_dist = llmin(SNAP_GUIDE_INNER_RADIUS * mRadiusMeters, projected_mouse.magVec());
- F32 mouse_depth = SNAP_GUIDE_INNER_RADIUS * mRadiusMeters;
- if (llabs(mouse_lateral_dist) > 0.01f)
- {
- mouse_depth = sqrtf((SNAP_GUIDE_INNER_RADIUS * mRadiusMeters) * (SNAP_GUIDE_INNER_RADIUS * mRadiusMeters) -
- (mouse_lateral_dist * mouse_lateral_dist));
- }
- LLVector3 projected_camera_at = cam_at_axis - projected_vec(cam_at_axis, constraint_axis);
- projected_mouse -= mouse_depth * projected_camera_at;
-
- if (!mInSnapRegime)
+
+ if (snap_plane == 0)
{
- mSmoothRotate = TRUE;
+ // try other plane
+ snap_plane_center = (center - (constraint_axis * mRadiusMeters * 0.5f));
+ if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
+ {
+ cam_to_snap_plane.setVec(1.f, 0.f, 0.f);
+ }
+ else
+ {
+ cam_to_snap_plane = snap_plane_center - gAgentCamera.getCameraPositionAgent();
+ cam_to_snap_plane.normVec();
+ }
+
+ hit = getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, constraint_axis);
+ projected_mouse -= snap_plane_center;
+
+ dot = cam_to_snap_plane * constraint_axis;
+ if (llabs(dot) < 0.01f)
+ {
+ // looking at ring edge on, project onto view plane and check if mouse is past ring
+ getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, cam_to_snap_plane);
+ projected_mouse -= snap_plane_center;
+ dot = projected_mouse * constraint_axis;
+ if (projected_mouse * constraint_axis < 0)
+ {
+ snap_plane = 2;
+ }
+ projected_mouse -= dot * constraint_axis;
+ }
+ else if (dot < 0.f)
+ {
+ // look for mouse position outside and in front of snap circle
+ if (hit && projected_mouse.magVec() > SNAP_GUIDE_INNER_RADIUS * mRadiusMeters && projected_mouse * cam_to_snap_plane < 0.f)
+ {
+ snap_plane = 2;
+ }
+ }
+ else
+ {
+ // look for mouse position inside or in back of snap circle
+ if (projected_mouse.magVec() < SNAP_GUIDE_INNER_RADIUS * mRadiusMeters || projected_mouse * cam_to_snap_plane > 0.f || !hit)
+ {
+ snap_plane = 2;
+ }
+ }
}
- mInSnapRegime = TRUE;
- // 0 to 360 deg
- F32 mouse_angle = fmodf(atan2(projected_mouse * axis1, projected_mouse * axis2) * RAD_TO_DEG + 360.f, 360.f);
- F32 relative_mouse_angle = fmodf(mouse_angle + (SNAP_ANGLE_DETENTE / 2), SNAP_ANGLE_INCREMENT);
- //fmodf(llround(mouse_angle * RAD_TO_DEG, 7.5f) + 360.f, 360.f);
-
- LLVector3 object_axis;
- getObjectAxisClosestToMouse(object_axis);
- object_axis = object_axis * first_object_node->mSavedRotation;
-
- // project onto constraint plane
- object_axis = object_axis - (object_axis * getConstraintAxis()) * getConstraintAxis();
- object_axis.normVec();
-
- if (relative_mouse_angle < SNAP_ANGLE_DETENTE)
+ if (snap_plane > 0)
{
- F32 quantized_mouse_angle = mouse_angle - (relative_mouse_angle - (SNAP_ANGLE_DETENTE * 0.5f));
- angle = (quantized_mouse_angle * DEG_TO_RAD) - atan2(object_axis * axis1, object_axis * axis2);
+ LLVector3 cam_at_axis;
+ if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
+ {
+ cam_at_axis.setVec(1.f, 0.f, 0.f);
+ }
+ else
+ {
+ cam_at_axis = snap_plane_center - gAgentCamera.getCameraPositionAgent();
+ cam_at_axis.normVec();
+ }
+
+ // first, project mouse onto screen plane at point tangent to rotation radius.
+ getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, cam_at_axis);
+ // project that point onto rotation plane
+ projected_mouse -= snap_plane_center;
+ projected_mouse -= projected_vec(projected_mouse, constraint_axis);
+
+ F32 mouse_lateral_dist = llmin(SNAP_GUIDE_INNER_RADIUS * mRadiusMeters, projected_mouse.magVec());
+ F32 mouse_depth = SNAP_GUIDE_INNER_RADIUS * mRadiusMeters;
+ if (llabs(mouse_lateral_dist) > 0.01f)
+ {
+ mouse_depth = sqrtf((SNAP_GUIDE_INNER_RADIUS * mRadiusMeters) * (SNAP_GUIDE_INNER_RADIUS * mRadiusMeters) -
+ (mouse_lateral_dist * mouse_lateral_dist));
+ }
+ LLVector3 projected_camera_at = cam_at_axis - projected_vec(cam_at_axis, constraint_axis);
+ projected_mouse -= mouse_depth * projected_camera_at;
+
+ if (!mInSnapRegime)
+ {
+ mSmoothRotate = TRUE;
+ }
+ mInSnapRegime = TRUE;
+ // 0 to 360 deg
+ F32 mouse_angle = fmodf(atan2(projected_mouse * axis1, projected_mouse * axis2) * RAD_TO_DEG + 360.f, 360.f);
+
+ F32 relative_mouse_angle = fmodf(mouse_angle + (SNAP_ANGLE_DETENTE / 2), SNAP_ANGLE_INCREMENT);
+ //fmodf(llround(mouse_angle * RAD_TO_DEG, 7.5f) + 360.f, 360.f);
+
+ LLVector3 object_axis;
+ getObjectAxisClosestToMouse(object_axis);
+ object_axis = object_axis * first_object_node->mSavedRotation;
+
+ // project onto constraint plane
+ object_axis = object_axis - (object_axis * getConstraintAxis()) * getConstraintAxis();
+ object_axis.normVec();
+
+ if (relative_mouse_angle < SNAP_ANGLE_DETENTE)
+ {
+ F32 quantized_mouse_angle = mouse_angle - (relative_mouse_angle - (SNAP_ANGLE_DETENTE * 0.5f));
+ angle = (quantized_mouse_angle * DEG_TO_RAD) - atan2(object_axis * axis1, object_axis * axis2);
+ }
+ else
+ {
+ angle = (mouse_angle * DEG_TO_RAD) - atan2(object_axis * axis1, object_axis * axis2);
+ }
+ return LLQuaternion( -angle, constraint_axis );
}
else
{
- angle = (mouse_angle * DEG_TO_RAD) - atan2(object_axis * axis1, object_axis * axis2);
+ if (mInSnapRegime)
+ {
+ mSmoothRotate = TRUE;
+ }
+ mInSnapRegime = FALSE;
}
- return LLQuaternion( -angle, constraint_axis );
}
- else
- {
+ else {
if (mInSnapRegime)
{
mSmoothRotate = TRUE;
}
mInSnapRegime = FALSE;
-
+ }
+
+ if (!mInSnapRegime)
+ {
LLVector3 up_from_axis = mCenterToCamNorm % constraint_axis;
up_from_axis.normVec();
LLVector3 cur_intersection;
@@ -1678,7 +1701,6 @@ void LLManipRotate::highlightManipulators( S32 x, S32 y )
return;
}
- LLQuaternion object_rot = first_object->getRenderRotation();
LLVector3 rotation_center = gAgent.getPosAgentFromGlobal(mRotationCenter);
LLVector3 mouse_dir_x;
LLVector3 mouse_dir_y;
@@ -1871,7 +1893,10 @@ BOOL LLManipRotate::canAffectSelection()
{
virtual bool apply(LLViewerObject* objectp)
{
- return objectp->permMove() && (objectp->permModify() || !gSavedSettings.getBOOL("EditLinkedParts"));
+ LLViewerObject *root_object = (objectp == NULL) ? NULL : objectp->getRootEdit();
+ return objectp->permMove() && !objectp->isPermanentEnforced() &&
+ ((root_object == NULL) || !root_object->isPermanentEnforced()) &&
+ (objectp->permModify() || !gSavedSettings.getBOOL("EditLinkedParts"));
}
} func;
can_rotate = mObjectSelection->applyToObjects(&func);
diff --git a/indra/newview/llmaniprotate.h b/indra/newview/llmaniprotate.h
index e8f1c24c58..e8f1c24c58 100644..100755
--- a/indra/newview/llmaniprotate.h
+++ b/indra/newview/llmaniprotate.h
diff --git a/indra/newview/llmanipscale.cpp b/indra/newview/llmanipscale.cpp
index f6df4cdfbf..ae0884ac5d 100644..100755
--- a/indra/newview/llmanipscale.cpp
+++ b/indra/newview/llmanipscale.cpp
@@ -826,7 +826,10 @@ void LLManipScale::drag( S32 x, S32 y )
{
LLSelectNode* selectNode = *iter;
LLViewerObject*cur = selectNode->getObject();
- if( cur->permModify() && cur->permMove() && !cur->isAvatar())
+ LLViewerObject *root_object = (cur == NULL) ? NULL : cur->getRootEdit();
+ if( cur->permModify() && cur->permMove() && !cur->isPermanentEnforced() &&
+ ((root_object == NULL) || !root_object->isPermanentEnforced()) &&
+ !cur->isAvatar())
{
selectNode->mLastScale = cur->getScale();
selectNode->mLastPositionLocal = cur->getPosition();
@@ -973,7 +976,10 @@ void LLManipScale::dragCorner( S32 x, S32 y )
{
LLSelectNode* selectNode = *iter;
LLViewerObject* cur = selectNode->getObject();
- if( cur->permModify() && cur->permMove() && !cur->isAvatar() )
+ LLViewerObject *root_object = (cur == NULL) ? NULL : cur->getRootEdit();
+ if( cur->permModify() && cur->permMove() && !cur->isPermanentEnforced() &&
+ ((root_object == NULL) || !root_object->isPermanentEnforced()) &&
+ !cur->isAvatar() )
{
const LLVector3& scale = selectNode->mSavedScale;
@@ -995,7 +1001,10 @@ void LLManipScale::dragCorner( S32 x, S32 y )
{
LLSelectNode* selectNode = *iter;
LLViewerObject* cur = selectNode->getObject();
- if( cur->permModify() && cur->permMove() && !cur->isAvatar() && cur->isRootEdit() )
+ LLViewerObject *root_object = (cur == NULL) ? NULL : cur->getRootEdit();
+ if( cur->permModify() && cur->permMove() && !cur->isPermanentEnforced() &&
+ ((root_object == NULL) || !root_object->isPermanentEnforced()) &&
+ !cur->isAvatar() && cur->isRootEdit() )
{
const LLVector3& scale = selectNode->mSavedScale;
cur->setScale( scale_factor * scale );
@@ -1043,7 +1052,10 @@ void LLManipScale::dragCorner( S32 x, S32 y )
{
LLSelectNode* selectNode = *iter;
LLViewerObject*cur = selectNode->getObject();
- if( cur->permModify() && cur->permMove() && !cur->isAvatar() && !cur->isRootEdit() )
+ LLViewerObject *root_object = (cur == NULL) ? NULL : cur->getRootEdit();
+ if( cur->permModify() && cur->permMove() && !cur->isPermanentEnforced() &&
+ ((root_object == NULL) || !root_object->isPermanentEnforced()) &&
+ !cur->isAvatar() && !cur->isRootEdit() )
{
const LLVector3& scale = selectNode->mSavedScale;
cur->setScale( scale_factor * scale, FALSE );
@@ -1179,9 +1191,6 @@ void LLManipScale::dragFace( S32 x, S32 y )
mInSnapRegime = FALSE;
}
- BOOL send_scale_update = FALSE;
- BOOL send_position_update = FALSE;
-
LLVector3 dir_agent;
if( part_dir_local.mV[VX] )
{
@@ -1198,8 +1207,6 @@ void LLManipScale::dragFace( S32 x, S32 y )
stretchFace(
projected_vec(drag_start_dir_f, dir_agent) + drag_start_center_agent,
projected_vec(drag_delta, dir_agent));
- send_position_update = TRUE;
- send_scale_update = TRUE;
mDragPointGlobal = drag_point_global;
}
@@ -1251,7 +1258,10 @@ void LLManipScale::stretchFace( const LLVector3& drag_start_agent, const LLVecto
{
LLSelectNode* selectNode = *iter;
LLViewerObject*cur = selectNode->getObject();
- if( cur->permModify() && cur->permMove() && !cur->isAvatar() )
+ LLViewerObject *root_object = (cur == NULL) ? NULL : cur->getRootEdit();
+ if( cur->permModify() && cur->permMove() && !cur->isPermanentEnforced() &&
+ ((root_object == NULL) || !root_object->isPermanentEnforced()) &&
+ !cur->isAvatar() )
{
LLBBox cur_bbox = cur->getBoundingBoxAgent();
LLVector3 start_local = cur_bbox.agentToLocal( drag_start_agent );
@@ -2057,7 +2067,10 @@ BOOL LLManipScale::canAffectSelection()
{
virtual bool apply(LLViewerObject* objectp)
{
- return objectp->permModify() && objectp->permMove() && !objectp->isSeat();
+ LLViewerObject *root_object = (objectp == NULL) ? NULL : objectp->getRootEdit();
+ return objectp->permModify() && objectp->permMove() && !objectp->isPermanentEnforced() &&
+ ((root_object == NULL) || !root_object->isPermanentEnforced()) &&
+ !objectp->isSeat();
}
} func;
can_scale = mObjectSelection->applyToObjects(&func);
diff --git a/indra/newview/llmanipscale.h b/indra/newview/llmanipscale.h
index 5cb8898fd0..5cb8898fd0 100644..100755
--- a/indra/newview/llmanipscale.h
+++ b/indra/newview/llmanipscale.h
diff --git a/indra/newview/llmaniptranslate.cpp b/indra/newview/llmaniptranslate.cpp
index 3a88fbd96d..06bf294417 100644..100755
--- a/indra/newview/llmaniptranslate.cpp
+++ b/indra/newview/llmaniptranslate.cpp
@@ -60,6 +60,7 @@
#include "llworld.h"
#include "llui.h"
#include "pipeline.h"
+#include "llviewershadermgr.h"
const S32 NUM_AXES = 3;
const S32 MOUSE_DRAG_SLOP = 2; // pixels
@@ -484,7 +485,6 @@ BOOL LLManipTranslate::handleHover(S32 x, S32 y, MASK mask)
}
// Throttle updates to 10 per second.
- BOOL send_update = FALSE;
LLVector3 axis_f;
LLVector3d axis_d;
@@ -687,7 +687,9 @@ BOOL LLManipTranslate::handleHover(S32 x, S32 y, MASK mask)
}
}
- if (object->permMove())
+ LLViewerObject* root_object = (object == NULL) ? NULL : object->getRootEdit();
+ if (object->permMove() && !object->isPermanentEnforced() &&
+ ((root_object == NULL) || !root_object->isPermanentEnforced()))
{
// handle attachments in local space
if (object->isAttachment() && object->mDrawable.notNull())
@@ -699,11 +701,6 @@ BOOL LLManipTranslate::handleHover(S32 x, S32 y, MASK mask)
LLVector3 old_position_local = object->getPosition();
LLVector3 new_position_local = selectNode->mSavedPositionLocal + (clamped_relative_move_f * objWorldRotation);
- // move and clamp root object first, before adjusting children
- if (new_position_local != old_position_local)
- {
- send_update = TRUE;
- }
//RN: I forget, but we need to do this because of snapping which doesn't often result
// in position changes even when the mouse moves
object->setPosition(new_position_local);
@@ -713,8 +710,6 @@ BOOL LLManipTranslate::handleHover(S32 x, S32 y, MASK mask)
if (selectNode->mIndividualSelection)
{
- send_update = FALSE;
-
// counter-translate child objects if we are moving the root as an individual
object->resetChildrenPosition(old_position_local - new_position_local, TRUE) ;
}
@@ -750,7 +745,6 @@ BOOL LLManipTranslate::handleHover(S32 x, S32 y, MASK mask)
}
// PR: Only update if changed
- LLVector3d old_position_global = object->getPositionGlobal();
LLVector3 old_position_agent = object->getPositionAgent();
LLVector3 new_position_agent = gAgent.getPosAgentFromGlobal(new_position_global);
if (object->isRootEdit())
@@ -772,11 +766,6 @@ BOOL LLManipTranslate::handleHover(S32 x, S32 y, MASK mask)
{
// counter-translate child objects if we are moving the root as an individual
object->resetChildrenPosition(old_position_agent - new_position_agent, TRUE) ;
- send_update = FALSE;
- }
- else if (old_position_global != new_position_global)
- {
- send_update = TRUE;
}
}
selectNode->mLastPositionLocal = object->getPosition();
@@ -1307,7 +1296,6 @@ void LLManipTranslate::renderSnapGuides()
// add in off-axis offset
tick_start += (mSnapOffsetAxis * mSnapOffsetMeters);
- BOOL is_sub_tick = FALSE;
F32 tick_scale = 1.f;
for (F32 division_level = max_subdivisions; division_level >= sGridMinSubdivisionLevel; division_level /= 2.f)
{
@@ -1316,7 +1304,6 @@ void LLManipTranslate::renderSnapGuides()
break;
}
tick_scale *= 0.7f;
- is_sub_tick = TRUE;
}
// S32 num_ticks_to_fade = is_sub_tick ? num_ticks_per_side / 2 : num_ticks_per_side;
@@ -1539,7 +1526,6 @@ void LLManipTranslate::renderSnapGuides()
float a = line_alpha;
- LLColor4 col = LLUIColorTable::instance().getColor("SilhouetteChildColor");
{
//draw grid behind objects
LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
@@ -1580,7 +1566,11 @@ void LLManipTranslate::renderSnapGuides()
LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE, GL_GREATER);
LLGLEnable stipple(GL_LINE_STIPPLE);
gGL.flush();
- glLineStipple(1, 0x3333);
+
+ if (!LLGLSLShader::sNoFixedFunction)
+ {
+ glLineStipple(1, 0x3333);
+ }
switch (mManipPart)
{
@@ -1645,17 +1635,28 @@ void LLManipTranslate::highlightIntersection(LLVector3 normal,
LLQuaternion grid_rotation,
LLColor4 inner_color)
{
- if (!gSavedSettings.getBOOL("GridCrossSections"))
+ if (!gSavedSettings.getBOOL("GridCrossSections") || !LLGLSLShader::sNoFixedFunction)
{
return;
}
+
+ LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
+
+
U32 types[] = { LLRenderPass::PASS_SIMPLE, LLRenderPass::PASS_ALPHA, LLRenderPass::PASS_FULLBRIGHT, LLRenderPass::PASS_SHINY };
U32 num_types = LL_ARRAY_SIZE(types);
GLuint stencil_mask = 0xFFFFFFFF;
//stencil in volumes
+
gGL.flush();
+
+ if (shader)
+ {
+ gClipProgram.bind();
+ }
+
{
glStencilMask(stencil_mask);
glClearStencil(1);
@@ -1666,6 +1667,7 @@ void LLManipTranslate::highlightIntersection(LLVector3 normal,
glStencilFunc(GL_ALWAYS, 0, stencil_mask);
gGL.setColorMask(false, false);
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
gGL.diffuseColor4f(1,1,1,1);
//setup clip plane
@@ -1675,10 +1677,13 @@ void LLManipTranslate::highlightIntersection(LLVector3 normal,
normal = -normal;
}
F32 d = -(selection_center * normal);
- F64 plane[] = { normal.mV[0], normal.mV[1], normal.mV[2], d };
- LLGLEnable clip(GL_CLIP_PLANE0);
- glClipPlane(GL_CLIP_PLANE0, plane);
+ glh::vec4f plane(normal.mV[0], normal.mV[1], normal.mV[2], d );
+
+ gGL.getModelviewMatrix().inverse().mult_vec_matrix(plane);
+ static LLStaticHashedString sClipPlane("clip_plane");
+ gClipProgram.uniform4fv(sClipPlane, 1, plane.v);
+
BOOL particles = gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_PARTICLES);
BOOL clouds = gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_CLOUDS);
@@ -1729,6 +1734,16 @@ void LLManipTranslate::highlightIntersection(LLVector3 normal,
F32 sz = mGridSizeMeters;
F32 tiles = sz;
+ if (shader)
+ {
+ shader->bind();
+ }
+
+ if (shader)
+ {
+ shader->bind();
+ }
+
//draw volume/plane intersections
{
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
@@ -2281,7 +2296,10 @@ BOOL LLManipTranslate::canAffectSelection()
{
virtual bool apply(LLViewerObject* objectp)
{
- return objectp->permMove() && (objectp->permModify() || !gSavedSettings.getBOOL("EditLinkedParts"));
+ LLViewerObject *root_object = (objectp == NULL) ? NULL : objectp->getRootEdit();
+ return objectp->permMove() && !objectp->isPermanentEnforced() &&
+ ((root_object == NULL) || !root_object->isPermanentEnforced()) &&
+ (objectp->permModify() || !gSavedSettings.getBOOL("EditLinkedParts"));
}
} func;
can_move = mObjectSelection->applyToObjects(&func);
diff --git a/indra/newview/llmaniptranslate.h b/indra/newview/llmaniptranslate.h
index 37567c7bd1..37567c7bd1 100644..100755
--- a/indra/newview/llmaniptranslate.h
+++ b/indra/newview/llmaniptranslate.h
diff --git a/indra/newview/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp
index 93dd82957f..0b009b68f7 100644..100755
--- a/indra/newview/llmarketplacefunctions.cpp
+++ b/indra/newview/llmarketplacefunctions.cpp
@@ -47,16 +47,16 @@ static std::string getMarketplaceDomain()
if (!LLGridManager::getInstance()->isInProductionGrid())
{
- const std::string& grid_label = LLGridManager::getInstance()->getGridLabel();
- const std::string& grid_label_lower = utf8str_tolower(grid_label);
+ const std::string& grid_id = LLGridManager::getInstance()->getGridId();
+ const std::string& grid_id_lower = utf8str_tolower(grid_id);
- if (grid_label_lower == "damballah")
+ if (grid_id_lower == "damballah")
{
domain = "secondlife-staging.com";
}
else
{
- domain = llformat("%s.lindenlab.com", grid_label_lower.c_str());
+ domain = llformat("%s.lindenlab.com", grid_id_lower.c_str());
}
}
@@ -336,13 +336,19 @@ namespace LLMarketplaceImport
// Interface class
//
+static const F32 MARKET_IMPORTER_UPDATE_FREQUENCY = 1.0f;
//static
void LLMarketplaceInventoryImporter::update()
{
if (instanceExists())
{
- LLMarketplaceInventoryImporter::instance().updateImport();
+ static LLTimer update_timer;
+ if (update_timer.hasExpired())
+ {
+ LLMarketplaceInventoryImporter::instance().updateImport();
+ update_timer.setTimerExpirySec(MARKET_IMPORTER_UPDATE_FREQUENCY);
+ }
}
}
diff --git a/indra/newview/llmarketplacefunctions.h b/indra/newview/llmarketplacefunctions.h
index 4b8f7a1ac7..4b8f7a1ac7 100644..100755
--- a/indra/newview/llmarketplacefunctions.h
+++ b/indra/newview/llmarketplacefunctions.h
diff --git a/indra/newview/llmarketplacenotifications.cpp b/indra/newview/llmarketplacenotifications.cpp
index 0886f9a990..0886f9a990 100644..100755
--- a/indra/newview/llmarketplacenotifications.cpp
+++ b/indra/newview/llmarketplacenotifications.cpp
diff --git a/indra/newview/llmarketplacenotifications.h b/indra/newview/llmarketplacenotifications.h
index 83a4e163c7..83a4e163c7 100644..100755
--- a/indra/newview/llmarketplacenotifications.h
+++ b/indra/newview/llmarketplacenotifications.h
diff --git a/indra/newview/llmaterialmgr.cpp b/indra/newview/llmaterialmgr.cpp
new file mode 100644
index 0000000000..14d3d4e7a8
--- /dev/null
+++ b/indra/newview/llmaterialmgr.cpp
@@ -0,0 +1,789 @@
+/**
+ * @file llmaterialmgr.cpp
+ * @brief Material manager
+ *
+ * $LicenseInfo:firstyear=2013&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2013, 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 "llsdserialize.h"
+#include "llsdutil.h"
+
+#include "llagent.h"
+#include "llcallbacklist.h"
+#include "llmaterialmgr.h"
+#include "llviewerobject.h"
+#include "llviewerobjectlist.h"
+#include "llviewerregion.h"
+#include "llworld.h"
+
+/**
+ * Materials cap parameters
+ */
+
+#define MATERIALS_CAPABILITY_NAME "RenderMaterials"
+
+#define MATERIALS_CAP_ZIP_FIELD "Zipped"
+
+#define MATERIALS_CAP_FULL_PER_FACE_FIELD "FullMaterialsPerFace"
+#define MATERIALS_CAP_FACE_FIELD "Face"
+#define MATERIALS_CAP_MATERIAL_FIELD "Material"
+#define MATERIALS_CAP_OBJECT_ID_FIELD "ID"
+#define MATERIALS_CAP_MATERIAL_ID_FIELD "MaterialID"
+#define SIM_FEATURE_MAX_MATERIALS_PER_TRANSACTION "MaxMaterialsPerTransaction"
+
+#define MATERIALS_GET_MAX_ENTRIES 50
+#define MATERIALS_GET_TIMEOUT (60.f * 20)
+#define MATERIALS_POST_MAX_ENTRIES 50
+#define MATERIALS_POST_TIMEOUT (60.f * 5)
+#define MATERIALS_PUT_THROTTLE_SECS 1.f
+#define MATERIALS_PUT_MAX_ENTRIES 50
+
+/**
+ * LLMaterialsResponder helper class
+ */
+
+class LLMaterialsResponder : public LLHTTPClient::Responder
+{
+public:
+ typedef boost::function<void (bool, const LLSD&)> CallbackFunction;
+
+ LLMaterialsResponder(const std::string& pMethod, const std::string& pCapabilityURL, CallbackFunction pCallback);
+ virtual ~LLMaterialsResponder();
+
+ virtual void result(const LLSD& pContent);
+ virtual void error(U32 pStatus, const std::string& pReason);
+
+private:
+ std::string mMethod;
+ std::string mCapabilityURL;
+ CallbackFunction mCallback;
+};
+
+LLMaterialsResponder::LLMaterialsResponder(const std::string& pMethod, const std::string& pCapabilityURL, CallbackFunction pCallback)
+ : LLHTTPClient::Responder()
+ , mMethod(pMethod)
+ , mCapabilityURL(pCapabilityURL)
+ , mCallback(pCallback)
+{
+}
+
+LLMaterialsResponder::~LLMaterialsResponder()
+{
+}
+
+void LLMaterialsResponder::result(const LLSD& pContent)
+{
+ LL_DEBUGS("Materials") << LL_ENDL;
+ mCallback(true, pContent);
+}
+
+void LLMaterialsResponder::error(U32 pStatus, const std::string& pReason)
+{
+ LL_WARNS("Materials")
+ << "\n--------------------------------------------------------------------------\n"
+ << mMethod << " Error[" << pStatus << "] cannot access cap '" << MATERIALS_CAPABILITY_NAME
+ << "'\n with url '" << mCapabilityURL << "' because " << pReason
+ << "\n--------------------------------------------------------------------------"
+ << LL_ENDL;
+
+ LLSD emptyResult;
+ mCallback(false, emptyResult);
+}
+
+/**
+ * LLMaterialMgr class
+ */
+
+LLMaterialMgr::LLMaterialMgr()
+{
+ mMaterials.insert(std::pair<LLMaterialID, LLMaterialPtr>(LLMaterialID::null, LLMaterialPtr(NULL)));
+ gIdleCallbacks.addFunction(&LLMaterialMgr::onIdle, NULL);
+ LLWorld::instance().setRegionRemovedCallback(boost::bind(&LLMaterialMgr::onRegionRemoved, this, _1));
+}
+
+LLMaterialMgr::~LLMaterialMgr()
+{
+ gIdleCallbacks.deleteFunction(&LLMaterialMgr::onIdle, NULL);
+}
+
+bool LLMaterialMgr::isGetPending(const LLUUID& region_id, const LLMaterialID& material_id) const
+{
+ get_pending_map_t::const_iterator itPending = mGetPending.find(pending_material_t(region_id, material_id));
+ return (mGetPending.end() != itPending) && (LLFrameTimer::getTotalSeconds() < itPending->second + MATERIALS_POST_TIMEOUT);
+}
+
+void LLMaterialMgr::markGetPending(const LLUUID& region_id, const LLMaterialID& material_id)
+{
+ get_pending_map_t::iterator itPending = mGetPending.find(pending_material_t(region_id, material_id));
+ if (mGetPending.end() == itPending)
+ {
+ mGetPending.insert(std::pair<pending_material_t, F64>(pending_material_t(region_id, material_id), LLFrameTimer::getTotalSeconds()));
+ }
+ else
+ {
+ itPending->second = LLFrameTimer::getTotalSeconds();
+ }
+}
+
+const LLMaterialPtr LLMaterialMgr::get(const LLUUID& region_id, const LLMaterialID& material_id)
+{
+ LL_DEBUGS("Materials") << "region " << region_id << " material id " << material_id << LL_ENDL;
+ LLMaterialPtr material;
+ material_map_t::const_iterator itMaterial = mMaterials.find(material_id);
+ if (mMaterials.end() != itMaterial)
+ {
+ material = itMaterial->second;
+ LL_DEBUGS("Materials") << " found material " << LL_ENDL;
+ }
+ else
+ {
+ if (!isGetPending(region_id, material_id))
+ {
+ LL_DEBUGS("Materials") << " material pending " << material_id << LL_ENDL;
+ get_queue_t::iterator itQueue = mGetQueue.find(region_id);
+ if (mGetQueue.end() == itQueue)
+ {
+ LL_DEBUGS("Materials") << "mGetQueue add region " << region_id << " pending " << material_id << LL_ENDL;
+ std::pair<get_queue_t::iterator, bool> ret = mGetQueue.insert(std::pair<LLUUID, material_queue_t>(region_id, material_queue_t()));
+ itQueue = ret.first;
+ }
+ itQueue->second.insert(material_id);
+ markGetPending(region_id, material_id);
+ }
+ LL_DEBUGS("Materials") << " returning empty material " << LL_ENDL;
+ material = LLMaterialPtr();
+ }
+ return material;
+}
+
+boost::signals2::connection LLMaterialMgr::get(const LLUUID& region_id, const LLMaterialID& material_id, LLMaterialMgr::get_callback_t::slot_type cb)
+{
+ boost::signals2::connection connection;
+
+ material_map_t::const_iterator itMaterial = mMaterials.find(material_id);
+ if (itMaterial != mMaterials.end())
+ {
+ LL_DEBUGS("Materials") << "region " << region_id << " found materialid " << material_id << LL_ENDL;
+ get_callback_t signal;
+ signal.connect(cb);
+ signal(material_id, itMaterial->second);
+ connection = boost::signals2::connection();
+ }
+ else
+ {
+ if (!isGetPending(region_id, material_id))
+ {
+ get_queue_t::iterator itQueue = mGetQueue.find(region_id);
+ if (mGetQueue.end() == itQueue)
+ {
+ LL_DEBUGS("Materials") << "mGetQueue inserting region "<<region_id << LL_ENDL;
+ std::pair<get_queue_t::iterator, bool> ret = mGetQueue.insert(std::pair<LLUUID, material_queue_t>(region_id, material_queue_t()));
+ itQueue = ret.first;
+ }
+ LL_DEBUGS("Materials") << "adding material id " << material_id << LL_ENDL;
+ itQueue->second.insert(material_id);
+ markGetPending(region_id, material_id);
+ }
+
+ get_callback_map_t::iterator itCallback = mGetCallbacks.find(material_id);
+ if (itCallback == mGetCallbacks.end())
+ {
+ std::pair<get_callback_map_t::iterator, bool> ret = mGetCallbacks.insert(std::pair<LLMaterialID, get_callback_t*>(material_id, new get_callback_t()));
+ itCallback = ret.first;
+ }
+ connection = itCallback->second->connect(cb);;
+ }
+
+ return connection;
+}
+
+boost::signals2::connection LLMaterialMgr::getTE(const LLUUID& region_id, const LLMaterialID& material_id, U32 te, LLMaterialMgr::get_callback_te_t::slot_type cb)
+{
+ boost::signals2::connection connection;
+
+ material_map_t::const_iterator itMaterial = mMaterials.find(material_id);
+ if (itMaterial != mMaterials.end())
+ {
+ LL_DEBUGS("Materials") << "region " << region_id << " found materialid " << material_id << LL_ENDL;
+ get_callback_te_t signal;
+ signal.connect(cb);
+ signal(material_id, itMaterial->second, te);
+ connection = boost::signals2::connection();
+ }
+ else
+ {
+ if (!isGetPending(region_id, material_id))
+ {
+ get_queue_t::iterator itQueue = mGetQueue.find(region_id);
+ if (mGetQueue.end() == itQueue)
+ {
+ LL_DEBUGS("Materials") << "mGetQueue inserting region "<<region_id << LL_ENDL;
+ std::pair<get_queue_t::iterator, bool> ret = mGetQueue.insert(std::pair<LLUUID, material_queue_t>(region_id, material_queue_t()));
+ itQueue = ret.first;
+ }
+ LL_DEBUGS("Materials") << "adding material id " << material_id << LL_ENDL;
+ itQueue->second.insert(material_id);
+ markGetPending(region_id, material_id);
+ }
+
+ TEMaterialPair te_mat_pair;
+ te_mat_pair.te = te;
+ te_mat_pair.materialID = material_id;
+
+ get_callback_te_map_t::iterator itCallback = mGetTECallbacks.find(te_mat_pair);
+ if (itCallback == mGetTECallbacks.end())
+ {
+ std::pair<get_callback_te_map_t::iterator, bool> ret = mGetTECallbacks.insert(std::pair<TEMaterialPair, get_callback_te_t*>(te_mat_pair, new get_callback_te_t()));
+ itCallback = ret.first;
+ }
+ connection = itCallback->second->connect(cb);
+ }
+
+ return connection;
+}
+
+bool LLMaterialMgr::isGetAllPending(const LLUUID& region_id) const
+{
+ getall_pending_map_t::const_iterator itPending = mGetAllPending.find(region_id);
+ return (mGetAllPending.end() != itPending) && (LLFrameTimer::getTotalSeconds() < itPending->second + MATERIALS_GET_TIMEOUT);
+}
+
+void LLMaterialMgr::getAll(const LLUUID& region_id)
+{
+ if (!isGetAllPending(region_id))
+ {
+ LL_DEBUGS("Materials") << "queuing for region " << region_id << LL_ENDL;
+ mGetAllQueue.insert(region_id);
+ }
+ else
+ {
+ LL_DEBUGS("Materials") << "already pending for region " << region_id << LL_ENDL;
+ }
+}
+
+boost::signals2::connection LLMaterialMgr::getAll(const LLUUID& region_id, LLMaterialMgr::getall_callback_t::slot_type cb)
+{
+ if (!isGetAllPending(region_id))
+ {
+ mGetAllQueue.insert(region_id);
+ }
+
+ getall_callback_map_t::iterator itCallback = mGetAllCallbacks.find(region_id);
+ if (mGetAllCallbacks.end() == itCallback)
+ {
+ std::pair<getall_callback_map_t::iterator, bool> ret = mGetAllCallbacks.insert(std::pair<LLUUID, getall_callback_t*>(region_id, new getall_callback_t()));
+ itCallback = ret.first;
+ }
+ return itCallback->second->connect(cb);;
+}
+
+void LLMaterialMgr::put(const LLUUID& object_id, const U8 te, const LLMaterial& material)
+{
+ put_queue_t::iterator itQueue = mPutQueue.find(object_id);
+ if (mPutQueue.end() == itQueue)
+ {
+ LL_DEBUGS("Materials") << "mPutQueue insert object " << object_id << LL_ENDL;
+ mPutQueue.insert(std::pair<LLUUID, facematerial_map_t>(object_id, facematerial_map_t()));
+ itQueue = mPutQueue.find(object_id);
+ }
+
+ facematerial_map_t::iterator itFace = itQueue->second.find(te);
+ if (itQueue->second.end() == itFace)
+ {
+ itQueue->second.insert(std::pair<U8, LLMaterial>(te, material));
+ }
+ else
+ {
+ itFace->second = material;
+ }
+}
+
+void LLMaterialMgr::remove(const LLUUID& object_id, const U8 te)
+{
+ put(object_id, te, LLMaterial::null);
+}
+
+const LLMaterialPtr LLMaterialMgr::setMaterial(const LLUUID& region_id, const LLMaterialID& material_id, const LLSD& material_data)
+{
+ LL_DEBUGS("Materials") << "region " << region_id << " material id " << material_id << LL_ENDL;
+ material_map_t::const_iterator itMaterial = mMaterials.find(material_id);
+ if (mMaterials.end() == itMaterial)
+ {
+ LL_DEBUGS("Materials") << "new material" << LL_ENDL;
+ LLMaterialPtr newMaterial(new LLMaterial(material_data));
+ std::pair<material_map_t::const_iterator, bool> ret = mMaterials.insert(std::pair<LLMaterialID, LLMaterialPtr>(material_id, newMaterial));
+ itMaterial = ret.first;
+ }
+
+ TEMaterialPair te_mat_pair;
+ te_mat_pair.materialID = material_id;
+
+ U32 i = 0;
+ while (i < LLTEContents::MAX_TES)
+ {
+ te_mat_pair.te = i++;
+ get_callback_te_map_t::iterator itCallbackTE = mGetTECallbacks.find(te_mat_pair);
+ if (itCallbackTE != mGetTECallbacks.end())
+ {
+ (*itCallbackTE->second)(material_id, itMaterial->second, te_mat_pair.te);
+ delete itCallbackTE->second;
+ mGetTECallbacks.erase(itCallbackTE);
+ }
+ }
+
+ get_callback_map_t::iterator itCallback = mGetCallbacks.find(material_id);
+ if (itCallback != mGetCallbacks.end())
+ {
+ (*itCallback->second)(material_id, itMaterial->second);
+
+ delete itCallback->second;
+ mGetCallbacks.erase(itCallback);
+ }
+
+ mGetPending.erase(pending_material_t(region_id, material_id));
+
+ return itMaterial->second;
+}
+
+void LLMaterialMgr::onGetResponse(bool success, const LLSD& content, const LLUUID& region_id)
+{
+ if (!success)
+ {
+ // *TODO: is there any kind of error handling we can do here?
+ LL_WARNS("Materials")<< "failed"<<LL_ENDL;
+ return;
+ }
+
+ llassert(content.isMap());
+ llassert(content.has(MATERIALS_CAP_ZIP_FIELD));
+ llassert(content[MATERIALS_CAP_ZIP_FIELD].isBinary());
+
+ LLSD::Binary content_binary = content[MATERIALS_CAP_ZIP_FIELD].asBinary();
+ std::string content_string(reinterpret_cast<const char*>(content_binary.data()), content_binary.size());
+ std::istringstream content_stream(content_string);
+
+ LLSD response_data;
+ if (!unzip_llsd(response_data, content_stream, content_binary.size()))
+ {
+ LL_WARNS("Materials") << "Cannot unzip LLSD binary content" << LL_ENDL;
+ return;
+ }
+
+ llassert(response_data.isArray());
+ LL_DEBUGS("Materials") << "response has "<< response_data.size() << " materials" << LL_ENDL;
+ for (LLSD::array_const_iterator itMaterial = response_data.beginArray(); itMaterial != response_data.endArray(); ++itMaterial)
+ {
+ const LLSD& material_data = *itMaterial;
+ llassert(material_data.isMap());
+
+ llassert(material_data.has(MATERIALS_CAP_OBJECT_ID_FIELD));
+ llassert(material_data[MATERIALS_CAP_OBJECT_ID_FIELD].isBinary());
+ LLMaterialID material_id(material_data[MATERIALS_CAP_OBJECT_ID_FIELD].asBinary());
+
+ llassert(material_data.has(MATERIALS_CAP_MATERIAL_FIELD));
+ llassert(material_data[MATERIALS_CAP_MATERIAL_FIELD].isMap());
+
+ setMaterial(region_id, material_id, material_data[MATERIALS_CAP_MATERIAL_FIELD]);
+ }
+}
+
+void LLMaterialMgr::onGetAllResponse(bool success, const LLSD& content, const LLUUID& region_id)
+{
+ if (!success)
+ {
+ // *TODO: is there any kind of error handling we can do here?
+ LL_WARNS("Materials")<< "failed"<<LL_ENDL;
+ return;
+ }
+
+ llassert(content.isMap());
+ llassert(content.has(MATERIALS_CAP_ZIP_FIELD));
+ llassert(content[MATERIALS_CAP_ZIP_FIELD].isBinary());
+
+ LLSD::Binary content_binary = content[MATERIALS_CAP_ZIP_FIELD].asBinary();
+ std::string content_string(reinterpret_cast<const char*>(content_binary.data()), content_binary.size());
+ std::istringstream content_stream(content_string);
+
+ LLSD response_data;
+ if (!unzip_llsd(response_data, content_stream, content_binary.size()))
+ {
+ LL_WARNS("Materials") << "Cannot unzip LLSD binary content" << LL_ENDL;
+ return;
+ }
+
+ get_queue_t::iterator itQueue = mGetQueue.find(region_id);
+ material_map_t materials;
+
+ llassert(response_data.isArray());
+ LL_DEBUGS("Materials") << "response has "<< response_data.size() << " materials" << LL_ENDL;
+ for (LLSD::array_const_iterator itMaterial = response_data.beginArray(); itMaterial != response_data.endArray(); ++itMaterial)
+ {
+ const LLSD& material_data = *itMaterial;
+ llassert(material_data.isMap());
+
+ llassert(material_data.has(MATERIALS_CAP_OBJECT_ID_FIELD));
+ llassert(material_data[MATERIALS_CAP_OBJECT_ID_FIELD].isBinary());
+ LLMaterialID material_id(material_data[MATERIALS_CAP_OBJECT_ID_FIELD].asBinary());
+ if (mGetQueue.end() != itQueue)
+ {
+ itQueue->second.erase(material_id);
+ }
+
+ llassert(material_data.has(MATERIALS_CAP_MATERIAL_FIELD));
+ llassert(material_data[MATERIALS_CAP_MATERIAL_FIELD].isMap());
+ LLMaterialPtr material = setMaterial(region_id, material_id, material_data[MATERIALS_CAP_MATERIAL_FIELD]);
+
+ materials[material_id] = material;
+ }
+
+ getall_callback_map_t::iterator itCallback = mGetAllCallbacks.find(region_id);
+ if (itCallback != mGetAllCallbacks.end())
+ {
+ (*itCallback->second)(region_id, materials);
+
+ delete itCallback->second;
+ mGetAllCallbacks.erase(itCallback);
+ }
+
+ if ( (mGetQueue.end() != itQueue) && (itQueue->second.empty()) )
+ {
+ mGetQueue.erase(itQueue);
+ }
+
+ LL_DEBUGS("Materials")<< "recording that getAll has been done for region id " << region_id << LL_ENDL;
+ mGetAllRequested.insert(region_id); // prevents subsequent getAll requests for this region
+ mGetAllPending.erase(region_id); // Invalidates region_id
+}
+
+void LLMaterialMgr::onPutResponse(bool success, const LLSD& content)
+{
+ if (!success)
+ {
+ // *TODO: is there any kind of error handling we can do here?
+ LL_WARNS("Materials")<< "failed"<<LL_ENDL;
+ return;
+ }
+
+ llassert(content.isMap());
+ llassert(content.has(MATERIALS_CAP_ZIP_FIELD));
+ llassert(content[MATERIALS_CAP_ZIP_FIELD].isBinary());
+
+ LLSD::Binary content_binary = content[MATERIALS_CAP_ZIP_FIELD].asBinary();
+ std::string content_string(reinterpret_cast<const char*>(content_binary.data()), content_binary.size());
+ std::istringstream content_stream(content_string);
+
+ LLSD response_data;
+ if (!unzip_llsd(response_data, content_stream, content_binary.size()))
+ {
+ LL_WARNS("Materials") << "Cannot unzip LLSD binary content" << LL_ENDL;
+ return;
+ }
+ else
+ {
+ llassert(response_data.isArray());
+ LL_DEBUGS("Materials") << "response has "<< response_data.size() << " materials" << LL_ENDL;
+ for (LLSD::array_const_iterator faceIter = response_data.beginArray(); faceIter != response_data.endArray(); ++faceIter)
+ {
+# ifndef LL_RELEASE_FOR_DOWNLOAD
+ const LLSD& face_data = *faceIter; // conditional to avoid unused variable warning
+# endif
+ llassert(face_data.isMap());
+
+ llassert(face_data.has(MATERIALS_CAP_OBJECT_ID_FIELD));
+ llassert(face_data[MATERIALS_CAP_OBJECT_ID_FIELD].isInteger());
+ // U32 local_id = face_data[MATERIALS_CAP_OBJECT_ID_FIELD].asInteger();
+
+ llassert(face_data.has(MATERIALS_CAP_FACE_FIELD));
+ llassert(face_data[MATERIALS_CAP_FACE_FIELD].isInteger());
+ // S32 te = face_data[MATERIALS_CAP_FACE_FIELD].asInteger();
+
+ llassert(face_data.has(MATERIALS_CAP_MATERIAL_ID_FIELD));
+ llassert(face_data[MATERIALS_CAP_MATERIAL_ID_FIELD].isBinary());
+ // LLMaterialID material_id(face_data[MATERIALS_CAP_MATERIAL_ID_FIELD].asBinary());
+
+ // *TODO: do we really still need to process this?
+ }
+ }
+}
+
+static LLFastTimer::DeclareTimer FTM_MATERIALS_IDLE("Materials");
+
+void LLMaterialMgr::onIdle(void*)
+{
+ LLFastTimer t(FTM_MATERIALS_IDLE);
+
+ LLMaterialMgr* instancep = LLMaterialMgr::getInstance();
+
+ if (!instancep->mGetQueue.empty())
+ {
+ instancep->processGetQueue();
+ }
+
+ if (!instancep->mGetAllQueue.empty())
+ {
+ instancep->processGetAllQueue();
+ }
+
+ if (!instancep->mPutQueue.empty())
+ {
+ instancep->processPutQueue();
+ }
+}
+
+void LLMaterialMgr::processGetQueue()
+{
+ get_queue_t::iterator loopRegionQueue = mGetQueue.begin();
+ while (mGetQueue.end() != loopRegionQueue)
+ {
+ get_queue_t::iterator itRegionQueue = loopRegionQueue++;
+
+ const LLUUID& region_id = itRegionQueue->first;
+ if (isGetAllPending(region_id))
+ {
+ continue;
+ }
+
+ LLViewerRegion* regionp = LLWorld::instance().getRegionFromID(region_id);
+ if (!regionp)
+ {
+ LL_WARNS("Materials") << "Unknown region with id " << region_id.asString() << LL_ENDL;
+ mGetQueue.erase(itRegionQueue);
+ continue;
+ }
+ else if (!regionp->capabilitiesReceived() || regionp->materialsCapThrottled())
+ {
+ continue;
+ }
+ else if (mGetAllRequested.end() == mGetAllRequested.find(region_id))
+ {
+ LL_DEBUGS("Materials") << "calling getAll for " << regionp->getName() << LL_ENDL;
+ getAll(region_id);
+ continue;
+ }
+
+ const std::string capURL = regionp->getCapability(MATERIALS_CAPABILITY_NAME);
+ if (capURL.empty())
+ {
+ LL_WARNS("Materials") << "Capability '" << MATERIALS_CAPABILITY_NAME
+ << "' is not defined on region '" << regionp->getName() << "'" << LL_ENDL;
+ mGetQueue.erase(itRegionQueue);
+ continue;
+ }
+
+ LLSD materialsData = LLSD::emptyArray();
+
+ material_queue_t& materials = itRegionQueue->second;
+ U32 max_entries = regionp->getMaxMaterialsPerTransaction();
+ material_queue_t::iterator loopMaterial = materials.begin();
+ while ( (materials.end() != loopMaterial) && (materialsData.size() < max_entries) )
+ {
+ material_queue_t::iterator itMaterial = loopMaterial++;
+ materialsData.append((*itMaterial).asLLSD());
+ materials.erase(itMaterial);
+ markGetPending(region_id, *itMaterial);
+ }
+ if (materials.empty())
+ {
+ mGetQueue.erase(itRegionQueue);
+ }
+
+ std::string materialString = zip_llsd(materialsData);
+
+ S32 materialSize = materialString.size();
+ if (materialSize <= 0)
+ {
+ LL_ERRS("Materials") << "cannot zip LLSD binary content" << LL_ENDL;
+ return;
+ }
+
+ LLSD::Binary materialBinary;
+ materialBinary.resize(materialSize);
+ memcpy(materialBinary.data(), materialString.data(), materialSize);
+
+ LLSD postData = LLSD::emptyMap();
+ postData[MATERIALS_CAP_ZIP_FIELD] = materialBinary;
+
+ LLHTTPClient::ResponderPtr materialsResponder = new LLMaterialsResponder("POST", capURL, boost::bind(&LLMaterialMgr::onGetResponse, this, _1, _2, region_id));
+ LL_DEBUGS("Materials") << "POSTing to region '" << regionp->getName() << "' at '"<< capURL << " for " << materialsData.size() << " materials."
+ << "\ndata: " << ll_pretty_print_sd(materialsData) << LL_ENDL;
+ LLHTTPClient::post(capURL, postData, materialsResponder);
+ regionp->resetMaterialsCapThrottle();
+ }
+}
+
+void LLMaterialMgr::processGetAllQueue()
+{
+ getall_queue_t::iterator loopRegion = mGetAllQueue.begin();
+ while (mGetAllQueue.end() != loopRegion)
+ {
+ getall_queue_t::iterator itRegion = loopRegion++;
+
+ const LLUUID& region_id = *itRegion;
+ LLViewerRegion* regionp = LLWorld::instance().getRegionFromID(region_id);
+ if (regionp == NULL)
+ {
+ LL_WARNS("Materials") << "Unknown region with id " << region_id.asString() << LL_ENDL;
+ clearGetQueues(region_id); // Invalidates region_id
+ continue;
+ }
+ else if (!regionp->capabilitiesReceived() || regionp->materialsCapThrottled())
+ {
+ continue;
+ }
+
+ std::string capURL = regionp->getCapability(MATERIALS_CAPABILITY_NAME);
+ if (capURL.empty())
+ {
+ LL_WARNS("Materials") << "Capability '" << MATERIALS_CAPABILITY_NAME
+ << "' is not defined on the current region '" << regionp->getName() << "'" << LL_ENDL;
+ clearGetQueues(region_id); // Invalidates region_id
+ continue;
+ }
+
+ LL_DEBUGS("Materials") << "GET all for region " << region_id << "url " << capURL << LL_ENDL;
+ LLHTTPClient::ResponderPtr materialsResponder = new LLMaterialsResponder("GET", capURL, boost::bind(&LLMaterialMgr::onGetAllResponse, this, _1, _2, *itRegion));
+ LLHTTPClient::get(capURL, materialsResponder);
+ regionp->resetMaterialsCapThrottle();
+ mGetAllPending.insert(std::pair<LLUUID, F64>(region_id, LLFrameTimer::getTotalSeconds()));
+ mGetAllQueue.erase(itRegion); // Invalidates region_id
+ }
+}
+
+void LLMaterialMgr::processPutQueue()
+{
+ typedef std::map<LLViewerRegion*, LLSD> regionput_request_map;
+ regionput_request_map requests;
+
+ put_queue_t::iterator loopQueue = mPutQueue.begin();
+ while (mPutQueue.end() != loopQueue)
+ {
+ put_queue_t::iterator itQueue = loopQueue++;
+
+ const LLUUID& object_id = itQueue->first;
+ const LLViewerObject* objectp = gObjectList.findObject(object_id);
+ if ( !objectp )
+ {
+ LL_WARNS("Materials") << "Object is NULL" << LL_ENDL;
+ mPutQueue.erase(itQueue);
+ }
+ else
+ {
+ LLViewerRegion* regionp = objectp->getRegion();
+ if ( !regionp )
+ {
+ LL_WARNS("Materials") << "Object region is NULL" << LL_ENDL;
+ mPutQueue.erase(itQueue);
+ }
+ else if ( regionp->capabilitiesReceived() && !regionp->materialsCapThrottled())
+ {
+ LLSD& facesData = requests[regionp];
+
+ facematerial_map_t& face_map = itQueue->second;
+ U32 max_entries = regionp->getMaxMaterialsPerTransaction();
+ facematerial_map_t::iterator itFace = face_map.begin();
+ while ( (face_map.end() != itFace) && (facesData.size() < max_entries) )
+ {
+ LLSD faceData = LLSD::emptyMap();
+ faceData[MATERIALS_CAP_FACE_FIELD] = static_cast<LLSD::Integer>(itFace->first);
+ faceData[MATERIALS_CAP_OBJECT_ID_FIELD] = static_cast<LLSD::Integer>(objectp->getLocalID());
+ if (!itFace->second.isNull())
+ {
+ faceData[MATERIALS_CAP_MATERIAL_FIELD] = itFace->second.asLLSD();
+ }
+ facesData.append(faceData);
+ face_map.erase(itFace++);
+ }
+ if (face_map.empty())
+ {
+ mPutQueue.erase(itQueue);
+ }
+ }
+ }
+ }
+
+ for (regionput_request_map::const_iterator itRequest = requests.begin(); itRequest != requests.end(); ++itRequest)
+ {
+ LLViewerRegion* regionp = itRequest->first;
+ std::string capURL = regionp->getCapability(MATERIALS_CAPABILITY_NAME);
+ if (capURL.empty())
+ {
+ LL_WARNS("Materials") << "Capability '" << MATERIALS_CAPABILITY_NAME
+ << "' is not defined on region '" << regionp->getName() << "'" << LL_ENDL;
+ continue;
+ }
+
+ LLSD materialsData = LLSD::emptyMap();
+ materialsData[MATERIALS_CAP_FULL_PER_FACE_FIELD] = itRequest->second;
+
+ std::string materialString = zip_llsd(materialsData);
+
+ S32 materialSize = materialString.size();
+
+ if (materialSize > 0)
+ {
+ LLSD::Binary materialBinary;
+ materialBinary.resize(materialSize);
+ memcpy(materialBinary.data(), materialString.data(), materialSize);
+
+ LLSD putData = LLSD::emptyMap();
+ putData[MATERIALS_CAP_ZIP_FIELD] = materialBinary;
+
+ LL_DEBUGS("Materials") << "put for " << itRequest->second.size() << " faces to region " << itRequest->first->getName() << LL_ENDL;
+ LLHTTPClient::ResponderPtr materialsResponder = new LLMaterialsResponder("PUT", capURL, boost::bind(&LLMaterialMgr::onPutResponse, this, _1, _2));
+ LLHTTPClient::put(capURL, putData, materialsResponder);
+ regionp->resetMaterialsCapThrottle();
+ }
+ else
+ {
+ LL_ERRS("debugMaterials") << "cannot zip LLSD binary content" << LL_ENDL;
+ }
+ }
+}
+
+void LLMaterialMgr::clearGetQueues(const LLUUID& region_id)
+{
+ mGetQueue.erase(region_id);
+ for (get_pending_map_t::iterator itPending = mGetPending.begin(); itPending != mGetPending.end();)
+ {
+ if (region_id == itPending->first.first)
+ {
+ mGetPending.erase(itPending++);
+ }
+ else
+ {
+ ++itPending;
+ }
+ }
+
+ mGetAllQueue.erase(region_id);
+ mGetAllRequested.erase(region_id);
+ mGetAllPending.erase(region_id);
+ mGetAllCallbacks.erase(region_id);
+}
+void LLMaterialMgr::onRegionRemoved(LLViewerRegion* regionp)
+{
+ clearGetQueues(regionp->getRegionID());
+ // Put doesn't need clearing: objects that can't be found will clean up in processPutQueue()
+}
+
diff --git a/indra/newview/llmaterialmgr.h b/indra/newview/llmaterialmgr.h
new file mode 100644
index 0000000000..e83f1f4e01
--- /dev/null
+++ b/indra/newview/llmaterialmgr.h
@@ -0,0 +1,132 @@
+/**
+ * @file llmaterialmgr.h
+ * @brief Material manager
+ *
+ * $LicenseInfo:firstyear=2006&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$
+ */
+
+#ifndef LL_LLMATERIALMGR_H
+#define LL_LLMATERIALMGR_H
+
+#include "llmaterial.h"
+#include "llmaterialid.h"
+#include "llsingleton.h"
+
+class LLViewerRegion;
+
+class LLMaterialMgr : public LLSingleton<LLMaterialMgr>
+{
+ friend class LLSingleton<LLMaterialMgr>;
+protected:
+ LLMaterialMgr();
+ virtual ~LLMaterialMgr();
+
+public:
+ typedef std::map<LLMaterialID, LLMaterialPtr> material_map_t;
+
+ typedef boost::signals2::signal<void (const LLMaterialID&, const LLMaterialPtr)> get_callback_t;
+ const LLMaterialPtr get(const LLUUID& region_id, const LLMaterialID& material_id);
+ boost::signals2::connection get(const LLUUID& region_id, const LLMaterialID& material_id, get_callback_t::slot_type cb);
+
+ typedef boost::signals2::signal<void (const LLMaterialID&, const LLMaterialPtr, U32 te)> get_callback_te_t;
+ boost::signals2::connection getTE(const LLUUID& region_id, const LLMaterialID& material_id, U32 te, get_callback_te_t::slot_type cb);
+
+ typedef boost::signals2::signal<void (const LLUUID&, const material_map_t&)> getall_callback_t;
+ void getAll(const LLUUID& region_id);
+ boost::signals2::connection getAll(const LLUUID& region_id, getall_callback_t::slot_type cb);
+ void put(const LLUUID& object_id, const U8 te, const LLMaterial& material);
+ void remove(const LLUUID& object_id, const U8 te);
+
+protected:
+ void clearGetQueues(const LLUUID& region_id);
+ bool isGetPending(const LLUUID& region_id, const LLMaterialID& material_id) const;
+ bool isGetAllPending(const LLUUID& region_id) const;
+ void markGetPending(const LLUUID& region_id, const LLMaterialID& material_id);
+ const LLMaterialPtr setMaterial(const LLUUID& region_id, const LLMaterialID& material_id, const LLSD& material_data);
+
+ static void onIdle(void*);
+ void processGetQueue();
+ void onGetResponse(bool success, const LLSD& content, const LLUUID& region_id);
+ void processGetAllQueue();
+ void onGetAllResponse(bool success, const LLSD& content, const LLUUID& region_id);
+ void processPutQueue();
+ void onPutResponse(bool success, const LLSD& content);
+ void onRegionRemoved(LLViewerRegion* regionp);
+
+protected:
+ typedef std::set<LLMaterialID> material_queue_t;
+ typedef std::map<LLUUID, material_queue_t> get_queue_t;
+ get_queue_t mGetQueue;
+ typedef std::pair<const LLUUID, LLMaterialID> pending_material_t;
+ typedef std::map<const pending_material_t, F64> get_pending_map_t;
+ get_pending_map_t mGetPending;
+ typedef std::map<LLMaterialID, get_callback_t*> get_callback_map_t;
+ get_callback_map_t mGetCallbacks;
+
+ // struct for TE-specific material ID query
+ class TEMaterialPair
+ {
+ public:
+
+ U32 te;
+ LLMaterialID materialID;
+
+ bool operator==(const TEMaterialPair& b) const { return (materialID == b.materialID) && (te == b.te); }
+ };
+
+ friend inline bool operator<(
+ const LLMaterialMgr::TEMaterialPair& lhs,
+ const LLMaterialMgr::TEMaterialPair& rhs)
+ {
+ return (lhs.te < rhs.te) ? TRUE :
+ (lhs.materialID < rhs.materialID);
+ }
+
+ struct TEMaterialPairHasher
+ {
+ enum { bucket_size = 8 };
+ size_t operator()(const TEMaterialPair& key_value) const { return *((size_t*)key_value.materialID.get()); } // cheesy, but effective
+ bool operator()(const TEMaterialPair& left, const TEMaterialPair& right) const { return left < right; }
+ };
+
+ typedef boost::unordered_map<TEMaterialPair, get_callback_te_t*, TEMaterialPairHasher> get_callback_te_map_t;
+ get_callback_te_map_t mGetTECallbacks;
+
+ typedef std::set<LLUUID> getall_queue_t;
+ getall_queue_t mGetAllQueue;
+ getall_queue_t mGetAllRequested;
+ typedef std::map<LLUUID, F64> getall_pending_map_t;
+ getall_pending_map_t mGetAllPending;
+ typedef std::map<LLUUID, getall_callback_t*> getall_callback_map_t;
+ getall_callback_map_t mGetAllCallbacks;
+
+ typedef std::map<U8, LLMaterial> facematerial_map_t;
+ typedef std::map<LLUUID, facematerial_map_t> put_queue_t;
+ put_queue_t mPutQueue;
+
+ material_map_t mMaterials;
+
+ U32 getMaxEntries(const LLViewerRegion* regionp);
+};
+
+#endif // LL_LLMATERIALMGR_H
+
diff --git a/indra/newview/llmediactrl.cpp b/indra/newview/llmediactrl.cpp
index 7650fe9229..2075aeed63 100644..100755
--- a/indra/newview/llmediactrl.cpp
+++ b/indra/newview/llmediactrl.cpp
@@ -119,8 +119,8 @@ LLMediaCtrl::LLMediaCtrl( const Params& p) :
if(!getDecoupleTextureSize())
{
- S32 screen_width = llround((F32)getRect().getWidth() * LLUI::sGLScaleFactor.mV[VX]);
- S32 screen_height = llround((F32)getRect().getHeight() * LLUI::sGLScaleFactor.mV[VY]);
+ S32 screen_width = llround((F32)getRect().getWidth() * LLUI::getScaleFactor().mV[VX]);
+ S32 screen_height = llround((F32)getRect().getHeight() * LLUI::getScaleFactor().mV[VY]);
setTextureSize(screen_width, screen_height);
}
@@ -469,8 +469,8 @@ void LLMediaCtrl::reshape( S32 width, S32 height, BOOL called_from_parent )
{
if(!getDecoupleTextureSize())
{
- S32 screen_width = llround((F32)width * LLUI::sGLScaleFactor.mV[VX]);
- S32 screen_height = llround((F32)height * LLUI::sGLScaleFactor.mV[VY]);
+ S32 screen_width = llround((F32)width * LLUI::getScaleFactor().mV[VX]);
+ S32 screen_height = llround((F32)height * LLUI::getScaleFactor().mV[VY]);
// when floater is minimized, these sizes are negative
if ( screen_height > 0 && screen_width > 0 )
@@ -564,32 +564,13 @@ void LLMediaCtrl::navigateTo( std::string url_in, std::string mime_type)
//
void LLMediaCtrl::navigateToLocalPage( const std::string& subdir, const std::string& filename_in )
{
- std::string language = LLUI::getLanguage();
- std::string delim = gDirUtilp->getDirDelimiter();
- std::string filename;
+ std::string filename(gDirUtilp->add(subdir, filename_in));
+ std::string expanded_filename = gDirUtilp->findSkinnedFilename("html", filename);
- filename += subdir;
- filename += delim;
- filename += filename_in;
-
- std::string expanded_filename = gDirUtilp->findSkinnedFilename("html", language, filename);
-
- if (! gDirUtilp->fileExists(expanded_filename))
+ if (expanded_filename.empty())
{
- if (language != "en")
- {
- expanded_filename = gDirUtilp->findSkinnedFilename("html", "en", filename);
- if (! gDirUtilp->fileExists(expanded_filename))
- {
- llwarns << "File " << subdir << delim << filename_in << "not found" << llendl;
- return;
- }
- }
- else
- {
- llwarns << "File " << subdir << delim << filename_in << "not found" << llendl;
- return;
- }
+ llwarns << "File " << filename << "not found" << llendl;
+ return;
}
if (ensureMediaSourceExists())
{
@@ -597,7 +578,6 @@ void LLMediaCtrl::navigateToLocalPage( const std::string& subdir, const std::str
mMediaSource->setSize(mTextureWidth, mTextureHeight);
mMediaSource->navigateTo(expanded_filename, "text/html", false);
}
-
}
////////////////////////////////////////////////////////////////////////////////
@@ -687,7 +667,7 @@ bool LLMediaCtrl::ensureMediaSourceExists()
mMediaSource->addObserver( this );
mMediaSource->setBackgroundColor( getBackgroundColor() );
mMediaSource->setTrustedBrowser(mTrusted);
- mMediaSource->setPageZoomFactor( LLUI::sGLScaleFactor.mV[ VX ] );
+ mMediaSource->setPageZoomFactor( LLUI::getScaleFactor().mV[ VX ] );
if(mClearCache)
{
@@ -770,7 +750,7 @@ void LLMediaCtrl::draw()
{
gGL.pushUIMatrix();
{
- mMediaSource->setPageZoomFactor( LLUI::sGLScaleFactor.mV[ VX ] );
+ mMediaSource->setPageZoomFactor( LLUI::getScaleFactor().mV[ VX ] );
// scale texture to fit the space using texture coords
gGL.getTexUnit(0)->bind(media_texture);
@@ -884,14 +864,14 @@ void LLMediaCtrl::convertInputCoords(S32& x, S32& y)
coords_opengl = mMediaSource->getMediaPlugin()->getTextureCoordsOpenGL();
}
- x = llround((F32)x * LLUI::sGLScaleFactor.mV[VX]);
+ x = llround((F32)x * LLUI::getScaleFactor().mV[VX]);
if ( ! coords_opengl )
{
- y = llround((F32)(y) * LLUI::sGLScaleFactor.mV[VY]);
+ y = llround((F32)(y) * LLUI::getScaleFactor().mV[VY]);
}
else
{
- y = llround((F32)(getRect().getHeight() - y) * LLUI::sGLScaleFactor.mV[VY]);
+ y = llround((F32)(getRect().getHeight() - y) * LLUI::getScaleFactor().mV[VY]);
};
}
diff --git a/indra/newview/llmediactrl.h b/indra/newview/llmediactrl.h
index 7f2a5e1642..6c38c1fb56 100644..100755
--- a/indra/newview/llmediactrl.h
+++ b/indra/newview/llmediactrl.h
@@ -46,6 +46,7 @@ class LLMediaCtrl :
{
LOG_CLASS(LLMediaCtrl);
public:
+
struct Params : public LLInitParam::Block<Params, LLPanel::Params>
{
Optional<std::string> start_url;
diff --git a/indra/newview/llmediadataclient.cpp b/indra/newview/llmediadataclient.cpp
index 31038b4aac..e3b46d5d2f 100644..100755
--- a/indra/newview/llmediadataclient.cpp
+++ b/indra/newview/llmediadataclient.cpp
@@ -564,7 +564,7 @@ LLMediaDataClient::Responder::Responder(const request_ptr_t &request)
}
/*virtual*/
-void LLMediaDataClient::Responder::error(U32 status, const std::string& reason)
+void LLMediaDataClient::Responder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)
{
mRequest->stopTracking();
@@ -596,8 +596,8 @@ void LLMediaDataClient::Responder::error(U32 status, const std::string& reason)
}
else
{
- std::string msg = boost::lexical_cast<std::string>(status) + ": " + reason;
- LL_WARNS("LLMediaDataClient") << *mRequest << " http error(" << msg << ")" << LL_ENDL;
+ LL_WARNS("LLMediaDataClient") << *mRequest << " http error [status:"
+ << status << "]:" << content << ")" << LL_ENDL;
}
}
@@ -1003,7 +1003,7 @@ LLMediaDataClient::Responder *LLObjectMediaNavigateClient::RequestNavigate::crea
}
/*virtual*/
-void LLObjectMediaNavigateClient::Responder::error(U32 status, const std::string& reason)
+void LLObjectMediaNavigateClient::Responder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)
{
getRequest()->stopTracking();
@@ -1017,7 +1017,7 @@ void LLObjectMediaNavigateClient::Responder::error(U32 status, const std::string
// class
if (status == HTTP_SERVICE_UNAVAILABLE)
{
- LLMediaDataClient::Responder::error(status, reason);
+ LLMediaDataClient::Responder::errorWithContent(status, reason, content);
}
else
{
diff --git a/indra/newview/llmediadataclient.h b/indra/newview/llmediadataclient.h
index ab90915c55..89e20a28d0 100644..100755
--- a/indra/newview/llmediadataclient.h
+++ b/indra/newview/llmediadataclient.h
@@ -195,7 +195,7 @@ protected:
public:
Responder(const request_ptr_t &request);
//If we get back an error (not found, etc...), handle it here
- virtual void error(U32 status, const std::string& reason);
+ virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content);
//If we get back a normal response, handle it here. Default just logs it.
virtual void result(const LLSD& content);
@@ -400,7 +400,7 @@ protected:
public:
Responder(const request_ptr_t &request)
: LLMediaDataClient::Responder(request) {}
- virtual void error(U32 status, const std::string& reason);
+ virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content);
virtual void result(const LLSD &content);
private:
void mediaNavigateBounceBack();
diff --git a/indra/newview/llmemoryview.cpp b/indra/newview/llmemoryview.cpp
deleted file mode 100644
index c0a323d6cb..0000000000
--- a/indra/newview/llmemoryview.cpp
+++ /dev/null
@@ -1,333 +0,0 @@
-/**
- * @file llmemoryview.cpp
- * @brief LLMemoryView class implementation
- *
- * $LicenseInfo:firstyear=2001&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 "llviewerprecompiledheaders.h"
-
-#include "llmemoryview.h"
-
-#include "llappviewer.h"
-#include "llallocator_heap_profile.h"
-#include "llgl.h" // LLGLSUIDefault
-#include "llviewerwindow.h"
-#include "llviewercontrol.h"
-
-#include <sstream>
-#include <boost/algorithm/string/split.hpp>
-
-#include "llmemory.h"
-
-LLMemoryView::LLMemoryView(const LLMemoryView::Params& p)
-: LLView(p),
- mPaused(FALSE),
- //mDelay(120),
- mAlloc(NULL)
-{
-}
-
-LLMemoryView::~LLMemoryView()
-{
-}
-
-BOOL LLMemoryView::handleMouseDown(S32 x, S32 y, MASK mask)
-{
- if (mask & MASK_SHIFT)
- {
- }
- else if (mask & MASK_CONTROL)
- {
- }
- else
- {
- mPaused = !mPaused;
- }
- return TRUE;
-}
-
-BOOL LLMemoryView::handleMouseUp(S32 x, S32 y, MASK mask)
-{
- return TRUE;
-}
-
-
-BOOL LLMemoryView::handleHover(S32 x, S32 y, MASK mask)
-{
- return FALSE;
-}
-
-void LLMemoryView::refreshProfile()
-{
- /*
- LLAllocator & alloc = LLAppViewer::instance()->getAllocator();
- if(alloc.isProfiling()) {
- std::string profile_text = alloc.getRawProfile();
-
- boost::algorithm::split(mLines, profile_text, boost::bind(std::equal_to<llwchar>(), '\n', _1));
- } else {
- mLines.clear();
- }
- */
- if (mAlloc == NULL) {
- mAlloc = &LLAppViewer::instance()->getAllocator();
- }
-
- mLines.clear();
-
- if(mAlloc->isProfiling())
- {
- const LLAllocatorHeapProfile &prof = mAlloc->getProfile();
- for(size_t i = 0; i < prof.mLines.size(); ++i)
- {
- std::stringstream ss;
- ss << "Unfreed Mem: " << (prof.mLines[i].mLiveSize >> 20) << " M Trace: ";
- for(size_t k = 0; k < prof.mLines[i].mTrace.size(); ++k)
- {
- ss << LLMemType::getNameFromID(prof.mLines[i].mTrace[k]) << " ";
- }
- mLines.push_back(utf8string_to_wstring(ss.str()));
- }
- }
-}
-
-void LLMemoryView::draw()
-{
- const S32 UPDATE_INTERVAL = 60;
- const S32 MARGIN_AMT = 10;
- static S32 curUpdate = UPDATE_INTERVAL;
- static LLUIColor s_console_color = LLUIColorTable::instance().getColor("ConsoleBackground", LLColor4U::black);
-
- // setup update interval
- if (curUpdate >= UPDATE_INTERVAL)
- {
- refreshProfile();
- curUpdate = 0;
- }
- curUpdate++;
-
- // setup window properly
- S32 height = (S32) (gViewerWindow->getWindowRectScaled().getHeight()*0.75f);
- S32 width = (S32) (gViewerWindow->getWindowRectScaled().getWidth() * 0.9f);
- setRect(LLRect().setLeftTopAndSize(getRect().mLeft, getRect().mTop, width, height));
-
- // setup window color
- F32 console_opacity = llclamp(gSavedSettings.getF32("ConsoleBackgroundOpacity"), 0.f, 1.f);
- LLColor4 color = s_console_color;
- color.mV[VALPHA] *= console_opacity;
-
- LLGLSUIDefault gls_ui;
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- gl_rect_2d(0, height, width, 0, color);
-
- LLFontGL * font = LLFontGL::getFontSansSerifSmall();
-
- // draw remaining lines
- F32 y_pos = 0.f;
- F32 y_off = 0.f;
-
- F32 line_height = font->getLineHeight();
- S32 target_width = width - 2 * MARGIN_AMT;
-
- // cut off lines on bottom
- U32 max_lines = U32((height - 2 * line_height) / line_height);
- y_pos = height - MARGIN_AMT - line_height;
- y_off = 0.f;
-
-#if !MEM_TRACK_MEM
- std::vector<LLWString>::const_iterator end = mLines.end();
- if(mLines.size() > max_lines) {
- end = mLines.begin() + max_lines;
- }
- for (std::vector<LLWString>::const_iterator i = mLines.begin(); i != end; ++i)
- {
- font->render(*i, 0, MARGIN_AMT, y_pos - y_off,
- LLColor4::white,
- LLFontGL::LEFT,
- LLFontGL::BASELINE,
- LLFontGL::NORMAL,
- LLFontGL::DROP_SHADOW,
- S32_MAX,
- target_width
- );
- y_off += line_height;
- }
-
-#else
- LLMemTracker::getInstance()->preDraw(mPaused) ;
-
- {
- F32 x_pos = MARGIN_AMT ;
- U32 lines = 0 ;
- const char* str = LLMemTracker::getInstance()->getNextLine() ;
- while(str != NULL)
- {
- lines++ ;
- font->renderUTF8(str, 0, x_pos, y_pos - y_off,
- LLColor4::white,
- LLFontGL::LEFT,
- LLFontGL::BASELINE,
- LLFontGL::NORMAL,
- LLFontGL::DROP_SHADOW,
- S32_MAX,
- target_width,
- NULL, FALSE);
-
- str = LLMemTracker::getInstance()->getNextLine() ;
- y_off += line_height;
-
- if(lines >= max_lines)
- {
- lines = 0 ;
- x_pos += 512.f ;
- if(x_pos + 512.f > target_width)
- {
- break ;
- }
-
- y_pos = height - MARGIN_AMT - line_height;
- y_off = 0.f;
- }
- }
- }
-
- LLMemTracker::getInstance()->postDraw() ;
-#endif
-
-#if MEM_TRACK_TYPE
-
- S32 left, top, right, bottom;
- S32 x, y;
-
- S32 margin = 10;
- S32 texth = LLFontGL::getFontMonospace()->getLineHeight();
-
- S32 xleft = margin;
- S32 ytop = height - margin;
- S32 labelwidth = 0;
- S32 maxmaxbytes = 1;
-
- // Make sure all timers are accounted for
- // Set 'MT_OTHER' to unaccounted ticks last frame
- {
- S32 display_memtypes[LLMemType::MTYPE_NUM_TYPES];
- for (S32 i=0; i < LLMemType::MTYPE_NUM_TYPES; i++)
- {
- display_memtypes[i] = 0;
- }
- for (S32 i=0; i < MTV_DISPLAY_NUM; i++)
- {
- S32 tidx = mtv_display_table[i].memtype;
- display_memtypes[tidx]++;
- }
- LLMemType::sMemCount[LLMemType::MTYPE_OTHER] = 0;
- LLMemType::sMaxMemCount[LLMemType::MTYPE_OTHER] = 0;
- for (S32 tidx = 0; tidx < LLMemType::MTYPE_NUM_TYPES; tidx++)
- {
- if (display_memtypes[tidx] == 0)
- {
- LLMemType::sMemCount[LLMemType::MTYPE_OTHER] += LLMemType::sMemCount[tidx];
- LLMemType::sMaxMemCount[LLMemType::MTYPE_OTHER] += LLMemType::sMaxMemCount[tidx];
- }
- }
- }
-
- // Labels
- {
- y = ytop;
- S32 peak = 0;
- for (S32 i=0; i<MTV_DISPLAY_NUM; i++)
- {
- x = xleft;
-
- int tidx = mtv_display_table[i].memtype;
- S32 bytes = LLMemType::sMemCount[tidx];
- S32 maxbytes = LLMemType::sMaxMemCount[tidx];
- maxmaxbytes = llmax(maxbytes, maxmaxbytes);
- peak += maxbytes;
- S32 mbytes = bytes >> 20;
-
- tdesc = llformat("%s [%4d MB] in %06d NEWS",mtv_display_table[i].desc,mbytes, LLMemType::sNewCount[tidx]);
- LLFontGL::getFontMonospace()->renderUTF8(tdesc, 0, x, y, LLColor4::white, LLFontGL::LEFT, LLFontGL::TOP);
-
- y -= (texth + 2);
-
- S32 textw = LLFontGL::getFontMonospace()->getWidth(tdesc);
- if (textw > labelwidth)
- labelwidth = textw;
- }
-
- S32 num_avatars = 0;
- S32 num_motions = 0;
- S32 num_loading_motions = 0;
- S32 num_loaded_motions = 0;
- S32 num_active_motions = 0;
- S32 num_deprecated_motions = 0;
- for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
- iter != LLCharacter::sInstances.end(); ++iter)
- {
- num_avatars++;
- (*iter)->getMotionController().incMotionCounts(num_motions, num_loading_motions, num_loaded_motions, num_active_motions, num_deprecated_motions);
- }
-
- x = xleft;
- tdesc = llformat("Total Bytes: %d MB Overhead: %d KB Avs %d Motions:%d Loading:%d Loaded:%d Active:%d Dep:%d",
- LLMemType::sTotalMem >> 20, LLMemType::sOverheadMem >> 10,
- num_avatars, num_motions, num_loading_motions, num_loaded_motions, num_active_motions, num_deprecated_motions);
- LLFontGL::getFontMonospace()->renderUTF8(tdesc, 0, x, y, LLColor4::white, LLFontGL::LEFT, LLFontGL::TOP);
- }
-
- // Bars
- y = ytop;
- labelwidth += 8;
- S32 barw = width - labelwidth - xleft - margin;
- for (S32 i=0; i<MTV_DISPLAY_NUM; i++)
- {
- x = xleft + labelwidth;
-
- int tidx = mtv_display_table[i].memtype;
- S32 bytes = LLMemType::sMemCount[tidx];
- F32 frac = (F32)bytes / (F32)maxmaxbytes;
- S32 w = (S32)(frac * (F32)barw);
- left = x; right = x + w;
- top = y; bottom = y - texth;
- gl_rect_2d(left, top, right, bottom, *mtv_display_table[i].color);
-
- S32 maxbytes = LLMemType::sMaxMemCount[tidx];
- F32 frac2 = (F32)maxbytes / (F32)maxmaxbytes;
- S32 w2 = (S32)(frac2 * (F32)barw);
- left = x + w + 1; right = x + w2;
- top = y; bottom = y - texth;
- LLColor4 tcolor = *mtv_display_table[i].color;
- tcolor.setAlpha(.5f);
- gl_rect_2d(left, top, right, bottom, tcolor);
-
- y -= (texth + 2);
- }
-
- dumpData();
-
-#endif
-
- LLView::draw();
-}
diff --git a/indra/newview/llmemoryview.h b/indra/newview/llmemoryview.h
deleted file mode 100644
index dc4849a9c4..0000000000
--- a/indra/newview/llmemoryview.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/**
- * @file llmemoryview.h
- * @brief LLMemoryView class definition
- *
- * $LicenseInfo:firstyear=2001&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$
- */
-
-#ifndef LL_LLMEMORYVIEW_H
-#define LL_LLMEMORYVIEW_H
-
-#include "llview.h"
-
-class LLAllocator;
-
-class LLMemoryView : public LLView
-{
-public:
- struct Params : public LLInitParam::Block<Params, LLView::Params>
- {
- Params()
- {
- changeDefault(mouse_opaque, true);
- changeDefault(visible, false);
- }
- };
- LLMemoryView(const LLMemoryView::Params&);
- virtual ~LLMemoryView();
-
- virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
- virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask);
- virtual BOOL handleHover(S32 x, S32 y, MASK mask);
- virtual void draw();
-
- void refreshProfile();
-
-private:
- std::vector<LLWString> mLines;
- LLAllocator* mAlloc;
- BOOL mPaused ;
-
-};
-
-#endif
diff --git a/indra/newview/llmenuoptionpathfindingrebakenavmesh.cpp b/indra/newview/llmenuoptionpathfindingrebakenavmesh.cpp
new file mode 100755
index 0000000000..a567d1217a
--- /dev/null
+++ b/indra/newview/llmenuoptionpathfindingrebakenavmesh.cpp
@@ -0,0 +1,245 @@
+/**
+* @file llmenuoptionpathfindingrebakenavmesh.cpp
+* @brief Implementation of llmenuoptionpathfindingrebakenavmesh
+* @author Prep@lindenlab.com
+*
+* $LicenseInfo:firstyear=2012&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2012, 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 "llmenuoptionpathfindingrebakenavmesh.h"
+
+#include <boost/bind.hpp>
+#include <boost/signals2.hpp>
+
+#include "llagent.h"
+#include "llenvmanager.h"
+#include "llnotificationsutil.h"
+#include "llpathfindingmanager.h"
+#include "llpathfindingnavmesh.h"
+#include "llpathfindingnavmeshstatus.h"
+#include "llviewerregion.h"
+
+LLMenuOptionPathfindingRebakeNavmesh::LLMenuOptionPathfindingRebakeNavmesh()
+ : LLSingleton<LLMenuOptionPathfindingRebakeNavmesh>(),
+ mIsInitialized(false),
+ mCanRebakeRegion(false),
+ mRebakeNavMeshMode(kRebakeNavMesh_Default),
+ mNavMeshSlot(),
+ mRegionCrossingSlot(),
+ mAgentStateSlot()
+{
+}
+
+LLMenuOptionPathfindingRebakeNavmesh::~LLMenuOptionPathfindingRebakeNavmesh()
+{
+ if (mIsInitialized)
+ {
+ if (mRebakeNavMeshMode == kRebakeNavMesh_RequestSent)
+ {
+ LL_WARNS("navmeshRebaking") << "During destruction of the LLMenuOptionPathfindingRebakeNavmesh "
+ << "singleton, the mode indicates that a request has been sent for which a response has yet "
+ << "to be received. This could contribute to a crash on exit." << LL_ENDL;
+ }
+
+ quit();
+ }
+}
+
+void LLMenuOptionPathfindingRebakeNavmesh::initialize()
+{
+ if (!mIsInitialized)
+ {
+ mIsInitialized = true;
+
+ setMode(kRebakeNavMesh_Default);
+
+ createNavMeshStatusListenerForCurrentRegion();
+
+ if ( !mRegionCrossingSlot.connected() )
+ {
+ mRegionCrossingSlot = LLEnvManagerNew::getInstance()->setRegionChangeCallback(boost::bind(&LLMenuOptionPathfindingRebakeNavmesh::handleRegionBoundaryCrossed, this));
+ }
+
+ if (!mAgentStateSlot.connected())
+ {
+ mAgentStateSlot = LLPathfindingManager::getInstance()->registerAgentStateListener(boost::bind(&LLMenuOptionPathfindingRebakeNavmesh::handleAgentState, this, _1));
+ }
+ LLPathfindingManager::getInstance()->requestGetAgentState();
+ }
+}
+
+void LLMenuOptionPathfindingRebakeNavmesh::quit()
+{
+ if (mIsInitialized) // Quitting from the login screen leaves this uninitialized
+ {
+ if (mNavMeshSlot.connected())
+ {
+ mNavMeshSlot.disconnect();
+ }
+
+ if (mRegionCrossingSlot.connected())
+ {
+ mRegionCrossingSlot.disconnect();
+ }
+
+ if (mAgentStateSlot.connected())
+ {
+ mAgentStateSlot.disconnect();
+ }
+
+ mIsInitialized = false;
+ }
+}
+
+bool LLMenuOptionPathfindingRebakeNavmesh::canRebakeRegion() const
+{
+ if (!mIsInitialized)
+ {
+ LL_ERRS("navmeshRebaking") << "LLMenuOptionPathfindingRebakeNavmesh class has not been initialized "
+ << "when the ability to rebake navmesh is being requested." << LL_ENDL;
+ }
+ return mCanRebakeRegion;
+}
+
+LLMenuOptionPathfindingRebakeNavmesh::ERebakeNavMeshMode LLMenuOptionPathfindingRebakeNavmesh::getMode() const
+{
+ if (!mIsInitialized)
+ {
+ LL_ERRS("navmeshRebaking") << "LLMenuOptionPathfindingRebakeNavmesh class has not been initialized "
+ << "when the mode is being requested." << LL_ENDL;
+ }
+ return mRebakeNavMeshMode;
+}
+
+void LLMenuOptionPathfindingRebakeNavmesh::sendRequestRebakeNavmesh()
+{
+ if (!mIsInitialized)
+ {
+ LL_ERRS("navmeshRebaking") << "LLMenuOptionPathfindingRebakeNavmesh class has not been initialized "
+ << "when the request is being made to rebake the navmesh." << LL_ENDL;
+ }
+ else
+ {
+ if (!canRebakeRegion())
+ {
+ LL_WARNS("navmeshRebaking") << "attempting to rebake navmesh when user does not have permissions "
+ << "on this region" << LL_ENDL;
+ }
+ if (getMode() != kRebakeNavMesh_Available)
+ {
+ LL_WARNS("navmeshRebaking") << "attempting to rebake navmesh when mode is not available"
+ << LL_ENDL;
+ }
+
+ setMode(kRebakeNavMesh_RequestSent);
+ LLPathfindingManager::getInstance()->requestRebakeNavMesh(boost::bind(&LLMenuOptionPathfindingRebakeNavmesh::handleRebakeNavMeshResponse, this, _1));
+ }
+}
+
+void LLMenuOptionPathfindingRebakeNavmesh::setMode(ERebakeNavMeshMode pRebakeNavMeshMode)
+{
+ mRebakeNavMeshMode = pRebakeNavMeshMode;
+}
+
+void LLMenuOptionPathfindingRebakeNavmesh::handleAgentState(BOOL pCanRebakeRegion)
+{
+ llassert(mIsInitialized);
+ mCanRebakeRegion = pCanRebakeRegion;
+}
+
+void LLMenuOptionPathfindingRebakeNavmesh::handleRebakeNavMeshResponse(bool pResponseStatus)
+{
+ llassert(mIsInitialized);
+ if (mIsInitialized)
+ {
+ if (getMode() == kRebakeNavMesh_RequestSent)
+ {
+ setMode(pResponseStatus ? kRebakeNavMesh_InProgress : kRebakeNavMesh_Default);
+ }
+
+ if (!pResponseStatus)
+ {
+ LLNotificationsUtil::add("PathfindingCannotRebakeNavmesh");
+ }
+ }
+}
+
+void LLMenuOptionPathfindingRebakeNavmesh::handleNavMeshStatus(const LLPathfindingNavMeshStatus &pNavMeshStatus)
+{
+ llassert(mIsInitialized);
+ if (mIsInitialized)
+ {
+ ERebakeNavMeshMode rebakeNavMeshMode = kRebakeNavMesh_Default;
+ if (pNavMeshStatus.isValid())
+ {
+ switch (pNavMeshStatus.getStatus())
+ {
+ case LLPathfindingNavMeshStatus::kPending :
+ case LLPathfindingNavMeshStatus::kRepending :
+ rebakeNavMeshMode = kRebakeNavMesh_Available;
+ break;
+ case LLPathfindingNavMeshStatus::kBuilding :
+ rebakeNavMeshMode = kRebakeNavMesh_InProgress;
+ break;
+ case LLPathfindingNavMeshStatus::kComplete :
+ rebakeNavMeshMode = kRebakeNavMesh_NotAvailable;
+ break;
+ default :
+ rebakeNavMeshMode = kRebakeNavMesh_Default;
+ llassert(0);
+ break;
+ }
+ }
+
+ setMode(rebakeNavMeshMode);
+ }
+}
+
+void LLMenuOptionPathfindingRebakeNavmesh::handleRegionBoundaryCrossed()
+{
+ llassert(mIsInitialized);
+ if (mIsInitialized)
+ {
+ createNavMeshStatusListenerForCurrentRegion();
+ mCanRebakeRegion = FALSE;
+ LLPathfindingManager::getInstance()->requestGetAgentState();
+ }
+}
+
+void LLMenuOptionPathfindingRebakeNavmesh::createNavMeshStatusListenerForCurrentRegion()
+{
+ if (mNavMeshSlot.connected())
+ {
+ mNavMeshSlot.disconnect();
+ }
+
+ LLViewerRegion *currentRegion = gAgent.getRegion();
+ if (currentRegion != NULL)
+ {
+ mNavMeshSlot = LLPathfindingManager::getInstance()->registerNavMeshListenerForRegion(currentRegion, boost::bind(&LLMenuOptionPathfindingRebakeNavmesh::handleNavMeshStatus, this, _2));
+ LLPathfindingManager::getInstance()->requestGetNavMeshForRegion(currentRegion, true);
+ }
+}
+
diff --git a/indra/newview/llmenuoptionpathfindingrebakenavmesh.h b/indra/newview/llmenuoptionpathfindingrebakenavmesh.h
new file mode 100755
index 0000000000..7b1d2873ba
--- /dev/null
+++ b/indra/newview/llmenuoptionpathfindingrebakenavmesh.h
@@ -0,0 +1,85 @@
+/**
+* @file llmenuoptionpathfindingrebakenavmesh.h
+* @brief Header file for llmenuoptionpathfindingrebakenavmesh
+* @author Prep@lindenlab.com
+*
+* $LicenseInfo:firstyear=2012&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2012, 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_LLMENUOPTIONPATHFINDINGREBAKENAVMESH_H
+#define LL_LLMENUOPTIONPATHFINDINGREBAKENAVMESH_H
+
+#include <boost/signals2.hpp>
+
+#include "llpathfindingmanager.h"
+#include "llpathfindingnavmesh.h"
+#include "llsingleton.h"
+
+class LLPathfindingNavMeshStatus;
+
+class LLMenuOptionPathfindingRebakeNavmesh : public LLSingleton<LLMenuOptionPathfindingRebakeNavmesh>
+{
+ LOG_CLASS(LLMenuOptionPathfindingRebakeNavmesh);
+
+public:
+ typedef enum
+ {
+ kRebakeNavMesh_Available,
+ kRebakeNavMesh_RequestSent,
+ kRebakeNavMesh_InProgress,
+ kRebakeNavMesh_NotAvailable,
+ kRebakeNavMesh_Default = kRebakeNavMesh_NotAvailable
+ } ERebakeNavMeshMode;
+
+ LLMenuOptionPathfindingRebakeNavmesh();
+ virtual ~LLMenuOptionPathfindingRebakeNavmesh();
+
+ void initialize();
+ void quit();
+
+ bool canRebakeRegion() const;
+ ERebakeNavMeshMode getMode() const;
+
+ void sendRequestRebakeNavmesh();
+
+protected:
+
+private:
+ void setMode(ERebakeNavMeshMode pRebakeNavMeshMode);
+
+ void handleAgentState(BOOL pCanRebakeRegion);
+ void handleRebakeNavMeshResponse(bool pResponseStatus);
+ void handleNavMeshStatus(const LLPathfindingNavMeshStatus &pNavMeshStatus);
+ void handleRegionBoundaryCrossed();
+
+ void createNavMeshStatusListenerForCurrentRegion();
+
+ bool mIsInitialized;
+
+ bool mCanRebakeRegion;
+ ERebakeNavMeshMode mRebakeNavMeshMode;
+
+ LLPathfindingNavMesh::navmesh_slot_t mNavMeshSlot;
+ boost::signals2::connection mRegionCrossingSlot;
+ LLPathfindingManager::agent_state_slot_t mAgentStateSlot;
+};
+
+#endif // LL_LLMENUOPTIONPATHFINDINGREBAKENAVMESH_H
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index 03547f103a..ff73c42ec9 100755
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -1,3 +1,4 @@
+
/**
* @file llmeshrepository.cpp
* @brief Mesh repository implementation.
@@ -204,16 +205,30 @@ class LLMeshHeaderResponder : public LLCurl::Responder
{
public:
LLVolumeParams mMeshParams;
-
+ bool mProcessed;
+
LLMeshHeaderResponder(const LLVolumeParams& mesh_params)
: mMeshParams(mesh_params)
{
- LLMeshRepoThread::sActiveHeaderRequests++;
+ LLMeshRepoThread::incActiveHeaderRequests();
+ mProcessed = false;
}
~LLMeshHeaderResponder()
{
- LLMeshRepoThread::sActiveHeaderRequests--;
+ if (!LLApp::isQuitting())
+ {
+ if (!mProcessed)
+ { //something went wrong, retry
+ llwarns << "Timeout or service unavailable, retrying." << llendl;
+ LLMeshRepository::sHTTPRetryCount++;
+ LLMeshRepoThread::HeaderRequest req(mMeshParams);
+ LLMutexLock lock(gMeshRepo.mThread->mMutex);
+ gMeshRepo.mThread->mHeaderReqQ.push(req);
+ }
+
+ LLMeshRepoThread::decActiveHeaderRequests();
+ }
}
virtual void completedRaw(U32 status, const std::string& reason,
@@ -229,16 +244,27 @@ public:
S32 mLOD;
U32 mRequestedBytes;
U32 mOffset;
+ bool mProcessed;
LLMeshLODResponder(const LLVolumeParams& mesh_params, S32 lod, U32 offset, U32 requested_bytes)
: mMeshParams(mesh_params), mLOD(lod), mOffset(offset), mRequestedBytes(requested_bytes)
{
- LLMeshRepoThread::sActiveLODRequests++;
+ LLMeshRepoThread::incActiveLODRequests();
+ mProcessed = false;
}
~LLMeshLODResponder()
{
- LLMeshRepoThread::sActiveLODRequests--;
+ if (!LLApp::isQuitting())
+ {
+ if (!mProcessed)
+ {
+ llwarns << "Killed without being processed, retrying." << llendl;
+ LLMeshRepository::sHTTPRetryCount++;
+ gMeshRepo.mThread->lockAndLoadMeshLOD(mMeshParams, mLOD);
+ }
+ LLMeshRepoThread::decActiveLODRequests();
+ }
}
virtual void completedRaw(U32 status, const std::string& reason,
@@ -253,10 +279,24 @@ public:
LLUUID mMeshID;
U32 mRequestedBytes;
U32 mOffset;
+ bool mProcessed;
LLMeshSkinInfoResponder(const LLUUID& id, U32 offset, U32 size)
: mMeshID(id), mRequestedBytes(size), mOffset(offset)
{
+ mProcessed = false;
+ }
+
+ ~LLMeshSkinInfoResponder()
+ {
+ if (!LLApp::isQuitting() &&
+ !mProcessed &&
+ mMeshID.notNull())
+ { // Something went wrong, retry
+ llwarns << "Timeout or service unavailable, retrying loadMeshSkinInfo() for " << mMeshID << llendl;
+ LLMeshRepository::sHTTPRetryCount++;
+ gMeshRepo.mThread->loadMeshSkinInfo(mMeshID);
+ }
}
virtual void completedRaw(U32 status, const std::string& reason,
@@ -271,10 +311,24 @@ public:
LLUUID mMeshID;
U32 mRequestedBytes;
U32 mOffset;
+ bool mProcessed;
LLMeshDecompositionResponder(const LLUUID& id, U32 offset, U32 size)
: mMeshID(id), mRequestedBytes(size), mOffset(offset)
{
+ mProcessed = false;
+ }
+
+ ~LLMeshDecompositionResponder()
+ {
+ if (!LLApp::isQuitting() &&
+ !mProcessed &&
+ mMeshID.notNull())
+ { // Something went wrong, retry
+ llwarns << "Timeout or service unavailable, retrying loadMeshDecomposition() for " << mMeshID << llendl;
+ LLMeshRepository::sHTTPRetryCount++;
+ gMeshRepo.mThread->loadMeshDecomposition(mMeshID);
+ }
}
virtual void completedRaw(U32 status, const std::string& reason,
@@ -289,10 +343,24 @@ public:
LLUUID mMeshID;
U32 mRequestedBytes;
U32 mOffset;
+ bool mProcessed;
LLMeshPhysicsShapeResponder(const LLUUID& id, U32 offset, U32 size)
: mMeshID(id), mRequestedBytes(size), mOffset(offset)
{
+ mProcessed = false;
+ }
+
+ ~LLMeshPhysicsShapeResponder()
+ {
+ if (!LLApp::isQuitting() &&
+ !mProcessed &&
+ mMeshID.notNull())
+ { // Something went wrong, retry
+ llwarns << "Timeout or service unavailable, retrying loadMeshPhysicsShape() for " << mMeshID << llendl;
+ LLMeshRepository::sHTTPRetryCount++;
+ gMeshRepo.mThread->loadMeshPhysicsShape(mMeshID);
+ }
}
virtual void completedRaw(U32 status, const std::string& reason,
@@ -361,7 +429,20 @@ public:
mModelData(model_data),
mObserverHandle(observer_handle)
{
+ if (mThread)
+ {
+ mThread->startRequest();
+ }
+ }
+
+ ~LLWholeModelFeeResponder()
+ {
+ if (mThread)
+ {
+ mThread->stopRequest();
+ }
}
+
virtual void completed(U32 status,
const std::string& reason,
const LLSD& content)
@@ -372,7 +453,6 @@ public:
cc = llsd_from_file("fake_upload_error.xml");
}
- mThread->mPendingUploads--;
dump_llsd_to_file(cc,make_dump_name("whole_model_fee_response_",dump_num));
LLWholeModelFeeObserver* observer = mObserverHandle.get();
@@ -415,7 +495,20 @@ public:
mModelData(model_data),
mObserverHandle(observer_handle)
{
+ if (mThread)
+ {
+ mThread->startRequest();
+ }
+ }
+
+ ~LLWholeModelUploadResponder()
+ {
+ if (mThread)
+ {
+ mThread->stopRequest();
+ }
}
+
virtual void completed(U32 status,
const std::string& reason,
const LLSD& content)
@@ -426,7 +519,6 @@ public:
cc = llsd_from_file("fake_upload_error.xml");
}
- mThread->mPendingUploads--;
dump_llsd_to_file(cc,make_dump_name("whole_model_upload_response_",dump_num));
LLWholeModelUploadObserver* observer = mObserverHandle.get();
@@ -518,7 +610,7 @@ void LLMeshRepoThread::run()
if (!fetchMeshLOD(req.mMeshParams, req.mLOD, count))//failed, resubmit
{
mMutex->lock();
- mLODReqQ.push(req) ;
+ mLODReqQ.push(req);
mMutex->unlock();
}
}
@@ -614,16 +706,24 @@ void LLMeshRepoThread::loadMeshPhysicsShape(const LLUUID& mesh_id)
mPhysicsShapeRequests.insert(mesh_id);
}
+void LLMeshRepoThread::lockAndLoadMeshLOD(const LLVolumeParams& mesh_params, S32 lod)
+{
+ if (!LLAppViewer::isQuitting())
+ {
+ loadMeshLOD(mesh_params, lod);
+ }
+}
+
-void LLMeshRepoThread::loadMeshLOD(const LLVolumeParams& mesh_params, S32 lod)
-{ //protected by mSignal, no locking needed here
+void LLMeshRepoThread::loadMeshLOD(const LLVolumeParams& mesh_params, S32 lod)
+{ //could be called from any thread
+ LLMutexLock lock(mMutex);
mesh_header_map::iterator iter = mMeshHeader.find(mesh_params.getSculptID());
if (iter != mMeshHeader.end())
{ //if we have the header, request LOD byte range
LODRequest req(mesh_params, lod);
{
- LLMutexLock lock(mMutex);
mLODReqQ.push(req);
LLMeshRepository::sLODProcessing++;
}
@@ -641,7 +741,6 @@ void LLMeshRepoThread::loadMeshLOD(const LLVolumeParams& mesh_params, S32 lod)
}
else
{ //if no header request is pending, fetch header
- LLMutexLock lock(mMutex);
mHeaderReqQ.push(req);
mPendingLOD[mesh_params].push_back(lod);
}
@@ -921,6 +1020,34 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id)
return ret;
}
+//static
+void LLMeshRepoThread::incActiveLODRequests()
+{
+ LLMutexLock lock(gMeshRepo.mThread->mMutex);
+ ++LLMeshRepoThread::sActiveLODRequests;
+}
+
+//static
+void LLMeshRepoThread::decActiveLODRequests()
+{
+ LLMutexLock lock(gMeshRepo.mThread->mMutex);
+ --LLMeshRepoThread::sActiveLODRequests;
+}
+
+//static
+void LLMeshRepoThread::incActiveHeaderRequests()
+{
+ LLMutexLock lock(gMeshRepo.mThread->mMutex);
+ ++LLMeshRepoThread::sActiveHeaderRequests;
+}
+
+//static
+void LLMeshRepoThread::decActiveHeaderRequests()
+{
+ LLMutexLock lock(gMeshRepo.mThread->mMutex);
+ --LLMeshRepoThread::sActiveHeaderRequests;
+}
+
//return false if failed to get header
bool LLMeshRepoThread::fetchMeshHeader(const LLVolumeParams& mesh_params, U32& count)
{
@@ -1095,21 +1222,22 @@ bool LLMeshRepoThread::headerReceived(const LLVolumeParams& mesh_params, U8* dat
LLMutexLock lock(mHeaderMutex);
mMeshHeaderSize[mesh_id] = header_size;
mMeshHeader[mesh_id] = header;
- }
+ }
+
+ LLMutexLock lock(mMutex); // make sure only one thread access mPendingLOD at the same time.
//check for pending requests
pending_lod_map::iterator iter = mPendingLOD.find(mesh_params);
if (iter != mPendingLOD.end())
{
- LLMutexLock lock(mMutex);
for (U32 i = 0; i < iter->second.size(); ++i)
{
LODRequest req(mesh_params, iter->second[i]);
mLODReqQ.push(req);
LLMeshRepository::sLODProcessing++;
}
+ mPendingLOD.erase(iter);
}
- mPendingLOD.erase(iter);
}
return true;
@@ -1620,7 +1748,7 @@ void LLMeshUploadThread::doWholeModelUpload()
mCurlRequest->process();
//sleep for 10ms to prevent eating a whole core
apr_sleep(10000);
- } while (mCurlRequest->getQueued() > 0);
+ } while (!LLAppViewer::isQuitting() && mPendingUploads > 0);
}
delete mCurlRequest;
@@ -1642,7 +1770,6 @@ void LLMeshUploadThread::requestWholeModelFee()
wholeModelToLLSD(model_data,false);
dump_llsd_to_file(model_data,make_dump_name("whole_model_fee_request_",dump_num));
- mPendingUploads++;
LLCurlRequest::headers_t headers;
{
@@ -1659,7 +1786,7 @@ void LLMeshUploadThread::requestWholeModelFee()
mCurlRequest->process();
//sleep for 10ms to prevent eating a whole core
apr_sleep(10000);
- } while (mCurlRequest->getQueued() > 0);
+ } while (!LLApp::isQuitting() && mPendingUploads > 0);
delete mCurlRequest;
mCurlRequest = NULL;
@@ -1796,7 +1923,14 @@ void LLMeshLODResponder::completedRaw(U32 status, const std::string& reason,
const LLChannelDescriptors& channels,
const LLIOPipe::buffer_ptr_t& buffer)
{
-
+ mProcessed = true;
+
+ // thread could have already be destroyed during logout
+ if( !gMeshRepo.mThread )
+ {
+ return;
+ }
+
S32 data_size = buffer->countAfter(channels.in(), NULL);
if (status < 200 || status > 400)
@@ -1806,13 +1940,15 @@ void LLMeshLODResponder::completedRaw(U32 status, const std::string& reason,
if (data_size < mRequestedBytes)
{
- if (status == 499 || status == 503)
+ if (status == HTTP_INTERNAL_ERROR || status == HTTP_SERVICE_UNAVAILABLE)
{ //timeout or service unavailable, try again
+ llwarns << "Timeout or service unavailable, retrying." << llendl;
LLMeshRepository::sHTTPRetryCount++;
gMeshRepo.mThread->loadMeshLOD(mMeshParams, mLOD);
}
else
{
+ llassert(status == HTTP_INTERNAL_ERROR || status == HTTP_SERVICE_UNAVAILABLE); //intentionally trigger a breakpoint
llwarns << "Unhandled status " << status << llendl;
}
return;
@@ -1851,6 +1987,14 @@ void LLMeshSkinInfoResponder::completedRaw(U32 status, const std::string& reason
const LLChannelDescriptors& channels,
const LLIOPipe::buffer_ptr_t& buffer)
{
+ mProcessed = true;
+
+ // thread could have already be destroyed during logout
+ if( !gMeshRepo.mThread )
+ {
+ return;
+ }
+
S32 data_size = buffer->countAfter(channels.in(), NULL);
if (status < 200 || status > 400)
@@ -1860,13 +2004,15 @@ void LLMeshSkinInfoResponder::completedRaw(U32 status, const std::string& reason
if (data_size < mRequestedBytes)
{
- if (status == 499 || status == 503)
+ if (status == HTTP_INTERNAL_ERROR || status == HTTP_SERVICE_UNAVAILABLE)
{ //timeout or service unavailable, try again
+ llwarns << "Timeout or service unavailable, retrying loadMeshSkinInfo() for " << mMeshID << llendl;
LLMeshRepository::sHTTPRetryCount++;
gMeshRepo.mThread->loadMeshSkinInfo(mMeshID);
}
else
{
+ llassert(status == HTTP_INTERNAL_ERROR || status == HTTP_SERVICE_UNAVAILABLE); //intentionally trigger a breakpoint
llwarns << "Unhandled status " << status << llendl;
}
return;
@@ -1905,6 +2051,13 @@ void LLMeshDecompositionResponder::completedRaw(U32 status, const std::string& r
const LLChannelDescriptors& channels,
const LLIOPipe::buffer_ptr_t& buffer)
{
+ mProcessed = true;
+
+ if( !gMeshRepo.mThread )
+ {
+ return;
+ }
+
S32 data_size = buffer->countAfter(channels.in(), NULL);
if (status < 200 || status > 400)
@@ -1914,13 +2067,15 @@ void LLMeshDecompositionResponder::completedRaw(U32 status, const std::string& r
if (data_size < mRequestedBytes)
{
- if (status == 499 || status == 503)
+ if (status == HTTP_INTERNAL_ERROR || status == HTTP_SERVICE_UNAVAILABLE)
{ //timeout or service unavailable, try again
+ llwarns << "Timeout or service unavailable, retrying loadMeshDecomposition() for " << mMeshID << llendl;
LLMeshRepository::sHTTPRetryCount++;
gMeshRepo.mThread->loadMeshDecomposition(mMeshID);
}
else
{
+ llassert(status == HTTP_INTERNAL_ERROR || status == HTTP_SERVICE_UNAVAILABLE); //intentionally trigger a breakpoint
llwarns << "Unhandled status " << status << llendl;
}
return;
@@ -1959,6 +2114,14 @@ void LLMeshPhysicsShapeResponder::completedRaw(U32 status, const std::string& re
const LLChannelDescriptors& channels,
const LLIOPipe::buffer_ptr_t& buffer)
{
+ mProcessed = true;
+
+ // thread could have already be destroyed during logout
+ if( !gMeshRepo.mThread )
+ {
+ return;
+ }
+
S32 data_size = buffer->countAfter(channels.in(), NULL);
if (status < 200 || status > 400)
@@ -1968,13 +2131,15 @@ void LLMeshPhysicsShapeResponder::completedRaw(U32 status, const std::string& re
if (data_size < mRequestedBytes)
{
- if (status == 499 || status == 503)
+ if (status == HTTP_INTERNAL_ERROR || status == HTTP_SERVICE_UNAVAILABLE)
{ //timeout or service unavailable, try again
+ llwarns << "Timeout or service unavailable, retrying loadMeshPhysicsShape() for " << mMeshID << llendl;
LLMeshRepository::sHTTPRetryCount++;
gMeshRepo.mThread->loadMeshPhysicsShape(mMeshID);
}
else
{
+ llassert(status == HTTP_INTERNAL_ERROR || status == HTTP_SERVICE_UNAVAILABLE); //intentionally trigger a breakpoint
llwarns << "Unhandled status " << status << llendl;
}
return;
@@ -2013,20 +2178,32 @@ void LLMeshHeaderResponder::completedRaw(U32 status, const std::string& reason,
const LLChannelDescriptors& channels,
const LLIOPipe::buffer_ptr_t& buffer)
{
+ mProcessed = true;
+
+ // thread could have already be destroyed during logout
+ if( !gMeshRepo.mThread )
+ {
+ return;
+ }
+
if (status < 200 || status > 400)
{
//llwarns
// << "Header responder failed with status: "
// << status << ": " << reason << llendl;
- // 503 (service unavailable) or 499 (timeout)
+ // 503 (service unavailable) or 499 (internal Linden-generated error)
// can be due to server load and can be retried
// TODO*: Add maximum retry logic, exponential backoff
// and (somewhat more optional than the others) retries
// again after some set period of time
- if (status == 503 || status == 499)
+
+ llassert(status == HTTP_NOT_FOUND || status == HTTP_SERVICE_UNAVAILABLE || status == HTTP_REQUEST_TIME_OUT || status == HTTP_INTERNAL_ERROR);
+
+ if (status == HTTP_SERVICE_UNAVAILABLE || status == HTTP_REQUEST_TIME_OUT || status == HTTP_INTERNAL_ERROR)
{ //retry
+ llwarns << "Timeout or service unavailable, retrying." << llendl;
LLMeshRepository::sHTTPRetryCount++;
LLMeshRepoThread::HeaderRequest req(mMeshParams);
LLMutexLock lock(gMeshRepo.mThread->mMutex);
@@ -2034,6 +2211,10 @@ void LLMeshHeaderResponder::completedRaw(U32 status, const std::string& reason,
return;
}
+ else
+ {
+ llwarns << "Unhandled status: " << status << llendl;
+ }
}
S32 data_size = buffer->countAfter(channels.in(), NULL);
@@ -2048,7 +2229,11 @@ void LLMeshHeaderResponder::completedRaw(U32 status, const std::string& reason,
LLMeshRepository::sBytesReceived += llmin(data_size, 4096);
- if (!gMeshRepo.mThread->headerReceived(mMeshParams, data, data_size))
+ bool success = gMeshRepo.mThread->headerReceived(mMeshParams, data, data_size);
+
+ llassert(success);
+
+ if (!success)
{
llwarns
<< "Unable to parse mesh header: "
@@ -3058,6 +3243,7 @@ void LLPhysicsDecomp::doDecomposition()
param_map[params[i].mName] = params+i;
}
+ U32 ret = LLCD_OK;
//set parameter values
for (decomp_params::iterator iter = mCurRequest->mParams.begin(); iter != mCurRequest->mParams.end(); ++iter)
{
@@ -3071,7 +3257,6 @@ void LLPhysicsDecomp::doDecomposition()
continue;
}
- U32 ret = LLCD_OK;
if (param->mType == LLCDParam::LLCD_FLOAT)
{
@@ -3090,8 +3275,6 @@ void LLPhysicsDecomp::doDecomposition()
mCurRequest->setStatusMessage("Executing.");
- LLCDResult ret = LLCD_OK;
-
if (LLConvexDecomposition::getInstance() != NULL)
{
ret = LLConvexDecomposition::getInstance()->executeStage(stage);
diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h
index da81bb057b..8eaf691d6f 100644..100755
--- a/indra/newview/llmeshrepository.h
+++ b/indra/newview/llmeshrepository.h
@@ -322,7 +322,9 @@ public:
virtual void run();
+ void lockAndLoadMeshLOD(const LLVolumeParams& mesh_params, S32 lod);
void loadMeshLOD(const LLVolumeParams& mesh_params, S32 lod);
+
bool fetchMeshHeader(const LLVolumeParams& mesh_params, U32& count);
bool fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod, U32& count);
bool headerReceived(const LLVolumeParams& mesh_params, U8* data, S32 data_size);
@@ -351,6 +353,10 @@ public:
// (should hold onto mesh_id and try again later if header info does not exist)
bool fetchMeshPhysicsShape(const LLUUID& mesh_id);
+ static void incActiveLODRequests();
+ static void decActiveLODRequests();
+ static void incActiveHeaderRequests();
+ static void decActiveHeaderRequests();
};
@@ -405,6 +411,9 @@ public:
LLHandle<LLWholeModelFeeObserver> fee_observer= (LLHandle<LLWholeModelFeeObserver>()), LLHandle<LLWholeModelUploadObserver> upload_observer = (LLHandle<LLWholeModelUploadObserver>()));
~LLMeshUploadThread();
+ void startRequest() { ++mPendingUploads; }
+ void stopRequest() { --mPendingUploads; }
+
bool finished() { return mFinished; }
virtual void run();
void preStart();
diff --git a/indra/newview/llmimetypes.cpp b/indra/newview/llmimetypes.cpp
index e689e39b26..e689e39b26 100644..100755
--- a/indra/newview/llmimetypes.cpp
+++ b/indra/newview/llmimetypes.cpp
diff --git a/indra/newview/llmimetypes.h b/indra/newview/llmimetypes.h
index ab629fd965..ab629fd965 100644..100755
--- a/indra/newview/llmimetypes.h
+++ b/indra/newview/llmimetypes.h
diff --git a/indra/newview/llmorphview.cpp b/indra/newview/llmorphview.cpp
index eaa044cb59..252d1b78ea 100644..100755
--- a/indra/newview/llmorphview.cpp
+++ b/indra/newview/llmorphview.cpp
@@ -99,8 +99,6 @@ void LLMorphView::initialize()
//-----------------------------------------------------------------------------
void LLMorphView::shutdown()
{
- LLVOAvatarSelf::onCustomizeEnd();
-
if (isAgentAvatarValid())
{
gAgentAvatarp->startMotion( ANIM_AGENT_BODY_NOISE );
diff --git a/indra/newview/llmorphview.h b/indra/newview/llmorphview.h
index 318d49bba5..318d49bba5 100644..100755
--- a/indra/newview/llmorphview.h
+++ b/indra/newview/llmorphview.h
diff --git a/indra/newview/llmoveview.cpp b/indra/newview/llmoveview.cpp
index c3d8b91d67..eb6591eb39 100644..100755
--- a/indra/newview/llmoveview.cpp
+++ b/indra/newview/llmoveview.cpp
@@ -686,7 +686,7 @@ void LLPanelStandStopFlying::onStopFlyingButtonClick()
gAgent.setFlying(FALSE);
setFocus(FALSE); // EXT-482
- setVisible(FALSE);
+ mStopFlyingButton->setVisible(FALSE);
}
/**
@@ -698,19 +698,28 @@ void LLPanelStandStopFlying::updatePosition()
S32 y_pos = 0;
S32 bottom_tb_center = 0;
- if (LLToolBar* toolbar_bottom = gToolBarView->getChild<LLToolBar>("toolbar_bottom"))
+ if (LLToolBar* toolbar_bottom = gToolBarView->getToolbar(LLToolBarView::TOOLBAR_BOTTOM))
{
y_pos = toolbar_bottom->getRect().getHeight();
bottom_tb_center = toolbar_bottom->getRect().getCenterX();
}
S32 left_tb_width = 0;
- if (LLToolBar* toolbar_left = gToolBarView->getChild<LLToolBar>("toolbar_left"))
+ if (LLToolBar* toolbar_left = gToolBarView->getToolbar(LLToolBarView::TOOLBAR_LEFT))
{
left_tb_width = toolbar_left->getRect().getWidth();
}
- if(LLPanel* panel_ssf_container = getRootView()->getChild<LLPanel>("stand_stop_flying_container"))
+ if (!mStateManagementButtons.get())
+ {
+ LLPanel* panel_ssf_container = getRootView()->getChild<LLPanel>("state_management_buttons_container");
+ if (panel_ssf_container)
+ {
+ mStateManagementButtons = panel_ssf_container->getHandle();
+ }
+ }
+
+ if(LLPanel* panel_ssf_container = mStateManagementButtons.get())
{
panel_ssf_container->setOrigin(0, y_pos);
}
diff --git a/indra/newview/llmoveview.h b/indra/newview/llmoveview.h
index 744dd866d4..c525d9dfdb 100644..100755
--- a/indra/newview/llmoveview.h
+++ b/indra/newview/llmoveview.h
@@ -172,6 +172,8 @@ private:
*/
LLHandle<LLPanel> mOriginalParent;
+ LLHandle<LLPanel> mStateManagementButtons;
+
/**
* True if the panel is currently attached to the movement controls floater.
*
diff --git a/indra/newview/llmutelist.cpp b/indra/newview/llmutelist.cpp
index a7059eb519..0720d443f8 100644..100755
--- a/indra/newview/llmutelist.cpp
+++ b/indra/newview/llmutelist.cpp
@@ -44,6 +44,8 @@
#include "llmutelist.h"
+#include "pipeline.h"
+
#include <boost/tokenizer.hpp>
#include "lldispatcher.h"
@@ -192,6 +194,23 @@ BOOL LLMuteList::isLinden(const std::string& name) const
return last_name == "Linden";
}
+static LLVOAvatar* find_avatar(const LLUUID& id)
+{
+ LLViewerObject *obj = gObjectList.findObject(id);
+ while (obj && obj->isAttachment())
+ {
+ obj = (LLViewerObject *)obj->getParent();
+ }
+
+ if (obj && obj->isAvatar())
+ {
+ return (LLVOAvatar*)obj;
+ }
+ else
+ {
+ return NULL;
+ }
+}
BOOL LLMuteList::add(const LLMute& mute, U32 flags)
{
@@ -232,6 +251,7 @@ BOOL LLMuteList::add(const LLMute& mute, U32 flags)
llinfos << "Muting by name " << mute.mName << llendl;
updateAdd(mute);
notifyObservers();
+ notifyObserversDetailed(mute);
return TRUE;
}
else
@@ -280,6 +300,7 @@ BOOL LLMuteList::add(const LLMute& mute, U32 flags)
llinfos << "Muting " << localmute.mName << " id " << localmute.mID << " flags " << localmute.mFlags << llendl;
updateAdd(localmute);
notifyObservers();
+ notifyObserversDetailed(localmute);
if(!(localmute.mFlags & LLMute::flagParticles))
{
//Kill all particle systems owned by muted task
@@ -288,6 +309,12 @@ BOOL LLMuteList::add(const LLMute& mute, U32 flags)
LLViewerPartSim::getInstance()->clearParticlesByOwnerID(localmute.mID);
}
}
+ //mute local lights that are attached to the avatar
+ LLVOAvatar *avatarp = find_avatar(localmute.mID);
+ if (avatarp)
+ {
+ LLPipeline::removeMutedAVsLights(avatarp);
+ }
return TRUE;
}
}
@@ -371,6 +398,7 @@ BOOL LLMuteList::remove(const LLMute& mute, U32 flags)
}
// Must be after erase.
+ notifyObserversDetailed(localmute);
setLoaded(); // why is this here? -MG
}
else
@@ -384,6 +412,7 @@ BOOL LLMuteList::remove(const LLMute& mute, U32 flags)
updateRemove(mute);
mLegacyMutes.erase(legacy_it);
// Must be after erase.
+ notifyObserversDetailed(mute);
setLoaded(); // why is this here? -MG
}
}
@@ -737,3 +766,16 @@ void LLMuteList::notifyObservers()
it = mObservers.upper_bound(observer);
}
}
+
+void LLMuteList::notifyObserversDetailed(const LLMute& mute)
+{
+ for (observer_set_t::iterator it = mObservers.begin();
+ it != mObservers.end();
+ )
+ {
+ LLMuteListObserver* observer = *it;
+ observer->onChangeDetailed(mute);
+ // In case onChange() deleted an entry.
+ it = mObservers.upper_bound(observer);
+ }
+}
diff --git a/indra/newview/llmutelist.h b/indra/newview/llmutelist.h
index 7a70370fe3..3e998b4f0e 100644..100755
--- a/indra/newview/llmutelist.h
+++ b/indra/newview/llmutelist.h
@@ -123,6 +123,7 @@ private:
void setLoaded();
void notifyObservers();
+ void notifyObserversDetailed(const LLMute &mute);
void updateAdd(const LLMute& mute);
void updateRemove(const LLMute& mute);
@@ -173,6 +174,7 @@ class LLMuteListObserver
public:
virtual ~LLMuteListObserver() { }
virtual void onChange() = 0;
+ virtual void onChangeDetailed(const LLMute& ) { }
};
diff --git a/indra/newview/llnamebox.cpp b/indra/newview/llnamebox.cpp
index 1099316a19..1099316a19 100644..100755
--- a/indra/newview/llnamebox.cpp
+++ b/indra/newview/llnamebox.cpp
diff --git a/indra/newview/llnamebox.h b/indra/newview/llnamebox.h
index 76e8551268..76e8551268 100644..100755
--- a/indra/newview/llnamebox.h
+++ b/indra/newview/llnamebox.h
diff --git a/indra/newview/llnameeditor.cpp b/indra/newview/llnameeditor.cpp
index b3b1ff7c06..b3b1ff7c06 100644..100755
--- a/indra/newview/llnameeditor.cpp
+++ b/indra/newview/llnameeditor.cpp
diff --git a/indra/newview/llnameeditor.h b/indra/newview/llnameeditor.h
index b8c4a6042e..b8c4a6042e 100644..100755
--- a/indra/newview/llnameeditor.h
+++ b/indra/newview/llnameeditor.h
diff --git a/indra/newview/llnamelistctrl.cpp b/indra/newview/llnamelistctrl.cpp
index 4e28d1f526..7ddd04fed0 100644..100755
--- a/indra/newview/llnamelistctrl.cpp
+++ b/indra/newview/llnamelistctrl.cpp
@@ -64,11 +64,12 @@ LLNameListCtrl::LLNameListCtrl(const LLNameListCtrl::Params& p)
mNameColumnIndex(p.name_column.column_index),
mNameColumn(p.name_column.column_name),
mAllowCallingCardDrop(p.allow_calling_card_drop),
- mShortNames(p.short_names)
+ mShortNames(p.short_names),
+ mAvatarNameCacheConnection()
{}
// public
-void LLNameListCtrl::addNameItem(const LLUUID& agent_id, EAddPosition pos,
+LLScrollListItem* LLNameListCtrl::addNameItem(const LLUUID& agent_id, EAddPosition pos,
BOOL enabled, const std::string& suffix)
{
//llinfos << "LLNameListCtrl::addNameItem " << agent_id << llendl;
@@ -78,7 +79,7 @@ void LLNameListCtrl::addNameItem(const LLUUID& agent_id, EAddPosition pos,
item.enabled = enabled;
item.target = INDIVIDUAL;
- addNameItemRow(item, pos, suffix);
+ return addNameItemRow(item, pos, suffix);
}
// virtual, public
@@ -204,7 +205,7 @@ BOOL LLNameListCtrl::handleToolTip(S32 x, S32 y, MASK mask)
{
BOOL handled = FALSE;
S32 column_index = getColumnIndexFromOffset(x);
- LLScrollListItem* hit_item = hitItem(x, y);
+ LLNameListItem* hit_item = dynamic_cast<LLNameListItem*>(hitItem(x, y));
if (hit_item
&& column_index == mNameColumnIndex)
{
@@ -228,7 +229,7 @@ BOOL LLNameListCtrl::handleToolTip(S32 x, S32 y, MASK mask)
LLCoordGL pos( sticky_rect.mRight - info_icon_size, sticky_rect.mTop - (sticky_rect.getHeight() - icon->getHeight())/2 );
// Should we show a group or an avatar inspector?
- bool is_group = hit_item->getValue()["is_group"].asBoolean();
+ bool is_group = hit_item->isGroup();
LLToolTip::Params params;
params.background_visible( false );
@@ -271,10 +272,10 @@ void LLNameListCtrl::addGroupNameItem(LLNameListCtrl::NameItem& item, EAddPositi
addNameItemRow(item, pos);
}
-void LLNameListCtrl::addNameItem(LLNameListCtrl::NameItem& item, EAddPosition pos)
+LLScrollListItem* LLNameListCtrl::addNameItem(LLNameListCtrl::NameItem& item, EAddPosition pos)
{
item.target = INDIVIDUAL;
- addNameItemRow(item, pos);
+ return addNameItemRow(item, pos);
}
LLScrollListItem* LLNameListCtrl::addElement(const LLSD& element, EAddPosition pos, void* userdata)
@@ -293,19 +294,12 @@ LLScrollListItem* LLNameListCtrl::addNameItemRow(
const std::string& suffix)
{
LLUUID id = name_item.value().asUUID();
- LLNameListItem* item = NULL;
-
- // Store item type so that we can invoke the proper inspector.
- // *TODO Vadim: Is there a more proper way of storing additional item data?
- {
- LLNameListCtrl::NameItem item_p(name_item);
- item_p.value = LLSD().with("uuid", id).with("is_group", name_item.target() == GROUP);
- item = new LLNameListItem(item_p);
- LLScrollListCtrl::addRow(item, item_p, pos);
- }
+ LLNameListItem* item = new LLNameListItem(name_item,name_item.target() == GROUP);
if (!item) return NULL;
+ LLScrollListCtrl::addRow(item, name_item, pos);
+
// use supplied name by default
std::string fullname = name_item.name;
switch(name_item.target)
@@ -327,16 +321,20 @@ LLScrollListItem* LLNameListCtrl::addNameItemRow(
else if (LLAvatarNameCache::get(id, &av_name))
{
if (mShortNames)
- fullname = av_name.mDisplayName;
+ fullname = av_name.getDisplayName();
else
fullname = av_name.getCompleteName();
}
else
{
// ...schedule a callback
- LLAvatarNameCache::get(id,
- boost::bind(&LLNameListCtrl::onAvatarNameCache,
- this, _1, _2));
+ // This is not correct and will likely lead to partially populated lists in cases where avatar names are not cached.
+ // *TODO : Change this to have 2 callbacks : one callback per list item and one for the whole list.
+ if (mAvatarNameCacheConnection.connected())
+ {
+ mAvatarNameCacheConnection.disconnect();
+ }
+ mAvatarNameCacheConnection = LLAvatarNameCache::get(id,boost::bind(&LLNameListCtrl::onAvatarNameCache,this, _1, _2, item->getHandle()));
}
break;
}
@@ -392,35 +390,35 @@ void LLNameListCtrl::removeNameItem(const LLUUID& agent_id)
}
void LLNameListCtrl::onAvatarNameCache(const LLUUID& agent_id,
- const LLAvatarName& av_name)
+ const LLAvatarName& av_name,
+ LLHandle<LLNameListItem> item)
{
+ mAvatarNameCacheConnection.disconnect();
+
std::string name;
if (mShortNames)
- name = av_name.mDisplayName;
+ name = av_name.getDisplayName();
else
name = av_name.getCompleteName();
- item_list::iterator iter;
- for (iter = getItemList().begin(); iter != getItemList().end(); iter++)
+ LLNameListItem* list_item = item.get();
+ if (list_item && list_item->getUUID() == agent_id)
{
- LLScrollListItem* item = *iter;
- if (item->getUUID() == agent_id)
+ LLScrollListCell* cell = list_item->getColumn(mNameColumnIndex);
+ if (cell)
{
- LLScrollListCell* cell = item->getColumn(mNameColumnIndex);
- if (cell)
- {
- cell->setValue(name);
- }
+ cell->setValue(name);
+ setNeedsSort();
}
}
-
+
dirtyColumns();
}
-void LLNameListCtrl::updateColumns()
+void LLNameListCtrl::updateColumns(bool force_update)
{
- LLScrollListCtrl::updateColumns();
+ LLScrollListCtrl::updateColumns(force_update);
if (!mNameColumn.empty())
{
@@ -431,3 +429,8 @@ void LLNameListCtrl::updateColumns()
}
}
}
+
+void LLNameListCtrl::sortByName(BOOL ascending)
+{
+ sortByColumnIndex(mNameColumnIndex,ascending);
+}
diff --git a/indra/newview/llnamelistctrl.h b/indra/newview/llnamelistctrl.h
index ca9956dc53..92e82b672d 100644..100755
--- a/indra/newview/llnamelistctrl.h
+++ b/indra/newview/llnamelistctrl.h
@@ -33,10 +33,41 @@
class LLAvatarName;
+/**
+ * LLNameListCtrl item
+ *
+ * We don't use LLScrollListItem to be able to override getUUID(), which is needed
+ * because the name list item value is not simply an UUID but a map (uuid, is_group).
+ */
+class LLNameListItem : public LLScrollListItem, public LLHandleProvider<LLNameListItem>
+{
+public:
+ bool isGroup() const { return mIsGroup; }
+ void setIsGroup(bool is_group) { mIsGroup = is_group; }
+
+protected:
+ friend class LLNameListCtrl;
+
+ LLNameListItem( const LLScrollListItem::Params& p )
+ : LLScrollListItem(p), mIsGroup(false)
+ {
+ }
+
+ LLNameListItem( const LLScrollListItem::Params& p, bool is_group )
+ : LLScrollListItem(p), mIsGroup(is_group)
+ {
+ }
+
+private:
+ bool mIsGroup;
+};
+
+
class LLNameListCtrl
: public LLScrollListCtrl, public LLInstanceTracker<LLNameListCtrl>
{
public:
+
typedef enum e_name_type
{
INDIVIDUAL,
@@ -81,13 +112,20 @@ public:
protected:
LLNameListCtrl(const Params&);
+ virtual ~LLNameListCtrl()
+ {
+ if (mAvatarNameCacheConnection.connected())
+ {
+ mAvatarNameCacheConnection.disconnect();
+ }
+ }
friend class LLUICtrlFactory;
public:
// Add a user to the list by name. It will be added, the name
// requested from the cache, and updated as necessary.
- void addNameItem(const LLUUID& agent_id, EAddPosition pos = ADD_BOTTOM,
+ LLScrollListItem* addNameItem(const LLUUID& agent_id, EAddPosition pos = ADD_BOTTOM,
BOOL enabled = TRUE, const std::string& suffix = LLStringUtil::null);
- void addNameItem(NameItem& item, EAddPosition pos = ADD_BOTTOM);
+ LLScrollListItem* addNameItem(NameItem& item, EAddPosition pos = ADD_BOTTOM);
/*virtual*/ LLScrollListItem* addElement(const LLSD& element, EAddPosition pos = ADD_BOTTOM, void* userdata = NULL);
LLScrollListItem* addNameItemRow(const NameItem& value, EAddPosition pos = ADD_BOTTOM, const std::string& suffix = LLStringUtil::null);
@@ -110,38 +148,22 @@ public:
void setAllowCallingCardDrop(BOOL b) { mAllowCallingCardDrop = b; }
- /*virtual*/ void updateColumns();
+ void sortByName(BOOL ascending);
+
+ /*virtual*/ void updateColumns(bool force_update);
/*virtual*/ void mouseOverHighlightNthItem( S32 index );
private:
void showInspector(const LLUUID& avatar_id, bool is_group);
- void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name);
+ void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name, LLHandle<LLNameListItem> item);
private:
S32 mNameColumnIndex;
std::string mNameColumn;
BOOL mAllowCallingCardDrop;
bool mShortNames; // display name only, no SLID
+ boost::signals2::connection mAvatarNameCacheConnection;
};
-/**
- * LLNameListCtrl item
- *
- * We don't use LLScrollListItem to be able to override getUUID(), which is needed
- * because the name list item value is not simply an UUID but a map (uuid, is_group).
- */
-class LLNameListItem : public LLScrollListItem
-{
-public:
- LLUUID getUUID() const { return getValue()["uuid"].asUUID(); }
-
-protected:
- friend class LLNameListCtrl;
-
- LLNameListItem( const LLScrollListItem::Params& p )
- : LLScrollListItem(p)
- {
- }
-};
#endif
diff --git a/indra/newview/llnavigationbar.cpp b/indra/newview/llnavigationbar.cpp
index 2a08cb1845..95caa2731a 100644..100755
--- a/indra/newview/llnavigationbar.cpp
+++ b/indra/newview/llnavigationbar.cpp
@@ -267,7 +267,6 @@ LLNavigationBar::LLNavigationBar()
mBtnForward(NULL),
mBtnHome(NULL),
mCmbLocation(NULL),
- mPurgeTPHistoryItems(false),
mSaveToLocationHistory(false)
{
buildFromFile( "panel_navigation_bar.xml");
@@ -338,12 +337,6 @@ void LLNavigationBar::setVisible(BOOL visible)
void LLNavigationBar::draw()
{
- if(mPurgeTPHistoryItems)
- {
- LLTeleportHistory::getInstance()->purgeItems();
- mPurgeTPHistoryItems = false;
- }
-
if (isBackgroundVisible())
{
static LLUICachedControl<S32> drop_shadow_floater ("DropShadowFloater", 0);
@@ -687,7 +680,7 @@ void LLNavigationBar::clearHistoryCache()
LLLocationHistory* lh = LLLocationHistory::getInstance();
lh->removeItems();
lh->save();
- mPurgeTPHistoryItems= true;
+ LLTeleportHistory::getInstance()->purgeItems();
}
int LLNavigationBar::getDefNavBarHeight()
diff --git a/indra/newview/llnavigationbar.h b/indra/newview/llnavigationbar.h
index e4ce9e3998..7878bab24e 100644..100755
--- a/indra/newview/llnavigationbar.h
+++ b/indra/newview/llnavigationbar.h
@@ -145,7 +145,6 @@ private:
boost::signals2::connection mTeleportFailedConnection;
boost::signals2::connection mTeleportFinishConnection;
boost::signals2::connection mHistoryMenuConnection;
- bool mPurgeTPHistoryItems;
// if true, save location to location history when teleport finishes
bool mSaveToLocationHistory;
};
diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp
deleted file mode 100644
index a7303ad035..0000000000
--- a/indra/newview/llnearbychat.cpp
+++ /dev/null
@@ -1,338 +0,0 @@
-/**
- * @file LLNearbyChat.cpp
- * @brief Nearby chat history scrolling panel implementation
- *
- * $LicenseInfo:firstyear=2009&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 "llviewerprecompiledheaders.h"
-
-#include "llnearbychat.h"
-#include "llviewercontrol.h"
-#include "llviewerwindow.h"
-#include "llrootview.h"
-//#include "llchatitemscontainerctrl.h"
-#include "lliconctrl.h"
-#include "llfloatersidepanelcontainer.h"
-#include "llfocusmgr.h"
-#include "lllogchat.h"
-#include "llresizebar.h"
-#include "llresizehandle.h"
-#include "llmenugl.h"
-#include "llviewermenu.h"//for gMenuHolder
-
-#include "llnearbychathandler.h"
-#include "llchannelmanager.h"
-
-#include "llagent.h" // gAgent
-#include "llchathistory.h"
-#include "llstylemap.h"
-
-#include "llavatarnamecache.h"
-
-#include "lldraghandle.h"
-
-#include "llnearbychatbar.h"
-#include "llfloaterreg.h"
-#include "lltrans.h"
-
-static const S32 RESIZE_BAR_THICKNESS = 3;
-
-
-static LLRegisterPanelClassWrapper<LLNearbyChat> t_panel_nearby_chat("panel_nearby_chat");
-
-LLNearbyChat::LLNearbyChat(const LLNearbyChat::Params& p)
-: LLPanel(p),
- mChatHistory(NULL)
-{
-}
-
-BOOL LLNearbyChat::postBuild()
-{
- //menu
- LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
- LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
-
- enable_registrar.add("NearbyChat.Check", boost::bind(&LLNearbyChat::onNearbyChatCheckContextMenuItem, this, _2));
- registrar.add("NearbyChat.Action", boost::bind(&LLNearbyChat::onNearbyChatContextMenuItemClicked, this, _2));
-
-
- LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_nearby_chat.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
- if(menu)
- mPopupMenuHandle = menu->getHandle();
-
- gSavedSettings.declareS32("nearbychat_showicons_and_names",2,"NearByChat header settings",true);
-
- mChatHistory = getChild<LLChatHistory>("chat_history");
-
- if(!LLPanel::postBuild())
- return false;
-
- return true;
-}
-
-std::string appendTime()
-{
- time_t utc_time;
- utc_time = time_corrected();
- std::string timeStr ="["+ LLTrans::getString("TimeHour")+"]:["
- +LLTrans::getString("TimeMin")+"]";
-
- LLSD substitution;
-
- substitution["datetime"] = (S32) utc_time;
- LLStringUtil::format (timeStr, substitution);
-
- return timeStr;
-}
-
-
-void LLNearbyChat::addMessage(const LLChat& chat,bool archive,const LLSD &args)
-{
- LLChat& tmp_chat = const_cast<LLChat&>(chat);
-
- if(tmp_chat.mTimeStr.empty())
- tmp_chat.mTimeStr = appendTime();
-
- bool use_plain_text_chat_history = gSavedSettings.getBOOL("PlainTextChatHistory");
-
- if (!chat.mMuted)
- {
- tmp_chat.mFromName = chat.mFromName;
- LLSD chat_args = args;
- chat_args["use_plain_text_chat_history"] = use_plain_text_chat_history;
- mChatHistory->appendMessage(chat, chat_args);
- }
-
- if(archive)
- {
- mMessageArchive.push_back(chat);
- if(mMessageArchive.size()>200)
- mMessageArchive.erase(mMessageArchive.begin());
- }
-
- if (args["do_not_log"].asBoolean())
- {
- return;
- }
-
- if (gSavedPerAccountSettings.getBOOL("LogNearbyChat"))
- {
- std::string from_name = chat.mFromName;
-
- if (chat.mSourceType == CHAT_SOURCE_AGENT)
- {
- // if the chat is coming from an agent, log the complete name
- LLAvatarName av_name;
- LLAvatarNameCache::get(chat.mFromID, &av_name);
-
- if (!av_name.mIsDisplayNameDefault)
- {
- from_name = av_name.getCompleteName();
- }
- }
-
- LLLogChat::saveHistory("chat", from_name, chat.mFromID, chat.mText);
- }
-}
-
-void LLNearbyChat::onNearbySpeakers()
-{
- LLSD param;
- param["people_panel_tab_name"] = "nearby_panel";
- LLFloaterSidePanelContainer::showPanel("people", "panel_people", param);
-}
-
-
-void LLNearbyChat::onNearbyChatContextMenuItemClicked(const LLSD& userdata)
-{
-}
-bool LLNearbyChat::onNearbyChatCheckContextMenuItem(const LLSD& userdata)
-{
- std::string str = userdata.asString();
- if(str == "nearby_people")
- onNearbySpeakers();
- return false;
-}
-
-void LLNearbyChat::removeScreenChat()
-{
- LLNotificationsUI::LLScreenChannelBase* chat_channel = LLNotificationsUI::LLChannelManager::getInstance()->findChannelByID(LLUUID(gSavedSettings.getString("NearByChatChannelUUID")));
- if(chat_channel)
- {
- chat_channel->removeToastsFromChannel();
- }
-}
-
-void LLNearbyChat::setVisible(BOOL visible)
-{
- if(visible)
- {
- removeScreenChat();
- }
-
- LLPanel::setVisible(visible);
-}
-
-
-void LLNearbyChat::getAllowedRect(LLRect& rect)
-{
- rect = gViewerWindow->getWorldViewRectScaled();
-}
-
-void LLNearbyChat::updateChatHistoryStyle()
-{
- mChatHistory->clear();
-
- LLSD do_not_log;
- do_not_log["do_not_log"] = true;
- for(std::vector<LLChat>::iterator it = mMessageArchive.begin();it!=mMessageArchive.end();++it)
- {
- // Update the messages without re-writing them to a log file.
- addMessage(*it,false, do_not_log);
- }
-}
-
-//static
-void LLNearbyChat::processChatHistoryStyleUpdate(const LLSD& newvalue)
-{
- LLFloater* chat_bar = LLFloaterReg::getInstance("chat_bar");
- LLNearbyChat* nearby_chat = chat_bar->findChild<LLNearbyChat>("nearby_chat");
- if(nearby_chat)
- nearby_chat->updateChatHistoryStyle();
-}
-
-bool isWordsName(const std::string& name)
-{
- // checking to see if it's display name plus username in parentheses
- S32 open_paren = name.find(" (", 0);
- S32 close_paren = name.find(')', 0);
-
- if (open_paren != std::string::npos &&
- close_paren == name.length()-1)
- {
- return true;
- }
- else
- {
- //checking for a single space
- S32 pos = name.find(' ', 0);
- return std::string::npos != pos && name.rfind(' ', name.length()) == pos && 0 != pos && name.length()-1 != pos;
- }
-}
-
-void LLNearbyChat::loadHistory()
-{
- LLSD do_not_log;
- do_not_log["do_not_log"] = true;
-
- std::list<LLSD> history;
- LLLogChat::loadAllHistory("chat", history);
-
- std::list<LLSD>::const_iterator it = history.begin();
- while (it != history.end())
- {
- const LLSD& msg = *it;
-
- std::string from = msg[IM_FROM];
- LLUUID from_id;
- if (msg[IM_FROM_ID].isDefined())
- {
- from_id = msg[IM_FROM_ID].asUUID();
- }
- else
- {
- std::string legacy_name = gCacheName->buildLegacyName(from);
- gCacheName->getUUID(legacy_name, from_id);
- }
-
- LLChat chat;
- chat.mFromName = from;
- chat.mFromID = from_id;
- chat.mText = msg[IM_TEXT].asString();
- chat.mTimeStr = msg[IM_TIME].asString();
- chat.mChatStyle = CHAT_STYLE_HISTORY;
-
- chat.mSourceType = CHAT_SOURCE_AGENT;
- if (from_id.isNull() && SYSTEM_FROM == from)
- {
- chat.mSourceType = CHAT_SOURCE_SYSTEM;
-
- }
- else if (from_id.isNull())
- {
- chat.mSourceType = isWordsName(from) ? CHAT_SOURCE_UNKNOWN : CHAT_SOURCE_OBJECT;
- }
-
- addMessage(chat, true, do_not_log);
-
- it++;
- }
-}
-
-//static
-LLNearbyChat* LLNearbyChat::getInstance()
-{
- LLFloater* chat_bar = LLFloaterReg::getInstance("chat_bar");
- return chat_bar->findChild<LLNearbyChat>("nearby_chat");
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-void LLNearbyChat::onFocusReceived()
-{
- setBackgroundOpaque(true);
- LLPanel::onFocusReceived();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-void LLNearbyChat::onFocusLost()
-{
- setBackgroundOpaque(false);
- LLPanel::onFocusLost();
-}
-
-BOOL LLNearbyChat::handleMouseDown(S32 x, S32 y, MASK mask)
-{
- //fix for EXT-6625
- //highlight NearbyChat history whenever mouseclick happen in NearbyChat
- //setting focus to eidtor will force onFocusLost() call that in its turn will change
- //background opaque. This all happenn since NearByChat is "chrome" and didn't process focus change.
-
- if(mChatHistory)
- mChatHistory->setFocus(TRUE);
- return LLPanel::handleMouseDown(x, y, mask);
-}
-
-void LLNearbyChat::draw()
-{
- // *HACK: Update transparency type depending on whether our children have focus.
- // This is needed because this floater is chrome and thus cannot accept focus, so
- // the transparency type setting code from LLFloater::setFocus() isn't reached.
- if (getTransparencyType() != TT_DEFAULT)
- {
- setTransparencyType(hasFocus() ? TT_ACTIVE : TT_INACTIVE);
- }
-
- LLPanel::draw();
-}
diff --git a/indra/newview/llnearbychat.h b/indra/newview/llnearbychat.h
deleted file mode 100644
index 7c5975cbc5..0000000000
--- a/indra/newview/llnearbychat.h
+++ /dev/null
@@ -1,83 +0,0 @@
- /**
- * @file llnearbychat.h
- * @brief nearby chat history scrolling panel implementation
- *
- * $LicenseInfo:firstyear=2004&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$
- */
-
-#ifndef LL_LLNEARBYCHAT_H_
-#define LL_LLNEARBYCHAT_H_
-
-#include "llscrollbar.h"
-#include "llviewerchat.h"
-#include "llfloater.h"
-
-class LLResizeBar;
-class LLChatHistory;
-
-class LLNearbyChat: public LLPanel
-{
-public:
- LLNearbyChat(const Params& p = LLPanel::getDefaultParams());
-
- BOOL postBuild ();
-
- /** @param archive true - to save a message to the chat history log */
- void addMessage (const LLChat& message,bool archive = true, const LLSD &args = LLSD());
- void onNearbyChatContextMenuItemClicked(const LLSD& userdata);
- bool onNearbyChatCheckContextMenuItem(const LLSD& userdata);
-
- virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
- virtual void draw();
-
- // focus overrides
- /*virtual*/ void onFocusLost();
- /*virtual*/ void onFocusReceived();
-
- /*virtual*/ void setVisible(BOOL visible);
-
- virtual void updateChatHistoryStyle();
-
- static void processChatHistoryStyleUpdate(const LLSD& newvalue);
-
- void loadHistory();
-
- static LLNearbyChat* getInstance();
- void removeScreenChat();
-
-private:
-
- void getAllowedRect (LLRect& rect);
-
- void onNearbySpeakers ();
-
-
-private:
- LLHandle<LLView> mPopupMenuHandle;
- LLChatHistory* mChatHistory;
-
- std::vector<LLChat> mMessageArchive;
-};
-
-#endif
-
-
diff --git a/indra/newview/llnearbychatbar.cpp b/indra/newview/llnearbychatbar.cpp
deleted file mode 100644
index b4224e30e6..0000000000
--- a/indra/newview/llnearbychatbar.cpp
+++ /dev/null
@@ -1,672 +0,0 @@
-/**
- * @file llnearbychatbar.cpp
- * @brief LLNearbyChatBar class implementation
- *
- * $LicenseInfo:firstyear=2002&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 "llviewerprecompiledheaders.h"
-
-#include "message.h"
-
-#include "llappviewer.h"
-#include "llfloaterreg.h"
-#include "lltrans.h"
-
-#include "llfirstuse.h"
-#include "llnearbychatbar.h"
-#include "llagent.h"
-#include "llgesturemgr.h"
-#include "llmultigesture.h"
-#include "llkeyboard.h"
-#include "llanimationstates.h"
-#include "llviewerstats.h"
-#include "llcommandhandler.h"
-#include "llviewercontrol.h"
-#include "llnavigationbar.h"
-#include "llwindow.h"
-#include "llviewerwindow.h"
-#include "llrootview.h"
-#include "llviewerchat.h"
-#include "llnearbychat.h"
-#include "lltranslate.h"
-
-#include "llresizehandle.h"
-
-S32 LLNearbyChatBar::sLastSpecialChatChannel = 0;
-
-const S32 EXPANDED_HEIGHT = 300;
-const S32 COLLAPSED_HEIGHT = 60;
-const S32 EXPANDED_MIN_HEIGHT = 150;
-
-// legacy callback glue
-void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 channel);
-
-struct LLChatTypeTrigger {
- std::string name;
- EChatType type;
-};
-
-static LLChatTypeTrigger sChatTypeTriggers[] = {
- { "/whisper" , CHAT_TYPE_WHISPER},
- { "/shout" , CHAT_TYPE_SHOUT}
-};
-
-LLNearbyChatBar::LLNearbyChatBar(const LLSD& key)
-: LLFloater(key),
- mChatBox(NULL),
- mNearbyChat(NULL),
- mOutputMonitor(NULL),
- mSpeakerMgr(NULL),
- mExpandedHeight(COLLAPSED_HEIGHT + EXPANDED_HEIGHT)
-{
- mSpeakerMgr = LLLocalSpeakerMgr::getInstance();
-}
-
-//virtual
-BOOL LLNearbyChatBar::postBuild()
-{
- mChatBox = getChild<LLLineEditor>("chat_box");
-
- mChatBox->setCommitCallback(boost::bind(&LLNearbyChatBar::onChatBoxCommit, this));
- mChatBox->setKeystrokeCallback(&onChatBoxKeystroke, this);
- mChatBox->setFocusLostCallback(boost::bind(&onChatBoxFocusLost, _1, this));
- mChatBox->setFocusReceivedCallback(boost::bind(&LLNearbyChatBar::onChatBoxFocusReceived, this));
-
- mChatBox->setIgnoreArrowKeys( FALSE );
- mChatBox->setCommitOnFocusLost( FALSE );
- mChatBox->setRevertOnEsc( FALSE );
- mChatBox->setIgnoreTab(TRUE);
- mChatBox->setPassDelete(TRUE);
- mChatBox->setReplaceNewlinesWithSpaces(FALSE);
- mChatBox->setEnableLineHistory(TRUE);
- mChatBox->setFont(LLViewerChat::getChatFont());
-
- mNearbyChat = getChildView("nearby_chat");
-
- LLUICtrl* show_btn = getChild<LLUICtrl>("show_nearby_chat");
- show_btn->setCommitCallback(boost::bind(&LLNearbyChatBar::onToggleNearbyChatPanel, this));
-
- mOutputMonitor = getChild<LLOutputMonitorCtrl>("chat_zone_indicator");
- mOutputMonitor->setVisible(FALSE);
-
- gSavedSettings.declareBOOL("nearbychat_history_visibility", mNearbyChat->getVisible(), "Visibility state of nearby chat history", TRUE);
-
- mNearbyChat->setVisible(gSavedSettings.getBOOL("nearbychat_history_visibility"));
-
- // Register for font change notifications
- LLViewerChat::setFontChangedCallback(boost::bind(&LLNearbyChatBar::onChatFontChange, this, _1));
-
- enableResizeCtrls(true, true, false);
-
- return TRUE;
-}
-
-// virtual
-void LLNearbyChatBar::onOpen(const LLSD& key)
-{
- showTranslationCheckbox(LLTranslate::isTranslationConfigured());
-}
-
-bool LLNearbyChatBar::applyRectControl()
-{
- bool rect_controlled = LLFloater::applyRectControl();
-
- if (!mNearbyChat->getVisible())
- {
- reshape(getRect().getWidth(), getMinHeight());
- enableResizeCtrls(true, true, false);
- }
- else
- {
- enableResizeCtrls(true);
- setResizeLimits(getMinWidth(), EXPANDED_MIN_HEIGHT);
- }
-
- return rect_controlled;
-}
-
-void LLNearbyChatBar::onChatFontChange(LLFontGL* fontp)
-{
- // Update things with the new font whohoo
- if (mChatBox)
- {
- mChatBox->setFont(fontp);
- }
-}
-
-//static
-LLNearbyChatBar* LLNearbyChatBar::getInstance()
-{
- return LLFloaterReg::getTypedInstance<LLNearbyChatBar>("chat_bar");
-}
-
-void LLNearbyChatBar::showHistory()
-{
- openFloater();
-
- if (!getChildView("nearby_chat")->getVisible())
- {
- onToggleNearbyChatPanel();
- }
-}
-
-void LLNearbyChatBar::showTranslationCheckbox(BOOL show)
-{
- getChild<LLUICtrl>("translate_chat_checkbox_lp")->setVisible(show);
-}
-
-void LLNearbyChatBar::draw()
-{
- displaySpeakingIndicator();
- LLFloater::draw();
-}
-
-std::string LLNearbyChatBar::getCurrentChat()
-{
- return mChatBox ? mChatBox->getText() : LLStringUtil::null;
-}
-
-// virtual
-BOOL LLNearbyChatBar::handleKeyHere( KEY key, MASK mask )
-{
- BOOL handled = FALSE;
-
- if( KEY_RETURN == key && mask == MASK_CONTROL)
- {
- // shout
- sendChat(CHAT_TYPE_SHOUT);
- handled = TRUE;
- }
-
- return handled;
-}
-
-BOOL LLNearbyChatBar::matchChatTypeTrigger(const std::string& in_str, std::string* out_str)
-{
- U32 in_len = in_str.length();
- S32 cnt = sizeof(sChatTypeTriggers) / sizeof(*sChatTypeTriggers);
-
- for (S32 n = 0; n < cnt; n++)
- {
- if (in_len > sChatTypeTriggers[n].name.length())
- continue;
-
- std::string trigger_trunc = sChatTypeTriggers[n].name;
- LLStringUtil::truncate(trigger_trunc, in_len);
-
- if (!LLStringUtil::compareInsensitive(in_str, trigger_trunc))
- {
- *out_str = sChatTypeTriggers[n].name;
- return TRUE;
- }
- }
-
- return FALSE;
-}
-
-void LLNearbyChatBar::onChatBoxKeystroke(LLLineEditor* caller, void* userdata)
-{
- LLFirstUse::otherAvatarChatFirst(false);
-
- LLNearbyChatBar* self = (LLNearbyChatBar *)userdata;
-
- LLWString raw_text = self->mChatBox->getWText();
-
- // Can't trim the end, because that will cause autocompletion
- // to eat trailing spaces that might be part of a gesture.
- LLWStringUtil::trimHead(raw_text);
-
- S32 length = raw_text.length();
-
- if( (length > 0) && (raw_text[0] != '/') ) // forward slash is used for escape (eg. emote) sequences
- {
- gAgent.startTyping();
- }
- else
- {
- gAgent.stopTyping();
- }
-
- /* Doesn't work -- can't tell the difference between a backspace
- that killed the selection vs. backspace at the end of line.
- if (length > 1
- && text[0] == '/'
- && key == KEY_BACKSPACE)
- {
- // the selection will already be deleted, but we need to trim
- // off the character before
- std::string new_text = raw_text.substr(0, length-1);
- self->mInputEditor->setText( new_text );
- self->mInputEditor->setCursorToEnd();
- length = length - 1;
- }
- */
-
- KEY key = gKeyboard->currentKey();
-
- // Ignore "special" keys, like backspace, arrows, etc.
- if (length > 1
- && raw_text[0] == '/'
- && key < KEY_SPECIAL)
- {
- // we're starting a gesture, attempt to autocomplete
-
- std::string utf8_trigger = wstring_to_utf8str(raw_text);
- std::string utf8_out_str(utf8_trigger);
-
- if (LLGestureMgr::instance().matchPrefix(utf8_trigger, &utf8_out_str))
- {
- std::string rest_of_match = utf8_out_str.substr(utf8_trigger.size());
- self->mChatBox->setText(utf8_trigger + rest_of_match); // keep original capitalization for user-entered part
- S32 outlength = self->mChatBox->getLength(); // in characters
-
- // Select to end of line, starting from the character
- // after the last one the user typed.
- self->mChatBox->setSelection(length, outlength);
- }
- else if (matchChatTypeTrigger(utf8_trigger, &utf8_out_str))
- {
- std::string rest_of_match = utf8_out_str.substr(utf8_trigger.size());
- self->mChatBox->setText(utf8_trigger + rest_of_match + " "); // keep original capitalization for user-entered part
- self->mChatBox->setCursorToEnd();
- }
-
- //llinfos << "GESTUREDEBUG " << trigger
- // << " len " << length
- // << " outlen " << out_str.getLength()
- // << llendl;
- }
-}
-
-// static
-void LLNearbyChatBar::onChatBoxFocusLost(LLFocusableElement* caller, void* userdata)
-{
- // stop typing animation
- gAgent.stopTyping();
-}
-
-void LLNearbyChatBar::onChatBoxFocusReceived()
-{
- mChatBox->setEnabled(!gDisconnected);
-}
-
-EChatType LLNearbyChatBar::processChatTypeTriggers(EChatType type, std::string &str)
-{
- U32 length = str.length();
- S32 cnt = sizeof(sChatTypeTriggers) / sizeof(*sChatTypeTriggers);
-
- for (S32 n = 0; n < cnt; n++)
- {
- if (length >= sChatTypeTriggers[n].name.length())
- {
- std::string trigger = str.substr(0, sChatTypeTriggers[n].name.length());
-
- if (!LLStringUtil::compareInsensitive(trigger, sChatTypeTriggers[n].name))
- {
- U32 trigger_length = sChatTypeTriggers[n].name.length();
-
- // It's to remove space after trigger name
- if (length > trigger_length && str[trigger_length] == ' ')
- trigger_length++;
-
- str = str.substr(trigger_length, length);
-
- if (CHAT_TYPE_NORMAL == type)
- return sChatTypeTriggers[n].type;
- else
- break;
- }
- }
- }
-
- return type;
-}
-
-void LLNearbyChatBar::sendChat( EChatType type )
-{
- if (mChatBox)
- {
- LLWString text = mChatBox->getConvertedText();
- if (!text.empty())
- {
- // store sent line in history, duplicates will get filtered
- mChatBox->updateHistory();
- // Check if this is destined for another channel
- S32 channel = 0;
- stripChannelNumber(text, &channel);
-
- std::string utf8text = wstring_to_utf8str(text);
- // Try to trigger a gesture, if not chat to a script.
- std::string utf8_revised_text;
- if (0 == channel)
- {
- // discard returned "found" boolean
- LLGestureMgr::instance().triggerAndReviseString(utf8text, &utf8_revised_text);
- }
- else
- {
- utf8_revised_text = utf8text;
- }
-
- utf8_revised_text = utf8str_trim(utf8_revised_text);
-
- type = processChatTypeTriggers(type, utf8_revised_text);
-
- if (!utf8_revised_text.empty())
- {
- // Chat with animation
- sendChatFromViewer(utf8_revised_text, type, TRUE);
- }
- }
-
- mChatBox->setText(LLStringExplicit(""));
- }
-
- gAgent.stopTyping();
-
- // If the user wants to stop chatting on hitting return, lose focus
- // and go out of chat mode.
- if (gSavedSettings.getBOOL("CloseChatOnReturn"))
- {
- stopChat();
- }
-}
-
-
-void LLNearbyChatBar::onToggleNearbyChatPanel()
-{
- LLView* nearby_chat = getChildView("nearby_chat");
-
- if (nearby_chat->getVisible())
- {
- if (!isMinimized())
- {
- mExpandedHeight = getRect().getHeight();
- }
- setResizeLimits(getMinWidth(), COLLAPSED_HEIGHT);
- nearby_chat->setVisible(FALSE);
- reshape(getRect().getWidth(), COLLAPSED_HEIGHT);
- enableResizeCtrls(true, true, false);
- storeRectControl();
- }
- else
- {
- nearby_chat->setVisible(TRUE);
- setResizeLimits(getMinWidth(), EXPANDED_MIN_HEIGHT);
- reshape(getRect().getWidth(), mExpandedHeight);
- enableResizeCtrls(true);
- storeRectControl();
- }
-
- gSavedSettings.setBOOL("nearbychat_history_visibility", mNearbyChat->getVisible());
-}
-
-void LLNearbyChatBar::setMinimized(BOOL b)
-{
- LLNearbyChat* nearby_chat = getChild<LLNearbyChat>("nearby_chat");
- // when unminimizing with nearby chat visible, go ahead and kill off screen chats
- if (!b && nearby_chat->getVisible())
- {
- nearby_chat->removeScreenChat();
- }
- LLFloater::setMinimized(b);
-}
-
-void LLNearbyChatBar::onChatBoxCommit()
-{
- if (mChatBox->getText().length() > 0)
- {
- sendChat(CHAT_TYPE_NORMAL);
- }
-
- gAgent.stopTyping();
-}
-
-void LLNearbyChatBar::displaySpeakingIndicator()
-{
- LLSpeakerMgr::speaker_list_t speaker_list;
- LLUUID id;
-
- id.setNull();
- mSpeakerMgr->update(TRUE);
- mSpeakerMgr->getSpeakerList(&speaker_list, FALSE);
-
- for (LLSpeakerMgr::speaker_list_t::iterator i = speaker_list.begin(); i != speaker_list.end(); ++i)
- {
- LLPointer<LLSpeaker> s = *i;
- if (s->mSpeechVolume > 0 || s->mStatus == LLSpeaker::STATUS_SPEAKING)
- {
- id = s->mID;
- break;
- }
- }
-
- if (!id.isNull())
- {
- mOutputMonitor->setVisible(TRUE);
- mOutputMonitor->setSpeakerId(id);
- }
- else
- {
- mOutputMonitor->setVisible(FALSE);
- }
-}
-
-void LLNearbyChatBar::sendChatFromViewer(const std::string &utf8text, EChatType type, BOOL animate)
-{
- sendChatFromViewer(utf8str_to_wstring(utf8text), type, animate);
-}
-
-void LLNearbyChatBar::sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL animate)
-{
- // Look for "/20 foo" channel chats.
- S32 channel = 0;
- LLWString out_text = stripChannelNumber(wtext, &channel);
- std::string utf8_out_text = wstring_to_utf8str(out_text);
- std::string utf8_text = wstring_to_utf8str(wtext);
-
- utf8_text = utf8str_trim(utf8_text);
- if (!utf8_text.empty())
- {
- utf8_text = utf8str_truncate(utf8_text, MAX_STRING - 1);
- }
-
- // Don't animate for chats people can't hear (chat to scripts)
- if (animate && (channel == 0))
- {
- if (type == CHAT_TYPE_WHISPER)
- {
- lldebugs << "You whisper " << utf8_text << llendl;
- gAgent.sendAnimationRequest(ANIM_AGENT_WHISPER, ANIM_REQUEST_START);
- }
- else if (type == CHAT_TYPE_NORMAL)
- {
- lldebugs << "You say " << utf8_text << llendl;
- gAgent.sendAnimationRequest(ANIM_AGENT_TALK, ANIM_REQUEST_START);
- }
- else if (type == CHAT_TYPE_SHOUT)
- {
- lldebugs << "You shout " << utf8_text << llendl;
- gAgent.sendAnimationRequest(ANIM_AGENT_SHOUT, ANIM_REQUEST_START);
- }
- else
- {
- llinfos << "send_chat_from_viewer() - invalid volume" << llendl;
- return;
- }
- }
- else
- {
- if (type != CHAT_TYPE_START && type != CHAT_TYPE_STOP)
- {
- lldebugs << "Channel chat: " << utf8_text << llendl;
- }
- }
-
- send_chat_from_viewer(utf8_out_text, type, channel);
-}
-
-// static
-void LLNearbyChatBar::startChat(const char* line)
-{
- LLNearbyChatBar* cb = LLNearbyChatBar::getInstance();
-
- if (!cb )
- return;
-
- cb->setVisible(TRUE);
- cb->setFocus(TRUE);
- cb->mChatBox->setFocus(TRUE);
-
- if (line)
- {
- std::string line_string(line);
- cb->mChatBox->setText(line_string);
- }
-
- cb->mChatBox->setCursorToEnd();
-}
-
-// Exit "chat mode" and do the appropriate focus changes
-// static
-void LLNearbyChatBar::stopChat()
-{
- LLNearbyChatBar* cb = LLNearbyChatBar::getInstance();
-
- if (!cb)
- return;
-
- cb->mChatBox->setFocus(FALSE);
-
- // stop typing animation
- gAgent.stopTyping();
-}
-
-// If input of the form "/20foo" or "/20 foo", returns "foo" and channel 20.
-// Otherwise returns input and channel 0.
-LLWString LLNearbyChatBar::stripChannelNumber(const LLWString &mesg, S32* channel)
-{
- if (mesg[0] == '/'
- && mesg[1] == '/')
- {
- // This is a "repeat channel send"
- *channel = sLastSpecialChatChannel;
- return mesg.substr(2, mesg.length() - 2);
- }
- else if (mesg[0] == '/'
- && mesg[1]
- && LLStringOps::isDigit(mesg[1]))
- {
- // This a special "/20" speak on a channel
- S32 pos = 0;
-
- // Copy the channel number into a string
- LLWString channel_string;
- llwchar c;
- do
- {
- c = mesg[pos+1];
- channel_string.push_back(c);
- pos++;
- }
- while(c && pos < 64 && LLStringOps::isDigit(c));
-
- // Move the pointer forward to the first non-whitespace char
- // Check isspace before looping, so we can handle "/33foo"
- // as well as "/33 foo"
- while(c && iswspace(c))
- {
- c = mesg[pos+1];
- pos++;
- }
-
- sLastSpecialChatChannel = strtol(wstring_to_utf8str(channel_string).c_str(), NULL, 10);
- *channel = sLastSpecialChatChannel;
- return mesg.substr(pos, mesg.length() - pos);
- }
- else
- {
- // This is normal chat.
- *channel = 0;
- return mesg;
- }
-}
-
-void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 channel)
-{
- LLMessageSystem* msg = gMessageSystem;
- msg->newMessageFast(_PREHASH_ChatFromViewer);
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- msg->nextBlockFast(_PREHASH_ChatData);
- msg->addStringFast(_PREHASH_Message, utf8_out_text);
- msg->addU8Fast(_PREHASH_Type, type);
- msg->addS32("Channel", channel);
-
- gAgent.sendReliableMessage();
-
- LLViewerStats::getInstance()->incStat(LLViewerStats::ST_CHAT_COUNT);
-}
-
-class LLChatCommandHandler : public LLCommandHandler
-{
-public:
- // not allowed from outside the app
- LLChatCommandHandler() : LLCommandHandler("chat", UNTRUSTED_BLOCK) { }
-
- // Your code here
- bool handle(const LLSD& tokens, const LLSD& query_map,
- LLMediaCtrl* web)
- {
- bool retval = false;
- // Need at least 2 tokens to have a valid message.
- if (tokens.size() < 2)
- {
- retval = false;
- }
- else
- {
- S32 channel = tokens[0].asInteger();
- // VWR-19499 Restrict function to chat channels greater than 0.
- if ((channel > 0) && (channel < CHAT_CHANNEL_DEBUG))
- {
- retval = true;
- // Send unescaped message, see EXT-6353.
- std::string unescaped_mesg (LLURI::unescape(tokens[1].asString()));
- send_chat_from_viewer(unescaped_mesg, CHAT_TYPE_NORMAL, channel);
- }
- else
- {
- retval = false;
- // Tell us this is an unsupported SLurl.
- }
- }
- return retval;
- }
-};
-
-// Creating the object registers with the dispatcher.
-LLChatCommandHandler gChatHandler;
-
-
diff --git a/indra/newview/llnearbychatbar.h b/indra/newview/llnearbychatbar.h
deleted file mode 100644
index 8547cf0bce..0000000000
--- a/indra/newview/llnearbychatbar.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/**
- * @file llnearbychatbar.h
- * @brief LLNearbyChatBar class definition
- *
- * $LicenseInfo:firstyear=2002&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$
- */
-
-#ifndef LL_LLNEARBYCHATBAR_H
-#define LL_LLNEARBYCHATBAR_H
-
-#include "llfloater.h"
-#include "llcombobox.h"
-#include "llgesturemgr.h"
-#include "llchat.h"
-#include "llvoiceclient.h"
-#include "lloutputmonitorctrl.h"
-#include "llspeakers.h"
-
-class LLNearbyChatBar : public LLFloater
-{
-public:
- // constructor for inline chat-bars (e.g. hosted in chat history window)
- LLNearbyChatBar(const LLSD& key);
- ~LLNearbyChatBar() {}
-
- virtual BOOL postBuild();
- /*virtual*/ void onOpen(const LLSD& key);
-
- static LLNearbyChatBar* getInstance();
-
- LLLineEditor* getChatBox() { return mChatBox; }
-
- virtual void draw();
-
- std::string getCurrentChat();
- virtual BOOL handleKeyHere( KEY key, MASK mask );
-
- static void startChat(const char* line);
- static void stopChat();
-
- static void sendChatFromViewer(const std::string &utf8text, EChatType type, BOOL animate);
- static void sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL animate);
-
- void showHistory();
- void showTranslationCheckbox(BOOL show);
- /*virtual*/void setMinimized(BOOL b);
-
-protected:
- static BOOL matchChatTypeTrigger(const std::string& in_str, std::string* out_str);
- static void onChatBoxKeystroke(LLLineEditor* caller, void* userdata);
- static void onChatBoxFocusLost(LLFocusableElement* caller, void* userdata);
- void onChatBoxFocusReceived();
-
- void sendChat( EChatType type );
- void onChatBoxCommit();
- void onChatFontChange(LLFontGL* fontp);
-
- /* virtual */ bool applyRectControl();
-
- void onToggleNearbyChatPanel();
-
- static LLWString stripChannelNumber(const LLWString &mesg, S32* channel);
- EChatType processChatTypeTriggers(EChatType type, std::string &str);
-
- void displaySpeakingIndicator();
-
- // Which non-zero channel did we last chat on?
- static S32 sLastSpecialChatChannel;
-
- LLLineEditor* mChatBox;
- LLView* mNearbyChat;
- LLOutputMonitorCtrl* mOutputMonitor;
- LLLocalSpeakerMgr* mSpeakerMgr;
-
- S32 mExpandedHeight;
-};
-
-#endif
diff --git a/indra/newview/llnearbychatbarlistener.cpp b/indra/newview/llnearbychatbarlistener.cpp
deleted file mode 100644
index a63e1fb76e..0000000000
--- a/indra/newview/llnearbychatbarlistener.cpp
+++ /dev/null
@@ -1,100 +0,0 @@
-/**
- * @file llnearbychatbarlistener.cpp
- * @author Dave Simmons
- * @date 2011-03-15
- * @brief Implementation for LLNearbyChatBarListener.
- *
- * $LicenseInfo:firstyear=2011&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2011, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-#include "llnearbychatbarlistener.h"
-#include "llnearbychatbar.h"
-
-#include "llagent.h"
-#include "llchat.h"
-
-
-
-LLNearbyChatBarListener::LLNearbyChatBarListener(LLNearbyChatBar & chatbar)
- : LLEventAPI("LLChatBar",
- "LLChatBar listener to (e.g.) sendChat, etc."),
- mChatbar(chatbar)
-{
- add("sendChat",
- "Send chat to the simulator:\n"
- "[\"message\"] chat message text [required]\n"
- "[\"channel\"] chat channel number [default = 0]\n"
- "[\"type\"] chat type \"whisper\", \"normal\", \"shout\" [default = \"normal\"]",
- &LLNearbyChatBarListener::sendChat);
-}
-
-
-// "sendChat" command
-void LLNearbyChatBarListener::sendChat(LLSD const & chat_data) const
-{
- // Extract the data
- std::string chat_text = chat_data["message"].asString();
-
- S32 channel = 0;
- if (chat_data.has("channel"))
- {
- channel = chat_data["channel"].asInteger();
- if (channel < 0 || channel >= CHAT_CHANNEL_DEBUG)
- { // Use 0 up to (but not including) CHAT_CHANNEL_DEBUG
- channel = 0;
- }
- }
-
- EChatType type_o_chat = CHAT_TYPE_NORMAL;
- if (chat_data.has("type"))
- {
- std::string type_string = chat_data["type"].asString();
- if (type_string == "whisper")
- {
- type_o_chat = CHAT_TYPE_WHISPER;
- }
- else if (type_string == "shout")
- {
- type_o_chat = CHAT_TYPE_SHOUT;
- }
- }
-
- // Have to prepend /42 style channel numbers
- std::string chat_to_send;
- if (channel == 0)
- {
- chat_to_send = chat_text;
- }
- else
- {
- chat_to_send += "/";
- chat_to_send += chat_data["channel"].asString();
- chat_to_send += " ";
- chat_to_send += chat_text;
- }
-
- // Send it as if it was typed in
- mChatbar.sendChatFromViewer(chat_to_send, type_o_chat, (BOOL)(channel == 0));
-}
-
diff --git a/indra/newview/llnearbychatbarlistener.h b/indra/newview/llnearbychatbarlistener.h
deleted file mode 100644
index 9af9bc1f7b..0000000000
--- a/indra/newview/llnearbychatbarlistener.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
- * @file llnearbychatbarlistener.h
- * @author Dave Simmons
- * @date 2011-03-15
- * @brief Class definition for LLNearbyChatBarListener.
- *
- * $LicenseInfo:firstyear=2011&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2011, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-
-#ifndef LL_LLNEARBYCHATBARLISTENER_H
-#define LL_LLNEARBYCHATBARLISTENER_H
-
-#include "lleventapi.h"
-
-class LLSD;
-class LLNearbyChatBar;
-
-class LLNearbyChatBarListener : public LLEventAPI
-{
-public:
- LLNearbyChatBarListener(LLNearbyChatBar & chatbar);
-
-private:
- void sendChat(LLSD const & chat_data) const;
-
- LLNearbyChatBar & mChatbar;
-};
-
-#endif // LL_LLNEARBYCHATBARLISTENER_H
-
diff --git a/indra/newview/llnearbychathandler.cpp b/indra/newview/llnearbychathandler.cpp
deleted file mode 100644
index 600fd395fb..0000000000
--- a/indra/newview/llnearbychathandler.cpp
+++ /dev/null
@@ -1,635 +0,0 @@
-/**
- * @file LLNearbyChatHandler.cpp
- * @brief Nearby chat notification managment
- *
- * $LicenseInfo:firstyear=2009&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 "llviewerprecompiledheaders.h"
-
-#include "llagentdata.h" // for gAgentID
-#include "llnearbychathandler.h"
-
-#include "llchatitemscontainerctrl.h"
-#include "llfirstuse.h"
-#include "llfloaterscriptdebug.h"
-#include "llhints.h"
-#include "llnearbychat.h"
-#include "llrecentpeople.h"
-
-#include "llviewercontrol.h"
-
-#include "llfloaterreg.h"//for LLFloaterReg::getTypedInstance
-#include "llviewerwindow.h"//for screen channel position
-#include "llnearbychatbar.h"
-#include "llrootview.h"
-#include "lllayoutstack.h"
-
-//add LLNearbyChatHandler to LLNotificationsUI namespace
-using namespace LLNotificationsUI;
-
-//-----------------------------------------------------------------------------------------------
-//LLNearbyChatScreenChannel
-//-----------------------------------------------------------------------------------------------
-LLToastPanelBase* createToastPanel()
-{
- LLNearbyChatToastPanel* item = LLNearbyChatToastPanel::createInstance();
- return item;
-}
-
-class LLNearbyChatScreenChannel: public LLScreenChannelBase
-{
- LOG_CLASS(LLNearbyChatScreenChannel);
-public:
- typedef std::vector<LLHandle<LLToast> > toast_vec_t;
- typedef std::list<LLHandle<LLToast> > toast_list_t;
-
- LLNearbyChatScreenChannel(const Params& p)
- : LLScreenChannelBase(p)
- {
- mStopProcessing = false;
-
- LLControlVariable* ctrl = gSavedSettings.getControl("NearbyToastLifeTime").get();
- if (ctrl)
- {
- ctrl->getSignal()->connect(boost::bind(&LLNearbyChatScreenChannel::updateToastsLifetime, this));
- }
-
- ctrl = gSavedSettings.getControl("NearbyToastFadingTime").get();
- if (ctrl)
- {
- ctrl->getSignal()->connect(boost::bind(&LLNearbyChatScreenChannel::updateToastFadingTime, this));
- }
- }
-
- void addNotification (LLSD& notification);
- void arrangeToasts ();
-
- typedef boost::function<LLToastPanelBase* (void )> create_toast_panel_callback_t;
- void setCreatePanelCallback(create_toast_panel_callback_t value) { m_create_toast_panel_callback_t = value;}
-
- void onToastDestroyed (LLToast* toast, bool app_quitting);
- void onToastFade (LLToast* toast);
-
- void redrawToasts()
- {
- arrangeToasts();
- }
-
- // hide all toasts from screen, but not remove them from a channel
- // removes all toasts from a channel
- virtual void removeToastsFromChannel()
- {
- for(toast_vec_t::iterator it = m_active_toasts.begin(); it != m_active_toasts.end(); ++it)
- {
- addToToastPool(it->get());
- }
- m_active_toasts.clear();
- };
-
- virtual void deleteAllChildren()
- {
- LL_DEBUGS("NearbyChat") << "Clearing toast pool" << llendl;
- m_toast_pool.clear();
- m_active_toasts.clear();
- LLScreenChannelBase::deleteAllChildren();
- }
-
-protected:
- void deactivateToast(LLToast* toast);
- void addToToastPool(LLToast* toast)
- {
- if (!toast) return;
- LL_DEBUGS("NearbyChat") << "Pooling toast" << llendl;
- toast->setVisible(FALSE);
- toast->stopTimer();
- toast->setIsHidden(true);
-
- // Nearby chat toasts that are hidden, not destroyed. They are collected to the toast pool, so that
- // they can be used next time, this is done for performance. But if the toast lifetime was changed
- // (from preferences floater (STORY-36)) while it was shown (at this moment toast isn't in the pool yet)
- // changes don't take affect.
- // So toast's lifetime should be updated each time it's added to the pool. Otherwise viewer would have
- // to be restarted so that changes take effect.
- toast->setLifetime(gSavedSettings.getS32("NearbyToastLifeTime"));
- toast->setFadingTime(gSavedSettings.getS32("NearbyToastFadingTime"));
- m_toast_pool.push_back(toast->getHandle());
- }
-
- void createOverflowToast(S32 bottom, F32 timer);
-
- void updateToastsLifetime();
-
- void updateToastFadingTime();
-
- create_toast_panel_callback_t m_create_toast_panel_callback_t;
-
- bool createPoolToast();
-
- toast_vec_t m_active_toasts;
- toast_list_t m_toast_pool;
-
- bool mStopProcessing;
- bool mChannelRect;
-};
-
-//-----------------------------------------------------------------------------------------------
-// LLNearbyChatToast
-//-----------------------------------------------------------------------------------------------
-
-// We're deriving from LLToast to be able to override onClose()
-// in order to handle closing nearby chat toasts properly.
-class LLNearbyChatToast : public LLToast
-{
- LOG_CLASS(LLNearbyChatToast);
-public:
- LLNearbyChatToast(const LLToast::Params& p, LLNearbyChatScreenChannel* nc_channelp)
- : LLToast(p),
- mNearbyChatScreenChannelp(nc_channelp)
- {
- }
-
- /*virtual*/ void onClose(bool app_quitting);
-
-private:
- LLNearbyChatScreenChannel* mNearbyChatScreenChannelp;
-};
-
-//-----------------------------------------------------------------------------------------------
-// LLNearbyChatScreenChannel
-//-----------------------------------------------------------------------------------------------
-
-void LLNearbyChatScreenChannel::deactivateToast(LLToast* toast)
-{
- toast_vec_t::iterator pos = std::find(m_active_toasts.begin(), m_active_toasts.end(), toast->getHandle());
-
- if (pos == m_active_toasts.end())
- {
- llassert(pos == m_active_toasts.end());
- return;
- }
-
- LL_DEBUGS("NearbyChat") << "Deactivating toast" << llendl;
- m_active_toasts.erase(pos);
-}
-
-void LLNearbyChatScreenChannel::createOverflowToast(S32 bottom, F32 timer)
-{
- //we don't need overflow toast in nearby chat
-}
-
-void LLNearbyChatScreenChannel::onToastDestroyed(LLToast* toast, bool app_quitting)
-{
- LL_DEBUGS("NearbyChat") << "Toast destroyed (app_quitting=" << app_quitting << ")" << llendl;
-
- if (app_quitting)
- {
- // Viewer is quitting.
- // Immediately stop processing chat messages (EXT-1419).
- mStopProcessing = true;
-}
- else
- {
- // The toast is being closed by user (STORM-192).
- // Remove it from the list of active toasts to prevent
- // further references to the invalid pointer.
- deactivateToast(toast);
- }
-}
-
-void LLNearbyChatScreenChannel::onToastFade(LLToast* toast)
-{
- LL_DEBUGS("NearbyChat") << "Toast fading" << llendl;
-
- //fade mean we put toast to toast pool
- if(!toast)
- return;
-
- deactivateToast(toast);
-
- addToToastPool(toast);
-
- arrangeToasts();
-}
-
-void LLNearbyChatScreenChannel::updateToastsLifetime()
-{
- S32 seconds = gSavedSettings.getS32("NearbyToastLifeTime");
- toast_list_t::iterator it;
-
- for(it = m_toast_pool.begin(); it != m_toast_pool.end(); ++it)
- {
- (*it).get()->setLifetime(seconds);
- }
-}
-
-void LLNearbyChatScreenChannel::updateToastFadingTime()
-{
- S32 seconds = gSavedSettings.getS32("NearbyToastFadingTime");
- toast_list_t::iterator it;
-
- for(it = m_toast_pool.begin(); it != m_toast_pool.end(); ++it)
- {
- (*it).get()->setFadingTime(seconds);
- }
-}
-
-bool LLNearbyChatScreenChannel::createPoolToast()
-{
- LLToastPanelBase* panel= m_create_toast_panel_callback_t();
- if(!panel)
- return false;
-
- LLToast::Params p;
- p.panel = panel;
- p.lifetime_secs = gSavedSettings.getS32("NearbyToastLifeTime");
- p.fading_time_secs = gSavedSettings.getS32("NearbyToastFadingTime");
-
- LLToast* toast = new LLNearbyChatToast(p, this);
-
-
- toast->setOnFadeCallback(boost::bind(&LLNearbyChatScreenChannel::onToastFade, this, _1));
-
- // If the toast gets somehow prematurely destroyed, deactivate it to prevent crash (STORM-1352).
- toast->setOnToastDestroyedCallback(boost::bind(&LLNearbyChatScreenChannel::onToastDestroyed, this, _1, false));
-
- LL_DEBUGS("NearbyChat") << "Creating and pooling toast" << llendl;
- m_toast_pool.push_back(toast->getHandle());
- return true;
-}
-
-void LLNearbyChatScreenChannel::addNotification(LLSD& notification)
-{
- //look in pool. if there is any message
- if(mStopProcessing)
- return;
-
- /*
- find last toast and check ID
- */
-
- if(m_active_toasts.size())
- {
- LLUUID fromID = notification["from_id"].asUUID(); // agent id or object id
- std::string from = notification["from"].asString();
- LLToast* toast = m_active_toasts[0].get();
- if (toast)
- {
- LLNearbyChatToastPanel* panel = dynamic_cast<LLNearbyChatToastPanel*>(toast->getPanel());
-
- if(panel && panel->messageID() == fromID && panel->getFromName() == from && panel->canAddText())
- {
- panel->addMessage(notification);
- toast->reshapeToPanel();
- toast->startTimer();
-
- arrangeToasts();
- return;
- }
- }
- }
-
-
-
- if(m_toast_pool.empty())
- {
- //"pool" is empty - create one more panel
- LL_DEBUGS("NearbyChat") << "Empty pool" << llendl;
- if(!createPoolToast())//created toast will go to pool. so next call will find it
- return;
- addNotification(notification);
- return;
- }
-
- int chat_type = notification["chat_type"].asInteger();
-
- if( ((EChatType)chat_type == CHAT_TYPE_DEBUG_MSG))
- {
- if(gSavedSettings.getBOOL("ShowScriptErrors") == FALSE)
- return;
- if(gSavedSettings.getS32("ShowScriptErrorsLocation")== 1)
- return;
- }
-
-
- //take 1st element from pool, (re)initialize it, put it in active toasts
-
- LL_DEBUGS("NearbyChat") << "Getting toast from pool" << llendl;
- LLToast* toast = m_toast_pool.back().get();
-
- m_toast_pool.pop_back();
-
-
- LLToastPanelBase* panel = dynamic_cast<LLToastPanelBase*>(toast->getPanel());
- if(!panel)
- return;
- panel->init(notification);
-
- toast->reshapeToPanel();
- toast->startTimer();
-
- m_active_toasts.push_back(toast->getHandle());
-
- arrangeToasts();
-}
-
-static bool sort_toasts_predicate(LLHandle<LLToast> first, LLHandle<LLToast> second)
-{
- if (!first.get() || !second.get()) return false; // STORM-1352
-
- F32 v1 = first.get()->getTimeLeftToLive();
- F32 v2 = second.get()->getTimeLeftToLive();
- return v1 > v2;
-}
-
-void LLNearbyChatScreenChannel::arrangeToasts()
-{
- if(mStopProcessing || isHovering())
- return;
-
- if (mFloaterSnapRegion == NULL)
- {
- mFloaterSnapRegion = gViewerWindow->getRootView()->getChildView("floater_snap_region");
- }
-
- if (!getParent())
- {
- // connect to floater snap region just to get resize events, we don't care about being a proper widget
- mFloaterSnapRegion->addChild(this);
- setFollows(FOLLOWS_ALL);
- }
-
- LLRect toast_rect;
- updateRect();
-
- LLRect channel_rect;
- mFloaterSnapRegion->localRectToOtherView(mFloaterSnapRegion->getLocalRect(), &channel_rect, gFloaterView);
- channel_rect.mLeft += 10;
- channel_rect.mRight = channel_rect.mLeft + 300;
-
- S32 channel_bottom = channel_rect.mBottom;
-
- S32 bottom = channel_bottom + 80;
- S32 margin = gSavedSettings.getS32("ToastGap");
-
- //sort active toasts
- std::sort(m_active_toasts.begin(),m_active_toasts.end(),sort_toasts_predicate);
-
- //calc max visible item and hide other toasts.
-
- for(toast_vec_t::iterator it = m_active_toasts.begin(); it != m_active_toasts.end(); ++it)
- {
- LLToast* toast = it->get();
- if (!toast)
- {
- llwarns << "NULL found in the active chat toasts list!" << llendl;
- continue;
- }
-
- S32 toast_top = bottom + toast->getRect().getHeight() + margin;
-
- if(toast_top > channel_rect.getHeight())
- {
- while(it!=m_active_toasts.end())
- {
- addToToastPool(it->get());
- it=m_active_toasts.erase(it);
- }
- break;
- }
-
- toast_rect = toast->getRect();
- toast_rect.setLeftTopAndSize(channel_rect.mLeft , bottom + toast_rect.getHeight(), toast_rect.getWidth() ,toast_rect.getHeight());
-
- toast->setRect(toast_rect);
- bottom += toast_rect.getHeight() - toast->getTopPad() + margin;
- }
-
- // use reverse order to provide correct z-order and avoid toast blinking
-
- for(toast_vec_t::reverse_iterator it = m_active_toasts.rbegin(); it != m_active_toasts.rend(); ++it)
- {
- LLToast* toast = it->get();
- if (toast)
- {
- toast->setIsHidden(false);
- toast->setVisible(TRUE);
- }
- }
-
-}
-
-
-
-//-----------------------------------------------------------------------------------------------
-//LLNearbyChatHandler
-//-----------------------------------------------------------------------------------------------
-boost::scoped_ptr<LLEventPump> LLNearbyChatHandler::sChatWatcher(new LLEventStream("LLChat"));
-
-LLNearbyChatHandler::LLNearbyChatHandler(e_notification_type type, const LLSD& id)
-{
- mType = type;
-
- // Getting a Channel for our notifications
- LLNearbyChatScreenChannel::Params p;
- p.id = LLUUID(gSavedSettings.getString("NearByChatChannelUUID"));
- LLNearbyChatScreenChannel* channel = new LLNearbyChatScreenChannel(p);
-
- LLNearbyChatScreenChannel::create_toast_panel_callback_t callback = createToastPanel;
-
- channel->setCreatePanelCallback(callback);
-
- LLChannelManager::getInstance()->addChannel(channel);
-
- mChannel = channel->getHandle();
-}
-
-LLNearbyChatHandler::~LLNearbyChatHandler()
-{
-}
-
-
-void LLNearbyChatHandler::initChannel()
-{
- //LLRect snap_rect = gFloaterView->getSnapRect();
- //mChannel->init(snap_rect.mLeft, snap_rect.mLeft + 200);
-}
-
-
-
-void LLNearbyChatHandler::processChat(const LLChat& chat_msg,
- const LLSD &args)
-{
- if(chat_msg.mMuted == TRUE)
- return;
-
- if(chat_msg.mText.empty())
- return;//don't process empty messages
-
- LLFloater* chat_bar = LLFloaterReg::getInstance("chat_bar");
-
- LLNearbyChat* nearby_chat = chat_bar->findChild<LLNearbyChat>("nearby_chat");
-
- // Build notification data
- LLSD notification;
- notification["message"] = chat_msg.mText;
- notification["from"] = chat_msg.mFromName;
- notification["from_id"] = chat_msg.mFromID;
- notification["time"] = chat_msg.mTime;
- notification["source"] = (S32)chat_msg.mSourceType;
- notification["chat_type"] = (S32)chat_msg.mChatType;
- notification["chat_style"] = (S32)chat_msg.mChatStyle;
- // Pass sender info so that it can be rendered properly (STORM-1021).
- notification["sender_slurl"] = LLViewerChat::getSenderSLURL(chat_msg, args);
-
- if (chat_msg.mChatType == CHAT_TYPE_DIRECT &&
- chat_msg.mText.length() > 0 &&
- chat_msg.mText[0] == '@')
- {
- // Send event on to LLEventStream and exit
- sChatWatcher->post(notification);
- return;
- }
-
- // don't show toast and add message to chat history on receive debug message
- // with disabled setting showing script errors or enabled setting to show script
- // errors in separate window.
- if (chat_msg.mChatType == CHAT_TYPE_DEBUG_MSG)
- {
- if(gSavedSettings.getBOOL("ShowScriptErrors") == FALSE)
- return;
-
- // don't process debug messages from not owned objects, see EXT-7762
- if (gAgentID != chat_msg.mOwnerID)
- {
- return;
- }
-
- if (gSavedSettings.getS32("ShowScriptErrorsLocation")== 1)// show error in window //("ScriptErrorsAsChat"))
- {
-
- LLColor4 txt_color;
-
- LLViewerChat::getChatColor(chat_msg,txt_color);
-
- LLFloaterScriptDebug::addScriptLine(chat_msg.mText,
- chat_msg.mFromName,
- txt_color,
- chat_msg.mFromID);
- return;
- }
- }
-
- nearby_chat->addMessage(chat_msg, true, args);
-
- if(chat_msg.mSourceType == CHAT_SOURCE_AGENT
- && chat_msg.mFromID.notNull()
- && chat_msg.mFromID != gAgentID)
- {
- LLFirstUse::otherAvatarChatFirst();
-
- // Add sender to the recent people list.
- LLRecentPeople::instance().add(chat_msg.mFromID);
-
- }
-
- // Send event on to LLEventStream
- sChatWatcher->post(notification);
-
-
- if( !chat_bar->isMinimized()
- && nearby_chat->isInVisibleChain()
- || ( chat_msg.mSourceType == CHAT_SOURCE_AGENT
- && gSavedSettings.getBOOL("UseChatBubbles") )
- || mChannel.isDead()
- || !mChannel.get()->getShowToasts() ) // to prevent toasts in Busy mode
- return;//no need in toast if chat is visible or if bubble chat is enabled
-
- // arrange a channel on a screen
- if(!mChannel.get()->getVisible())
- {
- initChannel();
- }
-
- /*
- //comment all this due to EXT-4432
- ..may clean up after some time...
-
- //only messages from AGENTS
- if(CHAT_SOURCE_OBJECT == chat_msg.mSourceType)
- {
- if(chat_msg.mChatType == CHAT_TYPE_DEBUG_MSG)
- return;//ok for now we don't skip messeges from object, so skip only debug messages
- }
- */
-
- LLNearbyChatScreenChannel* channel = dynamic_cast<LLNearbyChatScreenChannel*>(mChannel.get());
-
- if(channel)
- {
- // Handle IRC styled messages.
- std::string toast_msg;
- if (chat_msg.mChatStyle == CHAT_STYLE_IRC)
- {
- if (!chat_msg.mFromName.empty())
- {
- toast_msg += chat_msg.mFromName;
- }
- toast_msg += chat_msg.mText.substr(3);
- }
- else
- {
- toast_msg = chat_msg.mText;
- }
-
- // Add a nearby chat toast.
- LLUUID id;
- id.generate();
- notification["id"] = id;
- std::string r_color_name = "White";
- F32 r_color_alpha = 1.0f;
- LLViewerChat::getChatColor( chat_msg, r_color_name, r_color_alpha);
-
- notification["text_color"] = r_color_name;
- notification["color_alpha"] = r_color_alpha;
- notification["font_size"] = (S32)LLViewerChat::getChatFontSize() ;
- notification["message"] = toast_msg;
- channel->addNotification(notification);
- }
-}
-
-void LLNearbyChatHandler::onDeleteToast(LLToast* toast)
-{
-}
-
-
-//-----------------------------------------------------------------------------------------------
-// LLNearbyChatToast
-//-----------------------------------------------------------------------------------------------
-
-// virtual
-void LLNearbyChatToast::onClose(bool app_quitting)
-{
- mNearbyChatScreenChannelp->onToastDestroyed(this, app_quitting);
-}
-
-// EOF
diff --git a/indra/newview/llnearbychathandler.h b/indra/newview/llnearbychathandler.h
deleted file mode 100644
index b0e4f62d51..0000000000
--- a/indra/newview/llnearbychathandler.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/**
- * @file llnearbychathandler.h
- * @brief nearby chat notify
- *
- * $LicenseInfo:firstyear=2004&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$
- */
-
-#ifndef LL_LLNEARBYCHATHANDLER_H
-#define LL_LLNEARBYCHATHANDLER_H
-
-#include "llnotificationhandler.h"
-
-class LLEventPump;
-
-//add LLNearbyChatHandler to LLNotificationsUI namespace
-namespace LLNotificationsUI{
-
-class LLNearbyChatHandler : public LLChatHandler
-{
-public:
- LLNearbyChatHandler(e_notification_type type,const LLSD& id);
- virtual ~LLNearbyChatHandler();
-
-
- virtual void processChat(const LLChat& chat_msg, const LLSD &args);
-
-protected:
- virtual void onDeleteToast(LLToast* toast);
- virtual void initChannel();
-
- static boost::scoped_ptr<LLEventPump> sChatWatcher;
-};
-
-}
-
-#endif /* LL_LLNEARBYCHATHANDLER_H */
diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp
index 1bda7640bd..08b5eaedbb 100644..100755
--- a/indra/newview/llnetmap.cpp
+++ b/indra/newview/llnetmap.cpp
@@ -150,7 +150,7 @@ void LLNetMap::draw()
static LLUIColor map_avatar_color = LLUIColorTable::instance().getColor("MapAvatarColor", LLColor4::white);
static LLUIColor map_avatar_friend_color = LLUIColorTable::instance().getColor("MapAvatarFriendColor", LLColor4::white);
static LLUIColor map_track_color = LLUIColorTable::instance().getColor("MapTrackColor", LLColor4::white);
- static LLUIColor map_track_disabled_color = LLUIColorTable::instance().getColor("MapTrackDisabledColor", LLColor4::white);
+ //static LLUIColor map_track_disabled_color = LLUIColorTable::instance().getColor("MapTrackDisabledColor", LLColor4::white);
static LLUIColor map_frustum_color = LLUIColorTable::instance().getColor("MapFrustumColor", LLColor4::white);
static LLUIColor map_frustum_rotating_color = LLUIColorTable::instance().getColor("MapFrustumRotatingColor", LLColor4::white);
@@ -343,8 +343,11 @@ void LLNetMap::draw()
// Draw avatars
for (U32 i = 0; i < avatar_ids.size(); i++)
{
- pos_map = globalPosToView(positions[i]);
LLUUID uuid = avatar_ids[i];
+ // Skip self, we'll draw it later
+ if (uuid == gAgent.getID()) continue;
+
+ pos_map = globalPosToView(positions[i]);
bool show_as_friend = (LLAvatarTracker::instance().getBuddyInfo(uuid) != NULL);
diff --git a/indra/newview/llnetmap.h b/indra/newview/llnetmap.h
index 1f7e7d68c6..1f7e7d68c6 100644..100755
--- a/indra/newview/llnetmap.h
+++ b/indra/newview/llnetmap.h
diff --git a/indra/newview/llnotificationalerthandler.cpp b/indra/newview/llnotificationalerthandler.cpp
index 89fe7bb3c2..58a9b01a45 100644..100755
--- a/indra/newview/llnotificationalerthandler.cpp
+++ b/indra/newview/llnotificationalerthandler.cpp
@@ -29,6 +29,7 @@
#include "llnotificationhandler.h"
+#include "llagentcamera.h"
#include "llnotifications.h"
#include "llprogressview.h"
#include "lltoastnotifypanel.h"
@@ -40,10 +41,10 @@
using namespace LLNotificationsUI;
//--------------------------------------------------------------------------
-LLAlertHandler::LLAlertHandler(e_notification_type type, const LLSD& id) : mIsModal(false)
+LLAlertHandler::LLAlertHandler(const std::string& name, const std::string& notification_type, bool is_modal)
+: LLSystemNotificationHandler(name, notification_type),
+ mIsModal(is_modal)
{
- mType = type;
-
LLScreenChannelBase::Params p;
p.id = LLUUID(gSavedSettings.getString("AlertChannelUUID"));
p.display_toasts_always = true;
@@ -68,79 +69,83 @@ void LLAlertHandler::initChannel()
}
//--------------------------------------------------------------------------
-bool LLAlertHandler::processNotification(const LLSD& notify)
+bool LLAlertHandler::processNotification(const LLNotificationPtr& notification)
{
if(mChannel.isDead())
{
return false;
}
- LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID());
-
- if(!notification)
- return false;
-
// arrange a channel on a screen
if(!mChannel.get()->getVisible())
{
initChannel();
}
- if (notify["sigtype"].asString() == "add" || notify["sigtype"].asString() == "load")
+ if (notification->canLogToIM() && notification->hasFormElements())
{
- if (LLHandlerUtil::canSpawnSessionAndLogToIM(notification))
- {
- const std::string name = LLHandlerUtil::getSubstitutionName(notification);
-
- LLUUID from_id = notification->getPayload()["from_id"];
-
- // firstly create session...
- LLHandlerUtil::spawnIMSession(name, from_id);
-
- // ...then log message to have IM Well notified about new message
- LLHandlerUtil::logToIMP2P(notification);
- }
-
- LLToastAlertPanel* alert_dialog = new LLToastAlertPanel(notification, mIsModal);
- LLToast::Params p;
- p.notif_id = notification->getID();
- p.notification = notification;
- p.panel = dynamic_cast<LLToastPanel*>(alert_dialog);
- p.enable_hide_btn = false;
- p.can_fade = false;
- p.is_modal = mIsModal;
- p.on_delete_toast = boost::bind(&LLAlertHandler::onDeleteToast, this, _1);
-
- // Show alert in middle of progress view (during teleport) (EXT-1093)
- LLProgressView* progress = gViewerWindow->getProgressView();
- LLRect rc = progress && progress->getVisible() ? progress->getRect() : gViewerWindow->getWorldViewRectScaled();
- mChannel.get()->updatePositionAndSize(rc);
-
- LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel.get());
- if(channel)
- channel->addToast(p);
- }
- else if (notify["sigtype"].asString() == "change")
- {
- LLToastAlertPanel* alert_dialog = new LLToastAlertPanel(notification, mIsModal);
- LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel.get());
- if(channel)
- channel->modifyToastByNotificationID(notification->getID(), (LLToastPanel*)alert_dialog);
- }
- else
- {
- LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel.get());
- if(channel)
- channel->killToastByNotificationID(notification->getID());
+ const std::string name = LLHandlerUtil::getSubstitutionName(notification);
+
+ LLUUID from_id = notification->getPayload()["from_id"];
+
+ // firstly create session...
+ LLHandlerUtil::spawnIMSession(name, from_id);
+
+ // ...then log message to have IM Well notified about new message
+ LLHandlerUtil::logToIMP2P(notification);
}
+
+ LLToastAlertPanel* alert_dialog = new LLToastAlertPanel(notification, mIsModal);
+ LLToast::Params p;
+ p.notif_id = notification->getID();
+ p.notification = notification;
+ p.panel = dynamic_cast<LLToastPanel*>(alert_dialog);
+ p.enable_hide_btn = false;
+ p.can_fade = false;
+ p.is_modal = mIsModal;
+ p.on_delete_toast = boost::bind(&LLAlertHandler::onDeleteToast, this, _1);
+
+ // Show alert in middle of progress view (during teleport) (EXT-1093)
+ LLProgressView* progress = gViewerWindow->getProgressView();
+ LLRect rc = progress && progress->getVisible() ? progress->getRect() : gViewerWindow->getWorldViewRectScaled();
+ mChannel.get()->updatePositionAndSize(rc);
+
+ LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel.get());
+ if(channel)
+ channel->addToast(p);
+
return false;
}
+void LLAlertHandler::onChange( LLNotificationPtr notification )
+{
+ LLToastAlertPanel* alert_dialog = new LLToastAlertPanel(notification, mIsModal);
+ LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel.get());
+ if(channel)
+ channel->modifyToastByNotificationID(notification->getID(), (LLToastPanel*)alert_dialog);
+}
+
//--------------------------------------------------------------------------
+LLViewerAlertHandler::LLViewerAlertHandler(const std::string& name, const std::string& notification_type)
+ : LLSystemNotificationHandler(name, notification_type)
+{
+}
-void LLAlertHandler::onDeleteToast(LLToast* toast)
+bool LLViewerAlertHandler::processNotification(const LLNotificationPtr& p)
{
+ if (gHeadlessClient)
+ {
+ LL_INFOS("LLViewerAlertHandler") << "Alert: " << p->getName() << LL_ENDL;
+ }
+
+ // If we're in mouselook, the mouse is hidden and so the user can't click
+ // the dialog buttons. In that case, change to First Person instead.
+ if( gAgentCamera.cameraMouselook() )
+ {
+ gAgentCamera.changeCameraToDefault();
+ }
+
+ return false;
}
-//--------------------------------------------------------------------------
diff --git a/indra/newview/llnotificationgrouphandler.cpp b/indra/newview/llnotificationgrouphandler.cpp
index ad51389241..8fef102cf8 100644..100755
--- a/indra/newview/llnotificationgrouphandler.cpp
+++ b/indra/newview/llnotificationgrouphandler.cpp
@@ -37,15 +37,13 @@
using namespace LLNotificationsUI;
//--------------------------------------------------------------------------
-LLGroupHandler::LLGroupHandler(e_notification_type type, const LLSD& id)
+LLGroupHandler::LLGroupHandler()
+: LLCommunicationNotificationHandler("Group Notifications", "groupnotify")
{
- mType = type;
-
// Getting a Channel for our notifications
LLScreenChannel* channel = LLChannelManager::getInstance()->createNotificationChannel();
if(channel)
{
- channel->setOnRejectToastCallback(boost::bind(&LLGroupHandler::onRejectToast, this, _1));
mChannel = channel->getHandle();
}
}
@@ -64,72 +62,37 @@ void LLGroupHandler::initChannel()
}
//--------------------------------------------------------------------------
-bool LLGroupHandler::processNotification(const LLSD& notify)
+bool LLGroupHandler::processNotification(const LLNotificationPtr& notification)
{
if(mChannel.isDead())
{
return false;
}
- LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID());
-
- if(!notification)
- return false;
-
// arrange a channel on a screen
if(!mChannel.get()->getVisible())
{
initChannel();
}
- if(notify["sigtype"].asString() == "add" || notify["sigtype"].asString() == "change")
- {
- LLHandlerUtil::logGroupNoticeToIMGroup(notification);
+ LLHandlerUtil::logGroupNoticeToIMGroup(notification);
- LLPanel* notify_box = new LLToastGroupNotifyPanel(notification);
- LLToast::Params p;
- p.notif_id = notification->getID();
- p.notification = notification;
- p.panel = notify_box;
- p.on_delete_toast = boost::bind(&LLGroupHandler::onDeleteToast, this, _1);
+ LLPanel* notify_box = new LLToastGroupNotifyPanel(notification);
+ LLToast::Params p;
+ p.notif_id = notification->getID();
+ p.notification = notification;
+ p.panel = notify_box;
+ p.on_delete_toast = boost::bind(&LLGroupHandler::onDeleteToast, this, _1);
- LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel.get());
- if(channel)
- channel->addToast(p);
+ LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel.get());
+ if(channel)
+ channel->addToast(p);
- // send a signal to the counter manager
- mNewNotificationSignal();
+ LLGroupActions::refresh_notices();
- LLGroupActions::refresh_notices();
- }
- else if (notify["sigtype"].asString() == "delete")
- {
- mChannel.get()->killToastByNotificationID(notification->getID());
- }
return false;
}
-//--------------------------------------------------------------------------
-void LLGroupHandler::onDeleteToast(LLToast* toast)
-{
- // send a signal to the counter manager
- mDelNotificationSignal();
-
- // send a signal to a listener to let him perform some action
- // in this case listener is a SysWellWindow and it will remove a corresponding item from its list
- mNotificationIDSignal(toast->getNotificationID());
-}
-
-//--------------------------------------------------------------------------
-void LLGroupHandler::onRejectToast(LLUUID& id)
-{
- LLNotificationPtr notification = LLNotifications::instance().find(id);
-
- if (notification && LLNotificationManager::getInstance()->getHandlerForNotification(notification->getType()) == this)
- {
- LLNotifications::instance().cancel(notification);
- }
-}
//--------------------------------------------------------------------------
diff --git a/indra/newview/llnotificationhandler.h b/indra/newview/llnotificationhandler.h
index 3569ad6447..bff4efa9ea 100644..100755
--- a/indra/newview/llnotificationhandler.h
+++ b/indra/newview/llnotificationhandler.h
@@ -27,33 +27,20 @@
#ifndef LL_LLNOTIFICATIONHANDLER_H
#define LL_LLNOTIFICATIONHANDLER_H
+#include <boost/intrusive_ptr.hpp>
#include "llwindow.h"
-//#include "llnotificationsutil.h"
+#include "llnotifications.h"
#include "llchannelmanager.h"
#include "llchat.h"
#include "llinstantmessage.h"
#include "llnotificationptr.h"
-class LLIMFloater;
+class LLFloaterIMSession;
namespace LLNotificationsUI
{
-// ENotificationType enumerates all possible types of notifications that could be met
-//
-typedef enum e_notification_type
-{
- NT_NOTIFY,
- NT_NOTIFYTIP,
- NT_GROUPNOTIFY,
- NT_IMCHAT,
- NT_GROUPCHAT,
- NT_NEARBYCHAT,
- NT_ALERT,
- NT_ALERTMODAL,
- NT_OFFER
-} ENotificationType;
/**
* Handler of notification events.
@@ -81,21 +68,8 @@ class LLEventHandler
public:
virtual ~LLEventHandler() {};
- // callbacks for counters
- typedef boost::function<void (void)> notification_callback_t;
- typedef boost::signals2::signal<void (void)> notification_signal_t;
- notification_signal_t mNewNotificationSignal;
- notification_signal_t mDelNotificationSignal;
- boost::signals2::connection setNewNotificationCallback(notification_callback_t cb) { return mNewNotificationSignal.connect(cb); }
- boost::signals2::connection setDelNotification(notification_callback_t cb) { return mDelNotificationSignal.connect(cb); }
- // callback for notification/toast
- typedef boost::function<void (const LLUUID id)> notification_id_callback_t;
- typedef boost::signals2::signal<void (const LLUUID id)> notification_id_signal_t;
- notification_id_signal_t mNotificationIDSignal;
- boost::signals2::connection setNotificationIDCallback(notification_id_callback_t cb) { return mNotificationIDSignal.connect(cb); }
-
protected:
- virtual void onDeleteToast(LLToast* toast)=0;
+ virtual void onDeleteToast(LLToast* toast) {}
// arrange handler's channel on a screen
// is necessary to unbind a moment of creation of a channel and a moment of positioning of it
@@ -104,8 +78,6 @@ protected:
virtual void initChannel()=0;
LLHandle<LLScreenChannelBase> mChannel;
- e_notification_type mType;
-
};
// LLSysHandler and LLChatHandler are more specific base classes
@@ -115,24 +87,37 @@ protected:
/**
* Handler for system notifications.
*/
-class LLSysHandler : public LLEventHandler
+class LLNotificationHandler : public LLEventHandler, public LLNotificationChannel
{
public:
- LLSysHandler();
- virtual ~LLSysHandler() {};
+ LLNotificationHandler(const std::string& name, const std::string& notification_type, const std::string& parentName);
+ virtual ~LLNotificationHandler() {};
- virtual bool processNotification(const LLSD& notify)=0;
+ // base interface functions
+ virtual void onAdd(LLNotificationPtr p) { processNotification(p); }
+ virtual void onChange(LLNotificationPtr p) { processNotification(p); }
+ virtual void onLoad(LLNotificationPtr p) { processNotification(p); }
+ virtual void onDelete(LLNotificationPtr p) { if (mChannel.get()) mChannel.get()->removeToastByNotificationID(p->getID());}
-protected :
- static void init();
- void removeExclusiveNotifications(const LLNotificationPtr& notif);
+ virtual bool processNotification(const LLNotificationPtr& notify) = 0;
+};
- typedef std::list< std::set<std::string> > exclusive_notif_sets;
- static exclusive_notif_sets sExclusiveNotificationGroups;
+class LLSystemNotificationHandler : public LLNotificationHandler
+{
+public:
+ LLSystemNotificationHandler(const std::string& name, const std::string& notification_type);
+ virtual ~LLSystemNotificationHandler() {};
+};
+
+class LLCommunicationNotificationHandler : public LLNotificationHandler
+{
+public:
+ LLCommunicationNotificationHandler(const std::string& name, const std::string& notification_type);
+ virtual ~LLCommunicationNotificationHandler() {};
};
/**
- * Handler for chat message notifications.
+ * Handler for chat message notifications.
*/
class LLChatHandler : public LLEventHandler
{
@@ -146,17 +131,14 @@ public:
* Handler for IM notifications.
* It manages life time of IMs, group messages.
*/
-class LLIMHandler : public LLSysHandler
+class LLIMHandler : public LLCommunicationNotificationHandler
{
public:
- LLIMHandler(e_notification_type type, const LLSD& id);
+ LLIMHandler();
virtual ~LLIMHandler();
-
- // base interface functions
- virtual bool processNotification(const LLSD& notify);
+ bool processNotification(const LLNotificationPtr& p);
protected:
- virtual void onDeleteToast(LLToast* toast);
virtual void initChannel();
};
@@ -164,18 +146,15 @@ protected:
* Handler for system informational notices.
* It manages life time of tip notices.
*/
-class LLTipHandler : public LLSysHandler
+class LLTipHandler : public LLSystemNotificationHandler
{
public:
- LLTipHandler(e_notification_type type, const LLSD& id);
+ LLTipHandler();
virtual ~LLTipHandler();
- // base interface functions
- virtual bool processNotification(const LLSD& notify);
+ virtual bool processNotification(const LLNotificationPtr& p);
protected:
- virtual void onDeleteToast(LLToast* toast);
- virtual void onRejectToast(const LLUUID& id);
virtual void initChannel();
};
@@ -183,168 +162,144 @@ protected:
* Handler for system informational notices.
* It manages life time of script notices.
*/
-class LLScriptHandler : public LLSysHandler
+class LLScriptHandler : public LLSystemNotificationHandler
{
public:
- LLScriptHandler(e_notification_type type, const LLSD& id);
+ LLScriptHandler();
virtual ~LLScriptHandler();
- // base interface functions
- virtual bool processNotification(const LLSD& notify);
+ virtual void onDelete(LLNotificationPtr p);
+ virtual bool processNotification(const LLNotificationPtr& p);
protected:
virtual void onDeleteToast(LLToast* toast);
virtual void initChannel();
-
- // own handlers
- void onRejectToast(LLUUID& id);
};
/**
* Handler for group system notices.
*/
-class LLGroupHandler : public LLSysHandler
+class LLGroupHandler : public LLCommunicationNotificationHandler
{
public:
- LLGroupHandler(e_notification_type type, const LLSD& id);
+ LLGroupHandler();
virtual ~LLGroupHandler();
- // base interface functions
- virtual bool processNotification(const LLSD& notify);
+ virtual bool processNotification(const LLNotificationPtr& p);
protected:
- virtual void onDeleteToast(LLToast* toast);
virtual void initChannel();
-
- // own handlers
- void onRejectToast(LLUUID& id);
};
/**
* Handler for alert system notices.
*/
-class LLAlertHandler : public LLSysHandler
+class LLAlertHandler : public LLSystemNotificationHandler
{
public:
- LLAlertHandler(e_notification_type type, const LLSD& id);
+ LLAlertHandler(const std::string& name, const std::string& notification_type, bool is_modal);
virtual ~LLAlertHandler();
- void setAlertMode(bool is_modal) { mIsModal = is_modal; }
-
- // base interface functions
- virtual bool processNotification(const LLSD& notify);
+ virtual void onChange(LLNotificationPtr p);
+ virtual bool processNotification(const LLNotificationPtr& p);
protected:
- virtual void onDeleteToast(LLToast* toast);
virtual void initChannel();
bool mIsModal;
};
+class LLViewerAlertHandler : public LLSystemNotificationHandler
+{
+ LOG_CLASS(LLViewerAlertHandler);
+public:
+ LLViewerAlertHandler(const std::string& name, const std::string& notification_type);
+ virtual ~LLViewerAlertHandler() {};
+
+ virtual void onDelete(LLNotificationPtr p) {};
+ virtual bool processNotification(const LLNotificationPtr& p);
+
+protected:
+ virtual void initChannel() {};
+};
+
/**
* Handler for offers notices.
* It manages life time of offer notices.
*/
-class LLOfferHandler : public LLSysHandler
+class LLOfferHandler : public LLCommunicationNotificationHandler
{
public:
- LLOfferHandler(e_notification_type type, const LLSD& id);
+ LLOfferHandler();
virtual ~LLOfferHandler();
- // base interface functions
- virtual bool processNotification(const LLSD& notify);
+ virtual void onChange(LLNotificationPtr p);
+ virtual void onDelete(LLNotificationPtr notification);
+ virtual bool processNotification(const LLNotificationPtr& p);
protected:
- virtual void onDeleteToast(LLToast* toast);
virtual void initChannel();
-
- // own handlers
- void onRejectToast(LLUUID& id);
};
/**
* Handler for UI hints.
*/
-class LLHintHandler : public LLSingleton<LLHintHandler>
+class LLHintHandler : public LLSystemNotificationHandler
{
public:
LLHintHandler();
- virtual ~LLHintHandler();
+ virtual ~LLHintHandler() {}
- // base interface functions
- virtual bool processNotification(const LLSD& notify);
+ virtual void onAdd(LLNotificationPtr p);
+ virtual void onLoad(LLNotificationPtr p);
+ virtual void onDelete(LLNotificationPtr p);
+ virtual bool processNotification(const LLNotificationPtr& p);
+
+protected:
+ virtual void initChannel() {};
};
/**
* Handler for browser notifications
*/
-class LLBrowserNotification : public LLSingleton<LLBrowserNotification>
+class LLBrowserNotification : public LLSystemNotificationHandler
{
public:
- virtual bool processNotification(const LLSD& notify);
+ LLBrowserNotification();
+ virtual ~LLBrowserNotification() {}
+
+ virtual bool processNotification(const LLNotificationPtr& p);
+
+protected:
+ virtual void initChannel() {};
};
/**
* Handler for outbox notifications
*/
-class LLOutboxNotification : public LLSingleton<LLOutboxNotification>
+class LLOutboxNotification : public LLSystemNotificationHandler
{
public:
- virtual bool processNotification(const LLSD& notify);
+ LLOutboxNotification();
+ virtual ~LLOutboxNotification() {};
+ virtual void onChange(LLNotificationPtr p) { }
+ virtual void onDelete(LLNotificationPtr p);
+ virtual bool processNotification(const LLNotificationPtr& p);
+
+protected:
+ virtual void initChannel() {};
};
class LLHandlerUtil
{
public:
/**
- * Checks sufficient conditions to log notification message to IM session.
- */
- static bool canLogToIM(const LLNotificationPtr& notification);
-
- /**
- * Checks sufficient conditions to log notification message to nearby chat session.
- */
- static bool canLogToNearbyChat(const LLNotificationPtr& notification);
-
- /**
- * Checks sufficient conditions to spawn IM session.
- */
- static bool canSpawnIMSession(const LLNotificationPtr& notification);
-
- /**
- * Checks sufficient conditions to add notification toast panel IM floater.
- */
- static bool canAddNotifPanelToIM(const LLNotificationPtr& notification);
-
- /**
- * Checks whether notification can be used multiple times or not.
- */
- static bool isNotificationReusable(const LLNotificationPtr& notification);
-
- /**
- * Checks if passed notification can create IM session and be written into it.
- *
- * This method uses canLogToIM() & canSpawnIMSession().
- */
- static bool canSpawnSessionAndLogToIM(const LLNotificationPtr& notification);
-
- /**
- * Checks if passed notification can create toast.
- */
- static bool canSpawnToast(const LLNotificationPtr& notification);
-
- /**
* Determines whether IM floater is opened.
*/
static bool isIMFloaterOpened(const LLNotificationPtr& notification);
/**
- * Determines whether IM floater is focused.
- */
- static bool isIMFloaterFocused(const LLNotificationPtr& notification);
-
- /**
* Writes notification message to IM session.
*/
static void logToIM(const EInstantMessage& session_type,
@@ -355,12 +310,7 @@ public:
/**
* Writes notification message to IM p2p session.
*/
- static void logToIMP2P(const LLNotificationPtr& notification);
-
- /**
- * Writes notification message to IM p2p session.
- */
- static void logToIMP2P(const LLNotificationPtr& notification, bool to_file_only);
+ static void logToIMP2P(const LLNotificationPtr& notification, bool to_file_only = false);
/**
* Writes group notice notification message to IM group session.
@@ -406,13 +356,6 @@ public:
*/
static void decIMMesageCounter(const LLNotificationPtr& notification);
-private:
-
- /**
- * Find IM floater based on "from_id"
- */
- static LLIMFloater* findIMFloater(const LLNotificationPtr& notification);
-
};
}
diff --git a/indra/newview/llnotificationhandlerutil.cpp b/indra/newview/llnotificationhandlerutil.cpp
index 7c6287967a..ef4d735616 100644..100755
--- a/indra/newview/llnotificationhandlerutil.cpp
+++ b/indra/newview/llnotificationhandlerutil.cpp
@@ -34,207 +34,34 @@
#include "llurlaction.h"
#include "llagent.h"
-#include "llimfloater.h"
+#include "llfloaterimsession.h"
#include "llimview.h"
-#include "llnearbychat.h"
+#include "llfloaterimnearbychat.h"
#include "llnotificationhandler.h"
using namespace LLNotificationsUI;
-// static
-std::list< std::set<std::string> > LLSysHandler::sExclusiveNotificationGroups;
-
-// static
-void LLSysHandler::init()
-{
- std::set<std::string> online_offline_group;
- online_offline_group.insert("FriendOnline");
- online_offline_group.insert("FriendOffline");
-
- sExclusiveNotificationGroups.push_back(online_offline_group);
-}
-
-LLSysHandler::LLSysHandler()
-{
- if(sExclusiveNotificationGroups.empty())
- {
- init();
- }
-}
-
-void LLSysHandler::removeExclusiveNotifications(const LLNotificationPtr& notif)
-{
- LLScreenChannel* channel = dynamic_cast<LLScreenChannel *>(mChannel.get());
- if (channel == NULL)
- {
- return;
- }
-
- class ExclusiveMatcher: public LLScreenChannel::Matcher
- {
- public:
- ExclusiveMatcher(const std::set<std::string>& excl_group,
- const std::string& from_name) :
- mExclGroup(excl_group), mFromName(from_name)
- {
- }
- bool matches(const LLNotificationPtr notification) const
- {
- for (std::set<std::string>::const_iterator it = mExclGroup.begin(); it
- != mExclGroup.end(); it++)
- {
- std::string from_name = LLHandlerUtil::getSubstitutionName(notification);
- if (notification->getName() == *it && from_name == mFromName)
- {
- return true;
- }
- }
- return false;
- }
- private:
- const std::set<std::string>& mExclGroup;
- const std::string& mFromName;
- };
-
-
- for (exclusive_notif_sets::iterator it = sExclusiveNotificationGroups.begin(); it
- != sExclusiveNotificationGroups.end(); it++)
- {
- std::set<std::string> group = *it;
- std::set<std::string>::iterator g_it = group.find(notif->getName());
- if (g_it != group.end())
- {
- channel->killMatchedToasts(ExclusiveMatcher(group,
- LLHandlerUtil::getSubstitutionName(notif)));
- }
- }
-}
-
-const static std::string GRANTED_MODIFY_RIGHTS("GrantedModifyRights"),
- REVOKED_MODIFY_RIGHTS("RevokedModifyRights"),
- OBJECT_GIVE_ITEM("ObjectGiveItem"),
- OBJECT_GIVE_ITEM_UNKNOWN_USER("ObjectGiveItemUnknownUser"),
- PAYMENT_RECEIVED("PaymentReceived"),
- PAYMENT_SENT("PaymentSent"),
- ADD_FRIEND_WITH_MESSAGE("AddFriendWithMessage"),
- USER_GIVE_ITEM("UserGiveItem"),
- INVENTORY_ACCEPTED("InventoryAccepted"),
- INVENTORY_DECLINED("InventoryDeclined"),
- OFFER_FRIENDSHIP("OfferFriendship"),
- FRIENDSHIP_ACCEPTED("FriendshipAccepted"),
- FRIENDSHIP_OFFERED("FriendshipOffered"),
- FRIENDSHIP_ACCEPTED_BYME("FriendshipAcceptedByMe"),
- FRIENDSHIP_DECLINED_BYME("FriendshipDeclinedByMe"),
- FRIEND_ONLINE("FriendOnline"), FRIEND_OFFLINE("FriendOffline"),
- SERVER_OBJECT_MESSAGE("ServerObjectMessage"),
- TELEPORT_OFFERED("TeleportOffered"),
- TELEPORT_OFFER_SENT("TeleportOfferSent"),
- IM_SYSTEM_MESSAGE_TIP("IMSystemMessageTip");
+LLNotificationHandler::LLNotificationHandler(const std::string& name, const std::string& notification_type, const std::string& parentName)
+: LLNotificationChannel(name, parentName, LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, notification_type))
+{}
+LLSystemNotificationHandler::LLSystemNotificationHandler(const std::string& name, const std::string& notification_type)
+ : LLNotificationHandler(name, notification_type, "System")
+{}
-// static
-bool LLHandlerUtil::canLogToIM(const LLNotificationPtr& notification)
-{
- return GRANTED_MODIFY_RIGHTS == notification->getName()
- || REVOKED_MODIFY_RIGHTS == notification->getName()
- || PAYMENT_RECEIVED == notification->getName()
- || PAYMENT_SENT == notification->getName()
- || OFFER_FRIENDSHIP == notification->getName()
- || FRIENDSHIP_OFFERED == notification->getName()
- || FRIENDSHIP_ACCEPTED == notification->getName()
- || FRIENDSHIP_ACCEPTED_BYME == notification->getName()
- || FRIENDSHIP_DECLINED_BYME == notification->getName()
- || SERVER_OBJECT_MESSAGE == notification->getName()
- || INVENTORY_ACCEPTED == notification->getName()
- || INVENTORY_DECLINED == notification->getName()
- || USER_GIVE_ITEM == notification->getName()
- || TELEPORT_OFFERED == notification->getName()
- || TELEPORT_OFFER_SENT == notification->getName()
- || IM_SYSTEM_MESSAGE_TIP == notification->getName();
-}
-
-// static
-bool LLHandlerUtil::canLogToNearbyChat(const LLNotificationPtr& notification)
-{
- return notification->getType() == "notifytip"
- && FRIEND_ONLINE != notification->getName()
- && FRIEND_OFFLINE != notification->getName()
- && INVENTORY_ACCEPTED != notification->getName()
- && INVENTORY_DECLINED != notification->getName()
- && IM_SYSTEM_MESSAGE_TIP != notification->getName();
-}
-
-// static
-bool LLHandlerUtil::canSpawnIMSession(const LLNotificationPtr& notification)
-{
- return OFFER_FRIENDSHIP == notification->getName()
- || USER_GIVE_ITEM == notification->getName()
- || TELEPORT_OFFERED == notification->getName();
-}
-
-// static
-bool LLHandlerUtil::canAddNotifPanelToIM(const LLNotificationPtr& notification)
-{
- return OFFER_FRIENDSHIP == notification->getName()
- || USER_GIVE_ITEM == notification->getName()
- || TELEPORT_OFFERED == notification->getName();
-}
+LLCommunicationNotificationHandler::LLCommunicationNotificationHandler(const std::string& name, const std::string& notification_type)
+ : LLNotificationHandler(name, notification_type, "Communication")
+{}
// static
-bool LLHandlerUtil::isNotificationReusable(const LLNotificationPtr& notification)
-{
- return OFFER_FRIENDSHIP == notification->getName()
- || USER_GIVE_ITEM == notification->getName()
- || TELEPORT_OFFERED == notification->getName();
-}
-
-// static
-bool LLHandlerUtil::canSpawnSessionAndLogToIM(const LLNotificationPtr& notification)
-{
- return canLogToIM(notification) && canSpawnIMSession(notification);
-}
-
-// static
-bool LLHandlerUtil::canSpawnToast(const LLNotificationPtr& notification)
+bool LLHandlerUtil::isIMFloaterOpened(const LLNotificationPtr& notification)
{
- if(INVENTORY_DECLINED == notification->getName()
- || INVENTORY_ACCEPTED == notification->getName())
- {
- // return false for inventory accepted/declined notifications if respective IM window is open (EXT-5909)
- return ! isIMFloaterOpened(notification);
- }
-
- if(FRIENDSHIP_ACCEPTED == notification->getName())
- {
- // don't show FRIENDSHIP_ACCEPTED if IM window is opened and focused - EXT-6441
- return ! isIMFloaterFocused(notification);
- }
-
- if(OFFER_FRIENDSHIP == notification->getName()
- || USER_GIVE_ITEM == notification->getName()
- || TELEPORT_OFFERED == notification->getName())
- {
- // When ANY offer arrives, show toast, unless IM window is already open - EXT-5904
- return ! isIMFloaterOpened(notification);
- }
-
- return true;
-}
+ bool res = false;
-// static
-LLIMFloater* LLHandlerUtil::findIMFloater(const LLNotificationPtr& notification)
-{
LLUUID from_id = notification->getPayload()["from_id"];
LLUUID session_id = LLIMMgr::computeSessionID(IM_NOTHING_SPECIAL, from_id);
- return LLFloaterReg::findTypedInstance<LLIMFloater>("impanel", session_id);
-}
+ LLFloaterIMSession* im_floater = LLFloaterReg::findTypedInstance<LLFloaterIMSession>("impanel", session_id);
-// static
-bool LLHandlerUtil::isIMFloaterOpened(const LLNotificationPtr& notification)
-{
- bool res = false;
-
- LLIMFloater* im_floater = findIMFloater(notification);
if (im_floater != NULL)
{
res = im_floater->getVisible() == TRUE;
@@ -243,19 +70,6 @@ bool LLHandlerUtil::isIMFloaterOpened(const LLNotificationPtr& notification)
return res;
}
-bool LLHandlerUtil::isIMFloaterFocused(const LLNotificationPtr& notification)
-{
- bool res = false;
-
- LLIMFloater* im_floater = findIMFloater(notification);
- if (im_floater != NULL)
- {
- res = im_floater->hasFocus() == TRUE;
- }
-
- return res;
-}
-
// static
void LLHandlerUtil::logToIM(const EInstantMessage& session_type,
const std::string& session_name, const std::string& from_name,
@@ -287,13 +101,6 @@ void LLHandlerUtil::logToIM(const EInstantMessage& session_type,
}
else
{
- // store active session id
- const LLUUID & active_session_id =
- LLIMModel::instance().getActiveSessionID();
-
- // set searched session as active to avoid IM toast popup
- LLIMModel::instance().setActiveSessionID(session_id);
-
S32 unread = session->mNumUnread;
S32 participant_unread = session->mParticipantUnreadMessageCount;
LLIMModel::instance().addMessageSilently(session_id, from, from_id,
@@ -304,25 +111,9 @@ void LLHandlerUtil::logToIM(const EInstantMessage& session_type,
// update IM floater messages
updateIMFLoaterMesages(session_id);
-
- // restore active session id
- if (active_session_id.isNull())
- {
- LLIMModel::instance().resetActiveSessionID();
- }
- else
- {
- LLIMModel::instance().setActiveSessionID(active_session_id);
- }
}
}
-// static
-void LLHandlerUtil::logToIMP2P(const LLNotificationPtr& notification)
-{
- logToIMP2P(notification, false);
-}
-
void log_name_callback(const std::string& full_name, const std::string& from_name,
const std::string& message, const LLUUID& from_id)
@@ -334,25 +125,27 @@ void log_name_callback(const std::string& full_name, const std::string& from_nam
// static
void LLHandlerUtil::logToIMP2P(const LLNotificationPtr& notification, bool to_file_only)
{
- // don't create IM p2p session with objects, it's necessary condition to log
- if (notification->getName() != OBJECT_GIVE_ITEM)
+ if (!gCacheName)
{
- LLUUID from_id = notification->getPayload()["from_id"];
+ return;
+ }
- if (from_id.isNull())
- {
- llwarns << " from_id for notification " << notification->getName() << " is null " << llendl;
- return;
- }
+ LLUUID from_id = notification->getPayload()["from_id"];
- if(to_file_only)
- {
- gCacheName->get(from_id, false, boost::bind(&log_name_callback, _2, "", notification->getMessage(), LLUUID()));
- }
- else
- {
- gCacheName->get(from_id, false, boost::bind(&log_name_callback, _2, INTERACTIVE_SYSTEM_FROM, notification->getMessage(), from_id));
- }
+ if (from_id.isNull())
+ {
+ // Normal behavior for system generated messages, don't spam.
+ // llwarns << " from_id for notification " << notification->getName() << " is null " << llendl;
+ return;
+ }
+
+ if(to_file_only)
+ {
+ gCacheName->get(from_id, false, boost::bind(&log_name_callback, _2, "", notification->getMessage(), LLUUID()));
+ }
+ else
+ {
+ gCacheName->get(from_id, false, boost::bind(&log_name_callback, _2, INTERACTIVE_SYSTEM_FROM, notification->getMessage(), from_id));
}
}
@@ -385,8 +178,8 @@ void LLHandlerUtil::logGroupNoticeToIMGroup(
// static
void LLHandlerUtil::logToNearbyChat(const LLNotificationPtr& notification, EChatSourceType type)
{
- LLNearbyChat* nearby_chat = LLNearbyChat::getInstance();
- if(nearby_chat)
+ LLFloaterIMNearbyChat* nearby_chat = LLFloaterReg::findTypedInstance<LLFloaterIMNearbyChat>("nearby_chat");
+ if (nearby_chat)
{
LLChat chat_msg(notification->getMessage());
chat_msg.mSourceType = type;
@@ -465,7 +258,7 @@ void LLHandlerUtil::addNotifPanelToIM(const LLNotificationPtr& notification)
// static
void LLHandlerUtil::updateIMFLoaterMesages(const LLUUID& session_id)
{
- LLIMFloater* im_floater = LLIMFloater::findInstance(session_id);
+ LLFloaterIMSession* im_floater = LLFloaterIMSession::findInstance(session_id);
if (im_floater != NULL && im_floater->getVisible())
{
im_floater->updateMessages();
@@ -489,14 +282,10 @@ void LLHandlerUtil::decIMMesageCounter(const LLNotificationPtr& notification)
LLUUID from_id = notification->getPayload()["from_id"];
LLUUID session_id = LLIMMgr::computeSessionID(IM_NOTHING_SPECIAL, from_id);
- LLIMModel::LLIMSession * session = LLIMModel::getInstance()->findIMSession(
- session_id);
+ LLIMModel::LLIMSession * session = LLIMModel::getInstance()->findIMSession(session_id);
- if (session == NULL)
+ if (session)
{
- return;
- }
-
LLSD arg;
arg["session_id"] = session_id;
session->mNumUnread--;
@@ -505,3 +294,5 @@ void LLHandlerUtil::decIMMesageCounter(const LLNotificationPtr& notification)
arg["participant_unread"] = session->mParticipantUnreadMessageCount;
LLIMModel::getInstance()->mNewMsgSignal(arg);
}
+}
+
diff --git a/indra/newview/llnotificationhinthandler.cpp b/indra/newview/llnotificationhinthandler.cpp
index f7163cb04f..f40369a2e0 100644..100755
--- a/indra/newview/llnotificationhinthandler.cpp
+++ b/indra/newview/llnotificationhinthandler.cpp
@@ -34,25 +34,26 @@
using namespace LLNotificationsUI;
LLHintHandler::LLHintHandler()
+ : LLSystemNotificationHandler("Hints", "hint")
{
}
-LLHintHandler::~LLHintHandler()
+void LLHintHandler::onAdd(LLNotificationPtr p)
{
+ LLHints::show(p);
}
-bool LLHintHandler::processNotification(const LLSD& notify)
+void LLHintHandler::onLoad(LLNotificationPtr p)
+{
+ LLHints::show(p);
+}
+
+void LLHintHandler::onDelete(LLNotificationPtr p)
+{
+ LLHints::hide(p);
+}
+
+bool LLHintHandler::processNotification(const LLNotificationPtr& p)
{
- LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID());
-
- std::string sigtype = notify["sigtype"].asString();
- if (sigtype == "add" || sigtype == "load")
- {
- LLHints::show(notification);
- }
- else if (sigtype == "delete")
- {
- LLHints::hide(notification);
- }
return false;
}
diff --git a/indra/newview/llnotificationmanager.cpp b/indra/newview/llnotificationmanager.cpp
index f792f53ac5..152581c5a0 100644..100755
--- a/indra/newview/llnotificationmanager.cpp
+++ b/indra/newview/llnotificationmanager.cpp
@@ -31,7 +31,7 @@
#include "llnotificationmanager.h"
-#include "llnearbychathandler.h"
+#include "llfloaterimnearbychathandler.h"
#include "llnotifications.h"
#include <boost/bind.hpp>
@@ -42,107 +42,35 @@ using namespace LLNotificationsUI;
//--------------------------------------------------------------------------
LLNotificationManager::LLNotificationManager()
{
- mNotifyHandlers.clear();
init();
}
//--------------------------------------------------------------------------
LLNotificationManager::~LLNotificationManager()
{
- BOOST_FOREACH(listener_pair_t& pair, mChannelListeners)
- {
- pair.second.disconnect();
- }
}
//--------------------------------------------------------------------------
void LLNotificationManager::init()
{
- LLNotificationChannel::buildChannel("Notifications", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "notify"));
- LLNotificationChannel::buildChannel("NotificationTips", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "notifytip"));
- LLNotificationChannel::buildChannel("Group Notifications", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "groupnotify"));
- LLNotificationChannel::buildChannel("Alerts", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "alert"));
- LLNotificationChannel::buildChannel("AlertModal", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "alertmodal"));
- LLNotificationChannel::buildChannel("IM Notifications", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "notifytoast"));
- LLNotificationChannel::buildChannel("Offer", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "offer"));
- LLNotificationChannel::buildChannel("Hints", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "hint"));
- LLNotificationChannel::buildChannel("Browser", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "browser"));
- LLNotificationChannel::buildChannel("Outbox", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "outbox"));
+ mChannels.push_back(new LLScriptHandler());
+ mChannels.push_back(new LLTipHandler());
+ mChannels.push_back(new LLGroupHandler());
+ mChannels.push_back(new LLAlertHandler("Alerts", "alert", false));
+ mChannels.push_back(new LLAlertHandler("AlertModal", "alertmodal", true));
+ mChannels.push_back(new LLOfferHandler());
+ mChannels.push_back(new LLHintHandler());
+ mChannels.push_back(new LLBrowserNotification());
+ mChannels.push_back(new LLOutboxNotification());
+ mChannels.push_back(new LLIMHandler());
- mChannelListeners["Notifications"] = LLNotifications::instance().getChannel("Notifications")->connectChanged(boost::bind(&LLNotificationManager::onNotification, this, _1));
- mChannelListeners["NotificationTips"] = LLNotifications::instance().getChannel("NotificationTips")->connectChanged(boost::bind(&LLNotificationManager::onNotification, this, _1));
- mChannelListeners["Group Notifications"] = LLNotifications::instance().getChannel("Group Notifications")->connectChanged(boost::bind(&LLNotificationManager::onNotification, this, _1));
- mChannelListeners["Alerts"] = LLNotifications::instance().getChannel("Alerts")->connectChanged(boost::bind(&LLNotificationManager::onNotification, this, _1));
- mChannelListeners["AlertModal"] = LLNotifications::instance().getChannel("AlertModal")->connectChanged(boost::bind(&LLNotificationManager::onNotification, this, _1));
- mChannelListeners["IM Notifications"] = LLNotifications::instance().getChannel("IM Notifications")->connectChanged(boost::bind(&LLNotificationManager::onNotification, this, _1));
- mChannelListeners["Offer"] = LLNotifications::instance().getChannel("Offer")->connectChanged(boost::bind(&LLNotificationManager::onNotification, this, _1));
- mChannelListeners["Hints"] = LLNotifications::instance().getChannel("Hints")->connectChanged(boost::bind(&LLHintHandler::processNotification, LLHintHandler::getInstance(), _1));
- mChannelListeners["Browser"] = LLNotifications::instance().getChannel("Browser")->connectChanged(boost::bind(&LLBrowserNotification::processNotification, LLBrowserNotification::getInstance(), _1));
- mChannelListeners["Outbox"] = LLNotifications::instance().getChannel("Outbox")->connectChanged(boost::bind(&LLOutboxNotification::processNotification, LLOutboxNotification::getInstance(), _1));
-
- mNotifyHandlers["notify"] = boost::shared_ptr<LLEventHandler>(new LLScriptHandler(NT_NOTIFY, LLSD()));
- mNotifyHandlers["notifytip"] = boost::shared_ptr<LLEventHandler>(new LLTipHandler(NT_NOTIFY, LLSD()));
- mNotifyHandlers["groupnotify"] = boost::shared_ptr<LLEventHandler>(new LLGroupHandler(NT_GROUPNOTIFY, LLSD()));
- mNotifyHandlers["alert"] = boost::shared_ptr<LLEventHandler>(new LLAlertHandler(NT_ALERT, LLSD()));
- mNotifyHandlers["alertmodal"] = boost::shared_ptr<LLEventHandler>(new LLAlertHandler(NT_ALERT, LLSD()));
- static_cast<LLAlertHandler*>(mNotifyHandlers["alertmodal"].get())->setAlertMode(true);
- mNotifyHandlers["notifytoast"] = boost::shared_ptr<LLEventHandler>(new LLIMHandler(NT_IMCHAT, LLSD()));
-
- mNotifyHandlers["nearbychat"] = boost::shared_ptr<LLEventHandler>(new LLNearbyChatHandler(NT_NEARBYCHAT, LLSD()));
- mNotifyHandlers["offer"] = boost::shared_ptr<LLEventHandler>(new LLOfferHandler(NT_OFFER, LLSD()));
-}
-
-//--------------------------------------------------------------------------
-bool LLNotificationManager::onNotification(const LLSD& notify)
-{
- LLSysHandler* handle = NULL;
-
- if (LLNotifications::destroyed())
- return false;
-
- LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID());
-
- if (!notification)
- return false;
-
- std::string notification_type = notification->getType();
- handle = static_cast<LLSysHandler*>(mNotifyHandlers[notification_type].get());
-
- if(!handle)
- return false;
-
- return handle->processNotification(notify);
+ mChatHandler = boost::shared_ptr<LLFloaterIMNearbyChatHandler>(new LLFloaterIMNearbyChatHandler());
}
//--------------------------------------------------------------------------
void LLNotificationManager::onChat(const LLChat& msg, const LLSD &args)
{
- // check ENotificationType argument
- switch(args["type"].asInteger())
- {
- case NT_NEARBYCHAT:
- {
- LLNearbyChatHandler* handle = dynamic_cast<LLNearbyChatHandler*>(mNotifyHandlers["nearbychat"].get());
-
- if(handle)
- handle->processChat(msg, args);
+ if(mChatHandler)
+ mChatHandler->processChat(msg, args);
}
- break;
- default: //no need to handle all enum types
- break;
- }
-}
-
-//--------------------------------------------------------------------------
-LLEventHandler* LLNotificationManager::getHandlerForNotification(std::string notification_type)
-{
- std::map<std::string, boost::shared_ptr<LLEventHandler> >::iterator it = mNotifyHandlers.find(notification_type);
-
- if(it != mNotifyHandlers.end())
- return (*it).second.get();
-
- return NULL;
-}
-
-//--------------------------------------------------------------------------
diff --git a/indra/newview/llnotificationmanager.h b/indra/newview/llnotificationmanager.h
index 27b6ba1c71..f37c6b833c 100644..100755
--- a/indra/newview/llnotificationmanager.h
+++ b/indra/newview/llnotificationmanager.h
@@ -28,8 +28,6 @@
#ifndef LL_LLNOTIFICATIONMANAGER_H
#define LL_LLNOTIFICATIONMANAGER_H
-#include "llevents.h"
-
#include "lluictrl.h"
#include "llnotificationhandler.h"
@@ -49,7 +47,6 @@ class LLToast;
class LLNotificationManager : public LLSingleton<LLNotificationManager>
{
typedef std::pair<std::string, LLEventHandler*> eventhandlers;
- typedef std::pair<const std::string, LLBoundListener> listener_pair_t;
public:
LLNotificationManager();
virtual ~LLNotificationManager();
@@ -59,22 +56,12 @@ public:
void init(void);
//TODO: combine processing and storage (*)
- // this method reacts on system notifications and calls an appropriate handler
- bool onNotification(const LLSD& notification);
-
// this method reacts on chat notifications and calls an appropriate handler
void onChat(const LLChat& msg, const LLSD &args);
- // get a handler for a certain type of notification
- LLEventHandler* getHandlerForNotification(std::string notification_type);
-
-
private:
- //TODO (*)
- std::map<std::string, boost::shared_ptr<LLEventHandler> > mNotifyHandlers;
- // cruft std::map<std::string, LLChatHandler*> mChatHandlers;
-
- std::map<std::string, LLBoundListener> mChannelListeners;
+ boost::shared_ptr<class LLFloaterIMNearbyChatHandler> mChatHandler;
+ std::vector<LLNotificationChannelPtr> mChannels;
};
}
diff --git a/indra/newview/llnotificationofferhandler.cpp b/indra/newview/llnotificationofferhandler.cpp
index 1552ed3346..2657b84ef3 100644..100755
--- a/indra/newview/llnotificationofferhandler.cpp
+++ b/indra/newview/llnotificationofferhandler.cpp
@@ -40,16 +40,14 @@
using namespace LLNotificationsUI;
//--------------------------------------------------------------------------
-LLOfferHandler::LLOfferHandler(e_notification_type type, const LLSD& id)
+LLOfferHandler::LLOfferHandler()
+: LLCommunicationNotificationHandler("Offer", "offer")
{
- mType = type;
-
// Getting a Channel for our notifications
LLScreenChannel* channel = LLChannelManager::getInstance()->createNotificationChannel();
if(channel)
{
channel->setControlHovering(true);
- channel->setOnRejectToastCallback(boost::bind(&LLOfferHandler::onRejectToast, this, _1));
mChannel = channel->getHandle();
}
}
@@ -68,147 +66,124 @@ void LLOfferHandler::initChannel()
}
//--------------------------------------------------------------------------
-bool LLOfferHandler::processNotification(const LLSD& notify)
+bool LLOfferHandler::processNotification(const LLNotificationPtr& notification)
{
if(mChannel.isDead())
{
return false;
}
- LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID());
-
- if(!notification)
- return false;
-
// arrange a channel on a screen
if(!mChannel.get()->getVisible())
{
initChannel();
}
- if(notify["sigtype"].asString() == "add" || notify["sigtype"].asString() == "change")
- {
+ if( notification->getPayload().has("give_inventory_notification")
+ && notification->getPayload()["give_inventory_notification"].asBoolean() == false)
+ {
+ // This is an original inventory offer, so add a script floater
+ LLScriptFloaterManager::instance().onAddNotification(notification->getID());
+ }
+ else
+ {
+ bool add_notif_to_im = notification->canLogToIM() && notification->hasFormElements();
- if( notification->getPayload().has("give_inventory_notification")
- && !notification->getPayload()["give_inventory_notification"] )
+ if (add_notif_to_im)
{
- // This is an original inventory offer, so add a script floater
- LLScriptFloaterManager::instance().onAddNotification(notification->getID());
+ const std::string name = LLHandlerUtil::getSubstitutionName(notification);
+
+ LLUUID from_id = notification->getPayload()["from_id"];
+
+ //Will not play a notification sound for inventory and teleport offer based upon chat preference
+ bool playSound = (!notification->isDND()
+ && ((notification->getName() == "UserGiveItem"
+ && gSavedSettings.getBOOL("PlaySoundInventoryOffer"))
+ || (notification->getName() == "TeleportOffered"
+ && gSavedSettings.getBOOL("PlaySoundTeleportOffer"))));
+
+ if(playSound)
+ {
+ notification->playSound();
+ }
+
+ LLHandlerUtil::spawnIMSession(name, from_id);
+ LLHandlerUtil::addNotifPanelToIM(notification);
+
}
- else
+
+ if (!notification->canShowToast())
{
- notification->setReusable(LLHandlerUtil::isNotificationReusable(notification));
-
- LLUUID session_id;
- if (LLHandlerUtil::canSpawnIMSession(notification))
- {
- const std::string name = LLHandlerUtil::getSubstitutionName(notification);
-
- LLUUID from_id = notification->getPayload()["from_id"];
-
- session_id = LLHandlerUtil::spawnIMSession(name, from_id);
- }
-
- bool show_toast = LLHandlerUtil::canSpawnToast(notification);
- bool add_notid_to_im = LLHandlerUtil::canAddNotifPanelToIM(notification);
- if (add_notid_to_im)
- {
- LLHandlerUtil::addNotifPanelToIM(notification);
- }
-
- if (notification->getPayload().has("SUPPRESS_TOAST")
- && notification->getPayload()["SUPPRESS_TOAST"])
- {
- LLNotificationsUtil::cancel(notification);
- }
- else if(show_toast)
- {
- LLToastNotifyPanel* notify_box = new LLToastNotifyPanel(notification);
- // don't close notification on panel destroy since it will be used by IM floater
- notify_box->setCloseNotificationOnDestroy(!add_notid_to_im);
- LLToast::Params p;
- p.notif_id = notification->getID();
- p.notification = notification;
- p.panel = notify_box;
- p.on_delete_toast = boost::bind(&LLOfferHandler::onDeleteToast, this, _1);
- // we not save offer notifications to the syswell floater that should be added to the IM floater
- p.can_be_stored = !add_notid_to_im;
-
- LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel.get());
- if(channel)
- channel->addToast(p);
-
- // if we not add notification to IM - add it to notification well
- if (!add_notid_to_im)
- {
- // send a signal to the counter manager
- mNewNotificationSignal();
- }
- }
-
- if (LLHandlerUtil::canLogToIM(notification))
- {
- // log only to file if notif panel can be embedded to IM and IM is opened
- if (add_notid_to_im && LLHandlerUtil::isIMFloaterOpened(notification))
- {
- LLHandlerUtil::logToIMP2P(notification, true);
- }
- else
- {
- LLHandlerUtil::logToIMP2P(notification);
- }
- }
+ LLNotificationsUtil::cancel(notification);
}
- }
- else if (notify["sigtype"].asString() == "delete")
- {
- if( notification->getPayload().has("give_inventory_notification")
- && !notification->getPayload()["give_inventory_notification"] )
+ else if(!notification->canLogToIM() || !LLHandlerUtil::isIMFloaterOpened(notification))
{
- // Remove original inventory offer script floater
- LLScriptFloaterManager::instance().onRemoveNotification(notification->getID());
+ LLToastNotifyPanel* notify_box = new LLToastNotifyPanel(notification);
+ LLToast::Params p;
+ p.notif_id = notification->getID();
+ p.notification = notification;
+ p.panel = notify_box;
+ // we not save offer notifications to the syswell floater that should be added to the IM floater
+ p.can_be_stored = !add_notif_to_im;
+ p.force_show = notification->getOfferFromAgent();
+
+ LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel.get());
+ if(channel)
+ channel->addToast(p);
+
}
- else
+
+ if (notification->canLogToIM())
{
- if (LLHandlerUtil::canAddNotifPanelToIM(notification)
- && !LLHandlerUtil::isIMFloaterOpened(notification))
- {
- LLHandlerUtil::decIMMesageCounter(notification);
- }
- mChannel.get()->killToastByNotificationID(notification->getID());
+ // log only to file if notif panel can be embedded to IM and IM is opened
+ bool file_only = add_notif_to_im && LLHandlerUtil::isIMFloaterOpened(notification);
+ LLHandlerUtil::logToIMP2P(notification, file_only);
}
}
return false;
}
-//--------------------------------------------------------------------------
-
-void LLOfferHandler::onDeleteToast(LLToast* toast)
+/*virtual*/ void LLOfferHandler::onChange(LLNotificationPtr p)
{
- if (!LLHandlerUtil::canAddNotifPanelToIM(toast->getNotification()))
+ LLToastNotifyPanel* panelp = LLToastNotifyPanel::getInstance(p->getID());
+ if (panelp)
{
- // send a signal to the counter manager
- mDelNotificationSignal();
+ //
+ // HACK: if we're dealing with a notification embedded in IM, update it
+ // otherwise remove its toast
+ //
+ if (dynamic_cast<LLIMToastNotifyPanel*>(panelp))
+ {
+ panelp->updateNotification();
+ }
+ else
+ {
+ // if notification has changed, hide it
+ mChannel.get()->removeToastByNotificationID(p->getID());
+ }
}
-
- // send a signal to a listener to let him perform some action
- // in this case listener is a SysWellWindow and it will remove a corresponding item from its list
- mNotificationIDSignal(toast->getNotificationID());
}
-//--------------------------------------------------------------------------
-void LLOfferHandler::onRejectToast(LLUUID& id)
-{
- LLNotificationPtr notification = LLNotifications::instance().find(id);
- if (notification
- && LLNotificationManager::getInstance()->getHandlerForNotification(
- notification->getType()) == this
- // don't delete notification since it may be used by IM floater
- && !LLHandlerUtil::canAddNotifPanelToIM(notification))
+/*virtual*/ void LLOfferHandler::onDelete(LLNotificationPtr notification)
+{
+ if( notification->getPayload().has("give_inventory_notification")
+ && !notification->getPayload()["give_inventory_notification"] )
{
- LLNotifications::instance().cancel(notification);
+ // Remove original inventory offer script floater
+ LLScriptFloaterManager::instance().onRemoveNotification(notification->getID());
+ }
+ else
+ {
+ if (notification->canLogToIM()
+ && notification->hasFormElements()
+ && !LLHandlerUtil::isIMFloaterOpened(notification))
+ {
+ LLHandlerUtil::decIMMesageCounter(notification);
+ }
+ mChannel.get()->removeToastByNotificationID(notification->getID());
}
}
+
diff --git a/indra/newview/llnotificationscripthandler.cpp b/indra/newview/llnotificationscripthandler.cpp
index 995915206b..a3b15931c6 100644..100755
--- a/indra/newview/llnotificationscripthandler.cpp
+++ b/indra/newview/llnotificationscripthandler.cpp
@@ -27,6 +27,7 @@
#include "llviewerprecompiledheaders.h" // must be first include
+#include "llagent.h"
#include "llnotificationhandler.h"
#include "lltoastnotifypanel.h"
#include "llviewercontrol.h"
@@ -34,24 +35,21 @@
#include "llnotificationmanager.h"
#include "llnotifications.h"
#include "llscriptfloater.h"
+#include "llfacebookconnect.h"
+#include "llavatarname.h"
+#include "llavatarnamecache.h"
using namespace LLNotificationsUI;
-static const std::string SCRIPT_DIALOG ("ScriptDialog");
-static const std::string SCRIPT_DIALOG_GROUP ("ScriptDialogGroup");
-static const std::string SCRIPT_LOAD_URL ("LoadWebPage");
-
//--------------------------------------------------------------------------
-LLScriptHandler::LLScriptHandler(e_notification_type type, const LLSD& id)
+LLScriptHandler::LLScriptHandler()
+: LLSystemNotificationHandler("Notifications", "notify")
{
- mType = type;
-
// Getting a Channel for our notifications
LLScreenChannel* channel = LLChannelManager::getInstance()->createNotificationChannel();
if(channel)
{
channel->setControlHovering(true);
- channel->setOnRejectToastCallback(boost::bind(&LLScriptHandler::onRejectToast, this, _1));
mChannel = channel->getHandle();
}
}
@@ -70,104 +68,83 @@ void LLScriptHandler::initChannel()
}
//--------------------------------------------------------------------------
-bool LLScriptHandler::processNotification(const LLSD& notify)
+bool LLScriptHandler::processNotification(const LLNotificationPtr& notification)
{
if(mChannel.isDead())
{
return false;
}
- LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID());
-
- if(!notification)
- return false;
-
// arrange a channel on a screen
if(!mChannel.get()->getVisible())
{
initChannel();
}
- if(notify["sigtype"].asString() == "add")
+ if (notification->canLogToIM())
{
- if (LLHandlerUtil::canLogToIM(notification))
- {
- LLHandlerUtil::logToIMP2P(notification);
- }
+ LLHandlerUtil::logToIMP2P(notification);
+ }
- if(SCRIPT_DIALOG == notification->getName() || SCRIPT_DIALOG_GROUP == notification->getName() || SCRIPT_LOAD_URL == notification->getName())
- {
- LLScriptFloaterManager::getInstance()->onAddNotification(notification->getID());
+ if(notification->hasFormElements() && !notification->canShowToast())
+ {
+ LLScriptFloaterManager::getInstance()->onAddNotification(notification->getID());
+ }
+ else if (notification->canShowToast())
+ {
+ LLToastPanel* notify_box = LLToastPanel::buidPanelFromNotification(notification);
+
+ LLToast::Params p;
+ p.notif_id = notification->getID();
+ p.notification = notification;
+ p.panel = notify_box;
+ p.on_delete_toast = boost::bind(&LLScriptHandler::onDeleteToast, this, _1);
+ if(gAgent.isDoNotDisturb())
+ {
+ p.force_show = notification->getName() == "SystemMessage"
+ || notification->getName() == "GodMessage"
+ || notification->getPriority() >= NOTIFICATION_PRIORITY_HIGH;
}
- else
+
+ LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel.get());
+ if(channel)
{
- LLToastNotifyPanel* notify_box = new LLToastNotifyPanel(notification);
-
- LLToast::Params p;
- p.notif_id = notification->getID();
- p.notification = notification;
- p.panel = notify_box;
- p.on_delete_toast = boost::bind(&LLScriptHandler::onDeleteToast, this, _1);
-
- LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel.get());
- if(channel)
- {
- channel->addToast(p);
- }
-
- // send a signal to the counter manager
- mNewNotificationSignal();
+ channel->addToast(p);
}
}
- else if (notify["sigtype"].asString() == "delete")
+
+ return false;
+}
+
+
+void LLScriptHandler::onDelete( LLNotificationPtr notification )
{
- if(SCRIPT_DIALOG == notification->getName() || SCRIPT_DIALOG_GROUP == notification->getName() || SCRIPT_LOAD_URL == notification->getName())
+ if(notification->hasFormElements() && !notification->canShowToast())
{
LLScriptFloaterManager::getInstance()->onRemoveNotification(notification->getID());
}
else
{
- mChannel.get()->killToastByNotificationID(notification->getID());
+ mChannel.get()->removeToastByNotificationID(notification->getID());
}
}
- return false;
-}
+
//--------------------------------------------------------------------------
void LLScriptHandler::onDeleteToast(LLToast* toast)
{
- // send a signal to the counter manager
- mDelNotificationSignal();
-
// send a signal to a listener to let him perform some action
// in this case listener is a SysWellWindow and it will remove a corresponding item from its list
- mNotificationIDSignal(toast->getNotificationID());
-
LLNotificationPtr notification = LLNotifications::getInstance()->find(toast->getNotificationID());
- if( notification &&
- (SCRIPT_DIALOG == notification->getName() || SCRIPT_DIALOG_GROUP == notification->getName()) )
+ if( notification && notification->hasFormElements() && !notification->canShowToast())
{
LLScriptFloaterManager::getInstance()->onRemoveNotification(notification->getID());
}
-}
-
-//--------------------------------------------------------------------------
-void LLScriptHandler::onRejectToast(LLUUID& id)
-{
- LLNotificationPtr notification = LLNotifications::instance().find(id);
- if (notification
- && LLNotificationManager::getInstance()->getHandlerForNotification(
- notification->getType()) == this)
- {
- LLNotifications::instance().cancel(notification);
- }
}
-//--------------------------------------------------------------------------
-
diff --git a/indra/newview/llnotificationstorage.cpp b/indra/newview/llnotificationstorage.cpp
index fb1adc7ddf..2923221c90 100644..100755
--- a/indra/newview/llnotificationstorage.cpp
+++ b/indra/newview/llnotificationstorage.cpp
@@ -25,197 +25,115 @@
*/
#include "llviewerprecompiledheaders.h" // must be first include
+
#include "llnotificationstorage.h"
-#include "llxmlnode.h" // for linux compilers
+#include <string>
+#include <map>
-#include "llchannelmanager.h"
-#include "llscreenchannel.h"
-#include "llscriptfloater.h"
+#include "llerror.h"
+#include "llfile.h"
+#include "llnotifications.h"
+#include "llpointer.h"
+#include "llsd.h"
#include "llsdserialize.h"
-#include "llviewermessage.h"
+#include "llsingleton.h"
+#include "llregistry.h"
+#include "llviewermessage.h"
-//////////////////////////////////////////////////////////////////////////
+typedef boost::function<LLNotificationResponderInterface * (const LLSD& pParams)> responder_constructor_t;
-class LLResponderRegistry
+class LLResponderRegistry : public LLRegistrySingleton<std::string, responder_constructor_t, LLResponderRegistry>
{
-public:
-
- static void registerResponders();
-
- static LLNotificationResponderInterface* createResponder(const std::string& notification_name, const LLSD& params);
-
-private:
-
- template<typename RESPONDER_TYPE>
- static LLNotificationResponderInterface* create(const LLSD& params)
- {
- RESPONDER_TYPE* responder = new RESPONDER_TYPE();
- responder->fromLLSD(params);
- return responder;
- }
-
- typedef boost::function<LLNotificationResponderInterface* (const LLSD& params)> responder_constructor_t;
+ public:
+ template<typename RESPONDER_TYPE> static LLNotificationResponderInterface * create(const LLSD& pParams);
+ LLNotificationResponderInterface * createResponder(const std::string& pNotificationName, const LLSD& pParams);
+};
- static void add(const std::string& notification_name, const responder_constructor_t& ctr);
+template<typename RESPONDER_TYPE> LLNotificationResponderInterface * LLResponderRegistry::create(const LLSD& pParams)
+{
+ RESPONDER_TYPE* responder = new RESPONDER_TYPE();
+ responder->fromLLSD(pParams);
+ return responder;
+}
-private:
- typedef std::map<std::string, responder_constructor_t> build_map_t;
+LLNotificationResponderInterface * LLResponderRegistry::createResponder(const std::string& pNotificationName, const LLSD& pParams)
+{
+ responder_constructor_t * factoryFunc = (LLResponderRegistry::getValue(pNotificationName));
+
+ if(factoryFunc)
+ {
+ return (*factoryFunc)(pParams);
+ }
+
+ return NULL;
+}
- static build_map_t sBuildMap;
-};
+LLResponderRegistry::StaticRegistrar sRegisterObjectGiveItem("ObjectGiveItem", &LLResponderRegistry::create<LLOfferInfo>);
+LLResponderRegistry::StaticRegistrar sRegisterUserGiveItem("UserGiveItem", &LLResponderRegistry::create<LLOfferInfo>);
+LLResponderRegistry::StaticRegistrar sRegisterOfferInfo("offer_info", &LLResponderRegistry::create<LLOfferInfo>);
-//////////////////////////////////////////////////////////////////////////
-LLPersistentNotificationStorage::LLPersistentNotificationStorage()
+LLNotificationStorage::LLNotificationStorage(std::string pFileName)
+ : mFileName(pFileName)
{
- mFileName = gDirUtilp->getExpandedFilename ( LL_PATH_PER_SL_ACCOUNT, "open_notifications.xml" );
}
-bool LLPersistentNotificationStorage::onPersistentChannelChanged(const LLSD& payload)
+LLNotificationStorage::~LLNotificationStorage()
{
- // we ignore "load" messages, but rewrite the persistence file on any other
- const std::string sigtype = payload["sigtype"].asString();
- if ("load" != sigtype)
- {
- saveNotifications();
- }
- return false;
}
-void LLPersistentNotificationStorage::saveNotifications()
+bool LLNotificationStorage::writeNotifications(const LLSD& pNotificationData) const
{
- // TODO - think about save optimization.
- llofstream notify_file(mFileName.c_str());
- if (!notify_file.is_open())
+ llofstream notifyFile(mFileName.c_str());
+ bool didFileOpen = notifyFile.is_open();
+
+ if (!didFileOpen)
{
- llwarns << "Failed to open " << mFileName << llendl;
- return;
+ LL_WARNS("LLNotificationStorage") << "Failed to open file '" << mFileName << "'" << LL_ENDL;
}
-
- LLSD output;
- LLSD& data = output["data"];
-
- LLNotificationChannelPtr history_channel = LLNotifications::instance().getChannel("Persistent");
- LLNotificationSet::iterator it = history_channel->begin();
-
- for ( ; history_channel->end() != it; ++it)
+ else
{
- LLNotificationPtr notification = *it;
-
- // After a notification was placed in Persist channel, it can become
- // responded, expired or canceled - in this case we are should not save it
- if(notification->isRespondedTo() || notification->isCancelled()
- || notification->isExpired())
- {
- continue;
- }
-
- data.append(notification->asLLSD());
+ LLPointer<LLSDFormatter> formatter = new LLSDXMLFormatter();
+ formatter->format(pNotificationData, notifyFile, LLSDFormatter::OPTIONS_PRETTY);
}
- LLPointer<LLSDFormatter> formatter = new LLSDXMLFormatter();
- formatter->format(output, notify_file, LLSDFormatter::OPTIONS_PRETTY);
+ return didFileOpen;
}
-void LLPersistentNotificationStorage::loadNotifications()
+bool LLNotificationStorage::readNotifications(LLSD& pNotificationData) const
{
- LLResponderRegistry::registerResponders();
+ LL_INFOS("LLNotificationStorage") << "starting read '" << mFileName << "'" << LL_ENDL;
- LLNotifications::instance().getChannel("Persistent")->
- connectChanged(boost::bind(&LLPersistentNotificationStorage::onPersistentChannelChanged, this, _1));
+ bool didFileRead;
- llifstream notify_file(mFileName.c_str());
- if (!notify_file.is_open())
- {
- llwarns << "Failed to open " << mFileName << llendl;
- return;
- }
+ pNotificationData.clear();
- LLSD input;
- LLPointer<LLSDParser> parser = new LLSDXMLParser();
- if (parser->parse(notify_file, input, LLSDSerialize::SIZE_UNLIMITED) < 0)
+ llifstream notifyFile(mFileName.c_str());
+ didFileRead = notifyFile.is_open();
+ if (!didFileRead)
{
- llwarns << "Failed to parse open notifications" << llendl;
- return;
+ LL_WARNS("LLNotificationStorage") << "Failed to open file '" << mFileName << "'" << LL_ENDL;
}
-
- if (input.isUndefined())
- {
- return;
- }
-
- LLSD& data = input["data"];
- if (data.isUndefined())
+ else
{
- return;
- }
-
- using namespace LLNotificationsUI;
- LLScreenChannel* notification_channel = dynamic_cast<LLScreenChannel*>(LLChannelManager::getInstance()->
- findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID"))));
-
- LLNotifications& instance = LLNotifications::instance();
-
- for (LLSD::array_const_iterator notification_it = data.beginArray();
- notification_it != data.endArray();
- ++notification_it)
- {
- LLSD notification_params = *notification_it;
- LLNotificationPtr notification(new LLNotification(notification_params));
-
- LLNotificationResponderPtr responder(LLResponderRegistry::
- createResponder(notification_params["name"], notification_params["responder"]));
- notification->setResponseFunctor(responder);
-
- instance.add(notification);
-
- // hide script floaters so they don't confuse the user and don't overlap startup toast
- LLScriptFloaterManager::getInstance()->setFloaterVisible(notification->getID(), false);
-
- if(notification_channel)
+ LLPointer<LLSDParser> parser = new LLSDXMLParser();
+ didFileRead = (parser->parse(notifyFile, pNotificationData, LLSDSerialize::SIZE_UNLIMITED) >= 0);
+ if (!didFileRead)
{
- // hide saved toasts so they don't confuse the user
- notification_channel->hideToast(notification->getID());
+ LL_WARNS("LLNotificationStorage") << "Failed to parse open notifications from file '" << mFileName
+ << "'" << LL_ENDL;
}
}
-}
-
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-
-LLResponderRegistry::build_map_t LLResponderRegistry::sBuildMap;
-void LLResponderRegistry::registerResponders()
-{
- sBuildMap.clear();
-
- add("ObjectGiveItem", &create<LLOfferInfo>);
- add("UserGiveItem", &create<LLOfferInfo>);
-}
+ LL_INFOS("LLNotificationStorage") << "ending read '" << mFileName << "'" << LL_ENDL;
-LLNotificationResponderInterface* LLResponderRegistry::createResponder(const std::string& notification_name, const LLSD& params)
-{
- build_map_t::const_iterator it = sBuildMap.find(notification_name);
- if(sBuildMap.end() == it)
- {
- return NULL;
- }
- responder_constructor_t ctr = it->second;
- return ctr(params);
+ return didFileRead;
}
-void LLResponderRegistry::add(const std::string& notification_name, const responder_constructor_t& ctr)
+LLNotificationResponderInterface * LLNotificationStorage::createResponder(const std::string& pNotificationName, const LLSD& pParams) const
{
- if(sBuildMap.find(notification_name) != sBuildMap.end())
- {
- llwarns << "Responder is already registered : " << notification_name << llendl;
- llassert(!"Responder already registered");
- }
- sBuildMap[notification_name] = ctr;
+ return LLResponderRegistry::getInstance()->createResponder(pNotificationName, pParams);
}
-
-// EOF
diff --git a/indra/newview/llnotificationstorage.h b/indra/newview/llnotificationstorage.h
index 8635c797c0..53fd898ea4 100644..100755
--- a/indra/newview/llnotificationstorage.h
+++ b/indra/newview/llnotificationstorage.h
@@ -27,32 +27,28 @@
#ifndef LL_NOTIFICATIONSTORAGE_H
#define LL_NOTIFICATIONSTORAGE_H
-#include "llnotifications.h"
-
-// Class that saves not responded(unread) notifications.
-// Unread notifications are saved in open_notifications.xml in SL account folder
-//
-// Notifications that should be saved(if unread) are marked with persist="true" in notifications.xml
-// Notifications using functor responders are saved automatically (see llviewermessage.cpp
-// lure_callback_reg for example).
-// Notifications using object responders(LLOfferInfo) need additional tuning. Responder object should
-// be a) serializable(implement LLNotificationResponderInterface),
-// b) registered with LLResponderRegistry (found in llnotificationstorage.cpp).
-class LLPersistentNotificationStorage : public LLSingleton<LLPersistentNotificationStorage>
-{
- LOG_CLASS(LLPersistentNotificationStorage);
-public:
+#include <string>
- LLPersistentNotificationStorage();
+#include "llerror.h"
- void saveNotifications();
+class LLNotificationResponderInterface;
+class LLSD;
- void loadNotifications();
+class LLNotificationStorage
+{
+ LOG_CLASS(LLNotificationStorage);
+public:
+ LLNotificationStorage(std::string pFileName);
+ ~LLNotificationStorage();
-private:
+protected:
+ bool writeNotifications(const LLSD& pNotificationData) const;
+ bool readNotifications(LLSD& pNotificationData) const;
+ void setFileName(std::string pFileName) {mFileName = pFileName;}
- bool onPersistentChannelChanged(const LLSD& payload);
+ LLNotificationResponderInterface* createResponder(const std::string& pNotificationName, const LLSD& pParams) const;
+private:
std::string mFileName;
};
diff --git a/indra/newview/llnotificationtiphandler.cpp b/indra/newview/llnotificationtiphandler.cpp
index e397cfa046..4ca961c1f9 100644..100755
--- a/indra/newview/llnotificationtiphandler.cpp
+++ b/indra/newview/llnotificationtiphandler.cpp
@@ -28,8 +28,8 @@
#include "llviewerprecompiledheaders.h" // must be first include
#include "llfloaterreg.h"
-#include "llnearbychat.h"
-#include "llnearbychatbar.h"
+#include "llfloaterimnearbychat.h"
+#include "llfloaterimnearbychat.h"
#include "llnotificationhandler.h"
#include "llnotifications.h"
#include "lltoastnotifypanel.h"
@@ -41,15 +41,13 @@
using namespace LLNotificationsUI;
//--------------------------------------------------------------------------
-LLTipHandler::LLTipHandler(e_notification_type type, const LLSD& id)
+LLTipHandler::LLTipHandler()
+: LLSystemNotificationHandler("NotificationTips", "notifytip")
{
- mType = type;
-
// Getting a Channel for our notifications
LLScreenChannel* channel = LLChannelManager::getInstance()->createNotificationChannel();
if(channel)
{
- channel->setOnRejectToastCallback(boost::bind(&LLTipHandler::onRejectToast, this, _1));
mChannel = channel->getHandle();
}
}
@@ -68,102 +66,60 @@ void LLTipHandler::initChannel()
}
//--------------------------------------------------------------------------
-bool LLTipHandler::processNotification(const LLSD& notify)
+bool LLTipHandler::processNotification(const LLNotificationPtr& notification)
{
if(mChannel.isDead())
{
return false;
}
- LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID());
-
- if(!notification)
- return false;
-
// arrange a channel on a screen
if(!mChannel.get()->getVisible())
{
initChannel();
}
- if(notify["sigtype"].asString() == "add" || notify["sigtype"].asString() == "change")
- {
// archive message in nearby chat
- if (LLHandlerUtil::canLogToNearbyChat(notification))
- {
- LLHandlerUtil::logToNearbyChat(notification, CHAT_SOURCE_SYSTEM);
-
- // don't show toast if Nearby Chat is opened
- LLNearbyChat* nearby_chat = LLNearbyChat::getInstance();
- LLNearbyChatBar* nearby_chat_bar = LLNearbyChatBar::getInstance();
- if (!nearby_chat_bar->isMinimized() && nearby_chat_bar->getVisible() && nearby_chat->getVisible())
- {
- return false;
- }
- }
-
- std::string session_name = notification->getPayload()["SESSION_NAME"];
- const std::string name = notification->getSubstitutions()["NAME"];
- if (session_name.empty())
- {
- session_name = name;
- }
- LLUUID from_id = notification->getPayload()["from_id"];
- if (LLHandlerUtil::canLogToIM(notification))
- {
- LLHandlerUtil::logToIM(IM_NOTHING_SPECIAL, session_name, name,
- notification->getMessage(), from_id, from_id);
- }
-
- if (LLHandlerUtil::canSpawnIMSession(notification))
- {
- LLHandlerUtil::spawnIMSession(name, from_id);
- }
-
- // don't spawn toast for inventory accepted/declined offers if respective IM window is open (EXT-5909)
- if (!LLHandlerUtil::canSpawnToast(notification))
- {
- return false;
- }
-
- LLToastPanel* notify_box = LLToastPanel::buidPanelFromNotification(notification);
-
- LLToast::Params p;
- p.notif_id = notification->getID();
- p.notification = notification;
- p.lifetime_secs = gSavedSettings.getS32("NotificationTipToastLifeTime");
- p.panel = notify_box;
- p.is_tip = true;
- p.can_be_stored = false;
-
- removeExclusiveNotifications(notification);
+ if (notification->canLogToChat())
+ {
+ LLHandlerUtil::logToNearbyChat(notification, CHAT_SOURCE_SYSTEM);
+ }
- LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel.get());
- if(channel)
- channel->addToast(p);
+ std::string session_name = notification->getPayload()["SESSION_NAME"];
+ const std::string name = notification->getSubstitutions()["NAME"];
+ if (session_name.empty())
+ {
+ session_name = name;
}
- else if (notify["sigtype"].asString() == "delete")
+ LLUUID from_id = notification->getPayload()["from_id"];
+ if (notification->canLogToIM())
{
- mChannel.get()->killToastByNotificationID(notification->getID());
+ LLHandlerUtil::logToIM(IM_NOTHING_SPECIAL, session_name, name,
+ notification->getMessage(), from_id, from_id);
}
- return false;
-}
-//--------------------------------------------------------------------------
-void LLTipHandler::onDeleteToast(LLToast* toast)
-{
-}
-
-//--------------------------------------------------------------------------
-
-void LLTipHandler::onRejectToast(const LLUUID& id)
-{
- LLNotificationPtr notification = LLNotifications::instance().find(id);
+ if (notification->canLogToIM() && notification->hasFormElements())
+ {
+ LLHandlerUtil::spawnIMSession(name, from_id);
+ }
- if (notification
- && LLNotificationManager::getInstance()->getHandlerForNotification(
- notification->getType()) == this)
+ if (notification->canLogToIM() && LLHandlerUtil::isIMFloaterOpened(notification))
{
- LLNotifications::instance().cancel(notification);
+ return false;
}
+
+ LLToastPanel* notify_box = LLToastPanel::buidPanelFromNotification(notification);
+
+ LLToast::Params p;
+ p.notif_id = notification->getID();
+ p.notification = notification;
+ p.lifetime_secs = gSavedSettings.getS32("NotificationTipToastLifeTime");
+ p.panel = notify_box;
+ p.is_tip = true;
+ p.can_be_stored = false;
+
+ LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel.get());
+ if(channel)
+ channel->addToast(p);
+ return false;
}
diff --git a/indra/newview/lloutfitobserver.cpp b/indra/newview/lloutfitobserver.cpp
index 5bb69367aa..5bb69367aa 100644..100755
--- a/indra/newview/lloutfitobserver.cpp
+++ b/indra/newview/lloutfitobserver.cpp
diff --git a/indra/newview/lloutfitobserver.h b/indra/newview/lloutfitobserver.h
index 87d4b0c998..87d4b0c998 100644..100755
--- a/indra/newview/lloutfitobserver.h
+++ b/indra/newview/lloutfitobserver.h
diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp
index ef5ef2ddc8..c15b6bd0d3 100644..100755
--- a/indra/newview/lloutfitslist.cpp
+++ b/indra/newview/lloutfitslist.cpp
@@ -117,6 +117,8 @@ public:
registrar.add("Gear.Rename", boost::bind(&LLOutfitListGearMenu::onRename, this));
registrar.add("Gear.Delete", boost::bind(&LLOutfitsList::removeSelected, mOutfitList));
registrar.add("Gear.Create", boost::bind(&LLOutfitListGearMenu::onCreate, this, _2));
+ registrar.add("Gear.Collapse", boost::bind(&LLOutfitsList::collapse_all_folders, mOutfitList));
+ registrar.add("Gear.Expand", boost::bind(&LLOutfitsList::expand_all_folders, mOutfitList));
registrar.add("Gear.WearAdd", boost::bind(&LLOutfitListGearMenu::onAdd, this));
@@ -743,6 +745,34 @@ void LLOutfitsList::getSelectedItemsUUIDs(uuid_vec_t& selected_uuids) const
}
}
+void LLOutfitsList::collapse_all_folders()
+{
+ for (outfits_map_t::iterator iter = mOutfitsMap.begin();
+ iter != mOutfitsMap.end();
+ ++iter)
+ {
+ LLAccordionCtrlTab* tab = iter->second;
+ if(tab && tab->isExpanded())
+ {
+ tab->changeOpenClose(true);
+ }
+ }
+}
+
+void LLOutfitsList::expand_all_folders()
+{
+ for (outfits_map_t::iterator iter = mOutfitsMap.begin();
+ iter != mOutfitsMap.end();
+ ++iter)
+ {
+ LLAccordionCtrlTab* tab = iter->second;
+ if(tab && !tab->isExpanded())
+ {
+ tab->changeOpenClose(false);
+ }
+ }
+}
+
boost::signals2::connection LLOutfitsList::setSelectionChangeCallback(selection_change_callback_t cb)
{
return mSelectionChangeSignal.connect(cb);
diff --git a/indra/newview/lloutfitslist.h b/indra/newview/lloutfitslist.h
index a0598737f1..2e3fb3f488 100644..100755
--- a/indra/newview/lloutfitslist.h
+++ b/indra/newview/lloutfitslist.h
@@ -108,6 +108,16 @@ public:
*/
bool hasItemSelected();
+ /**
+ Collapses all outfit accordions.
+ */
+ void collapse_all_folders();
+ /**
+ Expands all outfit accordions.
+ */
+ void expand_all_folders();
+
+
private:
void onOutfitsRemovalConfirmation(const LLSD& notification, const LLSD& response);
diff --git a/indra/newview/lloutputmonitorctrl.cpp b/indra/newview/lloutputmonitorctrl.cpp
index 85626d8783..6c26073d5b 100644..100755
--- a/indra/newview/lloutputmonitorctrl.cpp
+++ b/indra/newview/lloutputmonitorctrl.cpp
@@ -28,6 +28,7 @@
#include "lloutputmonitorctrl.h"
// library includes
+#include "llfloaterreg.h"
#include "llui.h"
// viewer includes
@@ -72,8 +73,8 @@ LLOutputMonitorCtrl::LLOutputMonitorCtrl(const LLOutputMonitorCtrl::Params& p)
mAutoUpdate(p.auto_update),
mSpeakerId(p.speaker_id),
mIsAgentControl(false),
- mIsSwitchDirty(false),
- mShouldSwitchOn(false)
+ mIndicatorToggled(false),
+ mShowParticipantsSpeaking(false)
{
//static LLUIColor output_monitor_muted_color = LLUIColorTable::instance().getColor("OutputMonitorMutedColor", LLColor4::orange);
//static LLUIColor output_monitor_overdriven_color = LLUIColorTable::instance().getColor("OutputMonitorOverdrivenColor", LLColor4::red);
@@ -114,26 +115,6 @@ void LLOutputMonitorCtrl::setPower(F32 val)
void LLOutputMonitorCtrl::draw()
{
- // see also switchIndicator()
- if (mIsSwitchDirty)
- {
- mIsSwitchDirty = false;
- if (mShouldSwitchOn)
- {
- // just notify parent visibility may have changed
- notifyParentVisibilityChanged();
- }
- else
- {
- // make itself invisible and notify parent about this
- setVisible(FALSE);
- notifyParentVisibilityChanged();
-
- // no needs to render for invisible element
- return;
- }
- }
-
// Copied from llmediaremotectrl.cpp
// *TODO: Give the LLOutputMonitorCtrl an agent-id to monitor, then
// call directly into LLVoiceClient::getInstance() to ask if that agent-id is muted, is
@@ -156,6 +137,24 @@ void LLOutputMonitorCtrl::draw()
}
}
+ if ((mPower == 0.f && !mIsTalking) && mShowParticipantsSpeaking)
+ {
+ std::set<LLUUID> participant_uuids;
+ LLVoiceClient::instance().getParticipantList(participant_uuids);
+ std::set<LLUUID>::const_iterator part_it = participant_uuids.begin();
+
+ F32 power = 0;
+ for (; part_it != participant_uuids.end(); ++part_it)
+ {
+ power = LLVoiceClient::instance().getCurrentPower(*part_it);
+ if (power)
+ {
+ mPower = power;
+ break;
+ }
+ }
+ }
+
LLPointer<LLUIImage> icon;
if (mIsMuted)
{
@@ -241,14 +240,34 @@ void LLOutputMonitorCtrl::draw()
gl_rect_2d(0, monh, monw, 0, sColorBound, FALSE);
}
-void LLOutputMonitorCtrl::setSpeakerId(const LLUUID& speaker_id, const LLUUID& session_id/* = LLUUID::null*/)
+// virtual
+BOOL LLOutputMonitorCtrl::handleMouseUp(S32 x, S32 y, MASK mask)
+{
+ if (mSpeakerId != gAgentID && !mShowParticipantsSpeaking)
+ {
+ LLFloaterReg::showInstance("floater_voice_volume", LLSD().with("avatar_id", mSpeakerId));
+ }
+ else if(mShowParticipantsSpeaking)
+ {
+ LLFloaterReg::showInstance("chat_voice", LLSD());
+ }
+
+ return TRUE;
+}
+
+void LLOutputMonitorCtrl::setSpeakerId(const LLUUID& speaker_id, const LLUUID& session_id/* = LLUUID::null*/, bool show_other_participants_speaking /* = false */)
{
if (speaker_id.isNull() && mSpeakerId.notNull())
{
LLSpeakingIndicatorManager::unregisterSpeakingIndicator(mSpeakerId, this);
+ switchIndicator(false);
+ mSpeakerId = speaker_id;
}
- if (speaker_id.isNull() || speaker_id == mSpeakerId) return;
+ if (speaker_id.isNull() || (speaker_id == mSpeakerId))
+ {
+ return;
+ }
if (mSpeakerId.notNull())
{
@@ -256,6 +275,7 @@ void LLOutputMonitorCtrl::setSpeakerId(const LLUUID& speaker_id, const LLUUID& s
LLSpeakingIndicatorManager::unregisterSpeakingIndicator(mSpeakerId, this);
}
+ mShowParticipantsSpeaking = show_other_participants_speaking;
mSpeakerId = speaker_id;
LLSpeakingIndicatorManager::registerSpeakingIndicator(mSpeakerId, this, session_id);
@@ -264,12 +284,12 @@ void LLOutputMonitorCtrl::setSpeakerId(const LLUUID& speaker_id, const LLUUID& s
{
if (speaker_id == gAgentID)
{
- setIsMuted(false);
+ mIsMuted = false;
}
else
{
// check only blocking on voice. EXT-3542
- setIsMuted(LLMuteList::getInstance()->isMuted(mSpeakerId, LLMute::flagVoiceChat));
+ mIsMuted = LLMuteList::getInstance()->isMuted(mSpeakerId, LLMute::flagVoiceChat);
LLMuteList::getInstance()->addObserver(this);
}
}
@@ -278,32 +298,34 @@ void LLOutputMonitorCtrl::setSpeakerId(const LLUUID& speaker_id, const LLUUID& s
void LLOutputMonitorCtrl::onChange()
{
// check only blocking on voice. EXT-3542
- setIsMuted(LLMuteList::getInstance()->isMuted(mSpeakerId, LLMute::flagVoiceChat));
+ mIsMuted = LLMuteList::getInstance()->isMuted(mSpeakerId, LLMute::flagVoiceChat);
}
// virtual
void LLOutputMonitorCtrl::switchIndicator(bool switch_on)
{
- // ensure indicator is visible in case it is not in visible chain
- // to be called when parent became visible next time to notify parent that visibility is changed.
- setVisible(TRUE);
-
- // if parent is in visible chain apply switch_on state and notify it immediately
- if (getParent() && getParent()->isInVisibleChain())
- {
- LL_DEBUGS("SpeakingIndicator") << "Indicator is in visible chain, notifying parent: " << mSpeakerId << LL_ENDL;
- setVisible((BOOL)switch_on);
- notifyParentVisibilityChanged();
- }
- // otherwise remember necessary state and mark itself as dirty.
- // State will be applied in next draw when parents chain becomes visible.
- else
- {
- LL_DEBUGS("SpeakingIndicator") << "Indicator is not in visible chain, parent won't be notified: " << mSpeakerId << LL_ENDL;
- mIsSwitchDirty = true;
- mShouldSwitchOn = switch_on;
- }
+ if(getVisible() != (BOOL)switch_on)
+ {
+ setVisible(switch_on);
+
+ //Let parent adjust positioning of icons adjacent to speaker indicator
+ //(when speaker indicator hidden, adjacent icons move to right and when speaker
+ //indicator visible, adjacent icons move to the left)
+ if (getParent() && getParent()->isInVisibleChain())
+ {
+ notifyParentVisibilityChanged();
+ //Ignore toggled state in case it was set when parent visibility was hidden
+ mIndicatorToggled = false;
+ }
+ else
+ {
+ //Makes sure to only adjust adjacent icons when parent becomes visible
+ //(!mIndicatorToggled ensures that changes of TFT and FTF are discarded, real state changes are TF or FT)
+ mIndicatorToggled = !mIndicatorToggled;
+ }
+
+ }
}
//////////////////////////////////////////////////////////////////////////
diff --git a/indra/newview/lloutputmonitorctrl.h b/indra/newview/lloutputmonitorctrl.h
index 2d23753d46..0682af1278 100644..100755
--- a/indra/newview/lloutputmonitorctrl.h
+++ b/indra/newview/lloutputmonitorctrl.h
@@ -28,10 +28,10 @@
#define LL_LLOUTPUTMONITORCTRL_H
#include "v4color.h"
-#include "llview.h"
+#include "../llui/llview.h"
#include "llmutelist.h"
#include "llspeakingindicatormanager.h"
-#include "lluiimage.h"
+//#include "../llui/lluiimage.h"
class LLTextBox;
class LLUICtrlFactory;
@@ -68,19 +68,19 @@ public:
// llview overrides
virtual void draw();
+ virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask);
void setPower(F32 val);
F32 getPower(F32 val) const { return mPower; }
- bool getIsMuted() const { return mIsMuted; }
- void setIsMuted(bool val) { mIsMuted = val; }
-
// For the current user, need to know the PTT state to show
// correct button image.
void setIsAgentControl(bool val) { mIsAgentControl = val; }
void setIsTalking(bool val) { mIsTalking = val; }
+ void setShowParticipantsSpeaking(bool show) { mShowParticipantsSpeaking = show; }
+
/**
* Sets avatar UUID to interact with voice channel.
*
@@ -89,7 +89,7 @@ public:
* If this parameter is set registered indicator will be shown only in voice channel
* which has the same session id (EXT-5562).
*/
- void setSpeakerId(const LLUUID& speaker_id, const LLUUID& session_id = LLUUID::null);
+ void setSpeakerId(const LLUUID& speaker_id, const LLUUID& session_id = LLUUID::null, bool show_other_participants_speaking = false);
//called by mute list
virtual void onChange();
@@ -105,6 +105,8 @@ public:
* It will be applied in next draw and parent will be notified.
*/
virtual void switchIndicator(bool switch_on);
+ bool getIndicatorToggled() { return mIndicatorToggled;}
+ void setIndicatorToggled(bool value) { mIndicatorToggled = value;}
private:
@@ -131,6 +133,7 @@ private:
bool mIsAgentControl;
bool mIsMuted;
bool mIsTalking;
+ bool mShowParticipantsSpeaking;
LLPointer<LLUIImage> mImageMute;
LLPointer<LLUIImage> mImageOff;
LLPointer<LLUIImage> mImageOn;
@@ -144,9 +147,7 @@ private:
/** uuid of a speaker being monitored */
LLUUID mSpeakerId;
- /** indicates if the instance is dirty and should notify parent */
- bool mIsSwitchDirty;
- bool mShouldSwitchOn;
+ bool mIndicatorToggled;
};
#endif
diff --git a/indra/newview/llpanelappearancetab.cpp b/indra/newview/llpanelappearancetab.cpp
index 8fa8867c69..8fa8867c69 100644..100755
--- a/indra/newview/llpanelappearancetab.cpp
+++ b/indra/newview/llpanelappearancetab.cpp
diff --git a/indra/newview/llpanelappearancetab.h b/indra/newview/llpanelappearancetab.h
index 2ed6b00497..2ed6b00497 100644..100755
--- a/indra/newview/llpanelappearancetab.h
+++ b/indra/newview/llpanelappearancetab.h
diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp
index 679b1bdcda..679b1bdcda 100644..100755
--- a/indra/newview/llpanelavatar.cpp
+++ b/indra/newview/llpanelavatar.cpp
diff --git a/indra/newview/llpanelavatar.h b/indra/newview/llpanelavatar.h
index e33a850cfa..e33a850cfa 100644..100755
--- a/indra/newview/llpanelavatar.h
+++ b/indra/newview/llpanelavatar.h
diff --git a/indra/newview/llpanelavatartag.cpp b/indra/newview/llpanelavatartag.cpp
index 4ac818eb26..4ac818eb26 100644..100755
--- a/indra/newview/llpanelavatartag.cpp
+++ b/indra/newview/llpanelavatartag.cpp
diff --git a/indra/newview/llpanelavatartag.h b/indra/newview/llpanelavatartag.h
index 1068ae0b4f..1068ae0b4f 100644..100755
--- a/indra/newview/llpanelavatartag.h
+++ b/indra/newview/llpanelavatartag.h
diff --git a/indra/newview/llpanelblockedlist.cpp b/indra/newview/llpanelblockedlist.cpp
index 5c85ec438c..115114bb53 100644..100755
--- a/indra/newview/llpanelblockedlist.cpp
+++ b/indra/newview/llpanelblockedlist.cpp
@@ -30,15 +30,23 @@
// library include
#include "llavatarname.h"
+#include "llfiltereditor.h"
#include "llfloater.h"
#include "llfloaterreg.h"
#include "llnotificationsutil.h"
#include "llscrolllistctrl.h"
+#include "llmenubutton.h"
// project include
+#include "llavatarlistitem.h"
+#include "llblocklist.h"
+#include "llblockedlistitem.h"
#include "llfloateravatarpicker.h"
#include "llfloatersidepanelcontainer.h"
+#include "llinventorylistitem.h"
+#include "llinventorymodel.h"
#include "llsidetraypanelcontainer.h"
+#include "llviewercontrol.h"
static LLRegisterPanelClassWrapper<LLPanelBlockedList> t_panel_blocked_list("panel_block_list_sidetray");
@@ -54,26 +62,47 @@ const std::string BLOCKED_PARAM_NAME = "blocked_to_select";
LLPanelBlockedList::LLPanelBlockedList()
: LLPanel()
{
- mCommitCallbackRegistrar.add("Block.ClickPick", boost::bind(&LLPanelBlockedList::onPickBtnClick, this));
- mCommitCallbackRegistrar.add("Block.ClickBlockByName", boost::bind(&LLPanelBlockedList::onBlockByNameClick, this));
- mCommitCallbackRegistrar.add("Block.ClickRemove", boost::bind(&LLPanelBlockedList::onRemoveBtnClick, this));
+ mCommitCallbackRegistrar.add("Block.Action", boost::bind(&LLPanelBlockedList::onCustomAction, this, _2));
+ mEnableCallbackRegistrar.add("Block.Check", boost::bind(&LLPanelBlockedList::isActionChecked, this, _2));
}
-LLPanelBlockedList::~LLPanelBlockedList()
+void LLPanelBlockedList::removePicker()
{
- LLMuteList::getInstance()->removeObserver(this);
+ if(mPicker.get())
+ {
+ mPicker.get()->closeFloater();
+ }
}
BOOL LLPanelBlockedList::postBuild()
{
- mBlockedList = getChild<LLScrollListCtrl>("blocked");
+ mBlockedList = getChild<LLBlockList>("blocked");
mBlockedList->setCommitOnSelectionChange(TRUE);
+ this->setVisibleCallback(boost::bind(&LLPanelBlockedList::removePicker, this));
- childSetCommitCallback("back", boost::bind(&LLPanelBlockedList::onBackBtnClick, this), NULL);
+ switch (gSavedSettings.getU32("BlockPeopleSortOrder"))
+ {
+ case E_SORT_BY_NAME:
+ mBlockedList->sortByName();
+ break;
+
+ case E_SORT_BY_TYPE:
+ mBlockedList->sortByType();
+ break;
+ default:
+ llwarns << "Unrecognized sort order for blocked list" << llendl;
+ break;
+ }
+
+ // Use the context menu of the Block list for the Block tab gear menu.
+ LLToggleableMenu* blocked_gear_menu = mBlockedList->getContextMenu();
+ if (blocked_gear_menu)
+ {
+ getChild<LLMenuButton>("blocked_gear_btn")->setMenu(blocked_gear_menu, LLMenuButton::MP_BOTTOM_LEFT);
+ }
- LLMuteList::getInstance()->addObserver(this);
-
- refreshBlockedList();
+ getChild<LLButton>("unblock_btn")->setCommitCallback(boost::bind(&LLPanelBlockedList::unblockItem, this));
+ getChild<LLFilterEditor>("blocked_filter_input")->setCommitCallback(boost::bind(&LLPanelBlockedList::onFilterEdit, this, _2));
return LLPanel::postBuild();
}
@@ -94,97 +123,112 @@ void LLPanelBlockedList::onOpen(const LLSD& key)
void LLPanelBlockedList::selectBlocked(const LLUUID& mute_id)
{
- mBlockedList->selectByID(mute_id);
+ mBlockedList->selectItemByUUID(mute_id);
}
void LLPanelBlockedList::showPanelAndSelect(const LLUUID& idToSelect)
{
- LLFloaterSidePanelContainer::showPanel("people", "panel_block_list_sidetray", LLSD().with(BLOCKED_PARAM_NAME, idToSelect));
+ LLFloaterSidePanelContainer::showPanel("people", "panel_people",
+ LLSD().with("people_panel_tab_name", "blocked_panel").with(BLOCKED_PARAM_NAME, idToSelect));
}
//////////////////////////////////////////////////////////////////////////
// Private Section
//////////////////////////////////////////////////////////////////////////
-void LLPanelBlockedList::refreshBlockedList()
+void LLPanelBlockedList::updateButtons()
{
- mBlockedList->deleteAllItems();
+ bool hasSelected = NULL != mBlockedList->getSelectedItem();
+ getChildView("unblock_btn")->setEnabled(hasSelected);
+ getChildView("blocked_gear_btn")->setEnabled(hasSelected);
+}
- std::vector<LLMute> mutes = LLMuteList::getInstance()->getMutes();
- std::vector<LLMute>::iterator it;
- for (it = mutes.begin(); it != mutes.end(); ++it)
+void LLPanelBlockedList::unblockItem()
+{
+ LLBlockedListItem* item = mBlockedList->getBlockedItem();
+ if (item)
{
- LLScrollListItem::Params item_p;
- item_p.enabled(TRUE);
- item_p.value(it->mID); // link UUID of blocked item with ScrollListItem
- item_p.columns.add().column("item_name").value(it->mName);//.type("text");
- item_p.columns.add().column("item_type").value(it->getDisplayType());//.type("text").width(111);
-
- mBlockedList->addRow(item_p, ADD_BOTTOM);
+ LLMute mute(item->getUUID(), item->getName());
+ LLMuteList::instance().remove(mute);
}
}
-void LLPanelBlockedList::updateButtons()
+void LLPanelBlockedList::onCustomAction(const LLSD& userdata)
{
- bool hasSelected = NULL != mBlockedList->getFirstSelected();
- getChildView("Unblock")->setEnabled(hasSelected);
-}
-
+ const std::string command_name = userdata.asString();
-
-void LLPanelBlockedList::onBackBtnClick()
-{
- LLSideTrayPanelContainer* parent = dynamic_cast<LLSideTrayPanelContainer*>(getParent());
- if(parent)
+ if ("block_obj_by_name" == command_name)
+ {
+ blockObjectByName();
+ }
+ else if ("block_res_by_name" == command_name)
+ {
+ blockResidentByName();
+ }
+ else if ("sort_by_name" == command_name)
+ {
+ mBlockedList->sortByName();
+ gSavedSettings.setU32("BlockPeopleSortOrder", E_SORT_BY_NAME);
+ }
+ else if ("sort_by_type" == command_name)
{
- parent->openPreviousPanel();
+ mBlockedList->sortByType();
+ gSavedSettings.setU32("BlockPeopleSortOrder", E_SORT_BY_TYPE);
}
}
-void LLPanelBlockedList::onRemoveBtnClick()
+BOOL LLPanelBlockedList::isActionChecked(const LLSD& userdata)
{
- std::string name = mBlockedList->getSelectedItemLabel();
- LLUUID id = mBlockedList->getStringUUIDSelectedItem();
- LLMute mute(id, name);
-
- S32 last_selected = mBlockedList->getFirstSelectedIndex();
- if (LLMuteList::getInstance()->remove(mute))
+ std::string item = userdata.asString();
+ U32 sort_order = gSavedSettings.getU32("BlockPeopleSortOrder");
+
+ if ("sort_by_name" == item)
+ {
+ return E_SORT_BY_NAME == sort_order;
+ }
+ else if ("sort_by_type" == item)
{
- // Above removals may rebuild this dialog.
-
- if (last_selected == mBlockedList->getItemCount())
- {
- // we were on the last item, so select the last item again
- mBlockedList->selectNthItem(last_selected - 1);
- }
- else
- {
- // else select the item after the last item previously selected
- mBlockedList->selectNthItem(last_selected);
- }
+ return E_SORT_BY_TYPE == sort_order;
}
+
+ return false;
}
-void LLPanelBlockedList::onPickBtnClick()
+void LLPanelBlockedList::blockResidentByName()
{
const BOOL allow_multiple = FALSE;
const BOOL close_on_select = TRUE;
- /*LLFloaterAvatarPicker* picker = */LLFloaterAvatarPicker::show(boost::bind(&LLPanelBlockedList::callbackBlockPicked, this, _1, _2), allow_multiple, close_on_select);
-
- // *TODO: mantipov: should LLFloaterAvatarPicker be closed when panel is closed?
- // old Floater dependency is not enable in panel
- // addDependentFloater(picker);
+
+ LLView * button = findChild<LLButton>("plus_btn", TRUE);
+ LLFloater* root_floater = gFloaterView->getParentFloater(this);
+ LLFloaterAvatarPicker * picker = LLFloaterAvatarPicker::show(boost::bind(&LLPanelBlockedList::callbackBlockPicked, this, _1, _2),
+ allow_multiple, close_on_select, FALSE, root_floater->getName(), button);
+
+ if (root_floater)
+ {
+ root_floater->addDependentFloater(picker);
+ }
+
+ mPicker = picker->getHandle();
}
-void LLPanelBlockedList::onBlockByNameClick()
+void LLPanelBlockedList::blockObjectByName()
{
LLFloaterGetBlockedObjectName::show(&LLPanelBlockedList::callbackBlockByName);
}
+void LLPanelBlockedList::onFilterEdit(const std::string& search_string)
+{
+ std::string filter = search_string;
+ LLStringUtil::trimHead(filter);
+
+ mBlockedList->setNameFilter(filter);
+}
+
void LLPanelBlockedList::callbackBlockPicked(const uuid_vec_t& ids, const std::vector<LLAvatarName> names)
{
if (names.empty() || ids.empty()) return;
- LLMute mute(ids[0], names[0].getLegacyName(), LLMute::AGENT);
+ LLMute mute(ids[0], names[0].getAccountName(), LLMute::AGENT);
LLMuteList::getInstance()->add(mute);
showPanelAndSelect(mute.mID);
}
diff --git a/indra/newview/llpanelblockedlist.h b/indra/newview/llpanelblockedlist.h
index 74ad82e32d..07f0437656 100644..100755
--- a/indra/newview/llpanelblockedlist.h
+++ b/indra/newview/llpanelblockedlist.h
@@ -30,21 +30,15 @@
#include "llpanel.h"
#include "llmutelist.h"
#include "llfloater.h"
-// #include <vector>
-// class LLButton;
-// class LLLineEditor;
-// class LLMessageSystem;
-// class LLUUID;
class LLAvatarName;
-class LLScrollListCtrl;
+class LLBlockList;
-class LLPanelBlockedList
- : public LLPanel, public LLMuteListObserver
+class LLPanelBlockedList : public LLPanel
{
public:
LLPanelBlockedList();
- ~LLPanelBlockedList();
+ ~LLPanelBlockedList(){};
virtual BOOL postBuild();
virtual void draw();
@@ -59,25 +53,33 @@ public:
* If it is LLUUID::null, nothing will be selected.
*/
static void showPanelAndSelect(const LLUUID& idToSelect);
-
- // LLMuteListObserver callback interface implementation.
- /* virtual */ void onChange() { refreshBlockedList();}
private:
- void refreshBlockedList();
+
+ typedef enum e_sort_oder{
+ E_SORT_BY_NAME = 0,
+ E_SORT_BY_TYPE = 1,
+ } ESortOrder;
+
+ void removePicker();
void updateButtons();
// UI callbacks
- void onBackBtnClick();
- void onRemoveBtnClick();
- void onPickBtnClick();
- void onBlockByNameClick();
+ void unblockItem();
+ void blockResidentByName();
+ void blockObjectByName();
+ void onFilterEdit(const std::string& search_string);
+
+ // List commnads
+ void onCustomAction(const LLSD& userdata);
+ BOOL isActionChecked(const LLSD& userdata);
void callbackBlockPicked(const uuid_vec_t& ids, const std::vector<LLAvatarName> names);
static void callbackBlockByName(const std::string& text);
private:
- LLScrollListCtrl* mBlockedList;
+ LLBlockList* mBlockedList;
+ LLHandle<LLFloater> mPicker;
};
//-----------------------------------------------------------------------------
diff --git a/indra/newview/llpanelclassified.cpp b/indra/newview/llpanelclassified.cpp
index 6889b98ab1..862e4be203 100644..100755
--- a/indra/newview/llpanelclassified.cpp
+++ b/indra/newview/llpanelclassified.cpp
@@ -55,6 +55,7 @@
#include "lltrans.h"
#include "llscrollcontainer.h"
#include "llstatusbar.h"
+#include "llviewertexture.h"
const S32 MINIMUM_PRICE_FOR_LISTING = 50; // L$
diff --git a/indra/newview/llpanelclassified.h b/indra/newview/llpanelclassified.h
index cedd65c405..cedd65c405 100644..100755
--- a/indra/newview/llpanelclassified.h
+++ b/indra/newview/llpanelclassified.h
diff --git a/indra/newview/llpanelcontents.cpp b/indra/newview/llpanelcontents.cpp
index 7ade2c7972..697841ab88 100644..100755
--- a/indra/newview/llpanelcontents.cpp
+++ b/indra/newview/llpanelcontents.cpp
@@ -79,8 +79,6 @@ const char* LLPanelContents::PERMS_ANYONE_CONTROL_KEY = "perms_anyone_control";
BOOL LLPanelContents::postBuild()
{
- LLRect rect = this->getRect();
-
setMouseOpaque(FALSE);
childSetAction("button new script",&LLPanelContents::onClickNewScript, this);
@@ -117,7 +115,7 @@ void LLPanelContents::getState(LLViewerObject *objectp )
// BUG? Check for all objects being editable?
bool editable = gAgent.isGodlike()
- || (objectp->permModify()
+ || (objectp->permModify() && !objectp->isPermanentEnforced()
&& ( objectp->permYouOwner() || ( !group_id.isNull() && gAgent.isInGroup(group_id) ))); // solves SL-23488
BOOL all_volume = LLSelectMgr::getInstance()->selectionAllPCode( LL_PCODE_VOLUME );
@@ -128,6 +126,8 @@ void LLPanelContents::getState(LLViewerObject *objectp )
((LLSelectMgr::getInstance()->getSelection()->getRootObjectCount() == 1)
|| (LLSelectMgr::getInstance()->getSelection()->getObjectCount() == 1)));
+ getChildView("button permissions")->setEnabled(!objectp->isPermanentEnforced());
+ mPanelInventoryObject->setEnabled(!objectp->isPermanentEnforced());
}
void LLPanelContents::refresh()
diff --git a/indra/newview/llpanelcontents.h b/indra/newview/llpanelcontents.h
index 62ccb64a4c..62ccb64a4c 100644..100755
--- a/indra/newview/llpanelcontents.h
+++ b/indra/newview/llpanelcontents.h
diff --git a/indra/newview/llpaneleditwearable.cpp b/indra/newview/llpaneleditwearable.cpp
index 03404e816b..e71dba5cae 100644..100755
--- a/indra/newview/llpaneleditwearable.cpp
+++ b/indra/newview/llpaneleditwearable.cpp
@@ -28,7 +28,7 @@
#include "llpaneleditwearable.h"
#include "llpanel.h"
-#include "llwearable.h"
+#include "llviewerwearable.h"
#include "lluictrl.h"
#include "llscrollingpanellist.h"
#include "llvisualparam.h"
@@ -52,6 +52,7 @@
#include "lltexturectrl.h"
#include "lltextureentry.h"
#include "llviewercontrol.h" // gSavedSettings
+#include "llviewerregion.h"
#include "llviewertexturelist.h"
#include "llagentcamera.h"
#include "llmorphview.h"
@@ -104,7 +105,7 @@ enum ESubpart {
SUBPART_PHYSICS_ADVANCED,
};
-using namespace LLVOAvatarDefines;
+using namespace LLAvatarAppearanceDefines;
typedef std::vector<ESubpart> subpart_vec_t;
@@ -574,6 +575,7 @@ static void init_texture_ctrl(LLPanelEditWearable* self, LLPanel* panel, const L
texture_ctrl->setAllowNoTexture(entry->mAllowNoTexture);
// Don't allow (no copy) or (notransfer) textures to be selected.
texture_ctrl->setImmediateFilterPermMask(PERM_NONE);
+ texture_ctrl->setDnDFilterPermMask(PERM_NONE);
texture_ctrl->setNonImmediateFilterPermMask(PERM_NONE);
}
}
@@ -717,8 +719,8 @@ BOOL LLPanelEditWearable::postBuild()
mBtnBack = getChild<LLButton>("back_btn");
mBackBtnLabel = mBtnBack->getLabelUnselected();
mBtnBack->setLabel(LLStringUtil::null);
- // handled at appearance panel level?
- //mBtnBack->setClickedCallback(boost::bind(&LLPanelEditWearable::onBackButtonClicked, this));
+
+ mBtnBack->setClickedCallback(boost::bind(&LLPanelEditWearable::onBackButtonClicked, this));
mNameEditor = getChild<LLLineEditor>("description");
@@ -761,11 +763,11 @@ BOOL LLPanelEditWearable::postBuild()
mWearablePtr = NULL;
- configureAlphaCheckbox(LLVOAvatarDefines::TEX_LOWER_ALPHA, "lower alpha texture invisible");
- configureAlphaCheckbox(LLVOAvatarDefines::TEX_UPPER_ALPHA, "upper alpha texture invisible");
- configureAlphaCheckbox(LLVOAvatarDefines::TEX_HEAD_ALPHA, "head alpha texture invisible");
- configureAlphaCheckbox(LLVOAvatarDefines::TEX_EYES_ALPHA, "eye alpha texture invisible");
- configureAlphaCheckbox(LLVOAvatarDefines::TEX_HAIR_ALPHA, "hair alpha texture invisible");
+ configureAlphaCheckbox(LLAvatarAppearanceDefines::TEX_LOWER_ALPHA, "lower alpha texture invisible");
+ configureAlphaCheckbox(LLAvatarAppearanceDefines::TEX_UPPER_ALPHA, "upper alpha texture invisible");
+ configureAlphaCheckbox(LLAvatarAppearanceDefines::TEX_HEAD_ALPHA, "head alpha texture invisible");
+ configureAlphaCheckbox(LLAvatarAppearanceDefines::TEX_EYES_ALPHA, "eye alpha texture invisible");
+ configureAlphaCheckbox(LLAvatarAppearanceDefines::TEX_HAIR_ALPHA, "hair alpha texture invisible");
// configure tab expanded callbacks
for (U32 type_index = 0; type_index < (U32)LLWearableType::WT_COUNT; ++type_index)
@@ -834,11 +836,11 @@ BOOL LLPanelEditWearable::isDirty() const
BOOL isDirty = FALSE;
if (mWearablePtr)
{
- if (mWearablePtr->isDirty() ||
- mWearableItem->getName().compare(mNameEditor->getText()) != 0)
- {
- isDirty = TRUE;
- }
+ if (mWearablePtr->isDirty() ||
+ ( mWearableItem && mNameEditor && mWearableItem->getName().compare(mNameEditor->getText()) != 0 ))
+ {
+ isDirty = TRUE;
+ }
}
return isDirty;
}
@@ -855,6 +857,14 @@ void LLPanelEditWearable::draw()
LLPanel::draw();
}
+void LLPanelEditWearable::onClose()
+{
+ if ( isDirty() )
+ {
+ revertChanges();
+ }
+}
+
void LLPanelEditWearable::setVisible(BOOL visible)
{
if (!visible)
@@ -864,13 +874,22 @@ void LLPanelEditWearable::setVisible(BOOL visible)
LLPanel::setVisible(visible);
}
-void LLPanelEditWearable::setWearable(LLWearable *wearable, BOOL disable_camera_switch)
+void LLPanelEditWearable::setWearable(LLViewerWearable *wearable, BOOL disable_camera_switch)
{
showWearable(mWearablePtr, FALSE, disable_camera_switch);
mWearablePtr = wearable;
showWearable(mWearablePtr, TRUE, disable_camera_switch);
}
+//static
+void LLPanelEditWearable::onBackButtonClicked(void* userdata)
+{
+ LLPanelEditWearable *panel = (LLPanelEditWearable*) userdata;
+ if ( panel->isDirty() )
+ {
+ LLAppearanceMgr::instance().setOutfitDirty( true );
+ }
+}
//static
void LLPanelEditWearable::onRevertButtonClicked(void* userdata)
@@ -921,7 +940,7 @@ void LLPanelEditWearable::onCommitSexChange()
}
bool is_new_sex_male = (gSavedSettings.getU32("AvatarSex") ? SEX_MALE : SEX_FEMALE) == SEX_MALE;
- LLWearable* wearable = gAgentWearables.getWearable(type, index);
+ LLViewerWearable* wearable = gAgentWearables.getViewerWearable(type, index);
if (wearable)
{
wearable->setVisualParamWeight(param->getID(), is_new_sex_male, FALSE);
@@ -1006,13 +1025,11 @@ void LLPanelEditWearable::updatePanelPickerControls(LLWearableType::EType type)
return;
bool is_modifiable = false;
- bool is_copyable = false;
if(mWearableItem)
{
const LLPermissions& perm = mWearableItem->getPermissions();
is_modifiable = perm.allowModifyBy(gAgent.getID(), gAgent.getGroupID());
- is_copyable = perm.allowCopyBy(gAgent.getID(), gAgent.getGroupID());
}
if (is_modifiable)
@@ -1029,6 +1046,11 @@ void LLPanelEditWearable::updatePanelPickerControls(LLWearableType::EType type)
}
}
+void LLPanelEditWearable::incrementCofVersionLegacy()
+{
+
+}
+
void LLPanelEditWearable::saveChanges(bool force_save_as)
{
if (!mWearablePtr || !isDirty())
@@ -1040,17 +1062,50 @@ void LLPanelEditWearable::saveChanges(bool force_save_as)
U32 index = gAgentWearables.getWearableIndex(mWearablePtr);
std::string new_name = mNameEditor->getText();
+
+ // Find an existing link to this wearable's inventory item, if any, and its description field.
+ LLInventoryItem *link_item = NULL;
+ std::string description;
+ LLInventoryModel::item_array_t links =
+ LLAppearanceMgr::instance().findCOFItemLinks(mWearablePtr->getItemID());
+ if (links.size()>0)
+ {
+ link_item = links.get(0).get();
+ if (link_item && link_item->getIsLinkType())
+ {
+ description = link_item->getActualDescription();
+ }
+ }
+
if (force_save_as)
{
// the name of the wearable has changed, re-save wearable with new name
- LLAppearanceMgr::instance().removeCOFItemLinks(mWearablePtr->getItemID(),false);
- gAgentWearables.saveWearableAs(mWearablePtr->getType(), index, new_name, FALSE);
+ LLAppearanceMgr::instance().removeCOFItemLinks(mWearablePtr->getItemID());
+ gAgentWearables.saveWearableAs(mWearablePtr->getType(), index, new_name, description, FALSE);
mNameEditor->setText(mWearableItem->getName());
}
else
{
+ // Make another copy of this link, with the same
+ // description. This is needed to bump the COF
+ // version so texture baking service knows appearance has changed.
+ if (link_item)
+ {
+ // Create new link
+ link_inventory_item( gAgent.getID(),
+ link_item->getLinkedUUID(),
+ LLAppearanceMgr::instance().getCOF(),
+ link_item->getName(),
+ description,
+ LLAssetType::AT_LINK,
+ NULL);
+ // Remove old link
+ gInventory.purgeObject(link_item->getUUID());
+ }
gAgentWearables.saveWearable(mWearablePtr->getType(), index, TRUE, new_name);
}
+
+
}
void LLPanelEditWearable::revertChanges()
@@ -1068,7 +1123,7 @@ void LLPanelEditWearable::revertChanges()
gAgentAvatarp->wearableUpdated(mWearablePtr->getType(), FALSE);
}
-void LLPanelEditWearable::showWearable(LLWearable* wearable, BOOL show, BOOL disable_camera_switch)
+void LLPanelEditWearable::showWearable(LLViewerWearable* wearable, BOOL show, BOOL disable_camera_switch)
{
if (!wearable)
{
@@ -1185,7 +1240,7 @@ void LLPanelEditWearable::showWearable(LLWearable* wearable, BOOL show, BOOL dis
void LLPanelEditWearable::showDefaultSubpart()
{
- changeCamera(3);
+ changeCamera(0);
}
void LLPanelEditWearable::onTabExpandedCollapsed(const LLSD& param, U8 index)
@@ -1439,12 +1494,11 @@ void LLPanelEditWearable::buildParamList(LLScrollingPanelList *panel_list, value
{
panel_list->clearPanels();
value_map_t::iterator end = sorted_params.end();
- S32 height = 0;
for(value_map_t::iterator it = sorted_params.begin(); it != end; ++it)
{
LLPanel::Params p;
p.name("LLScrollingPanelParam");
- LLWearable *wearable = this->getWearable();
+ LLViewerWearable *wearable = this->getWearable();
LLScrollingPanelParamBase *panel_param = NULL;
if (wearable && wearable->getType() == LLWearableType::WT_PHYSICS) // Hack to show a different panel for physics. Should generalize this later.
{
@@ -1454,7 +1508,7 @@ void LLPanelEditWearable::buildParamList(LLScrollingPanelList *panel_list, value
{
panel_param = new LLScrollingPanelParam( p, NULL, (*it).second, TRUE, this->getWearable(), jointp);
}
- height = panel_list->addPanel( panel_param );
+ panel_list->addPanel( panel_param );
}
}
}
@@ -1504,7 +1558,7 @@ void LLPanelEditWearable::updateVerbs()
}
}
-void LLPanelEditWearable::configureAlphaCheckbox(LLVOAvatarDefines::ETextureIndex te, const std::string& name)
+void LLPanelEditWearable::configureAlphaCheckbox(LLAvatarAppearanceDefines::ETextureIndex te, const std::string& name)
{
LLCheckBoxCtrl* checkbox = mPanelAlpha->getChild<LLCheckBoxCtrl>(name);
checkbox->setCommitCallback(boost::bind(&LLPanelEditWearable::onInvisibilityCommit, this, checkbox, te));
@@ -1512,7 +1566,7 @@ void LLPanelEditWearable::configureAlphaCheckbox(LLVOAvatarDefines::ETextureInde
mAlphaCheckbox2Index[name] = te;
}
-void LLPanelEditWearable::onInvisibilityCommit(LLCheckBoxCtrl* checkbox_ctrl, LLVOAvatarDefines::ETextureIndex te)
+void LLPanelEditWearable::onInvisibilityCommit(LLCheckBoxCtrl* checkbox_ctrl, LLAvatarAppearanceDefines::ETextureIndex te)
{
if (!checkbox_ctrl) return;
if (!getWearable()) return;
@@ -1556,7 +1610,7 @@ void LLPanelEditWearable::updateAlphaCheckboxes()
for(string_texture_index_map_t::iterator iter = mAlphaCheckbox2Index.begin();
iter != mAlphaCheckbox2Index.end(); ++iter )
{
- LLVOAvatarDefines::ETextureIndex te = (LLVOAvatarDefines::ETextureIndex)iter->second;
+ LLAvatarAppearanceDefines::ETextureIndex te = (LLAvatarAppearanceDefines::ETextureIndex)iter->second;
LLCheckBoxCtrl* ctrl = mPanelAlpha->getChild<LLCheckBoxCtrl>(iter->first);
if (ctrl)
{
@@ -1574,7 +1628,7 @@ void LLPanelEditWearable::initPreviousAlphaTextures()
initPreviousAlphaTextureEntry(TEX_LOWER_ALPHA);
}
-void LLPanelEditWearable::initPreviousAlphaTextureEntry(LLVOAvatarDefines::ETextureIndex te)
+void LLPanelEditWearable::initPreviousAlphaTextureEntry(LLAvatarAppearanceDefines::ETextureIndex te)
{
LLLocalTextureObject *lto = getWearable()->getLocalTextureObject(te);
if (lto)
diff --git a/indra/newview/llpaneleditwearable.h b/indra/newview/llpaneleditwearable.h
index 692a7ce90f..81acc31863 100644..100755
--- a/indra/newview/llpaneleditwearable.h
+++ b/indra/newview/llpaneleditwearable.h
@@ -30,12 +30,12 @@
#include "llpanel.h"
#include "llscrollingpanellist.h"
#include "llmodaldialog.h"
-#include "llvoavatardefines.h"
+#include "llavatarappearancedefines.h"
#include "llwearabletype.h"
class LLAccordionCtrl;
class LLCheckBoxCtrl;
-class LLWearable;
+class LLViewerWearable;
class LLTextBox;
class LLViewerInventoryItem;
class LLViewerVisualParam;
@@ -54,12 +54,13 @@ public:
/*virtual*/ BOOL postBuild();
/*virtual*/ BOOL isDirty() const; // LLUICtrl
/*virtual*/ void draw();
+ void onClose();
// changes camera angle to default for selected subpart
void changeCamera(U8 subpart);
- LLWearable* getWearable() { return mWearablePtr; }
- void setWearable(LLWearable *wearable, BOOL disable_camera_switch = FALSE);
+ LLViewerWearable* getWearable() { return mWearablePtr; }
+ void setWearable(LLViewerWearable *wearable, BOOL disable_camera_switch = FALSE);
void saveChanges(bool force_save_as = false);
void revertChanges();
@@ -70,17 +71,17 @@ public:
void updateScrollingPanelList();
static void onRevertButtonClicked(void* userdata);
+ static void onBackButtonClicked(void* userdata);
void onCommitSexChange();
void onSaveAsButtonClicked();
void saveAsCallback(const LLSD& notification, const LLSD& response);
virtual void setVisible(BOOL visible);
-
private:
typedef std::map<F32, LLViewerVisualParam*> value_map_t;
- void showWearable(LLWearable* wearable, BOOL show, BOOL disable_camera_switch = FALSE);
+ void showWearable(LLViewerWearable* wearable, BOOL show, BOOL disable_camera_switch = FALSE);
void updateScrollingPanelUI();
LLPanel* getPanel(LLWearableType::EType type);
void getSortedParams(value_map_t &sorted_params, const std::string &edit_group);
@@ -95,16 +96,16 @@ private:
void updateTypeSpecificControls(LLWearableType::EType type);
//alpha mask checkboxes
- void configureAlphaCheckbox(LLVOAvatarDefines::ETextureIndex te, const std::string& name);
- void onInvisibilityCommit(LLCheckBoxCtrl* checkbox_ctrl, LLVOAvatarDefines::ETextureIndex te);
+ void configureAlphaCheckbox(LLAvatarAppearanceDefines::ETextureIndex te, const std::string& name);
+ void onInvisibilityCommit(LLCheckBoxCtrl* checkbox_ctrl, LLAvatarAppearanceDefines::ETextureIndex te);
void updateAlphaCheckboxes();
void initPreviousAlphaTextures();
- void initPreviousAlphaTextureEntry(LLVOAvatarDefines::ETextureIndex te);
+ void initPreviousAlphaTextureEntry(LLAvatarAppearanceDefines::ETextureIndex te);
// callback for HeightUnits parameter.
bool changeHeightUnits(const LLSD& new_value);
- // updates current metric and replacemet metric label text
+ // updates current metric and replacement metric label text
void updateMetricLayout(BOOL new_value);
// updates avatar height label
@@ -114,8 +115,11 @@ private:
void setWearablePanelVisibilityChangeCallback(LLPanel* bodypart_panel);
+ // *HACK Remove this when serverside texture baking is available on all regions.
+ void incrementCofVersionLegacy();
+
// the pointer to the wearable we're editing. NULL means we're not editing a wearable.
- LLWearable *mWearablePtr;
+ LLViewerWearable *mWearablePtr;
LLViewerInventoryItem* mWearableItem;
// these are constant no matter what wearable we're editing
@@ -128,7 +132,7 @@ private:
LLTextBox *mTxtAvatarHeight;
- // localized and parametrized strings that used to build avatar_height_label
+ // localized and parameterized strings that used to build avatar_height_label
std::string mMeters;
std::string mFeet;
std::string mHeigth;
@@ -165,10 +169,10 @@ private:
LLPanel *mPanelTattoo;
LLPanel *mPanelPhysics;
- typedef std::map<std::string, LLVOAvatarDefines::ETextureIndex> string_texture_index_map_t;
+ typedef std::map<std::string, LLAvatarAppearanceDefines::ETextureIndex> string_texture_index_map_t;
string_texture_index_map_t mAlphaCheckbox2Index;
- typedef std::map<LLVOAvatarDefines::ETextureIndex, LLUUID> s32_uuid_map_t;
+ typedef std::map<LLAvatarAppearanceDefines::ETextureIndex, LLUUID> s32_uuid_map_t;
s32_uuid_map_t mPreviousAlphaTexture;
};
diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp
index 7301b305b2..3869219da6 100644..100755
--- a/indra/newview/llpanelface.cpp
+++ b/indra/newview/llpanelface.cpp
@@ -38,6 +38,7 @@
#include "llfontgl.h"
// project includes
+#include "llagentdata.h"
#include "llbutton.h"
#include "llcheckboxctrl.h"
#include "llcolorswatch.h"
@@ -45,7 +46,9 @@
#include "lldrawpoolbump.h"
#include "llface.h"
#include "lllineeditor.h"
+#include "llmaterialmgr.h"
#include "llmediaentry.h"
+#include "llnotificationsutil.h"
#include "llresmgr.h"
#include "llselectmgr.h"
#include "llspinctrl.h"
@@ -53,15 +56,72 @@
#include "lltexturectrl.h"
#include "lltextureentry.h"
#include "lltooldraganddrop.h"
+#include "lltrans.h"
#include "llui.h"
#include "llviewercontrol.h"
#include "llviewermedia.h"
#include "llviewerobject.h"
+#include "llviewerregion.h"
#include "llviewerstats.h"
#include "llvovolume.h"
#include "lluictrlfactory.h"
#include "llpluginclassmedia.h"
-#include "llviewertexturelist.h"
+#include "llviewertexturelist.h"// Update sel manager as to which channel we're editing so it can reflect the correct overlay UI
+
+//
+// Constant definitions for comboboxes
+// Must match the commbobox definitions in panel_tools_texture.xml
+//
+const S32 MATMEDIA_MATERIAL = 0; // Material
+const S32 MATMEDIA_MEDIA = 1; // Media
+const S32 MATTYPE_DIFFUSE = 0; // Diffuse material texture
+const S32 MATTYPE_NORMAL = 1; // Normal map
+const S32 MATTYPE_SPECULAR = 2; // Specular map
+const S32 ALPHAMODE_NONE = 0; // No alpha mask applied
+const S32 ALPHAMODE_BLEND = 1; // Alpha blending mode
+const S32 ALPHAMODE_MASK = 2; // Alpha masking mode
+const S32 BUMPY_TEXTURE = 18; // use supplied normal map
+const S32 SHINY_TEXTURE = 4; // use supplied specular map
+
+//
+// "Use texture" label for normal/specular type comboboxes
+// Filled in at initialization from translated strings
+//
+std::string USE_TEXTURE;
+
+LLRender::eTexIndex LLPanelFace::getTextureChannelToEdit()
+{
+ LLComboBox* combobox_matmedia = getChild<LLComboBox>("combobox matmedia");
+ LLComboBox* combobox_mattype = getChild<LLComboBox>("combobox mattype");
+
+ LLRender::eTexIndex channel_to_edit = (combobox_matmedia && combobox_matmedia->getCurrentIndex() == MATMEDIA_MATERIAL) ?
+ (combobox_mattype ? (LLRender::eTexIndex)combobox_mattype->getCurrentIndex() : LLRender::DIFFUSE_MAP) : LLRender::DIFFUSE_MAP;
+
+ channel_to_edit = (channel_to_edit == LLRender::NORMAL_MAP) ? (getCurrentNormalMap().isNull() ? LLRender::DIFFUSE_MAP : channel_to_edit) : channel_to_edit;
+ channel_to_edit = (channel_to_edit == LLRender::SPECULAR_MAP) ? (getCurrentSpecularMap().isNull() ? LLRender::DIFFUSE_MAP : channel_to_edit) : channel_to_edit;
+ return channel_to_edit;
+}
+
+// Things the UI provides...
+//
+LLUUID LLPanelFace::getCurrentNormalMap() { return getChild<LLTextureCtrl>("bumpytexture control")->getImageAssetID(); }
+LLUUID LLPanelFace::getCurrentSpecularMap() { return getChild<LLTextureCtrl>("shinytexture control")->getImageAssetID(); }
+U32 LLPanelFace::getCurrentShininess() { return getChild<LLComboBox>("combobox shininess")->getCurrentIndex(); }
+U32 LLPanelFace::getCurrentBumpiness() { return getChild<LLComboBox>("combobox bumpiness")->getCurrentIndex(); }
+U8 LLPanelFace::getCurrentDiffuseAlphaMode() { return (U8)getChild<LLComboBox>("combobox alphamode")->getCurrentIndex(); }
+U8 LLPanelFace::getCurrentAlphaMaskCutoff() { return (U8)getChild<LLUICtrl>("maskcutoff")->getValue().asInteger(); }
+U8 LLPanelFace::getCurrentEnvIntensity() { return (U8)getChild<LLUICtrl>("environment")->getValue().asInteger(); }
+U8 LLPanelFace::getCurrentGlossiness() { return (U8)getChild<LLUICtrl>("glossiness")->getValue().asInteger(); }
+F32 LLPanelFace::getCurrentBumpyRot() { return getChild<LLUICtrl>("bumpyRot")->getValue().asReal(); }
+F32 LLPanelFace::getCurrentBumpyScaleU() { return getChild<LLUICtrl>("bumpyScaleU")->getValue().asReal(); }
+F32 LLPanelFace::getCurrentBumpyScaleV() { return getChild<LLUICtrl>("bumpyScaleV")->getValue().asReal(); }
+F32 LLPanelFace::getCurrentBumpyOffsetU() { return getChild<LLUICtrl>("bumpyOffsetU")->getValue().asReal(); }
+F32 LLPanelFace::getCurrentBumpyOffsetV() { return getChild<LLUICtrl>("bumpyOffsetV")->getValue().asReal(); }
+F32 LLPanelFace::getCurrentShinyRot() { return getChild<LLUICtrl>("shinyRot")->getValue().asReal(); }
+F32 LLPanelFace::getCurrentShinyScaleU() { return getChild<LLUICtrl>("shinyScaleU")->getValue().asReal(); }
+F32 LLPanelFace::getCurrentShinyScaleV() { return getChild<LLUICtrl>("shinyScaleV")->getValue().asReal(); }
+F32 LLPanelFace::getCurrentShinyOffsetU() { return getChild<LLUICtrl>("shinyOffsetU")->getValue().asReal(); }
+F32 LLPanelFace::getCurrentShinyOffsetV() { return getChild<LLUICtrl>("shinyOffsetV")->getValue().asReal(); }
//
// Methods
@@ -71,22 +131,40 @@ BOOL LLPanelFace::postBuild()
{
childSetCommitCallback("combobox shininess",&LLPanelFace::onCommitShiny,this);
childSetCommitCallback("combobox bumpiness",&LLPanelFace::onCommitBump,this);
+ childSetCommitCallback("combobox alphamode",&LLPanelFace::onCommitAlphaMode,this);
childSetCommitCallback("TexScaleU",&LLPanelFace::onCommitTextureInfo, this);
- childSetCommitCallback("checkbox flip s",&LLPanelFace::onCommitTextureInfo, this);
childSetCommitCallback("TexScaleV",&LLPanelFace::onCommitTextureInfo, this);
- childSetCommitCallback("checkbox flip t",&LLPanelFace::onCommitTextureInfo, this);
childSetCommitCallback("TexRot",&LLPanelFace::onCommitTextureInfo, this);
- childSetAction("button apply",&LLPanelFace::onClickApply,this);
+ childSetCommitCallback("rptctrl",&LLPanelFace::onCommitRepeatsPerMeter, this);
childSetCommitCallback("checkbox planar align",&LLPanelFace::onCommitPlanarAlign, this);
childSetCommitCallback("TexOffsetU",LLPanelFace::onCommitTextureInfo, this);
childSetCommitCallback("TexOffsetV",LLPanelFace::onCommitTextureInfo, this);
+
+ childSetCommitCallback("bumpyScaleU",&LLPanelFace::onCommitMaterialBumpyScaleX, this);
+ childSetCommitCallback("bumpyScaleV",&LLPanelFace::onCommitMaterialBumpyScaleY, this);
+ childSetCommitCallback("bumpyRot",&LLPanelFace::onCommitMaterialBumpyRot, this);
+ childSetCommitCallback("bumpyOffsetU",&LLPanelFace::onCommitMaterialBumpyOffsetX, this);
+ childSetCommitCallback("bumpyOffsetV",&LLPanelFace::onCommitMaterialBumpyOffsetY, this);
+ childSetCommitCallback("shinyScaleU",&LLPanelFace::onCommitMaterialShinyScaleX, this);
+ childSetCommitCallback("shinyScaleV",&LLPanelFace::onCommitMaterialShinyScaleY, this);
+ childSetCommitCallback("shinyRot",&LLPanelFace::onCommitMaterialShinyRot, this);
+ childSetCommitCallback("shinyOffsetU",&LLPanelFace::onCommitMaterialShinyOffsetX, this);
+ childSetCommitCallback("shinyOffsetV",&LLPanelFace::onCommitMaterialShinyOffsetY, this);
+ childSetCommitCallback("glossiness",&LLPanelFace::onCommitMaterialGloss, this);
+ childSetCommitCallback("environment",&LLPanelFace::onCommitMaterialEnv, this);
+ childSetCommitCallback("maskcutoff",&LLPanelFace::onCommitMaterialMaskCutoff, this);
+
childSetAction("button align",&LLPanelFace::onClickAutoFix,this);
- LLRect rect = this->getRect();
LLTextureCtrl* mTextureCtrl;
+ LLTextureCtrl* mShinyTextureCtrl;
+ LLTextureCtrl* mBumpyTextureCtrl;
LLColorSwatchCtrl* mColorSwatch;
+ LLColorSwatchCtrl* mShinyColorSwatch;
LLComboBox* mComboTexGen;
+ LLComboBox* mComboMatMedia;
+ LLComboBox* mComboMatType;
LLCheckBoxCtrl *mCheckFullbright;
@@ -96,6 +174,7 @@ BOOL LLPanelFace::postBuild()
LLSpinCtrl* mCtrlGlow;
setMouseOpaque(FALSE);
+
mTextureCtrl = getChild<LLTextureCtrl>("texture control");
if(mTextureCtrl)
{
@@ -104,27 +183,48 @@ BOOL LLPanelFace::postBuild()
mTextureCtrl->setOnCancelCallback( boost::bind(&LLPanelFace::onCancelTexture, this, _2) );
mTextureCtrl->setOnSelectCallback( boost::bind(&LLPanelFace::onSelectTexture, this, _2) );
mTextureCtrl->setDragCallback(boost::bind(&LLPanelFace::onDragTexture, this, _2));
+ mTextureCtrl->setOnTextureSelectedCallback(boost::bind(&LLPanelFace::onTextureSelectionChanged, this, _1));
+ mTextureCtrl->setOnCloseCallback( boost::bind(&LLPanelFace::onCloseTexturePicker, this, _2) );
+
mTextureCtrl->setFollowsTop();
mTextureCtrl->setFollowsLeft();
- // Don't allow (no copy) or (no transfer) textures to be selected during immediate mode
- mTextureCtrl->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER);
- // Allow any texture to be used during non-immediate mode.
- mTextureCtrl->setNonImmediateFilterPermMask(PERM_NONE);
- LLAggregatePermissions texture_perms;
- if (LLSelectMgr::getInstance()->selectGetAggregateTexturePermissions(texture_perms))
- {
- BOOL can_copy =
- texture_perms.getValue(PERM_COPY) == LLAggregatePermissions::AP_EMPTY ||
- texture_perms.getValue(PERM_COPY) == LLAggregatePermissions::AP_ALL;
- BOOL can_transfer =
- texture_perms.getValue(PERM_TRANSFER) == LLAggregatePermissions::AP_EMPTY ||
- texture_perms.getValue(PERM_TRANSFER) == LLAggregatePermissions::AP_ALL;
- mTextureCtrl->setCanApplyImmediately(can_copy && can_transfer);
- }
- else
- {
- mTextureCtrl->setCanApplyImmediately(FALSE);
- }
+ mTextureCtrl->setImmediateFilterPermMask(PERM_NONE);
+ mTextureCtrl->setDnDFilterPermMask(PERM_COPY | PERM_TRANSFER);
+ }
+
+ mShinyTextureCtrl = getChild<LLTextureCtrl>("shinytexture control");
+ if(mShinyTextureCtrl)
+ {
+ mShinyTextureCtrl->setDefaultImageAssetID(LLUUID( gSavedSettings.getString( "DefaultObjectSpecularTexture" )));
+ mShinyTextureCtrl->setCommitCallback( boost::bind(&LLPanelFace::onCommitSpecularTexture, this, _2) );
+ mShinyTextureCtrl->setOnCancelCallback( boost::bind(&LLPanelFace::onCancelSpecularTexture, this, _2) );
+ mShinyTextureCtrl->setOnSelectCallback( boost::bind(&LLPanelFace::onSelectSpecularTexture, this, _2) );
+ mShinyTextureCtrl->setOnCloseCallback( boost::bind(&LLPanelFace::onCloseTexturePicker, this, _2) );
+
+ mShinyTextureCtrl->setDragCallback(boost::bind(&LLPanelFace::onDragTexture, this, _2));
+ mShinyTextureCtrl->setOnTextureSelectedCallback(boost::bind(&LLPanelFace::onTextureSelectionChanged, this, _1));
+ mShinyTextureCtrl->setFollowsTop();
+ mShinyTextureCtrl->setFollowsLeft();
+ mShinyTextureCtrl->setImmediateFilterPermMask(PERM_NONE);
+ mShinyTextureCtrl->setDnDFilterPermMask(PERM_COPY | PERM_TRANSFER);
+ }
+
+ mBumpyTextureCtrl = getChild<LLTextureCtrl>("bumpytexture control");
+ if(mBumpyTextureCtrl)
+ {
+ mBumpyTextureCtrl->setDefaultImageAssetID(LLUUID( gSavedSettings.getString( "DefaultObjectNormalTexture" )));
+ mBumpyTextureCtrl->setBlankImageAssetID(LLUUID( gSavedSettings.getString( "DefaultBlankNormalTexture" )));
+ mBumpyTextureCtrl->setCommitCallback( boost::bind(&LLPanelFace::onCommitNormalTexture, this, _2) );
+ mBumpyTextureCtrl->setOnCancelCallback( boost::bind(&LLPanelFace::onCancelNormalTexture, this, _2) );
+ mBumpyTextureCtrl->setOnSelectCallback( boost::bind(&LLPanelFace::onSelectNormalTexture, this, _2) );
+ mBumpyTextureCtrl->setOnCloseCallback( boost::bind(&LLPanelFace::onCloseTexturePicker, this, _2) );
+
+ mBumpyTextureCtrl->setDragCallback(boost::bind(&LLPanelFace::onDragTexture, this, _2));
+ mBumpyTextureCtrl->setOnTextureSelectedCallback(boost::bind(&LLPanelFace::onTextureSelectionChanged, this, _1));
+ mBumpyTextureCtrl->setFollowsTop();
+ mBumpyTextureCtrl->setFollowsLeft();
+ mBumpyTextureCtrl->setImmediateFilterPermMask(PERM_NONE);
+ mBumpyTextureCtrl->setDnDFilterPermMask(PERM_COPY | PERM_TRANSFER);
}
mColorSwatch = getChild<LLColorSwatchCtrl>("colorswatch");
@@ -138,6 +238,15 @@ BOOL LLPanelFace::postBuild()
mColorSwatch->setCanApplyImmediately(TRUE);
}
+ mShinyColorSwatch = getChild<LLColorSwatchCtrl>("shinycolorswatch");
+ if(mShinyColorSwatch)
+ {
+ mShinyColorSwatch->setCommitCallback(boost::bind(&LLPanelFace::onCommitShinyColor, this, _2));
+ mShinyColorSwatch->setFollowsTop();
+ mShinyColorSwatch->setFollowsLeft();
+ mShinyColorSwatch->setCanApplyImmediately(TRUE);
+ }
+
mLabelColorTransp = getChild<LLTextBox>("color trans");
if(mLabelColorTransp)
{
@@ -167,6 +276,20 @@ BOOL LLPanelFace::postBuild()
mComboTexGen->setFollows(FOLLOWS_LEFT | FOLLOWS_TOP);
}
+ mComboMatMedia = getChild<LLComboBox>("combobox matmedia");
+ if(mComboMatMedia)
+ {
+ mComboMatMedia->setCommitCallback(LLPanelFace::onCommitMaterialsMedia,this);
+ mComboMatMedia->selectNthItem(MATMEDIA_MATERIAL);
+ }
+
+ mComboMatType = getChild<LLComboBox>("combobox mattype");
+ if(mComboMatType)
+ {
+ mComboMatType->setCommitCallback(LLPanelFace::onCommitMaterialType, this);
+ mComboMatType->selectNthItem(MATTYPE_DIFFUSE);
+ }
+
mCtrlGlow = getChild<LLSpinCtrl>("glow");
if(mCtrlGlow)
{
@@ -180,8 +303,10 @@ BOOL LLPanelFace::postBuild()
}
LLPanelFace::LLPanelFace()
-: LLPanel()
+: LLPanel(),
+ mIsAlpha(false)
{
+ USE_TEXTURE = LLTrans::getString("use_texture");
}
@@ -208,12 +333,32 @@ void LLPanelFace::sendTexture()
}
}
-void LLPanelFace::sendBump()
+void LLPanelFace::sendBump(U32 bumpiness)
{
- LLComboBox* mComboBumpiness = getChild<LLComboBox>("combobox bumpiness");
- if(!mComboBumpiness)return;
- U8 bump = (U8) mComboBumpiness->getCurrentIndex() & TEM_BUMP_MASK;
- LLSelectMgr::getInstance()->selectionSetBumpmap( bump );
+ LLTextureCtrl* bumpytexture_ctrl = getChild<LLTextureCtrl>("bumpytexture control");
+ if (bumpiness < BUMPY_TEXTURE)
+ {
+ LL_DEBUGS("Materials") << "clearing bumptexture control" << LL_ENDL;
+ bumpytexture_ctrl->clear();
+ bumpytexture_ctrl->setImageAssetID(LLUUID());
+ }
+
+ updateBumpyControls(bumpiness == BUMPY_TEXTURE, true);
+
+ LLUUID current_normal_map = bumpytexture_ctrl->getImageAssetID();
+
+ U8 bump = (U8) bumpiness & TEM_BUMP_MASK;
+
+ // Clear legacy bump to None when using an actual normal map
+ //
+ if (!current_normal_map.isNull())
+ bump = 0;
+
+ // Set the normal map or reset it to null as appropriate
+ //
+ LLSelectedTEMaterial::setNormalID(this, current_normal_map);
+
+ LLSelectMgr::getInstance()->selectionSetBumpmap( bump );
}
void LLPanelFace::sendTexGen()
@@ -224,12 +369,28 @@ void LLPanelFace::sendTexGen()
LLSelectMgr::getInstance()->selectionSetTexGen( tex_gen );
}
-void LLPanelFace::sendShiny()
+void LLPanelFace::sendShiny(U32 shininess)
{
- LLComboBox* mComboShininess = getChild<LLComboBox>("combobox shininess");
- if(!mComboShininess)return;
- U8 shiny = (U8) mComboShininess->getCurrentIndex() & TEM_SHINY_MASK;
+ LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>("shinytexture control");
+
+ if (shininess < SHINY_TEXTURE)
+ {
+ texture_ctrl->clear();
+ texture_ctrl->setImageAssetID(LLUUID());
+ }
+
+ LLUUID specmap = getCurrentSpecularMap();
+
+ U8 shiny = (U8) shininess & TEM_SHINY_MASK;
+ if (!specmap.isNull())
+ shiny = 0;
+
+ LLSelectedTEMaterial::setSpecularID(this, specmap);
+
LLSelectMgr::getInstance()->selectionSetShiny( shiny );
+
+ updateShinyControls(!specmap.isNull(), true);
+
}
void LLPanelFace::sendFullbright()
@@ -283,22 +444,16 @@ struct LLPanelFaceSetTEFunctor : public LLSelectedTEFunctor
LLSpinCtrl* ctrlTexOffsetS = mPanel->getChild<LLSpinCtrl>("TexOffsetU");
LLSpinCtrl* ctrlTexOffsetT = mPanel->getChild<LLSpinCtrl>("TexOffsetV");
LLSpinCtrl* ctrlTexRotation = mPanel->getChild<LLSpinCtrl>("TexRot");
- LLCheckBoxCtrl* checkFlipScaleS = mPanel->getChild<LLCheckBoxCtrl>("checkbox flip s");
- LLCheckBoxCtrl* checkFlipScaleT = mPanel->getChild<LLCheckBoxCtrl>("checkbox flip t");
LLComboBox* comboTexGen = mPanel->getChild<LLComboBox>("combobox texgen");
llassert(comboTexGen);
llassert(object);
if (ctrlTexScaleS)
{
- valid = !ctrlTexScaleS->getTentative() || !checkFlipScaleS->getTentative();
+ valid = !ctrlTexScaleS->getTentative(); // || !checkFlipScaleS->getTentative();
if (valid)
{
value = ctrlTexScaleS->get();
- if( checkFlipScaleS->get() )
- {
- value = -value;
- }
if (comboTexGen &&
comboTexGen->getCurrentIndex() == 1)
{
@@ -310,14 +465,14 @@ struct LLPanelFaceSetTEFunctor : public LLSelectedTEFunctor
if (ctrlTexScaleT)
{
- valid = !ctrlTexScaleT->getTentative() || !checkFlipScaleT->getTentative();
+ valid = !ctrlTexScaleT->getTentative(); // || !checkFlipScaleT->getTentative();
if (valid)
{
value = ctrlTexScaleT->get();
- if( checkFlipScaleT->get() )
- {
- value = -value;
- }
+ //if( checkFlipScaleT->get() )
+ //{
+ // value = -value;
+ //}
if (comboTexGen &&
comboTexGen->getCurrentIndex() == 1)
{
@@ -473,16 +628,9 @@ void LLPanelFace::sendTextureInfo()
{
if ((bool)childGetValue("checkbox planar align").asBoolean())
{
- struct f1 : public LLSelectedTEGetFunctor<LLFace *>
- {
- LLFace* get(LLViewerObject* object, S32 te)
- {
- return (object->mDrawable) ? object->mDrawable->getFace(te): NULL;
- }
- } get_last_face_func;
- LLFace* last_face;
- LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&get_last_face_func, last_face);
-
+ LLFace* last_face = NULL;
+ bool identical_face =false;
+ LLSelectedTE::getFace(last_face, identical_face);
LLPanelFaceSetAlignedTEFunctor setfunc(this, last_face);
LLSelectMgr::getInstance()->getSelection()->applyToTEs(&setfunc);
}
@@ -498,440 +646,729 @@ void LLPanelFace::sendTextureInfo()
void LLPanelFace::getState()
{
+ updateUI();
+}
+
+void LLPanelFace::updateUI()
+{ //set state of UI to match state of texture entry(ies) (calls setEnabled, setValue, etc, but NOT setVisible)
LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getFirstObject();
if( objectp
&& objectp->getPCode() == LL_PCODE_VOLUME
&& objectp->permModify())
{
- BOOL editable = objectp->permModify();
+ BOOL editable = objectp->permModify() && !objectp->isPermanentEnforced();
// only turn on auto-adjust button if there is a media renderer and the media is loaded
- getChildView("textbox autofix")->setEnabled(editable);
getChildView("button align")->setEnabled(editable);
+
+ LLComboBox* combobox_matmedia = getChild<LLComboBox>("combobox matmedia");
+ if (combobox_matmedia)
+ {
+ if (combobox_matmedia->getCurrentIndex() < MATMEDIA_MATERIAL)
+ {
+ combobox_matmedia->selectNthItem(MATMEDIA_MATERIAL);
+ }
+ }
+ else
+ {
+ llwarns << "failed getChild for 'combobox matmedia'" << llendl;
+ }
+ getChildView("combobox matmedia")->setEnabled(editable);
+
+ LLComboBox* combobox_mattype = getChild<LLComboBox>("combobox mattype");
+ if (combobox_mattype)
+ {
+ if (combobox_mattype->getCurrentIndex() < MATTYPE_DIFFUSE)
+ {
+ combobox_mattype->selectNthItem(MATTYPE_DIFFUSE);
+ }
+ }
+ else
+ {
+ LL_WARNS("Materials") << "failed getChild for 'combobox mattype'" << LL_ENDL;
+ }
+ getChildView("combobox mattype")->setEnabled(editable);
+
+ updateVisibility();
+
+ bool identical = true; // true because it is anded below
+ bool identical_diffuse = false;
+ bool identical_norm = false;
+ bool identical_spec = false;
+
+ LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>("texture control");
+ LLTextureCtrl* shinytexture_ctrl = getChild<LLTextureCtrl>("shinytexture control");
+ LLTextureCtrl* bumpytexture_ctrl = getChild<LLTextureCtrl>("bumpytexture control");
- //if ( LLMediaEngine::getInstance()->getMediaRenderer () )
- // if ( LLMediaEngine::getInstance()->getMediaRenderer ()->isLoaded () )
- // {
- //
- // //mLabelTexAutoFix->setEnabled ( editable );
- //
- // //mBtnAutoFix->setEnabled ( editable );
- // }
- getChildView("button apply")->setEnabled(editable);
-
- bool identical;
- LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>("texture control");
+ LLUUID id;
+ LLUUID normmap_id;
+ LLUUID specmap_id;
+
+ // Color swatch
+ {
+ getChildView("color label")->setEnabled(editable);
+ }
+ LLColorSwatchCtrl* mColorSwatch = getChild<LLColorSwatchCtrl>("colorswatch");
+
+ LLColor4 color = LLColor4::white;
+ bool identical_color = false;
+
+ if(mColorSwatch)
+ {
+ LLSelectedTE::getColor(color, identical_color);
+
+ mColorSwatch->setOriginal(color);
+ mColorSwatch->set(color, TRUE);
+
+ mColorSwatch->setValid(editable);
+ mColorSwatch->setEnabled( editable );
+ mColorSwatch->setCanApplyImmediately( editable );
+ }
+
+ // Color transparency
+ getChildView("color trans")->setEnabled(editable);
+
+ F32 transparency = (1.f - color.mV[VALPHA]) * 100.f;
+ getChild<LLUICtrl>("ColorTrans")->setValue(editable ? transparency : 0);
+ getChildView("ColorTrans")->setEnabled(editable);
+
+ // Specular map
+ LLSelectedTEMaterial::getSpecularID(specmap_id, identical_spec);
- // Texture
+ U8 shiny = 0;
+ bool identical_shiny = false;
+
+ // Shiny
+ LLSelectedTE::getShiny(shiny, identical_shiny);
+ identical = identical && identical_shiny;
+
+ shiny = specmap_id.isNull() ? shiny : SHINY_TEXTURE;
+
+ LLCtrlSelectionInterface* combobox_shininess = childGetSelectionInterface("combobox shininess");
+ if (combobox_shininess)
{
- LLUUID id;
- struct f1 : public LLSelectedTEGetFunctor<LLUUID>
+ combobox_shininess->selectNthItem((S32)shiny);
+ }
+
+ getChildView("label shininess")->setEnabled(editable);
+ getChildView("combobox shininess")->setEnabled(editable);
+
+ getChildView("label glossiness")->setEnabled(editable);
+ getChildView("glossiness")->setEnabled(editable);
+
+ getChildView("label environment")->setEnabled(editable);
+ getChildView("environment")->setEnabled(editable);
+ getChildView("label shinycolor")->setEnabled(editable);
+
+ getChild<LLUICtrl>("combobox shininess")->setTentative(!identical_spec);
+ getChild<LLUICtrl>("glossiness")->setTentative(!identical_spec);
+ getChild<LLUICtrl>("environment")->setTentative(!identical_spec);
+ getChild<LLUICtrl>("shinycolorswatch")->setTentative(!identical_spec);
+
+ LLColorSwatchCtrl* mShinyColorSwatch = getChild<LLColorSwatchCtrl>("shinycolorswatch");
+ if(mShinyColorSwatch)
+ {
+ mShinyColorSwatch->setValid(editable);
+ mShinyColorSwatch->setEnabled( editable );
+ mShinyColorSwatch->setCanApplyImmediately( editable );
+ }
+
+ U8 bumpy = 0;
+ // Bumpy
+ {
+ bool identical_bumpy = false;
+ LLSelectedTE::getBumpmap(bumpy,identical_bumpy);
+
+ LLUUID norm_map_id = getCurrentNormalMap();
+ LLCtrlSelectionInterface* combobox_bumpiness = childGetSelectionInterface("combobox bumpiness");
+
+ bumpy = norm_map_id.isNull() ? bumpy : BUMPY_TEXTURE;
+
+ if (combobox_bumpiness)
{
- LLUUID get(LLViewerObject* object, S32 te_index)
- {
- LLUUID id;
-
- LLViewerTexture* image = object->getTEImage(te_index);
- if (image) id = image->getID();
-
- if (!id.isNull() && LLViewerMedia::textureHasMedia(id))
- {
- LLTextureEntry *te = object->getTE(te_index);
- if (te)
- {
- LLViewerTexture* tex = te->getID().notNull() ? gTextureList.findImage(te->getID()) : NULL ;
- if(!tex)
- {
- tex = LLViewerFetchedTexture::sDefaultImagep;
- }
- if (tex)
- {
- id = tex->getID();
- }
- }
- }
- return id;
- }
- } func;
- identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, id );
+ combobox_bumpiness->selectNthItem((S32)bumpy);
+ }
+ else
+ {
+ llwarns << "failed childGetSelectionInterface for 'combobox bumpiness'" << llendl;
+ }
+
+ getChildView("combobox bumpiness")->setEnabled(editable);
+ getChild<LLUICtrl>("combobox bumpiness")->setTentative(!identical_bumpy);
+ getChildView("label bumpiness")->setEnabled(editable);
+ }
+
+ // Texture
+ {
+ LLSelectedTE::getTexId(id,identical_diffuse);
+
+ // Normal map
+ LLSelectedTEMaterial::getNormalID(normmap_id, identical_norm);
+
+ mIsAlpha = FALSE;
+ LLGLenum image_format = GL_RGB;
+ bool identical_image_format = false;
+ LLSelectedTE::getImageFormat(image_format, identical_image_format);
+
+ mIsAlpha = FALSE;
+ switch (image_format)
+ {
+ case GL_RGBA:
+ case GL_ALPHA:
+ {
+ mIsAlpha = TRUE;
+ }
+ break;
+
+ case GL_RGB: break;
+ default:
+ {
+ llwarns << "Unexpected tex format in LLPanelFace...resorting to no alpha" << llendl;
+ }
+ break;
+ }
if(LLViewerMedia::textureHasMedia(id))
{
- getChildView("textbox autofix")->setEnabled(editable);
getChildView("button align")->setEnabled(editable);
}
- if (identical)
+ // Diffuse Alpha Mode
+
+ // Init to the default that is appropriate for the alpha content of the asset
+ //
+ U8 alpha_mode = mIsAlpha ? LLMaterial::DIFFUSE_ALPHA_MODE_BLEND : LLMaterial::DIFFUSE_ALPHA_MODE_NONE;
+
+ bool identical_alpha_mode = false;
+
+ // See if that's been overridden by a material setting for same...
+ //
+ LLSelectedTEMaterial::getCurrentDiffuseAlphaMode(alpha_mode, identical_alpha_mode, mIsAlpha);
+
+ LLCtrlSelectionInterface* combobox_alphamode = childGetSelectionInterface("combobox alphamode");
+ if (combobox_alphamode)
+ {
+ //it is invalid to have any alpha mode other than blend if transparency is greater than zero ...
+ // Want masking? Want emissive? Tough! You get BLEND!
+ alpha_mode = (transparency > 0.f) ? LLMaterial::DIFFUSE_ALPHA_MODE_BLEND : alpha_mode;
+
+ // ... unless there is no alpha channel in the texture, in which case alpha mode MUST be none
+ alpha_mode = mIsAlpha ? alpha_mode : LLMaterial::DIFFUSE_ALPHA_MODE_NONE;
+
+ combobox_alphamode->selectNthItem(alpha_mode);
+ }
+ else
+ {
+ llwarns << "failed childGetSelectionInterface for 'combobox alphamode'" << llendl;
+ }
+
+ updateAlphaControls();
+
+ if(texture_ctrl)
{
- // All selected have the same texture
- if(texture_ctrl)
+ if (identical_diffuse)
{
texture_ctrl->setTentative( FALSE );
texture_ctrl->setEnabled( editable );
texture_ctrl->setImageAssetID( id );
+ getChildView("combobox alphamode")->setEnabled(editable && mIsAlpha && transparency <= 0.f);
+ getChildView("label alphamode")->setEnabled(editable && mIsAlpha);
+ getChildView("maskcutoff")->setEnabled(editable && mIsAlpha);
+ getChildView("label maskcutoff")->setEnabled(editable && mIsAlpha);
}
- }
- else
- {
- if(texture_ctrl)
+ else if (id.isNull())
{
- if( id.isNull() )
- {
- // None selected
- texture_ctrl->setTentative( FALSE );
- texture_ctrl->setEnabled( FALSE );
- texture_ctrl->setImageAssetID( LLUUID::null );
- }
- else
- {
- // Tentative: multiple selected with different textures
- texture_ctrl->setTentative( TRUE );
- texture_ctrl->setEnabled( editable );
- texture_ctrl->setImageAssetID( id );
- }
+ // None selected
+ texture_ctrl->setTentative( FALSE );
+ texture_ctrl->setEnabled( FALSE );
+ texture_ctrl->setImageAssetID( LLUUID::null );
+ getChildView("combobox alphamode")->setEnabled( FALSE );
+ getChildView("label alphamode")->setEnabled( FALSE );
+ getChildView("maskcutoff")->setEnabled( FALSE);
+ getChildView("label maskcutoff")->setEnabled( FALSE );
+ }
+ else
+ {
+ // Tentative: multiple selected with different textures
+ texture_ctrl->setTentative( TRUE );
+ texture_ctrl->setEnabled( editable );
+ texture_ctrl->setImageAssetID( id );
+ getChildView("combobox alphamode")->setEnabled(editable && mIsAlpha && transparency <= 0.f);
+ getChildView("label alphamode")->setEnabled(editable && mIsAlpha);
+ getChildView("maskcutoff")->setEnabled(editable && mIsAlpha);
+ getChildView("label maskcutoff")->setEnabled(editable && mIsAlpha);
}
}
- }
+
+ if (shinytexture_ctrl)
+ {
+ if (identical_spec && (shiny == SHINY_TEXTURE))
+ {
+ shinytexture_ctrl->setTentative( FALSE );
+ shinytexture_ctrl->setEnabled( editable );
+ shinytexture_ctrl->setImageAssetID( specmap_id );
+ }
+ else if (specmap_id.isNull())
+ {
+ shinytexture_ctrl->setTentative( FALSE );
+ shinytexture_ctrl->setEnabled( editable );
+ shinytexture_ctrl->setImageAssetID( LLUUID::null );
+ }
+ else
+ {
+ shinytexture_ctrl->setTentative( TRUE );
+ shinytexture_ctrl->setEnabled( editable );
+ shinytexture_ctrl->setImageAssetID( specmap_id );
+ }
+ }
-
- LLAggregatePermissions texture_perms;
- if(texture_ctrl)
- {
-// texture_ctrl->setValid( editable );
-
- if (LLSelectMgr::getInstance()->selectGetAggregateTexturePermissions(texture_perms))
- {
- BOOL can_copy =
- texture_perms.getValue(PERM_COPY) == LLAggregatePermissions::AP_EMPTY ||
- texture_perms.getValue(PERM_COPY) == LLAggregatePermissions::AP_ALL;
- BOOL can_transfer =
- texture_perms.getValue(PERM_TRANSFER) == LLAggregatePermissions::AP_EMPTY ||
- texture_perms.getValue(PERM_TRANSFER) == LLAggregatePermissions::AP_ALL;
- texture_ctrl->setCanApplyImmediately(can_copy && can_transfer);
- }
- else
- {
- texture_ctrl->setCanApplyImmediately(FALSE);
+ if (bumpytexture_ctrl)
+ {
+ if (identical_norm && (bumpy == BUMPY_TEXTURE))
+ {
+ bumpytexture_ctrl->setTentative( FALSE );
+ bumpytexture_ctrl->setEnabled( editable );
+ bumpytexture_ctrl->setImageAssetID( normmap_id );
+ }
+ else if (normmap_id.isNull())
+ {
+ bumpytexture_ctrl->setTentative( FALSE );
+ bumpytexture_ctrl->setEnabled( editable );
+ bumpytexture_ctrl->setImageAssetID( LLUUID::null );
+ }
+ else
+ {
+ bumpytexture_ctrl->setTentative( TRUE );
+ bumpytexture_ctrl->setEnabled( editable );
+ bumpytexture_ctrl->setImageAssetID( normmap_id );
+ }
}
}
-
-
+
// planar align
bool align_planar = false;
bool identical_planar_aligned = false;
- bool is_planar = false;
{
LLCheckBoxCtrl* cb_planar_align = getChild<LLCheckBoxCtrl>("checkbox planar align");
align_planar = (cb_planar_align && cb_planar_align->get());
- struct f1 : public LLSelectedTEGetFunctor<bool>
- {
- bool get(LLViewerObject* object, S32 face)
- {
- return (object->getTE(face)->getTexGen() == LLTextureEntry::TEX_GEN_PLANAR);
- }
- } func;
-
- bool texgens_identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, is_planar );
- bool enabled = (editable && texgens_identical && is_planar);
+
+ bool enabled = (editable && isIdenticalPlanarTexgen());
childSetValue("checkbox planar align", align_planar && enabled);
childSetEnabled("checkbox planar align", enabled);
if (align_planar && enabled)
{
- struct f2 : public LLSelectedTEGetFunctor<LLFace *>
- {
- LLFace* get(LLViewerObject* object, S32 te)
- {
- return (object->mDrawable) ? object->mDrawable->getFace(te): NULL;
- }
- } get_te_face_func;
- LLFace* last_face;
- LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&get_te_face_func, last_face);
+ LLFace* last_face = NULL;
+ bool identical_face = false;
+ LLSelectedTE::getFace(last_face, identical_face);
+
LLPanelFaceGetIsAlignedTEFunctor get_is_aligend_func(last_face);
// this will determine if the texture param controls are tentative:
identical_planar_aligned = LLSelectMgr::getInstance()->getSelection()->applyToTEs(&get_is_aligend_func);
}
}
+ // Needs to be public and before tex scale settings below to properly reflect
+ // behavior when in planar vs default texgen modes in the
+ // NORSPEC-84 et al
+ //
+ LLTextureEntry::e_texgen selected_texgen = LLTextureEntry::TEX_GEN_DEFAULT;
+ bool identical_texgen = true;
+ bool identical_planar_texgen = false;
+
+ {
+ LLSelectedTE::getTexGen(selected_texgen, identical_texgen);
+ identical_planar_texgen = (identical_texgen && (selected_texgen == LLTextureEntry::TEX_GEN_PLANAR));
+ }
+
// Texture scale
{
- F32 scale_s = 1.f;
- struct f2 : public LLSelectedTEGetFunctor<F32>
- {
- F32 get(LLViewerObject* object, S32 face)
- {
- return object->getTE(face)->mScaleS;
- }
- } func;
- identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, scale_s );
+ bool identical_diff_scale_s = false;
+ bool identical_spec_scale_s = false;
+ bool identical_norm_scale_s = false;
+
identical = align_planar ? identical_planar_aligned : identical;
- getChild<LLUICtrl>("TexScaleU")->setValue(editable ? llabs(scale_s) : 0);
- getChild<LLUICtrl>("TexScaleU")->setTentative(LLSD((BOOL)(!identical)));
+
+ F32 diff_scale_s = 1.f;
+ F32 spec_scale_s = 1.f;
+ F32 norm_scale_s = 1.f;
+
+ LLSelectedTE::getScaleS( diff_scale_s, identical_diff_scale_s);
+ LLSelectedTEMaterial::getSpecularRepeatX( spec_scale_s, identical_spec_scale_s);
+ LLSelectedTEMaterial::getNormalRepeatX( norm_scale_s, identical_norm_scale_s);
+
+ diff_scale_s = editable ? diff_scale_s : 1.0f;
+ diff_scale_s *= identical_planar_texgen ? 2.0f : 1.0f;
+
+ norm_scale_s = editable ? norm_scale_s : 1.0f;
+ norm_scale_s *= identical_planar_texgen ? 2.0f : 1.0f;
+
+ spec_scale_s = editable ? spec_scale_s : 1.0f;
+ spec_scale_s *= identical_planar_texgen ? 2.0f : 1.0f;
+
+ getChild<LLUICtrl>("TexScaleU")->setValue(diff_scale_s);
+ getChild<LLUICtrl>("shinyScaleU")->setValue(spec_scale_s);
+ getChild<LLUICtrl>("bumpyScaleU")->setValue(norm_scale_s);
+
getChildView("TexScaleU")->setEnabled(editable);
- getChild<LLUICtrl>("checkbox flip s")->setValue(LLSD((BOOL)(scale_s < 0 ? TRUE : FALSE )));
- getChild<LLUICtrl>("checkbox flip s")->setTentative(LLSD((BOOL)((!identical) ? TRUE : FALSE )));
- getChildView("checkbox flip s")->setEnabled(editable);
+ getChildView("shinyScaleU")->setEnabled(editable && specmap_id.notNull());
+ getChildView("bumpyScaleU")->setEnabled(editable && normmap_id.notNull());
+
+ BOOL diff_scale_tentative = !(identical && identical_diff_scale_s);
+ BOOL norm_scale_tentative = !(identical && identical_norm_scale_s);
+ BOOL spec_scale_tentative = !(identical && identical_spec_scale_s);
+
+ getChild<LLUICtrl>("TexScaleU")->setTentative( LLSD(diff_scale_tentative));
+ getChild<LLUICtrl>("shinyScaleU")->setTentative(LLSD(spec_scale_tentative));
+ getChild<LLUICtrl>("bumpyScaleU")->setTentative(LLSD(norm_scale_tentative));
}
{
- F32 scale_t = 1.f;
- struct f3 : public LLSelectedTEGetFunctor<F32>
- {
- F32 get(LLViewerObject* object, S32 face)
- {
- return object->getTE(face)->mScaleT;
- }
- } func;
- identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, scale_t );
- identical = align_planar ? identical_planar_aligned : identical;
+ bool identical_diff_scale_t = false;
+ bool identical_spec_scale_t = false;
+ bool identical_norm_scale_t = false;
+
+ F32 diff_scale_t = 1.f;
+ F32 spec_scale_t = 1.f;
+ F32 norm_scale_t = 1.f;
+
+ LLSelectedTE::getScaleT(diff_scale_t, identical_diff_scale_t);
+ LLSelectedTEMaterial::getSpecularRepeatY(spec_scale_t, identical_spec_scale_t);
+ LLSelectedTEMaterial::getNormalRepeatY(norm_scale_t, identical_norm_scale_t);
+
+ diff_scale_t = editable ? diff_scale_t : 1.0f;
+ diff_scale_t *= identical_planar_texgen ? 2.0f : 1.0f;
+
+ norm_scale_t = editable ? norm_scale_t : 1.0f;
+ norm_scale_t *= identical_planar_texgen ? 2.0f : 1.0f;
+
+ spec_scale_t = editable ? spec_scale_t : 1.0f;
+ spec_scale_t *= identical_planar_texgen ? 2.0f : 1.0f;
+
+ BOOL diff_scale_tentative = !identical_diff_scale_t;
+ BOOL norm_scale_tentative = !identical_norm_scale_t;
+ BOOL spec_scale_tentative = !identical_spec_scale_t;
- getChild<LLUICtrl>("TexScaleV")->setValue(llabs(editable ? llabs(scale_t) : 0));
- getChild<LLUICtrl>("TexScaleV")->setTentative(LLSD((BOOL)(!identical)));
getChildView("TexScaleV")->setEnabled(editable);
- getChild<LLUICtrl>("checkbox flip t")->setValue(LLSD((BOOL)(scale_t< 0 ? TRUE : FALSE )));
- getChild<LLUICtrl>("checkbox flip t")->setTentative(LLSD((BOOL)((!identical) ? TRUE : FALSE )));
- getChildView("checkbox flip t")->setEnabled(editable);
+ getChildView("shinyScaleV")->setEnabled(editable && specmap_id.notNull());
+ getChildView("bumpyScaleV")->setEnabled(editable && normmap_id.notNull());
+
+ getChild<LLUICtrl>("TexScaleV")->setValue(diff_scale_t);
+ getChild<LLUICtrl>("shinyScaleV")->setValue(norm_scale_t);
+ getChild<LLUICtrl>("bumpyScaleV")->setValue(spec_scale_t);
+
+ getChild<LLUICtrl>("TexScaleV")->setTentative(LLSD(diff_scale_tentative));
+ getChild<LLUICtrl>("shinyScaleV")->setTentative(LLSD(norm_scale_tentative));
+ getChild<LLUICtrl>("bumpyScaleV")->setTentative(LLSD(spec_scale_tentative));
}
// Texture offset
{
- getChildView("tex offset")->setEnabled(editable);
- F32 offset_s = 0.f;
- struct f4 : public LLSelectedTEGetFunctor<F32>
- {
- F32 get(LLViewerObject* object, S32 face)
- {
- return object->getTE(face)->mOffsetS;
- }
- } func;
- identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, offset_s );
- identical = align_planar ? identical_planar_aligned : identical;
- getChild<LLUICtrl>("TexOffsetU")->setValue(editable ? offset_s : 0);
- getChild<LLUICtrl>("TexOffsetU")->setTentative(!identical);
+ bool identical_diff_offset_s = false;
+ bool identical_norm_offset_s = false;
+ bool identical_spec_offset_s = false;
+
+ F32 diff_offset_s = 0.0f;
+ F32 norm_offset_s = 0.0f;
+ F32 spec_offset_s = 0.0f;
+
+ LLSelectedTE::getOffsetS(diff_offset_s, identical_diff_offset_s);
+ LLSelectedTEMaterial::getNormalOffsetX(norm_offset_s, identical_norm_offset_s);
+ LLSelectedTEMaterial::getSpecularOffsetX(spec_offset_s, identical_spec_offset_s);
+
+ BOOL diff_offset_u_tentative = !(align_planar ? identical_planar_aligned : identical_diff_offset_s);
+ BOOL norm_offset_u_tentative = !(align_planar ? identical_planar_aligned : identical_norm_offset_s);
+ BOOL spec_offset_u_tentative = !(align_planar ? identical_planar_aligned : identical_spec_offset_s);
+
+ getChild<LLUICtrl>("TexOffsetU")->setValue( editable ? diff_offset_s : 0.0f);
+ getChild<LLUICtrl>("bumpyOffsetU")->setValue(editable ? norm_offset_s : 0.0f);
+ getChild<LLUICtrl>("shinyOffsetU")->setValue(editable ? spec_offset_s : 0.0f);
+
+ getChild<LLUICtrl>("TexOffsetU")->setTentative(LLSD(diff_offset_u_tentative));
+ getChild<LLUICtrl>("shinyOffsetU")->setTentative(LLSD(norm_offset_u_tentative));
+ getChild<LLUICtrl>("bumpyOffsetU")->setTentative(LLSD(spec_offset_u_tentative));
+
getChildView("TexOffsetU")->setEnabled(editable);
+ getChildView("shinyOffsetU")->setEnabled(editable && specmap_id.notNull());
+ getChildView("bumpyOffsetU")->setEnabled(editable && normmap_id.notNull());
}
{
- F32 offset_t = 0.f;
- struct f5 : public LLSelectedTEGetFunctor<F32>
- {
- F32 get(LLViewerObject* object, S32 face)
- {
- return object->getTE(face)->mOffsetT;
- }
- } func;
- identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, offset_t );
- identical = align_planar ? identical_planar_aligned : identical;
- getChild<LLUICtrl>("TexOffsetV")->setValue(editable ? offset_t : 0);
- getChild<LLUICtrl>("TexOffsetV")->setTentative(!identical);
+ bool identical_diff_offset_t = false;
+ bool identical_norm_offset_t = false;
+ bool identical_spec_offset_t = false;
+
+ F32 diff_offset_t = 0.0f;
+ F32 norm_offset_t = 0.0f;
+ F32 spec_offset_t = 0.0f;
+
+ LLSelectedTE::getOffsetT(diff_offset_t, identical_diff_offset_t);
+ LLSelectedTEMaterial::getNormalOffsetY(norm_offset_t, identical_norm_offset_t);
+ LLSelectedTEMaterial::getSpecularOffsetY(spec_offset_t, identical_spec_offset_t);
+
+ BOOL diff_offset_v_tentative = !(align_planar ? identical_planar_aligned : identical_diff_offset_t);
+ BOOL norm_offset_v_tentative = !(align_planar ? identical_planar_aligned : identical_norm_offset_t);
+ BOOL spec_offset_v_tentative = !(align_planar ? identical_planar_aligned : identical_spec_offset_t);
+
+ getChild<LLUICtrl>("TexOffsetV")->setValue( editable ? diff_offset_t : 0.0f);
+ getChild<LLUICtrl>("bumpyOffsetV")->setValue(editable ? norm_offset_t : 0.0f);
+ getChild<LLUICtrl>("shinyOffsetV")->setValue(editable ? spec_offset_t : 0.0f);
+
+ getChild<LLUICtrl>("TexOffsetV")->setTentative(LLSD(diff_offset_v_tentative));
+ getChild<LLUICtrl>("shinyOffsetV")->setTentative(LLSD(norm_offset_v_tentative));
+ getChild<LLUICtrl>("bumpyOffsetV")->setTentative(LLSD(spec_offset_v_tentative));
+
getChildView("TexOffsetV")->setEnabled(editable);
+ getChildView("shinyOffsetV")->setEnabled(editable && specmap_id.notNull());
+ getChildView("bumpyOffsetV")->setEnabled(editable && normmap_id.notNull());
}
// Texture rotation
{
- F32 rotation = 0.f;
- struct f6 : public LLSelectedTEGetFunctor<F32>
- {
- F32 get(LLViewerObject* object, S32 face)
- {
- return object->getTE(face)->mRotation;
- }
- } func;
- identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, rotation );
- identical = align_planar ? identical_planar_aligned : identical;
- getChild<LLUICtrl>("TexRot")->setValue(editable ? rotation * RAD_TO_DEG : 0);
- getChild<LLUICtrl>("TexRot")->setTentative(!identical);
- getChildView("TexRot")->setEnabled(editable);
- }
+ bool identical_diff_rotation = false;
+ bool identical_norm_rotation = false;
+ bool identical_spec_rotation = false;
- // Color swatch
- LLColorSwatchCtrl* mColorSwatch = getChild<LLColorSwatchCtrl>("colorswatch");
- LLColor4 color = LLColor4::white;
- if(mColorSwatch)
- {
- struct f7 : public LLSelectedTEGetFunctor<LLColor4>
- {
- LLColor4 get(LLViewerObject* object, S32 face)
- {
- return object->getTE(face)->getColor();
- }
- } func;
- identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, color );
-
- mColorSwatch->setOriginal(color);
- mColorSwatch->set(color, TRUE);
+ F32 diff_rotation = 0.f;
+ F32 norm_rotation = 0.f;
+ F32 spec_rotation = 0.f;
- mColorSwatch->setValid(editable);
- mColorSwatch->setEnabled( editable );
- mColorSwatch->setCanApplyImmediately( editable );
- }
- // Color transparency
- {
- getChildView("color trans")->setEnabled(editable);
- }
+ LLSelectedTE::getRotation(diff_rotation,identical_diff_rotation);
+ LLSelectedTEMaterial::getSpecularRotation(spec_rotation,identical_spec_rotation);
+ LLSelectedTEMaterial::getNormalRotation(norm_rotation,identical_norm_rotation);
- F32 transparency = (1.f - color.mV[VALPHA]) * 100.f;
- {
- getChild<LLUICtrl>("ColorTrans")->setValue(editable ? transparency : 0);
- getChildView("ColorTrans")->setEnabled(editable);
- }
+ BOOL diff_rot_tentative = !(align_planar ? identical_planar_aligned : identical_diff_rotation);
+ BOOL norm_rot_tentative = !(align_planar ? identical_planar_aligned : identical_norm_rotation);
+ BOOL spec_rot_tentative = !(align_planar ? identical_planar_aligned : identical_spec_rotation);
- {
- F32 glow = 0.f;
- struct f8 : public LLSelectedTEGetFunctor<F32>
- {
- F32 get(LLViewerObject* object, S32 face)
- {
- return object->getTE(face)->getGlow();
- }
- } func;
- identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, glow );
+ F32 diff_rot_deg = diff_rotation * RAD_TO_DEG;
+ F32 norm_rot_deg = norm_rotation * RAD_TO_DEG;
+ F32 spec_rot_deg = spec_rotation * RAD_TO_DEG;
- getChild<LLUICtrl>("glow")->setValue(glow);
- getChildView("glow")->setEnabled(editable);
- getChild<LLUICtrl>("glow")->setTentative(!identical);
- getChildView("glow label")->setEnabled(editable);
+ getChildView("TexRot")->setEnabled(editable);
+ getChildView("shinyRot")->setEnabled(editable && specmap_id.notNull());
+ getChildView("bumpyRot")->setEnabled(editable && normmap_id.notNull());
- }
+ getChild<LLUICtrl>("TexRot")->setTentative(diff_rot_tentative);
+ getChild<LLUICtrl>("shinyRot")->setTentative(LLSD(norm_rot_tentative));
+ getChild<LLUICtrl>("bumpyRot")->setTentative(LLSD(spec_rot_tentative));
- // Bump
- {
- F32 shinyf = 0.f;
- struct f9 : public LLSelectedTEGetFunctor<F32>
- {
- F32 get(LLViewerObject* object, S32 face)
- {
- return (F32)(object->getTE(face)->getShiny());
- }
- } func;
- identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, shinyf );
- LLCtrlSelectionInterface* combobox_shininess =
- childGetSelectionInterface("combobox shininess");
- if (combobox_shininess)
- {
- combobox_shininess->selectNthItem((S32)shinyf);
- }
- else
- {
- llwarns << "failed childGetSelectionInterface for 'combobox shininess'" << llendl;
- }
- getChildView("combobox shininess")->setEnabled(editable);
- getChild<LLUICtrl>("combobox shininess")->setTentative(!identical);
- getChildView("label shininess")->setEnabled(editable);
+ getChild<LLUICtrl>("TexRot")->setValue( editable ? diff_rot_deg : 0.0f);
+ getChild<LLUICtrl>("shinyRot")->setValue(editable ? spec_rot_deg : 0.0f);
+ getChild<LLUICtrl>("bumpyRot")->setValue(editable ? norm_rot_deg : 0.0f);
}
{
- F32 bumpf = 0.f;
- struct f10 : public LLSelectedTEGetFunctor<F32>
- {
- F32 get(LLViewerObject* object, S32 face)
- {
- return (F32)(object->getTE(face)->getBumpmap());
- }
- } func;
- identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, bumpf );
- LLCtrlSelectionInterface* combobox_bumpiness =
- childGetSelectionInterface("combobox bumpiness");
- if (combobox_bumpiness)
- {
- combobox_bumpiness->selectNthItem((S32)bumpf);
- }
- else
- {
- llwarns << "failed childGetSelectionInterface for 'combobox bumpiness'" << llendl;
- }
- getChildView("combobox bumpiness")->setEnabled(editable);
- getChild<LLUICtrl>("combobox bumpiness")->setTentative(!identical);
- getChildView("label bumpiness")->setEnabled(editable);
+ F32 glow = 0.f;
+ bool identical_glow = false;
+ LLSelectedTE::getGlow(glow,identical_glow);
+ getChild<LLUICtrl>("glow")->setValue(glow);
+ getChild<LLUICtrl>("glow")->setTentative(!identical_glow);
+ getChildView("glow")->setEnabled(editable);
+ getChildView("glow label")->setEnabled(editable);
}
- {
- F32 genf = 0.f;
- struct f11 : public LLSelectedTEGetFunctor<F32>
- {
- F32 get(LLViewerObject* object, S32 face)
- {
- return (F32)(object->getTE(face)->getTexGen());
- }
- } func;
- identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, genf );
- S32 selected_texgen = ((S32) genf) >> TEM_TEX_GEN_SHIFT;
- LLCtrlSelectionInterface* combobox_texgen =
- childGetSelectionInterface("combobox texgen");
+ {
+ LLCtrlSelectionInterface* combobox_texgen = childGetSelectionInterface("combobox texgen");
if (combobox_texgen)
{
- combobox_texgen->selectNthItem(selected_texgen);
+ // Maps from enum to combobox entry index
+ combobox_texgen->selectNthItem(((S32)selected_texgen) >> 1);
}
else
{
llwarns << "failed childGetSelectionInterface for 'combobox texgen'" << llendl;
}
+
getChildView("combobox texgen")->setEnabled(editable);
getChild<LLUICtrl>("combobox texgen")->setTentative(!identical);
getChildView("tex gen")->setEnabled(editable);
- if (selected_texgen == 1)
+ if (selected_texgen == LLTextureEntry::TEX_GEN_PLANAR)
{
- getChild<LLUICtrl>("TexScaleU")->setValue(2.0f * getChild<LLUICtrl>("TexScaleU")->getValue().asReal() );
- getChild<LLUICtrl>("TexScaleV")->setValue(2.0f * getChild<LLUICtrl>("TexScaleV")->getValue().asReal() );
-
// EXP-1507 (change label based on the mapping mode)
getChild<LLUICtrl>("rpt")->setValue(getString("string repeats per meter"));
}
else
- if (selected_texgen == 0) // FIXME: should not be magic numbers
+ if (selected_texgen == LLTextureEntry::TEX_GEN_DEFAULT)
{
getChild<LLUICtrl>("rpt")->setValue(getString("string repeats per face"));
}
}
{
- F32 fullbrightf = 0.f;
- struct f12 : public LLSelectedTEGetFunctor<F32>
- {
- F32 get(LLViewerObject* object, S32 face)
- {
- return (F32)(object->getTE(face)->getFullbright());
- }
- } func;
- identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, fullbrightf );
+ U8 fullbright_flag = 0;
+ bool identical_fullbright = false;
+
+ LLSelectedTE::getFullbright(fullbright_flag,identical_fullbright);
- getChild<LLUICtrl>("checkbox fullbright")->setValue((S32)fullbrightf);
+ getChild<LLUICtrl>("checkbox fullbright")->setValue((S32)(fullbright_flag != 0));
getChildView("checkbox fullbright")->setEnabled(editable);
- getChild<LLUICtrl>("checkbox fullbright")->setTentative(!identical);
- }
-
- // Repeats per meter label
- {
- getChildView("rpt")->setEnabled(editable);
+ getChild<LLUICtrl>("checkbox fullbright")->setTentative(!identical_fullbright);
}
+
// Repeats per meter
{
- F32 repeats = 1.f;
- struct f13 : public LLSelectedTEGetFunctor<F32>
+ F32 repeats_diff = 1.f;
+ F32 repeats_norm = 1.f;
+ F32 repeats_spec = 1.f;
+
+ bool identical_diff_repeats = false;
+ bool identical_norm_repeats = false;
+ bool identical_spec_repeats = false;
+
+ LLSelectedTE::getMaxDiffuseRepeats(repeats_diff, identical_diff_repeats);
+ LLSelectedTEMaterial::getMaxNormalRepeats(repeats_norm, identical_norm_repeats);
+ LLSelectedTEMaterial::getMaxSpecularRepeats(repeats_spec, identical_spec_repeats);
+
+ LLComboBox* mComboTexGen = getChild<LLComboBox>("combobox texgen");
+ if (mComboTexGen)
{
- F32 get(LLViewerObject* object, S32 face)
+ S32 index = mComboTexGen ? mComboTexGen->getCurrentIndex() : 0;
+ BOOL enabled = editable && (index != 1);
+ BOOL identical_repeats = true;
+ F32 repeats = 1.0f;
+
+ U32 material_type = (combobox_matmedia->getCurrentIndex() == MATMEDIA_MATERIAL) ? combobox_mattype->getCurrentIndex() : MATTYPE_DIFFUSE;
+
+ LLSelectMgr::getInstance()->setTextureChannel(LLRender::eTexIndex(material_type));
+
+ switch (material_type)
{
- U32 s_axis = VX;
- U32 t_axis = VY;
- // BUG: Only repeats along S axis
- // BUG: Only works for boxes.
- LLPrimitive::getTESTAxes(face, &s_axis, &t_axis);
- return object->getTE(face)->mScaleS / object->getScale().mV[s_axis];
+ default:
+ case MATTYPE_DIFFUSE:
+ {
+ enabled = editable && !id.isNull();
+ identical_repeats = identical_diff_repeats;
+ repeats = repeats_diff;
+ }
+ break;
+
+ case MATTYPE_SPECULAR:
+ {
+ enabled = (editable && ((shiny == SHINY_TEXTURE) && !specmap_id.isNull()));
+ identical_repeats = identical_spec_repeats;
+ repeats = repeats_spec;
+ }
+ break;
+
+ case MATTYPE_NORMAL:
+ {
+ enabled = (editable && ((bumpy == BUMPY_TEXTURE) && !normmap_id.isNull()));
+ identical_repeats = identical_norm_repeats;
+ repeats = repeats_norm;
+ }
+ break;
}
- } func;
- identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, repeats );
-
- getChild<LLUICtrl>("rptctrl")->setValue(editable ? repeats : 0);
- getChild<LLUICtrl>("rptctrl")->setTentative(!identical);
- LLComboBox* mComboTexGen = getChild<LLComboBox>("combobox texgen");
- if (mComboTexGen)
+
+ BOOL repeats_tentative = !identical_repeats;
+
+ getChildView("rptctrl")->setEnabled(identical_planar_texgen ? FALSE : enabled);
+ getChild<LLUICtrl>("rptctrl")->setValue(editable ? repeats : 1.0f);
+ getChild<LLUICtrl>("rptctrl")->setTentative(LLSD(repeats_tentative));
+ }
+ }
+
+ // Materials
+ {
+ LLMaterialPtr material;
+ LLSelectedTEMaterial::getCurrent(material, identical);
+
+ if (material && editable)
{
- BOOL enabled = editable && (!mComboTexGen || mComboTexGen->getCurrentIndex() != 1);
- getChildView("rptctrl")->setEnabled(enabled);
- getChildView("button apply")->setEnabled(enabled);
+ LL_DEBUGS("Materials: OnMatererialsLoaded:") << material->asLLSD() << LL_ENDL;
+
+ // Alpha
+ LLCtrlSelectionInterface* combobox_alphamode =
+ childGetSelectionInterface("combobox alphamode");
+ if (combobox_alphamode)
+ {
+ U32 alpha_mode = material->getDiffuseAlphaMode();
+
+ if (transparency > 0.f)
+ { //it is invalid to have any alpha mode other than blend if transparency is greater than zero ...
+ alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_BLEND;
+ }
+
+ if (!mIsAlpha)
+ { // ... unless there is no alpha channel in the texture, in which case alpha mode MUST ebe none
+ alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_NONE;
+ }
+
+ combobox_alphamode->selectNthItem(alpha_mode);
+ }
+ else
+ {
+ llwarns << "failed childGetSelectionInterface for 'combobox alphamode'" << llendl;
+ }
+ getChild<LLUICtrl>("maskcutoff")->setValue(material->getAlphaMaskCutoff());
+ updateAlphaControls();
+
+ identical_planar_texgen = isIdenticalPlanarTexgen();
+
+ // Shiny (specular)
+ F32 offset_x, offset_y, repeat_x, repeat_y, rot;
+ LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>("shinytexture control");
+ texture_ctrl->setImageAssetID(material->getSpecularID());
+
+ if (!material->getSpecularID().isNull() && (shiny == SHINY_TEXTURE))
+ {
+ material->getSpecularOffset(offset_x,offset_y);
+ material->getSpecularRepeat(repeat_x,repeat_y);
+
+ if (identical_planar_texgen)
+ {
+ repeat_x *= 2.0f;
+ repeat_y *= 2.0f;
+ }
+
+ rot = material->getSpecularRotation();
+ getChild<LLUICtrl>("shinyScaleU")->setValue(repeat_x);
+ getChild<LLUICtrl>("shinyScaleV")->setValue(repeat_y);
+ getChild<LLUICtrl>("shinyRot")->setValue(rot*RAD_TO_DEG);
+ getChild<LLUICtrl>("shinyOffsetU")->setValue(offset_x);
+ getChild<LLUICtrl>("shinyOffsetV")->setValue(offset_y);
+ getChild<LLUICtrl>("glossiness")->setValue(material->getSpecularLightExponent());
+ getChild<LLUICtrl>("environment")->setValue(material->getEnvironmentIntensity());
+
+ updateShinyControls(!material->getSpecularID().isNull(), true);
+ }
+
+ // Assert desired colorswatch color to match material AFTER updateShinyControls
+ // to avoid getting overwritten with the default on some UI state changes.
+ //
+ if (!material->getSpecularID().isNull())
+ {
+ getChild<LLColorSwatchCtrl>("shinycolorswatch")->setOriginal(material->getSpecularLightColor());
+ getChild<LLColorSwatchCtrl>("shinycolorswatch")->set(material->getSpecularLightColor(),TRUE);
+ }
+
+ // Bumpy (normal)
+ texture_ctrl = getChild<LLTextureCtrl>("bumpytexture control");
+ texture_ctrl->setImageAssetID(material->getNormalID());
+
+ if (!material->getNormalID().isNull())
+ {
+ material->getNormalOffset(offset_x,offset_y);
+ material->getNormalRepeat(repeat_x,repeat_y);
+
+ if (identical_planar_texgen)
+ {
+ repeat_x *= 2.0f;
+ repeat_y *= 2.0f;
+ }
+
+ rot = material->getNormalRotation();
+ getChild<LLUICtrl>("bumpyScaleU")->setValue(repeat_x);
+ getChild<LLUICtrl>("bumpyScaleV")->setValue(repeat_y);
+ getChild<LLUICtrl>("bumpyRot")->setValue(rot*RAD_TO_DEG);
+ getChild<LLUICtrl>("bumpyOffsetU")->setValue(offset_x);
+ getChild<LLUICtrl>("bumpyOffsetV")->setValue(offset_y);
+
+ updateBumpyControls(!material->getNormalID().isNull(), true);
+ }
}
}
@@ -971,14 +1408,11 @@ void LLPanelFace::getState()
getChildView("tex gen")->setEnabled(FALSE);
getChildView("label shininess")->setEnabled(FALSE);
getChildView("label bumpiness")->setEnabled(FALSE);
-
- getChildView("textbox autofix")->setEnabled(FALSE);
-
getChildView("button align")->setEnabled(FALSE);
- getChildView("button apply")->setEnabled(FALSE);
//getChildView("has media")->setEnabled(FALSE);
//getChildView("media info set")->setEnabled(FALSE);
-
+
+ updateVisibility();
// Set variable values for numeric expressions
LLCalc* calcp = LLCalc::getInstance();
@@ -995,6 +1429,7 @@ void LLPanelFace::getState()
void LLPanelFace::refresh()
{
+ LL_DEBUGS("Materials") << LL_ENDL;
getState();
}
@@ -1014,6 +1449,11 @@ void LLPanelFace::onCommitColor(const LLSD& data)
sendColor();
}
+void LLPanelFace::onCommitShinyColor(const LLSD& data)
+{
+ LLSelectedTEMaterial::setSpecularLightColor(this, getChild<LLColorSwatchCtrl>("shinycolorswatch")->get());
+}
+
void LLPanelFace::onCommitAlpha(const LLSD& data)
{
sendAlpha();
@@ -1031,10 +1471,121 @@ void LLPanelFace::onSelectColor(const LLSD& data)
}
// static
+void LLPanelFace::onCommitMaterialsMedia(LLUICtrl* ctrl, void* userdata)
+{
+ LLPanelFace* self = (LLPanelFace*) userdata;
+ // Force to default states to side-step problems with menu contents
+ // and generally reflecting old state when switching tabs or objects
+ //
+ self->updateShinyControls(false,true);
+ self->updateBumpyControls(false,true);
+ self->updateUI();
+}
+
+// static
+void LLPanelFace::updateVisibility()
+{
+ LLComboBox* combo_matmedia = getChild<LLComboBox>("combobox matmedia");
+ LLComboBox* combo_mattype = getChild<LLComboBox>("combobox mattype");
+ LLComboBox* combo_shininess = getChild<LLComboBox>("combobox shininess");
+ LLComboBox* combo_bumpiness = getChild<LLComboBox>("combobox bumpiness");
+ if (!combo_mattype || !combo_matmedia || !combo_shininess || !combo_bumpiness)
+ {
+ LL_WARNS("Materials") << "Combo box not found...exiting." << LL_ENDL;
+ return;
+ }
+ U32 materials_media = combo_matmedia->getCurrentIndex();
+ U32 material_type = combo_mattype->getCurrentIndex();
+ bool show_media = (materials_media == MATMEDIA_MEDIA) && combo_matmedia->getEnabled();
+ bool show_texture = (show_media || ((material_type == MATTYPE_DIFFUSE) && combo_matmedia->getEnabled()));
+ bool show_bumpiness = (!show_media) && (material_type == MATTYPE_NORMAL) && combo_matmedia->getEnabled();
+ bool show_shininess = (!show_media) && (material_type == MATTYPE_SPECULAR) && combo_matmedia->getEnabled();
+ getChildView("combobox mattype")->setVisible(!show_media);
+ getChildView("rptctrl")->setVisible(true);
+
+ // Media controls
+ getChildView("media_info")->setVisible(show_media);
+ getChildView("add_media")->setVisible(show_media);
+ getChildView("delete_media")->setVisible(show_media);
+ getChildView("button align")->setVisible(show_media);
+
+ // Diffuse texture controls
+ getChildView("texture control")->setVisible(show_texture && !show_media);
+ getChildView("label alphamode")->setVisible(show_texture && !show_media);
+ getChildView("combobox alphamode")->setVisible(show_texture && !show_media);
+ getChildView("label maskcutoff")->setVisible(false);
+ getChildView("maskcutoff")->setVisible(false);
+ if (show_texture && !show_media)
+ {
+ updateAlphaControls();
+ }
+ getChildView("TexScaleU")->setVisible(show_texture);
+ getChildView("TexScaleV")->setVisible(show_texture);
+ getChildView("TexRot")->setVisible(show_texture);
+ getChildView("TexOffsetU")->setVisible(show_texture);
+ getChildView("TexOffsetV")->setVisible(show_texture);
+
+ // Specular map controls
+ getChildView("shinytexture control")->setVisible(show_shininess);
+ getChildView("combobox shininess")->setVisible(show_shininess);
+ getChildView("label shininess")->setVisible(show_shininess);
+ getChildView("label glossiness")->setVisible(false);
+ getChildView("glossiness")->setVisible(false);
+ getChildView("label environment")->setVisible(false);
+ getChildView("environment")->setVisible(false);
+ getChildView("label shinycolor")->setVisible(false);
+ getChildView("shinycolorswatch")->setVisible(false);
+ if (show_shininess)
+ {
+ updateShinyControls();
+ }
+ getChildView("shinyScaleU")->setVisible(show_shininess);
+ getChildView("shinyScaleV")->setVisible(show_shininess);
+ getChildView("shinyRot")->setVisible(show_shininess);
+ getChildView("shinyOffsetU")->setVisible(show_shininess);
+ getChildView("shinyOffsetV")->setVisible(show_shininess);
+
+ // Normal map controls
+ if (show_bumpiness)
+ {
+ updateBumpyControls();
+ }
+ getChildView("bumpytexture control")->setVisible(show_bumpiness);
+ getChildView("combobox bumpiness")->setVisible(show_bumpiness);
+ getChildView("label bumpiness")->setVisible(show_bumpiness);
+ getChildView("bumpyScaleU")->setVisible(show_bumpiness);
+ getChildView("bumpyScaleV")->setVisible(show_bumpiness);
+ getChildView("bumpyRot")->setVisible(show_bumpiness);
+ getChildView("bumpyOffsetU")->setVisible(show_bumpiness);
+ getChildView("bumpyOffsetV")->setVisible(show_bumpiness);
+
+
+}
+
+// static
+void LLPanelFace::onCommitMaterialType(LLUICtrl* ctrl, void* userdata)
+{
+ LLPanelFace* self = (LLPanelFace*) userdata;
+ // Force to default states to side-step problems with menu contents
+ // and generally reflecting old state when switching tabs or objects
+ //
+ self->updateShinyControls(false,true);
+ self->updateBumpyControls(false,true);
+ self->updateUI();
+}
+
+// static
void LLPanelFace::onCommitBump(LLUICtrl* ctrl, void* userdata)
{
LLPanelFace* self = (LLPanelFace*) userdata;
- self->sendBump();
+
+ LLComboBox* mComboBumpiness = self->getChild<LLComboBox>("combobox bumpiness");
+ if(!mComboBumpiness)
+ return;
+
+ U32 bumpiness = mComboBumpiness->getCurrentIndex();
+
+ self->sendBump(bumpiness);
}
// static
@@ -1045,10 +1596,143 @@ void LLPanelFace::onCommitTexGen(LLUICtrl* ctrl, void* userdata)
}
// static
+void LLPanelFace::updateShinyControls(bool is_setting_texture, bool mess_with_shiny_combobox)
+{
+ LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>("shinytexture control");
+ LLUUID shiny_texture_ID = texture_ctrl->getImageAssetID();
+ LL_DEBUGS("Materials") << "Shiny texture selected: " << shiny_texture_ID << LL_ENDL;
+ LLComboBox* comboShiny = getChild<LLComboBox>("combobox shininess");
+
+ if(mess_with_shiny_combobox)
+ {
+ if (!comboShiny)
+ {
+ return;
+ }
+ if (!shiny_texture_ID.isNull() && is_setting_texture)
+ {
+ if (!comboShiny->itemExists(USE_TEXTURE))
+ {
+ comboShiny->add(USE_TEXTURE);
+ }
+ comboShiny->setSimple(USE_TEXTURE);
+ }
+ else
+ {
+ if (comboShiny->itemExists(USE_TEXTURE))
+ {
+ comboShiny->remove(SHINY_TEXTURE);
+ comboShiny->selectFirstItem();
+ }
+ }
+ }
+
+ LLComboBox* combo_matmedia = getChild<LLComboBox>("combobox matmedia");
+ LLComboBox* combo_mattype = getChild<LLComboBox>("combobox mattype");
+ U32 materials_media = combo_matmedia->getCurrentIndex();
+ U32 material_type = combo_mattype->getCurrentIndex();
+ bool show_media = (materials_media == MATMEDIA_MEDIA) && combo_matmedia->getEnabled();
+ bool show_shininess = (!show_media) && (material_type == MATTYPE_SPECULAR) && combo_matmedia->getEnabled();
+ U32 shiny_value = comboShiny->getCurrentIndex();
+ bool show_shinyctrls = (shiny_value == SHINY_TEXTURE) && show_shininess; // Use texture
+ getChildView("label glossiness")->setVisible(show_shinyctrls);
+ getChildView("glossiness")->setVisible(show_shinyctrls);
+ getChildView("label environment")->setVisible(show_shinyctrls);
+ getChildView("environment")->setVisible(show_shinyctrls);
+ getChildView("label shinycolor")->setVisible(show_shinyctrls);
+ getChildView("shinycolorswatch")->setVisible(show_shinyctrls);
+}
+
+// static
+void LLPanelFace::updateBumpyControls(bool is_setting_texture, bool mess_with_combobox)
+{
+ LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>("bumpytexture control");
+ LLUUID bumpy_texture_ID = texture_ctrl->getImageAssetID();
+ LL_DEBUGS("Materials") << "texture: " << bumpy_texture_ID << (mess_with_combobox ? "" : " do not") << " update combobox" << LL_ENDL;
+ LLComboBox* comboBumpy = getChild<LLComboBox>("combobox bumpiness");
+ if (!comboBumpy)
+ {
+ return;
+ }
+
+ if (mess_with_combobox)
+ {
+ LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>("bumpytexture control");
+ LLUUID bumpy_texture_ID = texture_ctrl->getImageAssetID();
+ LL_DEBUGS("Materials") << "texture: " << bumpy_texture_ID << (mess_with_combobox ? "" : " do not") << " update combobox" << LL_ENDL;
+
+ if (!bumpy_texture_ID.isNull() && is_setting_texture)
+ {
+ if (!comboBumpy->itemExists(USE_TEXTURE))
+ {
+ comboBumpy->add(USE_TEXTURE);
+ }
+ comboBumpy->setSimple(USE_TEXTURE);
+ }
+ else
+ {
+ if (comboBumpy->itemExists(USE_TEXTURE))
+ {
+ comboBumpy->remove(BUMPY_TEXTURE);
+ comboBumpy->selectFirstItem();
+ }
+ }
+ }
+}
+
+// static
void LLPanelFace::onCommitShiny(LLUICtrl* ctrl, void* userdata)
{
LLPanelFace* self = (LLPanelFace*) userdata;
- self->sendShiny();
+
+
+ LLComboBox* mComboShininess = self->getChild<LLComboBox>("combobox shininess");
+ if(!mComboShininess)
+ return;
+
+ U32 shininess = mComboShininess->getCurrentIndex();
+
+ self->sendShiny(shininess);
+}
+
+// static
+void LLPanelFace::updateAlphaControls()
+{
+ LLComboBox* comboAlphaMode = getChild<LLComboBox>("combobox alphamode");
+ if (!comboAlphaMode)
+ {
+ return;
+ }
+ U32 alpha_value = comboAlphaMode->getCurrentIndex();
+ bool show_alphactrls = (alpha_value == ALPHAMODE_MASK); // Alpha masking
+
+ LLComboBox* combobox_matmedia = getChild<LLComboBox>("combobox matmedia");
+ U32 mat_media = MATMEDIA_MATERIAL;
+ if (combobox_matmedia)
+ {
+ mat_media = combobox_matmedia->getCurrentIndex();
+ }
+
+ LLComboBox* combobox_mattype = getChild<LLComboBox>("combobox mattype");
+ U32 mat_type = MATTYPE_DIFFUSE;
+ if (combobox_mattype)
+ {
+ mat_type = combobox_mattype->getCurrentIndex();
+ }
+
+ show_alphactrls = show_alphactrls && (mat_media == MATMEDIA_MATERIAL);
+ show_alphactrls = show_alphactrls && (mat_type == MATTYPE_DIFFUSE);
+
+ getChildView("label maskcutoff")->setVisible(show_alphactrls);
+ getChildView("maskcutoff")->setVisible(show_alphactrls);
+}
+
+// static
+void LLPanelFace::onCommitAlphaMode(LLUICtrl* ctrl, void* userdata)
+{
+ LLPanelFace* self = (LLPanelFace*) userdata;
+ self->updateAlphaControls();
+ LLSelectedTEMaterial::setDiffuseAlphaMode(self,self->getCurrentDiffuseAlphaMode());
}
// static
@@ -1098,8 +1782,211 @@ void LLPanelFace::onSelectTexture(const LLSD& data)
{
LLSelectMgr::getInstance()->saveSelectedObjectTextures();
sendTexture();
+
+ LLGLenum image_format;
+ bool identical_image_format = false;
+ LLSelectedTE::getImageFormat(image_format, identical_image_format);
+
+ LLCtrlSelectionInterface* combobox_alphamode =
+ childGetSelectionInterface("combobox alphamode");
+
+ U32 alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_NONE;
+ if (combobox_alphamode)
+ {
+ switch (image_format)
+ {
+ case GL_RGBA:
+ case GL_ALPHA:
+ {
+ alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_BLEND;
+ }
+ break;
+
+ case GL_RGB: break;
+ default:
+ {
+ llwarns << "Unexpected tex format in LLPanelFace...resorting to no alpha" << llendl;
+ }
+ break;
+ }
+
+ combobox_alphamode->selectNthItem(alpha_mode);
+ }
+ LLSelectedTEMaterial::setDiffuseAlphaMode(this, getCurrentDiffuseAlphaMode());
+}
+
+void LLPanelFace::onCloseTexturePicker(const LLSD& data)
+{
+ LL_DEBUGS("Materials") << data << LL_ENDL;
+ updateUI();
+}
+
+void LLPanelFace::onCommitSpecularTexture( const LLSD& data )
+{
+ LL_DEBUGS("Materials") << data << LL_ENDL;
+ sendShiny(SHINY_TEXTURE);
+}
+
+void LLPanelFace::onCommitNormalTexture( const LLSD& data )
+{
+ LL_DEBUGS("Materials") << data << LL_ENDL;
+ LLUUID nmap_id = getCurrentNormalMap();
+ sendBump(nmap_id.isNull() ? 0 : BUMPY_TEXTURE);
+}
+
+void LLPanelFace::onCancelSpecularTexture(const LLSD& data)
+{
+ U8 shiny = 0;
+ bool identical_shiny = false;
+ LLSelectedTE::getShiny(shiny, identical_shiny);
+ LLUUID spec_map_id = getChild<LLTextureCtrl>("shinytexture control")->getImageAssetID();
+ shiny = spec_map_id.isNull() ? shiny : SHINY_TEXTURE;
+ sendShiny(shiny);
+}
+
+void LLPanelFace::onCancelNormalTexture(const LLSD& data)
+{
+ U8 bumpy = 0;
+ bool identical_bumpy = false;
+ LLSelectedTE::getBumpmap(bumpy, identical_bumpy);
+ sendBump(bumpy);
+}
+
+void LLPanelFace::onSelectSpecularTexture(const LLSD& data)
+{
+ LL_DEBUGS("Materials") << data << LL_ENDL;
+ sendShiny(SHINY_TEXTURE);
}
+void LLPanelFace::onSelectNormalTexture(const LLSD& data)
+{
+ LL_DEBUGS("Materials") << data << LL_ENDL;
+ LLUUID nmap_id = getCurrentNormalMap();
+ sendBump(nmap_id.isNull() ? 0 : BUMPY_TEXTURE);
+}
+
+//static
+void LLPanelFace::onCommitMaterialBumpyOffsetX(LLUICtrl* ctrl, void* userdata)
+{
+ LLPanelFace* self = (LLPanelFace*) userdata;
+ llassert_always(self);
+ LLSelectedTEMaterial::setNormalOffsetX(self,self->getCurrentBumpyOffsetU());
+}
+
+//static
+void LLPanelFace::onCommitMaterialBumpyOffsetY(LLUICtrl* ctrl, void* userdata)
+{
+ LLPanelFace* self = (LLPanelFace*) userdata;
+ llassert_always(self);
+ LLSelectedTEMaterial::setNormalOffsetY(self,self->getCurrentBumpyOffsetV());
+}
+
+//static
+void LLPanelFace::onCommitMaterialShinyOffsetX(LLUICtrl* ctrl, void* userdata)
+{
+ LLPanelFace* self = (LLPanelFace*) userdata;
+ llassert_always(self);
+ LLSelectedTEMaterial::setSpecularOffsetX(self,self->getCurrentShinyOffsetU());
+}
+
+//static
+void LLPanelFace::onCommitMaterialShinyOffsetY(LLUICtrl* ctrl, void* userdata)
+{
+ LLPanelFace* self = (LLPanelFace*) userdata;
+ llassert_always(self);
+ LLSelectedTEMaterial::setSpecularOffsetY(self,self->getCurrentShinyOffsetV());
+}
+
+//static
+void LLPanelFace::onCommitMaterialBumpyScaleX(LLUICtrl* ctrl, void* userdata)
+{
+ LLPanelFace* self = (LLPanelFace*) userdata;
+ llassert_always(self);
+ F32 bumpy_scale_u = self->getCurrentBumpyScaleU();
+ if (self->isIdenticalPlanarTexgen())
+ {
+ bumpy_scale_u *= 0.5f;
+ }
+ LLSelectedTEMaterial::setNormalRepeatX(self,bumpy_scale_u);
+}
+
+//static
+void LLPanelFace::onCommitMaterialBumpyScaleY(LLUICtrl* ctrl, void* userdata)
+{
+ LLPanelFace* self = (LLPanelFace*) userdata;
+ llassert_always(self);
+ F32 bumpy_scale_v = self->getCurrentBumpyScaleV();
+ if (self->isIdenticalPlanarTexgen())
+ {
+ bumpy_scale_v *= 0.5f;
+ }
+ LLSelectedTEMaterial::setNormalRepeatY(self,bumpy_scale_v);
+}
+
+//static
+void LLPanelFace::onCommitMaterialShinyScaleX(LLUICtrl* ctrl, void* userdata)
+{
+ LLPanelFace* self = (LLPanelFace*) userdata;
+ llassert_always(self);
+ F32 shiny_scale_u = self->getCurrentShinyScaleU();
+ if (self->isIdenticalPlanarTexgen())
+ {
+ shiny_scale_u *= 0.5f;
+ }
+ LLSelectedTEMaterial::setSpecularRepeatX(self,shiny_scale_u);
+}
+
+//static
+void LLPanelFace::onCommitMaterialShinyScaleY(LLUICtrl* ctrl, void* userdata)
+{
+ LLPanelFace* self = (LLPanelFace*) userdata;
+ llassert_always(self);
+ F32 shiny_scale_v = self->getCurrentShinyScaleV();
+ if (self->isIdenticalPlanarTexgen())
+ {
+ shiny_scale_v *= 0.5f;
+ }
+ LLSelectedTEMaterial::setSpecularRepeatY(self,shiny_scale_v);
+}
+
+//static
+void LLPanelFace::onCommitMaterialBumpyRot(LLUICtrl* ctrl, void* userdata)
+{
+ LLPanelFace* self = (LLPanelFace*) userdata;
+ llassert_always(self);
+ LLSelectedTEMaterial::setNormalRotation(self,self->getCurrentBumpyRot() * DEG_TO_RAD);
+}
+
+//static
+void LLPanelFace::onCommitMaterialShinyRot(LLUICtrl* ctrl, void* userdata)
+{
+ LLPanelFace* self = (LLPanelFace*) userdata;
+ llassert_always(self);
+ LLSelectedTEMaterial::setSpecularRotation(self,self->getCurrentShinyRot() * DEG_TO_RAD);
+}
+
+//static
+void LLPanelFace::onCommitMaterialGloss(LLUICtrl* ctrl, void* userdata)
+{
+ LLPanelFace* self = (LLPanelFace*) userdata;
+ llassert_always(self);
+ LLSelectedTEMaterial::setSpecularLightExponent(self,self->getCurrentGlossiness());
+}
+
+//static
+void LLPanelFace::onCommitMaterialEnv(LLUICtrl* ctrl, void* userdata)
+{
+ LLPanelFace* self = (LLPanelFace*) userdata;
+ llassert_always(self);
+ LLSelectedTEMaterial::setEnvironmentIntensity(self,self->getCurrentEnvIntensity());
+}
+
+//static
+void LLPanelFace::onCommitMaterialMaskCutoff(LLUICtrl* ctrl, void* userdata)
+{
+ LLPanelFace* self = (LLPanelFace*) userdata;
+ LLSelectedTEMaterial::setAlphaMaskCutoff(self,self->getCurrentAlphaMaskCutoff());
+}
// static
void LLPanelFace::onCommitTextureInfo( LLUICtrl* ctrl, void* userdata )
@@ -1110,15 +1997,67 @@ void LLPanelFace::onCommitTextureInfo( LLUICtrl* ctrl, void* userdata )
// Commit the number of repeats per meter
// static
-void LLPanelFace::onClickApply(void* userdata)
+void LLPanelFace::onCommitRepeatsPerMeter(LLUICtrl* ctrl, void* userdata)
{
LLPanelFace* self = (LLPanelFace*) userdata;
- gFocusMgr.setKeyboardFocus( NULL );
+ LLUICtrl* repeats_ctrl = self->getChild<LLUICtrl>("rptctrl");
+ LLComboBox* combo_matmedia = self->getChild<LLComboBox>("combobox matmedia");
+ LLComboBox* combo_mattype = self->getChild<LLComboBox>("combobox mattype");
+
+ U32 materials_media = combo_matmedia->getCurrentIndex();
+
+
+ U32 material_type = (materials_media == MATMEDIA_MATERIAL) ? combo_mattype->getCurrentIndex() : 0;
+ F32 repeats_per_meter = repeats_ctrl->getValue().asReal();
+
+ F32 obj_scale_s = 1.0f;
+ F32 obj_scale_t = 1.0f;
- //F32 repeats_per_meter = self->mCtrlRepeatsPerMeter->get();
- F32 repeats_per_meter = (F32)self->getChild<LLUICtrl>("rptctrl")->getValue().asReal();//self->mCtrlRepeatsPerMeter->get();
- LLSelectMgr::getInstance()->selectionTexScaleAutofit( repeats_per_meter );
+ bool identical_scale_s = false;
+ bool identical_scale_t = false;
+
+ LLSelectedTE::getObjectScaleS(obj_scale_s, identical_scale_s);
+ LLSelectedTE::getObjectScaleS(obj_scale_t, identical_scale_t);
+
+ switch (material_type)
+ {
+ case MATTYPE_DIFFUSE:
+ {
+ LLSelectMgr::getInstance()->selectionTexScaleAutofit( repeats_per_meter );
+ }
+ break;
+
+ case MATTYPE_NORMAL:
+ {
+ LLUICtrl* bumpy_scale_u = self->getChild<LLUICtrl>("bumpyScaleU");
+ LLUICtrl* bumpy_scale_v = self->getChild<LLUICtrl>("bumpyScaleV");
+
+ bumpy_scale_u->setValue(obj_scale_s * repeats_per_meter);
+ bumpy_scale_v->setValue(obj_scale_t * repeats_per_meter);
+
+ LLSelectedTEMaterial::setNormalRepeatX(self,obj_scale_s * repeats_per_meter);
+ LLSelectedTEMaterial::setNormalRepeatY(self,obj_scale_t * repeats_per_meter);
+ }
+ break;
+
+ case MATTYPE_SPECULAR:
+ {
+ LLUICtrl* shiny_scale_u = self->getChild<LLUICtrl>("shinyScaleU");
+ LLUICtrl* shiny_scale_v = self->getChild<LLUICtrl>("shinyScaleV");
+
+ shiny_scale_u->setValue(obj_scale_s * repeats_per_meter);
+ shiny_scale_v->setValue(obj_scale_t * repeats_per_meter);
+
+ LLSelectedTEMaterial::setSpecularRepeatX(self,obj_scale_s * repeats_per_meter);
+ LLSelectedTEMaterial::setSpecularRepeatY(self,obj_scale_t * repeats_per_meter);
+ }
+ break;
+
+ default:
+ llassert(false);
+ break;
+ }
}
struct LLPanelFaceSetMediaFunctor : public LLSelectedTEFunctor
@@ -1190,3 +2129,263 @@ void LLPanelFace::onCommitPlanarAlign(LLUICtrl* ctrl, void* userdata)
self->sendTextureInfo();
}
+void LLPanelFace::onTextureSelectionChanged(LLInventoryItem* itemp)
+{
+ LL_DEBUGS("Materials") << "item asset " << itemp->getAssetUUID() << LL_ENDL;
+ LLComboBox* combo_mattype = getChild<LLComboBox>("combobox mattype");
+ if (!combo_mattype)
+ {
+ return;
+ }
+ U32 mattype = combo_mattype->getCurrentIndex();
+ std::string which_control="texture control";
+ switch (mattype)
+ {
+ case MATTYPE_SPECULAR:
+ which_control = "shinytexture control";
+ break;
+ case MATTYPE_NORMAL:
+ which_control = "bumpytexture control";
+ break;
+ // no default needed
+ }
+ LL_DEBUGS("Materials") << "control " << which_control << LL_ENDL;
+ LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>(which_control);
+ if (texture_ctrl)
+ {
+ LLUUID obj_owner_id;
+ std::string obj_owner_name;
+ LLSelectMgr::instance().selectGetOwner(obj_owner_id, obj_owner_name);
+
+ LLSaleInfo sale_info;
+ LLSelectMgr::instance().selectGetSaleInfo(sale_info);
+
+ bool can_copy = itemp->getPermissions().allowCopyBy(gAgentID); // do we have perm to copy this texture?
+ bool can_transfer = itemp->getPermissions().allowOperationBy(PERM_TRANSFER, gAgentID); // do we have perm to transfer this texture?
+ bool is_object_owner = gAgentID == obj_owner_id; // does object for which we are going to apply texture belong to the agent?
+ bool not_for_sale = !sale_info.isForSale(); // is object for which we are going to apply texture not for sale?
+
+ if (can_copy && can_transfer)
+ {
+ texture_ctrl->setCanApply(true, true);
+ return;
+ }
+
+ // if texture has (no-transfer) attribute it can be applied only for object which we own and is not for sale
+ texture_ctrl->setCanApply(false, can_transfer ? true : is_object_owner && not_for_sale);
+
+ if (gSavedSettings.getBOOL("TextureLivePreview"))
+ {
+ LLNotificationsUtil::add("LivePreviewUnavailable");
+ }
+ }
+}
+
+bool LLPanelFace::isIdenticalPlanarTexgen()
+{
+ LLTextureEntry::e_texgen selected_texgen = LLTextureEntry::TEX_GEN_DEFAULT;
+ bool identical_texgen = false;
+ LLSelectedTE::getTexGen(selected_texgen, identical_texgen);
+ return (identical_texgen && (selected_texgen == LLTextureEntry::TEX_GEN_PLANAR));
+}
+
+void LLPanelFace::LLSelectedTE::getFace(LLFace*& face_to_return, bool& identical_face)
+{
+ struct LLSelectedTEGetFace : public LLSelectedTEGetFunctor<LLFace *>
+ {
+ LLFace* get(LLViewerObject* object, S32 te)
+ {
+ return (object->mDrawable) ? object->mDrawable->getFace(te): NULL;
+ }
+ } get_te_face_func;
+ identical_face = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&get_te_face_func, face_to_return);
+}
+
+void LLPanelFace::LLSelectedTE::getImageFormat(LLGLenum& image_format_to_return, bool& identical_face)
+{
+ LLGLenum image_format;
+ struct LLSelectedTEGetImageFormat : public LLSelectedTEGetFunctor<LLGLenum>
+ {
+ LLGLenum get(LLViewerObject* object, S32 te_index)
+ {
+ LLViewerTexture* image = object->getTEImage(te_index);
+ return image ? image->getPrimaryFormat() : GL_RGB;
+ }
+ } get_glenum;
+ identical_face = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&get_glenum, image_format);
+ image_format_to_return = image_format;
+}
+
+void LLPanelFace::LLSelectedTE::getTexId(LLUUID& id, bool& identical)
+{
+ struct LLSelectedTEGetTexId : public LLSelectedTEGetFunctor<LLUUID>
+ {
+ LLUUID get(LLViewerObject* object, S32 te_index)
+ {
+ LLUUID id;
+ LLViewerTexture* image = object->getTEImage(te_index);
+ if (image)
+ {
+ id = image->getID();
+ }
+
+ if (!id.isNull() && LLViewerMedia::textureHasMedia(id))
+ {
+ LLTextureEntry *te = object->getTE(te_index);
+ if (te)
+ {
+ LLViewerTexture* tex = te->getID().notNull() ? gTextureList.findImage(te->getID()) : NULL;
+ if(!tex)
+ {
+ tex = LLViewerFetchedTexture::sDefaultImagep;
+ }
+ if (tex)
+ {
+ id = tex->getID();
+ }
+ }
+ }
+ return id;
+ }
+ } func;
+ identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, id );
+}
+
+void LLPanelFace::LLSelectedTEMaterial::getCurrent(LLMaterialPtr& material_ptr, bool& identical_material)
+{
+ struct MaterialFunctor : public LLSelectedTEGetFunctor<LLMaterialPtr>
+ {
+ LLMaterialPtr get(LLViewerObject* object, S32 te_index)
+ {
+ return object->getTE(te_index)->getMaterialParams();
+ }
+ } func;
+ identical_material = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, material_ptr);
+}
+
+void LLPanelFace::LLSelectedTEMaterial::getMaxSpecularRepeats(F32& repeats, bool& identical)
+{
+ struct LLSelectedTEGetMaxSpecRepeats : public LLSelectedTEGetFunctor<F32>
+ {
+ F32 get(LLViewerObject* object, S32 face)
+ {
+ LLMaterial* mat = object->getTE(face)->getMaterialParams().get();
+ U32 s_axis = VX;
+ U32 t_axis = VY;
+ F32 repeats_s = 1.0f;
+ F32 repeats_t = 1.0f;
+ if (mat)
+ {
+ mat->getSpecularRepeat(repeats_s, repeats_t);
+ repeats_s /= object->getScale().mV[s_axis];
+ repeats_t /= object->getScale().mV[t_axis];
+ }
+ return llmax(repeats_s, repeats_t);
+ }
+
+ } max_spec_repeats_func;
+ identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &max_spec_repeats_func, repeats);
+}
+
+void LLPanelFace::LLSelectedTEMaterial::getMaxNormalRepeats(F32& repeats, bool& identical)
+{
+ struct LLSelectedTEGetMaxNormRepeats : public LLSelectedTEGetFunctor<F32>
+ {
+ F32 get(LLViewerObject* object, S32 face)
+ {
+ LLMaterial* mat = object->getTE(face)->getMaterialParams().get();
+ U32 s_axis = VX;
+ U32 t_axis = VY;
+ F32 repeats_s = 1.0f;
+ F32 repeats_t = 1.0f;
+ if (mat)
+ {
+ mat->getNormalRepeat(repeats_s, repeats_t);
+ repeats_s /= object->getScale().mV[s_axis];
+ repeats_t /= object->getScale().mV[t_axis];
+ }
+ return llmax(repeats_s, repeats_t);
+ }
+
+ } max_norm_repeats_func;
+ identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &max_norm_repeats_func, repeats);
+}
+
+void LLPanelFace::LLSelectedTEMaterial::getCurrentDiffuseAlphaMode(U8& diffuse_alpha_mode, bool& identical, bool diffuse_texture_has_alpha)
+{
+ struct LLSelectedTEGetDiffuseAlphaMode : public LLSelectedTEGetFunctor<U8>
+ {
+ LLSelectedTEGetDiffuseAlphaMode() : _isAlpha(false) {}
+ LLSelectedTEGetDiffuseAlphaMode(bool diffuse_texture_has_alpha) : _isAlpha(diffuse_texture_has_alpha) {}
+ virtual ~LLSelectedTEGetDiffuseAlphaMode() {}
+
+ U8 get(LLViewerObject* object, S32 face)
+ {
+ U8 diffuse_mode = _isAlpha ? LLMaterial::DIFFUSE_ALPHA_MODE_BLEND : LLMaterial::DIFFUSE_ALPHA_MODE_NONE;
+
+ LLTextureEntry* tep = object->getTE(face);
+ if (tep)
+ {
+ LLMaterial* mat = tep->getMaterialParams().get();
+ if (mat)
+ {
+ diffuse_mode = mat->getDiffuseAlphaMode();
+ }
+ }
+
+ return diffuse_mode;
+ }
+ bool _isAlpha; // whether or not the diffuse texture selected contains alpha information
+ } get_diff_mode(diffuse_texture_has_alpha);
+ identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &get_diff_mode, diffuse_alpha_mode);
+}
+
+void LLPanelFace::LLSelectedTE::getObjectScaleS(F32& scale_s, bool& identical)
+{
+ struct LLSelectedTEGetObjectScaleS : public LLSelectedTEGetFunctor<F32>
+ {
+ F32 get(LLViewerObject* object, S32 face)
+ {
+ U32 s_axis = VX;
+ U32 t_axis = VY;
+ LLPrimitive::getTESTAxes(face, &s_axis, &t_axis);
+ return object->getScale().mV[s_axis];
+ }
+
+ } scale_s_func;
+ identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &scale_s_func, scale_s );
+}
+
+void LLPanelFace::LLSelectedTE::getObjectScaleT(F32& scale_t, bool& identical)
+{
+ struct LLSelectedTEGetObjectScaleS : public LLSelectedTEGetFunctor<F32>
+ {
+ F32 get(LLViewerObject* object, S32 face)
+ {
+ U32 s_axis = VX;
+ U32 t_axis = VY;
+ LLPrimitive::getTESTAxes(face, &s_axis, &t_axis);
+ return object->getScale().mV[t_axis];
+ }
+
+ } scale_t_func;
+ identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &scale_t_func, scale_t );
+}
+
+void LLPanelFace::LLSelectedTE::getMaxDiffuseRepeats(F32& repeats, bool& identical)
+{
+ struct LLSelectedTEGetMaxDiffuseRepeats : public LLSelectedTEGetFunctor<F32>
+ {
+ F32 get(LLViewerObject* object, S32 face)
+ {
+ U32 s_axis = VX;
+ U32 t_axis = VY;
+ LLPrimitive::getTESTAxes(face, &s_axis, &t_axis);
+ F32 repeats_s = object->getTE(face)->mScaleS / object->getScale().mV[s_axis];
+ F32 repeats_t = object->getTE(face)->mScaleT / object->getScale().mV[t_axis];
+ return llmax(repeats_s, repeats_t);
+ }
+
+ } max_diff_repeats_func;
+ identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &max_diff_repeats_func, repeats );
+}
diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h
index 42be9b257f..b684881225 100644..100755
--- a/indra/newview/llpanelface.h
+++ b/indra/newview/llpanelface.h
@@ -29,6 +29,10 @@
#include "v4color.h"
#include "llpanel.h"
+#include "llmaterial.h"
+#include "llmaterialmgr.h"
+#include "lltextureentry.h"
+#include "llselectmgr.h"
class LLButton;
class LLCheckBoxCtrl;
@@ -42,6 +46,48 @@ class LLTextureCtrl;
class LLUICtrl;
class LLViewerObject;
class LLFloater;
+class LLMaterialID;
+
+// Represents an edit for use in replicating the op across one or more materials in the selection set.
+//
+// The apply function optionally performs the edit which it implements
+// as a functor taking Data that calls member func MaterialFunc taking SetValueType
+// on an instance of the LLMaterial class.
+//
+// boost who?
+//
+template<
+ typename DataType,
+ typename SetValueType,
+ void (LLMaterial::*MaterialEditFunc)(SetValueType data) >
+class LLMaterialEditFunctor
+{
+public:
+ LLMaterialEditFunctor(const DataType& data) : _data(data) {}
+ virtual ~LLMaterialEditFunctor() {}
+ virtual void apply(LLMaterialPtr& material) { (material->*(MaterialEditFunc))(_data); }
+ DataType _data;
+};
+
+template<
+ typename DataType,
+ DataType (LLMaterial::*MaterialGetFunc)() >
+class LLMaterialGetFunctor
+{
+public:
+ LLMaterialGetFunctor() {}
+ virtual DataType get(LLMaterialPtr& material) { return (material->*(MaterialGetFunc)); }
+};
+
+template<
+ typename DataType,
+ DataType (LLTextureEntry::*TEGetFunc)() >
+class LLTEGetFunctor
+{
+public:
+ LLTEGetFunctor() {}
+ virtual DataType get(LLTextureEntry* entry) { return (entry*(TEGetFunc)); }
+};
class LLPanelFace : public LLPanel
{
@@ -54,6 +100,19 @@ public:
void setMediaURL(const std::string& url);
void setMediaType(const std::string& mime_type);
+ LLMaterialPtr createDefaultMaterial(LLMaterialPtr current_material)
+ {
+ LLMaterialPtr new_material(!current_material.isNull() ? new LLMaterial(current_material->asLLSD()) : new LLMaterial());
+ llassert_always(new_material);
+
+ // Preserve old diffuse alpha mode or assert correct default blend mode as appropriate for the alpha channel content of the diffuse texture
+ //
+ new_material->setDiffuseAlphaMode(current_material.isNull() ? (isAlpha() ? LLMaterial::DIFFUSE_ALPHA_MODE_BLEND : LLMaterial::DIFFUSE_ALPHA_MODE_NONE) : current_material->getDiffuseAlphaMode());
+ return new_material;
+ }
+
+ LLRender::eTexIndex getTextureChannelToEdit();
+
protected:
void getState();
@@ -61,11 +120,11 @@ protected:
void sendTextureInfo(); // applies and sends texture scale, offset, etc.
void sendColor(); // applies and sends color
void sendAlpha(); // applies and sends transparency
- void sendBump(); // applies and sends bump map
+ void sendBump(U32 bumpiness); // applies and sends bump map
void sendTexGen(); // applies and sends bump map
- void sendShiny(); // applies and sends shininess
+ void sendShiny(U32 shininess); // applies and sends shininess
void sendFullbright(); // applies and sends full bright
- void sendGlow();
+ void sendGlow();
void sendMedia();
// this function is to return TRUE if the drag should succeed.
@@ -74,23 +133,378 @@ protected:
void onCommitTexture(const LLSD& data);
void onCancelTexture(const LLSD& data);
void onSelectTexture(const LLSD& data);
+ void onCommitSpecularTexture(const LLSD& data);
+ void onCancelSpecularTexture(const LLSD& data);
+ void onSelectSpecularTexture(const LLSD& data);
+ void onCommitNormalTexture(const LLSD& data);
+ void onCancelNormalTexture(const LLSD& data);
+ void onSelectNormalTexture(const LLSD& data);
void onCommitColor(const LLSD& data);
+ void onCommitShinyColor(const LLSD& data);
void onCommitAlpha(const LLSD& data);
void onCancelColor(const LLSD& data);
void onSelectColor(const LLSD& data);
-
- static void onCommitTextureInfo( LLUICtrl* ctrl, void* userdata);
- static void onCommitBump( LLUICtrl* ctrl, void* userdata);
+
+ void onCloseTexturePicker(const LLSD& data);
+
+ // Make UI reflect state of currently selected material (refresh)
+ // and UI mode (e.g. editing normal map v diffuse map)
+ //
+ void updateUI();
+
+ // Convenience func to determine if all faces in selection have
+ // identical planar texgen settings during edits
+ //
+ bool isIdenticalPlanarTexgen();
+
+ // Callback funcs for individual controls
+ //
+ static void onCommitTextureInfo( LLUICtrl* ctrl, void* userdata);
+
+ static void onCommitMaterialBumpyScaleX( LLUICtrl* ctrl, void* userdata);
+ static void onCommitMaterialBumpyScaleY( LLUICtrl* ctrl, void* userdata);
+ static void onCommitMaterialBumpyRot( LLUICtrl* ctrl, void* userdata);
+ static void onCommitMaterialBumpyOffsetX( LLUICtrl* ctrl, void* userdata);
+ static void onCommitMaterialBumpyOffsetY( LLUICtrl* ctrl, void* userdata);
+
+ static void onCommitMaterialShinyScaleX( LLUICtrl* ctrl, void* userdata);
+ static void onCommitMaterialShinyScaleY( LLUICtrl* ctrl, void* userdata);
+ static void onCommitMaterialShinyRot( LLUICtrl* ctrl, void* userdata);
+ static void onCommitMaterialShinyOffsetX( LLUICtrl* ctrl, void* userdata);
+ static void onCommitMaterialShinyOffsetY( LLUICtrl* ctrl, void* userdata);
+
+ static void onCommitMaterialGloss( LLUICtrl* ctrl, void* userdata);
+ static void onCommitMaterialEnv( LLUICtrl* ctrl, void* userdata);
+ static void onCommitMaterialMaskCutoff( LLUICtrl* ctrl, void* userdata);
+
+ static void onCommitMaterialsMedia( LLUICtrl* ctrl, void* userdata);
+ static void onCommitMaterialType( LLUICtrl* ctrl, void* userdata);
+ static void onCommitBump( LLUICtrl* ctrl, void* userdata);
static void onCommitTexGen( LLUICtrl* ctrl, void* userdata);
- static void onCommitShiny( LLUICtrl* ctrl, void* userdata);
+ static void onCommitShiny( LLUICtrl* ctrl, void* userdata);
+ static void onCommitAlphaMode( LLUICtrl* ctrl, void* userdata);
static void onCommitFullbright( LLUICtrl* ctrl, void* userdata);
- static void onCommitGlow( LLUICtrl* ctrl, void *userdata);
- static void onCommitPlanarAlign( LLUICtrl* ctrl, void* userdata);
-
- static void onClickApply(void*);
+ static void onCommitGlow( LLUICtrl* ctrl, void *userdata);
+ static void onCommitPlanarAlign( LLUICtrl* ctrl, void* userdata);
+ static void onCommitRepeatsPerMeter( LLUICtrl* ctrl, void* userinfo);
static void onClickAutoFix(void*);
- static F32 valueGlow(LLViewerObject* object, S32 face);
+ static F32 valueGlow(LLViewerObject* object, S32 face);
+
+
+
+private:
+
+ bool isAlpha() { return mIsAlpha; }
+
+ // Convenience funcs to keep the visual flack to a minimum
+ //
+ LLUUID getCurrentNormalMap();
+ LLUUID getCurrentSpecularMap();
+ U32 getCurrentShininess();
+ U32 getCurrentBumpiness();
+ U8 getCurrentDiffuseAlphaMode();
+ U8 getCurrentAlphaMaskCutoff();
+ U8 getCurrentEnvIntensity();
+ U8 getCurrentGlossiness();
+ F32 getCurrentBumpyRot();
+ F32 getCurrentBumpyScaleU();
+ F32 getCurrentBumpyScaleV();
+ F32 getCurrentBumpyOffsetU();
+ F32 getCurrentBumpyOffsetV();
+ F32 getCurrentShinyRot();
+ F32 getCurrentShinyScaleU();
+ F32 getCurrentShinyScaleV();
+ F32 getCurrentShinyOffsetU();
+ F32 getCurrentShinyOffsetV();
+
+ // Update visibility of controls to match current UI mode
+ // (e.g. materials vs media editing)
+ //
+ // Do NOT call updateUI from within this function.
+ //
+ void updateVisibility();
+
+ // Make material(s) reflect current state of UI (apply edit)
+ //
+ void updateMaterial();
+
+ // Hey look everyone, a type-safe alternative to copy and paste! :)
+ //
+
+ // Update material parameters by applying 'edit_func' to selected TEs
+ //
+ template<
+ typename DataType,
+ typename SetValueType,
+ void (LLMaterial::*MaterialEditFunc)(SetValueType data) >
+ static void edit(LLPanelFace* p, DataType data)
+ {
+ LLMaterialEditFunctor< DataType, SetValueType, MaterialEditFunc > edit(data);
+ struct LLSelectedTEEditMaterial : public LLSelectedTEMaterialFunctor
+ {
+ LLSelectedTEEditMaterial(LLPanelFace* panel, LLMaterialEditFunctor< DataType, SetValueType, MaterialEditFunc >* editp) : _panel(panel), _edit(editp) {}
+ virtual ~LLSelectedTEEditMaterial() {};
+ virtual LLMaterialPtr apply(LLViewerObject* object, S32 face, LLTextureEntry* tep, LLMaterialPtr& current_material)
+ {
+ if (_edit)
+ {
+ LLMaterialPtr new_material = _panel->createDefaultMaterial(current_material);
+ llassert_always(new_material);
+
+ // Determine correct alpha mode for current diffuse texture
+ // (i.e. does it have an alpha channel that makes alpha mode useful)
+ //
+ // _panel->isAlpha() "lies" when one face has alpha and the rest do not (NORSPEC-329)
+ // need to get per-face answer to this question for sane alpha mode retention on updates.
+ //
+ bool is_alpha_face = object->isImageAlphaBlended(face);
+
+ // need to keep this original answer for valid comparisons in logic below
+ //
+ U8 original_default_alpha_mode = is_alpha_face ? LLMaterial::DIFFUSE_ALPHA_MODE_BLEND : LLMaterial::DIFFUSE_ALPHA_MODE_NONE;
+
+ U8 default_alpha_mode = original_default_alpha_mode;
+
+ if (!current_material.isNull())
+ {
+ default_alpha_mode = current_material->getDiffuseAlphaMode();
+ }
+
+ // Insure we don't inherit the default of blend by accident...
+ // this will be stomped by a legit request to change the alpha mode by the apply() below
+ //
+ new_material->setDiffuseAlphaMode(default_alpha_mode);
+
+ // Do "It"!
+ //
+ _edit->apply(new_material);
+
+ U32 new_alpha_mode = new_material->getDiffuseAlphaMode();
+ LLUUID new_normal_map_id = new_material->getNormalID();
+ LLUUID new_spec_map_id = new_material->getSpecularID();
+
+ if ((new_alpha_mode == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND) && !is_alpha_face)
+ {
+ new_alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_NONE;
+ new_material->setDiffuseAlphaMode(LLMaterial::DIFFUSE_ALPHA_MODE_NONE);
+ }
+
+ bool is_default_blend_mode = (new_alpha_mode == original_default_alpha_mode);
+ bool is_need_material = !is_default_blend_mode || !new_normal_map_id.isNull() || !new_spec_map_id.isNull();
+
+ if (!is_need_material)
+ {
+ LL_DEBUGS("Materials") << "Removing material from object " << object->getID() << " face " << face << LL_ENDL;
+ LLMaterialMgr::getInstance()->remove(object->getID(),face);
+ new_material = NULL;
+ }
+ else
+ {
+ LL_DEBUGS("Materials") << "Putting material on object " << object->getID() << " face " << face << ", material: " << new_material->asLLSD() << LL_ENDL;
+ LLMaterialMgr::getInstance()->put(object->getID(),face,*new_material);
+ }
+
+ object->setTEMaterialParams(face, new_material);
+ return new_material;
+ }
+ return NULL;
+ }
+ LLMaterialEditFunctor< DataType, SetValueType, MaterialEditFunc >* _edit;
+ LLPanelFace* _panel;
+ } editor(p, &edit);
+ LLSelectMgr::getInstance()->selectionSetMaterialParams(&editor);
+ }
+
+ template<
+ typename DataType,
+ typename ReturnType,
+ ReturnType (LLMaterial::* const MaterialGetFunc)() const >
+ static void getTEMaterialValue(DataType& data_to_return, bool& identical,DataType default_value)
+ {
+ DataType data_value;
+ struct GetTEMaterialVal : public LLSelectedTEGetFunctor<DataType>
+ {
+ GetTEMaterialVal(DataType default_value) : _default(default_value) {}
+ virtual ~GetTEMaterialVal() {}
+
+ DataType get(LLViewerObject* object, S32 face)
+ {
+ DataType ret = _default;
+ LLMaterialPtr material_ptr;
+ LLTextureEntry* tep = object ? object->getTE(face) : NULL;
+ if (tep)
+ {
+ material_ptr = tep->getMaterialParams();
+ if (!material_ptr.isNull())
+ {
+ ret = (material_ptr->*(MaterialGetFunc))();
+ }
+ }
+ return ret;
+ }
+ DataType _default;
+ } GetFunc(default_value);
+ identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &GetFunc, data_value);
+ data_to_return = data_value;
+ }
+
+ template<
+ typename DataType,
+ typename ReturnType, // some kids just have to different...
+ ReturnType (LLTextureEntry::* const TEGetFunc)() const >
+ static void getTEValue(DataType& data_to_return, bool& identical, DataType default_value)
+ {
+ DataType data_value;
+ struct GetTEVal : public LLSelectedTEGetFunctor<DataType>
+ {
+ GetTEVal(DataType default_value) : _default(default_value) {}
+ virtual ~GetTEVal() {}
+
+ DataType get(LLViewerObject* object, S32 face) {
+ LLTextureEntry* tep = object ? object->getTE(face) : NULL;
+ return tep ? ((tep->*(TEGetFunc))()) : _default;
+ }
+ DataType _default;
+ } GetTEValFunc(default_value);
+ identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &GetTEValFunc, data_value );
+ data_to_return = data_value;
+ }
+
+ // Update vis and enabling of specific subsets of controls based on material params
+ // (e.g. hide the spec controls if no spec texture is applied)
+ //
+ void updateShinyControls(bool is_setting_texture = false, bool mess_with_combobox = false);
+ void updateBumpyControls(bool is_setting_texture = false, bool mess_with_combobox = false);
+ void updateAlphaControls();
+
+ /*
+ * Checks whether the selected texture from the LLFloaterTexturePicker can be applied to the currently selected object.
+ * If agent selects texture which is not allowed to be applied for the currently selected object,
+ * all controls of the floater texture picker which allow to apply the texture will be disabled.
+ */
+ void onTextureSelectionChanged(LLInventoryItem* itemp);
+
+ bool mIsAlpha;
+
+ /* These variables interlock processing of materials updates sent to
+ * the sim. mUpdateInFlight is set to flag that an update has been
+ * sent to the sim and not acknowledged yet, and cleared when an
+ * update is received from the sim. mUpdatePending is set when
+ * there's an update in flight and another UI change has been made
+ * that needs to be sent as a materials update, and cleared when the
+ * update is sent. This prevents the sim from getting spammed with
+ * update messages when, for example, the user holds down the
+ * up-arrow on a spinner, and avoids running afoul of its throttle.
+ */
+ bool mUpdateInFlight;
+ bool mUpdatePending;
+
+ #if defined(DEF_GET_MAT_STATE)
+ #undef DEF_GET_MAT_STATE
+ #endif
+
+ #if defined(DEF_GET_TE_STATE)
+ #undef DEF_GET_TE_STATE
+ #endif
+
+ #if defined(DEF_EDIT_MAT_STATE)
+ DEF_EDIT_MAT_STATE
+ #endif
+
+ // Accessors for selected TE material state
+ //
+ #define DEF_GET_MAT_STATE(DataType,ReturnType,MaterialMemberFunc,DefaultValue) \
+ static void MaterialMemberFunc(DataType& data, bool& identical) \
+ { \
+ getTEMaterialValue< DataType, ReturnType, &LLMaterial::MaterialMemberFunc >(data, identical,DefaultValue); \
+ }
+
+ // Mutators for selected TE material
+ //
+ #define DEF_EDIT_MAT_STATE(DataType,ReturnType,MaterialMemberFunc) \
+ static void MaterialMemberFunc(LLPanelFace* p,DataType data) \
+ { \
+ edit< DataType, ReturnType, &LLMaterial::MaterialMemberFunc >(p,data); \
+ }
+
+ // Accessors for selected TE state proper (legacy settings etc)
+ //
+ #define DEF_GET_TE_STATE(DataType,ReturnType,TexEntryMemberFunc,DefaultValue) \
+ static void TexEntryMemberFunc(DataType& data, bool& identical) \
+ { \
+ getTEValue< DataType, ReturnType, &LLTextureEntry::TexEntryMemberFunc >(data, identical,DefaultValue); \
+ }
+
+ class LLSelectedTEMaterial
+ {
+ public:
+ static void getCurrent(LLMaterialPtr& material_ptr, bool& identical_material);
+ static void getMaxSpecularRepeats(F32& repeats, bool& identical);
+ static void getMaxNormalRepeats(F32& repeats, bool& identical);
+ static void getCurrentDiffuseAlphaMode(U8& diffuse_alpha_mode, bool& identical, bool diffuse_texture_has_alpha);
+
+ DEF_GET_MAT_STATE(LLUUID,const LLUUID&,getNormalID,LLUUID::null)
+ DEF_GET_MAT_STATE(LLUUID,const LLUUID&,getSpecularID,LLUUID::null)
+ DEF_GET_MAT_STATE(F32,F32,getSpecularRepeatX,1.0f)
+ DEF_GET_MAT_STATE(F32,F32,getSpecularRepeatY,1.0f)
+ DEF_GET_MAT_STATE(F32,F32,getSpecularOffsetX,0.0f)
+ DEF_GET_MAT_STATE(F32,F32,getSpecularOffsetY,0.0f)
+ DEF_GET_MAT_STATE(F32,F32,getSpecularRotation,0.0f)
+
+ DEF_GET_MAT_STATE(F32,F32,getNormalRepeatX,1.0f)
+ DEF_GET_MAT_STATE(F32,F32,getNormalRepeatY,1.0f)
+ DEF_GET_MAT_STATE(F32,F32,getNormalOffsetX,0.0f)
+ DEF_GET_MAT_STATE(F32,F32,getNormalOffsetY,0.0f)
+ DEF_GET_MAT_STATE(F32,F32,getNormalRotation,0.0f)
+
+ DEF_EDIT_MAT_STATE(U8,U8,setDiffuseAlphaMode);
+ DEF_EDIT_MAT_STATE(U8,U8,setAlphaMaskCutoff);
+
+ DEF_EDIT_MAT_STATE(F32,F32,setNormalOffsetX);
+ DEF_EDIT_MAT_STATE(F32,F32,setNormalOffsetY);
+ DEF_EDIT_MAT_STATE(F32,F32,setNormalRepeatX);
+ DEF_EDIT_MAT_STATE(F32,F32,setNormalRepeatY);
+ DEF_EDIT_MAT_STATE(F32,F32,setNormalRotation);
+
+ DEF_EDIT_MAT_STATE(F32,F32,setSpecularOffsetX);
+ DEF_EDIT_MAT_STATE(F32,F32,setSpecularOffsetY);
+ DEF_EDIT_MAT_STATE(F32,F32,setSpecularRepeatX);
+ DEF_EDIT_MAT_STATE(F32,F32,setSpecularRepeatY);
+ DEF_EDIT_MAT_STATE(F32,F32,setSpecularRotation);
+
+ DEF_EDIT_MAT_STATE(U8,U8,setEnvironmentIntensity);
+ DEF_EDIT_MAT_STATE(U8,U8,setSpecularLightExponent);
+
+ DEF_EDIT_MAT_STATE(LLUUID,const LLUUID&,setNormalID);
+ DEF_EDIT_MAT_STATE(LLUUID,const LLUUID&,setSpecularID);
+ DEF_EDIT_MAT_STATE(LLColor4U, const LLColor4U&,setSpecularLightColor);
+ };
+
+ class LLSelectedTE
+ {
+ public:
+
+ static void getFace(LLFace*& face_to_return, bool& identical_face);
+ static void getImageFormat(LLGLenum& image_format_to_return, bool& identical_face);
+ static void getTexId(LLUUID& id, bool& identical);
+ static void getObjectScaleS(F32& scale_s, bool& identical);
+ static void getObjectScaleT(F32& scale_t, bool& identical);
+ static void getMaxDiffuseRepeats(F32& repeats, bool& identical);
+
+ DEF_GET_TE_STATE(U8,U8,getBumpmap,0)
+ DEF_GET_TE_STATE(U8,U8,getShiny,0)
+ DEF_GET_TE_STATE(U8,U8,getFullbright,0)
+ DEF_GET_TE_STATE(F32,F32,getRotation,0.0f)
+ DEF_GET_TE_STATE(F32,F32,getOffsetS,0.0f)
+ DEF_GET_TE_STATE(F32,F32,getOffsetT,0.0f)
+ DEF_GET_TE_STATE(F32,F32,getScaleS,1.0f)
+ DEF_GET_TE_STATE(F32,F32,getScaleT,1.0f)
+ DEF_GET_TE_STATE(F32,F32,getGlow,0.0f)
+ DEF_GET_TE_STATE(LLTextureEntry::e_texgen,LLTextureEntry::e_texgen,getTexGen,LLTextureEntry::TEX_GEN_DEFAULT)
+ DEF_GET_TE_STATE(LLColor4,const LLColor4&,getColor,LLColor4::white)
+ };
};
#endif
+
diff --git a/indra/newview/llpanelgenerictip.cpp b/indra/newview/llpanelgenerictip.cpp
index 4ccdaa78f3..4ccdaa78f3 100644..100755
--- a/indra/newview/llpanelgenerictip.cpp
+++ b/indra/newview/llpanelgenerictip.cpp
diff --git a/indra/newview/llpanelgenerictip.h b/indra/newview/llpanelgenerictip.h
index f8a3413fe4..f8a3413fe4 100644..100755
--- a/indra/newview/llpanelgenerictip.h
+++ b/indra/newview/llpanelgenerictip.h
diff --git a/indra/newview/llpanelgroup.cpp b/indra/newview/llpanelgroup.cpp
index ae217958f0..ae217958f0 100644..100755
--- a/indra/newview/llpanelgroup.cpp
+++ b/indra/newview/llpanelgroup.cpp
diff --git a/indra/newview/llpanelgroup.h b/indra/newview/llpanelgroup.h
index b494c7d403..0e6f5b8924 100644..100755
--- a/indra/newview/llpanelgroup.h
+++ b/indra/newview/llpanelgroup.h
@@ -33,7 +33,7 @@
class LLOfferInfo;
-const S32 UPDATE_MEMBERS_PER_FRAME = 500;
+const F32 UPDATE_MEMBERS_SECONDS_PER_FRAME = 0.005; // 5ms
// Forward declares
class LLPanelGroupTab;
diff --git a/indra/newview/llpanelgroupgeneral.cpp b/indra/newview/llpanelgroupgeneral.cpp
index bc594b5517..0cd93b330a 100644..100755
--- a/indra/newview/llpanelgroupgeneral.cpp
+++ b/indra/newview/llpanelgroupgeneral.cpp
@@ -28,8 +28,10 @@
#include "llpanelgroupgeneral.h"
-#include "lluictrlfactory.h"
+#include "llavatarnamecache.h"
#include "llagent.h"
+#include "llsdparam.h"
+#include "lluictrlfactory.h"
#include "roles_constants.h"
// UI elements
@@ -77,13 +79,18 @@ LLPanelGroupGeneral::LLPanelGroupGeneral()
mCtrlReceiveNotices(NULL),
mCtrlListGroup(NULL),
mActiveTitleLabel(NULL),
- mComboActiveTitle(NULL)
+ mComboActiveTitle(NULL),
+ mAvatarNameCacheConnection()
{
}
LLPanelGroupGeneral::~LLPanelGroupGeneral()
{
+ if (mAvatarNameCacheConnection.connected())
+ {
+ mAvatarNameCacheConnection.disconnect();
+ }
}
BOOL LLPanelGroupGeneral::postBuild()
@@ -313,11 +320,10 @@ void LLPanelGroupGeneral::activate()
{
LLGroupMgr::getInstance()->sendGroupTitlesRequest(mGroupID);
LLGroupMgr::getInstance()->sendGroupPropertiesRequest(mGroupID);
-
if (!gdatap || !gdatap->isMemberDataComplete() )
{
- LLGroupMgr::getInstance()->sendGroupMembersRequest(mGroupID);
+ LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mGroupID);
}
mFirstUse = FALSE;
@@ -697,76 +703,48 @@ void LLPanelGroupGeneral::updateMembers()
LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID);
- if (!mListVisibleMembers || !gdatap
+ if (!mListVisibleMembers
+ || !gdatap
|| !gdatap->isMemberDataComplete()
|| gdatap->mMembers.empty())
{
return;
}
- static LLTimer all_timer;
- static LLTimer sd_timer;
- static LLTimer element_timer;
+ LLTimer update_time;
+ update_time.setTimerExpirySec(UPDATE_MEMBERS_SECONDS_PER_FRAME);
- all_timer.reset();
- S32 i = 0;
+ LLAvatarName av_name;
- for( ; mMemberProgress != gdatap->mMembers.end() && i<UPDATE_MEMBERS_PER_FRAME;
- ++mMemberProgress, ++i)
+ for( ; mMemberProgress != gdatap->mMembers.end() && !update_time.hasExpired();
+ ++mMemberProgress)
{
- //llinfos << "Adding " << iter->first << ", " << iter->second->getTitle() << llendl;
LLGroupMemberData* member = mMemberProgress->second;
if (!member)
{
continue;
}
- // Owners show up in bold.
- std::string style = "NORMAL";
- sd_timer.reset();
- LLSD row;
- row["id"] = member->getID();
-
- row["columns"][0]["column"] = "name";
- row["columns"][0]["font"]["name"] = "SANSSERIF_SMALL";
- row["columns"][0]["font"]["style"] = style;
- // value is filled in by name list control
-
- row["columns"][1]["column"] = "title";
- row["columns"][1]["value"] = member->getTitle();
- row["columns"][1]["font"]["name"] = "SANSSERIF_SMALL";
- row["columns"][1]["font"]["style"] = style;
-
- std::string status = member->getOnlineStatus();
-
- row["columns"][2]["column"] = "status";
- row["columns"][2]["value"] = status;
- row["columns"][2]["font"]["name"] = "SANSSERIF_SMALL";
- row["columns"][2]["font"]["style"] = style;
-
- sSDTime += sd_timer.getElapsedTimeF32();
- element_timer.reset();
- LLScrollListItem* member_row = mListVisibleMembers->addElement(row);
-
- if ( member->isOwner() )
+ if (LLAvatarNameCache::get(mMemberProgress->first, &av_name))
+ {
+ addMember(mMemberProgress->second);
+ }
+ else
{
- LLScrollListText* name_textp = dynamic_cast<LLScrollListText*>(member_row->getColumn(0));
- if (name_textp)
- name_textp->setFontStyle(LLFontGL::BOLD);
+ // If name is not cached, onNameCache() should be called when it is cached and add this member to list.
+ // *TODO : Use a callback per member, not for the panel group.
+ if (mAvatarNameCacheConnection.connected())
+ {
+ mAvatarNameCacheConnection.disconnect();
+ }
+ mAvatarNameCacheConnection = LLAvatarNameCache::get(mMemberProgress->first, boost::bind(&LLPanelGroupGeneral::onNameCache, this, gdatap->getMemberVersion(), member, _2));
}
- sElementTime += element_timer.getElapsedTimeF32();
}
- sAllTime += all_timer.getElapsedTimeF32();
- llinfos << "Updated " << i << " of " << UPDATE_MEMBERS_PER_FRAME << "members in the list." << llendl;
if (mMemberProgress == gdatap->mMembers.end())
{
- llinfos << " member list completed." << llendl;
+ lldebugs << " member list completed." << llendl;
mListVisibleMembers->setEnabled(TRUE);
-
- llinfos << "All Time: " << sAllTime << llendl;
- llinfos << "SD Time: " << sSDTime << llendl;
- llinfos << "Element Time: " << sElementTime << llendl;
}
else
{
@@ -775,6 +753,45 @@ void LLPanelGroupGeneral::updateMembers()
}
}
+void LLPanelGroupGeneral::addMember(LLGroupMemberData* member)
+{
+ LLNameListCtrl::NameItem item_params;
+ item_params.value = member->getID();
+
+ LLScrollListCell::Params column;
+ item_params.columns.add().column("name").font.name("SANSSERIF_SMALL");
+
+ item_params.columns.add().column("title").value(member->getTitle()).font.name("SANSSERIF_SMALL");
+
+ item_params.columns.add().column("status").value(member->getOnlineStatus()).font.name("SANSSERIF_SMALL");
+
+ LLScrollListItem* member_row = mListVisibleMembers->addNameItemRow(item_params);
+
+ if ( member->isOwner() )
+ {
+ LLScrollListText* name_textp = dynamic_cast<LLScrollListText*>(member_row->getColumn(0));
+ if (name_textp)
+ name_textp->setFontStyle(LLFontGL::BOLD);
+ }
+}
+
+void LLPanelGroupGeneral::onNameCache(const LLUUID& update_id, LLGroupMemberData* member, const LLAvatarName& av_name)
+{
+ mAvatarNameCacheConnection.disconnect();
+
+ LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID);
+
+ if (!gdatap
+ || !gdatap->isMemberDataComplete()
+ || gdatap->getMemberVersion() != update_id)
+ {
+ // Stale data
+ return;
+ }
+
+ addMember(member);
+}
+
void LLPanelGroupGeneral::updateChanged()
{
// List all the controls we want to check for changes...
diff --git a/indra/newview/llpanelgroupgeneral.h b/indra/newview/llpanelgroupgeneral.h
index 88c092c461..b7f4a01139 100644..100755
--- a/indra/newview/llpanelgroupgeneral.h
+++ b/indra/newview/llpanelgroupgeneral.h
@@ -38,6 +38,7 @@ class LLNameListCtrl;
class LLCheckBoxCtrl;
class LLComboBox;
class LLSpinCtrl;
+class LLAvatarName;
class LLPanelGroupGeneral : public LLPanelGroupTab
{
@@ -62,6 +63,7 @@ public:
virtual void setupCtrls (LLPanel* parent);
+ void onNameCache(const LLUUID& update_id, LLGroupMemberData* member, const LLAvatarName& av_name);
private:
void reset();
@@ -75,7 +77,8 @@ private:
static void onReceiveNotices(LLUICtrl* ctrl, void* data);
static void openProfile(void* data);
- S32 sortMembersList(S32,const LLScrollListItem*,const LLScrollListItem*);
+ S32 sortMembersList(S32,const LLScrollListItem*,const LLScrollListItem*);
+ void addMember(LLGroupMemberData* member);
static bool joinDlgCB(const LLSD& notification, const LLSD& response);
@@ -108,6 +111,7 @@ private:
LLComboBox *mComboMature;
LLGroupMgrGroupData::member_list_t::iterator mMemberProgress;
+ boost::signals2::connection mAvatarNameCacheConnection;
};
#endif
diff --git a/indra/newview/llpanelgroupinvite.cpp b/indra/newview/llpanelgroupinvite.cpp
index 7a15d93181..a9a3c686a6 100644..100755
--- a/indra/newview/llpanelgroupinvite.cpp
+++ b/indra/newview/llpanelgroupinvite.cpp
@@ -83,11 +83,15 @@ public:
LLTextBox *mGroupName;
std::string mOwnerWarning;
std::string mAlreadyInGroup;
+ std::string mTooManySelected;
bool mConfirmedOwnerInvite;
+ std::set<LLUUID> mInviteeIDs;
void (*mCloseCallback)(void* data);
void* mCloseCallbackUserData;
+
+ boost::signals2::connection mAvatarNameCacheConnection;
};
@@ -101,39 +105,43 @@ LLPanelGroupInvite::impl::impl(const LLUUID& group_id):
mGroupName( NULL ),
mConfirmedOwnerInvite( false ),
mCloseCallback( NULL ),
- mCloseCallbackUserData( NULL )
+ mCloseCallbackUserData( NULL ),
+ mAvatarNameCacheConnection()
{
}
LLPanelGroupInvite::impl::~impl()
{
+ if (mAvatarNameCacheConnection.connected())
+ {
+ mAvatarNameCacheConnection.disconnect();
+ }
}
+const S32 MAX_GROUP_INVITES = 100; // Max invites per request. 100 to match server cap.
+
void LLPanelGroupInvite::impl::addUsers(const std::vector<std::string>& names,
const uuid_vec_t& agent_ids)
{
std::string name;
LLUUID id;
+ if (names.size() + mInviteeIDs.size() > MAX_GROUP_INVITES)
+ {
+ // Fail! Show a warning and don't add any names.
+ LLSD msg;
+ msg["MESSAGE"] = mTooManySelected;
+ LLNotificationsUtil::add("GenericAlert", msg);
+ return;
+ }
+
for (S32 i = 0; i < (S32)names.size(); i++)
{
name = names[i];
id = agent_ids[i];
// Make sure this agent isn't already in the list.
- bool already_in_list = false;
- std::vector<LLScrollListItem*> items = mInvitees->getAllData();
- for (std::vector<LLScrollListItem*>::iterator iter = items.begin();
- iter != items.end(); ++iter)
- {
- LLScrollListItem* item = *iter;
- if (item->getUUID() == id)
- {
- already_in_list = true;
- break;
- }
- }
- if (already_in_list)
+ if (mInviteeIDs.find(id) != mInviteeIDs.end())
{
continue;
}
@@ -144,6 +152,7 @@ void LLPanelGroupInvite::impl::addUsers(const std::vector<std::string>& names,
row["columns"][0]["value"] = name;
mInvitees->addElement(row);
+ mInviteeIDs.insert(id);
}
}
@@ -185,6 +194,16 @@ void LLPanelGroupInvite::impl::submitInvitations()
role_member_pairs[item->getUUID()] = role_id;
}
+ if (role_member_pairs.size() > MAX_GROUP_INVITES)
+ {
+ // Fail!
+ LLSD msg;
+ msg["MESSAGE"] = mTooManySelected;
+ LLNotificationsUtil::add("GenericAlert", msg);
+ (*mCloseCallback)(mCloseCallbackUserData);
+ return;
+ }
+
LLGroupMgr::getInstance()->sendGroupMemberInvites(mGroupID, role_member_pairs);
if(already_in_group)
@@ -289,11 +308,13 @@ void LLPanelGroupInvite::impl::callbackClickAdd(void* userdata)
//Soon the avatar picker will be embedded into this panel
//instead of being it's own separate floater. But that is next week.
//This will do for now. -jwolk May 10, 2006
+ LLView * button = panelp->findChild<LLButton>("add_button");
+ LLFloater * root_floater = gFloaterView->getParentFloater(panelp);
LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(
- boost::bind(impl::callbackAddUsers, _1, panelp->mImplementation), TRUE);
+ boost::bind(impl::callbackAddUsers, _1, panelp->mImplementation), TRUE, FALSE, FALSE, root_floater->getName(), button);
if (picker)
{
- gFloaterView->getParentFloater(panelp)->addDependentFloater(picker);
+ root_floater->addDependentFloater(picker);
}
}
}
@@ -313,6 +334,12 @@ void LLPanelGroupInvite::impl::handleRemove()
mInvitees->getAllSelected();
if (selection.empty()) return;
+ std::vector<LLScrollListItem*>::iterator iter;
+ for(iter = selection.begin(); iter != selection.end(); ++iter)
+ {
+ mInviteeIDs.erase( (*iter)->getUUID() );
+ }
+
// Remove all selected invitees.
mInvitees->deleteSelectedItems();
mRemoveButton->setEnabled(FALSE);
@@ -366,8 +393,24 @@ void LLPanelGroupInvite::impl::callbackAddUsers(const uuid_vec_t& agent_ids, voi
std::vector<std::string> names;
for (S32 i = 0; i < (S32)agent_ids.size(); i++)
{
- LLAvatarNameCache::get(agent_ids[i],
- boost::bind(&LLPanelGroupInvite::impl::onAvatarNameCache, _1, _2, user_data));
+ LLAvatarName av_name;
+ if (LLAvatarNameCache::get(agent_ids[i], &av_name))
+ {
+ LLPanelGroupInvite::impl::onAvatarNameCache(agent_ids[i], av_name, user_data);
+ }
+ else
+ {
+ impl* selfp = (impl*) user_data;
+ if (selfp)
+ {
+ if (selfp->mAvatarNameCacheConnection.connected())
+ {
+ selfp->mAvatarNameCacheConnection.disconnect();
+ }
+ // *TODO : Add a callback per avatar name being fetched.
+ selfp->mAvatarNameCacheConnection = LLAvatarNameCache::get(agent_ids[i],boost::bind(&LLPanelGroupInvite::impl::onAvatarNameCache, _1, _2, user_data));
+ }
+ }
}
}
@@ -380,6 +423,10 @@ void LLPanelGroupInvite::impl::onAvatarNameCache(const LLUUID& agent_id,
if (selfp)
{
+ if (selfp->mAvatarNameCacheConnection.connected())
+ {
+ selfp->mAvatarNameCacheConnection.disconnect();
+ }
std::vector<std::string> names;
uuid_vec_t agent_ids;
agent_ids.push_back(agent_id);
@@ -418,6 +465,7 @@ void LLPanelGroupInvite::clear()
mImplementation->mRoleNames->clear();
mImplementation->mRoleNames->removeall();
mImplementation->mOKButton->setEnabled(FALSE);
+ mImplementation->mInviteeIDs.clear();
}
void LLPanelGroupInvite::addUsers(uuid_vec_t& agent_ids)
@@ -455,11 +503,11 @@ void LLPanelGroupInvite::addUsers(uuid_vec_t& agent_ids)
//so we need to do this additional search in avatar tracker, see EXT-4732
if (LLAvatarTracker::instance().isBuddy(agent_id))
{
- if (!gCacheName->getFullName(agent_id, fullname))
+ LLAvatarName av_name;
+ if (!LLAvatarNameCache::get(agent_id, &av_name))
{
// actually it should happen, just in case
- gCacheName->get(LLUUID(agent_id), false, boost::bind(
- &LLPanelGroupInvite::addUserCallback, this, _1, _2));
+ //LLAvatarNameCache::get(LLUUID(agent_id), boost::bind(&LLPanelGroupInvite::addUserCallback, this, _1, _2));
// for this special case!
//when there is no cached name we should remove resident from agent_ids list to avoid breaking of sequence
// removed id will be added in callback
@@ -467,7 +515,7 @@ void LLPanelGroupInvite::addUsers(uuid_vec_t& agent_ids)
}
else
{
- names.push_back(fullname);
+ names.push_back(av_name.getAccountName());
}
}
}
@@ -475,12 +523,12 @@ void LLPanelGroupInvite::addUsers(uuid_vec_t& agent_ids)
mImplementation->addUsers(names, agent_ids);
}
-void LLPanelGroupInvite::addUserCallback(const LLUUID& id, const std::string& full_name)
+void LLPanelGroupInvite::addUserCallback(const LLUUID& id, const LLAvatarName& av_name)
{
std::vector<std::string> names;
uuid_vec_t agent_ids;
agent_ids.push_back(id);
- names.push_back(full_name);
+ names.push_back(av_name.getAccountName());
mImplementation->addUsers(names, agent_ids);
}
@@ -558,8 +606,8 @@ void LLPanelGroupInvite::updateLists()
if (!mPendingUpdate)
{
LLGroupMgr::getInstance()->sendGroupPropertiesRequest(mImplementation->mGroupID);
- LLGroupMgr::getInstance()->sendGroupMembersRequest(mImplementation->mGroupID);
LLGroupMgr::getInstance()->sendGroupRoleDataRequest(mImplementation->mGroupID);
+ LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mImplementation->mGroupID);
}
mPendingUpdate = TRUE;
}
@@ -621,6 +669,7 @@ BOOL LLPanelGroupInvite::postBuild()
mImplementation->mOwnerWarning = getString("confirm_invite_owner_str");
mImplementation->mAlreadyInGroup = getString("already_in_group");
+ mImplementation->mTooManySelected = getString("invite_selection_too_large");
update();
diff --git a/indra/newview/llpanelgroupinvite.h b/indra/newview/llpanelgroupinvite.h
index a7bfd2226e..9f7b5ae9be 100644..100755
--- a/indra/newview/llpanelgroupinvite.h
+++ b/indra/newview/llpanelgroupinvite.h
@@ -29,6 +29,8 @@
#include "llpanel.h"
#include "lluuid.h"
+class LLAvatarName;
+
class LLPanelGroupInvite
: public LLPanel
{
@@ -40,7 +42,7 @@ public:
/**
* this callback is being used to add a user whose fullname isn't been loaded before invoking of addUsers().
*/
- void addUserCallback(const LLUUID& id, const std::string& full_name);
+ void addUserCallback(const LLUUID& id, const LLAvatarName& av_name);
void clear();
void update();
diff --git a/indra/newview/llpanelgrouplandmoney.cpp b/indra/newview/llpanelgrouplandmoney.cpp
index 363443646d..c927aeacb3 100644..100755
--- a/indra/newview/llpanelgrouplandmoney.cpp
+++ b/indra/newview/llpanelgrouplandmoney.cpp
@@ -517,7 +517,7 @@ void LLPanelGroupLandMoney::impl::processGroupLand(LLMessageSystem* msg)
row["columns"][3]["column"] = "type";
row["columns"][3]["value"] = land_type;
- row["columns"][3]["font"] = "SANSSERIFSMALL";
+ row["columns"][3]["font"] = "SANSSERIF_SMALL";
// hidden is always last column
row["columns"][4]["column"] = "hidden";
@@ -1383,13 +1383,11 @@ void LLGroupMoneyPlanningTabEventHandler::processReply(LLMessageSystem* msg,
S32 cur_land_tax;
S32 cur_group_tax;
S32 cur_parcel_dir_fee;
- S32 cur_total_tax;
S32 proj_object_tax;
S32 proj_light_tax;
S32 proj_land_tax;
S32 proj_group_tax;
S32 proj_parcel_dir_fee;
- S32 proj_total_tax;
S32 non_exempt_members;
msg->getS32Fast(_PREHASH_MoneyData, _PREHASH_IntervalDays, interval_days );
@@ -1413,8 +1411,6 @@ void LLGroupMoneyPlanningTabEventHandler::processReply(LLMessageSystem* msg,
msg->getStringFast(_PREHASH_MoneyData, _PREHASH_LastTaxDate, last_stipend_date);
msg->getStringFast(_PREHASH_MoneyData, _PREHASH_TaxDate, next_stipend_date);
- cur_total_tax = cur_object_tax + cur_light_tax + cur_land_tax + cur_group_tax + cur_parcel_dir_fee;
- proj_total_tax = proj_object_tax + proj_light_tax + proj_land_tax + proj_group_tax + proj_parcel_dir_fee;
if (interval_days != mImplementationp->mIntervalLength ||
current_interval != mImplementationp->mCurrentInterval)
diff --git a/indra/newview/llpanelgrouplandmoney.h b/indra/newview/llpanelgrouplandmoney.h
index ac3518ee19..ac3518ee19 100644..100755
--- a/indra/newview/llpanelgrouplandmoney.h
+++ b/indra/newview/llpanelgrouplandmoney.h
diff --git a/indra/newview/llpanelgroupnotices.cpp b/indra/newview/llpanelgroupnotices.cpp
index 31c0e3d01a..522ba5afae 100644..100755
--- a/indra/newview/llpanelgroupnotices.cpp
+++ b/indra/newview/llpanelgroupnotices.cpp
@@ -35,6 +35,7 @@
#include "llviewerinventory.h"
#include "llinventorydefines.h"
#include "llinventoryfunctions.h"
+#include "llinventoryicon.h"
#include "llinventorymodel.h"
#include "llfloaterinventory.h"
#include "llagent.h"
@@ -543,10 +544,7 @@ void LLPanelGroupNotices::processNotices(LLMessageSystem* msg)
msg->getU32("Data","Timestamp",timestamp,i);
// we only have the legacy name here, convert it to a username
- if (LLAvatarNameCache::useDisplayNames())
- {
- name = LLCacheName::buildUsername(name);
- }
+ name = LLCacheName::buildUsername(name);
LLSD row;
row["id"] = id;
diff --git a/indra/newview/llpanelgroupnotices.h b/indra/newview/llpanelgroupnotices.h
index 04629b5f6b..04629b5f6b 100644..100755
--- a/indra/newview/llpanelgroupnotices.h
+++ b/indra/newview/llpanelgroupnotices.h
diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp
index f825ee3215..fdcd1f5ebb 100644..100755
--- a/indra/newview/llpanelgrouproles.cpp
+++ b/indra/newview/llpanelgrouproles.cpp
@@ -29,6 +29,7 @@
#include "llcheckboxctrl.h"
#include "llagent.h"
+#include "llavatarnamecache.h"
#include "llbutton.h"
#include "llfiltereditor.h"
#include "llfloatergroupinvite.h"
@@ -356,7 +357,7 @@ void LLPanelGroupRoles::activate()
if (!gdatap || !gdatap->isMemberDataComplete() )
{
- LLGroupMgr::getInstance()->sendGroupMembersRequest(mGroupID);
+ LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mGroupID);
}
// Check role data.
@@ -742,13 +743,17 @@ LLPanelGroupMembersSubTab::LLPanelGroupMembersSubTab()
mChanged(FALSE),
mPendingMemberUpdate(FALSE),
mHasMatch(FALSE),
- mNumOwnerAdditions(0)
+ mNumOwnerAdditions(0),
+ mAvatarNameCacheConnection()
{
- mUdpateSessionID = LLUUID::null;
}
LLPanelGroupMembersSubTab::~LLPanelGroupMembersSubTab()
{
+ if (mAvatarNameCacheConnection.connected())
+ {
+ mAvatarNameCacheConnection.disconnect();
+ }
if (mMembersList)
{
gSavedSettings.setString("GroupMembersSortOrder", mMembersList->getSortColumnName());
@@ -1096,27 +1101,61 @@ void LLPanelGroupMembersSubTab::onEjectMembers(void *userdata)
}
void LLPanelGroupMembersSubTab::handleEjectMembers()
-{
- //send down an eject message
- uuid_vec_t selected_members;
-
+{
std::vector<LLScrollListItem*> selection = mMembersList->getAllSelected();
if (selection.empty()) return;
-
- std::vector<LLScrollListItem*>::iterator itor;
- for (itor = selection.begin() ;
- itor != selection.end(); ++itor)
+
+ S32 selection_count = selection.size();
+ if (selection_count == 1)
{
- LLUUID member_id = (*itor)->getUUID();
- selected_members.push_back( member_id );
+ LLSD args;
+ LLUUID selected_avatar = mMembersList->getValue().asUUID();
+ std::string fullname = LLSLURL("agent", selected_avatar, "inspect").getSLURLString();
+ args["AVATAR_NAME"] = fullname;
+ LLSD payload;
+ LLNotificationsUtil::add("EjectGroupMemberWarning",
+ args,
+ payload,
+ boost::bind(&LLPanelGroupMembersSubTab::handleEjectCallback, this, _1, _2));
}
+ else
+ {
+ LLSD args;
+ args["COUNT"] = llformat("%d", selection_count);
+ LLSD payload;
+ LLNotificationsUtil::add("EjectGroupMembersWarning",
+ args,
+ payload,
+ boost::bind(&LLPanelGroupMembersSubTab::handleEjectCallback, this, _1, _2));
+ }
+}
- mMembersList->deleteSelectedItems();
-
- sendEjectNotifications(mGroupID, selected_members);
-
- LLGroupMgr::getInstance()->sendGroupMemberEjects(mGroupID,
- selected_members);
+bool LLPanelGroupMembersSubTab::handleEjectCallback(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ if (0 == option) // Eject button
+ {
+ //send down an eject message
+ uuid_vec_t selected_members;
+
+ std::vector<LLScrollListItem*> selection = mMembersList->getAllSelected();
+ if (selection.empty()) return false;
+
+ std::vector<LLScrollListItem*>::iterator itor;
+ for (itor = selection.begin() ;
+ itor != selection.end(); ++itor)
+ {
+ LLUUID member_id = (*itor)->getUUID();
+ selected_members.push_back( member_id );
+ }
+
+ mMembersList->deleteSelectedItems();
+
+ sendEjectNotifications(mGroupID, selected_members);
+
+ LLGroupMgr::getInstance()->sendGroupMemberEjects(mGroupID, selected_members);
+ }
+ return false;
}
void LLPanelGroupMembersSubTab::sendEjectNotifications(const LLUUID& group_id, const uuid_vec_t& selected_members)
@@ -1426,13 +1465,20 @@ U64 LLPanelGroupMembersSubTab::getAgentPowersBasedOnRoleChanges(const LLUUID& ag
return GP_NO_POWERS;
}
- LLGroupMemberData* member_data = gdatap->mMembers[agent_id];
- if ( !member_data )
+ LLGroupMgrGroupData::member_list_t::iterator iter = gdatap->mMembers.find(agent_id);
+ if ( iter == gdatap->mMembers.end() )
{
llwarns << "LLPanelGroupMembersSubTab::getAgentPowersBasedOnRoleChanges() -- No member data for member with UUID " << agent_id << llendl;
return GP_NO_POWERS;
}
+ LLGroupMemberData* member_data = (*iter).second;
+ if (!member_data)
+ {
+ llwarns << "LLPanelGroupMembersSubTab::getAgentPowersBasedOnRoleChanges() -- Null member data for member with UUID " << agent_id << llendl;
+ return GP_NO_POWERS;
+ }
+
//see if there are unsaved role changes for this agent
role_change_data_map_t* role_change_datap = NULL;
member_role_changes_map_t::iterator member = mMemberRoleChangeData.find(agent_id);
@@ -1547,10 +1593,6 @@ void LLPanelGroupMembersSubTab::update(LLGroupChange gc)
mMemberProgress = gdatap->mMembers.begin();
mPendingMemberUpdate = TRUE;
mHasMatch = FALSE;
- // Generate unique ID for current updateMembers()- see onNameCache for details.
- // Using unique UUID is perhaps an overkill but this way we are perfectly safe
- // from coincidences.
- mUdpateSessionID.generate();
}
else
{
@@ -1578,55 +1620,43 @@ void LLPanelGroupMembersSubTab::update(LLGroupChange gc)
}
}
-void LLPanelGroupMembersSubTab::addMemberToList(LLUUID id, LLGroupMemberData* data)
+void LLPanelGroupMembersSubTab::addMemberToList(LLGroupMemberData* data)
{
if (!data) return;
LLUIString donated = getString("donation_area");
donated.setArg("[AREA]", llformat("%d", data->getContribution()));
- LLSD row;
- row["id"] = id;
-
- row["columns"][0]["column"] = "name";
- // value is filled in by name list control
+ LLNameListCtrl::NameItem item_params;
+ item_params.value = data->getID();
- row["columns"][1]["column"] = "donated";
- row["columns"][1]["value"] = donated.getString();
+ item_params.columns.add().column("name").font.name("SANSSERIF_SMALL").style("NORMAL");
- row["columns"][2]["column"] = "online";
- row["columns"][2]["value"] = data->getOnlineStatus();
- row["columns"][2]["font"] = "SANSSERIF_SMALL";
+ item_params.columns.add().column("donated").value(donated.getString())
+ .font.name("SANSSERIF_SMALL").style("NORMAL");
- mMembersList->addElement(row);
+ item_params.columns.add().column("online").value(data->getOnlineStatus())
+ .font.name("SANSSERIF_SMALL").style("NORMAL");
+ mMembersList->addNameItemRow(item_params);
mHasMatch = TRUE;
}
-void LLPanelGroupMembersSubTab::onNameCache(const LLUUID& update_id, const LLUUID& id)
+void LLPanelGroupMembersSubTab::onNameCache(const LLUUID& update_id, LLGroupMemberData* member, const LLAvatarName& av_name)
{
- // Update ID is used to determine whether member whose id is passed
- // into onNameCache() was passed after current or previous user-initiated update.
- // This is needed to avoid probable duplication of members in list after changing filter
- // or adding of members of another group if gets for their names were called on
- // previous update. If this id is from get() called from older update,
- // we do nothing.
- if (mUdpateSessionID != update_id) return;
-
+ mAvatarNameCacheConnection.disconnect();
+
LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID);
- if (!gdatap)
+ if (!gdatap
+ || gdatap->getMemberVersion() != update_id
+ || !member)
{
- llwarns << "LLPanelGroupMembersSubTab::updateMembers() -- No group data!" << llendl;
return;
}
- std::string fullname;
- gCacheName->getFullName(id, fullname);
-
- LLGroupMemberData* data;
// trying to avoid unnecessary hash lookups
- if (matchesSearchFilter(fullname) && ((data = gdatap->mMembers[id]) != NULL))
+ if (matchesSearchFilter(av_name.getAccountName()))
{
- addMemberToList(id, data);
+ addMemberToList(member);
if(!mMembersList->getEnabled())
{
mMembersList->setEnabled(TRUE);
@@ -1665,27 +1695,33 @@ void LLPanelGroupMembersSubTab::updateMembers()
LLGroupMgrGroupData::member_list_t::iterator end = gdatap->mMembers.end();
-
- S32 i = 0;
- for( ; mMemberProgress != end && i<UPDATE_MEMBERS_PER_FRAME;
- ++mMemberProgress, ++i)
+
+ LLTimer update_time;
+ update_time.setTimerExpirySec(UPDATE_MEMBERS_SECONDS_PER_FRAME);
+
+ for( ; mMemberProgress != end && !update_time.hasExpired(); ++mMemberProgress)
{
if (!mMemberProgress->second)
continue;
+
// Do filtering on name if it is already in the cache.
- std::string fullname;
- if (gCacheName->getFullName(mMemberProgress->first, fullname))
+ LLAvatarName av_name;
+ if (LLAvatarNameCache::get(mMemberProgress->first, &av_name))
{
- if (matchesSearchFilter(fullname))
+ if (matchesSearchFilter(av_name.getAccountName()))
{
- addMemberToList(mMemberProgress->first, mMemberProgress->second);
+ addMemberToList(mMemberProgress->second);
}
}
else
{
// If name is not cached, onNameCache() should be called when it is cached and add this member to list.
- gCacheName->get(mMemberProgress->first, FALSE, boost::bind(&LLPanelGroupMembersSubTab::onNameCache,
- this, mUdpateSessionID, _1));
+ // *TODO : Add one callback per fetched avatar name
+ if (mAvatarNameCacheConnection.connected())
+ {
+ mAvatarNameCacheConnection.disconnect();
+ }
+ mAvatarNameCacheConnection = LLAvatarNameCache::get(mMemberProgress->first, boost::bind(&LLPanelGroupMembersSubTab::onNameCache, this, gdatap->getMemberVersion(), mMemberProgress->second, _2));
}
}
@@ -1987,7 +2023,7 @@ void LLPanelGroupRolesSubTab::update(LLGroupChange gc)
if (!gdatap || !gdatap->isMemberDataComplete())
{
- LLGroupMgr::getInstance()->sendGroupMembersRequest(mGroupID);
+ LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mGroupID);
}
if (!gdatap || !gdatap->isRoleMemberDataComplete())
@@ -2580,7 +2616,7 @@ void LLPanelGroupActionsSubTab::handleActionSelect()
}
else
{
- LLGroupMgr::getInstance()->sendGroupMembersRequest(mGroupID);
+ LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mGroupID);
}
if (gdatap->isRoleDataComplete())
@@ -2604,6 +2640,7 @@ void LLPanelGroupActionsSubTab::handleActionSelect()
LLGroupMgr::getInstance()->sendGroupRoleDataRequest(mGroupID);
}
}
+
void LLPanelGroupRoles::setGroupID(const LLUUID& id)
{
LLPanelGroupTab::setGroupID(id);
diff --git a/indra/newview/llpanelgrouproles.h b/indra/newview/llpanelgrouproles.h
index a55e264150..0cf272f3ee 100644..100755
--- a/indra/newview/llpanelgrouproles.h
+++ b/indra/newview/llpanelgrouproles.h
@@ -167,6 +167,7 @@ public:
static void onEjectMembers(void*);
void handleEjectMembers();
void sendEjectNotifications(const LLUUID& group_id, const uuid_vec_t& selected_members);
+ bool handleEjectCallback(const LLSD& notification, const LLSD& response);
static void onRoleCheck(LLUICtrl* check, void* user_data);
void handleRoleCheck(const LLUUID& role_id,
@@ -187,8 +188,8 @@ public:
virtual void setGroupID(const LLUUID& id);
- void addMemberToList(LLUUID id, LLGroupMemberData* data);
- void onNameCache(const LLUUID& update_id, const LLUUID& id);
+ void addMemberToList(LLGroupMemberData* data);
+ void onNameCache(const LLUUID& update_id, LLGroupMemberData* member, const LLAvatarName& av_name);
protected:
typedef std::map<LLUUID, LLRoleMemberChangeType> role_change_data_map_t;
@@ -210,13 +211,11 @@ protected:
BOOL mPendingMemberUpdate;
BOOL mHasMatch;
- // This id is generated after each user initiated member list update(opening Roles or changing filter)
- LLUUID mUdpateSessionID;
-
member_role_changes_map_t mMemberRoleChangeData;
U32 mNumOwnerAdditions;
LLGroupMgrGroupData::member_list_t::iterator mMemberProgress;
+ boost::signals2::connection mAvatarNameCacheConnection;
};
class LLPanelGroupRolesSubTab : public LLPanelGroupSubTab
diff --git a/indra/newview/llpanelhome.cpp b/indra/newview/llpanelhome.cpp
index b03bab3127..b03bab3127 100644..100755
--- a/indra/newview/llpanelhome.cpp
+++ b/indra/newview/llpanelhome.cpp
diff --git a/indra/newview/llpanelhome.h b/indra/newview/llpanelhome.h
index 748566326f..748566326f 100644..100755
--- a/indra/newview/llpanelhome.h
+++ b/indra/newview/llpanelhome.h
diff --git a/indra/newview/llpanelimcontrolpanel.cpp b/indra/newview/llpanelimcontrolpanel.cpp
index eda0749cdb..389baa86cd 100644..100755
--- a/indra/newview/llpanelimcontrolpanel.cpp
+++ b/indra/newview/llpanelimcontrolpanel.cpp
@@ -1,31 +1,30 @@
-/**
+/**
* @file llpanelavatar.cpp
* @brief LLPanelAvatar and related class implementations
*
* $LicenseInfo:firstyear=2004&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 "llviewerprecompiledheaders.h"
-
#include "llfloaterreg.h"
#include "llpanelimcontrolpanel.h"
@@ -39,393 +38,7 @@
#include "llavatarlist.h"
#include "llparticipantlist.h"
#include "llimview.h"
-#include "llvoicechannel.h"
#include "llspeakers.h"
#include "lltrans.h"
-void LLPanelChatControlPanel::onCallButtonClicked()
-{
- gIMMgr->startCall(mSessionId);
-}
-
-void LLPanelChatControlPanel::onEndCallButtonClicked()
-{
- gIMMgr->endCall(mSessionId);
-}
-
-void LLPanelChatControlPanel::onOpenVoiceControlsClicked()
-{
- LLFloaterReg::showInstance("voice_controls");
-}
-
-void LLPanelChatControlPanel::onChange(EStatusType status, const std::string &channelURI, bool proximal)
-{
- if(status == STATUS_JOINING || status == STATUS_LEFT_CHANNEL)
- {
- return;
- }
-
- updateCallButton();
-}
-
-void LLPanelChatControlPanel::onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state)
-{
- updateButtons(new_state);
-}
-
-void LLPanelChatControlPanel::updateCallButton()
-{
- // hide/show call button
- bool voice_enabled = LLVoiceClient::getInstance()->voiceEnabled() && LLVoiceClient::getInstance()->isVoiceWorking();
-
- LLIMModel::LLIMSession* session = LLIMModel::getInstance()->findIMSession(mSessionId);
-
- if (!session)
- {
- getChildView("call_btn")->setEnabled(false);
- return;
- }
-
- bool session_initialized = session->mSessionInitialized;
- bool callback_enabled = session->mCallBackEnabled;
-
- BOOL enable_connect = session_initialized
- && voice_enabled
- && callback_enabled;
- getChildView("call_btn")->setEnabled(enable_connect);
-}
-
-void LLPanelChatControlPanel::updateButtons(LLVoiceChannel::EState state)
-{
- bool is_call_started = state >= LLVoiceChannel::STATE_CALL_STARTED;
- getChildView("end_call_btn_panel")->setVisible( is_call_started);
- getChildView("voice_ctrls_btn_panel")->setVisible( is_call_started && findChild<LLView>("voice_ctrls_btn_panel"));
- getChildView("call_btn_panel")->setVisible( ! is_call_started);
-
- getChildView("volume_ctrl_panel")->setVisible(state == LLVoiceChannel::STATE_CONNECTED);
-
- updateCallButton();
-
-}
-
-LLPanelChatControlPanel::~LLPanelChatControlPanel()
-{
- mVoiceChannelStateChangeConnection.disconnect();
- if(LLVoiceClient::instanceExists())
- {
- LLVoiceClient::getInstance()->removeObserver(this);
- }
-}
-
-BOOL LLPanelChatControlPanel::postBuild()
-{
- childSetAction("call_btn", boost::bind(&LLPanelChatControlPanel::onCallButtonClicked, this));
- childSetAction("end_call_btn", boost::bind(&LLPanelChatControlPanel::onEndCallButtonClicked, this));
- childSetAction("voice_ctrls_btn", boost::bind(&LLPanelChatControlPanel::onOpenVoiceControlsClicked, this));
-
- LLVoiceClient::getInstance()->addObserver(this);
-
- return TRUE;
-}
-
-void LLPanelChatControlPanel::setSessionId(const LLUUID& session_id)
-{
- //Method is called twice for AdHoc and Group chat. Second time when server init reply received
- mSessionId = session_id;
- LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionId);
- if(voice_channel)
- {
- mVoiceChannelStateChangeConnection = voice_channel->setStateChangedCallback(boost::bind(&LLPanelChatControlPanel::onVoiceChannelStateChanged, this, _1, _2));
-
- //call (either p2p, group or ad-hoc) can be already in started state
- updateButtons(voice_channel->getState());
- }
-}
-
-LLPanelIMControlPanel::LLPanelIMControlPanel()
-{
-}
-
-LLPanelIMControlPanel::~LLPanelIMControlPanel()
-{
- LLAvatarTracker::instance().removeParticularFriendObserver(mAvatarID, this);
-}
-
-BOOL LLPanelIMControlPanel::postBuild()
-{
- childSetAction("view_profile_btn", boost::bind(&LLPanelIMControlPanel::onViewProfileButtonClicked, this));
- childSetAction("add_friend_btn", boost::bind(&LLPanelIMControlPanel::onAddFriendButtonClicked, this));
-
- childSetAction("share_btn", boost::bind(&LLPanelIMControlPanel::onShareButtonClicked, this));
- childSetAction("teleport_btn", boost::bind(&LLPanelIMControlPanel::onTeleportButtonClicked, this));
- childSetAction("pay_btn", boost::bind(&LLPanelIMControlPanel::onPayButtonClicked, this));
-
- childSetAction("mute_btn", boost::bind(&LLPanelIMControlPanel::onClickMuteVolume, this));
- childSetAction("block_btn", boost::bind(&LLPanelIMControlPanel::onClickBlock, this));
- childSetAction("unblock_btn", boost::bind(&LLPanelIMControlPanel::onClickUnblock, this));
-
- getChild<LLUICtrl>("volume_slider")->setCommitCallback(boost::bind(&LLPanelIMControlPanel::onVolumeChange, this, _2));
-
- getChildView("add_friend_btn")->setEnabled(!LLAvatarActions::isFriend(getChild<LLAvatarIconCtrl>("avatar_icon")->getAvatarId()));
-
- setFocusReceivedCallback(boost::bind(&LLPanelIMControlPanel::onFocusReceived, this));
-
- return LLPanelChatControlPanel::postBuild();
-}
-
-void LLPanelIMControlPanel::draw()
-{
- bool is_muted = LLMuteList::getInstance()->isMuted(mAvatarID);
-
- getChild<LLUICtrl>("block_btn_panel")->setVisible(!is_muted);
- getChild<LLUICtrl>("unblock_btn_panel")->setVisible(is_muted);
-
- if (getChildView("volume_ctrl_panel")->getVisible())
- {
-
- bool is_muted_voice = LLMuteList::getInstance()->isMuted(mAvatarID, LLMute::flagVoiceChat);
-
- LLUICtrl* mute_btn = getChild<LLUICtrl>("mute_btn");
- mute_btn->setValue( is_muted_voice );
-
- LLUICtrl* volume_slider = getChild<LLUICtrl>("volume_slider");
- volume_slider->setEnabled( !is_muted_voice );
-
- F32 volume;
-
- if (is_muted_voice)
- {
- // it's clearer to display their volume as zero
- volume = 0.f;
- }
- else
- {
- // actual volume
- volume = LLVoiceClient::getInstance()->getUserVolume(mAvatarID);
- }
- volume_slider->setValue( (F64)volume );
- }
-
- LLPanelChatControlPanel::draw();
-}
-
-void LLPanelIMControlPanel::onClickMuteVolume()
-{
- // By convention, we only display and toggle voice mutes, not all mutes
- LLMuteList* mute_list = LLMuteList::getInstance();
- bool is_muted = mute_list->isMuted(mAvatarID, LLMute::flagVoiceChat);
-
- LLMute mute(mAvatarID, getChild<LLTextBox>("avatar_name")->getText(), LLMute::AGENT);
- if (!is_muted)
- {
- mute_list->add(mute, LLMute::flagVoiceChat);
- }
- else
- {
- mute_list->remove(mute, LLMute::flagVoiceChat);
- }
-}
-
-void LLPanelIMControlPanel::onClickBlock()
-{
- LLMute mute(mAvatarID, getChild<LLTextBox>("avatar_name")->getText(), LLMute::AGENT);
-
- LLMuteList::getInstance()->add(mute);
-}
-
-void LLPanelIMControlPanel::onClickUnblock()
-{
- LLMute mute(mAvatarID, getChild<LLTextBox>("avatar_name")->getText(), LLMute::AGENT);
-
- LLMuteList::getInstance()->remove(mute);
-}
-
-void LLPanelIMControlPanel::onVolumeChange(const LLSD& data)
-{
- F32 volume = (F32)data.asReal();
- LLVoiceClient::getInstance()->setUserVolume(mAvatarID, volume);
-}
-
-void LLPanelIMControlPanel::onTeleportButtonClicked()
-{
- LLAvatarActions::offerTeleport(mAvatarID);
-}
-void LLPanelIMControlPanel::onPayButtonClicked()
-{
- LLAvatarActions::pay(mAvatarID);
-}
-
-void LLPanelIMControlPanel::onViewProfileButtonClicked()
-{
- LLAvatarActions::showProfile(mAvatarID);
-}
-
-void LLPanelIMControlPanel::onAddFriendButtonClicked()
-{
- LLAvatarIconCtrl* avatar_icon = getChild<LLAvatarIconCtrl>("avatar_icon");
- std::string full_name = avatar_icon->getFullName();
- LLAvatarActions::requestFriendshipDialog(mAvatarID, full_name);
-}
-
-void LLPanelIMControlPanel::onShareButtonClicked()
-{
- LLAvatarActions::share(mAvatarID);
-}
-
-void LLPanelIMControlPanel::onFocusReceived()
-{
- // Disable all the buttons (Call, Teleport, etc) if disconnected.
- if (gDisconnected)
- {
- setAllChildrenEnabled(FALSE);
- }
-}
-
-void LLPanelIMControlPanel::setSessionId(const LLUUID& session_id)
-{
- LLPanelChatControlPanel::setSessionId(session_id);
-
- LLIMModel& im_model = LLIMModel::instance();
-
- LLAvatarTracker::instance().removeParticularFriendObserver(mAvatarID, this);
- mAvatarID = im_model.getOtherParticipantID(session_id);
- LLAvatarTracker::instance().addParticularFriendObserver(mAvatarID, this);
-
- // Disable "Add friend" button for friends.
- getChildView("add_friend_btn")->setEnabled(!LLAvatarActions::isFriend(mAvatarID));
-
- // Disable "Teleport" button if friend is offline
- if(LLAvatarActions::isFriend(mAvatarID))
- {
- getChildView("teleport_btn")->setEnabled(LLAvatarTracker::instance().isBuddyOnline(mAvatarID));
- }
-
- getChild<LLAvatarIconCtrl>("avatar_icon")->setValue(mAvatarID);
-
- // Disable most profile buttons if the participant is
- // not really an SL avatar (e.g., an Avaline caller).
- LLIMModel::LLIMSession* im_session =
- im_model.findIMSession(session_id);
- if( im_session && !im_session->mOtherParticipantIsAvatar )
- {
- getChildView("view_profile_btn")->setEnabled(FALSE);
- getChildView("add_friend_btn")->setEnabled(FALSE);
-
- getChildView("share_btn")->setEnabled(FALSE);
- getChildView("teleport_btn")->setEnabled(FALSE);
- getChildView("pay_btn")->setEnabled(FALSE);
-
- getChild<LLTextBox>("avatar_name")->setValue(im_session->mName);
- getChild<LLTextBox>("avatar_name")->setToolTip(im_session->mName);
- }
- else
- {
- // If the participant is an avatar, fetch the currect name
- gCacheName->get(mAvatarID, false,
- boost::bind(&LLPanelIMControlPanel::onNameCache, this, _1, _2, _3));
- }
-}
-
-//virtual
-void LLPanelIMControlPanel::changed(U32 mask)
-{
- getChildView("add_friend_btn")->setEnabled(!LLAvatarActions::isFriend(mAvatarID));
-
- // Disable "Teleport" button if friend is offline
- if(LLAvatarActions::isFriend(mAvatarID))
- {
- getChildView("teleport_btn")->setEnabled(LLAvatarTracker::instance().isBuddyOnline(mAvatarID));
- }
-}
-
-void LLPanelIMControlPanel::onNameCache(const LLUUID& id, const std::string& full_name, bool is_group)
-{
- if ( id == mAvatarID )
- {
- std::string avatar_name = full_name;
- getChild<LLTextBox>("avatar_name")->setValue(avatar_name);
- getChild<LLTextBox>("avatar_name")->setToolTip(avatar_name);
-
- bool is_linden = LLStringUtil::endsWith(full_name, " Linden");
- getChild<LLUICtrl>("mute_btn")->setEnabled( !is_linden);
- }
-}
-
-LLPanelGroupControlPanel::LLPanelGroupControlPanel(const LLUUID& session_id):
-mParticipantList(NULL)
-{
-}
-
-BOOL LLPanelGroupControlPanel::postBuild()
-{
- childSetAction("group_info_btn", boost::bind(&LLPanelGroupControlPanel::onGroupInfoButtonClicked, this));
-
- return LLPanelChatControlPanel::postBuild();
-}
-
-LLPanelGroupControlPanel::~LLPanelGroupControlPanel()
-{
- delete mParticipantList;
- mParticipantList = NULL;
-}
-
-// virtual
-void LLPanelGroupControlPanel::draw()
-{
- // Need to resort the participant list if it's in sort by recent speaker order.
- if (mParticipantList)
- mParticipantList->update();
- LLPanelChatControlPanel::draw();
-}
-
-void LLPanelGroupControlPanel::onGroupInfoButtonClicked()
-{
- LLGroupActions::show(mGroupID);
-}
-
-void LLPanelGroupControlPanel::onSortMenuItemClicked(const LLSD& userdata)
-{
- // TODO: Check this code when when sort order menu will be added. (EM)
- if (false && !mParticipantList)
- return;
-
- std::string chosen_item = userdata.asString();
-
- if (chosen_item == "sort_name")
- {
- mParticipantList->setSortOrder(LLParticipantList::E_SORT_BY_NAME);
- }
-
-}
-
-void LLPanelGroupControlPanel::onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state)
-{
- LLPanelChatControlPanel::onVoiceChannelStateChanged(old_state, new_state);
- mParticipantList->setSpeakingIndicatorsVisible(new_state >= LLVoiceChannel::STATE_CALL_STARTED);
-}
-
-void LLPanelGroupControlPanel::setSessionId(const LLUUID& session_id)
-{
- LLPanelChatControlPanel::setSessionId(session_id);
-
- mGroupID = session_id;
-
- // for group and Ad-hoc chat we need to include agent into list
- if(!mParticipantList)
- {
- LLSpeakerMgr* speaker_manager = LLIMModel::getInstance()->getSpeakerManager(session_id);
- mParticipantList = new LLParticipantList(speaker_manager, getChild<LLAvatarList>("speakers_list"), true,false);
- }
-}
-
-
-LLPanelAdHocControlPanel::LLPanelAdHocControlPanel(const LLUUID& session_id):LLPanelGroupControlPanel(session_id)
-{
-}
-
-BOOL LLPanelAdHocControlPanel::postBuild()
-{
- //We don't need LLPanelGroupControlPanel::postBuild() to be executed as there is no group_info_btn at AdHoc chat
- return LLPanelChatControlPanel::postBuild();
-}
diff --git a/indra/newview/llpanelimcontrolpanel.h b/indra/newview/llpanelimcontrolpanel.h
index bba847b5d4..02915ec4bb 100644..100755
--- a/indra/newview/llpanelimcontrolpanel.h
+++ b/indra/newview/llpanelimcontrolpanel.h
@@ -28,14 +28,12 @@
#define LL_LLPANELIMCONTROLPANEL_H
#include "llpanel.h"
-#include "llvoicechannel.h"
#include "llcallingcard.h"
class LLParticipantList;
-class LLPanelChatControlPanel
+class LLPanelChatControlPanel
: public LLPanel
- , public LLVoiceClientStatusObserver
{
public:
LLPanelChatControlPanel() :
@@ -44,21 +42,6 @@ public:
virtual BOOL postBuild();
- void onCallButtonClicked();
- void onEndCallButtonClicked();
- void onOpenVoiceControlsClicked();
-
- // Implements LLVoiceClientStatusObserver::onChange() to enable the call
- // button when voice is available
- /*virtual*/ void onChange(EStatusType status, const std::string &channelURI, bool proximal);
-
- virtual void onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state);
-
- void updateButtons(LLVoiceChannel::EState state);
-
- // Enables/disables call button depending on voice availability
- void updateCallButton();
-
virtual void setSessionId(const LLUUID& session_id);
const LLUUID& getSessionId() { return mSessionId; }
@@ -69,41 +52,6 @@ private:
boost::signals2::connection mVoiceChannelStateChangeConnection;
};
-
-class LLPanelIMControlPanel : public LLPanelChatControlPanel, LLFriendObserver
-{
-public:
- LLPanelIMControlPanel();
- ~LLPanelIMControlPanel();
-
- BOOL postBuild();
-
- void setSessionId(const LLUUID& session_id);
-
- // LLFriendObserver trigger
- virtual void changed(U32 mask);
-
-protected:
- void onNameCache(const LLUUID& id, const std::string& full_name, bool is_group);
-
-private:
- void onViewProfileButtonClicked();
- void onAddFriendButtonClicked();
- void onShareButtonClicked();
- void onTeleportButtonClicked();
- void onPayButtonClicked();
- void onFocusReceived();
-
- void onClickMuteVolume();
- void onClickBlock();
- void onClickUnblock();
- /*virtual*/ void draw();
- void onVolumeChange(const LLSD& data);
-
- LLUUID mAvatarID;
-};
-
-
class LLPanelGroupControlPanel : public LLPanelChatControlPanel
{
public:
@@ -121,9 +69,7 @@ protected:
LLParticipantList* mParticipantList;
private:
- void onGroupInfoButtonClicked();
void onSortMenuItemClicked(const LLSD& userdata);
- /*virtual*/ void onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state);
};
class LLPanelAdHocControlPanel : public LLPanelGroupControlPanel
diff --git a/indra/newview/llpanelland.cpp b/indra/newview/llpanelland.cpp
index 04c1a86f69..5321ebc777 100644..100755
--- a/indra/newview/llpanelland.cpp
+++ b/indra/newview/llpanelland.cpp
@@ -166,7 +166,7 @@ void LLPanelLandInfo::refresh()
getChildView("button abandon land")->setEnabled(owner_release || manager_releaseable || gAgent.isGodlike());
// only mainland sims are subdividable by owner
- if (regionp->getRegionFlags() && REGION_FLAGS_ALLOW_PARCEL_CHANGES)
+ if (regionp->getRegionFlag(REGION_FLAGS_ALLOW_PARCEL_CHANGES))
{
getChildView("button subdivide land")->setEnabled(owner_divide || manager_divideable || gAgent.isGodlike());
}
diff --git a/indra/newview/llpanelland.h b/indra/newview/llpanelland.h
index 2ab1618d47..2ab1618d47 100644..100755
--- a/indra/newview/llpanelland.h
+++ b/indra/newview/llpanelland.h
diff --git a/indra/newview/llpanellandaudio.cpp b/indra/newview/llpanellandaudio.cpp
index e7bdc51b4a..e7bdc51b4a 100644..100755
--- a/indra/newview/llpanellandaudio.cpp
+++ b/indra/newview/llpanellandaudio.cpp
diff --git a/indra/newview/llpanellandaudio.h b/indra/newview/llpanellandaudio.h
index 32a45100f4..32a45100f4 100644..100755
--- a/indra/newview/llpanellandaudio.h
+++ b/indra/newview/llpanellandaudio.h
diff --git a/indra/newview/llpanellandmarkinfo.cpp b/indra/newview/llpanellandmarkinfo.cpp
index c57746ec00..5c9b968ac9 100644..100755
--- a/indra/newview/llpanellandmarkinfo.cpp
+++ b/indra/newview/llpanellandmarkinfo.cpp
@@ -209,24 +209,6 @@ void LLPanelLandmarkInfo::processParcelInfo(const LLParcelData& parcel_data)
mMaturityRatingText->setText(LLViewerRegion::accessToString(SIM_ACCESS_PG));
}
- S32 region_x;
- S32 region_y;
- S32 region_z;
-
- // If the region position is zero, grab position from the global
- if(mPosRegion.isExactlyZero())
- {
- region_x = llround(parcel_data.global_x) % REGION_WIDTH_UNITS;
- region_y = llround(parcel_data.global_y) % REGION_WIDTH_UNITS;
- region_z = llround(parcel_data.global_z);
- }
- else
- {
- region_x = llround(mPosRegion.mV[VX]);
- region_y = llround(mPosRegion.mV[VY]);
- region_z = llround(mPosRegion.mV[VZ]);
- }
-
LLSD info;
info["update_verbs"] = true;
info["global_x"] = parcel_data.global_x;
diff --git a/indra/newview/llpanellandmarkinfo.h b/indra/newview/llpanellandmarkinfo.h
index 01a6fd6b3d..01a6fd6b3d 100644..100755
--- a/indra/newview/llpanellandmarkinfo.h
+++ b/indra/newview/llpanellandmarkinfo.h
diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp
index 68a3b6d1cd..88400e4ef2 100644..100755
--- a/indra/newview/llpanellandmarks.cpp
+++ b/indra/newview/llpanellandmarks.cpp
@@ -52,6 +52,7 @@
#include "llmenubutton.h"
#include "llplacesinventorybridge.h"
#include "llplacesinventorypanel.h"
+#include "llplacesfolderview.h"
#include "lltoggleablemenu.h"
#include "llviewermenu.h"
#include "llviewerregion.h"
@@ -102,7 +103,7 @@ void LLCheckFolderState::doFolder(LLFolderViewFolder* folder)
// Counting only folders that pass the filter.
// The listener check allow us to avoid counting the folder view
// object itself because it has no listener assigned.
- if (folder->hasFilteredDescendants() && folder->getListener())
+ if (folder->getViewModelItem()->descendantsPassedFilter())
{
if (folder->isOpen())
{
@@ -138,7 +139,7 @@ private:
// virtual
void LLOpenFolderByID::doFolder(LLFolderViewFolder* folder)
{
- if (folder->getListener() && folder->getListener()->getUUID() == mFolderID)
+ if (folder->getViewModelItem() && static_cast<LLFolderViewModelItemInventory*>(folder->getViewModelItem())->getUUID() == mFolderID)
{
if (!folder->isOpen())
{
@@ -177,7 +178,7 @@ void LLLandmarksPanelObserver::changed(U32 mask)
if (!mIsLibraryLandmarksOpen && library)
{
// Search for "Landmarks" folder in the Library and open it once on start up. See EXT-4827.
- const LLUUID &landmarks_cat = gInventory.findCategoryUUIDForType(LLFolderType::FT_LANDMARK, false, true);
+ const LLUUID &landmarks_cat = gInventory.findLibraryCategoryUUIDForType(LLFolderType::FT_LANDMARK, false);
if (landmarks_cat.notNull())
{
LLOpenFolderByID opener(landmarks_cat);
@@ -247,10 +248,7 @@ void LLLandmarksPanel::onSearchEdit(const std::string& string)
LLPlacesInventoryPanel* inventory_list = dynamic_cast<LLPlacesInventoryPanel*>(tab->getAccordionView());
if (NULL == inventory_list) continue;
- if (inventory_list->getFilter())
- {
- filter_list(inventory_list, string);
- }
+ filter_list(inventory_list, string);
}
if (sFilterSubString != string)
@@ -281,28 +279,21 @@ void LLLandmarksPanel::onShowOnMap()
//virtual
void LLLandmarksPanel::onShowProfile()
{
- LLFolderViewItem* cur_item = getCurSelectedItem();
+ LLFolderViewModelItemInventory* cur_item = getCurSelectedViewModelItem();
if(!cur_item)
return;
- cur_item->getListener()->performAction(mCurrentSelectedList->getModel(),"about");
+ cur_item->performAction(mCurrentSelectedList->getModel(),"about");
}
// virtual
void LLLandmarksPanel::onTeleport()
{
- LLFolderViewItem* current_item = getCurSelectedItem();
- if (!current_item)
- {
- llwarns << "There are no selected list. No actions are performed." << llendl;
- return;
- }
-
- LLFolderViewEventListener* listenerp = current_item->getListener();
- if (listenerp && listenerp->getInventoryType() == LLInventoryType::IT_LANDMARK)
+ LLFolderViewModelItemInventory* view_model_item = getCurSelectedViewModelItem();
+ if (view_model_item && view_model_item->getInventoryType() == LLInventoryType::IT_LANDMARK)
{
- listenerp->openItem();
+ view_model_item->openItem();
}
}
@@ -313,8 +304,7 @@ bool LLLandmarksPanel::isSingleItemSelected()
if (mCurrentSelectedList != NULL)
{
- LLPlacesFolderView* root_view =
- static_cast<LLPlacesFolderView*>(mCurrentSelectedList->getRootFolder());
+ LLFolderView* root_view = mCurrentSelectedList->getRootFolder();
if (root_view->getSelectedCount() == 1)
{
@@ -360,7 +350,7 @@ void LLLandmarksPanel::onSelectorButtonClicked()
LLFolderViewItem* cur_item = mFavoritesInventoryPanel->getRootFolder()->getCurSelectedItem();
if (!cur_item) return;
- LLFolderViewEventListener* listenerp = cur_item->getListener();
+ LLFolderViewModelItemInventory* listenerp = static_cast<LLFolderViewModelItemInventory*>(cur_item->getViewModelItem());
if (listenerp->getInventoryType() == LLInventoryType::IT_LANDMARK)
{
LLSD key;
@@ -373,10 +363,7 @@ void LLLandmarksPanel::onSelectorButtonClicked()
void LLLandmarksPanel::updateShowFolderState()
{
- if (!mLandmarksInventoryPanel->getFilter())
- return;
-
- bool show_all_folders = mLandmarksInventoryPanel->getRootFolder()->getFilterSubString().empty();
+ bool show_all_folders = mLandmarksInventoryPanel->getFilterSubString().empty();
if (show_all_folders)
{
show_all_folders = category_has_descendents(mLandmarksInventoryPanel);
@@ -417,13 +404,14 @@ void LLLandmarksPanel::setItemSelected(const LLUUID& obj_id, BOOL take_keyboard_
bool LLLandmarksPanel::isLandmarkSelected() const
{
- LLFolderViewItem* current_item = getCurSelectedItem();
- if(current_item && current_item->getListener()->getInventoryType() == LLInventoryType::IT_LANDMARK)
- {
- return true;
- }
+ LLFolderViewModelItemInventory* current_item = getCurSelectedViewModelItem();
+ return current_item && (current_item->getInventoryType() == LLInventoryType::IT_LANDMARK);
+}
- return false;
+bool LLLandmarksPanel::isFolderSelected() const
+{
+ LLFolderViewModelItemInventory* current_item = getCurSelectedViewModelItem();
+ return current_item && (current_item->getInventoryType() == LLInventoryType::IT_CATEGORY);
}
bool LLLandmarksPanel::isReceivedFolderSelected() const
@@ -440,10 +428,10 @@ bool LLLandmarksPanel::isReceivedFolderSelected() const
void LLLandmarksPanel::doActionOnCurSelectedLandmark(LLLandmarkList::loaded_callback_t cb)
{
- LLFolderViewItem* cur_item = getCurSelectedItem();
- if(cur_item && cur_item->getListener()->getInventoryType() == LLInventoryType::IT_LANDMARK)
+ LLFolderViewModelItemInventory* cur_item = getCurSelectedViewModelItem();
+ if(cur_item && cur_item->getInventoryType() == LLInventoryType::IT_LANDMARK)
{
- LLLandmark* landmark = LLLandmarkActions::getLandmark(cur_item->getListener()->getUUID(), cb);
+ LLLandmark* landmark = LLLandmarkActions::getLandmark(cur_item->getUUID(), cb);
if (landmark)
{
cb(landmark);
@@ -456,6 +444,17 @@ LLFolderViewItem* LLLandmarksPanel::getCurSelectedItem() const
return mCurrentSelectedList ? mCurrentSelectedList->getRootFolder()->getCurSelectedItem() : NULL;
}
+LLFolderViewModelItemInventory* LLLandmarksPanel::getCurSelectedViewModelItem() const
+{
+ LLFolderViewItem* cur_item = getCurSelectedItem();
+ if (cur_item)
+ {
+ return static_cast<LLFolderViewModelItemInventory*>(cur_item->getViewModelItem());
+ }
+ return NULL;
+}
+
+
LLFolderViewItem* LLLandmarksPanel::selectItemInAccordionTab(LLPlacesInventoryPanel* inventory_list,
const std::string& tab_name,
const LLUUID& obj_id,
@@ -466,7 +465,7 @@ LLFolderViewItem* LLLandmarksPanel::selectItemInAccordionTab(LLPlacesInventoryPa
LLFolderView* root = inventory_list->getRootFolder();
- LLFolderViewItem* item = root->getItemByID(obj_id);
+ LLFolderViewItem* item = inventory_list->getItemByID(obj_id);
if (!item)
return NULL;
@@ -508,12 +507,12 @@ void LLLandmarksPanel::processParcelInfo(const LLParcelData& parcel_data)
// We have to make request to sever to get parcel_id and snaption_id.
if(isLandmarkSelected())
{
- LLFolderViewItem* cur_item = getCurSelectedItem();
+ LLFolderViewModelItemInventory* cur_item = getCurSelectedViewModelItem();
if (!cur_item) return;
- LLUUID id = cur_item->getListener()->getUUID();
+ LLUUID id = cur_item->getUUID();
LLInventoryItem* inv_item = mCurrentSelectedList->getModel()->getItem(id);
doActionOnCurSelectedLandmark(boost::bind(
- &LLLandmarksPanel::doProcessParcelInfo, this, _1, cur_item, inv_item, parcel_data));
+ &LLLandmarksPanel::doProcessParcelInfo, this, _1, getCurSelectedItem(), inv_item, parcel_data));
}
}
@@ -543,7 +542,7 @@ void LLLandmarksPanel::initFavoritesInventoryPanel()
mFavoritesInventoryPanel = getChild<LLPlacesInventoryPanel>("favorites_list");
initLandmarksPanel(mFavoritesInventoryPanel);
- mFavoritesInventoryPanel->getFilter()->setEmptyLookupMessage("FavoritesNoMatchingItems");
+ mFavoritesInventoryPanel->getFilter().setEmptyLookupMessage("FavoritesNoMatchingItems");
initAccordion("tab_favorites", mFavoritesInventoryPanel, true);
}
@@ -554,12 +553,7 @@ void LLLandmarksPanel::initLandmarksInventoryPanel()
initLandmarksPanel(mLandmarksInventoryPanel);
- // Check if mLandmarksInventoryPanel is properly initialized and has a Filter created.
- // In case of a dummy widget getFilter() will return NULL.
- if (mLandmarksInventoryPanel->getFilter())
- {
- mLandmarksInventoryPanel->setShowFolderState(LLInventoryFilter::SHOW_ALL_FOLDERS);
- }
+ mLandmarksInventoryPanel->setShowFolderState(LLInventoryFilter::SHOW_ALL_FOLDERS);
// subscribe to have auto-rename functionality while creating New Folder
mLandmarksInventoryPanel->setSelectCallback(boost::bind(&LLInventoryPanel::onSelectionChange, mLandmarksInventoryPanel, _1, _2));
@@ -583,7 +577,7 @@ void LLLandmarksPanel::initLibraryInventoryPanel()
initLandmarksPanel(mLibraryInventoryPanel);
// We want to fetch only "Landmarks" category from the library.
- const LLUUID &landmarks_cat = gInventory.findCategoryUUIDForType(LLFolderType::FT_LANDMARK, false, true);
+ const LLUUID &landmarks_cat = gInventory.findLibraryCategoryUUIDForType(LLFolderType::FT_LANDMARK, false);
if (landmarks_cat.notNull())
{
LLInventoryModelBackgroundFetch::instance().start(landmarks_cat);
@@ -595,12 +589,7 @@ void LLLandmarksPanel::initLibraryInventoryPanel()
void LLLandmarksPanel::initLandmarksPanel(LLPlacesInventoryPanel* inventory_list)
{
- // In case of a dummy widget further we have no Folder View widget and no Filter,
- // so further initialization leads to crash.
- if (!inventory_list->getFilter())
- return;
-
- inventory_list->getFilter()->setEmptyLookupMessage("PlacesNoMatchingItems");
+ inventory_list->getFilter().setEmptyLookupMessage("PlacesNoMatchingItems");
inventory_list->setFilterTypes(0x1 << LLInventoryType::IT_LANDMARK);
inventory_list->setSelectCallback(boost::bind(&LLLandmarksPanel::onSelectionChange, this, inventory_list, _1, _2));
@@ -665,20 +654,20 @@ void LLLandmarksPanel::deselectOtherThan(const LLPlacesInventoryPanel* inventory
{
if (inventory_list != mFavoritesInventoryPanel)
{
- mFavoritesInventoryPanel->getRootFolder()->clearSelection();
+ mFavoritesInventoryPanel->clearSelection();
}
if (inventory_list != mLandmarksInventoryPanel)
{
- mLandmarksInventoryPanel->getRootFolder()->clearSelection();
+ mLandmarksInventoryPanel->clearSelection();
}
if (inventory_list != mMyInventoryPanel)
{
- mMyInventoryPanel->getRootFolder()->clearSelection();
+ mMyInventoryPanel->clearSelection();
}
if (inventory_list != mLibraryInventoryPanel)
{
- mLibraryInventoryPanel->getRootFolder()->clearSelection();
+ mLibraryInventoryPanel->clearSelection();
}
}
@@ -720,7 +709,7 @@ void LLLandmarksPanel::initListCommandsHandlers()
void LLLandmarksPanel::updateListCommands()
{
bool add_folder_enabled = isActionEnabled("category");
- bool trash_enabled = isActionEnabled("delete");
+ bool trash_enabled = isActionEnabled("delete") && (isFolderSelected() || isLandmarkSelected());
// keep Options & Add Landmark buttons always enabled
mListCommands->getChildView(ADD_FOLDER_BUTTON_NAME)->setEnabled(add_folder_enabled);
@@ -731,14 +720,9 @@ void LLLandmarksPanel::onActionsButtonClick()
{
LLToggleableMenu* menu = mGearFolderMenu;
- LLFolderViewItem* cur_item = NULL;
if(mCurrentSelectedList)
{
- cur_item = mCurrentSelectedList->getRootFolder()->getCurSelectedItem();
- if(!cur_item)
- return;
-
- LLFolderViewEventListener* listenerp = cur_item->getListener();
+ LLFolderViewModelItemInventory* listenerp = getCurSelectedViewModelItem();
if(!listenerp)
return;
@@ -776,6 +760,9 @@ void LLLandmarksPanel::onTrashButtonClick() const
void LLLandmarksPanel::onAddAction(const LLSD& userdata) const
{
+ LLFolderViewModelItemInventory* view_model = getCurSelectedViewModelItem();
+ LLFolderViewItem* item = getCurSelectedItem();
+
std::string command_name = userdata.asString();
if("add_landmark" == command_name)
{
@@ -791,24 +778,24 @@ void LLLandmarksPanel::onAddAction(const LLSD& userdata) const
}
else if ("category" == command_name)
{
- LLFolderViewItem* item = getCurSelectedItem();
if (item && mCurrentSelectedList == mLandmarksInventoryPanel)
{
- LLFolderViewEventListener* folder_bridge = NULL;
- if (item-> getListener()->getInventoryType()
+ LLFolderViewModelItem* folder_bridge = NULL;
+
+ if (view_model->getInventoryType()
== LLInventoryType::IT_LANDMARK)
{
// for a landmark get parent folder bridge
- folder_bridge = item->getParentFolder()->getListener();
+ folder_bridge = item->getParentFolder()->getViewModelItem();
}
- else if (item-> getListener()->getInventoryType()
+ else if (view_model->getInventoryType()
== LLInventoryType::IT_CATEGORY)
{
// for a folder get its own bridge
- folder_bridge = item->getListener();
+ folder_bridge = view_model;
}
- menu_create_inventory_item(mCurrentSelectedList->getRootFolder(),
+ menu_create_inventory_item(mCurrentSelectedList,
dynamic_cast<LLFolderBridge*> (folder_bridge), LLSD(
"category"), gInventory.findCategoryUUIDForType(
LLFolderType::FT_LANDMARK));
@@ -816,7 +803,7 @@ void LLLandmarksPanel::onAddAction(const LLSD& userdata) const
else
{
//in case My Landmarks tab is completely empty (thus cannot be determined as being selected)
- menu_create_inventory_item(mLandmarksInventoryPanel->getRootFolder(), NULL, LLSD("category"),
+ menu_create_inventory_item(mLandmarksInventoryPanel, NULL, LLSD("category"),
gInventory.findCategoryUUIDForType(LLFolderType::FT_LANDMARK));
if (mMyLandmarksAccordionTab)
@@ -834,9 +821,9 @@ void LLLandmarksPanel::onClipboardAction(const LLSD& userdata) const
std::string command_name = userdata.asString();
if("copy_slurl" == command_name)
{
- LLFolderViewItem* cur_item = getCurSelectedItem();
+ LLFolderViewModelItemInventory* cur_item = getCurSelectedViewModelItem();
if(cur_item)
- LLLandmarkActions::copySLURLtoClipboard(cur_item->getListener()->getUUID());
+ LLLandmarkActions::copySLURLtoClipboard(cur_item->getUUID());
}
else if ( "paste" == command_name)
{
@@ -848,7 +835,7 @@ void LLLandmarksPanel::onClipboardAction(const LLSD& userdata) const
}
else
{
- mCurrentSelectedList->getRootFolder()->doToSelected(mCurrentSelectedList->getModel(),command_name);
+ mCurrentSelectedList->doToSelected(command_name);
}
}
@@ -893,7 +880,7 @@ void LLLandmarksPanel::onFoldingAction(const LLSD& userdata)
{
if(mCurrentSelectedList)
{
- mCurrentSelectedList->getRootFolder()->doToSelected(&gInventory, userdata);
+ mCurrentSelectedList->doToSelected(userdata);
}
}
}
@@ -915,8 +902,9 @@ bool LLLandmarksPanel::isActionEnabled(const LLSD& userdata) const
{
std::string command_name = userdata.asString();
- LLPlacesFolderView* root_folder_view = mCurrentSelectedList ?
- static_cast<LLPlacesFolderView*>(mCurrentSelectedList->getRootFolder()) : NULL;
+ LLFolderView* root_folder_view = mCurrentSelectedList
+ ? mCurrentSelectedList->getRootFolder()
+ : NULL;
if ("collapse_all" == command_name)
{
@@ -977,18 +965,13 @@ bool LLLandmarksPanel::isActionEnabled(const LLSD& userdata) const
{
if (!root_folder_view) return false;
- std::set<LLUUID> selected_uuids = root_folder_view->getSelectionList();
+ std::set<LLFolderViewItem*> selected_uuids = root_folder_view->getSelectionList();
// Allow to execute the command only if it can be applied to all selected items.
- for (std::set<LLUUID>::const_iterator iter = selected_uuids.begin(); iter != selected_uuids.end(); ++iter)
+ for (std::set<LLFolderViewItem*>::const_iterator iter = selected_uuids.begin(); iter != selected_uuids.end(); ++iter)
{
- LLFolderViewItem* item = root_folder_view->getItemByID(*iter);
+ LLFolderViewItem* item = *iter;
- // If no item is found it might be a folder id.
- if (!item)
- {
- item = root_folder_view->getFolderByID(*iter);
- }
if (!item) return false;
if (!canItemBeModified(command_name, item)) return false;
@@ -1012,10 +995,10 @@ bool LLLandmarksPanel::isActionEnabled(const LLSD& userdata) const
if ("show_on_map" == command_name)
{
- LLFolderViewItem* cur_item = root_folder_view->getCurSelectedItem();
+ LLFolderViewModelItemInventory* cur_item = getCurSelectedViewModelItem();
if (!cur_item) return false;
- LLViewerInventoryItem* inv_item = cur_item->getInventoryItem();
+ LLViewerInventoryItem* inv_item = dynamic_cast<LLViewerInventoryItem*>(cur_item->getInventoryObject());
if (!inv_item) return false;
LLUUID asset_uuid = inv_item->getAssetUUID();
@@ -1049,7 +1032,7 @@ bool LLLandmarksPanel::isActionEnabled(const LLSD& userdata) const
{
if (mCurrentSelectedList)
{
- std::set<LLUUID> selection = mCurrentSelectedList->getRootFolder()->getSelectionList();
+ std::set<LLFolderViewItem*> selection = mCurrentSelectedList->getRootFolder()->getSelectionList();
if (!selection.empty())
{
return ( 1 == selection.size() && !LLAgentPicksInfo::getInstance()->isPickLimitReached() );
@@ -1105,27 +1088,23 @@ void LLLandmarksPanel::onMenuVisibilityChange(LLUICtrl* ctrl, const LLSD& param)
{
const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH);
- std::set<LLUUID> selected_uuids = root_folder_view->getSelectionList();
+ std::set<LLFolderViewItem*> selected_items = root_folder_view->getSelectionList();
// Iterate through selected items to find out if any of these items are in Trash
// or all the items are in Trash category.
- for (std::set<LLUUID>::const_iterator iter = selected_uuids.begin(); iter != selected_uuids.end(); ++iter)
+ for (std::set<LLFolderViewItem*>::const_iterator iter = selected_items.begin(); iter != selected_items.end(); ++iter)
{
- LLFolderViewItem* item = root_folder_view->getItemByID(*iter);
+ LLFolderViewItem* item = *iter;
// If no item is found it might be a folder id.
- if (!item)
- {
- item = root_folder_view->getFolderByID(*iter);
- }
if (!item) continue;
- LLFolderViewEventListener* listenerp = item->getListener();
+ LLFolderViewModelItemInventory* listenerp = static_cast<LLFolderViewModelItemInventory*>(item->getViewModelItem());
if(!listenerp) continue;
// Trash category itself should not be included because it can't be
// actually restored from trash.
- are_all_items_in_trash &= listenerp->isItemInTrash() && *iter != trash_id;
+ are_all_items_in_trash &= listenerp->isItemInTrash() && listenerp->getUUID() != trash_id;
// If there are any selected items in Trash including the Trash category itself
// we show "Restore Item" in context menu and hide other irrelevant items.
@@ -1164,7 +1143,7 @@ bool LLLandmarksPanel::canItemBeModified(const std::string& command_name, LLFold
bool can_be_modified = false;
// landmarks can be modified in any other accordion...
- if (item->getListener()->getInventoryType() == LLInventoryType::IT_LANDMARK)
+ if (static_cast<LLFolderViewModelItemInventory*>(item->getViewModelItem())->getInventoryType() == LLInventoryType::IT_LANDMARK)
{
can_be_modified = true;
@@ -1202,7 +1181,7 @@ bool LLLandmarksPanel::canItemBeModified(const std::string& command_name, LLFold
if (can_be_modified)
{
- LLFolderViewEventListener* listenerp = item->getListener();
+ LLFolderViewModelItemInventory* listenerp = static_cast<LLFolderViewModelItemInventory*>(item->getViewModelItem());
if ("cut" == command_name)
{
@@ -1262,8 +1241,9 @@ bool LLLandmarksPanel::handleDragAndDropToTrash(BOOL drop, EDragAndDropType carg
LLInventoryItem* item = static_cast<LLInventoryItem*>(cargo_data);
if (item)
{
- LLFolderViewItem* fv_item = (mCurrentSelectedList && mCurrentSelectedList->getRootFolder()) ?
- mCurrentSelectedList->getRootFolder()->getItemByID(item->getUUID()) : NULL;
+ LLFolderViewItem* fv_item = mCurrentSelectedList
+ ? mCurrentSelectedList->getItemByID(item->getUUID())
+ : NULL;
if (fv_item)
{
@@ -1391,7 +1371,7 @@ void LLLandmarksPanel::doCreatePick(LLLandmark* landmark)
static void filter_list(LLPlacesInventoryPanel* inventory_list, const std::string& string)
{
// When search is cleared, restore the old folder state.
- if (!inventory_list->getRootFolder()->getFilterSubString().empty() && string == "")
+ if (!inventory_list->getFilterSubString().empty() && string == "")
{
inventory_list->setFilterSubString(LLStringUtil::null);
// Re-open folders that were open before
@@ -1405,7 +1385,7 @@ static void filter_list(LLPlacesInventoryPanel* inventory_list, const std::strin
}
// save current folder open state if no filter currently applied
- if (inventory_list->getRootFolder()->getFilterSubString().empty())
+ if (inventory_list->getFilterSubString().empty())
{
inventory_list->saveFolderState();
}
diff --git a/indra/newview/llpanellandmarks.h b/indra/newview/llpanellandmarks.h
index b2f4e92473..8fae0f0b67 100644..100755
--- a/indra/newview/llpanellandmarks.h
+++ b/indra/newview/llpanellandmarks.h
@@ -44,6 +44,7 @@ class LLMenuGL;
class LLToggleableMenu;
class LLInventoryPanel;
class LLPlacesInventoryPanel;
+class LLFolderViewModelItemInventory;
class LLLandmarksPanel : public LLPanelPlacesTab, LLRemoteParcelInfoObserver
{
@@ -84,9 +85,11 @@ protected:
* @return true - if current selected panel is not null and selected item is a landmark
*/
bool isLandmarkSelected() const;
+ bool isFolderSelected() const;
bool isReceivedFolderSelected() const;
void doActionOnCurSelectedLandmark(LLLandmarkList::loaded_callback_t cb);
LLFolderViewItem* getCurSelectedItem() const;
+ LLFolderViewModelItemInventory* getCurSelectedViewModelItem() const;
/**
* Selects item with "obj_id" in "inventory_list" and scrolls accordion
diff --git a/indra/newview/llpanellandmedia.cpp b/indra/newview/llpanellandmedia.cpp
index b3adfac8a2..26cd3ff1c1 100644..100755
--- a/indra/newview/llpanellandmedia.cpp
+++ b/indra/newview/llpanellandmedia.cpp
@@ -85,6 +85,7 @@ BOOL LLPanelLandMedia::postBuild()
mMediaTextureCtrl->setCommitCallback( onCommitAny, this );
mMediaTextureCtrl->setAllowNoTexture ( TRUE );
mMediaTextureCtrl->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER);
+ mMediaTextureCtrl->setDnDFilterPermMask(PERM_COPY | PERM_TRANSFER);
mMediaTextureCtrl->setNonImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER);
mMediaAutoScaleCheck = getChild<LLCheckBoxCtrl>("media_auto_scale");
diff --git a/indra/newview/llpanellandmedia.h b/indra/newview/llpanellandmedia.h
index 0e6292a25e..0e6292a25e 100644..100755
--- a/indra/newview/llpanellandmedia.h
+++ b/indra/newview/llpanellandmedia.h
diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp
index 76aadcd913..911ecaad9d 100644..100755
--- a/indra/newview/llpanellogin.cpp
+++ b/indra/newview/llpanellogin.cpp
@@ -27,6 +27,7 @@
#include "llviewerprecompiledheaders.h"
#include "llpanellogin.h"
+#include "lllayoutstack.h"
#include "indra_constants.h" // for key and mask constants
#include "llfloaterreg.h"
@@ -81,10 +82,6 @@ const S32 MAX_PASSWORD = 16;
LLPanelLogin *LLPanelLogin::sInstance = NULL;
BOOL LLPanelLogin::sCapslockDidNotification = FALSE;
-// Helper for converting a user name into the canonical "Firstname Lastname" form.
-// For new accounts without a last name "Resident" is added as a last name.
-static std::string canonicalize_username(const std::string& name);
-
class LLLoginRefreshHandler : public LLCommandHandler
{
public:
@@ -104,7 +101,6 @@ public:
// Public methods
//---------------------------------------------------------------------------
LLPanelLogin::LLPanelLogin(const LLRect &rect,
- BOOL show_server,
void (*callback)(S32 option, void* user_data),
void *cb_data)
: LLPanel(),
@@ -119,7 +115,7 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
// instance management
if (LLPanelLogin::sInstance)
{
- llwarns << "Duplicate instance of login view deleted" << llendl;
+ LL_WARNS("AppInit") << "Duplicate instance of login view deleted" << LL_ENDL;
// Don't leave bad pointer in gFocusMgr
gFocusMgr.setDefaultKeyboardFocus(NULL);
@@ -139,44 +135,83 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
mLogoImage = LLUI::getUIImage("startup_logo");
buildFromFile( "panel_login.xml");
-
+
reshape(rect.getWidth(), rect.getHeight());
- getChild<LLLineEditor>("password_edit")->setKeystrokeCallback(onPassKey, this);
+ LLLineEditor* password_edit(getChild<LLLineEditor>("password_edit"));
+ password_edit->setKeystrokeCallback(onPassKey, this);
+ // STEAM-14: When user presses Enter with this field in focus, initiate login
+ password_edit->setCommitCallback(boost::bind(&LLPanelLogin::onClickConnect, this));
// change z sort of clickable text to be behind buttons
sendChildToBack(getChildView("forgot_password_text"));
- if(LLStartUp::getStartSLURL().getType() != LLSLURL::LOCATION)
- {
- LLSLURL slurl(gSavedSettings.getString("LoginLocation"));
- LLStartUp::setStartSLURL(slurl);
- }
- updateLocationCombo(false);
+ LLComboBox* location_combo = getChild<LLComboBox>("start_location_combo");
+ updateLocationSelectorsVisibility(); // separate so that it can be called from preferences
+ location_combo->setFocusLostCallback(boost::bind(&LLPanelLogin::onLocationSLURL, this));
+
+ LLComboBox* server_choice_combo = getChild<LLComboBox>("server_combo");
+ server_choice_combo->setCommitCallback(boost::bind(&LLPanelLogin::onSelectServer, this));
- LLComboBox* server_choice_combo = sInstance->getChild<LLComboBox>("server_combo");
- server_choice_combo->setCommitCallback(onSelectServer, NULL);
- server_choice_combo->setFocusLostCallback(boost::bind(onServerComboLostFocus, _1));
- updateServerCombo();
+ // Load all of the grids, sorted, and then add a bar and the current grid at the top
+ server_choice_combo->removeall();
+ std::string current_grid = LLGridManager::getInstance()->getGrid();
+ std::map<std::string, std::string> known_grids = LLGridManager::getInstance()->getKnownGrids();
+ for (std::map<std::string, std::string>::iterator grid_choice = known_grids.begin();
+ grid_choice != known_grids.end();
+ grid_choice++)
+ {
+ if (!grid_choice->first.empty() && current_grid != grid_choice->first)
+ {
+ LL_DEBUGS("AppInit")<<"adding "<<grid_choice->first<<LL_ENDL;
+ server_choice_combo->add(grid_choice->second, grid_choice->first);
+ }
+ }
+ server_choice_combo->sortByName();
+ server_choice_combo->addSeparator(ADD_TOP);
+ LL_DEBUGS("AppInit")<<"adding current "<<current_grid<<LL_ENDL;
+ server_choice_combo->add(LLGridManager::getInstance()->getGridLabel(),
+ current_grid,
+ ADD_TOP);
+ server_choice_combo->selectFirstItem();
+
+ LLSLURL start_slurl(LLStartUp::getStartSLURL());
+ if ( !start_slurl.isSpatial() ) // has a start been established by the command line or NextLoginLocation ?
+ {
+ // no, so get the preference setting
+ std::string defaultStartLocation = gSavedSettings.getString("LoginLocation");
+ LL_INFOS("AppInit")<<"default LoginLocation '"<<defaultStartLocation<<"'"<<LL_ENDL;
+ LLSLURL defaultStart(defaultStartLocation);
+ if ( defaultStart.isSpatial() )
+ {
+ LLStartUp::setStartSLURL(defaultStart);
+ }
+ else
+ {
+ LL_INFOS("AppInit")<<"no valid LoginLocation, using home"<<LL_ENDL;
+ LLSLURL homeStart(LLSLURL::SIM_LOCATION_HOME);
+ LLStartUp::setStartSLURL(homeStart);
+ }
+ }
+ else
+ {
+ LLPanelLogin::onUpdateStartSLURL(start_slurl); // updates grid if needed
+ }
+
childSetAction("connect_btn", onClickConnect, this);
- getChild<LLPanel>("login")->setDefaultBtn("connect_btn");
+ getChild<LLPanel>("links_login_panel")->setDefaultBtn("connect_btn");
std::string channel = LLVersionInfo::getChannel();
std::string version = llformat("%s (%d)",
LLVersionInfo::getShortVersion().c_str(),
LLVersionInfo::getBuild());
- //LLTextBox* channel_text = getChild<LLTextBox>("channel_text");
- //channel_text->setTextArg("[CHANNEL]", channel); // though not displayed
- //channel_text->setTextArg("[VERSION]", version);
- //channel_text->setClickedCallback(onClickVersion, this);
LLTextBox* forgot_password_text = getChild<LLTextBox>("forgot_password_text");
forgot_password_text->setClickedCallback(onClickForgotPassword, NULL);
- LLTextBox* create_new_account_text = getChild<LLTextBox>("create_new_account_text");
- create_new_account_text->setClickedCallback(onClickNewAccount, NULL);
+ childSetAction("create_new_account_btn", onClickNewAccount, NULL);
LLTextBox* need_help_text = getChild<LLTextBox>("login_help");
need_help_text->setClickedCallback(onClickHelp, NULL);
@@ -184,17 +219,17 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
// get the web browser control
LLMediaCtrl* web_browser = getChild<LLMediaCtrl>("login_html");
web_browser->addObserver(this);
-
+
reshapeBrowser();
loadLoginPage();
-
+
// Show last logged in user favorites in "Start at" combo.
addUsersWithFavoritesToUsername();
- getChild<LLComboBox>("username_combo")->setTextChangedCallback(boost::bind(&LLPanelLogin::addFavoritesToStartLocation, this));
-
- updateLocationCombo(false);
-
+ LLComboBox* username_combo(getChild<LLComboBox>("username_combo"));
+ username_combo->setTextChangedCallback(boost::bind(&LLPanelLogin::addFavoritesToStartLocation, this));
+ // STEAM-14: When user presses Enter with this field in focus, initiate login
+ username_combo->setCommitCallback(boost::bind(&LLPanelLogin::onClickConnect, this));
}
void LLPanelLogin::addUsersWithFavoritesToUsername()
@@ -227,7 +262,6 @@ void LLPanelLogin::addFavoritesToStartLocation()
// Load favorites into the combo.
std::string user_defined_name = getChild<LLComboBox>("username_combo")->getSimple();
- std::string canonical_user_name = canonicalize_username(user_defined_name);
std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "stored_favorites.xml");
LLSD fav_llsd;
llifstream file;
@@ -240,7 +274,7 @@ void LLPanelLogin::addFavoritesToStartLocation()
// The account name in stored_favorites.xml has Resident last name even if user has
// a single word account name, so it can be compared case-insensitive with the
// user defined "firstname lastname".
- S32 res = LLStringUtil::compareInsensitive(canonical_user_name, iter->first);
+ S32 res = LLStringUtil::compareInsensitive(user_defined_name, iter->first);
if (res != 0)
{
lldebugs << "Skipping favorites for " << iter->first << llendl;
@@ -389,25 +423,27 @@ void LLPanelLogin::giveFocus()
// static
void LLPanelLogin::showLoginWidgets()
{
- // *NOTE: Mani - This may or may not be obselete code.
- // It seems to be part of the defunct? reg-in-client project.
- sInstance->getChildView("login_widgets")->setVisible( true);
- LLMediaCtrl* web_browser = sInstance->getChild<LLMediaCtrl>("login_html");
- sInstance->reshapeBrowser();
- // *TODO: Append all the usual login parameters, like first_login=Y etc.
- std::string splash_screen_url = LLGridManager::getInstance()->getLoginPage();
- web_browser->navigateTo( splash_screen_url, "text/html" );
- LLUICtrl* username_combo = sInstance->getChild<LLUICtrl>("username_combo");
- username_combo->setFocus(TRUE);
+ if (sInstance)
+ {
+ // *NOTE: Mani - This may or may not be obselete code.
+ // It seems to be part of the defunct? reg-in-client project.
+ sInstance->getChildView("login_widgets")->setVisible( true);
+ LLMediaCtrl* web_browser = sInstance->getChild<LLMediaCtrl>("login_html");
+ sInstance->reshapeBrowser();
+ // *TODO: Append all the usual login parameters, like first_login=Y etc.
+ std::string splash_screen_url = LLGridManager::getInstance()->getLoginPage();
+ web_browser->navigateTo( splash_screen_url, "text/html" );
+ LLUICtrl* username_combo = sInstance->getChild<LLUICtrl>("username_combo");
+ username_combo->setFocus(TRUE);
+ }
}
// static
void LLPanelLogin::show(const LLRect &rect,
- BOOL show_server,
void (*callback)(S32 option, void* user_data),
void* callback_data)
{
- new LLPanelLogin(rect, show_server, callback, callback_data);
+ new LLPanelLogin(rect, callback, callback_data);
if( !gFocusMgr.getKeyboardFocus() )
{
@@ -567,21 +603,6 @@ void LLPanelLogin::getFields(LLPointer<LLCredential>& credential,
remember = sInstance->getChild<LLUICtrl>("remember_check")->getValue();
}
-// static
-BOOL LLPanelLogin::isGridComboDirty()
-{
- BOOL user_picked = FALSE;
- if (!sInstance)
- {
- llwarns << "Attempted getServer with no login view shown" << llendl;
- }
- else
- {
- LLComboBox* combo = sInstance->getChild<LLComboBox>("server_combo");
- user_picked = combo->isDirty();
- }
- return user_picked;
-}
// static
BOOL LLPanelLogin::areCredentialFieldsDirty()
@@ -611,83 +632,86 @@ BOOL LLPanelLogin::areCredentialFieldsDirty()
// static
-void LLPanelLogin::updateLocationCombo( bool force_visible )
+void LLPanelLogin::updateLocationSelectorsVisibility()
{
- if (!sInstance)
+ if (sInstance)
{
- return;
+ BOOL show_start = gSavedSettings.getBOOL("ShowStartLocation");
+ sInstance->getChild<LLLayoutPanel>("start_location_panel")->setVisible(show_start);
+
+ BOOL show_server = gSavedSettings.getBOOL("ForceShowGrid");
+ sInstance->getChild<LLLayoutPanel>("grid_panel")->setVisible(show_server);
}
-
- LLComboBox* combo = sInstance->getChild<LLComboBox>("start_location_combo");
-
- switch(LLStartUp::getStartSLURL().getType())
- {
- case LLSLURL::LOCATION:
- {
-
- combo->setCurrentByIndex( 2 );
- combo->setTextEntry(LLStartUp::getStartSLURL().getLocationString());
- break;
- }
- case LLSLURL::HOME_LOCATION:
- combo->setCurrentByIndex(1);
- break;
- default:
- combo->setCurrentByIndex(0);
- break;
- }
-
- BOOL show_start = TRUE;
-
- if ( ! force_visible )
- show_start = gSavedSettings.getBOOL("ShowStartLocation");
-
- sInstance->getChildView("start_location_combo")->setVisible( show_start);
- sInstance->getChildView("start_location_text")->setVisible( show_start);
-
- BOOL show_server = gSavedSettings.getBOOL("ForceShowGrid");
- sInstance->getChildView("server_combo_text")->setVisible( show_server);
- sInstance->getChildView("server_combo")->setVisible( show_server);
}
-// static
-void LLPanelLogin::updateStartSLURL()
+// static - called from LLStartUp::setStartSLURL
+void LLPanelLogin::onUpdateStartSLURL(const LLSLURL& new_start_slurl)
{
if (!sInstance) return;
-
- LLComboBox* combo = sInstance->getChild<LLComboBox>("start_location_combo");
- S32 index = combo->getCurrentIndex();
-
- switch (index)
- {
- case 0:
- {
- LLStartUp::setStartSLURL(LLSLURL(LLSLURL::SIM_LOCATION_LAST));
- break;
- }
- case 1:
- {
- LLStartUp::setStartSLURL(LLSLURL(LLSLURL::SIM_LOCATION_HOME));
- break;
- }
- default:
+
+ LL_DEBUGS("AppInit")<<new_start_slurl.asString()<<LL_ENDL;
+
+ LLComboBox* location_combo = sInstance->getChild<LLComboBox>("start_location_combo");
+ /*
+ * Determine whether or not the new_start_slurl modifies the grid.
+ *
+ * Note that some forms that could be in the slurl are grid-agnostic.,
+ * such as "home". Other forms, such as
+ * https://grid.example.com/region/Party%20Town/20/30/5
+ * specify a particular grid; in those cases we want to change the grid
+ * and the grid selector to match the new value.
+ */
+ enum LLSLURL::SLURL_TYPE new_slurl_type = new_start_slurl.getType();
+ switch ( new_slurl_type )
+ {
+ case LLSLURL::LOCATION:
+ {
+ std::string slurl_grid = LLGridManager::getInstance()->getGrid(new_start_slurl.getGrid());
+ if ( ! slurl_grid.empty() ) // is that a valid grid?
{
- LLSLURL slurl = LLSLURL(combo->getValue().asString());
- if(slurl.getType() == LLSLURL::LOCATION)
+ if ( slurl_grid != LLGridManager::getInstance()->getGrid() ) // new grid?
{
- // we've changed the grid, so update the grid selection
- LLStartUp::setStartSLURL(slurl);
+ // the slurl changes the grid, so update everything to match
+ LLGridManager::getInstance()->setGridChoice(slurl_grid);
+
+ // update the grid selector to match the slurl
+ LLComboBox* server_combo = sInstance->getChild<LLComboBox>("server_combo");
+ std::string server_label(LLGridManager::getInstance()->getGridLabel(slurl_grid));
+ server_combo->setSimple(server_label);
+
+ updateServer(); // to change the links and splash screen
}
- break;
- }
+ location_combo->setTextEntry(new_start_slurl.getLocationString());
+ }
+ else
+ {
+ // the grid specified by the slurl is not known
+ LLNotificationsUtil::add("InvalidLocationSLURL");
+ LL_WARNS("AppInit")<<"invalid LoginLocation:"<<new_start_slurl.asString()<<LL_ENDL;
+ location_combo->setTextEntry(LLStringUtil::null);
+ }
+ }
+ break;
+
+ case LLSLURL::HOME_LOCATION:
+ location_combo->setCurrentByIndex(1); // home location
+ break;
+
+ case LLSLURL::LAST_LOCATION:
+ location_combo->setCurrentByIndex(0); // last location
+ break;
+
+ default:
+ LL_WARNS("AppInit")<<"invalid login slurl, using home"<<LL_ENDL;
+ location_combo->setCurrentByIndex(1); // home location
+ break;
}
}
-
void LLPanelLogin::setLocation(const LLSLURL& slurl)
{
- LLStartUp::setStartSLURL(slurl);
- updateServer();
+ LL_DEBUGS("AppInit")<<"setting Location "<<slurl.asString()<<LL_ENDL;
+ LLStartUp::setStartSLURL(slurl); // calls onUpdateStartSLURL, above
}
// static
@@ -705,13 +729,14 @@ void LLPanelLogin::closePanel()
// static
void LLPanelLogin::setAlwaysRefresh(bool refresh)
{
- if (LLStartUp::getStartupState() >= STATE_LOGIN_CLEANUP) return;
-
- LLMediaCtrl* web_browser = sInstance->getChild<LLMediaCtrl>("login_html");
-
- if (web_browser)
+ if (sInstance && LLStartUp::getStartupState() < STATE_LOGIN_CLEANUP)
{
- web_browser->setAlwaysRefresh(refresh);
+ LLMediaCtrl* web_browser = sInstance->getChild<LLMediaCtrl>("login_html");
+
+ if (web_browser)
+ {
+ web_browser->setAlwaysRefresh(refresh);
+ }
}
}
@@ -720,82 +745,53 @@ void LLPanelLogin::setAlwaysRefresh(bool refresh)
void LLPanelLogin::loadLoginPage()
{
if (!sInstance) return;
-
- std::ostringstream oStr;
- std::string login_page = LLGridManager::getInstance()->getLoginPage();
+ LLURI login_page = LLURI(LLGridManager::getInstance()->getLoginPage());
+ LLSD params(login_page.queryMap());
- oStr << login_page;
-
- // Use the right delimeter depending on how LLURI parses the URL
- LLURI login_page_uri = LLURI(login_page);
-
- std::string first_query_delimiter = "&";
- if (login_page_uri.queryMap().size() == 0)
- {
- first_query_delimiter = "?";
- }
+ LL_DEBUGS("AppInit") << "login_page: " << login_page << LL_ENDL;
// Language
- std::string language = LLUI::getLanguage();
- oStr << first_query_delimiter<<"lang=" << language;
-
+ params["lang"] = LLUI::getLanguage();
+
// First Login?
if (gSavedSettings.getBOOL("FirstLoginThisInstall"))
{
- oStr << "&firstlogin=TRUE";
+ params["firstlogin"] = "TRUE"; // not bool: server expects string TRUE
}
// Channel and Version
- std::string version = llformat("%s (%d)",
- LLVersionInfo::getShortVersion().c_str(),
- LLVersionInfo::getBuild());
+ params["version"] = llformat("%s (%d)",
+ LLVersionInfo::getShortVersion().c_str(),
+ LLVersionInfo::getBuild());
+ params["channel"] = LLVersionInfo::getChannel();
+
+ // Grid
+ params["grid"] = LLGridManager::getInstance()->getGridId();
- char* curl_channel = curl_escape(LLVersionInfo::getChannel().c_str(), 0);
- char* curl_version = curl_escape(version.c_str(), 0);
+ // add OS info
+ params["os"] = LLAppViewer::instance()->getOSInfo().getOSStringSimple();
- oStr << "&channel=" << curl_channel;
- oStr << "&version=" << curl_version;
+ // sourceid
+ params["sourceid"] = gSavedSettings.getString("sourceid");
- curl_free(curl_channel);
- curl_free(curl_version);
+ // Make an LLURI with this augmented info
+ LLURI login_uri(LLURI::buildHTTP(login_page.authority(),
+ login_page.path(),
+ params));
- // Grid
- char* curl_grid = curl_escape(LLGridManager::getInstance()->getGridLabel().c_str(), 0);
- oStr << "&grid=" << curl_grid;
- curl_free(curl_grid);
-
- // add OS info
- char * os_info = curl_escape(LLAppViewer::instance()->getOSInfo().getOSStringSimple().c_str(), 0);
- oStr << "&os=" << os_info;
- curl_free(os_info);
-
gViewerWindow->setMenuBackgroundColor(false, !LLGridManager::getInstance()->isInProductionGrid());
-
+
LLMediaCtrl* web_browser = sInstance->getChild<LLMediaCtrl>("login_html");
- if (web_browser->getCurrentNavUrl() != oStr.str())
+ if (web_browser->getCurrentNavUrl() != login_uri.asString())
{
- web_browser->navigateTo( oStr.str(), "text/html" );
+ LL_DEBUGS("AppInit") << "loading: " << login_uri << LL_ENDL;
+ web_browser->navigateTo( login_uri.asString(), "text/html" );
}
}
void LLPanelLogin::handleMediaEvent(LLPluginClassMedia* /*self*/, EMediaEvent event)
{
- if(event == MEDIA_EVENT_NAVIGATE_COMPLETE)
- {
- LLMediaCtrl* web_browser = sInstance->getChild<LLMediaCtrl>("login_html");
- if (web_browser)
- {
- // *HACK HACK HACK HACK!
- /* Stuff a Tab key into the browser now so that the first field will
- ** get the focus! The embedded javascript on the page that properly
- ** sets the initial focus in a real web browser is not working inside
- ** the viewer, so this is an UGLY HACK WORKAROUND for now.
- */
- // Commented out as it's not reliable
- //web_browser->handleKey(KEY_TAB, MASK_NONE, false);
- }
- }
}
//---------------------------------------------------------------------------
@@ -812,15 +808,9 @@ void LLPanelLogin::onClickConnect(void *)
LLComboBox* combo = sInstance->getChild<LLComboBox>("server_combo");
LLSD combo_val = combo->getSelectedValue();
- if (combo_val.isUndefined())
- {
- combo_val = combo->getValue();
- }
- if(combo_val.isUndefined())
- {
- LLNotificationsUtil::add("StartRegionEmpty");
- return;
- }
+
+ // the grid definitions may come from a user-supplied grids.xml, so they may not be good
+ LL_DEBUGS("AppInit")<<"grid "<<combo_val.asString()<<LL_ENDL;
try
{
LLGridManager::getInstance()->setGridChoice(combo_val.asString());
@@ -828,13 +818,14 @@ void LLPanelLogin::onClickConnect(void *)
catch (LLInvalidGridName ex)
{
LLSD args;
- args["GRID"] = combo_val.asString();
+ args["GRID"] = ex.name();
LLNotificationsUtil::add("InvalidGrid", args);
return;
}
- updateStartSLURL();
- std::string username = sInstance->getChild<LLUICtrl>("username_combo")->getValue().asString();
+ // The start location SLURL has already been sent to LLStartUp::setStartSLURL
+
+ std::string username = sInstance->getChild<LLUICtrl>("username_combo")->getValue().asString();
if(username.empty())
{
@@ -877,7 +868,10 @@ void LLPanelLogin::onClickConnect(void *)
// static
void LLPanelLogin::onClickNewAccount(void*)
{
- LLWeb::loadURLExternal(sInstance->getString("create_account_url"));
+ if (sInstance)
+ {
+ LLWeb::loadURLExternal(LLTrans::getString("create_account_url"));
+ }
}
@@ -913,7 +907,7 @@ void LLPanelLogin::onPassKey(LLLineEditor* caller, void* user_data)
This->mPasswordModified = TRUE;
if (gKeyboard->getKeyDown(KEY_CAPSLOCK) && sCapslockDidNotification == FALSE)
{
-// *TODO: use another way to notify user about enabled caps lock, see EXT-6858
+ // *TODO: use another way to notify user about enabled caps lock, see EXT-6858
sCapslockDidNotification = TRUE;
}
}
@@ -921,135 +915,95 @@ void LLPanelLogin::onPassKey(LLLineEditor* caller, void* user_data)
void LLPanelLogin::updateServer()
{
- try
+ if (sInstance)
{
-
- updateServerCombo();
- // if they've selected another grid, we should load the credentials
- // for that grid and set them to the UI.
- if(sInstance && !sInstance->areCredentialFieldsDirty())
+ try
{
- LLPointer<LLCredential> credential = gSecAPIHandler->loadCredential(LLGridManager::getInstance()->getGrid());
- bool remember = sInstance->getChild<LLUICtrl>("remember_check")->getValue();
- sInstance->setFields(credential, remember);
- }
- // grid changed so show new splash screen (possibly)
- loadLoginPage();
- updateLocationCombo(LLStartUp::getStartSLURL().getType() == LLSLURL::LOCATION);
- }
- catch (LLInvalidGridName ex)
- {
- // do nothing
- }
-}
+ // if they've selected another grid, we should load the credentials
+ // for that grid and set them to the UI.
+ if(!sInstance->areCredentialFieldsDirty())
+ {
+ LLPointer<LLCredential> credential = gSecAPIHandler->loadCredential(LLGridManager::getInstance()->getGrid());
+ bool remember = sInstance->getChild<LLUICtrl>("remember_check")->getValue();
+ sInstance->setFields(credential, remember);
+ }
-void LLPanelLogin::updateServerCombo()
-{
- if (!sInstance)
- {
- return;
- }
- // We add all of the possible values, sorted, and then add a bar and the current value at the top
- LLComboBox* server_choice_combo = sInstance->getChild<LLComboBox>("server_combo");
- server_choice_combo->removeall();
+ // update the login panel links
+ bool system_grid = LLGridManager::getInstance()->isSystemGrid();
- std::map<std::string, std::string> known_grids = LLGridManager::getInstance()->getKnownGrids(!gSavedSettings.getBOOL("ShowBetaGrids"));
+ // Want to vanish not only create_new_account_btn, but also the
+ // title text over it, so turn on/off the whole layout_panel element.
+ sInstance->getChild<LLLayoutPanel>("links")->setVisible(system_grid);
+ sInstance->getChildView("forgot_password_text")->setVisible(system_grid);
- for (std::map<std::string, std::string>::iterator grid_choice = known_grids.begin();
- grid_choice != known_grids.end();
- grid_choice++)
- {
- if (!grid_choice->first.empty())
+ // grid changed so show new splash screen (possibly)
+ loadLoginPage();
+ }
+ catch (LLInvalidGridName ex)
{
- server_choice_combo->add(grid_choice->second, grid_choice->first);
+ LL_WARNS("AppInit")<<"server '"<<ex.name()<<"' selection failed"<<LL_ENDL;
+ LLSD args;
+ args["GRID"] = ex.name();
+ LLNotificationsUtil::add("InvalidGrid", args);
+ return;
}
}
- server_choice_combo->sortByName();
-
- server_choice_combo->addSeparator(ADD_TOP);
-
- server_choice_combo->add(LLGridManager::getInstance()->getGridLabel(),
- LLGridManager::getInstance()->getGrid(), ADD_TOP);
-
- server_choice_combo->selectFirstItem();
}
-// static
-void LLPanelLogin::onSelectServer(LLUICtrl*, void*)
+void LLPanelLogin::onSelectServer()
{
- // *NOTE: The paramters for this method are ignored.
- // LLPanelLogin::onServerComboLostFocus(LLFocusableElement* fe, void*)
- // calls this method.
- LL_INFOS("AppInit") << "onSelectServer" << LL_ENDL;
// The user twiddled with the grid choice ui.
// apply the selection to the grid setting.
LLPointer<LLCredential> credential;
- LLComboBox* combo = sInstance->getChild<LLComboBox>("server_combo");
- LLSD combo_val = combo->getSelectedValue();
- if (combo_val.isUndefined())
- {
- combo_val = combo->getValue();
- }
+ LLComboBox* server_combo = getChild<LLComboBox>("server_combo");
+ LLSD server_combo_val = server_combo->getSelectedValue();
+ LL_INFOS("AppInit") << "grid "<<server_combo_val.asString()<< LL_ENDL;
+ LLGridManager::getInstance()->setGridChoice(server_combo_val.asString());
- combo = sInstance->getChild<LLComboBox>("start_location_combo");
- combo->setCurrentByIndex(1);
- LLStartUp::setStartSLURL(LLSLURL(gSavedSettings.getString("LoginLocation")));
- LLGridManager::getInstance()->setGridChoice(combo_val.asString());
- // This new selection will override preset uris
- // from the command line.
- updateServer();
- updateLocationCombo(false);
- updateLoginPanelLinks();
-}
-
-void LLPanelLogin::onServerComboLostFocus(LLFocusableElement* fe)
-{
- if (!sInstance)
- {
- return;
- }
-
- LLComboBox* combo = sInstance->getChild<LLComboBox>("server_combo");
- if(fe == combo)
+ /*
+ * Determine whether or not the value in the start_location_combo makes sense
+ * with the new grid value.
+ *
+ * Note that some forms that could be in the location combo are grid-agnostic,
+ * such as "MyRegion/128/128/0". There could be regions with that name on any
+ * number of grids, so leave them alone. Other forms, such as
+ * https://grid.example.com/region/Party%20Town/20/30/5 specify a particular
+ * grid; in those cases we want to clear the location.
+ */
+ LLComboBox* location_combo = getChild<LLComboBox>("start_location_combo");
+ S32 index = location_combo->getCurrentIndex();
+ switch (index)
{
- onSelectServer(combo, NULL);
+ case 0: // last location
+ case 1: // home location
+ // do nothing - these are grid-agnostic locations
+ break;
+
+ default:
+ {
+ std::string location = location_combo->getValue().asString();
+ LLSLURL slurl(location); // generata a slurl from the location combo contents
+ if ( slurl.getType() == LLSLURL::LOCATION
+ && slurl.getGrid() != LLGridManager::getInstance()->getGrid()
+ )
+ {
+ // the grid specified by the location is not this one, so clear the combo
+ location_combo->setCurrentByIndex(0); // last location on the new grid
+ location_combo->setTextEntry(LLStringUtil::null);
+ }
+ }
+ break;
}
-}
-void LLPanelLogin::updateLoginPanelLinks()
-{
- LLSD grid_data;
- LLGridManager::getInstance()->getGridInfo(grid_data);
- bool system_grid = grid_data.has(GRID_IS_SYSTEM_GRID_VALUE);
-
- // need to call through sInstance, as it's called from onSelectServer, which
- // is static.
- sInstance->getChildView("create_new_account_text")->setVisible( system_grid);
- sInstance->getChildView("forgot_password_text")->setVisible( system_grid);
+ updateServer();
}
-std::string canonicalize_username(const std::string& name)
+void LLPanelLogin::onLocationSLURL()
{
- std::string cname = name;
- LLStringUtil::trim(cname);
-
- // determine if the username is a first/last form or not.
- size_t separator_index = cname.find_first_of(" ._");
- std::string first = cname.substr(0, separator_index);
- std::string last;
- if (separator_index != cname.npos)
- {
- last = cname.substr(separator_index+1, cname.npos);
- LLStringUtil::trim(last);
- }
- else
- {
- // ...on Linden grids, single username users as considered to have
- // last name "Resident"
- last = "Resident";
- }
+ LLComboBox* location_combo = getChild<LLComboBox>("start_location_combo");
+ std::string location = location_combo->getValue().asString();
+ LL_DEBUGS("AppInit")<<location<<LL_ENDL;
- // Username in traditional "firstname lastname" form.
- return first + ' ' + last;
+ LLStartUp::setStartSLURL(location); // calls onUpdateStartSLURL, above
}
diff --git a/indra/newview/llpanellogin.h b/indra/newview/llpanellogin.h
index a439c4ff6b..c71cfc3783 100644..100755
--- a/indra/newview/llpanellogin.h
+++ b/indra/newview/llpanellogin.h
@@ -44,7 +44,7 @@ class LLPanelLogin:
{
LOG_CLASS(LLPanelLogin);
public:
- LLPanelLogin(const LLRect &rect, BOOL show_server,
+ LLPanelLogin(const LLRect &rect,
void (*callback)(S32 option, void* user_data),
void *callback_data);
~LLPanelLogin();
@@ -57,7 +57,7 @@ public:
// hidden on startup for reg-in-client
static void showLoginWidgets();
- static void show(const LLRect &rect, BOOL show_server,
+ static void show(const LLRect &rect,
void (*callback)(S32 option, void* user_data),
void* callback_data);
@@ -65,11 +65,12 @@ public:
static void getFields(LLPointer<LLCredential>& credential, BOOL& remember);
- static BOOL isGridComboDirty();
static BOOL areCredentialFieldsDirty();
static void setLocation(const LLSLURL& slurl);
- static void updateLocationCombo(bool force_visible); // simply update the combo box
+ /// Call when preferences that control visibility may have changed
+ static void updateLocationSelectorsVisibility();
+
static void closePanel();
void setSiteIsAlive( bool alive );
@@ -82,22 +83,24 @@ public:
/*virtual*/ void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event);
static void updateServer(); // update the combo box, change the login page to the new server, clear the combo
+ /// to be called from LLStartUp::setStartSLURL
+ static void onUpdateStartSLURL(const LLSLURL& new_start_slurl);
+
private:
friend class LLPanelLoginListener;
void reshapeBrowser();
void addFavoritesToStartLocation();
void addUsersWithFavoritesToUsername();
+ void onSelectServer();
+ void onLocationSLURL();
+
static void onClickConnect(void*);
static void onClickNewAccount(void*);
static void onClickVersion(void*);
static void onClickForgotPassword(void*);
static void onClickHelp(void*);
static void onPassKey(LLLineEditor* caller, void* user_data);
- static void onSelectServer(LLUICtrl*, void*);
- static void onServerComboLostFocus(LLFocusableElement*);
static void updateServerCombo();
- static void updateStartSLURL();
- static void updateLoginPanelLinks();
private:
LLPointer<LLUIImage> mLogoImage;
diff --git a/indra/newview/llpanelloginlistener.cpp b/indra/newview/llpanelloginlistener.cpp
index 33efde11f3..33efde11f3 100644..100755
--- a/indra/newview/llpanelloginlistener.cpp
+++ b/indra/newview/llpanelloginlistener.cpp
diff --git a/indra/newview/llpanelloginlistener.h b/indra/newview/llpanelloginlistener.h
index 45dcea269c..45dcea269c 100644..100755
--- a/indra/newview/llpanelloginlistener.h
+++ b/indra/newview/llpanelloginlistener.h
diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp
index c11597f532..1ff0bfd091 100644..100755
--- a/indra/newview/llpanelmaininventory.cpp
+++ b/indra/newview/llpanelmaininventory.cpp
@@ -47,12 +47,14 @@
#include "llresmgr.h"
#include "llscrollcontainer.h"
#include "llsdserialize.h"
+#include "llsdparam.h"
#include "llspinctrl.h"
#include "lltoggleablemenu.h"
#include "lltooldraganddrop.h"
#include "llviewermenu.h"
#include "llviewertexturelist.h"
#include "llsidepanelinventory.h"
+#include "llfolderview.h"
const std::string FILTERS_FILENAME("filters.xml");
@@ -105,7 +107,6 @@ LLPanelMainInventory::LLPanelMainInventory(const LLPanel::Params& p)
mMenuAdd(NULL),
mNeedUploadCost(true)
{
- LLMemType mt(LLMemType::MTYPE_INVENTORY_VIEW_INIT);
// Menu Callbacks (non contex menus)
mCommitCallbackRegistrar.add("Inventory.DoToSelected", boost::bind(&LLPanelMainInventory::doToSelected, this, _2));
mCommitCallbackRegistrar.add("Inventory.CloseAllFolders", boost::bind(&LLPanelMainInventory::closeAllFolders, this));
@@ -116,7 +117,7 @@ LLPanelMainInventory::LLPanelMainInventory(const LLPanel::Params& p)
mCommitCallbackRegistrar.add("Inventory.ShowFilters", boost::bind(&LLPanelMainInventory::toggleFindOptions, this));
mCommitCallbackRegistrar.add("Inventory.ResetFilters", boost::bind(&LLPanelMainInventory::resetFilters, this));
mCommitCallbackRegistrar.add("Inventory.SetSortBy", boost::bind(&LLPanelMainInventory::setSortBy, this, _2));
- mCommitCallbackRegistrar.add("Inventory.Share", boost::bind(&LLAvatarActions::shareWithAvatars));
+ mCommitCallbackRegistrar.add("Inventory.Share", boost::bind(&LLAvatarActions::shareWithAvatars, this));
mSavedFolderState = new LLSaveFolderState();
mSavedFolderState->setApply(FALSE);
@@ -129,7 +130,9 @@ BOOL LLPanelMainInventory::postBuild()
mFilterTabs = getChild<LLTabContainer>("inventory filter tabs");
mFilterTabs->setCommitCallback(boost::bind(&LLPanelMainInventory::onFilterSelected, this));
- //panel->getFilter()->markDefault();
+ mCounterCtrl = getChild<LLUICtrl>("ItemcountText");
+
+ //panel->getFilter().markDefault();
// Set up the default inv. panel/filter settings.
mActivePanel = getChild<LLInventoryPanel>("All Items");
@@ -137,7 +140,7 @@ BOOL LLPanelMainInventory::postBuild()
{
// "All Items" is the previous only view, so it gets the InventorySortOrder
mActivePanel->setSortOrder(gSavedSettings.getU32(LLInventoryPanel::DEFAULT_SORT_ORDER));
- mActivePanel->getFilter()->markDefault();
+ mActivePanel->getFilter().markDefault();
mActivePanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState);
mActivePanel->setSelectCallback(boost::bind(&LLPanelMainInventory::onSelectionChange, this, mActivePanel, _1, _2));
mResortActivePanel = true;
@@ -148,7 +151,7 @@ BOOL LLPanelMainInventory::postBuild()
recent_items_panel->setSinceLogoff(TRUE);
recent_items_panel->setSortOrder(LLInventoryFilter::SO_DATE);
recent_items_panel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
- recent_items_panel->getFilter()->markDefault();
+ recent_items_panel->getFilter().markDefault();
recent_items_panel->setSelectCallback(boost::bind(&LLPanelMainInventory::onSelectionChange, this, recent_items_panel, _1, _2));
}
@@ -167,11 +170,14 @@ BOOL LLPanelMainInventory::postBuild()
// Note that the "All Items" settings do not persist.
if(recent_items_panel)
{
- if(savedFilterState.has(recent_items_panel->getFilter()->getName()))
+ if(savedFilterState.has(recent_items_panel->getFilter().getName()))
{
LLSD recent_items = savedFilterState.get(
- recent_items_panel->getFilter()->getName());
- recent_items_panel->getFilter()->fromLLSD(recent_items);
+ recent_items_panel->getFilter().getName());
+ LLInventoryFilter::Params p;
+ LLParamSDParser parser;
+ parser.readSD(recent_items, p);
+ recent_items_panel->getFilter().fromParams(p);
}
}
@@ -208,24 +214,28 @@ LLPanelMainInventory::~LLPanelMainInventory( void )
LLInventoryPanel* all_items_panel = getChild<LLInventoryPanel>("All Items");
if (all_items_panel)
{
- LLInventoryFilter* filter = all_items_panel->getFilter();
- if (filter)
+ LLSD filterState;
+ LLInventoryPanel::InventoryState p;
+ all_items_panel->getFilter().toParams(p.filter);
+ all_items_panel->getRootViewModel().getSorter().toParams(p.sort);
+ if (p.validateBlock(false))
{
- LLSD filterState;
- filter->toLLSD(filterState);
- filterRoot[filter->getName()] = filterState;
+ LLParamSDParser().writeSD(filterState, p);
+ filterRoot[all_items_panel->getName()] = filterState;
}
}
- LLInventoryPanel* recent_items_panel = getChild<LLInventoryPanel>("Recent Items");
- if (recent_items_panel)
+ LLInventoryPanel* panel = findChild<LLInventoryPanel>("Recent Items");
+ if (panel)
{
- LLInventoryFilter* filter = recent_items_panel->getFilter();
- if (filter)
+ LLSD filterState;
+ LLInventoryPanel::InventoryState p;
+ panel->getFilter().toParams(p.filter);
+ panel->getRootViewModel().getSorter().toParams(p.sort);
+ if (p.validateBlock(false))
{
- LLSD filterState;
- filter->toLLSD(filterState);
- filterRoot[filter->getName()] = filterState;
+ LLParamSDParser().writeSD(filterState, p);
+ filterRoot[panel->getName()] = filterState;
}
}
@@ -285,7 +295,7 @@ BOOL LLPanelMainInventory::handleKeyHere(KEY key, MASK mask)
void LLPanelMainInventory::doToSelected(const LLSD& userdata)
{
- getPanel()->getRootFolder()->doToSelected(&gInventory, userdata);
+ getPanel()->doToSelected(userdata);
}
void LLPanelMainInventory::closeAllFolders()
@@ -306,13 +316,14 @@ void LLPanelMainInventory::newWindow()
void LLPanelMainInventory::doCreate(const LLSD& userdata)
{
- menu_create_inventory_item(getPanel()->getRootFolder(), NULL, userdata);
+ reset_inventory_filter();
+ menu_create_inventory_item(getPanel(), NULL, userdata);
}
void LLPanelMainInventory::resetFilters()
{
LLFloaterInventoryFinder *finder = getFinder();
- getActivePanel()->getFilter()->resetDefault();
+ getActivePanel()->getFilter().resetDefault();
if (finder)
{
finder->updateElementsFromFilter();
@@ -417,7 +428,7 @@ void LLPanelMainInventory::onFilterEdit(const std::string& search_string )
}
// save current folder open state if no filter currently applied
- if (!mActivePanel->getRootFolder()->isFilterModified())
+ if (!mActivePanel->getFilter().isNotDefault())
{
mSavedFolderState->setApply(FALSE);
mActivePanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState);
@@ -479,13 +490,13 @@ void LLPanelMainInventory::onFilterSelected()
}
setFilterSubString(mFilterSubString);
- LLInventoryFilter* filter = mActivePanel->getFilter();
+ LLInventoryFilter& filter = mActivePanel->getFilter();
LLFloaterInventoryFinder *finder = getFinder();
if (finder)
{
- finder->changeFilter(filter);
+ finder->changeFilter(&filter);
}
- if (filter->isActive())
+ if (filter.isActive())
{
// If our filter is active we may be the first thing requiring a fetch so we better start it here.
LLInventoryModelBackgroundFetch::instance().start();
@@ -531,6 +542,13 @@ void LLPanelMainInventory::changed(U32)
updateItemcountText();
}
+void LLPanelMainInventory::setFocusFilterEditor()
+{
+ if(mFilterEditor)
+ {
+ mFilterEditor->setFocus(true);
+ }
+}
// virtual
void LLPanelMainInventory::draw()
@@ -557,7 +575,7 @@ void LLPanelMainInventory::draw()
void LLPanelMainInventory::updateItemcountText()
{
// *TODO: Calling setlocale() on each frame may be inefficient.
- LLLocale locale(LLStringUtil::getLocale());
+ //LLLocale locale(LLStringUtil::getLocale());
std::string item_count_string;
LLResMgr::getInstance()->getIntegerString(item_count_string, gInventory.getItemCount());
@@ -580,8 +598,7 @@ void LLPanelMainInventory::updateItemcountText()
text = getString("ItemcountUnknown");
}
- // *TODO: Cache the LLUICtrl* for the ItemcountText control
- getChild<LLUICtrl>("ItemcountText")->setValue(text);
+ mCounterCtrl->setValue(text);
}
void LLPanelMainInventory::onFocusReceived()
@@ -598,12 +615,11 @@ void LLPanelMainInventory::onFocusReceived()
void LLPanelMainInventory::setFilterTextFromFilter()
{
- mFilterText = mActivePanel->getFilter()->getFilterText();
+ mFilterText = mActivePanel->getFilter().getFilterText();
}
void LLPanelMainInventory::toggleFindOptions()
{
- LLMemType mt(LLMemType::MTYPE_INVENTORY_VIEW_TOGGLE);
LLFloater *floater = getFinder();
if (!floater)
{
@@ -648,7 +664,7 @@ LLFloaterInventoryFinder* LLPanelMainInventory::getFinder()
LLFloaterInventoryFinder::LLFloaterInventoryFinder(LLPanelMainInventory* inventory_view) :
LLFloater(LLSD()),
mPanelMainInventory(inventory_view),
- mFilter(inventory_view->getPanel()->getFilter())
+ mFilter(&inventory_view->getPanel()->getFilter())
{
buildFromFile("floater_inventory_view_finder.xml");
updateElementsFromFilter();
@@ -725,7 +741,6 @@ void LLFloaterInventoryFinder::updateElementsFromFilter()
void LLFloaterInventoryFinder::draw()
{
- LLMemType mt(LLMemType::MTYPE_INVENTORY_DRAW);
U64 filter = 0xffffffffffffffffULL;
BOOL filtered_by_all_types = TRUE;
@@ -961,7 +976,7 @@ void LLPanelMainInventory::onTrashButtonClick()
void LLPanelMainInventory::onClipboardAction(const LLSD& userdata)
{
std::string command_name = userdata.asString();
- getActivePanel()->getRootFolder()->doToSelected(getActivePanel()->getModel(),command_name);
+ getActivePanel()->doToSelected(command_name);
}
void LLPanelMainInventory::saveTexture(const LLSD& userdata)
@@ -972,7 +987,7 @@ void LLPanelMainInventory::saveTexture(const LLSD& userdata)
return;
}
- const LLUUID& item_id = current_item->getListener()->getUUID();
+ const LLUUID& item_id = static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->getUUID();
LLPreviewTexture* preview_texture = LLFloaterReg::showTypedInstance<LLPreviewTexture>("preview_texture", LLSD(item_id), TAKE_FOCUS_YES);
if (preview_texture)
{
@@ -1045,7 +1060,7 @@ void LLPanelMainInventory::onCustomAction(const LLSD& userdata)
{
return;
}
- const LLUUID item_id = current_item->getListener()->getUUID();
+ const LLUUID item_id = static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->getUUID();
LLViewerInventoryItem *item = gInventory.getItem(item_id);
if (item)
{
@@ -1060,7 +1075,7 @@ void LLPanelMainInventory::onCustomAction(const LLSD& userdata)
{
return;
}
- current_item->getListener()->performAction(getActivePanel()->getModel(), "goto");
+ static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->performAction(getActivePanel()->getModel(), "goto");
}
if (command_name == "find_links")
@@ -1070,17 +1085,17 @@ void LLPanelMainInventory::onCustomAction(const LLSD& userdata)
{
return;
}
- const LLUUID& item_id = current_item->getListener()->getUUID();
- const std::string &item_name = current_item->getListener()->getName();
+ const LLUUID& item_id = static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->getUUID();
+ const std::string &item_name = current_item->getViewModelItem()->getName();
mFilterSubString = item_name;
- LLInventoryFilter *filter = mActivePanel->getFilter();
- filter->setFilterSubString(item_name);
+ LLInventoryFilter &filter = mActivePanel->getFilter();
+ filter.setFilterSubString(item_name);
mFilterEditor->setText(item_name);
mFilterEditor->setFocus(TRUE);
- filter->setFilterUUID(item_id);
- filter->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
- filter->setFilterLinks(LLInventoryFilter::FILTERLINK_ONLY_LINKS);
+ filter.setFilterUUID(item_id);
+ filter.setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
+ filter.setFilterLinks(LLInventoryFilter::FILTERLINK_ONLY_LINKS);
}
}
@@ -1089,11 +1104,11 @@ bool LLPanelMainInventory::isSaveTextureEnabled(const LLSD& userdata)
LLFolderViewItem* current_item = getActivePanel()->getRootFolder()->getCurSelectedItem();
if (current_item)
{
- LLViewerInventoryItem *inv_item = current_item->getInventoryItem();
+ LLViewerInventoryItem *inv_item = dynamic_cast<LLViewerInventoryItem*>(static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->getInventoryObject());
if(inv_item)
{
bool can_save = inv_item->checkPermissionsSet(PERM_ITEM_UNRESTRICTED);
- LLInventoryType::EType curr_type = current_item->getListener()->getInventoryType();
+ LLInventoryType::EType curr_type = static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->getInventoryType();
return can_save && (curr_type == LLInventoryType::IT_TEXTURE || curr_type == LLInventoryType::IT_SNAPSHOT);
}
}
@@ -1105,28 +1120,7 @@ BOOL LLPanelMainInventory::isActionEnabled(const LLSD& userdata)
const std::string command_name = userdata.asString();
if (command_name == "delete")
{
- BOOL can_delete = FALSE;
- LLFolderView* root = getActivePanel()->getRootFolder();
- if (root)
- {
- can_delete = TRUE;
- std::set<LLUUID> selection_set = root->getSelectionList();
- if (selection_set.empty()) return FALSE;
- for (std::set<LLUUID>::iterator iter = selection_set.begin();
- iter != selection_set.end();
- ++iter)
- {
- const LLUUID &item_id = (*iter);
- LLFolderViewItem *item = root->getItemByID(item_id);
- const LLFolderViewEventListener *listener = item->getListener();
- llassert(listener);
- if (!listener) return FALSE;
- can_delete &= listener->isItemRemovable();
- can_delete &= !listener->isItemInTrash();
- }
- return can_delete;
- }
- return FALSE;
+ return getActivePanel()->isSelectionRemovable();
}
if (command_name == "save_texture")
{
@@ -1136,7 +1130,7 @@ BOOL LLPanelMainInventory::isActionEnabled(const LLSD& userdata)
{
LLFolderViewItem* current_item = getActivePanel()->getRootFolder()->getCurSelectedItem();
if (!current_item) return FALSE;
- const LLUUID& item_id = current_item->getListener()->getUUID();
+ const LLUUID& item_id = static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->getUUID();
const LLViewerInventoryItem *item = gInventory.getItem(item_id);
if (item && item->getIsLinkType() && !item->getIsBrokenLink())
{
@@ -1148,11 +1142,11 @@ BOOL LLPanelMainInventory::isActionEnabled(const LLSD& userdata)
if (command_name == "find_links")
{
LLFolderView* root = getActivePanel()->getRootFolder();
- std::set<LLUUID> selection_set = root->getSelectionList();
+ std::set<LLFolderViewItem*> selection_set = root->getSelectionList();
if (selection_set.size() != 1) return FALSE;
LLFolderViewItem* current_item = root->getCurSelectedItem();
if (!current_item) return FALSE;
- const LLUUID& item_id = current_item->getListener()->getUUID();
+ const LLUUID& item_id = static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->getUUID();
const LLInventoryObject *obj = gInventory.getObject(item_id);
if (obj && !obj->getIsLinkType() && LLAssetType::lookupCanLink(obj->getType()))
{
@@ -1165,7 +1159,7 @@ BOOL LLPanelMainInventory::isActionEnabled(const LLSD& userdata)
{
LLFolderViewItem* current_item = getActivePanel()->getRootFolder()->getCurSelectedItem();
if (!current_item) return FALSE;
- const LLUUID& item_id = current_item->getListener()->getUUID();
+ const LLUUID& item_id = static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->getUUID();
const LLViewerInventoryItem *item = gInventory.getItem(item_id);
if (item && item->getIsBrokenLink())
{
@@ -1176,6 +1170,8 @@ BOOL LLPanelMainInventory::isActionEnabled(const LLSD& userdata)
if (command_name == "share")
{
+ LLFolderViewItem* current_item = getActivePanel()->getRootFolder()->getCurSelectedItem();
+ if (!current_item) return FALSE;
LLSidepanelInventory* parent = LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory");
return parent ? parent->canShare() : FALSE;
}
diff --git a/indra/newview/llpanelmaininventory.h b/indra/newview/llpanelmaininventory.h
index 899931aa89..fc8cc67c33 100644..100755
--- a/indra/newview/llpanelmaininventory.h
+++ b/indra/newview/llpanelmaininventory.h
@@ -82,6 +82,9 @@ public:
void setSelectCallback(const LLFolderView::signal_t::slot_type& cb);
void onFilterEdit(const std::string& search_string );
+
+ void setFocusFilterEditor();
+
protected:
//
// Misc functions
@@ -121,6 +124,7 @@ private:
LLFilterEditor* mFilterEditor;
LLTabContainer* mFilterTabs;
+ LLUICtrl* mCounterCtrl;
LLHandle<LLFloater> mFinderHandle;
LLInventoryPanel* mActivePanel;
bool mResortActivePanel;
diff --git a/indra/newview/llpanelmarketplaceinbox.cpp b/indra/newview/llpanelmarketplaceinbox.cpp
index 66c9c323cb..dcecce6fe4 100644..100755
--- a/indra/newview/llpanelmarketplaceinbox.cpp
+++ b/indra/newview/llpanelmarketplaceinbox.cpp
@@ -94,14 +94,14 @@ LLInventoryPanel * LLPanelMarketplaceInbox::setupInventoryPanel()
mInventoryPanel->setShape(inventory_placeholder_rect);
// Set the sort order newest to oldest
- mInventoryPanel->setSortOrder(LLInventoryFilter::SO_DATE);
- mInventoryPanel->getFilter()->markDefault();
+ mInventoryPanel->getFolderViewModel()->setSorter(LLInventoryFilter::SO_DATE);
+ mInventoryPanel->getFilter().markDefault();
// Set selection callback for proper update of inventory status buttons
mInventoryPanel->setSelectCallback(boost::bind(&LLPanelMarketplaceInbox::onSelectionChange, this));
// Set up the note to display when the inbox is empty
- mInventoryPanel->getFilter()->setEmptyLookupMessage("InventoryInboxNoItems");
+ mInventoryPanel->getFilter().setEmptyLookupMessage("InventoryInboxNoItems");
// Hide the placeholder text
inbox_inventory_placeholder->setVisible(FALSE);
@@ -115,8 +115,8 @@ void LLPanelMarketplaceInbox::onFocusReceived()
if (sidepanel_inventory)
{
sidepanel_inventory->clearSelections(true, false);
- }
-
+ }
+
gSavedPerAccountSettings.setU32("LastInventoryInboxActivity", time_corrected());
}
@@ -128,7 +128,6 @@ BOOL LLPanelMarketplaceInbox::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL dr
U32 LLPanelMarketplaceInbox::getFreshItemCount() const
{
-#if SUPPORTING_FRESH_ITEM_COUNT
//
// NOTE: When turning this on, be sure to test the no inbox/outbox case because this code probably
@@ -139,7 +138,7 @@ U32 LLPanelMarketplaceInbox::getFreshItemCount() const
if (mInventoryPanel)
{
- const LLFolderViewFolder * inbox_folder = mInventoryPanel->getRootFolder();
+ LLFolderViewFolder * inbox_folder = mInventoryPanel->getRootFolder();
if (inbox_folder)
{
@@ -168,15 +167,12 @@ U32 LLPanelMarketplaceInbox::getFreshItemCount() const
if (inbox_item_view && inbox_item_view->isFresh())
{
fresh_item_count++;
- }
- }
+ }
+ }
}
}
return fresh_item_count;
-#else
- return getTotalItemCount();
-#endif
}
U32 LLPanelMarketplaceInbox::getTotalItemCount() const
@@ -231,7 +227,6 @@ void LLPanelMarketplaceInbox::draw()
args["[NUM]"] = item_count_str;
mInboxButton->setLabel(getString("InboxLabelWithArg", args));
-#if SUPPORTING_FRESH_ITEM_COUNT
// set green text to fresh item count
U32 fresh_item_count = getFreshItemCount();
mFreshCountCtrl->setVisible((fresh_item_count > 0));
@@ -240,9 +235,6 @@ void LLPanelMarketplaceInbox::draw()
{
mFreshCountCtrl->setTextArg("[NUM]", llformat("%d", fresh_item_count));
}
-#else
- mFreshCountCtrl->setVisible(FALSE);
-#endif
}
else
{
diff --git a/indra/newview/llpanelmarketplaceinbox.h b/indra/newview/llpanelmarketplaceinbox.h
index 9eb74581a2..9eb74581a2 100644..100755
--- a/indra/newview/llpanelmarketplaceinbox.h
+++ b/indra/newview/llpanelmarketplaceinbox.h
diff --git a/indra/newview/llpanelmarketplaceinboxinventory.cpp b/indra/newview/llpanelmarketplaceinboxinventory.cpp
index 678e4f2843..adfb2dee86 100644..100755
--- a/indra/newview/llpanelmarketplaceinboxinventory.cpp
+++ b/indra/newview/llpanelmarketplaceinboxinventory.cpp
@@ -29,7 +29,8 @@
#include "llpanelmarketplaceinboxinventory.h"
#include "llfolderview.h"
-#include "llfoldervieweventlistener.h"
+#include "llfolderviewitem.h"
+#include "llfolderviewmodel.h"
#include "llinventorybridge.h"
#include "llinventoryfunctions.h"
#include "llpanellandmarks.h"
@@ -39,6 +40,8 @@
#define DEBUGGING_FRESHNESS 0
+const LLColor4U DEFAULT_WHITE(255, 255, 255);
+
//
// statics
//
@@ -53,107 +56,42 @@ static LLDefaultChildRegistry::Register<LLInboxFolderViewItem> r3("inbox_folder_
//
LLInboxInventoryPanel::LLInboxInventoryPanel(const LLInboxInventoryPanel::Params& p)
- : LLInventoryPanel(p)
-{
-}
+: LLInventoryPanel(p)
+{}
LLInboxInventoryPanel::~LLInboxInventoryPanel()
-{
-}
-
-// virtual
-void LLInboxInventoryPanel::buildFolderView(const LLInventoryPanel::Params& params)
-{
- // Determine the root folder in case specified, and
- // build the views starting with that folder.
-
- LLUUID root_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX, false, false);
-
- // leslie -- temporary HACK to work around sim not creating inbox with proper system folder type
- if (root_id.isNull())
- {
- std::string start_folder_name(params.start_folder());
-
- LLInventoryModel::cat_array_t* cats;
- LLInventoryModel::item_array_t* items;
-
- gInventory.getDirectDescendentsOf(gInventory.getRootFolderID(), cats, items);
-
- if (cats)
- {
- for (LLInventoryModel::cat_array_t::const_iterator cat_it = cats->begin(); cat_it != cats->end(); ++cat_it)
- {
- LLInventoryCategory* cat = *cat_it;
-
- if (cat->getName() == start_folder_name)
- {
- root_id = cat->getUUID();
- break;
- }
- }
- }
-
- if (root_id == LLUUID::null)
- {
- llwarns << "No category found that matches inbox inventory panel start_folder: " << start_folder_name << llendl;
- }
- }
- // leslie -- end temporary HACK
-
- if (root_id == LLUUID::null)
- {
- llwarns << "Inbox inventory panel has no root folder!" << llendl;
- root_id = LLUUID::generateNewID();
- }
-
- LLInvFVBridge* new_listener = mInvFVBridgeBuilder->createBridge(LLAssetType::AT_CATEGORY,
- LLAssetType::AT_CATEGORY,
- LLInventoryType::IT_CATEGORY,
- this,
- NULL,
- root_id);
-
- mFolderRoot = createFolderView(new_listener, params.use_label_suffix());
-}
+{}
LLFolderViewFolder * LLInboxInventoryPanel::createFolderViewFolder(LLInvFVBridge * bridge)
{
+ LLUIColor item_color = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE);
+
LLInboxFolderViewFolder::Params params;
params.name = bridge->getDisplayName();
- params.icon = bridge->getIcon();
- params.icon_open = bridge->getOpenIcon();
-
- if (mShowItemLinkOverlays) // if false, then links show up just like normal items
- {
- params.icon_overlay = LLUI::getUIImage("Inv_Link");
- }
-
params.root = mFolderRoot;
params.listener = bridge;
params.tool_tip = params.name;
+ params.font_color = item_color;
+ params.font_highlight_color = item_color;
return LLUICtrlFactory::create<LLInboxFolderViewFolder>(params);
}
LLFolderViewItem * LLInboxInventoryPanel::createFolderViewItem(LLInvFVBridge * bridge)
{
+ LLUIColor item_color = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE);
+
LLInboxFolderViewItem::Params params;
params.name = bridge->getDisplayName();
- params.icon = bridge->getIcon();
- params.icon_open = bridge->getOpenIcon();
-
- if (mShowItemLinkOverlays) // if false, then links show up just like normal items
- {
- params.icon_overlay = LLUI::getUIImage("Inv_Link");
- }
-
params.creation_date = bridge->getCreationDate();
params.root = mFolderRoot;
params.listener = bridge;
params.rect = LLRect (0, 0, 0, 0);
params.tool_tip = params.name;
+ params.font_color = item_color;
+ params.font_highlight_color = item_color;
return LLUICtrlFactory::create<LLInboxFolderViewItem>(params);
}
@@ -163,26 +101,40 @@ LLFolderViewItem * LLInboxInventoryPanel::createFolderViewItem(LLInvFVBridge * b
//
LLInboxFolderViewFolder::LLInboxFolderViewFolder(const Params& p)
- : LLFolderViewFolder(p)
- , LLBadgeOwner(getHandle())
- , mFresh(false)
+: LLFolderViewFolder(p),
+ LLBadgeOwner(getHandle()),
+ mFresh(false)
{
-#if SUPPORTING_FRESH_ITEM_COUNT
initBadgeParams(p.new_badge());
-#endif
+}
+
+void LLInboxFolderViewFolder::addItem(LLFolderViewItem* item)
+{
+ LLFolderViewFolder::addItem(item);
+
+ if(item)
+ {
+ LLInvFVBridge* itemBridge = static_cast<LLInvFVBridge*>(item->getViewModelItem());
+ LLFolderBridge * bridge = static_cast<LLFolderBridge *>(getViewModelItem());
+ bridge->updateHierarchyCreationDate(itemBridge->getCreationDate());
+ }
+
+ // Compute freshness if our parent is the root folder for the inbox
+ if (mParentFolder == mRoot)
+ {
+ computeFreshness();
+ }
}
// virtual
void LLInboxFolderViewFolder::draw()
{
-#if SUPPORTING_FRESH_ITEM_COUNT
if (!badgeHasParent())
{
addBadgeToParentPanel();
}
setBadgeVisibility(mFresh);
-#endif
LLFolderViewFolder::draw();
}
@@ -207,7 +159,7 @@ void LLInboxFolderViewFolder::computeFreshness()
if (last_expansion_utc > 0)
{
- mFresh = (mCreationDate > last_expansion_utc);
+ mFresh = (static_cast<LLFolderViewModelItemInventory*>(getViewModelItem())->getCreationDate() > last_expansion_utc);
#if DEBUGGING_FRESHNESS
if (mFresh)
@@ -229,16 +181,6 @@ void LLInboxFolderViewFolder::deFreshify()
gSavedPerAccountSettings.setU32("LastInventoryInboxActivity", time_corrected());
}
-void LLInboxFolderViewFolder::setCreationDate(time_t creation_date_utc)
-{
- mCreationDate = creation_date_utc;
-
- if (mParentFolder == mRoot)
- {
- computeFreshness();
- }
-}
-
//
// LLInboxFolderViewItem Implementation
//
@@ -248,24 +190,18 @@ LLInboxFolderViewItem::LLInboxFolderViewItem(const Params& p)
, LLBadgeOwner(getHandle())
, mFresh(false)
{
-#if SUPPORTING_FRESH_ITEM_COUNT
initBadgeParams(p.new_badge());
-#endif
}
-BOOL LLInboxFolderViewItem::addToFolder(LLFolderViewFolder* folder, LLFolderView* root)
+void LLInboxFolderViewItem::addToFolder(LLFolderViewFolder* folder)
{
- BOOL retval = LLFolderViewItem::addToFolder(folder, root);
+ LLFolderViewItem::addToFolder(folder);
-#if SUPPORTING_FRESH_ITEM_COUNT
// Compute freshness if our parent is the root folder for the inbox
if (mParentFolder == mRoot)
{
computeFreshness();
}
-#endif
-
- return retval;
}
BOOL LLInboxFolderViewItem::handleDoubleClick(S32 x, S32 y, MASK mask)
@@ -278,14 +214,12 @@ BOOL LLInboxFolderViewItem::handleDoubleClick(S32 x, S32 y, MASK mask)
// virtual
void LLInboxFolderViewItem::draw()
{
-#if SUPPORTING_FRESH_ITEM_COUNT
if (!badgeHasParent())
{
addBadgeToParentPanel();
}
setBadgeVisibility(mFresh);
-#endif
LLFolderViewItem::draw();
}
@@ -303,7 +237,7 @@ void LLInboxFolderViewItem::computeFreshness()
if (last_expansion_utc > 0)
{
- mFresh = (mCreationDate > last_expansion_utc);
+ mFresh = (static_cast<LLFolderViewModelItemInventory*>(getViewModelItem())->getCreationDate() > last_expansion_utc);
#if DEBUGGING_FRESHNESS
if (mFresh)
diff --git a/indra/newview/llpanelmarketplaceinboxinventory.h b/indra/newview/llpanelmarketplaceinboxinventory.h
index d6b827ee3e..c05e18c300 100644..100755
--- a/indra/newview/llpanelmarketplaceinboxinventory.h
+++ b/indra/newview/llpanelmarketplaceinboxinventory.h
@@ -33,7 +33,6 @@
#include "llfolderviewitem.h"
-#define SUPPORTING_FRESH_ITEM_COUNT 1
@@ -47,9 +46,6 @@ public:
~LLInboxInventoryPanel();
// virtual
- void buildFolderView(const LLInventoryPanel::Params& params);
-
- // virtual
LLFolderViewFolder * createFolderViewFolder(LLInvFVBridge * bridge);
LLFolderViewItem * createFolderViewItem(LLInvFVBridge * bridge);
};
@@ -63,13 +59,13 @@ public:
Optional<LLBadge::Params> new_badge;
Params()
- : new_badge("new_badge")
- {
- }
+ : new_badge("new_badge")
+ {}
};
LLInboxFolderViewFolder(const Params& p);
+ void addItem(LLFolderViewItem* item);
void draw();
void selectItem();
@@ -81,8 +77,6 @@ public:
bool isFresh() const { return mFresh; }
protected:
- void setCreationDate(time_t creation_date_utc);
-
bool mFresh;
};
@@ -95,14 +89,13 @@ public:
Optional<LLBadge::Params> new_badge;
Params()
- : new_badge("new_badge")
- {
- }
+ : new_badge("new_badge")
+ {}
};
LLInboxFolderViewItem(const Params& p);
- BOOL addToFolder(LLFolderViewFolder* folder, LLFolderView* root);
+ void addToFolder(LLFolderViewFolder* folder);
BOOL handleDoubleClick(S32 x, S32 y, MASK mask);
void draw();
diff --git a/indra/newview/llpanelmarketplaceoutboxinventory.cpp b/indra/newview/llpanelmarketplaceoutboxinventory.cpp
deleted file mode 100644
index ff62cb23db..0000000000
--- a/indra/newview/llpanelmarketplaceoutboxinventory.cpp
+++ /dev/null
@@ -1,156 +0,0 @@
-/**
- * @file llpanelmarketplaceoutboxinventory.cpp
- * @brief LLOutboxInventoryPanel class definition
- *
- * $LicenseInfo:firstyear=2009&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 "llviewerprecompiledheaders.h"
-
-#include "llpanelmarketplaceoutboxinventory.h"
-
-#include "llfolderview.h"
-#include "llfoldervieweventlistener.h"
-#include "llinventorybridge.h"
-#include "llinventoryfunctions.h"
-#include "llpanellandmarks.h"
-#include "llplacesinventorybridge.h"
-#include "lltrans.h"
-#include "llviewerfoldertype.h"
-
-
-//
-// statics
-//
-
-static LLDefaultChildRegistry::Register<LLOutboxInventoryPanel> r1("outbox_inventory_panel");
-static LLDefaultChildRegistry::Register<LLOutboxFolderViewFolder> r2("outbox_folder_view_folder");
-
-
-//
-// LLOutboxInventoryPanel Implementation
-//
-
-LLOutboxInventoryPanel::LLOutboxInventoryPanel(const LLOutboxInventoryPanel::Params& p)
- : LLInventoryPanel(p)
-{
-}
-
-LLOutboxInventoryPanel::~LLOutboxInventoryPanel()
-{
-}
-
-// virtual
-void LLOutboxInventoryPanel::buildFolderView(const LLInventoryPanel::Params& params)
-{
- // Determine the root folder in case specified, and
- // build the views starting with that folder.
-
- LLUUID root_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false, false);
-
- if (root_id == LLUUID::null)
- {
- llwarns << "Outbox inventory panel has no root folder!" << llendl;
- root_id = LLUUID::generateNewID();
- }
-
- LLInvFVBridge* new_listener = mInvFVBridgeBuilder->createBridge(LLAssetType::AT_CATEGORY,
- LLAssetType::AT_CATEGORY,
- LLInventoryType::IT_CATEGORY,
- this,
- NULL,
- root_id);
-
- mFolderRoot = createFolderView(new_listener, params.use_label_suffix());
-}
-
-LLFolderViewFolder * LLOutboxInventoryPanel::createFolderViewFolder(LLInvFVBridge * bridge)
-{
- LLOutboxFolderViewFolder::Params params;
-
- params.name = bridge->getDisplayName();
- params.icon = bridge->getIcon();
- params.icon_open = bridge->getOpenIcon();
-
- if (mShowItemLinkOverlays) // if false, then links show up just like normal items
- {
- params.icon_overlay = LLUI::getUIImage("Inv_Link");
- }
-
- params.root = mFolderRoot;
- params.listener = bridge;
- params.tool_tip = params.name;
-
- return LLUICtrlFactory::create<LLOutboxFolderViewFolder>(params);
-}
-
-LLFolderViewItem * LLOutboxInventoryPanel::createFolderViewItem(LLInvFVBridge * bridge)
-{
- LLFolderViewItem::Params params;
-
- params.name = bridge->getDisplayName();
- params.icon = bridge->getIcon();
- params.icon_open = bridge->getOpenIcon();
-
- if (mShowItemLinkOverlays) // if false, then links show up just like normal items
- {
- params.icon_overlay = LLUI::getUIImage("Inv_Link");
- }
-
- params.creation_date = bridge->getCreationDate();
- params.root = mFolderRoot;
- params.listener = bridge;
- params.rect = LLRect (0, 0, 0, 0);
- params.tool_tip = params.name;
-
- return LLUICtrlFactory::create<LLOutboxFolderViewItem>(params);
-}
-
-//
-// LLOutboxFolderViewFolder Implementation
-//
-
-LLOutboxFolderViewFolder::LLOutboxFolderViewFolder(const Params& p)
- : LLFolderViewFolder(p)
-{
-}
-
-//
-// LLOutboxFolderViewItem Implementation
-//
-
-LLOutboxFolderViewItem::LLOutboxFolderViewItem(const Params& p)
- : LLFolderViewItem(p)
-{
-}
-
-BOOL LLOutboxFolderViewItem::handleDoubleClick(S32 x, S32 y, MASK mask)
-{
- return TRUE;
-}
-
-void LLOutboxFolderViewItem::openItem()
-{
- // Intentionally do nothing to block attaching items from the outbox
-}
-
-// eof
diff --git a/indra/newview/llpanelmarketplaceoutboxinventory.h b/indra/newview/llpanelmarketplaceoutboxinventory.h
deleted file mode 100644
index a6c522b7c2..0000000000
--- a/indra/newview/llpanelmarketplaceoutboxinventory.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/**
- * @file llpanelmarketplaceoutboxinventory.h
- * @brief LLOutboxInventoryPanel class declaration
- *
- * $LicenseInfo:firstyear=2009&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$
- */
-
-#ifndef LL_OUTBOXINVENTORYPANEL_H
-#define LL_OUTBOXINVENTORYPANEL_H
-
-
-#include "llinventorypanel.h"
-#include "llfolderviewitem.h"
-
-
-class LLOutboxInventoryPanel : public LLInventoryPanel
-{
-public:
- struct Params : public LLInitParam::Block<Params, LLInventoryPanel::Params>
- {
- Params() {}
- };
-
- LLOutboxInventoryPanel(const Params& p);
- ~LLOutboxInventoryPanel();
-
- // virtual
- void buildFolderView(const LLInventoryPanel::Params& params);
-
- // virtual
- LLFolderViewFolder * createFolderViewFolder(LLInvFVBridge * bridge);
- LLFolderViewItem * createFolderViewItem(LLInvFVBridge * bridge);
-};
-
-
-class LLOutboxFolderViewFolder : public LLFolderViewFolder
-{
-public:
- struct Params : public LLInitParam::Block<Params, LLFolderViewFolder::Params>
- {
- Params() {}
- };
-
- LLOutboxFolderViewFolder(const Params& p);
-};
-
-
-class LLOutboxFolderViewItem : public LLFolderViewItem
-{
-public:
- LLOutboxFolderViewItem(const Params& p);
-
- // virtual
- BOOL handleDoubleClick(S32 x, S32 y, MASK mask);
- void openItem();
-};
-
-
-#endif //LL_OUTBOXINVENTORYPANEL_H
diff --git a/indra/newview/llpanelme.cpp b/indra/newview/llpanelme.cpp
index a9af56f750..a9af56f750 100644..100755
--- a/indra/newview/llpanelme.cpp
+++ b/indra/newview/llpanelme.cpp
diff --git a/indra/newview/llpanelme.h b/indra/newview/llpanelme.h
index 60e9d4317d..60e9d4317d 100644..100755
--- a/indra/newview/llpanelme.h
+++ b/indra/newview/llpanelme.h
diff --git a/indra/newview/llpanelmediasettingsgeneral.cpp b/indra/newview/llpanelmediasettingsgeneral.cpp
index 2856ea9db1..2856ea9db1 100644..100755
--- a/indra/newview/llpanelmediasettingsgeneral.cpp
+++ b/indra/newview/llpanelmediasettingsgeneral.cpp
diff --git a/indra/newview/llpanelmediasettingsgeneral.h b/indra/newview/llpanelmediasettingsgeneral.h
index 0ae1401ab2..0ae1401ab2 100644..100755
--- a/indra/newview/llpanelmediasettingsgeneral.h
+++ b/indra/newview/llpanelmediasettingsgeneral.h
diff --git a/indra/newview/llpanelmediasettingspermissions.cpp b/indra/newview/llpanelmediasettingspermissions.cpp
index cb0b7789ff..cb0b7789ff 100644..100755
--- a/indra/newview/llpanelmediasettingspermissions.cpp
+++ b/indra/newview/llpanelmediasettingspermissions.cpp
diff --git a/indra/newview/llpanelmediasettingspermissions.h b/indra/newview/llpanelmediasettingspermissions.h
index f976720180..f976720180 100644..100755
--- a/indra/newview/llpanelmediasettingspermissions.h
+++ b/indra/newview/llpanelmediasettingspermissions.h
diff --git a/indra/newview/llpanelmediasettingssecurity.cpp b/indra/newview/llpanelmediasettingssecurity.cpp
index b588e8f930..b588e8f930 100644..100755
--- a/indra/newview/llpanelmediasettingssecurity.cpp
+++ b/indra/newview/llpanelmediasettingssecurity.cpp
diff --git a/indra/newview/llpanelmediasettingssecurity.h b/indra/newview/llpanelmediasettingssecurity.h
index fe8e843571..fe8e843571 100644..100755
--- a/indra/newview/llpanelmediasettingssecurity.h
+++ b/indra/newview/llpanelmediasettingssecurity.h
diff --git a/indra/newview/llpanelnearbymedia.cpp b/indra/newview/llpanelnearbymedia.cpp
index c01adc3c35..a50d9074f7 100644..100755
--- a/indra/newview/llpanelnearbymedia.cpp
+++ b/indra/newview/llpanelnearbymedia.cpp
@@ -176,7 +176,7 @@ void LLPanelNearByMedia::handleMediaAutoPlayChanged(const LLSD& newvalue)
{
// update mParcelAudioAutoStart if AUTO_PLAY_MEDIA_SETTING changes
mParcelAudioAutoStart = gSavedSettings.getBOOL(LLViewerMedia::AUTO_PLAY_MEDIA_SETTING) &&
- gSavedSettings.getBOOL("MediaTentativeAutoPlay");
+ gSavedSettings.getBOOL("MediaTentativeAutoPlay");
}
/*virtual*/
diff --git a/indra/newview/llpanelnearbymedia.h b/indra/newview/llpanelnearbymedia.h
index c3634de9b4..c3634de9b4 100644..100755
--- a/indra/newview/llpanelnearbymedia.h
+++ b/indra/newview/llpanelnearbymedia.h
diff --git a/indra/newview/llpanelobject.cpp b/indra/newview/llpanelobject.cpp
index 1f77e7a602..25ef9a3d6a 100644..100755
--- a/indra/newview/llpanelobject.cpp
+++ b/indra/newview/llpanelobject.cpp
@@ -119,7 +119,6 @@ BOOL LLPanelObject::postBuild()
mCheckPhantom = getChild<LLCheckBoxCtrl>("Phantom Checkbox Ctrl");
childSetCommitCallback("Phantom Checkbox Ctrl",onCommitPhantom,this);
-
// Position
mLabelPosition = getChild<LLTextBox>("label position");
mCtrlPosX = getChild<LLSpinCtrl>("Pos X");
@@ -245,6 +244,7 @@ BOOL LLPanelObject::postBuild()
mCtrlSculptTexture->setDropCallback( boost::bind(&LLPanelObject::onDropSculpt, this, _2 ));
// Don't allow (no copy) or (no transfer) textures to be selected during immediate mode
mCtrlSculptTexture->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER);
+ mCtrlSculptTexture->setDnDFilterPermMask(PERM_COPY | PERM_TRANSFER);
// Allow any texture to be used during non-immediate mode.
mCtrlSculptTexture->setNonImmediateFilterPermMask(PERM_NONE);
LLAggregatePermissions texture_perms;
@@ -271,7 +271,7 @@ BOOL LLPanelObject::postBuild()
childSetCommitCallback("sculpt mirror control", onCommitSculptType, this);
mCtrlSculptInvert = getChild<LLCheckBoxCtrl>("sculpt invert control");
childSetCommitCallback("sculpt invert control", onCommitSculptType, this);
-
+
// Start with everyone disabled
clearCtrls();
@@ -283,7 +283,6 @@ LLPanelObject::LLPanelObject()
mIsPhysical(FALSE),
mIsTemporary(FALSE),
mIsPhantom(FALSE),
- mCastShadows(TRUE),
mSelectedType(MI_BOX),
mSculptTextureRevert(LLUUID::null),
mSculptTypeRevert(0)
@@ -342,9 +341,9 @@ void LLPanelObject::getState( )
}
// can move or rotate only linked group with move permissions, or sub-object with move and modify perms
- BOOL enable_move = objectp->permMove() && !objectp->isAttachment() && (objectp->permModify() || !gSavedSettings.getBOOL("EditLinkedParts"));
- BOOL enable_scale = objectp->permMove() && objectp->permModify();
- BOOL enable_rotate = objectp->permMove() && ( (objectp->permModify() && !objectp->isAttachment()) || !gSavedSettings.getBOOL("EditLinkedParts"));
+ BOOL enable_move = objectp->permMove() && !objectp->isPermanentEnforced() && ((root_objectp == NULL) || !root_objectp->isPermanentEnforced()) && !objectp->isAttachment() && (objectp->permModify() || !gSavedSettings.getBOOL("EditLinkedParts"));
+ BOOL enable_scale = objectp->permMove() && !objectp->isPermanentEnforced() && ((root_objectp == NULL) || !root_objectp->isPermanentEnforced()) && objectp->permModify();
+ BOOL enable_rotate = objectp->permMove() && !objectp->isPermanentEnforced() && ((root_objectp == NULL) || !root_objectp->isPermanentEnforced()) && ( (objectp->permModify() && !objectp->isAttachment()) || !gSavedSettings.getBOOL("EditLinkedParts"));
S32 selected_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount();
BOOL single_volume = (LLSelectMgr::getInstance()->selectionAllPCode( LL_PCODE_VOLUME ))
@@ -440,10 +439,9 @@ void LLPanelObject::getState( )
mCtrlRotY->setEnabled( enable_rotate );
mCtrlRotZ->setEnabled( enable_rotate );
- BOOL owners_identical;
LLUUID owner_id;
std::string owner_name;
- owners_identical = LLSelectMgr::getInstance()->selectGetOwner(owner_id, owner_name);
+ LLSelectMgr::getInstance()->selectGetOwner(owner_id, owner_name);
// BUG? Check for all objects being editable?
S32 roots_selected = LLSelectMgr::getInstance()->getSelection()->getRootObjectCount();
@@ -462,9 +460,16 @@ void LLPanelObject::getState( )
getChildView("select_single")->setVisible( TRUE);
getChildView("select_single")->setEnabled(TRUE);
}
+
+ BOOL is_flexible = volobjp && volobjp->isFlexible();
+ BOOL is_permanent = root_objectp->flagObjectPermanent();
+ BOOL is_permanent_enforced = root_objectp->isPermanentEnforced();
+ BOOL is_character = root_objectp->flagCharacter();
+ llassert(!is_permanent || !is_character); // should never have a permanent object that is also a character
+
// Lock checkbox - only modifiable if you own the object.
BOOL self_owned = (gAgent.getID() == owner_id);
- mCheckLock->setEnabled( roots_selected > 0 && self_owned );
+ mCheckLock->setEnabled( roots_selected > 0 && self_owned && !is_permanent_enforced);
// More lock and debit checkbox - get the values
BOOL valid;
@@ -494,30 +499,27 @@ void LLPanelObject::getState( )
}
}
- BOOL is_flexible = volobjp && volobjp->isFlexible();
-
// Physics checkbox
- mIsPhysical = root_objectp->usePhysics();
+ mIsPhysical = root_objectp->flagUsePhysics();
+ llassert(!is_permanent || !mIsPhysical); // should never have a permanent object that is also physical
+
mCheckPhysics->set( mIsPhysical );
mCheckPhysics->setEnabled( roots_selected>0
&& (editable || gAgent.isGodlike())
- && !is_flexible);
+ && !is_flexible && !is_permanent);
mIsTemporary = root_objectp->flagTemporaryOnRez();
+ llassert(!is_permanent || !mIsTemporary); // should never has a permanent object that is also temporary
+
mCheckTemporary->set( mIsTemporary );
- mCheckTemporary->setEnabled( roots_selected>0 && editable );
+ mCheckTemporary->setEnabled( roots_selected>0 && editable && !is_permanent);
mIsPhantom = root_objectp->flagPhantom();
+ BOOL is_volume_detect = root_objectp->flagVolumeDetect();
+ llassert(!is_character || !mIsPhantom); // should never have a character that is also a phantom
mCheckPhantom->set( mIsPhantom );
- mCheckPhantom->setEnabled( roots_selected>0 && editable && !is_flexible );
+ mCheckPhantom->setEnabled( roots_selected>0 && editable && !is_flexible && !is_permanent_enforced && !is_character && !is_volume_detect);
-
-#if 0 // 1.9.2
- mCastShadows = root_objectp->flagCastShadows();
- mCheckCastShadows->set( mCastShadows );
- mCheckCastShadows->setEnabled( roots_selected==1 && editable );
-#endif
-
//----------------------------------------------------------------------------
S32 selected_item = MI_BOX;
@@ -555,7 +557,7 @@ void LLPanelObject::getState( )
{
// Only allowed to change these parameters for objects
// that you have permissions on AND are not attachments.
- enabled = root_objectp->permModify();
+ enabled = root_objectp->permModify() && !root_objectp->isPermanentEnforced();
// Volume type
const LLVolumeParams &volume_params = objectp->getVolume()->getParams();
@@ -1214,22 +1216,6 @@ void LLPanelObject::sendIsPhantom()
}
}
-void LLPanelObject::sendCastShadows()
-{
- BOOL value = mCheckCastShadows->get();
- if( mCastShadows != value )
- {
- LLSelectMgr::getInstance()->selectionUpdateCastShadows(value);
- mCastShadows = value;
-
- llinfos << "update cast shadows sent" << llendl;
- }
- else
- {
- llinfos << "update cast shadows not changed" << llendl;
- }
-}
-
// static
void LLPanelObject::onCommitParametric( LLUICtrl* ctrl, void* userdata )
{
@@ -1886,10 +1872,6 @@ void LLPanelObject::clearCtrls()
mCheckPhantom ->set(FALSE);
mCheckPhantom ->setEnabled( FALSE );
-#if 0 // 1.9.2
- mCheckCastShadows->set(FALSE);
- mCheckCastShadows->setEnabled( FALSE );
-#endif
// Disable text labels
mLabelPosition ->setEnabled( FALSE );
mLabelSize ->setEnabled( FALSE );
@@ -1977,14 +1959,6 @@ void LLPanelObject::onCommitPhantom( LLUICtrl* ctrl, void* userdata )
self->sendIsPhantom();
}
-// static
-void LLPanelObject::onCommitCastShadows( LLUICtrl* ctrl, void* userdata )
-{
- LLPanelObject* self = (LLPanelObject*) userdata;
- self->sendCastShadows();
-}
-
-
void LLPanelObject::onSelectSculpt(const LLSD& data)
{
LLTextureCtrl* mTextureCtrl = getChild<LLTextureCtrl>("sculpt texture control");
diff --git a/indra/newview/llpanelobject.h b/indra/newview/llpanelobject.h
index 475dfdaedb..c4cf27ab1a 100644..100755
--- a/indra/newview/llpanelobject.h
+++ b/indra/newview/llpanelobject.h
@@ -64,7 +64,6 @@ public:
static void onCommitRotation( LLUICtrl* ctrl, void* userdata);
static void onCommitTemporary( LLUICtrl* ctrl, void* userdata);
static void onCommitPhantom( LLUICtrl* ctrl, void* userdata);
- static void onCommitCastShadows( LLUICtrl* ctrl, void* userdata);
static void onCommitPhysics( LLUICtrl* ctrl, void* userdata);
static void onCommitParametric(LLUICtrl* ctrl, void* userdata);
@@ -75,8 +74,7 @@ public:
void onSelectSculpt(const LLSD& data);
BOOL onDropSculpt(LLInventoryItem* item);
static void onCommitSculptType( LLUICtrl *ctrl, void* userdata);
-
-
+
protected:
void getState();
@@ -87,7 +85,6 @@ protected:
void sendIsTemporary();
void sendIsPhantom();
- void sendCastShadows();
void sendSculpt();
void getVolumeParams(LLVolumeParams& volume_params);
@@ -153,7 +150,6 @@ protected:
LLCheckBoxCtrl *mCheckPhysics;
LLCheckBoxCtrl *mCheckTemporary;
LLCheckBoxCtrl *mCheckPhantom;
- LLCheckBoxCtrl *mCheckCastShadows;
LLTextureCtrl *mCtrlSculptTexture;
LLTextBox *mLabelSculptType;
@@ -165,7 +161,6 @@ protected:
BOOL mIsPhysical; // to avoid sending "physical" when not changed
BOOL mIsTemporary; // to avoid sending "temporary" when not changed
BOOL mIsPhantom; // to avoid sending "phantom" when not changed
- BOOL mCastShadows; // to avoid sending "cast shadows" when not changed
S32 mSelectedType; // So we know what selected type we last were
LLUUID mSculptTextureRevert; // so we can revert the sculpt texture on cancel
diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp
index 1ca24f3031..d7130820ab 100644..100755
--- a/indra/newview/llpanelobjectinventory.cpp
+++ b/indra/newview/llpanelobjectinventory.cpp
@@ -47,6 +47,7 @@
#include "llfolderview.h"
#include "llinventorybridge.h"
#include "llinventorydefines.h"
+#include "llinventoryicon.h"
#include "llinventoryfilter.h"
#include "llinventoryfunctions.h"
#include "llpreviewanim.h"
@@ -66,17 +67,19 @@
#include "llviewerobjectlist.h"
#include "llviewermessage.h"
+const LLColor4U DEFAULT_WHITE(255, 255, 255);
///----------------------------------------------------------------------------
/// Class LLTaskInvFVBridge
///----------------------------------------------------------------------------
-class LLTaskInvFVBridge : public LLFolderViewEventListener
+class LLTaskInvFVBridge : public LLFolderViewModelItemInventory
{
protected:
LLUUID mUUID;
std::string mName;
mutable std::string mDisplayName;
+ mutable std::string mSearchableName;
LLPanelObjectInventory* mPanel;
U32 mFlags;
LLAssetType::EType mAssetType;
@@ -102,26 +105,29 @@ public:
S32 getPrice();
static bool commitBuyItem(const LLSD& notification, const LLSD& response);
- // LLFolderViewEventListener functionality
+ // LLFolderViewModelItemInventory functionality
virtual const std::string& getName() const;
virtual const std::string& getDisplayName() const;
+ virtual const std::string& getSearchableName() const;
+
virtual PermissionMask getPermissionMask() const { return PERM_NONE; }
/*virtual*/ LLFolderType::EType getPreferredType() const { return LLFolderType::FT_NONE; }
virtual const LLUUID& getUUID() const { return mUUID; }
virtual time_t getCreationDate() const;
+ virtual void setCreationDate(time_t creation_date_utc);
+
virtual LLUIImagePtr getIcon() const;
virtual void openItem();
virtual BOOL canOpenItem() const { return FALSE; }
virtual void closeItem() {}
- virtual void previewItem();
virtual void selectItem() {}
virtual BOOL isItemRenameable() const;
virtual BOOL renameItem(const std::string& new_name);
virtual BOOL isItemMovable() const;
virtual BOOL isItemRemovable() const;
virtual BOOL removeItem();
- virtual void removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batch);
- virtual void move(LLFolderViewEventListener* parent_listener);
+ virtual void removeBatch(std::vector<LLFolderViewModelItem*>& batch);
+ virtual void move(LLFolderViewModelItem* parent_listener);
virtual BOOL isItemCopyable() const;
virtual BOOL copyToClipboard() const;
virtual BOOL cutToClipboard() const;
@@ -131,11 +137,15 @@ public:
virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
virtual void performAction(LLInventoryModel* model, std::string action);
virtual BOOL isUpToDate() const { return TRUE; }
- virtual BOOL hasChildren() const { return FALSE; }
+ virtual bool hasChildren() const { return FALSE; }
virtual LLInventoryType::EType getInventoryType() const { return LLInventoryType::IT_NONE; }
virtual LLWearableType::EType getWearableType() const { return LLWearableType::WT_NONE; }
+ virtual EInventorySortGroup getSortGroup() const { return SG_ITEM; }
+ virtual LLInventoryObject* getInventoryObject() const { return findInvObject(); }
+
// LLDragAndDropBridge functionality
+ virtual LLToolDragAndDrop::ESource getDragSource() const { return LLToolDragAndDrop::SOURCE_WORLD; }
virtual BOOL startDrag(EDragAndDropType* type, LLUUID* id) const;
virtual BOOL dragOrDrop(MASK mask, BOOL drop,
EDragAndDropType cargo_type,
@@ -147,7 +157,8 @@ LLTaskInvFVBridge::LLTaskInvFVBridge(
LLPanelObjectInventory* panel,
const LLUUID& uuid,
const std::string& name,
- U32 flags):
+ U32 flags)
+: LLFolderViewModelItemInventory(panel->getRootViewModel()),
mUUID(uuid),
mName(name),
mPanel(panel),
@@ -330,15 +341,27 @@ const std::string& LLTaskInvFVBridge::getDisplayName() const
}
}
+ mSearchableName.assign(mDisplayName + getLabelSuffix());
+
return mDisplayName;
}
+const std::string& LLTaskInvFVBridge::getSearchableName() const
+{
+ return mSearchableName;
+}
+
+
// BUG: No creation dates for task inventory
time_t LLTaskInvFVBridge::getCreationDate() const
{
return 0;
}
+void LLTaskInvFVBridge::setCreationDate(time_t creation_date_utc)
+{}
+
+
LLUIImagePtr LLTaskInvFVBridge::getIcon() const
{
const BOOL item_is_multi = (mFlags & LLInventoryItemFlags::II_FLAGS_OBJECT_HAS_MULTIPLE_ITEMS);
@@ -352,11 +375,6 @@ void LLTaskInvFVBridge::openItem()
lldebugs << "LLTaskInvFVBridge::openItem()" << llendl;
}
-void LLTaskInvFVBridge::previewItem()
-{
- openItem();
-}
-
BOOL LLTaskInvFVBridge::isItemRenameable() const
{
if(gAgent.isGodlike()) return TRUE;
@@ -467,7 +485,7 @@ BOOL LLTaskInvFVBridge::removeItem()
return FALSE;
}
-void LLTaskInvFVBridge::removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batch)
+void LLTaskInvFVBridge::removeBatch(std::vector<LLFolderViewModelItem*>& batch)
{
if (!mPanel)
{
@@ -507,7 +525,7 @@ void LLTaskInvFVBridge::removeBatch(LLDynamicArray<LLFolderViewEventListener*>&
}
}
-void LLTaskInvFVBridge::move(LLFolderViewEventListener* parent_listener)
+void LLTaskInvFVBridge::move(LLFolderViewModelItem* parent_listener)
{
}
@@ -709,7 +727,7 @@ public:
virtual BOOL renameItem(const std::string& new_name);
virtual BOOL isItemRemovable() const;
virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
- virtual BOOL hasChildren() const;
+ virtual bool hasChildren() const;
virtual BOOL startDrag(EDragAndDropType* type, LLUUID* id) const;
virtual BOOL dragOrDrop(MASK mask, BOOL drop,
EDragAndDropType cargo_type,
@@ -717,6 +735,7 @@ public:
std::string& tooltip_msg);
virtual BOOL canOpenItem() const { return TRUE; }
virtual void openItem();
+ virtual EInventorySortGroup getSortGroup() const { return SG_NORMAL_FOLDER; }
};
LLTaskCategoryBridge::LLTaskCategoryBridge(
@@ -739,15 +758,7 @@ const std::string& LLTaskCategoryBridge::getDisplayName() const
if (cat)
{
- // Localize "Contents" folder.
- if (cat->getParentUUID().isNull() && cat->getName() == "Contents")
- {
- mDisplayName.assign(LLTrans::getString("ViewerObjectContents"));
- }
- else
- {
- mDisplayName.assign(cat->getName());
- }
+ mDisplayName.assign(cat->getName());
}
return mDisplayName;
@@ -775,7 +786,7 @@ void LLTaskCategoryBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
hide_context_entries(menu, items, disabled_items);
}
-BOOL LLTaskCategoryBridge::hasChildren() const
+bool LLTaskCategoryBridge::hasChildren() const
{
// return TRUE if we have or do know know if we have children.
// *FIX: For now, return FALSE - we will know for sure soon enough.
@@ -1489,7 +1500,7 @@ LLPanelObjectInventory::LLPanelObjectInventory(const LLPanelObjectInventory::Par
mCommitCallbackRegistrar.add("Inventory.DoCreate", boost::bind(&do_nothing));
mCommitCallbackRegistrar.add("Inventory.AttachObject", boost::bind(&do_nothing));
mCommitCallbackRegistrar.add("Inventory.BeginIMSession", boost::bind(&do_nothing));
- mCommitCallbackRegistrar.add("Inventory.Share", boost::bind(&LLAvatarActions::shareWithAvatars));
+ mCommitCallbackRegistrar.add("Inventory.Share", boost::bind(&LLAvatarActions::shareWithAvatars, this));
}
// Destroys the object
@@ -1514,7 +1525,7 @@ BOOL LLPanelObjectInventory::postBuild()
void LLPanelObjectInventory::doToSelected(const LLSD& userdata)
{
- mFolders->doToSelected(&gInventory, userdata);
+ LLInventoryAction::doToSelected(&gInventory, mFolders, userdata.asString());
}
void LLPanelObjectInventory::clearContents()
@@ -1526,6 +1537,8 @@ void LLPanelObjectInventory::clearContents()
LLToolDragAndDrop::getInstance()->endDrag();
}
+ clearItemIDs();
+
if( mScroller )
{
// removes mFolders
@@ -1541,21 +1554,26 @@ void LLPanelObjectInventory::reset()
{
clearContents();
- //setBorderVisible(FALSE);
-
mCommitCallbackRegistrar.pushScope(); // push local callbacks
+ // Reset the inventory model to show all folders by default
+ mInventoryViewModel.getFilter().setShowFolderState(LLInventoryFilter::SHOW_ALL_FOLDERS);
+
+ // Create a new folder view root
LLRect dummy_rect(0, 1, 1, 0);
LLFolderView::Params p;
p.name = "task inventory";
p.title = "task inventory";
- p.task_id = getTaskUUID();
p.parent_panel = this;
p.tool_tip= LLTrans::getString("PanelContentsTooltip");
p.listener = LLTaskInvFVBridge::createObjectBridge(this, NULL);
+ p.folder_indentation = -14; // subtract space normally reserved for folder expanders
+ p.view_model = &mInventoryViewModel;
+ p.root = NULL;
+ p.options_menu = "menu_inventory.xml";
+
mFolders = LLUICtrlFactory::create<LLFolderView>(p);
- // this ensures that we never say "searching..." or "no items found"
- mFolders->getFilter()->setShowFolderState(LLInventoryFilter::SHOW_ALL_FOLDERS);
+
mFolders->setCallbackRegistrar(&mCommitCallbackRegistrar);
if (hasFocus())
@@ -1600,7 +1618,7 @@ void LLPanelObjectInventory::inventoryChanged(LLViewerObject* object,
iter != inventory->end(); )
{
LLInventoryObject* item = *iter++;
- LLFloaterProperties* floater = LLFloaterReg::findTypedInstance<LLFloaterProperties>("properites", item->getUUID());
+ LLFloaterProperties* floater = LLFloaterReg::findTypedInstance<LLFloaterProperties>("properties", item->getUUID());
if(floater)
{
floater->refresh();
@@ -1615,15 +1633,20 @@ void LLPanelObjectInventory::updateInventory()
// << " panel UUID: " << panel->mTaskUUID << "\n"
// << " task UUID: " << object->mID << llendl;
// We're still interested in this task's inventory.
- std::set<LLUUID> selected_items;
+ std::vector<LLUUID> selected_item_ids;
+ std::set<LLFolderViewItem*> selected_items;
BOOL inventory_has_focus = FALSE;
- if (mHaveInventory)
+ if (mHaveInventory && mFolders)
{
selected_items = mFolders->getSelectionList();
inventory_has_focus = gFocusMgr.childHasKeyboardFocus(mFolders);
}
-
- reset();
+ for (std::set<LLFolderViewItem*>::iterator it = selected_items.begin(), end_it = selected_items.end();
+ it != end_it;
+ ++it)
+ {
+ selected_item_ids.push_back(static_cast<LLFolderViewModelItemInventory*>((*it)->getViewModelItem())->getUUID());
+ }
LLViewerObject* objectp = gObjectList.findObject(mTaskUUID);
if (objectp)
@@ -1631,19 +1654,21 @@ void LLPanelObjectInventory::updateInventory()
LLInventoryObject* inventory_root = objectp->getInventoryRoot();
LLInventoryObject::object_list_t contents;
objectp->getInventoryContents(contents);
+
if (inventory_root)
{
- createFolderViews(inventory_root, contents);
- mHaveInventory = TRUE;
+ reset();
mIsInventoryEmpty = FALSE;
+ createFolderViews(inventory_root, contents);
mFolders->setEnabled(TRUE);
}
else
{
// TODO: create an empty inventory
mIsInventoryEmpty = TRUE;
- mHaveInventory = TRUE;
}
+
+ mHaveInventory = TRUE;
}
else
{
@@ -1653,11 +1678,12 @@ void LLPanelObjectInventory::updateInventory()
}
// restore previous selection
- std::set<LLUUID>::iterator selection_it;
- BOOL first_item = TRUE;
- for (selection_it = selected_items.begin(); selection_it != selected_items.end(); ++selection_it)
+ std::vector<LLUUID>::iterator selection_it;
+ bool first_item = true;
+ for (selection_it = selected_item_ids.begin(); selection_it != selected_item_ids.end(); ++selection_it)
{
- LLFolderViewItem* selected_item = mFolders->getItemByID(*selection_it);
+ LLFolderViewItem* selected_item = getItemByID(*selection_it);
+
if (selected_item)
{
//HACK: "set" first item then "change" each other one to get keyboard focus right
@@ -1673,7 +1699,10 @@ void LLPanelObjectInventory::updateInventory()
}
}
- mFolders->requestArrange();
+ if (mFolders)
+ {
+ mFolders->requestArrange();
+ }
mInventoryNeedsUpdate = FALSE;
// Edit menu handler is set in onFocusReceived
}
@@ -1694,19 +1723,24 @@ void LLPanelObjectInventory::createFolderViews(LLInventoryObject* inventory_root
bridge = LLTaskInvFVBridge::createObjectBridge(this, inventory_root);
if(bridge)
{
- LLFolderViewFolder* new_folder = NULL;
+ LLUIColor item_color = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE);
+
LLFolderViewFolder::Params p;
p.name = inventory_root->getName();
- p.icon = LLUI::getUIImage("Inv_FolderClosed");
- p.icon_open = LLUI::getUIImage("Inv_FolderOpen");
+ p.tool_tip = p.name;
p.root = mFolders;
p.listener = bridge;
- p.tool_tip = p.name;
- new_folder = LLUICtrlFactory::create<LLFolderViewFolder>(p);
- new_folder->addToFolder(mFolders, mFolders);
+ p.font_color = item_color;
+ p.font_highlight_color = item_color;
+
+ LLFolderViewFolder* new_folder = LLUICtrlFactory::create<LLFolderViewFolder>(p);
+ new_folder->addToFolder(mFolders);
new_folder->toggleOpen();
- createViewsForCategory(&contents, inventory_root, new_folder);
+ if (!contents.empty())
+ {
+ createViewsForCategory(&contents, inventory_root, new_folder);
+ }
}
}
@@ -1716,6 +1750,8 @@ void LLPanelObjectInventory::createViewsForCategory(LLInventoryObject::object_li
LLInventoryObject* parent,
LLFolderViewFolder* folder)
{
+ LLUIColor item_color = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE);
+
// Find all in the first pass
LLDynamicArray<obj_folder_pair*> child_categories;
LLTaskInvFVBridge* bridge;
@@ -1738,11 +1774,11 @@ void LLPanelObjectInventory::createViewsForCategory(LLInventoryObject::object_li
{
LLFolderViewFolder::Params p;
p.name = obj->getName();
- p.icon = LLUI::getUIImage("Inv_FolderClosed");
- p.icon_open = LLUI::getUIImage("Inv_FolderOpen");
p.root = mFolders;
p.listener = bridge;
p.tool_tip = p.name;
+ p.font_color = item_color;
+ p.font_highlight_color = item_color;
view = LLUICtrlFactory::create<LLFolderViewFolder>(p);
child_categories.put(new obj_folder_pair(obj,
(LLFolderViewFolder*)view));
@@ -1751,15 +1787,17 @@ void LLPanelObjectInventory::createViewsForCategory(LLInventoryObject::object_li
{
LLFolderViewItem::Params params;
params.name(obj->getName());
- params.icon(bridge->getIcon());
params.creation_date(bridge->getCreationDate());
params.root(mFolders);
params.listener(bridge);
params.rect(LLRect());
params.tool_tip = params.name;
+ params.font_color = item_color;
+ params.font_highlight_color = item_color;
view = LLUICtrlFactory::create<LLFolderViewItem> (params);
}
- view->addToFolder(folder, mFolders);
+ view->addToFolder(folder);
+ addItemID(obj->getUUID(), view);
}
}
@@ -1827,6 +1865,7 @@ void LLPanelObjectInventory::refresh()
removeVOInventoryListener();
clearContents();
}
+ mInventoryViewModel.setTaskID(mTaskUUID);
//llinfos << "LLPanelObjectInventory::refresh() " << mTaskUUID << llendl;
}
@@ -1914,7 +1953,10 @@ void LLPanelObjectInventory::idle(void* user_data)
{
LLPanelObjectInventory* self = (LLPanelObjectInventory*)user_data;
-
+ if (self->mFolders)
+ {
+ self->mFolders->update();
+ }
if (self->mInventoryNeedsUpdate)
{
self->updateInventory();
@@ -1939,3 +1981,32 @@ void LLPanelObjectInventory::onFocusReceived()
LLPanel::onFocusReceived();
}
+
+
+LLFolderViewItem* LLPanelObjectInventory::getItemByID( const LLUUID& id )
+{
+ std::map<LLUUID, LLFolderViewItem*>::iterator map_it;
+ map_it = mItemMap.find(id);
+ if (map_it != mItemMap.end())
+ {
+ return map_it->second;
+ }
+
+ return NULL;
+}
+
+void LLPanelObjectInventory::removeItemID( const LLUUID& id )
+{
+ mItemMap.erase(id);
+}
+
+void LLPanelObjectInventory::addItemID( const LLUUID& id, LLFolderViewItem* itemp )
+{
+ mItemMap[id] = itemp;
+}
+
+void LLPanelObjectInventory::clearItemIDs()
+{
+ mItemMap.clear();
+}
+
diff --git a/indra/newview/llpanelobjectinventory.h b/indra/newview/llpanelobjectinventory.h
index 607b705f7f..f497c695b3 100644..100755
--- a/indra/newview/llpanelobjectinventory.h
+++ b/indra/newview/llpanelobjectinventory.h
@@ -29,6 +29,7 @@
#include "llvoinventorylistener.h"
#include "llpanel.h"
+#include "llinventorypanel.h" // for LLFolderViewModelInventory
#include "llinventory.h"
@@ -55,6 +56,8 @@ public:
virtual BOOL postBuild();
+ LLFolderViewModelInventory& getRootViewModel() { return mInventoryViewModel; }
+
void doToSelected(const LLSD& userdata);
void refresh();
@@ -85,8 +88,15 @@ protected:
LLInventoryObject* parent,
LLFolderViewFolder* folder);
void clearContents();
+ LLFolderViewItem* getItemByID(const LLUUID& id);
+
+ void addItemID( const LLUUID& id, LLFolderViewItem* itemp );
+ void removeItemID(const LLUUID& id);
+ void clearItemIDs();
private:
+ std::map<LLUUID, LLFolderViewItem*> mItemMap;
+
LLScrollContainer* mScroller;
LLFolderView* mFolders;
@@ -94,6 +104,7 @@ private:
BOOL mHaveInventory;
BOOL mIsInventoryEmpty;
BOOL mInventoryNeedsUpdate;
+ LLFolderViewModelInventory mInventoryViewModel;
};
#endif // LL_LLPANELOBJECTINVENTORY_H
diff --git a/indra/newview/llpanelonlinestatus.cpp b/indra/newview/llpanelonlinestatus.cpp
index 8202dfe9a3..8202dfe9a3 100644..100755
--- a/indra/newview/llpanelonlinestatus.cpp
+++ b/indra/newview/llpanelonlinestatus.cpp
diff --git a/indra/newview/llpanelonlinestatus.h b/indra/newview/llpanelonlinestatus.h
index 7dc648f135..7dc648f135 100644..100755
--- a/indra/newview/llpanelonlinestatus.h
+++ b/indra/newview/llpanelonlinestatus.h
diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp
index 35e2e96bab..c09d4393c8 100644..100755
--- a/indra/newview/llpaneloutfitedit.cpp
+++ b/indra/newview/llpaneloutfitedit.cpp
@@ -169,7 +169,7 @@ public:
return menu;
}
-
+
private:
static void onCreate(const LLSD& param)
{
@@ -187,7 +187,7 @@ private:
static void populateCreateWearableSubmenus(LLMenuGL* menu)
{
LLView* menu_clothes = gMenuHolder->getChildView("COF.Gear.New_Clothes", FALSE);
- LLView* menu_bp = gMenuHolder->getChildView("COF.Geear.New_Body_Parts", FALSE);
+ LLView* menu_bp = gMenuHolder->getChildView("COF.Gear.New_Body_Parts", FALSE);
for (U8 i = LLWearableType::WT_SHAPE; i != (U8) LLWearableType::WT_COUNT; ++i)
{
@@ -200,8 +200,7 @@ private:
p.on_click.function_name = "Wearable.Create";
p.on_click.parameter = LLSD(type_name);
- LLView* parent = LLWearableType::getAssetType(type) == LLAssetType::AT_CLOTHING ?
- menu_clothes : menu_bp;
+ LLView* parent = LLWearableType::getAssetType(type) == LLAssetType::AT_CLOTHING ? menu_clothes : menu_bp;
LLUICtrlFactory::create<LLMenuItemCallGL>(p, parent);
}
}
@@ -270,7 +269,7 @@ private:
if (inventory_panel->getVisible())
{
- inventory_panel->setSortOrder(sort_order);
+ inventory_panel->getFolderViewModel()->setSorter(sort_order);
}
else
{
@@ -738,7 +737,7 @@ void LLPanelOutfitEdit::onSearchEdit(const std::string& string)
}
// save current folder open state if no filter currently applied
- if (mInventoryItemsPanel->getRootFolder()->getFilterSubString().empty())
+ if (mInventoryItemsPanel->getFilterSubString().empty())
{
mSavedFolderState->setApply(FALSE);
mInventoryItemsPanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState);
@@ -885,13 +884,13 @@ LLPanelOutfitEdit::selection_info_t LLPanelOutfitEdit::getAddMorePanelSelectionT
{
if (mInventoryItemsPanel != NULL && mInventoryItemsPanel->getVisible())
{
- std::set<LLUUID> selected_uuids = mInventoryItemsPanel->getRootFolder()->getSelectionList();
+ std::set<LLFolderViewItem*> selected_items = mInventoryItemsPanel->getRootFolder()->getSelectionList();
- result.second = selected_uuids.size();
+ result.second = selected_items.size();
if (result.second == 1)
{
- result.first = getWearableTypeByItemUUID(*(selected_uuids.begin()));
+ result.first = getWearableTypeByItemUUID(static_cast<LLFolderViewModelItemInventory*>((*selected_items.begin())->getViewModelItem())->getUUID());
}
}
else if (mWearableItemsList != NULL && mWearableItemsList->getVisible())
@@ -1310,7 +1309,7 @@ void LLPanelOutfitEdit::getCurrentItemUUID(LLUUID& selected_id)
LLFolderViewItem* curr_item = mInventoryItemsPanel->getRootFolder()->getCurSelectedItem();
if (!curr_item) return;
- LLFolderViewEventListener* listenerp = curr_item->getListener();
+ LLFolderViewModelItemInventory* listenerp = static_cast<LLFolderViewModelItemInventory*>(curr_item->getViewModelItem());
if (!listenerp) return;
selected_id = listenerp->getUUID();
@@ -1327,9 +1326,13 @@ void LLPanelOutfitEdit::getSelectedItemsUUID(uuid_vec_t& uuid_list)
void (uuid_vec_t::* tmp)(LLUUID const &) = &uuid_vec_t::push_back;
if (mInventoryItemsPanel->getVisible())
{
- std::set<LLUUID> item_set = mInventoryItemsPanel->getRootFolder()->getSelectionList();
-
- std::for_each(item_set.begin(), item_set.end(), boost::bind( tmp, &uuid_list, _1));
+ std::set<LLFolderViewItem*> item_set = mInventoryItemsPanel->getRootFolder()->getSelectionList();
+ for (std::set<LLFolderViewItem*>::iterator it = item_set.begin(), end_it = item_set.end();
+ it != end_it;
+ ++it)
+ {
+ uuid_list.push_back(static_cast<LLFolderViewModelItemInventory*>((*it)->getViewModelItem())->getUUID());
+ }
}
else if (mWearablesListViewPanel->getVisible())
{
@@ -1374,13 +1377,13 @@ void LLPanelOutfitEdit::saveListSelection()
{
if(mWearablesListViewPanel->getVisible())
{
- std::set<LLUUID> selected_ids = mInventoryItemsPanel->getRootFolder()->getSelectionList();
+ std::set<LLFolderViewItem*> selected_ids = mInventoryItemsPanel->getRootFolder()->getSelectionList();
if(!selected_ids.size()) return;
- for (std::set<LLUUID>::const_iterator item_id = selected_ids.begin(); item_id != selected_ids.end(); ++item_id)
+ for (std::set<LLFolderViewItem*>::const_iterator item_id = selected_ids.begin(); item_id != selected_ids.end(); ++item_id)
{
- mWearableItemsList->selectItemByUUID(*item_id, true);
+ mWearableItemsList->selectItemByUUID(static_cast<LLFolderViewModelItemInventory*>((*item_id)->getViewModelItem())->getUUID(), true);
}
mWearableItemsList->scrollToShowFirstSelectedItem();
}
@@ -1398,7 +1401,7 @@ void LLPanelOutfitEdit::saveListSelection()
for(std::vector<LLUUID>::const_iterator item_id = selected_ids.begin(); item_id != selected_ids.end(); ++item_id)
{
- LLFolderViewItem* item = root->getItemByID(*item_id);
+ LLFolderViewItem* item = mInventoryItemsPanel->getItemByID(*item_id);
if (!item) continue;
LLFolderViewFolder* parent = item->getParentFolder();
diff --git a/indra/newview/llpaneloutfitedit.h b/indra/newview/llpaneloutfitedit.h
index 5d4b8d4644..5d4b8d4644 100644..100755
--- a/indra/newview/llpaneloutfitedit.h
+++ b/indra/newview/llpaneloutfitedit.h
diff --git a/indra/newview/llpaneloutfitsinventory.cpp b/indra/newview/llpaneloutfitsinventory.cpp
index f90236f6f2..f90236f6f2 100644..100755
--- a/indra/newview/llpaneloutfitsinventory.cpp
+++ b/indra/newview/llpaneloutfitsinventory.cpp
diff --git a/indra/newview/llpaneloutfitsinventory.h b/indra/newview/llpaneloutfitsinventory.h
index a7917b457c..a7917b457c 100644..100755
--- a/indra/newview/llpaneloutfitsinventory.h
+++ b/indra/newview/llpaneloutfitsinventory.h
diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp
index f1380e7a36..f551fc96ee 100644..100755
--- a/indra/newview/llpanelpeople.cpp
+++ b/indra/newview/llpanelpeople.cpp
@@ -28,6 +28,8 @@
// libs
#include "llavatarname.h"
+#include "llconversationview.h"
+#include "llfloaterimcontainer.h"
#include "llfloaterreg.h"
#include "llfloatersidepanelcontainer.h"
#include "llmenubutton.h"
@@ -48,15 +50,19 @@
#include "llavataractions.h"
#include "llavatarlist.h"
#include "llavatarlistitem.h"
+#include "llavatarnamecache.h"
#include "llcallingcard.h" // for LLAvatarTracker
+#include "llcallbacklist.h"
+#include "llerror.h"
+#include "llfacebookconnect.h"
#include "llfloateravatarpicker.h"
-//#include "llfloaterminiinspector.h"
#include "llfriendcard.h"
#include "llgroupactions.h"
#include "llgrouplist.h"
#include "llinventoryobserver.h"
#include "llnetmap.h"
#include "llpanelpeoplemenus.h"
+#include "llparticipantlist.h"
#include "llsidetraypanelcontainer.h"
#include "llrecentpeople.h"
#include "llviewercontrol.h" // for gSavedSettings
@@ -64,6 +70,10 @@
#include "llvoiceclient.h"
#include "llworld.h"
#include "llspeakers.h"
+#include "llfloaterwebcontent.h"
+
+#include "llagentui.h"
+#include "llslurl.h"
#define FRIEND_LIST_UPDATE_TIMEOUT 0.5
#define NEARBY_LIST_UPDATE_INTERVAL 1
@@ -72,9 +82,12 @@ static const std::string NEARBY_TAB_NAME = "nearby_panel";
static const std::string FRIENDS_TAB_NAME = "friends_panel";
static const std::string GROUP_TAB_NAME = "groups_panel";
static const std::string RECENT_TAB_NAME = "recent_panel";
-
+static const std::string BLOCKED_TAB_NAME = "blocked_panel"; // blocked avatars
static const std::string COLLAPSED_BY_USER = "collapsed_by_user";
+
+extern S32 gMaxAgentGroups;
+
/** Comparator for comparing avatar items by last interaction date */
class LLAvatarItemRecentComparator : public LLAvatarItemComparator
{
@@ -492,26 +505,38 @@ public:
LLPanelPeople::LLPanelPeople()
: LLPanel(),
- mFilterSubString(LLStringUtil::null),
- mFilterSubStringOrig(LLStringUtil::null),
- mFilterEditor(NULL),
+ mTryToConnectToFbc(true),
mTabContainer(NULL),
mOnlineFriendList(NULL),
mAllFriendList(NULL),
mNearbyList(NULL),
mRecentList(NULL),
mGroupList(NULL),
- mNearbyGearButton(NULL),
- mFriendsGearButton(NULL),
- mGroupsGearButton(NULL),
- mRecentGearButton(NULL),
mMiniMap(NULL)
{
mFriendListUpdater = new LLFriendListUpdater(boost::bind(&LLPanelPeople::updateFriendList, this));
mNearbyListUpdater = new LLNearbyListUpdater(boost::bind(&LLPanelPeople::updateNearbyList, this));
mRecentListUpdater = new LLRecentListUpdater(boost::bind(&LLPanelPeople::updateRecentList, this));
mButtonsUpdater = new LLButtonsUpdater(boost::bind(&LLPanelPeople::updateButtons, this));
- mCommitCallbackRegistrar.add("People.addFriend", boost::bind(&LLPanelPeople::onAddFriendButtonClicked, this));
+
+ mCommitCallbackRegistrar.add("People.AddFriend", boost::bind(&LLPanelPeople::onAddFriendButtonClicked, this));
+ mCommitCallbackRegistrar.add("People.AddFriendWizard", boost::bind(&LLPanelPeople::onAddFriendWizButtonClicked, this));
+ mCommitCallbackRegistrar.add("People.DelFriend", boost::bind(&LLPanelPeople::onDeleteFriendButtonClicked, this));
+ mCommitCallbackRegistrar.add("People.Group.Minus", boost::bind(&LLPanelPeople::onGroupMinusButtonClicked, this));
+ mCommitCallbackRegistrar.add("People.Chat", boost::bind(&LLPanelPeople::onChatButtonClicked, this));
+ mCommitCallbackRegistrar.add("People.Gear", boost::bind(&LLPanelPeople::onGearButtonClicked, this, _1));
+
+ mCommitCallbackRegistrar.add("People.Group.Plus.Action", boost::bind(&LLPanelPeople::onGroupPlusMenuItemClicked, this, _2));
+ mCommitCallbackRegistrar.add("People.Friends.ViewSort.Action", boost::bind(&LLPanelPeople::onFriendsViewSortMenuItemClicked, this, _2));
+ mCommitCallbackRegistrar.add("People.Nearby.ViewSort.Action", boost::bind(&LLPanelPeople::onNearbyViewSortMenuItemClicked, this, _2));
+ mCommitCallbackRegistrar.add("People.Groups.ViewSort.Action", boost::bind(&LLPanelPeople::onGroupsViewSortMenuItemClicked, this, _2));
+ mCommitCallbackRegistrar.add("People.Recent.ViewSort.Action", boost::bind(&LLPanelPeople::onRecentViewSortMenuItemClicked, this, _2));
+
+ mEnableCallbackRegistrar.add("People.Friends.ViewSort.CheckItem", boost::bind(&LLPanelPeople::onFriendsViewSortMenuItemCheck, this, _2));
+ mEnableCallbackRegistrar.add("People.Recent.ViewSort.CheckItem", boost::bind(&LLPanelPeople::onRecentViewSortMenuItemCheck, this, _2));
+ mEnableCallbackRegistrar.add("People.Nearby.ViewSort.CheckItem", boost::bind(&LLPanelPeople::onNearbyViewSortMenuItemCheck, this, _2));
+
+ mEnableCallbackRegistrar.add("People.Group.Plus.Validate", boost::bind(&LLPanelPeople::onGroupPlusButtonValidate, this));
}
LLPanelPeople::~LLPanelPeople()
@@ -525,13 +550,6 @@ LLPanelPeople::~LLPanelPeople()
{
LLVoiceClient::getInstance()->removeObserver(this);
}
-
- if (mGroupPlusMenuHandle.get()) mGroupPlusMenuHandle.get()->die();
- if (mNearbyViewSortMenuHandle.get()) mNearbyViewSortMenuHandle.get()->die();
- if (mNearbyViewSortMenuHandle.get()) mNearbyViewSortMenuHandle.get()->die();
- if (mGroupsViewSortMenuHandle.get()) mGroupsViewSortMenuHandle.get()->die();
- if (mRecentViewSortMenuHandle.get()) mRecentViewSortMenuHandle.get()->die();
-
}
void LLPanelPeople::onFriendsAccordionExpandedCollapsed(LLUICtrl* ctrl, const LLSD& param, LLAvatarList* avatar_list)
@@ -551,19 +569,37 @@ void LLPanelPeople::onFriendsAccordionExpandedCollapsed(LLUICtrl* ctrl, const LL
}
}
+
+void LLPanelPeople::removePicker()
+{
+ if(mPicker.get())
+ {
+ mPicker.get()->closeFloater();
+ }
+}
+
BOOL LLPanelPeople::postBuild()
{
- mFilterEditor = getChild<LLFilterEditor>("filter_input");
- mFilterEditor->setCommitCallback(boost::bind(&LLPanelPeople::onFilterEdit, this, _2));
+ getChild<LLFilterEditor>("nearby_filter_input")->setCommitCallback(boost::bind(&LLPanelPeople::onFilterEdit, this, _2));
+ getChild<LLFilterEditor>("friends_filter_input")->setCommitCallback(boost::bind(&LLPanelPeople::onFilterEdit, this, _2));
+ getChild<LLFilterEditor>("groups_filter_input")->setCommitCallback(boost::bind(&LLPanelPeople::onFilterEdit, this, _2));
+ getChild<LLFilterEditor>("recent_filter_input")->setCommitCallback(boost::bind(&LLPanelPeople::onFilterEdit, this, _2));
+ getChild<LLFilterEditor>("fbc_filter_input")->setCommitCallback(boost::bind(&LLPanelPeople::onFilterEdit, this, _2));
mTabContainer = getChild<LLTabContainer>("tabs");
mTabContainer->setCommitCallback(boost::bind(&LLPanelPeople::onTabSelected, this, _2));
+ mSavedFilters.resize(mTabContainer->getTabCount());
+ mSavedOriginalFilters.resize(mTabContainer->getTabCount());
LLPanel* friends_tab = getChild<LLPanel>(FRIENDS_TAB_NAME);
// updater is active only if panel is visible to user.
friends_tab->setVisibleCallback(boost::bind(&Updater::setActive, mFriendListUpdater, _2));
+ friends_tab->setVisibleCallback(boost::bind(&LLPanelPeople::removePicker, this));
+ friends_tab->setVisibleCallback(boost::bind(&LLPanelPeople::updateFacebookList, this, _2));
+
mOnlineFriendList = friends_tab->getChild<LLAvatarList>("avatars_online");
mAllFriendList = friends_tab->getChild<LLAvatarList>("avatars_all");
+ mSuggestedFriends = friends_tab->getChild<LLAvatarList>("suggested_friends");
mOnlineFriendList->setNoItemsCommentText(getString("no_friends_online"));
mOnlineFriendList->setShowIcons("FriendsListShowIcons");
mOnlineFriendList->showPermissions("FriendsListShowPermissions");
@@ -592,23 +628,16 @@ BOOL LLPanelPeople::postBuild()
mGroupList->setNoItemsMsg(getString("no_groups_msg"));
mGroupList->setNoFilteredItemsMsg(getString("no_filtered_groups_msg"));
- mNearbyList->setContextMenu(&LLPanelPeopleMenus::gNearbyMenu);
- mRecentList->setContextMenu(&LLPanelPeopleMenus::gNearbyMenu);
- mAllFriendList->setContextMenu(&LLPanelPeopleMenus::gNearbyMenu);
- mOnlineFriendList->setContextMenu(&LLPanelPeopleMenus::gNearbyMenu);
+ mNearbyList->setContextMenu(&LLPanelPeopleMenus::gNearbyPeopleContextMenu);
+ mRecentList->setContextMenu(&LLPanelPeopleMenus::gPeopleContextMenu);
+ mAllFriendList->setContextMenu(&LLPanelPeopleMenus::gPeopleContextMenu);
+ mOnlineFriendList->setContextMenu(&LLPanelPeopleMenus::gPeopleContextMenu);
+ mSuggestedFriends->setContextMenu(&LLPanelPeopleMenus::gSuggestedFriendsContextMenu);
setSortOrder(mRecentList, (ESortOrder)gSavedSettings.getU32("RecentPeopleSortOrder"), false);
setSortOrder(mAllFriendList, (ESortOrder)gSavedSettings.getU32("FriendsSortOrder"), false);
setSortOrder(mNearbyList, (ESortOrder)gSavedSettings.getU32("NearbyPeopleSortOrder"), false);
- LLPanel* groups_panel = getChild<LLPanel>(GROUP_TAB_NAME);
- groups_panel->childSetAction("activate_btn", boost::bind(&LLPanelPeople::onActivateButtonClicked, this));
- groups_panel->childSetAction("plus_btn", boost::bind(&LLPanelPeople::onGroupPlusButtonClicked, this));
-
- LLPanel* friends_panel = getChild<LLPanel>(FRIENDS_TAB_NAME);
- friends_panel->childSetAction("add_btn", boost::bind(&LLPanelPeople::onAddFriendWizButtonClicked, this));
- friends_panel->childSetAction("del_btn", boost::bind(&LLPanelPeople::onDeleteFriendButtonClicked, this));
-
mOnlineFriendList->setItemDoubleClickCallback(boost::bind(&LLPanelPeople::onAvatarListDoubleClicked, this, _1));
mAllFriendList->setItemDoubleClickCallback(boost::bind(&LLPanelPeople::onAvatarListDoubleClicked, this, _1));
mNearbyList->setItemDoubleClickCallback(boost::bind(&LLPanelPeople::onAvatarListDoubleClicked, this, _1));
@@ -629,6 +658,19 @@ BOOL LLPanelPeople::postBuild()
mGroupList->setCommitCallback(boost::bind(&LLPanelPeople::updateButtons, this));
mGroupList->setReturnCallback(boost::bind(&LLPanelPeople::onChatButtonClicked, this));
+ LLMenuButton* groups_gear_btn = getChild<LLMenuButton>("groups_gear_btn");
+
+ // Use the context menu of the Groups list for the Groups tab gear menu.
+ LLToggleableMenu* groups_gear_menu = mGroupList->getContextMenu();
+ if (groups_gear_menu)
+ {
+ groups_gear_btn->setMenu(groups_gear_menu, LLMenuButton::MP_BOTTOM_LEFT);
+ }
+ else
+ {
+ llwarns << "People->Groups list menu not found" << llendl;
+ }
+
LLAccordionCtrlTab* accordion_tab = getChild<LLAccordionCtrlTab>("tab_all");
accordion_tab->setDropDownStateChangedCallback(
boost::bind(&LLPanelPeople::onFriendsAccordionExpandedCollapsed, this, _1, _2, mAllFriendList));
@@ -637,70 +679,9 @@ BOOL LLPanelPeople::postBuild()
accordion_tab->setDropDownStateChangedCallback(
boost::bind(&LLPanelPeople::onFriendsAccordionExpandedCollapsed, this, _1, _2, mOnlineFriendList));
- buttonSetAction("view_profile_btn", boost::bind(&LLPanelPeople::onViewProfileButtonClicked, this));
- buttonSetAction("group_info_btn", boost::bind(&LLPanelPeople::onGroupInfoButtonClicked, this));
- buttonSetAction("chat_btn", boost::bind(&LLPanelPeople::onChatButtonClicked, this));
- buttonSetAction("im_btn", boost::bind(&LLPanelPeople::onImButtonClicked, this));
- buttonSetAction("call_btn", boost::bind(&LLPanelPeople::onCallButtonClicked, this));
- buttonSetAction("group_call_btn", boost::bind(&LLPanelPeople::onGroupCallButtonClicked, this));
- buttonSetAction("teleport_btn", boost::bind(&LLPanelPeople::onTeleportButtonClicked, this));
- buttonSetAction("share_btn", boost::bind(&LLPanelPeople::onShareButtonClicked, this));
-
// Must go after setting commit callback and initializing all pointers to children.
mTabContainer->selectTabByName(NEARBY_TAB_NAME);
- // Create menus.
- LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
- LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
-
- registrar.add("People.Group.Plus.Action", boost::bind(&LLPanelPeople::onGroupPlusMenuItemClicked, this, _2));
- registrar.add("People.Group.Minus.Action", boost::bind(&LLPanelPeople::onGroupMinusButtonClicked, this));
- registrar.add("People.Friends.ViewSort.Action", boost::bind(&LLPanelPeople::onFriendsViewSortMenuItemClicked, this, _2));
- registrar.add("People.Nearby.ViewSort.Action", boost::bind(&LLPanelPeople::onNearbyViewSortMenuItemClicked, this, _2));
- registrar.add("People.Groups.ViewSort.Action", boost::bind(&LLPanelPeople::onGroupsViewSortMenuItemClicked, this, _2));
- registrar.add("People.Recent.ViewSort.Action", boost::bind(&LLPanelPeople::onRecentViewSortMenuItemClicked, this, _2));
-
- enable_registrar.add("People.Group.Minus.Enable", boost::bind(&LLPanelPeople::isRealGroup, this));
- enable_registrar.add("People.Friends.ViewSort.CheckItem", boost::bind(&LLPanelPeople::onFriendsViewSortMenuItemCheck, this, _2));
- enable_registrar.add("People.Recent.ViewSort.CheckItem", boost::bind(&LLPanelPeople::onRecentViewSortMenuItemCheck, this, _2));
- enable_registrar.add("People.Nearby.ViewSort.CheckItem", boost::bind(&LLPanelPeople::onNearbyViewSortMenuItemCheck, this, _2));
-
- mNearbyGearButton = getChild<LLMenuButton>("nearby_view_sort_btn");
- mFriendsGearButton = getChild<LLMenuButton>("friends_viewsort_btn");
- mGroupsGearButton = getChild<LLMenuButton>("groups_viewsort_btn");
- mRecentGearButton = getChild<LLMenuButton>("recent_viewsort_btn");
-
- LLMenuGL* plus_menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_group_plus.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
- mGroupPlusMenuHandle = plus_menu->getHandle();
-
- LLToggleableMenu* nearby_view_sort = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_people_nearby_view_sort.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
- if(nearby_view_sort)
- {
- mNearbyViewSortMenuHandle = nearby_view_sort->getHandle();
- mNearbyGearButton->setMenu(nearby_view_sort);
- }
-
- LLToggleableMenu* friend_view_sort = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_people_friends_view_sort.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
- if(friend_view_sort)
- {
- mFriendsViewSortMenuHandle = friend_view_sort->getHandle();
- mFriendsGearButton->setMenu(friend_view_sort);
- }
-
- LLToggleableMenu* group_view_sort = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_people_groups_view_sort.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
- if(group_view_sort)
- {
- mGroupsViewSortMenuHandle = group_view_sort->getHandle();
- mGroupsGearButton->setMenu(group_view_sort);
- }
-
- LLToggleableMenu* recent_view_sort = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_people_recent_view_sort.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
- if(recent_view_sort)
- {
- mRecentViewSortMenuHandle = recent_view_sort->getHandle();
- mRecentGearButton->setMenu(recent_view_sort);
- }
-
LLVoiceClient::getInstance()->addObserver(this);
// call this method in case some list is empty and buttons can be in inconsistent state
@@ -730,14 +711,16 @@ void LLPanelPeople::updateFriendListHelpText()
// Seems sometimes all_friends can be empty because of issue with Inventory loading (clear cache, slow connection...)
// So, lets check all lists to avoid overlapping the text with online list. See EXT-6448.
- bool any_friend_exists = mAllFriendList->filterHasMatches() || mOnlineFriendList->filterHasMatches();
+ bool any_friend_exists = mAllFriendList->filterHasMatches() || mOnlineFriendList->filterHasMatches() || mSuggestedFriends->filterHasMatches();
no_friends_text->setVisible(!any_friend_exists);
if (no_friends_text->getVisible())
{
//update help text for empty lists
- std::string message_name = mFilterSubString.empty() ? "no_friends_msg" : "no_filtered_friends_msg";
+ const std::string& filter = mSavedOriginalFilters[mTabContainer->getCurrentPanelIndex()];
+
+ std::string message_name = filter.empty() ? "no_friends_msg" : "no_filtered_friends_msg";
LLStringUtil::format_map_t args;
- args["[SEARCH_TERM]"] = LLURI::escape(mFilterSubStringOrig);
+ args["[SEARCH_TERM]"] = LLURI::escape(filter);
no_friends_text->setText(getString(message_name, args));
}
}
@@ -795,9 +778,40 @@ void LLPanelPeople::updateFriendList()
mAllFriendList->setDirty(true, !mAllFriendList->filterHasMatches());
//update trash and other buttons according to a selected item
updateButtons();
+ updateSuggestedFriendList();
showFriendsAccordionsIfNeeded();
}
+bool LLPanelPeople::updateSuggestedFriendList()
+{
+ const LLAvatarTracker& av_tracker = LLAvatarTracker::instance();
+ uuid_vec_t& suggested_friends = mSuggestedFriends->getIDs();
+ suggested_friends.clear();
+
+ //Add suggested friends
+ LLSD friends = LLFacebookConnect::instance().getContent();
+ for (LLSD::array_const_iterator i = friends.beginArray(); i != friends.endArray(); ++i)
+ {
+ LLUUID agent_id = (*i).asUUID();
+ bool second_life_buddy = agent_id.notNull() ? av_tracker.isBuddy(agent_id) : false;
+
+ if(!second_life_buddy)
+ {
+ //FB+SL but not SL friend
+ if (agent_id.notNull())
+ {
+ suggested_friends.push_back(agent_id);
+ }
+ }
+ }
+
+ //Force a refresh when there aren't any filter matches (prevent displaying content that shouldn't display)
+ mSuggestedFriends->setDirty(true, !mSuggestedFriends->filterHasMatches());
+ showFriendsAccordionsIfNeeded();
+
+ return false;
+}
+
void LLPanelPeople::updateNearbyList()
{
if (!mNearbyList)
@@ -821,31 +835,54 @@ void LLPanelPeople::updateRecentList()
mRecentList->setDirty();
}
-void LLPanelPeople::buttonSetVisible(std::string btn_name, BOOL visible)
+bool LLPanelPeople::onConnectedToFacebook(const LLSD& data)
{
- // To make sure we're referencing the right widget (a child of the button bar).
- LLButton* button = getChild<LLView>("button_bar")->getChild<LLButton>(btn_name);
- button->setVisible(visible);
-}
+ LLSD::Integer connection_state = data.get("enum").asInteger();
-void LLPanelPeople::buttonSetEnabled(const std::string& btn_name, bool enabled)
-{
- // To make sure we're referencing the right widget (a child of the button bar).
- LLButton* button = getChild<LLView>("button_bar")->getChild<LLButton>(btn_name);
- button->setEnabled(enabled);
+ if (connection_state == LLFacebookConnect::FB_CONNECTED)
+ {
+ LLFacebookConnect::instance().loadFacebookFriends();
+ }
+ else if(connection_state == LLFacebookConnect::FB_NOT_CONNECTED)
+ {
+ updateSuggestedFriendList();
+ };
+
+ return false;
}
-void LLPanelPeople::buttonSetAction(const std::string& btn_name, const commit_signal_t::slot_type& cb)
+void LLPanelPeople::updateFacebookList(bool visible)
{
- // To make sure we're referencing the right widget (a child of the button bar).
- LLButton* button = getChild<LLView>("button_bar")->getChild<LLButton>(btn_name);
- button->setClickedCallback(cb);
+ if (visible)
+ {
+ LLEventPumps::instance().obtain("FacebookConnectContent").stopListening("LLPanelPeople"); // just in case it is already listening
+ LLEventPumps::instance().obtain("FacebookConnectContent").listen("LLPanelPeople", boost::bind(&LLPanelPeople::updateSuggestedFriendList, this));
+
+ LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLPanelPeople"); // just in case it is already listening
+ LLEventPumps::instance().obtain("FacebookConnectState").listen("LLPanelPeople", boost::bind(&LLPanelPeople::onConnectedToFacebook, this, _1));
+
+ if (LLFacebookConnect::instance().isConnected())
+ {
+ LLFacebookConnect::instance().loadFacebookFriends();
+ }
+ else if(mTryToConnectToFbc)
+ {
+ LLFacebookConnect::instance().checkConnectionToFacebook();
+ mTryToConnectToFbc = false;
+ }
+
+ updateSuggestedFriendList();
+ }
+ else
+ {
+ LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLPanelPeople");
+ LLEventPumps::instance().obtain("FacebookConnectContent").stopListening("LLPanelPeople");
+ }
}
void LLPanelPeople::updateButtons()
{
std::string cur_tab = getActiveTabName();
- bool nearby_tab_active = (cur_tab == NEARBY_TAB_NAME);
bool friends_tab_active = (cur_tab == FRIENDS_TAB_NAME);
bool group_tab_active = (cur_tab == GROUP_TAB_NAME);
//bool recent_tab_active = (cur_tab == RECENT_TAB_NAME);
@@ -856,63 +893,47 @@ void LLPanelPeople::updateButtons()
bool item_selected = (selected_uuids.size() == 1);
bool multiple_selected = (selected_uuids.size() >= 1);
- buttonSetVisible("group_info_btn", group_tab_active);
- buttonSetVisible("chat_btn", group_tab_active);
- buttonSetVisible("view_profile_btn", !group_tab_active);
- buttonSetVisible("im_btn", !group_tab_active);
- buttonSetVisible("call_btn", !group_tab_active);
- buttonSetVisible("group_call_btn", group_tab_active);
- buttonSetVisible("teleport_btn", friends_tab_active);
- buttonSetVisible("share_btn", nearby_tab_active || friends_tab_active);
-
if (group_tab_active)
{
- bool cur_group_active = true;
-
if (item_selected)
{
selected_id = mGroupList->getSelectedUUID();
- cur_group_active = (gAgent.getGroupID() == selected_id);
}
LLPanel* groups_panel = mTabContainer->getCurrentPanel();
- groups_panel->getChildView("activate_btn")->setEnabled(item_selected && !cur_group_active); // "none" or a non-active group selected
- groups_panel->getChildView("minus_btn")->setEnabled(item_selected && selected_id.notNull());
+ groups_panel->getChildView("minus_btn")->setEnabled(item_selected && selected_id.notNull()); // a real group selected
+ groups_panel->getChild<LLUICtrl>("groupcount")->setTextArg("[COUNT]", llformat("%d",gAgent.mGroups.count()));
+ groups_panel->getChild<LLUICtrl>("groupcount")->setTextArg("[REMAINING]", llformat("%d",(gMaxAgentGroups-gAgent.mGroups.count())));
}
else
{
bool is_friend = true;
-
+ bool is_self = false;
// Check whether selected avatar is our friend.
if (item_selected)
{
selected_id = selected_uuids.front();
is_friend = LLAvatarTracker::instance().getBuddyInfo(selected_id) != NULL;
+ is_self = gAgent.getID() == selected_id;
}
LLPanel* cur_panel = mTabContainer->getCurrentPanel();
if (cur_panel)
{
- cur_panel->getChildView("add_friend_btn")->setEnabled(!is_friend);
+ if (cur_panel->hasChild("add_friend_btn", TRUE))
+ cur_panel->getChildView("add_friend_btn")->setEnabled(item_selected && !is_friend && !is_self);
+
if (friends_tab_active)
{
- cur_panel->getChildView("del_btn")->setEnabled(multiple_selected);
+ cur_panel->getChildView("friends_del_btn")->setEnabled(multiple_selected);
+ }
+
+ if (!group_tab_active)
+ {
+ cur_panel->getChildView("gear_btn")->setEnabled(multiple_selected);
}
}
}
-
- bool enable_calls = LLVoiceClient::getInstance()->isVoiceWorking() && LLVoiceClient::getInstance()->voiceEnabled();
-
- buttonSetEnabled("view_profile_btn",item_selected);
- buttonSetEnabled("share_btn", item_selected);
- buttonSetEnabled("im_btn", multiple_selected); // allow starting the friends conference for multiple selection
- buttonSetEnabled("call_btn", multiple_selected && enable_calls);
- buttonSetEnabled("teleport_btn", multiple_selected && LLAvatarActions::canOfferTeleport(selected_uuids));
-
- bool none_group_selected = item_selected && selected_id.isNull();
- buttonSetEnabled("group_info_btn", !none_group_selected);
- buttonSetEnabled("group_call_btn", !none_group_selected && enable_calls);
- buttonSetEnabled("chat_btn", !none_group_selected);
}
std::string LLPanelPeople::getActiveTabName() const
@@ -943,6 +964,9 @@ LLUUID LLPanelPeople::getCurrentItemID() const
if (cur_tab == GROUP_TAB_NAME)
return mGroupList->getSelectedUUID();
+ if (cur_tab == BLOCKED_TAB_NAME)
+ return LLUUID::null; // FIXME?
+
llassert(0 && "unknown tab selected");
return LLUUID::null;
}
@@ -963,6 +987,8 @@ void LLPanelPeople::getCurrentItemIDs(uuid_vec_t& selected_uuids) const
mRecentList->getSelectedUUIDs(selected_uuids);
else if (cur_tab == GROUP_TAB_NAME)
mGroupList->getSelectedUUIDs(selected_uuids);
+ else if (cur_tab == BLOCKED_TAB_NAME)
+ selected_uuids.clear(); // FIXME?
else
llassert(0 && "unknown tab selected");
@@ -1031,47 +1057,60 @@ void LLPanelPeople::setSortOrder(LLAvatarList* list, ESortOrder order, bool save
}
}
-bool LLPanelPeople::isRealGroup()
-{
- return getCurrentItemID() != LLUUID::null;
-}
-
void LLPanelPeople::onFilterEdit(const std::string& search_string)
{
- mFilterSubStringOrig = search_string;
- LLStringUtil::trimHead(mFilterSubStringOrig);
+ const S32 cur_tab_idx = mTabContainer->getCurrentPanelIndex();
+ std::string& filter = mSavedOriginalFilters[cur_tab_idx];
+ std::string& saved_filter = mSavedFilters[cur_tab_idx];
+
+ filter = search_string;
+ LLStringUtil::trimHead(filter);
+
// Searches are case-insensitive
- std::string search_upper = mFilterSubStringOrig;
+ std::string search_upper = filter;
LLStringUtil::toUpper(search_upper);
- if (mFilterSubString == search_upper)
+ if (saved_filter == search_upper)
return;
- mFilterSubString = search_upper;
+ saved_filter = search_upper;
- //store accordion tabs state before any manipulation with accordion tabs
- if(!mFilterSubString.empty())
+ // Apply new filter to the current tab.
+ const std::string cur_tab = getActiveTabName();
+ if (cur_tab == NEARBY_TAB_NAME)
{
- notifyChildren(LLSD().with("action","store_state"));
+ mNearbyList->setNameFilter(filter);
}
+ else if (cur_tab == FRIENDS_TAB_NAME)
+ {
+ // store accordion tabs opened/closed state before any manipulation with accordion tabs
+ if (!saved_filter.empty())
+ {
+ notifyChildren(LLSD().with("action","store_state"));
+ }
+ mOnlineFriendList->setNameFilter(filter);
+ mAllFriendList->setNameFilter(filter);
+ mSuggestedFriends->setNameFilter(filter);
- // Apply new filter.
- mNearbyList->setNameFilter(mFilterSubStringOrig);
- mOnlineFriendList->setNameFilter(mFilterSubStringOrig);
- mAllFriendList->setNameFilter(mFilterSubStringOrig);
- mRecentList->setNameFilter(mFilterSubStringOrig);
- mGroupList->setNameFilter(mFilterSubStringOrig);
-
- setAccordionCollapsedByUser("tab_online", false);
- setAccordionCollapsedByUser("tab_all", false);
-
- showFriendsAccordionsIfNeeded();
+ setAccordionCollapsedByUser("tab_online", false);
+ setAccordionCollapsedByUser("tab_all", false);
+ setAccordionCollapsedByUser("tab_suggested_friends", false);
+ showFriendsAccordionsIfNeeded();
- //restore accordion tabs state _after_ all manipulations...
- if(mFilterSubString.empty())
+ // restore accordion tabs state _after_ all manipulations
+ if(saved_filter.empty())
+ {
+ notifyChildren(LLSD().with("action","restore_state"));
+ }
+ }
+ else if (cur_tab == GROUP_TAB_NAME)
+ {
+ mGroupList->setNameFilter(filter);
+ }
+ else if (cur_tab == RECENT_TAB_NAME)
{
- notifyChildren(LLSD().with("action","restore_state"));
+ mRecentList->setNameFilter(filter);
}
}
@@ -1081,11 +1120,6 @@ void LLPanelPeople::onTabSelected(const LLSD& param)
updateButtons();
showFriendsAccordionsIfNeeded();
-
- if (GROUP_TAB_NAME == tab_name)
- mFilterEditor->setLabel(getString("groups_filter_label"));
- else
- mFilterEditor->setLabel(getString("people_filter_label"));
}
void LLPanelPeople::onAvatarListDoubleClicked(LLUICtrl* ctrl)
@@ -1097,6 +1131,10 @@ void LLPanelPeople::onAvatarListDoubleClicked(LLUICtrl* ctrl)
}
LLUUID clicked_id = item->getAvatarId();
+ if(gAgent.getID() == clicked_id)
+ {
+ return;
+ }
#if 0 // SJB: Useful for testing, but not currently functional or to spec
LLAvatarActions::showProfile(clicked_id);
@@ -1127,12 +1165,6 @@ void LLPanelPeople::onAvatarListCommitted(LLAvatarList* list)
updateButtons();
}
-void LLPanelPeople::onViewProfileButtonClicked()
-{
- LLUUID id = getCurrentItemID();
- LLAvatarActions::showProfile(id);
-}
-
void LLPanelPeople::onAddFriendButtonClicked()
{
LLUUID id = getCurrentItemID();
@@ -1160,8 +1192,12 @@ bool LLPanelPeople::isItemsFreeOfFriends(const uuid_vec_t& uuids)
void LLPanelPeople::onAddFriendWizButtonClicked()
{
+ LLPanel* cur_panel = mTabContainer->getCurrentPanel();
+ LLView * button = cur_panel->findChild<LLButton>("friends_add_btn", TRUE);
+
// Show add friend wizard.
- LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(boost::bind(&LLPanelPeople::onAvatarPicked, _1, _2), FALSE, TRUE);
+ LLFloater* root_floater = gFloaterView->getParentFloater(this);
+ LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(boost::bind(&LLPanelPeople::onAvatarPicked, _1, _2), FALSE, TRUE, FALSE, root_floater->getName(), button);
if (!picker)
{
return;
@@ -1169,11 +1205,13 @@ void LLPanelPeople::onAddFriendWizButtonClicked()
// Need to disable 'ok' button when friend occurs in selection
picker->setOkBtnEnableCb(boost::bind(&LLPanelPeople::isItemsFreeOfFriends, this, _1));
- LLFloater* root_floater = gFloaterView->getParentFloater(this);
+
if (root_floater)
{
root_floater->addDependentFloater(picker);
}
+
+ mPicker = picker->getHandle();
}
void LLPanelPeople::onDeleteFriendButtonClicked()
@@ -1191,11 +1229,6 @@ void LLPanelPeople::onDeleteFriendButtonClicked()
}
}
-void LLPanelPeople::onGroupInfoButtonClicked()
-{
- LLGroupActions::show(getCurrentItemID());
-}
-
void LLPanelPeople::onChatButtonClicked()
{
LLUUID group_id = getCurrentItemID();
@@ -1203,6 +1236,17 @@ void LLPanelPeople::onChatButtonClicked()
LLGroupActions::startIM(group_id);
}
+void LLPanelPeople::onGearButtonClicked(LLUICtrl* btn)
+{
+ uuid_vec_t selected_uuids;
+ getCurrentItemIDs(selected_uuids);
+ // Spawn at bottom left corner of the button.
+ if (getActiveTabName() == NEARBY_TAB_NAME)
+ LLPanelPeopleMenus::gNearbyPeopleContextMenu.show(btn, selected_uuids, 0, 0);
+ else
+ LLPanelPeopleMenus::gPeopleContextMenu.show(btn, selected_uuids, 0, 0);
+}
+
void LLPanelPeople::onImButtonClicked()
{
uuid_vec_t selected_uuids;
@@ -1219,11 +1263,6 @@ void LLPanelPeople::onImButtonClicked()
}
}
-void LLPanelPeople::onActivateButtonClicked()
-{
- LLGroupActions::activate(mGroupList->getSelectedUUID());
-}
-
// static
void LLPanelPeople::onAvatarPicked(const uuid_vec_t& ids, const std::vector<LLAvatarName> names)
{
@@ -1231,19 +1270,15 @@ void LLPanelPeople::onAvatarPicked(const uuid_vec_t& ids, const std::vector<LLAv
LLAvatarActions::requestFriendshipDialog(ids[0], names[0].getCompleteName());
}
-void LLPanelPeople::onGroupPlusButtonClicked()
+bool LLPanelPeople::onGroupPlusButtonValidate()
{
if (!gAgent.canJoinGroups())
{
LLNotificationsUtil::add("JoinedTooManyGroups");
- return;
+ return false;
}
- LLMenuGL* plus_menu = (LLMenuGL*)mGroupPlusMenuHandle.get();
- if (!plus_menu)
- return;
-
- showGroupMenu(plus_menu);
+ return true;
}
void LLPanelPeople::onGroupMinusButtonClicked()
@@ -1288,11 +1323,7 @@ void LLPanelPeople::onFriendsViewSortMenuItemClicked(const LLSD& userdata)
mAllFriendList->showPermissions(show_permissions);
mOnlineFriendList->showPermissions(show_permissions);
}
- else if (chosen_item == "panel_block_list_sidetray")
- {
- LLFloaterSidePanelContainer::showPanel("people", "panel_block_list_sidetray", LLSD());
}
-}
void LLPanelPeople::onGroupsViewSortMenuItemClicked(const LLSD& userdata)
{
@@ -1324,10 +1355,6 @@ void LLPanelPeople::onNearbyViewSortMenuItemClicked(const LLSD& userdata)
{
setSortOrder(mNearbyList, E_SORT_BY_DISTANCE);
}
- else if (chosen_item == "panel_block_list_sidetray")
- {
- LLFloaterSidePanelContainer::showPanel("people", "panel_block_list_sidetray", LLSD());
- }
}
bool LLPanelPeople::onNearbyViewSortMenuItemCheck(const LLSD& userdata)
@@ -1361,10 +1388,6 @@ void LLPanelPeople::onRecentViewSortMenuItemClicked(const LLSD& userdata)
{
mRecentList->toggleIcons();
}
- else if (chosen_item == "panel_block_list_sidetray")
- {
- LLFloaterSidePanelContainer::showPanel("people", "panel_block_list_sidetray", LLSD());
- }
}
bool LLPanelPeople::onFriendsViewSortMenuItemCheck(const LLSD& userdata)
@@ -1393,40 +1416,6 @@ bool LLPanelPeople::onRecentViewSortMenuItemCheck(const LLSD& userdata)
return false;
}
-void LLPanelPeople::onCallButtonClicked()
-{
- uuid_vec_t selected_uuids;
- getCurrentItemIDs(selected_uuids);
-
- if (selected_uuids.size() == 1)
- {
- // initiate a P2P voice chat with the selected user
- LLAvatarActions::startCall(getCurrentItemID());
- }
- else if (selected_uuids.size() > 1)
- {
- // initiate an ad-hoc voice chat with multiple users
- LLAvatarActions::startAdhocCall(selected_uuids);
- }
-}
-
-void LLPanelPeople::onGroupCallButtonClicked()
-{
- LLGroupActions::startCall(getCurrentItemID());
-}
-
-void LLPanelPeople::onTeleportButtonClicked()
-{
- uuid_vec_t selected_uuids;
- getCurrentItemIDs(selected_uuids);
- LLAvatarActions::offerTeleport(selected_uuids);
-}
-
-void LLPanelPeople::onShareButtonClicked()
-{
- LLAvatarActions::share(getCurrentItemID());
-}
-
void LLPanelPeople::onMoreButtonClicked()
{
// *TODO: not implemented yet
@@ -1492,6 +1481,7 @@ void LLPanelPeople::showFriendsAccordionsIfNeeded()
// Expand and show accordions if needed, else - hide them
showAccordion("tab_online", mOnlineFriendList->filterHasMatches());
showAccordion("tab_all", mAllFriendList->filterHasMatches());
+ showAccordion("tab_suggested_friends", mSuggestedFriends->filterHasMatches());
// Rearrange accordions
LLAccordionCtrl* accordion = getChild<LLAccordionCtrl>("friends_accordion");
@@ -1555,4 +1545,5 @@ bool LLPanelPeople::isAccordionCollapsedByUser(const std::string& name)
return isAccordionCollapsedByUser(getChild<LLUICtrl>(name));
}
+
// EOF
diff --git a/indra/newview/llpanelpeople.h b/indra/newview/llpanelpeople.h
index 46c58cd139..c7141f36ee 100644..100755
--- a/indra/newview/llpanelpeople.h
+++ b/indra/newview/llpanelpeople.h
@@ -22,7 +22,7 @@
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
- */
+ */
#ifndef LL_LLPANELPEOPLE_H
#define LL_LLPANELPEOPLE_H
@@ -30,6 +30,7 @@
#include <llpanel.h>
#include "llcallingcard.h" // for avatar tracker
+#include "llfloaterwebcontent.h"
#include "llvoiceclient.h"
class LLAvatarList;
@@ -55,6 +56,8 @@ public:
// when voice is available
/*virtual*/ void onChange(EStatusType status, const std::string &channelURI, bool proximal);
+ bool mTryToConnectToFbc;
+
// internals
class Updater;
@@ -68,11 +71,15 @@ private:
E_SORT_BY_RECENT_SPEAKERS = 4,
} ESortOrder;
+ void removePicker();
+
// methods indirectly called by the updaters
void updateFriendListHelpText();
void updateFriendList();
+ bool updateSuggestedFriendList();
void updateNearbyList();
void updateRecentList();
+ void updateFacebookList(bool visible);
bool isItemsFreeOfFriends(const uuid_vec_t& uuids);
@@ -80,31 +87,22 @@ private:
std::string getActiveTabName() const;
LLUUID getCurrentItemID() const;
void getCurrentItemIDs(uuid_vec_t& selected_uuids) const;
- void buttonSetVisible(std::string btn_name, BOOL visible);
- void buttonSetEnabled(const std::string& btn_name, bool enabled);
- void buttonSetAction(const std::string& btn_name, const commit_signal_t::slot_type& cb);
void showGroupMenu(LLMenuGL* menu);
void setSortOrder(LLAvatarList* list, ESortOrder order, bool save = true);
// UI callbacks
void onFilterEdit(const std::string& search_string);
void onTabSelected(const LLSD& param);
- void onViewProfileButtonClicked();
void onAddFriendButtonClicked();
void onAddFriendWizButtonClicked();
void onDeleteFriendButtonClicked();
- void onGroupInfoButtonClicked();
void onChatButtonClicked();
+ void onGearButtonClicked(LLUICtrl* btn);
void onImButtonClicked();
- void onCallButtonClicked();
- void onGroupCallButtonClicked();
- void onTeleportButtonClicked();
- void onShareButtonClicked();
void onMoreButtonClicked();
- void onActivateButtonClicked();
void onAvatarListDoubleClicked(LLUICtrl* ctrl);
void onAvatarListCommitted(LLAvatarList* list);
- void onGroupPlusButtonClicked();
+ bool onGroupPlusButtonValidate();
void onGroupMinusButtonClicked();
void onGroupPlusMenuItemClicked(const LLSD& userdata);
@@ -113,8 +111,6 @@ private:
void onGroupsViewSortMenuItemClicked(const LLSD& userdata);
void onRecentViewSortMenuItemClicked(const LLSD& userdata);
- //returns false only if group is "none"
- bool isRealGroup();
bool onFriendsViewSortMenuItemCheck(const LLSD& userdata);
bool onRecentViewSortMenuItemCheck(const LLSD& userdata);
bool onNearbyViewSortMenuItemCheck(const LLSD& userdata);
@@ -130,38 +126,31 @@ private:
void onFriendListRefreshComplete(LLUICtrl*ctrl, const LLSD& param);
+ bool onConnectedToFacebook(const LLSD& data);
+
void setAccordionCollapsedByUser(LLUICtrl* acc_tab, bool collapsed);
void setAccordionCollapsedByUser(const std::string& name, bool collapsed);
bool isAccordionCollapsedByUser(LLUICtrl* acc_tab);
bool isAccordionCollapsedByUser(const std::string& name);
- LLFilterEditor* mFilterEditor;
LLTabContainer* mTabContainer;
LLAvatarList* mOnlineFriendList;
LLAvatarList* mAllFriendList;
+ LLAvatarList* mSuggestedFriends;
LLAvatarList* mNearbyList;
LLAvatarList* mRecentList;
LLGroupList* mGroupList;
LLNetMap* mMiniMap;
- LLHandle<LLView> mGroupPlusMenuHandle;
- LLHandle<LLView> mNearbyViewSortMenuHandle;
- LLHandle<LLView> mFriendsViewSortMenuHandle;
- LLHandle<LLView> mGroupsViewSortMenuHandle;
- LLHandle<LLView> mRecentViewSortMenuHandle;
+ std::vector<std::string> mSavedOriginalFilters;
+ std::vector<std::string> mSavedFilters;
Updater* mFriendListUpdater;
Updater* mNearbyListUpdater;
Updater* mRecentListUpdater;
+ Updater* mFacebookListUpdater;
Updater* mButtonsUpdater;
-
- LLMenuButton* mNearbyGearButton;
- LLMenuButton* mFriendsGearButton;
- LLMenuButton* mGroupsGearButton;
- LLMenuButton* mRecentGearButton;
-
- std::string mFilterSubString;
- std::string mFilterSubStringOrig;
+ LLHandle< LLFloater > mPicker;
};
#endif //LL_LLPANELPEOPLE_H
diff --git a/indra/newview/llpanelpeoplemenus.cpp b/indra/newview/llpanelpeoplemenus.cpp
index f12c4de2f7..6979ae06e0 100644..100755
--- a/indra/newview/llpanelpeoplemenus.cpp
+++ b/indra/newview/llpanelpeoplemenus.cpp
@@ -37,20 +37,26 @@
#include "llagentdata.h" // for gAgentID
#include "llavataractions.h"
#include "llcallingcard.h" // for LLAvatarTracker
+#include "lllogchat.h"
#include "llviewermenu.h" // for gMenuHolder
+#include "llconversationmodel.h"
+#include "llviewerobjectlist.h"
namespace LLPanelPeopleMenus
{
-NearbyMenu gNearbyMenu;
+PeopleContextMenu gPeopleContextMenu;
+NearbyPeopleContextMenu gNearbyPeopleContextMenu;
+SuggestedFriendsContextMenu gSuggestedFriendsContextMenu;
-//== NearbyMenu ===============================================================
+//== PeopleContextMenu ===============================================================
-LLContextMenu* NearbyMenu::createMenu()
+LLContextMenu* PeopleContextMenu::createMenu()
{
// set up the callbacks for all of the avatar menu items
LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
+ LLContextMenu* menu;
if ( mUUIDs.size() == 1 )
{
@@ -62,38 +68,88 @@ LLContextMenu* NearbyMenu::createMenu()
registrar.add("Avatar.RemoveFriend", boost::bind(&LLAvatarActions::removeFriendDialog, id));
registrar.add("Avatar.IM", boost::bind(&LLAvatarActions::startIM, id));
registrar.add("Avatar.Call", boost::bind(&LLAvatarActions::startCall, id));
- registrar.add("Avatar.OfferTeleport", boost::bind(&NearbyMenu::offerTeleport, this));
+ registrar.add("Avatar.OfferTeleport", boost::bind(&PeopleContextMenu::offerTeleport, this));
+ registrar.add("Avatar.ZoomIn", boost::bind(&handle_zoom_to_object, id));
registrar.add("Avatar.ShowOnMap", boost::bind(&LLAvatarActions::showOnMap, id));
registrar.add("Avatar.Share", boost::bind(&LLAvatarActions::share, id));
registrar.add("Avatar.Pay", boost::bind(&LLAvatarActions::pay, id));
registrar.add("Avatar.BlockUnblock", boost::bind(&LLAvatarActions::toggleBlock, id));
+ registrar.add("Avatar.InviteToGroup", boost::bind(&LLAvatarActions::inviteToGroup, id));
+ registrar.add("Avatar.TeleportRequest", boost::bind(&PeopleContextMenu::requestTeleport, this));
+ registrar.add("Avatar.Calllog", boost::bind(&LLAvatarActions::viewChatHistory, id));
- enable_registrar.add("Avatar.EnableItem", boost::bind(&NearbyMenu::enableContextMenuItem, this, _2));
- enable_registrar.add("Avatar.CheckItem", boost::bind(&NearbyMenu::checkContextMenuItem, this, _2));
+ enable_registrar.add("Avatar.EnableItem", boost::bind(&PeopleContextMenu::enableContextMenuItem, this, _2));
+ enable_registrar.add("Avatar.CheckItem", boost::bind(&PeopleContextMenu::checkContextMenuItem, this, _2));
// create the context menu from the XUI
- return createFromFile("menu_people_nearby.xml");
+ menu = createFromFile("menu_people_nearby.xml");
+ buildContextMenu(*menu, 0x0);
}
else
{
// Set up for multi-selected People
// registrar.add("Avatar.AddFriend", boost::bind(&LLAvatarActions::requestFriendshipDialog, mUUIDs)); // *TODO: unimplemented
- registrar.add("Avatar.IM", boost::bind(&LLAvatarActions::startConference, mUUIDs));
- registrar.add("Avatar.Call", boost::bind(&LLAvatarActions::startAdhocCall, mUUIDs));
- registrar.add("Avatar.OfferTeleport", boost::bind(&NearbyMenu::offerTeleport, this));
- registrar.add("Avatar.RemoveFriend",boost::bind(&LLAvatarActions::removeFriendsDialog, mUUIDs));
+ registrar.add("Avatar.IM", boost::bind(&LLAvatarActions::startConference, mUUIDs, LLUUID::null));
+ registrar.add("Avatar.Call", boost::bind(&LLAvatarActions::startAdhocCall, mUUIDs, LLUUID::null));
+ registrar.add("Avatar.OfferTeleport", boost::bind(&PeopleContextMenu::offerTeleport, this));
+ registrar.add("Avatar.RemoveFriend", boost::bind(&LLAvatarActions::removeFriendsDialog, mUUIDs));
// registrar.add("Avatar.Share", boost::bind(&LLAvatarActions::startIM, mUUIDs)); // *TODO: unimplemented
- // registrar.add("Avatar.Pay", boost::bind(&LLAvatarActions::pay, mUUIDs)); // *TODO: unimplemented
- enable_registrar.add("Avatar.EnableItem", boost::bind(&NearbyMenu::enableContextMenuItem, this, _2));
+ // registrar.add("Avatar.Pay", boost::bind(&LLAvatarActions::pay, mUUIDs)); // *TODO: unimplemented
+
+ enable_registrar.add("Avatar.EnableItem", boost::bind(&PeopleContextMenu::enableContextMenuItem, this, _2));
// create the context menu from the XUI
- return createFromFile("menu_people_nearby_multiselect.xml");
+ menu = createFromFile("menu_people_nearby_multiselect.xml");
+ buildContextMenu(*menu, ITEM_IN_MULTI_SELECTION);
}
+
+ return menu;
+}
+
+void PeopleContextMenu::buildContextMenu(class LLMenuGL& menu, U32 flags)
+{
+ menuentry_vec_t items;
+ menuentry_vec_t disabled_items;
+
+ if (flags & ITEM_IN_MULTI_SELECTION)
+ {
+ items.push_back(std::string("add_friends"));
+ items.push_back(std::string("remove_friends"));
+ items.push_back(std::string("im"));
+ items.push_back(std::string("call"));
+ items.push_back(std::string("share"));
+ items.push_back(std::string("pay"));
+ items.push_back(std::string("offer_teleport"));
+ }
+ else
+ {
+ items.push_back(std::string("view_profile"));
+ items.push_back(std::string("im"));
+ items.push_back(std::string("offer_teleport"));
+ items.push_back(std::string("request_teleport"));
+ items.push_back(std::string("voice_call"));
+ items.push_back(std::string("chat_history"));
+ items.push_back(std::string("separator_chat_history"));
+ items.push_back(std::string("add_friend"));
+ items.push_back(std::string("remove_friend"));
+ items.push_back(std::string("invite_to_group"));
+ items.push_back(std::string("separator_invite_to_group"));
+ items.push_back(std::string("map"));
+ items.push_back(std::string("share"));
+ items.push_back(std::string("pay"));
+ items.push_back(std::string("block_unblock"));
+ }
+
+ hide_context_entries(menu, items, disabled_items);
}
-bool NearbyMenu::enableContextMenuItem(const LLSD& userdata)
+bool PeopleContextMenu::enableContextMenuItem(const LLSD& userdata)
{
+ if(gAgent.getID() == mUUIDs.front())
+ {
+ return false;
+ }
std::string item = userdata.asString();
// Note: can_block and can_delete is used only for one person selected menu
@@ -160,6 +216,12 @@ bool NearbyMenu::enableContextMenuItem(const LLSD& userdata)
{
return LLAvatarActions::canCall();
}
+ else if (item == std::string("can_zoom_in"))
+ {
+ const LLUUID& id = mUUIDs.front();
+
+ return gObjectList.findObject(id);
+ }
else if (item == std::string("can_show_on_map"))
{
const LLUUID& id = mUUIDs.front();
@@ -171,10 +233,19 @@ bool NearbyMenu::enableContextMenuItem(const LLSD& userdata)
{
return LLAvatarActions::canOfferTeleport(mUUIDs);
}
+ else if (item == std::string("can_callog"))
+ {
+ return LLLogChat::isTranscriptExist(mUUIDs.front());
+ }
+ else if (item == std::string("can_im") || item == std::string("can_invite") ||
+ item == std::string("can_share") || item == std::string("can_pay"))
+ {
+ return true;
+ }
return false;
}
-bool NearbyMenu::checkContextMenuItem(const LLSD& userdata)
+bool PeopleContextMenu::checkContextMenuItem(const LLSD& userdata)
{
std::string item = userdata.asString();
const LLUUID& id = mUUIDs.front();
@@ -187,11 +258,90 @@ bool NearbyMenu::checkContextMenuItem(const LLSD& userdata)
return false;
}
-void NearbyMenu::offerTeleport()
+void PeopleContextMenu::requestTeleport()
+{
+ // boost::bind cannot recognize overloaded method LLAvatarActions::teleportRequest(),
+ // so we have to use a wrapper.
+ LLAvatarActions::teleportRequest(mUUIDs.front());
+}
+
+void PeopleContextMenu::offerTeleport()
{
// boost::bind cannot recognize overloaded method LLAvatarActions::offerTeleport(),
// so we have to use a wrapper.
LLAvatarActions::offerTeleport(mUUIDs);
}
+//== NearbyPeopleContextMenu ===============================================================
+
+void NearbyPeopleContextMenu::buildContextMenu(class LLMenuGL& menu, U32 flags)
+{
+ menuentry_vec_t items;
+ menuentry_vec_t disabled_items;
+
+ if (flags & ITEM_IN_MULTI_SELECTION)
+ {
+ items.push_back(std::string("add_friends"));
+ items.push_back(std::string("remove_friends"));
+ items.push_back(std::string("im"));
+ items.push_back(std::string("call"));
+ items.push_back(std::string("share"));
+ items.push_back(std::string("pay"));
+ items.push_back(std::string("offer_teleport"));
+ }
+ else
+ {
+ items.push_back(std::string("view_profile"));
+ items.push_back(std::string("im"));
+ items.push_back(std::string("offer_teleport"));
+ items.push_back(std::string("request_teleport"));
+ items.push_back(std::string("voice_call"));
+ items.push_back(std::string("chat_history"));
+ items.push_back(std::string("separator_chat_history"));
+ items.push_back(std::string("add_friend"));
+ items.push_back(std::string("remove_friend"));
+ items.push_back(std::string("invite_to_group"));
+ items.push_back(std::string("separator_invite_to_group"));
+ items.push_back(std::string("zoom_in"));
+ items.push_back(std::string("map"));
+ items.push_back(std::string("share"));
+ items.push_back(std::string("pay"));
+ items.push_back(std::string("block_unblock"));
+ }
+
+ hide_context_entries(menu, items, disabled_items);
+}
+
+//== SuggestedFriendsContextMenu ===============================================================
+
+LLContextMenu* SuggestedFriendsContextMenu::createMenu()
+{
+ // set up the callbacks for all of the avatar menu items
+ LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
+ LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
+ LLContextMenu* menu;
+
+ // Set up for one person selected menu
+ const LLUUID& id = mUUIDs.front();
+ registrar.add("Avatar.Profile", boost::bind(&LLAvatarActions::showProfile, id));
+ registrar.add("Avatar.AddFriend", boost::bind(&LLAvatarActions::requestFriendshipDialog, id));
+
+ // create the context menu from the XUI
+ menu = createFromFile("menu_people_nearby.xml");
+ buildContextMenu(*menu, 0x0);
+
+ return menu;
+}
+
+void SuggestedFriendsContextMenu::buildContextMenu(class LLMenuGL& menu, U32 flags)
+{
+ menuentry_vec_t items;
+ menuentry_vec_t disabled_items;
+
+ items.push_back(std::string("view_profile"));
+ items.push_back(std::string("add_friend"));
+
+ hide_context_entries(menu, items, disabled_items);
+}
+
} // namespace LLPanelPeopleMenus
diff --git a/indra/newview/llpanelpeoplemenus.h b/indra/newview/llpanelpeoplemenus.h
index d51eaec716..945382ebc5 100644..100755
--- a/indra/newview/llpanelpeoplemenus.h
+++ b/indra/newview/llpanelpeoplemenus.h
@@ -33,19 +33,47 @@ namespace LLPanelPeopleMenus
{
/**
- * Menu used in the nearby people list.
+ * Menu used in the people lists.
*/
-class NearbyMenu : public LLListContextMenu
+class PeopleContextMenu : public LLListContextMenu
{
public:
/*virtual*/ LLContextMenu* createMenu();
+
+protected:
+ virtual void buildContextMenu(class LLMenuGL& menu, U32 flags);
+
private:
bool enableContextMenuItem(const LLSD& userdata);
bool checkContextMenuItem(const LLSD& userdata);
void offerTeleport();
+ void requestTeleport();
+};
+
+/**
+ * Menu used in the nearby people list.
+ */
+class NearbyPeopleContextMenu : public PeopleContextMenu
+{
+protected:
+ /*virtual*/ void buildContextMenu(class LLMenuGL& menu, U32 flags);
+};
+
+/**
+ * Menu used in the suggested friends list.
+ */
+class SuggestedFriendsContextMenu : public PeopleContextMenu
+{
+public:
+ /*virtual*/ LLContextMenu * createMenu();
+
+protected:
+ /*virtual*/ void buildContextMenu(class LLMenuGL& menu, U32 flags);
};
-extern NearbyMenu gNearbyMenu;
+extern PeopleContextMenu gPeopleContextMenu;
+extern NearbyPeopleContextMenu gNearbyPeopleContextMenu;
+extern SuggestedFriendsContextMenu gSuggestedFriendsContextMenu;
} // namespace LLPanelPeopleMenus
diff --git a/indra/newview/llpanelpermissions.cpp b/indra/newview/llpanelpermissions.cpp
index 59130236f2..131e8e9359 100644..100755
--- a/indra/newview/llpanelpermissions.cpp
+++ b/indra/newview/llpanelpermissions.cpp
@@ -62,6 +62,7 @@
#include "llspinctrl.h"
#include "roles_constants.h"
#include "llgroupactions.h"
+#include "lltrans.h"
U8 string_value_to_click_action(std::string p_value);
@@ -180,6 +181,9 @@ void LLPanelPermissions::disableAll()
getChildView("perm_modify")->setEnabled(FALSE);
getChild<LLUICtrl>("perm_modify")->setValue(LLStringUtil::null);
+ getChildView("pathfinding_attributes_value")->setEnabled(FALSE);
+ getChild<LLUICtrl>("pathfinding_attributes_value")->setValue(LLStringUtil::null);
+
getChildView("Creator:")->setEnabled(FALSE);
getChild<LLUICtrl>("Creator Name")->setValue(LLStringUtil::null);
getChildView("Creator Name")->setEnabled(FALSE);
@@ -299,6 +303,9 @@ void LLPanelPermissions::refresh()
BOOL is_perm_modify = (LLSelectMgr::getInstance()->getSelection()->getFirstRootNode()
&& LLSelectMgr::getInstance()->selectGetRootsModify())
|| LLSelectMgr::getInstance()->selectGetModify();
+ BOOL is_nonpermanent_enforced = (LLSelectMgr::getInstance()->getSelection()->getFirstRootNode()
+ && LLSelectMgr::getInstance()->selectGetRootsNonPermanentEnforced())
+ || LLSelectMgr::getInstance()->selectGetNonPermanentEnforced();
const LLFocusableElement* keyboard_focus_view = gFocusMgr.getKeyboardFocus();
S32 string_index = 0;
@@ -307,12 +314,18 @@ void LLPanelPermissions::refresh()
getString("text modify info 1"),
getString("text modify info 2"),
getString("text modify info 3"),
- getString("text modify info 4")
+ getString("text modify info 4"),
+ getString("text modify info 5"),
+ getString("text modify info 6")
};
if (!is_perm_modify)
{
string_index += 2;
}
+ else if (!is_nonpermanent_enforced)
+ {
+ string_index += 4;
+ }
if (!is_one_object)
{
++string_index;
@@ -320,14 +333,40 @@ void LLPanelPermissions::refresh()
getChildView("perm_modify")->setEnabled(TRUE);
getChild<LLUICtrl>("perm_modify")->setValue(MODIFY_INFO_STRINGS[string_index]);
+ std::string pfAttrName;
+
+ if ((LLSelectMgr::getInstance()->getSelection()->getFirstRootNode()
+ && LLSelectMgr::getInstance()->selectGetRootsNonPathfinding())
+ || LLSelectMgr::getInstance()->selectGetNonPathfinding())
+ {
+ pfAttrName = "Pathfinding_Object_Attr_None";
+ }
+ else if ((LLSelectMgr::getInstance()->getSelection()->getFirstRootNode()
+ && LLSelectMgr::getInstance()->selectGetRootsPermanent())
+ || LLSelectMgr::getInstance()->selectGetPermanent())
+ {
+ pfAttrName = "Pathfinding_Object_Attr_Permanent";
+ }
+ else if ((LLSelectMgr::getInstance()->getSelection()->getFirstRootNode()
+ && LLSelectMgr::getInstance()->selectGetRootsCharacter())
+ || LLSelectMgr::getInstance()->selectGetCharacter())
+ {
+ pfAttrName = "Pathfinding_Object_Attr_Character";
+ }
+ else
+ {
+ pfAttrName = "Pathfinding_Object_Attr_MultiSelect";
+ }
+
+ getChildView("pathfinding_attributes_value")->setEnabled(TRUE);
+ getChild<LLUICtrl>("pathfinding_attributes_value")->setValue(LLTrans::getString(pfAttrName));
+
getChildView("Permissions:")->setEnabled(TRUE);
// Update creator text field
getChildView("Creator:")->setEnabled(TRUE);
- BOOL creators_identical;
std::string creator_name;
- creators_identical = LLSelectMgr::getInstance()->selectGetCreator(mCreatorID,
- creator_name);
+ LLSelectMgr::getInstance()->selectGetCreator(mCreatorID, creator_name);
getChild<LLUICtrl>("Creator Name")->setValue(creator_name);
getChildView("Creator Name")->setEnabled(TRUE);
@@ -384,7 +423,7 @@ void LLPanelPermissions::refresh()
}
}
- getChildView("button set group")->setEnabled(owners_identical && (mOwnerID == gAgent.getID()));
+ getChildView("button set group")->setEnabled(root_selected && owners_identical && (mOwnerID == gAgent.getID()) && is_nonpermanent_enforced);
getChildView("Name:")->setEnabled(TRUE);
LLLineEditor* LineEditorObjectName = getChild<LLLineEditor>("Object Name");
@@ -414,7 +453,7 @@ void LLPanelPermissions::refresh()
// figure out the contents of the name, description, & category
BOOL edit_name_desc = FALSE;
- if (is_one_object && objectp->permModify())
+ if (is_one_object && objectp->permModify() && !objectp->isPermanentEnforced())
{
edit_name_desc = TRUE;
}
@@ -594,12 +633,12 @@ void LLPanelPermissions::refresh()
BOOL has_change_perm_ability = FALSE;
BOOL has_change_sale_ability = FALSE;
- if (valid_base_perms &&
+ if (valid_base_perms && is_nonpermanent_enforced &&
(self_owned || (group_owned && gAgent.hasPowerInGroup(group_id, GP_OBJECT_MANIPULATE))))
{
has_change_perm_ability = TRUE;
}
- if (valid_base_perms &&
+ if (valid_base_perms && is_nonpermanent_enforced &&
(self_owned || (group_owned && gAgent.hasPowerInGroup(group_id, GP_OBJECT_SET_SALE))))
{
has_change_sale_ability = TRUE;
@@ -812,8 +851,8 @@ void LLPanelPermissions::refresh()
combo_click_action->setValue(LLSD(combo_value));
}
}
- getChildView("label click action")->setEnabled(is_perm_modify && all_volume);
- getChildView("clickaction")->setEnabled(is_perm_modify && all_volume);
+ getChildView("label click action")->setEnabled(is_perm_modify && is_nonpermanent_enforced && all_volume);
+ getChildView("clickaction")->setEnabled(is_perm_modify && is_nonpermanent_enforced && all_volume);
}
diff --git a/indra/newview/llpanelpermissions.h b/indra/newview/llpanelpermissions.h
index 87805bbf90..87805bbf90 100644..100755
--- a/indra/newview/llpanelpermissions.h
+++ b/indra/newview/llpanelpermissions.h
diff --git a/indra/newview/llpanelpick.cpp b/indra/newview/llpanelpick.cpp
index 44cca21a76..44cca21a76 100644..100755
--- a/indra/newview/llpanelpick.cpp
+++ b/indra/newview/llpanelpick.cpp
diff --git a/indra/newview/llpanelpick.h b/indra/newview/llpanelpick.h
index 3c1f14759c..3c1f14759c 100644..100755
--- a/indra/newview/llpanelpick.h
+++ b/indra/newview/llpanelpick.h
diff --git a/indra/newview/llpanelplaceinfo.cpp b/indra/newview/llpanelplaceinfo.cpp
index 4ae0c0eb12..4ae0c0eb12 100644..100755
--- a/indra/newview/llpanelplaceinfo.cpp
+++ b/indra/newview/llpanelplaceinfo.cpp
diff --git a/indra/newview/llpanelplaceinfo.h b/indra/newview/llpanelplaceinfo.h
index 64f0b6b550..64f0b6b550 100644..100755
--- a/indra/newview/llpanelplaceinfo.h
+++ b/indra/newview/llpanelplaceinfo.h
diff --git a/indra/newview/llpanelplaceprofile.cpp b/indra/newview/llpanelplaceprofile.cpp
index ce8057eead..5d9971c16c 100644..100755
--- a/indra/newview/llpanelplaceprofile.cpp
+++ b/indra/newview/llpanelplaceprofile.cpp
@@ -499,9 +499,7 @@ void LLPanelPlaceProfile::displaySelectedParcelInfo(LLParcel* parcel,
std::string parcel_owner =
LLSLURL("agent", parcel->getOwnerID(), "inspect").getSLURLString();
mParcelOwner->setText(parcel_owner);
- LLAvatarNameCache::get(region->getOwner(),
- boost::bind(&LLPanelPlaceInfo::onAvatarNameCache,
- _1, _2, mRegionOwnerText));
+ LLAvatarNameCache::get(region->getOwner(), boost::bind(&LLPanelPlaceInfo::onAvatarNameCache, _1, _2, mRegionOwnerText));
}
if(LLParcel::OS_LEASE_PENDING == parcel->getOwnershipStatus())
@@ -523,9 +521,7 @@ void LLPanelPlaceProfile::displaySelectedParcelInfo(LLParcel* parcel,
const LLUUID& auth_buyer_id = parcel->getAuthorizedBuyerID();
if(auth_buyer_id.notNull())
{
- LLAvatarNameCache::get(auth_buyer_id,
- boost::bind(&LLPanelPlaceInfo::onAvatarNameCache,
- _1, _2, mSaleToText));
+ LLAvatarNameCache::get(auth_buyer_id, boost::bind(&LLPanelPlaceInfo::onAvatarNameCache, _1, _2, mSaleToText));
// Show sales info to a specific person or a group he belongs to.
if (auth_buyer_id != gAgent.getID() && !gAgent.isInGroup(auth_buyer_id))
@@ -572,7 +568,7 @@ void LLPanelPlaceProfile::displaySelectedParcelInfo(LLParcel* parcel,
mTerraformLimitsText->setText(parcel->getAllowTerraform() ? on : off);
- if (region->getRegionFlags() & REGION_FLAGS_ALLOW_PARCEL_CHANGES)
+ if (region->getRegionFlag(REGION_FLAGS_ALLOW_PARCEL_CHANGES))
{
mSubdivideText->setText(getString("can_change"));
}
@@ -580,7 +576,7 @@ void LLPanelPlaceProfile::displaySelectedParcelInfo(LLParcel* parcel,
{
mSubdivideText->setText(getString("can_not_change"));
}
- if (region->getRegionFlags() & REGION_FLAGS_BLOCK_LAND_RESELL)
+ if (region->getRegionFlag(REGION_FLAGS_BLOCK_LAND_RESELL))
{
mResaleText->setText(getString("can_not_resell"));
}
diff --git a/indra/newview/llpanelplaceprofile.h b/indra/newview/llpanelplaceprofile.h
index a33fc12ce4..f4c6145881 100644..100755
--- a/indra/newview/llpanelplaceprofile.h
+++ b/indra/newview/llpanelplaceprofile.h
@@ -38,7 +38,7 @@ class LLPanelPlaceProfile : public LLPanelPlaceInfo
public:
LLPanelPlaceProfile();
/*virtual*/ ~LLPanelPlaceProfile();
-
+
/*virtual*/ BOOL postBuild();
/*virtual*/ void resetLocation();
diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp
index 6d321d4716..6c2a01fc82 100644..100755
--- a/indra/newview/llpanelplaces.cpp
+++ b/indra/newview/llpanelplaces.cpp
@@ -366,6 +366,7 @@ void LLPanelPlaces::onOpen(const LLSD& key)
if (key.size() != 0)
{
+ isLandmarkEditModeOn = false;
std::string key_type = key["type"].asString();
if (key_type == LANDMARK_TAB_INFO_TYPE)
{
@@ -392,7 +393,6 @@ void LLPanelPlaces::onOpen(const LLSD& key)
mPlaceInfoType = key_type;
mPosGlobal.setZero();
mItem = NULL;
- isLandmarkEditModeOn = false;
togglePlaceInfoPanel(TRUE);
if (mPlaceInfoType == AGENT_INFO_TYPE)
diff --git a/indra/newview/llpanelplaces.h b/indra/newview/llpanelplaces.h
index 85bdc2c4e1..85bdc2c4e1 100644..100755
--- a/indra/newview/llpanelplaces.h
+++ b/indra/newview/llpanelplaces.h
diff --git a/indra/newview/llpanelplacestab.cpp b/indra/newview/llpanelplacestab.cpp
index 9644b7518e..9644b7518e 100644..100755
--- a/indra/newview/llpanelplacestab.cpp
+++ b/indra/newview/llpanelplacestab.cpp
diff --git a/indra/newview/llpanelplacestab.h b/indra/newview/llpanelplacestab.h
index 367ce46e2e..367ce46e2e 100644..100755
--- a/indra/newview/llpanelplacestab.h
+++ b/indra/newview/llpanelplacestab.h
diff --git a/indra/newview/llpanelprimmediacontrols.cpp b/indra/newview/llpanelprimmediacontrols.cpp
index 76d38f067d..9504f22a1d 100644..100755
--- a/indra/newview/llpanelprimmediacontrols.cpp
+++ b/indra/newview/llpanelprimmediacontrols.cpp
@@ -94,7 +94,8 @@ LLPanelPrimMediaControls::LLPanelPrimMediaControls() :
mZoomObjectFace(0),
mVolumeSliderVisible(0),
mWindowShade(NULL),
- mHideImmediately(false)
+ mHideImmediately(false),
+ mSecureURL(false)
{
mCommitCallbackRegistrar.add("MediaCtrl.Close", boost::bind(&LLPanelPrimMediaControls::onClickClose, this));
mCommitCallbackRegistrar.add("MediaCtrl.Back", boost::bind(&LLPanelPrimMediaControls::onClickBack, this));
@@ -345,7 +346,7 @@ void LLPanelPrimMediaControls::updateShape()
// Disable zoom if HUD
mZoomCtrl->setEnabled(!is_hud);
mUnzoomCtrl->setEnabled(!is_hud);
- mSecureLockIcon->setVisible(false);
+ mSecureURL = false;
mCurrentURL = media_impl->getCurrentMediaURL();
mBackCtrl->setEnabled((media_impl != NULL) && media_impl->canNavigateBack() && can_navigate);
@@ -382,7 +383,7 @@ void LLPanelPrimMediaControls::updateShape()
mVolumeSliderCtrl->setVisible(has_focus && shouldVolumeSliderBeVisible());
mWhitelistIcon->setVisible(false);
- mSecureLockIcon->setVisible(false);
+ mSecureURL = false;
if (mMediaPanelScroll)
{
mMediaPanelScroll->setVisible(false);
@@ -416,7 +417,7 @@ void LLPanelPrimMediaControls::updateShape()
mMediaPlaySliderCtrl->setEnabled(true);
}
- // video vloume
+ // video volume
if(volume <= 0.0)
{
mMuteBtn->setToggleState(true);
@@ -492,10 +493,8 @@ void LLPanelPrimMediaControls::updateShape()
std::string prefix = std::string("https://");
std::string test_prefix = mCurrentURL.substr(0, prefix.length());
LLStringUtil::toLower(test_prefix);
- if(test_prefix == prefix)
- {
- mSecureLockIcon->setVisible(has_focus);
- }
+ mSecureURL = has_focus && (test_prefix == prefix);
+ mCurrentURL = (mSecureURL ? " " + mCurrentURL : mCurrentURL);
if(mCurrentURL!=mPreviousURL)
{
@@ -746,6 +745,9 @@ void LLPanelPrimMediaControls::draw()
clearFaceOnFade();
}
}
+
+ // Show/hide the lock icon for secure browsing
+ mSecureLockIcon->setVisible(mSecureURL && !mMediaAddress->hasFocus());
// Build rect for icon area in coord system of this panel
// Assumes layout_stack is a direct child of this panel
diff --git a/indra/newview/llpanelprimmediacontrols.h b/indra/newview/llpanelprimmediacontrols.h
index eeb433e306..6d2eb3430e 100644..100755
--- a/indra/newview/llpanelprimmediacontrols.h
+++ b/indra/newview/llpanelprimmediacontrols.h
@@ -191,6 +191,7 @@ private:
bool mUpdateSlider;
bool mClearFaceOnFade;
bool mHideImmediately;
+ bool mSecureURL;
LLMatrix4 mLastCameraMat;
EZoomLevel mCurrentZoom;
diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp
index e2e7006773..5acc98904b 100755
--- a/indra/newview/llpanelprofile.cpp
+++ b/indra/newview/llpanelprofile.cpp
@@ -36,6 +36,8 @@
#include "lltabcontainer.h"
#include "llviewercontrol.h"
#include "llviewernetwork.h"
+#include "llmutelist.h"
+#include "llpanelblockedlist.h"
static const std::string PANEL_PICKS = "panel_picks";
@@ -137,6 +139,12 @@ public:
return true;
}
+ if (verb == "removefriend")
+ {
+ LLAvatarActions::removeFriendDialog(avatar_id);
+ return true;
+ }
+
if (verb == "mute")
{
if (! LLAvatarActions::isBlocked(avatar_id))
@@ -155,6 +163,18 @@ public:
return true;
}
+ if (verb == "block")
+ {
+ if (params.size() > 2)
+ {
+ const std::string object_name = params[2].asString();
+ LLMute mute(avatar_id, object_name, LLMute::OBJECT);
+ LLMuteList::getInstance()->add(mute);
+ LLPanelBlockedList::showPanelAndSelect(mute.mID);
+ }
+ return true;
+ }
+
return false;
}
};
diff --git a/indra/newview/llpanelsnapshot.cpp b/indra/newview/llpanelsnapshot.cpp
index 2f29e758c6..2f29e758c6 100644..100755
--- a/indra/newview/llpanelsnapshot.cpp
+++ b/indra/newview/llpanelsnapshot.cpp
diff --git a/indra/newview/llpanelsnapshot.h b/indra/newview/llpanelsnapshot.h
index f3274cf594..f3274cf594 100644..100755
--- a/indra/newview/llpanelsnapshot.h
+++ b/indra/newview/llpanelsnapshot.h
diff --git a/indra/newview/llpanelsnapshotinventory.cpp b/indra/newview/llpanelsnapshotinventory.cpp
index 381c11348d..381c11348d 100644..100755
--- a/indra/newview/llpanelsnapshotinventory.cpp
+++ b/indra/newview/llpanelsnapshotinventory.cpp
diff --git a/indra/newview/llpanelsnapshotlocal.cpp b/indra/newview/llpanelsnapshotlocal.cpp
index d153ff598d..d153ff598d 100644..100755
--- a/indra/newview/llpanelsnapshotlocal.cpp
+++ b/indra/newview/llpanelsnapshotlocal.cpp
diff --git a/indra/newview/llpanelsnapshotoptions.cpp b/indra/newview/llpanelsnapshotoptions.cpp
index 554fabe5b3..554fabe5b3 100644..100755
--- a/indra/newview/llpanelsnapshotoptions.cpp
+++ b/indra/newview/llpanelsnapshotoptions.cpp
diff --git a/indra/newview/llpanelsnapshotpostcard.cpp b/indra/newview/llpanelsnapshotpostcard.cpp
index f2bb8f530b..f2bb8f530b 100644..100755
--- a/indra/newview/llpanelsnapshotpostcard.cpp
+++ b/indra/newview/llpanelsnapshotpostcard.cpp
diff --git a/indra/newview/llpanelsnapshotprofile.cpp b/indra/newview/llpanelsnapshotprofile.cpp
index a706318369..a706318369 100644..100755
--- a/indra/newview/llpanelsnapshotprofile.cpp
+++ b/indra/newview/llpanelsnapshotprofile.cpp
diff --git a/indra/newview/llpanelteleporthistory.cpp b/indra/newview/llpanelteleporthistory.cpp
index c63d89fc98..0756faf5c0 100644..100755
--- a/indra/newview/llpanelteleporthistory.cpp
+++ b/indra/newview/llpanelteleporthistory.cpp
@@ -972,6 +972,11 @@ void LLTeleportHistoryPanel::onCollapseAllFolders()
mItemContainers.get(n)->setDisplayChildren(false);
}
mHistoryAccordion->arrange();
+
+ if (mLastSelectedFlatlList)
+ {
+ mLastSelectedFlatlList->resetSelection();
+ }
}
void LLTeleportHistoryPanel::onClearTeleportHistory()
diff --git a/indra/newview/llpanelteleporthistory.h b/indra/newview/llpanelteleporthistory.h
index 47b607a2f4..47b607a2f4 100644..100755
--- a/indra/newview/llpanelteleporthistory.h
+++ b/indra/newview/llpanelteleporthistory.h
diff --git a/indra/newview/llpaneltiptoast.cpp b/indra/newview/llpaneltiptoast.cpp
index 35009a552d..35009a552d 100644..100755
--- a/indra/newview/llpaneltiptoast.cpp
+++ b/indra/newview/llpaneltiptoast.cpp
diff --git a/indra/newview/llpaneltiptoast.h b/indra/newview/llpaneltiptoast.h
index cb09f1dca6..cb09f1dca6 100644..100755
--- a/indra/newview/llpaneltiptoast.h
+++ b/indra/newview/llpaneltiptoast.h
diff --git a/indra/newview/llpaneltopinfobar.cpp b/indra/newview/llpaneltopinfobar.cpp
index 280cc11179..9dd665198f 100644..100755
--- a/indra/newview/llpaneltopinfobar.cpp
+++ b/indra/newview/llpaneltopinfobar.cpp
@@ -64,9 +64,6 @@ private:
LLPanelTopInfoBar::LLPanelTopInfoBar(): mParcelChangedObserver(0)
{
- LLUICtrl::CommitCallbackRegistry::currentRegistrar()
- .add("TopInfoBar.Action", boost::bind(&LLPanelTopInfoBar::onContextMenuItemClicked, this, _2));
-
buildFromFile( "panel_topinfo_bar.xml");
}
@@ -132,6 +129,11 @@ void LLPanelTopInfoBar::handleLoginComplete()
BOOL LLPanelTopInfoBar::handleRightMouseDown(S32 x, S32 y, MASK mask)
{
+ if(!LLUICtrl::CommitCallbackRegistry::getValue("TopInfoBar.Action"))
+ {
+ LLUICtrl::CommitCallbackRegistry::currentRegistrar()
+ .add("TopInfoBar.Action", boost::bind(&LLPanelTopInfoBar::onContextMenuItemClicked, this, _2));
+ }
show_topinfobar_context_menu(this, x, y);
return TRUE;
}
@@ -230,7 +232,7 @@ void LLPanelTopInfoBar::buildLocationString(std::string& loc_str, bool show_coor
void LLPanelTopInfoBar::setParcelInfoText(const std::string& new_text)
{
LLRect old_rect = getRect();
- const LLFontGL* font = mParcelInfoText->getDefaultFont();
+ const LLFontGL* font = mParcelInfoText->getFont();
S32 new_text_width = font->getWidth(new_text);
mParcelInfoText->setText(new_text);
@@ -415,11 +417,11 @@ void LLPanelTopInfoBar::onParcelIconClick(EParcelIcon icon)
case SCRIPTS_ICON:
{
LLViewerRegion* region = gAgent.getRegion();
- if(region && region->getRegionFlags() & REGION_FLAGS_ESTATE_SKIP_SCRIPTS)
+ if(region && region->getRegionFlag(REGION_FLAGS_ESTATE_SKIP_SCRIPTS))
{
LLNotificationsUtil::add("ScriptsStopped");
}
- else if(region && region->getRegionFlags() & REGION_FLAGS_SKIP_SCRIPTS)
+ else if(region && region->getRegionFlag(REGION_FLAGS_SKIP_SCRIPTS))
{
LLNotificationsUtil::add("ScriptsNotRunning");
}
diff --git a/indra/newview/llpaneltopinfobar.h b/indra/newview/llpaneltopinfobar.h
index d58d95be90..d58d95be90 100644..100755
--- a/indra/newview/llpaneltopinfobar.h
+++ b/indra/newview/llpaneltopinfobar.h
diff --git a/indra/newview/llpanelvoicedevicesettings.cpp b/indra/newview/llpanelvoicedevicesettings.cpp
index 6be2ea6481..6be2ea6481 100644..100755
--- a/indra/newview/llpanelvoicedevicesettings.cpp
+++ b/indra/newview/llpanelvoicedevicesettings.cpp
diff --git a/indra/newview/llpanelvoicedevicesettings.h b/indra/newview/llpanelvoicedevicesettings.h
index ba3bcad0dc..ba3bcad0dc 100644..100755
--- a/indra/newview/llpanelvoicedevicesettings.h
+++ b/indra/newview/llpanelvoicedevicesettings.h
diff --git a/indra/newview/llpanelvoiceeffect.cpp b/indra/newview/llpanelvoiceeffect.cpp
index 5fec6d967d..5fec6d967d 100644..100755
--- a/indra/newview/llpanelvoiceeffect.cpp
+++ b/indra/newview/llpanelvoiceeffect.cpp
diff --git a/indra/newview/llpanelvoiceeffect.h b/indra/newview/llpanelvoiceeffect.h
index bba525e1df..bba525e1df 100644..100755
--- a/indra/newview/llpanelvoiceeffect.h
+++ b/indra/newview/llpanelvoiceeffect.h
diff --git a/indra/newview/llpanelvolume.cpp b/indra/newview/llpanelvolume.cpp
index 12eea7844d..a1d60b5b16 100644..100755
--- a/indra/newview/llpanelvolume.cpp
+++ b/indra/newview/llpanelvolume.cpp
@@ -68,6 +68,7 @@
#include "llworld.h"
#include "pipeline.h"
#include "llviewershadermgr.h"
+#include "llnotificationsutil.h"
#include "lldrawpool.h"
#include "lluictrlfactory.h"
@@ -77,13 +78,15 @@
#include "llviewercontrol.h"
#include "llmeshrepository.h"
+#include <boost/bind.hpp>
+
// "Features" Tab
BOOL LLPanelVolume::postBuild()
{
// Flexible Objects Parameters
{
- childSetCommitCallback("Flexible1D Checkbox Ctrl",onCommitIsFlexible,this);
+ childSetCommitCallback("Flexible1D Checkbox Ctrl", boost::bind(&LLPanelVolume::onCommitIsFlexible, this, _1, _2), NULL);
childSetCommitCallback("FlexNumSections",onCommitFlexible,this);
getChild<LLUICtrl>("FlexNumSections")->setValidateBeforeCommit(precommitValidate);
childSetCommitCallback("FlexGravity",onCommitFlexible,this);
@@ -249,13 +252,12 @@ void LLPanelVolume::getState( )
return;
}
- BOOL owners_identical;
LLUUID owner_id;
std::string owner_name;
- owners_identical = LLSelectMgr::getInstance()->selectGetOwner(owner_id, owner_name);
+ LLSelectMgr::getInstance()->selectGetOwner(owner_id, owner_name);
// BUG? Check for all objects being editable?
- BOOL editable = root_objectp->permModify();
+ BOOL editable = root_objectp->permModify() && !root_objectp->isPermanentEnforced();
BOOL single_volume = LLSelectMgr::getInstance()->selectionAllPCode( LL_PCODE_VOLUME )
&& LLSelectMgr::getInstance()->getSelection()->getObjectCount() == 1;
@@ -351,7 +353,7 @@ void LLPanelVolume::getState( )
getChild<LLUICtrl>("Flexible1D Checkbox Ctrl")->setValue(is_flexible);
if (is_flexible || (volobjp && volobjp->canBeFlexible()))
{
- getChildView("Flexible1D Checkbox Ctrl")->setEnabled(editable && single_volume && volobjp && !volobjp->isMesh());
+ getChildView("Flexible1D Checkbox Ctrl")->setEnabled(editable && single_volume && volobjp && !volobjp->isMesh() && !objectp->isPermanentEnforced());
}
else
{
@@ -495,7 +497,7 @@ void LLPanelVolume::getState( )
mComboPhysicsShapeType->add(getString("Convex Hull"), LLSD(2));
mComboPhysicsShapeType->setValue(LLSD(objectp->getPhysicsShapeType()));
- mComboPhysicsShapeType->setEnabled(editable);
+ mComboPhysicsShapeType->setEnabled(editable && !objectp->isPermanentEnforced() && ((root_objectp == NULL) || !root_objectp->isPermanentEnforced()));
mObject = objectp;
mRootObject = root_objectp;
@@ -708,9 +710,19 @@ void LLPanelVolume::onLightCancelColor(const LLSD& data)
void LLPanelVolume::onLightCancelTexture(const LLSD& data)
{
LLTextureCtrl* LightTextureCtrl = getChild<LLTextureCtrl>("light texture control");
+
if (LightTextureCtrl)
{
- LightTextureCtrl->setImageAssetID(mLightSavedTexture);
+ LightTextureCtrl->setImageAssetID(LLUUID::null);
+ }
+
+ LLVOVolume *volobjp = (LLVOVolume *) mObject.get();
+ if(volobjp)
+ {
+ // Cancel the light texture as requested
+ // NORSPEC-292
+ //
+ volobjp->setLightTextureID(LLUUID::null);
}
}
@@ -873,10 +885,26 @@ void LLPanelVolume::onCommitFlexible( LLUICtrl* ctrl, void* userdata )
self->refresh();
}
-// static
-void LLPanelVolume::onCommitIsFlexible( LLUICtrl* ctrl, void* userdata )
+void LLPanelVolume::onCommitIsFlexible(LLUICtrl *, void*)
{
- LLPanelVolume* self = (LLPanelVolume*) userdata;
- self->sendIsFlexible();
+ if (mObject->flagObjectPermanent())
+ {
+ LLNotificationsUtil::add("PathfindingLinksets_ChangeToFlexiblePath", LLSD(), LLSD(), boost::bind(&LLPanelVolume::handleResponseChangeToFlexible, this, _1, _2));
+ }
+ else
+ {
+ sendIsFlexible();
+ }
}
+void LLPanelVolume::handleResponseChangeToFlexible(const LLSD &pNotification, const LLSD &pResponse)
+{
+ if (LLNotificationsUtil::getSelectedOption(pNotification, pResponse) == 0)
+ {
+ sendIsFlexible();
+ }
+ else
+ {
+ getChild<LLUICtrl>("Flexible1D Checkbox Ctrl")->setValue(FALSE);
+ }
+}
diff --git a/indra/newview/llpanelvolume.h b/indra/newview/llpanelvolume.h
index 0ef47db0d9..deb6b6f2a6 100644..100755
--- a/indra/newview/llpanelvolume.h
+++ b/indra/newview/llpanelvolume.h
@@ -61,7 +61,7 @@ public:
static void onCommitIsLight( LLUICtrl* ctrl, void* userdata);
static void onCommitLight( LLUICtrl* ctrl, void* userdata);
- static void onCommitIsFlexible( LLUICtrl* ctrl, void* userdata);
+ void onCommitIsFlexible( LLUICtrl* ctrl, void* userdata);
static void onCommitFlexible( LLUICtrl* ctrl, void* userdata);
static void onCommitPhysicsParam( LLUICtrl* ctrl, void* userdata);
static void onCommitMaterial( LLUICtrl* ctrl, void* userdata);
@@ -84,6 +84,8 @@ protected:
void sendPhysicsRestitution(LLUICtrl* ctrl, void* userdata);
void sendPhysicsDensity(LLUICtrl* ctrl, void* userdata);
+ void handleResponseChangeToFlexible(const LLSD &pNotification, const LLSD &pResponse);
+
/*
LLTextBox* mLabelSelectSingleMessage;
// Light
diff --git a/indra/newview/llpanelvolumepulldown.cpp b/indra/newview/llpanelvolumepulldown.cpp
index aea7b33d7f..aea7b33d7f 100644..100755
--- a/indra/newview/llpanelvolumepulldown.cpp
+++ b/indra/newview/llpanelvolumepulldown.cpp
diff --git a/indra/newview/llpanelvolumepulldown.h b/indra/newview/llpanelvolumepulldown.h
index 0d86e6bd28..0d86e6bd28 100644..100755
--- a/indra/newview/llpanelvolumepulldown.h
+++ b/indra/newview/llpanelvolumepulldown.h
diff --git a/indra/newview/llpanelwearing.cpp b/indra/newview/llpanelwearing.cpp
index 3b9934d4be..aa3ed22bee 100644..100755
--- a/indra/newview/llpanelwearing.cpp
+++ b/indra/newview/llpanelwearing.cpp
@@ -77,11 +77,7 @@ private:
{
uuid_vec_t selected_uuids;
mPanelWearing->getSelectedItemsUUIDs(selected_uuids);
-
- for (uuid_vec_t::const_iterator it=selected_uuids.begin(); it != selected_uuids.end(); ++it)
- {
- LLAppearanceMgr::instance().removeItemFromAvatar(*it);
- }
+ LLAppearanceMgr::instance().removeItemsFromAvatar(selected_uuids);
}
LLToggleableMenu* mMenu;
@@ -97,12 +93,11 @@ protected:
{
LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
- functor_t take_off = boost::bind(&LLAppearanceMgr::removeItemFromAvatar, LLAppearanceMgr::getInstance(), _1);
-
registrar.add("Wearing.Edit", boost::bind(&edit_outfit));
- registrar.add("Wearing.TakeOff", boost::bind(handleMultiple, take_off, mUUIDs));
- registrar.add("Wearing.Detach", boost::bind(handleMultiple, take_off, mUUIDs));
-
+ registrar.add("Wearing.TakeOff",
+ boost::bind(&LLAppearanceMgr::removeItemsFromAvatar, LLAppearanceMgr::getInstance(), mUUIDs));
+ registrar.add("Wearing.Detach",
+ boost::bind(&LLAppearanceMgr::removeItemsFromAvatar, LLAppearanceMgr::getInstance(), mUUIDs));
LLContextMenu* menu = createFromFile("menu_wearing_tab.xml");
updateMenuItemsVisibility(menu);
diff --git a/indra/newview/llpanelwearing.h b/indra/newview/llpanelwearing.h
index 9a212b3cca..9a212b3cca 100644..100755
--- a/indra/newview/llpanelwearing.h
+++ b/indra/newview/llpanelwearing.h
diff --git a/indra/newview/llparcelselection.cpp b/indra/newview/llparcelselection.cpp
index 4d1901adc9..4d1901adc9 100644..100755
--- a/indra/newview/llparcelselection.cpp
+++ b/indra/newview/llparcelselection.cpp
diff --git a/indra/newview/llparcelselection.h b/indra/newview/llparcelselection.h
index 1cbdfc6f74..1cbdfc6f74 100644..100755
--- a/indra/newview/llparcelselection.h
+++ b/indra/newview/llparcelselection.h
diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp
index 975a6c67d8..ee6893907e 100644..100755
--- a/indra/newview/llparticipantlist.cpp
+++ b/indra/newview/llparticipantlist.cpp
@@ -1,6 +1,6 @@
/**
* @file llparticipantlist.cpp
- * @brief LLParticipantList intended to update view(LLAvatarList) according to incoming messages
+ * @brief LLParticipantList : model of a conversation session with added speaker events handling
*
* $LicenseInfo:firstyear=2009&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -26,38 +26,18 @@
#include "llviewerprecompiledheaders.h"
-// common includes
-#include "lltrans.h"
-#include "llavataractions.h"
-#include "llagent.h"
-
+#include "llavatarnamecache.h"
+#include "llerror.h"
#include "llimview.h"
-#include "llnotificationsutil.h"
+#include "llfloaterimcontainer.h"
#include "llparticipantlist.h"
#include "llspeakers.h"
-#include "llviewercontrol.h"
-#include "llviewermenu.h"
-#include "llvoiceclient.h"
//LLParticipantList retrieves add, clear and remove events and updates view accordingly
#if LL_MSVC
#pragma warning (disable : 4355) // 'this' used in initializer list: yes, intentionally
#endif
-static const LLAvatarItemAgentOnTopComparator AGENT_ON_TOP_NAME_COMPARATOR;
-
-// helper function to update AvatarList Item's indicator in the voice participant list
-static void update_speaker_indicator(const LLAvatarList* const avatar_list, const LLUUID& avatar_uuid, bool is_muted)
-{
- LLAvatarListItem* item = dynamic_cast<LLAvatarListItem*>(avatar_list->getItemByValue(avatar_uuid));
- if (item)
- {
- LLOutputMonitorCtrl* indicator = item->getChild<LLOutputMonitorCtrl>("speaking_indicator");
- indicator->setIsMuted(is_muted);
- }
-}
-
-
// See EXT-4301.
/**
* class LLAvalineUpdater - observe the list of voice participants in session and check
@@ -197,15 +177,9 @@ private:
uuid_set_t mAvalineCallers;
};
-LLParticipantList::LLParticipantList(LLSpeakerMgr* data_source,
- LLAvatarList* avatar_list,
- bool use_context_menu/* = true*/,
- bool exclude_agent /*= true*/,
- bool can_toggle_icons /*= true*/) :
+LLParticipantList::LLParticipantList(LLSpeakerMgr* data_source, LLFolderViewModelInterface& root_view_model) :
+ LLConversationItemSession(data_source->getSessionID(), root_view_model),
mSpeakerMgr(data_source),
- mAvatarList(avatar_list),
- mParticipantListMenu(NULL),
- mExcludeAgent(exclude_agent),
mValidateSpeakerCallback(NULL)
{
@@ -216,36 +190,16 @@ LLParticipantList::LLParticipantList(LLSpeakerMgr* data_source,
mSpeakerRemoveListener = new SpeakerRemoveListener(*this);
mSpeakerClearListener = new SpeakerClearListener(*this);
mSpeakerModeratorListener = new SpeakerModeratorUpdateListener(*this);
+ mSpeakerUpdateListener = new SpeakerUpdateListener(*this);
mSpeakerMuteListener = new SpeakerMuteListener(*this);
mSpeakerMgr->addListener(mSpeakerAddListener, "add");
mSpeakerMgr->addListener(mSpeakerRemoveListener, "remove");
mSpeakerMgr->addListener(mSpeakerClearListener, "clear");
mSpeakerMgr->addListener(mSpeakerModeratorListener, "update_moderator");
+ mSpeakerMgr->addListener(mSpeakerUpdateListener, "update_speaker");
- mAvatarList->setNoItemsCommentText(LLTrans::getString("LoadingData"));
- LL_DEBUGS("SpeakingIndicator") << "Set session for speaking indicators: " << mSpeakerMgr->getSessionID() << LL_ENDL;
- mAvatarList->setSessionID(mSpeakerMgr->getSessionID());
- mAvatarListDoubleClickConnection = mAvatarList->setItemDoubleClickCallback(boost::bind(&LLParticipantList::onAvatarListDoubleClicked, this, _1));
- mAvatarListRefreshConnection = mAvatarList->setRefreshCompleteCallback(boost::bind(&LLParticipantList::onAvatarListRefreshed, this, _1, _2));
- // Set onAvatarListDoubleClicked as default on_return action.
- mAvatarListReturnConnection = mAvatarList->setReturnCallback(boost::bind(&LLParticipantList::onAvatarListDoubleClicked, this, mAvatarList));
-
- if (use_context_menu)
- {
- mParticipantListMenu = new LLParticipantListMenu(*this);
- mAvatarList->setContextMenu(mParticipantListMenu);
- }
- else
- {
- mAvatarList->setContextMenu(NULL);
- }
-
- if (use_context_menu && can_toggle_icons)
- {
- mAvatarList->setShowIcons("ParticipantListShowIcons");
- mAvatarListToggleIconsConnection = gSavedSettings.getControl("ParticipantListShowIcons")->getSignal()->connect(boost::bind(&LLAvatarList::toggleIcons, mAvatarList));
- }
+ setSessionID(mSpeakerMgr->getSessionID());
//Lets fill avatarList with existing speakers
LLSpeakerMgr::speaker_list_t speaker_list;
@@ -264,138 +218,32 @@ LLParticipantList::LLParticipantList(LLSpeakerMgr* data_source,
mModeratorToRemoveList.insert(speakerp->mID);
}
}
- // we need to exclude agent id for non group chat
- sort();
-}
-
-LLParticipantList::~LLParticipantList()
-{
- mAvatarListDoubleClickConnection.disconnect();
- mAvatarListRefreshConnection.disconnect();
- mAvatarListReturnConnection.disconnect();
- mAvatarListToggleIconsConnection.disconnect();
-
- // It is possible Participant List will be re-created from LLCallFloater::onCurrentChannelChanged()
- // See ticket EXT-3427
- // hide menu before deleting it to stop enable and check handlers from triggering.
- if(mParticipantListMenu && !LLApp::isExiting())
- {
- mParticipantListMenu->hide();
- }
-
- if (mParticipantListMenu)
- {
- delete mParticipantListMenu;
- mParticipantListMenu = NULL;
- }
-
- mAvatarList->setContextMenu(NULL);
- mAvatarList->setComparator(NULL);
-
- delete mAvalineUpdater;
-}
-
-void LLParticipantList::setSpeakingIndicatorsVisible(BOOL visible)
-{
- mAvatarList->setSpeakingIndicatorsVisible(visible);
-};
-
-void LLParticipantList::onAvatarListDoubleClicked(LLUICtrl* ctrl)
-{
- LLAvatarListItem* item = dynamic_cast<LLAvatarListItem*>(ctrl);
- if(!item)
- {
- return;
- }
-
- LLUUID clicked_id = item->getAvatarId();
-
- if (clicked_id.isNull() || clicked_id == gAgent.getID())
- return;
- LLAvatarActions::startIM(clicked_id);
-}
-
-void LLParticipantList::onAvatarListRefreshed(LLUICtrl* ctrl, const LLSD& param)
-{
- LLAvatarList* list = dynamic_cast<LLAvatarList*>(ctrl);
- if (list)
+ // Identify and store what kind of session we are
+ LLIMModel::LLIMSession* im_session = LLIMModel::getInstance()->findIMSession(data_source->getSessionID());
+ if (im_session)
{
- const std::string moderator_indicator(LLTrans::getString("IM_moderator_label"));
- const std::size_t moderator_indicator_len = moderator_indicator.length();
-
- // Firstly remove moderators indicator
- std::set<LLUUID>::const_iterator
- moderator_list_it = mModeratorToRemoveList.begin(),
- moderator_list_end = mModeratorToRemoveList.end();
- for (;moderator_list_it != moderator_list_end; ++moderator_list_it)
+ // By default, sessions that can't be identified as group or ad-hoc will be considered P2P (i.e. 1 on 1)
+ mConvType = CONV_SESSION_1_ON_1;
+ if (im_session->isAdHocSessionType())
{
- LLAvatarListItem* item = dynamic_cast<LLAvatarListItem*> (list->getItemByValue(*moderator_list_it));
- if ( item )
- {
- std::string name = item->getAvatarName();
- std::string tooltip = item->getAvatarToolTip();
- size_t found = name.find(moderator_indicator);
- if (found != std::string::npos)
- {
- name.erase(found, moderator_indicator_len);
- item->setAvatarName(name);
- }
- found = tooltip.find(moderator_indicator);
- if (found != tooltip.npos)
- {
- tooltip.erase(found, moderator_indicator_len);
- item->setAvatarToolTip(tooltip);
- }
- }
- }
-
- mModeratorToRemoveList.clear();
-
- // Add moderators indicator
- moderator_list_it = mModeratorList.begin();
- moderator_list_end = mModeratorList.end();
- for (;moderator_list_it != moderator_list_end; ++moderator_list_it)
- {
- LLAvatarListItem* item = dynamic_cast<LLAvatarListItem*> (list->getItemByValue(*moderator_list_it));
- if ( item )
- {
- std::string name = item->getAvatarName();
- std::string tooltip = item->getAvatarToolTip();
- size_t found = name.find(moderator_indicator);
- if (found == std::string::npos)
- {
- name += " ";
- name += moderator_indicator;
- item->setAvatarName(name);
- }
- found = tooltip.find(moderator_indicator);
- if (found == std::string::npos)
- {
- tooltip += " ";
- tooltip += moderator_indicator;
- item->setAvatarToolTip(tooltip);
- }
- }
+ mConvType = CONV_SESSION_AD_HOC;
}
-
- // update voice mute state of all items. See EXT-7235
- LLSpeakerMgr::speaker_list_t speaker_list;
-
- // Use also participants which are not in voice session now (the second arg is TRUE).
- // They can already have mModeratorMutedVoice set from the previous voice session
- // and LLSpeakerVoiceModerationEvent will not be sent when speaker manager is updated next time.
- mSpeakerMgr->getSpeakerList(&speaker_list, TRUE);
- for(LLSpeakerMgr::speaker_list_t::iterator it = speaker_list.begin(); it != speaker_list.end(); it++)
+ else if (im_session->isGroupSessionType())
{
- const LLPointer<LLSpeaker>& speakerp = *it;
-
- if (speakerp->mStatus == LLSpeaker::STATUS_TEXT_ONLY)
- {
- update_speaker_indicator(list, speakerp->mID, speakerp->mModeratorMutedVoice);
- }
+ mConvType = CONV_SESSION_GROUP;
}
}
+ else
+ {
+ // That's the only session that doesn't get listed in the LLIMModel as a session...
+ mConvType = CONV_SESSION_NEARBY;
+ }
+}
+
+LLParticipantList::~LLParticipantList()
+{
+ delete mAvalineUpdater;
}
/*
@@ -411,31 +259,11 @@ void LLParticipantList::onAvatarListRefreshed(LLUICtrl* ctrl, const LLSD& param)
*/
void LLParticipantList::onAvalineCallerFound(const LLUUID& participant_id)
{
- LLPanel* item = mAvatarList->getItemByValue(participant_id);
-
- if (NULL == item)
- {
- LL_WARNS("Avaline") << "Something wrong. Unable to find item for: " << participant_id << LL_ENDL;
- return;
- }
-
- if (typeid(*item) == typeid(LLAvalineListItem))
+ LLConversationItemParticipant* participant = findParticipant(participant_id);
+ if (participant)
{
- LL_DEBUGS("Avaline") << "Avaline caller has already correct class type for: " << participant_id << LL_ENDL;
- // item representing an Avaline caller has a correct type already.
- return;
+ removeParticipant(participant);
}
-
- LL_DEBUGS("Avaline") << "remove item from the list and re-add it: " << participant_id << LL_ENDL;
-
- // remove UUID from LLAvatarList::mIDs to be able add it again.
- uuid_vec_t& ids = mAvatarList->getIDs();
- uuid_vec_t::iterator pos = std::find(ids.begin(), ids.end(), participant_id);
- ids.erase(pos);
-
- // remove item directly
- mAvatarList->removeItem(item);
-
// re-add avaline caller with a correct class instance.
addAvatarIDExceptAgent(participant_id);
}
@@ -447,23 +275,6 @@ void LLParticipantList::onAvalineCallerRemoved(const LLUUID& participant_id)
mSpeakerMgr->removeAvalineSpeaker(participant_id);
}
-void LLParticipantList::setSortOrder(EParticipantSortOrder order)
-{
- const U32 speaker_sort_order = gSavedSettings.getU32("SpeakerParticipantDefaultOrder");
-
- if ( speaker_sort_order != order )
- {
- gSavedSettings.setU32("SpeakerParticipantDefaultOrder", (U32)order);
- sort();
- }
-}
-
-const LLParticipantList::EParticipantSortOrder LLParticipantList::getSortOrder() const
-{
- const U32 speaker_sort_order = gSavedSettings.getU32("SpeakerParticipantDefaultOrder");
- return EParticipantSortOrder(speaker_sort_order);
-}
-
void LLParticipantList::setValidateSpeakerCallback(validate_speaker_callback_t cb)
{
mValidateSpeakerCallback = cb;
@@ -472,19 +283,6 @@ void LLParticipantList::setValidateSpeakerCallback(validate_speaker_callback_t c
void LLParticipantList::update()
{
mSpeakerMgr->update(true);
-
- if (E_SORT_BY_RECENT_SPEAKERS == getSortOrder() && !isHovered())
- {
- // Resort avatar list
- sort();
- }
-}
-
-bool LLParticipantList::isHovered()
-{
- S32 x, y;
- LLUI::getMousePositionScreen(&x, &y);
- return mAvatarList->calcScreenRect().pointInRect(x, y);
}
bool LLParticipantList::onAddItemEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata)
@@ -497,27 +295,34 @@ bool LLParticipantList::onAddItemEvent(LLPointer<LLOldEvents::LLEvent> event, co
}
addAvatarIDExceptAgent(uu_id);
- sort();
return true;
}
bool LLParticipantList::onRemoveItemEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata)
{
- uuid_vec_t& group_members = mAvatarList->getIDs();
- uuid_vec_t::iterator pos = std::find(group_members.begin(), group_members.end(), event->getValue().asUUID());
- if(pos != group_members.end())
- {
- group_members.erase(pos);
- mAvatarList->setDirty();
- }
+ LLUUID avatar_id = event->getValue().asUUID();
+ removeParticipant(avatar_id);
return true;
}
bool LLParticipantList::onClearListEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata)
{
- uuid_vec_t& group_members = mAvatarList->getIDs();
- group_members.clear();
- mAvatarList->setDirty();
+ clearParticipants();
+ return true;
+}
+
+bool LLParticipantList::onSpeakerUpdateEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata)
+{
+ const LLSD& evt_data = event->getValue();
+ if ( evt_data.has("id") )
+ {
+ LLUUID participant_id = evt_data["id"];
+ LLFloaterIMContainer* im_box = LLFloaterIMContainer::findInstance();
+ if (im_box)
+ {
+ im_box->setTimeNow(mUUID,participant_id);
+ }
+ }
return true;
}
@@ -541,9 +346,7 @@ bool LLParticipantList::onModeratorUpdateEvent(LLPointer<LLOldEvents::LLEvent> e
mModeratorList.erase(id);
}
}
-
- // apply changes immediately
- onAvatarListRefreshed(mAvatarList, LLSD());
+ // *TODO : do we have to fire an event so that LLFloaterIMSessionTab::refreshConversation() gets called
}
}
return true;
@@ -557,63 +360,50 @@ bool LLParticipantList::onSpeakerMuteEvent(LLPointer<LLOldEvents::LLEvent> event
// update UI on confirmation of moderator mutes
if (event->getValue().asString() == "voice")
{
- update_speaker_indicator(mAvatarList, speakerp->mID, speakerp->mModeratorMutedVoice);
+ setParticipantIsMuted(speakerp->mID, speakerp->mModeratorMutedVoice);
}
return true;
}
-void LLParticipantList::sort()
+void LLParticipantList::addAvatarIDExceptAgent(const LLUUID& avatar_id)
{
- if ( !mAvatarList )
- return;
-
- switch ( getSortOrder() )
+ // Do not add if already in there, is the session id (hence not an avatar) or excluded for some reason
+ if (findParticipant(avatar_id) || (avatar_id == mUUID))
{
- case E_SORT_BY_NAME :
- // if mExcludeAgent == true , then no need to keep agent on top of the list
- if(mExcludeAgent)
- {
- mAvatarList->sortByName();
- }
- else
- {
- mAvatarList->setComparator(&AGENT_ON_TOP_NAME_COMPARATOR);
- mAvatarList->sort();
- }
- break;
- case E_SORT_BY_RECENT_SPEAKERS:
- if (mSortByRecentSpeakers.isNull())
- mSortByRecentSpeakers = new LLAvatarItemRecentSpeakerComparator(*this);
- mAvatarList->setComparator(mSortByRecentSpeakers.get());
- mAvatarList->sort();
- break;
- default :
- llwarns << "Unrecognized sort order for " << mAvatarList->getName() << llendl;
- return;
+ return;
}
-}
-
-void LLParticipantList::addAvatarIDExceptAgent(const LLUUID& avatar_id)
-{
- if (mExcludeAgent && gAgent.getID() == avatar_id) return;
- if (mAvatarList->contains(avatar_id)) return;
bool is_avatar = LLVoiceClient::getInstance()->isParticipantAvatar(avatar_id);
+ LLConversationItemParticipant* participant = NULL;
+
if (is_avatar)
{
- mAvatarList->getIDs().push_back(avatar_id);
- mAvatarList->setDirty();
+ // Create a participant view model instance
+ LLAvatarName avatar_name;
+ bool has_name = LLAvatarNameCache::get(avatar_id, &avatar_name);
+ participant = new LLConversationItemParticipant(!has_name ? LLTrans::getString("AvatarNameWaiting") : avatar_name.getDisplayName() , avatar_id, mRootViewModel);
+ participant->fetchAvatarName();
}
else
{
std::string display_name = LLVoiceClient::getInstance()->getDisplayName(avatar_id);
- mAvatarList->addAvalineItem(avatar_id, mSpeakerMgr->getSessionID(), display_name.empty() ? LLTrans::getString("AvatarNameWaiting") : display_name);
+ // Create a participant view model instance
+ participant = new LLConversationItemParticipant(display_name.empty() ? LLTrans::getString("AvatarNameWaiting") : display_name, avatar_id, mRootViewModel);
mAvalineUpdater->watchAvalineCaller(avatar_id);
}
+
+ // *TODO : Need to update the online/offline status of the participant
+ // Hack for this: LLAvatarTracker::instance().isBuddyOnline(avatar_id))
+
+ // Add the participant model to the session's children list
+ addParticipant(participant);
+
adjustParticipant(avatar_id);
}
+static LLFastTimer::DeclareTimer FTM_FOLDERVIEW_TEST("add test avatar agents");
+
void LLParticipantList::adjustParticipant(const LLUUID& speaker_id)
{
LLPointer<LLSpeaker> speakerp = mSpeakerMgr->findSpeaker(speaker_id);
@@ -629,12 +419,12 @@ void LLParticipantList::adjustParticipant(const LLUUID& speaker_id)
bool LLParticipantList::SpeakerAddListener::handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata)
{
/**
- * We need to filter speaking objects. These objects shouldn't appear in the list
+ * We need to filter speaking objects. These objects shouldn't appear in the list.
* @see LLFloaterChat::addChat() in llviewermessage.cpp to get detailed call hierarchy
*/
const LLUUID& speaker_id = event->getValue().asUUID();
LLPointer<LLSpeaker> speaker = mParent.mSpeakerMgr->findSpeaker(speaker_id);
- if(speaker.isNull() || speaker->mType == LLSpeaker::SPEAKER_OBJECT)
+ if (speaker.isNull() || (speaker->mType == LLSpeaker::SPEAKER_OBJECT))
{
return false;
}
@@ -658,6 +448,14 @@ bool LLParticipantList::SpeakerClearListener::handleEvent(LLPointer<LLOldEvents:
}
//
+// LLParticipantList::SpeakerUpdateListener
+//
+bool LLParticipantList::SpeakerUpdateListener::handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata)
+{
+ return mParent.onSpeakerUpdateEvent(event, userdata);
+}
+
+//
// LLParticipantList::SpeakerModeratorListener
//
bool LLParticipantList::SpeakerModeratorUpdateListener::handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata)
@@ -670,377 +468,4 @@ bool LLParticipantList::SpeakerMuteListener::handleEvent(LLPointer<LLOldEvents::
return mParent.onSpeakerMuteEvent(event, userdata);
}
-LLContextMenu* LLParticipantList::LLParticipantListMenu::createMenu()
-{
- // set up the callbacks for all of the avatar menu items
- LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
- LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
-
- registrar.add("ParticipantList.Sort", boost::bind(&LLParticipantList::LLParticipantListMenu::sortParticipantList, this, _2));
- registrar.add("ParticipantList.ToggleAllowTextChat", boost::bind(&LLParticipantList::LLParticipantListMenu::toggleAllowTextChat, this, _2));
- registrar.add("ParticipantList.ToggleMuteText", boost::bind(&LLParticipantList::LLParticipantListMenu::toggleMuteText, this, _2));
-
- registrar.add("Avatar.Profile", boost::bind(&LLAvatarActions::showProfile, mUUIDs.front()));
- registrar.add("Avatar.IM", boost::bind(&LLAvatarActions::startIM, mUUIDs.front()));
- registrar.add("Avatar.AddFriend", boost::bind(&LLAvatarActions::requestFriendshipDialog, mUUIDs.front()));
- registrar.add("Avatar.BlockUnblock", boost::bind(&LLParticipantList::LLParticipantListMenu::toggleMuteVoice, this, _2));
- registrar.add("Avatar.Share", boost::bind(&LLAvatarActions::share, mUUIDs.front()));
- registrar.add("Avatar.Pay", boost::bind(&LLAvatarActions::pay, mUUIDs.front()));
- registrar.add("Avatar.Call", boost::bind(&LLAvatarActions::startCall, mUUIDs.front()));
-
- registrar.add("ParticipantList.ModerateVoice", boost::bind(&LLParticipantList::LLParticipantListMenu::moderateVoice, this, _2));
-
- enable_registrar.add("ParticipantList.EnableItem", boost::bind(&LLParticipantList::LLParticipantListMenu::enableContextMenuItem, this, _2));
- enable_registrar.add("ParticipantList.EnableItem.Moderate", boost::bind(&LLParticipantList::LLParticipantListMenu::enableModerateContextMenuItem, this, _2));
- enable_registrar.add("ParticipantList.CheckItem", boost::bind(&LLParticipantList::LLParticipantListMenu::checkContextMenuItem, this, _2));
-
- // create the context menu from the XUI
- LLContextMenu* main_menu = createFromFile("menu_participant_list.xml");
-
- // Don't show sort options for P2P chat
- bool is_sort_visible = (mParent.mAvatarList && mParent.mAvatarList->size() > 1);
- main_menu->setItemVisible("SortByName", is_sort_visible);
- main_menu->setItemVisible("SortByRecentSpeakers", is_sort_visible);
- main_menu->setItemVisible("Moderator Options Separator", isGroupModerator());
- main_menu->setItemVisible("Moderator Options", isGroupModerator());
- main_menu->setItemVisible("View Icons Separator", mParent.mAvatarListToggleIconsConnection.connected());
- main_menu->setItemVisible("View Icons", mParent.mAvatarListToggleIconsConnection.connected());
- main_menu->arrangeAndClear();
-
- return main_menu;
-}
-
-void LLParticipantList::LLParticipantListMenu::show(LLView* spawning_view, const uuid_vec_t& uuids, S32 x, S32 y)
-{
- if (uuids.size() == 0) return;
-
- LLListContextMenu::show(spawning_view, uuids, x, y);
-
- const LLUUID& speaker_id = mUUIDs.front();
- BOOL is_muted = isMuted(speaker_id);
-
- if (is_muted)
- {
- LLMenuGL::sMenuContainer->getChildView("ModerateVoiceMuteSelected")->setVisible( false);
- }
- else
- {
- LLMenuGL::sMenuContainer->getChildView("ModerateVoiceUnMuteSelected")->setVisible( false);
- }
-}
-
-void LLParticipantList::LLParticipantListMenu::sortParticipantList(const LLSD& userdata)
-{
- std::string param = userdata.asString();
- if ("sort_by_name" == param)
- {
- mParent.setSortOrder(E_SORT_BY_NAME);
- }
- else if ("sort_by_recent_speakers" == param)
- {
- mParent.setSortOrder(E_SORT_BY_RECENT_SPEAKERS);
- }
-}
-
-void LLParticipantList::LLParticipantListMenu::toggleAllowTextChat(const LLSD& userdata)
-{
-
- LLIMSpeakerMgr* mgr = dynamic_cast<LLIMSpeakerMgr*>(mParent.mSpeakerMgr);
- if (mgr)
- {
- const LLUUID speaker_id = mUUIDs.front();
- mgr->toggleAllowTextChat(speaker_id);
- }
-}
-
-void LLParticipantList::LLParticipantListMenu::toggleMute(const LLSD& userdata, U32 flags)
-{
- const LLUUID speaker_id = mUUIDs.front();
- BOOL is_muted = LLMuteList::getInstance()->isMuted(speaker_id, flags);
- std::string name;
-
- //fill in name using voice client's copy of name cache
- LLPointer<LLSpeaker> speakerp = mParent.mSpeakerMgr->findSpeaker(speaker_id);
- if (speakerp.isNull())
- {
- LL_WARNS("Speakers") << "Speaker " << speaker_id << " not found" << llendl;
- return;
- }
- LLAvatarListItem* item = dynamic_cast<LLAvatarListItem*>(mParent.mAvatarList->getItemByValue(speaker_id));
- if (NULL == item) return;
-
- name = item->getAvatarName();
-
- LLMute::EType mute_type;
- switch (speakerp->mType)
- {
- case LLSpeaker::SPEAKER_AGENT:
- mute_type = LLMute::AGENT;
- break;
- case LLSpeaker::SPEAKER_OBJECT:
- mute_type = LLMute::OBJECT;
- break;
- case LLSpeaker::SPEAKER_EXTERNAL:
- default:
- mute_type = LLMute::EXTERNAL;
- break;
- }
- LLMute mute(speaker_id, name, mute_type);
-
- if (!is_muted)
- {
- LLMuteList::getInstance()->add(mute, flags);
- }
- else
- {
- LLMuteList::getInstance()->remove(mute, flags);
- }
-}
-
-void LLParticipantList::LLParticipantListMenu::toggleMuteText(const LLSD& userdata)
-{
- toggleMute(userdata, LLMute::flagTextChat);
-}
-
-void LLParticipantList::LLParticipantListMenu::toggleMuteVoice(const LLSD& userdata)
-{
- toggleMute(userdata, LLMute::flagVoiceChat);
-}
-
-bool LLParticipantList::LLParticipantListMenu::isGroupModerator()
-{
- if (!mParent.mSpeakerMgr)
- {
- llwarns << "Speaker manager is missing" << llendl;
- return false;
- }
-
- // Is session a group call/chat?
- if(gAgent.isInGroup(mParent.mSpeakerMgr->getSessionID()))
- {
- LLSpeaker* speaker = mParent.mSpeakerMgr->findSpeaker(gAgentID).get();
-
- // Is agent a moderator?
- return speaker && speaker->mIsModerator;
- }
- return false;
-}
-
-bool LLParticipantList::LLParticipantListMenu::isMuted(const LLUUID& avatar_id)
-{
- LLPointer<LLSpeaker> selected_speakerp = mParent.mSpeakerMgr->findSpeaker(avatar_id);
- if (!selected_speakerp) return true;
-
- return selected_speakerp->mStatus == LLSpeaker::STATUS_MUTED;
-}
-
-void LLParticipantList::LLParticipantListMenu::moderateVoice(const LLSD& userdata)
-{
- if (!gAgent.getRegion()) return;
-
- bool moderate_selected = userdata.asString() == "selected";
-
- if (moderate_selected)
- {
- const LLUUID& selected_avatar_id = mUUIDs.front();
- bool is_muted = isMuted(selected_avatar_id);
- moderateVoiceParticipant(selected_avatar_id, is_muted);
- }
- else
- {
- bool unmute_all = userdata.asString() == "unmute_all";
- moderateVoiceAllParticipants(unmute_all);
- }
-}
-
-void LLParticipantList::LLParticipantListMenu::moderateVoiceParticipant(const LLUUID& avatar_id, bool unmute)
-{
- LLIMSpeakerMgr* mgr = dynamic_cast<LLIMSpeakerMgr*>(mParent.mSpeakerMgr);
- if (mgr)
- {
- mgr->moderateVoiceParticipant(avatar_id, unmute);
- }
-}
-
-void LLParticipantList::LLParticipantListMenu::moderateVoiceAllParticipants(bool unmute)
-{
- LLIMSpeakerMgr* mgr = dynamic_cast<LLIMSpeakerMgr*>(mParent.mSpeakerMgr);
- if (mgr)
- {
- if (!unmute)
- {
- LLSD payload;
- payload["session_id"] = mgr->getSessionID();
- LLNotificationsUtil::add("ConfirmMuteAll", LLSD(), payload, confirmMuteAllCallback);
- return;
- }
-
- mgr->moderateVoiceAllParticipants(unmute);
- }
-}
-
-// static
-void LLParticipantList::LLParticipantListMenu::confirmMuteAllCallback(const LLSD& notification, const LLSD& response)
-{
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
- // if Cancel pressed
- if (option == 1)
- {
- return;
- }
-
- const LLSD& payload = notification["payload"];
- const LLUUID& session_id = payload["session_id"];
-
- LLIMSpeakerMgr * speaker_manager = dynamic_cast<LLIMSpeakerMgr*> (
- LLIMModel::getInstance()->getSpeakerManager(session_id));
- if (speaker_manager)
- {
- speaker_manager->moderateVoiceAllParticipants(false);
- }
-
- return;
-}
-
-
-bool LLParticipantList::LLParticipantListMenu::enableContextMenuItem(const LLSD& userdata)
-{
- std::string item = userdata.asString();
- const LLUUID& participant_id = mUUIDs.front();
-
- // For now non of "can_view_profile" action and menu actions listed below except "can_block"
- // can be performed for Avaline callers.
- bool is_participant_avatar = LLVoiceClient::getInstance()->isParticipantAvatar(participant_id);
- if (!is_participant_avatar && "can_block" != item) return false;
-
- if (item == "can_mute_text" || "can_block" == item || "can_share" == item || "can_im" == item
- || "can_pay" == item)
- {
- return mUUIDs.front() != gAgentID;
- }
- else if (item == std::string("can_add"))
- {
- // We can add friends if:
- // - there are selected people
- // - and there are no friends among selection yet.
-
- bool result = (mUUIDs.size() > 0);
-
- uuid_vec_t::const_iterator
- id = mUUIDs.begin(),
- uuids_end = mUUIDs.end();
-
- for (;id != uuids_end; ++id)
- {
- if ( *id == gAgentID || LLAvatarActions::isFriend(*id) )
- {
- result = false;
- break;
- }
- }
- return result;
- }
- else if (item == "can_call")
- {
- bool not_agent = mUUIDs.front() != gAgentID;
- bool can_call = not_agent && LLVoiceClient::getInstance()->voiceEnabled() && LLVoiceClient::getInstance()->isVoiceWorking();
- return can_call;
- }
-
- return true;
-}
-
-/*
- Processed menu items with such parameters:
- can_allow_text_chat
- can_moderate_voice
-*/
-bool LLParticipantList::LLParticipantListMenu::enableModerateContextMenuItem(const LLSD& userdata)
-{
- // only group moderators can perform actions related to this "enable callback"
- if (!isGroupModerator()) return false;
-
- const LLUUID& participant_id = mUUIDs.front();
- LLPointer<LLSpeaker> speakerp = mParent.mSpeakerMgr->findSpeaker(participant_id);
-
- // not in voice participants can not be moderated
- bool speaker_in_voice = speakerp.notNull() && speakerp->isInVoiceChannel();
-
- const std::string& item = userdata.asString();
-
- if ("can_moderate_voice" == item)
- {
- return speaker_in_voice;
- }
-
- // For now non of menu actions except "can_moderate_voice" can be performed for Avaline callers.
- bool is_participant_avatar = LLVoiceClient::getInstance()->isParticipantAvatar(participant_id);
- if (!is_participant_avatar) return false;
-
- return true;
-}
-
-bool LLParticipantList::LLParticipantListMenu::checkContextMenuItem(const LLSD& userdata)
-{
- std::string item = userdata.asString();
- const LLUUID& id = mUUIDs.front();
-
- if (item == "is_muted")
- {
- return LLMuteList::getInstance()->isMuted(id, LLMute::flagTextChat);
- }
- else if (item == "is_allowed_text_chat")
- {
- LLPointer<LLSpeaker> selected_speakerp = mParent.mSpeakerMgr->findSpeaker(id);
-
- if (selected_speakerp.notNull())
- {
- return !selected_speakerp->mModeratorMutedText;
- }
- }
- else if(item == "is_blocked")
- {
- return LLMuteList::getInstance()->isMuted(id, LLMute::flagVoiceChat);
- }
- else if(item == "is_sorted_by_name")
- {
- return E_SORT_BY_NAME == mParent.getSortOrder();
- }
- else if(item == "is_sorted_by_recent_speakers")
- {
- return E_SORT_BY_RECENT_SPEAKERS == mParent.getSortOrder();
- }
-
- return false;
-}
-
-bool LLParticipantList::LLAvatarItemRecentSpeakerComparator::doCompare(const LLAvatarListItem* avatar_item1, const LLAvatarListItem* avatar_item2) const
-{
- if (mParent.mSpeakerMgr)
- {
- LLPointer<LLSpeaker> lhs = mParent.mSpeakerMgr->findSpeaker(avatar_item1->getAvatarId());
- LLPointer<LLSpeaker> rhs = mParent.mSpeakerMgr->findSpeaker(avatar_item2->getAvatarId());
- if ( lhs.notNull() && rhs.notNull() )
- {
- // Compare by last speaking time
- if( lhs->mLastSpokeTime != rhs->mLastSpokeTime )
- return ( lhs->mLastSpokeTime > rhs->mLastSpokeTime );
- else if ( lhs->mSortIndex != rhs->mSortIndex )
- return ( lhs->mSortIndex < rhs->mSortIndex );
- }
- else if ( lhs.notNull() )
- {
- // True if only avatar_item1 speaker info available
- return true;
- }
- else if ( rhs.notNull() )
- {
- // False if only avatar_item2 speaker info available
- return false;
- }
- }
- // By default compare by name.
- return LLAvatarItemNameComparator::doCompare(avatar_item1, avatar_item2);
-}
-
//EOF
diff --git a/indra/newview/llparticipantlist.h b/indra/newview/llparticipantlist.h
index 53966c15fe..3a3ae76604 100644..100755
--- a/indra/newview/llparticipantlist.h
+++ b/indra/newview/llparticipantlist.h
@@ -1,6 +1,6 @@
/**
* @file llparticipantlist.h
- * @brief LLParticipantList intended to update view(LLAvatarList) according to incoming messages
+ * @brief LLParticipantList : model of a conversation session with added speaker events handling
*
* $LicenseInfo:firstyear=2009&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -28,35 +28,21 @@
#define LL_PARTICIPANTLIST_H
#include "llviewerprecompiledheaders.h"
-#include "llevent.h"
-#include "llavatarlist.h" // for LLAvatarItemRecentSpeakerComparator
-#include "lllistcontextmenu.h"
+#include "llconversationmodel.h"
class LLSpeakerMgr;
-class LLAvatarList;
class LLUICtrl;
class LLAvalineUpdater;
-class LLParticipantList
+class LLParticipantList : public LLConversationItemSession
{
LOG_CLASS(LLParticipantList);
public:
typedef boost::function<bool (const LLUUID& speaker_id)> validate_speaker_callback_t;
- LLParticipantList(LLSpeakerMgr* data_source,
- LLAvatarList* avatar_list,
- bool use_context_menu = true,
- bool exclude_agent = true,
- bool can_toggle_icons = true);
+ LLParticipantList(LLSpeakerMgr* data_source, LLFolderViewModelInterface& root_view_model);
~LLParticipantList();
- void setSpeakingIndicatorsVisible(BOOL visible);
-
- enum EParticipantSortOrder
- {
- E_SORT_BY_NAME = 0,
- E_SORT_BY_RECENT_SPEAKERS = 1,
- };
/**
* Adds specified avatar ID to the existing list if it is not Agent's ID
@@ -66,12 +52,6 @@ public:
void addAvatarIDExceptAgent(const LLUUID& avatar_id);
/**
- * Set and sort Avatarlist by given order
- */
- void setSortOrder(EParticipantSortOrder order = E_SORT_BY_NAME);
- const EParticipantSortOrder getSortOrder() const;
-
- /**
* Refreshes the participant list.
*/
void update();
@@ -93,14 +73,10 @@ protected:
bool onRemoveItemEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata);
bool onClearListEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata);
bool onModeratorUpdateEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata);
+ bool onSpeakerUpdateEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata);
bool onSpeakerMuteEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata);
/**
- * Sorts the Avatarlist by stored order
- */
- void sort();
-
- /**
* List of listeners implementing LLOldEvents::LLSimpleListener.
* There is no way to handle all the events in one listener as LLSpeakerMgr registers
* listeners in such a way that one listener can handle only one type of event
@@ -134,6 +110,13 @@ protected:
/*virtual*/ bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata);
};
+ class SpeakerUpdateListener : public BaseSpeakerListener
+ {
+ public:
+ SpeakerUpdateListener(LLParticipantList& parent) : BaseSpeakerListener(parent) {}
+ /*virtual*/ bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata);
+ };
+
class SpeakerModeratorUpdateListener : public BaseSpeakerListener
{
public:
@@ -149,98 +132,7 @@ protected:
/*virtual*/ bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata);
};
- /**
- * Menu used in the participant list.
- */
- class LLParticipantListMenu : public LLListContextMenu
- {
- public:
- LLParticipantListMenu(LLParticipantList& parent):mParent(parent){};
- /*virtual*/ LLContextMenu* createMenu();
- /*virtual*/ void show(LLView* spawning_view, const uuid_vec_t& uuids, S32 x, S32 y);
- protected:
- LLParticipantList& mParent;
- private:
- bool enableContextMenuItem(const LLSD& userdata);
- bool enableModerateContextMenuItem(const LLSD& userdata);
- bool checkContextMenuItem(const LLSD& userdata);
-
- void sortParticipantList(const LLSD& userdata);
- void toggleAllowTextChat(const LLSD& userdata);
- void toggleMute(const LLSD& userdata, U32 flags);
- void toggleMuteText(const LLSD& userdata);
- void toggleMuteVoice(const LLSD& userdata);
-
- /**
- * Return true if Agent is group moderator(and moderator of group call).
- */
- bool isGroupModerator();
-
- // Voice moderation support
- /**
- * Check whether specified by argument avatar is muted for group chat or not.
- */
- bool isMuted(const LLUUID& avatar_id);
-
- /**
- * Processes Voice moderation menu items.
- *
- * It calls either moderateVoiceParticipant() or moderateVoiceParticipant() depend on
- * passed parameter.
- *
- * @param userdata can be "selected" or "others".
- *
- * @see moderateVoiceParticipant()
- * @see moderateVoiceAllParticipants()
- */
- void moderateVoice(const LLSD& userdata);
-
- /**
- * Mutes/Unmutes avatar for current group voice chat.
- *
- * It only marks avatar as muted for session and does not use local Agent's Block list.
- * It does not mute Agent itself.
- *
- * @param[in] avatar_id UUID of avatar to be processed
- * @param[in] unmute if true - specified avatar will be muted, otherwise - unmuted.
- *
- * @see moderateVoiceAllParticipants()
- */
- void moderateVoiceParticipant(const LLUUID& avatar_id, bool unmute);
-
- /**
- * Mutes/Unmutes all avatars for current group voice chat.
- *
- * It only marks avatars as muted for session and does not use local Agent's Block list.
- *
- * @param[in] unmute if true - avatars will be muted, otherwise - unmuted.
- *
- * @see moderateVoiceParticipant()
- */
- void moderateVoiceAllParticipants(bool unmute);
-
- static void confirmMuteAllCallback(const LLSD& notification, const LLSD& response);
- };
-
- /**
- * Comparator for comparing avatar items by last spoken time
- */
- class LLAvatarItemRecentSpeakerComparator : public LLAvatarItemNameComparator, public LLRefCount
- {
- LOG_CLASS(LLAvatarItemRecentSpeakerComparator);
- public:
- LLAvatarItemRecentSpeakerComparator(LLParticipantList& parent):mParent(parent){};
- virtual ~LLAvatarItemRecentSpeakerComparator() {};
- protected:
- virtual bool doCompare(const LLAvatarListItem* avatar_item1, const LLAvatarListItem* avatar_item2) const;
- private:
- LLParticipantList& mParent;
- };
-
private:
- void onAvatarListDoubleClicked(LLUICtrl* ctrl);
- void onAvatarListRefreshed(LLUICtrl* ctrl, const LLSD& param);
-
void onAvalineCallerFound(const LLUUID& participant_id);
void onAvalineCallerRemoved(const LLUUID& participant_id);
@@ -251,10 +143,7 @@ private:
*/
void adjustParticipant(const LLUUID& speaker_id);
- bool isHovered();
-
LLSpeakerMgr* mSpeakerMgr;
- LLAvatarList* mAvatarList;
std::set<LLUUID> mModeratorList;
std::set<LLUUID> mModeratorToRemoveList;
@@ -262,25 +151,10 @@ private:
LLPointer<SpeakerAddListener> mSpeakerAddListener;
LLPointer<SpeakerRemoveListener> mSpeakerRemoveListener;
LLPointer<SpeakerClearListener> mSpeakerClearListener;
+ LLPointer<SpeakerUpdateListener> mSpeakerUpdateListener;
LLPointer<SpeakerModeratorUpdateListener> mSpeakerModeratorListener;
LLPointer<SpeakerMuteListener> mSpeakerMuteListener;
- LLParticipantListMenu* mParticipantListMenu;
-
- /**
- * This field manages an adding a new avatar_id in the mAvatarList
- * If true, then agent_id wont be added into mAvatarList
- * Also by default this field is controlling a sort procedure, @c sort()
- */
- bool mExcludeAgent;
-
- // boost::connections
- boost::signals2::connection mAvatarListDoubleClickConnection;
- boost::signals2::connection mAvatarListRefreshConnection;
- boost::signals2::connection mAvatarListReturnConnection;
- boost::signals2::connection mAvatarListToggleIconsConnection;
-
- LLPointer<LLAvatarItemRecentSpeakerComparator> mSortByRecentSpeakers;
validate_speaker_callback_t mValidateSpeakerCallback;
LLAvalineUpdater* mAvalineUpdater;
};
diff --git a/indra/newview/llpatchvertexarray.cpp b/indra/newview/llpatchvertexarray.cpp
index dece2928c0..dece2928c0 100644..100755
--- a/indra/newview/llpatchvertexarray.cpp
+++ b/indra/newview/llpatchvertexarray.cpp
diff --git a/indra/newview/llpatchvertexarray.h b/indra/newview/llpatchvertexarray.h
index 721f3f18b1..721f3f18b1 100644..100755
--- a/indra/newview/llpatchvertexarray.h
+++ b/indra/newview/llpatchvertexarray.h
diff --git a/indra/newview/llpathfindingcharacter.cpp b/indra/newview/llpathfindingcharacter.cpp
new file mode 100755
index 0000000000..00f2ebc4bb
--- /dev/null
+++ b/indra/newview/llpathfindingcharacter.cpp
@@ -0,0 +1,99 @@
+/**
+* @file llpathfindingcharacter.cpp
+* @brief Definition of a pathfinding character that contains various properties required for havok pathfinding.
+* @author Stinson@lindenlab.com
+*
+* $LicenseInfo:firstyear=2012&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2012, 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 "llpathfindingcharacter.h"
+
+#include <string>
+
+#include "llpathfindingobject.h"
+#include "llsd.h"
+
+#define CHARACTER_CPU_TIME_FIELD "cpu_time"
+#define CHARACTER_HORIZONTAL_FIELD "horizontal"
+#define CHARACTER_LENGTH_FIELD "length"
+#define CHARACTER_RADIUS_FIELD "radius"
+
+//---------------------------------------------------------------------------
+// LLPathfindingCharacter
+//---------------------------------------------------------------------------
+
+LLPathfindingCharacter::LLPathfindingCharacter(const std::string &pUUID, const LLSD& pCharacterData)
+ : LLPathfindingObject(pUUID, pCharacterData),
+ mCPUTime(0U),
+ mIsHorizontal(FALSE),
+ mLength(0.0f),
+ mRadius(0.0f)
+{
+ parseCharacterData(pCharacterData);
+}
+
+LLPathfindingCharacter::LLPathfindingCharacter(const LLPathfindingCharacter& pOther)
+ : LLPathfindingObject(pOther),
+ mCPUTime(pOther.mCPUTime),
+ mIsHorizontal(pOther.mIsHorizontal),
+ mLength(pOther.mLength),
+ mRadius(pOther.mRadius)
+{
+}
+
+LLPathfindingCharacter::~LLPathfindingCharacter()
+{
+}
+
+LLPathfindingCharacter& LLPathfindingCharacter::operator =(const LLPathfindingCharacter& pOther)
+{
+ dynamic_cast<LLPathfindingObject &>(*this) = pOther;
+
+ mCPUTime = pOther.mCPUTime;
+ mIsHorizontal = pOther.mIsHorizontal;
+ mLength = pOther.mLength;
+ mRadius = pOther.mRadius;
+
+ return *this;
+}
+
+void LLPathfindingCharacter::parseCharacterData(const LLSD &pCharacterData)
+{
+ llassert(pCharacterData.has(CHARACTER_CPU_TIME_FIELD));
+ llassert(pCharacterData.get(CHARACTER_CPU_TIME_FIELD).isReal());
+ mCPUTime = pCharacterData.get(CHARACTER_CPU_TIME_FIELD).asReal();
+
+ llassert(pCharacterData.has(CHARACTER_HORIZONTAL_FIELD));
+ llassert(pCharacterData.get(CHARACTER_HORIZONTAL_FIELD).isBoolean());
+ mIsHorizontal = pCharacterData.get(CHARACTER_HORIZONTAL_FIELD).asBoolean();
+
+ llassert(pCharacterData.has(CHARACTER_LENGTH_FIELD));
+ llassert(pCharacterData.get(CHARACTER_LENGTH_FIELD).isReal());
+ mLength = pCharacterData.get(CHARACTER_LENGTH_FIELD).asReal();
+
+ llassert(pCharacterData.has(CHARACTER_RADIUS_FIELD));
+ llassert(pCharacterData.get(CHARACTER_RADIUS_FIELD).isReal());
+ mRadius = pCharacterData.get(CHARACTER_RADIUS_FIELD).asReal();
+}
diff --git a/indra/newview/llpathfindingcharacter.h b/indra/newview/llpathfindingcharacter.h
new file mode 100755
index 0000000000..7cf9f401b0
--- /dev/null
+++ b/indra/newview/llpathfindingcharacter.h
@@ -0,0 +1,63 @@
+/**
+* @file llpathfindingcharacter.h
+* @brief Definition of a pathfinding character that contains various properties required for havok pathfinding.
+* @author Stinson@lindenlab.com
+*
+* $LicenseInfo:firstyear=2012&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2012, 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_LLPATHFINDINGCHARACTER_H
+#define LL_LLPATHFINDINGCHARACTER_H
+
+#include <string>
+
+#include "llpathfindingobject.h"
+
+class LLSD;
+
+class LLPathfindingCharacter : public LLPathfindingObject
+{
+public:
+ LLPathfindingCharacter(const std::string &pUUID, const LLSD &pCharacterData);
+ LLPathfindingCharacter(const LLPathfindingCharacter& pOther);
+ virtual ~LLPathfindingCharacter();
+
+ LLPathfindingCharacter& operator =(const LLPathfindingCharacter& pOther);
+
+ inline F32 getCPUTime() const {return mCPUTime;};
+
+ inline BOOL isHorizontal() const {return mIsHorizontal;};
+ inline F32 getLength() const {return mLength;};
+ inline F32 getRadius() const {return mRadius;};
+
+protected:
+
+private:
+ void parseCharacterData(const LLSD &pCharacterData);
+
+ F32 mCPUTime;
+
+ BOOL mIsHorizontal;
+ F32 mLength;
+ F32 mRadius;
+};
+
+#endif // LL_LLPATHFINDINGCHARACTER_H
diff --git a/indra/newview/llpathfindingcharacterlist.cpp b/indra/newview/llpathfindingcharacterlist.cpp
new file mode 100755
index 0000000000..12340cebfa
--- /dev/null
+++ b/indra/newview/llpathfindingcharacterlist.cpp
@@ -0,0 +1,69 @@
+/**
+* @file llpathfindingcharacterlist.cpp
+* @brief Implementation of llpathfindingcharacterlist
+* @author Stinson@lindenlab.com
+*
+* $LicenseInfo:firstyear=2012&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2012, 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 "llpathfindingcharacterlist.h"
+
+#include "llpathfindingcharacter.h"
+#include "llpathfindingobject.h"
+#include "llpathfindingobjectlist.h"
+#include "llsd.h"
+
+//---------------------------------------------------------------------------
+// LLPathfindingCharacterList
+//---------------------------------------------------------------------------
+
+LLPathfindingCharacterList::LLPathfindingCharacterList()
+ : LLPathfindingObjectList()
+{
+}
+
+LLPathfindingCharacterList::LLPathfindingCharacterList(const LLSD& pCharacterListData)
+ : LLPathfindingObjectList()
+{
+ parseCharacterListData(pCharacterListData);
+}
+
+LLPathfindingCharacterList::~LLPathfindingCharacterList()
+{
+}
+
+void LLPathfindingCharacterList::parseCharacterListData(const LLSD& pCharacterListData)
+{
+ LLPathfindingObjectMap &objectMap = getObjectMap();
+
+ for (LLSD::map_const_iterator characterDataIter = pCharacterListData.beginMap();
+ characterDataIter != pCharacterListData.endMap(); ++characterDataIter)
+ {
+ const std::string& uuid(characterDataIter->first);
+ const LLSD& characterData = characterDataIter->second;
+ LLPathfindingObjectPtr character(new LLPathfindingCharacter(uuid, characterData));
+ objectMap.insert(std::pair<std::string, LLPathfindingObjectPtr>(uuid, character));
+ }
+}
diff --git a/indra/newview/llpathfindingcharacterlist.h b/indra/newview/llpathfindingcharacterlist.h
new file mode 100755
index 0000000000..4ecf70001d
--- /dev/null
+++ b/indra/newview/llpathfindingcharacterlist.h
@@ -0,0 +1,47 @@
+/**
+* @file llpathfindingcharacterlist.h
+* @brief Header file for llpathfindingcharacterlist
+* @author Stinson@lindenlab.com
+*
+* $LicenseInfo:firstyear=2012&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2012, 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_LLPATHFINDINGCHARACTERLIST_H
+#define LL_LLPATHFINDINGCHARACTERLIST_H
+
+#include "llpathfindingobjectlist.h"
+
+class LLSD;
+
+class LLPathfindingCharacterList : public LLPathfindingObjectList
+{
+public:
+ LLPathfindingCharacterList();
+ LLPathfindingCharacterList(const LLSD& pCharacterListData);
+ virtual ~LLPathfindingCharacterList();
+
+protected:
+
+private:
+ void parseCharacterListData(const LLSD& pCharacterListData);
+};
+
+#endif // LL_LLPATHFINDINGCHARACTERLIST_H
diff --git a/indra/newview/llpathfindinglinkset.cpp b/indra/newview/llpathfindinglinkset.cpp
new file mode 100755
index 0000000000..50b76378f5
--- /dev/null
+++ b/indra/newview/llpathfindinglinkset.cpp
@@ -0,0 +1,408 @@
+/**
+* @file llpathfindinglinkset.cpp
+* @brief Definition of a pathfinding linkset that contains various properties required for havok pathfinding.
+* @author Stinson@lindenlab.com
+*
+* $LicenseInfo:firstyear=2012&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2012, 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 "llpathfindinglinkset.h"
+
+#include <string>
+
+#include "llpathfindingobject.h"
+#include "llsd.h"
+
+#define LINKSET_LAND_IMPACT_FIELD "landimpact"
+#define LINKSET_MODIFIABLE_FIELD "modifiable"
+#define LINKSET_CATEGORY_FIELD "navmesh_category"
+#define LINKSET_CAN_BE_VOLUME "can_be_volume"
+#define LINKSET_IS_SCRIPTED_FIELD "is_scripted"
+#define LINKSET_PHANTOM_FIELD "phantom"
+#define LINKSET_WALKABILITY_A_FIELD "A"
+#define LINKSET_WALKABILITY_B_FIELD "B"
+#define LINKSET_WALKABILITY_C_FIELD "C"
+#define LINKSET_WALKABILITY_D_FIELD "D"
+
+#define LINKSET_CATEGORY_VALUE_INCLUDE 0
+#define LINKSET_CATEGORY_VALUE_EXCLUDE 1
+#define LINKSET_CATEGORY_VALUE_IGNORE 2
+
+//---------------------------------------------------------------------------
+// LLPathfindingLinkset
+//---------------------------------------------------------------------------
+
+const S32 LLPathfindingLinkset::MIN_WALKABILITY_VALUE(0);
+const S32 LLPathfindingLinkset::MAX_WALKABILITY_VALUE(100);
+
+LLPathfindingLinkset::LLPathfindingLinkset(const LLSD& pTerrainData)
+ : LLPathfindingObject(),
+ mIsTerrain(true),
+ mLandImpact(0U),
+ mIsModifiable(FALSE),
+ mCanBeVolume(FALSE),
+ mIsScripted(FALSE),
+ mHasIsScripted(TRUE),
+ mLinksetUse(kUnknown),
+ mWalkabilityCoefficientA(MIN_WALKABILITY_VALUE),
+ mWalkabilityCoefficientB(MIN_WALKABILITY_VALUE),
+ mWalkabilityCoefficientC(MIN_WALKABILITY_VALUE),
+ mWalkabilityCoefficientD(MIN_WALKABILITY_VALUE)
+{
+ parsePathfindingData(pTerrainData);
+}
+
+LLPathfindingLinkset::LLPathfindingLinkset(const std::string &pUUID, const LLSD& pLinksetData)
+ : LLPathfindingObject(pUUID, pLinksetData),
+ mIsTerrain(false),
+ mLandImpact(0U),
+ mIsModifiable(TRUE),
+ mCanBeVolume(TRUE),
+ mIsScripted(FALSE),
+ mHasIsScripted(FALSE),
+ mLinksetUse(kUnknown),
+ mWalkabilityCoefficientA(MIN_WALKABILITY_VALUE),
+ mWalkabilityCoefficientB(MIN_WALKABILITY_VALUE),
+ mWalkabilityCoefficientC(MIN_WALKABILITY_VALUE),
+ mWalkabilityCoefficientD(MIN_WALKABILITY_VALUE)
+{
+ parseLinksetData(pLinksetData);
+ parsePathfindingData(pLinksetData);
+}
+
+LLPathfindingLinkset::LLPathfindingLinkset(const LLPathfindingLinkset& pOther)
+ : LLPathfindingObject(pOther),
+ mIsTerrain(pOther.mIsTerrain),
+ mLandImpact(pOther.mLandImpact),
+ mIsModifiable(pOther.mIsModifiable),
+ mCanBeVolume(pOther.mCanBeVolume),
+ mIsScripted(pOther.mIsScripted),
+ mHasIsScripted(pOther.mHasIsScripted),
+ mLinksetUse(pOther.mLinksetUse),
+ mWalkabilityCoefficientA(pOther.mWalkabilityCoefficientA),
+ mWalkabilityCoefficientB(pOther.mWalkabilityCoefficientB),
+ mWalkabilityCoefficientC(pOther.mWalkabilityCoefficientC),
+ mWalkabilityCoefficientD(pOther.mWalkabilityCoefficientD)
+{
+}
+
+LLPathfindingLinkset::~LLPathfindingLinkset()
+{
+}
+
+LLPathfindingLinkset& LLPathfindingLinkset::operator =(const LLPathfindingLinkset& pOther)
+{
+ dynamic_cast<LLPathfindingObject &>(*this) = pOther;
+
+ mIsTerrain = pOther.mIsTerrain;
+ mLandImpact = pOther.mLandImpact;
+ mIsModifiable = pOther.mIsModifiable;
+ mCanBeVolume = pOther.mCanBeVolume;
+ mIsScripted = pOther.mIsScripted;
+ mHasIsScripted = pOther.mHasIsScripted;
+ mLinksetUse = pOther.mLinksetUse;
+ mWalkabilityCoefficientA = pOther.mWalkabilityCoefficientA;
+ mWalkabilityCoefficientB = pOther.mWalkabilityCoefficientB;
+ mWalkabilityCoefficientC = pOther.mWalkabilityCoefficientC;
+ mWalkabilityCoefficientD = pOther.mWalkabilityCoefficientD;
+
+ return *this;
+}
+
+BOOL LLPathfindingLinkset::isPhantom() const
+{
+ return isPhantom(getLinksetUse());
+}
+
+LLPathfindingLinkset::ELinksetUse LLPathfindingLinkset::getLinksetUseWithToggledPhantom(ELinksetUse pLinksetUse)
+{
+ BOOL isPhantom = LLPathfindingLinkset::isPhantom(pLinksetUse);
+ ENavMeshGenerationCategory navMeshGenerationCategory = getNavMeshGenerationCategory(pLinksetUse);
+
+ return getLinksetUse(!isPhantom, navMeshGenerationCategory);
+}
+
+bool LLPathfindingLinkset::isShowUnmodifiablePhantomWarning(ELinksetUse pLinksetUse) const
+{
+ return (!isModifiable() && (isPhantom() != isPhantom(pLinksetUse)));
+}
+
+bool LLPathfindingLinkset::isShowPhantomToggleWarning(ELinksetUse pLinksetUse) const
+{
+ return (isModifiable() && (isPhantom() != isPhantom(pLinksetUse)));
+}
+
+bool LLPathfindingLinkset::isShowCannotBeVolumeWarning(ELinksetUse pLinksetUse) const
+{
+ return (!canBeVolume() && ((pLinksetUse == kMaterialVolume) || (pLinksetUse == kExclusionVolume)));
+}
+
+LLSD LLPathfindingLinkset::encodeAlteredFields(ELinksetUse pLinksetUse, S32 pA, S32 pB, S32 pC, S32 pD) const
+{
+ LLSD itemData;
+
+ if (!isTerrain() && (pLinksetUse != kUnknown) && (getLinksetUse() != pLinksetUse) &&
+ (canBeVolume() || ((pLinksetUse != kMaterialVolume) && (pLinksetUse != kExclusionVolume))))
+ {
+ if (isModifiable())
+ {
+ itemData[LINKSET_PHANTOM_FIELD] = static_cast<bool>(isPhantom(pLinksetUse));
+ }
+
+ itemData[LINKSET_CATEGORY_FIELD] = convertCategoryToLLSD(getNavMeshGenerationCategory(pLinksetUse));
+ }
+
+ if (mWalkabilityCoefficientA != pA)
+ {
+ itemData[LINKSET_WALKABILITY_A_FIELD] = llclamp(pA, MIN_WALKABILITY_VALUE, MAX_WALKABILITY_VALUE);
+ }
+
+ if (mWalkabilityCoefficientB != pB)
+ {
+ itemData[LINKSET_WALKABILITY_B_FIELD] = llclamp(pB, MIN_WALKABILITY_VALUE, MAX_WALKABILITY_VALUE);
+ }
+
+ if (mWalkabilityCoefficientC != pC)
+ {
+ itemData[LINKSET_WALKABILITY_C_FIELD] = llclamp(pC, MIN_WALKABILITY_VALUE, MAX_WALKABILITY_VALUE);
+ }
+
+ if (mWalkabilityCoefficientD != pD)
+ {
+ itemData[LINKSET_WALKABILITY_D_FIELD] = llclamp(pD, MIN_WALKABILITY_VALUE, MAX_WALKABILITY_VALUE);
+ }
+
+ return itemData;
+}
+
+void LLPathfindingLinkset::parseLinksetData(const LLSD &pLinksetData)
+{
+ llassert(pLinksetData.has(LINKSET_LAND_IMPACT_FIELD));
+ llassert(pLinksetData.get(LINKSET_LAND_IMPACT_FIELD).isInteger());
+ llassert(pLinksetData.get(LINKSET_LAND_IMPACT_FIELD).asInteger() >= 0);
+ mLandImpact = pLinksetData.get(LINKSET_LAND_IMPACT_FIELD).asInteger();
+
+ llassert(pLinksetData.has(LINKSET_MODIFIABLE_FIELD));
+ llassert(pLinksetData.get(LINKSET_MODIFIABLE_FIELD).isBoolean());
+ mIsModifiable = pLinksetData.get(LINKSET_MODIFIABLE_FIELD).asBoolean();
+
+ mHasIsScripted = pLinksetData.has(LINKSET_IS_SCRIPTED_FIELD);
+ if (mHasIsScripted)
+ {
+ llassert(pLinksetData.get(LINKSET_IS_SCRIPTED_FIELD).isBoolean());
+ mIsScripted = pLinksetData.get(LINKSET_IS_SCRIPTED_FIELD).asBoolean();
+ }
+}
+
+void LLPathfindingLinkset::parsePathfindingData(const LLSD &pLinksetData)
+{
+ bool isPhantom = false;
+ if (pLinksetData.has(LINKSET_PHANTOM_FIELD))
+ {
+ llassert(pLinksetData.get(LINKSET_PHANTOM_FIELD).isBoolean());
+ isPhantom = pLinksetData.get(LINKSET_PHANTOM_FIELD).asBoolean();
+ }
+
+ llassert(pLinksetData.has(LINKSET_CATEGORY_FIELD));
+ mLinksetUse = getLinksetUse(isPhantom, convertCategoryFromLLSD(pLinksetData.get(LINKSET_CATEGORY_FIELD)));
+
+ if (pLinksetData.has(LINKSET_CAN_BE_VOLUME))
+ {
+ llassert(pLinksetData.get(LINKSET_CAN_BE_VOLUME).isBoolean());
+ mCanBeVolume = pLinksetData.get(LINKSET_CAN_BE_VOLUME).asBoolean();
+ }
+
+ llassert(pLinksetData.has(LINKSET_WALKABILITY_A_FIELD));
+ llassert(pLinksetData.get(LINKSET_WALKABILITY_A_FIELD).isInteger());
+ mWalkabilityCoefficientA = pLinksetData.get(LINKSET_WALKABILITY_A_FIELD).asInteger();
+ llassert(mWalkabilityCoefficientA >= MIN_WALKABILITY_VALUE);
+ llassert(mWalkabilityCoefficientA <= MAX_WALKABILITY_VALUE);
+
+ llassert(pLinksetData.has(LINKSET_WALKABILITY_B_FIELD));
+ llassert(pLinksetData.get(LINKSET_WALKABILITY_B_FIELD).isInteger());
+ mWalkabilityCoefficientB = pLinksetData.get(LINKSET_WALKABILITY_B_FIELD).asInteger();
+ llassert(mWalkabilityCoefficientB >= MIN_WALKABILITY_VALUE);
+ llassert(mWalkabilityCoefficientB <= MAX_WALKABILITY_VALUE);
+
+ llassert(pLinksetData.has(LINKSET_WALKABILITY_C_FIELD));
+ llassert(pLinksetData.get(LINKSET_WALKABILITY_C_FIELD).isInteger());
+ mWalkabilityCoefficientC = pLinksetData.get(LINKSET_WALKABILITY_C_FIELD).asInteger();
+ llassert(mWalkabilityCoefficientC >= MIN_WALKABILITY_VALUE);
+ llassert(mWalkabilityCoefficientC <= MAX_WALKABILITY_VALUE);
+
+ llassert(pLinksetData.has(LINKSET_WALKABILITY_D_FIELD));
+ llassert(pLinksetData.get(LINKSET_WALKABILITY_D_FIELD).isInteger());
+ mWalkabilityCoefficientD = pLinksetData.get(LINKSET_WALKABILITY_D_FIELD).asInteger();
+ llassert(mWalkabilityCoefficientD >= MIN_WALKABILITY_VALUE);
+ llassert(mWalkabilityCoefficientD <= MAX_WALKABILITY_VALUE);
+}
+
+BOOL LLPathfindingLinkset::isPhantom(ELinksetUse pLinksetUse)
+{
+ BOOL retVal;
+
+ switch (pLinksetUse)
+ {
+ case kWalkable :
+ case kStaticObstacle :
+ case kDynamicObstacle :
+ retVal = false;
+ break;
+ case kMaterialVolume :
+ case kExclusionVolume :
+ case kDynamicPhantom :
+ retVal = true;
+ break;
+ case kUnknown :
+ default :
+ retVal = false;
+ llassert(0);
+ break;
+ }
+
+ return retVal;
+}
+
+LLPathfindingLinkset::ELinksetUse LLPathfindingLinkset::getLinksetUse(bool pIsPhantom, ENavMeshGenerationCategory pNavMeshGenerationCategory)
+{
+ ELinksetUse linksetUse = kUnknown;
+
+ if (pIsPhantom)
+ {
+ switch (pNavMeshGenerationCategory)
+ {
+ case kNavMeshGenerationIgnore :
+ linksetUse = kDynamicPhantom;
+ break;
+ case kNavMeshGenerationInclude :
+ linksetUse = kMaterialVolume;
+ break;
+ case kNavMeshGenerationExclude :
+ linksetUse = kExclusionVolume;
+ break;
+ default :
+ linksetUse = kUnknown;
+ llassert(0);
+ break;
+ }
+ }
+ else
+ {
+ switch (pNavMeshGenerationCategory)
+ {
+ case kNavMeshGenerationIgnore :
+ linksetUse = kDynamicObstacle;
+ break;
+ case kNavMeshGenerationInclude :
+ linksetUse = kWalkable;
+ break;
+ case kNavMeshGenerationExclude :
+ linksetUse = kStaticObstacle;
+ break;
+ default :
+ linksetUse = kUnknown;
+ llassert(0);
+ break;
+ }
+ }
+
+ return linksetUse;
+}
+
+LLPathfindingLinkset::ENavMeshGenerationCategory LLPathfindingLinkset::getNavMeshGenerationCategory(ELinksetUse pLinksetUse)
+{
+ ENavMeshGenerationCategory navMeshGenerationCategory;
+ switch (pLinksetUse)
+ {
+ case kWalkable :
+ case kMaterialVolume :
+ navMeshGenerationCategory = kNavMeshGenerationInclude;
+ break;
+ case kStaticObstacle :
+ case kExclusionVolume :
+ navMeshGenerationCategory = kNavMeshGenerationExclude;
+ break;
+ case kDynamicObstacle :
+ case kDynamicPhantom :
+ navMeshGenerationCategory = kNavMeshGenerationIgnore;
+ break;
+ case kUnknown :
+ default :
+ navMeshGenerationCategory = kNavMeshGenerationIgnore;
+ llassert(0);
+ break;
+ }
+
+ return navMeshGenerationCategory;
+}
+
+LLSD LLPathfindingLinkset::convertCategoryToLLSD(ENavMeshGenerationCategory pNavMeshGenerationCategory)
+{
+ LLSD llsd;
+
+ switch (pNavMeshGenerationCategory)
+ {
+ case kNavMeshGenerationIgnore :
+ llsd = static_cast<S32>(LINKSET_CATEGORY_VALUE_IGNORE);
+ break;
+ case kNavMeshGenerationInclude :
+ llsd = static_cast<S32>(LINKSET_CATEGORY_VALUE_INCLUDE);
+ break;
+ case kNavMeshGenerationExclude :
+ llsd = static_cast<S32>(LINKSET_CATEGORY_VALUE_EXCLUDE);
+ break;
+ default :
+ llsd = static_cast<S32>(LINKSET_CATEGORY_VALUE_IGNORE);
+ llassert(0);
+ break;
+ }
+
+ return llsd;
+}
+
+LLPathfindingLinkset::ENavMeshGenerationCategory LLPathfindingLinkset::convertCategoryFromLLSD(const LLSD &llsd)
+{
+ ENavMeshGenerationCategory navMeshGenerationCategory;
+
+ llassert(llsd.isInteger());
+ switch (llsd.asInteger())
+ {
+ case LINKSET_CATEGORY_VALUE_IGNORE :
+ navMeshGenerationCategory = kNavMeshGenerationIgnore;
+ break;
+ case LINKSET_CATEGORY_VALUE_INCLUDE :
+ navMeshGenerationCategory = kNavMeshGenerationInclude;
+ break;
+ case LINKSET_CATEGORY_VALUE_EXCLUDE :
+ navMeshGenerationCategory = kNavMeshGenerationExclude;
+ break;
+ default :
+ navMeshGenerationCategory = kNavMeshGenerationIgnore;
+ llassert(0);
+ break;
+ }
+
+ return navMeshGenerationCategory;
+}
diff --git a/indra/newview/llpathfindinglinkset.h b/indra/newview/llpathfindinglinkset.h
new file mode 100755
index 0000000000..308a3a1e0f
--- /dev/null
+++ b/indra/newview/llpathfindinglinkset.h
@@ -0,0 +1,114 @@
+/**
+* @file llpathfindinglinkset.h
+* @brief Definition of a pathfinding linkset that contains various properties required for havok pathfinding.
+* @author Stinson@lindenlab.com
+*
+* $LicenseInfo:firstyear=2012&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2012, 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_LLPATHFINDINGLINKSET_H
+#define LL_LLPATHFINDINGLINKSET_H
+
+#include <string>
+
+#include "llpathfindingobject.h"
+
+class LLSD;
+
+class LLPathfindingLinkset : public LLPathfindingObject
+{
+public:
+ typedef enum
+ {
+ kUnknown,
+ kWalkable,
+ kStaticObstacle,
+ kDynamicObstacle,
+ kMaterialVolume,
+ kExclusionVolume,
+ kDynamicPhantom
+ } ELinksetUse;
+
+ LLPathfindingLinkset(const LLSD &pTerrainData);
+ LLPathfindingLinkset(const std::string &pUUID, const LLSD &pLinksetData);
+ LLPathfindingLinkset(const LLPathfindingLinkset& pOther);
+ virtual ~LLPathfindingLinkset();
+
+ LLPathfindingLinkset& operator = (const LLPathfindingLinkset& pOther);
+
+ inline bool isTerrain() const {return mIsTerrain;};
+ inline U32 getLandImpact() const {return mLandImpact;};
+ BOOL isModifiable() const {return mIsModifiable;};
+ BOOL isPhantom() const;
+ BOOL canBeVolume() const {return mCanBeVolume;};
+ static ELinksetUse getLinksetUseWithToggledPhantom(ELinksetUse pLinksetUse);
+
+ inline ELinksetUse getLinksetUse() const {return mLinksetUse;};
+
+ inline BOOL isScripted() const {return mIsScripted;};
+ inline BOOL hasIsScripted() const {return mHasIsScripted;};
+
+ inline S32 getWalkabilityCoefficientA() const {return mWalkabilityCoefficientA;};
+ inline S32 getWalkabilityCoefficientB() const {return mWalkabilityCoefficientB;};
+ inline S32 getWalkabilityCoefficientC() const {return mWalkabilityCoefficientC;};
+ inline S32 getWalkabilityCoefficientD() const {return mWalkabilityCoefficientD;};
+
+ bool isShowUnmodifiablePhantomWarning(ELinksetUse pLinksetUse) const;
+ bool isShowPhantomToggleWarning(ELinksetUse pLinksetUse) const;
+ bool isShowCannotBeVolumeWarning(ELinksetUse pLinksetUse) const;
+ LLSD encodeAlteredFields(ELinksetUse pLinksetUse, S32 pA, S32 pB, S32 pC, S32 pD) const;
+
+ static const S32 MIN_WALKABILITY_VALUE;
+ static const S32 MAX_WALKABILITY_VALUE;
+
+protected:
+
+private:
+ typedef enum
+ {
+ kNavMeshGenerationIgnore,
+ kNavMeshGenerationInclude,
+ kNavMeshGenerationExclude
+ } ENavMeshGenerationCategory;
+
+ void parseLinksetData(const LLSD &pLinksetData);
+ void parsePathfindingData(const LLSD &pLinksetData);
+
+ static BOOL isPhantom(ELinksetUse pLinksetUse);
+ static ELinksetUse getLinksetUse(bool pIsPhantom, ENavMeshGenerationCategory pNavMeshGenerationCategory);
+ static ENavMeshGenerationCategory getNavMeshGenerationCategory(ELinksetUse pLinksetUse);
+ static LLSD convertCategoryToLLSD(ENavMeshGenerationCategory pNavMeshGenerationCategory);
+ static ENavMeshGenerationCategory convertCategoryFromLLSD(const LLSD &llsd);
+
+ bool mIsTerrain;
+ U32 mLandImpact;
+ BOOL mIsModifiable;
+ BOOL mCanBeVolume;
+ BOOL mIsScripted;
+ BOOL mHasIsScripted;
+ ELinksetUse mLinksetUse;
+ S32 mWalkabilityCoefficientA;
+ S32 mWalkabilityCoefficientB;
+ S32 mWalkabilityCoefficientC;
+ S32 mWalkabilityCoefficientD;
+};
+
+#endif // LL_LLPATHFINDINGLINKSET_H
diff --git a/indra/newview/llpathfindinglinksetlist.cpp b/indra/newview/llpathfindinglinksetlist.cpp
new file mode 100755
index 0000000000..b886e46765
--- /dev/null
+++ b/indra/newview/llpathfindinglinksetlist.cpp
@@ -0,0 +1,210 @@
+/**
+* @file llpathfindinglinksetlist.cpp
+* @brief Implementation of llpathfindinglinksetlist
+* @author Stinson@lindenlab.com
+*
+* $LicenseInfo:firstyear=2012&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2012, 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 "llpathfindinglinksetlist.h"
+
+#include <string>
+#include <map>
+
+#include "llpathfindinglinkset.h"
+#include "llpathfindingobject.h"
+#include "llpathfindingobjectlist.h"
+#include "llsd.h"
+
+//---------------------------------------------------------------------------
+// LLPathfindingLinksetList
+//---------------------------------------------------------------------------
+
+LLPathfindingLinksetList::LLPathfindingLinksetList()
+ : LLPathfindingObjectList()
+{
+}
+
+LLPathfindingLinksetList::LLPathfindingLinksetList(const LLSD& pLinksetListData)
+ : LLPathfindingObjectList()
+{
+ parseLinksetListData(pLinksetListData);
+}
+
+LLPathfindingLinksetList::~LLPathfindingLinksetList()
+{
+}
+
+LLSD LLPathfindingLinksetList::encodeObjectFields(LLPathfindingLinkset::ELinksetUse pLinksetUse, S32 pA, S32 pB, S32 pC, S32 pD) const
+{
+ LLSD listData;
+
+ for (const_iterator linksetIter = begin(); linksetIter != end(); ++linksetIter)
+ {
+ const LLPathfindingObjectPtr objectPtr = linksetIter->second;
+ const LLPathfindingLinkset *linkset = dynamic_cast<const LLPathfindingLinkset *>(objectPtr.get());
+
+ if (!linkset->isTerrain())
+ {
+ LLSD linksetData = linkset->encodeAlteredFields(pLinksetUse, pA, pB, pC, pD);
+ if (!linksetData.isUndefined())
+ {
+ const std::string& uuid(linksetIter->first);
+ listData[uuid] = linksetData;
+ }
+ }
+ }
+
+ return listData;
+}
+
+LLSD LLPathfindingLinksetList::encodeTerrainFields(LLPathfindingLinkset::ELinksetUse pLinksetUse, S32 pA, S32 pB, S32 pC, S32 pD) const
+{
+ LLSD terrainData;
+
+ for (const_iterator linksetIter = begin(); linksetIter != end(); ++linksetIter)
+ {
+ const LLPathfindingObjectPtr objectPtr = linksetIter->second;
+ const LLPathfindingLinkset *linkset = dynamic_cast<const LLPathfindingLinkset *>(objectPtr.get());
+
+ if (linkset->isTerrain())
+ {
+ terrainData = linkset->encodeAlteredFields(pLinksetUse, pA, pB, pC, pD);
+ break;
+ }
+ }
+
+ return terrainData;
+}
+
+bool LLPathfindingLinksetList::isShowUnmodifiablePhantomWarning(LLPathfindingLinkset::ELinksetUse pLinksetUse) const
+{
+ bool isShowWarning = false;
+
+ for (const_iterator objectIter = begin(); !isShowWarning && (objectIter != end()); ++objectIter)
+ {
+ const LLPathfindingObjectPtr objectPtr = objectIter->second;
+ const LLPathfindingLinkset *linkset = dynamic_cast<const LLPathfindingLinkset *>(objectPtr.get());
+ isShowWarning = linkset->isShowUnmodifiablePhantomWarning(pLinksetUse);
+ }
+
+ return isShowWarning;
+}
+
+bool LLPathfindingLinksetList::isShowPhantomToggleWarning(LLPathfindingLinkset::ELinksetUse pLinksetUse) const
+{
+ bool isShowWarning = false;
+
+ for (const_iterator objectIter = begin(); !isShowWarning && (objectIter != end()); ++objectIter)
+ {
+ const LLPathfindingObjectPtr objectPtr = objectIter->second;
+ const LLPathfindingLinkset *linkset = dynamic_cast<const LLPathfindingLinkset *>(objectPtr.get());
+ isShowWarning = linkset->isShowPhantomToggleWarning(pLinksetUse);
+ }
+
+ return isShowWarning;
+}
+
+bool LLPathfindingLinksetList::isShowCannotBeVolumeWarning(LLPathfindingLinkset::ELinksetUse pLinksetUse) const
+{
+ bool isShowWarning = false;
+
+ for (const_iterator objectIter = begin(); !isShowWarning && (objectIter != end()); ++objectIter)
+ {
+ const LLPathfindingObjectPtr objectPtr = objectIter->second;
+ const LLPathfindingLinkset *linkset = dynamic_cast<const LLPathfindingLinkset *>(objectPtr.get());
+ isShowWarning = linkset->isShowCannotBeVolumeWarning(pLinksetUse);
+ }
+
+ return isShowWarning;
+}
+
+void LLPathfindingLinksetList::determinePossibleStates(BOOL &pCanBeWalkable, BOOL &pCanBeStaticObstacle, BOOL &pCanBeDynamicObstacle,
+ BOOL &pCanBeMaterialVolume, BOOL &pCanBeExclusionVolume, BOOL &pCanBeDynamicPhantom) const
+{
+ pCanBeWalkable = FALSE;
+ pCanBeStaticObstacle = FALSE;
+ pCanBeDynamicObstacle = FALSE;
+ pCanBeMaterialVolume = FALSE;
+ pCanBeExclusionVolume = FALSE;
+ pCanBeDynamicPhantom = FALSE;
+
+ for (const_iterator objectIter = begin();
+ !(pCanBeWalkable && pCanBeStaticObstacle && pCanBeDynamicObstacle && pCanBeMaterialVolume && pCanBeExclusionVolume && pCanBeDynamicPhantom) && (objectIter != end());
+ ++objectIter)
+ {
+ const LLPathfindingObjectPtr objectPtr = objectIter->second;
+ const LLPathfindingLinkset *linkset = dynamic_cast<const LLPathfindingLinkset *>(objectPtr.get());
+
+ if (linkset->isTerrain())
+ {
+ pCanBeWalkable = TRUE;
+ }
+ else
+ {
+ if (linkset->isModifiable())
+ {
+ pCanBeWalkable = TRUE;
+ pCanBeStaticObstacle = TRUE;
+ pCanBeDynamicObstacle = TRUE;
+ pCanBeDynamicPhantom = TRUE;
+ if (linkset->canBeVolume())
+ {
+ pCanBeMaterialVolume = TRUE;
+ pCanBeExclusionVolume = TRUE;
+ }
+ }
+ else if (linkset->isPhantom())
+ {
+ pCanBeDynamicPhantom = TRUE;
+ if (linkset->canBeVolume())
+ {
+ pCanBeMaterialVolume = TRUE;
+ pCanBeExclusionVolume = TRUE;
+ }
+ }
+ else
+ {
+ pCanBeWalkable = TRUE;
+ pCanBeStaticObstacle = TRUE;
+ pCanBeDynamicObstacle = TRUE;
+ }
+ }
+ }
+}
+
+void LLPathfindingLinksetList::parseLinksetListData(const LLSD& pLinksetListData)
+{
+ LLPathfindingObjectMap &objectMap = getObjectMap();
+
+ for (LLSD::map_const_iterator linksetDataIter = pLinksetListData.beginMap();
+ linksetDataIter != pLinksetListData.endMap(); ++linksetDataIter)
+ {
+ const std::string& uuid(linksetDataIter->first);
+ const LLSD& linksetData = linksetDataIter->second;
+ LLPathfindingObjectPtr linksetPtr(new LLPathfindingLinkset(uuid, linksetData));
+ objectMap.insert(std::pair<std::string, LLPathfindingObjectPtr>(uuid, linksetPtr));
+ }
+}
diff --git a/indra/newview/llpathfindinglinksetlist.h b/indra/newview/llpathfindinglinksetlist.h
new file mode 100755
index 0000000000..1d38e4c11a
--- /dev/null
+++ b/indra/newview/llpathfindinglinksetlist.h
@@ -0,0 +1,58 @@
+/**
+* @file llpathfindinglinksetlist.h
+* @brief Header file for llpathfindinglinksetlist
+* @author Stinson@lindenlab.com
+*
+* $LicenseInfo:firstyear=2012&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2012, 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_LLPATHFINDINGLINKSETLIST_H
+#define LL_LLPATHFINDINGLINKSETLIST_H
+
+#include "llpathfindinglinkset.h"
+#include "llpathfindingobjectlist.h"
+
+class LLSD;
+
+class LLPathfindingLinksetList : public LLPathfindingObjectList
+{
+public:
+ LLPathfindingLinksetList();
+ LLPathfindingLinksetList(const LLSD& pLinksetListData);
+ virtual ~LLPathfindingLinksetList();
+
+ LLSD encodeObjectFields(LLPathfindingLinkset::ELinksetUse pLinksetUse, S32 pA, S32 pB, S32 pC, S32 pD) const;
+ LLSD encodeTerrainFields(LLPathfindingLinkset::ELinksetUse pLinksetUse, S32 pA, S32 pB, S32 pC, S32 pD) const;
+
+ bool isShowUnmodifiablePhantomWarning(LLPathfindingLinkset::ELinksetUse pLinksetUse) const;
+ bool isShowPhantomToggleWarning(LLPathfindingLinkset::ELinksetUse pLinksetUse) const;
+ bool isShowCannotBeVolumeWarning(LLPathfindingLinkset::ELinksetUse pLinksetUse) const;
+
+ void determinePossibleStates(BOOL &pCanBeWalkable, BOOL &pCanBeStaticObstacle, BOOL &pCanBeDynamicObstacle,
+ BOOL &pCanBeMaterialVolume, BOOL &pCanBeExclusionVolume, BOOL &pCanBeDynamicPhantom) const;
+
+protected:
+
+private:
+ void parseLinksetListData(const LLSD& pLinksetListData);
+};
+
+#endif // LL_LLPATHFINDINGLINKSETLIST_H
diff --git a/indra/newview/llpathfindingmanager.cpp b/indra/newview/llpathfindingmanager.cpp
new file mode 100755
index 0000000000..c277359133
--- /dev/null
+++ b/indra/newview/llpathfindingmanager.cpp
@@ -0,0 +1,1056 @@
+/**
+* @file llpathfindingmanager.cpp
+* @brief Implementation of llpathfindingmanager
+* @author Stinson@lindenlab.com
+*
+* $LicenseInfo:firstyear=2012&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2012, 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 "llpathfindingmanager.h"
+
+#include <string>
+#include <map>
+
+#include <boost/bind.hpp>
+#include <boost/function.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/signals2.hpp>
+
+#include "llagent.h"
+#include "llhttpclient.h"
+#include "llhttpnode.h"
+#include "llnotificationsutil.h"
+#include "llpathfindingcharacterlist.h"
+#include "llpathfindinglinkset.h"
+#include "llpathfindinglinksetlist.h"
+#include "llpathfindingnavmesh.h"
+#include "llpathfindingnavmeshstatus.h"
+#include "llpathfindingobject.h"
+#include "llpathinglib.h"
+#include "llsingleton.h"
+#include "llsd.h"
+#include "lltrans.h"
+#include "lluuid.h"
+#include "llviewerregion.h"
+#include "llweb.h"
+
+#define CAP_SERVICE_RETRIEVE_NAVMESH "RetrieveNavMeshSrc"
+
+#define CAP_SERVICE_NAVMESH_STATUS "NavMeshGenerationStatus"
+
+#define CAP_SERVICE_OBJECT_LINKSETS "ObjectNavMeshProperties"
+#define CAP_SERVICE_TERRAIN_LINKSETS "TerrainNavMeshProperties"
+
+#define CAP_SERVICE_CHARACTERS "CharacterProperties"
+
+#define SIM_MESSAGE_NAVMESH_STATUS_UPDATE "/message/NavMeshStatusUpdate"
+#define SIM_MESSAGE_AGENT_STATE_UPDATE "/message/AgentStateUpdate"
+#define SIM_MESSAGE_BODY_FIELD "body"
+
+#define CAP_SERVICE_AGENT_STATE "AgentState"
+
+#define AGENT_STATE_CAN_REBAKE_REGION_FIELD "can_modify_navmesh"
+
+//---------------------------------------------------------------------------
+// LLNavMeshSimStateChangeNode
+//---------------------------------------------------------------------------
+
+class LLNavMeshSimStateChangeNode : public LLHTTPNode
+{
+public:
+ virtual void post(ResponsePtr pResponse, const LLSD &pContext, const LLSD &pInput) const;
+};
+
+LLHTTPRegistration<LLNavMeshSimStateChangeNode> gHTTPRegistrationNavMeshSimStateChangeNode(SIM_MESSAGE_NAVMESH_STATUS_UPDATE);
+
+
+//---------------------------------------------------------------------------
+// LLAgentStateChangeNode
+//---------------------------------------------------------------------------
+class LLAgentStateChangeNode : public LLHTTPNode
+{
+public:
+ virtual void post(ResponsePtr pResponse, const LLSD &pContext, const LLSD &pInput) const;
+};
+
+LLHTTPRegistration<LLAgentStateChangeNode> gHTTPRegistrationAgentStateChangeNode(SIM_MESSAGE_AGENT_STATE_UPDATE);
+
+//---------------------------------------------------------------------------
+// NavMeshStatusResponder
+//---------------------------------------------------------------------------
+
+class NavMeshStatusResponder : public LLHTTPClient::Responder
+{
+public:
+ NavMeshStatusResponder(const std::string &pCapabilityURL, LLViewerRegion *pRegion, bool pIsGetStatusOnly);
+ virtual ~NavMeshStatusResponder();
+
+ virtual void result(const LLSD &pContent);
+ virtual void errorWithContent(U32 pStatus, const std::string& pReason, const LLSD& pContent);
+
+protected:
+
+private:
+ std::string mCapabilityURL;
+ LLViewerRegion *mRegion;
+ LLUUID mRegionUUID;
+ bool mIsGetStatusOnly;
+};
+
+//---------------------------------------------------------------------------
+// NavMeshResponder
+//---------------------------------------------------------------------------
+
+class NavMeshResponder : public LLHTTPClient::Responder
+{
+public:
+ NavMeshResponder(const std::string &pCapabilityURL, U32 pNavMeshVersion, LLPathfindingNavMeshPtr pNavMeshPtr);
+ virtual ~NavMeshResponder();
+
+ virtual void result(const LLSD &pContent);
+ virtual void errorWithContent(U32 pStatus, const std::string& pReason, const LLSD& pContent);
+
+protected:
+
+private:
+ std::string mCapabilityURL;
+ U32 mNavMeshVersion;
+ LLPathfindingNavMeshPtr mNavMeshPtr;
+};
+
+//---------------------------------------------------------------------------
+// AgentStateResponder
+//---------------------------------------------------------------------------
+
+class AgentStateResponder : public LLHTTPClient::Responder
+{
+public:
+ AgentStateResponder(const std::string &pCapabilityURL);
+ virtual ~AgentStateResponder();
+
+ virtual void result(const LLSD &pContent);
+ virtual void errorWithContent(U32 pStatus, const std::string& pReason, const LLSD& pContent);
+
+protected:
+
+private:
+ std::string mCapabilityURL;
+};
+
+
+//---------------------------------------------------------------------------
+// NavMeshRebakeResponder
+//---------------------------------------------------------------------------
+class NavMeshRebakeResponder : public LLHTTPClient::Responder
+{
+public:
+ NavMeshRebakeResponder(const std::string &pCapabilityURL, LLPathfindingManager::rebake_navmesh_callback_t pRebakeNavMeshCallback);
+ virtual ~NavMeshRebakeResponder();
+
+ virtual void result(const LLSD &pContent);
+ virtual void errorWithContent(U32 pStatus, const std::string& pReason, const LLSD& pContent);
+
+protected:
+
+private:
+ std::string mCapabilityURL;
+ LLPathfindingManager::rebake_navmesh_callback_t mRebakeNavMeshCallback;
+};
+
+//---------------------------------------------------------------------------
+// LinksetsResponder
+//---------------------------------------------------------------------------
+
+class LinksetsResponder
+{
+public:
+ LinksetsResponder(LLPathfindingManager::request_id_t pRequestId, LLPathfindingManager::object_request_callback_t pLinksetsCallback, bool pIsObjectRequested, bool pIsTerrainRequested);
+ virtual ~LinksetsResponder();
+
+ void handleObjectLinksetsResult(const LLSD &pContent);
+ void handleObjectLinksetsError(U32 pStatus, const std::string &pReason,
+ const LLSD& pContent, const std::string &pURL);
+ void handleTerrainLinksetsResult(const LLSD &pContent);
+ void handleTerrainLinksetsError(U32 pStatus, const std::string &pReason,
+ const LLSD& pContent, const std::string &pURL);
+
+protected:
+
+private:
+ void sendCallback();
+
+ typedef enum
+ {
+ kNotRequested,
+ kWaiting,
+ kReceivedGood,
+ kReceivedError
+ } EMessagingState;
+
+ LLPathfindingManager::request_id_t mRequestId;
+ LLPathfindingManager::object_request_callback_t mLinksetsCallback;
+
+ EMessagingState mObjectMessagingState;
+ EMessagingState mTerrainMessagingState;
+
+ LLPathfindingObjectListPtr mObjectLinksetListPtr;
+ LLPathfindingObjectPtr mTerrainLinksetPtr;
+};
+
+typedef boost::shared_ptr<LinksetsResponder> LinksetsResponderPtr;
+
+//---------------------------------------------------------------------------
+// ObjectLinksetsResponder
+//---------------------------------------------------------------------------
+
+class ObjectLinksetsResponder : public LLHTTPClient::Responder
+{
+public:
+ ObjectLinksetsResponder(const std::string &pCapabilityURL, LinksetsResponderPtr pLinksetsResponsderPtr);
+ virtual ~ObjectLinksetsResponder();
+
+ virtual void result(const LLSD &pContent);
+ virtual void errorWithContent(U32 pStatus, const std::string &pReason, const LLSD& pContent);
+
+protected:
+
+private:
+ std::string mCapabilityURL;
+ LinksetsResponderPtr mLinksetsResponsderPtr;
+};
+
+//---------------------------------------------------------------------------
+// TerrainLinksetsResponder
+//---------------------------------------------------------------------------
+
+class TerrainLinksetsResponder : public LLHTTPClient::Responder
+{
+public:
+ TerrainLinksetsResponder(const std::string &pCapabilityURL, LinksetsResponderPtr pLinksetsResponsderPtr);
+ virtual ~TerrainLinksetsResponder();
+
+ virtual void result(const LLSD &pContent);
+ virtual void errorWithContent(U32 pStatus, const std::string &pReason, const LLSD& pContent);
+
+protected:
+
+private:
+ std::string mCapabilityURL;
+ LinksetsResponderPtr mLinksetsResponsderPtr;
+};
+
+//---------------------------------------------------------------------------
+// CharactersResponder
+//---------------------------------------------------------------------------
+
+class CharactersResponder : public LLHTTPClient::Responder
+{
+public:
+ CharactersResponder(const std::string &pCapabilityURL, LLPathfindingManager::request_id_t pRequestId, LLPathfindingManager::object_request_callback_t pCharactersCallback);
+ virtual ~CharactersResponder();
+
+ virtual void result(const LLSD &pContent);
+ virtual void errorWithContent(U32 pStatus, const std::string &pReason, const LLSD& pContent);
+
+protected:
+
+private:
+ std::string mCapabilityURL;
+ LLPathfindingManager::request_id_t mRequestId;
+ LLPathfindingManager::object_request_callback_t mCharactersCallback;
+};
+
+//---------------------------------------------------------------------------
+// LLPathfindingManager
+//---------------------------------------------------------------------------
+
+LLPathfindingManager::LLPathfindingManager()
+ : LLSingleton<LLPathfindingManager>(),
+ mNavMeshMap(),
+ mAgentStateSignal()
+{
+}
+
+LLPathfindingManager::~LLPathfindingManager()
+{
+ quitSystem();
+}
+
+void LLPathfindingManager::initSystem()
+{
+ if (LLPathingLib::getInstance() == NULL)
+ {
+ LLPathingLib::initSystem();
+ }
+}
+
+void LLPathfindingManager::quitSystem()
+{
+ if (LLPathingLib::getInstance() != NULL)
+ {
+ LLPathingLib::quitSystem();
+ }
+}
+
+bool LLPathfindingManager::isPathfindingViewEnabled() const
+{
+ return (LLPathingLib::getInstance() != NULL);
+}
+
+bool LLPathfindingManager::isPathfindingEnabledForCurrentRegion() const
+{
+ return isPathfindingEnabledForRegion(getCurrentRegion());
+}
+
+bool LLPathfindingManager::isPathfindingEnabledForRegion(LLViewerRegion *pRegion) const
+{
+ std::string retrieveNavMeshURL = getRetrieveNavMeshURLForRegion(pRegion);
+ return !retrieveNavMeshURL.empty();
+}
+
+bool LLPathfindingManager::isAllowViewTerrainProperties() const
+{
+ LLViewerRegion* region = getCurrentRegion();
+ return (gAgent.isGodlike() || ((region != NULL) && region->canManageEstate()));
+}
+
+LLPathfindingNavMesh::navmesh_slot_t LLPathfindingManager::registerNavMeshListenerForRegion(LLViewerRegion *pRegion, LLPathfindingNavMesh::navmesh_callback_t pNavMeshCallback)
+{
+ LLPathfindingNavMeshPtr navMeshPtr = getNavMeshForRegion(pRegion);
+ return navMeshPtr->registerNavMeshListener(pNavMeshCallback);
+}
+
+void LLPathfindingManager::requestGetNavMeshForRegion(LLViewerRegion *pRegion, bool pIsGetStatusOnly)
+{
+ LLPathfindingNavMeshPtr navMeshPtr = getNavMeshForRegion(pRegion);
+
+ if (pRegion == NULL)
+ {
+ navMeshPtr->handleNavMeshNotEnabled();
+ }
+ else if (!pRegion->capabilitiesReceived())
+ {
+ navMeshPtr->handleNavMeshWaitForRegionLoad();
+ pRegion->setCapabilitiesReceivedCallback(boost::bind(&LLPathfindingManager::handleDeferredGetNavMeshForRegion, this, _1, pIsGetStatusOnly));
+ }
+ else if (!isPathfindingEnabledForRegion(pRegion))
+ {
+ navMeshPtr->handleNavMeshNotEnabled();
+ }
+ else
+ {
+ std::string navMeshStatusURL = getNavMeshStatusURLForRegion(pRegion);
+ llassert(!navMeshStatusURL.empty());
+ navMeshPtr->handleNavMeshCheckVersion();
+ LLHTTPClient::ResponderPtr navMeshStatusResponder = new NavMeshStatusResponder(navMeshStatusURL, pRegion, pIsGetStatusOnly);
+ LLHTTPClient::get(navMeshStatusURL, navMeshStatusResponder);
+ }
+}
+
+void LLPathfindingManager::requestGetLinksets(request_id_t pRequestId, object_request_callback_t pLinksetsCallback) const
+{
+ LLPathfindingObjectListPtr emptyLinksetListPtr;
+ LLViewerRegion *currentRegion = getCurrentRegion();
+
+ if (currentRegion == NULL)
+ {
+ pLinksetsCallback(pRequestId, kRequestNotEnabled, emptyLinksetListPtr);
+ }
+ else if (!currentRegion->capabilitiesReceived())
+ {
+ pLinksetsCallback(pRequestId, kRequestStarted, emptyLinksetListPtr);
+ currentRegion->setCapabilitiesReceivedCallback(boost::bind(&LLPathfindingManager::handleDeferredGetLinksetsForRegion, this, _1, pRequestId, pLinksetsCallback));
+ }
+ else
+ {
+ std::string objectLinksetsURL = getObjectLinksetsURLForCurrentRegion();
+ std::string terrainLinksetsURL = getTerrainLinksetsURLForCurrentRegion();
+ if (objectLinksetsURL.empty() || terrainLinksetsURL.empty())
+ {
+ pLinksetsCallback(pRequestId, kRequestNotEnabled, emptyLinksetListPtr);
+ }
+ else
+ {
+ pLinksetsCallback(pRequestId, kRequestStarted, emptyLinksetListPtr);
+
+ bool doRequestTerrain = isAllowViewTerrainProperties();
+ LinksetsResponderPtr linksetsResponderPtr(new LinksetsResponder(pRequestId, pLinksetsCallback, true, doRequestTerrain));
+
+ LLHTTPClient::ResponderPtr objectLinksetsResponder = new ObjectLinksetsResponder(objectLinksetsURL, linksetsResponderPtr);
+ LLHTTPClient::get(objectLinksetsURL, objectLinksetsResponder);
+
+ if (doRequestTerrain)
+ {
+ LLHTTPClient::ResponderPtr terrainLinksetsResponder = new TerrainLinksetsResponder(terrainLinksetsURL, linksetsResponderPtr);
+ LLHTTPClient::get(terrainLinksetsURL, terrainLinksetsResponder);
+ }
+ }
+ }
+}
+
+void LLPathfindingManager::requestSetLinksets(request_id_t pRequestId, const LLPathfindingObjectListPtr &pLinksetListPtr, LLPathfindingLinkset::ELinksetUse pLinksetUse, S32 pA, S32 pB, S32 pC, S32 pD, object_request_callback_t pLinksetsCallback) const
+{
+ LLPathfindingObjectListPtr emptyLinksetListPtr;
+
+ std::string objectLinksetsURL = getObjectLinksetsURLForCurrentRegion();
+ std::string terrainLinksetsURL = getTerrainLinksetsURLForCurrentRegion();
+ if (objectLinksetsURL.empty() || terrainLinksetsURL.empty())
+ {
+ pLinksetsCallback(pRequestId, kRequestNotEnabled, emptyLinksetListPtr);
+ }
+ else if ((pLinksetListPtr == NULL) || pLinksetListPtr->isEmpty())
+ {
+ pLinksetsCallback(pRequestId, kRequestCompleted, emptyLinksetListPtr);
+ }
+ else
+ {
+ const LLPathfindingLinksetList *linksetList = dynamic_cast<const LLPathfindingLinksetList *>(pLinksetListPtr.get());
+
+ LLSD objectPostData = linksetList->encodeObjectFields(pLinksetUse, pA, pB, pC, pD);
+ LLSD terrainPostData;
+ if (isAllowViewTerrainProperties())
+ {
+ terrainPostData = linksetList->encodeTerrainFields(pLinksetUse, pA, pB, pC, pD);
+ }
+
+ if (objectPostData.isUndefined() && terrainPostData.isUndefined())
+ {
+ pLinksetsCallback(pRequestId, kRequestCompleted, emptyLinksetListPtr);
+ }
+ else
+ {
+ pLinksetsCallback(pRequestId, kRequestStarted, emptyLinksetListPtr);
+
+ LinksetsResponderPtr linksetsResponderPtr(new LinksetsResponder(pRequestId, pLinksetsCallback, !objectPostData.isUndefined(), !terrainPostData.isUndefined()));
+
+ if (!objectPostData.isUndefined())
+ {
+ LLHTTPClient::ResponderPtr objectLinksetsResponder = new ObjectLinksetsResponder(objectLinksetsURL, linksetsResponderPtr);
+ LLHTTPClient::put(objectLinksetsURL, objectPostData, objectLinksetsResponder);
+ }
+
+ if (!terrainPostData.isUndefined())
+ {
+ LLHTTPClient::ResponderPtr terrainLinksetsResponder = new TerrainLinksetsResponder(terrainLinksetsURL, linksetsResponderPtr);
+ LLHTTPClient::put(terrainLinksetsURL, terrainPostData, terrainLinksetsResponder);
+ }
+ }
+ }
+}
+
+void LLPathfindingManager::requestGetCharacters(request_id_t pRequestId, object_request_callback_t pCharactersCallback) const
+{
+ LLPathfindingObjectListPtr emptyCharacterListPtr;
+
+ LLViewerRegion *currentRegion = getCurrentRegion();
+
+ if (currentRegion == NULL)
+ {
+ pCharactersCallback(pRequestId, kRequestNotEnabled, emptyCharacterListPtr);
+ }
+ else if (!currentRegion->capabilitiesReceived())
+ {
+ pCharactersCallback(pRequestId, kRequestStarted, emptyCharacterListPtr);
+ currentRegion->setCapabilitiesReceivedCallback(boost::bind(&LLPathfindingManager::handleDeferredGetCharactersForRegion, this, _1, pRequestId, pCharactersCallback));
+ }
+ else
+ {
+ std::string charactersURL = getCharactersURLForCurrentRegion();
+ if (charactersURL.empty())
+ {
+ pCharactersCallback(pRequestId, kRequestNotEnabled, emptyCharacterListPtr);
+ }
+ else
+ {
+ pCharactersCallback(pRequestId, kRequestStarted, emptyCharacterListPtr);
+
+ LLHTTPClient::ResponderPtr charactersResponder = new CharactersResponder(charactersURL, pRequestId, pCharactersCallback);
+ LLHTTPClient::get(charactersURL, charactersResponder);
+ }
+ }
+}
+
+LLPathfindingManager::agent_state_slot_t LLPathfindingManager::registerAgentStateListener(agent_state_callback_t pAgentStateCallback)
+{
+ return mAgentStateSignal.connect(pAgentStateCallback);
+}
+
+void LLPathfindingManager::requestGetAgentState()
+{
+ LLViewerRegion *currentRegion = getCurrentRegion();
+
+ if (currentRegion == NULL)
+ {
+ mAgentStateSignal(FALSE);
+ }
+ else
+ {
+ if (!currentRegion->capabilitiesReceived())
+ {
+ currentRegion->setCapabilitiesReceivedCallback(boost::bind(&LLPathfindingManager::handleDeferredGetAgentStateForRegion, this, _1));
+ }
+ else if (!isPathfindingEnabledForRegion(currentRegion))
+ {
+ mAgentStateSignal(FALSE);
+ }
+ else
+ {
+ std::string agentStateURL = getAgentStateURLForRegion(currentRegion);
+ llassert(!agentStateURL.empty());
+ LLHTTPClient::ResponderPtr responder = new AgentStateResponder(agentStateURL);
+ LLHTTPClient::get(agentStateURL, responder);
+ }
+ }
+}
+
+void LLPathfindingManager::requestRebakeNavMesh(rebake_navmesh_callback_t pRebakeNavMeshCallback)
+{
+ LLViewerRegion *currentRegion = getCurrentRegion();
+
+ if (currentRegion == NULL)
+ {
+ pRebakeNavMeshCallback(false);
+ }
+ else if (!isPathfindingEnabledForRegion(currentRegion))
+ {
+ pRebakeNavMeshCallback(false);
+ }
+ else
+ {
+ std::string navMeshStatusURL = getNavMeshStatusURLForCurrentRegion();
+ llassert(!navMeshStatusURL.empty());
+ LLSD postData;
+ postData["command"] = "rebuild";
+ LLHTTPClient::ResponderPtr responder = new NavMeshRebakeResponder(navMeshStatusURL, pRebakeNavMeshCallback);
+ LLHTTPClient::post(navMeshStatusURL, postData, responder);
+ }
+}
+
+void LLPathfindingManager::sendRequestGetNavMeshForRegion(LLPathfindingNavMeshPtr navMeshPtr, LLViewerRegion *pRegion, const LLPathfindingNavMeshStatus &pNavMeshStatus)
+{
+ if ((pRegion == NULL) || !pRegion->isAlive())
+ {
+ navMeshPtr->handleNavMeshNotEnabled();
+ }
+ else
+ {
+ std::string navMeshURL = getRetrieveNavMeshURLForRegion(pRegion);
+
+ if (navMeshURL.empty())
+ {
+ navMeshPtr->handleNavMeshNotEnabled();
+ }
+ else
+ {
+ navMeshPtr->handleNavMeshStart(pNavMeshStatus);
+ LLHTTPClient::ResponderPtr responder = new NavMeshResponder(navMeshURL, pNavMeshStatus.getVersion(), navMeshPtr);
+
+ LLSD postData;
+ LLHTTPClient::post(navMeshURL, postData, responder);
+ }
+ }
+}
+
+void LLPathfindingManager::handleDeferredGetAgentStateForRegion(const LLUUID &pRegionUUID)
+{
+ LLViewerRegion *currentRegion = getCurrentRegion();
+
+ if ((currentRegion != NULL) && (currentRegion->getRegionID() == pRegionUUID))
+ {
+ requestGetAgentState();
+ }
+}
+
+void LLPathfindingManager::handleDeferredGetNavMeshForRegion(const LLUUID &pRegionUUID, bool pIsGetStatusOnly)
+{
+ LLViewerRegion *currentRegion = getCurrentRegion();
+
+ if ((currentRegion != NULL) && (currentRegion->getRegionID() == pRegionUUID))
+ {
+ requestGetNavMeshForRegion(currentRegion, pIsGetStatusOnly);
+ }
+}
+
+void LLPathfindingManager::handleDeferredGetLinksetsForRegion(const LLUUID &pRegionUUID, request_id_t pRequestId, object_request_callback_t pLinksetsCallback) const
+{
+ LLViewerRegion *currentRegion = getCurrentRegion();
+
+ if ((currentRegion != NULL) && (currentRegion->getRegionID() == pRegionUUID))
+ {
+ requestGetLinksets(pRequestId, pLinksetsCallback);
+ }
+}
+
+void LLPathfindingManager::handleDeferredGetCharactersForRegion(const LLUUID &pRegionUUID, request_id_t pRequestId, object_request_callback_t pCharactersCallback) const
+{
+ LLViewerRegion *currentRegion = getCurrentRegion();
+
+ if ((currentRegion != NULL) && (currentRegion->getRegionID() == pRegionUUID))
+ {
+ requestGetCharacters(pRequestId, pCharactersCallback);
+ }
+}
+
+void LLPathfindingManager::handleNavMeshStatusRequest(const LLPathfindingNavMeshStatus &pNavMeshStatus, LLViewerRegion *pRegion, bool pIsGetStatusOnly)
+{
+ LLPathfindingNavMeshPtr navMeshPtr = getNavMeshForRegion(pNavMeshStatus.getRegionUUID());
+
+ if (!pNavMeshStatus.isValid())
+ {
+ navMeshPtr->handleNavMeshError();
+ }
+ else
+ {
+ if (navMeshPtr->hasNavMeshVersion(pNavMeshStatus))
+ {
+ navMeshPtr->handleRefresh(pNavMeshStatus);
+ }
+ else if (pIsGetStatusOnly)
+ {
+ navMeshPtr->handleNavMeshNewVersion(pNavMeshStatus);
+ }
+ else
+ {
+ sendRequestGetNavMeshForRegion(navMeshPtr, pRegion, pNavMeshStatus);
+ }
+ }
+}
+
+void LLPathfindingManager::handleNavMeshStatusUpdate(const LLPathfindingNavMeshStatus &pNavMeshStatus)
+{
+ LLPathfindingNavMeshPtr navMeshPtr = getNavMeshForRegion(pNavMeshStatus.getRegionUUID());
+
+ if (!pNavMeshStatus.isValid())
+ {
+ navMeshPtr->handleNavMeshError();
+ }
+ else
+ {
+ navMeshPtr->handleNavMeshNewVersion(pNavMeshStatus);
+ }
+}
+
+void LLPathfindingManager::handleAgentState(BOOL pCanRebakeRegion)
+{
+ mAgentStateSignal(pCanRebakeRegion);
+}
+
+LLPathfindingNavMeshPtr LLPathfindingManager::getNavMeshForRegion(const LLUUID &pRegionUUID)
+{
+ LLPathfindingNavMeshPtr navMeshPtr;
+ NavMeshMap::iterator navMeshIter = mNavMeshMap.find(pRegionUUID);
+ if (navMeshIter == mNavMeshMap.end())
+ {
+ navMeshPtr = LLPathfindingNavMeshPtr(new LLPathfindingNavMesh(pRegionUUID));
+ mNavMeshMap.insert(std::pair<LLUUID, LLPathfindingNavMeshPtr>(pRegionUUID, navMeshPtr));
+ }
+ else
+ {
+ navMeshPtr = navMeshIter->second;
+ }
+
+ return navMeshPtr;
+}
+
+LLPathfindingNavMeshPtr LLPathfindingManager::getNavMeshForRegion(LLViewerRegion *pRegion)
+{
+ LLUUID regionUUID;
+ if (pRegion != NULL)
+ {
+ regionUUID = pRegion->getRegionID();
+ }
+
+ return getNavMeshForRegion(regionUUID);
+}
+
+std::string LLPathfindingManager::getNavMeshStatusURLForCurrentRegion() const
+{
+ return getNavMeshStatusURLForRegion(getCurrentRegion());
+}
+
+std::string LLPathfindingManager::getNavMeshStatusURLForRegion(LLViewerRegion *pRegion) const
+{
+ return getCapabilityURLForRegion(pRegion, CAP_SERVICE_NAVMESH_STATUS);
+}
+
+std::string LLPathfindingManager::getRetrieveNavMeshURLForRegion(LLViewerRegion *pRegion) const
+{
+ return getCapabilityURLForRegion(pRegion, CAP_SERVICE_RETRIEVE_NAVMESH);
+}
+
+std::string LLPathfindingManager::getObjectLinksetsURLForCurrentRegion() const
+{
+ return getCapabilityURLForCurrentRegion(CAP_SERVICE_OBJECT_LINKSETS);
+}
+
+std::string LLPathfindingManager::getTerrainLinksetsURLForCurrentRegion() const
+{
+ return getCapabilityURLForCurrentRegion(CAP_SERVICE_TERRAIN_LINKSETS);
+}
+
+std::string LLPathfindingManager::getCharactersURLForCurrentRegion() const
+{
+ return getCapabilityURLForCurrentRegion(CAP_SERVICE_CHARACTERS);
+}
+
+std::string LLPathfindingManager::getAgentStateURLForRegion(LLViewerRegion *pRegion) const
+{
+ return getCapabilityURLForRegion(pRegion, CAP_SERVICE_AGENT_STATE);
+}
+
+std::string LLPathfindingManager::getCapabilityURLForCurrentRegion(const std::string &pCapabilityName) const
+{
+ return getCapabilityURLForRegion(getCurrentRegion(), pCapabilityName);
+}
+
+std::string LLPathfindingManager::getCapabilityURLForRegion(LLViewerRegion *pRegion, const std::string &pCapabilityName) const
+{
+ std::string capabilityURL("");
+
+ if (pRegion != NULL)
+ {
+ capabilityURL = pRegion->getCapability(pCapabilityName);
+ }
+
+ if (capabilityURL.empty())
+ {
+ llwarns << "cannot find capability '" << pCapabilityName << "' for current region '"
+ << ((pRegion != NULL) ? pRegion->getName() : "<null>") << "'" << llendl;
+ }
+
+ return capabilityURL;
+}
+
+LLViewerRegion *LLPathfindingManager::getCurrentRegion() const
+{
+ return gAgent.getRegion();
+}
+
+//---------------------------------------------------------------------------
+// LLNavMeshSimStateChangeNode
+//---------------------------------------------------------------------------
+
+void LLNavMeshSimStateChangeNode::post(ResponsePtr pResponse, const LLSD &pContext, const LLSD &pInput) const
+{
+ llassert(pInput.has(SIM_MESSAGE_BODY_FIELD));
+ llassert(pInput.get(SIM_MESSAGE_BODY_FIELD).isMap());
+ LLPathfindingNavMeshStatus navMeshStatus(pInput.get(SIM_MESSAGE_BODY_FIELD));
+ LLPathfindingManager::getInstance()->handleNavMeshStatusUpdate(navMeshStatus);
+}
+
+//---------------------------------------------------------------------------
+// LLAgentStateChangeNode
+//---------------------------------------------------------------------------
+
+void LLAgentStateChangeNode::post(ResponsePtr pResponse, const LLSD &pContext, const LLSD &pInput) const
+{
+ llassert(pInput.has(SIM_MESSAGE_BODY_FIELD));
+ llassert(pInput.get(SIM_MESSAGE_BODY_FIELD).isMap());
+ llassert(pInput.get(SIM_MESSAGE_BODY_FIELD).has(AGENT_STATE_CAN_REBAKE_REGION_FIELD));
+ llassert(pInput.get(SIM_MESSAGE_BODY_FIELD).get(AGENT_STATE_CAN_REBAKE_REGION_FIELD).isBoolean());
+ BOOL canRebakeRegion = pInput.get(SIM_MESSAGE_BODY_FIELD).get(AGENT_STATE_CAN_REBAKE_REGION_FIELD).asBoolean();
+
+ LLPathfindingManager::getInstance()->handleAgentState(canRebakeRegion);
+}
+
+//---------------------------------------------------------------------------
+// NavMeshStatusResponder
+//---------------------------------------------------------------------------
+
+NavMeshStatusResponder::NavMeshStatusResponder(const std::string &pCapabilityURL, LLViewerRegion *pRegion, bool pIsGetStatusOnly)
+ : LLHTTPClient::Responder(),
+ mCapabilityURL(pCapabilityURL),
+ mRegion(pRegion),
+ mRegionUUID(),
+ mIsGetStatusOnly(pIsGetStatusOnly)
+{
+ if (mRegion != NULL)
+ {
+ mRegionUUID = mRegion->getRegionID();
+ }
+}
+
+NavMeshStatusResponder::~NavMeshStatusResponder()
+{
+}
+
+void NavMeshStatusResponder::result(const LLSD &pContent)
+{
+ LLPathfindingNavMeshStatus navMeshStatus(mRegionUUID, pContent);
+ LLPathfindingManager::getInstance()->handleNavMeshStatusRequest(navMeshStatus, mRegion, mIsGetStatusOnly);
+}
+
+void NavMeshStatusResponder::errorWithContent(U32 pStatus, const std::string& pReason, const LLSD& pContent)
+{
+ llwarns << "NavMeshStatusResponder error [status:" << pStatus << "]: " << pContent << llendl;
+ LLPathfindingNavMeshStatus navMeshStatus(mRegionUUID);
+ LLPathfindingManager::getInstance()->handleNavMeshStatusRequest(navMeshStatus, mRegion, mIsGetStatusOnly);
+}
+
+//---------------------------------------------------------------------------
+// NavMeshResponder
+//---------------------------------------------------------------------------
+
+NavMeshResponder::NavMeshResponder(const std::string &pCapabilityURL, U32 pNavMeshVersion, LLPathfindingNavMeshPtr pNavMeshPtr)
+ : LLHTTPClient::Responder(),
+ mCapabilityURL(pCapabilityURL),
+ mNavMeshVersion(pNavMeshVersion),
+ mNavMeshPtr(pNavMeshPtr)
+{
+}
+
+NavMeshResponder::~NavMeshResponder()
+{
+}
+
+void NavMeshResponder::result(const LLSD &pContent)
+{
+ mNavMeshPtr->handleNavMeshResult(pContent, mNavMeshVersion);
+}
+
+void NavMeshResponder::errorWithContent(U32 pStatus, const std::string& pReason, const LLSD& pContent)
+{
+ mNavMeshPtr->handleNavMeshError(pStatus, pReason, pContent, mCapabilityURL, mNavMeshVersion);
+}
+
+//---------------------------------------------------------------------------
+// AgentStateResponder
+//---------------------------------------------------------------------------
+
+AgentStateResponder::AgentStateResponder(const std::string &pCapabilityURL)
+: LLHTTPClient::Responder()
+, mCapabilityURL(pCapabilityURL)
+{
+}
+
+AgentStateResponder::~AgentStateResponder()
+{
+}
+
+void AgentStateResponder::result(const LLSD &pContent)
+{
+ llassert(pContent.has(AGENT_STATE_CAN_REBAKE_REGION_FIELD));
+ llassert(pContent.get(AGENT_STATE_CAN_REBAKE_REGION_FIELD).isBoolean());
+ BOOL canRebakeRegion = pContent.get(AGENT_STATE_CAN_REBAKE_REGION_FIELD).asBoolean();
+ LLPathfindingManager::getInstance()->handleAgentState(canRebakeRegion);
+}
+
+void AgentStateResponder::errorWithContent(U32 pStatus, const std::string &pReason, const LLSD& pContent)
+{
+ llwarns << "AgentStateResponder error [status:" << pStatus << "]: " << pContent << llendl;
+ LLPathfindingManager::getInstance()->handleAgentState(FALSE);
+}
+
+
+//---------------------------------------------------------------------------
+// navmesh rebake responder
+//---------------------------------------------------------------------------
+NavMeshRebakeResponder::NavMeshRebakeResponder(const std::string &pCapabilityURL, LLPathfindingManager::rebake_navmesh_callback_t pRebakeNavMeshCallback)
+ : LLHTTPClient::Responder(),
+ mCapabilityURL(pCapabilityURL),
+ mRebakeNavMeshCallback(pRebakeNavMeshCallback)
+{
+}
+
+NavMeshRebakeResponder::~NavMeshRebakeResponder()
+{
+}
+
+void NavMeshRebakeResponder::result(const LLSD &pContent)
+{
+ mRebakeNavMeshCallback(true);
+}
+
+void NavMeshRebakeResponder::errorWithContent(U32 pStatus, const std::string &pReason, const LLSD& pContent)
+{
+ llwarns << "NavMeshRebakeResponder error [status:" << pStatus << "]: " << pContent << llendl;
+ mRebakeNavMeshCallback(false);
+}
+
+//---------------------------------------------------------------------------
+// LinksetsResponder
+//---------------------------------------------------------------------------
+
+LinksetsResponder::LinksetsResponder(LLPathfindingManager::request_id_t pRequestId, LLPathfindingManager::object_request_callback_t pLinksetsCallback, bool pIsObjectRequested, bool pIsTerrainRequested)
+ : mRequestId(pRequestId),
+ mLinksetsCallback(pLinksetsCallback),
+ mObjectMessagingState(pIsObjectRequested ? kWaiting : kNotRequested),
+ mTerrainMessagingState(pIsTerrainRequested ? kWaiting : kNotRequested),
+ mObjectLinksetListPtr(),
+ mTerrainLinksetPtr()
+{
+}
+
+LinksetsResponder::~LinksetsResponder()
+{
+}
+
+void LinksetsResponder::handleObjectLinksetsResult(const LLSD &pContent)
+{
+ mObjectLinksetListPtr = LLPathfindingObjectListPtr(new LLPathfindingLinksetList(pContent));
+
+ mObjectMessagingState = kReceivedGood;
+ if (mTerrainMessagingState != kWaiting)
+ {
+ sendCallback();
+ }
+}
+
+void LinksetsResponder::handleObjectLinksetsError(U32 pStatus, const std::string &pReason,
+ const LLSD& pContent, const std::string &pURL)
+{
+ llwarns << "LinksetsResponder object linksets error with request to URL '" << pURL << "' [status:"
+ << pStatus << "]: " << pContent << llendl;
+ mObjectMessagingState = kReceivedError;
+ if (mTerrainMessagingState != kWaiting)
+ {
+ sendCallback();
+ }
+}
+
+void LinksetsResponder::handleTerrainLinksetsResult(const LLSD &pContent)
+{
+ mTerrainLinksetPtr = LLPathfindingObjectPtr(new LLPathfindingLinkset(pContent));
+
+ mTerrainMessagingState = kReceivedGood;
+ if (mObjectMessagingState != kWaiting)
+ {
+ sendCallback();
+ }
+}
+
+void LinksetsResponder::handleTerrainLinksetsError(U32 pStatus, const std::string &pReason,
+ const LLSD& pContent, const std::string &pURL)
+{
+ llwarns << "LinksetsResponder terrain linksets error with request to URL '" << pURL << "' [status:"
+ << pStatus << "]: " << pContent << llendl;
+ mTerrainMessagingState = kReceivedError;
+ if (mObjectMessagingState != kWaiting)
+ {
+ sendCallback();
+ }
+}
+
+void LinksetsResponder::sendCallback()
+{
+ llassert(mObjectMessagingState != kWaiting);
+ llassert(mTerrainMessagingState != kWaiting);
+ LLPathfindingManager::ERequestStatus requestStatus =
+ ((((mObjectMessagingState == kReceivedGood) || (mObjectMessagingState == kNotRequested)) &&
+ ((mTerrainMessagingState == kReceivedGood) || (mTerrainMessagingState == kNotRequested))) ?
+ LLPathfindingManager::kRequestCompleted : LLPathfindingManager::kRequestError);
+
+ if (mObjectMessagingState != kReceivedGood)
+ {
+ mObjectLinksetListPtr = LLPathfindingObjectListPtr(new LLPathfindingLinksetList());
+ }
+
+ if (mTerrainMessagingState == kReceivedGood)
+ {
+ mObjectLinksetListPtr->update(mTerrainLinksetPtr);
+ }
+
+ mLinksetsCallback(mRequestId, requestStatus, mObjectLinksetListPtr);
+}
+
+//---------------------------------------------------------------------------
+// ObjectLinksetsResponder
+//---------------------------------------------------------------------------
+
+ObjectLinksetsResponder::ObjectLinksetsResponder(const std::string &pCapabilityURL, LinksetsResponderPtr pLinksetsResponsderPtr)
+ : LLHTTPClient::Responder(),
+ mCapabilityURL(pCapabilityURL),
+ mLinksetsResponsderPtr(pLinksetsResponsderPtr)
+{
+}
+
+ObjectLinksetsResponder::~ObjectLinksetsResponder()
+{
+}
+
+void ObjectLinksetsResponder::result(const LLSD &pContent)
+{
+ mLinksetsResponsderPtr->handleObjectLinksetsResult(pContent);
+}
+
+void ObjectLinksetsResponder::errorWithContent(U32 pStatus, const std::string &pReason, const LLSD& pContent)
+{
+ mLinksetsResponsderPtr->handleObjectLinksetsError(pStatus, pReason, pContent, mCapabilityURL);
+}
+
+//---------------------------------------------------------------------------
+// TerrainLinksetsResponder
+//---------------------------------------------------------------------------
+
+TerrainLinksetsResponder::TerrainLinksetsResponder(const std::string &pCapabilityURL, LinksetsResponderPtr pLinksetsResponsderPtr)
+ : LLHTTPClient::Responder(),
+ mCapabilityURL(pCapabilityURL),
+ mLinksetsResponsderPtr(pLinksetsResponsderPtr)
+{
+}
+
+TerrainLinksetsResponder::~TerrainLinksetsResponder()
+{
+}
+
+void TerrainLinksetsResponder::result(const LLSD &pContent)
+{
+ mLinksetsResponsderPtr->handleTerrainLinksetsResult(pContent);
+}
+
+void TerrainLinksetsResponder::errorWithContent(U32 pStatus, const std::string &pReason, const LLSD& pContent)
+{
+ mLinksetsResponsderPtr->handleTerrainLinksetsError(pStatus, pReason, pContent, mCapabilityURL);
+}
+
+//---------------------------------------------------------------------------
+// CharactersResponder
+//---------------------------------------------------------------------------
+
+CharactersResponder::CharactersResponder(const std::string &pCapabilityURL, LLPathfindingManager::request_id_t pRequestId, LLPathfindingManager::object_request_callback_t pCharactersCallback)
+ : LLHTTPClient::Responder(),
+ mCapabilityURL(pCapabilityURL),
+ mRequestId(pRequestId),
+ mCharactersCallback(pCharactersCallback)
+{
+}
+
+CharactersResponder::~CharactersResponder()
+{
+}
+
+void CharactersResponder::result(const LLSD &pContent)
+{
+ LLPathfindingObjectListPtr characterListPtr = LLPathfindingObjectListPtr(new LLPathfindingCharacterList(pContent));
+ mCharactersCallback(mRequestId, LLPathfindingManager::kRequestCompleted, characterListPtr);
+}
+
+void CharactersResponder::errorWithContent(U32 pStatus, const std::string &pReason, const LLSD& pContent)
+{
+ llwarns << "CharactersResponder error [status:" << pStatus << "]: " << pContent << llendl;
+
+ LLPathfindingObjectListPtr characterListPtr = LLPathfindingObjectListPtr(new LLPathfindingCharacterList());
+ mCharactersCallback(mRequestId, LLPathfindingManager::kRequestError, characterListPtr);
+}
diff --git a/indra/newview/llpathfindingmanager.h b/indra/newview/llpathfindingmanager.h
new file mode 100755
index 0000000000..c61ff244fc
--- /dev/null
+++ b/indra/newview/llpathfindingmanager.h
@@ -0,0 +1,127 @@
+/**
+* @file llpathfindingmanager.h
+* @brief Header file for llpathfindingmanager
+* @author Stinson@lindenlab.com
+*
+* $LicenseInfo:firstyear=2012&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2012, 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_LLPATHFINDINGMANAGER_H
+#define LL_LLPATHFINDINGMANAGER_H
+
+#include <string>
+#include <map>
+
+#include <boost/function.hpp>
+#include <boost/signals2.hpp>
+
+#include "llpathfindinglinkset.h"
+#include "llpathfindingobjectlist.h"
+#include "llpathfindingnavmesh.h"
+#include "llsingleton.h"
+
+class LLPathfindingNavMeshStatus;
+class LLUUID;
+class LLViewerRegion;
+
+class LLPathfindingManager : public LLSingleton<LLPathfindingManager>
+{
+ friend class LLNavMeshSimStateChangeNode;
+ friend class NavMeshStatusResponder;
+ friend class LLAgentStateChangeNode;
+ friend class AgentStateResponder;
+public:
+ typedef enum {
+ kRequestStarted,
+ kRequestCompleted,
+ kRequestNotEnabled,
+ kRequestError
+ } ERequestStatus;
+
+ LLPathfindingManager();
+ virtual ~LLPathfindingManager();
+
+ void initSystem();
+ void quitSystem();
+
+ bool isPathfindingViewEnabled() const;
+ bool isPathfindingEnabledForCurrentRegion() const;
+ bool isPathfindingEnabledForRegion(LLViewerRegion *pRegion) const;
+
+ bool isAllowViewTerrainProperties() const;
+
+ LLPathfindingNavMesh::navmesh_slot_t registerNavMeshListenerForRegion(LLViewerRegion *pRegion, LLPathfindingNavMesh::navmesh_callback_t pNavMeshCallback);
+ void requestGetNavMeshForRegion(LLViewerRegion *pRegion, bool pIsGetStatusOnly);
+
+ typedef U32 request_id_t;
+ typedef boost::function<void (request_id_t, ERequestStatus, LLPathfindingObjectListPtr)> object_request_callback_t;
+
+ void requestGetLinksets(request_id_t pRequestId, object_request_callback_t pLinksetsCallback) const;
+ void requestSetLinksets(request_id_t pRequestId, const LLPathfindingObjectListPtr &pLinksetListPtr, LLPathfindingLinkset::ELinksetUse pLinksetUse, S32 pA, S32 pB, S32 pC, S32 pD, object_request_callback_t pLinksetsCallback) const;
+
+ void requestGetCharacters(request_id_t pRequestId, object_request_callback_t pCharactersCallback) const;
+
+ typedef boost::function<void (BOOL)> agent_state_callback_t;
+ typedef boost::signals2::signal<void (BOOL)> agent_state_signal_t;
+ typedef boost::signals2::connection agent_state_slot_t;
+
+ agent_state_slot_t registerAgentStateListener(agent_state_callback_t pAgentStateCallback);
+ void requestGetAgentState();
+
+ typedef boost::function<void (bool)> rebake_navmesh_callback_t;
+ void requestRebakeNavMesh(rebake_navmesh_callback_t pRebakeNavMeshCallback);
+
+protected:
+
+private:
+ typedef std::map<LLUUID, LLPathfindingNavMeshPtr> NavMeshMap;
+
+ void sendRequestGetNavMeshForRegion(LLPathfindingNavMeshPtr navMeshPtr, LLViewerRegion *pRegion, const LLPathfindingNavMeshStatus &pNavMeshStatus);
+
+ void handleDeferredGetAgentStateForRegion(const LLUUID &pRegionUUID);
+ void handleDeferredGetNavMeshForRegion(const LLUUID &pRegionUUID, bool pIsGetStatusOnly);
+ void handleDeferredGetLinksetsForRegion(const LLUUID &pRegionUUID, request_id_t pRequestId, object_request_callback_t pLinksetsCallback) const;
+ void handleDeferredGetCharactersForRegion(const LLUUID &pRegionUUID, request_id_t pRequestId, object_request_callback_t pCharactersCallback) const;
+
+ void handleNavMeshStatusRequest(const LLPathfindingNavMeshStatus &pNavMeshStatus, LLViewerRegion *pRegion, bool pIsGetStatusOnly);
+ void handleNavMeshStatusUpdate(const LLPathfindingNavMeshStatus &pNavMeshStatus);
+
+ void handleAgentState(BOOL pCanRebakeRegion);
+
+ LLPathfindingNavMeshPtr getNavMeshForRegion(const LLUUID &pRegionUUID);
+ LLPathfindingNavMeshPtr getNavMeshForRegion(LLViewerRegion *pRegion);
+
+ std::string getNavMeshStatusURLForCurrentRegion() const;
+ std::string getNavMeshStatusURLForRegion(LLViewerRegion *pRegion) const;
+ std::string getRetrieveNavMeshURLForRegion(LLViewerRegion *pRegion) const;
+ std::string getObjectLinksetsURLForCurrentRegion() const;
+ std::string getTerrainLinksetsURLForCurrentRegion() const;
+ std::string getCharactersURLForCurrentRegion() const;
+ std::string getAgentStateURLForRegion(LLViewerRegion *pRegion) const;
+ std::string getCapabilityURLForCurrentRegion(const std::string &pCapabilityName) const;
+ std::string getCapabilityURLForRegion(LLViewerRegion *pRegion, const std::string &pCapabilityName) const;
+ LLViewerRegion *getCurrentRegion() const;
+
+ NavMeshMap mNavMeshMap;
+ agent_state_signal_t mAgentStateSignal;
+};
+
+#endif // LL_LLPATHFINDINGMANAGER_H
diff --git a/indra/newview/llpathfindingnavmesh.cpp b/indra/newview/llpathfindingnavmesh.cpp
new file mode 100755
index 0000000000..0c23e5ac92
--- /dev/null
+++ b/indra/newview/llpathfindingnavmesh.cpp
@@ -0,0 +1,206 @@
+/**
+* @file llpathfindingnavmesh.cpp
+* @brief Implementation of llpathfindingnavmesh
+* @author Stinson@lindenlab.com
+*
+* $LicenseInfo:firstyear=2012&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2012, 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 "llpathfindingnavmesh.h"
+
+#include <string>
+
+#include "llpathfindingnavmeshstatus.h"
+#include "llsd.h"
+#include "llsdserialize.h"
+#include "lluuid.h"
+
+#define NAVMESH_VERSION_FIELD "navmesh_version"
+#define NAVMESH_DATA_FIELD "navmesh_data"
+
+//---------------------------------------------------------------------------
+// LLPathfindingNavMesh
+//---------------------------------------------------------------------------
+
+LLPathfindingNavMesh::LLPathfindingNavMesh(const LLUUID &pRegionUUID)
+ : mNavMeshStatus(pRegionUUID),
+ mNavMeshRequestStatus(kNavMeshRequestUnknown),
+ mNavMeshSignal(),
+ mNavMeshData()
+
+{
+}
+
+LLPathfindingNavMesh::~LLPathfindingNavMesh()
+{
+}
+
+LLPathfindingNavMesh::navmesh_slot_t LLPathfindingNavMesh::registerNavMeshListener(navmesh_callback_t pNavMeshCallback)
+{
+ return mNavMeshSignal.connect(pNavMeshCallback);
+}
+
+bool LLPathfindingNavMesh::hasNavMeshVersion(const LLPathfindingNavMeshStatus &pNavMeshStatus) const
+{
+ return ((mNavMeshStatus.getVersion() == pNavMeshStatus.getVersion()) &&
+ ((mNavMeshRequestStatus == kNavMeshRequestStarted) || (mNavMeshRequestStatus == kNavMeshRequestCompleted) ||
+ ((mNavMeshRequestStatus == kNavMeshRequestChecking) && !mNavMeshData.empty())));
+}
+
+void LLPathfindingNavMesh::handleNavMeshWaitForRegionLoad()
+{
+ setRequestStatus(kNavMeshRequestWaiting);
+}
+
+void LLPathfindingNavMesh::handleNavMeshCheckVersion()
+{
+ setRequestStatus(kNavMeshRequestChecking);
+}
+
+void LLPathfindingNavMesh::handleRefresh(const LLPathfindingNavMeshStatus &pNavMeshStatus)
+{
+ llassert(mNavMeshStatus.getRegionUUID() == pNavMeshStatus.getRegionUUID());
+ llassert(mNavMeshStatus.getVersion() == pNavMeshStatus.getVersion());
+ mNavMeshStatus = pNavMeshStatus;
+ if (mNavMeshRequestStatus == kNavMeshRequestChecking)
+ {
+ llassert(!mNavMeshData.empty());
+ setRequestStatus(kNavMeshRequestCompleted);
+ }
+ else
+ {
+ sendStatus();
+ }
+}
+
+void LLPathfindingNavMesh::handleNavMeshNewVersion(const LLPathfindingNavMeshStatus &pNavMeshStatus)
+{
+ llassert(mNavMeshStatus.getRegionUUID() == pNavMeshStatus.getRegionUUID());
+ if (mNavMeshStatus.getVersion() == pNavMeshStatus.getVersion())
+ {
+ mNavMeshStatus = pNavMeshStatus;
+ sendStatus();
+ }
+ else
+ {
+ mNavMeshData.clear();
+ mNavMeshStatus = pNavMeshStatus;
+ setRequestStatus(kNavMeshRequestNeedsUpdate);
+ }
+}
+
+void LLPathfindingNavMesh::handleNavMeshStart(const LLPathfindingNavMeshStatus &pNavMeshStatus)
+{
+ llassert(mNavMeshStatus.getRegionUUID() == pNavMeshStatus.getRegionUUID());
+ mNavMeshStatus = pNavMeshStatus;
+ setRequestStatus(kNavMeshRequestStarted);
+}
+
+void LLPathfindingNavMesh::handleNavMeshResult(const LLSD &pContent, U32 pNavMeshVersion)
+{
+ llassert(pContent.has(NAVMESH_VERSION_FIELD));
+ if (pContent.has(NAVMESH_VERSION_FIELD))
+ {
+ llassert(pContent.get(NAVMESH_VERSION_FIELD).isInteger());
+ llassert(pContent.get(NAVMESH_VERSION_FIELD).asInteger() >= 0);
+ U32 embeddedNavMeshVersion = static_cast<U32>(pContent.get(NAVMESH_VERSION_FIELD).asInteger());
+ llassert(embeddedNavMeshVersion == pNavMeshVersion); // stinson 03/13/2012 : does this ever occur?
+ if (embeddedNavMeshVersion != pNavMeshVersion)
+ {
+ llwarns << "Mismatch between expected and embedded navmesh versions occurred" << llendl;
+ pNavMeshVersion = embeddedNavMeshVersion;
+ }
+ }
+
+ if (mNavMeshStatus.getVersion() == pNavMeshVersion)
+ {
+ ENavMeshRequestStatus status;
+ if ( pContent.has(NAVMESH_DATA_FIELD) )
+ {
+ const LLSD::Binary &value = pContent.get(NAVMESH_DATA_FIELD).asBinary();
+ unsigned int binSize = value.size();
+ std::string newStr(reinterpret_cast<const char *>(&value[0]), binSize);
+ std::istringstream streamdecomp( newStr );
+ unsigned int decompBinSize = 0;
+ bool valid = false;
+ U8* pUncompressedNavMeshContainer = unzip_llsdNavMesh( valid, decompBinSize, streamdecomp, binSize ) ;
+ if ( !valid )
+ {
+ llwarns << "Unable to decompress the navmesh llsd." << llendl;
+ status = kNavMeshRequestError;
+ }
+ else
+ {
+ llassert(pUncompressedNavMeshContainer);
+ mNavMeshData.resize( decompBinSize );
+ memcpy( &mNavMeshData[0], &pUncompressedNavMeshContainer[0], decompBinSize );
+ status = kNavMeshRequestCompleted;
+ }
+ if ( pUncompressedNavMeshContainer )
+ {
+ free( pUncompressedNavMeshContainer );
+ }
+ }
+ else
+ {
+ llwarns << "No mesh data received" << llendl;
+ status = kNavMeshRequestError;
+ }
+ setRequestStatus(status);
+ }
+}
+
+void LLPathfindingNavMesh::handleNavMeshNotEnabled()
+{
+ mNavMeshData.clear();
+ setRequestStatus(kNavMeshRequestNotEnabled);
+}
+
+void LLPathfindingNavMesh::handleNavMeshError()
+{
+ mNavMeshData.clear();
+ setRequestStatus(kNavMeshRequestError);
+}
+
+void LLPathfindingNavMesh::handleNavMeshError(U32 pStatus, const std::string &pReason, const LLSD& pContent, const std::string &pURL, U32 pNavMeshVersion)
+{
+ llwarns << "LLPathfindingNavMesh error with request to URL '" << pURL << "' [status:"
+ << pStatus << "]: " << pContent << llendl;
+ if (mNavMeshStatus.getVersion() == pNavMeshVersion)
+ {
+ handleNavMeshError();
+ }
+}
+
+void LLPathfindingNavMesh::setRequestStatus(ENavMeshRequestStatus pNavMeshRequestStatus)
+{
+ mNavMeshRequestStatus = pNavMeshRequestStatus;
+ sendStatus();
+}
+
+void LLPathfindingNavMesh::sendStatus()
+{
+ mNavMeshSignal(mNavMeshRequestStatus, mNavMeshStatus, mNavMeshData);
+}
diff --git a/indra/newview/llpathfindingnavmesh.h b/indra/newview/llpathfindingnavmesh.h
new file mode 100755
index 0000000000..b872ccad7c
--- /dev/null
+++ b/indra/newview/llpathfindingnavmesh.h
@@ -0,0 +1,91 @@
+/**
+* @file llpathfindingnavmesh.h
+* @brief Header file for llpathfindingnavmesh
+* @author Stinson@lindenlab.com
+*
+* $LicenseInfo:firstyear=2012&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2012, 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_LLPATHFINDINGNAVMESH_H
+#define LL_LLPATHFINDINGNAVMESH_H
+
+#include <string>
+
+#include <boost/shared_ptr.hpp>
+#include <boost/function.hpp>
+#include <boost/signals2.hpp>
+
+#include "llpathfindingnavmeshstatus.h"
+#include "llsd.h"
+
+class LLPathfindingNavMesh;
+class LLUUID;
+
+typedef boost::shared_ptr<LLPathfindingNavMesh> LLPathfindingNavMeshPtr;
+
+class LLPathfindingNavMesh
+{
+public:
+ typedef enum {
+ kNavMeshRequestUnknown,
+ kNavMeshRequestWaiting,
+ kNavMeshRequestChecking,
+ kNavMeshRequestNeedsUpdate,
+ kNavMeshRequestStarted,
+ kNavMeshRequestCompleted,
+ kNavMeshRequestNotEnabled,
+ kNavMeshRequestError
+ } ENavMeshRequestStatus;
+
+ typedef boost::function<void (ENavMeshRequestStatus, const LLPathfindingNavMeshStatus &, const LLSD::Binary &)> navmesh_callback_t;
+ typedef boost::signals2::signal<void (ENavMeshRequestStatus, const LLPathfindingNavMeshStatus &, const LLSD::Binary &)> navmesh_signal_t;
+ typedef boost::signals2::connection navmesh_slot_t;
+
+ LLPathfindingNavMesh(const LLUUID &pRegionUUID);
+ virtual ~LLPathfindingNavMesh();
+
+ navmesh_slot_t registerNavMeshListener(navmesh_callback_t pNavMeshCallback);
+
+ bool hasNavMeshVersion(const LLPathfindingNavMeshStatus &pNavMeshStatus) const;
+
+ void handleNavMeshWaitForRegionLoad();
+ void handleNavMeshCheckVersion();
+ void handleRefresh(const LLPathfindingNavMeshStatus &pNavMeshStatus);
+ void handleNavMeshNewVersion(const LLPathfindingNavMeshStatus &pNavMeshStatus);
+ void handleNavMeshStart(const LLPathfindingNavMeshStatus &pNavMeshStatus);
+ void handleNavMeshResult(const LLSD &pContent, U32 pNavMeshVersion);
+ void handleNavMeshNotEnabled();
+ void handleNavMeshError();
+ void handleNavMeshError(U32 pStatus, const std::string &pReason, const LLSD& pContent, const std::string &pURL, U32 pNavMeshVersion);
+
+protected:
+
+private:
+ void setRequestStatus(ENavMeshRequestStatus pNavMeshRequestStatus);
+ void sendStatus();
+
+ LLPathfindingNavMeshStatus mNavMeshStatus;
+ ENavMeshRequestStatus mNavMeshRequestStatus;
+ navmesh_signal_t mNavMeshSignal;
+ LLSD::Binary mNavMeshData;
+};
+
+#endif // LL_LLPATHFINDINGNAVMESH_H
diff --git a/indra/newview/llpathfindingnavmeshstatus.cpp b/indra/newview/llpathfindingnavmeshstatus.cpp
new file mode 100755
index 0000000000..2eaa6075ca
--- /dev/null
+++ b/indra/newview/llpathfindingnavmeshstatus.cpp
@@ -0,0 +1,145 @@
+/**
+* @file llpathfindingnavmeshstatus.cpp
+* @brief Implementation of llpathfindingnavmeshstatus
+* @author Stinson@lindenlab.com
+*
+* $LicenseInfo:firstyear=2012&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2012, 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 "llpathfindingnavmeshstatus.h"
+
+#include <string>
+
+#include "llsd.h"
+#include "llstring.h"
+#include "lluuid.h"
+
+#define REGION_FIELD "region_id"
+#define STATUS_FIELD "status"
+#define VERSION_FIELD "version"
+
+const std::string LLPathfindingNavMeshStatus::sStatusPending("pending");
+const std::string LLPathfindingNavMeshStatus::sStatusBuilding("building");
+const std::string LLPathfindingNavMeshStatus::sStatusComplete("complete");
+const std::string LLPathfindingNavMeshStatus::sStatusRepending("repending");
+
+
+//---------------------------------------------------------------------------
+// LLPathfindingNavMeshStatus
+//---------------------------------------------------------------------------
+
+LLPathfindingNavMeshStatus::LLPathfindingNavMeshStatus()
+ : mIsValid(false),
+ mRegionUUID(),
+ mVersion(0U),
+ mStatus(kComplete)
+{
+}
+
+LLPathfindingNavMeshStatus::LLPathfindingNavMeshStatus(const LLUUID &pRegionUUID)
+ : mIsValid(false),
+ mRegionUUID(pRegionUUID),
+ mVersion(0U),
+ mStatus(kComplete)
+{
+}
+
+LLPathfindingNavMeshStatus::LLPathfindingNavMeshStatus(const LLUUID &pRegionUUID, const LLSD &pContent)
+ : mIsValid(true),
+ mRegionUUID(pRegionUUID),
+ mVersion(0U),
+ mStatus(kComplete)
+{
+ parseStatus(pContent);
+}
+
+LLPathfindingNavMeshStatus::LLPathfindingNavMeshStatus(const LLSD &pContent)
+ : mIsValid(true),
+ mRegionUUID(),
+ mVersion(0U),
+ mStatus(kComplete)
+{
+ llassert(pContent.has(REGION_FIELD));
+ llassert(pContent.get(REGION_FIELD).isUUID());
+ mRegionUUID = pContent.get(REGION_FIELD).asUUID();
+
+ parseStatus(pContent);
+}
+
+LLPathfindingNavMeshStatus::LLPathfindingNavMeshStatus(const LLPathfindingNavMeshStatus &pOther)
+ : mIsValid(pOther.mIsValid),
+ mRegionUUID(pOther.mRegionUUID),
+ mVersion(pOther.mVersion),
+ mStatus(pOther.mStatus)
+{
+}
+
+LLPathfindingNavMeshStatus::~LLPathfindingNavMeshStatus()
+{
+}
+
+LLPathfindingNavMeshStatus &LLPathfindingNavMeshStatus::operator =(const LLPathfindingNavMeshStatus &pOther)
+{
+ mIsValid = pOther.mIsValid;
+ mRegionUUID = pOther.mRegionUUID;
+ mVersion = pOther.mVersion;
+ mStatus = pOther.mStatus;
+
+ return *this;
+}
+
+void LLPathfindingNavMeshStatus::parseStatus(const LLSD &pContent)
+{
+ llassert(pContent.has(VERSION_FIELD));
+ llassert(pContent.get(VERSION_FIELD).isInteger());
+ llassert(pContent.get(VERSION_FIELD).asInteger() >= 0);
+ mVersion = static_cast<U32>(pContent.get(VERSION_FIELD).asInteger());
+
+ llassert(pContent.has(STATUS_FIELD));
+ llassert(pContent.get(STATUS_FIELD).isString());
+ std::string status = pContent.get(STATUS_FIELD).asString();
+
+ if (LLStringUtil::compareStrings(status, sStatusPending) == 0)
+ {
+ mStatus = kPending;
+ }
+ else if (LLStringUtil::compareStrings(status, sStatusBuilding) == 0)
+ {
+ mStatus = kBuilding;
+ }
+ else if (LLStringUtil::compareStrings(status, sStatusComplete) == 0)
+ {
+ mStatus = kComplete;
+ }
+ else if (LLStringUtil::compareStrings(status, sStatusRepending) == 0)
+ {
+ mStatus = kRepending;
+ }
+ else
+ {
+ mStatus = kComplete;
+ llassert(0);
+ }
+}
diff --git a/indra/newview/llpathfindingnavmeshstatus.h b/indra/newview/llpathfindingnavmeshstatus.h
new file mode 100755
index 0000000000..74533fa484
--- /dev/null
+++ b/indra/newview/llpathfindingnavmeshstatus.h
@@ -0,0 +1,77 @@
+/**
+* @file llpathfindingnavmeshstatus.h
+* @brief Header file for llpathfindingnavmeshstatus
+* @author Stinson@lindenlab.com
+*
+* $LicenseInfo:firstyear=2012&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2012, 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_LLPATHFINDINGNAVMESHSTATUS_H
+#define LL_LLPATHFINDINGNAVMESHSTATUS_H
+
+#include <string>
+
+#include "lluuid.h"
+
+class LLSD;
+
+class LLPathfindingNavMeshStatus
+{
+public:
+ typedef enum
+ {
+ kPending,
+ kBuilding,
+ kComplete,
+ kRepending
+ } ENavMeshStatus;
+
+ LLPathfindingNavMeshStatus();
+ LLPathfindingNavMeshStatus(const LLUUID &pRegionUUID);
+ LLPathfindingNavMeshStatus(const LLUUID &pRegionUUID, const LLSD &pContent);
+ LLPathfindingNavMeshStatus(const LLSD &pContent);
+ LLPathfindingNavMeshStatus(const LLPathfindingNavMeshStatus &pOther);
+ virtual ~LLPathfindingNavMeshStatus();
+
+ LLPathfindingNavMeshStatus &operator =(const LLPathfindingNavMeshStatus &pOther);
+
+ bool isValid() const {return mIsValid;};
+ const LLUUID &getRegionUUID() const {return mRegionUUID;};
+ U32 getVersion() const {return mVersion;};
+ ENavMeshStatus getStatus() const {return mStatus;};
+
+protected:
+
+private:
+ void parseStatus(const LLSD &pContent);
+
+ bool mIsValid;
+ LLUUID mRegionUUID;
+ U32 mVersion;
+ ENavMeshStatus mStatus;
+
+ static const std::string sStatusPending;
+ static const std::string sStatusBuilding;
+ static const std::string sStatusComplete;
+ static const std::string sStatusRepending;
+};
+
+#endif // LL_LLPATHFINDINGNAVMESHSTATUS_H
diff --git a/indra/newview/llpathfindingnavmeshzone.cpp b/indra/newview/llpathfindingnavmeshzone.cpp
new file mode 100755
index 0000000000..e190dbba65
--- /dev/null
+++ b/indra/newview/llpathfindingnavmeshzone.cpp
@@ -0,0 +1,423 @@
+/**
+* @file llpathfindingnavmeshzone.cpp
+* @brief Implementation of llpathfindingnavmeshzone
+* @author Stinson@lindenlab.com
+*
+* $LicenseInfo:firstyear=2012&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2012, 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 "llpathfindingnavmeshzone.h"
+
+#include <vector>
+
+#include <boost/bind.hpp>
+#include <boost/function.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/signals2.hpp>
+
+#include "llagent.h"
+#include "llpathfindingmanager.h"
+#include "llpathfindingnavmesh.h"
+#include "llpathfindingnavmeshstatus.h"
+#include "llpathinglib.h"
+#include "llsd.h"
+#include "lluuid.h"
+#include "llviewercontrol.h"
+#include "llviewerregion.h"
+
+#define CENTER_REGION 99
+
+//---------------------------------------------------------------------------
+// LLPathfindingNavMeshZone
+//---------------------------------------------------------------------------
+
+LLPathfindingNavMeshZone::LLPathfindingNavMeshZone()
+ : mNavMeshLocationPtrs(),
+ mNavMeshZoneRequestStatus(kNavMeshZoneRequestUnknown),
+ mNavMeshZoneSignal()
+{
+}
+
+LLPathfindingNavMeshZone::~LLPathfindingNavMeshZone()
+{
+}
+
+LLPathfindingNavMeshZone::navmesh_zone_slot_t LLPathfindingNavMeshZone::registerNavMeshZoneListener(navmesh_zone_callback_t pNavMeshZoneCallback)
+{
+ return mNavMeshZoneSignal.connect(pNavMeshZoneCallback);
+}
+
+void LLPathfindingNavMeshZone::initialize()
+{
+ mNavMeshLocationPtrs.clear();
+
+ NavMeshLocationPtr centerNavMeshPtr(new NavMeshLocation(CENTER_REGION, boost::bind(&LLPathfindingNavMeshZone::handleNavMeshLocation, this)));
+ mNavMeshLocationPtrs.push_back(centerNavMeshPtr);
+
+ U32 neighborRegionDir = gSavedSettings.getU32("PathfindingRetrieveNeighboringRegion");
+ if (neighborRegionDir != CENTER_REGION)
+ {
+ NavMeshLocationPtr neighborNavMeshPtr(new NavMeshLocation(neighborRegionDir, boost::bind(&LLPathfindingNavMeshZone::handleNavMeshLocation, this)));
+ mNavMeshLocationPtrs.push_back(neighborNavMeshPtr);
+ }
+}
+
+void LLPathfindingNavMeshZone::enable()
+{
+ for (NavMeshLocationPtrs::iterator navMeshLocationPtrIter = mNavMeshLocationPtrs.begin();
+ navMeshLocationPtrIter != mNavMeshLocationPtrs.end(); ++navMeshLocationPtrIter)
+ {
+ NavMeshLocationPtr navMeshLocationPtr = *navMeshLocationPtrIter;
+ navMeshLocationPtr->enable();
+ }
+}
+
+void LLPathfindingNavMeshZone::disable()
+{
+ for (NavMeshLocationPtrs::iterator navMeshLocationPtrIter = mNavMeshLocationPtrs.begin();
+ navMeshLocationPtrIter != mNavMeshLocationPtrs.end(); ++navMeshLocationPtrIter)
+ {
+ NavMeshLocationPtr navMeshLocationPtr = *navMeshLocationPtrIter;
+ navMeshLocationPtr->disable();
+ }
+}
+
+void LLPathfindingNavMeshZone::refresh()
+{
+ if (LLPathingLib::getInstance() != NULL)
+ {
+ LLPathingLib::getInstance()->cleanupResidual();
+ }
+
+ for (NavMeshLocationPtrs::iterator navMeshLocationPtrIter = mNavMeshLocationPtrs.begin();
+ navMeshLocationPtrIter != mNavMeshLocationPtrs.end(); ++navMeshLocationPtrIter)
+ {
+ NavMeshLocationPtr navMeshLocationPtr = *navMeshLocationPtrIter;
+ navMeshLocationPtr->refresh();
+ }
+}
+
+LLPathfindingNavMeshZone::ENavMeshZoneStatus LLPathfindingNavMeshZone::getNavMeshZoneStatus() const
+{
+ bool hasPending = false;
+ bool hasBuilding = false;
+ bool hasComplete = false;
+ bool hasRepending = false;
+
+ for (NavMeshLocationPtrs::const_iterator navMeshLocationPtrIter = mNavMeshLocationPtrs.begin();
+ navMeshLocationPtrIter != mNavMeshLocationPtrs.end(); ++navMeshLocationPtrIter)
+ {
+ const NavMeshLocationPtr navMeshLocationPtr = *navMeshLocationPtrIter;
+
+ switch (navMeshLocationPtr->getNavMeshStatus())
+ {
+ case LLPathfindingNavMeshStatus::kPending :
+ hasPending = true;
+ break;
+ case LLPathfindingNavMeshStatus::kBuilding :
+ hasBuilding = true;
+ break;
+ case LLPathfindingNavMeshStatus::kComplete :
+ hasComplete = true;
+ break;
+ case LLPathfindingNavMeshStatus::kRepending :
+ hasRepending = true;
+ break;
+ default :
+ hasPending = true;
+ llassert(0);
+ break;
+ }
+ }
+
+ ENavMeshZoneStatus zoneStatus = kNavMeshZoneComplete;
+ if (hasRepending || (hasPending && hasBuilding))
+ {
+ zoneStatus = kNavMeshZonePendingAndBuilding;
+ }
+ else if (hasComplete)
+ {
+ if (hasPending)
+ {
+ zoneStatus = kNavMeshZoneSomePending;
+ }
+ else if (hasBuilding)
+ {
+ zoneStatus = kNavMeshZoneSomeBuilding;
+ }
+ else
+ {
+ zoneStatus = kNavMeshZoneComplete;
+ }
+ }
+ else if (hasPending)
+ {
+ zoneStatus = kNavMeshZonePending;
+ }
+ else if (hasBuilding)
+ {
+ zoneStatus = kNavMeshZoneBuilding;
+ }
+
+ return zoneStatus;
+}
+
+void LLPathfindingNavMeshZone::handleNavMeshLocation()
+{
+ updateStatus();
+}
+
+void LLPathfindingNavMeshZone::updateStatus()
+{
+ bool hasRequestUnknown = false;
+ bool hasRequestWaiting = false;
+ bool hasRequestChecking = false;
+ bool hasRequestNeedsUpdate = false;
+ bool hasRequestStarted = false;
+ bool hasRequestCompleted = false;
+ bool hasRequestNotEnabled = false;
+ bool hasRequestError = false;
+
+ for (NavMeshLocationPtrs::const_iterator navMeshLocationPtrIter = mNavMeshLocationPtrs.begin();
+ navMeshLocationPtrIter != mNavMeshLocationPtrs.end(); ++navMeshLocationPtrIter)
+ {
+ const NavMeshLocationPtr navMeshLocationPtr = *navMeshLocationPtrIter;
+ switch (navMeshLocationPtr->getRequestStatus())
+ {
+ case LLPathfindingNavMesh::kNavMeshRequestUnknown :
+ hasRequestUnknown = true;
+ break;
+ case LLPathfindingNavMesh::kNavMeshRequestWaiting :
+ hasRequestWaiting = true;
+ break;
+ case LLPathfindingNavMesh::kNavMeshRequestChecking :
+ hasRequestChecking = true;
+ break;
+ case LLPathfindingNavMesh::kNavMeshRequestNeedsUpdate :
+ hasRequestNeedsUpdate = true;
+ break;
+ case LLPathfindingNavMesh::kNavMeshRequestStarted :
+ hasRequestStarted = true;
+ break;
+ case LLPathfindingNavMesh::kNavMeshRequestCompleted :
+ hasRequestCompleted = true;
+ break;
+ case LLPathfindingNavMesh::kNavMeshRequestNotEnabled :
+ hasRequestNotEnabled = true;
+ break;
+ case LLPathfindingNavMesh::kNavMeshRequestError :
+ hasRequestError = true;
+ break;
+ default :
+ hasRequestError = true;
+ llassert(0);
+ break;
+ }
+ }
+
+ ENavMeshZoneRequestStatus zoneRequestStatus = kNavMeshZoneRequestUnknown;
+ if (hasRequestWaiting)
+ {
+ zoneRequestStatus = kNavMeshZoneRequestWaiting;
+ }
+ else if (hasRequestNeedsUpdate)
+ {
+ zoneRequestStatus = kNavMeshZoneRequestNeedsUpdate;
+ }
+ else if (hasRequestChecking)
+ {
+ zoneRequestStatus = kNavMeshZoneRequestChecking;
+ }
+ else if (hasRequestStarted)
+ {
+ zoneRequestStatus = kNavMeshZoneRequestStarted;
+ }
+ else if (hasRequestError)
+ {
+ zoneRequestStatus = kNavMeshZoneRequestError;
+ }
+ else if (hasRequestUnknown)
+ {
+ zoneRequestStatus = kNavMeshZoneRequestUnknown;
+ }
+ else if (hasRequestCompleted)
+ {
+ zoneRequestStatus = kNavMeshZoneRequestCompleted;
+ }
+ else if (hasRequestNotEnabled)
+ {
+ zoneRequestStatus = kNavMeshZoneRequestNotEnabled;
+ }
+ else
+ {
+ zoneRequestStatus = kNavMeshZoneRequestError;
+ llassert(0);
+ }
+
+ if ((mNavMeshZoneRequestStatus != kNavMeshZoneRequestCompleted) &&
+ (zoneRequestStatus == kNavMeshZoneRequestCompleted))
+ {
+ llassert(LLPathingLib::getInstance() != NULL);
+ if (LLPathingLib::getInstance() != NULL)
+ {
+ LLPathingLib::getInstance()->processNavMeshData();
+ }
+ }
+
+ mNavMeshZoneRequestStatus = zoneRequestStatus;
+ mNavMeshZoneSignal(mNavMeshZoneRequestStatus);
+}
+
+//---------------------------------------------------------------------------
+// LLPathfindingNavMeshZone::NavMeshLocation
+//---------------------------------------------------------------------------
+
+LLPathfindingNavMeshZone::NavMeshLocation::NavMeshLocation(S32 pDirection, navmesh_location_callback_t pLocationCallback)
+ : mDirection(pDirection),
+ mRegionUUID(),
+ mHasNavMesh(false),
+ mNavMeshVersion(0U),
+ mNavMeshStatus(LLPathfindingNavMeshStatus::kComplete),
+ mLocationCallback(pLocationCallback),
+ mRequestStatus(LLPathfindingNavMesh::kNavMeshRequestUnknown),
+ mNavMeshSlot()
+{
+}
+
+LLPathfindingNavMeshZone::NavMeshLocation::~NavMeshLocation()
+{
+}
+
+void LLPathfindingNavMeshZone::NavMeshLocation::enable()
+{
+ clear();
+
+ LLViewerRegion *region = getRegion();
+ if (region == NULL)
+ {
+ mRegionUUID.setNull();
+ }
+ else
+ {
+ mRegionUUID = region->getRegionID();
+ mNavMeshSlot = LLPathfindingManager::getInstance()->registerNavMeshListenerForRegion(region, boost::bind(&LLPathfindingNavMeshZone::NavMeshLocation::handleNavMesh, this, _1, _2, _3));
+ }
+}
+
+void LLPathfindingNavMeshZone::NavMeshLocation::refresh()
+{
+ LLViewerRegion *region = getRegion();
+
+ if (region == NULL)
+ {
+ llassert(mRegionUUID.isNull());
+ LLPathfindingNavMeshStatus newNavMeshStatus(mRegionUUID);
+ LLSD::Binary nullData;
+ handleNavMesh(LLPathfindingNavMesh::kNavMeshRequestNotEnabled, newNavMeshStatus, nullData);
+ }
+ else
+ {
+ llassert(mRegionUUID == region->getRegionID());
+ LLPathfindingManager::getInstance()->requestGetNavMeshForRegion(region, false);
+ }
+}
+
+void LLPathfindingNavMeshZone::NavMeshLocation::disable()
+{
+ clear();
+}
+
+LLPathfindingNavMesh::ENavMeshRequestStatus LLPathfindingNavMeshZone::NavMeshLocation::getRequestStatus() const
+{
+ return mRequestStatus;
+}
+
+LLPathfindingNavMeshStatus::ENavMeshStatus LLPathfindingNavMeshZone::NavMeshLocation::getNavMeshStatus() const
+{
+ return mNavMeshStatus;
+}
+
+void LLPathfindingNavMeshZone::NavMeshLocation::handleNavMesh(LLPathfindingNavMesh::ENavMeshRequestStatus pNavMeshRequestStatus, const LLPathfindingNavMeshStatus &pNavMeshStatus, const LLSD::Binary &pNavMeshData)
+{
+ llassert(mRegionUUID == pNavMeshStatus.getRegionUUID());
+
+ if ((pNavMeshRequestStatus == LLPathfindingNavMesh::kNavMeshRequestCompleted) &&
+ (!mHasNavMesh || (mNavMeshVersion != pNavMeshStatus.getVersion())))
+ {
+ llassert(!pNavMeshData.empty());
+ mHasNavMesh = true;
+ mNavMeshVersion = pNavMeshStatus.getVersion();
+ llassert(LLPathingLib::getInstance() != NULL);
+ if (LLPathingLib::getInstance() != NULL)
+ {
+ LLPathingLib::getInstance()->extractNavMeshSrcFromLLSD(pNavMeshData, mDirection);
+ }
+ }
+
+ mRequestStatus = pNavMeshRequestStatus;
+ mNavMeshStatus = pNavMeshStatus.getStatus();
+ mLocationCallback();
+}
+
+void LLPathfindingNavMeshZone::NavMeshLocation::clear()
+{
+ mHasNavMesh = false;
+ mRequestStatus = LLPathfindingNavMesh::kNavMeshRequestUnknown;
+ mNavMeshStatus = LLPathfindingNavMeshStatus::kComplete;
+ if (mNavMeshSlot.connected())
+ {
+ mNavMeshSlot.disconnect();
+ }
+}
+
+LLViewerRegion *LLPathfindingNavMeshZone::NavMeshLocation::getRegion() const
+{
+ LLViewerRegion *region = NULL;
+
+ LLViewerRegion *currentRegion = gAgent.getRegion();
+ if (currentRegion != NULL)
+ {
+ if (mDirection == CENTER_REGION)
+ {
+ region = currentRegion;
+ }
+ else
+ {
+ //User wants to pull in a neighboring region
+ std::vector<S32> availableRegions;
+ currentRegion->getNeighboringRegionsStatus( availableRegions );
+ //Is the desired region in the available list
+ std::vector<S32>::iterator foundElem = std::find(availableRegions.begin(),availableRegions.end(),mDirection);
+ if ( foundElem != availableRegions.end() )
+ {
+ std::vector<LLViewerRegion*> neighborRegionsPtrs;
+ currentRegion->getNeighboringRegions( neighborRegionsPtrs );
+ region = neighborRegionsPtrs[foundElem - availableRegions.begin()];
+ }
+ }
+ }
+
+ return region;
+}
diff --git a/indra/newview/llpathfindingnavmeshzone.h b/indra/newview/llpathfindingnavmeshzone.h
new file mode 100755
index 0000000000..baa1cc5979
--- /dev/null
+++ b/indra/newview/llpathfindingnavmeshzone.h
@@ -0,0 +1,128 @@
+/**
+* @file llpathfindingnavmeshzone.h
+* @brief Header file for llpathfindingnavmeshzone
+* @author Stinson@lindenlab.com
+*
+* $LicenseInfo:firstyear=2012&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2012, 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_LLPATHFINDINGNAVMESHZONE_H
+#define LL_LLPATHFINDINGNAVMESHZONE_H
+
+#include <vector>
+
+#include <boost/shared_ptr.hpp>
+#include <boost/function.hpp>
+#include <boost/signals2.hpp>
+
+#include "llpathfindingnavmesh.h"
+#include "llpathfindingnavmeshstatus.h"
+#include "llsd.h"
+#include "lluuid.h"
+
+class LLViewerRegion;
+
+class LLPathfindingNavMeshZone
+{
+public:
+ typedef enum {
+ kNavMeshZoneRequestUnknown,
+ kNavMeshZoneRequestWaiting,
+ kNavMeshZoneRequestChecking,
+ kNavMeshZoneRequestNeedsUpdate,
+ kNavMeshZoneRequestStarted,
+ kNavMeshZoneRequestCompleted,
+ kNavMeshZoneRequestNotEnabled,
+ kNavMeshZoneRequestError
+ } ENavMeshZoneRequestStatus;
+
+ typedef enum {
+ kNavMeshZonePending,
+ kNavMeshZoneBuilding,
+ kNavMeshZoneSomePending,
+ kNavMeshZoneSomeBuilding,
+ kNavMeshZonePendingAndBuilding,
+ kNavMeshZoneComplete
+ } ENavMeshZoneStatus;
+
+ typedef boost::function<void (ENavMeshZoneRequestStatus)> navmesh_zone_callback_t;
+ typedef boost::signals2::signal<void (ENavMeshZoneRequestStatus)> navmesh_zone_signal_t;
+ typedef boost::signals2::connection navmesh_zone_slot_t;
+
+ LLPathfindingNavMeshZone();
+ virtual ~LLPathfindingNavMeshZone();
+
+ navmesh_zone_slot_t registerNavMeshZoneListener(navmesh_zone_callback_t pNavMeshZoneCallback);
+ void initialize();
+
+ void enable();
+ void disable();
+ void refresh();
+
+ ENavMeshZoneStatus getNavMeshZoneStatus() const;
+
+protected:
+
+private:
+ typedef boost::function<void (void)> navmesh_location_callback_t;
+ class NavMeshLocation
+ {
+ public:
+ NavMeshLocation(S32 pDirection, navmesh_location_callback_t pLocationCallback);
+ virtual ~NavMeshLocation();
+
+ void enable();
+ void refresh();
+ void disable();
+
+ LLPathfindingNavMesh::ENavMeshRequestStatus getRequestStatus() const;
+ LLPathfindingNavMeshStatus::ENavMeshStatus getNavMeshStatus() const;
+
+ protected:
+
+ private:
+ void handleNavMesh(LLPathfindingNavMesh::ENavMeshRequestStatus pNavMeshRequestStatus, const LLPathfindingNavMeshStatus &pNavMeshStatus, const LLSD::Binary &pNavMeshData);
+
+ void clear();
+ LLViewerRegion *getRegion() const;
+
+ S32 mDirection;
+ LLUUID mRegionUUID;
+ bool mHasNavMesh;
+ U32 mNavMeshVersion;
+ LLPathfindingNavMeshStatus::ENavMeshStatus mNavMeshStatus;
+ navmesh_location_callback_t mLocationCallback;
+ LLPathfindingNavMesh::ENavMeshRequestStatus mRequestStatus;
+ LLPathfindingNavMesh::navmesh_slot_t mNavMeshSlot;
+ };
+
+ typedef boost::shared_ptr<NavMeshLocation> NavMeshLocationPtr;
+ typedef std::vector<NavMeshLocationPtr> NavMeshLocationPtrs;
+
+ void handleNavMeshLocation();
+ void updateStatus();
+
+ NavMeshLocationPtrs mNavMeshLocationPtrs;
+ ENavMeshZoneRequestStatus mNavMeshZoneRequestStatus;
+ navmesh_zone_signal_t mNavMeshZoneSignal;
+};
+
+#endif // LL_LLPATHFINDINGNAVMESHZONE_H
diff --git a/indra/newview/llpathfindingobject.cpp b/indra/newview/llpathfindingobject.cpp
new file mode 100755
index 0000000000..900763eae4
--- /dev/null
+++ b/indra/newview/llpathfindingobject.cpp
@@ -0,0 +1,200 @@
+/**
+* @file llpathfindingobject.cpp
+* @brief Implementation of llpathfindingobject
+* @author Stinson@lindenlab.com
+*
+* $LicenseInfo:firstyear=2012&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2012, 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 "llpathfindingobject.h"
+
+#include <string>
+
+#include "llavatarname.h"
+#include "llavatarnamecache.h"
+#include "llsd.h"
+#include "lluuid.h"
+#include "v3math.h"
+
+#define PATHFINDING_OBJECT_NAME_FIELD "name"
+#define PATHFINDING_OBJECT_DESCRIPTION_FIELD "description"
+#define PATHFINDING_OBJECT_OWNER_FIELD "owner"
+#define PATHFINDING_OBJECT_POSITION_FIELD "position"
+#define PATHFINDING_OBJECT_IS_GROUP_OWNED_FIELD "owner_is_group"
+
+//---------------------------------------------------------------------------
+// LLPathfindingObject
+//---------------------------------------------------------------------------
+
+LLPathfindingObject::LLPathfindingObject()
+ : mUUID(),
+ mName(),
+ mDescription(),
+ mOwnerUUID(),
+ mHasOwnerName(false),
+ mOwnerName(),
+ mAvatarNameCacheConnection(),
+ mIsGroupOwned(false),
+ mLocation(),
+ mOwnerNameSignal()
+{
+}
+
+LLPathfindingObject::LLPathfindingObject(const std::string &pUUID, const LLSD &pObjectData)
+ : mUUID(pUUID),
+ mName(),
+ mDescription(),
+ mOwnerUUID(),
+ mHasOwnerName(false),
+ mOwnerName(),
+ mAvatarNameCacheConnection(),
+ mIsGroupOwned(false),
+ mLocation(),
+ mOwnerNameSignal()
+{
+ parseObjectData(pObjectData);
+}
+
+LLPathfindingObject::LLPathfindingObject(const LLPathfindingObject& pOther)
+ : mUUID(pOther.mUUID),
+ mName(pOther.mName),
+ mDescription(pOther.mDescription),
+ mOwnerUUID(pOther.mOwnerUUID),
+ mHasOwnerName(false),
+ mOwnerName(),
+ mAvatarNameCacheConnection(),
+ mIsGroupOwned(pOther.mIsGroupOwned),
+ mLocation(pOther.mLocation),
+ mOwnerNameSignal()
+{
+ fetchOwnerName();
+}
+
+LLPathfindingObject::~LLPathfindingObject()
+{
+ disconnectAvatarNameCacheConnection();
+}
+
+LLPathfindingObject &LLPathfindingObject::operator =(const LLPathfindingObject& pOther)
+{
+ mUUID = pOther.mUUID;
+ mName = pOther.mName;
+ mDescription = pOther.mDescription;
+ mOwnerUUID = pOther.mOwnerUUID;
+ fetchOwnerName();
+ mIsGroupOwned = pOther.mIsGroupOwned;
+ mLocation = pOther.mLocation;
+
+ return *this;
+}
+
+std::string LLPathfindingObject::getOwnerName() const
+{
+ std::string ownerName;
+
+ if (hasOwner())
+ {
+ ownerName = mOwnerName.getCompleteName();
+ }
+
+ return ownerName;
+}
+
+LLPathfindingObject::name_connection_t LLPathfindingObject::registerOwnerNameListener(name_callback_t pOwnerNameCallback)
+{
+ llassert(hasOwner());
+
+ name_connection_t connection;
+ if (hasOwnerName())
+ {
+ pOwnerNameCallback(this);
+ }
+ else
+ {
+ connection = mOwnerNameSignal.connect(pOwnerNameCallback);
+ }
+
+ return connection;
+}
+
+void LLPathfindingObject::parseObjectData(const LLSD &pObjectData)
+{
+ llassert(pObjectData.has(PATHFINDING_OBJECT_NAME_FIELD));
+ llassert(pObjectData.get(PATHFINDING_OBJECT_NAME_FIELD).isString());
+ mName = pObjectData.get(PATHFINDING_OBJECT_NAME_FIELD).asString();
+
+ llassert(pObjectData.has(PATHFINDING_OBJECT_DESCRIPTION_FIELD));
+ llassert(pObjectData.get(PATHFINDING_OBJECT_DESCRIPTION_FIELD).isString());
+ mDescription = pObjectData.get(PATHFINDING_OBJECT_DESCRIPTION_FIELD).asString();
+
+ llassert(pObjectData.has(PATHFINDING_OBJECT_OWNER_FIELD));
+ llassert(pObjectData.get(PATHFINDING_OBJECT_OWNER_FIELD).isUUID());
+ mOwnerUUID = pObjectData.get(PATHFINDING_OBJECT_OWNER_FIELD).asUUID();
+ fetchOwnerName();
+
+ if (pObjectData.has(PATHFINDING_OBJECT_IS_GROUP_OWNED_FIELD))
+ {
+ llassert(pObjectData.get(PATHFINDING_OBJECT_IS_GROUP_OWNED_FIELD).isBoolean());
+ mIsGroupOwned = pObjectData.get(PATHFINDING_OBJECT_IS_GROUP_OWNED_FIELD).asBoolean();
+ }
+
+ llassert(pObjectData.has(PATHFINDING_OBJECT_POSITION_FIELD));
+ llassert(pObjectData.get(PATHFINDING_OBJECT_POSITION_FIELD).isArray());
+ mLocation.setValue(pObjectData.get(PATHFINDING_OBJECT_POSITION_FIELD));
+}
+
+void LLPathfindingObject::fetchOwnerName()
+{
+ mHasOwnerName = false;
+ if (hasOwner())
+ {
+ mHasOwnerName = LLAvatarNameCache::get(mOwnerUUID, &mOwnerName);
+ if (!mHasOwnerName)
+ {
+ disconnectAvatarNameCacheConnection();
+ mAvatarNameCacheConnection = LLAvatarNameCache::get(mOwnerUUID, boost::bind(&LLPathfindingObject::handleAvatarNameFetch, this, _1, _2));
+ }
+ }
+}
+
+void LLPathfindingObject::handleAvatarNameFetch(const LLUUID &pOwnerUUID, const LLAvatarName &pAvatarName)
+{
+ llassert(mOwnerUUID == pOwnerUUID);
+
+ mOwnerName = pAvatarName;
+ mHasOwnerName = true;
+
+ disconnectAvatarNameCacheConnection();
+
+ mOwnerNameSignal(this);
+}
+
+void LLPathfindingObject::disconnectAvatarNameCacheConnection()
+{
+ if (mAvatarNameCacheConnection.connected())
+ {
+ mAvatarNameCacheConnection.disconnect();
+ }
+}
diff --git a/indra/newview/llpathfindingobject.h b/indra/newview/llpathfindingobject.h
new file mode 100755
index 0000000000..b8d3ca2364
--- /dev/null
+++ b/indra/newview/llpathfindingobject.h
@@ -0,0 +1,92 @@
+/**
+* @file llpathfindingobject.h
+* @brief Header file for llpathfindingobject
+* @author Stinson@lindenlab.com
+*
+* $LicenseInfo:firstyear=2012&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2012, 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_LLPATHFINDINGOBJECT_H
+#define LL_LLPATHFINDINGOBJECT_H
+
+#include <string>
+
+#include <boost/shared_ptr.hpp>
+#include <boost/function.hpp>
+#include <boost/signals2.hpp>
+
+#include "llavatarname.h"
+#include "llavatarnamecache.h"
+#include "lluuid.h"
+#include "v3math.h"
+
+class LLPathfindingObject;
+class LLSD;
+
+typedef boost::shared_ptr<LLPathfindingObject> LLPathfindingObjectPtr;
+
+class LLPathfindingObject
+{
+public:
+ LLPathfindingObject();
+ LLPathfindingObject(const std::string &pUUID, const LLSD &pObjectData);
+ LLPathfindingObject(const LLPathfindingObject& pOther);
+ virtual ~LLPathfindingObject();
+
+ LLPathfindingObject& operator =(const LLPathfindingObject& pOther);
+
+ inline const LLUUID& getUUID() const {return mUUID;};
+ inline const std::string& getName() const {return mName;};
+ inline const std::string& getDescription() const {return mDescription;};
+ inline BOOL hasOwner() const {return mOwnerUUID.notNull();};
+ inline bool hasOwnerName() const {return mHasOwnerName;};
+ std::string getOwnerName() const;
+ inline BOOL isGroupOwned() const {return mIsGroupOwned;};
+ inline const LLVector3& getLocation() const {return mLocation;};
+
+ typedef boost::function<void (const LLPathfindingObject *)> name_callback_t;
+ typedef boost::signals2::signal<void (const LLPathfindingObject *)> name_signal_t;
+ typedef boost::signals2::connection name_connection_t;
+
+ name_connection_t registerOwnerNameListener(name_callback_t pOwnerNameCallback);
+
+protected:
+
+private:
+ void parseObjectData(const LLSD &pObjectData);
+
+ void fetchOwnerName();
+ void handleAvatarNameFetch(const LLUUID &pOwnerUUID, const LLAvatarName &pAvatarName);
+ void disconnectAvatarNameCacheConnection();
+
+ LLUUID mUUID;
+ std::string mName;
+ std::string mDescription;
+ LLUUID mOwnerUUID;
+ bool mHasOwnerName;
+ LLAvatarName mOwnerName;
+ LLAvatarNameCache::callback_connection_t mAvatarNameCacheConnection;
+ BOOL mIsGroupOwned;
+ LLVector3 mLocation;
+ name_signal_t mOwnerNameSignal;
+};
+
+#endif // LL_LLPATHFINDINGOBJECT_H
diff --git a/indra/newview/llpathfindingobjectlist.cpp b/indra/newview/llpathfindingobjectlist.cpp
new file mode 100755
index 0000000000..f1ecb45fc0
--- /dev/null
+++ b/indra/newview/llpathfindingobjectlist.cpp
@@ -0,0 +1,122 @@
+/**
+* @file llpathfindingobjectlist.cpp
+* @brief Implementation of llpathfindingobjectlist
+* @author Stinson@lindenlab.com
+*
+* $LicenseInfo:firstyear=2012&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2012, 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 "llpathfindingobjectlist.h"
+
+#include <string>
+#include <map>
+
+#include "llpathfindingobject.h"
+
+//---------------------------------------------------------------------------
+// LLPathfindingObjectList
+//---------------------------------------------------------------------------
+
+LLPathfindingObjectList::LLPathfindingObjectList()
+ : mObjectMap()
+{
+}
+
+LLPathfindingObjectList::~LLPathfindingObjectList()
+{
+ clear();
+}
+
+bool LLPathfindingObjectList::isEmpty() const
+{
+ return mObjectMap.empty();
+}
+
+void LLPathfindingObjectList::clear()
+{
+ for (LLPathfindingObjectMap::iterator objectIter = mObjectMap.begin(); objectIter != mObjectMap.end(); ++objectIter)
+ {
+ objectIter->second.reset();
+ }
+ mObjectMap.clear();
+}
+
+void LLPathfindingObjectList::update(LLPathfindingObjectPtr pUpdateObjectPtr)
+{
+ if (pUpdateObjectPtr != NULL)
+ {
+ std::string updateObjectId = pUpdateObjectPtr->getUUID().asString();
+
+ LLPathfindingObjectMap::iterator foundObjectIter = mObjectMap.find(updateObjectId);
+ if (foundObjectIter == mObjectMap.end())
+ {
+ mObjectMap.insert(std::pair<std::string, LLPathfindingObjectPtr>(updateObjectId, pUpdateObjectPtr));
+ }
+ else
+ {
+ foundObjectIter->second = pUpdateObjectPtr;
+ }
+ }
+}
+
+void LLPathfindingObjectList::update(LLPathfindingObjectListPtr pUpdateObjectListPtr)
+{
+ if ((pUpdateObjectListPtr != NULL) && !pUpdateObjectListPtr->isEmpty())
+ {
+ for (LLPathfindingObjectMap::const_iterator updateObjectIter = pUpdateObjectListPtr->begin();
+ updateObjectIter != pUpdateObjectListPtr->end(); ++updateObjectIter)
+ {
+ const LLPathfindingObjectPtr updateObjectPtr = updateObjectIter->second;
+ update(updateObjectPtr);
+ }
+ }
+}
+
+LLPathfindingObjectPtr LLPathfindingObjectList::find(const std::string &pObjectId) const
+{
+ LLPathfindingObjectPtr objectPtr;
+
+ LLPathfindingObjectMap::const_iterator objectIter = mObjectMap.find(pObjectId);
+ if (objectIter != mObjectMap.end())
+ {
+ objectPtr = objectIter->second;
+ }
+
+ return objectPtr;
+}
+
+LLPathfindingObjectList::const_iterator LLPathfindingObjectList::begin() const
+{
+ return mObjectMap.begin();
+}
+
+LLPathfindingObjectList::const_iterator LLPathfindingObjectList::end() const
+{
+ return mObjectMap.end();
+}
+
+LLPathfindingObjectMap &LLPathfindingObjectList::getObjectMap()
+{
+ return mObjectMap;
+}
diff --git a/indra/newview/llpathfindingobjectlist.h b/indra/newview/llpathfindingobjectlist.h
new file mode 100755
index 0000000000..61580582d3
--- /dev/null
+++ b/indra/newview/llpathfindingobjectlist.h
@@ -0,0 +1,68 @@
+/**
+* @file llpathfindingobjectlist.h
+* @brief Header file for llpathfindingobjectlist
+* @author Stinson@lindenlab.com
+*
+* $LicenseInfo:firstyear=2012&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2012, 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_LLPATHFINDINGOBJECTLIST_H
+#define LL_LLPATHFINDINGOBJECTLIST_H
+
+#include <string>
+#include <map>
+
+#include <boost/shared_ptr.hpp>
+
+#include "llpathfindingobject.h"
+
+class LLPathfindingObjectList;
+
+typedef boost::shared_ptr<LLPathfindingObjectList> LLPathfindingObjectListPtr;
+typedef std::map<std::string, LLPathfindingObjectPtr> LLPathfindingObjectMap;
+
+class LLPathfindingObjectList
+{
+public:
+ LLPathfindingObjectList();
+ virtual ~LLPathfindingObjectList();
+
+ bool isEmpty() const;
+
+ void clear();
+
+ void update(LLPathfindingObjectPtr pUpdateObjectPtr);
+ void update(LLPathfindingObjectListPtr pUpdateObjectListPtr);
+
+ LLPathfindingObjectPtr find(const std::string &pObjectId) const;
+
+ typedef LLPathfindingObjectMap::const_iterator const_iterator;
+ const_iterator begin() const;
+ const_iterator end() const;
+
+protected:
+ LLPathfindingObjectMap &getObjectMap();
+
+private:
+ LLPathfindingObjectMap mObjectMap;
+};
+
+#endif // LL_LLPATHFINDINGOBJECTLIST_H
diff --git a/indra/newview/llpathfindingpathtool.cpp b/indra/newview/llpathfindingpathtool.cpp
new file mode 100755
index 0000000000..006755e20b
--- /dev/null
+++ b/indra/newview/llpathfindingpathtool.cpp
@@ -0,0 +1,467 @@
+/**
+* @file llpathfindingpathtool.cpp
+* @brief Implementation of llpathfindingpathtool
+* @author Stinson@lindenlab.com
+*
+* $LicenseInfo:firstyear=2012&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2012, 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 "llpathfindingpathtool.h"
+
+#include <boost/function.hpp>
+#include <boost/signals2.hpp>
+
+#include "llagent.h"
+#include "llpathfindingmanager.h"
+#include "llpathinglib.h"
+#include "llsingleton.h"
+#include "lltool.h"
+#include "llviewercamera.h"
+#include "llviewerregion.h"
+#include "llviewerwindow.h"
+
+#define PATH_TOOL_NAME "PathfindingPathTool"
+
+LLPathfindingPathTool::LLPathfindingPathTool()
+ : LLTool(PATH_TOOL_NAME),
+ LLSingleton<LLPathfindingPathTool>(),
+ mFinalPathData(),
+ mTempPathData(),
+ mPathResult(LLPathingLib::LLPL_NO_PATH),
+ mCharacterType(kCharacterTypeNone),
+ mPathEventSignal(),
+ mIsLeftMouseButtonHeld(false),
+ mIsMiddleMouseButtonHeld(false),
+ mIsRightMouseButtonHeld(false)
+{
+ setCharacterWidth(1.0f);
+ setCharacterType(mCharacterType);
+}
+
+LLPathfindingPathTool::~LLPathfindingPathTool()
+{
+}
+
+BOOL LLPathfindingPathTool::handleMouseDown(S32 pX, S32 pY, MASK pMask)
+{
+ BOOL returnVal = FALSE;
+
+ if (!mIsLeftMouseButtonHeld && !mIsMiddleMouseButtonHeld && !mIsRightMouseButtonHeld)
+ {
+ if (isAnyPathToolModKeys(pMask))
+ {
+ gViewerWindow->setCursor(isPointAModKeys(pMask)
+ ? UI_CURSOR_TOOLPATHFINDING_PATH_START_ADD
+ : UI_CURSOR_TOOLPATHFINDING_PATH_END_ADD);
+ computeFinalPoints(pX, pY, pMask);
+ mIsLeftMouseButtonHeld = true;
+ setMouseCapture(TRUE);
+ returnVal = TRUE;
+ }
+ else if (!isCameraModKeys(pMask))
+ {
+ gViewerWindow->setCursor(UI_CURSOR_TOOLNO);
+ mIsLeftMouseButtonHeld = true;
+ setMouseCapture(TRUE);
+ returnVal = TRUE;
+ }
+ }
+ mIsLeftMouseButtonHeld = true;
+
+ return returnVal;
+}
+
+BOOL LLPathfindingPathTool::handleMouseUp(S32 pX, S32 pY, MASK pMask)
+{
+ BOOL returnVal = FALSE;
+
+ if (mIsLeftMouseButtonHeld && !mIsMiddleMouseButtonHeld && !mIsRightMouseButtonHeld)
+ {
+ computeFinalPoints(pX, pY, pMask);
+ setMouseCapture(FALSE);
+ returnVal = TRUE;
+ }
+ mIsLeftMouseButtonHeld = false;
+
+ return returnVal;
+}
+
+BOOL LLPathfindingPathTool::handleMiddleMouseDown(S32 pX, S32 pY, MASK pMask)
+{
+ setMouseCapture(TRUE);
+ mIsMiddleMouseButtonHeld = true;
+ gViewerWindow->setCursor(UI_CURSOR_TOOLNO);
+
+ return TRUE;
+}
+
+BOOL LLPathfindingPathTool::handleMiddleMouseUp(S32 pX, S32 pY, MASK pMask)
+{
+ if (!mIsLeftMouseButtonHeld && mIsMiddleMouseButtonHeld && !mIsRightMouseButtonHeld)
+ {
+ setMouseCapture(FALSE);
+ }
+ mIsMiddleMouseButtonHeld = false;
+
+ return TRUE;
+}
+
+BOOL LLPathfindingPathTool::handleRightMouseDown(S32 pX, S32 pY, MASK pMask)
+{
+ setMouseCapture(TRUE);
+ mIsRightMouseButtonHeld = true;
+ gViewerWindow->setCursor(UI_CURSOR_TOOLNO);
+
+ return TRUE;
+}
+
+BOOL LLPathfindingPathTool::handleRightMouseUp(S32 pX, S32 pY, MASK pMask)
+{
+ if (!mIsLeftMouseButtonHeld && !mIsMiddleMouseButtonHeld && mIsRightMouseButtonHeld)
+ {
+ setMouseCapture(FALSE);
+ }
+ mIsRightMouseButtonHeld = false;
+
+ return TRUE;
+}
+
+BOOL LLPathfindingPathTool::handleDoubleClick(S32 pX, S32 pY, MASK pMask)
+{
+ return TRUE;
+}
+
+BOOL LLPathfindingPathTool::handleHover(S32 pX, S32 pY, MASK pMask)
+{
+ BOOL returnVal = FALSE;
+
+ if (!mIsLeftMouseButtonHeld && !mIsMiddleMouseButtonHeld && !mIsRightMouseButtonHeld && !isAnyPathToolModKeys(pMask))
+ {
+ gViewerWindow->setCursor(UI_CURSOR_TOOLPATHFINDING);
+ }
+
+ if (!mIsMiddleMouseButtonHeld && !mIsRightMouseButtonHeld && isAnyPathToolModKeys(pMask))
+ {
+ gViewerWindow->setCursor(isPointAModKeys(pMask)
+ ? (mIsLeftMouseButtonHeld ? UI_CURSOR_TOOLPATHFINDING_PATH_START_ADD : UI_CURSOR_TOOLPATHFINDING_PATH_START)
+ : (mIsLeftMouseButtonHeld ? UI_CURSOR_TOOLPATHFINDING_PATH_END_ADD : UI_CURSOR_TOOLPATHFINDING_PATH_END));
+ computeTempPoints(pX, pY, pMask);
+ returnVal = TRUE;
+ }
+ else
+ {
+ clearTemp();
+ computeFinalPath();
+ }
+
+ return returnVal;
+}
+
+BOOL LLPathfindingPathTool::handleKey(KEY pKey, MASK pMask)
+{
+ // Eat the escape key or else the camera tool will pick up and reset to default view. This,
+ // in turn, will cause some other methods to get called. And one of those methods will reset
+ // the current toolset back to the basic toolset. This means that the pathfinding path toolset
+ // will no longer be active, but typically with pathfinding path elements on screen.
+ return (pKey == KEY_ESCAPE);
+}
+
+LLPathfindingPathTool::EPathStatus LLPathfindingPathTool::getPathStatus() const
+{
+ EPathStatus status = kPathStatusUnknown;
+
+ if (LLPathingLib::getInstance() == NULL)
+ {
+ status = kPathStatusNotImplemented;
+ }
+ else if ((gAgent.getRegion() != NULL) && !gAgent.getRegion()->capabilitiesReceived())
+ {
+ status = kPathStatusUnknown;
+ }
+ else if (!LLPathfindingManager::getInstance()->isPathfindingEnabledForCurrentRegion())
+ {
+ status = kPathStatusNotEnabled;
+ }
+ else if (!hasFinalA() && !hasFinalB())
+ {
+ status = kPathStatusChooseStartAndEndPoints;
+ }
+ else if (!hasFinalA())
+ {
+ status = kPathStatusChooseStartPoint;
+ }
+ else if (!hasFinalB())
+ {
+ status = kPathStatusChooseEndPoint;
+ }
+ else if (mPathResult == LLPathingLib::LLPL_PATH_GENERATED_OK)
+ {
+ status = kPathStatusHasValidPath;
+ }
+ else if (mPathResult == LLPathingLib::LLPL_NO_PATH)
+ {
+ status = kPathStatusHasInvalidPath;
+ }
+ else
+ {
+ status = kPathStatusError;
+ }
+
+ return status;
+}
+
+F32 LLPathfindingPathTool::getCharacterWidth() const
+{
+ return mFinalPathData.mCharacterWidth;
+}
+
+void LLPathfindingPathTool::setCharacterWidth(F32 pCharacterWidth)
+{
+ mFinalPathData.mCharacterWidth = pCharacterWidth;
+ mTempPathData.mCharacterWidth = pCharacterWidth;
+ computeFinalPath();
+}
+
+LLPathfindingPathTool::ECharacterType LLPathfindingPathTool::getCharacterType() const
+{
+ return mCharacterType;
+}
+
+void LLPathfindingPathTool::setCharacterType(ECharacterType pCharacterType)
+{
+ mCharacterType = pCharacterType;
+
+ LLPathingLib::LLPLCharacterType characterType;
+ switch (pCharacterType)
+ {
+ case kCharacterTypeNone :
+ characterType = LLPathingLib::LLPL_CHARACTER_TYPE_NONE;
+ break;
+ case kCharacterTypeA :
+ characterType = LLPathingLib::LLPL_CHARACTER_TYPE_A;
+ break;
+ case kCharacterTypeB :
+ characterType = LLPathingLib::LLPL_CHARACTER_TYPE_B;
+ break;
+ case kCharacterTypeC :
+ characterType = LLPathingLib::LLPL_CHARACTER_TYPE_C;
+ break;
+ case kCharacterTypeD :
+ characterType = LLPathingLib::LLPL_CHARACTER_TYPE_D;
+ break;
+ default :
+ characterType = LLPathingLib::LLPL_CHARACTER_TYPE_NONE;
+ llassert(0);
+ break;
+ }
+ mFinalPathData.mCharacterType = characterType;
+ mTempPathData.mCharacterType = characterType;
+ computeFinalPath();
+}
+
+bool LLPathfindingPathTool::isRenderPath() const
+{
+ return (hasFinalA() || hasFinalB() || hasTempA() || hasTempB());
+}
+
+void LLPathfindingPathTool::clearPath()
+{
+ clearFinal();
+ clearTemp();
+ computeFinalPath();
+}
+
+LLPathfindingPathTool::path_event_slot_t LLPathfindingPathTool::registerPathEventListener(path_event_callback_t pPathEventCallback)
+{
+ return mPathEventSignal.connect(pPathEventCallback);
+}
+
+bool LLPathfindingPathTool::isAnyPathToolModKeys(MASK pMask) const
+{
+ return ((pMask & (MASK_CONTROL|MASK_SHIFT)) != 0);
+}
+
+bool LLPathfindingPathTool::isPointAModKeys(MASK pMask) const
+{
+ return ((pMask & MASK_CONTROL) != 0);
+}
+
+bool LLPathfindingPathTool::isPointBModKeys(MASK pMask) const
+{
+ return ((pMask & MASK_SHIFT) != 0);
+}
+
+bool LLPathfindingPathTool::isCameraModKeys(MASK pMask) const
+{
+ return ((pMask & MASK_ALT) != 0);
+}
+
+void LLPathfindingPathTool::getRayPoints(S32 pX, S32 pY, LLVector3 &pRayStart, LLVector3 &pRayEnd) const
+{
+ LLVector3 dv = gViewerWindow->mouseDirectionGlobal(pX, pY);
+ LLVector3 mousePos = LLViewerCamera::getInstance()->getOrigin();
+ pRayStart = mousePos;
+ pRayEnd = mousePos + dv * 150;
+}
+
+void LLPathfindingPathTool::computeFinalPoints(S32 pX, S32 pY, MASK pMask)
+{
+ LLVector3 rayStart, rayEnd;
+ getRayPoints(pX, pY, rayStart, rayEnd);
+
+ if (isPointAModKeys(pMask))
+ {
+ setFinalA(rayStart, rayEnd);
+ }
+ else if (isPointBModKeys(pMask))
+ {
+ setFinalB(rayStart, rayEnd);
+ }
+ computeFinalPath();
+}
+
+void LLPathfindingPathTool::computeTempPoints(S32 pX, S32 pY, MASK pMask)
+{
+ LLVector3 rayStart, rayEnd;
+ getRayPoints(pX, pY, rayStart, rayEnd);
+
+ if (isPointAModKeys(pMask))
+ {
+ setTempA(rayStart, rayEnd);
+ if (hasFinalB())
+ {
+ setTempB(getFinalBStart(), getFinalBEnd());
+ }
+ }
+ else if (isPointBModKeys(pMask))
+ {
+ if (hasFinalA())
+ {
+ setTempA(getFinalAStart(), getFinalAEnd());
+ }
+ setTempB(rayStart, rayEnd);
+ }
+ computeTempPath();
+}
+
+void LLPathfindingPathTool::setFinalA(const LLVector3 &pStartPoint, const LLVector3 &pEndPoint)
+{
+ mFinalPathData.mStartPointA = pStartPoint;
+ mFinalPathData.mEndPointA = pEndPoint;
+ mFinalPathData.mHasPointA = true;
+}
+
+bool LLPathfindingPathTool::hasFinalA() const
+{
+ return mFinalPathData.mHasPointA;
+}
+
+const LLVector3 &LLPathfindingPathTool::getFinalAStart() const
+{
+ return mFinalPathData.mStartPointA;
+}
+
+const LLVector3 &LLPathfindingPathTool::getFinalAEnd() const
+{
+ return mFinalPathData.mEndPointA;
+}
+
+void LLPathfindingPathTool::setTempA(const LLVector3 &pStartPoint, const LLVector3 &pEndPoint)
+{
+ mTempPathData.mStartPointA = pStartPoint;
+ mTempPathData.mEndPointA = pEndPoint;
+ mTempPathData.mHasPointA = true;
+}
+
+bool LLPathfindingPathTool::hasTempA() const
+{
+ return mTempPathData.mHasPointA;
+}
+
+void LLPathfindingPathTool::setFinalB(const LLVector3 &pStartPoint, const LLVector3 &pEndPoint)
+{
+ mFinalPathData.mStartPointB = pStartPoint;
+ mFinalPathData.mEndPointB = pEndPoint;
+ mFinalPathData.mHasPointB = true;
+}
+
+bool LLPathfindingPathTool::hasFinalB() const
+{
+ return mFinalPathData.mHasPointB;
+}
+
+const LLVector3 &LLPathfindingPathTool::getFinalBStart() const
+{
+ return mFinalPathData.mStartPointB;
+}
+
+const LLVector3 &LLPathfindingPathTool::getFinalBEnd() const
+{
+ return mFinalPathData.mEndPointB;
+}
+
+void LLPathfindingPathTool::setTempB(const LLVector3 &pStartPoint, const LLVector3 &pEndPoint)
+{
+ mTempPathData.mStartPointB = pStartPoint;
+ mTempPathData.mEndPointB = pEndPoint;
+ mTempPathData.mHasPointB = true;
+}
+
+bool LLPathfindingPathTool::hasTempB() const
+{
+ return mTempPathData.mHasPointB;
+}
+
+void LLPathfindingPathTool::clearFinal()
+{
+ mFinalPathData.mHasPointA = false;
+ mFinalPathData.mHasPointB = false;
+}
+
+void LLPathfindingPathTool::clearTemp()
+{
+ mTempPathData.mHasPointA = false;
+ mTempPathData.mHasPointB = false;
+}
+
+void LLPathfindingPathTool::computeFinalPath()
+{
+ mPathResult = LLPathingLib::LLPL_NO_PATH;
+ if (LLPathingLib::getInstance() != NULL)
+ {
+ mPathResult = LLPathingLib::getInstance()->generatePath(mFinalPathData);
+ }
+ mPathEventSignal();
+}
+
+void LLPathfindingPathTool::computeTempPath()
+{
+ mPathResult = LLPathingLib::LLPL_NO_PATH;
+ if (LLPathingLib::getInstance() != NULL)
+ {
+ mPathResult = LLPathingLib::getInstance()->generatePath(mTempPathData);
+ }
+ mPathEventSignal();
+}
diff --git a/indra/newview/llpathfindingpathtool.h b/indra/newview/llpathfindingpathtool.h
new file mode 100755
index 0000000000..97284265f1
--- /dev/null
+++ b/indra/newview/llpathfindingpathtool.h
@@ -0,0 +1,138 @@
+/**
+* @file llpathfindingpathtool.h
+* @brief Header file for llpathfindingpathtool
+* @author Stinson@lindenlab.com
+*
+* $LicenseInfo:firstyear=2012&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2012, 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_LLPATHFINDINGPATHTOOL_H
+#define LL_LLPATHFINDINGPATHTOOL_H
+
+#include <boost/function.hpp>
+#include <boost/signals2.hpp>
+
+#include "llpathinglib.h"
+#include "llsingleton.h"
+#include "lltool.h"
+
+class LLPathfindingPathTool : public LLTool, public LLSingleton<LLPathfindingPathTool>
+{
+public:
+ typedef enum
+ {
+ kPathStatusUnknown,
+ kPathStatusChooseStartAndEndPoints,
+ kPathStatusChooseStartPoint,
+ kPathStatusChooseEndPoint,
+ kPathStatusHasValidPath,
+ kPathStatusHasInvalidPath,
+ kPathStatusNotEnabled,
+ kPathStatusNotImplemented,
+ kPathStatusError
+ } EPathStatus;
+
+ typedef enum
+ {
+ kCharacterTypeNone,
+ kCharacterTypeA,
+ kCharacterTypeB,
+ kCharacterTypeC,
+ kCharacterTypeD
+ } ECharacterType;
+
+ LLPathfindingPathTool();
+ virtual ~LLPathfindingPathTool();
+
+ typedef boost::function<void (void)> path_event_callback_t;
+ typedef boost::signals2::signal<void (void)> path_event_signal_t;
+ typedef boost::signals2::connection path_event_slot_t;
+
+ virtual BOOL handleMouseDown(S32 pX, S32 pY, MASK pMask);
+ virtual BOOL handleMouseUp(S32 pX, S32 pY, MASK pMask);
+ virtual BOOL handleMiddleMouseDown(S32 pX, S32 pY, MASK pMask);
+ virtual BOOL handleMiddleMouseUp(S32 pX, S32 pY, MASK pMask);
+ virtual BOOL handleRightMouseDown(S32 pX, S32 pY, MASK pMask);
+ virtual BOOL handleRightMouseUp(S32 pX, S32 pY, MASK pMask);
+ virtual BOOL handleDoubleClick(S32 x, S32 y, MASK mask);
+
+ virtual BOOL handleHover(S32 pX, S32 pY, MASK pMask);
+
+ virtual BOOL handleKey(KEY pKey, MASK pMask);
+
+ EPathStatus getPathStatus() const;
+
+ F32 getCharacterWidth() const;
+ void setCharacterWidth(F32 pCharacterWidth);
+
+ ECharacterType getCharacterType() const;
+ void setCharacterType(ECharacterType pCharacterType);
+
+ bool isRenderPath() const;
+ void clearPath();
+
+ path_event_slot_t registerPathEventListener(path_event_callback_t pPathEventCallback);
+
+protected:
+
+private:
+ bool isAnyPathToolModKeys(MASK pMask) const;
+ bool isPointAModKeys(MASK pMask) const;
+ bool isPointBModKeys(MASK pMask) const;
+ bool isCameraModKeys(MASK pMask) const;
+
+ void getRayPoints(S32 pX, S32 pY, LLVector3 &pRayStart, LLVector3 &pRayEnd) const;
+ void computeFinalPoints(S32 pX, S32 pY, MASK pMask);
+ void computeTempPoints(S32 pX, S32 pY, MASK pMask);
+
+ void setFinalA(const LLVector3 &pStartPoint, const LLVector3 &pEndPoint);
+ bool hasFinalA() const;
+ const LLVector3 &getFinalAStart() const;
+ const LLVector3 &getFinalAEnd() const;
+
+ void setTempA(const LLVector3 &pStartPoint, const LLVector3 &pEndPoint);
+ bool hasTempA() const;
+
+ void setFinalB(const LLVector3 &pStartPoint, const LLVector3 &pEndPoint);
+ bool hasFinalB() const;
+ const LLVector3 &getFinalBStart() const;
+ const LLVector3 &getFinalBEnd() const;
+
+ void setTempB(const LLVector3 &pStartPoint, const LLVector3 &pEndPoint);
+ bool hasTempB() const;
+
+ void clearFinal();
+ void clearTemp();
+
+ void computeFinalPath();
+ void computeTempPath();
+
+ LLPathingLib::PathingPacket mFinalPathData;
+ LLPathingLib::PathingPacket mTempPathData;
+ LLPathingLib::LLPLResult mPathResult;
+ ECharacterType mCharacterType;
+ path_event_signal_t mPathEventSignal;
+ bool mIsLeftMouseButtonHeld;
+ bool mIsMiddleMouseButtonHeld;
+ bool mIsRightMouseButtonHeld;
+};
+
+#endif // LL_LLPATHFINDINGPATHTOOL_H
diff --git a/indra/newview/llpersistentnotificationstorage.cpp b/indra/newview/llpersistentnotificationstorage.cpp
new file mode 100755
index 0000000000..d8fc2bee32
--- /dev/null
+++ b/indra/newview/llpersistentnotificationstorage.cpp
@@ -0,0 +1,182 @@
+/**
+* @file llpersistentnotificationstorage.cpp
+* @brief Implementation of llpersistentnotificationstorage
+* @author Stinson@lindenlab.com
+*
+* $LicenseInfo:firstyear=2012&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2012, 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 "llpersistentnotificationstorage.h"
+
+#include "llchannelmanager.h"
+#include "llnotificationstorage.h"
+#include "llscreenchannel.h"
+#include "llscriptfloater.h"
+#include "llviewermessage.h"
+
+LLPersistentNotificationStorage::LLPersistentNotificationStorage()
+ : LLSingleton<LLPersistentNotificationStorage>()
+ , LLNotificationStorage("")
+ , mLoaded(false)
+{
+}
+
+LLPersistentNotificationStorage::~LLPersistentNotificationStorage()
+{
+}
+
+static LLFastTimer::DeclareTimer FTM_SAVE_NOTIFICATIONS("Save Notifications");
+
+void LLPersistentNotificationStorage::saveNotifications()
+{
+ LLFastTimer _(FTM_SAVE_NOTIFICATIONS);
+
+ boost::intrusive_ptr<LLPersistentNotificationChannel> history_channel = boost::dynamic_pointer_cast<LLPersistentNotificationChannel>(LLNotifications::instance().getChannel("Persistent"));
+ if (!history_channel)
+ {
+ return;
+ }
+
+ LLSD output = LLSD::emptyMap();
+ LLSD& data = output["data"];
+
+ for ( std::vector<LLNotificationPtr>::iterator it = history_channel->beginHistory(), end_it = history_channel->endHistory();
+ it != end_it;
+ ++it)
+ {
+ LLNotificationPtr notification = *it;
+
+ // After a notification was placed in Persist channel, it can become
+ // responded, expired or canceled - in this case we are should not save it
+ if(notification->isRespondedTo() || notification->isCancelled()
+ || notification->isExpired())
+ {
+ continue;
+ }
+
+ data.append(notification->asLLSD(true));
+ if (data.size() >= gSavedSettings.getS32("MaxPersistentNotifications"))
+ {
+ llwarns << "Too many persistent notifications."
+ << " Saved " << gSavedSettings.getS32("MaxPersistentNotifications") << " of " << history_channel->size()
+ << " persistent notifications." << llendl;
+ break;
+ }
+
+ }
+
+ writeNotifications(output);
+}
+
+static LLFastTimer::DeclareTimer FTM_LOAD_NOTIFICATIONS("Load Notifications");
+
+void LLPersistentNotificationStorage::loadNotifications()
+{
+ LLFastTimer _(FTM_LOAD_NOTIFICATIONS);
+
+ LL_INFOS("LLPersistentNotificationStorage") << "start loading notifications" << LL_ENDL;
+
+ if (mLoaded)
+ {
+ LL_INFOS("LLPersistentNotificationStorage") << "notifications already loaded, exiting" << LL_ENDL;
+ return;
+ }
+
+ mLoaded = true;
+ LLSD input;
+ if (!readNotifications(input) ||input.isUndefined())
+ {
+ return;
+ }
+
+ LLSD& data = input["data"];
+ if (data.isUndefined())
+ {
+ return;
+ }
+
+ using namespace LLNotificationsUI;
+ LLScreenChannel* notification_channel = dynamic_cast<LLScreenChannel*>(LLChannelManager::getInstance()->
+ findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID"))));
+
+ LLNotifications& instance = LLNotifications::instance();
+ S32 processed_notifications = 0;
+ for (LLSD::reverse_array_iterator notification_it = data.rbeginArray();
+ notification_it != data.rendArray();
+ ++notification_it)
+ {
+ LLSD notification_params = *notification_it;
+ LLNotificationPtr notification(new LLNotification(notification_params));
+
+ LLNotificationResponderPtr responder(createResponder(notification_params["name"], notification_params["responder"]));
+ notification->setResponseFunctor(responder);
+
+ instance.add(notification);
+
+ // hide script floaters so they don't confuse the user and don't overlap startup toast
+ LLScriptFloaterManager::getInstance()->setFloaterVisible(notification->getID(), false);
+
+ if(notification_channel)
+ {
+ // hide saved toasts so they don't confuse the user
+ notification_channel->hideToast(notification->getID());
+ }
+ ++processed_notifications;
+ if (processed_notifications >= gSavedSettings.getS32("MaxPersistentNotifications"))
+ {
+ llwarns << "Too many persistent notifications."
+ << " Processed " << gSavedSettings.getS32("MaxPersistentNotifications") << " of " << data.size() << " persistent notifications." << llendl;
+ break;
+ }
+ }
+ LLNotifications::instance().getChannel("Persistent")->
+ connectChanged(boost::bind(&LLPersistentNotificationStorage::onPersistentChannelChanged, this, _1));
+ LL_INFOS("LLPersistentNotificationStorage") << "finished loading notifications" << LL_ENDL;
+}
+
+void LLPersistentNotificationStorage::initialize()
+{
+ setFileName(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "open_notifications.xml"));
+ LLNotifications::instance().getChannel("Persistent")->
+ connectChanged(boost::bind(&LLPersistentNotificationStorage::onPersistentChannelChanged, this, _1));
+}
+
+bool LLPersistentNotificationStorage::onPersistentChannelChanged(const LLSD& payload)
+{
+ // In case we received channel changed signal but haven't yet loaded notifications, do it
+ if (!mLoaded)
+ {
+ loadNotifications();
+ }
+ // we ignore "load" messages, but rewrite the persistence file on any other
+ const std::string sigtype = payload["sigtype"].asString();
+ if ("load" != sigtype)
+ {
+ saveNotifications();
+ }
+ return false;
+}
+
+// EOF
diff --git a/indra/newview/llpersistentnotificationstorage.h b/indra/newview/llpersistentnotificationstorage.h
new file mode 100755
index 0000000000..bf0306380e
--- /dev/null
+++ b/indra/newview/llpersistentnotificationstorage.h
@@ -0,0 +1,66 @@
+/**
+* @file llpersistentnotificationstorage.h
+* @brief Header file for llpersistentnotificationstorage
+* @author Stinson@lindenlab.com
+*
+* $LicenseInfo:firstyear=2012&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2012, 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_LLPERSISTENTNOTIFICATIONSTORAGE_H
+#define LL_LLPERSISTENTNOTIFICATIONSTORAGE_H
+
+#include "llerror.h"
+#include "llnotificationstorage.h"
+#include "llsingleton.h"
+
+class LLSD;
+
+// Class that saves not responded(unread) notifications.
+// Unread notifications are saved in open_notifications.xml in SL account folder
+//
+// Notifications that should be saved(if unread) are marked with persist="true" in notifications.xml
+// Notifications using functor responders are saved automatically (see llviewermessage.cpp
+// lure_callback_reg for example).
+// Notifications using object responders(LLOfferInfo) need additional tuning. Responder object should
+// be a) serializable(implement LLNotificationResponderInterface),
+// b) registered with LLResponderRegistry (found in llpersistentnotificationstorage.cpp).
+
+class LLPersistentNotificationStorage : public LLSingleton<LLPersistentNotificationStorage>, public LLNotificationStorage
+{
+ LOG_CLASS(LLPersistentNotificationStorage);
+public:
+ LLPersistentNotificationStorage();
+ ~LLPersistentNotificationStorage();
+
+ void saveNotifications();
+ void loadNotifications();
+
+ void initialize();
+
+protected:
+
+private:
+ bool onPersistentChannelChanged(const LLSD& payload);
+ bool mLoaded;
+};
+
+#endif // LL_LLPERSISTENTNOTIFICATIONSTORAGE_H
+
diff --git a/indra/newview/llphysicsmotion.cpp b/indra/newview/llphysicsmotion.cpp
index e124916c48..18b85cc9c3 100644..100755
--- a/indra/newview/llphysicsmotion.cpp
+++ b/indra/newview/llphysicsmotion.cpp
@@ -67,6 +67,19 @@ inline F64 llsgn(const F64 a)
class LLPhysicsMotion
{
public:
+ typedef enum
+ {
+ SMOOTHING = 0,
+ MASS,
+ GRAVITY,
+ SPRING,
+ GAIN,
+ DAMPING,
+ DRAG,
+ MAX_EFFECT,
+ NUM_PARAMS
+ } eParamName;
+
/*
param_driver_name: The param that controls the params that are being affected by the physics.
joint_name: The joint that the body part is attached to. The joint is
@@ -98,6 +111,11 @@ public:
mPositionLastUpdate_local(0)
{
mJointState = new LLJointState;
+
+ for (U32 i = 0; i < NUM_PARAMS; ++i)
+ {
+ mParamCache[i] = NULL;
+ }
}
BOOL initialize();
@@ -111,17 +129,44 @@ public:
return mJointState;
}
protected:
- F32 getParamValue(const std::string& controller_key)
- {
- const controller_map_t::const_iterator& entry = mParamControllers.find(controller_key);
+
+ F32 getParamValue(eParamName param)
+ {
+ static std::string controller_key[] =
+ {
+ "Smoothing",
+ "Mass",
+ "Gravity",
+ "Spring",
+ "Gain",
+ "Damping",
+ "Drag",
+ "MaxEffect"
+ };
+
+ if (!mParamCache[param])
+ {
+ const controller_map_t::const_iterator& entry = mParamControllers.find(controller_key[param]);
if (entry == mParamControllers.end())
{
- return sDefaultController[controller_key];
+ return sDefaultController[controller_key[param]];
}
const std::string& param_name = (*entry).second.c_str();
- return mCharacter->getVisualParamWeight(param_name.c_str());
- }
- void setParamValue(LLViewerVisualParam *param,
+ mParamCache[param] = mCharacter->getVisualParam(param_name.c_str());
+ }
+
+ if (mParamCache[param])
+ {
+ return mParamCache[param]->getWeight();
+ }
+ else
+ {
+ return sDefaultController[controller_key[param]];
+ }
+ }
+
+
+ void setParamValue(const LLViewerVisualParam *param,
const F32 new_value_local,
F32 behavior_maxeffect);
@@ -150,6 +195,8 @@ private:
F32 mLastTime;
+ LLVisualParam* mParamCache[NUM_PARAMS];
+
static default_controller_map_t sDefaultController;
};
@@ -383,7 +430,6 @@ F32 LLPhysicsMotion::calculateVelocity_local()
const F32 world_to_model_scale = 100.0f;
LLJoint *joint = mJointState->getJoint();
const LLVector3 position_world = joint->getWorldPosition();
- const LLQuaternion rotation_world = joint->getWorldRotation();
const LLVector3 last_position_world = mPosition_world;
const LLVector3 positionchange_world = (position_world-last_position_world) * world_to_model_scale;
const LLVector3 velocity_world = positionchange_world;
@@ -427,7 +473,6 @@ BOOL LLPhysicsMotionController::onUpdate(F32 time, U8* joint_mask)
return TRUE;
}
-
// Return TRUE if character has to update visual params.
BOOL LLPhysicsMotion::onUpdate(F32 time)
{
@@ -471,15 +516,16 @@ BOOL LLPhysicsMotion::onUpdate(F32 time)
LLJoint *joint = mJointState->getJoint();
- const F32 behavior_mass = getParamValue("Mass");
- const F32 behavior_gravity = getParamValue("Gravity");
- const F32 behavior_spring = getParamValue("Spring");
- const F32 behavior_gain = getParamValue("Gain");
- const F32 behavior_damping = getParamValue("Damping");
- const F32 behavior_drag = getParamValue("Drag");
- const BOOL physics_test = FALSE; // Enable this to simulate bouncing on all parts.
+ const F32 behavior_mass = getParamValue(MASS);
+ const F32 behavior_gravity = getParamValue(GRAVITY);
+ const F32 behavior_spring = getParamValue(SPRING);
+ const F32 behavior_gain = getParamValue(GAIN);
+ const F32 behavior_damping = getParamValue(DAMPING);
+ const F32 behavior_drag = getParamValue(DRAG);
+ F32 behavior_maxeffect = getParamValue(MAX_EFFECT);
+
+ const BOOL physics_test = FALSE; // Enable this to simulate bouncing on all parts.
- F32 behavior_maxeffect = getParamValue("MaxEffect");
if (physics_test)
behavior_maxeffect = 1.0f;
@@ -626,12 +672,10 @@ BOOL LLPhysicsMotion::onUpdate(F32 time)
0,
FALSE);
}
- for (LLDriverParam::entry_list_t::iterator iter = driver_param->mDriven.begin();
- iter != driver_param->mDriven.end();
- ++iter)
+ S32 num_driven = driver_param->getDrivenParamsCount();
+ for (S32 i = 0; i < num_driven; ++i)
{
- LLDrivenEntry &entry = (*iter);
- LLViewerVisualParam *driven_param = entry.mParam;
+ const LLViewerVisualParam *driven_param = driver_param->getDrivenParam(i);
setParamValue(driven_param,position_new_local_clamped, behavior_maxeffect);
}
}
@@ -711,7 +755,7 @@ BOOL LLPhysicsMotion::onUpdate(F32 time)
}
// Range of new_value_local is assumed to be [0 , 1] normalized.
-void LLPhysicsMotion::setParamValue(LLViewerVisualParam *param,
+void LLPhysicsMotion::setParamValue(const LLViewerVisualParam *param,
F32 new_value_normalized,
F32 behavior_maxeffect)
{
diff --git a/indra/newview/llphysicsmotion.h b/indra/newview/llphysicsmotion.h
index b246fa99bb..b246fa99bb 100644..100755
--- a/indra/newview/llphysicsmotion.h
+++ b/indra/newview/llphysicsmotion.h
diff --git a/indra/newview/llphysicsshapebuilderutil.cpp b/indra/newview/llphysicsshapebuilderutil.cpp
index 5bfe5c9941..5bfe5c9941 100644..100755
--- a/indra/newview/llphysicsshapebuilderutil.cpp
+++ b/indra/newview/llphysicsshapebuilderutil.cpp
diff --git a/indra/newview/llphysicsshapebuilderutil.h b/indra/newview/llphysicsshapebuilderutil.h
index 7dedfb05e2..7dedfb05e2 100644..100755
--- a/indra/newview/llphysicsshapebuilderutil.h
+++ b/indra/newview/llphysicsshapebuilderutil.h
diff --git a/indra/newview/llpipelinelistener.cpp b/indra/newview/llpipelinelistener.cpp
new file mode 100644
index 0000000000..20759239bf
--- /dev/null
+++ b/indra/newview/llpipelinelistener.cpp
@@ -0,0 +1,216 @@
+/**
+ * @file llpipelinelistener.h
+ * @author Don Kjer
+ * @date 2012-07-09
+ * @brief Implementation for LLPipelineListener
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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$
+ */
+
+// Precompiled header
+#include "llviewerprecompiledheaders.h"
+
+#include "llpipelinelistener.h"
+
+#include "pipeline.h"
+#include "stringize.h"
+#include <sstream>
+#include "llviewermenu.h"
+
+
+namespace {
+ // Render Types
+ void toggle_render_types_wrapper(LLSD const& request)
+ {
+ for (LLSD::array_const_iterator iter = request["types"].beginArray();
+ iter != request["types"].endArray();
+ ++iter)
+ {
+ U32 render_type = render_type_from_string( iter->asString() );
+ if ( render_type != 0 )
+ {
+ LLPipeline::toggleRenderTypeControl( (void*) render_type );
+ }
+ }
+ }
+
+ void has_render_type_wrapper(LLSD const& request)
+ {
+ LLEventAPI::Response response(LLSD(), request);
+ U32 render_type = render_type_from_string( request["type"].asString() );
+ if ( render_type != 0 )
+ {
+ response["value"] = LLPipeline::hasRenderTypeControl( (void*) render_type );
+ }
+ else
+ {
+ response.error(STRINGIZE("unknown type '" << request["type"].asString() << "'"));
+ }
+ }
+
+ void disable_all_render_types_wrapper(LLSD const& request)
+ {
+ gPipeline.clearAllRenderTypes();
+ }
+
+ void enable_all_render_types_wrapper(LLSD const& request)
+ {
+ gPipeline.setAllRenderTypes();
+ }
+
+ // Render Features
+ void toggle_render_features_wrapper(LLSD const& request)
+ {
+ for (LLSD::array_const_iterator iter = request["features"].beginArray();
+ iter != request["features"].endArray();
+ ++iter)
+ {
+ U32 render_feature = feature_from_string( iter->asString() );
+ if ( render_feature != 0 )
+ {
+ LLPipeline::toggleRenderDebugControl( (void*) render_feature );
+ }
+ }
+ }
+
+ void has_render_feature_wrapper(LLSD const& request)
+ {
+ LLEventAPI::Response response(LLSD(), request);
+ U32 render_feature = feature_from_string( request["feature"].asString() );
+ if ( render_feature != 0 )
+ {
+ response["value"] = gPipeline.hasRenderDebugFeatureMask(render_feature);
+ }
+ else
+ {
+ response.error(STRINGIZE("unknown feature '" << request["feature"].asString() << "'"));
+ }
+ }
+
+ void disable_all_render_features_wrapper(LLSD const& request)
+ {
+ gPipeline.clearAllRenderDebugFeatures();
+ }
+
+ void enable_all_render_features_wrapper(LLSD const& request)
+ {
+ gPipeline.setAllRenderDebugFeatures();
+ }
+
+ // Render Info Displays
+ void toggle_info_displays_wrapper(LLSD const& request)
+ {
+ for (LLSD::array_const_iterator iter = request["displays"].beginArray();
+ iter != request["displays"].endArray();
+ ++iter)
+ {
+ U32 info_display = info_display_from_string( iter->asString() );
+ if ( info_display != 0 )
+ {
+ LLPipeline::toggleRenderDebug( (void*) info_display );
+ }
+ }
+ }
+
+ void has_info_display_wrapper(LLSD const& request)
+ {
+ LLEventAPI::Response response(LLSD(), request);
+ U32 info_display = info_display_from_string( request["display"].asString() );
+ if ( info_display != 0 )
+ {
+ response["value"] = gPipeline.hasRenderDebugMask(info_display);
+ }
+ else
+ {
+ response.error(STRINGIZE("unknown display '" << request["display"].asString() << "'"));
+ }
+ }
+
+ void disable_all_info_displays_wrapper(LLSD const& request)
+ {
+ gPipeline.clearAllRenderDebugDisplays();
+ }
+
+ void enable_all_info_displays_wrapper(LLSD const& request)
+ {
+ gPipeline.setAllRenderDebugDisplays();
+ }
+
+}
+
+
+LLPipelineListener::LLPipelineListener():
+ LLEventAPI("LLPipeline",
+ "API to te rendering pipeline.")
+{
+ // Render Types
+ add("toggleRenderTypes",
+ "Toggle rendering [\"types\"]:\n"
+ "See: llviewermenu.cpp:render_type_from_string for list of available types.",
+ &toggle_render_types_wrapper);
+ add("hasRenderType",
+ "Check if rendering [\"type\"] is enabled:\n"
+ "See: llviewermenu.cpp:render_type_from_string for list of available types.",
+ &has_render_type_wrapper,
+ LLSDMap("reply", LLSD()));
+ add("disableAllRenderTypes",
+ "Turn off all rendering types.",
+ &disable_all_render_types_wrapper);
+ add("enableAllRenderTypes",
+ "Turn on all rendering types.",
+ &enable_all_render_types_wrapper);
+
+ // Render Features
+ add("toggleRenderFeatures",
+ "Toggle rendering [\"features\"]:\n"
+ "See: llviewermenu.cpp:feature_from_string for list of available features.",
+ &toggle_render_features_wrapper);
+ add("hasRenderFeature",
+ "Check if rendering [\"feature\"] is enabled:\n"
+ "See: llviewermenu.cpp:render_feature_from_string for list of available features.",
+ &has_render_feature_wrapper,
+ LLSDMap("reply", LLSD()));
+ add("disableAllRenderFeatures",
+ "Turn off all rendering features.",
+ &disable_all_render_features_wrapper);
+ add("enableAllRenderFeatures",
+ "Turn on all rendering features.",
+ &enable_all_render_features_wrapper);
+
+ // Render Info Displays
+ add("toggleRenderInfoDisplays",
+ "Toggle info [\"displays\"]:\n"
+ "See: llviewermenu.cpp:info_display_from_string for list of available displays.",
+ &toggle_info_displays_wrapper);
+ add("hasRenderInfoDisplay",
+ "Check if info [\"display\"] is enabled:\n"
+ "See: llviewermenu.cpp:info_display_from_string for list of available displays.",
+ &has_info_display_wrapper,
+ LLSDMap("reply", LLSD()));
+ add("disableAllRenderInfoDisplays",
+ "Turn off all info displays.",
+ &disable_all_info_displays_wrapper);
+ add("enableAllRenderInfoDisplays",
+ "Turn on all info displays.",
+ &enable_all_info_displays_wrapper);
+}
+
diff --git a/indra/newview/llpipelinelistener.h b/indra/newview/llpipelinelistener.h
new file mode 100644
index 0000000000..da1898e57b
--- /dev/null
+++ b/indra/newview/llpipelinelistener.h
@@ -0,0 +1,41 @@
+/**
+ * @file llpipelinelistener.h
+ * @author Don Kjer
+ * @date 2012-07-09
+ * @brief Wrap subset of LLPipeline API in event API
+ *
+ * $LicenseInfo:firstyear=2012&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$
+ */
+
+#if ! defined(LL_LLPIPELINELISTENER_H)
+#define LL_LLPIPELINELISTENER_H
+
+#include "lleventapi.h"
+
+/// Listen on an LLEventPump with specified name for LLPipeline request events.
+class LLPipelineListener: public LLEventAPI
+{
+public:
+ LLPipelineListener();
+};
+
+#endif /* ! defined(LL_LLPIPELINELISTENER_H) */
diff --git a/indra/newview/llplacesfolderview.cpp b/indra/newview/llplacesfolderview.cpp
new file mode 100755
index 0000000000..3caa93ae71
--- /dev/null
+++ b/indra/newview/llplacesfolderview.cpp
@@ -0,0 +1,74 @@
+/**
+* @file llplacesfolderview.cpp
+* @brief llplacesfolderview used within llplacesinventorypanel
+* @author Gilbert@lindenlab.com
+*
+* $LicenseInfo:firstyear=2012&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2012, 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 "llplacesfolderview.h"
+
+#include "llplacesinventorypanel.h"
+#include "llpanellandmarks.h"
+
+LLPlacesFolderView::LLPlacesFolderView(const LLFolderView::Params& p)
+ : LLFolderView(p)
+{
+ // we do not need auto select functionality in places landmarks, so override default behavior.
+ // this disables applying of the LLSelectFirstFilteredItem in LLFolderView::doIdle.
+ // Fixed issues: EXT-1631, EXT-4994.
+ mAutoSelectOverride = TRUE;
+}
+
+BOOL LLPlacesFolderView::handleRightMouseDown(S32 x, S32 y, MASK mask)
+{
+ // let children to change selection first
+ childrenHandleRightMouseDown(x, y, mask);
+ mParentLandmarksPanel->setCurrentSelectedList((LLPlacesInventoryPanel*)getParentPanel());
+
+ // then determine its type and set necessary menu handle
+ if (getCurSelectedItem())
+ {
+ LLInventoryType::EType inventory_type = static_cast<LLFolderViewModelItemInventory*>(getCurSelectedItem()->getViewModelItem())->getInventoryType();
+ inventory_type_menu_handle_t::iterator it_handle = mMenuHandlesByInventoryType.find(inventory_type);
+
+ if (it_handle != mMenuHandlesByInventoryType.end())
+ {
+ mPopupMenuHandle = (*it_handle).second;
+ }
+ else
+ {
+ llwarns << "Requested menu handle for non-setup inventory type: " << inventory_type << llendl;
+ }
+
+ }
+
+ return LLFolderView::handleRightMouseDown(x, y, mask);
+}
+
+void LLPlacesFolderView::setupMenuHandle(LLInventoryType::EType asset_type, LLHandle<LLView> menu_handle)
+{
+ mMenuHandlesByInventoryType[asset_type] = menu_handle;
+}
+
diff --git a/indra/newview/llplacesfolderview.h b/indra/newview/llplacesfolderview.h
new file mode 100755
index 0000000000..8c5be39b5e
--- /dev/null
+++ b/indra/newview/llplacesfolderview.h
@@ -0,0 +1,72 @@
+/**
+* @file llplacesfolderview.h
+* @brief llplacesfolderview used within llplacesinventorypanel
+* @author Gilbert@lindenlab.com
+*
+* $LicenseInfo:firstyear=2012&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2012, 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_LLPLACESFOLDERVIEW_H
+#define LL_LLPLACESFOLDERVIEW_H
+
+#include "llfolderview.h"
+#include "llinventorypanel.h"
+
+class LLLandmarksPanel;
+
+class LLPlacesFolderView : public LLFolderView
+{
+public:
+
+ struct Params : public LLInitParam::Block<Params, LLFolderView::Params>
+ {
+ Params()
+ {}
+ };
+
+ LLPlacesFolderView(const LLFolderView::Params& p);
+ /**
+ * Handles right mouse down
+ *
+ * Contains workaround for EXT-2786: sets current selected list for landmark
+ * panel using @c mParentLandmarksPanel which is set in @c LLLandmarksPanel::initLandmarksPanel
+ */
+ /*virtual*/ BOOL handleRightMouseDown( S32 x, S32 y, MASK mask );
+
+ void setupMenuHandle(LLInventoryType::EType asset_type, LLHandle<LLView> menu_handle);
+
+ void setParentLandmarksPanel(LLLandmarksPanel* panel)
+ {
+ mParentLandmarksPanel = panel;
+ }
+
+private:
+ /**
+ * holds pointer to landmark panel. This pointer is used in @c LLPlacesFolderView::handleRightMouseDown
+ */
+ LLLandmarksPanel* mParentLandmarksPanel;
+ typedef std::map<LLInventoryType::EType, LLHandle<LLView> > inventory_type_menu_handle_t;
+ inventory_type_menu_handle_t mMenuHandlesByInventoryType;
+
+};
+
+#endif // LL_LLPLACESFOLDERVIEW_H
+
diff --git a/indra/newview/llplacesinventorybridge.cpp b/indra/newview/llplacesinventorybridge.cpp
index fe4cc0f55f..ebd9604c5b 100644..100755
--- a/indra/newview/llplacesinventorybridge.cpp
+++ b/indra/newview/llplacesinventorybridge.cpp
@@ -85,34 +85,33 @@ void LLPlacesLandmarkBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
void LLPlacesFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
{
+ std::vector<std::string> items;
+ std::vector<std::string> disabled_items;
+
+ LLInventoryPanel* inv_panel = mInventoryPanel.get();
+ bool is_open = false;
+ if (inv_panel)
{
- std::vector<std::string> items;
- std::vector<std::string> disabled_items;
+ LLFolderViewFolder* folder = dynamic_cast<LLFolderViewFolder*>(inv_panel->getItemByID(mUUID));
+ is_open = (NULL != folder) && folder->isOpen();
+ }
- LLInventoryPanel* inv_panel = mInventoryPanel.get();
- bool is_open = false;
- if (inv_panel)
- {
- LLFolderViewFolder* folder = dynamic_cast<LLFolderViewFolder*>(inv_panel->getRootFolder()->getItemByID(mUUID));
- is_open = (NULL != folder) && folder->isOpen();
- }
+ // collect all items' names
+ fill_items_with_menu_items(items, menu);
- // collect all items' names
- fill_items_with_menu_items(items, menu);
+ // remove expand or collapse menu item depend on folder state
+ std::string collapse_expand_item_to_hide(is_open ? "expand" : "collapse");
+ std::vector<std::string>::iterator it = std::find(items.begin(), items.end(), collapse_expand_item_to_hide);
+ if (it != items.end()) items.erase(it);
- // remove expand or collapse menu item depend on folder state
- std::string collapse_expand_item_to_hide(is_open ? "expand" : "collapse");
- std::vector<std::string>::iterator it = std::find(items.begin(), items.end(), collapse_expand_item_to_hide);
- if (it != items.end()) items.erase(it);
- // Disabled items are processed via LLLandmarksPanel::isActionEnabled()
- // they should be synchronized with Places/My Landmarks/Gear menu. See EXT-1601
+ // Disabled items are processed via LLLandmarksPanel::isActionEnabled()
+ // they should be synchronized with Places/My Landmarks/Gear menu. See EXT-1601
- // repeat parent functionality
- sSelf = getHandle(); // necessary for "New Folder" functionality
+ // repeat parent functionality
+ sSelf = getHandle(); // necessary for "New Folder" functionality
- hide_context_entries(menu, items, disabled_items);
- }
+ hide_context_entries(menu, items, disabled_items);
}
//virtual
@@ -140,7 +139,7 @@ LLFolderViewFolder* LLPlacesFolderBridge::getFolder()
LLInventoryPanel* inv_panel = mInventoryPanel.get();
if (inv_panel)
{
- folder = dynamic_cast<LLFolderViewFolder*>(inv_panel->getRootFolder()->getItemByID(mUUID));
+ folder = dynamic_cast<LLFolderViewFolder*>(inv_panel->getItemByID(mUUID));
}
return folder;
@@ -152,6 +151,7 @@ LLInvFVBridge* LLPlacesInventoryBridgeBuilder::createBridge(
LLAssetType::EType actual_asset_type,
LLInventoryType::EType inv_type,
LLInventoryPanel* inventory,
+ LLFolderViewModelInventory* view_model,
LLFolderView* root,
const LLUUID& uuid,
U32 flags/* = 0x00*/) const
@@ -170,11 +170,12 @@ LLInvFVBridge* LLPlacesInventoryBridgeBuilder::createBridge(
if (actual_asset_type == LLAssetType::AT_LINK_FOLDER)
{
// *TODO: Create a link folder handler instead if it is necessary
- new_listener = LLInventoryFVBridgeBuilder::createBridge(
+ new_listener = LLInventoryFolderViewModelBuilder::createBridge(
asset_type,
actual_asset_type,
inv_type,
inventory,
+ view_model,
root,
uuid,
flags);
@@ -183,11 +184,12 @@ LLInvFVBridge* LLPlacesInventoryBridgeBuilder::createBridge(
new_listener = new LLPlacesFolderBridge(inv_type, inventory, root, uuid);
break;
default:
- new_listener = LLInventoryFVBridgeBuilder::createBridge(
+ new_listener = LLInventoryFolderViewModelBuilder::createBridge(
asset_type,
actual_asset_type,
inv_type,
inventory,
+ view_model,
root,
uuid,
flags);
diff --git a/indra/newview/llplacesinventorybridge.h b/indra/newview/llplacesinventorybridge.h
index 52beacef9c..07d18d03c5 100644..100755
--- a/indra/newview/llplacesinventorybridge.h
+++ b/indra/newview/llplacesinventorybridge.h
@@ -82,13 +82,14 @@ protected:
*
* It builds Bridges for Landmarks and Folders in Places Landmarks Panel
*/
-class LLPlacesInventoryBridgeBuilder : public LLInventoryFVBridgeBuilder
+class LLPlacesInventoryBridgeBuilder : public LLInventoryFolderViewModelBuilder
{
public:
/*virtual*/ LLInvFVBridge* createBridge(LLAssetType::EType asset_type,
LLAssetType::EType actual_asset_type,
LLInventoryType::EType inv_type,
LLInventoryPanel* inventory,
+ LLFolderViewModelInventory* view_model,
LLFolderView* root,
const LLUUID& uuid,
U32 flags = 0x00) const;
diff --git a/indra/newview/llplacesinventorypanel.cpp b/indra/newview/llplacesinventorypanel.cpp
index f7823f4fe8..4c2213c198 100644..100755
--- a/indra/newview/llplacesinventorypanel.cpp
+++ b/indra/newview/llplacesinventorypanel.cpp
@@ -30,7 +30,8 @@
#include "llplacesinventorypanel.h"
-#include "llfoldervieweventlistener.h"
+#include "llfolderviewmodel.h"
+#include "llplacesfolderview.h"
#include "llinventorybridge.h"
#include "llinventoryfunctions.h"
#include "llpanellandmarks.h"
@@ -57,44 +58,35 @@ LLPlacesInventoryPanel::~LLPlacesInventoryPanel()
delete mSavedFolderState;
}
-void LLPlacesInventoryPanel::buildFolderView(const LLInventoryPanel::Params& params)
-{
- // Determine the root folder in case specified, and
- // build the views starting with that folder.
- const LLFolderType::EType preferred_type = LLViewerFolderType::lookupTypeFromNewCategoryName(params.start_folder);
-
- LLUUID root_id;
- if ("LIBRARY" == params.start_folder())
- {
- root_id = gInventory.getLibraryRootFolderID();
- }
- else
- {
- root_id = (preferred_type != LLFolderType::FT_NONE ? gInventory.findCategoryUUIDForType(preferred_type) : LLUUID::null);
- }
-
- LLRect folder_rect(0,
- 0,
- getRect().getWidth(),
- 0);
- LLPlacesFolderView::Params p;
- p.name = getName();
- p.title = getLabel();
- p.rect = folder_rect;
- p.listener = mInvFVBridgeBuilder->createBridge(LLAssetType::AT_CATEGORY,
- LLAssetType::AT_CATEGORY,
- LLInventoryType::IT_CATEGORY,
- this,
- NULL,
- root_id);
- p.parent_panel = this;
- p.allow_multiselect = mAllowMultiSelect;
- p.use_ellipses = true; // truncate inventory item text so remove horizontal scroller
- mFolderRoot = (LLFolderView*)LLUICtrlFactory::create<LLPlacesFolderView>(p);
+LLFolderView * LLPlacesInventoryPanel::createFolderRoot(LLUUID root_id )
+{
+ LLPlacesFolderView::Params p;
+
+ p.name = getName();
+ p.title = getLabel();
+ p.rect = LLRect(0, 0, getRect().getWidth(), 0);
+ p.parent_panel = this;
+ p.tool_tip = p.name;
+ p.listener = mInvFVBridgeBuilder->createBridge( LLAssetType::AT_CATEGORY,
+ LLAssetType::AT_CATEGORY,
+ LLInventoryType::IT_CATEGORY,
+ this,
+ &mInventoryViewModel,
+ NULL,
+ root_id);
+ p.view_model = &mInventoryViewModel;
+ p.use_label_suffix = mParams.use_label_suffix;
+ p.allow_multiselect = mAllowMultiSelect;
+ p.show_empty_message = mShowEmptyMessage;
+ p.show_item_link_overlays = mShowItemLinkOverlays;
+ p.root = NULL;
+ p.use_ellipses = mParams.folder_view.use_ellipses;
+ p.options_menu = "menu_inventory.xml";
+
+ return LLUICtrlFactory::create<LLPlacesFolderView>(p);
}
-
// save current folder open state
void LLPlacesInventoryPanel::saveFolderState()
{
@@ -128,59 +120,3 @@ S32 LLPlacesInventoryPanel::notify(const LLSD& info)
}
return 0;
}
-
-/************************************************************************/
-/* PROTECTED METHODS */
-/************************************************************************/
-
-
-
-/************************************************************************/
-/* LLPlacesFolderView implementation */
-/************************************************************************/
-
-//////////////////////////////////////////////////////////////////////////
-// PUBLIC METHODS
-//////////////////////////////////////////////////////////////////////////
-
-LLPlacesFolderView::LLPlacesFolderView(const LLFolderView::Params& p)
-: LLFolderView(p)
-{
- // we do not need auto select functionality in places landmarks, so override default behavior.
- // this disables applying of the LLSelectFirstFilteredItem in LLFolderView::doIdle.
- // Fixed issues: EXT-1631, EXT-4994.
- mAutoSelectOverride = TRUE;
-}
-
-BOOL LLPlacesFolderView::handleRightMouseDown(S32 x, S32 y, MASK mask)
-{
- // let children to change selection first
- childrenHandleRightMouseDown(x, y, mask);
- mParentLandmarksPanel->setCurrentSelectedList((LLPlacesInventoryPanel*)getParentPanel());
-
- // then determine its type and set necessary menu handle
- if (getCurSelectedItem())
- {
- LLInventoryType::EType inventory_type = getCurSelectedItem()->getListener()->getInventoryType();
- inventory_type_menu_handle_t::iterator it_handle = mMenuHandlesByInventoryType.find(inventory_type);
-
- if (it_handle != mMenuHandlesByInventoryType.end())
- {
- mPopupMenuHandle = (*it_handle).second;
- }
- else
- {
- llwarns << "Requested menu handle for non-setup inventory type: " << inventory_type << llendl;
- }
-
- }
-
- return LLFolderView::handleRightMouseDown(x, y, mask);
-}
-
-void LLPlacesFolderView::setupMenuHandle(LLInventoryType::EType asset_type, LLHandle<LLView> menu_handle)
-{
- mMenuHandlesByInventoryType[asset_type] = menu_handle;
-}
-
-// EOF
diff --git a/indra/newview/llplacesinventorypanel.h b/indra/newview/llplacesinventorypanel.h
index f647e7f970..2805fc4257 100644..100755
--- a/indra/newview/llplacesinventorypanel.h
+++ b/indra/newview/llplacesinventorypanel.h
@@ -29,9 +29,9 @@
#include "llfloaterinventory.h"
#include "llinventorypanel.h"
-#include "llfolderview.h"
class LLLandmarksPanel;
+class LLFolderView;
class LLPlacesInventoryPanel : public LLInventoryPanel
{
@@ -46,8 +46,7 @@ public:
LLPlacesInventoryPanel(const Params& p);
~LLPlacesInventoryPanel();
- /*virtual*/ void buildFolderView(const LLInventoryPanel::Params& params);
-
+ LLFolderView * createFolderRoot(LLUUID root_id );
void saveFolderState();
void restoreFolderState();
@@ -57,36 +56,4 @@ private:
LLSaveFolderState* mSavedFolderState;
};
-
-class LLPlacesFolderView : public LLFolderView
-{
-public:
- LLPlacesFolderView(const LLFolderView::Params& p);
- /**
- * Handles right mouse down
- *
- * Contains workaround for EXT-2786: sets current selected list for landmark
- * panel using @c mParentLandmarksPanel which is set in @c LLLandmarksPanel::initLandmarksPanel
- */
- /*virtual*/ BOOL handleRightMouseDown( S32 x, S32 y, MASK mask );
-
- void setupMenuHandle(LLInventoryType::EType asset_type, LLHandle<LLView> menu_handle);
-
- void setParentLandmarksPanel(LLLandmarksPanel* panel)
- {
- mParentLandmarksPanel = panel;
- }
-
- S32 getSelectedCount() { return (S32)mSelectedItems.size(); }
-
-private:
- /**
- * holds pointer to landmark panel. This pointer is used in @c LLPlacesFolderView::handleRightMouseDown
- */
- LLLandmarksPanel* mParentLandmarksPanel;
- typedef std::map<LLInventoryType::EType, LLHandle<LLView> > inventory_type_menu_handle_t;
- inventory_type_menu_handle_t mMenuHandlesByInventoryType;
-
-};
-
#endif //LL_LLINVENTORYSUBTREEPANEL_H
diff --git a/indra/newview/llpolymesh.cpp b/indra/newview/llpolymesh.cpp
deleted file mode 100644
index 450f9b2be7..0000000000
--- a/indra/newview/llpolymesh.cpp
+++ /dev/null
@@ -1,1261 +0,0 @@
-/**
- * @file llpolymesh.cpp
- * @brief Implementation of LLPolyMesh class
- *
- * $LicenseInfo:firstyear=2001&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$
- */
-
-//-----------------------------------------------------------------------------
-// Header Files
-//-----------------------------------------------------------------------------
-#include "llviewerprecompiledheaders.h"
-
-#include "llfasttimer.h"
-#include "llmemory.h"
-
-#include "llviewercontrol.h"
-#include "llxmltree.h"
-#include "llvoavatar.h"
-#include "llwearable.h"
-#include "lldir.h"
-#include "llvolume.h"
-#include "llendianswizzle.h"
-
-#include "llpolymesh.h"
-
-#define HEADER_ASCII "Linden Mesh 1.0"
-#define HEADER_BINARY "Linden Binary Mesh 1.0"
-
-extern LLControlGroup gSavedSettings; // read only
-
-LLPolyMorphData *clone_morph_param_duplicate(const LLPolyMorphData *src_data,
- const std::string &name);
-LLPolyMorphData *clone_morph_param_direction(const LLPolyMorphData *src_data,
- const LLVector3 &direction,
- const std::string &name);
-LLPolyMorphData *clone_morph_param_cleavage(const LLPolyMorphData *src_data,
- F32 scale,
- const std::string &name);
-
-//-----------------------------------------------------------------------------
-// Global table of loaded LLPolyMeshes
-//-----------------------------------------------------------------------------
-LLPolyMesh::LLPolyMeshSharedDataTable LLPolyMesh::sGlobalSharedMeshList;
-
-//-----------------------------------------------------------------------------
-// LLPolyMeshSharedData()
-//-----------------------------------------------------------------------------
-LLPolyMeshSharedData::LLPolyMeshSharedData()
-{
- mNumVertices = 0;
- mBaseCoords = NULL;
- mBaseNormals = NULL;
- mBaseBinormals = NULL;
- mTexCoords = NULL;
- mDetailTexCoords = NULL;
- mWeights = NULL;
- mHasWeights = FALSE;
- mHasDetailTexCoords = FALSE;
-
- mNumFaces = 0;
- mFaces = NULL;
-
- mNumJointNames = 0;
- mJointNames = NULL;
-
- mTriangleIndices = NULL;
- mNumTriangleIndices = 0;
-
- mReferenceData = NULL;
-
- mLastIndexOffset = -1;
-}
-
-//-----------------------------------------------------------------------------
-// ~LLPolyMeshSharedData()
-//-----------------------------------------------------------------------------
-LLPolyMeshSharedData::~LLPolyMeshSharedData()
-{
- freeMeshData();
- for_each(mMorphData.begin(), mMorphData.end(), DeletePointer());
- mMorphData.clear();
-}
-
-//-----------------------------------------------------------------------------
-// setupLOD()
-//-----------------------------------------------------------------------------
-void LLPolyMeshSharedData::setupLOD(LLPolyMeshSharedData* reference_data)
-{
- mReferenceData = reference_data;
-
- if (reference_data)
- {
- mBaseCoords = reference_data->mBaseCoords;
- mBaseNormals = reference_data->mBaseNormals;
- mBaseBinormals = reference_data->mBaseBinormals;
- mTexCoords = reference_data->mTexCoords;
- mDetailTexCoords = reference_data->mDetailTexCoords;
- mWeights = reference_data->mWeights;
- mHasWeights = reference_data->mHasWeights;
- mHasDetailTexCoords = reference_data->mHasDetailTexCoords;
- }
-}
-
-//-----------------------------------------------------------------------------
-// LLPolyMeshSharedData::freeMeshData()
-//-----------------------------------------------------------------------------
-void LLPolyMeshSharedData::freeMeshData()
-{
- if (!mReferenceData)
- {
- mNumVertices = 0;
-
- delete [] mBaseCoords;
- mBaseCoords = NULL;
-
- delete [] mBaseNormals;
- mBaseNormals = NULL;
-
- delete [] mBaseBinormals;
- mBaseBinormals = NULL;
-
- delete [] mTexCoords;
- mTexCoords = NULL;
-
- delete [] mDetailTexCoords;
- mDetailTexCoords = NULL;
-
- delete [] mWeights;
- mWeights = NULL;
- }
-
- mNumFaces = 0;
- delete [] mFaces;
- mFaces = NULL;
-
- mNumJointNames = 0;
- delete [] mJointNames;
- mJointNames = NULL;
-
- delete [] mTriangleIndices;
- mTriangleIndices = NULL;
-
-// mVertFaceMap.deleteAllData();
-}
-
-// compate_int is used by the qsort function to sort the index array
-int compare_int(const void *a, const void *b);
-
-//-----------------------------------------------------------------------------
-// genIndices()
-//-----------------------------------------------------------------------------
-void LLPolyMeshSharedData::genIndices(S32 index_offset)
-{
- if (index_offset == mLastIndexOffset)
- {
- return;
- }
-
- delete []mTriangleIndices;
- mTriangleIndices = new U32[mNumTriangleIndices];
-
- S32 cur_index = 0;
- for (S32 i = 0; i < mNumFaces; i++)
- {
- mTriangleIndices[cur_index] = mFaces[i][0] + index_offset;
- cur_index++;
- mTriangleIndices[cur_index] = mFaces[i][1] + index_offset;
- cur_index++;
- mTriangleIndices[cur_index] = mFaces[i][2] + index_offset;
- cur_index++;
- }
-
- mLastIndexOffset = index_offset;
-}
-
-//--------------------------------------------------------------------
-// LLPolyMeshSharedData::getNumKB()
-//--------------------------------------------------------------------
-U32 LLPolyMeshSharedData::getNumKB()
-{
- U32 num_kb = sizeof(LLPolyMesh);
-
- if (!isLOD())
- {
- num_kb += mNumVertices *
- ( sizeof(LLVector3) + // coords
- sizeof(LLVector3) + // normals
- sizeof(LLVector2) ); // texCoords
- }
-
- if (mHasDetailTexCoords && !isLOD())
- {
- num_kb += mNumVertices * sizeof(LLVector2); // detailTexCoords
- }
-
- if (mHasWeights && !isLOD())
- {
- num_kb += mNumVertices * sizeof(float); // weights
- }
-
- num_kb += mNumFaces * sizeof(LLPolyFace); // faces
-
- num_kb /= 1024;
- return num_kb;
-}
-
-//-----------------------------------------------------------------------------
-// LLPolyMeshSharedData::allocateVertexData()
-//-----------------------------------------------------------------------------
-BOOL LLPolyMeshSharedData::allocateVertexData( U32 numVertices )
-{
- U32 i;
- mBaseCoords = new LLVector3[ numVertices ];
- mBaseNormals = new LLVector3[ numVertices ];
- mBaseBinormals = new LLVector3[ numVertices ];
- mTexCoords = new LLVector2[ numVertices ];
- mDetailTexCoords = new LLVector2[ numVertices ];
- mWeights = new F32[ numVertices ];
- for (i = 0; i < numVertices; i++)
- {
- mWeights[i] = 0.f;
- }
- mNumVertices = numVertices;
- return TRUE;
-}
-
-//-----------------------------------------------------------------------------
-// LLPolyMeshSharedData::allocateFaceData()
-//-----------------------------------------------------------------------------
-BOOL LLPolyMeshSharedData::allocateFaceData( U32 numFaces )
-{
- mFaces = new LLPolyFace[ numFaces ];
- mNumFaces = numFaces;
- mNumTriangleIndices = mNumFaces * 3;
- return TRUE;
-}
-
-//-----------------------------------------------------------------------------
-// LLPolyMeshSharedData::allocateJointNames()
-//-----------------------------------------------------------------------------
-BOOL LLPolyMeshSharedData::allocateJointNames( U32 numJointNames )
-{
- mJointNames = new std::string[ numJointNames ];
- mNumJointNames = numJointNames;
- return TRUE;
-}
-
-//--------------------------------------------------------------------
-// LLPolyMeshSharedData::loadMesh()
-//--------------------------------------------------------------------
-BOOL LLPolyMeshSharedData::loadMesh( const std::string& fileName )
-{
- //-------------------------------------------------------------------------
- // Open the file
- //-------------------------------------------------------------------------
- if(fileName.empty())
- {
- llerrs << "Filename is Empty!" << llendl;
- return FALSE;
- }
- LLFILE* fp = LLFile::fopen(fileName, "rb"); /*Flawfinder: ignore*/
- if (!fp)
- {
- llerrs << "can't open: " << fileName << llendl;
- return FALSE;
- }
-
- //-------------------------------------------------------------------------
- // Read a chunk
- //-------------------------------------------------------------------------
- char header[128]; /*Flawfinder: ignore*/
- if (fread(header, sizeof(char), 128, fp) != 128)
- {
- llwarns << "Short read" << llendl;
- }
-
- //-------------------------------------------------------------------------
- // Check for proper binary header
- //-------------------------------------------------------------------------
- BOOL status = FALSE;
- if ( strncmp(header, HEADER_BINARY, strlen(HEADER_BINARY)) == 0 ) /*Flawfinder: ignore*/
- {
- lldebugs << "Loading " << fileName << llendl;
-
- //----------------------------------------------------------------
- // File Header (seek past it)
- //----------------------------------------------------------------
- fseek(fp, 24, SEEK_SET);
-
- //----------------------------------------------------------------
- // HasWeights
- //----------------------------------------------------------------
- U8 hasWeights;
- size_t numRead = fread(&hasWeights, sizeof(U8), 1, fp);
- if (numRead != 1)
- {
- llerrs << "can't read HasWeights flag from " << fileName << llendl;
- return FALSE;
- }
- if (!isLOD())
- {
- mHasWeights = (hasWeights==0) ? FALSE : TRUE;
- }
-
- //----------------------------------------------------------------
- // HasDetailTexCoords
- //----------------------------------------------------------------
- U8 hasDetailTexCoords;
- numRead = fread(&hasDetailTexCoords, sizeof(U8), 1, fp);
- if (numRead != 1)
- {
- llerrs << "can't read HasDetailTexCoords flag from " << fileName << llendl;
- return FALSE;
- }
-
- //----------------------------------------------------------------
- // Position
- //----------------------------------------------------------------
- LLVector3 position;
- numRead = fread(position.mV, sizeof(float), 3, fp);
- llendianswizzle(position.mV, sizeof(float), 3);
- if (numRead != 3)
- {
- llerrs << "can't read Position from " << fileName << llendl;
- return FALSE;
- }
- setPosition( position );
-
- //----------------------------------------------------------------
- // Rotation
- //----------------------------------------------------------------
- LLVector3 rotationAngles;
- numRead = fread(rotationAngles.mV, sizeof(float), 3, fp);
- llendianswizzle(rotationAngles.mV, sizeof(float), 3);
- if (numRead != 3)
- {
- llerrs << "can't read RotationAngles from " << fileName << llendl;
- return FALSE;
- }
-
- U8 rotationOrder;
- numRead = fread(&rotationOrder, sizeof(U8), 1, fp);
-
- if (numRead != 1)
- {
- llerrs << "can't read RotationOrder from " << fileName << llendl;
- return FALSE;
- }
-
- rotationOrder = 0;
-
- setRotation( mayaQ( rotationAngles.mV[0],
- rotationAngles.mV[1],
- rotationAngles.mV[2],
- (LLQuaternion::Order)rotationOrder ) );
-
- //----------------------------------------------------------------
- // Scale
- //----------------------------------------------------------------
- LLVector3 scale;
- numRead = fread(scale.mV, sizeof(float), 3, fp);
- llendianswizzle(scale.mV, sizeof(float), 3);
- if (numRead != 3)
- {
- llerrs << "can't read Scale from " << fileName << llendl;
- return FALSE;
- }
- setScale( scale );
-
- //-------------------------------------------------------------------------
- // Release any existing mesh geometry
- //-------------------------------------------------------------------------
- freeMeshData();
-
- U16 numVertices = 0;
-
- //----------------------------------------------------------------
- // NumVertices
- //----------------------------------------------------------------
- if (!isLOD())
- {
- numRead = fread(&numVertices, sizeof(U16), 1, fp);
- llendianswizzle(&numVertices, sizeof(U16), 1);
- if (numRead != 1)
- {
- llerrs << "can't read NumVertices from " << fileName << llendl;
- return FALSE;
- }
-
- allocateVertexData( numVertices );
-
- //----------------------------------------------------------------
- // Coords
- //----------------------------------------------------------------
- numRead = fread(mBaseCoords, 3*sizeof(float), numVertices, fp);
- llendianswizzle(mBaseCoords, sizeof(float), 3*numVertices);
- if (numRead != numVertices)
- {
- llerrs << "can't read Coordinates from " << fileName << llendl;
- return FALSE;
- }
-
- //----------------------------------------------------------------
- // Normals
- //----------------------------------------------------------------
- numRead = fread(mBaseNormals, 3*sizeof(float), numVertices, fp);
- llendianswizzle(mBaseNormals, sizeof(float), 3*numVertices);
- if (numRead != numVertices)
- {
- llerrs << " can't read Normals from " << fileName << llendl;
- return FALSE;
- }
-
- //----------------------------------------------------------------
- // Binormals
- //----------------------------------------------------------------
- numRead = fread(mBaseBinormals, 3*sizeof(float), numVertices, fp);
- llendianswizzle(mBaseBinormals, sizeof(float), 3*numVertices);
- if (numRead != numVertices)
- {
- llerrs << " can't read Binormals from " << fileName << llendl;
- return FALSE;
- }
-
-
- //----------------------------------------------------------------
- // TexCoords
- //----------------------------------------------------------------
- numRead = fread(mTexCoords, 2*sizeof(float), numVertices, fp);
- llendianswizzle(mTexCoords, sizeof(float), 2*numVertices);
- if (numRead != numVertices)
- {
- llerrs << "can't read TexCoords from " << fileName << llendl;
- return FALSE;
- }
-
- //----------------------------------------------------------------
- // DetailTexCoords
- //----------------------------------------------------------------
- if (mHasDetailTexCoords)
- {
- numRead = fread(mDetailTexCoords, 2*sizeof(float), numVertices, fp);
- llendianswizzle(mDetailTexCoords, sizeof(float), 2*numVertices);
- if (numRead != numVertices)
- {
- llerrs << "can't read DetailTexCoords from " << fileName << llendl;
- return FALSE;
- }
- }
-
- //----------------------------------------------------------------
- // Weights
- //----------------------------------------------------------------
- if (mHasWeights)
- {
- numRead = fread(mWeights, sizeof(float), numVertices, fp);
- llendianswizzle(mWeights, sizeof(float), numVertices);
- if (numRead != numVertices)
- {
- llerrs << "can't read Weights from " << fileName << llendl;
- return FALSE;
- }
- }
- }
-
- //----------------------------------------------------------------
- // NumFaces
- //----------------------------------------------------------------
- U16 numFaces;
- numRead = fread(&numFaces, sizeof(U16), 1, fp);
- llendianswizzle(&numFaces, sizeof(U16), 1);
- if (numRead != 1)
- {
- llerrs << "can't read NumFaces from " << fileName << llendl;
- return FALSE;
- }
- allocateFaceData( numFaces );
-
-
- //----------------------------------------------------------------
- // Faces
- //----------------------------------------------------------------
- U32 i;
- U32 numTris = 0;
- for (i = 0; i < numFaces; i++)
- {
- S16 face[3];
- numRead = fread(face, sizeof(U16), 3, fp);
- llendianswizzle(face, sizeof(U16), 3);
- if (numRead != 3)
- {
- llerrs << "can't read Face[" << i << "] from " << fileName << llendl;
- return FALSE;
- }
- if (mReferenceData)
- {
- llassert(face[0] < mReferenceData->mNumVertices);
- llassert(face[1] < mReferenceData->mNumVertices);
- llassert(face[2] < mReferenceData->mNumVertices);
- }
-
- if (isLOD())
- {
- // store largest index in case of LODs
- for (S32 j = 0; j < 3; j++)
- {
- if (face[j] > mNumVertices - 1)
- {
- mNumVertices = face[j] + 1;
- }
- }
- }
- mFaces[i][0] = face[0];
- mFaces[i][1] = face[1];
- mFaces[i][2] = face[2];
-
-// S32 j;
-// for(j = 0; j < 3; j++)
-// {
-// LLDynamicArray<S32> *face_list = mVertFaceMap.getIfThere(face[j]);
-// if (!face_list)
-// {
-// face_list = new LLDynamicArray<S32>;
-// mVertFaceMap.addData(face[j], face_list);
-// }
-// face_list->put(i);
-// }
-
- numTris++;
- }
-
- lldebugs << "verts: " << numVertices
- << ", faces: " << numFaces
- << ", tris: " << numTris
- << llendl;
-
- //----------------------------------------------------------------
- // NumSkinJoints
- //----------------------------------------------------------------
- if (!isLOD())
- {
- U16 numSkinJoints = 0;
- if ( mHasWeights )
- {
- numRead = fread(&numSkinJoints, sizeof(U16), 1, fp);
- llendianswizzle(&numSkinJoints, sizeof(U16), 1);
- if (numRead != 1)
- {
- llerrs << "can't read NumSkinJoints from " << fileName << llendl;
- return FALSE;
- }
- allocateJointNames( numSkinJoints );
- }
-
- //----------------------------------------------------------------
- // SkinJoints
- //----------------------------------------------------------------
- for (i=0; i < numSkinJoints; i++)
- {
- char jointName[64+1];
- numRead = fread(jointName, sizeof(jointName)-1, 1, fp);
- jointName[sizeof(jointName)-1] = '\0'; // ensure nul-termination
- if (numRead != 1)
- {
- llerrs << "can't read Skin[" << i << "].Name from " << fileName << llendl;
- return FALSE;
- }
-
- std::string *jn = &mJointNames[i];
- *jn = jointName;
- }
-
- //-------------------------------------------------------------------------
- // look for morph section
- //-------------------------------------------------------------------------
- char morphName[64+1];
- morphName[sizeof(morphName)-1] = '\0'; // ensure nul-termination
- while(fread(&morphName, sizeof(char), 64, fp) == 64)
- {
- if (!strcmp(morphName, "End Morphs"))
- {
- // we reached the end of the morphs
- break;
- }
- LLPolyMorphData* morph_data = new LLPolyMorphData(std::string(morphName));
-
- BOOL result = morph_data->loadBinary(fp, this);
-
- if (!result)
- {
- delete morph_data;
- continue;
- }
-
- mMorphData.insert(morph_data);
-
- if (!strcmp(morphName, "Breast_Female_Cleavage"))
- {
- mMorphData.insert(clone_morph_param_cleavage(morph_data,
- .75f,
- "Breast_Physics_LeftRight_Driven"));
- }
-
- if (!strcmp(morphName, "Breast_Female_Cleavage"))
- {
- mMorphData.insert(clone_morph_param_duplicate(morph_data,
- "Breast_Physics_InOut_Driven"));
- }
- if (!strcmp(morphName, "Breast_Gravity"))
- {
- mMorphData.insert(clone_morph_param_duplicate(morph_data,
- "Breast_Physics_UpDown_Driven"));
- }
-
- if (!strcmp(morphName, "Big_Belly_Torso"))
- {
- mMorphData.insert(clone_morph_param_direction(morph_data,
- LLVector3(0,0,0.05f),
- "Belly_Physics_Torso_UpDown_Driven"));
- }
-
- if (!strcmp(morphName, "Big_Belly_Legs"))
- {
- mMorphData.insert(clone_morph_param_direction(morph_data,
- LLVector3(0,0,0.05f),
- "Belly_Physics_Legs_UpDown_Driven"));
- }
-
- if (!strcmp(morphName, "skirt_belly"))
- {
- mMorphData.insert(clone_morph_param_direction(morph_data,
- LLVector3(0,0,0.05f),
- "Belly_Physics_Skirt_UpDown_Driven"));
- }
-
- if (!strcmp(morphName, "Small_Butt"))
- {
- mMorphData.insert(clone_morph_param_direction(morph_data,
- LLVector3(0,0,0.05f),
- "Butt_Physics_UpDown_Driven"));
- }
- if (!strcmp(morphName, "Small_Butt"))
- {
- mMorphData.insert(clone_morph_param_direction(morph_data,
- LLVector3(0,0.03f,0),
- "Butt_Physics_LeftRight_Driven"));
- }
- }
-
- S32 numRemaps;
- if (fread(&numRemaps, sizeof(S32), 1, fp) == 1)
- {
- llendianswizzle(&numRemaps, sizeof(S32), 1);
- for (S32 i = 0; i < numRemaps; i++)
- {
- S32 remapSrc;
- S32 remapDst;
- if (fread(&remapSrc, sizeof(S32), 1, fp) != 1)
- {
- llerrs << "can't read source vertex in vertex remap data" << llendl;
- break;
- }
- if (fread(&remapDst, sizeof(S32), 1, fp) != 1)
- {
- llerrs << "can't read destination vertex in vertex remap data" << llendl;
- break;
- }
- llendianswizzle(&remapSrc, sizeof(S32), 1);
- llendianswizzle(&remapDst, sizeof(S32), 1);
-
- mSharedVerts[remapSrc] = remapDst;
- }
- }
- }
-
- status = TRUE;
- }
- else
- {
- llerrs << "invalid mesh file header: " << fileName << llendl;
- status = FALSE;
- }
-
- if (0 == mNumJointNames)
- {
- allocateJointNames(1);
- }
-
- fclose( fp );
-
- return status;
-}
-
-//-----------------------------------------------------------------------------
-// getSharedVert()
-//-----------------------------------------------------------------------------
-const S32 *LLPolyMeshSharedData::getSharedVert(S32 vert)
-{
- if (mSharedVerts.count(vert) > 0)
- {
- return &mSharedVerts[vert];
- }
- return NULL;
-}
-
-//-----------------------------------------------------------------------------
-// getUV()
-//-----------------------------------------------------------------------------
-const LLVector2 &LLPolyMeshSharedData::getUVs(U32 index)
-{
- // TODO: convert all index variables to S32
- llassert((S32)index < mNumVertices);
-
- return mTexCoords[index];
-}
-
-//-----------------------------------------------------------------------------
-// LLPolyMesh()
-//-----------------------------------------------------------------------------
-LLPolyMesh::LLPolyMesh(LLPolyMeshSharedData *shared_data, LLPolyMesh *reference_mesh)
-{
- LLMemType mt(LLMemType::MTYPE_AVATAR_MESH);
-
- llassert(shared_data);
-
- mSharedData = shared_data;
- mReferenceMesh = reference_mesh;
- mAvatarp = NULL;
- mVertexData = NULL;
-
- mCurVertexCount = 0;
- mFaceIndexCount = 0;
- mFaceIndexOffset = 0;
- mFaceVertexCount = 0;
- mFaceVertexOffset = 0;
-
- if (shared_data->isLOD() && reference_mesh)
- {
- mCoords = reference_mesh->mCoords;
- mNormals = reference_mesh->mNormals;
- mScaledNormals = reference_mesh->mScaledNormals;
- mBinormals = reference_mesh->mBinormals;
- mScaledBinormals = reference_mesh->mScaledBinormals;
- mTexCoords = reference_mesh->mTexCoords;
- mClothingWeights = reference_mesh->mClothingWeights;
- }
- else
- {
- // Allocate memory without initializing every vector
- // NOTE: This makes asusmptions about the size of LLVector[234]
- int nverts = mSharedData->mNumVertices;
- int nfloats = nverts * (2*4 + 3*3 + 2 + 4);
- //use 16 byte aligned vertex data to make LLPolyMesh SSE friendly
- mVertexData = (F32*) ll_aligned_malloc_16(nfloats*4);
- int offset = 0;
- mCoords = (LLVector4*)(mVertexData + offset); offset += 4*nverts;
- mNormals = (LLVector4*)(mVertexData + offset); offset += 4*nverts;
- mClothingWeights = (LLVector4*)(mVertexData + offset); offset += 4*nverts;
- mTexCoords = (LLVector2*)(mVertexData + offset); offset += 2*nverts;
-
- // these members don't need to be 16-byte aligned, but the first one might be
- // read during an aligned memcpy of mTexCoords
- mScaledNormals = (LLVector3*)(mVertexData + offset); offset += 3*nverts;
- mBinormals = (LLVector3*)(mVertexData + offset); offset += 3*nverts;
- mScaledBinormals = (LLVector3*)(mVertexData + offset); offset += 3*nverts;
- initializeForMorph();
- }
-}
-
-
-//-----------------------------------------------------------------------------
-// ~LLPolyMesh()
-//-----------------------------------------------------------------------------
-LLPolyMesh::~LLPolyMesh()
-{
- S32 i;
- for (i = 0; i < mJointRenderData.count(); i++)
- {
- delete mJointRenderData[i];
- mJointRenderData[i] = NULL;
- }
-
- ll_aligned_free_16(mVertexData);
-
-}
-
-
-//-----------------------------------------------------------------------------
-// LLPolyMesh::getMesh()
-//-----------------------------------------------------------------------------
-LLPolyMesh *LLPolyMesh::getMesh(const std::string &name, LLPolyMesh* reference_mesh)
-{
- //-------------------------------------------------------------------------
- // search for an existing mesh by this name
- //-------------------------------------------------------------------------
- LLPolyMeshSharedData* meshSharedData = get_if_there(sGlobalSharedMeshList, name, (LLPolyMeshSharedData*)NULL);
- if (meshSharedData)
- {
-// llinfos << "Polymesh " << name << " found in global mesh table." << llendl;
- LLPolyMesh *poly_mesh = new LLPolyMesh(meshSharedData, reference_mesh);
- return poly_mesh;
- }
-
- //-------------------------------------------------------------------------
- // if not found, create a new one, add it to the list
- //-------------------------------------------------------------------------
- std::string full_path;
- full_path = gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,name);
-
- LLPolyMeshSharedData *mesh_data = new LLPolyMeshSharedData();
- if (reference_mesh)
- {
- mesh_data->setupLOD(reference_mesh->getSharedData());
- }
- if ( ! mesh_data->loadMesh( full_path ) )
- {
- delete mesh_data;
- return NULL;
- }
-
- LLPolyMesh *poly_mesh = new LLPolyMesh(mesh_data, reference_mesh);
-
-// llinfos << "Polymesh " << name << " added to global mesh table." << llendl;
- sGlobalSharedMeshList[name] = poly_mesh->mSharedData;
-
- return poly_mesh;
-}
-
-//-----------------------------------------------------------------------------
-// LLPolyMesh::freeAllMeshes()
-//-----------------------------------------------------------------------------
-void LLPolyMesh::freeAllMeshes()
-{
- // delete each item in the global lists
- for_each(sGlobalSharedMeshList.begin(), sGlobalSharedMeshList.end(), DeletePairedPointer());
- sGlobalSharedMeshList.clear();
-}
-
-LLPolyMeshSharedData *LLPolyMesh::getSharedData() const
-{
- return mSharedData;
-}
-
-
-//--------------------------------------------------------------------
-// LLPolyMesh::dumpDiagInfo()
-//--------------------------------------------------------------------
-void LLPolyMesh::dumpDiagInfo()
-{
- // keep track of totals
- U32 total_verts = 0;
- U32 total_faces = 0;
- U32 total_kb = 0;
-
- std::string buf;
-
- llinfos << "-----------------------------------------------------" << llendl;
- llinfos << " Global PolyMesh Table (DEBUG only)" << llendl;
- llinfos << " Verts Faces Mem(KB) Name" << llendl;
- llinfos << "-----------------------------------------------------" << llendl;
-
- // print each loaded mesh, and it's memory usage
- for(LLPolyMeshSharedDataTable::iterator iter = sGlobalSharedMeshList.begin();
- iter != sGlobalSharedMeshList.end(); ++iter)
- {
- const std::string& mesh_name = iter->first;
- LLPolyMeshSharedData* mesh = iter->second;
-
- S32 num_verts = mesh->mNumVertices;
- S32 num_faces = mesh->mNumFaces;
- U32 num_kb = mesh->getNumKB();
-
- buf = llformat("%8d %8d %8d %s", num_verts, num_faces, num_kb, mesh_name.c_str());
- llinfos << buf << llendl;
-
- total_verts += num_verts;
- total_faces += num_faces;
- total_kb += num_kb;
- }
-
- llinfos << "-----------------------------------------------------" << llendl;
- buf = llformat("%8d %8d %8d TOTAL", total_verts, total_faces, total_kb );
- llinfos << buf << llendl;
- llinfos << "-----------------------------------------------------" << llendl;
-}
-
-//-----------------------------------------------------------------------------
-// getWritableCoords()
-//-----------------------------------------------------------------------------
-LLVector4 *LLPolyMesh::getWritableCoords()
-{
- return mCoords;
-}
-
-//-----------------------------------------------------------------------------
-// getWritableNormals()
-//-----------------------------------------------------------------------------
-LLVector4 *LLPolyMesh::getWritableNormals()
-{
- return mNormals;
-}
-
-//-----------------------------------------------------------------------------
-// getWritableBinormals()
-//-----------------------------------------------------------------------------
-LLVector3 *LLPolyMesh::getWritableBinormals()
-{
- return mBinormals;
-}
-
-
-//-----------------------------------------------------------------------------
-// getWritableClothingWeights()
-//-----------------------------------------------------------------------------
-LLVector4 *LLPolyMesh::getWritableClothingWeights()
-{
- return mClothingWeights;
-}
-
-//-----------------------------------------------------------------------------
-// getWritableTexCoords()
-//-----------------------------------------------------------------------------
-LLVector2 *LLPolyMesh::getWritableTexCoords()
-{
- return mTexCoords;
-}
-
-//-----------------------------------------------------------------------------
-// getScaledNormals()
-//-----------------------------------------------------------------------------
-LLVector3 *LLPolyMesh::getScaledNormals()
-{
- return mScaledNormals;
-}
-
-//-----------------------------------------------------------------------------
-// getScaledBinormals()
-//-----------------------------------------------------------------------------
-LLVector3 *LLPolyMesh::getScaledBinormals()
-{
- return mScaledBinormals;
-}
-
-
-//-----------------------------------------------------------------------------
-// initializeForMorph()
-//-----------------------------------------------------------------------------
-void LLPolyMesh::initializeForMorph()
-{
- for (U32 i = 0; i < mSharedData->mNumVertices; ++i)
- {
- mCoords[i] = LLVector4(mSharedData->mBaseCoords[i]);
- mNormals[i] = LLVector4(mSharedData->mBaseNormals[i]);
- }
-
- memcpy(mScaledNormals, mSharedData->mBaseNormals, sizeof(LLVector3) * mSharedData->mNumVertices); /*Flawfinder: ignore*/
- memcpy(mBinormals, mSharedData->mBaseBinormals, sizeof(LLVector3) * mSharedData->mNumVertices); /*Flawfinder: ignore*/
- memcpy(mScaledBinormals, mSharedData->mBaseBinormals, sizeof(LLVector3) * mSharedData->mNumVertices); /*Flawfinder: ignore*/
- memcpy(mTexCoords, mSharedData->mTexCoords, sizeof(LLVector2) * mSharedData->mNumVertices); /*Flawfinder: ignore*/
- memset(mClothingWeights, 0, sizeof(LLVector4) * mSharedData->mNumVertices);
-}
-
-//-----------------------------------------------------------------------------
-// getMorphData()
-//-----------------------------------------------------------------------------
-LLPolyMorphData* LLPolyMesh::getMorphData(const std::string& morph_name)
-{
- if (!mSharedData)
- return NULL;
- for (LLPolyMeshSharedData::morphdata_list_t::iterator iter = mSharedData->mMorphData.begin();
- iter != mSharedData->mMorphData.end(); ++iter)
- {
- LLPolyMorphData *morph_data = *iter;
- if (morph_data->getName() == morph_name)
- {
- return morph_data;
- }
- }
- return NULL;
-}
-
-//-----------------------------------------------------------------------------
-// removeMorphData()
-//-----------------------------------------------------------------------------
-// // erasing but not deleting seems bad, but fortunately we don't actually use this...
-// void LLPolyMesh::removeMorphData(LLPolyMorphData *morph_target)
-// {
-// if (!mSharedData)
-// return;
-// mSharedData->mMorphData.erase(morph_target);
-// }
-
-//-----------------------------------------------------------------------------
-// deleteAllMorphData()
-//-----------------------------------------------------------------------------
-// void LLPolyMesh::deleteAllMorphData()
-// {
-// if (!mSharedData)
-// return;
-
-// for_each(mSharedData->mMorphData.begin(), mSharedData->mMorphData.end(), DeletePointer());
-// mSharedData->mMorphData.clear();
-// }
-
-//-----------------------------------------------------------------------------
-// getWritableWeights()
-//-----------------------------------------------------------------------------
-F32* LLPolyMesh::getWritableWeights() const
-{
- return mSharedData->mWeights;
-}
-
-//-----------------------------------------------------------------------------
-// LLPolySkeletalDistortionInfo()
-//-----------------------------------------------------------------------------
-LLPolySkeletalDistortionInfo::LLPolySkeletalDistortionInfo()
-{
-}
-
-BOOL LLPolySkeletalDistortionInfo::parseXml(LLXmlTreeNode* node)
-{
- llassert( node->hasName( "param" ) && node->getChildByName( "param_skeleton" ) );
-
- if (!LLViewerVisualParamInfo::parseXml(node))
- return FALSE;
-
- LLXmlTreeNode* skeletalParam = node->getChildByName("param_skeleton");
-
- if (NULL == skeletalParam)
- {
- llwarns << "Failed to getChildByName(\"param_skeleton\")"
- << llendl;
- return FALSE;
- }
-
- for( LLXmlTreeNode* bone = skeletalParam->getFirstChild(); bone; bone = skeletalParam->getNextChild() )
- {
- if (bone->hasName("bone"))
- {
- std::string name;
- LLVector3 scale;
- LLVector3 pos;
- BOOL haspos = FALSE;
-
- static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name");
- if (!bone->getFastAttributeString(name_string, name))
- {
- llwarns << "No bone name specified for skeletal param." << llendl;
- continue;
- }
-
- static LLStdStringHandle scale_string = LLXmlTree::addAttributeString("scale");
- if (!bone->getFastAttributeVector3(scale_string, scale))
- {
- llwarns << "No scale specified for bone " << name << "." << llendl;
- continue;
- }
-
- // optional offset deformation (translation)
- static LLStdStringHandle offset_string = LLXmlTree::addAttributeString("offset");
- if (bone->getFastAttributeVector3(offset_string, pos))
- {
- haspos = TRUE;
- }
- mBoneInfoList.push_back(LLPolySkeletalBoneInfo(name, scale, pos, haspos));
- }
- else
- {
- llwarns << "Unrecognized element " << bone->getName() << " in skeletal distortion" << llendl;
- continue;
- }
- }
- return TRUE;
-}
-
-//-----------------------------------------------------------------------------
-// LLPolySkeletalDistortion()
-//-----------------------------------------------------------------------------
-LLPolySkeletalDistortion::LLPolySkeletalDistortion(LLVOAvatar *avatarp)
-{
- mAvatar = avatarp;
- mDefaultVec.setVec(0.001f, 0.001f, 0.001f);
-}
-
-//-----------------------------------------------------------------------------
-// ~LLPolySkeletalDistortion()
-//-----------------------------------------------------------------------------
-LLPolySkeletalDistortion::~LLPolySkeletalDistortion()
-{
-}
-
-BOOL LLPolySkeletalDistortion::setInfo(LLPolySkeletalDistortionInfo *info)
-{
- llassert(mInfo == NULL);
- if (info->mID < 0)
- return FALSE;
- mInfo = info;
- mID = info->mID;
- setWeight(getDefaultWeight(), FALSE );
-
- LLPolySkeletalDistortionInfo::bone_info_list_t::iterator iter;
- for (iter = getInfo()->mBoneInfoList.begin(); iter != getInfo()->mBoneInfoList.end(); iter++)
- {
- LLPolySkeletalBoneInfo *bone_info = &(*iter);
- LLJoint* joint = mAvatar->getJoint(bone_info->mBoneName);
- if (!joint)
- {
- llwarns << "Joint " << bone_info->mBoneName << " not found." << llendl;
- continue;
- }
-
- if (mJointScales.find(joint) != mJointScales.end())
- {
- llwarns << "Scale deformation already supplied for joint " << joint->getName() << "." << llendl;
- }
-
- // store it
- mJointScales[joint] = bone_info->mScaleDeformation;
-
- // apply to children that need to inherit it
- for (LLJoint::child_list_t::iterator iter = joint->mChildren.begin();
- iter != joint->mChildren.end(); ++iter)
- {
- LLViewerJoint* child_joint = (LLViewerJoint*)(*iter);
- if (child_joint->inheritScale())
- {
- LLVector3 childDeformation = LLVector3(child_joint->getScale());
- childDeformation.scaleVec(bone_info->mScaleDeformation);
- mJointScales[child_joint] = childDeformation;
- }
- }
-
- if (bone_info->mHasPositionDeformation)
- {
- if (mJointOffsets.find(joint) != mJointOffsets.end())
- {
- llwarns << "Offset deformation already supplied for joint " << joint->getName() << "." << llendl;
- }
- mJointOffsets[joint] = bone_info->mPositionDeformation;
- }
- }
- return TRUE;
-}
-
-/*virtual*/ LLViewerVisualParam* LLPolySkeletalDistortion::cloneParam(LLWearable* wearable) const
-{
- LLPolySkeletalDistortion *new_param = new LLPolySkeletalDistortion(mAvatar);
- *new_param = *this;
- return new_param;
-}
-
-//-----------------------------------------------------------------------------
-// apply()
-//-----------------------------------------------------------------------------
-void LLPolySkeletalDistortion::apply( ESex avatar_sex )
-{
- F32 effective_weight = ( getSex() & avatar_sex ) ? mCurWeight : getDefaultWeight();
-
- LLJoint* joint;
- joint_vec_map_t::iterator iter;
-
- for (iter = mJointScales.begin();
- iter != mJointScales.end();
- iter++)
- {
- joint = iter->first;
- LLVector3 newScale = joint->getScale();
- LLVector3 scaleDelta = iter->second;
- newScale = newScale + (effective_weight * scaleDelta) - (mLastWeight * scaleDelta);
- joint->setScale(newScale);
- }
-
- for (iter = mJointOffsets.begin();
- iter != mJointOffsets.end();
- iter++)
- {
- joint = iter->first;
- LLVector3 newPosition = joint->getPosition();
- LLVector3 positionDelta = iter->second;
- newPosition = newPosition + (effective_weight * positionDelta) - (mLastWeight * positionDelta);
- joint->setPosition(newPosition);
- }
-
- if (mLastWeight != mCurWeight && !mIsAnimating)
- {
- mAvatar->setSkeletonSerialNum(mAvatar->getSkeletonSerialNum() + 1);
- }
- mLastWeight = mCurWeight;
-}
-
-
-LLPolyMorphData *clone_morph_param_duplicate(const LLPolyMorphData *src_data,
- const std::string &name)
-{
- LLPolyMorphData* cloned_morph_data = new LLPolyMorphData(*src_data);
- cloned_morph_data->mName = name;
- for (U32 v=0; v < cloned_morph_data->mNumIndices; v++)
- {
- cloned_morph_data->mCoords[v] = src_data->mCoords[v];
- cloned_morph_data->mNormals[v] = src_data->mNormals[v];
- cloned_morph_data->mBinormals[v] = src_data->mBinormals[v];
- }
- return cloned_morph_data;
-}
-
-LLPolyMorphData *clone_morph_param_direction(const LLPolyMorphData *src_data,
- const LLVector3 &direction,
- const std::string &name)
-{
- LLPolyMorphData* cloned_morph_data = new LLPolyMorphData(*src_data);
- cloned_morph_data->mName = name;
- for (U32 v=0; v < cloned_morph_data->mNumIndices; v++)
- {
- cloned_morph_data->mCoords[v] = direction;
- cloned_morph_data->mNormals[v] = LLVector3(0,0,0);
- cloned_morph_data->mBinormals[v] = LLVector3(0,0,0);
- }
- return cloned_morph_data;
-}
-
-LLPolyMorphData *clone_morph_param_cleavage(const LLPolyMorphData *src_data,
- F32 scale,
- const std::string &name)
-{
- LLPolyMorphData* cloned_morph_data = new LLPolyMorphData(*src_data);
- cloned_morph_data->mName = name;
- for (U32 v=0; v < cloned_morph_data->mNumIndices; v++)
- {
- cloned_morph_data->mCoords[v] = src_data->mCoords[v]*scale;
- cloned_morph_data->mNormals[v] = src_data->mNormals[v]*scale;
- cloned_morph_data->mBinormals[v] = src_data->mBinormals[v]*scale;
- if (cloned_morph_data->mCoords[v][1] < 0)
- {
- cloned_morph_data->mCoords[v][1] *= -1;
- cloned_morph_data->mNormals[v][1] *= -1;
- cloned_morph_data->mBinormals[v][1] *= -1;
- }
- }
- return cloned_morph_data;
-}
-
-// End
diff --git a/indra/newview/llpolymesh.h b/indra/newview/llpolymesh.h
deleted file mode 100644
index ba2bf85570..0000000000
--- a/indra/newview/llpolymesh.h
+++ /dev/null
@@ -1,438 +0,0 @@
-/**
- * @file llpolymesh.h
- * @brief Implementation of LLPolyMesh class
- *
- * $LicenseInfo:firstyear=2001&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$
- */
-
-#ifndef LL_LLPOLYMESH_H
-#define LL_LLPOLYMESH_H
-
-#include <string>
-#include <map>
-#include "llstl.h"
-
-#include "v3math.h"
-#include "v2math.h"
-#include "llquaternion.h"
-#include "llpolymorph.h"
-#include "lljoint.h"
-//#include "lldarray.h"
-
-class LLSkinJoint;
-class LLVOAvatar;
-class LLWearable;
-
-//#define USE_STRIPS // Use tri-strips for rendering.
-
-//-----------------------------------------------------------------------------
-// LLPolyFace
-// A set of 4 vertex indices.
-// An LLPolyFace can represent either a triangle or quad.
-// If the last index is -1, it's a triangle.
-//-----------------------------------------------------------------------------
-typedef S32 LLPolyFace[3];
-
-//struct PrimitiveGroup;
-
-//-----------------------------------------------------------------------------
-// LLPolyMesh
-// A polyhedra consisting of any number of triangles and quads.
-// All instances contain a set of faces, and optionally may include
-// faces grouped into named face sets.
-//-----------------------------------------------------------------------------
-class LLPolyMorphTarget;
-
-class LLPolyMeshSharedData
-{
- friend class LLPolyMesh;
-private:
- // transform data
- LLVector3 mPosition;
- LLQuaternion mRotation;
- LLVector3 mScale;
-
- // vertex data
- S32 mNumVertices;
- LLVector3 *mBaseCoords;
- LLVector3 *mBaseNormals;
- LLVector3 *mBaseBinormals;
- LLVector2 *mTexCoords;
- LLVector2 *mDetailTexCoords;
- F32 *mWeights;
-
- BOOL mHasWeights;
- BOOL mHasDetailTexCoords;
-
- // face data
- S32 mNumFaces;
- LLPolyFace *mFaces;
-
- // face set data
- U32 mNumJointNames;
- std::string* mJointNames;
-
- // morph targets
- typedef std::set<LLPolyMorphData*> morphdata_list_t;
- morphdata_list_t mMorphData;
-
- std::map<S32, S32> mSharedVerts;
-
- LLPolyMeshSharedData* mReferenceData;
- S32 mLastIndexOffset;
-
-public:
- // Temporarily...
- // Triangle indices
- U32 mNumTriangleIndices;
- U32 *mTriangleIndices;
-
-public:
- LLPolyMeshSharedData();
- ~LLPolyMeshSharedData();
-
-private:
- void setupLOD(LLPolyMeshSharedData* reference_data);
-
- // Frees all mesh memory resources
- void freeMeshData();
-
- void setPosition( const LLVector3 &pos ) { mPosition = pos; }
- void setRotation( const LLQuaternion &rot ) { mRotation = rot; }
- void setScale( const LLVector3 &scale ) { mScale = scale; }
-
- BOOL allocateVertexData( U32 numVertices );
-
- BOOL allocateFaceData( U32 numFaces );
-
- BOOL allocateJointNames( U32 numJointNames );
-
- // Retrieve the number of KB of memory used by this instance
- U32 getNumKB();
-
- // Load mesh data from file
- BOOL loadMesh( const std::string& fileName );
-
-public:
- void genIndices(S32 offset);
-
- const LLVector2 &getUVs(U32 index);
-
- const S32 *getSharedVert(S32 vert);
-
- BOOL isLOD() { return (mReferenceData != NULL); }
-};
-
-
-class LLJointRenderData
-{
-public:
- LLJointRenderData(const LLMatrix4* world_matrix, LLSkinJoint* skin_joint) : mWorldMatrix(world_matrix), mSkinJoint(skin_joint) {}
- ~LLJointRenderData(){}
-
- const LLMatrix4* mWorldMatrix;
- LLSkinJoint* mSkinJoint;
-};
-
-
-class LLPolyMesh
-{
-public:
-
- // Constructor
- LLPolyMesh(LLPolyMeshSharedData *shared_data, LLPolyMesh *reference_mesh);
-
- // Destructor
- ~LLPolyMesh();
-
- // Requests a mesh by name.
- // If the mesh already exists in the global mesh table, it is returned,
- // otherwise it is loaded from file, added to the table, and returned.
- static LLPolyMesh *getMesh( const std::string &name, LLPolyMesh* reference_mesh = NULL);
-
- // Frees all loaded meshes.
- // This should only be called once you know there are no outstanding
- // references to these objects. Generally, upon exit of the application.
- static void freeAllMeshes();
-
- //--------------------------------------------------------------------
- // Transform Data Access
- //--------------------------------------------------------------------
- // Get position
- const LLVector3 &getPosition() {
- llassert (mSharedData);
- return mSharedData->mPosition;
- }
-
- // Get rotation
- const LLQuaternion &getRotation() {
- llassert (mSharedData);
- return mSharedData->mRotation;
- }
-
- // Get scale
- const LLVector3 &getScale() {
- llassert (mSharedData);
- return mSharedData->mScale;
- }
-
- //--------------------------------------------------------------------
- // Vertex Data Access
- //--------------------------------------------------------------------
- // Get number of vertices
- U32 getNumVertices() {
- llassert (mSharedData);
- return mSharedData->mNumVertices;
- }
-
- // Returns whether or not the mesh has detail texture coords
- BOOL hasDetailTexCoords() {
- llassert (mSharedData);
- return mSharedData->mHasDetailTexCoords;
- }
-
- // Returns whether or not the mesh has vertex weights
- BOOL hasWeights() const{
- llassert (mSharedData);
- return mSharedData->mHasWeights;
- }
-
- // Get coords
- const LLVector4 *getCoords() const{
- return mCoords;
- }
-
- // non const version
- LLVector4 *getWritableCoords();
-
- // Get normals
- const LLVector4 *getNormals() const{
- return mNormals;
- }
-
- // Get normals
- const LLVector3 *getBinormals() const{
- return mBinormals;
- }
-
- // Get base mesh normals
- const LLVector3 *getBaseNormals() const{
- llassert(mSharedData);
- return mSharedData->mBaseNormals;
- }
-
- // Get base mesh normals
- const LLVector3 *getBaseBinormals() const{
- llassert(mSharedData);
- return mSharedData->mBaseBinormals;
- }
-
- // intermediate morphed normals and output normals
- LLVector4 *getWritableNormals();
- LLVector3 *getScaledNormals();
-
- LLVector3 *getWritableBinormals();
- LLVector3 *getScaledBinormals();
-
- // Get texCoords
- const LLVector2 *getTexCoords() const {
- return mTexCoords;
- }
-
- // non const version
- LLVector2 *getWritableTexCoords();
-
- // Get detailTexCoords
- const LLVector2 *getDetailTexCoords() const {
- llassert (mSharedData);
- return mSharedData->mDetailTexCoords;
- }
-
- // Get weights
- const F32 *getWeights() const {
- llassert (mSharedData);
- return mSharedData->mWeights;
- }
-
- F32 *getWritableWeights() const;
-
- LLVector4 *getWritableClothingWeights();
-
- const LLVector4 *getClothingWeights()
- {
- return mClothingWeights;
- }
-
- //--------------------------------------------------------------------
- // Face Data Access
- //--------------------------------------------------------------------
- // Get number of faces
- S32 getNumFaces() {
- llassert (mSharedData);
- return mSharedData->mNumFaces;
- }
-
- // Get faces
- LLPolyFace *getFaces() {
- llassert (mSharedData);
- return mSharedData->mFaces;
- }
-
- U32 getNumJointNames() {
- llassert (mSharedData);
- return mSharedData->mNumJointNames;
- }
-
- std::string *getJointNames() {
- llassert (mSharedData);
- return mSharedData->mJointNames;
- }
-
- LLPolyMorphData* getMorphData(const std::string& morph_name);
-// void removeMorphData(LLPolyMorphData *morph_target);
-// void deleteAllMorphData();
-
- LLPolyMeshSharedData *getSharedData() const;
- LLPolyMesh *getReferenceMesh() { return mReferenceMesh ? mReferenceMesh : this; }
-
- // Get indices
- U32* getIndices() { return mSharedData ? mSharedData->mTriangleIndices : NULL; }
-
- BOOL isLOD() { return mSharedData && mSharedData->isLOD(); }
-
- void setAvatar(LLVOAvatar* avatarp) { mAvatarp = avatarp; }
- LLVOAvatar* getAvatar() { return mAvatarp; }
-
- LLDynamicArray<LLJointRenderData*> mJointRenderData;
-
- U32 mFaceVertexOffset;
- U32 mFaceVertexCount;
- U32 mFaceIndexOffset;
- U32 mFaceIndexCount;
- U32 mCurVertexCount;
-private:
- void initializeForMorph();
-
- // Dumps diagnostic information about the global mesh table
- static void dumpDiagInfo();
-
-protected:
- // mesh data shared across all instances of a given mesh
- LLPolyMeshSharedData *mSharedData;
- // Single array of floats for allocation / deletion
- F32 *mVertexData;
- // deformed vertices (resulting from application of morph targets)
- LLVector4 *mCoords;
- // deformed normals (resulting from application of morph targets)
- LLVector3 *mScaledNormals;
- // output normals (after normalization)
- LLVector4 *mNormals;
- // deformed binormals (resulting from application of morph targets)
- LLVector3 *mScaledBinormals;
- // output binormals (after normalization)
- LLVector3 *mBinormals;
- // weight values that mark verts as clothing/skin
- LLVector4 *mClothingWeights;
- // output texture coordinates
- LLVector2 *mTexCoords;
-
- LLPolyMesh *mReferenceMesh;
-
- // global mesh list
- typedef std::map<std::string, LLPolyMeshSharedData*> LLPolyMeshSharedDataTable;
- static LLPolyMeshSharedDataTable sGlobalSharedMeshList;
-
- // Backlink only; don't make this an LLPointer.
- LLVOAvatar* mAvatarp;
-};
-
-//-----------------------------------------------------------------------------
-// LLPolySkeletalDeformationInfo
-// Shared information for LLPolySkeletalDeformations
-//-----------------------------------------------------------------------------
-struct LLPolySkeletalBoneInfo
-{
- LLPolySkeletalBoneInfo(std::string &name, LLVector3 &scale, LLVector3 &pos, BOOL haspos)
- : mBoneName(name),
- mScaleDeformation(scale),
- mPositionDeformation(pos),
- mHasPositionDeformation(haspos) {}
- std::string mBoneName;
- LLVector3 mScaleDeformation;
- LLVector3 mPositionDeformation;
- BOOL mHasPositionDeformation;
-};
-
-class LLPolySkeletalDistortionInfo : public LLViewerVisualParamInfo
-{
- friend class LLPolySkeletalDistortion;
-public:
- LLPolySkeletalDistortionInfo();
- /*virtual*/ ~LLPolySkeletalDistortionInfo() {};
-
- /*virtual*/ BOOL parseXml(LLXmlTreeNode* node);
-
-protected:
- typedef std::vector<LLPolySkeletalBoneInfo> bone_info_list_t;
- bone_info_list_t mBoneInfoList;
-};
-
-//-----------------------------------------------------------------------------
-// LLPolySkeletalDeformation
-// A set of joint scale data for deforming the avatar mesh
-//-----------------------------------------------------------------------------
-class LLPolySkeletalDistortion : public LLViewerVisualParam
-{
-public:
- LLPolySkeletalDistortion(LLVOAvatar *avatarp);
- ~LLPolySkeletalDistortion();
-
- // Special: These functions are overridden by child classes
- LLPolySkeletalDistortionInfo* getInfo() const { return (LLPolySkeletalDistortionInfo*)mInfo; }
- // This sets mInfo and calls initialization functions
- BOOL setInfo(LLPolySkeletalDistortionInfo *info);
-
- /*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable) const;
-
- // LLVisualParam Virtual functions
- ///*virtual*/ BOOL parseData(LLXmlTreeNode* node);
- /*virtual*/ void apply( ESex sex );
-
- // LLViewerVisualParam Virtual functions
- /*virtual*/ F32 getTotalDistortion() { return 0.1f; }
- /*virtual*/ const LLVector3& getAvgDistortion() { return mDefaultVec; }
- /*virtual*/ F32 getMaxDistortion() { return 0.1f; }
- /*virtual*/ LLVector3 getVertexDistortion(S32 index, LLPolyMesh *poly_mesh){return LLVector3(0.001f, 0.001f, 0.001f);}
- /*virtual*/ const LLVector3* getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh){index = 0; poly_mesh = NULL; return &mDefaultVec;};
- /*virtual*/ const LLVector3* getNextDistortion(U32 *index, LLPolyMesh **poly_mesh){index = 0; poly_mesh = NULL; return NULL;};
-
-protected:
- typedef std::map<LLJoint*, LLVector3> joint_vec_map_t;
- joint_vec_map_t mJointScales;
- joint_vec_map_t mJointOffsets;
- LLVector3 mDefaultVec;
- // Backlink only; don't make this an LLPointer.
- LLVOAvatar *mAvatar;
-};
-
-#endif // LL_LLPOLYMESH_H
-
diff --git a/indra/newview/llpolymorph.cpp b/indra/newview/llpolymorph.cpp
deleted file mode 100644
index cefd7df3fe..0000000000
--- a/indra/newview/llpolymorph.cpp
+++ /dev/null
@@ -1,718 +0,0 @@
-/**
- * @file llpolymorph.cpp
- * @brief Implementation of LLPolyMesh class
- *
- * $LicenseInfo:firstyear=2001&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$
- */
-
-//-----------------------------------------------------------------------------
-// Header Files
-//-----------------------------------------------------------------------------
-#include "llviewerprecompiledheaders.h"
-
-#include "llpolymorph.h"
-#include "llvoavatar.h"
-#include "llwearable.h"
-#include "llxmltree.h"
-#include "llendianswizzle.h"
-
-//#include "../tools/imdebug/imdebug.h"
-
-const F32 NORMAL_SOFTEN_FACTOR = 0.65f;
-
-//-----------------------------------------------------------------------------
-// LLPolyMorphData()
-//-----------------------------------------------------------------------------
-LLPolyMorphData::LLPolyMorphData(const std::string& morph_name)
- : mName(morph_name)
-{
- mNumIndices = 0;
- mCurrentIndex = 0;
- mTotalDistortion = 0.f;
- mAvgDistortion.zeroVec();
- mMaxDistortion = 0.f;
- mVertexIndices = NULL;
- mCoords = NULL;
- mNormals = NULL;
- mBinormals = NULL;
- mTexCoords = NULL;
-
- mMesh = NULL;
-}
-
-LLPolyMorphData::LLPolyMorphData(const LLPolyMorphData &rhs) :
- mName(rhs.mName),
- mNumIndices(rhs.mNumIndices),
- mTotalDistortion(rhs.mTotalDistortion),
- mAvgDistortion(rhs.mAvgDistortion),
- mMaxDistortion(rhs.mMaxDistortion),
- mVertexIndices(NULL),
- mCoords(NULL),
- mNormals(NULL),
- mBinormals(NULL),
- mTexCoords(NULL)
-{
- const S32 numVertices = mNumIndices;
-
- mCoords = new LLVector3[numVertices];
- mNormals = new LLVector3[numVertices];
- mBinormals = new LLVector3[numVertices];
- mTexCoords = new LLVector2[numVertices];
- mVertexIndices = new U32[numVertices];
-
- for (S32 v=0; v < numVertices; v++)
- {
- mCoords[v] = rhs.mCoords[v];
- mNormals[v] = rhs.mNormals[v];
- mBinormals[v] = rhs.mBinormals[v];
- mTexCoords[v] = rhs.mTexCoords[v];
- mVertexIndices[v] = rhs.mVertexIndices[v];
- }
-}
-
-
-//-----------------------------------------------------------------------------
-// ~LLPolyMorphData()
-//-----------------------------------------------------------------------------
-LLPolyMorphData::~LLPolyMorphData()
-{
- delete [] mVertexIndices;
- delete [] mCoords;
- delete [] mNormals;
- delete [] mBinormals;
- delete [] mTexCoords;
-}
-
-//-----------------------------------------------------------------------------
-// loadBinary()
-//-----------------------------------------------------------------------------
-BOOL LLPolyMorphData::loadBinary(LLFILE *fp, LLPolyMeshSharedData *mesh)
-{
- S32 numVertices;
- S32 numRead;
-
- numRead = fread(&numVertices, sizeof(S32), 1, fp);
- llendianswizzle(&numVertices, sizeof(S32), 1);
- if (numRead != 1)
- {
- llwarns << "Can't read number of morph target vertices" << llendl;
- return FALSE;
- }
-
- //-------------------------------------------------------------------------
- // allocate vertices
- //-------------------------------------------------------------------------
- mCoords = new LLVector3[numVertices];
- mNormals = new LLVector3[numVertices];
- mBinormals = new LLVector3[numVertices];
- mTexCoords = new LLVector2[numVertices];
- // Actually, we are allocating more space than we need for the skiplist
- mVertexIndices = new U32[numVertices];
- mNumIndices = 0;
- mTotalDistortion = 0.f;
- mMaxDistortion = 0.f;
- mAvgDistortion.zeroVec();
- mMesh = mesh;
-
- //-------------------------------------------------------------------------
- // read vertices
- //-------------------------------------------------------------------------
- for(S32 v = 0; v < numVertices; v++)
- {
- numRead = fread(&mVertexIndices[v], sizeof(U32), 1, fp);
- llendianswizzle(&mVertexIndices[v], sizeof(U32), 1);
- if (numRead != 1)
- {
- llwarns << "Can't read morph target vertex number" << llendl;
- return FALSE;
- }
-
- if (mVertexIndices[v] > 10000)
- {
- llerrs << "Bad morph index: " << mVertexIndices[v] << llendl;
- }
-
-
- numRead = fread(&mCoords[v].mV, sizeof(F32), 3, fp);
- llendianswizzle(&mCoords[v].mV, sizeof(F32), 3);
- if (numRead != 3)
- {
- llwarns << "Can't read morph target vertex coordinates" << llendl;
- return FALSE;
- }
-
- F32 magnitude = mCoords[v].magVec();
-
- mTotalDistortion += magnitude;
- mAvgDistortion.mV[VX] += fabs(mCoords[v].mV[VX]);
- mAvgDistortion.mV[VY] += fabs(mCoords[v].mV[VY]);
- mAvgDistortion.mV[VZ] += fabs(mCoords[v].mV[VZ]);
-
- if (magnitude > mMaxDistortion)
- {
- mMaxDistortion = magnitude;
- }
-
- numRead = fread(&mNormals[v].mV, sizeof(F32), 3, fp);
- llendianswizzle(&mNormals[v].mV, sizeof(F32), 3);
- if (numRead != 3)
- {
- llwarns << "Can't read morph target normal" << llendl;
- return FALSE;
- }
-
- numRead = fread(&mBinormals[v].mV, sizeof(F32), 3, fp);
- llendianswizzle(&mBinormals[v].mV, sizeof(F32), 3);
- if (numRead != 3)
- {
- llwarns << "Can't read morph target binormal" << llendl;
- return FALSE;
- }
-
-
- numRead = fread(&mTexCoords[v].mV, sizeof(F32), 2, fp);
- llendianswizzle(&mTexCoords[v].mV, sizeof(F32), 2);
- if (numRead != 2)
- {
- llwarns << "Can't read morph target uv" << llendl;
- return FALSE;
- }
-
- mNumIndices++;
- }
-
- mAvgDistortion = mAvgDistortion * (1.f/(F32)mNumIndices);
- mAvgDistortion.normVec();
-
- return TRUE;
-}
-
-//-----------------------------------------------------------------------------
-// LLPolyMorphTargetInfo()
-//-----------------------------------------------------------------------------
-LLPolyMorphTargetInfo::LLPolyMorphTargetInfo()
- : mIsClothingMorph(FALSE)
-{
-}
-
-BOOL LLPolyMorphTargetInfo::parseXml(LLXmlTreeNode* node)
-{
- llassert( node->hasName( "param" ) && node->getChildByName( "param_morph" ) );
-
- if (!LLViewerVisualParamInfo::parseXml(node))
- return FALSE;
-
- // Get mixed-case name
- static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name");
- if( !node->getFastAttributeString( name_string, mMorphName ) )
- {
- llwarns << "Avatar file: <param> is missing name attribute" << llendl;
- return FALSE; // Continue, ignoring this tag
- }
-
- static LLStdStringHandle clothing_morph_string = LLXmlTree::addAttributeString("clothing_morph");
- node->getFastAttributeBOOL(clothing_morph_string, mIsClothingMorph);
-
- LLXmlTreeNode *paramNode = node->getChildByName("param_morph");
-
- if (NULL == paramNode)
- {
- llwarns << "Failed to getChildByName(\"param_morph\")"
- << llendl;
- return FALSE;
- }
-
- for (LLXmlTreeNode* child_node = paramNode->getFirstChild();
- child_node;
- child_node = paramNode->getNextChild())
- {
- static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name");
- if (child_node->hasName("volume_morph"))
- {
- std::string volume_name;
- if (child_node->getFastAttributeString(name_string, volume_name))
- {
- LLVector3 scale;
- static LLStdStringHandle scale_string = LLXmlTree::addAttributeString("scale");
- child_node->getFastAttributeVector3(scale_string, scale);
-
- LLVector3 pos;
- static LLStdStringHandle pos_string = LLXmlTree::addAttributeString("pos");
- child_node->getFastAttributeVector3(pos_string, pos);
-
- mVolumeInfoList.push_back(LLPolyVolumeMorphInfo(volume_name,scale,pos));
- }
- }
- }
-
- return TRUE;
-}
-
-//-----------------------------------------------------------------------------
-// LLPolyMorphTarget()
-//-----------------------------------------------------------------------------
-LLPolyMorphTarget::LLPolyMorphTarget(LLPolyMesh *poly_mesh)
- : mMorphData(NULL), mMesh(poly_mesh),
- mVertMask(NULL),
- mLastSex(SEX_FEMALE),
- mNumMorphMasksPending(0)
-{
-}
-
-//-----------------------------------------------------------------------------
-// ~LLPolyMorphTarget()
-//-----------------------------------------------------------------------------
-LLPolyMorphTarget::~LLPolyMorphTarget()
-{
- if (mVertMask)
- {
- delete mVertMask;
- }
-}
-
-//-----------------------------------------------------------------------------
-// setInfo()
-//-----------------------------------------------------------------------------
-BOOL LLPolyMorphTarget::setInfo(LLPolyMorphTargetInfo* info)
-{
- llassert(mInfo == NULL);
- if (info->mID < 0)
- return FALSE;
- mInfo = info;
- mID = info->mID;
- setWeight(getDefaultWeight(), FALSE );
-
- LLVOAvatar* avatarp = mMesh->getAvatar();
- LLPolyMorphTargetInfo::volume_info_list_t::iterator iter;
- for (iter = getInfo()->mVolumeInfoList.begin(); iter != getInfo()->mVolumeInfoList.end(); iter++)
- {
- LLPolyVolumeMorphInfo *volume_info = &(*iter);
- for (S32 i = 0; i < avatarp->mNumCollisionVolumes; i++)
- {
- if (avatarp->mCollisionVolumes[i].getName() == volume_info->mName)
- {
- mVolumeMorphs.push_back(LLPolyVolumeMorph(&avatarp->mCollisionVolumes[i],
- volume_info->mScale,
- volume_info->mPos));
- break;
- }
- }
- }
-
- std::string morph_param_name = getInfo()->mMorphName;
-
- mMorphData = mMesh->getMorphData(morph_param_name);
- if (!mMorphData)
- {
- const std::string driven_tag = "_Driven";
- U32 pos = morph_param_name.find(driven_tag);
- if (pos > 0)
- {
- morph_param_name = morph_param_name.substr(0,pos);
- mMorphData = mMesh->getMorphData(morph_param_name);
- }
- }
- if (!mMorphData)
- {
- llwarns << "No morph target named " << morph_param_name << " found in mesh." << llendl;
- return FALSE; // Continue, ignoring this tag
- }
- return TRUE;
-}
-
-/*virtual*/ LLViewerVisualParam* LLPolyMorphTarget::cloneParam(LLWearable* wearable) const
-{
- LLPolyMorphTarget *new_param = new LLPolyMorphTarget(mMesh);
- *new_param = *this;
- return new_param;
-}
-
-#if 0 // obsolete
-//-----------------------------------------------------------------------------
-// parseData()
-//-----------------------------------------------------------------------------
-BOOL LLPolyMorphTarget::parseData(LLXmlTreeNode* node)
-{
- LLPolyMorphTargetInfo* info = new LLPolyMorphTargetInfo;
-
- info->parseXml(node);
- if (!setInfo(info))
- {
- delete info;
- return FALSE;
- }
- return TRUE;
-}
-#endif
-
-//-----------------------------------------------------------------------------
-// getVertexDistortion()
-//-----------------------------------------------------------------------------
-LLVector3 LLPolyMorphTarget::getVertexDistortion(S32 requested_index, LLPolyMesh *mesh)
-{
- if (!mMorphData || mMesh != mesh) return LLVector3::zero;
-
- for(U32 index = 0; index < mMorphData->mNumIndices; index++)
- {
- if (mMorphData->mVertexIndices[index] == (U32)requested_index)
- {
- return mMorphData->mCoords[index];
- }
- }
-
- return LLVector3::zero;
-}
-
-//-----------------------------------------------------------------------------
-// getFirstDistortion()
-//-----------------------------------------------------------------------------
-const LLVector3 *LLPolyMorphTarget::getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh)
-{
- if (!mMorphData) return &LLVector3::zero;
-
- LLVector3* resultVec;
- mMorphData->mCurrentIndex = 0;
- if (mMorphData->mNumIndices)
- {
- resultVec = &mMorphData->mCoords[mMorphData->mCurrentIndex];
- if (index != NULL)
- {
- *index = mMorphData->mVertexIndices[mMorphData->mCurrentIndex];
- }
- if (poly_mesh != NULL)
- {
- *poly_mesh = mMesh;
- }
-
- return resultVec;
- }
- return NULL;
-}
-
-//-----------------------------------------------------------------------------
-// getNextDistortion()
-//-----------------------------------------------------------------------------
-const LLVector3 *LLPolyMorphTarget::getNextDistortion(U32 *index, LLPolyMesh **poly_mesh)
-{
- if (!mMorphData) return &LLVector3::zero;
-
- LLVector3* resultVec;
- mMorphData->mCurrentIndex++;
- if (mMorphData->mCurrentIndex < mMorphData->mNumIndices)
- {
- resultVec = &mMorphData->mCoords[mMorphData->mCurrentIndex];
- if (index != NULL)
- {
- *index = mMorphData->mVertexIndices[mMorphData->mCurrentIndex];
- }
- if (poly_mesh != NULL)
- {
- *poly_mesh = mMesh;
- }
- return resultVec;
- }
- return NULL;
-}
-
-//-----------------------------------------------------------------------------
-// getTotalDistortion()
-//-----------------------------------------------------------------------------
-F32 LLPolyMorphTarget::getTotalDistortion()
-{
- if (mMorphData)
- {
- return mMorphData->mTotalDistortion;
- }
- else
- {
- return 0.f;
- }
-}
-
-//-----------------------------------------------------------------------------
-// getAvgDistortion()
-//-----------------------------------------------------------------------------
-const LLVector3& LLPolyMorphTarget::getAvgDistortion()
-{
- if (mMorphData)
- {
- return mMorphData->mAvgDistortion;
- }
- else
- {
- return LLVector3::zero;
- }
-}
-
-//-----------------------------------------------------------------------------
-// getMaxDistortion()
-//-----------------------------------------------------------------------------
-F32 LLPolyMorphTarget::getMaxDistortion()
-{
- if (mMorphData)
- {
- return mMorphData->mMaxDistortion;
- }
- else
- {
- return 0.f;
- }
-}
-
-//-----------------------------------------------------------------------------
-// apply()
-//-----------------------------------------------------------------------------
-void LLPolyMorphTarget::apply( ESex avatar_sex )
-{
- if (!mMorphData || mNumMorphMasksPending > 0)
- {
- return;
- }
-
- mLastSex = avatar_sex;
-
- // Check for NaN condition (NaN is detected if a variable doesn't equal itself.
- if (mCurWeight != mCurWeight)
- {
- mCurWeight = 0.0;
- }
- if (mLastWeight != mLastWeight)
- {
- mLastWeight = mCurWeight+.001;
- }
-
- // perform differential update of morph
- F32 delta_weight = ( getSex() & avatar_sex ) ? (mCurWeight - mLastWeight) : (getDefaultWeight() - mLastWeight);
- // store last weight
- mLastWeight += delta_weight;
-
- if (delta_weight != 0.f)
- {
- llassert(!mMesh->isLOD());
- LLVector4 *coords = mMesh->getWritableCoords();
-
- LLVector3 *scaled_normals = mMesh->getScaledNormals();
- LLVector4 *normals = mMesh->getWritableNormals();
-
- LLVector3 *scaled_binormals = mMesh->getScaledBinormals();
- LLVector3 *binormals = mMesh->getWritableBinormals();
-
- LLVector4 *clothing_weights = mMesh->getWritableClothingWeights();
- LLVector2 *tex_coords = mMesh->getWritableTexCoords();
-
- F32 *maskWeightArray = (mVertMask) ? mVertMask->getMorphMaskWeights() : NULL;
-
- for(U32 vert_index_morph = 0; vert_index_morph < mMorphData->mNumIndices; vert_index_morph++)
- {
- S32 vert_index_mesh = mMorphData->mVertexIndices[vert_index_morph];
-
- F32 maskWeight = 1.f;
- if (maskWeightArray)
- {
- maskWeight = maskWeightArray[vert_index_morph];
- }
-
- coords[vert_index_mesh] += LLVector4(mMorphData->mCoords[vert_index_morph] * delta_weight * maskWeight);
-
- if (getInfo()->mIsClothingMorph && clothing_weights)
- {
- LLVector3 clothing_offset = mMorphData->mCoords[vert_index_morph] * delta_weight * maskWeight;
- LLVector4* clothing_weight = &clothing_weights[vert_index_mesh];
- clothing_weight->mV[VX] += clothing_offset.mV[VX];
- clothing_weight->mV[VY] += clothing_offset.mV[VY];
- clothing_weight->mV[VZ] += clothing_offset.mV[VZ];
- clothing_weight->mV[VW] = maskWeight;
- }
-
- // calculate new normals based on half angles
- scaled_normals[vert_index_mesh] += mMorphData->mNormals[vert_index_morph] * delta_weight * maskWeight * NORMAL_SOFTEN_FACTOR;
- LLVector3 normalized_normal = scaled_normals[vert_index_mesh];
- normalized_normal.normVec();
- normals[vert_index_mesh] = LLVector4(normalized_normal);
-
- // calculate new binormals
- scaled_binormals[vert_index_mesh] += mMorphData->mBinormals[vert_index_morph] * delta_weight * maskWeight * NORMAL_SOFTEN_FACTOR;
- LLVector3 tangent = scaled_binormals[vert_index_mesh] % normalized_normal;
- LLVector3 normalized_binormal = normalized_normal % tangent;
- normalized_binormal.normVec();
- binormals[vert_index_mesh] = normalized_binormal;
-
- tex_coords[vert_index_mesh] += mMorphData->mTexCoords[vert_index_morph] * delta_weight * maskWeight;
- }
-
- // now apply volume changes
- for( volume_list_t::iterator iter = mVolumeMorphs.begin(); iter != mVolumeMorphs.end(); iter++ )
- {
- LLPolyVolumeMorph* volume_morph = &(*iter);
- LLVector3 scale_delta = volume_morph->mScale * delta_weight;
- LLVector3 pos_delta = volume_morph->mPos * delta_weight;
-
- volume_morph->mVolume->setScale(volume_morph->mVolume->getScale() + scale_delta);
- volume_morph->mVolume->setPosition(volume_morph->mVolume->getPosition() + pos_delta);
- }
- }
-
- if (mNext)
- {
- mNext->apply(avatar_sex);
- }
-}
-
-//-----------------------------------------------------------------------------
-// applyMask()
-//-----------------------------------------------------------------------------
-void LLPolyMorphTarget::applyMask(U8 *maskTextureData, S32 width, S32 height, S32 num_components, BOOL invert)
-{
- LLVector4 *clothing_weights = getInfo()->mIsClothingMorph ? mMesh->getWritableClothingWeights() : NULL;
-
- if (!mVertMask)
- {
- mVertMask = new LLPolyVertexMask(mMorphData);
- mNumMorphMasksPending--;
- }
- else
- {
- // remove effect of previous mask
- F32 *maskWeights = (mVertMask) ? mVertMask->getMorphMaskWeights() : NULL;
-
- if (maskWeights)
- {
- LLVector4 *coords = mMesh->getWritableCoords();
- LLVector3 *scaled_normals = mMesh->getScaledNormals();
- LLVector3 *scaled_binormals = mMesh->getScaledBinormals();
- LLVector2 *tex_coords = mMesh->getWritableTexCoords();
-
- for(U32 vert = 0; vert < mMorphData->mNumIndices; vert++)
- {
- F32 lastMaskWeight = mLastWeight * maskWeights[vert];
- S32 out_vert = mMorphData->mVertexIndices[vert];
-
- // remove effect of existing masked morph
- coords[out_vert] -= LLVector4(mMorphData->mCoords[vert]) * lastMaskWeight;
- scaled_normals[out_vert] -= mMorphData->mNormals[vert] * lastMaskWeight * NORMAL_SOFTEN_FACTOR;
- scaled_binormals[out_vert] -= mMorphData->mBinormals[vert] * lastMaskWeight * NORMAL_SOFTEN_FACTOR;
- tex_coords[out_vert] -= mMorphData->mTexCoords[vert] * lastMaskWeight;
-
- if (clothing_weights)
- {
- LLVector3 clothing_offset = mMorphData->mCoords[vert] * lastMaskWeight;
- LLVector4* clothing_weight = &clothing_weights[out_vert];
- clothing_weight->mV[VX] -= clothing_offset.mV[VX];
- clothing_weight->mV[VY] -= clothing_offset.mV[VY];
- clothing_weight->mV[VZ] -= clothing_offset.mV[VZ];
- }
- }
- }
- }
-
- // set last weight to 0, since we've removed the effect of this morph
- mLastWeight = 0.f;
-
- mVertMask->generateMask(maskTextureData, width, height, num_components, invert, clothing_weights);
-
- apply(mLastSex);
-}
-
-
-//-----------------------------------------------------------------------------
-// LLPolyVertexMask()
-//-----------------------------------------------------------------------------
-LLPolyVertexMask::LLPolyVertexMask(LLPolyMorphData* morph_data)
-{
- mWeights = new F32[morph_data->mNumIndices];
- mMorphData = morph_data;
- mWeightsGenerated = FALSE;
-}
-
-//-----------------------------------------------------------------------------
-// ~LLPolyVertexMask()
-//-----------------------------------------------------------------------------
-LLPolyVertexMask::~LLPolyVertexMask()
-{
- delete[] mWeights;
-}
-
-//-----------------------------------------------------------------------------
-// generateMask()
-//-----------------------------------------------------------------------------
-void LLPolyVertexMask::generateMask(U8 *maskTextureData, S32 width, S32 height, S32 num_components, BOOL invert, LLVector4 *clothing_weights)
-{
-// RN debug output that uses Image Debugger (http://www.cs.unc.edu/~baxter/projects/imdebug/)
-// BOOL debugImg = FALSE;
-// if (debugImg)
-// {
-// if (invert)
-// {
-// imdebug("lum rbga=rgba b=8 w=%d h=%d *-1 %p", width, height, maskTextureData);
-// }
-// else
-// {
-// imdebug("lum rbga=rgba b=8 w=%d h=%d %p", width, height, maskTextureData);
-// }
-// }
- for (U32 index = 0; index < mMorphData->mNumIndices; index++)
- {
- S32 vertIndex = mMorphData->mVertexIndices[index];
- const S32 *sharedVertIndex = mMorphData->mMesh->getSharedVert(vertIndex);
- LLVector2 uvCoords;
-
- if (sharedVertIndex)
- {
- uvCoords = mMorphData->mMesh->getUVs(*sharedVertIndex);
- }
- else
- {
- uvCoords = mMorphData->mMesh->getUVs(vertIndex);
- }
- U32 s = llclamp((U32)(uvCoords.mV[VX] * (F32)(width - 1)), (U32)0, (U32)width - 1);
- U32 t = llclamp((U32)(uvCoords.mV[VY] * (F32)(height - 1)), (U32)0, (U32)height - 1);
-
- mWeights[index] = ((F32) maskTextureData[((t * width + s) * num_components) + (num_components - 1)]) / 255.f;
-
- if (invert)
- {
- mWeights[index] = 1.f - mWeights[index];
- }
-
- // now apply step function
- // mWeights[index] = mWeights[index] > 0.95f ? 1.f : 0.f;
-
- if (clothing_weights)
- {
- clothing_weights[vertIndex].mV[VW] = mWeights[index];
- }
- }
- mWeightsGenerated = TRUE;
-}
-
-//-----------------------------------------------------------------------------
-// getMaskForMorphIndex()
-//-----------------------------------------------------------------------------
-F32* LLPolyVertexMask::getMorphMaskWeights()
-{
- if (!mWeightsGenerated)
- {
- return NULL;
- }
-
- return mWeights;
-}
diff --git a/indra/newview/llpolymorph.h b/indra/newview/llpolymorph.h
deleted file mode 100644
index 8a024f2e9e..0000000000
--- a/indra/newview/llpolymorph.h
+++ /dev/null
@@ -1,182 +0,0 @@
-/**
- * @file llpolymorph.h
- * @brief Implementation of LLPolyMesh class
- *
- * $LicenseInfo:firstyear=2001&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$
- */
-
-#ifndef LL_LLPOLYMORPH_H
-#define LL_LLPOLYMORPH_H
-
-#include <string>
-#include <vector>
-
-#include "llviewervisualparam.h"
-
-class LLPolyMeshSharedData;
-class LLVOAvatar;
-class LLVector2;
-class LLViewerJointCollisionVolume;
-class LLWearable;
-
-//-----------------------------------------------------------------------------
-// LLPolyMorphData()
-//-----------------------------------------------------------------------------
-class LLPolyMorphData
-{
-public:
- LLPolyMorphData(const std::string& morph_name);
- ~LLPolyMorphData();
- LLPolyMorphData(const LLPolyMorphData &rhs);
-
- BOOL loadBinary(LLFILE* fp, LLPolyMeshSharedData *mesh);
- const std::string& getName() { return mName; }
-
-public:
- std::string mName;
-
- // morphology
- U32 mNumIndices;
- U32* mVertexIndices;
- U32 mCurrentIndex;
- LLVector3* mCoords;
- LLVector3* mNormals;
- LLVector3* mBinormals;
- LLVector2* mTexCoords;
-
- F32 mTotalDistortion; // vertex distortion summed over entire morph
- F32 mMaxDistortion; // maximum single vertex distortion in a given morph
- LLVector3 mAvgDistortion; // average vertex distortion, to infer directionality of the morph
- LLPolyMeshSharedData* mMesh;
-};
-
-//-----------------------------------------------------------------------------
-// LLPolyVertexMask()
-//-----------------------------------------------------------------------------
-class LLPolyVertexMask
-{
-public:
- LLPolyVertexMask(LLPolyMorphData* morph_data);
- ~LLPolyVertexMask();
-
- void generateMask(U8 *maskData, S32 width, S32 height, S32 num_components, BOOL invert, LLVector4 *clothing_weights);
- F32* getMorphMaskWeights();
-
-
-protected:
- F32* mWeights;
- LLPolyMorphData *mMorphData;
- BOOL mWeightsGenerated;
-
-};
-
-//-----------------------------------------------------------------------------
-// LLPolyMorphTarget Data structs
-//-----------------------------------------------------------------------------
-struct LLPolyVolumeMorphInfo
-{
- LLPolyVolumeMorphInfo(std::string &name, LLVector3 &scale, LLVector3 &pos)
- : mName(name), mScale(scale), mPos(pos) {};
-
- std::string mName;
- LLVector3 mScale;
- LLVector3 mPos;
-};
-
-struct LLPolyVolumeMorph
-{
- LLPolyVolumeMorph(LLViewerJointCollisionVolume* volume, LLVector3 scale, LLVector3 pos)
- : mVolume(volume), mScale(scale), mPos(pos) {};
-
- LLViewerJointCollisionVolume* mVolume;
- LLVector3 mScale;
- LLVector3 mPos;
-};
-
-//-----------------------------------------------------------------------------
-// LLPolyMorphTargetInfo
-// Shared information for LLPolyMorphTargets
-//-----------------------------------------------------------------------------
-class LLPolyMorphTargetInfo : public LLViewerVisualParamInfo
-{
- friend class LLPolyMorphTarget;
-public:
- LLPolyMorphTargetInfo();
- /*virtual*/ ~LLPolyMorphTargetInfo() {};
-
- /*virtual*/ BOOL parseXml(LLXmlTreeNode* node);
-
-protected:
- std::string mMorphName;
- BOOL mIsClothingMorph;
- typedef std::vector<LLPolyVolumeMorphInfo> volume_info_list_t;
- volume_info_list_t mVolumeInfoList;
-};
-
-//-----------------------------------------------------------------------------
-// LLPolyMorphTarget
-// A set of vertex data associated with morph target.
-// These morph targets must be topologically consistent with a given Polymesh
-// (share face sets)
-//-----------------------------------------------------------------------------
-class LLPolyMorphTarget : public LLViewerVisualParam
-{
-public:
- LLPolyMorphTarget(LLPolyMesh *poly_mesh);
- ~LLPolyMorphTarget();
-
- // Special: These functions are overridden by child classes
- LLPolyMorphTargetInfo* getInfo() const { return (LLPolyMorphTargetInfo*)mInfo; }
- // This sets mInfo and calls initialization functions
- BOOL setInfo(LLPolyMorphTargetInfo *info);
-
- /*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable) const;
-
- // LLVisualParam Virtual functions
- ///*virtual*/ BOOL parseData(LLXmlTreeNode* node);
- /*virtual*/ void apply( ESex sex );
-
- // LLViewerVisualParam Virtual functions
- /*virtual*/ F32 getTotalDistortion();
- /*virtual*/ const LLVector3& getAvgDistortion();
- /*virtual*/ F32 getMaxDistortion();
- /*virtual*/ LLVector3 getVertexDistortion(S32 index, LLPolyMesh *poly_mesh);
- /*virtual*/ const LLVector3* getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh);
- /*virtual*/ const LLVector3* getNextDistortion(U32 *index, LLPolyMesh **poly_mesh);
-
- void applyMask(U8 *maskData, S32 width, S32 height, S32 num_components, BOOL invert);
- void addPendingMorphMask() { mNumMorphMasksPending++; }
-
-protected:
- LLPolyMorphData* mMorphData;
- LLPolyMesh* mMesh;
- LLPolyVertexMask * mVertMask;
- ESex mLastSex;
- // number of morph masks that haven't been generated, must be 0 before this morph is applied
- BOOL mNumMorphMasksPending;
-
- typedef std::vector<LLPolyVolumeMorph> volume_list_t;
- volume_list_t mVolumeMorphs;
-
-};
-
-#endif // LL_LLPOLYMORPH_H
diff --git a/indra/newview/llpopupview.cpp b/indra/newview/llpopupview.cpp
index 08829c1184..08829c1184 100644..100755
--- a/indra/newview/llpopupview.cpp
+++ b/indra/newview/llpopupview.cpp
diff --git a/indra/newview/llpopupview.h b/indra/newview/llpopupview.h
index b378f61984..b378f61984 100644..100755
--- a/indra/newview/llpopupview.h
+++ b/indra/newview/llpopupview.h
diff --git a/indra/newview/llpostcard.cpp b/indra/newview/llpostcard.cpp
index 4f2d6da7e5..aebe636f59 100644..100755
--- a/indra/newview/llpostcard.cpp
+++ b/indra/newview/llpostcard.cpp
@@ -35,6 +35,7 @@
#include "message.h"
#include "llagent.h"
+#include "llassetstorage.h"
#include "llassetuploadresponders.h"
///////////////////////////////////////////////////////////////////////////////
diff --git a/indra/newview/llpostcard.h b/indra/newview/llpostcard.h
index 0eb118b906..0eb118b906 100644..100755
--- a/indra/newview/llpostcard.h
+++ b/indra/newview/llpostcard.h
diff --git a/indra/newview/llpreview.cpp b/indra/newview/llpreview.cpp
index 18626e3273..04934b13f1 100644..100755
--- a/indra/newview/llpreview.cpp
+++ b/indra/newview/llpreview.cpp
@@ -464,7 +464,9 @@ LLMultiPreview::LLMultiPreview()
void LLMultiPreview::onOpen(const LLSD& key)
{
- LLPreview* frontmost_preview = (LLPreview*)mTabContainer->getCurrentPanel();
+ // Floater could be something else than LLPreview, eg LLFloaterProfile.
+ LLPreview* frontmost_preview = dynamic_cast<LLPreview*>(mTabContainer->getCurrentPanel());
+
if (frontmost_preview && frontmost_preview->getAssetStatus() == LLPreview::PREVIEW_ASSET_UNLOADED)
{
frontmost_preview->loadAsset();
@@ -477,8 +479,13 @@ void LLMultiPreview::handleReshape(const LLRect& new_rect, bool by_user)
{
if(new_rect.getWidth() != getRect().getWidth() || new_rect.getHeight() != getRect().getHeight())
{
- LLPreview* frontmost_preview = (LLPreview*)mTabContainer->getCurrentPanel();
- if (frontmost_preview) frontmost_preview->userResized();
+ // Floater could be something else than LLPreview, eg LLFloaterProfile.
+ LLPreview* frontmost_preview = dynamic_cast<LLPreview*>(mTabContainer->getCurrentPanel());
+
+ if (frontmost_preview)
+ {
+ frontmost_preview->userResized();
+ }
}
LLFloater::handleReshape(new_rect, by_user);
}
@@ -486,7 +493,9 @@ void LLMultiPreview::handleReshape(const LLRect& new_rect, bool by_user)
void LLMultiPreview::tabOpen(LLFloater* opened_floater, bool from_click)
{
- LLPreview* opened_preview = (LLPreview*)opened_floater;
+ // Floater could be something else than LLPreview, eg LLFloaterProfile.
+ LLPreview* opened_preview = dynamic_cast<LLPreview*>(opened_floater);
+
if (opened_preview && opened_preview->getAssetStatus() == LLPreview::PREVIEW_ASSET_UNLOADED)
{
opened_preview->loadAsset();
diff --git a/indra/newview/llpreview.h b/indra/newview/llpreview.h
index 759430c3a5..759430c3a5 100644..100755
--- a/indra/newview/llpreview.h
+++ b/indra/newview/llpreview.h
diff --git a/indra/newview/llpreviewanim.cpp b/indra/newview/llpreviewanim.cpp
index 35ac0537a3..35ac0537a3 100644..100755
--- a/indra/newview/llpreviewanim.cpp
+++ b/indra/newview/llpreviewanim.cpp
diff --git a/indra/newview/llpreviewanim.h b/indra/newview/llpreviewanim.h
index 8eaed6ca1f..8eaed6ca1f 100644..100755
--- a/indra/newview/llpreviewanim.h
+++ b/indra/newview/llpreviewanim.h
diff --git a/indra/newview/llpreviewgesture.cpp b/indra/newview/llpreviewgesture.cpp
index f47928b131..f47928b131 100644..100755
--- a/indra/newview/llpreviewgesture.cpp
+++ b/indra/newview/llpreviewgesture.cpp
diff --git a/indra/newview/llpreviewgesture.h b/indra/newview/llpreviewgesture.h
index fd4fcf9d8f..fd4fcf9d8f 100644..100755
--- a/indra/newview/llpreviewgesture.h
+++ b/indra/newview/llpreviewgesture.h
diff --git a/indra/newview/llpreviewnotecard.cpp b/indra/newview/llpreviewnotecard.cpp
index 3a9360fd23..3a9360fd23 100644..100755
--- a/indra/newview/llpreviewnotecard.cpp
+++ b/indra/newview/llpreviewnotecard.cpp
diff --git a/indra/newview/llpreviewnotecard.h b/indra/newview/llpreviewnotecard.h
index b53c0da6be..b53c0da6be 100644..100755
--- a/indra/newview/llpreviewnotecard.h
+++ b/indra/newview/llpreviewnotecard.h
diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp
index 88727bf59b..e533be7f24 100644..100755
--- a/indra/newview/llpreviewscript.cpp
+++ b/indra/newview/llpreviewscript.cpp
@@ -86,6 +86,7 @@
#include "lltrans.h"
#include "llviewercontrol.h"
#include "llappviewer.h"
+#include "llfloatergotoline.h"
const std::string HELLO_LSL =
"default\n"
@@ -193,12 +194,17 @@ private:
LLScriptEdCore* mEditorCore;
static LLFloaterScriptSearch* sInstance;
+
+protected:
+ LLLineEditor* mSearchBox;
+ void onSearchBoxCommit();
};
LLFloaterScriptSearch* LLFloaterScriptSearch::sInstance = NULL;
LLFloaterScriptSearch::LLFloaterScriptSearch(LLScriptEdCore* editor_core)
: LLFloater(LLSD()),
+ mSearchBox(NULL),
mEditorCore(editor_core)
{
buildFromFile("floater_script_search.xml");
@@ -221,6 +227,9 @@ LLFloaterScriptSearch::LLFloaterScriptSearch(LLScriptEdCore* editor_core)
BOOL LLFloaterScriptSearch::postBuild()
{
+ mSearchBox = getChild<LLLineEditor>("search_text");
+ mSearchBox->setCommitCallback(boost::bind(&LLFloaterScriptSearch::onSearchBoxCommit, this));
+ mSearchBox->setCommitOnFocusLost(FALSE);
childSetAction("search_btn", onBtnSearch,this);
childSetAction("replace_btn", onBtnReplace,this);
childSetAction("replace_all_btn", onBtnReplaceAll,this);
@@ -305,12 +314,25 @@ BOOL LLFloaterScriptSearch::handleKeyHere(KEY key, MASK mask)
{
if (mEditorCore)
{
- return mEditorCore->handleKeyHere(key, mask);
+ BOOL handled = mEditorCore->handleKeyHere(key, mask);
+ if (!handled)
+ {
+ LLFloater::handleKeyHere(key, mask);
+ }
}
return FALSE;
}
+void LLFloaterScriptSearch::onSearchBoxCommit()
+{
+ if (mEditorCore && mEditorCore->mEditor)
+ {
+ LLCheckBoxCtrl* caseChk = getChild<LLCheckBoxCtrl>("case_text");
+ mEditorCore->mEditor->selectNext(getChild<LLUICtrl>("search_text")->getValue().asString(), caseChk->get());
+ }
+}
+
/// ---------------------------------------------------------------------------
/// LLScriptEdCore
/// ---------------------------------------------------------------------------
@@ -499,6 +521,9 @@ void LLScriptEdCore::initMenu()
menuItem = getChild<LLMenuItemCallGL>("Search / Replace...");
menuItem->setClickCallback(boost::bind(&LLFloaterScriptSearch::show, this));
+ menuItem = getChild<LLMenuItemCallGL>("Go to line...");
+ menuItem->setClickCallback(boost::bind(&LLFloaterGotoLine::show, this));
+
menuItem = getChild<LLMenuItemCallGL>("Help...");
menuItem->setClickCallback(boost::bind(&LLScriptEdCore::onBtnHelp, this));
@@ -815,7 +840,7 @@ void LLScriptEdCore::onBtnDynamicHelp()
if (!live_help_floater)
{
live_help_floater = new LLFloater(LLSD());
- live_help_floater->buildFromFile("floater_lsl_guide.xml", NULL);
+ live_help_floater->buildFromFile("floater_lsl_guide.xml");
LLFloater* parent = dynamic_cast<LLFloater*>(getParent());
llassert(parent);
if (parent)
diff --git a/indra/newview/llpreviewscript.h b/indra/newview/llpreviewscript.h
index 7563cecd9d..9fb0a4fb63 100644..100755
--- a/indra/newview/llpreviewscript.h
+++ b/indra/newview/llpreviewscript.h
@@ -34,6 +34,7 @@
#include "llcombobox.h"
#include "lliconctrl.h"
#include "llframetimer.h"
+#include "llfloatergotoline.h"
class LLLiveLSLFile;
class LLMessageSystem;
@@ -49,6 +50,7 @@ class LLKeywordToken;
class LLVFS;
class LLViewerInventoryItem;
class LLScriptEdContainer;
+class LLFloaterGotoLine;
// Inner, implementation class. LLPreviewScript and LLLiveLSLEditor each own one of these.
class LLScriptEdCore : public LLPanel
@@ -58,6 +60,7 @@ class LLScriptEdCore : public LLPanel
friend class LLLiveLSLEditor;
friend class LLFloaterScriptSearch;
friend class LLScriptEdContainer;
+ friend class LLFloaterGotoLine;
protected:
// Supposed to be invoked only by the container.
diff --git a/indra/newview/llpreviewsound.cpp b/indra/newview/llpreviewsound.cpp
index 33d2d015ad..33d2d015ad 100644..100755
--- a/indra/newview/llpreviewsound.cpp
+++ b/indra/newview/llpreviewsound.cpp
diff --git a/indra/newview/llpreviewsound.h b/indra/newview/llpreviewsound.h
index 0453bfd936..0453bfd936 100644..100755
--- a/indra/newview/llpreviewsound.h
+++ b/indra/newview/llpreviewsound.h
diff --git a/indra/newview/llpreviewtexture.cpp b/indra/newview/llpreviewtexture.cpp
index 3ff5a05d81..1ed48a978f 100644..100755
--- a/indra/newview/llpreviewtexture.cpp
+++ b/indra/newview/llpreviewtexture.cpp
@@ -36,6 +36,7 @@
#include "llfilepicker.h"
#include "llfloaterreg.h"
#include "llimagetga.h"
+#include "llimagepng.h"
#include "llinventory.h"
#include "llnotificationsutil.h"
#include "llresmgr.h"
@@ -70,7 +71,7 @@ LLPreviewTexture::LLPreviewTexture(const LLSD& key)
mAspectRatio(0.f),
mPreviewToSave(FALSE),
mImage(NULL),
- mImageOldBoostLevel(LLViewerTexture::BOOST_NONE)
+ mImageOldBoostLevel(LLGLTexture::BOOST_NONE)
{
updateImageID();
if (key.has("save_as"))
@@ -261,7 +262,7 @@ void LLPreviewTexture::saveAs()
LLFilePicker& file_picker = LLFilePicker::instance();
const LLInventoryItem* item = getItem() ;
- if( !file_picker.getSaveFile( LLFilePicker::FFSAVE_TGA, item ? LLDir::getScrubbedFileName(item->getName()) : LLStringUtil::null) )
+ if( !file_picker.getSaveFile( LLFilePicker::FFSAVE_TGAPNG, item ? LLDir::getScrubbedFileName(item->getName()) : LLStringUtil::null) )
{
// User canceled or we failed to acquire save file.
return;
@@ -358,14 +359,27 @@ void LLPreviewTexture::onFileLoadedForSave(BOOL success,
if( self && final && success )
{
- LLPointer<LLImageTGA> image_tga = new LLImageTGA;
- if( !image_tga->encode( src ) )
+ const U32 ext_length = 3;
+ std::string extension = self->mSaveFileName.substr( self->mSaveFileName.length() - ext_length);
+
+ // We only support saving in PNG or TGA format
+ LLPointer<LLImageFormatted> image;
+ if(extension == "png")
+ {
+ image = new LLImagePNG;
+ }
+ else if(extension == "tga")
+ {
+ image = new LLImageTGA;
+ }
+
+ if( image && !image->encode( src, 0 ) )
{
LLSD args;
args["FILE"] = self->mSaveFileName;
LLNotificationsUtil::add("CannotEncodeFile", args);
}
- else if( !image_tga->save( self->mSaveFileName ) )
+ else if( image && !image->save( self->mSaveFileName ) )
{
LLSD args;
args["FILE"] = self->mSaveFileName;
@@ -468,9 +482,9 @@ void LLPreviewTexture::onAspectRatioCommit(LLUICtrl* ctrl, void* userdata)
void LLPreviewTexture::loadAsset()
{
- mImage = LLViewerTextureManager::getFetchedTexture(mImageID, MIPMAP_TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
+ mImage = LLViewerTextureManager::getFetchedTexture(mImageID, FTT_DEFAULT, MIPMAP_TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
mImageOldBoostLevel = mImage->getBoostLevel();
- mImage->setBoostLevel(LLViewerTexture::BOOST_PREVIEW);
+ mImage->setBoostLevel(LLGLTexture::BOOST_PREVIEW);
mImage->forceToSaveRawImage(0) ;
mAssetStatus = PREVIEW_ASSET_LOADING;
mUpdateDimensions = TRUE;
diff --git a/indra/newview/llpreviewtexture.h b/indra/newview/llpreviewtexture.h
index cd16bacde2..cd16bacde2 100644..100755
--- a/indra/newview/llpreviewtexture.h
+++ b/indra/newview/llpreviewtexture.h
diff --git a/indra/newview/llproductinforequest.cpp b/indra/newview/llproductinforequest.cpp
index 93bf8b2328..1390000fc5 100644..100755
--- a/indra/newview/llproductinforequest.cpp
+++ b/indra/newview/llproductinforequest.cpp
@@ -43,10 +43,10 @@ public:
}
//If we get back an error (not found, etc...), handle it here
- virtual void error(U32 status, const std::string& reason)
+ virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content)
{
- llwarns << "LLProductInfoRequest::error("
- << status << ": " << reason << ")" << llendl;
+ llwarns << "LLProductInfoRequest error [status:"
+ << status << ":] " << content << llendl;
}
};
diff --git a/indra/newview/llproductinforequest.h b/indra/newview/llproductinforequest.h
index fe8f7093b0..fe8f7093b0 100644..100755
--- a/indra/newview/llproductinforequest.h
+++ b/indra/newview/llproductinforequest.h
diff --git a/indra/newview/llprogressview.cpp b/indra/newview/llprogressview.cpp
index 5d7a5b1c59..989f0b0e60 100644..100755
--- a/indra/newview/llprogressview.cpp
+++ b/indra/newview/llprogressview.cpp
@@ -40,6 +40,7 @@
#include "llagent.h"
#include "llbutton.h"
+#include "llcallbacklist.h"
#include "llfocusmgr.h"
#include "llnotifications.h"
#include "llprogressbar.h"
@@ -72,6 +73,8 @@ LLProgressView::LLProgressView()
mStartupComplete(false)
{
mUpdateEvents.listen("self", boost::bind(&LLProgressView::handleUpdate, this, _1));
+ mFadeToWorldTimer.stop();
+ mFadeFromLoginTimer.stop();
}
BOOL LLProgressView::postBuild()
@@ -87,15 +90,13 @@ BOOL LLProgressView::postBuild()
mCancelBtn = getChild<LLButton>("cancel_btn");
mCancelBtn->setClickedCallback( LLProgressView::onCancelButtonClicked, NULL );
- mFadeToWorldTimer.stop();
- mFadeFromLoginTimer.stop();
getChild<LLTextBox>("title_text")->setText(LLStringExplicit(LLAppViewer::instance()->getSecondLifeTitle()));
getChild<LLTextBox>("message_text")->setClickedCallback(onClickMessage, this);
// hidden initially, until we need it
- LLPanel::setVisible(FALSE);
+ setVisible(FALSE);
LLNotifications::instance().getChannel("AlertModal")->connectChanged(boost::bind(&LLProgressView::onAlertModal, this, _1));
@@ -106,6 +107,9 @@ BOOL LLProgressView::postBuild()
LLProgressView::~LLProgressView()
{
+ // Just in case something went wrong, make sure we deregister our idle callback.
+ gIdleCallbacks.deleteFunction(onIdle, this);
+
gFocusMgr.releaseFocusIfNeeded( this );
sInstance = NULL;
@@ -154,6 +158,7 @@ void LLProgressView::revealIntroPanel()
}
mFadeFromLoginTimer.start();
+ gIdleCallbacks.addFunction(onIdle, this);
}
void LLProgressView::setStartupComplete()
@@ -236,13 +241,6 @@ void LLProgressView::draw()
}
LLPanel::draw();
-
- if (mFadeFromLoginTimer.getElapsedTimeF32() > FADE_TO_WORLD_TIME )
- {
- mFadeFromLoginTimer.stop();
- LLPanelLogin::closePanel();
- }
-
return;
}
@@ -267,7 +265,7 @@ void LLProgressView::draw()
gFocusMgr.releaseFocusIfNeeded( this );
// turn off panel that hosts intro so we see the world
- LLPanel::setVisible(FALSE);
+ setVisible(FALSE);
// stop observing events since we no longer care
mMediaCtrl->remObserver( this );
@@ -424,3 +422,21 @@ void LLProgressView::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent even
}
}
}
+
+
+// static
+void LLProgressView::onIdle(void* user_data)
+{
+ LLProgressView* self = (LLProgressView*) user_data;
+
+ // Close login panel on mFadeToWorldTimer expiration.
+ if (self->mFadeFromLoginTimer.getStarted() &&
+ self->mFadeFromLoginTimer.getElapsedTimeF32() > FADE_TO_WORLD_TIME)
+ {
+ self->mFadeFromLoginTimer.stop();
+ LLPanelLogin::closePanel();
+
+ // Nothing to do anymore.
+ gIdleCallbacks.deleteFunction(onIdle, user_data);
+ }
+}
diff --git a/indra/newview/llprogressview.h b/indra/newview/llprogressview.h
index fac00ad04d..813576b21d 100644..100755
--- a/indra/newview/llprogressview.h
+++ b/indra/newview/llprogressview.h
@@ -41,6 +41,8 @@ class LLProgressView :
public LLViewerMediaObserver
{
+ LOG_CLASS(LLProgressView);
+
public:
LLProgressView();
virtual ~LLProgressView();
@@ -74,10 +76,6 @@ public:
static void onClickMessage(void*);
bool onAlertModal(const LLSD& sd);
- // note - this is not just hiding the intro panel - it also hides the parent panel
- // and is used when the intro is finished and we want to show the world
- void removeIntroPanel();
-
protected:
LLProgressBar* mProgressBar;
LLMediaCtrl* mMediaCtrl;
@@ -96,6 +94,7 @@ protected:
LLEventStream mUpdateEvents;
bool handleUpdate(const LLSD& event_data);
+ static void onIdle(void* user_data);
};
#endif // LL_LLPROGRESSVIEW_H
diff --git a/indra/newview/llrecentpeople.cpp b/indra/newview/llrecentpeople.cpp
index 7689cd1a52..7689cd1a52 100644..100755
--- a/indra/newview/llrecentpeople.cpp
+++ b/indra/newview/llrecentpeople.cpp
diff --git a/indra/newview/llrecentpeople.h b/indra/newview/llrecentpeople.h
index d0d6376867..d0d6376867 100644..100755
--- a/indra/newview/llrecentpeople.h
+++ b/indra/newview/llrecentpeople.h
diff --git a/indra/newview/llregioninfomodel.cpp b/indra/newview/llregioninfomodel.cpp
index 698c4f9bb9..590e246482 100644..100755
--- a/indra/newview/llregioninfomodel.cpp
+++ b/indra/newview/llregioninfomodel.cpp
@@ -119,7 +119,7 @@ void LLRegionInfoModel::sendRegionTerrain(const LLUUID& invoice) const
bool LLRegionInfoModel::getUseFixedSun() const
{
- return mRegionFlags & REGION_FLAGS_SUN_FIXED;
+ return ((mRegionFlags & REGION_FLAGS_SUN_FIXED) != 0);
}
void LLRegionInfoModel::setUseFixedSun(bool fixed)
@@ -141,7 +141,6 @@ void LLRegionInfoModel::update(LLMessageSystem* msg)
msg->getStringFast(_PREHASH_RegionInfo, _PREHASH_SimName, mSimName);
msg->getU32Fast(_PREHASH_RegionInfo, _PREHASH_EstateID, mEstateID);
msg->getU32Fast(_PREHASH_RegionInfo, _PREHASH_ParentEstateID, mParentEstateID);
- msg->getU32Fast(_PREHASH_RegionInfo, _PREHASH_RegionFlags, mRegionFlags);
msg->getU8Fast(_PREHASH_RegionInfo, _PREHASH_SimAccess, mSimAccess);
msg->getU8Fast(_PREHASH_RegionInfo, _PREHASH_MaxAgents, mAgentLimit);
msg->getF32Fast(_PREHASH_RegionInfo, _PREHASH_ObjectBonusFactor, mObjectBonusFactor);
@@ -159,6 +158,17 @@ void LLRegionInfoModel::update(LLMessageSystem* msg)
msg->getF32(_PREHASH_RegionInfo, _PREHASH_SunHour, mSunHour);
LL_DEBUGS("Windlight Sync") << "Got region sun hour: " << mSunHour << LL_ENDL;
+ if (msg->has(_PREHASH_RegionInfo3))
+ {
+ msg->getU64Fast(_PREHASH_RegionInfo3, _PREHASH_RegionFlagsExtended, mRegionFlags);
+ }
+ else
+ {
+ U32 flags = 0;
+ msg->getU32Fast(_PREHASH_RegionInfo, _PREHASH_RegionFlags, flags);
+ mRegionFlags = flags;
+ }
+
// the only reasonable way to decide if we actually have any data is to
// check to see if any of these fields have nonzero sizes
if (msg->getSize(_PREHASH_RegionInfo2, _PREHASH_ProductSKU) > 0 ||
diff --git a/indra/newview/llregioninfomodel.h b/indra/newview/llregioninfomodel.h
index 89efd82767..d22a0de463 100644..100755
--- a/indra/newview/llregioninfomodel.h
+++ b/indra/newview/llregioninfomodel.h
@@ -52,7 +52,7 @@ public:
U8 mSimAccess;
U8 mAgentLimit;
- U32 mRegionFlags;
+ U64 mRegionFlags;
U32 mEstateID;
U32 mParentEstateID;
diff --git a/indra/newview/llregionposition.cpp b/indra/newview/llregionposition.cpp
index 32c271b2b8..32c271b2b8 100644..100755
--- a/indra/newview/llregionposition.cpp
+++ b/indra/newview/llregionposition.cpp
diff --git a/indra/newview/llregionposition.h b/indra/newview/llregionposition.h
index 8f72fa2e4e..8f72fa2e4e 100644..100755
--- a/indra/newview/llregionposition.h
+++ b/indra/newview/llregionposition.h
diff --git a/indra/newview/llremoteparcelrequest.cpp b/indra/newview/llremoteparcelrequest.cpp
index 3862dac340..500dec7ee5 100644..100755
--- a/indra/newview/llremoteparcelrequest.cpp
+++ b/indra/newview/llremoteparcelrequest.cpp
@@ -62,10 +62,10 @@ void LLRemoteParcelRequestResponder::result(const LLSD& content)
//If we get back an error (not found, etc...), handle it here
//virtual
-void LLRemoteParcelRequestResponder::error(U32 status, const std::string& reason)
+void LLRemoteParcelRequestResponder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)
{
- llinfos << "LLRemoteParcelRequest::error("
- << status << ": " << reason << ")" << llendl;
+ llwarns << "LLRemoteParcelRequest error [status:"
+ << status << "]: " << content << llendl;
// Panel inspecting the information may be closed and destroyed
// before this response is received.
diff --git a/indra/newview/llremoteparcelrequest.h b/indra/newview/llremoteparcelrequest.h
index 74cf1616df..b87056573b 100644..100755
--- a/indra/newview/llremoteparcelrequest.h
+++ b/indra/newview/llremoteparcelrequest.h
@@ -44,7 +44,7 @@ public:
/*virtual*/ void result(const LLSD& content);
//If we get back an error (not found, etc...), handle it here
- /*virtual*/ void error(U32 status, const std::string& reason);
+ /*virtual*/ void errorWithContent(U32 status, const std::string& reason, const LLSD& content);
protected:
LLHandle<LLRemoteParcelInfoObserver> mObserverHandle;
diff --git a/indra/newview/llresourcedata.h b/indra/newview/llresourcedata.h
index 28b97ed130..28b97ed130 100644..100755
--- a/indra/newview/llresourcedata.h
+++ b/indra/newview/llresourcedata.h
diff --git a/indra/newview/llrootview.h b/indra/newview/llrootview.h
index 5223a314f3..5223a314f3 100644..100755
--- a/indra/newview/llrootview.h
+++ b/indra/newview/llrootview.h
diff --git a/indra/newview/llsavedsettingsglue.cpp b/indra/newview/llsavedsettingsglue.cpp
index 37b576814d..37b576814d 100644..100755
--- a/indra/newview/llsavedsettingsglue.cpp
+++ b/indra/newview/llsavedsettingsglue.cpp
diff --git a/indra/newview/llsavedsettingsglue.h b/indra/newview/llsavedsettingsglue.h
index e8c6a7dbdb..e8c6a7dbdb 100644..100755
--- a/indra/newview/llsavedsettingsglue.h
+++ b/indra/newview/llsavedsettingsglue.h
diff --git a/indra/newview/llsaveoutfitcombobtn.cpp b/indra/newview/llsaveoutfitcombobtn.cpp
index cbad85cfd3..32295cd96f 100644..100755
--- a/indra/newview/llsaveoutfitcombobtn.cpp
+++ b/indra/newview/llsaveoutfitcombobtn.cpp
@@ -76,8 +76,8 @@ void LLSaveOutfitComboBtn::saveOutfit(bool as_new)
if (panel_outfits_inventory)
{
panel_outfits_inventory->onSave();
- }
-
+ }
+
//*TODO how to get to know when base outfit is updated or new outfit is created?
}
diff --git a/indra/newview/llsaveoutfitcombobtn.h b/indra/newview/llsaveoutfitcombobtn.h
index 3987a99f51..3987a99f51 100644..100755
--- a/indra/newview/llsaveoutfitcombobtn.h
+++ b/indra/newview/llsaveoutfitcombobtn.h
diff --git a/indra/newview/llsceneview.cpp b/indra/newview/llsceneview.cpp
index 09e799e4f7..cbd8bee9d5 100644..100755
--- a/indra/newview/llsceneview.cpp
+++ b/indra/newview/llsceneview.cpp
@@ -51,7 +51,7 @@ LLSceneView::LLSceneView(const LLRect& rect)
setCanClose(true);
}
-void LLSceneView::onClickCloseBtn()
+void LLSceneView::onClickCloseBtn(bool)
{
setVisible(false);
}
diff --git a/indra/newview/llsceneview.h b/indra/newview/llsceneview.h
index 2a3a14bbee..1fceecb9e1 100644..100755
--- a/indra/newview/llsceneview.h
+++ b/indra/newview/llsceneview.h
@@ -38,7 +38,7 @@ public:
virtual void draw();
protected:
- virtual void onClickCloseBtn();
+ virtual void onClickCloseBtn(bool app_qutting = false);
};
diff --git a/indra/newview/llscreenchannel.cpp b/indra/newview/llscreenchannel.cpp
index d340b304ca..168a941ec3 100644..100755
--- a/indra/newview/llscreenchannel.cpp
+++ b/indra/newview/llscreenchannel.cpp
@@ -39,7 +39,7 @@
#include "lldockablefloater.h"
#include "llsyswellwindow.h"
-#include "llimfloater.h"
+#include "llfloaterimsession.h"
#include "llscriptfloater.h"
#include "llrootview.h"
@@ -253,12 +253,26 @@ void LLScreenChannel::addToast(const LLToast::Params& p)
{
bool store_toast = false, show_toast = false;
- mDisplayToastsAlways ? show_toast = true : show_toast = mWasStartUpToastShown && (mShowToasts || p.force_show);
+ if (mDisplayToastsAlways)
+ {
+ show_toast = true;
+ }
+ else
+ {
+ show_toast = mWasStartUpToastShown && (mShowToasts || p.force_show);
+ }
store_toast = !show_toast && p.can_be_stored && mCanStoreToasts;
if(!show_toast && !store_toast)
{
- mRejectToastSignal(p.notif_id);
+ LLNotificationPtr notification = LLNotifications::instance().find(p.notif_id);
+
+ if (notification &&
+ (!notification->canLogToIM() || !notification->hasFormElements()))
+ {
+ // only cancel notification if it isn't being used in IM session
+ LLNotifications::instance().cancel(notification);
+ }
return;
}
@@ -371,7 +385,7 @@ void LLScreenChannel::storeToast(ToastElem& toast_elem)
const LLToast* toast = toast_elem.getToast();
if (toast)
{
- mStoredToastList.push_back(toast_elem);
+ mStoredToastList.push_back(toast_elem);
mOnStoreToast(toast->getPanel(), toast->getNotificationID());
}
}
@@ -410,14 +424,14 @@ void LLScreenChannel::loadStoredToastByNotificationIDToChannel(LLUUID id)
LLToast* toast = it->getToast();
if (toast)
{
- if(toast->getVisible())
- {
- // toast is already in channel
- return;
- }
+ if(toast->getVisible())
+ {
+ // toast is already in channel
+ return;
+ }
- toast->setIsHidden(false);
- toast->startTimer();
+ toast->setIsHidden(false);
+ toast->startTimer();
mToastList.push_back(*it);
}
@@ -425,34 +439,12 @@ void LLScreenChannel::loadStoredToastByNotificationIDToChannel(LLUUID id)
}
//--------------------------------------------------------------------------
-void LLScreenChannel::removeStoredToastByNotificationID(LLUUID id)
-{
- // *TODO: may be remove this function
- std::vector<ToastElem>::iterator it = find(mStoredToastList.begin(), mStoredToastList.end(), id);
-
- if( it == mStoredToastList.end() )
- return;
-
- const LLToast* toast = it->getToast();
- if (toast)
- {
- mRejectToastSignal(toast->getNotificationID());
- }
-
- // Call find() once more, because the mStoredToastList could have been changed
- // in mRejectToastSignal callback and the iterator could have become invalid.
- it = find(mStoredToastList.begin(), mStoredToastList.end(), id);
- if (it != mStoredToastList.end())
- {
- mStoredToastList.erase(it);
- }
-}
-
-//--------------------------------------------------------------------------
void LLScreenChannel::killToastByNotificationID(LLUUID id)
{
// searching among toasts on a screen
std::vector<ToastElem>::iterator it = find(mToastList.begin(), mToastList.end(), id);
+ LLNotificationPtr notification = LLNotifications::instance().find(id);
+ if (!notification) return;
if( it != mToastList.end())
{
@@ -465,42 +457,67 @@ void LLScreenChannel::killToastByNotificationID(LLUUID id)
// the toast will be destroyed.
if(toast && toast->isNotificationValid())
{
- mRejectToastSignal(toast->getNotificationID());
+ if (!notification->canLogToIM() || !notification->hasFormElements())
+ {
+ // only cancel notification if it isn't being used in IM session
+ LLNotifications::instance().cancel(notification);
+ }
}
else
{
-
- deleteToast(toast);
- mToastList.erase(it);
- redrawToasts();
+ removeToastByNotificationID(id);
}
- return;
}
-
- // searching among stored toasts
- it = find(mStoredToastList.begin(), mStoredToastList.end(), id);
-
- if (it != mStoredToastList.end())
+ else
{
- LLToast* toast = it->getToast();
- if (toast)
+ // searching among stored toasts
+ it = find(mStoredToastList.begin(), mStoredToastList.end(), id);
+
+ if( it != mStoredToastList.end() )
{
- // send signal to a listener to let him perform some action on toast rejecting
- mRejectToastSignal(toast->getNotificationID());
- deleteToast(toast);
+ LLToast* toast = it->getToast();
+ if (toast)
+ {
+ if (!notification->canLogToIM() || !notification->hasFormElements())
+ {
+ // only cancel notification if it isn't being used in IM session
+ LLNotifications::instance().cancel(notification);
+ }
+ deleteToast(toast);
+ }
+ }
+
+ // Call find() once more, because the mStoredToastList could have been changed
+ // via notification cancellation and the iterator could have become invalid.
+ it = find(mStoredToastList.begin(), mStoredToastList.end(), id);
+ if (it != mStoredToastList.end())
+ {
+ mStoredToastList.erase(it);
}
}
+}
+
+void LLScreenChannel::removeToastByNotificationID(LLUUID id)
+{
+ std::vector<ToastElem>::iterator it = find(mToastList.begin(), mToastList.end(), id);
+ while( it != mToastList.end())
+ {
+ deleteToast(it->getToast());
+ mToastList.erase(it);
+ redrawToasts();
+ // find next toast with matching id
+ it = find(mToastList.begin(), mToastList.end(), id);
+ }
- // Call find() once more, because the mStoredToastList could have been changed
- // in mRejectToastSignal callback and the iterator could have become invalid.
it = find(mStoredToastList.begin(), mStoredToastList.end(), id);
if (it != mStoredToastList.end())
{
+ deleteToast(it->getToast());
mStoredToastList.erase(it);
}
-
}
+
void LLScreenChannel::killMatchedToasts(const Matcher& matcher)
{
std::list<const LLToast*> to_delete = findToasts(matcher);
@@ -521,11 +538,11 @@ void LLScreenChannel::modifyToastByNotificationID(LLUUID id, LLPanel* panel)
LLToast* toast = it->getToast();
if (toast)
{
- LLPanel* old_panel = toast->getPanel();
- toast->removeChild(old_panel);
- delete old_panel;
- toast->insertPanel(panel);
- toast->startTimer();
+ LLPanel* old_panel = toast->getPanel();
+ toast->removeChild(old_panel);
+ delete old_panel;
+ toast->insertPanel(panel);
+ toast->startTimer();
}
redrawToasts();
}
@@ -571,9 +588,13 @@ void LLScreenChannel::showToastsBottom()
LLDockableFloater* floater = dynamic_cast<LLDockableFloater*>(LLDockableFloater::getInstanceHandle().get());
- for(it = mToastList.rbegin(); it != mToastList.rend(); ++it)
+ // Use a local variable instead of mToastList.
+ // mToastList can be modified during recursive calls and then all iteratos will be invalidated.
+ std::vector<ToastElem> vToastList( mToastList );
+
+ for(it = vToastList.rbegin(); it != vToastList.rend(); ++it)
{
- if(it != mToastList.rbegin())
+ if(it != vToastList.rbegin())
{
LLToast* toast = (it-1)->getToast();
if (!toast)
@@ -601,7 +622,7 @@ void LLScreenChannel::showToastsBottom()
if(floater && floater->overlapsScreenChannel())
{
- if(it == mToastList.rbegin())
+ if(it == vToastList.rbegin())
{
// move first toast above docked floater
S32 shift = floater->getRect().getHeight();
@@ -624,7 +645,7 @@ void LLScreenChannel::showToastsBottom()
if(!stop_showing_toasts)
{
- if( it != mToastList.rend()-1)
+ if( it != vToastList.rend()-1)
{
S32 toast_top = toast->getRect().mTop + gSavedSettings.getS32("ToastGap");
stop_showing_toasts = toast_top > getRect().mTop;
@@ -632,7 +653,8 @@ void LLScreenChannel::showToastsBottom()
}
// at least one toast should be visible
- if(it == mToastList.rbegin())
+
+ if(it == vToastList.rbegin())
{
stop_showing_toasts = false;
}
@@ -655,10 +677,11 @@ void LLScreenChannel::showToastsBottom()
}
// Dismiss toasts we don't have space for (STORM-391).
- if(it != mToastList.rend())
+ if(it != vToastList.rend())
{
mHiddenToastsNum = 0;
- for(; it != mToastList.rend(); it++)
+
+ for(; it != vToastList.rend(); it++)
{
LLToast* toast = it->getToast();
if (toast)
@@ -679,7 +702,7 @@ void LLScreenChannel::showToastsCentre()
return;
}
- LLRect toast_rect;
+ LLRect toast_rect;
S32 bottom = (getRect().mTop - getRect().mBottom)/2 + toast->getRect().getHeight()/2;
std::vector<ToastElem>::reverse_iterator it;
@@ -707,16 +730,19 @@ void LLScreenChannel::showToastsTop()
LLRect toast_rect;
S32 top = channel_rect.mTop;
- S32 toast_margin = 0;
std::vector<ToastElem>::reverse_iterator it;
updateRect();
LLDockableFloater* floater = dynamic_cast<LLDockableFloater*>(LLDockableFloater::getInstanceHandle().get());
- for(it = mToastList.rbegin(); it != mToastList.rend(); ++it)
+ // Use a local variable instead of mToastList.
+ // mToastList can be modified during recursive calls and then all iteratos will be invalidated.
+ std::vector<ToastElem> vToastList( mToastList );
+
+ for(it = vToastList.rbegin(); it != vToastList.rend(); ++it)
{
- if(it != mToastList.rbegin())
+ if(it != vToastList.rbegin())
{
LLToast* toast = (it-1)->getToast();
if (!toast)
@@ -726,7 +752,7 @@ void LLScreenChannel::showToastsTop()
}
top = toast->getRect().mBottom - toast->getTopPad();
- toast_margin = gSavedSettings.getS32("ToastGap");
+ gSavedSettings.getS32("ToastGap");
}
LLToast* toast = it->getToast();
@@ -744,7 +770,7 @@ void LLScreenChannel::showToastsTop()
if(floater && floater->overlapsScreenChannel())
{
- if(it == mToastList.rbegin())
+ if(it == vToastList.rbegin())
{
// move first toast above docked floater
S32 shift = -floater->getRect().getHeight();
@@ -767,7 +793,7 @@ void LLScreenChannel::showToastsTop()
if(!stop_showing_toasts)
{
- if( it != mToastList.rend()-1)
+ if( it != vToastList.rend()-1)
{
S32 toast_bottom = toast->getRect().mBottom - gSavedSettings.getS32("ToastGap");
stop_showing_toasts = toast_bottom < channel_rect.mBottom;
@@ -775,7 +801,7 @@ void LLScreenChannel::showToastsTop()
}
// at least one toast should be visible
- if(it == mToastList.rbegin())
+ if(it == vToastList.rbegin())
{
stop_showing_toasts = false;
}
@@ -799,10 +825,12 @@ void LLScreenChannel::showToastsTop()
// Dismiss toasts we don't have space for (STORM-391).
std::vector<LLToast*> toasts_to_hide;
- if(it != mToastList.rend())
+
+ if(it != vToastList.rend())
{
mHiddenToastsNum = 0;
- for(; it != mToastList.rend(); it++)
+
+ for(; it != vToastList.rend(); it++)
{
LLToast* toast = it->getToast();
if (toast)
diff --git a/indra/newview/llscreenchannel.h b/indra/newview/llscreenchannel.h
index 56a9cf8b4b..e5f4807ab7 100644..100755
--- a/indra/newview/llscreenchannel.h
+++ b/indra/newview/llscreenchannel.h
@@ -84,6 +84,7 @@ public:
// kill or modify a toast by its ID
virtual void killToastByNotificationID(LLUUID id) {};
virtual void modifyToastNotificationByID(LLUUID id, LLSD data) {};
+ virtual void removeToastByNotificationID(LLUUID id){};
// hide all toasts from screen, but not remove them from a channel
virtual void hideToastsFromScreen() {};
@@ -175,6 +176,7 @@ public:
void addToast(const LLToast::Params& p);
// kill or modify a toast by its ID
void killToastByNotificationID(LLUUID id);
+ void removeToastByNotificationID(LLUUID id);
void killMatchedToasts(const Matcher& matcher);
void modifyToastByNotificationID(LLUUID id, LLPanel* panel);
// hide all toasts from screen, but not remove them from a channel
@@ -195,8 +197,6 @@ public:
void loadStoredToastsToChannel();
// finds a toast among stored by its Notification ID and throws it on a screen to a channel
void loadStoredToastByNotificationIDToChannel(LLUUID id);
- // removes a toast from stored finding it by its Notification ID
- void removeStoredToastByNotificationID(LLUUID id);
// removes from channel all toasts that belongs to the certain IM session
void removeToastsBySessionID(LLUUID id);
// remove all storable toasts from screen and store them
@@ -227,16 +227,12 @@ public:
// Channel's signals
// signal on storing of faded toasts event
- typedef boost::function<void (LLPanel* info_panel, const LLUUID id)> store_tost_callback_t;
- typedef boost::signals2::signal<void (LLPanel* info_panel, const LLUUID id)> store_tost_signal_t;
- store_tost_signal_t mOnStoreToast;
- boost::signals2::connection setOnStoreToastCallback(store_tost_callback_t cb) { return mOnStoreToast.connect(cb); }
- // signal on rejecting of a toast event
- typedef boost::function<void (LLUUID id)> reject_tost_callback_t;
- typedef boost::signals2::signal<void (LLUUID id)> reject_tost_signal_t;
- reject_tost_signal_t mRejectToastSignal; boost::signals2::connection setOnRejectToastCallback(reject_tost_callback_t cb) { return mRejectToastSignal.connect(cb); }
+ typedef boost::signals2::signal<void (LLPanel* info_panel, const LLUUID id)> store_toast_signal_t;
+ boost::signals2::connection addOnStoreToastCallback(store_toast_signal_t::slot_type cb) { return mOnStoreToast.connect(cb); }
private:
+ store_toast_signal_t mOnStoreToast;
+
class ToastElem
{
public:
diff --git a/indra/newview/llscriptfloater.cpp b/indra/newview/llscriptfloater.cpp
index 6f98be1cb8..0e0da6bdc7 100644..100755
--- a/indra/newview/llscriptfloater.cpp
+++ b/indra/newview/llscriptfloater.cpp
@@ -41,7 +41,7 @@
#include "lltoastscripttextbox.h"
#include "lltrans.h"
#include "llviewerwindow.h"
-#include "llimfloater.h"
+#include "llfloaterimsession.h"
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
@@ -95,7 +95,12 @@ bool LLScriptFloater::toggle(const LLUUID& notification_id)
show(notification_id);
}
- LLChicletBar::getInstance()->getChicletPanel()->setChicletToggleState(notification_id, true);
+ LLChicletPanel * chiclet_panelp = LLChicletBar::getInstance()->getChicletPanel();
+ if (NULL != chiclet_panelp)
+ {
+ chiclet_panelp->setChicletToggleState(notification_id, true);
+ }
+
return true;
}
@@ -206,10 +211,14 @@ void LLScriptFloater::setVisible(BOOL visible)
if(!visible)
{
- LLIMChiclet* chiclet = LLChicletBar::getInstance()->getChicletPanel()->findChiclet<LLIMChiclet>(getNotificationId());
- if(chiclet)
+ LLChicletPanel * chiclet_panelp = LLChicletBar::getInstance()->getChicletPanel();
+ if (NULL != chiclet_panelp)
{
- chiclet->setToggleState(false);
+ LLIMChiclet * chicletp = chiclet_panelp->findChiclet<LLIMChiclet>(getNotificationId());
+ if(NULL != chicletp)
+ {
+ chicletp->setToggleState(false);
+ }
}
}
}
@@ -218,15 +227,19 @@ void LLScriptFloater::onMouseDown()
{
if(getNotificationId().notNull())
{
- // Remove new message icon
- LLIMChiclet* chiclet = LLChicletBar::getInstance()->getChicletPanel()->findChiclet<LLIMChiclet>(getNotificationId());
- if (chiclet == NULL)
+ LLChicletPanel * chiclet_panelp = LLChicletBar::getInstance()->getChicletPanel();
+ if (NULL != chiclet_panelp)
{
- llerror("Dock chiclet for LLScriptFloater doesn't exist", 0);
- }
- else
- {
- chiclet->setShowNewMessagesIcon(false);
+ LLIMChiclet * chicletp = chiclet_panelp->findChiclet<LLIMChiclet>(getNotificationId());
+ // Remove new message icon
+ if (NULL == chicletp)
+ {
+ llerror("Dock chiclet for LLScriptFloater doesn't exist", 0);
+ }
+ else
+ {
+ chicletp->setShowNewMessagesIcon(false);
+ }
}
}
}
@@ -262,7 +275,11 @@ void LLScriptFloater::onFocusLost()
{
if(getNotificationId().notNull())
{
- LLChicletBar::getInstance()->getChicletPanel()->setChicletToggleState(getNotificationId(), false);
+ LLChicletPanel * chiclet_panelp = LLChicletBar::getInstance()->getChicletPanel();
+ if (NULL != chiclet_panelp)
+ {
+ chiclet_panelp->setChicletToggleState(getNotificationId(), false);
+ }
}
}
@@ -271,7 +288,11 @@ void LLScriptFloater::onFocusReceived()
// first focus will be received before setObjectId() call - don't toggle chiclet
if(getNotificationId().notNull())
{
- LLChicletBar::getInstance()->getChicletPanel()->setChicletToggleState(getNotificationId(), true);
+ LLChicletPanel * chiclet_panelp = LLChicletBar::getInstance()->getChicletPanel();
+ if (NULL != chiclet_panelp)
+ {
+ chiclet_panelp->setChicletToggleState(getNotificationId(), true);
+ }
}
}
@@ -279,28 +300,30 @@ void LLScriptFloater::dockToChiclet(bool dock)
{
if (getDockControl() == NULL)
{
- LLChiclet* chiclet = LLChicletBar::getInstance()->getChicletPanel()->findChiclet<LLChiclet>(getNotificationId());
- if (chiclet == NULL)
- {
- llwarns << "Dock chiclet for LLScriptFloater doesn't exist" << llendl;
- return;
- }
- else
+ LLChicletPanel * chiclet_panelp = LLChicletBar::getInstance()->getChicletPanel();
+ if (NULL != chiclet_panelp)
{
- LLChicletBar::getInstance()->getChicletPanel()->scrollToChiclet(chiclet);
- }
+ LLChiclet * chicletp = chiclet_panelp->findChiclet<LLChiclet>(getNotificationId());
+ if (NULL == chicletp)
+ {
+ llwarns << "Dock chiclet for LLScriptFloater doesn't exist" << llendl;
+ return;
+ }
- // Stop saving position while we dock floater
- bool save = getSavePosition();
- setSavePosition(false);
+ chiclet_panelp->scrollToChiclet(chicletp);
- setDockControl(new LLDockControl(chiclet, this, getDockTongue(),
- LLDockControl::BOTTOM));
+ // Stop saving position while we dock floater
+ bool save = getSavePosition();
+ setSavePosition(false);
- setDocked(dock);
+ setDockControl(new LLDockControl(chicletp, this, getDockTongue(),
+ LLDockControl::BOTTOM));
- // Restore saving
- setSavePosition(save);
+ setDocked(dock);
+
+ // Restore saving
+ setSavePosition(save);
+ }
}
}
@@ -347,11 +370,15 @@ void LLScriptFloaterManager::onAddNotification(const LLUUID& notification_id)
script_notification_map_t::const_iterator it = findUsingObjectId(object_id);
if(it != mNotifications.end())
{
- LLIMChiclet* chiclet = LLChicletBar::getInstance()->getChicletPanel()->findChiclet<LLIMChiclet>(it->first);
- if(chiclet)
+ LLChicletPanel * chiclet_panelp = LLChicletBar::getInstance()->getChicletPanel();
+ if (NULL != chiclet_panelp)
{
- // Pass the new_message icon state further.
- set_new_message = chiclet->getShowNewMessagesIcon();
+ LLIMChiclet * chicletp = chiclet_panelp->findChiclet<LLIMChiclet>(it->first);
+ if(NULL != chicletp)
+ {
+ // Pass the new_message icon state further.
+ set_new_message = chicletp->getShowNewMessagesIcon();
+ }
}
LLScriptFloater* floater = LLFloaterReg::findTypedInstance<LLScriptFloater>("script_floater", it->first);
@@ -367,14 +394,18 @@ void LLScriptFloaterManager::onAddNotification(const LLUUID& notification_id)
mNotifications.insert(std::make_pair(notification_id, object_id));
- // Create inventory offer chiclet for offer type notifications
- if( OBJ_GIVE_INVENTORY == obj_type )
+ LLChicletPanel * chiclet_panelp = LLChicletBar::getInstance()->getChicletPanel();
+ if (NULL != chiclet_panelp)
{
- LLChicletBar::instance().getChicletPanel()->createChiclet<LLInvOfferChiclet>(notification_id);
- }
- else
- {
- LLChicletBar::getInstance()->getChicletPanel()->createChiclet<LLScriptChiclet>(notification_id);
+ // Create inventory offer chiclet for offer type notifications
+ if( OBJ_GIVE_INVENTORY == obj_type )
+ {
+ chiclet_panelp->createChiclet<LLInvOfferChiclet>(notification_id);
+ }
+ else
+ {
+ chiclet_panelp->createChiclet<LLScriptChiclet>(notification_id);
+ }
}
LLIMWellWindow::getInstance()->addObjectRow(notification_id, set_new_message);
@@ -410,7 +441,11 @@ void LLScriptFloaterManager::onRemoveNotification(const LLUUID& notification_id)
// remove related chiclet
if (LLChicletBar::instanceExists())
{
- LLChicletBar::getInstance()->getChicletPanel()->removeChiclet(notification_id);
+ LLChicletPanel * chiclet_panelp = LLChicletBar::getInstance()->getChicletPanel();
+ if (NULL != chiclet_panelp)
+ {
+ chiclet_panelp->removeChiclet(notification_id);
+ }
}
LLIMWellWindow* im_well_window = LLIMWellWindow::findInstance();
diff --git a/indra/newview/llscriptfloater.h b/indra/newview/llscriptfloater.h
index 70451194b3..70451194b3 100644..100755
--- a/indra/newview/llscriptfloater.h
+++ b/indra/newview/llscriptfloater.h
diff --git a/indra/newview/llscrollingpanelparam.cpp b/indra/newview/llscrollingpanelparam.cpp
index 05b82ba967..a7e24b86b1 100644..100755
--- a/indra/newview/llscrollingpanelparam.cpp
+++ b/indra/newview/llscrollingpanelparam.cpp
@@ -267,7 +267,7 @@ void LLScrollingPanelParam::onHintHeldDown( LLVisualParamHint* hint )
&& new_percent < slider->getMaxValue())
{
mWearable->setVisualParamWeight( hint->getVisualParam()->getID(), new_weight, FALSE);
- mWearable->writeToAvatar();
+ mWearable->writeToAvatar(gAgentAvatarp);
gAgentAvatarp->updateVisualParams();
slider->setValue( weightToPercent( new_weight ) );
@@ -300,7 +300,7 @@ void LLScrollingPanelParam::onHintMinMouseUp( void* userdata )
&& new_percent < slider->getMaxValue())
{
self->mWearable->setVisualParamWeight(hint->getVisualParam()->getID(), new_weight, FALSE);
- self->mWearable->writeToAvatar();
+ self->mWearable->writeToAvatar(gAgentAvatarp);
slider->setValue( self->weightToPercent( new_weight ) );
}
}
@@ -334,7 +334,7 @@ void LLScrollingPanelParam::onHintMaxMouseUp( void* userdata )
&& new_percent < slider->getMaxValue())
{
self->mWearable->setVisualParamWeight(hint->getVisualParam()->getID(), new_weight, FALSE);
- self->mWearable->writeToAvatar();
+ self->mWearable->writeToAvatar(gAgentAvatarp);
slider->setValue( self->weightToPercent( new_weight ) );
}
}
diff --git a/indra/newview/llscrollingpanelparam.h b/indra/newview/llscrollingpanelparam.h
index c7a47d5c7a..c7a47d5c7a 100644..100755
--- a/indra/newview/llscrollingpanelparam.h
+++ b/indra/newview/llscrollingpanelparam.h
diff --git a/indra/newview/llscrollingpanelparambase.cpp b/indra/newview/llscrollingpanelparambase.cpp
index 62e3039d2f..8e083ddb6c 100644..100755
--- a/indra/newview/llscrollingpanelparambase.cpp
+++ b/indra/newview/llscrollingpanelparambase.cpp
@@ -94,7 +94,7 @@ void LLScrollingPanelParamBase::onSliderMoved(LLUICtrl* ctrl, void* userdata)
if (current_weight != new_weight )
{
self->mWearable->setVisualParamWeight( param->getID(), new_weight, FALSE );
- self->mWearable->writeToAvatar();
+ self->mWearable->writeToAvatar(gAgentAvatarp);
gAgentAvatarp->updateVisualParams();
}
}
diff --git a/indra/newview/llscrollingpanelparambase.h b/indra/newview/llscrollingpanelparambase.h
index 9538826251..9538826251 100644..100755
--- a/indra/newview/llscrollingpanelparambase.h
+++ b/indra/newview/llscrollingpanelparambase.h
diff --git a/indra/newview/llsearchcombobox.cpp b/indra/newview/llsearchcombobox.cpp
index 2824c70582..2824c70582 100644..100755
--- a/indra/newview/llsearchcombobox.cpp
+++ b/indra/newview/llsearchcombobox.cpp
diff --git a/indra/newview/llsearchcombobox.h b/indra/newview/llsearchcombobox.h
index 68f3979532..68f3979532 100644..100755
--- a/indra/newview/llsearchcombobox.h
+++ b/indra/newview/llsearchcombobox.h
diff --git a/indra/newview/llsearchhistory.cpp b/indra/newview/llsearchhistory.cpp
index 7b4bf63740..7b4bf63740 100644..100755
--- a/indra/newview/llsearchhistory.cpp
+++ b/indra/newview/llsearchhistory.cpp
diff --git a/indra/newview/llsearchhistory.h b/indra/newview/llsearchhistory.h
index 3309a8fcac..3309a8fcac 100644..100755
--- a/indra/newview/llsearchhistory.h
+++ b/indra/newview/llsearchhistory.h
diff --git a/indra/newview/llsecapi.cpp b/indra/newview/llsecapi.cpp
index 43bb7b1596..43bb7b1596 100644..100755
--- a/indra/newview/llsecapi.cpp
+++ b/indra/newview/llsecapi.cpp
diff --git a/indra/newview/llsecapi.h b/indra/newview/llsecapi.h
index db57848320..db57848320 100644..100755
--- a/indra/newview/llsecapi.h
+++ b/indra/newview/llsecapi.h
diff --git a/indra/newview/llsechandler_basic.cpp b/indra/newview/llsechandler_basic.cpp
index 30400a4c6a..c4d5450e2b 100644..100755
--- a/indra/newview/llsechandler_basic.cpp
+++ b/indra/newview/llsechandler_basic.cpp
@@ -207,6 +207,7 @@ LLSD _basic_constraints_ext(X509* cert)
}
}
+ BASIC_CONSTRAINTS_free( bs );
}
return result;
}
@@ -268,6 +269,8 @@ LLSD _ext_key_usage_ext(X509* cert)
ASN1_OBJECT_free(usage);
}
}
+
+ EXTENDED_KEY_USAGE_free( eku );
}
return result;
}
@@ -280,6 +283,8 @@ LLSD _subject_key_identifier_ext(X509 *cert)
if(skeyid)
{
result = cert_string_from_octet_string(skeyid);
+
+ ASN1_OCTET_STRING_free( skeyid );
}
return result;
}
@@ -300,6 +305,9 @@ LLSD _authority_key_identifier_ext(X509* cert)
{
result[CERT_AUTHORITY_KEY_IDENTIFIER_SERIAL] = cert_string_from_asn1_integer(akeyid->serial);
}
+
+
+ AUTHORITY_KEYID_free( akeyid );
}
// we ignore the issuer name in the authority key identifier, we check the issue name via
@@ -1049,6 +1057,8 @@ void LLBasicCertificateStore::validate(int validation_policy,
throw LLInvalidCertificate((*current_cert));
}
std::string sha1_hash((const char *)cert_x509->sha1_hash, SHA_DIGEST_LENGTH);
+ X509_free( cert_x509 );
+ cert_x509 = NULL;
t_cert_cache::iterator cache_entry = mTrustedCertCache.find(sha1_hash);
if(cache_entry != mTrustedCertCache.end())
{
@@ -1239,7 +1249,6 @@ void LLSecAPIBasicHandler::_readProtectedData()
llifstream::binary);
if (!protected_data_stream.fail()) {
- int offset;
U8 salt[STORE_SALT_SIZE];
U8 buffer[BUFFER_READ_SIZE];
U8 decrypted_buffer[BUFFER_READ_SIZE];
@@ -1250,7 +1259,6 @@ void LLSecAPIBasicHandler::_readProtectedData()
// read in the salt and key
protected_data_stream.read((char *)salt, STORE_SALT_SIZE);
- offset = 0;
if (protected_data_stream.gcount() < STORE_SALT_SIZE)
{
throw LLProtectedDataException("Config file too short.");
diff --git a/indra/newview/llsechandler_basic.h b/indra/newview/llsechandler_basic.h
index 1ce5a87c75..1ce5a87c75 100644..100755
--- a/indra/newview/llsechandler_basic.h
+++ b/indra/newview/llsechandler_basic.h
diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index 6111255a66..7b397d46f3 100644..100755
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -29,6 +29,7 @@
// file include
#define LLSELECTMGR_CPP
#include "llselectmgr.h"
+#include "llmaterialmgr.h"
// library includes
#include "llcachename.h"
@@ -90,7 +91,7 @@
#include "llvovolume.h"
#include "pipeline.h"
#include "llviewershadermgr.h"
-
+#include "llpanelface.h"
#include "llglheaders.h"
LLViewerObject* getSelectedParentObject(LLViewerObject *object) ;
@@ -103,7 +104,6 @@ const F32 SILHOUETTE_UPDATE_THRESHOLD_SQUARED = 0.02f;
const S32 MAX_ACTION_QUEUE_SIZE = 20;
const S32 MAX_SILS_PER_FRAME = 50;
const S32 MAX_OBJECTS_PER_PACKET = 254;
-const S32 TE_SELECT_MASK_ALL = 0xFFFFFFFF;
//
// Globals
@@ -188,6 +188,7 @@ LLSelectMgr::LLSelectMgr()
mDebugSelectMgr(LLCachedControl<bool>(gSavedSettings, "DebugSelectMgr", FALSE))
{
mTEMode = FALSE;
+ mTextureChannel = LLRender::DIFFUSE_MAP;
mLastCameraPos.clearVec();
sHighlightThickness = gSavedSettings.getF32("SelectionHighlightThickness");
@@ -211,7 +212,6 @@ LLSelectMgr::LLSelectMgr()
mGridMode = GRID_MODE_WORLD;
gSavedSettings.setS32("GridMode", (S32)GRID_MODE_WORLD);
- mGridValid = FALSE;
mSelectedObjects = new LLObjectSelection();
mHoverObjects = new LLObjectSelection();
@@ -237,6 +237,8 @@ void LLSelectMgr::clearSelections()
mHighlightedObjects->deleteAllNodes();
mRectSelectedObjects.clear();
mGridObjects.deleteAllNodes();
+
+ LLPipeline::setRenderHighlightTextureChannel(LLRender::DIFFUSE_MAP);
}
void LLSelectMgr::update()
@@ -276,7 +278,7 @@ void LLSelectMgr::overrideObjectUpdates()
virtual bool apply(LLSelectNode* selectNode)
{
LLViewerObject* object = selectNode->getObject();
- if (object && object->permMove())
+ if (object && object->permMove() && !object->isPermanentEnforced())
{
if (!selectNode->mLastPositionLocal.isExactlyZero())
{
@@ -390,7 +392,7 @@ LLObjectSelectionHandle LLSelectMgr::selectObjectAndFamily(LLViewerObject* obj,
// don't include an avatar.
LLViewerObject* root = obj;
- while(!root->isAvatar() && root->getParent() && !root->isJointChild())
+ while(!root->isAvatar() && root->getParent())
{
LLViewerObject* parent = (LLViewerObject*)root->getParent();
if (parent->isAvatar())
@@ -593,6 +595,12 @@ bool LLSelectMgr::linkObjects()
return true;
}
+ if (!LLSelectMgr::getInstance()->selectGetRootsNonPermanentEnforced())
+ {
+ LLNotificationsUtil::add("CannotLinkPermanent");
+ return true;
+ }
+
LLUUID owner_id;
std::string owner_name;
if (!LLSelectMgr::getInstance()->selectGetOwner(owner_id, owner_name))
@@ -638,7 +646,9 @@ bool LLSelectMgr::enableLinkObjects()
{
virtual bool apply(LLViewerObject* object)
{
- return object->permModify();
+ LLViewerObject *root_object = (object == NULL) ? NULL : object->getRootEdit();
+ return object->permModify() && !object->isPermanentEnforced() &&
+ ((root_object == NULL) || !root_object->isPermanentEnforced());
}
} func;
const bool firstonly = true;
@@ -651,10 +661,12 @@ bool LLSelectMgr::enableLinkObjects()
bool LLSelectMgr::enableUnlinkObjects()
{
LLViewerObject* first_editable_object = LLSelectMgr::getInstance()->getSelection()->getFirstEditableObject();
+ LLViewerObject *root_object = (first_editable_object == NULL) ? NULL : first_editable_object->getRootEdit();
bool new_value = LLSelectMgr::getInstance()->selectGetAllRootsValid() &&
first_editable_object &&
- !first_editable_object->isAttachment();
+ !first_editable_object->isAttachment() && !first_editable_object->isPermanentEnforced() &&
+ ((root_object == NULL) || !root_object->isPermanentEnforced());
return new_value;
}
@@ -674,7 +686,7 @@ void LLSelectMgr::deselectObjectAndFamily(LLViewerObject* object, BOOL send_to_s
// don't include an avatar.
LLViewerObject* root = object;
- while(!root->isAvatar() && root->getParent() && !root->isJointChild())
+ while(!root->isAvatar() && root->getParent())
{
LLViewerObject* parent = (LLViewerObject*)root->getParent();
if (parent->isAvatar())
@@ -806,6 +818,7 @@ void LLSelectMgr::addAsFamily(std::vector<LLViewerObject*>& objects, BOOL add_to
if (objectp->getNumTEs() > 0)
{
nodep->selectAllTEs(TRUE);
+ objectp->setAllTESelected(true);
}
else
{
@@ -834,6 +847,10 @@ void LLSelectMgr::addAsIndividual(LLViewerObject *objectp, S32 face, BOOL undoab
// check to see if object is already in list
LLSelectNode *nodep = mSelectedObjects->findNode(objectp);
+ // Reset (in anticipation of being set to an appropriate value by panel refresh, if they're up)
+ //
+ setTextureChannel(LLRender::DIFFUSE_MAP);
+
// if not in list, add it
if (!nodep)
{
@@ -863,10 +880,12 @@ void LLSelectMgr::addAsIndividual(LLViewerObject *objectp, S32 face, BOOL undoab
else if (face == SELECT_ALL_TES)
{
nodep->selectAllTEs(TRUE);
+ objectp->setAllTESelected(true);
}
else if (0 <= face && face < SELECT_MAX_TES)
{
nodep->selectTE(face, TRUE);
+ objectp->setTESelected(face, true);
}
else
{
@@ -955,7 +974,7 @@ void LLSelectMgr::highlightObjectOnly(LLViewerObject* objectp)
}
if ((gSavedSettings.getBOOL("SelectOwnedOnly") && !objectp->permYouOwner())
- || (gSavedSettings.getBOOL("SelectMovableOnly") && !objectp->permMove()))
+ || (gSavedSettings.getBOOL("SelectMovableOnly") && (!objectp->permMove() || objectp->isPermanentEnforced())))
{
// only select my own objects
return;
@@ -1086,6 +1105,7 @@ LLObjectSelectionHandle LLSelectMgr::selectHighlightedObjects()
// flag this object as selected
objectp->setSelected(TRUE);
+ objectp->setAllTESelected(true);
mSelectedObjects->mSelectType = getSelectTypeForObject(objectp);
@@ -1160,7 +1180,6 @@ void LLSelectMgr::setGridMode(EGridMode mode)
mGridMode = mode;
gSavedSettings.setS32("GridMode", mode);
updateSelectionCenter();
- mGridValid = FALSE;
}
void LLSelectMgr::getGrid(LLVector3& origin, LLQuaternion &rotation, LLVector3 &scale)
@@ -1172,7 +1191,6 @@ void LLSelectMgr::getGrid(LLVector3& origin, LLQuaternion &rotation, LLVector3 &
if (mGridMode == GRID_MODE_LOCAL && mSelectedObjects->getObjectCount())
{
//LLViewerObject* root = getSelectedParentObject(mSelectedObjects->getFirstObject());
- LLBBox bbox = mSavedSelectionBBox;
mGridOrigin = mSavedSelectionBBox.getCenterAgent();
mGridScale = mSavedSelectionBBox.getExtentLocal() * 0.5f;
@@ -1190,7 +1208,6 @@ void LLSelectMgr::getGrid(LLVector3& origin, LLQuaternion &rotation, LLVector3 &
else if (mGridMode == GRID_MODE_REF_OBJECT && first_grid_object && first_grid_object->mDrawable.notNull())
{
mGridRotation = first_grid_object->getRenderRotation();
- LLVector3 first_grid_obj_pos = first_grid_object->getRenderPosition();
LLVector4a min_extents(F32_MAX);
LLVector4a max_extents(-F32_MAX);
@@ -1261,7 +1278,6 @@ void LLSelectMgr::getGrid(LLVector3& origin, LLQuaternion &rotation, LLVector3 &
origin = mGridOrigin;
rotation = mGridRotation;
scale = mGridScale;
- mGridValid = TRUE;
}
//-----------------------------------------------------------------------------
@@ -1313,6 +1329,7 @@ void LLSelectMgr::remove(LLViewerObject *objectp, S32 te, BOOL undoable)
if (nodep->isTESelected(te))
{
nodep->selectTE(te, FALSE);
+ objectp->setTESelected(te, false);
}
else
{
@@ -1387,7 +1404,7 @@ void LLSelectMgr::promoteSelectionToRoot()
}
LLViewerObject* parentp = object;
- while(parentp->getParent() && !(parentp->isRootEdit() || parentp->isJointChild()))
+ while(parentp->getParent() && !(parentp->isRootEdit()))
{
parentp = (LLViewerObject*)parentp->getParent();
}
@@ -1508,6 +1525,49 @@ struct LLSelectMgrSendFunctor : public LLSelectedObjectFunctor
}
};
+void LLObjectSelection::applyNoCopyTextureToTEs(LLViewerInventoryItem* item)
+{
+ if (!item)
+ {
+ return;
+ }
+ LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(item->getAssetUUID());
+
+ for (iterator iter = begin(); iter != end(); ++iter)
+ {
+ LLSelectNode* node = *iter;
+ LLViewerObject* object = (*iter)->getObject();
+ if (!object)
+ {
+ continue;
+ }
+
+ S32 num_tes = llmin((S32)object->getNumTEs(), (S32)object->getNumFaces());
+ bool texture_copied = false;
+ for (S32 te = 0; te < num_tes; ++te)
+ {
+ if (node->isTESelected(te))
+ {
+ //(no-copy) textures must be moved to the object's inventory only once
+ // without making any copies
+ if (!texture_copied)
+ {
+ LLToolDragAndDrop::handleDropTextureProtections(object, item, LLToolDragAndDrop::SOURCE_AGENT, LLUUID::null);
+ texture_copied = true;
+ }
+
+ // apply texture for the selected faces
+ LLViewerStats::getInstance()->incStat(LLViewerStats::ST_EDIT_TEXTURE_COUNT );
+ object->setTEImage(te, image);
+ dialog_refresh_all();
+
+ // send the update to the simulator
+ object->sendTEUpdate();
+ }
+ }
+ }
+}
+
//-----------------------------------------------------------------------------
// selectionSetImage()
//-----------------------------------------------------------------------------
@@ -1555,12 +1615,22 @@ void LLSelectMgr::selectionSetImage(const LLUUID& imageid)
// Texture picker defaults aren't inventory items
// * Don't need to worry about permissions for them
// * Can just apply the texture and be done with it.
- objectp->setTEImage(te, LLViewerTextureManager::getFetchedTexture(mImageID, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE));
+ objectp->setTEImage(te, LLViewerTextureManager::getFetchedTexture(mImageID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE));
}
return true;
}
- } setfunc(item, imageid);
- getSelection()->applyToTEs(&setfunc);
+ };
+
+ if (item && !item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID()))
+ {
+ getSelection()->applyNoCopyTextureToTEs(item);
+ }
+ else
+ {
+ f setfunc(item, imageid);
+ getSelection()->applyToTEs(&setfunc);
+ }
+
struct g : public LLSelectedObjectFunctor
{
@@ -1711,7 +1781,7 @@ BOOL LLSelectMgr::selectionRevertTextures()
}
else
{
- object->setTEImage(te, LLViewerTextureManager::getFetchedTexture(id, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE));
+ object->setTEImage(te, LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE));
}
}
}
@@ -1946,6 +2016,76 @@ void LLSelectMgr::selectionSetGlow(F32 glow)
mSelectedObjects->applyToObjects( &func2 );
}
+void LLSelectMgr::selectionSetMaterialParams(LLSelectedTEMaterialFunctor* material_func)
+{
+ struct f1 : public LLSelectedTEFunctor
+ {
+ LLMaterialPtr mMaterial;
+ f1(LLSelectedTEMaterialFunctor* material_func) : _material_func(material_func) {}
+
+ bool apply(LLViewerObject* object, S32 face)
+ {
+ if (object && object->permModify() && _material_func)
+ {
+ LLTextureEntry* tep = object->getTE(face);
+ if (tep)
+ {
+ LLMaterialPtr current_material = tep->getMaterialParams();
+ _material_func->apply(object, face, tep, current_material);
+ }
+ }
+ return true;
+ }
+
+ LLSelectedTEMaterialFunctor* _material_func;
+ } func1(material_func);
+ mSelectedObjects->applyToTEs( &func1 );
+
+ struct f2 : public LLSelectedObjectFunctor
+ {
+ virtual bool apply(LLViewerObject* object)
+ {
+ if (object->permModify())
+ {
+ object->sendTEUpdate();
+ }
+ return true;
+ }
+ } func2;
+ mSelectedObjects->applyToObjects( &func2 );
+}
+
+void LLSelectMgr::selectionRemoveMaterial()
+{
+ struct f1 : public LLSelectedTEFunctor
+ {
+ bool apply(LLViewerObject* object, S32 face)
+ {
+ if (object->permModify())
+ {
+ LL_DEBUGS("Materials") << "Removing material from object " << object->getID() << " face " << face << LL_ENDL;
+ LLMaterialMgr::getInstance()->remove(object->getID(),face);
+ object->setTEMaterialParams(face, NULL);
+ }
+ return true;
+ }
+ } func1;
+ mSelectedObjects->applyToTEs( &func1 );
+
+ struct f2 : public LLSelectedObjectFunctor
+ {
+ virtual bool apply(LLViewerObject* object)
+ {
+ if (object->permModify())
+ {
+ object->sendTEUpdate();
+ }
+ return true;
+ }
+ } func2;
+ mSelectedObjects->applyToObjects( &func2 );
+}
+
//-----------------------------------------------------------------------------
// findObjectPermissions()
@@ -2286,50 +2426,6 @@ void LLSelectMgr::packObjectIDAsParam(LLSelectNode* node, void *)
}
//-----------------------------------------------------------------------------
-// Rotation options
-//-----------------------------------------------------------------------------
-void LLSelectMgr::selectionResetRotation()
-{
- struct f : public LLSelectedObjectFunctor
- {
- virtual bool apply(LLViewerObject* object)
- {
- LLQuaternion identity(0.f, 0.f, 0.f, 1.f);
- object->setRotation(identity);
- if (object->mDrawable.notNull())
- {
- gPipeline.markMoved(object->mDrawable, TRUE);
- }
- object->sendRotationUpdate();
- return true;
- }
- } func;
- getSelection()->applyToRootObjects(&func);
-}
-
-void LLSelectMgr::selectionRotateAroundZ(F32 degrees)
-{
- LLQuaternion rot( degrees * DEG_TO_RAD, LLVector3(0,0,1) );
- struct f : public LLSelectedObjectFunctor
- {
- LLQuaternion mRot;
- f(const LLQuaternion& rot) : mRot(rot) {}
- virtual bool apply(LLViewerObject* object)
- {
- object->setRotation( object->getRotationEdit() * mRot );
- if (object->mDrawable.notNull())
- {
- gPipeline.markMoved(object->mDrawable, TRUE);
- }
- object->sendRotationUpdate();
- return true;
- }
- } func(rot);
- getSelection()->applyToRootObjects(&func);
-}
-
-
-//-----------------------------------------------------------------------------
// selectionTexScaleAutofit()
//-----------------------------------------------------------------------------
void LLSelectMgr::selectionTexScaleAutofit(F32 repeats_per_meter)
@@ -2411,19 +2507,66 @@ void LLSelectMgr::adjustTexturesByScale(BOOL send_to_sim, BOOL stretch)
continue;
}
- LLVector3 scale_ratio = selectNode->mTextureScaleRatios[te_num];
LLVector3 object_scale = object->getScale();
+ LLVector3 diffuse_scale_ratio = selectNode->mTextureScaleRatios[te_num];
+
+ // We like these to track together. NORSPEC-96
+ //
+ LLVector3 normal_scale_ratio = diffuse_scale_ratio;
+ LLVector3 specular_scale_ratio = diffuse_scale_ratio;
// Apply new scale to face
if (planar)
{
- object->setTEScale(te_num, 1.f/object_scale.mV[s_axis]*scale_ratio.mV[s_axis],
- 1.f/object_scale.mV[t_axis]*scale_ratio.mV[t_axis]);
+ F32 diffuse_scale_s = diffuse_scale_ratio.mV[s_axis]/object_scale.mV[s_axis];
+ F32 diffuse_scale_t = diffuse_scale_ratio.mV[t_axis]/object_scale.mV[t_axis];
+
+ F32 normal_scale_s = normal_scale_ratio.mV[s_axis]/object_scale.mV[s_axis];
+ F32 normal_scale_t = normal_scale_ratio.mV[t_axis]/object_scale.mV[t_axis];
+
+ F32 specular_scale_s = specular_scale_ratio.mV[s_axis]/object_scale.mV[s_axis];
+ F32 specular_scale_t = specular_scale_ratio.mV[t_axis]/object_scale.mV[t_axis];
+
+ object->setTEScale(te_num, diffuse_scale_s, diffuse_scale_t);
+
+ LLTextureEntry* tep = object->getTE(te_num);
+
+ if (tep && !tep->getMaterialParams().isNull())
+ {
+ LLMaterialPtr orig = tep->getMaterialParams();
+ LLMaterialPtr p = gFloaterTools->getPanelFace()->createDefaultMaterial(orig);
+ p->setNormalRepeat(normal_scale_s, normal_scale_t);
+ p->setSpecularRepeat(specular_scale_s, specular_scale_t);
+
+ LLMaterialMgr::getInstance()->put(object->getID(), te_num, *p);
+ }
}
else
{
- object->setTEScale(te_num, scale_ratio.mV[s_axis]*object_scale.mV[s_axis],
- scale_ratio.mV[t_axis]*object_scale.mV[t_axis]);
+
+ F32 diffuse_scale_s = diffuse_scale_ratio.mV[s_axis]*object_scale.mV[s_axis];
+ F32 diffuse_scale_t = diffuse_scale_ratio.mV[t_axis]*object_scale.mV[t_axis];
+
+ F32 normal_scale_s = normal_scale_ratio.mV[s_axis]*object_scale.mV[s_axis];
+ F32 normal_scale_t = normal_scale_ratio.mV[t_axis]*object_scale.mV[t_axis];
+
+ F32 specular_scale_s = specular_scale_ratio.mV[s_axis]*object_scale.mV[s_axis];
+ F32 specular_scale_t = specular_scale_ratio.mV[t_axis]*object_scale.mV[t_axis];
+
+ object->setTEScale(te_num, diffuse_scale_s,diffuse_scale_t);
+
+ LLTextureEntry* tep = object->getTE(te_num);
+
+ if (tep && !tep->getMaterialParams().isNull())
+ {
+ LLMaterialPtr orig = tep->getMaterialParams();
+ LLMaterialPtr p = gFloaterTools->getPanelFace()->createDefaultMaterial(orig);
+
+ p->setNormalRepeat(normal_scale_s, normal_scale_t);
+ p->setSpecularRepeat(specular_scale_s, specular_scale_t);
+
+ LLMaterialMgr::getInstance()->put(object->getID(), te_num, *p);
+ }
}
send = send_to_sim;
}
@@ -2543,10 +2686,33 @@ BOOL LLSelectMgr::selectGetRootsModify()
//-----------------------------------------------------------------------------
-// selectGetRootsTransfer() - return TRUE if current agent can transfer all
-// selected root objects.
+// selectGetNonPermanentEnforced() - return TRUE if all objects are not
+// permanent enforced
//-----------------------------------------------------------------------------
-BOOL LLSelectMgr::selectGetRootsTransfer()
+BOOL LLSelectMgr::selectGetNonPermanentEnforced()
+{
+ for (LLObjectSelection::iterator iter = getSelection()->begin();
+ iter != getSelection()->end(); iter++ )
+ {
+ LLSelectNode* node = *iter;
+ LLViewerObject* object = node->getObject();
+ if( !object || !node->mValid )
+ {
+ return FALSE;
+ }
+ if( object->isPermanentEnforced())
+ {
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// selectGetRootsNonPermanentEnforced() - return TRUE if all root objects are
+// not permanent enforced
+//-----------------------------------------------------------------------------
+BOOL LLSelectMgr::selectGetRootsNonPermanentEnforced()
{
for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
iter != getSelection()->root_end(); iter++ )
@@ -2557,19 +2723,42 @@ BOOL LLSelectMgr::selectGetRootsTransfer()
{
return FALSE;
}
- if(!object->permTransfer())
+ if( object->isPermanentEnforced())
{
return FALSE;
}
}
+
return TRUE;
}
//-----------------------------------------------------------------------------
-// selectGetRootsCopy() - return TRUE if current agent can copy all
-// selected root objects.
+// selectGetPermanent() - return TRUE if all objects are permanent
//-----------------------------------------------------------------------------
-BOOL LLSelectMgr::selectGetRootsCopy()
+BOOL LLSelectMgr::selectGetPermanent()
+{
+ for (LLObjectSelection::iterator iter = getSelection()->begin();
+ iter != getSelection()->end(); iter++ )
+ {
+ LLSelectNode* node = *iter;
+ LLViewerObject* object = node->getObject();
+ if( !object || !node->mValid )
+ {
+ return FALSE;
+ }
+ if( !object->flagObjectPermanent())
+ {
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// selectGetRootsPermanent() - return TRUE if all root objects are
+// permanent
+//-----------------------------------------------------------------------------
+BOOL LLSelectMgr::selectGetRootsPermanent()
{
for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
iter != getSelection()->root_end(); iter++ )
@@ -2580,256 +2769,537 @@ BOOL LLSelectMgr::selectGetRootsCopy()
{
return FALSE;
}
- if(!object->permCopy())
+ if( !object->flagObjectPermanent())
{
return FALSE;
}
}
+
return TRUE;
}
//-----------------------------------------------------------------------------
-// selectGetCreator()
-// Creator information only applies to root objects.
+// selectGetCharacter() - return TRUE if all objects are character
//-----------------------------------------------------------------------------
-BOOL LLSelectMgr::selectGetCreator(LLUUID& result_id, std::string& name)
+BOOL LLSelectMgr::selectGetCharacter()
{
- BOOL identical = TRUE;
- BOOL first = TRUE;
- LLUUID first_id;
- for (LLObjectSelection::root_object_iterator iter = getSelection()->root_object_begin();
- iter != getSelection()->root_object_end(); iter++ )
+ for (LLObjectSelection::iterator iter = getSelection()->begin();
+ iter != getSelection()->end(); iter++ )
{
- LLSelectNode* node = *iter;
- if (!node->mValid)
+ LLSelectNode* node = *iter;
+ LLViewerObject* object = node->getObject();
+ if( !object || !node->mValid )
+ {
+ return FALSE;
+ }
+ if( !object->flagCharacter())
{
return FALSE;
}
+ }
+ return TRUE;
+}
- if (first)
+//-----------------------------------------------------------------------------
+// selectGetRootsCharacter() - return TRUE if all root objects are
+// character
+//-----------------------------------------------------------------------------
+BOOL LLSelectMgr::selectGetRootsCharacter()
+{
+ for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
+ iter != getSelection()->root_end(); iter++ )
+ {
+ LLSelectNode* node = *iter;
+ LLViewerObject* object = node->getObject();
+ if( !node->mValid )
{
- first_id = node->mPermissions->getCreator();
- first = FALSE;
+ return FALSE;
}
- else
+ if( !object->flagCharacter())
{
- if ( !(first_id == node->mPermissions->getCreator() ) )
- {
- identical = FALSE;
- break;
- }
+ return FALSE;
}
}
- if (first_id.isNull())
- {
- name = LLTrans::getString("AvatarNameNobody");
- return FALSE;
- }
-
- result_id = first_id;
-
- if (identical)
+
+ return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// selectGetNonPathfinding() - return TRUE if all objects are not pathfinding
+//-----------------------------------------------------------------------------
+BOOL LLSelectMgr::selectGetNonPathfinding()
+{
+ for (LLObjectSelection::iterator iter = getSelection()->begin();
+ iter != getSelection()->end(); iter++ )
{
- name = LLSLURL("agent", first_id, "inspect").getSLURLString();
+ LLSelectNode* node = *iter;
+ LLViewerObject* object = node->getObject();
+ if( !object || !node->mValid )
+ {
+ return FALSE;
+ }
+ if( object->flagObjectPermanent() || object->flagCharacter())
+ {
+ return FALSE;
+ }
}
- else
+ return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// selectGetRootsNonPathfinding() - return TRUE if all root objects are not
+// pathfinding
+//-----------------------------------------------------------------------------
+BOOL LLSelectMgr::selectGetRootsNonPathfinding()
+{
+ for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
+ iter != getSelection()->root_end(); iter++ )
{
- name = LLTrans::getString("AvatarNameMultiple");
+ LLSelectNode* node = *iter;
+ LLViewerObject* object = node->getObject();
+ if( !node->mValid )
+ {
+ return FALSE;
+ }
+ if( object->flagObjectPermanent() || object->flagCharacter())
+ {
+ return FALSE;
+ }
}
- return identical;
+ return TRUE;
}
-
//-----------------------------------------------------------------------------
-// selectGetOwner()
-// Owner information only applies to roots.
+// selectGetNonPermanent() - return TRUE if all objects are not permanent
//-----------------------------------------------------------------------------
-BOOL LLSelectMgr::selectGetOwner(LLUUID& result_id, std::string& name)
+BOOL LLSelectMgr::selectGetNonPermanent()
{
- BOOL identical = TRUE;
- BOOL first = TRUE;
- BOOL first_group_owned = FALSE;
- LLUUID first_id;
- for (LLObjectSelection::root_object_iterator iter = getSelection()->root_object_begin();
- iter != getSelection()->root_object_end(); iter++ )
+ for (LLObjectSelection::iterator iter = getSelection()->begin();
+ iter != getSelection()->end(); iter++ )
{
- LLSelectNode* node = *iter;
- if (!node->mValid)
+ LLSelectNode* node = *iter;
+ LLViewerObject* object = node->getObject();
+ if( !object || !node->mValid )
{
return FALSE;
}
-
- if (first)
+ if( object->flagObjectPermanent())
{
- node->mPermissions->getOwnership(first_id, first_group_owned);
- first = FALSE;
+ return FALSE;
}
- else
+ }
+ return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// selectGetRootsNonPermanent() - return TRUE if all root objects are not
+// permanent
+//-----------------------------------------------------------------------------
+BOOL LLSelectMgr::selectGetRootsNonPermanent()
+{
+ for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
+ iter != getSelection()->root_end(); iter++ )
+ {
+ LLSelectNode* node = *iter;
+ LLViewerObject* object = node->getObject();
+ if( !node->mValid )
{
- LLUUID owner_id;
- BOOL is_group_owned = FALSE;
- if (!(node->mPermissions->getOwnership(owner_id, is_group_owned))
- || owner_id != first_id || is_group_owned != first_group_owned)
- {
- identical = FALSE;
- break;
- }
+ return FALSE;
+ }
+ if( object->flagObjectPermanent())
+ {
+ return FALSE;
}
}
- if (first_id.isNull())
+
+ return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// selectGetNonCharacter() - return TRUE if all objects are not character
+//-----------------------------------------------------------------------------
+BOOL LLSelectMgr::selectGetNonCharacter()
+{
+ for (LLObjectSelection::iterator iter = getSelection()->begin();
+ iter != getSelection()->end(); iter++ )
{
- return FALSE;
+ LLSelectNode* node = *iter;
+ LLViewerObject* object = node->getObject();
+ if( !object || !node->mValid )
+ {
+ return FALSE;
+ }
+ if( object->flagCharacter())
+ {
+ return FALSE;
+ }
}
+ return TRUE;
+}
- result_id = first_id;
-
- if (identical)
+//-----------------------------------------------------------------------------
+// selectGetRootsNonCharacter() - return TRUE if all root objects are not
+// character
+//-----------------------------------------------------------------------------
+BOOL LLSelectMgr::selectGetRootsNonCharacter()
+{
+ for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
+ iter != getSelection()->root_end(); iter++ )
{
- BOOL public_owner = (first_id.isNull() && !first_group_owned);
- if (first_group_owned)
+ LLSelectNode* node = *iter;
+ LLViewerObject* object = node->getObject();
+ if( !node->mValid )
{
- name = LLSLURL("group", first_id, "inspect").getSLURLString();
+ return FALSE;
}
- else if(!public_owner)
+ if( object->flagCharacter())
{
- name = LLSLURL("agent", first_id, "inspect").getSLURLString();
+ return FALSE;
}
- else
+ }
+
+ return TRUE;
+}
+
+
+//-----------------------------------------------------------------------------
+// selectGetEditableLinksets() - return TRUE if all objects are editable
+// pathfinding linksets
+//-----------------------------------------------------------------------------
+BOOL LLSelectMgr::selectGetEditableLinksets()
+{
+ for (LLObjectSelection::iterator iter = getSelection()->begin();
+ iter != getSelection()->end(); iter++ )
+ {
+ LLSelectNode* node = *iter;
+ LLViewerObject* object = node->getObject();
+ if( !object || !node->mValid )
+ {
+ return FALSE;
+ }
+ if (object->flagUsePhysics() ||
+ object->flagTemporaryOnRez() ||
+ object->flagCharacter() ||
+ object->flagVolumeDetect() ||
+ object->flagAnimSource() ||
+ (object->getRegion() != gAgent.getRegion()) ||
+ (!gAgent.isGodlike() &&
+ !gAgent.canManageEstate() &&
+ !object->permYouOwner() &&
+ !object->permMove()))
{
- name = LLTrans::getString("AvatarNameNobody");
+ return FALSE;
}
}
- else
+ return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// selectGetViewableCharacters() - return TRUE if all objects are characters
+// viewable within the pathfinding characters floater
+//-----------------------------------------------------------------------------
+BOOL LLSelectMgr::selectGetViewableCharacters()
+{
+ for (LLObjectSelection::iterator iter = getSelection()->begin();
+ iter != getSelection()->end(); iter++ )
{
- name = LLTrans::getString("AvatarNameMultiple");
+ LLSelectNode* node = *iter;
+ LLViewerObject* object = node->getObject();
+ if( !object || !node->mValid )
+ {
+ return FALSE;
+ }
+ if( !object->flagCharacter() ||
+ (object->getRegion() != gAgent.getRegion()))
+ {
+ return FALSE;
+ }
}
-
- return identical;
+ return TRUE;
}
+//-----------------------------------------------------------------------------
+// selectGetRootsTransfer() - return TRUE if current agent can transfer all
+// selected root objects.
+//-----------------------------------------------------------------------------
+BOOL LLSelectMgr::selectGetRootsTransfer()
+{
+ for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
+ iter != getSelection()->root_end(); iter++ )
+ {
+ LLSelectNode* node = *iter;
+ LLViewerObject* object = node->getObject();
+ if( !node->mValid )
+ {
+ return FALSE;
+ }
+ if(!object->permTransfer())
+ {
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
//-----------------------------------------------------------------------------
-// selectGetLastOwner()
-// Owner information only applies to roots.
+// selectGetRootsCopy() - return TRUE if current agent can copy all
+// selected root objects.
//-----------------------------------------------------------------------------
-BOOL LLSelectMgr::selectGetLastOwner(LLUUID& result_id, std::string& name)
+BOOL LLSelectMgr::selectGetRootsCopy()
{
- BOOL identical = TRUE;
- BOOL first = TRUE;
- LLUUID first_id;
- for (LLObjectSelection::root_object_iterator iter = getSelection()->root_object_begin();
- iter != getSelection()->root_object_end(); iter++ )
+ for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
+ iter != getSelection()->root_end(); iter++ )
{
- LLSelectNode* node = *iter;
- if (!node->mValid)
+ LLSelectNode* node = *iter;
+ LLViewerObject* object = node->getObject();
+ if( !node->mValid )
+ {
+ return FALSE;
+ }
+ if(!object->permCopy())
{
return FALSE;
}
+ }
+ return TRUE;
+}
- if (first)
+struct LLSelectGetFirstTest
+{
+ LLSelectGetFirstTest() : mIdentical(true), mFirst(true) { }
+ virtual ~LLSelectGetFirstTest() { }
+
+ // returns false to break out of the iteration.
+ bool checkMatchingNode(LLSelectNode* node)
+ {
+ if (!node || !node->mValid)
{
- first_id = node->mPermissions->getLastOwner();
- first = FALSE;
+ return false;
+ }
+
+ if (mFirst)
+ {
+ mFirstValue = getValueFromNode(node);
+ mFirst = false;
}
else
{
- if ( !(first_id == node->mPermissions->getLastOwner() ) )
+ if ( mFirstValue != getValueFromNode(node) )
+ {
+ mIdentical = false;
+ // stop testing once we know not all selected are identical.
+ return false;
+ }
+ }
+ // continue testing.
+ return true;
+ }
+
+ bool mIdentical;
+ LLUUID mFirstValue;
+
+protected:
+ virtual const LLUUID& getValueFromNode(LLSelectNode* node) = 0;
+
+private:
+ bool mFirst;
+};
+
+void LLSelectMgr::getFirst(LLSelectGetFirstTest* test)
+{
+ if (gSavedSettings.getBOOL("EditLinkedParts"))
+ {
+ for (LLObjectSelection::valid_iterator iter = getSelection()->valid_begin();
+ iter != getSelection()->valid_end(); ++iter )
+ {
+ if (!test->checkMatchingNode(*iter))
{
- identical = FALSE;
break;
}
}
}
- if (first_id.isNull())
+ else
+ {
+ for (LLObjectSelection::root_object_iterator iter = getSelection()->root_object_begin();
+ iter != getSelection()->root_object_end(); ++iter )
+ {
+ if (!test->checkMatchingNode(*iter))
+ {
+ break;
+ }
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// selectGetCreator()
+// Creator information only applies to roots unless editing linked parts.
+//-----------------------------------------------------------------------------
+struct LLSelectGetFirstCreator : public LLSelectGetFirstTest
+{
+protected:
+ virtual const LLUUID& getValueFromNode(LLSelectNode* node)
+ {
+ return node->mPermissions->getCreator();
+ }
+};
+
+BOOL LLSelectMgr::selectGetCreator(LLUUID& result_id, std::string& name)
+{
+ LLSelectGetFirstCreator test;
+ getFirst(&test);
+
+ if (test.mFirstValue.isNull())
+ {
+ name = LLTrans::getString("AvatarNameNobody");
+ return FALSE;
+ }
+
+ result_id = test.mFirstValue;
+
+ if (test.mIdentical)
+ {
+ name = LLSLURL("agent", test.mFirstValue, "inspect").getSLURLString();
+ }
+ else
+ {
+ name = LLTrans::getString("AvatarNameMultiple");
+ }
+
+ return test.mIdentical;
+}
+
+//-----------------------------------------------------------------------------
+// selectGetOwner()
+// Owner information only applies to roots unless editing linked parts.
+//-----------------------------------------------------------------------------
+struct LLSelectGetFirstOwner : public LLSelectGetFirstTest
+{
+protected:
+ virtual const LLUUID& getValueFromNode(LLSelectNode* node)
+ {
+ // Don't use 'getOwnership' since we return a reference, not a copy.
+ // Will return LLUUID::null if unowned (which is not allowed and should never happen.)
+ return node->mPermissions->isGroupOwned() ? node->mPermissions->getGroup() : node->mPermissions->getOwner();
+ }
+};
+
+BOOL LLSelectMgr::selectGetOwner(LLUUID& result_id, std::string& name)
+{
+ LLSelectGetFirstOwner test;
+ getFirst(&test);
+
+ if (test.mFirstValue.isNull())
{
return FALSE;
}
- result_id = first_id;
+ result_id = test.mFirstValue;
- if (identical)
+ if (test.mIdentical)
{
- BOOL public_owner = (first_id.isNull());
- if(!public_owner)
+ bool group_owned = selectIsGroupOwned();
+ if (group_owned)
{
- name = LLSLURL("agent", first_id, "inspect").getSLURLString();
+ name = LLSLURL("group", test.mFirstValue, "inspect").getSLURLString();
}
else
{
- name.assign("Public or Group");
+ name = LLSLURL("agent", test.mFirstValue, "inspect").getSLURLString();
}
}
else
{
- name.assign( "" );
+ name = LLTrans::getString("AvatarNameMultiple");
}
- return identical;
+ return test.mIdentical;
}
+//-----------------------------------------------------------------------------
+// selectGetLastOwner()
+// Owner information only applies to roots unless editing linked parts.
+//-----------------------------------------------------------------------------
+struct LLSelectGetFirstLastOwner : public LLSelectGetFirstTest
+{
+protected:
+ virtual const LLUUID& getValueFromNode(LLSelectNode* node)
+ {
+ return node->mPermissions->getLastOwner();
+ }
+};
+
+BOOL LLSelectMgr::selectGetLastOwner(LLUUID& result_id, std::string& name)
+{
+ LLSelectGetFirstLastOwner test;
+ getFirst(&test);
+
+ if (test.mFirstValue.isNull())
+ {
+ return FALSE;
+ }
+
+ result_id = test.mFirstValue;
+
+ if (test.mIdentical)
+ {
+ name = LLSLURL("agent", test.mFirstValue, "inspect").getSLURLString();
+ }
+ else
+ {
+ name.assign( "" );
+ }
+
+ return test.mIdentical;
+}
//-----------------------------------------------------------------------------
// selectGetGroup()
-// Group information only applies to roots.
+// Group information only applies to roots unless editing linked parts.
//-----------------------------------------------------------------------------
-BOOL LLSelectMgr::selectGetGroup(LLUUID& result_id)
+struct LLSelectGetFirstGroup : public LLSelectGetFirstTest
{
- BOOL identical = TRUE;
- BOOL first = TRUE;
- LLUUID first_id;
- for (LLObjectSelection::root_object_iterator iter = getSelection()->root_object_begin();
- iter != getSelection()->root_object_end(); iter++ )
+protected:
+ virtual const LLUUID& getValueFromNode(LLSelectNode* node)
{
- LLSelectNode* node = *iter;
- if (!node->mValid)
- {
- return FALSE;
- }
-
- if (first)
- {
- first_id = node->mPermissions->getGroup();
- first = FALSE;
- }
- else
- {
- if ( !(first_id == node->mPermissions->getGroup() ) )
- {
- identical = FALSE;
- break;
- }
- }
+ return node->mPermissions->getGroup();
}
+};
- result_id = first_id;
+BOOL LLSelectMgr::selectGetGroup(LLUUID& result_id)
+{
+ LLSelectGetFirstGroup test;
+ getFirst(&test);
- return identical;
+ result_id = test.mFirstValue;
+ return test.mIdentical;
}
//-----------------------------------------------------------------------------
// selectIsGroupOwned()
-// Only operates on root nodes.
-// Returns TRUE if all have valid data and they are all group owned.
+// Only operates on root nodes unless editing linked parts.
+// Returns TRUE if the first selected is group owned.
//-----------------------------------------------------------------------------
-BOOL LLSelectMgr::selectIsGroupOwned()
+struct LLSelectGetFirstGroupOwner : public LLSelectGetFirstTest
{
- BOOL found_one = FALSE;
- for (LLObjectSelection::root_object_iterator iter = getSelection()->root_object_begin();
- iter != getSelection()->root_object_end(); iter++ )
+protected:
+ virtual const LLUUID& getValueFromNode(LLSelectNode* node)
{
- LLSelectNode* node = *iter;
- if (!node->mValid)
+ if (node->mPermissions->isGroupOwned())
{
- return FALSE;
+ return node->mPermissions->getGroup();
}
- found_one = TRUE;
- if (!node->mPermissions->isGroupOwned())
- {
- return FALSE;
- }
- }
- return found_one ? TRUE : FALSE;
+ return LLUUID::null;
+ }
+};
+
+BOOL LLSelectMgr::selectIsGroupOwned()
+{
+ LLSelectGetFirstGroupOwner test;
+ getFirst(&test);
+
+ return test.mFirstValue.notNull() ? TRUE : FALSE;
}
//-----------------------------------------------------------------------------
@@ -3051,11 +3521,11 @@ bool LLSelectMgr::confirmDelete(const LLSD& notification, const LLSD& response,
// TODO: Make sure you have delete permissions on all of them.
const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH);
// attempt to derez into the trash.
- LLDeRezInfo* info = new LLDeRezInfo(DRD_TRASH, trash_id);
+ LLDeRezInfo info(DRD_TRASH, trash_id);
LLSelectMgr::getInstance()->sendListToRegions("DeRezObject",
packDeRezHeader,
packObjectLocalID,
- (void*)info,
+ (void*) &info,
SEND_ONLY_ROOTS);
// VEFFECT: Delete Object - one effect for all deletes
if (LLSelectMgr::getInstance()->mSelectedObjects->mSelectType != SELECT_TYPE_HUD)
@@ -3745,13 +4215,15 @@ void LLSelectMgr::deselectAllIfTooFar()
void LLSelectMgr::selectionSetObjectName(const std::string& name)
{
+ std::string name_copy(name);
+
// we only work correctly if 1 object is selected.
if(mSelectedObjects->getRootObjectCount() == 1)
{
sendListToRegions("ObjectName",
packAgentAndSessionID,
packObjectName,
- (void*)(new std::string(name)),
+ (void*)(&name_copy),
SEND_ONLY_ROOTS);
}
else if(mSelectedObjects->getObjectCount() == 1)
@@ -3759,20 +4231,22 @@ void LLSelectMgr::selectionSetObjectName(const std::string& name)
sendListToRegions("ObjectName",
packAgentAndSessionID,
packObjectName,
- (void*)(new std::string(name)),
+ (void*)(&name_copy),
SEND_INDIVIDUALS);
}
}
void LLSelectMgr::selectionSetObjectDescription(const std::string& desc)
{
+ std::string desc_copy(desc);
+
// we only work correctly if 1 object is selected.
if(mSelectedObjects->getRootObjectCount() == 1)
{
sendListToRegions("ObjectDescription",
packAgentAndSessionID,
packObjectDescription,
- (void*)(new std::string(desc)),
+ (void*)(&desc_copy),
SEND_ONLY_ROOTS);
}
else if(mSelectedObjects->getObjectCount() == 1)
@@ -3780,7 +4254,7 @@ void LLSelectMgr::selectionSetObjectDescription(const std::string& desc)
sendListToRegions("ObjectDescription",
packAgentAndSessionID,
packObjectDescription,
- (void*)(new std::string(desc)),
+ (void*)(&desc_copy),
SEND_INDIVIDUALS);
}
}
@@ -4053,7 +4527,8 @@ void LLSelectMgr::saveSelectedObjectTransform(EActionType action_type)
struct f : public LLSelectedNodeFunctor
{
EActionType mActionType;
- f(EActionType a) : mActionType(a) {}
+ LLSelectMgr* mManager;
+ f(EActionType a, LLSelectMgr* p) : mActionType(a), mManager(p) {}
virtual bool apply(LLSelectNode* selectNode)
{
LLViewerObject* object = selectNode->getObject();
@@ -4100,10 +4575,10 @@ void LLSelectMgr::saveSelectedObjectTransform(EActionType action_type)
}
selectNode->mSavedScale = object->getScale();
- selectNode->saveTextureScaleRatios();
+ selectNode->saveTextureScaleRatios(mManager->mTextureChannel);
return true;
}
- } func(action_type);
+ } func(action_type, this);
getSelection()->applyToNodes(&func);
mSavedSelectionBBox = getBBoxOfSelection();
@@ -4117,8 +4592,7 @@ struct LLSelectMgrApplyFlags : public LLSelectedObjectFunctor
virtual bool apply(LLViewerObject* object)
{
if ( object->permModify() && // preemptive permissions check
- object->isRoot() && // don't send for child objects
- !object->isJointChild())
+ object->isRoot()) // don't send for child objects
{
object->setFlags( mFlags, mState);
}
@@ -4144,12 +4618,6 @@ void LLSelectMgr::selectionUpdatePhantom(BOOL is_phantom)
getSelection()->applyToObjects(&func);
}
-void LLSelectMgr::selectionUpdateCastShadows(BOOL cast_shadows)
-{
- LLSelectMgrApplyFlags func( FLAGS_CAST_SHADOWS, cast_shadows);
- getSelection()->applyToObjects(&func);
-}
-
//----------------------------------------------------------------------
// Helpful packing functions for sendObjectMessage()
//----------------------------------------------------------------------
@@ -4298,15 +4766,14 @@ void LLSelectMgr::packObjectName(LLSelectNode* node, void* user_data)
gMessageSystem->addU32Fast(_PREHASH_LocalID, node->getObject()->getLocalID());
gMessageSystem->addStringFast(_PREHASH_Name, *name);
}
- delete name;
}
// static
void LLSelectMgr::packObjectDescription(LLSelectNode* node, void* user_data)
{
const std::string* desc = (const std::string*)user_data;
- if(!desc->empty())
- {
+ if(desc)
+ { // Empty (non-null, but zero length) descriptions are OK
gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
gMessageSystem->addU32Fast(_PREHASH_LocalID, node->getObject()->getLocalID());
gMessageSystem->addStringFast(_PREHASH_Description, *desc);
@@ -4638,7 +5105,11 @@ void LLSelectMgr::processObjectProperties(LLMessageSystem* msg, void** user_data
} func(id);
LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstNode(&func);
- if (node)
+ if (!node)
+ {
+ llwarns << "Couldn't find object " << id << " selected." << llendl;
+ }
+ else
{
if (node->mInventorySerial != inv_serial)
{
@@ -4709,13 +5180,6 @@ void LLSelectMgr::processObjectProperties(LLMessageSystem* msg, void** user_data
dialog_refresh_all();
- // silly hack to allow 'save into inventory'
- if(gPopupMenuView->getVisible())
- {
- gPopupMenuView->setItemEnabled(SAVE_INTO_INVENTORY,
- enable_save_into_inventory(NULL));
- }
-
// hack for left-click buy object
LLToolPie::selectionPropertiesReceived();
}
@@ -4849,7 +5313,7 @@ void LLSelectMgr::updateSilhouettes()
if (!mSilhouetteImagep)
{
- mSilhouetteImagep = LLViewerTextureManager::getFetchedTextureFromFile("silhouette.j2c", TRUE, LLViewerTexture::BOOST_UI);
+ mSilhouetteImagep = LLViewerTextureManager::getFetchedTextureFromFile("silhouette.j2c", FTT_LOCAL_FILE, TRUE, LLGLTexture::BOOST_UI);
}
mHighlightedObjects->cleanupNodes();
@@ -5425,36 +5889,43 @@ void LLSelectNode::saveTextures(const uuid_vec_t& textures)
}
}
-void LLSelectNode::saveTextureScaleRatios()
+void LLSelectNode::saveTextureScaleRatios(LLRender::eTexIndex index_to_query)
{
mTextureScaleRatios.clear();
+
if (mObject.notNull())
{
+
+ LLVector3 scale = mObject->getScale();
+
for (U8 i = 0; i < mObject->getNumTEs(); i++)
{
- F32 s,t;
+ F32 diffuse_s = 1.0f;
+ F32 diffuse_t = 1.0f;
+
+ LLVector3 v;
const LLTextureEntry* tep = mObject->getTE(i);
- tep->getScale(&s,&t);
- U32 s_axis = 0;
- U32 t_axis = 0;
+ if (!tep)
+ continue;
+ U32 s_axis = VX;
+ U32 t_axis = VY;
LLPrimitive::getTESTAxes(i, &s_axis, &t_axis);
- LLVector3 v;
- LLVector3 scale = mObject->getScale();
-
+ tep->getScale(&diffuse_s,&diffuse_t);
+
if (tep->getTexGen() == LLTextureEntry::TEX_GEN_PLANAR)
{
- v.mV[s_axis] = s*scale.mV[s_axis];
- v.mV[t_axis] = t*scale.mV[t_axis];
+ v.mV[s_axis] = diffuse_s*scale.mV[s_axis];
+ v.mV[t_axis] = diffuse_t*scale.mV[t_axis];
+ mTextureScaleRatios.push_back(v);
}
else
{
- v.mV[s_axis] = s/scale.mV[s_axis];
- v.mV[t_axis] = t/scale.mV[t_axis];
- }
-
- mTextureScaleRatios.push_back(v);
+ v.mV[s_axis] = diffuse_s/scale.mV[s_axis];
+ v.mV[t_axis] = diffuse_t/scale.mV[t_axis];
+ mTextureScaleRatios.push_back(v);
+ }
}
}
}
@@ -5580,7 +6051,7 @@ void pushWireframe(LLDrawable* drawable)
for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i)
{
const LLVolumeFace& face = volume->getVolumeFace(i);
- LLVertexBuffer::drawElements(LLRender::TRIANGLES, face.mPositions, face.mTexCoords, face.mNumIndices, face.mIndices);
+ LLVertexBuffer::drawElements(LLRender::TRIANGLES, face.mPositions, NULL, face.mNumIndices, face.mIndices);
}
}
@@ -5607,7 +6078,7 @@ void LLSelectNode::renderOneWireframe(const LLColor4& color)
if (shader)
{
- gHighlightProgram.bind();
+ gDebugProgram.bind();
}
gGL.matrixMode(LLRender::MM_MODELVIEW);
@@ -5980,8 +6451,6 @@ void LLSelectMgr::updateSelectionCenter()
// matches the root prim's (affecting the orientation of the manipulators).
bbox.addBBoxAgent( (mSelectedObjects->getFirstRootObject(TRUE))->getBoundingBoxAgent() );
- std::vector < LLViewerObject *> jointed_objects;
-
for (LLObjectSelection::iterator iter = mSelectedObjects->begin();
iter != mSelectedObjects->end(); iter++)
{
@@ -5999,11 +6468,6 @@ void LLSelectMgr::updateSelectionCenter()
}
bbox.addBBoxAgent( object->getBoundingBoxAgent() );
-
- if (object->isJointChild())
- {
- jointed_objects.push_back(object);
- }
}
LLVector3 bbox_center_agent = bbox.getCenterAgent();
@@ -6242,7 +6706,7 @@ BOOL LLSelectMgr::canSelectObject(LLViewerObject* object)
}
if ((gSavedSettings.getBOOL("SelectOwnedOnly") && !object->permYouOwner()) ||
- (gSavedSettings.getBOOL("SelectMovableOnly") && !object->permMove()))
+ (gSavedSettings.getBOOL("SelectMovableOnly") && (!object->permMove() || object->isPermanentEnforced())))
{
// only select my own objects
return FALSE;
@@ -6293,19 +6757,19 @@ void LLSelectMgr::setAgentHUDZoom(F32 target_zoom, F32 current_zoom)
bool LLObjectSelection::is_root::operator()(LLSelectNode *node)
{
LLViewerObject* object = node->getObject();
- return (object != NULL) && !node->mIndividualSelection && (object->isRootEdit() || object->isJointChild());
+ return (object != NULL) && !node->mIndividualSelection && (object->isRootEdit());
}
bool LLObjectSelection::is_valid_root::operator()(LLSelectNode *node)
{
LLViewerObject* object = node->getObject();
- return (object != NULL) && node->mValid && !node->mIndividualSelection && (object->isRootEdit() || object->isJointChild());
+ return (object != NULL) && node->mValid && !node->mIndividualSelection && (object->isRootEdit());
}
bool LLObjectSelection::is_root_object::operator()(LLSelectNode *node)
{
LLViewerObject* object = node->getObject();
- return (object != NULL) && (object->isRootEdit() || object->isJointChild());
+ return (object != NULL) && (object->isRootEdit());
}
LLObjectSelection::LLObjectSelection() :
@@ -6934,7 +7398,7 @@ LLSelectNode* LLObjectSelection::getFirstMoveableNode(BOOL get_root_first)
bool apply(LLSelectNode* node)
{
LLViewerObject* obj = node->getObject();
- return obj && obj->permMove();
+ return obj && obj->permMove() && !obj->isPermanentEnforced();
}
} func;
LLSelectNode* res = get_root_first ? getFirstRootNode(&func, TRUE) : getFirstNode(&func);
@@ -6972,9 +7436,10 @@ LLViewerObject* LLObjectSelection::getFirstDeleteableObject()
LLViewerObject* obj = node->getObject();
// you can delete an object if you are the owner
// or you have permission to modify it.
- if( obj && ( (obj->permModify()) ||
- (obj->permYouOwner()) ||
- (!obj->permAnyOwner()) )) // public
+ if( obj && !obj->isPermanentEnforced() &&
+ ( (obj->permModify()) ||
+ (obj->permYouOwner()) ||
+ (!obj->permAnyOwner()) )) // public
{
if( !obj->isAttachment() )
{
@@ -7014,7 +7479,7 @@ LLViewerObject* LLObjectSelection::getFirstMoveableObject(BOOL get_parent)
bool apply(LLSelectNode* node)
{
LLViewerObject* obj = node->getObject();
- return obj && obj->permMove();
+ return obj && obj->permMove() && !obj->isPermanentEnforced();
}
} func;
return getFirstSelectedObject(&func, get_parent);
@@ -7083,7 +7548,7 @@ bool LLSelectMgr::selectionMove(const LLVector3& displ,
{
obj = (*it)->getObject();
bool enable_pos = false, enable_rot = false;
- bool perm_move = obj->permMove();
+ bool perm_move = obj->permMove() && !obj->isPermanentEnforced();
bool perm_mod = obj->permModify();
LLVector3d sel_center(getSelectionCenterGlobal());
diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h
index 87ada5ac6b..d4b736640c 100644..100755
--- a/indra/newview/llselectmgr.h
+++ b/indra/newview/llselectmgr.h
@@ -43,10 +43,12 @@
#include "llpermissions.h"
#include "llcontrol.h"
#include "llviewerobject.h" // LLObjectSelection::getSelectedTEValue template
+#include "llmaterial.h"
#include <deque>
#include <boost/iterator/filter_iterator.hpp>
#include <boost/signals2.hpp>
+#include <boost/make_shared.hpp> // boost::make_shared
class LLMessageSystem;
class LLViewerTexture;
@@ -83,6 +85,12 @@ struct LLSelectedTEFunctor
virtual bool apply(LLViewerObject* object, S32 face) = 0;
};
+struct LLSelectedTEMaterialFunctor
+{
+ virtual ~LLSelectedTEMaterialFunctor() {};
+ virtual LLMaterialPtr apply(LLViewerObject* object, S32 face, LLTextureEntry* tep, LLMaterialPtr& current_material) = 0;
+};
+
template <typename T> struct LLSelectedTEGetFunctor
{
virtual ~LLSelectedTEGetFunctor() {};
@@ -121,6 +129,8 @@ typedef enum e_selection_type
SELECT_TYPE_HUD
}ESelectType;
+const S32 TE_SELECT_MASK_ALL = 0xFFFFFFFF;
+
// Contains information about a selected object, particularly which TEs are selected.
class LLSelectNode
{
@@ -143,7 +153,7 @@ public:
// *NOTE: invalidate stored textures and colors when # faces change
void saveColors();
void saveTextures(const uuid_vec_t& textures);
- void saveTextureScaleRatios();
+ void saveTextureScaleRatios(LLRender::eTexIndex index_to_query);
BOOL allowOperationOnNode(PermissionBit op, U64 group_proxy_power) const;
@@ -307,6 +317,15 @@ public:
bool applyToRootNodes(LLSelectedNodeFunctor* func, bool firstonly = false);
bool applyToNodes(LLSelectedNodeFunctor* func, bool firstonly = false);
+ /*
+ * Used to apply (no-copy) textures to the selected object or
+ * selected face/faces of the object.
+ * This method moves (no-copy) texture to the object's inventory
+ * and doesn't make copy of the texture for each face.
+ * Then this only texture is used for all selected faces.
+ */
+ void applyNoCopyTextureToTEs(LLViewerInventoryItem* item);
+
ESelectType getSelectType() const { return mSelectType; }
private:
@@ -334,6 +353,9 @@ typedef LLSafeHandle<LLObjectSelection> LLObjectSelectionHandle;
extern template class LLSelectMgr* LLSingleton<class LLSelectMgr>::getInstance();
#endif
+// For use with getFirstTest()
+struct LLSelectGetFirstTest;
+
class LLSelectMgr : public LLEditMenuHandler, public LLSingleton<LLSelectMgr>
{
public:
@@ -498,10 +520,14 @@ public:
void saveSelectedObjectColors();
void saveSelectedObjectTextures();
+ // Sets which texture channel to query for scale and rot of display
+ // and depends on UI state of LLPanelFace when editing
+ void setTextureChannel(LLRender::eTexIndex texIndex) { mTextureChannel = texIndex; }
+ LLRender::eTexIndex getTextureChannel() { return mTextureChannel; }
+
void selectionUpdatePhysics(BOOL use_physics);
void selectionUpdateTemporary(BOOL is_temporary);
void selectionUpdatePhantom(BOOL is_ghost);
- void selectionUpdateCastShadows(BOOL cast_shadows);
void selectionDump();
BOOL selectionAllPCode(LLPCode code); // all objects have this PCode
@@ -529,6 +555,8 @@ public:
void selectionSetClickAction(U8 action);
void selectionSetIncludeInSearch(bool include_in_search);
void selectionSetGlow(const F32 glow);
+ void selectionSetMaterialParams(LLSelectedTEMaterialFunctor* material_func);
+ void selectionRemoveMaterial();
void selectionSetObjectPermissions(U8 perm_field, BOOL set, U32 perm_mask, BOOL override = FALSE);
void selectionSetObjectName(const std::string& name);
@@ -539,8 +567,6 @@ public:
void selectionTexScaleAutofit(F32 repeats_per_meter);
void adjustTexturesByScale(BOOL send_to_sim, BOOL stretch);
- void selectionResetRotation(); // sets rotation quat to identity
- void selectionRotateAroundZ(F32 degrees);
bool selectionMove(const LLVector3& displ, F32 rx, F32 ry, F32 rz,
U32 update_type);
void sendSelectionMove();
@@ -563,6 +589,33 @@ public:
BOOL selectGetRootsModify();
BOOL selectGetModify();
+ // returns TRUE if is all objects are non-permanent-enforced
+ BOOL selectGetRootsNonPermanentEnforced();
+ BOOL selectGetNonPermanentEnforced();
+
+ // returns TRUE if is all objects are permanent
+ BOOL selectGetRootsPermanent();
+ BOOL selectGetPermanent();
+
+ // returns TRUE if is all objects are character
+ BOOL selectGetRootsCharacter();
+ BOOL selectGetCharacter();
+
+ // returns TRUE if is all objects are not permanent
+ BOOL selectGetRootsNonPathfinding();
+ BOOL selectGetNonPathfinding();
+
+ // returns TRUE if is all objects are not permanent
+ BOOL selectGetRootsNonPermanent();
+ BOOL selectGetNonPermanent();
+
+ // returns TRUE if is all objects are not character
+ BOOL selectGetRootsNonCharacter();
+ BOOL selectGetNonCharacter();
+
+ BOOL selectGetEditableLinksets();
+ BOOL selectGetViewableCharacters();
+
// returns TRUE if selected objects can be transferred.
BOOL selectGetRootsTransfer();
@@ -712,6 +765,9 @@ private:
static void packGodlikeHead(void* user_data);
static bool confirmDelete(const LLSD& notification, const LLSD& response, LLObjectSelectionHandle handle);
+ // Get the first ID that matches test and whether or not all ids are identical in selected objects.
+ void getFirst(LLSelectGetFirstTest* test);
+
public:
// Observer/callback support for when object selection changes or
// properties are received/updated
@@ -730,10 +786,9 @@ private:
LLVector3 mGridOrigin;
LLVector3 mGridScale;
EGridMode mGridMode;
- BOOL mGridValid;
-
BOOL mTEMode; // render te
+ LLRender::eTexIndex mTextureChannel; // diff, norm, or spec, depending on UI editing mode
LLVector3d mSelectionCenterGlobal;
LLBBox mSelectionBBox;
diff --git a/indra/newview/llshareavatarhandler.cpp b/indra/newview/llshareavatarhandler.cpp
index 6b4f1d3dc6..6b4f1d3dc6 100644..100755
--- a/indra/newview/llshareavatarhandler.cpp
+++ b/indra/newview/llshareavatarhandler.cpp
diff --git a/indra/newview/llsidepanelappearance.cpp b/indra/newview/llsidepanelappearance.cpp
index 853656905c..df413ab849 100644..100755
--- a/indra/newview/llsidepanelappearance.cpp
+++ b/indra/newview/llsidepanelappearance.cpp
@@ -38,7 +38,7 @@
#include "llfiltereditor.h"
#include "llfloaterreg.h"
#include "llfloaterworldmap.h"
-#include "llfoldervieweventlistener.h"
+#include "llfolderviewmodel.h"
#include "lloutfitobserver.h"
#include "llpaneleditwearable.h"
#include "llpaneloutfitsinventory.h"
@@ -47,7 +47,7 @@
#include "llviewercontrol.h"
#include "llviewerregion.h"
#include "llvoavatarself.h"
-#include "llwearable.h"
+#include "llviewerwearable.h"
static LLRegisterPanelClassWrapper<LLSidepanelAppearance> t_appearance("sidepanel_appearance");
@@ -198,7 +198,7 @@ void LLSidepanelAppearance::updateToVisibility(const LLSD &new_visibility)
if (is_outfit_edit_visible || is_wearable_edit_visible)
{
- const LLWearable *wearable_ptr = mEditWearable->getWearable();
+ const LLViewerWearable *wearable_ptr = mEditWearable->getWearable();
if (!wearable_ptr)
{
llwarns << "Visibility change to invalid wearable" << llendl;
@@ -206,12 +206,9 @@ void LLSidepanelAppearance::updateToVisibility(const LLSD &new_visibility)
}
// Disable camera switch is currently just for WT_PHYSICS type since we don't want to freeze the avatar
// when editing its physics.
- const BOOL disable_camera_motion = LLWearableType::getDisableCameraSwitch(wearable_ptr->getType());
- if (!gAgentCamera.cameraCustomizeAvatar() &&
- !disable_camera_motion &&
- gSavedSettings.getBOOL("AppearanceCameraMovement"))
+ if (!gAgentCamera.cameraCustomizeAvatar())
{
- gAgentCamera.changeCameraToCustomizeAvatar();
+ LLVOAvatarSelf::onCustomizeStart(LLWearableType::getDisableCameraSwitch(wearable_ptr->getType()));
}
if (is_wearable_edit_visible)
{
@@ -267,11 +264,11 @@ void LLSidepanelAppearance::onOpenOutfitButtonClicked()
if (inventory_panel)
{
LLFolderView* root = inventory_panel->getRootFolder();
- LLFolderViewItem *outfit_folder = root->getItemByID(outfit_link->getLinkedUUID());
+ LLFolderViewItem *outfit_folder = inventory_panel->getItemByID(outfit_link->getLinkedUUID());
if (outfit_folder)
{
outfit_folder->setOpen(!outfit_folder->isOpen());
- root->setSelectionFromRoot(outfit_folder,TRUE);
+ root->setSelection(outfit_folder,TRUE);
root->scrollToShowSelection();
}
}
@@ -283,7 +280,7 @@ void LLSidepanelAppearance::onEditAppearanceButtonClicked()
{
if (gAgentWearables.areWearablesLoaded())
{
- gAgentCamera.changeCameraToCustomizeAvatar();
+ LLVOAvatarSelf::onCustomizeStart();
}
}
@@ -329,7 +326,7 @@ void LLSidepanelAppearance::showOutfitEditPanel()
toggleOutfitEditPanel(TRUE);
}
-void LLSidepanelAppearance::showWearableEditPanel(LLWearable *wearable /* = NULL*/, BOOL disable_camera_switch)
+void LLSidepanelAppearance::showWearableEditPanel(LLViewerWearable *wearable /* = NULL*/, BOOL disable_camera_switch)
{
toggleMyOutfitsPanel(FALSE);
toggleOutfitEditPanel(FALSE, TRUE); // don't switch out of edit appearance mode
@@ -371,19 +368,19 @@ void LLSidepanelAppearance::toggleOutfitEditPanel(BOOL visible, BOOL disable_cam
if (visible)
{
mOutfitEdit->onOpen(LLSD());
- if (!disable_camera_switch && gSavedSettings.getBOOL("AppearanceCameraMovement") )
- {
- gAgentCamera.changeCameraToCustomizeAvatar();
- }
+ LLVOAvatarSelf::onCustomizeStart(disable_camera_switch);
}
- else if (!disable_camera_switch && gSavedSettings.getBOOL("AppearanceCameraMovement") )
+ else
{
- gAgentCamera.changeCameraToDefault();
- gAgentCamera.resetView();
+ if (!disable_camera_switch) // if we're just switching between outfit and wearable editing, don't end customization.
+ {
+ LLVOAvatarSelf::onCustomizeEnd(disable_camera_switch);
+ LLAppearanceMgr::getInstance()->updateIsDirty();
+ }
}
}
-void LLSidepanelAppearance::toggleWearableEditPanel(BOOL visible, LLWearable *wearable, BOOL disable_camera_switch)
+void LLSidepanelAppearance::toggleWearableEditPanel(BOOL visible, LLViewerWearable *wearable, BOOL disable_camera_switch)
{
if (!mEditWearable || mEditWearable->getVisible() == visible)
{
@@ -393,7 +390,7 @@ void LLSidepanelAppearance::toggleWearableEditPanel(BOOL visible, LLWearable *we
if (!wearable)
{
- wearable = gAgentWearables.getWearable(LLWearableType::WT_SHAPE, 0);
+ wearable = gAgentWearables.getViewerWearable(LLWearableType::WT_SHAPE, 0);
}
if (!wearable)
{
@@ -405,10 +402,7 @@ void LLSidepanelAppearance::toggleWearableEditPanel(BOOL visible, LLWearable *we
if (visible)
{
- if (!disable_camera_switch && gSavedSettings.getBOOL("AppearanceCameraMovement") )
- {
- gAgentCamera.changeCameraToCustomizeAvatar();
- }
+ LLVOAvatarSelf::onCustomizeStart(disable_camera_switch);
mEditWearable->setWearable(wearable, disable_camera_switch);
mEditWearable->onOpen(LLSD()); // currently no-op, just for consistency
}
@@ -416,10 +410,10 @@ void LLSidepanelAppearance::toggleWearableEditPanel(BOOL visible, LLWearable *we
{
// Save changes if closing.
mEditWearable->saveChanges();
- if (!disable_camera_switch && gSavedSettings.getBOOL("AppearanceCameraMovement") )
+ LLAppearanceMgr::getInstance()->updateIsDirty();
+ if (!disable_camera_switch) // if we're just switching between outfit and wearable editing, don't end customization.
{
- gAgentCamera.changeCameraToDefault();
- gAgentCamera.resetView();
+ LLVOAvatarSelf::onCustomizeEnd(disable_camera_switch);
}
}
}
@@ -453,10 +447,9 @@ void LLSidepanelAppearance::refreshCurrentOutfitName(const std::string& name)
}
//static
-void LLSidepanelAppearance::editWearable(LLWearable *wearable, LLView *data, BOOL disable_camera_switch)
+void LLSidepanelAppearance::editWearable(LLViewerWearable *wearable, LLView *data, BOOL disable_camera_switch)
{
LLFloaterSidePanelContainer::showPanel("appearance", LLSD());
-
LLSidepanelAppearance *panel = dynamic_cast<LLSidepanelAppearance*>(data);
if (panel)
{
diff --git a/indra/newview/llsidepanelappearance.h b/indra/newview/llsidepanelappearance.h
index 6dd3520266..b0a6b9cf91 100644..100755
--- a/indra/newview/llsidepanelappearance.h
+++ b/indra/newview/llsidepanelappearance.h
@@ -36,7 +36,7 @@
class LLFilterEditor;
class LLCurrentlyWornFetchObserver;
class LLPanelEditWearable;
-class LLWearable;
+class LLViewerWearable;
class LLPanelOutfitsInventory;
class LLSidepanelAppearance : public LLPanel
@@ -51,7 +51,7 @@ public:
void refreshCurrentOutfitName(const std::string& name = "");
- static void editWearable(LLWearable *wearable, LLView *data, BOOL disable_camera_switch = FALSE);
+ static void editWearable(LLViewerWearable *wearable, LLView *data, BOOL disable_camera_switch = FALSE);
void fetchInventory();
void inventoryFetched();
@@ -59,11 +59,12 @@ public:
void showOutfitsInventoryPanel();
void showOutfitEditPanel();
- void showWearableEditPanel(LLWearable *wearable = NULL, BOOL disable_camera_switch = FALSE);
+ void showWearableEditPanel(LLViewerWearable *wearable = NULL, BOOL disable_camera_switch = FALSE);
void setWearablesLoading(bool val);
void showDefaultSubpart();
void updateScrollingPanelList();
void updateToVisibility( const LLSD& new_visibility );
+ LLPanelEditWearable* getWearable(){ return mEditWearable; }
private:
void onFilterEdit(const std::string& search_string);
@@ -74,7 +75,7 @@ private:
void toggleMyOutfitsPanel(BOOL visible);
void toggleOutfitEditPanel(BOOL visible, BOOL disable_camera_switch = FALSE);
- void toggleWearableEditPanel(BOOL visible, LLWearable* wearable = NULL, BOOL disable_camera_switch = FALSE);
+ void toggleWearableEditPanel(BOOL visible, LLViewerWearable* wearable = NULL, BOOL disable_camera_switch = FALSE);
LLFilterEditor* mFilterEditor;
LLPanelOutfitsInventory* mPanelOutfitsInventory;
diff --git a/indra/newview/llsidepanelinventory.cpp b/indra/newview/llsidepanelinventory.cpp
index 4f9ab318a5..cbf43dbb93 100644..100755
--- a/indra/newview/llsidepanelinventory.cpp
+++ b/indra/newview/llsidepanelinventory.cpp
@@ -36,6 +36,7 @@
#include "llfirstuse.h"
#include "llfloatersidepanelcontainer.h"
#include "llfoldertype.h"
+#include "llfolderview.h"
#include "llhttpclient.h"
#include "llinventorybridge.h"
#include "llinventoryfunctions.h"
@@ -259,9 +260,8 @@ void LLSidepanelInventory::updateInbox()
//
const bool do_not_create_folder = false;
- const bool do_not_find_in_library = false;
- const LLUUID inbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX, do_not_create_folder, do_not_find_in_library);
+ const LLUUID inbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX, do_not_create_folder);
// Set up observer to listen for creation of inbox if at least one of them doesn't exist
if (inbox_id.isNull())
@@ -383,10 +383,10 @@ void LLSidepanelInventory::onToggleInboxBtn()
{
inboxPanel->setTargetDim(gSavedPerAccountSettings.getS32("InventoryInboxHeight"));
if (inboxPanel->isInVisibleChain())
- {
- gSavedPerAccountSettings.setU32("LastInventoryInboxActivity", time_corrected());
- }
+ {
+ gSavedPerAccountSettings.setU32("LastInventoryInboxActivity", time_corrected());
}
+}
else
{
gSavedPerAccountSettings.setS32("InventoryInboxHeight", inboxPanel->getTargetDim());
@@ -397,7 +397,7 @@ void LLSidepanelInventory::onToggleInboxBtn()
void LLSidepanelInventory::onOpen(const LLSD& key)
{
LLFirstUse::newInventory(false);
-
+ mPanelMainInventory->setFocusFilterEditor();
#if AUTO_EXPAND_INBOX
// Expand the inbox if we have fresh items
LLPanelMarketplaceInbox * inbox = findChild<LLPanelMarketplaceInbox>(MARKETPLACE_INBOX_PANEL);
@@ -448,7 +448,7 @@ void LLSidepanelInventory::onInfoButtonClicked()
void LLSidepanelInventory::onShareButtonClicked()
{
- LLAvatarActions::shareWithAvatars();
+ LLAvatarActions::shareWithAvatars(this);
}
void LLSidepanelInventory::onShopButtonClicked()
@@ -472,7 +472,7 @@ void LLSidepanelInventory::performActionOnSelection(const std::string &action)
}
}
- current_item->getListener()->performAction(mPanelMainInventory->getActivePanel()->getModel(), action);
+ static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->performAction(mPanelMainInventory->getActivePanel()->getModel(), action);
}
void LLSidepanelInventory::onWearButtonClicked()
@@ -662,7 +662,7 @@ LLInventoryItem *LLSidepanelInventory::getSelectedItem()
return NULL;
}
}
- const LLUUID &item_id = current_item->getListener()->getUUID();
+ const LLUUID &item_id = static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->getUUID();
LLInventoryItem *item = gInventory.getItem(item_id);
return item;
}
@@ -671,7 +671,7 @@ U32 LLSidepanelInventory::getSelectedCount()
{
int count = 0;
- std::set<LLUUID> selection_list = mPanelMainInventory->getActivePanel()->getRootFolder()->getSelectionList();
+ std::set<LLFolderViewItem*> selection_list = mPanelMainInventory->getActivePanel()->getRootFolder()->getSelectionList();
count += selection_list.size();
if ((count == 0) && mInboxEnabled && (mInventoryPanelInbox != NULL))
@@ -722,9 +722,9 @@ void LLSidepanelInventory::clearSelections(bool clearMain, bool clearInbox)
updateVerbs();
}
-std::set<LLUUID> LLSidepanelInventory::getInboxSelectionList()
+std::set<LLFolderViewItem*> LLSidepanelInventory::getInboxSelectionList()
{
- std::set<LLUUID> inventory_selected_uuids;
+ std::set<LLFolderViewItem*> inventory_selected_uuids;
if (mInboxEnabled && (mInventoryPanelInbox != NULL))
{
diff --git a/indra/newview/llsidepanelinventory.h b/indra/newview/llsidepanelinventory.h
index a33607f50d..e8b2808d4f 100644..100755
--- a/indra/newview/llsidepanelinventory.h
+++ b/indra/newview/llsidepanelinventory.h
@@ -63,7 +63,7 @@ public:
BOOL isMainInventoryPanelActive() const;
void clearSelections(bool clearMain, bool clearInbox);
- std::set<LLUUID> getInboxSelectionList();
+ std::set<LLFolderViewItem*> getInboxSelectionList();
void showItemInfoPanel();
void showTaskInfoPanel();
diff --git a/indra/newview/llsidepanelinventorysubpanel.cpp b/indra/newview/llsidepanelinventorysubpanel.cpp
index 2918bb388a..2918bb388a 100644..100755
--- a/indra/newview/llsidepanelinventorysubpanel.cpp
+++ b/indra/newview/llsidepanelinventorysubpanel.cpp
diff --git a/indra/newview/llsidepanelinventorysubpanel.h b/indra/newview/llsidepanelinventorysubpanel.h
index b5cf3aaf17..b5cf3aaf17 100644..100755
--- a/indra/newview/llsidepanelinventorysubpanel.h
+++ b/indra/newview/llsidepanelinventorysubpanel.h
diff --git a/indra/newview/llsidepaneliteminfo.cpp b/indra/newview/llsidepaneliteminfo.cpp
index 1ce05da849..92c2863ffd 100644..100755
--- a/indra/newview/llsidepaneliteminfo.cpp
+++ b/indra/newview/llsidepaneliteminfo.cpp
@@ -352,7 +352,7 @@ void LLSidepanelItemInfo::refreshFromItem(LLViewerInventoryItem* item)
getChildView("BtnCreator")->setEnabled(FALSE);
getChildView("LabelCreatorTitle")->setEnabled(FALSE);
getChildView("LabelCreatorName")->setEnabled(FALSE);
- getChild<LLUICtrl>("LabelCreatorName")->setValue(getString("unknown"));
+ getChild<LLUICtrl>("LabelCreatorName")->setValue(getString("unknown_multiple"));
}
////////////////
diff --git a/indra/newview/llsidepaneliteminfo.h b/indra/newview/llsidepaneliteminfo.h
index 12aaca923e..12aaca923e 100644..100755
--- a/indra/newview/llsidepaneliteminfo.h
+++ b/indra/newview/llsidepaneliteminfo.h
diff --git a/indra/newview/llsidepaneltaskinfo.cpp b/indra/newview/llsidepaneltaskinfo.cpp
index 24cb559fd0..9be6d0c5f1 100644..100755
--- a/indra/newview/llsidepaneltaskinfo.cpp
+++ b/indra/newview/llsidepaneltaskinfo.cpp
@@ -61,6 +61,9 @@
#include "llspinctrl.h"
#include "roles_constants.h"
#include "llgroupactions.h"
+#include "lltextbase.h"
+#include "llstring.h"
+#include "lltrans.h"
///----------------------------------------------------------------------------
/// Class llsidepaneltaskinfo
@@ -94,10 +97,12 @@ BOOL LLSidepanelTaskInfo::postBuild()
mPayBtn = getChild<LLButton>("pay_btn");
mPayBtn->setClickedCallback(boost::bind(&LLSidepanelTaskInfo::onPayButtonClicked, this));
mBuyBtn = getChild<LLButton>("buy_btn");
- mBuyBtn->setClickedCallback(boost::bind(&LLSidepanelTaskInfo::onBuyButtonClicked, this));
+ mBuyBtn->setClickedCallback(boost::bind(&handle_buy));
mDetailsBtn = getChild<LLButton>("details_btn");
mDetailsBtn->setClickedCallback(boost::bind(&LLSidepanelTaskInfo::onDetailsButtonClicked, this));
+ mDeedBtn = getChild<LLButton>("button deed");
+
mLabelGroupName = getChild<LLNameBox>("Group Name Proxy");
childSetCommitCallback("Object Name", LLSidepanelTaskInfo::onCommitName,this);
@@ -146,6 +151,7 @@ BOOL LLSidepanelTaskInfo::postBuild()
mDAEditCost = getChild<LLUICtrl>("Edit Cost");
mDALabelClickAction = getChildView("label click action");
mDAComboClickAction = getChild<LLComboBox>("clickaction");
+ mDAPathfindingAttributes = getChild<LLTextBase>("pathfinding_attributes_value");
mDAB = getChildView("B:");
mDAO = getChildView("O:");
mDAG = getChildView("G:");
@@ -242,6 +248,9 @@ void LLSidepanelTaskInfo::disableAll()
mDAComboClickAction->clear();
}
+ mDAPathfindingAttributes->setEnabled(FALSE);
+ mDAPathfindingAttributes->setValue(LLStringUtil::null);
+
mDAB->setVisible(FALSE);
mDAO->setVisible(FALSE);
mDAG->setVisible(FALSE);
@@ -256,7 +265,7 @@ void LLSidepanelTaskInfo::disableAll()
void LLSidepanelTaskInfo::refresh()
{
- LLButton* btn_deed_to_group = getChild<LLButton>("button deed");
+ LLButton* btn_deed_to_group = mDeedBtn;
if (btn_deed_to_group)
{
std::string deedText;
@@ -301,6 +310,8 @@ void LLSidepanelTaskInfo::refresh()
// BUG: fails if a root and non-root are both single-selected.
const BOOL is_perm_modify = (mObjectSelection->getFirstRootNode() && LLSelectMgr::getInstance()->selectGetRootsModify()) ||
LLSelectMgr::getInstance()->selectGetModify();
+ const BOOL is_nonpermanent_enforced = (mObjectSelection->getFirstRootNode() && LLSelectMgr::getInstance()->selectGetRootsNonPermanentEnforced()) ||
+ LLSelectMgr::getInstance()->selectGetNonPermanentEnforced();
S32 string_index = 0;
std::string MODIFY_INFO_STRINGS[] =
@@ -308,12 +319,18 @@ void LLSidepanelTaskInfo::refresh()
getString("text modify info 1"),
getString("text modify info 2"),
getString("text modify info 3"),
- getString("text modify info 4")
+ getString("text modify info 4"),
+ getString("text modify info 5"),
+ getString("text modify info 6")
};
if (!is_perm_modify)
{
string_index += 2;
}
+ else if (!is_nonpermanent_enforced)
+ {
+ string_index += 4;
+ }
if (!is_one_object)
{
++string_index;
@@ -321,14 +338,40 @@ void LLSidepanelTaskInfo::refresh()
getChildView("perm_modify")->setEnabled(TRUE);
getChild<LLUICtrl>("perm_modify")->setValue(MODIFY_INFO_STRINGS[string_index]);
+ std::string pfAttrName;
+
+ if ((mObjectSelection->getFirstRootNode()
+ && LLSelectMgr::getInstance()->selectGetRootsNonPathfinding())
+ || LLSelectMgr::getInstance()->selectGetNonPathfinding())
+ {
+ pfAttrName = "Pathfinding_Object_Attr_None";
+ }
+ else if ((mObjectSelection->getFirstRootNode()
+ && LLSelectMgr::getInstance()->selectGetRootsPermanent())
+ || LLSelectMgr::getInstance()->selectGetPermanent())
+ {
+ pfAttrName = "Pathfinding_Object_Attr_Permanent";
+ }
+ else if ((mObjectSelection->getFirstRootNode()
+ && LLSelectMgr::getInstance()->selectGetRootsCharacter())
+ || LLSelectMgr::getInstance()->selectGetCharacter())
+ {
+ pfAttrName = "Pathfinding_Object_Attr_Character";
+ }
+ else
+ {
+ pfAttrName = "Pathfinding_Object_Attr_MultiSelect";
+ }
+
+ mDAPathfindingAttributes->setEnabled(TRUE);
+ mDAPathfindingAttributes->setValue(LLTrans::getString(pfAttrName));
+
getChildView("Permissions:")->setEnabled(TRUE);
// Update creator text field
getChildView("Creator:")->setEnabled(TRUE);
- BOOL creators_identical;
std::string creator_name;
- creators_identical = LLSelectMgr::getInstance()->selectGetCreator(mCreatorID,
- creator_name);
+ LLSelectMgr::getInstance()->selectGetCreator(mCreatorID, creator_name);
getChild<LLUICtrl>("Creator Name")->setValue(creator_name);
getChildView("Creator Name")->setEnabled(TRUE);
@@ -385,7 +428,7 @@ void LLSidepanelTaskInfo::refresh()
}
}
- getChildView("button set group")->setEnabled(owners_identical && (mOwnerID == gAgent.getID()));
+ getChildView("button set group")->setEnabled(owners_identical && (mOwnerID == gAgent.getID()) && is_nonpermanent_enforced);
getChildView("Name:")->setEnabled(TRUE);
LLLineEditor* LineEditorObjectName = getChild<LLLineEditor>("Object Name");
@@ -415,7 +458,7 @@ void LLSidepanelTaskInfo::refresh()
// figure out the contents of the name, description, & category
BOOL edit_name_desc = FALSE;
- if (is_one_object && objectp->permModify())
+ if (is_one_object && objectp->permModify() && !objectp->isPermanentEnforced())
{
edit_name_desc = TRUE;
}
@@ -595,12 +638,12 @@ void LLSidepanelTaskInfo::refresh()
BOOL has_change_perm_ability = FALSE;
BOOL has_change_sale_ability = FALSE;
- if (valid_base_perms &&
+ if (valid_base_perms && is_nonpermanent_enforced &&
(self_owned || (group_owned && gAgent.hasPowerInGroup(group_id, GP_OBJECT_MANIPULATE))))
{
has_change_perm_ability = TRUE;
}
- if (valid_base_perms &&
+ if (valid_base_perms && is_nonpermanent_enforced &&
(self_owned || (group_owned && gAgent.hasPowerInGroup(group_id, GP_OBJECT_SET_SALE))))
{
has_change_sale_ability = TRUE;
@@ -812,8 +855,8 @@ void LLSidepanelTaskInfo::refresh()
ComboClickAction->setCurrentByIndex((S32)click_action);
}
}
- getChildView("label click action")->setEnabled(is_perm_modify && all_volume);
- getChildView("clickaction")->setEnabled(is_perm_modify && all_volume);
+ getChildView("label click action")->setEnabled(is_perm_modify && is_nonpermanent_enforced && all_volume);
+ getChildView("clickaction")->setEnabled(is_perm_modify && is_nonpermanent_enforced && all_volume);
if (!getIsEditing())
{
@@ -1114,8 +1157,6 @@ void LLSidepanelTaskInfo::doClickAction(U8 click_action)
// Set click action back to its old value
U8 click_action = 0;
LLSelectMgr::getInstance()->selectionGetClickAction(&click_action);
-// box->setCurrentByIndex((S32)click_action);
-
return;
}
}
@@ -1129,6 +1170,10 @@ void LLSidepanelTaskInfo::doClickAction(U8 click_action)
// Warn, but do it anyway.
LLNotificationsUtil::add("ClickActionNotPayable");
}
+ else
+ {
+ handle_give_money_dialog();
+ }
}
LLSelectMgr::getInstance()->selectionSetClickAction(click_action);
}
diff --git a/indra/newview/llsidepaneltaskinfo.h b/indra/newview/llsidepaneltaskinfo.h
index be0fee2127..05edcda5ed 100644..100755
--- a/indra/newview/llsidepaneltaskinfo.h
+++ b/indra/newview/llsidepaneltaskinfo.h
@@ -41,6 +41,7 @@ class LLCheckBoxCtrl;
class LLComboBox;
class LLNameBox;
class LLViewerObject;
+class LLTextBase;
class LLSidepanelTaskInfo : public LLSidepanelInventorySubpanel
{
@@ -112,6 +113,7 @@ private:
LLButton* mPayBtn;
LLButton* mBuyBtn;
LLButton* mDetailsBtn;
+ LLButton* mDeedBtn;
protected:
LLViewerObject* getObject();
@@ -150,6 +152,7 @@ private:
LLUICtrl* mDAEditCost;
LLView* mDALabelClickAction;
LLComboBox* mDAComboClickAction;
+ LLTextBase* mDAPathfindingAttributes;
LLView* mDAB;
LLView* mDAO;
LLView* mDAG;
diff --git a/indra/newview/llsidetraypanelcontainer.cpp b/indra/newview/llsidetraypanelcontainer.cpp
index e340333c2c..e340333c2c 100644..100755
--- a/indra/newview/llsidetraypanelcontainer.cpp
+++ b/indra/newview/llsidetraypanelcontainer.cpp
diff --git a/indra/newview/llsidetraypanelcontainer.h b/indra/newview/llsidetraypanelcontainer.h
index 93a85ed374..93a85ed374 100644..100755
--- a/indra/newview/llsidetraypanelcontainer.h
+++ b/indra/newview/llsidetraypanelcontainer.h
diff --git a/indra/newview/llsimplestat.h b/indra/newview/llsimplestat.h
index 9d7780c4f9..9d7780c4f9 100644..100755
--- a/indra/newview/llsimplestat.h
+++ b/indra/newview/llsimplestat.h
diff --git a/indra/newview/llsky.cpp b/indra/newview/llsky.cpp
index a961f0e3b4..a961f0e3b4 100644..100755
--- a/indra/newview/llsky.cpp
+++ b/indra/newview/llsky.cpp
diff --git a/indra/newview/llsky.h b/indra/newview/llsky.h
index 7b98c97840..7b98c97840 100644..100755
--- a/indra/newview/llsky.h
+++ b/indra/newview/llsky.h
diff --git a/indra/newview/llslurl.cpp b/indra/newview/llslurl.cpp
index a853726dea..3a82233320 100644..100755
--- a/indra/newview/llslurl.cpp
+++ b/indra/newview/llslurl.cpp
@@ -56,14 +56,13 @@ LLSLURL::LLSLURL(const std::string& slurl)
{
// by default we go to agni.
mType = INVALID;
- LL_INFOS("AppInit") << "SLURL: " << slurl << LL_ENDL;
+
if(slurl == SIM_LOCATION_HOME)
{
mType = HOME_LOCATION;
}
else if(slurl.empty() || (slurl == SIM_LOCATION_LAST))
{
-
mType = LAST_LOCATION;
}
else
@@ -80,6 +79,7 @@ LLSLURL::LLSLURL(const std::string& slurl)
// these slurls are typically passed in from the 'starting location' box on the login panel,
// where the user can type in <regionname>/<x>/<y>/<z>
std::string fixed_slurl = LLGridManager::getInstance()->getSLURLBase();
+
// the slurl that was passed in might have a prepended /, or not. So,
// we strip off the prepended '/' so we don't end up with http://slurl.com/secondlife/<region>/<x>/<y>/<z>
// or some such.
@@ -138,7 +138,7 @@ LLSLURL::LLSLURL(const std::string& slurl)
// so parse the grid name to derive the grid ID
if (!slurl_uri.hostName().empty())
{
- mGrid = LLGridManager::getInstance()->getGridByLabel(slurl_uri.hostName());
+ mGrid = LLGridManager::getInstance()->getGridId(slurl_uri.hostName());
}
else if(path_array[0].asString() == LLSLURL::SLURL_SECONDLIFE_PATH)
{
@@ -150,12 +150,13 @@ LLSLURL::LLSLURL(const std::string& slurl)
{
// for app style slurls, where no grid name is specified, assume the currently
// selected or logged in grid.
- mGrid = LLGridManager::getInstance()->getGrid();
+ mGrid = LLGridManager::getInstance()->getGridId();
}
if(mGrid.empty())
{
// we couldn't find the grid in the grid manager, so bail
+ LL_WARNS("AppInit")<<"unable to find grid"<<LL_ENDL;
return;
}
// set the type as appropriate.
@@ -334,7 +335,7 @@ LLSLURL::LLSLURL(const std::string& grid,
LLSLURL::LLSLURL(const std::string& region,
const LLVector3& position)
{
- *this = LLSLURL(LLGridManager::getInstance()->getGrid(),
+ *this = LLSLURL(LLGridManager::getInstance()->getGridId(),
region, position);
}
@@ -343,7 +344,7 @@ LLSLURL::LLSLURL(const std::string& grid,
const std::string& region,
const LLVector3d& global_position)
{
- *this = LLSLURL(grid,
+ *this = LLSLURL(LLGridManager::getInstance()->getGridId(grid),
region, LLVector3(global_position.mdV[VX],
global_position.mdV[VY],
global_position.mdV[VZ]));
@@ -353,7 +354,7 @@ LLSLURL::LLSLURL(const std::string& grid,
LLSLURL::LLSLURL(const std::string& region,
const LLVector3d& global_position)
{
- *this = LLSLURL(LLGridManager::getInstance()->getGrid(),
+ *this = LLSLURL(LLGridManager::getInstance()->getGridId(),
region, global_position);
}
@@ -426,7 +427,7 @@ std::string LLSLURL::getLoginString() const
unescaped_start << "last";
break;
default:
- LL_WARNS("AppInit") << "Unexpected SLURL type for login string" << (int)mType << LL_ENDL;
+ LL_WARNS("AppInit") << "Unexpected SLURL type ("<<(int)mType <<")for login string"<< LL_ENDL;
break;
}
return xml_escape_string(unescaped_start.str());
@@ -465,18 +466,47 @@ std::string LLSLURL::getLocationString() const
(int)llround(mPosition[1]),
(int)llround(mPosition[2]));
}
+
+// static
+const std::string LLSLURL::typeName[NUM_SLURL_TYPES] =
+{
+ "INVALID",
+ "LOCATION",
+ "HOME_LOCATION",
+ "LAST_LOCATION",
+ "APP",
+ "HELP"
+};
+
+std::string LLSLURL::getTypeString(SLURL_TYPE type)
+{
+ std::string name;
+ if ( type >= INVALID && type < NUM_SLURL_TYPES )
+ {
+ name = LLSLURL::typeName[type];
+ }
+ else
+ {
+ name = llformat("Out of Range (%d)",type);
+ }
+ return name;
+}
+
+
std::string LLSLURL::asString() const
{
std::ostringstream result;
- result << " mAppCmd:" << getAppCmd() <<
- " mAppPath:" + getAppPath().asString() <<
- " mAppQueryMap:" + getAppQueryMap().asString() <<
- " mAppQuery: " + getAppQuery() <<
- " mGrid: " + getGrid() <<
- " mRegion: " + getRegion() <<
- " mPosition: " <<
- " mType: " << mType <<
- " mPosition: " << mPosition;
+ result
+ << " mType: " << LLSLURL::getTypeString(mType)
+ << " mGrid: " + getGrid()
+ << " mRegion: " + getRegion()
+ << " mPosition: " << mPosition
+ << " mAppCmd:" << getAppCmd()
+ << " mAppPath:" + getAppPath().asString()
+ << " mAppQueryMap:" + getAppQueryMap().asString()
+ << " mAppQuery: " + getAppQuery()
+ ;
+
return result.str();
}
diff --git a/indra/newview/llslurl.h b/indra/newview/llslurl.h
index 1a3f0543dd..b86cf7949b 100644..100755
--- a/indra/newview/llslurl.h
+++ b/indra/newview/llslurl.h
@@ -51,13 +51,15 @@ public:
static const char* SLURL_APP_PATH;
static const char* SLURL_REGION_PATH;
+ // if you modify this enumeration, update typeName as well
enum SLURL_TYPE {
INVALID,
LOCATION,
HOME_LOCATION,
LAST_LOCATION,
APP,
- HELP
+ HELP,
+ NUM_SLURL_TYPES // must be last
};
@@ -92,6 +94,10 @@ public:
std::string asString() const ;
protected:
+ static const std::string typeName[NUM_SLURL_TYPES];
+ /// Get a human-readable version of the type for logging
+ static std::string getTypeString(SLURL_TYPE type);
+
SLURL_TYPE mType;
// used for Apps and Help
diff --git a/indra/newview/llsnapshotlivepreview.cpp b/indra/newview/llsnapshotlivepreview.cpp
new file mode 100644
index 0000000000..7532ebfc57
--- /dev/null
+++ b/indra/newview/llsnapshotlivepreview.cpp
@@ -0,0 +1,874 @@
+/**
+* @file llsnapshotlivepreview.cpp
+* @brief Implementation of llsnapshotlivepreview
+* @author Gilbert@lindenlab.com
+*
+* $LicenseInfo:firstyear=2013&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2013, 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 "llagent.h"
+#include "llagentcamera.h"
+#include "llagentui.h"
+#include "llcombobox.h"
+#include "lleconomy.h"
+#include "llfloaterperms.h"
+#include "llfloaterreg.h"
+#include "llfloatersocial.h"
+#include "llimagebmp.h"
+#include "llimagej2c.h"
+#include "llimagejpeg.h"
+#include "llimagepng.h"
+#include "lllandmarkactions.h"
+#include "lllocalcliprect.h"
+#include "llnotificationsutil.h"
+#include "llslurl.h"
+#include "llsnapshotlivepreview.h"
+#include "lltoolfocus.h"
+#include "llviewercontrol.h"
+#include "llviewermenufile.h" // upload_new_resource()
+#include "llviewerstats.h"
+#include "llvfile.h"
+#include "llvfs.h"
+#include "llwebsharing.h"
+#include "llwindow.h"
+#include "llworld.h"
+
+const F32 AUTO_SNAPSHOT_TIME_DELAY = 1.f;
+
+F32 SHINE_TIME = 0.5f;
+F32 SHINE_WIDTH = 0.6f;
+F32 SHINE_OPACITY = 0.3f;
+F32 FALL_TIME = 0.6f;
+S32 BORDER_WIDTH = 6;
+
+const S32 MAX_TEXTURE_SIZE = 512 ; //max upload texture size 512 * 512
+
+std::set<LLSnapshotLivePreview*> LLSnapshotLivePreview::sList;
+
+LLSnapshotLivePreview::LLSnapshotLivePreview (const LLSnapshotLivePreview::Params& p)
+ : LLView(p),
+ mColor(1.f, 0.f, 0.f, 0.5f),
+ mCurImageIndex(0),
+ mPreviewImage(NULL),
+ mThumbnailImage(NULL) ,
+ mThumbnailWidth(0),
+ mThumbnailHeight(0),
+ mPreviewImageEncoded(NULL),
+ mFormattedImage(NULL),
+ mShineCountdown(0),
+ mFlashAlpha(0.f),
+ mNeedsFlash(TRUE),
+ mSnapshotQuality(gSavedSettings.getS32("SnapshotQuality")),
+ mDataSize(0),
+ mSnapshotType(SNAPSHOT_POSTCARD),
+ mSnapshotFormat(LLFloaterSnapshot::ESnapshotFormat(gSavedSettings.getS32("SnapshotFormat"))),
+ mSnapshotUpToDate(FALSE),
+ mCameraPos(LLViewerCamera::getInstance()->getOrigin()),
+ mCameraRot(LLViewerCamera::getInstance()->getQuaternion()),
+ mSnapshotActive(FALSE),
+ mSnapshotBufferType(LLViewerWindow::SNAPSHOT_TYPE_COLOR)
+{
+ setSnapshotQuality(gSavedSettings.getS32("SnapshotQuality"));
+ mSnapshotDelayTimer.setTimerExpirySec(0.0f);
+ mSnapshotDelayTimer.start();
+ // gIdleCallbacks.addFunction( &LLSnapshotLivePreview::onIdle, (void*)this );
+ sList.insert(this);
+ setFollowsAll();
+ mWidth[0] = gViewerWindow->getWindowWidthRaw();
+ mWidth[1] = gViewerWindow->getWindowWidthRaw();
+ mHeight[0] = gViewerWindow->getWindowHeightRaw();
+ mHeight[1] = gViewerWindow->getWindowHeightRaw();
+ mImageScaled[0] = FALSE;
+ mImageScaled[1] = FALSE;
+
+ mMaxImageSize = MAX_SNAPSHOT_IMAGE_SIZE ;
+ mKeepAspectRatio = gSavedSettings.getBOOL("KeepAspectForSnapshot") ;
+ mThumbnailUpdateLock = FALSE ;
+ mThumbnailUpToDate = FALSE ;
+}
+
+LLSnapshotLivePreview::~LLSnapshotLivePreview()
+{
+ // delete images
+ mPreviewImage = NULL;
+ mPreviewImageEncoded = NULL;
+ mFormattedImage = NULL;
+
+ // gIdleCallbacks.deleteFunction( &LLSnapshotLivePreview::onIdle, (void*)this );
+ sList.erase(this);
+}
+
+void LLSnapshotLivePreview::setMaxImageSize(S32 size)
+{
+ if(size < MAX_SNAPSHOT_IMAGE_SIZE)
+ {
+ mMaxImageSize = size;
+ }
+ else
+ {
+ mMaxImageSize = MAX_SNAPSHOT_IMAGE_SIZE ;
+ }
+}
+
+LLViewerTexture* LLSnapshotLivePreview::getCurrentImage()
+{
+ return mViewerImage[mCurImageIndex];
+}
+
+F32 LLSnapshotLivePreview::getAspect()
+{
+ F32 image_aspect_ratio = ((F32)getWidth()) / ((F32)getHeight());
+ F32 window_aspect_ratio = ((F32)getRect().getWidth()) / ((F32)getRect().getHeight());
+
+ if (!mKeepAspectRatio)//gSavedSettings.getBOOL("KeepAspectForSnapshot"))
+ {
+ return image_aspect_ratio;
+ }
+ else
+ {
+ return window_aspect_ratio;
+ }
+}
+
+F32 LLSnapshotLivePreview::getImageAspect()
+{
+ if (!getCurrentImage())
+ {
+ return 0.f;
+ }
+
+ return getAspect() ;
+}
+
+void LLSnapshotLivePreview::updateSnapshot(BOOL new_snapshot, BOOL new_thumbnail, F32 delay)
+{
+ // Invalidate current image.
+ lldebugs << "updateSnapshot: mSnapshotUpToDate = " << getSnapshotUpToDate() << llendl;
+ if (getSnapshotUpToDate())
+ {
+ S32 old_image_index = mCurImageIndex;
+ mCurImageIndex = (mCurImageIndex + 1) % 2;
+ setSize(mWidth[old_image_index], mHeight[old_image_index]);
+ mFallAnimTimer.start();
+ }
+ mSnapshotUpToDate = FALSE;
+
+ // Update snapshot source rect depending on whether we keep the aspect ratio.
+ LLRect& rect = mImageRect[mCurImageIndex];
+ rect.set(0, getRect().getHeight(), getRect().getWidth(), 0);
+
+ F32 image_aspect_ratio = ((F32)getWidth()) / ((F32)getHeight());
+ F32 window_aspect_ratio = ((F32)getRect().getWidth()) / ((F32)getRect().getHeight());
+
+ if (mKeepAspectRatio)//gSavedSettings.getBOOL("KeepAspectForSnapshot"))
+ {
+ if (image_aspect_ratio > window_aspect_ratio)
+ {
+ // trim off top and bottom
+ S32 new_height = llround((F32)getRect().getWidth() / image_aspect_ratio);
+ rect.mBottom += (getRect().getHeight() - new_height) / 2;
+ rect.mTop -= (getRect().getHeight() - new_height) / 2;
+ }
+ else if (image_aspect_ratio < window_aspect_ratio)
+ {
+ // trim off left and right
+ S32 new_width = llround((F32)getRect().getHeight() * image_aspect_ratio);
+ rect.mLeft += (getRect().getWidth() - new_width) / 2;
+ rect.mRight -= (getRect().getWidth() - new_width) / 2;
+ }
+ }
+
+ // Stop shining animation.
+ mShineAnimTimer.stop();
+
+ // Update snapshot if requested.
+ if (new_snapshot)
+ {
+ mSnapshotDelayTimer.start();
+ mSnapshotDelayTimer.setTimerExpirySec(delay);
+ LLFloaterSnapshot::preUpdate();
+ LLFloaterSocial::preUpdate();
+ }
+
+ // Update thumbnail if requested.
+ if(new_thumbnail)
+ {
+ mThumbnailUpToDate = FALSE ;
+ }
+}
+
+void LLSnapshotLivePreview::setSnapshotQuality(S32 quality)
+{
+ llclamp(quality, 0, 100);
+ if (quality != mSnapshotQuality)
+ {
+ mSnapshotQuality = quality;
+ gSavedSettings.setS32("SnapshotQuality", quality);
+ mSnapshotUpToDate = FALSE;
+ }
+}
+
+void LLSnapshotLivePreview::drawPreviewRect(S32 offset_x, S32 offset_y)
+{
+ F32 line_width ;
+ glGetFloatv(GL_LINE_WIDTH, &line_width) ;
+ glLineWidth(2.0f * line_width) ;
+ LLColor4 color(0.0f, 0.0f, 0.0f, 1.0f) ;
+ gl_rect_2d( mPreviewRect.mLeft + offset_x, mPreviewRect.mTop + offset_y,
+ mPreviewRect.mRight + offset_x, mPreviewRect.mBottom + offset_y, color, FALSE ) ;
+ glLineWidth(line_width) ;
+
+ //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())
+ {
+ dwl = (mThumbnailWidth - mPreviewRect.getWidth()) >> 1 ;
+ dwr = mThumbnailWidth - mPreviewRect.getWidth() - dwl ;
+
+ gl_rect_2d(mPreviewRect.mLeft + offset_x - dwl, mPreviewRect.mTop + offset_y,
+ mPreviewRect.mLeft + offset_x, mPreviewRect.mBottom + offset_y, alpha_color, TRUE ) ;
+ gl_rect_2d( mPreviewRect.mRight + offset_x, mPreviewRect.mTop + offset_y,
+ mPreviewRect.mRight + offset_x + dwr, mPreviewRect.mBottom + offset_y, alpha_color, TRUE ) ;
+ }
+
+ if(mThumbnailHeight > mPreviewRect.getHeight())
+ {
+ S32 dh = (mThumbnailHeight - mPreviewRect.getHeight()) >> 1 ;
+ gl_rect_2d(mPreviewRect.mLeft + offset_x - dwl, mPreviewRect.mBottom + offset_y ,
+ mPreviewRect.mRight + offset_x + dwr, mPreviewRect.mBottom + offset_y - dh, alpha_color, TRUE ) ;
+
+ dh = mThumbnailHeight - mPreviewRect.getHeight() - dh ;
+ gl_rect_2d( mPreviewRect.mLeft + offset_x - dwl, mPreviewRect.mTop + offset_y + dh,
+ mPreviewRect.mRight + offset_x + dwr, mPreviewRect.mTop + offset_y, alpha_color, TRUE ) ;
+ }
+ }
+}
+
+//called when the frame is frozen.
+void LLSnapshotLivePreview::draw()
+{
+ if (getCurrentImage() &&
+ mPreviewImageEncoded.notNull() &&
+ getSnapshotUpToDate())
+ {
+ LLColor4 bg_color(0.f, 0.f, 0.3f, 0.4f);
+ gl_rect_2d(getRect(), bg_color);
+ const LLRect& rect = getImageRect();
+ LLRect shadow_rect = rect;
+ shadow_rect.stretch(BORDER_WIDTH);
+ gl_drop_shadow(shadow_rect.mLeft, shadow_rect.mTop, shadow_rect.mRight, shadow_rect.mBottom, LLColor4(0.f, 0.f, 0.f, mNeedsFlash ? 0.f :0.5f), 10);
+
+ LLColor4 image_color(1.f, 1.f, 1.f, 1.f);
+ gGL.color4fv(image_color.mV);
+ gGL.getTexUnit(0)->bind(getCurrentImage());
+ // calculate UV scale
+ F32 uv_width = isImageScaled() ? 1.f : llmin((F32)getWidth() / (F32)getCurrentImage()->getWidth(), 1.f);
+ F32 uv_height = isImageScaled() ? 1.f : llmin((F32)getHeight() / (F32)getCurrentImage()->getHeight(), 1.f);
+ gGL.pushMatrix();
+ {
+ gGL.translatef((F32)rect.mLeft, (F32)rect.mBottom, 0.f);
+ gGL.begin(LLRender::QUADS);
+ {
+ gGL.texCoord2f(uv_width, uv_height);
+ gGL.vertex2i(rect.getWidth(), rect.getHeight() );
+
+ gGL.texCoord2f(0.f, uv_height);
+ gGL.vertex2i(0, rect.getHeight() );
+
+ gGL.texCoord2f(0.f, 0.f);
+ gGL.vertex2i(0, 0);
+
+ gGL.texCoord2f(uv_width, 0.f);
+ gGL.vertex2i(rect.getWidth(), 0);
+ }
+ gGL.end();
+ }
+ gGL.popMatrix();
+
+ gGL.color4f(1.f, 1.f, 1.f, mFlashAlpha);
+ gl_rect_2d(getRect());
+ if (mNeedsFlash)
+ {
+ if (mFlashAlpha < 1.f)
+ {
+ mFlashAlpha = lerp(mFlashAlpha, 1.f, LLCriticalDamp::getInterpolant(0.02f));
+ }
+ else
+ {
+ mNeedsFlash = FALSE;
+ }
+ }
+ else
+ {
+ mFlashAlpha = lerp(mFlashAlpha, 0.f, LLCriticalDamp::getInterpolant(0.15f));
+ }
+
+ // Draw shining animation if appropriate.
+ if (mShineCountdown > 0)
+ {
+ mShineCountdown--;
+ if (mShineCountdown == 0)
+ {
+ mShineAnimTimer.start();
+ }
+ }
+ else if (mShineAnimTimer.getStarted())
+ {
+ lldebugs << "Drawing shining animation" << llendl;
+ F32 shine_interp = llmin(1.f, mShineAnimTimer.getElapsedTimeF32() / SHINE_TIME);
+
+ // draw "shine" effect
+ LLLocalClipRect clip(getLocalRect());
+ {
+ // draw diagonal stripe with gradient that passes over screen
+ S32 x1 = gViewerWindow->getWindowWidthScaled() * llround((clamp_rescale(shine_interp, 0.f, 1.f, -1.f - SHINE_WIDTH, 1.f)));
+ S32 x2 = x1 + llround(gViewerWindow->getWindowWidthScaled() * SHINE_WIDTH);
+ S32 x3 = x2 + llround(gViewerWindow->getWindowWidthScaled() * SHINE_WIDTH);
+ S32 y1 = 0;
+ S32 y2 = gViewerWindow->getWindowHeightScaled();
+
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.begin(LLRender::QUADS);
+ {
+ gGL.color4f(1.f, 1.f, 1.f, 0.f);
+ gGL.vertex2i(x1, y1);
+ gGL.vertex2i(x1 + gViewerWindow->getWindowWidthScaled(), y2);
+ gGL.color4f(1.f, 1.f, 1.f, SHINE_OPACITY);
+ gGL.vertex2i(x2 + gViewerWindow->getWindowWidthScaled(), y2);
+ gGL.vertex2i(x2, y1);
+
+ gGL.color4f(1.f, 1.f, 1.f, SHINE_OPACITY);
+ gGL.vertex2i(x2, y1);
+ gGL.vertex2i(x2 + gViewerWindow->getWindowWidthScaled(), y2);
+ gGL.color4f(1.f, 1.f, 1.f, 0.f);
+ gGL.vertex2i(x3 + gViewerWindow->getWindowWidthScaled(), y2);
+ gGL.vertex2i(x3, y1);
+ }
+ gGL.end();
+ }
+
+ // if we're at the end of the animation, stop
+ if (shine_interp >= 1.f)
+ {
+ mShineAnimTimer.stop();
+ }
+ }
+ }
+
+ // draw framing rectangle
+ {
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.color4f(1.f, 1.f, 1.f, 1.f);
+ const LLRect& outline_rect = getImageRect();
+ gGL.begin(LLRender::QUADS);
+ {
+ gGL.vertex2i(outline_rect.mLeft - BORDER_WIDTH, outline_rect.mTop + BORDER_WIDTH);
+ gGL.vertex2i(outline_rect.mRight + BORDER_WIDTH, outline_rect.mTop + BORDER_WIDTH);
+ gGL.vertex2i(outline_rect.mRight, outline_rect.mTop);
+ gGL.vertex2i(outline_rect.mLeft, outline_rect.mTop);
+
+ gGL.vertex2i(outline_rect.mLeft, outline_rect.mBottom);
+ gGL.vertex2i(outline_rect.mRight, outline_rect.mBottom);
+ gGL.vertex2i(outline_rect.mRight + BORDER_WIDTH, outline_rect.mBottom - BORDER_WIDTH);
+ gGL.vertex2i(outline_rect.mLeft - BORDER_WIDTH, outline_rect.mBottom - BORDER_WIDTH);
+
+ gGL.vertex2i(outline_rect.mLeft, outline_rect.mTop);
+ gGL.vertex2i(outline_rect.mLeft, outline_rect.mBottom);
+ gGL.vertex2i(outline_rect.mLeft - BORDER_WIDTH, outline_rect.mBottom - BORDER_WIDTH);
+ gGL.vertex2i(outline_rect.mLeft - BORDER_WIDTH, outline_rect.mTop + BORDER_WIDTH);
+
+ gGL.vertex2i(outline_rect.mRight, outline_rect.mBottom);
+ gGL.vertex2i(outline_rect.mRight, outline_rect.mTop);
+ gGL.vertex2i(outline_rect.mRight + BORDER_WIDTH, outline_rect.mTop + BORDER_WIDTH);
+ gGL.vertex2i(outline_rect.mRight + BORDER_WIDTH, outline_rect.mBottom - BORDER_WIDTH);
+ }
+ gGL.end();
+ }
+
+ // draw old image dropping away
+ if (mFallAnimTimer.getStarted())
+ {
+ S32 old_image_index = (mCurImageIndex + 1) % 2;
+ if (mViewerImage[old_image_index].notNull() && mFallAnimTimer.getElapsedTimeF32() < FALL_TIME)
+ {
+ lldebugs << "Drawing fall animation" << llendl;
+ F32 fall_interp = mFallAnimTimer.getElapsedTimeF32() / FALL_TIME;
+ F32 alpha = clamp_rescale(fall_interp, 0.f, 1.f, 0.8f, 0.4f);
+ LLColor4 image_color(1.f, 1.f, 1.f, alpha);
+ gGL.color4fv(image_color.mV);
+ gGL.getTexUnit(0)->bind(mViewerImage[old_image_index]);
+ // calculate UV scale
+ // *FIX get this to work with old image
+ BOOL rescale = !mImageScaled[old_image_index] && mViewerImage[mCurImageIndex].notNull();
+ F32 uv_width = rescale ? llmin((F32)mWidth[old_image_index] / (F32)mViewerImage[mCurImageIndex]->getWidth(), 1.f) : 1.f;
+ F32 uv_height = rescale ? llmin((F32)mHeight[old_image_index] / (F32)mViewerImage[mCurImageIndex]->getHeight(), 1.f) : 1.f;
+ gGL.pushMatrix();
+ {
+ LLRect& rect = mImageRect[old_image_index];
+ gGL.translatef((F32)rect.mLeft, (F32)rect.mBottom - llround(getRect().getHeight() * 2.f * (fall_interp * fall_interp)), 0.f);
+ gGL.rotatef(-45.f * fall_interp, 0.f, 0.f, 1.f);
+ gGL.begin(LLRender::QUADS);
+ {
+ gGL.texCoord2f(uv_width, uv_height);
+ gGL.vertex2i(rect.getWidth(), rect.getHeight() );
+
+ gGL.texCoord2f(0.f, uv_height);
+ gGL.vertex2i(0, rect.getHeight() );
+
+ gGL.texCoord2f(0.f, 0.f);
+ gGL.vertex2i(0, 0);
+
+ gGL.texCoord2f(uv_width, 0.f);
+ gGL.vertex2i(rect.getWidth(), 0);
+ }
+ gGL.end();
+ }
+ gGL.popMatrix();
+ }
+ }
+}
+
+/*virtual*/
+void LLSnapshotLivePreview::reshape(S32 width, S32 height, BOOL called_from_parent)
+{
+ LLRect old_rect = getRect();
+ LLView::reshape(width, height, called_from_parent);
+ if (old_rect.getWidth() != width || old_rect.getHeight() != height)
+ {
+ lldebugs << "window reshaped, updating thumbnail" << llendl;
+ updateSnapshot(FALSE, TRUE);
+ }
+}
+
+BOOL LLSnapshotLivePreview::setThumbnailImageSize()
+{
+ if(getWidth() < 10 || getHeight() < 10)
+ {
+ return FALSE ;
+ }
+ S32 window_width = gViewerWindow->getWindowWidthRaw() ;
+ S32 window_height = gViewerWindow->getWindowHeightRaw() ;
+
+ F32 window_aspect_ratio = ((F32)window_width) / ((F32)window_height);
+
+ // UI size for thumbnail
+ // *FIXME: the rect does not change, so maybe there's no need to recalculate max w/h.
+ const LLRect& thumbnail_rect = mThumbnailPlaceholderRect;
+ S32 max_width = thumbnail_rect.getWidth();
+ S32 max_height = thumbnail_rect.getHeight();
+
+ if (window_aspect_ratio > (F32)max_width / max_height)
+ {
+ // image too wide, shrink to width
+ mThumbnailWidth = max_width;
+ mThumbnailHeight = llround((F32)max_width / window_aspect_ratio);
+ }
+ else
+ {
+ // image too tall, shrink to height
+ mThumbnailHeight = max_height;
+ mThumbnailWidth = llround((F32)max_height * window_aspect_ratio);
+ }
+
+ if(mThumbnailWidth > window_width || mThumbnailHeight > window_height)
+ {
+ return FALSE ;//if the window is too small, ignore thumbnail updating.
+ }
+
+ S32 left = 0 , top = mThumbnailHeight, right = mThumbnailWidth, bottom = 0 ;
+ if(!mKeepAspectRatio)
+ {
+ F32 ratio_x = (F32)getWidth() / window_width ;
+ F32 ratio_y = (F32)getHeight() / window_height ;
+
+ //if(getWidth() > window_width ||
+ // getHeight() > window_height )
+ {
+ if(ratio_x > ratio_y)
+ {
+ top = (S32)(top * ratio_y / ratio_x) ;
+ }
+ else
+ {
+ right = (S32)(right * ratio_x / ratio_y) ;
+ }
+ }
+ //else
+ //{
+ // right = (S32)(right * ratio_x) ;
+ // top = (S32)(top * ratio_y) ;
+ //}
+ left = (S32)((mThumbnailWidth - right) * 0.5f) ;
+ bottom = (S32)((mThumbnailHeight - top) * 0.5f) ;
+ top += bottom ;
+ right += left ;
+ }
+ mPreviewRect.set(left - 1, top + 1, right + 1, bottom - 1) ;
+
+ return TRUE ;
+}
+
+void LLSnapshotLivePreview::generateThumbnailImage(BOOL force_update)
+{
+ if(mThumbnailUpdateLock) //in the process of updating
+ {
+ return ;
+ }
+ if(getThumbnailUpToDate() && !force_update)//already updated
+ {
+ return ;
+ }
+ if(getWidth() < 10 || getHeight() < 10)
+ {
+ return ;
+ }
+
+ ////lock updating
+ mThumbnailUpdateLock = TRUE ;
+
+ if(!setThumbnailImageSize())
+ {
+ mThumbnailUpdateLock = FALSE ;
+ mThumbnailUpToDate = TRUE ;
+ return ;
+ }
+
+ if(mThumbnailImage)
+ {
+ resetThumbnailImage() ;
+ }
+
+ LLPointer<LLImageRaw> raw = new LLImageRaw;
+ if(!gViewerWindow->thumbnailSnapshot(raw,
+ mThumbnailWidth, mThumbnailHeight,
+ gSavedSettings.getBOOL("RenderUIInSnapshot"),
+ FALSE,
+ mSnapshotBufferType) )
+ {
+ raw = NULL ;
+ }
+
+ if(raw)
+ {
+ raw->expandToPowerOfTwo();
+ mThumbnailImage = LLViewerTextureManager::getLocalTexture(raw.get(), FALSE);
+ mThumbnailUpToDate = TRUE ;
+ }
+
+ //unlock updating
+ mThumbnailUpdateLock = FALSE ;
+}
+
+
+// Called often. Checks whether it's time to grab a new snapshot and if so, does it.
+// Returns TRUE if new snapshot generated, FALSE otherwise.
+//static
+BOOL LLSnapshotLivePreview::onIdle( void* snapshot_preview )
+{
+ LLSnapshotLivePreview* previewp = (LLSnapshotLivePreview*)snapshot_preview;
+ if (previewp->getWidth() == 0 || previewp->getHeight() == 0)
+ {
+ llwarns << "Incorrect dimensions: " << previewp->getWidth() << "x" << previewp->getHeight() << llendl;
+ return FALSE;
+ }
+
+ // If we're in freeze-frame mode and camera has moved, update snapshot.
+ LLVector3 new_camera_pos = LLViewerCamera::getInstance()->getOrigin();
+ LLQuaternion new_camera_rot = LLViewerCamera::getInstance()->getQuaternion();
+ if (gSavedSettings.getBOOL("FreezeTime") &&
+ (new_camera_pos != previewp->mCameraPos || dot(new_camera_rot, previewp->mCameraRot) < 0.995f))
+ {
+ previewp->mCameraPos = new_camera_pos;
+ previewp->mCameraRot = new_camera_rot;
+ // request a new snapshot whenever the camera moves, with a time delay
+ BOOL autosnap = gSavedSettings.getBOOL("AutoSnapshot");
+ lldebugs << "camera moved, updating thumbnail" << llendl;
+ previewp->updateSnapshot(
+ autosnap, // whether a new snapshot is needed or merely invalidate the existing one
+ FALSE, // or if 1st arg is false, whether to produce a new thumbnail image.
+ autosnap ? AUTO_SNAPSHOT_TIME_DELAY : 0.f); // shutter delay if 1st arg is true.
+ }
+
+ // see if it's time yet to snap the shot and bomb out otherwise.
+ previewp->mSnapshotActive =
+ (previewp->mSnapshotDelayTimer.getStarted() && previewp->mSnapshotDelayTimer.hasExpired())
+ && !LLToolCamera::getInstance()->hasMouseCapture(); // don't take snapshots while ALT-zoom active
+ if ( ! previewp->mSnapshotActive)
+ {
+ return FALSE;
+ }
+
+ // time to produce a snapshot
+ previewp->setThumbnailImageSize();
+
+ lldebugs << "producing snapshot" << llendl;
+ if (!previewp->mPreviewImage)
+ {
+ previewp->mPreviewImage = new LLImageRaw;
+ }
+
+ if (!previewp->mPreviewImageEncoded)
+ {
+ previewp->mPreviewImageEncoded = new LLImageRaw;
+ }
+
+ previewp->setVisible(FALSE);
+ previewp->setEnabled(FALSE);
+
+ previewp->getWindow()->incBusyCount();
+ previewp->setImageScaled(FALSE);
+
+ // grab the raw image and encode it into desired format
+ if(gViewerWindow->rawSnapshot(
+ previewp->mPreviewImage,
+ previewp->getWidth(),
+ previewp->getHeight(),
+ previewp->mKeepAspectRatio,//gSavedSettings.getBOOL("KeepAspectForSnapshot"),
+ previewp->getSnapshotType() == LLSnapshotLivePreview::SNAPSHOT_TEXTURE,
+ gSavedSettings.getBOOL("RenderUIInSnapshot"),
+ FALSE,
+ previewp->mSnapshotBufferType,
+ previewp->getMaxImageSize()))
+ {
+ previewp->mPreviewImageEncoded->resize(
+ previewp->mPreviewImage->getWidth(),
+ previewp->mPreviewImage->getHeight(),
+ previewp->mPreviewImage->getComponents());
+
+ if(previewp->getSnapshotType() == SNAPSHOT_TEXTURE)
+ {
+ lldebugs << "Encoding new image of format J2C" << llendl;
+ LLPointer<LLImageJ2C> formatted = new LLImageJ2C;
+ LLPointer<LLImageRaw> scaled = new LLImageRaw(
+ previewp->mPreviewImage->getData(),
+ previewp->mPreviewImage->getWidth(),
+ previewp->mPreviewImage->getHeight(),
+ previewp->mPreviewImage->getComponents());
+
+ scaled->biasedScaleToPowerOfTwo(MAX_TEXTURE_SIZE);
+ previewp->setImageScaled(TRUE);
+ if (formatted->encode(scaled, 0.f))
+ {
+ previewp->mDataSize = formatted->getDataSize();
+ formatted->decode(previewp->mPreviewImageEncoded, 0);
+ }
+ }
+ else
+ {
+ // delete any existing image
+ previewp->mFormattedImage = NULL;
+ // now create the new one of the appropriate format.
+ LLFloaterSnapshot::ESnapshotFormat format = previewp->getSnapshotFormat();
+ lldebugs << "Encoding new image of format " << format << llendl;
+
+ switch(format)
+ {
+ case LLFloaterSnapshot::SNAPSHOT_FORMAT_PNG:
+ previewp->mFormattedImage = new LLImagePNG();
+ break;
+ case LLFloaterSnapshot::SNAPSHOT_FORMAT_JPEG:
+ previewp->mFormattedImage = new LLImageJPEG(previewp->mSnapshotQuality);
+ break;
+ case LLFloaterSnapshot::SNAPSHOT_FORMAT_BMP:
+ previewp->mFormattedImage = new LLImageBMP();
+ break;
+ }
+ if (previewp->mFormattedImage->encode(previewp->mPreviewImage, 0))
+ {
+ previewp->mDataSize = previewp->mFormattedImage->getDataSize();
+ // special case BMP to copy instead of decode otherwise decode will crash.
+ if(format == LLFloaterSnapshot::SNAPSHOT_FORMAT_BMP)
+ {
+ previewp->mPreviewImageEncoded->copy(previewp->mPreviewImage);
+ }
+ else
+ {
+ previewp->mFormattedImage->decode(previewp->mPreviewImageEncoded, 0);
+ }
+ }
+ }
+
+ LLPointer<LLImageRaw> scaled = new LLImageRaw(
+ previewp->mPreviewImageEncoded->getData(),
+ previewp->mPreviewImageEncoded->getWidth(),
+ previewp->mPreviewImageEncoded->getHeight(),
+ previewp->mPreviewImageEncoded->getComponents());
+
+ if(!scaled->isBufferInvalid())
+ {
+ // leave original image dimensions, just scale up texture buffer
+ if (previewp->mPreviewImageEncoded->getWidth() > 1024 || previewp->mPreviewImageEncoded->getHeight() > 1024)
+ {
+ // go ahead and shrink image to appropriate power of 2 for display
+ scaled->biasedScaleToPowerOfTwo(1024);
+ previewp->setImageScaled(TRUE);
+ }
+ else
+ {
+ // expand image but keep original image data intact
+ scaled->expandToPowerOfTwo(1024, FALSE);
+ }
+
+ previewp->mViewerImage[previewp->mCurImageIndex] = LLViewerTextureManager::getLocalTexture(scaled.get(), FALSE);
+ LLPointer<LLViewerTexture> curr_preview_image = previewp->mViewerImage[previewp->mCurImageIndex];
+ gGL.getTexUnit(0)->bind(curr_preview_image);
+ if (previewp->getSnapshotType() != SNAPSHOT_TEXTURE)
+ {
+ curr_preview_image->setFilteringOption(LLTexUnit::TFO_POINT);
+ }
+ else
+ {
+ curr_preview_image->setFilteringOption(LLTexUnit::TFO_ANISOTROPIC);
+ }
+ curr_preview_image->setAddressMode(LLTexUnit::TAM_CLAMP);
+
+ previewp->mSnapshotUpToDate = TRUE;
+ previewp->generateThumbnailImage(TRUE) ;
+
+ previewp->mPosTakenGlobal = gAgentCamera.getCameraPositionGlobal();
+ previewp->mShineCountdown = 4; // wait a few frames to avoid animation glitch due to readback this frame
+ }
+ }
+ previewp->getWindow()->decBusyCount();
+ // only show fullscreen preview when in freeze frame mode
+ previewp->setVisible(gSavedSettings.getBOOL("UseFreezeFrame"));
+ previewp->mSnapshotDelayTimer.stop();
+ previewp->mSnapshotActive = FALSE;
+
+ if(!previewp->getThumbnailUpToDate())
+ {
+ previewp->generateThumbnailImage() ;
+ }
+ lldebugs << "done creating snapshot" << llendl;
+ LLFloaterSnapshot::postUpdate();
+ LLFloaterSocial::postUpdate();
+
+ return TRUE;
+}
+
+void LLSnapshotLivePreview::setSize(S32 w, S32 h)
+{
+ lldebugs << "setSize(" << w << ", " << h << ")" << llendl;
+ setWidth(w);
+ setHeight(h);
+}
+
+void LLSnapshotLivePreview::getSize(S32& w, S32& h) const
+{
+ w = getWidth();
+ h = getHeight();
+}
+
+void LLSnapshotLivePreview::saveTexture()
+{
+ lldebugs << "saving texture: " << mPreviewImage->getWidth() << "x" << mPreviewImage->getHeight() << llendl;
+ // gen a new uuid for this asset
+ LLTransactionID tid;
+ tid.generate();
+ LLAssetID new_asset_id = tid.makeAssetID(gAgent.getSecureSessionID());
+
+ LLPointer<LLImageJ2C> formatted = new LLImageJ2C;
+ LLPointer<LLImageRaw> scaled = new LLImageRaw(mPreviewImage->getData(),
+ mPreviewImage->getWidth(),
+ mPreviewImage->getHeight(),
+ mPreviewImage->getComponents());
+
+ scaled->biasedScaleToPowerOfTwo(MAX_TEXTURE_SIZE);
+ lldebugs << "scaled texture to " << scaled->getWidth() << "x" << scaled->getHeight() << llendl;
+
+ if (formatted->encode(scaled, 0.0f))
+ {
+ LLVFile::writeFile(formatted->getData(), formatted->getDataSize(), gVFS, new_asset_id, LLAssetType::AT_TEXTURE);
+ std::string pos_string;
+ LLAgentUI::buildLocationString(pos_string, LLAgentUI::LOCATION_FORMAT_FULL);
+ std::string who_took_it;
+ LLAgentUI::buildFullname(who_took_it);
+ LLAssetStorage::LLStoreAssetCallback callback = NULL;
+ S32 expected_upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload();
+ void *userdata = NULL;
+ upload_new_resource(tid, // tid
+ LLAssetType::AT_TEXTURE,
+ "Snapshot : " + pos_string,
+ "Taken by " + who_took_it + " at " + pos_string,
+ 0,
+ LLFolderType::FT_SNAPSHOT_CATEGORY,
+ LLInventoryType::IT_SNAPSHOT,
+ PERM_ALL, // Note: Snapshots to inventory is a special case of content upload
+ LLFloaterPerms::getGroupPerms(), // that is more permissive than other uploads
+ LLFloaterPerms::getEveryonePerms(),
+ "Snapshot : " + pos_string,
+ callback, expected_upload_cost, userdata);
+ gViewerWindow->playSnapshotAnimAndSound();
+ }
+ else
+ {
+ LLNotificationsUtil::add("ErrorEncodingSnapshot");
+ llwarns << "Error encoding snapshot" << llendl;
+ }
+
+ LLViewerStats::getInstance()->incStat(LLViewerStats::ST_SNAPSHOT_COUNT );
+
+ mDataSize = 0;
+}
+
+BOOL LLSnapshotLivePreview::saveLocal()
+{
+ BOOL success = gViewerWindow->saveImageNumbered(mFormattedImage);
+
+ if(success)
+ {
+ gViewerWindow->playSnapshotAnimAndSound();
+ }
+ return success;
+}
+
+void LLSnapshotLivePreview::saveWeb()
+{
+ // *FIX: Will break if the window closes because of CloseSnapshotOnKeep!
+ // Needs to pass on ownership of the image.
+ LLImageJPEG* jpg = dynamic_cast<LLImageJPEG*>(mFormattedImage.get());
+ if(!jpg)
+ {
+ llwarns << "Formatted image not a JPEG" << llendl;
+ return;
+ }
+
+ LLSD metadata;
+ metadata["description"] = getChild<LLLineEditor>("description")->getText();
+
+ LLLandmarkActions::getRegionNameAndCoordsFromPosGlobal(gAgentCamera.getCameraPositionGlobal(),
+ boost::bind(&LLSnapshotLivePreview::regionNameCallback, this, jpg, metadata, _1, _2, _3, _4));
+
+ gViewerWindow->playSnapshotAnimAndSound();
+}
+
+void LLSnapshotLivePreview::regionNameCallback(LLImageJPEG* snapshot, LLSD& metadata, const std::string& name, S32 x, S32 y, S32 z)
+{
+ metadata["slurl"] = LLSLURL(name, LLVector3d(x, y, z)).getSLURLString();
+
+ LLWebSharing::instance().shareSnapshot(snapshot, metadata);
+}
diff --git a/indra/newview/llsnapshotlivepreview.h b/indra/newview/llsnapshotlivepreview.h
new file mode 100644
index 0000000000..fe3d257b02
--- /dev/null
+++ b/indra/newview/llsnapshotlivepreview.h
@@ -0,0 +1,164 @@
+/**
+* @file llsnapshotlivepreview.h
+* @brief Header file for llsnapshotlivepreview
+* @author Gilbert@lindenlab.com
+*
+* $LicenseInfo:firstyear=2013&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2013, 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_LLSNAPSHOTLIVEPREVIEW_H
+#define LL_LLSNAPSHOTLIVEPREVIEW_H
+
+#include "llpanelsnapshot.h"
+#include "llviewerwindow.h"
+
+class LLImageJPEG;
+
+///----------------------------------------------------------------------------
+/// Class LLSnapshotLivePreview
+///----------------------------------------------------------------------------
+class LLSnapshotLivePreview : public LLView
+{
+ LOG_CLASS(LLSnapshotLivePreview);
+public:
+ enum ESnapshotType
+ {
+ SNAPSHOT_POSTCARD,
+ SNAPSHOT_TEXTURE,
+ SNAPSHOT_LOCAL,
+ SNAPSHOT_WEB
+ };
+
+
+ struct Params : public LLInitParam::Block<Params, LLView::Params>
+ {
+ Params()
+ {
+ name = "snapshot_live_preview";
+ mouse_opaque = false;
+ }
+ };
+
+
+ LLSnapshotLivePreview(const LLSnapshotLivePreview::Params& p);
+ ~LLSnapshotLivePreview();
+
+ /*virtual*/ void draw();
+ /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent);
+
+ void setSize(S32 w, S32 h);
+ void setWidth(S32 w) { mWidth[mCurImageIndex] = w; }
+ void setHeight(S32 h) { mHeight[mCurImageIndex] = h; }
+ void getSize(S32& w, S32& h) const;
+ S32 getWidth() const { return mWidth[mCurImageIndex]; }
+ S32 getHeight() const { return mHeight[mCurImageIndex]; }
+ S32 getDataSize() const { return mDataSize; }
+ void setMaxImageSize(S32 size) ;
+ S32 getMaxImageSize() {return mMaxImageSize ;}
+
+ ESnapshotType getSnapshotType() const { return mSnapshotType; }
+ LLFloaterSnapshot::ESnapshotFormat getSnapshotFormat() const { return mSnapshotFormat; }
+ BOOL getSnapshotUpToDate() const { return mSnapshotUpToDate; }
+ BOOL isSnapshotActive() { return mSnapshotActive; }
+ LLViewerTexture* getThumbnailImage() const { return mThumbnailImage ; }
+ S32 getThumbnailWidth() const { return mThumbnailWidth ; }
+ S32 getThumbnailHeight() const { return mThumbnailHeight ; }
+ BOOL getThumbnailLock() const { return mThumbnailUpdateLock ; }
+ BOOL getThumbnailUpToDate() const { return mThumbnailUpToDate ;}
+ LLViewerTexture* getCurrentImage();
+ F32 getImageAspect();
+ F32 getAspect() ;
+ const LLRect& getImageRect() const { return mImageRect[mCurImageIndex]; }
+ BOOL isImageScaled() const { return mImageScaled[mCurImageIndex]; }
+ void setImageScaled(BOOL scaled) { mImageScaled[mCurImageIndex] = scaled; }
+ const LLVector3d& getPosTakenGlobal() const { return mPosTakenGlobal; }
+
+ void setSnapshotType(ESnapshotType type) { mSnapshotType = type; }
+ void setSnapshotFormat(LLFloaterSnapshot::ESnapshotFormat type) { mSnapshotFormat = type; }
+ void setSnapshotQuality(S32 quality);
+ void setSnapshotBufferType(LLViewerWindow::ESnapshotType type) { mSnapshotBufferType = type; }
+ void updateSnapshot(BOOL new_snapshot, BOOL new_thumbnail = FALSE, F32 delay = 0.f);
+ void saveWeb();
+ void saveTexture();
+ BOOL saveLocal();
+
+ LLPointer<LLImageFormatted> getFormattedImage() const { return mFormattedImage; }
+ LLPointer<LLImageRaw> getEncodedImage() const { return mPreviewImageEncoded; }
+
+ /// Sets size of preview thumbnail image and thhe surrounding rect.
+ void setThumbnailPlaceholderRect(const LLRect& rect) {mThumbnailPlaceholderRect = rect; }
+ BOOL setThumbnailImageSize() ;
+ void generateThumbnailImage(BOOL force_update = FALSE) ;
+ void resetThumbnailImage() { mThumbnailImage = NULL ; }
+ void drawPreviewRect(S32 offset_x, S32 offset_y) ;
+
+ // Returns TRUE when snapshot generated, FALSE otherwise.
+ static BOOL onIdle( void* snapshot_preview );
+
+ // callback for region name resolve
+ void regionNameCallback(LLImageJPEG* snapshot, LLSD& metadata, const std::string& name, S32 x, S32 y, S32 z);
+
+private:
+ LLColor4 mColor;
+ LLPointer<LLViewerTexture> mViewerImage[2]; //used to represent the scene when the frame is frozen.
+ LLRect mImageRect[2];
+ S32 mWidth[2];
+ S32 mHeight[2];
+ BOOL mImageScaled[2];
+ S32 mMaxImageSize ;
+
+ //thumbnail image
+ LLPointer<LLViewerTexture> mThumbnailImage ;
+ S32 mThumbnailWidth ;
+ S32 mThumbnailHeight ;
+ LLRect mPreviewRect ;
+ BOOL mThumbnailUpdateLock ;
+ BOOL mThumbnailUpToDate ;
+ LLRect mThumbnailPlaceholderRect;
+
+ S32 mCurImageIndex;
+ LLPointer<LLImageRaw> mPreviewImage;
+ LLPointer<LLImageRaw> mPreviewImageEncoded;
+ LLPointer<LLImageFormatted> mFormattedImage;
+ LLFrameTimer mSnapshotDelayTimer;
+ S32 mShineCountdown;
+ LLFrameTimer mShineAnimTimer;
+ F32 mFlashAlpha;
+ BOOL mNeedsFlash;
+ LLVector3d mPosTakenGlobal;
+ S32 mSnapshotQuality;
+ S32 mDataSize;
+ ESnapshotType mSnapshotType;
+ LLFloaterSnapshot::ESnapshotFormat mSnapshotFormat;
+ BOOL mSnapshotUpToDate;
+ LLFrameTimer mFallAnimTimer;
+ LLVector3 mCameraPos;
+ LLQuaternion mCameraRot;
+ BOOL mSnapshotActive;
+ LLViewerWindow::ESnapshotType mSnapshotBufferType;
+
+public:
+ static std::set<LLSnapshotLivePreview*> sList;
+ BOOL mKeepAspectRatio ;
+};
+
+#endif // LL_LLSNAPSHOTLIVEPREVIEW_H
+
diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp
index 5d196a465f..2c83f6d0b7 100644..100755
--- a/indra/newview/llspatialpartition.cpp
+++ b/indra/newview/llspatialpartition.cpp
@@ -55,7 +55,7 @@
#include "llviewershadermgr.h"
static LLFastTimer::DeclareTimer FTM_FRUSTUM_CULL("Frustum Culling");
-static LLFastTimer::DeclareTimer FTM_CULL_REBOUND("Cull Rebound");
+static LLFastTimer::DeclareTimer FTM_CULL_REBOUND("Cull Rebound Partition");
const F32 SG_OCCLUSION_FUDGE = 0.25f;
#define SG_DISCARD_TOLERANCE 0.01f
@@ -68,6 +68,7 @@ const F32 SG_OCCLUSION_FUDGE = 0.25f;
#define assert_states_valid(x)
#endif
+extern bool gShiftFrame;
static U32 sZombieGroups = 0;
U32 LLSpatialGroup::sNodeCount = 0;
@@ -85,12 +86,21 @@ static F32 sCurMaxTexPriority = 1.f;
class LLOcclusionQueryPool : public LLGLNamePool
{
+public:
+ LLOcclusionQueryPool()
+ {
+
+ }
+
protected:
+
virtual GLuint allocateName()
{
- GLuint name;
- glGenQueriesARB(1, &name);
- return name;
+ GLuint ret = 0;
+
+ glGenQueriesARB(1, &ret);
+
+ return ret;
}
virtual void releaseName(GLuint name)
@@ -259,79 +269,39 @@ U8* get_box_fan_indices_ptr(LLCamera* camera, const LLVector4a& center)
return (U8*) (sOcclusionIndices+cypher*8);
}
-
-static LLFastTimer::DeclareTimer FTM_BUILD_OCCLUSION("Build Occlusion");
-
-void LLSpatialGroup::buildOcclusion()
+//create a vertex buffer for efficiently rendering cubes
+LLVertexBuffer* ll_create_cube_vb(U32 type_mask, U32 usage)
{
- //if (mOcclusionVerts.isNull())
- {
- mOcclusionVerts = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX,
- LLVertexBuffer::sUseStreamDraw ? mBufferUsage : 0); //if GL has a hard time with VBOs, don't use them for occlusion culling.
- mOcclusionVerts->allocateBuffer(8, 64, true);
-
- LLStrider<U16> idx;
- mOcclusionVerts->getIndexStrider(idx);
- for (U32 i = 0; i < 64; i++)
- {
- *idx++ = sOcclusionIndices[i];
- }
- }
+ LLVertexBuffer* ret = new LLVertexBuffer(type_mask, usage);
- LLVector4a fudge;
- fudge.splat(SG_OCCLUSION_FUDGE);
-
- LLVector4a r;
- r.setAdd(mBounds[1], fudge);
+ ret->allocateBuffer(8, 64, true);
LLStrider<LLVector3> pos;
-
- {
- LLFastTimer t(FTM_BUILD_OCCLUSION);
- mOcclusionVerts->getVertexStrider(pos);
- }
+ LLStrider<U16> idx;
- {
- LLVector4a* v = (LLVector4a*) pos.get();
+ ret->getVertexStrider(pos);
+ ret->getIndexStrider(idx);
- const LLVector4a& c = mBounds[0];
- const LLVector4a& s = r;
-
- static const LLVector4a octant[] =
- {
- LLVector4a(-1.f, -1.f, -1.f),
- LLVector4a(-1.f, -1.f, 1.f),
- LLVector4a(-1.f, 1.f, -1.f),
- LLVector4a(-1.f, 1.f, 1.f),
-
- LLVector4a(1.f, -1.f, -1.f),
- LLVector4a(1.f, -1.f, 1.f),
- LLVector4a(1.f, 1.f, -1.f),
- LLVector4a(1.f, 1.f, 1.f),
- };
-
- //vertex positions are encoded so the 3 bits of their vertex index
- //correspond to their axis facing, with bit position 3,2,1 matching
- //axis facing x,y,z, bit set meaning positive facing, bit clear
- //meaning negative facing
-
- for (S32 i = 0; i < 8; ++i)
- {
- LLVector4a p;
- p.setMul(s, octant[i]);
- p.add(c);
- v[i] = p;
- }
- }
-
+ pos[0] = LLVector3(-1,-1,-1);
+ pos[1] = LLVector3(-1,-1, 1);
+ pos[2] = LLVector3(-1, 1,-1);
+ pos[3] = LLVector3(-1, 1, 1);
+ pos[4] = LLVector3( 1,-1,-1);
+ pos[5] = LLVector3( 1,-1, 1);
+ pos[6] = LLVector3( 1, 1,-1);
+ pos[7] = LLVector3( 1, 1, 1);
+
+ for (U32 i = 0; i < 64; i++)
{
- mOcclusionVerts->flush();
- LLVertexBuffer::unbind();
+ idx[i] = sOcclusionIndices[i];
}
- clearState(LLSpatialGroup::OCCLUSION_DIRTY);
+ ret->flush();
+
+ return ret;
}
+static LLFastTimer::DeclareTimer FTM_BUILD_OCCLUSION("Build Occlusion");
BOOL earlyFail(LLCamera* camera, LLSpatialGroup* group);
@@ -394,9 +364,6 @@ LLSpatialGroup::~LLSpatialGroup()
}
}
- mOcclusionVerts = NULL;
-
- LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
clearDrawMap();
clearAtlasList() ;
}
@@ -550,6 +517,7 @@ void LLSpatialGroup::setVisible()
void LLSpatialGroup::validate()
{
+ ll_assert_aligned(this,64);
#if LL_OCTREE_PARANOIA_CHECK
sg_assert(!isState(DIRTY));
@@ -562,7 +530,7 @@ void LLSpatialGroup::validate()
validateDrawMap();
- for (element_iter i = getData().begin(); i != getData().end(); ++i)
+ for (element_iter i = getDataBegin(); i != getDataEnd(); ++i)
{
LLDrawable* drawable = *i;
sg_assert(drawable->getSpatialGroup() == this);
@@ -634,8 +602,6 @@ void LLSpatialGroup::validateDrawMap()
BOOL LLSpatialGroup::updateInGroup(LLDrawable *drawablep, BOOL immediate)
{
- LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
-
drawablep->updateSpatialExtents();
OctreeNode* parent = mOctreeNode->getOctParent();
@@ -657,7 +623,6 @@ BOOL LLSpatialGroup::updateInGroup(LLDrawable *drawablep, BOOL immediate)
BOOL LLSpatialGroup::addObject(LLDrawable *drawablep, BOOL add_all, BOOL from_octree)
{
- LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
if (!from_octree)
{
mOctreeNode->insert(drawablep);
@@ -683,10 +648,14 @@ BOOL LLSpatialGroup::addObject(LLDrawable *drawablep, BOOL add_all, BOOL from_oc
void LLSpatialGroup::rebuildGeom()
{
- LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
if (!isDead())
{
mSpatialPartition->rebuildGeom(this);
+
+ if (isState(LLSpatialGroup::MESH_DIRTY))
+ {
+ gPipeline.markMeshDirty(this);
+ }
}
}
@@ -699,6 +668,9 @@ void LLSpatialGroup::rebuildMesh()
}
static LLFastTimer::DeclareTimer FTM_REBUILD_VBO("VBO Rebuilt");
+static LLFastTimer::DeclareTimer FTM_ADD_GEOMETRY_COUNT("Add Geometry");
+static LLFastTimer::DeclareTimer FTM_CREATE_VB("Create VB");
+static LLFastTimer::DeclareTimer FTM_GET_GEOMETRY("Get Geometry");
void LLSpatialPartition::rebuildGeom(LLSpatialGroup* group)
{
@@ -720,27 +692,36 @@ void LLSpatialPartition::rebuildGeom(LLSpatialGroup* group)
//get geometry count
U32 index_count = 0;
U32 vertex_count = 0;
-
- addGeometryCount(group, vertex_count, index_count);
+
+ {
+ LLFastTimer t(FTM_ADD_GEOMETRY_COUNT);
+ addGeometryCount(group, vertex_count, index_count);
+ }
if (vertex_count > 0 && index_count > 0)
{ //create vertex buffer containing volume geometry for this node
- group->mBuilt = 1.f;
- if (group->mVertexBuffer.isNull() ||
- !group->mVertexBuffer->isWriteable() ||
- (group->mBufferUsage != group->mVertexBuffer->getUsage() && LLVertexBuffer::sEnableVBOs))
{
- group->mVertexBuffer = createVertexBuffer(mVertexDataMask, group->mBufferUsage);
- group->mVertexBuffer->allocateBuffer(vertex_count, index_count, true);
- stop_glerror();
+ LLFastTimer t(FTM_CREATE_VB);
+ group->mBuilt = 1.f;
+ if (group->mVertexBuffer.isNull() ||
+ !group->mVertexBuffer->isWriteable() ||
+ (group->mBufferUsage != group->mVertexBuffer->getUsage() && LLVertexBuffer::sEnableVBOs))
+ {
+ group->mVertexBuffer = createVertexBuffer(mVertexDataMask, group->mBufferUsage);
+ group->mVertexBuffer->allocateBuffer(vertex_count, index_count, true);
+ stop_glerror();
+ }
+ else
+ {
+ group->mVertexBuffer->resizeBuffer(vertex_count, index_count);
+ stop_glerror();
+ }
}
- else
+
{
- group->mVertexBuffer->resizeBuffer(vertex_count, index_count);
- stop_glerror();
+ LLFastTimer t(FTM_GET_GEOMETRY);
+ getGeometry(group);
}
-
- getGeometry(group);
}
else
{
@@ -762,7 +743,7 @@ BOOL LLSpatialGroup::boundObjects(BOOL empty, LLVector4a& minOut, LLVector4a& ma
{
const OctreeNode* node = mOctreeNode;
- if (node->getData().empty())
+ if (node->isEmpty())
{ //don't do anything if there are no objects
if (empty && mOctreeNode->getParent())
{ //only root is allowed to be empty
@@ -779,14 +760,14 @@ BOOL LLSpatialGroup::boundObjects(BOOL empty, LLVector4a& minOut, LLVector4a& ma
clearState(OBJECT_DIRTY);
//initialize bounding box to first element
- OctreeNode::const_element_iter i = node->getData().begin();
+ OctreeNode::const_element_iter i = node->getDataBegin();
LLDrawable* drawablep = *i;
const LLVector4a* minMax = drawablep->getSpatialExtents();
newMin = minMax[0];
newMax = minMax[1];
- for (++i; i != node->getData().end(); ++i)
+ for (++i; i != node->getDataEnd(); ++i)
{
drawablep = *i;
minMax = drawablep->getSpatialExtents();
@@ -878,7 +859,6 @@ LLSpatialGroup* LLSpatialGroup::getParent()
BOOL LLSpatialGroup::removeObject(LLDrawable *drawablep, BOOL from_octree)
{
- LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
unbound();
if (mOctreeNode && !from_octree)
{
@@ -915,7 +895,6 @@ BOOL LLSpatialGroup::removeObject(LLDrawable *drawablep, BOOL from_octree)
void LLSpatialGroup::shift(const LLVector4a &offset)
{
- LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
LLVector4a t = mOctreeNode->getCenter();
t.add(offset);
mOctreeNode->setCenter(t);
@@ -927,16 +906,14 @@ void LLSpatialGroup::shift(const LLVector4a &offset)
mObjectExtents[0].add(offset);
mObjectExtents[1].add(offset);
- //if (!mSpatialPartition->mRenderByGroup)
+ if (!mSpatialPartition->mRenderByGroup &&
+ mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_TREE &&
+ mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_TERRAIN &&
+ mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_BRIDGE)
{
setState(GEOM_DIRTY);
gPipeline.markRebuild(this, TRUE);
}
-
- if (mOcclusionVerts.notNull())
- {
- setState(OCCLUSION_DIRTY);
- }
}
class LLSpatialSetState : public LLSpatialGroup::OctreeTraveler
@@ -972,8 +949,6 @@ void LLSpatialGroup::setState(U32 state)
void LLSpatialGroup::setState(U32 state, S32 mode)
{
- LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
-
llassert(state <= LLSpatialGroup::STATE_MASK);
if (mode > STATE_MODE_SINGLE)
@@ -1030,8 +1005,6 @@ void LLSpatialGroup::clearState(U32 state, S32 mode)
{
llassert(state <= LLSpatialGroup::STATE_MASK);
- LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
-
if (mode > STATE_MODE_SINGLE)
{
if (mode == STATE_MODE_DIFF)
@@ -1088,8 +1061,6 @@ public:
void LLSpatialGroup::setOcclusionState(U32 state, S32 mode)
{
- LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
-
if (mode > STATE_MODE_SINGLE)
{
if (mode == STATE_MODE_DIFF)
@@ -1154,8 +1125,6 @@ public:
void LLSpatialGroup::clearOcclusionState(U32 state, S32 mode)
{
- LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
-
if (mode > STATE_MODE_SINGLE)
{
if (mode == STATE_MODE_DIFF)
@@ -1186,6 +1155,7 @@ void LLSpatialGroup::clearOcclusionState(U32 state, S32 mode)
//======================================
LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) :
+ mObjectBoxSize(1.f),
mState(0),
mGeometryBytes(0),
mSurfaceArea(0.f),
@@ -1203,8 +1173,9 @@ LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) :
mCurUpdatingSlotp(NULL),
mCurUpdatingTexture (NULL)
{
+ ll_assert_aligned(this,16);
+
sNodeCount++;
- LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
mViewAngle.splat(0.f);
mLastUpdateViewAngle.splat(-1.f);
@@ -1234,8 +1205,6 @@ LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) :
mVisible[i] = 0;
}
- mOcclusionVerts = NULL;
-
mRadius = 1;
mPixelArea = 1024.f;
}
@@ -1248,13 +1217,18 @@ void LLSpatialGroup::updateDistance(LLCamera &camera)
return;
}
+ if (gShiftFrame)
+ {
+ return;
+ }
+
#if !LL_RELEASE_FOR_DOWNLOAD
if (isState(LLSpatialGroup::OBJECT_DIRTY))
{
llerrs << "Spatial group dirty on distance update." << llendl;
}
#endif
- if (!getData().empty())
+ if (!isEmpty())
{
mRadius = mSpatialPartition->mRenderByGroup ? mObjectBounds[1].getLength3().getF32() :
(F32) mOctreeNode->getSize().getLength3().getF32();
@@ -1387,7 +1361,6 @@ BOOL LLSpatialGroup::changeLOD()
void LLSpatialGroup::handleInsertion(const TreeNode* node, LLDrawable* drawablep)
{
- LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
addObject(drawablep, FALSE, TRUE);
unbound();
setState(OBJECT_DIRTY);
@@ -1395,17 +1368,15 @@ void LLSpatialGroup::handleInsertion(const TreeNode* node, LLDrawable* drawablep
void LLSpatialGroup::handleRemoval(const TreeNode* node, LLDrawable* drawable)
{
- LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
removeObject(drawable, TRUE);
setState(OBJECT_DIRTY);
}
void LLSpatialGroup::handleDestruction(const TreeNode* node)
{
- LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
setState(DEAD);
- for (element_iter i = getData().begin(); i != getData().end(); ++i)
+ for (element_iter i = getDataBegin(); i != getDataEnd(); ++i)
{
LLDrawable* drawable = *i;
if (drawable->getSpatialGroup() == this)
@@ -1421,7 +1392,9 @@ void LLSpatialGroup::handleDestruction(const TreeNode* node)
if (bridge->mAvatar.notNull())
{
bridge->mAvatar->mAttachmentGeometryBytes -= mGeometryBytes;
+ bridge->mAvatar->mAttachmentGeometryBytes = llmax(bridge->mAvatar->mAttachmentGeometryBytes, 0);
bridge->mAvatar->mAttachmentSurfaceArea -= mSurfaceArea;
+ bridge->mAvatar->mAttachmentSurfaceArea = llmax(bridge->mAvatar->mAttachmentSurfaceArea, 0.f);
}
}
@@ -1444,7 +1417,6 @@ void LLSpatialGroup::handleStateChange(const TreeNode* node)
void LLSpatialGroup::handleChildAddition(const OctreeNode* parent, OctreeNode* child)
{
- LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
if (child->getListenerCount() == 0)
{
new LLSpatialGroup(child, mSpatialPartition);
@@ -1464,10 +1436,14 @@ void LLSpatialGroup::handleChildRemoval(const OctreeNode* parent, const OctreeNo
unbound();
}
-void LLSpatialGroup::destroyGL()
+void LLSpatialGroup::destroyGL(bool keep_occlusion)
{
setState(LLSpatialGroup::GEOM_DIRTY | LLSpatialGroup::IMAGE_DIRTY);
- gPipeline.markRebuild(this, TRUE);
+
+ if (!keep_occlusion)
+ { //going to need a rebuild
+ gPipeline.markRebuild(this, TRUE);
+ }
mLastUpdateTime = gFrameTimeSeconds;
mVertexBuffer = NULL;
@@ -1475,24 +1451,29 @@ void LLSpatialGroup::destroyGL()
clearDrawMap();
- for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++)
+ if (!keep_occlusion)
{
- if (mOcclusionQuery[i])
+ for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++)
{
- sQueryPool.release(mOcclusionQuery[i]);
- mOcclusionQuery[i] = 0;
+ if (mOcclusionQuery[i])
+ {
+ sQueryPool.release(mOcclusionQuery[i]);
+ mOcclusionQuery[i] = 0;
+ }
}
}
- mOcclusionVerts = NULL;
- for (LLSpatialGroup::element_iter i = getData().begin(); i != getData().end(); ++i)
+ for (LLSpatialGroup::element_iter i = getDataBegin(); i != getDataEnd(); ++i)
{
LLDrawable* drawable = *i;
for (S32 j = 0; j < drawable->getNumFaces(); j++)
{
LLFace* facep = drawable->getFace(j);
- facep->clearVertexBuffer();
+ if (facep)
+ {
+ facep->clearVertexBuffer();
+ }
}
}
}
@@ -1507,6 +1488,8 @@ BOOL LLSpatialGroup::rebound()
if (mOctreeNode->getChildCount() == 1 && mOctreeNode->getElementCount() == 0)
{
LLSpatialGroup* group = (LLSpatialGroup*) mOctreeNode->getChild(0)->getListener(0);
+
+ //rebound single child
group->rebound();
//copy single child's bounding box
@@ -1515,10 +1498,11 @@ BOOL LLSpatialGroup::rebound()
mExtents[0] = group->mExtents[0];
mExtents[1] = group->mExtents[1];
+ //treat this node as a "chute" to a deeper level of the tree
group->setState(SKIP_FRUSTUM_CHECK);
}
else if (mOctreeNode->isLeaf())
- { //copy object bounding box if this is a leaf
+ { //copy object bounding box if this is a leaf
boundObjects(TRUE, mExtents[0], mExtents[1]);
mBounds[0] = mObjectBounds[0];
mBounds[1] = mObjectBounds[1];
@@ -1527,14 +1511,17 @@ BOOL LLSpatialGroup::rebound()
{
LLVector4a& newMin = mExtents[0];
LLVector4a& newMax = mExtents[1];
+
+ //get bounding box of first child
LLSpatialGroup* group = (LLSpatialGroup*) mOctreeNode->getChild(0)->getListener(0);
group->clearState(SKIP_FRUSTUM_CHECK);
group->rebound();
+
//initialize to first child
newMin = group->mExtents[0];
newMax = group->mExtents[1];
- //first, rebound children
+ //rebound remaining children, expanding bounding box to encompass children
for (U32 i = 1; i < mOctreeNode->getChildCount(); i++)
{
group = (LLSpatialGroup*) mOctreeNode->getChild(i)->getListener(0);
@@ -1555,15 +1542,13 @@ BOOL LLSpatialGroup::rebound()
mBounds[1].mul(0.5f);
}
- setState(OCCLUSION_DIRTY);
-
clearState(DIRTY);
return TRUE;
}
static LLFastTimer::DeclareTimer FTM_OCCLUSION_READBACK("Readback Occlusion");
-static LLFastTimer::DeclareTimer FTM_OCCLUSION_WAIT("Wait");
+static LLFastTimer::DeclareTimer FTM_OCCLUSION_WAIT("Occlusion Wait");
void LLSpatialGroup::checkOcclusion()
{
@@ -1583,7 +1568,9 @@ void LLSpatialGroup::checkOcclusion()
{
glGetQueryObjectuivARB(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_AVAILABLE_ARB, &available);
- if (mOcclusionIssued[LLViewerCamera::sCurCameraID] < gFrameCount)
+ static LLCachedControl<bool> wait_for_query(gSavedSettings, "RenderSynchronousOcclusion", true);
+
+ if (wait_for_query && mOcclusionIssued[LLViewerCamera::sCurCameraID] < gFrameCount)
{ //query was issued last frame, wait until it's available
S32 max_loop = 1024;
LLFastTimer t(FTM_OCCLUSION_WAIT);
@@ -1634,7 +1621,9 @@ void LLSpatialGroup::checkOcclusion()
else
{
assert_states_valid(this);
+
setOcclusionState(LLSpatialGroup::OCCLUDED, LLSpatialGroup::STATE_MODE_DIFF);
+
assert_states_valid(this);
}
@@ -1689,12 +1678,6 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera)
mOcclusionQuery[LLViewerCamera::sCurCameraID] = sQueryPool.allocate();
}
- if (mOcclusionVerts.isNull() || isState(LLSpatialGroup::OCCLUSION_DIRTY))
- {
- LLFastTimer t(FTM_OCCLUSION_BUILD);
- buildOcclusion();
- }
-
// Depth clamp all water to avoid it being culled as a result of being
// behind the far clip plane, and in the case of edge water to avoid
// it being culled while still visible.
@@ -1725,10 +1708,13 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera)
glBeginQueryARB(mode, mOcclusionQuery[LLViewerCamera::sCurCameraID]);
}
- {
- LLFastTimer t(FTM_OCCLUSION_SET_BUFFER);
- mOcclusionVerts->setBuffer(LLVertexBuffer::MAP_VERTEX);
- }
+ LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
+ llassert(shader);
+
+ shader->uniform3fv(LLShaderMgr::BOX_CENTER, 1, mBounds[0].getF32ptr());
+ shader->uniform3f(LLShaderMgr::BOX_SIZE, mBounds[1][0]+SG_OCCLUSION_FUDGE,
+ mBounds[1][1]+SG_OCCLUSION_FUDGE,
+ mBounds[1][2]+SG_OCCLUSION_FUDGE);
if (!use_depth_clamp && mSpatialPartition->mDrawableType == LLDrawPool::POOL_VOIDWATER)
{
@@ -1737,12 +1723,12 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera)
LLGLSquashToFarClip squash(glh_get_current_projection(), 1);
if (camera->getOrigin().isExactlyZero())
{ //origin is invalid, draw entire box
- mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, 0);
- mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, b111*8);
+ gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, 0);
+ gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, b111*8);
}
else
{
- mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, mBounds[0]));
+ gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, mBounds[0]));
}
}
else
@@ -1750,12 +1736,12 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera)
LLFastTimer t(FTM_OCCLUSION_DRAW);
if (camera->getOrigin().isExactlyZero())
{ //origin is invalid, draw entire box
- mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, 0);
- mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, b111*8);
+ gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, 0);
+ gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, b111*8);
}
else
{
- mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, mBounds[0]));
+ gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, mBounds[0]));
}
}
@@ -1782,7 +1768,6 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera)
LLSpatialPartition::LLSpatialPartition(U32 data_mask, BOOL render_by_group, U32 buffer_usage)
: mRenderByGroup(render_by_group), mBridge(NULL)
{
- LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
mOcclusionEnabled = TRUE;
mDrawableType = 0;
mPartitionType = LLViewerRegion::PARTITION_NONE;
@@ -1806,8 +1791,6 @@ LLSpatialPartition::LLSpatialPartition(U32 data_mask, BOOL render_by_group, U32
LLSpatialPartition::~LLSpatialPartition()
{
- LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
-
delete mOctree;
mOctree = NULL;
}
@@ -1815,8 +1798,6 @@ LLSpatialPartition::~LLSpatialPartition()
LLSpatialGroup *LLSpatialPartition::put(LLDrawable *drawablep, BOOL was_visible)
{
- LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
-
drawablep->updateSpatialExtents();
//keep drawable from being garbage collected
@@ -1838,14 +1819,16 @@ LLSpatialGroup *LLSpatialPartition::put(LLDrawable *drawablep, BOOL was_visible)
BOOL LLSpatialPartition::remove(LLDrawable *drawablep, LLSpatialGroup *curp)
{
- LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
-
- drawablep->setSpatialGroup(NULL);
-
if (!curp->removeObject(drawablep))
{
OCT_ERRS << "Failed to remove drawable from octree!" << llendl;
}
+ else
+ {
+ drawablep->setSpatialGroup(NULL);
+ }
+
+ drawablep->setSpatialGroup(NULL);
assert_octree_valid(mOctree);
@@ -1854,8 +1837,6 @@ BOOL LLSpatialPartition::remove(LLDrawable *drawablep, LLSpatialGroup *curp)
void LLSpatialPartition::move(LLDrawable *drawablep, LLSpatialGroup *curp, BOOL immediate)
{
- LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
-
// sanity check submitted by open source user bushing Spatula
// who was seeing crashing here. (See VWR-424 reported by Bunny Mayne)
if (!drawablep)
@@ -1912,7 +1893,6 @@ public:
void LLSpatialPartition::shift(const LLVector4a &offset)
{ //shift octree node bounding boxes by offset
- LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
LLSpatialShift shifter(offset);
shifter.traverse(mOctree);
}
@@ -2116,7 +2096,7 @@ public:
virtual void processGroup(LLSpatialGroup* group)
{
- llassert(!group->isState(LLSpatialGroup::DIRTY) && !group->getData().empty())
+ llassert(!group->isState(LLSpatialGroup::DIRTY) && !group->isEmpty())
if (mRes < 2)
{
@@ -2183,7 +2163,7 @@ public:
{
LLSpatialGroup::OctreeNode* branch = group->mOctreeNode;
- for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getData().begin(); i != branch->getData().end(); ++i)
+ for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i)
{
LLDrawable* drawable = *i;
@@ -2250,6 +2230,18 @@ void drawBox(const LLVector4a& c, const LLVector4a& r)
void drawBoxOutline(const LLVector3& pos, const LLVector3& size)
{
+
+ llassert(pos.isFinite());
+ llassert(size.isFinite());
+
+ llassert(!llisnan(pos.mV[0]));
+ llassert(!llisnan(pos.mV[1]));
+ llassert(!llisnan(pos.mV[2]));
+
+ llassert(!llisnan(size.mV[0]));
+ llassert(!llisnan(size.mV[1]));
+ llassert(!llisnan(size.mV[2]));
+
LLVector3 v1 = size.scaledVec(LLVector3( 1, 1,1));
LLVector3 v2 = size.scaledVec(LLVector3(-1, 1,1));
LLVector3 v3 = size.scaledVec(LLVector3(-1,-1,1));
@@ -2307,7 +2299,7 @@ public:
LLSpatialGroup* group = (LLSpatialGroup*) state->getListener(0);
group->destroyGL();
- for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i)
+ for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)
{
LLDrawable* drawable = *i;
if (drawable->getVObj().notNull() && !group->mSpatialPartition->mRenderByGroup)
@@ -2326,7 +2318,6 @@ public:
void LLSpatialPartition::restoreGL()
{
- LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
}
void LLSpatialPartition::resetVertexBuffers()
@@ -2369,7 +2360,6 @@ BOOL LLSpatialPartition::visibleObjectsInFrustum(LLCamera& camera)
S32 LLSpatialPartition::cull(LLCamera &camera, std::vector<LLDrawable *>* results, BOOL for_select)
{
- LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
#if LL_OCTREE_PARANOIA_CHECK
((LLSpatialGroup*)mOctree->getListener(0))->checkStates();
#endif
@@ -2479,18 +2469,21 @@ void pushVerts(LLSpatialGroup* group, U32 mask)
void pushVerts(LLFace* face, U32 mask)
{
- llassert(face->verify());
+ if (face)
+ {
+ llassert(face->verify());
- LLVertexBuffer* buffer = face->getVertexBuffer();
+ LLVertexBuffer* buffer = face->getVertexBuffer();
- if (buffer && (face->getGeomCount() >= 3))
- {
- buffer->setBuffer(mask);
- U16 start = face->getGeomStart();
- U16 end = start + face->getGeomCount()-1;
- U32 count = face->getIndicesCount();
- U16 offset = face->getIndicesStart();
- buffer->drawRange(LLRender::TRIANGLES, start, end, count, offset);
+ if (buffer && (face->getGeomCount() >= 3))
+ {
+ buffer->setBuffer(mask);
+ U16 start = face->getGeomStart();
+ U16 end = start + face->getGeomCount()-1;
+ U32 count = face->getIndicesCount();
+ U16 offset = face->getIndicesStart();
+ buffer->drawRange(LLRender::TRIANGLES, start, end, count, offset);
+ }
}
}
@@ -2521,7 +2514,7 @@ void pushBufferVerts(LLVertexBuffer* buffer, U32 mask)
}
}
-void pushBufferVerts(LLSpatialGroup* group, U32 mask)
+void pushBufferVerts(LLSpatialGroup* group, U32 mask, bool push_alpha = true)
{
if (group->mSpatialPartition->mRenderByGroup)
{
@@ -2530,7 +2523,10 @@ void pushBufferVerts(LLSpatialGroup* group, U32 mask)
LLDrawInfo* params = *(group->mDrawMap.begin()->second.begin());
LLRenderPass::applyModelMatrix(*params);
- pushBufferVerts(group->mVertexBuffer, mask);
+ if (push_alpha)
+ {
+ pushBufferVerts(group->mVertexBuffer, mask);
+ }
for (LLSpatialGroup::buffer_map_t::iterator i = group->mBufferMap.begin(); i != group->mBufferMap.end(); ++i)
{
@@ -2544,10 +2540,10 @@ void pushBufferVerts(LLSpatialGroup* group, U32 mask)
}
}
}
- else
+ /*else
{
- drawBox(group->mBounds[0], group->mBounds[1]);
- }
+ //drawBox(group->mBounds[0], group->mBounds[1]);
+ }*/
}
void pushVertsColorCoded(LLSpatialGroup* group, U32 mask)
@@ -2614,7 +2610,7 @@ void renderOctree(LLSpatialGroup* group)
gGL.flush();
glLineWidth(1.f);
gGL.flush();
- for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i)
+ for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)
{
LLDrawable* drawable = *i;
if (!group->mSpatialPartition->isBridge())
@@ -2627,7 +2623,7 @@ void renderOctree(LLSpatialGroup* group)
for (S32 j = 0; j < drawable->getNumFaces(); j++)
{
LLFace* face = drawable->getFace(j);
- if (face->getVertexBuffer())
+ if (face && face->getVertexBuffer())
{
if (gFrameTimeSeconds - face->mLastUpdateTime < 0.5f)
{
@@ -2660,7 +2656,7 @@ void renderOctree(LLSpatialGroup* group)
}
else
{
- if (group->mBufferUsage == GL_STATIC_DRAW_ARB && !group->getData().empty()
+ if (group->mBufferUsage == GL_STATIC_DRAW_ARB && !group->isEmpty()
&& group->mSpatialPartition->mRenderByGroup)
{
col.setVec(0.8f, 0.4f, 0.1f, 0.1f);
@@ -2720,18 +2716,54 @@ void renderOctree(LLSpatialGroup* group)
// drawBoxOutline(LLVector3(node->getCenter()), LLVector3(node->getSize()));
}
+std::set<LLSpatialGroup*> visible_selected_groups;
+
void renderVisibility(LLSpatialGroup* group, LLCamera* camera)
{
- LLGLEnable blend(GL_BLEND);
+ /*LLGLEnable blend(GL_BLEND);
gGL.setSceneBlendType(LLRender::BT_ALPHA);
LLGLEnable cull(GL_CULL_FACE);
- glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);*/
+
+ /*BOOL render_objects = (!LLPipeline::sUseOcclusion || !group->isOcclusionState(LLSpatialGroup::OCCLUDED)) && group->isVisible() &&
+ !group->isEmpty();
- BOOL render_objects = (!LLPipeline::sUseOcclusion || !group->isOcclusionState(LLSpatialGroup::OCCLUDED)) && group->isVisible() &&
- !group->getData().empty();
if (render_objects)
{
+ LLGLDepthTest depth(GL_TRUE, GL_FALSE);
+
+ LLGLDisable blend(GL_BLEND);
+ gGL.diffuseColor4f(0.f, 0.75f, 0.f,0.5f);
+ pushBufferVerts(group, LLVertexBuffer::MAP_VERTEX, false);
+
+ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+ glLineWidth(4.f);
+ gGL.diffuseColor4f(0.f, 0.5f, 0.f, 1.f);
+ pushBufferVerts(group, LLVertexBuffer::MAP_VERTEX, false);
+ glLineWidth(1.f);
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+
+ bool selected = false;
+
+ for (LLSpatialGroup::element_iter iter = group->getDataBegin(); iter != group->getDataEnd(); ++iter)
+ {
+ LLDrawable* drawable = *iter;
+ if (drawable->getVObj().notNull() && drawable->getVObj()->isSelected())
+ {
+ selected = true;
+ break;
+ }
+ }
+
+ if (selected)
+ { //store for rendering occlusion volume as overlay
+ visible_selected_groups.insert(group);
+ }
+ }*/
+
+ /*if (render_objects)
+ {
LLGLDepthTest depth_under(GL_TRUE, GL_FALSE, GL_GREATER);
gGL.diffuseColor4f(0, 0.5f, 0, 0.5f);
gGL.diffuseColor4f(0, 0.5f, 0, 0.5f);
@@ -2755,26 +2787,66 @@ void renderVisibility(LLSpatialGroup* group, LLCamera* camera)
gGL.diffuseColor4f(0.f, 0.75f, 0.f,0.5f);
gGL.diffuseColor4f(0.f, 0.75f, 0.f, 0.5f);
pushBufferVerts(group, LLVertexBuffer::MAP_VERTEX);
- }
- /*else if (camera && group->mOcclusionVerts.notNull())
+
+ bool selected = false;
+
+ for (LLSpatialGroup::element_iter iter = group->getDataBegin(); iter != group->getDataEnd(); ++iter)
+ {
+ LLDrawable* drawable = *iter;
+ if (drawable->getVObj().notNull() && drawable->getVObj()->isSelected())
+ {
+ selected = true;
+ break;
+ }
+ }
+
+ if (selected)
+ { //store for rendering occlusion volume as overlay
+ visible_selected_groups.insert(group);
+ }
+ }
+ }*/
+}
+
+void renderXRay(LLSpatialGroup* group, LLCamera* camera)
+{
+ BOOL render_objects = (!LLPipeline::sUseOcclusion || !group->isOcclusionState(LLSpatialGroup::OCCLUDED)) && group->isVisible() &&
+ !group->isEmpty();
+
+ if (render_objects)
+ {
+ pushBufferVerts(group, LLVertexBuffer::MAP_VERTEX, false);
+
+ bool selected = false;
+
+ for (LLSpatialGroup::element_iter iter = group->getDataBegin(); iter != group->getDataEnd(); ++iter)
{
- LLVertexBuffer::unbind();
- group->mOcclusionVerts->setBuffer(LLVertexBuffer::MAP_VERTEX);
-
- gGL.diffuseColor4f(1.0f, 0.f, 0.f, 0.5f);
- group->mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, group->mBounds[0]));
- glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
-
- gGL.diffuseColor4f(1.0f, 1.f, 1.f, 1.0f);
- group->mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, group->mBounds[0]));
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
- }*/
+ LLDrawable* drawable = *iter;
+ if (drawable->getVObj().notNull() && drawable->getVObj()->isSelected())
+ {
+ selected = true;
+ break;
+ }
+ }
+
+ if (selected)
+ { //store for rendering occlusion volume as overlay
+
+ if (!group->mSpatialPartition->isBridge())
+ {
+ visible_selected_groups.insert(group);
+ }
+ else
+ {
+ visible_selected_groups.insert(group->mSpatialPartition->asBridge()->getSpatialGroup());
+ }
+ }
}
}
void renderCrossHairs(LLVector3 position, F32 size, LLColor4 color)
{
- gGL.diffuseColor4fv(color.mV);
+ gGL.color4fv(color.mV);
gGL.begin(LLRender::LINES);
{
gGL.vertex3fv((position - LLVector3(size, 0.f, 0.f)).mV);
@@ -2994,19 +3066,24 @@ void renderBoundingBox(LLDrawable* drawable, BOOL set_color = TRUE)
const LLVector4a* ext;
LLVector4a pos, size;
- //render face bounding boxes
- for (S32 i = 0; i < drawable->getNumFaces(); i++)
+ if (drawable->getVOVolume())
{
- LLFace* facep = drawable->getFace(i);
-
- ext = facep->mExtents;
+ //render face bounding boxes
+ for (S32 i = 0; i < drawable->getNumFaces(); i++)
+ {
+ LLFace* facep = drawable->getFace(i);
+ if (facep)
+ {
+ ext = facep->mExtents;
- pos.setAdd(ext[0], ext[1]);
- pos.mul(0.5f);
- size.setSub(ext[1], ext[0]);
- size.mul(0.5f);
+ pos.setAdd(ext[0], ext[1]);
+ pos.mul(0.5f);
+ size.setSub(ext[1], ext[0]);
+ size.mul(0.5f);
- drawBoxOutline(pos,size);
+ drawBoxOutline(pos,size);
+ }
+ }
}
//render drawable bounding box
@@ -3065,9 +3142,9 @@ void renderNormals(LLDrawable* drawablep)
gGL.vertex3fv(face.mPositions[j].getF32ptr());
gGL.vertex3fv(p.getF32ptr());
- if (face.mBinormals)
+ if (face.mTangents)
{
- n.setMul(face.mBinormals[j], scale);
+ n.setMul(face.mTangents[j], scale);
p.setAdd(face.mPositions[j], n);
gGL.diffuseColor4f(0,1,1,1);
@@ -3385,7 +3462,7 @@ void renderPhysicsShape(LLDrawable* drawable, LLVOVolume* volume)
}
else if (type == LLPhysicsShapeBuilderUtil::PhysicsShapeSpecification::SPHERE)
{
- /*LLVolumeParams volume_params;
+ LLVolumeParams volume_params;
volume_params.setType( LL_PCODE_PROFILE_CIRCLE_HALF, LL_PCODE_PATH_CIRCLE );
volume_params.setBeginAndEndS( 0.f, 1.f );
volume_params.setBeginAndEndT( 0.f, 1.f );
@@ -3395,7 +3472,7 @@ void renderPhysicsShape(LLDrawable* drawable, LLVOVolume* volume)
gGL.diffuseColor4fv(color.mV);
pushVerts(sphere);
- LLPrimitive::sVolumeManager->unrefVolume(sphere);*/
+ LLPrimitive::sVolumeManager->unrefVolume(sphere);
}
else if (type == LLPhysicsShapeBuilderUtil::PhysicsShapeSpecification::CYLINDER)
{
@@ -3470,47 +3547,69 @@ void renderPhysicsShape(LLDrawable* drawable, LLVOVolume* volume)
void renderPhysicsShapes(LLSpatialGroup* group)
{
- for (LLSpatialGroup::OctreeNode::const_element_iter i = group->getData().begin(); i != group->getData().end(); ++i)
+ for (LLSpatialGroup::OctreeNode::const_element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)
{
LLDrawable* drawable = *i;
- LLVOVolume* volume = drawable->getVOVolume();
- if (volume && !volume->isAttachment() && volume->getPhysicsShapeType() != LLViewerObject::PHYSICS_SHAPE_NONE )
+
+ if (drawable->isSpatialBridge())
{
- if (!group->mSpatialPartition->isBridge())
+ LLSpatialBridge* bridge = drawable->asPartition()->asBridge();
+
+ if (bridge)
{
gGL.pushMatrix();
- LLVector3 trans = drawable->getRegion()->getOriginAgent();
- gGL.translatef(trans.mV[0], trans.mV[1], trans.mV[2]);
- renderPhysicsShape(drawable, volume);
+ gGL.multMatrix((F32*)bridge->mDrawable->getRenderMatrix().mMatrix);
+ bridge->renderPhysicsShapes();
gGL.popMatrix();
}
- else
- {
- renderPhysicsShape(drawable, volume);
- }
}
else
{
- LLViewerObject* object = drawable->getVObj();
- if (object && object->getPCode() == LLViewerObject::LL_VO_SURFACE_PATCH)
+ LLVOVolume* volume = drawable->getVOVolume();
+ if (volume && !volume->isAttachment() && volume->getPhysicsShapeType() != LLViewerObject::PHYSICS_SHAPE_NONE )
{
- //push face vertices for terrain
- for (S32 i = 0; i < drawable->getNumFaces(); ++i)
+ if (!group->mSpatialPartition->isBridge())
{
- LLFace* face = drawable->getFace(i);
- LLVertexBuffer* buff = face->getVertexBuffer();
- if (buff)
+ gGL.pushMatrix();
+ LLVector3 trans = drawable->getRegion()->getOriginAgent();
+ gGL.translatef(trans.mV[0], trans.mV[1], trans.mV[2]);
+ renderPhysicsShape(drawable, volume);
+ gGL.popMatrix();
+ }
+ else
+ {
+ renderPhysicsShape(drawable, volume);
+ }
+ }
+ else
+ {
+ LLViewerObject* object = drawable->getVObj();
+ if (object && object->getPCode() == LLViewerObject::LL_VO_SURFACE_PATCH)
+ {
+ gGL.pushMatrix();
+ gGL.multMatrix((F32*) object->getRegion()->mRenderMatrix.mMatrix);
+ //push face vertices for terrain
+ for (S32 i = 0; i < drawable->getNumFaces(); ++i)
{
- glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+ LLFace* face = drawable->getFace(i);
+ if (face)
+ {
+ LLVertexBuffer* buff = face->getVertexBuffer();
+ if (buff)
+ {
+ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
- buff->setBuffer(LLVertexBuffer::MAP_VERTEX);
- gGL.diffuseColor3f(0.2f, 0.5f, 0.3f);
- buff->draw(LLRender::TRIANGLES, buff->getNumIndices(), 0);
+ buff->setBuffer(LLVertexBuffer::MAP_VERTEX);
+ gGL.diffuseColor3f(0.2f, 0.5f, 0.3f);
+ buff->draw(LLRender::TRIANGLES, buff->getNumIndices(), 0);
- gGL.diffuseColor3f(0.2f, 1.f, 0.3f);
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
- buff->draw(LLRender::TRIANGLES, buff->getNumIndices(), 0);
+ gGL.diffuseColor3f(0.2f, 1.f, 0.3f);
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ buff->draw(LLRender::TRIANGLES, buff->getNumIndices(), 0);
+ }
+ }
}
+ gGL.popMatrix();
}
}
}
@@ -3533,6 +3632,7 @@ void renderTexturePriority(LLDrawable* drawable)
//LLViewerTexture* imagep = facep->getTexture();
//if (imagep)
+ if (facep)
{
//F32 vsize = imagep->mMaxVirtualSize;
@@ -3563,9 +3663,9 @@ void renderTexturePriority(LLDrawable* drawable)
drawBox(center, size);
/*S32 boost = imagep->getBoostLevel();
- if (boost>LLViewerTexture::BOOST_NONE)
+ if (boost>LLGLTexture::BOOST_NONE)
{
- F32 t = (F32) boost / (F32) (LLViewerTexture::BOOST_MAX_LEVEL-1);
+ F32 t = (F32) boost / (F32) (LLGLTexture::BOOST_MAX_LEVEL-1);
LLVector4 col = lerp(boost_cold, boost_hot, t);
LLGLEnable blend_on(GL_BLEND);
gGL.blendFunc(GL_SRC_ALPHA, GL_ONE);
@@ -3585,7 +3685,11 @@ void renderPoints(LLDrawable* drawablep)
gGL.diffuseColor3f(1,1,1);
for (S32 i = 0; i < drawablep->getNumFaces(); i++)
{
- gGL.vertex3fv(drawablep->getFace(i)->mCenterLocal.mV);
+ LLFace * face = drawablep->getFace(i);
+ if (face)
+ {
+ gGL.vertex3fv(face->mCenterLocal.mV);
+ }
}
gGL.end();
}
@@ -3647,6 +3751,110 @@ void renderShadowFrusta(LLDrawInfo* params)
gGL.setSceneBlendType(LLRender::BT_ALPHA);
}
+void renderTexelDensity(LLDrawable* drawable)
+{
+ if (LLViewerTexture::sDebugTexelsMode == LLViewerTexture::DEBUG_TEXELS_OFF
+ || LLViewerTexture::sCheckerBoardImagep.isNull())
+ {
+ return;
+ }
+
+ LLGLEnable _(GL_BLEND);
+ //gObjectFullbrightProgram.bind();
+
+ LLMatrix4 checkerboard_matrix;
+ S32 discard_level = -1;
+
+ for (S32 f = 0; f < drawable->getNumFaces(); f++)
+ {
+ LLFace* facep = drawable->getFace(f);
+ LLVertexBuffer* buffer = facep->getVertexBuffer();
+ LLViewerTexture* texturep = facep->getTexture();
+
+ if (texturep == NULL) continue;
+
+ switch(LLViewerTexture::sDebugTexelsMode)
+ {
+ case LLViewerTexture::DEBUG_TEXELS_CURRENT:
+ discard_level = -1;
+ break;
+ case LLViewerTexture::DEBUG_TEXELS_DESIRED:
+ {
+ LLViewerFetchedTexture* fetched_texturep = dynamic_cast<LLViewerFetchedTexture*>(texturep);
+ discard_level = fetched_texturep ? fetched_texturep->getDesiredDiscardLevel() : -1;
+ break;
+ }
+ default:
+ case LLViewerTexture::DEBUG_TEXELS_FULL:
+ discard_level = 0;
+ break;
+ }
+
+ checkerboard_matrix.initScale(LLVector3(texturep->getWidth(discard_level) / 8, texturep->getHeight(discard_level) / 8, 1.f));
+
+ gGL.getTexUnit(0)->bind(LLViewerTexture::sCheckerBoardImagep, TRUE);
+ gGL.matrixMode(LLRender::MM_TEXTURE);
+ gGL.loadMatrix((GLfloat*)&checkerboard_matrix.mMatrix);
+
+ if (buffer && (facep->getGeomCount() >= 3))
+ {
+ buffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0);
+ U16 start = facep->getGeomStart();
+ U16 end = start + facep->getGeomCount()-1;
+ U32 count = facep->getIndicesCount();
+ U16 offset = facep->getIndicesStart();
+ buffer->drawRange(LLRender::TRIANGLES, start, end, count, offset);
+ }
+
+ gGL.loadIdentity();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ }
+
+ //S32 num_textures = llmax(1, (S32)params->mTextureList.size());
+
+ //for (S32 i = 0; i < num_textures; i++)
+ //{
+ // LLViewerTexture* texturep = params->mTextureList.empty() ? params->mTexture.get() : params->mTextureList[i].get();
+ // if (texturep == NULL) continue;
+
+ // LLMatrix4 checkboard_matrix;
+ // S32 discard_level = -1;
+ // switch(LLViewerTexture::sDebugTexelsMode)
+ // {
+ // case LLViewerTexture::DEBUG_TEXELS_CURRENT:
+ // discard_level = -1;
+ // break;
+ // case LLViewerTexture::DEBUG_TEXELS_DESIRED:
+ // {
+ // LLViewerFetchedTexture* fetched_texturep = dynamic_cast<LLViewerFetchedTexture*>(texturep);
+ // discard_level = fetched_texturep ? fetched_texturep->getDesiredDiscardLevel() : -1;
+ // break;
+ // }
+ // default:
+ // case LLViewerTexture::DEBUG_TEXELS_FULL:
+ // discard_level = 0;
+ // break;
+ // }
+
+ // checkboard_matrix.initScale(LLVector3(texturep->getWidth(discard_level) / 8, texturep->getHeight(discard_level) / 8, 1.f));
+ // gGL.getTexUnit(i)->activate();
+
+ // glMatrixMode(GL_TEXTURE);
+ // glPushMatrix();
+ // glLoadIdentity();
+ // //gGL.matrixMode(LLRender::MM_TEXTURE);
+ // glLoadMatrixf((GLfloat*) checkboard_matrix.mMatrix);
+
+ // gGL.getTexUnit(i)->bind(LLViewerTexture::sCheckerBoardImagep, TRUE);
+
+ // pushVerts(params, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_NORMAL );
+
+ // glPopMatrix();
+ // glMatrixMode(GL_MODELVIEW);
+ // //gGL.matrixMode(LLRender::MM_MODELVIEW);
+ //}
+}
+
void renderLights(LLDrawable* drawablep)
{
@@ -3662,7 +3870,11 @@ void renderLights(LLDrawable* drawablep)
for (S32 i = 0; i < drawablep->getNumFaces(); i++)
{
- pushVerts(drawablep->getFace(i), LLVertexBuffer::MAP_VERTEX);
+ LLFace * face = drawablep->getFace(i);
+ if (face)
+ {
+ pushVerts(face, LLVertexBuffer::MAP_VERTEX);
+ }
}
const LLVector4a* ext = drawablep->getSpatialExtents();
@@ -3703,7 +3915,7 @@ public:
LLVector3 center, size;
- if (branch->getData().empty())
+ if (branch->isEmpty())
{
gGL.diffuseColor3f(1.f,0.2f,0.f);
center.set(branch->getCenter().getF32ptr());
@@ -3739,8 +3951,8 @@ public:
}
gGL.begin(LLRender::TRIANGLES);
- for (LLOctreeNode<LLVolumeTriangle>::const_element_iter iter = branch->getData().begin();
- iter != branch->getData().end();
+ for (LLOctreeNode<LLVolumeTriangle>::const_element_iter iter = branch->getDataBegin();
+ iter != branch->getDataEnd();
++iter)
{
const LLVolumeTriangle* tri = *iter;
@@ -3795,11 +4007,17 @@ void renderRaycast(LLDrawable* drawablep)
gGL.translatef(trans.mV[0], trans.mV[1], trans.mV[2]);
gGL.multMatrix((F32*) vobj->getRelativeXform().mMatrix);
- LLVector3 start, end;
+ LLVector4a start, end;
if (transform)
{
- start = vobj->agentPositionToVolume(gDebugRaycastStart);
- end = vobj->agentPositionToVolume(gDebugRaycastEnd);
+ LLVector3 v_start(gDebugRaycastStart.getF32ptr());
+ LLVector3 v_end(gDebugRaycastEnd.getF32ptr());
+
+ v_start = vobj->agentPositionToVolume(v_start);
+ v_end = vobj->agentPositionToVolume(v_end);
+
+ start.load3(v_start.mV);
+ end.load3(v_end.mV);
}
else
{
@@ -3807,11 +4025,8 @@ void renderRaycast(LLDrawable* drawablep)
end = gDebugRaycastEnd;
}
- LLVector4a starta, enda;
- starta.load3(start.mV);
- enda.load3(end.mV);
LLVector4a dir;
- dir.setSub(enda, starta);
+ dir.setSub(end, start);
gGL.flush();
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
@@ -3834,7 +4049,7 @@ void renderRaycast(LLDrawable* drawablep)
((LLVolumeFace*) &face)->createOctree();
}
- LLRenderOctreeRaycast render(starta, dir, &t);
+ LLRenderOctreeRaycast render(start, dir, &t);
render.traverse(face.mOctree);
}
@@ -3859,10 +4074,18 @@ void renderRaycast(LLDrawable* drawablep)
// draw intersection point
gGL.pushMatrix();
gGL.loadMatrix(gGLModelView);
- LLVector3 translate = gDebugRaycastIntersection;
+ LLVector3 translate(gDebugRaycastIntersection.getF32ptr());
gGL.translatef(translate.mV[0], translate.mV[1], translate.mV[2]);
LLCoordFrame orient;
- orient.lookDir(gDebugRaycastNormal, gDebugRaycastBinormal);
+ LLVector4a debug_binormal;
+
+ debug_binormal.setCross3(gDebugRaycastNormal, gDebugRaycastTangent);
+ debug_binormal.mul(gDebugRaycastTangent.getF32ptr()[3]);
+
+ LLVector3 normal(gDebugRaycastNormal.getF32ptr());
+ LLVector3 binormal(debug_binormal.getF32ptr());
+
+ orient.lookDir(normal, binormal);
LLMatrix4 rotation;
orient.getRotMatrixToParent(rotation);
gGL.multMatrix((float*)rotation.mMatrix);
@@ -3904,8 +4127,8 @@ void renderAgentTarget(LLVOAvatar* avatar)
if (avatar->isSelf())
{
renderCrossHairs(avatar->getPositionAgent(), 0.2f, LLColor4(1, 0, 0, 0.8f));
- renderCrossHairs(avatar->mDrawable->getPositionAgent(), 0.2f, LLColor4(1, 0, 0, 0.8f));
- renderCrossHairs(avatar->mRoot.getWorldPosition(), 0.2f, LLColor4(1, 1, 1, 0.8f));
+ renderCrossHairs(avatar->mDrawable->getPositionAgent(), 0.2f, LLColor4(0, 1, 0, 0.8f));
+ renderCrossHairs(avatar->mRoot->getWorldPosition(), 0.2f, LLColor4(1, 1, 1, 0.8f));
renderCrossHairs(avatar->mPelvisp->getWorldPosition(), 0.2f, LLColor4(0, 0, 1, 0.8f));
}
}
@@ -3969,23 +4192,24 @@ public:
return;
}
- LLVector4a nodeCenter = group->mBounds[0];
- LLVector4a octCenter = group->mOctreeNode->getCenter();
-
group->rebuildGeom();
group->rebuildMesh();
if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_BBOXES))
{
- if (!group->getData().empty())
+ if (!group->isEmpty())
{
gGL.diffuseColor3f(0,0,1);
+
+ llassert(group->mObjectBounds[0].isFinite3());
+ llassert(group->mObjectBounds[1].isFinite3());
+
drawBoxOutline(group->mObjectBounds[0],
group->mObjectBounds[1]);
}
}
- for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getData().begin(); i != branch->getData().end(); ++i)
+ for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i)
{
LLDrawable* drawable = *i;
@@ -4042,6 +4266,10 @@ public:
{
renderComplexityDisplay(drawable);
}
+ if(gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY))
+ {
+ renderTexelDensity(drawable);
+ }
LLVOAvatar* avatar = dynamic_cast<LLVOAvatar*>(drawable->getVObj().get());
@@ -4060,18 +4288,21 @@ public:
for (U32 i = 0; i < drawable->getNumFaces(); ++i)
{
LLFace* facep = drawable->getFace(i);
- U8 index = facep->getTextureIndex();
- if (facep->mDrawInfo)
+ if (facep)
{
- if (index < 255)
+ U8 index = facep->getTextureIndex();
+ if (facep->mDrawInfo)
{
- if (facep->mDrawInfo->mTextureList.size() <= index)
+ if (index < 255)
{
- llerrs << "Face texture index out of bounds." << llendl;
- }
- else if (facep->mDrawInfo->mTextureList[index] != facep->getTexture())
- {
- llerrs << "Face texture index incorrect." << llendl;
+ if (facep->mDrawInfo->mTextureList.size() <= index)
+ {
+ llerrs << "Face texture index out of bounds." << llendl;
+ }
+ else if (facep->mDrawInfo->mTextureList[index] != facep->getTexture())
+ {
+ llerrs << "Face texture index incorrect." << llendl;
+ }
}
}
}
@@ -4102,6 +4333,48 @@ public:
}
};
+class LLOctreeRenderXRay : public LLOctreeTraveler<LLDrawable>
+{
+public:
+ LLCamera* mCamera;
+ LLOctreeRenderXRay(LLCamera* camera): mCamera(camera) {}
+
+ virtual void traverse(const LLSpatialGroup::OctreeNode* node)
+ {
+ LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0);
+
+ if (!mCamera || mCamera->AABBInFrustumNoFarClip(group->mBounds[0], group->mBounds[1]))
+ {
+ node->accept(this);
+ stop_glerror();
+
+ for (U32 i = 0; i < node->getChildCount(); i++)
+ {
+ traverse(node->getChild(i));
+ stop_glerror();
+ }
+
+ //render visibility wireframe
+ if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCCLUSION))
+ {
+ group->rebuildGeom();
+ group->rebuildMesh();
+
+ gGL.flush();
+ gGL.pushMatrix();
+ gGLLastMatrix = NULL;
+ gGL.loadMatrix(gGLModelView);
+ renderXRay(group, mCamera);
+ stop_glerror();
+ gGLLastMatrix = NULL;
+ gGL.popMatrix();
+ }
+ }
+ }
+
+ virtual void visit(const LLSpatialGroup::OctreeNode* node) {}
+
+};
class LLOctreeRenderPhysicsShapes : public LLOctreeTraveler<LLDrawable>
{
@@ -4167,7 +4440,7 @@ public:
return;
}
- for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getData().begin(); i != branch->getData().end(); ++i)
+ for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i)
{
LLDrawable* drawable = *i;
@@ -4291,7 +4564,8 @@ void LLSpatialPartition::renderDebug()
LLPipeline::RENDER_DEBUG_AGENT_TARGET |
//LLPipeline::RENDER_DEBUG_BUILD_QUEUE |
LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA |
- LLPipeline::RENDER_DEBUG_RENDER_COMPLEXITY))
+ LLPipeline::RENDER_DEBUG_RENDER_COMPLEXITY |
+ LLPipeline::RENDER_DEBUG_TEXEL_DENSITY))
{
return;
}
@@ -4308,8 +4582,6 @@ void LLSpatialPartition::renderDebug()
sCurMaxTexPriority = 0.f;
}
- LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
-
LLGLDisable cullface(GL_CULL_FACE);
LLGLEnable blend(GL_BLEND);
gGL.setSceneBlendType(LLRender::BT_ALPHA);
@@ -4330,6 +4602,26 @@ void LLSpatialPartition::renderDebug()
LLOctreeRenderNonOccluded render_debug(camera);
render_debug.traverse(mOctree);
+
+ if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCCLUSION))
+ {
+ {
+ LLGLEnable cull(GL_CULL_FACE);
+
+ LLGLEnable blend(GL_BLEND);
+ LLGLDepthTest depth_under(GL_TRUE, GL_FALSE, GL_GREATER);
+ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+ gGL.diffuseColor4f(0.5f, 0.0f, 0, 0.25f);
+
+ LLGLEnable offset(GL_POLYGON_OFFSET_LINE);
+ glPolygonOffset(-1.f, -1.f);
+
+ LLOctreeRenderXRay xray(camera);
+ xray.traverse(mOctree);
+
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ }
+ }
if (LLGLSLShader::sNoFixedFunction)
{
gDebugProgram.unbind();
@@ -4361,28 +4653,30 @@ BOOL LLSpatialPartition::isVisible(const LLVector3& v)
return TRUE;
}
+LL_ALIGN_PREFIX(16)
class LLOctreeIntersect : public LLSpatialGroup::OctreeTraveler
{
public:
- LLVector3 mStart;
- LLVector3 mEnd;
+ LL_ALIGN_16(LLVector4a mStart);
+ LL_ALIGN_16(LLVector4a mEnd);
+
S32 *mFaceHit;
- LLVector3 *mIntersection;
+ LLVector4a *mIntersection;
LLVector2 *mTexCoord;
- LLVector3 *mNormal;
- LLVector3 *mBinormal;
+ LLVector4a *mNormal;
+ LLVector4a *mTangent;
LLDrawable* mHit;
BOOL mPickTransparent;
- LLOctreeIntersect(LLVector3 start, LLVector3 end, BOOL pick_transparent,
- S32* face_hit, LLVector3* intersection, LLVector2* tex_coord, LLVector3* normal, LLVector3* binormal)
+ LLOctreeIntersect(const LLVector4a& start, const LLVector4a& end, BOOL pick_transparent,
+ S32* face_hit, LLVector4a* intersection, LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent)
: mStart(start),
mEnd(end),
mFaceHit(face_hit),
mIntersection(intersection),
mTexCoord(tex_coord),
mNormal(normal),
- mBinormal(binormal),
+ mTangent(tangent),
mHit(NULL),
mPickTransparent(pick_transparent)
{
@@ -4390,7 +4684,7 @@ public:
virtual void visit(const LLSpatialGroup::OctreeNode* branch)
{
- for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getData().begin(); i != branch->getData().end(); ++i)
+ for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i)
{
check(*i);
}
@@ -4413,23 +4707,22 @@ public:
size = group->mBounds[1];
center = group->mBounds[0];
- LLVector3 local_start = mStart;
- LLVector3 local_end = mEnd;
+ LLVector4a local_start = mStart;
+ LLVector4a local_end = mEnd;
if (group->mSpatialPartition->isBridge())
{
LLMatrix4 local_matrix = group->mSpatialPartition->asBridge()->mDrawable->getRenderMatrix();
local_matrix.invert();
-
- local_start = mStart * local_matrix;
- local_end = mEnd * local_matrix;
- }
- LLVector4a start, end;
- start.load3(local_start.mV);
- end.load3(local_end.mV);
+ LLMatrix4a local_matrix4a;
+ local_matrix4a.loadu(local_matrix);
+
+ local_matrix4a.affineTransform(mStart, local_start);
+ local_matrix4a.affineTransform(mEnd, local_end);
+ }
- if (LLLineSegmentBoxIntersect(start, end, center, size))
+ if (LLLineSegmentBoxIntersect(local_start, local_end, center, size))
{
check(child);
}
@@ -4440,9 +4733,6 @@ public:
virtual bool check(LLDrawable* drawable)
{
- LLVector3 local_start = mStart;
- LLVector3 local_end = mEnd;
-
if (!drawable || !gPipeline.hasRenderType(drawable->getRenderType()) || !drawable->isVisible())
{
return false;
@@ -4463,14 +4753,14 @@ public:
if (vobj)
{
- LLVector3 intersection;
+ LLVector4a intersection;
bool skip_check = false;
if (vobj->isAvatar())
{
LLVOAvatar* avatar = (LLVOAvatar*) vobj;
if (avatar->isSelf() && LLFloater::isVisible(gFloaterTools))
{
- LLViewerObject* hit = avatar->lineSegmentIntersectRiggedAttachments(mStart, mEnd, -1, mPickTransparent, mFaceHit, &intersection, mTexCoord, mNormal, mBinormal);
+ LLViewerObject* hit = avatar->lineSegmentIntersectRiggedAttachments(mStart, mEnd, -1, mPickTransparent, mFaceHit, &intersection, mTexCoord, mNormal, mTangent);
if (hit)
{
mEnd = intersection;
@@ -4486,7 +4776,7 @@ public:
}
}
- if (!skip_check && vobj->lineSegmentIntersect(mStart, mEnd, -1, mPickTransparent, mFaceHit, &intersection, mTexCoord, mNormal, mBinormal))
+ if (!skip_check && vobj->lineSegmentIntersect(mStart, mEnd, -1, mPickTransparent, mFaceHit, &intersection, mTexCoord, mNormal, mTangent))
{
mEnd = intersection; // shorten ray so we only find CLOSER hits
if (mIntersection)
@@ -4501,19 +4791,19 @@ public:
return false;
}
-};
+} LL_ALIGN_POSTFIX(16);
-LLDrawable* LLSpatialPartition::lineSegmentIntersect(const LLVector3& start, const LLVector3& end,
+LLDrawable* LLSpatialPartition::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
BOOL pick_transparent,
S32* face_hit, // return the face hit
- LLVector3* intersection, // return the intersection point
+ LLVector4a* intersection, // return the intersection point
LLVector2* tex_coord, // return the texture coordinates of the intersection point
- LLVector3* normal, // return the surface normal at the intersection point
- LLVector3* bi_normal // return the surface bi-normal at the intersection point
+ LLVector4a* normal, // return the surface normal at the intersection point
+ LLVector4a* tangent // return the surface tangent at the intersection point
)
{
- LLOctreeIntersect intersect(start, end, pick_transparent, face_hit, intersection, tex_coord, normal, bi_normal);
+ LLOctreeIntersect intersect(start, end, pick_transparent, face_hit, intersection, tex_coord, normal, tangent);
LLDrawable* drawable = intersect.check(mOctree);
return drawable;
@@ -4539,7 +4829,16 @@ LLDrawInfo::LLDrawInfo(U16 start, U16 end, U32 count, U32 offset,
mGroup(NULL),
mFace(NULL),
mDistance(0.f),
- mDrawMode(LLRender::TRIANGLES)
+ mDrawMode(LLRender::TRIANGLES),
+ mMaterial(NULL),
+ mShaderMask(0),
+ mSpecColor(1.0f, 1.0f, 1.0f, 0.5f),
+ mBlendFuncSrc(LLRender::BF_SOURCE_ALPHA),
+ mBlendFuncDst(LLRender::BF_ONE_MINUS_SOURCE_ALPHA),
+ mHasGlow(FALSE),
+ mEnvIntensity(0.0f),
+ mAlphaMaskCutoff(0.5f),
+ mDiffuseAlphaMode(0)
{
mVertexBuffer->validateRange(mStart, mEnd, mCount, mOffset);
@@ -4576,28 +4875,70 @@ LLVertexBuffer* LLGeometryManager::createVertexBuffer(U32 type_mask, U32 usage)
LLCullResult::LLCullResult()
{
+ mVisibleGroupsAllocated = 0;
+ mAlphaGroupsAllocated = 0;
+ mOcclusionGroupsAllocated = 0;
+ mDrawableGroupsAllocated = 0;
+ mVisibleListAllocated = 0;
+ mVisibleBridgeAllocated = 0;
+
+ mVisibleGroups.clear();
+ mVisibleGroups.push_back(NULL);
+ mVisibleGroupsEnd = &mVisibleGroups[0];
+ mAlphaGroups.clear();
+ mAlphaGroups.push_back(NULL);
+ mAlphaGroupsEnd = &mAlphaGroups[0];
+ mOcclusionGroups.clear();
+ mOcclusionGroups.push_back(NULL);
+ mOcclusionGroupsEnd = &mOcclusionGroups[0];
+ mDrawableGroups.clear();
+ mDrawableGroups.push_back(NULL);
+ mDrawableGroupsEnd = &mDrawableGroups[0];
+ mVisibleList.clear();
+ mVisibleList.push_back(NULL);
+ mVisibleListEnd = &mVisibleList[0];
+ mVisibleBridge.clear();
+ mVisibleBridge.push_back(NULL);
+ mVisibleBridgeEnd = &mVisibleBridge[0];
+
+ for (U32 i = 0; i < LLRenderPass::NUM_RENDER_TYPES; i++)
+ {
+ mRenderMap[i].clear();
+ mRenderMap[i].push_back(NULL);
+ mRenderMapEnd[i] = &mRenderMap[i][0];
+ mRenderMapAllocated[i] = 0;
+ }
+
clear();
}
+template <class T, class V>
+void LLCullResult::pushBack(T& head, U32& count, V* val)
+{
+ head[count] = val;
+ head.push_back(NULL);
+ count++;
+}
+
void LLCullResult::clear()
{
mVisibleGroupsSize = 0;
- mVisibleGroupsEnd = mVisibleGroups.begin();
+ mVisibleGroupsEnd = &mVisibleGroups[0];
mAlphaGroupsSize = 0;
- mAlphaGroupsEnd = mAlphaGroups.begin();
+ mAlphaGroupsEnd = &mAlphaGroups[0];
mOcclusionGroupsSize = 0;
- mOcclusionGroupsEnd = mOcclusionGroups.begin();
+ mOcclusionGroupsEnd = &mOcclusionGroups[0];
mDrawableGroupsSize = 0;
- mDrawableGroupsEnd = mDrawableGroups.begin();
+ mDrawableGroupsEnd = &mDrawableGroups[0];
mVisibleListSize = 0;
- mVisibleListEnd = mVisibleList.begin();
+ mVisibleListEnd = &mVisibleList[0];
mVisibleBridgeSize = 0;
- mVisibleBridgeEnd = mVisibleBridge.begin();
+ mVisibleBridgeEnd = &mVisibleBridge[0];
for (U32 i = 0; i < LLRenderPass::NUM_RENDER_TYPES; i++)
@@ -4607,176 +4948,176 @@ void LLCullResult::clear()
mRenderMap[i][j] = 0;
}
mRenderMapSize[i] = 0;
- mRenderMapEnd[i] = mRenderMap[i].begin();
+ mRenderMapEnd[i] = &(mRenderMap[i][0]);
}
}
-LLCullResult::sg_list_t::iterator LLCullResult::beginVisibleGroups()
+LLCullResult::sg_iterator LLCullResult::beginVisibleGroups()
{
- return mVisibleGroups.begin();
+ return &mVisibleGroups[0];
}
-LLCullResult::sg_list_t::iterator LLCullResult::endVisibleGroups()
+LLCullResult::sg_iterator LLCullResult::endVisibleGroups()
{
return mVisibleGroupsEnd;
}
-LLCullResult::sg_list_t::iterator LLCullResult::beginAlphaGroups()
+LLCullResult::sg_iterator LLCullResult::beginAlphaGroups()
{
- return mAlphaGroups.begin();
+ return &mAlphaGroups[0];
}
-LLCullResult::sg_list_t::iterator LLCullResult::endAlphaGroups()
+LLCullResult::sg_iterator LLCullResult::endAlphaGroups()
{
return mAlphaGroupsEnd;
}
-LLCullResult::sg_list_t::iterator LLCullResult::beginOcclusionGroups()
+LLCullResult::sg_iterator LLCullResult::beginOcclusionGroups()
{
- return mOcclusionGroups.begin();
+ return &mOcclusionGroups[0];
}
-LLCullResult::sg_list_t::iterator LLCullResult::endOcclusionGroups()
+LLCullResult::sg_iterator LLCullResult::endOcclusionGroups()
{
return mOcclusionGroupsEnd;
}
-LLCullResult::sg_list_t::iterator LLCullResult::beginDrawableGroups()
+LLCullResult::sg_iterator LLCullResult::beginDrawableGroups()
{
- return mDrawableGroups.begin();
+ return &mDrawableGroups[0];
}
-LLCullResult::sg_list_t::iterator LLCullResult::endDrawableGroups()
+LLCullResult::sg_iterator LLCullResult::endDrawableGroups()
{
return mDrawableGroupsEnd;
}
-LLCullResult::drawable_list_t::iterator LLCullResult::beginVisibleList()
+LLCullResult::drawable_iterator LLCullResult::beginVisibleList()
{
- return mVisibleList.begin();
+ return &mVisibleList[0];
}
-LLCullResult::drawable_list_t::iterator LLCullResult::endVisibleList()
+LLCullResult::drawable_iterator LLCullResult::endVisibleList()
{
return mVisibleListEnd;
}
-LLCullResult::bridge_list_t::iterator LLCullResult::beginVisibleBridge()
+LLCullResult::bridge_iterator LLCullResult::beginVisibleBridge()
{
- return mVisibleBridge.begin();
+ return &mVisibleBridge[0];
}
-LLCullResult::bridge_list_t::iterator LLCullResult::endVisibleBridge()
+LLCullResult::bridge_iterator LLCullResult::endVisibleBridge()
{
return mVisibleBridgeEnd;
}
-LLCullResult::drawinfo_list_t::iterator LLCullResult::beginRenderMap(U32 type)
+LLCullResult::drawinfo_iterator LLCullResult::beginRenderMap(U32 type)
{
- return mRenderMap[type].begin();
+ return &mRenderMap[type][0];
}
-LLCullResult::drawinfo_list_t::iterator LLCullResult::endRenderMap(U32 type)
+LLCullResult::drawinfo_iterator LLCullResult::endRenderMap(U32 type)
{
return mRenderMapEnd[type];
}
void LLCullResult::pushVisibleGroup(LLSpatialGroup* group)
{
- if (mVisibleGroupsSize < mVisibleGroups.size())
+ if (mVisibleGroupsSize < mVisibleGroupsAllocated)
{
mVisibleGroups[mVisibleGroupsSize] = group;
}
else
{
- mVisibleGroups.push_back(group);
+ pushBack(mVisibleGroups, mVisibleGroupsAllocated, group);
}
++mVisibleGroupsSize;
- mVisibleGroupsEnd = mVisibleGroups.begin()+mVisibleGroupsSize;
+ mVisibleGroupsEnd = &mVisibleGroups[mVisibleGroupsSize];
}
void LLCullResult::pushAlphaGroup(LLSpatialGroup* group)
{
- if (mAlphaGroupsSize < mAlphaGroups.size())
+ if (mAlphaGroupsSize < mAlphaGroupsAllocated)
{
mAlphaGroups[mAlphaGroupsSize] = group;
}
else
{
- mAlphaGroups.push_back(group);
+ pushBack(mAlphaGroups, mAlphaGroupsAllocated, group);
}
++mAlphaGroupsSize;
- mAlphaGroupsEnd = mAlphaGroups.begin()+mAlphaGroupsSize;
+ mAlphaGroupsEnd = &mAlphaGroups[mAlphaGroupsSize];
}
void LLCullResult::pushOcclusionGroup(LLSpatialGroup* group)
{
- if (mOcclusionGroupsSize < mOcclusionGroups.size())
+ if (mOcclusionGroupsSize < mOcclusionGroupsAllocated)
{
mOcclusionGroups[mOcclusionGroupsSize] = group;
}
else
{
- mOcclusionGroups.push_back(group);
+ pushBack(mOcclusionGroups, mOcclusionGroupsAllocated, group);
}
++mOcclusionGroupsSize;
- mOcclusionGroupsEnd = mOcclusionGroups.begin()+mOcclusionGroupsSize;
+ mOcclusionGroupsEnd = &mOcclusionGroups[mOcclusionGroupsSize];
}
void LLCullResult::pushDrawableGroup(LLSpatialGroup* group)
{
- if (mDrawableGroupsSize < mDrawableGroups.size())
+ if (mDrawableGroupsSize < mDrawableGroupsAllocated)
{
mDrawableGroups[mDrawableGroupsSize] = group;
}
else
{
- mDrawableGroups.push_back(group);
+ pushBack(mDrawableGroups, mDrawableGroupsAllocated, group);
}
++mDrawableGroupsSize;
- mDrawableGroupsEnd = mDrawableGroups.begin()+mDrawableGroupsSize;
+ mDrawableGroupsEnd = &mDrawableGroups[mDrawableGroupsSize];
}
void LLCullResult::pushDrawable(LLDrawable* drawable)
{
- if (mVisibleListSize < mVisibleList.size())
+ if (mVisibleListSize < mVisibleListAllocated)
{
mVisibleList[mVisibleListSize] = drawable;
}
else
{
- mVisibleList.push_back(drawable);
+ pushBack(mVisibleList, mVisibleListAllocated, drawable);
}
++mVisibleListSize;
- mVisibleListEnd = mVisibleList.begin()+mVisibleListSize;
+ mVisibleListEnd = &mVisibleList[mVisibleListSize];
}
void LLCullResult::pushBridge(LLSpatialBridge* bridge)
{
- if (mVisibleBridgeSize < mVisibleBridge.size())
+ if (mVisibleBridgeSize < mVisibleBridgeAllocated)
{
mVisibleBridge[mVisibleBridgeSize] = bridge;
}
else
{
- mVisibleBridge.push_back(bridge);
+ pushBack(mVisibleBridge, mVisibleBridgeAllocated, bridge);
}
++mVisibleBridgeSize;
- mVisibleBridgeEnd = mVisibleBridge.begin()+mVisibleBridgeSize;
+ mVisibleBridgeEnd = &mVisibleBridge[mVisibleBridgeSize];
}
void LLCullResult::pushDrawInfo(U32 type, LLDrawInfo* draw_info)
{
- if (mRenderMapSize[type] < mRenderMap[type].size())
+ if (mRenderMapSize[type] < mRenderMapAllocated[type])
{
mRenderMap[type][mRenderMapSize[type]] = draw_info;
}
else
{
- mRenderMap[type].push_back(draw_info);
+ pushBack(mRenderMap[type], mRenderMapAllocated[type], draw_info);
}
++mRenderMapSize[type];
- mRenderMapEnd[type] = mRenderMap[type].begin() + mRenderMapSize[type];
+ mRenderMapEnd[type] = &(mRenderMap[type][mRenderMapSize[type]]);
}
diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h
index 6c14ecf452..f26defd5e1 100644..100755
--- a/indra/newview/llspatialpartition.h
+++ b/indra/newview/llspatialpartition.h
@@ -68,6 +68,16 @@ protected:
~LLDrawInfo();
public:
+ void* operator new(size_t size)
+ {
+ return ll_aligned_malloc(size,64);
+ }
+
+ void operator delete(void* ptr)
+ {
+ ll_aligned_free(ptr);
+ }
+
LLDrawInfo(const LLDrawInfo& rhs)
{
@@ -102,13 +112,29 @@ public:
U32 mOffset;
BOOL mFullbright;
U8 mBump;
+ U8 mShiny;
BOOL mParticle;
F32 mPartSize;
F32 mVSize;
LLSpatialGroup* mGroup;
- LLFace* mFace; //associated face
+ LL_ALIGN_16(LLFace* mFace); //associated face
F32 mDistance;
U32 mDrawMode;
+ LLMaterialPtr mMaterial; // If this is null, the following parameters are unused.
+ LLMaterialID mMaterialID;
+ U32 mShaderMask;
+ U32 mBlendFuncSrc;
+ U32 mBlendFuncDst;
+ BOOL mHasGlow;
+ LLPointer<LLViewerTexture> mSpecularMap;
+ const LLMatrix4* mSpecularMapMatrix;
+ LLPointer<LLViewerTexture> mNormalMap;
+ const LLMatrix4* mNormalMapMatrix;
+ LLVector4 mSpecColor; // XYZ = Specular RGB, W = Specular Exponent
+ F32 mEnvIntensity;
+ F32 mAlphaMaskCutoff;
+ U8 mDiffuseAlphaMode;
+
struct CompareTexture
{
@@ -159,7 +185,7 @@ public:
}
};
-
+
struct CompareBump
{
bool operator()(const LLPointer<LLDrawInfo>& lhs, const LLPointer<LLDrawInfo>& rhs)
@@ -193,6 +219,16 @@ public:
*this = rhs;
}
+ void* operator new(size_t size)
+ {
+ return ll_aligned_malloc_16(size);
+ }
+
+ void operator delete(void* ptr)
+ {
+ ll_aligned_free_16(ptr);
+ }
+
const LLSpatialGroup& operator=(const LLSpatialGroup& rhs)
{
llerrs << "Illegal operation!" << llendl;
@@ -263,11 +299,10 @@ public:
SKIP_FRUSTUM_CHECK = 0x00000020,
IN_IMAGE_QUEUE = 0x00000040,
IMAGE_DIRTY = 0x00000080,
- OCCLUSION_DIRTY = 0x00000100,
- MESH_DIRTY = 0x00000200,
- NEW_DRAWINFO = 0x00000400,
- IN_BUILD_Q1 = 0x00000800,
- IN_BUILD_Q2 = 0x00001000,
+ MESH_DIRTY = 0x00000100,
+ NEW_DRAWINFO = 0x00000200,
+ IN_BUILD_Q1 = 0x00000400,
+ IN_BUILD_Q2 = 0x00000800,
STATE_MASK = 0x0000FFFF,
} eSpatialState;
@@ -313,10 +348,9 @@ public:
BOOL boundObjects(BOOL empty, LLVector4a& newMin, LLVector4a& newMax);
void unbound();
BOOL rebound();
- void buildOcclusion(); //rebuild mOcclusionVerts
void checkOcclusion(); //read back last occlusion query (if any)
void doOcclusion(LLCamera* camera); //issue occlusion query
- void destroyGL();
+ void destroyGL(bool keep_occlusion = false);
void updateDistance(LLCamera& camera);
BOOL needsUpdate();
@@ -327,8 +361,15 @@ public:
void dirtyGeom() { setState(GEOM_DIRTY); }
void dirtyMesh() { setState(MESH_DIRTY); }
+
+ //octree wrappers to make code more readable
element_list& getData() { return mOctreeNode->getData(); }
+ element_iter getDataBegin() { return mOctreeNode->getDataBegin(); }
+ element_iter getDataEnd() { return mOctreeNode->getDataEnd(); }
+ bool hasElement(LLDrawable* drawablep) { return std::find(mOctreeNode->getDataBegin(), mOctreeNode->getDataEnd(), drawablep) != mOctreeNode->getDataEnd(); }
+
U32 getElementCount() const { return mOctreeNode->getElementCount(); }
+ bool isEmpty() const { return mOctreeNode->isEmpty(); }
void drawObjectBox(LLColor4 col);
@@ -372,12 +413,14 @@ public:
V4_COUNT = 10
} eV4Index;
- LLVector4a mBounds[2]; // bounding box (center, size) of this node and all its children (tight fit to objects)
- LLVector4a mExtents[2]; // extents (min, max) of this node and all its children
- LLVector4a mObjectExtents[2]; // extents (min, max) of objects in this node
- LLVector4a mObjectBounds[2]; // bounding box (center, size) of objects in this node
- LLVector4a mViewAngle;
- LLVector4a mLastUpdateViewAngle;
+ LL_ALIGN_16(LLVector4a mBounds[2]); // bounding box (center, size) of this node and all its children (tight fit to objects)
+ LL_ALIGN_16(LLVector4a mExtents[2]); // extents (min, max) of this node and all its children
+ LL_ALIGN_16(LLVector4a mObjectExtents[2]); // extents (min, max) of objects in this node
+ LL_ALIGN_16(LLVector4a mObjectBounds[2]); // bounding box (center, size) of objects in this node
+ LL_ALIGN_16(LLVector4a mViewAngle);
+ LL_ALIGN_16(LLVector4a mLastUpdateViewAngle);
+
+ F32 mObjectBoxSize; //cached mObjectBounds[1].getLength3()
private:
U32 mCurUpdatingTime ;
@@ -413,7 +456,6 @@ public:
LLSpatialPartition* mSpatialPartition;
LLPointer<LLVertexBuffer> mVertexBuffer;
- LLPointer<LLVertexBuffer> mOcclusionVerts;
GLuint mOcclusionQuery[LLViewerCamera::NUM_CAMERAS];
U32 mBufferUsage;
@@ -451,13 +493,13 @@ public:
LLSpatialGroup *put(LLDrawable *drawablep, BOOL was_visible = FALSE);
BOOL remove(LLDrawable *drawablep, LLSpatialGroup *curp);
- LLDrawable* lineSegmentIntersect(const LLVector3& start, const LLVector3& end,
+ LLDrawable* lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
BOOL pick_transparent,
S32* face_hit, // return the face hit
- LLVector3* intersection = NULL, // return the intersection point
+ LLVector4a* intersection = NULL, // return the intersection point
LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
- LLVector3* normal = NULL, // return the surface normal at the intersection point
- LLVector3* bi_normal = NULL // return the surface bi-normal at the intersection point
+ LLVector4a* normal = NULL, // return the surface normal at the intersection point
+ LLVector4a* tangent = NULL // return the surface tangent at the intersection point
);
@@ -548,29 +590,34 @@ public:
typedef std::vector<LLSpatialBridge*> bridge_list_t;
typedef std::vector<LLDrawInfo*> drawinfo_list_t;
+ typedef LLSpatialGroup** sg_iterator;
+ typedef LLSpatialBridge** bridge_iterator;
+ typedef LLDrawInfo** drawinfo_iterator;
+ typedef LLDrawable** drawable_iterator;
+
void clear();
- sg_list_t::iterator beginVisibleGroups();
- sg_list_t::iterator endVisibleGroups();
+ sg_iterator beginVisibleGroups();
+ sg_iterator endVisibleGroups();
- sg_list_t::iterator beginAlphaGroups();
- sg_list_t::iterator endAlphaGroups();
+ sg_iterator beginAlphaGroups();
+ sg_iterator endAlphaGroups();
bool hasOcclusionGroups() { return mOcclusionGroupsSize > 0; }
- sg_list_t::iterator beginOcclusionGroups();
- sg_list_t::iterator endOcclusionGroups();
+ sg_iterator beginOcclusionGroups();
+ sg_iterator endOcclusionGroups();
- sg_list_t::iterator beginDrawableGroups();
- sg_list_t::iterator endDrawableGroups();
+ sg_iterator beginDrawableGroups();
+ sg_iterator endDrawableGroups();
- drawable_list_t::iterator beginVisibleList();
- drawable_list_t::iterator endVisibleList();
+ drawable_iterator beginVisibleList();
+ drawable_iterator endVisibleList();
- bridge_list_t::iterator beginVisibleBridge();
- bridge_list_t::iterator endVisibleBridge();
+ bridge_iterator beginVisibleBridge();
+ bridge_iterator endVisibleBridge();
- drawinfo_list_t::iterator beginRenderMap(U32 type);
- drawinfo_list_t::iterator endRenderMap(U32 type);
+ drawinfo_iterator beginRenderMap(U32 type);
+ drawinfo_iterator endRenderMap(U32 type);
void pushVisibleGroup(LLSpatialGroup* group);
void pushAlphaGroup(LLSpatialGroup* group);
@@ -590,28 +637,41 @@ public:
void assertDrawMapsEmpty();
private:
+
+ template <class T, class V> void pushBack(T &head, U32& count, V* val);
+
U32 mVisibleGroupsSize;
U32 mAlphaGroupsSize;
U32 mOcclusionGroupsSize;
U32 mDrawableGroupsSize;
U32 mVisibleListSize;
U32 mVisibleBridgeSize;
+
+ U32 mVisibleGroupsAllocated;
+ U32 mAlphaGroupsAllocated;
+ U32 mOcclusionGroupsAllocated;
+ U32 mDrawableGroupsAllocated;
+ U32 mVisibleListAllocated;
+ U32 mVisibleBridgeAllocated;
+
U32 mRenderMapSize[LLRenderPass::NUM_RENDER_TYPES];
sg_list_t mVisibleGroups;
- sg_list_t::iterator mVisibleGroupsEnd;
+ sg_iterator mVisibleGroupsEnd;
sg_list_t mAlphaGroups;
- sg_list_t::iterator mAlphaGroupsEnd;
+ sg_iterator mAlphaGroupsEnd;
sg_list_t mOcclusionGroups;
- sg_list_t::iterator mOcclusionGroupsEnd;
+ sg_iterator mOcclusionGroupsEnd;
sg_list_t mDrawableGroups;
- sg_list_t::iterator mDrawableGroupsEnd;
+ sg_iterator mDrawableGroupsEnd;
drawable_list_t mVisibleList;
- drawable_list_t::iterator mVisibleListEnd;
+ drawable_iterator mVisibleListEnd;
bridge_list_t mVisibleBridge;
- bridge_list_t::iterator mVisibleBridgeEnd;
+ bridge_iterator mVisibleBridgeEnd;
drawinfo_list_t mRenderMap[LLRenderPass::NUM_RENDER_TYPES];
- drawinfo_list_t::iterator mRenderMapEnd[LLRenderPass::NUM_RENDER_TYPES];
+ U32 mRenderMapAllocated[LLRenderPass::NUM_RENDER_TYPES];
+ drawinfo_iterator mRenderMapEnd[LLRenderPass::NUM_RENDER_TYPES];
+
};
@@ -655,6 +715,7 @@ class LLParticlePartition : public LLSpatialPartition
{
public:
LLParticlePartition();
+ virtual void rebuildGeom(LLSpatialGroup* group);
virtual void getGeometry(LLSpatialGroup* group);
virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32& index_count);
virtual F32 calcPixelArea(LLSpatialGroup* group, LLCamera& camera);
@@ -669,10 +730,14 @@ public:
};
//spatial partition for grass (implemented in LLVOGrass.cpp)
-class LLGrassPartition : public LLParticlePartition
+class LLGrassPartition : public LLSpatialPartition
{
public:
LLGrassPartition();
+ virtual void getGeometry(LLSpatialGroup* group);
+ virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32& index_count);
+protected:
+ U32 mRenderPass;
};
//class for wrangling geometry out of volumes (implemented in LLVOVolume.cpp)
@@ -690,7 +755,7 @@ class LLVolumeGeometryManager: public LLGeometryManager
virtual void rebuildGeom(LLSpatialGroup* group);
virtual void rebuildMesh(LLSpatialGroup* group);
virtual void getGeometry(LLSpatialGroup* group);
- void genDrawInfo(LLSpatialGroup* group, U32 mask, std::vector<LLFace*>& faces, BOOL distance_sort = FALSE, BOOL batch_textures = FALSE);
+ void genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace** faces, U32 face_count, BOOL distance_sort = FALSE, BOOL batch_textures = FALSE, BOOL no_materials = FALSE);
void registerFace(LLSpatialGroup* group, LLFace* facep, U32 type);
};
diff --git a/indra/newview/llspeakers.cpp b/indra/newview/llspeakers.cpp
index 07d2f1ad6f..a4582071e8 100644..100755
--- a/indra/newview/llspeakers.cpp
+++ b/indra/newview/llspeakers.cpp
@@ -31,12 +31,15 @@
#include "llagent.h"
#include "llappviewer.h"
#include "llimview.h"
+#include "llgroupmgr.h"
#include "llsdutil.h"
#include "lluicolortable.h"
#include "llviewerobjectlist.h"
#include "llvoavatar.h"
#include "llworld.h"
+extern LLControlGroup gSavedSettings;
+
const LLColor4 INACTIVE_COLOR(0.3f, 0.3f, 0.3f, 0.5f);
const LLColor4 ACTIVE_COLOR(0.5f, 0.5f, 0.5f, 1.f);
@@ -84,6 +87,19 @@ bool LLSpeaker::isInVoiceChannel()
return mStatus <= LLSpeaker::STATUS_VOICE_ACTIVE || mStatus == LLSpeaker::STATUS_MUTED;
}
+LLSpeakerUpdateSpeakerEvent::LLSpeakerUpdateSpeakerEvent(LLSpeaker* source)
+: LLEvent(source, "Speaker update speaker event"),
+ mSpeakerID (source->mID)
+{
+}
+
+LLSD LLSpeakerUpdateSpeakerEvent::getValue()
+{
+ LLSD ret;
+ ret["id"] = mSpeakerID;
+ return ret;
+}
+
LLSpeakerUpdateModeratorEvent::LLSpeakerUpdateModeratorEvent(LLSpeaker* source)
: LLEvent(source, "Speaker add moderator event"),
mSpeakerID (source->mID),
@@ -241,16 +257,63 @@ bool LLSpeakersDelayActionsStorage::onTimerActionCallback(const LLUUID& speaker_
return true;
}
+bool LLSpeakersDelayActionsStorage::isTimerStarted(const LLUUID& speaker_id)
+{
+ return (mActionTimersMap.size() > 0) && (mActionTimersMap.find(speaker_id) != mActionTimersMap.end());
+}
+
+//
+// ModerationResponder
+//
+
+class ModerationResponder : public LLHTTPClient::Responder
+{
+public:
+ ModerationResponder(const LLUUID& session_id)
+ {
+ mSessionID = session_id;
+ }
+
+ virtual void error(U32 status, const std::string& reason)
+ {
+ llwarns << status << ": " << reason << llendl;
+
+ if ( gIMMgr )
+ {
+ //403 == you're not a mod
+ //should be disabled if you're not a moderator
+ if ( 403 == status )
+ {
+ gIMMgr->showSessionEventError(
+ "mute",
+ "not_a_mod_error",
+ mSessionID);
+ }
+ else
+ {
+ gIMMgr->showSessionEventError(
+ "mute",
+ "generic_request_error",
+ mSessionID);
+ }
+ }
+ }
+
+private:
+ LLUUID mSessionID;
+};
//
// LLSpeakerMgr
//
LLSpeakerMgr::LLSpeakerMgr(LLVoiceChannel* channelp) :
- mVoiceChannel(channelp)
-, mVoiceModerated(false)
-, mModerateModeHandledFirstTime(false)
+ mVoiceChannel(channelp),
+ mVoiceModerated(false),
+ mModerateModeHandledFirstTime(false),
+ mSpeakerListUpdated(false)
{
+ mGetListTime.reset();
static LLUICachedControl<F32> remove_delay ("SpeakerParticipantRemoveDelay", 10.0);
mSpeakerDelayRemover = new LLSpeakersDelayActionsStorage(boost::bind(&LLSpeakerMgr::removeSpeaker, this, _1), remove_delay);
@@ -263,7 +326,11 @@ LLSpeakerMgr::~LLSpeakerMgr()
LLPointer<LLSpeaker> LLSpeakerMgr::setSpeaker(const LLUUID& id, const std::string& name, LLSpeaker::ESpeakerStatus status, LLSpeaker::ESpeakerType type)
{
- if (id.isNull()) return NULL;
+ LLUUID session_id = getSessionID();
+ if (id.isNull() || (id == session_id))
+ {
+ return NULL;
+ }
LLPointer<LLSpeaker> speakerp;
if (mSpeakers.find(id) == mSpeakers.end())
@@ -345,12 +412,10 @@ void LLSpeakerMgr::update(BOOL resort_ok)
// update status of all current speakers
BOOL voice_channel_active = (!mVoiceChannel && LLVoiceClient::getInstance()->inProximalChannel()) || (mVoiceChannel && mVoiceChannel->isActive());
- for (speaker_map_t::iterator speaker_it = mSpeakers.begin(); speaker_it != mSpeakers.end();)
+ for (speaker_map_t::iterator speaker_it = mSpeakers.begin(); speaker_it != mSpeakers.end(); speaker_it++)
{
LLUUID speaker_id = speaker_it->first;
LLSpeaker* speakerp = speaker_it->second;
-
- speaker_map_t::iterator cur_speaker_it = speaker_it++;
if (voice_channel_active && LLVoiceClient::getInstance()->getVoiceEnabled(speaker_id))
{
@@ -374,6 +439,7 @@ void LLSpeakerMgr::update(BOOL resort_ok)
{
speakerp->mLastSpokeTime = mSpeechTimer.getElapsedTimeF32();
speakerp->mHasSpoken = TRUE;
+ fireEvent(new LLSpeakerUpdateSpeakerEvent(speakerp), "update_speaker");
}
speakerp->mStatus = LLSpeaker::STATUS_SPEAKING;
// interpolate between active color and full speaking color based on power of speech output
@@ -448,24 +514,89 @@ void LLSpeakerMgr::update(BOOL resort_ok)
void LLSpeakerMgr::updateSpeakerList()
{
- // are we bound to the currently active voice channel?
+ // Are we bound to the currently active voice channel?
if ((!mVoiceChannel && LLVoiceClient::getInstance()->inProximalChannel()) || (mVoiceChannel && mVoiceChannel->isActive()))
{
- std::set<LLUUID> participants;
- LLVoiceClient::getInstance()->getParticipantList(participants);
- // add new participants to our list of known speakers
- for (std::set<LLUUID>::iterator participant_it = participants.begin();
- participant_it != participants.end();
- ++participant_it)
+ std::set<LLUUID> participants;
+ LLVoiceClient::getInstance()->getParticipantList(participants);
+ // If we are, add all voice client participants to our list of known speakers
+ for (std::set<LLUUID>::iterator participant_it = participants.begin(); participant_it != participants.end(); ++participant_it)
{
setSpeaker(*participant_it,
LLVoiceClient::getInstance()->getDisplayName(*participant_it),
LLSpeaker::STATUS_VOICE_ACTIVE,
(LLVoiceClient::getInstance()->isParticipantAvatar(*participant_it)?LLSpeaker::SPEAKER_AGENT:LLSpeaker::SPEAKER_EXTERNAL));
-
-
}
}
+ else
+ {
+ // If not, check if the list is empty, except if it's Nearby Chat (session_id NULL).
+ LLUUID session_id = getSessionID();
+ if (!session_id.isNull() && !mSpeakerListUpdated)
+ {
+ // If the list is empty, we update it with whatever we have locally so that it doesn't stay empty too long.
+ // *TODO: Fix the server side code that sometimes forgets to send back the list of participants after a chat started.
+ // (IOW, fix why we get no ChatterBoxSessionAgentListUpdates message after the initial ChatterBoxSessionStartReply)
+ LLIMModel::LLIMSession* session = LLIMModel::getInstance()->findIMSession(session_id);
+ if (session->isGroupSessionType() && (mSpeakers.size() <= 1))
+ {
+ const F32 load_group_timeout = gSavedSettings.getF32("ChatLoadGroupTimeout");
+ // For groups, we need to hit the group manager.
+ // Note: The session uuid and the group uuid are actually one and the same. If that was to change, this will fail.
+ LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(session_id);
+ if (!gdatap && (mGetListTime.getElapsedTimeF32() >= load_group_timeout))
+ {
+ // Request the data the first time around
+ LLGroupMgr::getInstance()->sendCapGroupMembersRequest(session_id);
+ }
+ else if (gdatap && gdatap->isMemberDataComplete() && !gdatap->mMembers.empty())
+ {
+ // Add group members when we get the complete list (note: can take a while before we get that list)
+ LLGroupMgrGroupData::member_list_t::iterator member_it = gdatap->mMembers.begin();
+ const S32 load_group_max_members = gSavedSettings.getS32("ChatLoadGroupMaxMembers");
+ S32 updated = 0;
+ while (member_it != gdatap->mMembers.end())
+ {
+ LLGroupMemberData* member = member_it->second;
+ LLUUID id = member_it->first;
+ // Add only members who are online and not already in the list
+ if ((member->getOnlineStatus() == "Online") && (mSpeakers.find(id) == mSpeakers.end()))
+ {
+ LLPointer<LLSpeaker> speakerp = setSpeaker(id, "", LLSpeaker::STATUS_VOICE_ACTIVE, LLSpeaker::SPEAKER_AGENT);
+ speakerp->mIsModerator = ((member->getAgentPowers() & GP_SESSION_MODERATOR) == GP_SESSION_MODERATOR);
+ updated++;
+ }
+ ++member_it;
+ // Limit the number of "manually updated" participants to a reasonable number to avoid severe fps drop
+ // *TODO : solve the perf issue of having several hundreds of widgets in the conversation list
+ if (updated >= load_group_max_members)
+ break;
+ }
+ mSpeakerListUpdated = true;
+ }
+ }
+ else if (mSpeakers.size() == 0)
+ {
+ // For all other session type (ad-hoc, P2P, avaline), we use the initial participants targets list
+ for (uuid_vec_t::iterator it = session->mInitialTargetIDs.begin();it!=session->mInitialTargetIDs.end();++it)
+ {
+ // Add buddies if they are on line, add any other avatar.
+ if (!LLAvatarTracker::instance().isBuddy(*it) || LLAvatarTracker::instance().isBuddyOnline(*it))
+ {
+ setSpeaker(*it, "", LLSpeaker::STATUS_VOICE_ACTIVE, LLSpeaker::SPEAKER_AGENT);
+ }
+ }
+ mSpeakerListUpdated = true;
+ }
+ else
+ {
+ // The list has been updated the normal way (i.e. by a ChatterBoxSessionAgentListUpdates received from the server)
+ mSpeakerListUpdated = true;
+ }
+ }
+ }
+ // Always add the current agent (it has to be there...). Will do nothing if already there.
+ setSpeaker(gAgentID, "", LLSpeaker::STATUS_VOICE_ACTIVE, LLSpeaker::SPEAKER_AGENT);
}
void LLSpeakerMgr::setSpeakerNotInChannel(LLSpeaker* speakerp)
@@ -530,6 +661,10 @@ const LLUUID LLSpeakerMgr::getSessionID()
return mVoiceChannel->getSessionID();
}
+bool LLSpeakerMgr::isSpeakerToBeRemoved(const LLUUID& speaker_id)
+{
+ return mSpeakerDelayRemover && mSpeakerDelayRemover->isTimerStarted(speaker_id);
+}
void LLSpeakerMgr::setSpeakerTyping(const LLUUID& speaker_id, BOOL typing)
{
@@ -548,6 +683,7 @@ void LLSpeakerMgr::speakerChatted(const LLUUID& speaker_id)
{
speakerp->mLastSpokeTime = mSpeechTimer.getElapsedTimeF32();
speakerp->mHasSpoken = TRUE;
+ fireEvent(new LLSpeakerUpdateSpeakerEvent(speakerp), "update_speaker");
}
}
@@ -717,44 +853,10 @@ void LLIMSpeakerMgr::updateSpeakers(const LLSD& update)
}
}
}
-
-class ModerationResponder : public LLHTTPClient::Responder
-{
-public:
- ModerationResponder(const LLUUID& session_id)
- {
- mSessionID = session_id;
- }
-
- virtual void error(U32 status, const std::string& reason)
- {
- llwarns << status << ": " << reason << llendl;
-
- if ( gIMMgr )
- {
- //403 == you're not a mod
- //should be disabled if you're not a moderator
- if ( 403 == status )
- {
- gIMMgr->showSessionEventError(
- "mute",
- "not_a_mod_error",
- mSessionID);
- }
- else
- {
- gIMMgr->showSessionEventError(
- "mute",
- "generic_request_error",
- mSessionID);
- }
- }
- }
-
-private:
- LLUUID mSessionID;
-};
-
+/*prep#
+ virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content)
+ llwarns << "ModerationResponder error [status:" << status << "]: " << content << llendl;
+ */
void LLIMSpeakerMgr::toggleAllowTextChat(const LLUUID& speaker_id)
{
LLPointer<LLSpeaker> speakerp = findSpeaker(speaker_id);
diff --git a/indra/newview/llspeakers.h b/indra/newview/llspeakers.h
index b9358cf37c..e953dd0e1a 100644..100755
--- a/indra/newview/llspeakers.h
+++ b/indra/newview/llspeakers.h
@@ -29,7 +29,6 @@
#include "llevent.h"
#include "lleventtimer.h"
-#include "llspeakers.h"
#include "llvoicechannel.h"
class LLSpeakerMgr;
@@ -80,6 +79,15 @@ public:
BOOL mModeratorMutedText;
};
+class LLSpeakerUpdateSpeakerEvent : public LLOldEvents::LLEvent
+{
+public:
+ LLSpeakerUpdateSpeakerEvent(LLSpeaker* source);
+ /*virtual*/ LLSD getValue();
+private:
+ const LLUUID& mSpeakerID;
+};
+
class LLSpeakerUpdateModeratorEvent : public LLOldEvents::LLEvent
{
public:
@@ -185,6 +193,8 @@ public:
void unsetActionTimer(const LLUUID& speaker_id);
void removeAllTimers();
+
+ bool isTimerStarted(const LLUUID& speaker_id);
private:
/**
* Callback of the each instance of LLSpeakerActionTimer.
@@ -229,6 +239,7 @@ public:
void getSpeakerList(speaker_list_t* speaker_list, BOOL include_text);
LLVoiceChannel* getVoiceChannel() { return mVoiceChannel; }
const LLUUID getSessionID();
+ bool isSpeakerToBeRemoved(const LLUUID& speaker_id);
/**
* Removes avaline speaker.
@@ -252,6 +263,8 @@ protected:
typedef std::map<LLUUID, LLPointer<LLSpeaker> > speaker_map_t;
speaker_map_t mSpeakers;
+ bool mSpeakerListUpdated;
+ LLTimer mGetListTime;
speaker_list_t mSpeakersSorted;
LLFrameTimer mSpeechTimer;
diff --git a/indra/newview/llspeakingindicatormanager.cpp b/indra/newview/llspeakingindicatormanager.cpp
index 9b38bf22ff..07e9371124 100644..100755
--- a/indra/newview/llspeakingindicatormanager.cpp
+++ b/indra/newview/llspeakingindicatormanager.cpp
@@ -74,6 +74,16 @@ public:
*/
void unregisterSpeakingIndicator(const LLUUID& speaker_id, const LLSpeakingIndicator* const speaking_indicator);
+ /**
+ * Callback of changing voice participant list (from LLVoiceClientParticipantObserver).
+ *
+ * Switches off indicators had been switched on and switches on indicators of current participants list.
+ * There is only a few indicators in lists should be switched off/on.
+ * So, method does not calculate difference between these list it only switches off already
+ * switched on indicators and switches on indicators of voice channel participants
+ */
+ void onParticipantsChanged();
+
private:
typedef std::set<LLUUID> speaker_ids_t;
typedef std::multimap<LLUUID, LLSpeakingIndicator*> speaking_indicators_mmap_t;
@@ -94,16 +104,6 @@ private:
void sOnCurrentChannelChanged(const LLUUID& session_id);
/**
- * Callback of changing voice participant list (from LLVoiceClientParticipantObserver).
- *
- * Switches off indicators had been switched on and switches on indicators of current participants list.
- * There is only a few indicators in lists should be switched off/on.
- * So, method does not calculate difference between these list it only switches off already
- * switched on indicators and switches on indicators of voice channel participants
- */
- void onParticipantsChanged();
-
- /**
* Changes state of indicators specified by LLUUIDs
*
* @param speakers_uuids - avatars' LLUUIDs whose speaking indicators should be switched
@@ -237,28 +237,18 @@ void SpeakingIndicatorManager::switchSpeakerIndicators(const speaker_ids_t& spea
{
was_found = true;
LLSpeakingIndicator* indicator = (*it_indicator).second;
+ was_switched_on = was_switched_on || switch_on;
- BOOL switch_current_on = switch_on;
-
- // we should show indicator for specified voice session only if this is current channel. EXT-5562.
- if (switch_current_on && indicator->getTargetSessionID().notNull())
- {
- switch_current_on = indicator->getTargetSessionID() == session_id;
- LL_DEBUGS("SpeakingIndicator") << "Session: " << session_id << ", target: " << indicator->getTargetSessionID() << ", the same? = " << switch_current_on << LL_ENDL;
- }
- was_switched_on = was_switched_on || switch_current_on;
-
- indicator->switchIndicator(switch_current_on);
-
+ indicator->switchIndicator(switch_on);
}
if (was_found)
{
- LL_DEBUGS("SpeakingIndicator") << mSpeakingIndicators.count(*it_uuid) << " indicators where found" << LL_ENDL;
+ LL_DEBUGS("SpeakingIndicator") << mSpeakingIndicators.count(*it_uuid) << " indicators were found" << LL_ENDL;
if (switch_on && !was_switched_on)
{
- LL_DEBUGS("SpeakingIndicator") << "but non of them where switched on" << LL_ENDL;
+ LL_DEBUGS("SpeakingIndicator") << "but none of them were switched on" << LL_ENDL;
}
if (was_switched_on)
@@ -314,5 +304,13 @@ void LLSpeakingIndicatorManager::unregisterSpeakingIndicator(const LLUUID& speak
}
}
+void LLSpeakingIndicatorManager::updateSpeakingIndicators()
+{
+ if(SpeakingIndicatorManager::instanceExists())
+ {
+ SpeakingIndicatorManager::instance().onParticipantsChanged();
+ }
+}
+
// EOF
diff --git a/indra/newview/llspeakingindicatormanager.h b/indra/newview/llspeakingindicatormanager.h
index b0a147865b..e5afcd1cb7 100644..100755
--- a/indra/newview/llspeakingindicatormanager.h
+++ b/indra/newview/llspeakingindicatormanager.h
@@ -78,6 +78,11 @@ namespace LLSpeakingIndicatorManager
* @param speaking_indicator instance of the speaker indicator to be unregistered.
*/
void unregisterSpeakingIndicator(const LLUUID& speaker_id, const LLSpeakingIndicator* const speaking_indicator);
+
+ /**
+ * Switch on/off registered speaking indicator according to the most current voice client status
+ */
+ void updateSpeakingIndicators();
}
#endif // LL_LLSPEAKINGINDICATORMANAGER_H
diff --git a/indra/newview/llsplitbutton.cpp b/indra/newview/llsplitbutton.cpp
index 790305103d..790305103d 100644..100755
--- a/indra/newview/llsplitbutton.cpp
+++ b/indra/newview/llsplitbutton.cpp
diff --git a/indra/newview/llsplitbutton.h b/indra/newview/llsplitbutton.h
index 4f20c8b379..4f20c8b379 100644..100755
--- a/indra/newview/llsplitbutton.h
+++ b/indra/newview/llsplitbutton.h
diff --git a/indra/newview/llsprite.cpp b/indra/newview/llsprite.cpp
index c3eb70f850..c3eb70f850 100644..100755
--- a/indra/newview/llsprite.cpp
+++ b/indra/newview/llsprite.cpp
diff --git a/indra/newview/llsprite.h b/indra/newview/llsprite.h
index d00b8ef695..d00b8ef695 100644..100755
--- a/indra/newview/llsprite.h
+++ b/indra/newview/llsprite.h
diff --git a/indra/newview/llsrv.cpp b/indra/newview/llsrv.cpp
index 567c2a0158..567c2a0158 100644..100755
--- a/indra/newview/llsrv.cpp
+++ b/indra/newview/llsrv.cpp
diff --git a/indra/newview/llsrv.h b/indra/newview/llsrv.h
index db5543f772..db5543f772 100644..100755
--- a/indra/newview/llsrv.h
+++ b/indra/newview/llsrv.h
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 0ac8c1fe39..67a76460a7 100644..100755
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -26,6 +26,7 @@
#include "llviewerprecompiledheaders.h"
+#include "llappviewer.h"
#include "llstartup.h"
#if LL_WINDOWS
@@ -37,8 +38,8 @@
#include "llviewermedia_streamingaudio.h"
#include "llaudioengine.h"
-#ifdef LL_FMOD
-# include "llaudioengine_fmod.h"
+#ifdef LL_FMODEX
+# include "llaudioengine_fmodex.h"
#endif
#ifdef LL_OPENAL
@@ -50,11 +51,12 @@
#include "lllandmark.h"
#include "llcachename.h"
#include "lldir.h"
+#include "lldonotdisturbnotificationstorage.h"
#include "llerrorcontrol.h"
#include "llfloaterreg.h"
#include "llfocusmgr.h"
#include "llhttpsender.h"
-#include "llimfloater.h"
+#include "llfloaterimsession.h"
#include "lllocationhistory.h"
#include "llimageworker.h"
@@ -63,9 +65,11 @@
#include "llmemorystream.h"
#include "llmessageconfig.h"
#include "llmoveview.h"
-#include "llnearbychat.h"
+#include "llfloaterimcontainer.h"
+#include "llfloaterimnearbychat.h"
#include "llnotifications.h"
#include "llnotificationsutil.h"
+#include "llpersistentnotificationstorage.h"
#include "llteleporthistory.h"
#include "llregionhandle.h"
#include "llsd.h"
@@ -94,6 +98,7 @@
#include "llcallingcard.h"
#include "llconsole.h"
#include "llcontainerview.h"
+#include "llconversationlog.h"
#include "lldebugview.h"
#include "lldrawable.h"
#include "lleventnotifier.h"
@@ -186,6 +191,7 @@
#include "llappearancemgr.h"
#include "llavatariconctrl.h"
#include "llvoicechannel.h"
+#include "llpathfindingmanager.h"
#include "lllogin.h"
#include "llevents.h"
@@ -240,6 +246,7 @@ static bool mLoginStatePastUI = false;
boost::scoped_ptr<LLEventPump> LLStartUp::sStateWatcher(new LLEventStream("StartupState"));
boost::scoped_ptr<LLStartupListener> LLStartUp::sListener(new LLStartupListener());
+boost::scoped_ptr<LLViewerStats::PhaseMap> LLStartUp::sPhases(new LLViewerStats::PhaseMap);
//
// local function declaration
@@ -310,11 +317,8 @@ void update_texture_fetch()
// true when all initialization done.
bool idle_startup()
{
- LLMemType mt1(LLMemType::MTYPE_STARTUP);
-
const F32 PRECACHING_DELAY = gSavedSettings.getF32("PrecachingDelay");
static LLTimer timeout;
- static S32 timeout_count = 0;
static LLTimer login_time;
@@ -330,7 +334,6 @@ bool idle_startup()
// last location by default
static S32 agent_location_id = START_LOCATION_ID_LAST;
- static S32 location_which = START_LOCATION_ID_LAST;
static bool show_connect_box = true;
@@ -360,6 +363,15 @@ bool idle_startup()
if ( STATE_FIRST == LLStartUp::getStartupState() )
{
+ static bool first_call = true;
+ if (first_call)
+ {
+ // Other phases get handled when startup state changes,
+ // need to capture the initial state as well.
+ LLStartUp::getPhases().startPhase(LLStartUp::getStartupStateString());
+ first_call = false;
+ }
+
gViewerWindow->showCursor();
gViewerWindow->getWindow()->setCursor(UI_CURSOR_WAIT);
@@ -614,32 +626,32 @@ bool idle_startup()
{
gAudiop = NULL;
-#ifdef LL_OPENAL
+#ifdef LL_FMODEX
if (!gAudiop
#if !LL_WINDOWS
- && NULL == getenv("LL_BAD_OPENAL_DRIVER")
+ && NULL == getenv("LL_BAD_FMODEX_DRIVER")
#endif // !LL_WINDOWS
)
{
- gAudiop = (LLAudioEngine *) new LLAudioEngine_OpenAL();
+ gAudiop = (LLAudioEngine *) new LLAudioEngine_FMODEX(gSavedSettings.getBOOL("FMODExProfilerEnable"));
}
#endif
-#ifdef LL_FMOD
+#ifdef LL_OPENAL
if (!gAudiop
#if !LL_WINDOWS
- && NULL == getenv("LL_BAD_FMOD_DRIVER")
+ && NULL == getenv("LL_BAD_OPENAL_DRIVER")
#endif // !LL_WINDOWS
)
{
- gAudiop = (LLAudioEngine *) new LLAudioEngine_FMOD();
+ gAudiop = (LLAudioEngine *) new LLAudioEngine_OpenAL();
}
#endif
if (gAudiop)
{
#if LL_WINDOWS
- // FMOD on Windows needs the window handle to stop playing audio
+ // FMOD Ex on Windows needs the window handle to stop playing audio
// when window is minimized. JC
void* window_handle = (HWND)gViewerWindow->getPlatformWindow();
#else
@@ -719,26 +731,28 @@ bool idle_startup()
if (STATE_LOGIN_SHOW == LLStartUp::getStartupState())
{
- LL_DEBUGS("AppInit") << "Initializing Window" << LL_ENDL;
+ LL_DEBUGS("AppInit") << "Initializing Window, show_connect_box = "
+ << show_connect_box << LL_ENDL;
// if we've gone backwards in the login state machine, to this state where we show the UI
// AND the debug setting to exit in this case is true, then go ahead and bail quickly
if ( mLoginStatePastUI && gSavedSettings.getBOOL("QuitOnLoginActivated") )
{
+ LL_DEBUGS("AppInit") << "taking QuitOnLoginActivated exit" << LL_ENDL;
// no requirement for notification here - just exit
LLAppViewer::instance()->earlyExitNoNotify();
}
gViewerWindow->getWindow()->setCursor(UI_CURSOR_ARROW);
- timeout_count = 0;
-
// Login screen needs menus for preferences, but we can enter
// this startup phase more than once.
if (gLoginMenuBarView == NULL)
{
+ LL_DEBUGS("AppInit") << "initializing menu bar" << LL_ENDL;
display_startup();
initialize_edit_menu();
+ initialize_spellcheck_menu();
display_startup();
init_menus();
display_startup();
@@ -746,19 +760,17 @@ bool idle_startup()
if (show_connect_box)
{
+ LL_DEBUGS("AppInit") << "show_connect_box on" << LL_ENDL;
// Load all the name information out of the login view
// NOTE: Hits "Attempted getFields with no login view shown" warning, since we don't
// show the login view until login_show() is called below.
if (gUserCredential.isNull())
{
+ LL_DEBUGS("AppInit") << "loading credentials from gLoginHandler" << LL_ENDL;
display_startup();
gUserCredential = gLoginHandler.initializeLoginInfo();
display_startup();
}
- if (gHeadlessClient)
- {
- LL_WARNS("AppInit") << "Waiting at connection box in headless client. Did you mean to add autologin params?" << LL_ENDL;
- }
// Make sure the process dialog doesn't hide things
display_startup();
gViewerWindow->setShowProgress(FALSE);
@@ -767,17 +779,28 @@ bool idle_startup()
login_show();
display_startup();
// connect dialog is already shown, so fill in the names
- if (gUserCredential.notNull())
- {
- LLPanelLogin::setFields( gUserCredential, gRememberPassword);
- }
+ if (gUserCredential.notNull())
+ {
+ LLPanelLogin::setFields( gUserCredential, gRememberPassword);
+ }
display_startup();
LLPanelLogin::giveFocus();
+ if (gSavedSettings.getBOOL("FirstLoginThisInstall"))
+ {
+ LL_INFOS("AppInit") << "FirstLoginThisInstall, calling show_first_run_dialog()" << LL_ENDL;
+ show_first_run_dialog();
+ }
+ else
+ {
+ LL_DEBUGS("AppInit") << "FirstLoginThisInstall off" << LL_ENDL;
+ }
+
LLStartUp::setStartupState( STATE_LOGIN_WAIT ); // Wait for user input
}
else
{
+ LL_DEBUGS("AppInit") << "show_connect_box off, skipping to STATE_LOGIN_CLEANUP" << LL_ENDL;
// skip directly to message template verification
LLStartUp::setStartupState( STATE_LOGIN_CLEANUP );
}
@@ -879,6 +902,10 @@ bool idle_startup()
gDirUtilp->setLindenUserDir(userid);
LLFile::mkdir(gDirUtilp->getLindenUserDir());
+ // As soon as directories are ready initialize notification storages
+ LLPersistentNotificationStorage::getInstance()->initialize();
+ LLDoNotDisturbNotificationStorage::getInstance()->initialize();
+
// Set PerAccountSettingsFile to the default value.
gSavedSettings.setString("PerAccountSettingsFile",
gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT,
@@ -889,6 +916,13 @@ bool idle_startup()
// Overwrite default user settings with user settings
LLAppViewer::instance()->loadSettingsFromDirectory("Account");
+ // Convert 'LogInstantMessages' into 'KeepConversationLogTranscripts' for backward compatibility (CHUI-743).
+ LLControlVariablePtr logInstantMessagesControl = gSavedPerAccountSettings.getControl("LogInstantMessages");
+ if (logInstantMessagesControl.notNull())
+ {
+ gSavedPerAccountSettings.setS32("KeepConversationLogTranscripts", logInstantMessagesControl->getValue() ? 2 : 1);
+ }
+
// Need to set the LastLogoff time here if we don't have one. LastLogoff is used for "Recent Items" calculation
// and startup time is close enough if we don't have a real value.
if (gSavedPerAccountSettings.getU32("LastLogoff") == 0)
@@ -958,15 +992,12 @@ bool idle_startup()
{
case LLSLURL::LOCATION:
agent_location_id = START_LOCATION_ID_URL;
- location_which = START_LOCATION_ID_LAST;
break;
case LLSLURL::LAST_LOCATION:
agent_location_id = START_LOCATION_ID_LAST;
- location_which = START_LOCATION_ID_LAST;
break;
default:
agent_location_id = START_LOCATION_ID_HOME;
- location_which = START_LOCATION_ID_HOME;
break;
}
@@ -994,7 +1025,7 @@ bool idle_startup()
if(STATE_LOGIN_AUTH_INIT == LLStartUp::getStartupState())
{
- gDebugInfo["GridName"] = LLGridManager::getInstance()->getGridLabel();
+ gDebugInfo["GridName"] = LLGridManager::getInstance()->getGridId();
// Update progress status and the display loop.
auth_desc = LLTrans::getString("LoginInProgress");
@@ -1008,6 +1039,7 @@ bool idle_startup()
login->setSerialNumber(LLAppViewer::instance()->getSerialNumber());
login->setLastExecEvent(gLastExecEvent);
+ login->setLastExecDuration(gLastExecDuration);
login->setUpdaterLauncher(boost::bind(&LLAppViewer::launchUpdater, LLAppViewer::instance()));
// This call to LLLoginInstance::connect() starts the
@@ -1158,7 +1190,6 @@ bool idle_startup()
LLVoiceClient::getInstance()->userAuthorized(gUserCredential->userID(), gAgentID);
// create the default proximal channel
LLVoiceChannel::initClass();
- LLGridManager::getInstance()->setFavorite();
LLStartUp::setStartupState( STATE_WORLD_INIT);
}
else
@@ -1220,6 +1251,9 @@ bool idle_startup()
LLPostProcess::initClass();
display_startup();
+ LLAvatarAppearance::initClass();
+ display_startup();
+
LLViewerObject::initVOClasses();
display_startup();
@@ -1266,6 +1300,8 @@ bool idle_startup()
display_startup();
LLStartUp::setStartupState( STATE_MULTIMEDIA_INIT );
+ LLConversationLog::getInstance();
+
return FALSE;
}
@@ -1376,14 +1412,9 @@ bool idle_startup()
LLVoiceClient::getInstance()->updateSettings();
display_startup();
- //gCacheName is required for nearby chat history loading
- //so I just moved nearby history loading a few states further
- if (gSavedPerAccountSettings.getBOOL("LogShowHistory"))
- {
- LLNearbyChat* nearby_chat = LLNearbyChat::getInstance();
- if (nearby_chat) nearby_chat->loadHistory();
- }
- display_startup();
+ // create a container's instance for start a controlling conversation windows
+ // by the voice's events
+ LLFloaterIMContainer::getInstance();
// *Note: this is where gWorldMap used to be initialized.
@@ -1393,7 +1424,7 @@ bool idle_startup()
display_startup();
//reset statistics
- LLViewerStats::getInstance()->resetStats();
+ LLViewerStats::instance().resetStats();
display_startup();
//
@@ -1494,7 +1525,7 @@ bool idle_startup()
}
//---------------------------------------------------------------------
- // Agent Send
+ // World Wait
//---------------------------------------------------------------------
if(STATE_WORLD_WAIT == LLStartUp::getStartupState())
{
@@ -1820,6 +1851,10 @@ bool idle_startup()
// Set the show start location to true, now that the user has logged
// on with this install.
gSavedSettings.setBOOL("ShowStartLocation", TRUE);
+
+ // Open Conversation floater on first login.
+ LLFloaterReg::toggleInstanceOrBringToFront("im_container");
+
}
display_startup();
@@ -1921,6 +1956,7 @@ bool idle_startup()
{
llinfos << "gAgentStartLocation : " << gAgentStartLocation << llendl;
LLSLURL start_slurl = LLStartUp::getStartSLURL();
+ LL_DEBUGS("AppInit") << "start slurl "<<start_slurl.asString()<<LL_ENDL;
if (((start_slurl.getType() == LLSLURL::LOCATION) && (gAgentStartLocation == "url")) ||
((start_slurl.getType() == LLSLURL::LAST_LOCATION) && (gAgentStartLocation == "last")) ||
@@ -2141,7 +2177,6 @@ bool idle_startup()
display_startup();
// Unmute audio if desired and setup volumes.
- // Unmute audio if desired and setup volumes.
// This is a not-uncommon crash site, so surround it with
// llinfos output to aid diagnosis.
LL_INFOS("AppInit") << "Doing first audio_update_volume..." << LL_ENDL;
@@ -2162,9 +2197,11 @@ bool idle_startup()
LLAgentPicksInfo::getInstance()->requestNumberOfPicks();
- LLIMFloater::initIMFloater();
display_startup();
+ llassert(LLPathfindingManager::getInstance() != NULL);
+ LLPathfindingManager::getInstance()->initSystem();
+
return TRUE;
}
@@ -2180,21 +2217,13 @@ void login_show()
{
LL_INFOS("AppInit") << "Initializing Login Screen" << LL_ENDL;
-#ifdef LL_RELEASE_FOR_DOWNLOAD
- BOOL bUseDebugLogin = gSavedSettings.getBOOL("UseDebugLogin");
-#else
- BOOL bUseDebugLogin = TRUE;
-#endif
// Hide the toolbars: may happen to come back here if login fails after login agent but before login in region
if (gToolBarView)
{
gToolBarView->setVisible(FALSE);
}
- LLPanelLogin::show( gViewerWindow->getWindowRectScaled(),
- bUseDebugLogin || gSavedSettings.getBOOL("SecondLifeEnterprise"),
- login_callback, NULL );
-
+ LLPanelLogin::show( gViewerWindow->getWindowRectScaled(), login_callback, NULL );
}
// Callback for when login screen is closed. Option 0 = connect, option 1 = quit.
@@ -2559,12 +2588,17 @@ void LLStartUp::loadInitialOutfit( const std::string& outfit_folder_name,
}
else
{
+ // FIXME SH-3860 - this creates a race condition, where COF
+ // changes (base outfit link added) after appearance update
+ // request has been submitted.
sWearablesLoadedCon = gAgentWearables.addLoadedCallback(LLStartUp::saveInitialOutfit);
bool do_copy = true;
bool do_append = false;
LLViewerInventoryCategory *cat = gInventory.getCategory(cat_id);
- LLAppearanceMgr::instance().wearInventoryCategory(cat, do_copy, do_append);
+ // Need to fetch cof contents before we can wear.
+ callAfterCategoryFetch(LLAppearanceMgr::instance().getCOF(),
+ boost::bind(&LLAppearanceMgr::wearInventoryCategory, LLAppearanceMgr::getInstance(), cat, do_copy, do_append));
lldebugs << "initial outfit category id: " << cat_id << llendl;
}
@@ -2705,7 +2739,11 @@ void LLStartUp::setStartupState( EStartupState state )
LL_INFOS("AppInit") << "Startup state changing from " <<
getStartupStateString() << " to " <<
startupStateToString(state) << LL_ENDL;
+
+ getPhases().stopPhase(getStartupStateString());
gStartupState = state;
+ getPhases().startPhase(getStartupStateString());
+
postStartupState();
}
@@ -2778,7 +2816,7 @@ void LLStartUp::initNameCache()
// Start cache in not-running state until we figure out if we have
// capabilities for display name lookup
- LLAvatarNameCache::initClass(false);
+ LLAvatarNameCache::initClass(false,gSavedSettings.getBOOL("UsePeopleAPI"));
LLAvatarNameCache::setUseDisplayNames(gSavedSettings.getBOOL("UseDisplayNames"));
}
@@ -2822,25 +2860,33 @@ bool LLStartUp::dispatchURL()
void LLStartUp::setStartSLURL(const LLSLURL& slurl)
{
- sStartSLURL = slurl;
- switch(slurl.getType())
- {
- case LLSLURL::HOME_LOCATION:
- {
- gSavedSettings.setString("LoginLocation", LLSLURL::SIM_LOCATION_HOME);
- break;
- }
- case LLSLURL::LAST_LOCATION:
- {
- gSavedSettings.setString("LoginLocation", LLSLURL::SIM_LOCATION_LAST);
- break;
- }
- default:
- LLGridManager::getInstance()->setGridChoice(slurl.getGrid());
- break;
- }
+ LL_DEBUGS("AppInit")<<slurl.asString()<<LL_ENDL;
+
+ if ( slurl.isSpatial() )
+ {
+ std::string new_start = slurl.getSLURLString();
+ LL_DEBUGS("AppInit")<<new_start<<LL_ENDL;
+ sStartSLURL = slurl;
+ LLPanelLogin::onUpdateStartSLURL(slurl); // updates grid if needed
+
+ // remember that this is where we wanted to log in...if the login fails,
+ // the next attempt will default to the same place.
+ gSavedSettings.setString("NextLoginLocation", new_start);
+ // following a successful login, this is cleared
+ // and the default reverts to LoginLocation
+ }
+ else
+ {
+ LL_WARNS("AppInit")<<"Invalid start SLURL (ignored): "<<slurl.asString()<<LL_ENDL;
+ }
}
+// static
+LLSLURL& LLStartUp::getStartSLURL()
+{
+ return sStartSLURL;
+}
+
/**
* Read all proxy configuration settings and set up both the HTTP proxy and
* SOCKS proxy as needed.
@@ -3211,17 +3257,6 @@ bool process_login_success_response()
gSavedSettings.setU32("PreferredMaturity", preferredMaturity);
}
- // During the AO transition, this flag will be true. Then the flag will
- // go away. After the AO transition, this code and all the code that
- // uses it can be deleted.
- text = response["ao_transition"].asString();
- if (!text.empty())
- {
- if (text == "1")
- {
- gAgent.setAOTransition();
- }
- }
text = response["start_location"].asString();
if(!text.empty())
@@ -3283,11 +3318,8 @@ bool process_login_success_response()
{
// replace the default help URL format
gSavedSettings.setString("HelpURLFormat",text);
-
- // don't fall back to Standalone's pre-connection static help
- gSavedSettings.setBOOL("HelpUseLocal", false);
}
-
+
std::string home_location = response["home"];
if(!home_location.empty())
{
@@ -3428,6 +3460,14 @@ bool process_login_success_response()
}
+ // set the location of the Agent Appearance service, from which we can request
+ // avatar baked textures if they are supported by the current region
+ std::string agent_appearance_url = response["agent_appearance_service"];
+ if (!agent_appearance_url.empty())
+ {
+ LLAppearanceMgr::instance().setAppearanceServiceURL(agent_appearance_url);
+ }
+
// Set the location of the snapshot sharing config endpoint
std::string snapshot_config_url = response["snapshot_config_url"];
if(!snapshot_config_url.empty())
@@ -3472,13 +3512,6 @@ bool process_login_success_response()
void transition_back_to_login_panel(const std::string& emsg)
{
- if (gHeadlessClient && gSavedSettings.getBOOL("AutoLogin"))
- {
- LL_WARNS("AppInit") << "Failed to login!" << LL_ENDL;
- LL_WARNS("AppInit") << emsg << LL_ENDL;
- exit(0);
- }
-
// Bounce back to the login screen.
reset_login(); // calls LLStartUp::setStartupState( STATE_LOGIN_SHOW );
gSavedSettings.setBOOL("AutoLogin", FALSE);
diff --git a/indra/newview/llstartup.h b/indra/newview/llstartup.h
index 0a18ef1b2d..760e38890b 100644..100755
--- a/indra/newview/llstartup.h
+++ b/indra/newview/llstartup.h
@@ -34,6 +34,8 @@ class LLEventPump;
class LLStartupListener;
class LLSLURL;
+#include "llviewerstats.h"
+
// functions
bool idle_startup();
void release_start_screen();
@@ -109,10 +111,11 @@ public:
static void postStartupState();
static void setStartSLURL(const LLSLURL& slurl);
- static LLSLURL& getStartSLURL() { return sStartSLURL; }
+ static LLSLURL& getStartSLURL();
static bool startLLProxy(); // Initialize the SOCKS 5 proxy
+ static LLViewerStats::PhaseMap& getPhases() { return *sPhases; }
private:
static LLSLURL sStartSLURL;
@@ -120,6 +123,7 @@ private:
static EStartupState gStartupState; // Do not set directly, use LLStartup::setStartupState
static boost::scoped_ptr<LLEventPump> sStateWatcher;
static boost::scoped_ptr<LLStartupListener> sListener;
+ static boost::scoped_ptr<LLViewerStats::PhaseMap> sPhases;
};
diff --git a/indra/newview/llstartuplistener.cpp b/indra/newview/llstartuplistener.cpp
index d9a21f908e..d9a21f908e 100644..100755
--- a/indra/newview/llstartuplistener.cpp
+++ b/indra/newview/llstartuplistener.cpp
diff --git a/indra/newview/llstartuplistener.h b/indra/newview/llstartuplistener.h
index a35e11f6eb..a35e11f6eb 100644..100755
--- a/indra/newview/llstartuplistener.h
+++ b/indra/newview/llstartuplistener.h
diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp
index 89240c982f..ff69c6e9fd 100644..100755
--- a/indra/newview/llstatusbar.cpp
+++ b/indra/newview/llstatusbar.cpp
@@ -469,7 +469,7 @@ void LLStatusBar::onMouseEnterVolume()
LLRect vol_btn_rect = volbtn->getRect();
LLRect volume_pulldown_rect = mPanelVolumePulldown->getRect();
volume_pulldown_rect.setLeftTopAndSize(vol_btn_rect.mLeft -
- (volume_pulldown_rect.getWidth() - vol_btn_rect.getWidth())/2,
+ (volume_pulldown_rect.getWidth() - vol_btn_rect.getWidth()),
vol_btn_rect.mBottom,
volume_pulldown_rect.getWidth(),
volume_pulldown_rect.getHeight());
diff --git a/indra/newview/llstatusbar.h b/indra/newview/llstatusbar.h
index 9d28e6c2bc..9d28e6c2bc 100644..100755
--- a/indra/newview/llstatusbar.h
+++ b/indra/newview/llstatusbar.h
diff --git a/indra/newview/llstylemap.cpp b/indra/newview/llstylemap.cpp
index 43fe37ac77..43fe37ac77 100644..100755
--- a/indra/newview/llstylemap.cpp
+++ b/indra/newview/llstylemap.cpp
diff --git a/indra/newview/llstylemap.h b/indra/newview/llstylemap.h
index 8aa0af535c..8aa0af535c 100644..100755
--- a/indra/newview/llstylemap.h
+++ b/indra/newview/llstylemap.h
diff --git a/indra/newview/llsurface.cpp b/indra/newview/llsurface.cpp
index 66df7dae3e..93c7f54101 100644..100755
--- a/indra/newview/llsurface.cpp
+++ b/indra/newview/llsurface.cpp
@@ -56,13 +56,12 @@
#include "lldrawable.h"
extern LLPipeline gPipeline;
+extern bool gShiftFrame;
LLColor4U MAX_WATER_COLOR(0, 48, 96, 240);
S32 LLSurface::sTextureSize = 256;
-S32 LLSurface::sTexelsUpdated = 0;
-F32 LLSurface::sTextureUpdateTime = 0.f;
// ---------------- LLSurface:: Public Members ---------------
@@ -294,7 +293,7 @@ void LLSurface::initTextures()
mWaterObjp = (LLVOWater *)gObjectList.createObjectViewer(LLViewerObject::LL_VO_WATER, mRegionp);
gPipeline.createObject(mWaterObjp);
LLVector3d water_pos_global = from_region_handle(mRegionp->getHandle());
- water_pos_global += LLVector3d(128.0, 128.0, DEFAULT_WATER_HEIGHT);
+ water_pos_global += LLVector3d(128.0, 128.0, DEFAULT_WATER_HEIGHT); // region doesn't have a valid water height yet
mWaterObjp->setPositionGlobal(water_pos_global);
}
}
@@ -346,6 +345,19 @@ void LLSurface::getNeighboringRegions( std::vector<LLViewerRegion*>& uniqueRegio
}
}
+
+void LLSurface::getNeighboringRegionsStatus( std::vector<S32>& regions )
+{
+ S32 i;
+ for (i = 0; i < 8; i++)
+ {
+ if ( mNeighbors[i] != NULL )
+ {
+ regions.push_back( i );
+ }
+ }
+}
+
void LLSurface::connectNeighbor(LLSurface *neighborp, U32 direction)
{
S32 i;
@@ -608,6 +620,11 @@ void LLSurface::moveZ(const S32 x, const S32 y, const F32 delta)
void LLSurface::updatePatchVisibilities(LLAgent &agent)
{
+ if (gShiftFrame)
+ {
+ return;
+ }
+
LLVector3 pos_region = mRegionp->getPosRegionFromGlobal(gAgentCamera.getCameraPositionGlobal());
LLSurfacePatch *patchp;
@@ -628,7 +645,6 @@ void LLSurface::updatePatchVisibilities(LLAgent &agent)
BOOL LLSurface::idleUpdate(F32 max_update_time)
{
- LLMemType mt_ius(LLMemType::MTYPE_IDLE_UPDATE_SURFACE);
if (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_TERRAIN))
{
return FALSE;
@@ -1230,8 +1246,6 @@ BOOL LLSurface::generateWaterTexture(const F32 x, const F32 y,
y_end = tex_width;
}
- LLVector3d origin_global = from_region_handle(getRegion()->getHandle());
-
// OK, for now, just have the composition value equal the height at the point.
LLVector3 location;
LLColor4U coloru;
diff --git a/indra/newview/llsurface.h b/indra/newview/llsurface.h
index a4ef4fe2de..9d24bf8771 100644..100755
--- a/indra/newview/llsurface.h
+++ b/indra/newview/llsurface.h
@@ -142,6 +142,7 @@ public:
friend std::ostream& operator<<(std::ostream &s, const LLSurface &S);
void getNeighboringRegions( std::vector<LLViewerRegion*>& uniqueRegions );
+ void getNeighboringRegionsStatus( std::vector<S32>& regions );
public:
// Number of grid points on one side of a region, including +1 buffer for
@@ -168,9 +169,6 @@ public:
F32 mDetailTextureScale; // Number of times to repeat detail texture across this surface
- static F32 sTextureUpdateTime;
- static S32 sTexelsUpdated;
-
protected:
void createSTexture();
void createWaterTexture();
diff --git a/indra/newview/llsurfacepatch.cpp b/indra/newview/llsurfacepatch.cpp
index 5077c2c7e1..a9ba2bce9c 100644..100755
--- a/indra/newview/llsurfacepatch.cpp
+++ b/indra/newview/llsurfacepatch.cpp
@@ -43,6 +43,7 @@
#include "lldrawpool.h"
#include "noise.h"
+extern bool gShiftFrame;
extern U64 gFrameTime;
extern LLPipeline gPipeline;
@@ -218,7 +219,7 @@ void LLSurfacePatch::eval(const U32 x, const U32 y, const U32 stride, LLVector3
pos_agent.mV[VX] += x * mSurfacep->getMetersPerGrid();
pos_agent.mV[VY] += y * mSurfacep->getMetersPerGrid();
pos_agent.mV[VZ] = *(mDataZ + point_offset);
- *vertex = pos_agent;
+ *vertex = pos_agent-mVObjp->getRegion()->getOriginAgent();
LLVector3 rel_pos = pos_agent - mSurfacep->getOriginAgent();
LLVector3 tex_pos = rel_pos * (1.f/surface_stride);
@@ -366,10 +367,13 @@ void LLSurfacePatch::updateCameraDistanceRegion(const LLVector3 &pos_region)
{
if (LLPipeline::sDynamicLOD)
{
- LLVector3 dv = pos_region;
- dv -= mCenterRegion;
- mVisInfo.mDistance = llmax(0.f, (F32)(dv.magVec() - mRadius))/
- llmax(LLVOSurfacePatch::sLODFactor, 0.1f);
+ if (!gShiftFrame)
+ {
+ LLVector3 dv = pos_region;
+ dv -= mCenterRegion;
+ mVisInfo.mDistance = llmax(0.f, (F32)(dv.magVec() - mRadius))/
+ llmax(LLVOSurfacePatch::sLODFactor, 0.1f);
+ }
}
else
{
diff --git a/indra/newview/llsurfacepatch.h b/indra/newview/llsurfacepatch.h
index 8c8f501dce..8c8f501dce 100644..100755
--- a/indra/newview/llsurfacepatch.h
+++ b/indra/newview/llsurfacepatch.h
diff --git a/indra/newview/llsyswellitem.cpp b/indra/newview/llsyswellitem.cpp
index 057d80457c..057d80457c 100644..100755
--- a/indra/newview/llsyswellitem.cpp
+++ b/indra/newview/llsyswellitem.cpp
diff --git a/indra/newview/llsyswellitem.h b/indra/newview/llsyswellitem.h
index d961708a01..d961708a01 100644..100755
--- a/indra/newview/llsyswellitem.h
+++ b/indra/newview/llsyswellitem.h
diff --git a/indra/newview/llsyswellwindow.cpp b/indra/newview/llsyswellwindow.cpp
index 0cb6c85012..626d69aca4 100644..100755
--- a/indra/newview/llsyswellwindow.cpp
+++ b/indra/newview/llsyswellwindow.cpp
@@ -23,29 +23,18 @@
* $/LicenseInfo$
*/
-
#include "llviewerprecompiledheaders.h" // must be first include
-
#include "llsyswellwindow.h"
-#include "llagent.h"
-#include "llavatarnamecache.h"
-
-#include "llflatlistview.h"
-#include "llfloaterreg.h"
-#include "llnotifications.h"
-
-#include "llscriptfloater.h"
-#include "llviewercontrol.h"
-#include "llviewerwindow.h"
-
#include "llchiclet.h"
#include "llchicletbar.h"
-#include "lltoastpanel.h"
+#include "llflatlistview.h"
+#include "llfloaterreg.h"
#include "llnotificationmanager.h"
#include "llnotificationsutil.h"
+#include "llscriptfloater.h"
#include "llspeakers.h"
-#include "lltoolbarview.h"
+#include "lltoastpanel.h"
//---------------------------------------------------------------------------------
LLSysWellWindow::LLSysWellWindow(const LLSD& key) : LLTransientDockableFloater(NULL, true, key),
@@ -68,10 +57,6 @@ BOOL LLSysWellWindow::postBuild()
// get a corresponding channel
initChannel();
- // click on SysWell Window should clear "new message" state (and 'Lit' status). EXT-3147.
- // mouse up callback is not called in this case.
- setMouseDownCallback(boost::bind(&LLSysWellWindow::releaseNewMessagesState, this));
-
return LLTransientDockableFloater::postBuild();
}
@@ -98,9 +83,12 @@ void LLSysWellWindow::onStartUpToastClick(S32 x, S32 y, MASK mask)
void LLSysWellWindow::setSysWellChiclet(LLSysWellChiclet* chiclet)
{
mSysWellChiclet = chiclet;
- if(mSysWellChiclet)
- mSysWellChiclet->updateWidget(isWindowEmpty());
+ if(NULL != mSysWellChiclet)
+ {
+ mSysWellChiclet->updateWidget(isWindowEmpty());
+ }
}
+
//---------------------------------------------------------------------------------
LLSysWellWindow::~LLSysWellWindow()
{
@@ -111,7 +99,10 @@ void LLSysWellWindow::removeItemByID(const LLUUID& id)
{
if(mMessageList->removeItemByValue(id))
{
- mSysWellChiclet->updateWidget(isWindowEmpty());
+ if (NULL != mSysWellChiclet)
+ {
+ mSysWellChiclet->updateWidget(isWindowEmpty());
+ }
reshapeWindow();
}
else
@@ -127,6 +118,11 @@ void LLSysWellWindow::removeItemByID(const LLUUID& id)
}
}
+ LLPanel * LLSysWellWindow::findItemByID(const LLUUID& id)
+{
+ return mMessageList->getItemByValue(id);
+}
+
//---------------------------------------------------------------------------------
//---------------------------------------------------------------------------------
void LLSysWellWindow::initChannel()
@@ -165,11 +161,6 @@ void LLSysWellWindow::setVisible(BOOL visible)
mChannel->updateShowToastsState();
mChannel->redrawToasts();
}
-
- if (visible)
- {
- releaseNewMessagesState();
- }
}
//---------------------------------------------------------------------------------
@@ -219,14 +210,6 @@ void LLSysWellWindow::reshapeWindow()
}
}
-void LLSysWellWindow::releaseNewMessagesState()
-{
- if (NULL != mSysWellChiclet)
- {
- mSysWellChiclet->setNewMessagesState(false);
- }
-}
-
//---------------------------------------------------------------------------------
bool LLSysWellWindow::isWindowEmpty()
{
@@ -234,121 +217,6 @@ bool LLSysWellWindow::isWindowEmpty()
}
/************************************************************************/
-/* RowPanel implementation */
-/************************************************************************/
-
-//---------------------------------------------------------------------------------
-LLIMWellWindow::RowPanel::RowPanel(const LLSysWellWindow* parent, const LLUUID& sessionId,
- S32 chicletCounter, const std::string& name, const LLUUID& otherParticipantId) :
- LLPanel(LLPanel::Params()), mChiclet(NULL), mParent(parent)
-{
- buildFromFile( "panel_activeim_row.xml", NULL);
-
- // Choose which of the pre-created chiclets (IM/group) to use.
- // The other one gets hidden.
-
- LLIMChiclet::EType im_chiclet_type = LLIMChiclet::getIMSessionType(sessionId);
- switch (im_chiclet_type)
- {
- case LLIMChiclet::TYPE_GROUP:
- mChiclet = getChild<LLIMGroupChiclet>("group_chiclet");
- break;
- case LLIMChiclet::TYPE_AD_HOC:
- mChiclet = getChild<LLAdHocChiclet>("adhoc_chiclet");
- break;
- case LLIMChiclet::TYPE_UNKNOWN: // assign mChiclet a non-null value anyway
- case LLIMChiclet::TYPE_IM:
- mChiclet = getChild<LLIMP2PChiclet>("p2p_chiclet");
- break;
- }
-
- // Initialize chiclet.
- mChiclet->setChicletSizeChangedCallback(boost::bind(&LLIMWellWindow::RowPanel::onChicletSizeChanged, this, mChiclet, _2));
- mChiclet->enableCounterControl(true);
- mChiclet->setCounter(chicletCounter);
- mChiclet->setSessionId(sessionId);
- mChiclet->setIMSessionName(name);
- mChiclet->setOtherParticipantId(otherParticipantId);
- mChiclet->setVisible(true);
-
- if (im_chiclet_type == LLIMChiclet::TYPE_IM)
- {
- LLAvatarNameCache::get(otherParticipantId,
- boost::bind(&LLIMWellWindow::RowPanel::onAvatarNameCache,
- this, _1, _2));
- }
- else
- {
- LLTextBox* contactName = getChild<LLTextBox>("contact_name");
- contactName->setValue(name);
- }
-
- mCloseBtn = getChild<LLButton>("hide_btn");
- mCloseBtn->setCommitCallback(boost::bind(&LLIMWellWindow::RowPanel::onClosePanel, this));
-}
-
-//---------------------------------------------------------------------------------
-void LLIMWellWindow::RowPanel::onAvatarNameCache(const LLUUID& agent_id,
- const LLAvatarName& av_name)
-{
- LLTextBox* contactName = getChild<LLTextBox>("contact_name");
- contactName->setValue( av_name.getCompleteName() );
-}
-
-//---------------------------------------------------------------------------------
-void LLIMWellWindow::RowPanel::onChicletSizeChanged(LLChiclet* ctrl, const LLSD& param)
-{
- LLTextBox* text = getChild<LLTextBox>("contact_name");
- S32 new_text_left = mChiclet->getRect().mRight + CHICLET_HPAD;
- LLRect text_rect = text->getRect();
- text_rect.mLeft = new_text_left;
- text->setShape(text_rect);
-}
-
-//---------------------------------------------------------------------------------
-LLIMWellWindow::RowPanel::~RowPanel()
-{
-}
-
-//---------------------------------------------------------------------------------
-void LLIMWellWindow::RowPanel::onClosePanel()
-{
- gIMMgr->leaveSession(mChiclet->getSessionId());
- // This row panel will be removed from the list in LLSysWellWindow::sessionRemoved().
-}
-
-//---------------------------------------------------------------------------------
-void LLIMWellWindow::RowPanel::onMouseEnter(S32 x, S32 y, MASK mask)
-{
- setTransparentColor(LLUIColorTable::instance().getColor("SysWellItemSelected"));
-}
-
-//---------------------------------------------------------------------------------
-void LLIMWellWindow::RowPanel::onMouseLeave(S32 x, S32 y, MASK mask)
-{
- setTransparentColor(LLUIColorTable::instance().getColor("SysWellItemUnselected"));
-}
-
-//---------------------------------------------------------------------------------
-// virtual
-BOOL LLIMWellWindow::RowPanel::handleMouseDown(S32 x, S32 y, MASK mask)
-{
- // Pass the mouse down event to the chiclet (EXT-596).
- if (!mChiclet->pointInView(x, y) && !mCloseBtn->getRect().pointInRect(x, y)) // prevent double call of LLIMChiclet::onMouseDown()
- {
- mChiclet->onMouseDown();
- return TRUE;
- }
-
- return LLPanel::handleMouseDown(x, y, mask);
-}
-
-// virtual
-BOOL LLIMWellWindow::RowPanel::handleRightMouseDown(S32 x, S32 y, MASK mask)
-{
- return mChiclet->handleRightMouseDown(x, y, mask);
-}
-/************************************************************************/
/* ObjectRowPanel implementation */
/************************************************************************/
@@ -356,7 +224,7 @@ LLIMWellWindow::ObjectRowPanel::ObjectRowPanel(const LLUUID& notification_id, bo
: LLPanel()
, mChiclet(NULL)
{
- buildFromFile( "panel_active_object_row.xml", NULL);
+ buildFromFile( "panel_active_object_row.xml");
initChiclet(notification_id);
@@ -433,13 +301,19 @@ BOOL LLIMWellWindow::ObjectRowPanel::handleRightMouseDown(S32 x, S32 y, MASK mas
//////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
+LLNotificationWellWindow::WellNotificationChannel::WellNotificationChannel(LLNotificationWellWindow* well_window)
+: LLNotificationChannel(LLNotificationChannel::Params().name(well_window->getPathname())),
+ mWellWindow(well_window)
+{
+ connectToChannel("Notifications");
+ connectToChannel("Group Notifications");
+ connectToChannel("Offer");
+}
+
LLNotificationWellWindow::LLNotificationWellWindow(const LLSD& key)
-: LLSysWellWindow(key)
+: LLSysWellWindow(key)
{
- // init connections to the list's update events
- connectListUpdaterToSignal("notify");
- connectListUpdaterToSignal("groupnotify");
- connectListUpdaterToSignal("offer");
+ mNotificationUpdates.reset(new WellNotificationChannel(this));
}
// static
@@ -481,7 +355,6 @@ void LLNotificationWellWindow::addItem(LLSysWellItem::Params p)
{
mSysWellChiclet->updateWidget(isWindowEmpty());
reshapeWindow();
-
new_item->setOnItemCloseCallback(boost::bind(&LLNotificationWellWindow::onItemClose, this, _1));
new_item->setOnItemClickCallback(boost::bind(&LLNotificationWellWindow::onItemClick, this, _1));
}
@@ -519,7 +392,7 @@ void LLNotificationWellWindow::initChannel()
LLSysWellWindow::initChannel();
if(mChannel)
{
- mChannel->setOnStoreToastCallback(boost::bind(&LLNotificationWellWindow::onStoreToast, this, _1, _2));
+ mChannel->addOnStoreToastCallback(boost::bind(&LLNotificationWellWindow::onStoreToast, this, _1, _2));
}
}
@@ -546,20 +419,6 @@ void LLNotificationWellWindow::onStoreToast(LLPanel* info_panel, LLUUID id)
addItem(p);
}
-void LLNotificationWellWindow::connectListUpdaterToSignal(std::string notification_type)
-{
- LLNotificationsUI::LLNotificationManager* manager = LLNotificationsUI::LLNotificationManager::getInstance();
- LLNotificationsUI::LLEventHandler* n_handler = manager->getHandlerForNotification(notification_type);
- if(n_handler)
- {
- n_handler->setNotificationIDCallback(boost::bind(&LLNotificationWellWindow::removeItemByID, this, _1));
- }
- else
- {
- llwarns << "LLSysWellWindow::connectListUpdaterToSignal() - could not get a handler for '" << notification_type <<"' type of notifications" << llendl;
- }
-}
-
void LLNotificationWellWindow::onItemClick(LLSysWellItem* item)
{
LLUUID id = item->getID();
@@ -569,12 +428,24 @@ void LLNotificationWellWindow::onItemClick(LLSysWellItem* item)
void LLNotificationWellWindow::onItemClose(LLSysWellItem* item)
{
LLUUID id = item->getID();
- removeItemByID(id);
+
if(mChannel)
+ {
+ // removeItemByID() is invoked from killToastByNotificationID() and item will removed;
mChannel->killToastByNotificationID(id);
-}
+ }
+ else
+ {
+ // removeItemByID() should be called one time for each item to remove it from notification well
+ removeItemByID(id);
+ }
+}
+void LLNotificationWellWindow::onAdd( LLNotificationPtr notify )
+{
+ removeItemByID(notify->getID());
+}
/************************************************************************/
/* LLIMWellWindow implementation */
@@ -585,12 +456,10 @@ void LLNotificationWellWindow::onItemClose(LLSysWellItem* item)
LLIMWellWindow::LLIMWellWindow(const LLSD& key)
: LLSysWellWindow(key)
{
- LLIMMgr::getInstance()->addSessionObserver(this);
}
LLIMWellWindow::~LLIMWellWindow()
{
- LLIMMgr::getInstance()->removeSessionObserver(this);
}
// static
@@ -611,47 +480,11 @@ BOOL LLIMWellWindow::postBuild()
BOOL rv = LLSysWellWindow::postBuild();
setTitle(getString("title_im_well_window"));
- LLIMChiclet::sFindChicletsSignal.connect(boost::bind(&LLIMWellWindow::findIMChiclet, this, _1));
LLIMChiclet::sFindChicletsSignal.connect(boost::bind(&LLIMWellWindow::findObjectChiclet, this, _1));
return rv;
}
-//virtual
-void LLIMWellWindow::sessionAdded(const LLUUID& session_id,
- const std::string& name, const LLUUID& other_participant_id)
-{
- LLIMModel::LLIMSession* session = LLIMModel::getInstance()->findIMSession(session_id);
- if (!session) return;
-
- // no need to spawn chiclets for participants in P2P calls called through Avaline
- if (session->isP2P() && session->isOtherParticipantAvaline()) return;
-
- if (mMessageList->getItemByValue(session_id)) return;
-
- addIMRow(session_id, 0, name, other_participant_id);
- reshapeWindow();
-}
-
-//virtual
-void LLIMWellWindow::sessionRemoved(const LLUUID& sessionId)
-{
- delIMRow(sessionId);
- reshapeWindow();
-}
-
-//virtual
-void LLIMWellWindow::sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id)
-{
- //for outgoing ad-hoc and group im sessions only
- LLChiclet* chiclet = findIMChiclet(old_session_id);
- if (chiclet)
- {
- chiclet->setSessionId(new_session_id);
- mMessageList->updateValue(old_session_id, new_session_id);
- }
-}
-
LLChiclet* LLIMWellWindow::findObjectChiclet(const LLUUID& notification_id)
{
if (!mMessageList) return NULL;
@@ -668,85 +501,13 @@ LLChiclet* LLIMWellWindow::findObjectChiclet(const LLUUID& notification_id)
//////////////////////////////////////////////////////////////////////////
// PRIVATE METHODS
-LLChiclet* LLIMWellWindow::findIMChiclet(const LLUUID& sessionId)
-{
- if (!mMessageList) return NULL;
-
- LLChiclet* res = NULL;
- RowPanel* panel = mMessageList->getTypedItemByValue<RowPanel>(sessionId);
- if (panel != NULL)
- {
- res = panel->mChiclet;
- }
-
- return res;
-}
-
-//---------------------------------------------------------------------------------
-void LLIMWellWindow::addIMRow(const LLUUID& sessionId, S32 chicletCounter,
- const std::string& name, const LLUUID& otherParticipantId)
-{
- RowPanel* item = new RowPanel(this, sessionId, chicletCounter, name, otherParticipantId);
- if (mMessageList->addItem(item, sessionId))
- {
- mSysWellChiclet->updateWidget(isWindowEmpty());
- }
- else
- {
- llwarns << "Unable to add IM Row into the list, sessionID: " << sessionId
- << ", name: " << name
- << ", other participant ID: " << otherParticipantId
- << llendl;
-
- item->die();
- }
-}
-
-//---------------------------------------------------------------------------------
-void LLIMWellWindow::delIMRow(const LLUUID& sessionId)
-{
- //fix for EXT-3252
- //without this line LLIMWellWindow receive onFocusLost
- //and hide itself. It was becaue somehow LLIMChicklet was in focus group for
- //LLIMWellWindow...
- //But I didn't find why this happen..
- gFocusMgr.clearLastFocusForGroup(this);
-
- if (mMessageList->removeItemByValue(sessionId))
- {
- mSysWellChiclet->updateWidget(isWindowEmpty());
- }
- else
- {
- llwarns << "Unable to remove IM Row from the list, sessionID: " << sessionId
- << llendl;
- }
-
- // remove all toasts that belong to this session from a screen
- if(mChannel)
- mChannel->removeToastsBySessionID(sessionId);
-
- // hide chiclet window if there are no items left
- if(isWindowEmpty())
- {
- setVisible(FALSE);
- }
- else
- {
- setFocus(true);
- }
-}
void LLIMWellWindow::addObjectRow(const LLUUID& notification_id, bool new_message/* = false*/)
{
if (mMessageList->getItemByValue(notification_id) == NULL)
{
ObjectRowPanel* item = new ObjectRowPanel(notification_id, new_message);
- if (mMessageList->addItem(item, notification_id))
- {
- mSysWellChiclet->updateWidget(isWindowEmpty());
- }
- else
+ if (!mMessageList->addItem(item, notification_id))
{
llwarns << "Unable to add Object Row into the list, notificationID: " << notification_id << llendl;
item->die();
@@ -757,14 +518,7 @@ void LLIMWellWindow::addObjectRow(const LLUUID& notification_id, bool new_messag
void LLIMWellWindow::removeObjectRow(const LLUUID& notification_id)
{
- if (mMessageList->removeItemByValue(notification_id))
- {
- if (mSysWellChiclet)
- {
- mSysWellChiclet->updateWidget(isWindowEmpty());
- }
- }
- else
+ if (!mMessageList->removeItemByValue(notification_id))
{
llwarns << "Unable to remove Object Row from the list, notificationID: " << notification_id << llendl;
}
@@ -777,21 +531,6 @@ void LLIMWellWindow::removeObjectRow(const LLUUID& notification_id)
}
}
-
-void LLIMWellWindow::addIMRow(const LLUUID& session_id)
-{
- if (hasIMRow(session_id)) return;
-
- LLIMModel* im_model = LLIMModel::getInstance();
- addIMRow(session_id, 0, im_model->getName(session_id), im_model->getOtherParticipantID(session_id));
- reshapeWindow();
-}
-
-bool LLIMWellWindow::hasIMRow(const LLUUID& session_id)
-{
- return mMessageList->getItemByValue(session_id);
-}
-
void LLIMWellWindow::closeAll()
{
// Generate an ignorable alert dialog if there is an active voice IM sesion
@@ -836,13 +575,6 @@ void LLIMWellWindow::closeAllImpl()
{
LLPanel* panel = mMessageList->getItemByValue(*iter);
- RowPanel* im_panel = dynamic_cast <RowPanel*> (panel);
- if (im_panel)
- {
- gIMMgr->leaveSession(*iter);
- continue;
- }
-
ObjectRowPanel* obj_panel = dynamic_cast <ObjectRowPanel*> (panel);
if (obj_panel)
{
@@ -867,4 +599,4 @@ bool LLIMWellWindow::confirmCloseAll(const LLSD& notification, const LLSD& respo
return false;
}
-// EOF
+
diff --git a/indra/newview/llsyswellwindow.h b/indra/newview/llsyswellwindow.h
index 272e9cfcb1..71b41476f5 100644..100755
--- a/indra/newview/llsyswellwindow.h
+++ b/indra/newview/llsyswellwindow.h
@@ -27,29 +27,26 @@
#ifndef LL_LLSYSWELLWINDOW_H
#define LL_LLSYSWELLWINDOW_H
+#include "llimview.h"
+#include "llnotifications.h"
+#include "llscreenchannel.h"
#include "llsyswellitem.h"
-
#include "lltransientdockablefloater.h"
-#include "llbutton.h"
-#include "llscreenchannel.h"
-#include "llscrollcontainer.h"
-#include "llimview.h"
-
-#include "boost/shared_ptr.hpp"
class LLAvatarName;
-class LLFlatListView;
class LLChiclet;
+class LLFlatListView;
class LLIMChiclet;
class LLScriptChiclet;
class LLSysWellChiclet;
-
class LLSysWellWindow : public LLTransientDockableFloater
{
public:
+ LOG_CLASS(LLSysWellWindow);
+
LLSysWellWindow(const LLSD& key);
- ~LLSysWellWindow();
+ virtual ~LLSysWellWindow();
BOOL postBuild();
// other interface functions
@@ -58,6 +55,7 @@ public:
// Operating with items
void removeItemByID(const LLUUID& id);
+ LLPanel * findItemByID(const LLUUID& id);
// Operating with outfit
virtual void setVisible(BOOL visible);
@@ -84,7 +82,6 @@ protected:
virtual const std::string& getAnchorViewName() = 0;
void reshapeWindow();
- void releaseNewMessagesState();
// pointer to a corresponding channel's instance
LLNotificationsUI::LLScreenChannel* mChannel;
@@ -111,7 +108,7 @@ public:
/*virtual*/ BOOL postBuild();
/*virtual*/ void setVisible(BOOL visible);
-
+ /*virtual*/ void onAdd(LLNotificationPtr notify);
// Operating with items
void addItem(LLSysWellItem::Params p);
@@ -119,6 +116,18 @@ public:
void closeAll();
protected:
+ struct WellNotificationChannel : public LLNotificationChannel
+ {
+ WellNotificationChannel(LLNotificationWellWindow*);
+ void onDelete(LLNotificationPtr notify)
+ {
+ mWellWindow->removeItemByID(notify->getID());
+ }
+
+ LLNotificationWellWindow* mWellWindow;
+ };
+
+ LLNotificationChannelPtr mNotificationUpdates;
/*virtual*/ const std::string& getAnchorViewName() { return NOTIFICATION_WELL_ANCHOR_NAME; }
private:
@@ -126,12 +135,8 @@ private:
void initChannel();
void clearScreenChannels();
-
void onStoreToast(LLPanel* info_panel, LLUUID id);
- // connect counter and list updaters to the corresponding signals
- void connectListUpdaterToSignal(std::string notification_type);
-
// Handlers
void onItemClick(LLSysWellItem* item);
void onItemClose(LLSysWellItem* item);
@@ -146,7 +151,7 @@ private:
*
* It contains a list list of all active IM sessions.
*/
-class LLIMWellWindow : public LLSysWellWindow, LLIMSessionObserver, LLInitClass<LLIMWellWindow>
+class LLIMWellWindow : public LLSysWellWindow, LLInitClass<LLIMWellWindow>
{
public:
LLIMWellWindow(const LLSD& key);
@@ -158,57 +163,19 @@ public:
/*virtual*/ BOOL postBuild();
- // LLIMSessionObserver observe triggers
- /*virtual*/ void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id);
- /*virtual*/ void sessionRemoved(const LLUUID& session_id);
- /*virtual*/ void sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id);
-
void addObjectRow(const LLUUID& notification_id, bool new_message = false);
void removeObjectRow(const LLUUID& notification_id);
-
- void addIMRow(const LLUUID& session_id);
- bool hasIMRow(const LLUUID& session_id);
-
void closeAll();
protected:
/*virtual*/ const std::string& getAnchorViewName() { return IM_WELL_ANCHOR_NAME; }
private:
- LLChiclet * findIMChiclet(const LLUUID& sessionId);
LLChiclet* findObjectChiclet(const LLUUID& notification_id);
- void addIMRow(const LLUUID& sessionId, S32 chicletCounter, const std::string& name, const LLUUID& otherParticipantId);
- void delIMRow(const LLUUID& sessionId);
bool confirmCloseAll(const LLSD& notification, const LLSD& response);
void closeAllImpl();
- /**
- * Scrolling row panel.
- */
- class RowPanel: public LLPanel
- {
- public:
- RowPanel(const LLSysWellWindow* parent, const LLUUID& sessionId, S32 chicletCounter,
- const std::string& name, const LLUUID& otherParticipantId);
- virtual ~RowPanel();
- void onMouseEnter(S32 x, S32 y, MASK mask);
- void onMouseLeave(S32 x, S32 y, MASK mask);
- BOOL handleMouseDown(S32 x, S32 y, MASK mask);
- BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
-
- private:
- static const S32 CHICLET_HPAD = 10;
- void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name);
- void onChicletSizeChanged(LLChiclet* ctrl, const LLSD& param);
- void onClosePanel();
- public:
- LLIMChiclet* mChiclet;
- private:
- LLButton* mCloseBtn;
- const LLSysWellWindow* mParent;
- };
-
class ObjectRowPanel: public LLPanel
{
public:
diff --git a/indra/newview/lltable.h b/indra/newview/lltable.h
index d75ef84ae4..d75ef84ae4 100644..100755
--- a/indra/newview/lltable.h
+++ b/indra/newview/lltable.h
diff --git a/indra/newview/llteleporthistory.cpp b/indra/newview/llteleporthistory.cpp
index 50a088b799..50a088b799 100644..100755
--- a/indra/newview/llteleporthistory.cpp
+++ b/indra/newview/llteleporthistory.cpp
diff --git a/indra/newview/llteleporthistory.h b/indra/newview/llteleporthistory.h
index e9c29c39bf..e9c29c39bf 100644..100755
--- a/indra/newview/llteleporthistory.h
+++ b/indra/newview/llteleporthistory.h
diff --git a/indra/newview/llteleporthistorystorage.cpp b/indra/newview/llteleporthistorystorage.cpp
index af5a047da4..af5a047da4 100644..100755
--- a/indra/newview/llteleporthistorystorage.cpp
+++ b/indra/newview/llteleporthistorystorage.cpp
diff --git a/indra/newview/llteleporthistorystorage.h b/indra/newview/llteleporthistorystorage.h
index cf4c85a991..cf4c85a991 100644..100755
--- a/indra/newview/llteleporthistorystorage.h
+++ b/indra/newview/llteleporthistorystorage.h
diff --git a/indra/newview/lltexglobalcolor.cpp b/indra/newview/lltexglobalcolor.cpp
deleted file mode 100644
index ebe5ccd6c0..0000000000
--- a/indra/newview/lltexglobalcolor.cpp
+++ /dev/null
@@ -1,152 +0,0 @@
-/**
- * @file lltexlayerglobalcolor.cpp
- * @brief Color for texture layers.
- *
- * $LicenseInfo:firstyear=2008&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 "llviewerprecompiledheaders.h"
-#include "llagent.h"
-#include "lltexlayer.h"
-#include "llvoavatar.h"
-#include "llwearable.h"
-#include "lltexglobalcolor.h"
-
-//-----------------------------------------------------------------------------
-// LLTexGlobalColor
-//-----------------------------------------------------------------------------
-
-LLTexGlobalColor::LLTexGlobalColor(LLVOAvatar* avatar)
- :
- mAvatar(avatar),
- mInfo(NULL)
-{
-}
-
-LLTexGlobalColor::~LLTexGlobalColor()
-{
- // mParamColorList are LLViewerVisualParam's and get deleted with ~LLCharacter()
- //std::for_each(mParamColorList.begin(), mParamColorList.end(), DeletePointer());
-}
-
-BOOL LLTexGlobalColor::setInfo(LLTexGlobalColorInfo *info)
-{
- llassert(mInfo == NULL);
- mInfo = info;
- //mID = info->mID; // No ID
-
- mParamGlobalColorList.reserve(mInfo->mParamColorInfoList.size());
- for (param_color_info_list_t::iterator iter = mInfo->mParamColorInfoList.begin();
- iter != mInfo->mParamColorInfoList.end();
- iter++)
- {
- LLTexParamGlobalColor* param_color = new LLTexParamGlobalColor(this);
- if (!param_color->setInfo(*iter, TRUE))
- {
- mInfo = NULL;
- return FALSE;
- }
- mParamGlobalColorList.push_back(param_color);
- }
-
- return TRUE;
-}
-
-LLColor4 LLTexGlobalColor::getColor() const
-{
- // Sum of color params
- if (mParamGlobalColorList.empty())
- return LLColor4(1.f, 1.f, 1.f, 1.f);
-
- LLColor4 net_color(0.f, 0.f, 0.f, 0.f);
- LLTexLayer::calculateTexLayerColor(mParamGlobalColorList, net_color);
- return net_color;
-}
-
-const std::string& LLTexGlobalColor::getName() const
-{
- return mInfo->mName;
-}
-
-//-----------------------------------------------------------------------------
-// LLTexParamGlobalColor
-//-----------------------------------------------------------------------------
-LLTexParamGlobalColor::LLTexParamGlobalColor(LLTexGlobalColor* tex_global_color) :
- LLTexLayerParamColor(tex_global_color->getAvatar()),
- mTexGlobalColor(tex_global_color)
-{
-}
-
-/*virtual*/ LLViewerVisualParam* LLTexParamGlobalColor::cloneParam(LLWearable* wearable) const
-{
- LLTexParamGlobalColor *new_param = new LLTexParamGlobalColor(mTexGlobalColor);
- *new_param = *this;
- return new_param;
-}
-
-void LLTexParamGlobalColor::onGlobalColorChanged(bool upload_bake)
-{
- mAvatar->onGlobalColorChanged(mTexGlobalColor, upload_bake);
-}
-
-//-----------------------------------------------------------------------------
-// LLTexGlobalColorInfo
-//-----------------------------------------------------------------------------
-
-LLTexGlobalColorInfo::LLTexGlobalColorInfo()
-{
-}
-
-
-LLTexGlobalColorInfo::~LLTexGlobalColorInfo()
-{
- for_each(mParamColorInfoList.begin(), mParamColorInfoList.end(), DeletePointer());
-}
-
-BOOL LLTexGlobalColorInfo::parseXml(LLXmlTreeNode* node)
-{
- // name attribute
- static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name");
- if (!node->getFastAttributeString(name_string, mName))
- {
- llwarns << "<global_color> element is missing name attribute." << llendl;
- return FALSE;
- }
- // <param> sub-element
- for (LLXmlTreeNode* child = node->getChildByName("param");
- child;
- child = node->getNextNamedChild())
- {
- if (child->getChildByName("param_color"))
- {
- // <param><param_color/></param>
- LLTexLayerParamColorInfo* info = new LLTexLayerParamColorInfo();
- if (!info->parseXml(child))
- {
- delete info;
- return FALSE;
- }
- mParamColorInfoList.push_back(info);
- }
- }
- return TRUE;
-}
diff --git a/indra/newview/lltexglobalcolor.h b/indra/newview/lltexglobalcolor.h
deleted file mode 100644
index ae04798445..0000000000
--- a/indra/newview/lltexglobalcolor.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/**
- * @file lltexglobalcolor.h
- * @brief This is global texture color info used by llvoavatar.
- *
- * $LicenseInfo:firstyear=2008&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$
- */
-
-#ifndef LL_LLTEXGLOBALCOLOR_H
-#define LL_LLTEXGLOBALCOLOR_H
-
-#include "lltexlayer.h"
-#include "lltexlayerparams.h"
-
-class LLVOAvatar;
-class LLWearable;
-class LLTexGlobalColorInfo;
-
-class LLTexGlobalColor
-{
-public:
- LLTexGlobalColor( LLVOAvatar* avatar );
- ~LLTexGlobalColor();
-
- LLTexGlobalColorInfo* getInfo() const { return mInfo; }
- // This sets mInfo and calls initialization functions
- BOOL setInfo(LLTexGlobalColorInfo *info);
-
- LLVOAvatar* getAvatar() const { return mAvatar; }
- LLColor4 getColor() const;
- const std::string& getName() const;
-
-private:
- param_color_list_t mParamGlobalColorList;
- LLVOAvatar* mAvatar; // just backlink, don't LLPointer
- LLTexGlobalColorInfo *mInfo;
-};
-
-// Used by llvoavatar to determine skin/eye/hair color.
-class LLTexGlobalColorInfo
-{
- friend class LLTexGlobalColor;
-public:
- LLTexGlobalColorInfo();
- ~LLTexGlobalColorInfo();
-
- BOOL parseXml(LLXmlTreeNode* node);
-
-private:
- param_color_info_list_t mParamColorInfoList;
- std::string mName;
-};
-
-class LLTexParamGlobalColor : public LLTexLayerParamColor
-{
-public:
- LLTexParamGlobalColor(LLTexGlobalColor *tex_color);
- /*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable) const;
-protected:
- /*virtual*/ void onGlobalColorChanged(bool upload_bake);
-private:
- LLTexGlobalColor* mTexGlobalColor;
-};
-
-#endif
diff --git a/indra/newview/lltexlayer.cpp b/indra/newview/lltexlayer.cpp
deleted file mode 100644
index 6f6d5dbf12..0000000000
--- a/indra/newview/lltexlayer.cpp
+++ /dev/null
@@ -1,2506 +0,0 @@
-/**
- * @file lltexlayer.cpp
- * @brief A texture layer. Used for avatars.
- *
- * $LicenseInfo:firstyear=2002&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 "llviewerprecompiledheaders.h"
-
-#include "lltexlayer.h"
-
-#include "llagent.h"
-#include "llimagej2c.h"
-#include "llimagetga.h"
-#include "llnotificationsutil.h"
-#include "llvfile.h"
-#include "llvfs.h"
-#include "llviewerstats.h"
-#include "llviewerregion.h"
-#include "llvoavatar.h"
-#include "llvoavatarself.h"
-#include "pipeline.h"
-#include "llassetuploadresponders.h"
-#include "lltexlayerparams.h"
-#include "llui.h"
-#include "llagentwearables.h"
-#include "llwearable.h"
-#include "llviewercontrol.h"
-#include "llviewershadermgr.h"
-#include "llviewervisualparam.h"
-
-//#include "../tools/imdebug/imdebug.h"
-
-using namespace LLVOAvatarDefines;
-
-static const S32 BAKE_UPLOAD_ATTEMPTS = 7;
-static const F32 BAKE_UPLOAD_RETRY_DELAY = 2.f; // actual delay grows by power of 2 each attempt
-
-class LLTexLayerInfo
-{
- friend class LLTexLayer;
- friend class LLTexLayerTemplate;
- friend class LLTexLayerInterface;
-public:
- LLTexLayerInfo();
- ~LLTexLayerInfo();
-
- BOOL parseXml(LLXmlTreeNode* node);
- BOOL createVisualParams(LLVOAvatar *avatar);
- BOOL isUserSettable() { return mLocalTexture != -1; }
- S32 getLocalTexture() const { return mLocalTexture; }
- BOOL getOnlyAlpha() const { return mUseLocalTextureAlphaOnly; }
- std::string getName() const { return mName; }
-
-private:
- std::string mName;
-
- BOOL mWriteAllChannels; // Don't use masking. Just write RGBA into buffer,
- LLTexLayerInterface::ERenderPass mRenderPass;
-
- std::string mGlobalColor;
- LLColor4 mFixedColor;
-
- S32 mLocalTexture;
- std::string mStaticImageFileName;
- BOOL mStaticImageIsMask;
- BOOL mUseLocalTextureAlphaOnly; // Ignore RGB channels from the input texture. Use alpha as a mask
- BOOL mIsVisibilityMask;
-
- typedef std::vector< std::pair< std::string,BOOL > > morph_name_list_t;
- morph_name_list_t mMorphNameList;
- param_color_info_list_t mParamColorInfoList;
- param_alpha_info_list_t mParamAlphaInfoList;
-};
-
-//-----------------------------------------------------------------------------
-// LLBakedUploadData()
-//-----------------------------------------------------------------------------
-LLBakedUploadData::LLBakedUploadData(const LLVOAvatarSelf* avatar,
- LLTexLayerSet* layerset,
- const LLUUID& id,
- bool highest_res) :
- mAvatar(avatar),
- mTexLayerSet(layerset),
- mID(id),
- mStartTime(LLFrameTimer::getTotalTime()), // Record starting time
- mIsHighestRes(highest_res)
-{
-}
-
-//-----------------------------------------------------------------------------
-// LLTexLayerSetBuffer
-// The composite image that a LLTexLayerSet writes to. Each LLTexLayerSet has one.
-//-----------------------------------------------------------------------------
-
-// static
-S32 LLTexLayerSetBuffer::sGLByteCount = 0;
-
-LLTexLayerSetBuffer::LLTexLayerSetBuffer(LLTexLayerSet* const owner,
- S32 width, S32 height) :
- // ORDER_LAST => must render these after the hints are created.
- LLViewerDynamicTexture( width, height, 4, LLViewerDynamicTexture::ORDER_LAST, TRUE ),
- mUploadPending(FALSE), // Not used for any logic here, just to sync sending of updates
- mNeedsUpload(FALSE),
- mNumLowresUploads(0),
- mUploadFailCount(0),
- mNeedsUpdate(TRUE),
- mNumLowresUpdates(0),
- mTexLayerSet(owner)
-{
- LLTexLayerSetBuffer::sGLByteCount += getSize();
- mNeedsUploadTimer.start();
- mNeedsUpdateTimer.start();
-}
-
-LLTexLayerSetBuffer::~LLTexLayerSetBuffer()
-{
- LLTexLayerSetBuffer::sGLByteCount -= getSize();
- destroyGLTexture();
- for( S32 order = 0; order < ORDER_COUNT; order++ )
- {
- LLViewerDynamicTexture::sInstances[order].erase(this); // will fail in all but one case.
- }
-}
-
-//virtual
-S8 LLTexLayerSetBuffer::getType() const
-{
- return LLViewerDynamicTexture::LL_TEX_LAYER_SET_BUFFER ;
-}
-
-//virtual
-void LLTexLayerSetBuffer::restoreGLTexture()
-{
- LLViewerDynamicTexture::restoreGLTexture() ;
-}
-
-//virtual
-void LLTexLayerSetBuffer::destroyGLTexture()
-{
- LLViewerDynamicTexture::destroyGLTexture() ;
-}
-
-// static
-void LLTexLayerSetBuffer::dumpTotalByteCount()
-{
- llinfos << "Composite System GL Buffers: " << (LLTexLayerSetBuffer::sGLByteCount/1024) << "KB" << llendl;
-}
-
-void LLTexLayerSetBuffer::requestUpdate()
-{
- restartUpdateTimer();
- mNeedsUpdate = TRUE;
- mNumLowresUpdates = 0;
- // If we're in the middle of uploading a baked texture, we don't care about it any more.
- // When it's downloaded, ignore it.
- mUploadID.setNull();
-}
-
-void LLTexLayerSetBuffer::requestUpload()
-{
- conditionalRestartUploadTimer();
- mNeedsUpload = TRUE;
- mNumLowresUploads = 0;
- mUploadPending = TRUE;
-}
-
-void LLTexLayerSetBuffer::conditionalRestartUploadTimer()
-{
- // If we requested a new upload but haven't even uploaded
- // a low res version of our last upload request, then
- // keep the timer ticking instead of resetting it.
- if (mNeedsUpload && (mNumLowresUploads == 0))
- {
- mNeedsUploadTimer.unpause();
- }
- else
- {
- mNeedsUploadTimer.reset();
- mNeedsUploadTimer.start();
- }
-}
-
-void LLTexLayerSetBuffer::restartUpdateTimer()
-{
- mNeedsUpdateTimer.reset();
- mNeedsUpdateTimer.start();
-}
-
-void LLTexLayerSetBuffer::cancelUpload()
-{
- mNeedsUpload = FALSE;
- mUploadPending = FALSE;
- mNeedsUploadTimer.pause();
- mUploadRetryTimer.reset();
-}
-
-void LLTexLayerSetBuffer::pushProjection() const
-{
- gGL.matrixMode(LLRender::MM_PROJECTION);
- gGL.pushMatrix();
- gGL.loadIdentity();
- gGL.ortho(0.0f, mFullWidth, 0.0f, mFullHeight, -1.0f, 1.0f);
-
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.pushMatrix();
- gGL.loadIdentity();
-}
-
-void LLTexLayerSetBuffer::popProjection() const
-{
- gGL.matrixMode(LLRender::MM_PROJECTION);
- gGL.popMatrix();
-
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.popMatrix();
-}
-
-BOOL LLTexLayerSetBuffer::needsRender()
-{
- llassert(mTexLayerSet->getAvatar() == gAgentAvatarp);
- if (!isAgentAvatarValid()) return FALSE;
-
- const BOOL upload_now = mNeedsUpload && isReadyToUpload();
- const BOOL update_now = mNeedsUpdate && isReadyToUpdate();
-
- // Don't render if we don't want to (or aren't ready to) upload or update.
- if (!(update_now || upload_now))
- {
- return FALSE;
- }
-
- // Don't render if we're animating our appearance.
- if (gAgentAvatarp->getIsAppearanceAnimating())
- {
- return FALSE;
- }
-
- // Don't render if we are trying to create a shirt texture but aren't wearing a skirt.
- if (gAgentAvatarp->getBakedTE(mTexLayerSet) == LLVOAvatarDefines::TEX_SKIRT_BAKED &&
- !gAgentAvatarp->isWearingWearableType(LLWearableType::WT_SKIRT))
- {
- cancelUpload();
- return FALSE;
- }
-
- // Render if we have at least minimal level of detail for each local texture.
- return mTexLayerSet->isLocalTextureDataAvailable();
-}
-
-void LLTexLayerSetBuffer::preRender(BOOL clear_depth)
-{
- // Set up an ortho projection
- pushProjection();
-
- // keep depth buffer, we don't need to clear it
- LLViewerDynamicTexture::preRender(FALSE);
-}
-
-void LLTexLayerSetBuffer::postRender(BOOL success)
-{
- popProjection();
-
- LLViewerDynamicTexture::postRender(success);
-}
-
-BOOL LLTexLayerSetBuffer::render()
-{
- // Default color mask for tex layer render
- gGL.setColorMask(true, true);
-
- // do we need to upload, and do we have sufficient data to create an uploadable composite?
- // TODO: When do we upload the texture if gAgent.mNumPendingQueries is non-zero?
- const BOOL upload_now = mNeedsUpload && isReadyToUpload();
- const BOOL update_now = mNeedsUpdate && isReadyToUpdate();
-
- BOOL success = TRUE;
-
- bool use_shaders = LLGLSLShader::sNoFixedFunction;
-
- if (use_shaders)
- {
- gAlphaMaskProgram.bind();
- gAlphaMaskProgram.setMinimumAlpha(0.004f);
- }
-
- LLVertexBuffer::unbind();
-
- // Composite the color data
- LLGLSUIDefault gls_ui;
- success &= mTexLayerSet->render( mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight );
- gGL.flush();
-
- if(upload_now)
- {
- if (!success)
- {
- llinfos << "Failed attempt to bake " << mTexLayerSet->getBodyRegionName() << llendl;
- mUploadPending = FALSE;
- }
- else
- {
- if (mTexLayerSet->isVisible())
- {
- mTexLayerSet->getAvatar()->debugBakedTextureUpload(mTexLayerSet->getBakedTexIndex(), FALSE); // FALSE for start of upload, TRUE for finish.
- doUpload();
- }
- else
- {
- mUploadPending = FALSE;
- mNeedsUpload = FALSE;
- mNeedsUploadTimer.pause();
- mTexLayerSet->getAvatar()->setNewBakedTexture(mTexLayerSet->getBakedTexIndex(),IMG_INVISIBLE);
- }
- }
- }
-
- if (update_now)
- {
- doUpdate();
- }
-
- if (use_shaders)
- {
- gAlphaMaskProgram.unbind();
- }
-
- LLVertexBuffer::unbind();
-
- // reset GL state
- gGL.setColorMask(true, true);
- gGL.setSceneBlendType(LLRender::BT_ALPHA);
-
- // we have valid texture data now
- mGLTexturep->setGLTextureCreated(true);
-
- return success;
-}
-
-BOOL LLTexLayerSetBuffer::isInitialized(void) const
-{
- return mGLTexturep.notNull() && mGLTexturep->isGLTextureCreated();
-}
-
-BOOL LLTexLayerSetBuffer::uploadPending() const
-{
- return mUploadPending;
-}
-
-BOOL LLTexLayerSetBuffer::uploadNeeded() const
-{
- return mNeedsUpload;
-}
-
-BOOL LLTexLayerSetBuffer::uploadInProgress() const
-{
- return !mUploadID.isNull();
-}
-
-BOOL LLTexLayerSetBuffer::isReadyToUpload() const
-{
- if (!gAgentQueryManager.hasNoPendingQueries()) return FALSE; // Can't upload if there are pending queries.
- if (isAgentAvatarValid() && !gAgentAvatarp->isUsingBakedTextures()) return FALSE; // Don't upload if avatar is using composites.
-
- BOOL ready = FALSE;
- if (mTexLayerSet->isLocalTextureDataFinal())
- {
- // If we requested an upload and have the final LOD ready, upload (or wait a while if this is a retry)
- if (mUploadFailCount == 0)
- {
- ready = TRUE;
- }
- else
- {
- ready = mUploadRetryTimer.getElapsedTimeF32() >= BAKE_UPLOAD_RETRY_DELAY * (1 << (mUploadFailCount - 1));
- }
- }
- else
- {
- // Upload if we've hit a timeout. Upload is a pretty expensive process so we need to make sure
- // we aren't doing uploads too frequently.
- const U32 texture_timeout = gSavedSettings.getU32("AvatarBakedTextureUploadTimeout");
- if (texture_timeout != 0)
- {
- // The timeout period increases exponentially between every lowres upload in order to prevent
- // spamming the server with frequent uploads.
- const U32 texture_timeout_threshold = texture_timeout*(1 << mNumLowresUploads);
-
- // If we hit our timeout and have textures available at even lower resolution, then upload.
- const BOOL is_upload_textures_timeout = mNeedsUploadTimer.getElapsedTimeF32() >= texture_timeout_threshold;
- const BOOL has_lower_lod = mTexLayerSet->isLocalTextureDataAvailable();
- ready = has_lower_lod && is_upload_textures_timeout;
- }
- }
-
- return ready;
-}
-
-BOOL LLTexLayerSetBuffer::isReadyToUpdate() const
-{
- // If we requested an update and have the final LOD ready, then update.
- if (mTexLayerSet->isLocalTextureDataFinal()) return TRUE;
-
- // If we haven't done an update yet, then just do one now regardless of state of textures.
- if (mNumLowresUpdates == 0) return TRUE;
-
- // Update if we've hit a timeout. Unlike for uploads, we can make this timeout fairly small
- // since render unnecessarily doesn't cost much.
- const U32 texture_timeout = gSavedSettings.getU32("AvatarBakedLocalTextureUpdateTimeout");
- if (texture_timeout != 0)
- {
- // If we hit our timeout and have textures available at even lower resolution, then update.
- const BOOL is_update_textures_timeout = mNeedsUpdateTimer.getElapsedTimeF32() >= texture_timeout;
- const BOOL has_lower_lod = mTexLayerSet->isLocalTextureDataAvailable();
- if (has_lower_lod && is_update_textures_timeout) return TRUE;
- }
-
- return FALSE;
-}
-
-BOOL LLTexLayerSetBuffer::requestUpdateImmediate()
-{
- mNeedsUpdate = TRUE;
- BOOL result = FALSE;
-
- if (needsRender())
- {
- preRender(FALSE);
- result = render();
- postRender(result);
- }
-
- return result;
-}
-
-// Create the baked texture, send it out to the server, then wait for it to come
-// back so we can switch to using it.
-void LLTexLayerSetBuffer::doUpload()
-{
- llinfos << "Uploading baked " << mTexLayerSet->getBodyRegionName() << llendl;
- LLViewerStats::getInstance()->incStat(LLViewerStats::ST_TEX_BAKES);
-
- // Don't need caches since we're baked now. (note: we won't *really* be baked
- // until this image is sent to the server and the Avatar Appearance message is received.)
- mTexLayerSet->deleteCaches();
-
- // Get the COLOR information from our texture
- U8* baked_color_data = new U8[ mFullWidth * mFullHeight * 4 ];
- glReadPixels(mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight, GL_RGBA, GL_UNSIGNED_BYTE, baked_color_data );
- stop_glerror();
-
- // Get the MASK information from our texture
- LLGLSUIDefault gls_ui;
- LLPointer<LLImageRaw> baked_mask_image = new LLImageRaw(mFullWidth, mFullHeight, 1 );
- U8* baked_mask_data = baked_mask_image->getData();
- mTexLayerSet->gatherMorphMaskAlpha(baked_mask_data, mFullWidth, mFullHeight);
-
-
- // Create the baked image from our color and mask information
- const S32 baked_image_components = 5; // red green blue [bump] clothing
- LLPointer<LLImageRaw> baked_image = new LLImageRaw( mFullWidth, mFullHeight, baked_image_components );
- U8* baked_image_data = baked_image->getData();
- S32 i = 0;
- for (S32 u=0; u < mFullWidth; u++)
- {
- for (S32 v=0; v < mFullHeight; v++)
- {
- baked_image_data[5*i + 0] = baked_color_data[4*i + 0];
- baked_image_data[5*i + 1] = baked_color_data[4*i + 1];
- baked_image_data[5*i + 2] = baked_color_data[4*i + 2];
- baked_image_data[5*i + 3] = baked_color_data[4*i + 3]; // alpha should be correct for eyelashes.
- baked_image_data[5*i + 4] = baked_mask_data[i];
- i++;
- }
- }
-
- LLPointer<LLImageJ2C> compressedImage = new LLImageJ2C;
- compressedImage->setRate(0.f);
- const char* comment_text = LINDEN_J2C_COMMENT_PREFIX "RGBHM"; // writes into baked_color_data. 5 channels (rgb, heightfield/alpha, mask)
- if (compressedImage->encode(baked_image, comment_text))
- {
- LLTransactionID tid;
- tid.generate();
- const LLAssetID asset_id = tid.makeAssetID(gAgent.getSecureSessionID());
- if (LLVFile::writeFile(compressedImage->getData(), compressedImage->getDataSize(),
- gVFS, asset_id, LLAssetType::AT_TEXTURE))
- {
- // Read back the file and validate.
- BOOL valid = FALSE;
- LLPointer<LLImageJ2C> integrity_test = new LLImageJ2C;
- S32 file_size = 0;
- U8* data = LLVFile::readFile(gVFS, asset_id, LLAssetType::AT_TEXTURE, &file_size);
- if (data)
- {
- valid = integrity_test->validate(data, file_size); // integrity_test will delete 'data'
- }
- else
- {
- integrity_test->setLastError("Unable to read entire file");
- }
-
- if (valid)
- {
- const bool highest_lod = mTexLayerSet->isLocalTextureDataFinal();
- // Baked_upload_data is owned by the responder and deleted after the request completes.
- LLBakedUploadData* baked_upload_data = new LLBakedUploadData(gAgentAvatarp,
- this->mTexLayerSet,
- asset_id,
- highest_lod);
- // upload ID is used to avoid overlaps, e.g. when the user rapidly makes two changes outside of Face Edit.
- mUploadID = asset_id;
-
- // Upload the image
- const std::string url = gAgent.getRegion()->getCapability("UploadBakedTexture");
- if(!url.empty()
- && !LLPipeline::sForceOldBakedUpload // toggle debug setting UploadBakedTexOld to change between the new caps method and old method
- && (mUploadFailCount < (BAKE_UPLOAD_ATTEMPTS - 1))) // Try last ditch attempt via asset store if cap upload is failing.
- {
- LLSD body = LLSD::emptyMap();
- // The responder will call LLTexLayerSetBuffer::onTextureUploadComplete()
- LLHTTPClient::post(url, body, new LLSendTexLayerResponder(body, mUploadID, LLAssetType::AT_TEXTURE, baked_upload_data));
- llinfos << "Baked texture upload via capability of " << mUploadID << " to " << url << llendl;
- }
- else
- {
- gAssetStorage->storeAssetData(tid,
- LLAssetType::AT_TEXTURE,
- LLTexLayerSetBuffer::onTextureUploadComplete,
- baked_upload_data,
- TRUE, // temp_file
- TRUE, // is_priority
- TRUE); // store_local
- llinfos << "Baked texture upload via Asset Store." << llendl;
- }
-
- if (highest_lod)
- {
- // Sending the final LOD for the baked texture. All done, pause
- // the upload timer so we know how long it took.
- mNeedsUpload = FALSE;
- mNeedsUploadTimer.pause();
- }
- else
- {
- // Sending a lower level LOD for the baked texture. Restart the upload timer.
- mNumLowresUploads++;
- mNeedsUploadTimer.unpause();
- mNeedsUploadTimer.reset();
- }
-
- // Print out notification that we uploaded this texture.
- if (gSavedSettings.getBOOL("DebugAvatarRezTime"))
- {
- const std::string lod_str = highest_lod ? "HighRes" : "LowRes";
- LLSD args;
- args["EXISTENCE"] = llformat("%d",(U32)mTexLayerSet->getAvatar()->debugGetExistenceTimeElapsedF32());
- args["TIME"] = llformat("%d",(U32)mNeedsUploadTimer.getElapsedTimeF32());
- args["BODYREGION"] = mTexLayerSet->getBodyRegionName();
- args["RESOLUTION"] = lod_str;
- LLNotificationsUtil::add("AvatarRezSelfBakedTextureUploadNotification",args);
- llinfos << "Uploading [ name: " << mTexLayerSet->getBodyRegionName() << " res:" << lod_str << " time:" << (U32)mNeedsUploadTimer.getElapsedTimeF32() << " ]" << llendl;
- }
- }
- else
- {
- // The read back and validate operation failed. Remove the uploaded file.
- mUploadPending = FALSE;
- LLVFile file(gVFS, asset_id, LLAssetType::AT_TEXTURE, LLVFile::WRITE);
- file.remove();
- llinfos << "Unable to create baked upload file (reason: corrupted)." << llendl;
- }
- }
- }
- else
- {
- // The VFS write file operation failed.
- mUploadPending = FALSE;
- llinfos << "Unable to create baked upload file (reason: failed to write file)" << llendl;
- }
-
- delete [] baked_color_data;
-}
-
-// Mostly bookkeeping; don't need to actually "do" anything since
-// render() will actually do the update.
-void LLTexLayerSetBuffer::doUpdate()
-{
- const BOOL highest_lod = mTexLayerSet->isLocalTextureDataFinal();
- if (highest_lod)
- {
- mNeedsUpdate = FALSE;
- }
- else
- {
- mNumLowresUpdates++;
- }
-
- restartUpdateTimer();
-
- // need to swtich to using this layerset if this is the first update
- // after getting the lowest LOD
- mTexLayerSet->getAvatar()->updateMeshTextures();
-
- // Print out notification that we uploaded this texture.
- if (gSavedSettings.getBOOL("DebugAvatarRezTime"))
- {
- const BOOL highest_lod = mTexLayerSet->isLocalTextureDataFinal();
- const std::string lod_str = highest_lod ? "HighRes" : "LowRes";
- LLSD args;
- args["EXISTENCE"] = llformat("%d",(U32)mTexLayerSet->getAvatar()->debugGetExistenceTimeElapsedF32());
- args["TIME"] = llformat("%d",(U32)mNeedsUpdateTimer.getElapsedTimeF32());
- args["BODYREGION"] = mTexLayerSet->getBodyRegionName();
- args["RESOLUTION"] = lod_str;
- LLNotificationsUtil::add("AvatarRezSelfBakedTextureUpdateNotification",args);
- llinfos << "Locally updating [ name: " << mTexLayerSet->getBodyRegionName() << " res:" << lod_str << " time:" << (U32)mNeedsUpdateTimer.getElapsedTimeF32() << " ]" << llendl;
- }
-}
-
-// static
-void LLTexLayerSetBuffer::onTextureUploadComplete(const LLUUID& uuid,
- void* userdata,
- S32 result,
- LLExtStat ext_status) // StoreAssetData callback (not fixed)
-{
- LLBakedUploadData* baked_upload_data = (LLBakedUploadData*)userdata;
-
- if (isAgentAvatarValid() &&
- !gAgentAvatarp->isDead() &&
- (baked_upload_data->mAvatar == gAgentAvatarp) && // Sanity check: only the user's avatar should be uploading textures.
- (baked_upload_data->mTexLayerSet->hasComposite()))
- {
- LLTexLayerSetBuffer* layerset_buffer = baked_upload_data->mTexLayerSet->getComposite();
- S32 failures = layerset_buffer->mUploadFailCount;
- layerset_buffer->mUploadFailCount = 0;
-
- if (layerset_buffer->mUploadID.isNull())
- {
- // The upload got canceled, we should be in the
- // process of baking a new texture so request an
- // upload with the new data
-
- // BAP: does this really belong in this callback, as
- // opposed to where the cancellation takes place?
- // suspect this does nothing.
- layerset_buffer->requestUpload();
- }
- else if (baked_upload_data->mID == layerset_buffer->mUploadID)
- {
- // This is the upload we're currently waiting for.
- layerset_buffer->mUploadID.setNull();
- const std::string name(baked_upload_data->mTexLayerSet->getBodyRegionName());
- const std::string resolution = baked_upload_data->mIsHighestRes ? " full res " : " low res ";
- if (result >= 0)
- {
- layerset_buffer->mUploadPending = FALSE; // Allows sending of AgentSetAppearance later
- LLVOAvatarDefines::ETextureIndex baked_te = gAgentAvatarp->getBakedTE(layerset_buffer->mTexLayerSet);
- // Update baked texture info with the new UUID
- U64 now = LLFrameTimer::getTotalTime(); // Record starting time
- llinfos << "Baked" << resolution << "texture upload for " << name << " took " << (S32)((now - baked_upload_data->mStartTime) / 1000) << " ms" << llendl;
- gAgentAvatarp->setNewBakedTexture(baked_te, uuid);
- }
- else
- {
- ++failures;
- S32 max_attempts = baked_upload_data->mIsHighestRes ? BAKE_UPLOAD_ATTEMPTS : 1; // only retry final bakes
- llwarns << "Baked" << resolution << "texture upload for " << name << " failed (attempt " << failures << "/" << max_attempts << ")" << llendl;
- if (failures < max_attempts)
- {
- layerset_buffer->mUploadFailCount = failures;
- layerset_buffer->mUploadRetryTimer.start();
- layerset_buffer->requestUpload();
- }
- }
- }
- else
- {
- llinfos << "Received baked texture out of date, ignored." << llendl;
- }
-
- gAgentAvatarp->dirtyMesh();
- }
- else
- {
- // Baked texture failed to upload (in which case since we
- // didn't set the new baked texture, it means that they'll try
- // and rebake it at some point in the future (after login?)),
- // or this response to upload is out of date, in which case a
- // current response should be on the way or already processed.
- llwarns << "Baked upload failed" << llendl;
- }
-
- delete baked_upload_data;
-}
-
-//-----------------------------------------------------------------------------
-// LLTexLayerSet
-// An ordered set of texture layers that get composited into a single texture.
-//-----------------------------------------------------------------------------
-
-LLTexLayerSetInfo::LLTexLayerSetInfo() :
- mBodyRegion( "" ),
- mWidth( 512 ),
- mHeight( 512 ),
- mClearAlpha( TRUE )
-{
-}
-
-LLTexLayerSetInfo::~LLTexLayerSetInfo( )
-{
- std::for_each(mLayerInfoList.begin(), mLayerInfoList.end(), DeletePointer());
-}
-
-BOOL LLTexLayerSetInfo::parseXml(LLXmlTreeNode* node)
-{
- llassert( node->hasName( "layer_set" ) );
- if( !node->hasName( "layer_set" ) )
- {
- return FALSE;
- }
-
- // body_region
- static LLStdStringHandle body_region_string = LLXmlTree::addAttributeString("body_region");
- if( !node->getFastAttributeString( body_region_string, mBodyRegion ) )
- {
- llwarns << "<layer_set> is missing body_region attribute" << llendl;
- return FALSE;
- }
-
- // width, height
- static LLStdStringHandle width_string = LLXmlTree::addAttributeString("width");
- if( !node->getFastAttributeS32( width_string, mWidth ) )
- {
- return FALSE;
- }
-
- static LLStdStringHandle height_string = LLXmlTree::addAttributeString("height");
- if( !node->getFastAttributeS32( height_string, mHeight ) )
- {
- return FALSE;
- }
-
- // Optional alpha component to apply after all compositing is complete.
- static LLStdStringHandle alpha_tga_file_string = LLXmlTree::addAttributeString("alpha_tga_file");
- node->getFastAttributeString( alpha_tga_file_string, mStaticAlphaFileName );
-
- static LLStdStringHandle clear_alpha_string = LLXmlTree::addAttributeString("clear_alpha");
- node->getFastAttributeBOOL( clear_alpha_string, mClearAlpha );
-
- // <layer>
- for (LLXmlTreeNode* child = node->getChildByName( "layer" );
- child;
- child = node->getNextNamedChild())
- {
- LLTexLayerInfo* info = new LLTexLayerInfo();
- if( !info->parseXml( child ))
- {
- delete info;
- return FALSE;
- }
- mLayerInfoList.push_back( info );
- }
- return TRUE;
-}
-
-// creates visual params without generating layersets or layers
-void LLTexLayerSetInfo::createVisualParams(LLVOAvatar *avatar)
-{
- //layer_info_list_t mLayerInfoList;
- for (layer_info_list_t::iterator layer_iter = mLayerInfoList.begin();
- layer_iter != mLayerInfoList.end();
- layer_iter++)
- {
- LLTexLayerInfo *layer_info = *layer_iter;
- layer_info->createVisualParams(avatar);
- }
-}
-
-//-----------------------------------------------------------------------------
-// LLTexLayerSet
-// An ordered set of texture layers that get composited into a single texture.
-//-----------------------------------------------------------------------------
-
-BOOL LLTexLayerSet::sHasCaches = FALSE;
-
-LLTexLayerSet::LLTexLayerSet(LLVOAvatarSelf* const avatar) :
- mComposite( NULL ),
- mAvatar( avatar ),
- mUpdatesEnabled( FALSE ),
- mIsVisible( TRUE ),
- mBakedTexIndex(LLVOAvatarDefines::BAKED_HEAD),
- mInfo( NULL )
-{
-}
-
-LLTexLayerSet::~LLTexLayerSet()
-{
- deleteCaches();
- std::for_each(mLayerList.begin(), mLayerList.end(), DeletePointer());
- std::for_each(mMaskLayerList.begin(), mMaskLayerList.end(), DeletePointer());
-}
-
-//-----------------------------------------------------------------------------
-// setInfo
-//-----------------------------------------------------------------------------
-
-BOOL LLTexLayerSet::setInfo(const LLTexLayerSetInfo *info)
-{
- llassert(mInfo == NULL);
- mInfo = info;
- //mID = info->mID; // No ID
-
- mLayerList.reserve(info->mLayerInfoList.size());
- for (LLTexLayerSetInfo::layer_info_list_t::const_iterator iter = info->mLayerInfoList.begin();
- iter != info->mLayerInfoList.end();
- iter++)
- {
- LLTexLayerInterface *layer = NULL;
- if ( (*iter)->isUserSettable() )
- {
- layer = new LLTexLayerTemplate( this );
- }
- else
- {
- layer = new LLTexLayer(this);
- }
- // this is the first time this layer (of either type) is being created - make sure you add the parameters to the avatar
- if (!layer->setInfo(*iter, NULL))
- {
- mInfo = NULL;
- return FALSE;
- }
- if (!layer->isVisibilityMask())
- {
- mLayerList.push_back( layer );
- }
- else
- {
- mMaskLayerList.push_back(layer);
- }
- }
-
- requestUpdate();
-
- stop_glerror();
-
- return TRUE;
-}
-
-#if 0 // obsolete
-//-----------------------------------------------------------------------------
-// parseData
-//-----------------------------------------------------------------------------
-
-BOOL LLTexLayerSet::parseData(LLXmlTreeNode* node)
-{
- LLTexLayerSetInfo *info = new LLTexLayerSetInfo;
-
- if (!info->parseXml(node))
- {
- delete info;
- return FALSE;
- }
- if (!setInfo(info))
- {
- delete info;
- return FALSE;
- }
- return TRUE;
-}
-#endif
-
-void LLTexLayerSet::deleteCaches()
-{
- for( layer_list_t::iterator iter = mLayerList.begin(); iter != mLayerList.end(); iter++ )
- {
- LLTexLayerInterface* layer = *iter;
- layer->deleteCaches();
- }
- for (layer_list_t::iterator iter = mMaskLayerList.begin(); iter != mMaskLayerList.end(); iter++)
- {
- LLTexLayerInterface* layer = *iter;
- layer->deleteCaches();
- }
-}
-
-// Returns TRUE if at least one packet of data has been received for each of the textures that this layerset depends on.
-BOOL LLTexLayerSet::isLocalTextureDataAvailable() const
-{
- if (!mAvatar->isSelf()) return FALSE;
- return ((LLVOAvatarSelf *)mAvatar)->isLocalTextureDataAvailable(this);
-}
-
-
-// Returns TRUE if all of the data for the textures that this layerset depends on have arrived.
-BOOL LLTexLayerSet::isLocalTextureDataFinal() const
-{
- if (!mAvatar->isSelf()) return FALSE;
- return ((LLVOAvatarSelf *)mAvatar)->isLocalTextureDataFinal(this);
-}
-
-
-BOOL LLTexLayerSet::render( S32 x, S32 y, S32 width, S32 height )
-{
- BOOL success = TRUE;
- mIsVisible = TRUE;
-
- if (mMaskLayerList.size() > 0)
- {
- for (layer_list_t::iterator iter = mMaskLayerList.begin(); iter != mMaskLayerList.end(); iter++)
- {
- LLTexLayerInterface* layer = *iter;
- if (layer->isInvisibleAlphaMask())
- {
- mIsVisible = FALSE;
- }
- }
- }
-
- bool use_shaders = LLGLSLShader::sNoFixedFunction;
-
- LLGLSUIDefault gls_ui;
- LLGLDepthTest gls_depth(GL_FALSE, GL_FALSE);
- gGL.setColorMask(true, true);
-
- // clear buffer area to ensure we don't pick up UI elements
- {
- gGL.flush();
- LLGLDisable no_alpha(GL_ALPHA_TEST);
- if (use_shaders)
- {
- gAlphaMaskProgram.setMinimumAlpha(0.0f);
- }
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.color4f( 0.f, 0.f, 0.f, 1.f );
-
- gl_rect_2d_simple( width, height );
-
- gGL.flush();
- if (use_shaders)
- {
- gAlphaMaskProgram.setMinimumAlpha(0.004f);
- }
- }
-
- if (mIsVisible)
- {
- // composite color layers
- for( layer_list_t::iterator iter = mLayerList.begin(); iter != mLayerList.end(); iter++ )
- {
- LLTexLayerInterface* layer = *iter;
- if (layer->getRenderPass() == LLTexLayer::RP_COLOR)
- {
- gGL.flush();
- success &= layer->render(x, y, width, height);
- gGL.flush();
- }
- }
-
- renderAlphaMaskTextures(x, y, width, height, false);
-
- stop_glerror();
- }
- else
- {
- gGL.flush();
-
- gGL.setSceneBlendType(LLRender::BT_REPLACE);
- LLGLDisable no_alpha(GL_ALPHA_TEST);
- if (use_shaders)
- {
- gAlphaMaskProgram.setMinimumAlpha(0.f);
- }
-
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.color4f( 0.f, 0.f, 0.f, 0.f );
-
- gl_rect_2d_simple( width, height );
- gGL.setSceneBlendType(LLRender::BT_ALPHA);
-
- gGL.flush();
- if (use_shaders)
- {
- gAlphaMaskProgram.setMinimumAlpha(0.004f);
- }
- }
-
- return success;
-}
-
-
-BOOL LLTexLayerSet::isBodyRegion(const std::string& region) const
-{
- return mInfo->mBodyRegion == region;
-}
-
-const std::string LLTexLayerSet::getBodyRegionName() const
-{
- return mInfo->mBodyRegion;
-}
-
-void LLTexLayerSet::requestUpdate()
-{
- if( mUpdatesEnabled )
- {
- createComposite();
- mComposite->requestUpdate();
- }
-}
-
-void LLTexLayerSet::requestUpload()
-{
- createComposite();
- mComposite->requestUpload();
-}
-
-void LLTexLayerSet::cancelUpload()
-{
- if(mComposite)
- {
- mComposite->cancelUpload();
- }
-}
-
-void LLTexLayerSet::createComposite()
-{
- if(!mComposite)
- {
- S32 width = mInfo->mWidth;
- S32 height = mInfo->mHeight;
- // Composite other avatars at reduced resolution
- if( !mAvatar->isSelf() )
- {
- llerrs << "composites should not be created for non-self avatars!" << llendl;
- }
- mComposite = new LLTexLayerSetBuffer( this, width, height );
- }
-}
-
-void LLTexLayerSet::destroyComposite()
-{
- if( mComposite )
- {
- mComposite = NULL;
- }
-}
-
-void LLTexLayerSet::setUpdatesEnabled( BOOL b )
-{
- mUpdatesEnabled = b;
-}
-
-
-void LLTexLayerSet::updateComposite()
-{
- createComposite();
- mComposite->requestUpdateImmediate();
-}
-
-LLTexLayerSetBuffer* LLTexLayerSet::getComposite()
-{
- if (!mComposite)
- {
- createComposite();
- }
- return mComposite;
-}
-
-const LLTexLayerSetBuffer* LLTexLayerSet::getComposite() const
-{
- return mComposite;
-}
-
-void LLTexLayerSet::gatherMorphMaskAlpha(U8 *data, S32 width, S32 height)
-{
- memset(data, 255, width * height);
-
- for( layer_list_t::iterator iter = mLayerList.begin(); iter != mLayerList.end(); iter++ )
- {
- LLTexLayerInterface* layer = *iter;
- layer->gatherAlphaMasks(data, mComposite->getOriginX(),mComposite->getOriginY(), width, height);
- }
-
- // Set alpha back to that of our alpha masks.
- renderAlphaMaskTextures(mComposite->getOriginX(), mComposite->getOriginY(), width, height, true);
-}
-
-void LLTexLayerSet::renderAlphaMaskTextures(S32 x, S32 y, S32 width, S32 height, bool forceClear)
-{
- const LLTexLayerSetInfo *info = getInfo();
-
- bool use_shaders = LLGLSLShader::sNoFixedFunction;
-
- gGL.setColorMask(false, true);
- gGL.setSceneBlendType(LLRender::BT_REPLACE);
-
- // (Optionally) replace alpha with a single component image from a tga file.
- if (!info->mStaticAlphaFileName.empty())
- {
- gGL.flush();
- {
- LLViewerTexture* tex = LLTexLayerStaticImageList::getInstance()->getTexture(info->mStaticAlphaFileName, TRUE);
- if( tex )
- {
- LLGLSUIDefault gls_ui;
- gGL.getTexUnit(0)->bind(tex);
- gGL.getTexUnit(0)->setTextureBlendType( LLTexUnit::TB_REPLACE );
- gl_rect_2d_simple_tex( width, height );
- }
- }
- gGL.flush();
- }
- else if (forceClear || info->mClearAlpha || (mMaskLayerList.size() > 0))
- {
- // Set the alpha channel to one (clean up after previous blending)
- gGL.flush();
- LLGLDisable no_alpha(GL_ALPHA_TEST);
- if (use_shaders)
- {
- gAlphaMaskProgram.setMinimumAlpha(0.f);
- }
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.color4f( 0.f, 0.f, 0.f, 1.f );
-
- gl_rect_2d_simple( width, height );
-
- gGL.flush();
- if (use_shaders)
- {
- gAlphaMaskProgram.setMinimumAlpha(0.004f);
- }
- }
-
- // (Optional) Mask out part of the baked texture with alpha masks
- // will still have an effect even if mClearAlpha is set or the alpha component was replaced
- if (mMaskLayerList.size() > 0)
- {
- gGL.setSceneBlendType(LLRender::BT_MULT_ALPHA);
- gGL.getTexUnit(0)->setTextureBlendType( LLTexUnit::TB_REPLACE );
- for (layer_list_t::iterator iter = mMaskLayerList.begin(); iter != mMaskLayerList.end(); iter++)
- {
- LLTexLayerInterface* layer = *iter;
- gGL.flush();
- layer->blendAlphaTexture(x,y,width, height);
- gGL.flush();
- }
-
- }
-
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
- gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
- gGL.setColorMask(true, true);
- gGL.setSceneBlendType(LLRender::BT_ALPHA);
-}
-
-void LLTexLayerSet::applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_components)
-{
- mAvatar->applyMorphMask(tex_data, width, height, num_components, mBakedTexIndex);
-}
-
-BOOL LLTexLayerSet::isMorphValid() const
-{
- for(layer_list_t::const_iterator iter = mLayerList.begin(); iter != mLayerList.end(); iter++ )
- {
- const LLTexLayerInterface* layer = *iter;
- if (layer && !layer->isMorphValid())
- {
- return FALSE;
- }
- }
- return TRUE;
-}
-
-void LLTexLayerSet::invalidateMorphMasks()
-{
- for( layer_list_t::iterator iter = mLayerList.begin(); iter != mLayerList.end(); iter++ )
- {
- LLTexLayerInterface* layer = *iter;
- if (layer)
- {
- layer->invalidateMorphMasks();
- }
- }
-}
-
-
-//-----------------------------------------------------------------------------
-// LLTexLayerInfo
-//-----------------------------------------------------------------------------
-LLTexLayerInfo::LLTexLayerInfo() :
- mWriteAllChannels( FALSE ),
- mRenderPass(LLTexLayer::RP_COLOR),
- mFixedColor( 0.f, 0.f, 0.f, 0.f ),
- mLocalTexture( -1 ),
- mStaticImageIsMask( FALSE ),
- mUseLocalTextureAlphaOnly(FALSE),
- mIsVisibilityMask(FALSE)
-{
-}
-
-LLTexLayerInfo::~LLTexLayerInfo( )
-{
- std::for_each(mParamColorInfoList.begin(), mParamColorInfoList.end(), DeletePointer());
- std::for_each(mParamAlphaInfoList.begin(), mParamAlphaInfoList.end(), DeletePointer());
-}
-
-BOOL LLTexLayerInfo::parseXml(LLXmlTreeNode* node)
-{
- llassert( node->hasName( "layer" ) );
-
- // name attribute
- static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name");
- if( !node->getFastAttributeString( name_string, mName ) )
- {
- return FALSE;
- }
-
- static LLStdStringHandle write_all_channels_string = LLXmlTree::addAttributeString("write_all_channels");
- node->getFastAttributeBOOL( write_all_channels_string, mWriteAllChannels );
-
- std::string render_pass_name;
- static LLStdStringHandle render_pass_string = LLXmlTree::addAttributeString("render_pass");
- if( node->getFastAttributeString( render_pass_string, render_pass_name ) )
- {
- if( render_pass_name == "bump" )
- {
- mRenderPass = LLTexLayer::RP_BUMP;
- }
- }
-
- // Note: layers can have either a "global_color" attrib, a "fixed_color" attrib, or a <param_color> child.
- // global color attribute (optional)
- static LLStdStringHandle global_color_string = LLXmlTree::addAttributeString("global_color");
- node->getFastAttributeString( global_color_string, mGlobalColor );
-
- // Visibility mask (optional)
- BOOL is_visibility;
- static LLStdStringHandle visibility_mask_string = LLXmlTree::addAttributeString("visibility_mask");
- if (node->getFastAttributeBOOL(visibility_mask_string, is_visibility))
- {
- mIsVisibilityMask = is_visibility;
- }
-
- // color attribute (optional)
- LLColor4U color4u;
- static LLStdStringHandle fixed_color_string = LLXmlTree::addAttributeString("fixed_color");
- if( node->getFastAttributeColor4U( fixed_color_string, color4u ) )
- {
- mFixedColor.setVec( color4u );
- }
-
- // <texture> optional sub-element
- for (LLXmlTreeNode* texture_node = node->getChildByName( "texture" );
- texture_node;
- texture_node = node->getNextNamedChild())
- {
- std::string local_texture_name;
- static LLStdStringHandle tga_file_string = LLXmlTree::addAttributeString("tga_file");
- static LLStdStringHandle local_texture_string = LLXmlTree::addAttributeString("local_texture");
- static LLStdStringHandle file_is_mask_string = LLXmlTree::addAttributeString("file_is_mask");
- static LLStdStringHandle local_texture_alpha_only_string = LLXmlTree::addAttributeString("local_texture_alpha_only");
- if( texture_node->getFastAttributeString( tga_file_string, mStaticImageFileName ) )
- {
- texture_node->getFastAttributeBOOL( file_is_mask_string, mStaticImageIsMask );
- }
- else if (texture_node->getFastAttributeString(local_texture_string, local_texture_name))
- {
- texture_node->getFastAttributeBOOL( local_texture_alpha_only_string, mUseLocalTextureAlphaOnly );
-
- /* if ("upper_shirt" == local_texture_name)
- mLocalTexture = TEX_UPPER_SHIRT; */
- mLocalTexture = TEX_NUM_INDICES;
- for (LLVOAvatarDictionary::Textures::const_iterator iter = LLVOAvatarDictionary::getInstance()->getTextures().begin();
- iter != LLVOAvatarDictionary::getInstance()->getTextures().end();
- iter++)
- {
- const LLVOAvatarDictionary::TextureEntry *texture_dict = iter->second;
- if (local_texture_name == texture_dict->mName)
- {
- mLocalTexture = iter->first;
- break;
- }
- }
- if (mLocalTexture == TEX_NUM_INDICES)
- {
- llwarns << "<texture> element has invalid local_texture attribute: " << mName << " " << local_texture_name << llendl;
- return FALSE;
- }
- }
- else
- {
- llwarns << "<texture> element is missing a required attribute. " << mName << llendl;
- return FALSE;
- }
- }
-
- for (LLXmlTreeNode* maskNode = node->getChildByName( "morph_mask" );
- maskNode;
- maskNode = node->getNextNamedChild())
- {
- std::string morph_name;
- static LLStdStringHandle morph_name_string = LLXmlTree::addAttributeString("morph_name");
- if (maskNode->getFastAttributeString(morph_name_string, morph_name))
- {
- BOOL invert = FALSE;
- static LLStdStringHandle invert_string = LLXmlTree::addAttributeString("invert");
- maskNode->getFastAttributeBOOL(invert_string, invert);
- mMorphNameList.push_back(std::pair<std::string,BOOL>(morph_name,invert));
- }
- }
-
- // <param> optional sub-element (color or alpha params)
- for (LLXmlTreeNode* child = node->getChildByName( "param" );
- child;
- child = node->getNextNamedChild())
- {
- if( child->getChildByName( "param_color" ) )
- {
- // <param><param_color/></param>
- LLTexLayerParamColorInfo* info = new LLTexLayerParamColorInfo();
- if (!info->parseXml(child))
- {
- delete info;
- return FALSE;
- }
- mParamColorInfoList.push_back(info);
- }
- else if( child->getChildByName( "param_alpha" ) )
- {
- // <param><param_alpha/></param>
- LLTexLayerParamAlphaInfo* info = new LLTexLayerParamAlphaInfo( );
- if (!info->parseXml(child))
- {
- delete info;
- return FALSE;
- }
- mParamAlphaInfoList.push_back(info);
- }
- }
-
- return TRUE;
-}
-
-BOOL LLTexLayerInfo::createVisualParams(LLVOAvatar *avatar)
-{
- BOOL success = TRUE;
- for (param_color_info_list_t::iterator color_info_iter = mParamColorInfoList.begin();
- color_info_iter != mParamColorInfoList.end();
- color_info_iter++)
- {
- LLTexLayerParamColorInfo * color_info = *color_info_iter;
- LLTexLayerParamColor* param_color = new LLTexLayerParamColor(avatar);
- if (!param_color->setInfo(color_info, TRUE))
- {
- llwarns << "NULL TexLayer Color Param could not be added to visual param list. Deleting." << llendl;
- delete param_color;
- success = FALSE;
- }
- }
-
- for (param_alpha_info_list_t::iterator alpha_info_iter = mParamAlphaInfoList.begin();
- alpha_info_iter != mParamAlphaInfoList.end();
- alpha_info_iter++)
- {
- LLTexLayerParamAlphaInfo * alpha_info = *alpha_info_iter;
- LLTexLayerParamAlpha* param_alpha = new LLTexLayerParamAlpha(avatar);
- if (!param_alpha->setInfo(alpha_info, TRUE))
- {
- llwarns << "NULL TexLayer Alpha Param could not be added to visual param list. Deleting." << llendl;
- delete param_alpha;
- success = FALSE;
- }
- }
-
- return success;
-}
-
-LLTexLayerInterface::LLTexLayerInterface(LLTexLayerSet* const layer_set):
- mTexLayerSet( layer_set ),
- mMorphMasksValid( FALSE ),
- mInfo(NULL),
- mHasMorph(FALSE)
-{
-}
-
-LLTexLayerInterface::LLTexLayerInterface(const LLTexLayerInterface &layer, LLWearable *wearable):
- mTexLayerSet( layer.mTexLayerSet ),
- mInfo(NULL)
-{
- // don't add visual params for cloned layers
- setInfo(layer.getInfo(), wearable);
-
- mHasMorph = layer.mHasMorph;
-}
-
-BOOL LLTexLayerInterface::setInfo(const LLTexLayerInfo *info, LLWearable* wearable ) // This sets mInfo and calls initialization functions
-{
- // setInfo should only be called once. Code is not robust enough to handle redefinition of a texlayer.
- // Not a critical warning, but could be useful for debugging later issues. -Nyx
- if (mInfo != NULL)
- {
- llwarns << "mInfo != NULL" << llendl;
- }
- mInfo = info;
- //mID = info->mID; // No ID
-
- mParamColorList.reserve(mInfo->mParamColorInfoList.size());
- for (param_color_info_list_t::const_iterator iter = mInfo->mParamColorInfoList.begin();
- iter != mInfo->mParamColorInfoList.end();
- iter++)
- {
- LLTexLayerParamColor* param_color;
- if (!wearable)
- {
- param_color = new LLTexLayerParamColor(this);
- if (!param_color->setInfo(*iter, TRUE))
- {
- mInfo = NULL;
- return FALSE;
- }
- }
- else
- {
- param_color = (LLTexLayerParamColor*)wearable->getVisualParam((*iter)->getID());
- if (!param_color)
- {
- mInfo = NULL;
- return FALSE;
- }
- }
- mParamColorList.push_back( param_color );
- }
-
- mParamAlphaList.reserve(mInfo->mParamAlphaInfoList.size());
- for (param_alpha_info_list_t::const_iterator iter = mInfo->mParamAlphaInfoList.begin();
- iter != mInfo->mParamAlphaInfoList.end();
- iter++)
- {
- LLTexLayerParamAlpha* param_alpha;
- if (!wearable)
- {
- param_alpha = new LLTexLayerParamAlpha( this );
- if (!param_alpha->setInfo(*iter, TRUE))
- {
- mInfo = NULL;
- return FALSE;
- }
- }
- else
- {
- param_alpha = (LLTexLayerParamAlpha*) wearable->getVisualParam((*iter)->getID());
- if (!param_alpha)
- {
- mInfo = NULL;
- return FALSE;
- }
- }
- mParamAlphaList.push_back( param_alpha );
- }
-
- return TRUE;
-}
-
-/*virtual*/ void LLTexLayerInterface::requestUpdate()
-{
- mTexLayerSet->requestUpdate();
-}
-
-const std::string& LLTexLayerInterface::getName() const
-{
- return mInfo->mName;
-}
-
-LLTexLayerInterface::ERenderPass LLTexLayerInterface::getRenderPass() const
-{
- return mInfo->mRenderPass;
-}
-
-const std::string& LLTexLayerInterface::getGlobalColor() const
-{
- return mInfo->mGlobalColor;
-}
-
-BOOL LLTexLayerInterface::isVisibilityMask() const
-{
- return mInfo->mIsVisibilityMask;
-}
-
-void LLTexLayerInterface::invalidateMorphMasks()
-{
- mMorphMasksValid = FALSE;
-}
-
-LLViewerVisualParam* LLTexLayerInterface::getVisualParamPtr(S32 index) const
-{
- LLViewerVisualParam *result = NULL;
- for (param_color_list_t::const_iterator color_iter = mParamColorList.begin(); color_iter != mParamColorList.end() && !result; ++color_iter)
- {
- if ((*color_iter)->getID() == index)
- {
- result = *color_iter;
- }
- }
- for (param_alpha_list_t::const_iterator alpha_iter = mParamAlphaList.begin(); alpha_iter != mParamAlphaList.end() && !result; ++alpha_iter)
- {
- if ((*alpha_iter)->getID() == index)
- {
- result = *alpha_iter;
- }
- }
-
- return result;
-}
-
-//-----------------------------------------------------------------------------
-// LLTexLayer
-// A single texture layer, consisting of:
-// * color, consisting of either
-// * one or more color parameters (weighted colors)
-// * a reference to a global color
-// * a fixed color with non-zero alpha
-// * opaque white (the default)
-// * (optional) a texture defined by either
-// * a GUID
-// * a texture entry index (TE)
-// * (optional) one or more alpha parameters (weighted alpha textures)
-//-----------------------------------------------------------------------------
-LLTexLayer::LLTexLayer(LLTexLayerSet* const layer_set) :
- LLTexLayerInterface( layer_set ),
- mLocalTextureObject(NULL)
-{
-}
-
-LLTexLayer::LLTexLayer(const LLTexLayer &layer, LLWearable *wearable) :
- LLTexLayerInterface( layer, wearable ),
- mLocalTextureObject(NULL)
-{
-}
-
-LLTexLayer::LLTexLayer(const LLTexLayerTemplate &layer_template, LLLocalTextureObject *lto, LLWearable *wearable) :
- LLTexLayerInterface( layer_template, wearable ),
- mLocalTextureObject(lto)
-{
-}
-
-LLTexLayer::~LLTexLayer()
-{
- // mParamAlphaList and mParamColorList are LLViewerVisualParam's and get
- // deleted with ~LLCharacter()
- //std::for_each(mParamAlphaList.begin(), mParamAlphaList.end(), DeletePointer());
- //std::for_each(mParamColorList.begin(), mParamColorList.end(), DeletePointer());
-
- for( alpha_cache_t::iterator iter = mAlphaCache.begin();
- iter != mAlphaCache.end(); iter++ )
- {
- U8* alpha_data = iter->second;
- delete [] alpha_data;
- }
-
-}
-
-//-----------------------------------------------------------------------------
-// setInfo
-//-----------------------------------------------------------------------------
-
-BOOL LLTexLayer::setInfo(const LLTexLayerInfo* info, LLWearable* wearable )
-{
- return LLTexLayerInterface::setInfo(info, wearable);
-}
-
-//static
-void LLTexLayer::calculateTexLayerColor(const param_color_list_t &param_list, LLColor4 &net_color)
-{
- for (param_color_list_t::const_iterator iter = param_list.begin();
- iter != param_list.end(); iter++)
- {
- const LLTexLayerParamColor* param = *iter;
- LLColor4 param_net = param->getNetColor();
- const LLTexLayerParamColorInfo *info = (LLTexLayerParamColorInfo *)param->getInfo();
- switch(info->getOperation())
- {
- case LLTexLayerParamColor::OP_ADD:
- net_color += param_net;
- break;
- case LLTexLayerParamColor::OP_MULTIPLY:
- net_color = net_color * param_net;
- break;
- case LLTexLayerParamColor::OP_BLEND:
- net_color = lerp(net_color, param_net, param->getWeight());
- break;
- default:
- llassert(0);
- break;
- }
- }
- net_color.clamp();
-}
-
-/*virtual*/ void LLTexLayer::deleteCaches()
-{
- // Only need to delete caches for alpha params. Color params don't hold extra memory
- for (param_alpha_list_t::iterator iter = mParamAlphaList.begin();
- iter != mParamAlphaList.end(); iter++ )
- {
- LLTexLayerParamAlpha* param = *iter;
- param->deleteCaches();
- }
-}
-
-BOOL LLTexLayer::render(S32 x, S32 y, S32 width, S32 height)
-{
- LLGLEnable color_mat(GL_COLOR_MATERIAL);
- gPipeline.disableLights();
-
- bool use_shaders = LLGLSLShader::sNoFixedFunction;
-
- LLColor4 net_color;
- BOOL color_specified = findNetColor(&net_color);
-
- if (mTexLayerSet->getAvatar()->mIsDummy)
- {
- color_specified = true;
- net_color = LLVOAvatar::getDummyColor();
- }
-
- BOOL success = TRUE;
-
- // If you can't see the layer, don't render it.
- if( is_approx_zero( net_color.mV[VW] ) )
- {
- return success;
- }
-
- BOOL alpha_mask_specified = FALSE;
- param_alpha_list_t::const_iterator iter = mParamAlphaList.begin();
- if( iter != mParamAlphaList.end() )
- {
- // If we have alpha masks, but we're skipping all of them, skip the whole layer.
- // However, we can't do this optimization if we have morph masks that need updating.
-/* if (!mHasMorph)
- {
- BOOL skip_layer = TRUE;
-
- while( iter != mParamAlphaList.end() )
- {
- const LLTexLayerParamAlpha* param = *iter;
-
- if( !param->getSkip() )
- {
- skip_layer = FALSE;
- break;
- }
-
- iter++;
- }
-
- if( skip_layer )
- {
- return success;
- }
- }//*/
-
- renderMorphMasks(x, y, width, height, net_color);
- alpha_mask_specified = TRUE;
- gGL.flush();
- gGL.blendFunc(LLRender::BF_DEST_ALPHA, LLRender::BF_ONE_MINUS_DEST_ALPHA);
- }
-
- gGL.color4fv( net_color.mV);
-
- if( getInfo()->mWriteAllChannels )
- {
- gGL.flush();
- gGL.setSceneBlendType(LLRender::BT_REPLACE);
- }
-
- if( (getInfo()->mLocalTexture != -1) && !getInfo()->mUseLocalTextureAlphaOnly )
- {
- {
- LLViewerTexture* tex = NULL;
- if (mLocalTextureObject && mLocalTextureObject->getImage())
- {
- tex = mLocalTextureObject->getImage();
- if (mLocalTextureObject->getID() == IMG_DEFAULT_AVATAR)
- {
- tex = NULL;
- }
- }
- else
- {
- llinfos << "lto not defined or image not defined: " << getInfo()->getLocalTexture() << " lto: " << mLocalTextureObject << llendl;
- }
-// if( mTexLayerSet->getAvatar()->getLocalTextureGL((ETextureIndex)getInfo()->mLocalTexture, &image_gl ) )
- {
- if( tex )
- {
- bool no_alpha_test = getInfo()->mWriteAllChannels;
- LLGLDisable alpha_test(no_alpha_test ? GL_ALPHA_TEST : 0);
- if (use_shaders && no_alpha_test)
- {
- gAlphaMaskProgram.setMinimumAlpha(0.f);
- }
-
- LLTexUnit::eTextureAddressMode old_mode = tex->getAddressMode();
-
- gGL.getTexUnit(0)->bind(tex, TRUE);
- gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
-
- gl_rect_2d_simple_tex( width, height );
-
- gGL.getTexUnit(0)->setTextureAddressMode(old_mode);
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- if (use_shaders && no_alpha_test)
- {
- gAlphaMaskProgram.setMinimumAlpha(0.004f);
- }
-
- }
- }
-// else
-// {
-// success = FALSE;
-// }
- }
- }
-
- if( !getInfo()->mStaticImageFileName.empty() )
- {
- {
- LLViewerTexture* tex = LLTexLayerStaticImageList::getInstance()->getTexture(getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask);
- if( tex )
- {
- gGL.getTexUnit(0)->bind(tex, TRUE);
- gl_rect_2d_simple_tex( width, height );
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- }
- else
- {
- success = FALSE;
- }
- }
- }
-
- if(((-1 == getInfo()->mLocalTexture) ||
- getInfo()->mUseLocalTextureAlphaOnly) &&
- getInfo()->mStaticImageFileName.empty() &&
- color_specified )
- {
- LLGLDisable no_alpha(GL_ALPHA_TEST);
- if (use_shaders)
- {
- gAlphaMaskProgram.setMinimumAlpha(0.f);
- }
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.color4fv( net_color.mV );
- gl_rect_2d_simple( width, height );
- if (use_shaders)
- {
- gAlphaMaskProgram.setMinimumAlpha(0.004f);
- }
- }
-
- if( alpha_mask_specified || getInfo()->mWriteAllChannels )
- {
- // Restore standard blend func value
- gGL.flush();
- gGL.setSceneBlendType(LLRender::BT_ALPHA);
- stop_glerror();
- }
-
- if( !success )
- {
- llinfos << "LLTexLayer::render() partial: " << getInfo()->mName << llendl;
- }
- return success;
-}
-
-const U8* LLTexLayer::getAlphaData() const
-{
- LLCRC alpha_mask_crc;
- const LLUUID& uuid = getUUID();
- alpha_mask_crc.update((U8*)(&uuid.mData), UUID_BYTES);
-
- for (param_alpha_list_t::const_iterator iter = mParamAlphaList.begin(); iter != mParamAlphaList.end(); iter++)
- {
- const LLTexLayerParamAlpha* param = *iter;
- // MULTI-WEARABLE: verify visual parameters used here
- F32 param_weight = param->getWeight();
- alpha_mask_crc.update((U8*)&param_weight, sizeof(F32));
- }
-
- U32 cache_index = alpha_mask_crc.getCRC();
-
- alpha_cache_t::const_iterator iter2 = mAlphaCache.find(cache_index);
- return (iter2 == mAlphaCache.end()) ? 0 : iter2->second;
-}
-
-BOOL LLTexLayer::findNetColor(LLColor4* net_color) const
-{
- // Color is either:
- // * one or more color parameters (weighted colors) (which may make use of a global color or fixed color)
- // * a reference to a global color
- // * a fixed color with non-zero alpha
- // * opaque white (the default)
-
- if( !mParamColorList.empty() )
- {
- if( !getGlobalColor().empty() )
- {
- net_color->setVec( mTexLayerSet->getAvatar()->getGlobalColor( getInfo()->mGlobalColor ) );
- }
- else if (getInfo()->mFixedColor.mV[VW])
- {
- net_color->setVec( getInfo()->mFixedColor );
- }
- else
- {
- net_color->setVec( 0.f, 0.f, 0.f, 0.f );
- }
-
- calculateTexLayerColor(mParamColorList, *net_color);
- return TRUE;
- }
-
- if( !getGlobalColor().empty() )
- {
- net_color->setVec( mTexLayerSet->getAvatar()->getGlobalColor( getGlobalColor() ) );
- return TRUE;
- }
-
- if( getInfo()->mFixedColor.mV[VW] )
- {
- net_color->setVec( getInfo()->mFixedColor );
- return TRUE;
- }
-
- net_color->setToWhite();
-
- return FALSE; // No need to draw a separate colored polygon
-}
-
-BOOL LLTexLayer::blendAlphaTexture(S32 x, S32 y, S32 width, S32 height)
-{
- BOOL success = TRUE;
-
- gGL.flush();
-
- bool use_shaders = LLGLSLShader::sNoFixedFunction;
-
- if( !getInfo()->mStaticImageFileName.empty() )
- {
- LLViewerTexture* tex = LLTexLayerStaticImageList::getInstance()->getTexture( getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask );
- if( tex )
- {
- LLGLSNoAlphaTest gls_no_alpha_test;
- if (use_shaders)
- {
- gAlphaMaskProgram.setMinimumAlpha(0.f);
- }
- gGL.getTexUnit(0)->bind(tex, TRUE);
- gl_rect_2d_simple_tex( width, height );
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- if (use_shaders)
- {
- gAlphaMaskProgram.setMinimumAlpha(0.004f);
- }
- }
- else
- {
- success = FALSE;
- }
- }
- else
- {
- if (getInfo()->mLocalTexture >=0 && getInfo()->mLocalTexture < TEX_NUM_INDICES)
- {
- LLViewerTexture* tex = mLocalTextureObject->getImage();
- if (tex)
- {
- LLGLSNoAlphaTest gls_no_alpha_test;
- if (use_shaders)
- {
- gAlphaMaskProgram.setMinimumAlpha(0.f);
- }
- gGL.getTexUnit(0)->bind(tex);
- gl_rect_2d_simple_tex( width, height );
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- success = TRUE;
- if (use_shaders)
- {
- gAlphaMaskProgram.setMinimumAlpha(0.004f);
- }
- }
- }
- }
-
- return success;
-}
-
-/*virtual*/ void LLTexLayer::gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height)
-{
- addAlphaMask(data, originX, originY, width, height);
-}
-
-BOOL LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLColor4 &layer_color)
-{
- BOOL success = TRUE;
-
- llassert( !mParamAlphaList.empty() );
-
- bool use_shaders = LLGLSLShader::sNoFixedFunction;
-
- if (use_shaders)
- {
- gAlphaMaskProgram.setMinimumAlpha(0.f);
- }
-
- gGL.setColorMask(false, true);
-
- LLTexLayerParamAlpha* first_param = *mParamAlphaList.begin();
- // Note: if the first param is a mulitply, multiply against the current buffer's alpha
- if( !first_param || !first_param->getMultiplyBlend() )
- {
- LLGLDisable no_alpha(GL_ALPHA_TEST);
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
- // Clear the alpha
- gGL.flush();
- gGL.setSceneBlendType(LLRender::BT_REPLACE);
-
- gGL.color4f( 0.f, 0.f, 0.f, 0.f );
- gl_rect_2d_simple( width, height );
- }
-
- // Accumulate alphas
- LLGLSNoAlphaTest gls_no_alpha_test;
- gGL.color4f( 1.f, 1.f, 1.f, 1.f );
- for (param_alpha_list_t::iterator iter = mParamAlphaList.begin(); iter != mParamAlphaList.end(); iter++)
- {
- LLTexLayerParamAlpha* param = *iter;
- success &= param->render( x, y, width, height );
- }
-
- // Approximates a min() function
- gGL.flush();
- gGL.setSceneBlendType(LLRender::BT_MULT_ALPHA);
-
- // Accumulate the alpha component of the texture
- if( getInfo()->mLocalTexture != -1 )
- {
- LLViewerTexture* tex = mLocalTextureObject->getImage();
- if( tex && (tex->getComponents() == 4) )
- {
- LLGLSNoAlphaTest gls_no_alpha_test;
- LLTexUnit::eTextureAddressMode old_mode = tex->getAddressMode();
-
- gGL.getTexUnit(0)->bind(tex, TRUE);
- gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
-
- gl_rect_2d_simple_tex( width, height );
-
- gGL.getTexUnit(0)->setTextureAddressMode(old_mode);
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- }
- }
-
- if( !getInfo()->mStaticImageFileName.empty() )
- {
- LLViewerTexture* tex = LLTexLayerStaticImageList::getInstance()->getTexture(getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask);
- if( tex )
- {
- if( (tex->getComponents() == 4) ||
- ( (tex->getComponents() == 1) && getInfo()->mStaticImageIsMask ) )
- {
- LLGLSNoAlphaTest gls_no_alpha_test;
- gGL.getTexUnit(0)->bind(tex, TRUE);
- gl_rect_2d_simple_tex( width, height );
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- }
- }
- }
-
- // Draw a rectangle with the layer color to multiply the alpha by that color's alpha.
- // Note: we're still using gGL.blendFunc( GL_DST_ALPHA, GL_ZERO );
- if (layer_color.mV[VW] != 1.f)
- {
- LLGLDisable no_alpha(GL_ALPHA_TEST);
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.color4fv(layer_color.mV);
- gl_rect_2d_simple( width, height );
- }
-
- if (use_shaders)
- {
- gAlphaMaskProgram.setMinimumAlpha(0.004f);
- }
-
- LLGLSUIDefault gls_ui;
-
- gGL.setColorMask(true, true);
-
- if (hasMorph() && success)
- {
- LLCRC alpha_mask_crc;
- const LLUUID& uuid = getUUID();
- alpha_mask_crc.update((U8*)(&uuid.mData), UUID_BYTES);
-
- for (param_alpha_list_t::const_iterator iter = mParamAlphaList.begin(); iter != mParamAlphaList.end(); iter++)
- {
- const LLTexLayerParamAlpha* param = *iter;
- F32 param_weight = param->getWeight();
- alpha_mask_crc.update((U8*)&param_weight, sizeof(F32));
- }
-
- U32 cache_index = alpha_mask_crc.getCRC();
- U8* alpha_data = get_if_there(mAlphaCache,cache_index,(U8*)NULL);
- if (!alpha_data)
- {
- // clear out a slot if we have filled our cache
- S32 max_cache_entries = getTexLayerSet()->getAvatar()->isSelf() ? 4 : 1;
- while ((S32)mAlphaCache.size() >= max_cache_entries)
- {
- alpha_cache_t::iterator iter2 = mAlphaCache.begin(); // arbitrarily grab the first entry
- alpha_data = iter2->second;
- delete [] alpha_data;
- mAlphaCache.erase(iter2);
- }
- alpha_data = new U8[width * height];
- mAlphaCache[cache_index] = alpha_data;
- glReadPixels(x, y, width, height, GL_ALPHA, GL_UNSIGNED_BYTE, alpha_data);
- }
-
- getTexLayerSet()->getAvatar()->dirtyMesh();
-
- mMorphMasksValid = TRUE;
- getTexLayerSet()->applyMorphMask(alpha_data, width, height, 1);
- }
-
- return success;
-}
-
-void LLTexLayer::addAlphaMask(U8 *data, S32 originX, S32 originY, S32 width, S32 height)
-{
- S32 size = width * height;
- const U8* alphaData = getAlphaData();
- if (!alphaData && hasAlphaParams())
- {
- LLColor4 net_color;
- findNetColor( &net_color );
- // TODO: eliminate need for layer morph mask valid flag
- invalidateMorphMasks();
- renderMorphMasks(originX, originY, width, height, net_color);
- alphaData = getAlphaData();
- }
- if (alphaData)
- {
- for( S32 i = 0; i < size; i++ )
- {
- U8 curAlpha = data[i];
- U16 resultAlpha = curAlpha;
- resultAlpha *= (alphaData[i] + 1);
- resultAlpha = resultAlpha >> 8;
- data[i] = (U8)resultAlpha;
- }
- }
-}
-
-/*virtual*/ BOOL LLTexLayer::isInvisibleAlphaMask() const
-{
- if (mLocalTextureObject)
- {
- if (mLocalTextureObject->getID() == IMG_INVISIBLE)
- {
- return TRUE;
- }
- }
-
- return FALSE;
-}
-
-LLUUID LLTexLayer::getUUID() const
-{
- LLUUID uuid;
- if( getInfo()->mLocalTexture != -1 )
- {
- LLViewerTexture* tex = mLocalTextureObject->getImage();
- if (tex)
- {
- uuid = mLocalTextureObject->getID();
- }
- }
- if( !getInfo()->mStaticImageFileName.empty() )
- {
- LLViewerTexture* tex = LLTexLayerStaticImageList::getInstance()->getTexture(getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask);
- if( tex )
- {
- uuid = tex->getID();
- }
- }
- return uuid;
-}
-
-
-//-----------------------------------------------------------------------------
-// LLTexLayerTemplate
-// A single texture layer, consisting of:
-// * color, consisting of either
-// * one or more color parameters (weighted colors)
-// * a reference to a global color
-// * a fixed color with non-zero alpha
-// * opaque white (the default)
-// * (optional) a texture defined by either
-// * a GUID
-// * a texture entry index (TE)
-// * (optional) one or more alpha parameters (weighted alpha textures)
-//-----------------------------------------------------------------------------
-LLTexLayerTemplate::LLTexLayerTemplate(LLTexLayerSet* layer_set) :
- LLTexLayerInterface(layer_set)
-{
-}
-
-LLTexLayerTemplate::LLTexLayerTemplate(const LLTexLayerTemplate &layer) :
- LLTexLayerInterface(layer)
-{
-}
-
-LLTexLayerTemplate::~LLTexLayerTemplate()
-{
-}
-
-//-----------------------------------------------------------------------------
-// setInfo
-//-----------------------------------------------------------------------------
-
-/*virtual*/ BOOL LLTexLayerTemplate::setInfo(const LLTexLayerInfo* info, LLWearable* wearable )
-{
- return LLTexLayerInterface::setInfo(info, wearable);
-}
-
-U32 LLTexLayerTemplate::updateWearableCache() const
-{
- mWearableCache.clear();
-
- S32 te = mInfo->mLocalTexture;
- if (te == -1)
- {
- //this isn't a cloneable layer
- return 0;
- }
- LLWearableType::EType wearable_type = LLVOAvatarDictionary::getTEWearableType((ETextureIndex)te);
- U32 num_wearables = gAgentWearables.getWearableCount(wearable_type);
- U32 added = 0;
- for (U32 i = 0; i < num_wearables; i++)
- {
- LLWearable* wearable = gAgentWearables.getWearable(wearable_type, i);
- if (!wearable)
- {
- continue;
- }
- mWearableCache.push_back(wearable);
- added++;
- }
- return added;
-}
-LLTexLayer* LLTexLayerTemplate::getLayer(U32 i) const
-{
- if (mWearableCache.size() <= i)
- {
- return NULL;
- }
- LLWearable *wearable = mWearableCache[i];
- LLLocalTextureObject *lto = NULL;
- LLTexLayer *layer = NULL;
- if (wearable)
- {
- lto = wearable->getLocalTextureObject(mInfo->mLocalTexture);
- }
- if (lto)
- {
- layer = lto->getTexLayer(getName());
- }
- return layer;
-}
-
-/*virtual*/ BOOL LLTexLayerTemplate::render(S32 x, S32 y, S32 width, S32 height)
-{
- if(!mInfo)
- {
- return FALSE ;
- }
-
- BOOL success = TRUE;
- updateWearableCache();
- for (wearable_cache_t::const_iterator iter = mWearableCache.begin(); iter!= mWearableCache.end(); iter++)
- {
- LLWearable* wearable = NULL;
- LLLocalTextureObject *lto = NULL;
- LLTexLayer *layer = NULL;
- wearable = *iter;
- if (wearable)
- {
- lto = wearable->getLocalTextureObject(mInfo->mLocalTexture);
- }
- if (lto)
- {
- layer = lto->getTexLayer(getName());
- }
- if (layer)
- {
- wearable->writeToAvatar();
- layer->setLTO(lto);
- success &= layer->render(x,y,width,height);
- }
- }
-
- return success;
-}
-
-/*virtual*/ BOOL LLTexLayerTemplate::blendAlphaTexture( S32 x, S32 y, S32 width, S32 height) // Multiplies a single alpha texture against the frame buffer
-{
- BOOL success = TRUE;
- U32 num_wearables = updateWearableCache();
- for (U32 i = 0; i < num_wearables; i++)
- {
- LLTexLayer *layer = getLayer(i);
- if (layer)
- {
- success &= layer->blendAlphaTexture(x,y,width,height);
- }
- }
- return success;
-}
-
-/*virtual*/ void LLTexLayerTemplate::gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height)
-{
- U32 num_wearables = updateWearableCache();
- for (U32 i = 0; i < num_wearables; i++)
- {
- LLTexLayer *layer = getLayer(i);
- if (layer)
- {
- layer->addAlphaMask(data, originX, originY, width, height);
- }
- }
-}
-
-/*virtual*/ void LLTexLayerTemplate::setHasMorph(BOOL newval)
-{
- mHasMorph = newval;
- U32 num_wearables = updateWearableCache();
- for (U32 i = 0; i < num_wearables; i++)
- {
- LLTexLayer *layer = getLayer(i);
- if (layer)
- {
- layer->setHasMorph(newval);
- }
- }
-}
-
-/*virtual*/ void LLTexLayerTemplate::deleteCaches()
-{
- U32 num_wearables = updateWearableCache();
- for (U32 i = 0; i < num_wearables; i++)
- {
- LLTexLayer *layer = getLayer(i);
- if (layer)
- {
- layer->deleteCaches();
- }
- }
-}
-
-/*virtual*/ BOOL LLTexLayerTemplate::isInvisibleAlphaMask() const
-{
- U32 num_wearables = updateWearableCache();
- for (U32 i = 0; i < num_wearables; i++)
- {
- LLTexLayer *layer = getLayer(i);
- if (layer)
- {
- if (layer->isInvisibleAlphaMask())
- {
- return TRUE;
- }
- }
- }
-
- return FALSE;
-}
-
-
-//-----------------------------------------------------------------------------
-// finds a specific layer based on a passed in name
-//-----------------------------------------------------------------------------
-LLTexLayerInterface* LLTexLayerSet::findLayerByName(const std::string& name)
-{
- for (layer_list_t::iterator iter = mLayerList.begin(); iter != mLayerList.end(); iter++ )
- {
- LLTexLayerInterface* layer = *iter;
- if (layer->getName() == name)
- {
- return layer;
- }
- }
- for (layer_list_t::iterator iter = mMaskLayerList.begin(); iter != mMaskLayerList.end(); iter++ )
- {
- LLTexLayerInterface* layer = *iter;
- if (layer->getName() == name)
- {
- return layer;
- }
- }
- return NULL;
-}
-
-void LLTexLayerSet::cloneTemplates(LLLocalTextureObject *lto, LLVOAvatarDefines::ETextureIndex tex_index, LLWearable *wearable)
-{
- // initialize all texlayers with this texture type for this LTO
- for( LLTexLayerSet::layer_list_t::iterator iter = mLayerList.begin(); iter != mLayerList.end(); iter++ )
- {
- LLTexLayerTemplate* layer = (LLTexLayerTemplate*)*iter;
- if (layer->getInfo()->getLocalTexture() == (S32) tex_index)
- {
- lto->addTexLayer(layer, wearable);
- }
- }
- for( LLTexLayerSet::layer_list_t::iterator iter = mMaskLayerList.begin(); iter != mMaskLayerList.end(); iter++ )
- {
- LLTexLayerTemplate* layer = (LLTexLayerTemplate*)*iter;
- if (layer->getInfo()->getLocalTexture() == (S32) tex_index)
- {
- lto->addTexLayer(layer, wearable);
- }
- }
-}
-//-----------------------------------------------------------------------------
-// LLTexLayerStaticImageList
-//-----------------------------------------------------------------------------
-
-LLTexLayerStaticImageList::LLTexLayerStaticImageList() :
- mGLBytes(0),
- mTGABytes(0),
- mImageNames(16384)
-{
-}
-
-LLTexLayerStaticImageList::~LLTexLayerStaticImageList()
-{
- deleteCachedImages();
-}
-
-void LLTexLayerStaticImageList::dumpByteCount() const
-{
- llinfos << "Avatar Static Textures " <<
- "KB GL:" << (mGLBytes / 1024) <<
- "KB TGA:" << (mTGABytes / 1024) << "KB" << llendl;
-}
-
-void LLTexLayerStaticImageList::deleteCachedImages()
-{
- if( mGLBytes || mTGABytes )
- {
- llinfos << "Clearing Static Textures " <<
- "KB GL:" << (mGLBytes / 1024) <<
- "KB TGA:" << (mTGABytes / 1024) << "KB" << llendl;
-
- //mStaticImageLists uses LLPointers, clear() will cause deletion
-
- mStaticImageListTGA.clear();
- mStaticImageList.clear();
-
- mGLBytes = 0;
- mTGABytes = 0;
- }
-}
-
-// Note: in general, for a given image image we'll call either getImageTga() or getTexture().
-// We call getImageTga() if the image is used as an alpha gradient.
-// Otherwise, we call getTexture()
-
-// Returns an LLImageTGA that contains the encoded data from a tga file named file_name.
-// Caches the result to speed identical subsequent requests.
-LLImageTGA* LLTexLayerStaticImageList::getImageTGA(const std::string& file_name)
-{
- const char *namekey = mImageNames.addString(file_name);
- image_tga_map_t::const_iterator iter = mStaticImageListTGA.find(namekey);
- if( iter != mStaticImageListTGA.end() )
- {
- return iter->second;
- }
- else
- {
- std::string path;
- path = gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,file_name);
- LLPointer<LLImageTGA> image_tga = new LLImageTGA( path );
- if( image_tga->getDataSize() > 0 )
- {
- mStaticImageListTGA[ namekey ] = image_tga;
- mTGABytes += image_tga->getDataSize();
- return image_tga;
- }
- else
- {
- return NULL;
- }
- }
-}
-
-// Returns a GL Image (without a backing ImageRaw) that contains the decoded data from a tga file named file_name.
-// Caches the result to speed identical subsequent requests.
-LLViewerTexture* LLTexLayerStaticImageList::getTexture(const std::string& file_name, BOOL is_mask)
-{
- LLPointer<LLViewerTexture> tex;
- const char *namekey = mImageNames.addString(file_name);
-
- texture_map_t::const_iterator iter = mStaticImageList.find(namekey);
- if( iter != mStaticImageList.end() )
- {
- tex = iter->second;
- }
- else
- {
- tex = LLViewerTextureManager::getLocalTexture( FALSE );
- LLPointer<LLImageRaw> image_raw = new LLImageRaw;
- if( loadImageRaw( file_name, image_raw ) )
- {
- if( (image_raw->getComponents() == 1) && is_mask )
- {
- // Note: these are static, unchanging images so it's ok to assume
- // that once an image is a mask it's always a mask.
- tex->setExplicitFormat( GL_ALPHA8, GL_ALPHA );
- }
- tex->createGLTexture(0, image_raw, 0, TRUE, LLViewerTexture::LOCAL);
-
- gGL.getTexUnit(0)->bind(tex);
- tex->setAddressMode(LLTexUnit::TAM_CLAMP);
-
- mStaticImageList [ namekey ] = tex;
- mGLBytes += (S32)tex->getWidth() * tex->getHeight() * tex->getComponents();
- }
- else
- {
- tex = NULL;
- }
- }
-
- return tex;
-}
-
-// Reads a .tga file, decodes it, and puts the decoded data in image_raw.
-// Returns TRUE if successful.
-BOOL LLTexLayerStaticImageList::loadImageRaw(const std::string& file_name, LLImageRaw* image_raw)
-{
- BOOL success = FALSE;
- std::string path;
- path = gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,file_name);
- LLPointer<LLImageTGA> image_tga = new LLImageTGA( path );
- if( image_tga->getDataSize() > 0 )
- {
- // Copy data from tga to raw.
- success = image_tga->decode( image_raw );
- }
-
- return success;
-}
-
-const std::string LLTexLayerSetBuffer::dumpTextureInfo() const
-{
- if (!isAgentAvatarValid()) return "";
-
- const BOOL is_high_res = !mNeedsUpload;
- const U32 num_low_res = mNumLowresUploads;
- const U32 upload_time = (U32)mNeedsUploadTimer.getElapsedTimeF32();
- const std::string local_texture_info = gAgentAvatarp->debugDumpLocalTextureDataInfo(mTexLayerSet);
-
- std::string status = "CREATING ";
- if (!uploadNeeded()) status = "DONE ";
- if (uploadInProgress()) status = "UPLOADING";
-
- std::string text = llformat("[%s] [HiRes:%d LoRes:%d] [Elapsed:%d] %s",
- status.c_str(),
- is_high_res, num_low_res,
- upload_time,
- local_texture_info.c_str());
- return text;
-}
diff --git a/indra/newview/lltexlayer.h b/indra/newview/lltexlayer.h
deleted file mode 100644
index 4f43547dae..0000000000
--- a/indra/newview/lltexlayer.h
+++ /dev/null
@@ -1,380 +0,0 @@
-/**
- * @file lltexlayer.h
- * @brief Texture layer classes. Used for avatars.
- *
- * $LicenseInfo:firstyear=2002&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$
- */
-
-#ifndef LL_LLTEXLAYER_H
-#define LL_LLTEXLAYER_H
-
-#include <deque>
-#include "lldynamictexture.h"
-#include "llvoavatardefines.h"
-#include "lltexlayerparams.h"
-
-class LLVOAvatar;
-class LLVOAvatarSelf;
-class LLImageTGA;
-class LLImageRaw;
-class LLXmlTreeNode;
-class LLTexLayerSet;
-class LLTexLayerSetInfo;
-class LLTexLayerInfo;
-class LLTexLayerSetBuffer;
-class LLWearable;
-class LLViewerVisualParam;
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// LLTexLayerInterface
-//
-// Interface class to generalize functionality shared by LLTexLayer
-// and LLTexLayerTemplate.
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-class LLTexLayerInterface
-{
-public:
- enum ERenderPass
- {
- RP_COLOR,
- RP_BUMP,
- RP_SHINE
- };
-
- LLTexLayerInterface(LLTexLayerSet* const layer_set);
- LLTexLayerInterface(const LLTexLayerInterface &layer, LLWearable *wearable);
- virtual ~LLTexLayerInterface() {}
-
- virtual BOOL render(S32 x, S32 y, S32 width, S32 height) = 0;
- virtual void deleteCaches() = 0;
- virtual BOOL blendAlphaTexture(S32 x, S32 y, S32 width, S32 height) = 0;
- virtual BOOL isInvisibleAlphaMask() const = 0;
-
- const LLTexLayerInfo* getInfo() const { return mInfo; }
- virtual BOOL setInfo(const LLTexLayerInfo *info, LLWearable* wearable); // sets mInfo, calls initialization functions
-
- const std::string& getName() const;
- const LLTexLayerSet* const getTexLayerSet() const { return mTexLayerSet; }
- LLTexLayerSet* const getTexLayerSet() { return mTexLayerSet; }
-
- void invalidateMorphMasks();
- virtual void setHasMorph(BOOL newval) { mHasMorph = newval; }
- BOOL hasMorph() const { return mHasMorph; }
- BOOL isMorphValid() const { return mMorphMasksValid; }
-
- void requestUpdate();
- virtual void gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height) = 0;
- BOOL hasAlphaParams() const { return !mParamAlphaList.empty(); }
-
- ERenderPass getRenderPass() const;
- BOOL isVisibilityMask() const;
-
-protected:
- const std::string& getGlobalColor() const;
- LLViewerVisualParam* getVisualParamPtr(S32 index) const;
-
-protected:
- LLTexLayerSet* const mTexLayerSet;
- const LLTexLayerInfo* mInfo;
- BOOL mMorphMasksValid;
- BOOL mHasMorph;
-
- // Layers can have either mParamColorList, mGlobalColor, or mFixedColor. They are looked for in that order.
- param_color_list_t mParamColorList;
- param_alpha_list_t mParamAlphaList;
- // mGlobalColor name stored in mInfo
- // mFixedColor value stored in mInfo
-};
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// LLTexLayerTemplate
-//
-// Only exists for llvoavatarself.
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-class LLTexLayerTemplate : public LLTexLayerInterface
-{
-public:
- LLTexLayerTemplate(LLTexLayerSet* const layer_set);
- LLTexLayerTemplate(const LLTexLayerTemplate &layer);
- /*virtual*/ ~LLTexLayerTemplate();
- /*virtual*/ BOOL render(S32 x, S32 y, S32 width, S32 height);
- /*virtual*/ BOOL setInfo(const LLTexLayerInfo *info, LLWearable* wearable); // This sets mInfo and calls initialization functions
- /*virtual*/ BOOL blendAlphaTexture(S32 x, S32 y, S32 width, S32 height); // Multiplies a single alpha texture against the frame buffer
- /*virtual*/ void gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height);
- /*virtual*/ void setHasMorph(BOOL newval);
- /*virtual*/ void deleteCaches();
- /*virtual*/ BOOL isInvisibleAlphaMask() const;
-protected:
- U32 updateWearableCache() const;
- LLTexLayer* getLayer(U32 i) const;
-private:
- typedef std::vector<LLWearable*> wearable_cache_t;
- mutable wearable_cache_t mWearableCache; // mutable b/c most get- require updating this cache
-};
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// LLTexLayer
-//
-// A single texture layer. Only exists for llvoavatarself.
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-class LLTexLayer : public LLTexLayerInterface
-{
-public:
- LLTexLayer(LLTexLayerSet* const layer_set);
- LLTexLayer(const LLTexLayer &layer, LLWearable *wearable);
- LLTexLayer(const LLTexLayerTemplate &layer_template, LLLocalTextureObject *lto, LLWearable *wearable);
- /*virtual*/ ~LLTexLayer();
-
- /*virtual*/ BOOL setInfo(const LLTexLayerInfo *info, LLWearable* wearable); // This sets mInfo and calls initialization functions
- /*virtual*/ BOOL render(S32 x, S32 y, S32 width, S32 height);
-
- /*virtual*/ void deleteCaches();
- const U8* getAlphaData() const;
-
- BOOL findNetColor(LLColor4* color) const;
- /*virtual*/ BOOL blendAlphaTexture(S32 x, S32 y, S32 width, S32 height); // Multiplies a single alpha texture against the frame buffer
- /*virtual*/ void gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height);
- BOOL renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLColor4 &layer_color);
- void addAlphaMask(U8 *data, S32 originX, S32 originY, S32 width, S32 height);
- /*virtual*/ BOOL isInvisibleAlphaMask() const;
-
- void setLTO(LLLocalTextureObject *lto) { mLocalTextureObject = lto; }
- LLLocalTextureObject* getLTO() { return mLocalTextureObject; }
-
- static void calculateTexLayerColor(const param_color_list_t &param_list, LLColor4 &net_color);
-protected:
- LLUUID getUUID() const;
-private:
- typedef std::map<U32, U8*> alpha_cache_t;
- alpha_cache_t mAlphaCache;
- LLLocalTextureObject* mLocalTextureObject;
-};
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// LLTexLayerSet
-//
-// An ordered set of texture layers that gets composited into a single texture.
-// Only exists for llvoavatarself.
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-class LLTexLayerSet
-{
- friend class LLTexLayerSetBuffer;
-public:
- LLTexLayerSet(LLVOAvatarSelf* const avatar);
- ~LLTexLayerSet();
-
- const LLTexLayerSetInfo* getInfo() const { return mInfo; }
- BOOL setInfo(const LLTexLayerSetInfo *info); // This sets mInfo and calls initialization functions
-
- BOOL render(S32 x, S32 y, S32 width, S32 height);
- void renderAlphaMaskTextures(S32 x, S32 y, S32 width, S32 height, bool forceClear = false);
-
- BOOL isBodyRegion(const std::string& region) const;
- LLTexLayerSetBuffer* getComposite();
- const LLTexLayerSetBuffer* getComposite() const; // Do not create one if it doesn't exist.
- void requestUpdate();
- void requestUpload();
- void cancelUpload();
- void updateComposite();
- BOOL isLocalTextureDataAvailable() const;
- BOOL isLocalTextureDataFinal() const;
- void createComposite();
- void destroyComposite();
- void setUpdatesEnabled(BOOL b);
- BOOL getUpdatesEnabled() const { return mUpdatesEnabled; }
- void deleteCaches();
- void gatherMorphMaskAlpha(U8 *data, S32 width, S32 height);
- void applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_components);
- BOOL isMorphValid() const;
- void invalidateMorphMasks();
- LLTexLayerInterface* findLayerByName(const std::string& name);
- void cloneTemplates(LLLocalTextureObject *lto, LLVOAvatarDefines::ETextureIndex tex_index, LLWearable* wearable);
-
- LLVOAvatarSelf* getAvatar() const { return mAvatar; }
- const std::string getBodyRegionName() const;
- BOOL hasComposite() const { return (mComposite.notNull()); }
- LLVOAvatarDefines::EBakedTextureIndex getBakedTexIndex() { return mBakedTexIndex; }
- void setBakedTexIndex(LLVOAvatarDefines::EBakedTextureIndex index) { mBakedTexIndex = index; }
- BOOL isVisible() const { return mIsVisible; }
-
- static BOOL sHasCaches;
-
-private:
- typedef std::vector<LLTexLayerInterface *> layer_list_t;
- layer_list_t mLayerList;
- layer_list_t mMaskLayerList;
- LLPointer<LLTexLayerSetBuffer> mComposite;
- LLVOAvatarSelf* const mAvatar; // note: backlink only; don't make this an LLPointer.
- BOOL mUpdatesEnabled;
- BOOL mIsVisible;
-
- LLVOAvatarDefines::EBakedTextureIndex mBakedTexIndex;
- const LLTexLayerSetInfo* mInfo;
-};
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// LLTexLayerSetInfo
-//
-// Contains shared layer set data.
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-class LLTexLayerSetInfo
-{
- friend class LLTexLayerSet;
-public:
- LLTexLayerSetInfo();
- ~LLTexLayerSetInfo();
- BOOL parseXml(LLXmlTreeNode* node);
- void createVisualParams(LLVOAvatar *avatar);
-private:
- std::string mBodyRegion;
- S32 mWidth;
- S32 mHeight;
- std::string mStaticAlphaFileName;
- BOOL mClearAlpha; // Set alpha to 1 for this layerset (if there is no mStaticAlphaFileName)
- typedef std::vector<LLTexLayerInfo*> layer_info_list_t;
- layer_info_list_t mLayerInfoList;
-};
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// LLTexLayerSetBuffer
-//
-// The composite image that a LLTexLayerSet writes to. Each LLTexLayerSet has one.
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-class LLTexLayerSetBuffer : public LLViewerDynamicTexture
-{
- LOG_CLASS(LLTexLayerSetBuffer);
-
-public:
- LLTexLayerSetBuffer(LLTexLayerSet* const owner, S32 width, S32 height);
- virtual ~LLTexLayerSetBuffer();
-
-public:
- /*virtual*/ S8 getType() const;
- BOOL isInitialized(void) const;
- static void dumpTotalByteCount();
- const std::string dumpTextureInfo() const;
- virtual void restoreGLTexture();
- virtual void destroyGLTexture();
-protected:
- void pushProjection() const;
- void popProjection() const;
-private:
- LLTexLayerSet* const mTexLayerSet;
- static S32 sGLByteCount;
-
- //--------------------------------------------------------------------
- // Render
- //--------------------------------------------------------------------
-public:
- /*virtual*/ BOOL needsRender();
-protected:
- BOOL render(S32 x, S32 y, S32 width, S32 height);
- virtual void preRender(BOOL clear_depth);
- virtual void postRender(BOOL success);
- virtual BOOL render();
-
- //--------------------------------------------------------------------
- // Uploads
- //--------------------------------------------------------------------
-public:
- void requestUpload();
- void cancelUpload();
- BOOL uploadNeeded() const; // We need to upload a new texture
- BOOL uploadInProgress() const; // We have started uploading a new texture and are awaiting the result
- BOOL uploadPending() const; // We are expecting a new texture to be uploaded at some point
- static void onTextureUploadComplete(const LLUUID& uuid,
- void* userdata,
- S32 result, LLExtStat ext_status);
-protected:
- BOOL isReadyToUpload() const;
- void doUpload(); // Does a read back and upload.
- void conditionalRestartUploadTimer();
-private:
- BOOL mNeedsUpload; // Whether we need to send our baked textures to the server
- U32 mNumLowresUploads; // Number of times we've sent a lowres version of our baked textures to the server
- BOOL mUploadPending; // Whether we have received back the new baked textures
- LLUUID mUploadID; // The current upload process (null if none).
- LLFrameTimer mNeedsUploadTimer; // Tracks time since upload was requested and performed.
- S32 mUploadFailCount; // Number of consecutive upload failures
- LLFrameTimer mUploadRetryTimer; // Tracks time since last upload failure.
-
- //--------------------------------------------------------------------
- // Updates
- //--------------------------------------------------------------------
-public:
- void requestUpdate();
- BOOL requestUpdateImmediate();
-protected:
- BOOL isReadyToUpdate() const;
- void doUpdate();
- void restartUpdateTimer();
-private:
- BOOL mNeedsUpdate; // Whether we need to locally update our baked textures
- U32 mNumLowresUpdates; // Number of times we've locally updated with lowres version of our baked textures
- LLFrameTimer mNeedsUpdateTimer; // Tracks time since update was requested and performed.
-};
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// LLTexLayerStaticImageList
-//
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-class LLTexLayerStaticImageList : public LLSingleton<LLTexLayerStaticImageList>
-{
-public:
- LLTexLayerStaticImageList();
- ~LLTexLayerStaticImageList();
- LLViewerTexture* getTexture(const std::string& file_name, BOOL is_mask);
- LLImageTGA* getImageTGA(const std::string& file_name);
- void deleteCachedImages();
- void dumpByteCount() const;
-protected:
- BOOL loadImageRaw(const std::string& file_name, LLImageRaw* image_raw);
-private:
- LLStringTable mImageNames;
- typedef std::map<const char*, LLPointer<LLViewerTexture> > texture_map_t;
- texture_map_t mStaticImageList;
- typedef std::map<const char*, LLPointer<LLImageTGA> > image_tga_map_t;
- image_tga_map_t mStaticImageListTGA;
- S32 mGLBytes;
- S32 mTGABytes;
-};
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// LLBakedUploadData
-//
-// Used by LLTexLayerSetBuffer for a callback.
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-struct LLBakedUploadData
-{
- LLBakedUploadData(const LLVOAvatarSelf* avatar,
- LLTexLayerSet* layerset,
- const LLUUID& id,
- bool highest_res);
- ~LLBakedUploadData() {}
- const LLUUID mID;
- const LLVOAvatarSelf* mAvatar; // note: backlink only; don't LLPointer
- LLTexLayerSet* mTexLayerSet;
- const U64 mStartTime; // for measuring baked texture upload time
- const bool mIsHighestRes; // whether this is a "final" bake, or intermediate low res
-};
-
-#endif // LL_LLTEXLAYER_H
diff --git a/indra/newview/lltexlayerparams.cpp b/indra/newview/lltexlayerparams.cpp
deleted file mode 100644
index 8972827eff..0000000000
--- a/indra/newview/lltexlayerparams.cpp
+++ /dev/null
@@ -1,568 +0,0 @@
-/**
- * @file lltexlayerparams.cpp
- * @brief Texture layer parameters
- *
- * $LicenseInfo:firstyear=2002&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 "llviewerprecompiledheaders.h"
-
-#include "lltexlayerparams.h"
-
-#include "llagentcamera.h"
-#include "llimagetga.h"
-#include "lltexlayer.h"
-#include "llvoavatarself.h"
-#include "llwearable.h"
-#include "llui.h"
-
-//-----------------------------------------------------------------------------
-// LLTexLayerParam
-//-----------------------------------------------------------------------------
-LLTexLayerParam::LLTexLayerParam(LLTexLayerInterface *layer) :
- mTexLayer(layer),
- mAvatar(NULL)
-{
- if (mTexLayer != NULL)
- {
- mAvatar = mTexLayer->getTexLayerSet()->getAvatar();
- }
- else
- {
- llerrs << "LLTexLayerParam constructor passed with NULL reference for layer!" << llendl;
- }
-}
-
-LLTexLayerParam::LLTexLayerParam(LLVOAvatar *avatar) :
- mTexLayer(NULL)
-{
- mAvatar = avatar;
-}
-
-
-BOOL LLTexLayerParam::setInfo(LLViewerVisualParamInfo *info, BOOL add_to_avatar )
-{
- LLViewerVisualParam::setInfo(info);
-
- if (add_to_avatar)
- {
- mAvatar->addVisualParam( this);
- }
-
- return TRUE;
-}
-
-
-//-----------------------------------------------------------------------------
-// LLTexLayerParamAlpha
-//-----------------------------------------------------------------------------
-
-// static
-LLTexLayerParamAlpha::param_alpha_ptr_list_t LLTexLayerParamAlpha::sInstances;
-
-// static
-void LLTexLayerParamAlpha::dumpCacheByteCount()
-{
- S32 gl_bytes = 0;
- getCacheByteCount( &gl_bytes);
- llinfos << "Processed Alpha Texture Cache GL:" << (gl_bytes/1024) << "KB" << llendl;
-}
-
-// static
-void LLTexLayerParamAlpha::getCacheByteCount(S32* gl_bytes)
-{
- *gl_bytes = 0;
-
- for (param_alpha_ptr_list_t::iterator iter = sInstances.begin();
- iter != sInstances.end(); iter++)
- {
- LLTexLayerParamAlpha* instance = *iter;
- LLViewerTexture* tex = instance->mCachedProcessedTexture;
- if (tex)
- {
- S32 bytes = (S32)tex->getWidth() * tex->getHeight() * tex->getComponents();
-
- if (tex->hasGLTexture())
- {
- *gl_bytes += bytes;
- }
- }
- }
-}
-
-LLTexLayerParamAlpha::LLTexLayerParamAlpha(LLTexLayerInterface* layer) :
- LLTexLayerParam(layer),
- mCachedProcessedTexture(NULL),
- mNeedsCreateTexture(FALSE),
- mStaticImageInvalid(FALSE),
- mAvgDistortionVec(1.f, 1.f, 1.f),
- mCachedEffectiveWeight(0.f)
-{
- sInstances.push_front(this);
-}
-
-LLTexLayerParamAlpha::LLTexLayerParamAlpha(LLVOAvatar* avatar) :
- LLTexLayerParam(avatar),
- mCachedProcessedTexture(NULL),
- mNeedsCreateTexture(FALSE),
- mStaticImageInvalid(FALSE),
- mAvgDistortionVec(1.f, 1.f, 1.f),
- mCachedEffectiveWeight(0.f)
-{
- sInstances.push_front(this);
-}
-
-
-LLTexLayerParamAlpha::~LLTexLayerParamAlpha()
-{
- deleteCaches();
- sInstances.remove(this);
-}
-
-/*virtual*/ LLViewerVisualParam* LLTexLayerParamAlpha::cloneParam(LLWearable* wearable) const
-{
- LLTexLayerParamAlpha *new_param = new LLTexLayerParamAlpha(mTexLayer);
- *new_param = *this;
- return new_param;
-}
-
-void LLTexLayerParamAlpha::deleteCaches()
-{
- mStaticImageTGA = NULL; // deletes image
- mCachedProcessedTexture = NULL;
- mStaticImageRaw = NULL;
- mNeedsCreateTexture = FALSE;
-}
-
-BOOL LLTexLayerParamAlpha::getMultiplyBlend() const
-{
- return ((LLTexLayerParamAlphaInfo *)getInfo())->mMultiplyBlend;
-}
-
-void LLTexLayerParamAlpha::setWeight(F32 weight, BOOL upload_bake)
-{
- if (mIsAnimating || mTexLayer == NULL)
- {
- return;
- }
- F32 min_weight = getMinWeight();
- F32 max_weight = getMaxWeight();
- F32 new_weight = llclamp(weight, min_weight, max_weight);
- U8 cur_u8 = F32_to_U8(mCurWeight, min_weight, max_weight);
- U8 new_u8 = F32_to_U8(new_weight, min_weight, max_weight);
- if (cur_u8 != new_u8)
- {
- mCurWeight = new_weight;
-
- if ((mAvatar->getSex() & getSex()) && (mAvatar->isSelf() && !mIsDummy)) // only trigger a baked texture update if we're changing a wearable's visual param.
- {
- if (isAgentAvatarValid() && !gAgentAvatarp->isUsingBakedTextures())
- {
- upload_bake = FALSE;
- }
- mAvatar->invalidateComposite(mTexLayer->getTexLayerSet(), upload_bake);
- mTexLayer->invalidateMorphMasks();
- }
- }
-}
-
-void LLTexLayerParamAlpha::setAnimationTarget(F32 target_value, BOOL upload_bake)
-{
- // do not animate dummy parameters
- if (mIsDummy)
- {
- setWeight(target_value, upload_bake);
- return;
- }
-
- mTargetWeight = target_value;
- setWeight(target_value, upload_bake);
- mIsAnimating = TRUE;
- if (mNext)
- {
- mNext->setAnimationTarget(target_value, upload_bake);
- }
-}
-
-void LLTexLayerParamAlpha::animate(F32 delta, BOOL upload_bake)
-{
- if (mNext)
- {
- mNext->animate(delta, upload_bake);
- }
-}
-
-BOOL LLTexLayerParamAlpha::getSkip() const
-{
- if (!mTexLayer)
- {
- return TRUE;
- }
-
- const LLVOAvatar *avatar = mTexLayer->getTexLayerSet()->getAvatar();
-
- if (((LLTexLayerParamAlphaInfo *)getInfo())->mSkipIfZeroWeight)
- {
- F32 effective_weight = (avatar->getSex() & getSex()) ? mCurWeight : getDefaultWeight();
- if (is_approx_zero(effective_weight))
- {
- return TRUE;
- }
- }
-
- LLWearableType::EType type = (LLWearableType::EType)getWearableType();
- if ((type != LLWearableType::WT_INVALID) && !avatar->isWearingWearableType(type))
- {
- return TRUE;
- }
-
- return FALSE;
-}
-
-
-BOOL LLTexLayerParamAlpha::render(S32 x, S32 y, S32 width, S32 height)
-{
- BOOL success = TRUE;
-
- if (!mTexLayer)
- {
- return success;
- }
-
- F32 effective_weight = (mTexLayer->getTexLayerSet()->getAvatar()->getSex() & getSex()) ? mCurWeight : getDefaultWeight();
- BOOL weight_changed = effective_weight != mCachedEffectiveWeight;
- if (getSkip())
- {
- return success;
- }
-
- LLTexLayerParamAlphaInfo *info = (LLTexLayerParamAlphaInfo *)getInfo();
- gGL.flush();
- if (info->mMultiplyBlend)
- {
- gGL.blendFunc(LLRender::BF_DEST_ALPHA, LLRender::BF_ZERO); // Multiplication: approximates a min() function
- }
- else
- {
- gGL.setSceneBlendType(LLRender::BT_ADD); // Addition: approximates a max() function
- }
-
- if (!info->mStaticImageFileName.empty() && !mStaticImageInvalid)
- {
- if (mStaticImageTGA.isNull())
- {
- // Don't load the image file until we actually need it the first time. Like now.
- mStaticImageTGA = LLTexLayerStaticImageList::getInstance()->getImageTGA(info->mStaticImageFileName);
- // We now have something in one of our caches
- LLTexLayerSet::sHasCaches |= mStaticImageTGA.notNull() ? TRUE : FALSE;
-
- if (mStaticImageTGA.isNull())
- {
- llwarns << "Unable to load static file: " << info->mStaticImageFileName << llendl;
- mStaticImageInvalid = TRUE; // don't try again.
- return FALSE;
- }
- }
-
- const S32 image_tga_width = mStaticImageTGA->getWidth();
- const S32 image_tga_height = mStaticImageTGA->getHeight();
- if (!mCachedProcessedTexture ||
- (mCachedProcessedTexture->getWidth() != image_tga_width) ||
- (mCachedProcessedTexture->getHeight() != image_tga_height) ||
- (weight_changed))
- {
-// llinfos << "Building Cached Alpha: " << mName << ": (" << mStaticImageRaw->getWidth() << ", " << mStaticImageRaw->getHeight() << ") " << effective_weight << llendl;
- mCachedEffectiveWeight = effective_weight;
-
- if (!mCachedProcessedTexture)
- {
- mCachedProcessedTexture = LLViewerTextureManager::getLocalTexture(image_tga_width, image_tga_height, 1, FALSE);
-
- // We now have something in one of our caches
- LLTexLayerSet::sHasCaches |= mCachedProcessedTexture ? TRUE : FALSE;
-
- mCachedProcessedTexture->setExplicitFormat(GL_ALPHA8, GL_ALPHA);
- }
-
- // Applies domain and effective weight to data as it is decoded. Also resizes the raw image if needed.
- mStaticImageRaw = NULL;
- mStaticImageRaw = new LLImageRaw;
- mStaticImageTGA->decodeAndProcess(mStaticImageRaw, info->mDomain, effective_weight);
- mNeedsCreateTexture = TRUE;
- }
-
- if (mCachedProcessedTexture)
- {
- {
- // Create the GL texture, and then hang onto it for future use.
- if (mNeedsCreateTexture)
- {
- mCachedProcessedTexture->createGLTexture(0, mStaticImageRaw);
- mNeedsCreateTexture = FALSE;
- gGL.getTexUnit(0)->bind(mCachedProcessedTexture);
- mCachedProcessedTexture->setAddressMode(LLTexUnit::TAM_CLAMP);
- }
-
- LLGLSNoAlphaTest gls_no_alpha_test;
- gGL.getTexUnit(0)->bind(mCachedProcessedTexture);
- gl_rect_2d_simple_tex(width, height);
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- stop_glerror();
- }
- }
-
- // Don't keep the cache for other people's avatars
- // (It's not really a "cache" in that case, but the logic is the same)
- if (!mAvatar->isSelf())
- {
- mCachedProcessedTexture = NULL;
- }
- }
- else
- {
- LLGLDisable no_alpha(GL_ALPHA_TEST);
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.color4f(0.f, 0.f, 0.f, effective_weight);
- gl_rect_2d_simple(width, height);
- }
-
- return success;
-}
-
-//-----------------------------------------------------------------------------
-// LLTexLayerParamAlphaInfo
-//-----------------------------------------------------------------------------
-LLTexLayerParamAlphaInfo::LLTexLayerParamAlphaInfo() :
- mMultiplyBlend(FALSE),
- mSkipIfZeroWeight(FALSE),
- mDomain(0.f)
-{
-}
-
-BOOL LLTexLayerParamAlphaInfo::parseXml(LLXmlTreeNode* node)
-{
- llassert(node->hasName("param") && node->getChildByName("param_alpha"));
-
- if (!LLViewerVisualParamInfo::parseXml(node))
- return FALSE;
-
- LLXmlTreeNode* param_alpha_node = node->getChildByName("param_alpha");
- if (!param_alpha_node)
- {
- return FALSE;
- }
-
- static LLStdStringHandle tga_file_string = LLXmlTree::addAttributeString("tga_file");
- if (param_alpha_node->getFastAttributeString(tga_file_string, mStaticImageFileName))
- {
- // Don't load the image file until it's actually needed.
- }
-// else
-// {
-// llwarns << "<param_alpha> element is missing tga_file attribute." << llendl;
-// }
-
- static LLStdStringHandle multiply_blend_string = LLXmlTree::addAttributeString("multiply_blend");
- param_alpha_node->getFastAttributeBOOL(multiply_blend_string, mMultiplyBlend);
-
- static LLStdStringHandle skip_if_zero_string = LLXmlTree::addAttributeString("skip_if_zero");
- param_alpha_node->getFastAttributeBOOL(skip_if_zero_string, mSkipIfZeroWeight);
-
- static LLStdStringHandle domain_string = LLXmlTree::addAttributeString("domain");
- param_alpha_node->getFastAttributeF32(domain_string, mDomain);
-
- return TRUE;
-}
-
-
-
-
-LLTexLayerParamColor::LLTexLayerParamColor(LLTexLayerInterface* layer) :
- LLTexLayerParam(layer),
- mAvgDistortionVec(1.f, 1.f, 1.f)
-{
-}
-
-LLTexLayerParamColor::LLTexLayerParamColor(LLVOAvatar *avatar) :
- LLTexLayerParam(avatar),
- mAvgDistortionVec(1.f, 1.f, 1.f)
-{
-}
-
-LLTexLayerParamColor::~LLTexLayerParamColor()
-{
-}
-
-/*virtual*/ LLViewerVisualParam* LLTexLayerParamColor::cloneParam(LLWearable* wearable) const
-{
- LLTexLayerParamColor *new_param = new LLTexLayerParamColor(mTexLayer);
- *new_param = *this;
- return new_param;
-}
-
-LLColor4 LLTexLayerParamColor::getNetColor() const
-{
- const LLTexLayerParamColorInfo *info = (LLTexLayerParamColorInfo *)getInfo();
-
- llassert(info->mNumColors >= 1);
-
- F32 effective_weight = (mAvatar && (mAvatar->getSex() & getSex())) ? mCurWeight : getDefaultWeight();
-
- S32 index_last = info->mNumColors - 1;
- F32 scaled_weight = effective_weight * index_last;
- S32 index_start = (S32) scaled_weight;
- S32 index_end = index_start + 1;
- if (index_start == index_last)
- {
- return info->mColors[index_last];
- }
- else
- {
- F32 weight = scaled_weight - index_start;
- const LLColor4 *start = &info->mColors[ index_start ];
- const LLColor4 *end = &info->mColors[ index_end ];
- return LLColor4((1.f - weight) * start->mV[VX] + weight * end->mV[VX],
- (1.f - weight) * start->mV[VY] + weight * end->mV[VY],
- (1.f - weight) * start->mV[VZ] + weight * end->mV[VZ],
- (1.f - weight) * start->mV[VW] + weight * end->mV[VW]);
- }
-}
-
-void LLTexLayerParamColor::setWeight(F32 weight, BOOL upload_bake)
-{
- if (mIsAnimating)
- {
- return;
- }
-
- const LLTexLayerParamColorInfo *info = (LLTexLayerParamColorInfo *)getInfo();
- F32 min_weight = getMinWeight();
- F32 max_weight = getMaxWeight();
- F32 new_weight = llclamp(weight, min_weight, max_weight);
- U8 cur_u8 = F32_to_U8(mCurWeight, min_weight, max_weight);
- U8 new_u8 = F32_to_U8(new_weight, min_weight, max_weight);
- if (cur_u8 != new_u8)
- {
- mCurWeight = new_weight;
-
- if (info->mNumColors <= 0)
- {
- // This will happen when we set the default weight the first time.
- return;
- }
-
- if ((mAvatar->getSex() & getSex()) && (mAvatar->isSelf() && !mIsDummy)) // only trigger a baked texture update if we're changing a wearable's visual param.
- {
- onGlobalColorChanged(upload_bake);
- if (mTexLayer)
- {
- mAvatar->invalidateComposite(mTexLayer->getTexLayerSet(), upload_bake);
- }
- }
-
-// llinfos << "param " << mName << " = " << new_weight << llendl;
- }
-}
-
-void LLTexLayerParamColor::setAnimationTarget(F32 target_value, BOOL upload_bake)
-{
- // set value first then set interpolating flag to ignore further updates
- mTargetWeight = target_value;
- setWeight(target_value, upload_bake);
- mIsAnimating = TRUE;
- if (mNext)
- {
- mNext->setAnimationTarget(target_value, upload_bake);
- }
-}
-
-void LLTexLayerParamColor::animate(F32 delta, BOOL upload_bake)
-{
- if (mNext)
- {
- mNext->animate(delta, upload_bake);
- }
-}
-
-//-----------------------------------------------------------------------------
-// LLTexLayerParamColorInfo
-//-----------------------------------------------------------------------------
-LLTexLayerParamColorInfo::LLTexLayerParamColorInfo() :
- mOperation(LLTexLayerParamColor::OP_ADD),
- mNumColors(0)
-{
-}
-
-BOOL LLTexLayerParamColorInfo::parseXml(LLXmlTreeNode *node)
-{
- llassert(node->hasName("param") && node->getChildByName("param_color"));
-
- if (!LLViewerVisualParamInfo::parseXml(node))
- return FALSE;
-
- LLXmlTreeNode* param_color_node = node->getChildByName("param_color");
- if (!param_color_node)
- {
- return FALSE;
- }
-
- std::string op_string;
- static LLStdStringHandle operation_string = LLXmlTree::addAttributeString("operation");
- if (param_color_node->getFastAttributeString(operation_string, op_string))
- {
- LLStringUtil::toLower(op_string);
- if (op_string == "add") mOperation = LLTexLayerParamColor::OP_ADD;
- else if (op_string == "multiply") mOperation = LLTexLayerParamColor::OP_MULTIPLY;
- else if (op_string == "blend") mOperation = LLTexLayerParamColor::OP_BLEND;
- }
-
- mNumColors = 0;
-
- LLColor4U color4u;
- for (LLXmlTreeNode* child = param_color_node->getChildByName("value");
- child;
- child = param_color_node->getNextNamedChild())
- {
- if ((mNumColors < MAX_COLOR_VALUES))
- {
- static LLStdStringHandle color_string = LLXmlTree::addAttributeString("color");
- if (child->getFastAttributeColor4U(color_string, color4u))
- {
- mColors[ mNumColors ].setVec(color4u);
- mNumColors++;
- }
- }
- }
- if (!mNumColors)
- {
- llwarns << "<param_color> is missing <value> sub-elements" << llendl;
- return FALSE;
- }
-
- if ((mOperation == LLTexLayerParamColor::OP_BLEND) && (mNumColors != 1))
- {
- llwarns << "<param_color> with operation\"blend\" must have exactly one <value>" << llendl;
- return FALSE;
- }
-
- return TRUE;
-}
diff --git a/indra/newview/lltexlayerparams.h b/indra/newview/lltexlayerparams.h
deleted file mode 100644
index 74c22b0cdf..0000000000
--- a/indra/newview/lltexlayerparams.h
+++ /dev/null
@@ -1,193 +0,0 @@
-/**
- * @file lltexlayerparams.h
- * @brief Texture layer parameters, used by lltexlayer.
- *
- * $LicenseInfo:firstyear=2002&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$
- */
-
-#ifndef LL_LLTEXLAYERPARAMS_H
-#define LL_LLTEXLAYERPARAMS_H
-
-#include "llviewervisualparam.h"
-
-class LLImageRaw;
-class LLImageTGA;
-class LLTexLayer;
-class LLTexLayerInterface;
-class LLViewerTexture;
-class LLVOAvatar;
-class LLWearable;
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// LLTexLayerParam
-//
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-class LLTexLayerParam : public LLViewerVisualParam
-{
-public:
- LLTexLayerParam(LLTexLayerInterface *layer);
- LLTexLayerParam(LLVOAvatar *avatar);
- /*virtual*/ BOOL setInfo(LLViewerVisualParamInfo *info, BOOL add_to_avatar );
- /*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable) const = 0;
-
-protected:
- LLTexLayerInterface* mTexLayer;
- LLVOAvatar* mAvatar;
-};
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// LLTexLayerParamAlpha
-//
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-class LLTexLayerParamAlpha : public LLTexLayerParam
-{
-public:
- LLTexLayerParamAlpha( LLTexLayerInterface* layer );
- LLTexLayerParamAlpha( LLVOAvatar* avatar );
- /*virtual*/ ~LLTexLayerParamAlpha();
-
- /*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable = NULL) const;
-
- // LLVisualParam Virtual functions
- ///*virtual*/ BOOL parseData(LLXmlTreeNode* node);
- /*virtual*/ void apply( ESex avatar_sex ) {}
- /*virtual*/ void setWeight(F32 weight, BOOL upload_bake);
- /*virtual*/ void setAnimationTarget(F32 target_value, BOOL upload_bake);
- /*virtual*/ void animate(F32 delta, BOOL upload_bake);
-
- // LLViewerVisualParam Virtual functions
- /*virtual*/ F32 getTotalDistortion() { return 1.f; }
- /*virtual*/ const LLVector3& getAvgDistortion() { return mAvgDistortionVec; }
- /*virtual*/ F32 getMaxDistortion() { return 3.f; }
- /*virtual*/ LLVector3 getVertexDistortion(S32 index, LLPolyMesh *poly_mesh) { return LLVector3(1.f, 1.f, 1.f);}
- /*virtual*/ const LLVector3* getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh) { index = 0; poly_mesh = NULL; return &mAvgDistortionVec;};
- /*virtual*/ const LLVector3* getNextDistortion(U32 *index, LLPolyMesh **poly_mesh) { index = 0; poly_mesh = NULL; return NULL;};
-
- // New functions
- BOOL render( S32 x, S32 y, S32 width, S32 height );
- BOOL getSkip() const;
- void deleteCaches();
- BOOL getMultiplyBlend() const;
-
-private:
- LLPointer<LLViewerTexture> mCachedProcessedTexture;
- LLPointer<LLImageTGA> mStaticImageTGA;
- LLPointer<LLImageRaw> mStaticImageRaw;
- BOOL mNeedsCreateTexture;
- BOOL mStaticImageInvalid;
- LLVector3 mAvgDistortionVec;
- F32 mCachedEffectiveWeight;
-
-public:
- // Global list of instances for gathering statistics
- static void dumpCacheByteCount();
- static void getCacheByteCount( S32* gl_bytes );
-
- typedef std::list< LLTexLayerParamAlpha* > param_alpha_ptr_list_t;
- static param_alpha_ptr_list_t sInstances;
-};
-class LLTexLayerParamAlphaInfo : public LLViewerVisualParamInfo
-{
- friend class LLTexLayerParamAlpha;
-public:
- LLTexLayerParamAlphaInfo();
- /*virtual*/ ~LLTexLayerParamAlphaInfo() {};
-
- /*virtual*/ BOOL parseXml(LLXmlTreeNode* node);
-
-private:
- std::string mStaticImageFileName;
- BOOL mMultiplyBlend;
- BOOL mSkipIfZeroWeight;
- F32 mDomain;
-};
-//
-// LLTexLayerParamAlpha
-//-----------------------------------------------------------------------------
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// LLTexLayerParamColor
-//
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-class LLTexLayerParamColor : public LLTexLayerParam
-{
-public:
- enum EColorOperation
- {
- OP_ADD = 0,
- OP_MULTIPLY = 1,
- OP_BLEND = 2,
- OP_COUNT = 3 // Number of operations
- };
-
- LLTexLayerParamColor( LLTexLayerInterface* layer );
- LLTexLayerParamColor( LLVOAvatar* avatar );
- /* virtual */ ~LLTexLayerParamColor();
-
- /*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable = NULL) const;
-
- // LLVisualParam Virtual functions
- ///*virtual*/ BOOL parseData(LLXmlTreeNode* node);
- /*virtual*/ void apply( ESex avatar_sex ) {}
- /*virtual*/ void setWeight(F32 weight, BOOL upload_bake);
- /*virtual*/ void setAnimationTarget(F32 target_value, BOOL upload_bake);
- /*virtual*/ void animate(F32 delta, BOOL upload_bake);
-
-
- // LLViewerVisualParam Virtual functions
- /*virtual*/ F32 getTotalDistortion() { return 1.f; }
- /*virtual*/ const LLVector3& getAvgDistortion() { return mAvgDistortionVec; }
- /*virtual*/ F32 getMaxDistortion() { return 3.f; }
- /*virtual*/ LLVector3 getVertexDistortion(S32 index, LLPolyMesh *poly_mesh) { return LLVector3(1.f, 1.f, 1.f); }
- /*virtual*/ const LLVector3* getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh) { index = 0; poly_mesh = NULL; return &mAvgDistortionVec;};
- /*virtual*/ const LLVector3* getNextDistortion(U32 *index, LLPolyMesh **poly_mesh) { index = 0; poly_mesh = NULL; return NULL;};
-
- // New functions
- LLColor4 getNetColor() const;
-protected:
- virtual void onGlobalColorChanged(bool upload_bake) {}
-private:
- LLVector3 mAvgDistortionVec;
-};
-
-class LLTexLayerParamColorInfo : public LLViewerVisualParamInfo
-{
- friend class LLTexLayerParamColor;
-
-public:
- LLTexLayerParamColorInfo();
- virtual ~LLTexLayerParamColorInfo() {};
- BOOL parseXml( LLXmlTreeNode* node );
- LLTexLayerParamColor::EColorOperation getOperation() const { return mOperation; }
-private:
- enum { MAX_COLOR_VALUES = 20 };
- LLTexLayerParamColor::EColorOperation mOperation;
- LLColor4 mColors[MAX_COLOR_VALUES];
- S32 mNumColors;
-};
-
-typedef std::vector<LLTexLayerParamColor *> param_color_list_t;
-typedef std::vector<LLTexLayerParamAlpha *> param_alpha_list_t;
-typedef std::vector<LLTexLayerParamColorInfo *> param_color_info_list_t;
-typedef std::vector<LLTexLayerParamAlphaInfo *> param_alpha_info_list_t;
-
-#endif
diff --git a/indra/newview/lltextureatlas.cpp b/indra/newview/lltextureatlas.cpp
index d2e4b01732..dbbe331954 100644..100755
--- a/indra/newview/lltextureatlas.cpp
+++ b/indra/newview/lltextureatlas.cpp
@@ -71,7 +71,7 @@ LLTextureAtlas::~LLTextureAtlas()
//virtual
S8 LLTextureAtlas::getType() const
{
- return LLViewerTexture::ATLAS_TEXTURE ;
+ return 0; //LLViewerTexture::ATLAS_TEXTURE ;
}
void LLTextureAtlas::getTexCoordOffset(S16 col, S16 row, F32& xoffset, F32& yoffset)
@@ -116,7 +116,6 @@ LLGLuint LLTextureAtlas::insertSubTexture(LLImageGL* source_gl_tex, S32 discard_
return 0 ;
}
- glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, TRUE);
glTexSubImage2D(GL_TEXTURE_2D, 0, xoffset, yoffset, w, h,
mGLTexturep->getPrimaryFormat(), mGLTexturep->getFormatType(), raw_image->getData());
diff --git a/indra/newview/lltextureatlas.h b/indra/newview/lltextureatlas.h
index 6b36eb7fe4..6b36eb7fe4 100644..100755
--- a/indra/newview/lltextureatlas.h
+++ b/indra/newview/lltextureatlas.h
diff --git a/indra/newview/lltextureatlasmanager.cpp b/indra/newview/lltextureatlasmanager.cpp
index ca9d6da4db..ca9d6da4db 100644..100755
--- a/indra/newview/lltextureatlasmanager.cpp
+++ b/indra/newview/lltextureatlasmanager.cpp
diff --git a/indra/newview/lltextureatlasmanager.h b/indra/newview/lltextureatlasmanager.h
index b643056198..b643056198 100644..100755
--- a/indra/newview/lltextureatlasmanager.h
+++ b/indra/newview/lltextureatlasmanager.h
diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp
index 8632890bbb..5bc2e971eb 100644..100755
--- a/indra/newview/lltexturecache.cpp
+++ b/indra/newview/lltexturecache.cpp
@@ -50,6 +50,8 @@
const S32 TEXTURE_CACHE_ENTRY_SIZE = FIRST_PACKET_SIZE;//1024;
const F32 TEXTURE_CACHE_PURGE_AMOUNT = .20f; // % amount to reduce the cache by when it exceeds its limit
const F32 TEXTURE_CACHE_LRU_SIZE = .10f; // % amount for LRU list (low overhead to regenerate)
+const S32 TEXTURE_FAST_CACHE_ENTRY_OVERHEAD = sizeof(S32) * 4; //w, h, c, level
+const S32 TEXTURE_FAST_CACHE_ENTRY_SIZE = 16 * 16 * 4 + TEXTURE_FAST_CACHE_ENTRY_OVERHEAD;
class LLTextureCacheWorker : public LLWorkerClass
{
@@ -283,9 +285,12 @@ public:
LLTextureCacheRemoteWorker(LLTextureCache* cache, U32 priority, const LLUUID& id,
U8* data, S32 datasize, S32 offset,
S32 imagesize, // for writes
+ LLPointer<LLImageRaw> raw, S32 discardlevel,
LLTextureCache::Responder* responder)
: LLTextureCacheWorker(cache, priority, id, data, datasize, offset, imagesize, responder),
- mState(INIT)
+ mState(INIT),
+ mRawImage(raw),
+ mRawDiscardLevel(discardlevel)
{
}
@@ -303,6 +308,8 @@ private:
};
e_state mState;
+ LLPointer<LLImageRaw> mRawImage;
+ S32 mRawDiscardLevel;
};
@@ -559,6 +566,14 @@ bool LLTextureCacheRemoteWorker::doWrite()
if(idx < 0)
{
idx = mCache->setHeaderCacheEntry(mID, entry, mImageSize, mDataSize); // create the new entry.
+ if(idx >= 0)
+ {
+ // (almost always) write to the fast cache.
+ if (mRawImage->getDataSize())
+ {
+ llassert_always(mCache->writeToFastCache(idx, mRawImage, mRawDiscardLevel));
+ }
+ }
}
else
{
@@ -658,6 +673,7 @@ bool LLTextureCacheRemoteWorker::doWrite()
// Nothing else to do at that point...
done = true;
}
+ mRawImage = NULL;
// Clean up and exit
return done;
@@ -744,10 +760,14 @@ LLTextureCache::LLTextureCache(bool threaded)
mWorkersMutex(NULL),
mHeaderMutex(NULL),
mListMutex(NULL),
+ mFastCacheMutex(NULL),
mHeaderAPRFile(NULL),
mReadOnly(TRUE), //do not allow to change the texture cache until setReadOnly() is called.
mTexturesSizeTotal(0),
- mDoPurge(FALSE)
+ mDoPurge(FALSE),
+ mFastCachep(NULL),
+ mFastCachePoolp(NULL),
+ mFastCachePadBuffer(NULL)
{
}
@@ -755,6 +775,9 @@ LLTextureCache::~LLTextureCache()
{
clearDeleteList() ;
writeUpdatedEntries() ;
+ delete mFastCachep;
+ delete mFastCachePoolp;
+ FREE_MEM(LLImageBase::getPrivatePool(), mFastCachePadBuffer);
}
//////////////////////////////////////////////////////////////////////////////
@@ -879,15 +902,15 @@ BOOL LLTextureCache::isInLocal(const LLUUID& id)
//////////////////////////////////////////////////////////////////////////////
//static
-const S32 MAX_REASONABLE_FILE_SIZE = 512*1024*1024; // 512 MB
-F32 LLTextureCache::sHeaderCacheVersion = 1.4f;
-U32 LLTextureCache::sCacheMaxEntries = MAX_REASONABLE_FILE_SIZE / TEXTURE_CACHE_ENTRY_SIZE;
+F32 LLTextureCache::sHeaderCacheVersion = 1.7f;
+U32 LLTextureCache::sCacheMaxEntries = 1024 * 1024; //~1 million textures.
S64 LLTextureCache::sCacheMaxTexturesSize = 0; // no limit
const char* entries_filename = "texture.entries";
const char* cache_filename = "texture.cache";
const char* old_textures_dirname = "textures";
//change the location of the texture cache to prevent from being deleted by old version viewers.
const char* textures_dirname = "texturecache";
+const char* fast_cache_filename = "FastCache.cache";
void LLTextureCache::setDirNames(ELLPath location)
{
@@ -896,6 +919,7 @@ void LLTextureCache::setDirNames(ELLPath location)
mHeaderEntriesFileName = gDirUtilp->getExpandedFilename(location, textures_dirname, entries_filename);
mHeaderDataFileName = gDirUtilp->getExpandedFilename(location, textures_dirname, cache_filename);
mTexturesDirName = gDirUtilp->getExpandedFilename(location, textures_dirname);
+ mFastCacheFileName = gDirUtilp->getExpandedFilename(location, textures_dirname, fast_cache_filename);
}
void LLTextureCache::purgeCache(ELLPath location)
@@ -938,8 +962,8 @@ S64 LLTextureCache::initCache(ELLPath location, S64 max_size, BOOL texture_cache
{
llassert_always(getPending() == 0) ; //should not start accessing the texture cache before initialized.
- S64 header_size = (max_size * 2) / 10;
- S64 max_entries = header_size / TEXTURE_CACHE_ENTRY_SIZE;
+ S64 header_size = (max_size / 100) * 36; //0.36 * max_size
+ S64 max_entries = header_size / (TEXTURE_CACHE_ENTRY_SIZE + TEXTURE_FAST_CACHE_ENTRY_SIZE);
sCacheMaxEntries = (S32)(llmin((S64)sCacheMaxEntries, max_entries));
header_size = sCacheMaxEntries * TEXTURE_CACHE_ENTRY_SIZE;
max_size -= header_size;
@@ -981,6 +1005,7 @@ S64 LLTextureCache::initCache(ELLPath location, S64 max_size, BOOL texture_cache
purgeTextures(true); // calc mTexturesSize and make some room in the texture cache if we need it
llassert_always(getPending() == 0) ; //should not start accessing the texture cache before initialized.
+ openFastCache(true);
return max_size; // unused cache space
}
@@ -1751,7 +1776,7 @@ LLTextureCache::handle_t LLTextureCache::readFromCache(const LLUUID& id, U32 pri
LLMutexLock lock(&mWorkersMutex);
LLTextureCacheWorker* worker = new LLTextureCacheRemoteWorker(this, priority, id,
NULL, size, offset,
- 0, responder);
+ 0, NULL, 0, responder);
handle_t handle = worker->read();
mReaders[handle] = worker;
return handle;
@@ -1789,6 +1814,7 @@ bool LLTextureCache::readComplete(handle_t handle, bool abort)
LLTextureCache::handle_t LLTextureCache::writeToCache(const LLUUID& id, U32 priority,
U8* data, S32 datasize, S32 imagesize,
+ LLPointer<LLImageRaw> rawimage, S32 discardlevel,
WriteResponder* responder)
{
if (mReadOnly)
@@ -1807,12 +1833,184 @@ LLTextureCache::handle_t LLTextureCache::writeToCache(const LLUUID& id, U32 prio
LLMutexLock lock(&mWorkersMutex);
LLTextureCacheWorker* worker = new LLTextureCacheRemoteWorker(this, priority, id,
data, datasize, 0,
- imagesize, responder);
+ imagesize, rawimage, discardlevel, responder);
handle_t handle = worker->write();
mWriters[handle] = worker;
return handle;
}
+//called in the main thread
+LLPointer<LLImageRaw> LLTextureCache::readFromFastCache(const LLUUID& id, S32& discardlevel)
+{
+ U32 offset;
+ {
+ LLMutexLock lock(&mHeaderMutex);
+ id_map_t::const_iterator iter = mHeaderIDMap.find(id);
+ if(iter == mHeaderIDMap.end())
+ {
+ return NULL; //not in the cache
+ }
+
+ offset = iter->second;
+ }
+ offset *= TEXTURE_FAST_CACHE_ENTRY_SIZE;
+
+ U8* data;
+ S32 head[4];
+ {
+ LLMutexLock lock(&mFastCacheMutex);
+
+ openFastCache();
+
+ mFastCachep->seek(APR_SET, offset);
+
+ if(mFastCachep->read(head, TEXTURE_FAST_CACHE_ENTRY_OVERHEAD) != TEXTURE_FAST_CACHE_ENTRY_OVERHEAD)
+ {
+ //cache corrupted or under thread race condition
+ closeFastCache();
+ return NULL;
+ }
+
+ S32 image_size = head[0] * head[1] * head[2];
+ if(!image_size) //invalid
+ {
+ closeFastCache();
+ return NULL;
+ }
+ discardlevel = head[3];
+
+ data = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), image_size);
+ if(mFastCachep->read(data, image_size) != image_size)
+ {
+ FREE_MEM(LLImageBase::getPrivatePool(), data);
+ closeFastCache();
+ return NULL;
+ }
+
+ closeFastCache();
+ }
+ LLPointer<LLImageRaw> raw = new LLImageRaw(data, head[0], head[1], head[2], true);
+
+ return raw;
+}
+
+//return the fast cache location
+bool LLTextureCache::writeToFastCache(S32 id, LLPointer<LLImageRaw> raw, S32 discardlevel)
+{
+ //rescale image if needed
+ if (raw.isNull() || !raw->getData())
+ {
+ llerrs << "Attempted to write NULL raw image to fastcache" << llendl;
+ return false;
+ }
+
+ S32 w, h, c;
+ w = raw->getWidth();
+ h = raw->getHeight();
+ c = raw->getComponents();
+
+ S32 i = 0 ;
+
+ while(((w >> i) * (h >> i) * c) > TEXTURE_FAST_CACHE_ENTRY_SIZE - TEXTURE_FAST_CACHE_ENTRY_OVERHEAD)
+ {
+ ++i ;
+ }
+
+ if(i)
+ {
+ w >>= i;
+ h >>= i;
+ if(w * h *c > 0) //valid
+ {
+ //make a duplicate to keep the original raw image untouched.
+ raw = raw->duplicate();
+ raw->scale(w, h) ;
+
+ discardlevel += i ;
+ }
+ }
+
+ //copy data
+ memcpy(mFastCachePadBuffer, &w, sizeof(S32));
+ memcpy(mFastCachePadBuffer + sizeof(S32), &h, sizeof(S32));
+ memcpy(mFastCachePadBuffer + sizeof(S32) * 2, &c, sizeof(S32));
+ memcpy(mFastCachePadBuffer + sizeof(S32) * 3, &discardlevel, sizeof(S32));
+
+ S32 copy_size = w * h * c;
+ if(copy_size > 0) //valid
+ {
+ copy_size = llmin(copy_size, TEXTURE_FAST_CACHE_ENTRY_SIZE - TEXTURE_FAST_CACHE_ENTRY_OVERHEAD);
+ memcpy(mFastCachePadBuffer + TEXTURE_FAST_CACHE_ENTRY_OVERHEAD, raw->getData(), copy_size);
+ }
+ S32 offset = id * TEXTURE_FAST_CACHE_ENTRY_SIZE;
+
+ {
+ LLMutexLock lock(&mFastCacheMutex);
+
+ openFastCache();
+
+ mFastCachep->seek(APR_SET, offset);
+
+ //no need to do this assertion check. When it fails, let it fail quietly.
+ //this failure could happen because other viewer removes the fast cache file when clearing cache.
+ //--> llassert_always(mFastCachep->write(mFastCachePadBuffer, TEXTURE_FAST_CACHE_ENTRY_SIZE) == TEXTURE_FAST_CACHE_ENTRY_SIZE);
+ mFastCachep->write(mFastCachePadBuffer, TEXTURE_FAST_CACHE_ENTRY_SIZE);
+
+ closeFastCache(true);
+ }
+
+ return true;
+}
+
+void LLTextureCache::openFastCache(bool first_time)
+{
+ if(!mFastCachep)
+ {
+ if(first_time)
+ {
+ if(!mFastCachePadBuffer)
+ {
+ mFastCachePadBuffer = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), TEXTURE_FAST_CACHE_ENTRY_SIZE);
+ }
+ mFastCachePoolp = new LLVolatileAPRPool();
+ if (LLAPRFile::isExist(mFastCacheFileName, mFastCachePoolp))
+ {
+ mFastCachep = new LLAPRFile(mFastCacheFileName, APR_READ|APR_WRITE|APR_BINARY, mFastCachePoolp) ;
+ }
+ else
+ {
+ mFastCachep = new LLAPRFile(mFastCacheFileName, APR_CREATE|APR_READ|APR_WRITE|APR_BINARY, mFastCachePoolp) ;
+ }
+ }
+ else
+ {
+ mFastCachep = new LLAPRFile(mFastCacheFileName, APR_READ|APR_WRITE|APR_BINARY, mFastCachePoolp) ;
+ }
+
+ mFastCacheTimer.reset();
+ }
+ return;
+}
+
+void LLTextureCache::closeFastCache(bool forced)
+{
+ static const F32 timeout = 10.f ; //seconds
+
+ if(!mFastCachep)
+ {
+ return ;
+ }
+
+ if(!forced && mFastCacheTimer.getElapsedTimeF32() < timeout)
+ {
+ return ;
+ }
+
+ delete mFastCachep;
+ mFastCachep = NULL;
+ return;
+}
+
bool LLTextureCache::writeComplete(handle_t handle, bool abort)
{
lockWorkers();
diff --git a/indra/newview/lltexturecache.h b/indra/newview/lltexturecache.h
index dd0cc9b4bd..deaacc4975 100644..100755
--- a/indra/newview/lltexturecache.h
+++ b/indra/newview/lltexturecache.h
@@ -24,7 +24,7 @@
* $/LicenseInfo$
*/
-#ifndef LL_LLTEXTURECACHE_
+#ifndef LL_LLTEXTURECACHE_H
#define LL_LLTEXTURECACHE_H
#include "lldir.h"
@@ -36,6 +36,7 @@
class LLImageFormatted;
class LLTextureCacheWorker;
+class LLImageRaw;
class LLTextureCache : public LLWorkerThread
{
@@ -113,8 +114,9 @@ public:
handle_t readFromCache(const LLUUID& id, U32 priority, S32 offset, S32 size,
ReadResponder* responder);
bool readComplete(handle_t handle, bool abort);
- handle_t writeToCache(const LLUUID& id, U32 priority, U8* data, S32 datasize, S32 imagesize,
+ handle_t writeToCache(const LLUUID& id, U32 priority, U8* data, S32 datasize, S32 imagesize, LLPointer<LLImageRaw> rawimage, S32 discardlevel,
WriteResponder* responder);
+ LLPointer<LLImageRaw> readFromFastCache(const LLUUID& id, S32& discardlevel);
bool writeComplete(handle_t handle, bool abort = false);
void prioritizeWrite(handle_t handle);
@@ -171,12 +173,18 @@ private:
void lockHeaders() { mHeaderMutex.lock(); }
void unlockHeaders() { mHeaderMutex.unlock(); }
+ void openFastCache(bool first_time = false);
+ void closeFastCache(bool forced = false);
+ bool writeToFastCache(S32 id, LLPointer<LLImageRaw> raw, S32 discardlevel);
+
private:
// Internal
LLMutex mWorkersMutex;
LLMutex mHeaderMutex;
LLMutex mListMutex;
+ LLMutex mFastCacheMutex;
LLAPRFile* mHeaderAPRFile;
+ LLVolatileAPRPool* mFastCachePoolp;
typedef std::map<handle_t, LLTextureCacheWorker*> handle_map_t;
handle_map_t mReaders;
@@ -193,12 +201,17 @@ private:
// HEADERS (Include first mip)
std::string mHeaderEntriesFileName;
std::string mHeaderDataFileName;
+ std::string mFastCacheFileName;
EntriesInfo mHeaderEntriesInfo;
std::set<S32> mFreeList; // deleted entries
std::set<LLUUID> mLRU;
- typedef std::map<LLUUID,S32> id_map_t;
+ typedef std::map<LLUUID, S32> id_map_t;
id_map_t mHeaderIDMap;
+ LLAPRFile* mFastCachep;
+ LLFrameTimer mFastCacheTimer;
+ U8* mFastCachePadBuffer;
+
// BODIES (TEXTURES minus headers)
std::string mTexturesDirName;
typedef std::map<LLUUID,S32> size_map_t;
diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp
index ed9faa0706..4300cafb6b 100644..100755
--- a/indra/newview/lltexturectrl.cpp
+++ b/indra/newview/lltexturectrl.cpp
@@ -39,7 +39,7 @@
#include "llfocusmgr.h"
#include "llviewertexture.h"
#include "llfolderview.h"
-#include "llfoldervieweventlistener.h"
+#include "llfolderviewmodel.h"
#include "llinventory.h"
#include "llinventoryfunctions.h"
#include "llinventorymodelbackgroundfetch.h"
@@ -58,6 +58,7 @@
#include "lltoolmgr.h"
#include "lltoolpipette.h"
#include "llfiltereditor.h"
+#include "llwindow.h"
#include "lltool.h"
#include "llviewerwindow.h"
@@ -97,6 +98,7 @@ public:
LLTextureCtrl* owner,
const std::string& label,
PermissionMask immediate_filter_perm_mask,
+ PermissionMask dnd_filter_perm_mask,
PermissionMask non_immediate_filter_perm_mask,
BOOL can_apply_immediately,
LLUIImagePtr fallback_image_name);
@@ -131,15 +133,19 @@ public:
PermissionMask getFilterPermMask();
void updateFilterPermMask();
void commitIfImmediateSet();
+ void commitCancel();
void onFilterEdit(const std::string& search_string );
+ void setCanApply(bool can_preview, bool can_apply);
+ void setTextureSelectedCallback(texture_selected_callback cb) {mTextureSelectedCallback = cb;}
+
static void onBtnSetToDefault( void* userdata );
static void onBtnSelect( void* userdata );
static void onBtnCancel( void* userdata );
void onBtnPipette( );
//static void onBtnRevert( void* userdata );
- static void onBtnWhite( void* userdata );
+ static void onBtnBlank( void* userdata );
static void onBtnNone( void* userdata );
static void onBtnClear( void* userdata );
void onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action);
@@ -160,7 +166,6 @@ protected:
LLUUID mImageAssetID; // Currently selected texture
LLUIImagePtr mFallbackImage; // What to show if currently selected texture is null.
- LLUUID mWhiteImageAssetID;
LLUUID mSpecialCurrentImageAssetID; // Used when the asset id has no corresponding texture in the user's inventory.
LLUUID mOriginalImageAssetID;
@@ -175,29 +180,35 @@ protected:
LLFilterEditor* mFilterEdit;
LLInventoryPanel* mInventoryPanel;
PermissionMask mImmediateFilterPermMask;
+ PermissionMask mDnDFilterPermMask;
PermissionMask mNonImmediateFilterPermMask;
BOOL mCanApplyImmediately;
BOOL mNoCopyTextureSelected;
F32 mContextConeOpacity;
LLSaveFolderState mSavedFolderState;
BOOL mSelectedItemPinned;
-
+
LLRadioGroup* mModeSelector;
LLScrollListCtrl* mLocalScrollCtrl;
+
+private:
+ bool mCanApply;
+ bool mCanPreview;
+ texture_selected_callback mTextureSelectedCallback;
};
LLFloaterTexturePicker::LLFloaterTexturePicker(
LLTextureCtrl* owner,
const std::string& label,
PermissionMask immediate_filter_perm_mask,
+ PermissionMask dnd_filter_perm_mask,
PermissionMask non_immediate_filter_perm_mask,
BOOL can_apply_immediately,
LLUIImagePtr fallback_image)
: LLFloater(LLSD()),
mOwner( owner ),
mImageAssetID( owner->getImageAssetID() ),
- mFallbackImage( fallback_image ),
- mWhiteImageAssetID( gSavedSettings.getString( "UIImgWhiteUUID" ) ),
+ mFallbackImage( fallback_image ),
mOriginalImageAssetID(owner->getImageAssetID()),
mLabel(label),
mTentativeLabel(NULL),
@@ -205,9 +216,12 @@ LLFloaterTexturePicker::LLFloaterTexturePicker(
mActive( TRUE ),
mFilterEdit(NULL),
mImmediateFilterPermMask(immediate_filter_perm_mask),
+ mDnDFilterPermMask(dnd_filter_perm_mask),
mNonImmediateFilterPermMask(non_immediate_filter_perm_mask),
mContextConeOpacity(0.f),
- mSelectedItemPinned( FALSE )
+ mSelectedItemPinned( FALSE ),
+ mCanApply(true),
+ mCanPreview(true)
{
buildFromFile("floater_texture_ctrl.xml");
mCanApplyImmediately = can_apply_immediately;
@@ -319,7 +333,7 @@ BOOL LLFloaterTexturePicker::handleDragAndDrop(
if (xfer) item_perm_mask |= PERM_TRANSFER;
//PermissionMask filter_perm_mask = getFilterPermMask(); Commented out due to no-copy texture loss.
- PermissionMask filter_perm_mask = mImmediateFilterPermMask;
+ PermissionMask filter_perm_mask = mDnDFilterPermMask;
if ( (item_perm_mask & filter_perm_mask) == filter_perm_mask )
{
if (drop)
@@ -358,7 +372,7 @@ BOOL LLFloaterTexturePicker::handleKeyHere(KEY key, MASK mask)
{
if (!root_folder->getCurSelectedItem())
{
- LLFolderViewItem* itemp = root_folder->getItemByID(gInventory.getRootFolderID());
+ LLFolderViewItem* itemp = mInventoryPanel->getItemByID(gInventory.getRootFolderID());
if (itemp)
{
root_folder->setSelection(itemp, FALSE, FALSE);
@@ -411,7 +425,7 @@ BOOL LLFloaterTexturePicker::postBuild()
childSetAction("Default",LLFloaterTexturePicker::onBtnSetToDefault,this);
childSetAction("None", LLFloaterTexturePicker::onBtnNone,this);
- childSetAction("Blank", LLFloaterTexturePicker::onBtnWhite,this);
+ childSetAction("Blank", LLFloaterTexturePicker::onBtnBlank,this);
childSetCommitCallback("show_folders_check", onShowFolders, this);
@@ -440,7 +454,7 @@ BOOL LLFloaterTexturePicker::postBuild()
// Commented out to scroll to currently selected texture. See EXT-5403.
// // store this filter as the default one
- // mInventoryPanel->getRootFolder()->getFilter()->markDefault();
+ // mInventoryPanel->getRootFolder()->getFilter().markDefault();
// Commented out to stop opening all folders with textures
// mInventoryPanel->openDefaultFolderForType(LLFolderType::FT_TEXTURE);
@@ -464,7 +478,7 @@ BOOL LLFloaterTexturePicker::postBuild()
mNoCopyTextureSelected = FALSE;
- getChild<LLUICtrl>("apply_immediate_check")->setValue(gSavedSettings.getBOOL("ApplyTextureImmediately"));
+ getChild<LLUICtrl>("apply_immediate_check")->setValue(gSavedSettings.getBOOL("TextureLivePreview"));
childSetCommitCallback("apply_immediate_check", onApplyImmediateCheck, this);
if (!mCanApplyImmediately)
@@ -546,7 +560,7 @@ void LLFloaterTexturePicker::draw()
// if we're inactive, gray out "apply immediate" checkbox
getChildView("show_folders_check")->setEnabled(mActive && mCanApplyImmediately && !mNoCopyTextureSelected);
- getChildView("Select")->setEnabled(mActive);
+ getChildView("Select")->setEnabled(mActive && mCanApply);
getChildView("Pipette")->setEnabled(mActive);
getChild<LLUICtrl>("Pipette")->setValue(LLToolMgr::getInstance()->getCurrentTool() == LLToolPipette::getInstance());
@@ -556,8 +570,8 @@ void LLFloaterTexturePicker::draw()
mTexturep = NULL;
if(mImageAssetID.notNull())
{
- mTexturep = LLViewerTextureManager::getFetchedTexture(mImageAssetID, MIPMAP_YES);
- mTexturep->setBoostLevel(LLViewerTexture::BOOST_PREVIEW);
+ mTexturep = LLViewerTextureManager::getFetchedTexture(mImageAssetID);
+ mTexturep->setBoostLevel(LLGLTexture::BOOST_PREVIEW);
}
if (mTentativeLabel)
@@ -566,7 +580,7 @@ void LLFloaterTexturePicker::draw()
}
getChildView("Default")->setEnabled(mImageAssetID != mOwner->getDefaultImageAssetID());
- getChildView("Blank")->setEnabled(mImageAssetID != mWhiteImageAssetID );
+ getChildView("Blank")->setEnabled(mImageAssetID != mOwner->getBlankImageAssetID());
getChildView("None")->setEnabled(mOwner->getAllowNoTexture() && !mImageAssetID.isNull() );
LLFloater::draw();
@@ -623,11 +637,10 @@ void LLFloaterTexturePicker::draw()
LLFolderView* folder_view = mInventoryPanel->getRootFolder();
if (!folder_view) return;
- LLInventoryFilter* filter = folder_view->getFilter();
- if (!filter) return;
+ LLFolderViewFilter& filter = static_cast<LLFolderViewModelInventory*>(folder_view->getFolderViewModel())->getFilter();
- bool is_filter_active = folder_view->getCompletedFilterGeneration() < filter->getCurrentGeneration() &&
- filter->isNotDefault();
+ bool is_filter_active = folder_view->getViewModelItem()->getLastFilterGeneration() < filter.getCurrentGeneration() &&
+ filter.isNotDefault();
// After inventory panel filter is applied we have to update
// constraint rect for the selected item because of folder view
@@ -637,26 +650,12 @@ void LLFloaterTexturePicker::draw()
if (!is_filter_active && !mSelectedItemPinned)
{
folder_view->setPinningSelectedItem(mSelectedItemPinned);
- folder_view->dirtyFilter();
- folder_view->arrangeFromRoot();
-
+ folder_view->getViewModelItem()->dirtyFilter();
mSelectedItemPinned = TRUE;
}
}
}
-// static
-/*
-void LLFloaterTexturePicker::onSaveAnotherCopyDialog( S32 option, void* userdata )
-{
- LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata;
- if( 0 == option )
- {
- self->copyToInventoryFinal();
- }
-}
-*/
-
const LLUUID& LLFloaterTexturePicker::findItemID(const LLUUID& asset_id, BOOL copyable_only)
{
LLViewerInventoryCategory::cat_array_t cats;
@@ -702,17 +701,25 @@ PermissionMask LLFloaterTexturePicker::getFilterPermMask()
void LLFloaterTexturePicker::commitIfImmediateSet()
{
- bool apply_immediate = getChild<LLUICtrl>("apply_immediate_check")->getValue().asBoolean();
- if (!mNoCopyTextureSelected && apply_immediate && mOwner)
+ if (!mNoCopyTextureSelected && mOwner && mCanApply)
{
mOwner->onFloaterCommit(LLTextureCtrl::TEXTURE_CHANGE);
}
}
+void LLFloaterTexturePicker::commitCancel()
+{
+ if (!mNoCopyTextureSelected && mOwner && mCanApply)
+ {
+ mOwner->onFloaterCommit(LLTextureCtrl::TEXTURE_CANCEL);
+ }
+}
+
// static
void LLFloaterTexturePicker::onBtnSetToDefault(void* userdata)
{
LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata;
+ self->setCanApply(true, true);
if (self->mOwner)
{
self->setImageID( self->mOwner->getDefaultImageAssetID() );
@@ -721,10 +728,11 @@ void LLFloaterTexturePicker::onBtnSetToDefault(void* userdata)
}
// static
-void LLFloaterTexturePicker::onBtnWhite(void* userdata)
+void LLFloaterTexturePicker::onBtnBlank(void* userdata)
{
LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata;
- self->setImageID( self->mWhiteImageAssetID );
+ self->setCanApply(true, true);
+ self->setImageID( self->mOwner->getBlankImageAssetID() );
self->commitIfImmediateSet();
}
@@ -734,7 +742,7 @@ void LLFloaterTexturePicker::onBtnNone(void* userdata)
{
LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata;
self->setImageID( LLUUID::null );
- self->commitIfImmediateSet();
+ self->commitCancel();
}
/*
@@ -800,17 +808,21 @@ void LLFloaterTexturePicker::onSelectionChange(const std::deque<LLFolderViewItem
if (items.size())
{
LLFolderViewItem* first_item = items.front();
- LLInventoryItem* itemp = gInventory.getItem(first_item->getListener()->getUUID());
+ LLInventoryItem* itemp = gInventory.getItem(static_cast<LLFolderViewModelItemInventory*>(first_item->getViewModelItem())->getUUID());
mNoCopyTextureSelected = FALSE;
if (itemp)
{
+ if (!mTextureSelectedCallback.empty())
+ {
+ mTextureSelectedCallback(itemp);
+ }
if (!itemp->getPermissions().allowCopyBy(gAgent.getID()))
{
mNoCopyTextureSelected = TRUE;
}
mImageAssetID = itemp->getAssetUUID();
mViewModel->setDirty(); // *TODO: shouldn't we be using setValue() here?
- if (user_action)
+ if (user_action && mCanPreview)
{
// only commit intentional selections, not implicit ones
commitIfImmediateSet();
@@ -947,7 +959,7 @@ void LLFloaterTexturePicker::onApplyImmediateCheck(LLUICtrl* ctrl, void *user_da
LLFloaterTexturePicker* picker = (LLFloaterTexturePicker*)user_data;
LLCheckBoxCtrl* check_box = (LLCheckBoxCtrl*)ctrl;
- gSavedSettings.setBOOL("ApplyTextureImmediately", check_box->get());
+ gSavedSettings.setBOOL("TextureLivePreview", check_box->get());
picker->updateFilterPermMask();
picker->commitIfImmediateSet();
@@ -958,6 +970,16 @@ void LLFloaterTexturePicker::updateFilterPermMask()
//mInventoryPanel->setFilterPermMask( getFilterPermMask() ); Commented out due to no-copy texture loss.
}
+void LLFloaterTexturePicker::setCanApply(bool can_preview, bool can_apply)
+{
+ getChildRef<LLUICtrl>("Select").setEnabled(can_apply);
+ getChildRef<LLUICtrl>("preview_disabled").setVisible(!can_preview);
+ getChildRef<LLUICtrl>("apply_immediate_check").setVisible(can_preview);
+
+ mCanApply = can_apply;
+ mCanPreview = can_preview ? gSavedSettings.getBOOL("TextureLivePreview") : false;
+}
+
void LLFloaterTexturePicker::onFilterEdit(const std::string& search_string )
{
std::string upper_case_search_string = search_string;
@@ -982,7 +1004,7 @@ void LLFloaterTexturePicker::onFilterEdit(const std::string& search_string )
else if (mInventoryPanel->getFilterSubString().empty())
{
// first letter in search term, save existing folder open state
- if (!mInventoryPanel->getRootFolder()->isFilterModified())
+ if (!mInventoryPanel->getFilter().isNotDefault())
{
mSavedFolderState.setApply(FALSE);
mInventoryPanel->getRootFolder()->applyFunctorRecursively(mSavedFolderState);
@@ -1027,6 +1049,7 @@ LLTextureCtrl::LLTextureCtrl(const LLTextureCtrl::Params& p)
mDragCallback(NULL),
mDropCallback(NULL),
mOnCancelCallback(NULL),
+ mOnCloseCallback(NULL),
mOnSelectCallback(NULL),
mBorderColor( p.border_color() ),
mAllowNoTexture( FALSE ),
@@ -1041,6 +1064,12 @@ LLTextureCtrl::LLTextureCtrl(const LLTextureCtrl::Params& p)
mDefaultImageName(p.default_image_name),
mFallbackImage(p.fallback_image)
{
+
+ // Default of defaults is white image for diff tex
+ //
+ LLUUID whiteImage( gSavedSettings.getString( "UIImgWhiteUUID" ) );
+ setBlankImageAssetID( whiteImage );
+
setAllowNoTexture(p.allow_no_texture);
setCanApplyImmediately(p.can_apply_immediately);
mCommitOnSelection = !p.no_commit_on_selection;
@@ -1108,6 +1137,15 @@ void LLTextureCtrl::setCanApplyImmediately(BOOL b)
}
}
+void LLTextureCtrl::setCanApply(bool can_preview, bool can_apply)
+{
+ LLFloaterTexturePicker* floaterp = dynamic_cast<LLFloaterTexturePicker*>(mFloaterHandle.get());
+ if( floaterp )
+ {
+ floaterp->setCanApply(can_preview, can_apply);
+ }
+}
+
void LLTextureCtrl::setVisible( BOOL visible )
{
if( !visible )
@@ -1188,12 +1226,19 @@ void LLTextureCtrl::showPicker(BOOL take_focus)
this,
mLabel,
mImmediateFilterPermMask,
+ mDnDFilterPermMask,
mNonImmediateFilterPermMask,
mCanApplyImmediately,
mFallbackImage);
mFloaterHandle = floaterp->getHandle();
+ LLFloaterTexturePicker* texture_floaterp = dynamic_cast<LLFloaterTexturePicker*>(floaterp);
+ if (texture_floaterp && mOnTextureSelectedCallback)
+ {
+ texture_floaterp->setTextureSelectedCallback(mOnTextureSelectedCallback);
+ }
+
LLFloater* root_floater = gFloaterView->getParentFloater(this);
if (root_floater)
root_floater->addDependentFloater(floaterp);
@@ -1261,6 +1306,10 @@ void LLTextureCtrl::onFloaterClose()
if (floaterp)
{
+ if (mOnCloseCallback)
+ {
+ mOnCloseCallback(this,LLSD());
+ }
floaterp->setOwner(NULL);
}
@@ -1280,7 +1329,7 @@ void LLTextureCtrl::onFloaterCommit(ETexturePickOp op, LLUUID id)
// (i.e. op == TEXTURE_SELECT) or texture changes via DnD.
else if (mCommitOnSelection || op == TEXTURE_SELECT)
mViewModel->setDirty(); // *TODO: shouldn't we be using setValue() here?
-
+
if(floaterp->isDirty() || id.notNull()) // mModelView->setDirty does not work.
{
setTentative( FALSE );
@@ -1292,10 +1341,10 @@ void LLTextureCtrl::onFloaterCommit(ETexturePickOp op, LLUUID id)
}
else
{
- mImageItemID = floaterp->findItemID(floaterp->getAssetID(), FALSE);
- lldebugs << "mImageItemID: " << mImageItemID << llendl;
- mImageAssetID = floaterp->getAssetID();
- lldebugs << "mImageAssetID: " << mImageAssetID << llendl;
+ mImageItemID = floaterp->findItemID(floaterp->getAssetID(), FALSE);
+ lldebugs << "mImageItemID: " << mImageItemID << llendl;
+ mImageAssetID = floaterp->getAssetID();
+ lldebugs << "mImageAssetID: " << mImageAssetID << llendl;
}
if (op == TEXTURE_SELECT && mOnSelectCallback)
@@ -1318,6 +1367,16 @@ void LLTextureCtrl::onFloaterCommit(ETexturePickOp op, LLUUID id)
}
}
+void LLTextureCtrl::setOnTextureSelectedCallback(texture_selected_callback cb)
+{
+ mOnTextureSelectedCallback = cb;
+ LLFloaterTexturePicker* floaterp = dynamic_cast<LLFloaterTexturePicker*>(mFloaterHandle.get());
+ if (floaterp)
+ {
+ floaterp->setTextureSelectedCallback(cb);
+ }
+}
+
void LLTextureCtrl::setImageAssetName(const std::string& name)
{
LLPointer<LLUIImage> imagep = LLUI::getUIImage(name);
@@ -1401,9 +1460,9 @@ void LLTextureCtrl::draw()
}
else if (!mImageAssetID.isNull())
{
- LLPointer<LLViewerFetchedTexture> texture = LLViewerTextureManager::getFetchedTexture(mImageAssetID, MIPMAP_YES,LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
+ LLPointer<LLViewerFetchedTexture> texture = LLViewerTextureManager::getFetchedTexture(mImageAssetID, FTT_DEFAULT, MIPMAP_YES,LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
- texture->setBoostLevel(LLViewerTexture::BOOST_PREVIEW);
+ texture->setBoostLevel(LLGLTexture::BOOST_PREVIEW);
texture->forceToSaveRawImage(0) ;
mTexturep = texture;
diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h
index 3abe84dcc3..ad79042ef1 100644..100755
--- a/indra/newview/lltexturectrl.h
+++ b/indra/newview/lltexturectrl.h
@@ -43,6 +43,7 @@ class LLViewerFetchedTexture;
// used for setting drag & drop callbacks.
typedef boost::function<BOOL (LLUICtrl*, LLInventoryItem*)> drag_n_drop_callback;
+typedef boost::function<void (LLInventoryItem*)> texture_selected_callback;
//////////////////////////////////////////////////////////////////////////////////////////
@@ -125,6 +126,7 @@ public:
// LLTextureCtrl interface
void showPicker(BOOL take_focus);
+ bool isPickerShown() { return !mFloaterHandle.isDead(); }
void setLabel(const std::string& label);
void setLabelWidth(S32 label_width) {mLabelWidth =label_width;}
const std::string& getLabel() const { return mLabel; }
@@ -144,11 +146,18 @@ public:
const std::string& getDefaultImageName() const { return mDefaultImageName; }
+ void setBlankImageAssetID( const LLUUID& id ) { mBlankImageAssetID = id; }
+ const LLUUID& getBlankImageAssetID() const { return mBlankImageAssetID; }
+
void setCaption(const std::string& caption);
void setCanApplyImmediately(BOOL b);
+ void setCanApply(bool can_preview, bool can_apply);
+
void setImmediateFilterPermMask(PermissionMask mask)
{ mImmediateFilterPermMask = mask; }
+ void setDnDFilterPermMask(PermissionMask mask)
+ { mDnDFilterPermMask = mask; }
void setNonImmediateFilterPermMask(PermissionMask mask)
{ mNonImmediateFilterPermMask = mask; }
PermissionMask getImmediateFilterPermMask() { return mImmediateFilterPermMask; }
@@ -169,9 +178,14 @@ public:
void setDropCallback(drag_n_drop_callback cb) { mDropCallback = cb; }
void setOnCancelCallback(commit_callback_t cb) { mOnCancelCallback = cb; }
-
+ void setOnCloseCallback(commit_callback_t cb) { mOnCloseCallback = cb; }
void setOnSelectCallback(commit_callback_t cb) { mOnSelectCallback = cb; }
+ /*
+ * callback for changing texture selection in inventory list of texture floater
+ */
+ void setOnTextureSelectedCallback(texture_selected_callback cb);
+
void setShowLoadingPlaceholder(BOOL showLoadingPlaceholder);
LLViewerFetchedTexture* getTexture() { return mTexturep; }
@@ -185,11 +199,14 @@ private:
drag_n_drop_callback mDropCallback;
commit_callback_t mOnCancelCallback;
commit_callback_t mOnSelectCallback;
+ commit_callback_t mOnCloseCallback;
+ texture_selected_callback mOnTextureSelectedCallback;
LLPointer<LLViewerFetchedTexture> mTexturep;
LLUIColor mBorderColor;
LLUUID mImageItemID;
LLUUID mImageAssetID;
LLUUID mDefaultImageAssetID;
+ LLUUID mBlankImageAssetID;
LLUIImagePtr mFallbackImage;
std::string mDefaultImageName;
LLHandle<LLFloater> mFloaterHandle;
@@ -198,6 +215,7 @@ private:
std::string mLabel;
BOOL mAllowNoTexture; // If true, the user can select "none" as an option
PermissionMask mImmediateFilterPermMask;
+ PermissionMask mDnDFilterPermMask;
PermissionMask mNonImmediateFilterPermMask;
BOOL mCanApplyImmediately;
BOOL mCommitOnSelection;
diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp
index f18aa8b4e6..def26b3885 100644
--- a/indra/newview/lltexturefetch.cpp
+++ b/indra/newview/lltexturefetch.cpp
@@ -4,7 +4,7 @@
*
* $LicenseInfo:firstyear=2000&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
+ * Copyright (C) 2012, 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
@@ -28,12 +28,12 @@
#include <iostream>
#include <map>
+#include <algorithm>
#include "llstl.h"
#include "lltexturefetch.h"
-#include "llcurl.h"
#include "lldir.h"
#include "llhttpclient.h"
#include "llhttpstatuscodes.h"
@@ -50,24 +50,219 @@
#include "llviewertexture.h"
#include "llviewerregion.h"
#include "llviewerstats.h"
+#include "llviewerstatsrecorder.h"
#include "llviewerassetstats.h"
#include "llworld.h"
+#include "llsdutil.h"
+#include "llstartup.h"
+#include "llsdserialize.h"
+
+#include "httprequest.h"
+#include "httphandler.h"
+#include "httpresponse.h"
+#include "bufferarray.h"
+#include "bufferstream.h"
+
+bool LLTextureFetchDebugger::sDebuggerEnabled = false ;
+LLStat LLTextureFetch::sCacheHitRate("texture_cache_hits", 128);
+LLStat LLTextureFetch::sCacheReadLatency("texture_cache_read_latency", 128);
+
//////////////////////////////////////////////////////////////////////////////
-class LLTextureFetchWorker : public LLWorkerClass
+//
+// Introduction
+//
+// This is an attempt to document what's going on in here after-the-fact.
+// It's a sincere attempt to be accurate but there will be mistakes.
+//
+//
+// Purpose
+//
+// What is this module trying to do? It accepts requests to load textures
+// at a given priority and discard level and notifies the caller when done
+// (successfully or not). Additional constraints are:
+//
+// * Support a local texture cache. Don't hit network when possible
+// to avoid it.
+// * Use UDP or HTTP as directed or as fallback. HTTP is tried when
+// not disabled and a URL is available. UDP when a URL isn't
+// available or HTTP attempts fail.
+// * Asynchronous (using threads). Main thread is not to be blocked or
+// burdened.
+// * High concurrency. Many requests need to be in-flight and at various
+// stages of completion.
+// * Tolerate frequent re-prioritizations of requests. Priority is
+// a reflection of a camera's viewpoint and as that viewpoint changes,
+// objects and textures become more and less relevant and that is
+// expressed at this level by priority changes and request cancelations.
+//
+// The caller interfaces that fall out of the above and shape the
+// implementation are:
+// * createRequest - Load j2c image via UDP or HTTP at given discard level and priority
+// * deleteRequest - Request removal of prior request
+// * getRequestFinished - Test if request is finished returning data to caller
+// * updateRequestPriority - Change priority of existing request
+// * getFetchState - Retrieve progress on existing request
+//
+// Everything else in here is mostly plumbing, metrics and debug.
+//
+//
+// The Work Queue
+//
+// The two central classes are LLTextureFetch and LLTextureFetchWorker.
+// LLTextureFetch combines threading with a priority queue of work
+// requests. The priority queue is sorted by a U32 priority derived
+// from the F32 priority in the APIs. The *only* work request that
+// receives service time by this thread is the highest priority
+// request. All others wait until it is complete or a dynamic priority
+// change has re-ordered work.
+//
+// LLTextureFetchWorker implements the work request and is 1:1 with
+// texture fetch requests. Embedded in each is a state machine that
+// walks it through the cache, HTTP, UDP, image decode and retry
+// steps of texture acquisition.
+//
+//
+// Threads
+//
+// Several threads are actively invoking code in this module. They
+// include:
+//
+// 1. Tmain Main thread of execution
+// 2. Ttf LLTextureFetch's worker thread provided by LLQueuedThread
+// 3. Tcurl LLCurl's worker thread (should disappear over time)
+// 4. Ttc LLTextureCache's worker thread
+// 5. Tid Image decoder's worker thread
+// 6. Thl HTTP library's worker thread
+//
+//
+// Mutexes/Condition Variables
+//
+// 1. Mt Mutex defined for LLThread's condition variable (base class of
+// LLTextureFetch)
+// 2. Ct Condition variable for LLThread and used by lock/unlockData().
+// 3. Mwtd Special LLWorkerThread mutex used for request deletion
+// operations (base class of LLTextureFetch)
+// 4. Mfq LLTextureFetch's mutex covering request and command queue
+// data.
+// 5. Mfnq LLTextureFetch's mutex covering udp and http request
+// queue data.
+// 6. Mwc Mutex covering LLWorkerClass's members (base class of
+// LLTextureFetchWorker). One per request.
+// 7. Mw LLTextureFetchWorker's mutex. One per request.
+//
+//
+// Lock Ordering Rules
+//
+// Not an exhaustive list but shows the order of lock acquisition
+// needed to prevent deadlocks. 'A < B' means acquire 'A' before
+// acquiring 'B'.
+//
+// 1. Mw < Mfnq
+// (there are many more...)
+//
+//
+// Method and Member Definitions
+//
+// With the above, we'll try to document what threads can call what
+// methods (using T* for any), what locks must be held on entry and
+// are taken out during execution and what data is covered by which
+// lock (if any). This latter category will be especially prone to
+// error so be skeptical.
+//
+// A line like: "// Locks: M<xxx>" indicates a method that must
+// be invoked by a caller holding the 'M<xxx>' lock. Similarly,
+// "// Threads: T<xxx>" means that a caller should be running in
+// the indicated thread.
+//
+// For data members, a trailing comment like "// M<xxx>" means that
+// the data member is covered by the specified lock. Absence of a
+// comment can mean the member is unlocked or that I didn't bother
+// to do the archaeology. In the case of LLTextureFetchWorker,
+// most data members added by the leaf class are actually covered
+// by the Mw lock. You may also see "// T<xxx>" which means that
+// the member's usage is restricted to one thread (except for
+// perhaps construction and destruction) and so explicit locking
+// isn't used.
+//
+// In code, a trailing comment like "// [-+]M<xxx>" indicates a
+// lock acquision or release point.
+//
+//
+// Worker Lifecycle
+//
+// The threading and responder model makes it very likely that
+// other components are holding on to a pointer to a worker request.
+// So, uncoordinated deletions of requests is a guarantee of memory
+// corruption in a short time. So destroying a request involves
+// invocations's of LLQueuedThread/LLWorkerThread's abort/stop
+// logic that removes workers and puts them ona delete queue for
+// 2-phase destruction. That second phase is deferrable by calls
+// to deleteOK() which only allow final destruction (via dtor)
+// once deleteOK has determined that the request is in a safe
+// state.
+//
+//
+// Worker State Machine
+//
+// (ASCII art needed)
+//
+//
+// Priority Scheme
+//
+// [PRIORITY_LOW, PRIORITY_NORMAL) - for WAIT_HTTP_RESOURCE state
+// and other wait states
+// [PRIORITY_HIGH, PRIORITY_URGENT) - External event delivered,
+// rapidly transitioning through states,
+// no waiting allowed
+//
+// By itself, the above work queue model would fail the concurrency
+// and liveness requirements of the interface. A high priority
+// request could find itself on the head and stalled for external
+// reasons (see VWR-28996). So a few additional constraints are
+// required to keep things running:
+// * Anything that can make forward progress must be kept at a
+// higher priority than anything that can't.
+// * On completion of external events, the associated request
+// needs to be elevated beyond the normal range to handle
+// any data delivery and release any external resource.
+//
+// This effort is made to keep higher-priority entities moving
+// forward in their state machines at every possible step of
+// processing. It's not entirely proven that this produces the
+// experiencial benefits promised.
+//
+
+
+//////////////////////////////////////////////////////////////////////////////
+
+// Tuning/Parameterization Constants
+
+static const S32 HTTP_REQUESTS_IN_QUEUE_HIGH_WATER = 40; // Maximum requests to have active in HTTP
+static const S32 HTTP_REQUESTS_IN_QUEUE_LOW_WATER = 20; // Active level at which to refill
+
+
+//////////////////////////////////////////////////////////////////////////////
+
+class LLTextureFetchWorker : public LLWorkerClass, public LLCore::HttpHandler
+
{
friend class LLTextureFetch;
- friend class HTTPGetResponder;
+ friend class LLTextureFetchDebugger;
private:
class CacheReadResponder : public LLTextureCache::ReadResponder
{
public:
+
+ // Threads: Ttf
CacheReadResponder(LLTextureFetch* fetcher, const LLUUID& id, LLImageFormatted* image)
: mFetcher(fetcher), mID(id)
{
setImage(image);
}
+
+ // Threads: Ttc
virtual void completed(bool success)
{
LLTextureFetchWorker* worker = mFetcher->getWorker(mID);
@@ -84,10 +279,14 @@ private:
class CacheWriteResponder : public LLTextureCache::WriteResponder
{
public:
+
+ // Threads: Ttf
CacheWriteResponder(LLTextureFetch* fetcher, const LLUUID& id)
: mFetcher(fetcher), mID(id)
{
}
+
+ // Threads: Ttc
virtual void completed(bool success)
{
LLTextureFetchWorker* worker = mFetcher->getWorker(mID);
@@ -104,10 +303,14 @@ private:
class DecodeResponder : public LLImageDecodeThread::Responder
{
public:
+
+ // Threads: Ttf
DecodeResponder(LLTextureFetch* fetcher, const LLUUID& id, LLTextureFetchWorker* worker)
: mFetcher(fetcher), mID(id), mWorker(worker)
{
}
+
+ // Threads: Tid
virtual void completed(bool success, LLImageRaw* raw, LLImageRaw* aux)
{
LLTextureFetchWorker* worker = mFetcher->getWorker(mID);
@@ -140,22 +343,35 @@ private:
};
public:
+
+ // Threads: Ttf
/*virtual*/ bool doWork(S32 param); // Called from LLWorkerThread::processRequest()
+
+ // Threads: Ttf
/*virtual*/ void finishWork(S32 param, bool completed); // called from finishRequest() (WORK THREAD)
- /*virtual*/ bool deleteOK(); // called from update() (WORK THREAD)
+
+ // Threads: Tmain
+ /*virtual*/ bool deleteOK(); // called from update()
~LLTextureFetchWorker();
- // void relese() { --mActiveCount; }
- S32 callbackHttpGet(const LLChannelDescriptors& channels,
- const LLIOPipe::buffer_ptr_t& buffer,
- bool partial, bool success);
+ // Threads: Ttf
+ // Locks: Mw
+ S32 callbackHttpGet(LLCore::HttpResponse * response,
+ bool partial, bool success);
+
+ // Threads: Ttc
void callbackCacheRead(bool success, LLImageFormatted* image,
S32 imagesize, BOOL islocal);
+
+ // Threads: Ttc
void callbackCacheWrite(bool success);
+
+ // Threads: Tid
void callbackDecoded(bool success, LLImageRaw* raw, LLImageRaw* aux);
- void setGetStatus(U32 status, const std::string& reason)
+ // Threads: T*
+ void setGetStatus(LLCore::HttpStatus status, const std::string& reason)
{
LLMutexLock lock(&mWorkMutex);
@@ -167,33 +383,94 @@ public:
bool getCanUseHTTP() const { return mCanUseHTTP; }
LLTextureFetch & getFetcher() { return *mFetcher; }
+
+ // Inherited from LLCore::HttpHandler
+ // Threads: Ttf
+ virtual void onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response);
protected:
- LLTextureFetchWorker(LLTextureFetch* fetcher, const std::string& url, const LLUUID& id, const LLHost& host,
+ LLTextureFetchWorker(LLTextureFetch* fetcher, FTType f_type,
+ const std::string& url, const LLUUID& id, const LLHost& host,
F32 priority, S32 discard, S32 size);
private:
+
+ // Threads: Tmain
/*virtual*/ void startWork(S32 param); // called from addWork() (MAIN THREAD)
+
+ // Threads: Tmain
/*virtual*/ void endWork(S32 param, bool aborted); // called from doWork() (MAIN THREAD)
+ // Locks: Mw
void resetFormattedData();
+ // Locks: Mw
void setImagePriority(F32 priority);
+
+ // Locks: Mw (ctor invokes without lock)
void setDesiredDiscard(S32 discard, S32 size);
+
+ // Threads: T*
+ // Locks: Mw
bool insertPacket(S32 index, U8* data, S32 size);
+
+ // Locks: Mw
void clearPackets();
+
+ // Locks: Mw
void setupPacketData();
+
+ // Locks: Mw (ctor invokes without lock)
U32 calcWorkPriority();
+
+ // Locks: Mw
void removeFromCache();
+
+ // Threads: Ttf
+ // Locks: Mw
bool processSimulatorPackets();
+
+ // Threads: Ttf
bool writeToCacheComplete();
+ // Threads: Ttf
+ void recordTextureStart(bool is_http);
+
+ // Threads: Ttf
+ void recordTextureDone(bool is_http);
+
void lockWorkMutex() { mWorkMutex.lock(); }
void unlockWorkMutex() { mWorkMutex.unlock(); }
+ // Threads: Ttf
+ // Locks: Mw
+ bool acquireHttpSemaphore()
+ {
+ llassert(! mHttpHasResource);
+ if (mFetcher->mHttpSemaphore <= 0)
+ {
+ return false;
+ }
+ mHttpHasResource = true;
+ mFetcher->mHttpSemaphore--;
+ return true;
+ }
+
+ // Threads: Ttf
+ // Locks: Mw
+ void releaseHttpSemaphore()
+ {
+ llassert(mHttpHasResource);
+ mHttpHasResource = false;
+ mFetcher->mHttpSemaphore++;
+ }
+
private:
enum e_state // mState
{
+ // *NOTE: Do not change the order/value of state variables, some code
+ // depends upon specific ordering/adjacency.
+
// NOTE: Affects LLTextureBar::draw in lltextureview.cpp (debug hack)
INVALID = 0,
INIT,
@@ -201,8 +478,10 @@ private:
CACHE_POST,
LOAD_FROM_NETWORK,
LOAD_FROM_SIMULATOR,
- SEND_HTTP_REQ,
- WAIT_HTTP_REQ,
+ WAIT_HTTP_RESOURCE, // Waiting for HTTP resources
+ WAIT_HTTP_RESOURCE2, // Waiting for HTTP resources
+ SEND_HTTP_REQ, // Commit to sending as HTTP
+ WAIT_HTTP_REQ, // Request sent, wait for completion
DECODE_IMAGE,
DECODE_IMAGE_UPDATE,
WRITE_TO_CACHE,
@@ -223,11 +502,13 @@ private:
};
static const char* sStateDescs[];
e_state mState;
+ void setState(e_state new_state);
e_write_to_cache_state mWriteToCacheState;
LLTextureFetch* mFetcher;
LLPointer<LLImageFormatted> mFormattedImage;
LLPointer<LLImageRaw> mRawImage;
LLPointer<LLImageRaw> mAuxImage;
+ FTType mFTType;
LLUUID mID;
LLHost mHost;
std::string mUrl;
@@ -242,11 +523,12 @@ private:
S32 mDecodedDiscard;
LLFrameTimer mRequestedTimer;
LLFrameTimer mFetchTimer;
+ LLTimer mCacheReadTimer;
+ F32 mCacheReadTime;
LLTextureCache::handle_t mCacheReadHandle;
LLTextureCache::handle_t mCacheWriteHandle;
- U8* mBuffer;
- S32 mBufferSize;
S32 mRequestedSize;
+ S32 mRequestedOffset;
S32 mDesiredSize;
S32 mFileSize;
S32 mCachedSize;
@@ -258,12 +540,12 @@ private:
BOOL mNeedsAux;
BOOL mHaveAllData;
BOOL mInLocalCache;
+ BOOL mInCache;
bool mCanUseHTTP ;
bool mCanUseNET ; //can get from asset server.
- S32 mHTTPFailCount;
S32 mRetryAttempt;
S32 mActiveCount;
- U32 mGetStatus;
+ LLCore::HttpStatus mGetStatus;
std::string mGetReason;
// Work Data
@@ -283,105 +565,19 @@ private:
U8 mImageCodec;
LLViewerAssetStats::duration_t mMetricsStartTime;
-};
-
-//////////////////////////////////////////////////////////////////////////////
-class HTTPGetResponder : public LLCurl::Responder
-{
- LOG_CLASS(HTTPGetResponder);
-public:
- HTTPGetResponder(LLTextureFetch* fetcher, const LLUUID& id, U64 startTime, S32 requestedSize, U32 offset, bool redir)
- : mFetcher(fetcher), mID(id), mStartTime(startTime), mRequestedSize(requestedSize), mOffset(offset), mFollowRedir(redir)
- {
- }
- ~HTTPGetResponder()
- {
- }
-
- virtual void completedRaw(U32 status, const std::string& reason,
- const LLChannelDescriptors& channels,
- const LLIOPipe::buffer_ptr_t& buffer)
- {
- static LLCachedControl<bool> log_to_viewer_log(gSavedSettings,"LogTextureDownloadsToViewerLog");
- static LLCachedControl<bool> log_to_sim(gSavedSettings,"LogTextureDownloadsToSimulator");
- static LLCachedControl<bool> log_texture_traffic(gSavedSettings,"LogTextureNetworkTraffic") ;
-
- if (log_to_viewer_log || log_to_sim)
- {
- mFetcher->mTextureInfo.setRequestStartTime(mID, mStartTime);
- U64 timeNow = LLTimer::getTotalTime();
- mFetcher->mTextureInfo.setRequestType(mID, LLTextureInfoDetails::REQUEST_TYPE_HTTP);
- mFetcher->mTextureInfo.setRequestSize(mID, mRequestedSize);
- mFetcher->mTextureInfo.setRequestOffset(mID, mOffset);
- mFetcher->mTextureInfo.setRequestCompleteTimeAndLog(mID, timeNow);
- }
-
- lldebugs << "HTTP COMPLETE: " << mID << llendl;
- LLTextureFetchWorker* worker = mFetcher->getWorker(mID);
- if (worker)
- {
- bool success = false;
- bool partial = false;
- if (HTTP_OK <= status && status < HTTP_MULTIPLE_CHOICES)
- {
- success = true;
- if (HTTP_PARTIAL_CONTENT == status) // partial information
- {
- partial = true;
- }
- }
-
- if (!success)
- {
- worker->setGetStatus(status, reason);
-// llwarns << "CURL GET FAILED, status:" << status << " reason:" << reason << llendl;
- }
-
- S32 data_size = worker->callbackHttpGet(channels, buffer, partial, success);
-
- if(log_texture_traffic && data_size > 0)
- {
- LLViewerTexture* tex = LLViewerTextureManager::findTexture(mID) ;
- if(tex)
- {
- gTotalTextureBytesPerBoostLevel[tex->getBoostLevel()] += data_size ;
- }
- }
-
- mFetcher->removeFromHTTPQueue(mID, data_size);
-
- if (worker->mMetricsStartTime)
- {
- LLViewerAssetStatsFF::record_response_thread1(LLViewerAssetType::AT_TEXTURE,
- true,
- LLImageBase::TYPE_AVATAR_BAKE == worker->mType,
- LLViewerAssetStatsFF::get_timestamp() - worker->mMetricsStartTime);
- worker->mMetricsStartTime = 0;
- }
- LLViewerAssetStatsFF::record_dequeue_thread1(LLViewerAssetType::AT_TEXTURE,
- true,
- LLImageBase::TYPE_AVATAR_BAKE == worker->mType);
- }
- else
- {
- mFetcher->removeFromHTTPQueue(mID);
- llwarns << "Worker not found: " << mID << llendl;
- }
- }
-
- virtual bool followRedir()
- {
- return mFollowRedir;
- }
-
-private:
- LLTextureFetch* mFetcher;
- LLUUID mID;
- U64 mStartTime;
- S32 mRequestedSize;
- U32 mOffset;
- bool mFollowRedir;
+ LLCore::HttpHandle mHttpHandle; // Handle of any active request
+ LLCore::BufferArray * mHttpBufferArray; // Refcounted pointer to response data
+ int mHttpPolicyClass;
+ bool mHttpActive; // Active request to http library
+ unsigned int mHttpReplySize; // Actual received data size
+ unsigned int mHttpReplyOffset; // Actual received data offset
+ bool mHttpHasResource; // Counts against Fetcher's mHttpSemaphore
+
+ // State history
+ U32 mCacheReadCount;
+ U32 mCacheWriteCount;
+ U32 mResourceWaitCount; // Requests entering WAIT_HTTP_RESOURCE2
};
//////////////////////////////////////////////////////////////////////////////
@@ -617,13 +813,15 @@ const char* LLTextureFetchWorker::sStateDescs[] = {
"CACHE_POST",
"LOAD_FROM_NETWORK",
"LOAD_FROM_SIMULATOR",
+ "WAIT_HTTP_RESOURCE",
+ "WAIT_HTTP_RESOURCE2",
"SEND_HTTP_REQ",
"WAIT_HTTP_REQ",
"DECODE_IMAGE",
"DECODE_IMAGE_UPDATE",
"WRITE_TO_CACHE",
"WAIT_ON_WRITE",
- "DONE",
+ "DONE"
};
// static
@@ -632,6 +830,7 @@ volatile bool LLTextureFetch::svMetricsDataBreak(true); // Start with a data bre
// called from MAIN THREAD
LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher,
+ FTType f_type, // Fetched image type
const std::string& url, // Optional URL
const LLUUID& id, // Image UUID
const LLHost& host, // Simulator host
@@ -639,9 +838,11 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher,
S32 discard, // Desired discard
S32 size) // Desired size
: LLWorkerClass(fetcher, "TextureFetch"),
+ LLCore::HttpHandler(),
mState(INIT),
mWriteToCacheState(NOT_WRITE),
mFetcher(fetcher),
+ mFTType(f_type),
mID(id),
mHost(host),
mUrl(url),
@@ -653,11 +854,11 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher,
mRequestedDiscard(-1),
mLoadedDiscard(-1),
mDecodedDiscard(-1),
+ mCacheReadTime(0.f),
mCacheReadHandle(LLTextureCache::nullHandle()),
mCacheWriteHandle(LLTextureCache::nullHandle()),
- mBuffer(NULL),
- mBufferSize(0),
mRequestedSize(0),
+ mRequestedOffset(0),
mDesiredSize(TEXTURE_CACHE_ENTRY_SIZE),
mFileSize(0),
mCachedSize(0),
@@ -669,20 +870,29 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher,
mNeedsAux(FALSE),
mHaveAllData(FALSE),
mInLocalCache(FALSE),
+ mInCache(FALSE),
mCanUseHTTP(true),
- mHTTPFailCount(0),
mRetryAttempt(0),
mActiveCount(0),
- mGetStatus(0),
mWorkMutex(NULL),
mFirstPacket(0),
mLastPacket(-1),
mTotalPackets(0),
mImageCodec(IMG_CODEC_INVALID),
- mMetricsStartTime(0)
+ mMetricsStartTime(0),
+ mHttpHandle(LLCORE_HTTP_HANDLE_INVALID),
+ mHttpBufferArray(NULL),
+ mHttpPolicyClass(mFetcher->mHttpPolicyClass),
+ mHttpActive(false),
+ mHttpReplySize(0U),
+ mHttpReplyOffset(0U),
+ mHttpHasResource(false),
+ mCacheReadCount(0U),
+ mCacheWriteCount(0U),
+ mResourceWaitCount(0U)
{
mCanUseNET = mUrl.empty() ;
-
+
calcWorkPriority();
mType = host.isOk() ? LLImageBase::TYPE_AVATAR_BAKE : LLImageBase::TYPE_NORMAL;
// llinfos << "Create: " << mID << " mHost:" << host << " Discard=" << discard << llendl;
@@ -701,7 +911,20 @@ LLTextureFetchWorker::~LLTextureFetchWorker()
// << " Requested=" << mRequestedDiscard
// << " Desired=" << mDesiredDiscard << llendl;
llassert_always(!haveWork());
- lockWorkMutex();
+
+ lockWorkMutex(); // +Mw (should be useless)
+ if (mHttpHasResource)
+ {
+ // Last-chance catchall to recover the resource. Using an
+ // atomic datatype solely because this can be running in
+ // another thread.
+ releaseHttpSemaphore();
+ }
+ if (mHttpActive)
+ {
+ // Issue a cancel on a live request...
+ mFetcher->getHttpRequest().requestCancel(mHttpHandle, NULL);
+ }
if (mCacheReadHandle != LLTextureCache::nullHandle() && mFetcher->mTextureCache)
{
mFetcher->mTextureCache->readComplete(mCacheReadHandle, true);
@@ -712,10 +935,18 @@ LLTextureFetchWorker::~LLTextureFetchWorker()
}
mFormattedImage = NULL;
clearPackets();
- unlockWorkMutex();
- mFetcher->removeFromHTTPQueue(mID);
+ if (mHttpBufferArray)
+ {
+ mHttpBufferArray->release();
+ mHttpBufferArray = NULL;
+ }
+ unlockWorkMutex(); // -Mw
+ mFetcher->removeFromHTTPQueue(mID, 0);
+ mFetcher->removeHttpWaiter(mID);
+ mFetcher->updateStateStats(mCacheReadCount, mCacheWriteCount, mResourceWaitCount);
}
+// Locks: Mw
void LLTextureFetchWorker::clearPackets()
{
for_each(mPackets.begin(), mPackets.end(), DeletePointer());
@@ -725,6 +956,7 @@ void LLTextureFetchWorker::clearPackets()
mFirstPacket = 0;
}
+// Locks: Mw
void LLTextureFetchWorker::setupPacketData()
{
S32 data_size = 0;
@@ -757,6 +989,7 @@ void LLTextureFetchWorker::setupPacketData()
}
}
+// Locks: Mw (ctor invokes without lock)
U32 LLTextureFetchWorker::calcWorkPriority()
{
//llassert_always(mImagePriority >= 0 && mImagePriority <= LLViewerFetchedTexture::maxDecodePriority());
@@ -766,7 +999,7 @@ U32 LLTextureFetchWorker::calcWorkPriority()
return mWorkPriority;
}
-// mWorkMutex is locked
+// Locks: Mw (ctor invokes without lock)
void LLTextureFetchWorker::setDesiredDiscard(S32 discard, S32 size)
{
bool prioritize = false;
@@ -796,12 +1029,13 @@ void LLTextureFetchWorker::setDesiredDiscard(S32 discard, S32 size)
mDesiredSize = llmax(mDesiredSize, TEXTURE_CACHE_ENTRY_SIZE);
if ((prioritize && mState == INIT) || mState == DONE)
{
- mState = INIT;
+ setState(INIT);
U32 work_priority = mWorkPriority | LLWorkerThread::PRIORITY_HIGH;
setPriority(work_priority);
}
}
+// Locks: Mw
void LLTextureFetchWorker::setImagePriority(F32 priority)
{
// llassert_always(priority >= 0 && priority <= LLViewerTexture::maxDecodePriority());
@@ -815,30 +1049,37 @@ void LLTextureFetchWorker::setImagePriority(F32 priority)
}
}
+// Locks: Mw
void LLTextureFetchWorker::resetFormattedData()
{
- FREE_MEM(LLImageBase::getPrivatePool(), mBuffer);
- mBuffer = NULL;
- mBufferSize = 0;
+ if (mHttpBufferArray)
+ {
+ mHttpBufferArray->release();
+ mHttpBufferArray = NULL;
+ }
if (mFormattedImage.notNull())
{
mFormattedImage->deleteData();
}
+ mHttpReplySize = 0;
+ mHttpReplyOffset = 0;
mHaveAllData = FALSE;
}
-// Called from MAIN thread
+// Threads: Tmain
void LLTextureFetchWorker::startWork(S32 param)
{
llassert(mFormattedImage.isNull());
}
-#include "llviewertexturelist.h" // debug
-
-// Called from LLWorkerThread::processRequest()
+// Threads: Ttf
bool LLTextureFetchWorker::doWork(S32 param)
{
- LLMutexLock lock(&mWorkMutex);
+ static const LLCore::HttpStatus http_not_found(HTTP_NOT_FOUND); // 404
+ static const LLCore::HttpStatus http_service_unavail(HTTP_SERVICE_UNAVAILABLE); // 503
+ static const LLCore::HttpStatus http_not_sat(HTTP_REQUESTED_RANGE_NOT_SATISFIABLE); // 416;
+
+ LLMutexLock lock(&mWorkMutex); // +Mw
if ((mFetcher->isQuitting() || getFlags(LLWorkerClass::WCF_DELETE_REQUESTED)))
{
@@ -852,12 +1093,14 @@ bool LLTextureFetchWorker::doWork(S32 param)
{
if (mState == INIT || mState == LOAD_FROM_NETWORK || mState == LOAD_FROM_SIMULATOR)
{
+ LL_DEBUGS("Texture") << mID << " abort: mImagePriority < F_ALMOST_ZERO" << llendl;
return true; // abort
}
}
if(mState > CACHE_POST && !mCanUseNET && !mCanUseHTTP)
{
//nowhere to get data, abort.
+ LL_WARNS("Texture") << mID << " abort, nowhere to get data" << llendl;
return true ;
}
@@ -882,20 +1125,26 @@ bool LLTextureFetchWorker::doWork(S32 param)
mLoadedDiscard = -1;
mDecodedDiscard = -1;
mRequestedSize = 0;
+ mRequestedOffset = 0;
mFileSize = 0;
mCachedSize = 0;
mLoaded = FALSE;
mSentRequest = UNSENT;
mDecoded = FALSE;
mWritten = FALSE;
- FREE_MEM(LLImageBase::getPrivatePool(), mBuffer);
- mBuffer = NULL;
- mBufferSize = 0;
+ if (mHttpBufferArray)
+ {
+ mHttpBufferArray->release();
+ mHttpBufferArray = NULL;
+ }
+ mHttpReplySize = 0;
+ mHttpReplyOffset = 0;
mHaveAllData = FALSE;
clearPackets(); // TODO: Shouldn't be necessary
mCacheReadHandle = LLTextureCache::nullHandle();
mCacheWriteHandle = LLTextureCache::nullHandle();
- mState = LOAD_FROM_TEXTURE_CACHE;
+ setState(LOAD_FROM_TEXTURE_CACHE);
+ mInCache = FALSE;
mDesiredSize = llmax(mDesiredSize, TEXTURE_CACHE_ENTRY_SIZE); // min desired size is TEXTURE_CACHE_ENTRY_SIZE
LL_DEBUGS("Texture") << mID << ": Priority: " << llformat("%8.0f",mImagePriority)
<< " Desired Discard: " << mDesiredDiscard << " Desired Size: " << mDesiredSize << LL_ENDL;
@@ -911,7 +1160,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
S32 size = mDesiredSize - offset;
if (size <= 0)
{
- mState = CACHE_POST;
+ setState(CACHE_POST);
return false;
}
mFileSize = 0;
@@ -922,33 +1171,34 @@ bool LLTextureFetchWorker::doWork(S32 param)
setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); // Set priority first since Responder may change it
// read file from local disk
+ ++mCacheReadCount;
std::string filename = mUrl.substr(7, std::string::npos);
CacheReadResponder* responder = new CacheReadResponder(mFetcher, mID, mFormattedImage);
mCacheReadHandle = mFetcher->mTextureCache->readFromCache(filename, mID, cache_priority,
offset, size, responder);
+ mCacheReadTimer.reset();
}
- else if (mUrl.empty())
+/* SH-3980 - disabling caching of server bakes until we can fix the blurring problems */
+/* else if ((mUrl.empty()||mFTType==FTT_SERVER_BAKE) && mFetcher->canLoadFromCache()) */
+ else if (mUrl.empty() && mFetcher->canLoadFromCache())
{
setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); // Set priority first since Responder may change it
+ ++mCacheReadCount;
CacheReadResponder* responder = new CacheReadResponder(mFetcher, mID, mFormattedImage);
mCacheReadHandle = mFetcher->mTextureCache->readFromCache(mID, cache_priority,
offset, size, responder);
+ mCacheReadTimer.reset();
}
- else if(mCanUseHTTP)
+ else if(!mUrl.empty() && mCanUseHTTP)
{
- if (!(mUrl.compare(0, 7, "http://") == 0))
- {
- // *TODO:?remove this warning
- llwarns << "Unknown URL Type: " << mUrl << llendl;
- }
setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
- mState = SEND_HTTP_REQ;
+ setState(WAIT_HTTP_RESOURCE);
}
else
{
setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
- mState = LOAD_FROM_NETWORK;
+ setState(LOAD_FROM_NETWORK);
}
}
@@ -958,11 +1208,15 @@ bool LLTextureFetchWorker::doWork(S32 param)
if (mFetcher->mTextureCache->readComplete(mCacheReadHandle, false))
{
mCacheReadHandle = LLTextureCache::nullHandle();
- mState = CACHE_POST;
+ setState(CACHE_POST);
// fall through
}
else
{
+ //
+ //This should never happen
+ //
+ LL_DEBUGS("Texture") << mID << " this should never happen" << llendl;
return false;
}
}
@@ -981,33 +1235,42 @@ bool LLTextureFetchWorker::doWork(S32 param)
// we have enough data, decode it
llassert_always(mFormattedImage->getDataSize() > 0);
mLoadedDiscard = mDesiredDiscard;
- mState = DECODE_IMAGE;
+ if (mLoadedDiscard < 0)
+ {
+ LL_WARNS("Texture") << mID << " mLoadedDiscard is " << mLoadedDiscard
+ << ", should be >=0" << llendl;
+ }
+ setState(DECODE_IMAGE);
+ mInCache = TRUE;
mWriteToCacheState = NOT_WRITE ;
LL_DEBUGS("Texture") << mID << ": Cached. Bytes: " << mFormattedImage->getDataSize()
<< " Size: " << llformat("%dx%d",mFormattedImage->getWidth(),mFormattedImage->getHeight())
<< " Desired Discard: " << mDesiredDiscard << " Desired Size: " << mDesiredSize << LL_ENDL;
- // fall through
+ LLTextureFetch::sCacheHitRate.addValue(100.f);
}
else
{
if (mUrl.compare(0, 7, "file://") == 0)
{
// failed to load local file, we're done.
+ LL_WARNS("Texture") << mID << ": abort, failed to load local file " << mUrl << LL_ENDL;
return true;
}
// need more data
else
{
LL_DEBUGS("Texture") << mID << ": Not in Cache" << LL_ENDL;
- mState = LOAD_FROM_NETWORK;
+ setState(LOAD_FROM_NETWORK);
}
+
// fall through
+ LLTextureFetch::sCacheHitRate.addValue(0.f);
}
}
if (mState == LOAD_FROM_NETWORK)
{
- static LLCachedControl<bool> use_http(gSavedSettings,"ImagePipelineUseHTTP");
+ static LLCachedControl<bool> use_http(gSavedSettings,"ImagePipelineUseHTTP", true);
// if (mHost != LLHost::invalid) get_url = false;
if ( use_http && mCanUseHTTP && mUrl.empty())//get http url.
@@ -1038,9 +1301,15 @@ bool LLTextureFetchWorker::doWork(S32 param)
mCanUseHTTP = false;
}
}
+#if 0 /* SH-3980 - disabling caching of server bakes until we can fix the blurring problems */
+ if (mFTType == FTT_SERVER_BAKE)
+ {
+ mWriteToCacheState = CAN_WRITE;
+ }
+#endif
if (mCanUseHTTP && !mUrl.empty())
{
- mState = LLTextureFetchWorker::SEND_HTTP_REQ;
+ setState(WAIT_HTTP_RESOURCE);
setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
if(mWriteToCacheState != NOT_WRITE)
{
@@ -1057,13 +1326,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
mRequestedDiscard = mDesiredDiscard;
mSentRequest = QUEUED;
mFetcher->addToNetworkQueue(this);
- if (! mMetricsStartTime)
- {
- mMetricsStartTime = LLViewerAssetStatsFF::get_timestamp();
- }
- LLViewerAssetStatsFF::record_enqueue_thread1(LLViewerAssetType::AT_TEXTURE,
- false,
- LLImageBase::TYPE_AVATAR_BAKE == mType);
+ recordTextureStart(false);
setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);
return false;
@@ -1074,13 +1337,10 @@ bool LLTextureFetchWorker::doWork(S32 param)
//llassert_always(mFetcher->mNetworkQueue.find(mID) != mFetcher->mNetworkQueue.end());
// Make certain this is in the network queue
//mFetcher->addToNetworkQueue(this);
- //if (! mMetricsStartTime)
- //{
- // mMetricsStartTime = LLViewerAssetStatsFF::get_timestamp();
- //}
- //LLViewerAssetStatsFF::record_enqueue_thread1(LLViewerAssetType::AT_TEXTURE, false,
- // LLImageBase::TYPE_AVATAR_BAKE == mType);
+ //recordTextureStart(false);
//setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);
+
+ LL_DEBUGS("Texture") << mID << " does this happen?" << llendl;
return false;
}
}
@@ -1099,199 +1359,277 @@ bool LLTextureFetchWorker::doWork(S32 param)
{
// processSimulatorPackets() failed
// llwarns << "processSimulatorPackets() failed to load buffer" << llendl;
+ LL_WARNS("Texture") << mID << " processSimulatorPackets() failed to load buffer" << llendl;
return true; // failed
}
setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
- mState = DECODE_IMAGE;
- mWriteToCacheState = SHOULD_WRITE;
-
- if (mMetricsStartTime)
+ if (mLoadedDiscard < 0)
{
- LLViewerAssetStatsFF::record_response_thread1(LLViewerAssetType::AT_TEXTURE,
- false,
- LLImageBase::TYPE_AVATAR_BAKE == mType,
- LLViewerAssetStatsFF::get_timestamp() - mMetricsStartTime);
- mMetricsStartTime = 0;
+ LL_WARNS("Texture") << mID << " mLoadedDiscard is " << mLoadedDiscard
+ << ", should be >=0" << llendl;
}
- LLViewerAssetStatsFF::record_dequeue_thread1(LLViewerAssetType::AT_TEXTURE,
- false,
- LLImageBase::TYPE_AVATAR_BAKE == mType);
+ setState(DECODE_IMAGE);
+ mWriteToCacheState = SHOULD_WRITE;
+ recordTextureDone(false);
}
else
{
mFetcher->addToNetworkQueue(this); // failsafe
- if (! mMetricsStartTime)
- {
- mMetricsStartTime = LLViewerAssetStatsFF::get_timestamp();
- }
- LLViewerAssetStatsFF::record_enqueue_thread1(LLViewerAssetType::AT_TEXTURE,
- false,
- LLImageBase::TYPE_AVATAR_BAKE == mType);
setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);
+ recordTextureStart(false);
+ }
+ return false;
+ }
+
+ if (mState == WAIT_HTTP_RESOURCE)
+ {
+ // NOTE:
+ // control the number of the http requests issued for:
+ // 1, not openning too many file descriptors at the same time;
+ // 2, control the traffic of http so udp gets bandwidth.
+ //
+ // If it looks like we're busy, keep this request here.
+ // Otherwise, advance into the HTTP states.
+ if (mFetcher->getHttpWaitersCount() || ! acquireHttpSemaphore())
+ {
+ setState(WAIT_HTTP_RESOURCE2);
+ setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);
+ mFetcher->addHttpWaiter(this->mID);
+ ++mResourceWaitCount;
+ return false;
}
+
+ setState(SEND_HTTP_REQ);
+ // *NOTE: You must invoke releaseHttpSemaphore() if you transition
+ // to a state other than SEND_HTTP_REQ or WAIT_HTTP_REQ or abort
+ // the request.
+ }
+
+ if (mState == WAIT_HTTP_RESOURCE2)
+ {
+ // Just idle it if we make it to the head...
return false;
}
if (mState == SEND_HTTP_REQ)
{
- if(mCanUseHTTP)
+ if (! mCanUseHTTP)
{
- //NOTE:
- //control the number of the http requests issued for:
- //1, not openning too many file descriptors at the same time;
- //2, control the traffic of http so udp gets bandwidth.
- //
- static const S32 MAX_NUM_OF_HTTP_REQUESTS_IN_QUEUE = 8 ;
- if(mFetcher->getNumHTTPRequests() > MAX_NUM_OF_HTTP_REQUESTS_IN_QUEUE)
- {
- return false ; //wait.
- }
+ releaseHttpSemaphore();
+ LL_WARNS("Texture") << mID << " abort: SEND_HTTP_REQ but !mCanUseHTTP" << llendl;
+ return true; // abort
+ }
- mFetcher->removeFromNetworkQueue(this, false);
+ mFetcher->removeFromNetworkQueue(this, false);
- S32 cur_size = 0;
- if (mFormattedImage.notNull())
+ S32 cur_size = 0;
+ if (mFormattedImage.notNull())
+ {
+ cur_size = mFormattedImage->getDataSize(); // amount of data we already have
+ if (mFormattedImage->getDiscardLevel() == 0)
{
- cur_size = mFormattedImage->getDataSize(); // amount of data we already have
- if (mFormattedImage->getDiscardLevel() == 0)
+ if (cur_size > 0)
{
- if(cur_size > 0)
- {
- // We already have all the data, just decode it
- mLoadedDiscard = mFormattedImage->getDiscardLevel();
- mState = DECODE_IMAGE;
- return false;
- }
- else
+ // We already have all the data, just decode it
+ mLoadedDiscard = mFormattedImage->getDiscardLevel();
+ setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
+ if (mLoadedDiscard < 0)
{
- return true ; //abort.
+ LL_WARNS("Texture") << mID << " mLoadedDiscard is " << mLoadedDiscard
+ << ", should be >=0" << llendl;
}
+ setState(DECODE_IMAGE);
+ releaseHttpSemaphore();
+ return false;
}
- }
- mRequestedSize = mDesiredSize;
- mRequestedDiscard = mDesiredDiscard;
- mRequestedSize -= cur_size;
- S32 offset = cur_size;
- mBufferSize = cur_size; // This will get modified by callbackHttpGet()
-
- bool res = false;
- if (!mUrl.empty())
- {
- mLoaded = FALSE;
- mGetStatus = 0;
- mGetReason.clear();
- LL_DEBUGS("Texture") << "HTTP GET: " << mID << " Offset: " << offset
- << " Bytes: " << mRequestedSize
- << " Bandwidth(kbps): " << mFetcher->getTextureBandwidth() << "/" << mFetcher->mMaxBandwidth
- << LL_ENDL;
- setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);
- mState = WAIT_HTTP_REQ;
-
- mFetcher->addToHTTPQueue(mID);
- if (! mMetricsStartTime)
+ else
{
- mMetricsStartTime = LLViewerAssetStatsFF::get_timestamp();
+ releaseHttpSemaphore();
+ LL_WARNS("Texture") << mID << " SEND_HTTP_REQ abort: cur_size " << cur_size << " <=0" << llendl;
+ return true; // abort.
}
- LLViewerAssetStatsFF::record_enqueue_thread1(LLViewerAssetType::AT_TEXTURE,
- true,
- LLImageBase::TYPE_AVATAR_BAKE == mType);
-
- // Will call callbackHttpGet when curl request completes
- std::vector<std::string> headers;
- headers.push_back("Accept: image/x-j2c");
- res = mFetcher->mCurlGetRequest->getByteRange(mUrl, headers, offset, mRequestedSize,
- new HTTPGetResponder(mFetcher, mID, LLTimer::getTotalTime(), mRequestedSize, offset, true));
- }
- if (!res)
- {
- llwarns << "HTTP GET request failed for " << mID << llendl;
- resetFormattedData();
- ++mHTTPFailCount;
- return true; // failed
}
- // fall through
}
- else //can not use http fetch.
+ mRequestedSize = mDesiredSize;
+ mRequestedDiscard = mDesiredDiscard;
+ mRequestedSize -= cur_size;
+ mRequestedOffset = cur_size;
+ if (mRequestedOffset)
+ {
+ // Texture fetching often issues 'speculative' loads that
+ // start beyond the end of the actual asset. Some cache/web
+ // systems, e.g. Varnish, will respond to this not with a
+ // 416 but with a 200 and the entire asset in the response
+ // body. By ensuring that we always have a partially
+ // satisfiable Range request, we avoid that hit to the network.
+ // We just have to deal with the overlapping data which is made
+ // somewhat harder by the fact that grid services don't necessarily
+ // return the Content-Range header on 206 responses. *Sigh*
+ mRequestedOffset -= 1;
+ mRequestedSize += 1;
+ }
+
+ mHttpHandle = LLCORE_HTTP_HANDLE_INVALID;
+ if (!mUrl.empty())
+ {
+ mRequestedTimer.reset();
+ mLoaded = FALSE;
+ mGetStatus = LLCore::HttpStatus();
+ mGetReason.clear();
+ LL_DEBUGS("Texture") << "HTTP GET: " << mID << " Offset: " << mRequestedOffset
+ << " Bytes: " << mRequestedSize
+ << " Bandwidth(kbps): " << mFetcher->getTextureBandwidth() << "/" << mFetcher->mMaxBandwidth
+ << LL_ENDL;
+
+ // Will call callbackHttpGet when curl request completes
+ mHttpHandle = mFetcher->mHttpRequest->requestGetByteRange(mHttpPolicyClass,
+ mWorkPriority,
+ mUrl,
+ mRequestedOffset,
+ mRequestedSize,
+ mFetcher->mHttpOptions,
+ mFetcher->mHttpHeaders,
+ this);
+ }
+ if (LLCORE_HTTP_HANDLE_INVALID == mHttpHandle)
{
- return true ; //abort
+ llwarns << "HTTP GET request failed for " << mID << llendl;
+ resetFormattedData();
+ releaseHttpSemaphore();
+ return true; // failed
}
+
+ mHttpActive = true;
+ mFetcher->addToHTTPQueue(mID);
+ recordTextureStart(true);
+ setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);
+ setState(WAIT_HTTP_REQ);
+
+ // fall through
}
if (mState == WAIT_HTTP_REQ)
{
+ // *NOTE: As stated above, all transitions out of this state should
+ // call releaseHttpSemaphore().
if (mLoaded)
{
S32 cur_size = mFormattedImage.notNull() ? mFormattedImage->getDataSize() : 0;
if (mRequestedSize < 0)
{
- S32 max_attempts;
- if (mGetStatus == HTTP_NOT_FOUND)
+ if (http_not_found == mGetStatus)
{
- mHTTPFailCount = max_attempts = 1; // Don't retry
+ if(mWriteToCacheState == NOT_WRITE) //map tiles
+ {
+ setState(DONE);
+ releaseHttpSemaphore();
+ LL_DEBUGS("Texture") << mID << " abort: WAIT_HTTP_REQ not found" << llendl;
+ return true; // failed, means no map tile on the empty region.
+ }
+
llwarns << "Texture missing from server (404): " << mUrl << llendl;
- //roll back to try UDP
- if(mCanUseNET)
+ // roll back to try UDP
+ if (mCanUseNET)
{
- mState = INIT ;
- mCanUseHTTP = false ;
+ setState(INIT);
+ mCanUseHTTP = false;
+ mUrl.clear();
setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
- return false ;
+ releaseHttpSemaphore();
+ return false;
}
}
- else if (mGetStatus == HTTP_SERVICE_UNAVAILABLE)
+ else if (http_service_unavail == mGetStatus)
{
- // *TODO: Should probably introduce a timer here to delay future HTTP requsts
- // for a short time (~1s) to ease server load? Ideally the server would queue
- // requests instead of returning 503... we already limit the number pending.
- ++mHTTPFailCount;
- max_attempts = mHTTPFailCount+1; // Keep retrying
LL_INFOS_ONCE("Texture") << "Texture server busy (503): " << mUrl << LL_ENDL;
}
+ else if (http_not_sat == mGetStatus)
+ {
+ // Allowed, we'll accept whatever data we have as complete.
+ mHaveAllData = TRUE;
+ }
else
{
- const S32 HTTP_MAX_RETRY_COUNT = 3;
- max_attempts = HTTP_MAX_RETRY_COUNT + 1;
- ++mHTTPFailCount;
llinfos << "HTTP GET failed for: " << mUrl
- << " Status: " << mGetStatus << " Reason: '" << mGetReason << "'"
- << " Attempt:" << mHTTPFailCount+1 << "/" << max_attempts << llendl;
+ << " Status: " << mGetStatus.toHex()
+ << " Reason: '" << mGetReason << "'"
+ << llendl;
}
- if (mHTTPFailCount >= max_attempts)
+ mUrl.clear();
+ if (cur_size > 0)
{
- if (cur_size > 0)
- {
- // Use available data
- mLoadedDiscard = mFormattedImage->getDiscardLevel();
- mState = DECODE_IMAGE;
- return false;
- }
- else
+ // Use available data
+ mLoadedDiscard = mFormattedImage->getDiscardLevel();
+ setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
+ if (mLoadedDiscard < 0)
{
- resetFormattedData();
- mState = DONE;
- return true; // failed
+ LL_WARNS("Texture") << mID << " mLoadedDiscard is " << mLoadedDiscard
+ << ", should be >=0" << llendl;
}
+ setState(DECODE_IMAGE);
+ releaseHttpSemaphore();
+ return false;
}
- else
- {
- mState = SEND_HTTP_REQ;
- return false; // retry
- }
+
+ // Fail harder
+ resetFormattedData();
+ setState(DONE);
+ releaseHttpSemaphore();
+ LL_WARNS("Texture") << mID << " abort: fail harder" << llendl;
+ return true; // failed
+ }
+
+ // Clear the url since we're done with the fetch
+ // Note: mUrl is used to check is fetching is required so failure to clear it will force an http fetch
+ // next time the texture is requested, even if the data have already been fetched.
+ if(mWriteToCacheState != NOT_WRITE)
+ {
+ // Why do we want to keep url if NOT_WRITE - is this a proxy for map tiles?
+ mUrl.clear();
}
- llassert_always(mBufferSize == cur_size + mRequestedSize);
- if(!mBufferSize)//no data received.
+ if (! mHttpBufferArray || ! mHttpBufferArray->size())
{
- FREE_MEM(LLImageBase::getPrivatePool(), mBuffer);
- mBuffer = NULL;
+ // no data received.
+ if (mHttpBufferArray)
+ {
+ mHttpBufferArray->release();
+ mHttpBufferArray = NULL;
+ }
- //abort.
- mState = DONE;
+ // abort.
+ setState(DONE);
+ LL_WARNS("Texture") << mID << " abort: no data received" << llendl;
+ releaseHttpSemaphore();
return true;
}
+ S32 append_size(mHttpBufferArray->size());
+ S32 total_size(cur_size + append_size);
+ S32 src_offset(0);
+ llassert_always(append_size == mRequestedSize);
+ if (mHttpReplyOffset && mHttpReplyOffset != cur_size)
+ {
+ // In case of a partial response, our offset may
+ // not be trivially contiguous with the data we have.
+ // Get back into alignment.
+ if (mHttpReplyOffset > cur_size)
+ {
+ LL_WARNS("Texture") << "Partial HTTP response produces break in image data for texture "
+ << mID << ". Aborting load." << LL_ENDL;
+ setState(DONE);
+ releaseHttpSemaphore();
+ return true;
+ }
+ src_offset = cur_size - mHttpReplyOffset;
+ append_size -= src_offset;
+ total_size -= src_offset;
+ mRequestedSize -= src_offset; // Make requested values reflect useful part
+ mRequestedOffset += src_offset;
+ }
+
if (mFormattedImage.isNull())
{
// For now, create formatted image based on extension
@@ -1303,38 +1641,55 @@ bool LLTextureFetchWorker::doWork(S32 param)
}
}
- if (mHaveAllData && mRequestedDiscard == 0) //the image file is fully loaded.
+ if (mHaveAllData) //the image file is fully loaded.
{
- mFileSize = mBufferSize;
+ mFileSize = total_size;
}
else //the file size is unknown.
{
- mFileSize = mBufferSize + 1 ; //flag the file is not fully loaded.
+ mFileSize = total_size + 1 ; //flag the file is not fully loaded.
}
- U8* buffer = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), mBufferSize);
+ U8 * buffer = (U8 *) ALLOCATE_MEM(LLImageBase::getPrivatePool(), total_size);
if (cur_size > 0)
{
memcpy(buffer, mFormattedImage->getData(), cur_size);
}
- memcpy(buffer + cur_size, mBuffer, mRequestedSize); // append
+ mHttpBufferArray->read(src_offset, (char *) buffer + cur_size, append_size);
+
// NOTE: setData releases current data and owns new data (buffer)
- mFormattedImage->setData(buffer, mBufferSize);
- // delete temp data
- FREE_MEM(LLImageBase::getPrivatePool(), mBuffer); // Note: not 'buffer' (assigned in setData())
- mBuffer = NULL;
- mBufferSize = 0;
+ mFormattedImage->setData(buffer, total_size);
+
+ // Done with buffer array
+ mHttpBufferArray->release();
+ mHttpBufferArray = NULL;
+ mHttpReplySize = 0;
+ mHttpReplyOffset = 0;
+
mLoadedDiscard = mRequestedDiscard;
- mState = DECODE_IMAGE;
- if(mWriteToCacheState != NOT_WRITE)
+ if (mLoadedDiscard < 0)
+ {
+ LL_WARNS("Texture") << mID << " mLoadedDiscard is " << mLoadedDiscard
+ << ", should be >=0" << llendl;
+ }
+ setState(DECODE_IMAGE);
+ if (mWriteToCacheState != NOT_WRITE)
{
mWriteToCacheState = SHOULD_WRITE ;
}
setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
+ releaseHttpSemaphore();
return false;
}
else
{
+ // *HISTORY: There was a texture timeout test here originally that
+ // would cancel a request that was over 120 seconds old. That's
+ // probably not a good idea. Particularly rich regions can take
+ // an enormous amount of time to load textures. We'll revisit the
+ // various possible timeout components (total request time, connection
+ // time, I/O time, with and without retries, etc.) in the future.
+
setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);
return false;
}
@@ -1342,49 +1697,50 @@ bool LLTextureFetchWorker::doWork(S32 param)
if (mState == DECODE_IMAGE)
{
- static LLCachedControl<bool> textures_decode_disabled(gSavedSettings,"TextureDecodeDisabled");
- if(textures_decode_disabled)
+ static LLCachedControl<bool> textures_decode_disabled(gSavedSettings,"TextureDecodeDisabled", false);
+
+ setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); // Set priority first since Responder may change it
+ if (textures_decode_disabled)
{
// for debug use, don't decode
- mState = DONE;
- setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);
+ setState(DONE);
return true;
}
if (mDesiredDiscard < 0)
{
// We aborted, don't decode
- mState = DONE;
- setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);
+ setState(DONE);
+ LL_DEBUGS("Texture") << mID << " DECODE_IMAGE abort: desired discard " << mDesiredDiscard << "<0" << llendl;
return true;
}
if (mFormattedImage->getDataSize() <= 0)
{
- //llerrs << "Decode entered with invalid mFormattedImage. ID = " << mID << llendl;
+ llwarns << "Decode entered with invalid mFormattedImage. ID = " << mID << llendl;
//abort, don't decode
- mState = DONE;
- setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);
+ setState(DONE);
+ LL_DEBUGS("Texture") << mID << " DECODE_IMAGE abort: (mFormattedImage->getDataSize() <= 0)" << llendl;
return true;
}
if (mLoadedDiscard < 0)
{
- //llerrs << "Decode entered with invalid mLoadedDiscard. ID = " << mID << llendl;
+ llwarns << "Decode entered with invalid mLoadedDiscard. ID = " << mID << llendl;
//abort, don't decode
- mState = DONE;
- setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);
+ setState(DONE);
+ LL_DEBUGS("Texture") << mID << " DECODE_IMAGE abort: mLoadedDiscard < 0" << llendl;
return true;
}
- setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); // Set priority first since Responder may change it
+
mRawImage = NULL;
mAuxImage = NULL;
llassert_always(mFormattedImage.notNull());
S32 discard = mHaveAllData ? 0 : mLoadedDiscard;
U32 image_priority = LLWorkerThread::PRIORITY_NORMAL | mWorkPriority;
mDecoded = FALSE;
- mState = DECODE_IMAGE_UPDATE;
+ setState(DECODE_IMAGE_UPDATE);
LL_DEBUGS("Texture") << mID << ": Decoding. Bytes: " << mFormattedImage->getDataSize() << " Discard: " << discard
<< " All Data: " << mHaveAllData << LL_ENDL;
mDecodeHandle = mFetcher->mImageDecodeThread->decodeImage(mFormattedImage, image_priority, discard, mNeedsAux,
@@ -1396,6 +1752,11 @@ bool LLTextureFetchWorker::doWork(S32 param)
{
if (mDecoded)
{
+ if(mFetcher->getFetchDebugger() && !mInLocalCache)
+ {
+ mFetcher->getFetchDebugger()->addHistoryEntry(this);
+ }
+
if (mDecodedDiscard < 0)
{
LL_DEBUGS("Texture") << mID << ": Failed to Decode." << LL_ENDL;
@@ -1407,13 +1768,13 @@ bool LLTextureFetchWorker::doWork(S32 param)
mFormattedImage = NULL;
++mRetryAttempt;
setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
- mState = INIT;
+ setState(INIT);
return false;
}
else
{
// llwarns << "UNABLE TO LOAD TEXTURE: " << mID << " RETRIES: " << mRetryAttempt << llendl;
- mState = DONE; // failed
+ setState(DONE); // failed
}
}
else
@@ -1422,7 +1783,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
LL_DEBUGS("Texture") << mID << ": Decoded. Discard: " << mDecodedDiscard
<< " Raw Image: " << llformat("%dx%d",mRawImage->getWidth(),mRawImage->getHeight()) << LL_ENDL;
setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
- mState = WRITE_TO_CACHE;
+ setState(WRITE_TO_CACHE);
}
// fall through
}
@@ -1438,7 +1799,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
{
// If we're in a local cache or we didn't actually receive any new data,
// or we failed to load anything, skip
- mState = DONE;
+ setState(DONE);
return false;
}
S32 datasize = mFormattedImage->getDataSize();
@@ -1457,11 +1818,12 @@ bool LLTextureFetchWorker::doWork(S32 param)
setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); // Set priority first since Responder may change it
U32 cache_priority = mWorkPriority;
mWritten = FALSE;
- mState = WAIT_ON_WRITE;
+ setState(WAIT_ON_WRITE);
+ ++mCacheWriteCount;
CacheWriteResponder* responder = new CacheWriteResponder(mFetcher, mID);
mCacheWriteHandle = mFetcher->mTextureCache->writeToCache(mID, cache_priority,
mFormattedImage->getData(), datasize,
- mFileSize, responder);
+ mFileSize, mRawImage, mDecodedDiscard, responder);
// fall through
}
@@ -1469,7 +1831,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
{
if (writeToCacheComplete())
{
- mState = DONE;
+ setState(DONE);
// fall through
}
else
@@ -1490,7 +1852,10 @@ bool LLTextureFetchWorker::doWork(S32 param)
if (mDecodedDiscard >= 0 && mDesiredDiscard < mDecodedDiscard)
{
// More data was requested, return to INIT
- mState = INIT;
+ setState(INIT);
+ LL_DEBUGS("Texture") << mID << " more data requested, returning to INIT: "
+ << " mDecodedDiscard " << mDecodedDiscard << ">= 0 && mDesiredDiscard " << mDesiredDiscard
+ << "<" << " mDecodedDiscard " << mDecodedDiscard << llendl;
setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
return false;
}
@@ -1502,9 +1867,84 @@ bool LLTextureFetchWorker::doWork(S32 param)
}
return false;
-}
+} // -Mw
+
+// Threads: Ttf
+// virtual
+void LLTextureFetchWorker::onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response)
+{
+ static LLCachedControl<bool> log_to_viewer_log(gSavedSettings, "LogTextureDownloadsToViewerLog", false);
+ static LLCachedControl<bool> log_to_sim(gSavedSettings, "LogTextureDownloadsToSimulator", false);
+ static LLCachedControl<bool> log_texture_traffic(gSavedSettings, "LogTextureNetworkTraffic", false) ;
-// Called from MAIN thread
+ LLMutexLock lock(&mWorkMutex); // +Mw
+
+ mHttpActive = false;
+
+ if (log_to_viewer_log || log_to_sim)
+ {
+ U64 timeNow = LLTimer::getTotalTime();
+ mFetcher->mTextureInfo.setRequestStartTime(mID, mMetricsStartTime);
+ mFetcher->mTextureInfo.setRequestType(mID, LLTextureInfoDetails::REQUEST_TYPE_HTTP);
+ mFetcher->mTextureInfo.setRequestSize(mID, mRequestedSize);
+ mFetcher->mTextureInfo.setRequestOffset(mID, mRequestedOffset);
+ mFetcher->mTextureInfo.setRequestCompleteTimeAndLog(mID, timeNow);
+ }
+
+ bool success = true;
+ bool partial = false;
+ LLCore::HttpStatus status(response->getStatus());
+
+ LL_DEBUGS("Texture") << "HTTP COMPLETE: " << mID
+ << " status: " << status.toHex()
+ << " '" << status.toString() << "'"
+ << llendl;
+// unsigned int offset(0), length(0), full_length(0);
+// response->getRange(&offset, &length, &full_length);
+// llwarns << "HTTP COMPLETE: " << mID << " handle: " << handle
+// << " status: " << status.toULong() << " '" << status.toString() << "'"
+// << " req offset: " << mRequestedOffset << " req length: " << mRequestedSize
+// << " offset: " << offset << " length: " << length
+// << llendl;
+
+ if (! status)
+ {
+ success = false;
+ std::string reason(status.toString());
+ setGetStatus(status, reason);
+ llwarns << "CURL GET FAILED, status: " << status.toHex()
+ << " reason: " << reason << llendl;
+ }
+ else
+ {
+ // A warning about partial (HTTP 206) data. Some grid services
+ // do *not* return a 'Content-Range' header in the response to
+ // Range requests with a 206 status. We're forced to assume
+ // we get what we asked for in these cases until we can fix
+ // the services.
+ static const LLCore::HttpStatus par_status(HTTP_PARTIAL_CONTENT);
+
+ partial = (par_status == status);
+ }
+
+ S32 data_size = callbackHttpGet(response, partial, success);
+
+ if (log_texture_traffic && data_size > 0)
+ {
+ LLViewerTexture* tex = LLViewerTextureManager::findTexture(mID);
+ if (tex)
+ {
+ gTotalTextureBytesPerBoostLevel[tex->getBoostLevel()] += data_size ;
+ }
+ }
+
+ mFetcher->removeFromHTTPQueue(mID, data_size);
+
+ recordTextureDone(true);
+} // -Mw
+
+
+// Threads: Tmain
void LLTextureFetchWorker::endWork(S32 param, bool aborted)
{
if (mDecodeHandle != 0)
@@ -1517,6 +1957,8 @@ void LLTextureFetchWorker::endWork(S32 param, bool aborted)
//////////////////////////////////////////////////////////////////////////////
+// Threads: Ttf
+
// virtual
void LLTextureFetchWorker::finishWork(S32 param, bool completed)
{
@@ -1533,10 +1975,37 @@ void LLTextureFetchWorker::finishWork(S32 param, bool completed)
}
}
+// LLQueuedThread's update() method is asking if it's okay to
+// delete this worker. You'll notice we're not locking in here
+// which is a slight concern. Caller is expected to have made
+// this request 'quiet' by whatever means...
+//
+// Threads: Tmain
+
// virtual
bool LLTextureFetchWorker::deleteOK()
{
bool delete_ok = true;
+
+ if (mHttpActive)
+ {
+ // HTTP library has a pointer to this worker
+ // and will dereference it to do notification.
+ delete_ok = false;
+ }
+
+ if (WAIT_HTTP_RESOURCE2 == mState)
+ {
+ if (mFetcher->isHttpWaiter(mID))
+ {
+ // Don't delete the worker out from under the releaseHttpWaiters()
+ // method. Keep the pointers valid, clean up after that method
+ // has recognized the cancelation and removed the UUID from the
+ // waiter list.
+ delete_ok = false;
+ }
+ }
+
// Allow any pending reads or writes to complete
if (mCacheReadHandle != LLTextureCache::nullHandle())
{
@@ -1571,6 +2040,7 @@ bool LLTextureFetchWorker::deleteOK()
return delete_ok;
}
+// Threads: Ttf
void LLTextureFetchWorker::removeFromCache()
{
if (!mInLocalCache)
@@ -1582,6 +2052,8 @@ void LLTextureFetchWorker::removeFromCache()
//////////////////////////////////////////////////////////////////////////////
+// Threads: Ttf
+// Locks: Mw
bool LLTextureFetchWorker::processSimulatorPackets()
{
if (mFormattedImage.isNull() || mRequestedSize < 0)
@@ -1642,14 +2114,13 @@ bool LLTextureFetchWorker::processSimulatorPackets()
//////////////////////////////////////////////////////////////////////////////
-S32 LLTextureFetchWorker::callbackHttpGet(const LLChannelDescriptors& channels,
- const LLIOPipe::buffer_ptr_t& buffer,
- bool partial, bool success)
+// Threads: Ttf
+// Locks: Mw
+S32 LLTextureFetchWorker::callbackHttpGet(LLCore::HttpResponse * response,
+ bool partial, bool success)
{
S32 data_size = 0 ;
- LLMutexLock lock(&mWorkMutex);
-
if (mState != WAIT_HTTP_REQ)
{
llwarns << "callbackHttpGet for unrequested fetch worker: " << mID
@@ -1664,27 +2135,69 @@ S32 LLTextureFetchWorker::callbackHttpGet(const LLChannelDescriptors& channels,
if (success)
{
// get length of stream:
- data_size = buffer->countAfter(channels.in(), NULL);
-
+ LLCore::BufferArray * body(response->getBody());
+ data_size = body ? body->size() : 0;
+
LL_DEBUGS("Texture") << "HTTP RECEIVED: " << mID.asString() << " Bytes: " << data_size << LL_ENDL;
if (data_size > 0)
{
+ LLViewerStatsRecorder::instance().textureFetch(data_size);
// *TODO: set the formatted image data here directly to avoid the copy
- mBuffer = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), data_size);
- buffer->readAfter(channels.in(), NULL, mBuffer, data_size);
- mBufferSize += data_size;
- if (data_size < mRequestedSize && mRequestedDiscard == 0)
+
+ // Hold on to body for later copy
+ llassert_always(NULL == mHttpBufferArray);
+ body->addRef();
+ mHttpBufferArray = body;
+
+ if (partial)
+ {
+ unsigned int offset(0), length(0), full_length(0);
+ response->getRange(&offset, &length, &full_length);
+ if (! offset && ! length)
+ {
+ // This is the case where we receive a 206 status but
+ // there wasn't a useful Content-Range header in the response.
+ // This could be because it was badly formatted but is more
+ // likely due to capabilities services which scrub headers
+ // from responses. Assume we got what we asked for...
+ mHttpReplySize = data_size;
+ mHttpReplyOffset = mRequestedOffset;
+ }
+ else
+ {
+ mHttpReplySize = length;
+ mHttpReplyOffset = offset;
+ }
+ }
+
+ if (! partial)
+ {
+ // Response indicates this is the entire asset regardless
+ // of our asking for a byte range. Mark it so and drop
+ // any partial data we might have so that the current
+ // response body becomes the entire dataset.
+ if (data_size <= mRequestedOffset)
+ {
+ LL_WARNS("Texture") << "Fetched entire texture " << mID
+ << " when it was expected to be marked complete. mImageSize: "
+ << mFileSize << " datasize: " << mFormattedImage->getDataSize()
+ << LL_ENDL;
+ }
+ mHaveAllData = TRUE;
+ llassert_always(mDecodeHandle == 0);
+ mFormattedImage = NULL; // discard any previous data we had
+ }
+ else if (data_size < mRequestedSize)
{
mHaveAllData = TRUE;
}
else if (data_size > mRequestedSize)
{
- // *TODO: This shouldn't be happening any more
+ // *TODO: This shouldn't be happening any more (REALLY don't expect this anymore)
llwarns << "data_size = " << data_size << " > requested: " << mRequestedSize << llendl;
mHaveAllData = TRUE;
llassert_always(mDecodeHandle == 0);
mFormattedImage = NULL; // discard any previous data we had
- mBufferSize = data_size;
}
}
else
@@ -1699,18 +2212,21 @@ S32 LLTextureFetchWorker::callbackHttpGet(const LLChannelDescriptors& channels,
{
mRequestedSize = -1; // error
}
+
mLoaded = TRUE;
setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
+ LLViewerStatsRecorder::instance().log(0.2f);
return data_size ;
}
//////////////////////////////////////////////////////////////////////////////
+// Threads: Ttc
void LLTextureFetchWorker::callbackCacheRead(bool success, LLImageFormatted* image,
S32 imagesize, BOOL islocal)
{
- LLMutexLock lock(&mWorkMutex);
+ LLMutexLock lock(&mWorkMutex); // +Mw
if (mState != LOAD_FROM_TEXTURE_CACHE)
{
// llwarns << "Read callback for " << mID << " with state = " << mState << llendl;
@@ -1730,11 +2246,12 @@ void LLTextureFetchWorker::callbackCacheRead(bool success, LLImageFormatted* ima
}
mLoaded = TRUE;
setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
-}
+} // -Mw
+// Threads: Ttc
void LLTextureFetchWorker::callbackCacheWrite(bool success)
{
- LLMutexLock lock(&mWorkMutex);
+ LLMutexLock lock(&mWorkMutex); // +Mw
if (mState != WAIT_ON_WRITE)
{
// llwarns << "Write callback for " << mID << " with state = " << mState << llendl;
@@ -1742,13 +2259,14 @@ void LLTextureFetchWorker::callbackCacheWrite(bool success)
}
mWritten = TRUE;
setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
-}
+} // -Mw
//////////////////////////////////////////////////////////////////////////////
+// Threads: Tid
void LLTextureFetchWorker::callbackDecoded(bool success, LLImageRaw* raw, LLImageRaw* aux)
{
- LLMutexLock lock(&mWorkMutex);
+ LLMutexLock lock(&mWorkMutex); // +Mw
if (mDecodeHandle == 0)
{
return; // aborted, ignore
@@ -1780,10 +2298,12 @@ void LLTextureFetchWorker::callbackDecoded(bool success, LLImageRaw* raw, LLImag
mDecoded = TRUE;
// llinfos << mID << " : DECODE COMPLETE " << llendl;
setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
-}
+ mCacheReadTime = mCacheReadTimer.getElapsedTimeF32();
+} // -Mw
//////////////////////////////////////////////////////////////////////////////
+// Threads: Ttf
bool LLTextureFetchWorker::writeToCacheComplete()
{
// Complete write to cache
@@ -1806,6 +2326,36 @@ bool LLTextureFetchWorker::writeToCacheComplete()
}
+// Threads: Ttf
+void LLTextureFetchWorker::recordTextureStart(bool is_http)
+{
+ if (! mMetricsStartTime)
+ {
+ mMetricsStartTime = LLViewerAssetStatsFF::get_timestamp();
+ }
+ LLViewerAssetStatsFF::record_enqueue_thread1(LLViewerAssetType::AT_TEXTURE,
+ is_http,
+ LLImageBase::TYPE_AVATAR_BAKE == mType);
+}
+
+
+// Threads: Ttf
+void LLTextureFetchWorker::recordTextureDone(bool is_http)
+{
+ if (mMetricsStartTime)
+ {
+ LLViewerAssetStatsFF::record_response_thread1(LLViewerAssetType::AT_TEXTURE,
+ is_http,
+ LLImageBase::TYPE_AVATAR_BAKE == mType,
+ LLViewerAssetStatsFF::get_timestamp() - mMetricsStartTime);
+ mMetricsStartTime = 0;
+ }
+ LLViewerAssetStatsFF::record_dequeue_thread1(LLViewerAssetType::AT_TEXTURE,
+ is_http,
+ LLImageBase::TYPE_AVATAR_BAKE == mType);
+}
+
+
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
// public
@@ -1823,17 +2373,49 @@ LLTextureFetch::LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* image
mTextureBandwidth(0),
mHTTPTextureBits(0),
mTotalHTTPRequests(0),
- mCurlGetRequest(NULL),
- mQAMode(qa_mode)
+ mQAMode(qa_mode),
+ mHttpRequest(NULL),
+ mHttpOptions(NULL),
+ mHttpHeaders(NULL),
+ mHttpMetricsHeaders(NULL),
+ mHttpPolicyClass(LLCore::HttpRequest::DEFAULT_POLICY_ID),
+ mHttpSemaphore(HTTP_REQUESTS_IN_QUEUE_HIGH_WATER),
+ mTotalCacheReadCount(0U),
+ mTotalCacheWriteCount(0U),
+ mTotalResourceWaitCount(0U),
+ mFetchDebugger(NULL),
+ mFetchSource(LLTextureFetch::FROM_ALL),
+ mOriginFetchSource(LLTextureFetch::FROM_ALL),
+ mFetcherLocked(FALSE)
{
- mCurlPOSTRequestCount = 0;
mMaxBandwidth = gSavedSettings.getF32("ThrottleBandwidthKBPS");
mTextureInfo.setUpLogging(gSavedSettings.getBOOL("LogTextureDownloadsToViewerLog"), gSavedSettings.getBOOL("LogTextureDownloadsToSimulator"), gSavedSettings.getU32("TextureLoggingThreshold"));
+
+ LLTextureFetchDebugger::sDebuggerEnabled = gSavedSettings.getBOOL("TextureFetchDebuggerEnabled");
+ if(LLTextureFetchDebugger::isEnabled())
+ {
+ mFetchDebugger = new LLTextureFetchDebugger(this, cache, imagedecodethread) ;
+ mFetchSource = (e_tex_source)gSavedSettings.getS32("TextureFetchSource");
+ if(mFetchSource < 0 && mFetchSource >= INVALID_SOURCE)
+ {
+ mFetchSource = LLTextureFetch::FROM_ALL;
+ gSavedSettings.setS32("TextureFetchSource", 0);
+ }
+ mOriginFetchSource = mFetchSource;
+ }
+
+ mHttpRequest = new LLCore::HttpRequest;
+ mHttpOptions = new LLCore::HttpOptions;
+ mHttpHeaders = new LLCore::HttpHeaders;
+ mHttpHeaders->mHeaders.push_back("Accept: image/x-j2c");
+ mHttpMetricsHeaders = new LLCore::HttpHeaders;
+ mHttpMetricsHeaders->mHeaders.push_back("Content-Type: application/llsd+xml");
+ mHttpPolicyClass = LLAppViewer::instance()->getAppCoreHttp().getPolicyDefault();
}
LLTextureFetch::~LLTextureFetch()
{
- clearDeleteList() ;
+ clearDeleteList();
while (! mCommands.empty())
{
@@ -1841,13 +2423,43 @@ LLTextureFetch::~LLTextureFetch()
mCommands.erase(mCommands.begin());
delete req;
}
+
+ if (mHttpOptions)
+ {
+ mHttpOptions->release();
+ mHttpOptions = NULL;
+ }
+
+ if (mHttpHeaders)
+ {
+ mHttpHeaders->release();
+ mHttpHeaders = NULL;
+ }
+
+ if (mHttpMetricsHeaders)
+ {
+ mHttpMetricsHeaders->release();
+ mHttpMetricsHeaders = NULL;
+ }
+
+ mHttpWaitResource.clear();
+
+ delete mHttpRequest;
+ mHttpRequest = NULL;
+
+ delete mFetchDebugger;
+ mFetchDebugger = NULL;
// ~LLQueuedThread() called here
}
-bool LLTextureFetch::createRequest(const std::string& url, const LLUUID& id, const LLHost& host, F32 priority,
+bool LLTextureFetch::createRequest(FTType f_type, const std::string& url, const LLUUID& id, const LLHost& host, F32 priority,
S32 w, S32 h, S32 c, S32 desired_discard, bool needs_aux, bool can_use_http)
{
+ if(mFetcherLocked)
+ {
+ return false;
+ }
if (mDebugPause)
{
return false;
@@ -1870,6 +2482,7 @@ bool LLTextureFetch::createRequest(const std::string& url, const LLUUID& id, con
std::string exten = gDirUtilp->getExtension(url);
if (!url.empty() && (!exten.empty() && LLImageBase::getCodecFromExtension(exten) != IMG_CODEC_J2C))
{
+ LL_DEBUGS("Texture") << "full request for " << id << " exten is not J2C: " << exten << llendl;
// Only do partial requests for J2C at the moment
desired_size = MAX_IMAGE_DATA_SIZE;
desired_discard = 0;
@@ -1891,6 +2504,8 @@ bool LLTextureFetch::createRequest(const std::string& url, const LLUUID& id, con
}
else
{
+ // If the requester knows nothing about the file, we fetch the smallest
+ // amount of data at the lowest resolution (highest discard level) possible.
desired_size = TEXTURE_CACHE_ENTRY_SIZE;
desired_discard = MAX_DISCARD_LEVEL;
}
@@ -1902,7 +2517,7 @@ bool LLTextureFetch::createRequest(const std::string& url, const LLUUID& id, con
{
return false; // need to wait for previous aborted request to complete
}
- worker->lockWorkMutex();
+ worker->lockWorkMutex(); // +Mw
worker->mActiveCount++;
worker->mNeedsAux = needs_aux;
worker->setImagePriority(priority);
@@ -1910,42 +2525,45 @@ bool LLTextureFetch::createRequest(const std::string& url, const LLUUID& id, con
worker->setCanUseHTTP(can_use_http) ;
if (!worker->haveWork())
{
- worker->mState = LLTextureFetchWorker::INIT;
- worker->unlockWorkMutex();
+ worker->setState(LLTextureFetchWorker::INIT);
+ worker->unlockWorkMutex(); // -Mw
worker->addWork(0, LLWorkerThread::PRIORITY_HIGH | worker->mWorkPriority);
}
else
{
- worker->unlockWorkMutex();
+ worker->unlockWorkMutex(); // -Mw
}
}
else
{
- worker = new LLTextureFetchWorker(this, url, id, host, priority, desired_discard, desired_size);
- lockQueue() ;
+ worker = new LLTextureFetchWorker(this, f_type, url, id, host, priority, desired_discard, desired_size);
+ lockQueue(); // +Mfq
mRequestMap[id] = worker;
- unlockQueue() ;
+ unlockQueue(); // -Mfq
- worker->lockWorkMutex();
+ worker->lockWorkMutex(); // +Mw
worker->mActiveCount++;
worker->mNeedsAux = needs_aux;
worker->setCanUseHTTP(can_use_http) ;
- worker->unlockWorkMutex();
+ worker->unlockWorkMutex(); // -Mw
}
-// llinfos << "REQUESTED: " << id << " Discard: " << desired_discard << llendl;
+ LL_DEBUGS("Texture") << "REQUESTED: " << id << " Discard: " << desired_discard << " size " << desired_size << llendl;
return true;
}
+
+// Threads: T* (but Ttf in practice)
+
// protected
void LLTextureFetch::addToNetworkQueue(LLTextureFetchWorker* worker)
{
- lockQueue() ;
+ lockQueue(); // +Mfq
bool in_request_map = (mRequestMap.find(worker->mID) != mRequestMap.end()) ;
- unlockQueue() ;
+ unlockQueue(); // -Mfq
- LLMutexLock lock(&mNetworkQueueMutex);
+ LLMutexLock lock(&mNetworkQueueMutex); // +Mfnq
if (in_request_map)
{
// only add to the queue if in the request map
@@ -1957,44 +2575,52 @@ void LLTextureFetch::addToNetworkQueue(LLTextureFetchWorker* worker)
{
iter1->second.erase(worker->mID);
}
-}
+} // -Mfnq
+// Threads: T*
void LLTextureFetch::removeFromNetworkQueue(LLTextureFetchWorker* worker, bool cancel)
{
- LLMutexLock lock(&mNetworkQueueMutex);
+ LLMutexLock lock(&mNetworkQueueMutex); // +Mfnq
size_t erased = mNetworkQueue.erase(worker->mID);
if (cancel && erased > 0)
{
mCancelQueue[worker->mHost].insert(worker->mID);
}
-}
+} // -Mfnq
+// Threads: T*
+//
// protected
void LLTextureFetch::addToHTTPQueue(const LLUUID& id)
{
- LLMutexLock lock(&mNetworkQueueMutex);
+ LLMutexLock lock(&mNetworkQueueMutex); // +Mfnq
mHTTPTextureQueue.insert(id);
mTotalHTTPRequests++;
-}
+} // -Mfnq
+// Threads: T*
void LLTextureFetch::removeFromHTTPQueue(const LLUUID& id, S32 received_size)
{
- LLMutexLock lock(&mNetworkQueueMutex);
+ LLMutexLock lock(&mNetworkQueueMutex); // +Mfnq
mHTTPTextureQueue.erase(id);
mHTTPTextureBits += received_size * 8; // Approximate - does not include header bits
-}
+} // -Mfnq
+// NB: If you change deleteRequest() you should probably make
+// parallel changes in removeRequest(). They're functionally
+// identical with only argument variations.
+//
+// Threads: T*
void LLTextureFetch::deleteRequest(const LLUUID& id, bool cancel)
{
- lockQueue() ;
+ lockQueue(); // +Mfq
LLTextureFetchWorker* worker = getWorkerAfterLock(id);
if (worker)
{
size_t erased_1 = mRequestMap.erase(worker->mID);
- unlockQueue() ;
+ unlockQueue(); // -Mfq
llassert_always(erased_1 > 0) ;
-
removeFromNetworkQueue(worker, cancel);
llassert_always(!(worker->getFlags(LLWorkerClass::WCF_DELETE_REQUESTED))) ;
@@ -2002,15 +2628,25 @@ void LLTextureFetch::deleteRequest(const LLUUID& id, bool cancel)
}
else
{
- unlockQueue() ;
+ unlockQueue(); // -Mfq
}
}
+// NB: If you change removeRequest() you should probably make
+// parallel changes in deleteRequest(). They're functionally
+// identical with only argument variations.
+//
+// Threads: T*
void LLTextureFetch::removeRequest(LLTextureFetchWorker* worker, bool cancel)
{
- lockQueue() ;
+ if(!worker)
+ {
+ return;
+ }
+
+ lockQueue(); // +Mfq
size_t erased_1 = mRequestMap.erase(worker->mID);
- unlockQueue() ;
+ unlockQueue(); // -Mfq
llassert_always(erased_1 > 0) ;
removeFromNetworkQueue(worker, cancel);
@@ -2019,34 +2655,57 @@ void LLTextureFetch::removeRequest(LLTextureFetchWorker* worker, bool cancel)
worker->scheduleDelete();
}
+void LLTextureFetch::deleteAllRequests()
+{
+ while(1)
+ {
+ lockQueue();
+ if(mRequestMap.empty())
+ {
+ unlockQueue() ;
+ break;
+ }
+
+ LLTextureFetchWorker* worker = mRequestMap.begin()->second;
+ unlockQueue() ;
+
+ removeRequest(worker, true);
+ }
+}
+
+// Threads: T*
S32 LLTextureFetch::getNumRequests()
{
- lockQueue() ;
+ lockQueue(); // +Mfq
S32 size = (S32)mRequestMap.size();
- unlockQueue() ;
+ unlockQueue(); // -Mfq
- return size ;
+ return size;
}
+// Threads: T*
S32 LLTextureFetch::getNumHTTPRequests()
{
- mNetworkQueueMutex.lock() ;
+ mNetworkQueueMutex.lock(); // +Mfq
S32 size = (S32)mHTTPTextureQueue.size();
- mNetworkQueueMutex.unlock() ;
+ mNetworkQueueMutex.unlock(); // -Mfq
- return size ;
+ return size;
}
+// Threads: T*
U32 LLTextureFetch::getTotalNumHTTPRequests()
{
- mNetworkQueueMutex.lock() ;
- U32 size = mTotalHTTPRequests ;
- mNetworkQueueMutex.unlock() ;
+ mNetworkQueueMutex.lock(); // +Mfq
+ U32 size = mTotalHTTPRequests;
+ mNetworkQueueMutex.unlock(); // -Mfq
- return size ;
+ return size;
}
// call lockQueue() first!
+// Threads: T*
+// Locks: Mfq
LLTextureFetchWorker* LLTextureFetch::getWorkerAfterLock(const LLUUID& id)
{
LLTextureFetchWorker* res = NULL;
@@ -2058,14 +2717,16 @@ LLTextureFetchWorker* LLTextureFetch::getWorkerAfterLock(const LLUUID& id)
return res;
}
+// Threads: T*
LLTextureFetchWorker* LLTextureFetch::getWorker(const LLUUID& id)
{
- LLMutexLock lock(&mQueueMutex) ;
+ LLMutexLock lock(&mQueueMutex); // +Mfq
- return getWorkerAfterLock(id) ;
-}
+ return getWorkerAfterLock(id);
+} // -Mfq
+// Threads: T*
bool LLTextureFetch::getRequestFinished(const LLUUID& id, S32& discard_level,
LLPointer<LLImageRaw>& raw, LLPointer<LLImageRaw>& aux)
{
@@ -2088,17 +2749,22 @@ bool LLTextureFetch::getRequestFinished(const LLUUID& id, S32& discard_level,
}
else if (worker->checkWork())
{
- worker->lockWorkMutex();
+ worker->lockWorkMutex(); // +Mw
discard_level = worker->mDecodedDiscard;
raw = worker->mRawImage;
aux = worker->mAuxImage;
+ F32 cache_read_time = worker->mCacheReadTime;
+ if (cache_read_time != 0.f)
+ {
+ sCacheReadLatency.addValue(cache_read_time * 1000.f);
+ }
res = true;
LL_DEBUGS("Texture") << id << ": Request Finished. State: " << worker->mState << " Discard: " << discard_level << LL_ENDL;
- worker->unlockWorkMutex();
+ worker->unlockWorkMutex(); // -Mw
}
else
{
- worker->lockWorkMutex();
+ worker->lockWorkMutex(); // +Mw
if ((worker->mDecodedDiscard >= 0) &&
(worker->mDecodedDiscard < discard_level || discard_level < 0) &&
(worker->mState >= LLTextureFetchWorker::WAIT_ON_WRITE))
@@ -2108,7 +2774,7 @@ bool LLTextureFetch::getRequestFinished(const LLUUID& id, S32& discard_level,
raw = worker->mRawImage;
aux = worker->mAuxImage;
}
- worker->unlockWorkMutex();
+ worker->unlockWorkMutex(); // -Mw
}
}
else
@@ -2118,15 +2784,16 @@ bool LLTextureFetch::getRequestFinished(const LLUUID& id, S32& discard_level,
return res;
}
+// Threads: T*
bool LLTextureFetch::updateRequestPriority(const LLUUID& id, F32 priority)
{
bool res = false;
LLTextureFetchWorker* worker = getWorker(id);
if (worker)
{
- worker->lockWorkMutex();
+ worker->lockWorkMutex(); // +Mw
worker->setImagePriority(priority);
- worker->unlockWorkMutex();
+ worker->unlockWorkMutex(); // -Mw
res = true;
}
return res;
@@ -2141,24 +2808,24 @@ bool LLTextureFetch::updateRequestPriority(const LLUUID& id, F32 priority)
// in step, at least until this can be refactored and
// the redundancy eliminated.
//
-// May be called from any thread
+// Threads: T*
//virtual
S32 LLTextureFetch::getPending()
{
S32 res;
- lockData();
+ lockData(); // +Ct
{
- LLMutexLock lock(&mQueueMutex);
+ LLMutexLock lock(&mQueueMutex); // +Mfq
res = mRequestQueue.size();
- res += mCurlPOSTRequestCount;
res += mCommands.size();
- }
- unlockData();
+ } // -Mfq
+ unlockData(); // -Ct
return res;
}
+// Locks: Ct
// virtual
bool LLTextureFetch::runCondition()
{
@@ -2173,56 +2840,65 @@ bool LLTextureFetch::runCondition()
bool have_no_commands(false);
{
- LLMutexLock lock(&mQueueMutex);
+ LLMutexLock lock(&mQueueMutex); // +Mfq
have_no_commands = mCommands.empty();
- }
-
- bool have_no_curl_requests(0 == mCurlPOSTRequestCount);
+ } // -Mfq
return ! (have_no_commands
- && have_no_curl_requests
&& (mRequestQueue.empty() && mIdleThread)); // From base class
}
//////////////////////////////////////////////////////////////////////////////
-// MAIN THREAD (unthreaded envs), WORKER THREAD (threaded envs)
+// Threads: Ttf
void LLTextureFetch::commonUpdate()
{
+ // Release waiters
+ releaseHttpWaiters();
+
// Run a cross-thread command, if any.
cmdDoWork();
- // Update Curl on same thread as mCurlGetRequest was constructed
- S32 processed = mCurlGetRequest->process();
- if (processed > 0)
+ // Deliver all completion notifications
+ LLCore::HttpStatus status = mHttpRequest->update(0);
+ if (! status)
{
- lldebugs << "processed: " << processed << " messages." << llendl;
+ LL_INFOS_ONCE("Texture") << "Problem during HTTP servicing. Reason: "
+ << status.toString()
+ << LL_ENDL;
}
}
-// MAIN THREAD
+// Threads: Tmain
+
//virtual
S32 LLTextureFetch::update(F32 max_time_ms)
{
- static LLCachedControl<F32> band_width(gSavedSettings,"ThrottleBandwidthKBPS");
+ static LLCachedControl<F32> band_width(gSavedSettings,"ThrottleBandwidthKBPS", 500.0);
{
- mNetworkQueueMutex.lock() ;
- mMaxBandwidth = band_width ;
+ mNetworkQueueMutex.lock(); // +Mfnq
+ mMaxBandwidth = band_width;
- gTextureList.sTextureBits += mHTTPTextureBits ;
- mHTTPTextureBits = 0 ;
+ gTextureList.sTextureBits += mHTTPTextureBits;
+ mHTTPTextureBits = 0;
- mNetworkQueueMutex.unlock() ;
+ mNetworkQueueMutex.unlock(); // -Mfnq
}
S32 res = LLWorkerThread::update(max_time_ms);
if (!mDebugPause)
{
- sendRequestListToSimulators();
+ // this is the startup state when send_complete_agent_movement() message is sent.
+ // Before this, the RequestImages message sent by sendRequestListToSimulators
+ // won't work so don't bother trying
+ if (LLStartUp::getStartupState() > STATE_AGENT_SEND)
+ {
+ sendRequestListToSimulators();
+ }
}
if (!mThreaded)
@@ -2230,10 +2906,17 @@ S32 LLTextureFetch::update(F32 max_time_ms)
commonUpdate();
}
+ if (mFetchDebugger)
+ {
+ mFetchDebugger->tryToStopDebug(); //check if need to stop debugger.
+ }
+
return res;
}
-//called in the MAIN thread after the TextureCacheThread shuts down.
+// called in the MAIN thread after the TextureCacheThread shuts down.
+//
+// Threads: Tmain
void LLTextureFetch::shutDownTextureCacheThread()
{
if(mTextureCache)
@@ -2243,7 +2926,9 @@ void LLTextureFetch::shutDownTextureCacheThread()
}
}
-//called in the MAIN thread after the ImageDecodeThread shuts down.
+// called in the MAIN thread after the ImageDecodeThread shuts down.
+//
+// Threads: Tmain
void LLTextureFetch::shutDownImageDecodeThread()
{
if(mImageDecodeThread)
@@ -2253,26 +2938,27 @@ void LLTextureFetch::shutDownImageDecodeThread()
}
}
-// WORKER THREAD
+// Threads: Ttf
void LLTextureFetch::startThread()
{
- // Construct mCurlGetRequest from Worker Thread
- mCurlGetRequest = new LLCurlRequest();
}
-// WORKER THREAD
+// Threads: Ttf
void LLTextureFetch::endThread()
{
- // Destroy mCurlGetRequest from Worker Thread
- delete mCurlGetRequest;
- mCurlGetRequest = NULL;
+ LL_INFOS("Texture") << "CacheReads: " << mTotalCacheReadCount
+ << ", CacheWrites: " << mTotalCacheWriteCount
+ << ", ResWaits: " << mTotalResourceWaitCount
+ << ", TotalHTTPReq: " << getTotalNumHTTPRequests()
+ << LL_ENDL;
}
-// WORKER THREAD
+// Threads: Ttf
void LLTextureFetch::threadedUpdate()
{
- llassert_always(mCurlGetRequest);
-
+ llassert_always(mHttpRequest);
+
+#if 0
// Limit update frequency
const F32 PROCESS_TIME = 0.05f;
static LLFrameTimer process_timer;
@@ -2281,9 +2967,10 @@ void LLTextureFetch::threadedUpdate()
return;
}
process_timer.reset();
+#endif
commonUpdate();
-
+
#if 0
const F32 INFO_TIME = 1.0f;
static LLFrameTimer info_timer;
@@ -2297,11 +2984,11 @@ void LLTextureFetch::threadedUpdate()
}
}
#endif
-
}
//////////////////////////////////////////////////////////////////////////////
+// Threads: Tmain
void LLTextureFetch::sendRequestListToSimulators()
{
// All requests
@@ -2327,48 +3014,48 @@ void LLTextureFetch::sendRequestListToSimulators()
typedef std::map< LLHost, request_list_t > work_request_map_t;
work_request_map_t requests;
{
- LLMutexLock lock2(&mNetworkQueueMutex);
- for (queue_t::iterator iter = mNetworkQueue.begin(); iter != mNetworkQueue.end(); )
- {
- queue_t::iterator curiter = iter++;
- LLTextureFetchWorker* req = getWorker(*curiter);
- if (!req)
- {
- mNetworkQueue.erase(curiter);
- continue; // paranoia
- }
- if ((req->mState != LLTextureFetchWorker::LOAD_FROM_NETWORK) &&
- (req->mState != LLTextureFetchWorker::LOAD_FROM_SIMULATOR))
- {
- // We already received our URL, remove from the queue
- llwarns << "Worker: " << req->mID << " in mNetworkQueue but in wrong state: " << req->mState << llendl;
- mNetworkQueue.erase(curiter);
- continue;
- }
- if (req->mID == mDebugID)
- {
- mDebugCount++; // for setting breakpoints
- }
- if (req->mSentRequest == LLTextureFetchWorker::SENT_SIM &&
- req->mTotalPackets > 0 &&
- req->mLastPacket >= req->mTotalPackets-1)
+ LLMutexLock lock2(&mNetworkQueueMutex); // +Mfnq
+ for (queue_t::iterator iter = mNetworkQueue.begin(); iter != mNetworkQueue.end(); )
{
- // We have all the packets... make sure this is high priority
+ queue_t::iterator curiter = iter++;
+ LLTextureFetchWorker* req = getWorker(*curiter);
+ if (!req)
+ {
+ mNetworkQueue.erase(curiter);
+ continue; // paranoia
+ }
+ if ((req->mState != LLTextureFetchWorker::LOAD_FROM_NETWORK) &&
+ (req->mState != LLTextureFetchWorker::LOAD_FROM_SIMULATOR))
+ {
+ // We already received our URL, remove from the queue
+ llwarns << "Worker: " << req->mID << " in mNetworkQueue but in wrong state: " << req->mState << llendl;
+ mNetworkQueue.erase(curiter);
+ continue;
+ }
+ if (req->mID == mDebugID)
+ {
+ mDebugCount++; // for setting breakpoints
+ }
+ if (req->mSentRequest == LLTextureFetchWorker::SENT_SIM &&
+ req->mTotalPackets > 0 &&
+ req->mLastPacket >= req->mTotalPackets-1)
+ {
+ // We have all the packets... make sure this is high priority
// req->setPriority(LLWorkerThread::PRIORITY_HIGH | req->mWorkPriority);
- continue;
- }
- F32 elapsed = req->mRequestedTimer.getElapsedTimeF32();
- {
- F32 delta_priority = llabs(req->mRequestedPriority - req->mImagePriority);
- if ((req->mSimRequestedDiscard != req->mDesiredDiscard) ||
- (delta_priority > MIN_DELTA_PRIORITY && elapsed >= MIN_REQUEST_TIME) ||
- (elapsed >= SIM_LAZY_FLUSH_TIMEOUT))
+ continue;
+ }
+ F32 elapsed = req->mRequestedTimer.getElapsedTimeF32();
{
- requests[req->mHost].insert(req);
+ F32 delta_priority = llabs(req->mRequestedPriority - req->mImagePriority);
+ if ((req->mSimRequestedDiscard != req->mDesiredDiscard) ||
+ (delta_priority > MIN_DELTA_PRIORITY && elapsed >= MIN_REQUEST_TIME) ||
+ (elapsed >= SIM_LAZY_FLUSH_TIMEOUT))
+ {
+ requests[req->mHost].insert(req);
+ }
}
}
- }
- }
+ } // -Mfnq
for (work_request_map_t::iterator iter1 = requests.begin();
iter1 != requests.end(); ++iter1)
@@ -2391,9 +3078,9 @@ void LLTextureFetch::sendRequestListToSimulators()
if (req->mSentRequest != LLTextureFetchWorker::SENT_SIM)
{
// Initialize packet data based on data read from cache
- req->lockWorkMutex();
+ req->lockWorkMutex(); // +Mw
req->setupPacketData();
- req->unlockWorkMutex();
+ req->unlockWorkMutex(); // -Mw
}
if (0 == sim_request_count)
{
@@ -2412,8 +3099,8 @@ void LLTextureFetch::sendRequestListToSimulators()
// llinfos << "IMAGE REQUEST: " << req->mID << " Discard: " << req->mDesiredDiscard
// << " Packet: " << packet << " Priority: " << req->mImagePriority << llendl;
- static LLCachedControl<bool> log_to_viewer_log(gSavedSettings,"LogTextureDownloadsToViewerLog");
- static LLCachedControl<bool> log_to_sim(gSavedSettings,"LogTextureDownloadsToSimulator");
+ static LLCachedControl<bool> log_to_viewer_log(gSavedSettings,"LogTextureDownloadsToViewerLog", false);
+ static LLCachedControl<bool> log_to_sim(gSavedSettings,"LogTextureDownloadsToSimulator", false);
if (log_to_viewer_log || log_to_sim)
{
mTextureInfo.setRequestStartTime(req->mID, LLTimer::getTotalTime());
@@ -2422,12 +3109,12 @@ void LLTextureFetch::sendRequestListToSimulators()
mTextureInfo.setRequestType(req->mID, LLTextureInfoDetails::REQUEST_TYPE_UDP);
}
- req->lockWorkMutex();
+ req->lockWorkMutex(); // +Mw
req->mSentRequest = LLTextureFetchWorker::SENT_SIM;
req->mSimRequestedDiscard = req->mDesiredDiscard;
req->mRequestedPriority = req->mImagePriority;
req->mRequestedTimer.reset();
- req->unlockWorkMutex();
+ req->unlockWorkMutex(); // -Mw
sim_request_count++;
if (sim_request_count >= IMAGES_PER_REQUEST)
{
@@ -2448,55 +3135,57 @@ void LLTextureFetch::sendRequestListToSimulators()
// Send cancelations
{
- LLMutexLock lock2(&mNetworkQueueMutex);
- if (gMessageSystem && !mCancelQueue.empty())
- {
- for (cancel_queue_t::iterator iter1 = mCancelQueue.begin();
- iter1 != mCancelQueue.end(); ++iter1)
+ LLMutexLock lock2(&mNetworkQueueMutex); // +Mfnq
+ if (gMessageSystem && !mCancelQueue.empty())
{
- LLHost host = iter1->first;
- if (host == LLHost::invalid)
+ for (cancel_queue_t::iterator iter1 = mCancelQueue.begin();
+ iter1 != mCancelQueue.end(); ++iter1)
{
- host = gAgent.getRegionHost();
- }
- S32 request_count = 0;
- for (queue_t::iterator iter2 = iter1->second.begin();
- iter2 != iter1->second.end(); ++iter2)
- {
- if (0 == request_count)
+ LLHost host = iter1->first;
+ if (host == LLHost::invalid)
{
- gMessageSystem->newMessageFast(_PREHASH_RequestImage);
- gMessageSystem->nextBlockFast(_PREHASH_AgentData);
- gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ host = gAgent.getRegionHost();
}
- gMessageSystem->nextBlockFast(_PREHASH_RequestImage);
- gMessageSystem->addUUIDFast(_PREHASH_Image, *iter2);
- gMessageSystem->addS8Fast(_PREHASH_DiscardLevel, -1);
- gMessageSystem->addF32Fast(_PREHASH_DownloadPriority, 0);
- gMessageSystem->addU32Fast(_PREHASH_Packet, 0);
- gMessageSystem->addU8Fast(_PREHASH_Type, 0);
+ S32 request_count = 0;
+ for (queue_t::iterator iter2 = iter1->second.begin();
+ iter2 != iter1->second.end(); ++iter2)
+ {
+ if (0 == request_count)
+ {
+ gMessageSystem->newMessageFast(_PREHASH_RequestImage);
+ gMessageSystem->nextBlockFast(_PREHASH_AgentData);
+ gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ }
+ gMessageSystem->nextBlockFast(_PREHASH_RequestImage);
+ gMessageSystem->addUUIDFast(_PREHASH_Image, *iter2);
+ gMessageSystem->addS8Fast(_PREHASH_DiscardLevel, -1);
+ gMessageSystem->addF32Fast(_PREHASH_DownloadPriority, 0);
+ gMessageSystem->addU32Fast(_PREHASH_Packet, 0);
+ gMessageSystem->addU8Fast(_PREHASH_Type, 0);
// llinfos << "CANCELING IMAGE REQUEST: " << (*iter2) << llendl;
- request_count++;
- if (request_count >= IMAGES_PER_REQUEST)
+ request_count++;
+ if (request_count >= IMAGES_PER_REQUEST)
+ {
+ gMessageSystem->sendSemiReliable(host, NULL, NULL);
+ request_count = 0;
+ }
+ }
+ if (request_count > 0 && request_count < IMAGES_PER_REQUEST)
{
gMessageSystem->sendSemiReliable(host, NULL, NULL);
- request_count = 0;
}
}
- if (request_count > 0 && request_count < IMAGES_PER_REQUEST)
- {
- gMessageSystem->sendSemiReliable(host, NULL, NULL);
- }
+ mCancelQueue.clear();
}
- mCancelQueue.clear();
- }
- }
+ } // -Mfnq
}
//////////////////////////////////////////////////////////////////////////////
+// Threads: T*
+// Locks: Mw
bool LLTextureFetchWorker::insertPacket(S32 index, U8* data, S32 size)
{
mRequestedTimer.reset();
@@ -2529,6 +3218,31 @@ bool LLTextureFetchWorker::insertPacket(S32 index, U8* data, S32 size)
return true;
}
+void LLTextureFetchWorker::setState(e_state new_state)
+{
+ static const char* e_state_name[] =
+ {
+ "INVALID",
+ "INIT",
+ "LOAD_FROM_TEXTURE_CACHE",
+ "CACHE_POST",
+ "LOAD_FROM_NETWORK",
+ "LOAD_FROM_SIMULATOR",
+ "WAIT_HTTP_RESOURCE",
+ "WAIT_HTTP_RESOURCE2",
+ "SEND_HTTP_REQ",
+ "WAIT_HTTP_REQ",
+ "DECODE_IMAGE",
+ "DECODE_IMAGE_UPDATE",
+ "WRITE_TO_CACHE",
+ "WAIT_ON_WRITE",
+ "DONE"
+ };
+ LL_DEBUGS("Texture") << "id: " << mID << " FTType: " << mFTType << " disc: " << mDesiredDiscard << " sz: " << mDesiredSize << " state: " << e_state_name[mState] << " => " << e_state_name[new_state] << llendl;
+ mState = new_state;
+}
+
+// Threads: T*
bool LLTextureFetch::receiveImageHeader(const LLHost& host, const LLUUID& id, U8 codec, U16 packets, U32 totalbytes,
U16 data_size, U8* data)
{
@@ -2563,15 +3277,19 @@ bool LLTextureFetch::receiveImageHeader(const LLHost& host, const LLUUID& id, U8
}
if (!res)
{
+ mNetworkQueueMutex.lock(); // +Mfnq
++mBadPacketCount;
- mNetworkQueueMutex.lock() ;
mCancelQueue[host].insert(id);
- mNetworkQueueMutex.unlock() ;
+ mNetworkQueueMutex.unlock(); // -Mfnq
return false;
}
+ LLViewerStatsRecorder::instance().textureFetch(data_size);
+ LLViewerStatsRecorder::instance().log(0.1f);
+
worker->lockWorkMutex();
+
// Copy header data into image object
worker->mImageCodec = codec;
worker->mTotalPackets = packets;
@@ -2580,11 +3298,13 @@ bool LLTextureFetch::receiveImageHeader(const LLHost& host, const LLUUID& id, U8
llassert_always(data_size == FIRST_PACKET_SIZE || data_size == worker->mFileSize);
res = worker->insertPacket(0, data, data_size);
worker->setPriority(LLWorkerThread::PRIORITY_HIGH | worker->mWorkPriority);
- worker->mState = LLTextureFetchWorker::LOAD_FROM_SIMULATOR;
- worker->unlockWorkMutex();
+ worker->setState(LLTextureFetchWorker::LOAD_FROM_SIMULATOR);
+ worker->unlockWorkMutex(); // -Mw
return res;
}
+
+// Threads: T*
bool LLTextureFetch::receiveImagePacket(const LLHost& host, const LLUUID& id, U16 packet_num, U16 data_size, U8* data)
{
LLTextureFetchWorker* worker = getWorker(id);
@@ -2609,14 +3329,18 @@ bool LLTextureFetch::receiveImagePacket(const LLHost& host, const LLUUID& id, U1
}
if (!res)
{
+ mNetworkQueueMutex.lock(); // +Mfnq
++mBadPacketCount;
- mNetworkQueueMutex.lock() ;
mCancelQueue[host].insert(id);
- mNetworkQueueMutex.unlock() ;
+ mNetworkQueueMutex.unlock(); // -Mfnq
return false;
}
+
+ LLViewerStatsRecorder::instance().textureFetch(data_size);
+ LLViewerStatsRecorder::instance().log(0.1f);
worker->lockWorkMutex();
+
res = worker->insertPacket(packet_num, data, data_size);
@@ -2624,7 +3348,7 @@ bool LLTextureFetch::receiveImagePacket(const LLHost& host, const LLUUID& id, U1
(worker->mState == LLTextureFetchWorker::LOAD_FROM_NETWORK))
{
worker->setPriority(LLWorkerThread::PRIORITY_HIGH | worker->mWorkPriority);
- worker->mState = LLTextureFetchWorker::LOAD_FROM_SIMULATOR;
+ worker->setState(LLTextureFetchWorker::LOAD_FROM_SIMULATOR);
}
else
{
@@ -2633,10 +3357,10 @@ bool LLTextureFetch::receiveImagePacket(const LLHost& host, const LLUUID& id, U1
removeFromNetworkQueue(worker, true); // failsafe
}
- if(packet_num >= (worker->mTotalPackets - 1))
+ if (packet_num >= (worker->mTotalPackets - 1))
{
- static LLCachedControl<bool> log_to_viewer_log(gSavedSettings,"LogTextureDownloadsToViewerLog");
- static LLCachedControl<bool> log_to_sim(gSavedSettings,"LogTextureDownloadsToSimulator");
+ static LLCachedControl<bool> log_to_viewer_log(gSavedSettings,"LogTextureDownloadsToViewerLog", false);
+ static LLCachedControl<bool> log_to_sim(gSavedSettings,"LogTextureDownloadsToSimulator", false);
if (log_to_viewer_log || log_to_sim)
{
@@ -2645,12 +3369,14 @@ bool LLTextureFetch::receiveImagePacket(const LLHost& host, const LLUUID& id, U1
mTextureInfo.setRequestCompleteTimeAndLog(id, timeNow);
}
}
- worker->unlockWorkMutex();
+ worker->unlockWorkMutex(); // -Mw
return res;
}
//////////////////////////////////////////////////////////////////////////////
+
+// Threads: T*
BOOL LLTextureFetch::isFromLocalCache(const LLUUID& id)
{
BOOL from_cache = FALSE ;
@@ -2658,14 +3384,15 @@ BOOL LLTextureFetch::isFromLocalCache(const LLUUID& id)
LLTextureFetchWorker* worker = getWorker(id);
if (worker)
{
- worker->lockWorkMutex() ;
- from_cache = worker->mInLocalCache ;
- worker->unlockWorkMutex() ;
+ worker->lockWorkMutex(); // +Mw
+ from_cache = worker->mInLocalCache;
+ worker->unlockWorkMutex(); // -Mw
}
return from_cache ;
}
+// Threads: T*
S32 LLTextureFetch::getFetchState(const LLUUID& id, F32& data_progress_p, F32& requested_priority_p,
U32& fetch_priority_p, F32& fetch_dtime_p, F32& request_dtime_p, bool& can_use_http)
{
@@ -2679,7 +3406,7 @@ S32 LLTextureFetch::getFetchState(const LLUUID& id, F32& data_progress_p, F32& r
LLTextureFetchWorker* worker = getWorker(id);
if (worker && worker->haveWork())
{
- worker->lockWorkMutex();
+ worker->lockWorkMutex(); // +Mw
state = worker->mState;
fetch_dtime = worker->mFetchTimer.getElapsedTimeF32();
request_dtime = worker->mRequestedTimer.getElapsedTimeF32();
@@ -2706,7 +3433,7 @@ S32 LLTextureFetch::getFetchState(const LLUUID& id, F32& data_progress_p, F32& r
}
fetch_priority = worker->getPriority();
can_use_http = worker->getCanUseHTTP() ;
- worker->unlockWorkMutex();
+ worker->unlockWorkMutex(); // -Mw
}
data_progress_p = data_progress;
requested_priority_p = requested_priority;
@@ -2730,12 +3457,219 @@ void LLTextureFetch::dump()
<< " STATE: " << worker->sStateDescs[worker->mState]
<< llendl;
}
+
+ llinfos << "LLTextureFetch ACTIVE_HTTP:" << llendl;
+ for (queue_t::const_iterator iter(mHTTPTextureQueue.begin());
+ mHTTPTextureQueue.end() != iter;
+ ++iter)
+ {
+ llinfos << " ID: " << (*iter) << llendl;
+ }
+
+ llinfos << "LLTextureFetch WAIT_HTTP_RESOURCE:" << llendl;
+ for (wait_http_res_queue_t::const_iterator iter(mHttpWaitResource.begin());
+ mHttpWaitResource.end() != iter;
+ ++iter)
+ {
+ llinfos << " ID: " << (*iter) << llendl;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+// HTTP Resource Waiting Methods
+
+// Threads: Ttf
+void LLTextureFetch::addHttpWaiter(const LLUUID & tid)
+{
+ mNetworkQueueMutex.lock(); // +Mfnq
+ mHttpWaitResource.insert(tid);
+ mNetworkQueueMutex.unlock(); // -Mfnq
+}
+
+// Threads: Ttf
+void LLTextureFetch::removeHttpWaiter(const LLUUID & tid)
+{
+ mNetworkQueueMutex.lock(); // +Mfnq
+ wait_http_res_queue_t::iterator iter(mHttpWaitResource.find(tid));
+ if (mHttpWaitResource.end() != iter)
+ {
+ mHttpWaitResource.erase(iter);
+ }
+ mNetworkQueueMutex.unlock(); // -Mfnq
+}
+
+// Threads: T*
+bool LLTextureFetch::isHttpWaiter(const LLUUID & tid)
+{
+ mNetworkQueueMutex.lock(); // +Mfnq
+ wait_http_res_queue_t::iterator iter(mHttpWaitResource.find(tid));
+ const bool ret(mHttpWaitResource.end() != iter);
+ mNetworkQueueMutex.unlock(); // -Mfnq
+ return ret;
+}
+
+// Release as many requests as permitted from the WAIT_HTTP_RESOURCE2
+// state to the SEND_HTTP_REQ state based on their current priority.
+//
+// This data structures and code associated with this looks a bit
+// indirect and naive but it's done in the name of safety. An
+// ordered container may become invalid from time to time due to
+// priority changes caused by actions in other threads. State itself
+// could also suffer the same fate with canceled operations. Even
+// done this way, I'm not fully trusting we're truly safe. This
+// module is due for a major refactoring and we'll deal with it then.
+//
+// Threads: Ttf
+// Locks: -Mw (must not hold any worker when called)
+void LLTextureFetch::releaseHttpWaiters()
+{
+ // Use mHttpSemaphore rather than mHTTPTextureQueue.size()
+ // to avoid a lock.
+ if (mHttpSemaphore < (HTTP_REQUESTS_IN_QUEUE_HIGH_WATER - HTTP_REQUESTS_IN_QUEUE_LOW_WATER))
+ return;
+
+ // Quickly make a copy of all the LLUIDs. Get off the
+ // mutex as early as possible.
+ typedef std::vector<LLUUID> uuid_vec_t;
+ uuid_vec_t tids;
+
+ {
+ LLMutexLock lock(&mNetworkQueueMutex); // +Mfnq
+
+ if (mHttpWaitResource.empty())
+ return;
+ tids.reserve(mHttpWaitResource.size());
+ tids.assign(mHttpWaitResource.begin(), mHttpWaitResource.end());
+ } // -Mfnq
+
+ // Now lookup the UUUIDs to find valid requests and sort
+ // them in priority order, highest to lowest. We're going
+ // to modify priority later as a side-effect of releasing
+ // these objects. That, in turn, would violate the partial
+ // ordering assumption of std::set, std::map, etc. so we
+ // don't use those containers. We use a vector and an explicit
+ // sort to keep the containers valid later.
+ typedef std::vector<LLTextureFetchWorker *> worker_list_t;
+ worker_list_t tids2;
+
+ tids2.reserve(tids.size());
+ for (uuid_vec_t::iterator iter(tids.begin());
+ tids.end() != iter;
+ ++iter)
+ {
+ LLTextureFetchWorker * worker(getWorker(* iter));
+ if (worker)
+ {
+ tids2.push_back(worker);
+ }
+ else
+ {
+ // If worker isn't found, this should be due to a request
+ // for deletion. We signal our recognition that this
+ // uuid shouldn't be used for resource waiting anymore by
+ // erasing it from the resource waiter list. That allows
+ // deleteOK to do final deletion on the worker.
+ removeHttpWaiter(* iter);
+ }
+ }
+ tids.clear();
+
+ // Sort into priority order, if necessary and only as much as needed
+ if (tids2.size() > mHttpSemaphore)
+ {
+ LLTextureFetchWorker::Compare compare;
+ std::partial_sort(tids2.begin(), tids2.begin() + mHttpSemaphore, tids2.end(), compare);
+ }
+
+ // Release workers up to the high water mark. Since we aren't
+ // holding any locks at this point, we can be in competition
+ // with other callers. Do defensive things like getting
+ // refreshed counts of requests and checking if someone else
+ // has moved any worker state around....
+ for (worker_list_t::iterator iter2(tids2.begin()); tids2.end() != iter2; ++iter2)
+ {
+ LLTextureFetchWorker * worker(* iter2);
+
+ worker->lockWorkMutex(); // +Mw
+ if (LLTextureFetchWorker::WAIT_HTTP_RESOURCE2 != worker->mState)
+ {
+ // Not in expected state, remove it, try the next one
+ worker->unlockWorkMutex(); // -Mw
+ LL_WARNS("Texture") << "Resource-waited texture " << worker->mID
+ << " in unexpected state: " << worker->mState
+ << ". Removing from wait list."
+ << LL_ENDL;
+ removeHttpWaiter(worker->mID);
+ continue;
+ }
+
+ if (! worker->acquireHttpSemaphore())
+ {
+ // Out of active slots, quit
+ worker->unlockWorkMutex(); // -Mw
+ break;
+ }
+
+ worker->setState(LLTextureFetchWorker::SEND_HTTP_REQ);
+ worker->setPriority(LLWorkerThread::PRIORITY_HIGH | worker->mWorkPriority);
+ worker->unlockWorkMutex(); // -Mw
+
+ removeHttpWaiter(worker->mID);
+ }
+}
+
+// Threads: T*
+void LLTextureFetch::cancelHttpWaiters()
+{
+ mNetworkQueueMutex.lock(); // +Mfnq
+ mHttpWaitResource.clear();
+ mNetworkQueueMutex.unlock(); // -Mfnq
+}
+
+// Threads: T*
+int LLTextureFetch::getHttpWaitersCount()
+{
+ mNetworkQueueMutex.lock(); // +Mfnq
+ int ret(mHttpWaitResource.size());
+ mNetworkQueueMutex.unlock(); // -Mfnq
+ return ret;
+}
+
+
+// Threads: T*
+void LLTextureFetch::updateStateStats(U32 cache_read, U32 cache_write, U32 res_wait)
+{
+ LLMutexLock lock(&mQueueMutex); // +Mfq
+
+ mTotalCacheReadCount += cache_read;
+ mTotalCacheWriteCount += cache_write;
+ mTotalResourceWaitCount += res_wait;
+} // -Mfq
+
+
+// Threads: T*
+void LLTextureFetch::getStateStats(U32 * cache_read, U32 * cache_write, U32 * res_wait)
+{
+ U32 ret1(0U), ret2(0U), ret3(0U);
+
+ {
+ LLMutexLock lock(&mQueueMutex); // +Mfq
+ ret1 = mTotalCacheReadCount;
+ ret2 = mTotalCacheWriteCount;
+ ret3 = mTotalResourceWaitCount;
+ } // -Mfq
+
+ *cache_read = ret1;
+ *cache_write = ret2;
+ *res_wait = ret3;
}
//////////////////////////////////////////////////////////////////////////////
// cross-thread command methods
+// Threads: T*
void LLTextureFetch::commandSetRegion(U64 region_handle)
{
TFReqSetRegion * req = new TFReqSetRegion(region_handle);
@@ -2743,6 +3677,7 @@ void LLTextureFetch::commandSetRegion(U64 region_handle)
cmdEnqueue(req);
}
+// Threads: T*
void LLTextureFetch::commandSendMetrics(const std::string & caps_url,
const LLUUID & session_id,
const LLUUID & agent_id,
@@ -2753,6 +3688,7 @@ void LLTextureFetch::commandSendMetrics(const std::string & caps_url,
cmdEnqueue(req);
}
+// Threads: T*
void LLTextureFetch::commandDataBreak()
{
// The pedantically correct way to implement this is to create a command
@@ -2763,30 +3699,33 @@ void LLTextureFetch::commandDataBreak()
LLTextureFetch::svMetricsDataBreak = true;
}
+// Threads: T*
void LLTextureFetch::cmdEnqueue(TFRequest * req)
{
- lockQueue();
+ lockQueue(); // +Mfq
mCommands.push_back(req);
- unlockQueue();
+ unlockQueue(); // -Mfq
unpause();
}
+// Threads: T*
LLTextureFetch::TFRequest * LLTextureFetch::cmdDequeue()
{
TFRequest * ret = 0;
- lockQueue();
+ lockQueue(); // +Mfq
if (! mCommands.empty())
{
ret = mCommands.front();
mCommands.erase(mCommands.begin());
}
- unlockQueue();
+ unlockQueue(); // -Mfq
return ret;
}
+// Threads: Ttf
void LLTextureFetch::cmdDoWork()
{
if (mDebugPause)
@@ -2803,7 +3742,6 @@ void LLTextureFetch::cmdDoWork()
}
}
-
//////////////////////////////////////////////////////////////////////////////
// Private (anonymous) class methods implementing the command scheme.
@@ -2811,6 +3749,38 @@ void LLTextureFetch::cmdDoWork()
namespace
{
+
+// Example of a simple notification handler for metrics
+// delivery notification. Earlier versions of the code used
+// a Responder that tried harder to detect delivery breaks
+// but it really isn't that important. If someone wants to
+// revisit that effort, here is a place to start.
+class AssetReportHandler : public LLCore::HttpHandler
+{
+public:
+
+ // Threads: Ttf
+ virtual void onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response)
+ {
+ LLCore::HttpStatus status(response->getStatus());
+
+ if (status)
+ {
+ LL_DEBUGS("Texture") << "Successfully delivered asset metrics to grid."
+ << LL_ENDL;
+ }
+ else
+ {
+ LL_WARNS("Texture") << "Error delivering asset metrics to grid. Status: "
+ << status.toHex()
+ << ", Reason: " << status.toString() << LL_ENDL;
+ }
+ }
+}; // end class AssetReportHandler
+
+AssetReportHandler stats_handler;
+
+
/**
* Implements the 'Set Region' command.
*
@@ -2841,73 +3811,8 @@ TFReqSendMetrics::~TFReqSendMetrics()
bool
TFReqSendMetrics::doWork(LLTextureFetch * fetcher)
{
- /*
- * HTTP POST responder. Doesn't do much but tries to
- * detect simple breaks in recording the metrics stream.
- *
- * The 'volatile' modifiers don't indicate signals,
- * mmap'd memory or threads, really. They indicate that
- * the referenced data is part of a pseudo-closure for
- * this responder rather than being required for correct
- * operation.
- *
- * We don't try very hard with the POST request. We give
- * it one shot and that's more-or-less it. With a proper
- * refactoring of the LLQueuedThread usage, these POSTs
- * could be put in a request object and made more reliable.
- */
- class lcl_responder : public LLCurl::Responder
- {
- public:
- lcl_responder(LLTextureFetch * fetcher,
- S32 expected_sequence,
- volatile const S32 & live_sequence,
- volatile bool & reporting_break,
- volatile bool & reporting_started)
- : LLCurl::Responder(),
- mFetcher(fetcher),
- mExpectedSequence(expected_sequence),
- mLiveSequence(live_sequence),
- mReportingBreak(reporting_break),
- mReportingStarted(reporting_started)
- {
- mFetcher->incrCurlPOSTCount();
- }
-
- ~lcl_responder()
- {
- mFetcher->decrCurlPOSTCount();
- }
-
- // virtual
- void error(U32 status_num, const std::string & reason)
- {
- if (mLiveSequence == mExpectedSequence)
- {
- mReportingBreak = true;
- }
- LL_WARNS("Texture") << "Break in metrics stream due to POST failure to metrics collection service. Reason: "
- << reason << LL_ENDL;
- }
-
- // virtual
- void result(const LLSD & content)
- {
- if (mLiveSequence == mExpectedSequence)
- {
- mReportingBreak = false;
- mReportingStarted = true;
- }
- }
-
- private:
- LLTextureFetch * mFetcher;
- S32 mExpectedSequence;
- volatile const S32 & mLiveSequence;
- volatile bool & mReportingBreak;
- volatile bool & mReportingStarted;
-
- }; // class lcl_responder
+ static const U32 report_priority(1);
+ static LLCore::HttpHandler * const handler(fetcher->isQAMode() || true ? &stats_handler : NULL);
if (! gViewerAssetStatsThread1)
return true;
@@ -2935,21 +3840,26 @@ TFReqSendMetrics::doWork(LLTextureFetch * fetcher)
// Update sequence number
if (S32_MAX == ++report_sequence)
report_sequence = 0;
-
+ reporting_started = true;
+
// Limit the size of the stats report if necessary.
merged_llsd["truncated"] = truncate_viewer_metrics(10, merged_llsd);
if (! mCapsURL.empty())
{
- LLCurlRequest::headers_t headers;
- fetcher->getCurlRequest().post(mCapsURL,
- headers,
- merged_llsd,
- new lcl_responder(fetcher,
- report_sequence,
- report_sequence,
- LLTextureFetch::svMetricsDataBreak,
- reporting_started));
+ LLCore::BufferArray * ba = new LLCore::BufferArray;
+ LLCore::BufferArrayStream bas(ba);
+ LLSDSerialize::toXML(merged_llsd, bas);
+
+ fetcher->getHttpRequest().requestPost(fetcher->getPolicyClass(),
+ report_priority,
+ mCapsURL,
+ ba,
+ NULL,
+ fetcher->getMetricsHeaders(),
+ handler);
+ ba->release();
+ LLTextureFetch::svMetricsDataBreak = false;
}
else
{
@@ -2959,7 +3869,7 @@ TFReqSendMetrics::doWork(LLTextureFetch * fetcher)
// In QA mode, Metrics submode, log the result for ease of testing
if (fetcher->isQAMode())
{
- LL_INFOS("Textures") << merged_llsd << LL_ENDL;
+ LL_INFOS("Textures") << ll_pretty_print_sd(merged_llsd) << LL_ENDL;
}
gViewerAssetStatsThread1->reset();
@@ -3008,4 +3918,951 @@ truncate_viewer_metrics(int max_regions, LLSD & metrics)
} // end of anonymous namespace
+///////////////////////////////////////////////////////////////////////////////////////////
+//Start LLTextureFetchDebugger
+///////////////////////////////////////////////////////////////////////////////////////////
+//---------------------
+class LLDebuggerCacheReadResponder : public LLTextureCache::ReadResponder
+{
+public:
+ LLDebuggerCacheReadResponder(LLTextureFetchDebugger* debugger, S32 id, LLImageFormatted* image)
+ : mDebugger(debugger), mID(id)
+ {
+ setImage(image);
+ }
+ virtual void completed(bool success)
+ {
+ mDebugger->callbackCacheRead(mID, success, mFormattedImage, mImageSize, mImageLocal);
+ }
+private:
+ LLTextureFetchDebugger* mDebugger;
+ S32 mID;
+};
+
+class LLDebuggerCacheWriteResponder : public LLTextureCache::WriteResponder
+{
+public:
+ LLDebuggerCacheWriteResponder(LLTextureFetchDebugger* debugger, S32 id)
+ : mDebugger(debugger), mID(id)
+ {
+ }
+ virtual void completed(bool success)
+ {
+ mDebugger->callbackCacheWrite(mID, success);
+ }
+private:
+ LLTextureFetchDebugger* mDebugger;
+ S32 mID;
+};
+
+class LLDebuggerDecodeResponder : public LLImageDecodeThread::Responder
+{
+public:
+ LLDebuggerDecodeResponder(LLTextureFetchDebugger* debugger, S32 id)
+ : mDebugger(debugger), mID(id)
+ {
+ }
+ virtual void completed(bool success, LLImageRaw* raw, LLImageRaw* aux)
+ {
+ mDebugger->callbackDecoded(mID, success, raw, aux);
+ }
+private:
+ LLTextureFetchDebugger* mDebugger;
+ S32 mID;
+};
+
+
+LLTextureFetchDebugger::LLTextureFetchDebugger(LLTextureFetch* fetcher, LLTextureCache* cache, LLImageDecodeThread* imagedecodethread) :
+ LLCore::HttpHandler(),
+ mFetcher(fetcher),
+ mTextureCache(cache),
+ mImageDecodeThread(imagedecodethread),
+ mHttpHeaders(NULL),
+ mHttpPolicyClass(fetcher->getPolicyClass()),
+ mNbCurlCompleted(0),
+ mTempIndex(0),
+ mHistoryListIndex(0)
+{
+ init();
+}
+
+LLTextureFetchDebugger::~LLTextureFetchDebugger()
+{
+ mFetchingHistory.clear();
+ mStopDebug = TRUE;
+ tryToStopDebug();
+ if (mHttpHeaders)
+ {
+ mHttpHeaders->release();
+ mHttpHeaders = NULL;
+ }
+}
+
+void LLTextureFetchDebugger::init()
+{
+ mState = IDLE;
+
+ mCacheReadTime = -1.f;
+ mCacheWriteTime = -1.f;
+ mDecodingTime = -1.f;
+ mHTTPTime = -1.f;
+ mGLCreationTime = -1.f;
+
+ mTotalFetchingTime = 0.f;
+ mRefetchVisCacheTime = -1.f;
+ mRefetchVisHTTPTime = -1.f;
+ mRefetchAllCacheTime = -1.f;
+ mRefetchAllHTTPTime = -1.f;
+
+ mNumFetchedTextures = 0;
+ mNumCacheHits = 0;
+ mNumVisibleFetchedTextures = 0;
+ mNumVisibleFetchingRequests = 0;
+ mFetchedData = 0;
+ mDecodedData = 0;
+ mVisibleFetchedData = 0;
+ mVisibleDecodedData = 0;
+ mRenderedData = 0;
+ mRenderedDecodedData = 0;
+ mFetchedPixels = 0;
+ mRenderedPixels = 0;
+ mRefetchedVisData = 0;
+ mRefetchedVisPixels = 0;
+ mRefetchedAllData = 0;
+ mRefetchedAllPixels = 0;
+
+ mFreezeHistory = FALSE;
+ mStopDebug = FALSE;
+ mClearHistory = FALSE;
+ mRefetchNonVis = FALSE;
+
+ mNbCurlRequests = 0;
+
+ if (! mHttpHeaders)
+ {
+ mHttpHeaders = new LLCore::HttpHeaders;
+ mHttpHeaders->mHeaders.push_back("Accept: image/x-j2c");
+ }
+}
+
+void LLTextureFetchDebugger::startWork(e_debug_state state)
+{
+ switch(state)
+ {
+ case IDLE:
+ break;
+ case START_DEBUG:
+ startDebug();
+ break;
+ case READ_CACHE:
+ debugCacheRead();
+ break;
+ case WRITE_CACHE:
+ debugCacheWrite();
+ break;
+ case DECODING:
+ debugDecoder();
+ break;
+ case HTTP_FETCHING:
+ debugHTTP();
+ break;
+ case GL_TEX:
+ debugGLTextureCreation();
+ break;
+ case REFETCH_VIS_CACHE:
+ debugRefetchVisibleFromCache();
+ break;
+ case REFETCH_VIS_HTTP:
+ debugRefetchVisibleFromHTTP();
+ break;
+ case REFETCH_ALL_CACHE:
+ debugRefetchAllFromCache();
+ break;
+ case REFETCH_ALL_HTTP:
+ debugRefetchAllFromHTTP();
+ break;
+ default:
+ break;
+ }
+ return;
+}
+
+void LLTextureFetchDebugger::startDebug()
+{
+ //lock the fetcher
+ mFetcher->lockFetcher(true);
+ mFreezeHistory = TRUE;
+ mFetcher->resetLoadSource();
+
+ //clear the current fetching queue
+ gTextureList.clearFetchingRequests();
+
+ mState = START_DEBUG;
+}
+
+bool LLTextureFetchDebugger::processStartDebug(F32 max_time)
+{
+ mTimer.reset();
+
+ //wait for all works to be done
+ while(1)
+ {
+ S32 pending = 0;
+ pending += LLAppViewer::getTextureCache()->update(1);
+ pending += LLAppViewer::getImageDecodeThread()->update(1);
+ // pending += LLAppViewer::getTextureFetch()->update(1); // This causes infinite recursion in some cases
+ pending += mNbCurlRequests;
+ if(!pending)
+ {
+ break;
+ }
+
+ if(mTimer.getElapsedTimeF32() > max_time)
+ {
+ return false;
+ }
+ }
+
+ //collect statistics
+ mTotalFetchingTime = gTextureTimer.getElapsedTimeF32() - mTotalFetchingTime;
+
+ std::set<LLUUID> fetched_textures;
+ S32 size = mFetchingHistory.size();
+ for(S32 i = 0 ; i < size; i++)
+ {
+ bool in_list = true;
+ if(fetched_textures.find(mFetchingHistory[i].mID) == fetched_textures.end())
+ {
+ fetched_textures.insert(mFetchingHistory[i].mID);
+ in_list = false;
+ }
+
+ LLViewerFetchedTexture* tex = LLViewerTextureManager::findFetchedTexture(mFetchingHistory[i].mID);
+ if(tex && tex->isJustBound()) //visible
+ {
+ if(!in_list)
+ {
+ mNumVisibleFetchedTextures++;
+ }
+ mNumVisibleFetchingRequests++;
+
+ mVisibleFetchedData += mFetchingHistory[i].mFetchedSize;
+ mVisibleDecodedData += mFetchingHistory[i].mDecodedSize;
+
+ if(tex->getDiscardLevel() >= mFetchingHistory[i].mDecodedLevel)
+ {
+ mRenderedData += mFetchingHistory[i].mFetchedSize;
+ mRenderedDecodedData += mFetchingHistory[i].mDecodedSize;
+ mRenderedPixels += tex->getWidth() * tex->getHeight();
+ }
+ }
+ }
+
+ mNumFetchedTextures = fetched_textures.size();
+
+ return true;
+}
+
+void LLTextureFetchDebugger::tryToStopDebug()
+{
+ if(!mStopDebug)
+ {
+ return;
+ }
+
+ //clear the current debug work
+ S32 size = mFetchingHistory.size();
+ switch(mState)
+ {
+ case READ_CACHE:
+ for(S32 i = 0 ; i < size; i++)
+ {
+ if (mFetchingHistory[i]. mCacheHandle != LLTextureCache::nullHandle())
+ {
+ mTextureCache->readComplete(mFetchingHistory[i].mCacheHandle, true);
+ }
+ }
+ break;
+ case WRITE_CACHE:
+ for(S32 i = 0 ; i < size; i++)
+ {
+ if (mFetchingHistory[i].mCacheHandle != LLTextureCache::nullHandle())
+ {
+ mTextureCache->writeComplete(mFetchingHistory[i].mCacheHandle, true);
+ }
+ }
+ break;
+ case DECODING:
+ break;
+ case HTTP_FETCHING:
+ break;
+ case GL_TEX:
+ break;
+ case REFETCH_VIS_CACHE:
+ break;
+ case REFETCH_VIS_HTTP:
+ break;
+ case REFETCH_ALL_CACHE:
+ mRefetchList.clear();
+ break;
+ case REFETCH_ALL_HTTP:
+ mRefetchList.clear();
+ break;
+ default:
+ break;
+ }
+
+ if(update(0.005f))
+ {
+ //unlock the fetcher
+ mFetcher->lockFetcher(false);
+ mFetcher->resetLoadSource();
+ mFreezeHistory = FALSE;
+ mStopDebug = FALSE;
+
+ if(mClearHistory)
+ {
+ mFetchingHistory.clear();
+ mHandleToFetchIndex.clear();
+ init();
+ mTotalFetchingTime = gTextureTimer.getElapsedTimeF32(); //reset
+ }
+ }
+}
+
+//called in the main thread and when the fetching queue is empty
+void LLTextureFetchDebugger::clearHistory()
+{
+ mClearHistory = TRUE;
+}
+
+void LLTextureFetchDebugger::addHistoryEntry(LLTextureFetchWorker* worker)
+{
+ if(worker->mRawImage.isNull() || worker->mFormattedImage.isNull())
+ {
+ return;
+ }
+
+ if(mFreezeHistory)
+ {
+ if(mState == REFETCH_VIS_CACHE || mState == REFETCH_VIS_HTTP)
+ {
+ mRefetchedVisPixels += worker->mRawImage->getWidth() * worker->mRawImage->getHeight();
+ mRefetchedVisData += worker->mFormattedImage->getDataSize();
+ }
+ else
+ {
+ mRefetchedAllPixels += worker->mRawImage->getWidth() * worker->mRawImage->getHeight();
+ mRefetchedAllData += worker->mFormattedImage->getDataSize();
+
+ LLViewerFetchedTexture* tex = LLViewerTextureManager::findFetchedTexture(worker->mID);
+ if(tex && mRefetchList[tex].begin() != mRefetchList[tex].end())
+ {
+ if(worker->mDecodedDiscard == mFetchingHistory[mRefetchList[tex][0]].mDecodedLevel)
+ {
+ mRefetchList[tex].erase(mRefetchList[tex].begin());
+ }
+ }
+ }
+ return;
+ }
+
+ if(worker->mInCache)
+ {
+ mNumCacheHits++;
+ }
+ mFetchedData += worker->mFormattedImage->getDataSize();
+ mDecodedData += worker->mRawImage->getDataSize();
+ mFetchedPixels += worker->mRawImage->getWidth() * worker->mRawImage->getHeight();
+
+ mFetchingHistory.push_back(FetchEntry(worker->mID, worker->mDesiredSize, worker->mDecodedDiscard,
+ worker->mFormattedImage->getDataSize(), worker->mRawImage->getDataSize()));
+}
+
+void LLTextureFetchDebugger::lockCache()
+{
+}
+
+void LLTextureFetchDebugger::unlockCache()
+{
+}
+
+void LLTextureFetchDebugger::debugCacheRead()
+{
+ lockCache();
+ llassert_always(mState == IDLE);
+ mTimer.reset();
+ mState = READ_CACHE;
+ mCacheReadTime = -1.f;
+
+ S32 size = mFetchingHistory.size();
+ for(S32 i = 0 ; i < size ; i++)
+ {
+ mFetchingHistory[i].mFormattedImage = NULL;
+ mFetchingHistory[i].mCacheHandle = mTextureCache->readFromCache(mFetchingHistory[i].mID, LLWorkerThread::PRIORITY_NORMAL, 0, mFetchingHistory[i].mFetchedSize,
+ new LLDebuggerCacheReadResponder(this, i, mFetchingHistory[i].mFormattedImage));
+ }
+}
+
+void LLTextureFetchDebugger::clearCache()
+{
+ S32 size = mFetchingHistory.size();
+ {
+ std::set<LLUUID> deleted_list;
+ for(S32 i = 0 ; i < size ; i++)
+ {
+ if(deleted_list.find(mFetchingHistory[i].mID) == deleted_list.end())
+ {
+ deleted_list.insert(mFetchingHistory[i].mID);
+ mTextureCache->removeFromCache(mFetchingHistory[i].mID);
+ }
+ }
+ }
+}
+
+void LLTextureFetchDebugger::debugCacheWrite()
+{
+ //remove from cache
+ clearCache();
+
+ lockCache();
+ llassert_always(mState == IDLE);
+ mTimer.reset();
+ mState = WRITE_CACHE;
+ mCacheWriteTime = -1.f;
+
+ S32 size = mFetchingHistory.size();
+ for(S32 i = 0 ; i < size ; i++)
+ {
+ if(mFetchingHistory[i].mFormattedImage.notNull())
+ {
+ mFetchingHistory[i].mCacheHandle = mTextureCache->writeToCache(mFetchingHistory[i].mID, LLWorkerThread::PRIORITY_NORMAL,
+ mFetchingHistory[i].mFormattedImage->getData(), mFetchingHistory[i].mFetchedSize,
+ mFetchingHistory[i].mDecodedLevel == 0 ? mFetchingHistory[i].mFetchedSize : mFetchingHistory[i].mFetchedSize + 1,
+ NULL, 0, new LLDebuggerCacheWriteResponder(this, i));
+ }
+ }
+}
+
+void LLTextureFetchDebugger::lockDecoder()
+{
+}
+
+void LLTextureFetchDebugger::unlockDecoder()
+{
+}
+
+void LLTextureFetchDebugger::debugDecoder()
+{
+ lockDecoder();
+ llassert_always(mState == IDLE);
+ mTimer.reset();
+ mState = DECODING;
+ mDecodingTime = -1.f;
+
+ S32 size = mFetchingHistory.size();
+ for(S32 i = 0 ; i < size ; i++)
+ {
+ if(mFetchingHistory[i].mFormattedImage.isNull())
+ {
+ continue;
+ }
+
+ mImageDecodeThread->decodeImage(mFetchingHistory[i].mFormattedImage, LLWorkerThread::PRIORITY_NORMAL,
+ mFetchingHistory[i].mDecodedLevel, mFetchingHistory[i].mNeedsAux,
+ new LLDebuggerDecodeResponder(this, i));
+ }
+}
+
+void LLTextureFetchDebugger::debugHTTP()
+{
+ llassert_always(mState == IDLE);
+
+ LLViewerRegion* region = gAgent.getRegion();
+ if (!region)
+ {
+ llinfos << "Fetch Debugger : Current region undefined. Cannot fetch textures through HTTP." << llendl;
+ return;
+ }
+
+ mHTTPUrl = region->getHttpUrl();
+ if (mHTTPUrl.empty())
+ {
+ llinfos << "Fetch Debugger : Current region URL undefined. Cannot fetch textures through HTTP." << llendl;
+ return;
+ }
+
+ mTimer.reset();
+ mState = HTTP_FETCHING;
+ mHTTPTime = -1.f;
+
+ S32 size = mFetchingHistory.size();
+ for (S32 i = 0 ; i < size ; i++)
+ {
+ mFetchingHistory[i].mCurlState = FetchEntry::CURL_NOT_DONE;
+ mFetchingHistory[i].mCurlReceivedSize = 0;
+ mFetchingHistory[i].mFormattedImage = NULL;
+ }
+ mNbCurlRequests = 0;
+ mNbCurlCompleted = 0;
+
+ fillCurlQueue();
+}
+
+S32 LLTextureFetchDebugger::fillCurlQueue()
+{
+ if(mStopDebug) //stop
+ {
+ mNbCurlCompleted = mFetchingHistory.size();
+ return 0;
+ }
+ if (mNbCurlRequests > HTTP_REQUESTS_IN_QUEUE_LOW_WATER)
+ {
+ return mNbCurlRequests;
+ }
+
+ S32 size = mFetchingHistory.size();
+ for (S32 i = 0 ; i < size ; i++)
+ {
+ if (mFetchingHistory[i].mCurlState != FetchEntry::CURL_NOT_DONE)
+ {
+ continue;
+ }
+ std::string texture_url = mHTTPUrl + "/?texture_id=" + mFetchingHistory[i].mID.asString().c_str();
+ S32 requestedSize = mFetchingHistory[i].mRequestedSize;
+ // We request the whole file if the size was not set.
+ requestedSize = llmax(0,requestedSize);
+ // We request the whole file if the size was set to an absurdly high value (meaning all file)
+ requestedSize = (requestedSize == 33554432 ? 0 : requestedSize);
+
+ LLCore::HttpHandle handle = mFetcher->getHttpRequest().requestGetByteRange(mHttpPolicyClass,
+ LLWorkerThread::PRIORITY_LOWBITS,
+ texture_url,
+ 0,
+ requestedSize,
+ NULL,
+ mHttpHeaders,
+ this);
+ if (LLCORE_HTTP_HANDLE_INVALID != handle)
+ {
+ mHandleToFetchIndex[handle] = i;
+ mFetchingHistory[i].mHttpHandle = handle;
+ mFetchingHistory[i].mCurlState = FetchEntry::CURL_IN_PROGRESS;
+ mNbCurlRequests++;
+ if (mNbCurlRequests >= HTTP_REQUESTS_IN_QUEUE_HIGH_WATER) // emulate normal pipeline
+ {
+ break;
+ }
+ }
+ else
+ {
+ // Failed to queue request, log it and mark it done.
+ LLCore::HttpStatus status(mFetcher->getHttpRequest().getStatus());
+
+ LL_WARNS("Texture") << "Couldn't issue HTTP request in debugger for texture "
+ << mFetchingHistory[i].mID
+ << ", status: " << status.toHex()
+ << " reason: " << status.toString()
+ << LL_ENDL;
+ mFetchingHistory[i].mCurlState = FetchEntry::CURL_DONE;
+ }
+ }
+ //llinfos << "Fetch Debugger : Having " << mNbCurlRequests << " requests through the curl thread." << llendl;
+ return mNbCurlRequests;
+}
+
+void LLTextureFetchDebugger::debugGLTextureCreation()
+{
+ llassert_always(mState == IDLE);
+ mState = GL_TEX;
+ mTempTexList.clear();
+
+ S32 size = mFetchingHistory.size();
+ for(S32 i = 0 ; i < size ; i++)
+ {
+ if(mFetchingHistory[i].mRawImage.notNull())
+ {
+ LLViewerFetchedTexture* tex = gTextureList.findImage(mFetchingHistory[i].mID) ;
+ if(tex && !tex->isForSculptOnly())
+ {
+ tex->destroyGLTexture() ;
+ mTempTexList.push_back(tex);
+ }
+ }
+ }
+
+ mGLCreationTime = -1.f;
+ mTempIndex = 0;
+ mHistoryListIndex = 0;
+
+ return;
+}
+
+bool LLTextureFetchDebugger::processGLCreation(F32 max_time)
+{
+ mTimer.reset();
+
+ bool done = true;
+ S32 size = mFetchingHistory.size();
+ S32 size1 = mTempTexList.size();
+ for(; mHistoryListIndex < size && mTempIndex < size1; mHistoryListIndex++)
+ {
+ if(mFetchingHistory[mHistoryListIndex].mRawImage.notNull())
+ {
+ if(mFetchingHistory[mHistoryListIndex].mID == mTempTexList[mTempIndex]->getID())
+ {
+ mTempTexList[mTempIndex]->createGLTexture(mFetchingHistory[mHistoryListIndex].mDecodedLevel,
+ mFetchingHistory[mHistoryListIndex].mRawImage, 0, TRUE, mTempTexList[mTempIndex]->getBoostLevel());
+ mTempIndex++;
+ }
+ }
+
+ if(mTimer.getElapsedTimeF32() > max_time)
+ {
+ done = false;
+ break;
+ }
+ }
+
+ if(mGLCreationTime < 0.f)
+ {
+ mGLCreationTime = mTimer.getElapsedTimeF32() ;
+ }
+ else
+ {
+ mGLCreationTime += mTimer.getElapsedTimeF32() ;
+ }
+
+ return done;
+}
+
+//clear fetching results of all textures.
+void LLTextureFetchDebugger::clearTextures()
+{
+ S32 size = mFetchingHistory.size();
+ for(S32 i = 0 ; i < size ; i++)
+ {
+ LLViewerFetchedTexture* tex = gTextureList.findImage(mFetchingHistory[i].mID) ;
+ if(tex)
+ {
+ tex->clearFetchedResults() ;
+ }
+ }
+}
+
+void LLTextureFetchDebugger::makeRefetchList()
+{
+ mRefetchList.clear();
+ S32 size = mFetchingHistory.size();
+ for(S32 i = 0 ; i < size; i++)
+ {
+ LLViewerFetchedTexture* tex = LLViewerTextureManager::getFetchedTexture(mFetchingHistory[i].mID);
+ if(tex && tex->isJustBound()) //visible
+ {
+ continue; //the texture fetch pipeline will take care of visible textures.
+ }
+
+ mRefetchList[tex].push_back(i);
+ }
+}
+
+void LLTextureFetchDebugger::scanRefetchList()
+{
+ if(mStopDebug)
+ {
+ return;
+ }
+ if(!mRefetchNonVis)
+ {
+ return;
+ }
+
+ for(std::map< LLPointer<LLViewerFetchedTexture>, std::vector<S32> >::iterator iter = mRefetchList.begin();
+ iter != mRefetchList.end(); )
+ {
+ if(iter->second.empty())
+ {
+ gTextureList.setDebugFetching(iter->first, -1);
+ mRefetchList.erase(iter++); // This is the correct method to "erase and move on" in an std::map
+ }
+ else
+ {
+ gTextureList.setDebugFetching(iter->first, mFetchingHistory[iter->second[0]].mDecodedLevel);
+ ++iter;
+ }
+ }
+}
+
+void LLTextureFetchDebugger::debugRefetchVisibleFromCache()
+{
+ llassert_always(mState == IDLE);
+ mState = REFETCH_VIS_CACHE;
+
+ clearTextures();
+ mFetcher->setLoadSource(LLTextureFetch::FROM_ALL);
+
+ mTimer.reset();
+ mFetcher->lockFetcher(false);
+ mRefetchVisCacheTime = -1.f;
+ mRefetchedVisData = 0;
+ mRefetchedVisPixels = 0;
+}
+
+void LLTextureFetchDebugger::debugRefetchVisibleFromHTTP()
+{
+ llassert_always(mState == IDLE);
+ mState = REFETCH_VIS_HTTP;
+
+ clearTextures();
+ mFetcher->setLoadSource(LLTextureFetch::FROM_HTTP_ONLY);
+
+ mTimer.reset();
+ mFetcher->lockFetcher(false);
+ mRefetchVisHTTPTime = -1.f;
+ mRefetchedVisData = 0;
+ mRefetchedVisPixels = 0;
+}
+
+void LLTextureFetchDebugger::debugRefetchAllFromCache()
+{
+ llassert_always(mState == IDLE);
+ mState = REFETCH_ALL_CACHE;
+
+ clearTextures();
+ makeRefetchList();
+ mFetcher->setLoadSource(LLTextureFetch::FROM_ALL);
+
+ mTimer.reset();
+ mFetcher->lockFetcher(false);
+ mRefetchAllCacheTime = -1.f;
+ mRefetchedAllData = 0;
+ mRefetchedAllPixels = 0;
+ mRefetchNonVis = FALSE;
+}
+
+void LLTextureFetchDebugger::debugRefetchAllFromHTTP()
+{
+ llassert_always(mState == IDLE);
+ mState = REFETCH_ALL_HTTP;
+
+ clearTextures();
+ makeRefetchList();
+ mFetcher->setLoadSource(LLTextureFetch::FROM_HTTP_ONLY);
+
+ mTimer.reset();
+ mFetcher->lockFetcher(false);
+ mRefetchAllHTTPTime = -1.f;
+ mRefetchedAllData = 0;
+ mRefetchedAllPixels = 0;
+ mRefetchNonVis = TRUE;
+}
+
+bool LLTextureFetchDebugger::update(F32 max_time)
+{
+ switch(mState)
+ {
+ case START_DEBUG:
+ if(processStartDebug(max_time))
+ {
+ mState = IDLE;
+ }
+ break;
+ case READ_CACHE:
+ if(!mTextureCache->update(1))
+ {
+ mCacheReadTime = mTimer.getElapsedTimeF32() ;
+ mState = IDLE;
+ unlockCache();
+ }
+ break;
+ case WRITE_CACHE:
+ if(!mTextureCache->update(1))
+ {
+ mCacheWriteTime = mTimer.getElapsedTimeF32() ;
+ mState = IDLE;
+ unlockCache();
+ }
+ break;
+ case DECODING:
+ if(!mImageDecodeThread->update(1))
+ {
+ mDecodingTime = mTimer.getElapsedTimeF32() ;
+ mState = IDLE;
+ unlockDecoder();
+ }
+ break;
+ case HTTP_FETCHING:
+ // Do some notifications...
+ mFetcher->getHttpRequest().update(10);
+ if (!fillCurlQueue() && mNbCurlCompleted == mFetchingHistory.size())
+ {
+ mHTTPTime = mTimer.getElapsedTimeF32() ;
+ mState = IDLE;
+ }
+ break;
+ case GL_TEX:
+ if(processGLCreation(max_time))
+ {
+ mState = IDLE;
+ mTempTexList.clear();
+ }
+ break;
+ case REFETCH_VIS_CACHE:
+ if (LLAppViewer::getTextureFetch()->getNumRequests() == 0)
+ {
+ mRefetchVisCacheTime = mTimer.getElapsedTimeF32() ;
+ mState = IDLE;
+ mFetcher->lockFetcher(true);
+ mFetcher->resetLoadSource();
+ }
+ break;
+ case REFETCH_VIS_HTTP:
+ if (LLAppViewer::getTextureFetch()->getNumRequests() == 0)
+ {
+ mRefetchVisHTTPTime = mTimer.getElapsedTimeF32() ;
+ mState = IDLE;
+ mFetcher->lockFetcher(true);
+ mFetcher->resetLoadSource();
+ }
+ break;
+ case REFETCH_ALL_CACHE:
+ scanRefetchList();
+ if (LLAppViewer::getTextureFetch()->getNumRequests() == 0)
+ {
+ if(!mRefetchNonVis)
+ {
+ mRefetchNonVis = TRUE; //start to fetch non-vis
+ scanRefetchList();
+ break;
+ }
+
+ mRefetchAllCacheTime = mTimer.getElapsedTimeF32() ;
+ mState = IDLE;
+ mFetcher->lockFetcher(true);
+ mFetcher->resetLoadSource();
+ mRefetchList.clear();
+ mRefetchNonVis = FALSE;
+ }
+ break;
+ case REFETCH_ALL_HTTP:
+ scanRefetchList();
+ if (LLAppViewer::getTextureFetch()->getNumRequests() == 0)
+ {
+ mRefetchAllHTTPTime = mTimer.getElapsedTimeF32() ;
+ mState = IDLE;
+ mFetcher->lockFetcher(true);
+ mFetcher->resetLoadSource();
+ mRefetchList.clear();
+ mRefetchNonVis = FALSE;
+ }
+ break;
+ default:
+ mState = IDLE;
+ break;
+ }
+
+ return mState == IDLE;
+}
+
+void LLTextureFetchDebugger::onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response)
+{
+ handle_fetch_map_t::iterator iter(mHandleToFetchIndex.find(handle));
+ if (mHandleToFetchIndex.end() == iter)
+ {
+ llinfos << "Fetch Debugger : Couldn't find handle " << handle << " in fetch list." << llendl;
+ return;
+ }
+
+ S32 fetch_ind(iter->second);
+ mHandleToFetchIndex.erase(iter);
+ if (fetch_ind >= mFetchingHistory.size() || mFetchingHistory[fetch_ind].mHttpHandle != handle)
+ {
+ llinfos << "Fetch Debugger : Handle and fetch object in disagreement. Punting." << llendl;
+ }
+ else
+ {
+ callbackHTTP(mFetchingHistory[fetch_ind], response);
+ mFetchingHistory[fetch_ind].mHttpHandle = LLCORE_HTTP_HANDLE_INVALID; // Not valid after notification
+ }
+}
+
+void LLTextureFetchDebugger::callbackCacheRead(S32 id, bool success, LLImageFormatted* image,
+ S32 imagesize, BOOL islocal)
+{
+ if (success)
+ {
+ mFetchingHistory[id].mFormattedImage = image;
+ }
+ mTextureCache->readComplete(mFetchingHistory[id].mCacheHandle, false);
+ mFetchingHistory[id].mCacheHandle = LLTextureCache::nullHandle();
+}
+
+void LLTextureFetchDebugger::callbackCacheWrite(S32 id, bool success)
+{
+ mTextureCache->writeComplete(mFetchingHistory[id].mCacheHandle);
+ mFetchingHistory[id].mCacheHandle = LLTextureCache::nullHandle();
+}
+
+void LLTextureFetchDebugger::callbackDecoded(S32 id, bool success, LLImageRaw* raw, LLImageRaw* aux)
+{
+ if (success)
+ {
+ llassert_always(raw);
+ mFetchingHistory[id].mRawImage = raw;
+ }
+}
+
+void LLTextureFetchDebugger::callbackHTTP(FetchEntry & fetch, LLCore::HttpResponse * response)
+{
+ static const LLCore::HttpStatus par_status(HTTP_PARTIAL_CONTENT);
+
+ LLCore::HttpStatus status(response->getStatus());
+ mNbCurlRequests--;
+ mNbCurlCompleted++;
+ fetch.mCurlState = FetchEntry::CURL_DONE;
+ if (status)
+ {
+ const bool partial(par_status == status);
+ LLCore::BufferArray * ba(response->getBody()); // *Not* holding reference to body
+
+ S32 data_size = ba ? ba->size() : 0;
+ fetch.mCurlReceivedSize += data_size;
+ //llinfos << "Fetch Debugger : got results for " << fetch.mID << ", data_size = " << data_size << ", received = " << fetch.mCurlReceivedSize << ", requested = " << fetch.mRequestedSize << ", partial = " << partial << llendl;
+ if ((fetch.mCurlReceivedSize >= fetch.mRequestedSize) || !partial || (fetch.mRequestedSize == 600))
+ {
+ U8* d_buffer = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), data_size);
+ if (ba)
+ {
+ ba->read(0, d_buffer, data_size);
+ }
+
+ llassert_always(fetch.mFormattedImage.isNull());
+ {
+ // For now, create formatted image based on extension
+ std::string texture_url = mHTTPUrl + "/?texture_id=" + fetch.mID.asString().c_str();
+ std::string extension = gDirUtilp->getExtension(texture_url);
+ fetch.mFormattedImage = LLImageFormatted::createFromType(LLImageBase::getCodecFromExtension(extension));
+ if (fetch.mFormattedImage.isNull())
+ {
+ fetch.mFormattedImage = new LLImageJ2C; // default
+ }
+ }
+
+ fetch.mFormattedImage->setData(d_buffer, data_size);
+ }
+ }
+ else //failed
+ {
+ llinfos << "Fetch Debugger : CURL GET FAILED, ID = " << fetch.mID
+ << ", status: " << status.toHex()
+ << " reason: " << status.toString() << llendl;
+ }
+}
+
+
+//---------------------
+///////////////////////////////////////////////////////////////////////////////////////////
+//End LLTextureFetchDebugger
+///////////////////////////////////////////////////////////////////////////////////////////
+
diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h
index 35df7d816f..902a3d7a25 100644..100755
--- a/indra/newview/lltexturefetch.h
+++ b/indra/newview/lltexturefetch.h
@@ -4,7 +4,7 @@
*
* $LicenseInfo:firstyear=2000&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
+ * Copyright (C) 2012, 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
@@ -27,27 +27,37 @@
#ifndef LL_LLTEXTUREFETCH_H
#define LL_LLTEXTUREFETCH_H
+#include <vector>
+#include <map>
+
#include "lldir.h"
#include "llimage.h"
#include "lluuid.h"
#include "llworkerthread.h"
-#include "llcurl.h"
#include "lltextureinfo.h"
#include "llapr.h"
+#include "llimageworker.h"
+#include "llstat.h"
+#include "llcurl.h"
+#include "llstat.h"
+#include "httprequest.h"
+#include "httpoptions.h"
+#include "httpheaders.h"
+#include "httphandler.h"
+#include "llviewertexture.h"
-class LLViewerTexture;
class LLTextureFetchWorker;
-class HTTPGetResponder;
-class LLTextureCache;
class LLImageDecodeThread;
class LLHost;
class LLViewerAssetStats;
+class LLTextureFetchDebugger;
+class LLTextureCache;
// Interface class
+
class LLTextureFetch : public LLWorkerThread
{
friend class LLTextureFetchWorker;
- friend class HTTPGetResponder;
public:
LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* imagedecodethread, bool threaded, bool qa_mode);
@@ -55,72 +65,201 @@ public:
class TFRequest;
- /*virtual*/ S32 update(F32 max_time_ms);
- void shutDownTextureCacheThread() ; //called in the main thread after the TextureCacheThread shuts down.
- void shutDownImageDecodeThread() ; //called in the main thread after the ImageDecodeThread shuts down.
+ // Threads: Tmain
+ /*virtual*/ S32 update(F32 max_time_ms);
+
+ // called in the main thread after the TextureCacheThread shuts down.
+ // Threads: Tmain
+ void shutDownTextureCacheThread();
- bool createRequest(const std::string& url, const LLUUID& id, const LLHost& host, F32 priority,
+ //called in the main thread after the ImageDecodeThread shuts down.
+ // Threads: Tmain
+ void shutDownImageDecodeThread();
+
+ // Threads: T* (but Tmain mostly)
+ bool createRequest(FTType f_type, const std::string& url, const LLUUID& id, const LLHost& host, F32 priority,
S32 w, S32 h, S32 c, S32 discard, bool needs_aux, bool can_use_http);
+
+ // Requests that a fetch operation be deleted from the queue.
+ // If @cancel is true, also stops any I/O operations pending.
+ // Actual delete will be scheduled and performed later.
+ //
+ // Note: This *looks* like an override/variant of the
+ // base class's deleteRequest() but is functionally quite
+ // different.
+ //
+ // Threads: T*
void deleteRequest(const LLUUID& id, bool cancel);
+
+ void deleteAllRequests();
+
+ // Threads: T*
bool getRequestFinished(const LLUUID& id, S32& discard_level,
LLPointer<LLImageRaw>& raw, LLPointer<LLImageRaw>& aux);
+
+ // Threads: T*
bool updateRequestPriority(const LLUUID& id, F32 priority);
+ // Threads: T*
bool receiveImageHeader(const LLHost& host, const LLUUID& id, U8 codec, U16 packets, U32 totalbytes, U16 data_size, U8* data);
+
+ // Threads: T*
bool receiveImagePacket(const LLHost& host, const LLUUID& id, U16 packet_num, U16 data_size, U8* data);
+ // Threads: T* (but not safe)
void setTextureBandwidth(F32 bandwidth) { mTextureBandwidth = bandwidth; }
+
+ // Threads: T* (but not safe)
F32 getTextureBandwidth() { return mTextureBandwidth; }
- // Debug
+ // Threads: T*
BOOL isFromLocalCache(const LLUUID& id);
+
+ // @return Magic number giving the internal state of the
+ // request. We should make these codes public if we're
+ // going to return them as a status value.
+ //
+ // Threads: T*
S32 getFetchState(const LLUUID& id, F32& decode_progress_p, F32& requested_priority_p,
U32& fetch_priority_p, F32& fetch_dtime_p, F32& request_dtime_p, bool& can_use_http);
+
+ // Debug utility - generally not safe
void dump();
- S32 getNumRequests() ;
- S32 getNumHTTPRequests() ;
- U32 getTotalNumHTTPRequests() ;
+
+ // Threads: T*
+ S32 getNumRequests();
+
+ // Threads: T*
+ S32 getNumHTTPRequests();
+
+ // Threads: T*
+ U32 getTotalNumHTTPRequests();
- // Public for access by callbacks
+ // Threads: T*
S32 getPending();
+
+ // Threads: T*
void lockQueue() { mQueueMutex.lock(); }
+
+ // Threads: T*
void unlockQueue() { mQueueMutex.unlock(); }
+
+ // Threads: T*
LLTextureFetchWorker* getWorker(const LLUUID& id);
+
+ // Threads: T*
+ // Locks: Mfq
LLTextureFetchWorker* getWorkerAfterLock(const LLUUID& id);
- LLTextureInfo* getTextureInfo() { return &mTextureInfo; }
-
// Commands available to other threads to control metrics gathering operations.
+
+ // Threads: T*
void commandSetRegion(U64 region_handle);
+
+ // Threads: T*
void commandSendMetrics(const std::string & caps_url,
const LLUUID & session_id,
const LLUUID & agent_id,
LLViewerAssetStats * main_stats);
+
+ // Threads: T*
void commandDataBreak();
- LLCurlRequest & getCurlRequest() { return *mCurlGetRequest; }
+ // Threads: T*
+ LLCore::HttpRequest & getHttpRequest() { return *mHttpRequest; }
+
+ // Threads: T*
+ LLCore::HttpRequest::policy_t getPolicyClass() const { return mHttpPolicyClass; }
+
+ // Return a pointer to the shared metrics headers definition.
+ // Does not increment the reference count, caller is required
+ // to do that to hold a reference for any length of time.
+ //
+ // Threads: T*
+ LLCore::HttpHeaders * getMetricsHeaders() const { return mHttpMetricsHeaders; }
bool isQAMode() const { return mQAMode; }
- // Curl POST counter maintenance
- inline void incrCurlPOSTCount() { mCurlPOSTRequestCount++; }
- inline void decrCurlPOSTCount() { mCurlPOSTRequestCount--; }
+ // ----------------------------------
+ // HTTP resource waiting methods
+
+ // Threads: T*
+ void addHttpWaiter(const LLUUID & tid);
+
+ // Threads: T*
+ void removeHttpWaiter(const LLUUID & tid);
+
+ // Threads: T*
+ bool isHttpWaiter(const LLUUID & tid);
+
+ // If there are slots, release one or more LLTextureFetchWorker
+ // requests from resource wait state (WAIT_HTTP_RESOURCE) to
+ // active (SEND_HTTP_REQ).
+ //
+ // Because this will modify state of many workers, you may not
+ // hold any Mw lock while calling. This makes it a little
+ // inconvenient to use but that's the rule.
+ //
+ // Threads: T*
+ // Locks: -Mw (must not hold any worker when called)
+ void releaseHttpWaiters();
+ // Threads: T*
+ void cancelHttpWaiters();
+
+ // Threads: T*
+ int getHttpWaitersCount();
+ // ----------------------------------
+ // Stats management
+
+ // Add given counts to the global totals for the states/requests
+ // Threads: T*
+ void updateStateStats(U32 cache_read, U32 cache_write, U32 res_wait);
+
+ // Return the global counts
+ // Threads: T*
+ void getStateStats(U32 * cache_read, U32 * cache_write, U32 * res_wait);
+
+ // ----------------------------------
+
protected:
+ // Threads: T* (but Ttf in practice)
void addToNetworkQueue(LLTextureFetchWorker* worker);
+
+ // Threads: T*
void removeFromNetworkQueue(LLTextureFetchWorker* worker, bool cancel);
+
+ // Threads: T*
void addToHTTPQueue(const LLUUID& id);
- void removeFromHTTPQueue(const LLUUID& id, S32 received_size = 0);
- void removeRequest(LLTextureFetchWorker* worker, bool cancel);
+ // XXX possible delete
+ // Threads: T*
+ void removeFromHTTPQueue(const LLUUID& id, S32 received_size);
+
+ // Identical to @deleteRequest but with different arguments
+ // (caller already has the worker pointer).
+ //
+ // Threads: T*
+ void removeRequest(LLTextureFetchWorker* worker, bool cancel);
+
// Overrides from the LLThread tree
+ // Locks: Ct
bool runCondition();
private:
+ // Threads: Tmain
void sendRequestListToSimulators();
+
+ // Threads: Ttf
/*virtual*/ void startThread(void);
+
+ // Threads: Ttf
/*virtual*/ void endThread(void);
+
+ // Threads: Ttf
/*virtual*/ void threadedUpdate(void);
+
+ // Threads: Ttf
void commonUpdate();
// Metrics command helpers
@@ -131,6 +270,8 @@ private:
* Takes ownership of the TFRequest object.
*
* Method locks the command queue.
+ *
+ * Threads: T*
*/
void cmdEnqueue(TFRequest *);
@@ -141,6 +282,8 @@ private:
* Caller acquires ownership of the object and must dispose of it.
*
* Method locks the command queue.
+ *
+ * Threads: T*
*/
TFRequest * cmdDequeue();
@@ -150,6 +293,8 @@ private:
* additional commands.
*
* Method locks the command queue.
+ *
+ * Threads: Ttf
*/
void cmdDoWork();
@@ -164,52 +309,311 @@ private:
LLMutex mQueueMutex; //to protect mRequestMap and mCommands only
LLMutex mNetworkQueueMutex; //to protect mNetworkQueue, mHTTPTextureQueue and mCancelQueue.
+ static LLStat sCacheHitRate;
+ static LLStat sCacheReadLatency;
+
LLTextureCache* mTextureCache;
LLImageDecodeThread* mImageDecodeThread;
- LLCurlRequest* mCurlGetRequest;
// Map of all requests by UUID
typedef std::map<LLUUID,LLTextureFetchWorker*> map_t;
- map_t mRequestMap;
+ map_t mRequestMap; // Mfq
// Set of requests that require network data
typedef std::set<LLUUID> queue_t;
- queue_t mNetworkQueue;
- queue_t mHTTPTextureQueue;
+ queue_t mNetworkQueue; // Mfnq
+ queue_t mHTTPTextureQueue; // Mfnq
typedef std::map<LLHost,std::set<LLUUID> > cancel_queue_t;
- cancel_queue_t mCancelQueue;
- F32 mTextureBandwidth;
- F32 mMaxBandwidth;
+ cancel_queue_t mCancelQueue; // Mfnq
+ F32 mTextureBandwidth; // <none>
+ F32 mMaxBandwidth; // Mfnq
LLTextureInfo mTextureInfo;
- U32 mHTTPTextureBits;
+ // XXX possible delete
+ U32 mHTTPTextureBits; // Mfnq
+ // XXX possible delete
//debug use
- U32 mTotalHTTPRequests ;
+ U32 mTotalHTTPRequests;
// Out-of-band cross-thread command queue. This command queue
// is logically tied to LLQueuedThread's list of
// QueuedRequest instances and so must be covered by the
// same locks.
typedef std::vector<TFRequest *> command_queue_t;
- command_queue_t mCommands;
+ command_queue_t mCommands; // Mfq
// If true, modifies some behaviors that help with QA tasks.
const bool mQAMode;
- // Count of POST requests outstanding. We maintain the count
- // indirectly in the CURL request responder's ctor and dtor and
- // use it when determining whether or not to sleep the thread. Can't
- // use the LLCurl module's request counter as it isn't thread compatible.
- // *NOTE: Don't mix Atomic and static, apr_initialize must be called first.
- LLAtomic32<S32> mCurlPOSTRequestCount;
+ // Interfaces and objects into the core http library used
+ // to make our HTTP requests. These replace the various
+ // LLCurl interfaces used in the past.
+ LLCore::HttpRequest * mHttpRequest; // Ttf
+ LLCore::HttpOptions * mHttpOptions; // Ttf
+ LLCore::HttpHeaders * mHttpHeaders; // Ttf
+ LLCore::HttpHeaders * mHttpMetricsHeaders; // Ttf
+ LLCore::HttpRequest::policy_t mHttpPolicyClass; // T*
+
+ // We use a resource semaphore to keep HTTP requests in
+ // WAIT_HTTP_RESOURCE2 if there aren't sufficient slots in the
+ // transport. This keeps them near where they can be cheaply
+ // reprioritized rather than dumping them all across a thread
+ // where it's more expensive to get at them. Requests in either
+ // SEND_HTTP_REQ or WAIT_HTTP_REQ charge against the semaphore
+ // and tracking state transitions is critical to liveness.
+ LLAtomicS32 mHttpSemaphore; // Ttf + Tmain
+
+ typedef std::set<LLUUID> wait_http_res_queue_t;
+ wait_http_res_queue_t mHttpWaitResource; // Mfnq
+
+ // Cumulative stats on the states/requests issued by
+ // textures running through here.
+ U32 mTotalCacheReadCount; // Mfq
+ U32 mTotalCacheWriteCount; // Mfq
+ U32 mTotalResourceWaitCount; // Mfq
public:
// A probabilistically-correct indicator that the current
// attempt to log metrics follows a break in the metrics stream
// reporting due to either startup or a problem POSTing data.
static volatile bool svMetricsDataBreak;
+
+public:
+ //debug use
+ enum e_tex_source
+ {
+ FROM_ALL = 0,
+ FROM_HTTP_ONLY,
+ INVALID_SOURCE
+ };
+private:
+ //debug use
+ LLTextureFetchDebugger* mFetchDebugger;
+ bool mFetcherLocked;
+
+ e_tex_source mFetchSource;
+ e_tex_source mOriginFetchSource;
+
+public:
+ //debug use
+ LLTextureFetchDebugger* getFetchDebugger() { return mFetchDebugger;}
+ void lockFetcher(bool lock) { mFetcherLocked = lock;}
+
+ void setLoadSource(e_tex_source source) {mFetchSource = source;}
+ void resetLoadSource() {mFetchSource = mOriginFetchSource;}
+ bool canLoadFromCache() { return mFetchSource != FROM_HTTP_ONLY;}
};
+//debug use
+class LLViewerFetchedTexture;
+class LLTextureFetchDebugger : public LLCore::HttpHandler
+{
+ friend class LLTextureFetch;
+public:
+ LLTextureFetchDebugger(LLTextureFetch* fetcher, LLTextureCache* cache, LLImageDecodeThread* imagedecodethread) ;
+ ~LLTextureFetchDebugger();
+
+public:
+ enum e_debug_state
+ {
+ IDLE = 0,
+ START_DEBUG,
+ READ_CACHE,
+ WRITE_CACHE,
+ DECODING,
+ HTTP_FETCHING,
+ GL_TEX,
+ REFETCH_VIS_CACHE,
+ REFETCH_VIS_HTTP,
+ REFETCH_ALL_CACHE,
+ REFETCH_ALL_HTTP,
+ INVALID
+ };
+
+private:
+ struct FetchEntry
+ {
+ enum e_curl_state
+ {
+ CURL_NOT_DONE = 0,
+ CURL_IN_PROGRESS,
+ CURL_DONE
+ };
+ LLUUID mID;
+ S32 mRequestedSize;
+ S32 mDecodedLevel;
+ S32 mFetchedSize;
+ S32 mDecodedSize;
+ BOOL mNeedsAux;
+ U32 mCacheHandle;
+ LLPointer<LLImageFormatted> mFormattedImage;
+ LLPointer<LLImageRaw> mRawImage;
+ e_curl_state mCurlState;
+ S32 mCurlReceivedSize;
+ LLCore::HttpHandle mHttpHandle;
+
+ FetchEntry() :
+ mDecodedLevel(-1),
+ mFetchedSize(0),
+ mDecodedSize(0),
+ mHttpHandle(LLCORE_HTTP_HANDLE_INVALID)
+ {}
+ FetchEntry(LLUUID& id, S32 r_size, /*S32 f_discard, S32 c,*/ S32 level, S32 f_size, S32 d_size) :
+ mID(id),
+ mRequestedSize(r_size),
+ mDecodedLevel(level),
+ mFetchedSize(f_size),
+ mDecodedSize(d_size),
+ mNeedsAux(false),
+ mHttpHandle(LLCORE_HTTP_HANDLE_INVALID)
+ {}
+ };
+ typedef std::vector<FetchEntry> fetch_list_t;
+ fetch_list_t mFetchingHistory;
+
+ typedef std::map<LLCore::HttpHandle, S32> handle_fetch_map_t;
+ handle_fetch_map_t mHandleToFetchIndex;
+
+ e_debug_state mState;
+
+ F32 mCacheReadTime;
+ F32 mCacheWriteTime;
+ F32 mDecodingTime;
+ F32 mHTTPTime;
+ F32 mGLCreationTime;
+
+ F32 mTotalFetchingTime;
+ F32 mRefetchVisCacheTime;
+ F32 mRefetchVisHTTPTime;
+ F32 mRefetchAllCacheTime;
+ F32 mRefetchAllHTTPTime;
+
+ LLTimer mTimer;
+
+ LLTextureFetch* mFetcher;
+ LLTextureCache* mTextureCache;
+ LLImageDecodeThread* mImageDecodeThread;
+ LLCore::HttpHeaders* mHttpHeaders;
+ LLCore::HttpRequest::policy_t mHttpPolicyClass;
+
+ S32 mNumFetchedTextures;
+ S32 mNumCacheHits;
+ S32 mNumVisibleFetchedTextures;
+ S32 mNumVisibleFetchingRequests;
+ U32 mFetchedData;
+ U32 mDecodedData;
+ U32 mVisibleFetchedData;
+ U32 mVisibleDecodedData;
+ U32 mRenderedData;
+ U32 mRenderedDecodedData;
+ U32 mFetchedPixels;
+ U32 mRenderedPixels;
+ U32 mRefetchedVisData;
+ U32 mRefetchedVisPixels;
+ U32 mRefetchedAllData;
+ U32 mRefetchedAllPixels;
+
+ BOOL mFreezeHistory;
+ BOOL mStopDebug;
+ BOOL mClearHistory;
+ BOOL mRefetchNonVis;
+
+ std::string mHTTPUrl;
+ S32 mNbCurlRequests;
+ S32 mNbCurlCompleted;
+
+ std::map< LLPointer<LLViewerFetchedTexture>, std::vector<S32> > mRefetchList;
+ std::vector< LLPointer<LLViewerFetchedTexture> > mTempTexList;
+ S32 mTempIndex;
+ S32 mHistoryListIndex;
+
+public:
+ bool update(F32 max_time); //called in the main thread once per frame
+
+ //fetching history
+ void clearHistory();
+ void addHistoryEntry(LLTextureFetchWorker* worker);
+
+ // Inherited from LLCore::HttpHandler
+ // Threads: Ttf
+ virtual void onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response);
+
+ void startWork(e_debug_state state);
+ void setStopDebug() {mStopDebug = TRUE;}
+ void tryToStopDebug(); //stop everything
+ void callbackCacheRead(S32 id, bool success, LLImageFormatted* image,
+ S32 imagesize, BOOL islocal);
+ void callbackCacheWrite(S32 id, bool success);
+ void callbackDecoded(S32 id, bool success, LLImageRaw* raw, LLImageRaw* aux);
+ void callbackHTTP(FetchEntry & fetch, LLCore::HttpResponse * response);
+
+ e_debug_state getState() {return mState;}
+ S32 getNumFetchedTextures() {return mNumFetchedTextures;}
+ S32 getNumFetchingRequests() {return mFetchingHistory.size();}
+ S32 getNumCacheHits() {return mNumCacheHits;}
+ S32 getNumVisibleFetchedTextures() {return mNumVisibleFetchedTextures;}
+ S32 getNumVisibleFetchingRequests() {return mNumVisibleFetchingRequests;}
+ U32 getFetchedData() {return mFetchedData;}
+ U32 getDecodedData() {return mDecodedData;}
+ U32 getVisibleFetchedData() {return mVisibleFetchedData;}
+ U32 getVisibleDecodedData() {return mVisibleDecodedData;}
+ U32 getRenderedData() {return mRenderedData;}
+ U32 getRenderedDecodedData() {return mRenderedDecodedData;}
+ U32 getFetchedPixels() {return mFetchedPixels;}
+ U32 getRenderedPixels() {return mRenderedPixels;}
+ U32 getRefetchedVisData() {return mRefetchedVisData;}
+ U32 getRefetchedVisPixels() {return mRefetchedVisPixels;}
+ U32 getRefetchedAllData() {return mRefetchedAllData;}
+ U32 getRefetchedAllPixels() {return mRefetchedAllPixels;}
+
+ F32 getCacheReadTime() {return mCacheReadTime;}
+ F32 getCacheWriteTime() {return mCacheWriteTime;}
+ F32 getDecodeTime() {return mDecodingTime;}
+ F32 getGLCreationTime() {return mGLCreationTime;}
+ F32 getHTTPTime() {return mHTTPTime;}
+ F32 getTotalFetchingTime() {return mTotalFetchingTime;}
+ F32 getRefetchVisCacheTime() {return mRefetchVisCacheTime;}
+ F32 getRefetchVisHTTPTime() {return mRefetchVisHTTPTime;}
+ F32 getRefetchAllCacheTime() {return mRefetchAllCacheTime;}
+ F32 getRefetchAllHTTPTime() {return mRefetchAllHTTPTime;}
+
+private:
+ void init();
+ void clearTextures();//clear fetching results of all textures.
+ void clearCache();
+ void makeRefetchList();
+ void scanRefetchList();
+
+ void lockFetcher();
+ void unlockFetcher();
+
+ void lockCache();
+ void unlockCache();
+
+ void lockDecoder();
+ void unlockDecoder();
+
+ S32 fillCurlQueue();
+
+ void startDebug();
+ void debugCacheRead();
+ void debugCacheWrite();
+ void debugHTTP();
+ void debugDecoder();
+ void debugGLTextureCreation();
+ void debugRefetchVisibleFromCache();
+ void debugRefetchVisibleFromHTTP();
+ void debugRefetchAllFromCache();
+ void debugRefetchAllFromHTTP();
+
+ bool processStartDebug(F32 max_time);
+ bool processGLCreation(F32 max_time);
+
+private:
+ static bool sDebuggerEnabled;
+public:
+ static bool isEnabled() {return sDebuggerEnabled;}
+};
#endif // LL_LLTEXTUREFETCH_H
diff --git a/indra/newview/lltextureinfo.cpp b/indra/newview/lltextureinfo.cpp
index adfdbc997e..adfdbc997e 100644..100755
--- a/indra/newview/lltextureinfo.cpp
+++ b/indra/newview/lltextureinfo.cpp
diff --git a/indra/newview/lltextureinfo.h b/indra/newview/lltextureinfo.h
index 2ccbcc5fd2..2ccbcc5fd2 100644..100755
--- a/indra/newview/lltextureinfo.h
+++ b/indra/newview/lltextureinfo.h
diff --git a/indra/newview/lltextureinfodetails.cpp b/indra/newview/lltextureinfodetails.cpp
index 0d750db3bf..0d750db3bf 100644..100755
--- a/indra/newview/lltextureinfodetails.cpp
+++ b/indra/newview/lltextureinfodetails.cpp
diff --git a/indra/newview/lltextureinfodetails.h b/indra/newview/lltextureinfodetails.h
index 4a3cd29084..4a3cd29084 100644..100755
--- a/indra/newview/lltextureinfodetails.h
+++ b/indra/newview/lltextureinfodetails.h
diff --git a/indra/newview/lltexturestats.cpp b/indra/newview/lltexturestats.cpp
index f820ae65df..f820ae65df 100644..100755
--- a/indra/newview/lltexturestats.cpp
+++ b/indra/newview/lltexturestats.cpp
diff --git a/indra/newview/lltexturestats.h b/indra/newview/lltexturestats.h
index 09bab41fc3..09bab41fc3 100644..100755
--- a/indra/newview/lltexturestats.h
+++ b/indra/newview/lltexturestats.h
diff --git a/indra/newview/lltexturestatsuploader.cpp b/indra/newview/lltexturestatsuploader.cpp
index 23ba09cb91..23ba09cb91 100644..100755
--- a/indra/newview/lltexturestatsuploader.cpp
+++ b/indra/newview/lltexturestatsuploader.cpp
diff --git a/indra/newview/lltexturestatsuploader.h b/indra/newview/lltexturestatsuploader.h
index 6b02aeb845..6b02aeb845 100644..100755
--- a/indra/newview/lltexturestatsuploader.h
+++ b/indra/newview/lltexturestatsuploader.h
diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp
index 5b41a05f2a..e80136b286 100644..100755
--- a/indra/newview/lltextureview.cpp
+++ b/indra/newview/lltextureview.cpp
@@ -4,7 +4,7 @@
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
+ * Copyright (C) 2012, 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
@@ -40,7 +40,7 @@
#include "lltooltip.h"
#include "llappviewer.h"
#include "llselectmgr.h"
-#include "lltexlayer.h"
+#include "llviewertexlayer.h"
#include "lltexturecache.h"
#include "lltexturefetch.h"
#include "llviewercontrol.h"
@@ -57,8 +57,6 @@
extern F32 texmem_lower_bound_scale;
LLTextureView *gTextureView = NULL;
-LLTextureSizeView *gTextureSizeView = NULL;
-LLTextureSizeView *gTextureCategoryView = NULL;
#define HIGH_PRIORITY 100000000.f
@@ -76,7 +74,7 @@ static std::string title_string4(" W x H (Dis) Mem");
static S32 title_x1 = 0;
static S32 title_x2 = 460;
static S32 title_x3 = title_x2 + 40;
-static S32 title_x4 = title_x3 + 50;
+static S32 title_x4 = title_x3 + 46;
static S32 texture_bar_height = 8;
////////////////////////////////////////////////////////////////////////////
@@ -172,7 +170,7 @@ void LLTextureBar::draw()
{
color = LLColor4::green4;
}
- else if (mImagep->getBoostLevel() > LLViewerTexture::BOOST_NONE)
+ else if (mImagep->getBoostLevel() > LLGLTexture::BOOST_NONE)
{
color = LLColor4::magenta;
}
@@ -234,6 +232,8 @@ void LLTextureBar::draw()
{ "DSK", LLColor4::blue }, // CACHE_POST
{ "NET", LLColor4::green }, // LOAD_FROM_NETWORK
{ "SIM", LLColor4::green }, // LOAD_FROM_SIMULATOR
+ { "HTW", LLColor4::green }, // WAIT_HTTP_RESOURCE
+ { "HTW", LLColor4::green }, // WAIT_HTTP_RESOURCE2
{ "REQ", LLColor4::yellow },// SEND_HTTP_REQ
{ "HTP", LLColor4::green }, // WAIT_HTTP_REQ
{ "DEC", LLColor4::yellow },// DECODE_IMAGE
@@ -241,7 +241,7 @@ void LLTextureBar::draw()
{ "WRT", LLColor4::purple },// WRITE_TO_CACHE
{ "WRT", LLColor4::orange },// WAIT_ON_WRITE
{ "END", LLColor4::red }, // DONE
-#define LAST_STATE 12
+#define LAST_STATE 14
{ "CRE", LLColor4::magenta }, // LAST_STATE+1
{ "FUL", LLColor4::green }, // LAST_STATE+2
{ "BAD", LLColor4::red }, // LAST_STATE+3
@@ -347,7 +347,7 @@ void LLTextureBar::draw()
// draw the image size at the end
{
- std::string num_str = llformat("%3dx%3d (%d) %7d", mImagep->getWidth(), mImagep->getHeight(),
+ std::string num_str = llformat("%3dx%3d (%2d) %7d", mImagep->getWidth(), mImagep->getHeight(),
mImagep->getDiscardLevel(), mImagep->hasGLTexture() ? mImagep->getTextureMemory() : 0);
LLFontGL::getFontMonospace()->renderUTF8(num_str, 0, title_x4, getRect().getHeight(), color,
LLFontGL::LEFT, LLFontGL::TOP);
@@ -420,14 +420,14 @@ void LLAvatarTexBar::draw()
LLColor4 color;
U32 line_num = 1;
- for (LLVOAvatarDefines::LLVOAvatarDictionary::BakedTextures::const_iterator baked_iter = LLVOAvatarDefines::LLVOAvatarDictionary::getInstance()->getBakedTextures().begin();
- baked_iter != LLVOAvatarDefines::LLVOAvatarDictionary::getInstance()->getBakedTextures().end();
+ for (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().begin();
+ baked_iter != LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().end();
++baked_iter)
{
- const LLVOAvatarDefines::EBakedTextureIndex baked_index = baked_iter->first;
- const LLTexLayerSet *layerset = avatarp->debugGetLayerSet(baked_index);
+ const LLAvatarAppearanceDefines::EBakedTextureIndex baked_index = baked_iter->first;
+ const LLViewerTexLayerSet *layerset = avatarp->debugGetLayerSet(baked_index);
if (!layerset) continue;
- const LLTexLayerSetBuffer *layerset_buffer = layerset->getComposite();
+ const LLViewerTexLayerSetBuffer *layerset_buffer = layerset->getViewerComposite();
if (!layerset_buffer) continue;
LLColor4 text_color = LLColor4::white;
@@ -513,94 +513,54 @@ void LLGLTexMemBar::draw()
F32 cache_usage = (F32)BYTES_TO_MEGA_BYTES(LLAppViewer::getTextureCache()->getUsage()) ;
F32 cache_max_usage = (F32)BYTES_TO_MEGA_BYTES(LLAppViewer::getTextureCache()->getMaxUsage()) ;
S32 line_height = LLFontGL::getFontMonospace()->getLineHeight();
- S32 v_offset = (S32)((texture_bar_height + 2.2f) * mTextureView->mNumTextureBars + 2.0f);
+ S32 v_offset = 0;//(S32)((texture_bar_height + 2.2f) * mTextureView->mNumTextureBars + 2.0f);
F32 total_texture_downloaded = (F32)gTotalTextureBytes / (1024 * 1024);
F32 total_object_downloaded = (F32)gTotalObjectBytes / (1024 * 1024);
- U32 total_http_requests = LLAppViewer::getTextureFetch()->getTotalNumHTTPRequests() ;
+ U32 total_http_requests = LLAppViewer::getTextureFetch()->getTotalNumHTTPRequests();
//----------------------------------------------------------------------------
LLGLSUIDefault gls_ui;
LLColor4 text_color(1.f, 1.f, 1.f, 0.75f);
LLColor4 color;
-
- std::string text = "";
+ // Gray background using completely magic numbers
+ gGL.color4f(0.f, 0.f, 0.f, 0.25f);
+ // const LLRect & rect(getRect());
+ // gl_rect_2d(-4, v_offset, rect.mRight - rect.mLeft + 2, v_offset + line_height*4);
+
+ std::string text = "";
LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*6,
text_color, LLFontGL::LEFT, LLFontGL::TOP);
- text = llformat("GL Tot: %d/%d MB Bound: %d/%d MB FBO: %d MB Raw Tot: %d MB Bias: %.2f Cache: %.1f/%.1f MB Net Tot Tex: %.1f MB Tot Obj: %.1f MB Tot Htp: %d",
+ text = llformat("GL Tot: %d/%d MB Bound: %d/%d MB FBO: %d MB Raw Tot: %d MB Bias: %.2f Cache: %.1f/%.1f MB",
total_mem,
max_total_mem,
bound_mem,
max_bound_mem,
LLRenderTarget::sBytesAllocated/(1024*1024),
- LLImageRaw::sGlobalRawMemory >> 20, discard_bias,
- cache_usage, cache_max_usage, total_texture_downloaded, total_object_downloaded, total_http_requests);
+ LLImageRaw::sGlobalRawMemory >> 20,
+ discard_bias,
+ cache_usage,
+ cache_max_usage);
//, cache_entries, cache_max_entries
- LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*3,
+ LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*4,
text_color, LLFontGL::LEFT, LLFontGL::TOP);
- //----------------------------------------------------------------------------
-#if 0
- S32 bar_left = 400;
- S32 bar_width = 200;
- S32 top = line_height*3 - 2 + v_offset;
- S32 bottom = top - 6;
- S32 left = bar_left;
- S32 right = left + bar_width;
- F32 bar_scale;
+ U32 cache_read(0U), cache_write(0U), res_wait(0U);
+ LLAppViewer::getTextureFetch()->getStateStats(&cache_read, &cache_write, &res_wait);
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ text = llformat("Net Tot Tex: %.1f MB Tot Obj: %.1f MB Tot Htp: %d Cread: %u Cwrite: %u Rwait: %u",
+ total_texture_downloaded,
+ total_object_downloaded,
+ total_http_requests,
+ cache_read,
+ cache_write,
+ res_wait);
- // GL Mem Bar
-
- left = bar_left;
- text = "GL";
- LLFontGL::getFontMonospace()->renderUTF8(text, 0, left, line_height*3,
+ LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*3,
text_color, LLFontGL::LEFT, LLFontGL::TOP);
-
- left = bar_left+20;
- right = left + bar_width;
-
- gGL.color4f(0.5f, 0.5f, 0.5f, 0.75f); // grey
- gl_rect_2d(left, top, right, bottom);
-
- bar_scale = (F32)bar_width / (max_total_mem * 1.5f);
- right = left + llfloor(total_mem * bar_scale);
- right = llclamp(right, bar_left, bar_left + bar_width);
-
- color = (total_mem < llfloor(max_total_mem * texmem_lower_bound_scale)) ? LLColor4::green :
- (total_mem < max_total_mem) ? LLColor4::yellow : LLColor4::red;
- color[VALPHA] = .75f;
- gGL.diffuseColor4fv(color.mV);
-
- gl_rect_2d(left, top, right, bottom); // red/yellow/green
-
- //
- bar_left += bar_width + bar_space;
- //top = bottom - 2; bottom = top - 6;
-
- // Bound Mem Bar
-
- left = bar_left;
- text = "GL";
- LLFontGL::getFontMonospace()->renderUTF8(text, 0, left, line_height*3,
- text_color, LLFontGL::LEFT, LLFontGL::TOP);
- left = bar_left + 20;
- right = left + bar_width;
-
- gGL.color4f(0.5f, 0.5f, 0.5f, 0.75f);
- gl_rect_2d(left, top, right, bottom);
-
- color = (bound_mem < llfloor(max_bound_mem * texmem_lower_bound_scale)) ? LLColor4::green :
- (bound_mem < max_bound_mem) ? LLColor4::yellow : LLColor4::red;
- color[VALPHA] = .75f;
- gGL.diffuseColor4fv(color.mV);
- gl_rect_2d(left, top, right, bottom);
-#else
S32 left = 0 ;
-#endif
//----------------------------------------------------------------------------
text = llformat("Textures: %d Fetch: %d(%d) Pkts:%d(%d) Cache R/W: %d/%d LFS:%d RAW:%d HTP:%d DEC:%d CRE:%d",
@@ -669,8 +629,7 @@ BOOL LLGLTexMemBar::handleMouseDown(S32 x, S32 y, MASK mask)
LLRect LLGLTexMemBar::getRequiredRect()
{
LLRect rect;
- //rect.mTop = 50;
- rect.mTop = 0;
+ rect.mTop = 50; //LLFontGL::getFontMonospace()->getLineHeight() * 6;
return rect;
}
@@ -954,9 +913,11 @@ void LLTextureView::draw()
LLRect tmbr;
tmbp.name("gl texmem bar");
tmbp.rect(tmbr);
+ tmbp.follows.flags = FOLLOWS_LEFT|FOLLOWS_TOP;
tmbp.texture_view(this);
mGLTexMemBar = LLUICtrlFactory::create<LLGLTexMemBar>(tmbp);
- addChildInBack(mGLTexMemBar);
+ addChild(mGLTexMemBar);
+ sendChildToFront(mGLTexMemBar);
LLAvatarTexBar::Params atbp;
LLRect atbr;
@@ -965,16 +926,13 @@ void LLTextureView::draw()
atbp.rect(atbr);
mAvatarTexBar = LLUICtrlFactory::create<LLAvatarTexBar>(atbp);
addChild(mAvatarTexBar);
+ sendChildToFront(mAvatarTexBar);
reshape(getRect().getWidth(), getRect().getHeight(), TRUE);
- /*
- count = gTextureList.getNumImages();
- std::string info_string;
- info_string = llformat("Global Info:\nTexture Count: %d", count);
- mInfoTextp->setText(info_string);
- */
-
+ LLUI::popMatrix();
+ LLUI::pushMatrix();
+ LLUI::translate((F32)getRect().mLeft, (F32)getRect().mBottom);
for (child_list_const_iter_t child_iter = getChildList()->begin();
child_iter != getChildList()->end(); ++child_iter)
@@ -1049,302 +1007,4 @@ BOOL LLTextureView::handleKey(KEY key, MASK mask, BOOL called_from_parent)
return FALSE;
}
-//-----------------------------------------------------------------
-LLTextureSizeView::LLTextureSizeView(const LLTextureSizeView::Params& p) : LLContainerView(p)
-{
- setVisible(FALSE) ;
-
- mTextureSizeBarWidth = 30 ;
-}
-
-LLTextureSizeView::~LLTextureSizeView()
-{
- if(mTextureSizeBar.size())
- {
- for(U32 i = 0 ; i < mTextureSizeBar.size() ; i++)
- {
- delete mTextureSizeBar[i] ;
- }
- mTextureSizeBar.clear() ;
- }
-}
-void LLTextureSizeView::draw()
-{
- if(mType == TEXTURE_MEM_OVER_SIZE)
- {
- drawTextureSizeGraph();
- }
- else
- {
- drawTextureCategoryGraph() ;
- }
-
- LLView::draw();
-}
-
-BOOL LLTextureSizeView::handleHover(S32 x, S32 y, MASK mask)
-{
- if(x > mTextureSizeBarRect.mLeft && x < mTextureSizeBarRect.mRight)
- {
- mTextureSizeBar[(x - mTextureSizeBarRect.mLeft) / mTextureSizeBarWidth]->handleHover(x, y, mask, (mType == TEXTURE_MEM_OVER_SIZE)) ;
- }
-
- return TRUE ;
-}
-
-//draw real-time texture mem bar over size
-void LLTextureSizeView::drawTextureSizeGraph()
-{
- if(mTextureSizeBar.size() == 0)
- {
- S32 line_height = LLFontGL::getFontMonospace()->getLineHeight();
- mTextureSizeBar.resize(LLImageGL::sTextureLoadedCounter.size()) ;
- mTextureSizeBarRect.set(700, line_height * 2 + 400, 700 + mTextureSizeBar.size() * mTextureSizeBarWidth, line_height * 2) ;
-
- for(U32 i = 0 ; i < mTextureSizeBar.size() ; i++)
- {
- mTextureSizeBar[i] = new LLGLTexSizeBar(i, mTextureSizeBarRect.mLeft + i * mTextureSizeBarWidth ,
- line_height * 2, mTextureSizeBarRect.mLeft + (i + 1) * mTextureSizeBarWidth, line_height) ;
- }
- }
-
- F32 size_bar_scale = drawTextureSizeDistributionGraph() ;
- for(U32 i = 0 ; i < mTextureSizeBar.size() ; i++)
- {
- mTextureSizeBar[i]->setTop(LLImageGL::sTextureLoadedCounter[i], LLImageGL::sTextureBoundCounter[i], size_bar_scale) ;
- mTextureSizeBar[i]->draw() ;
- }
- LLImageGL::resetCurTexSizebar();
-}
-
-//draw background of texture size bar graph
-F32 LLTextureSizeView::drawTextureSizeDistributionGraph()
-{
- //scale
- F32 scale = 1.0f ;
-
- LLGLSUIDefault gls_ui;
-
- {
- S32 count = 0 ;
- for(U32 i = 0 ; i < LLImageGL::sTextureLoadedCounter.size() ; i++)
- {
- if(LLImageGL::sTextureLoadedCounter[i] > count)
- {
- count = LLImageGL::sTextureLoadedCounter[i] ;
- }
- }
- if(count > mTextureSizeBarRect.getHeight())
- {
- scale = (F32)mTextureSizeBarRect.getHeight() / count ;
- }
- }
-
- S32 line_height = LLFontGL::getFontMonospace()->getLineHeight();
- S32 left = mTextureSizeBarRect.mLeft ;
- S32 bottom = mTextureSizeBarRect.mBottom ;
- S32 right = mTextureSizeBarRect.mRight ;
- S32 top = mTextureSizeBarRect.mTop ;
-
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
- //background rect
- gl_rect_2d(left - 25, top + 30, right + 100, bottom - 25, LLColor4(0.0f, 0.0f, 0.0f, 0.25f)) ;
-
- //--------------------------------------------------
- gGL.color4f(1.0f, 0.5f, 0.5f, 0.75f);
- gl_line_2d(left, bottom, right, bottom) ; //x axis
- gl_line_2d(left, bottom, left, top) ; //y axis
-
- //ruler
- //--------------------------------------------------
- gGL.color4f(1.0f, 0.5f, 0.5f, 0.5f);
- for(S32 i = bottom + 50 ; i <= top ; i += 50)
- {
- gl_line_2d(left, i, right, i) ;
- }
-
- //texts
- //--------------------------------------------------
- F32 text_color[] = {1.f, 1.f, 1.f, 0.75f};
- std::string text;
-
- //-------
- //x axis: size label
- text = llformat("%d", 0) ;
- LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + 12, bottom - line_height / 2,
- text_color, LLFontGL::LEFT, LLFontGL::TOP);
- for(U32 i = 1 ; i < mTextureSizeBar.size() ; i++)
- {
- text = llformat("%d", (1 << (i / 2)) + ((i & 1) ? ((1 << (i / 2)) >> 1) : 0)) ;
- LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + i * mTextureSizeBarWidth + 12, bottom - line_height / 2,
- text_color, LLFontGL::LEFT, LLFontGL::TOP);
- }
- text = llformat("(w + h)/2") ;
- LLFontGL::getFontMonospace()->renderUTF8(text, 0, right + 10, bottom - line_height / 2,
- text_color, LLFontGL::LEFT, LLFontGL::TOP);
- //-------
-
- //y axis: number label
- for(S32 i = bottom + 50 ; i <= top ; i += 50)
- {
- text = llformat("%d", (S32)((i - bottom) / scale)) ;
- LLFontGL::getFontMonospace()->renderUTF8(text, 0, left - 20, i + line_height / 2 ,
- text_color, LLFontGL::LEFT, LLFontGL::TOP);
- LLFontGL::getFontMonospace()->renderUTF8(text, 0, right + 5, i + line_height / 2 ,
- text_color, LLFontGL::LEFT, LLFontGL::TOP);
- }
-
- //--------------------------------------------------
- F32 loaded_color[] = {1.0f, 0.0f, 0.0f, 0.75f};
- gl_rect_2d(left + 70, top + line_height * 2, left + 90, top + line_height, loaded_color) ;
- text = llformat("Loaded") ;
- LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + 100, top + line_height * 2,
- loaded_color, LLFontGL::LEFT, LLFontGL::TOP);
-
- F32 bound_color[] = {1.0f, 1.0f, 0.0f, 0.75f};
- gl_rect_2d(left + 170, top + line_height * 2, left + 190, top + line_height, bound_color) ;
- text = llformat("Bound") ;
- LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + 200, top + line_height * 2,
- bound_color, LLFontGL::LEFT, LLFontGL::TOP);
-
- //--------------------------------------------------
-
- //title
- text = llformat("Texture Size Distribution") ;
- LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + 250, top + line_height * 3,
- text_color, LLFontGL::LEFT, LLFontGL::TOP);
- return scale ;
-}
-
-//draw real-time texture mem bar over category
-void LLTextureSizeView::drawTextureCategoryGraph()
-{
- if(mTextureSizeBar.size() == 0)
- {
- S32 line_height = LLFontGL::getFontMonospace()->getLineHeight();
- mTextureSizeBar.resize(LLViewerTexture::getTotalNumOfCategories()) ;
- mTextureSizeBarRect.set(700, line_height * 2 + 400, 700 + mTextureSizeBar.size() * mTextureSizeBarWidth, line_height * 2) ;
-
- for(U32 i = 0 ; i < mTextureSizeBar.size() ; i++)
- {
- mTextureSizeBar[i] = new LLGLTexSizeBar(i, mTextureSizeBarRect.mLeft + i * mTextureSizeBarWidth ,
- line_height * 2, mTextureSizeBarRect.mLeft + (i + 1) * mTextureSizeBarWidth, line_height) ;
- }
- }
-
- F32 size_bar_scale = drawTextureCategoryDistributionGraph() ;
- for(U32 i = 0 ; i < mTextureSizeBar.size() ; i++)
- {
- U32 k = LLViewerTexture::getIndexFromCategory(i) ;
- mTextureSizeBar[i]->setTop(LLImageGL::sTextureMemByCategory[k] >> 20, LLImageGL::sTextureMemByCategoryBound[k] >> 20, size_bar_scale) ;
- mTextureSizeBar[i]->draw() ;
- }
- LLImageGL::resetCurTexSizebar();
-}
-
-//draw background for TEXTURE_MEM_OVER_CATEGORY
-F32 LLTextureSizeView::drawTextureCategoryDistributionGraph()
-{
- //scale
- F32 scale = 4.0f ;
-
- LLGLSUIDefault gls_ui;
-
- {
- S32 count = 0 ;
- for(U32 i = 0 ; i < LLImageGL::sTextureMemByCategory.size() ; i++)
- {
- S32 tmp = LLImageGL::sTextureMemByCategory[i] >> 20 ;
- if(tmp > count)
- {
- count = tmp ;
- }
- }
- if(count > mTextureSizeBarRect.getHeight() * 0.25f)
- {
- scale = (F32)mTextureSizeBarRect.getHeight() * 0.25f / count ;
- }
- }
-
- S32 line_height = LLFontGL::getFontMonospace()->getLineHeight();
- S32 left = mTextureSizeBarRect.mLeft ;
- S32 bottom = mTextureSizeBarRect.mBottom ;
- S32 right = mTextureSizeBarRect.mRight ;
- S32 top = mTextureSizeBarRect.mTop ;
-
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
- //background rect
- gl_rect_2d(left - 25, top + 30, right + 100, bottom - 25, LLColor4(0.0f, 0.0f, 0.0f, 0.25f)) ;
-
- //--------------------------------------------------
- gGL.color4f(1.0f, 0.5f, 0.5f, 0.75f);
- gl_line_2d(left, bottom, right, bottom) ; //x axis
- gl_line_2d(left, bottom, left, top) ; //y axis
-
- //ruler
- //--------------------------------------------------
- gGL.color4f(1.0f, 0.5f, 0.5f, 0.5f);
- for(S32 i = bottom + 50 ; i <= top ; i += 50)
- {
- gl_line_2d(left, i, right, i) ;
- }
-
- //texts
- //--------------------------------------------------
- F32 text_color[] = {1.f, 1.f, 1.f, 0.75f};
- std::string text;
-
- //-------
- //x axis: size label
- static char category[LLViewerTexture::MAX_GL_IMAGE_CATEGORY][4] =
- {"Non", "Bak", "Av", "Cld", "Scp", "Hi", "Trn", "Slt", "Hud", "Bsf", "UI", "Pvw", "Map", "Mvs", "Slf", "Loc", "Scr", "Dyn", "Mdi", "ALT", "Oth" } ;
-
- text = llformat("%s", category[0]) ;
- LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + 12, bottom - line_height / 2,
- text_color, LLFontGL::LEFT, LLFontGL::TOP);
- for(U32 i = 1 ; i < mTextureSizeBar.size() ; i++)
- {
- text = llformat("%s", category[i]) ;
- LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + i * mTextureSizeBarWidth + 12, bottom - line_height / 2,
- text_color, LLFontGL::LEFT, LLFontGL::TOP);
- }
- //-------
-
- //y axis: number label
- for(S32 i = bottom + 50 ; i <= top ; i += 50)
- {
- text = llformat("%d", (S32)((i - bottom) / scale)) ;
- LLFontGL::getFontMonospace()->renderUTF8(text, 0, left - 20, i + line_height / 2 ,
- text_color, LLFontGL::LEFT, LLFontGL::TOP);
- LLFontGL::getFontMonospace()->renderUTF8(text, 0, right + 5, i + line_height / 2 ,
- text_color, LLFontGL::LEFT, LLFontGL::TOP);
- }
- text = llformat("MB") ;
- LLFontGL::getFontMonospace()->renderUTF8(text, 0, left - 20, top + line_height * 2 ,
- text_color, LLFontGL::LEFT, LLFontGL::TOP);
- //--------------------------------------------------
- F32 loaded_color[] = {1.0f, 0.0f, 0.0f, 0.75f};
- gl_rect_2d(left + 70, top + line_height * 2, left + 90, top + line_height, loaded_color) ;
- text = llformat("Loaded") ;
- LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + 100, top + line_height * 2,
- loaded_color,
- LLFontGL::LEFT, LLFontGL::TOP);
-
- F32 bound_color[] = {1.0f, 1.0f, 0.0f, 0.75f};
- gl_rect_2d(left + 170, top + line_height * 2, left + 190, top + line_height, bound_color) ;
- text = llformat("Bound") ;
- LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + 200, top + line_height * 2,
- bound_color, LLFontGL::LEFT, LLFontGL::TOP);
-
- //--------------------------------------------------
-
- //title
- text = llformat("Texture Category Distribution") ;
- LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + 250, top + line_height * 3,
- text_color, LLFontGL::LEFT, LLFontGL::TOP);
-
- return scale ;
-}
diff --git a/indra/newview/lltextureview.h b/indra/newview/lltextureview.h
index 3723eb737b..900b4e17d8 100644..100755
--- a/indra/newview/lltextureview.h
+++ b/indra/newview/lltextureview.h
@@ -75,41 +75,6 @@ public:
};
class LLGLTexSizeBar;
-class LLTextureSizeView : public LLContainerView
-{
-protected:
- LLTextureSizeView(const Params&);
- friend class LLUICtrlFactory;
-public:
- ~LLTextureSizeView();
-
- /*virtual*/ void draw();
- /*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask) ;
-
- void setType(S32 type) {mType = type ;}
- enum
- {
- TEXTURE_MEM_OVER_SIZE,
- TEXTURE_MEM_OVER_CATEGORY
- };
-private:
- //draw background for TEXTURE_MEM_OVER_SIZE
- F32 drawTextureSizeDistributionGraph() ;
- //draw real-time texture mem bar over size
- void drawTextureSizeGraph();
-
- //draw background for TEXTURE_MEM_OVER_CATEGORY
- F32 drawTextureCategoryDistributionGraph() ;
- //draw real-time texture mem bar over category
- void drawTextureCategoryGraph();
-private:
- std::vector<LLGLTexSizeBar*> mTextureSizeBar ;
- LLRect mTextureSizeBarRect ;
- S32 mTextureSizeBarWidth ;
- S32 mType ;
-};
extern LLTextureView *gTextureView;
-extern LLTextureSizeView *gTextureSizeView;
-extern LLTextureSizeView *gTextureCategoryView;
#endif // LL_TEXTURE_VIEW_H
diff --git a/indra/newview/lltoast.cpp b/indra/newview/lltoast.cpp
index 0eec7f0afd..448fae48de 100644..100755
--- a/indra/newview/lltoast.cpp
+++ b/indra/newview/lltoast.cpp
@@ -118,7 +118,7 @@ LLToast::LLToast(const LLToast::Params& p)
{
mTimer.reset(new LLToastLifeTimer(this, p.lifetime_secs));
- buildFromFile("panel_toast.xml", NULL);
+ buildFromFile("panel_toast.xml");
setCanDrag(FALSE);
@@ -173,8 +173,20 @@ void LLToast::setHideButtonEnabled(bool enabled)
//--------------------------------------------------------------------------
LLToast::~LLToast()
-{
- mOnToastDestroyedSignal(this);
+{
+ if(LLApp::isQuitting())
+ {
+ mOnFadeSignal.disconnect_all_slots();
+ mOnDeleteToastSignal.disconnect_all_slots();
+ mOnToastDestroyedSignal.disconnect_all_slots();
+ mOnToastHoverSignal.disconnect_all_slots();
+ mToastMouseEnterSignal.disconnect_all_slots();
+ mToastMouseLeaveSignal.disconnect_all_slots();
+ }
+ else
+ {
+ mOnToastDestroyedSignal(this);
+ }
}
//--------------------------------------------------------------------------
@@ -543,7 +555,7 @@ BOOL LLToast::handleMouseDown(S32 x, S32 y, MASK mask)
mHideBtnPressed = mHideBtn->getRect().pointInRect(x, y);
}
- return LLFloater::handleMouseDown(x, y, mask);
+ return LLModalDialog::handleMouseDown(x, y, mask);
}
//--------------------------------------------------------------------------
@@ -572,10 +584,34 @@ S32 LLToast::notifyParent(const LLSD& info)
//static
void LLToast::updateClass()
{
- for (LLInstanceTracker<LLToast>::instance_iter iter = LLInstanceTracker<LLToast>::beginInstances(); iter != LLInstanceTracker<LLToast>::endInstances(); )
+ for (LLInstanceTracker<LLToast>::instance_iter iter = LLInstanceTracker<LLToast>::beginInstances();
+ iter != LLInstanceTracker<LLToast>::endInstances(); )
{
LLToast& toast = *iter++;
toast.updateHoveredState();
}
}
+
+// static
+void LLToast::cleanupToasts()
+{
+ LLToast * toastp = NULL;
+
+ while (LLInstanceTracker<LLToast>::instanceCount() > 0)
+ {
+ { // Need to scope iter to allow deletion
+ LLInstanceTracker<LLToast>::instance_iter iter = LLInstanceTracker<LLToast>::beginInstances();
+ toastp = &(*iter);
+ }
+
+ //llinfos << "Cleaning up toast id " << toastp->getNotificationID() << llendl;
+
+ // LLToast destructor will remove it from the LLInstanceTracker.
+ if (!toastp)
+ break; // Don't get stuck in the loop if a null pointer somehow got on the list
+
+ delete toastp;
+ }
+}
+
diff --git a/indra/newview/lltoast.h b/indra/newview/lltoast.h
index e1d99b1bcb..f02d7c2a1a 100644..100755
--- a/indra/newview/lltoast.h
+++ b/indra/newview/lltoast.h
@@ -73,6 +73,7 @@ class LLToast : public LLModalDialog, public LLInstanceTracker<LLToast>
{
friend class LLToastLifeTimer;
public:
+
typedef boost::function<void (LLToast* toast)> toast_callback_t;
typedef boost::signals2::signal<void (LLToast* toast)> toast_signal_t;
typedef boost::signals2::signal<void (LLToast* toast, bool mouse_enter)> toast_hover_check_signal_t;
@@ -105,6 +106,7 @@ public:
};
static void updateClass();
+ static void cleanupToasts();
LLToast(const LLToast::Params& p);
virtual ~LLToast();
@@ -169,6 +171,7 @@ public:
// get/set Toast's flags or states
// get information whether the notification corresponding to the toast is valid or not
bool isNotificationValid();
+
// get toast's Notification ID
const LLUUID getNotificationID() const { return mNotificationID;}
// get toast's Session ID
@@ -212,7 +215,7 @@ private:
//LLRootHandle<LLToast> mHandle;
- LLPanel* mWrapperPanel;
+ LLPanel* mWrapperPanel;
// timer counts a lifetime of a toast
std::auto_ptr<LLToastLifeTimer> mTimer;
@@ -220,8 +223,8 @@ private:
F32 mToastLifetime; // in seconds
F32 mToastFadingTime; // in seconds
- LLPanel* mPanel;
- LLButton* mHideBtn;
+ LLPanel* mPanel;
+ LLButton* mHideBtn;
LLColor4 mBgColor;
bool mCanFade;
diff --git a/indra/newview/lltoastalertpanel.cpp b/indra/newview/lltoastalertpanel.cpp
index 8fef2ed6d1..6083210080 100644..100755
--- a/indra/newview/lltoastalertpanel.cpp
+++ b/indra/newview/lltoastalertpanel.cpp
@@ -357,6 +357,7 @@ LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal
if (mLineEditor)
{
mLineEditor->selectAll();
+ mLineEditor->setFocus(TRUE);
}
if(mDefaultOption >= 0)
{
@@ -491,7 +492,7 @@ void LLToastAlertPanel::draw()
}
static LLUIColor shadow_color = LLUIColorTable::instance().getColor("ColorDropShadow");
- static LLUICachedControl<S32> shadow_lines ("DropShadowFloater");
+ static LLUICachedControl<S32> shadow_lines ("DropShadowFloater", 5);
gl_drop_shadow( 0, LLToastPanel::getRect().getHeight(), LLToastPanel::getRect().getWidth(), 0,
shadow_color, shadow_lines);
diff --git a/indra/newview/lltoastalertpanel.h b/indra/newview/lltoastalertpanel.h
index d1be5e018e..d1be5e018e 100644..100755
--- a/indra/newview/lltoastalertpanel.h
+++ b/indra/newview/lltoastalertpanel.h
diff --git a/indra/newview/lltoastgroupnotifypanel.cpp b/indra/newview/lltoastgroupnotifypanel.cpp
index 75178a6ef8..beb45e8179 100644..100755
--- a/indra/newview/lltoastgroupnotifypanel.cpp
+++ b/indra/newview/lltoastgroupnotifypanel.cpp
@@ -33,6 +33,7 @@
#include "llbutton.h"
#include "lliconctrl.h"
#include "llinventoryfunctions.h"
+#include "llinventoryicon.h"
#include "llnotifications.h"
#include "llviewertexteditor.h"
@@ -51,7 +52,7 @@
const S32 LLToastGroupNotifyPanel::DEFAULT_MESSAGE_MAX_LINE_COUNT = 7;
-LLToastGroupNotifyPanel::LLToastGroupNotifyPanel(LLNotificationPtr& notification)
+LLToastGroupNotifyPanel::LLToastGroupNotifyPanel(const LLNotificationPtr& notification)
: LLToastPanel(notification),
mInventoryOffer(NULL)
{
@@ -69,10 +70,8 @@ LLToastGroupNotifyPanel::LLToastGroupNotifyPanel(LLNotificationPtr& notification
//header title
std::string from_name = payload["sender_name"].asString();
- if (LLAvatarNameCache::useDisplayNames())
- {
- from_name = LLCacheName::buildUsername(from_name);
- }
+ from_name = LLCacheName::buildUsername(from_name);
+
std::stringstream from;
from << from_name << "/" << groupData.mName;
LLTextBox* pTitleText = getChild<LLTextBox>("title");
@@ -112,7 +111,7 @@ LLToastGroupNotifyPanel::LLToastGroupNotifyPanel(LLNotificationPtr& notification
style.font = date_font;
pMessageText->appendText(timeStr + "\n", TRUE, style);
- style.font = pMessageText->getDefaultFont();
+ style.font = pMessageText->getFont();
pMessageText->appendText(message, TRUE, style);
//attachment
diff --git a/indra/newview/lltoastgroupnotifypanel.h b/indra/newview/lltoastgroupnotifypanel.h
index 7794ec9f63..dfdc6ae559 100644..100755
--- a/indra/newview/lltoastgroupnotifypanel.h
+++ b/indra/newview/lltoastgroupnotifypanel.h
@@ -47,13 +47,10 @@ class LLToastGroupNotifyPanel
public:
void close();
- static bool onNewNotification(const LLSD& notification);
-
-
// Non-transient messages. You can specify non-default button
// layouts (like one for script dialogs) by passing various
// numbers in for "layout".
- LLToastGroupNotifyPanel(LLNotificationPtr& notification);
+ LLToastGroupNotifyPanel(const LLNotificationPtr& notification);
/*virtual*/ ~LLToastGroupNotifyPanel();
protected:
diff --git a/indra/newview/lltoastimpanel.cpp b/indra/newview/lltoastimpanel.cpp
index e0cb200ef5..bdbd8f1f83 100644..100755
--- a/indra/newview/lltoastimpanel.cpp
+++ b/indra/newview/lltoastimpanel.cpp
@@ -28,6 +28,7 @@
#include "lltoastimpanel.h"
#include "llagent.h"
+#include "llavatarnamecache.h"
#include "llfloaterreg.h"
#include "llgroupactions.h"
#include "llgroupiconctrl.h"
@@ -61,6 +62,15 @@ LLToastIMPanel::LLToastIMPanel(LLToastIMPanel::Params &p) : LLToastPanel(p.notif
style_params.font.name(font_name);
style_params.font.size(font_size);
+ LLIMModel::LLIMSession* im_session = LLIMModel::getInstance()->findIMSession(p.session_id);
+ mIsGroupMsg = (im_session && im_session->mSessionType == LLIMModel::LLIMSession::GROUP_SESSION);
+ if(mIsGroupMsg)
+ {
+ mAvatarName->setValue(im_session->mName);
+ LLAvatarName avatar_name;
+ LLAvatarNameCache::get(p.avatar_id, &avatar_name);
+ p.message = "[From " + avatar_name.getDisplayName() + "]\n" + p.message;
+ }
//Handle IRC styled /me messages.
std::string prefix = p.message.substr(0, 4);
@@ -81,12 +91,17 @@ LLToastIMPanel::LLToastIMPanel(LLToastIMPanel::Params &p) : LLToastPanel(p.notif
mMessage->setText(p.message, style_params);
}
+ if(!mIsGroupMsg)
+ {
mAvatarName->setValue(p.from);
+ }
mTime->setValue(p.time);
mSessionID = p.session_id;
mAvatarID = p.avatar_id;
mNotification = p.notification;
+
+
initIcon();
S32 maxLinesCount;
@@ -104,9 +119,9 @@ LLToastIMPanel::~LLToastIMPanel()
}
//virtual
-BOOL LLToastIMPanel::handleMouseDown(S32 x, S32 y, MASK mask)
+BOOL LLToastIMPanel::handleMouseUp(S32 x, S32 y, MASK mask)
{
- if (LLPanel::handleMouseDown(x,y,mask) == FALSE)
+ if (LLPanel::handleMouseUp(x,y,mask) == FALSE)
{
mNotification->respond(mNotification->getResponseTemplate());
}
@@ -147,7 +162,14 @@ void LLToastIMPanel::spawnNameToolTip()
LLToolTip::Params params;
params.background_visible(false);
+ if(!mIsGroupMsg)
+ {
params.click_callback(boost::bind(&LLFloaterReg::showInstance, "inspect_avatar", LLSD().with("avatar_id", mAvatarID), FALSE));
+ }
+ else
+ {
+ params.click_callback(boost::bind(&LLFloaterReg::showInstance, "inspect_group", LLSD().with("group_id", mSessionID), FALSE));
+ }
params.delay_time(0.0f); // spawn instantly on hover
params.image(LLUI::getUIImage("Info_Small"));
params.message("");
diff --git a/indra/newview/lltoastimpanel.h b/indra/newview/lltoastimpanel.h
index a803387576..767617dabc 100644..100755
--- a/indra/newview/lltoastimpanel.h
+++ b/indra/newview/lltoastimpanel.h
@@ -41,18 +41,18 @@ public:
struct Params
{
LLNotificationPtr notification;
- LLUUID avatar_id;
- LLUUID session_id;
- std::string from;
- std::string time;
- std::string message;
+ LLUUID avatar_id,
+ session_id;
+ std::string from,
+ time,
+ message;
Params() {}
};
LLToastIMPanel(LLToastIMPanel::Params &p);
virtual ~LLToastIMPanel();
- /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask);
+ /*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask);
/*virtual*/ BOOL handleToolTip(S32 x, S32 y, MASK mask);
private:
void showInspector();
@@ -73,6 +73,8 @@ private:
LLTextBox* mAvatarName;
LLTextBox* mTime;
LLTextBox* mMessage;
+
+ bool mIsGroupMsg;
};
#endif // LLTOASTIMPANEL_H_
diff --git a/indra/newview/lltoastnotifypanel.cpp b/indra/newview/lltoastnotifypanel.cpp
index a8060649ba..3a41bf28b4 100644..100755
--- a/indra/newview/lltoastnotifypanel.cpp
+++ b/indra/newview/lltoastnotifypanel.cpp
@@ -40,11 +40,14 @@
#include "lltrans.h"
#include "llnotificationsutil.h"
#include "llviewermessage.h"
-#include "llimfloater.h"
+#include "llfloaterimsession.h"
const S32 BOTTOM_PAD = VPAD * 3;
const S32 IGNORE_BTN_TOP_DELTA = 3*VPAD;//additional ignore_btn padding
S32 BUTTON_WIDTH = 90;
+// *TODO: magic numbers(???) - copied from llnotify.cpp(250)
+const S32 MAX_LENGTH = 512 + 20 + DB_FIRST_NAME_BUF_SIZE + DB_LAST_NAME_BUF_SIZE + DB_INV_ITEM_NAME_BUF_SIZE;
+
//static
const LLFontGL* LLToastNotifyPanel::sFont = NULL;
@@ -52,171 +55,11 @@ const LLFontGL* LLToastNotifyPanel::sFontSmall = NULL;
LLToastNotifyPanel::button_click_signal_t LLToastNotifyPanel::sButtonClickSignal;
-LLToastNotifyPanel::LLToastNotifyPanel(LLNotificationPtr& notification, const LLRect& rect, bool show_images) :
-LLToastPanel(notification),
-mTextBox(NULL),
-mInfoPanel(NULL),
-mControlPanel(NULL),
-mNumOptions(0),
-mNumButtons(0),
-mAddedDefaultBtn(false),
-mCloseNotificationOnDestroy(true)
+LLToastNotifyPanel::LLToastNotifyPanel(const LLNotificationPtr& notification, const LLRect& rect, bool show_images)
+: LLToastPanel(notification),
+ LLInstanceTracker<LLToastNotifyPanel, LLUUID>(notification->getID())
{
- buildFromFile( "panel_notification.xml");
- if(rect != LLRect::null)
- {
- this->setShape(rect);
- }
- mInfoPanel = getChild<LLPanel>("info_panel");
- mControlPanel = getChild<LLPanel>("control_panel");
- BUTTON_WIDTH = gSavedSettings.getS32("ToastButtonWidth");
- // customize panel's attributes
- // is it intended for displaying a tip?
- mIsTip = notification->getType() == "notifytip";
- // is it a script dialog?
- mIsScriptDialog = (notification->getName() == "ScriptDialog" || notification->getName() == "ScriptDialogGroup");
- // is it a caution?
- //
- // caution flag can be set explicitly by specifying it in the notification payload, or it can be set implicitly if the
- // notify xml template specifies that it is a caution
- // tip-style notification handle 'caution' differently -they display the tip in a different color
- mIsCaution = notification->getPriority() >= NOTIFICATION_PRIORITY_HIGH;
-
- // setup parameters
- // get a notification message
- mMessage = notification->getMessage();
- // init font variables
- if (!sFont)
- {
- sFont = LLFontGL::getFontSansSerif();
- sFontSmall = LLFontGL::getFontSansSerifSmall();
- }
- // initialize
- setFocusRoot(!mIsTip);
- // get a form for the notification
- LLNotificationFormPtr form(notification->getForm());
- // get number of elements
- mNumOptions = form->getNumElements();
-
- // customize panel's outfit
- // preliminary adjust panel's layout
- //move to the end
- //mIsTip ? adjustPanelForTipNotice() : adjustPanelForScriptNotice(form);
-
- // adjust text options according to the notification type
- // add a caution textbox at the top of a caution notification
- if (mIsCaution && !mIsTip)
- {
- mTextBox = getChild<LLTextBox>("caution_text_box");
- }
- else
- {
- mTextBox = getChild<LLTextEditor>("text_editor_box");
- }
-
- // *TODO: magic numbers(???) - copied from llnotify.cpp(250)
- const S32 MAX_LENGTH = 512 + 20 + DB_FIRST_NAME_BUF_SIZE + DB_LAST_NAME_BUF_SIZE + DB_INV_ITEM_NAME_BUF_SIZE;
-
- mTextBox->setMaxTextLength(MAX_LENGTH);
- mTextBox->setVisible(TRUE);
- mTextBox->setPlainText(!show_images);
- mTextBox->setValue(notification->getMessage());
-
- // add buttons for a script notification
- if (mIsTip)
- {
- adjustPanelForTipNotice();
- }
- else
- {
- std::vector<index_button_pair_t> buttons;
- buttons.reserve(mNumOptions);
- S32 buttons_width = 0;
- // create all buttons and accumulate they total width to reshape mControlPanel
- for (S32 i = 0; i < mNumOptions; i++)
- {
- LLSD form_element = form->getElement(i);
- if (form_element["type"].asString() != "button")
- {
- // not a button.
- continue;
- }
- if (form_element["name"].asString() == TEXTBOX_MAGIC_TOKEN)
- {
- // a textbox pretending to be a button.
- continue;
- }
- LLButton* new_button = createButton(form_element, TRUE);
- buttons_width += new_button->getRect().getWidth();
- S32 index = form_element["index"].asInteger();
- buttons.push_back(index_button_pair_t(index,new_button));
- }
- if (buttons.empty())
- {
- addDefaultButton();
- }
- else
- {
- const S32 button_panel_width = mControlPanel->getRect().getWidth();// do not change width of the panel
- S32 button_panel_height = mControlPanel->getRect().getHeight();
- //try get an average h_pad to spread out buttons
- S32 h_pad = (button_panel_width - buttons_width) / (S32(buttons.size()));
- if(h_pad < 2*HPAD)
- {
- /*
- * Probably it is a scriptdialog toast
- * for a scriptdialog toast h_pad can be < 2*HPAD if we have a lot of buttons.
- * In last case set default h_pad to avoid heaping of buttons
- */
- S32 button_per_row = button_panel_width / BUTTON_WIDTH;
- h_pad = (button_panel_width % BUTTON_WIDTH) / (button_per_row - 1);// -1 because we do not need space after last button in a row
- if(h_pad < 2*HPAD) // still not enough space between buttons ?
- {
- h_pad = 2*HPAD;
- }
- }
- if (mIsScriptDialog)
- {
- // we are using default width for script buttons so we can determinate button_rows
- //to get a number of rows we divide the required width of the buttons to button_panel_width
- S32 button_rows = llceil(F32(buttons.size() - 1) * (BUTTON_WIDTH + h_pad) / button_panel_width);
- //S32 button_rows = (buttons.size() - 1) * (BUTTON_WIDTH + h_pad) / button_panel_width;
- //reserve one row for the ignore_btn
- button_rows++;
- //calculate required panel height for scripdialog notification.
- button_panel_height = button_rows * (BTN_HEIGHT + VPAD) + IGNORE_BTN_TOP_DELTA + BOTTOM_PAD;
- }
- else
- {
- // in common case buttons can have different widths so we need to calculate button_rows according to buttons_width
- //S32 button_rows = llceil(F32(buttons.size()) * (buttons_width + h_pad) / button_panel_width);
- S32 button_rows = llceil(F32((buttons.size() - 1) * h_pad + buttons_width) / button_panel_width);
- //calculate required panel height
- button_panel_height = button_rows * (BTN_HEIGHT + VPAD) + BOTTOM_PAD;
- }
-
- // we need to keep min width and max height to make visible all buttons, because width of the toast can not be changed
- adjustPanelForScriptNotice(button_panel_width, button_panel_height);
- updateButtonsLayout(buttons, h_pad);
- // save buttons for later use in disableButtons()
- mButtons.assign(buttons.begin(), buttons.end());
- }
- }
- // adjust panel's height to the text size
- mInfoPanel->setFollowsAll();
- snapToMessageHeight(mTextBox, MAX_LENGTH);
-
- if(notification->isReusable())
- {
- mButtonClickConnection = sButtonClickSignal.connect(
- boost::bind(&LLToastNotifyPanel::onToastPanelButtonClicked, this, _1, _2));
-
- if(notification->isRespondedTo())
- {
- // User selected an option in toast, now disable required buttons in IM window
- disableRespondedOptions(notification);
- }
- }
+ init(rect, show_images);
}
void LLToastNotifyPanel::addDefaultButton()
{
@@ -235,7 +78,6 @@ void LLToastNotifyPanel::addDefaultButton()
}
LLButton* LLToastNotifyPanel::createButton(const LLSD& form_element, BOOL is_option)
{
-
InstanceAndS32* userdata = new InstanceAndS32;
userdata->mSelf = this;
userdata->mButtonName = is_option ? form_element["name"].asString() : "";
@@ -245,14 +87,15 @@ LLButton* LLToastNotifyPanel::createButton(const LLSD& form_element, BOOL is_opt
LLButton::Params p;
bool make_small_btn = form_element["index"].asInteger() == -1 || form_element["index"].asInteger() == -2;
const LLFontGL* font = make_small_btn ? sFontSmall: sFont; // for block and ignore buttons in script dialog
- p.name(form_element["name"].asString());
- p.label(form_element["text"].asString());
- p.font(font);
+ p.name = form_element["name"].asString();
+ p.label = form_element["text"].asString();
+ p.font = font;
p.rect.height = BTN_HEIGHT;
p.click_callback.function(boost::bind(&LLToastNotifyPanel::onClickButton, userdata));
p.rect.width = BUTTON_WIDTH;
p.auto_resize = false;
p.follows.flags(FOLLOWS_LEFT | FOLLOWS_BOTTOM);
+ p.enabled = !form_element.has("enabled") || form_element["enabled"].asBoolean();
if (mIsCaution)
{
p.image_color(LLUIColorTable::instance().getColor("ButtonCautionImageColor"));
@@ -287,16 +130,11 @@ LLToastNotifyPanel::~LLToastNotifyPanel()
mButtonClickConnection.disconnect();
std::for_each(mBtnCallbackData.begin(), mBtnCallbackData.end(), DeletePointer());
- if (mCloseNotificationOnDestroy && LLNotificationsUtil::find(mNotification->getID()) != NULL)
- {
- // let reusable notification be deleted
- mNotification->setReusable(false);
- if (!mNotification->isPersistent())
+ if (mIsTip)
{
LLNotifications::getInstance()->cancel(mNotification);
}
}
-}
void LLToastNotifyPanel::updateButtonsLayout(const std::vector<index_button_pair_t>& buttons, S32 h_pad)
{
@@ -334,32 +172,24 @@ void LLToastNotifyPanel::updateButtonsLayout(const std::vector<index_button_pair
}
U32 ignore_btn_width = 0;
+ U32 mute_btn_pad = 0;
if (mIsScriptDialog && ignore_btn != NULL)
{
LLRect ignore_btn_rect(ignore_btn->getRect());
- S32 buttons_per_row = max_width / BUTTON_WIDTH; //assume that h_pad far less than BUTTON_WIDTH
- S32 ignore_btn_left = buttons_per_row * BUTTON_WIDTH + (buttons_per_row - 1) * h_pad - ignore_btn_rect.getWidth();
- if (ignore_btn_left + ignore_btn_rect.getWidth() > max_width)// make sure that the ignore button is in panel
- {
- ignore_btn_left = max_width - ignore_btn_rect.getWidth() - 2 * HPAD;
- }
+ S32 ignore_btn_left = max_width - ignore_btn_rect.getWidth();
ignore_btn_rect.setOriginAndSize(ignore_btn_left, BOTTOM_PAD,// always move ignore button at the bottom
ignore_btn_rect.getWidth(), ignore_btn_rect.getHeight());
ignore_btn->setRect(ignore_btn_rect);
ignore_btn_width = ignore_btn_rect.getWidth();
mControlPanel->addChild(ignore_btn, -1);
+ mute_btn_pad = 4 * HPAD; //only use a 4 * HPAD padding if an ignore button exists
}
if (mIsScriptDialog && mute_btn != NULL)
{
LLRect mute_btn_rect(mute_btn->getRect());
- S32 buttons_per_row = max_width / BUTTON_WIDTH; //assume that h_pad far less than BUTTON_WIDTH
// Place mute (Block) button to the left of the ignore button.
- S32 mute_btn_left = buttons_per_row * BUTTON_WIDTH + (buttons_per_row - 1) * h_pad - mute_btn_rect.getWidth() - ignore_btn_width - (h_pad / 2);
- if (mute_btn_left + mute_btn_rect.getWidth() > max_width) // make sure that the mute button is in panel
- {
- mute_btn_left = max_width - mute_btn_rect.getWidth() - 2 * HPAD;
- }
+ S32 mute_btn_left = max_width - mute_btn_rect.getWidth() - ignore_btn_width - mute_btn_pad;
mute_btn_rect.setOriginAndSize(mute_btn_left, BOTTOM_PAD,// always move mute button at the bottom
mute_btn_rect.getWidth(), mute_btn_rect.getHeight());
mute_btn->setRect(mute_btn_rect);
@@ -377,8 +207,6 @@ void LLToastNotifyPanel::adjustPanelForScriptNotice(S32 button_panel_width, S32
void LLToastNotifyPanel::adjustPanelForTipNotice()
{
- LLRect info_rect = mInfoPanel->getRect();
- LLRect this_rect = getRect();
//we don't need display ControlPanel for tips because they doesn't contain any buttons.
mControlPanel->setVisible(FALSE);
reshape(getRect().getWidth(), mInfoPanel->getRect().getHeight());
@@ -393,104 +221,6 @@ void LLToastNotifyPanel::adjustPanelForTipNotice()
}
}
-typedef std::set<std::string> button_name_set_t;
-typedef std::map<std::string, button_name_set_t> disable_button_map_t;
-
-disable_button_map_t initUserGiveItemDisableButtonMap()
-{
- // see EXT-5905 for disable rules
-
- disable_button_map_t disable_map;
- button_name_set_t buttons;
-
- buttons.insert("Show");
- disable_map.insert(std::make_pair("Show", buttons));
-
- buttons.insert("Discard");
- disable_map.insert(std::make_pair("Discard", buttons));
-
- buttons.insert("Mute");
- disable_map.insert(std::make_pair("Mute", buttons));
-
- return disable_map;
-}
-
-disable_button_map_t initTeleportOfferedDisableButtonMap()
-{
- disable_button_map_t disable_map;
- button_name_set_t buttons;
-
- buttons.insert("Teleport");
- buttons.insert("Cancel");
-
- disable_map.insert(std::make_pair("Teleport", buttons));
- disable_map.insert(std::make_pair("Cancel", buttons));
-
- return disable_map;
-}
-
-disable_button_map_t initFriendshipOfferedDisableButtonMap()
-{
- disable_button_map_t disable_map;
- button_name_set_t buttons;
-
- buttons.insert("Accept");
- buttons.insert("Decline");
-
- disable_map.insert(std::make_pair("Accept", buttons));
- disable_map.insert(std::make_pair("Decline", buttons));
-
- return disable_map;
-}
-
-button_name_set_t getButtonDisableList(const std::string& notification_name, const std::string& button_name)
-{
- static disable_button_map_t user_give_item_disable_map = initUserGiveItemDisableButtonMap();
- static disable_button_map_t teleport_offered_disable_map = initTeleportOfferedDisableButtonMap();
- static disable_button_map_t friendship_offered_disable_map = initFriendshipOfferedDisableButtonMap();
-
- disable_button_map_t::const_iterator it;
- disable_button_map_t::const_iterator it_end;
- disable_button_map_t search_map;
-
- if("UserGiveItem" == notification_name)
- {
- search_map = user_give_item_disable_map;
- }
- else if("TeleportOffered" == notification_name)
- {
- search_map = teleport_offered_disable_map;
- }
- else if("OfferFriendship" == notification_name)
- {
- search_map = friendship_offered_disable_map;
- }
-
- it = search_map.find(button_name);
- it_end = search_map.end();
-
- if(it_end != it)
- {
- return it->second;
- }
- return button_name_set_t();
-}
-
-void LLToastNotifyPanel::disableButtons(const std::string& notification_name, const std::string& selected_button)
-{
- button_name_set_t buttons = getButtonDisableList(notification_name, selected_button);
-
- std::vector<index_button_pair_t>::const_iterator it = mButtons.begin();
- for ( ; it != mButtons.end(); it++)
- {
- LLButton* btn = it->second;
- if(buttons.find(btn->getName()) != buttons.end())
- {
- btn->setEnabled(FALSE);
- }
- }
-}
-
// static
void LLToastNotifyPanel::onClickButton(void* data)
{
@@ -503,100 +233,288 @@ void LLToastNotifyPanel::onClickButton(void* data)
{
response[button_name] = true;
}
-
- bool is_reusable = self->mNotification->isReusable();
- // When we call respond(), LLOfferInfo will delete itself in inventory_offer_callback(),
- // lets copy it while it's still valid.
- LLOfferInfo* old_info = static_cast<LLOfferInfo*>(self->mNotification->getResponder());
- LLOfferInfo* new_info = NULL;
- if(is_reusable && old_info)
- {
- new_info = new LLOfferInfo(*old_info);
- self->mNotification->setResponder(new_info);
- }
- self->mNotification->respond(response);
+ // disable all buttons
+ self->mControlPanel->setEnabled(FALSE);
- if(is_reusable)
- {
- sButtonClickSignal(self->mNotification->getID(), button_name);
- }
- else
- {
- // disable all buttons
- self->mControlPanel->setEnabled(FALSE);
- }
+ // this might repost notification with new form data/enabled buttons
+ self->mNotification->respond(response);
}
-void LLToastNotifyPanel::onToastPanelButtonClicked(const LLUUID& notification_id, const std::string btn_name)
+void LLToastNotifyPanel::init( LLRect rect, bool show_images )
{
- if(mNotification->getID() == notification_id)
+ deleteAllChildren();
+
+ mTextBox = NULL;
+ mInfoPanel = NULL;
+ mControlPanel = NULL;
+ mNumOptions = 0;
+ mNumButtons = 0;
+ mAddedDefaultBtn = false;
+
+ LLRect current_rect = getRect();
+
+ setXMLFilename("");
+ buildFromFile("panel_notification.xml");
+
+ if(rect != LLRect::null)
+ {
+ this->setShape(rect);
+ }
+ mInfoPanel = getChild<LLPanel>("info_panel");
+
+ mControlPanel = getChild<LLPanel>("control_panel");
+ BUTTON_WIDTH = gSavedSettings.getS32("ToastButtonWidth");
+ // customize panel's attributes
+ // is it intended for displaying a tip?
+ mIsTip = mNotification->getType() == "notifytip";
+ // is it a script dialog?
+ mIsScriptDialog = (mNotification->getName() == "ScriptDialog" || mNotification->getName() == "ScriptDialogGroup");
+ // is it a caution?
+ //
+ // caution flag can be set explicitly by specifying it in the notification payload, or it can be set implicitly if the
+ // notify xml template specifies that it is a caution
+ // tip-style notification handle 'caution' differently -they display the tip in a different color
+ mIsCaution = mNotification->getPriority() >= NOTIFICATION_PRIORITY_HIGH;
+
+ // setup parameters
+ // get a notification message
+ mMessage = mNotification->getMessage();
+ // init font variables
+ if (!sFont)
+ {
+ sFont = LLFontGL::getFontSansSerif();
+ sFontSmall = LLFontGL::getFontSansSerifSmall();
+ }
+ // initialize
+ setFocusRoot(!mIsTip);
+ // get a form for the notification
+ LLNotificationFormPtr form(mNotification->getForm());
+ // get number of elements
+ mNumOptions = form->getNumElements();
+
+ // customize panel's outfit
+ // preliminary adjust panel's layout
+ //move to the end
+ //mIsTip ? adjustPanelForTipNotice() : adjustPanelForScriptNotice(form);
+
+ // adjust text options according to the notification type
+ // add a caution textbox at the top of a caution notification
+ if (mIsCaution && !mIsTip)
+ {
+ mTextBox = getChild<LLTextBox>("caution_text_box");
+ }
+ else
+ {
+ mTextBox = getChild<LLTextEditor>("text_editor_box");
+ }
+
+ mTextBox->setMaxTextLength(MAX_LENGTH);
+ mTextBox->setVisible(TRUE);
+ mTextBox->setPlainText(!show_images);
+ mTextBox->setValue(mNotification->getMessage());
+
+ // add buttons for a script notification
+ if (mIsTip)
+ {
+ adjustPanelForTipNotice();
+ }
+ else
+ {
+ std::vector<index_button_pair_t> buttons;
+ buttons.reserve(mNumOptions);
+ S32 buttons_width = 0;
+ // create all buttons and accumulate they total width to reshape mControlPanel
+ for (S32 i = 0; i < mNumOptions; i++)
+ {
+ LLSD form_element = form->getElement(i);
+ if (form_element["type"].asString() != "button")
+ {
+ // not a button.
+ continue;
+ }
+ if (form_element["name"].asString() == TEXTBOX_MAGIC_TOKEN)
+ {
+ // a textbox pretending to be a button.
+ continue;
+ }
+ LLButton* new_button = createButton(form_element, TRUE);
+ buttons_width += new_button->getRect().getWidth();
+ S32 index = form_element["index"].asInteger();
+ buttons.push_back(index_button_pair_t(index,new_button));
+ }
+ if (buttons.empty())
+ {
+ addDefaultButton();
+ }
+ else
+ {
+ const S32 button_panel_width = mControlPanel->getRect().getWidth();// do not change width of the panel
+ S32 button_panel_height = mControlPanel->getRect().getHeight();
+ //try get an average h_pad to spread out buttons
+ S32 h_pad = (button_panel_width - buttons_width) / (S32(buttons.size()));
+ if(h_pad < 2*HPAD)
+ {
+ /*
+ * Probably it is a scriptdialog toast
+ * for a scriptdialog toast h_pad can be < 2*HPAD if we have a lot of buttons.
+ * In last case set default h_pad to avoid heaping of buttons
+ */
+ S32 button_per_row = button_panel_width / BUTTON_WIDTH;
+ h_pad = (button_panel_width % BUTTON_WIDTH) / (button_per_row - 1);// -1 because we do not need space after last button in a row
+ if(h_pad < 2*HPAD) // still not enough space between buttons ?
+ {
+ h_pad = 2*HPAD;
+ }
+ }
+ if (mIsScriptDialog)
+ {
+ // we are using default width for script buttons so we can determinate button_rows
+ //to get a number of rows we divide the required width of the buttons to button_panel_width
+ S32 button_rows = llceil(F32(buttons.size() - 1) * (BUTTON_WIDTH + h_pad) / button_panel_width);
+ //S32 button_rows = (buttons.size() - 1) * (BUTTON_WIDTH + h_pad) / button_panel_width;
+ //reserve one row for the ignore_btn
+ button_rows++;
+ //calculate required panel height for scripdialog notification.
+ button_panel_height = button_rows * (BTN_HEIGHT + VPAD) + IGNORE_BTN_TOP_DELTA + BOTTOM_PAD;
+ }
+ else
+ {
+ // in common case buttons can have different widths so we need to calculate button_rows according to buttons_width
+ //S32 button_rows = llceil(F32(buttons.size()) * (buttons_width + h_pad) / button_panel_width);
+ S32 button_rows = llceil(F32((buttons.size() - 1) * h_pad + buttons_width) / button_panel_width);
+ //calculate required panel height
+ button_panel_height = button_rows * (BTN_HEIGHT + VPAD) + BOTTOM_PAD;
+ }
+
+ // we need to keep min width and max height to make visible all buttons, because width of the toast can not be changed
+ adjustPanelForScriptNotice(button_panel_width, button_panel_height);
+ updateButtonsLayout(buttons, h_pad);
+ // save buttons for later use in disableButtons()
+ //mButtons.assign(buttons.begin(), buttons.end());
+ }
+ }
+
+ //.xml file intially makes info panel only follow left/right/top. This is so that when control buttons are added the info panel
+ //can shift upward making room for the buttons inside mControlPanel. After the buttons are added, the info panel can then be set to follow 'all'.
+ mInfoPanel->setFollowsAll();
+ snapToMessageHeight(mTextBox, MAX_LENGTH);
+
+ // reshape the panel to its previous size
+ if (current_rect.notEmpty())
{
- disableButtons(mNotification->getName(), btn_name);
+ reshape(current_rect.getWidth(), current_rect.getHeight());
}
}
-void LLToastNotifyPanel::disableRespondedOptions(LLNotificationPtr& notification)
+bool LLToastNotifyPanel::isControlPanelEnabled() const
{
- LLSD response = notification->getResponse();
- for (LLSD::map_const_iterator response_it = response.beginMap();
- response_it != response.endMap(); ++response_it)
+ bool cp_enabled = mControlPanel->getEnabled();
+ bool some_buttons_enabled = false;
+ if (cp_enabled)
{
- if (response_it->second.isBoolean() && response_it->second.asBoolean())
+ LLView::child_list_const_iter_t child_it = mControlPanel->beginChild();
+ LLView::child_list_const_iter_t child_it_end = mControlPanel->endChild();
+ for(; child_it != child_it_end; ++child_it)
{
- // that after multiple responses there can be many pressed buttons
- // need to process them all
- disableButtons(notification->getName(), response_it->first);
+ LLButton * buttonp = dynamic_cast<LLButton *>(*child_it);
+ if (buttonp && buttonp->getEnabled())
+ {
+ some_buttons_enabled = true;
+ break;
+ }
}
}
-}
+ return cp_enabled && some_buttons_enabled;
+}
//////////////////////////////////////////////////////////////////////////
LLIMToastNotifyPanel::LLIMToastNotifyPanel(LLNotificationPtr& pNotification, const LLUUID& session_id, const LLRect& rect /* = LLRect::null */,
- bool show_images /* = true */)
- : mSessionID(session_id), LLToastNotifyPanel(pNotification, rect, show_images)
+ bool show_images /* = true */, LLTextBase* parent_text)
+: mSessionID(session_id), LLToastNotifyPanel(pNotification, rect, show_images),
+ mParentText(parent_text)
{
- mTextBox->setFollowsAll();
+ compactButtons();
}
LLIMToastNotifyPanel::~LLIMToastNotifyPanel()
{
- // We shouldn't delete notification when IM floater exists
- // since that notification will be reused by IM floater.
- // This may happened when IM floater reloads messages, exactly when user
- // changes layout of IM chat log(disable/enable plaintext mode).
- // See EXT-6500
- LLIMFloater* im_floater = LLIMFloater::findInstance(mSessionID);
- if (im_floater != NULL && !im_floater->isDead())
- {
- mCloseNotificationOnDestroy = false;
- }
}
void LLIMToastNotifyPanel::reshape(S32 width, S32 height, BOOL called_from_parent /* = TRUE */)
{
- S32 text_height = mTextBox->getTextBoundingRect().getHeight();
- S32 widget_height = mTextBox->getRect().getHeight();
- S32 delta = text_height - widget_height;
- LLRect rc = getRect();
+ LLToastPanel::reshape(width, height, called_from_parent);
+ snapToMessageHeight();
+}
- rc.setLeftTopAndSize(rc.mLeft, rc.mTop, width, height + delta);
- height = rc.getHeight();
- width = rc.getWidth();
+void LLIMToastNotifyPanel::snapToMessageHeight()
+{
+ if(!mTextBox)
+ {
+ return;
+ }
- bool is_width_changed = width != getRect().getWidth();
+ //Add message height if it is visible
+ if (mTextBox->getVisible())
+ {
+ S32 new_panel_height = computeSnappedToMessageHeight(mTextBox, MAX_LENGTH);
- LLToastPanel::reshape(width, height, called_from_parent);
+ //reshape the panel with new height
+ if (new_panel_height != getRect().getHeight())
+ {
+ LLToastNotifyPanel::reshape( getRect().getWidth(), new_panel_height);
+ }
+ }
+}
+
+void LLIMToastNotifyPanel::compactButtons()
+{
+ //we can't set follows in xml since it broke toasts behavior
+ setFollows(FOLLOWS_LEFT|FOLLOWS_RIGHT|FOLLOWS_TOP);
+
+ const child_list_t* children = getControlPanel()->getChildList();
+ S32 offset = 0;
+ // Children were added by addChild() which uses push_front to insert them into list,
+ // so to get buttons in correct order reverse iterator is used (EXT-5906)
+ for (child_list_t::const_reverse_iterator it = children->rbegin(); it != children->rend(); it++)
+ {
+ LLButton * button = dynamic_cast<LLButton*> (*it);
+ if (button != NULL)
+ {
+ button->setOrigin( offset,button->getRect().mBottom);
+ button->setLeftHPad(2 * HPAD);
+ button->setRightHPad(2 * HPAD);
+ // set zero width before perform autoResize()
+ button->setRect(LLRect(button->getRect().mLeft,
+ button->getRect().mTop,
+ button->getRect().mLeft,
+ button->getRect().mBottom));
+ button->setAutoResize(true);
+ button->autoResize();
+ offset += HPAD + button->getRect().getWidth();
+ button->setFollowsNone();
+ }
+ }
- // Notification height required to display the text message depends on
- // the width of the text box thus if panel width is changed the text box
- // width is also changed then reshape() is called to adjust proper height.
- if (is_width_changed)
+ if (mParentText)
{
- reshape(width, height, called_from_parent);
+ mParentText->needsReflow();
}
}
+void LLIMToastNotifyPanel::updateNotification()
+ {
+ init(LLRect(), true);
+ }
+
+void LLIMToastNotifyPanel::init( LLRect rect, bool show_images )
+{
+ LLToastNotifyPanel::init(LLRect(), show_images);
+
+ compactButtons();
+}
+
// EOF
+
diff --git a/indra/newview/lltoastnotifypanel.h b/indra/newview/lltoastnotifypanel.h
index 57711b3d80..fe7f1cf8f3 100644..100755
--- a/indra/newview/lltoastnotifypanel.h
+++ b/indra/newview/lltoastnotifypanel.h
@@ -47,7 +47,7 @@ class LLNotificationForm;
* @deprecated this class will be removed after all toast panel types are
* implemented in separate classes.
*/
-class LLToastNotifyPanel: public LLToastPanel
+class LLToastNotifyPanel: public LLToastPanel, public LLInstanceTracker<LLToastNotifyPanel, LLUUID>
{
public:
/**
@@ -60,11 +60,17 @@ public:
* @deprecated if you intend to instantiate LLToastNotifyPanel - it's point to
* implement right class for desired toast panel. @see LLGenericTipPanel as example.
*/
- LLToastNotifyPanel(LLNotificationPtr& pNotification, const LLRect& rect = LLRect::null, bool show_images = true);
+ LLToastNotifyPanel(const LLNotificationPtr& pNotification, const LLRect& rect = LLRect::null, bool show_images = true);
+
+ virtual void init( LLRect rect, bool show_images );
+
virtual ~LLToastNotifyPanel();
LLPanel * getControlPanel() { return mControlPanel; }
- void setCloseNotificationOnDestroy(bool close) { mCloseNotificationOnDestroy = close; }
+ virtual void updateNotification() {}
+
+ bool isControlPanelEnabled() const;
+
protected:
LLButton* createButton(const LLSD& form_element, BOOL is_option);
@@ -76,8 +82,6 @@ protected:
};
std::vector<InstanceAndS32*> mBtnCallbackData;
- bool mCloseNotificationOnDestroy;
-
typedef std::pair<int,LLButton*> index_button_pair_t;
void adjustPanelForScriptNotice(S32 max_width, S32 max_height);
void adjustPanelForTipNotice();
@@ -93,9 +97,9 @@ protected:
/**
* Disable specific button(s) based on notification name and clicked button
*/
- void disableButtons(const std::string& notification_name, const std::string& selected_button);
+ //void disableButtons(const std::string& notification_name, const std::string& selected_button);
- std::vector<index_button_pair_t> mButtons;
+ //std::vector<index_button_pair_t> mButtons;
// panel elements
LLTextBase* mTextBox;
@@ -118,7 +122,7 @@ protected:
/**
* Process response data. Will disable selected options
*/
- void disableRespondedOptions(LLNotificationPtr& notification);
+ //void disableRespondedOptions(const LLNotificationPtr& notification);
bool mIsTip;
bool mAddedDefaultBtn;
@@ -137,14 +141,27 @@ class LLIMToastNotifyPanel : public LLToastNotifyPanel
{
public:
- LLIMToastNotifyPanel(LLNotificationPtr& pNotification, const LLUUID& session_id, const LLRect& rect = LLRect::null, bool show_images = true);
+ LLIMToastNotifyPanel(LLNotificationPtr& pNotification,
+ const LLUUID& session_id,
+ const LLRect& rect = LLRect::null,
+ bool show_images = true,
+ LLTextBase* parent_text = NULL);
+
+ void compactButtons();
+
+ virtual void updateNotification();
+ virtual void init( LLRect rect, bool show_images );
~LLIMToastNotifyPanel();
/*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
protected:
+ LLTextBase* mParentText;
LLUUID mSessionID;
+
+private:
+ void snapToMessageHeight();
};
#endif /* LLTOASTNOTIFYPANEL_H_ */
diff --git a/indra/newview/lltoastpanel.cpp b/indra/newview/lltoastpanel.cpp
index d2a4ce8745..e1b764a943 100644..100755
--- a/indra/newview/lltoastpanel.cpp
+++ b/indra/newview/lltoastpanel.cpp
@@ -29,7 +29,9 @@
#include "llpanelgenerictip.h"
#include "llpanelonlinestatus.h"
#include "llnotifications.h"
+#include "lltoastnotifypanel.h"
#include "lltoastpanel.h"
+#include "lltoastscriptquestion.h"
//static
const S32 LLToastPanel::MIN_PANEL_HEIGHT = 40; // VPAD(4)*2 + ICON_HEIGHT(32)
@@ -51,11 +53,36 @@ std::string LLToastPanel::getTitle()
}
//virtual
+const std::string& LLToastPanel::getNotificationName()
+{
+ return mNotification->getName();
+}
+
+//virtual
const LLUUID& LLToastPanel::getID()
{
return mNotification->id();
}
+S32 LLToastPanel::computeSnappedToMessageHeight(LLTextBase* message, S32 maxLineCount)
+{
+ S32 heightDelta = 0;
+ S32 maxTextHeight = message->getFont()->getLineHeight() * maxLineCount;
+
+ LLRect messageRect = message->getRect();
+ S32 oldTextHeight = messageRect.getHeight();
+
+ //Knowing the height is set to max allowed, getTextPixelHeight returns needed text height
+ //Perhaps we need to pass maxLineCount as parameter to getTextPixelHeight to avoid previous reshape.
+ S32 requiredTextHeight = message->getTextBoundingRect().getHeight();
+ S32 newTextHeight = llmin(requiredTextHeight, maxTextHeight);
+
+ heightDelta = newTextHeight - oldTextHeight;
+ S32 new_panel_height = llmax(getRect().getHeight() + heightDelta, MIN_PANEL_HEIGHT);
+
+ return new_panel_height;
+}
+
//snap to the message height if it is visible
void LLToastPanel::snapToMessageHeight(LLTextBase* message, S32 maxLineCount)
{
@@ -67,22 +94,13 @@ void LLToastPanel::snapToMessageHeight(LLTextBase* message, S32 maxLineCount)
//Add message height if it is visible
if (message->getVisible())
{
- S32 heightDelta = 0;
- S32 maxTextHeight = message->getDefaultFont()->getLineHeight() * maxLineCount;
-
- LLRect messageRect = message->getRect();
- S32 oldTextHeight = messageRect.getHeight();
-
- //Knowing the height is set to max allowed, getTextPixelHeight returns needed text height
- //Perhaps we need to pass maxLineCount as parameter to getTextPixelHeight to avoid previous reshape.
- S32 requiredTextHeight = message->getTextBoundingRect().getHeight();
- S32 newTextHeight = llmin(requiredTextHeight, maxTextHeight);
-
- //Calculate last delta height deducting previous heightDelta
- heightDelta = newTextHeight - oldTextHeight - heightDelta;
+ S32 new_panel_height = computeSnappedToMessageHeight(message, maxLineCount);
//reshape the panel with new height
- reshape( getRect().getWidth(), llmax(getRect().getHeight() + heightDelta, MIN_PANEL_HEIGHT));
+ if (new_panel_height != getRect().getHeight())
+ {
+ reshape( getRect().getWidth(), new_panel_height);
+ }
}
}
@@ -96,7 +114,7 @@ LLToastPanel* LLToastPanel::buidPanelFromNotification(
if ("notifytip" == notification->getType())
{
// if it is online/offline notification
- if ("FriendOffline" == notification->getName() || "FriendOnline" == notification->getName())
+ if ("FriendOnlineOffline" == notification->getName())
{
res = new LLPanelOnlineStatus(notification);
}
@@ -106,6 +124,17 @@ LLToastPanel* LLToastPanel::buidPanelFromNotification(
res = new LLPanelGenericTip(notification);
}
}
+ else if("notify" == notification->getType())
+ {
+ if (notification->getPriority() == NOTIFICATION_PRIORITY_CRITICAL)
+ {
+ res = new LLToastScriptQuestion(notification);
+ }
+ else
+ {
+ res = new LLToastNotifyPanel(notification);
+ }
+ }
/*
else if(...)
create all other specific non-public toast panel
diff --git a/indra/newview/lltoastpanel.h b/indra/newview/lltoastpanel.h
index 346e014d73..51630381f2 100644..100755
--- a/indra/newview/lltoastpanel.h
+++ b/indra/newview/lltoastpanel.h
@@ -33,24 +33,19 @@
#include <string>
-class LLToastPanelBase: public LLPanel
-{
-public:
- virtual void init(LLSD& data){};
-};
-
/**
* Base class for all panels that can be added to the toast.
* All toast panels should contain necessary logic for representing certain notification
* but shouldn't contain logic related to this panel lifetime control and positioning
* on the parent view.
*/
-class LLToastPanel: public LLPanel {
+class LLToastPanel : public LLPanel {
public:
LLToastPanel(const LLNotificationPtr&);
virtual ~LLToastPanel() = 0;
virtual std::string getTitle();
+ virtual const std::string& getNotificationName();
virtual const LLUUID& getID();
static const S32 MIN_PANEL_HEIGHT;
@@ -65,6 +60,7 @@ public:
protected:
LLNotificationPtr mNotification;
void snapToMessageHeight(LLTextBase* message, S32 maxLineCount);
+ S32 computeSnappedToMessageHeight(LLTextBase* message, S32 maxLineCount);
};
#endif /* LL_TOASTPANEL_H */
diff --git a/indra/newview/lltoastscriptquestion.cpp b/indra/newview/lltoastscriptquestion.cpp
new file mode 100755
index 0000000000..91ba8c0247
--- /dev/null
+++ b/indra/newview/lltoastscriptquestion.cpp
@@ -0,0 +1,130 @@
+/**
+ * @file lltoastscriptquestion.cpp
+ *
+ * $LicenseInfo:firstyear=2010&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 "llbutton.h"
+#include "llnotifications.h"
+#include "lltoastscriptquestion.h"
+
+const int LEFT_PAD = 10;
+const int BUTTON_HEIGHT = 27;
+const int MAX_LINES_COUNT = 50;
+
+LLToastScriptQuestion::LLToastScriptQuestion(const LLNotificationPtr& notification)
+:
+LLToastPanel(notification)
+{
+ buildFromFile("panel_script_question_toast.xml");
+}
+
+BOOL LLToastScriptQuestion::postBuild()
+{
+ createButtons();
+
+ LLTextBox* mMessage = getChild<LLTextBox>("top_info_message");
+ LLTextBox* mFooter = getChild<LLTextBox>("bottom_info_message");
+
+ mMessage->setValue(mNotification->getMessage());
+ mFooter->setValue(mNotification->getFooter());
+
+ snapToMessageHeight();
+
+ return TRUE;
+}
+void LLToastScriptQuestion::snapToMessageHeight()
+{
+ LLTextBox* mMessage = getChild<LLTextBox>("top_info_message");
+ LLTextBox* mFooter = getChild<LLTextBox>("bottom_info_message");
+ if (!mMessage || !mFooter)
+ {
+ return;
+ }
+
+ if (mMessage->getVisible() && mFooter->getVisible())
+ {
+ S32 heightDelta = 0;
+ S32 maxTextHeight = (mMessage->getFont()->getLineHeight() * MAX_LINES_COUNT)
+ + (mFooter->getFont()->getLineHeight() * MAX_LINES_COUNT);
+
+ LLRect messageRect = mMessage->getRect();
+ LLRect footerRect = mFooter->getRect();
+
+ S32 oldTextHeight = messageRect.getHeight() + footerRect.getHeight();
+
+ S32 requiredTextHeight = mMessage->getTextBoundingRect().getHeight() + mFooter->getTextBoundingRect().getHeight();
+ S32 newTextHeight = llmin(requiredTextHeight, maxTextHeight);
+
+ heightDelta = newTextHeight - oldTextHeight - heightDelta;
+
+ reshape( getRect().getWidth(), llmax(getRect().getHeight() + heightDelta, MIN_PANEL_HEIGHT));
+ }
+}
+
+void LLToastScriptQuestion::createButtons()
+{
+ LLNotificationFormPtr form = mNotification->getForm();
+ int num_elements = form->getNumElements();
+ int buttons_width = 0;
+
+ for (int i = 0; i < num_elements; ++i)
+ {
+ LLSD form_element = form->getElement(i);
+ if ("button" == form_element["type"].asString())
+ {
+ LLButton::Params p;
+ const LLFontGL* font = LLFontGL::getFontSansSerif();
+ p.name(form_element["name"].asString());
+ p.label(form_element["text"].asString());
+ p.layout("topleft");
+ p.font(font);
+ p.rect.height(BUTTON_HEIGHT);
+ p.click_callback.function(boost::bind(&LLToastScriptQuestion::onButtonClicked, this, form_element["name"].asString()));
+ p.rect.left = LEFT_PAD;
+ p.rect.width = font->getWidth(form_element["text"].asString());
+ p.auto_resize = true;
+ p.follows.flags(FOLLOWS_LEFT | FOLLOWS_BOTTOM);
+ p.image_color(LLUIColorTable::instance().getColor("ButtonCautionImageColor"));
+ p.image_color_disabled(LLUIColorTable::instance().getColor("ButtonCautionImageColor"));
+
+ LLButton* button = LLUICtrlFactory::create<LLButton>(p);
+ button->autoResize();
+ getChild<LLPanel>("buttons_panel")->addChild(button);
+
+ LLRect rect = button->getRect();
+ rect.setLeftTopAndSize(buttons_width, rect.mTop, rect.getWidth(), rect.getHeight());
+ button->setRect(rect);
+
+ buttons_width += rect.getWidth() + LEFT_PAD;
+ }
+ }
+}
+
+void LLToastScriptQuestion::onButtonClicked(std::string btn_name)
+{
+ LLSD response = mNotification->getResponseTemplate();
+ response[btn_name] = true;
+ mNotification->respond(response);
+}
diff --git a/indra/newview/lltoastscriptquestion.h b/indra/newview/lltoastscriptquestion.h
new file mode 100755
index 0000000000..3a557f60f6
--- /dev/null
+++ b/indra/newview/lltoastscriptquestion.h
@@ -0,0 +1,49 @@
+/**
+ * @file lltoastscriptquestion.h
+ *
+ * $LicenseInfo:firstyear=2010&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, 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 "lltoastpanel.h"
+
+#ifndef LLTOASTSCRIPTQUESTION_H_
+#define LLTOASTSCRIPTQUESTION_H_
+
+class LLToastScriptQuestion : public LLToastPanel
+{
+ LOG_CLASS(LLToastScriptQuestion);
+
+public:
+ LLToastScriptQuestion(const LLNotificationPtr& notification);
+ virtual BOOL postBuild();
+ virtual ~LLToastScriptQuestion(){};
+
+private:
+ void snapToMessageHeight();
+
+ void createButtons();
+ void onButtonClicked(std::string btn_name);
+};
+
+#endif /* LLTOASTSCRIPTQUESTION_H_ */
diff --git a/indra/newview/lltoastscripttextbox.cpp b/indra/newview/lltoastscripttextbox.cpp
index 2529ec865a..45fbabad59 100644..100755
--- a/indra/newview/lltoastscripttextbox.cpp
+++ b/indra/newview/lltoastscripttextbox.cpp
@@ -65,7 +65,7 @@ LLToastScriptTextbox::LLToastScriptTextbox(const LLNotificationPtr& notification
pMessageText->clear();
LLStyle::Params style;
- style.font = pMessageText->getDefaultFont();
+ style.font = pMessageText->getFont();
pMessageText->appendText(message, TRUE, style);
//submit button
diff --git a/indra/newview/lltoastscripttextbox.h b/indra/newview/lltoastscripttextbox.h
index 8e69d8834d..7d33446248 100644..100755
--- a/indra/newview/lltoastscripttextbox.h
+++ b/indra/newview/lltoastscripttextbox.h
@@ -39,8 +39,6 @@ class LLToastScriptTextbox
public:
void close();
- static bool onNewNotification(const LLSD& notification);
-
// Non-transient messages. You can specify non-default button
// layouts (like one for script dialogs) by passing various
// numbers in for "layout".
diff --git a/indra/newview/lltool.cpp b/indra/newview/lltool.cpp
index 2d8ce95347..2d8ce95347 100644..100755
--- a/indra/newview/lltool.cpp
+++ b/indra/newview/lltool.cpp
diff --git a/indra/newview/lltool.h b/indra/newview/lltool.h
index ecc435d844..ecc435d844 100644..100755
--- a/indra/newview/lltool.h
+++ b/indra/newview/lltool.h
diff --git a/indra/newview/lltoolbarview.cpp b/indra/newview/lltoolbarview.cpp
index 81ad96f39e..78a555d67d 100644..100755
--- a/indra/newview/lltoolbarview.cpp
+++ b/indra/newview/lltoolbarview.cpp
@@ -51,8 +51,6 @@ LLToolBarView* gToolBarView = NULL;
static LLDefaultChildRegistry::Register<LLToolBarView> r("toolbar_view");
-void handleLoginToolbarSetup();
-
bool isToolDragged()
{
return (LLToolDragAndDrop::getInstance()->getSource() == LLToolDragAndDrop::SOURCE_VIEWER);
@@ -76,7 +74,8 @@ LLToolBarView::LLToolBarView(const LLToolBarView::Params& p)
mShowToolbars(true),
mDragToolbarButton(NULL),
mDragItem(NULL),
- mToolbarsLoaded(false)
+ mToolbarsLoaded(false),
+ mBottomToolbarPanel(NULL)
{
for (S32 i = 0; i < TOOLBAR_COUNT; i++)
{
@@ -100,6 +99,7 @@ BOOL LLToolBarView::postBuild()
mToolbars[TOOLBAR_LEFT] = getChild<LLToolBar>("toolbar_left");
mToolbars[TOOLBAR_RIGHT] = getChild<LLToolBar>("toolbar_right");
mToolbars[TOOLBAR_BOTTOM] = getChild<LLToolBar>("toolbar_bottom");
+ mBottomToolbarPanel = getChild<LLView>("bottom_toolbar_panel");
for (int i = TOOLBAR_FIRST; i <= TOOLBAR_LAST; i++)
{
@@ -109,8 +109,6 @@ BOOL LLToolBarView::postBuild()
mToolbars[i]->setButtonAddCallback(boost::bind(LLToolBarView::onToolBarButtonAdded,_1));
mToolbars[i]->setButtonRemoveCallback(boost::bind(LLToolBarView::onToolBarButtonRemoved,_1));
}
-
- LLAppViewer::instance()->setOnLoginCompletedCallback(boost::bind(&handleLoginToolbarSetup));
return TRUE;
}
@@ -178,13 +176,13 @@ S32 LLToolBarView::stopCommandInProgress(const LLCommandId& commandId)
return command_location;
}
-S32 LLToolBarView::flashCommand(const LLCommandId& commandId, bool flash)
+S32 LLToolBarView::flashCommand(const LLCommandId& commandId, bool flash, bool force_flashing/* = false */)
{
S32 command_location = hasCommand(commandId);
if (command_location != TOOLBAR_NONE)
{
- mToolbars[command_location]->flashCommand(commandId, flash);
+ mToolbars[command_location]->flashCommand(commandId, flash, force_flashing);
}
return command_location;
@@ -239,8 +237,9 @@ bool LLToolBarView::loadToolbars(bool force_default)
LLXUIParser parser;
if (!err)
{
- parser.readXUI(root, toolbar_set, toolbar_file);
+ parser.readXUI(root, toolbar_set, toolbar_file);
}
+
if (!err && !toolbar_set.validateBlock())
{
llwarns << "Unable to validate toolbars from file: " << toolbar_file << llendl;
@@ -252,8 +251,9 @@ bool LLToolBarView::loadToolbars(bool force_default)
if (force_default)
{
llerrs << "Unable to load toolbars from default file : " << toolbar_file << llendl;
- return false;
- }
+ return false;
+ }
+
// Try to load the default toolbars
return loadToolbars(true);
}
@@ -603,7 +603,7 @@ BOOL LLToolBarView::handleDragTool( S32 x, S32 y, const LLUUID& uuid, LLAssetTyp
BOOL LLToolBarView::handleDropTool( void* cargo_data, S32 x, S32 y, LLToolBar* toolbar)
{
BOOL handled = FALSE;
- LLInventoryItem* inv_item = (LLInventoryItem*)cargo_data;
+ LLInventoryObject* inv_item = static_cast<LLInventoryObject*>(cargo_data);
LLAssetType::EType type = inv_item->getType();
if (type == LLAssetType::AT_WIDGET)
@@ -692,18 +692,3 @@ bool LLToolBarView::isModified() const
}
-//
-// HACK to bring up destinations guide at startup
-//
-
-void handleLoginToolbarSetup()
-{
- // Open the destinations guide by default on first login, per Rhett
- if (gSavedPerAccountSettings.getBOOL("DisplayDestinationsOnInitialRun") || gAgent.isFirstLogin())
- {
- LLFloaterReg::showInstance("destinations");
-
- gSavedPerAccountSettings.setBOOL("DisplayDestinationsOnInitialRun", FALSE);
- }
-}
-
diff --git a/indra/newview/lltoolbarview.h b/indra/newview/lltoolbarview.h
index 9c4194ebed..dcc3862074 100644..100755
--- a/indra/newview/lltoolbarview.h
+++ b/indra/newview/lltoolbarview.h
@@ -90,7 +90,7 @@ public:
S32 removeCommand(const LLCommandId& commandId, int& rank); // Sets the rank the removed command was at, RANK_NONE if not found
S32 enableCommand(const LLCommandId& commandId, bool enabled);
S32 stopCommandInProgress(const LLCommandId& commandId);
- S32 flashCommand(const LLCommandId& commandId, bool flash);
+ S32 flashCommand(const LLCommandId& commandId, bool flash, bool force_flashing = false);
// Loads the toolbars from the existing user or default settings
bool loadToolbars(bool force_default = false); // return false if load fails
@@ -108,7 +108,8 @@ public:
static BOOL handleDropTool(void* cargo_data, S32 x, S32 y, LLToolBar* toolbar);
static void resetDragTool(LLToolBarButton* toolbarButton);
LLInventoryObject* getDragItem();
-
+ LLView* getBottomToolbar() { return mBottomToolbarPanel; }
+ LLToolBar* getToolbar(EToolBarLocation toolbar) { return mToolbars[toolbar]; }
bool isModified() const;
protected:
@@ -133,6 +134,7 @@ private:
LLToolBarButton* mDragToolbarButton;
LLInventoryObject* mDragItem;
bool mShowToolbars;
+ LLView* mBottomToolbarPanel;
};
extern LLToolBarView* gToolBarView;
diff --git a/indra/newview/lltoolbrush.cpp b/indra/newview/lltoolbrush.cpp
index aba43a9715..08d82ea9cb 100644..100755
--- a/indra/newview/lltoolbrush.cpp
+++ b/indra/newview/lltoolbrush.cpp
@@ -657,7 +657,7 @@ bool LLToolBrushLand::canTerraform(LLViewerRegion* regionp) const
{
if (!regionp) return false;
if (regionp->canManageEstate()) return true;
- return !(regionp->getRegionFlags() & REGION_FLAGS_BLOCK_TERRAFORM);
+ return !regionp->getRegionFlag(REGION_FLAGS_BLOCK_TERRAFORM);
}
// static
diff --git a/indra/newview/lltoolbrush.h b/indra/newview/lltoolbrush.h
index 1c7f198900..1c7f198900 100644..100755
--- a/indra/newview/lltoolbrush.h
+++ b/indra/newview/lltoolbrush.h
diff --git a/indra/newview/lltoolcomp.cpp b/indra/newview/lltoolcomp.cpp
index 923fbecb1a..5270c3d33f 100644..100755
--- a/indra/newview/lltoolcomp.cpp
+++ b/indra/newview/lltoolcomp.cpp
@@ -471,7 +471,7 @@ BOOL LLToolCompCreate::handleMouseDown(S32 x, S32 y, MASK mask)
mObjectPlacedOnMouseDown = TRUE;
- return TRUE;
+ return handled;
}
void LLToolCompCreate::pickCallback(const LLPickInfo& pick_info)
diff --git a/indra/newview/lltoolcomp.h b/indra/newview/lltoolcomp.h
index bbb5ed5797..bbb5ed5797 100644..100755
--- a/indra/newview/lltoolcomp.h
+++ b/indra/newview/lltoolcomp.h
diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp
index 4f4eef0f3d..1a137f7129 100644..100755
--- a/indra/newview/lltooldraganddrop.cpp
+++ b/indra/newview/lltooldraganddrop.cpp
@@ -58,7 +58,7 @@
#include "llviewerwindow.h"
#include "llvoavatarself.h"
#include "llworld.h"
-#include "llclipboard.h"
+#include "llpanelface.h"
// syntactic sugar
#define callMemberFunction(object,ptrToMember) ((object).*(ptrToMember))
@@ -355,7 +355,7 @@ void LLToolDragAndDrop::setDragStart(S32 x, S32 y)
BOOL LLToolDragAndDrop::isOverThreshold(S32 x,S32 y)
{
- static LLCachedControl<S32> drag_and_drop_threshold(gSavedSettings,"DragAndDropDistanceThreshold");
+ static LLCachedControl<S32> drag_and_drop_threshold(gSavedSettings,"DragAndDropDistanceThreshold", 3);
S32 mouse_delta_x = x - mDragStartX;
S32 mouse_delta_y = y - mDragStartY;
@@ -654,33 +654,41 @@ void LLToolDragAndDrop::dragOrDrop( S32 x, S32 y, MASK mask, BOOL drop,
sOperationId++;
}
+ // For people drag and drop we don't need an actual inventory object,
+ // instead we need the current cargo id, which should be a person id.
+ bool is_uuid_dragged = (mSource == SOURCE_PEOPLE);
+
if (top_view)
{
handled = TRUE;
for (mCurItemIndex = 0; mCurItemIndex < (S32)mCargoIDs.size(); mCurItemIndex++)
{
- LLInventoryObject* cargo = locateInventory(item, cat);
+ S32 local_x, local_y;
+ top_view->screenPointToLocal( x, y, &local_x, &local_y );
+ EAcceptance item_acceptance = ACCEPT_NO;
+ LLInventoryObject* cargo = locateInventory(item, cat);
if (cargo)
{
- S32 local_x, local_y;
- top_view->screenPointToLocal( x, y, &local_x, &local_y );
- EAcceptance item_acceptance = ACCEPT_NO;
handled = handled && top_view->handleDragAndDrop(local_x, local_y, mask, FALSE,
mCargoTypes[mCurItemIndex],
(void*)cargo,
&item_acceptance,
mToolTipMsg);
- if (handled)
- {
- // use sort order to determine priority of acceptance
- *acceptance = (EAcceptance)llmin((U32)item_acceptance, (U32)*acceptance);
- }
}
- else
+ else if (is_uuid_dragged)
{
- return;
+ handled = handled && top_view->handleDragAndDrop(local_x, local_y, mask, FALSE,
+ mCargoTypes[mCurItemIndex],
+ (void*)&mCargoIDs[mCurItemIndex],
+ &item_acceptance,
+ mToolTipMsg);
+ }
+ if (handled)
+ {
+ // use sort order to determine priority of acceptance
+ *acceptance = (EAcceptance)llmin((U32)item_acceptance, (U32)*acceptance);
}
}
@@ -697,20 +705,27 @@ void LLToolDragAndDrop::dragOrDrop( S32 x, S32 y, MASK mask, BOOL drop,
for (mCurItemIndex = 0; mCurItemIndex < (S32)mCargoIDs.size(); mCurItemIndex++)
{
- LLInventoryObject* cargo = locateInventory(item, cat);
+ S32 local_x, local_y;
+ EAcceptance item_acceptance;
+ top_view->screenPointToLocal( x, y, &local_x, &local_y );
+ LLInventoryObject* cargo = locateInventory(item, cat);
if (cargo)
{
- S32 local_x, local_y;
-
- EAcceptance item_acceptance;
- top_view->screenPointToLocal( x, y, &local_x, &local_y );
handled = handled && top_view->handleDragAndDrop(local_x, local_y, mask, TRUE,
mCargoTypes[mCurItemIndex],
(void*)cargo,
&item_acceptance,
mToolTipMsg);
}
+ else if (is_uuid_dragged)
+ {
+ handled = handled && top_view->handleDragAndDrop(local_x, local_y, mask, FALSE,
+ mCargoTypes[mCurItemIndex],
+ (void*)&mCargoIDs[mCurItemIndex],
+ &item_acceptance,
+ mToolTipMsg);
+ }
}
}
if (handled)
@@ -727,17 +742,27 @@ void LLToolDragAndDrop::dragOrDrop( S32 x, S32 y, MASK mask, BOOL drop,
for (mCurItemIndex = 0; mCurItemIndex < (S32)mCargoIDs.size(); mCurItemIndex++)
{
+ EAcceptance item_acceptance = ACCEPT_NO;
+
LLInventoryObject* cargo = locateInventory(item, cat);
// fix for EXT-3191
- if (NULL == cargo) return;
-
- EAcceptance item_acceptance = ACCEPT_NO;
- handled = handled && root_view->handleDragAndDrop(x, y, mask, FALSE,
- mCargoTypes[mCurItemIndex],
- (void*)cargo,
- &item_acceptance,
- mToolTipMsg);
+ if (cargo)
+ {
+ handled = handled && root_view->handleDragAndDrop(x, y, mask, FALSE,
+ mCargoTypes[mCurItemIndex],
+ (void*)cargo,
+ &item_acceptance,
+ mToolTipMsg);
+ }
+ else if (is_uuid_dragged)
+ {
+ handled = handled && root_view->handleDragAndDrop(x, y, mask, FALSE,
+ mCargoTypes[mCurItemIndex],
+ (void*)&mCargoIDs[mCurItemIndex],
+ &item_acceptance,
+ mToolTipMsg);
+ }
if (handled)
{
// use sort order to determine priority of acceptance
@@ -757,17 +782,25 @@ void LLToolDragAndDrop::dragOrDrop( S32 x, S32 y, MASK mask, BOOL drop,
for (mCurItemIndex = 0; mCurItemIndex < (S32)mCargoIDs.size(); mCurItemIndex++)
{
- LLInventoryObject* cargo = locateInventory(item, cat);
+ EAcceptance item_acceptance;
+ LLInventoryObject* cargo = locateInventory(item, cat);
if (cargo)
{
- EAcceptance item_acceptance;
handled = handled && root_view->handleDragAndDrop(x, y, mask, TRUE,
mCargoTypes[mCurItemIndex],
(void*)cargo,
&item_acceptance,
mToolTipMsg);
}
+ else if (is_uuid_dragged)
+ {
+ handled = handled && root_view->handleDragAndDrop(x, y, mask, TRUE,
+ mCargoTypes[mCurItemIndex],
+ (void*)&mCargoIDs[mCurItemIndex],
+ &item_acceptance,
+ mToolTipMsg);
+ }
}
}
@@ -780,7 +813,7 @@ void LLToolDragAndDrop::dragOrDrop( S32 x, S32 y, MASK mask, BOOL drop,
if (!handled)
{
// Disallow drag and drop to 3D from the outbox
- const LLUUID outbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false, false);
+ const LLUUID outbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false);
if (outbox_id.notNull())
{
for (S32 item_index = 0; item_index < (S32)mCargoIDs.size(); item_index++)
@@ -1007,7 +1040,14 @@ BOOL LLToolDragAndDrop::handleDropTextureProtections(LLViewerObject* hit_obj,
}
}
// Add the texture item to the target object's inventory.
- hit_obj->updateInventory(new_item, TASK_INVENTORY_ITEM_KEY, true);
+ if (LLAssetType::AT_TEXTURE == new_item->getType())
+ {
+ hit_obj->updateTextureInventory(new_item, TASK_INVENTORY_ITEM_KEY, true);
+ }
+ else
+ {
+ hit_obj->updateInventory(new_item, TASK_INVENTORY_ITEM_KEY, true);
+ }
// TODO: Check to see if adding the item was successful; if not, then
// we should return false here.
}
@@ -1022,7 +1062,14 @@ BOOL LLToolDragAndDrop::handleDropTextureProtections(LLViewerObject* hit_obj,
// *FIX: may want to make sure agent can paint hit_obj.
// Add the texture item to the target object's inventory.
- hit_obj->updateInventory(new_item, TASK_INVENTORY_ITEM_KEY, true);
+ if (LLAssetType::AT_TEXTURE == new_item->getType())
+ {
+ hit_obj->updateTextureInventory(new_item, TASK_INVENTORY_ITEM_KEY, true);
+ }
+ else
+ {
+ hit_obj->updateInventory(new_item, TASK_INVENTORY_ITEM_KEY, true);
+ }
// Force the object to update its refetch its inventory so it has this texture.
hit_obj->fetchInventoryFromServer();
// TODO: Check to see if adding the item was successful; if not, then
@@ -1117,7 +1164,51 @@ void LLToolDragAndDrop::dropTextureOneFace(LLViewerObject* hit_obj,
// update viewer side image in anticipation of update from simulator
LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(asset_id);
LLViewerStats::getInstance()->incStat(LLViewerStats::ST_EDIT_TEXTURE_COUNT );
- hit_obj->setTEImage(hit_face, image);
+
+ LLTextureEntry* tep = hit_obj ? (hit_obj->getTE(hit_face)) : NULL;
+
+ LLPanelFace* panel_face = gFloaterTools->getPanelFace();
+
+ if (gFloaterTools->getVisible() && panel_face)
+ {
+ switch (LLSelectMgr::getInstance()->getTextureChannel())
+ {
+
+ case 0:
+ default:
+ {
+ hit_obj->setTEImage(hit_face, image);
+ }
+ break;
+
+ case 1:
+ {
+ LLMaterialPtr old_mat = tep->getMaterialParams();
+ LLMaterialPtr new_mat = panel_face->createDefaultMaterial(old_mat);
+ new_mat->setNormalID(asset_id);
+ tep->setMaterialParams(new_mat);
+ hit_obj->setTENormalMap(hit_face, asset_id);
+ LLMaterialMgr::getInstance()->put(hit_obj->getID(), hit_face, *new_mat);
+ }
+ break;
+
+ case 2:
+ {
+ LLMaterialPtr old_mat = tep->getMaterialParams();
+ LLMaterialPtr new_mat = panel_face->createDefaultMaterial(old_mat);
+ new_mat->setSpecularID(asset_id);
+ tep->setMaterialParams(new_mat);
+ hit_obj->setTESpecularMap(hit_face, asset_id);
+ LLMaterialMgr::getInstance()->put(hit_obj->getID(), hit_face, *new_mat);
+ }
+ break;
+ }
+ }
+ else
+ {
+ hit_obj->setTEImage(hit_face, image);
+ }
+
dialog_refresh_all();
// send the update to the simulator
@@ -1201,7 +1292,7 @@ void LLToolDragAndDrop::dropObject(LLViewerObject* raycast_target,
if (!item || !item->isFinished()) return;
//if (regionp
- // && (regionp->getRegionFlags() & REGION_FLAGS_SANDBOX))
+ // && (regionp->getRegionFlag(REGION_FLAGS_SANDBOX)))
//{
// LLFirstUse::useSandbox();
//}
@@ -1695,7 +1786,7 @@ EAcceptance LLToolDragAndDrop::dad3dRezAttachmentFromInv(
{
if(mSource == SOURCE_LIBRARY)
{
- LLPointer<LLInventoryCallback> cb = new RezAttachmentCallback(0);
+ LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(rez_attachment_cb, _1, (LLViewerJointAttachment*)0));
copy_inventory_item(
gAgent.getID(),
item->getPermissions().getOwner(),
@@ -2048,7 +2139,7 @@ EAcceptance LLToolDragAndDrop::dad3dActivateGesture(
{
// create item based on that one, and put it on if that
// was a success.
- LLPointer<LLInventoryCallback> cb = new ActivateGestureCallback();
+ LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(activate_gesture_cb);
copy_inventory_item(
gAgent.getID(),
item->getPermissions().getOwner(),
@@ -2495,7 +2586,13 @@ LLInventoryObject* LLToolDragAndDrop::locateInventory(
{
item = NULL;
cat = NULL;
- if(mCargoIDs.empty()) return NULL;
+
+ if (mCargoIDs.empty()
+ || (mSource == SOURCE_PEOPLE)) ///< There is no inventory item for people drag and drop.
+ {
+ return NULL;
+ }
+
if((mSource == SOURCE_AGENT) || (mSource == SOURCE_LIBRARY))
{
// The object should be in user inventory.
@@ -2531,6 +2628,7 @@ LLInventoryObject* LLToolDragAndDrop::locateInventory(
{
item = (LLViewerInventoryItem*)gToolBarView->getDragItem();
}
+
if(item) return item;
if(cat) return cat;
return NULL;
diff --git a/indra/newview/lltooldraganddrop.h b/indra/newview/lltooldraganddrop.h
index 245c2a23e6..f17300a76a 100644..100755
--- a/indra/newview/lltooldraganddrop.h
+++ b/indra/newview/lltooldraganddrop.h
@@ -67,7 +67,8 @@ public:
SOURCE_WORLD,
SOURCE_NOTECARD,
SOURCE_LIBRARY,
- SOURCE_VIEWER
+ SOURCE_VIEWER,
+ SOURCE_PEOPLE
};
void beginDrag(EDragAndDropType type,
@@ -93,6 +94,13 @@ public:
static S32 getOperationId() { return sOperationId; }
+ // deal with permissions of object, etc. returns TRUE if drop can
+ // proceed, otherwise FALSE.
+ static BOOL handleDropTextureProtections(LLViewerObject* hit_obj,
+ LLInventoryItem* item,
+ LLToolDragAndDrop::ESource source,
+ const LLUUID& src_id);
+
protected:
enum EDropTarget
{
@@ -219,13 +227,6 @@ protected:
// inventory items to determine if a drop would be ok.
static EAcceptance willObjectAcceptInventory(LLViewerObject* obj, LLInventoryItem* item);
- // deal with permissions of object, etc. returns TRUE if drop can
- // proceed, otherwise FALSE.
- static BOOL handleDropTextureProtections(LLViewerObject* hit_obj,
- LLInventoryItem* item,
- LLToolDragAndDrop::ESource source,
- const LLUUID& src_id);
-
public:
// helper functions
static BOOL isInventoryDropAcceptable(LLViewerObject* obj, LLInventoryItem* item) { return (ACCEPT_YES_COPY_SINGLE <= willObjectAcceptInventory(obj, item)); }
diff --git a/indra/newview/lltoolface.cpp b/indra/newview/lltoolface.cpp
index a00ac10698..a00ac10698 100644..100755
--- a/indra/newview/lltoolface.cpp
+++ b/indra/newview/lltoolface.cpp
diff --git a/indra/newview/lltoolface.h b/indra/newview/lltoolface.h
index 7eb13b0fbc..7eb13b0fbc 100644..100755
--- a/indra/newview/lltoolface.h
+++ b/indra/newview/lltoolface.h
diff --git a/indra/newview/lltoolfocus.cpp b/indra/newview/lltoolfocus.cpp
index a754d8ee7e..857b0f0714 100644..100755
--- a/indra/newview/lltoolfocus.cpp
+++ b/indra/newview/lltoolfocus.cpp
@@ -314,8 +314,6 @@ BOOL LLToolCamera::handleHover(S32 x, S32 y, MASK mask)
S32 dx = gViewerWindow->getCurrentMouseDX();
S32 dy = gViewerWindow->getCurrentMouseDY();
- BOOL moved_outside_slop = FALSE;
-
if (hasMouseCapture() && mValidClickPoint)
{
mAccumX += llabs(dx);
@@ -323,19 +321,11 @@ BOOL LLToolCamera::handleHover(S32 x, S32 y, MASK mask)
if (mAccumX >= SLOP_RANGE)
{
- if (!mOutsideSlopX)
- {
- moved_outside_slop = TRUE;
- }
mOutsideSlopX = TRUE;
}
if (mAccumY >= SLOP_RANGE)
{
- if (!mOutsideSlopY)
- {
- moved_outside_slop = TRUE;
- }
mOutsideSlopY = TRUE;
}
}
diff --git a/indra/newview/lltoolfocus.h b/indra/newview/lltoolfocus.h
index b1ac42e33f..b1ac42e33f 100644..100755
--- a/indra/newview/lltoolfocus.h
+++ b/indra/newview/lltoolfocus.h
diff --git a/indra/newview/lltoolgrab.cpp b/indra/newview/lltoolgrab.cpp
index 319e2508e0..9907da0f0e 100644..100755
--- a/indra/newview/lltoolgrab.cpp
+++ b/indra/newview/lltoolgrab.cpp
@@ -205,9 +205,9 @@ BOOL LLToolGrab::handleObjectHit(const LLPickInfo& info)
// Clicks on scripted or physical objects are temporary grabs, so
// not "Build mode"
- mHideBuildHighlight = script_touch || objectp->usePhysics();
+ mHideBuildHighlight = script_touch || objectp->flagUsePhysics();
- if (!objectp->usePhysics())
+ if (!objectp->flagUsePhysics())
{
if (script_touch)
{
@@ -222,18 +222,24 @@ BOOL LLToolGrab::handleObjectHit(const LLPickInfo& info)
if (gAgentCamera.cameraMouselook())
{
mMode = GRAB_LOCKED;
+ gViewerWindow->hideCursor();
+ gViewerWindow->moveCursorToCenter();
}
- else
+ else if (objectp->permMove() && !objectp->isPermanentEnforced())
{
mMode = GRAB_ACTIVE_CENTER;
+ gViewerWindow->hideCursor();
+ gViewerWindow->moveCursorToCenter();
+ }
+ else
+ {
+ mMode = GRAB_LOCKED;
}
- gViewerWindow->hideCursor();
- gViewerWindow->moveCursorToCenter();
}
}
- else if( !objectp->permMove() )
+ else if( objectp->flagCharacter() || !objectp->permMove() || objectp->isPermanentEnforced())
{
// if mouse is over a physical object without move permission, show feedback if user tries to move it.
mMode = GRAB_LOCKED;
diff --git a/indra/newview/lltoolgrab.h b/indra/newview/lltoolgrab.h
index 06a3b662c8..06a3b662c8 100644..100755
--- a/indra/newview/lltoolgrab.h
+++ b/indra/newview/lltoolgrab.h
diff --git a/indra/newview/lltoolgun.cpp b/indra/newview/lltoolgun.cpp
index 857d105361..c1735adc9c 100644..100755
--- a/indra/newview/lltoolgun.cpp
+++ b/indra/newview/lltoolgun.cpp
@@ -42,7 +42,7 @@
#include "llhudmanager.h"
#include "lltoolmgr.h"
#include "lltoolgrab.h"
-
+#include "lluiimage.h"
// Linden library includes
#include "llwindow.h" // setMouseClipping()
diff --git a/indra/newview/lltoolgun.h b/indra/newview/lltoolgun.h
index 8ae926b741..8ae926b741 100644..100755
--- a/indra/newview/lltoolgun.h
+++ b/indra/newview/lltoolgun.h
diff --git a/indra/newview/lltoolindividual.cpp b/indra/newview/lltoolindividual.cpp
index 885c1442a0..885c1442a0 100644..100755
--- a/indra/newview/lltoolindividual.cpp
+++ b/indra/newview/lltoolindividual.cpp
diff --git a/indra/newview/lltoolindividual.h b/indra/newview/lltoolindividual.h
index 961a6a4d93..961a6a4d93 100644..100755
--- a/indra/newview/lltoolindividual.h
+++ b/indra/newview/lltoolindividual.h
diff --git a/indra/newview/lltoolmgr.cpp b/indra/newview/lltoolmgr.cpp
index ac01316462..a135ba70f5 100644..100755
--- a/indra/newview/lltoolmgr.cpp
+++ b/indra/newview/lltoolmgr.cpp
@@ -91,6 +91,8 @@ LLToolMgr::LLToolMgr()
// gLandToolset = new LLToolset();
gMouselookToolset = new LLToolset();
gFaceEditToolset = new LLToolset();
+ gMouselookToolset->setShowFloaterTools(false);
+ gFaceEditToolset->setShowFloaterTools(false);
}
void LLToolMgr::initTools()
diff --git a/indra/newview/lltoolmgr.h b/indra/newview/lltoolmgr.h
index 12649cfba2..e7d1c56c83 100644..100755
--- a/indra/newview/lltoolmgr.h
+++ b/indra/newview/lltoolmgr.h
@@ -89,7 +89,7 @@ protected:
class LLToolset
{
public:
- LLToolset() : mSelectedTool(NULL) {}
+ LLToolset() : mSelectedTool(NULL), mIsShowFloaterTools(true) {}
LLTool* getSelectedTool() { return mSelectedTool; }
@@ -105,10 +105,14 @@ public:
BOOL isToolSelected( S32 index );
+ void setShowFloaterTools(bool pShowFloaterTools) {mIsShowFloaterTools = pShowFloaterTools;};
+ bool isShowFloaterTools() const {return mIsShowFloaterTools;};
+
protected:
LLTool* mSelectedTool;
typedef std::vector<LLTool*> tool_list_t;
tool_list_t mToolList;
+ bool mIsShowFloaterTools;
};
// Globals
diff --git a/indra/newview/lltoolmorph.cpp b/indra/newview/lltoolmorph.cpp
index 718201e381..148e5a015b 100644..100755
--- a/indra/newview/lltoolmorph.cpp
+++ b/indra/newview/lltoolmorph.cpp
@@ -34,6 +34,7 @@
#include "llaudioengine.h"
#include "llviewercontrol.h"
#include "llfontgl.h"
+#include "llwearable.h"
#include "sound_ids.h"
#include "v3math.h"
#include "v3color.h"
@@ -225,7 +226,8 @@ BOOL LLVisualParamHint::render()
LLViewerCamera::getInstance()->setPerspective(FALSE, mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight, FALSE);
- if (gAgentAvatarp->mDrawable.notNull())
+ if (gAgentAvatarp->mDrawable.notNull() &&
+ gAgentAvatarp->mDrawable->getFace(0))
{
LLDrawPoolAvatar *avatarPoolp = (LLDrawPoolAvatar *)gAgentAvatarp->mDrawable->getFace(0)->getPool();
LLGLDepthTest gls_depth(GL_TRUE, GL_TRUE);
diff --git a/indra/newview/lltoolmorph.h b/indra/newview/lltoolmorph.h
index a6889be151..a6889be151 100644..100755
--- a/indra/newview/lltoolmorph.h
+++ b/indra/newview/lltoolmorph.h
diff --git a/indra/newview/lltoolobjpicker.cpp b/indra/newview/lltoolobjpicker.cpp
index b65c4c1ec8..b65c4c1ec8 100644..100755
--- a/indra/newview/lltoolobjpicker.cpp
+++ b/indra/newview/lltoolobjpicker.cpp
diff --git a/indra/newview/lltoolobjpicker.h b/indra/newview/lltoolobjpicker.h
index 0c37be1f92..0c37be1f92 100644..100755
--- a/indra/newview/lltoolobjpicker.h
+++ b/indra/newview/lltoolobjpicker.h
diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp
index b0d9bd5d70..1c362c18e0 100644..100755
--- a/indra/newview/lltoolpie.cpp
+++ b/indra/newview/lltoolpie.cpp
@@ -121,13 +121,14 @@ BOOL LLToolPie::handleMouseDown(S32 x, S32 y, MASK mask)
BOOL LLToolPie::handleRightMouseDown(S32 x, S32 y, MASK mask)
{
// don't pick transparent so users can't "pay" transparent objects
- mPick = gViewerWindow->pickImmediate(x, y, FALSE);
+ mPick = gViewerWindow->pickImmediate(x, y, FALSE, TRUE);
mPick.mKeyMask = mask;
// claim not handled so UI focus stays same
-
- handleRightClickPick();
-
+ if(gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK)
+ {
+ handleRightClickPick();
+ }
return FALSE;
}
@@ -312,7 +313,7 @@ BOOL LLToolPie::handleLeftClickPick()
// Switch to grab tool if physical or triggerable
if (object &&
!object->isAvatar() &&
- ((object->usePhysics() || (parent && !parent->isAvatar() && parent->usePhysics())) || touchable)
+ ((object->flagUsePhysics() || (parent && !parent->isAvatar() && parent->flagUsePhysics())) || touchable)
)
{
gGrabTransientTool = this;
@@ -596,8 +597,8 @@ BOOL LLToolPie::handleHover(S32 x, S32 y, MASK mask)
lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolPie (inactive)" << llendl;
}
- else if ((object && !object->isAvatar() && object->usePhysics())
- || (parent && !parent->isAvatar() && parent->usePhysics()))
+ else if ((object && !object->isAvatar() && object->flagUsePhysics())
+ || (parent && !parent->isAvatar() && parent->flagUsePhysics()))
{
show_highlight = true;
gViewerWindow->setCursor(UI_CURSOR_TOOLGRAB);
@@ -790,14 +791,10 @@ BOOL LLToolPie::handleTooltipLand(std::string line, std::string tooltip_msg)
LLParcel* hover_parcel = LLViewerParcelMgr::getInstance()->getHoverParcel();
LLUUID owner;
- S32 width = 0;
- S32 height = 0;
if ( hover_parcel )
{
owner = hover_parcel->getOwnerID();
- width = S32(LLViewerParcelMgr::getInstance()->getHoverParcelWidth());
- height = S32(LLViewerParcelMgr::getInstance()->getHoverParcelHeight());
}
// Line: "Land"
@@ -972,33 +969,16 @@ BOOL LLToolPie::handleTooltipObject( LLViewerObject* hover_object, std::string l
|| !existing_inspector->getVisible()
|| existing_inspector->getKey()["avatar_id"].asUUID() != hover_object->getID())
{
- // IDEVO: try to get display name + username
+ // Try to get display name + username
std::string final_name;
- std::string full_name;
- if (!gCacheName->getFullName(hover_object->getID(), full_name))
- {
- LLNameValue* firstname = hover_object->getNVPair("FirstName");
- LLNameValue* lastname = hover_object->getNVPair("LastName");
- if (firstname && lastname)
- {
- full_name = LLCacheName::buildFullName(
- firstname->getString(), lastname->getString());
- }
- else
- {
- full_name = LLTrans::getString("TooltipPerson");
- }
- }
-
LLAvatarName av_name;
- if (LLAvatarNameCache::useDisplayNames() &&
- LLAvatarNameCache::get(hover_object->getID(), &av_name))
+ if (LLAvatarNameCache::get(hover_object->getID(), &av_name))
{
final_name = av_name.getCompleteName();
}
else
{
- final_name = full_name;
+ final_name = LLTrans::getString("TooltipPerson");;
}
// *HACK: We may select this object, so pretend it was clicked
@@ -1609,9 +1589,6 @@ BOOL LLToolPie::handleRightClickPick()
// didn't click in any UI object, so must have clicked in the world
LLViewerObject *object = mPick.getObject();
- LLViewerObject *parent = NULL;
- if(object)
- parent = object->getRootEdit();
// Can't ignore children here.
LLToolSelect::handleObjectSelection(mPick, FALSE, TRUE);
@@ -1710,6 +1687,13 @@ BOOL LLToolPie::handleRightClickPick()
showVisualContextMenuEffect();
}
}
+ else if (mPick.mParticleOwnerID.notNull())
+ {
+ if (gMenuMuteParticle && mPick.mParticleOwnerID != gAgent.getID())
+ {
+ gMenuMuteParticle->show(x,y);
+ }
+ }
LLTool::handleRightMouseDown(x, y, mask);
// We handled the event.
diff --git a/indra/newview/lltoolpie.h b/indra/newview/lltoolpie.h
index 68fe8bc4a5..68fe8bc4a5 100644..100755
--- a/indra/newview/lltoolpie.h
+++ b/indra/newview/lltoolpie.h
diff --git a/indra/newview/lltoolpipette.cpp b/indra/newview/lltoolpipette.cpp
index ff3dad2675..ff3dad2675 100644..100755
--- a/indra/newview/lltoolpipette.cpp
+++ b/indra/newview/lltoolpipette.cpp
diff --git a/indra/newview/lltoolpipette.h b/indra/newview/lltoolpipette.h
index 8a83bf31af..8a83bf31af 100644..100755
--- a/indra/newview/lltoolpipette.h
+++ b/indra/newview/lltoolpipette.h
diff --git a/indra/newview/lltoolplacer.cpp b/indra/newview/lltoolplacer.cpp
index 93ba3b2558..641fbc5042 100644..100755
--- a/indra/newview/lltoolplacer.cpp
+++ b/indra/newview/lltoolplacer.cpp
@@ -182,7 +182,7 @@ BOOL LLToolPlacer::addObject( LLPCode pcode, S32 x, S32 y, U8 use_physics )
return FALSE;
}
- if (regionp->getRegionFlags() & REGION_FLAGS_SANDBOX)
+ if (regionp->getRegionFlag(REGION_FLAGS_SANDBOX))
{
//LLFirstUse::useSandbox();
}
@@ -485,7 +485,7 @@ BOOL LLToolPlacer::addDuplicate(S32 x, S32 y)
FALSE); // select copy
if (regionp
- && (regionp->getRegionFlags() & REGION_FLAGS_SANDBOX))
+ && (regionp->getRegionFlag(REGION_FLAGS_SANDBOX)))
{
//LLFirstUse::useSandbox();
}
diff --git a/indra/newview/lltoolplacer.h b/indra/newview/lltoolplacer.h
index ad59cb0daa..ad59cb0daa 100644..100755
--- a/indra/newview/lltoolplacer.h
+++ b/indra/newview/lltoolplacer.h
diff --git a/indra/newview/lltoolselect.cpp b/indra/newview/lltoolselect.cpp
index 7c604a04bf..7c604a04bf 100644..100755
--- a/indra/newview/lltoolselect.cpp
+++ b/indra/newview/lltoolselect.cpp
diff --git a/indra/newview/lltoolselect.h b/indra/newview/lltoolselect.h
index baa27f6071..74dababe8c 100644..100755
--- a/indra/newview/lltoolselect.h
+++ b/indra/newview/lltoolselect.h
@@ -34,7 +34,7 @@
class LLObjectSelection;
-class LLToolSelect : public LLTool, public LLSingleton<LLToolSelect>
+class LLToolSelect : public LLTool
{
public:
LLToolSelect( LLToolComposite* composite );
diff --git a/indra/newview/lltoolselectland.cpp b/indra/newview/lltoolselectland.cpp
index a48388c591..a48388c591 100644..100755
--- a/indra/newview/lltoolselectland.cpp
+++ b/indra/newview/lltoolselectland.cpp
diff --git a/indra/newview/lltoolselectland.h b/indra/newview/lltoolselectland.h
index b368a4b153..b368a4b153 100644..100755
--- a/indra/newview/lltoolselectland.h
+++ b/indra/newview/lltoolselectland.h
diff --git a/indra/newview/lltoolselectrect.cpp b/indra/newview/lltoolselectrect.cpp
index a3f4e5a18c..a3f4e5a18c 100644..100755
--- a/indra/newview/lltoolselectrect.cpp
+++ b/indra/newview/lltoolselectrect.cpp
diff --git a/indra/newview/lltoolselectrect.h b/indra/newview/lltoolselectrect.h
index 5fdf622b49..5fdf622b49 100644..100755
--- a/indra/newview/lltoolselectrect.h
+++ b/indra/newview/lltoolselectrect.h
diff --git a/indra/newview/lltoolview.cpp b/indra/newview/lltoolview.cpp
index 8c40ff3cb3..8c40ff3cb3 100644..100755
--- a/indra/newview/lltoolview.cpp
+++ b/indra/newview/lltoolview.cpp
diff --git a/indra/newview/lltoolview.h b/indra/newview/lltoolview.h
index 3b5fb55cce..3b5fb55cce 100644..100755
--- a/indra/newview/lltoolview.h
+++ b/indra/newview/lltoolview.h
diff --git a/indra/newview/lltracker.cpp b/indra/newview/lltracker.cpp
index bf1f8808a7..cbd16e873d 100644..100755
--- a/indra/newview/lltracker.cpp
+++ b/indra/newview/lltracker.cpp
@@ -251,7 +251,7 @@ void LLTracker::render3D()
instance()->mBeaconText->setDoFade(FALSE);
}
- F32 dist = gFloaterWorldMap->getDistanceToDestination(instance()->mTrackedPositionGlobal, 0.0f);
+ F32 dist = gFloaterWorldMap->getDistanceToDestination(instance()->getTrackedPositionGlobal(), 0.0f);
if (dist < DESTINATION_REACHED_RADIUS)
{
instance()->stopTrackingAvatar();
diff --git a/indra/newview/lltracker.h b/indra/newview/lltracker.h
index 8e916af315..8e916af315 100644..100755
--- a/indra/newview/lltracker.h
+++ b/indra/newview/lltracker.h
diff --git a/indra/newview/lltransientdockablefloater.cpp b/indra/newview/lltransientdockablefloater.cpp
index c108f1dfdc..c108f1dfdc 100644..100755
--- a/indra/newview/lltransientdockablefloater.cpp
+++ b/indra/newview/lltransientdockablefloater.cpp
diff --git a/indra/newview/lltransientdockablefloater.h b/indra/newview/lltransientdockablefloater.h
index 5fb79597f4..5fb79597f4 100644..100755
--- a/indra/newview/lltransientdockablefloater.h
+++ b/indra/newview/lltransientdockablefloater.h
diff --git a/indra/newview/lltransientfloatermgr.cpp b/indra/newview/lltransientfloatermgr.cpp
index 3d68c10489..3d68c10489 100644..100755
--- a/indra/newview/lltransientfloatermgr.cpp
+++ b/indra/newview/lltransientfloatermgr.cpp
diff --git a/indra/newview/lltransientfloatermgr.h b/indra/newview/lltransientfloatermgr.h
index b4611c8c87..b4611c8c87 100644..100755
--- a/indra/newview/lltransientfloatermgr.h
+++ b/indra/newview/lltransientfloatermgr.h
diff --git a/indra/newview/lltranslate.h b/indra/newview/lltranslate.h
index c58e1adb8c..db5ad9479c 100755
--- a/indra/newview/lltranslate.h
+++ b/indra/newview/lltranslate.h
@@ -263,8 +263,8 @@ public :
EService mService;
};
- typedef boost::intrusive_ptr<TranslationReceiver> TranslationReceiverPtr;
- typedef boost::intrusive_ptr<KeyVerificationReceiver> KeyVerificationReceiverPtr;
+ typedef LLPointer<TranslationReceiver> TranslationReceiverPtr;
+ typedef LLPointer<KeyVerificationReceiver> KeyVerificationReceiverPtr;
/**
* Translate given text.
diff --git a/indra/newview/lluiconstants.h b/indra/newview/lluiconstants.h
index 1479e58c43..1479e58c43 100644..100755
--- a/indra/newview/lluiconstants.h
+++ b/indra/newview/lluiconstants.h
diff --git a/indra/newview/lluilistener.cpp b/indra/newview/lluilistener.cpp
index 6b2cd71d40..6b2cd71d40 100644..100755
--- a/indra/newview/lluilistener.cpp
+++ b/indra/newview/lluilistener.cpp
diff --git a/indra/newview/lluilistener.h b/indra/newview/lluilistener.h
index 08724024dc..08724024dc 100644..100755
--- a/indra/newview/lluilistener.h
+++ b/indra/newview/lluilistener.h
diff --git a/indra/newview/lluploaddialog.cpp b/indra/newview/lluploaddialog.cpp
index e59064c074..e59064c074 100644..100755
--- a/indra/newview/lluploaddialog.cpp
+++ b/indra/newview/lluploaddialog.cpp
diff --git a/indra/newview/lluploaddialog.h b/indra/newview/lluploaddialog.h
index 3aa9583315..3aa9583315 100644..100755
--- a/indra/newview/lluploaddialog.h
+++ b/indra/newview/lluploaddialog.h
diff --git a/indra/newview/lluploadfloaterobservers.cpp b/indra/newview/lluploadfloaterobservers.cpp
index 5a6a17fbca..1d777b3f7f 100644..100755
--- a/indra/newview/lluploadfloaterobservers.cpp
+++ b/indra/newview/lluploadfloaterobservers.cpp
@@ -33,9 +33,10 @@ LLUploadModelPremissionsResponder::LLUploadModelPremissionsResponder(const LLHan
{
}
-void LLUploadModelPremissionsResponder::error(U32 status, const std::string& reason)
+void LLUploadModelPremissionsResponder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)
{
- llwarns << "LLUploadModelPremissionsResponder::error("<< status << ": " << reason << ")" << llendl;
+ llwarns << "LLUploadModelPremissionsResponder error [status:"
+ << status << "]: " << content << llendl;
LLUploadPermissionsObserver* observer = mObserverHandle.get();
diff --git a/indra/newview/lluploadfloaterobservers.h b/indra/newview/lluploadfloaterobservers.h
index 79aad282d7..b43ddb44d9 100644..100755
--- a/indra/newview/lluploadfloaterobservers.h
+++ b/indra/newview/lluploadfloaterobservers.h
@@ -86,7 +86,7 @@ public:
LLUploadModelPremissionsResponder(const LLHandle<LLUploadPermissionsObserver>& observer);
- void error(U32 status, const std::string& reason);
+ void errorWithContent(U32 status, const std::string& reason, const LLSD& content);
void result(const LLSD& content);
diff --git a/indra/newview/llurl.cpp b/indra/newview/llurl.cpp
index aa90d16c67..aa90d16c67 100644..100755
--- a/indra/newview/llurl.cpp
+++ b/indra/newview/llurl.cpp
diff --git a/indra/newview/llurl.h b/indra/newview/llurl.h
index 01ab3bdfc2..01ab3bdfc2 100644..100755
--- a/indra/newview/llurl.h
+++ b/indra/newview/llurl.h
diff --git a/indra/newview/llurldispatcher.cpp b/indra/newview/llurldispatcher.cpp
index 4240a38326..00b15a5f26 100644..100755
--- a/indra/newview/llurldispatcher.cpp
+++ b/indra/newview/llurldispatcher.cpp
@@ -205,18 +205,18 @@ void LLURLDispatcherImpl::regionHandleCallback(U64 region_handle, const LLSLURL&
{
// we can't teleport cross grid at this point
- if((!LLGridManager::getInstance()->isSystemGrid(slurl.getGrid()) || !LLGridManager::getInstance()->isSystemGrid()) &&
- (slurl.getGrid() != LLGridManager::getInstance()->getGrid()))
+ if( LLGridManager::getInstance()->getGrid(slurl.getGrid())
+ != LLGridManager::getInstance()->getGrid())
{
LLSD args;
args["SLURL"] = slurl.getLocationString();
args["CURRENT_GRID"] = LLGridManager::getInstance()->getGridLabel();
- LLSD grid_info;
- LLGridManager::getInstance()->getGridInfo(slurl.getGrid(), grid_info);
+ std::string grid_label =
+ LLGridManager::getInstance()->getGridLabel(slurl.getGrid());
- if(grid_info.has(GRID_LABEL_VALUE))
+ if(!grid_label.empty())
{
- args["GRID"] = grid_info[GRID_LABEL_VALUE].asString();
+ args["GRID"] = grid_label;
}
else
{
diff --git a/indra/newview/llurldispatcher.h b/indra/newview/llurldispatcher.h
index 6309a97af5..6309a97af5 100644..100755
--- a/indra/newview/llurldispatcher.h
+++ b/indra/newview/llurldispatcher.h
diff --git a/indra/newview/llurldispatcherlistener.cpp b/indra/newview/llurldispatcherlistener.cpp
index c7b9afafef..c7b9afafef 100644..100755
--- a/indra/newview/llurldispatcherlistener.cpp
+++ b/indra/newview/llurldispatcherlistener.cpp
diff --git a/indra/newview/llurldispatcherlistener.h b/indra/newview/llurldispatcherlistener.h
index b09594bb39..b09594bb39 100644..100755
--- a/indra/newview/llurldispatcherlistener.h
+++ b/indra/newview/llurldispatcherlistener.h
diff --git a/indra/newview/llurlhistory.cpp b/indra/newview/llurlhistory.cpp
index edec30f8c4..a80b9da13c 100644..100755
--- a/indra/newview/llurlhistory.cpp
+++ b/indra/newview/llurlhistory.cpp
@@ -103,24 +103,29 @@ LLSD LLURLHistory::getURLHistory(const std::string& collection)
// static
void LLURLHistory::addURL(const std::string& collection, const std::string& url)
{
- if(! url.empty())
+ if(!url.empty())
{
- sHistorySD[collection].insert(0, url);
+ LLURI u(url);
+ std::string simplified_url = u.scheme() + "://" + u.authority() + u.path();
+ sHistorySD[collection].insert(0, simplified_url);
LLURLHistory::limitSize(collection);
}
}
// static
void LLURLHistory::removeURL(const std::string& collection, const std::string& url)
{
- LLSD::array_iterator iter = sHistorySD[collection].beginArray();
- LLSD::array_iterator end = sHistorySD[collection].endArray();
- for(int index = 0; index < sHistorySD[collection].size(); index++)
+ if(!url.empty())
{
- if(sHistorySD[collection].get(index).asString() == url)
- {
- sHistorySD[collection].erase(index);
- }
- }
+ LLURI u(url);
+ std::string simplified_url = u.scheme() + "://" + u.authority() + u.path();
+ for(int index = 0; index < sHistorySD[collection].size(); index++)
+ {
+ if(sHistorySD[collection].get(index).asString() == simplified_url)
+ {
+ sHistorySD[collection].erase(index);
+ }
+ }
+ }
}
// static
diff --git a/indra/newview/llurlhistory.h b/indra/newview/llurlhistory.h
index 3cce4cbe1d..3cce4cbe1d 100644..100755
--- a/indra/newview/llurlhistory.h
+++ b/indra/newview/llurlhistory.h
diff --git a/indra/newview/llurllineeditorctrl.cpp b/indra/newview/llurllineeditorctrl.cpp
index cad5769042..cad5769042 100644..100755
--- a/indra/newview/llurllineeditorctrl.cpp
+++ b/indra/newview/llurllineeditorctrl.cpp
diff --git a/indra/newview/llurllineeditorctrl.h b/indra/newview/llurllineeditorctrl.h
index b9540dd571..b9540dd571 100644..100755
--- a/indra/newview/llurllineeditorctrl.h
+++ b/indra/newview/llurllineeditorctrl.h
diff --git a/indra/newview/llurlwhitelist.cpp b/indra/newview/llurlwhitelist.cpp
index 72029203d9..72029203d9 100644..100755
--- a/indra/newview/llurlwhitelist.cpp
+++ b/indra/newview/llurlwhitelist.cpp
diff --git a/indra/newview/llurlwhitelist.h b/indra/newview/llurlwhitelist.h
index b0969051a7..b0969051a7 100644..100755
--- a/indra/newview/llurlwhitelist.h
+++ b/indra/newview/llurlwhitelist.h
diff --git a/indra/newview/llvectorperfoptions.cpp b/indra/newview/llvectorperfoptions.cpp
index b80058d98c..b80058d98c 100644..100755
--- a/indra/newview/llvectorperfoptions.cpp
+++ b/indra/newview/llvectorperfoptions.cpp
diff --git a/indra/newview/llvectorperfoptions.h b/indra/newview/llvectorperfoptions.h
index e7a5748256..e7a5748256 100644..100755
--- a/indra/newview/llvectorperfoptions.h
+++ b/indra/newview/llvectorperfoptions.h
diff --git a/indra/newview/llversioninfo.cpp b/indra/newview/llversioninfo.cpp
index 673d0c24cf..6a8fad0134 100644..100755
--- a/indra/newview/llversioninfo.cpp
+++ b/indra/newview/llversioninfo.cpp
@@ -26,73 +26,76 @@
*/
#include "llviewerprecompiledheaders.h"
+#include <iostream>
+#include <sstream>
#include "llversioninfo.h"
-#include "llversionviewer.h"
+#if ! defined(LL_VIEWER_CHANNEL) \
+ || ! defined(LL_VIEWER_VERSION_MAJOR) \
+ || ! defined(LL_VIEWER_VERSION_MINOR) \
+ || ! defined(LL_VIEWER_VERSION_PATCH) \
+ || ! defined(LL_VIEWER_VERSION_BUILD)
+ #error "Channel or Version information is undefined"
+#endif
+
+const char * const LL_CHANNEL = LL_VIEWER_CHANNEL;
//
-// Set the version numbers in indra/llcommon/llversionviewer.h
+// Set the version numbers in indra/VIEWER_VERSION
//
//static
S32 LLVersionInfo::getMajor()
{
- return LL_VERSION_MAJOR;
+ return LL_VIEWER_VERSION_MAJOR;
}
//static
S32 LLVersionInfo::getMinor()
{
- return LL_VERSION_MINOR;
+ return LL_VIEWER_VERSION_MINOR;
}
//static
S32 LLVersionInfo::getPatch()
{
- return LL_VERSION_PATCH;
+ return LL_VIEWER_VERSION_PATCH;
}
//static
S32 LLVersionInfo::getBuild()
{
- return LL_VERSION_BUILD;
+ return LL_VIEWER_VERSION_BUILD;
}
//static
const std::string &LLVersionInfo::getVersion()
{
static std::string version("");
-
if (version.empty())
{
- // cache the version string
std::ostringstream stream;
- stream << LL_VERSION_MAJOR << "."
- << LL_VERSION_MINOR << "."
- << LL_VERSION_PATCH << "."
- << LL_VERSION_BUILD;
+ stream << LLVersionInfo::getShortVersion() << "." << LLVersionInfo::getBuild();
+ // cache the version string
version = stream.str();
}
-
return version;
}
//static
const std::string &LLVersionInfo::getShortVersion()
{
- static std::string version("");
-
- if (version.empty())
+ static std::string short_version("");
+ if(short_version.empty())
{
// cache the version string
std::ostringstream stream;
- stream << LL_VERSION_MAJOR << "."
- << LL_VERSION_MINOR << "."
- << LL_VERSION_PATCH;
- version = stream.str();
+ stream << LL_VIEWER_VERSION_MAJOR << "."
+ << LL_VIEWER_VERSION_MINOR << "."
+ << LL_VIEWER_VERSION_PATCH;
+ short_version = stream.str();
}
-
- return version;
+ return short_version;
}
namespace
@@ -100,7 +103,7 @@ namespace
/// Storage of the channel name the viewer is using.
// The channel name is set by hardcoded constant,
// or by calling LLVersionInfo::resetChannel()
- std::string sWorkingChannelName(LL_CHANNEL);
+ std::string sWorkingChannelName(LL_VIEWER_CHANNEL);
// Storage for the "version and channel" string.
// This will get reset too.
@@ -113,11 +116,7 @@ const std::string &LLVersionInfo::getChannelAndVersion()
if (sVersionChannel.empty())
{
// cache the version string
- std::ostringstream stream;
- stream << LLVersionInfo::getChannel()
- << " "
- << LLVersionInfo::getVersion();
- sVersionChannel = stream.str();
+ sVersionChannel = LLVersionInfo::getChannel() + " " + LLVersionInfo::getVersion();
}
return sVersionChannel;
diff --git a/indra/newview/llversioninfo.h b/indra/newview/llversioninfo.h
index 6f64544f3b..077105cae8 100644..100755
--- a/indra/newview/llversioninfo.h
+++ b/indra/newview/llversioninfo.h
@@ -29,6 +29,7 @@
#define LL_LLVERSIONINFO_H
#include <string>
+#include "stdtypes.h"
///
/// This API provides version information for the viewer. This
diff --git a/indra/newview/llviewchildren.cpp b/indra/newview/llviewchildren.cpp
index 5c5bbdc8f5..5c5bbdc8f5 100644..100755
--- a/indra/newview/llviewchildren.cpp
+++ b/indra/newview/llviewchildren.cpp
diff --git a/indra/newview/llviewchildren.h b/indra/newview/llviewchildren.h
index 4cd8209259..4cd8209259 100644..100755
--- a/indra/newview/llviewchildren.h
+++ b/indra/newview/llviewchildren.h
diff --git a/indra/newview/llviewerassetstats.cpp b/indra/newview/llviewerassetstats.cpp
index e621cf647e..aaa81c57d4 100644..100755
--- a/indra/newview/llviewerassetstats.cpp
+++ b/indra/newview/llviewerassetstats.cpp
@@ -30,6 +30,7 @@
#include "llregionhandle.h"
#include "stdtypes.h"
+#include "llvoavatar.h"
/*
* Classes and utility functions for per-thread and per-region
@@ -126,6 +127,8 @@ LLViewerAssetStats::PerRegionStats::merge(const LLViewerAssetStats::PerRegionSta
mFPS.merge(src.mFPS);
}
+ // Avatar stats - data all comes from main thread, so leave alone.
+
// Requests
for (int i = 0; i < LL_ARRAY_SIZE(mRequests); ++i)
{
@@ -133,6 +136,7 @@ LLViewerAssetStats::PerRegionStats::merge(const LLViewerAssetStats::PerRegionSta
mRequests[i].mDequeued.merge(src.mRequests[i].mDequeued);
mRequests[i].mResponse.merge(src.mRequests[i].mResponse);
}
+
}
@@ -329,7 +333,6 @@ LLViewerAssetStats::asLLSD(bool compact_output)
slot[max_tag] = LLSD(F64(stats.mFPS.getMax()));
slot[mean_tag] = LLSD(F64(stats.mFPS.getMean()));
}
-
U32 grid_x(0), grid_y(0);
grid_from_region_handle(it->first, &grid_x, &grid_y);
reg_stat["grid_x"] = LLSD::Integer(grid_x);
@@ -439,7 +442,6 @@ record_fps_main(F32 fps)
gViewerAssetStatsMain->recordFPS(fps);
}
-
// 'thread1' - should be for TextureFetch thread
void
diff --git a/indra/newview/llviewerassetstats.h b/indra/newview/llviewerassetstats.h
index 73ec5974b2..e4581d2120 100644..100755
--- a/indra/newview/llviewerassetstats.h
+++ b/indra/newview/llviewerassetstats.h
@@ -36,6 +36,7 @@
#include "llviewerassetstorage.h"
#include "llsimplestat.h"
#include "llsd.h"
+#include "llvoavatar.h"
/**
* @class LLViewerAssetStats
@@ -181,6 +182,9 @@ public:
// Frames-Per-Second Samples
void recordFPS(F32 fps);
+ // Avatar-related statistics
+ void recordAvatarStats();
+
// Merge a source instance into a destination instance. This is
// conceptually an 'operator+=()' method:
// - counts are added
@@ -310,7 +314,6 @@ void record_response_main(LLViewerAssetType::EType at, bool with_http, bool is_t
void record_fps_main(F32 fps);
-
/**
* Region context, event and duration loggers for Thread 1.
*/
diff --git a/indra/newview/llviewerassetstorage.cpp b/indra/newview/llviewerassetstorage.cpp
index d042f62830..d042f62830 100644..100755
--- a/indra/newview/llviewerassetstorage.cpp
+++ b/indra/newview/llviewerassetstorage.cpp
diff --git a/indra/newview/llviewerassetstorage.h b/indra/newview/llviewerassetstorage.h
index ca9b9943fa..ca9b9943fa 100644..100755
--- a/indra/newview/llviewerassetstorage.h
+++ b/indra/newview/llviewerassetstorage.h
diff --git a/indra/newview/llviewerassettype.cpp b/indra/newview/llviewerassettype.cpp
index a4b1c2155f..08ba5a5f25 100644..100755
--- a/indra/newview/llviewerassettype.cpp
+++ b/indra/newview/llviewerassettype.cpp
@@ -83,6 +83,8 @@ LLViewerAssetDictionary::LLViewerAssetDictionary()
addEntry(LLViewerAssetType::AT_WIDGET, new ViewerAssetEntry(DAD_WIDGET));
+ addEntry(LLViewerAssetType::AT_PERSON, new ViewerAssetEntry(DAD_PERSON));
+
addEntry(LLViewerAssetType::AT_NONE, new ViewerAssetEntry(DAD_NONE));
};
diff --git a/indra/newview/llviewerassettype.h b/indra/newview/llviewerassettype.h
index ec8b822917..ec8b822917 100644..100755
--- a/indra/newview/llviewerassettype.h
+++ b/indra/newview/llviewerassettype.h
diff --git a/indra/newview/llviewerattachmenu.cpp b/indra/newview/llviewerattachmenu.cpp
index db7dc3fea6..3975292ed3 100644..100755
--- a/indra/newview/llviewerattachmenu.cpp
+++ b/indra/newview/llviewerattachmenu.cpp
@@ -121,7 +121,7 @@ void LLViewerAttachMenu::attachObjects(const uuid_vec_t& items, const std::strin
else if(item && item->isFinished())
{
// must be in library. copy it to our inventory and put it on.
- LLPointer<LLInventoryCallback> cb = new RezAttachmentCallback(attachmentp);
+ LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(rez_attachment_cb, _1, attachmentp));
copy_inventory_item(gAgent.getID(),
item->getPermissions().getOwner(),
item->getUUID(),
diff --git a/indra/newview/llviewerattachmenu.h b/indra/newview/llviewerattachmenu.h
index 064c69ef4d..064c69ef4d 100644..100755
--- a/indra/newview/llviewerattachmenu.h
+++ b/indra/newview/llviewerattachmenu.h
diff --git a/indra/newview/llvieweraudio.cpp b/indra/newview/llvieweraudio.cpp
index 2447f5dea8..3da934b148 100644..100755
--- a/indra/newview/llvieweraudio.cpp
+++ b/indra/newview/llvieweraudio.cpp
@@ -30,6 +30,7 @@
#include "llagent.h"
#include "llagentcamera.h"
#include "llappviewer.h"
+#include "lldeferredsounds.h"
#include "llvieweraudio.h"
#include "llviewercamera.h"
#include "llviewercontrol.h"
@@ -41,6 +42,9 @@
#include "llstartup.h"
#include "llviewerparcelmgr.h"
#include "llparcel.h"
+#include "llviewermessage.h"
+
+#include "llstreamingaudio.h"
/////////////////////////////////////////////////////////
@@ -49,15 +53,22 @@ LLViewerAudio::LLViewerAudio() :
mFadeState(FADE_IDLE),
mFadeTime(),
mIdleListnerActive(false),
- mForcedTeleportFade(false)
+ mForcedTeleportFade(false),
+ mWasPlaying(false)
{
mTeleportFailedConnection = LLViewerParcelMgr::getInstance()->
setTeleportFailedCallback(boost::bind(&LLViewerAudio::onTeleportFailed, this));
+ mTeleportFinishedConnection = LLViewerParcelMgr::getInstance()->
+ setTeleportFinishedCallback(boost::bind(&LLViewerAudio::onTeleportFinished, this, _1, _2));
+ mTeleportStartedConnection = LLViewerMessage::getInstance()->
+ setTeleportStartedCallback(boost::bind(&LLViewerAudio::onTeleportStarted, this));
}
LLViewerAudio::~LLViewerAudio()
{
mTeleportFailedConnection.disconnect();
+ mTeleportFinishedConnection.disconnect();
+ mTeleportStartedConnection.disconnect();
}
void LLViewerAudio::registerIdleListener()
@@ -67,7 +78,6 @@ void LLViewerAudio::registerIdleListener()
mIdleListnerActive = true;
doOnIdleRepeating(boost::bind(boost::bind(&LLViewerAudio::onIdleUpdate, this)));
}
-
}
void LLViewerAudio::startInternetStreamWithAutoFade(std::string streamURI)
@@ -94,6 +104,11 @@ void LLViewerAudio::startInternetStreamWithAutoFade(std::string streamURI)
else
{
mFadeState = FADE_IN;
+
+ LLStreamingAudioInterface *stream = gAudiop->getStreamingAudioImpl();
+ if(stream && stream->supportsAdjustableBufferSizes())
+ stream->setBufferSizes(gSavedSettings.getU32("FMODExStreamBufferSize"),gSavedSettings.getU32("FMODExDecodeBufferSize"));
+
gAudiop->startInternetStream(mNextStreamURI);
startFading();
registerIdleListener();
@@ -149,6 +164,11 @@ bool LLViewerAudio::onIdleUpdate()
if (!mNextStreamURI.empty())
{
mFadeState = FADE_IN;
+
+ LLStreamingAudioInterface *stream = gAudiop->getStreamingAudioImpl();
+ if(stream && stream->supportsAdjustableBufferSizes())
+ stream->setBufferSizes(gSavedSettings.getU32("FMODExStreamBufferSize"),gSavedSettings.getU32("FMODExDecodeBufferSize"));
+
gAudiop->startInternetStream(mNextStreamURI);
startFading();
}
@@ -245,16 +265,54 @@ F32 LLViewerAudio::getFadeVolume()
return fade_volume;
}
+void LLViewerAudio::onTeleportStarted()
+{
+ if (!LLViewerAudio::getInstance()->getForcedTeleportFade())
+ {
+ // Even though the music was turned off it was starting up (with autoplay disabled) occasionally
+ // after a failed teleport or after an intra-parcel teleport. Also, the music sometimes was not
+ // restarting after a successful intra-parcel teleport. Setting mWasPlaying fixes these issues.
+ LLViewerAudio::getInstance()->setWasPlaying(!gAudiop->getInternetStreamURL().empty());
+ LLViewerAudio::getInstance()->setForcedTeleportFade(true);
+ LLViewerAudio::getInstance()->startInternetStreamWithAutoFade(LLStringUtil::null);
+ LLViewerAudio::getInstance()->setNextStreamURI(LLStringUtil::null);
+ }
+}
+
void LLViewerAudio::onTeleportFailed()
{
- if (gAudiop)
+ // Calling audio_update_volume makes sure that the music stream is properly set to be restored to
+ // its previous value
+ audio_update_volume(false);
+
+ if (gAudiop && mWasPlaying)
+ {
+ LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
+ if (parcel)
+ {
+ mNextStreamURI = parcel->getMusicURL();
+ llinfos << "Teleport failed -- setting music stream to " << mNextStreamURI << llendl;
+ }
+ }
+ mWasPlaying = false;
+}
+
+void LLViewerAudio::onTeleportFinished(const LLVector3d& pos, const bool& local)
+{
+ // Calling audio_update_volume makes sure that the music stream is properly set to be restored to
+ // its previous value
+ audio_update_volume(false);
+
+ if (gAudiop && local && mWasPlaying)
{
LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
if (parcel)
{
mNextStreamURI = parcel->getMusicURL();
+ llinfos << "Intraparcel teleport -- setting music stream to " << mNextStreamURI << llendl;
}
}
+ mWasPlaying = false;
}
void init_audio()
@@ -340,9 +398,20 @@ void audio_update_volume(bool force_update)
gAudiop->setMasterGain ( master_volume );
gAudiop->setDopplerFactor(gSavedSettings.getF32("AudioLevelDoppler"));
+
+ if(!LLViewerCamera::getInstance()->cameraUnderWater())
gAudiop->setRolloffFactor(gSavedSettings.getF32("AudioLevelRolloff"));
+ else
+ gAudiop->setRolloffFactor(gSavedSettings.getF32("AudioLevelUnderwaterRolloff"));
+
gAudiop->setMuted(mute_audio || progress_view_visible);
+ //Play any deferred sounds when unmuted
+ if(!gAudiop->getMuted())
+ {
+ LLDeferredSounds::instance().playdeferredSounds();
+ }
+
if (force_update)
{
audio_update_wind(true);
@@ -360,15 +429,9 @@ void audio_update_volume(bool force_update)
// Streaming Music
if (gAudiop)
{
- if (progress_view_visible && !LLViewerAudio::getInstance()->getForcedTeleportFade())
- {
- LLViewerAudio::getInstance()->setForcedTeleportFade(true);
- LLViewerAudio::getInstance()->startInternetStreamWithAutoFade(LLStringUtil::null);
- LLViewerAudio::getInstance()->setNextStreamURI(LLStringUtil::null);
- }
-
- if (!progress_view_visible && LLViewerAudio::getInstance()->getForcedTeleportFade() == true)
+ if (!progress_view_visible && LLViewerAudio::getInstance()->getForcedTeleportFade())
{
+ LLViewerAudio::getInstance()->setWasPlaying(!gAudiop->getInternetStreamURL().empty());
LLViewerAudio::getInstance()->setForcedTeleportFade(false);
}
@@ -427,32 +490,10 @@ void audio_update_listener()
void audio_update_wind(bool force_update)
{
#ifdef kAUDIO_ENABLE_WIND
- //
- // Extract height above water to modulate filter by whether above/below water
- //
+
LLViewerRegion* region = gAgent.getRegion();
if (region)
{
- static F32 last_camera_water_height = -1000.f;
- LLVector3 camera_pos = gAgentCamera.getCameraPositionAgent();
- F32 camera_water_height = camera_pos.mV[VZ] - region->getWaterHeight();
-
- //
- // Don't update rolloff factor unless water surface has been crossed
- //
- if (force_update || (last_camera_water_height * camera_water_height) < 0.f)
- {
- static LLUICachedControl<F32> rolloff("AudioLevelRolloff", 1.0f);
- if (camera_water_height < 0.f)
- {
- gAudiop->setRolloffFactor(rolloff * LL_ROLLOFF_MULTIPLIER_UNDER_WATER);
- }
- else
- {
- gAudiop->setRolloffFactor(rolloff);
- }
- }
-
// Scale down the contribution of weather-simulation wind to the
// ambient wind noise. Wind velocity averages 3.5 m/s, with gusts to 7 m/s
// whereas steady-state avatar walk velocity is only 3.2 m/s.
@@ -497,8 +538,7 @@ void audio_update_wind(bool force_update)
gAudiop->mMaxWindGain = llmax(gAudiop->mMaxWindGain - volume_delta, 0.f);
}
- last_camera_water_height = camera_water_height;
- gAudiop->updateWind(gRelativeWindVec, camera_water_height);
+ gAudiop->updateWind(gRelativeWindVec, gAgentCamera.getCameraPositionAgent()[VZ] - gAgent.getRegion()->getWaterHeight());
}
#endif
}
diff --git a/indra/newview/llvieweraudio.h b/indra/newview/llvieweraudio.h
index a3da9fc6b8..8c302c6549 100644..100755
--- a/indra/newview/llvieweraudio.h
+++ b/indra/newview/llvieweraudio.h
@@ -66,6 +66,7 @@ public:
bool getForcedTeleportFade() { return mForcedTeleportFade; };
void setForcedTeleportFade(bool fade) { mForcedTeleportFade = fade;} ;
void setNextStreamURI(std::string stream) { mNextStreamURI = stream; } ;
+ void setWasPlaying(bool playing) { mWasPlaying = playing;} ;
private:
@@ -76,13 +77,17 @@ private:
LLFrameTimer stream_fade_timer;
bool mIdleListnerActive;
bool mForcedTeleportFade;
+ bool mWasPlaying;
boost::signals2::connection mTeleportFailedConnection;
+ boost::signals2::connection mTeleportFinishedConnection;
+ boost::signals2::connection mTeleportStartedConnection;
void registerIdleListener();
void deregisterIdleListener() { mIdleListnerActive = false; };
void startFading();
void onTeleportFailed();
-
+ void onTeleportFinished(const LLVector3d& pos, const bool& local);
+ void onTeleportStarted();
};
#endif //LL_VIEWER_H
diff --git a/indra/newview/llviewercamera.cpp b/indra/newview/llviewercamera.cpp
index a437a8b3b5..b5aa0ac92a 100644..100755
--- a/indra/newview/llviewercamera.cpp
+++ b/indra/newview/llviewercamera.cpp
@@ -136,9 +136,6 @@ void LLViewerCamera::updateCameraLocation(const LLVector3 &center,
mLastPointOfInterest = point_of_interest;
- // constrain to max distance from avatar
- LLVector3 camera_offset = center - gAgent.getPositionAgent();
-
LLViewerRegion * regp = gAgent.getRegion();
F32 water_height = (NULL != regp) ? regp->getWaterHeight() : 0.f;
@@ -318,7 +315,7 @@ void LLViewerCamera::setPerspective(BOOL for_selection,
{
F32 fov_y, aspect;
fov_y = RAD_TO_DEG * getView();
- BOOL z_default_near, z_default_far = FALSE;
+ BOOL z_default_far = FALSE;
if (z_far <= 0)
{
z_default_far = TRUE;
@@ -326,7 +323,6 @@ void LLViewerCamera::setPerspective(BOOL for_selection,
}
if (z_near <= 0)
{
- z_default_near = TRUE;
z_near = getNear();
}
aspect = getAspect();
diff --git a/indra/newview/llviewercamera.h b/indra/newview/llviewercamera.h
index 184033de42..b857c7fe89 100644..100755
--- a/indra/newview/llviewercamera.h
+++ b/indra/newview/llviewercamera.h
@@ -51,9 +51,19 @@ const BOOL NOT_FOR_SELECTION = FALSE;
extern template class LLViewerCamera* LLSingleton<class LLViewerCamera>::getInstance();
#endif
+LL_ALIGN_PREFIX(16)
class LLViewerCamera : public LLCamera, public LLSingleton<LLViewerCamera>
{
public:
+ void* operator new(size_t size)
+ {
+ return ll_aligned_malloc_16(size);
+ }
+
+ void operator delete(void* ptr)
+ {
+ ll_aligned_free_16(ptr);
+ }
typedef enum
{
@@ -137,6 +147,7 @@ protected:
S16 mZoomSubregion;
public:
-};
+} LL_ALIGN_POSTFIX(16);
+
#endif // LL_LLVIEWERCAMERA_H
diff --git a/indra/newview/llviewerchat.cpp b/indra/newview/llviewerchat.cpp
index 93687dbd5f..93687dbd5f 100644..100755
--- a/indra/newview/llviewerchat.cpp
+++ b/indra/newview/llviewerchat.cpp
diff --git a/indra/newview/llviewerchat.h b/indra/newview/llviewerchat.h
index c05caf0a95..c05caf0a95 100644..100755
--- a/indra/newview/llviewerchat.h
+++ b/indra/newview/llviewerchat.h
diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp
index ab45aae5cc..744ec4de2b 100644..100755
--- a/indra/newview/llviewercontrol.cpp
+++ b/indra/newview/llviewercontrol.cpp
@@ -71,13 +71,21 @@
#include "llpaneloutfitsinventory.h"
#include "llpanellogin.h"
#include "llpaneltopinfobar.h"
+#include "llspellcheck.h"
+#include "llslurl.h"
+#include "llstartup.h"
#include "llupdaterservice.h"
+// Third party library includes
+#include <boost/algorithm/string.hpp>
+
#ifdef TOGGLE_HACKED_GODLIKE_VIEWER
BOOL gHackGodmode = FALSE;
#endif
-
+// Should you contemplate changing the name "Global", please first grep for
+// that string literal. There are at least a couple other places in the C++
+// code that assume the LLControlGroup named "Global" is gSavedSettings.
LLControlGroup gSavedSettings("Global"); // saved at end of session
LLControlGroup gSavedPerAccountSettings("PerAccount"); // saved at end of session
LLControlGroup gCrashSettings("CrashSettings"); // saved at end of session
@@ -87,7 +95,6 @@ std::string gLastRunVersion;
extern BOOL gResizeScreenTexture;
extern BOOL gDebugGL;
-extern BOOL gAuditTexture;
////////////////////////////////////////////////////////////////////////////
// Listeners
@@ -326,7 +333,7 @@ static bool handleJoystickChanged(const LLSD& newvalue)
static bool handleUseOcclusionChanged(const LLSD& newvalue)
{
- LLPipeline::sUseOcclusion = (newvalue.asBoolean() && gGLManager.mHasOcclusionQuery
+ LLPipeline::sUseOcclusion = (newvalue.asBoolean() && gGLManager.mHasOcclusionQuery && LLGLSLShader::sNoFixedFunction
&& LLFeatureManager::getInstance()->isFeatureAvailable("UseOcclusion") && !gUseWireframe) ? 2 : 0;
return true;
}
@@ -338,15 +345,6 @@ static bool handleUploadBakedTexOldChanged(const LLSD& newvalue)
}
-static bool handleNumpadControlChanged(const LLSD& newvalue)
-{
- if (gKeyboard)
- {
- gKeyboard->setNumpadDistinct(static_cast<LLKeyboard::e_numpad_distinct>(newvalue.asInteger()));
- }
- return true;
-}
-
static bool handleWLSkyDetailChanged(const LLSD&)
{
if (gSky.mVOWLSkyp.notNull())
@@ -405,15 +403,28 @@ static bool handleRenderDeferredChanged(const LLSD& newvalue)
return true;
}
-static bool handleRenderUseImpostorsChanged(const LLSD& newvalue)
+// This looks a great deal like handleRenderDeferredChanged because
+// Advanced Lighting (Materials) implies bumps and shiny so disabling
+// bumps should further disable that feature.
+//
+static bool handleRenderBumpChanged(const LLSD& newval)
{
- LLVOAvatar::sUseImpostors = newvalue.asBoolean();
+ LLRenderTarget::sUseFBO = newval.asBoolean();
+ if (gPipeline.isInit())
+ {
+ gPipeline.updateRenderBump();
+ gPipeline.updateRenderDeferred();
+ gPipeline.releaseGLBuffers();
+ gPipeline.createGLBuffers();
+ gPipeline.resetVertexBuffers();
+ LLViewerShaderMgr::instance()->setShaders();
+ }
return true;
}
-static bool handleAuditTextureChanged(const LLSD& newvalue)
+static bool handleRenderUseImpostorsChanged(const LLSD& newvalue)
{
- gAuditTexture = newvalue.asBoolean();
+ LLVOAvatar::sUseImpostors = newvalue.asBoolean();
return true;
}
@@ -508,6 +519,39 @@ bool handleForceShowGrid(const LLSD& newvalue)
return true;
}
+bool handleLoginLocationChanged()
+{
+ /*
+ * This connects the default preference setting to the state of the login
+ * panel if it is displayed; if you open the preferences panel before
+ * logging in, and change the default login location there, the login
+ * panel immediately changes to match your new preference.
+ */
+ std::string new_login_location = gSavedSettings.getString("LoginLocation");
+ LL_DEBUGS("AppInit")<<new_login_location<<LL_ENDL;
+ LLStartUp::setStartSLURL(LLSLURL(new_login_location));
+ return true;
+}
+
+bool handleSpellCheckChanged()
+{
+ if (gSavedSettings.getBOOL("SpellCheck"))
+ {
+ std::list<std::string> dict_list;
+ std::string dict_setting = gSavedSettings.getString("SpellCheckDictionary");
+ boost::split(dict_list, dict_setting, boost::is_any_of(std::string(",")));
+ if (!dict_list.empty())
+ {
+ LLSpellChecker::setUseSpellCheck(dict_list.front());
+ dict_list.pop_front();
+ LLSpellChecker::instance().setSecondaryDictionaries(dict_list);
+ return true;
+ }
+ }
+ LLSpellChecker::setUseSpellCheck(LLStringUtil::null);
+ return true;
+}
+
bool toggle_agent_pause(const LLSD& newvalue)
{
if ( newvalue.asBoolean() )
@@ -606,7 +650,7 @@ void settings_setup_listeners()
gSavedSettings.getControl("RenderDebugTextureBind")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
gSavedSettings.getControl("RenderAutoMaskAlphaDeferred")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
gSavedSettings.getControl("RenderAutoMaskAlphaNonDeferred")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
- gSavedSettings.getControl("RenderObjectBump")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
+ gSavedSettings.getControl("RenderObjectBump")->getSignal()->connect(boost::bind(&handleRenderBumpChanged, _2));
gSavedSettings.getControl("RenderMaxVBOSize")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
gSavedSettings.getControl("RenderDeferredNoise")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2));
gSavedSettings.getControl("RenderUseImpostors")->getSignal()->connect(boost::bind(&handleRenderUseImpostorsChanged, _2));
@@ -618,7 +662,6 @@ void settings_setup_listeners()
gSavedSettings.getControl("RenderDeferredSSAO")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
gSavedSettings.getControl("RenderPerformanceTest")->getSignal()->connect(boost::bind(&handleRenderPerfTestChanged, _2));
gSavedSettings.getControl("TextureMemory")->getSignal()->connect(boost::bind(&handleVideoMemoryChanged, _2));
- gSavedSettings.getControl("AuditTexture")->getSignal()->connect(boost::bind(&handleAuditTextureChanged, _2));
gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&handleChatFontSizeChanged, _2));
gSavedSettings.getControl("ChatPersistTime")->getSignal()->connect(boost::bind(&handleChatPersistTimeChanged, _2));
gSavedSettings.getControl("ConsoleMaxLines")->getSignal()->connect(boost::bind(&handleConsoleMaxLinesChanged, _2));
@@ -633,6 +676,7 @@ void settings_setup_listeners()
gSavedSettings.getControl("AudioLevelVoice")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
gSavedSettings.getControl("AudioLevelDoppler")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
gSavedSettings.getControl("AudioLevelRolloff")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
+ gSavedSettings.getControl("AudioLevelUnderwaterRolloff")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
gSavedSettings.getControl("MuteAudio")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
gSavedSettings.getControl("MuteMusic")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
gSavedSettings.getControl("MuteMedia")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
@@ -645,7 +689,6 @@ void settings_setup_listeners()
gSavedSettings.getControl("RenderUseStreamVBO")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
gSavedSettings.getControl("RenderPreferStreamDraw")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
gSavedSettings.getControl("WLSkyDetail")->getSignal()->connect(boost::bind(&handleWLSkyDetailChanged, _2));
- gSavedSettings.getControl("NumpadControl")->getSignal()->connect(boost::bind(&handleNumpadControlChanged, _2));
gSavedSettings.getControl("JoystickAxis0")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
gSavedSettings.getControl("JoystickAxis1")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
gSavedSettings.getControl("JoystickAxis2")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
@@ -714,6 +757,9 @@ void settings_setup_listeners()
gSavedSettings.getControl("UpdaterServiceSetting")->getSignal()->connect(boost::bind(&toggle_updater_service_active, _2));
gSavedSettings.getControl("ForceShowGrid")->getSignal()->connect(boost::bind(&handleForceShowGrid, _2));
gSavedSettings.getControl("RenderTransparentWater")->getSignal()->connect(boost::bind(&handleRenderTransparentWaterChanged, _2));
+ gSavedSettings.getControl("SpellCheck")->getSignal()->connect(boost::bind(&handleSpellCheckChanged));
+ gSavedSettings.getControl("SpellCheckDictionary")->getSignal()->connect(boost::bind(&handleSpellCheckChanged));
+ gSavedSettings.getControl("LoginLocation")->getSignal()->connect(boost::bind(&handleLoginLocationChanged));
}
#if TEST_CACHED_CONTROL
diff --git a/indra/newview/llviewercontrol.h b/indra/newview/llviewercontrol.h
index d7191f5c8d..d7191f5c8d 100644..100755
--- a/indra/newview/llviewercontrol.h
+++ b/indra/newview/llviewercontrol.h
diff --git a/indra/newview/llviewercontrollistener.cpp b/indra/newview/llviewercontrollistener.cpp
index 361b96221c..361b96221c 100644..100755
--- a/indra/newview/llviewercontrollistener.cpp
+++ b/indra/newview/llviewercontrollistener.cpp
diff --git a/indra/newview/llviewercontrollistener.h b/indra/newview/llviewercontrollistener.h
index 2e72046924..2e72046924 100644..100755
--- a/indra/newview/llviewercontrollistener.h
+++ b/indra/newview/llviewercontrollistener.h
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index 0adb187dd2..bbebeea3e0 100644..100755
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -79,6 +79,7 @@
#include "llpostprocess.h"
extern LLPointer<LLViewerTexture> gStartTexture;
+extern bool gShiftFrame;
LLPointer<LLViewerTexture> gDisconnectedImagep = NULL;
@@ -97,6 +98,7 @@ BOOL gDepthDirty = FALSE;
BOOL gResizeScreenTexture = FALSE;
BOOL gWindowResized = FALSE;
BOOL gSnapshot = FALSE;
+BOOL gShaderProfileFrame = FALSE;
U32 gRecentFrameCount = 0; // number of 'recent' frames
LLFrameTimer gRecentFPSTime;
@@ -113,7 +115,8 @@ void render_disconnected_background();
void display_startup()
{
- if ( !gViewerWindow->getActive()
+ if ( !gViewerWindow
+ || !gViewerWindow->getActive()
|| !gViewerWindow->getWindow()->getVisible()
|| gViewerWindow->getWindow()->getMinimized() )
{
@@ -124,7 +127,14 @@ void display_startup()
// Update images?
//gImageList.updateImages(0.01f);
- LLTexUnit::sWhiteTexture = LLViewerFetchedTexture::sWhiteImagep->getTexName();
+
+ // Written as branch to appease GCC which doesn't like different
+ // pointer types across ternary ops
+ //
+ if (!LLViewerFetchedTexture::sWhiteImagep.isNull())
+ {
+ LLTexUnit::sWhiteTexture = LLViewerFetchedTexture::sWhiteImagep->getTexName();
+ }
LLGLSDefault gls_default;
@@ -146,10 +156,12 @@ void display_startup()
LLGLSUIDefault gls_ui;
gPipeline.disableLights();
+ if (gViewerWindow)
gViewerWindow->setup2DRender();
gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
gGL.color4f(1,1,1,1);
+ if (gViewerWindow)
gViewerWindow->draw();
gGL.flush();
@@ -158,13 +170,17 @@ void display_startup()
LLGLState::checkStates();
LLGLState::checkTextureChannels();
+ if (gViewerWindow && gViewerWindow->getWindow())
gViewerWindow->getWindow()->swapBuffers();
+
glClear(GL_DEPTH_BUFFER_BIT);
}
+static LLFastTimer::DeclareTimer FTM_UPDATE_CAMERA("Update Camera");
+
void display_update_camera()
{
- LLMemType mt_uc(LLMemType::MTYPE_DISPLAY_UPDATE_CAMERA);
+ LLFastTimer t(FTM_UPDATE_CAMERA);
// TODO: cut draw distance down if customizing avatar?
// TODO: cut draw distance on per-parcel basis?
@@ -214,18 +230,23 @@ static LLFastTimer::DeclareTimer FTM_UPDATE_SKY("Update Sky");
static LLFastTimer::DeclareTimer FTM_UPDATE_TEXTURES("Update Textures");
static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE("Update Images");
static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE_CLASS("Class");
-static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE_BUMP("Bump");
+static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE_BUMP("Image Update Bump");
static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE_LIST("List");
static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE_DELETE("Delete");
+static LLFastTimer::DeclareTimer FTM_RESIZE_WINDOW("Resize Window");
+static LLFastTimer::DeclareTimer FTM_HUD_UPDATE("HUD Update");
+static LLFastTimer::DeclareTimer FTM_DISPLAY_UPDATE_GEOM("Update Geom");
+static LLFastTimer::DeclareTimer FTM_TEXTURE_UNBIND("Texture Unbind");
+static LLFastTimer::DeclareTimer FTM_TELEPORT_DISPLAY("Teleport Display");
// Paint the display!
void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
{
- LLMemType mt_render(LLMemType::MTYPE_RENDER);
LLFastTimer t(FTM_RENDER);
if (gWindowResized)
{ //skip render on frames where window has been resized
+ LLFastTimer t(FTM_RESIZE_WINDOW);
gGL.flush();
glClear(GL_COLOR_BUFFER_BIT);
gViewerWindow->getWindow()->swapBuffers();
@@ -332,6 +353,12 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
return;
}
+
+ if (gShaderProfileFrame)
+ {
+ LLGLSLShader::initProfile();
+ }
+
//LLGLState::verify(FALSE);
/////////////////////////////////////////////////
@@ -362,6 +389,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
if (gTeleportDisplay)
{
+ LLFastTimer t(FTM_TELEPORT_DISPLAY);
LLAppViewer::instance()->pingMainloopTimeout("Display:Teleport");
const F32 TELEPORT_ARRIVAL_DELAY = 2.f; // Time to preload the world before raising the curtain after we've actually already arrived.
@@ -383,15 +411,24 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
const std::string& message = gAgent.getTeleportMessage();
switch( gAgent.getTeleportState() )
{
+ case LLAgent::TELEPORT_PENDING:
+ gTeleportDisplayTimer.reset();
+ gViewerWindow->setShowProgress(TRUE);
+ gViewerWindow->setProgressPercent(llmin(teleport_percent, 0.0f));
+ gAgent.setTeleportMessage(LLAgent::sTeleportProgressMessages["pending"]);
+ gViewerWindow->setProgressString(LLAgent::sTeleportProgressMessages["pending"]);
+ break;
+
case LLAgent::TELEPORT_START:
// Transition to REQUESTED. Viewer has sent some kind
// of TeleportRequest to the source simulator
gTeleportDisplayTimer.reset();
gViewerWindow->setShowProgress(TRUE);
- gViewerWindow->setProgressPercent(0);
+ gViewerWindow->setProgressPercent(llmin(teleport_percent, 0.0f));
gAgent.setTeleportState( LLAgent::TELEPORT_REQUESTED );
gAgent.setTeleportMessage(
LLAgent::sTeleportProgressMessages["requesting"]);
+ gViewerWindow->setProgressString(LLAgent::sTeleportProgressMessages["requesting"]);
break;
case LLAgent::TELEPORT_REQUESTED:
@@ -416,6 +453,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
LLAgent::sTeleportProgressMessages["arriving"]);
gTextureList.mForceResetTextureStats = TRUE;
gAgentCamera.resetView(TRUE, TRUE);
+
break;
case LLAgent::TELEPORT_ARRIVING:
@@ -560,7 +598,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
if (!gDisconnected)
{
- LLMemType mt_du(LLMemType::MTYPE_DISPLAY_UPDATE);
LLAppViewer::instance()->pingMainloopTimeout("Display:Update");
if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD))
{ //don't draw hud objects in this frame
@@ -581,14 +618,14 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
// *TODO: merge these two methods
{
- LLMemType mt_uh(LLMemType::MTYPE_DISPLAY_UPDATE_HUD);
+ LLFastTimer t(FTM_HUD_UPDATE);
LLHUDManager::getInstance()->updateEffects();
LLHUDObject::updateAll();
stop_glerror();
}
{
- LLMemType mt_ug(LLMemType::MTYPE_DISPLAY_UPDATE_GEOM);
+ LLFastTimer t(FTM_DISPLAY_UPDATE_GEOM);
const F32 max_geom_update_time = 0.005f*10.f*gFrameIntervalSeconds; // 50 ms/second update time
gPipeline.createObjects(max_geom_update_time);
gPipeline.processPartitionQ();
@@ -597,6 +634,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
}
gPipeline.updateGL();
+
stop_glerror();
S32 water_clip = 0;
@@ -622,11 +660,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
LLSpatialGroup::sNoDelete = TRUE;
LLTexUnit::sWhiteTexture = LLViewerFetchedTexture::sWhiteImagep->getTexName();
- /*if (LLPipeline::sUseOcclusion && LLPipeline::sRenderDeferred)
- { //force occlusion on for all render types if doing deferred render (tighter shadow frustum)
- LLPipeline::sUseOcclusion = 3;
- }*/
-
S32 occlusion = LLPipeline::sUseOcclusion;
if (gDepthDirty)
{ //depth buffer is invalid, don't overwrite occlusion state
@@ -640,6 +673,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
static LLCullResult result;
LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
+ LLPipeline::sUnderWaterRender = LLViewerCamera::getInstance()->cameraUnderWater() ? TRUE : FALSE;
gPipeline.updateCull(*LLViewerCamera::getInstance(), result, water_clip);
stop_glerror();
@@ -653,8 +687,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
LLAppViewer::instance()->pingMainloopTimeout("Display:Swap");
{
- LLMemType mt_ds(LLMemType::MTYPE_DISPLAY_SWAP);
-
if (gResizeScreenTexture)
{
gResizeScreenTexture = FALSE;
@@ -713,7 +745,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
//if (!for_snapshot)
{
- LLMemType mt_gw(LLMemType::MTYPE_DISPLAY_GEN_REFLECTION);
LLAppViewer::instance()->pingMainloopTimeout("Display:Imagery");
gPipeline.generateWaterReflection(*LLViewerCamera::getInstance());
gPipeline.generateHighlight(*LLViewerCamera::getInstance());
@@ -733,7 +764,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
LLAppViewer::instance()->pingMainloopTimeout("Display:UpdateImages");
{
- LLMemType mt_iu(LLMemType::MTYPE_DISPLAY_IMAGE_UPDATE);
LLFastTimer t(FTM_IMAGE_UPDATE);
{
@@ -755,13 +785,13 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
gTextureList.updateImages(max_image_decode_time);
}
- {
+ /*{
LLFastTimer t(FTM_IMAGE_UPDATE_DELETE);
//remove dead textures from GL
LLImageGL::deleteDeadTextures();
stop_glerror();
+ }*/
}
- }
LLGLState::checkStates();
LLGLState::checkClientArrays();
@@ -777,7 +807,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
LLAppViewer::instance()->pingMainloopTimeout("Display:StateSort");
{
LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
- LLMemType mt_ss(LLMemType::MTYPE_DISPLAY_STATE_SORT);
gPipeline.stateSort(*LLViewerCamera::getInstance(), result);
stop_glerror();
@@ -799,7 +828,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
LLPipeline::sUseOcclusion = occlusion;
{
- LLMemType mt_ds(LLMemType::MTYPE_DISPLAY_SKY);
LLAppViewer::instance()->pingMainloopTimeout("Display:Sky");
LLFastTimer t(FTM_UPDATE_SKY);
gSky.updateSky();
@@ -852,7 +880,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
//}
LLPipeline::sUnderWaterRender = LLViewerCamera::getInstance()->cameraUnderWater() ? TRUE : FALSE;
-
+
LLGLState::checkStates();
LLGLState::checkClientArrays();
@@ -862,7 +890,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
{
gGL.setColorMask(true, true);
- if (LLPipeline::sRenderDeferred && !LLPipeline::sUnderWaterRender)
+ if (LLPipeline::sRenderDeferred)
{
gPipeline.mDeferredScreen.bindTarget();
glClearColor(1,0,1,1);
@@ -888,9 +916,30 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
&& !gRestoreGL)
{
LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
- LLMemType mt_rg(LLMemType::MTYPE_DISPLAY_RENDER_GEOM);
+
+ if (gSavedSettings.getBOOL("RenderDepthPrePass") && LLGLSLShader::sNoFixedFunction)
+ {
+ gGL.setColorMask(false, false);
+
+ U32 types[] = {
+ LLRenderPass::PASS_SIMPLE,
+ LLRenderPass::PASS_FULLBRIGHT,
+ LLRenderPass::PASS_SHINY
+ };
+
+ U32 num_types = LL_ARRAY_SIZE(types);
+ gOcclusionProgram.bind();
+ for (U32 i = 0; i < num_types; i++)
+ {
+ gPipeline.renderObjects(types[i], LLVertexBuffer::MAP_VERTEX, FALSE);
+ }
+
+ gOcclusionProgram.unbind();
+ }
+
+
gGL.setColorMask(true, false);
- if (LLPipeline::sRenderDeferred && !LLPipeline::sUnderWaterRender)
+ if (LLPipeline::sRenderDeferred)
{
gPipeline.renderGeomDeferred(*LLViewerCamera::getInstance());
}
@@ -911,20 +960,23 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
stop_glerror();
}
- for (U32 i = 0; i < gGLManager.mNumTextureImageUnits; i++)
- { //dummy cleanup of any currently bound textures
- if (gGL.getTexUnit(i)->getCurrType() != LLTexUnit::TT_NONE)
- {
- gGL.getTexUnit(i)->unbind(gGL.getTexUnit(i)->getCurrType());
- gGL.getTexUnit(i)->disable();
+ {
+ LLFastTimer t(FTM_TEXTURE_UNBIND);
+ for (U32 i = 0; i < gGLManager.mNumTextureImageUnits; i++)
+ { //dummy cleanup of any currently bound textures
+ if (gGL.getTexUnit(i)->getCurrType() != LLTexUnit::TT_NONE)
+ {
+ gGL.getTexUnit(i)->unbind(gGL.getTexUnit(i)->getCurrType());
+ gGL.getTexUnit(i)->disable();
+ }
}
}
+
LLAppViewer::instance()->pingMainloopTimeout("Display:RenderFlush");
if (to_texture)
{
- LLMemType mt_rf(LLMemType::MTYPE_DISPLAY_RENDER_FLUSH);
- if (LLPipeline::sRenderDeferred && !LLPipeline::sUnderWaterRender)
+ if (LLPipeline::sRenderDeferred)
{
gPipeline.mDeferredScreen.flush();
if(LLRenderTarget::sUseFBO)
@@ -950,7 +1002,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
}
}
- if (LLPipeline::sRenderDeferred && !LLPipeline::sUnderWaterRender)
+ if (LLPipeline::sRenderDeferred)
{
gPipeline.renderDeferredLighting();
}
@@ -984,11 +1036,18 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
display_stats();
LLAppViewer::instance()->pingMainloopTimeout("Display:Done");
+
+ gShiftFrame = false;
+
+ if (gShaderProfileFrame)
+ {
+ gShaderProfileFrame = FALSE;
+ LLGLSLShader::finishProfile();
+ }
}
void render_hud_attachments()
{
- LLMemType mt_ra(LLMemType::MTYPE_DISPLAY_RENDER_ATTACHMENTS);
gGL.matrixMode(LLRender::MM_PROJECTION);
gGL.pushMatrix();
gGL.matrixMode(LLRender::MM_MODELVIEW);
@@ -1004,8 +1063,8 @@ void render_hud_attachments()
if (LLPipeline::sShowHUDAttachments && !gDisconnected && setup_hud_matrices())
{
+ LLPipeline::sRenderingHUDs = TRUE;
LLCamera hud_cam = *LLViewerCamera::getInstance();
- LLVector3 origin = hud_cam.getOrigin();
hud_cam.setOrigin(-1.f,0,0);
hud_cam.setAxes(LLVector3(1,0,0), LLVector3(0,1,0), LLVector3(0,0,1));
LLViewerCamera::updateFrustumPlanes(hud_cam, TRUE);
@@ -1049,10 +1108,13 @@ void render_hud_attachments()
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_SIMPLE);
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_VOLUME);
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_ALPHA);
+ gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_ALPHA_MASK);
+ gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_FULLBRIGHT_ALPHA_MASK);
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_FULLBRIGHT);
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_ALPHA);
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK);
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_BUMP);
+ gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_MATERIAL);
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT);
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK);
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY);
@@ -1077,6 +1139,7 @@ void render_hud_attachments()
gPipeline.toggleRenderDebugFeature((void*) LLPipeline::RENDER_DEBUG_FEATURE_UI);
}
LLPipeline::sUseOcclusion = use_occlusion;
+ LLPipeline::sRenderingHUDs = FALSE;
}
gGL.matrixMode(LLRender::MM_PROJECTION);
gGL.popMatrix();
@@ -1178,7 +1241,6 @@ static LLFastTimer::DeclareTimer FTM_SWAP("Swap");
void render_ui(F32 zoom_factor, int subfield)
{
- LLMemType mt_ru(LLMemType::MTYPE_DISPLAY_RENDER_UI);
LLGLState::checkStates();
glh::matrix4f saved_view = glh_get_current_modelview();
@@ -1393,7 +1455,7 @@ void render_ui_2d()
gGL.pushMatrix();
S32 half_width = (gViewerWindow->getWorldViewWidthScaled() / 2);
S32 half_height = (gViewerWindow->getWorldViewHeightScaled() / 2);
- gGL.scalef(LLUI::sGLScaleFactor.mV[0], LLUI::sGLScaleFactor.mV[1], 1.f);
+ gGL.scalef(LLUI::getScaleFactor().mV[0], LLUI::getScaleFactor().mV[1], 1.f);
gGL.translatef((F32)half_width, (F32)half_height, 0.f);
F32 zoom = gAgentCamera.mHUDCurZoom;
gGL.scalef(zoom,zoom,1.f);
@@ -1431,10 +1493,10 @@ void render_ui_2d()
LLUI::sDirtyRect = last_rect;
last_rect = t_rect;
- last_rect.mLeft = LLRect::tCoordType(last_rect.mLeft / LLUI::sGLScaleFactor.mV[0]);
- last_rect.mRight = LLRect::tCoordType(last_rect.mRight / LLUI::sGLScaleFactor.mV[0]);
- last_rect.mTop = LLRect::tCoordType(last_rect.mTop / LLUI::sGLScaleFactor.mV[1]);
- last_rect.mBottom = LLRect::tCoordType(last_rect.mBottom / LLUI::sGLScaleFactor.mV[1]);
+ last_rect.mLeft = LLRect::tCoordType(last_rect.mLeft / LLUI::getScaleFactor().mV[0]);
+ last_rect.mRight = LLRect::tCoordType(last_rect.mRight / LLUI::getScaleFactor().mV[0]);
+ last_rect.mTop = LLRect::tCoordType(last_rect.mTop / LLUI::getScaleFactor().mV[1]);
+ last_rect.mBottom = LLRect::tCoordType(last_rect.mBottom / LLUI::getScaleFactor().mV[1]);
LLRect clip_rect(last_rect);
@@ -1561,3 +1623,4 @@ void display_cleanup()
{
gDisconnectedImagep = NULL;
}
+
diff --git a/indra/newview/llviewerdisplay.h b/indra/newview/llviewerdisplay.h
index f6467d7f93..f6467d7f93 100644..100755
--- a/indra/newview/llviewerdisplay.h
+++ b/indra/newview/llviewerdisplay.h
diff --git a/indra/newview/llviewerdisplayname.cpp b/indra/newview/llviewerdisplayname.cpp
index 5741fab29a..f81206ffec 100644..100755
--- a/indra/newview/llviewerdisplayname.cpp
+++ b/indra/newview/llviewerdisplayname.cpp
@@ -53,14 +53,17 @@ namespace LLViewerDisplayName
sNameChangedSignal.connect(cb);
}
+ void doNothing() { }
}
class LLSetDisplayNameResponder : public LLHTTPClient::Responder
{
public:
// only care about errors
- /*virtual*/ void error(U32 status, const std::string& reason)
+ /*virtual*/ void errorWithContent(U32 status, const std::string& reason, const LLSD& content)
{
+ llwarns << "LLSetDisplayNameResponder error [status:"
+ << status << "]: " << content << llendl;
LLViewerDisplayName::sSetDisplayNameSignal(false, "", LLSD());
LLViewerDisplayName::sSetDisplayNameSignal.disconnect_all_slots();
}
@@ -97,7 +100,7 @@ void LLViewerDisplayName::set(const std::string& display_name, const set_name_sl
// People API expects array of [ "old value", "new value" ]
LLSD change_array = LLSD::emptyArray();
- change_array.append(av_name.mDisplayName);
+ change_array.append(av_name.getDisplayName());
change_array.append(display_name);
llinfos << "Set name POST to " << cap_url << llendl;
@@ -139,9 +142,9 @@ public:
LLUUID agent_id = gAgent.getID();
// Flush stale data
LLAvatarNameCache::erase( agent_id );
- // Queue request for new data
- LLAvatarName ignored;
- LLAvatarNameCache::get( agent_id, &ignored );
+ // Queue request for new data: nothing to do on callback though...
+ // Note: no need to disconnect the callback as it never gets out of scope
+ LLAvatarNameCache::get(agent_id, boost::bind(&LLViewerDisplayName::doNothing));
// Kill name tag, as it is wrong
LLVOAvatar::invalidateNameTag( agent_id );
}
@@ -189,8 +192,8 @@ class LLDisplayNameUpdate : public LLHTTPNode
LLSD args;
args["OLD_NAME"] = old_display_name;
- args["SLID"] = av_name.mUsername;
- args["NEW_NAME"] = av_name.mDisplayName;
+ args["SLID"] = av_name.getUserName();
+ args["NEW_NAME"] = av_name.getDisplayName();
LLNotificationsUtil::add("DisplayNameUpdate", args);
if (agent_id == gAgent.getID())
{
diff --git a/indra/newview/llviewerdisplayname.h b/indra/newview/llviewerdisplayname.h
index 16d59ae43b..16d59ae43b 100644..100755
--- a/indra/newview/llviewerdisplayname.h
+++ b/indra/newview/llviewerdisplayname.h
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index 356c79a036..3d0eb0c6e7 100644..100755
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -30,9 +30,8 @@
#include "llfloaterreg.h"
#include "llviewerfloaterreg.h"
-
+#include "llfloaterautoreplacesettings.h"
#include "llcompilequeue.h"
-#include "llcallfloater.h"
#include "llfasttimerview.h"
#include "llfloaterabout.h"
#include "llfloaterauction.h"
@@ -50,6 +49,9 @@
#include "llfloaterbump.h"
#include "llfloaterbvhpreview.h"
#include "llfloatercamera.h"
+#include "llfloaterchatvoicevolume.h"
+#include "llfloaterconversationlog.h"
+#include "llfloaterconversationpreview.h"
#include "llfloaterdeleteenvpreset.h"
#include "llfloaterdisplayname.h"
#include "llfloatereditdaycycle.h"
@@ -69,7 +71,7 @@
#include "llfloatermediasettings.h"
#include "llfloaterhud.h"
#include "llfloaterimagepreview.h"
-#include "llimfloater.h"
+#include "llfloaterimsession.h"
#include "llfloaterinspect.h"
#include "llfloaterinventory.h"
#include "llfloaterjoystick.h"
@@ -78,12 +80,14 @@
#include "llfloaterlandholdings.h"
#include "llfloatermap.h"
#include "llfloatermemleak.h"
-#include "llfloatermodelwizard.h"
#include "llfloaternamedesc.h"
#include "llfloaternotificationsconsole.h"
#include "llfloaterobjectweights.h"
#include "llfloateropenobject.h"
#include "llfloateroutbox.h"
+#include "llfloaterpathfindingcharacters.h"
+#include "llfloaterpathfindinglinksets.h"
+#include "llfloaterpathfindingconsole.h"
#include "llfloaterpay.h"
#include "llfloaterperms.h"
#include "llfloaterpostprocess.h"
@@ -99,10 +103,13 @@
#include "llfloatersettingsdebug.h"
#include "llfloatersidepanelcontainer.h"
#include "llfloatersnapshot.h"
+#include "llfloatersocial.h"
#include "llfloatersounddevices.h"
+#include "llfloaterspellchecksettings.h"
#include "llfloatertelehub.h"
#include "llfloatertestinspectors.h"
#include "llfloatertestlistview.h"
+#include "llfloatertexturefetchdebugger.h"
#include "llfloatertools.h"
#include "llfloatertos.h"
#include "llfloatertopobjects.h"
@@ -110,17 +117,18 @@
#include "llfloatertranslationsettings.h"
#include "llfloateruipreview.h"
#include "llfloatervoiceeffect.h"
+#include "llfloatervoicevolume.h"
#include "llfloaterwhitelistentry.h"
#include "llfloaterwindowsize.h"
#include "llfloaterworldmap.h"
-#include "llimfloatercontainer.h"
+#include "llfloaterimcontainer.h"
#include "llinspectavatar.h"
#include "llinspectgroup.h"
#include "llinspectobject.h"
#include "llinspectremoteobject.h"
#include "llinspecttoast.h"
#include "llmoveview.h"
-#include "llnearbychat.h"
+#include "llfloaterimnearbychat.h"
#include "llpanelblockedlist.h"
#include "llpanelclassified.h"
#include "llpreviewanim.h"
@@ -133,7 +141,6 @@
#include "llscriptfloater.h"
#include "llfloatermodelpreview.h"
#include "llcommandhandler.h"
-#include "llnearbychatbar.h"
// *NOTE: Please add files in alphabetical order to keep merges easy.
@@ -186,9 +193,10 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("bumps", "floater_bumps.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterBump>);
LLFloaterReg::add("camera", "floater_camera.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCamera>);
- LLFloaterReg::add("chat_bar", "floater_chat_bar.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLNearbyChatBar>);
-
+ LLFloaterReg::add("chat_voice", "floater_voice_chat_volume.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterChatVoiceVolume>);
+ LLFloaterReg::add("nearby_chat", "floater_im_session.xml", (LLFloaterBuildFunc)&LLFloaterIMNearbyChat::buildFloater);
LLFloaterReg::add("compile_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCompileQueue>);
+ LLFloaterReg::add("conversation", "floater_conversation_log.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterConversationLog>);
LLFloaterReg::add("destinations", "floater_destinations.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterDestinations>);
@@ -210,8 +218,8 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("help_browser", "floater_help_browser.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterHelpBrowser>);
LLFloaterReg::add("hud", "floater_hud.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterHUD>);
- LLFloaterReg::add("impanel", "floater_im_session.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLIMFloater>);
- LLFloaterReg::add("im_container", "floater_im_container.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLIMFloaterContainer>);
+ LLFloaterReg::add("impanel", "floater_im_session.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterIMSession>);
+ LLFloaterReg::add("im_container", "floater_im_container.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterIMContainer>);
LLFloaterReg::add("im_well_window", "floater_sys_well.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLIMWellWindow>);
LLFloaterReg::add("incoming_call", "floater_incoming_call.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLIncomingCallDialog>);
LLFloaterReg::add("inventory", "floater_my_inventory.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSidePanelContainer>);
@@ -220,6 +228,7 @@ void LLViewerFloaterReg::registerFloaters()
LLInspectGroupUtil::registerFloater();
LLInspectObjectUtil::registerFloater();
LLInspectRemoteObjectUtil::registerFloater();
+ LLFloaterVoiceVolumeUtil::registerFloater();
LLNotificationsUI::registerFloater();
LLFloaterDisplayNameUtil::registerFloater();
@@ -227,6 +236,11 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("land_holdings", "floater_land_holdings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterLandHoldings>);
LLFloaterReg::add("mem_leaking", "floater_mem_leaking.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMemLeak>);
+
+ if(gSavedSettings.getBOOL("TextureFetchDebuggerEnabled"))
+ {
+ LLFloaterReg::add("tex_fetch_debugger", "floater_texture_fetch_debugger.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterTextureFetchDebugger>);
+ }
LLFloaterReg::add("media_settings", "floater_media_settings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMediaSettings>);
LLFloaterReg::add("message_critical", "floater_critical.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterTOS>);
LLFloaterReg::add("message_tos", "floater_tos.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterTOS>);
@@ -243,16 +257,23 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("outgoing_call", "floater_outgoing_call.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLOutgoingCallDialog>);
LLFloaterPayUtil::registerFloater();
+ LLFloaterReg::add("pathfinding_characters", "floater_pathfinding_characters.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPathfindingCharacters>);
+ LLFloaterReg::add("pathfinding_linksets", "floater_pathfinding_linksets.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPathfindingLinksets>);
+ LLFloaterReg::add("pathfinding_console", "floater_pathfinding_console.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPathfindingConsole>);
LLFloaterReg::add("people", "floater_people.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSidePanelContainer>);
LLFloaterReg::add("perms_default", "floater_perms_default.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPermsDefault>);
LLFloaterReg::add("places", "floater_places.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSidePanelContainer>);
LLFloaterReg::add("preferences", "floater_preferences.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPreference>);
LLFloaterReg::add("prefs_proxy", "floater_preferences_proxy.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPreferenceProxy>);
LLFloaterReg::add("prefs_hardware_settings", "floater_hardware_settings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterHardwareSettings>);
+ LLFloaterReg::add("prefs_spellchecker_import", "floater_spellcheck_import.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSpellCheckerImport>);
LLFloaterReg::add("prefs_translation", "floater_translation_settings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterTranslationSettings>);
+ LLFloaterReg::add("prefs_spellchecker", "floater_spellcheck.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSpellCheckerSettings>);
+ LLFloaterReg::add("prefs_autoreplace", "floater_autoreplace.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAutoReplaceSettings>);
LLFloaterReg::add("picks", "floater_picks.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSidePanelContainer>);
LLFloaterReg::add("pref_joystick", "floater_joystick.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterJoystick>);
LLFloaterReg::add("preview_anim", "floater_preview_animation.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLPreviewAnim>, "preview");
+ LLFloaterReg::add("preview_conversation", "floater_conversation_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterConversationPreview>);
LLFloaterReg::add("preview_gesture", "floater_preview_gesture.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLPreviewGesture>, "preview");
LLFloaterReg::add("preview_notecard", "floater_preview_notecard.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLPreviewNotecard>, "preview");
LLFloaterReg::add("preview_script", "floater_script_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLPreviewLSL>, "preview");
@@ -283,6 +304,7 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("sell_land", "floater_sell_land.xml", &LLFloaterSellLand::buildFloater);
LLFloaterReg::add("settings_debug", "floater_settings_debug.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSettingsDebug>);
LLFloaterReg::add("sound_devices", "floater_sound_devices.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSoundDevices>);
+ LLFloaterReg::add("social", "floater_social.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSocial>);
LLFloaterReg::add("stats", "floater_stats.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloater>);
LLFloaterReg::add("start_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterRunQueue>);
LLFloaterReg::add("stop_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterNotRunQueue>);
@@ -291,18 +313,16 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("my_profile", "floater_my_web_profile.xml", (LLFloaterBuildFunc)&LLFloaterWebProfile::create);
LLFloaterReg::add("profile", "floater_web_profile.xml", (LLFloaterBuildFunc)&LLFloaterWebProfile::create);
LLFloaterReg::add("how_to", "floater_how_to.xml", (LLFloaterBuildFunc)&LLFloaterWebContent::create);
-
+ LLFloaterReg::add("fbc_web", "floater_fbc_web.xml", (LLFloaterBuildFunc)&LLFloaterWebContent::create);
LLFloaterUIPreviewUtil::registerFloater();
LLFloaterReg::add("upload_anim_bvh", "floater_animation_bvh_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterBvhPreview>, "upload");
LLFloaterReg::add("upload_anim_anim", "floater_animation_anim_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAnimPreview>, "upload");
LLFloaterReg::add("upload_image", "floater_image_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterImagePreview>, "upload");
LLFloaterReg::add("upload_model", "floater_model_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterModelPreview>, "upload");
- LLFloaterReg::add("upload_model_wizard", "floater_model_wizard.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterModelWizard>);
LLFloaterReg::add("upload_script", "floater_script_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterScriptPreview>, "upload");
LLFloaterReg::add("upload_sound", "floater_sound_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSoundPreview>, "upload");
- LLFloaterReg::add("voice_controls", "floater_voice_controls.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLCallFloater>);
LLFloaterReg::add("voice_effect", "floater_voice_effect.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterVoiceEffect>);
LLFloaterReg::add("web_content", "floater_web_content.xml", (LLFloaterBuildFunc)&LLFloaterWebContent::create);
diff --git a/indra/newview/llviewerfloaterreg.h b/indra/newview/llviewerfloaterreg.h
index 8a827a003e..8a827a003e 100644..100755
--- a/indra/newview/llviewerfloaterreg.h
+++ b/indra/newview/llviewerfloaterreg.h
diff --git a/indra/newview/llviewerfoldertype.h b/indra/newview/llviewerfoldertype.h
index 13d5a8fbbd..13d5a8fbbd 100644..100755
--- a/indra/newview/llviewerfoldertype.h
+++ b/indra/newview/llviewerfoldertype.h
diff --git a/indra/newview/llviewergenericmessage.cpp b/indra/newview/llviewergenericmessage.cpp
index f8a2be14d4..f8a2be14d4 100644..100755
--- a/indra/newview/llviewergenericmessage.cpp
+++ b/indra/newview/llviewergenericmessage.cpp
diff --git a/indra/newview/llviewergenericmessage.h b/indra/newview/llviewergenericmessage.h
index 9d451ec0bc..9d451ec0bc 100644..100755
--- a/indra/newview/llviewergenericmessage.h
+++ b/indra/newview/llviewergenericmessage.h
diff --git a/indra/newview/llviewergesture.cpp b/indra/newview/llviewergesture.cpp
index a32a78cbf9..3f35a5001d 100644..100755
--- a/indra/newview/llviewergesture.cpp
+++ b/indra/newview/llviewergesture.cpp
@@ -33,6 +33,7 @@
#include "llviewerinventory.h"
#include "sound_ids.h" // for testing
+#include "llfloaterreg.h"
#include "llkeyboard.h" // for key shortcuts for testing
#include "llinventorymodel.h"
#include "llvoavatar.h"
@@ -40,7 +41,7 @@
#include "llviewermessage.h" // send_guid_sound_trigger
#include "llviewernetwork.h"
#include "llagent.h"
-#include "llnearbychatbar.h"
+#include "llfloaterimnearbychat.h"
// Globals
LLViewerGestureList gGestureList;
@@ -130,7 +131,8 @@ void LLViewerGesture::doTrigger( BOOL send_chat )
{
// Don't play nodding animation, since that might not blend
// with the gesture animation.
- LLNearbyChatBar::getInstance()->sendChatFromViewer(mOutputString, CHAT_TYPE_NORMAL, FALSE);
+ (LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat"))->
+ sendChatFromViewer(mOutputString, CHAT_TYPE_NORMAL, FALSE);
}
}
diff --git a/indra/newview/llviewergesture.h b/indra/newview/llviewergesture.h
index 8dba10226b..8dba10226b 100644..100755
--- a/indra/newview/llviewergesture.h
+++ b/indra/newview/llviewergesture.h
diff --git a/indra/newview/llviewerhelp.cpp b/indra/newview/llviewerhelp.cpp
index a8a918f259..04c2e27c9d 100644..100755
--- a/indra/newview/llviewerhelp.cpp
+++ b/indra/newview/llviewerhelp.cpp
@@ -71,12 +71,6 @@ LLHelpHandler gHelpHandler;
std::string LLViewerHelp::getURL(const std::string &topic)
{
- // allow overriding the help server with a local help file
- if( gSavedSettings.getBOOL("HelpUseLocal") )
- {
- return "__local";
- }
-
// if the help topic is empty, use the default topic
std::string help_topic = topic;
if (help_topic.empty())
diff --git a/indra/newview/llviewerhelp.h b/indra/newview/llviewerhelp.h
index a983012e2e..a983012e2e 100644..100755
--- a/indra/newview/llviewerhelp.h
+++ b/indra/newview/llviewerhelp.h
diff --git a/indra/newview/llviewerhelputil.cpp b/indra/newview/llviewerhelputil.cpp
index ef4b955a5e..ef4b955a5e 100644..100755
--- a/indra/newview/llviewerhelputil.cpp
+++ b/indra/newview/llviewerhelputil.cpp
diff --git a/indra/newview/llviewerhelputil.h b/indra/newview/llviewerhelputil.h
index d8f08f3f04..d8f08f3f04 100644..100755
--- a/indra/newview/llviewerhelputil.h
+++ b/indra/newview/llviewerhelputil.h
diff --git a/indra/newview/llviewerhome.cpp b/indra/newview/llviewerhome.cpp
index e4e60b981c..e4e60b981c 100644..100755
--- a/indra/newview/llviewerhome.cpp
+++ b/indra/newview/llviewerhome.cpp
diff --git a/indra/newview/llviewerhome.h b/indra/newview/llviewerhome.h
index 8e0cdc85ec..8e0cdc85ec 100644..100755
--- a/indra/newview/llviewerhome.h
+++ b/indra/newview/llviewerhome.h
diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp
index a7ba150294..fff9821e86 100644..100755
--- a/indra/newview/llviewerinventory.cpp
+++ b/indra/newview/llviewerinventory.cpp
@@ -64,7 +64,11 @@
#include "llavatarnamecache.h"
#include "llavataractions.h"
#include "lllogininstance.h"
-#include "llfloaterperms.h"
+#include "llfavoritesbar.h"
+
+// Two do-nothing ops for use in callbacks.
+void no_op_inventory_func(const LLUUID&) {}
+void no_op() {}
///----------------------------------------------------------------------------
/// Helper class to store special inventory item names and their localized values.
@@ -343,8 +347,8 @@ void LLViewerInventoryItem::cloneViewerItem(LLPointer<LLViewerInventoryItem>& ne
void LLViewerInventoryItem::removeFromServer()
{
- llinfos << "Removing inventory item " << mUUID << " from server."
- << llendl;
+ lldebugs << "Removing inventory item " << mUUID << " from server."
+ << llendl;
LLInventoryModel::LLCategoryUpdate up(mParentUUID, -1);
gInventory.accountForUpdate(up);
@@ -589,7 +593,7 @@ void LLViewerInventoryCategory::copyViewerCategory(const LLViewerInventoryCatego
{
copyCategory(other);
mOwnerID = other->mOwnerID;
- mVersion = other->mVersion;
+ setVersion(other->getVersion());
mDescendentCount = other->mDescendentCount;
mDescendentsRequested = other->mDescendentsRequested;
}
@@ -657,9 +661,19 @@ void LLViewerInventoryCategory::removeFromServer( void )
gAgent.sendReliableMessage();
}
+S32 LLViewerInventoryCategory::getVersion() const
+{
+ return mVersion;
+}
+
+void LLViewerInventoryCategory::setVersion(S32 version)
+{
+ mVersion = version;
+}
+
bool LLViewerInventoryCategory::fetch()
{
- if((VERSION_UNKNOWN == mVersion)
+ if((VERSION_UNKNOWN == getVersion())
&& mDescendentsRequested.hasExpired()) //Expired check prevents multiple downloads.
{
LL_DEBUGS("InventoryFetch") << "Fetching category children: " << mName << ", UUID: " << mUUID << LL_ENDL;
@@ -950,7 +964,7 @@ void LLInventoryCallbackManager::fire(U32 callback_id, const LLUUID& item_id)
}
}
-void WearOnAvatarCallback::fire(const LLUUID& inv_item)
+void rez_attachment_cb(const LLUUID& inv_item, LLViewerJointAttachment *attachmentp)
{
if (inv_item.isNull())
return;
@@ -958,50 +972,11 @@ void WearOnAvatarCallback::fire(const LLUUID& inv_item)
LLViewerInventoryItem *item = gInventory.getItem(inv_item);
if (item)
{
- LLAppearanceMgr::instance().wearItemOnAvatar(inv_item, true, mReplace);
+ rez_attachment(item, attachmentp);
}
}
-void ModifiedCOFCallback::fire(const LLUUID& inv_item)
-{
- LLAppearanceMgr::instance().updateAppearanceFromCOF();
-
- // Start editing the item if previously requested.
- gAgentWearables.editWearableIfRequested(inv_item);
-
- // TODO: camera mode may not be changed if a debug setting is tweaked
- if( gAgentCamera.cameraCustomizeAvatar() )
- {
- // If we're in appearance editing mode, the current tab may need to be refreshed
- LLSidepanelAppearance *panel = dynamic_cast<LLSidepanelAppearance*>(LLFloaterSidePanelContainer::getPanel("appearance"));
- if (panel)
- {
- panel->showDefaultSubpart();
- }
- }
-}
-
-RezAttachmentCallback::RezAttachmentCallback(LLViewerJointAttachment *attachmentp)
-{
- mAttach = attachmentp;
-}
-RezAttachmentCallback::~RezAttachmentCallback()
-{
-}
-
-void RezAttachmentCallback::fire(const LLUUID& inv_item)
-{
- if (inv_item.isNull())
- return;
-
- LLViewerInventoryItem *item = gInventory.getItem(inv_item);
- if (item)
- {
- rez_attachment(item, mAttach);
- }
-}
-
-void ActivateGestureCallback::fire(const LLUUID& inv_item)
+void activate_gesture_cb(const LLUUID& inv_item)
{
if (inv_item.isNull())
return;
@@ -1014,25 +989,7 @@ void ActivateGestureCallback::fire(const LLUUID& inv_item)
LLGestureMgr::instance().activateGesture(inv_item);
}
-void CreateScriptCallback::fire(const LLUUID& inv_item)
-{
- if (inv_item.isNull())
- return;
-
- LLViewerInventoryItem* item = gInventory.getItem(inv_item);
- if (!item) return;
-
- LLPermissions perm = item->getPermissions();
- perm.setMaskEveryone(LLFloaterPerms::getEveryonePerms("Scripts"));
- perm.setMaskGroup(LLFloaterPerms::getGroupPerms("Scripts"));
- item->setPermissions(perm);
-
- item->updateServer(FALSE);
- gInventory.updateItem(item);
- gInventory.notifyObservers();
-}
-
-void CreateGestureCallback::fire(const LLUUID& inv_item)
+void create_gesture_cb(const LLUUID& inv_item)
{
if (inv_item.isNull())
return;
@@ -1041,45 +998,14 @@ void CreateGestureCallback::fire(const LLUUID& inv_item)
LLViewerInventoryItem* item = gInventory.getItem(inv_item);
if (!item) return;
-
- LLPermissions perm = item->getPermissions();
- perm.setMaskEveryone(LLFloaterPerms::getEveryonePerms("Gestures"));
- perm.setMaskGroup(LLFloaterPerms::getGroupPerms("Gestures"));
- item->setPermissions(perm);
-
- item->updateServer(FALSE);
- gInventory.updateItem(item);
- gInventory.notifyObservers();
+ gInventory.updateItem(item);
+ gInventory.notifyObservers();
LLPreviewGesture* preview = LLPreviewGesture::show(inv_item, LLUUID::null);
// Force to be entirely onscreen.
gFloaterView->adjustToFitScreen(preview, FALSE);
}
-void CreateNotecardCallback::fire(const LLUUID& inv_item)
-{
- if (inv_item.isNull())
- return;
-
- LLViewerInventoryItem* item = gInventory.getItem(inv_item);
- if (!item) return;
-
- LLPermissions perm = item->getPermissions();
- perm.setMaskEveryone(LLFloaterPerms::getEveryonePerms("Notecards"));
- perm.setMaskGroup(LLFloaterPerms::getGroupPerms("Notecards"));
- item->setPermissions(perm);
-
- item->updateServer(FALSE);
- gInventory.updateItem(item);
- gInventory.notifyObservers();
-}
-
-void AddFavoriteLandmarkCallback::fire(const LLUUID& inv_item_id)
-{
- if (mTargetLandmarkId.isNull()) return;
-
- gInventory.rearrangeFavoriteLandmarks(inv_item_id, mTargetLandmarkId);
-}
LLInventoryCallbackManager gInventoryCallbacks;
@@ -1206,6 +1132,11 @@ void link_inventory_item(
}
}
+#if 1 // debugging stuff
+ LLViewerInventoryCategory* cat = gInventory.getCategory(parent_id);
+ lldebugs << "cat: " << cat << llendl;
+
+#endif
LLMessageSystem* msg = gMessageSystem;
msg->newMessageFast(_PREHASH_LinkInventoryItem);
msg->nextBlock(_PREHASH_AgentData);
@@ -1329,46 +1260,22 @@ void create_new_item(const std::string& name,
LLViewerAssetType::generateDescriptionFor(asset_type, desc);
next_owner_perm = (next_owner_perm) ? next_owner_perm : PERM_MOVE | PERM_TRANSFER;
- LLPointer<LLInventoryCallback> cb = NULL;
-
- switch (inv_type)
- {
- case LLInventoryType::IT_LSL:
- {
- cb = new CreateScriptCallback();
- next_owner_perm = LLFloaterPerms::getNextOwnerPerms("Scripts");
- break;
- }
-
- case LLInventoryType::IT_GESTURE:
- {
- cb = new CreateGestureCallback();
- next_owner_perm = LLFloaterPerms::getNextOwnerPerms("Gestures");
- break;
- }
-
- case LLInventoryType::IT_NOTECARD:
- {
- cb = new CreateNotecardCallback();
- next_owner_perm = LLFloaterPerms::getNextOwnerPerms("Notecards");
- break;
- }
- default:
- break;
+ if (inv_type == LLInventoryType::IT_GESTURE)
+ {
+ LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(create_gesture_cb);
+ create_inventory_item(gAgent.getID(), gAgent.getSessionID(),
+ parent_id, LLTransactionID::tnull, name, desc, asset_type, inv_type,
+ NOT_WEARABLE, next_owner_perm, cb);
}
-
- create_inventory_item(gAgent.getID(),
- gAgent.getSessionID(),
- parent_id,
- LLTransactionID::tnull,
- name,
- desc,
- asset_type,
- inv_type,
- NOT_WEARABLE,
- next_owner_perm,
- cb);
+ else
+ {
+ LLPointer<LLInventoryCallback> cb = NULL;
+ create_inventory_item(gAgent.getID(), gAgent.getSessionID(),
+ parent_id, LLTransactionID::tnull, name, desc, asset_type, inv_type,
+ NOT_WEARABLE, next_owner_perm, cb);
+ }
+
}
const std::string NEW_LSL_NAME = "New Script"; // *TODO:Translate? (probably not)
@@ -1376,7 +1283,7 @@ const std::string NEW_NOTECARD_NAME = "New Note"; // *TODO:Translate? (probably
const std::string NEW_GESTURE_NAME = "New Gesture"; // *TODO:Translate? (probably not)
// ! REFACTOR ! Really need to refactor this so that it's not a bunch of if-then statements...
-void menu_create_inventory_item(LLFolderView* root, LLFolderBridge *bridge, const LLSD& userdata, const LLUUID& default_parent_uuid)
+void menu_create_inventory_item(LLInventoryPanel* panel, LLFolderBridge *bridge, const LLSD& userdata, const LLUUID& default_parent_uuid)
{
std::string type_name = userdata.asString();
@@ -1400,7 +1307,7 @@ void menu_create_inventory_item(LLFolderView* root, LLFolderBridge *bridge, cons
LLUUID category = gInventory.createNewCategory(parent_id, preferred_type, LLStringUtil::null);
gInventory.notifyObservers();
- root->setSelectionByID(category, TRUE);
+ panel->setSelectionByID(category, TRUE);
}
else if ("lsl" == type_name)
{
@@ -1409,7 +1316,7 @@ void menu_create_inventory_item(LLFolderView* root, LLFolderBridge *bridge, cons
parent_id,
LLAssetType::AT_LSL_TEXT,
LLInventoryType::IT_LSL,
- PERM_MOVE | PERM_TRANSFER); // overridden in create_new_item
+ PERM_MOVE | PERM_TRANSFER);
}
else if ("notecard" == type_name)
{
@@ -1418,7 +1325,7 @@ void menu_create_inventory_item(LLFolderView* root, LLFolderBridge *bridge, cons
parent_id,
LLAssetType::AT_NOTECARD,
LLInventoryType::IT_NOTECARD,
- PERM_ALL); // overridden in create_new_item
+ PERM_ALL);
}
else if ("gesture" == type_name)
{
@@ -1427,7 +1334,7 @@ void menu_create_inventory_item(LLFolderView* root, LLFolderBridge *bridge, cons
parent_id,
LLAssetType::AT_GESTURE,
LLInventoryType::IT_GESTURE,
- PERM_ALL); // overridden in create_new_item
+ PERM_ALL);
}
else
{
@@ -1443,7 +1350,7 @@ void menu_create_inventory_item(LLFolderView* root, LLFolderBridge *bridge, cons
llwarns << "Can't create unrecognized type " << type_name << llendl;
}
}
- root->setNeedsAutoRename(TRUE);
+ panel->getRootFolder()->setNeedsAutoRename(TRUE);
}
LLAssetType::EType LLViewerInventoryItem::getType() const
@@ -1517,336 +1424,16 @@ const std::string& LLViewerInventoryItem::getName() const
return LLInventoryItem::getName();
}
-/**
- * Class to store sorting order of favorites landmarks in a local file. EXT-3985.
- * It replaced previously implemented solution to store sort index in landmark's name as a "<N>@" prefix.
- * Data are stored in user home directory.
- */
-class LLFavoritesOrderStorage : public LLSingleton<LLFavoritesOrderStorage>
- , public LLDestroyClass<LLFavoritesOrderStorage>
-{
- LOG_CLASS(LLFavoritesOrderStorage);
-public:
- /**
- * Sets sort index for specified with LLUUID favorite landmark
- */
- void setSortIndex(const LLUUID& inv_item_id, S32 sort_index);
-
- /**
- * Gets sort index for specified with LLUUID favorite landmark
- */
- S32 getSortIndex(const LLUUID& inv_item_id);
- void removeSortIndex(const LLUUID& inv_item_id);
-
- void getSLURL(const LLUUID& asset_id);
-
- /**
- * Implementation of LLDestroyClass. Calls cleanup() instance method.
- *
- * It is important this callback is called before gInventory is cleaned.
- * For now it is called from LLAppViewer::cleanup() -> LLAppViewer::disconnectViewer(),
- * Inventory is cleaned later from LLAppViewer::cleanup() after LLAppViewer::disconnectViewer() is called.
- * @see cleanup()
- */
- static void destroyClass();
-
- const static S32 NO_INDEX;
-private:
- friend class LLSingleton<LLFavoritesOrderStorage>;
- LLFavoritesOrderStorage() : mIsDirty(false) { load(); }
- ~LLFavoritesOrderStorage() { save(); }
-
- /**
- * Removes sort indexes for items which are not in Favorites bar for now.
- */
- void cleanup();
-
- const static std::string SORTING_DATA_FILE_NAME;
-
- void load();
- void save();
-
- void saveFavoritesSLURLs();
-
- // Remove record of current user's favorites from file on disk.
- void removeFavoritesRecordOfUser();
-
- void onLandmarkLoaded(const LLUUID& asset_id, LLLandmark* landmark);
- void storeFavoriteSLURL(const LLUUID& asset_id, std::string& slurl);
-
- typedef std::map<LLUUID, S32> sort_index_map_t;
- sort_index_map_t mSortIndexes;
-
- typedef std::map<LLUUID, std::string> slurls_map_t;
- slurls_map_t mSLURLs;
-
- bool mIsDirty;
-
- struct IsNotInFavorites
- {
- IsNotInFavorites(const LLInventoryModel::item_array_t& items)
- : mFavoriteItems(items)
- {
-
- }
-
- /**
- * Returns true if specified item is not found among inventory items
- */
- bool operator()(const sort_index_map_t::value_type& id_index_pair) const
- {
- LLPointer<LLViewerInventoryItem> item = gInventory.getItem(id_index_pair.first);
- if (item.isNull()) return true;
-
- LLInventoryModel::item_array_t::const_iterator found_it =
- std::find(mFavoriteItems.begin(), mFavoriteItems.end(), item);
-
- return found_it == mFavoriteItems.end();
- }
- private:
- LLInventoryModel::item_array_t mFavoriteItems;
- };
-
-};
-
-const std::string LLFavoritesOrderStorage::SORTING_DATA_FILE_NAME = "landmarks_sorting.xml";
-const S32 LLFavoritesOrderStorage::NO_INDEX = -1;
-
-void LLFavoritesOrderStorage::setSortIndex(const LLUUID& inv_item_id, S32 sort_index)
-{
- mSortIndexes[inv_item_id] = sort_index;
- mIsDirty = true;
-}
-
-S32 LLFavoritesOrderStorage::getSortIndex(const LLUUID& inv_item_id)
-{
- sort_index_map_t::const_iterator it = mSortIndexes.find(inv_item_id);
- if (it != mSortIndexes.end())
- {
- return it->second;
- }
- return NO_INDEX;
-}
-
-void LLFavoritesOrderStorage::removeSortIndex(const LLUUID& inv_item_id)
-{
- mSortIndexes.erase(inv_item_id);
- mIsDirty = true;
-}
-
-void LLFavoritesOrderStorage::getSLURL(const LLUUID& asset_id)
-{
- slurls_map_t::iterator slurl_iter = mSLURLs.find(asset_id);
- if (slurl_iter != mSLURLs.end()) return; // SLURL for current landmark is already cached
-
- LLLandmark* lm = gLandmarkList.getAsset(asset_id,
- boost::bind(&LLFavoritesOrderStorage::onLandmarkLoaded, this, asset_id, _1));
- if (lm)
- {
- onLandmarkLoaded(asset_id, lm);
- }
-}
-
-// static
-void LLFavoritesOrderStorage::destroyClass()
-{
- LLFavoritesOrderStorage::instance().cleanup();
- if (gSavedPerAccountSettings.getBOOL("ShowFavoritesOnLogin"))
- {
- LLFavoritesOrderStorage::instance().saveFavoritesSLURLs();
- }
- else
- {
- LLFavoritesOrderStorage::instance().removeFavoritesRecordOfUser();
- }
-}
-
-void LLFavoritesOrderStorage::load()
-{
- // load per-resident sorting information
- std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, SORTING_DATA_FILE_NAME);
-
- LLSD settings_llsd;
- llifstream file;
- file.open(filename);
- if (file.is_open())
- {
- LLSDSerialize::fromXML(settings_llsd, file);
- }
-
- for (LLSD::map_const_iterator iter = settings_llsd.beginMap();
- iter != settings_llsd.endMap(); ++iter)
- {
- mSortIndexes.insert(std::make_pair(LLUUID(iter->first), (S32)iter->second.asInteger()));
- }
-}
-
-void LLFavoritesOrderStorage::saveFavoritesSLURLs()
-{
- // Do not change the file if we are not logged in yet.
- if (!LLLoginInstance::getInstance()->authSuccess())
- {
- llwarns << "Cannot save favorites: not logged in" << llendl;
- return;
- }
-
- std::string user_dir = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "");
- if (user_dir.empty())
- {
- llwarns << "Cannot save favorites: empty user dir name" << llendl;
- return;
- }
-
- std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "stored_favorites.xml");
- llifstream in_file;
- in_file.open(filename);
- LLSD fav_llsd;
- if (in_file.is_open())
- {
- LLSDSerialize::fromXML(fav_llsd, in_file);
- }
-
- const LLUUID fav_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
- LLInventoryModel::cat_array_t cats;
- LLInventoryModel::item_array_t items;
- gInventory.collectDescendents(fav_id, cats, items, LLInventoryModel::EXCLUDE_TRASH);
-
- LLSD user_llsd;
- for (LLInventoryModel::item_array_t::iterator it = items.begin(); it != items.end(); it++)
- {
- LLSD value;
- value["name"] = (*it)->getName();
- value["asset_id"] = (*it)->getAssetUUID();
-
- slurls_map_t::iterator slurl_iter = mSLURLs.find(value["asset_id"]);
- if (slurl_iter != mSLURLs.end())
- {
- lldebugs << "Saving favorite: idx=" << (*it)->getSortField() << ", SLURL=" << slurl_iter->second << ", value=" << value << llendl;
- value["slurl"] = slurl_iter->second;
- user_llsd[(*it)->getSortField()] = value;
- }
- else
- {
- llwarns << "Not saving favorite " << value["name"] << ": no matching SLURL" << llendl;
- }
- }
-
- LLAvatarName av_name;
- LLAvatarNameCache::get( gAgentID, &av_name );
- lldebugs << "Saved favorites for " << av_name.getLegacyName() << llendl;
- fav_llsd[av_name.getLegacyName()] = user_llsd;
-
- llofstream file;
- file.open(filename);
- LLSDSerialize::toPrettyXML(fav_llsd, file);
-}
-
-void LLFavoritesOrderStorage::removeFavoritesRecordOfUser()
-{
- std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "stored_favorites.xml");
- LLSD fav_llsd;
- llifstream file;
- file.open(filename);
- if (!file.is_open()) return;
- LLSDSerialize::fromXML(fav_llsd, file);
-
- LLAvatarName av_name;
- LLAvatarNameCache::get( gAgentID, &av_name );
- lldebugs << "Removed favorites for " << av_name.getLegacyName() << llendl;
- if (fav_llsd.has(av_name.getLegacyName()))
- {
- fav_llsd.erase(av_name.getLegacyName());
- }
-
- llofstream out_file;
- out_file.open(filename);
- LLSDSerialize::toPrettyXML(fav_llsd, out_file);
-
-}
-
-void LLFavoritesOrderStorage::onLandmarkLoaded(const LLUUID& asset_id, LLLandmark* landmark)
-{
- if (!landmark) return;
-
- LLVector3d pos_global;
- if (!landmark->getGlobalPos(pos_global))
- {
- // If global position was unknown on first getGlobalPos() call
- // it should be set for the subsequent calls.
- landmark->getGlobalPos(pos_global);
- }
-
- if (!pos_global.isExactlyZero())
- {
- LLLandmarkActions::getSLURLfromPosGlobal(pos_global,
- boost::bind(&LLFavoritesOrderStorage::storeFavoriteSLURL, this, asset_id, _1));
- }
-}
-
-void LLFavoritesOrderStorage::storeFavoriteSLURL(const LLUUID& asset_id, std::string& slurl)
-{
- lldebugs << "Saving landmark SLURL: " << slurl << llendl;
- mSLURLs[asset_id] = slurl;
-}
-
-void LLFavoritesOrderStorage::save()
-{
- // nothing to save if clean
- if (!mIsDirty) return;
-
- // If we quit from the login screen we will not have an SL account
- // name. Don't try to save, otherwise we'll dump a file in
- // C:\Program Files\SecondLife\ or similar. JC
- std::string user_dir = gDirUtilp->getLindenUserDir();
- if (!user_dir.empty())
- {
- std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, SORTING_DATA_FILE_NAME);
- LLSD settings_llsd;
-
- for(sort_index_map_t::const_iterator iter = mSortIndexes.begin(); iter != mSortIndexes.end(); ++iter)
- {
- settings_llsd[iter->first.asString()] = iter->second;
- }
-
- llofstream file;
- file.open(filename);
- LLSDSerialize::toPrettyXML(settings_llsd, file);
- }
-}
-
-void LLFavoritesOrderStorage::cleanup()
-{
- // nothing to clean
- if (!mIsDirty) return;
-
- const LLUUID fav_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
- LLInventoryModel::cat_array_t cats;
- LLInventoryModel::item_array_t items;
- gInventory.collectDescendents(fav_id, cats, items, LLInventoryModel::EXCLUDE_TRASH);
-
- IsNotInFavorites is_not_in_fav(items);
-
- sort_index_map_t aTempMap;
- //copy unremoved values from mSortIndexes to aTempMap
- std::remove_copy_if(mSortIndexes.begin(), mSortIndexes.end(),
- inserter(aTempMap, aTempMap.begin()),
- is_not_in_fav);
-
- //Swap the contents of mSortIndexes and aTempMap
- mSortIndexes.swap(aTempMap);
-}
-
-
S32 LLViewerInventoryItem::getSortField() const
{
return LLFavoritesOrderStorage::instance().getSortIndex(mUUID);
}
-void LLViewerInventoryItem::setSortField(S32 sortField)
-{
- LLFavoritesOrderStorage::instance().setSortIndex(mUUID, sortField);
- getSLURL();
-}
+//void LLViewerInventoryItem::setSortField(S32 sortField)
+//{
+// LLFavoritesOrderStorage::instance().setSortIndex(mUUID, sortField);
+// getSLURL();
+//}
void LLViewerInventoryItem::getSLURL()
{
diff --git a/indra/newview/llviewerinventory.h b/indra/newview/llviewerinventory.h
index a88a5d31be..ab19a12014 100644..100755
--- a/indra/newview/llviewerinventory.h
+++ b/indra/newview/llviewerinventory.h
@@ -34,6 +34,7 @@
#include <boost/signals2.hpp> // boost::signals2::trackable
+class LLInventoryPanel;
class LLFolderView;
class LLFolderBridge;
class LLViewerInventoryCategory;
@@ -61,7 +62,7 @@ public:
virtual const LLUUID& getProtectedAssetUUID() const; // returns LLUUID::null if current agent does not have permission to expose this asset's UUID to the user
virtual const std::string& getName() const;
virtual S32 getSortField() const;
- virtual void setSortField(S32 sortField);
+ //virtual void setSortField(S32 sortField);
virtual void getSLURL(); //Caches SLURL for landmark. //*TODO: Find a better way to do it and remove this method from here.
virtual const LLPermissions& getPermissions() const;
virtual const bool getIsFullPerm() const; // 'fullperm' in the popular sense: modify-ok & copy-ok & transfer-ok, no special god rules applied
@@ -205,13 +206,13 @@ public:
// Version handling
enum { VERSION_UNKNOWN = -1, VERSION_INITIAL = 1 };
- S32 getVersion() const { return mVersion; }
- void setVersion(S32 version) { mVersion = version; }
+ S32 getVersion() const;
+ void setVersion(S32 version);
// Returns true if a fetch was issued.
bool fetch();
- // used to help make cacheing more robust - for example, if
+ // used to help make caching more robust - for example, if
// someone is getting 4 packets but logs out after 3. the viewer
// may never know the cache is wrong.
enum { DESCENDENT_COUNT_UNKNOWN = -1 };
@@ -219,7 +220,7 @@ public:
void setDescendentCount(S32 descendents) { mDescendentCount = descendents; }
// file handling on the viewer. These are not meant for anything
- // other than cacheing.
+ // other than caching.
bool exportFileLocal(LLFILE* fp) const;
bool importFileLocal(LLFILE* fp);
void determineFolderType();
@@ -242,71 +243,60 @@ public:
virtual void fire(const LLUUID& inv_item) = 0;
};
-class WearOnAvatarCallback : public LLInventoryCallback
-{
-public:
- WearOnAvatarCallback(bool do_replace = false) : mReplace(do_replace) {}
-
- void fire(const LLUUID& inv_item);
+class LLViewerJointAttachment;
-protected:
- bool mReplace;
-};
+void rez_attachment_cb(const LLUUID& inv_item, LLViewerJointAttachment *attachmentp);
-class ModifiedCOFCallback : public LLInventoryCallback
-{
- void fire(const LLUUID& inv_item);
-};
+void activate_gesture_cb(const LLUUID& inv_item);
-class LLViewerJointAttachment;
+void create_gesture_cb(const LLUUID& inv_item);
-class RezAttachmentCallback : public LLInventoryCallback
+class AddFavoriteLandmarkCallback : public LLInventoryCallback
{
public:
- RezAttachmentCallback(LLViewerJointAttachment *attachmentp);
+ AddFavoriteLandmarkCallback() : mTargetLandmarkId(LLUUID::null) {}
+ void setTargetLandmarkId(const LLUUID& target_uuid) { mTargetLandmarkId = target_uuid; }
+
+private:
void fire(const LLUUID& inv_item);
-protected:
- ~RezAttachmentCallback();
-
-private:
- LLViewerJointAttachment* mAttach;
+ LLUUID mTargetLandmarkId;
};
-class ActivateGestureCallback : public LLInventoryCallback
-{
-public:
- void fire(const LLUUID& inv_item);
-};
+typedef boost::function<void(const LLUUID&)> inventory_func_type;
+void no_op_inventory_func(const LLUUID&); // A do-nothing inventory_func
-class CreateScriptCallback : public LLInventoryCallback
-{
-public:
- void fire(const LLUUID& inv_item);
-};
+typedef boost::function<void()> nullary_func_type;
+void no_op(); // A do-nothing nullary func.
-class CreateGestureCallback : public LLInventoryCallback
+// Shim between inventory callback and boost function/callable
+class LLBoostFuncInventoryCallback: public LLInventoryCallback
{
public:
- void fire(const LLUUID& inv_item);
-};
-class CreateNotecardCallback : public LLInventoryCallback
+ LLBoostFuncInventoryCallback(inventory_func_type fire_func,
+ nullary_func_type destroy_func = no_op):
+ mFireFunc(fire_func),
+ mDestroyFunc(destroy_func)
+ {
+ }
+
+ // virtual
+ void fire(const LLUUID& item_id)
{
-public:
- void fire(const LLUUID& inv_item);
-};
+ mFireFunc(item_id);
+ }
-class AddFavoriteLandmarkCallback : public LLInventoryCallback
+ // virtual
+ ~LLBoostFuncInventoryCallback()
{
-public:
- AddFavoriteLandmarkCallback() : mTargetLandmarkId(LLUUID::null) {}
- void setTargetLandmarkId(const LLUUID& target_uuid) { mTargetLandmarkId = target_uuid; }
+ mDestroyFunc();
+ }
+
private:
- void fire(const LLUUID& inv_item);
-
- LLUUID mTargetLandmarkId;
+ inventory_func_type mFireFunc;
+ nullary_func_type mDestroyFunc;
};
// misc functions
@@ -384,7 +374,7 @@ void copy_inventory_from_notecard(const LLUUID& destination_id,
U32 callback_id = 0);
-void menu_create_inventory_item(LLFolderView* root,
+void menu_create_inventory_item(LLInventoryPanel* root,
LLFolderBridge* bridge,
const LLSD& userdata,
const LLUUID& default_parent_uuid = LLUUID::null);
diff --git a/indra/newview/llviewerjoint.cpp b/indra/newview/llviewerjoint.cpp
index a907f102f8..e46299f9d2 100644..100755
--- a/indra/newview/llviewerjoint.cpp
+++ b/indra/newview/llviewerjoint.cpp
@@ -35,50 +35,26 @@
#include "llrender.h"
#include "llmath.h"
#include "llglheaders.h"
-#include "llrendersphere.h"
#include "llvoavatar.h"
#include "pipeline.h"
-#define DEFAULT_LOD 0.0f
-
-const S32 MIN_PIXEL_AREA_3PASS_HAIR = 64*64;
-
-//-----------------------------------------------------------------------------
-// Static Data
-//-----------------------------------------------------------------------------
-BOOL LLViewerJoint::sDisableLOD = FALSE;
+static const S32 MIN_PIXEL_AREA_3PASS_HAIR = 64*64;
//-----------------------------------------------------------------------------
// LLViewerJoint()
-// Class Constructor
+// Class Constructors
//-----------------------------------------------------------------------------
-LLViewerJoint::LLViewerJoint()
- : LLJoint()
-{
- init();
-}
+LLViewerJoint::LLViewerJoint() :
+ LLAvatarJoint()
+{ }
+LLViewerJoint::LLViewerJoint(const std::string &name, LLJoint *parent) :
+ LLAvatarJoint(name, parent)
+{ }
-//-----------------------------------------------------------------------------
-// LLViewerJoint()
-// Class Constructor
-//-----------------------------------------------------------------------------
-LLViewerJoint::LLViewerJoint(const std::string &name, LLJoint *parent)
- : LLJoint(name, parent)
-{
- init();
-}
-
-
-void LLViewerJoint::init()
-{
- mValid = FALSE;
- mComponents = SC_JOINT | SC_BONE | SC_AXES;
- mMinPixelArea = DEFAULT_LOD;
- mPickName = PN_DEFAULT;
- mVisible = TRUE;
- mMeshID = 0;
-}
+LLViewerJoint::LLViewerJoint(S32 joint_num) :
+ LLAvatarJoint(joint_num)
+{ }
//-----------------------------------------------------------------------------
@@ -89,154 +65,6 @@ LLViewerJoint::~LLViewerJoint()
{
}
-
-//--------------------------------------------------------------------
-// setValid()
-//--------------------------------------------------------------------
-void LLViewerJoint::setValid( BOOL valid, BOOL recursive )
-{
- //----------------------------------------------------------------
- // set visibility for this joint
- //----------------------------------------------------------------
- mValid = valid;
-
- //----------------------------------------------------------------
- // set visibility for children
- //----------------------------------------------------------------
- if (recursive)
- {
- for (child_list_t::iterator iter = mChildren.begin();
- iter != mChildren.end(); ++iter)
- {
- LLViewerJoint* joint = (LLViewerJoint*)(*iter);
- joint->setValid(valid, TRUE);
- }
- }
-
-}
-
-//--------------------------------------------------------------------
-// renderSkeleton()
-// DEBUG (UNUSED)
-//--------------------------------------------------------------------
-// void LLViewerJoint::renderSkeleton(BOOL recursive)
-// {
-// F32 nc = 0.57735f;
-
-// //----------------------------------------------------------------
-// // push matrix stack
-// //----------------------------------------------------------------
-// gGL.pushMatrix();
-
-// //----------------------------------------------------------------
-// // render the bone to my parent
-// //----------------------------------------------------------------
-// if (mComponents & SC_BONE)
-// {
-// drawBone();
-// }
-
-// //----------------------------------------------------------------
-// // offset to joint position and
-// // rotate to our orientation
-// //----------------------------------------------------------------
-// gGL.loadIdentity();
-// gGL.multMatrix( &getWorldMatrix().mMatrix[0][0] );
-
-// //----------------------------------------------------------------
-// // render joint axes
-// //----------------------------------------------------------------
-// if (mComponents & SC_AXES)
-// {
-// gGL.begin(LLRender::LINES);
-// gGL.color3f( 1.0f, 0.0f, 0.0f );
-// gGL.vertex3f( 0.0f, 0.0f, 0.0f );
-// gGL.vertex3f( 0.1f, 0.0f, 0.0f );
-
-// gGL.color3f( 0.0f, 1.0f, 0.0f );
-// gGL.vertex3f( 0.0f, 0.0f, 0.0f );
-// gGL.vertex3f( 0.0f, 0.1f, 0.0f );
-
-// gGL.color3f( 0.0f, 0.0f, 1.0f );
-// gGL.vertex3f( 0.0f, 0.0f, 0.0f );
-// gGL.vertex3f( 0.0f, 0.0f, 0.1f );
-// gGL.end();
-// }
-
-// //----------------------------------------------------------------
-// // render the joint graphic
-// //----------------------------------------------------------------
-// if (mComponents & SC_JOINT)
-// {
-// gGL.color3f( 1.0f, 1.0f, 0.0f );
-
-// gGL.begin(LLRender::TRIANGLES);
-
-// // joint top half
-// glNormal3f(nc, nc, nc);
-// gGL.vertex3f(0.0f, 0.0f, 0.05f);
-// gGL.vertex3f(0.05f, 0.0f, 0.0f);
-// gGL.vertex3f(0.0f, 0.05f, 0.0f);
-
-// glNormal3f(-nc, nc, nc);
-// gGL.vertex3f(0.0f, 0.0f, 0.05f);
-// gGL.vertex3f(0.0f, 0.05f, 0.0f);
-// gGL.vertex3f(-0.05f, 0.0f, 0.0f);
-
-// glNormal3f(-nc, -nc, nc);
-// gGL.vertex3f(0.0f, 0.0f, 0.05f);
-// gGL.vertex3f(-0.05f, 0.0f, 0.0f);
-// gGL.vertex3f(0.0f, -0.05f, 0.0f);
-
-// glNormal3f(nc, -nc, nc);
-// gGL.vertex3f(0.0f, 0.0f, 0.05f);
-// gGL.vertex3f(0.0f, -0.05f, 0.0f);
-// gGL.vertex3f(0.05f, 0.0f, 0.0f);
-
-// // joint bottom half
-// glNormal3f(nc, nc, -nc);
-// gGL.vertex3f(0.0f, 0.0f, -0.05f);
-// gGL.vertex3f(0.0f, 0.05f, 0.0f);
-// gGL.vertex3f(0.05f, 0.0f, 0.0f);
-
-// glNormal3f(-nc, nc, -nc);
-// gGL.vertex3f(0.0f, 0.0f, -0.05f);
-// gGL.vertex3f(-0.05f, 0.0f, 0.0f);
-// gGL.vertex3f(0.0f, 0.05f, 0.0f);
-
-// glNormal3f(-nc, -nc, -nc);
-// gGL.vertex3f(0.0f, 0.0f, -0.05f);
-// gGL.vertex3f(0.0f, -0.05f, 0.0f);
-// gGL.vertex3f(-0.05f, 0.0f, 0.0f);
-
-// glNormal3f(nc, -nc, -nc);
-// gGL.vertex3f(0.0f, 0.0f, -0.05f);
-// gGL.vertex3f(0.05f, 0.0f, 0.0f);
-// gGL.vertex3f(0.0f, -0.05f, 0.0f);
-
-// gGL.end();
-// }
-
-// //----------------------------------------------------------------
-// // render children
-// //----------------------------------------------------------------
-// if (recursive)
-// {
-// for (child_list_t::iterator iter = mChildren.begin();
-// iter != mChildren.end(); ++iter)
-// {
-// LLViewerJoint* joint = (LLViewerJoint*)(*iter);
-// joint->renderSkeleton();
-// }
-// }
-
-// //----------------------------------------------------------------
-// // pop matrix stack
-// //----------------------------------------------------------------
-// gGL.popMatrix();
-// }
-
-
//--------------------------------------------------------------------
// render()
//--------------------------------------------------------------------
@@ -317,13 +145,13 @@ U32 LLViewerJoint::render( F32 pixelArea, BOOL first_pass, BOOL is_dummy )
for (child_list_t::iterator iter = mChildren.begin();
iter != mChildren.end(); ++iter)
{
- LLViewerJoint* joint = (LLViewerJoint*)(*iter);
+ LLAvatarJoint* joint = dynamic_cast<LLAvatarJoint*>(*iter);
F32 jointLOD = joint->getLOD();
if (pixelArea >= jointLOD || sDisableLOD)
{
triangle_count += joint->render( pixelArea, TRUE, is_dummy );
- if (jointLOD != DEFAULT_LOD)
+ if (jointLOD != DEFAULT_AVATAR_JOINT_LOD)
{
break;
}
@@ -333,72 +161,6 @@ U32 LLViewerJoint::render( F32 pixelArea, BOOL first_pass, BOOL is_dummy )
return triangle_count;
}
-
-//--------------------------------------------------------------------
-// drawBone()
-// DEBUG (UNUSED)
-//--------------------------------------------------------------------
-// void LLViewerJoint::drawBone()
-// {
-// if ( mParent == NULL )
-// return;
-
-// F32 boneSize = 0.02f;
-
-// // rotate to point to child (bone direction)
-// gGL.pushMatrix();
-
-// LLVector3 boneX = getPosition();
-// F32 length = boneX.normVec();
-
-// LLVector3 boneZ(1.0f, 0.0f, 1.0f);
-
-// LLVector3 boneY = boneZ % boneX;
-// boneY.normVec();
-
-// boneZ = boneX % boneY;
-
-// LLMatrix4 rotateMat;
-// rotateMat.setFwdRow( boneX );
-// rotateMat.setLeftRow( boneY );
-// rotateMat.setUpRow( boneZ );
-// gGL.multMatrix( &rotateMat.mMatrix[0][0] );
-
-// // render the bone
-// gGL.color3f( 0.5f, 0.5f, 0.0f );
-
-// gGL.begin(LLRender::TRIANGLES);
-
-// gGL.vertex3f( length, 0.0f, 0.0f);
-// gGL.vertex3f( 0.0f, boneSize, 0.0f);
-// gGL.vertex3f( 0.0f, 0.0f, boneSize);
-
-// gGL.vertex3f( length, 0.0f, 0.0f);
-// gGL.vertex3f( 0.0f, 0.0f, -boneSize);
-// gGL.vertex3f( 0.0f, boneSize, 0.0f);
-
-// gGL.vertex3f( length, 0.0f, 0.0f);
-// gGL.vertex3f( 0.0f, -boneSize, 0.0f);
-// gGL.vertex3f( 0.0f, 0.0f, -boneSize);
-
-// gGL.vertex3f( length, 0.0f, 0.0f);
-// gGL.vertex3f( 0.0f, 0.0f, boneSize);
-// gGL.vertex3f( 0.0f, -boneSize, 0.0f);
-
-// gGL.end();
-
-// // restore matrix
-// gGL.popMatrix();
-// }
-
-//--------------------------------------------------------------------
-// isTransparent()
-//--------------------------------------------------------------------
-BOOL LLViewerJoint::isTransparent()
-{
- return FALSE;
-}
-
//--------------------------------------------------------------------
// drawShape()
//--------------------------------------------------------------------
@@ -407,213 +169,4 @@ U32 LLViewerJoint::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy )
return 0;
}
-//--------------------------------------------------------------------
-// setSkeletonComponents()
-//--------------------------------------------------------------------
-void LLViewerJoint::setSkeletonComponents( U32 comp, BOOL recursive )
-{
- mComponents = comp;
- if (recursive)
- {
- for (child_list_t::iterator iter = mChildren.begin();
- iter != mChildren.end(); ++iter)
- {
- LLViewerJoint* joint = (LLViewerJoint*)(*iter);
- joint->setSkeletonComponents(comp, recursive);
- }
- }
-}
-
-void LLViewerJoint::updateFaceSizes(U32 &num_vertices, U32& num_indices, F32 pixel_area)
-{
- for (child_list_t::iterator iter = mChildren.begin();
- iter != mChildren.end(); ++iter)
- {
- LLViewerJoint* joint = (LLViewerJoint*)(*iter);
- joint->updateFaceSizes(num_vertices, num_indices, pixel_area);
- }
-}
-
-void LLViewerJoint::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind, bool terse_update)
-{
- for (child_list_t::iterator iter = mChildren.begin();
- iter != mChildren.end(); ++iter)
- {
- LLViewerJoint* joint = (LLViewerJoint*)(*iter);
- joint->updateFaceData(face, pixel_area, damp_wind, terse_update);
- }
-}
-
-void LLViewerJoint::updateJointGeometry()
-{
- for (child_list_t::iterator iter = mChildren.begin();
- iter != mChildren.end(); ++iter)
- {
- LLViewerJoint* joint = (LLViewerJoint*)(*iter);
- joint->updateJointGeometry();
- }
-}
-
-
-BOOL LLViewerJoint::updateLOD(F32 pixel_area, BOOL activate)
-{
- BOOL lod_changed = FALSE;
- BOOL found_lod = FALSE;
-
- for (child_list_t::iterator iter = mChildren.begin();
- iter != mChildren.end(); ++iter)
- {
- LLViewerJoint* joint = (LLViewerJoint*)(*iter);
- F32 jointLOD = joint->getLOD();
-
- if (found_lod || jointLOD == DEFAULT_LOD)
- {
- // we've already found a joint to enable, so enable the rest as alternatives
- lod_changed |= joint->updateLOD(pixel_area, TRUE);
- }
- else
- {
- if (pixel_area >= jointLOD || sDisableLOD)
- {
- lod_changed |= joint->updateLOD(pixel_area, TRUE);
- found_lod = TRUE;
- }
- else
- {
- lod_changed |= joint->updateLOD(pixel_area, FALSE);
- }
- }
- }
- return lod_changed;
-}
-
-void LLViewerJoint::dump()
-{
- for (child_list_t::iterator iter = mChildren.begin();
- iter != mChildren.end(); ++iter)
- {
- LLViewerJoint* joint = (LLViewerJoint*)(*iter);
- joint->dump();
- }
-}
-
-void LLViewerJoint::setVisible(BOOL visible, BOOL recursive)
-{
- mVisible = visible;
-
- if (recursive)
- {
- for (child_list_t::iterator iter = mChildren.begin();
- iter != mChildren.end(); ++iter)
- {
- LLViewerJoint* joint = (LLViewerJoint*)(*iter);
- joint->setVisible(visible, recursive);
- }
- }
-}
-
-
-void LLViewerJoint::setMeshesToChildren()
-{
- removeAllChildren();
- for (std::vector<LLViewerJointMesh*>::iterator iter = mMeshParts.begin();
- iter != mMeshParts.end(); iter++)
- {
- addChild((LLViewerJointMesh *) *iter);
- }
-}
-//-----------------------------------------------------------------------------
-// LLViewerJointCollisionVolume()
-//-----------------------------------------------------------------------------
-
-LLViewerJointCollisionVolume::LLViewerJointCollisionVolume()
-{
- mUpdateXform = FALSE;
-}
-
-LLViewerJointCollisionVolume::LLViewerJointCollisionVolume(const std::string &name, LLJoint *parent) : LLViewerJoint(name, parent)
-{
-
-}
-
-void LLViewerJointCollisionVolume::renderCollision()
-{
- updateWorldMatrix();
-
- gGL.pushMatrix();
- gGL.multMatrix( &mXform.getWorldMatrix().mMatrix[0][0] );
-
- gGL.diffuseColor3f( 0.f, 0.f, 1.f );
-
- gGL.begin(LLRender::LINES);
-
- LLVector3 v[] =
- {
- LLVector3(1,0,0),
- LLVector3(-1,0,0),
- LLVector3(0,1,0),
- LLVector3(0,-1,0),
-
- LLVector3(0,0,-1),
- LLVector3(0,0,1),
- };
-
- //sides
- gGL.vertex3fv(v[0].mV);
- gGL.vertex3fv(v[2].mV);
-
- gGL.vertex3fv(v[0].mV);
- gGL.vertex3fv(v[3].mV);
-
- gGL.vertex3fv(v[1].mV);
- gGL.vertex3fv(v[2].mV);
-
- gGL.vertex3fv(v[1].mV);
- gGL.vertex3fv(v[3].mV);
-
-
- //top
- gGL.vertex3fv(v[0].mV);
- gGL.vertex3fv(v[4].mV);
-
- gGL.vertex3fv(v[1].mV);
- gGL.vertex3fv(v[4].mV);
-
- gGL.vertex3fv(v[2].mV);
- gGL.vertex3fv(v[4].mV);
-
- gGL.vertex3fv(v[3].mV);
- gGL.vertex3fv(v[4].mV);
-
-
- //bottom
- gGL.vertex3fv(v[0].mV);
- gGL.vertex3fv(v[5].mV);
-
- gGL.vertex3fv(v[1].mV);
- gGL.vertex3fv(v[5].mV);
-
- gGL.vertex3fv(v[2].mV);
- gGL.vertex3fv(v[5].mV);
-
- gGL.vertex3fv(v[3].mV);
- gGL.vertex3fv(v[5].mV);
-
- gGL.end();
-
- gGL.popMatrix();
-}
-
-LLVector3 LLViewerJointCollisionVolume::getVolumePos(LLVector3 &offset)
-{
- mUpdateXform = TRUE;
-
- LLVector3 result = offset;
- result.scaleVec(getScale());
- result.rotVec(getWorldRotation());
- result += getWorldPosition();
-
- return result;
-}
-
// End
diff --git a/indra/newview/llviewerjoint.h b/indra/newview/llviewerjoint.h
index 76e3833acb..fd262b6e80 100644..100755
--- a/indra/newview/llviewerjoint.h
+++ b/indra/newview/llviewerjoint.h
@@ -30,7 +30,8 @@
//-----------------------------------------------------------------------------
// Header Files
//-----------------------------------------------------------------------------
-#include "lljoint.h"
+#include "llavatarjoint.h"
+#include "lljointpickname.h"
class LLFace;
class LLViewerJointMesh;
@@ -39,124 +40,25 @@ class LLViewerJointMesh;
// class LLViewerJoint
//-----------------------------------------------------------------------------
class LLViewerJoint :
- public LLJoint
+ public virtual LLAvatarJoint
{
public:
LLViewerJoint();
+ LLViewerJoint(S32 joint_num);
+ // *TODO: Only used for LLVOAvatarSelf::mScreenp. *DOES NOT INITIALIZE mResetAfterRestoreOldXform*
LLViewerJoint(const std::string &name, LLJoint *parent = NULL);
virtual ~LLViewerJoint();
- // Gets the validity of this joint
- BOOL getValid() { return mValid; }
-
- // Sets the validity of this joint
- virtual void setValid( BOOL valid, BOOL recursive=FALSE );
-
- // Primarily for debugging and character setup
- // Derived classes may add text/graphic output.
- // Draw skeleton graphic for debugging and character setup
- void renderSkeleton(BOOL recursive=TRUE); // debug only (unused)
-
- // Draws a bone graphic to the parent joint.
- // Derived classes may add text/graphic output.
- // Called by renderSkeleton().
- void drawBone(); // debug only (unused)
-
// Render character hierarchy.
// Traverses the entire joint hierarchy, setting up
// transforms and calling the drawShape().
// Derived classes may add text/graphic output.
virtual U32 render( F32 pixelArea, BOOL first_pass = TRUE, BOOL is_dummy = FALSE ); // Returns triangle count
- // Returns true if this object is transparent.
- // This is used to determine in which order to draw objects.
- virtual BOOL isTransparent();
-
- // Returns true if this object should inherit scale modifiers from its immediate parent
- virtual BOOL inheritScale() { return FALSE; }
-
// Draws the shape attached to a joint.
// Called by render().
virtual U32 drawShape( F32 pixelArea, BOOL first_pass = TRUE, BOOL is_dummy = FALSE );
virtual void drawNormals() {}
-
- enum Components
- {
- SC_BONE = 1,
- SC_JOINT = 2,
- SC_AXES = 4
- };
-
- // Selects which skeleton components to draw
- void setSkeletonComponents( U32 comp, BOOL recursive = TRUE );
-
- // Returns which skeleton components are enables for drawing
- U32 getSkeletonComponents() { return mComponents; }
-
- // Sets the level of detail for this node as a minimum
- // pixel area threshold. If the current pixel area for this
- // object is less than the specified threshold, the node is
- // not traversed. In addition, if a value is specified (not
- // default of 0.0), and the pixel area is larger than the
- // specified minimum, the node is rendered, but no other siblings
- // of this node under the same parent will be.
- F32 getLOD() { return mMinPixelArea; }
- void setLOD( F32 pixelArea ) { mMinPixelArea = pixelArea; }
-
- // Sets the OpenGL selection stack name that is pushed and popped
- // with this joint state. The default value indicates that no name
- // should be pushed/popped.
- enum PickName
- {
- PN_DEFAULT = -1,
- PN_0 = 0,
- PN_1 = 1,
- PN_2 = 2,
- PN_3 = 3,
- PN_4 = 4,
- PN_5 = 5
- };
- void setPickName(PickName name) { mPickName = name; }
- PickName getPickName() { return mPickName; }
-
- virtual void updateFaceSizes(U32 &num_vertices, U32& num_indices, F32 pixel_area);
- virtual void updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind = FALSE, bool terse_update = false);
- virtual BOOL updateLOD(F32 pixel_area, BOOL activate);
- virtual void updateJointGeometry();
- virtual void dump();
-
- void setVisible( BOOL visible, BOOL recursive );
-
- // Takes meshes in mMeshParts and sets each one as a child joint
- void setMeshesToChildren();
-
-public:
- static BOOL sDisableLOD;
- std::vector<LLViewerJointMesh*> mMeshParts;
- void setMeshID( S32 id ) {mMeshID = id;}
-
-protected:
- void init();
-
- BOOL mValid;
- U32 mComponents;
- F32 mMinPixelArea;
- PickName mPickName;
- BOOL mVisible;
- S32 mMeshID;
-};
-
-class LLViewerJointCollisionVolume : public LLViewerJoint
-{
-public:
- LLViewerJointCollisionVolume();
- LLViewerJointCollisionVolume(const std::string &name, LLJoint *parent = NULL);
- virtual ~LLViewerJointCollisionVolume() {};
-
- virtual BOOL inheritScale() { return TRUE; }
-
- void renderCollision();
- LLVector3 getVolumePos(LLVector3 &offset);
};
#endif // LL_LLVIEWERJOINT_H
diff --git a/indra/newview/llviewerjointattachment.cpp b/indra/newview/llviewerjointattachment.cpp
index 4e14824e69..3a04bbed4f 100644..100755
--- a/indra/newview/llviewerjointattachment.cpp
+++ b/indra/newview/llviewerjointattachment.cpp
@@ -127,7 +127,11 @@ void LLViewerJointAttachment::setupDrawable(LLViewerObject *object)
{
for (S32 face_num = 0; face_num < object->mDrawable->getNumFaces(); face_num++)
{
- object->mDrawable->getFace(face_num)->setState(LLFace::HUD_RENDER);
+ LLFace *face = object->mDrawable->getFace(face_num);
+ if (face)
+ {
+ face->setState(LLFace::HUD_RENDER);
+ }
}
}
@@ -146,7 +150,11 @@ void LLViewerJointAttachment::setupDrawable(LLViewerObject *object)
{
for (S32 face_num = 0; face_num < childp->mDrawable->getNumFaces(); face_num++)
{
- childp->mDrawable->getFace(face_num)->setState(LLFace::HUD_RENDER);
+ LLFace * face = childp->mDrawable->getFace(face_num);
+ if (face)
+ {
+ face->setState(LLFace::HUD_RENDER);
+ }
}
}
}
@@ -254,7 +262,11 @@ void LLViewerJointAttachment::removeObject(LLViewerObject *object)
{
for (S32 face_num = 0; face_num < object->mDrawable->getNumFaces(); face_num++)
{
- object->mDrawable->getFace(face_num)->clearState(LLFace::HUD_RENDER);
+ LLFace * face = object->mDrawable->getFace(face_num);
+ if (face)
+ {
+ face->clearState(LLFace::HUD_RENDER);
+ }
}
}
}
@@ -272,7 +284,11 @@ void LLViewerJointAttachment::removeObject(LLViewerObject *object)
{
for (S32 face_num = 0; face_num < childp->mDrawable->getNumFaces(); face_num++)
{
- childp->mDrawable->getFace(face_num)->clearState(LLFace::HUD_RENDER);
+ LLFace * face = childp->mDrawable->getFace(face_num);
+ if (face)
+ {
+ face->clearState(LLFace::HUD_RENDER);
+ }
}
}
}
diff --git a/indra/newview/llviewerjointattachment.h b/indra/newview/llviewerjointattachment.h
index 9addafaee1..9addafaee1 100644..100755
--- a/indra/newview/llviewerjointattachment.h
+++ b/indra/newview/llviewerjointattachment.h
diff --git a/indra/newview/llviewerjointmesh.cpp b/indra/newview/llviewerjointmesh.cpp
index e052e37393..64454a03d1 100644..100755
--- a/indra/newview/llviewerjointmesh.cpp
+++ b/indra/newview/llviewerjointmesh.cpp
@@ -42,7 +42,7 @@
#include "llface.h"
#include "llgldbg.h"
#include "llglheaders.h"
-#include "lltexlayer.h"
+#include "llviewertexlayer.h"
#include "llviewercamera.h"
#include "llviewercontrol.h"
#include "llviewertexturelist.h"
@@ -67,101 +67,20 @@ static const U32 sRenderMask = LLVertexBuffer::MAP_VERTEX |
LLVertexBuffer::MAP_NORMAL |
LLVertexBuffer::MAP_TEXCOORD0;
-
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-// LLViewerJointMesh::LLSkinJoint
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-
-//-----------------------------------------------------------------------------
-// LLSkinJoint
-//-----------------------------------------------------------------------------
-LLSkinJoint::LLSkinJoint()
-{
- mJoint = NULL;
-}
-
-//-----------------------------------------------------------------------------
-// ~LLSkinJoint
-//-----------------------------------------------------------------------------
-LLSkinJoint::~LLSkinJoint()
-{
- mJoint = NULL;
-}
-
-
-//-----------------------------------------------------------------------------
-// LLSkinJoint::setupSkinJoint()
-//-----------------------------------------------------------------------------
-BOOL LLSkinJoint::setupSkinJoint( LLViewerJoint *joint)
-{
- // find the named joint
- mJoint = joint;
- if ( !mJoint )
- {
- llinfos << "Can't find joint" << llendl;
- }
-
- // compute the inverse root skin matrix
- mRootToJointSkinOffset.clearVec();
-
- LLVector3 rootSkinOffset;
- while (joint)
- {
- rootSkinOffset += joint->getSkinOffset();
- joint = (LLViewerJoint*)joint->getParent();
- }
-
- mRootToJointSkinOffset = -rootSkinOffset;
- mRootToParentJointSkinOffset = mRootToJointSkinOffset;
- mRootToParentJointSkinOffset += mJoint->getSkinOffset();
-
- return TRUE;
-}
-
-
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// LLViewerJointMesh
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
-BOOL LLViewerJointMesh::sPipelineRender = FALSE;
-EAvatarRenderPass LLViewerJointMesh::sRenderPass = AVATAR_RENDER_PASS_SINGLE;
-U32 LLViewerJointMesh::sClothingMaskImageName = 0;
-LLColor4 LLViewerJointMesh::sClothingInnerColor;
//-----------------------------------------------------------------------------
// LLViewerJointMesh()
//-----------------------------------------------------------------------------
LLViewerJointMesh::LLViewerJointMesh()
:
- mTexture( NULL ),
- mLayerSet( NULL ),
- mTestImageName( 0 ),
- mFaceIndexCount(0),
- mIsTransparent(FALSE)
+ LLAvatarJointMesh()
{
-
- mColor[0] = 1.0f;
- mColor[1] = 1.0f;
- mColor[2] = 1.0f;
- mColor[3] = 1.0f;
- mShiny = 0.0f;
- mCullBackFaces = TRUE;
-
- mMesh = NULL;
-
- mNumSkinJoints = 0;
- mSkinJoints = NULL;
-
- mFace = NULL;
-
- mMeshID = 0;
- mUpdateXform = FALSE;
-
- mValid = FALSE;
}
@@ -171,199 +90,6 @@ LLViewerJointMesh::LLViewerJointMesh()
//-----------------------------------------------------------------------------
LLViewerJointMesh::~LLViewerJointMesh()
{
- mMesh = NULL;
- mTexture = NULL;
- freeSkinData();
-}
-
-
-//-----------------------------------------------------------------------------
-// LLViewerJointMesh::allocateSkinData()
-//-----------------------------------------------------------------------------
-BOOL LLViewerJointMesh::allocateSkinData( U32 numSkinJoints )
-{
- mSkinJoints = new LLSkinJoint[ numSkinJoints ];
- mNumSkinJoints = numSkinJoints;
- return TRUE;
-}
-
-//-----------------------------------------------------------------------------
-// LLViewerJointMesh::freeSkinData()
-//-----------------------------------------------------------------------------
-void LLViewerJointMesh::freeSkinData()
-{
- mNumSkinJoints = 0;
- delete [] mSkinJoints;
- mSkinJoints = NULL;
-}
-
-//--------------------------------------------------------------------
-// LLViewerJointMesh::getColor()
-//--------------------------------------------------------------------
-void LLViewerJointMesh::getColor( F32 *red, F32 *green, F32 *blue, F32 *alpha )
-{
- *red = mColor[0];
- *green = mColor[1];
- *blue = mColor[2];
- *alpha = mColor[3];
-}
-
-//--------------------------------------------------------------------
-// LLViewerJointMesh::setColor()
-//--------------------------------------------------------------------
-void LLViewerJointMesh::setColor( F32 red, F32 green, F32 blue, F32 alpha )
-{
- mColor[0] = red;
- mColor[1] = green;
- mColor[2] = blue;
- mColor[3] = alpha;
-}
-
-
-//--------------------------------------------------------------------
-// LLViewerJointMesh::getTexture()
-//--------------------------------------------------------------------
-//LLViewerTexture *LLViewerJointMesh::getTexture()
-//{
-// return mTexture;
-//}
-
-//--------------------------------------------------------------------
-// LLViewerJointMesh::setTexture()
-//--------------------------------------------------------------------
-void LLViewerJointMesh::setTexture( LLViewerTexture *texture )
-{
- mTexture = texture;
-
- // texture and dynamic_texture are mutually exclusive
- if( texture )
- {
- mLayerSet = NULL;
- //texture->bindTexture(0);
- //texture->setClamp(TRUE, TRUE);
- }
-}
-
-//--------------------------------------------------------------------
-// LLViewerJointMesh::setLayerSet()
-// Sets the shape texture (takes precedence over normal texture)
-//--------------------------------------------------------------------
-void LLViewerJointMesh::setLayerSet( LLTexLayerSet* layer_set )
-{
- mLayerSet = layer_set;
-
- // texture and dynamic_texture are mutually exclusive
- if( layer_set )
- {
- mTexture = NULL;
- }
-}
-
-
-
-//--------------------------------------------------------------------
-// LLViewerJointMesh::getMesh()
-//--------------------------------------------------------------------
-LLPolyMesh *LLViewerJointMesh::getMesh()
-{
- return mMesh;
-}
-
-//-----------------------------------------------------------------------------
-// LLViewerJointMesh::setMesh()
-//-----------------------------------------------------------------------------
-void LLViewerJointMesh::setMesh( LLPolyMesh *mesh )
-{
- // set the mesh pointer
- mMesh = mesh;
-
- // release any existing skin joints
- freeSkinData();
-
- if ( mMesh == NULL )
- {
- return;
- }
-
- // acquire the transform from the mesh object
- setPosition( mMesh->getPosition() );
- setRotation( mMesh->getRotation() );
- setScale( mMesh->getScale() );
-
- // create skin joints if necessary
- if ( mMesh->hasWeights() && !mMesh->isLOD())
- {
- U32 numJointNames = mMesh->getNumJointNames();
-
- allocateSkinData( numJointNames );
- std::string *jointNames = mMesh->getJointNames();
-
- U32 jn;
- for (jn = 0; jn < numJointNames; jn++)
- {
- //llinfos << "Setting up joint " << jointNames[jn] << llendl;
- LLViewerJoint* joint = (LLViewerJoint*)(getRoot()->findJoint(jointNames[jn]) );
- mSkinJoints[jn].setupSkinJoint( joint );
- }
- }
-
- // setup joint array
- if (!mMesh->isLOD())
- {
- setupJoint((LLViewerJoint*)getRoot());
- }
-
-// llinfos << "joint render entries: " << mMesh->mJointRenderData.count() << llendl;
-}
-
-//-----------------------------------------------------------------------------
-// setupJoint()
-//-----------------------------------------------------------------------------
-void LLViewerJointMesh::setupJoint(LLViewerJoint* current_joint)
-{
-// llinfos << "Mesh: " << getName() << llendl;
-
-// S32 joint_count = 0;
- U32 sj;
- for (sj=0; sj<mNumSkinJoints; sj++)
- {
- LLSkinJoint &js = mSkinJoints[sj];
-
- if (js.mJoint != current_joint)
- {
- continue;
- }
-
- // we've found a skinjoint for this joint..
-
- // is the last joint in the array our parent?
- if(mMesh->mJointRenderData.count() && mMesh->mJointRenderData[mMesh->mJointRenderData.count() - 1]->mWorldMatrix == &current_joint->getParent()->getWorldMatrix())
- {
- // ...then just add ourselves
- LLViewerJoint* jointp = js.mJoint;
- mMesh->mJointRenderData.put(new LLJointRenderData(&jointp->getWorldMatrix(), &js));
-// llinfos << "joint " << joint_count << js.mJoint->getName() << llendl;
-// joint_count++;
- }
- // otherwise add our parent and ourselves
- else
- {
- mMesh->mJointRenderData.put(new LLJointRenderData(&current_joint->getParent()->getWorldMatrix(), NULL));
-// llinfos << "joint " << joint_count << current_joint->getParent()->getName() << llendl;
-// joint_count++;
- mMesh->mJointRenderData.put(new LLJointRenderData(&current_joint->getWorldMatrix(), &js));
-// llinfos << "joint " << joint_count << current_joint->getName() << llendl;
-// joint_count++;
- }
- }
-
- // depth-first traversal
- for (LLJoint::child_list_t::iterator iter = current_joint->mChildren.begin();
- iter != current_joint->mChildren.end(); ++iter)
- {
- LLViewerJoint* child_joint = (LLViewerJoint*)(*iter);
- setupJoint(child_joint);
- }
}
const S32 NUM_AXES = 3;
@@ -475,21 +201,6 @@ void LLViewerJointMesh::uploadJointMatrices()
}
//--------------------------------------------------------------------
-// LLViewerJointMesh::drawBone()
-//--------------------------------------------------------------------
-void LLViewerJointMesh::drawBone()
-{
-}
-
-//--------------------------------------------------------------------
-// LLViewerJointMesh::isTransparent()
-//--------------------------------------------------------------------
-BOOL LLViewerJointMesh::isTransparent()
-{
- return mIsTransparent;
-}
-
-//--------------------------------------------------------------------
// DrawElementsBLEND and utility code
//--------------------------------------------------------------------
@@ -544,6 +255,7 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy)
llassert( !(mTexture.notNull() && mLayerSet) ); // mutually exclusive
LLTexUnit::eTextureAddressMode old_mode = LLTexUnit::TAM_WRAP;
+ LLViewerTexLayerSet *layerset = dynamic_cast<LLViewerTexLayerSet*>(mLayerSet);
if (mTestImageName)
{
gGL.getTexUnit(diffuse_channel)->bindManual(LLTexUnit::TT_TEXTURE, mTestImageName);
@@ -558,11 +270,11 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy)
gGL.getTexUnit(diffuse_channel)->setTextureColorBlend(LLTexUnit::TBO_LERP_TEX_ALPHA, LLTexUnit::TBS_TEX_COLOR, LLTexUnit::TBS_PREV_COLOR);
}
}
- else if( !is_dummy && mLayerSet )
+ else if( !is_dummy && layerset )
{
- if( mLayerSet->hasComposite() )
+ if( layerset->hasComposite() )
{
- gGL.getTexUnit(diffuse_channel)->bind(mLayerSet->getComposite());
+ gGL.getTexUnit(diffuse_channel)->bind(layerset->getViewerComposite());
}
else
{
@@ -576,7 +288,6 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy)
{
old_mode = mTexture->getAddressMode();
}
- gGL.getTexUnit(diffuse_channel)->bind(mTexture.get());
gGL.getTexUnit(diffuse_channel)->bind(mTexture);
gGL.getTexUnit(diffuse_channel)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
}
@@ -730,8 +441,10 @@ void LLViewerJointMesh::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_w
F32* vw = (F32*) vertex_weightsp.get();
F32* cw = (F32*) clothing_weightsp.get();
- LLVector4a::memcpyNonAliased16(tc, (F32*) mMesh->getTexCoords(), num_verts*2*sizeof(F32));
- LLVector4a::memcpyNonAliased16(vw, (F32*) mMesh->getWeights(), num_verts*sizeof(F32));
+ S32 tc_size = (num_verts*2*sizeof(F32)+0xF) & ~0xF;
+ LLVector4a::memcpyNonAliased16(tc, (F32*) mMesh->getTexCoords(), tc_size);
+ S32 vw_size = (num_verts*sizeof(F32)+0xF) & ~0xF;
+ LLVector4a::memcpyNonAliased16(vw, (F32*) mMesh->getWeights(), vw_size);
LLVector4a::memcpyNonAliased16(cw, (F32*) mMesh->getClothingWeights(), num_verts*4*sizeof(F32));
}
diff --git a/indra/newview/llviewerjointmesh.h b/indra/newview/llviewerjointmesh.h
index 0191f0cae8..0db2836e15 100644..100755
--- a/indra/newview/llviewerjointmesh.h
+++ b/indra/newview/llviewerjointmesh.h
@@ -1,6 +1,6 @@
/**
* @file llviewerjointmesh.h
- * @brief Implementation of LLViewerJointMesh class
+ * @brief Declaration of LLViewerJointMesh class
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -29,63 +29,20 @@
#include "llviewerjoint.h"
#include "llviewertexture.h"
+#include "llavatarjointmesh.h"
#include "llpolymesh.h"
#include "v4color.h"
class LLDrawable;
class LLFace;
class LLCharacter;
-class LLTexLayerSet;
-
-typedef enum e_avatar_render_pass
-{
- AVATAR_RENDER_PASS_SINGLE,
- AVATAR_RENDER_PASS_CLOTHING_INNER,
- AVATAR_RENDER_PASS_CLOTHING_OUTER
-} EAvatarRenderPass;
-
-class LLSkinJoint
-{
-public:
- LLSkinJoint();
- ~LLSkinJoint();
- BOOL setupSkinJoint( LLViewerJoint *joint);
-
- LLViewerJoint *mJoint;
- LLVector3 mRootToJointSkinOffset;
- LLVector3 mRootToParentJointSkinOffset;
-};
+class LLViewerTexLayerSet;
//-----------------------------------------------------------------------------
// class LLViewerJointMesh
//-----------------------------------------------------------------------------
-class LLViewerJointMesh : public LLViewerJoint
+class LLViewerJointMesh : public LLAvatarJointMesh, public LLViewerJoint
{
-protected:
- LLColor4 mColor; // color value
-// LLColor4 mSpecular; // specular color (always white for now)
- F32 mShiny; // shiny value
- LLPointer<LLViewerTexture> mTexture; // ptr to a global texture
- LLTexLayerSet* mLayerSet; // ptr to a layer set owned by the avatar
- U32 mTestImageName; // handle to a temporary texture for previewing uploads
- LLPolyMesh* mMesh; // ptr to a global polymesh
- BOOL mCullBackFaces; // true by default
- LLFace* mFace; // ptr to a face w/ AGP copy of mesh
-
- U32 mFaceIndexCount;
- BOOL mIsTransparent;
-
- U32 mNumSkinJoints;
- LLSkinJoint* mSkinJoints;
- S32 mMeshID;
-
-public:
- static BOOL sPipelineRender;
- //RN: this is here for testing purposes
- static U32 sClothingMaskImageName;
- static EAvatarRenderPass sRenderPass;
- static LLColor4 sClothingInnerColor;
-
public:
// Constructor
LLViewerJointMesh();
@@ -93,67 +50,28 @@ public:
// Destructor
virtual ~LLViewerJointMesh();
- // Gets the shape color
- void getColor( F32 *red, F32 *green, F32 *blue, F32 *alpha );
-
- // Sets the shape color
- void setColor( F32 red, F32 green, F32 blue, F32 alpha );
-
- // Sets the shininess
- void setSpecular( const LLColor4& color, F32 shiny ) { /*mSpecular = color;*/ mShiny = shiny; };
-
- // Sets the shape texture
- void setTexture( LLViewerTexture *texture );
-
- void setTestTexture( U32 name ) { mTestImageName = name; }
-
- // Sets layer set responsible for a dynamic shape texture (takes precedence over normal texture)
- void setLayerSet( LLTexLayerSet* layer_set );
-
- // Gets the poly mesh
- LLPolyMesh *getMesh();
-
- // Sets the poly mesh
- void setMesh( LLPolyMesh *mesh );
-
- // Sets up joint matrix data for rendering
- void setupJoint(LLViewerJoint* current_joint);
-
// Render time method to upload batches of joint matrices
void uploadJointMatrices();
- // Sets ID for picking
- void setMeshID( S32 id ) {mMeshID = id;}
-
- // Gets ID for picking
- S32 getMeshID() { return mMeshID; }
-
// overloaded from base class
- /*virtual*/ void drawBone();
- /*virtual*/ BOOL isTransparent();
/*virtual*/ U32 drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy );
+ // necessary because MS's compiler warns on function inheritance via dominance in the diamond inheritance here.
+ // warns even though LLViewerJoint holds the only non virtual implementation.
+ /*virtual*/ U32 render( F32 pixelArea, BOOL first_pass = TRUE, BOOL is_dummy = FALSE ) { return LLViewerJoint::render(pixelArea,first_pass,is_dummy);}
+
/*virtual*/ void updateFaceSizes(U32 &num_vertices, U32& num_indices, F32 pixel_area);
/*virtual*/ void updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind = FALSE, bool terse_update = false);
/*virtual*/ BOOL updateLOD(F32 pixel_area, BOOL activate);
/*virtual*/ void updateJointGeometry();
/*virtual*/ void dump();
- void setIsTransparent(BOOL is_transparent) { mIsTransparent = is_transparent; }
-
/*virtual*/ BOOL isAnimatable() const { return FALSE; }
private:
//copy mesh into given face's vertex buffer, applying current animation pose
static void updateGeometry(LLFace* face, LLPolyMesh* mesh);
-
-private:
- // Allocate skin data
- BOOL allocateSkinData( U32 numSkinJoints );
-
- // Free skin data
- void freeSkinData();
};
#endif // LL_LLVIEWERJOINTMESH_H
diff --git a/indra/newview/llviewerjoystick.cpp b/indra/newview/llviewerjoystick.cpp
index f6e840adcd..aeeb591d55 100644..100755
--- a/indra/newview/llviewerjoystick.cpp
+++ b/indra/newview/llviewerjoystick.cpp
@@ -919,7 +919,7 @@ void LLViewerJoystick::moveFlycam(bool reset)
{
if (i == X_I || i == Y_I || i == Z_I)
{
- static LLCachedControl<F32> build_mode_scale(gSavedSettings,"FlycamBuildModeScale");
+ static LLCachedControl<F32> build_mode_scale(gSavedSettings,"FlycamBuildModeScale", 1.0);
cur_delta[i] *= build_mode_scale;
}
}
diff --git a/indra/newview/llviewerjoystick.h b/indra/newview/llviewerjoystick.h
index 80c758a5af..80c758a5af 100644..100755
--- a/indra/newview/llviewerjoystick.h
+++ b/indra/newview/llviewerjoystick.h
diff --git a/indra/newview/llviewerkeyboard.cpp b/indra/newview/llviewerkeyboard.cpp
index 1aa9fd8a45..aa9de076b8 100644..100755
--- a/indra/newview/llviewerkeyboard.cpp
+++ b/indra/newview/llviewerkeyboard.cpp
@@ -27,11 +27,12 @@
#include "llviewerprecompiledheaders.h"
#include "llappviewer.h"
+#include "llfloaterreg.h"
#include "llviewerkeyboard.h"
#include "llmath.h"
#include "llagent.h"
#include "llagentcamera.h"
-#include "llnearbychatbar.h"
+#include "llfloaterimnearbychat.h"
#include "llviewercontrol.h"
#include "llfocusmgr.h"
#include "llmorphview.h"
@@ -533,8 +534,13 @@ void stop_moving( EKeystate s )
void start_chat( EKeystate s )
{
+ if (LLAppViewer::instance()->quitRequested())
+ {
+ return; // can't talk, gotta go, kthxbye!
+ }
+
// start chat
- LLNearbyChatBar::startChat(NULL);
+ LLFloaterIMNearbyChat::startChat(NULL);
}
void start_gesture( EKeystate s )
@@ -543,15 +549,15 @@ void start_gesture( EKeystate s )
if (KEYSTATE_UP == s &&
! (focus_ctrlp && focus_ctrlp->acceptsTextInput()))
{
- if (LLNearbyChatBar::getInstance()->getCurrentChat().empty())
+ if ((LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat"))->getCurrentChat().empty())
{
// No existing chat in chat editor, insert '/'
- LLNearbyChatBar::startChat("/");
+ LLFloaterIMNearbyChat::startChat("/");
}
else
{
// Don't overwrite existing text in chat editor
- LLNearbyChatBar::startChat(NULL);
+ LLFloaterIMNearbyChat::startChat(NULL);
}
}
}
@@ -675,12 +681,16 @@ BOOL LLViewerKeyboard::handleKey(KEY translated_key, MASK translated_mask, BOOL
if(mKeysSkippedByUI.find(translated_key) != mKeysSkippedByUI.end())
{
mKeyHandledByUI[translated_key] = FALSE;
+ LL_INFOS("Keyboard Handling") << "Key wasn't handled by UI!" << LL_ENDL;
}
else
{
// it is sufficient to set this value once per call to handlekey
// without clearing it, as it is only used in the subsequent call to scanKey
- mKeyHandledByUI[translated_key] = gViewerWindow->handleKey(translated_key, translated_mask);
+ mKeyHandledByUI[translated_key] = gViewerWindow->handleKey(translated_key, translated_mask);
+ // mKeyHandledByUI is not what you think ... this indicates whether the UI has handled this keypress yet (any keypress)
+ // NOT whether some UI shortcut wishes to handle the keypress
+
}
return mKeyHandledByUI[translated_key];
}
diff --git a/indra/newview/llviewerkeyboard.h b/indra/newview/llviewerkeyboard.h
index ca73212ed1..ca73212ed1 100644..100755
--- a/indra/newview/llviewerkeyboard.h
+++ b/indra/newview/llviewerkeyboard.h
diff --git a/indra/newview/llviewerlayer.cpp b/indra/newview/llviewerlayer.cpp
index 1a07251e92..1a07251e92 100644..100755
--- a/indra/newview/llviewerlayer.cpp
+++ b/indra/newview/llviewerlayer.cpp
diff --git a/indra/newview/llviewerlayer.h b/indra/newview/llviewerlayer.h
index f9ec9c0c83..f9ec9c0c83 100644..100755
--- a/indra/newview/llviewerlayer.h
+++ b/indra/newview/llviewerlayer.h
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index 1eb4bedfaf..21fb8d519b 100644..100755
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -316,9 +316,13 @@ public:
/* virtual */ void completedHeader(U32 status, const std::string& reason, const LLSD& content)
{
LL_WARNS("MediaAuth") << "status = " << status << ", reason = " << reason << LL_ENDL;
- LL_WARNS("MediaAuth") << content << LL_ENDL;
+
+ LLSD stripped_content = content;
+ stripped_content.erase("set-cookie");
+ LL_WARNS("MediaAuth") << stripped_content << LL_ENDL;
std::string cookie = content["set-cookie"].asString();
+ LL_DEBUGS("MediaAuth") << "cookie = " << cookie << LL_ENDL;
LLViewerMedia::getCookieStore()->setCookiesFromHost(cookie, mHost);
@@ -1184,12 +1188,9 @@ void LLViewerMedia::clearAllCookies()
LLDirIterator dir_iter(base_dir, "*_*");
while (dir_iter.next(filename))
{
- target = base_dir;
- target += filename;
- target += gDirUtilp->getDirDelimiter();
- target += "browser_profile";
- target += gDirUtilp->getDirDelimiter();
- target += "cookies";
+ target = gDirUtilp->add(base_dir, filename);
+ gDirUtilp->append(target, "browser_profile");
+ gDirUtilp->append(target, "cookies");
lldebugs << "target = " << target << llendl;
if(LLFile::isfile(target))
{
@@ -1197,10 +1198,8 @@ void LLViewerMedia::clearAllCookies()
}
// Other accounts may have new-style cookie files too -- delete them as well
- target = base_dir;
- target += filename;
- target += gDirUtilp->getDirDelimiter();
- target += PLUGIN_COOKIE_FILE_NAME;
+ target = gDirUtilp->add(base_dir, filename);
+ gDirUtilp->append(target, PLUGIN_COOKIE_FILE_NAME);
lldebugs << "target = " << target << llendl;
if(LLFile::isfile(target))
{
@@ -2001,7 +2000,12 @@ void LLViewerMediaImpl::loadURI()
"<>#%"
";/?:@&=",
false);
- llinfos << "Asking media source to load URI: " << uri << llendl;
+ {
+ // Do not log the query parts
+ LLURI u(uri);
+ std::string sanitized_uri = (u.query().empty() ? uri : u.scheme() + "://" + u.authority() + u.path());
+ llinfos << "Asking media source to load URI: " << sanitized_uri << llendl;
+ }
mMediaSource->loadURI( uri );
@@ -2568,7 +2572,12 @@ void LLViewerMediaImpl::navigateTo(const std::string& url, const std::string& mi
if(mPriority == LLPluginClassMedia::PRIORITY_UNLOADED)
{
// Helpful to have media urls in log file. Shouldn't be spammy.
- llinfos << "NOT LOADING media id= " << mTextureId << " url=" << url << " mime_type=" << mime_type << llendl;
+ {
+ // Do not log the query parts
+ LLURI u(url);
+ std::string sanitized_url = (u.query().empty() ? url : u.scheme() + "://" + u.authority() + u.path());
+ llinfos << "NOT LOADING media id= " << mTextureId << " url=" << sanitized_url << ", mime_type=" << mime_type << llendl;
+ }
// This impl should not be loaded at this time.
LL_DEBUGS("PluginPriority") << this << "Not loading (PRIORITY_UNLOADED)" << LL_ENDL;
@@ -2583,7 +2592,12 @@ void LLViewerMediaImpl::navigateTo(const std::string& url, const std::string& mi
void LLViewerMediaImpl::navigateInternal()
{
// Helpful to have media urls in log file. Shouldn't be spammy.
- llinfos << "media id= " << mTextureId << " url=" << mMediaURL << " mime_type=" << mMimeType << llendl;
+ {
+ // Do not log the query parts
+ LLURI u(mMediaURL);
+ std::string sanitized_url = (u.query().empty() ? mMediaURL : u.scheme() + "://" + u.authority() + u.path());
+ llinfos << "media id= " << mTextureId << " url=" << sanitized_url << ", mime_type=" << mMimeType << llendl;
+ }
if(mNavigateSuspended)
{
@@ -3759,18 +3773,18 @@ bool LLViewerMediaImpl::shouldShowBasedOnClass() const
// If it is attached to an avatar and the pref is off, we shouldn't show it
if (attached_to_another_avatar)
{
- static LLCachedControl<bool> show_media_on_others(gSavedSettings, LLViewerMedia::SHOW_MEDIA_ON_OTHERS_SETTING);
+ static LLCachedControl<bool> show_media_on_others(gSavedSettings, LLViewerMedia::SHOW_MEDIA_ON_OTHERS_SETTING, false);
return show_media_on_others;
}
if (inside_parcel)
{
- static LLCachedControl<bool> show_media_within_parcel(gSavedSettings, LLViewerMedia::SHOW_MEDIA_WITHIN_PARCEL_SETTING);
+ static LLCachedControl<bool> show_media_within_parcel(gSavedSettings, LLViewerMedia::SHOW_MEDIA_WITHIN_PARCEL_SETTING, true);
return show_media_within_parcel;
}
else
{
- static LLCachedControl<bool> show_media_outside_parcel(gSavedSettings, LLViewerMedia::SHOW_MEDIA_OUTSIDE_PARCEL_SETTING);
+ static LLCachedControl<bool> show_media_outside_parcel(gSavedSettings, LLViewerMedia::SHOW_MEDIA_OUTSIDE_PARCEL_SETTING, true);
return show_media_outside_parcel;
}
diff --git a/indra/newview/llviewermedia.h b/indra/newview/llviewermedia.h
index fff5b3fc08..fff5b3fc08 100644..100755
--- a/indra/newview/llviewermedia.h
+++ b/indra/newview/llviewermedia.h
diff --git a/indra/newview/llviewermedia_streamingaudio.cpp b/indra/newview/llviewermedia_streamingaudio.cpp
index e2a74e8e3c..e2a74e8e3c 100644..100755
--- a/indra/newview/llviewermedia_streamingaudio.cpp
+++ b/indra/newview/llviewermedia_streamingaudio.cpp
diff --git a/indra/newview/llviewermedia_streamingaudio.h b/indra/newview/llviewermedia_streamingaudio.h
index 1e7f771e17..1e7f771e17 100644..100755
--- a/indra/newview/llviewermedia_streamingaudio.h
+++ b/indra/newview/llviewermedia_streamingaudio.h
diff --git a/indra/newview/llviewermediafocus.cpp b/indra/newview/llviewermediafocus.cpp
index 4543a1ba9a..297906803b 100644..100755
--- a/indra/newview/llviewermediafocus.cpp
+++ b/indra/newview/llviewermediafocus.cpp
@@ -406,11 +406,9 @@ void LLViewerMediaFocus::update()
LLViewerObject *viewer_object = getFocusedObject();
S32 face = mFocusedObjectFace;
LLVector3 normal = mFocusedObjectNormal;
- bool focus = true;
if(!media_impl || !viewer_object)
{
- focus = false;
media_impl = getHoverMediaImpl();
viewer_object = getHoverObject();
face = mHoverObjectFace;
diff --git a/indra/newview/llviewermediafocus.h b/indra/newview/llviewermediafocus.h
index f03dd8751e..f03dd8751e 100644..100755
--- a/indra/newview/llviewermediafocus.h
+++ b/indra/newview/llviewermediafocus.h
diff --git a/indra/newview/llviewermediaobserver.h b/indra/newview/llviewermediaobserver.h
index 5dab7e399e..5dab7e399e 100644..100755
--- a/indra/newview/llviewermediaobserver.h
+++ b/indra/newview/llviewermediaobserver.h
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 7481414b5c..ac2940fcfc 100644..100755
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -40,11 +40,13 @@
#include "llinventorypanel.h"
#include "llnotifications.h"
#include "llnotificationsutil.h"
+#include "llviewereventrecorder.h"
// newview includes
#include "llagent.h"
#include "llagentaccess.h"
#include "llagentcamera.h"
+#include "llagentui.h"
#include "llagentwearables.h"
#include "llagentpilot.h"
#include "llcompilequeue.h"
@@ -52,6 +54,7 @@
#include "lldaycyclemanager.h"
#include "lldebugview.h"
#include "llenvmanager.h"
+#include "llfacebookconnect.h"
#include "llfilepicker.h"
#include "llfirstuse.h"
#include "llfloaterbuy.h"
@@ -59,7 +62,10 @@
#include "llbuycurrencyhtml.h"
#include "llfloatergodtools.h"
#include "llfloaterinventory.h"
+#include "llfloaterimcontainer.h"
#include "llfloaterland.h"
+#include "llfloaterpathfindingcharacters.h"
+#include "llfloaterpathfindinglinksets.h"
#include "llfloaterpay.h"
#include "llfloaterreporter.h"
#include "llfloatersearch.h"
@@ -81,11 +87,13 @@
#include "llinventoryfunctions.h"
#include "llpanellogin.h"
#include "llpanelblockedlist.h"
+#include "llmenuoptionpathfindingrebakenavmesh.h"
#include "llmoveview.h"
#include "llparcel.h"
#include "llrootview.h"
#include "llsceneview.h"
#include "llselectmgr.h"
+#include "llspellcheckmenuhandler.h"
#include "llstatusbar.h"
#include "lltextureview.h"
#include "lltoolcomp.h"
@@ -93,6 +101,7 @@
#include "lltoolpie.h"
#include "lltoolselectland.h"
#include "lltrans.h"
+#include "llviewerdisplay.h" //for gWindowResized
#include "llviewergenericmessage.h"
#include "llviewerhelp.h"
#include "llviewermenufile.h" // init_menu_file()
@@ -102,6 +111,7 @@
#include "llviewerparcelmgr.h"
#include "llviewerstats.h"
#include "llvoavatarself.h"
+#include "llvoicevivox.h"
#include "llworldmap.h"
#include "pipeline.h"
#include "llviewerjoystick.h"
@@ -115,9 +125,10 @@
#include "lleconomy.h"
#include "lltoolgrab.h"
#include "llwindow.h"
+#include "llpathfindingmanager.h"
#include "boost/unordered_map.hpp"
-using namespace LLVOAvatarDefines;
+using namespace LLAvatarAppearanceDefines;
typedef LLPointer<LLViewerObject> LLViewerObjectPtr;
@@ -139,6 +150,8 @@ void handle_test_load_url(void*);
//extern BOOL gDebugAvatarRotation;
extern BOOL gDebugClicks;
extern BOOL gDebugWindowProc;
+extern BOOL gShaderProfileFrame;
+
//extern BOOL gDebugTextEditorTips;
//extern BOOL gDebugSelectMgr;
@@ -159,8 +172,8 @@ LLContextMenu *gMenuObject = NULL;
LLContextMenu *gMenuAttachmentSelf = NULL;
LLContextMenu *gMenuAttachmentOther = NULL;
LLContextMenu *gMenuLand = NULL;
+LLContextMenu *gMenuMuteParticle = NULL;
-const std::string SAVE_INTO_INVENTORY("Save Object Back to My Inventory");
const std::string SAVE_INTO_TASK_INVENTORY("Save Object Back to Object Contents");
LLMenuGL* gAttachSubMenu = NULL;
@@ -173,9 +186,6 @@ LLContextMenu* gDetachPieMenu = NULL;
LLContextMenu* gDetachScreenPieMenu = NULL;
LLContextMenu* gDetachBodyPartPieMenus[8];
-LLMenuItemCallGL* gAFKMenu = NULL;
-LLMenuItemCallGL* gBusyMenu = NULL;
-
//
// Local prototypes
@@ -202,10 +212,9 @@ void near_sit_object();
BOOL is_selection_buy_not_take();
S32 selection_price();
BOOL enable_take();
-void handle_take();
void handle_object_show_inspector();
void handle_avatar_show_inspector();
-bool confirm_take(const LLSD& notification, const LLSD& response);
+bool confirm_take(const LLSD& notification, const LLSD& response, LLObjectSelectionHandle selection_handle);
void handle_buy_object(LLSaleInfo sale_info);
void handle_buy_contents(LLSaleInfo sale_info);
@@ -288,6 +297,7 @@ void request_friendship(const LLUUID& agent_id);
// Tools menu
void handle_selected_texture_info(void*);
+void handle_selected_material_info();
void handle_dump_followcam(void*);
void handle_viewer_enable_message_log(void*);
@@ -299,7 +309,6 @@ BOOL enable_buy_land(void*);
void handle_test_male(void *);
void handle_test_female(void *);
-void handle_toggle_pg(void*);
void handle_dump_attachments(void *);
void handle_dump_avatar_local_textures(void*);
void handle_debug_avatar_textures(void*);
@@ -307,7 +316,6 @@ void handle_grab_baked_texture(void*);
BOOL enable_grab_baked_texture(void*);
void handle_dump_region_object_cache(void*);
-BOOL enable_save_into_inventory(void*);
BOOL enable_save_into_task_inventory(void*);
BOOL enable_detach(const LLSD& = LLSD());
@@ -338,7 +346,8 @@ LLMenuParcelObserver::~LLMenuParcelObserver()
void LLMenuParcelObserver::changed()
{
- gMenuHolder->childSetEnabled("Land Buy Pass", LLPanelLandGeneral::enableBuyPass(NULL));
+ LLParcel *parcel = LLViewerParcelMgr::getInstance()->getParcelSelection()->getParcel();
+ gMenuHolder->childSetEnabled("Land Buy Pass", LLPanelLandGeneral::enableBuyPass(NULL) && !(parcel->getOwnerID()== gAgent.getID()));
BOOL buyable = enable_buy_land(NULL);
gMenuHolder->childSetEnabled("Land Buy", buyable);
@@ -420,6 +429,9 @@ void init_menus()
gMenuLand = LLUICtrlFactory::createFromFile<LLContextMenu>(
"menu_land.xml", gMenuHolder, registry);
+ gMenuMuteParticle = LLUICtrlFactory::createFromFile<LLContextMenu>(
+ "menu_mute_particle.xml", gMenuHolder, registry);
+
///
/// set up the colors
///
@@ -467,8 +479,6 @@ void init_menus()
gMenuHolder->childSetLabelArg("Upload Animation", "[COST]", upload_cost);
gMenuHolder->childSetLabelArg("Bulk Upload", "[COST]", upload_cost);
- gAFKMenu = gMenuBarView->getChild<LLMenuItemCallGL>("Set Away", TRUE);
- gBusyMenu = gMenuBarView->getChild<LLMenuItemCallGL>("Set Busy", TRUE);
gAttachSubMenu = gMenuBarView->findChildMenuByName("Attach Object", TRUE);
gDetachSubMenu = gMenuBarView->findChildMenuByName("Detach Object", TRUE);
@@ -516,14 +526,6 @@ class LLAdvancedToggleConsole : public view_listener_t
{
toggle_visibility( (void*)static_cast<LLUICtrl*>(gDebugView->mDebugConsolep));
}
- else if (gTextureSizeView && "texture size" == console_type)
- {
- toggle_visibility( (void*)gTextureSizeView );
- }
- else if (gTextureCategoryView && "texture category" == console_type)
- {
- toggle_visibility( (void*)gTextureCategoryView );
- }
else if ("fast timers" == console_type)
{
LLFloaterReg::toggleInstance("fast_timers");
@@ -556,14 +558,6 @@ class LLAdvancedCheckConsole : public view_listener_t
{
new_value = get_visibility( (void*)((LLView*)gDebugView->mDebugConsolep) );
}
- else if (gTextureSizeView && "texture size" == console_type)
- {
- new_value = get_visibility( (void*)gTextureSizeView );
- }
- else if (gTextureCategoryView && "texture category" == console_type)
- {
- new_value = get_visibility( (void*)gTextureCategoryView );
- }
else if ("fast timers" == console_type)
{
new_value = LLFloaterReg::instanceVisible("fast_timers");
@@ -866,6 +860,73 @@ class LLAdvancedCheckFeature : public view_listener_t
}
};
+class LLAdvancedCheckDisplayTextureDensity : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ std::string mode = userdata.asString();
+ if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY))
+ {
+ return mode == "none";
+ }
+ if (mode == "current")
+ {
+ return LLViewerTexture::sDebugTexelsMode == LLViewerTexture::DEBUG_TEXELS_CURRENT;
+ }
+ else if (mode == "desired")
+ {
+ return LLViewerTexture::sDebugTexelsMode == LLViewerTexture::DEBUG_TEXELS_DESIRED;
+ }
+ else if (mode == "full")
+ {
+ return LLViewerTexture::sDebugTexelsMode == LLViewerTexture::DEBUG_TEXELS_FULL;
+ }
+ return false;
+ }
+};
+
+class LLAdvancedSetDisplayTextureDensity : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ std::string mode = userdata.asString();
+ if (mode == "none")
+ {
+ if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY) == TRUE)
+ {
+ gPipeline.toggleRenderDebug((void*)LLPipeline::RENDER_DEBUG_TEXEL_DENSITY);
+ }
+ LLViewerTexture::sDebugTexelsMode = LLViewerTexture::DEBUG_TEXELS_OFF;
+ }
+ else if (mode == "current")
+ {
+ if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY) == FALSE)
+ {
+ gPipeline.toggleRenderDebug((void*)LLPipeline::RENDER_DEBUG_TEXEL_DENSITY);
+ }
+ LLViewerTexture::sDebugTexelsMode = LLViewerTexture::DEBUG_TEXELS_CURRENT;
+ }
+ else if (mode == "desired")
+ {
+ if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY) == FALSE)
+ {
+ gPipeline.toggleRenderDebug((void*)LLPipeline::RENDER_DEBUG_TEXEL_DENSITY);
+ }
+ gPipeline.setRenderDebugFeatureControl(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY, true);
+ LLViewerTexture::sDebugTexelsMode = LLViewerTexture::DEBUG_TEXELS_DESIRED;
+ }
+ else if (mode == "full")
+ {
+ if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY) == FALSE)
+ {
+ gPipeline.toggleRenderDebug((void*)LLPipeline::RENDER_DEBUG_TEXEL_DENSITY);
+ }
+ LLViewerTexture::sDebugTexelsMode = LLViewerTexture::DEBUG_TEXELS_FULL;
+ }
+ return true;
+ }
+};
+
//////////////////
// INFO DISPLAY //
@@ -980,6 +1041,10 @@ U32 info_display_from_string(std::string info_display)
{
return LLPipeline::RENDER_DEBUG_WIND_VECTORS;
}
+ else if ("texel density" == info_display)
+ {
+ return LLPipeline::RENDER_DEBUG_TEXEL_DENSITY;
+ }
else
{
return 0;
@@ -1011,8 +1076,6 @@ class LLAdvancedCheckInfoDisplay : public view_listener_t
U32 info_display = info_display_from_string( userdata.asString() );
bool new_value = false;
- LL_INFOS("ViewerMenu") << "check " << userdata.asString() << LL_ENDL;
-
if ( info_display != 0 )
{
new_value = LLPipeline::toggleRenderDebugControl( (void*)info_display );
@@ -1118,6 +1181,7 @@ class LLAdvancedToggleWireframe : public view_listener_t
bool handleEvent(const LLSD& userdata)
{
gUseWireframe = !(gUseWireframe);
+ gWindowResized = TRUE;
LLPipeline::updateRenderDeferred();
gPipeline.resetVertexBuffers();
return true;
@@ -1133,28 +1197,6 @@ class LLAdvancedCheckWireframe : public view_listener_t
}
};
-//////////////////////
-// TEXTURE ATLAS //
-//////////////////////
-
-class LLAdvancedToggleTextureAtlas : public view_listener_t
-{
- bool handleEvent(const LLSD& userdata)
- {
- LLViewerTexture::sUseTextureAtlas = !LLViewerTexture::sUseTextureAtlas;
- gSavedSettings.setBOOL("EnableTextureAtlas", LLViewerTexture::sUseTextureAtlas) ;
- return true;
- }
-};
-
-class LLAdvancedCheckTextureAtlas : public view_listener_t
-{
- bool handleEvent(const LLSD& userdata)
- {
- bool new_value = LLViewerTexture::sUseTextureAtlas; // <-- make this using LLCacheControl
- return new_value;
- }
-};
//////////////////////////
// DUMP SCRIPTED CAMERA //
@@ -1257,22 +1299,6 @@ class LLAdvancedPrintAgentInfo : public view_listener_t
}
};
-
-
-////////////////////////////////
-// PRINT TEXTURE MEMORY STATS //
-////////////////////////////////
-
-
-class LLAdvancedPrintTextureMemoryStats : public view_listener_t
-{
- bool handleEvent(const LLSD& userdata)
- {
- output_statistics(NULL);
- return true;
- }
-};
-
//////////////////
// DEBUG CLICKS //
//////////////////
@@ -1537,11 +1563,26 @@ class LLAdvancedEnableGrabBakedTexture : public view_listener_t
///////////////////////
+class LLAdvancedEnableAppearanceToXML : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ return gSavedSettings.getBOOL("DebugAvatarAppearanceMessage");
+ }
+};
+
class LLAdvancedAppearanceToXML : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
{
- LLVOAvatar::dumpArchetypeXML(NULL);
+ std::string emptyname;
+ LLVOAvatar* avatar =
+ find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() );
+ if (!avatar)
+ {
+ avatar = gAgentAvatarp;
+ }
+ avatar->dumpArchetypeXML(emptyname);
return true;
}
};
@@ -1586,32 +1627,63 @@ class LLAdvancedTestFemale : public view_listener_t
}
};
+class LLAdvancedForceParamsToDefault : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLAgent::clearVisualParams(NULL);
+ return true;
+ }
+};
-///////////////
-// TOGGLE PG //
-///////////////
+//////////////////////////
+// ANIMATION SPEED //
+//////////////////////////
+// Utility function to set all AV time factors to the same global value
+static void set_all_animation_time_factors(F32 time_factor)
+{
+ LLMotionController::setCurrentTimeFactor(time_factor);
+ for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
+ iter != LLCharacter::sInstances.end(); ++iter)
+ {
+ (*iter)->setAnimTimeFactor(time_factor);
+ }
+}
-class LLAdvancedTogglePG : public view_listener_t
+class LLAdvancedAnimTenFaster : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
{
- handle_toggle_pg(NULL);
+ //llinfos << "LLAdvancedAnimTenFaster" << llendl;
+ F32 time_factor = LLMotionController::getCurrentTimeFactor();
+ time_factor = llmin(time_factor + 0.1f, 2.f); // Upper limit is 200% speed
+ set_all_animation_time_factors(time_factor);
return true;
}
};
-
-class LLAdvancedForceParamsToDefault : public view_listener_t
+class LLAdvancedAnimTenSlower : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
{
- LLAgent::clearVisualParams(NULL);
+ //llinfos << "LLAdvancedAnimTenSlower" << llendl;
+ F32 time_factor = LLMotionController::getCurrentTimeFactor();
+ time_factor = llmax(time_factor - 0.1f, 0.1f); // Lower limit is at 10% of normal speed
+ set_all_animation_time_factors(time_factor);
return true;
}
};
+class LLAdvancedAnimResetAll : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ set_all_animation_time_factors(1.f);
+ return true;
+ }
+};
//////////////////////////
@@ -1883,6 +1955,43 @@ class LLAdvancedDropPacket : public view_listener_t
};
+////////////////////
+// EVENT Recorder //
+///////////////////
+
+
+class LLAdvancedViewerEventRecorder : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ std::string command = userdata.asString();
+ if ("start playback" == command)
+ {
+ llinfos << "Event Playback starting" << llendl;
+ LLViewerEventRecorder::instance().playbackRecording();
+ llinfos << "Event Playback completed" << llendl;
+ }
+ else if ("stop playback" == command)
+ {
+ // Future
+ }
+ else if ("start recording" == command)
+ {
+ LLViewerEventRecorder::instance().setEventLoggingOn();
+ llinfos << "Event recording started" << llendl;
+ }
+ else if ("stop recording" == command)
+ {
+ LLViewerEventRecorder::instance().setEventLoggingOff();
+ llinfos << "Event recording stopped" << llendl;
+ }
+
+ return true;
+ }
+};
+
+
+
/////////////////
// AGENT PILOT //
@@ -1982,7 +2091,6 @@ class LLAdvancedCompressImage : public view_listener_t
};
-
/////////////////////////
// SHOW DEBUG SETTINGS //
/////////////////////////
@@ -2245,6 +2353,14 @@ class LLDevelopSetLoggingLevel : public view_listener_t
}
};
+class LLDevelopTextureFetchDebugger : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ return gSavedSettings.getBOOL("TextureFetchDebuggerEnabled");
+ }
+};
+
//////////////////
// ADMIN MENU //
//////////////////
@@ -2376,6 +2492,9 @@ void cleanup_menus()
delete gMenuLand;
gMenuLand = NULL;
+ delete gMenuMuteParticle;
+ gMenuMuteParticle = NULL;
+
delete gMenuBarView;
gMenuBarView = NULL;
@@ -2729,17 +2848,34 @@ bool enable_object_edit()
return enable;
}
+bool enable_mute_particle()
+{
+ const LLPickInfo& pick = LLToolPie::getInstance()->getPick();
+
+ return pick.mParticleOwnerID != LLUUID::null && pick.mParticleOwnerID != gAgent.getID();
+}
+
// mutually exclusive - show either edit option or build in menu
bool enable_object_build()
{
return !enable_object_edit();
}
+bool enable_object_select_in_pathfinding_linksets()
+{
+ return LLPathfindingManager::getInstance()->isPathfindingEnabledForCurrentRegion() && LLSelectMgr::getInstance()->selectGetEditableLinksets();
+}
+
+bool enable_object_select_in_pathfinding_characters()
+{
+ return LLPathfindingManager::getInstance()->isPathfindingEnabledForCurrentRegion() && LLSelectMgr::getInstance()->selectGetViewableCharacters();
+}
+
class LLSelfRemoveAllAttachments : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
{
- LLAgentWearables::userRemoveAllAttachments();
+ LLAppearanceMgr::instance().removeAllAttachmentsFromAvatar();
return true;
}
};
@@ -2832,6 +2968,67 @@ bool enable_object_unmute()
}
}
+
+// 0 = normal, 1 = always, 2 = never
+class LLAvatarCheckImpostorMode : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
+ if (!object) return false;
+
+ LLVOAvatar* avatar = find_avatar_from_object(object);
+ if (!avatar) return false;
+
+ U32 mode = userdata.asInteger();
+ switch (mode)
+ {
+ case 0:
+ return (avatar->getVisualMuteSettings() == LLVOAvatar::VISUAL_MUTE_NOT_SET);
+ case 1:
+ return (avatar->getVisualMuteSettings() == LLVOAvatar::ALWAYS_VISUAL_MUTE);
+ case 2:
+ return (avatar->getVisualMuteSettings() == LLVOAvatar::NEVER_VISUAL_MUTE);
+ default:
+ return false;
+ }
+ } // handleEvent()
+};
+
+// 0 = normal, 1 = always, 2 = never
+class LLAvatarSetImpostorMode : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
+ if (!object) return false;
+
+ LLVOAvatar* avatar = find_avatar_from_object(object);
+ if (!avatar) return false;
+
+ U32 mode = userdata.asInteger();
+ switch (mode)
+ {
+ case 0:
+ avatar->setVisualMuteSettings(LLVOAvatar::VISUAL_MUTE_NOT_SET);
+ break;
+ case 1:
+ avatar->setVisualMuteSettings(LLVOAvatar::ALWAYS_VISUAL_MUTE);
+ break;
+ case 2:
+ avatar->setVisualMuteSettings(LLVOAvatar::NEVER_VISUAL_MUTE);
+ break;
+ default:
+ return false;
+ }
+
+ avatar->forceUpdateVisualMuteSettings();
+ LLVOAvatar::cullAvatarsByPixelArea();
+ return true;
+ } // handleEvent()
+};
+
+
class LLObjectMute : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
@@ -3204,15 +3401,6 @@ bool enable_freeze_eject(const LLSD& avatar_id)
return new_value;
}
-
-void login_done(S32 which, void *user)
-{
- llinfos << "Login done " << which << llendl;
-
- LLPanelLogin::closePanel();
-}
-
-
bool callback_leave_group(const LLSD& notification, const LLSD& response)
{
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
@@ -3256,7 +3444,7 @@ void append_aggregate(std::string& string, const LLAggregatePermissions& ag_perm
bool enable_buy_object()
{
// In order to buy, there must only be 1 purchaseable object in
- // the selection manger.
+ // the selection manager.
if(LLSelectMgr::getInstance()->getSelection()->getRootObjectCount() != 1) return false;
LLViewerObject* obj = NULL;
LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode();
@@ -3404,6 +3592,20 @@ bool enable_sitdown_self()
return isAgentAvatarValid() && !gAgentAvatarp->isSitting() && !gAgent.getFlying();
}
+class LLCheckPanelPeopleTab : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ std::string panel_name = userdata.asString();
+
+ LLPanel *panel = LLFloaterSidePanelContainer::getPanel("people", panel_name);
+ if(panel && panel->isInVisibleChain())
+ {
+ return true;
+ }
+ return false;
+ }
+};
// Toggle one of "People" panel tabs in side tray.
class LLTogglePanelPeopleTab : public view_listener_t
{
@@ -3416,7 +3618,8 @@ class LLTogglePanelPeopleTab : public view_listener_t
if ( panel_name == "friends_panel"
|| panel_name == "groups_panel"
- || panel_name == "nearby_panel")
+ || panel_name == "nearby_panel"
+ || panel_name == "blocked_panel")
{
return togglePeoplePanel(panel_name, param);
}
@@ -3852,25 +4055,27 @@ class LLViewToggleUI : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
{
- LLNotification::Params params("ConfirmHideUI");
- params.functor.function(boost::bind(&LLViewToggleUI::confirm, this, _1, _2));
- LLSD substitutions;
+ if(gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK)
+ {
+ LLNotification::Params params("ConfirmHideUI");
+ params.functor.function(boost::bind(&LLViewToggleUI::confirm, this, _1, _2));
+ LLSD substitutions;
#if LL_DARWIN
- substitutions["SHORTCUT"] = "Cmd+Shift+U";
+ substitutions["SHORTCUT"] = "Cmd+Shift+U";
#else
- substitutions["SHORTCUT"] = "Ctrl+Shift+U";
+ substitutions["SHORTCUT"] = "Ctrl+Shift+U";
#endif
- params.substitutions = substitutions;
- if (gViewerWindow->getUIVisibility())
- {
- // hiding, so show notification
- LLNotifications::instance().add(params);
- }
- else
- {
- LLNotifications::instance().forceResponse(params, 0);
+ params.substitutions = substitutions;
+ if (!gSavedSettings.getBOOL("HideUIControls"))
+ {
+ // hiding, so show notification
+ LLNotifications::instance().add(params);
+ }
+ else
+ {
+ LLNotifications::instance().forceResponse(params, 0);
+ }
}
-
return true;
}
@@ -3880,7 +4085,9 @@ class LLViewToggleUI : public view_listener_t
if (option == 0) // OK
{
- gViewerWindow->setUIVisibility(!gViewerWindow->getUIVisibility());
+ gViewerWindow->setUIVisibility(gSavedSettings.getBOOL("HideUIControls"));
+ LLPanelStandStopFlying::getInstance()->setVisible(gSavedSettings.getBOOL("HideUIControls"));
+ gSavedSettings.setBOOL("HideUIControls",!gSavedSettings.getBOOL("HideUIControls"));
}
}
};
@@ -4134,8 +4341,9 @@ static bool get_derezzable_objects(
{
case DRD_TAKE_INTO_AGENT_INVENTORY:
case DRD_TRASH:
- if( (node->mPermissions->allowTransferTo(gAgent.getID()) && object->permModify())
- || (node->allowOperationOnNode(PERM_OWNER, GP_OBJECT_MANIPULATE)) )
+ if (!object->isPermanentEnforced() &&
+ ((node->mPermissions->allowTransferTo(gAgent.getID()) && object->permModify())
+ || (node->allowOperationOnNode(PERM_OWNER, GP_OBJECT_MANIPULATE))))
{
can_derez_current = TRUE;
}
@@ -4448,7 +4656,10 @@ void handle_take()
LLNotification::Params params("ConfirmObjectTakeLock");
params.payload(payload);
- params.functor.function(confirm_take);
+ // MAINT-290
+ // Reason: Showing the confirmation dialog resets object selection, thus there is nothing to derez.
+ // Fix: pass selection to the confirm_take, so that selection doesn't "die" after confirmation dialog is opened
+ params.functor.function(boost::bind(confirm_take, _1, _2, LLSelectMgr::instance().getSelection()));
if(locked_but_takeable_object ||
!you_own_everything)
@@ -4501,7 +4712,7 @@ void handle_avatar_show_inspector()
-bool confirm_take(const LLSD& notification, const LLSD& response)
+bool confirm_take(const LLSD& notification, const LLSD& response, LLObjectSelectionHandle selection_handle)
{
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
if(enable_take() && (option == 0))
@@ -4542,9 +4753,10 @@ BOOL enable_take()
return TRUE;
}
# endif
- if((node->mPermissions->allowTransferTo(gAgent.getID())
+ if(!object->isPermanentEnforced() &&
+ ((node->mPermissions->allowTransferTo(gAgent.getID())
&& object->permModify())
- || (node->mPermissions->getOwner() == gAgent.getID()))
+ || (node->mPermissions->getOwner() == gAgent.getID())))
{
return TRUE;
}
@@ -4770,29 +4982,64 @@ BOOL sitting_on_selection()
return (gAgentAvatarp->isSitting() && gAgentAvatarp->getRoot() == root_object);
}
-class LLToolsSaveToInventory : public view_listener_t
+class LLToolsSaveToObjectInventory : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
{
- if(enable_save_into_inventory(NULL))
+ LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode();
+ if(node && (node->mValid) && (!node->mFromTaskID.isNull()))
{
- derez_objects(DRD_SAVE_INTO_AGENT_INVENTORY, LLUUID::null);
+ // *TODO: check to see if the fromtaskid object exists.
+ derez_objects(DRD_SAVE_INTO_TASK_INVENTORY, node->mFromTaskID);
}
return true;
}
};
-class LLToolsSaveToObjectInventory : public view_listener_t
+class LLToolsEnablePathfinding : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
{
- LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode();
- if(node && (node->mValid) && (!node->mFromTaskID.isNull()))
+ return (LLPathfindingManager::getInstance() != NULL) && LLPathfindingManager::getInstance()->isPathfindingEnabledForCurrentRegion();
+ }
+};
+
+class LLToolsEnablePathfindingView : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ return (LLPathfindingManager::getInstance() != NULL) && LLPathfindingManager::getInstance()->isPathfindingEnabledForCurrentRegion() && LLPathfindingManager::getInstance()->isPathfindingViewEnabled();
+ }
+};
+
+class LLToolsDoPathfindingRebakeRegion : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ bool hasPathfinding = (LLPathfindingManager::getInstance() != NULL);
+
+ if (hasPathfinding)
{
- // *TODO: check to see if the fromtaskid object exists.
- derez_objects(DRD_SAVE_INTO_TASK_INVENTORY, node->mFromTaskID);
+ LLMenuOptionPathfindingRebakeNavmesh::getInstance()->sendRequestRebakeNavmesh();
}
- return true;
+
+ return hasPathfinding;
+ }
+};
+
+class LLToolsEnablePathfindingRebakeRegion : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ bool returnValue = false;
+
+ if (LLPathfindingManager::getInstance() != NULL)
+ {
+ LLMenuOptionPathfindingRebakeNavmesh *rebakeInstance = LLMenuOptionPathfindingRebakeNavmesh::getInstance();
+ returnValue = (rebakeInstance->canRebakeRegion() &&
+ (rebakeInstance->getMode() == LLMenuOptionPathfindingRebakeNavmesh::kRebakeNavMesh_Available));
+ }
+ return returnValue;
}
};
@@ -5054,6 +5301,84 @@ class LLEditDelete : public view_listener_t
}
};
+void handle_spellcheck_replace_with_suggestion(const LLUICtrl* ctrl, const LLSD& param)
+{
+ const LLContextMenu* menu = dynamic_cast<const LLContextMenu*>(ctrl->getParent());
+ LLSpellCheckMenuHandler* spellcheck_handler = (menu) ? dynamic_cast<LLSpellCheckMenuHandler*>(menu->getSpawningView()) : NULL;
+ if ( (!spellcheck_handler) || (!spellcheck_handler->getSpellCheck()) )
+ {
+ return;
+ }
+
+ U32 index = 0;
+ if ( (!LLStringUtil::convertToU32(param.asString(), index)) || (index >= spellcheck_handler->getSuggestionCount()) )
+ {
+ return;
+ }
+
+ spellcheck_handler->replaceWithSuggestion(index);
+}
+
+bool visible_spellcheck_suggestion(LLUICtrl* ctrl, const LLSD& param)
+{
+ LLMenuItemGL* item = dynamic_cast<LLMenuItemGL*>(ctrl);
+ const LLContextMenu* menu = (item) ? dynamic_cast<const LLContextMenu*>(item->getParent()) : NULL;
+ const LLSpellCheckMenuHandler* spellcheck_handler = (menu) ? dynamic_cast<const LLSpellCheckMenuHandler*>(menu->getSpawningView()) : NULL;
+ if ( (!spellcheck_handler) || (!spellcheck_handler->getSpellCheck()) )
+ {
+ return false;
+ }
+
+ U32 index = 0;
+ if ( (!LLStringUtil::convertToU32(param.asString(), index)) || (index >= spellcheck_handler->getSuggestionCount()) )
+ {
+ return false;
+ }
+
+ item->setLabel(spellcheck_handler->getSuggestion(index));
+ return true;
+}
+
+void handle_spellcheck_add_to_dictionary(const LLUICtrl* ctrl)
+{
+ const LLContextMenu* menu = dynamic_cast<const LLContextMenu*>(ctrl->getParent());
+ LLSpellCheckMenuHandler* spellcheck_handler = (menu) ? dynamic_cast<LLSpellCheckMenuHandler*>(menu->getSpawningView()) : NULL;
+ if ( (spellcheck_handler) && (spellcheck_handler->canAddToDictionary()) )
+ {
+ spellcheck_handler->addToDictionary();
+ }
+}
+
+bool enable_spellcheck_add_to_dictionary(const LLUICtrl* ctrl)
+{
+ const LLContextMenu* menu = dynamic_cast<const LLContextMenu*>(ctrl->getParent());
+ const LLSpellCheckMenuHandler* spellcheck_handler = (menu) ? dynamic_cast<const LLSpellCheckMenuHandler*>(menu->getSpawningView()) : NULL;
+ return (spellcheck_handler) && (spellcheck_handler->canAddToDictionary());
+}
+
+void handle_spellcheck_add_to_ignore(const LLUICtrl* ctrl)
+{
+ const LLContextMenu* menu = dynamic_cast<const LLContextMenu*>(ctrl->getParent());
+ LLSpellCheckMenuHandler* spellcheck_handler = (menu) ? dynamic_cast<LLSpellCheckMenuHandler*>(menu->getSpawningView()) : NULL;
+ if ( (spellcheck_handler) && (spellcheck_handler->canAddToIgnore()) )
+ {
+ spellcheck_handler->addToIgnore();
+ }
+}
+
+bool enable_spellcheck_add_to_ignore(const LLUICtrl* ctrl)
+{
+ const LLContextMenu* menu = dynamic_cast<const LLContextMenu*>(ctrl->getParent());
+ const LLSpellCheckMenuHandler* spellcheck_handler = (menu) ? dynamic_cast<const LLSpellCheckMenuHandler*>(menu->getSpawningView()) : NULL;
+ return (spellcheck_handler) && (spellcheck_handler->canAddToIgnore());
+}
+
+bool enable_object_return()
+{
+ return (!LLSelectMgr::getInstance()->getSelection()->isEmpty() &&
+ (gAgent.isGodlike() || can_derez(DRD_RETURN_TO_OWNER)));
+}
+
bool enable_object_delete()
{
bool new_value =
@@ -5069,6 +5394,49 @@ bool enable_object_delete()
return new_value;
}
+class LLObjectsReturnPackage
+{
+public:
+ LLObjectsReturnPackage() : mObjectSelection(), mReturnableObjects(), mError(), mFirstRegion(NULL) {};
+ ~LLObjectsReturnPackage()
+ {
+ mObjectSelection.clear();
+ mReturnableObjects.clear();
+ mError.clear();
+ mFirstRegion = NULL;
+ };
+
+ LLObjectSelectionHandle mObjectSelection;
+ LLDynamicArray<LLViewerObjectPtr> mReturnableObjects;
+ std::string mError;
+ LLViewerRegion *mFirstRegion;
+};
+
+static void return_objects(LLObjectsReturnPackage *objectsReturnPackage, const LLSD& notification, const LLSD& response)
+{
+ if (LLNotificationsUtil::getSelectedOption(notification, response) == 0)
+ {
+ // Ignore category ID for this derez destination.
+ derez_objects(DRD_RETURN_TO_OWNER, LLUUID::null, objectsReturnPackage->mFirstRegion, objectsReturnPackage->mError, &objectsReturnPackage->mReturnableObjects);
+ }
+
+ delete objectsReturnPackage;
+}
+
+void handle_object_return()
+{
+ if (!LLSelectMgr::getInstance()->getSelection()->isEmpty())
+ {
+ LLObjectsReturnPackage *objectsReturnPackage = new LLObjectsReturnPackage();
+ objectsReturnPackage->mObjectSelection = LLSelectMgr::getInstance()->getEditSelection();
+
+ // Save selected objects, so that we still know what to return after the confirmation dialog resets selection.
+ get_derezzable_objects(DRD_RETURN_TO_OWNER, objectsReturnPackage->mError, objectsReturnPackage->mFirstRegion, &objectsReturnPackage->mReturnableObjects);
+
+ LLNotificationsUtil::add("ReturnToOwner", LLSD(), LLSD(), boost::bind(&return_objects, objectsReturnPackage, _1, _2));
+ }
+}
+
void handle_object_delete()
{
@@ -5298,8 +5666,6 @@ void toggle_debug_menus(void*)
// gExportDialog = LLUploadDialog::modalUploadDialog("Exporting selected objects...");
// }
//
-
-
class LLWorldSetHomeLocation : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
@@ -5373,18 +5739,18 @@ class LLWorldSetAway : public view_listener_t
}
};
-class LLWorldSetBusy : public view_listener_t
+class LLWorldSetDoNotDisturb : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
{
- if (gAgent.getBusy())
+ if (gAgent.isDoNotDisturb())
{
- gAgent.clearBusy();
+ gAgent.setDoNotDisturb(false);
}
else
{
- gAgent.setBusy();
- LLNotificationsUtil::add("BusyModeSet");
+ gAgent.setDoNotDisturb(true);
+ LLNotificationsUtil::add("DoNotDisturbModeSet");
}
return true;
}
@@ -5546,7 +5912,7 @@ bool complete_give_money(const LLSD& notification, const LLSD& response, LLObjec
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
if (option == 0)
{
- gAgent.clearBusy();
+ gAgent.setDoNotDisturb(false);
}
LLViewerObject* objectp = selection->getPrimaryObject();
@@ -5579,12 +5945,12 @@ bool complete_give_money(const LLSD& notification, const LLSD& response, LLObjec
void handle_give_money_dialog()
{
- LLNotification::Params params("BusyModePay");
+ LLNotification::Params params("DoNotDisturbModePay");
params.functor.function(boost::bind(complete_give_money, _1, _2, LLSelectMgr::getInstance()->getSelection()));
- if (gAgent.getBusy())
+ if (gAgent.isDoNotDisturb())
{
- // warn users of being in busy mode during a transaction
+ // warn users of being in do not disturb mode during a transaction
LLNotifications::instance().add(params);
}
else
@@ -5967,6 +6333,33 @@ class LLLandEdit : public view_listener_t
}
};
+class LLMuteParticle : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLUUID id = LLToolPie::getInstance()->getPick().mParticleOwnerID;
+
+ if (id.notNull())
+ {
+ std::string name;
+ gCacheName->getFullName(id, name);
+
+ LLMute mute(id, name, LLMute::AGENT);
+ if (LLMuteList::getInstance()->isMuted(mute.mID))
+ {
+ LLMuteList::getInstance()->remove(mute);
+ }
+ else
+ {
+ LLMuteList::getInstance()->add(mute);
+ LLPanelBlockedList::showPanelAndSelect(mute.mID);
+ }
+ }
+
+ return true;
+ }
+};
+
class LLWorldEnableBuyLand : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
@@ -6180,23 +6573,21 @@ class LLAttachmentDetachFromPoint : public view_listener_t
{
bool handleEvent(const LLSD& user_data)
{
+ uuid_vec_t ids_to_remove;
const LLViewerJointAttachment *attachment = get_if_there(gAgentAvatarp->mAttachmentPoints, user_data.asInteger(), (LLViewerJointAttachment*)NULL);
if (attachment->getNumObjects() > 0)
{
- gMessageSystem->newMessage("ObjectDetach");
- gMessageSystem->nextBlockFast(_PREHASH_AgentData);
- gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
- gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
-
for (LLViewerJointAttachment::attachedobjs_vec_t::const_iterator iter = attachment->mAttachedObjects.begin();
iter != attachment->mAttachedObjects.end();
iter++)
{
LLViewerObject *attached_object = (*iter);
- gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
- gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, attached_object->getLocalID());
+ ids_to_remove.push_back(attached_object->getAttachmentItemID());
+ }
}
- gMessageSystem->sendReliable( gAgent.getRegionHost() );
+ if (!ids_to_remove.empty())
+ {
+ LLAppearanceMgr::instance().removeItemsFromAvatar(ids_to_remove);
}
return true;
}
@@ -6269,17 +6660,8 @@ class LLAttachmentDetach : public view_listener_t
return true;
}
- // The sendDetach() method works on the list of selected
- // objects. Thus we need to clear the list, make sure it only
- // contains the object the user clicked, send the message,
- // then clear the list.
- // We use deselectAll to update the simulator's notion of what's
- // selected, and removeAll just to change things locally.
- //RN: I thought it was more useful to detach everything that was selected
- if (LLSelectMgr::getInstance()->getSelection()->isAttachment())
- {
- LLSelectMgr::getInstance()->sendDetach();
- }
+ LLAppearanceMgr::instance().removeItemFromAvatar(object->getAttachmentItemID());
+
return true;
}
};
@@ -6422,6 +6804,7 @@ BOOL object_selected_and_point_valid()
(selection->getFirstRootObject()->getPCode() == LL_PCODE_VOLUME) &&
selection->getFirstRootObject()->permYouOwner() &&
selection->getFirstRootObject()->flagObjectMove() &&
+ !selection->getFirstRootObject()->flagObjectPermanent() &&
!((LLViewerObject*)selection->getFirstRootObject()->getRoot())->isAvatar() &&
(selection->getFirstRootObject()->getNVPair("AssetContainer") == NULL);
}
@@ -6658,6 +7041,47 @@ void handle_selected_texture_info(void*)
}
}
+void handle_selected_material_info()
+{
+ for (LLObjectSelection::valid_iterator iter = LLSelectMgr::getInstance()->getSelection()->valid_begin();
+ iter != LLSelectMgr::getInstance()->getSelection()->valid_end(); iter++)
+ {
+ LLSelectNode* node = *iter;
+
+ std::string msg;
+ msg.assign("Material info for: \n");
+ msg.append(node->mName);
+
+ U8 te_count = node->getObject()->getNumTEs();
+ // map from material ID to list of faces using it
+ typedef std::map<LLMaterialID, std::vector<U8> > map_t;
+ map_t faces_per_material;
+ for (U8 i = 0; i < te_count; i++)
+ {
+ if (!node->isTESelected(i)) continue;
+
+ const LLMaterialID& material_id = node->getObject()->getTE(i)->getMaterialID();
+ faces_per_material[material_id].push_back(i);
+ }
+ // Per-material, dump which faces are using it.
+ map_t::iterator it;
+ for (it = faces_per_material.begin(); it != faces_per_material.end(); ++it)
+ {
+ const LLMaterialID& material_id = it->first;
+ msg += llformat("%s on face ", material_id.asString().c_str());
+ for (U8 i = 0; i < it->second.size(); ++i)
+ {
+ msg.append( llformat("%d ", (S32)(it->second[i])));
+ }
+ msg.append("\n");
+ }
+
+ LLSD args;
+ args["MESSAGE"] = msg;
+ LLNotificationsUtil::add("SystemMessage", args);
+ }
+}
+
void handle_test_male(void*)
{
LLAppearanceMgr::instance().wearOutfitByName("Male Shape & Outfit");
@@ -6670,15 +7094,6 @@ void handle_test_female(void*)
//gGestureList.requestResetFromServer( FALSE );
}
-void handle_toggle_pg(void*)
-{
- gAgent.setTeen( !gAgent.isTeen() );
-
- LLFloaterWorldMap::reloadIcons(NULL);
-
- llinfos << "PG status set to " << (S32)gAgent.isTeen() << llendl;
-}
-
void handle_dump_attachments(void*)
{
if(!isAgentAvatarValid()) return;
@@ -6769,6 +7184,15 @@ class LLAdvancedClickRenderShadowOption: public view_listener_t
}
};
+class LLAdvancedClickRenderProfile: public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ gShaderProfileFrame = TRUE;
+ return true;
+ }
+};
+
void menu_toggle_attached_lights(void* user_data)
{
LLPipeline::sRenderAttachedLights = gSavedSettings.getBOOL("RenderAttachedLights");
@@ -6906,50 +7330,6 @@ bool LLHasAsset::operator()(LLInventoryCategory* cat,
return FALSE;
}
-BOOL enable_save_into_inventory(void*)
-{
- // *TODO: clean this up
- // find the last root
- LLSelectNode* last_node = NULL;
- for (LLObjectSelection::root_iterator iter = LLSelectMgr::getInstance()->getSelection()->root_begin();
- iter != LLSelectMgr::getInstance()->getSelection()->root_end(); iter++)
- {
- last_node = *iter;
- }
-
-#ifdef HACKED_GODLIKE_VIEWER
- return TRUE;
-#else
-# ifdef TOGGLE_HACKED_GODLIKE_VIEWER
- if (!LLGridManager::getInstance()->isInProductionGrid()
- && gAgent.isGodlike())
- {
- return TRUE;
- }
-# endif
- // check all pre-req's for save into inventory.
- if(last_node && last_node->mValid && !last_node->mItemID.isNull()
- && (last_node->mPermissions->getOwner() == gAgent.getID())
- && (gInventory.getItem(last_node->mItemID) != NULL))
- {
- LLViewerObject* obj = last_node->getObject();
- if( obj && !obj->isAttachment() )
- {
- return TRUE;
- }
- }
-#endif
- return FALSE;
-}
-
-class LLToolsEnableSaveToInventory : public view_listener_t
-{
- bool handleEvent(const LLSD& userdata)
- {
- bool new_value = enable_save_into_inventory(NULL);
- return new_value;
- }
-};
BOOL enable_save_into_task_inventory(void*)
{
@@ -7186,7 +7566,7 @@ void handle_grab_baked_texture(void* data)
if(folder_id.notNull())
{
std::string name;
- name = "Baked " + LLVOAvatarDictionary::getInstance()->getBakedTexture(baked_tex_index)->mNameCapitalized + " Texture";
+ name = "Baked " + LLAvatarAppearanceDictionary::getInstance()->getBakedTexture(baked_tex_index)->mNameCapitalized + " Texture";
LLUUID item_id;
item_id.generate();
@@ -7331,6 +7711,7 @@ class LLToolsUseSelectionForGrid : public view_listener_t
} func;
LLSelectMgr::getInstance()->getSelection()->applyToRootObjects(&func);
LLSelectMgr::getInstance()->setGridMode(GRID_MODE_REF_OBJECT);
+ LLFloaterTools::setGridMode((S32)GRID_MODE_REF_OBJECT);
return true;
}
};
@@ -7407,6 +7788,20 @@ void handle_web_content_test(const LLSD& param)
LLWeb::loadURLInternal(url);
}
+void handle_show_url(const LLSD& param)
+{
+ std::string url = param.asString();
+ if(gSavedSettings.getBOOL("UseExternalBrowser"))
+ {
+ LLWeb::loadURLExternal(url);
+ }
+ else
+ {
+ LLWeb::loadURLInternal(url);
+ }
+
+}
+
void handle_buy_currency_test(void*)
{
std::string url =
@@ -7430,6 +7825,10 @@ void handle_rebake_textures(void*)
// Slam pending upload count to "unstick" things
bool slam_for_debug = true;
gAgentAvatarp->forceBakeAllTextures(slam_for_debug);
+ if (gAgent.getRegion() && gAgent.getRegion()->getCentralBakeVersion())
+ {
+ LLAppearanceMgr::instance().requestServerAppearanceUpdate();
+ }
}
void toggle_visibility(void* user_data)
@@ -7660,6 +8059,22 @@ class LLViewCheckRenderType : public view_listener_t
}
};
+class LLViewStatusAway : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ return (gAgent.isInitialized() && gAgent.getAFK());
+ }
+};
+
+class LLViewStatusDoNotDisturb : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ return (gAgent.isInitialized() && gAgent.isDoNotDisturb());
+ }
+};
+
class LLViewShowHUDAttachments : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
@@ -7696,7 +8111,7 @@ class LLEditTakeOff : public view_listener_t
{
std::string clothing = userdata.asString();
if (clothing == "all")
- LLWearableBridge::removeAllClothesFromAvatar();
+ LLAppearanceMgr::instance().removeAllClothesFromAvatar();
else
{
LLWearableType::EType type = LLWearableType::typeNameToType(clothing);
@@ -7706,8 +8121,8 @@ class LLEditTakeOff : public view_listener_t
{
// MULTI-WEARABLES: assuming user wanted to remove top shirt.
U32 wearable_index = gAgentWearables.getWearableCount(type) - 1;
- LLViewerInventoryItem *item = dynamic_cast<LLViewerInventoryItem*>(gAgentWearables.getWearableInventoryItem(type,wearable_index));
- LLWearableBridge::removeItemFromAvatar(item);
+ LLUUID item_id = gAgentWearables.getWearableItemID(type,wearable_index);
+ LLAppearanceMgr::instance().removeItemFromAvatar(item_id);
}
}
@@ -7886,11 +8301,7 @@ class LLWorldPostProcess : public view_listener_t
void handle_flush_name_caches()
{
- // Toggle display names on and off to flush
- bool use_display_names = LLAvatarNameCache::useDisplayNames();
- LLAvatarNameCache::setUseDisplayNames(!use_display_names);
- LLAvatarNameCache::setUseDisplayNames(use_display_names);
-
+ LLAvatarNameCache::cleanupClass();
if (gCacheName) gCacheName->clear();
}
@@ -7915,6 +8326,11 @@ public:
}
};
+void handle_voice_morphing_subscribe()
+{
+ LLWeb::loadURLExternal(LLTrans::getString("voice_morphing_url"));
+}
+
class LLToggleUIHints : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
@@ -8004,6 +8420,19 @@ void initialize_edit_menu()
}
+void initialize_spellcheck_menu()
+{
+ LLUICtrl::CommitCallbackRegistry::Registrar& commit = LLUICtrl::CommitCallbackRegistry::currentRegistrar();
+ LLUICtrl::EnableCallbackRegistry::Registrar& enable = LLUICtrl::EnableCallbackRegistry::currentRegistrar();
+
+ commit.add("SpellCheck.ReplaceWithSuggestion", boost::bind(&handle_spellcheck_replace_with_suggestion, _1, _2));
+ enable.add("SpellCheck.VisibleSuggestion", boost::bind(&visible_spellcheck_suggestion, _1, _2));
+ commit.add("SpellCheck.AddToDictionary", boost::bind(&handle_spellcheck_add_to_dictionary, _1));
+ enable.add("SpellCheck.EnableAddToDictionary", boost::bind(&enable_spellcheck_add_to_dictionary, _1));
+ commit.add("SpellCheck.AddToIgnore", boost::bind(&handle_spellcheck_add_to_ignore, _1));
+ enable.add("SpellCheck.EnableAddToIgnore", boost::bind(&enable_spellcheck_add_to_ignore, _1));
+}
+
void initialize_menus()
{
// A parameterized event handler used as ctrl-8/9/0 zoom controls below.
@@ -8031,10 +8460,11 @@ void initialize_menus()
// Don't prepend MenuName.Foo because these can be used in any menu.
enable.add("IsGodCustomerService", boost::bind(&is_god_customer_service));
- view_listener_t::addEnable(new LLUploadCostCalculator(), "Upload.CalculateCosts");
+ enable.add("displayViewerEventRecorderMenuItems",boost::bind(&LLViewerEventRecorder::displayViewerEventRecorderMenuItems,&LLViewerEventRecorder::instance()));
+ view_listener_t::addEnable(new LLUploadCostCalculator(), "Upload.CalculateCosts");
- commit.add("Inventory.NewWindow", boost::bind(&LLFloaterInventory::showAgentInventory));
+ enable.add("Conversation.IsConversationLoggingAllowed", boost::bind(&LLFloaterIMContainer::isConversationLoggingAllowed));
// Agent
commit.add("Agent.toggleFlying", boost::bind(&LLAgent::toggleFlying));
@@ -8080,11 +8510,21 @@ void initialize_menus()
view_listener_t::addMenu(new LLViewCheckShowHoverTips(), "View.CheckShowHoverTips");
view_listener_t::addMenu(new LLViewCheckHighlightTransparent(), "View.CheckHighlightTransparent");
view_listener_t::addMenu(new LLViewCheckRenderType(), "View.CheckRenderType");
+ view_listener_t::addMenu(new LLViewStatusAway(), "View.Status.CheckAway");
+ view_listener_t::addMenu(new LLViewStatusDoNotDisturb(), "View.Status.CheckDoNotDisturb");
view_listener_t::addMenu(new LLViewCheckHUDAttachments(), "View.CheckHUDAttachments");
-
+
// Me > Movement
view_listener_t::addMenu(new LLAdvancedAgentFlyingInfo(), "Agent.getFlying");
-
+
+ // Communicate > Voice morphing > Subscribe...
+ commit.add("Communicate.VoiceMorphing.Subscribe", boost::bind(&handle_voice_morphing_subscribe));
+ LLVivoxVoiceClient * voice_clientp = LLVivoxVoiceClient::getInstance();
+ enable.add("Communicate.VoiceMorphing.NoVoiceMorphing.Check"
+ , boost::bind(&LLVivoxVoiceClient::onCheckVoiceEffect, voice_clientp, "NoVoiceMorphing"));
+ commit.add("Communicate.VoiceMorphing.NoVoiceMorphing.Click"
+ , boost::bind(&LLVivoxVoiceClient::onClickVoiceEffect, voice_clientp, "NoVoiceMorphing"));
+
// World menu
view_listener_t::addMenu(new LLWorldAlwaysRun(), "World.AlwaysRun");
view_listener_t::addMenu(new LLWorldCreateLandmark(), "World.CreateLandmark");
@@ -8092,7 +8532,7 @@ void initialize_menus()
view_listener_t::addMenu(new LLWorldSetHomeLocation(), "World.SetHomeLocation");
view_listener_t::addMenu(new LLWorldTeleportHome(), "World.TeleportHome");
view_listener_t::addMenu(new LLWorldSetAway(), "World.SetAway");
- view_listener_t::addMenu(new LLWorldSetBusy(), "World.SetBusy");
+ view_listener_t::addMenu(new LLWorldSetDoNotDisturb(), "World.SetDoNotDisturb");
view_listener_t::addMenu(new LLWorldEnableCreateLandmark(), "World.EnableCreateLandmark");
view_listener_t::addMenu(new LLWorldEnableSetHomeLocation(), "World.EnableSetHomeLocation");
@@ -8125,7 +8565,6 @@ void initialize_menus()
commit.add("Tools.LookAtSelection", boost::bind(&handle_look_at_selection, _2));
commit.add("Tools.BuyOrTake", boost::bind(&handle_buy_or_take));
commit.add("Tools.TakeCopy", boost::bind(&handle_take_copy));
- view_listener_t::addMenu(new LLToolsSaveToInventory(), "Tools.SaveToInventory");
view_listener_t::addMenu(new LLToolsSaveToObjectInventory(), "Tools.SaveToObjectInventory");
view_listener_t::addMenu(new LLToolsSelectedScriptAction(), "Tools.SelectedScriptAction");
@@ -8137,9 +8576,13 @@ void initialize_menus()
enable.add("Tools.EnableTakeCopy", boost::bind(&enable_object_take_copy));
enable.add("Tools.VisibleBuyObject", boost::bind(&tools_visible_buy_object));
enable.add("Tools.VisibleTakeObject", boost::bind(&tools_visible_take_object));
- view_listener_t::addMenu(new LLToolsEnableSaveToInventory(), "Tools.EnableSaveToInventory");
view_listener_t::addMenu(new LLToolsEnableSaveToObjectInventory(), "Tools.EnableSaveToObjectInventory");
+ view_listener_t::addMenu(new LLToolsEnablePathfinding(), "Tools.EnablePathfinding");
+ view_listener_t::addMenu(new LLToolsEnablePathfindingView(), "Tools.EnablePathfindingView");
+ view_listener_t::addMenu(new LLToolsDoPathfindingRebakeRegion(), "Tools.DoPathfindingRebakeRegion");
+ view_listener_t::addMenu(new LLToolsEnablePathfindingRebakeRegion(), "Tools.EnablePathfindingRebakeRegion");
+
// Help menu
// most items use the ShowFloater method
view_listener_t::addMenu(new LLToggleHowTo(), "Help.ToggleHowTo");
@@ -8164,15 +8607,18 @@ void initialize_menus()
//// Advanced > Render > Features
view_listener_t::addMenu(new LLAdvancedToggleFeature(), "Advanced.ToggleFeature");
view_listener_t::addMenu(new LLAdvancedCheckFeature(), "Advanced.CheckFeature");
+
+ view_listener_t::addMenu(new LLAdvancedCheckDisplayTextureDensity(), "Advanced.CheckDisplayTextureDensity");
+ view_listener_t::addMenu(new LLAdvancedSetDisplayTextureDensity(), "Advanced.SetDisplayTextureDensity");
+
// Advanced > Render > Info Displays
view_listener_t::addMenu(new LLAdvancedToggleInfoDisplay(), "Advanced.ToggleInfoDisplay");
view_listener_t::addMenu(new LLAdvancedCheckInfoDisplay(), "Advanced.CheckInfoDisplay");
view_listener_t::addMenu(new LLAdvancedSelectedTextureInfo(), "Advanced.SelectedTextureInfo");
+ commit.add("Advanced.SelectedMaterialInfo", boost::bind(&handle_selected_material_info));
view_listener_t::addMenu(new LLAdvancedToggleWireframe(), "Advanced.ToggleWireframe");
view_listener_t::addMenu(new LLAdvancedCheckWireframe(), "Advanced.CheckWireframe");
// Develop > Render
- view_listener_t::addMenu(new LLAdvancedToggleTextureAtlas(), "Advanced.ToggleTextureAtlas");
- view_listener_t::addMenu(new LLAdvancedCheckTextureAtlas(), "Advanced.CheckTextureAtlas");
view_listener_t::addMenu(new LLAdvancedEnableObjectObjectOcclusion(), "Advanced.EnableObjectObjectOcclusion");
view_listener_t::addMenu(new LLAdvancedEnableRenderFBO(), "Advanced.EnableRenderFBO");
view_listener_t::addMenu(new LLAdvancedEnableRenderDeferred(), "Advanced.EnableRenderDeferred");
@@ -8186,7 +8632,7 @@ void initialize_menus()
view_listener_t::addMenu(new LLAdvancedHandleAttachedLightParticles(), "Advanced.HandleAttachedLightParticles");
view_listener_t::addMenu(new LLAdvancedCheckRenderShadowOption(), "Advanced.CheckRenderShadowOption");
view_listener_t::addMenu(new LLAdvancedClickRenderShadowOption(), "Advanced.ClickRenderShadowOption");
-
+ view_listener_t::addMenu(new LLAdvancedClickRenderProfile(), "Advanced.ClickRenderProfile");
#ifdef TOGGLE_HACKED_GODLIKE_VIEWER
view_listener_t::addMenu(new LLAdvancedHandleToggleHackedGodmode(), "Advanced.HandleToggleHackedGodmode");
@@ -8201,6 +8647,7 @@ void initialize_menus()
// Advanced > UI
commit.add("Advanced.WebBrowserTest", boost::bind(&handle_web_browser_test, _2)); // sigh! this one opens the MEDIA browser
commit.add("Advanced.WebContentTest", boost::bind(&handle_web_content_test, _2)); // this one opens the Web Content floater
+ commit.add("Advanced.ShowURL", boost::bind(&handle_show_url, _2));
view_listener_t::addMenu(new LLAdvancedBuyCurrencyTest(), "Advanced.BuyCurrencyTest");
view_listener_t::addMenu(new LLAdvancedDumpSelectMgr(), "Advanced.DumpSelectMgr");
view_listener_t::addMenu(new LLAdvancedDumpInventory(), "Advanced.DumpInventory");
@@ -8208,7 +8655,6 @@ void initialize_menus()
commit.add("Advanced.DumpFocusHolder", boost::bind(&handle_dump_focus) );
view_listener_t::addMenu(new LLAdvancedPrintSelectedObjectInfo(), "Advanced.PrintSelectedObjectInfo");
view_listener_t::addMenu(new LLAdvancedPrintAgentInfo(), "Advanced.PrintAgentInfo");
- view_listener_t::addMenu(new LLAdvancedPrintTextureMemoryStats(), "Advanced.PrintTextureMemoryStats");
view_listener_t::addMenu(new LLAdvancedToggleDebugClicks(), "Advanced.ToggleDebugClicks");
view_listener_t::addMenu(new LLAdvancedCheckDebugClicks(), "Advanced.CheckDebugClicks");
view_listener_t::addMenu(new LLAdvancedCheckDebugViews(), "Advanced.CheckDebugViews");
@@ -8235,12 +8681,17 @@ void initialize_menus()
// Advanced > Character > Character Tests
view_listener_t::addMenu(new LLAdvancedAppearanceToXML(), "Advanced.AppearanceToXML");
+ view_listener_t::addMenu(new LLAdvancedEnableAppearanceToXML(), "Advanced.EnableAppearanceToXML");
view_listener_t::addMenu(new LLAdvancedToggleCharacterGeometry(), "Advanced.ToggleCharacterGeometry");
view_listener_t::addMenu(new LLAdvancedTestMale(), "Advanced.TestMale");
view_listener_t::addMenu(new LLAdvancedTestFemale(), "Advanced.TestFemale");
- view_listener_t::addMenu(new LLAdvancedTogglePG(), "Advanced.TogglePG");
+ // Advanced > Character > Animation Speed
+ view_listener_t::addMenu(new LLAdvancedAnimTenFaster(), "Advanced.AnimTenFaster");
+ view_listener_t::addMenu(new LLAdvancedAnimTenSlower(), "Advanced.AnimTenSlower");
+ view_listener_t::addMenu(new LLAdvancedAnimResetAll(), "Advanced.AnimResetAll");
+
// Advanced > Character (toplevel)
view_listener_t::addMenu(new LLAdvancedForceParamsToDefault(), "Advanced.ForceParamsToDefault");
view_listener_t::addMenu(new LLAdvancedReloadVertexShader(), "Advanced.ReloadVertexShader");
@@ -8269,6 +8720,7 @@ void initialize_menus()
view_listener_t::addMenu(new LLAdvancedAgentPilot(), "Advanced.AgentPilot");
view_listener_t::addMenu(new LLAdvancedToggleAgentPilotLoop(), "Advanced.ToggleAgentPilotLoop");
view_listener_t::addMenu(new LLAdvancedCheckAgentPilotLoop(), "Advanced.CheckAgentPilotLoop");
+ view_listener_t::addMenu(new LLAdvancedViewerEventRecorder(), "Advanced.EventRecorder");
// Advanced > Debugging
view_listener_t::addMenu(new LLAdvancedForceErrorBreakpoint(), "Advanced.ForceErrorBreakpoint");
@@ -8295,6 +8747,9 @@ void initialize_menus()
// Develop >Set logging level
view_listener_t::addMenu(new LLDevelopCheckLoggingLevel(), "Develop.CheckLoggingLevel");
view_listener_t::addMenu(new LLDevelopSetLoggingLevel(), "Develop.SetLoggingLevel");
+
+ //Develop (Texture Fetch Debug Console)
+ view_listener_t::addMenu(new LLDevelopTextureFetchDebugger(), "Develop.SetTexFetchDebugger");
// Admin >Object
view_listener_t::addMenu(new LLAdminForceTakeCopy(), "Admin.ForceTakeCopy");
@@ -8325,8 +8780,11 @@ void initialize_menus()
// we don't use boost::bind directly to delay side tray construction
view_listener_t::addMenu( new LLTogglePanelPeopleTab(), "SideTray.PanelPeopleTab");
+ view_listener_t::addMenu( new LLCheckPanelPeopleTab(), "SideTray.CheckPanelPeopleTab");
// Avatar pie menu
+ view_listener_t::addMenu(new LLAvatarCheckImpostorMode(), "Avatar.CheckImpostorMode");
+ view_listener_t::addMenu(new LLAvatarSetImpostorMode(), "Avatar.SetImpostorMode");
view_listener_t::addMenu(new LLObjectMute(), "Avatar.Mute");
view_listener_t::addMenu(new LLAvatarAddFriend(), "Avatar.AddFriend");
view_listener_t::addMenu(new LLAvatarAddContact(), "Avatar.AddContact");
@@ -8400,6 +8858,9 @@ void initialize_menus()
view_listener_t::addMenu(new LLLandBuyPass(), "Land.BuyPass");
view_listener_t::addMenu(new LLLandEdit(), "Land.Edit");
+ // Particle muting
+ view_listener_t::addMenu(new LLMuteParticle(), "Particle.Mute");
+
view_listener_t::addMenu(new LLLandEnableBuyPass(), "Land.EnableBuyPass");
commit.add("Land.Buy", boost::bind(&handle_buy_land));
@@ -8422,7 +8883,12 @@ void initialize_menus()
enable.add("EnablePayObject", boost::bind(&enable_pay_object));
enable.add("EnablePayAvatar", boost::bind(&enable_pay_avatar));
enable.add("EnableEdit", boost::bind(&enable_object_edit));
+ enable.add("EnableMuteParticle", boost::bind(&enable_mute_particle));
enable.add("VisibleBuild", boost::bind(&enable_object_build));
+ commit.add("Pathfinding.Linksets.Select", boost::bind(&LLFloaterPathfindingLinksets::openLinksetsWithSelectedObjects));
+ enable.add("EnableSelectInPathfindingLinksets", boost::bind(&enable_object_select_in_pathfinding_linksets));
+ commit.add("Pathfinding.Characters.Select", boost::bind(&LLFloaterPathfindingCharacters::openCharactersWithSelectedObjects));
+ enable.add("EnableSelectInPathfindingCharacters", boost::bind(&enable_object_select_in_pathfinding_characters));
view_listener_t::addMenu(new LLFloaterVisible(), "FloaterVisible");
view_listener_t::addMenu(new LLShowSidetrayPanel(), "ShowSidetrayPanel");
diff --git a/indra/newview/llviewermenu.h b/indra/newview/llviewermenu.h
index 87cb4efbc4..7f09fc2d8f 100644..100755
--- a/indra/newview/llviewermenu.h
+++ b/indra/newview/llviewermenu.h
@@ -27,7 +27,7 @@
#ifndef LL_LLVIEWERMENU_H
#define LL_LLVIEWERMENU_H
-#include "llmenugl.h"
+#include "../llui/llmenugl.h"
#include "llsafehandle.h"
class LLMessageSystem;
@@ -39,6 +39,7 @@ class LLObjectSelection;
class LLSelectNode;
void initialize_edit_menu();
+void initialize_spellcheck_menu();
void init_menus();
void cleanup_menus();
@@ -48,7 +49,6 @@ void show_context_menu( S32 x, S32 y, MASK mask );
void show_build_mode_context_menu(S32 x, S32 y, MASK mask);
void show_navbar_context_menu(LLView* ctrl, S32 x, S32 y);
void show_topinfobar_context_menu(LLView* ctrl, S32 x, S32 y);
-BOOL enable_save_into_inventory(void*);
void handle_reset_view();
void handle_cut(void*);
void handle_copy(void*);
@@ -93,11 +93,20 @@ void handle_object_touch();
bool enable_object_open();
void handle_object_open();
+bool visible_take_object();
+bool tools_visible_take_object();
+bool enable_object_take_copy();
+bool enable_object_return();
+bool enable_object_delete();
+
// Buy either contents or object itself
void handle_buy();
+void handle_take();
void handle_take_copy();
void handle_look_at_selection(const LLSD& param);
void handle_zoom_to_object(LLUUID object_id);
+void handle_object_return();
+void handle_object_delete();
void handle_buy_land();
@@ -129,6 +138,11 @@ bool handle_go_to();
// Export to XML or Collada
void handle_export_selected( void * );
+// Convert strings to internal types
+U32 render_type_from_string(std::string render_type);
+U32 feature_from_string(std::string feature);
+U32 info_display_from_string(std::string info_display);
+
class LLViewerMenuHolderGL : public LLMenuHolderGL
{
public:
@@ -149,8 +163,6 @@ protected:
LLSafeHandle<LLObjectSelection> mObjectSelection;
};
-extern const std::string SAVE_INTO_INVENTORY;
-
extern LLMenuBarGL* gMenuBarView;
//extern LLView* gMenuBarHolder;
extern LLMenuGL* gEditMenu;
@@ -165,6 +177,7 @@ extern LLContextMenu *gMenuObject;
extern LLContextMenu *gMenuAttachmentSelf;
extern LLContextMenu *gMenuAttachmentOther;
extern LLContextMenu *gMenuLand;
+extern LLContextMenu *gMenuMuteParticle;
// Needed to build menus when attachment site list available
extern LLMenuGL* gAttachSubMenu;
@@ -177,8 +190,6 @@ extern LLContextMenu* gDetachPieMenu;
extern LLContextMenu* gAttachBodyPartPieMenus[8];
extern LLContextMenu* gDetachBodyPartPieMenus[8];
-extern LLMenuItemCallGL* gAFKMenu;
-extern LLMenuItemCallGL* gBusyMenu;
extern LLMenuItemCallGL* gMutePieMenu;
extern LLMenuItemCallGL* gMuteObjectPieMenu;
extern LLMenuItemCallGL* gBuyPassPieMenu;
diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp
index aa0c0008aa..16e75a4ad7 100644..100755
--- a/indra/newview/llviewermenufile.cpp
+++ b/indra/newview/llviewermenufile.cpp
@@ -34,6 +34,7 @@
#include "llfilepicker.h"
#include "llfloaterreg.h"
#include "llbuycurrencyhtml.h"
+#include "llfloatermap.h"
#include "llfloatermodelpreview.h"
#include "llfloatersnapshot.h"
#include "llimage.h"
@@ -475,7 +476,7 @@ class LLFileEnableCloseWindow : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
{
- bool new_value = NULL != LLFloater::getClosableFloaterFromFocus();
+ bool new_value = NULL != gFloaterView->getFrontmostClosableFloater();
return new_value;
}
};
@@ -484,8 +485,7 @@ class LLFileCloseWindow : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
{
- LLFloater::closeFocusedFloater();
-
+ LLFloater::closeFrontmostFloater();
return true;
}
};
@@ -494,7 +494,7 @@ class LLFileEnableCloseAllWindows : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
{
- bool open_children = gFloaterView->allChildrenClosed();
+ bool open_children = gFloaterView->allChildrenClosed() && !LLFloaterSnapshot::getInstance()->isInVisibleChain();
return !open_children;
}
};
@@ -505,7 +505,7 @@ class LLFileCloseAllWindows : public view_listener_t
{
bool app_quitting = false;
gFloaterView->closeAllChildren(app_quitting);
-
+ LLFloaterSnapshot::getInstance()->closeFloater(app_quitting);
return true;
}
};
diff --git a/indra/newview/llviewermenufile.h b/indra/newview/llviewermenufile.h
index 3136358b83..3136358b83 100644..100755
--- a/indra/newview/llviewermenufile.h
+++ b/indra/newview/llviewermenufile.h
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 854e2bea52..82131c6675 100755
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -42,8 +42,10 @@
#include "llinventorydefines.h"
#include "lllslconstants.h"
#include "llregionhandle.h"
+#include "llsd.h"
#include "llsdserialize.h"
#include "llteleportflags.h"
+#include "lltoastnotifypanel.h"
#include "lltransactionflags.h"
#include "llvfile.h"
#include "llvfs.h"
@@ -64,10 +66,11 @@
#include "llfloatersnapshot.h"
#include "llhudeffecttrail.h"
#include "llhudmanager.h"
+#include "llimview.h"
#include "llinventoryfunctions.h"
#include "llinventoryobserver.h"
#include "llinventorypanel.h"
-#include "llnearbychat.h"
+#include "llfloaterimnearbychat.h"
#include "llnotifications.h"
#include "llnotificationsutil.h"
#include "llpanelgrouplandmoney.h"
@@ -107,6 +110,7 @@
#include "llagentui.h"
#include "llpanelblockedlist.h"
#include "llpanelplaceprofile.h"
+#include "llviewerregion.h"
#include <boost/algorithm/string/split.hpp> //
#include <boost/regex.hpp>
@@ -118,6 +122,8 @@
#pragma warning (disable:4702)
#endif
+extern void on_new_message(const LLSD& msg);
+
//
// Constants
//
@@ -132,6 +138,7 @@ static const U32 LLREQUEST_PERMISSION_THROTTLE_LIMIT = 5; // requests
static const F32 LLREQUEST_PERMISSION_THROTTLE_INTERVAL = 10.0f; // seconds
extern BOOL gDebugClicks;
+extern bool gShiftFrame;
// function prototypes
bool check_offer_throttle(const std::string& from_name, bool check_only);
@@ -157,7 +164,11 @@ const std::string SCRIPT_QUESTIONS[SCRIPT_PERMISSION_EOF] =
"ChangePermissions",
"TrackYourCamera",
"ControlYourCamera",
- "TeleportYourAgent"
+ "TeleportYourAgent",
+ "JoinAnExperience",
+ "SilentlyManageEstateAccess",
+ "OverrideYourAnimations",
+ "ScriptReturnObjects"
};
const BOOL SCRIPT_QUESTION_IS_CAUTION[SCRIPT_PERMISSION_EOF] =
@@ -173,7 +184,11 @@ const BOOL SCRIPT_QUESTION_IS_CAUTION[SCRIPT_PERMISSION_EOF] =
FALSE, // ChangePermissions
FALSE, // TrackYourCamera,
FALSE, // ControlYourCamera
- FALSE // TeleportYourAgent
+ FALSE, // TeleportYourAgent
+ FALSE, // JoinAnExperience
+ FALSE, // SilentlyManageEstateAccess
+ FALSE, // OverrideYourAnimations
+ FALSE, // ScriptReturnObjects
};
bool friendship_offer_callback(const LLSD& notification, const LLSD& response)
@@ -181,78 +196,86 @@ bool friendship_offer_callback(const LLSD& notification, const LLSD& response)
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
LLMessageSystem* msg = gMessageSystem;
const LLSD& payload = notification["payload"];
-
- // add friend to recent people list
- LLRecentPeople::instance().add(payload["from_id"]);
-
- switch(option)
- {
- case 0:
- {
- // accept
- LLAvatarTracker::formFriendship(payload["from_id"]);
-
- const LLUUID fid = gInventory.findCategoryUUIDForType(LLFolderType::FT_CALLINGCARD);
-
- // This will also trigger an onlinenotification if the user is online
- msg->newMessageFast(_PREHASH_AcceptFriendship);
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- msg->nextBlockFast(_PREHASH_TransactionBlock);
- msg->addUUIDFast(_PREHASH_TransactionID, payload["session_id"]);
- msg->nextBlockFast(_PREHASH_FolderData);
- msg->addUUIDFast(_PREHASH_FolderID, fid);
- msg->sendReliable(LLHost(payload["sender"].asString()));
-
- LLSD payload = notification["payload"];
- payload["SUPPRESS_TOAST"] = true;
- LLNotificationsUtil::add("FriendshipAcceptedByMe",
- notification["substitutions"], payload);
- break;
- }
- case 1: // Decline
- {
- LLSD payload = notification["payload"];
- payload["SUPPRESS_TOAST"] = true;
- LLNotificationsUtil::add("FriendshipDeclinedByMe",
- notification["substitutions"], payload);
- }
- // fall-through
- case 2: // Send IM - decline and start IM session
- {
- // decline
- // We no longer notify other viewers, but we DO still send
- // the rejection to the simulator to delete the pending userop.
- msg->newMessageFast(_PREHASH_DeclineFriendship);
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- msg->nextBlockFast(_PREHASH_TransactionBlock);
- msg->addUUIDFast(_PREHASH_TransactionID, payload["session_id"]);
- msg->sendReliable(LLHost(payload["sender"].asString()));
-
- // start IM session
- if(2 == option)
- {
- LLAvatarActions::startIM(payload["from_id"].asUUID());
- }
- }
- default:
- // close button probably, possibly timed out
- break;
- }
+ LLNotificationPtr notification_ptr = LLNotifications::instance().find(notification["id"].asUUID());
+
+ // this will be skipped if the user offering friendship is blocked
+ if (notification_ptr)
+ {
+ // add friend to recent people list
+ LLRecentPeople::instance().add(payload["from_id"]);
+
+ switch(option)
+ {
+ case 0:
+ {
+ // accept
+ LLAvatarTracker::formFriendship(payload["from_id"]);
+
+ const LLUUID fid = gInventory.findCategoryUUIDForType(LLFolderType::FT_CALLINGCARD);
+
+ // This will also trigger an onlinenotification if the user is online
+ msg->newMessageFast(_PREHASH_AcceptFriendship);
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ msg->nextBlockFast(_PREHASH_TransactionBlock);
+ msg->addUUIDFast(_PREHASH_TransactionID, payload["session_id"]);
+ msg->nextBlockFast(_PREHASH_FolderData);
+ msg->addUUIDFast(_PREHASH_FolderID, fid);
+ msg->sendReliable(LLHost(payload["sender"].asString()));
+
+ LLSD payload = notification["payload"];
+ LLNotificationsUtil::add("FriendshipAcceptedByMe",
+ notification["substitutions"], payload);
+ break;
+ }
+ case 1: // Decline
+ {
+ LLSD payload = notification["payload"];
+ LLNotificationsUtil::add("FriendshipDeclinedByMe",
+ notification["substitutions"], payload);
+ }
+ // fall-through
+ case 2: // Send IM - decline and start IM session
+ {
+ // decline
+ // We no longer notify other viewers, but we DO still send
+ // the rejection to the simulator to delete the pending userop.
+ msg->newMessageFast(_PREHASH_DeclineFriendship);
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ msg->nextBlockFast(_PREHASH_TransactionBlock);
+ msg->addUUIDFast(_PREHASH_TransactionID, payload["session_id"]);
+ msg->sendReliable(LLHost(payload["sender"].asString()));
+
+ // start IM session
+ if(2 == option)
+ {
+ LLAvatarActions::startIM(payload["from_id"].asUUID());
+ }
+ }
+ default:
+ // close button probably, possibly timed out
+ break;
+ }
+
+ // TODO: this set of calls has undesirable behavior under Windows OS (CHUI-985):
+ // here appears three additional toasts instead one modified
+ // need investigation and fix
+
+ // LLNotificationFormPtr modified_form(new LLNotificationForm(*notification_ptr->getForm()));
+ // modified_form->setElementEnabled("Accept", false);
+ // modified_form->setElementEnabled("Decline", false);
+ // notification_ptr->updateForm(modified_form);
+ // notification_ptr->repost();
+ }
return false;
}
static LLNotificationFunctorRegistration friendship_offer_callback_reg("OfferFriendship", friendship_offer_callback);
static LLNotificationFunctorRegistration friendship_offer_callback_reg_nm("OfferFriendshipNoMessage", friendship_offer_callback);
-//const char BUSY_AUTO_RESPONSE[] = "The Resident you messaged is in 'busy mode' which means they have "
-// "requested not to be disturbed. Your message will still be shown in their IM "
-// "panel for later viewing.";
-
-//
// Functions
//
@@ -623,7 +646,6 @@ void send_sound_trigger(const LLUUID& sound_id, F32 gain)
bool join_group_response(const LLSD& notification, const LLSD& response)
{
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
- BOOL delete_context_data = TRUE;
bool accept_invite = false;
LLUUID group_id = notification["payload"]["group_id"].asUUID();
@@ -652,7 +674,6 @@ bool join_group_response(const LLSD& notification, const LLSD& response)
}
else
{
- delete_context_data = FALSE;
LLSD args;
args["NAME"] = name;
LLNotificationsUtil::add("JoinedTooManyGroupsMember", args, notification["payload"]);
@@ -665,7 +686,6 @@ bool join_group_response(const LLSD& notification, const LLSD& response)
// sure the user is sure they want to join.
if (fee > 0)
{
- delete_context_data = FALSE;
LLSD args;
args["COST"] = llformat("%d", fee);
// Set the fee for next time to 0, so that we don't keep
@@ -723,7 +743,7 @@ static void highlight_inventory_objects_in_panel(const std::vector<LLUUID>& item
LLFolderView* fv = inventory_panel->getRootFolder();
if (fv)
{
- LLFolderViewItem* fv_item = fv->getItemByID(item_id);
+ LLFolderViewItem* fv_item = inventory_panel->getItemByID(item_id);
if (fv_item)
{
LLFolderViewItem* fv_folder = fv_item->getParentFolder();
@@ -811,7 +831,13 @@ private:
mSelectedItems.clear();
if (LLInventoryPanel::getActiveInventoryPanel())
{
- mSelectedItems = LLInventoryPanel::getActiveInventoryPanel()->getRootFolder()->getSelectionList();
+ std::set<LLFolderViewItem*> selection = LLInventoryPanel::getActiveInventoryPanel()->getRootFolder()->getSelectionList();
+ for (std::set<LLFolderViewItem*>::iterator it = selection.begin(), end_it = selection.end();
+ it != end_it;
+ ++it)
+ {
+ mSelectedItems.insert(static_cast<LLFolderViewModelItemInventory*>((*it)->getViewModelItem())->getUUID());
+ }
}
mSelectedItems.erase(mMoveIntoFolderID);
}
@@ -846,7 +872,15 @@ private:
}
// get selected items (without destination folder)
- selected_items_t selected_items = active_panel->getRootFolder()->getSelectionList();
+ selected_items_t selected_items;
+
+ std::set<LLFolderViewItem*> selection = LLInventoryPanel::getActiveInventoryPanel()->getRootFolder()->getSelectionList();
+ for (std::set<LLFolderViewItem*>::iterator it = selection.begin(), end_it = selection.end();
+ it != end_it;
+ ++it)
+ {
+ selected_items.insert(static_cast<LLFolderViewModelItemInventory*>((*it)->getViewModelItem())->getUUID());
+ }
selected_items.erase(mMoveIntoFolderID);
// compare stored & current sets of selected items
@@ -1152,7 +1186,7 @@ bool check_offer_throttle(const std::string& from_name, bool check_only)
}
}
}
-
+
// Return "true" if we have a preview method for that asset type, "false" otherwise
bool check_asset_previewable(const LLAssetType::EType asset_type)
{
@@ -1341,6 +1375,8 @@ void inventory_offer_mute_callback(const LLUUID& blocked_id,
gSavedSettings.getString("NotificationChannelUUID")), OfferMatcher(blocked_id));
}
+std::string LLOfferInfo::mResponderType = "offer_info";
+
LLOfferInfo::LLOfferInfo()
: LLNotificationResponderInterface()
, mFromGroup(FALSE)
@@ -1386,6 +1422,7 @@ LLOfferInfo::LLOfferInfo(const LLOfferInfo& info)
LLSD LLOfferInfo::asLLSD()
{
LLSD sd;
+ sd["responder_type"] = mResponderType;
sd["im_type"] = mIM;
sd["from_id"] = mFromID;
sd["from_group"] = mFromGroup;
@@ -1475,16 +1512,15 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&
itemp = (LLViewerInventoryItem*)gInventory.getItem(mObjectID);
}
+ LLNotificationPtr notification_ptr = LLNotifications::instance().find(notification["id"].asUUID());
+
// For muting, we need to add the mute, then decline the offer.
// This must be done here because:
// * callback may be called immediately,
// * adding the mute sends a message,
// * we can't build two messages at once.
- if (2 == button) // Block
+ if (IOR_MUTE == button) // Block
{
- LLNotificationPtr notification_ptr = LLNotifications::instance().find(notification["id"].asUUID());
-
- llassert(notification_ptr != NULL);
if (notification_ptr != NULL)
{
gCacheName->get(mFromID, mFromGroup, boost::bind(&inventory_offer_mute_callback, _1, _2, _3));
@@ -1497,8 +1533,8 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&
// TODO: when task inventory offers can also be handled the new way, migrate the code that sets these strings here:
from_string = chatHistory_string = mFromName;
- bool busy = gAgent.getBusy();
-
+ LLNotificationFormPtr modified_form(notification_ptr ? new LLNotificationForm(*notification_ptr->getForm()) : new LLNotificationForm());
+
switch(button)
{
case IOR_SHOW:
@@ -1542,6 +1578,11 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&
LL_WARNS("Messaging") << "inventory_offer_callback: unknown offer type" << LL_ENDL;
break;
}
+
+ if (modified_form != NULL)
+ {
+ modified_form->setElementEnabled("Show", false);
+ }
break;
// end switch (mIM)
@@ -1554,9 +1595,14 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&
args["MESSAGE"] = log_message;
LLNotificationsUtil::add("SystemMessageTip", args);
}
+
break;
case IOR_MUTE:
+ if (modified_form != NULL)
+ {
+ modified_form->setElementEnabled("Mute", false);
+ }
// MUTE falls through to decline
case IOR_DECLINE:
{
@@ -1586,12 +1632,13 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&
{
opener = discard_agent_offer;
}
-
-
- if (busy && (!mFromGroup && !mFromObject))
+
+ if (modified_form != NULL)
{
- busy_message(gMessageSystem, mFromID);
+ modified_form->setElementEnabled("Show", false);
+ modified_form->setElementEnabled("Discard", false);
}
+
break;
}
default:
@@ -1611,6 +1658,7 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&
{
delete this;
}
+
return false;
}
@@ -1701,7 +1749,7 @@ bool LLOfferInfo::inventory_task_offer_callback(const LLSD& notification, const
from_string = chatHistory_string = mFromName;
}
- bool busy = gAgent.getBusy();
+ bool is_do_not_disturb = gAgent.isDoNotDisturb();
switch(button)
{
@@ -1774,9 +1822,9 @@ bool LLOfferInfo::inventory_task_offer_callback(const LLSD& notification, const
LLNotificationsUtil::add("SystemMessageTip", args);
}
- if (busy && (!mFromGroup && !mFromObject))
+ if (is_do_not_disturb && (!mFromGroup && !mFromObject))
{
- busy_message(msg,mFromID);
+ send_do_not_disturb_message(msg,mFromID);
}
break;
}
@@ -1928,6 +1976,7 @@ void inventory_offer_handler(LLOfferInfo* info)
p.substitutions(args).payload(payload).functor.responder(LLNotificationResponderPtr(info));
info->mPersist = true;
p.name = "UserGiveItem";
+ p.offer_from_agent = true;
// Prefetch the item into your local inventory.
LLInventoryFetchItemsObserver* fetch_item = new LLInventoryFetchItemsObserver(info->mObjectID);
@@ -1944,6 +1993,11 @@ void inventory_offer_handler(LLOfferInfo* info)
// In viewer 2 we're now auto receiving inventory offers and messaging as such (not sending reject messages).
info->send_auto_receive_response();
+ if (gAgent.isDoNotDisturb())
+ {
+ send_do_not_disturb_message(gMessageSystem, info->mFromID);
+ }
+
// Inform user that there is a script floater via toast system
{
payload["give_inventory_notification"] = TRUE;
@@ -1988,10 +2042,62 @@ bool lure_callback(const LLSD& notification, const LLSD& response)
lure_id);
break;
}
+
+ LLNotificationPtr notification_ptr = LLNotifications::instance().find(notification["id"].asUUID());
+
+ if (notification_ptr)
+ {
+ LLNotificationFormPtr modified_form(new LLNotificationForm(*notification_ptr->getForm()));
+ modified_form->setElementEnabled("Teleport", false);
+ modified_form->setElementEnabled("Cancel", false);
+ notification_ptr->updateForm(modified_form);
+ notification_ptr->repost();
+ }
+
return false;
}
static LLNotificationFunctorRegistration lure_callback_reg("TeleportOffered", lure_callback);
+bool mature_lure_callback(const LLSD& notification, const LLSD& response)
+{
+ S32 option = 0;
+ if (response.isInteger())
+ {
+ option = response.asInteger();
+ }
+ else
+ {
+ option = LLNotificationsUtil::getSelectedOption(notification, response);
+ }
+
+ LLUUID from_id = notification["payload"]["from_id"].asUUID();
+ LLUUID lure_id = notification["payload"]["lure_id"].asUUID();
+ BOOL godlike = notification["payload"]["godlike"].asBoolean();
+ U8 region_access = static_cast<U8>(notification["payload"]["region_maturity"].asInteger());
+
+ switch(option)
+ {
+ case 0:
+ {
+ // accept
+ gSavedSettings.setU32("PreferredMaturity", static_cast<U32>(region_access));
+ gAgent.setMaturityRatingChangeDuringTeleport(region_access);
+ gAgent.teleportViaLure(lure_id, godlike);
+ }
+ break;
+ case 1:
+ default:
+ // decline
+ send_simple_im(from_id,
+ LLStringUtil::null,
+ IM_LURE_DECLINED,
+ lure_id);
+ break;
+ }
+ return false;
+}
+static LLNotificationFunctorRegistration mature_lure_callback_reg("TeleportOffered_MaturityExceeded", mature_lure_callback);
+
bool goto_url_callback(const LLSD& notification, const LLSD& response)
{
std::string url = notification["payload"]["url"].asString();
@@ -2109,13 +2215,13 @@ static std::string clean_name_from_im(const std::string& name, EInstantMessage t
case IM_SESSION_SEND:
case IM_SESSION_LEAVE:
//IM_FROM_TASK
- case IM_BUSY_AUTO_RESPONSE:
+ case IM_DO_NOT_DISTURB_AUTO_RESPONSE:
case IM_CONSOLE_AND_CHAT_HISTORY:
case IM_LURE_USER:
case IM_LURE_ACCEPTED:
case IM_LURE_DECLINED:
case IM_GODLIKE_LURE_USER:
- case IM_YET_TO_BE_USED:
+ case IM_TELEPORT_REQUEST:
case IM_GROUP_ELECTION_DEPRECATED:
//IM_GOTO_URL
//IM_FROM_TASK_AS_ALERT
@@ -2150,16 +2256,7 @@ static std::string clean_name_from_task_im(const std::string& msg,
// Don't try to clean up group names
if (!from_group)
{
- if (LLAvatarNameCache::useDisplayNames())
- {
- // ...just convert to username
- final += LLCacheName::buildUsername(name);
- }
- else
- {
- // ...strip out legacy "Resident" name
- final += LLCacheName::cleanFullName(name);
- }
+ final += LLCacheName::buildUsername(name);
}
final += match[3].str();
return final;
@@ -2167,13 +2264,13 @@ static std::string clean_name_from_task_im(const std::string& msg,
return msg;
}
-void notification_display_name_callback(const LLUUID& id,
+static void notification_display_name_callback(const LLUUID& id,
const LLAvatarName& av_name,
const std::string& name,
LLSD& substitutions,
const LLSD& payload)
{
- substitutions["NAME"] = av_name.mDisplayName;
+ substitutions["NAME"] = av_name.getDisplayName();
LLNotificationsUtil::add(name, substitutions, payload);
}
@@ -2191,7 +2288,7 @@ protected:
};
// Callback for name resolution of a god/estate message
-void god_message_name_cb(const LLAvatarName& av_name, LLChat chat, std::string message)
+static void god_message_name_cb(const LLAvatarName& av_name, LLChat chat, std::string message)
{
LLSD args;
args["NAME"] = av_name.getCompleteName();
@@ -2201,12 +2298,11 @@ void god_message_name_cb(const LLAvatarName& av_name, LLChat chat, std::string m
// Treat like a system message and put in chat history.
chat.mText = av_name.getCompleteName() + ": " + message;
- LLNearbyChat* nearby_chat = LLNearbyChat::getInstance();
- if(nearby_chat)
+ LLFloaterIMNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat");
+ if (nearby_chat)
{
nearby_chat->addMessage(chat);
}
-
}
void process_improved_im(LLMessageSystem *msg, void **user_data)
@@ -2259,16 +2355,17 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
// IDEVO convert new-style "Resident" names for display
name = clean_name_from_im(name, dialog);
- BOOL is_busy = gAgent.getBusy();
+ BOOL is_do_not_disturb = gAgent.isDoNotDisturb();
BOOL is_muted = LLMuteList::getInstance()->isMuted(from_id, name, LLMute::flagTextChat)
// object IMs contain sender object id in session_id (STORM-1209)
|| dialog == IM_FROM_TASK && LLMuteList::getInstance()->isMuted(session_id);
- BOOL is_linden = LLMuteList::getInstance()->isLinden(name);
BOOL is_owned_by_me = FALSE;
BOOL is_friend = (LLAvatarTracker::instance().getBuddyInfo(from_id) == NULL) ? false : true;
BOOL accept_im_from_only_friend = gSavedSettings.getBOOL("VoiceCallsFriendsOnly");
-
- chat.mMuted = is_muted && !is_linden;
+ BOOL is_linden = chat.mSourceType != CHAT_SOURCE_OBJECT &&
+ LLMuteList::getInstance()->isLinden(name);
+
+ chat.mMuted = is_muted;
chat.mFromID = from_id;
chat.mFromName = name;
chat.mSourceType = (from_id.isNull() || (name == std::string(SYSTEM_FROM))) ? CHAT_SOURCE_SYSTEM : CHAT_SOURCE_AGENT;
@@ -2286,7 +2383,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
LLNotification::Params params;
switch(dialog)
- {
+ {
case IM_CONSOLE_AND_CHAT_HISTORY:
args["MESSAGE"] = message;
payload["from_id"] = from_id;
@@ -2297,7 +2394,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
LLPostponedNotification::add<LLPostponedIMSystemTipNotification>(params, from_id, false);
break;
- case IM_NOTHING_SPECIAL:
+ case IM_NOTHING_SPECIAL: // p2p IM
// Don't show dialog, just do IM
if (!gAgent.isGodlike()
&& gAgent.getRegion()->isPrelude()
@@ -2306,29 +2403,18 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
// do nothing -- don't distract newbies in
// Prelude with global IMs
}
- else if (offline == IM_ONLINE && !is_linden && is_busy && name != SYSTEM_FROM)
+ else if (offline == IM_ONLINE
+ && is_do_not_disturb
+ && from_id.notNull() //not a system message
+ && to_id.notNull()) //not global message
{
- // return a standard "busy" message, but only do it to online IM
+ // return a standard "do not disturb" message, but only do it to online IM
// (i.e. not other auto responses and not store-and-forward IM)
if (!gIMMgr->hasSession(session_id))
{
// if there is not a panel for this conversation (i.e. it is a new IM conversation
// initiated by the other party) then...
- std::string my_name;
- LLAgentUI::buildFullname(my_name);
- std::string response = gSavedPerAccountSettings.getString("BusyModeResponse");
- pack_instant_message(
- gMessageSystem,
- gAgent.getID(),
- FALSE,
- gAgent.getSessionID(),
- from_id,
- my_name,
- response,
- IM_ONLINE,
- IM_BUSY_AUTO_RESPONSE,
- session_id);
- gAgent.sendReliableMessage();
+ send_do_not_disturb_message(msg, from_id, session_id);
}
// now store incoming IM in chat history
@@ -2343,6 +2429,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
from_id,
name,
buffer,
+ IM_OFFLINE == offline,
LLStringUtil::null,
dialog,
parent_estate_id,
@@ -2377,24 +2464,25 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
LL_INFOS("Messaging") << "process_improved_im: session_id( " << session_id << " ), from_id( " << from_id << " )" << LL_ENDL;
bool mute_im = is_muted;
- if (accept_im_from_only_friend && !is_friend)
+ if(accept_im_from_only_friend && !is_friend && !is_linden)
{
if (!gIMMgr->isNonFriendSessionNotified(session_id))
{
std::string message = LLTrans::getString("IM_unblock_only_groups_friends");
- gIMMgr->addMessage(session_id, from_id, name, message);
+ gIMMgr->addMessage(session_id, from_id, name, message, IM_OFFLINE == offline);
gIMMgr->addNotifiedNonFriendSessionID(session_id);
}
mute_im = true;
}
- if (!mute_im || is_linden)
+ if (!mute_im)
{
gIMMgr->addMessage(
session_id,
from_id,
name,
buffer,
+ IM_OFFLINE == offline,
LLStringUtil::null,
dialog,
parent_estate_id,
@@ -2539,7 +2627,10 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
payload["sender_name"] = name;
payload["group_id"] = group_id;
payload["inventory_name"] = item_name;
- payload["inventory_offer"] = info ? info->asLLSD() : LLSD();
+ if(info && info->asLLSD())
+ {
+ payload["inventory_offer"] = info->asLLSD();
+ }
LLSD args;
args["SUBJECT"] = subj;
@@ -2561,13 +2652,12 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
break;
case IM_GROUP_INVITATION:
{
- //if (!is_linden && (is_busy || is_muted))
- if ((is_busy || is_muted))
+ if (is_do_not_disturb || is_muted)
{
- LLMessageSystem *msg = gMessageSystem;
- busy_message(msg,from_id);
+ send_do_not_disturb_message(msg, from_id);
}
- else
+
+ if (!is_muted)
{
LL_INFOS("Messaging") << "Received IM_GROUP_INVITATION message." << LL_ENDL;
// Read the binary bucket for more information.
@@ -2648,7 +2738,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
info->mFromName = name;
info->mDesc = message;
info->mHost = msg->getSender();
- //if (((is_busy && !is_owned_by_me) || is_muted))
+ //if (((is_do_not_disturb && !is_owned_by_me) || is_muted))
if (is_muted)
{
// Prefetch the offered item so that it can be discarded by the appropriate observer. (EXT-4331)
@@ -2659,9 +2749,11 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
// Same as closing window
info->forceResponse(IOR_DECLINE);
}
- else if (is_busy && dialog != IM_TASK_INVENTORY_OFFERED) // busy mode must not affect interaction with objects (STORM-565)
+ // old logic: busy mode must not affect interaction with objects (STORM-565)
+ // new logic: inventory offers from in-world objects should be auto-declined (CHUI-519)
+ else if (is_do_not_disturb && dialog == IM_TASK_INVENTORY_OFFERED)
{
- // Until throttling is implemented, busy mode should reject inventory instead of silently
+ // Until throttling is implemented, do not disturb mode should reject inventory instead of silently
// accepting it. SEE SL-39554
info->forceResponse(IOR_DECLINE);
}
@@ -2704,49 +2796,9 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
}
break;
- case IM_SESSION_SEND:
- {
- if (!is_linden && is_busy)
- {
- return;
- }
-
- // Only show messages if we have a session open (which
- // should happen after you get an "invitation"
- if ( !gIMMgr->hasSession(session_id) )
- {
- return;
- }
-
- // standard message, not from system
- std::string saved;
- if(offline == IM_OFFLINE)
- {
- saved = llformat("(Saved %s) ", formatted_time(timestamp).c_str());
- }
- buffer = saved + message;
- BOOL is_this_agent = FALSE;
- if(from_id == gAgentID)
- {
- is_this_agent = TRUE;
- }
- gIMMgr->addMessage(
- session_id,
- from_id,
- name,
- buffer,
- ll_safe_string((char*)binary_bucket),
- IM_SESSION_INVITE,
- parent_estate_id,
- region_id,
- position,
- true);
- }
- break;
-
case IM_FROM_TASK:
{
- if (is_busy && !is_owned_by_me)
+ if (is_do_not_disturb && !is_owned_by_me)
{
return;
}
@@ -2770,7 +2822,11 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
chat.mSourceType = CHAT_SOURCE_OBJECT;
- if(SYSTEM_FROM == name)
+ // To conclude that the source type of message is CHAT_SOURCE_SYSTEM it's not
+ // enough to check only from name (i.e. fromName = "Second Life"). For example
+ // source type of messages from objects called "Second Life" should not be CHAT_SOURCE_SYSTEM.
+ bool chat_from_system = (SYSTEM_FROM == name) && region_id.isNull() && position.isNull();
+ if(chat_from_system)
{
// System's UUID is NULL (fixes EXT-4766)
chat.mFromID = LLUUID::null;
@@ -2794,13 +2850,12 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
// Note: lie to Nearby Chat, pretending that this is NOT an IM, because
// IMs from obejcts don't open IM sessions.
- LLNearbyChat* nearby_chat = LLNearbyChat::getInstance();
- if(SYSTEM_FROM != name && nearby_chat)
+ LLFloaterIMNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat");
+ if(!chat_from_system && nearby_chat)
{
chat.mOwnerID = from_id;
LLSD args;
args["slurl"] = location;
- args["type"] = LLNotificationsUI::NT_NEARBYCHAT;
// Look for IRC-style emotes here so object name formatting is correct
std::string prefix = message.substr(0, 4);
@@ -2814,7 +2869,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
//Object IMs send with from name: 'Second Life' need to be displayed also in notification toasts (EXT-1590)
- if (SYSTEM_FROM != name) break;
+ if (!chat_from_system) break;
LLSD substitutions;
substitutions["NAME"] = name;
@@ -2839,8 +2894,78 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
LLPostponedNotification::add<LLPostponedServerObjectNotification>(params, from_id, from_group);
}
break;
+
+ case IM_SESSION_SEND: // ad-hoc or group IMs
+
+ // Only show messages if we have a session open (which
+ // should happen after you get an "invitation"
+ if ( !gIMMgr->hasSession(session_id) )
+ {
+ return;
+ }
+
+ else if (offline == IM_ONLINE && is_do_not_disturb)
+ {
+
+ // return a standard "do not disturb" message, but only do it to online IM
+ // (i.e. not other auto responses and not store-and-forward IM)
+ if (!gIMMgr->hasSession(session_id))
+ {
+ // if there is not a panel for this conversation (i.e. it is a new IM conversation
+ // initiated by the other party) then...
+ send_do_not_disturb_message(msg, from_id, session_id);
+ }
+
+ // now store incoming IM in chat history
+
+ buffer = message;
+
+ LL_INFOS("Messaging") << "process_improved_im: session_id( " << session_id << " ), from_id( " << from_id << " )" << LL_ENDL;
+
+ // add to IM panel, but do not bother the user
+ gIMMgr->addMessage(
+ session_id,
+ from_id,
+ name,
+ buffer,
+ IM_OFFLINE == offline,
+ ll_safe_string((char*)binary_bucket),
+ IM_SESSION_INVITE,
+ parent_estate_id,
+ region_id,
+ position,
+ true);
+ }
+ else
+ {
+ // standard message, not from system
+ std::string saved;
+ if(offline == IM_OFFLINE)
+ {
+ saved = llformat("(Saved %s) ", formatted_time(timestamp).c_str());
+ }
+
+ buffer = saved + message;
+
+ LL_INFOS("Messaging") << "process_improved_im: session_id( " << session_id << " ), from_id( " << from_id << " )" << LL_ENDL;
+
+ gIMMgr->addMessage(
+ session_id,
+ from_id,
+ name,
+ buffer,
+ IM_OFFLINE == offline,
+ ll_safe_string((char*)binary_bucket),
+ IM_SESSION_INVITE,
+ parent_estate_id,
+ region_id,
+ position,
+ true);
+ }
+ break;
+
case IM_FROM_TASK_AS_ALERT:
- if (is_busy && !is_owned_by_me)
+ if (is_do_not_disturb && !is_owned_by_me)
{
return;
}
@@ -2851,43 +2976,82 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
LLNotificationsUtil::add("ObjectMessage", args);
}
break;
- case IM_BUSY_AUTO_RESPONSE:
+ case IM_DO_NOT_DISTURB_AUTO_RESPONSE:
if (is_muted)
{
- LL_DEBUGS("Messaging") << "Ignoring busy response from " << from_id << LL_ENDL;
+ LL_DEBUGS("Messaging") << "Ignoring do-not-disturb response from " << from_id << LL_ENDL;
return;
}
else
{
- // TODO: after LLTrans hits release, get "busy response" into translatable file
- buffer = llformat("%s (%s): %s", name.c_str(), "busy response", message.c_str());
- gIMMgr->addMessage(session_id, from_id, name, buffer);
+ gIMMgr->addMessage(session_id, from_id, name, message);
}
break;
case IM_LURE_USER:
+ case IM_TELEPORT_REQUEST:
{
if (is_muted)
{
return;
}
- else if (is_busy)
+ else if (is_do_not_disturb)
{
- busy_message(msg,from_id);
+ send_do_not_disturb_message(msg, from_id);
}
else
{
LLVector3 pos, look_at;
U64 region_handle(0);
- U8 region_access(0);
+ U8 region_access(SIM_ACCESS_MIN);
std::string region_info = ll_safe_string((char*)binary_bucket, binary_bucket_size);
std::string region_access_str = LLStringUtil::null;
std::string region_access_icn = LLStringUtil::null;
+ std::string region_access_lc = LLStringUtil::null;
+
+ bool canUserAccessDstRegion = true;
+ bool doesUserRequireMaturityIncrease = false;
- if (parse_lure_bucket(region_info, region_handle, pos, look_at, region_access))
+ // Do not parse the (empty) lure bucket for TELEPORT_REQUEST
+ if (IM_TELEPORT_REQUEST != dialog && parse_lure_bucket(region_info, region_handle, pos, look_at, region_access))
{
region_access_str = LLViewerRegion::accessToString(region_access);
region_access_icn = LLViewerRegion::getAccessIcon(region_access);
+ region_access_lc = region_access_str;
+ LLStringUtil::toLower(region_access_lc);
+
+ if (!gAgent.isGodlike())
+ {
+ switch (region_access)
+ {
+ case SIM_ACCESS_MIN :
+ case SIM_ACCESS_PG :
+ break;
+ case SIM_ACCESS_MATURE :
+ if (gAgent.isTeen())
+ {
+ canUserAccessDstRegion = false;
+ }
+ else if (gAgent.prefersPG())
+ {
+ doesUserRequireMaturityIncrease = true;
+ }
+ break;
+ case SIM_ACCESS_ADULT :
+ if (!gAgent.isAdult())
+ {
+ canUserAccessDstRegion = false;
+ }
+ else if (!gAgent.prefersAdult())
+ {
+ doesUserRequireMaturityIncrease = true;
+ }
+ break;
+ default :
+ llassert(0);
+ break;
+ }
+ }
}
LLSD args;
@@ -2896,29 +3060,141 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
args["MESSAGE"] = message;
args["MATURITY_STR"] = region_access_str;
args["MATURITY_ICON"] = region_access_icn;
+ args["REGION_CONTENT_MATURITY"] = region_access_lc;
LLSD payload;
payload["from_id"] = from_id;
payload["lure_id"] = session_id;
payload["godlike"] = FALSE;
+ payload["region_maturity"] = region_access;
+
+ if (!canUserAccessDstRegion)
+ {
+ LLNotification::Params params("TeleportOffered_MaturityBlocked");
+ params.substitutions = args;
+ params.payload = payload;
+ LLPostponedNotification::add<LLPostponedOfferNotification>( params, from_id, false);
+ send_simple_im(from_id, LLTrans::getString("TeleportMaturityExceeded"), IM_NOTHING_SPECIAL, session_id);
+ send_simple_im(from_id, LLStringUtil::null, IM_LURE_DECLINED, session_id);
+ }
+ else if (doesUserRequireMaturityIncrease)
+ {
+ LLNotification::Params params("TeleportOffered_MaturityExceeded");
+ params.substitutions = args;
+ params.payload = payload;
+ LLPostponedNotification::add<LLPostponedOfferNotification>( params, from_id, false);
+ }
+ else
+ {
+ LLNotification::Params params;
+ if (IM_LURE_USER == dialog)
+ {
+ params.name = "TeleportOffered";
+ params.functor.name = "TeleportOffered";
+ }
+ else if (IM_TELEPORT_REQUEST == dialog)
+ {
+ params.name = "TeleportRequest";
+ params.functor.name = "TeleportRequest";
+ }
- LLNotification::Params params("TeleportOffered");
params.substitutions = args;
params.payload = payload;
LLPostponedNotification::add<LLPostponedOfferNotification>( params, from_id, false);
}
+ }
}
break;
case IM_GODLIKE_LURE_USER:
{
+ LLVector3 pos, look_at;
+ U64 region_handle(0);
+ U8 region_access(SIM_ACCESS_MIN);
+ std::string region_info = ll_safe_string((char*)binary_bucket, binary_bucket_size);
+ std::string region_access_str = LLStringUtil::null;
+ std::string region_access_icn = LLStringUtil::null;
+ std::string region_access_lc = LLStringUtil::null;
+
+ bool canUserAccessDstRegion = true;
+ bool doesUserRequireMaturityIncrease = false;
+
+ if (parse_lure_bucket(region_info, region_handle, pos, look_at, region_access))
+ {
+ region_access_str = LLViewerRegion::accessToString(region_access);
+ region_access_icn = LLViewerRegion::getAccessIcon(region_access);
+ region_access_lc = region_access_str;
+ LLStringUtil::toLower(region_access_lc);
+
+ if (!gAgent.isGodlike())
+ {
+ switch (region_access)
+ {
+ case SIM_ACCESS_MIN :
+ case SIM_ACCESS_PG :
+ break;
+ case SIM_ACCESS_MATURE :
+ if (gAgent.isTeen())
+ {
+ canUserAccessDstRegion = false;
+ }
+ else if (gAgent.prefersPG())
+ {
+ doesUserRequireMaturityIncrease = true;
+ }
+ break;
+ case SIM_ACCESS_ADULT :
+ if (!gAgent.isAdult())
+ {
+ canUserAccessDstRegion = false;
+ }
+ else if (!gAgent.prefersAdult())
+ {
+ doesUserRequireMaturityIncrease = true;
+ }
+ break;
+ default :
+ llassert(0);
+ break;
+ }
+ }
+ }
+
+ LLSD args;
+ // *TODO: Translate -> [FIRST] [LAST] (maybe)
+ args["NAME_SLURL"] = LLSLURL("agent", from_id, "about").getSLURLString();
+ args["MESSAGE"] = message;
+ args["MATURITY_STR"] = region_access_str;
+ args["MATURITY_ICON"] = region_access_icn;
+ args["REGION_CONTENT_MATURITY"] = region_access_lc;
LLSD payload;
payload["from_id"] = from_id;
payload["lure_id"] = session_id;
payload["godlike"] = TRUE;
+ payload["region_maturity"] = region_access;
+
+ if (!canUserAccessDstRegion)
+ {
+ LLNotification::Params params("TeleportOffered_MaturityBlocked");
+ params.substitutions = args;
+ params.payload = payload;
+ LLPostponedNotification::add<LLPostponedOfferNotification>( params, from_id, false);
+ send_simple_im(from_id, LLTrans::getString("TeleportMaturityExceeded"), IM_NOTHING_SPECIAL, session_id);
+ send_simple_im(from_id, LLStringUtil::null, IM_LURE_DECLINED, session_id);
+ }
+ else if (doesUserRequireMaturityIncrease)
+ {
+ LLNotification::Params params("TeleportOffered_MaturityExceeded");
+ params.substitutions = args;
+ params.payload = payload;
+ LLPostponedNotification::add<LLPostponedOfferNotification>( params, from_id, false);
+ }
+ else
+ {
// do not show a message box, because you're about to be
// teleported.
LLNotifications::instance().forceResponse(LLNotification::Params("TeleportOffered").payload(payload), 0);
}
+ }
break;
case IM_GOTO_URL:
@@ -2953,30 +3229,46 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
payload["online"] = (offline == IM_ONLINE);
payload["sender"] = msg->getSender().getIPandPort();
- if (is_busy)
+ bool add_notification = true;
+ for (LLToastNotifyPanel::instance_iter ti(LLToastNotifyPanel::beginInstances())
+ , tend(LLToastNotifyPanel::endInstances()); ti != tend; ++ti)
{
- busy_message(msg, from_id);
- LLNotifications::instance().forceResponse(LLNotification::Params("OfferFriendship").payload(payload), 1);
+ LLToastNotifyPanel& panel = *ti;
+ const std::string& notification_name = panel.getNotificationName();
+ if (notification_name == "OfferFriendship" && panel.isControlPanelEnabled())
+ {
+ add_notification = false;
+ break;
+ }
}
- else if (is_muted)
+
+ if (is_muted && add_notification)
{
LLNotifications::instance().forceResponse(LLNotification::Params("OfferFriendship").payload(payload), 1);
}
else
{
- args["NAME_SLURL"] = LLSLURL("agent", from_id, "about").getSLURLString();
- if(message.empty())
+ if (is_do_not_disturb)
{
- //support for frienship offers from clients before July 2008
- LLNotificationsUtil::add("OfferFriendshipNoMessage", args, payload);
+ send_do_not_disturb_message(msg, from_id);
}
- else
+ args["NAME_SLURL"] = LLSLURL("agent", from_id, "about").getSLURLString();
+
+ if (add_notification)
{
- args["[MESSAGE]"] = message;
- LLNotification::Params params("OfferFriendship");
- params.substitutions = args;
- params.payload = payload;
- LLPostponedNotification::add<LLPostponedOfferNotification>( params, from_id, false);
+ if(message.empty())
+ {
+ //support for frienship offers from clients before July 2008
+ LLNotificationsUtil::add("OfferFriendshipNoMessage", args, payload);
+ }
+ else
+ {
+ args["[MESSAGE]"] = message;
+ LLNotification::Params params("OfferFriendship");
+ params.substitutions = args;
+ params.payload = payload;
+ LLPostponedNotification::add<LLPostponedOfferNotification>( params, from_id, false);
+ }
}
}
}
@@ -2996,12 +3288,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
args["NAME"] = name;
LLSD payload;
payload["from_id"] = from_id;
- LLAvatarNameCache::get(from_id, boost::bind(&notification_display_name_callback,
- _1,
- _2,
- "FriendshipAccepted",
- args,
- payload));
+ LLAvatarNameCache::get(from_id, boost::bind(&notification_display_name_callback,_1,_2,"FriendshipAccepted",args,payload));
}
break;
@@ -3019,15 +3306,15 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
}
}
-void busy_message (LLMessageSystem* msg, LLUUID from_id)
+void send_do_not_disturb_message (LLMessageSystem* msg, const LLUUID& from_id, const LLUUID& session_id)
{
- if (gAgent.getBusy())
+ if (gAgent.isDoNotDisturb())
{
std::string my_name;
LLAgentUI::buildFullname(my_name);
- std::string response = gSavedPerAccountSettings.getString("BusyModeResponse");
+ std::string response = gSavedPerAccountSettings.getString("DoNotDisturbModeResponse");
pack_instant_message(
- gMessageSystem,
+ msg,
gAgent.getID(),
FALSE,
gAgent.getSessionID(),
@@ -3035,7 +3322,8 @@ void busy_message (LLMessageSystem* msg, LLUUID from_id)
my_name,
response,
IM_ONLINE,
- IM_BUSY_AUTO_RESPONSE);
+ IM_DO_NOT_DISTURB_AUTO_RESPONSE,
+ session_id);
gAgent.sendReliableMessage();
}
}
@@ -3070,7 +3358,7 @@ bool callingcard_offer_callback(const LLSD& notification, const LLSD& response)
msg->nextBlockFast(_PREHASH_TransactionBlock);
msg->addUUIDFast(_PREHASH_TransactionID, notification["payload"]["transaction_id"].asUUID());
msg->sendReliable(LLHost(notification["payload"]["sender"].asString()));
- busy_message(msg, notification["payload"]["source_id"].asUUID());
+ send_do_not_disturb_message(msg, notification["payload"]["source_id"].asUUID());
break;
default:
// close button probably, possibly timed out
@@ -3112,7 +3400,7 @@ void process_offer_callingcard(LLMessageSystem* msg, void**)
if(!source_name.empty())
{
- if (gAgent.getBusy()
+ if (gAgent.isDoNotDisturb()
|| LLMuteList::getInstance()->isMuted(source_id, source_name, LLMute::flagTextChat))
{
// automatically decline offer
@@ -3152,9 +3440,9 @@ public :
{
}
- static boost::intrusive_ptr<ChatTranslationReceiver> build(const std::string &from_lang, const std::string &to_lang, const std::string &mesg, const LLChat &chat, const LLSD &toast_args)
+ static ChatTranslationReceiver* build(const std::string &from_lang, const std::string &to_lang, const std::string &mesg, const LLChat &chat, const LLSD &toast_args)
{
- return boost::intrusive_ptr<ChatTranslationReceiver>(new ChatTranslationReceiver(from_lang, to_lang, mesg, chat, toast_args));
+ return new ChatTranslationReceiver(from_lang, to_lang, mesg, chat, toast_args);
}
protected:
@@ -3198,7 +3486,6 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)
LLColor4 color(1.0f, 1.0f, 1.0f, 1.0f);
LLUUID from_id;
LLUUID owner_id;
- BOOL is_owned_by_me = FALSE;
LLViewerObject* chatter;
msg->getString("ChatData", "FromName", from_name);
@@ -3229,7 +3516,7 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)
LLAvatarName av_name;
if (LLAvatarNameCache::get(from_id, &av_name))
{
- chat.mFromName = av_name.mDisplayName;
+ chat.mFromName = av_name.getDisplayName();
}
else
{
@@ -3241,7 +3528,7 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)
chat.mFromName = from_name;
}
- BOOL is_busy = gAgent.getBusy();
+ BOOL is_do_not_disturb = gAgent.isDoNotDisturb();
BOOL is_muted = FALSE;
BOOL is_linden = FALSE;
@@ -3275,7 +3562,7 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)
// record last audible utterance
if (is_audible
- && (is_linden || (!is_muted && !is_busy)))
+ && (is_linden || (!is_muted && !is_do_not_disturb)))
{
if (chat.mChatType != CHAT_TYPE_START
&& chat.mChatType != CHAT_TYPE_STOP)
@@ -3283,13 +3570,11 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)
gAgent.heardChat(chat.mFromID);
}
}
-
- is_owned_by_me = chatter->permYouOwner();
}
if (is_audible)
{
- BOOL visible_in_chat_bubble = FALSE;
+ //BOOL visible_in_chat_bubble = FALSE;
color.setVec(1.f,1.f,1.f,1.f);
msg->getStringFast(_PREHASH_ChatData, _PREHASH_Message, mesg);
@@ -3370,9 +3655,9 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)
LLLocalSpeakerMgr::getInstance()->setSpeakerTyping(from_id, FALSE);
((LLVOAvatar*)chatter)->stopTyping();
- if (!is_muted && !is_busy)
+ if (!is_muted && !is_do_not_disturb)
{
- visible_in_chat_bubble = gSavedSettings.getBOOL("UseChatBubbles");
+ //visible_in_chat_bubble = gSavedSettings.getBOOL("UseChatBubbles");
std::string formated_msg = "";
LLViewerChat::formatChatMsg(chat, formated_msg);
LLChat chat_bubble = chat;
@@ -3403,7 +3688,6 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)
// pass owner_id to chat so that we can display the remote
// object inspect for an object that is chatting with you
LLSD args;
- args["type"] = LLNotificationsUI::NT_NEARBYCHAT;
chat.mOwnerID = owner_id;
if (gSavedSettings.getBOOL("TranslateChat") && chat.mSourceType != CHAT_SOURCE_SYSTEM)
@@ -3422,6 +3706,12 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)
{
LLNotificationsUI::LLNotificationManager::instance().onChat(chat, args);
}
+
+ LLSD msg_notify = LLSD(LLSD::emptyMap());
+ msg_notify["session_id"] = LLUUID();
+ msg_notify["from_id"] = chat.mFromID;
+ msg_notify["source_type"] = chat.mSourceType;
+ on_new_message(msg_notify);
}
}
@@ -3441,6 +3731,9 @@ void process_teleport_start(LLMessageSystem *msg, void**)
LL_DEBUGS("Messaging") << "Got TeleportStart with TeleportFlags=" << teleport_flags << ". gTeleportDisplay: " << gTeleportDisplay << ", gAgent.mTeleportState: " << gAgent.getTeleportState() << LL_ENDL;
+ // *NOTE: The server sends two StartTeleport packets when you are teleporting to a LM
+ LLViewerMessage::getInstance()->mTeleportStartedSignal();
+
if (teleport_flags & TELEPORT_FLAGS_DISABLE_CANCEL)
{
gViewerWindow->setProgressCancelButtonVisible(FALSE);
@@ -3460,11 +3753,17 @@ void process_teleport_start(LLMessageSystem *msg, void**)
make_ui_sound("UISndTeleportOut");
LL_INFOS("Messaging") << "Teleport initiated by remote TeleportStart message with TeleportFlags: " << teleport_flags << LL_ENDL;
+
// Don't call LLFirstUse::useTeleport here because this could be
// due to being killed, which would send you home, not to a Telehub
}
}
+boost::signals2::connection LLViewerMessage::setTeleportStartedCallback(teleport_started_callback_t cb)
+{
+ return mTeleportStartedSignal.connect(cb);
+}
+
void process_teleport_progress(LLMessageSystem* msg, void**)
{
LLUUID agent_id;
@@ -3535,19 +3834,6 @@ public:
LLInventoryModel::EXCLUDE_TRASH,
is_card);
}
- LLSD args;
- if ( land_items.count() > 0 )
- { // Show notification that they can now teleport to landmarks. Use a random landmark from the inventory
- S32 random_land = ll_rand( land_items.count() - 1 );
- args["NAME"] = land_items[random_land]->getName();
- LLNotificationsUtil::add("TeleportToLandmark",args);
- }
- if ( card_items.count() > 0 )
- { // Show notification that they can now contact people. Use a random calling card from the inventory
- S32 random_card = ll_rand( card_items.count() - 1 );
- args["NAME"] = card_items[random_card]->getName();
- LLNotificationsUtil::add("TeleportToPerson",args);
- }
gInventory.removeObserver(this);
delete this;
@@ -3734,6 +4020,7 @@ void process_avatar_init_complete(LLMessageSystem* msg, void**)
void process_agent_movement_complete(LLMessageSystem* msg, void**)
{
+ gShiftFrame = true;
gAgentMovementCompleted = true;
LLUUID agent_id;
@@ -3823,18 +4110,6 @@ void process_agent_movement_complete(LLMessageSystem* msg, void**)
if (isAgentAvatarValid())
{
- // Chat the "back" SLURL. (DEV-4907)
-
- LLSLURL slurl;
- gAgent.getTeleportSourceSLURL(slurl);
- LLSD substitution = LLSD().with("[T_SLURL]", slurl.getSLURLString());
- std::string completed_from = LLAgent::sTeleportProgressMessages["completed_from"];
- LLStringUtil::format(completed_from, substitution);
-
- LLSD args;
- args["MESSAGE"] = completed_from;
- LLNotificationsUtil::add("SystemMessageTip", args);
-
// Set the new position
gAgentAvatarp->setPositionAgent(agent_pos);
gAgentAvatarp->clearChat();
@@ -3867,7 +4142,7 @@ void process_agent_movement_complete(LLMessageSystem* msg, void**)
{
LLTracker::stopTracking(NULL);
}
- else if ( is_teleport && !gAgent.getTeleportKeepsLookAt() )
+ else if ( is_teleport && !gAgent.getTeleportKeepsLookAt() && look_at.isExactlyZero())
{
//look at the beacon
LLVector3 global_agent_pos = agent_pos;
@@ -3899,14 +4174,14 @@ void process_agent_movement_complete(LLMessageSystem* msg, void**)
gAgent.setFlying(gAgent.canFly());
}
- // force simulator to recognize busy state
- if (gAgent.getBusy())
+ // force simulator to recognize do not disturb state
+ if (gAgent.isDoNotDisturb())
{
- gAgent.setBusy();
+ gAgent.setDoNotDisturb(true);
}
else
{
- gAgent.clearBusy();
+ gAgent.setDoNotDisturb(false);
}
if (isAgentAvatarValid())
@@ -4064,6 +4339,8 @@ void send_agent_update(BOOL force_send, BOOL send_reliable)
head_rot_chg = dot(last_head_rot, head_rotation);
+ //static S32 msg_number = 0; // Used for diagnostic log messages
+
if (force_send ||
(cam_center_chg.magVec() > TRANSLATE_THRESHOLD) ||
(head_rot_chg < THRESHOLD_HEAD_ROT_QDOT) ||
@@ -4072,19 +4349,20 @@ void send_agent_update(BOOL force_send, BOOL send_reliable)
control_flag_change != 0 ||
flag_change != 0)
{
-/*
+ /* Diagnotics to show why we send the AgentUpdate message. Also un-commment the msg_number code above and below this block
+ msg_number += 1;
if (head_rot_chg < THRESHOLD_HEAD_ROT_QDOT)
{
//LL_INFOS("Messaging") << "head rot " << head_rotation << LL_ENDL;
- LL_INFOS("Messaging") << "head_rot_chg = " << head_rot_chg << LL_ENDL;
+ LL_INFOS("Messaging") << "msg " << msg_number << ", frame " << LLFrameTimer::getFrameCount() << ", head_rot_chg " << head_rot_chg << LL_ENDL;
}
if (cam_rot_chg.magVec() > ROTATION_THRESHOLD)
{
- LL_INFOS("Messaging") << "cam rot " << cam_rot_chg.magVec() << LL_ENDL;
+ LL_INFOS("Messaging") << "msg " << msg_number << ", frame " << LLFrameTimer::getFrameCount() << ", cam rot " << cam_rot_chg.magVec() << LL_ENDL;
}
if (cam_center_chg.magVec() > TRANSLATE_THRESHOLD)
{
- LL_INFOS("Messaging") << "cam center " << cam_center_chg.magVec() << LL_ENDL;
+ LL_INFOS("Messaging") << "msg " << msg_number << ", frame " << LLFrameTimer::getFrameCount() << ", cam center " << cam_center_chg.magVec() << LL_ENDL;
}
// if (drag_delta_chg.magVec() > TRANSLATE_THRESHOLD)
// {
@@ -4092,7 +4370,7 @@ void send_agent_update(BOOL force_send, BOOL send_reliable)
// }
if (control_flag_change)
{
- LL_INFOS("Messaging") << "dcf = " << control_flag_change << LL_ENDL;
+ LL_INFOS("Messaging") << "msg " << msg_number << ", frame " << LLFrameTimer::getFrameCount() << ", dcf = " << control_flag_change << LL_ENDL;
}
*/
@@ -4129,6 +4407,26 @@ void send_agent_update(BOOL force_send, BOOL send_reliable)
if (duplicate_count < DUP_MSGS && !gDisconnected)
{
+ /* More diagnostics to count AgentUpdate messages
+ static S32 update_sec = 0;
+ static S32 update_count = 0;
+ static S32 max_update_count = 0;
+ S32 cur_sec = lltrunc( LLTimer::getTotalSeconds() );
+ update_count += 1;
+ if (cur_sec != update_sec)
+ {
+ if (update_sec != 0)
+ {
+ update_sec = cur_sec;
+ //msg_number = 0;
+ max_update_count = llmax(max_update_count, update_count);
+ llinfos << "Sent " << update_count << " AgentUpdate messages per second, max is " << max_update_count << llendl;
+ }
+ update_sec = cur_sec;
+ update_count = 0;
+ }
+ */
+
LLFastTimer t(FTM_AGENT_UPDATE_SEND);
// Build the message
msg->newMessageFast(_PREHASH_AgentUpdate);
@@ -4199,7 +4497,6 @@ extern U32 gObjectBits;
void process_object_update(LLMessageSystem *mesgsys, void **user_data)
{
- LLMemType mt(LLMemType::MTYPE_OBJECT);
// Update the data counters
if (mesgsys->getReceiveCompressedSize())
{
@@ -4216,7 +4513,6 @@ void process_object_update(LLMessageSystem *mesgsys, void **user_data)
void process_compressed_object_update(LLMessageSystem *mesgsys, void **user_data)
{
- LLMemType mt(LLMemType::MTYPE_OBJECT);
// Update the data counters
if (mesgsys->getReceiveCompressedSize())
{
@@ -4233,7 +4529,6 @@ void process_compressed_object_update(LLMessageSystem *mesgsys, void **user_data
void process_cached_object_update(LLMessageSystem *mesgsys, void **user_data)
{
- LLMemType mt(LLMemType::MTYPE_OBJECT);
// Update the data counters
if (mesgsys->getReceiveCompressedSize())
{
@@ -4251,7 +4546,6 @@ void process_cached_object_update(LLMessageSystem *mesgsys, void **user_data)
void process_terse_object_update_improved(LLMessageSystem *mesgsys, void **user_data)
{
- LLMemType mt(LLMemType::MTYPE_OBJECT);
if (mesgsys->getReceiveCompressedSize())
{
gObjectBits += mesgsys->getReceiveCompressedSize() * 8;
@@ -4264,7 +4558,7 @@ void process_terse_object_update_improved(LLMessageSystem *mesgsys, void **user_
gObjectList.processCompressedObjectUpdate(mesgsys, user_data, OUT_TERSE_IMPROVED);
}
-static LLFastTimer::DeclareTimer FTM_PROCESS_OBJECTS("Process Objects");
+static LLFastTimer::DeclareTimer FTM_PROCESS_OBJECTS("Process Kill Objects");
void process_kill_object(LLMessageSystem *mesgsys, void **user_data)
@@ -4289,7 +4583,6 @@ void process_kill_object(LLMessageSystem *mesgsys, void **user_data)
if (id == LLUUID::null)
{
LL_DEBUGS("Messaging") << "Unknown kill for local " << local_id << LL_ENDL;
- gObjectList.mNumUnknownKills++;
continue;
}
else
@@ -4297,8 +4590,6 @@ void process_kill_object(LLMessageSystem *mesgsys, void **user_data)
LL_DEBUGS("Messaging") << "Kill message for local " << local_id << LL_ENDL;
}
- LLSelectMgr::getInstance()->removeObjectFromSelections(id);
-
// ...don't kill the avatar
if (!(id == gAgentID))
{
@@ -4315,12 +4606,12 @@ void process_kill_object(LLMessageSystem *mesgsys, void **user_data)
// Do the kill
gObjectList.killObject(objectp);
}
- else
- {
- LL_WARNS("Messaging") << "Object in UUID lookup, but not on object list in kill!" << LL_ENDL;
- gObjectList.mNumUnknownKills++;
- }
}
+
+ // We should remove the object from selection after it is marked dead by gObjectList to make LLToolGrab,
+ // which is using the object, release the mouse capture correctly when the object dies.
+ // See LLToolGrab::handleHoverActive() and LLToolGrab::handleHoverNonPhysical().
+ LLSelectMgr::getInstance()->removeObjectFromSelections(id);
}
}
@@ -4630,6 +4921,18 @@ void process_sim_stats(LLMessageSystem *msg, void **user_data)
case LL_SIM_STAT_IOPUMPTIME:
LLViewerStats::getInstance()->mSimPumpIOMsec.addValue(stat_value);
break;
+ case LL_SIM_STAT_PCTSCRIPTSRUN:
+ LLViewerStats::getInstance()->mSimPctScriptsRun.addValue(stat_value);
+ break;
+ case LL_SIM_STAT_SIMAISTEPTIMEMS:
+ LLViewerStats::getInstance()->mSimSimAIStepMsec.addValue(stat_value);
+ break;
+ case LL_SIM_STAT_SKIPPEDAISILSTEPS_PS:
+ LLViewerStats::getInstance()->mSimSimSkippedSilhouetteSteps.addValue(stat_value);
+ break;
+ case LL_SIM_STAT_PCTSTEPPEDCHARACTERS:
+ LLViewerStats::getInstance()->mSimSimPctSteppedCharacters.addValue(stat_value);
+ break;
default:
// Used to be a commented out warning.
LL_DEBUGS("Messaging") << "Unknown stat id" << stat_id << LL_ENDL;
@@ -4663,9 +4966,19 @@ void process_sim_stats(LLMessageSystem *msg, void **user_data)
// Various hacks that aren't statistics, but are being handled here.
//
U32 max_tasks_per_region;
- U32 region_flags;
+ U64 region_flags;
msg->getU32("Region", "ObjectCapacity", max_tasks_per_region);
- msg->getU32("Region", "RegionFlags", region_flags);
+
+ if (msg->has(_PREHASH_RegionInfo))
+ {
+ msg->getU64("RegionInfo", "RegionFlagsExtended", region_flags);
+ }
+ else
+ {
+ U32 flags = 0;
+ msg->getU32("Region", "RegionFlags", flags);
+ region_flags = flags;
+ }
LLViewerRegion* regionp = gAgent.getRegion();
if (regionp)
@@ -4739,7 +5052,7 @@ void process_avatar_animation(LLMessageSystem *mesgsys, void **user_data)
LLViewerObject* object = gObjectList.findObject(object_id);
if (object)
{
- object->mFlags |= FLAGS_ANIM_SOURCE;
+ object->setFlagsWithoutUpdate(FLAGS_ANIM_SOURCE, TRUE);
BOOL anim_found = FALSE;
LLVOAvatar::AnimSourceIterator anim_it = avatarp->mAnimationSources.find(object_id);
@@ -4886,7 +5199,7 @@ void process_set_follow_cam_properties(LLMessageSystem *mesgsys, void **user_dat
LLViewerObject* objectp = gObjectList.findObject(source_id);
if (objectp)
{
- objectp->mFlags |= FLAGS_CAMERA_SOURCE;
+ objectp->setFlagsWithoutUpdate(FLAGS_CAMERA_SOURCE, TRUE);
}
S32 num_objects = mesgsys->getNumberOfBlocks("CameraProperty");
@@ -5381,31 +5694,41 @@ static void process_money_balance_reply_extended(LLMessageSystem* msg)
_1, _2, _3,
notification, final_args, payload));
}
- else {
- LLAvatarNameCache::get(name_id,
- boost::bind(&money_balance_avatar_notify,
- _1, _2,
- notification, final_args, payload));
+ else
+ {
+ LLAvatarNameCache::get(name_id, boost::bind(&money_balance_avatar_notify, _1, _2, notification, final_args, payload));
}
}
+bool handle_prompt_for_maturity_level_change_callback(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ if (0 == option)
+ {
+ // set the preference to the maturity of the region we're calling
+ U8 preferredMaturity = static_cast<U8>(notification["payload"]["_region_access"].asInteger());
+ gSavedSettings.setU32("PreferredMaturity", static_cast<U32>(preferredMaturity));
+ }
-bool handle_special_notification_callback(const LLSD& notification, const LLSD& response)
+ return false;
+}
+
+bool handle_prompt_for_maturity_level_change_and_reteleport_callback(const LLSD& notification, const LLSD& response)
{
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
if (0 == option)
{
// set the preference to the maturity of the region we're calling
- int preferredMaturity = notification["payload"]["_region_access"].asInteger();
- gSavedSettings.setU32("PreferredMaturity", preferredMaturity);
- gAgent.sendMaturityPreferenceToServer(preferredMaturity);
-
- // notify user that the maturity preference has been changed
- LLSD args;
- args["RATING"] = LLViewerRegion::accessToString(preferredMaturity);
- LLNotificationsUtil::add("PreferredMaturityChanged", args);
+ U8 preferredMaturity = static_cast<U8>(notification["payload"]["_region_access"].asInteger());
+ gSavedSettings.setU32("PreferredMaturity", static_cast<U32>(preferredMaturity));
+ gAgent.setMaturityRatingChangeDuringTeleport(preferredMaturity);
+ gAgent.restartFailedTeleportRequest();
+ }
+ else
+ {
+ gAgent.clearTeleportRequest();
}
return false;
@@ -5414,39 +5737,148 @@ bool handle_special_notification_callback(const LLSD& notification, const LLSD&
// some of the server notifications need special handling. This is where we do that.
bool handle_special_notification(std::string notificationID, LLSD& llsdBlock)
{
- int regionAccess = llsdBlock["_region_access"].asInteger();
- llsdBlock["REGIONMATURITY"] = LLViewerRegion::accessToString(regionAccess);
+ U8 regionAccess = static_cast<U8>(llsdBlock["_region_access"].asInteger());
+ std::string regionMaturity = LLViewerRegion::accessToString(regionAccess);
+ LLStringUtil::toLower(regionMaturity);
+ llsdBlock["REGIONMATURITY"] = regionMaturity;
- // we're going to throw the LLSD in there in case anyone ever wants to use it
- LLNotificationsUtil::add(notificationID+"_Notify", llsdBlock);
+ bool returnValue = false;
+ LLNotificationPtr maturityLevelNotification;
+ std::string notifySuffix = "_Notify";
+ if (regionAccess == SIM_ACCESS_MATURE)
+ {
+ if (gAgent.isTeen())
+ {
+ gAgent.clearTeleportRequest();
+ maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_AdultsOnlyContent", llsdBlock);
+ returnValue = true;
+
+ notifySuffix = "_NotifyAdultsOnly";
+ }
+ else if (gAgent.prefersPG())
+ {
+ maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_Change", llsdBlock, llsdBlock, handle_prompt_for_maturity_level_change_callback);
+ returnValue = true;
+ }
+ else if (LLStringUtil::compareStrings(notificationID, "RegionEntryAccessBlocked") == 0)
+ {
+ maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_PreferencesOutOfSync", llsdBlock, llsdBlock);
+ returnValue = true;
+ }
+ }
+ else if (regionAccess == SIM_ACCESS_ADULT)
+ {
+ if (!gAgent.isAdult())
+ {
+ gAgent.clearTeleportRequest();
+ maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_AdultsOnlyContent", llsdBlock);
+ returnValue = true;
+
+ notifySuffix = "_NotifyAdultsOnly";
+ }
+ else if (gAgent.prefersPG() || gAgent.prefersMature())
+ {
+ maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_Change", llsdBlock, llsdBlock, handle_prompt_for_maturity_level_change_callback);
+ returnValue = true;
+ }
+ else if (LLStringUtil::compareStrings(notificationID, "RegionEntryAccessBlocked") == 0)
+ {
+ maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_PreferencesOutOfSync", llsdBlock, llsdBlock);
+ returnValue = true;
+ }
+ }
+
+ if ((maturityLevelNotification == NULL) || maturityLevelNotification->isIgnored())
+ {
+ // Given a simple notification if no maturityLevelNotification is set or it is ignore
+ LLNotificationsUtil::add(notificationID + notifySuffix, llsdBlock);
+ }
+
+ return returnValue;
+}
+
+// some of the server notifications need special handling. This is where we do that.
+bool handle_teleport_access_blocked(LLSD& llsdBlock)
+{
+ std::string notificationID("TeleportEntryAccessBlocked");
+ U8 regionAccess = static_cast<U8>(llsdBlock["_region_access"].asInteger());
+ std::string regionMaturity = LLViewerRegion::accessToString(regionAccess);
+ LLStringUtil::toLower(regionMaturity);
+ llsdBlock["REGIONMATURITY"] = regionMaturity;
+ bool returnValue = false;
+ LLNotificationPtr maturityLevelNotification;
+ std::string notifySuffix = "_Notify";
if (regionAccess == SIM_ACCESS_MATURE)
{
if (gAgent.isTeen())
{
- LLNotificationsUtil::add(notificationID+"_KB", llsdBlock);
- return true;
+ gAgent.clearTeleportRequest();
+ maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_AdultsOnlyContent", llsdBlock);
+ returnValue = true;
+
+ notifySuffix = "_NotifyAdultsOnly";
}
else if (gAgent.prefersPG())
{
- LLNotificationsUtil::add(notificationID+"_Change", llsdBlock, llsdBlock, handle_special_notification_callback);
- return true;
+ if (gAgent.hasRestartableFailedTeleportRequest())
+ {
+ maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_ChangeAndReTeleport", llsdBlock, llsdBlock, handle_prompt_for_maturity_level_change_and_reteleport_callback);
+ returnValue = true;
+ }
+ else
+ {
+ gAgent.clearTeleportRequest();
+ maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_Change", llsdBlock, llsdBlock, handle_prompt_for_maturity_level_change_callback);
+ returnValue = true;
+ }
+ }
+ else
+ {
+ gAgent.clearTeleportRequest();
+ maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_PreferencesOutOfSync", llsdBlock, llsdBlock, handle_prompt_for_maturity_level_change_callback);
+ returnValue = true;
}
}
else if (regionAccess == SIM_ACCESS_ADULT)
{
if (!gAgent.isAdult())
{
- LLNotificationsUtil::add(notificationID+"_KB", llsdBlock);
- return true;
+ gAgent.clearTeleportRequest();
+ maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_AdultsOnlyContent", llsdBlock);
+ returnValue = true;
+
+ notifySuffix = "_NotifyAdultsOnly";
}
else if (gAgent.prefersPG() || gAgent.prefersMature())
{
- LLNotificationsUtil::add(notificationID+"_Change", llsdBlock, llsdBlock, handle_special_notification_callback);
- return true;
+ if (gAgent.hasRestartableFailedTeleportRequest())
+ {
+ maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_ChangeAndReTeleport", llsdBlock, llsdBlock, handle_prompt_for_maturity_level_change_and_reteleport_callback);
+ returnValue = true;
+ }
+ else
+ {
+ gAgent.clearTeleportRequest();
+ maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_Change", llsdBlock, llsdBlock, handle_prompt_for_maturity_level_change_callback);
+ returnValue = true;
+ }
+ }
+ else
+ {
+ gAgent.clearTeleportRequest();
+ maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_PreferencesOutOfSync", llsdBlock, llsdBlock, handle_prompt_for_maturity_level_change_callback);
+ returnValue = true;
}
+ }
+
+ if ((maturityLevelNotification == NULL) || maturityLevelNotification->isIgnored())
+ {
+ // Given a simple notification if no maturityLevelNotification is set or it is ignore
+ LLNotificationsUtil::add(notificationID + notifySuffix, llsdBlock);
}
- return false;
+
+ return returnValue;
}
bool attempt_standard_notification(LLMessageSystem* msgsystem)
@@ -5490,16 +5922,20 @@ bool attempt_standard_notification(LLMessageSystem* msgsystem)
RegionEntryAccessBlocked
RegionEntryAccessBlocked_Notify
+ RegionEntryAccessBlocked_NotifyAdultsOnly
RegionEntryAccessBlocked_Change
- RegionEntryAccessBlocked_KB
+ RegionEntryAccessBlocked_AdultsOnlyContent
+ RegionEntryAccessBlocked_ChangeAndReTeleport
LandClaimAccessBlocked
LandClaimAccessBlocked_Notify
+ LandClaimAccessBlocked_NotifyAdultsOnly
LandClaimAccessBlocked_Change
- LandClaimAccessBlocked_KB
+ LandClaimAccessBlocked_AdultsOnlyContent
LandBuyAccessBlocked
LandBuyAccessBlocked_Notify
+ LandBuyAccessBlocked_NotifyAdultsOnly
LandBuyAccessBlocked_Change
- LandBuyAccessBlocked_KB
+ LandBuyAccessBlocked_AdultsOnlyContent
-----------------------------------------------------------------------*/
if (handle_special_notification(notificationID, llsdBlock))
@@ -5507,6 +5943,15 @@ bool attempt_standard_notification(LLMessageSystem* msgsystem)
return true;
}
}
+ // HACK -- handle callbacks for specific alerts.
+ if( notificationID == "HomePositionSet" )
+ {
+ // save the home location image to disk
+ std::string snap_filename = gDirUtilp->getLindenUserDir();
+ snap_filename += gDirUtilp->getDirDelimiter();
+ snap_filename += SCREEN_HOME_FILENAME;
+ gViewerWindow->saveSnapshot(snap_filename, gViewerWindow->getWindowWidthRaw(), gViewerWindow->getWindowHeightRaw(), FALSE, FALSE);
+ }
LLNotificationsUtil::add(notificationID, llsdBlock);
return true;
@@ -5515,19 +5960,42 @@ bool attempt_standard_notification(LLMessageSystem* msgsystem)
}
+static void process_special_alert_messages(const std::string & message)
+{
+ // Do special handling for alert messages. This is a legacy hack, and any actual displayed
+ // text should be altered in the notifications.xml files.
+ if ( message == "You died and have been teleported to your home location")
+ {
+ LLViewerStats::getInstance()->incStat(LLViewerStats::ST_KILLED_COUNT);
+ }
+ else if( message == "Home position set." )
+ {
+ // save the home location image to disk
+ std::string snap_filename = gDirUtilp->getLindenUserDir();
+ snap_filename += gDirUtilp->getDirDelimiter();
+ snap_filename += SCREEN_HOME_FILENAME;
+ gViewerWindow->saveSnapshot(snap_filename, gViewerWindow->getWindowWidthRaw(), gViewerWindow->getWindowHeightRaw(), FALSE, FALSE);
+ }
+}
+
+
+
void process_agent_alert_message(LLMessageSystem* msgsystem, void** user_data)
{
// make sure the cursor is back to the usual default since the
// alert is probably due to some kind of error.
gViewerWindow->getWindow()->resetBusyCount();
+ std::string message;
+ msgsystem->getStringFast(_PREHASH_AlertData, _PREHASH_Message, message);
+
+ process_special_alert_messages(message);
+
if (!attempt_standard_notification(msgsystem))
{
BOOL modal = FALSE;
msgsystem->getBOOL("AlertData", "Modal", modal);
- std::string buffer;
- msgsystem->getStringFast(_PREHASH_AlertData, _PREHASH_Message, buffer);
- process_alert_core(buffer, modal);
+ process_alert_core(message, modal);
}
}
@@ -5542,31 +6010,44 @@ void process_alert_message(LLMessageSystem *msgsystem, void **user_data)
// alert is probably due to some kind of error.
gViewerWindow->getWindow()->resetBusyCount();
+ std::string message;
+ msgsystem->getStringFast(_PREHASH_AlertData, _PREHASH_Message, message);
+
+ process_special_alert_messages(message);
+
if (!attempt_standard_notification(msgsystem))
{
BOOL modal = FALSE;
- std::string buffer;
- msgsystem->getStringFast(_PREHASH_AlertData, _PREHASH_Message, buffer);
- process_alert_core(buffer, modal);
+ process_alert_core(message, modal);
}
}
-void process_alert_core(const std::string& message, BOOL modal)
+bool handle_not_age_verified_alert(const std::string &pAlertName)
{
- // HACK -- handle callbacks for specific alerts. It also is localized in notifications.xml
- if ( message == "You died and have been teleported to your home location")
+ LLNotificationPtr notification = LLNotificationsUtil::add(pAlertName);
+ if ((notification == NULL) || notification->isIgnored())
{
- LLViewerStats::getInstance()->incStat(LLViewerStats::ST_KILLED_COUNT);
+ LLNotificationsUtil::add(pAlertName + "_Notify");
}
- else if( message == "Home position set." )
+
+ return true;
+}
+
+bool handle_special_alerts(const std::string &pAlertName)
+{
+ bool isHandled = false;
+
+ if (LLStringUtil::compareStrings(pAlertName, "NotAgeVerified") == 0)
{
- // save the home location image to disk
- std::string snap_filename = gDirUtilp->getLindenUserDir();
- snap_filename += gDirUtilp->getDirDelimiter();
- snap_filename += SCREEN_HOME_FILENAME;
- gViewerWindow->saveSnapshot(snap_filename, gViewerWindow->getWindowWidthRaw(), gViewerWindow->getWindowHeightRaw(), FALSE, FALSE);
+
+ isHandled = handle_not_age_verified_alert(pAlertName);
}
+ return isHandled;
+}
+
+void process_alert_core(const std::string& message, BOOL modal)
+{
const std::string ALERT_PREFIX("ALERT: ");
const std::string NOTIFY_PREFIX("NOTIFY: ");
if (message.find(ALERT_PREFIX) == 0)
@@ -5574,8 +6055,11 @@ void process_alert_core(const std::string& message, BOOL modal)
// Allow the server to spawn a named alert so that server alerts can be
// translated out of English.
std::string alert_name(message.substr(ALERT_PREFIX.length()));
+ if (!handle_special_alerts(alert_name))
+ {
LLNotificationsUtil::add(alert_name);
}
+ }
else if (message.find(NOTIFY_PREFIX) == 0)
{
// Allow the server to spawn a named notification so that server notifications can be
@@ -5833,6 +6317,19 @@ void notify_cautioned_script_question(const LLSD& notification, const LLSD& resp
}
}
+void script_question_mute(const LLUUID& item_id, const std::string& object_name);
+
+bool unknown_script_question_cb(const LLSD& notification, const LLSD& response)
+{
+ // Only care if they muted the object here.
+ if ( response["Mute"] ) // mute
+ {
+ LLUUID task_id = notification["payload"]["task_id"].asUUID();
+ script_question_mute(task_id,notification["payload"]["object_name"].asString());
+ }
+ return false;
+}
+
bool script_question_cb(const LLSD& notification, const LLSD& response)
{
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
@@ -5883,34 +6380,42 @@ bool script_question_cb(const LLSD& notification, const LLSD& response)
if ( response["Mute"] ) // mute
{
- LLMuteList::getInstance()->add(LLMute(item_id, notification["payload"]["object_name"].asString(), LLMute::OBJECT));
-
- // purge the message queue of any previously queued requests from the same source. DEV-4879
- class OfferMatcher : public LLNotificationsUI::LLScreenChannel::Matcher
- {
- public:
- OfferMatcher(const LLUUID& to_block) : blocked_id(to_block) {}
- bool matches(const LLNotificationPtr notification) const
- {
- if (notification->getName() == "ScriptQuestionCaution"
- || notification->getName() == "ScriptQuestion")
- {
- return (notification->getPayload()["item_id"].asUUID() == blocked_id);
- }
- return false;
- }
- private:
- const LLUUID& blocked_id;
- };
-
- LLNotificationsUI::LLChannelManager::getInstance()->killToastsFromChannel(LLUUID(
- gSavedSettings.getString("NotificationChannelUUID")), OfferMatcher(item_id));
+ script_question_mute(task_id,notification["payload"]["object_name"].asString());
}
return false;
}
+
+void script_question_mute(const LLUUID& task_id, const std::string& object_name)
+{
+ LLMuteList::getInstance()->add(LLMute(task_id, object_name, LLMute::OBJECT));
+
+ // purge the message queue of any previously queued requests from the same source. DEV-4879
+ class OfferMatcher : public LLNotificationsUI::LLScreenChannel::Matcher
+ {
+ public:
+ OfferMatcher(const LLUUID& to_block) : blocked_id(to_block) {}
+ bool matches(const LLNotificationPtr notification) const
+ {
+ if (notification->getName() == "ScriptQuestionCaution"
+ || notification->getName() == "ScriptQuestion"
+ || notification->getName() == "UnknownScriptQuestion")
+ {
+ return (notification->getPayload()["task_id"].asUUID() == blocked_id);
+ }
+ return false;
+ }
+ private:
+ const LLUUID& blocked_id;
+ };
+
+ LLNotificationsUI::LLChannelManager::getInstance()->killToastsFromChannel(LLUUID(
+ gSavedSettings.getString("NotificationChannelUUID")), OfferMatcher(task_id));
+}
+
static LLNotificationFunctorRegistration script_question_cb_reg_1("ScriptQuestion", script_question_cb);
static LLNotificationFunctorRegistration script_question_cb_reg_2("ScriptQuestionCaution", script_question_cb);
+static LLNotificationFunctorRegistration unknown_script_question_cb_reg("UnknownScriptQuestion", unknown_script_question_cb);
void process_script_question(LLMessageSystem *msg, void **user_data)
{
@@ -5975,41 +6480,64 @@ void process_script_question(LLMessageSystem *msg, void **user_data)
LLSD args;
args["OBJECTNAME"] = object_name;
args["NAME"] = LLCacheName::cleanFullName(owner_name);
-
+ S32 known_questions = 0;
+ BOOL has_not_only_debit = questions ^ LSCRIPTRunTimePermissionBits[SCRIPT_PERMISSION_DEBIT];
// check the received permission flags against each permission
for (S32 i = 0; i < SCRIPT_PERMISSION_EOF; i++)
{
if (questions & LSCRIPTRunTimePermissionBits[i])
{
count++;
- script_question += " " + LLTrans::getString(SCRIPT_QUESTIONS[i]) + "\n";
-
+ known_questions |= LSCRIPTRunTimePermissionBits[i];
// check whether permission question should cause special caution dialog
caution |= (SCRIPT_QUESTION_IS_CAUTION[i]);
+
+ if (("ScriptTakeMoney" == SCRIPT_QUESTIONS[i]) && has_not_only_debit)
+ continue;
+
+ script_question += " " + LLTrans::getString(SCRIPT_QUESTIONS[i]) + "\n";
}
}
+
args["QUESTIONS"] = script_question;
- LLSD payload;
- payload["task_id"] = taskid;
- payload["item_id"] = itemid;
- payload["sender"] = sender.getIPandPort();
- payload["questions"] = questions;
- payload["object_name"] = object_name;
- payload["owner_name"] = owner_name;
-
- // check whether cautions are even enabled or not
- if (gSavedSettings.getBOOL("PermissionsCautionEnabled"))
- {
- // display the caution permissions prompt
- LLNotificationsUtil::add(caution ? "ScriptQuestionCaution" : "ScriptQuestion", args, payload);
+ if (known_questions != questions)
+ { // This is in addition to the normal dialog.
+ LLSD payload;
+ payload["task_id"] = taskid;
+ payload["item_id"] = itemid;
+ payload["object_name"] = object_name;
+
+ args["DOWNLOADURL"] = LLTrans::getString("ViewerDownloadURL");
+ LLNotificationsUtil::add("UnknownScriptQuestion",args,payload);
}
- else
+
+ if (known_questions)
{
- // fall back to default behavior if cautions are entirely disabled
- LLNotificationsUtil::add("ScriptQuestion", args, payload);
+ LLSD payload;
+ payload["task_id"] = taskid;
+ payload["item_id"] = itemid;
+ payload["sender"] = sender.getIPandPort();
+ payload["questions"] = known_questions;
+ payload["object_name"] = object_name;
+ payload["owner_name"] = owner_name;
+
+ // check whether cautions are even enabled or not
+ if (gSavedSettings.getBOOL("PermissionsCautionEnabled"))
+ {
+ if (caution)
+ {
+ args["FOOTERTEXT"] = (count > 1) ? LLTrans::getString("AdditionalPermissionsRequestHeader") + "\n\n" + script_question : "";
+ }
+ // display the caution permissions prompt
+ LLNotificationsUtil::add(caution ? "ScriptQuestionCaution" : "ScriptQuestion", args, payload);
+ }
+ else
+ {
+ // fall back to default behavior if cautions are entirely disabled
+ LLNotificationsUtil::add("ScriptQuestion", args, payload);
+ }
}
-
}
}
@@ -6151,6 +6679,9 @@ void process_teleport_failed(LLMessageSystem *msg, void**)
std::string big_reason;
LLSD args;
+ // Let the interested parties know that teleport failed.
+ LLViewerParcelMgr::getInstance()->onTeleportFailed();
+
// if we have additional alert data
if (msg->has(_PREHASH_AlertInfo) && msg->getSizeFast(_PREHASH_AlertInfo, _PREHASH_Message) > 0)
{
@@ -6180,7 +6711,7 @@ void process_teleport_failed(LLMessageSystem *msg, void**)
else
{
// change notification name in this special case
- if (handle_special_notification("RegionEntryAccessBlocked", llsd_block))
+ if (handle_teleport_access_blocked(llsd_block))
{
if( gAgent.getTeleportState() != LLAgent::TELEPORT_NONE )
{
@@ -6209,9 +6740,6 @@ void process_teleport_failed(LLMessageSystem *msg, void**)
LLNotificationsUtil::add("CouldNotTeleportReason", args);
- // Let the interested parties know that teleport failed.
- LLViewerParcelMgr::getInstance()->onTeleportFailed();
-
if( gAgent.getTeleportState() != LLAgent::TELEPORT_NONE )
{
gAgent.setTeleportState( LLAgent::TELEPORT_NONE );
@@ -6350,6 +6878,51 @@ void send_group_notice(const LLUUID& group_id,
bin_bucket_size);
}
+void send_lures(const LLSD& notification, const LLSD& response)
+{
+ std::string text = response["message"].asString();
+ LLSLURL slurl;
+ LLAgentUI::buildSLURL(slurl);
+ text.append("\r\n").append(slurl.getSLURLString());
+
+ LLMessageSystem* msg = gMessageSystem;
+ msg->newMessageFast(_PREHASH_StartLure);
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ msg->nextBlockFast(_PREHASH_Info);
+ msg->addU8Fast(_PREHASH_LureType, (U8)0); // sim will fill this in.
+ msg->addStringFast(_PREHASH_Message, text);
+ for(LLSD::array_const_iterator it = notification["payload"]["ids"].beginArray();
+ it != notification["payload"]["ids"].endArray();
+ ++it)
+ {
+ LLUUID target_id = it->asUUID();
+
+ msg->nextBlockFast(_PREHASH_TargetData);
+ msg->addUUIDFast(_PREHASH_TargetID, target_id);
+
+ // Record the offer.
+ {
+ std::string target_name;
+ gCacheName->getFullName(target_id, target_name); // for im log filenames
+ LLSD args;
+ args["TO_NAME"] = LLSLURL("agent", target_id, "displayname").getSLURLString();;
+
+ LLSD payload;
+
+ //*TODO please rewrite all keys to the same case, lower or upper
+ payload["from_id"] = target_id;
+ payload["SUPPRESS_TOAST"] = true;
+ LLNotificationsUtil::add("TeleportOfferSent", args, payload);
+
+ // Add the recepient to the recent people list.
+ LLRecentPeople::instance().add(target_id);
+ }
+ }
+ gAgent.sendReliableMessage();
+}
+
bool handle_lure_callback(const LLSD& notification, const LLSD& response)
{
static const unsigned OFFER_RECIPIENT_LIMIT = 250;
@@ -6363,51 +6936,12 @@ bool handle_lure_callback(const LLSD& notification, const LLSD& response)
LLNotificationsUtil::add("TooManyTeleportOffers", args);
return false;
}
-
- std::string text = response["message"].asString();
- LLSLURL slurl;
- LLAgentUI::buildSLURL(slurl);
- text.append("\r\n").append(slurl.getSLURLString());
+
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
if(0 == option)
{
- LLMessageSystem* msg = gMessageSystem;
- msg->newMessageFast(_PREHASH_StartLure);
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- msg->nextBlockFast(_PREHASH_Info);
- msg->addU8Fast(_PREHASH_LureType, (U8)0); // sim will fill this in.
- msg->addStringFast(_PREHASH_Message, text);
- for(LLSD::array_const_iterator it = notification["payload"]["ids"].beginArray();
- it != notification["payload"]["ids"].endArray();
- ++it)
- {
- LLUUID target_id = it->asUUID();
-
- msg->nextBlockFast(_PREHASH_TargetData);
- msg->addUUIDFast(_PREHASH_TargetID, target_id);
-
- // Record the offer.
- {
- std::string target_name;
- gCacheName->getFullName(target_id, target_name); // for im log filenames
- LLSD args;
- args["TO_NAME"] = LLSLURL("agent", target_id, "displayname").getSLURLString();;
-
- LLSD payload;
-
- //*TODO please rewrite all keys to the same case, lower or upper
- payload["from_id"] = target_id;
- payload["SUPPRESS_TOAST"] = true;
- LLNotificationsUtil::add("TeleportOfferSent", args, payload);
-
- // Add the recepient to the recent people list.
- LLRecentPeople::instance().add(target_id);
- }
- }
- gAgent.sendReliableMessage();
+ send_lures(notification, response);
}
return false;
@@ -6447,6 +6981,58 @@ void handle_lure(const uuid_vec_t& ids)
}
}
+bool teleport_request_callback(const LLSD& notification, const LLSD& response)
+{
+ LLUUID from_id = notification["payload"]["from_id"].asUUID();
+ if(from_id.isNull())
+ {
+ llwarns << "from_id is NULL" << llendl;
+ return false;
+ }
+
+ std::string from_name;
+ gCacheName->getFullName(from_id, from_name);
+
+ if(LLMuteList::getInstance()->isMuted(from_id) && !LLMuteList::getInstance()->isLinden(from_name))
+ {
+ return false;
+ }
+
+ S32 option = 0;
+ if (response.isInteger())
+ {
+ option = response.asInteger();
+ }
+ else
+ {
+ option = LLNotificationsUtil::getSelectedOption(notification, response);
+ }
+
+ switch(option)
+ {
+ // Yes
+ case 0:
+ {
+ LLSD dummy_notification;
+ dummy_notification["payload"]["ids"][0] = from_id;
+
+ LLSD dummy_response;
+ dummy_response["message"] = response["message"];
+
+ send_lures(dummy_notification, dummy_response);
+ }
+ break;
+
+ // No
+ case 1:
+ default:
+ break;
+ }
+
+ return false;
+}
+
+static LLNotificationFunctorRegistration teleport_request_callback_reg("TeleportRequest", teleport_request_callback);
void send_improved_im(const LLUUID& to_id,
const std::string& name,
@@ -6521,7 +7107,7 @@ void process_user_info_reply(LLMessageSystem* msg, void**)
std::string dir_visibility;
msg->getString( "UserData", "DirectoryVisibility", dir_visibility);
- LLFloaterPreference::updateUserInfo(dir_visibility, im_via_email, email);
+ LLFloaterPreference::updateUserInfo(dir_visibility, im_via_email);
LLFloaterSnapshot::setAgentEmail(email);
}
@@ -6826,8 +7412,12 @@ void process_script_teleport_request(LLMessageSystem* msg, void**)
LLFloaterWorldMap* instance = LLFloaterWorldMap::getInstance();
if(instance)
{
- instance->trackURL(
- sim_name, (S32)pos.mV[VX], (S32)pos.mV[VY], (S32)pos.mV[VZ]);
+ llinfos << "Object named " << object_name
+ << " is offering TP to region "
+ << sim_name << " position " << pos
+ << llendl;
+
+ instance->trackURL(sim_name, (S32)pos.mV[VX], (S32)pos.mV[VY], (S32)pos.mV[VZ]);
LLFloaterReg::showInstance("world_map", "center");
}
diff --git a/indra/newview/llviewermessage.h b/indra/newview/llviewermessage.h
index 46bfb2dad0..3237f3fbdd 100644..100755
--- a/indra/newview/llviewermessage.h
+++ b/indra/newview/llviewermessage.h
@@ -37,6 +37,9 @@
#include "llnotifications.h"
#include "llextendedstatus.h"
+#include <boost/function.hpp>
+#include <boost/signals2.hpp>
+
//
// Forward declarations
//
@@ -64,7 +67,6 @@ enum InventoryOfferResponse
BOOL can_afford_transaction(S32 cost);
void give_money(const LLUUID& uuid, LLViewerRegion* region, S32 amount, BOOL is_group = FALSE,
S32 trx_type = TRANS_GIFT, const std::string& desc = LLStringUtil::null);
-void busy_message (LLMessageSystem* msg, LLUUID from_id);
void process_logout_reply(LLMessageSystem* msg, void**);
void process_layer_data(LLMessageSystem *mesgsys, void **user_data);
@@ -150,6 +152,8 @@ void send_group_notice(const LLUUID& group_id,
const std::string& message,
const LLInventoryItem* item);
+void send_do_not_disturb_message (LLMessageSystem* msg, const LLUUID& from_id, const LLUUID& session_id = LLUUID::null);
+
void handle_lure(const LLUUID& invitee);
void handle_lure(const uuid_vec_t& ids);
@@ -205,6 +209,15 @@ bool highlight_offered_object(const LLUUID& obj_id);
void set_dad_inventory_item(LLInventoryItem* inv_item, const LLUUID& into_folder_uuid);
void set_dad_inbox_object(const LLUUID& object_id);
+class LLViewerMessage : public LLSingleton<LLViewerMessage>
+{
+public:
+ typedef boost::function<void()> teleport_started_callback_t;
+ typedef boost::signals2::signal<void()> teleport_started_signal_t;
+ boost::signals2::connection setTeleportStartedCallback(teleport_started_callback_t cb);
+
+ teleport_started_signal_t mTeleportStartedSignal;
+};
class LLOfferInfo : public LLNotificationResponderInterface
{
@@ -216,6 +229,7 @@ public:
void forceResponse(InventoryOfferResponse response);
+ static std::string mResponderType;
EInstantMessage mIM;
LLUUID mFromID;
BOOL mFromGroup;
@@ -253,5 +267,3 @@ private:
void process_feature_disabled_message(LLMessageSystem* msg, void**);
#endif
-
-
diff --git a/indra/newview/llviewernetwork.cpp b/indra/newview/llviewernetwork.cpp
index ef5c65eb87..e7821d4b9e 100644..100755
--- a/indra/newview/llviewernetwork.cpp
+++ b/indra/newview/llviewernetwork.cpp
@@ -1,4 +1,4 @@
-/**
+/**
* @file llviewernetwork.cpp
* @author James Cook, Richard Nelson
* @brief Networking constants and globals for viewer.
@@ -6,21 +6,21 @@
* $LicenseInfo:firstyear=2006&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$
*/
@@ -34,13 +34,43 @@
#include "lltrans.h"
#include "llweb.h"
-
-const char* DEFAULT_LOGIN_PAGE = "http://viewer-login.agni.lindenlab.com/";
-const char* SYSTEM_GRID_SLURL_BASE = "secondlife://%s/secondlife/";
-const char* MAIN_GRID_SLURL_BASE = "http://maps.secondlife.com/secondlife/";
-const char* SYSTEM_GRID_APP_SLURL_BASE = "secondlife:///app";
+/// key used to store the grid, and the name attribute in the grid data
+const std::string GRID_VALUE = "keyname";
+/// the value displayed in the grid selector menu, and other human-oriented text
+const std::string GRID_LABEL_VALUE = "label";
+/// the value used on the --grid command line argument
+const std::string GRID_ID_VALUE = "grid_login_id";
+/// the url for the login cgi script
+const std::string GRID_LOGIN_URI_VALUE = "login_uri";
+/// url base for update queries
+const std::string GRID_UPDATE_SERVICE_URL = "update_query_url_base";
+///
+const std::string GRID_HELPER_URI_VALUE = "helper_uri";
+/// the splash page url
+const std::string GRID_LOGIN_PAGE_VALUE = "login_page";
+/// internal data on system grids
+const std::string GRID_IS_SYSTEM_GRID_VALUE = "system_grid";
+/// whether this is single or double names
+const std::string GRID_LOGIN_IDENTIFIER_TYPES = "login_identifier_types";
+
+// defines slurl formats associated with various grids.
+// we need to continue to support existing forms, as slurls
+// are shared between viewers that may not understand newer
+// forms.
+const std::string GRID_SLURL_BASE = "slurl_base";
+const std::string GRID_APP_SLURL_BASE = "app_slurl_base";
+
+const std::string DEFAULT_LOGIN_PAGE = "http://viewer-login.agni.lindenlab.com/";
+
+const std::string MAIN_GRID_LOGIN_URI = "https://login.agni.lindenlab.com/cgi-bin/login.cgi";
+
+const std::string SL_UPDATE_QUERY_URL = "https://update.secondlife.com/update";
+
+const std::string MAIN_GRID_SLURL_BASE = "http://maps.secondlife.com/secondlife/";
+const std::string SYSTEM_GRID_APP_SLURL_BASE = "secondlife:///app";
+const char* SYSTEM_GRID_SLURL_BASE = "secondlife://%s/secondlife/";
const char* DEFAULT_SLURL_BASE = "https://%s/region/";
const char* DEFAULT_APP_SLURL_BASE = "x-grid-location-info://%s/app";
@@ -54,14 +84,17 @@ LLGridManager::LLGridManager()
// an attacker. Don't want someone snagging a password.
std::string grid_file = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS,
"grids.xml");
+ LL_DEBUGS("GridManager")<<LL_ENDL;
+
initialize(grid_file);
-
+
}
LLGridManager::LLGridManager(const std::string& grid_file)
{
// initialize with an explicity grid file for testing.
+ LL_DEBUGS("GridManager")<<LL_ENDL;
initialize(grid_file);
}
@@ -74,183 +107,85 @@ LLGridManager::LLGridManager(const std::string& grid_file)
//
// LLGridManager::initialze - initialize the list of known grids based
// on the fixed list of linden grids (fixed for security reasons)
-// the grids.xml file
-// and the command line.
+// and the grids.xml file
void LLGridManager::initialize(const std::string& grid_file)
{
// default grid list.
// Don't move to a modifiable file for security reasons,
mGrid.clear() ;
+
// set to undefined
mGridList = LLSD();
mGridFile = grid_file;
// as we don't want an attacker to override our grid list
// to point the default grid to an invalid grid
- addSystemGrid("None", "", "", "", DEFAULT_LOGIN_PAGE);
-
-
-
- addSystemGrid("Agni",
- MAINGRID,
- "https://login.agni.lindenlab.com/cgi-bin/login.cgi",
- "https://secondlife.com/helpers/",
- DEFAULT_LOGIN_PAGE);
- addSystemGrid("Aditi",
- "util.aditi.lindenlab.com",
- "https://login.aditi.lindenlab.com/cgi-bin/login.cgi",
+ addSystemGrid("Second Life Main Grid (Agni)",
+ MAINGRID,
+ MAIN_GRID_LOGIN_URI,
+ "https://secondlife.com/helpers/",
+ DEFAULT_LOGIN_PAGE,
+ SL_UPDATE_QUERY_URL,
+ "Agni");
+ addSystemGrid("Second Life Beta Test Grid (Aditi)",
+ "util.aditi.lindenlab.com",
+ "https://login.aditi.lindenlab.com/cgi-bin/login.cgi",
"http://aditi-secondlife.webdev.lindenlab.com/helpers/",
- DEFAULT_LOGIN_PAGE);
- addSystemGrid("Aruna",
- "util.aruna.lindenlab.com",
- "https://login.aruna.lindenlab.com/cgi-bin/login.cgi",
- "http://aruna-secondlife.webdev.lindenlab.com/helpers/",
- DEFAULT_LOGIN_PAGE);
- addSystemGrid("Bharati",
- "util.bharati.lindenlab.com",
- "https://login.bharati.lindenlab.com/cgi-bin/login.cgi",
- "http://bharati-secondlife.webdev.lindenlab.com/helpers/",
- DEFAULT_LOGIN_PAGE);
- addSystemGrid("Chandra",
- "util.chandra.lindenlab.com",
- "https://login.chandra.lindenlab.com/cgi-bin/login.cgi",
- "http://chandra-secondlife.webdev.lindenlab.com/helpers/",
- DEFAULT_LOGIN_PAGE);
- addSystemGrid("Damballah",
- "util.damballah.lindenlab.com",
- "https://login.damballah.lindenlab.com/cgi-bin/login.cgi",
- "http://damballah-secondlife.webdev.lindenlab.com/helpers/",
- DEFAULT_LOGIN_PAGE);
- addSystemGrid("Danu",
- "util.danu.lindenlab.com",
- "https://login.danu.lindenlab.com/cgi-bin/login.cgi",
- "http://danu-secondlife.webdev.lindenlab.com/helpers/",
- DEFAULT_LOGIN_PAGE);
- addSystemGrid("Durga",
- "util.durga.lindenlab.com",
- "https://login.durga.lindenlab.com/cgi-bin/login.cgi",
- "http://durga-secondlife.webdev.lindenlab.com/helpers/",
- DEFAULT_LOGIN_PAGE);
- addSystemGrid("Ganga",
- "util.ganga.lindenlab.com",
- "https://login.ganga.lindenlab.com/cgi-bin/login.cgi",
- "http://ganga-secondlife.webdev.lindenlab.com/helpers/",
- DEFAULT_LOGIN_PAGE);
- addSystemGrid("Mitra",
- "util.mitra.lindenlab.com",
- "https://login.mitra.lindenlab.com/cgi-bin/login.cgi",
- "http://mitra-secondlife.webdev.lindenlab.com/helpers/",
- DEFAULT_LOGIN_PAGE);
- addSystemGrid("Mohini",
- "util.mohini.lindenlab.com",
- "https://login.mohini.lindenlab.com/cgi-bin/login.cgi",
- "http://mohini-secondlife.webdev.lindenlab.com/helpers/",
- DEFAULT_LOGIN_PAGE);
- addSystemGrid("Nandi",
- "util.nandi.lindenlab.com",
- "https://login.nandi.lindenlab.com/cgi-bin/login.cgi",
- "http://nandi-secondlife.webdev.lindenlab.com/helpers/",
- DEFAULT_LOGIN_PAGE);
- addSystemGrid("Parvati",
- "util.parvati.lindenlab.com",
- "https://login.parvati.lindenlab.com/cgi-bin/login.cgi",
- "http://parvati-secondlife.webdev.lindenlab.com/helpers/",
- DEFAULT_LOGIN_PAGE);
- addSystemGrid("Radha",
- "util.radha.lindenlab.com",
- "https://login.radha.lindenlab.com/cgi-bin/login.cgi",
- "http://radha-secondlife.webdev.lindenlab.com/helpers/",
- DEFAULT_LOGIN_PAGE);
- addSystemGrid("Ravi",
- "util.ravi.lindenlab.com",
- "https://login.ravi.lindenlab.com/cgi-bin/login.cgi",
- "http://ravi-secondlife.webdev.lindenlab.com/helpers/",
- DEFAULT_LOGIN_PAGE);
- addSystemGrid("Siva",
- "util.siva.lindenlab.com",
- "https://login.siva.lindenlab.com/cgi-bin/login.cgi",
- "http://siva-secondlife.webdev.lindenlab.com/helpers/",
- DEFAULT_LOGIN_PAGE);
- addSystemGrid("Shakti",
- "util.shakti.lindenlab.com",
- "https://login.shakti.lindenlab.com/cgi-bin/login.cgi",
- "http://shakti-secondlife.webdev.lindenlab.com/helpers/",
- DEFAULT_LOGIN_PAGE);
- addSystemGrid("Soma",
- "util.soma.lindenlab.com",
- "https://login.soma.lindenlab.com/cgi-bin/login.cgi",
- "http://soma-secondlife.webdev.lindenlab.com/helpers/",
- DEFAULT_LOGIN_PAGE);
- addSystemGrid("Uma",
- "util.uma.lindenlab.com",
- "https://login.uma.lindenlab.com/cgi-bin/login.cgi",
- "http://uma-secondlife.webdev.lindenlab.com/helpers/",
- DEFAULT_LOGIN_PAGE);
- addSystemGrid("Vaak",
- "util.vaak.lindenlab.com",
- "https://login.vaak.lindenlab.com/cgi-bin/login.cgi",
- "http://vaak-secondlife.webdev.lindenlab.com/helpers/",
- DEFAULT_LOGIN_PAGE);
- addSystemGrid("Yami",
- "util.yami.lindenlab.com",
- "https://login.yami.lindenlab.com/cgi-bin/login.cgi",
- "http://yami-secondlife.webdev.lindenlab.com/helpers/",
- DEFAULT_LOGIN_PAGE);
- addSystemGrid("Local (Linden)",
- "localhost",
- "https://login.dmz.lindenlab.com/cgi-bin/login.cgi",
- "",
- DEFAULT_LOGIN_PAGE);
-
-
+ DEFAULT_LOGIN_PAGE,
+ SL_UPDATE_QUERY_URL,
+ "Aditi");
+
LLSD other_grids;
llifstream llsd_xml;
if (!grid_file.empty())
{
+ LL_INFOS("GridManager")<<"Grid configuration file '"<<grid_file<<"'"<<LL_ENDL;
llsd_xml.open( grid_file.c_str(), std::ios::in | std::ios::binary );
// parse through the gridfile, inserting grids into the list unless
- // they overwrite a linden grid.
- if( llsd_xml.is_open())
+ // they overwrite an existing grid.
+ if( llsd_xml.is_open())
{
LLSDSerialize::fromXMLDocument( other_grids, llsd_xml );
if(other_grids.isMap())
{
- for(LLSD::map_iterator grid_itr = other_grids.beginMap();
+ for(LLSD::map_iterator grid_itr = other_grids.beginMap();
grid_itr != other_grids.endMap();
++grid_itr)
{
LLSD::String key_name = grid_itr->first;
LLSD grid = grid_itr->second;
- // TODO: Make sure gridfile specified label is not
- // a system grid label
- LL_DEBUGS("GridManager") << "reading: " << key_name << LL_ENDL;
- if (mGridList.has(key_name) &&
- mGridList[key_name].has(GRID_IS_SYSTEM_GRID_VALUE))
+
+ std::string existingGrid = getGrid(grid);
+ if (mGridList.has(key_name) || !existingGrid.empty())
{
- LL_DEBUGS("GridManager") << "Cannot override grid " << key_name << " as it's a system grid" << LL_ENDL;
- // If the system grid does exist in the grids file, and it's marked as a favorite, set it as a favorite.
- if(grid_itr->second.has(GRID_IS_FAVORITE_VALUE) && grid_itr->second[GRID_IS_FAVORITE_VALUE].asBoolean() )
- {
- mGridList[key_name][GRID_IS_FAVORITE_VALUE] = TRUE;
- }
+ LL_WARNS("GridManager") << "Cannot override existing grid '" << key_name << "'; ignoring definition from '"<<grid_file<<"'" << LL_ENDL;
+ }
+ else if ( addGrid(grid) )
+ {
+ LL_INFOS("GridManager") << "added grid '"<<key_name<<"'"<<LL_ENDL;
}
else
{
- try
- {
- addGrid(grid);
- LL_DEBUGS("GridManager") << "Added grid: " << key_name << LL_ENDL;
- }
- catch (...)
- {
- }
+ LL_WARNS("GridManager") << "failed to add invalid grid '"<<key_name<<"'"<<LL_ENDL;
}
}
llsd_xml.close();
- }
- }
+ }
+ else
+ {
+ LL_WARNS("GridManager")<<"Failed to parse grid configuration '"<<grid_file<<"'"<<LL_ENDL;
+ }
+ }
+ else
+ {
+ LL_WARNS("GridManager")<<"Failed to open grid configuration '"<<grid_file<<"'"<<LL_ENDL;
+ }
}
-
+ else
+ {
+ LL_DEBUGS("GridManager")<<"no grid file specified"<<LL_ENDL;
+ }
+
// load a grid from the command line.
// if the actual grid name is specified from the command line,
// set it as the 'selected' grid.
@@ -259,50 +194,38 @@ void LLGridManager::initialize(const std::string& grid_file)
{
// try to find the grid assuming the command line parameter is
// the case-insensitive 'label' of the grid. ie 'Agni'
- mGrid = getGridByLabel(cmd_line_grid);
+ mGrid = getGrid(cmd_line_grid);
if(mGrid.empty())
{
- // if we couldn't find it, assume the
- // requested grid is the actual grid 'name' or index,
- // which would be the dns name of the grid (for non
- // linden hosted grids)
- // If the grid isn't there, that's ok, as it will be
- // automatically added later.
- mGrid = cmd_line_grid;
+ LL_WARNS("GridManager")<<"Unknown grid '"<<cmd_line_grid<<"'"<<LL_ENDL;
+ }
+ else
+ {
+ LL_INFOS("GridManager")<<"Command line specified '"<<cmd_line_grid<<"': "<<mGrid<<LL_ENDL;
}
-
}
else
{
// if a grid was not passed in via the command line, grab it from the CurrentGrid setting.
// if there's no current grid, that's ok as it'll be either set by the value passed
// in via the login uri if that's specified, or will default to maingrid
- mGrid = gSavedSettings.getString("CurrentGrid");
+ std::string last_grid = gSavedSettings.getString("CurrentGrid");
+ if ( ! getGrid(last_grid).empty() )
+ {
+ LL_INFOS("GridManager")<<"Using last grid: "<<last_grid<<LL_ENDL;
+ mGrid = last_grid;
+ }
+ else
+ {
+ LL_INFOS("GridManager")<<"Last grid '"<<last_grid<<"' not configured"<<LL_ENDL;
+ }
}
-
+
if(mGrid.empty())
{
// no grid was specified so default to maingrid
- LL_DEBUGS("GridManager") << "Setting grid to MAINGRID as no grid has been specified " << LL_ENDL;
+ LL_INFOS("GridManager") << "Default grid to "<<MAINGRID<< LL_ENDL;
mGrid = MAINGRID;
-
- }
-
- // generate a 'grid list' entry for any command line parameter overrides
- // or setting overides that we'll add to the grid list or override
- // any grid list entries with.
- LLSD grid = LLSD::emptyMap();
-
- if(mGridList.has(mGrid))
- {
- grid = mGridList[mGrid];
- }
- else
- {
- grid[GRID_VALUE] = mGrid;
- // add the grid with the additional values, or update the
- // existing grid if it exists with the given values
- addGrid(grid);
}
LLControlVariablePtr grid_control = gSavedSettings.getControl("CurrentGrid");
@@ -314,117 +237,108 @@ void LLGridManager::initialize(const std::string& grid_file)
// since above only triggers on changes, trigger the callback manually to initialize state
updateIsInProductionGrid();
- LL_DEBUGS("GridManager") << "Selected grid is " << mGrid << LL_ENDL;
setGridChoice(mGrid);
- if(mGridList[mGrid][GRID_LOGIN_URI_VALUE].isArray())
- {
- llinfos << "is array" << llendl;
- }
}
LLGridManager::~LLGridManager()
{
- saveFavorites();
}
-void LLGridManager::getGridInfo(const std::string &grid, LLSD& grid_info)
-{
-
- grid_info = mGridList[grid];
-
- // override any grid data with the command line info.
-
- LLSD cmd_line_login_uri = gSavedSettings.getLLSD("CmdLineLoginURI");
- if (cmd_line_login_uri.isString())
- {
- grid_info[GRID_LOGIN_URI_VALUE] = LLSD::emptyArray();
- grid_info[GRID_LOGIN_URI_VALUE].append(cmd_line_login_uri);
- }
-
- // override the helper uri if it was passed in
- std::string cmd_line_helper_uri = gSavedSettings.getString("CmdLineHelperURI");
- if(!cmd_line_helper_uri.empty())
- {
- grid_info[GRID_HELPER_URI_VALUE] = cmd_line_helper_uri;
- }
-
- // override the login page if it was passed in
- std::string cmd_line_login_page = gSavedSettings.getString("LoginPage");
- if(!cmd_line_login_page.empty())
- {
- grid_info[GRID_LOGIN_PAGE_VALUE] = cmd_line_login_page;
- }
-}
-
-
//
// LLGridManager::addGrid - add a grid to the grid list, populating the needed values
// if they're not populated yet.
//
-void LLGridManager::addGrid(LLSD& grid_data)
+bool LLGridManager::addGrid(LLSD& grid_data)
{
+ bool added = false;
if (grid_data.isMap() && grid_data.has(GRID_VALUE))
{
- std::string grid = utf8str_tolower(grid_data[GRID_VALUE]);
+ std::string grid = utf8str_tolower(grid_data[GRID_VALUE].asString());
- // grid should be in the form of a dns address
- if (!grid.empty() &&
- grid.find_first_not_of("abcdefghijklmnopqrstuvwxyz1234567890-_. ") != std::string::npos)
- {
- printf("grid name: %s", grid.c_str());
- throw LLInvalidGridName(grid);
- }
-
- // populate the other values if they don't exist
- if (!grid_data.has(GRID_LABEL_VALUE))
- {
- grid_data[GRID_LABEL_VALUE] = grid;
- }
- if (!grid_data.has(GRID_ID_VALUE))
- {
- grid_data[GRID_ID_VALUE] = grid;
- }
-
- // if the grid data doesn't include any of the URIs, then
- // generate them from the grid, which should be a dns address
- if (!grid_data.has(GRID_LOGIN_URI_VALUE))
+ if ( getGrid(grid_data[GRID_VALUE]).empty() && getGrid(grid).empty() )
{
- grid_data[GRID_LOGIN_URI_VALUE] = LLSD::emptyArray();
- grid_data[GRID_LOGIN_URI_VALUE].append(std::string("https://") +
- grid + "/cgi-bin/login.cgi");
- }
- // Populate to the default values
- if (!grid_data.has(GRID_LOGIN_PAGE_VALUE))
- {
- grid_data[GRID_LOGIN_PAGE_VALUE] = std::string("http://") + grid + "/app/login/";
- }
- if (!grid_data.has(GRID_HELPER_URI_VALUE))
- {
- grid_data[GRID_HELPER_URI_VALUE] = std::string("https://") + grid + "/helpers/";
+ std::string grid_id = grid_data.has(GRID_ID_VALUE) ? grid_data[GRID_ID_VALUE].asString() : "";
+ if ( getGrid(grid_id).empty() )
+ {
+ // populate the other values if they don't exist
+ if (!grid_data.has(GRID_LABEL_VALUE))
+ {
+ grid_data[GRID_LABEL_VALUE] = grid;
+ }
+ if (!grid_data.has(GRID_ID_VALUE))
+ {
+ grid_data[GRID_ID_VALUE] = grid;
+ }
+
+ // if the grid data doesn't include any of the URIs, then
+ // generate them from the grid, which should be a dns address
+ if (!grid_data.has(GRID_LOGIN_URI_VALUE))
+ {
+ grid_data[GRID_LOGIN_URI_VALUE] = LLSD::emptyArray();
+ grid_data[GRID_LOGIN_URI_VALUE].append(std::string("https://") +
+ grid + "/cgi-bin/login.cgi");
+ }
+ // Populate to the default values
+ if (!grid_data.has(GRID_LOGIN_PAGE_VALUE))
+ {
+ grid_data[GRID_LOGIN_PAGE_VALUE] = std::string("http://") + grid + "/app/login/";
+ }
+ if (!grid_data.has(GRID_HELPER_URI_VALUE))
+ {
+ grid_data[GRID_HELPER_URI_VALUE] = std::string("https://") + grid + "/helpers/";
+ }
+
+ if (!grid_data.has(GRID_LOGIN_IDENTIFIER_TYPES))
+ {
+ // non system grids and grids that haven't already been configured with values
+ // get both types of credentials.
+ grid_data[GRID_LOGIN_IDENTIFIER_TYPES] = LLSD::emptyArray();
+ grid_data[GRID_LOGIN_IDENTIFIER_TYPES].append(CRED_IDENTIFIER_TYPE_AGENT);
+ grid_data[GRID_LOGIN_IDENTIFIER_TYPES].append(CRED_IDENTIFIER_TYPE_ACCOUNT);
+ }
+
+ LL_DEBUGS("GridManager") <<grid<<"\n"
+ <<" id: "<<grid_data[GRID_ID_VALUE].asString()<<"\n"
+ <<" label: "<<grid_data[GRID_LABEL_VALUE].asString()<<"\n"
+ <<" login page: "<<grid_data[GRID_LOGIN_PAGE_VALUE].asString()<<"\n"
+ <<" helper page: "<<grid_data[GRID_HELPER_URI_VALUE].asString()<<"\n";
+ /* still in LL_DEBUGS */
+ for (LLSD::array_const_iterator login_uris = grid_data[GRID_LOGIN_URI_VALUE].beginArray();
+ login_uris != grid_data[GRID_LOGIN_URI_VALUE].endArray();
+ login_uris++)
+ {
+ LL_CONT << " login uri: "<<login_uris->asString()<<"\n";
+ }
+ LL_CONT << LL_ENDL;
+ mGridList[grid] = grid_data;
+ added = true;
+ }
+ else
+ {
+ LL_WARNS("GridManager")<<"duplicate grid id'"<<grid_id<<"' ignored"<<LL_ENDL;
+ }
}
-
- if (!grid_data.has(GRID_LOGIN_IDENTIFIER_TYPES))
+ else
{
- // non system grids and grids that haven't already been configured with values
- // get both types of credentials.
- grid_data[GRID_LOGIN_IDENTIFIER_TYPES] = LLSD::emptyArray();
- grid_data[GRID_LOGIN_IDENTIFIER_TYPES].append(CRED_IDENTIFIER_TYPE_AGENT);
- grid_data[GRID_LOGIN_IDENTIFIER_TYPES].append(CRED_IDENTIFIER_TYPE_ACCOUNT);
+ LL_WARNS("GridManager")<<"duplicate grid name '"<<grid<<"' ignored"<<LL_ENDL;
}
-
- LL_DEBUGS("GridManager") << "ADDING: " << grid << LL_ENDL;
- mGridList[grid] = grid_data;
}
+ else
+ {
+ LL_WARNS("GridManager")<<"invalid grid definition ignored"<<LL_ENDL;
+ }
+ return added;
}
//
// LLGridManager::addSystemGrid - helper for adding a system grid.
-void LLGridManager::addSystemGrid(const std::string& label,
- const std::string& name,
- const std::string& login,
+void LLGridManager::addSystemGrid(const std::string& label,
+ const std::string& name,
+ const std::string& login_uri,
const std::string& helper,
const std::string& login_page,
+ const std::string& update_url_base,
const std::string& login_id)
{
LLSD grid = LLSD::emptyMap();
@@ -432,12 +346,13 @@ void LLGridManager::addSystemGrid(const std::string& label,
grid[GRID_LABEL_VALUE] = label;
grid[GRID_HELPER_URI_VALUE] = helper;
grid[GRID_LOGIN_URI_VALUE] = LLSD::emptyArray();
- grid[GRID_LOGIN_URI_VALUE].append(login);
+ grid[GRID_LOGIN_URI_VALUE].append(login_uri);
grid[GRID_LOGIN_PAGE_VALUE] = login_page;
- grid[GRID_IS_SYSTEM_GRID_VALUE] = TRUE;
+ grid[GRID_UPDATE_SERVICE_URL] = update_url_base;
+ grid[GRID_IS_SYSTEM_GRID_VALUE] = true;
grid[GRID_LOGIN_IDENTIFIER_TYPES] = LLSD::emptyArray();
grid[GRID_LOGIN_IDENTIFIER_TYPES].append(CRED_IDENTIFIER_TYPE_AGENT);
-
+
grid[GRID_APP_SLURL_BASE] = SYSTEM_GRID_APP_SLURL_BASE;
if (login_id.empty())
{
@@ -447,124 +362,211 @@ void LLGridManager::addSystemGrid(const std::string& label,
{
grid[GRID_ID_VALUE] = login_id;
}
-
- // only add the system grids beyond agni to the visible list
- // if we're building a debug version.
+
if (name == std::string(MAINGRID))
{
- grid[GRID_SLURL_BASE] = MAIN_GRID_SLURL_BASE;
- grid[GRID_IS_FAVORITE_VALUE] = TRUE;
+ grid[GRID_SLURL_BASE] = MAIN_GRID_SLURL_BASE;
}
else
{
- grid[GRID_SLURL_BASE] = llformat(SYSTEM_GRID_SLURL_BASE, label.c_str());
+ grid[GRID_SLURL_BASE] = llformat(SYSTEM_GRID_SLURL_BASE, grid[GRID_ID_VALUE].asString().c_str());
}
+
addGrid(grid);
}
// return a list of grid name -> grid label mappings for UI purposes
-std::map<std::string, std::string> LLGridManager::getKnownGrids(bool favorite_only)
+std::map<std::string, std::string> LLGridManager::getKnownGrids()
{
std::map<std::string, std::string> result;
for(LLSD::map_iterator grid_iter = mGridList.beginMap();
grid_iter != mGridList.endMap();
- grid_iter++)
+ grid_iter++)
{
- if(!favorite_only || grid_iter->second.has(GRID_IS_FAVORITE_VALUE))
- {
- result[grid_iter->first] = grid_iter->second[GRID_LABEL_VALUE].asString();
- }
+ result[grid_iter->first] = grid_iter->second[GRID_LABEL_VALUE].asString();
}
return result;
}
-
void LLGridManager::setGridChoice(const std::string& grid)
{
// Set the grid choice based on a string.
- // The string can be:
- // - a grid label from the gGridInfo table
- // - a hostname
- // - an ip address
+ LL_DEBUGS("GridManager")<<"requested "<<grid<<LL_ENDL;
+ std::string grid_name = getGrid(grid); // resolved either the name or the id to the name
- // loop through. We could do just a hash lookup but we also want to match
- // on label
- std::string grid_name = grid;
- if(!mGridList.has(grid_name))
+ if(!grid_name.empty())
{
- // case insensitive
- grid_name = getGridByLabel(grid);
+ LL_INFOS("GridManager")<<"setting "<<grid_name<<LL_ENDL;
+ mGrid = grid_name;
+ gSavedSettings.setString("CurrentGrid", grid_name);
+
+ updateIsInProductionGrid();
}
-
- if(grid_name.empty())
+ else
{
// the grid was not in the list of grids.
- LLSD grid_data = LLSD::emptyMap();
- grid_data[GRID_VALUE] = grid;
- addGrid(grid_data);
+ LL_WARNS("GridManager")<<"unknown grid "<<grid<<LL_ENDL;
}
- mGrid = grid;
- gSavedSettings.setString("CurrentGrid", grid);
-
- updateIsInProductionGrid();
}
-std::string LLGridManager::getGridByLabel( const std::string &grid_label, bool case_sensitive)
+std::string LLGridManager::getGrid( const std::string &grid )
{
- for(LLSD::map_iterator grid_iter = mGridList.beginMap();
- grid_iter != mGridList.endMap();
- grid_iter++)
+ std::string grid_name;
+
+ if (mGridList.has(grid))
+ {
+ // the grid was the long name, so we're good, return it
+ grid_name = grid;
+ }
+ else
{
- if (grid_iter->second.has(GRID_LABEL_VALUE))
+ // search the grid list for a grid with a matching id
+ for(LLSD::map_iterator grid_iter = mGridList.beginMap();
+ grid_name.empty() && grid_iter != mGridList.endMap();
+ grid_iter++)
{
- if (0 == (case_sensitive?LLStringUtil::compareStrings(grid_label, grid_iter->second[GRID_LABEL_VALUE].asString()):
- LLStringUtil::compareInsensitive(grid_label, grid_iter->second[GRID_LABEL_VALUE].asString())))
+ if (grid_iter->second.has(GRID_ID_VALUE))
{
- return grid_iter->first;
+ if (0 == (LLStringUtil::compareInsensitive(grid,
+ grid_iter->second[GRID_ID_VALUE].asString())))
+ {
+ // found a matching label, return this name
+ grid_name = grid_iter->first;
+ }
}
}
}
- return std::string();
+ return grid_name;
}
-void LLGridManager::getLoginURIs(std::vector<std::string>& uris)
+std::string LLGridManager::getGridLabel(const std::string& grid)
+{
+ std::string grid_label;
+ std::string grid_name = getGrid(grid);
+ if (!grid.empty())
+ {
+ grid_label = mGridList[grid_name][GRID_LABEL_VALUE].asString();
+ }
+ else
+ {
+ LL_WARNS("GridManager")<<"invalid grid '"<<grid<<"'"<<LL_ENDL;
+ }
+ LL_DEBUGS("GridManager")<<"returning "<<grid_label<<LL_ENDL;
+ return grid_label;
+}
+
+std::string LLGridManager::getGridId(const std::string& grid)
+{
+ std::string grid_id;
+ std::string grid_name = getGrid(grid);
+ if (!grid.empty())
+ {
+ grid_id = mGridList[grid_name][GRID_ID_VALUE].asString();
+ }
+ else
+ {
+ LL_WARNS("GridManager")<<"invalid grid '"<<grid<<"'"<<LL_ENDL;
+ }
+ LL_DEBUGS("GridManager")<<"returning "<<grid_id<<LL_ENDL;
+ return grid_id;
+}
+
+void LLGridManager::getLoginURIs(const std::string& grid, std::vector<std::string>& uris)
{
uris.clear();
- LLSD cmd_line_login_uri = gSavedSettings.getLLSD("CmdLineLoginURI");
- if (cmd_line_login_uri.isString())
- {
- uris.push_back(cmd_line_login_uri);
- return;
+ std::string grid_name = getGrid(grid);
+ if (!grid_name.empty())
+ {
+ for (LLSD::array_iterator llsd_uri = mGridList[grid_name][GRID_LOGIN_URI_VALUE].beginArray();
+ llsd_uri != mGridList[grid_name][GRID_LOGIN_URI_VALUE].endArray();
+ llsd_uri++)
+ {
+ uris.push_back(llsd_uri->asString());
+ }
+ }
+ else
+ {
+ LL_WARNS("GridManager")<<"invalid grid '"<<grid<<"'"<<LL_ENDL;
+ }
+}
+
+void LLGridManager::getLoginURIs(std::vector<std::string>& uris)
+{
+ getLoginURIs(mGrid, uris);
+}
+
+std::string LLGridManager::getHelperURI(const std::string& grid)
+{
+ std::string helper_uri;
+ std::string grid_name = getGrid(grid);
+ if (!grid_name.empty())
+ {
+ helper_uri = mGridList[grid_name][GRID_HELPER_URI_VALUE].asString();
}
- for (LLSD::array_iterator llsd_uri = mGridList[mGrid][GRID_LOGIN_URI_VALUE].beginArray();
- llsd_uri != mGridList[mGrid][GRID_LOGIN_URI_VALUE].endArray();
- llsd_uri++)
+ else
{
- uris.push_back(llsd_uri->asString());
+ LL_WARNS("GridManager")<<"invalid grid '"<<grid<<"'"<<LL_ENDL;
}
+
+ LL_DEBUGS("GridManager")<<"returning "<<helper_uri<<LL_ENDL;
+ return helper_uri;
}
-std::string LLGridManager::getHelperURI()
+std::string LLGridManager::getLoginPage(const std::string& grid)
{
- std::string cmd_line_helper_uri = gSavedSettings.getString("CmdLineHelperURI");
- if(!cmd_line_helper_uri.empty())
+ std::string grid_login_page;
+ std::string grid_name = getGrid(grid);
+ if (!grid_name.empty())
+ {
+ grid_login_page = mGridList[grid_name][GRID_LOGIN_PAGE_VALUE].asString();
+ }
+ else
{
- return cmd_line_helper_uri;
+ LL_WARNS("GridManager")<<"invalid grid '"<<grid<<"'"<<LL_ENDL;
}
- return mGridList[mGrid][GRID_HELPER_URI_VALUE];
+ return grid_login_page;
+}
+
+std::string LLGridManager::getLoginPage()
+{
+ std::string login_page = mGridList[mGrid][GRID_LOGIN_PAGE_VALUE].asString();
+ LL_DEBUGS("GridManager")<<"returning "<<login_page<<LL_ENDL;
+ return login_page;
+}
+
+void LLGridManager::getLoginIdentifierTypes(LLSD& idTypes)
+{
+ idTypes = mGridList[mGrid][GRID_LOGIN_IDENTIFIER_TYPES];
}
-std::string LLGridManager::getLoginPage()
+std::string LLGridManager::getGridLoginID()
{
- // override the login page if it was passed in
- std::string cmd_line_login_page = gSavedSettings.getString("LoginPage");
- if(!cmd_line_login_page.empty())
- {
- return cmd_line_login_page;
- }
-
- return mGridList[mGrid][GRID_LOGIN_PAGE_VALUE];
+ return mGridList[mGrid][GRID_ID_VALUE];
+}
+
+std::string LLGridManager::getUpdateServiceURL()
+{
+ std::string update_url_base = gSavedSettings.getString("CmdLineUpdateService");;
+ if ( !update_url_base.empty() )
+ {
+ LL_INFOS2("UpdaterService","GridManager")
+ << "Update URL base overridden from command line: " << update_url_base
+ << LL_ENDL;
+ }
+ else if ( mGridList[mGrid].has(GRID_UPDATE_SERVICE_URL) )
+ {
+ update_url_base = mGridList[mGrid][GRID_UPDATE_SERVICE_URL].asString();
+ }
+ else
+ {
+ LL_WARNS2("UpdaterService","GridManager")
+ << "The grid property '" << GRID_UPDATE_SERVICE_URL
+ << "' is not defined for the grid '" << mGrid << "'"
+ << LL_ENDL;
+ }
+
+ return update_url_base;
}
void LLGridManager::updateIsInProductionGrid()
@@ -578,13 +580,19 @@ void LLGridManager::updateIsInProductionGrid()
if (uris.empty())
{
mIsInProductionGrid = true;
- return;
}
- LLStringUtil::toLower(uris[0]);
- if((uris[0].find("agni") != std::string::npos))
+ else
{
- mIsInProductionGrid = true;
- return;
+ for ( std::vector<std::string>::iterator uri_it = uris.begin();
+ ! mIsInProductionGrid && uri_it != uris.end();
+ uri_it++
+ )
+ {
+ if( MAIN_GRID_LOGIN_URI == *uri_it )
+ {
+ mIsInProductionGrid = true;
+ }
+ }
}
}
@@ -593,50 +601,53 @@ bool LLGridManager::isInProductionGrid()
return mIsInProductionGrid;
}
-void LLGridManager::saveFavorites()
+bool LLGridManager::isSystemGrid(const std::string& grid)
{
- // filter out just those marked as favorites
- LLSD output_grid_list = LLSD::emptyMap();
- for(LLSD::map_iterator grid_iter = mGridList.beginMap();
- grid_iter != mGridList.endMap();
- grid_iter++)
- {
- if(grid_iter->second.has(GRID_IS_FAVORITE_VALUE))
- {
- output_grid_list[grid_iter->first] = grid_iter->second;
- }
- }
- llofstream llsd_xml;
- llsd_xml.open( mGridFile.c_str(), std::ios::out | std::ios::binary);
- LLSDSerialize::toPrettyXML(output_grid_list, llsd_xml);
- llsd_xml.close();
-}
+ std::string grid_name = getGrid(grid);
+ return ( !grid_name.empty()
+ && mGridList.has(grid)
+ && mGridList[grid].has(GRID_IS_SYSTEM_GRID_VALUE)
+ && mGridList[grid][GRID_IS_SYSTEM_GRID_VALUE].asBoolean()
+ );
+}
// build a slurl for the given region within the selected grid
std::string LLGridManager::getSLURLBase(const std::string& grid)
{
- std::string grid_base;
- if(mGridList.has(grid) && mGridList[grid].has(GRID_SLURL_BASE))
- {
- return mGridList[grid][GRID_SLURL_BASE].asString();
- }
- else
+ std::string grid_base = "";
+ std::string grid_name = getGrid(grid);
+ if( ! grid_name.empty() && mGridList.has(grid_name) )
{
- return llformat(DEFAULT_SLURL_BASE, grid.c_str());
+ if (mGridList[grid_name].has(GRID_SLURL_BASE))
+ {
+ grid_base = mGridList[grid_name][GRID_SLURL_BASE].asString();
+ }
+ else
+ {
+ grid_base = llformat(DEFAULT_SLURL_BASE, grid_name.c_str());
+ }
}
+ LL_DEBUGS("GridManager")<<"returning '"<<grid_base<<"'"<<LL_ENDL;
+ return grid_base;
}
// build a slurl for the given region within the selected grid
std::string LLGridManager::getAppSLURLBase(const std::string& grid)
{
- std::string grid_base;
- if(mGridList.has(grid) && mGridList[grid].has(GRID_APP_SLURL_BASE))
+ std::string grid_base = "";
+ std::string grid_name = getGrid(grid);
+ if(!grid_name.empty() && mGridList.has(grid))
{
- return mGridList[grid][GRID_APP_SLURL_BASE].asString();
- }
- else
- {
- return llformat(DEFAULT_APP_SLURL_BASE, grid.c_str());
+ if (mGridList[grid].has(GRID_APP_SLURL_BASE))
+ {
+ grid_base = mGridList[grid][GRID_APP_SLURL_BASE].asString();
+ }
+ else
+ {
+ grid_base = llformat(DEFAULT_APP_SLURL_BASE, grid_name.c_str());
+ }
}
+ LL_DEBUGS("GridManager")<<"returning '"<<grid_base<<"'"<<LL_ENDL;
+ return grid_base;
}
diff --git a/indra/newview/llviewernetwork.h b/indra/newview/llviewernetwork.h
index 15e25b4952..8526c0ba7f 100644..100755
--- a/indra/newview/llviewernetwork.h
+++ b/indra/newview/llviewernetwork.h
@@ -27,118 +27,195 @@
#ifndef LL_LLVIEWERNETWORK_H
#define LL_LLVIEWERNETWORK_H
-
-extern const char* DEFAULT_LOGIN_PAGE;
-
-#define GRID_VALUE "name"
-#define GRID_LABEL_VALUE "label"
-#define GRID_ID_VALUE "grid_login_id"
-#define GRID_LOGIN_URI_VALUE "login_uri"
-#define GRID_HELPER_URI_VALUE "helper_uri"
-#define GRID_LOGIN_PAGE_VALUE "login_page"
-#define GRID_IS_SYSTEM_GRID_VALUE "system_grid"
-#define GRID_IS_FAVORITE_VALUE "favorite"
+
+// @TODO this really should be private, but is used in llslurl
#define MAINGRID "util.agni.lindenlab.com"
-#define GRID_LOGIN_IDENTIFIER_TYPES "login_identifier_types"
-// defines slurl formats associated with various grids.
-// we need to continue to support existing forms, as slurls
-// are shared between viewers that may not understand newer
-// forms.
-#define GRID_SLURL_BASE "slurl_base"
-#define GRID_APP_SLURL_BASE "app_slurl_base"
+/// Exception thrown when a grid is not valid
class LLInvalidGridName
{
public:
LLInvalidGridName(std::string grid) : mGrid(grid)
{
}
+ std::string name() { return mGrid; }
protected:
std::string mGrid;
};
-
/**
- * @brief A class to manage the grids available to the viewer
- * including persistance. This class also maintains the currently
- * selected grid.
- *
+ * @brief A singleton class to manage the grids available to the viewer.
+ *
+ * This class maintains several properties for each known grid, and provides
+ * interfaces for obtaining each of these properties given a specified
+ * grid. Grids are specified by either of two identifiers, each of which
+ * must be unique among all known grids:
+ * - grid name : DNS name for the grid
+ * - grid id : a short form (conventionally a single word)
+ *
+ * This class maintains the currently selected grid, and provides short
+ * form accessors for each of the properties of the selected grid.
**/
class LLGridManager : public LLSingleton<LLGridManager>
{
-public:
-
- // when the grid manager is instantiated, the default grids are automatically
- // loaded, and the grids favorites list is loaded from the xml file.
+ public:
+ /* ================================================================
+ * @name Initialization and Configuration
+ * @{
+ */
+ /// Instantiate the grid manager, load default grids, selects the default grid
LLGridManager(const std::string& grid_file);
LLGridManager();
~LLGridManager();
+ /// add grids from an external grids file
void initialize(const std::string& grid_file);
- // grid list management
-
- // add a grid to the list of grids
- void addGrid(LLSD& grid_info);
-
- // retrieve a map of grid-name <-> label
- // by default only return the user visible grids
- std::map<std::string, std::string> getKnownGrids(bool favorites_only=FALSE);
- void getGridInfo(const std::string& grid, LLSD &grid_info);
+ //@}
- // current grid management
+ /* ================================================================
+ * @name Grid Identifiers
+ * @{
+ * The id is a short form (typically one word) grid name,
+ * It should be used in URL path elements or parameters
+ *
+ * Each grid also has a "label", intented to be a user friendly
+ * descriptive form (it is used in the login panel grid menu, for example).
+ */
+ /// Return the name of a grid, given either its name or its id
+ std::string getGrid( const std::string &grid );
- // select a given grid as the current grid. If the grid
- // is not a known grid, then it's assumed to be a dns name for the
- // grid, and the various URIs will be automatically generated.
- void setGridChoice(const std::string& grid);
+ /// Get the id (short form selector) for a given grid
+ std::string getGridId(const std::string& grid);
+
+ /// Get the id (short form selector) for the selected grid
+ std::string getGridId() { return getGridId(mGrid); }
+
+ /// Get the user-friendly long form descriptor for a given grid
+ std::string getGridLabel(const std::string& grid);
+ /// Get the user-friendly long form descriptor for the selected grid
+ std::string getGridLabel() { return getGridLabel(mGrid); }
+
+ /// Retrieve a map of grid-name -> label
+ std::map<std::string, std::string> getKnownGrids();
+
+ //@}
+
+ /* ================================================================
+ * @name Login related properties
+ * @{
+ */
+
+ /**
+ * Get the login uris for the specified grid.
+ * The login uri for a grid is the target of the authentication request.
+ * A grid may have multple login uris, so they are returned as a vector.
+ */
+ void getLoginURIs(const std::string& grid, std::vector<std::string>& uris);
- std::string getGridLabel() { return mGridList[mGrid][GRID_LABEL_VALUE]; }
- std::string getGrid() const { return mGrid; }
+ /// Get the login uris for the selected grid
void getLoginURIs(std::vector<std::string>& uris);
- std::string getHelperURI();
+
+ /// Get the URI for webdev help functions for the specified grid
+ std::string getHelperURI(const std::string& grid);
+
+ /// Get the URI for webdev help functions for the selected grid
+ std::string getHelperURI() { return getHelperURI(mGrid); }
+
+ /// Get the url of the splash page to be displayed prior to login
+ std::string getLoginPage(const std::string& grid_name);
+
+ /// Get the URI for the login splash page for the selected grid
std::string getLoginPage();
- std::string getGridLoginID() { return mGridList[mGrid][GRID_ID_VALUE]; }
- std::string getLoginPage(const std::string& grid) { return mGridList[grid][GRID_LOGIN_PAGE_VALUE]; }
- void getLoginIdentifierTypes(LLSD& idTypes) { idTypes = mGridList[mGrid][GRID_LOGIN_IDENTIFIER_TYPES]; }
+
+ /// Get the id to be used as a short name in url path components or parameters
+ std::string getGridLoginID();
+
+ /// Get an array of the login types supported by the grid
+ void getLoginIdentifierTypes(LLSD& idTypes);
+ /**< the types are "agent" and "avatar";
+ * one means single-name (someone Resident) accounts and other first/last name accounts
+ * I am not sure which is which
+ */
+
+ //@}
+ /* ================================================================
+ * @name Update Related Properties
+ * @{
+ */
+ /// Get the update service URL base (host and path) for the selected grid
+ std::string getUpdateServiceURL();
- // build a slurl for the given region within the selected grid
+ //@}
+
+ /* ================================================================
+ * @name URL Construction Properties
+ * @{
+ */
+
+ /// Return the slurl prefix (everything up to but not including the region) for a given grid
std::string getSLURLBase(const std::string& grid);
+
+ /// Return the slurl prefix (everything up to but not including the region) for the selected grid
std::string getSLURLBase() { return getSLURLBase(mGrid); }
+ /// Return the application URL prefix for the given grid
std::string getAppSLURLBase(const std::string& grid);
+
+ /// Return the application URL prefix for the selected grid
std::string getAppSLURLBase() { return getAppSLURLBase(mGrid); }
-
- void getGridInfo(LLSD &grid_info) { getGridInfo(mGrid, grid_info); }
-
- std::string getGridByLabel( const std::string &grid_label, bool case_sensitive = false);
-
- bool isSystemGrid(const std::string& grid)
- {
- return mGridList.has(grid) &&
- mGridList[grid].has(GRID_IS_SYSTEM_GRID_VALUE) &&
- mGridList[grid][GRID_IS_SYSTEM_GRID_VALUE].asBoolean();
- }
+
+ //@}
+
+ /* ================================================================
+ * @name Selecting the current grid
+ * @{
+ * At initialization, the current grid is set by the first of:
+ * -# The value supplied by the --grid command line option (setting CmdLineGridChoice);
+ * Note that a default for this may be set at build time.
+ * -# The grid used most recently (setting CurrentGrid)
+ * -# The main grid (Agni)
+ */
+
+ /// Select a given grid as the current grid.
+ void setGridChoice(const std::string& grid);
+
+ /// Returns the name of the currently selected grid
+ std::string getGrid() const { return mGrid; }
+
+ //@}
+
+ /// Is the given grid one of the hard-coded default grids (Agni or Aditi)
+ bool isSystemGrid(const std::string& grid);
+
+ /// Is the selected grid one of the hard-coded default grids (Agni or Aditi)
bool isSystemGrid() { return isSystemGrid(mGrid); }
- // Mark this grid as a favorite that should be persisited on 'save'
- // this is currently used to persist a grid after a successful login
- void setFavorite() { mGridList[mGrid][GRID_IS_FAVORITE_VALUE] = TRUE; }
-
+
+ /// Is the selected grid a production grid?
bool isInProductionGrid();
- void saveFavorites();
- void clearFavorites();
+ /**
+ * yes, that's not a very helpful description.
+ * I don't really know why that is different from isSystemGrid()
+ * In practice, the implementation is that it
+ * @returns true if the login uri for the grid is the uri for MAINGRID
+ */
-protected:
+ private:
+
+ /// Add a grid to the list of grids
+ bool addGrid(LLSD& grid_info);
+ ///< @returns true if successfully added
void updateIsInProductionGrid();
- // helper function for adding the predefined grids
+ // helper function for adding the hard coded grids
void addSystemGrid(const std::string& label,
const std::string& name,
const std::string& login,
const std::string& helper,
const std::string& login_page,
+ const std::string& update_url_base,
const std::string& login_id = "");
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index ff714f24b4..7de72dc2cd 100644..100755
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -200,7 +200,10 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe
mID(id),
mLocalID(0),
mTotalCRC(0),
+ mListIndex(-1),
mTEImages(NULL),
+ mTENormalMaps(NULL),
+ mTESpecularMaps(NULL),
mGLName(0),
mbCanSelect(TRUE),
mFlags(0),
@@ -236,7 +239,8 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe
mNumFaces(0),
mTimeDilation(1.f),
mRotTime(0.f),
- mJointInfo(NULL),
+ mAngularVelocityRot(),
+ mPreviousRotation(),
mState(0),
mMedia(NULL),
mClickAction(0),
@@ -266,6 +270,7 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe
{
mPositionAgent = mRegionp->getOriginAgent();
}
+ resetRot();
LLViewerObject::sNumObjects++;
}
@@ -281,12 +286,6 @@ LLViewerObject::~LLViewerObject()
mInventory = NULL;
}
- if (mJointInfo)
- {
- delete mJointInfo;
- mJointInfo = NULL;
- }
-
if (mPartSourcep)
{
mPartSourcep->setDead();
@@ -325,6 +324,18 @@ void LLViewerObject::deleteTEImages()
{
delete[] mTEImages;
mTEImages = NULL;
+
+ if (mTENormalMaps != NULL)
+ {
+ delete[] mTENormalMaps;
+ mTENormalMaps = NULL;
+ }
+
+ if (mTESpecularMaps != NULL)
+ {
+ delete[] mTESpecularMaps;
+ mTESpecularMaps = NULL;
+ }
}
void LLViewerObject::markDead()
@@ -337,9 +348,6 @@ void LLViewerObject::markDead()
if (getParent())
{
((LLViewerObject *)getParent())->removeChild(this);
- // go ahead and delete any jointinfo's that we find
- delete mJointInfo;
- mJointInfo = NULL;
}
// Mark itself as dead
@@ -433,7 +441,9 @@ void LLViewerObject::dump() const
llinfos << "PositionAgent: " << getPositionAgent() << llendl;
llinfos << "PositionGlobal: " << getPositionGlobal() << llendl;
llinfos << "Velocity: " << getVelocity() << llendl;
- if (mDrawable.notNull() && mDrawable->getNumFaces())
+ if (mDrawable.notNull() &&
+ mDrawable->getNumFaces() &&
+ mDrawable->getFace(0))
{
LLFacePool *poolp = mDrawable->getFace(0)->getPool();
if (poolp)
@@ -447,7 +457,7 @@ void LLViewerObject::dump() const
/*
llinfos << "Velocity: " << getVelocity() << llendl;
llinfos << "AnyOwner: " << permAnyOwner() << " YouOwner: " << permYouOwner() << " Edit: " << mPermEdit << llendl;
- llinfos << "UsePhysics: " << usePhysics() << " CanSelect " << mbCanSelect << " UserSelected " << mUserSelected << llendl;
+ llinfos << "UsePhysics: " << flagUsePhysics() << " CanSelect " << mbCanSelect << " UserSelected " << mUserSelected << llendl;
llinfos << "AppAngle: " << mAppAngle << llendl;
llinfos << "PixelArea: " << mPixelArea << llendl;
@@ -521,6 +531,17 @@ void LLViewerObject::setNameValueList(const std::string& name_value_list)
}
}
+void LLViewerObject::setSelected(BOOL sel)
+{
+ mUserSelected = sel;
+ resetRot();
+
+ if (!sel)
+ {
+ setAllTESelected(false);
+ }
+}
+
// This method returns true if the object is over land owned by the
// agent.
bool LLViewerObject::isReturnable()
@@ -740,7 +761,7 @@ void LLViewerObject::addThisAndNonJointChildren(std::vector<LLViewerObject*>& ob
iter != mChildList.end(); iter++)
{
LLViewerObject* child = *iter;
- if ( (!child->isAvatar()) && (!child->isJointChild()))
+ if ( (!child->isAvatar()))
{
child->addThisAndNonJointChildren(objects);
}
@@ -791,6 +812,12 @@ BOOL LLViewerObject::setDrawableParent(LLDrawable* parentp)
LLDrawable* old_parent = mDrawable->mParent;
mDrawable->mParent = parentp;
+ if (parentp && mDrawable->isActive())
+ {
+ parentp->makeActive();
+ parentp->setState(LLDrawable::ACTIVE_CHILD);
+ }
+
gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE);
if( (old_parent != parentp && old_parent)
|| (parentp && parentp->isActive()))
@@ -875,7 +902,6 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
const EObjectUpdateType update_type,
LLDataPacker *dp)
{
- LLMemType mt(LLMemType::MTYPE_OBJECT);
U32 retval = 0x0;
// If region is removed from the list it is also deleted.
@@ -1231,12 +1257,8 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
coloru.mV[3] = 255 - coloru.mV[3];
mText->setColor(LLColor4(coloru));
mText->setString(temp_string);
-
- if (mDrawable.notNull())
- {
- setChanged(MOVED | SILHOUETTE);
- gPipeline.markMoved(mDrawable, FALSE); // undamped
- }
+
+ setChanged(MOVED | SILHOUETTE);
}
else if (mText.notNull())
{
@@ -1293,26 +1315,6 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
}
}
- U8 joint_type = 0;
- mesgsys->getU8Fast(_PREHASH_ObjectData, _PREHASH_JointType, joint_type, block_num);
- if (joint_type)
- {
- // create new joint info
- if (!mJointInfo)
- {
- mJointInfo = new LLVOJointInfo;
- }
- mJointInfo->mJointType = (EHavokJointType) joint_type;
- mesgsys->getVector3Fast(_PREHASH_ObjectData, _PREHASH_JointPivot, mJointInfo->mPivot, block_num);
- mesgsys->getVector3Fast(_PREHASH_ObjectData, _PREHASH_JointAxisOrAnchor, mJointInfo->mAxisOrAnchor, block_num);
- }
- else if (mJointInfo)
- {
- // this joint info is no longer needed
- delete mJointInfo;
- mJointInfo = NULL;
- }
-
break;
}
@@ -1430,9 +1432,10 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
#else
val = (U16 *) &data[count];
#endif
- setAngularVelocity( U16_to_F32(val[VX], -size, size),
+ new_angv.set(U16_to_F32(val[VX], -size, size),
U16_to_F32(val[VY], -size, size),
U16_to_F32(val[VZ], -size, size));
+ setAngularVelocity(new_angv);
break;
case 16:
@@ -1456,9 +1459,10 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
new_rot.mQ[VZ] = U8_to_F32(data[11], -1.f, 1.f);
new_rot.mQ[VW] = U8_to_F32(data[12], -1.f, 1.f);
- setAngularVelocity( U8_to_F32(data[13], -size, size),
+ new_angv.set(U8_to_F32(data[13], -size, size),
U8_to_F32(data[14], -size, size),
U8_to_F32(data[15], -size, size) );
+ setAngularVelocity(new_angv);
break;
}
@@ -1530,9 +1534,10 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
dp->unpackU16(val[VX], "AccX");
dp->unpackU16(val[VY], "AccY");
dp->unpackU16(val[VZ], "AccZ");
- setAngularVelocity( U16_to_F32(val[VX], -64.f, 64.f),
+ new_angv.set(U16_to_F32(val[VX], -64.f, 64.f),
U16_to_F32(val[VY], -64.f, 64.f),
U16_to_F32(val[VZ], -64.f, 64.f));
+ setAngularVelocity(new_angv);
}
break;
case OUT_FULL_COMPRESSED:
@@ -1574,10 +1579,12 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
dp->setPassFlags(value);
dp->unpackUUID(owner_id, "Owner");
+ mOwnerID = owner_id;
+
if (value & 0x80)
{
- dp->unpackVector3(vec, "Omega");
- setAngularVelocity(vec);
+ dp->unpackVector3(new_angv, "Omega");
+ setAngularVelocity(new_angv);
}
if (value & 0x20)
@@ -1647,13 +1654,13 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
retval |= checkMediaURL(media_url);
//
- // Unpack particle system data
+ // Unpack particle system data (legacy)
//
if (value & 0x8)
{
- unpackParticleSource(*dp, owner_id);
+ unpackParticleSource(*dp, owner_id, true);
}
- else
+ else if (!(value & 0x400))
{
deleteParticleSource();
}
@@ -1960,14 +1967,6 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
cur_parentp->removeChild(this);
- if (mJointInfo && !parent_id)
- {
- // since this object is no longer parent-relative
- // we make sure we delete any joint info
- delete mJointInfo;
- mJointInfo = NULL;
- }
-
setChanged(MOVED | SILHOUETTE);
if (mDrawable.notNull())
@@ -2066,21 +2065,33 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
}
}
- if (new_rot != mLastRot
- || new_angv != old_angv)
+ if ((new_rot != getRotation())
+ || (new_angv != old_angv))
{
- if (new_rot != mLastRot)
+ if (new_rot != mPreviousRotation)
{
- mLastRot = new_rot;
- setRotation(new_rot);
+ resetRot();
}
-
+ else if (new_angv != old_angv)
+ {
+ if (flagUsePhysics())
+ {
+ resetRot();
+ }
+ else
+ {
+ resetRotTime();
+ }
+ }
+
+ // Remember the last rotation value
+ mPreviousRotation = new_rot;
+
+ // Set the rotation of the object followed by adjusting for the accumulated angular velocity (llSetTargetOmega)
+ setRotation(new_rot * mAngularVelocityRot);
setChanged(ROTATED | SILHOUETTE);
-
- resetRot();
}
-
if ( gShowObjectUpdates )
{
LLColor4 color;
@@ -2095,9 +2106,15 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
gPipeline.addDebugBlip(getPositionAgent(), color);
}
- if ((0.0f == vel_mag_sq) &&
- (0.0f == accel_mag_sq) &&
- (0.0f == getAngularVelocity().magVecSquared()))
+ const F32 MAG_CUTOFF = F_APPROXIMATELY_ZERO;
+
+ llassert(vel_mag_sq >= 0.f);
+ llassert(accel_mag_sq >= 0.f);
+ llassert(getAngularVelocity().magVecSquared() >= 0.f);
+
+ if ((MAG_CUTOFF >= vel_mag_sq) &&
+ (MAG_CUTOFF >= accel_mag_sq) &&
+ (MAG_CUTOFF >= getAngularVelocity().magVecSquared()))
{
mStatic = TRUE; // This object doesn't move!
}
@@ -2146,7 +2163,8 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
if (mDrawable->isState(LLDrawable::FORCE_INVISIBLE) && !mOrphaned)
{
// lldebugs << "Clearing force invisible: " << mID << ":" << getPCodeString() << ":" << getPositionAgent() << llendl;
- mDrawable->setState(LLDrawable::CLEAR_INVISIBLE);
+ mDrawable->clearState(LLDrawable::FORCE_INVISIBLE);
+ gPipeline.markRebuild( mDrawable, LLDrawable::REBUILD_ALL, TRUE );
}
}
@@ -2168,17 +2186,13 @@ BOOL LLViewerObject::isActive() const
-BOOL LLViewerObject::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
+void LLViewerObject::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
{
- static LLFastTimer::DeclareTimer ftm("Viewer Object");
- LLFastTimer t(ftm);
+ //static LLFastTimer::DeclareTimer ftm("Viewer Object");
+ //LLFastTimer t(ftm);
- if (mDead)
+ if (!mDead)
{
- // It's dead. Don't update it.
- return TRUE;
- }
-
// CRO - don't velocity interp linked objects!
// Leviathan - but DO velocity interp joints
if (!mStatic && sVelocityInterpolate && !isSelected())
@@ -2187,88 +2201,12 @@ BOOL LLViewerObject::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
F32 dt_raw = (F32)(time - mLastInterpUpdateSecs);
F32 dt = mTimeDilation * dt_raw;
- if (!mJointInfo)
- {
applyAngularVelocity(dt);
- }
-
- LLViewerObject *parentp = (LLViewerObject *) getParent();
- if (mJointInfo)
- {
- if (parentp)
- {
- // do parent-relative stuff
- LLVector3 ang_vel = getAngularVelocity();
- F32 omega = ang_vel.magVecSquared();
- F32 angle = 0.0f;
- LLQuaternion dQ;
- if (omega > 0.00001f)
- {
- omega = sqrt(omega);
- angle = omega * dt;
- dQ.setQuat(angle, ang_vel);
- }
- LLVector3 pos = getPosition();
-
- if (HJT_HINGE == mJointInfo->mJointType)
- {
- // hinge = uniform circular motion
- LLVector3 parent_pivot = getVelocity();
- LLVector3 parent_axis = getAcceleration();
-
- angle = dt * (ang_vel * mJointInfo->mAxisOrAnchor); // AxisOrAnchor = axis
- dQ.setQuat(angle, mJointInfo->mAxisOrAnchor); // AxisOrAnchor = axis
- LLVector3 pivot_offset = pos - mJointInfo->mPivot; // pos in pivot-frame
- pivot_offset = pivot_offset * dQ; // new rotated pivot-frame pos
- pos = mJointInfo->mPivot + pivot_offset; // parent-frame
- LLViewerObject::setPosition(pos);
- LLQuaternion Q_PC = getRotation();
- setRotation(Q_PC * dQ);
- mLastInterpUpdateSecs = time;
- }
- else if (HJT_POINT == mJointInfo->mJointType)
- // || HJT_LPOINT == mJointInfo->mJointType)
- {
- // point-to-point = spin about axis and uniform circular motion
- // of axis about the pivot point
- //
- // NOTE: this interpolation scheme is not quite good enough to
- // reduce the bandwidth -- needs a gravitational correction.
- // Similarly for hinges with axes that deviate from vertical.
-
- LLQuaternion Q_PC = getRotation();
- Q_PC = Q_PC * dQ;
- setRotation(Q_PC);
- LLVector3 pivot_to_child = - mJointInfo->mAxisOrAnchor; // AxisOrAnchor = anchor
- pos = mJointInfo->mPivot + pivot_to_child * Q_PC;
- LLViewerObject::setPosition(pos);
- mLastInterpUpdateSecs = time;
- }
- /* else if (HJT_WHEEL == mJointInfo->mJointInfo)
+ if (isAttachment())
{
- // wheel = uniform rotation about axis, with linear
- // velocity interpolation (if any)
- LLVector3 parent_axis = getAcceleration(); // HACK -- accel stores the parent-axis (parent-frame)
-
- LLQuaternion Q_PC = getRotation();
-
- angle = dt * (parent_axis * ang_vel);
- dQ.setQuat(angle, parent_axis);
-
- Q_PC = Q_PC * dQ;
- setRotation(Q_PC);
-
- pos = getPosition() + dt * getVelocity();
- LLViewerObject::setPosition(pos);
mLastInterpUpdateSecs = time;
- }*/
- }
- }
- else if (isAttachment())
- {
- mLastInterpUpdateSecs = time;
- return TRUE;
+ return;
}
else
{ // Move object based on it's velocity and rotation
@@ -2277,8 +2215,7 @@ BOOL LLViewerObject::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
}
updateDrawable(FALSE);
-
- return TRUE;
+ }
}
@@ -2390,10 +2327,11 @@ void LLViewerObject::interpolateLinearMotion(const F64 & time, const F32 & dt)
{ // This will put the object underground, but we can't tell if it will stop
// at ground level or not
min_height = LLWorld::getInstance()->getMinAllowedZ(this, new_pos_global);
+ // Cap maximum height
+ new_pos.mV[VZ] = llmin(LLWorld::getInstance()->getRegionMaxHeight(), new_pos.mV[VZ]);
}
new_pos.mV[VZ] = llmax(min_height, new_pos.mV[VZ]);
- new_pos.mV[VZ] = llmin(LLWorld::getInstance()->getRegionMaxHeight(), new_pos.mV[VZ]);
// Check to see if it's going off the region
LLVector3 temp(new_pos);
@@ -2437,8 +2375,6 @@ void LLViewerObject::interpolateLinearMotion(const F64 & time, const F32 & dt)
BOOL LLViewerObject::setData(const U8 *datap, const U32 data_size)
{
- LLMemType mt(LLMemType::MTYPE_OBJECT);
-
delete [] mData;
if (datap)
@@ -2480,8 +2416,6 @@ void LLViewerObject::doUpdateInventory(
U8 key,
bool is_new)
{
- LLMemType mt(LLMemType::MTYPE_OBJECT);
-
LLViewerInventoryItem* old_item = NULL;
if(TASK_INVENTORY_ITEM_KEY == key)
{
@@ -2565,8 +2499,6 @@ void LLViewerObject::saveScript(
BOOL active,
bool is_new)
{
- LLMemType mt(LLMemType::MTYPE_OBJECT);
-
/*
* XXXPAM Investigate not making this copy. Seems unecessary, but I'm unsure about the
* interaction with doUpdateInventory() called below.
@@ -2643,8 +2575,6 @@ void LLViewerObject::dirtyInventory()
void LLViewerObject::registerInventoryListener(LLVOInventoryListener* listener, void* user_data)
{
- LLMemType mt(LLMemType::MTYPE_OBJECT);
-
LLInventoryCallbackInfo* info = new LLInventoryCallbackInfo;
info->mListener = listener;
info->mInventoryData = user_data;
@@ -2742,8 +2672,6 @@ S32 LLFilenameAndTask::sCount = 0;
// static
void LLViewerObject::processTaskInv(LLMessageSystem* msg, void** user_data)
{
- LLMemType mt(LLMemType::MTYPE_OBJECT);
-
LLUUID task_id;
msg->getUUIDFast(_PREHASH_InventoryData, _PREHASH_TaskID, task_id);
LLViewerObject* object = gObjectList.findObject(task_id);
@@ -2799,7 +2727,33 @@ void LLViewerObject::processTaskInvFile(void** user_data, S32 error_code, LLExtS
if(ft && (0 == error_code) &&
(object = gObjectList.findObject(ft->mTaskID)))
{
- object->loadTaskInvFile(ft->mFilename);
+ if (object->loadTaskInvFile(ft->mFilename))
+ {
+
+ LLInventoryObject::object_list_t::iterator it = object->mInventory->begin();
+ LLInventoryObject::object_list_t::iterator end = object->mInventory->end();
+ std::list<LLUUID>& pending_lst = object->mPendingInventoryItemsIDs;
+
+ for (; it != end && pending_lst.size(); ++it)
+ {
+ LLViewerInventoryItem* item = dynamic_cast<LLViewerInventoryItem*>(it->get());
+ if(item && item->getType() != LLAssetType::AT_CATEGORY)
+ {
+ std::list<LLUUID>::iterator id_it = std::find(pending_lst.begin(), pending_lst.begin(), item->getAssetUUID());
+ if (id_it != pending_lst.end())
+ {
+ pending_lst.erase(id_it);
+ }
+ }
+ }
+ }
+ else
+ {
+ // MAINT-2597 - crash when trying to edit a no-mod object
+ // Somehow get an contents inventory response, but with an invalid stream (possibly 0 size?)
+ // Stated repro was specific to no-mod objects so failing without user interaction should be safe.
+ llwarns << "Trying to load invalid task inventory file. Ignoring file contents." << llendl;
+ }
}
else
{
@@ -2811,10 +2765,8 @@ void LLViewerObject::processTaskInvFile(void** user_data, S32 error_code, LLExtS
delete ft;
}
-void LLViewerObject::loadTaskInvFile(const std::string& filename)
+BOOL LLViewerObject::loadTaskInvFile(const std::string& filename)
{
- LLMemType mt(LLMemType::MTYPE_OBJECT);
-
std::string filename_and_local_path = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, filename);
llifstream ifs(filename_and_local_path);
if(ifs.good())
@@ -2860,8 +2812,11 @@ void LLViewerObject::loadTaskInvFile(const std::string& filename)
{
llwarns << "unable to load task inventory: " << filename_and_local_path
<< llendl;
+ return FALSE;
}
doInventoryCallback();
+
+ return TRUE;
}
void LLViewerObject::doInventoryCallback()
@@ -2906,13 +2861,38 @@ void LLViewerObject::removeInventory(const LLUUID& item_id)
++mInventorySerialNum;
}
+bool LLViewerObject::isTextureInInventory(LLViewerInventoryItem* item)
+{
+ bool result = false;
+
+ if (item && LLAssetType::AT_TEXTURE == item->getType())
+ {
+ std::list<LLUUID>::iterator begin = mPendingInventoryItemsIDs.begin();
+ std::list<LLUUID>::iterator end = mPendingInventoryItemsIDs.end();
+
+ bool is_fetching = std::find(begin, end, item->getAssetUUID()) != end;
+ bool is_fetched = getInventoryItemByAsset(item->getAssetUUID()) != NULL;
+
+ result = is_fetched || is_fetching;
+ }
+
+ return result;
+}
+
+void LLViewerObject::updateTextureInventory(LLViewerInventoryItem* item, U8 key, bool is_new)
+{
+ if (item && !isTextureInInventory(item))
+ {
+ mPendingInventoryItemsIDs.push_back(item->getAssetUUID());
+ updateInventory(item, key, is_new);
+ }
+}
+
void LLViewerObject::updateInventory(
LLViewerInventoryItem* item,
U8 key,
bool is_new)
{
- LLMemType mt(LLMemType::MTYPE_OBJECT);
-
// This slices the object into what we're concerned about on the
// viewer. The simulator will take the permissions and transfer
// ownership.
@@ -3328,14 +3308,14 @@ void LLViewerObject::boostTexturePriority(BOOL boost_children /* = TRUE */)
S32 tex_count = getNumTEs();
for (i = 0; i < tex_count; i++)
{
- getTEImage(i)->setBoostLevel(LLViewerTexture::BOOST_SELECTED);
+ getTEImage(i)->setBoostLevel(LLGLTexture::BOOST_SELECTED);
}
if (isSculpted() && !isMesh())
{
LLSculptParams *sculpt_params = (LLSculptParams *)getParameterEntry(LLNetworkData::PARAMS_SCULPT);
LLUUID sculpt_id = sculpt_params->getSculptTexture();
- LLViewerTextureManager::getFetchedTexture(sculpt_id, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE)->setBoostLevel(LLViewerTexture::BOOST_SELECTED);
+ LLViewerTextureManager::getFetchedTexture(sculpt_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE)->setBoostLevel(LLGLTexture::BOOST_SELECTED);
}
if (boost_children)
@@ -3824,15 +3804,6 @@ void LLViewerObject::setPositionEdit(const LLVector3 &pos_edit, BOOL damped)
((LLViewerObject *)getParent())->setPositionEdit(pos_edit - position_offset);
updateDrawable(damped);
}
- else if (isJointChild())
- {
- // compute new parent-relative position
- LLViewerObject *parent = (LLViewerObject *) getParent();
- LLQuaternion inv_parent_rot = parent->getRotation();
- inv_parent_rot.transQuat();
- LLVector3 pos_parent = (pos_edit - parent->getPositionRegion()) * inv_parent_rot;
- LLViewerObject::setPosition(pos_parent, damped);
- }
else
{
LLViewerObject::setPosition(pos_edit, damped);
@@ -3846,8 +3817,7 @@ LLViewerObject* LLViewerObject::getRootEdit() const
{
const LLViewerObject* root = this;
while (root->mParent
- && !(root->mJointInfo
- || ((LLViewerObject*)root->mParent)->isAvatar()) )
+ && !((LLViewerObject*)root->mParent)->isAvatar())
{
root = (LLViewerObject*)root->mParent;
}
@@ -3855,19 +3825,19 @@ LLViewerObject* LLViewerObject::getRootEdit() const
}
-BOOL LLViewerObject::lineSegmentIntersect(const LLVector3& start, const LLVector3& end,
+BOOL LLViewerObject::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
S32 face,
BOOL pick_transparent,
S32* face_hit,
- LLVector3* intersection,
+ LLVector4a* intersection,
LLVector2* tex_coord,
- LLVector3* normal,
- LLVector3* bi_normal)
+ LLVector4a* normal,
+ LLVector4a* tangent)
{
return false;
}
-BOOL LLViewerObject::lineSegmentBoundingBox(const LLVector3& start, const LLVector3& end)
+BOOL LLViewerObject::lineSegmentBoundingBox(const LLVector4a& start, const LLVector4a& end)
{
if (mDrawable.isNull() || mDrawable->isDead())
{
@@ -3884,11 +3854,7 @@ BOOL LLViewerObject::lineSegmentBoundingBox(const LLVector3& start, const LLVect
size.setSub(ext[1], ext[0]);
size.mul(0.5f);
- LLVector4a starta, enda;
- starta.load3(start.mV);
- enda.load3(end.mV);
-
- return LLLineSegmentBoxIntersect(starta, enda, center, size);
+ return LLLineSegmentBoxIntersect(start, end, center, size);
}
U8 LLViewerObject::getMediaType() const
@@ -3931,8 +3897,6 @@ std::string LLViewerObject::getMediaURL() const
void LLViewerObject::setMediaURL(const std::string& media_url)
{
- LLMemType mt(LLMemType::MTYPE_OBJECT);
-
if (!mMedia)
{
mMedia = new LLViewerObjectMedia;
@@ -3982,8 +3946,6 @@ BOOL LLViewerObject::setMaterial(const U8 material)
void LLViewerObject::setNumTEs(const U8 num_tes)
{
- LLMemType mt(LLMemType::MTYPE_OBJECT);
-
U32 i;
if (num_tes != getNumTEs())
{
@@ -3991,25 +3953,39 @@ void LLViewerObject::setNumTEs(const U8 num_tes)
{
LLPointer<LLViewerTexture> *new_images;
new_images = new LLPointer<LLViewerTexture>[num_tes];
+
+ LLPointer<LLViewerTexture> *new_normmaps;
+ new_normmaps = new LLPointer<LLViewerTexture>[num_tes];
+
+ LLPointer<LLViewerTexture> *new_specmaps;
+ new_specmaps = new LLPointer<LLViewerTexture>[num_tes];
for (i = 0; i < num_tes; i++)
{
if (i < getNumTEs())
{
new_images[i] = mTEImages[i];
+ new_normmaps[i] = mTENormalMaps[i];
+ new_specmaps[i] = mTESpecularMaps[i];
}
else if (getNumTEs())
{
new_images[i] = mTEImages[getNumTEs()-1];
+ new_normmaps[i] = mTENormalMaps[getNumTEs()-1];
+ new_specmaps[i] = mTESpecularMaps[getNumTEs()-1];
}
else
{
new_images[i] = NULL;
+ new_normmaps[i] = NULL;
+ new_specmaps[i] = NULL;
}
}
deleteTEImages();
mTEImages = new_images;
+ mTENormalMaps = new_normmaps;
+ mTESpecularMaps = new_specmaps;
}
else
{
@@ -4040,38 +4016,6 @@ void LLViewerObject::sendMaterialUpdate() const
}
-// formerly send_object_rotation
-void LLViewerObject::sendRotationUpdate() const
-{
- LLViewerRegion* regionp = getRegion();
- if(!regionp) return;
- gMessageSystem->newMessageFast(_PREHASH_ObjectRotation);
- gMessageSystem->nextBlockFast(_PREHASH_AgentData);
- gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
- gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
- gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, mLocalID);
- gMessageSystem->addQuatFast(_PREHASH_Rotation, getRotationEdit());
- //llinfos << "Sent rotation " << getRotationEdit() << llendl;
- gMessageSystem->sendReliable( regionp->getHost() );
-}
-
-/* Obsolete, we use MultipleObjectUpdate instead
-//// formerly send_object_position_global
-//void LLViewerObject::sendPositionUpdate() const
-//{
-// gMessageSystem->newMessageFast(_PREHASH_ObjectPosition);
-// gMessageSystem->nextBlockFast(_PREHASH_AgentData);
-// gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
-// gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
-// gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
-// gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, mLocalID );
-// gMessageSystem->addVector3Fast(_PREHASH_Position, getPositionRegion());
-// LLViewerRegion* regionp = getRegion();
-// gMessageSystem->sendReliable(regionp->getHost());
-//}
-*/
-
//formerly send_object_shape(LLViewerObject *object)
void LLViewerObject::sendShapeUpdate()
{
@@ -4120,12 +4064,18 @@ void LLViewerObject::sendTEUpdate() const
void LLViewerObject::setTE(const U8 te, const LLTextureEntry &texture_entry)
{
LLPrimitive::setTE(te, texture_entry);
-// This doesn't work, don't get any textures.
-// if (mDrawable.notNull() && mDrawable->isVisible())
-// {
- const LLUUID& image_id = getTE(te)->getID();
- mTEImages[te] = LLViewerTextureManager::getFetchedTexture(image_id, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
-// }
+
+ const LLUUID& image_id = getTE(te)->getID();
+ mTEImages[te] = LLViewerTextureManager::getFetchedTexture(image_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
+
+ if (getTE(te)->getMaterialParams().notNull())
+ {
+ const LLUUID& norm_id = getTE(te)->getMaterialParams()->getNormalID();
+ mTENormalMaps[te] = LLViewerTextureManager::getFetchedTexture(norm_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
+
+ const LLUUID& spec_id = getTE(te)->getMaterialParams()->getSpecularID();
+ mTESpecularMaps[te] = LLViewerTextureManager::getFetchedTexture(spec_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
+ }
}
void LLViewerObject::setTEImage(const U8 te, LLViewerTexture *imagep)
@@ -4142,15 +4092,15 @@ void LLViewerObject::setTEImage(const U8 te, LLViewerTexture *imagep)
}
}
-
-S32 LLViewerObject::setTETextureCore(const U8 te, const LLUUID& uuid, LLHost host)
+S32 LLViewerObject::setTETextureCore(const U8 te, LLViewerTexture *image)
{
+ const LLUUID& uuid = image->getID();
S32 retval = 0;
if (uuid != getTE(te)->getID() ||
uuid == LLUUID::null)
{
retval = LLPrimitive::setTETexture(te, uuid);
- mTEImages[te] = LLViewerTextureManager::getFetchedTexture(uuid, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, host);
+ mTEImages[te] = image;
setChanged(TEXTURE);
if (mDrawable.notNull())
{
@@ -4160,7 +4110,53 @@ S32 LLViewerObject::setTETextureCore(const U8 te, const LLUUID& uuid, LLHost hos
return retval;
}
+S32 LLViewerObject::setTENormalMapCore(const U8 te, LLViewerTexture *image)
+{
+ S32 retval = TEM_CHANGE_TEXTURE;
+ const LLUUID& uuid = image ? image->getID() : LLUUID::null;
+ if (uuid != getTE(te)->getID() ||
+ uuid == LLUUID::null)
+ {
+ LLTextureEntry* tep = getTE(te);
+ LLMaterial* mat = NULL;
+ if (tep)
+ {
+ mat = tep->getMaterialParams();
+ }
+
+ if (mat)
+ {
+ mat->setNormalID(uuid);
+ }
+ }
+ changeTENormalMap(te,image);
+ return retval;
+}
+S32 LLViewerObject::setTESpecularMapCore(const U8 te, LLViewerTexture *image)
+{
+ S32 retval = TEM_CHANGE_TEXTURE;
+ const LLUUID& uuid = image ? image->getID() : LLUUID::null;
+ if (uuid != getTE(te)->getID() ||
+ uuid == LLUUID::null)
+ {
+ LLTextureEntry* tep = getTE(te);
+ LLMaterial* mat = NULL;
+ if (tep)
+ {
+ mat = tep->getMaterialParams();
+ }
+
+ if (mat)
+ {
+ mat->setSpecularID(uuid);
+ }
+ }
+ changeTESpecularMap(te, image);
+ return retval;
+}
+
+//virtual
void LLViewerObject::changeTEImage(S32 index, LLViewerTexture* new_image)
{
if(index < 0 || index >= getNumTEs())
@@ -4170,12 +4166,47 @@ void LLViewerObject::changeTEImage(S32 index, LLViewerTexture* new_image)
mTEImages[index] = new_image ;
}
+void LLViewerObject::changeTENormalMap(S32 index, LLViewerTexture* new_image)
+{
+ if(index < 0 || index >= getNumTEs())
+ {
+ return ;
+ }
+ mTENormalMaps[index] = new_image ;
+ refreshMaterials();
+}
+
+void LLViewerObject::changeTESpecularMap(S32 index, LLViewerTexture* new_image)
+{
+ if(index < 0 || index >= getNumTEs())
+ {
+ return ;
+ }
+ mTESpecularMaps[index] = new_image ;
+ refreshMaterials();
+}
+
S32 LLViewerObject::setTETexture(const U8 te, const LLUUID& uuid)
{
// Invalid host == get from the agent's sim
- return setTETextureCore(te, uuid, LLHost::invalid);
+ LLViewerFetchedTexture *image = LLViewerTextureManager::getFetchedTexture(
+ uuid, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, LLHost::invalid);
+ return setTETextureCore(te,image);
}
+S32 LLViewerObject::setTENormalMap(const U8 te, const LLUUID& uuid)
+{
+ LLViewerFetchedTexture *image = (uuid == LLUUID::null) ? NULL : LLViewerTextureManager::getFetchedTexture(
+ uuid, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, LLHost::invalid);
+ return setTENormalMapCore(te, image);
+}
+
+S32 LLViewerObject::setTESpecularMap(const U8 te, const LLUUID& uuid)
+{
+ LLViewerFetchedTexture *image = (uuid == LLUUID::null) ? NULL : LLViewerTextureManager::getFetchedTexture(
+ uuid, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, LLHost::invalid);
+ return setTESpecularMapCore(te, image);
+}
S32 LLViewerObject::setTEColor(const U8 te, const LLColor3& color)
{
@@ -4336,6 +4367,59 @@ S32 LLViewerObject::setTEGlow(const U8 te, const F32 glow)
return retval;
}
+S32 LLViewerObject::setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID)
+{
+ S32 retval = 0;
+ const LLTextureEntry *tep = getTE(te);
+ if (!tep)
+ {
+ LL_WARNS("Material") << "No texture entry for te " << (S32)te
+ << ", object " << mID
+ << ", material " << pMaterialID
+ << LL_ENDL;
+ }
+ //else if (pMaterialID != tep->getMaterialID())
+ {
+ LL_DEBUGS("Material") << "Changing texture entry for te " << (S32)te
+ << ", object " << mID
+ << ", material " << pMaterialID
+ << LL_ENDL;
+ retval = LLPrimitive::setTEMaterialID(te, pMaterialID);
+ refreshMaterials();
+ }
+ return retval;
+}
+
+S32 LLViewerObject::setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams)
+{
+ S32 retval = 0;
+ const LLTextureEntry *tep = getTE(te);
+ if (!tep)
+ {
+ llwarns << "No texture entry for te " << (S32)te << ", object " << mID << llendl;
+ return 0;
+ }
+
+ retval = LLPrimitive::setTEMaterialParams(te, pMaterialParams);
+ LL_DEBUGS("Material") << "Changing material params for te " << (S32)te
+ << ", object " << mID
+ << " (" << retval << ")"
+ << LL_ENDL;
+ setTENormalMap(te, (pMaterialParams) ? pMaterialParams->getNormalID() : LLUUID::null);
+ setTESpecularMap(te, (pMaterialParams) ? pMaterialParams->getSpecularID() : LLUUID::null);
+
+ refreshMaterials();
+ return retval;
+}
+
+void LLViewerObject::refreshMaterials()
+{
+ setChanged(TEXTURE);
+ if (mDrawable.notNull())
+ {
+ gPipeline.markTextured(mDrawable);
+ }
+}
S32 LLViewerObject::setTEScale(const U8 te, const F32 s, const F32 t)
{
@@ -4437,6 +4521,74 @@ LLViewerTexture *LLViewerObject::getTEImage(const U8 face) const
}
+bool LLViewerObject::isImageAlphaBlended(const U8 te) const
+{
+ LLViewerTexture* image = getTEImage(te);
+ LLGLenum format = image ? image->getPrimaryFormat() : GL_RGB;
+ switch (format)
+ {
+ case GL_RGBA:
+ case GL_ALPHA:
+ {
+ return true;
+ }
+ break;
+
+ case GL_RGB: break;
+ default:
+ {
+ llwarns << "Unexpected tex format in LLViewerObject::isImageAlphaBlended...returning no alpha." << llendl;
+ }
+ break;
+ }
+
+ return false;
+}
+
+LLViewerTexture *LLViewerObject::getTENormalMap(const U8 face) const
+{
+ // llassert(mTEImages);
+
+ if (face < getNumTEs())
+ {
+ LLViewerTexture* image = mTENormalMaps[face];
+ if (image)
+ {
+ return image;
+ }
+ else
+ {
+ return (LLViewerTexture*)(LLViewerFetchedTexture::sDefaultImagep);
+ }
+ }
+
+ llerrs << llformat("Requested Image from invalid face: %d/%d",face,getNumTEs()) << llendl;
+
+ return NULL;
+}
+
+LLViewerTexture *LLViewerObject::getTESpecularMap(const U8 face) const
+{
+ // llassert(mTEImages);
+
+ if (face < getNumTEs())
+ {
+ LLViewerTexture* image = mTESpecularMaps[face];
+ if (image)
+ {
+ return image;
+ }
+ else
+ {
+ return (LLViewerTexture*)(LLViewerFetchedTexture::sDefaultImagep);
+ }
+ }
+
+ llerrs << llformat("Requested Image from invalid face: %d/%d",face,getNumTEs()) << llendl;
+
+ return NULL;
+}
+
void LLViewerObject::fitFaceTexture(const U8 face)
{
llinfos << "fitFaceTexture not implemented" << llendl;
@@ -4479,7 +4631,11 @@ U32 LLViewerObject::getNumVertices() const
num_faces = mDrawable->getNumFaces();
for (i = 0; i < num_faces; i++)
{
- num_vertices += mDrawable->getFace(i)->getGeomCount();
+ LLFace * facep = mDrawable->getFace(i);
+ if (facep)
+ {
+ num_vertices += facep->getGeomCount();
+ }
}
}
return num_vertices;
@@ -4494,7 +4650,11 @@ U32 LLViewerObject::getNumIndices() const
num_faces = mDrawable->getNumFaces();
for (i = 0; i < num_faces; i++)
{
- num_indices += mDrawable->getFace(i)->getIndicesCount();
+ LLFace * facep = mDrawable->getFace(i);
+ if (facep)
+ {
+ num_indices += facep->getIndicesCount();
+ }
}
}
return num_indices;
@@ -4580,19 +4740,11 @@ void LLViewerObject::clearIcon()
LLViewerObject* LLViewerObject::getSubParent()
{
- if (isJointChild())
- {
- return this;
- }
return (LLViewerObject*) getParent();
}
const LLViewerObject* LLViewerObject::getSubParent() const
{
- if (isJointChild())
- {
- return this;
- }
return (const LLViewerObject*) getParent();
}
@@ -4712,7 +4864,7 @@ void LLViewerObject::unpackParticleSource(const S32 block_num, const LLUUID& own
}
}
-void LLViewerObject::unpackParticleSource(LLDataPacker &dp, const LLUUID& owner_id)
+void LLViewerObject::unpackParticleSource(LLDataPacker &dp, const LLUUID& owner_id, bool legacy)
{
if (!mPartSourcep.isNull() && mPartSourcep->isDead())
{
@@ -4721,7 +4873,7 @@ void LLViewerObject::unpackParticleSource(LLDataPacker &dp, const LLUUID& owner_
if (mPartSourcep)
{
// If we've got one already, just update the existing source (or remove it)
- if (!LLViewerPartSourceScript::unpackPSS(this, mPartSourcep, dp))
+ if (!LLViewerPartSourceScript::unpackPSS(this, mPartSourcep, dp, legacy))
{
mPartSourcep->setDead();
mPartSourcep = NULL;
@@ -4729,7 +4881,7 @@ void LLViewerObject::unpackParticleSource(LLDataPacker &dp, const LLUUID& owner_
}
else
{
- LLPointer<LLViewerPartSourceScript> pss = LLViewerPartSourceScript::unpackPSS(this, NULL, dp);
+ LLPointer<LLViewerPartSourceScript> pss = LLViewerPartSourceScript::unpackPSS(this, NULL, dp, legacy);
//If the owner is muted, don't create the system
if(LLMuteList::getInstance()->isMuted(owner_id, LLMute::flagParticles)) return;
// We need to be able to deal with a particle source that hasn't changed, but still got an update!
@@ -4771,9 +4923,11 @@ void LLViewerObject::deleteParticleSource()
// virtual
void LLViewerObject::updateDrawable(BOOL force_damped)
{
- if (mDrawable.notNull() &&
- !mDrawable->isState(LLDrawable::ON_MOVE_LIST) &&
- isChanged(MOVED))
+ if (!isChanged(MOVED))
+ { //most common case, having an empty if case here makes for better branch prediction
+ }
+ else if (mDrawable.notNull() &&
+ !mDrawable->isState(LLDrawable::ON_MOVE_LIST))
{
BOOL damped_motion =
!isChanged(SHIFTED) && // not shifted between regions this frame and...
@@ -5138,7 +5292,7 @@ BOOL LLViewerObject::permAnyOwner() const
{
if (isRootEdit())
{
- return ((mFlags & FLAGS_OBJECT_ANY_OWNER) != 0);
+ return flagObjectAnyOwner();
}
else
{
@@ -5160,7 +5314,7 @@ BOOL LLViewerObject::permYouOwner() const
return TRUE;
}
# endif
- return ((mFlags & FLAGS_OBJECT_YOU_OWNER) != 0);
+ return flagObjectYouOwner();
#endif
}
else
@@ -5174,7 +5328,7 @@ BOOL LLViewerObject::permGroupOwner() const
{
if (isRootEdit())
{
- return ((mFlags & FLAGS_OBJECT_GROUP_OWNED) != 0);
+ return flagObjectGroupOwned();
}
else
{
@@ -5197,7 +5351,7 @@ BOOL LLViewerObject::permOwnerModify() const
return TRUE;
}
# endif
- return ((mFlags & FLAGS_OBJECT_OWNER_MODIFY) != 0);
+ return flagObjectOwnerModify();
#endif
}
else
@@ -5221,7 +5375,7 @@ BOOL LLViewerObject::permModify() const
return TRUE;
}
# endif
- return ((mFlags & FLAGS_OBJECT_MODIFY) != 0);
+ return flagObjectModify();
#endif
}
else
@@ -5245,7 +5399,7 @@ BOOL LLViewerObject::permCopy() const
return TRUE;
}
# endif
- return ((mFlags & FLAGS_OBJECT_COPY) != 0);
+ return flagObjectCopy();
#endif
}
else
@@ -5269,7 +5423,7 @@ BOOL LLViewerObject::permMove() const
return TRUE;
}
# endif
- return ((mFlags & FLAGS_OBJECT_MOVE) != 0);
+ return flagObjectMove();
#endif
}
else
@@ -5293,7 +5447,7 @@ BOOL LLViewerObject::permTransfer() const
return TRUE;
}
# endif
- return ((mFlags & FLAGS_OBJECT_TRANSFER) != 0);
+ return flagObjectTransfer();
#endif
}
else
@@ -5336,21 +5490,19 @@ void LLViewerObject::markForUpdate(BOOL priority)
}
}
+bool LLViewerObject::isPermanentEnforced() const
+{
+ return flagObjectPermanent() && (mRegionp != gAgent.getRegion()) && !gAgent.isGodlike();
+}
+
bool LLViewerObject::getIncludeInSearch() const
{
- return ((mFlags & FLAGS_INCLUDE_IN_SEARCH) != 0);
+ return flagIncludeInSearch();
}
void LLViewerObject::setIncludeInSearch(bool include_in_search)
{
- if (include_in_search)
- {
- mFlags |= FLAGS_INCLUDE_IN_SEARCH;
- }
- else
- {
- mFlags &= ~FLAGS_INCLUDE_IN_SEARCH;
- }
+ setFlags(FLAGS_INCLUDE_IN_SEARCH, include_in_search);
}
void LLViewerObject::setRegion(LLViewerRegion *regionp)
@@ -5389,8 +5541,8 @@ void LLViewerObject::updateRegion(LLViewerRegion *regionp)
bool LLViewerObject::specialHoverCursor() const
{
- return (mFlags & FLAGS_USE_PHYSICS)
- || (mFlags & FLAGS_HANDLE_TOUCH)
+ return flagUsePhysics()
+ || flagHandleTouch()
|| (mClickAction != 0);
}
@@ -5403,10 +5555,15 @@ void LLViewerObject::updateFlags(BOOL physics_changed)
gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, getLocalID() );
- gMessageSystem->addBOOLFast(_PREHASH_UsePhysics, usePhysics() );
+ gMessageSystem->addBOOLFast(_PREHASH_UsePhysics, flagUsePhysics() );
gMessageSystem->addBOOL("IsTemporary", flagTemporaryOnRez() );
gMessageSystem->addBOOL("IsPhantom", flagPhantom() );
- gMessageSystem->addBOOL("CastsShadows", flagCastShadows() );
+
+ // stinson 02/28/2012 : This CastsShadows BOOL is no longer used in either the viewer or the simulator
+ // The simulator code does not even unpack this value when the message is received.
+ // This could be potentially hijacked in the future for another use should the urgent need arise.
+ gMessageSystem->addBOOL("CastsShadows", FALSE );
+
if (physics_changed)
{
gMessageSystem->nextBlock("ExtraPhysics");
@@ -5421,6 +5578,19 @@ void LLViewerObject::updateFlags(BOOL physics_changed)
BOOL LLViewerObject::setFlags(U32 flags, BOOL state)
{
+ BOOL setit = setFlagsWithoutUpdate(flags, state);
+
+ // BUG: Sometimes viewer physics and simulator physics get
+ // out of sync. To fix this, always send update to simulator.
+// if (setit)
+ {
+ updateFlags();
+ }
+ return setit;
+}
+
+BOOL LLViewerObject::setFlagsWithoutUpdate(U32 flags, BOOL state)
+{
BOOL setit = FALSE;
if (state)
{
@@ -5438,22 +5608,18 @@ BOOL LLViewerObject::setFlags(U32 flags, BOOL state)
setit = TRUE;
}
}
-
- // BUG: Sometimes viewer physics and simulator physics get
- // out of sync. To fix this, always send update to simulator.
-// if (setit)
- {
- updateFlags();
- }
return setit;
}
void LLViewerObject::setPhysicsShapeType(U8 type)
{
mPhysicsShapeUnknown = false;
+ if (type != mPhysicsShapeType)
+ {
mPhysicsShapeType = type;
mCostStale = true;
}
+}
void LLViewerObject::setPhysicsGravity(F32 gravity)
{
@@ -5479,7 +5645,6 @@ U8 LLViewerObject::getPhysicsShapeType() const
{
if (mPhysicsShapeUnknown)
{
- mPhysicsShapeUnknown = false;
gObjectList.updatePhysicsFlags(this);
}
@@ -5501,18 +5666,31 @@ void LLViewerObject::applyAngularVelocity(F32 dt)
ang_vel *= 1.f/omega;
+ // calculate the delta increment based on the object's angular velocity
dQ.setQuat(angle, ang_vel);
+
+ // accumulate the angular velocity rotations to re-apply in the case of an object update
+ mAngularVelocityRot *= dQ;
+ // Just apply the delta increment to the current rotation
setRotation(getRotation()*dQ);
setChanged(MOVED | SILHOUETTE);
}
}
-void LLViewerObject::resetRot()
+void LLViewerObject::resetRotTime()
{
mRotTime = 0.0f;
}
+void LLViewerObject::resetRot()
+{
+ resetRotTime();
+
+ // Reset the accumulated angular velocity rotation
+ mAngularVelocityRot.loadIdentity();
+}
+
U32 LLViewerObject::getPartitionType() const
{
return LLViewerRegion::PARTITION_NONE;
@@ -5549,6 +5727,11 @@ F32 LLAlphaObject::getPartSize(S32 idx)
return 0.f;
}
+void LLAlphaObject::getBlendFunc(S32 face, U32& src, U32& dst)
+{
+
+}
+
// virtual
void LLStaticViewerObject::updateDrawable(BOOL force_damped)
{
@@ -5698,6 +5881,13 @@ void LLViewerObject::resetChildrenPosition(const LLVector3& offset, BOOL simplif
return ;
}
+// virtual
+BOOL LLViewerObject::isTempAttachment() const
+{
+ return (mID.notNull() && (mID == mAttachmentItemID));
+}
+
+
const LLUUID &LLViewerObject::getAttachmentItemID() const
{
return mAttachmentItemID;
diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h
index c8152e1539..80bdd628a1 100644..100755
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -34,7 +34,6 @@
#include "llhudicon.h"
#include "llinventory.h"
#include "llrefcount.h"
-#include "llmemtype.h"
#include "llprimitive.h"
#include "lluuid.h"
#include "llvoinventorylistener.h"
@@ -88,18 +87,6 @@ typedef void (*inventory_callback)(LLViewerObject*,
S32 serial_num,
void*);
-// a small struct for keeping track of joints
-struct LLVOJointInfo
-{
- EHavokJointType mJointType;
- LLVector3 mPivot; // parent-frame
- // whether the below an axis or anchor (and thus its frame)
- // depends on the joint type:
- // HINGE ==> axis=parent-frame
- // P2P ==> anchor=child-frame
- LLVector3 mAxisOrAnchor;
-};
-
// for exporting textured materials from SL
struct LLMaterialExportInfo
{
@@ -140,7 +127,6 @@ public:
typedef const child_list_t const_child_list_t;
LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp, BOOL is_global = FALSE);
- MEM_TYPE_NEW(LLMemType::MTYPE_OBJECT);
virtual void markDead(); // Mark this object as dead, and clean up its references
BOOL isDead() const {return mDead;}
@@ -157,7 +143,7 @@ public:
LLNameValue* getNVPair(const std::string& name) const; // null if no name value pair by that name
// Object create and update functions
- virtual BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time);
+ virtual void idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time);
// Types of media we can associate
enum { MEDIA_NONE = 0, MEDIA_SET = 1 };
@@ -185,11 +171,11 @@ public:
virtual BOOL isAttachment() const { return FALSE; }
virtual LLVOAvatar* getAvatar() const; //get the avatar this object is attached to, or NULL if object is not an attachment
virtual BOOL isHUDAttachment() const { return FALSE; }
+ virtual BOOL isTempAttachment() const;
+
virtual void updateRadius() {};
virtual F32 getVObjRadius() const; // default implemenation is mDrawable->getRadius()
- BOOL isJointChild() const { return mJointInfo ? TRUE : FALSE; }
- EHavokJointType getJointType() const { return mJointInfo ? mJointInfo->mJointType : HJT_INVALID; }
// for jointed and other parent-relative hacks
LLViewerObject* getSubParent();
const LLViewerObject* getSubParent() const;
@@ -212,6 +198,9 @@ public:
virtual BOOL updateLOD();
virtual BOOL setDrawableParent(LLDrawable* parentp);
F32 getRotTime() { return mRotTime; }
+private:
+ void resetRotTime();
+public:
void resetRot();
void applyAngularVelocity(F32 dt);
@@ -224,11 +213,13 @@ public:
LLViewerRegion* getRegion() const { return mRegionp; }
BOOL isSelected() const { return mUserSelected; }
- virtual void setSelected(BOOL sel) { mUserSelected = sel; mRotTime = 0.f;}
+ virtual void setSelected(BOOL sel);
const LLUUID &getID() const { return mID; }
U32 getLocalID() const { return mLocalID; }
U32 getCRC() const { return mTotalCRC; }
+ S32 getListIndex() const { return mListIndex; }
+ void setListIndex(S32 idx) { mListIndex = idx; }
virtual BOOL isFlexible() const { return FALSE; }
virtual BOOL isSculpted() const { return FALSE; }
@@ -269,17 +260,17 @@ public:
//detect if given line segment (in agent space) intersects with this viewer object.
//returns TRUE if intersection detected and returns information about intersection
- virtual BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end,
+ virtual BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
S32 face = -1, // which face to check, -1 = ALL_SIDES
BOOL pick_transparent = FALSE,
S32* face_hit = NULL, // which face was hit
- LLVector3* intersection = NULL, // return the intersection point
+ LLVector4a* intersection = NULL, // return the intersection point
LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
- LLVector3* normal = NULL, // return the surface normal at the intersection point
- LLVector3* bi_normal = NULL // return the surface bi-normal at the intersection point
+ LLVector4a* normal = NULL, // return the surface normal at the intersection point
+ LLVector4a* tangent = NULL // return the surface tangent at the intersection point
);
- virtual BOOL lineSegmentBoundingBox(const LLVector3& start, const LLVector3& end);
+ virtual BOOL lineSegmentBoundingBox(const LLVector4a& start, const LLVector4a& end);
virtual const LLVector3d getPositionGlobal() const;
virtual const LLVector3 &getPositionRegion() const;
@@ -308,12 +299,15 @@ public:
inline void setRotation(const F32 x, const F32 y, const F32 z, BOOL damped = FALSE);
inline void setRotation(const LLQuaternion& quat, BOOL damped = FALSE);
- void sendRotationUpdate() const;
/*virtual*/ void setNumTEs(const U8 num_tes);
/*virtual*/ void setTE(const U8 te, const LLTextureEntry &texture_entry);
/*virtual*/ S32 setTETexture(const U8 te, const LLUUID &uuid);
- S32 setTETextureCore(const U8 te, const LLUUID& uuid, LLHost host);
+ /*virtual*/ S32 setTENormalMap(const U8 te, const LLUUID &uuid);
+ /*virtual*/ S32 setTESpecularMap(const U8 te, const LLUUID &uuid);
+ S32 setTETextureCore(const U8 te, LLViewerTexture *image);
+ S32 setTENormalMapCore(const U8 te, LLViewerTexture *image);
+ S32 setTESpecularMapCore(const U8 te, LLViewerTexture *image);
/*virtual*/ S32 setTEColor(const U8 te, const LLColor3 &color);
/*virtual*/ S32 setTEColor(const U8 te, const LLColor4 &color);
/*virtual*/ S32 setTEScale(const U8 te, const F32 s, const F32 t);
@@ -330,11 +324,25 @@ public:
/*virtual*/ S32 setTEFullbright(const U8 te, const U8 fullbright );
/*virtual*/ S32 setTEMediaFlags(const U8 te, const U8 media_flags );
/*virtual*/ S32 setTEGlow(const U8 te, const F32 glow);
+ /*virtual*/ S32 setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID);
+ /*virtual*/ S32 setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams);
+
+ // Used by Materials update functions to properly kick off rebuilds
+ // of VBs etc when materials updates require changes.
+ //
+ void refreshMaterials();
+
/*virtual*/ BOOL setMaterial(const U8 material);
virtual void setTEImage(const U8 te, LLViewerTexture *imagep); // Not derived from LLPrimitive
- void changeTEImage(S32 index, LLViewerTexture* new_image) ;
+ virtual void changeTEImage(S32 index, LLViewerTexture* new_image) ;
+ virtual void changeTENormalMap(S32 index, LLViewerTexture* new_image) ;
+ virtual void changeTESpecularMap(S32 index, LLViewerTexture* new_image) ;
LLViewerTexture *getTEImage(const U8 te) const;
+ LLViewerTexture *getTENormalMap(const U8 te) const;
+ LLViewerTexture *getTESpecularMap(const U8 te) const;
+ bool isImageAlphaBlended(const U8 te) const;
+
void fitFaceTexture(const U8 face);
void sendTEUpdate() const; // Sends packed representation of all texture entry information
@@ -432,12 +440,15 @@ public:
// manager until we have better iterators.
void updateInventory(LLViewerInventoryItem* item, U8 key, bool is_new);
void updateInventoryLocal(LLInventoryItem* item, U8 key); // Update without messaging.
+ void updateTextureInventory(LLViewerInventoryItem* item, U8 key, bool is_new);
LLInventoryObject* getInventoryObject(const LLUUID& item_id);
void getInventoryContents(LLInventoryObject::object_list_t& objects);
LLInventoryObject* getInventoryRoot();
LLViewerInventoryItem* getInventoryItemByAsset(const LLUUID& asset_id);
S16 getInventorySerial() const { return mInventorySerialNum; }
+ bool isTextureInInventory(LLViewerInventoryItem* item);
+
// These functions does viewer-side only object inventory modifications
void updateViewerInventoryAsset(
const LLViewerInventoryItem* item,
@@ -468,26 +479,37 @@ public:
BOOL permCopy() const;
BOOL permMove() const;
BOOL permTransfer() const;
- inline BOOL usePhysics() const { return ((mFlags & FLAGS_USE_PHYSICS) != 0); }
+ inline BOOL flagUsePhysics() const { return ((mFlags & FLAGS_USE_PHYSICS) != 0); }
+ inline BOOL flagObjectAnyOwner() const { return ((mFlags & FLAGS_OBJECT_ANY_OWNER) != 0); }
+ inline BOOL flagObjectYouOwner() const { return ((mFlags & FLAGS_OBJECT_YOU_OWNER) != 0); }
+ inline BOOL flagObjectGroupOwned() const { return ((mFlags & FLAGS_OBJECT_GROUP_OWNED) != 0); }
+ inline BOOL flagObjectOwnerModify() const { return ((mFlags & FLAGS_OBJECT_OWNER_MODIFY) != 0); }
+ inline BOOL flagObjectModify() const { return ((mFlags & FLAGS_OBJECT_MODIFY) != 0); }
+ inline BOOL flagObjectCopy() const { return ((mFlags & FLAGS_OBJECT_COPY) != 0); }
+ inline BOOL flagObjectMove() const { return ((mFlags & FLAGS_OBJECT_MOVE) != 0); }
+ inline BOOL flagObjectTransfer() const { return ((mFlags & FLAGS_OBJECT_TRANSFER) != 0); }
+ inline BOOL flagObjectPermanent() const { return ((mFlags & FLAGS_AFFECTS_NAVMESH) != 0); }
+ inline BOOL flagCharacter() const { return ((mFlags & FLAGS_CHARACTER) != 0); }
+ inline BOOL flagVolumeDetect() const { return ((mFlags & FLAGS_VOLUME_DETECT) != 0); }
+ inline BOOL flagIncludeInSearch() const { return ((mFlags & FLAGS_INCLUDE_IN_SEARCH) != 0); }
inline BOOL flagScripted() const { return ((mFlags & FLAGS_SCRIPTED) != 0); }
inline BOOL flagHandleTouch() const { return ((mFlags & FLAGS_HANDLE_TOUCH) != 0); }
inline BOOL flagTakesMoney() const { return ((mFlags & FLAGS_TAKES_MONEY) != 0); }
inline BOOL flagPhantom() const { return ((mFlags & FLAGS_PHANTOM) != 0); }
inline BOOL flagInventoryEmpty() const { return ((mFlags & FLAGS_INVENTORY_EMPTY) != 0); }
- inline BOOL flagCastShadows() const { return ((mFlags & FLAGS_CAST_SHADOWS) != 0); }
inline BOOL flagAllowInventoryAdd() const { return ((mFlags & FLAGS_ALLOW_INVENTORY_DROP) != 0); }
- inline BOOL flagTemporary() const { return ((mFlags & FLAGS_TEMPORARY) != 0); }
inline BOOL flagTemporaryOnRez() const { return ((mFlags & FLAGS_TEMPORARY_ON_REZ) != 0); }
inline BOOL flagAnimSource() const { return ((mFlags & FLAGS_ANIM_SOURCE) != 0); }
inline BOOL flagCameraSource() const { return ((mFlags & FLAGS_CAMERA_SOURCE) != 0); }
inline BOOL flagCameraDecoupled() const { return ((mFlags & FLAGS_CAMERA_DECOUPLED) != 0); }
- inline BOOL flagObjectMove() const { return ((mFlags & FLAGS_OBJECT_MOVE) != 0); }
U8 getPhysicsShapeType() const;
inline F32 getPhysicsGravity() const { return mPhysicsGravity; }
inline F32 getPhysicsFriction() const { return mPhysicsFriction; }
inline F32 getPhysicsDensity() const { return mPhysicsDensity; }
inline F32 getPhysicsRestitution() const { return mPhysicsRestitution; }
+
+ bool isPermanentEnforced() const;
bool getIncludeInSearch() const;
void setIncludeInSearch(bool include_in_search);
@@ -504,6 +526,7 @@ public:
void updateFlags(BOOL physics_changed = FALSE);
BOOL setFlags(U32 flag, BOOL state);
+ BOOL setFlagsWithoutUpdate(U32 flag, BOOL state);
void setPhysicsShapeType(U8 type);
void setPhysicsGravity(F32 gravity);
void setPhysicsFriction(F32 friction);
@@ -581,6 +604,7 @@ public:
} EPhysicsShapeType;
LLUUID mID;
+ LLUUID mOwnerID; //null if unknown
// unique within region, not unique across regions
// Local ID = 0 is not used
@@ -589,15 +613,22 @@ public:
// Last total CRC received from sim, used for caching
U32 mTotalCRC;
+ // index into LLViewerObjectList::mActiveObjects or -1 if not in list
+ S32 mListIndex;
+
LLPointer<LLViewerTexture> *mTEImages;
+ LLPointer<LLViewerTexture> *mTENormalMaps;
+ LLPointer<LLViewerTexture> *mTESpecularMaps;
// Selection, picking and rendering variables
U32 mGLName; // GL "name" used by selection code
BOOL mbCanSelect; // true if user can select this object by clicking
+private:
// Grabbed from UPDATE_FLAGS
U32 mFlags;
+public:
// Sent to sim in UPDATE_FLAGS, received in ObjectPhysicsProperties
U8 mPhysicsShapeType;
F32 mPhysicsGravity;
@@ -648,13 +679,13 @@ protected:
//
static void processTaskInvFile(void** user_data, S32 error_code, LLExtStat ext_status);
- void loadTaskInvFile(const std::string& filename);
+ BOOL loadTaskInvFile(const std::string& filename);
void doInventoryCallback();
BOOL isOnMap();
void unpackParticleSource(const S32 block_num, const LLUUID& owner_id);
- void unpackParticleSource(LLDataPacker &dp, const LLUUID& owner_id);
+ void unpackParticleSource(LLDataPacker &dp, const LLUUID& owner_id, bool legacy);
void deleteParticleSource();
void setParticleSource(const LLPartSysData& particle_parameters, const LLUUID& owner_id);
@@ -684,6 +715,10 @@ protected:
F32 mAppAngle; // Apparent visual arc in degrees
F32 mPixelArea; // Apparent area in pixels
+ // IDs of of all items in the object's content which are added to the object's content,
+ // but not updated on the server yet. After item was updated, its ID will be removed from this list.
+ std::list<LLUUID> mPendingInventoryItemsIDs;
+
// This is the object's inventory from the viewer's perspective.
LLInventoryObject::object_list_t* mInventory;
class LLInventoryCallbackInfo
@@ -710,9 +745,9 @@ protected:
F32 mTimeDilation; // Time dilation sent with the object.
F32 mRotTime; // Amount (in seconds) that object has rotated according to angular velocity (llSetTargetOmega)
- LLQuaternion mLastRot; // last rotation received from the simulator
+ LLQuaternion mAngularVelocityRot; // accumulated rotation from the angular velocity computations
+ LLQuaternion mPreviousRotation;
- LLVOJointInfo* mJointInfo;
U8 mState; // legacy
LLViewerObjectMedia* mMedia; // NULL if no media associated
U8 mClickAction;
@@ -815,8 +850,11 @@ public:
LLStrider<LLVector3>& normalsp,
LLStrider<LLVector2>& texcoordsp,
LLStrider<LLColor4U>& colorsp,
+ LLStrider<LLColor4U>& emissivep,
LLStrider<U16>& indicesp) = 0;
+ virtual void getBlendFunc(S32 face, U32& src, U32& dst);
+
F32 mDepth;
};
diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp
index 09eec8e5ab..34d36dd887 100644..100755
--- a/indra/newview/llviewerobjectlist.cpp
+++ b/indra/newview/llviewerobjectlist.cpp
@@ -49,6 +49,8 @@
#include "llstring.h"
#include "llhudnametag.h"
#include "lldrawable.h"
+#include "llflexibleobject.h"
+#include "llviewertextureanim.h"
#include "xform.h"
#include "llsky.h"
#include "llviewercamera.h"
@@ -79,11 +81,9 @@
extern F32 gMinObjectDistance;
extern BOOL gAnimateTextures;
-void dialog_refresh_all();
+#define MAX_CONCURRENT_PHYSICS_REQUESTS 256
-#define CULL_VIS
-//#define ORPHAN_SPAM
-//#define IGNORE_DEAD
+void dialog_refresh_all();
// Global lists of objects - should go away soon.
LLViewerObjectList gObjectList;
@@ -92,8 +92,9 @@ extern LLPipeline gPipeline;
// Statics for object lookup tables.
U32 LLViewerObjectList::sSimulatorMachineIndex = 1; // Not zero deliberately, to speed up index check.
-std::map<U64, U32> LLViewerObjectList::sIPAndPortToIndex;
+std::map<U64, U32> LLViewerObjectList::sIPAndPortToIndex;
std::map<U64, LLUUID> LLViewerObjectList::sIndexAndLocalIDToUUID;
+LLStat LLViewerObjectList::sCacheHitRate("object_cache_hits", 128);
LLViewerObjectList::LLViewerObjectList()
{
@@ -106,7 +107,6 @@ LLViewerObjectList::LLViewerObjectList()
mNumNewObjects = 0;
mWasPaused = FALSE;
mNumDeadObjectUpdates = 0;
- mNumUnknownKills = 0;
mNumUnknownUpdates = 0;
}
@@ -230,7 +230,6 @@ void LLViewerObjectList::processUpdateCore(LLViewerObject* objectp,
LLDataPacker* dpp,
BOOL just_created)
{
- LLMemType mt(LLMemType::MTYPE_OBJECT_PROCESS_UPDATE_CORE);
LLMessageSystem* msg = gMessageSystem;
// ignore returned flags
@@ -294,10 +293,8 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
const EObjectUpdateType update_type,
bool cached, bool compressed)
{
- LLMemType mt(LLMemType::MTYPE_OBJECT_PROCESS_UPDATE);
LLFastTimer t(FTM_PROCESS_OBJECTS);
- LLVector3d camera_global = gAgentCamera.getCameraPositionGlobal();
LLViewerObject *objectp;
S32 num_objects;
U32 local_id;
@@ -316,6 +313,7 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
{
//llinfos << "TEST: !cached && !compressed && update_type != OUT_FULL" << llendl;
gTerseObjectUpdates += num_objects;
+ /*
S32 size;
if (mesgsys->getReceiveCompressedSize())
{
@@ -325,10 +323,12 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
{
size = mesgsys->getReceiveSize();
}
- //llinfos << "Received terse " << num_objects << " in " << size << " byte (" << size/num_objects << ")" << llendl;
+ llinfos << "Received terse " << num_objects << " in " << size << " byte (" << size/num_objects << ")" << llendl;
+ */
}
else
{
+ /*
S32 size;
if (mesgsys->getReceiveCompressedSize())
{
@@ -339,12 +339,14 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
size = mesgsys->getReceiveSize();
}
- // llinfos << "Received " << num_objects << " in " << size << " byte (" << size/num_objects << ")" << llendl;
+ llinfos << "Received " << num_objects << " in " << size << " byte (" << size/num_objects << ")" << llendl;
+ */
gFullObjectUpdates += num_objects;
}
U64 region_handle;
mesgsys->getU64Fast(_PREHASH_RegionData, _PREHASH_RegionHandle, region_handle);
+
LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(region_handle);
if (!regionp)
@@ -356,16 +358,14 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
U8 compressed_dpbuffer[2048];
LLDataPackerBinaryBuffer compressed_dp(compressed_dpbuffer, 2048);
LLDataPacker *cached_dpp = NULL;
-
-#if LL_RECORD_VIEWER_STATS
- LLViewerStatsRecorder::instance()->beginObjectUpdateEvents(regionp);
-#endif
+ LLViewerStatsRecorder& recorder = LLViewerStatsRecorder::instance();
for (i = 0; i < num_objects; i++)
{
// timer is unused?
LLTimer update_timer;
BOOL justCreated = FALSE;
+ S32 msg_size = 0;
if (cached)
{
@@ -373,6 +373,7 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
U32 crc;
mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_ID, id, i);
mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_CRC, crc, i);
+ msg_size += sizeof(U32) * 2;
// Lookup data packer and add this id to cache miss lists if necessary.
U8 cache_miss_type = LLViewerRegion::CACHE_MISS_TYPE_NONE;
@@ -388,18 +389,14 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
else
{
// Cache Miss.
- #if LL_RECORD_VIEWER_STATS
- LLViewerStatsRecorder::instance()->recordCacheMissEvent(id, update_type, cache_miss_type);
- #endif
+ recorder.cacheMissEvent(id, update_type, cache_miss_type, msg_size);
continue; // no data packer, skip this object
}
}
else if (compressed)
{
- U8 compbuffer[2048];
S32 uncompressed_length = 2048;
- S32 compressed_length;
compressed_dp.reset();
U32 flags = 0;
@@ -408,24 +405,9 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_UpdateFlags, flags, i);
}
- // I don't think we ever use this flag from the server. DK 2010/12/09
- if (flags & FLAGS_ZLIB_COMPRESSED)
- {
- //llinfos << "TEST: flags & FLAGS_ZLIB_COMPRESSED" << llendl;
- compressed_length = mesgsys->getSizeFast(_PREHASH_ObjectData, i, _PREHASH_Data);
- mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_Data, compbuffer, 0, i);
- uncompressed_length = 2048;
- uncompress(compressed_dpbuffer, (unsigned long *)&uncompressed_length,
- compbuffer, compressed_length);
- compressed_dp.assignBuffer(compressed_dpbuffer, uncompressed_length);
- }
- else
- {
- uncompressed_length = mesgsys->getSizeFast(_PREHASH_ObjectData, i, _PREHASH_Data);
- mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_Data, compressed_dpbuffer, 0, i);
- compressed_dp.assignBuffer(compressed_dpbuffer, uncompressed_length);
- }
-
+ uncompressed_length = mesgsys->getSizeFast(_PREHASH_ObjectData, i, _PREHASH_Data);
+ mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_Data, compressed_dpbuffer, 0, i);
+ compressed_dp.assignBuffer(compressed_dpbuffer, uncompressed_length);
if (update_type != OUT_TERSE_IMPROVED) // OUT_FULL_COMPRESSED only?
{
@@ -450,6 +432,8 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
else if (update_type != OUT_FULL) // !compressed, !OUT_FULL ==> OUT_FULL_CACHED only?
{
mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_ID, local_id, i);
+ msg_size += sizeof(U32);
+
getUUIDFromLocal(fullid,
local_id,
gMessageSystem->getSenderIP(),
@@ -464,6 +448,8 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
{
mesgsys->getUUIDFast(_PREHASH_ObjectData, _PREHASH_FullID, fullid, i);
mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_ID, local_id, i);
+ msg_size += sizeof(LLUUID);
+ msg_size += sizeof(U32);
// llinfos << "Full Update, obj " << local_id << ", global ID" << fullid << "from " << mesgsys->getSender() << llendl;
}
objectp = findObject(fullid);
@@ -509,9 +495,7 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
if (update_type == OUT_TERSE_IMPROVED)
{
// llinfos << "terse update for an unknown object (compressed):" << fullid << llendl;
- #if LL_RECORD_VIEWER_STATS
- LLViewerStatsRecorder::instance()->recordObjectUpdateFailure(local_id, update_type);
- #endif
+ recorder.objectUpdateFailure(local_id, update_type, msg_size);
continue;
}
}
@@ -523,22 +507,20 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
if (update_type != OUT_FULL)
{
//llinfos << "terse update for an unknown object:" << fullid << llendl;
- #if LL_RECORD_VIEWER_STATS
- LLViewerStatsRecorder::instance()->recordObjectUpdateFailure(local_id, update_type);
- #endif
+ recorder.objectUpdateFailure(local_id, update_type, msg_size);
continue;
}
mesgsys->getU8Fast(_PREHASH_ObjectData, _PREHASH_PCode, pcode, i);
+ msg_size += sizeof(U8);
+
}
#ifdef IGNORE_DEAD
if (mDeadObjects.find(fullid) != mDeadObjects.end())
{
mNumDeadObjectUpdates++;
//llinfos << "update for a dead object:" << fullid << llendl;
- #if LL_RECORD_VIEWER_STATS
- LLViewerStatsRecorder::instance()->recordObjectUpdateFailure(local_id, update_type);
- #endif
+ recorder.objectUpdateFailure(local_id, update_type, msg_size);
continue;
}
#endif
@@ -547,13 +529,13 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
if (!objectp)
{
llinfos << "createObject failure for object: " << fullid << llendl;
- #if LL_RECORD_VIEWER_STATS
- LLViewerStatsRecorder::instance()->recordObjectUpdateFailure(local_id, update_type);
- #endif
+ recorder.objectUpdateFailure(local_id, update_type, msg_size);
continue;
}
justCreated = TRUE;
mNumNewObjects++;
+ sCacheHitRate.addValue(cached ? 100.f : 0.f);
+
}
@@ -573,12 +555,8 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
if (update_type != OUT_TERSE_IMPROVED) // OUT_FULL_COMPRESSED only?
{
bCached = true;
- #if LL_RECORD_VIEWER_STATS
LLViewerRegion::eCacheUpdateResult result = objectp->mRegionp->cacheFullUpdate(objectp, compressed_dp);
- LLViewerStatsRecorder::instance()->recordCacheFullUpdate(local_id, update_type, result, objectp);
- #else
- objectp->mRegionp->cacheFullUpdate(objectp, compressed_dp);
- #endif
+ recorder.cacheFullUpdate(local_id, update_type, result, objectp, msg_size);
}
}
else if (cached) // Cache hit only?
@@ -594,16 +572,12 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
}
processUpdateCore(objectp, user_data, i, update_type, NULL, justCreated);
}
- #if LL_RECORD_VIEWER_STATS
- LLViewerStatsRecorder::instance()->recordObjectUpdateEvent(local_id, update_type, objectp);
- #endif
+ recorder.objectUpdateEvent(local_id, update_type, objectp, msg_size);
objectp->setLastUpdateType(update_type);
objectp->setLastUpdateCached(bCached);
}
-#if LL_RECORD_VIEWER_STATS
- LLViewerStatsRecorder::instance()->endObjectUpdateEvents();
-#endif
+ recorder.log(0.2f);
LLVOAvatar::cullAvatarsByPixelArea();
}
@@ -728,12 +702,12 @@ public:
}
}
- void error(U32 statusNum, const std::string& reason)
+ void errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content)
{
llwarns
<< "Transport error requesting object cost "
- << "HTTP status: " << statusNum << ", reason: "
- << reason << "." << llendl;
+ << "[status: " << statusNum << "]: "
+ << content << llendl;
// TODO*: Error message to user
// For now just clear the request from the pending list
@@ -817,12 +791,12 @@ public:
}
}
- void error(U32 statusNum, const std::string& reason)
+ void errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content)
{
llwarns
<< "Transport error requesting object physics flags "
- << "HTTP status: " << statusNum << ", reason: "
- << reason << "." << llendl;
+ << "[status: " << statusNum << "]: "
+ << content << llendl;
// TODO*: Error message to user
// For now just clear the request from the pending list
@@ -892,8 +866,6 @@ private:
void LLViewerObjectList::update(LLAgent &agent, LLWorld &world)
{
- LLMemType mt(LLMemType::MTYPE_OBJECT);
-
// Update globals
LLViewerObject::setVelocityInterpolate( gSavedSettings.getBOOL("VelocityInterpolate") );
LLViewerObject::setPingInterpolate( gSavedSettings.getBOOL("PingInterpolate") );
@@ -935,28 +907,35 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world)
const F64 frame_time = LLFrameTimer::getElapsedSeconds();
- std::vector<LLViewerObject*> kill_list;
- S32 num_active_objects = 0;
LLViewerObject *objectp = NULL;
// Make a copy of the list in case something in idleUpdate() messes with it
- std::vector<LLViewerObject*> idle_list;
+ static std::vector<LLViewerObject*> idle_list;
+
+ U32 idle_count = 0;
static LLFastTimer::DeclareTimer idle_copy("Idle Copy");
{
LLFastTimer t(idle_copy);
- idle_list.reserve( mActiveObjects.size() );
- for (std::set<LLPointer<LLViewerObject> >::iterator active_iter = mActiveObjects.begin();
+ for (std::vector<LLPointer<LLViewerObject> >::iterator active_iter = mActiveObjects.begin();
active_iter != mActiveObjects.end(); active_iter++)
{
objectp = *active_iter;
if (objectp)
{
+ if (idle_count >= idle_list.size())
+ {
idle_list.push_back( objectp );
}
else
+ {
+ idle_list[idle_count] = objectp;
+ }
+ ++idle_count;
+ }
+ else
{ // There shouldn't be any NULL pointers in the list, but they have caused
// crashes before. This may be idleUpdate() messing with the list.
llwarns << "LLViewerObjectList::update has a NULL objectp" << llendl;
@@ -964,10 +943,13 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world)
}
}
+ std::vector<LLViewerObject*>::iterator idle_end = idle_list.begin()+idle_count;
+
if (gSavedSettings.getBOOL("FreezeTime"))
{
+
for (std::vector<LLViewerObject*>::iterator iter = idle_list.begin();
- iter != idle_list.end(); iter++)
+ iter != idle_end; iter++)
{
objectp = *iter;
if (objectp->isAvatar())
@@ -979,27 +961,25 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world)
else
{
for (std::vector<LLViewerObject*>::iterator idle_iter = idle_list.begin();
- idle_iter != idle_list.end(); idle_iter++)
+ idle_iter != idle_end; idle_iter++)
{
objectp = *idle_iter;
- if (!objectp->idleUpdate(agent, world, frame_time))
- {
- // If Idle Update returns false, kill object!
- kill_list.push_back(objectp);
- }
- else
- {
- num_active_objects++;
- }
+ llassert(objectp->isActive());
+ objectp->idleUpdate(agent, world, frame_time);
}
- for (std::vector<LLViewerObject*>::iterator kill_iter = kill_list.begin();
- kill_iter != kill_list.end(); kill_iter++)
+
+ //update flexible objects
+ LLVolumeImplFlexible::updateClass();
+
+ //update animated textures
+ if (gAnimateTextures)
{
- objectp = *kill_iter;
- killObject(objectp);
+ LLViewerTextureAnim::updateClass();
}
}
+
+
fetchObjectCosts();
fetchPhysicsFlags();
@@ -1066,7 +1046,7 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world)
*/
LLViewerStats::getInstance()->mNumObjectsStat.addValue((S32) mObjects.size());
- LLViewerStats::getInstance()->mNumActiveObjectsStat.addValue(num_active_objects);
+ LLViewerStats::getInstance()->mNumActiveObjectsStat.addValue(idle_count);
LLViewerStats::getInstance()->mNumSizeCulledStat.addValue(mNumSizeCulled);
LLViewerStats::getInstance()->mNumVisCulledStat.addValue(mNumVisCulled);
}
@@ -1087,8 +1067,6 @@ void LLViewerObjectList::fetchObjectCosts()
LLSD id_list;
U32 object_index = 0;
- U32 count = 0;
-
for (
std::set<LLUUID>::iterator iter = mStaleObjectCost.begin();
iter != mStaleObjectCost.end();
@@ -1105,7 +1083,7 @@ void LLViewerObjectList::fetchObjectCosts()
mStaleObjectCost.erase(iter++);
- if (count++ >= 450)
+ if (object_index >= MAX_CONCURRENT_PHYSICS_REQUESTS)
{
break;
}
@@ -1150,7 +1128,7 @@ void LLViewerObjectList::fetchPhysicsFlags()
for (
std::set<LLUUID>::iterator iter = mStalePhysicsFlags.begin();
iter != mStalePhysicsFlags.end();
- ++iter)
+ )
{
// Check to see if a request for this object
// has already been made.
@@ -1160,12 +1138,14 @@ void LLViewerObjectList::fetchPhysicsFlags()
mPendingPhysicsFlags.insert(*iter);
id_list[object_index++] = *iter;
}
- }
- // id_list should now contain all
- // requests in mStalePhysicsFlags before, so clear
- // it now
- mStalePhysicsFlags.clear();
+ mStalePhysicsFlags.erase(iter++);
+
+ if (object_index >= MAX_CONCURRENT_PHYSICS_REQUESTS)
+ {
+ break;
+ }
+ }
if ( id_list.size() > 0 )
{
@@ -1199,7 +1179,6 @@ void LLViewerObjectList::clearDebugText()
void LLViewerObjectList::cleanupReferences(LLViewerObject *objectp)
{
- LLMemType mt(LLMemType::MTYPE_OBJECT);
if (mDeadObjects.find(objectp->mID) != mDeadObjects.end())
{
llinfos << "Object " << objectp->mID << " already on dead list!" << llendl;
@@ -1227,7 +1206,7 @@ void LLViewerObjectList::cleanupReferences(LLViewerObject *objectp)
{
//llinfos << "Removing " << objectp->mID << " " << objectp->getPCodeString() << " from active list in cleanupReferences." << llendl;
objectp->setOnActiveList(FALSE);
- mActiveObjects.erase(objectp);
+ removeFromActiveList(objectp);
}
if (objectp->isOnMap())
@@ -1404,9 +1383,29 @@ void LLViewerObjectList::cleanDeadObjects(BOOL use_timer)
mNumDeadObjects = 0;
}
+void LLViewerObjectList::removeFromActiveList(LLViewerObject* objectp)
+{
+ S32 idx = objectp->getListIndex();
+ if (idx != -1)
+ { //remove by moving last element to this object's position
+ llassert(mActiveObjects[idx] == objectp);
+
+ objectp->setListIndex(-1);
+
+ S32 last_index = mActiveObjects.size()-1;
+
+ if (idx != last_index)
+ {
+ mActiveObjects[idx] = mActiveObjects[last_index];
+ mActiveObjects[idx]->setListIndex(idx);
+ }
+
+ mActiveObjects.pop_back();
+ }
+}
+
void LLViewerObjectList::updateActive(LLViewerObject *objectp)
{
- LLMemType mt(LLMemType::MTYPE_OBJECT);
if (objectp->isDead())
{
return; // We don't update dead objects!
@@ -1418,16 +1417,38 @@ void LLViewerObjectList::updateActive(LLViewerObject *objectp)
if (active)
{
//llinfos << "Adding " << objectp->mID << " " << objectp->getPCodeString() << " to active list." << llendl;
- mActiveObjects.insert(objectp);
+ S32 idx = objectp->getListIndex();
+ if (idx <= -1)
+ {
+ mActiveObjects.push_back(objectp);
+ objectp->setListIndex(mActiveObjects.size()-1);
objectp->setOnActiveList(TRUE);
}
else
{
+ llassert(idx < mActiveObjects.size());
+ llassert(mActiveObjects[idx] == objectp);
+
+ if (idx >= mActiveObjects.size() ||
+ mActiveObjects[idx] != objectp)
+ {
+ llwarns << "Invalid object list index detected!" << llendl;
+ }
+ }
+ }
+ else
+ {
//llinfos << "Removing " << objectp->mID << " " << objectp->getPCodeString() << " from active list." << llendl;
- mActiveObjects.erase(objectp);
+ removeFromActiveList(objectp);
objectp->setOnActiveList(FALSE);
}
}
+
+ //post condition: if object is active, it must be on the active list
+ llassert(!active || std::find(mActiveObjects.begin(), mActiveObjects.end(), objectp) != mActiveObjects.end());
+
+ //post condition: if object is not active, it must not be on the active list
+ llassert(active || std::find(mActiveObjects.begin(), mActiveObjects.end(), objectp) == mActiveObjects.end());
}
void LLViewerObjectList::updateObjectCost(LLViewerObject* object)
@@ -1498,6 +1519,10 @@ void LLViewerObjectList::onPhysicsFlagsFetchFailure(const LLUUID& object_id)
mPendingPhysicsFlags.erase(object_id);
}
+static LLFastTimer::DeclareTimer FTM_SHIFT_OBJECTS("Shift Objects");
+static LLFastTimer::DeclareTimer FTM_PIPELINE_SHIFT("Pipeline Shift");
+static LLFastTimer::DeclareTimer FTM_REGION_SHIFT("Region Shift");
+
void LLViewerObjectList::shiftObjects(const LLVector3 &offset)
{
// This is called when we shift our origin when we cross region boundaries...
@@ -1509,6 +1534,8 @@ void LLViewerObjectList::shiftObjects(const LLVector3 &offset)
return;
}
+ LLFastTimer t(FTM_SHIFT_OBJECTS);
+
LLViewerObject *objectp;
for (vobj_list_t::iterator iter = mObjects.begin(); iter != mObjects.end(); ++iter)
{
@@ -1525,9 +1552,16 @@ void LLViewerObjectList::shiftObjects(const LLVector3 &offset)
}
}
+ {
+ LLFastTimer t(FTM_PIPELINE_SHIFT);
gPipeline.shiftObjects(offset);
+ }
+
+ {
+ LLFastTimer t(FTM_REGION_SHIFT);
LLWorld::getInstance()->shiftRegions(offset);
}
+}
void LLViewerObjectList::repartitionObjects()
{
@@ -1730,7 +1764,10 @@ void LLViewerObjectList::generatePickList(LLCamera &camera)
LLViewerObject* last_objectp = NULL;
for (S32 face_num = 0; face_num < drawablep->getNumFaces(); face_num++)
{
- LLViewerObject* objectp = drawablep->getFace(face_num)->getViewerObject();
+ LLFace * facep = drawablep->getFace(face_num);
+ if (!facep) continue;
+
+ LLViewerObject* objectp = facep->getViewerObject();
if (objectp && objectp != last_objectp)
{
@@ -1850,7 +1887,6 @@ void LLViewerObjectList::resetObjectBeacons()
LLViewerObject *LLViewerObjectList::createObjectViewer(const LLPCode pcode, LLViewerRegion *regionp)
{
- LLMemType mt(LLMemType::MTYPE_OBJECT);
LLUUID fullid;
fullid.generate();
@@ -1871,13 +1907,9 @@ LLViewerObject *LLViewerObjectList::createObjectViewer(const LLPCode pcode, LLVi
}
-static LLFastTimer::DeclareTimer FTM_CREATE_OBJECT("Create Object");
-
LLViewerObject *LLViewerObjectList::createObject(const LLPCode pcode, LLViewerRegion *regionp,
const LLUUID &uuid, const U32 local_id, const LLHost &sender)
{
- LLMemType mt(LLMemType::MTYPE_OBJECT);
- LLFastTimer t(FTM_CREATE_OBJECT);
LLUUID fullid;
if (uuid == LLUUID::null)
@@ -1941,7 +1973,6 @@ S32 LLViewerObjectList::findReferences(LLDrawable *drawablep) const
void LLViewerObjectList::orphanize(LLViewerObject *childp, U32 parent_id, U32 ip, U32 port)
{
- LLMemType mt(LLMemType::MTYPE_OBJECT);
#ifdef ORPHAN_SPAM
llinfos << "Orphaning object " << childp->getID() << " with parent " << parent_id << llendl;
#endif
@@ -2047,8 +2078,9 @@ void LLViewerObjectList::findOrphans(LLViewerObject* objectp, U32 ip, U32 port)
if (childp->mDrawable.notNull())
{
// Make the drawable visible again and set the drawable parent
- childp->mDrawable->setState(LLDrawable::CLEAR_INVISIBLE);
+ childp->mDrawable->clearState(LLDrawable::FORCE_INVISIBLE);
childp->setDrawableParent(objectp->mDrawable); // LLViewerObjectList::findOrphans()
+ gPipeline.markRebuild( childp->mDrawable, LLDrawable::REBUILD_ALL, TRUE );
}
// Make certain particles, icon and HUD aren't hidden
diff --git a/indra/newview/llviewerobjectlist.h b/indra/newview/llviewerobjectlist.h
index c5f2a2c1ee..6518c25d09 100644..100755
--- a/indra/newview/llviewerobjectlist.h
+++ b/indra/newview/llviewerobjectlist.h
@@ -118,7 +118,9 @@ public:
void dirtyAllObjectInventory();
+ void removeFromActiveList(LLViewerObject* objectp);
void updateActive(LLViewerObject *objectp);
+
void updateAvatarVisibility();
// Selection related stuff
@@ -127,6 +129,7 @@ public:
LLViewerObject *getSelectedObject(const U32 object_id);
inline S32 getNumObjects() { return (S32) mObjects.size(); }
+ inline S32 getNumActiveObjects() { return (S32) mActiveObjects.size(); }
void addToMap(LLViewerObject *objectp);
void removeFromMap(LLViewerObject *objectp);
@@ -185,17 +188,18 @@ public:
S32 mNumUnknownUpdates;
S32 mNumDeadObjectUpdates;
- S32 mNumUnknownKills;
S32 mNumDeadObjects;
protected:
std::vector<U64> mOrphanParents; // LocalID/ip,port of orphaned objects
std::vector<OrphanInfo> mOrphanChildren; // UUID's of orphaned objects
S32 mNumOrphans;
+ static LLStat sCacheHitRate;
+
typedef std::vector<LLPointer<LLViewerObject> > vobj_list_t;
vobj_list_t mObjects;
- std::set<LLPointer<LLViewerObject> > mActiveObjects;
+ std::vector<LLPointer<LLViewerObject> > mActiveObjects;
vobj_list_t mMapObjects;
diff --git a/indra/newview/llviewerparcelmedia.cpp b/indra/newview/llviewerparcelmedia.cpp
index 90fbc41daa..386b2fd400 100644..100755
--- a/indra/newview/llviewerparcelmedia.cpp
+++ b/indra/newview/llviewerparcelmedia.cpp
@@ -85,7 +85,6 @@ void LLViewerParcelMedia::update(LLParcel* parcel)
}
// we're in a parcel
- bool new_parcel = false;
S32 parcelid = parcel->getLocalID();
LLUUID regionid = gAgent.getRegion()->getRegionID();
@@ -94,7 +93,6 @@ void LLViewerParcelMedia::update(LLParcel* parcel)
LL_DEBUGS("Media") << "New parcel, parcel id = " << parcelid << ", region id = " << regionid << LL_ENDL;
sMediaParcelLocalID = parcelid;
sMediaRegionID = regionid;
- new_parcel = true;
}
std::string mediaUrl = std::string ( parcel->getMediaURL () );
diff --git a/indra/newview/llviewerparcelmedia.h b/indra/newview/llviewerparcelmedia.h
index 534f65b419..534f65b419 100644..100755
--- a/indra/newview/llviewerparcelmedia.h
+++ b/indra/newview/llviewerparcelmedia.h
diff --git a/indra/newview/llviewerparcelmediaautoplay.cpp b/indra/newview/llviewerparcelmediaautoplay.cpp
index 57ee583eae..57ee583eae 100644..100755
--- a/indra/newview/llviewerparcelmediaautoplay.cpp
+++ b/indra/newview/llviewerparcelmediaautoplay.cpp
diff --git a/indra/newview/llviewerparcelmediaautoplay.h b/indra/newview/llviewerparcelmediaautoplay.h
index a052362829..a052362829 100644..100755
--- a/indra/newview/llviewerparcelmediaautoplay.h
+++ b/indra/newview/llviewerparcelmediaautoplay.h
diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp
index 9db784101d..4cdb568d17 100644..100755
--- a/indra/newview/llviewerparcelmgr.cpp
+++ b/indra/newview/llviewerparcelmgr.cpp
@@ -82,7 +82,6 @@ LLPointer<LLViewerTexture> sBlockedImage;
LLPointer<LLViewerTexture> sPassImage;
// Local functions
-void optionally_start_music(const std::string& music_url);
void callback_start_music(S32 option, void* data);
void optionally_prepare_video(const LLParcel *parcelp);
void callback_prepare_video(S32 option, void* data);
@@ -546,9 +545,6 @@ LLParcelSelectionHandle LLViewerParcelMgr::selectLand(const LLVector3d &corner1,
mRequestResult = PARCEL_RESULT_NO_DATA;
- // clear the list of segments to prevent flashing
- resetSegments(mHighlightSegments);
-
mFloatingParcelSelection->setParcel(mCurrentParcel);
mCurrentParcelSelection->setParcel(NULL);
mCurrentParcelSelection = new LLParcelSelection(mCurrentParcel);
@@ -700,8 +696,8 @@ bool LLViewerParcelMgr::allowAgentScripts(const LLViewerRegion* region, const LL
// This mirrors the traditional menu bar parcel icon code, but is not
// technically correct.
return region
- && !(region->getRegionFlags() & REGION_FLAGS_SKIP_SCRIPTS)
- && !(region->getRegionFlags() & REGION_FLAGS_ESTATE_SKIP_SCRIPTS)
+ && !region->getRegionFlag(REGION_FLAGS_SKIP_SCRIPTS)
+ && !region->getRegionFlag(REGION_FLAGS_ESTATE_SKIP_SCRIPTS)
&& parcel
&& parcel->getAllowOtherScripts();
}
@@ -1589,7 +1585,7 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
if (instance->mTeleportInProgress)
{
instance->mTeleportInProgress = FALSE;
- instance->mTeleportFinishedSignal(gAgent.getPositionGlobal());
+ instance->mTeleportFinishedSignal(gAgent.getPositionGlobal(), false);
}
}
}
@@ -1662,9 +1658,6 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
// Request access list information for this land
parcel_mgr.sendParcelAccessListRequest(AL_ACCESS | AL_BAN);
- // Request the media url filter list for this land
- parcel_mgr.requestParcelMediaURLFilter();
-
// Request dwell for this land, if it's not public land.
parcel_mgr.mSelectedDwell = DWELL_NAN;
if (0 != local_id)
@@ -1773,13 +1766,13 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
};
}
-void optionally_start_music(const std::string& music_url)
+void LLViewerParcelMgr::optionally_start_music(const std::string& music_url)
{
if (gSavedSettings.getBOOL("AudioStreamingMusic"))
{
// only play music when you enter a new parcel if the UI control for this
// was not *explicitly* stopped by the user. (part of SL-4878)
- LLPanelNearByMedia* nearby_media_panel = gStatusBar->getNearbyMediaPanel();;
+ LLPanelNearByMedia* nearby_media_panel = gStatusBar->getNearbyMediaPanel();
if ((nearby_media_panel &&
nearby_media_panel->getParcelAudioAutoStart()) ||
// or they have expressed no opinion in the UI, but have autoplay on...
@@ -1993,67 +1986,6 @@ void LLViewerParcelMgr::sendParcelAccessListUpdate(U32 which)
}
}
-class LLParcelMediaURLFilterResponder : public LLHTTPClient::Responder
-{
- virtual void result(const LLSD& content)
- {
- LLViewerParcelMgr::getInstance()->receiveParcelMediaURLFilter(content);
- }
-};
-
-void LLViewerParcelMgr::requestParcelMediaURLFilter()
-{
- if (!mSelected)
- {
- return;
- }
-
- LLViewerRegion* region = LLWorld::getInstance()->getRegionFromPosGlobal( mWestSouth );
- if (!region)
- {
- return;
- }
-
- LLParcel* parcel = mCurrentParcel;
- if (!parcel)
- {
- llwarns << "no parcel" << llendl;
- return;
- }
-
- LLSD body;
- body["local-id"] = parcel->getLocalID();
- body["list"] = parcel->getMediaURLFilterList();
-
- std::string url = region->getCapability("ParcelMediaURLFilterList");
- if (!url.empty())
- {
- LLHTTPClient::post(url, body, new LLParcelMediaURLFilterResponder);
- }
- else
- {
- llwarns << "can't get ParcelMediaURLFilterList cap" << llendl;
- }
-}
-
-
-void LLViewerParcelMgr::receiveParcelMediaURLFilter(const LLSD &content)
-{
- if (content.has("list"))
- {
- LLParcel* parcel = LLViewerParcelMgr::getInstance()->mCurrentParcel;
- if (!parcel) return;
-
- if (content["local-id"].asInteger() == parcel->getLocalID())
- {
- parcel->setMediaURLFilterList(content["list"]);
-
- LLViewerParcelMgr::getInstance()->notifyObservers();
- }
- }
-}
-
-
void LLViewerParcelMgr::deedLandToGroup()
{
std::string group_name;
@@ -2125,7 +2057,7 @@ void LLViewerParcelMgr::startReleaseLand()
return;
}
/*
- if ((region->getRegionFlags() & REGION_FLAGS_BLOCK_LAND_RESELL)
+ if (region->getRegionFlag(REGION_FLAGS_BLOCK_LAND_RESELL)
&& !gAgent.isGodlike())
{
LLSD args;
@@ -2370,7 +2302,7 @@ void LLViewerParcelMgr::startDeedLandToGroup()
/*
if(!gAgent.isGodlike())
{
- if((region->getRegionFlags() & REGION_FLAGS_BLOCK_LAND_RESELL)
+ if(region->getRegionFlag(REGION_FLAGS_BLOCK_LAND_RESELL)
&& (mCurrentParcel->getOwnerID() != region->getOwner()))
{
LLSD args;
@@ -2559,7 +2491,7 @@ void LLViewerParcelMgr::onTeleportFinished(bool local, const LLVector3d& new_pos
{
// Local teleport. We already have the agent parcel data.
// Emit the signal immediately.
- getInstance()->mTeleportFinishedSignal(new_pos);
+ getInstance()->mTeleportFinishedSignal(new_pos, local);
}
else
{
diff --git a/indra/newview/llviewerparcelmgr.h b/indra/newview/llviewerparcelmgr.h
index cac8d8391c..6183b7e90e 100644..100755
--- a/indra/newview/llviewerparcelmgr.h
+++ b/indra/newview/llviewerparcelmgr.h
@@ -78,8 +78,8 @@ class LLViewerParcelMgr : public LLSingleton<LLViewerParcelMgr>
{
public:
- typedef boost::function<void (const LLVector3d&)> teleport_finished_callback_t;
- typedef boost::signals2::signal<void (const LLVector3d&)> teleport_finished_signal_t;
+ typedef boost::function<void (const LLVector3d&, const bool& local)> teleport_finished_callback_t;
+ typedef boost::signals2::signal<void (const LLVector3d&, const bool&)> teleport_finished_signal_t;
typedef boost::function<void()> parcel_changed_callback_t;
typedef boost::signals2::signal<void()> parcel_changed_signal_t;
@@ -223,11 +223,6 @@ public:
// Takes an Access List flag, like AL_ACCESS or AL_BAN
void sendParcelAccessListRequest(U32 flags);
- // asks for the parcel's media url filter list
- void requestParcelMediaURLFilter();
- // receive the response
- void receiveParcelMediaURLFilter(const LLSD &content);
-
// Dwell is not part of the usual parcel update information because the
// simulator doesn't actually know the per-parcel dwell. Ack! We have
// to get it out of the database.
@@ -275,6 +270,8 @@ public:
// *NOTE: Taken out 2005-03-21. Phoenix.
//void makeLandmarkAtSelection();
+ static void optionally_start_music(const std::string& music_url);
+
static void processParcelOverlay(LLMessageSystem *msg, void **user_data);
static void processParcelProperties(LLMessageSystem *msg, void **user_data);
static void processParcelAccessListReply(LLMessageSystem *msg, void **user);
diff --git a/indra/newview/llviewerparceloverlay.cpp b/indra/newview/llviewerparceloverlay.cpp
index a0cf2fc803..a1c12c5cd6 100644..100755
--- a/indra/newview/llviewerparceloverlay.cpp
+++ b/indra/newview/llviewerparceloverlay.cpp
@@ -828,7 +828,6 @@ void LLViewerParcelOverlay::updateGL()
void LLViewerParcelOverlay::idleUpdate(bool force_update)
{
- LLMemType mt_iup(LLMemType::MTYPE_IDLE_UPDATE_PARCEL_OVERLAY);
if (gGLManager.mIsDisabled)
{
return;
diff --git a/indra/newview/llviewerparceloverlay.h b/indra/newview/llviewerparceloverlay.h
index 7445d5bf1d..7445d5bf1d 100644..100755
--- a/indra/newview/llviewerparceloverlay.h
+++ b/indra/newview/llviewerparceloverlay.h
diff --git a/indra/newview/llviewerpartsim.cpp b/indra/newview/llviewerpartsim.cpp
index 6b3e04348a..163c90019f 100644..100755
--- a/indra/newview/llviewerpartsim.cpp
+++ b/indra/newview/llviewerpartsim.cpp
@@ -79,15 +79,32 @@ LLViewerPart::LLViewerPart() :
mVPCallback(NULL),
mImagep(NULL)
{
- LLMemType mt(LLMemType::MTYPE_PARTICLES);
mPartSourcep = NULL;
-
+ mParent = NULL;
+ mChild = NULL;
++LLViewerPartSim::sParticleCount2 ;
}
LLViewerPart::~LLViewerPart()
{
- LLMemType mt(LLMemType::MTYPE_PARTICLES);
+ if (mPartSourcep.notNull() && mPartSourcep->mLastPart == this)
+ {
+ mPartSourcep->mLastPart = NULL;
+ }
+
+ //patch up holes in the ribbon
+ if (mParent)
+ {
+ llassert(mParent->mChild == this);
+ mParent->mChild = mChild;
+ }
+
+ if (mChild)
+ {
+ llassert (mChild->mParent == this);
+ mChild->mParent = mParent;
+ }
+
mPartSourcep = NULL;
--LLViewerPartSim::sParticleCount2 ;
@@ -95,7 +112,6 @@ LLViewerPart::~LLViewerPart()
void LLViewerPart::init(LLPointer<LLViewerPartSource> sourcep, LLViewerTexture *imagep, LLVPCallback cb)
{
- LLMemType mt(LLMemType::MTYPE_PARTICLES);
mPartID = LLViewerPart::sNextPartID;
LLViewerPart::sNextPartID++;
mFlags = 0x00f;
@@ -120,7 +136,6 @@ void LLViewerPart::init(LLPointer<LLViewerPartSource> sourcep, LLViewerTexture *
LLViewerPartGroup::LLViewerPartGroup(const LLVector3 &center_agent, const F32 box_side, bool hud)
: mHud(hud)
{
- LLMemType mt(LLMemType::MTYPE_PARTICLES);
mVOPartGroupp = NULL;
mUniformParticles = TRUE;
@@ -145,7 +160,11 @@ LLViewerPartGroup::LLViewerPartGroup(const LLVector3 &center_agent, const F32 bo
}
mVOPartGroupp->setViewerPartGroup(this);
mVOPartGroupp->setPositionAgent(getCenterAgent());
+
+ mBoxSide = box_side;
+
F32 scale = box_side * 0.5f;
+
mVOPartGroupp->setScale(LLVector3(scale,scale,scale));
//gPipeline.addObject(mVOPartGroupp);
@@ -177,7 +196,6 @@ LLViewerPartGroup::LLViewerPartGroup(const LLVector3 &center_agent, const F32 bo
LLViewerPartGroup::~LLViewerPartGroup()
{
- LLMemType mt(LLMemType::MTYPE_PARTICLES);
cleanup();
S32 count = (S32) mParticles.size();
@@ -192,7 +210,6 @@ LLViewerPartGroup::~LLViewerPartGroup()
void LLViewerPartGroup::cleanup()
{
- LLMemType mt(LLMemType::MTYPE_PARTICLES);
if (mVOPartGroupp)
{
if (!mVOPartGroupp->isDead())
@@ -205,7 +222,6 @@ void LLViewerPartGroup::cleanup()
BOOL LLViewerPartGroup::posInGroup(const LLVector3 &pos, const F32 desired_size)
{
- LLMemType mt(LLMemType::MTYPE_PARTICLES);
if ((pos.mV[VX] < mMinObjPos.mV[VX])
|| (pos.mV[VY] < mMinObjPos.mV[VY])
|| (pos.mV[VZ] < mMinObjPos.mV[VZ]))
@@ -233,8 +249,6 @@ BOOL LLViewerPartGroup::posInGroup(const LLVector3 &pos, const F32 desired_size)
BOOL LLViewerPartGroup::addPart(LLViewerPart* part, F32 desired_size)
{
- LLMemType mt(LLMemType::MTYPE_PARTICLES);
-
if (part->mFlags & LLPartData::LL_PART_HUD && !mHud)
{
return FALSE;
@@ -261,7 +275,6 @@ BOOL LLViewerPartGroup::addPart(LLViewerPart* part, F32 desired_size)
void LLViewerPartGroup::updateParticles(const F32 lastdt)
{
- LLMemType mt(LLMemType::MTYPE_PARTICLES);
F32 dt;
LLVector3 gravity(0.f, 0.f, GRAVITY);
@@ -377,6 +390,9 @@ void LLViewerPartGroup::updateParticles(const F32 lastdt)
part->mScale += frac*part->mEndScale;
}
+ // Do glow interpolation
+ part->mGlow.mV[3] = (U8) llround(lerp(part->mStartGlow, part->mEndGlow, frac)*255.f);
+
// Set the last update time to now.
part->mLastUpdateTime = cur_time;
@@ -429,7 +445,6 @@ void LLViewerPartGroup::updateParticles(const F32 lastdt)
void LLViewerPartGroup::shift(const LLVector3 &offset)
{
- LLMemType mt(LLMemType::MTYPE_PARTICLES);
mCenterAgent += offset;
mMinObjPos += offset;
mMaxObjPos += offset;
@@ -442,8 +457,6 @@ void LLViewerPartGroup::shift(const LLVector3 &offset)
void LLViewerPartGroup::removeParticlesByID(const U32 source_id)
{
- LLMemType mt(LLMemType::MTYPE_PARTICLES);
-
for (S32 i = 0; i < (S32)mParticles.size(); i++)
{
if(mParticles[i]->mPartSourcep->getID() == source_id)
@@ -475,8 +488,7 @@ void LLViewerPartSim::checkParticleCount(U32 size)
LLViewerPartSim::LLViewerPartSim()
{
- LLMemType mt(LLMemType::MTYPE_PARTICLES);
- sMaxParticleCount = gSavedSettings.getS32("RenderMaxPartCount");
+ sMaxParticleCount = llmin(gSavedSettings.getS32("RenderMaxPartCount"), LL_MAX_PARTICLE_COUNT);
static U32 id_seed = 0;
mID = ++id_seed;
}
@@ -484,7 +496,6 @@ LLViewerPartSim::LLViewerPartSim()
void LLViewerPartSim::destroyClass()
{
- LLMemType mt(LLMemType::MTYPE_PARTICLES);
S32 i;
S32 count;
@@ -500,12 +511,16 @@ void LLViewerPartSim::destroyClass()
mViewerPartSources.clear();
}
+//static
BOOL LLViewerPartSim::shouldAddPart()
{
- LLMemType mt(LLMemType::MTYPE_PARTICLES);
- if (sParticleCount > PART_THROTTLE_THRESHOLD*sMaxParticleCount)
+ if (sParticleCount >= MAX_PART_COUNT)
{
+ return FALSE;
+ }
+ if (sParticleCount > PART_THROTTLE_THRESHOLD*sMaxParticleCount)
+ {
F32 frac = (F32)sParticleCount/(F32)sMaxParticleCount;
frac -= PART_THROTTLE_THRESHOLD;
frac *= PART_THROTTLE_RESCALE;
@@ -515,7 +530,10 @@ BOOL LLViewerPartSim::shouldAddPart()
return FALSE;
}
}
- if (sParticleCount >= MAX_PART_COUNT)
+
+ // Check frame rate, and don't add more if the viewer is really slow
+ const F32 MIN_FRAME_RATE_FOR_NEW_PARTICLES = 4.f;
+ if (gFPSClamped < MIN_FRAME_RATE_FOR_NEW_PARTICLES)
{
return FALSE;
}
@@ -525,7 +543,6 @@ BOOL LLViewerPartSim::shouldAddPart()
void LLViewerPartSim::addPart(LLViewerPart* part)
{
- LLMemType mt(LLMemType::MTYPE_PARTICLES);
if (sParticleCount < MAX_PART_COUNT)
{
put(part);
@@ -541,7 +558,6 @@ void LLViewerPartSim::addPart(LLViewerPart* part)
LLViewerPartGroup *LLViewerPartSim::put(LLViewerPart* part)
{
- LLMemType mt(LLMemType::MTYPE_PARTICLES);
const F32 MAX_MAG = 1000000.f*1000000.f; // 1 million
LLViewerPartGroup *return_group = NULL ;
if (part->mPosAgent.magVecSquared() > MAX_MAG || !part->mPosAgent.isFinite())
@@ -599,7 +615,6 @@ LLViewerPartGroup *LLViewerPartSim::put(LLViewerPart* part)
LLViewerPartGroup *LLViewerPartSim::createViewerPartGroup(const LLVector3 &pos_agent, const F32 desired_size, bool hud)
{
- LLMemType mt(LLMemType::MTYPE_PARTICLES);
//find a box that has a center position divisible by PART_SIM_BOX_SIDE that encompasses
//pos_agent
LLViewerPartGroup *groupp = new LLViewerPartGroup(pos_agent, desired_size, hud);
@@ -632,10 +647,11 @@ static LLFastTimer::DeclareTimer FTM_SIMULATE_PARTICLES("Simulate Particles");
void LLViewerPartSim::updateSimulation()
{
- LLMemType mt(LLMemType::MTYPE_PARTICLES);
-
static LLFrameTimer update_timer;
+ //reset VBO cursor
+ LLVOPartGroup::sVBSlotCursor = 0;
+
const F32 dt = llmin(update_timer.getElapsedTimeAndResetF32(), 0.1f);
if (!(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_PARTICLES)))
@@ -800,7 +816,6 @@ void LLViewerPartSim::updatePartBurstRate()
void LLViewerPartSim::addPartSource(LLPointer<LLViewerPartSource> sourcep)
{
- LLMemType mt(LLMemType::MTYPE_PARTICLES);
if (!sourcep)
{
llwarns << "Null part source!" << llendl;
@@ -817,7 +832,6 @@ void LLViewerPartSim::removeLastCreatedSource()
void LLViewerPartSim::cleanupRegion(LLViewerRegion *regionp)
{
- LLMemType mt(LLMemType::MTYPE_PARTICLES);
for (group_list_t::iterator i = mViewerPartGroups.begin(); i != mViewerPartGroups.end(); )
{
group_list_t::iterator iter = i++;
@@ -832,7 +846,6 @@ void LLViewerPartSim::cleanupRegion(LLViewerRegion *regionp)
void LLViewerPartSim::clearParticlesByID(const U32 system_id)
{
- LLMemType mt(LLMemType::MTYPE_PARTICLES);
for (group_list_t::iterator g = mViewerPartGroups.begin(); g != mViewerPartGroups.end(); ++g)
{
(*g)->removeParticlesByID(system_id);
@@ -850,7 +863,6 @@ void LLViewerPartSim::clearParticlesByID(const U32 system_id)
void LLViewerPartSim::clearParticlesByOwnerID(const LLUUID& task_id)
{
- LLMemType mt(LLMemType::MTYPE_PARTICLES);
for (source_list_t::iterator iter = mViewerPartSources.begin(); iter != mViewerPartSources.end(); ++iter)
{
if ((*iter)->getOwnerUUID() == task_id)
diff --git a/indra/newview/llviewerpartsim.h b/indra/newview/llviewerpartsim.h
index 3e20f999c0..2daa07ed8c 100644..100755
--- a/indra/newview/llviewerpartsim.h
+++ b/indra/newview/llviewerpartsim.h
@@ -39,6 +39,8 @@ class LLViewerRegion;
class LLViewerTexture;
class LLVOPartGroup;
+#define LL_MAX_PARTICLE_COUNT 8192
+
typedef void (*LLVPCallback)(LLViewerPart &part, const F32 dt);
///////////////////
@@ -63,15 +65,22 @@ public:
LLVPCallback mVPCallback; // Callback function for more complicated behaviors
LLPointer<LLViewerPartSource> mPartSourcep; // Particle source used for this object
-
+
+ LLViewerPart* mParent; // particle to connect to if this is part of a particle ribbon
+ LLViewerPart* mChild; // child particle for clean reference destruction
// Current particle state (possibly used for rendering)
LLPointer<LLViewerTexture> mImagep;
LLVector3 mPosAgent;
LLVector3 mVelocity;
LLVector3 mAccel;
+ LLVector3 mAxis;
LLColor4 mColor;
LLVector2 mScale;
+ F32 mStartGlow;
+ F32 mEndGlow;
+ LLColor4U mGlow;
+
static U32 sNextPartID;
};
@@ -96,6 +105,9 @@ public:
void shift(const LLVector3 &offset);
+ F32 getBoxRadius() { return mBoxRadius; }
+ F32 getBoxSide() { return mBoxSide; }
+
typedef std::vector<LLViewerPart*> part_list_t;
part_list_t mParticles;
@@ -116,6 +128,7 @@ public:
protected:
LLVector3 mCenterAgent;
F32 mBoxRadius;
+ F32 mBoxSide;
LLVector3 mMinObjPos;
LLVector3 mMaxObjPos;
@@ -140,7 +153,7 @@ public:
void cleanupRegion(LLViewerRegion *regionp);
- BOOL shouldAddPart(); // Just decides whether this particle should be added or not (for particle count capping)
+ static BOOL shouldAddPart(); // Just decides whether this particle should be added or not (for particle count capping)
F32 maxRate() // Return maximum particle generation rate
{
if (sParticleCount >= MAX_PART_COUNT)
diff --git a/indra/newview/llviewerpartsource.cpp b/indra/newview/llviewerpartsource.cpp
index 4af92e79ff..b6bbd6140d 100644..100755
--- a/indra/newview/llviewerpartsource.cpp
+++ b/indra/newview/llviewerpartsource.cpp
@@ -52,6 +52,8 @@ LLViewerPartSource::LLViewerPartSource(const U32 type) :
static U32 id_seed = 0;
mID = ++id_seed;
+ mLastPart = NULL;
+
mDelay = 0 ;
}
@@ -90,7 +92,6 @@ void LLViewerPartSource::setStart()
LLViewerPartSourceScript::LLViewerPartSourceScript(LLViewerObject *source_objp) :
LLViewerPartSource(LL_PART_SOURCE_SCRIPT)
{
- LLMemType mt(LLMemType::MTYPE_PARTICLES);
llassert(source_objp);
mSourceObjectp = source_objp;
mPosAgent = mSourceObjectp->getPositionAgent();
@@ -102,7 +103,6 @@ LLViewerPartSourceScript::LLViewerPartSourceScript(LLViewerObject *source_objp)
void LLViewerPartSourceScript::setDead()
{
- LLMemType mt(LLMemType::MTYPE_PARTICLES);
mIsDead = TRUE;
mSourceObjectp = NULL;
mTargetObjectp = NULL;
@@ -113,7 +113,6 @@ void LLViewerPartSourceScript::update(const F32 dt)
if( mIsSuspended )
return;
- LLMemType mt(LLMemType::MTYPE_PARTICLES);
F32 old_update_time = mLastUpdateTime;
mLastUpdateTime += dt;
@@ -282,6 +281,22 @@ void LLViewerPartSourceScript::update(const F32 dt)
{
part->mFlags |= LLPartData::LL_PART_HUD;
}
+
+ if (part->mFlags & LLPartData::LL_PART_RIBBON_MASK && mLastPart)
+ { //set previous particle's parent to this particle to chain ribbon together
+ mLastPart->mParent = part;
+ part->mChild = mLastPart;
+ part->mAxis = LLVector3(0,0,1);
+
+ if (mSourceObjectp.notNull())
+ {
+ LLQuaternion rot = mSourceObjectp->getRenderRotation();
+ part->mAxis *= rot;
+ }
+ }
+
+ mLastPart = part;
+
part->mMaxAge = mPartSysData.mPartData.mMaxAge;
part->mStartColor = mPartSysData.mPartData.mStartColor;
part->mEndColor = mPartSysData.mPartData.mEndColor;
@@ -293,6 +308,13 @@ void LLViewerPartSourceScript::update(const F32 dt)
part->mAccel = mPartSysData.mPartAccel;
+ part->mBlendFuncDest = mPartSysData.mPartData.mBlendFuncDest;
+ part->mBlendFuncSource = mPartSysData.mPartData.mBlendFuncSource;
+
+ part->mStartGlow = mPartSysData.mPartData.mStartGlow;
+ part->mEndGlow = mPartSysData.mPartData.mEndGlow;
+ part->mGlow = LLColor4U(0, 0, 0, (U8) llround(part->mStartGlow*255.f));
+
if (mPartSysData.mPattern & LLPartSysData::LL_PART_SRC_PATTERN_DROP)
{
part->mPosAgent = mPosAgent;
@@ -394,7 +416,6 @@ void LLViewerPartSourceScript::update(const F32 dt)
// static
LLPointer<LLViewerPartSourceScript> LLViewerPartSourceScript::unpackPSS(LLViewerObject *source_objp, LLPointer<LLViewerPartSourceScript> pssp, const S32 block_num)
{
- LLMemType mt(LLMemType::MTYPE_PARTICLES);
if (!pssp)
{
if (LLPartSysData::isNullPS(block_num))
@@ -434,29 +455,51 @@ LLPointer<LLViewerPartSourceScript> LLViewerPartSourceScript::unpackPSS(LLViewer
}
-LLPointer<LLViewerPartSourceScript> LLViewerPartSourceScript::unpackPSS(LLViewerObject *source_objp, LLPointer<LLViewerPartSourceScript> pssp, LLDataPacker &dp)
+LLPointer<LLViewerPartSourceScript> LLViewerPartSourceScript::unpackPSS(LLViewerObject *source_objp, LLPointer<LLViewerPartSourceScript> pssp, LLDataPacker &dp, bool legacy)
{
- LLMemType mt(LLMemType::MTYPE_PARTICLES);
if (!pssp)
{
LLPointer<LLViewerPartSourceScript> new_pssp = new LLViewerPartSourceScript(source_objp);
- if (!new_pssp->mPartSysData.unpack(dp))
+ if (legacy)
{
- return NULL;
+ if (!new_pssp->mPartSysData.unpackLegacy(dp))
+ {
+ return NULL;
+ }
}
+ else
+ {
+ if (!new_pssp->mPartSysData.unpack(dp))
+ {
+ return NULL;
+ }
+ }
+
if (new_pssp->mPartSysData.mTargetUUID.notNull())
{
LLViewerObject *target_objp = gObjectList.findObject(new_pssp->mPartSysData.mTargetUUID);
new_pssp->setTargetObject(target_objp);
}
+
return new_pssp;
}
else
{
- if (!pssp->mPartSysData.unpack(dp))
+ if (legacy)
{
- return NULL;
+ if (!pssp->mPartSysData.unpackLegacy(dp))
+ {
+ return NULL;
+ }
}
+ else
+ {
+ if (!pssp->mPartSysData.unpack(dp))
+ {
+ return NULL;
+ }
+ }
+
if (pssp->mPartSysData.mTargetUUID.notNull())
{
LLViewerObject *target_objp = gObjectList.findObject(pssp->mPartSysData.mTargetUUID);
@@ -470,8 +513,6 @@ LLPointer<LLViewerPartSourceScript> LLViewerPartSourceScript::unpackPSS(LLViewer
/* static */
LLPointer<LLViewerPartSourceScript> LLViewerPartSourceScript::createPSS(LLViewerObject *source_objp, const LLPartSysData& particle_parameters)
{
- LLMemType mt(LLMemType::MTYPE_PARTICLES);
-
LLPointer<LLViewerPartSourceScript> new_pssp = new LLViewerPartSourceScript(source_objp);
new_pssp->mPartSysData = particle_parameters;
@@ -487,13 +528,11 @@ LLPointer<LLViewerPartSourceScript> LLViewerPartSourceScript::createPSS(LLViewer
void LLViewerPartSourceScript::setImage(LLViewerTexture *imagep)
{
- LLMemType mt(LLMemType::MTYPE_PARTICLES);
mImagep = imagep;
}
void LLViewerPartSourceScript::setTargetObject(LLViewerObject *objp)
{
- LLMemType mt(LLMemType::MTYPE_PARTICLES);
mTargetObjectp = objp;
}
@@ -509,7 +548,6 @@ LLViewerPartSourceSpiral::LLViewerPartSourceSpiral(const LLVector3 &pos) :
void LLViewerPartSourceSpiral::setDead()
{
- LLMemType mt(LLMemType::MTYPE_PARTICLES);
mIsDead = TRUE;
mSourceObjectp = NULL;
}
@@ -517,7 +555,6 @@ void LLViewerPartSourceSpiral::setDead()
void LLViewerPartSourceSpiral::updatePart(LLViewerPart &part, const F32 dt)
{
- LLMemType mt(LLMemType::MTYPE_PARTICLES);
F32 frac = part.mLastUpdateTime/part.mMaxAge;
LLVector3 center_pos;
@@ -542,7 +579,6 @@ void LLViewerPartSourceSpiral::updatePart(LLViewerPart &part, const F32 dt)
void LLViewerPartSourceSpiral::update(const F32 dt)
{
- LLMemType mt(LLMemType::MTYPE_PARTICLES);
if (!mImagep)
{
mImagep = LLViewerTextureManager::getFetchedTextureFromFile("pixiesmall.j2c");
@@ -581,6 +617,11 @@ void LLViewerPartSourceSpiral::update(const F32 dt)
part->mScale.mV[0] = 0.25f;
part->mScale.mV[1] = 0.25f;
part->mParameter = ll_frand(F_TWO_PI);
+ part->mBlendFuncDest = LLRender::BF_ONE_MINUS_SOURCE_ALPHA;
+ part->mBlendFuncSource = LLRender::BF_SOURCE_ALPHA;
+ part->mStartGlow = 0.f;
+ part->mEndGlow = 0.f;
+ part->mGlow = LLColor4U(0, 0, 0, 0);
LLViewerPartSim::getInstance()->addPart(part);
}
@@ -588,7 +629,6 @@ void LLViewerPartSourceSpiral::update(const F32 dt)
void LLViewerPartSourceSpiral::setSourceObject(LLViewerObject *objp)
{
- LLMemType mt(LLMemType::MTYPE_PARTICLES);
mSourceObjectp = objp;
}
@@ -612,7 +652,6 @@ LLViewerPartSourceBeam::~LLViewerPartSourceBeam()
void LLViewerPartSourceBeam::setDead()
{
- LLMemType mt(LLMemType::MTYPE_PARTICLES);
mIsDead = TRUE;
mSourceObjectp = NULL;
mTargetObjectp = NULL;
@@ -626,7 +665,6 @@ void LLViewerPartSourceBeam::setColor(const LLColor4 &color)
void LLViewerPartSourceBeam::updatePart(LLViewerPart &part, const F32 dt)
{
- LLMemType mt(LLMemType::MTYPE_PARTICLES);
F32 frac = part.mLastUpdateTime/part.mMaxAge;
LLViewerPartSource *ps = (LLViewerPartSource*)part.mPartSourcep;
@@ -671,7 +709,6 @@ void LLViewerPartSourceBeam::updatePart(LLViewerPart &part, const F32 dt)
void LLViewerPartSourceBeam::update(const F32 dt)
{
- LLMemType mt(LLMemType::MTYPE_PARTICLES);
const F32 RATE = 0.025f;
mLastUpdateTime += dt;
@@ -737,19 +774,23 @@ void LLViewerPartSourceBeam::update(const F32 dt)
part->mPosAgent = mPosAgent;
part->mVelocity = mTargetPosAgent - mPosAgent;
+ part->mBlendFuncDest = LLRender::BF_ONE_MINUS_SOURCE_ALPHA;
+ part->mBlendFuncSource = LLRender::BF_SOURCE_ALPHA;
+ part->mStartGlow = 0.f;
+ part->mEndGlow = 0.f;
+ part->mGlow = LLColor4U(0, 0, 0, 0);
+
LLViewerPartSim::getInstance()->addPart(part);
}
}
void LLViewerPartSourceBeam::setSourceObject(LLViewerObject* objp)
{
- LLMemType mt(LLMemType::MTYPE_PARTICLES);
mSourceObjectp = objp;
}
void LLViewerPartSourceBeam::setTargetObject(LLViewerObject* objp)
{
- LLMemType mt(LLMemType::MTYPE_PARTICLES);
mTargetObjectp = objp;
}
@@ -764,7 +805,6 @@ LLViewerPartSourceChat::LLViewerPartSourceChat(const LLVector3 &pos) :
void LLViewerPartSourceChat::setDead()
{
- LLMemType mt(LLMemType::MTYPE_PARTICLES);
mIsDead = TRUE;
mSourceObjectp = NULL;
}
@@ -772,7 +812,6 @@ void LLViewerPartSourceChat::setDead()
void LLViewerPartSourceChat::updatePart(LLViewerPart &part, const F32 dt)
{
- LLMemType mt(LLMemType::MTYPE_PARTICLES);
F32 frac = part.mLastUpdateTime/part.mMaxAge;
LLVector3 center_pos;
@@ -797,7 +836,6 @@ void LLViewerPartSourceChat::updatePart(LLViewerPart &part, const F32 dt)
void LLViewerPartSourceChat::update(const F32 dt)
{
- LLMemType mt(LLMemType::MTYPE_PARTICLES);
if (!mImagep)
{
mImagep = LLViewerTextureManager::getFetchedTextureFromFile("pixiesmall.j2c");
@@ -846,6 +884,12 @@ void LLViewerPartSourceChat::update(const F32 dt)
part->mScale.mV[0] = 0.25f;
part->mScale.mV[1] = 0.25f;
part->mParameter = ll_frand(F_TWO_PI);
+ part->mBlendFuncDest = LLRender::BF_ONE_MINUS_SOURCE_ALPHA;
+ part->mBlendFuncSource = LLRender::BF_SOURCE_ALPHA;
+ part->mStartGlow = 0.f;
+ part->mEndGlow = 0.f;
+ part->mGlow = LLColor4U(0, 0, 0, 0);
+
LLViewerPartSim::getInstance()->addPart(part);
}
@@ -853,7 +897,6 @@ void LLViewerPartSourceChat::update(const F32 dt)
void LLViewerPartSourceChat::setSourceObject(LLViewerObject *objp)
{
- LLMemType mt(LLMemType::MTYPE_PARTICLES);
mSourceObjectp = objp;
}
diff --git a/indra/newview/llviewerpartsource.h b/indra/newview/llviewerpartsource.h
index 28702d36a2..12e926173b 100644..100755
--- a/indra/newview/llviewerpartsource.h
+++ b/indra/newview/llviewerpartsource.h
@@ -76,6 +76,7 @@ public:
LLVector3 mLastUpdatePosAgent;
LLPointer<LLViewerObject> mSourceObjectp;
U32 mID;
+ LLViewerPart* mLastPart; //last particle emitted (for making particle ribbons)
protected:
U32 mType;
@@ -85,7 +86,6 @@ protected:
F32 mLastPartTime;
LLUUID mOwnerUUID;
LLPointer<LLViewerTexture> mImagep;
-
// Particle information
U32 mPartFlags; // Flags for the particle
U32 mDelay ; //delay to start particles
@@ -114,7 +114,7 @@ public:
// Returns a new particle source to attach to an object...
static LLPointer<LLViewerPartSourceScript> unpackPSS(LLViewerObject *source_objp, LLPointer<LLViewerPartSourceScript> pssp, const S32 block_num);
- static LLPointer<LLViewerPartSourceScript> unpackPSS(LLViewerObject *source_objp, LLPointer<LLViewerPartSourceScript> pssp, LLDataPacker &dp);
+ static LLPointer<LLViewerPartSourceScript> unpackPSS(LLViewerObject *source_objp, LLPointer<LLViewerPartSourceScript> pssp, LLDataPacker &dp, bool legacy);
static LLPointer<LLViewerPartSourceScript> createPSS(LLViewerObject *source_objp, const LLPartSysData& particle_parameters);
LLViewerTexture *getImage() const { return mImagep; }
diff --git a/indra/newview/llviewerprecompiledheaders.cpp b/indra/newview/llviewerprecompiledheaders.cpp
index 307e903726..307e903726 100644..100755
--- a/indra/newview/llviewerprecompiledheaders.cpp
+++ b/indra/newview/llviewerprecompiledheaders.cpp
diff --git a/indra/newview/llviewerprecompiledheaders.h b/indra/newview/llviewerprecompiledheaders.h
index f738b84bb9..a565005f30 100644..100755
--- a/indra/newview/llviewerprecompiledheaders.h
+++ b/indra/newview/llviewerprecompiledheaders.h
@@ -33,8 +33,6 @@
// in viewer.
// It is used to precompile headers for improved build speed.
-#include <boost/coroutine/coroutine.hpp>
-
#include "linden_common.h"
// Work around stupid Microsoft STL warning
@@ -57,8 +55,8 @@
#include "lldeleteutils.h"
#include "imageids.h"
#include "indra_constants.h"
-//#include "linden_common.h"
-//#include "llpreprocessor.h"
+#include "llinitparam.h"
+
#include "llallocator.h"
#include "llapp.h"
#include "llcriticaldamp.h"
@@ -75,10 +73,8 @@
#include "llprocessor.h"
#include "llrefcount.h"
#include "llsafehandle.h"
-//#include "llsecondlifeurls.h"
#include "llsd.h"
#include "llsingleton.h"
-#include "llstat.h"
#include "llstl.h"
#include "llstrider.h"
#include "llstring.h"
@@ -86,11 +82,8 @@
#include "llthread.h"
#include "lltimer.h"
#include "lluuidhashmap.h"
-//#include "processor.h"
#include "stdenums.h"
#include "stdtypes.h"
-//#include "string_table.h"
-//#include "timer.h"
#include "timing.h"
#include "u64.h"
@@ -124,7 +117,5 @@
// Library includes from llmessage project
#include "llcachename.h"
-// Library includes from llxuixml
-#include "llinitparam.h"
#endif
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index 21e0db46c9..c6e67355c3 100644..100755
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -44,6 +44,7 @@
#include "llagent.h"
#include "llagentcamera.h"
+#include "llavatarrenderinfoaccountant.h"
#include "llcallingcard.h"
#include "llcaphttpsender.h"
#include "llcapabilitylistener.h"
@@ -143,6 +144,7 @@ public:
LLUUID mCacheID;
CapabilityMap mCapabilities;
+ CapabilityMap mSecondCapabilitiesTracker;
LLEventPoll* mEventPoll;
@@ -210,9 +212,9 @@ public:
virtual ~BaseCapabilitiesComplete()
{ }
- void error(U32 statusNum, const std::string& reason)
+ void errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content)
{
- LL_WARNS2("AppInit", "Capabilities") << statusNum << ": " << reason << LL_ENDL;
+ LL_WARNS2("AppInit", "Capabilities") << "[status:" << statusNum << ":] " << content << LL_ENDL;
LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(mRegionHandle);
if (regionp)
{
@@ -231,6 +233,7 @@ public:
if( mID != regionp->getHttpResponderID() ) // region is no longer referring to this responder
{
LL_WARNS2("AppInit", "Capabilities") << "Received results for a stale http responder!" << LL_ENDL;
+ regionp->failedSeedCapability();
return ;
}
@@ -238,6 +241,7 @@ public:
for(iter = content.beginMap(); iter != content.endMap(); ++iter)
{
regionp->setCapability(iter->first, iter->second);
+
LL_DEBUGS2("AppInit", "Capabilities") << "got capability for "
<< iter->first << LL_ENDL;
@@ -256,10 +260,9 @@ public:
}
}
- static boost::intrusive_ptr<BaseCapabilitiesComplete> build( U64 region_handle, S32 id )
+ static BaseCapabilitiesComplete* build( U64 region_handle, S32 id )
{
- return boost::intrusive_ptr<BaseCapabilitiesComplete>(
- new BaseCapabilitiesComplete(region_handle, id) );
+ return new BaseCapabilitiesComplete(region_handle, id);
}
private:
@@ -267,6 +270,62 @@ private:
S32 mID;
};
+class BaseCapabilitiesCompleteTracker : public LLHTTPClient::Responder
+{
+ LOG_CLASS(BaseCapabilitiesCompleteTracker);
+public:
+ BaseCapabilitiesCompleteTracker( U64 region_handle)
+ : mRegionHandle(region_handle)
+ { }
+
+ virtual ~BaseCapabilitiesCompleteTracker()
+ { }
+
+ void errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content)
+ {
+ llwarns << "BaseCapabilitiesCompleteTracker error [status:"
+ << statusNum << "]: " << content << llendl;
+ }
+
+ void result(const LLSD& content)
+ {
+ LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(mRegionHandle);
+ if( !regionp )
+ {
+ return ;
+ }
+ LLSD::map_const_iterator iter;
+ for(iter = content.beginMap(); iter != content.endMap(); ++iter)
+ {
+ regionp->setCapabilityDebug(iter->first, iter->second);
+ //llinfos<<"BaseCapabilitiesCompleteTracker New Caps "<<iter->first<<" "<< iter->second<<llendl;
+ }
+
+ if ( regionp->getRegionImpl()->mCapabilities.size() != regionp->getRegionImpl()->mSecondCapabilitiesTracker.size() )
+ {
+ llinfos<<"BaseCapabilitiesCompleteTracker "<<"Sim sent duplicate seed caps that differs in size - most likely content."<<llendl;
+ //todo#add cap debug versus original check?
+ /*CapabilityMap::const_iterator iter = regionp->getRegionImpl()->mCapabilities.begin();
+ while (iter!=regionp->getRegionImpl()->mCapabilities.end() )
+ {
+ llinfos<<"BaseCapabilitiesCompleteTracker Original "<<iter->first<<" "<< iter->second<<llendl;
+ ++iter;
+ }
+ */
+ regionp->getRegionImplNC()->mSecondCapabilitiesTracker.clear();
+ }
+
+ }
+
+ static BaseCapabilitiesCompleteTracker* build( U64 region_handle )
+ {
+ return new BaseCapabilitiesCompleteTracker( region_handle );
+ }
+
+private:
+ U64 mRegionHandle;
+};
+
LLViewerRegion::LLViewerRegion(const U64 &handle,
const LLHost &host,
@@ -280,9 +339,11 @@ LLViewerRegion::LLViewerRegion(const U64 &handle,
mZoning(""),
mIsEstateManager(FALSE),
mRegionFlags( REGION_FLAGS_DEFAULT ),
+ mRegionProtocols( 0 ),
mSimAccess( SIM_ACCESS_MIN ),
mBillableFactor(1.0),
mMaxTasks(DEFAULT_MAX_REGION_WIDE_PRIM_COUNT),
+ mCentralBakeVersion(0),
mClassID(0),
mCPURatio(0),
mColoName("unknown"),
@@ -455,18 +516,6 @@ void LLViewerRegion::sendReliableMessage()
gMessageSystem->sendReliable(mImpl->mHost);
}
-void LLViewerRegion::setFlags(BOOL b, U32 flags)
-{
- if (b)
- {
- mRegionFlags |= flags;
- }
- else
- {
- mRegionFlags &= ~flags;
- }
-}
-
void LLViewerRegion::setWaterHeight(F32 water_level)
{
mImpl->mLandp->setWaterHeight(water_level);
@@ -479,10 +528,10 @@ F32 LLViewerRegion::getWaterHeight() const
BOOL LLViewerRegion::isVoiceEnabled() const
{
- return (getRegionFlags() & REGION_FLAGS_ALLOW_VOICE);
+ return getRegionFlag(REGION_FLAGS_ALLOW_VOICE);
}
-void LLViewerRegion::setRegionFlags(U32 flags)
+void LLViewerRegion::setRegionFlags(U64 flags)
{
mRegionFlags = flags;
}
@@ -575,7 +624,7 @@ std::string LLViewerRegion::getLocalizedSimProductName() const
}
// static
-std::string LLViewerRegion::regionFlagsToString(U32 flags)
+std::string LLViewerRegion::regionFlagsToString(U64 flags)
{
std::string result;
@@ -656,6 +705,31 @@ std::string LLViewerRegion::accessToShortString(U8 sim_access)
}
// static
+U8 LLViewerRegion::shortStringToAccess(const std::string &sim_access)
+{
+ U8 accessValue;
+
+ if (LLStringUtil::compareStrings(sim_access, "PG") == 0)
+ {
+ accessValue = SIM_ACCESS_PG;
+ }
+ else if (LLStringUtil::compareStrings(sim_access, "M") == 0)
+ {
+ accessValue = SIM_ACCESS_MATURE;
+ }
+ else if (LLStringUtil::compareStrings(sim_access, "A") == 0)
+ {
+ accessValue = SIM_ACCESS_ADULT;
+ }
+ else
+ {
+ accessValue = SIM_ACCESS_MIN;
+ }
+
+ return accessValue;
+}
+
+// static
void LLViewerRegion::processRegionInfo(LLMessageSystem* msg, void**)
{
// send it to 'observers'
@@ -696,7 +770,6 @@ void LLViewerRegion::dirtyHeights()
BOOL LLViewerRegion::idleUpdate(F32 max_update_time)
{
- LLMemType mt_ivr(LLMemType::MTYPE_IDLE_UPDATE_VIEWER_REGION);
// did_update returns TRUE if we did at least one significant update
BOOL did_update = mImpl->mLandp->idleUpdate(max_update_time);
@@ -1149,9 +1222,10 @@ void LLViewerRegion::getInfo(LLSD& info)
info["Region"]["Handle"]["y"] = (LLSD::Integer)y;
}
-void LLViewerRegion::getSimulatorFeatures(LLSD& sim_features)
+void LLViewerRegion::getSimulatorFeatures(LLSD& sim_features) const
{
sim_features = mSimulatorFeatures;
+
}
void LLViewerRegion::setSimulatorFeatures(const LLSD& sim_features)
@@ -1318,11 +1392,8 @@ void LLViewerRegion::requestCacheMisses()
mCacheDirty = TRUE ;
// llinfos << "KILLDEBUG Sent cache miss full " << full_count << " crc " << crc_count << llendl;
- #if LL_RECORD_VIEWER_STATS
- LLViewerStatsRecorder::instance()->beginObjectUpdateEvents(this);
- LLViewerStatsRecorder::instance()->recordRequestCacheMissesEvent(full_count + crc_count);
- LLViewerStatsRecorder::instance()->endObjectUpdateEvents();
- #endif
+ LLViewerStatsRecorder::instance().requestCacheMissesEvent(full_count + crc_count);
+ LLViewerStatsRecorder::instance().log(0.2f);
}
void LLViewerRegion::dumpCache()
@@ -1368,7 +1439,8 @@ void LLViewerRegion::unpackRegionHandshake()
{
LLMessageSystem *msg = gMessageSystem;
- U32 region_flags;
+ U64 region_flags = 0;
+ U64 region_protocols = 0;
U8 sim_access;
std::string sim_name;
LLUUID sim_owner;
@@ -1377,7 +1449,6 @@ void LLViewerRegion::unpackRegionHandshake()
F32 billable_factor;
LLUUID cache_id;
- msg->getU32 ("RegionInfo", "RegionFlags", region_flags);
msg->getU8 ("RegionInfo", "SimAccess", sim_access);
msg->getString ("RegionInfo", "SimName", sim_name);
msg->getUUID ("RegionInfo", "SimOwner", sim_owner);
@@ -1386,7 +1457,20 @@ void LLViewerRegion::unpackRegionHandshake()
msg->getF32 ("RegionInfo", "BillableFactor", billable_factor);
msg->getUUID ("RegionInfo", "CacheID", cache_id );
+ if (msg->has(_PREHASH_RegionInfo4))
+ {
+ msg->getU64Fast(_PREHASH_RegionInfo4, _PREHASH_RegionFlagsExtended, region_flags);
+ msg->getU64Fast(_PREHASH_RegionInfo4, _PREHASH_RegionProtocols, region_protocols);
+ }
+ else
+ {
+ U32 flags = 0;
+ msg->getU32Fast(_PREHASH_RegionInfo, _PREHASH_RegionFlags, flags);
+ region_flags = flags;
+ }
+
setRegionFlags(region_flags);
+ setRegionProtocols(region_protocols);
setSimAccess(sim_access);
setRegionNameAndZone(sim_name);
setOwner(sim_owner);
@@ -1425,6 +1509,8 @@ void LLViewerRegion::unpackRegionHandshake()
mProductName = productName;
}
+
+ mCentralBakeVersion = region_protocols & 1; // was (S32)gSavedSettings.getBOOL("UseServerTextureBaking");
LLVLComposition *compp = getComposition();
if (compp)
{
@@ -1462,7 +1548,8 @@ void LLViewerRegion::unpackRegionHandshake()
// all of our terrain stuff, by
if (compp->getParamsReady())
{
- getLand().dirtyAllPatches();
+ //this line creates frame stalls on region crossing and removing it appears to have no effect
+ //getLand().dirtyAllPatches();
}
else
{
@@ -1494,18 +1581,20 @@ void LLViewerRegion::unpackRegionHandshake()
void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
{
+ capabilityNames.append("AgentState");
capabilityNames.append("AttachmentResources");
capabilityNames.append("AvatarPickerSearch");
+ capabilityNames.append("CharacterProperties");
capabilityNames.append("ChatSessionRequest");
capabilityNames.append("CopyInventoryFromNotecard");
capabilityNames.append("CreateInventoryCategory");
capabilityNames.append("DefaultObjectPermissions");
capabilityNames.append("DispatchRegionInfo");
+ capabilityNames.append("EnvironmentSettings");
capabilityNames.append("EstateChangeInfo");
capabilityNames.append("EventQueueGet");
- capabilityNames.append("EnvironmentSettings");
- capabilityNames.append("ObjectMedia");
- capabilityNames.append("ObjectMediaNavigate");
+ capabilityNames.append("FacebookConnect");
+ //capabilityNames.append("FacebookRedirect");
if (gSavedSettings.getBOOL("UseHTTPInventory"))
{
@@ -1513,49 +1602,56 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
capabilityNames.append("FetchLibDescendents2");
capabilityNames.append("FetchInventory2");
capabilityNames.append("FetchInventoryDescendents2");
+ capabilityNames.append("IncrementCOFVersion");
}
capabilityNames.append("GetDisplayNames");
- capabilityNames.append("GetTexture");
capabilityNames.append("GetMesh");
capabilityNames.append("GetObjectCost");
capabilityNames.append("GetObjectPhysicsData");
+ capabilityNames.append("GetTexture");
+ capabilityNames.append("GroupMemberData");
capabilityNames.append("GroupProposalBallot");
capabilityNames.append("HomeLocation");
capabilityNames.append("LandResources");
capabilityNames.append("MapLayer");
capabilityNames.append("MapLayerGod");
capabilityNames.append("MeshUploadFlag");
+ capabilityNames.append("NavMeshGenerationStatus");
capabilityNames.append("NewFileAgentInventory");
+ capabilityNames.append("ObjectMedia");
+ capabilityNames.append("ObjectMediaNavigate");
+ capabilityNames.append("ObjectNavMeshProperties");
capabilityNames.append("ParcelPropertiesUpdate");
- capabilityNames.append("ParcelMediaURLFilterList");
- capabilityNames.append("ParcelNavigateMedia");
capabilityNames.append("ParcelVoiceInfoRequest");
capabilityNames.append("ProductInfoRequest");
capabilityNames.append("ProvisionVoiceAccountRequest");
capabilityNames.append("RemoteParcelRequest");
+ capabilityNames.append("RenderMaterials");
capabilityNames.append("RequestTextureDownload");
capabilityNames.append("ResourceCostSelected");
+ capabilityNames.append("RetrieveNavMeshSrc");
capabilityNames.append("SearchStatRequest");
capabilityNames.append("SearchStatTracking");
capabilityNames.append("SendPostcard");
capabilityNames.append("SendUserReport");
capabilityNames.append("SendUserReportWithScreenshot");
capabilityNames.append("ServerReleaseNotes");
- capabilityNames.append("SimConsole");
- capabilityNames.append("SimulatorFeatures");
capabilityNames.append("SetDisplayName");
capabilityNames.append("SimConsoleAsync");
+ capabilityNames.append("SimulatorFeatures");
capabilityNames.append("StartGroupProposal");
+ capabilityNames.append("TerrainNavMeshProperties");
capabilityNames.append("TextureStats");
capabilityNames.append("UntrustedSimulatorMessage");
capabilityNames.append("UpdateAgentInformation");
capabilityNames.append("UpdateAgentLanguage");
+ capabilityNames.append("UpdateAvatarAppearance");
capabilityNames.append("UpdateGestureAgentInventory");
- capabilityNames.append("UpdateNotecardAgentInventory");
- capabilityNames.append("UpdateScriptAgent");
capabilityNames.append("UpdateGestureTaskInventory");
+ capabilityNames.append("UpdateNotecardAgentInventory");
capabilityNames.append("UpdateNotecardTaskInventory");
+ capabilityNames.append("UpdateScriptAgent");
capabilityNames.append("UpdateScriptTask");
capabilityNames.append("UploadBakedTexture");
capabilityNames.append("ViewerMetrics");
@@ -1571,6 +1667,12 @@ void LLViewerRegion::setSeedCapability(const std::string& url)
if (getCapability("Seed") == url)
{
// llwarns << "Ignoring duplicate seed capability" << llendl;
+ //Instead of just returning we build up a second set of seed caps and compare them
+ //to the "original" seed cap received and determine why there is problem!
+ LLSD capabilityNames = LLSD::emptyArray();
+ mImpl->buildCapabilityNames( capabilityNames );
+ LLHTTPClient::post( url, capabilityNames, BaseCapabilitiesCompleteTracker::build(getHandle() ),
+ LLSD(), CAP_REQUEST_TIMEOUT );
return;
}
@@ -1643,9 +1745,9 @@ public:
{ }
- void error(U32 statusNum, const std::string& reason)
+ void errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content)
{
- LL_WARNS2("AppInit", "SimulatorFeatures") << statusNum << ": " << reason << LL_ENDL;
+ LL_WARNS2("AppInit", "SimulatorFeatures") << "[status:" << statusNum << "]: " << content << LL_ENDL;
retry();
}
@@ -1706,6 +1808,11 @@ void LLViewerRegion::setCapability(const std::string& name, const std::string& u
}
}
+void LLViewerRegion::setCapabilityDebug(const std::string& name, const std::string& url)
+{
+ mImpl->mSecondCapabilitiesTracker[name] = url;
+}
+
bool LLViewerRegion::isSpecialCapabilityName(const std::string &name)
{
return name == "EventQueueGet" || name == "UntrustedSimulatorMessage";
@@ -1713,6 +1820,11 @@ bool LLViewerRegion::isSpecialCapabilityName(const std::string &name)
std::string LLViewerRegion::getCapability(const std::string& name) const
{
+ if (!capabilitiesReceived() && (name!=std::string("Seed")) && (name!=std::string("ObjectMedia")))
+ {
+ llwarns << "getCapability called before caps received" << llendl;
+ }
+
CapabilityMap::const_iterator iter = mImpl->mCapabilities.find(name);
if(iter == mImpl->mCapabilities.end())
{
@@ -1772,7 +1884,7 @@ LLSpatialPartition* LLViewerRegion::getSpatialPartition(U32 type)
// the viewer can not yet distinquish between normal- and estate-owned objects
// so we collapse these two bits and enable the UI if either are set
-const U32 ALLOW_RETURN_ENCROACHING_OBJECT = REGION_FLAGS_ALLOW_RETURN_ENCROACHING_OBJECT
+const U64 ALLOW_RETURN_ENCROACHING_OBJECT = REGION_FLAGS_ALLOW_RETURN_ENCROACHING_OBJECT
| REGION_FLAGS_ALLOW_RETURN_ENCROACHING_ESTATE_OBJECT;
bool LLViewerRegion::objectIsReturnable(const LLVector3& pos, const std::vector<LLBBox>& boxes) const
@@ -1780,7 +1892,7 @@ bool LLViewerRegion::objectIsReturnable(const LLVector3& pos, const std::vector<
return (mParcelOverlay != NULL)
&& (mParcelOverlay->isOwnedSelf(pos)
|| mParcelOverlay->isOwnedGroup(pos)
- || ((mRegionFlags & ALLOW_RETURN_ENCROACHING_OBJECT)
+ || (getRegionFlag(ALLOW_RETURN_ENCROACHING_OBJECT)
&& mParcelOverlay->encroachesOwned(boxes)) );
}
@@ -1800,7 +1912,10 @@ void LLViewerRegion::getNeighboringRegions( std::vector<LLViewerRegion*>& unique
{
mImpl->mLandp->getNeighboringRegions( uniqueRegions );
}
-
+void LLViewerRegion::getNeighboringRegionsStatus( std::vector<S32>& regions )
+{
+ mImpl->mLandp->getNeighboringRegionsStatus( regions );
+}
void LLViewerRegion::showReleaseNotes()
{
std::string url = this->getCapability("ServerReleaseNotes");
@@ -1833,4 +1948,53 @@ bool LLViewerRegion::meshRezEnabled() const
mSimulatorFeatures["MeshRezEnabled"].asBoolean());
}
+bool LLViewerRegion::dynamicPathfindingEnabled() const
+{
+ return ( mSimulatorFeatures.has("DynamicPathfindingEnabled") &&
+ mSimulatorFeatures["DynamicPathfindingEnabled"].asBoolean());
+}
+
+void LLViewerRegion::resetMaterialsCapThrottle()
+{
+ F32 requests_per_sec = 1.0f; // original default;
+ if ( mSimulatorFeatures.has("RenderMaterialsCapability")
+ && mSimulatorFeatures["RenderMaterialsCapability"].isReal() )
+ {
+ requests_per_sec = mSimulatorFeatures["RenderMaterialsCapability"].asReal();
+ if ( requests_per_sec == 0.0f )
+ {
+ requests_per_sec = 1.0f;
+ LL_WARNS("Materials")
+ << "region '" << getName()
+ << "' returned zero for RenderMaterialsCapability; using default "
+ << requests_per_sec << " per second"
+ << LL_ENDL;
+ }
+ LL_DEBUGS("Materials") << "region '" << getName()
+ << "' RenderMaterialsCapability " << requests_per_sec
+ << LL_ENDL;
+ }
+ else
+ {
+ LL_DEBUGS("Materials")
+ << "region '" << getName()
+ << "' did not return RenderMaterialsCapability, using default "
+ << requests_per_sec << " per second"
+ << LL_ENDL;
+ }
+
+ mMaterialsCapThrottleTimer.resetWithExpiry( 1.0f / requests_per_sec );
+}
+
+U32 LLViewerRegion::getMaxMaterialsPerTransaction() const
+{
+ U32 max_entries = 50; // original hard coded default
+ if ( mSimulatorFeatures.has( "MaxMaterialsPerTransaction" )
+ && mSimulatorFeatures[ "MaxMaterialsPerTransaction" ].isInteger())
+ {
+ max_entries = mSimulatorFeatures[ "MaxMaterialsPerTransaction" ].asInteger();
+ }
+ return max_entries;
+}
+
diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h
index c483c6ef52..8f8bfa23c1 100644..100755
--- a/indra/newview/llviewerregion.h
+++ b/indra/newview/llviewerregion.h
@@ -43,6 +43,7 @@
#include "llcapabilityprovider.h"
#include "m4math.h" // LLMatrix4
#include "llhttpclient.h"
+#include "llframetimer.h"
// Surface id's
#define LAND 1
@@ -109,13 +110,13 @@ public:
//void setAgentOffset(const LLVector3d &offset);
void updateRenderMatrix();
- void setAllowDamage(BOOL b) { setFlags(b, REGION_FLAGS_ALLOW_DAMAGE); }
- void setAllowLandmark(BOOL b) { setFlags(b, REGION_FLAGS_ALLOW_LANDMARK); }
- void setAllowSetHome(BOOL b) { setFlags(b, REGION_FLAGS_ALLOW_SET_HOME); }
- void setResetHomeOnTeleport(BOOL b) { setFlags(b, REGION_FLAGS_RESET_HOME_ON_TELEPORT); }
- void setSunFixed(BOOL b) { setFlags(b, REGION_FLAGS_SUN_FIXED); }
- void setBlockFly(BOOL b) { setFlags(b, REGION_FLAGS_BLOCK_FLY); }
- void setAllowDirectTeleport(BOOL b) { setFlags(b, REGION_FLAGS_ALLOW_DIRECT_TELEPORT); }
+ void setAllowDamage(BOOL b) { setRegionFlag(REGION_FLAGS_ALLOW_DAMAGE, b); }
+ void setAllowLandmark(BOOL b) { setRegionFlag(REGION_FLAGS_ALLOW_LANDMARK, b); }
+ void setAllowSetHome(BOOL b) { setRegionFlag(REGION_FLAGS_ALLOW_SET_HOME, b); }
+ void setResetHomeOnTeleport(BOOL b) { setRegionFlag(REGION_FLAGS_RESET_HOME_ON_TELEPORT, b); }
+ void setSunFixed(BOOL b) { setRegionFlag(REGION_FLAGS_SUN_FIXED, b); }
+ void setBlockFly(BOOL b) { setRegionFlag(REGION_FLAGS_BLOCK_FLY, b); }
+ void setAllowDirectTeleport(BOOL b) { setRegionFlag(REGION_FLAGS_ALLOW_DIRECT_TELEPORT, b); }
inline BOOL getAllowDamage() const;
@@ -156,8 +157,15 @@ public:
LLViewerParcelOverlay *getParcelOverlay() const
{ return mParcelOverlay; }
- void setRegionFlags(U32 flags);
- U32 getRegionFlags() const { return mRegionFlags; }
+ inline void setRegionFlag(U64 flag, BOOL on);
+ inline BOOL getRegionFlag(U64 flag) const;
+ void setRegionFlags(U64 flags);
+ U64 getRegionFlags() const { return mRegionFlags; }
+
+ inline void setRegionProtocol(U64 protocol, BOOL on);
+ BOOL getRegionProtocol(U64 protocol) const;
+ void setRegionProtocols(U64 protocols) { mRegionProtocols = protocols; }
+ U64 getRegionProtocols() const { return mRegionProtocols; }
void setTimeDilation(F32 time_dilation);
F32 getTimeDilation() const { return mTimeDilation; }
@@ -195,13 +203,14 @@ public:
std::string getLocalizedSimProductName() const;
// Returns "Sandbox", "Expensive", etc.
- static std::string regionFlagsToString(U32 flags);
+ static std::string regionFlagsToString(U64 flags);
// Returns translated version of "Mature", "PG", "Adult", etc.
static std::string accessToString(U8 sim_access);
// Returns "M", "PG", "A" etc.
static std::string accessToShortString(U8 sim_access);
+ static U8 shortStringToAccess(const std::string &sim_access);
// Return access icon name
static std::string getAccessIcon(U8 sim_access);
@@ -233,6 +242,7 @@ public:
void failedSeedCapability();
S32 getNumSeedCapRetries();
void setCapability(const std::string& name, const std::string& url);
+ void setCapabilityDebug(const std::string& name, const std::string& url);
// implements LLCapabilityProvider
virtual std::string getCapability(const std::string& name) const;
@@ -277,14 +287,19 @@ public:
F32 getLandHeightRegion(const LLVector3& region_pos);
+ U8 getCentralBakeVersion() { return mCentralBakeVersion; }
+
void getInfo(LLSD& info);
bool meshRezEnabled() const;
bool meshUploadEnabled() const;
- void getSimulatorFeatures(LLSD& info);
+ void getSimulatorFeatures(LLSD& info) const;
void setSimulatorFeatures(const LLSD& info);
+
+ bool dynamicPathfindingEnabled() const;
+
typedef enum
{
CACHE_MISS_TYPE_FULL = 0,
@@ -325,7 +340,15 @@ public:
bool objectsCrossParcel(const std::vector<LLBBox>& boxes) const;
void getNeighboringRegions( std::vector<LLViewerRegion*>& uniqueRegions );
+ void getNeighboringRegionsStatus( std::vector<S32>& regions );
+ const LLViewerRegionImpl * getRegionImpl() const { return mImpl; }
+ LLViewerRegionImpl * getRegionImplNC() { return mImpl; }
+
+ // implements the materials capability throttle
+ bool materialsCapThrottled() const { return !mMaterialsCapThrottleTimer.hasExpired(); }
+ void resetMaterialsCapThrottle();
+ U32 getMaxMaterialsPerTransaction() const;
public:
struct CompareDistance
{
@@ -340,7 +363,6 @@ public:
protected:
void disconnectAllNeighbors();
void initStats();
- void setFlags(BOOL b, U32 flags);
public:
LLWind mWind;
@@ -360,6 +382,8 @@ public:
LLDynamicArray<U32> mMapAvatars;
LLDynamicArray<LLUUID> mMapAvatarIDs;
+ LLFrameTimer & getRenderInfoRequestTimer() { return mRenderInfoRequestTimer; };
+
private:
LLViewerRegionImpl * mImpl;
@@ -385,11 +409,13 @@ private:
U32 mPingDelay;
F32 mDeltaTime; // Time since last measurement of lastPackets, Bits, etc
- U32 mRegionFlags; // includes damage flags
+ U64 mRegionFlags; // includes damage flags
+ U64 mRegionProtocols; // protocols supported by this region
U8 mSimAccess;
F32 mBillableFactor;
U32 mMaxTasks; // max prim count
F32 mCameraDistanceSquared; // updated once per frame
+ U8 mCentralBakeVersion;
// Information for Homestead / CR-53
S32 mClassID;
@@ -416,8 +442,46 @@ private:
BOOL mReleaseNotesRequested;
LLSD mSimulatorFeatures;
+
+ // the materials capability throttle
+ LLFrameTimer mMaterialsCapThrottleTimer;
+LLFrameTimer mRenderInfoRequestTimer;
};
+inline BOOL LLViewerRegion::getRegionProtocol(U64 protocol) const
+{
+ return ((mRegionProtocols & protocol) != 0);
+}
+
+inline void LLViewerRegion::setRegionProtocol(U64 protocol, BOOL on)
+{
+ if (on)
+ {
+ mRegionProtocols |= protocol;
+ }
+ else
+ {
+ mRegionProtocols &= ~protocol;
+ }
+}
+
+inline BOOL LLViewerRegion::getRegionFlag(U64 flag) const
+{
+ return ((mRegionFlags & flag) != 0);
+}
+
+inline void LLViewerRegion::setRegionFlag(U64 flag, BOOL on)
+{
+ if (on)
+ {
+ mRegionFlags |= flag;
+ }
+ else
+ {
+ mRegionFlags &= ~flag;
+ }
+}
+
inline BOOL LLViewerRegion::getAllowDamage() const
{
return ((mRegionFlags & REGION_FLAGS_ALLOW_DAMAGE) !=0);
diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp
index 10c61c01d5..553f6a2d59 100644..100755
--- a/indra/newview/llviewershadermgr.cpp
+++ b/indra/newview/llviewershadermgr.cpp
@@ -42,16 +42,19 @@
#include "llvosky.h"
#include "llrender.h"
-#if LL_DARWIN
-#include "OpenGL/OpenGL.h"
-#endif
-
#ifdef LL_RELEASE_FOR_DOWNLOAD
#define UNIFORM_ERRS LL_WARNS_ONCE("Shader")
#else
#define UNIFORM_ERRS LL_ERRS("Shader")
#endif
+static LLStaticHashedString sTexture0("texture0");
+static LLStaticHashedString sTexture1("texture1");
+static LLStaticHashedString sTex0("tex0");
+static LLStaticHashedString sTex1("tex1");
+static LLStaticHashedString sGlowMap("glowMap");
+static LLStaticHashedString sScreenMap("screenMap");
+
// Lots of STL stuff in here, using namespace std to keep things more readable
using std::vector;
using std::pair;
@@ -63,8 +66,16 @@ bool LLViewerShaderMgr::sSkipReload = false;
LLVector4 gShinyOrigin;
+//transform shaders
+LLGLSLShader gTransformPositionProgram;
+LLGLSLShader gTransformTexCoordProgram;
+LLGLSLShader gTransformNormalProgram;
+LLGLSLShader gTransformColorProgram;
+LLGLSLShader gTransformTangentProgram;
+
//utility shaders
LLGLSLShader gOcclusionProgram;
+LLGLSLShader gOcclusionCubeProgram;
LLGLSLShader gCustomAlphaProgram;
LLGLSLShader gGlowCombineProgram;
LLGLSLShader gSplatTextureRectProgram;
@@ -72,10 +83,14 @@ LLGLSLShader gGlowCombineFXAAProgram;
LLGLSLShader gTwoTextureAddProgram;
LLGLSLShader gOneTextureNoColorProgram;
LLGLSLShader gDebugProgram;
+LLGLSLShader gClipProgram;
+LLGLSLShader gDownsampleDepthProgram;
+LLGLSLShader gDownsampleDepthRectProgram;
LLGLSLShader gAlphaMaskProgram;
//object shaders
LLGLSLShader gObjectSimpleProgram;
+LLGLSLShader gObjectSimpleImpostorProgram;
LLGLSLShader gObjectPreviewProgram;
LLGLSLShader gObjectSimpleWaterProgram;
LLGLSLShader gObjectSimpleAlphaMaskProgram;
@@ -134,6 +149,11 @@ LLGLSLShader gUnderWaterProgram;
//interface shaders
LLGLSLShader gHighlightProgram;
+LLGLSLShader gHighlightNormalProgram;
+LLGLSLShader gHighlightSpecularProgram;
+
+LLGLSLShader gPathfindingProgram;
+LLGLSLShader gPathfindingNoNormalsProgram;
//avatar shader handles
LLGLSLShader gAvatarProgram;
@@ -156,6 +176,7 @@ LLGLSLShader gPostNightVisionProgram;
// Deferred rendering shaders
LLGLSLShader gDeferredImpostorProgram;
LLGLSLShader gDeferredWaterProgram;
+LLGLSLShader gDeferredUnderWaterProgram;
LLGLSLShader gDeferredDiffuseProgram;
LLGLSLShader gDeferredDiffuseAlphaMaskProgram;
LLGLSLShader gDeferredNonIndexedDiffuseProgram;
@@ -171,30 +192,45 @@ LLGLSLShader gDeferredTreeShadowProgram;
LLGLSLShader gDeferredAvatarProgram;
LLGLSLShader gDeferredAvatarAlphaProgram;
LLGLSLShader gDeferredLightProgram;
-LLGLSLShader gDeferredMultiLightProgram;
+LLGLSLShader gDeferredMultiLightProgram[16];
LLGLSLShader gDeferredSpotLightProgram;
LLGLSLShader gDeferredMultiSpotLightProgram;
LLGLSLShader gDeferredSunProgram;
LLGLSLShader gDeferredBlurLightProgram;
LLGLSLShader gDeferredSoftenProgram;
+LLGLSLShader gDeferredSoftenWaterProgram;
LLGLSLShader gDeferredShadowProgram;
+LLGLSLShader gDeferredShadowCubeProgram;
LLGLSLShader gDeferredShadowAlphaMaskProgram;
LLGLSLShader gDeferredAvatarShadowProgram;
LLGLSLShader gDeferredAttachmentShadowProgram;
LLGLSLShader gDeferredAlphaProgram;
+LLGLSLShader gDeferredAlphaImpostorProgram;
+LLGLSLShader gDeferredAlphaWaterProgram;
LLGLSLShader gDeferredAvatarEyesProgram;
LLGLSLShader gDeferredFullbrightProgram;
+LLGLSLShader gDeferredFullbrightAlphaMaskProgram;
+LLGLSLShader gDeferredFullbrightWaterProgram;
+LLGLSLShader gDeferredFullbrightAlphaMaskWaterProgram;
LLGLSLShader gDeferredEmissiveProgram;
LLGLSLShader gDeferredPostProgram;
LLGLSLShader gDeferredCoFProgram;
LLGLSLShader gDeferredDoFCombineProgram;
+LLGLSLShader gDeferredPostGammaCorrectProgram;
LLGLSLShader gFXAAProgram;
LLGLSLShader gDeferredPostNoDoFProgram;
LLGLSLShader gDeferredWLSkyProgram;
LLGLSLShader gDeferredWLCloudProgram;
LLGLSLShader gDeferredStarProgram;
+LLGLSLShader gDeferredFullbrightShinyProgram;
+LLGLSLShader gDeferredSkinnedFullbrightShinyProgram;
+LLGLSLShader gDeferredSkinnedFullbrightProgram;
LLGLSLShader gNormalMapGenProgram;
+// Deferred materials shaders
+LLGLSLShader gDeferredMaterialProgram[LLMaterial::SHADER_COUNT*2];
+LLGLSLShader gDeferredMaterialWaterProgram[LLMaterial::SHADER_COUNT*2];
+
LLViewerShaderMgr::LLViewerShaderMgr() :
mVertexShaderLevel(SHADER_COUNT, 0),
mMaxAvatarShaderLevel(0)
@@ -209,6 +245,7 @@ LLViewerShaderMgr::LLViewerShaderMgr() :
mShaderList.push_back(&gWaterProgram);
mShaderList.push_back(&gAvatarEyeballProgram);
mShaderList.push_back(&gObjectSimpleProgram);
+ mShaderList.push_back(&gObjectSimpleImpostorProgram);
mShaderList.push_back(&gObjectPreviewProgram);
mShaderList.push_back(&gImpostorProgram);
mShaderList.push_back(&gObjectFullbrightNoColorProgram);
@@ -259,12 +296,38 @@ LLViewerShaderMgr::LLViewerShaderMgr() :
mShaderList.push_back(&gUnderWaterProgram);
mShaderList.push_back(&gDeferredSunProgram);
mShaderList.push_back(&gDeferredSoftenProgram);
+ mShaderList.push_back(&gDeferredSoftenWaterProgram);
+ mShaderList.push_back(&gDeferredMaterialProgram[1]);
+ mShaderList.push_back(&gDeferredMaterialProgram[5]);
+ mShaderList.push_back(&gDeferredMaterialProgram[9]);
+ mShaderList.push_back(&gDeferredMaterialProgram[13]);
+ mShaderList.push_back(&gDeferredMaterialProgram[1+LLMaterial::SHADER_COUNT]);
+ mShaderList.push_back(&gDeferredMaterialProgram[5+LLMaterial::SHADER_COUNT]);
+ mShaderList.push_back(&gDeferredMaterialProgram[9+LLMaterial::SHADER_COUNT]);
+ mShaderList.push_back(&gDeferredMaterialProgram[13+LLMaterial::SHADER_COUNT]);
+ mShaderList.push_back(&gDeferredMaterialWaterProgram[1]);
+ mShaderList.push_back(&gDeferredMaterialWaterProgram[5]);
+ mShaderList.push_back(&gDeferredMaterialWaterProgram[9]);
+ mShaderList.push_back(&gDeferredMaterialWaterProgram[13]);
+ mShaderList.push_back(&gDeferredMaterialWaterProgram[1+LLMaterial::SHADER_COUNT]);
+ mShaderList.push_back(&gDeferredMaterialWaterProgram[5+LLMaterial::SHADER_COUNT]);
+ mShaderList.push_back(&gDeferredMaterialWaterProgram[9+LLMaterial::SHADER_COUNT]);
+ mShaderList.push_back(&gDeferredMaterialWaterProgram[13+LLMaterial::SHADER_COUNT]);
mShaderList.push_back(&gDeferredAlphaProgram);
+ mShaderList.push_back(&gDeferredAlphaImpostorProgram);
+ mShaderList.push_back(&gDeferredAlphaWaterProgram);
mShaderList.push_back(&gDeferredSkinnedAlphaProgram);
mShaderList.push_back(&gDeferredFullbrightProgram);
+ mShaderList.push_back(&gDeferredFullbrightAlphaMaskProgram);
+ mShaderList.push_back(&gDeferredFullbrightWaterProgram);
+ mShaderList.push_back(&gDeferredFullbrightAlphaMaskWaterProgram);
+ mShaderList.push_back(&gDeferredFullbrightShinyProgram);
+ mShaderList.push_back(&gDeferredSkinnedFullbrightShinyProgram);
+ mShaderList.push_back(&gDeferredSkinnedFullbrightProgram);
mShaderList.push_back(&gDeferredEmissiveProgram);
mShaderList.push_back(&gDeferredAvatarEyesProgram);
mShaderList.push_back(&gDeferredWaterProgram);
+ mShaderList.push_back(&gDeferredUnderWaterProgram);
mShaderList.push_back(&gDeferredAvatarAlphaProgram);
mShaderList.push_back(&gDeferredWLSkyProgram);
mShaderList.push_back(&gDeferredWLCloudProgram);
@@ -292,47 +355,6 @@ void LLViewerShaderMgr::initAttribsAndUniforms(void)
if (mReservedAttribs.empty())
{
LLShaderMgr::initAttribsAndUniforms();
-
- mAvatarUniforms.push_back("matrixPalette");
- mAvatarUniforms.push_back("gWindDir");
- mAvatarUniforms.push_back("gSinWaveParams");
- mAvatarUniforms.push_back("gGravity");
-
- mWLUniforms.push_back("camPosLocal");
-
- mTerrainUniforms.reserve(5);
- mTerrainUniforms.push_back("detail_0");
- mTerrainUniforms.push_back("detail_1");
- mTerrainUniforms.push_back("detail_2");
- mTerrainUniforms.push_back("detail_3");
- mTerrainUniforms.push_back("alpha_ramp");
-
- mGlowUniforms.push_back("glowDelta");
- mGlowUniforms.push_back("glowStrength");
-
- mGlowExtractUniforms.push_back("minLuminance");
- mGlowExtractUniforms.push_back("maxExtractAlpha");
- mGlowExtractUniforms.push_back("lumWeights");
- mGlowExtractUniforms.push_back("warmthWeights");
- mGlowExtractUniforms.push_back("warmthAmount");
-
- mShinyUniforms.push_back("origin");
-
- mWaterUniforms.reserve(12);
- mWaterUniforms.push_back("screenTex");
- mWaterUniforms.push_back("screenDepth");
- mWaterUniforms.push_back("refTex");
- mWaterUniforms.push_back("eyeVec");
- mWaterUniforms.push_back("time");
- mWaterUniforms.push_back("d1");
- mWaterUniforms.push_back("d2");
- mWaterUniforms.push_back("lightDir");
- mWaterUniforms.push_back("specular");
- mWaterUniforms.push_back("lightExp");
- mWaterUniforms.push_back("fogCol");
- mWaterUniforms.push_back("kd");
- mWaterUniforms.push_back("refScale");
- mWaterUniforms.push_back("waterHeight");
}
}
@@ -437,6 +459,13 @@ void LLViewerShaderMgr::setShaders()
S32 wl_class = 2;
S32 water_class = 2;
S32 deferred_class = 0;
+ S32 transform_class = gGLManager.mHasTransformFeedback ? 1 : 0;
+
+ static LLCachedControl<bool> use_transform_feedback(gSavedSettings, "RenderUseTransformFeedback", false);
+ if (!use_transform_feedback)
+ {
+ transform_class = 0;
+ }
if (LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&
gSavedSettings.getBOOL("RenderDeferred") &&
@@ -475,6 +504,7 @@ void LLViewerShaderMgr::setShaders()
gSky.mVOSkyp->forceSkyUpdate();
}
+
// Load lighting shaders
mVertexShaderLevel[SHADER_LIGHTING] = light_class;
mVertexShaderLevel[SHADER_INTERFACE] = light_class;
@@ -484,6 +514,7 @@ void LLViewerShaderMgr::setShaders()
mVertexShaderLevel[SHADER_EFFECT] = effect_class;
mVertexShaderLevel[SHADER_WINDLIGHT] = wl_class;
mVertexShaderLevel[SHADER_DEFERRED] = deferred_class;
+ mVertexShaderLevel[SHADER_TRANSFORM] = transform_class;
BOOL loaded = loadBasicShaders();
@@ -493,65 +524,110 @@ void LLViewerShaderMgr::setShaders()
gPipeline.mVertexShadersLoaded = 1;
// Load all shaders to set max levels
- loadShadersEnvironment();
- loadShadersWater();
- loadShadersWindLight();
- loadShadersEffects();
- loadShadersInterface();
-
- // Load max avatar shaders to set the max level
- mVertexShaderLevel[SHADER_AVATAR] = 3;
- mMaxAvatarShaderLevel = 3;
-
- if (gSavedSettings.getBOOL("RenderAvatarVP") && loadShadersObject())
- { //hardware skinning is enabled and rigged attachment shaders loaded correctly
- BOOL avatar_cloth = gSavedSettings.getBOOL("RenderAvatarCloth");
- S32 avatar_class = 1;
-
- // cloth is a class3 shader
- if(avatar_cloth)
- {
- avatar_class = 3;
- }
+ loaded = loadShadersEnvironment();
- // Set the actual level
- mVertexShaderLevel[SHADER_AVATAR] = avatar_class;
- loadShadersAvatar();
- if (mVertexShaderLevel[SHADER_AVATAR] != avatar_class)
- {
- if (mVertexShaderLevel[SHADER_AVATAR] == 0)
+ if (loaded)
+ {
+ loaded = loadShadersWater();
+ }
+
+ if (loaded)
+ {
+ loaded = loadShadersWindLight();
+ }
+
+ if (loaded)
+ {
+ loaded = loadShadersEffects();
+ }
+
+ if (loaded)
+ {
+ loaded = loadShadersInterface();
+ }
+
+ if (loaded)
+
+ {
+ loaded = loadTransformShaders();
+ }
+
+ if (loaded)
+ {
+ // Load max avatar shaders to set the max level
+ mVertexShaderLevel[SHADER_AVATAR] = 3;
+ mMaxAvatarShaderLevel = 3;
+
+ if (gSavedSettings.getBOOL("RenderAvatarVP") && loadShadersObject())
+ { //hardware skinning is enabled and rigged attachment shaders loaded correctly
+ BOOL avatar_cloth = gSavedSettings.getBOOL("RenderAvatarCloth");
+ S32 avatar_class = 1;
+
+ // cloth is a class3 shader
+ if(avatar_cloth)
{
- gSavedSettings.setBOOL("RenderAvatarVP", FALSE);
+ avatar_class = 3;
}
- if(llmax(mVertexShaderLevel[SHADER_AVATAR]-1,0) >= 3)
+
+ // Set the actual level
+ mVertexShaderLevel[SHADER_AVATAR] = avatar_class;
+ loadShadersAvatar();
+ if (mVertexShaderLevel[SHADER_AVATAR] != avatar_class)
{
- avatar_cloth = true;
+ if (mVertexShaderLevel[SHADER_AVATAR] == 0)
+ {
+ gSavedSettings.setBOOL("RenderAvatarVP", FALSE);
+ }
+ if(llmax(mVertexShaderLevel[SHADER_AVATAR]-1,0) >= 3)
+ {
+ avatar_cloth = true;
+ }
+ else
+ {
+ avatar_cloth = false;
+ }
+ gSavedSettings.setBOOL("RenderAvatarCloth", avatar_cloth);
}
- else
+ }
+ else
+ { //hardware skinning not possible, neither is deferred rendering
+ mVertexShaderLevel[SHADER_AVATAR] = 0;
+ mVertexShaderLevel[SHADER_DEFERRED] = 0;
+
+ if (gSavedSettings.getBOOL("RenderAvatarVP"))
{
- avatar_cloth = false;
+ gSavedSettings.setBOOL("RenderDeferred", FALSE);
+ gSavedSettings.setBOOL("RenderAvatarCloth", FALSE);
+ gSavedSettings.setBOOL("RenderAvatarVP", FALSE);
}
- gSavedSettings.setBOOL("RenderAvatarCloth", avatar_cloth);
+
+ loadShadersAvatar(); // unloads
+
+ loaded = loadShadersObject();
}
}
- else
- { //hardware skinning not possible, neither is deferred rendering
- mVertexShaderLevel[SHADER_AVATAR] = 0;
- mVertexShaderLevel[SHADER_DEFERRED] = 0;
-
- if (gSavedSettings.getBOOL("RenderAvatarVP"))
- {
- gSavedSettings.setBOOL("RenderDeferred", FALSE);
- gSavedSettings.setBOOL("RenderAvatarCloth", FALSE);
- gSavedSettings.setBOOL("RenderAvatarVP", FALSE);
+
+ if (!loaded)
+ { //some shader absolutely could not load, try to fall back to a simpler setting
+ if (gSavedSettings.getBOOL("WindLightUseAtmosShaders"))
+ { //disable windlight and try again
+ gSavedSettings.setBOOL("WindLightUseAtmosShaders", FALSE);
+ reentrance = false;
+ setShaders();
+ return;
}
- loadShadersAvatar(); // unloads
- loadShadersObject();
- }
+ if (gSavedSettings.getBOOL("VertexShaderEnable"))
+ { //disable shaders outright and try again
+ gSavedSettings.setBOOL("VertexShaderEnable", FALSE);
+ reentrance = false;
+ setShaders();
+ return;
+ }
+ }
- if (!loadShadersDeferred())
- {
+ if (loaded && !loadShadersDeferred())
+ { //everything else succeeded but deferred failed, disable deferred and try again
gSavedSettings.setBOOL("RenderDeferred", FALSE);
reentrance = false;
setShaders();
@@ -600,9 +676,15 @@ void LLViewerShaderMgr::setShaders()
void LLViewerShaderMgr::unloadShaders()
{
gOcclusionProgram.unload();
+ gOcclusionCubeProgram.unload();
gDebugProgram.unload();
+ gClipProgram.unload();
+ gDownsampleDepthProgram.unload();
+ gDownsampleDepthRectProgram.unload();
gAlphaMaskProgram.unload();
gUIProgram.unload();
+ gPathfindingProgram.unload();
+ gPathfindingNoNormalsProgram.unload();
gCustomAlphaProgram.unload();
gGlowCombineProgram.unload();
gSplatTextureRectProgram.unload();
@@ -614,6 +696,7 @@ void LLViewerShaderMgr::unloadShaders()
gObjectFullbrightNoColorProgram.unload();
gObjectFullbrightNoColorWaterProgram.unload();
gObjectSimpleProgram.unload();
+ gObjectSimpleImpostorProgram.unload();
gObjectPreviewProgram.unload();
gImpostorProgram.unload();
gObjectSimpleAlphaMaskProgram.unload();
@@ -676,6 +759,8 @@ void LLViewerShaderMgr::unloadShaders()
gAvatarEyeballProgram.unload();
gAvatarPickProgram.unload();
gHighlightProgram.unload();
+ gHighlightNormalProgram.unload();
+ gHighlightSpecularProgram.unload();
gWLSkyProgram.unload();
gWLCloudProgram.unload();
@@ -692,6 +777,12 @@ void LLViewerShaderMgr::unloadShaders()
gDeferredSkinnedBumpProgram.unload();
gDeferredSkinnedAlphaProgram.unload();
+ gTransformPositionProgram.unload();
+ gTransformTexCoordProgram.unload();
+ gTransformNormalProgram.unload();
+ gTransformColorProgram.unload();
+ gTransformTangentProgram.unload();
+
mVertexShaderLevel[SHADER_LIGHTING] = 0;
mVertexShaderLevel[SHADER_OBJECT] = 0;
mVertexShaderLevel[SHADER_AVATAR] = 0;
@@ -700,6 +791,7 @@ void LLViewerShaderMgr::unloadShaders()
mVertexShaderLevel[SHADER_INTERFACE] = 0;
mVertexShaderLevel[SHADER_EFFECT] = 0;
mVertexShaderLevel[SHADER_WINDLIGHT] = 0;
+ mVertexShaderLevel[SHADER_TRANSFORM] = 0;
gPipeline.mVertexShadersLoaded = 0;
}
@@ -709,9 +801,6 @@ BOOL LLViewerShaderMgr::loadBasicShaders()
// Load basic dependency shaders first
// All of these have to load for any shaders to function
-#if LL_DARWIN // Mac can't currently handle all 8 lights,
- S32 sum_lights_class = 2;
-#else
S32 sum_lights_class = 3;
// class one cards will get the lower sum lights
@@ -722,7 +811,6 @@ BOOL LLViewerShaderMgr::loadBasicShaders()
{
sum_lights_class = 2;
}
-#endif
// If we have sun and moon only checked, then only sum those lights.
if (gPipeline.getLightingDetail() == 0)
@@ -730,6 +818,14 @@ BOOL LLViewerShaderMgr::loadBasicShaders()
sum_lights_class = 1;
}
+#if LL_DARWIN
+ // Work around driver crashes on older Macs when using deferred rendering
+ // NORSPEC-59
+ //
+ if (gGLManager.mIsMobileGF)
+ sum_lights_class = 3;
+#endif
+
// Use the feature table to mask out the max light level to use. Also make sure it's at least 1.
S32 max_light_class = gSavedSettings.getS32("RenderShaderLightingMaxLevel");
sum_lights_class = llclamp(sum_lights_class, 1, max_light_class);
@@ -755,12 +851,14 @@ BOOL LLViewerShaderMgr::loadBasicShaders()
shaders.push_back( make_pair( "objects/indexedTextureV.glsl", 1 ) );
}
shaders.push_back( make_pair( "objects/nonindexedTextureV.glsl", 1 ) );
-
+
+ boost::unordered_map<std::string, std::string> attribs;
+
// We no longer have to bind the shaders to global glhandles, they are automatically added to a map now.
for (U32 i = 0; i < shaders.size(); i++)
{
// Note usage of GL_VERTEX_SHADER_ARB
- if (loadShaderFile(shaders[i].first, shaders[i].second, GL_VERTEX_SHADER_ARB) == 0)
+ if (loadShaderFile(shaders[i].first, shaders[i].second, GL_VERTEX_SHADER_ARB, &attribs) == 0)
{
return FALSE;
}
@@ -808,11 +906,11 @@ BOOL LLViewerShaderMgr::loadBasicShaders()
index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightFullbrightShinyF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) );
index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightShinyWaterF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) );
index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightFullbrightShinyWaterF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) );
-
+
for (U32 i = 0; i < shaders.size(); i++)
{
// Note usage of GL_FRAGMENT_SHADER_ARB
- if (loadShaderFile(shaders[i].first, shaders[i].second, GL_FRAGMENT_SHADER_ARB, index_channels[i]) == 0)
+ if (loadShaderFile(shaders[i].first, shaders[i].second, GL_FRAGMENT_SHADER_ARB, &attribs, index_channels[i]) == 0)
{
return FALSE;
}
@@ -828,7 +926,7 @@ BOOL LLViewerShaderMgr::loadShadersEnvironment()
if (mVertexShaderLevel[SHADER_ENVIRONMENT] == 0)
{
gTerrainProgram.unload();
- return FALSE;
+ return TRUE;
}
if (success)
@@ -844,7 +942,7 @@ BOOL LLViewerShaderMgr::loadShadersEnvironment()
gTerrainProgram.mShaderFiles.push_back(make_pair("environment/terrainV.glsl", GL_VERTEX_SHADER_ARB));
gTerrainProgram.mShaderFiles.push_back(make_pair("environment/terrainF.glsl", GL_FRAGMENT_SHADER_ARB));
gTerrainProgram.mShaderLevel = mVertexShaderLevel[SHADER_ENVIRONMENT];
- success = gTerrainProgram.createShader(NULL, &mTerrainUniforms);
+ success = gTerrainProgram.createShader(NULL, NULL);
}
if (!success)
@@ -868,7 +966,7 @@ BOOL LLViewerShaderMgr::loadShadersWater()
gWaterProgram.unload();
gUnderWaterProgram.unload();
gTerrainWaterProgram.unload();
- return FALSE;
+ return TRUE;
}
if (success)
@@ -882,7 +980,7 @@ BOOL LLViewerShaderMgr::loadShadersWater()
gWaterProgram.mShaderFiles.push_back(make_pair("environment/waterV.glsl", GL_VERTEX_SHADER_ARB));
gWaterProgram.mShaderFiles.push_back(make_pair("environment/waterF.glsl", GL_FRAGMENT_SHADER_ARB));
gWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_WATER];
- success = gWaterProgram.createShader(NULL, &mWaterUniforms);
+ success = gWaterProgram.createShader(NULL, NULL);
}
if (success)
@@ -896,7 +994,7 @@ BOOL LLViewerShaderMgr::loadShadersWater()
gUnderWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_WATER];
gUnderWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
- success = gUnderWaterProgram.createShader(NULL, &mWaterUniforms);
+ success = gUnderWaterProgram.createShader(NULL, NULL);
}
if (success)
@@ -914,7 +1012,7 @@ BOOL LLViewerShaderMgr::loadShadersWater()
gTerrainWaterProgram.mShaderFiles.push_back(make_pair("environment/terrainWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
gTerrainWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_ENVIRONMENT];
gTerrainWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
- terrainWaterSuccess = gTerrainWaterProgram.createShader(NULL, &mTerrainUniforms);
+ terrainWaterSuccess = gTerrainWaterProgram.createShader(NULL, NULL);
}
/// Keep track of water shader levels
@@ -953,7 +1051,7 @@ BOOL LLViewerShaderMgr::loadShadersEffects()
gGlowExtractProgram.unload();
gPostColorFilterProgram.unload();
gPostNightVisionProgram.unload();
- return FALSE;
+ return TRUE;
}
if (success)
@@ -963,7 +1061,7 @@ BOOL LLViewerShaderMgr::loadShadersEffects()
gGlowProgram.mShaderFiles.push_back(make_pair("effects/glowV.glsl", GL_VERTEX_SHADER_ARB));
gGlowProgram.mShaderFiles.push_back(make_pair("effects/glowF.glsl", GL_FRAGMENT_SHADER_ARB));
gGlowProgram.mShaderLevel = mVertexShaderLevel[SHADER_EFFECT];
- success = gGlowProgram.createShader(NULL, &mGlowUniforms);
+ success = gGlowProgram.createShader(NULL, NULL);
if (!success)
{
LLPipeline::sRenderGlow = FALSE;
@@ -977,7 +1075,7 @@ BOOL LLViewerShaderMgr::loadShadersEffects()
gGlowExtractProgram.mShaderFiles.push_back(make_pair("effects/glowExtractV.glsl", GL_VERTEX_SHADER_ARB));
gGlowExtractProgram.mShaderFiles.push_back(make_pair("effects/glowExtractF.glsl", GL_FRAGMENT_SHADER_ARB));
gGlowExtractProgram.mShaderLevel = mVertexShaderLevel[SHADER_EFFECT];
- success = gGlowExtractProgram.createShader(NULL, &mGlowExtractUniforms);
+ success = gGlowExtractProgram.createShader(NULL, NULL);
if (!success)
{
LLPipeline::sRenderGlow = FALSE;
@@ -1006,31 +1104,51 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredImpostorProgram.unload();
gDeferredTerrainProgram.unload();
gDeferredLightProgram.unload();
- gDeferredMultiLightProgram.unload();
+ for (U32 i = 0; i < LL_DEFERRED_MULTI_LIGHT_COUNT; ++i)
+ {
+ gDeferredMultiLightProgram[i].unload();
+ }
gDeferredSpotLightProgram.unload();
gDeferredMultiSpotLightProgram.unload();
gDeferredSunProgram.unload();
gDeferredBlurLightProgram.unload();
gDeferredSoftenProgram.unload();
+ gDeferredSoftenWaterProgram.unload();
gDeferredShadowProgram.unload();
+ gDeferredShadowCubeProgram.unload();
gDeferredShadowAlphaMaskProgram.unload();
gDeferredAvatarShadowProgram.unload();
gDeferredAttachmentShadowProgram.unload();
gDeferredAvatarProgram.unload();
gDeferredAvatarAlphaProgram.unload();
gDeferredAlphaProgram.unload();
+ gDeferredAlphaWaterProgram.unload();
gDeferredFullbrightProgram.unload();
+ gDeferredFullbrightAlphaMaskProgram.unload();
+ gDeferredFullbrightWaterProgram.unload();
+ gDeferredFullbrightAlphaMaskWaterProgram.unload();
gDeferredEmissiveProgram.unload();
gDeferredAvatarEyesProgram.unload();
gDeferredPostProgram.unload();
gDeferredCoFProgram.unload();
gDeferredDoFCombineProgram.unload();
+ gDeferredPostGammaCorrectProgram.unload();
gFXAAProgram.unload();
gDeferredWaterProgram.unload();
+ gDeferredUnderWaterProgram.unload();
gDeferredWLSkyProgram.unload();
gDeferredWLCloudProgram.unload();
gDeferredStarProgram.unload();
+ gDeferredFullbrightShinyProgram.unload();
+ gDeferredSkinnedFullbrightShinyProgram.unload();
+ gDeferredSkinnedFullbrightProgram.unload();
+
gNormalMapGenProgram.unload();
+ for (U32 i = 0; i < LLMaterial::SHADER_COUNT*2; ++i)
+ {
+ gDeferredMaterialProgram[i].unload();
+ gDeferredMaterialWaterProgram[i].unload();
+ }
return TRUE;
}
@@ -1114,20 +1232,19 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
if (success)
{
gDeferredSkinnedAlphaProgram.mName = "Deferred Skinned Alpha Shader";
- gDeferredSkinnedAlphaProgram.mFeatures.atmosphericHelpers = true;
gDeferredSkinnedAlphaProgram.mFeatures.hasObjectSkinning = true;
- gDeferredSkinnedAlphaProgram.mFeatures.calculatesAtmospherics = true;
- gDeferredSkinnedAlphaProgram.mFeatures.hasGamma = true;
- gDeferredSkinnedAlphaProgram.mFeatures.hasAtmospherics = true;
gDeferredSkinnedAlphaProgram.mFeatures.calculatesLighting = false;
gDeferredSkinnedAlphaProgram.mFeatures.hasLighting = false;
gDeferredSkinnedAlphaProgram.mFeatures.isAlphaLighting = true;
gDeferredSkinnedAlphaProgram.mFeatures.disableTextureIndex = true;
gDeferredSkinnedAlphaProgram.mShaderFiles.clear();
- gDeferredSkinnedAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaSkinnedV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredSkinnedAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaNonIndexedF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredSkinnedAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER_ARB));
+ gDeferredSkinnedAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB));
gDeferredSkinnedAlphaProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
-
+ gDeferredSkinnedAlphaProgram.addPermutation("USE_DIFFUSE_TEX", "1");
+ gDeferredSkinnedAlphaProgram.addPermutation("HAS_SKIN", "1");
+ gDeferredSkinnedAlphaProgram.addPermutation("USE_VERTEX_COLOR", "1");
+ gDeferredSkinnedAlphaProgram.addPermutation("HAS_SHADOW", mVertexShaderLevel[SHADER_DEFERRED] > 1 ? "1" : "0");
success = gDeferredSkinnedAlphaProgram.createShader(NULL, NULL);
// Hack to include uniforms for lighting without linking in lighting file
@@ -1144,7 +1261,100 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredBumpProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
success = gDeferredBumpProgram.createShader(NULL, NULL);
}
+
+ gDeferredMaterialProgram[1].mFeatures.hasLighting = false;
+ gDeferredMaterialProgram[5].mFeatures.hasLighting = false;
+ gDeferredMaterialProgram[9].mFeatures.hasLighting = false;
+ gDeferredMaterialProgram[13].mFeatures.hasLighting = false;
+ gDeferredMaterialProgram[1+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false;
+ gDeferredMaterialProgram[5+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false;
+ gDeferredMaterialProgram[9+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false;
+ gDeferredMaterialProgram[13+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false;
+
+ gDeferredMaterialWaterProgram[1].mFeatures.hasLighting = false;
+ gDeferredMaterialWaterProgram[5].mFeatures.hasLighting = false;
+ gDeferredMaterialWaterProgram[9].mFeatures.hasLighting = false;
+ gDeferredMaterialWaterProgram[13].mFeatures.hasLighting = false;
+ gDeferredMaterialWaterProgram[1+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false;
+ gDeferredMaterialWaterProgram[5+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false;
+ gDeferredMaterialWaterProgram[9+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false;
+ gDeferredMaterialWaterProgram[13+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false;
+
+ for (U32 i = 0; i < LLMaterial::SHADER_COUNT*2; ++i)
+ {
+ if (success)
+ {
+ gDeferredMaterialProgram[i].mName = llformat("Deferred Material Shader %d", i);
+
+ U32 alpha_mode = i & 0x3;
+
+ gDeferredMaterialProgram[i].mShaderFiles.clear();
+ gDeferredMaterialProgram[i].mShaderFiles.push_back(make_pair("deferred/materialV.glsl", GL_VERTEX_SHADER_ARB));
+ gDeferredMaterialProgram[i].mShaderFiles.push_back(make_pair("deferred/materialF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredMaterialProgram[i].mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ gDeferredMaterialProgram[i].addPermutation("HAS_NORMAL_MAP", i & 0x8? "1" : "0");
+ gDeferredMaterialProgram[i].addPermutation("HAS_SPECULAR_MAP", i & 0x4 ? "1" : "0");
+ gDeferredMaterialProgram[i].addPermutation("DIFFUSE_ALPHA_MODE", llformat("%d", alpha_mode));
+ gDeferredMaterialProgram[i].addPermutation("HAS_SUN_SHADOW", mVertexShaderLevel[SHADER_DEFERRED] > 1 ? "1" : "0");
+ bool has_skin = i & 0x10;
+ gDeferredMaterialProgram[i].addPermutation("HAS_SKIN",has_skin ? "1" : "0");
+
+ if (has_skin)
+ {
+ gDeferredMaterialProgram[i].mFeatures.hasObjectSkinning = true;
+ }
+ success = gDeferredMaterialProgram[i].createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
+ gDeferredMaterialWaterProgram[i].mName = llformat("Deferred Underwater Material Shader %d", i);
+
+ U32 alpha_mode = i & 0x3;
+
+ gDeferredMaterialWaterProgram[i].mShaderFiles.clear();
+ gDeferredMaterialWaterProgram[i].mShaderFiles.push_back(make_pair("deferred/materialV.glsl", GL_VERTEX_SHADER_ARB));
+ gDeferredMaterialWaterProgram[i].mShaderFiles.push_back(make_pair("deferred/materialF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredMaterialWaterProgram[i].mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ gDeferredMaterialWaterProgram[i].mShaderGroup = LLGLSLShader::SG_WATER;
+
+ gDeferredMaterialWaterProgram[i].addPermutation("HAS_NORMAL_MAP", i & 0x8? "1" : "0");
+ gDeferredMaterialWaterProgram[i].addPermutation("HAS_SPECULAR_MAP", i & 0x4 ? "1" : "0");
+ gDeferredMaterialWaterProgram[i].addPermutation("DIFFUSE_ALPHA_MODE", llformat("%d", alpha_mode));
+ gDeferredMaterialWaterProgram[i].addPermutation("HAS_SUN_SHADOW", mVertexShaderLevel[SHADER_DEFERRED] > 1 ? "1" : "0");
+ bool has_skin = i & 0x10;
+ gDeferredMaterialWaterProgram[i].addPermutation("HAS_SKIN",has_skin ? "1" : "0");
+ gDeferredMaterialWaterProgram[i].addPermutation("WATER_FOG","1");
+
+ if (has_skin)
+ {
+ gDeferredMaterialWaterProgram[i].mFeatures.hasObjectSkinning = true;
+ }
+
+ success = gDeferredMaterialWaterProgram[i].createShader(NULL, NULL);//&mWLUniforms);
+ }
+ }
+
+ gDeferredMaterialProgram[1].mFeatures.hasLighting = true;
+ gDeferredMaterialProgram[5].mFeatures.hasLighting = true;
+ gDeferredMaterialProgram[9].mFeatures.hasLighting = true;
+ gDeferredMaterialProgram[13].mFeatures.hasLighting = true;
+ gDeferredMaterialProgram[1+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true;
+ gDeferredMaterialProgram[5+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true;
+ gDeferredMaterialProgram[9+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true;
+ gDeferredMaterialProgram[13+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true;
+
+ gDeferredMaterialWaterProgram[1].mFeatures.hasLighting = true;
+ gDeferredMaterialWaterProgram[5].mFeatures.hasLighting = true;
+ gDeferredMaterialWaterProgram[9].mFeatures.hasLighting = true;
+ gDeferredMaterialWaterProgram[13].mFeatures.hasLighting = true;
+ gDeferredMaterialWaterProgram[1+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true;
+ gDeferredMaterialWaterProgram[5+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true;
+ gDeferredMaterialWaterProgram[9+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true;
+ gDeferredMaterialWaterProgram[13+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true;
+
+
if (success)
{
gDeferredTreeProgram.mName = "Deferred Tree Shader";
@@ -1182,17 +1392,22 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightV.glsl", GL_VERTEX_SHADER_ARB));
gDeferredLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightF.glsl", GL_FRAGMENT_SHADER_ARB));
gDeferredLightProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+
success = gDeferredLightProgram.createShader(NULL, NULL);
}
+ for (U32 i = 0; i < LL_DEFERRED_MULTI_LIGHT_COUNT; i++)
+ {
if (success)
{
- gDeferredMultiLightProgram.mName = "Deferred MultiLight Shader";
- gDeferredMultiLightProgram.mShaderFiles.clear();
- gDeferredMultiLightProgram.mShaderFiles.push_back(make_pair("deferred/multiPointLightV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredMultiLightProgram.mShaderFiles.push_back(make_pair("deferred/multiPointLightF.glsl", GL_FRAGMENT_SHADER_ARB));
- gDeferredMultiLightProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
- success = gDeferredMultiLightProgram.createShader(NULL, NULL);
+ gDeferredMultiLightProgram[i].mName = llformat("Deferred MultiLight Shader %d", i);
+ gDeferredMultiLightProgram[i].mShaderFiles.clear();
+ gDeferredMultiLightProgram[i].mShaderFiles.push_back(make_pair("deferred/multiPointLightV.glsl", GL_VERTEX_SHADER_ARB));
+ gDeferredMultiLightProgram[i].mShaderFiles.push_back(make_pair("deferred/multiPointLightF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredMultiLightProgram[i].mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ gDeferredMultiLightProgram[i].addPermutation("LIGHT_COUNT", llformat("%d", i+1));
+ success = gDeferredMultiLightProgram[i].createShader(NULL, NULL);
+ }
}
if (success)
@@ -1200,8 +1415,9 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredSpotLightProgram.mName = "Deferred SpotLight Shader";
gDeferredSpotLightProgram.mShaderFiles.clear();
gDeferredSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/multiSpotLightF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/spotLightF.glsl", GL_FRAGMENT_SHADER_ARB));
gDeferredSpotLightProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+
success = gDeferredSpotLightProgram.createShader(NULL, NULL);
}
@@ -1209,9 +1425,10 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
{
gDeferredMultiSpotLightProgram.mName = "Deferred MultiSpotLight Shader";
gDeferredMultiSpotLightProgram.mShaderFiles.clear();
- gDeferredMultiSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightV.glsl", GL_VERTEX_SHADER_ARB));
+ gDeferredMultiSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/multiPointLightV.glsl", GL_VERTEX_SHADER_ARB));
gDeferredMultiSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/multiSpotLightF.glsl", GL_FRAGMENT_SHADER_ARB));
gDeferredMultiSpotLightProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+
success = gDeferredMultiSpotLightProgram.createShader(NULL, NULL);
}
@@ -1238,6 +1455,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredSunProgram.mShaderFiles.push_back(make_pair(vertex, GL_VERTEX_SHADER_ARB));
gDeferredSunProgram.mShaderFiles.push_back(make_pair(fragment, GL_FRAGMENT_SHADER_ARB));
gDeferredSunProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+
success = gDeferredSunProgram.createShader(NULL, NULL);
}
@@ -1248,17 +1466,15 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredBlurLightProgram.mShaderFiles.push_back(make_pair("deferred/blurLightV.glsl", GL_VERTEX_SHADER_ARB));
gDeferredBlurLightProgram.mShaderFiles.push_back(make_pair("deferred/blurLightF.glsl", GL_FRAGMENT_SHADER_ARB));
gDeferredBlurLightProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+
success = gDeferredBlurLightProgram.createShader(NULL, NULL);
}
if (success)
{
gDeferredAlphaProgram.mName = "Deferred Alpha Shader";
- gDeferredAlphaProgram.mFeatures.atmosphericHelpers = true;
+
gDeferredAlphaProgram.mFeatures.calculatesLighting = false;
- gDeferredAlphaProgram.mFeatures.calculatesAtmospherics = true;
- gDeferredAlphaProgram.mFeatures.hasGamma = true;
- gDeferredAlphaProgram.mFeatures.hasAtmospherics = true;
gDeferredAlphaProgram.mFeatures.hasLighting = false;
gDeferredAlphaProgram.mFeatures.isAlphaLighting = true;
gDeferredAlphaProgram.mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels
@@ -1274,6 +1490,9 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredAlphaProgram.mShaderFiles.clear();
gDeferredAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER_ARB));
gDeferredAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredAlphaProgram.addPermutation("USE_INDEXED_TEX", "1");
+ gDeferredAlphaProgram.addPermutation("HAS_SHADOW", mVertexShaderLevel[SHADER_DEFERRED] > 1 ? "1" : "0");
+ gDeferredAlphaProgram.addPermutation("USE_VERTEX_COLOR", "1");
gDeferredAlphaProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
success = gDeferredAlphaProgram.createShader(NULL, NULL);
@@ -1285,6 +1504,72 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
if (success)
{
+ gDeferredAlphaImpostorProgram.mName = "Deferred Alpha Shader";
+
+ gDeferredAlphaImpostorProgram.mFeatures.calculatesLighting = false;
+ gDeferredAlphaImpostorProgram.mFeatures.hasLighting = false;
+ gDeferredAlphaImpostorProgram.mFeatures.isAlphaLighting = true;
+ gDeferredAlphaImpostorProgram.mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels
+ if (mVertexShaderLevel[SHADER_DEFERRED] < 1)
+ {
+ gDeferredAlphaImpostorProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
+ }
+ else
+ { //shave off some texture units for shadow maps
+ gDeferredAlphaImpostorProgram.mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels - 6, 1);
+ }
+
+ gDeferredAlphaImpostorProgram.mShaderFiles.clear();
+ gDeferredAlphaImpostorProgram.mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER_ARB));
+ gDeferredAlphaImpostorProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredAlphaImpostorProgram.addPermutation("USE_INDEXED_TEX", "1");
+ gDeferredAlphaImpostorProgram.addPermutation("HAS_SHADOW", mVertexShaderLevel[SHADER_DEFERRED] > 1 ? "1" : "0");
+ gDeferredAlphaImpostorProgram.addPermutation("USE_VERTEX_COLOR", "1");
+ gDeferredAlphaImpostorProgram.addPermutation("FOR_IMPOSTOR", "1");
+
+ gDeferredAlphaImpostorProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+
+ success = gDeferredAlphaImpostorProgram.createShader(NULL, NULL);
+
+ // Hack
+ gDeferredAlphaImpostorProgram.mFeatures.calculatesLighting = true;
+ gDeferredAlphaImpostorProgram.mFeatures.hasLighting = true;
+ }
+
+ if (success)
+ {
+ gDeferredAlphaWaterProgram.mName = "Deferred Alpha Underwater Shader";
+ gDeferredAlphaWaterProgram.mFeatures.calculatesLighting = false;
+ gDeferredAlphaWaterProgram.mFeatures.hasLighting = false;
+ gDeferredAlphaWaterProgram.mFeatures.isAlphaLighting = true;
+ gDeferredAlphaWaterProgram.mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels
+ if (mVertexShaderLevel[SHADER_DEFERRED] < 1)
+ {
+ gDeferredAlphaWaterProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
+ }
+ else
+ { //shave off some texture units for shadow maps
+ gDeferredAlphaWaterProgram.mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels - 6, 1);
+ }
+ gDeferredAlphaWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
+ gDeferredAlphaWaterProgram.mShaderFiles.clear();
+ gDeferredAlphaWaterProgram.mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER_ARB));
+ gDeferredAlphaWaterProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredAlphaWaterProgram.addPermutation("USE_INDEXED_TEX", "1");
+ gDeferredAlphaWaterProgram.addPermutation("WATER_FOG", "1");
+ gDeferredAlphaWaterProgram.addPermutation("USE_VERTEX_COLOR", "1");
+ gDeferredAlphaWaterProgram.addPermutation("HAS_SHADOW", mVertexShaderLevel[SHADER_DEFERRED] > 1 ? "1" : "0");
+ gDeferredAlphaWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+
+ success = gDeferredAlphaWaterProgram.createShader(NULL, NULL);
+
+ // Hack
+ gDeferredAlphaWaterProgram.mFeatures.calculatesLighting = true;
+ gDeferredAlphaWaterProgram.mFeatures.hasLighting = true;
+ }
+
+ if (success)
+ {
gDeferredAvatarEyesProgram.mName = "Deferred Avatar Eyes Shader";
gDeferredAvatarEyesProgram.mFeatures.calculatesAtmospherics = true;
gDeferredAvatarEyesProgram.mFeatures.hasGamma = true;
@@ -1313,6 +1598,98 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
if (success)
{
+ gDeferredFullbrightAlphaMaskProgram.mName = "Deferred Fullbright Alpha Masking Shader";
+ gDeferredFullbrightAlphaMaskProgram.mFeatures.calculatesAtmospherics = true;
+ gDeferredFullbrightAlphaMaskProgram.mFeatures.hasGamma = true;
+ gDeferredFullbrightAlphaMaskProgram.mFeatures.hasTransport = true;
+ gDeferredFullbrightAlphaMaskProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
+ gDeferredFullbrightAlphaMaskProgram.mShaderFiles.clear();
+ gDeferredFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER_ARB));
+ gDeferredFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredFullbrightAlphaMaskProgram.addPermutation("HAS_ALPHA_MASK","1");
+ gDeferredFullbrightAlphaMaskProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ success = gDeferredFullbrightAlphaMaskProgram.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
+ gDeferredFullbrightWaterProgram.mName = "Deferred Fullbright Underwater Shader";
+ gDeferredFullbrightWaterProgram.mFeatures.calculatesAtmospherics = true;
+ gDeferredFullbrightWaterProgram.mFeatures.hasGamma = true;
+ gDeferredFullbrightWaterProgram.mFeatures.hasTransport = true;
+ gDeferredFullbrightWaterProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
+ gDeferredFullbrightWaterProgram.mShaderFiles.clear();
+ gDeferredFullbrightWaterProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER_ARB));
+ gDeferredFullbrightWaterProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredFullbrightWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ gDeferredFullbrightWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
+ gDeferredFullbrightWaterProgram.addPermutation("WATER_FOG","1");
+ success = gDeferredFullbrightWaterProgram.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
+ gDeferredFullbrightAlphaMaskWaterProgram.mName = "Deferred Fullbright Underwater Alpha Masking Shader";
+ gDeferredFullbrightAlphaMaskWaterProgram.mFeatures.calculatesAtmospherics = true;
+ gDeferredFullbrightAlphaMaskWaterProgram.mFeatures.hasGamma = true;
+ gDeferredFullbrightAlphaMaskWaterProgram.mFeatures.hasTransport = true;
+ gDeferredFullbrightAlphaMaskWaterProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
+ gDeferredFullbrightAlphaMaskWaterProgram.mShaderFiles.clear();
+ gDeferredFullbrightAlphaMaskWaterProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER_ARB));
+ gDeferredFullbrightAlphaMaskWaterProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredFullbrightAlphaMaskWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ gDeferredFullbrightAlphaMaskWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
+ gDeferredFullbrightAlphaMaskWaterProgram.addPermutation("HAS_ALPHA_MASK","1");
+ gDeferredFullbrightAlphaMaskWaterProgram.addPermutation("WATER_FOG","1");
+ success = gDeferredFullbrightAlphaMaskWaterProgram.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
+ gDeferredFullbrightShinyProgram.mName = "Deferred FullbrightShiny Shader";
+ gDeferredFullbrightShinyProgram.mFeatures.calculatesAtmospherics = true;
+ gDeferredFullbrightShinyProgram.mFeatures.hasGamma = true;
+ gDeferredFullbrightShinyProgram.mFeatures.hasTransport = true;
+ gDeferredFullbrightShinyProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels-1;
+ gDeferredFullbrightShinyProgram.mShaderFiles.clear();
+ gDeferredFullbrightShinyProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightShinyV.glsl", GL_VERTEX_SHADER_ARB));
+ gDeferredFullbrightShinyProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredFullbrightShinyProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ success = gDeferredFullbrightShinyProgram.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
+ gDeferredSkinnedFullbrightProgram.mName = "Skinned Fullbright Shader";
+ gDeferredSkinnedFullbrightProgram.mFeatures.calculatesAtmospherics = true;
+ gDeferredSkinnedFullbrightProgram.mFeatures.hasGamma = true;
+ gDeferredSkinnedFullbrightProgram.mFeatures.hasTransport = true;
+ gDeferredSkinnedFullbrightProgram.mFeatures.hasObjectSkinning = true;
+ gDeferredSkinnedFullbrightProgram.mFeatures.disableTextureIndex = true;
+ gDeferredSkinnedFullbrightProgram.mShaderFiles.clear();
+ gDeferredSkinnedFullbrightProgram.mShaderFiles.push_back(make_pair("objects/fullbrightSkinnedV.glsl", GL_VERTEX_SHADER_ARB));
+ gDeferredSkinnedFullbrightProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredSkinnedFullbrightProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
+ success = gDeferredSkinnedFullbrightProgram.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
+ gDeferredSkinnedFullbrightShinyProgram.mName = "Skinned Fullbright Shiny Shader";
+ gDeferredSkinnedFullbrightShinyProgram.mFeatures.calculatesAtmospherics = true;
+ gDeferredSkinnedFullbrightShinyProgram.mFeatures.hasGamma = true;
+ gDeferredSkinnedFullbrightShinyProgram.mFeatures.hasTransport = true;
+ gDeferredSkinnedFullbrightShinyProgram.mFeatures.hasObjectSkinning = true;
+ gDeferredSkinnedFullbrightShinyProgram.mFeatures.disableTextureIndex = true;
+ gDeferredSkinnedFullbrightShinyProgram.mShaderFiles.clear();
+ gDeferredSkinnedFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinySkinnedV.glsl", GL_VERTEX_SHADER_ARB));
+ gDeferredSkinnedFullbrightShinyProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredSkinnedFullbrightShinyProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
+ success = gDeferredSkinnedFullbrightShinyProgram.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
gDeferredEmissiveProgram.mName = "Deferred Emissive Shader";
gDeferredEmissiveProgram.mFeatures.calculatesAtmospherics = true;
gDeferredEmissiveProgram.mFeatures.hasGamma = true;
@@ -1336,7 +1713,21 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredWaterProgram.mShaderFiles.push_back(make_pair("deferred/waterV.glsl", GL_VERTEX_SHADER_ARB));
gDeferredWaterProgram.mShaderFiles.push_back(make_pair("deferred/waterF.glsl", GL_FRAGMENT_SHADER_ARB));
gDeferredWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
- success = gDeferredWaterProgram.createShader(NULL, &mWaterUniforms);
+ success = gDeferredWaterProgram.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
+ // load water shader
+ gDeferredUnderWaterProgram.mName = "Deferred Under Water Shader";
+ gDeferredUnderWaterProgram.mFeatures.calculatesAtmospherics = true;
+ gDeferredUnderWaterProgram.mFeatures.hasGamma = true;
+ gDeferredUnderWaterProgram.mFeatures.hasTransport = true;
+ gDeferredUnderWaterProgram.mShaderFiles.clear();
+ gDeferredUnderWaterProgram.mShaderFiles.push_back(make_pair("deferred/waterV.glsl", GL_VERTEX_SHADER_ARB));
+ gDeferredUnderWaterProgram.mShaderFiles.push_back(make_pair("deferred/underWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredUnderWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ success = gDeferredUnderWaterProgram.createShader(NULL, NULL);
}
if (success)
@@ -1358,21 +1749,53 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
if (success)
{
+ gDeferredSoftenWaterProgram.mName = "Deferred Soften Underwater Shader";
+ gDeferredSoftenWaterProgram.mShaderFiles.clear();
+ gDeferredSoftenWaterProgram.mShaderFiles.push_back(make_pair("deferred/softenLightV.glsl", GL_VERTEX_SHADER_ARB));
+ gDeferredSoftenWaterProgram.mShaderFiles.push_back(make_pair("deferred/softenLightF.glsl", GL_FRAGMENT_SHADER_ARB));
+
+ gDeferredSoftenWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ gDeferredSoftenWaterProgram.addPermutation("WATER_FOG", "1");
+ gDeferredSoftenWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
+
+ if (gSavedSettings.getBOOL("RenderDeferredSSAO"))
+ { //if using SSAO, take screen space light map into account as if shadows are enabled
+ gDeferredSoftenWaterProgram.mShaderLevel = llmax(gDeferredSoftenWaterProgram.mShaderLevel, 2);
+ }
+
+ success = gDeferredSoftenWaterProgram.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
gDeferredShadowProgram.mName = "Deferred Shadow Shader";
gDeferredShadowProgram.mShaderFiles.clear();
gDeferredShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowV.glsl", GL_VERTEX_SHADER_ARB));
gDeferredShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowF.glsl", GL_FRAGMENT_SHADER_ARB));
gDeferredShadowProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ gDeferredShadowProgram.addPermutation("DEPTH_CLAMP", gGLManager.mHasDepthClamp ? "1" : "0");
success = gDeferredShadowProgram.createShader(NULL, NULL);
}
if (success)
{
+ gDeferredShadowCubeProgram.mName = "Deferred Shadow Cube Shader";
+ gDeferredShadowCubeProgram.mShaderFiles.clear();
+ gDeferredShadowCubeProgram.mShaderFiles.push_back(make_pair("deferred/shadowCubeV.glsl", GL_VERTEX_SHADER_ARB));
+ gDeferredShadowCubeProgram.mShaderFiles.push_back(make_pair("deferred/shadowF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredShadowCubeProgram.addPermutation("DEPTH_CLAMP", gGLManager.mHasDepthClamp ? "1" : "0");
+ gDeferredShadowCubeProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ success = gDeferredShadowCubeProgram.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
gDeferredShadowAlphaMaskProgram.mName = "Deferred Shadow Alpha Mask Shader";
gDeferredShadowAlphaMaskProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
gDeferredShadowAlphaMaskProgram.mShaderFiles.clear();
gDeferredShadowAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskV.glsl", GL_VERTEX_SHADER_ARB));
gDeferredShadowAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredShadowAlphaMaskProgram.addPermutation("DEPTH_CLAMP", gGLManager.mHasDepthClamp ? "1" : "0");
gDeferredShadowAlphaMaskProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
success = gDeferredShadowAlphaMaskProgram.createShader(NULL, NULL);
}
@@ -1384,8 +1807,9 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredAvatarShadowProgram.mShaderFiles.clear();
gDeferredAvatarShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarShadowV.glsl", GL_VERTEX_SHADER_ARB));
gDeferredAvatarShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarShadowF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredAvatarShadowProgram.addPermutation("DEPTH_CLAMP", gGLManager.mHasDepthClamp ? "1" : "0");
gDeferredAvatarShadowProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
- success = gDeferredAvatarShadowProgram.createShader(NULL, &mAvatarUniforms);
+ success = gDeferredAvatarShadowProgram.createShader(NULL, NULL);
}
if (success)
@@ -1395,6 +1819,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredAttachmentShadowProgram.mShaderFiles.clear();
gDeferredAttachmentShadowProgram.mShaderFiles.push_back(make_pair("deferred/attachmentShadowV.glsl", GL_VERTEX_SHADER_ARB));
gDeferredAttachmentShadowProgram.mShaderFiles.push_back(make_pair("deferred/attachmentShadowF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredAttachmentShadowProgram.addPermutation("DEPTH_CLAMP", gGLManager.mHasDepthClamp ? "1" : "0");
gDeferredAttachmentShadowProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
success = gDeferredAttachmentShadowProgram.createShader(NULL, NULL);
}
@@ -1406,7 +1831,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredTerrainProgram.mShaderFiles.push_back(make_pair("deferred/terrainV.glsl", GL_VERTEX_SHADER_ARB));
gDeferredTerrainProgram.mShaderFiles.push_back(make_pair("deferred/terrainF.glsl", GL_FRAGMENT_SHADER_ARB));
gDeferredTerrainProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
- success = gDeferredTerrainProgram.createShader(NULL, &mTerrainUniforms);
+ success = gDeferredTerrainProgram.createShader(NULL, NULL);
}
if (success)
@@ -1417,31 +1842,40 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredAvatarProgram.mShaderFiles.push_back(make_pair("deferred/avatarV.glsl", GL_VERTEX_SHADER_ARB));
gDeferredAvatarProgram.mShaderFiles.push_back(make_pair("deferred/avatarF.glsl", GL_FRAGMENT_SHADER_ARB));
gDeferredAvatarProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
- success = gDeferredAvatarProgram.createShader(NULL, &mAvatarUniforms);
+ success = gDeferredAvatarProgram.createShader(NULL, NULL);
}
if (success)
{
gDeferredAvatarAlphaProgram.mName = "Avatar Alpha Shader";
- gDeferredAvatarAlphaProgram.mFeatures.atmosphericHelpers = true;
gDeferredAvatarAlphaProgram.mFeatures.hasSkinning = true;
gDeferredAvatarAlphaProgram.mFeatures.calculatesLighting = false;
- gDeferredAvatarAlphaProgram.mFeatures.calculatesAtmospherics = true;
- gDeferredAvatarAlphaProgram.mFeatures.hasGamma = true;
- gDeferredAvatarAlphaProgram.mFeatures.hasAtmospherics = true;
gDeferredAvatarAlphaProgram.mFeatures.hasLighting = false;
gDeferredAvatarAlphaProgram.mFeatures.isAlphaLighting = true;
gDeferredAvatarAlphaProgram.mFeatures.disableTextureIndex = true;
gDeferredAvatarAlphaProgram.mShaderFiles.clear();
- gDeferredAvatarAlphaProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaNoColorV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredAvatarAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaNonIndexedNoColorF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredAvatarAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER_ARB));
+ gDeferredAvatarAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredAvatarAlphaProgram.addPermutation("USE_DIFFUSE_TEX", "1");
+ gDeferredAvatarAlphaProgram.addPermutation("IS_AVATAR_SKIN", "1");
+ gDeferredAvatarAlphaProgram.addPermutation("HAS_SHADOW", mVertexShaderLevel[SHADER_DEFERRED] > 1 ? "1" : "0");
gDeferredAvatarAlphaProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
- success = gDeferredAvatarAlphaProgram.createShader(NULL, &mAvatarUniforms);
+ success = gDeferredAvatarAlphaProgram.createShader(NULL, NULL);
gDeferredAvatarAlphaProgram.mFeatures.calculatesLighting = true;
gDeferredAvatarAlphaProgram.mFeatures.hasLighting = true;
}
+
+ if (success)
+ {
+ gDeferredPostGammaCorrectProgram.mName = "Deferred Gamma Correction Post Process";
+ gDeferredPostGammaCorrectProgram.mShaderFiles.clear();
+ gDeferredPostGammaCorrectProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER_ARB));
+ gDeferredPostGammaCorrectProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredGammaCorrect.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredPostGammaCorrectProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ success = gDeferredPostGammaCorrectProgram.createShader(NULL, NULL);
+ }
if (success)
{
@@ -1502,7 +1936,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredWLSkyProgram.mShaderFiles.push_back(make_pair("deferred/skyF.glsl", GL_FRAGMENT_SHADER_ARB));
gDeferredWLSkyProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
gDeferredWLSkyProgram.mShaderGroup = LLGLSLShader::SG_SKY;
- success = gDeferredWLSkyProgram.createShader(NULL, &mWLUniforms);
+ success = gDeferredWLSkyProgram.createShader(NULL, NULL);
}
if (success)
@@ -1513,7 +1947,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredWLCloudProgram.mShaderFiles.push_back(make_pair("deferred/cloudsF.glsl", GL_FRAGMENT_SHADER_ARB));
gDeferredWLCloudProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
gDeferredWLCloudProgram.mShaderGroup = LLGLSLShader::SG_SKY;
- success = gDeferredWLCloudProgram.createShader(NULL, &mWLUniforms);
+ success = gDeferredWLCloudProgram.createShader(NULL, NULL);
}
if (success)
@@ -1524,7 +1958,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredStarProgram.mShaderFiles.push_back(make_pair("deferred/starsF.glsl", GL_FRAGMENT_SHADER_ARB));
gDeferredStarProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
gDeferredStarProgram.mShaderGroup = LLGLSLShader::SG_SKY;
- success = gDeferredStarProgram.createShader(NULL, &mWLUniforms);
+ success = gDeferredStarProgram.createShader(NULL, NULL);
}
if (success)
@@ -1554,6 +1988,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectFullbrightNoColorProgram.unload();
gObjectFullbrightNoColorWaterProgram.unload();
gObjectSimpleProgram.unload();
+ gObjectSimpleImpostorProgram.unload();
gObjectPreviewProgram.unload();
gImpostorProgram.unload();
gObjectSimpleAlphaMaskProgram.unload();
@@ -1875,7 +2310,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectShinyNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/shinyV.glsl", GL_VERTEX_SHADER_ARB));
gObjectShinyNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/shinyF.glsl", GL_FRAGMENT_SHADER_ARB));
gObjectShinyNonIndexedProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
- success = gObjectShinyNonIndexedProgram.createShader(NULL, &mShinyUniforms);
+ success = gObjectShinyNonIndexedProgram.createShader(NULL, NULL);
}
if (success)
@@ -1892,7 +2327,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectShinyNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/shinyV.glsl", GL_VERTEX_SHADER_ARB));
gObjectShinyNonIndexedWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
gObjectShinyNonIndexedWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
- success = gObjectShinyNonIndexedWaterProgram.createShader(NULL, &mShinyUniforms);
+ success = gObjectShinyNonIndexedWaterProgram.createShader(NULL, NULL);
}
if (success)
@@ -1908,7 +2343,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectFullbrightShinyNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyV.glsl", GL_VERTEX_SHADER_ARB));
gObjectFullbrightShinyNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER_ARB));
gObjectFullbrightShinyNonIndexedProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
- success = gObjectFullbrightShinyNonIndexedProgram.createShader(NULL, &mShinyUniforms);
+ success = gObjectFullbrightShinyNonIndexedProgram.createShader(NULL, NULL);
}
if (success)
@@ -1926,7 +2361,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectFullbrightShinyNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
gObjectFullbrightShinyNonIndexedWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
gObjectFullbrightShinyNonIndexedWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
- success = gObjectFullbrightShinyNonIndexedWaterProgram.createShader(NULL, &mShinyUniforms);
+ success = gObjectFullbrightShinyNonIndexedWaterProgram.createShader(NULL, NULL);
}
if (success)
@@ -1943,18 +2378,19 @@ BOOL LLViewerShaderMgr::loadShadersObject()
if (success)
{
gObjectPreviewProgram.mName = "Simple Shader";
- gObjectPreviewProgram.mFeatures.calculatesLighting = true;
- gObjectPreviewProgram.mFeatures.calculatesAtmospherics = true;
- gObjectPreviewProgram.mFeatures.hasGamma = true;
- gObjectPreviewProgram.mFeatures.hasAtmospherics = true;
- gObjectPreviewProgram.mFeatures.hasLighting = true;
+ gObjectPreviewProgram.mFeatures.calculatesLighting = false;
+ gObjectPreviewProgram.mFeatures.calculatesAtmospherics = false;
+ gObjectPreviewProgram.mFeatures.hasGamma = false;
+ gObjectPreviewProgram.mFeatures.hasAtmospherics = false;
+ gObjectPreviewProgram.mFeatures.hasLighting = false;
gObjectPreviewProgram.mFeatures.mIndexedTextureChannels = 0;
gObjectPreviewProgram.mFeatures.disableTextureIndex = true;
gObjectPreviewProgram.mShaderFiles.clear();
gObjectPreviewProgram.mShaderFiles.push_back(make_pair("objects/previewV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectPreviewProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gObjectPreviewProgram.mShaderFiles.push_back(make_pair("objects/previewF.glsl", GL_FRAGMENT_SHADER_ARB));
gObjectPreviewProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
success = gObjectPreviewProgram.createShader(NULL, NULL);
+ gObjectPreviewProgram.mFeatures.hasLighting = true;
}
if (success)
@@ -1975,6 +2411,27 @@ BOOL LLViewerShaderMgr::loadShadersObject()
if (success)
{
+ gObjectSimpleImpostorProgram.mName = "Simple Impostor Shader";
+ gObjectSimpleImpostorProgram.mFeatures.calculatesLighting = true;
+ gObjectSimpleImpostorProgram.mFeatures.calculatesAtmospherics = true;
+ gObjectSimpleImpostorProgram.mFeatures.hasGamma = true;
+ gObjectSimpleImpostorProgram.mFeatures.hasAtmospherics = true;
+ gObjectSimpleImpostorProgram.mFeatures.hasLighting = true;
+ gObjectSimpleImpostorProgram.mFeatures.mIndexedTextureChannels = 0;
+ // force alpha mask version of lighting so we can weed out
+ // transparent pixels from impostor temp buffer
+ //
+ gObjectSimpleImpostorProgram.mFeatures.hasAlphaMask = true;
+ gObjectSimpleImpostorProgram.mShaderFiles.clear();
+ gObjectSimpleImpostorProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER_ARB));
+ gObjectSimpleImpostorProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gObjectSimpleImpostorProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
+
+ success = gObjectSimpleImpostorProgram.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
gObjectSimpleWaterProgram.mName = "Simple Water Shader";
gObjectSimpleWaterProgram.mFeatures.calculatesLighting = true;
gObjectSimpleWaterProgram.mFeatures.calculatesAtmospherics = true;
@@ -2004,12 +2461,11 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectBumpProgram.mShaderFiles.push_back(make_pair("objects/bumpF.glsl", GL_FRAGMENT_SHADER_ARB));
gObjectBumpProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
success = gObjectBumpProgram.createShader(NULL, NULL);
-
if (success)
{ //lldrawpoolbump assumes "texture0" has channel 0 and "texture1" has channel 1
gObjectBumpProgram.bind();
- gObjectBumpProgram.uniform1i("texture0", 0);
- gObjectBumpProgram.uniform1i("texture1", 1);
+ gObjectBumpProgram.uniform1i(sTexture0, 0);
+ gObjectBumpProgram.uniform1i(sTexture1, 1);
gObjectBumpProgram.unbind();
}
}
@@ -2158,7 +2614,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectShinyProgram.mShaderFiles.push_back(make_pair("objects/shinyV.glsl", GL_VERTEX_SHADER_ARB));
gObjectShinyProgram.mShaderFiles.push_back(make_pair("objects/shinyF.glsl", GL_FRAGMENT_SHADER_ARB));
gObjectShinyProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
- success = gObjectShinyProgram.createShader(NULL, &mShinyUniforms);
+ success = gObjectShinyProgram.createShader(NULL, NULL);
}
if (success)
@@ -2175,7 +2631,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/shinyV.glsl", GL_VERTEX_SHADER_ARB));
gObjectShinyWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
gObjectShinyWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
- success = gObjectShinyWaterProgram.createShader(NULL, &mShinyUniforms);
+ success = gObjectShinyWaterProgram.createShader(NULL, NULL);
}
if (success)
@@ -2191,7 +2647,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyV.glsl", GL_VERTEX_SHADER_ARB));
gObjectFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER_ARB));
gObjectFullbrightShinyProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
- success = gObjectFullbrightShinyProgram.createShader(NULL, &mShinyUniforms);
+ success = gObjectFullbrightShinyProgram.createShader(NULL, NULL);
}
if (success)
@@ -2209,7 +2665,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectFullbrightShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
gObjectFullbrightShinyWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
gObjectFullbrightShinyWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
- success = gObjectFullbrightShinyWaterProgram.createShader(NULL, &mShinyUniforms);
+ success = gObjectFullbrightShinyWaterProgram.createShader(NULL, NULL);
}
if (mVertexShaderLevel[SHADER_AVATAR] > 0)
@@ -2223,6 +2679,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gSkinnedObjectSimpleProgram.mFeatures.hasAtmospherics = true;
gSkinnedObjectSimpleProgram.mFeatures.hasLighting = true;
gSkinnedObjectSimpleProgram.mFeatures.hasObjectSkinning = true;
+ gSkinnedObjectSimpleProgram.mFeatures.hasAlphaMask = true;
gSkinnedObjectSimpleProgram.mFeatures.disableTextureIndex = true;
gSkinnedObjectSimpleProgram.mShaderFiles.clear();
gSkinnedObjectSimpleProgram.mShaderFiles.push_back(make_pair("objects/simpleSkinnedV.glsl", GL_VERTEX_SHADER_ARB));
@@ -2239,6 +2696,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gSkinnedObjectFullbrightProgram.mFeatures.hasTransport = true;
gSkinnedObjectFullbrightProgram.mFeatures.isFullbright = true;
gSkinnedObjectFullbrightProgram.mFeatures.hasObjectSkinning = true;
+ gSkinnedObjectFullbrightProgram.mFeatures.hasAlphaMask = true;
gSkinnedObjectFullbrightProgram.mFeatures.disableTextureIndex = true;
gSkinnedObjectFullbrightProgram.mShaderFiles.clear();
gSkinnedObjectFullbrightProgram.mShaderFiles.push_back(make_pair("objects/fullbrightSkinnedV.glsl", GL_VERTEX_SHADER_ARB));
@@ -2289,12 +2747,13 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gSkinnedObjectFullbrightShinyProgram.mFeatures.isShiny = true;
gSkinnedObjectFullbrightShinyProgram.mFeatures.isFullbright = true;
gSkinnedObjectFullbrightShinyProgram.mFeatures.hasObjectSkinning = true;
+ gSkinnedObjectFullbrightShinyProgram.mFeatures.hasAlphaMask = true;
gSkinnedObjectFullbrightShinyProgram.mFeatures.disableTextureIndex = true;
gSkinnedObjectFullbrightShinyProgram.mShaderFiles.clear();
gSkinnedObjectFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinySkinnedV.glsl", GL_VERTEX_SHADER_ARB));
gSkinnedObjectFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER_ARB));
gSkinnedObjectFullbrightShinyProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
- success = gSkinnedObjectFullbrightShinyProgram.createShader(NULL, &mShinyUniforms);
+ success = gSkinnedObjectFullbrightShinyProgram.createShader(NULL, NULL);
}
if (success)
@@ -2305,13 +2764,14 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gSkinnedObjectShinySimpleProgram.mFeatures.hasGamma = true;
gSkinnedObjectShinySimpleProgram.mFeatures.hasAtmospherics = true;
gSkinnedObjectShinySimpleProgram.mFeatures.hasObjectSkinning = true;
+ gSkinnedObjectShinySimpleProgram.mFeatures.hasAlphaMask = true;
gSkinnedObjectShinySimpleProgram.mFeatures.isShiny = true;
gSkinnedObjectShinySimpleProgram.mFeatures.disableTextureIndex = true;
gSkinnedObjectShinySimpleProgram.mShaderFiles.clear();
gSkinnedObjectShinySimpleProgram.mShaderFiles.push_back(make_pair("objects/shinySimpleSkinnedV.glsl", GL_VERTEX_SHADER_ARB));
gSkinnedObjectShinySimpleProgram.mShaderFiles.push_back(make_pair("objects/shinyF.glsl", GL_FRAGMENT_SHADER_ARB));
gSkinnedObjectShinySimpleProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
- success = gSkinnedObjectShinySimpleProgram.createShader(NULL, &mShinyUniforms);
+ success = gSkinnedObjectShinySimpleProgram.createShader(NULL, NULL);
}
if (success)
@@ -2342,6 +2802,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gSkinnedObjectFullbrightWaterProgram.mFeatures.hasTransport = true;
gSkinnedObjectFullbrightWaterProgram.mFeatures.isFullbright = true;
gSkinnedObjectFullbrightWaterProgram.mFeatures.hasObjectSkinning = true;
+ gSkinnedObjectFullbrightWaterProgram.mFeatures.hasAlphaMask = true;
gSkinnedObjectFullbrightWaterProgram.mFeatures.hasWaterFog = true;
gSkinnedObjectFullbrightWaterProgram.mFeatures.disableTextureIndex = true;
gSkinnedObjectFullbrightWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
@@ -2361,6 +2822,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.isShiny = true;
gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.isFullbright = true;
gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.hasObjectSkinning = true;
+ gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.hasAlphaMask = true;
gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.hasWaterFog = true;
gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.disableTextureIndex = true;
gSkinnedObjectFullbrightShinyWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
@@ -2368,7 +2830,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gSkinnedObjectFullbrightShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinySkinnedV.glsl", GL_VERTEX_SHADER_ARB));
gSkinnedObjectFullbrightShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
gSkinnedObjectFullbrightShinyWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
- success = gSkinnedObjectFullbrightShinyWaterProgram.createShader(NULL, &mShinyUniforms);
+ success = gSkinnedObjectFullbrightShinyWaterProgram.createShader(NULL, NULL);
}
if (success)
@@ -2379,6 +2841,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gSkinnedObjectShinySimpleWaterProgram.mFeatures.hasGamma = true;
gSkinnedObjectShinySimpleWaterProgram.mFeatures.hasAtmospherics = true;
gSkinnedObjectShinySimpleWaterProgram.mFeatures.hasObjectSkinning = true;
+ gSkinnedObjectShinySimpleWaterProgram.mFeatures.hasAlphaMask = true;
gSkinnedObjectShinySimpleWaterProgram.mFeatures.isShiny = true;
gSkinnedObjectShinySimpleWaterProgram.mFeatures.hasWaterFog = true;
gSkinnedObjectShinySimpleWaterProgram.mFeatures.disableTextureIndex = true;
@@ -2387,7 +2850,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gSkinnedObjectShinySimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/shinySimpleSkinnedV.glsl", GL_VERTEX_SHADER_ARB));
gSkinnedObjectShinySimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/shinyWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
gSkinnedObjectShinySimpleWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
- success = gSkinnedObjectShinySimpleWaterProgram.createShader(NULL, &mShinyUniforms);
+ success = gSkinnedObjectShinySimpleWaterProgram.createShader(NULL, NULL);
}
}
@@ -2410,7 +2873,7 @@ BOOL LLViewerShaderMgr::loadShadersAvatar()
gAvatarWaterProgram.unload();
gAvatarEyeballProgram.unload();
gAvatarPickProgram.unload();
- return FALSE;
+ return TRUE;
}
if (success)
@@ -2428,7 +2891,7 @@ BOOL LLViewerShaderMgr::loadShadersAvatar()
gAvatarProgram.mShaderFiles.push_back(make_pair("avatar/avatarV.glsl", GL_VERTEX_SHADER_ARB));
gAvatarProgram.mShaderFiles.push_back(make_pair("avatar/avatarF.glsl", GL_FRAGMENT_SHADER_ARB));
gAvatarProgram.mShaderLevel = mVertexShaderLevel[SHADER_AVATAR];
- success = gAvatarProgram.createShader(NULL, &mAvatarUniforms);
+ success = gAvatarProgram.createShader(NULL, NULL);
if (success)
{
@@ -2447,7 +2910,7 @@ BOOL LLViewerShaderMgr::loadShadersAvatar()
// Note: no cloth under water:
gAvatarWaterProgram.mShaderLevel = llmin(mVertexShaderLevel[SHADER_AVATAR], 1);
gAvatarWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
- success = gAvatarWaterProgram.createShader(NULL, &mAvatarUniforms);
+ success = gAvatarWaterProgram.createShader(NULL, NULL);
}
/// Keep track of avatar levels
@@ -2466,7 +2929,7 @@ BOOL LLViewerShaderMgr::loadShadersAvatar()
gAvatarPickProgram.mShaderFiles.push_back(make_pair("avatar/pickAvatarV.glsl", GL_VERTEX_SHADER_ARB));
gAvatarPickProgram.mShaderFiles.push_back(make_pair("avatar/pickAvatarF.glsl", GL_FRAGMENT_SHADER_ARB));
gAvatarPickProgram.mShaderLevel = mVertexShaderLevel[SHADER_AVATAR];
- success = gAvatarPickProgram.createShader(NULL, &mAvatarUniforms);
+ success = gAvatarPickProgram.createShader(NULL, NULL);
}
if (success)
@@ -2504,7 +2967,7 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
if (mVertexShaderLevel[SHADER_INTERFACE] == 0)
{
gHighlightProgram.unload();
- return FALSE;
+ return TRUE;
}
if (success)
@@ -2519,6 +2982,26 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
if (success)
{
+ gHighlightNormalProgram.mName = "Highlight Normals Shader";
+ gHighlightNormalProgram.mShaderFiles.clear();
+ gHighlightNormalProgram.mShaderFiles.push_back(make_pair("interface/highlightNormV.glsl", GL_VERTEX_SHADER_ARB));
+ gHighlightNormalProgram.mShaderFiles.push_back(make_pair("interface/highlightF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gHighlightNormalProgram.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE];
+ success = gHighlightNormalProgram.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
+ gHighlightSpecularProgram.mName = "Highlight Spec Shader";
+ gHighlightSpecularProgram.mShaderFiles.clear();
+ gHighlightSpecularProgram.mShaderFiles.push_back(make_pair("interface/highlightSpecV.glsl", GL_VERTEX_SHADER_ARB));
+ gHighlightSpecularProgram.mShaderFiles.push_back(make_pair("interface/highlightF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gHighlightSpecularProgram.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE];
+ success = gHighlightSpecularProgram.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
gUIProgram.mName = "UI Shader";
gUIProgram.mShaderFiles.clear();
gUIProgram.mShaderFiles.push_back(make_pair("interface/uiV.glsl", GL_VERTEX_SHADER_ARB));
@@ -2529,6 +3012,26 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
if (success)
{
+ gPathfindingProgram.mName = "Pathfinding Shader";
+ gPathfindingProgram.mShaderFiles.clear();
+ gPathfindingProgram.mShaderFiles.push_back(make_pair("interface/pathfindingV.glsl", GL_VERTEX_SHADER_ARB));
+ gPathfindingProgram.mShaderFiles.push_back(make_pair("interface/pathfindingF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gPathfindingProgram.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE];
+ success = gPathfindingProgram.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
+ gPathfindingNoNormalsProgram.mName = "PathfindingNoNormals Shader";
+ gPathfindingNoNormalsProgram.mShaderFiles.clear();
+ gPathfindingNoNormalsProgram.mShaderFiles.push_back(make_pair("interface/pathfindingNoNormalV.glsl", GL_VERTEX_SHADER_ARB));
+ gPathfindingNoNormalsProgram.mShaderFiles.push_back(make_pair("interface/pathfindingF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gPathfindingNoNormalsProgram.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE];
+ success = gPathfindingNoNormalsProgram.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
gCustomAlphaProgram.mName = "Custom Alpha Shader";
gCustomAlphaProgram.mShaderFiles.clear();
gCustomAlphaProgram.mShaderFiles.push_back(make_pair("interface/customalphaV.glsl", GL_VERTEX_SHADER_ARB));
@@ -2548,7 +3051,7 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
if (success)
{
gSplatTextureRectProgram.bind();
- gSplatTextureRectProgram.uniform1i("screenMap", 0);
+ gSplatTextureRectProgram.uniform1i(sScreenMap, 0);
gSplatTextureRectProgram.unbind();
}
}
@@ -2564,8 +3067,8 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
if (success)
{
gGlowCombineProgram.bind();
- gGlowCombineProgram.uniform1i("glowMap", 0);
- gGlowCombineProgram.uniform1i("screenMap", 1);
+ gGlowCombineProgram.uniform1i(sGlowMap, 0);
+ gGlowCombineProgram.uniform1i(sScreenMap, 1);
gGlowCombineProgram.unbind();
}
}
@@ -2581,8 +3084,8 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
if (success)
{
gGlowCombineFXAAProgram.bind();
- gGlowCombineFXAAProgram.uniform1i("glowMap", 0);
- gGlowCombineFXAAProgram.uniform1i("screenMap", 1);
+ gGlowCombineFXAAProgram.uniform1i(sGlowMap, 0);
+ gGlowCombineFXAAProgram.uniform1i(sScreenMap, 1);
gGlowCombineFXAAProgram.unbind();
}
}
@@ -2599,8 +3102,8 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
if (success)
{
gTwoTextureAddProgram.bind();
- gTwoTextureAddProgram.uniform1i("tex0", 0);
- gTwoTextureAddProgram.uniform1i("tex1", 1);
+ gTwoTextureAddProgram.uniform1i(sTex0, 0);
+ gTwoTextureAddProgram.uniform1i(sTex1, 1);
}
}
@@ -2615,7 +3118,7 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
if (success)
{
gOneTextureNoColorProgram.bind();
- gOneTextureNoColorProgram.uniform1i("tex0", 0);
+ gOneTextureNoColorProgram.uniform1i(sTex0, 0);
}
}
@@ -2630,7 +3133,7 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
if (success)
{
gSolidColorProgram.bind();
- gSolidColorProgram.uniform1i("tex0", 0);
+ gSolidColorProgram.uniform1i(sTex0, 0);
gSolidColorProgram.unbind();
}
}
@@ -2647,6 +3150,16 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
if (success)
{
+ gOcclusionCubeProgram.mName = "Occlusion Cube Shader";
+ gOcclusionCubeProgram.mShaderFiles.clear();
+ gOcclusionCubeProgram.mShaderFiles.push_back(make_pair("interface/occlusionCubeV.glsl", GL_VERTEX_SHADER_ARB));
+ gOcclusionCubeProgram.mShaderFiles.push_back(make_pair("interface/occlusionF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gOcclusionCubeProgram.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE];
+ success = gOcclusionCubeProgram.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
gDebugProgram.mName = "Debug Shader";
gDebugProgram.mShaderFiles.clear();
gDebugProgram.mShaderFiles.push_back(make_pair("interface/debugV.glsl", GL_VERTEX_SHADER_ARB));
@@ -2657,6 +3170,36 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
if (success)
{
+ gClipProgram.mName = "Clip Shader";
+ gClipProgram.mShaderFiles.clear();
+ gClipProgram.mShaderFiles.push_back(make_pair("interface/clipV.glsl", GL_VERTEX_SHADER_ARB));
+ gClipProgram.mShaderFiles.push_back(make_pair("interface/clipF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gClipProgram.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE];
+ success = gClipProgram.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
+ gDownsampleDepthProgram.mName = "DownsampleDepth Shader";
+ gDownsampleDepthProgram.mShaderFiles.clear();
+ gDownsampleDepthProgram.mShaderFiles.push_back(make_pair("interface/downsampleDepthV.glsl", GL_VERTEX_SHADER_ARB));
+ gDownsampleDepthProgram.mShaderFiles.push_back(make_pair("interface/downsampleDepthF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDownsampleDepthProgram.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE];
+ success = gDownsampleDepthProgram.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
+ gDownsampleDepthRectProgram.mName = "DownsampleDepthRect Shader";
+ gDownsampleDepthRectProgram.mShaderFiles.clear();
+ gDownsampleDepthRectProgram.mShaderFiles.push_back(make_pair("interface/downsampleDepthV.glsl", GL_VERTEX_SHADER_ARB));
+ gDownsampleDepthRectProgram.mShaderFiles.push_back(make_pair("interface/downsampleDepthRectF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDownsampleDepthRectProgram.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE];
+ success = gDownsampleDepthRectProgram.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
gAlphaMaskProgram.mName = "Alpha Mask Shader";
gAlphaMaskProgram.mShaderFiles.clear();
gAlphaMaskProgram.mShaderFiles.push_back(make_pair("interface/alphamaskV.glsl", GL_VERTEX_SHADER_ARB));
@@ -2682,7 +3225,7 @@ BOOL LLViewerShaderMgr::loadShadersWindLight()
{
gWLSkyProgram.unload();
gWLCloudProgram.unload();
- return FALSE;
+ return TRUE;
}
if (success)
@@ -2694,7 +3237,7 @@ BOOL LLViewerShaderMgr::loadShadersWindLight()
gWLSkyProgram.mShaderFiles.push_back(make_pair("windlight/skyF.glsl", GL_FRAGMENT_SHADER_ARB));
gWLSkyProgram.mShaderLevel = mVertexShaderLevel[SHADER_WINDLIGHT];
gWLSkyProgram.mShaderGroup = LLGLSLShader::SG_SKY;
- success = gWLSkyProgram.createShader(NULL, &mWLUniforms);
+ success = gWLSkyProgram.createShader(NULL, NULL);
}
if (success)
@@ -2706,12 +3249,101 @@ BOOL LLViewerShaderMgr::loadShadersWindLight()
gWLCloudProgram.mShaderFiles.push_back(make_pair("windlight/cloudsF.glsl", GL_FRAGMENT_SHADER_ARB));
gWLCloudProgram.mShaderLevel = mVertexShaderLevel[SHADER_WINDLIGHT];
gWLCloudProgram.mShaderGroup = LLGLSLShader::SG_SKY;
- success = gWLCloudProgram.createShader(NULL, &mWLUniforms);
+ success = gWLCloudProgram.createShader(NULL, NULL);
}
return success;
}
+BOOL LLViewerShaderMgr::loadTransformShaders()
+{
+ BOOL success = TRUE;
+
+ if (mVertexShaderLevel[SHADER_TRANSFORM] < 1)
+ {
+ gTransformPositionProgram.unload();
+ gTransformTexCoordProgram.unload();
+ gTransformNormalProgram.unload();
+ gTransformColorProgram.unload();
+ gTransformTangentProgram.unload();
+ return TRUE;
+ }
+
+ if (success)
+ {
+ gTransformPositionProgram.mName = "Position Transform Shader";
+ gTransformPositionProgram.mShaderFiles.clear();
+ gTransformPositionProgram.mShaderFiles.push_back(make_pair("transform/positionV.glsl", GL_VERTEX_SHADER_ARB));
+ gTransformPositionProgram.mShaderLevel = mVertexShaderLevel[SHADER_TRANSFORM];
+
+ const char* varyings[] = {
+ "position_out",
+ "texture_index_out",
+ };
+
+ success = gTransformPositionProgram.createShader(NULL, NULL, 2, varyings);
+ }
+
+ if (success)
+ {
+ gTransformTexCoordProgram.mName = "TexCoord Transform Shader";
+ gTransformTexCoordProgram.mShaderFiles.clear();
+ gTransformTexCoordProgram.mShaderFiles.push_back(make_pair("transform/texcoordV.glsl", GL_VERTEX_SHADER_ARB));
+ gTransformTexCoordProgram.mShaderLevel = mVertexShaderLevel[SHADER_TRANSFORM];
+
+ const char* varyings[] = {
+ "texcoord_out",
+ };
+
+ success = gTransformTexCoordProgram.createShader(NULL, NULL, 1, varyings);
+ }
+
+ if (success)
+ {
+ gTransformNormalProgram.mName = "Normal Transform Shader";
+ gTransformNormalProgram.mShaderFiles.clear();
+ gTransformNormalProgram.mShaderFiles.push_back(make_pair("transform/normalV.glsl", GL_VERTEX_SHADER_ARB));
+ gTransformNormalProgram.mShaderLevel = mVertexShaderLevel[SHADER_TRANSFORM];
+
+ const char* varyings[] = {
+ "normal_out",
+ };
+
+ success = gTransformNormalProgram.createShader(NULL, NULL, 1, varyings);
+ }
+
+ if (success)
+ {
+ gTransformColorProgram.mName = "Color Transform Shader";
+ gTransformColorProgram.mShaderFiles.clear();
+ gTransformColorProgram.mShaderFiles.push_back(make_pair("transform/colorV.glsl", GL_VERTEX_SHADER_ARB));
+ gTransformColorProgram.mShaderLevel = mVertexShaderLevel[SHADER_TRANSFORM];
+
+ const char* varyings[] = {
+ "color_out",
+ };
+
+ success = gTransformColorProgram.createShader(NULL, NULL, 1, varyings);
+ }
+
+ if (success)
+ {
+ gTransformTangentProgram.mName = "Binormal Transform Shader";
+ gTransformTangentProgram.mShaderFiles.clear();
+ gTransformTangentProgram.mShaderFiles.push_back(make_pair("transform/binormalV.glsl", GL_VERTEX_SHADER_ARB));
+ gTransformTangentProgram.mShaderLevel = mVertexShaderLevel[SHADER_TRANSFORM];
+
+ const char* varyings[] = {
+ "tangent_out",
+ };
+
+ success = gTransformTangentProgram.createShader(NULL, NULL, 1, varyings);
+ }
+
+
+ return success;
+}
+
std::string LLViewerShaderMgr::getShaderDirPrefix(void)
{
return gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "shaders/class");
@@ -2732,3 +3364,4 @@ LLViewerShaderMgr::shader_iter LLViewerShaderMgr::endShaders() const
{
return mShaderList.end();
}
+
diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h
index 95eb551bf1..3d89f8d20a 100644..100755
--- a/indra/newview/llviewershadermgr.h
+++ b/indra/newview/llviewershadermgr.h
@@ -28,6 +28,9 @@
#define LL_VIEWER_SHADER_MGR_H
#include "llshadermgr.h"
+#include "llmaterial.h"
+
+#define LL_DEFERRED_MULTI_LIGHT_COUNT 16
class LLViewerShaderMgr: public LLShaderMgr
{
@@ -54,6 +57,7 @@ public:
BOOL loadShadersWater();
BOOL loadShadersInterface();
BOOL loadShadersWindLight();
+ BOOL loadTransformShaders();
std::vector<S32> mVertexShaderLevel;
S32 mMaxAvatarShaderLevel;
@@ -69,60 +73,10 @@ public:
SHADER_WINDLIGHT,
SHADER_WATER,
SHADER_DEFERRED,
+ SHADER_TRANSFORM,
SHADER_COUNT
};
- typedef enum
- {
- SHINY_ORIGIN = END_RESERVED_UNIFORMS
- } eShinyUniforms;
-
- typedef enum
- {
- WATER_SCREENTEX = END_RESERVED_UNIFORMS,
- WATER_SCREENDEPTH,
- WATER_REFTEX,
- WATER_EYEVEC,
- WATER_TIME,
- WATER_WAVE_DIR1,
- WATER_WAVE_DIR2,
- WATER_LIGHT_DIR,
- WATER_SPECULAR,
- WATER_SPECULAR_EXP,
- WATER_FOGCOLOR,
- WATER_FOGDENSITY,
- WATER_REFSCALE,
- WATER_WATERHEIGHT,
- } eWaterUniforms;
-
- typedef enum
- {
- WL_CAMPOSLOCAL = END_RESERVED_UNIFORMS,
- WL_WATERHEIGHT
- } eWLUniforms;
-
- typedef enum
- {
- TERRAIN_DETAIL0 = END_RESERVED_UNIFORMS,
- TERRAIN_DETAIL1,
- TERRAIN_DETAIL2,
- TERRAIN_DETAIL3,
- TERRAIN_ALPHARAMP
- } eTerrainUniforms;
-
- typedef enum
- {
- GLOW_DELTA = END_RESERVED_UNIFORMS
- } eGlowUniforms;
-
- typedef enum
- {
- AVATAR_MATRIX = END_RESERVED_UNIFORMS,
- AVATAR_WIND,
- AVATAR_SINWAVE,
- AVATAR_GRAVITY,
- } eAvatarUniforms;
-
// simple model of forward iterator
// http://www.sgi.com/tech/stl/ForwardIterator.html
class shader_iter
@@ -209,14 +163,26 @@ inline bool operator != (LLViewerShaderMgr::shader_iter const & a, LLViewerShade
extern LLVector4 gShinyOrigin;
+//transform shaders
+extern LLGLSLShader gTransformPositionProgram;
+extern LLGLSLShader gTransformTexCoordProgram;
+extern LLGLSLShader gTransformNormalProgram;
+extern LLGLSLShader gTransformColorProgram;
+extern LLGLSLShader gTransformTangentProgram;
+
+
+
//utility shaders
extern LLGLSLShader gOcclusionProgram;
+extern LLGLSLShader gOcclusionCubeProgram;
extern LLGLSLShader gCustomAlphaProgram;
extern LLGLSLShader gGlowCombineProgram;
extern LLGLSLShader gSplatTextureRectProgram;
extern LLGLSLShader gGlowCombineFXAAProgram;
extern LLGLSLShader gDebugProgram;
-extern LLGLSLShader gAlphaMaskProgram;
+extern LLGLSLShader gClipProgram;
+extern LLGLSLShader gDownsampleDepthProgram;
+extern LLGLSLShader gDownsampleDepthRectProgram;
//output tex0[tc0] + tex1[tc1]
extern LLGLSLShader gTwoTextureAddProgram;
@@ -225,6 +191,7 @@ extern LLGLSLShader gOneTextureNoColorProgram;
//object shaders
extern LLGLSLShader gObjectSimpleProgram;
+extern LLGLSLShader gObjectSimpleImpostorProgram;
extern LLGLSLShader gObjectPreviewProgram;
extern LLGLSLShader gObjectSimpleAlphaMaskProgram;
extern LLGLSLShader gObjectSimpleWaterProgram;
@@ -288,6 +255,11 @@ extern LLGLSLShader gGlowExtractProgram;
//interface shaders
extern LLGLSLShader gHighlightProgram;
+extern LLGLSLShader gHighlightNormalProgram;
+extern LLGLSLShader gHighlightSpecularProgram;
+
+extern LLGLSLShader gPathfindingProgram;
+extern LLGLSLShader gPathfindingNoNormalsProgram;
// avatar shader handles
extern LLGLSLShader gAvatarProgram;
@@ -304,9 +276,11 @@ extern LLGLSLShader gWLCloudProgram;
extern LLGLSLShader gPostColorFilterProgram;
extern LLGLSLShader gPostNightVisionProgram;
+
// Deferred rendering shaders
extern LLGLSLShader gDeferredImpostorProgram;
extern LLGLSLShader gDeferredWaterProgram;
+extern LLGLSLShader gDeferredUnderWaterProgram;
extern LLGLSLShader gDeferredDiffuseProgram;
extern LLGLSLShader gDeferredDiffuseAlphaMaskProgram;
extern LLGLSLShader gDeferredNonIndexedDiffuseAlphaMaskProgram;
@@ -320,30 +294,44 @@ extern LLGLSLShader gDeferredTerrainProgram;
extern LLGLSLShader gDeferredTreeProgram;
extern LLGLSLShader gDeferredTreeShadowProgram;
extern LLGLSLShader gDeferredLightProgram;
-extern LLGLSLShader gDeferredMultiLightProgram;
+extern LLGLSLShader gDeferredMultiLightProgram[LL_DEFERRED_MULTI_LIGHT_COUNT];
extern LLGLSLShader gDeferredSpotLightProgram;
extern LLGLSLShader gDeferredMultiSpotLightProgram;
extern LLGLSLShader gDeferredSunProgram;
extern LLGLSLShader gDeferredBlurLightProgram;
extern LLGLSLShader gDeferredAvatarProgram;
extern LLGLSLShader gDeferredSoftenProgram;
+extern LLGLSLShader gDeferredSoftenWaterProgram;
extern LLGLSLShader gDeferredShadowProgram;
+extern LLGLSLShader gDeferredShadowCubeProgram;
extern LLGLSLShader gDeferredShadowAlphaMaskProgram;
extern LLGLSLShader gDeferredPostProgram;
extern LLGLSLShader gDeferredCoFProgram;
extern LLGLSLShader gDeferredDoFCombineProgram;
extern LLGLSLShader gFXAAProgram;
extern LLGLSLShader gDeferredPostNoDoFProgram;
+extern LLGLSLShader gDeferredPostGammaCorrectProgram;
extern LLGLSLShader gDeferredAvatarShadowProgram;
extern LLGLSLShader gDeferredAttachmentShadowProgram;
extern LLGLSLShader gDeferredAlphaProgram;
+extern LLGLSLShader gDeferredAlphaImpostorProgram;
extern LLGLSLShader gDeferredFullbrightProgram;
+extern LLGLSLShader gDeferredFullbrightAlphaMaskProgram;
+extern LLGLSLShader gDeferredAlphaWaterProgram;
+extern LLGLSLShader gDeferredFullbrightWaterProgram;
+extern LLGLSLShader gDeferredFullbrightAlphaMaskWaterProgram;
extern LLGLSLShader gDeferredEmissiveProgram;
extern LLGLSLShader gDeferredAvatarEyesProgram;
extern LLGLSLShader gDeferredAvatarAlphaProgram;
extern LLGLSLShader gDeferredWLSkyProgram;
extern LLGLSLShader gDeferredWLCloudProgram;
extern LLGLSLShader gDeferredStarProgram;
+extern LLGLSLShader gDeferredFullbrightShinyProgram;
+extern LLGLSLShader gDeferredSkinnedFullbrightShinyProgram;
+extern LLGLSLShader gDeferredSkinnedFullbrightProgram;
extern LLGLSLShader gNormalMapGenProgram;
+// Deferred materials shaders
+extern LLGLSLShader gDeferredMaterialProgram[LLMaterial::SHADER_COUNT*2];
+extern LLGLSLShader gDeferredMaterialWaterProgram[LLMaterial::SHADER_COUNT*2];
#endif
diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp
index c88122f22c..35bba4184e 100644..100755
--- a/indra/newview/llviewerstats.cpp
+++ b/indra/newview/llviewerstats.cpp
@@ -233,6 +233,9 @@ LLViewerStats::LLViewerStats() :
mSimSimPhysicsStepMsec("simsimphysicsstepmsec"),
mSimSimPhysicsShapeUpdateMsec("simsimphysicsshapeupdatemsec"),
mSimSimPhysicsOtherMsec("simsimphysicsothermsec"),
+ mSimSimAIStepMsec("simsimaistepmsec"),
+ mSimSimSkippedSilhouetteSteps("simsimskippedsilhouettesteps"),
+ mSimSimPctSteppedCharacters("simsimpctsteppedcharacters"),
mSimAgentMsec("simagentmsec"),
mSimImagesMsec("simimagesmsec"),
mSimScriptMsec("simscriptmsec"),
@@ -244,6 +247,7 @@ LLViewerStats::LLViewerStats() :
mSimObjects("simobjects"),
mSimActiveObjects("simactiveobjects"),
mSimActiveScripts("simactivescripts"),
+ mSimPctScriptsRun("simpctscriptsrun"),
mSimInPPS("siminpps"),
mSimOutPPS("simoutpps"),
mSimPendingDownloads("simpendingdownloads"),
@@ -286,19 +290,19 @@ LLViewerStats::~LLViewerStats()
void LLViewerStats::resetStats()
{
- LLViewerStats::getInstance()->mKBitStat.reset();
- LLViewerStats::getInstance()->mLayersKBitStat.reset();
- LLViewerStats::getInstance()->mObjectKBitStat.reset();
- LLViewerStats::getInstance()->mTextureKBitStat.reset();
- LLViewerStats::getInstance()->mVFSPendingOperations.reset();
- LLViewerStats::getInstance()->mAssetKBitStat.reset();
- LLViewerStats::getInstance()->mPacketsInStat.reset();
- LLViewerStats::getInstance()->mPacketsLostStat.reset();
- LLViewerStats::getInstance()->mPacketsOutStat.reset();
- LLViewerStats::getInstance()->mFPSStat.reset();
- LLViewerStats::getInstance()->mTexturePacketsStat.reset();
-
- LLViewerStats::getInstance()->mAgentPositionSnaps.reset();
+ LLViewerStats& stats = LLViewerStats::instance();
+ stats.mKBitStat.reset();
+ stats.mLayersKBitStat.reset();
+ stats.mObjectKBitStat.reset();
+ stats.mTextureKBitStat.reset();
+ stats.mVFSPendingOperations.reset();
+ stats.mAssetKBitStat.reset();
+ stats.mPacketsInStat.reset();
+ stats.mPacketsLostStat.reset();
+ stats.mPacketsOutStat.reset();
+ stats.mFPSStat.reset();
+ stats.mTexturePacketsStat.reset();
+ stats.mAgentPositionSnaps.reset();
}
@@ -323,55 +327,55 @@ void LLViewerStats::updateFrameStats(const F64 time_diff)
{
if (mPacketsLostPercentStat.getCurrent() > 5.0)
{
- incStat(LLViewerStats::ST_LOSS_05_SECONDS, time_diff);
+ incStat(ST_LOSS_05_SECONDS, time_diff);
}
if (mSimFPS.getCurrent() < 20.f && mSimFPS.getCurrent() > 0.f)
{
- incStat(LLViewerStats::ST_SIM_FPS_20_SECONDS, time_diff);
+ incStat(ST_SIM_FPS_20_SECONDS, time_diff);
}
if (mSimPhysicsFPS.getCurrent() < 20.f && mSimPhysicsFPS.getCurrent() > 0.f)
{
- incStat(LLViewerStats::ST_PHYS_FPS_20_SECONDS, time_diff);
+ incStat(ST_PHYS_FPS_20_SECONDS, time_diff);
}
if (time_diff >= 0.5)
{
- incStat(LLViewerStats::ST_FPS_2_SECONDS, time_diff);
+ incStat(ST_FPS_2_SECONDS, time_diff);
}
if (time_diff >= 0.125)
{
- incStat(LLViewerStats::ST_FPS_8_SECONDS, time_diff);
+ incStat(ST_FPS_8_SECONDS, time_diff);
}
if (time_diff >= 0.1)
{
- incStat(LLViewerStats::ST_FPS_10_SECONDS, time_diff);
+ incStat(ST_FPS_10_SECONDS, time_diff);
}
if (gFrameCount && mLastTimeDiff > 0.0)
{
// new "stutter" meter
- setStat(LLViewerStats::ST_FPS_DROP_50_RATIO,
- (getStat(LLViewerStats::ST_FPS_DROP_50_RATIO) * (F64)(gFrameCount - 1) +
+ setStat(ST_FPS_DROP_50_RATIO,
+ (getStat(ST_FPS_DROP_50_RATIO) * (F64)(gFrameCount - 1) +
(time_diff >= 2.0 * mLastTimeDiff ? 1.0 : 0.0)) / gFrameCount);
// old stats that were never really used
- setStat(LLViewerStats::ST_FRAMETIME_JITTER,
- (getStat(LLViewerStats::ST_FRAMETIME_JITTER) * (gFrameCount - 1) +
+ setStat(ST_FRAMETIME_JITTER,
+ (getStat(ST_FRAMETIME_JITTER) * (gFrameCount - 1) +
fabs(mLastTimeDiff - time_diff) / mLastTimeDiff) / gFrameCount);
F32 average_frametime = gRenderStartTime.getElapsedTimeF32() / (F32)gFrameCount;
- setStat(LLViewerStats::ST_FRAMETIME_SLEW,
- (getStat(LLViewerStats::ST_FRAMETIME_SLEW) * (gFrameCount - 1) +
+ setStat(ST_FRAMETIME_SLEW,
+ (getStat(ST_FRAMETIME_SLEW) * (gFrameCount - 1) +
fabs(average_frametime - time_diff) / average_frametime) / gFrameCount);
F32 max_bandwidth = gViewerThrottle.getMaxBandwidth();
F32 delta_bandwidth = gViewerThrottle.getCurrentBandwidth() - max_bandwidth;
- setStat(LLViewerStats::ST_DELTA_BANDWIDTH, delta_bandwidth / 1024.f);
+ setStat(ST_DELTA_BANDWIDTH, delta_bandwidth / 1024.f);
- setStat(LLViewerStats::ST_MAX_BANDWIDTH, max_bandwidth / 1024.f);
+ setStat(ST_MAX_BANDWIDTH, max_bandwidth / 1024.f);
}
@@ -399,155 +403,8 @@ void LLViewerStats::addToMessage(LLSD &body) const
<< "; Count = " << mAgentPositionSnaps.getCount() << llendl;
}
-// static
-// const std::string LLViewerStats::statTypeToText(EStatType type)
-// {
-// if (type >= 0 && type < ST_COUNT)
-// {
-// return STAT_INFO[type].mName;
-// }
-// else
-// {
-// return "Unknown statistic";
-// }
-// }
-
// *NOTE:Mani The following methods used to exist in viewer.cpp
// Moving them here, but not merging them into LLViewerStats yet.
-void reset_statistics()
-{
- if (LLSurface::sTextureUpdateTime)
- {
- LLSurface::sTexelsUpdated = 0;
- LLSurface::sTextureUpdateTime = 0.f;
- }
-}
-
-
-void output_statistics(void*)
-{
- llinfos << "Number of orphans: " << gObjectList.getOrphanCount() << llendl;
- llinfos << "Number of dead objects: " << gObjectList.mNumDeadObjects << llendl;
- llinfos << "Num images: " << gTextureList.getNumImages() << llendl;
- llinfos << "Texture usage: " << LLImageGL::sGlobalTextureMemoryInBytes << llendl;
- llinfos << "Texture working set: " << LLImageGL::sBoundTextureMemoryInBytes << llendl;
- llinfos << "Raw usage: " << LLImageRaw::sGlobalRawMemory << llendl;
- llinfos << "Formatted usage: " << LLImageFormatted::sGlobalFormattedMemory << llendl;
- llinfos << "Zombie Viewer Objects: " << LLViewerObject::getNumZombieObjects() << llendl;
- llinfos << "Number of lights: " << gPipeline.getLightCount() << llendl;
-
- llinfos << "Memory Usage:" << llendl;
- llinfos << "--------------------------------" << llendl;
- llinfos << "Pipeline:" << llendl;
- llinfos << llendl;
-
-#if LL_SMARTHEAP
- llinfos << "--------------------------------" << llendl;
- {
- llinfos << "sizeof(LLVOVolume) = " << sizeof(LLVOVolume) << llendl;
-
- U32 total_pool_size = 0;
- U32 total_used_size = 0;
- MEM_POOL_INFO pool_info;
- MEM_POOL_STATUS pool_status;
- U32 pool_num = 0;
- for(pool_status = MemPoolFirst( &pool_info, 1 );
- pool_status != MEM_POOL_END;
- pool_status = MemPoolNext( &pool_info, 1 ) )
- {
- llinfos << "Pool #" << pool_num << llendl;
- if( MEM_POOL_OK != pool_status )
- {
- llwarns << "Pool not ok" << llendl;
- continue;
- }
-
- llinfos << "Pool blockSizeFS " << pool_info.blockSizeFS
- << " pageSize " << pool_info.pageSize
- << llendl;
-
- U32 pool_count = MemPoolCount(pool_info.pool);
- llinfos << "Blocks " << pool_count << llendl;
-
- U32 pool_size = MemPoolSize( pool_info.pool );
- if( pool_size == MEM_ERROR_RET )
- {
- llinfos << "MemPoolSize() failed (" << pool_num << ")" << llendl;
- }
- else
- {
- llinfos << "MemPool Size " << pool_size / 1024 << "K" << llendl;
- }
-
- total_pool_size += pool_size;
-
- if( !MemPoolLock( pool_info.pool ) )
- {
- llinfos << "MemPoolLock failed (" << pool_num << ") " << llendl;
- continue;
- }
-
- U32 used_size = 0;
- MEM_POOL_ENTRY entry;
- entry.entry = NULL;
- while( MemPoolWalk( pool_info.pool, &entry ) == MEM_POOL_OK )
- {
- if( entry.isInUse )
- {
- used_size += entry.size;
- }
- }
-
- MemPoolUnlock( pool_info.pool );
-
- llinfos << "MemPool Used " << used_size/1024 << "K" << llendl;
- total_used_size += used_size;
- pool_num++;
- }
-
- llinfos << "Total Pool Size " << total_pool_size/1024 << "K" << llendl;
- llinfos << "Total Used Size " << total_used_size/1024 << "K" << llendl;
-
- }
-#endif
-
- llinfos << "--------------------------------" << llendl;
- llinfos << "Avatar Memory (partly overlaps with above stats):" << llendl;
- LLTexLayerStaticImageList::getInstance()->dumpByteCount();
- LLVOAvatarSelf::dumpScratchTextureByteCount();
- LLTexLayerSetBuffer::dumpTotalByteCount();
- LLVOAvatarSelf::dumpTotalLocalTextureByteCount();
- LLTexLayerParamAlpha::dumpCacheByteCount();
- LLVOAvatar::dumpBakedStatus();
-
- llinfos << llendl;
-
- llinfos << "Object counts:" << llendl;
- S32 i;
- S32 obj_counts[256];
-// S32 app_angles[256];
- for (i = 0; i < 256; i++)
- {
- obj_counts[i] = 0;
- }
- for (i = 0; i < gObjectList.getNumObjects(); i++)
- {
- LLViewerObject *objectp = gObjectList.getObject(i);
- if (objectp)
- {
- obj_counts[objectp->getPCode()]++;
- }
- }
- for (i = 0; i < 256; i++)
- {
- if (obj_counts[i])
- {
- llinfos << LLPrimitive::pCodeToString(i) << ":" << obj_counts[i] << llendl;
- }
- }
-}
-
-
U32 gTotalLandIn = 0, gTotalLandOut = 0;
U32 gTotalWaterIn = 0, gTotalWaterOut = 0;
@@ -565,20 +422,15 @@ U32 gTotalTextureBytesPerBoostLevel[LLViewerTexture::MAX_GL_IMAGE_CATEGORY]
extern U32 gVisCompared;
extern U32 gVisTested;
-std::map<S32,LLFrameTimer> gDebugTimers;
-std::map<S32,std::string> gDebugTimerLabel;
-
-void init_statistics()
-{
- // Label debug timers
- gDebugTimerLabel[0] = "Texture";
-}
+LLFrameTimer gTextureTimer;
-void update_statistics(U32 frame_count)
+void update_statistics()
{
gTotalWorldBytes += gVLManager.getTotalBytes();
gTotalObjectBytes += gObjectBits / 8;
+ LLViewerStats& stats = LLViewerStats::instance();
+
// make sure we have a valid time delta for this frame
if (gFrameIntervalSeconds > 0.f)
{
@@ -595,51 +447,47 @@ void update_statistics(U32 frame_count)
LLViewerStats::getInstance()->incStat(LLViewerStats::ST_TOOLBOX_SECONDS, gFrameIntervalSeconds);
}
}
- LLViewerStats::getInstance()->setStat(LLViewerStats::ST_ENABLE_VBO, (F64)gSavedSettings.getBOOL("RenderVBOEnable"));
- LLViewerStats::getInstance()->setStat(LLViewerStats::ST_LIGHTING_DETAIL, (F64)gPipeline.getLightingDetail());
- LLViewerStats::getInstance()->setStat(LLViewerStats::ST_DRAW_DIST, (F64)gSavedSettings.getF32("RenderFarClip"));
- LLViewerStats::getInstance()->setStat(LLViewerStats::ST_CHAT_BUBBLES, (F64)gSavedSettings.getBOOL("UseChatBubbles"));
-#if 0 // 1.9.2
- LLViewerStats::getInstance()->setStat(LLViewerStats::ST_SHADER_OBJECTS, (F64)gSavedSettings.getS32("VertexShaderLevelObject"));
- LLViewerStats::getInstance()->setStat(LLViewerStats::ST_SHADER_AVATAR, (F64)gSavedSettings.getBOOL("VertexShaderLevelAvatar"));
- LLViewerStats::getInstance()->setStat(LLViewerStats::ST_SHADER_ENVIRONMENT, (F64)gSavedSettings.getBOOL("VertexShaderLevelEnvironment"));
-#endif
- LLViewerStats::getInstance()->setStat(LLViewerStats::ST_FRAME_SECS, gDebugView->mFastTimerView->getTime("Frame"));
+ stats.setStat(LLViewerStats::ST_ENABLE_VBO, (F64)gSavedSettings.getBOOL("RenderVBOEnable"));
+ stats.setStat(LLViewerStats::ST_LIGHTING_DETAIL, (F64)gPipeline.getLightingDetail());
+ stats.setStat(LLViewerStats::ST_DRAW_DIST, (F64)gSavedSettings.getF32("RenderFarClip"));
+ stats.setStat(LLViewerStats::ST_CHAT_BUBBLES, (F64)gSavedSettings.getBOOL("UseChatBubbles"));
+
+ stats.setStat(LLViewerStats::ST_FRAME_SECS, gDebugView->mFastTimerView->getTime("Frame"));
F64 idle_secs = gDebugView->mFastTimerView->getTime("Idle");
F64 network_secs = gDebugView->mFastTimerView->getTime("Network");
- LLViewerStats::getInstance()->setStat(LLViewerStats::ST_UPDATE_SECS, idle_secs - network_secs);
- LLViewerStats::getInstance()->setStat(LLViewerStats::ST_NETWORK_SECS, network_secs);
- LLViewerStats::getInstance()->setStat(LLViewerStats::ST_IMAGE_SECS, gDebugView->mFastTimerView->getTime("Update Images"));
- LLViewerStats::getInstance()->setStat(LLViewerStats::ST_REBUILD_SECS, gDebugView->mFastTimerView->getTime("Sort Draw State"));
- LLViewerStats::getInstance()->setStat(LLViewerStats::ST_RENDER_SECS, gDebugView->mFastTimerView->getTime("Geometry"));
+ stats.setStat(LLViewerStats::ST_UPDATE_SECS, idle_secs - network_secs);
+ stats.setStat(LLViewerStats::ST_NETWORK_SECS, network_secs);
+ stats.setStat(LLViewerStats::ST_IMAGE_SECS, gDebugView->mFastTimerView->getTime("Update Images"));
+ stats.setStat(LLViewerStats::ST_REBUILD_SECS, gDebugView->mFastTimerView->getTime("Sort Draw State"));
+ stats.setStat(LLViewerStats::ST_RENDER_SECS, gDebugView->mFastTimerView->getTime("Geometry"));
LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(gAgent.getRegion()->getHost());
if (cdp)
{
- LLViewerStats::getInstance()->mSimPingStat.addValue(cdp->getPingDelay());
+ stats.mSimPingStat.addValue(cdp->getPingDelay());
gAvgSimPing = ((gAvgSimPing * (F32)gSimPingCount) + (F32)(cdp->getPingDelay())) / ((F32)gSimPingCount + 1);
gSimPingCount++;
}
else
{
- LLViewerStats::getInstance()->mSimPingStat.addValue(10000);
+ stats.mSimPingStat.addValue(10000);
}
- LLViewerStats::getInstance()->mFPSStat.addValue(1);
+ stats.mFPSStat.addValue(1);
F32 layer_bits = (F32)(gVLManager.getLandBits() + gVLManager.getWindBits() + gVLManager.getCloudBits());
- LLViewerStats::getInstance()->mLayersKBitStat.addValue(layer_bits/1024.f);
- LLViewerStats::getInstance()->mObjectKBitStat.addValue(gObjectBits/1024.f);
- LLViewerStats::getInstance()->mVFSPendingOperations.addValue(LLVFile::getVFSThread()->getPending());
- LLViewerStats::getInstance()->mAssetKBitStat.addValue(gTransferManager.getTransferBitsIn(LLTCT_ASSET)/1024.f);
+ stats.mLayersKBitStat.addValue(layer_bits/1024.f);
+ stats.mObjectKBitStat.addValue(gObjectBits/1024.f);
+ stats.mVFSPendingOperations.addValue(LLVFile::getVFSThread()->getPending());
+ stats.mAssetKBitStat.addValue(gTransferManager.getTransferBitsIn(LLTCT_ASSET)/1024.f);
gTransferManager.resetTransferBitsIn(LLTCT_ASSET);
if (LLAppViewer::getTextureFetch()->getNumRequests() == 0)
{
- gDebugTimers[0].pause();
+ gTextureTimer.pause();
}
else
{
- gDebugTimers[0].unpause();
+ gTextureTimer.unpause();
}
{
@@ -651,7 +499,7 @@ void update_statistics(U32 frame_count)
visible_avatar_frames = 1.f;
avg_visible_avatars = (avg_visible_avatars * (F32)(visible_avatar_frames - 1.f) + visible_avatars) / visible_avatar_frames;
}
- LLViewerStats::getInstance()->setStat(LLViewerStats::ST_VISIBLE_AVATARS, (F64)avg_visible_avatars);
+ stats.setStat(LLViewerStats::ST_VISIBLE_AVATARS, (F64)avg_visible_avatars);
}
LLWorld::getInstance()->updateNetStats();
LLWorld::getInstance()->requestCacheMisses();
@@ -667,15 +515,14 @@ void update_statistics(U32 frame_count)
static LLFrameTimer texture_stats_timer;
if (texture_stats_timer.getElapsedTimeF32() >= texture_stats_freq)
{
- LLViewerStats::getInstance()->mTextureKBitStat.addValue(LLViewerTextureList::sTextureBits/1024.f);
- LLViewerStats::getInstance()->mTexturePacketsStat.addValue(LLViewerTextureList::sTexturePackets);
+ stats.mTextureKBitStat.addValue(LLViewerTextureList::sTextureBits/1024.f);
+ stats.mTexturePacketsStat.addValue(LLViewerTextureList::sTexturePackets);
gTotalTextureBytes += LLViewerTextureList::sTextureBits / 8;
LLViewerTextureList::sTextureBits = 0;
LLViewerTextureList::sTexturePackets = 0;
texture_stats_timer.reset();
}
}
-
}
class ViewerStatsResponder : public LLHTTPClient::Responder
@@ -783,12 +630,41 @@ void send_stats()
"%-6s Class %d ",
gGLManager.mGLVendorShort.substr(0,6).c_str(),
(S32)LLFeatureManager::getInstance()->getGPUClass())
- + LLFeatureManager::getInstance()->getGPUString();
+ + gGLManager.getRawGLString();
system["gpu"] = gpu_desc;
system["gpu_class"] = (S32)LLFeatureManager::getInstance()->getGPUClass();
system["gpu_vendor"] = gGLManager.mGLVendorShort;
system["gpu_version"] = gGLManager.mDriverVersionVendorString;
+ system["opengl_version"] = gGLManager.mGLVersionString;
+
+ S32 shader_level = 0;
+ if (LLPipeline::sRenderDeferred)
+ {
+ if (LLPipeline::RenderShadowDetail > 0)
+ {
+ shader_level = 5;
+ }
+ else if (LLPipeline::RenderDeferredSSAO)
+ {
+ shader_level = 4;
+ }
+ else
+ {
+ shader_level = 3;
+ }
+ }
+ else if (gPipeline.canUseWindLightShadersOnObjects())
+ {
+ shader_level = 2;
+ }
+ else if (gPipeline.canUseVertexShaders())
+ {
+ shader_level = 1;
+ }
+
+
+ system["shader_level"] = shader_level;
LLSD &download = body["downloads"];
@@ -835,10 +711,7 @@ void send_stats()
S32 window_height = gViewerWindow->getWindowHeightRaw();
S32 window_size = (window_width * window_height) / 1024;
misc["string_1"] = llformat("%d", window_size);
- if (gDebugTimers.find(0) != gDebugTimers.end() && gFrameTimeSeconds > 0)
- {
- misc["string_2"] = llformat("Texture Time: %.2f, Total Time: %.2f", gDebugTimers[0].getElapsedTimeF32(), gFrameTimeSeconds);
- }
+ misc["string_2"] = llformat("Texture Time: %.2f, Total Time: %.2f", gTextureTimer.getElapsedTimeF32(), gFrameTimeSeconds);
// misc["int_1"] = LLSD::Integer(gSavedSettings.getU32("RenderQualityPerformance")); // Steve: 1.21
// misc["int_2"] = LLSD::Integer(gFrameStalls); // Steve: 1.21
@@ -860,3 +733,112 @@ void send_stats()
LLHTTPClient::post(url, body, new ViewerStatsResponder());
}
+LLFrameTimer& LLViewerStats::PhaseMap::getPhaseTimer(const std::string& phase_name)
+{
+ phase_map_t::iterator iter = mPhaseMap.find(phase_name);
+ if (iter == mPhaseMap.end())
+ {
+ LLFrameTimer timer;
+ mPhaseMap[phase_name] = timer;
+ }
+ LLFrameTimer& timer = mPhaseMap[phase_name];
+ return timer;
+}
+
+void LLViewerStats::PhaseMap::startPhase(const std::string& phase_name)
+{
+ LLFrameTimer& timer = getPhaseTimer(phase_name);
+ lldebugs << "startPhase " << phase_name << llendl;
+ timer.unpause();
+}
+
+void LLViewerStats::PhaseMap::stopAllPhases()
+{
+ for (phase_map_t::iterator iter = mPhaseMap.begin();
+ iter != mPhaseMap.end(); ++iter)
+ {
+ const std::string& phase_name = iter->first;
+ if (iter->second.getStarted())
+ {
+ // Going from started to paused state - record stats.
+ recordPhaseStat(phase_name,iter->second.getElapsedTimeF32());
+ }
+ lldebugs << "stopPhase (all) " << phase_name << llendl;
+ iter->second.pause();
+ }
+}
+
+void LLViewerStats::PhaseMap::clearPhases()
+{
+ lldebugs << "clearPhases" << llendl;
+
+ mPhaseMap.clear();
+}
+
+LLSD LLViewerStats::PhaseMap::dumpPhases()
+{
+ LLSD result;
+ for (phase_map_t::iterator iter = mPhaseMap.begin(); iter != mPhaseMap.end(); ++iter)
+ {
+ const std::string& phase_name = iter->first;
+ result[phase_name]["completed"] = LLSD::Integer(!(iter->second.getStarted()));
+ result[phase_name]["elapsed"] = iter->second.getElapsedTimeF32();
+ }
+ return result;
+}
+
+// static initializer
+//static
+LLViewerStats::phase_stats_t LLViewerStats::PhaseMap::sStats;
+
+LLViewerStats::PhaseMap::PhaseMap()
+{
+}
+
+
+void LLViewerStats::PhaseMap::stopPhase(const std::string& phase_name)
+{
+ phase_map_t::iterator iter = mPhaseMap.find(phase_name);
+ if (iter != mPhaseMap.end())
+ {
+ if (iter->second.getStarted())
+ {
+ // Going from started to stopped state - record stats.
+ iter->second.stop();
+ }
+ }
+}
+// static
+LLViewerStats::StatsAccumulator& LLViewerStats::PhaseMap::getPhaseStats(const std::string& phase_name)
+{
+ phase_stats_t::iterator it = sStats.find(phase_name);
+ if (it == sStats.end())
+ {
+ LLViewerStats::StatsAccumulator new_stats;
+ sStats[phase_name] = new_stats;
+ }
+ return sStats[phase_name];
+}
+
+// static
+void LLViewerStats::PhaseMap::recordPhaseStat(const std::string& phase_name, F32 value)
+{
+ LLViewerStats::StatsAccumulator& stats = getPhaseStats(phase_name);
+ stats.push(value);
+}
+
+
+bool LLViewerStats::PhaseMap::getPhaseValues(const std::string& phase_name, F32& elapsed, bool& completed)
+{
+ phase_map_t::iterator iter = mPhaseMap.find(phase_name);
+ if (iter != mPhaseMap.end())
+ {
+ elapsed = iter->second.getElapsedTimeF32();
+ completed = !iter->second.getStarted();
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
diff --git a/indra/newview/llviewerstats.h b/indra/newview/llviewerstats.h
index f91a1241fe..6b2461be41 100644..100755
--- a/indra/newview/llviewerstats.h
+++ b/indra/newview/llviewerstats.h
@@ -33,87 +33,90 @@
class LLViewerStats : public LLSingleton<LLViewerStats>
{
public:
- LLStat mKBitStat;
- LLStat mLayersKBitStat;
- LLStat mObjectKBitStat;
- LLStat mAssetKBitStat;
- LLStat mTextureKBitStat;
- LLStat mVFSPendingOperations;
- LLStat mObjectsDrawnStat;
- LLStat mObjectsCulledStat;
- LLStat mObjectsTestedStat;
- LLStat mObjectsComparedStat;
- LLStat mObjectsOccludedStat;
- LLStat mFPSStat;
- LLStat mPacketsInStat;
- LLStat mPacketsLostStat;
- LLStat mPacketsOutStat;
- LLStat mPacketsLostPercentStat;
- LLStat mTexturePacketsStat;
- LLStat mActualInKBitStat; // From the packet ring (when faking a bad connection)
- LLStat mActualOutKBitStat; // From the packet ring (when faking a bad connection)
- LLStat mTrianglesDrawnStat;
+ LLStat mKBitStat,
+ mLayersKBitStat,
+ mObjectKBitStat,
+ mAssetKBitStat,
+ mTextureKBitStat,
+ mVFSPendingOperations,
+ mObjectsDrawnStat,
+ mObjectsCulledStat,
+ mObjectsTestedStat,
+ mObjectsComparedStat,
+ mObjectsOccludedStat,
+ mFPSStat,
+ mPacketsInStat,
+ mPacketsLostStat,
+ mPacketsOutStat,
+ mPacketsLostPercentStat,
+ mTexturePacketsStat,
+ mActualInKBitStat, // From the packet ring (when faking a bad connection)
+ mActualOutKBitStat, // From the packet ring (when faking a bad connection)
+ mTrianglesDrawnStat;
// Simulator stats
- LLStat mSimTimeDilation;
-
- LLStat mSimFPS;
- LLStat mSimPhysicsFPS;
- LLStat mSimAgentUPS;
- LLStat mSimScriptEPS;
-
- LLStat mSimFrameMsec;
- LLStat mSimNetMsec;
- LLStat mSimSimOtherMsec;
- LLStat mSimSimPhysicsMsec;
-
- LLStat mSimSimPhysicsStepMsec;
- LLStat mSimSimPhysicsShapeUpdateMsec;
- LLStat mSimSimPhysicsOtherMsec;
-
- LLStat mSimAgentMsec;
- LLStat mSimImagesMsec;
- LLStat mSimScriptMsec;
- LLStat mSimSpareMsec;
- LLStat mSimSleepMsec;
- LLStat mSimPumpIOMsec;
-
- LLStat mSimMainAgents;
- LLStat mSimChildAgents;
- LLStat mSimObjects;
- LLStat mSimActiveObjects;
- LLStat mSimActiveScripts;
-
- LLStat mSimInPPS;
- LLStat mSimOutPPS;
- LLStat mSimPendingDownloads;
- LLStat mSimPendingUploads;
- LLStat mSimPendingLocalUploads;
- LLStat mSimTotalUnackedBytes;
-
- LLStat mPhysicsPinnedTasks;
- LLStat mPhysicsLODTasks;
- LLStat mPhysicsMemoryAllocated;
-
- LLStat mSimPingStat;
-
- LLStat mNumImagesStat;
- LLStat mNumRawImagesStat;
- LLStat mGLTexMemStat;
- LLStat mGLBoundMemStat;
- LLStat mRawMemStat;
- LLStat mFormattedMemStat;
-
- LLStat mNumObjectsStat;
- LLStat mNumActiveObjectsStat;
- LLStat mNumNewObjectsStat;
- LLStat mNumSizeCulledStat;
- LLStat mNumVisCulledStat;
+ LLStat mSimTimeDilation,
+
+ mSimFPS,
+ mSimPhysicsFPS,
+ mSimAgentUPS,
+ mSimScriptEPS,
+
+ mSimFrameMsec,
+ mSimNetMsec,
+ mSimSimOtherMsec,
+ mSimSimPhysicsMsec,
+
+ mSimSimPhysicsStepMsec,
+ mSimSimPhysicsShapeUpdateMsec,
+ mSimSimPhysicsOtherMsec,
+ mSimSimAIStepMsec,
+ mSimSimSkippedSilhouetteSteps,
+ mSimSimPctSteppedCharacters,
+
+ mSimAgentMsec,
+ mSimImagesMsec,
+ mSimScriptMsec,
+ mSimSpareMsec,
+ mSimSleepMsec,
+ mSimPumpIOMsec,
+
+ mSimMainAgents,
+ mSimChildAgents,
+ mSimObjects,
+ mSimActiveObjects,
+ mSimActiveScripts,
+ mSimPctScriptsRun,
+
+ mSimInPPS,
+ mSimOutPPS,
+ mSimPendingDownloads,
+ mSimPendingUploads,
+ mSimPendingLocalUploads,
+ mSimTotalUnackedBytes,
+
+ mPhysicsPinnedTasks,
+ mPhysicsLODTasks,
+ mPhysicsMemoryAllocated,
+
+ mSimPingStat,
+
+ mNumImagesStat,
+ mNumRawImagesStat,
+ mGLTexMemStat,
+ mGLBoundMemStat,
+ mRawMemStat,
+ mFormattedMemStat,
+
+ mNumObjectsStat,
+ mNumActiveObjectsStat,
+ mNumNewObjectsStat,
+ mNumSizeCulledStat,
+ mNumVisCulledStat;
void resetStats();
public:
- // If you change this, please also add a corresponding text label
- // in statTypeToText in llviewerstats.cpp
+ // If you change this, please also add a corresponding text label in llviewerstats.cpp
enum EStatType
{
ST_VERSION = 0,
@@ -178,7 +181,6 @@ public:
ST_COUNT = 58
};
-
LLViewerStats();
~LLViewerStats();
@@ -244,7 +246,7 @@ public:
inline F32 getStdDev() const
{
const F32 mean = getMean();
- return (mCount == 0) ? 0.f : sqrt( mSumOfSquares/mCount - (mean * mean) );
+ return (mCount < 2) ? 0.f : sqrt(llmax(0.f,mSumOfSquares/mCount - (mean * mean)));
}
inline U32 getCount() const
@@ -274,7 +276,32 @@ public:
};
StatsAccumulator mAgentPositionSnaps;
-
+
+ // Phase tracking (originally put in for avatar rezzing), tracking
+ // progress of active/completed phases for activities like outfit changing.
+ typedef std::map<std::string,LLFrameTimer> phase_map_t;
+ typedef std::map<std::string,StatsAccumulator> phase_stats_t;
+ class PhaseMap
+ {
+ private:
+ phase_map_t mPhaseMap;
+ static phase_stats_t sStats;
+ public:
+ PhaseMap();
+ LLFrameTimer& getPhaseTimer(const std::string& phase_name);
+ bool getPhaseValues(const std::string& phase_name, F32& elapsed, bool& completed);
+ void startPhase(const std::string& phase_name);
+ void stopPhase(const std::string& phase_name);
+ void stopAllPhases();
+ void clearPhases();
+ LLSD dumpPhases();
+ static StatsAccumulator& getPhaseStats(const std::string& phase_name);
+ static void recordPhaseStat(const std::string& phase_name, F32 value);
+ phase_map_t::iterator begin() { return mPhaseMap.begin(); }
+ phase_map_t::iterator end() { return mPhaseMap.end(); }
+ };
+
+
private:
F64 mStats[ST_COUNT];
@@ -284,14 +311,10 @@ private:
static const F32 SEND_STATS_PERIOD = 300.0f;
// The following are from (older?) statistics code found in appviewer.
-void init_statistics();
-void reset_statistics();
-void output_statistics(void*);
-void update_statistics(U32 frame_count);
+void update_statistics();
void send_stats();
-extern std::map<S32,LLFrameTimer> gDebugTimers;
-extern std::map<S32,std::string> gDebugTimerLabel;
+extern LLFrameTimer gTextureTimer;
extern U32 gTotalTextureBytes;
extern U32 gTotalObjectBytes;
extern U32 gTotalTextureBytesPerBoostLevel[] ;
diff --git a/indra/newview/llviewerstatsrecorder.cpp b/indra/newview/llviewerstatsrecorder.cpp
index e9d21b4848..2b3e293229 100644..100755
--- a/indra/newview/llviewerstatsrecorder.cpp
+++ b/indra/newview/llviewerstatsrecorder.cpp
@@ -27,7 +27,6 @@
#include "llviewerprecompiledheaders.h"
#include "llviewerstatsrecorder.h"
-#if LL_RECORD_VIEWER_STATS
#include "llfile.h"
#include "llviewerregion.h"
@@ -45,9 +44,8 @@ LLViewerStatsRecorder* LLViewerStatsRecorder::sInstance = NULL;
LLViewerStatsRecorder::LLViewerStatsRecorder() :
mObjectCacheFile(NULL),
mTimer(),
- mRegionp(NULL),
- mStartTime(0.f),
- mProcessingTime(0.f)
+ mStartTime(0.0),
+ mLastSnapshotTime(0.0)
{
if (NULL != sInstance)
{
@@ -61,112 +59,77 @@ LLViewerStatsRecorder::~LLViewerStatsRecorder()
{
if (mObjectCacheFile != NULL)
{
+ // last chance snapshot
+ writeToLog(0.f);
LLFile::close(mObjectCacheFile);
mObjectCacheFile = NULL;
}
}
-// static
-void LLViewerStatsRecorder::initClass()
-{
- sInstance = new LLViewerStatsRecorder();
-}
-
-// static
-void LLViewerStatsRecorder::cleanupClass()
-{
- delete sInstance;
- sInstance = NULL;
-}
-
-
-void LLViewerStatsRecorder::initStatsRecorder(LLViewerRegion *regionp)
-{
- if (mObjectCacheFile == NULL)
- {
- mStartTime = LLTimer::getTotalTime();
- mObjectCacheFile = LLFile::fopen(STATS_FILE_NAME, "wb");
- if (mObjectCacheFile)
- { // Write column headers
- std::ostringstream data_msg;
- data_msg << "EventTime, "
- << "ProcessingTime, "
- << "CacheHits, "
- << "CacheFullMisses, "
- << "CacheCrcMisses, "
- << "FullUpdates, "
- << "TerseUpdates, "
- << "CacheMissRequests, "
- << "CacheMissResponses, "
- << "CacheUpdateDupes, "
- << "CacheUpdateChanges, "
- << "CacheUpdateAdds, "
- << "CacheUpdateReplacements, "
- << "UpdateFailures"
- << "\n";
-
- fwrite(data_msg.str().c_str(), 1, data_msg.str().size(), mObjectCacheFile );
- }
- }
-}
-
-void LLViewerStatsRecorder::beginObjectUpdateEvents(LLViewerRegion *regionp)
-{
- initStatsRecorder(regionp);
- mRegionp = regionp;
- mProcessingTime = LLTimer::getTotalTime();
- clearStats();
-}
-
void LLViewerStatsRecorder::clearStats()
{
mObjectCacheHitCount = 0;
+ mObjectCacheHitSize = 0;
mObjectCacheMissFullCount = 0;
+ mObjectCacheMissFullSize = 0;
mObjectCacheMissCrcCount = 0;
+ mObjectCacheMissCrcSize = 0;
mObjectFullUpdates = 0;
+ mObjectFullUpdatesSize = 0;
mObjectTerseUpdates = 0;
+ mObjectTerseUpdatesSize = 0;
mObjectCacheMissRequests = 0;
mObjectCacheMissResponses = 0;
+ mObjectCacheMissResponsesSize = 0;
mObjectCacheUpdateDupes = 0;
mObjectCacheUpdateChanges = 0;
mObjectCacheUpdateAdds = 0;
mObjectCacheUpdateReplacements = 0;
mObjectUpdateFailures = 0;
+ mObjectUpdateFailuresSize = 0;
+ mTextureFetchSize = 0;
}
-void LLViewerStatsRecorder::recordObjectUpdateFailure(U32 local_id, const EObjectUpdateType update_type)
+void LLViewerStatsRecorder::recordObjectUpdateFailure(U32 local_id, const EObjectUpdateType update_type, S32 msg_size)
{
mObjectUpdateFailures++;
+ mObjectUpdateFailuresSize += msg_size;
}
-void LLViewerStatsRecorder::recordCacheMissEvent(U32 local_id, const EObjectUpdateType update_type, U8 cache_miss_type)
+void LLViewerStatsRecorder::recordCacheMissEvent(U32 local_id, const EObjectUpdateType update_type, U8 cache_miss_type, S32 msg_size)
{
if (LLViewerRegion::CACHE_MISS_TYPE_FULL == cache_miss_type)
{
mObjectCacheMissFullCount++;
+ mObjectCacheMissFullSize += msg_size;
}
else
{
mObjectCacheMissCrcCount++;
+ mObjectCacheMissCrcSize += msg_size;
}
}
-void LLViewerStatsRecorder::recordObjectUpdateEvent(U32 local_id, const EObjectUpdateType update_type, LLViewerObject * objectp)
+void LLViewerStatsRecorder::recordObjectUpdateEvent(U32 local_id, const EObjectUpdateType update_type, LLViewerObject * objectp, S32 msg_size)
{
switch (update_type)
{
case OUT_FULL:
mObjectFullUpdates++;
+ mObjectFullUpdatesSize += msg_size;
break;
case OUT_TERSE_IMPROVED:
mObjectTerseUpdates++;
+ mObjectTerseUpdatesSize += msg_size;
break;
case OUT_FULL_COMPRESSED:
mObjectCacheMissResponses++;
+ mObjectCacheMissResponsesSize += msg_size;
break;
case OUT_FULL_CACHED:
mObjectCacheHitCount++;
+ mObjectCacheHitSize += msg_size;
break;
default:
llwarns << "Unknown update_type" << llendl;
@@ -174,7 +137,7 @@ void LLViewerStatsRecorder::recordObjectUpdateEvent(U32 local_id, const EObjectU
};
}
-void LLViewerStatsRecorder::recordCacheFullUpdate(U32 local_id, const EObjectUpdateType update_type, LLViewerRegion::eCacheUpdateResult update_result, LLViewerObject* objectp)
+void LLViewerStatsRecorder::recordCacheFullUpdate(U32 local_id, const EObjectUpdateType update_type, LLViewerRegion::eCacheUpdateResult update_result, LLViewerObject* objectp, S32 msg_size)
{
switch (update_result)
{
@@ -201,9 +164,16 @@ void LLViewerStatsRecorder::recordRequestCacheMissesEvent(S32 count)
mObjectCacheMissRequests += count;
}
-void LLViewerStatsRecorder::endObjectUpdateEvents()
+void LLViewerStatsRecorder::writeToLog( F32 interval )
{
- llinfos << "ILX: "
+ size_t data_size = 0;
+ F64 delta_time = LLTimer::getTotalSeconds() - mLastSnapshotTime;
+ S32 total_objects = mObjectCacheHitCount + mObjectCacheMissCrcCount + mObjectCacheMissFullCount + mObjectFullUpdates + mObjectTerseUpdates + mObjectCacheMissRequests + mObjectCacheMissResponses + mObjectCacheUpdateDupes + mObjectCacheUpdateChanges + mObjectCacheUpdateAdds + mObjectCacheUpdateReplacements + mObjectUpdateFailures;
+
+ if ( delta_time < interval || total_objects == 0) return;
+
+ mLastSnapshotTime = LLTimer::getTotalSeconds();
+ lldebugs << "ILX: "
<< mObjectCacheHitCount << " hits, "
<< mObjectCacheMissFullCount << " full misses, "
<< mObjectCacheMissCrcCount << " crc misses, "
@@ -218,30 +188,76 @@ void LLViewerStatsRecorder::endObjectUpdateEvents()
<< mObjectUpdateFailures << " update failures"
<< llendl;
- S32 total_objects = mObjectCacheHitCount + mObjectCacheMissCrcCount + mObjectCacheMissFullCount + mObjectFullUpdates + mObjectTerseUpdates + mObjectCacheMissRequests + mObjectCacheMissResponses + mObjectCacheUpdateDupes + mObjectCacheUpdateChanges + mObjectCacheUpdateAdds + mObjectCacheUpdateReplacements + mObjectUpdateFailures;
- if (mObjectCacheFile != NULL &&
- total_objects > 0)
+ if (mObjectCacheFile == NULL)
{
- std::ostringstream data_msg;
- F32 processing32 = (F32) ((LLTimer::getTotalTime() - mProcessingTime) / 1000.0);
+ mStartTime = LLTimer::getTotalSeconds();
+ mObjectCacheFile = LLFile::fopen(STATS_FILE_NAME, "wb");
+ if (mObjectCacheFile)
+ { // Write column headers
+ std::ostringstream data_msg;
+ data_msg << "EventTime(ms)\t"
+ << "Cache Hits\t"
+ << "Cache Full Misses\t"
+ << "Cache Crc Misses\t"
+ << "Full Updates\t"
+ << "Terse Updates\t"
+ << "Cache Miss Requests\t"
+ << "Cache Miss Responses\t"
+ << "Cache Update Dupes\t"
+ << "Cache Update Changes\t"
+ << "Cache Update Adds\t"
+ << "Cache Update Replacements\t"
+ << "Update Failures\t"
+ << "Cache Hits bps\t"
+ << "Cache Full Misses bps\t"
+ << "Cache Crc Misses bps\t"
+ << "Full Updates bps\t"
+ << "Terse Updates bps\t"
+ << "Cache Miss Responses bps\t"
+ << "Texture Fetch bps\t"
+ << "\n";
+
+ data_size = data_msg.str().size();
+ if (fwrite(data_msg.str().c_str(), 1, data_size, mObjectCacheFile ) != data_size)
+ {
+ llwarns << "failed to write full headers to " << STATS_FILE_NAME << llendl;
+ }
+ }
+ else
+ {
+ llwarns << "Couldn't open " << STATS_FILE_NAME << " for logging." << llendl;
+ return;
+ }
+ }
- data_msg << getTimeSinceStart()
- << ", " << processing32
- << ", " << mObjectCacheHitCount
- << ", " << mObjectCacheMissFullCount
- << ", " << mObjectCacheMissCrcCount
- << ", " << mObjectFullUpdates
- << ", " << mObjectTerseUpdates
- << ", " << mObjectCacheMissRequests
- << ", " << mObjectCacheMissResponses
- << ", " << mObjectCacheUpdateDupes
- << ", " << mObjectCacheUpdateChanges
- << ", " << mObjectCacheUpdateAdds
- << ", " << mObjectCacheUpdateReplacements
- << ", " << mObjectUpdateFailures
- << "\n";
+ std::ostringstream data_msg;
- fwrite(data_msg.str().c_str(), 1, data_msg.str().size(), mObjectCacheFile );
+ data_msg << getTimeSinceStart()
+ << "\t " << mObjectCacheHitCount
+ << "\t" << mObjectCacheMissFullCount
+ << "\t" << mObjectCacheMissCrcCount
+ << "\t" << mObjectFullUpdates
+ << "\t" << mObjectTerseUpdates
+ << "\t" << mObjectCacheMissRequests
+ << "\t" << mObjectCacheMissResponses
+ << "\t" << mObjectCacheUpdateDupes
+ << "\t" << mObjectCacheUpdateChanges
+ << "\t" << mObjectCacheUpdateAdds
+ << "\t" << mObjectCacheUpdateReplacements
+ << "\t" << mObjectUpdateFailures
+ << "\t" << (mObjectCacheHitSize * 8 / delta_time)
+ << "\t" << (mObjectCacheMissFullSize * 8 / delta_time)
+ << "\t" << (mObjectCacheMissCrcSize * 8 / delta_time)
+ << "\t" << (mObjectFullUpdatesSize * 8 / delta_time)
+ << "\t" << (mObjectTerseUpdatesSize * 8 / delta_time)
+ << "\t" << (mObjectCacheMissResponsesSize * 8 / delta_time)
+ << "\t" << (mTextureFetchSize * 8 / delta_time)
+ << "\n";
+
+ data_size = data_msg.str().size();
+ if ( data_size != fwrite(data_msg.str().c_str(), 1, data_size, mObjectCacheFile ))
+ {
+ llwarns << "Unable to write complete column data to " << STATS_FILE_NAME << llendl;
}
clearStats();
@@ -249,10 +265,13 @@ void LLViewerStatsRecorder::endObjectUpdateEvents()
F32 LLViewerStatsRecorder::getTimeSinceStart()
{
- return (F32) ((LLTimer::getTotalTime() - mStartTime) / 1000.0);
+ return (F32) (LLTimer::getTotalSeconds() - mStartTime);
}
-#endif
+void LLViewerStatsRecorder::recordTextureFetch( S32 msg_size )
+{
+ mTextureFetchSize += msg_size;
+}
diff --git a/indra/newview/llviewerstatsrecorder.h b/indra/newview/llviewerstatsrecorder.h
index 612ac380f7..d1744f4910 100644..100755
--- a/indra/newview/llviewerstatsrecorder.h
+++ b/indra/newview/llviewerstatsrecorder.h
@@ -35,63 +35,111 @@
#define LL_RECORD_VIEWER_STATS 0
-#if LL_RECORD_VIEWER_STATS
#include "llframetimer.h"
#include "llviewerobject.h"
#include "llviewerregion.h"
class LLMutex;
-class LLViewerRegion;
class LLViewerObject;
-class LLViewerStatsRecorder
+class LLViewerStatsRecorder : public LLSingleton<LLViewerStatsRecorder>
{
public:
+ LOG_CLASS(LLViewerStatsRecorder);
LLViewerStatsRecorder();
~LLViewerStatsRecorder();
- static void initClass();
- static void cleanupClass();
- static LLViewerStatsRecorder* instance() {return sInstance; }
+ void objectUpdateFailure(U32 local_id, const EObjectUpdateType update_type, S32 msg_size)
+ {
+#if LL_RECORD_VIEWER_STATS
+ recordObjectUpdateFailure(local_id, update_type, msg_size);
+#endif
+ }
- void initStatsRecorder(LLViewerRegion *regionp);
+ void cacheMissEvent(U32 local_id, const EObjectUpdateType update_type, U8 cache_miss_type, S32 msg_size)
+ {
+#if LL_RECORD_VIEWER_STATS
+ recordCacheMissEvent(local_id, update_type, cache_miss_type, msg_size);
+#endif
+ }
- void beginObjectUpdateEvents(LLViewerRegion *regionp);
- void recordObjectUpdateFailure(U32 local_id, const EObjectUpdateType update_type);
- void recordCacheMissEvent(U32 local_id, const EObjectUpdateType update_type, U8 cache_miss_type);
- void recordObjectUpdateEvent(U32 local_id, const EObjectUpdateType update_type, LLViewerObject * objectp);
- void recordCacheFullUpdate(U32 local_id, const EObjectUpdateType update_type, LLViewerRegion::eCacheUpdateResult update_result, LLViewerObject* objectp);
- void recordRequestCacheMissesEvent(S32 count);
- void endObjectUpdateEvents();
+ void objectUpdateEvent(U32 local_id, const EObjectUpdateType update_type, LLViewerObject * objectp, S32 msg_size)
+ {
+#if LL_RECORD_VIEWER_STATS
+ recordObjectUpdateEvent(local_id, update_type, objectp, msg_size);
+#endif
+ }
+
+ void cacheFullUpdate(U32 local_id, const EObjectUpdateType update_type, LLViewerRegion::eCacheUpdateResult update_result, LLViewerObject* objectp, S32 msg_size)
+ {
+#if LL_RECORD_VIEWER_STATS
+ recordCacheFullUpdate(local_id, update_type, update_result, objectp, msg_size);
+#endif
+ }
+
+ void requestCacheMissesEvent(S32 count)
+ {
+#if LL_RECORD_VIEWER_STATS
+ recordRequestCacheMissesEvent(count);
+#endif
+ }
+
+ void textureFetch(S32 msg_size)
+ {
+#if LL_RECORD_VIEWER_STATS
+ recordTextureFetch(msg_size);
+#endif
+ }
+
+ void log(F32 interval)
+ {
+#if LL_RECORD_VIEWER_STATS
+ writeToLog(interval);
+#endif
+ }
F32 getTimeSinceStart();
private:
+ void recordObjectUpdateFailure(U32 local_id, const EObjectUpdateType update_type, S32 msg_size);
+ void recordCacheMissEvent(U32 local_id, const EObjectUpdateType update_type, U8 cache_miss_type, S32 msg_size);
+ void recordObjectUpdateEvent(U32 local_id, const EObjectUpdateType update_type, LLViewerObject * objectp, S32 msg_size);
+ void recordCacheFullUpdate(U32 local_id, const EObjectUpdateType update_type, LLViewerRegion::eCacheUpdateResult update_result, LLViewerObject* objectp, S32 msg_size);
+ void recordRequestCacheMissesEvent(S32 count);
+ void recordTextureFetch(S32 msg_size);
+ void writeToLog(F32 interval);
+
static LLViewerStatsRecorder* sInstance;
LLFILE * mObjectCacheFile; // File to write data into
LLFrameTimer mTimer;
- LLViewerRegion* mRegionp;
F64 mStartTime;
- F64 mProcessingTime;
+ F64 mLastSnapshotTime;
S32 mObjectCacheHitCount;
+ S32 mObjectCacheHitSize;
S32 mObjectCacheMissFullCount;
+ S32 mObjectCacheMissFullSize;
S32 mObjectCacheMissCrcCount;
+ S32 mObjectCacheMissCrcSize;
S32 mObjectFullUpdates;
+ S32 mObjectFullUpdatesSize;
S32 mObjectTerseUpdates;
+ S32 mObjectTerseUpdatesSize;
S32 mObjectCacheMissRequests;
S32 mObjectCacheMissResponses;
+ S32 mObjectCacheMissResponsesSize;
S32 mObjectCacheUpdateDupes;
S32 mObjectCacheUpdateChanges;
S32 mObjectCacheUpdateAdds;
S32 mObjectCacheUpdateReplacements;
S32 mObjectUpdateFailures;
+ S32 mObjectUpdateFailuresSize;
+ S32 mTextureFetchSize;
void clearStats();
};
-#endif // LL_RECORD_VIEWER_STATS
#endif // LLVIEWERSTATSRECORDER_H
diff --git a/indra/newview/llviewertexlayer.cpp b/indra/newview/llviewertexlayer.cpp
new file mode 100755
index 0000000000..777e1f9c76
--- /dev/null
+++ b/indra/newview/llviewertexlayer.cpp
@@ -0,0 +1,748 @@
+/**
+ * @file llviewertexlayer.cpp
+ * @brief Viewer texture layer. Used for avatars.
+ *
+ * $LicenseInfo:firstyear=2012&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 "llviewerprecompiledheaders.h"
+
+#include "llviewertexlayer.h"
+
+#include "llagent.h"
+#include "llimagej2c.h"
+#include "llnotificationsutil.h"
+#include "llvfile.h"
+#include "llvfs.h"
+#include "llviewerregion.h"
+#include "llglslshader.h"
+#include "llvoavatarself.h"
+#include "pipeline.h"
+#include "llassetuploadresponders.h"
+#include "llviewercontrol.h"
+
+static const S32 BAKE_UPLOAD_ATTEMPTS = 7;
+static const F32 BAKE_UPLOAD_RETRY_DELAY = 2.f; // actual delay grows by power of 2 each attempt
+
+// runway consolidate
+extern std::string self_av_string();
+
+
+//-----------------------------------------------------------------------------
+// LLBakedUploadData()
+//-----------------------------------------------------------------------------
+LLBakedUploadData::LLBakedUploadData(const LLVOAvatarSelf* avatar,
+ LLViewerTexLayerSet* layerset,
+ const LLUUID& id,
+ bool highest_res) :
+ mAvatar(avatar),
+ mTexLayerSet(layerset),
+ mID(id),
+ mStartTime(LLFrameTimer::getTotalTime()), // Record starting time
+ mIsHighestRes(highest_res)
+{
+}
+
+//-----------------------------------------------------------------------------
+// LLViewerTexLayerSetBuffer
+// The composite image that a LLViewerTexLayerSet writes to. Each LLViewerTexLayerSet has one.
+//-----------------------------------------------------------------------------
+
+// static
+S32 LLViewerTexLayerSetBuffer::sGLByteCount = 0;
+
+LLViewerTexLayerSetBuffer::LLViewerTexLayerSetBuffer(LLTexLayerSet* const owner,
+ S32 width, S32 height) :
+ // ORDER_LAST => must render these after the hints are created.
+ LLTexLayerSetBuffer(owner),
+ LLViewerDynamicTexture( width, height, 4, LLViewerDynamicTexture::ORDER_LAST, TRUE ),
+ mUploadPending(FALSE), // Not used for any logic here, just to sync sending of updates
+ mNeedsUpload(FALSE),
+ mNumLowresUploads(0),
+ mUploadFailCount(0),
+ mNeedsUpdate(TRUE),
+ mNumLowresUpdates(0)
+{
+ LLViewerTexLayerSetBuffer::sGLByteCount += getSize();
+ mNeedsUploadTimer.start();
+ mNeedsUpdateTimer.start();
+}
+
+LLViewerTexLayerSetBuffer::~LLViewerTexLayerSetBuffer()
+{
+ LLViewerTexLayerSetBuffer::sGLByteCount -= getSize();
+ destroyGLTexture();
+ for( S32 order = 0; order < ORDER_COUNT; order++ )
+ {
+ LLViewerDynamicTexture::sInstances[order].erase(this); // will fail in all but one case.
+ }
+}
+
+//virtual
+S8 LLViewerTexLayerSetBuffer::getType() const
+{
+ return LLViewerDynamicTexture::LL_TEX_LAYER_SET_BUFFER ;
+}
+
+//virtual
+void LLViewerTexLayerSetBuffer::restoreGLTexture()
+{
+ LLViewerDynamicTexture::restoreGLTexture() ;
+}
+
+//virtual
+void LLViewerTexLayerSetBuffer::destroyGLTexture()
+{
+ LLViewerDynamicTexture::destroyGLTexture() ;
+}
+
+// static
+void LLViewerTexLayerSetBuffer::dumpTotalByteCount()
+{
+ llinfos << "Composite System GL Buffers: " << (LLViewerTexLayerSetBuffer::sGLByteCount/1024) << "KB" << llendl;
+}
+
+void LLViewerTexLayerSetBuffer::requestUpdate()
+{
+ restartUpdateTimer();
+ mNeedsUpdate = TRUE;
+ mNumLowresUpdates = 0;
+ // If we're in the middle of uploading a baked texture, we don't care about it any more.
+ // When it's downloaded, ignore it.
+ mUploadID.setNull();
+}
+
+void LLViewerTexLayerSetBuffer::requestUpload()
+{
+ conditionalRestartUploadTimer();
+ mNeedsUpload = TRUE;
+ mNumLowresUploads = 0;
+ mUploadPending = TRUE;
+}
+
+void LLViewerTexLayerSetBuffer::conditionalRestartUploadTimer()
+{
+ // If we requested a new upload but haven't even uploaded
+ // a low res version of our last upload request, then
+ // keep the timer ticking instead of resetting it.
+ if (mNeedsUpload && (mNumLowresUploads == 0))
+ {
+ mNeedsUploadTimer.unpause();
+ }
+ else
+ {
+ mNeedsUploadTimer.reset();
+ mNeedsUploadTimer.start();
+ }
+}
+
+void LLViewerTexLayerSetBuffer::restartUpdateTimer()
+{
+ mNeedsUpdateTimer.reset();
+ mNeedsUpdateTimer.start();
+}
+
+void LLViewerTexLayerSetBuffer::cancelUpload()
+{
+ mNeedsUpload = FALSE;
+ mUploadPending = FALSE;
+ mNeedsUploadTimer.pause();
+ mUploadRetryTimer.reset();
+}
+
+// virtual
+BOOL LLViewerTexLayerSetBuffer::needsRender()
+{
+ llassert(mTexLayerSet->getAvatarAppearance() == gAgentAvatarp);
+ if (!isAgentAvatarValid()) return FALSE;
+
+ const BOOL upload_now = mNeedsUpload && isReadyToUpload();
+ const BOOL update_now = mNeedsUpdate && isReadyToUpdate();
+
+ // Don't render if we don't want to (or aren't ready to) upload or update.
+ if (!(update_now || upload_now))
+ {
+ return FALSE;
+ }
+
+ // Don't render if we're animating our appearance.
+ if (gAgentAvatarp->getIsAppearanceAnimating())
+ {
+ return FALSE;
+ }
+
+ // Don't render if we are trying to create a shirt texture but aren't wearing a skirt.
+ if (gAgentAvatarp->getBakedTE(getViewerTexLayerSet()) == LLAvatarAppearanceDefines::TEX_SKIRT_BAKED &&
+ !gAgentAvatarp->isWearingWearableType(LLWearableType::WT_SKIRT))
+ {
+ cancelUpload();
+ return FALSE;
+ }
+
+ // Render if we have at least minimal level of detail for each local texture.
+ return getViewerTexLayerSet()->isLocalTextureDataAvailable();
+}
+
+// virtual
+void LLViewerTexLayerSetBuffer::preRenderTexLayerSet()
+{
+ LLTexLayerSetBuffer::preRenderTexLayerSet();
+
+ // keep depth buffer, we don't need to clear it
+ LLViewerDynamicTexture::preRender(FALSE);
+}
+
+// virtual
+void LLViewerTexLayerSetBuffer::postRenderTexLayerSet(BOOL success)
+{
+
+ LLTexLayerSetBuffer::postRenderTexLayerSet(success);
+ LLViewerDynamicTexture::postRender(success);
+}
+
+// virtual
+void LLViewerTexLayerSetBuffer::midRenderTexLayerSet(BOOL success)
+{
+ // do we need to upload, and do we have sufficient data to create an uploadable composite?
+ // TODO: When do we upload the texture if gAgent.mNumPendingQueries is non-zero?
+ const BOOL upload_now = mNeedsUpload && isReadyToUpload();
+ const BOOL update_now = mNeedsUpdate && isReadyToUpdate();
+
+ if(upload_now)
+ {
+ if (!success)
+ {
+ llinfos << "Failed attempt to bake " << mTexLayerSet->getBodyRegionName() << llendl;
+ mUploadPending = FALSE;
+ }
+ else
+ {
+ LLViewerTexLayerSet* layer_set = getViewerTexLayerSet();
+ if (layer_set->isVisible())
+ {
+ layer_set->getAvatar()->debugBakedTextureUpload(layer_set->getBakedTexIndex(), FALSE); // FALSE for start of upload, TRUE for finish.
+ doUpload();
+ }
+ else
+ {
+ mUploadPending = FALSE;
+ mNeedsUpload = FALSE;
+ mNeedsUploadTimer.pause();
+ layer_set->getAvatar()->setNewBakedTexture(layer_set->getBakedTexIndex(),IMG_INVISIBLE);
+ }
+ }
+ }
+
+ if (update_now)
+ {
+ doUpdate();
+ }
+
+ // *TODO: Old logic does not check success before setGLTextureCreated
+ // we have valid texture data now
+ mGLTexturep->setGLTextureCreated(true);
+}
+
+BOOL LLViewerTexLayerSetBuffer::isInitialized(void) const
+{
+ return mGLTexturep.notNull() && mGLTexturep->isGLTextureCreated();
+}
+
+BOOL LLViewerTexLayerSetBuffer::uploadPending() const
+{
+ return mUploadPending;
+}
+
+BOOL LLViewerTexLayerSetBuffer::uploadNeeded() const
+{
+ return mNeedsUpload;
+}
+
+BOOL LLViewerTexLayerSetBuffer::uploadInProgress() const
+{
+ return !mUploadID.isNull();
+}
+
+BOOL LLViewerTexLayerSetBuffer::isReadyToUpload() const
+{
+ if (!gAgentQueryManager.hasNoPendingQueries()) return FALSE; // Can't upload if there are pending queries.
+ if (isAgentAvatarValid() && gAgentAvatarp->isEditingAppearance()) return FALSE; // Don't upload if avatar is being edited.
+
+ BOOL ready = FALSE;
+ if (getViewerTexLayerSet()->isLocalTextureDataFinal())
+ {
+ // If we requested an upload and have the final LOD ready, upload (or wait a while if this is a retry)
+ if (mUploadFailCount == 0)
+ {
+ ready = TRUE;
+ }
+ else
+ {
+ ready = mUploadRetryTimer.getElapsedTimeF32() >= BAKE_UPLOAD_RETRY_DELAY * (1 << (mUploadFailCount - 1));
+ }
+ }
+ else
+ {
+ // Upload if we've hit a timeout. Upload is a pretty expensive process so we need to make sure
+ // we aren't doing uploads too frequently.
+ const U32 texture_timeout = gSavedSettings.getU32("AvatarBakedTextureUploadTimeout");
+ if (texture_timeout != 0)
+ {
+ // The timeout period increases exponentially between every lowres upload in order to prevent
+ // spamming the server with frequent uploads.
+ const U32 texture_timeout_threshold = texture_timeout*(1 << mNumLowresUploads);
+
+ // If we hit our timeout and have textures available at even lower resolution, then upload.
+ const BOOL is_upload_textures_timeout = mNeedsUploadTimer.getElapsedTimeF32() >= texture_timeout_threshold;
+ const BOOL has_lower_lod = getViewerTexLayerSet()->isLocalTextureDataAvailable();
+ ready = has_lower_lod && is_upload_textures_timeout;
+ }
+ }
+
+ return ready;
+}
+
+BOOL LLViewerTexLayerSetBuffer::isReadyToUpdate() const
+{
+ // If we requested an update and have the final LOD ready, then update.
+ if (getViewerTexLayerSet()->isLocalTextureDataFinal()) return TRUE;
+
+ // If we haven't done an update yet, then just do one now regardless of state of textures.
+ if (mNumLowresUpdates == 0) return TRUE;
+
+ // Update if we've hit a timeout. Unlike for uploads, we can make this timeout fairly small
+ // since render unnecessarily doesn't cost much.
+ const U32 texture_timeout = gSavedSettings.getU32("AvatarBakedLocalTextureUpdateTimeout");
+ if (texture_timeout != 0)
+ {
+ // If we hit our timeout and have textures available at even lower resolution, then update.
+ const BOOL is_update_textures_timeout = mNeedsUpdateTimer.getElapsedTimeF32() >= texture_timeout;
+ const BOOL has_lower_lod = getViewerTexLayerSet()->isLocalTextureDataAvailable();
+ if (has_lower_lod && is_update_textures_timeout) return TRUE;
+ }
+
+ return FALSE;
+}
+
+BOOL LLViewerTexLayerSetBuffer::requestUpdateImmediate()
+{
+ mNeedsUpdate = TRUE;
+ BOOL result = FALSE;
+
+ if (needsRender())
+ {
+ preRender(FALSE);
+ result = render();
+ postRender(result);
+ }
+
+ return result;
+}
+
+// Create the baked texture, send it out to the server, then wait for it to come
+// back so we can switch to using it.
+void LLViewerTexLayerSetBuffer::doUpload()
+{
+ LLViewerTexLayerSet* layer_set = getViewerTexLayerSet();
+ LL_DEBUGS("Avatar") << "Uploading baked " << layer_set->getBodyRegionName() << llendl;
+ LLViewerStats::getInstance()->incStat(LLViewerStats::ST_TEX_BAKES);
+
+ // Don't need caches since we're baked now. (note: we won't *really* be baked
+ // until this image is sent to the server and the Avatar Appearance message is received.)
+ layer_set->deleteCaches();
+
+ // Get the COLOR information from our texture
+ U8* baked_color_data = new U8[ mFullWidth * mFullHeight * 4 ];
+ glReadPixels(mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight, GL_RGBA, GL_UNSIGNED_BYTE, baked_color_data );
+ stop_glerror();
+
+ // Get the MASK information from our texture
+ LLGLSUIDefault gls_ui;
+ LLPointer<LLImageRaw> baked_mask_image = new LLImageRaw(mFullWidth, mFullHeight, 1 );
+ U8* baked_mask_data = baked_mask_image->getData();
+ layer_set->gatherMorphMaskAlpha(baked_mask_data,
+ mOrigin.mX, mOrigin.mY,
+ mFullWidth, mFullHeight);
+
+
+ // Create the baked image from our color and mask information
+ const S32 baked_image_components = 5; // red green blue [bump] clothing
+ LLPointer<LLImageRaw> baked_image = new LLImageRaw( mFullWidth, mFullHeight, baked_image_components );
+ U8* baked_image_data = baked_image->getData();
+ S32 i = 0;
+ for (S32 u=0; u < mFullWidth; u++)
+ {
+ for (S32 v=0; v < mFullHeight; v++)
+ {
+ baked_image_data[5*i + 0] = baked_color_data[4*i + 0];
+ baked_image_data[5*i + 1] = baked_color_data[4*i + 1];
+ baked_image_data[5*i + 2] = baked_color_data[4*i + 2];
+ baked_image_data[5*i + 3] = baked_color_data[4*i + 3]; // alpha should be correct for eyelashes.
+ baked_image_data[5*i + 4] = baked_mask_data[i];
+ i++;
+ }
+ }
+
+ LLPointer<LLImageJ2C> compressedImage = new LLImageJ2C;
+ const char* comment_text = LINDEN_J2C_COMMENT_PREFIX "RGBHM"; // writes into baked_color_data. 5 channels (rgb, heightfield/alpha, mask)
+ if (compressedImage->encode(baked_image, comment_text))
+ {
+ LLTransactionID tid;
+ tid.generate();
+ const LLAssetID asset_id = tid.makeAssetID(gAgent.getSecureSessionID());
+ if (LLVFile::writeFile(compressedImage->getData(), compressedImage->getDataSize(),
+ gVFS, asset_id, LLAssetType::AT_TEXTURE))
+ {
+ // Read back the file and validate.
+ BOOL valid = FALSE;
+ LLPointer<LLImageJ2C> integrity_test = new LLImageJ2C;
+ S32 file_size = 0;
+ LLVFile file(gVFS, asset_id, LLAssetType::AT_TEXTURE);
+ file_size = file.getSize();
+ U8* data = integrity_test->allocateData(file_size);
+ file.read(data, file_size);
+ if (data)
+ {
+ valid = integrity_test->validate(data, file_size); // integrity_test will delete 'data'
+ }
+ else
+ {
+ integrity_test->setLastError("Unable to read entire file");
+ }
+
+ if (valid)
+ {
+ const bool highest_lod = layer_set->isLocalTextureDataFinal();
+ // Baked_upload_data is owned by the responder and deleted after the request completes.
+ LLBakedUploadData* baked_upload_data = new LLBakedUploadData(gAgentAvatarp,
+ layer_set,
+ asset_id,
+ highest_lod);
+ // upload ID is used to avoid overlaps, e.g. when the user rapidly makes two changes outside of Face Edit.
+ mUploadID = asset_id;
+
+ // Upload the image
+ const std::string url = gAgent.getRegion()->getCapability("UploadBakedTexture");
+ if(!url.empty()
+ && !LLPipeline::sForceOldBakedUpload // toggle debug setting UploadBakedTexOld to change between the new caps method and old method
+ && (mUploadFailCount < (BAKE_UPLOAD_ATTEMPTS - 1))) // Try last ditch attempt via asset store if cap upload is failing.
+ {
+ LLSD body = LLSD::emptyMap();
+ // The responder will call LLViewerTexLayerSetBuffer::onTextureUploadComplete()
+ LLHTTPClient::post(url, body, new LLSendTexLayerResponder(body, mUploadID, LLAssetType::AT_TEXTURE, baked_upload_data));
+ llinfos << "Baked texture upload via capability of " << mUploadID << " to " << url << llendl;
+ }
+ else
+ {
+ gAssetStorage->storeAssetData(tid,
+ LLAssetType::AT_TEXTURE,
+ LLViewerTexLayerSetBuffer::onTextureUploadComplete,
+ baked_upload_data,
+ TRUE, // temp_file
+ TRUE, // is_priority
+ TRUE); // store_local
+ llinfos << "Baked texture upload via Asset Store." << llendl;
+ }
+
+ if (highest_lod)
+ {
+ // Sending the final LOD for the baked texture. All done, pause
+ // the upload timer so we know how long it took.
+ mNeedsUpload = FALSE;
+ mNeedsUploadTimer.pause();
+ }
+ else
+ {
+ // Sending a lower level LOD for the baked texture. Restart the upload timer.
+ mNumLowresUploads++;
+ mNeedsUploadTimer.unpause();
+ mNeedsUploadTimer.reset();
+ }
+
+ // Print out notification that we uploaded this texture.
+ if (gSavedSettings.getBOOL("DebugAvatarRezTime"))
+ {
+ const std::string lod_str = highest_lod ? "HighRes" : "LowRes";
+ LLSD args;
+ args["EXISTENCE"] = llformat("%d",(U32)layer_set->getAvatar()->debugGetExistenceTimeElapsedF32());
+ args["TIME"] = llformat("%d",(U32)mNeedsUploadTimer.getElapsedTimeF32());
+ args["BODYREGION"] = layer_set->getBodyRegionName();
+ args["RESOLUTION"] = lod_str;
+ LLNotificationsUtil::add("AvatarRezSelfBakedTextureUploadNotification",args);
+ LL_DEBUGS("Avatar") << self_av_string() << "Uploading [ name: " << layer_set->getBodyRegionName() << " res:" << lod_str << " time:" << (U32)mNeedsUploadTimer.getElapsedTimeF32() << " ]" << LL_ENDL;
+ }
+ }
+ else
+ {
+ // The read back and validate operation failed. Remove the uploaded file.
+ mUploadPending = FALSE;
+ LLVFile file(gVFS, asset_id, LLAssetType::AT_TEXTURE, LLVFile::WRITE);
+ file.remove();
+ llinfos << "Unable to create baked upload file (reason: corrupted)." << llendl;
+ }
+ }
+ }
+ else
+ {
+ // The VFS write file operation failed.
+ mUploadPending = FALSE;
+ llinfos << "Unable to create baked upload file (reason: failed to write file)" << llendl;
+ }
+
+ delete [] baked_color_data;
+}
+
+// Mostly bookkeeping; don't need to actually "do" anything since
+// render() will actually do the update.
+void LLViewerTexLayerSetBuffer::doUpdate()
+{
+ LLViewerTexLayerSet* layer_set = getViewerTexLayerSet();
+ const BOOL highest_lod = layer_set->isLocalTextureDataFinal();
+ if (highest_lod)
+ {
+ mNeedsUpdate = FALSE;
+ }
+ else
+ {
+ mNumLowresUpdates++;
+ }
+
+ restartUpdateTimer();
+
+ // need to switch to using this layerset if this is the first update
+ // after getting the lowest LOD
+ layer_set->getAvatar()->updateMeshTextures();
+
+ // Print out notification that we updated this texture.
+ if (gSavedSettings.getBOOL("DebugAvatarRezTime"))
+ {
+ const BOOL highest_lod = layer_set->isLocalTextureDataFinal();
+ const std::string lod_str = highest_lod ? "HighRes" : "LowRes";
+ LLSD args;
+ args["EXISTENCE"] = llformat("%d",(U32)layer_set->getAvatar()->debugGetExistenceTimeElapsedF32());
+ args["TIME"] = llformat("%d",(U32)mNeedsUpdateTimer.getElapsedTimeF32());
+ args["BODYREGION"] = layer_set->getBodyRegionName();
+ args["RESOLUTION"] = lod_str;
+ LLNotificationsUtil::add("AvatarRezSelfBakedTextureUpdateNotification",args);
+ LL_DEBUGS("Avatar") << self_av_string() << "Locally updating [ name: " << layer_set->getBodyRegionName() << " res:" << lod_str << " time:" << (U32)mNeedsUpdateTimer.getElapsedTimeF32() << " ]" << LL_ENDL;
+ }
+}
+
+// static
+void LLViewerTexLayerSetBuffer::onTextureUploadComplete(const LLUUID& uuid,
+ void* userdata,
+ S32 result,
+ LLExtStat ext_status) // StoreAssetData callback (not fixed)
+{
+ LLBakedUploadData* baked_upload_data = (LLBakedUploadData*)userdata;
+
+ if (isAgentAvatarValid() &&
+ !gAgentAvatarp->isDead() &&
+ (baked_upload_data->mAvatar == gAgentAvatarp) && // Sanity check: only the user's avatar should be uploading textures.
+ (baked_upload_data->mTexLayerSet->hasComposite()))
+ {
+ LLViewerTexLayerSetBuffer* layerset_buffer = baked_upload_data->mTexLayerSet->getViewerComposite();
+ S32 failures = layerset_buffer->mUploadFailCount;
+ layerset_buffer->mUploadFailCount = 0;
+
+ if (layerset_buffer->mUploadID.isNull())
+ {
+ // The upload got canceled, we should be in the
+ // process of baking a new texture so request an
+ // upload with the new data
+
+ // BAP: does this really belong in this callback, as
+ // opposed to where the cancellation takes place?
+ // suspect this does nothing.
+ layerset_buffer->requestUpload();
+ }
+ else if (baked_upload_data->mID == layerset_buffer->mUploadID)
+ {
+ // This is the upload we're currently waiting for.
+ layerset_buffer->mUploadID.setNull();
+ const std::string name(baked_upload_data->mTexLayerSet->getBodyRegionName());
+ const std::string resolution = baked_upload_data->mIsHighestRes ? " full res " : " low res ";
+ if (result >= 0)
+ {
+ layerset_buffer->mUploadPending = FALSE; // Allows sending of AgentSetAppearance later
+ LLAvatarAppearanceDefines::ETextureIndex baked_te = gAgentAvatarp->getBakedTE(layerset_buffer->getViewerTexLayerSet());
+ // Update baked texture info with the new UUID
+ U64 now = LLFrameTimer::getTotalTime(); // Record starting time
+ llinfos << "Baked" << resolution << "texture upload for " << name << " took " << (S32)((now - baked_upload_data->mStartTime) / 1000) << " ms" << llendl;
+ gAgentAvatarp->setNewBakedTexture(baked_te, uuid);
+ }
+ else
+ {
+ ++failures;
+ S32 max_attempts = baked_upload_data->mIsHighestRes ? BAKE_UPLOAD_ATTEMPTS : 1; // only retry final bakes
+ llwarns << "Baked" << resolution << "texture upload for " << name << " failed (attempt " << failures << "/" << max_attempts << ")" << llendl;
+ if (failures < max_attempts)
+ {
+ layerset_buffer->mUploadFailCount = failures;
+ layerset_buffer->mUploadRetryTimer.start();
+ layerset_buffer->requestUpload();
+ }
+ }
+ }
+ else
+ {
+ llinfos << "Received baked texture out of date, ignored." << llendl;
+ }
+
+ gAgentAvatarp->dirtyMesh();
+ }
+ else
+ {
+ // Baked texture failed to upload (in which case since we
+ // didn't set the new baked texture, it means that they'll try
+ // and rebake it at some point in the future (after login?)),
+ // or this response to upload is out of date, in which case a
+ // current response should be on the way or already processed.
+ llwarns << "Baked upload failed" << llendl;
+ }
+
+ delete baked_upload_data;
+}
+
+//-----------------------------------------------------------------------------
+// LLViewerTexLayerSet
+// An ordered set of texture layers that get composited into a single texture.
+//-----------------------------------------------------------------------------
+
+LLViewerTexLayerSet::LLViewerTexLayerSet(LLAvatarAppearance* const appearance) :
+ LLTexLayerSet(appearance),
+ mUpdatesEnabled( FALSE )
+{
+}
+
+// virtual
+LLViewerTexLayerSet::~LLViewerTexLayerSet()
+{
+}
+
+// Returns TRUE if at least one packet of data has been received for each of the textures that this layerset depends on.
+BOOL LLViewerTexLayerSet::isLocalTextureDataAvailable() const
+{
+ if (!mAvatarAppearance->isSelf()) return FALSE;
+ return getAvatar()->isLocalTextureDataAvailable(this);
+}
+
+
+// Returns TRUE if all of the data for the textures that this layerset depends on have arrived.
+BOOL LLViewerTexLayerSet::isLocalTextureDataFinal() const
+{
+ if (!mAvatarAppearance->isSelf()) return FALSE;
+ return getAvatar()->isLocalTextureDataFinal(this);
+}
+
+// virtual
+void LLViewerTexLayerSet::requestUpdate()
+{
+ if( mUpdatesEnabled )
+ {
+ createComposite();
+ getViewerComposite()->requestUpdate();
+ }
+}
+
+void LLViewerTexLayerSet::requestUpload()
+{
+ createComposite();
+ getViewerComposite()->requestUpload();
+}
+
+void LLViewerTexLayerSet::cancelUpload()
+{
+ if(mComposite)
+ {
+ getViewerComposite()->cancelUpload();
+ }
+}
+
+void LLViewerTexLayerSet::updateComposite()
+{
+ createComposite();
+ getViewerComposite()->requestUpdateImmediate();
+}
+
+// virtual
+void LLViewerTexLayerSet::createComposite()
+{
+ if(!mComposite)
+ {
+ S32 width = mInfo->getWidth();
+ S32 height = mInfo->getHeight();
+ // Composite other avatars at reduced resolution
+ if( !mAvatarAppearance->isSelf() )
+ {
+ llerrs << "composites should not be created for non-self avatars!" << llendl;
+ }
+ mComposite = new LLViewerTexLayerSetBuffer( this, width, height );
+ }
+}
+
+void LLViewerTexLayerSet::setUpdatesEnabled( BOOL b )
+{
+ mUpdatesEnabled = b;
+}
+
+LLVOAvatarSelf* LLViewerTexLayerSet::getAvatar()
+{
+ return dynamic_cast<LLVOAvatarSelf*> (mAvatarAppearance);
+}
+
+const LLVOAvatarSelf* LLViewerTexLayerSet::getAvatar() const
+{
+ return dynamic_cast<const LLVOAvatarSelf*> (mAvatarAppearance);
+}
+
+LLViewerTexLayerSetBuffer* LLViewerTexLayerSet::getViewerComposite()
+{
+ return dynamic_cast<LLViewerTexLayerSetBuffer*> (getComposite());
+}
+
+const LLViewerTexLayerSetBuffer* LLViewerTexLayerSet::getViewerComposite() const
+{
+ return dynamic_cast<const LLViewerTexLayerSetBuffer*> (getComposite());
+}
+
+
+const std::string LLViewerTexLayerSetBuffer::dumpTextureInfo() const
+{
+ if (!isAgentAvatarValid()) return "";
+
+ const BOOL is_high_res = !mNeedsUpload;
+ const U32 num_low_res = mNumLowresUploads;
+ const U32 upload_time = (U32)mNeedsUploadTimer.getElapsedTimeF32();
+ const std::string local_texture_info = gAgentAvatarp->debugDumpLocalTextureDataInfo(getViewerTexLayerSet());
+
+ std::string status = "CREATING ";
+ if (!uploadNeeded()) status = "DONE ";
+ if (uploadInProgress()) status = "UPLOADING";
+
+ std::string text = llformat("[%s] [HiRes:%d LoRes:%d] [Elapsed:%d] %s",
+ status.c_str(),
+ is_high_res, num_low_res,
+ upload_time,
+ local_texture_info.c_str());
+ return text;
+}
diff --git a/indra/newview/llviewertexlayer.h b/indra/newview/llviewertexlayer.h
new file mode 100644
index 0000000000..959c883da8
--- /dev/null
+++ b/indra/newview/llviewertexlayer.h
@@ -0,0 +1,180 @@
+/**
+ * @file llviewertexlayer.h
+ * @brief Viewer Texture layer classes. Used for avatars.
+ *
+ * $LicenseInfo:firstyear=2012&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$
+ */
+
+#ifndef LL_VIEWER_TEXLAYER_H
+#define LL_VIEWER_TEXLAYER_H
+
+#include "lldynamictexture.h"
+#include "llextendedstatus.h"
+#include "lltexlayer.h"
+
+class LLVOAvatarSelf;
+class LLViewerTexLayerSetBuffer;
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// LLViewerTexLayerSet
+//
+// An ordered set of texture layers that gets composited into a single texture.
+// Only exists for llavatarappearanceself.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+class LLViewerTexLayerSet : public LLTexLayerSet
+{
+public:
+ LLViewerTexLayerSet(LLAvatarAppearance* const appearance);
+ virtual ~LLViewerTexLayerSet();
+
+ /*virtual*/void requestUpdate();
+ void requestUpload();
+ void cancelUpload();
+ BOOL isLocalTextureDataAvailable() const;
+ BOOL isLocalTextureDataFinal() const;
+ void updateComposite();
+ /*virtual*/void createComposite();
+ void setUpdatesEnabled(BOOL b);
+ BOOL getUpdatesEnabled() const { return mUpdatesEnabled; }
+
+ LLVOAvatarSelf* getAvatar();
+ const LLVOAvatarSelf* getAvatar() const;
+ LLViewerTexLayerSetBuffer* getViewerComposite();
+ const LLViewerTexLayerSetBuffer* getViewerComposite() const;
+
+private:
+ BOOL mUpdatesEnabled;
+
+};
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// LLViewerTexLayerSetBuffer
+//
+// The composite image that a LLViewerTexLayerSet writes to. Each LLViewerTexLayerSet has one.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+class LLViewerTexLayerSetBuffer : public LLTexLayerSetBuffer, public LLViewerDynamicTexture
+{
+ LOG_CLASS(LLViewerTexLayerSetBuffer);
+
+public:
+ LLViewerTexLayerSetBuffer(LLTexLayerSet* const owner, S32 width, S32 height);
+ virtual ~LLViewerTexLayerSetBuffer();
+
+public:
+ /*virtual*/ S8 getType() const;
+ BOOL isInitialized(void) const;
+ static void dumpTotalByteCount();
+ const std::string dumpTextureInfo() const;
+ virtual void restoreGLTexture();
+ virtual void destroyGLTexture();
+private:
+ LLViewerTexLayerSet* getViewerTexLayerSet()
+ { return dynamic_cast<LLViewerTexLayerSet*> (mTexLayerSet); }
+ const LLViewerTexLayerSet* getViewerTexLayerSet() const
+ { return dynamic_cast<const LLViewerTexLayerSet*> (mTexLayerSet); }
+ static S32 sGLByteCount;
+
+ //--------------------------------------------------------------------
+ // Tex Layer Render
+ //--------------------------------------------------------------------
+ virtual void preRenderTexLayerSet();
+ virtual void midRenderTexLayerSet(BOOL success);
+ virtual void postRenderTexLayerSet(BOOL success);
+ virtual S32 getCompositeOriginX() const { return getOriginX(); }
+ virtual S32 getCompositeOriginY() const { return getOriginY(); }
+ virtual S32 getCompositeWidth() const { return getFullWidth(); }
+ virtual S32 getCompositeHeight() const { return getFullHeight(); }
+
+ //--------------------------------------------------------------------
+ // Dynamic Texture Interface
+ //--------------------------------------------------------------------
+public:
+ /*virtual*/ BOOL needsRender();
+protected:
+ // Pass these along for tex layer rendering.
+ virtual void preRender(BOOL clear_depth) { preRenderTexLayerSet(); }
+ virtual void postRender(BOOL success) { postRenderTexLayerSet(success); }
+ virtual BOOL render() { return renderTexLayerSet(); }
+
+ //--------------------------------------------------------------------
+ // Uploads
+ //--------------------------------------------------------------------
+public:
+ void requestUpload();
+ void cancelUpload();
+ BOOL uploadNeeded() const; // We need to upload a new texture
+ BOOL uploadInProgress() const; // We have started uploading a new texture and are awaiting the result
+ BOOL uploadPending() const; // We are expecting a new texture to be uploaded at some point
+ static void onTextureUploadComplete(const LLUUID& uuid,
+ void* userdata,
+ S32 result, LLExtStat ext_status);
+protected:
+ BOOL isReadyToUpload() const;
+ void doUpload(); // Does a read back and upload.
+ void conditionalRestartUploadTimer();
+private:
+ BOOL mNeedsUpload; // Whether we need to send our baked textures to the server
+ U32 mNumLowresUploads; // Number of times we've sent a lowres version of our baked textures to the server
+ BOOL mUploadPending; // Whether we have received back the new baked textures
+ LLUUID mUploadID; // The current upload process (null if none).
+ LLFrameTimer mNeedsUploadTimer; // Tracks time since upload was requested and performed.
+ S32 mUploadFailCount; // Number of consecutive upload failures
+ LLFrameTimer mUploadRetryTimer; // Tracks time since last upload failure.
+
+ //--------------------------------------------------------------------
+ // Updates
+ //--------------------------------------------------------------------
+public:
+ void requestUpdate();
+ BOOL requestUpdateImmediate();
+protected:
+ BOOL isReadyToUpdate() const;
+ void doUpdate();
+ void restartUpdateTimer();
+private:
+ BOOL mNeedsUpdate; // Whether we need to locally update our baked textures
+ U32 mNumLowresUpdates; // Number of times we've locally updated with lowres version of our baked textures
+ LLFrameTimer mNeedsUpdateTimer; // Tracks time since update was requested and performed.
+};
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// LLBakedUploadData
+//
+// Used by LLTexLayerSetBuffer for a callback.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+struct LLBakedUploadData
+{
+ LLBakedUploadData(const LLVOAvatarSelf* avatar,
+ LLViewerTexLayerSet* layerset,
+ const LLUUID& id,
+ bool highest_res);
+ ~LLBakedUploadData() {}
+ const LLUUID mID;
+ const LLVOAvatarSelf* mAvatar; // note: backlink only; don't LLPointer
+ LLViewerTexLayerSet* mTexLayerSet;
+ const U64 mStartTime; // for measuring baked texture upload time
+ const bool mIsHighestRes; // whether this is a "final" bake, or intermediate low res
+};
+
+#endif // LL_VIEWER_TEXLAYER_H
+
diff --git a/indra/newview/llviewertexteditor.cpp b/indra/newview/llviewertexteditor.cpp
index 99102309a1..8036a4e258 100644..100755
--- a/indra/newview/llviewertexteditor.cpp
+++ b/indra/newview/llviewertexteditor.cpp
@@ -1052,8 +1052,6 @@ void LLViewerTextEditor::findEmbeddedItemSegments(S32 start, S32 end)
{
LLWString text = getWText();
- LLColor4 text_color = ( mReadOnly ? mReadOnlyFgColor.get() : mFgColor.get() );
-
// Start with i just after the first embedded item
for(S32 idx = start; idx < end; idx++ )
{
@@ -1144,6 +1142,14 @@ void LLViewerTextEditor::openEmbeddedTexture( LLInventoryItem* item, llwchar wc
{
preview->setAuxItem( item );
preview->setNotecardInfo(mNotecardInventoryID, mObjectID);
+ if (preview->hasString("Title"))
+ {
+ LLStringUtil::format_map_t args;
+ args["[NAME]"] = item->getName();
+ LLUIString title = preview->getString("Title", args);
+ preview->setTitle(title.getString());
+ }
+ preview->getChild<LLUICtrl>("desc")->setValue(item->getDescription());
}
}
diff --git a/indra/newview/llviewertexteditor.h b/indra/newview/llviewertexteditor.h
index fb428d0dc1..fb428d0dc1 100644..100755
--- a/indra/newview/llviewertexteditor.h
+++ b/indra/newview/llviewertexteditor.h
diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index 61236edc86..693eca8a06 100644..100755
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -39,7 +39,6 @@
#include "llimagebmp.h"
#include "llimagej2c.h"
#include "llimagetga.h"
-#include "llmemtype.h"
#include "llstl.h"
#include "llvfile.h"
#include "llvfs.h"
@@ -56,21 +55,23 @@
#include "llappviewer.h"
#include "llface.h"
#include "llviewercamera.h"
-#include "lltextureatlas.h"
-#include "lltextureatlasmanager.h"
#include "lltextureentry.h"
+#include "lltexturemanagerbridge.h"
#include "llmediaentry.h"
#include "llvovolume.h"
#include "llviewermedia.h"
+#include "lltexturecache.h"
///////////////////////////////////////////////////////////////////////////////
// statics
LLPointer<LLViewerTexture> LLViewerTexture::sNullImagep = NULL;
LLPointer<LLViewerTexture> LLViewerTexture::sBlackImagep = NULL;
+LLPointer<LLViewerTexture> LLViewerTexture::sCheckerBoardImagep = NULL;
LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sMissingAssetImagep = NULL;
LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sWhiteImagep = NULL;
LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sDefaultImagep = NULL;
LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sSmokeImagep = NULL;
+LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sFlatNormalImagep = NULL;
LLViewerMediaTexture::media_map_t LLViewerMediaTexture::sMediaMap ;
LLTexturePipelineTester* LLViewerTextureManager::sTesterp = NULL ;
const std::string sTesterName("TextureTester");
@@ -87,6 +88,7 @@ S32 LLViewerTexture::sMaxBoundTextureMemInMegaBytes = 0;
S32 LLViewerTexture::sMaxTotalTextureMemInMegaBytes = 0;
S32 LLViewerTexture::sMaxDesiredTextureMemInBytes = 0 ;
S8 LLViewerTexture::sCameraMovingDiscardBias = 0 ;
+F32 LLViewerTexture::sCameraMovingBias = 0.0f ;
S32 LLViewerTexture::sMaxSculptRez = 128 ; //max sculpt image size
const S32 MAX_CACHED_RAW_IMAGE_AREA = 64 * 64 ;
const S32 MAX_CACHED_RAW_SCULPT_IMAGE_AREA = LLViewerTexture::sMaxSculptRez * LLViewerTexture::sMaxSculptRez ;
@@ -95,7 +97,9 @@ S32 LLViewerTexture::sMinLargeImageSize = 65536 ; //256 * 256.
S32 LLViewerTexture::sMaxSmallImageSize = MAX_CACHED_RAW_IMAGE_AREA ;
BOOL LLViewerTexture::sFreezeImageScalingDown = FALSE ;
F32 LLViewerTexture::sCurrentTime = 0.0f ;
-BOOL LLViewerTexture::sUseTextureAtlas = FALSE ;
+F32 LLViewerTexture::sTexelPixelRatio = 1.0f;
+
+LLViewerTexture::EDebugTexels LLViewerTexture::sDebugTexelsMode = LLViewerTexture::DEBUG_TEXELS_OFF;
const F32 desired_discard_bias_min = -2.0f; // -max number of levels to improve image quality by
const F32 desired_discard_bias_max = (F32)MAX_DISCARD_LEVEL; // max number of levels to reduce image quality by
@@ -175,7 +179,12 @@ LLViewerTexture* LLViewerTextureManager::findTexture(const LLUUID& id)
}
return tex ;
}
-
+
+LLViewerFetchedTexture* LLViewerTextureManager::findFetchedTexture(const LLUUID& id)
+{
+ return gTextureList.findImage(id);
+}
+
LLViewerMediaTexture* LLViewerTextureManager::findMediaTexture(const LLUUID &media_id)
{
return LLViewerMediaTexture::findMediaTexture(media_id) ;
@@ -221,7 +230,7 @@ LLPointer<LLViewerTexture> LLViewerTextureManager::getLocalTexture(BOOL usemipma
if(generate_gl_tex)
{
tex->generateGLTexture() ;
- tex->setCategory(LLViewerTexture::LOCAL) ;
+ tex->setCategory(LLGLTexture::LOCAL) ;
}
return tex ;
}
@@ -231,14 +240,14 @@ LLPointer<LLViewerTexture> LLViewerTextureManager::getLocalTexture(const LLUUID&
if(generate_gl_tex)
{
tex->generateGLTexture() ;
- tex->setCategory(LLViewerTexture::LOCAL) ;
+ tex->setCategory(LLGLTexture::LOCAL) ;
}
return tex ;
}
LLPointer<LLViewerTexture> LLViewerTextureManager::getLocalTexture(const LLImageRaw* raw, BOOL usemipmaps)
{
LLPointer<LLViewerTexture> tex = new LLViewerTexture(raw, usemipmaps) ;
- tex->setCategory(LLViewerTexture::LOCAL) ;
+ tex->setCategory(LLGLTexture::LOCAL) ;
return tex ;
}
LLPointer<LLViewerTexture> LLViewerTextureManager::getLocalTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps, BOOL generate_gl_tex)
@@ -247,13 +256,14 @@ LLPointer<LLViewerTexture> LLViewerTextureManager::getLocalTexture(const U32 wid
if(generate_gl_tex)
{
tex->generateGLTexture() ;
- tex->setCategory(LLViewerTexture::LOCAL) ;
+ tex->setCategory(LLGLTexture::LOCAL) ;
}
return tex ;
}
LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTexture(
const LLUUID &image_id,
+ FTType f_type,
BOOL usemipmaps,
LLViewerTexture::EBoostLevel boost_priority,
S8 texture_type,
@@ -261,11 +271,12 @@ LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTexture(
LLGLenum primary_format,
LLHost request_from_host)
{
- return gTextureList.getImage(image_id, usemipmaps, boost_priority, texture_type, internal_format, primary_format, request_from_host) ;
+ return gTextureList.getImage(image_id, f_type, usemipmaps, boost_priority, texture_type, internal_format, primary_format, request_from_host) ;
}
LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromFile(
const std::string& filename,
+ FTType f_type,
BOOL usemipmaps,
LLViewerTexture::EBoostLevel boost_priority,
S8 texture_type,
@@ -273,11 +284,12 @@ LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromFile(
LLGLenum primary_format,
const LLUUID& force_id)
{
- return gTextureList.getImageFromFile(filename, usemipmaps, boost_priority, texture_type, internal_format, primary_format, force_id) ;
+ return gTextureList.getImageFromFile(filename, f_type, usemipmaps, boost_priority, texture_type, internal_format, primary_format, force_id) ;
}
//static
LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromUrl(const std::string& url,
+ FTType f_type,
BOOL usemipmaps,
LLViewerTexture::EBoostLevel boost_priority,
S8 texture_type,
@@ -286,14 +298,34 @@ LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromUrl(const s
const LLUUID& force_id
)
{
- return gTextureList.getImageFromUrl(url, usemipmaps, boost_priority, texture_type, internal_format, primary_format, force_id) ;
+ return gTextureList.getImageFromUrl(url, f_type, usemipmaps, boost_priority, texture_type, internal_format, primary_format, force_id) ;
}
-LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromHost(const LLUUID& image_id, LLHost host)
+LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromHost(const LLUUID& image_id, FTType f_type, LLHost host)
{
- return gTextureList.getImageFromHost(image_id, host) ;
+ return gTextureList.getImageFromHost(image_id, f_type, host) ;
}
+// Create a bridge to the viewer texture manager.
+class LLViewerTextureManagerBridge : public LLTextureManagerBridge
+{
+ /*virtual*/ LLPointer<LLGLTexture> getLocalTexture(BOOL usemipmaps = TRUE, BOOL generate_gl_tex = TRUE)
+ {
+ return LLViewerTextureManager::getLocalTexture(usemipmaps, generate_gl_tex);
+ }
+
+ /*virtual*/ LLPointer<LLGLTexture> getLocalTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps, BOOL generate_gl_tex = TRUE)
+ {
+ return LLViewerTextureManager::getLocalTexture(width, height, components, usemipmaps, generate_gl_tex);
+ }
+
+ /*virtual*/ LLGLTexture* getFetchedTexture(const LLUUID &image_id)
+ {
+ return LLViewerTextureManager::getFetchedTexture(image_id);
+ }
+};
+
+
void LLViewerTextureManager::init()
{
{
@@ -339,16 +371,34 @@ void LLViewerTextureManager::init()
imagep->setCachedRawImage(0, image_raw) ;
image_raw = NULL;
#else
- LLViewerFetchedTexture::sDefaultImagep = LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT, TRUE, LLViewerTexture::BOOST_UI);
+ LLViewerFetchedTexture::sDefaultImagep = LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT, TRUE, LLGLTexture::BOOST_UI);
#endif
LLViewerFetchedTexture::sDefaultImagep->dontDiscard();
- LLViewerFetchedTexture::sDefaultImagep->setCategory(LLViewerTexture::OTHER) ;
+ LLViewerFetchedTexture::sDefaultImagep->setCategory(LLGLTexture::OTHER) ;
- LLViewerFetchedTexture::sSmokeImagep = LLViewerTextureManager::getFetchedTexture(IMG_SMOKE, TRUE, LLViewerTexture::BOOST_UI);
+ LLViewerFetchedTexture::sSmokeImagep = LLViewerTextureManager::getFetchedTexture(IMG_SMOKE, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);
LLViewerFetchedTexture::sSmokeImagep->setNoDelete() ;
+ image_raw = new LLImageRaw(32,32,3);
+ data = image_raw->getData();
+
+ for (S32 i = 0; i < (32*32*3); i+=3)
+ {
+ S32 x = (i % (32*3)) / (3*16);
+ S32 y = i / (32*3*16);
+ U8 color = ((x + y) % 2) * 255;
+ data[i] = color;
+ data[i+1] = color;
+ data[i+2] = color;
+ }
+
+ LLViewerTexture::sCheckerBoardImagep = LLViewerTextureManager::getLocalTexture(image_raw.get(), TRUE);
+
LLViewerTexture::initClass() ;
+ // Create a texture manager bridge.
+ gTextureManagerBridgep = new LLViewerTextureManagerBridge;
+
if (LLMetricPerformanceTesterBasic::isMetricLogRequested(sTesterName) && !LLMetricPerformanceTesterBasic::getTester(sTesterName))
{
sTesterp = new LLTexturePipelineTester() ;
@@ -364,13 +414,16 @@ void LLViewerTextureManager::cleanup()
{
stop_glerror();
+ delete gTextureManagerBridgep;
LLImageGL::sDefaultGLTexture = NULL ;
LLViewerTexture::sNullImagep = NULL;
LLViewerTexture::sBlackImagep = NULL;
+ LLViewerTexture::sCheckerBoardImagep = NULL;
LLViewerFetchedTexture::sDefaultImagep = NULL;
LLViewerFetchedTexture::sSmokeImagep = NULL;
LLViewerFetchedTexture::sMissingAssetImagep = NULL;
LLViewerFetchedTexture::sWhiteImagep = NULL;
+ LLViewerFetchedTexture::sFlatNormalImagep = NULL;
LLViewerMediaTexture::cleanUpClass() ;
}
@@ -383,32 +436,13 @@ void LLViewerTextureManager::cleanup()
void LLViewerTexture::initClass()
{
LLImageGL::sDefaultGLTexture = LLViewerFetchedTexture::sDefaultImagep->getGLTexture() ;
-
- if(gAuditTexture)
+
+ if(gSavedSettings.getBOOL("TextureFetchDebuggerEnabled"))
{
- LLImageGL::setHighlightTexture(LLViewerTexture::OTHER) ;
+ sTexelPixelRatio = gSavedSettings.getF32("TexelPixelRatio");
}
}
-// static
-S32 LLViewerTexture::getTotalNumOfCategories()
-{
- return MAX_GL_IMAGE_CATEGORY - (BOOST_HIGH - BOOST_SCULPTED) + 2 ;
-}
-
-// static
-//index starts from zero.
-S32 LLViewerTexture::getIndexFromCategory(S32 category)
-{
- return (category < BOOST_HIGH) ? category : category - (BOOST_HIGH - BOOST_SCULPTED) + 1 ;
-}
-
-//static
-S32 LLViewerTexture::getCategoryFromIndex(S32 index)
-{
- return (index < BOOST_HIGH) ? index : index + (BOOST_HIGH - BOOST_SCULPTED) - 1 ;
-}
-
// tuning params
const F32 discard_bias_delta = .25f;
const F32 discard_delta_time = 0.5f;
@@ -530,11 +564,11 @@ void LLViewerTexture::updateClass(const F32 velocity, const F32 angular_velocity
}
}
sDesiredDiscardBias = llclamp(sDesiredDiscardBias, desired_discard_bias_min, desired_discard_bias_max);
- LLViewerTexture::sUseTextureAtlas = gSavedSettings.getBOOL("EnableTextureAtlas") ;
-
+
F32 camera_moving_speed = LLViewerCamera::getInstance()->getAverageSpeed() ;
F32 camera_angular_speed = LLViewerCamera::getInstance()->getAverageAngularSpeed();
- sCameraMovingDiscardBias = (S8)llmax(0.2f * camera_moving_speed, 2.0f * camera_angular_speed - 1) ;
+ sCameraMovingBias = llmax(0.2f * camera_moving_speed, 2.0f * camera_angular_speed - 1);
+ sCameraMovingDiscardBias = (S8)(sCameraMovingBias);
LLViewerTexture::sFreezeImageScalingDown = (BYTES_TO_MEGA_BYTES(sBoundTextureMemoryInBytes) < 0.75f * sMaxBoundTextureMemInMegaBytes * texmem_middle_bound_scale) &&
(BYTES_TO_MEGA_BYTES(sTotalTextureMemoryInBytes) < 0.75f * sMaxTotalTextureMemInMegaBytes * texmem_middle_bound_scale) ;
@@ -544,76 +578,66 @@ void LLViewerTexture::updateClass(const F32 velocity, const F32 angular_velocity
//-------------------------------------------------------------------------------------------
const U32 LLViewerTexture::sCurrentFileVersion = 1;
-LLViewerTexture::LLViewerTexture(BOOL usemipmaps)
+LLViewerTexture::LLViewerTexture(BOOL usemipmaps) :
+ LLGLTexture(usemipmaps)
{
init(true);
- mUseMipMaps = usemipmaps ;
mID.generate();
sImageCount++;
}
-LLViewerTexture::LLViewerTexture(const LLUUID& id, BOOL usemipmaps)
- : mID(id)
+LLViewerTexture::LLViewerTexture(const LLUUID& id, BOOL usemipmaps) :
+ LLGLTexture(usemipmaps),
+ mID(id)
{
init(true);
- mUseMipMaps = usemipmaps ;
sImageCount++;
}
-LLViewerTexture::LLViewerTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps)
+LLViewerTexture::LLViewerTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps) :
+ LLGLTexture(width, height, components, usemipmaps)
{
init(true);
- mFullWidth = width ;
- mFullHeight = height ;
- mUseMipMaps = usemipmaps ;
- mComponents = components ;
- setTexelsPerImage();
-
mID.generate();
sImageCount++;
}
-LLViewerTexture::LLViewerTexture(const LLImageRaw* raw, BOOL usemipmaps)
+LLViewerTexture::LLViewerTexture(const LLImageRaw* raw, BOOL usemipmaps) :
+ LLGLTexture(raw, usemipmaps)
{
init(true);
- mUseMipMaps = usemipmaps ;
- mGLTexturep = new LLImageGL(raw, usemipmaps) ;
- // Create an empty image of the specified size and width
mID.generate();
sImageCount++;
}
LLViewerTexture::~LLViewerTexture()
{
+ // LL_DEBUGS("Avatar") << mID << llendl;
cleanup();
sImageCount--;
}
+// virtual
void LLViewerTexture::init(bool firstinit)
{
- mBoostLevel = LLViewerTexture::BOOST_NONE;
-
- mFullWidth = 0;
- mFullHeight = 0;
- mTexelsPerImage = 0 ;
- mUseMipMaps = FALSE ;
- mComponents = 0 ;
-
- mTextureState = NO_DELETE ;
- mDontDiscard = FALSE;
+ mSelectedTime = 0.f;
mMaxVirtualSize = 0.f;
- mNeedsGLTexture = FALSE ;
mMaxVirtualSizeResetInterval = 1;
mMaxVirtualSizeResetCounter = mMaxVirtualSizeResetInterval ;
mAdditionalDecodePriority = 0.f ;
mParcelMedia = NULL ;
- mNumFaces = 0 ;
+
mNumVolumes = 0;
- mFaceList.clear() ;
+ mFaceList[LLRender::DIFFUSE_MAP].clear() ;
+ mFaceList[LLRender::NORMAL_MAP].clear() ;
+ mFaceList[LLRender::SPECULAR_MAP].clear() ;
+ mNumFaces[LLRender::DIFFUSE_MAP] =
+ mNumFaces[LLRender::NORMAL_MAP] =
+ mNumFaces[LLRender::SPECULAR_MAP] = 0 ;
mVolumeList.clear();
}
@@ -625,21 +649,16 @@ S8 LLViewerTexture::getType() const
void LLViewerTexture::cleanup()
{
- mFaceList.clear() ;
+ mFaceList[LLRender::DIFFUSE_MAP].clear() ;
+ mFaceList[LLRender::NORMAL_MAP].clear() ;
+ mFaceList[LLRender::SPECULAR_MAP].clear() ;
mVolumeList.clear();
- if(mGLTexturep)
- {
- mGLTexturep->cleanup();
- }
}
// virtual
void LLViewerTexture::dump()
{
- if(mGLTexturep)
- {
- mGLTexturep->dump();
- }
+ LLGLTexture::dump();
llinfos << "LLViewerTexture"
<< " mID " << mID
@@ -651,17 +670,18 @@ void LLViewerTexture::setBoostLevel(S32 level)
if(mBoostLevel != level)
{
mBoostLevel = level ;
- if(mBoostLevel != LLViewerTexture::BOOST_NONE)
+ if(mBoostLevel != LLViewerTexture::BOOST_NONE &&
+ mBoostLevel != LLViewerTexture::BOOST_SELECTED)
{
setNoDelete() ;
}
- if(gAuditTexture)
- {
- setCategory(mBoostLevel);
- }
}
-}
+ if (mBoostLevel == LLViewerTexture::BOOST_SELECTED)
+ {
+ mSelectedTime = gFrameTimeSeconds;
+ }
+}
bool LLViewerTexture::bindDefaultImage(S32 stage)
{
@@ -712,6 +732,7 @@ void LLViewerTexture::addTextureStats(F32 virtual_size, BOOL needs_gltexture) co
mNeedsGLTexture = TRUE ;
}
+ virtual_size *= sTexelPixelRatio;
if(!mMaxVirtualSizeResetCounter)
{
//flag to reset the values because the old values are used.
@@ -746,38 +767,57 @@ void LLViewerTexture::setKnownDrawSize(S32 width, S32 height)
}
//virtual
-void LLViewerTexture::addFace(LLFace* facep)
+void LLViewerTexture::addFace(U32 ch, LLFace* facep)
{
- if(mNumFaces >= mFaceList.size())
+ llassert(ch < LLRender::NUM_TEXTURE_CHANNELS);
+
+ if(mNumFaces[ch] >= mFaceList[ch].size())
{
- mFaceList.resize(2 * mNumFaces + 1) ;
+ mFaceList[ch].resize(2 * mNumFaces[ch] + 1) ;
}
- mFaceList[mNumFaces] = facep ;
- facep->setIndexInTex(mNumFaces) ;
- mNumFaces++ ;
+ mFaceList[ch][mNumFaces[ch]] = facep ;
+ facep->setIndexInTex(ch, mNumFaces[ch]) ;
+ mNumFaces[ch]++ ;
mLastFaceListUpdateTimer.reset() ;
}
//virtual
-void LLViewerTexture::removeFace(LLFace* facep)
+void LLViewerTexture::removeFace(U32 ch, LLFace* facep)
{
- if(mNumFaces > 1)
+ llassert(ch < LLRender::NUM_TEXTURE_CHANNELS);
+
+ if(mNumFaces[ch] > 1)
{
- S32 index = facep->getIndexInTex() ;
- mFaceList[index] = mFaceList[--mNumFaces] ;
- mFaceList[index]->setIndexInTex(index) ;
+ S32 index = facep->getIndexInTex(ch) ;
+ llassert(index < mFaceList[ch].size());
+ llassert(index < mNumFaces[ch]);
+ mFaceList[ch][index] = mFaceList[ch][--mNumFaces[ch]] ;
+ mFaceList[ch][index]->setIndexInTex(ch, index) ;
}
else
{
- mFaceList.clear() ;
- mNumFaces = 0 ;
+ mFaceList[ch].clear() ;
+ mNumFaces[ch] = 0 ;
}
mLastFaceListUpdateTimer.reset() ;
}
-S32 LLViewerTexture::getNumFaces() const
+S32 LLViewerTexture::getTotalNumFaces() const
+{
+ S32 ret = 0;
+
+ for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i)
+ {
+ ret += mNumFaces[i];
+ }
+
+ return ret;
+}
+
+S32 LLViewerTexture::getNumFaces(U32 ch) const
{
- return mNumFaces ;
+ llassert(ch < LLRender::NUM_TEXTURE_CHANNELS);
+ return mNumFaces[ch];
}
@@ -800,6 +840,8 @@ void LLViewerTexture::removeVolume(LLVOVolume* volumep)
if(mNumVolumes > 1)
{
S32 index = volumep->getIndexInTex() ;
+ llassert(index < mVolumeList.size());
+ llassert(index < mNumVolumes);
mVolumeList[index] = mVolumeList[--mNumVolumes] ;
mVolumeList[index]->setIndexInTex(index) ;
}
@@ -821,18 +863,22 @@ void LLViewerTexture::reorganizeFaceList()
static const F32 MAX_WAIT_TIME = 20.f; // seconds
static const U32 MAX_EXTRA_BUFFER_SIZE = 4 ;
- if(mNumFaces + MAX_EXTRA_BUFFER_SIZE > mFaceList.size())
+ if(mLastFaceListUpdateTimer.getElapsedTimeF32() < MAX_WAIT_TIME)
{
- return ;
+ return;
}
- if(mLastFaceListUpdateTimer.getElapsedTimeF32() < MAX_WAIT_TIME)
+ for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i)
{
- return ;
+ if(mNumFaces[i] + MAX_EXTRA_BUFFER_SIZE > mFaceList[i].size())
+ {
+ return ;
+ }
+
+ mFaceList[i].erase(mFaceList[i].begin() + mNumFaces[i], mFaceList[i].end());
}
-
+
mLastFaceListUpdateTimer.reset() ;
- mFaceList.erase(mFaceList.begin() + mNumFaces, mFaceList.end());
}
void LLViewerTexture::reorganizeVolumeList()
@@ -854,294 +900,18 @@ void LLViewerTexture::reorganizeVolumeList()
mVolumeList.erase(mVolumeList.begin() + mNumVolumes, mVolumeList.end());
}
-
-
//virtual
void LLViewerTexture::switchToCachedImage()
{
//nothing here.
}
-void LLViewerTexture::forceActive()
-{
- mTextureState = ACTIVE ;
-}
-
-void LLViewerTexture::setActive()
-{
- if(mTextureState != NO_DELETE)
- {
- mTextureState = ACTIVE ;
- }
-}
-
-//set the texture to stay in memory
-void LLViewerTexture::setNoDelete()
-{
- mTextureState = NO_DELETE ;
-}
-
-void LLViewerTexture::generateGLTexture()
-{
- if(mGLTexturep.isNull())
- {
- mGLTexturep = new LLImageGL(mFullWidth, mFullHeight, mComponents, mUseMipMaps) ;
- }
-}
-
-LLImageGL* LLViewerTexture::getGLTexture() const
-{
- llassert(mGLTexturep.notNull()) ;
-
- return mGLTexturep ;
-}
-
-BOOL LLViewerTexture::createGLTexture()
-{
- if(mGLTexturep.isNull())
- {
- generateGLTexture() ;
- }
-
- return mGLTexturep->createGLTexture() ;
-}
-
-BOOL LLViewerTexture::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename, BOOL to_create, S32 category)
-{
- llassert(mGLTexturep.notNull()) ;
-
- BOOL ret = mGLTexturep->createGLTexture(discard_level, imageraw, usename, to_create, category) ;
-
- if(ret)
- {
- mFullWidth = mGLTexturep->getCurrentWidth() ;
- mFullHeight = mGLTexturep->getCurrentHeight() ;
- mComponents = mGLTexturep->getComponents() ;
- setTexelsPerImage();
- }
-
- return ret ;
-}
-
//virtual
void LLViewerTexture::setCachedRawImage(S32 discard_level, LLImageRaw* imageraw)
{
//nothing here.
}
-void LLViewerTexture::setExplicitFormat(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format, BOOL swap_bytes)
-{
- llassert(mGLTexturep.notNull()) ;
-
- mGLTexturep->setExplicitFormat(internal_format, primary_format, type_format, swap_bytes) ;
-}
-void LLViewerTexture::setAddressMode(LLTexUnit::eTextureAddressMode mode)
-{
- llassert(mGLTexturep.notNull()) ;
- mGLTexturep->setAddressMode(mode) ;
-}
-void LLViewerTexture::setFilteringOption(LLTexUnit::eTextureFilterOptions option)
-{
- llassert(mGLTexturep.notNull()) ;
- mGLTexturep->setFilteringOption(option) ;
-}
-
-//virtual
-S32 LLViewerTexture::getWidth(S32 discard_level) const
-{
- llassert(mGLTexturep.notNull()) ;
- return mGLTexturep->getWidth(discard_level) ;
-}
-
-//virtual
-S32 LLViewerTexture::getHeight(S32 discard_level) const
-{
- llassert(mGLTexturep.notNull()) ;
- return mGLTexturep->getHeight(discard_level) ;
-}
-
-S32 LLViewerTexture::getMaxDiscardLevel() const
-{
- llassert(mGLTexturep.notNull()) ;
- return mGLTexturep->getMaxDiscardLevel() ;
-}
-S32 LLViewerTexture::getDiscardLevel() const
-{
- llassert(mGLTexturep.notNull()) ;
- return mGLTexturep->getDiscardLevel() ;
-}
-S8 LLViewerTexture::getComponents() const
-{
- llassert(mGLTexturep.notNull()) ;
-
- return mGLTexturep->getComponents() ;
-}
-
-LLGLuint LLViewerTexture::getTexName() const
-{
- llassert(mGLTexturep.notNull()) ;
-
- return mGLTexturep->getTexName() ;
-}
-
-BOOL LLViewerTexture::hasGLTexture() const
-{
- if(mGLTexturep.notNull())
- {
- return mGLTexturep->getHasGLTexture() ;
- }
- return FALSE ;
-}
-
-BOOL LLViewerTexture::getBoundRecently() const
-{
- if(mGLTexturep.notNull())
- {
- return mGLTexturep->getBoundRecently() ;
- }
- return FALSE ;
-}
-
-LLTexUnit::eTextureType LLViewerTexture::getTarget(void) const
-{
- llassert(mGLTexturep.notNull()) ;
- return mGLTexturep->getTarget() ;
-}
-
-BOOL LLViewerTexture::setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height)
-{
- llassert(mGLTexturep.notNull()) ;
-
- return mGLTexturep->setSubImage(imageraw, x_pos, y_pos, width, height) ;
-}
-
-BOOL LLViewerTexture::setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height)
-{
- llassert(mGLTexturep.notNull()) ;
-
- return mGLTexturep->setSubImage(datap, data_width, data_height, x_pos, y_pos, width, height) ;
-}
-
-void LLViewerTexture::setGLTextureCreated (bool initialized)
-{
- llassert(mGLTexturep.notNull()) ;
-
- mGLTexturep->setGLTextureCreated (initialized) ;
-}
-
-void LLViewerTexture::setCategory(S32 category)
-{
- llassert(mGLTexturep.notNull()) ;
-
- mGLTexturep->setCategory(category) ;
-}
-
-LLTexUnit::eTextureAddressMode LLViewerTexture::getAddressMode(void) const
-{
- llassert(mGLTexturep.notNull()) ;
-
- return mGLTexturep->getAddressMode() ;
-}
-
-S32 LLViewerTexture::getTextureMemory() const
-{
- llassert(mGLTexturep.notNull()) ;
-
- return mGLTexturep->mTextureMemory ;
-}
-
-LLGLenum LLViewerTexture::getPrimaryFormat() const
-{
- llassert(mGLTexturep.notNull()) ;
-
- return mGLTexturep->getPrimaryFormat() ;
-}
-
-BOOL LLViewerTexture::getIsAlphaMask() const
-{
- llassert(mGLTexturep.notNull()) ;
-
- return mGLTexturep->getIsAlphaMask() ;
-}
-
-BOOL LLViewerTexture::getMask(const LLVector2 &tc)
-{
- llassert(mGLTexturep.notNull()) ;
-
- return mGLTexturep->getMask(tc) ;
-}
-
-F32 LLViewerTexture::getTimePassedSinceLastBound()
-{
- llassert(mGLTexturep.notNull()) ;
-
- return mGLTexturep->getTimePassedSinceLastBound() ;
-}
-BOOL LLViewerTexture::getMissed() const
-{
- llassert(mGLTexturep.notNull()) ;
-
- return mGLTexturep->getMissed() ;
-}
-
-BOOL LLViewerTexture::isJustBound() const
-{
- llassert(mGLTexturep.notNull()) ;
-
- return mGLTexturep->isJustBound() ;
-}
-
-void LLViewerTexture::forceUpdateBindStats(void) const
-{
- llassert(mGLTexturep.notNull()) ;
-
- return mGLTexturep->forceUpdateBindStats() ;
-}
-
-U32 LLViewerTexture::getTexelsInAtlas() const
-{
- llassert(mGLTexturep.notNull()) ;
-
- return mGLTexturep->getTexelsInAtlas() ;
-}
-
-U32 LLViewerTexture::getTexelsInGLTexture() const
-{
- llassert(mGLTexturep.notNull()) ;
-
- return mGLTexturep->getTexelsInGLTexture() ;
-}
-
-BOOL LLViewerTexture::isGLTextureCreated() const
-{
- llassert(mGLTexturep.notNull()) ;
-
- return mGLTexturep->isGLTextureCreated() ;
-}
-
-S32 LLViewerTexture::getDiscardLevelInAtlas() const
-{
- llassert(mGLTexturep.notNull()) ;
-
- return mGLTexturep->getDiscardLevelInAtlas() ;
-}
-
-void LLViewerTexture::destroyGLTexture()
-{
- if(mGLTexturep.notNull() && mGLTexturep->getHasGLTexture())
- {
- mGLTexturep->destroyGLTexture() ;
- mTextureState = DELETED ;
- }
-}
-
-void LLViewerTexture::setTexelsPerImage()
-{
- S32 fullwidth = llmin(mFullWidth,(S32)MAX_IMAGE_SIZE_DEFAULT);
- S32 fullheight = llmin(mFullHeight,(S32)MAX_IMAGE_SIZE_DEFAULT);
- mTexelsPerImage = (F32)fullwidth * fullheight;
-}
-
BOOL LLViewerTexture::isLargeImage()
{
return (S32)mTexelsPerImage > LLViewerTexture::sMinLargeImageSize ;
@@ -1165,25 +935,32 @@ void LLViewerTexture::updateBindStatsForTester()
//start of LLViewerFetchedTexture
//----------------------------------------------------------------------------------------------
-LLViewerFetchedTexture::LLViewerFetchedTexture(const LLUUID& id, const LLHost& host, BOOL usemipmaps)
+LLViewerFetchedTexture::LLViewerFetchedTexture(const LLUUID& id, FTType f_type, const LLHost& host, BOOL usemipmaps)
: LLViewerTexture(id, usemipmaps),
mTargetHost(host)
{
init(TRUE) ;
+ mFTType = f_type;
+ if (mFTType == FTT_HOST_BAKE)
+ {
+ mCanUseHTTP = false;
+ }
generateGLTexture() ;
}
-LLViewerFetchedTexture::LLViewerFetchedTexture(const LLImageRaw* raw, BOOL usemipmaps)
+LLViewerFetchedTexture::LLViewerFetchedTexture(const LLImageRaw* raw, FTType f_type, BOOL usemipmaps)
: LLViewerTexture(raw, usemipmaps)
{
init(TRUE) ;
+ mFTType = f_type;
}
-LLViewerFetchedTexture::LLViewerFetchedTexture(const std::string& url, const LLUUID& id, BOOL usemipmaps)
+LLViewerFetchedTexture::LLViewerFetchedTexture(const std::string& url, FTType f_type, const LLUUID& id, BOOL usemipmaps)
: LLViewerTexture(id, usemipmaps),
mUrl(url)
{
init(TRUE) ;
+ mFTType = f_type;
generateGLTexture() ;
}
@@ -1216,7 +993,7 @@ void LLViewerFetchedTexture::init(bool firstinit)
mIsMissingAsset = FALSE;
mLoadedCallbackDesiredDiscardLevel = S8_MAX;
- mPauseLoadedCallBacks = TRUE ;
+ mPauseLoadedCallBacks = FALSE ;
mNeedsCreateTexture = FALSE;
@@ -1233,6 +1010,7 @@ void LLViewerFetchedTexture::init(bool firstinit)
mRequestDeltaTime = 0.f;
mForSculpt = FALSE ;
mIsFetched = FALSE ;
+ mInFastCacheList = FALSE;
mCachedRawImage = NULL ;
mCachedRawDiscardLevel = -1 ;
@@ -1246,6 +1024,10 @@ void LLViewerFetchedTexture::init(bool firstinit)
mLastReferencedSavedRawImageTime = 0.0f ;
mKeptSavedRawImageTime = 0.f ;
mLastCallBackActiveTime = 0.f;
+
+ mInDebug = FALSE;
+
+ mFTType = FTT_UNKNOWN;
}
LLViewerFetchedTexture::~LLViewerFetchedTexture()
@@ -1266,6 +1048,11 @@ S8 LLViewerFetchedTexture::getType() const
return LLViewerTexture::FETCHED_TEXTURE ;
}
+FTType LLViewerFetchedTexture::getFTType() const
+{
+ return mFTType;
+}
+
void LLViewerFetchedTexture::cleanup()
{
for(callback_list_t::iterator iter = mLoadedCallbackList.begin();
@@ -1287,6 +1074,40 @@ void LLViewerFetchedTexture::cleanup()
mCachedRawDiscardLevel = -1 ;
mCachedRawImageReady = FALSE ;
mSavedRawImage = NULL ;
+ mSavedRawDiscardLevel = -1;
+}
+
+//access the fast cache
+void LLViewerFetchedTexture::loadFromFastCache()
+{
+ if(!mInFastCacheList)
+ {
+ return; //no need to access the fast cache.
+ }
+ mInFastCacheList = FALSE;
+
+ mRawImage = LLAppViewer::getTextureCache()->readFromFastCache(getID(), mRawDiscardLevel) ;
+ if(mRawImage.notNull())
+ {
+ mFullWidth = mRawImage->getWidth() << mRawDiscardLevel;
+ mFullHeight = mRawImage->getHeight() << mRawDiscardLevel;
+ setTexelsPerImage();
+
+ if(mFullWidth > MAX_IMAGE_SIZE || mFullHeight > MAX_IMAGE_SIZE)
+ {
+ //discard all oversized textures.
+ destroyRawImage();
+ llwarns << "oversized, setting as missing" << llendl;
+ setIsMissingAsset();
+ mRawDiscardLevel = INVALID_DISCARD_LEVEL ;
+ }
+ else
+ {
+ mRequestedDiscardLevel = mDesiredDiscardLevel + 1;
+ mIsRawImageValid = TRUE;
+ addToCreateTexture() ;
+ }
+ }
}
void LLViewerFetchedTexture::setForSculpt()
@@ -1294,9 +1115,10 @@ void LLViewerFetchedTexture::setForSculpt()
static const S32 MAX_INTERVAL = 8 ; //frames
mForSculpt = TRUE ;
- if(isForSculptOnly() && !getBoundRecently())
+ if(isForSculptOnly() && hasGLTexture() && !getBoundRecently())
{
destroyGLTexture() ; //sculpt image does not need gl texture.
+ mTextureState = ACTIVE;
}
checkCachedRawSculptImage() ;
setMaxVirtualSizeResetInterval(MAX_INTERVAL) ;
@@ -1377,7 +1199,7 @@ void LLViewerFetchedTexture::dump()
// ONLY called from LLViewerFetchedTextureList
void LLViewerFetchedTexture::destroyTexture()
{
- if(LLImageGL::sGlobalTextureMemoryInBytes < sMaxDesiredTextureMemInBytes)//not ready to release unused memory.
+ if(LLImageGL::sGlobalTextureMemoryInBytes < sMaxDesiredTextureMemInBytes * 0.95f)//not ready to release unused memory.
{
return ;
}
@@ -1386,6 +1208,7 @@ void LLViewerFetchedTexture::destroyTexture()
return ;
}
+ //LL_DEBUGS("Avatar") << mID << llendl;
destroyGLTexture() ;
mFullyLoaded = FALSE ;
}
@@ -1401,9 +1224,14 @@ void LLViewerFetchedTexture::addToCreateTexture()
mGLTexturep->setComponents(mComponents) ;
force_update = true ;
- for(U32 i = 0 ; i < mNumFaces ; i++)
+ for (U32 j = 0; j < LLRender::NUM_TEXTURE_CHANNELS; ++j)
{
- mFaceList[i]->dirtyTexture() ;
+ llassert(mNumFaces[j] <= mFaceList[j].size());
+
+ for(U32 i = 0 ; i < mNumFaces[j]; i++)
+ {
+ mFaceList[j][i]->dirtyTexture() ;
+ }
}
//discard the cached raw image and the saved raw image
@@ -1462,7 +1290,12 @@ void LLViewerFetchedTexture::addToCreateTexture()
destroyRawImage();
return ;
}
- mRawImage->scale(w >> i, h >> i) ;
+
+ {
+ //make a duplicate in case somebody else is using this raw image
+ mRawImage = mRawImage->duplicate();
+ mRawImage->scale(w >> i, h >> i) ;
+ }
}
}
}
@@ -1541,16 +1374,14 @@ BOOL LLViewerFetchedTexture::createTexture(S32 usename/*= 0*/)
// An inappropriately-sized image was uploaded (through a non standard client)
// We treat these images as missing assets which causes them to
// be renderd as 'missing image' and to stop requesting data
+ llwarns << "!size_ok, setting as missing" << llendl;
setIsMissingAsset();
destroyRawImage();
return FALSE;
}
- if(!(res = insertToAtlas()))
- {
- res = mGLTexturep->createGLTexture(mRawDiscardLevel, mRawImage, usename, TRUE, mBoostLevel);
- resetFaceAtlas() ;
- }
+ res = mGLTexturep->createGLTexture(mRawDiscardLevel, mRawImage, usename, TRUE, mBoostLevel);
+
setActive() ;
if (!needsToSaveRawImage())
@@ -1591,7 +1422,7 @@ void LLViewerFetchedTexture::processTextureStats()
{
updateVirtualSize() ;
- static LLCachedControl<bool> textures_fullres(gSavedSettings,"TextureLoadFullRes");
+ static LLCachedControl<bool> textures_fullres(gSavedSettings,"TextureLoadFullRes", false);
if (textures_fullres)
{
@@ -1688,14 +1519,14 @@ F32 LLViewerFetchedTexture::calcDecodePriority()
// Don't decode anything we don't need
priority = -4.0f;
}
- else if ((mBoostLevel == LLViewerTexture::BOOST_UI || mBoostLevel == LLViewerTexture::BOOST_ICON) && !have_all_data)
+ else if ((mBoostLevel == LLGLTexture::BOOST_UI || mBoostLevel == LLGLTexture::BOOST_ICON) && !have_all_data)
{
priority = 1.f;
}
else if (pixel_priority < 0.001f && !have_all_data)
{
// Not on screen but we might want some data
- if (mBoostLevel > BOOST_HIGH)
+ if (mBoostLevel > BOOST_SELECTED)
{
// Always want high boosted images
priority = 1.f;
@@ -1714,7 +1545,7 @@ F32 LLViewerFetchedTexture::calcDecodePriority()
S32 ddiscard = MAX_DISCARD_LEVEL - (S32)desired;
ddiscard = llclamp(ddiscard, 0, MAX_DELTA_DISCARD_LEVEL_FOR_PRIORITY);
priority = (ddiscard + 1) * PRIORITY_DELTA_DISCARD_LEVEL_FACTOR;
- setAdditionalDecodePriority(1.0f) ;//boost the textures without any data so far.
+ setAdditionalDecodePriority(0.1f) ;//boost the textures without any data so far.
}
else if ((mMinDiscardLevel > 0) && (cur_discard <= mMinDiscardLevel))
{
@@ -1815,8 +1646,6 @@ F32 LLViewerFetchedTexture::maxDecodePriority()
void LLViewerFetchedTexture::setDecodePriority(F32 priority)
{
- llassert(!mInImageList);
-
mDecodePriority = priority;
if(mDecodePriority < F_ALMOST_ZERO)
@@ -1841,15 +1670,40 @@ void LLViewerFetchedTexture::updateVirtualSize()
addTextureStats(0.f, FALSE) ;//reset
}
- for(U32 i = 0 ; i < mNumFaces ; i++)
- {
- LLFace* facep = mFaceList[i] ;
- if(facep->getDrawable()->isRecentlyVisible())
- {
- addTextureStats(facep->getVirtualSize()) ;
- setAdditionalDecodePriority(facep->getImportanceToCamera()) ;
+ for (U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch)
+ {
+ llassert(mNumFaces[ch] <= mFaceList[ch].size());
+
+ for(U32 i = 0 ; i < mNumFaces[ch]; i++)
+ {
+ LLFace* facep = mFaceList[ch][i] ;
+ if( facep )
+ {
+ LLDrawable* drawable = facep->getDrawable();
+ if (drawable)
+ {
+ if(drawable->isRecentlyVisible())
+ {
+ if (getBoostLevel() == LLViewerTexture::BOOST_NONE &&
+ drawable->getVObj() && drawable->getVObj()->isSelected())
+ {
+ setBoostLevel(LLViewerTexture::BOOST_SELECTED);
+ }
+ addTextureStats(facep->getVirtualSize()) ;
+ setAdditionalDecodePriority(facep->getImportanceToCamera()) ;
+ }
+ }
+ }
}
}
+ //reset whether or not a face was selected after 10 seconds
+ const F32 SELECTION_RESET_TIME = 10.f;
+
+ if (getBoostLevel() == LLViewerTexture::BOOST_SELECTED &&
+ gFrameTimeSeconds - mSelectedTime > SELECTION_RESET_TIME)
+ {
+ setBoostLevel(LLViewerTexture::BOOST_NONE);
+ }
if(mMaxVirtualSizeResetCounter > 0)
{
@@ -1877,9 +1731,25 @@ S32 LLViewerFetchedTexture::getCurrentDiscardLevelForFetching()
return current_discard ;
}
+bool LLViewerFetchedTexture::setDebugFetching(S32 debug_level)
+{
+ if(debug_level < 0)
+ {
+ mInDebug = FALSE;
+ return false;
+ }
+ mInDebug = TRUE;
+
+ mDesiredDiscardLevel = debug_level;
+
+ return true;
+}
+
bool LLViewerFetchedTexture::updateFetch()
{
- static LLCachedControl<bool> textures_decode_disabled(gSavedSettings,"TextureDecodeDisabled");
+ static LLCachedControl<bool> textures_decode_disabled(gSavedSettings,"TextureDecodeDisabled", false);
+ static LLCachedControl<F32> sCameraMotionThreshold(gSavedSettings,"TextureCameraMotionThreshold", 0.2);
+ static LLCachedControl<S32> sCameraMotionBoost(gSavedSettings,"TextureCameraMotionBoost", 3);
if(textures_decode_disabled)
{
return false ;
@@ -1912,6 +1782,10 @@ bool LLViewerFetchedTexture::updateFetch()
{
return false; // process any raw image data in callbacks before replacing
}
+ if(mInFastCacheList)
+ {
+ return false;
+ }
S32 current_discard = getCurrentDiscardLevelForFetching() ;
S32 desired_discard = getDesiredDiscardLevel();
@@ -1960,6 +1834,7 @@ bool LLViewerFetchedTexture::updateFetch()
{
//discard all oversized textures.
destroyRawImage();
+ llwarns << "oversize, setting as missing" << llendl;
setIsMissingAsset();
mRawDiscardLevel = INVALID_DISCARD_LEVEL ;
mIsFetching = FALSE ;
@@ -1989,6 +1864,10 @@ bool LLViewerFetchedTexture::updateFetch()
// We finished but received no data
if (current_discard < 0)
{
+ llwarns << "!mIsFetching, setting as missing, decode_priority " << decode_priority
+ << " mRawDiscardLevel " << mRawDiscardLevel
+ << " current_discard " << current_discard
+ << llendl;
setIsMissingAsset();
desired_discard = -1;
}
@@ -2029,6 +1908,10 @@ bool LLViewerFetchedTexture::updateFetch()
{
make_request = false;
}
+ else if(mDesiredDiscardLevel > getMaxDiscardLevel())
+ {
+ make_request = false;
+ }
else if (mNeedsCreateTexture || mIsMissingAsset)
{
make_request = false;
@@ -2037,23 +1920,34 @@ bool LLViewerFetchedTexture::updateFetch()
{
make_request = false;
}
+ else if(mCachedRawImage.notNull() && (current_discard < 0 || current_discard > mCachedRawDiscardLevel))
+ {
+ make_request = false;
+ switchToCachedImage() ; //use the cached raw data first
+ }
//else if (!isJustBound() && mCachedRawImageReady)
//{
// make_request = false;
//}
- if(make_request)
+ if (make_request)
{
- //load the texture progressively.
- S32 delta_level = (mBoostLevel > LLViewerTexture::BOOST_NONE) ? 2 : 1 ;
- if(current_discard < 0)
+ // Load the texture progressively: we try not to rush to the desired discard too fast.
+ // If the camera is not moving, we do not tweak the discard level notch by notch but go to the desired discard with larger boosted steps
+ // This mitigates the "textures stay blurry" problem when loading while not killing the texture memory while moving around
+ S32 delta_level = (mBoostLevel > LLGLTexture::BOOST_NONE) ? 2 : 1 ;
+ if (current_discard < 0)
{
desired_discard = llmax(desired_discard, getMaxDiscardLevel() - delta_level);
}
- else
+ else if (LLViewerTexture::sCameraMovingBias < sCameraMotionThreshold)
{
- desired_discard = llmax(desired_discard, current_discard - delta_level);
+ desired_discard = llmax(desired_discard, current_discard - sCameraMotionBoost);
}
+ else
+ {
+ desired_discard = llmax(desired_discard, current_discard - delta_level);
+ }
if (mIsFetching)
{
@@ -2089,7 +1983,7 @@ bool LLViewerFetchedTexture::updateFetch()
// bypass texturefetch directly by pulling from LLTextureCache
bool fetch_request_created = false;
- fetch_request_created = LLAppViewer::getTextureFetch()->createRequest(mUrl, getID(),getTargetHost(), decode_priority,
+ fetch_request_created = LLAppViewer::getTextureFetch()->createRequest(mFTType, mUrl, getID(), getTargetHost(), decode_priority,
w, h, c, desired_discard, needsAux(), mCanUseHTTP);
if (fetch_request_created)
@@ -2106,11 +2000,13 @@ bool LLViewerFetchedTexture::updateFetch()
}
else if (mHasFetcher && !mIsFetching)
{
- // Only delete requests that haven't receeived any network data for a while
+ // Only delete requests that haven't received any network data
+ // for a while. Note - this is the normal mechanism for
+ // deleting requests, not just a place to handle timeouts.
const F32 FETCH_IDLE_TIME = 5.f;
if (mLastPacketTimer.getElapsedTimeF32() > FETCH_IDLE_TIME)
{
-// llinfos << "Deleting request: " << getID() << " Discard: " << current_discard << " <= min:" << mMinDiscardLevel << " or priority == 0: " << decode_priority << llendl;
+ LL_DEBUGS("Texture") << "exceeded idle time " << FETCH_IDLE_TIME << ", deleting request: " << getID() << llendl;
LLAppViewer::getTextureFetch()->deleteRequest(getID(), true);
mHasFetcher = FALSE;
}
@@ -2121,6 +2017,35 @@ bool LLViewerFetchedTexture::updateFetch()
return mIsFetching ? true : false;
}
+void LLViewerFetchedTexture::clearFetchedResults()
+{
+ if(mNeedsCreateTexture || mIsFetching)
+ {
+ return ;
+ }
+
+ cleanup();
+ destroyGLTexture();
+
+ if(getDiscardLevel() >= 0) //sculpty texture, force to invalidate
+ {
+ mGLTexturep->forceToInvalidateGLTexture();
+ }
+}
+
+void LLViewerFetchedTexture::forceToDeleteRequest()
+{
+ if (mHasFetcher)
+ {
+ mHasFetcher = FALSE;
+ mIsFetching = FALSE ;
+ }
+
+ resetTextureStats();
+
+ mDesiredDiscardLevel = getMaxDiscardLevel() + 1;
+}
+
void LLViewerFetchedTexture::setIsMissingAsset()
{
if (mUrl.empty())
@@ -2129,6 +2054,9 @@ void LLViewerFetchedTexture::setIsMissingAsset()
}
else
{
+ // This may or may not be an error - it is normal to have no
+ // map tile on an empty region, but bad if we're failing on a
+ // server bake texture.
llwarns << mUrl << ": Marking image as missing" << llendl;
}
if (mHasFetcher)
@@ -2161,10 +2089,18 @@ void LLViewerFetchedTexture::setLoadedCallback( loaded_callback_func loaded_call
mLoadedCallbackDesiredDiscardLevel = llmin(mLoadedCallbackDesiredDiscardLevel, (S8)discard_level) ;
}
- if(mPauseLoadedCallBacks && !pause)
+ if(mPauseLoadedCallBacks)
+ {
+ if(!pause)
+ {
+ unpauseLoadedCallbacks(src_callback_list) ;
+ }
+ }
+ else if(pause)
{
- unpauseLoadedCallbacks(src_callback_list) ;
+ pauseLoadedCallbacks(src_callback_list) ;
}
+
LLLoadedCallbackEntry* entryp = new LLLoadedCallbackEntry(loaded_callback, discard_level, keep_imageraw, userdata, src_callback_list, this, pause);
mLoadedCallbackList.push_back(entryp);
@@ -2254,7 +2190,7 @@ void LLViewerFetchedTexture::deleteCallbackEntry(const LLLoadedCallbackEntry::so
destroySavedRawImage() ;
}
}
- else if(needsToSaveRawImage() && mBoostLevel != LLViewerTexture::BOOST_PREVIEW)
+ else if(needsToSaveRawImage() && mBoostLevel != LLGLTexture::BOOST_PREVIEW)
{
if(desired_raw_discard != INVALID_DISCARD_LEVEL)
{
@@ -2712,7 +2648,7 @@ void LLViewerFetchedTexture::setCachedRawImage()
S32 h = mRawImage->getHeight() ;
S32 max_size = MAX_CACHED_RAW_IMAGE_AREA ;
- if(LLViewerTexture::BOOST_TERRAIN == mBoostLevel)
+ if(LLGLTexture::BOOST_TERRAIN == mBoostLevel)
{
max_size = MAX_CACHED_RAW_TERRAIN_IMAGE_AREA ;
}
@@ -2738,7 +2674,11 @@ void LLViewerFetchedTexture::setCachedRawImage()
--i ;
}
- mRawImage->scale(w >> i, h >> i) ;
+ {
+ //make a duplicate in case somebody else is using this raw image
+ mRawImage = mRawImage->duplicate();
+ mRawImage->scale(w >> i, h >> i) ;
+ }
}
mCachedRawImage = mRawImage ;
mRawDiscardLevel += i ;
@@ -2844,190 +2784,6 @@ F32 LLViewerFetchedTexture::getElapsedLastReferencedSavedRawImageTime() const
{
return sCurrentTime - mLastReferencedSavedRawImageTime ;
}
-//----------------------------------------------------------------------------------------------
-//atlasing
-//----------------------------------------------------------------------------------------------
-void LLViewerFetchedTexture::resetFaceAtlas()
-{
- //Nothing should be done here.
-}
-
-//invalidate all atlas slots for this image.
-void LLViewerFetchedTexture::invalidateAtlas(BOOL rebuild_geom)
-{
- for(U32 i = 0 ; i < mNumFaces ; i++)
- {
- LLFace* facep = mFaceList[i] ;
- facep->removeAtlas() ;
- if(rebuild_geom && facep->getDrawable() && facep->getDrawable()->getSpatialGroup())
- {
- facep->getDrawable()->getSpatialGroup()->setState(LLSpatialGroup::GEOM_DIRTY);
- }
- }
-}
-
-BOOL LLViewerFetchedTexture::insertToAtlas()
-{
- if(!LLViewerTexture::sUseTextureAtlas)
- {
- return FALSE ;
- }
- if(getNumFaces() < 1)
- {
- return FALSE ;
- }
- if(mGLTexturep->getDiscardLevelInAtlas() > 0 && mRawDiscardLevel >= mGLTexturep->getDiscardLevelInAtlas())
- {
- return FALSE ;
- }
- if(!LLTextureAtlasManager::getInstance()->canAddToAtlas(mRawImage->getWidth(), mRawImage->getHeight(), mRawImage->getComponents(), mGLTexturep->getTexTarget()))
- {
- return FALSE ;
- }
-
- BOOL ret = TRUE ;//if ret is set to false, will generate a gl texture for this image.
- S32 raw_w = mRawImage->getWidth() ;
- S32 raw_h = mRawImage->getHeight() ;
- F32 xscale = 1.0f, yscale = 1.0f ;
- LLPointer<LLTextureAtlasSlot> slot_infop;
- LLTextureAtlasSlot* cur_slotp ;//no need to be smart pointer.
- LLSpatialGroup* groupp ;
- LLFace* facep;
-
- //if the atlas slot pointers for some faces are null, process them later.
- ll_face_list_t waiting_list ;
- for(U32 i = 0 ; i < mNumFaces ; i++)
- {
- {
- facep = mFaceList[i] ;
-
- //face can not use atlas.
- if(!facep->canUseAtlas())
- {
- if(facep->getAtlasInfo())
- {
- facep->removeAtlas() ;
- }
- ret = FALSE ;
- continue ;
- }
-
- //the atlas slot is updated
- slot_infop = facep->getAtlasInfo() ;
- groupp = facep->getDrawable()->getSpatialGroup() ;
-
- if(slot_infop)
- {
- if(slot_infop->getSpatialGroup() != groupp)
- {
- if((cur_slotp = groupp->getCurUpdatingSlot(this))) //switch slot
- {
- facep->setAtlasInfo(cur_slotp) ;
- facep->setAtlasInUse(TRUE) ;
- continue ;
- }
- else //do not forget to update slot_infop->getSpatialGroup().
- {
- LLSpatialGroup* gp = slot_infop->getSpatialGroup() ;
- gp->setCurUpdatingTime(gFrameCount) ;
- gp->setCurUpdatingTexture(this) ;
- gp->setCurUpdatingSlot(slot_infop) ;
- }
- }
- else //same group
- {
- if(gFrameCount && slot_infop->getUpdatedTime() == gFrameCount)//slot is just updated
- {
- facep->setAtlasInUse(TRUE) ;
- continue ;
- }
- }
- }
- else
- {
- //if the slot is null, wait to process them later.
- waiting_list.push_back(facep) ;
- continue ;
- }
-
- //----------
- //insert to atlas
- if(!slot_infop->getAtlas()->insertSubTexture(mGLTexturep, mRawDiscardLevel, mRawImage, slot_infop->getSlotCol(), slot_infop->getSlotRow()))
- {
-
- //the texture does not qualify to add to atlas, do not bother to try for other faces.
- //invalidateAtlas();
- return FALSE ;
- }
-
- //update texture scale
- slot_infop->getAtlas()->getTexCoordScale(raw_w, raw_h, xscale, yscale) ;
- slot_infop->setTexCoordScale(xscale, yscale) ;
- slot_infop->setValid() ;
- slot_infop->setUpdatedTime(gFrameCount) ;
-
- //update spatial group atlas info
- groupp->setCurUpdatingTime(gFrameCount) ;
- groupp->setCurUpdatingTexture(this) ;
- groupp->setCurUpdatingSlot(slot_infop) ;
-
- //make the face to switch to the atlas.
- facep->setAtlasInUse(TRUE) ;
- }
- }
-
- //process the waiting_list
- for(std::vector<LLFace*>::iterator iter = waiting_list.begin(); iter != waiting_list.end(); ++iter)
- {
- facep = (LLFace*)*iter ;
- groupp = facep->getDrawable()->getSpatialGroup() ;
-
- //check if this texture already inserted to atlas for this group
- if((cur_slotp = groupp->getCurUpdatingSlot(this)))
- {
- facep->setAtlasInfo(cur_slotp) ;
- facep->setAtlasInUse(TRUE) ;
- continue ;
- }
-
- //need to reserve a slot from atlas
- slot_infop = LLTextureAtlasManager::getInstance()->reserveAtlasSlot(llmax(mFullWidth, mFullHeight), getComponents(), groupp, this) ;
-
- facep->setAtlasInfo(slot_infop) ;
-
- groupp->setCurUpdatingTime(gFrameCount) ;
- groupp->setCurUpdatingTexture(this) ;
- groupp->setCurUpdatingSlot(slot_infop) ;
-
- //slot allocation failed.
- if(!slot_infop || !slot_infop->getAtlas())
- {
- ret = FALSE ;
- facep->setAtlasInUse(FALSE) ;
- continue ;
- }
-
- //insert to atlas
- if(!slot_infop->getAtlas()->insertSubTexture(mGLTexturep, mRawDiscardLevel, mRawImage, slot_infop->getSlotCol(), slot_infop->getSlotRow()))
- {
- //the texture does not qualify to add to atlas, do not bother to try for other faces.
- ret = FALSE ;
- //invalidateAtlas();
- break ;
- }
-
- //update texture scale
- slot_infop->getAtlas()->getTexCoordScale(raw_w, raw_h, xscale, yscale) ;
- slot_infop->setTexCoordScale(xscale, yscale) ;
- slot_infop->setValid() ;
- slot_infop->setUpdatedTime(gFrameCount) ;
-
- //make the face to switch to the atlas.
- facep->setAtlasInUse(TRUE) ;
- }
-
- return ret ;
-}
//----------------------------------------------------------------------------------------------
//end of LLViewerFetchedTexture
@@ -3036,14 +2792,14 @@ BOOL LLViewerFetchedTexture::insertToAtlas()
//----------------------------------------------------------------------------------------------
//start of LLViewerLODTexture
//----------------------------------------------------------------------------------------------
-LLViewerLODTexture::LLViewerLODTexture(const LLUUID& id, const LLHost& host, BOOL usemipmaps)
- : LLViewerFetchedTexture(id, host, usemipmaps)
+LLViewerLODTexture::LLViewerLODTexture(const LLUUID& id, FTType f_type, const LLHost& host, BOOL usemipmaps)
+ : LLViewerFetchedTexture(id, f_type, host, usemipmaps)
{
init(TRUE) ;
}
-LLViewerLODTexture::LLViewerLODTexture(const std::string& url, const LLUUID& id, BOOL usemipmaps)
- : LLViewerFetchedTexture(url, id, usemipmaps)
+LLViewerLODTexture::LLViewerLODTexture(const std::string& url, FTType f_type, const LLUUID& id, BOOL usemipmaps)
+ : LLViewerFetchedTexture(url, f_type, id, usemipmaps)
{
init(TRUE) ;
}
@@ -3072,7 +2828,7 @@ void LLViewerLODTexture::processTextureStats()
{
updateVirtualSize() ;
- static LLCachedControl<bool> textures_fullres(gSavedSettings,"TextureLoadFullRes");
+ static LLCachedControl<bool> textures_fullres(gSavedSettings,"TextureLoadFullRes", false);
if (textures_fullres)
{
@@ -3085,7 +2841,7 @@ void LLViewerLODTexture::processTextureStats()
if (mFullWidth > MAX_IMAGE_SIZE_DEFAULT || mFullHeight > MAX_IMAGE_SIZE_DEFAULT)
mDesiredDiscardLevel = 1; // MAX_IMAGE_SIZE_DEFAULT = 1024 and max size ever is 2048
}
- else if (mBoostLevel < LLViewerTexture::BOOST_HIGH && mMaxVirtualSize <= 10.f)
+ else if (mBoostLevel < LLGLTexture::BOOST_HIGH && mMaxVirtualSize <= 10.f)
{
// If the image has not been significantly visible in a while, we don't want it
mDesiredDiscardLevel = llmin(mMinDesiredDiscardLevel, (S8)(MAX_DISCARD_LEVEL + 1));
@@ -3135,7 +2891,7 @@ void LLViewerLODTexture::processTextureStats()
mCalculatedDiscardLevel = discard_level;
}
}
- if (mBoostLevel < LLViewerTexture::BOOST_SCULPTED)
+ if (mBoostLevel < LLGLTexture::BOOST_SCULPTED)
{
discard_level += sDesiredDiscardBias;
discard_level *= sDesiredDiscardScale; // scale
@@ -3161,7 +2917,7 @@ void LLViewerLODTexture::processTextureStats()
//
S32 current_discard = getDiscardLevel();
- if (sDesiredDiscardBias > 0.0f && mBoostLevel < LLViewerTexture::BOOST_SCULPTED && current_discard >= 0)
+ if (sDesiredDiscardBias > 0.0f && mBoostLevel < LLGLTexture::BOOST_SCULPTED && current_discard >= 0)
{
if(desired_discard_bias_max <= sDesiredDiscardBias && !mForceToSaveRawImage)
{
@@ -3290,17 +3046,21 @@ LLViewerMediaTexture::LLViewerMediaTexture(const LLUUID& id, BOOL usemipmaps, LL
sMediaMap.insert(std::make_pair(id, this));
mGLTexturep = gl_image ;
+
if(mGLTexturep.isNull())
{
generateGLTexture() ;
}
+
+ mGLTexturep->setAllowCompression(false);
+
mGLTexturep->setNeedsAlphaAndPickMask(FALSE) ;
mIsPlaying = FALSE ;
setMediaImpl() ;
- setCategory(LLViewerTexture::MEDIA) ;
+ setCategory(LLGLTexture::MEDIA) ;
LLViewerTexture* tex = gTextureList.findImage(mID) ;
if(tex) //this media is a parcel media for tex.
@@ -3370,11 +3130,14 @@ BOOL LLViewerMediaTexture::findFaces()
LLViewerTexture* tex = gTextureList.findImage(mID) ;
if(tex) //this media is a parcel media for tex.
{
- const ll_face_list_t* face_list = tex->getFaceList() ;
- U32 end = tex->getNumFaces() ;
- for(U32 i = 0 ; i < end ; i++)
+ for (U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch)
{
- mMediaFaceList.push_back((*face_list)[i]) ;
+ const ll_face_list_t* face_list = tex->getFaceList(ch) ;
+ U32 end = tex->getNumFaces(ch) ;
+ for(U32 i = 0 ; i < end ; i++)
+ {
+ mMediaFaceList.push_back((*face_list)[i]) ;
+ }
}
}
@@ -3439,7 +3202,7 @@ void LLViewerMediaTexture::addMediaToFace(LLFace* facep)
return ; //no need to add the face because the media is not in playing.
}
- switchTexture(facep) ;
+ switchTexture(LLRender::DIFFUSE_MAP, facep) ;
}
void LLViewerMediaTexture::removeMediaFromFace(LLFace* facep)
@@ -3456,19 +3219,19 @@ void LLViewerMediaTexture::removeMediaFromFace(LLFace* facep)
}
mIsPlaying = FALSE ; //set to remove the media from the face.
- switchTexture(facep) ;
+ switchTexture(LLRender::DIFFUSE_MAP, facep) ;
mIsPlaying = TRUE ; //set the flag back.
- if(getNumFaces() < 1) //no face referencing to this media
+ if(getTotalNumFaces() < 1) //no face referencing to this media
{
stopPlaying() ;
}
}
//virtual
-void LLViewerMediaTexture::addFace(LLFace* facep)
+void LLViewerMediaTexture::addFace(U32 ch, LLFace* facep)
{
- LLViewerTexture::addFace(facep) ;
+ LLViewerTexture::addFace(ch, facep) ;
const LLTextureEntry* te = facep->getTextureEntry() ;
if(te && te->getID().notNull())
@@ -3495,9 +3258,9 @@ void LLViewerMediaTexture::addFace(LLFace* facep)
}
//virtual
-void LLViewerMediaTexture::removeFace(LLFace* facep)
+void LLViewerMediaTexture::removeFace(U32 ch, LLFace* facep)
{
- LLViewerTexture::removeFace(facep) ;
+ LLViewerTexture::removeFace(ch, facep) ;
const LLTextureEntry* te = facep->getTextureEntry() ;
if(te && te->getID().notNull())
@@ -3515,24 +3278,35 @@ void LLViewerMediaTexture::removeFace(LLFace* facep)
}
}
- //
- //we have some trouble here: the texture of the face is changed.
- //we need to find the former texture, and remove it from the list to avoid memory leaking.
- if(!mNumFaces)
+ std::vector<const LLTextureEntry*> te_list;
+
+ for (U32 ch = 0; ch < 3; ++ch)
{
- mTextureList.clear() ;
- return ;
+ //
+ //we have some trouble here: the texture of the face is changed.
+ //we need to find the former texture, and remove it from the list to avoid memory leaking.
+
+ llassert(mNumFaces[ch] <= mFaceList[ch].size());
+
+ for(U32 j = 0 ; j < mNumFaces[ch] ; j++)
+ {
+ te_list.push_back(mFaceList[ch][j]->getTextureEntry());//all textures are in use.
+ }
}
- S32 end = getNumFaces() ;
- std::vector<const LLTextureEntry*> te_list(end) ;
- S32 i = 0 ;
- for(U32 j = 0 ; j < mNumFaces ; j++)
+
+ if (te_list.empty())
{
- te_list[i++] = mFaceList[j]->getTextureEntry() ;//all textures are in use.
+ mTextureList.clear() ;
+ return ;
}
+
+ S32 end = te_list.size();
+
for(std::list< LLPointer<LLViewerTexture> >::iterator iter = mTextureList.begin();
iter != mTextureList.end(); ++iter)
{
+ S32 i = 0;
+
for(i = 0 ; i < end ; i++)
{
if(te_list[i] && te_list[i]->getID() == (*iter)->getID())//the texture is in use.
@@ -3577,7 +3351,7 @@ void LLViewerMediaTexture::stopPlaying()
mIsPlaying = FALSE ;
}
-void LLViewerMediaTexture::switchTexture(LLFace* facep)
+void LLViewerMediaTexture::switchTexture(U32 ch, LLFace* facep)
{
if(facep)
{
@@ -3593,7 +3367,7 @@ void LLViewerMediaTexture::switchTexture(LLFace* facep)
if(mIsPlaying) //old textures switch to the media texture
{
- facep->switchTexture(this) ;
+ facep->switchTexture(ch, this) ;
}
else //switch to old textures.
{
@@ -3609,7 +3383,7 @@ void LLViewerMediaTexture::switchTexture(LLFace* facep)
{
tex = LLViewerFetchedTexture::sDefaultImagep ;
}
- facep->switchTexture(tex) ;
+ facep->switchTexture(ch, tex) ;
}
}
}
@@ -3648,14 +3422,17 @@ void LLViewerMediaTexture::setPlaying(BOOL playing)
for(std::list< LLFace* >::iterator iter = mMediaFaceList.begin(); iter!= mMediaFaceList.end(); ++iter)
{
- switchTexture(*iter) ;
+ switchTexture(LLRender::DIFFUSE_MAP, *iter) ;
}
}
else //stop playing this media
{
- for(U32 i = mNumFaces ; i ; i--)
+ U32 ch = LLRender::DIFFUSE_MAP;
+
+ llassert(mNumFaces[ch] <= mFaceList[ch].size());
+ for(U32 i = mNumFaces[ch] ; i ; i--)
{
- switchTexture(mFaceList[i - 1]) ; //current face could be removed in this function.
+ switchTexture(ch, mFaceList[ch][i - 1]) ; //current face could be removed in this function.
}
}
return ;
@@ -3677,14 +3454,18 @@ F32 LLViewerMediaTexture::getMaxVirtualSize()
if(mIsPlaying) //media is playing
{
- for(U32 i = 0 ; i < mNumFaces ; i++)
+ for (U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch)
{
- LLFace* facep = mFaceList[i] ;
- if(facep->getDrawable()->isRecentlyVisible())
+ llassert(mNumFaces[ch] <= mFaceList[ch].size());
+ for(U32 i = 0 ; i < mNumFaces[ch] ; i++)
{
- addTextureStats(facep->getVirtualSize()) ;
- }
- }
+ LLFace* facep = mFaceList[ch][i] ;
+ if(facep->getDrawable()->isRecentlyVisible())
+ {
+ addTextureStats(facep->getVirtualSize()) ;
+ }
+ }
+ }
}
else //media is not in playing
{
diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h
index b96441127d..10101a4b9b 100644..100755
--- a/indra/newview/llviewertexture.h
+++ b/indra/newview/llviewertexture.h
@@ -27,13 +27,14 @@
#ifndef LL_LLVIEWERTEXTURE_H
#define LL_LLVIEWERTEXTURE_H
-#include "lltexture.h"
+#include "llgltexture.h"
#include "lltimer.h"
#include "llframetimer.h"
#include "llhost.h"
#include "llgltypes.h"
#include "llrender.h"
#include "llmetricperformancetester.h"
+#include "llface.h"
#include <map>
#include <list>
@@ -41,7 +42,6 @@
#define MIN_VIDEO_RAM_IN_MEGA_BYTES 32
#define MAX_VIDEO_RAM_IN_MEGA_BYTES 512 // 512MB max for performance reasons.
-class LLFace;
class LLImageGL ;
class LLImageRaw;
class LLViewerObject;
@@ -88,60 +88,19 @@ public:
class LLTextureBar;
-class LLViewerTexture : public LLTexture
+class LLViewerTexture : public LLGLTexture
{
public:
enum
{
- MAX_IMAGE_SIZE_DEFAULT = 1024,
- INVALID_DISCARD_LEVEL = 0x7fff
- };
- enum
- {
LOCAL_TEXTURE,
MEDIA_TEXTURE,
DYNAMIC_TEXTURE,
FETCHED_TEXTURE,
LOD_TEXTURE,
- ATLAS_TEXTURE,
INVALID_TEXTURE_TYPE
};
- enum EBoostLevel
- {
- BOOST_NONE = 0,
- BOOST_AVATAR_BAKED ,
- BOOST_AVATAR ,
- BOOST_CLOUDS ,
- BOOST_SCULPTED ,
-
- BOOST_HIGH = 10,
- BOOST_BUMP ,
- BOOST_TERRAIN , // has to be high priority for minimap / low detail
- BOOST_SELECTED ,
- BOOST_AVATAR_BAKED_SELF ,
- BOOST_AVATAR_SELF , // needed for baking avatar
- BOOST_SUPER_HIGH , //textures higher than this need to be downloaded at the required resolution without delay.
- BOOST_HUD ,
- BOOST_ICON ,
- BOOST_UI ,
- BOOST_PREVIEW ,
- BOOST_MAP ,
- BOOST_MAP_VISIBLE ,
- BOOST_MAX_LEVEL,
-
- //other texture Categories
- LOCAL = BOOST_MAX_LEVEL,
- AVATAR_SCRATCH_TEX,
- DYNAMIC_TEX,
- MEDIA,
- ATLAS,
- OTHER,
- MAX_GL_IMAGE_CATEGORY
- };
- static S32 getTotalNumOfCategories() ;
- static S32 getIndexFromCategory(S32 category) ;
- static S32 getCategoryFromIndex(S32 index) ;
typedef std::vector<LLFace*> ll_face_list_t;
typedef std::vector<LLVOVolume*> ll_volume_list_t;
@@ -167,8 +126,7 @@ public:
/*virtual*/ bool bindDefaultImage(const S32 stage = 0) ;
/*virtual*/ void forceImmediateUpdate() ;
- const LLUUID& getID() const { return mID; }
-
+ /*virtual*/ const LLUUID& getID() const { return mID; }
void setBoostLevel(S32 level);
S32 getBoostLevel() { return mBoostLevel; }
@@ -176,6 +134,7 @@ public:
void resetTextureStats();
void setMaxVirtualSizeResetInterval(S32 interval)const {mMaxVirtualSizeResetInterval = interval;}
void resetMaxVirtualSizeResetCounter()const {mMaxVirtualSizeResetCounter = mMaxVirtualSizeResetInterval;}
+ S32 getMaxVirtualSizeResetCounter() const { return mMaxVirtualSizeResetCounter; }
virtual F32 getMaxVirtualSize() ;
@@ -185,70 +144,19 @@ public:
S32 getFullHeight() const { return mFullHeight; }
/*virtual*/ void setKnownDrawSize(S32 width, S32 height);
- virtual void addFace(LLFace* facep) ;
- virtual void removeFace(LLFace* facep) ;
- S32 getNumFaces() const;
- const ll_face_list_t* getFaceList() const {return &mFaceList;}
+ virtual void addFace(U32 channel, LLFace* facep) ;
+ virtual void removeFace(U32 channel, LLFace* facep) ;
+ S32 getTotalNumFaces() const;
+ S32 getNumFaces(U32 ch) const;
+ const ll_face_list_t* getFaceList(U32 channel) const {llassert(channel < LLRender::NUM_TEXTURE_CHANNELS); return &mFaceList[channel];}
virtual void addVolume(LLVOVolume* volumep);
virtual void removeVolume(LLVOVolume* volumep);
S32 getNumVolumes() const;
const ll_volume_list_t* getVolumeList() const { return &mVolumeList; }
- void generateGLTexture() ;
- void destroyGLTexture() ;
-
- //---------------------------------------------------------------------------------------------
- //functions to access LLImageGL
- //---------------------------------------------------------------------------------------------
- /*virtual*/S32 getWidth(S32 discard_level = -1) const;
- /*virtual*/S32 getHeight(S32 discard_level = -1) const;
- BOOL hasGLTexture() const ;
- LLGLuint getTexName() const ;
- BOOL createGLTexture() ;
- BOOL createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename = 0, BOOL to_create = TRUE, S32 category = LLViewerTexture::OTHER);
virtual void setCachedRawImage(S32 discard_level, LLImageRaw* imageraw) ;
-
- void setFilteringOption(LLTexUnit::eTextureFilterOptions option);
- void setExplicitFormat(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format = 0, BOOL swap_bytes = FALSE);
- void setAddressMode(LLTexUnit::eTextureAddressMode mode);
- BOOL setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height);
- BOOL setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height);
- void setGLTextureCreated (bool initialized);
- void setCategory(S32 category) ;
-
- LLTexUnit::eTextureAddressMode getAddressMode(void) const ;
- S32 getMaxDiscardLevel() const;
- S32 getDiscardLevel() const;
- S8 getComponents() const ;
- BOOL getBoundRecently() const;
- S32 getTextureMemory() const ;
- LLGLenum getPrimaryFormat() const;
- BOOL getIsAlphaMask() const ;
- LLTexUnit::eTextureType getTarget(void) const ;
- BOOL getMask(const LLVector2 &tc);
- F32 getTimePassedSinceLastBound();
- BOOL getMissed() const ;
- BOOL isJustBound()const ;
- void forceUpdateBindStats(void) const;
-
- U32 getTexelsInAtlas() const ;
- U32 getTexelsInGLTexture() const ;
- BOOL isGLTextureCreated() const ;
- S32 getDiscardLevelInAtlas() const ;
- //---------------------------------------------------------------------------------------------
- //end of functions to access LLImageGL
- //---------------------------------------------------------------------------------------------
-
- //-----------------
- /*virtual*/ void setActive() ;
- void forceActive() ;
- void setNoDelete() ;
- void dontDiscard() { mDontDiscard = 1; mTextureState = NO_DELETE; }
- BOOL getDontDiscard() const { return mDontDiscard; }
- //-----------------
-
BOOL isLargeImage() ;
void setParcelMedia(LLViewerMediaTexture* media) {mParcelMedia = media;}
@@ -261,34 +169,24 @@ protected:
void init(bool firstinit) ;
void reorganizeFaceList() ;
void reorganizeVolumeList() ;
- void setTexelsPerImage();
private:
- //note: do not make this function public.
- /*virtual*/ LLImageGL* getGLTexture() const ;
+ friend class LLBumpImageList;
+ friend class LLUIImageList;
+
virtual void switchToCachedImage();
static bool isMemoryForTextureLow() ;
protected:
LLUUID mID;
- S32 mBoostLevel; // enum describing priority level
- S32 mFullWidth;
- S32 mFullHeight;
- BOOL mUseMipMaps ;
- S8 mComponents;
- F32 mTexelsPerImage; // Texels per image.
- mutable S8 mNeedsGLTexture;
+ F32 mSelectedTime; // time texture was last selected
mutable F32 mMaxVirtualSize; // The largest virtual size of the image, in pixels - how much data to we need?
mutable S32 mMaxVirtualSizeResetCounter ;
mutable S32 mMaxVirtualSizeResetInterval;
mutable F32 mAdditionalDecodePriority; // priority add to mDecodePriority.
LLFrameTimer mLastReferencedTimer;
- //GL texture
- LLPointer<LLImageGL> mGLTexturep ;
- S8 mDontDiscard; // Keep full res version of this image (for UI, etc)
-
- ll_face_list_t mFaceList ; //reverse pointer pointing to the faces using this image as texture
- U32 mNumFaces ;
+ ll_face_list_t mFaceList[LLRender::NUM_TEXTURE_CHANNELS]; //reverse pointer pointing to the faces using this image as texture
+ U32 mNumFaces[LLRender::NUM_TEXTURE_CHANNELS];
LLFrameTimer mLastFaceListUpdateTimer ;
ll_volume_list_t mVolumeList;
@@ -298,17 +196,7 @@ protected:
//do not use LLPointer here.
LLViewerMediaTexture* mParcelMedia ;
-protected:
- typedef enum
- {
- DELETED = 0, //removed from memory
- DELETION_CANDIDATE, //ready to be removed from memory
- INACTIVE, //not be used for the last certain period (i.e., 30 seconds).
- ACTIVE, //just being used, can become inactive if not being used for a certain time (10 seconds).
- NO_DELETE = 99 //stay in memory, can not be removed.
- } LLGLTextureState;
- LLGLTextureState mTextureState ;
-
+ static F32 sTexelPixelRatio;
public:
static const U32 sCurrentFileVersion;
static S32 sImageCount;
@@ -323,18 +211,39 @@ public:
static S32 sMaxTotalTextureMemInMegaBytes;
static S32 sMaxDesiredTextureMemInBytes ;
static S8 sCameraMovingDiscardBias;
+ static F32 sCameraMovingBias;
static S32 sMaxSculptRez ;
static S32 sMinLargeImageSize ;
static S32 sMaxSmallImageSize ;
static BOOL sFreezeImageScalingDown ;//do not scale down image res if set.
static F32 sCurrentTime ;
- static BOOL sUseTextureAtlas ;
+
+ enum EDebugTexels
+ {
+ DEBUG_TEXELS_OFF,
+ DEBUG_TEXELS_CURRENT,
+ DEBUG_TEXELS_DESIRED,
+ DEBUG_TEXELS_FULL
+ };
+
+ static EDebugTexels sDebugTexelsMode;
static LLPointer<LLViewerTexture> sNullImagep; // Null texture for non-textured objects.
static LLPointer<LLViewerTexture> sBlackImagep; // Texture to show NOTHING (pure black)
+ static LLPointer<LLViewerTexture> sCheckerBoardImagep; // Texture to show NOTHING (pure black)
};
+enum FTType
+{
+ FTT_UNKNOWN = -1,
+ FTT_DEFAULT = 0, // standard texture fetched by id.
+ FTT_SERVER_BAKE, // texture produced by appearance service and fetched from there.
+ FTT_HOST_BAKE, // old-style baked texture uploaded by viewer and fetched from avatar's host.
+ FTT_MAP_TILE, // tiles are fetched from map server directly.
+ FTT_LOCAL_FILE // fetch directly from a local file.
+};
+
//
//textures are managed in gTextureList.
//raw image data is fetched from remote or local cache
@@ -348,9 +257,9 @@ class LLViewerFetchedTexture : public LLViewerTexture
protected:
/*virtual*/ ~LLViewerFetchedTexture();
public:
- LLViewerFetchedTexture(const LLUUID& id, const LLHost& host = LLHost::invalid, BOOL usemipmaps = TRUE);
- LLViewerFetchedTexture(const LLImageRaw* raw, BOOL usemipmaps);
- LLViewerFetchedTexture(const std::string& url, const LLUUID& id, BOOL usemipmaps = TRUE);
+ LLViewerFetchedTexture(const LLUUID& id, FTType f_type, const LLHost& host = LLHost::invalid, BOOL usemipmaps = TRUE);
+ LLViewerFetchedTexture(const LLImageRaw* raw, FTType f_type, BOOL usemipmaps);
+ LLViewerFetchedTexture(const std::string& url, FTType f_type, const LLUUID& id, BOOL usemipmaps = TRUE);
public:
static F32 maxDecodePriority();
@@ -375,6 +284,7 @@ public:
public:
/*virtual*/ S8 getType() const ;
+ FTType getFTType() const;
/*virtual*/ void forceImmediateUpdate() ;
/*virtual*/ void dump() ;
@@ -410,6 +320,7 @@ public:
// the priority list, and cause horrible things to happen.
void setDecodePriority(F32 priority = -1.0f);
F32 getDecodePriority() const { return mDecodePriority; };
+ F32 getAdditionalDecodePriority() const { return mAdditionalDecodePriority; };
void setAdditionalDecodePriority(F32 priority) ;
@@ -419,7 +330,11 @@ public:
void setMinDiscardLevel(S32 discard) { mMinDesiredDiscardLevel = llmin(mMinDesiredDiscardLevel,(S8)discard); }
bool updateFetch();
+ bool setDebugFetching(S32 debug_level);
+ bool isInDebug() {return mInDebug;}
+ void clearFetchedResults(); //clear all fetched results, for debug use.
+
// Override the computation of discard levels if we know the exact output
// size of the image. Used for UI textures to not decode, even if we have
// more data.
@@ -478,6 +393,10 @@ public:
BOOL hasFetcher() const { return mHasFetcher;}
void setCanUseHTTP(bool can_use_http) {mCanUseHTTP = can_use_http;}
+ void forceToDeleteRequest();
+ void loadFromFastCache();
+ void setInFastCacheList(bool in_list) { mInFastCacheList = in_list; }
+ bool isInFastCacheList() { return mInFastCacheList; }
protected:
/*virtual*/ void switchToCachedImage();
S32 getCurrentDiscardLevelForFetching() ;
@@ -489,13 +408,10 @@ private:
void saveRawImage() ;
void setCachedRawImage() ;
- //for atlas
- void resetFaceAtlas() ;
- void invalidateAtlas(BOOL rebuild_geom) ;
- BOOL insertToAtlas() ;
-
private:
BOOL mFullyLoaded;
+ BOOL mInDebug;
+ BOOL mInFastCacheList;
protected:
std::string mLocalFileName;
@@ -529,6 +445,7 @@ protected:
S8 mIsFetching; // Fetch request is active
bool mCanUseHTTP ; //This texture can be fetched through http if true.
+ FTType mFTType; // What category of image is this - map tile, server bake, etc?
mutable S8 mIsMissingAsset; // True if we know that there is no image asset with this image id in the database.
typedef std::list<LLLoadedCallbackEntry*> callback_list_t;
@@ -576,6 +493,7 @@ public:
static LLPointer<LLViewerFetchedTexture> sWhiteImagep; // Texture to show NOTHING (whiteness)
static LLPointer<LLViewerFetchedTexture> sDefaultImagep; // "Default" texture for error cases, the only case of fetched texture which is generated in local.
static LLPointer<LLViewerFetchedTexture> sSmokeImagep; // Old "Default" translucent texture
+ static LLPointer<LLViewerFetchedTexture> sFlatNormalImagep; // Flat normal map denoting no bumpiness on a surface
};
//
@@ -588,8 +506,8 @@ protected:
/*virtual*/ ~LLViewerLODTexture(){}
public:
- LLViewerLODTexture(const LLUUID& id, const LLHost& host = LLHost::invalid, BOOL usemipmaps = TRUE);
- LLViewerLODTexture(const std::string& url, const LLUUID& id, BOOL usemipmaps = TRUE);
+ LLViewerLODTexture(const LLUUID& id, FTType f_type, const LLHost& host = LLHost::invalid, BOOL usemipmaps = TRUE);
+ LLViewerLODTexture(const std::string& url, FTType f_type, const LLUUID& id, BOOL usemipmaps = TRUE);
/*virtual*/ S8 getType() const;
// Process image stats to determine priority/quality requirements.
@@ -633,12 +551,12 @@ public:
void addMediaToFace(LLFace* facep) ;
void removeMediaFromFace(LLFace* facep) ;
- /*virtual*/ void addFace(LLFace* facep) ;
- /*virtual*/ void removeFace(LLFace* facep) ;
+ /*virtual*/ void addFace(U32 ch, LLFace* facep) ;
+ /*virtual*/ void removeFace(U32 ch, LLFace* facep) ;
/*virtual*/ F32 getMaxVirtualSize() ;
private:
- void switchTexture(LLFace* facep) ;
+ void switchTexture(U32 ch, LLFace* facep) ;
BOOL findFaces() ;
void stopPlaying() ;
@@ -687,6 +605,7 @@ public:
//"find-texture" just check if the texture exists, if yes, return it, otherwise return null.
//
static LLViewerTexture* findTexture(const LLUUID& id) ;
+ static LLViewerFetchedTexture* findFetchedTexture(const LLUUID& id) ;
static LLViewerMediaTexture* findMediaTexture(const LLUUID& id) ;
static LLViewerMediaTexture* createMediaTexture(const LLUUID& id, BOOL usemipmaps = TRUE, LLImageGL* gl_image = NULL) ;
@@ -702,8 +621,9 @@ public:
static LLPointer<LLViewerTexture> getLocalTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps, BOOL generate_gl_tex = TRUE) ;
static LLViewerFetchedTexture* getFetchedTexture(const LLUUID &image_id,
+ FTType f_type = FTT_DEFAULT,
BOOL usemipmap = TRUE,
- LLViewerTexture::EBoostLevel boost_priority = LLViewerTexture::BOOST_NONE, // Get the requested level immediately upon creation.
+ LLViewerTexture::EBoostLevel boost_priority = LLGLTexture::BOOST_NONE, // Get the requested level immediately upon creation.
S8 texture_type = LLViewerTexture::FETCHED_TEXTURE,
LLGLint internal_format = 0,
LLGLenum primary_format = 0,
@@ -711,8 +631,9 @@ public:
);
static LLViewerFetchedTexture* getFetchedTextureFromFile(const std::string& filename,
+ FTType f_type = FTT_LOCAL_FILE,
BOOL usemipmap = TRUE,
- LLViewerTexture::EBoostLevel boost_priority = LLViewerTexture::BOOST_NONE,
+ LLViewerTexture::EBoostLevel boost_priority = LLGLTexture::BOOST_NONE,
S8 texture_type = LLViewerTexture::FETCHED_TEXTURE,
LLGLint internal_format = 0,
LLGLenum primary_format = 0,
@@ -720,15 +641,16 @@ public:
);
static LLViewerFetchedTexture* getFetchedTextureFromUrl(const std::string& url,
+ FTType f_type,
BOOL usemipmap = TRUE,
- LLViewerTexture::EBoostLevel boost_priority = LLViewerTexture::BOOST_NONE,
+ LLViewerTexture::EBoostLevel boost_priority = LLGLTexture::BOOST_NONE,
S8 texture_type = LLViewerTexture::FETCHED_TEXTURE,
LLGLint internal_format = 0,
LLGLenum primary_format = 0,
const LLUUID& force_id = LLUUID::null
);
- static LLViewerFetchedTexture* getFetchedTextureFromHost(const LLUUID& image_id, LLHost host) ;
+ static LLViewerFetchedTexture* getFetchedTextureFromHost(const LLUUID& image_id, FTType f_type, LLHost host) ;
static void init() ;
static void cleanup() ;
diff --git a/indra/newview/llviewertextureanim.cpp b/indra/newview/llviewertextureanim.cpp
index 9f1ac7c49c..2b364851a7 100644..100755
--- a/indra/newview/llviewertextureanim.cpp
+++ b/indra/newview/llviewertextureanim.cpp
@@ -27,21 +27,37 @@
#include "llviewerprecompiledheaders.h"
#include "llviewertextureanim.h"
+#include "llvovolume.h"
#include "llmath.h"
#include "llerror.h"
-LLViewerTextureAnim::LLViewerTextureAnim() : LLTextureAnim()
+std::vector<LLViewerTextureAnim*> LLViewerTextureAnim::sInstanceList;
+
+LLViewerTextureAnim::LLViewerTextureAnim(LLVOVolume* vobj) : LLTextureAnim()
{
+ mVObj = vobj;
mLastFrame = -1.f; // Force an update initially
mLastTime = 0.f;
mOffS = mOffT = 0;
mScaleS = mScaleT = 1;
mRot = 0;
+
+ mInstanceIndex = sInstanceList.size();
+ sInstanceList.push_back(this);
}
LLViewerTextureAnim::~LLViewerTextureAnim()
{
+ S32 end_idx = sInstanceList.size()-1;
+
+ if (end_idx != mInstanceIndex)
+ {
+ sInstanceList[mInstanceIndex] = sInstanceList[end_idx];
+ sInstanceList[mInstanceIndex]->mInstanceIndex = mInstanceIndex;
+ }
+
+ sInstanceList.pop_back();
}
void LLViewerTextureAnim::reset()
@@ -50,6 +66,14 @@ void LLViewerTextureAnim::reset()
mTimer.reset();
}
+//static
+void LLViewerTextureAnim::updateClass()
+{
+ for (std::vector<LLViewerTextureAnim*>::iterator iter = sInstanceList.begin(); iter != sInstanceList.end(); ++iter)
+ {
+ (*iter)->mVObj->animateTextures();
+ }
+}
S32 LLViewerTextureAnim::animateTextures(F32 &off_s, F32 &off_t,
F32 &scale_s, F32 &scale_t,
diff --git a/indra/newview/llviewertextureanim.h b/indra/newview/llviewertextureanim.h
index dd7bd0cb90..abbfabceb9 100644..100755
--- a/indra/newview/llviewertextureanim.h
+++ b/indra/newview/llviewertextureanim.h
@@ -30,10 +30,18 @@
#include "lltextureanim.h"
#include "llframetimer.h"
+class LLVOVolume;
+
class LLViewerTextureAnim : public LLTextureAnim
{
+private:
+ static std::vector<LLViewerTextureAnim*> sInstanceList;
+ S32 mInstanceIndex;
+
public:
- LLViewerTextureAnim();
+ static void updateClass();
+
+ LLViewerTextureAnim(LLVOVolume* vobj);
virtual ~LLViewerTextureAnim();
/*virtual*/ void reset();
@@ -51,6 +59,7 @@ public:
F32 mRot;
protected:
+ LLVOVolume* mVObj;
LLFrameTimer mTimer;
F64 mLastTime;
F32 mLastFrame;
diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp
index 089f45ca89..783d1f2202 100644..100755
--- a/indra/newview/llviewertexturelist.cpp
+++ b/indra/newview/llviewertexturelist.cpp
@@ -58,6 +58,7 @@
#include "pipeline.h"
#include "llappviewer.h"
#include "llxuiparser.h"
+#include "llviewerdisplay.h"
////////////////////////////////////////////////////////////////////////////
@@ -66,12 +67,12 @@ void (*LLViewerTextureList::sUUIDCallback)(void **, const LLUUID&) = NULL;
U32 LLViewerTextureList::sTextureBits = 0;
U32 LLViewerTextureList::sTexturePackets = 0;
S32 LLViewerTextureList::sNumImages = 0;
-LLStat LLViewerTextureList::sNumImagesStat(32, TRUE);
-LLStat LLViewerTextureList::sNumRawImagesStat(32, TRUE);
-LLStat LLViewerTextureList::sGLTexMemStat(32, TRUE);
-LLStat LLViewerTextureList::sGLBoundMemStat(32, TRUE);
-LLStat LLViewerTextureList::sRawMemStat(32, TRUE);
-LLStat LLViewerTextureList::sFormattedMemStat(32, TRUE);
+LLStat LLViewerTextureList::sNumImagesStat("Num Images", 32, TRUE);
+LLStat LLViewerTextureList::sNumRawImagesStat("Num Raw Images", 32, TRUE);
+LLStat LLViewerTextureList::sGLTexMemStat("GL Texture Mem", 32, TRUE);
+LLStat LLViewerTextureList::sGLBoundMemStat("GL Bound Mem", 32, TRUE);
+LLStat LLViewerTextureList::sRawMemStat("Raw Image Mem", 32, TRUE);
+LLStat LLViewerTextureList::sFormattedMemStat("Formatted Image Mem", 32, TRUE);
LLViewerTextureList gTextureList;
static LLFastTimer::DeclareTimer FTM_PROCESS_IMAGES("Process Images");
@@ -111,13 +112,16 @@ void LLViewerTextureList::doPreloadImages()
llassert_always(mUUIDMap.empty()) ;
// Set the "missing asset" image
- LLViewerFetchedTexture::sMissingAssetImagep = LLViewerTextureManager::getFetchedTextureFromFile("missing_asset.tga", MIPMAP_NO, LLViewerFetchedTexture::BOOST_UI);
+ LLViewerFetchedTexture::sMissingAssetImagep = LLViewerTextureManager::getFetchedTextureFromFile("missing_asset.tga", FTT_LOCAL_FILE, MIPMAP_NO, LLViewerFetchedTexture::BOOST_UI);
// Set the "white" image
- LLViewerFetchedTexture::sWhiteImagep = LLViewerTextureManager::getFetchedTextureFromFile("white.tga", MIPMAP_NO, LLViewerFetchedTexture::BOOST_UI);
+ LLViewerFetchedTexture::sWhiteImagep = LLViewerTextureManager::getFetchedTextureFromFile("white.tga", FTT_LOCAL_FILE, MIPMAP_NO, LLViewerFetchedTexture::BOOST_UI);
LLTexUnit::sWhiteTexture = LLViewerFetchedTexture::sWhiteImagep->getTexName();
LLUIImageList* image_list = LLUIImageList::getInstance();
+ // Set the default flat normal map
+ LLViewerFetchedTexture::sFlatNormalImagep = LLViewerTextureManager::getFetchedTextureFromFile("flatnormal.tga", FTT_LOCAL_FILE, MIPMAP_NO, LLViewerFetchedTexture::BOOST_BUMP);
+
image_list->initFromFile();
// turn off clamping and bilinear filtering for uv picking images
@@ -129,33 +133,33 @@ void LLViewerTextureList::doPreloadImages()
//uv_test->setMipFilterNearest(TRUE, TRUE);
// prefetch specific UUIDs
- LLViewerTextureManager::getFetchedTexture(IMG_SHOT, TRUE);
- LLViewerTextureManager::getFetchedTexture(IMG_SMOKE_POOF, TRUE);
- LLViewerFetchedTexture* image = LLViewerTextureManager::getFetchedTextureFromFile("silhouette.j2c", MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI);
+ LLViewerTextureManager::getFetchedTexture(IMG_SHOT);
+ LLViewerTextureManager::getFetchedTexture(IMG_SMOKE_POOF);
+ LLViewerFetchedTexture* image = LLViewerTextureManager::getFetchedTextureFromFile("silhouette.j2c", FTT_LOCAL_FILE, MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI);
if (image)
{
image->setAddressMode(LLTexUnit::TAM_WRAP);
mImagePreloads.insert(image);
}
- image = LLViewerTextureManager::getFetchedTextureFromFile("world/NoEntryLines.png", MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI);
+ image = LLViewerTextureManager::getFetchedTextureFromFile("world/NoEntryLines.png", FTT_LOCAL_FILE, MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI);
if (image)
{
image->setAddressMode(LLTexUnit::TAM_WRAP);
mImagePreloads.insert(image);
}
- image = LLViewerTextureManager::getFetchedTextureFromFile("world/NoEntryPassLines.png", MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI);
+ image = LLViewerTextureManager::getFetchedTextureFromFile("world/NoEntryPassLines.png", FTT_LOCAL_FILE, MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI);
if (image)
{
image->setAddressMode(LLTexUnit::TAM_WRAP);
mImagePreloads.insert(image);
}
- image = LLViewerTextureManager::getFetchedTexture(DEFAULT_WATER_NORMAL, MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI);
+ image = LLViewerTextureManager::getFetchedTexture(DEFAULT_WATER_NORMAL, FTT_DEFAULT, MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI);
if (image)
{
image->setAddressMode(LLTexUnit::TAM_WRAP);
mImagePreloads.insert(image);
}
- image = LLViewerTextureManager::getFetchedTextureFromFile("transparent.j2c", MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI, LLViewerTexture::FETCHED_TEXTURE,
+ image = LLViewerTextureManager::getFetchedTextureFromFile("transparent.j2c", FTT_LOCAL_FILE, MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI, LLViewerTexture::FETCHED_TEXTURE,
0,0,LLUUID("8dcd4a48-2d37-4909-9f78-f7a9eb4ef903"));
if (image)
{
@@ -197,7 +201,7 @@ void LLViewerTextureList::doPrefetchImages()
if(LLViewerTexture::FETCHED_TEXTURE == texture_type || LLViewerTexture::LOD_TEXTURE == texture_type)
{
- LLViewerFetchedTexture* image = LLViewerTextureManager::getFetchedTexture(uuid, MIPMAP_TRUE, LLViewerTexture::BOOST_NONE, texture_type);
+ LLViewerFetchedTexture* image = LLViewerTextureManager::getFetchedTexture(uuid, FTT_DEFAULT, MIPMAP_TRUE, LLGLTexture::BOOST_NONE, texture_type);
if (image)
{
image->addTextureStats((F32)pixel_area);
@@ -227,7 +231,9 @@ void LLViewerTextureList::shutdown()
if (!image->hasGLTexture() ||
!image->getUseDiscard() ||
image->needsAux() ||
- image->getTargetHost() != LLHost::invalid)
+ image->getTargetHost() != LLHost::invalid ||
+ !image->getUrl().empty()
+ )
{
continue; // avoid UI, baked, and other special images
}
@@ -275,6 +281,7 @@ void LLViewerTextureList::shutdown()
// Flush all of the references
mLoadingStreamList.clear();
mCreateTextureList.clear();
+ mFastCacheList.clear();
mUUIDMap.clear();
@@ -321,6 +328,7 @@ void LLViewerTextureList::restoreGL()
///////////////////////////////////////////////////////////////////////////////
LLViewerFetchedTexture* LLViewerTextureList::getImageFromFile(const std::string& filename,
+ FTType f_type,
BOOL usemipmaps,
LLViewerTexture::EBoostLevel boost_priority,
S8 texture_type,
@@ -337,15 +345,16 @@ LLViewerFetchedTexture* LLViewerTextureList::getImageFromFile(const std::string&
if (full_path.empty())
{
llwarns << "Failed to find local image file: " << filename << llendl;
- return LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT, TRUE, LLViewerTexture::BOOST_UI);
+ return LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);
}
std::string url = "file://" + full_path;
- return getImageFromUrl(url, usemipmaps, boost_priority, texture_type, internal_format, primary_format, force_id);
+ return getImageFromUrl(url, f_type, usemipmaps, boost_priority, texture_type, internal_format, primary_format, force_id);
}
LLViewerFetchedTexture* LLViewerTextureList::getImageFromUrl(const std::string& url,
+ FTType f_type,
BOOL usemipmaps,
LLViewerTexture::EBoostLevel boost_priority,
S8 texture_type,
@@ -371,15 +380,32 @@ LLViewerFetchedTexture* LLViewerTextureList::getImageFromUrl(const std::string&
LLPointer<LLViewerFetchedTexture> imagep = findImage(new_id);
+ if (!imagep.isNull())
+ {
+ LLViewerFetchedTexture *texture = imagep.get();
+ if (texture->getUrl().empty())
+ {
+ llwarns << "Requested texture " << new_id << " already exists but does not have a URL" << llendl;
+ }
+ else if (texture->getUrl() != url)
+ {
+ // This is not an error as long as the images really match -
+ // e.g. could be two avatars wearing the same outfit.
+ LL_DEBUGS("Avatar") << "Requested texture " << new_id
+ << " already exists with a different url, requested: " << url
+ << " current: " << texture->getUrl() << llendl;
+ }
+
+ }
if (imagep.isNull())
{
switch(texture_type)
{
case LLViewerTexture::FETCHED_TEXTURE:
- imagep = new LLViewerFetchedTexture(url, new_id, usemipmaps);
+ imagep = new LLViewerFetchedTexture(url, f_type, new_id, usemipmaps);
break ;
case LLViewerTexture::LOD_TEXTURE:
- imagep = new LLViewerLODTexture(url, new_id, usemipmaps);
+ imagep = new LLViewerLODTexture(url, f_type, new_id, usemipmaps);
break ;
default:
llerrs << "Invalid texture type " << texture_type << llendl ;
@@ -410,6 +436,7 @@ LLViewerFetchedTexture* LLViewerTextureList::getImageFromUrl(const std::string&
LLViewerFetchedTexture* LLViewerTextureList::getImage(const LLUUID &image_id,
+ FTType f_type,
BOOL usemipmaps,
LLViewerTexture::EBoostLevel boost_priority,
S8 texture_type,
@@ -428,14 +455,34 @@ LLViewerFetchedTexture* LLViewerTextureList::getImage(const LLUUID &image_id,
if ((&image_id == NULL) || image_id.isNull())
{
- return (LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT, TRUE, LLViewerTexture::BOOST_UI));
+ return (LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI));
}
LLPointer<LLViewerFetchedTexture> imagep = findImage(image_id);
+ if (!imagep.isNull())
+ {
+ LLViewerFetchedTexture *texture = imagep.get();
+ if (request_from_host.isOk() &&
+ !texture->getTargetHost().isOk())
+ {
+ llwarns << "Requested texture " << image_id << " already exists but does not have a host" << llendl;
+ }
+ else if (request_from_host.isOk() &&
+ texture->getTargetHost().isOk() &&
+ request_from_host != texture->getTargetHost())
+ {
+ llwarns << "Requested texture " << image_id << " already exists with a different target host, requested: "
+ << request_from_host << " current: " << texture->getTargetHost() << llendl;
+ }
+ if (f_type != FTT_DEFAULT && imagep->getFTType() != f_type)
+ {
+ llwarns << "FTType mismatch: requested " << f_type << " image has " << imagep->getFTType() << llendl;
+ }
+ }
if (imagep.isNull())
{
- imagep = createImage(image_id, usemipmaps, boost_priority, texture_type, internal_format, primary_format, request_from_host) ;
+ imagep = createImage(image_id, f_type, usemipmaps, boost_priority, texture_type, internal_format, primary_format, request_from_host) ;
}
imagep->setGLTextureCreated(true);
@@ -445,6 +492,7 @@ LLViewerFetchedTexture* LLViewerTextureList::getImage(const LLUUID &image_id,
//when this function is called, there is no such texture in the gTextureList with image_id.
LLViewerFetchedTexture* LLViewerTextureList::createImage(const LLUUID &image_id,
+ FTType f_type,
BOOL usemipmaps,
LLViewerTexture::EBoostLevel boost_priority,
S8 texture_type,
@@ -452,14 +500,16 @@ LLViewerFetchedTexture* LLViewerTextureList::createImage(const LLUUID &image_id,
LLGLenum primary_format,
LLHost request_from_host)
{
+ static LLCachedControl<bool> fast_cache_fetching_enabled(gSavedSettings, "FastCacheFetchEnabled", true);
+
LLPointer<LLViewerFetchedTexture> imagep ;
switch(texture_type)
{
case LLViewerTexture::FETCHED_TEXTURE:
- imagep = new LLViewerFetchedTexture(image_id, request_from_host, usemipmaps);
+ imagep = new LLViewerFetchedTexture(image_id, f_type, request_from_host, usemipmaps);
break ;
case LLViewerTexture::LOD_TEXTURE:
- imagep = new LLViewerLODTexture(image_id, request_from_host, usemipmaps);
+ imagep = new LLViewerLODTexture(image_id, f_type, request_from_host, usemipmaps);
break ;
default:
llerrs << "Invalid texture type " << texture_type << llendl ;
@@ -489,6 +539,11 @@ LLViewerFetchedTexture* LLViewerTextureList::createImage(const LLUUID &image_id,
imagep->forceActive() ;
}
+ if(fast_cache_fetching_enabled)
+ {
+ mFastCacheList.insert(imagep);
+ imagep->setInFastCacheList(true);
+ }
return imagep ;
}
@@ -502,40 +557,66 @@ LLViewerFetchedTexture *LLViewerTextureList::findImage(const LLUUID &image_id)
void LLViewerTextureList::addImageToList(LLViewerFetchedTexture *image)
{
+ assert_main_thread();
llassert_always(mInitialized) ;
llassert(image);
if (image->isInImageList())
- {
- llerrs << "LLViewerTextureList::addImageToList - Image already in list" << llendl;
+ { // Flag is already set?
+ llwarns << "LLViewerTextureList::addImageToList - image " << image->getID() << " already in list" << llendl;
}
+ else
+ {
if((mImageList.insert(image)).second != true)
{
- llerrs << "Error happens when insert image to mImageList!" << llendl ;
+ llwarns << "Error happens when insert image " << image->getID() << " into mImageList!" << llendl ;
}
-
image->setInImageList(TRUE) ;
}
+}
void LLViewerTextureList::removeImageFromList(LLViewerFetchedTexture *image)
{
+ assert_main_thread();
llassert_always(mInitialized) ;
llassert(image);
- if (!image->isInImageList())
+
+ S32 count = 0;
+ if (image->isInImageList())
+ {
+ count = mImageList.erase(image) ;
+ if(count != 1)
{
- llinfos << "RefCount: " << image->getNumRefs() << llendl ;
+ llinfos << "Image " << image->getID()
+ << " had mInImageList set but mImageList.erase() returned " << count
+ << llendl;
+ }
+ }
+ else
+ { // Something is wrong, image is expected in list or callers should check first
+ llinfos << "Calling removeImageFromList() for " << image->getID()
+ << " but doesn't have mInImageList set"
+ << " ref count is " << image->getNumRefs()
+ << llendl;
uuid_map_t::iterator iter = mUUIDMap.find(image->getID());
- if(iter == mUUIDMap.end() || iter->second != image)
+ if(iter == mUUIDMap.end())
{
- llinfos << "Image is not in mUUIDMap!" << llendl ;
+ llinfos << "Image " << image->getID() << " is also not in mUUIDMap!" << llendl ;
}
- llerrs << "LLViewerTextureList::removeImageFromList - Image not in list" << llendl;
+ else if (iter->second != image)
+ {
+ llinfos << "Image " << image->getID() << " was in mUUIDMap but with different pointer" << llendl ;
}
-
- S32 count = mImageList.erase(image) ;
- if(count != 1)
+ else
{
- llinfos << image->getID() << llendl ;
- llerrs << "Error happens when remove image from mImageList: " << count << llendl ;
+ llinfos << "Image " << image->getID() << " was in mUUIDMap with same pointer" << llendl ;
+ }
+ count = mImageList.erase(image) ;
+ if(count != 0)
+ { // it was in the list already?
+ llwarns << "Image " << image->getID()
+ << " had mInImageList false but mImageList.erase() returned " << count
+ << llendl;
+ }
}
image->setInImageList(FALSE) ;
@@ -545,15 +626,15 @@ void LLViewerTextureList::addImage(LLViewerFetchedTexture *new_image)
{
if (!new_image)
{
- llwarning("No image to add to image list", 0);
return;
}
+ llassert(new_image);
LLUUID image_id = new_image->getID();
LLViewerFetchedTexture *image = findImage(image_id);
if (image)
{
- llwarns << "Image with ID " << image_id << " already in list" << llendl;
+ llinfos << "Image with ID " << image_id << " already in list" << llendl;
}
sNumImages++;
@@ -592,11 +673,25 @@ static LLFastTimer::DeclareTimer FTM_IMAGE_MARK_DIRTY("Dirty Images");
static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE_PRIORITIES("Prioritize");
static LLFastTimer::DeclareTimer FTM_IMAGE_CALLBACKS("Callbacks");
static LLFastTimer::DeclareTimer FTM_IMAGE_FETCH("Fetch");
+static LLFastTimer::DeclareTimer FTM_FAST_CACHE_IMAGE_FETCH("Fast Cache Fetch");
static LLFastTimer::DeclareTimer FTM_IMAGE_CREATE("Create");
static LLFastTimer::DeclareTimer FTM_IMAGE_STATS("Stats");
void LLViewerTextureList::updateImages(F32 max_time)
{
+ static BOOL cleared = FALSE;
+ if(gTeleportDisplay)
+ {
+ if(!cleared)
+ {
+ clearFetchingRequests();
+ gPipeline.clearRebuildGroups();
+ cleared = TRUE;
+ }
+ return;
+ }
+ cleared = FALSE;
+
LLAppViewer::getTextureFetch()->setTextureBandwidth(LLViewerStats::getInstance()->mTextureKBitStat.getMeanPerSec());
LLViewerStats::getInstance()->mNumImagesStat.addValue(sNumImages);
@@ -606,6 +701,11 @@ void LLViewerTextureList::updateImages(F32 max_time)
LLViewerStats::getInstance()->mRawMemStat.addValue((F32)BYTES_TO_MEGA_BYTES(LLImageRaw::sGlobalRawMemory));
LLViewerStats::getInstance()->mFormattedMemStat.addValue((F32)BYTES_TO_MEGA_BYTES(LLImageFormatted::sGlobalFormattedMemory));
+ {
+ //loading from fast cache
+ LLFastTimer t(FTM_FAST_CACHE_IMAGE_FETCH);
+ max_time -= updateImagesLoadingFastCache(max_time);
+ }
{
LLFastTimer t(FTM_IMAGE_UPDATE_PRIORITIES);
@@ -659,14 +759,32 @@ void LLViewerTextureList::updateImages(F32 max_time)
}
}
+void LLViewerTextureList::clearFetchingRequests()
+{
+ if (LLAppViewer::getTextureFetch()->getNumRequests() == 0)
+ {
+ return;
+ }
+
+ LLAppViewer::getTextureFetch()->deleteAllRequests();
+
+ for (image_priority_list_t::iterator iter = mImageList.begin();
+ iter != mImageList.end(); ++iter)
+ {
+ LLViewerFetchedTexture* imagep = *iter;
+ imagep->forceToDeleteRequest() ;
+ }
+}
+
void LLViewerTextureList::updateImagesDecodePriorities()
{
// Update the decode priority for N images each frame
{
- const size_t max_update_count = llmin((S32) (1024*gFrameIntervalSeconds) + 1, 32); //target 1024 textures per second
- S32 update_counter = llmin(max_update_count, mUUIDMap.size()/10);
+ static const S32 MAX_PRIO_UPDATES = gSavedSettings.getS32("TextureFetchUpdatePriorities"); // default: 32
+ const size_t max_update_count = llmin((S32) (MAX_PRIO_UPDATES*MAX_PRIO_UPDATES*gFrameIntervalSeconds) + 1, MAX_PRIO_UPDATES);
+ S32 update_counter = llmin(max_update_count, mUUIDMap.size());
uuid_map_t::iterator iter = mUUIDMap.upper_bound(mLastUpdateUUID);
- while(update_counter > 0 && !mUUIDMap.empty())
+ while ((update_counter-- > 0) && !mUUIDMap.empty())
{
if (iter == mUUIDMap.end())
{
@@ -674,13 +792,19 @@ void LLViewerTextureList::updateImagesDecodePriorities()
}
mLastUpdateUUID = iter->first;
LLPointer<LLViewerFetchedTexture> imagep = iter->second;
- ++iter; // safe to incrament now
+ ++iter; // safe to increment now
+
+ if(imagep->isInDebug())
+ {
+ update_counter--;
+ continue; //is in debug, ignore.
+ }
//
// Flush formatted images using a lazy flush
//
const F32 LAZY_FLUSH_TIMEOUT = 30.f; // stop decoding
- const F32 MAX_INACTIVE_TIME = 50.f; // actually delete
+ const F32 MAX_INACTIVE_TIME = 20.f; // actually delete
S32 min_refs = 3; // 1 for mImageList, 1 for mUUIDMap, 1 for local reference
S32 num_refs = imagep->getNumRefs();
@@ -729,7 +853,16 @@ void LLViewerTextureList::updateImagesDecodePriorities()
imagep->setInactive() ;
}
}
-
+
+ if (!imagep->isInImageList())
+ {
+ continue;
+ }
+ if(imagep->isInFastCacheList())
+ {
+ continue; //wait for loading from the fast cache.
+ }
+
imagep->processTextureStats();
F32 old_priority = imagep->getDecodePriority();
F32 old_priority_test = llmax(old_priority, 0.0f);
@@ -739,15 +872,35 @@ void LLViewerTextureList::updateImagesDecodePriorities()
if ((decode_priority_test < old_priority_test * .8f) ||
(decode_priority_test > old_priority_test * 1.25f))
{
- removeImageFromList(imagep);
+ mImageList.erase(imagep) ;
imagep->setDecodePriority(decode_priority);
- addImageToList(imagep);
+ mImageList.insert(imagep);
}
- update_counter--;
}
}
}
+void LLViewerTextureList::setDebugFetching(LLViewerFetchedTexture* tex, S32 debug_level)
+{
+ if(!tex->setDebugFetching(debug_level))
+ {
+ return;
+ }
+
+ const F32 DEBUG_PRIORITY = 100000.f;
+ F32 old_priority_test = llmax(tex->getDecodePriority(), 0.0f);
+ F32 decode_priority_test = DEBUG_PRIORITY;
+
+ // Ignore < 20% difference
+ if ((decode_priority_test < old_priority_test * .8f) ||
+ (decode_priority_test > old_priority_test * 1.25f))
+ {
+ removeImageFromList(tex);
+ tex->setDecodePriority(decode_priority_test);
+ addImageToList(tex);
+ }
+}
+
/*
static U8 get_image_type(LLViewerFetchedTexture* imagep, LLHost target_host)
{
@@ -802,6 +955,36 @@ F32 LLViewerTextureList::updateImagesCreateTextures(F32 max_time)
return create_timer.getElapsedTimeF32();
}
+F32 LLViewerTextureList::updateImagesLoadingFastCache(F32 max_time)
+{
+ if (gGLManager.mIsDisabled) return 0.0f;
+ if(mFastCacheList.empty())
+ {
+ return 0.f;
+ }
+
+ //
+ // loading texture raw data from the fast cache directly.
+ //
+
+ LLTimer timer;
+ image_list_t::iterator enditer = mFastCacheList.begin();
+ for (image_list_t::iterator iter = mFastCacheList.begin();
+ iter != mFastCacheList.end();)
+ {
+ image_list_t::iterator curiter = iter++;
+ enditer = iter;
+ LLViewerFetchedTexture *imagep = *curiter;
+ imagep->loadFromFastCache();
+ if (timer.getElapsedTimeF32() > max_time)
+ {
+ break;
+ }
+ }
+ mFastCacheList.erase(mFastCacheList.begin(), enditer);
+ return timer.getElapsedTimeF32();
+}
+
void LLViewerTextureList::forceImmediateUpdate(LLViewerFetchedTexture* imagep)
{
if(!imagep)
@@ -825,15 +1008,24 @@ F32 LLViewerTextureList::updateImagesFetchTextures(F32 max_time)
{
LLTimer image_op_timer;
- // Update the decode priority for N images each frame
- // Make a list with 32 high priority entries + 256 cycled entries
- const size_t max_priority_count = llmin((S32) (256*10.f*gFrameIntervalSeconds)+1, 32);
- const size_t max_update_count = llmin((S32) (1024*10.f*gFrameIntervalSeconds)+1, 256);
+ // Update fetch for N images each frame
+ static const S32 MAX_HIGH_PRIO_COUNT = gSavedSettings.getS32("TextureFetchUpdateHighPriority"); // default: 32
+ static const S32 MAX_UPDATE_COUNT = gSavedSettings.getS32("TextureFetchUpdateMaxMediumPriority"); // default: 256
+ static const S32 MIN_UPDATE_COUNT = gSavedSettings.getS32("TextureFetchUpdateMinMediumPriority"); // default: 32
+ static const F32 MIN_PRIORITY_THRESHOLD = gSavedSettings.getF32("TextureFetchUpdatePriorityThreshold"); // default: 0.0
+ static const bool SKIP_LOW_PRIO = gSavedSettings.getBOOL("TextureFetchUpdateSkipLowPriority"); // default: false
+
+ size_t max_priority_count = llmin((S32) (MAX_HIGH_PRIO_COUNT*MAX_HIGH_PRIO_COUNT*gFrameIntervalSeconds)+1, MAX_HIGH_PRIO_COUNT);
+ max_priority_count = llmin(max_priority_count, mImageList.size());
+
+ size_t total_update_count = mUUIDMap.size();
+ size_t max_update_count = llmin((S32) (MAX_UPDATE_COUNT*MAX_UPDATE_COUNT*gFrameIntervalSeconds)+1, MAX_UPDATE_COUNT);
+ max_update_count = llmin(max_update_count, total_update_count);
- // 32 high priority entries
+ // MAX_HIGH_PRIO_COUNT high priority entries
typedef std::vector<LLViewerFetchedTexture*> entries_list_t;
entries_list_t entries;
- size_t update_counter = llmin(max_priority_count, mImageList.size());
+ size_t update_counter = max_priority_count;
image_priority_list_t::iterator iter1 = mImageList.begin();
while(update_counter > 0)
{
@@ -843,52 +1035,47 @@ F32 LLViewerTextureList::updateImagesFetchTextures(F32 max_time)
update_counter--;
}
- // 256 cycled entries
- update_counter = llmin(max_update_count, mUUIDMap.size());
+ // MAX_UPDATE_COUNT cycled entries
+ update_counter = max_update_count;
if(update_counter > 0)
{
uuid_map_t::iterator iter2 = mUUIDMap.upper_bound(mLastFetchUUID);
- uuid_map_t::iterator iter2p = iter2;
- while(update_counter > 0)
+ while ((update_counter > 0) && (total_update_count > 0))
{
if (iter2 == mUUIDMap.end())
{
iter2 = mUUIDMap.begin();
}
- entries.push_back(iter2->second);
- iter2p = iter2++;
- update_counter--;
+ LLViewerFetchedTexture* imagep = iter2->second;
+ // Skip the textures where there's really nothing to do so to give some times to others. Also skip the texture if it's already in the high prio set.
+ if (!SKIP_LOW_PRIO || (SKIP_LOW_PRIO && ((imagep->getDecodePriority() > MIN_PRIORITY_THRESHOLD) || imagep->hasFetcher())))
+ {
+ entries.push_back(imagep);
+ update_counter--;
+ }
+
+ iter2++;
+ total_update_count--;
}
-
- mLastFetchUUID = iter2p->first;
}
S32 fetch_count = 0;
- S32 min_count = max_priority_count + max_update_count/4;
+ size_t min_update_count = llmin(MIN_UPDATE_COUNT,(S32)(entries.size()-max_priority_count));
+ S32 min_count = max_priority_count + min_update_count;
for (entries_list_t::iterator iter3 = entries.begin();
iter3 != entries.end(); )
{
LLViewerFetchedTexture* imagep = *iter3++;
-
- bool fetching = imagep->updateFetch();
- if (fetching)
+ fetch_count += (imagep->updateFetch() ? 1 : 0);
+ if (min_count <= min_update_count)
{
- fetch_count++;
+ mLastFetchUUID = imagep->getID();
}
- if (min_count <= 0 && image_op_timer.getElapsedTimeF32() > max_time)
+ if ((min_count-- <= 0) && (image_op_timer.getElapsedTimeF32() > max_time))
{
break;
}
- min_count--;
- }
- //if (fetch_count == 0)
- //{
- // gDebugTimers[0].pause();
- //}
- //else
- //{
- // gDebugTimers[0].unpause();
- //}
+ }
return image_op_timer.getElapsedTimeF32();
}
@@ -911,6 +1098,9 @@ void LLViewerTextureList::decodeAllImages(F32 max_time)
{
LLTimer timer;
+ //loading from fast cache
+ updateImagesLoadingFastCache(max_time);
+
// Update texture stats and priorities
std::vector<LLPointer<LLViewerFetchedTexture> > image_list;
for (image_priority_list_t::iterator iter = mImageList.begin();
@@ -1030,7 +1220,6 @@ LLPointer<LLImageJ2C> LLViewerTextureList::convertToUploadFile(LLPointer<LLImage
{
raw_image->biasedScaleToPowerOfTwo(LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT);
LLPointer<LLImageJ2C> compressedImage = new LLImageJ2C();
- compressedImage->setRate(0.f);
if (gSavedSettings.getBOOL("LosslessJ2CUpload") &&
(raw_image->getWidth() * raw_image->getHeight() <= LL_IMAGE_REZ_LOSSLESS_CUTOFF * LL_IMAGE_REZ_LOSSLESS_CUTOFF))
@@ -1072,7 +1261,7 @@ S32 LLViewerTextureList::getMinVideoRamSetting()
//static
// Returns max setting for TextureMemory (in MB)
-S32 LLViewerTextureList::getMaxVideoRamSetting(bool get_recommended)
+S32 LLViewerTextureList::getMaxVideoRamSetting(bool get_recommended, float mem_multiplier)
{
S32 max_texmem;
if (gGLManager.mVRAM != 0)
@@ -1116,7 +1305,10 @@ S32 LLViewerTextureList::getMaxVideoRamSetting(bool get_recommended)
max_texmem = llmin(max_texmem, (S32)(system_ram/2));
else
max_texmem = llmin(max_texmem, (S32)(system_ram));
-
+
+ // limit the texture memory to a multiple of the default if we've found some cards to behave poorly otherwise
+ max_texmem = llmin(max_texmem, (S32) (mem_multiplier * (F32) max_texmem));
+
max_texmem = llclamp(max_texmem, getMinVideoRamSetting(), MAX_VIDEO_RAM_IN_MEGA_BYTES);
return max_texmem;
@@ -1129,7 +1321,7 @@ void LLViewerTextureList::updateMaxResidentTexMem(S32 mem)
// Initialize the image pipeline VRAM settings
S32 cur_mem = gSavedSettings.getS32("TextureMemory");
F32 mem_multiplier = gSavedSettings.getF32("RenderTextureMemoryMultiple");
- S32 default_mem = getMaxVideoRamSetting(true); // recommended default
+ S32 default_mem = getMaxVideoRamSetting(true, mem_multiplier); // recommended default
if (mem == 0)
{
mem = cur_mem > 0 ? cur_mem : default_mem;
@@ -1139,10 +1331,7 @@ void LLViewerTextureList::updateMaxResidentTexMem(S32 mem)
mem = default_mem;
}
- // limit the texture memory to a multiple of the default if we've found some cards to behave poorly otherwise
- mem = llmin(mem, (S32) (mem_multiplier * (F32) default_mem));
-
- mem = llclamp(mem, getMinVideoRamSetting(), getMaxVideoRamSetting());
+ mem = llclamp(mem, getMinVideoRamSetting(), getMaxVideoRamSetting(false, mem_multiplier));
if (mem != cur_mem)
{
gSavedSettings.setS32("TextureMemory", mem);
@@ -1184,7 +1373,7 @@ void LLViewerTextureList::updateMaxResidentTexMem(S32 mem)
// static
void LLViewerTextureList::receiveImageHeader(LLMessageSystem *msg, void **user_data)
{
- static LLCachedControl<bool> log_texture_traffic(gSavedSettings,"LogTextureNetworkTraffic") ;
+ static LLCachedControl<bool> log_texture_traffic(gSavedSettings,"LogTextureNetworkTraffic", false) ;
LLFastTimer t(FTM_PROCESS_IMAGES);
@@ -1234,7 +1423,7 @@ void LLViewerTextureList::receiveImageHeader(LLMessageSystem *msg, void **user_d
U8 *data = new U8[data_size];
msg->getBinaryDataFast(_PREHASH_ImageData, _PREHASH_Data, data, data_size);
- LLViewerFetchedTexture *image = LLViewerTextureManager::getFetchedTexture(id, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
+ LLViewerFetchedTexture *image = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
if (!image)
{
delete [] data;
@@ -1256,9 +1445,8 @@ void LLViewerTextureList::receiveImageHeader(LLMessageSystem *msg, void **user_d
// static
void LLViewerTextureList::receiveImagePacket(LLMessageSystem *msg, void **user_data)
{
- static LLCachedControl<bool> log_texture_traffic(gSavedSettings,"LogTextureNetworkTraffic") ;
+ static LLCachedControl<bool> log_texture_traffic(gSavedSettings,"LogTextureNetworkTraffic", false) ;
- LLMemType mt1(LLMemType::MTYPE_APPFMTIMAGE);
LLFastTimer t(FTM_PROCESS_IMAGES);
// Receives image packet, copy into image object,
@@ -1307,7 +1495,7 @@ void LLViewerTextureList::receiveImagePacket(LLMessageSystem *msg, void **user_d
U8 *data = new U8[data_size];
msg->getBinaryDataFast(_PREHASH_ImageData, _PREHASH_Data, data, data_size);
- LLViewerFetchedTexture *image = LLViewerTextureManager::getFetchedTexture(id, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
+ LLViewerFetchedTexture *image = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
if (!image)
{
delete [] data;
@@ -1338,6 +1526,7 @@ void LLViewerTextureList::processImageNotInDatabase(LLMessageSystem *msg,void **
LLViewerFetchedTexture* image = gTextureList.findImage( image_id );
if( image )
{
+ llwarns << "not in db" << llendl;
image->setIsMissingAsset();
}
}
@@ -1407,22 +1596,22 @@ LLUIImagePtr LLUIImageList::getUIImage(const std::string& image_name, S32 priori
LLUIImagePtr LLUIImageList::loadUIImageByName(const std::string& name, const std::string& filename,
BOOL use_mips, const LLRect& scale_rect, const LLRect& clip_rect, LLViewerTexture::EBoostLevel boost_priority )
{
- if (boost_priority == LLViewerTexture::BOOST_NONE)
+ if (boost_priority == LLGLTexture::BOOST_NONE)
{
- boost_priority = LLViewerTexture::BOOST_UI;
+ boost_priority = LLGLTexture::BOOST_UI;
}
- LLViewerFetchedTexture* imagep = LLViewerTextureManager::getFetchedTextureFromFile(filename, MIPMAP_NO, boost_priority);
+ LLViewerFetchedTexture* imagep = LLViewerTextureManager::getFetchedTextureFromFile(filename, FTT_LOCAL_FILE, MIPMAP_NO, boost_priority);
return loadUIImage(imagep, name, use_mips, scale_rect, clip_rect);
}
LLUIImagePtr LLUIImageList::loadUIImageByID(const LLUUID& id,
BOOL use_mips, const LLRect& scale_rect, const LLRect& clip_rect, LLViewerTexture::EBoostLevel boost_priority)
{
- if (boost_priority == LLViewerTexture::BOOST_NONE)
+ if (boost_priority == LLGLTexture::BOOST_NONE)
{
- boost_priority = LLViewerTexture::BOOST_UI;
+ boost_priority = LLGLTexture::BOOST_UI;
}
- LLViewerFetchedTexture* imagep = LLViewerTextureManager::getFetchedTexture(id, MIPMAP_NO, boost_priority);
+ LLViewerFetchedTexture* imagep = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, MIPMAP_NO, boost_priority);
return loadUIImage(imagep, id.asString(), use_mips, scale_rect, clip_rect);
}
@@ -1432,6 +1621,9 @@ LLUIImagePtr LLUIImageList::loadUIImage(LLViewerFetchedTexture* imagep, const st
imagep->setAddressMode(LLTexUnit::TAM_CLAMP);
+ //don't compress UI images
+ imagep->getGLTexture()->setAllowCompression(false);
+
//all UI images are non-deletable
imagep->setNoDelete();
@@ -1442,7 +1634,7 @@ LLUIImagePtr LLUIImageList::loadUIImage(LLViewerFetchedTexture* imagep, const st
//Note:
//Some other textures such as ICON also through this flow to be fetched.
//But only UI textures need to set this callback.
- if(imagep->getBoostLevel() == LLViewerTexture::BOOST_UI)
+ if(imagep->getBoostLevel() == LLGLTexture::BOOST_UI)
{
LLUIImageLoadData* datap = new LLUIImageLoadData;
datap->mImageName = name;
@@ -1556,49 +1748,43 @@ struct UIImageDeclarations : public LLInitParam::Block<UIImageDeclarations>
bool LLUIImageList::initFromFile()
{
- // construct path to canonical textures.xml in default skin dir
- std::string base_file_path = gDirUtilp->getExpandedFilename(LL_PATH_SKINS, "default", "textures", "textures.xml");
+ // Look for textures.xml in all the right places. Pass
+ // constraint=LLDir::ALL_SKINS because we want to overlay textures.xml
+ // from all the skins directories.
+ std::vector<std::string> textures_paths =
+ gDirUtilp->findSkinnedFilenames(LLDir::TEXTURES, "textures.xml", LLDir::ALL_SKINS);
+ std::vector<std::string>::const_iterator pi(textures_paths.begin()), pend(textures_paths.end());
+ if (pi == pend)
+ {
+ llwarns << "No textures.xml found in skins directories" << llendl;
+ return false;
+ }
+ // The first (most generic) file gets special validations
LLXMLNodePtr root;
-
- if (!LLXMLNode::parseFile(base_file_path, root, NULL))
+ if (!LLXMLNode::parseFile(*pi, root, NULL))
{
- llwarns << "Unable to parse UI image list file " << base_file_path << llendl;
+ llwarns << "Unable to parse UI image list file " << *pi << llendl;
return false;
}
if (!root->hasAttribute("version"))
{
- llwarns << "No valid version number in UI image list file " << base_file_path << llendl;
+ llwarns << "No valid version number in UI image list file " << *pi << llendl;
return false;
}
UIImageDeclarations images;
LLXUIParser parser;
- parser.readXUI(root, images, base_file_path);
-
- // add components defined in current skin
- std::string skin_update_path = gDirUtilp->getSkinDir()
- + gDirUtilp->getDirDelimiter()
- + "textures"
- + gDirUtilp->getDirDelimiter()
- + "textures.xml";
- LLXMLNodePtr update_root;
- if (skin_update_path != base_file_path
- && LLXMLNode::parseFile(skin_update_path, update_root, NULL))
- {
- parser.readXUI(update_root, images, skin_update_path);
- }
-
- // add components defined in user override of current skin
- skin_update_path = gDirUtilp->getUserSkinDir()
- + gDirUtilp->getDirDelimiter()
- + "textures"
- + gDirUtilp->getDirDelimiter()
- + "textures.xml";
- if (skin_update_path != base_file_path
- && LLXMLNode::parseFile(skin_update_path, update_root, NULL))
- {
- parser.readXUI(update_root, images, skin_update_path);
+ parser.readXUI(root, images, *pi);
+
+ // add components defined in the rest of the skin paths
+ while (++pi != pend)
+ {
+ LLXMLNodePtr update_root;
+ if (LLXMLNode::parseFile(*pi, update_root, NULL))
+ {
+ parser.readXUI(update_root, images, *pi);
+ }
}
if (!images.validateBlock()) return false;
diff --git a/indra/newview/llviewertexturelist.h b/indra/newview/llviewertexturelist.h
index b386c73d2a..26dc6dcbe2 100644..100755
--- a/indra/newview/llviewertexturelist.h
+++ b/indra/newview/llviewertexturelist.h
@@ -110,14 +110,18 @@ public:
void doPreloadImages();
void doPrefetchImages();
+ void clearFetchingRequests();
+ void setDebugFetching(LLViewerFetchedTexture* tex, S32 debug_level);
+
static S32 getMinVideoRamSetting();
- static S32 getMaxVideoRamSetting(bool get_recommended = false);
+ static S32 getMaxVideoRamSetting(bool get_recommended, float mem_multiplier);
private:
void updateImagesDecodePriorities();
F32 updateImagesCreateTextures(F32 max_time);
F32 updateImagesFetchTextures(F32 max_time);
void updateImagesUpdateStats();
+ F32 updateImagesLoadingFastCache(F32 max_time);
void addImage(LLViewerFetchedTexture *image);
void deleteImage(LLViewerFetchedTexture *image);
@@ -126,8 +130,9 @@ private:
void removeImageFromList(LLViewerFetchedTexture *image);
LLViewerFetchedTexture * getImage(const LLUUID &image_id,
+ FTType f_type = FTT_DEFAULT,
BOOL usemipmap = TRUE,
- LLViewerTexture::EBoostLevel boost_priority = LLViewerTexture::BOOST_NONE, // Get the requested level immediately upon creation.
+ LLViewerTexture::EBoostLevel boost_priority = LLGLTexture::BOOST_NONE, // Get the requested level immediately upon creation.
S8 texture_type = LLViewerTexture::FETCHED_TEXTURE,
LLGLint internal_format = 0,
LLGLenum primary_format = 0,
@@ -135,8 +140,9 @@ private:
);
LLViewerFetchedTexture * getImageFromFile(const std::string& filename,
+ FTType f_type = FTT_LOCAL_FILE,
BOOL usemipmap = TRUE,
- LLViewerTexture::EBoostLevel boost_priority = LLViewerTexture::BOOST_NONE, // Get the requested level immediately upon creation.
+ LLViewerTexture::EBoostLevel boost_priority = LLGLTexture::BOOST_NONE, // Get the requested level immediately upon creation.
S8 texture_type = LLViewerTexture::FETCHED_TEXTURE,
LLGLint internal_format = 0,
LLGLenum primary_format = 0,
@@ -144,8 +150,9 @@ private:
);
LLViewerFetchedTexture* getImageFromUrl(const std::string& url,
+ FTType f_type,
BOOL usemipmap = TRUE,
- LLViewerTexture::EBoostLevel boost_priority = LLViewerTexture::BOOST_NONE, // Get the requested level immediately upon creation.
+ LLViewerTexture::EBoostLevel boost_priority = LLGLTexture::BOOST_NONE, // Get the requested level immediately upon creation.
S8 texture_type = LLViewerTexture::FETCHED_TEXTURE,
LLGLint internal_format = 0,
LLGLenum primary_format = 0,
@@ -153,8 +160,9 @@ private:
);
LLViewerFetchedTexture* createImage(const LLUUID &image_id,
+ FTType f_type,
BOOL usemipmap = TRUE,
- LLViewerTexture::EBoostLevel boost_priority = LLViewerTexture::BOOST_NONE, // Get the requested level immediately upon creation.
+ LLViewerTexture::EBoostLevel boost_priority = LLGLTexture::BOOST_NONE, // Get the requested level immediately upon creation.
S8 texture_type = LLViewerTexture::FETCHED_TEXTURE,
LLGLint internal_format = 0,
LLGLenum primary_format = 0,
@@ -163,14 +171,15 @@ private:
// Request image from a specific host, used for baked avatar textures.
// Implemented in header in case someone changes default params above. JC
- LLViewerFetchedTexture* getImageFromHost(const LLUUID& image_id, LLHost host)
- { return getImage(image_id, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, host); }
+ LLViewerFetchedTexture* getImageFromHost(const LLUUID& image_id, FTType f_type, LLHost host)
+ { return getImage(image_id, f_type, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, host); }
public:
typedef std::set<LLPointer<LLViewerFetchedTexture> > image_list_t;
image_list_t mLoadingStreamList;
image_list_t mCreateTextureList;
image_list_t mCallbackList;
+ image_list_t mFastCacheList;
// Note: just raw pointers because they are never referenced, just compared against
std::set<LLViewerFetchedTexture*> mDirtyTextureList;
@@ -228,11 +237,11 @@ private:
LLPointer<LLUIImage> loadUIImageByName(const std::string& name, const std::string& filename,
BOOL use_mips = FALSE, const LLRect& scale_rect = LLRect::null,
const LLRect& clip_rect = LLRect::null,
- LLViewerTexture::EBoostLevel boost_priority = LLViewerTexture::BOOST_UI);
+ LLViewerTexture::EBoostLevel boost_priority = LLGLTexture::BOOST_UI);
LLPointer<LLUIImage> loadUIImageByID(const LLUUID& id,
BOOL use_mips = FALSE, const LLRect& scale_rect = LLRect::null,
const LLRect& clip_rect = LLRect::null,
- LLViewerTexture::EBoostLevel boost_priority = LLViewerTexture::BOOST_UI);
+ LLViewerTexture::EBoostLevel boost_priority = LLGLTexture::BOOST_UI);
LLPointer<LLUIImage> loadUIImage(LLViewerFetchedTexture* imagep, const std::string& name, BOOL use_mips = FALSE, const LLRect& scale_rect = LLRect::null, const LLRect& clip_rect = LLRect::null);
diff --git a/indra/newview/llviewerthrottle.cpp b/indra/newview/llviewerthrottle.cpp
index 5147272122..5147272122 100644..100755
--- a/indra/newview/llviewerthrottle.cpp
+++ b/indra/newview/llviewerthrottle.cpp
diff --git a/indra/newview/llviewerthrottle.h b/indra/newview/llviewerthrottle.h
index fe54b06662..fe54b06662 100644..100755
--- a/indra/newview/llviewerthrottle.h
+++ b/indra/newview/llviewerthrottle.h
diff --git a/indra/newview/llviewervisualparam.cpp b/indra/newview/llviewervisualparam.cpp
deleted file mode 100644
index f0cf9b7692..0000000000
--- a/indra/newview/llviewervisualparam.cpp
+++ /dev/null
@@ -1,164 +0,0 @@
-/**
- * @file llviewervisualparam.cpp
- * @brief Implementation of LLViewerVisualParam class
- *
- * $LicenseInfo:firstyear=2001&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$
- */
-
-//-----------------------------------------------------------------------------
-// Header Files
-//-----------------------------------------------------------------------------
-#include "llviewerprecompiledheaders.h"
-
-#include "llviewervisualparam.h"
-#include "llxmltree.h"
-#include "llui.h"
-#include "llwearable.h"
-
-//-----------------------------------------------------------------------------
-// LLViewerVisualParamInfo()
-//-----------------------------------------------------------------------------
-LLViewerVisualParamInfo::LLViewerVisualParamInfo()
- :
- mWearableType( LLWearableType::WT_INVALID ),
- mCrossWearable(FALSE),
- mCamDist( 0.5f ),
- mCamAngle( 0.f ),
- mCamElevation( 0.f ),
- mEditGroupDisplayOrder( 0 ),
- mShowSimple(FALSE),
- mSimpleMin(0.f),
- mSimpleMax(100.f)
-{
-}
-
-LLViewerVisualParamInfo::~LLViewerVisualParamInfo()
-{
-}
-
-//-----------------------------------------------------------------------------
-// parseXml()
-//-----------------------------------------------------------------------------
-BOOL LLViewerVisualParamInfo::parseXml(LLXmlTreeNode *node)
-{
- llassert( node->hasName( "param" ) );
-
- if (!LLVisualParamInfo::parseXml(node))
- return FALSE;
-
- // VIEWER SPECIFIC PARAMS
-
- std::string wearable;
- static LLStdStringHandle wearable_string = LLXmlTree::addAttributeString("wearable");
- if( node->getFastAttributeString( wearable_string, wearable) )
- {
- mWearableType = LLWearableType::typeNameToType( wearable );
- }
-
- static LLStdStringHandle edit_group_string = LLXmlTree::addAttributeString("edit_group");
- if (!node->getFastAttributeString( edit_group_string, mEditGroup))
- {
- mEditGroup = "";
- }
-
- static LLStdStringHandle cross_wearable_string = LLXmlTree::addAttributeString("cross_wearable");
- if (!node->getFastAttributeBOOL(cross_wearable_string, mCrossWearable))
- {
- mCrossWearable = FALSE;
- }
-
- // Optional camera offsets from the current joint center. Used for generating "hints" (thumbnails).
- static LLStdStringHandle camera_distance_string = LLXmlTree::addAttributeString("camera_distance");
- node->getFastAttributeF32( camera_distance_string, mCamDist );
- static LLStdStringHandle camera_angle_string = LLXmlTree::addAttributeString("camera_angle");
- node->getFastAttributeF32( camera_angle_string, mCamAngle ); // in degrees
- static LLStdStringHandle camera_elevation_string = LLXmlTree::addAttributeString("camera_elevation");
- node->getFastAttributeF32( camera_elevation_string, mCamElevation );
-
- mCamAngle += 180;
-
- static S32 params_loaded = 0;
-
- // By default, parameters are displayed in the order in which they appear in the xml file.
- // "edit_group_order" overriddes.
- static LLStdStringHandle edit_group_order_string = LLXmlTree::addAttributeString("edit_group_order");
- if( !node->getFastAttributeF32( edit_group_order_string, mEditGroupDisplayOrder ) )
- {
- mEditGroupDisplayOrder = (F32)params_loaded;
- }
-
- params_loaded++;
-
- return TRUE;
-}
-
-/*virtual*/ void LLViewerVisualParamInfo::toStream(std::ostream &out)
-{
- LLVisualParamInfo::toStream(out);
-
- out << mWearableType << "\t";
- out << mEditGroup << "\t";
- out << mEditGroupDisplayOrder << "\t";
-}
-
-//-----------------------------------------------------------------------------
-// LLViewerVisualParam()
-//-----------------------------------------------------------------------------
-LLViewerVisualParam::LLViewerVisualParam()
-{
-}
-
-//-----------------------------------------------------------------------------
-// setInfo()
-//-----------------------------------------------------------------------------
-
-BOOL LLViewerVisualParam::setInfo(LLViewerVisualParamInfo *info)
-{
- llassert(mInfo == NULL);
- if (info->mID < 0)
- return FALSE;
- mInfo = info;
- mID = info->mID;
- setWeight(getDefaultWeight(), FALSE );
- return TRUE;
-}
-
-/*
-//=============================================================================
-// These virtual functions should always be overridden,
-// but are included here for use as templates
-//=============================================================================
-
-//-----------------------------------------------------------------------------
-// parseData()
-//-----------------------------------------------------------------------------
-BOOL LLViewerVisualParam::parseData(LLXmlTreeNode *node)
-{
- LLViewerVisualParamInfo* info = new LLViewerVisualParamInfo;
-
- info->parseXml(node);
- if (!setInfo(info))
- return FALSE;
-
- return TRUE;
-}
-*/
diff --git a/indra/newview/llviewervisualparam.h b/indra/newview/llviewervisualparam.h
deleted file mode 100644
index dd7751acd7..0000000000
--- a/indra/newview/llviewervisualparam.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/**
- * @file llviewervisualparam.h
- * @brief viewer side visual params (with data file parsing)
- *
- * $LicenseInfo:firstyear=2001&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$
- */
-
-#ifndef LL_LLViewerVisualParam_H
-#define LL_LLViewerVisualParam_H
-
-#include "v3math.h"
-#include "llstring.h"
-#include "llvisualparam.h"
-
-class LLWearable;
-
-//-----------------------------------------------------------------------------
-// LLViewerVisualParamInfo
-//-----------------------------------------------------------------------------
-class LLViewerVisualParamInfo : public LLVisualParamInfo
-{
- friend class LLViewerVisualParam;
-public:
- LLViewerVisualParamInfo();
- /*virtual*/ ~LLViewerVisualParamInfo();
-
- /*virtual*/ BOOL parseXml(LLXmlTreeNode* node);
-
- /*virtual*/ void toStream(std::ostream &out);
-
-protected:
- S32 mWearableType;
- BOOL mCrossWearable;
- std::string mEditGroup;
- F32 mCamDist;
- F32 mCamAngle; // degrees
- F32 mCamElevation;
- F32 mEditGroupDisplayOrder;
- BOOL mShowSimple; // show edit controls when in "simple ui" mode?
- F32 mSimpleMin; // when in simple UI, apply this minimum, range 0.f to 100.f
- F32 mSimpleMax; // when in simple UI, apply this maximum, range 0.f to 100.f
-};
-
-//-----------------------------------------------------------------------------
-// LLViewerVisualParam
-// VIRTUAL CLASS
-// a viewer side interface class for a generalized parametric modification of the avatar mesh
-//-----------------------------------------------------------------------------
-class LLViewerVisualParam : public LLVisualParam
-{
-public:
- LLViewerVisualParam();
- /*virtual*/ ~LLViewerVisualParam(){};
-
- // Special: These functions are overridden by child classes
- LLViewerVisualParamInfo *getInfo() const { return (LLViewerVisualParamInfo*)mInfo; };
- // This sets mInfo and calls initialization functions
- BOOL setInfo(LLViewerVisualParamInfo *info);
-
- virtual LLViewerVisualParam* cloneParam(LLWearable* wearable) const = 0;
-
- // LLVisualParam Virtual functions
- ///*virtual*/ BOOL parseData(LLXmlTreeNode* node);
-
- // New Virtual functions
- virtual F32 getTotalDistortion() = 0;
- virtual const LLVector3& getAvgDistortion() = 0;
- virtual F32 getMaxDistortion() = 0;
- virtual LLVector3 getVertexDistortion(S32 index, LLPolyMesh *mesh) = 0;
- virtual const LLVector3* getFirstDistortion(U32 *index, LLPolyMesh **mesh) = 0;
- virtual const LLVector3* getNextDistortion(U32 *index, LLPolyMesh **mesh) = 0;
-
- // interface methods
- F32 getDisplayOrder() const { return getInfo()->mEditGroupDisplayOrder; }
- S32 getWearableType() const { return getInfo()->mWearableType; }
- const std::string& getEditGroup() const { return getInfo()->mEditGroup; }
-
- F32 getCameraDistance() const { return getInfo()->mCamDist; }
- F32 getCameraAngle() const { return getInfo()->mCamAngle; } // degrees
- F32 getCameraElevation() const { return getInfo()->mCamElevation; }
-
- BOOL getShowSimple() const { return getInfo()->mShowSimple; }
- F32 getSimpleMin() const { return getInfo()->mSimpleMin; }
- F32 getSimpleMax() const { return getInfo()->mSimpleMax; }
-
- BOOL getCrossWearable() const { return getInfo()->mCrossWearable; }
-
-};
-
-#endif // LL_LLViewerVisualParam_H
diff --git a/indra/newview/llviewerwearable.cpp b/indra/newview/llviewerwearable.cpp
new file mode 100644
index 0000000000..e8425dc76a
--- /dev/null
+++ b/indra/newview/llviewerwearable.cpp
@@ -0,0 +1,656 @@
+/**
+ * @file llviewerwearable.cpp
+ * @brief LLViewerWearable class implementation
+ *
+ * $LicenseInfo:firstyear=2012&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 "llviewerprecompiledheaders.h"
+
+#include "llagent.h"
+#include "llagentcamera.h"
+#include "llagentwearables.h"
+#include "llfloatersidepanelcontainer.h"
+#include "llnotificationsutil.h"
+#include "llsidepanelappearance.h"
+#include "lltextureentry.h"
+#include "llviewertexlayer.h"
+#include "llvoavatarself.h"
+#include "llavatarappearancedefines.h"
+#include "llviewerwearable.h"
+#include "llviewercontrol.h"
+#include "llviewerregion.h"
+
+using namespace LLAvatarAppearanceDefines;
+
+// support class - remove for 2.1 (hackity hack hack)
+class LLOverrideBakedTextureUpdate
+{
+public:
+ LLOverrideBakedTextureUpdate(bool temp_state)
+ {
+ U32 num_bakes = (U32) LLAvatarAppearanceDefines::BAKED_NUM_INDICES;
+ for( U32 index = 0; index < num_bakes; ++index )
+ {
+ composite_enabled[index] = gAgentAvatarp->isCompositeUpdateEnabled(index);
+ }
+ gAgentAvatarp->setCompositeUpdatesEnabled(temp_state);
+ }
+
+ ~LLOverrideBakedTextureUpdate()
+ {
+ U32 num_bakes = (U32)LLAvatarAppearanceDefines::BAKED_NUM_INDICES;
+ for( U32 index = 0; index < num_bakes; ++index )
+ {
+ gAgentAvatarp->setCompositeUpdatesEnabled(index, composite_enabled[index]);
+ }
+ }
+private:
+ bool composite_enabled[LLAvatarAppearanceDefines::BAKED_NUM_INDICES];
+};
+
+// Private local functions
+static std::string asset_id_to_filename(const LLUUID &asset_id);
+
+LLViewerWearable::LLViewerWearable(const LLTransactionID& transaction_id) :
+ LLWearable()
+{
+ mTransactionID = transaction_id;
+ mAssetID = mTransactionID.makeAssetID(gAgent.getSecureSessionID());
+}
+
+LLViewerWearable::LLViewerWearable(const LLAssetID& asset_id) :
+ LLWearable()
+{
+ mAssetID = asset_id;
+ mTransactionID.setNull();
+}
+
+// virtual
+LLViewerWearable::~LLViewerWearable()
+{
+}
+
+// virtual
+LLWearable::EImportResult LLViewerWearable::importStream( std::istream& input_stream, LLAvatarAppearance* avatarp )
+{
+ // suppress texlayerset updates while wearables are being imported. Layersets will be updated
+ // when the wearables are "worn", not loaded. Note state will be restored when this object is destroyed.
+ LLOverrideBakedTextureUpdate stop_bakes(false);
+
+ LLWearable::EImportResult result = LLWearable::importStream(input_stream, avatarp);
+ if (LLWearable::FAILURE == result) return result;
+ if (LLWearable::BAD_HEADER == result)
+ {
+ // Shouldn't really log the asset id for security reasons, but
+ // we need it in this case.
+ llwarns << "Bad Wearable asset header: " << mAssetID << llendl;
+ //gVFS->dumpMap();
+ return result;
+ }
+
+ LLStringUtil::truncate(mName, DB_INV_ITEM_NAME_STR_LEN );
+ LLStringUtil::truncate(mDescription, DB_INV_ITEM_DESC_STR_LEN );
+
+ te_map_t::const_iterator iter = mTEMap.begin();
+ te_map_t::const_iterator end = mTEMap.end();
+ for (; iter != end; ++iter)
+ {
+ S32 te = iter->first;
+ LLLocalTextureObject* lto = iter->second;
+ LLUUID textureid = LLUUID::null;
+ if (lto)
+ {
+ textureid = lto->getID();
+ }
+
+ LLViewerFetchedTexture* image = LLViewerTextureManager::getFetchedTexture( textureid );
+ if(gSavedSettings.getBOOL("DebugAvatarLocalTexLoadedTime"))
+ {
+ image->setLoadedCallback(LLVOAvatarSelf::debugOnTimingLocalTexLoaded,0,TRUE,FALSE, new LLVOAvatarSelf::LLAvatarTexData(textureid, (LLAvatarAppearanceDefines::ETextureIndex)te), NULL);
+ }
+ }
+
+ return result;
+}
+
+
+// Avatar parameter and texture definitions can change over time.
+// This function returns true if parameters or textures have been added or removed
+// since this wearable was created.
+BOOL LLViewerWearable::isOldVersion() const
+{
+ if (!isAgentAvatarValid()) return FALSE;
+
+ if( LLWearable::sCurrentDefinitionVersion < mDefinitionVersion )
+ {
+ llwarns << "Wearable asset has newer version (" << mDefinitionVersion << ") than XML (" << LLWearable::sCurrentDefinitionVersion << ")" << llendl;
+ llassert(0);
+ }
+
+ if( LLWearable::sCurrentDefinitionVersion != mDefinitionVersion )
+ {
+ return TRUE;
+ }
+
+ S32 param_count = 0;
+ for( LLViewerVisualParam* param = (LLViewerVisualParam*) gAgentAvatarp->getFirstVisualParam();
+ param;
+ param = (LLViewerVisualParam*) gAgentAvatarp->getNextVisualParam() )
+ {
+ if( (param->getWearableType() == mType) && (param->isTweakable() ) )
+ {
+ param_count++;
+ if( !is_in_map(mVisualParamIndexMap, param->getID() ) )
+ {
+ return TRUE;
+ }
+ }
+ }
+ if( param_count != mVisualParamIndexMap.size() )
+ {
+ return TRUE;
+ }
+
+
+ S32 te_count = 0;
+ for( S32 te = 0; te < TEX_NUM_INDICES; te++ )
+ {
+ if (LLAvatarAppearanceDictionary::getTEWearableType((ETextureIndex) te) == mType)
+ {
+ te_count++;
+ if( !is_in_map(mTEMap, te ) )
+ {
+ return TRUE;
+ }
+ }
+ }
+ if( te_count != mTEMap.size() )
+ {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+// Avatar parameter and texture definitions can change over time.
+// * If parameters or textures have been REMOVED since the wearable was created,
+// they're just ignored, so we consider the wearable clean even though isOldVersion()
+// will return true.
+// * If parameters or textures have been ADDED since the wearable was created,
+// they are taken to have default values, so we consider the wearable clean
+// only if those values are the same as the defaults.
+BOOL LLViewerWearable::isDirty() const
+{
+ if (!isAgentAvatarValid()) return FALSE;
+
+ for( LLViewerVisualParam* param = (LLViewerVisualParam*) gAgentAvatarp->getFirstVisualParam();
+ param;
+ param = (LLViewerVisualParam*) gAgentAvatarp->getNextVisualParam() )
+ {
+ if( (param->getWearableType() == mType)
+ && (param->isTweakable() )
+ && !param->getCrossWearable())
+ {
+ F32 current_weight = getVisualParamWeight(param->getID());
+ current_weight = llclamp( current_weight, param->getMinWeight(), param->getMaxWeight() );
+ F32 saved_weight = get_if_there(mSavedVisualParamMap, param->getID(), param->getDefaultWeight());
+ saved_weight = llclamp( saved_weight, param->getMinWeight(), param->getMaxWeight() );
+
+ U8 a = F32_to_U8( saved_weight, param->getMinWeight(), param->getMaxWeight() );
+ U8 b = F32_to_U8( current_weight, param->getMinWeight(), param->getMaxWeight() );
+ if( a != b )
+ {
+ return TRUE;
+ }
+ }
+ }
+
+ for( S32 te = 0; te < TEX_NUM_INDICES; te++ )
+ {
+ if (LLAvatarAppearanceDictionary::getTEWearableType((ETextureIndex) te) == mType)
+ {
+ te_map_t::const_iterator current_iter = mTEMap.find(te);
+ if(current_iter != mTEMap.end())
+ {
+ const LLUUID& current_image_id = current_iter->second->getID();
+ te_map_t::const_iterator saved_iter = mSavedTEMap.find(te);
+ if(saved_iter != mSavedTEMap.end())
+ {
+ const LLUUID& saved_image_id = saved_iter->second->getID();
+ if (saved_image_id != current_image_id)
+ {
+ // saved vs current images are different, wearable is dirty
+ return TRUE;
+ }
+ }
+ else
+ {
+ // image found in current image list but not saved image list
+ return TRUE;
+ }
+ }
+ }
+ }
+
+ return FALSE;
+}
+
+
+void LLViewerWearable::setParamsToDefaults()
+{
+ if (!isAgentAvatarValid()) return;
+
+ for( LLVisualParam* param = gAgentAvatarp->getFirstVisualParam(); param; param = gAgentAvatarp->getNextVisualParam() )
+ {
+ if( (((LLViewerVisualParam*)param)->getWearableType() == mType ) && (param->isTweakable() ) )
+ {
+ setVisualParamWeight(param->getID(),param->getDefaultWeight(), FALSE);
+ }
+ }
+}
+
+void LLViewerWearable::setTexturesToDefaults()
+{
+ for( S32 te = 0; te < TEX_NUM_INDICES; te++ )
+ {
+ if (LLAvatarAppearanceDictionary::getTEWearableType((ETextureIndex) te) == mType)
+ {
+ LLUUID id = getDefaultTextureImageID((ETextureIndex) te);
+ LLViewerFetchedTexture * image = LLViewerTextureManager::getFetchedTexture( id );
+ if( mTEMap.find(te) == mTEMap.end() )
+ {
+ mTEMap[te] = new LLLocalTextureObject(image, id);
+ createLayers(te, gAgentAvatarp);
+ }
+ else
+ {
+ // Local Texture Object already created, just set image and UUID
+ LLLocalTextureObject *lto = mTEMap[te];
+ lto->setID(id);
+ lto->setImage(image);
+ }
+ }
+ }
+}
+
+
+// virtual
+LLUUID LLViewerWearable::getDefaultTextureImageID(ETextureIndex index) const
+{
+ const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearanceDictionary::getInstance()->getTexture(index);
+ const std::string &default_image_name = texture_dict->mDefaultImageName;
+ if (default_image_name == "")
+ {
+ return IMG_DEFAULT_AVATAR;
+ }
+ else
+ {
+ return LLUUID(gSavedSettings.getString(default_image_name));
+ }
+}
+
+
+// Updates the user's avatar's appearance
+//virtual
+void LLViewerWearable::writeToAvatar(LLAvatarAppearance *avatarp)
+{
+ LLVOAvatarSelf* viewer_avatar = dynamic_cast<LLVOAvatarSelf*>(avatarp);
+
+ if (!avatarp || !viewer_avatar) return;
+
+ if (!viewer_avatar->isValid()) return;
+
+#if 0
+ // FIXME DRANO - kludgy way to avoid overwriting avatar state from wearables.
+ // Ideally would avoid calling this func in the first place.
+ if (viewer_avatar->isUsingServerBakes() &&
+ !viewer_avatar->isUsingLocalAppearance())
+ {
+ return;
+ }
+#endif
+
+ ESex old_sex = avatarp->getSex();
+
+ LLWearable::writeToAvatar(avatarp);
+
+
+ // Pull texture entries
+ for( S32 te = 0; te < TEX_NUM_INDICES; te++ )
+ {
+ if (LLAvatarAppearanceDictionary::getTEWearableType((ETextureIndex) te) == mType)
+ {
+ te_map_t::const_iterator iter = mTEMap.find(te);
+ LLUUID image_id;
+ if(iter != mTEMap.end())
+ {
+ image_id = iter->second->getID();
+ }
+ else
+ {
+ image_id = getDefaultTextureImageID((ETextureIndex) te);
+ }
+ LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture( image_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE );
+ // MULTI-WEARABLE: assume index 0 will be used when writing to avatar. TODO: eliminate the need for this.
+ viewer_avatar->setLocalTextureTE(te, image, 0);
+ }
+ }
+
+ ESex new_sex = avatarp->getSex();
+ if( old_sex != new_sex )
+ {
+ viewer_avatar->updateSexDependentLayerSets( FALSE );
+ }
+
+// if( upload_bake )
+// {
+// gAgent.sendAgentSetAppearance();
+// }
+}
+
+
+// Updates the user's avatar's appearance, replacing this wearables' parameters and textures with default values.
+// static
+void LLViewerWearable::removeFromAvatar( LLWearableType::EType type, BOOL upload_bake )
+{
+ if (!isAgentAvatarValid()) return;
+
+ // You can't just remove body parts.
+ if( (type == LLWearableType::WT_SHAPE) ||
+ (type == LLWearableType::WT_SKIN) ||
+ (type == LLWearableType::WT_HAIR) ||
+ (type == LLWearableType::WT_EYES) )
+ {
+ return;
+ }
+
+ // Pull params
+ for( LLVisualParam* param = gAgentAvatarp->getFirstVisualParam(); param; param = gAgentAvatarp->getNextVisualParam() )
+ {
+ if( (((LLViewerVisualParam*)param)->getWearableType() == type) && (param->isTweakable() ) )
+ {
+ S32 param_id = param->getID();
+ gAgentAvatarp->setVisualParamWeight( param_id, param->getDefaultWeight(), upload_bake );
+ }
+ }
+
+ if(gAgentCamera.cameraCustomizeAvatar())
+ {
+ LLFloaterSidePanelContainer::showPanel("appearance", LLSD().with("type", "edit_outfit"));
+ }
+
+ gAgentAvatarp->updateVisualParams();
+ gAgentAvatarp->wearableUpdated(type, FALSE);
+
+// if( upload_bake )
+// {
+// gAgent.sendAgentSetAppearance();
+// }
+}
+
+// Does not copy mAssetID.
+// Definition version is current: removes obsolete enties and creates default values for new ones.
+void LLViewerWearable::copyDataFrom(const LLViewerWearable* src)
+{
+ if (!isAgentAvatarValid()) return;
+
+ mDefinitionVersion = LLWearable::sCurrentDefinitionVersion;
+
+ mName = src->mName;
+ mDescription = src->mDescription;
+ mPermissions = src->mPermissions;
+ mSaleInfo = src->mSaleInfo;
+
+ setType(src->mType, gAgentAvatarp);
+
+ mSavedVisualParamMap.clear();
+ // Deep copy of mVisualParamMap (copies only those params that are current, filling in defaults where needed)
+ for (LLViewerVisualParam* param = (LLViewerVisualParam*) gAgentAvatarp->getFirstVisualParam();
+ param;
+ param = (LLViewerVisualParam*) gAgentAvatarp->getNextVisualParam() )
+ {
+ if( (param->getWearableType() == mType) )
+ {
+ S32 id = param->getID();
+ F32 weight = src->getVisualParamWeight(id);
+ mSavedVisualParamMap[id] = weight;
+ }
+ }
+
+ destroyTextures();
+ // Deep copy of mTEMap (copies only those tes that are current, filling in defaults where needed)
+ for (S32 te = 0; te < TEX_NUM_INDICES; te++)
+ {
+ if (LLAvatarAppearanceDictionary::getTEWearableType((ETextureIndex) te) == mType)
+ {
+ te_map_t::const_iterator iter = src->mTEMap.find(te);
+ LLUUID image_id;
+ LLViewerFetchedTexture *image = NULL;
+ if(iter != src->mTEMap.end())
+ {
+ image = dynamic_cast<LLViewerFetchedTexture*> (src->getLocalTextureObject(te)->getImage());
+ image_id = src->getLocalTextureObject(te)->getID();
+ mTEMap[te] = new LLLocalTextureObject(image, image_id);
+ mSavedTEMap[te] = new LLLocalTextureObject(image, image_id);
+ mTEMap[te]->setBakedReady(src->getLocalTextureObject(te)->getBakedReady());
+ mTEMap[te]->setDiscard(src->getLocalTextureObject(te)->getDiscard());
+ }
+ else
+ {
+ image_id = getDefaultTextureImageID((ETextureIndex) te);
+ image = LLViewerTextureManager::getFetchedTexture( image_id );
+ mTEMap[te] = new LLLocalTextureObject(image, image_id);
+ mSavedTEMap[te] = new LLLocalTextureObject(image, image_id);
+ }
+ createLayers(te, gAgentAvatarp);
+ }
+ }
+
+ // Probably reduntant, but ensure that the newly created wearable is not dirty by setting current value of params in new wearable
+ // to be the same as the saved values (which were loaded from src at param->cloneParam(this))
+ revertValues();
+}
+
+void LLViewerWearable::setItemID(const LLUUID& item_id)
+{
+ mItemID = item_id;
+}
+
+void LLViewerWearable::revertValues()
+{
+#if 0
+ // DRANO avoid overwrite when not in local appearance
+ if (isAgentAvatarValid() && gAgentAvatarp->isUsingServerBakes() && !gAgentAvatarp->isUsingLocalAppearance())
+ {
+ return;
+ }
+#endif
+ LLWearable::revertValues();
+
+
+ LLSidepanelAppearance *panel = dynamic_cast<LLSidepanelAppearance*>(LLFloaterSidePanelContainer::getPanel("appearance"));
+ if( panel )
+ {
+ panel->updateScrollingPanelList();
+ }
+}
+
+void LLViewerWearable::saveValues()
+{
+ LLWearable::saveValues();
+
+ LLSidepanelAppearance *panel = dynamic_cast<LLSidepanelAppearance*>(LLFloaterSidePanelContainer::getPanel("appearance"));
+ if( panel )
+ {
+ panel->updateScrollingPanelList();
+ }
+}
+
+// virtual
+void LLViewerWearable::setUpdated() const
+{
+ gInventory.addChangedMask(LLInventoryObserver::LABEL, getItemID());
+}
+
+void LLViewerWearable::refreshName()
+{
+ LLUUID item_id = getItemID();
+ LLInventoryItem* item = gInventory.getItem(item_id);
+ if( item )
+ {
+ mName = item->getName();
+ }
+}
+
+// virtual
+void LLViewerWearable::addToBakedTextureHash(LLMD5& hash) const
+{
+ LLUUID asset_id = getAssetID();
+ hash.update((const unsigned char*)asset_id.mData, UUID_BYTES);
+}
+
+struct LLWearableSaveData
+{
+ LLWearableType::EType mType;
+};
+
+void LLViewerWearable::saveNewAsset() const
+{
+// llinfos << "LLViewerWearable::saveNewAsset() type: " << getTypeName() << llendl;
+ //llinfos << *this << llendl;
+
+ const std::string filename = asset_id_to_filename(mAssetID);
+ LLFILE* fp = LLFile::fopen(filename, "wb"); /* Flawfinder: ignore */
+ BOOL successful_save = FALSE;
+ if(fp && exportFile(fp))
+ {
+ successful_save = TRUE;
+ }
+ if(fp)
+ {
+ fclose(fp);
+ fp = NULL;
+ }
+ if(!successful_save)
+ {
+ std::string buffer = llformat("Unable to save '%s' to wearable file.", mName.c_str());
+ llwarns << buffer << llendl;
+
+ LLSD args;
+ args["NAME"] = mName;
+ LLNotificationsUtil::add("CannotSaveWearableOutOfSpace", args);
+ return;
+ }
+
+ // save it out to database
+ if( gAssetStorage )
+ {
+ /*
+ std::string url = gAgent.getRegion()->getCapability("NewAgentInventory");
+ if (!url.empty())
+ {
+ llinfos << "Update Agent Inventory via capability" << llendl;
+ LLSD body;
+ body["folder_id"] = gInventory.findCategoryUUIDForType(LLFolderType::assetToFolderType(getAssetType()));
+ body["asset_type"] = LLAssetType::lookup(getAssetType());
+ body["inventory_type"] = LLInventoryType::lookup(LLInventoryType::IT_WEARABLE);
+ body["name"] = getName();
+ body["description"] = getDescription();
+ LLHTTPClient::post(url, body, new LLNewAgentInventoryResponder(body, filename));
+ }
+ else
+ {
+ }
+ */
+ LLWearableSaveData* data = new LLWearableSaveData;
+ data->mType = mType;
+ gAssetStorage->storeAssetData(filename, mTransactionID, getAssetType(),
+ &LLViewerWearable::onSaveNewAssetComplete,
+ (void*)data);
+ }
+}
+
+// static
+void LLViewerWearable::onSaveNewAssetComplete(const LLUUID& new_asset_id, void* userdata, S32 status, LLExtStat ext_status) // StoreAssetData callback (fixed)
+{
+ LLWearableSaveData* data = (LLWearableSaveData*)userdata;
+ const std::string& type_name = LLWearableType::getTypeName(data->mType);
+ if(0 == status)
+ {
+ // Success
+ llinfos << "Saved wearable " << type_name << llendl;
+ }
+ else
+ {
+ std::string buffer = llformat("Unable to save %s to central asset store.", type_name.c_str());
+ llwarns << buffer << " Status: " << status << llendl;
+ LLSD args;
+ args["NAME"] = type_name;
+ LLNotificationsUtil::add("CannotSaveToAssetStore", args);
+ }
+
+ // Delete temp file
+ const std::string src_filename = asset_id_to_filename(new_asset_id);
+ LLFile::remove(src_filename);
+
+ // delete the context data
+ delete data;
+
+}
+
+std::ostream& operator<<(std::ostream &s, const LLViewerWearable &w)
+{
+ s << "wearable " << LLWearableType::getTypeName(w.mType) << "\n";
+ s << " Name: " << w.mName << "\n";
+ s << " Desc: " << w.mDescription << "\n";
+ //w.mPermissions
+ //w.mSaleInfo
+
+ s << " Params:" << "\n";
+ for (LLWearable::visual_param_index_map_t::const_iterator iter = w.mVisualParamIndexMap.begin();
+ iter != w.mVisualParamIndexMap.end(); ++iter)
+ {
+ S32 param_id = iter->first;
+ LLVisualParam *wearable_param = iter->second;
+ F32 param_weight = wearable_param->getWeight();
+ s << " " << param_id << " " << param_weight << "\n";
+ }
+
+ s << " Textures:" << "\n";
+ for (LLViewerWearable::te_map_t::const_iterator iter = w.mTEMap.begin();
+ iter != w.mTEMap.end(); ++iter)
+ {
+ S32 te = iter->first;
+ const LLUUID& image_id = iter->second->getID();
+ s << " " << te << " " << image_id << "\n";
+ }
+ return s;
+}
+
+std::string asset_id_to_filename(const LLUUID &asset_id)
+{
+ std::string asset_id_string;
+ asset_id.toString(asset_id_string);
+ std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,asset_id_string) + ".wbl";
+ return filename;
+}
diff --git a/indra/newview/llviewerwearable.h b/indra/newview/llviewerwearable.h
new file mode 100644
index 0000000000..65566f23a5
--- /dev/null
+++ b/indra/newview/llviewerwearable.h
@@ -0,0 +1,104 @@
+/**
+ * @file llviewerwearable.h
+ * @brief LLViewerWearable class header file
+ *
+ * $LicenseInfo:firstyear=2012&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$
+ */
+
+#ifndef LL_VIEWER_WEARABLE_H
+#define LL_VIEWER_WEARABLE_H
+
+#include "llwearable.h"
+#include "llavatarappearancedefines.h"
+
+class LLVOAvatar;
+
+class LLViewerWearable : public LLWearable
+{
+ friend class LLWearableList;
+
+ //--------------------------------------------------------------------
+ // Constructors and destructors
+ //--------------------------------------------------------------------
+private:
+ // Private constructors used by LLViewerWearableList
+ LLViewerWearable(const LLTransactionID& transactionID);
+ LLViewerWearable(const LLAssetID& assetID);
+public:
+ virtual ~LLViewerWearable();
+
+ //--------------------------------------------------------------------
+ // Accessors
+ //--------------------------------------------------------------------
+public:
+ const LLUUID& getItemID() const { return mItemID; }
+ const LLAssetID& getAssetID() const { return mAssetID; }
+ const LLTransactionID& getTransactionID() const { return mTransactionID; }
+ void setItemID(const LLUUID& item_id);
+
+public:
+
+ BOOL isDirty() const;
+ BOOL isOldVersion() const;
+
+ /*virtual*/ void writeToAvatar(LLAvatarAppearance *avatarp);
+ void removeFromAvatar( BOOL upload_bake ) { LLViewerWearable::removeFromAvatar( mType, upload_bake ); }
+ static void removeFromAvatar( LLWearableType::EType type, BOOL upload_bake );
+
+ /*virtual*/ EImportResult importStream( std::istream& input_stream, LLAvatarAppearance* avatarp );
+
+ void setParamsToDefaults();
+ void setTexturesToDefaults();
+
+ /*virtual*/ LLUUID getDefaultTextureImageID(LLAvatarAppearanceDefines::ETextureIndex index) const;
+
+
+ void saveNewAsset() const;
+ static void onSaveNewAssetComplete( const LLUUID& asset_uuid, void* user_data, S32 status, LLExtStat ext_status );
+
+ void copyDataFrom(const LLViewerWearable* src);
+
+ friend std::ostream& operator<<(std::ostream &s, const LLViewerWearable &w);
+
+ /*virtual*/ void revertValues();
+ /*virtual*/ void saveValues();
+
+ // Something happened that requires the wearable's label to be updated (e.g. worn/unworn).
+ /*virtual*/void setUpdated() const;
+
+ // the wearable was worn. make sure the name of the wearable object matches the LLViewerInventoryItem,
+ // not the wearable asset itself.
+ void refreshName();
+
+ // Update the baked texture hash.
+ /*virtual*/void addToBakedTextureHash(LLMD5& hash) const;
+
+protected:
+ LLAssetID mAssetID;
+ LLTransactionID mTransactionID;
+
+ LLUUID mItemID; // ID of the inventory item in the agent's inventory
+};
+
+
+#endif // LL_VIEWER_WEARABLE_H
+
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index ecd76f5495..cb7536edce 100755
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -34,11 +34,14 @@
#include <fstream>
#include <algorithm>
#include <boost/lambda/core.hpp>
+#include <boost/regex.hpp>
#include "llagent.h"
#include "llagentcamera.h"
+#include "llcommunicationchannel.h"
#include "llfloaterreg.h"
#include "llmeshrepository.h"
+#include "llnotificationhandler.h"
#include "llpanellogin.h"
#include "llviewerkeyboard.h"
#include "llviewermenu.h"
@@ -56,6 +59,7 @@
// linden library includes
#include "llaudioengine.h" // mute on minimize
+#include "llchatentry.h"
#include "indra_constants.h"
#include "llassetstorage.h"
#include "llerrorcontrol.h"
@@ -77,6 +81,7 @@
#include "llmediaentry.h"
#include "llurldispatcher.h"
#include "raytrace.h"
+#include "llstat.h"
// newview includes
#include "llagent.h"
@@ -122,10 +127,12 @@
#include "llkeyboard.h"
#include "lllineeditor.h"
#include "llmenugl.h"
+#include "llmenuoptionpathfindingrebakenavmesh.h"
#include "llmodaldialog.h"
#include "llmorphview.h"
#include "llmoveview.h"
#include "llnavigationbar.h"
+#include "llnotificationhandler.h"
#include "llpaneltopinfobar.h"
#include "llpopupview.h"
#include "llpreviewtexture.h"
@@ -144,6 +151,7 @@
#include "lltexturecache.h"
#include "lltexturefetch.h"
#include "lltextureview.h"
+#include "lltoast.h"
#include "lltool.h"
#include "lltoolbarview.h"
#include "lltoolcomp.h"
@@ -175,6 +183,7 @@
#include "llviewershadermgr.h"
#include "llviewerstats.h"
#include "llvoavatarself.h"
+#include "llvopartgroup.h"
#include "llvovolume.h"
#include "llworld.h"
#include "llworldmapview.h"
@@ -185,17 +194,18 @@
#include "llviewerjoystick.h"
#include "llviewernetwork.h"
#include "llpostprocess.h"
-#include "llnearbychatbar.h"
+#include "llfloaterimnearbychat.h"
#include "llagentui.h"
#include "llwearablelist.h"
+#include "llviewereventrecorder.h"
+
#include "llnotifications.h"
#include "llnotificationsutil.h"
#include "llnotificationmanager.h"
#include "llfloaternotificationsconsole.h"
-#include "llnearbychat.h"
#include "llwindowlistener.h"
#include "llviewerwindowlistener.h"
#include "llpaneltopinfobar.h"
@@ -222,13 +232,15 @@ LLFrameTimer gAwayTriggerTimer;
BOOL gShowOverlayTitle = FALSE;
LLViewerObject* gDebugRaycastObject = NULL;
-LLVector3 gDebugRaycastIntersection;
-LLVector2 gDebugRaycastTexCoord;
-LLVector3 gDebugRaycastNormal;
-LLVector3 gDebugRaycastBinormal;
-S32 gDebugRaycastFaceHit;
-LLVector3 gDebugRaycastStart;
-LLVector3 gDebugRaycastEnd;
+LLVOPartGroup* gDebugRaycastParticle = NULL;
+LLVector4a gDebugRaycastIntersection;
+LLVector4a gDebugRaycastParticleIntersection;
+LLVector2 gDebugRaycastTexCoord;
+LLVector4a gDebugRaycastNormal;
+LLVector4a gDebugRaycastTangent;
+S32 gDebugRaycastFaceHit;
+LLVector4a gDebugRaycastStart;
+LLVector4a gDebugRaycastEnd;
// HUD display lines in lower right
BOOL gDisplayWindInfo = FALSE;
@@ -303,7 +315,7 @@ public:
void update()
{
- static LLCachedControl<bool> log_texture_traffic(gSavedSettings,"LogTextureNetworkTraffic") ;
+ static LLCachedControl<bool> log_texture_traffic(gSavedSettings,"LogTextureNetworkTraffic", false) ;
std::string wind_vel_text;
std::string wind_vector_text;
@@ -324,35 +336,33 @@ public:
mTextColor = LLColor4( 0.86f, 0.86f, 0.86f, 1.f );
// Draw stuff growing up from right lower corner of screen
- U32 xpos = mWindow->getWorldViewWidthScaled() - 350;
- U32 ypos = 64;
- const U32 y_inc = 20;
+ S32 xpos = mWindow->getWorldViewWidthScaled() - 400;
+ xpos = llmax(xpos, 0);
+ S32 ypos = 64;
+ const S32 y_inc = 20;
clearText();
if (gSavedSettings.getBOOL("DebugShowTime"))
{
- const U32 y_inc2 = 15;
- for (std::map<S32,LLFrameTimer>::reverse_iterator iter = gDebugTimers.rbegin();
- iter != gDebugTimers.rend(); ++iter)
{
- S32 idx = iter->first;
- LLFrameTimer& timer = iter->second;
+ const U32 y_inc2 = 15;
+ LLFrameTimer& timer = gTextureTimer;
F32 time = timer.getElapsedTimeF32();
S32 hours = (S32)(time / (60*60));
S32 mins = (S32)((time - hours*(60*60)) / 60);
S32 secs = (S32)((time - hours*(60*60) - mins*60));
- std::string label = gDebugTimerLabel[idx];
- if (label.empty()) label = llformat("Debug: %d", idx);
- addText(xpos, ypos, llformat(" %s: %d:%02d:%02d", label.c_str(), hours,mins,secs)); ypos += y_inc2;
+ addText(xpos, ypos, llformat("Texture: %d:%02d:%02d", hours,mins,secs)); ypos += y_inc2;
}
+ {
F32 time = gFrameTimeSeconds;
S32 hours = (S32)(time / (60*60));
S32 mins = (S32)((time - hours*(60*60)) / 60);
S32 secs = (S32)((time - hours*(60*60) - mins*60));
addText(xpos, ypos, llformat("Time: %d:%02d:%02d", hours,mins,secs)); ypos += y_inc;
}
+ }
#if LL_WINDOWS
if (gSavedSettings.getBOOL("DebugShowMemory"))
@@ -380,7 +390,7 @@ public:
if (isAgentAvatarValid())
{
- tvector = gAgent.getPosGlobalFromAgent(gAgentAvatarp->mRoot.getWorldPosition());
+ tvector = gAgent.getPosGlobalFromAgent(gAgentAvatarp->mRoot->getWorldPosition());
agent_root_center_text = llformat("AgentRootCenter %f %f %f",
(F32)(tvector.mdV[VX]), (F32)(tvector.mdV[VY]), (F32)(tvector.mdV[VZ]));
}
@@ -534,7 +544,10 @@ public:
}
- addText(xpos, ypos, llformat("%d MB Vertex Data (%d MB Pooled)", LLVertexBuffer::sAllocatedBytes/(1024*1024), LLVBOPool::sBytesPooled/(1024*1024)));
+ addText(xpos, ypos, llformat("%d MB Index Data (%d MB Pooled, %d KIndices)", LLVertexBuffer::sAllocatedIndexBytes/(1024*1024), LLVBOPool::sIndexBytesPooled/(1024*1024), LLVertexBuffer::sIndexCount/1024));
+ ypos += y_inc;
+
+ addText(xpos, ypos, llformat("%d MB Vertex Data (%d MB Pooled, %d KVerts)", LLVertexBuffer::sAllocatedBytes/(1024*1024), LLVBOPool::sBytesPooled/(1024*1024), LLVertexBuffer::sVertexCount/1024));
ypos += y_inc;
addText(xpos, ypos, llformat("%d Vertex Buffers", LLVertexBuffer::sGLCount));
@@ -558,6 +571,9 @@ public:
addText(xpos, ypos, llformat("%d Render Calls", gPipeline.mBatchCount));
ypos += y_inc;
+ addText(xpos, ypos, llformat("%d/%d Objects Active", gObjectList.getNumActiveObjects(), gObjectList.getNumObjects()));
+ ypos += y_inc;
+
addText(xpos, ypos, llformat("%d Matrix Ops", gPipeline.mMatrixOpCount));
ypos += y_inc;
@@ -623,6 +639,42 @@ public:
LLVertexBuffer::sSetCount = LLImageGL::sUniqueCount =
gPipeline.mNumVisibleNodes = LLPipeline::sVisibleLightCount = 0;
}
+ if (gSavedSettings.getBOOL("DebugShowAvatarRenderInfo"))
+ {
+ std::map<std::string, LLVOAvatar*> sorted_avs;
+
+ std::vector<LLCharacter*>::iterator sort_iter = LLCharacter::sInstances.begin();
+ while (sort_iter != LLCharacter::sInstances.end())
+ {
+ LLVOAvatar* avatar = dynamic_cast<LLVOAvatar*>(*sort_iter);
+ if (avatar &&
+ !avatar->isDead()) // Not dead yet
+ {
+ // Stuff into a sorted map so the display is ordered
+ sorted_avs[avatar->getFullname()] = avatar;
+ }
+ sort_iter++;
+ }
+
+ std::string trunc_name;
+ std::map<std::string, LLVOAvatar*>::reverse_iterator av_iter = sorted_avs.rbegin(); // Put "A" at the top
+ while (av_iter != sorted_avs.rend())
+ {
+ LLVOAvatar* avatar = av_iter->second;
+
+ avatar->calculateUpdateRenderCost(); // Make sure the numbers are up-to-date
+
+ trunc_name = utf8str_truncate(avatar->getFullname(), 16);
+ addText(xpos, ypos, llformat("%s : rez %d, weight %d, bytes %d area %.2f",
+ trunc_name.c_str(),
+ avatar->getRezzedStatus(),
+ avatar->getVisualComplexity(),
+ avatar->getAttachmentGeometryBytes(),
+ avatar->getAttachmentSurfaceArea()));
+ ypos += y_inc;
+ av_iter++;
+ }
+ }
if (gSavedSettings.getBOOL("DebugShowRenderMatrices"))
{
addText(xpos, ypos, llformat("%.4f .%4f %.4f %.4f", gGLProjection[12], gGLProjection[13], gGLProjection[14], gGLProjection[15]));
@@ -742,40 +794,41 @@ public:
if (gSavedSettings.getBOOL("DebugShowTextureInfo"))
{
LLViewerObject* objectp = NULL ;
- //objectp = = gAgentCamera.getFocusObject();
LLSelectNode* nodep = LLSelectMgr::instance().getHoverNode();
if (nodep)
{
- objectp = nodep->getObject();
+ objectp = nodep->getObject();
}
+
if (objectp && !objectp->isDead())
{
S32 num_faces = objectp->mDrawable->getNumFaces() ;
-
+ std::set<LLViewerFetchedTexture*> tex_list;
+
for(S32 i = 0 ; i < num_faces; i++)
{
LLFace* facep = objectp->mDrawable->getFace(i) ;
if(facep)
- {
- //addText(xpos, ypos, llformat("ts_min: %.3f ts_max: %.3f tt_min: %.3f tt_max: %.3f", facep->mTexExtents[0].mV[0], facep->mTexExtents[1].mV[0],
- // facep->mTexExtents[0].mV[1], facep->mTexExtents[1].mV[1]));
- //ypos += y_inc;
-
- addText(xpos, ypos, llformat("v_size: %.3f: p_size: %.3f", facep->getVirtualSize(), facep->getPixelArea()));
- ypos += y_inc;
-
- //const LLTextureEntry *tep = facep->getTextureEntry();
- //if(tep)
- //{
- // addText(xpos, ypos, llformat("scale_s: %.3f: scale_t: %.3f", tep->mScaleS, tep->mScaleT)) ;
- // ypos += y_inc;
- //}
-
- LLViewerTexture* tex = facep->getTexture() ;
+ {
+ LLViewerFetchedTexture* tex = dynamic_cast<LLViewerFetchedTexture*>(facep->getTexture()) ;
if(tex)
{
- addText(xpos, ypos, llformat("ID: %s v_size: %.3f", tex->getID().asString().c_str(), tex->getMaxVirtualSize()));
+ if(tex_list.find(tex) != tex_list.end())
+ {
+ continue ; //already displayed.
+ }
+ tex_list.insert(tex);
+
+ std::string uuid_str;
+ tex->getID().toString(uuid_str);
+ uuid_str = uuid_str.substr(0,7);
+
+ addText(xpos, ypos, llformat("ID: %s v_size: %.3f", uuid_str.c_str(), tex->getMaxVirtualSize()));
+ ypos += y_inc;
+
+ addText(xpos, ypos, llformat("discard level: %d desired level: %d Missing: %s", tex->getDiscardLevel(),
+ tex->getDesiredDiscardLevel(), tex->isMissingAsset() ? "Y" : "N"));
ypos += y_inc;
}
}
@@ -903,27 +956,18 @@ BOOL LLViewerWindow::handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK
{
llinfos << buttonname << " Mouse " << buttonstatestr << " handled by captor " << mouse_captor->getName() << llendl;
}
- return mouse_captor->handleAnyMouseClick(local_x, local_y, mask, clicktype, down);
- }
- // Topmost view gets a chance before the hierarchy
- //LLUICtrl* top_ctrl = gFocusMgr.getTopCtrl();
- //if (top_ctrl)
- //{
- // S32 local_x, local_y;
- // top_ctrl->screenPointToLocal( x, y, &local_x, &local_y );
- // if (top_ctrl->pointInView(local_x, local_y))
- // {
- // return top_ctrl->handleAnyMouseClick(local_x, local_y, mask, clicktype, down) ;
- // }
- // else
- // {
- // if (down)
- // {
- // gFocusMgr.setTopCtrl(NULL);
- // }
- // }
- //}
+ BOOL r = mouse_captor->handleAnyMouseClick(local_x, local_y, mask, clicktype, down);
+ if (r) {
+
+ lldebugs << "LLViewerWindow::handleAnyMouseClick viewer with mousecaptor calling updatemouseeventinfo - local_x|global x "<< local_x << " " << x << "local/global y " << local_y << " " << y << llendl;
+
+ LLViewerEventRecorder::instance().setMouseGlobalCoords(x,y);
+ LLViewerEventRecorder::instance().logMouseEvent(std::string(buttonstatestr),std::string(buttonname));
+
+ }
+ return r;
+ }
// Mark the click as handled and return if we aren't within the root view to avoid spurious bugs
if( !mRootView->pointInView(x, y) )
@@ -931,27 +975,44 @@ BOOL LLViewerWindow::handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK
return TRUE;
}
// Give the UI views a chance to process the click
- if( mRootView->handleAnyMouseClick(x, y, mask, clicktype, down) )
+
+ BOOL r= mRootView->handleAnyMouseClick(x, y, mask, clicktype, down) ;
+ if (r)
{
+
+ lldebugs << "LLViewerWindow::handleAnyMouseClick calling updatemouseeventinfo - global x "<< " " << x << "global y " << y << "buttonstate: " << buttonstatestr << " buttonname " << buttonname << llendl;
+
+ LLViewerEventRecorder::instance().setMouseGlobalCoords(x,y);
+
+ // Clear local coords - this was a click on root window so these are not needed
+ // By not including them, this allows the test skeleton generation tool to be smarter when generating code
+ // the code generator can be smarter because when local coords are present it can try the xui path with local coords
+ // and fallback to global coordinates only if needed.
+ // The drawback to this approach is sometimes a valid xui path will appear to work fine, but NOT interact with the UI element
+ // (VITA support not implemented yet or not visible to VITA due to widget further up xui path not being visible to VITA)
+ // For this reason it's best to provide hints where possible here by leaving out local coordinates
+ LLViewerEventRecorder::instance().setMouseLocalCoords(-1,-1);
+ LLViewerEventRecorder::instance().logMouseEvent(buttonstatestr,buttonname);
+
if (LLView::sDebugMouseHandling)
{
- llinfos << buttonname << " Mouse " << buttonstatestr << " " << LLView::sMouseHandlerMessage << llendl;
- }
+ llinfos << buttonname << " Mouse " << buttonstatestr << " " << LLViewerEventRecorder::instance().get_xui() << llendl;
+ }
return TRUE;
- }
- else if (LLView::sDebugMouseHandling)
- {
- llinfos << buttonname << " Mouse " << buttonstatestr << " not handled by view" << llendl;
- }
+ } else if (LLView::sDebugMouseHandling)
+ {
+ llinfos << buttonname << " Mouse " << buttonstatestr << " not handled by view" << llendl;
+ }
}
// Do not allow tool manager to handle mouseclicks if we have disconnected
if(!gDisconnected && LLToolMgr::getInstance()->getCurrentTool()->handleAnyMouseClick( x, y, mask, clicktype, down ) )
{
+ LLViewerEventRecorder::instance().clear_xui();
return TRUE;
}
-
+
// If we got this far on a down-click, it wasn't handled.
// Up-clicks, though, are always handled as far as the OS is concerned.
BOOL default_rtn = !down;
@@ -1322,7 +1383,8 @@ BOOL LLViewerWindow::handleTranslatedKeyUp(KEY key, MASK mask)
void LLViewerWindow::handleScanKey(KEY key, BOOL key_down, BOOL key_up, BOOL key_level)
{
LLViewerJoystick::getInstance()->setCameraNeedsUpdate(true);
- return gViewerKeyboard.scanKey(key, key_down, key_up, key_level);
+ gViewerKeyboard.scanKey(key, key_down, key_up, key_level);
+ return; // Be clear this function returns nothing
}
@@ -1536,7 +1598,8 @@ LLViewerWindow::LLViewerWindow(const Params& p)
mResDirty(false),
mStatesDirty(false),
mCurrResolutionIndex(0),
- mProgressView(NULL)
+ mProgressView(NULL),
+ mMouseVelocityStat(new LLStat("Mouse Velocity"))
{
// gKeyboard is still NULL, so it doesn't do LLWindowListener any good to
// pass its value right now. Instead, pass it a nullary function that
@@ -1544,19 +1607,34 @@ LLViewerWindow::LLViewerWindow(const Params& p)
// boost::lambda::var() constructs such a functor on the fly.
mWindowListener.reset(new LLWindowListener(this, boost::lambda::var(gKeyboard)));
mViewerWindowListener.reset(new LLViewerWindowListener(this));
- LLNotificationChannel::buildChannel("VW_alerts", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "alert"));
- LLNotificationChannel::buildChannel("VW_alertmodal", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "alertmodal"));
- LLNotifications::instance().getChannel("VW_alerts")->connectChanged(&LLViewerWindow::onAlert);
- LLNotifications::instance().getChannel("VW_alertmodal")->connectChanged(&LLViewerWindow::onAlert);
- LLNotifications::instance().setIgnoreAllNotifications(gSavedSettings.getBOOL("IgnoreAllNotifications"));
+ mSystemChannel.reset(new LLNotificationChannel("System", "Visible", LLNotificationFilters::includeEverything));
+ mCommunicationChannel.reset(new LLCommunicationChannel("Communication", "Visible"));
+ mAlertsChannel.reset(new LLNotificationsUI::LLViewerAlertHandler("VW_alerts", "alert"));
+ mModalAlertsChannel.reset(new LLNotificationsUI::LLViewerAlertHandler("VW_alertmodal", "alertmodal"));
+
+ bool ignore = gSavedSettings.getBOOL("IgnoreAllNotifications");
+ LLNotifications::instance().setIgnoreAllNotifications(ignore);
+ if (ignore)
+ {
llinfos << "NOTE: ALL NOTIFICATIONS THAT OCCUR WILL GET ADDED TO IGNORE LIST FOR LATER RUNS." << llendl;
+ }
// Default to application directory.
LLViewerWindow::sSnapshotBaseName = "Snapshot";
LLViewerWindow::sMovieBaseName = "SLmovie";
resetSnapshotLoc();
+
+ /*
+ LLWindowCallbacks* callbacks,
+ const std::string& title, const std::string& name, S32 x, S32 y, S32 width, S32 height, U32 flags,
+ BOOL fullscreen,
+ BOOL clearBg,
+ BOOL disable_vsync,
+ BOOL ignore_pixel_depth,
+ U32 fsaa_samples)
+ */
// create window
mWindow = LLWindowManager::createWindow(this,
p.title, p.name, p.x, p.y, p.width, p.height, 0,
@@ -1679,8 +1757,7 @@ LLViewerWindow::LLViewerWindow(const Params& p)
LLFontGL::initClass( gSavedSettings.getF32("FontScreenDPI"),
mDisplayScale.mV[VX],
mDisplayScale.mV[VY],
- gDirUtilp->getAppRODataDir(),
- LLUI::getXUIPaths());
+ gDirUtilp->getAppRODataDir());
// Create container for all sub-views
LLView::Params rvp;
@@ -1700,9 +1777,6 @@ LLViewerWindow::LLViewerWindow(const Params& p)
// Can't have spaces in settings.ini strings, so use underscores instead and convert them.
LLStringUtil::replaceChar(mOverlayTitle, '_', ' ');
- // sync the keyboard's setting with the saved setting
- gSavedSettings.getControl("NumpadControl")->firePropertyChanged();
-
mDebugText = new LLDebugText(this);
mWorldViewRectScaled = calcScaledRect(mWorldViewRectRaw, mDisplayScale);
@@ -1788,7 +1862,6 @@ void LLViewerWindow::initBase()
gFloaterView = main_view->getChild<LLFloaterView>("Floater View");
gFloaterView->setFloaterSnapView(main_view->getChild<LLView>("floater_snap_region")->getHandle());
gSnapshotFloaterView = main_view->getChild<LLSnapshotFloaterView>("Snapshot Floater View");
-
// Console
llassert( !gConsole );
@@ -1817,8 +1890,8 @@ void LLViewerWindow::initBase()
gDebugView->init();
gToolTipView = getRootView()->getChild<LLToolTipView>("tooltip view");
- // Initialize busy response message when logged in
- LLAppViewer::instance()->setOnLoginCompletedCallback(boost::bind(&LLFloaterPreference::initBusyResponse));
+ // Initialize do not disturb response message when logged in
+ LLAppViewer::instance()->setOnLoginCompletedCallback(boost::bind(&LLFloaterPreference::initDoNotDisturbResponse));
// Add the progress bar view (startup view), which overrides everything
mProgressView = getRootView()->findChild<LLProgressView>("progress_view");
@@ -1919,11 +1992,15 @@ void LLViewerWindow::initWorldUI()
getRootView()->addChild(gHUDView);
}
- LLPanel* panel_ssf_container = getRootView()->getChild<LLPanel>("stand_stop_flying_container");
+ LLPanel* panel_ssf_container = getRootView()->getChild<LLPanel>("state_management_buttons_container");
+
LLPanelStandStopFlying* panel_stand_stop_flying = LLPanelStandStopFlying::getInstance();
panel_ssf_container->addChild(panel_stand_stop_flying);
+
panel_ssf_container->setVisible(TRUE);
+ LLMenuOptionPathfindingRebakeNavmesh::getInstance()->initialize();
+
// Load and make the toolbars visible
// Note: we need to load the toolbars only *after* the user is logged in and IW
if (gToolBarView)
@@ -1970,6 +2047,9 @@ void LLViewerWindow::shutdownViews()
}
llinfos << "Global views cleaned." << llendl ;
+ LLNotificationsUI::LLToast::cleanupToasts();
+ llinfos << "Leftover toast cleaned up." << llendl;
+
// DEV-40930: Clear sModalStack. Otherwise, any LLModalDialog left open
// will crump with LL_ERRS.
LLModalDialog::shutdownModals();
@@ -1993,6 +2073,8 @@ void LLViewerWindow::shutdownViews()
mRootView = NULL;
llinfos << "RootView deleted." << llendl ;
+ LLMenuOptionPathfindingRebakeNavmesh::getInstance()->quit();
+
// Automatically deleted as children of mRootView. Fix the globals.
gStatusBar = NULL;
gIMMgr = NULL;
@@ -2060,6 +2142,8 @@ LLViewerWindow::~LLViewerWindow()
delete mDebugText;
mDebugText = NULL;
+
+ delete mMouseVelocityStat;
}
@@ -2127,7 +2211,7 @@ void LLViewerWindow::reshape(S32 width, S32 height)
calcDisplayScale();
- BOOL display_scale_changed = mDisplayScale != LLUI::sGLScaleFactor;
+ BOOL display_scale_changed = mDisplayScale != LLUI::getScaleFactor();
LLUI::setScaleFactor(mDisplayScale);
// update our window rectangle
@@ -2219,29 +2303,42 @@ void LLViewerWindow::setMenuBackgroundColor(bool god_mode, bool dev_grid)
// no l10n problem because channel is always an english string
std::string channel = LLVersionInfo::getChannel();
- bool isProject = (channel.find("Project") != std::string::npos);
+ static const boost::regex is_beta_channel("\\bBeta\\b");
+ static const boost::regex is_project_channel("\\bProject\\b");
+ static const boost::regex is_test_channel("\\bTest$");
// god more important than project, proj more important than grid
- if(god_mode && LLGridManager::getInstance()->isInProductionGrid())
+ if ( god_mode )
{
- new_bg_color = LLUIColorTable::instance().getColor( "MenuBarGodBgColor" );
- }
- else if(god_mode && !LLGridManager::getInstance()->isInProductionGrid())
- {
- new_bg_color = LLUIColorTable::instance().getColor( "MenuNonProductionGodBgColor" );
+ if ( LLGridManager::getInstance()->isInProductionGrid() )
+ {
+ new_bg_color = LLUIColorTable::instance().getColor( "MenuBarGodBgColor" );
+ }
+ else
+ {
+ new_bg_color = LLUIColorTable::instance().getColor( "MenuNonProductionGodBgColor" );
+ }
}
- else if (!god_mode && isProject)
+ else if (boost::regex_search(channel, is_beta_channel))
+ {
+ new_bg_color = LLUIColorTable::instance().getColor( "MenuBarBetaBgColor" );
+ }
+ else if (boost::regex_search(channel, is_project_channel))
{
new_bg_color = LLUIColorTable::instance().getColor( "MenuBarProjectBgColor" );
- }
- else if(!god_mode && !LLGridManager::getInstance()->isInProductionGrid())
- {
- new_bg_color = LLUIColorTable::instance().getColor( "MenuNonProductionBgColor" );
- }
- else
- {
- new_bg_color = LLUIColorTable::instance().getColor( "MenuBarBgColor" );
- }
+ }
+ else if (boost::regex_search(channel, is_test_channel))
+ {
+ new_bg_color = LLUIColorTable::instance().getColor( "MenuBarTestBgColor" );
+ }
+ else if(!LLGridManager::getInstance()->isInProductionGrid())
+ {
+ new_bg_color = LLUIColorTable::instance().getColor( "MenuNonProductionBgColor" );
+ }
+ else
+ {
+ new_bg_color = LLUIColorTable::instance().getColor( "MenuBarBgColor" );
+ }
if(gMenuBarView)
{
@@ -2333,7 +2430,7 @@ void LLViewerWindow::draw()
// scale view by UI global scale factor and aspect ratio correction factor
gGL.scaleUI(mDisplayScale.mV[VX], mDisplayScale.mV[VY], 1.f);
- LLVector2 old_scale_factor = LLUI::sGLScaleFactor;
+ LLVector2 old_scale_factor = LLUI::getScaleFactor();
// apply camera zoom transform (for high res screenshots)
F32 zoom_factor = LLViewerCamera::getInstance()->getZoomFactor();
S16 sub_region = LLViewerCamera::getInstance()->getZoomSubRegion();
@@ -2347,7 +2444,7 @@ void LLViewerWindow::draw()
(F32)getWindowHeightScaled() * -(F32)pos_y,
0.f);
gGL.scalef(zoom_factor, zoom_factor, 1.f);
- LLUI::sGLScaleFactor *= zoom_factor;
+ LLUI::getScaleFactor() *= zoom_factor;
}
// Draw tool specific overlay on world
@@ -2395,7 +2492,7 @@ void LLViewerWindow::draw()
LLFontGL::HCENTER, LLFontGL::TOP);
}
- LLUI::sGLScaleFactor = old_scale_factor;
+ LLUI::setScaleFactor(old_scale_factor);
}
LLUI::popMatrix();
gGL.popMatrix();
@@ -2433,6 +2530,8 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)
||(gLoginMenuBarView && gLoginMenuBarView->handleKey(key, mask, TRUE))
||(gMenuHolder && gMenuHolder->handleKey(key, mask, TRUE)))
{
+ lldebugs << "LLviewerWindow::handleKey handle nav keys for nav" << llendl;
+ LLViewerEventRecorder::instance().logKeyEvent(key,mask);
return TRUE;
}
@@ -2447,12 +2546,14 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)
&& keyboard_focus
&& keyboard_focus->handleKey(key,mask,FALSE))
{
+ LLViewerEventRecorder::instance().logKeyEvent(key,mask);
return TRUE;
}
if ((gMenuBarView && gMenuBarView->handleAcceleratorKey(key, mask))
||(gLoginMenuBarView && gLoginMenuBarView->handleAcceleratorKey(key, mask)))
{
+ LLViewerEventRecorder::instance().logKeyEvent(key,mask);
return TRUE;
}
}
@@ -2462,6 +2563,7 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)
// if nothing has focus, go to first or last UI element as appropriate
if (key == KEY_TAB && (mask & MASK_CONTROL || gFocusMgr.getKeyboardFocus() == NULL))
{
+ llwarns << "LLviewerWindow::handleKey give floaters first chance at tab key " << llendl;
if (gMenuHolder) gMenuHolder->hideMenus();
// if CTRL-tabbing (and not just TAB with no focus), go into window cycle mode
@@ -2476,34 +2578,30 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)
{
mRootView->focusNextRoot();
}
+ LLViewerEventRecorder::instance().logKeyEvent(key,mask);
return TRUE;
}
// hidden edit menu for cut/copy/paste
if (gEditMenu && gEditMenu->handleAcceleratorKey(key, mask))
{
+ LLViewerEventRecorder::instance().logKeyEvent(key,mask);
return TRUE;
}
- // Traverses up the hierarchy
+ LLFloater* focused_floaterp = gFloaterView->getFocusedFloater();
+ std::string focusedFloaterName = (focused_floaterp ? focused_floaterp->getInstanceName() : "");
+
if( keyboard_focus )
{
- LLNearbyChatBar* nearby_chat = LLFloaterReg::findTypedInstance<LLNearbyChatBar>("chat_bar");
-
- if (nearby_chat)
- {
- LLLineEditor* chat_editor = nearby_chat->getChatBox();
-
- // arrow keys move avatar while chatting hack
- if (chat_editor && chat_editor->hasFocus())
+ if ((focusedFloaterName == "nearby_chat") || (focusedFloaterName == "im_container") || (focusedFloaterName == "impanel"))
{
- // If text field is empty, there's no point in trying to move
- // cursor with arrow keys, so allow movement
- if (chat_editor->getText().empty()
- || gSavedSettings.getBOOL("ArrowKeysAlwaysMove"))
+ if (gSavedSettings.getBOOL("ArrowKeysAlwaysMove"))
{
// let Control-Up and Control-Down through for chat line history,
if (!(key == KEY_UP && mask == MASK_CONTROL)
- && !(key == KEY_DOWN && mask == MASK_CONTROL))
+ && !(key == KEY_DOWN && mask == MASK_CONTROL)
+ && !(key == KEY_UP && mask == MASK_ALT)
+ && !(key == KEY_DOWN && mask == MASK_ALT))
{
switch(key)
{
@@ -2521,23 +2619,32 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)
break;
}
}
- }
}
}
+
if (keyboard_focus->handleKey(key, mask, FALSE))
{
+
+ lldebugs << "LLviewerWindow::handleKey - in 'traverse up' - no loops seen... just called keyboard_focus->handleKey an it returned true" << llendl;
+ LLViewerEventRecorder::instance().logKeyEvent(key,mask);
return TRUE;
+ } else {
+ lldebugs << "LLviewerWindow::handleKey - in 'traverse up' - no loops seen... just called keyboard_focus->handleKey an it returned FALSE" << llendl;
}
}
if( LLToolMgr::getInstance()->getCurrentTool()->handleKey(key, mask) )
{
+ lldebugs << "LLviewerWindow::handleKey toolbar handling?" << llendl;
+ LLViewerEventRecorder::instance().logKeyEvent(key,mask);
return TRUE;
}
// Try for a new-format gesture
if (LLGestureMgr::instance().triggerGesture(key, mask))
{
+ lldebugs << "LLviewerWindow::handleKey new gesture feature" << llendl;
+ LLViewerEventRecorder::instance().logKeyEvent(key,mask);
return TRUE;
}
@@ -2545,6 +2652,8 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)
// don't pass it down to the menus.
if (gGestureList.trigger(key, mask))
{
+ lldebugs << "LLviewerWindow::handleKey check gesture trigger" << llendl;
+ LLViewerEventRecorder::instance().logKeyEvent(key,mask);
return TRUE;
}
@@ -2554,11 +2663,19 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)
if ( gSavedSettings.getS32("LetterKeysFocusChatBar") && !gAgentCamera.cameraMouselook() &&
!keyboard_focus && key < 0x80 && (mask == MASK_NONE || mask == MASK_SHIFT) )
{
- LLLineEditor* chat_editor = LLFloaterReg::getTypedInstance<LLNearbyChatBar>("chat_bar")->getChatBox();
+ // Initialize nearby chat if it's missing
+ LLFloaterIMNearbyChat* nearby_chat = LLFloaterReg::findTypedInstance<LLFloaterIMNearbyChat>("nearby_chat");
+ if (!nearby_chat)
+ {
+ LLSD name("im_container");
+ LLFloaterReg::toggleInstanceOrBringToFront(name);
+ }
+
+ LLChatEntry* chat_editor = LLFloaterReg::findTypedInstance<LLFloaterIMNearbyChat>("nearby_chat")->getChatBox();
if (chat_editor)
{
// passing NULL here, character will be added later when it is handled by character handler.
- LLNearbyChatBar::getInstance()->startChat(NULL);
+ nearby_chat->startChat(NULL);
return TRUE;
}
}
@@ -2585,9 +2702,12 @@ BOOL LLViewerWindow::handleUnicodeChar(llwchar uni_char, MASK mask)
// HACK: Numeric keypad <enter> on Mac is Unicode 3
// HACK: Control-M on Windows is Unicode 13
if ((uni_char == 13 && mask != MASK_CONTROL)
- || (uni_char == 3 && mask == MASK_NONE))
+ || (uni_char == 3 && mask == MASK_NONE) )
{
- return gViewerKeyboard.handleKey(KEY_RETURN, mask, gKeyboard->getKeyRepeated(KEY_RETURN));
+ if (mask != MASK_ALT)
+ {
+ return gViewerKeyboard.handleKey(KEY_RETURN, mask, gKeyboard->getKeyRepeated(KEY_RETURN));
+ }
}
// let menus handle navigation (jump) keys
@@ -2605,14 +2725,7 @@ BOOL LLViewerWindow::handleUnicodeChar(llwchar uni_char, MASK mask)
return TRUE;
}
- //// Topmost view gets a chance before the hierarchy
- //LLUICtrl* top_ctrl = gFocusMgr.getTopCtrl();
- //if (top_ctrl && top_ctrl->handleUnicodeChar( uni_char, FALSE ) )
- //{
- // return TRUE;
- //}
-
- return TRUE;
+ return TRUE;
}
return FALSE;
@@ -2621,8 +2734,6 @@ BOOL LLViewerWindow::handleUnicodeChar(llwchar uni_char, MASK mask)
void LLViewerWindow::handleScrollWheel(S32 clicks)
{
- LLView::sMouseHandlerMessage.clear();
-
LLUI::resetMouseIdleTimer();
LLMouseHandler* mouse_captor = gFocusMgr.getMouseCapture();
@@ -2792,9 +2903,11 @@ void LLViewerWindow::updateUI()
&gDebugRaycastIntersection,
&gDebugRaycastTexCoord,
&gDebugRaycastNormal,
- &gDebugRaycastBinormal,
+ &gDebugRaycastTangent,
&gDebugRaycastStart,
&gDebugRaycastEnd);
+
+ gDebugRaycastParticle = gPipeline.lineSegmentIntersectParticle(gDebugRaycastStart, gDebugRaycastEnd, &gDebugRaycastParticleIntersection, NULL);
}
updateMouseDelta();
@@ -2802,7 +2915,6 @@ void LLViewerWindow::updateUI()
BOOL handled = FALSE;
- BOOL handled_by_top_ctrl = FALSE;
LLUICtrl* top_ctrl = gFocusMgr.getTopCtrl();
LLMouseHandler* mouse_captor = gFocusMgr.getMouseCapture();
LLView* captor_view = dynamic_cast<LLView*>(mouse_captor);
@@ -2987,7 +3099,6 @@ void LLViewerWindow::updateUI()
S32 local_x, local_y;
top_ctrl->screenPointToLocal( x, y, &local_x, &local_y );
handled = top_ctrl->pointInView(local_x, local_y) && top_ctrl->handleHover(local_x, local_y, mask);
- handled_by_top_ctrl = TRUE;
}
if ( !handled )
@@ -3164,8 +3275,7 @@ void LLViewerWindow::updateLayout()
|| (tool != LLToolPie::getInstance() // not default tool
&& tool != LLToolCompGun::getInstance() // not coming out of mouselook
&& !suppress_toolbox // not override in third person
- && LLToolMgr::getInstance()->getCurrentToolset() != gFaceEditToolset // not special mode
- && LLToolMgr::getInstance()->getCurrentToolset() != gMouselookToolset
+ && LLToolMgr::getInstance()->getCurrentToolset()->isShowFloaterTools()
&& (!captor || dynamic_cast<LLView*>(captor) != NULL))) // not dragging
{
// Force floater tools to be visible (unless minimized)
@@ -3196,8 +3306,8 @@ void LLViewerWindow::updateLayout()
void LLViewerWindow::updateMouseDelta()
{
- S32 dx = lltrunc((F32) (mCurrentMousePoint.mX - mLastMousePoint.mX) * LLUI::sGLScaleFactor.mV[VX]);
- S32 dy = lltrunc((F32) (mCurrentMousePoint.mY - mLastMousePoint.mY) * LLUI::sGLScaleFactor.mV[VY]);
+ S32 dx = lltrunc((F32) (mCurrentMousePoint.mX - mLastMousePoint.mX) * LLUI::getScaleFactor().mV[VX]);
+ S32 dy = lltrunc((F32) (mCurrentMousePoint.mY - mLastMousePoint.mY) * LLUI::getScaleFactor().mV[VY]);
//RN: fix for asynchronous notification of mouse leaving window not working
LLCoordWindow mouse_pos;
@@ -3234,7 +3344,7 @@ void LLViewerWindow::updateMouseDelta()
mouse_vel.setVec((F32) dx, (F32) dy);
}
- mMouseVelocityStat.addValue(mouse_vel.magVec());
+ mMouseVelocityStat->addValue(mouse_vel.magVec());
}
void LLViewerWindow::updateKeyboardFocus()
@@ -3519,8 +3629,11 @@ void LLViewerWindow::renderSelections( BOOL for_gl_pick, BOOL pick_parcel_walls,
{
LLSelectNode* nodep = *iter;
LLViewerObject* object = nodep->getObject();
+ LLViewerObject *root_object = (object == NULL) ? NULL : object->getRootEdit();
BOOL this_object_movable = FALSE;
- if (object->permMove() && (object->permModify() || selecting_linked_set))
+ if (object->permMove() && !object->isPermanentEnforced() &&
+ ((root_object == NULL) || !root_object->isPermanentEnforced()) &&
+ (object->permModify() || selecting_linked_set))
{
moveable_object_selected = TRUE;
this_object_movable = TRUE;
@@ -3615,7 +3728,7 @@ void LLViewerWindow::pickAsync(S32 x, S32 y_from_bot, MASK mask, void (*callback
pick_transparent = TRUE;
}
- LLPickInfo pick_info(LLCoordGL(x, y_from_bot), mask, pick_transparent, TRUE, callback);
+ LLPickInfo pick_info(LLCoordGL(x, y_from_bot), mask, pick_transparent, FALSE, TRUE, callback);
schedulePick(pick_info);
}
@@ -3671,7 +3784,7 @@ void LLViewerWindow::returnEmptyPicks()
}
// Performs the GL object/land pick.
-LLPickInfo LLViewerWindow::pickImmediate(S32 x, S32 y_from_bot, BOOL pick_transparent)
+LLPickInfo LLViewerWindow::pickImmediate(S32 x, S32 y_from_bot, BOOL pick_transparent, BOOL pick_particle)
{
BOOL in_build_mode = LLFloaterReg::instanceVisible("build");
if (in_build_mode || LLDrawPoolAlpha::sShowDebugAlpha)
@@ -3680,17 +3793,17 @@ LLPickInfo LLViewerWindow::pickImmediate(S32 x, S32 y_from_bot, BOOL pick_trans
// "Show Debug Alpha" means no object actually transparent
pick_transparent = TRUE;
}
-
+
// shortcut queueing in mPicks and just update mLastPick in place
MASK key_mask = gKeyboard->currentMask(TRUE);
- mLastPick = LLPickInfo(LLCoordGL(x, y_from_bot), key_mask, pick_transparent, TRUE, NULL);
+ mLastPick = LLPickInfo(LLCoordGL(x, y_from_bot), key_mask, pick_transparent, pick_particle, TRUE, NULL);
mLastPick.fetchResults();
return mLastPick;
}
LLHUDIcon* LLViewerWindow::cursorIntersectIcon(S32 mouse_x, S32 mouse_y, F32 depth,
- LLVector3* intersection)
+ LLVector4a* intersection)
{
S32 x = mouse_x;
S32 y = mouse_y;
@@ -3702,14 +3815,17 @@ LLHUDIcon* LLViewerWindow::cursorIntersectIcon(S32 mouse_x, S32 mouse_y, F32 dep
}
// world coordinates of mouse
+ // VECTORIZE THIS
LLVector3 mouse_direction_global = mouseDirectionGlobal(x,y);
LLVector3 mouse_point_global = LLViewerCamera::getInstance()->getOrigin();
LLVector3 mouse_world_start = mouse_point_global;
LLVector3 mouse_world_end = mouse_point_global + mouse_direction_global * depth;
- return LLHUDIcon::lineSegmentIntersectAll(mouse_world_start, mouse_world_end, intersection);
-
+ LLVector4a start, end;
+ start.load3(mouse_world_start.mV);
+ end.load3(mouse_world_end.mV);
+ return LLHUDIcon::lineSegmentIntersectAll(start, end, intersection);
}
LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 depth,
@@ -3717,12 +3833,12 @@ LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 de
S32 this_face,
BOOL pick_transparent,
S32* face_hit,
- LLVector3 *intersection,
+ LLVector4a *intersection,
LLVector2 *uv,
- LLVector3 *normal,
- LLVector3 *binormal,
- LLVector3* start,
- LLVector3* end)
+ LLVector4a *normal,
+ LLVector4a *tangent,
+ LLVector4a* start,
+ LLVector4a* end)
{
S32 x = mouse_x;
S32 y = mouse_y;
@@ -3757,17 +3873,27 @@ LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 de
if (!LLViewerJoystick::getInstance()->getOverrideCamera())
{ //always set raycast intersection to mouse_world_end unless
//flycam is on (for DoF effect)
- gDebugRaycastIntersection = mouse_world_end;
+ gDebugRaycastIntersection.load3(mouse_world_end.mV);
}
+ LLVector4a mw_start;
+ mw_start.load3(mouse_world_start.mV);
+ LLVector4a mw_end;
+ mw_end.load3(mouse_world_end.mV);
+
+ LLVector4a mh_start;
+ mh_start.load3(mouse_hud_start.mV);
+ LLVector4a mh_end;
+ mh_end.load3(mouse_hud_end.mV);
+
if (start)
{
- *start = mouse_world_start;
+ *start = mw_start;
}
if (end)
{
- *end = mouse_world_end;
+ *end = mw_end;
}
LLViewerObject* found = NULL;
@@ -3776,16 +3902,16 @@ LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 de
{
if (this_object->isHUDAttachment()) // is a HUD object?
{
- if (this_object->lineSegmentIntersect(mouse_hud_start, mouse_hud_end, this_face, pick_transparent,
- face_hit, intersection, uv, normal, binormal))
+ if (this_object->lineSegmentIntersect(mh_start, mh_end, this_face, pick_transparent,
+ face_hit, intersection, uv, normal, tangent))
{
found = this_object;
}
}
else // is a world object
{
- if (this_object->lineSegmentIntersect(mouse_world_start, mouse_world_end, this_face, pick_transparent,
- face_hit, intersection, uv, normal, binormal))
+ if (this_object->lineSegmentIntersect(mw_start, mw_end, this_face, pick_transparent,
+ face_hit, intersection, uv, normal, tangent))
{
found = this_object;
}
@@ -3793,20 +3919,20 @@ LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 de
}
else // check ALL objects
{
- found = gPipeline.lineSegmentIntersectInHUD(mouse_hud_start, mouse_hud_end, pick_transparent,
- face_hit, intersection, uv, normal, binormal);
+ found = gPipeline.lineSegmentIntersectInHUD(mh_start, mh_end, pick_transparent,
+ face_hit, intersection, uv, normal, tangent);
if (!found) // if not found in HUD, look in world:
{
- found = gPipeline.lineSegmentIntersectInWorld(mouse_world_start, mouse_world_end, pick_transparent,
- face_hit, intersection, uv, normal, binormal);
+ found = gPipeline.lineSegmentIntersectInWorld(mw_start, mw_end, pick_transparent,
+ face_hit, intersection, uv, normal, tangent);
if (found && !pick_transparent)
{
gDebugRaycastIntersection = *intersection;
}
}
}
-
+
return found;
}
@@ -4220,14 +4346,51 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei
image_height = llmin(image_height, window_height);
}
+ S32 original_width = 0;
+ S32 original_height = 0;
+ bool reset_deferred = false;
+
+ LLRenderTarget scratch_space;
+
F32 scale_factor = 1.0f ;
if (!keep_window_aspect || (image_width > window_width) || (image_height > window_height))
{
- // if image cropping or need to enlarge the scene, compute a scale_factor
- F32 ratio = llmin( (F32)window_width / image_width , (F32)window_height / image_height) ;
- snapshot_width = (S32)(ratio * image_width) ;
- snapshot_height = (S32)(ratio * image_height) ;
- scale_factor = llmax(1.0f, 1.0f / ratio) ;
+ if ((image_width <= gGLManager.mGLMaxTextureSize && image_height <= gGLManager.mGLMaxTextureSize) &&
+ (image_width > window_width || image_height > window_height) && LLPipeline::sRenderDeferred && !show_ui)
+ {
+ if (scratch_space.allocate(image_width, image_height, GL_RGBA, true, true))
+ {
+ original_width = gPipeline.mDeferredScreen.getWidth();
+ original_height = gPipeline.mDeferredScreen.getHeight();
+
+ if (gPipeline.allocateScreenBuffer(image_width, image_height))
+ {
+ window_width = image_width;
+ window_height = image_height;
+ snapshot_width = image_width;
+ snapshot_height = image_height;
+ reset_deferred = true;
+ mWorldViewRectRaw.set(0, image_height, image_width, 0);
+ LLViewerCamera::getInstance()->setViewHeightInPixels( mWorldViewRectRaw.getHeight() );
+ LLViewerCamera::getInstance()->setAspect( getWorldViewAspectRatio() );
+ scratch_space.bindTarget();
+ }
+ else
+ {
+ scratch_space.release();
+ gPipeline.allocateScreenBuffer(original_width, original_height);
+ }
+ }
+ }
+
+ if (!reset_deferred)
+ {
+ // if image cropping or need to enlarge the scene, compute a scale_factor
+ F32 ratio = llmin( (F32)window_width / image_width , (F32)window_height / image_height) ;
+ snapshot_width = (S32)(ratio * image_width) ;
+ snapshot_height = (S32)(ratio * image_height) ;
+ scale_factor = llmax(1.0f, 1.0f / ratio) ;
+ }
}
if (show_ui && scale_factor > 1.f)
@@ -4416,11 +4579,22 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei
gPipeline.resetDrawOrders();
}
+ if (reset_deferred)
+ {
+ mWorldViewRectRaw = window_rect;
+ LLViewerCamera::getInstance()->setViewHeightInPixels( mWorldViewRectRaw.getHeight() );
+ LLViewerCamera::getInstance()->setAspect( getWorldViewAspectRatio() );
+ scratch_space.flush();
+ scratch_space.release();
+ gPipeline.allocateScreenBuffer(original_width, original_height);
+
+ }
+
if (high_res)
{
send_agent_resume();
}
-
+
return ret;
}
@@ -4656,6 +4830,8 @@ void LLViewerWindow::stopGL(BOOL save_state)
LLVOAvatar::destroyGL();
stop_glerror();
+ LLVOPartGroup::destroyGL();
+
LLViewerDynamicTexture::destroyGL();
stop_glerror();
@@ -4709,11 +4885,12 @@ void LLViewerWindow::restoreGL(const std::string& progress_message)
gBumpImageList.restoreGL();
LLViewerDynamicTexture::restoreGL();
LLVOAvatar::restoreGL();
+ LLVOPartGroup::restoreGL();
gResizeScreenTexture = TRUE;
gWindowResized = TRUE;
- if (isAgentAvatarValid() && !gAgentAvatarp->isUsingBakedTextures())
+ if (isAgentAvatarValid() && gAgentAvatarp->isEditingAppearance())
{
LLVisualParamHint::requestHintUpdates();
}
@@ -4744,8 +4921,7 @@ void LLViewerWindow::initFonts(F32 zoom_factor)
LLFontGL::initClass( gSavedSettings.getF32("FontScreenDPI"),
mDisplayScale.mV[VX] * zoom_factor,
mDisplayScale.mV[VY] * zoom_factor,
- gDirUtilp->getAppRODataDir(),
- LLUI::getXUIPaths());
+ gDirUtilp->getAppRODataDir());
// Force font reloads, which can be very slow
LLFontGL::loadDefaultFonts();
}
@@ -4755,8 +4931,11 @@ void LLViewerWindow::requestResolutionUpdate()
mResDirty = true;
}
+static LLFastTimer::DeclareTimer FTM_WINDOW_CHECK_SETTINGS("Window Settings");
+
void LLViewerWindow::checkSettings()
{
+ LLFastTimer t(FTM_WINDOW_CHECK_SETTINGS);
if (mStatesDirty)
{
gGL.refreshState();
@@ -4934,7 +5113,7 @@ S32 LLViewerWindow::getChatConsoleBottomPad()
S32 offset = 0;
if(gToolBarView)
- offset += gToolBarView->getChild<LLView>("bottom_toolbar_panel")->getRect().getHeight();
+ offset += gToolBarView->getBottomToolbar()->getRect().getHeight();
return offset;
}
@@ -4971,25 +5150,6 @@ LLRect LLViewerWindow::getChatConsoleRect()
//----------------------------------------------------------------------------
-//static
-bool LLViewerWindow::onAlert(const LLSD& notify)
-{
- LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID());
-
- if (gHeadlessClient)
- {
- llinfos << "Alert: " << notification->getName() << llendl;
- }
-
- // If we're in mouselook, the mouse is hidden and so the user can't click
- // the dialog buttons. In that case, change to First Person instead.
- if( gAgentCamera.cameraMouselook() )
- {
- gAgentCamera.changeCameraToDefault();
- }
- return false;
-}
-
void LLViewerWindow::setUIVisibility(bool visible)
{
mUIVisible = visible;
@@ -5034,15 +5194,18 @@ LLPickInfo::LLPickInfo()
mXYCoords(-1, -1),
mIntersection(),
mNormal(),
+ mTangent(),
mBinormal(),
mHUDIcon(NULL),
- mPickTransparent(FALSE)
+ mPickTransparent(FALSE),
+ mPickParticle(FALSE)
{
}
LLPickInfo::LLPickInfo(const LLCoordGL& mouse_pos,
MASK keyboard_mask,
BOOL pick_transparent,
+ BOOL pick_particle,
BOOL pick_uv_coords,
void (*pick_callback)(const LLPickInfo& pick_info))
: mMousePt(mouse_pos),
@@ -5055,9 +5218,11 @@ LLPickInfo::LLPickInfo(const LLCoordGL& mouse_pos,
mSTCoords(-1.f, -1.f),
mXYCoords(-1, -1),
mNormal(),
+ mTangent(),
mBinormal(),
mHUDIcon(NULL),
- mPickTransparent(pick_transparent)
+ mPickTransparent(pick_transparent),
+ mPickParticle(pick_particle)
{
}
@@ -5065,36 +5230,62 @@ void LLPickInfo::fetchResults()
{
S32 face_hit = -1;
- LLVector3 intersection, normal, binormal;
+ LLVector4a intersection, normal;
+ LLVector4a tangent;
+
LLVector2 uv;
LLHUDIcon* hit_icon = gViewerWindow->cursorIntersectIcon(mMousePt.mX, mMousePt.mY, 512.f, &intersection);
+ LLVector4a origin;
+ origin.load3(LLViewerCamera::getInstance()->getOrigin().mV);
F32 icon_dist = 0.f;
+ LLVector4a start;
+ LLVector4a end;
+ LLVector4a particle_end;
+
if (hit_icon)
{
- icon_dist = (LLViewerCamera::getInstance()->getOrigin()-intersection).magVec();
+ LLVector4a delta;
+ delta.setSub(intersection, origin);
+ icon_dist = delta.getLength3().getF32();
}
+
LLViewerObject* hit_object = gViewerWindow->cursorIntersect(mMousePt.mX, mMousePt.mY, 512.f,
NULL, -1, mPickTransparent, &face_hit,
- &intersection, &uv, &normal, &binormal);
+ &intersection, &uv, &normal, &tangent, &start, &end);
mPickPt = mMousePt;
U32 te_offset = face_hit > -1 ? face_hit : 0;
- //unproject relative clicked coordinate from window coordinate using GL
-
+ if (mPickParticle)
+ { //get the end point of line segement to use for particle raycast
+ if (hit_object)
+ {
+ particle_end = intersection;
+ }
+ else
+ {
+ particle_end = end;
+ }
+ }
+
LLViewerObject* objectp = hit_object;
+
+ LLVector4a delta;
+ delta.setSub(origin, intersection);
+
if (hit_icon &&
(!objectp ||
- icon_dist < (LLViewerCamera::getInstance()->getOrigin()-intersection).magVec()))
+ icon_dist < delta.getLength3().getF32()))
{
// was this name referring to a hud icon?
mHUDIcon = hit_icon;
mPickType = PICK_ICON;
mPosGlobal = mHUDIcon->getPositionGlobal();
+
}
else if (objectp)
{
@@ -5126,11 +5317,16 @@ void LLPickInfo::fetchResults()
{
mPickType = PICK_OBJECT;
}
- mObjectOffset = gAgentCamera.calcFocusOffset(objectp, intersection, mPickPt.mX, mPickPt.mY);
+
+ LLVector3 v_intersection(intersection.getF32ptr());
+
+ mObjectOffset = gAgentCamera.calcFocusOffset(objectp, v_intersection, mPickPt.mX, mPickPt.mY);
mObjectID = objectp->mID;
mObjectFace = (te_offset == NO_FACE) ? -1 : (S32)te_offset;
- mPosGlobal = gAgent.getPosGlobalFromAgent(intersection);
+
+
+ mPosGlobal = gAgent.getPosGlobalFromAgent(v_intersection);
if (mWantSurfaceInfo)
{
@@ -5139,6 +5335,18 @@ void LLPickInfo::fetchResults()
}
}
+ if (mPickParticle)
+ { //search for closest particle to click origin out to intersection point
+ S32 part_face = -1;
+
+ LLVOPartGroup* group = gPipeline.lineSegmentIntersectParticle(start, particle_end, NULL, &part_face);
+ if (group)
+ {
+ mParticleOwnerID = group->getPartOwner(part_face);
+ mParticleSourceID = group->getPartSource(part_face);
+ }
+ }
+
if (mPickCallback)
{
mPickCallback(*this);
@@ -5174,7 +5382,16 @@ void LLPickInfo::getSurfaceInfo()
mIntersection = LLVector3(0,0,0);
mNormal = LLVector3(0,0,0);
mBinormal = LLVector3(0,0,0);
+ mTangent = LLVector4(0,0,0,0);
+ LLVector4a tangent;
+ LLVector4a intersection;
+ LLVector4a normal;
+
+ tangent.clear();
+ normal.clear();
+ intersection.clear();
+
LLViewerObject* objectp = getObject();
if (objectp)
@@ -5182,20 +5399,38 @@ void LLPickInfo::getSurfaceInfo()
if (gViewerWindow->cursorIntersect(llround((F32)mMousePt.mX), llround((F32)mMousePt.mY), 1024.f,
objectp, -1, mPickTransparent,
&mObjectFace,
- &mIntersection,
+ &intersection,
&mSTCoords,
- &mNormal,
- &mBinormal))
+ &normal,
+ &tangent))
{
// if we succeeded with the intersect above, compute the texture coordinates:
if (objectp->mDrawable.notNull() && mObjectFace > -1)
{
LLFace* facep = objectp->mDrawable->getFace(mObjectFace);
-
- mUVCoords = facep->surfaceToTexture(mSTCoords, mIntersection, mNormal);
+ if (facep)
+ {
+ mUVCoords = facep->surfaceToTexture(mSTCoords, intersection, normal);
+ }
}
+ mIntersection.set(intersection.getF32ptr());
+ mNormal.set(normal.getF32ptr());
+ mTangent.set(tangent.getF32ptr());
+
+ //extrapoloate binormal from normal and tangent
+
+ LLVector4a binormal;
+ binormal.setCross3(normal, tangent);
+ binormal.mul(tangent.getF32ptr()[3]);
+
+ mBinormal.set(binormal.getF32ptr());
+
+ mBinormal.normalize();
+ mNormal.normalize();
+ mTangent.normalize();
+
// and XY coords:
updateXYCoords();
diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h
index 6efcaeaf18..c16b80b214 100644..100755
--- a/indra/newview/llviewerwindow.h
+++ b/indra/newview/llviewerwindow.h
@@ -41,8 +41,8 @@
#include "llcursortypes.h"
#include "llwindowcallbacks.h"
#include "lltimer.h"
-#include "llstat.h"
#include "llmousehandler.h"
+#include "llnotifications.h"
#include "llhandle.h"
#include "llinitparam.h"
@@ -50,7 +50,7 @@
#include <boost/signals2.hpp>
#include <boost/scoped_ptr.hpp>
-
+class LLStat;
class LLView;
class LLViewerObject;
class LLUUID;
@@ -65,6 +65,7 @@ class LLWindow;
class LLRootView;
class LLWindowListener;
class LLViewerWindowListener;
+class LLVOPartGroup;
class LLPopupView;
#define PICK_HALF_WIDTH 5
@@ -87,7 +88,8 @@ public:
LLPickInfo();
LLPickInfo(const LLCoordGL& mouse_pos,
MASK keyboard_mask,
- BOOL pick_transparent,
+ BOOL pick_transparent,
+ BOOL pick_particle,
BOOL pick_surface_info,
void (*pick_callback)(const LLPickInfo& pick_info));
@@ -108,6 +110,8 @@ public:
LLVector3d mPosGlobal;
LLVector3 mObjectOffset;
LLUUID mObjectID;
+ LLUUID mParticleOwnerID;
+ LLUUID mParticleSourceID;
S32 mObjectFace;
LLHUDIcon* mHUDIcon;
LLVector3 mIntersection;
@@ -115,8 +119,10 @@ public:
LLVector2 mSTCoords;
LLCoordScreen mXYCoords;
LLVector3 mNormal;
+ LLVector4 mTangent;
LLVector3 mBinormal;
BOOL mPickTransparent;
+ BOOL mPickParticle;
void getSurfaceInfo();
private:
@@ -251,7 +257,7 @@ public:
S32 getCurrentMouseDX() const { return mCurrentMouseDelta.mX; }
S32 getCurrentMouseDY() const { return mCurrentMouseDelta.mY; }
LLCoordGL getCurrentMouseDelta() const { return mCurrentMouseDelta; }
- LLStat * getMouseVelocityStat() { return &mMouseVelocityStat; }
+ LLStat* getMouseVelocityStat() { return mMouseVelocityStat; }
BOOL getLeftMouseDown() const { return mLeftMouseDown; }
BOOL getMiddleMouseDown() const { return mMiddleMouseDown; }
BOOL getRightMouseDown() const { return mRightMouseDown; }
@@ -355,21 +361,21 @@ public:
void returnEmptyPicks();
void pickAsync(S32 x, S32 y_from_bot, MASK mask, void (*callback)(const LLPickInfo& pick_info), BOOL pick_transparent = FALSE);
- LLPickInfo pickImmediate(S32 x, S32 y, BOOL pick_transparent);
+ LLPickInfo pickImmediate(S32 x, S32 y, BOOL pick_transparent, BOOL pick_particle = FALSE);
LLHUDIcon* cursorIntersectIcon(S32 mouse_x, S32 mouse_y, F32 depth,
- LLVector3* intersection);
+ LLVector4a* intersection);
LLViewerObject* cursorIntersect(S32 mouse_x = -1, S32 mouse_y = -1, F32 depth = 512.f,
LLViewerObject *this_object = NULL,
S32 this_face = -1,
BOOL pick_transparent = FALSE,
S32* face_hit = NULL,
- LLVector3 *intersection = NULL,
+ LLVector4a *intersection = NULL,
LLVector2 *uv = NULL,
- LLVector3 *normal = NULL,
- LLVector3 *binormal = NULL,
- LLVector3* start = NULL,
- LLVector3* end = NULL);
+ LLVector4a *normal = NULL,
+ LLVector4a *tangent = NULL,
+ LLVector4a* start = NULL,
+ LLVector4a* end = NULL);
// Returns a pointer to the last object hit
@@ -401,7 +407,6 @@ public:
private:
bool shouldShowToolTipFor(LLMouseHandler *mh);
- static bool onAlert(const LLSD& notify);
void switchToolByMask(MASK mask);
void destroyWindow();
@@ -418,6 +423,11 @@ private:
bool mActive;
bool mUIVisible;
+ LLNotificationChannelPtr mSystemChannel;
+ LLNotificationChannelPtr mCommunicationChannel;
+ LLNotificationChannelPtr mAlertsChannel;
+ LLNotificationChannelPtr mModalAlertsChannel;
+
LLRect mWindowRectRaw; // whole window, including UI
LLRect mWindowRectScaled; // whole window, scaled by UI size
LLRect mWorldViewRectRaw; // area of screen for 3D world
@@ -428,7 +438,7 @@ private:
LLCoordGL mCurrentMousePoint; // last mouse position in GL coords
LLCoordGL mLastMousePoint; // Mouse point at last frame.
LLCoordGL mCurrentMouseDelta; //amount mouse moved this frame
- LLStat mMouseVelocityStat;
+ LLStat* mMouseVelocityStat;
BOOL mLeftMouseDown;
BOOL mMiddleMouseDown;
BOOL mRightMouseDown;
@@ -495,13 +505,15 @@ extern LLFrameTimer gAwayTimer; // tracks time before setting the avatar awa
extern LLFrameTimer gAwayTriggerTimer; // how long the avatar has been away
extern LLViewerObject* gDebugRaycastObject;
-extern LLVector3 gDebugRaycastIntersection;
+extern LLVector4a gDebugRaycastIntersection;
+extern LLVOPartGroup* gDebugRaycastParticle;
+extern LLVector4a gDebugRaycastParticleIntersection;
extern LLVector2 gDebugRaycastTexCoord;
-extern LLVector3 gDebugRaycastNormal;
-extern LLVector3 gDebugRaycastBinormal;
+extern LLVector4a gDebugRaycastNormal;
+extern LLVector4a gDebugRaycastTangent;
extern S32 gDebugRaycastFaceHit;
-extern LLVector3 gDebugRaycastStart;
-extern LLVector3 gDebugRaycastEnd;
+extern LLVector4a gDebugRaycastStart;
+extern LLVector4a gDebugRaycastEnd;
extern BOOL gDisplayCameraPos;
extern BOOL gDisplayWindInfo;
diff --git a/indra/newview/llviewerwindowlistener.cpp b/indra/newview/llviewerwindowlistener.cpp
index 1fe5fc9800..1fe5fc9800 100644..100755
--- a/indra/newview/llviewerwindowlistener.cpp
+++ b/indra/newview/llviewerwindowlistener.cpp
diff --git a/indra/newview/llviewerwindowlistener.h b/indra/newview/llviewerwindowlistener.h
index d627aad266..d627aad266 100644..100755
--- a/indra/newview/llviewerwindowlistener.h
+++ b/indra/newview/llviewerwindowlistener.h
diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp
index ec932501e5..94760e3c83 100644..100755
--- a/indra/newview/llvlcomposition.cpp
+++ b/indra/newview/llvlcomposition.cpp
@@ -223,7 +223,7 @@ BOOL LLVLComposition::generateComposition()
{
if (mDetailTextures[i]->getDiscardLevel() < 0)
{
- mDetailTextures[i]->setBoostLevel(LLViewerTexture::BOOST_TERRAIN); // in case we are at low detail
+ mDetailTextures[i]->setBoostLevel(LLGLTexture::BOOST_TERRAIN); // in case we are at low detail
mDetailTextures[i]->addTextureStats(BASE_SIZE*BASE_SIZE);
return FALSE;
}
@@ -240,7 +240,7 @@ BOOL LLVLComposition::generateComposition()
ddiscard++;
min_dim /= 2;
}
- mDetailTextures[i]->setBoostLevel(LLViewerTexture::BOOST_TERRAIN); // in case we are at low detail
+ mDetailTextures[i]->setBoostLevel(LLGLTexture::BOOST_TERRAIN); // in case we are at low detail
mDetailTextures[i]->setMinDiscardLevel(ddiscard);
return FALSE;
}
@@ -376,9 +376,6 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y,
LLPointer<LLImageRaw> raw = new LLImageRaw(tex_width, tex_height, tex_comps);
U8 *rawp = raw->getData();
- F32 tex_width_inv = 1.f/tex_width;
- F32 tex_height_inv = 1.f/tex_height;
-
F32 st_x_stride, st_y_stride;
st_x_stride = ((F32)st_width / (F32)mTexScaleX)*((F32)mWidth / (F32)tex_width);
st_y_stride = ((F32)st_height / (F32)mTexScaleY)*((F32)mWidth / (F32)tex_height);
@@ -413,11 +410,6 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y,
tex1 = tex0 + 1;
tex1 = llclamp(tex1, 0, 3);
- F32 xy_int_i, xy_int_j;
-
- xy_int_i = i * tex_width_inv;
- xy_int_j = j * tex_height_inv;
-
st_offset = (lltrunc(sti) + lltrunc(stj)*st_width) * st_comps;
for (U32 k = 0; k < tex_comps; k++)
{
@@ -457,13 +449,11 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y,
texturep->createGLTexture(0, raw);
}
texturep->setSubImage(raw, tex_x_begin, tex_y_begin, tex_x_end - tex_x_begin, tex_y_end - tex_y_begin);
- LLSurface::sTextureUpdateTime += gen_timer.getElapsedTimeF32();
- LLSurface::sTexelsUpdated += (tex_x_end - tex_x_begin) * (tex_y_end - tex_y_begin);
for (S32 i = 0; i < 4; i++)
{
// Un-boost detatil textures (will get re-boosted if rendering in high detail)
- mDetailTextures[i]->setBoostLevel(LLViewerTexture::BOOST_NONE);
+ mDetailTextures[i]->setBoostLevel(LLGLTexture::BOOST_NONE);
mDetailTextures[i]->setMinDiscardLevel(MAX_DISCARD_LEVEL + 1);
}
diff --git a/indra/newview/llvlcomposition.h b/indra/newview/llvlcomposition.h
index 2dd04ac5a5..2dd04ac5a5 100644..100755
--- a/indra/newview/llvlcomposition.h
+++ b/indra/newview/llvlcomposition.h
diff --git a/indra/newview/llvlmanager.cpp b/indra/newview/llvlmanager.cpp
index d8de979f56..d8de979f56 100644..100755
--- a/indra/newview/llvlmanager.cpp
+++ b/indra/newview/llvlmanager.cpp
diff --git a/indra/newview/llvlmanager.h b/indra/newview/llvlmanager.h
index 74b4823a5c..74b4823a5c 100644..100755
--- a/indra/newview/llvlmanager.h
+++ b/indra/newview/llvlmanager.h
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index a7a4281860..f5918a0a5f 100644..100755
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -24,18 +24,13 @@
* $/LicenseInfo$
*/
-#if LL_MSVC
-// disable warning about boost::lexical_cast returning uninitialized data
-// when it fails to parse the string
-#pragma warning (disable:4701)
-#endif
-
#include "llviewerprecompiledheaders.h"
#include "llvoavatar.h"
#include <stdio.h>
#include <ctype.h>
+#include <sstream>
#include "llaudioengine.h"
#include "noise.h"
@@ -53,6 +48,7 @@
#include "llcallingcard.h" // IDEVO for LLAvatarTracker
#include "lldrawpoolavatar.h"
#include "lldriverparam.h"
+#include "llpolyskeletaldistortion.h"
#include "lleditingmotion.h"
#include "llemote.h"
//#include "llfirstuse.h"
@@ -62,6 +58,8 @@
#include "llhudmanager.h"
#include "llhudnametag.h"
#include "llhudtext.h" // for mText/mDebugText
+#include "llimview.h"
+#include "llinitparam.h"
#include "llkeyframefallmotion.h"
#include "llkeyframestandmotion.h"
#include "llkeyframewalkmotion.h"
@@ -77,15 +75,16 @@
#include "llselectmgr.h"
#include "llsprite.h"
#include "lltargetingmotion.h"
-#include "lltexlayer.h"
#include "lltoolmorph.h"
#include "llviewercamera.h"
+#include "llviewertexlayer.h"
#include "llviewertexturelist.h"
#include "llviewermenu.h"
#include "llviewerobjectlist.h"
#include "llviewerparcelmgr.h"
#include "llviewershadermgr.h"
#include "llviewerstats.h"
+#include "llviewerwearable.h"
#include "llvoavatarself.h"
#include "llvovolume.h"
#include "llworld.h"
@@ -101,21 +100,18 @@
#include "llvoicevisualizer.h" // Ventrella
#include "lldebugmessagebox.h"
+#include "llsdutil.h"
+#include "llsdserialize.h"
+
extern F32 SPEED_ADJUST_MAX;
extern F32 SPEED_ADJUST_MAX_SEC;
extern F32 ANIM_SPEED_MAX;
extern F32 ANIM_SPEED_MIN;
-#if LL_MSVC
-// disable boost::lexical_cast warning
-#pragma warning (disable:4702)
-#endif
-
-#include <boost/lexical_cast.hpp>
// #define OUTPUT_BREAST_DATA
-using namespace LLVOAvatarDefines;
+using namespace LLAvatarAppearanceDefines;
//-----------------------------------------------------------------------------
// Global constants
@@ -136,7 +132,6 @@ const LLUUID ANIM_AGENT_PHYSICS_MOTION = LLUUID("7360e029-3cb8-ebc4-863e-212df44
//-----------------------------------------------------------------------------
// Constants
//-----------------------------------------------------------------------------
-const std::string AVATAR_DEFAULT_CHAR = "avatar";
const S32 MIN_PIXEL_AREA_FOR_COMPOSITE = 1024;
const F32 SHADOW_OFFSET_AMT = 0.03f;
@@ -189,8 +184,9 @@ const S32 MAX_BUBBLE_CHAT_LENGTH = DB_CHAT_MSG_STR_LEN;
const S32 MAX_BUBBLE_CHAT_UTTERANCES = 12;
const F32 CHAT_FADE_TIME = 8.0;
const F32 BUBBLE_CHAT_TIME = CHAT_FADE_TIME * 3.f;
-
-const LLColor4 DUMMY_COLOR = LLColor4(0.5,0.5,0.5,1.0);
+const F32 NAMETAG_UPDATE_THRESHOLD = 0.3f;
+const F32 NAMETAG_VERTICAL_SCREEN_OFFSET = 25.f;
+const F32 NAMETAG_VERT_OFFSET_WEIGHT = 0.17f;
enum ERenderName
{
@@ -220,57 +216,86 @@ struct LLTextureMaskData
**/
//------------------------------------------------------------------------
-// LLVOBoneInfo
+// LLVOAvatarBoneInfo
// Trans/Scale/Rot etc. info about each avatar bone. Used by LLVOAvatarSkeleton.
//------------------------------------------------------------------------
-class LLVOAvatarBoneInfo
+struct LLVOAvatarCollisionVolumeInfo : public LLInitParam::Block<LLVOAvatarCollisionVolumeInfo>
{
- friend class LLVOAvatar;
- friend class LLVOAvatarSkeletonInfo;
-public:
- LLVOAvatarBoneInfo() : mIsJoint(FALSE) {}
- ~LLVOAvatarBoneInfo()
+ LLVOAvatarCollisionVolumeInfo()
+ : name("name"),
+ pos("pos"),
+ rot("rot"),
+ scale("scale")
+ {}
+
+ Mandatory<std::string> name;
+ Mandatory<LLVector3> pos,
+ rot,
+ scale;
+};
+
+struct LLAppearanceMessageContents
+{
+ LLAppearanceMessageContents():
+ mAppearanceVersion(-1),
+ mParamAppearanceVersion(-1),
+ mCOFVersion(LLViewerInventoryCategory::VERSION_UNKNOWN)
{
- std::for_each(mChildList.begin(), mChildList.end(), DeletePointer());
}
- BOOL parseXml(LLXmlTreeNode* node);
+ LLTEContents mTEContents;
+ S32 mAppearanceVersion;
+ S32 mParamAppearanceVersion;
+ S32 mCOFVersion;
+ // For future use:
+ //U32 appearance_flags = 0;
+ std::vector<F32> mParamWeights;
+ std::vector<LLVisualParam*> mParams;
+};
+
+struct LLVOAvatarChildJoint : public LLInitParam::ChoiceBlock<LLVOAvatarChildJoint>
+ {
+ Alternative<Lazy<struct LLVOAvatarBoneInfo, IS_A_BLOCK> > bone;
+ Alternative<LLVOAvatarCollisionVolumeInfo> collision_volume;
-private:
- std::string mName;
- BOOL mIsJoint;
- LLVector3 mPos;
- LLVector3 mRot;
- LLVector3 mScale;
- LLVector3 mPivot;
- typedef std::vector<LLVOAvatarBoneInfo*> child_list_t;
- child_list_t mChildList;
+ LLVOAvatarChildJoint()
+ : bone("bone"),
+ collision_volume("collision_volume")
+ {}
+};
+
+
+
+struct LLVOAvatarBoneInfo : public LLInitParam::Block<LLVOAvatarBoneInfo, LLVOAvatarCollisionVolumeInfo>
+{
+ LLVOAvatarBoneInfo()
+ : pivot("pivot")
+ {}
+
+ Mandatory<LLVector3> pivot;
+ Multiple<LLVOAvatarChildJoint> children;
};
//------------------------------------------------------------------------
// LLVOAvatarSkeletonInfo
// Overall avatar skeleton
//------------------------------------------------------------------------
-class LLVOAvatarSkeletonInfo
+struct LLVOAvatarSkeletonInfo : public LLInitParam::Block<LLVOAvatarSkeletonInfo>
{
- friend class LLVOAvatar;
-public:
- LLVOAvatarSkeletonInfo() :
- mNumBones(0), mNumCollisionVolumes(0) {}
- ~LLVOAvatarSkeletonInfo()
- {
- std::for_each(mBoneInfoList.begin(), mBoneInfoList.end(), DeletePointer());
- }
- BOOL parseXml(LLXmlTreeNode* node);
- S32 getNumBones() const { return mNumBones; }
- S32 getNumCollisionVolumes() const { return mNumCollisionVolumes; }
+ LLVOAvatarSkeletonInfo()
+ : skeleton_root(""),
+ num_bones("num_bones"),
+ num_collision_volumes("num_collision_volumes"),
+ version("version")
+ {}
-private:
- S32 mNumBones;
- S32 mNumCollisionVolumes;
- typedef std::vector<LLVOAvatarBoneInfo*> bone_info_list_t;
- bone_info_list_t mBoneInfoList;
+ Mandatory<std::string> version;
+ Mandatory<S32> num_bones,
+ num_collision_volumes;
+ Mandatory<LLVOAvatarChildJoint> skeleton_root;
};
+
+
//-----------------------------------------------------------------------------
// class LLBodyNoiseMotion
//-----------------------------------------------------------------------------
@@ -592,11 +617,7 @@ private:
//-----------------------------------------------------------------------------
// Static Data
//-----------------------------------------------------------------------------
-LLXmlTree LLVOAvatar::sXMLTree;
-LLXmlTree LLVOAvatar::sSkeletonXMLTree;
-LLVOAvatarSkeletonInfo* LLVOAvatar::sAvatarSkeletonInfo = NULL;
-LLVOAvatar::LLVOAvatarXmlInfo* LLVOAvatar::sAvatarXmlInfo = NULL;
-LLVOAvatarDictionary *LLVOAvatar::sAvatarDictionary = NULL;
+LLAvatarAppearanceDictionary *LLVOAvatar::sAvatarDictionary = NULL;
S32 LLVOAvatar::sFreezeCounter = 0;
U32 LLVOAvatar::sMaxVisible = 12;
F32 LLVOAvatar::sRenderDistance = 256.f;
@@ -627,7 +648,6 @@ F32 LLVOAvatar::sLODFactor = 1.f;
F32 LLVOAvatar::sPhysicsLODFactor = 1.f;
BOOL LLVOAvatar::sUseImpostors = FALSE;
BOOL LLVOAvatar::sJointDebug = FALSE;
-
F32 LLVOAvatar::sUnbakedTime = 0.f;
F32 LLVOAvatar::sUnbakedUpdateTime = 0.f;
F32 LLVOAvatar::sGreyTime = 0.f;
@@ -644,15 +664,14 @@ static F32 calc_bouncy_animation(F32 x);
LLVOAvatar::LLVOAvatar(const LLUUID& id,
const LLPCode pcode,
LLViewerRegion* regionp) :
+ LLAvatarAppearance(&gAgentWearables),
LLViewerObject(id, pcode, regionp),
- mIsDummy(FALSE),
mSpecialRenderMode(0),
- mAttachmentGeometryBytes(0),
- mAttachmentSurfaceArea(0.f),
+ mAttachmentGeometryBytes(-1),
+ mAttachmentSurfaceArea(-1.f),
+ mReportedVisualComplexity(-1),
mTurning(FALSE),
- mPelvisToFoot(0.f),
mLastSkeletonSerialNum( 0 ),
- mHeadOffset(),
mIsSitting(FALSE),
mTimeVisible(),
mTyping(FALSE),
@@ -663,10 +682,10 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
mBelowWater(FALSE),
mLastAppearanceBlendTime(0.f),
mAppearanceAnimating(FALSE),
- mNameString(),
+ mNameIsSet(false),
mTitle(),
mNameAway(false),
- mNameBusy(false),
+ mNameDoNotDisturb(false),
mNameMute(false),
mNameAppearance(false),
mNameFriend(false),
@@ -677,21 +696,25 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
mFirstAppearanceMessageReceived( FALSE ),
mCulled( FALSE ),
mVisibilityRank(0),
- mTexSkinColor( NULL ),
- mTexHairColor( NULL ),
- mTexEyeColor( NULL ),
mNeedsSkin(FALSE),
mLastSkinTime(0.f),
mUpdatePeriod(1),
+ mFirstFullyVisible(TRUE),
mFullyLoaded(FALSE),
mPreviousFullyLoaded(FALSE),
mFullyLoadedInitialized(FALSE),
- mSupportsAlphaLayers(FALSE),
+ mVisualComplexity(0),
+ mVisualComplexityStale(TRUE),
mLoadedCallbacksPaused(FALSE),
mHasPelvisOffset( FALSE ),
- mRenderUnloadedAvatar(LLCachedControl<bool>(gSavedSettings, "RenderUnloadedAvatar"))
+ mRenderUnloadedAvatar(LLCachedControl<bool>(gSavedSettings, "RenderUnloadedAvatar", false)),
+ mLastRezzedStatus(-1),
+ mIsEditingAppearance(FALSE),
+ mUseLocalAppearance(FALSE),
+ mUseServerBakes(FALSE), // FIXME DRANO consider using boost::optional, defaulting to unknown.
+ mLastUpdateRequestCOFVersion(-1),
+ mLastUpdateReceivedCOFVersion(-1)
{
- LLMemType mt(LLMemType::MTYPE_AVATAR);
//VTResume(); // VTune
// mVoiceVisualizer is created by the hud effects manager and uses the HUD Effects pipeline
@@ -702,28 +725,10 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
mPelvisp = NULL;
- mBakedTextureDatas.resize(BAKED_NUM_INDICES);
- for (U32 i = 0; i < mBakedTextureDatas.size(); i++ )
- {
- mBakedTextureDatas[i].mLastTextureIndex = IMG_DEFAULT_AVATAR;
- mBakedTextureDatas[i].mTexLayerSet = NULL;
- mBakedTextureDatas[i].mIsLoaded = false;
- mBakedTextureDatas[i].mIsUsed = false;
- mBakedTextureDatas[i].mMaskTexName = 0;
- mBakedTextureDatas[i].mTextureIndex = LLVOAvatarDictionary::bakedToLocalTextureIndex((EBakedTextureIndex)i);
- }
-
mDirtyMesh = 2; // Dirty geometry, need to regenerate.
mMeshTexturesDirty = FALSE;
mHeadp = NULL;
- mIsBuilt = FALSE;
-
- mNumJoints = 0;
- mSkeleton = NULL;
-
- mNumCollisionVolumes = 0;
- mCollisionVolumes = NULL;
// set up animation variables
mSpeed = 0.f;
@@ -768,6 +773,39 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
mLastPelvisToFoot = 0.0f;
mPelvisFixup = 0.0f;
mLastPelvisFixup = 0.0f;
+
+ mCachedVisualMute = !isSelf();
+ mCachedVisualMuteUpdateTime = LLFrameTimer::getTotalSeconds() + 5.0;
+ mVisuallyMuteSetting = VISUAL_MUTE_NOT_SET;
+
+ F32 color_value = (F32) (getID().mData[0]);
+ mMutedAVColor = calcMutedAVColor(color_value, 0, 256);
+}
+
+std::string LLVOAvatar::avString() const
+{
+ std::string viz_string = LLVOAvatar::rezStatusToString(getRezzedStatus());
+ return " Avatar '" + getFullname() + "' " + viz_string + " ";
+}
+
+void LLVOAvatar::debugAvatarRezTime(std::string notification_name, std::string comment)
+{
+ LL_INFOS("Avatar") << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32()
+ << "sec ]"
+ << avString()
+ << "RuthTimer " << (U32)mRuthDebugTimer.getElapsedTimeF32()
+ << " Notification " << notification_name
+ << " : " << comment
+ << llendl;
+
+ if (gSavedSettings.getBOOL("DebugAvatarRezTime"))
+ {
+ LLSD args;
+ args["EXISTENCE"] = llformat("%d",(U32)mDebugExistenceTimer.getElapsedTimeF32());
+ args["TIME"] = llformat("%d",(U32)mRuthDebugTimer.getElapsedTimeF32());
+ args["NAME"] = getFullname();
+ LLNotificationsUtil::add(notification_name,args);
+ }
}
//------------------------------------------------------------------------
@@ -775,75 +813,29 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
//------------------------------------------------------------------------
LLVOAvatar::~LLVOAvatar()
{
- if (gSavedSettings.getBOOL("DebugAvatarRezTime"))
- {
if (!mFullyLoaded)
{
- llinfos << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32() << "sec ] Avatar '" << getFullname() << "' left after " << (U32)mRuthDebugTimer.getElapsedTimeF32() << " seconds as cloud." << llendl;
- LLSD args;
- args["EXISTENCE"] = llformat("%d",(U32)mDebugExistenceTimer.getElapsedTimeF32());
- args["TIME"] = llformat("%d",(U32)mRuthDebugTimer.getElapsedTimeF32());
- args["NAME"] = getFullname();
- LLNotificationsUtil::add("AvatarRezLeftCloudNotification",args);
+ debugAvatarRezTime("AvatarRezLeftCloudNotification","left after ruth seconds as cloud");
}
else
{
- llinfos << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32() << "sec ] Avatar '" << getFullname() << "' left." << llendl;
- LLSD args;
- args["EXISTENCE"] = llformat("%d",(U32)mDebugExistenceTimer.getElapsedTimeF32());
- args["NAME"] = getFullname();
- LLNotificationsUtil::add("AvatarRezLeftNotification",args);
+ debugAvatarRezTime("AvatarRezLeftNotification","left sometime after declouding");
}
- }
- lldebugs << "LLVOAvatar Destructor (0x" << this << ") id:" << mID << llendl;
-
- mRoot.removeAllChildren();
-
- deleteAndClearArray(mSkeleton);
- deleteAndClearArray(mCollisionVolumes);
-
- mNumJoints = 0;
-
- for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
- {
- deleteAndClear(mBakedTextureDatas[i].mTexLayerSet);
- mBakedTextureDatas[i].mMeshes.clear();
+ logPendingPhases();
- for (morph_list_t::iterator iter2 = mBakedTextureDatas[i].mMaskedMorphs.begin();
- iter2 != mBakedTextureDatas[i].mMaskedMorphs.end(); iter2++)
- {
- LLMaskedMorph* masked_morph = (*iter2);
- delete masked_morph;
- }
- }
+ lldebugs << "LLVOAvatar Destructor (0x" << this << ") id:" << mID << llendl;
std::for_each(mAttachmentPoints.begin(), mAttachmentPoints.end(), DeletePairedPointer());
mAttachmentPoints.clear();
- deleteAndClear(mTexSkinColor);
- deleteAndClear(mTexHairColor);
- deleteAndClear(mTexEyeColor);
-
- std::for_each(mMeshes.begin(), mMeshes.end(), DeletePairedPointer());
- mMeshes.clear();
-
- for (std::vector<LLViewerJoint*>::iterator jointIter = mMeshLOD.begin();
- jointIter != mMeshLOD.end();
- ++jointIter)
- {
- LLViewerJoint* joint = (LLViewerJoint *) *jointIter;
- std::for_each(joint->mMeshParts.begin(), joint->mMeshParts.end(), DeletePointer());
- joint->mMeshParts.clear();
- }
- std::for_each(mMeshLOD.begin(), mMeshLOD.end(), DeletePointer());
- mMeshLOD.clear();
-
mDead = TRUE;
mAnimationSources.clear();
LLLoadedCallbackEntry::cleanUpCallbackList(&mCallbackTextureList) ;
+ getPhases().clearPhases();
+
lldebugs << "LLVOAvatar Destructor end" << llendl;
}
@@ -877,6 +869,56 @@ BOOL LLVOAvatar::isFullyBaked()
return TRUE;
}
+BOOL LLVOAvatar::isFullyTextured() const
+{
+ for (S32 i = 0; i < mMeshLOD.size(); i++)
+ {
+ LLAvatarJoint* joint = mMeshLOD[i];
+ if (i==MESH_ID_SKIRT && !isWearingWearableType(LLWearableType::WT_SKIRT))
+ {
+ continue; // don't care about skirt textures if we're not wearing one.
+ }
+ if (!joint)
+ {
+ continue; // nonexistent LOD OK.
+ }
+ avatar_joint_mesh_list_t::iterator meshIter = joint->mMeshParts.begin();
+ if (meshIter != joint->mMeshParts.end())
+ {
+ LLAvatarJointMesh *mesh = (*meshIter);
+ if (!mesh)
+ {
+ continue; // nonexistent mesh OK
+ }
+ if (mesh->hasGLTexture())
+ {
+ continue; // Mesh exists and has a baked texture.
+ }
+ if (mesh->hasComposite())
+ {
+ continue; // Mesh exists and has a composite texture.
+ }
+ // Fail
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+BOOL LLVOAvatar::hasGray() const
+{
+ return !getIsCloud() && !isFullyTextured();
+}
+
+S32 LLVOAvatar::getRezzedStatus() const
+{
+ if (getIsCloud()) return 0;
+ if (isFullyTextured() && allBakedTexturesCompletelyDownloaded()) return 3;
+ if (isFullyTextured()) return 2;
+ llassert(hasGray());
+ return 1; // gray
+}
+
void LLVOAvatar::deleteLayerSetCaches(bool clearAll)
{
for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
@@ -892,7 +934,7 @@ void LLVOAvatar::deleteLayerSetCaches(bool clearAll)
}
if (mBakedTextureDatas[i].mMaskTexName)
{
- glDeleteTextures(1, (GLuint*)&(mBakedTextureDatas[i].mMaskTexName));
+ LLImageGL::deleteTextures(1, (GLuint*)&(mBakedTextureDatas[i].mMaskTexName));
mBakedTextureDatas[i].mMaskTexName = 0 ;
}
}
@@ -924,6 +966,32 @@ BOOL LLVOAvatar::areAllNearbyInstancesBaked(S32& grey_avatars)
}
// static
+void LLVOAvatar::getNearbyRezzedStats(std::vector<S32>& counts)
+{
+ counts.clear();
+ counts.resize(4);
+ for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
+ iter != LLCharacter::sInstances.end(); ++iter)
+ {
+ LLVOAvatar* inst = (LLVOAvatar*) *iter;
+ if (!inst)
+ continue;
+ S32 rez_status = inst->getRezzedStatus();
+ counts[rez_status]++;
+ }
+}
+
+// static
+std::string LLVOAvatar::rezStatusToString(S32 rez_status)
+{
+ if (rez_status==0) return "cloud";
+ if (rez_status==1) return "gray";
+ if (rez_status==2) return "textured";
+ if (rez_status==3) return "textured_and_downloaded";
+ return "unknown";
+}
+
+// static
void LLVOAvatar::dumpBakedStatus()
{
LLVector3d camera_pos_global = gAgentCamera.getCameraPositionGlobal();
@@ -981,15 +1049,15 @@ void LLVOAvatar::dumpBakedStatus()
{
llcont << " Unbaked (";
- for (LLVOAvatarDictionary::BakedTextures::const_iterator iter = LLVOAvatarDictionary::getInstance()->getBakedTextures().begin();
- iter != LLVOAvatarDictionary::getInstance()->getBakedTextures().end();
+ for (LLAvatarAppearanceDictionary::BakedTextures::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().begin();
+ iter != LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().end();
++iter)
{
- const LLVOAvatarDictionary::BakedEntry *baked_dict = iter->second;
+ const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = iter->second;
const ETextureIndex index = baked_dict->mTextureIndex;
if (!inst->isTextureDefined(index))
{
- llcont << " " << LLVOAvatarDictionary::getInstance()->getTexture(index)->mName;
+ llcont << " " << LLAvatarAppearanceDictionary::getInstance()->getTexture(index)->mName;
}
}
llcont << " ) " << inst->getUnbakedPixelAreaRank();
@@ -1010,7 +1078,7 @@ void LLVOAvatar::restoreGL()
gAgentAvatarp->setCompositeUpdatesEnabled(TRUE);
for (U32 i = 0; i < gAgentAvatarp->mBakedTextureDatas.size(); i++)
{
- gAgentAvatarp->invalidateComposite(gAgentAvatarp->mBakedTextureDatas[i].mTexLayerSet, FALSE);
+ gAgentAvatarp->invalidateComposite(gAgentAvatarp->getTexLayerSet(i), FALSE);
}
gAgentAvatarp->updateMeshTextures();
}
@@ -1037,7 +1105,7 @@ void LLVOAvatar::resetImpostors()
// static
void LLVOAvatar::deleteCachedImages(bool clearAll)
{
- if (LLTexLayerSet::sHasCaches)
+ if (LLViewerTexLayerSet::sHasCaches)
{
lldebugs << "Deleting layer set caches" << llendl;
for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
@@ -1046,7 +1114,7 @@ void LLVOAvatar::deleteCachedImages(bool clearAll)
LLVOAvatar* inst = (LLVOAvatar*) *iter;
inst->deleteLayerSetCaches(clearAll);
}
- LLTexLayerSet::sHasCaches = FALSE;
+ LLViewerTexLayerSet::sHasCaches = FALSE;
}
LLVOAvatarSelf::deleteScratchTextures();
LLTexLayerStaticImageList::getInstance()->deleteCachedImages();
@@ -1059,109 +1127,6 @@ void LLVOAvatar::deleteCachedImages(bool clearAll)
//------------------------------------------------------------------------
void LLVOAvatar::initClass()
{
- std::string xmlFile;
-
- xmlFile = gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,AVATAR_DEFAULT_CHAR) + "_lad.xml";
- BOOL success = sXMLTree.parseFile( xmlFile, FALSE );
- if (!success)
- {
- llerrs << "Problem reading avatar configuration file:" << xmlFile << llendl;
- }
-
- // now sanity check xml file
- LLXmlTreeNode* root = sXMLTree.getRoot();
- if (!root)
- {
- llerrs << "No root node found in avatar configuration file: " << xmlFile << llendl;
- return;
- }
-
- //-------------------------------------------------------------------------
- // <linden_avatar version="1.0"> (root)
- //-------------------------------------------------------------------------
- if( !root->hasName( "linden_avatar" ) )
- {
- llerrs << "Invalid avatar file header: " << xmlFile << llendl;
- }
-
- std::string version;
- static LLStdStringHandle version_string = LLXmlTree::addAttributeString("version");
- if( !root->getFastAttributeString( version_string, version ) || (version != "1.0") )
- {
- llerrs << "Invalid avatar file version: " << version << " in file: " << xmlFile << llendl;
- }
-
- S32 wearable_def_version = 1;
- static LLStdStringHandle wearable_definition_version_string = LLXmlTree::addAttributeString("wearable_definition_version");
- root->getFastAttributeS32( wearable_definition_version_string, wearable_def_version );
- LLWearable::setCurrentDefinitionVersion( wearable_def_version );
-
- std::string mesh_file_name;
-
- LLXmlTreeNode* skeleton_node = root->getChildByName( "skeleton" );
- if (!skeleton_node)
- {
- llerrs << "No skeleton in avatar configuration file: " << xmlFile << llendl;
- return;
- }
-
- std::string skeleton_file_name;
- static LLStdStringHandle file_name_string = LLXmlTree::addAttributeString("file_name");
- if (!skeleton_node->getFastAttributeString(file_name_string, skeleton_file_name))
- {
- llerrs << "No file name in skeleton node in avatar config file: " << xmlFile << llendl;
- }
-
- std::string skeleton_path;
- skeleton_path = gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,skeleton_file_name);
- if (!parseSkeletonFile(skeleton_path))
- {
- llerrs << "Error parsing skeleton file: " << skeleton_path << llendl;
- }
-
- // Process XML data
-
- // avatar_skeleton.xml
- if (sAvatarSkeletonInfo)
- { //this can happen if a login attempt failed
- delete sAvatarSkeletonInfo;
- }
- sAvatarSkeletonInfo = new LLVOAvatarSkeletonInfo;
- if (!sAvatarSkeletonInfo->parseXml(sSkeletonXMLTree.getRoot()))
- {
- llerrs << "Error parsing skeleton XML file: " << skeleton_path << llendl;
- }
- // parse avatar_lad.xml
- if (sAvatarXmlInfo)
- { //this can happen if a login attempt failed
- deleteAndClear(sAvatarXmlInfo);
- }
- sAvatarXmlInfo = new LLVOAvatarXmlInfo;
- if (!sAvatarXmlInfo->parseXmlSkeletonNode(root))
- {
- llerrs << "Error parsing skeleton node in avatar XML file: " << skeleton_path << llendl;
- }
- if (!sAvatarXmlInfo->parseXmlMeshNodes(root))
- {
- llerrs << "Error parsing skeleton node in avatar XML file: " << skeleton_path << llendl;
- }
- if (!sAvatarXmlInfo->parseXmlColorNodes(root))
- {
- llerrs << "Error parsing skeleton node in avatar XML file: " << skeleton_path << llendl;
- }
- if (!sAvatarXmlInfo->parseXmlLayerNodes(root))
- {
- llerrs << "Error parsing skeleton node in avatar XML file: " << skeleton_path << llendl;
- }
- if (!sAvatarXmlInfo->parseXmlDriverNodes(root))
- {
- llerrs << "Error parsing skeleton node in avatar XML file: " << skeleton_path << llendl;
- }
- if (!sAvatarXmlInfo->parseXmlMorphNodes(root))
- {
- llerrs << "Error parsing skeleton node in avatar XML file: " << skeleton_path << llendl;
- }
-
gAnimLibrary.animStateSetString(ANIM_AGENT_BODY_NOISE,"body_noise");
gAnimLibrary.animStateSetString(ANIM_AGENT_BREATHE_ROT,"breathe_rot");
gAnimLibrary.animStateSetString(ANIM_AGENT_PHYSICS_MOTION,"physics_motion");
@@ -1178,91 +1143,18 @@ void LLVOAvatar::initClass()
void LLVOAvatar::cleanupClass()
{
- deleteAndClear(sAvatarXmlInfo);
- sSkeletonXMLTree.cleanup();
- sXMLTree.cleanup();
}
+// virtual
void LLVOAvatar::initInstance(void)
{
//-------------------------------------------------------------------------
- // initialize joint, mesh and shape members
- //-------------------------------------------------------------------------
- mRoot.setName( "mRoot" );
-
- for (LLVOAvatarDictionary::Meshes::const_iterator iter = LLVOAvatarDictionary::getInstance()->getMeshes().begin();
- iter != LLVOAvatarDictionary::getInstance()->getMeshes().end();
- ++iter)
- {
- const EMeshIndex mesh_index = iter->first;
- const LLVOAvatarDictionary::MeshEntry *mesh_dict = iter->second;
- LLViewerJoint* joint = new LLViewerJoint();
- joint->setName(mesh_dict->mName);
- joint->setMeshID(mesh_index);
- mMeshLOD.push_back(joint);
-
- /* mHairLOD.setName("mHairLOD");
- mHairMesh0.setName("mHairMesh0");
- mHairMesh0.setMeshID(MESH_ID_HAIR);
- mHairMesh1.setName("mHairMesh1"); */
- for (U32 lod = 0; lod < mesh_dict->mLOD; lod++)
- {
- LLViewerJointMesh* mesh = new LLViewerJointMesh();
- std::string mesh_name = "m" + mesh_dict->mName + boost::lexical_cast<std::string>(lod);
- // We pre-pended an m - need to capitalize first character for camelCase
- mesh_name[1] = toupper(mesh_name[1]);
- mesh->setName(mesh_name);
- mesh->setMeshID(mesh_index);
- mesh->setPickName(mesh_dict->mPickName);
- mesh->setIsTransparent(FALSE);
- switch((int)mesh_index)
- {
- case MESH_ID_HAIR:
- mesh->setIsTransparent(TRUE);
- break;
- case MESH_ID_SKIRT:
- mesh->setIsTransparent(TRUE);
- break;
- case MESH_ID_EYEBALL_LEFT:
- case MESH_ID_EYEBALL_RIGHT:
- mesh->setSpecular( LLColor4( 1.0f, 1.0f, 1.0f, 1.0f ), 1.f );
- break;
- }
-
- joint->mMeshParts.push_back(mesh);
- }
- }
-
- //-------------------------------------------------------------------------
- // associate baked textures with meshes
- //-------------------------------------------------------------------------
- for (LLVOAvatarDictionary::Meshes::const_iterator iter = LLVOAvatarDictionary::getInstance()->getMeshes().begin();
- iter != LLVOAvatarDictionary::getInstance()->getMeshes().end();
- ++iter)
- {
- const EMeshIndex mesh_index = iter->first;
- const LLVOAvatarDictionary::MeshEntry *mesh_dict = iter->second;
- const EBakedTextureIndex baked_texture_index = mesh_dict->mBakedID;
- // Skip it if there's no associated baked texture.
- if (baked_texture_index == BAKED_NUM_INDICES) continue;
-
- for (std::vector<LLViewerJointMesh* >::iterator iter = mMeshLOD[mesh_index]->mMeshParts.begin();
- iter != mMeshLOD[mesh_index]->mMeshParts.end();
- ++iter)
- {
- LLViewerJointMesh* mesh = (LLViewerJointMesh*) *iter;
- mBakedTextureDatas[(int)baked_texture_index].mMeshes.push_back(mesh);
- }
- }
-
-
- //-------------------------------------------------------------------------
// register motions
//-------------------------------------------------------------------------
if (LLCharacter::sInstances.size() == 1)
{
LLKeyframeMotion::setVFS(gStaticVFS);
- registerMotion( ANIM_AGENT_BUSY, LLNullMotion::create );
+ registerMotion( ANIM_AGENT_DO_NOT_DISTURB, LLNullMotion::create );
registerMotion( ANIM_AGENT_CROUCH, LLKeyframeStandMotion::create );
registerMotion( ANIM_AGENT_CROUCHWALK, LLKeyframeWalkMotion::create );
registerMotion( ANIM_AGENT_EXPRESS_AFRAID, LLEmote::create );
@@ -1314,10 +1206,9 @@ void LLVOAvatar::initInstance(void)
registerMotion( ANIM_AGENT_SIT_FEMALE, LLKeyframeMotion::create );
registerMotion( ANIM_AGENT_TARGET, LLTargetingMotion::create );
registerMotion( ANIM_AGENT_WALK_ADJUST, LLWalkAdjustMotion::create );
-
}
- buildCharacter();
+ LLAvatarAppearance::initInstance();
// preload specific motions here
createMotion( ANIM_AGENT_CUSTOMIZE);
@@ -1326,7 +1217,30 @@ void LLVOAvatar::initInstance(void)
//VTPause(); // VTune
mVoiceVisualizer->setVoiceEnabled( LLVoiceClient::getInstance()->getVoiceEnabled( mID ) );
+}
+// virtual
+LLAvatarJoint* LLVOAvatar::createAvatarJoint()
+{
+ return new LLViewerJoint();
+}
+
+// virtual
+LLAvatarJoint* LLVOAvatar::createAvatarJoint(S32 joint_num)
+{
+ return new LLViewerJoint(joint_num);
+}
+
+// virtual
+LLAvatarJointMesh* LLVOAvatar::createAvatarJointMesh()
+{
+ return new LLViewerJointMesh();
+}
+
+// virtual
+LLTexLayerSet* LLVOAvatar::createTexLayerSet()
+{
+ return new LLViewerTexLayerSet(this);
}
const LLVector3 LLVOAvatar::getRenderPosition() const
@@ -1365,8 +1279,6 @@ void LLVOAvatar::onShift(const LLVector4a& shift_vector)
const LLVector3& shift = reinterpret_cast<const LLVector3&>(shift_vector);
mLastAnimExtents[0] += shift;
mLastAnimExtents[1] += shift;
- mNeedsImpostorUpdate = TRUE;
- mNeedsAnimUpdate = TRUE;
}
void LLVOAvatar::updateSpatialExtents(LLVector4a& newMin, LLVector4a &newMax)
@@ -1403,7 +1315,7 @@ void LLVOAvatar::getSpatialExtents(LLVector4a& newMin, LLVector4a& newMax)
float max_attachment_span = get_default_max_prim_scale() * 5.0f;
//stretch bounding box by joint positions
- for (polymesh_map_t::iterator i = mMeshes.begin(); i != mMeshes.end(); ++i)
+ for (polymesh_map_t::iterator i = mPolyMeshes.begin(); i != mPolyMeshes.end(); ++i)
{
LLPolyMesh* mesh = i->second;
for (S32 joint_num = 0; joint_num < mesh->mJointRenderData.count(); joint_num++)
@@ -1487,19 +1399,20 @@ void LLVOAvatar::renderCollisionVolumes()
if (mNameText.notNull())
{
- LLVector3 unused;
- mNameText->lineSegmentIntersect(LLVector3(0,0,0), LLVector3(0,0,1), unused, TRUE);
+ LLVector4a unused;
+
+ mNameText->lineSegmentIntersect(unused, unused, unused, TRUE);
}
}
-BOOL LLVOAvatar::lineSegmentIntersect(const LLVector3& start, const LLVector3& end,
+BOOL LLVOAvatar::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
S32 face,
BOOL pick_transparent,
S32* face_hit,
- LLVector3* intersection,
+ LLVector4a* intersection,
LLVector2* tex_coord,
- LLVector3* normal,
- LLVector3* bi_normal)
+ LLVector4a* normal,
+ LLVector4a* tangent)
{
if ((isSelf() && !gAgent.needsRenderAvatar()) || !LLPipeline::sPickAvatar)
{
@@ -1516,8 +1429,8 @@ BOOL LLVOAvatar::lineSegmentIntersect(const LLVector3& start, const LLVector3& e
glh::matrix4f inverse = mat.inverse();
glh::matrix4f norm_mat = inverse.transpose();
- glh::vec3f p1(start.mV);
- glh::vec3f p2(end.mV);
+ glh::vec3f p1(start.getF32ptr());
+ glh::vec3f p2(end.getF32ptr());
inverse.mult_matrix_vec(p1);
inverse.mult_matrix_vec(p2);
@@ -1536,12 +1449,12 @@ BOOL LLVOAvatar::lineSegmentIntersect(const LLVector3& start, const LLVector3& e
if (intersection)
{
- *intersection = LLVector3(res_pos.v);
+ intersection->load3(res_pos.v);
}
if (normal)
{
- *normal = LLVector3(res_norm.v);
+ normal->load3(res_norm.v);
}
return TRUE;
@@ -1577,7 +1490,7 @@ BOOL LLVOAvatar::lineSegmentIntersect(const LLVector3& start, const LLVector3& e
- LLVector3 position;
+ LLVector4a position;
if (mNameText.notNull() && mNameText->lineSegmentIntersect(start, end, position))
{
if (intersection)
@@ -1591,14 +1504,14 @@ BOOL LLVOAvatar::lineSegmentIntersect(const LLVector3& start, const LLVector3& e
return FALSE;
}
-LLViewerObject* LLVOAvatar::lineSegmentIntersectRiggedAttachments(const LLVector3& start, const LLVector3& end,
+LLViewerObject* LLVOAvatar::lineSegmentIntersectRiggedAttachments(const LLVector4a& start, const LLVector4a& end,
S32 face,
BOOL pick_transparent,
S32* face_hit,
- LLVector3* intersection,
+ LLVector4a* intersection,
LLVector2* tex_coord,
- LLVector3* normal,
- LLVector3* bi_normal)
+ LLVector4a* normal,
+ LLVector4a* tangent)
{
if (isSelf() && !gAgent.needsRenderAvatar())
{
@@ -1609,8 +1522,8 @@ LLViewerObject* LLVOAvatar::lineSegmentIntersectRiggedAttachments(const LLVector
if (lineSegmentBoundingBox(start, end))
{
- LLVector3 local_end = end;
- LLVector3 local_intersection;
+ LLVector4a local_end = end;
+ LLVector4a local_intersection;
for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
iter != mAttachmentPoints.end();
@@ -1624,7 +1537,7 @@ LLViewerObject* LLVOAvatar::lineSegmentIntersectRiggedAttachments(const LLVector
{
LLViewerObject* attached_object = (*attachment_iter);
- if (attached_object->lineSegmentIntersect(start, local_end, face, pick_transparent, face_hit, &local_intersection, tex_coord, normal, bi_normal))
+ if (attached_object->lineSegmentIntersect(start, local_end, face, pick_transparent, face_hit, &local_intersection, tex_coord, normal, tangent))
{
local_end = local_intersection;
if (intersection)
@@ -1641,159 +1554,6 @@ LLViewerObject* LLVOAvatar::lineSegmentIntersectRiggedAttachments(const LLVector
return hit;
}
-//-----------------------------------------------------------------------------
-// parseSkeletonFile()
-//-----------------------------------------------------------------------------
-BOOL LLVOAvatar::parseSkeletonFile(const std::string& filename)
-{
- LLMemType mt(LLMemType::MTYPE_AVATAR);
-
- //-------------------------------------------------------------------------
- // parse the file
- //-------------------------------------------------------------------------
- BOOL parsesuccess = sSkeletonXMLTree.parseFile( filename, FALSE );
-
- if (!parsesuccess)
- {
- llerrs << "Can't parse skeleton file: " << filename << llendl;
- return FALSE;
- }
-
- // now sanity check xml file
- LLXmlTreeNode* root = sSkeletonXMLTree.getRoot();
- if (!root)
- {
- llerrs << "No root node found in avatar skeleton file: " << filename << llendl;
- return FALSE;
- }
-
- if( !root->hasName( "linden_skeleton" ) )
- {
- llerrs << "Invalid avatar skeleton file header: " << filename << llendl;
- return FALSE;
- }
-
- std::string version;
- static LLStdStringHandle version_string = LLXmlTree::addAttributeString("version");
- if( !root->getFastAttributeString( version_string, version ) || (version != "1.0") )
- {
- llerrs << "Invalid avatar skeleton file version: " << version << " in file: " << filename << llendl;
- return FALSE;
- }
-
- return TRUE;
-}
-
-//-----------------------------------------------------------------------------
-// setupBone()
-//-----------------------------------------------------------------------------
-BOOL LLVOAvatar::setupBone(const LLVOAvatarBoneInfo* info, LLViewerJoint* parent, S32 &volume_num, S32 &joint_num)
-{
- LLMemType mt(LLMemType::MTYPE_AVATAR);
-
- LLViewerJoint* joint = NULL;
-
- if (info->mIsJoint)
- {
- joint = (LLViewerJoint*)getCharacterJoint(joint_num);
- if (!joint)
- {
- llwarns << "Too many bones" << llendl;
- return FALSE;
- }
- joint->setName( info->mName );
- }
- else // collision volume
- {
- if (volume_num >= (S32)mNumCollisionVolumes)
- {
- llwarns << "Too many bones" << llendl;
- return FALSE;
- }
- joint = (LLViewerJoint*)(&mCollisionVolumes[volume_num]);
- joint->setName( info->mName );
- }
-
- // add to parent
- if (parent)
- {
- parent->addChild( joint );
- }
-
- joint->setPosition(info->mPos);
- joint->setRotation(mayaQ(info->mRot.mV[VX], info->mRot.mV[VY],
- info->mRot.mV[VZ], LLQuaternion::XYZ));
- joint->setScale(info->mScale);
-
- joint->setDefaultFromCurrentXform();
-
- if (info->mIsJoint)
- {
- joint->setSkinOffset( info->mPivot );
- joint_num++;
- }
- else // collision volume
- {
- volume_num++;
- }
-
- // setup children
- LLVOAvatarBoneInfo::child_list_t::const_iterator iter;
- for (iter = info->mChildList.begin(); iter != info->mChildList.end(); ++iter)
- {
- LLVOAvatarBoneInfo *child_info = *iter;
- if (!setupBone(child_info, joint, volume_num, joint_num))
- {
- return FALSE;
- }
- }
-
- return TRUE;
-}
-
-//-----------------------------------------------------------------------------
-// buildSkeleton()
-//-----------------------------------------------------------------------------
-BOOL LLVOAvatar::buildSkeleton(const LLVOAvatarSkeletonInfo *info)
-{
- LLMemType mt(LLMemType::MTYPE_AVATAR);
-
- //-------------------------------------------------------------------------
- // allocate joints
- //-------------------------------------------------------------------------
- if (!allocateCharacterJoints(info->mNumBones))
- {
- llerrs << "Can't allocate " << info->mNumBones << " joints" << llendl;
- return FALSE;
- }
-
- //-------------------------------------------------------------------------
- // allocate volumes
- //-------------------------------------------------------------------------
- if (info->mNumCollisionVolumes)
- {
- if (!allocateCollisionVolumes(info->mNumCollisionVolumes))
- {
- llerrs << "Can't allocate " << info->mNumCollisionVolumes << " collision volumes" << llendl;
- return FALSE;
- }
- }
-
- S32 current_joint_num = 0;
- S32 current_volume_num = 0;
- LLVOAvatarSkeletonInfo::bone_info_list_t::const_iterator iter;
- for (iter = info->mBoneInfoList.begin(); iter != info->mBoneInfoList.end(); ++iter)
- {
- LLVOAvatarBoneInfo *info = *iter;
- if (!setupBone(info, NULL, current_volume_num, current_joint_num))
- {
- llerrs << "Error parsing bone in skeleton file" << llendl;
- return FALSE;
- }
- }
-
- return TRUE;
-}
LLVOAvatar* LLVOAvatar::asAvatar()
{
@@ -1826,115 +1586,15 @@ void LLVOAvatar::startDefaultMotions()
// LLVOAvatar::buildCharacter()
// Deferred initialization and rebuild of the avatar.
//-----------------------------------------------------------------------------
+// virtual
void LLVOAvatar::buildCharacter()
{
- LLMemType mt(LLMemType::MTYPE_AVATAR);
-
- //-------------------------------------------------------------------------
- // remove all references to our existing skeleton
- // so we can rebuild it
- //-------------------------------------------------------------------------
- flushAllMotions();
+ LLAvatarAppearance::buildCharacter();
- //-------------------------------------------------------------------------
- // remove all of mRoot's children
- //-------------------------------------------------------------------------
- mRoot.removeAllChildren();
+ // Not done building yet; more to do.
mIsBuilt = FALSE;
//-------------------------------------------------------------------------
- // clear mesh data
- //-------------------------------------------------------------------------
- for (std::vector<LLViewerJoint*>::iterator jointIter = mMeshLOD.begin();
- jointIter != mMeshLOD.end(); ++jointIter)
- {
- LLViewerJoint* joint = (LLViewerJoint*) *jointIter;
- for (std::vector<LLViewerJointMesh*>::iterator meshIter = joint->mMeshParts.begin();
- meshIter != joint->mMeshParts.end(); ++meshIter)
- {
- LLViewerJointMesh * mesh = (LLViewerJointMesh *) *meshIter;
- mesh->setMesh(NULL);
- }
- }
-
- //-------------------------------------------------------------------------
- // (re)load our skeleton and meshes
- //-------------------------------------------------------------------------
- LLTimer timer;
-
- BOOL status = loadAvatar();
- stop_glerror();
-
-// gPrintMessagesThisFrame = TRUE;
- lldebugs << "Avatar load took " << timer.getElapsedTimeF32() << " seconds." << llendl;
-
- if (!status)
- {
- if (isSelf())
- {
- llerrs << "Unable to load user's avatar" << llendl;
- }
- else
- {
- llwarns << "Unable to load other's avatar" << llendl;
- }
- return;
- }
-
- //-------------------------------------------------------------------------
- // initialize "well known" joint pointers
- //-------------------------------------------------------------------------
- mPelvisp = (LLViewerJoint*)mRoot.findJoint("mPelvis");
- mTorsop = (LLViewerJoint*)mRoot.findJoint("mTorso");
- mChestp = (LLViewerJoint*)mRoot.findJoint("mChest");
- mNeckp = (LLViewerJoint*)mRoot.findJoint("mNeck");
- mHeadp = (LLViewerJoint*)mRoot.findJoint("mHead");
- mSkullp = (LLViewerJoint*)mRoot.findJoint("mSkull");
- mHipLeftp = (LLViewerJoint*)mRoot.findJoint("mHipLeft");
- mHipRightp = (LLViewerJoint*)mRoot.findJoint("mHipRight");
- mKneeLeftp = (LLViewerJoint*)mRoot.findJoint("mKneeLeft");
- mKneeRightp = (LLViewerJoint*)mRoot.findJoint("mKneeRight");
- mAnkleLeftp = (LLViewerJoint*)mRoot.findJoint("mAnkleLeft");
- mAnkleRightp = (LLViewerJoint*)mRoot.findJoint("mAnkleRight");
- mFootLeftp = (LLViewerJoint*)mRoot.findJoint("mFootLeft");
- mFootRightp = (LLViewerJoint*)mRoot.findJoint("mFootRight");
- mWristLeftp = (LLViewerJoint*)mRoot.findJoint("mWristLeft");
- mWristRightp = (LLViewerJoint*)mRoot.findJoint("mWristRight");
- mEyeLeftp = (LLViewerJoint*)mRoot.findJoint("mEyeLeft");
- mEyeRightp = (LLViewerJoint*)mRoot.findJoint("mEyeRight");
-
- //-------------------------------------------------------------------------
- // Make sure "well known" pointers exist
- //-------------------------------------------------------------------------
- if (!(mPelvisp &&
- mTorsop &&
- mChestp &&
- mNeckp &&
- mHeadp &&
- mSkullp &&
- mHipLeftp &&
- mHipRightp &&
- mKneeLeftp &&
- mKneeRightp &&
- mAnkleLeftp &&
- mAnkleRightp &&
- mFootLeftp &&
- mFootRightp &&
- mWristLeftp &&
- mWristRightp &&
- mEyeLeftp &&
- mEyeRightp))
- {
- llerrs << "Failed to create avatar." << llendl;
- return;
- }
-
- //-------------------------------------------------------------------------
- // initialize the pelvis
- //-------------------------------------------------------------------------
- mPelvisp->setPosition( LLVector3(0.0f, 0.0f, 0.0f) );
-
- //-------------------------------------------------------------------------
// set head offset from pelvis
//-------------------------------------------------------------------------
updateHeadOffset();
@@ -1978,8 +1638,6 @@ void LLVOAvatar::buildCharacter()
//-----------------------------------------------------------------------------
void LLVOAvatar::releaseMeshData()
{
- LLMemType mt(LLMemType::MTYPE_AVATAR);
-
if (sInstances.size() < AVATAR_RELEASE_THRESHOLD || mIsDummy)
{
return;
@@ -1988,11 +1646,11 @@ void LLVOAvatar::releaseMeshData()
//llinfos << "Releasing" << llendl;
// cleanup mesh data
- for (std::vector<LLViewerJoint*>::iterator iter = mMeshLOD.begin();
+ for (avatar_joint_list_t::iterator iter = mMeshLOD.begin();
iter != mMeshLOD.end();
++iter)
{
- LLViewerJoint* joint = (LLViewerJoint*) *iter;
+ LLAvatarJoint* joint = (*iter);
joint->setValid(FALSE, TRUE);
}
@@ -2000,13 +1658,19 @@ void LLVOAvatar::releaseMeshData()
if (mDrawable.notNull())
{
LLFace* facep = mDrawable->getFace(0);
+ if (facep)
+ {
facep->setSize(0, 0);
for(S32 i = mNumInitFaces ; i < mDrawable->getNumFaces(); i++)
{
facep = mDrawable->getFace(i);
+ if (facep)
+ {
facep->setSize(0, 0);
}
}
+ }
+ }
for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
iter != mAttachmentPoints.end();
@@ -2028,7 +1692,6 @@ void LLVOAvatar::releaseMeshData()
void LLVOAvatar::restoreMeshData()
{
llassert(!isSelf());
- LLMemType mt(LLMemType::MTYPE_AVATAR);
//llinfos << "Restoring" << llendl;
mMeshValid = TRUE;
@@ -2076,7 +1739,11 @@ void LLVOAvatar::updateMeshData()
last_v_num = num_vertices ;
last_i_num = num_indices ;
- mMeshLOD[part_index++]->updateFaceSizes(num_vertices, num_indices, mAdjustedPixelArea);
+ LLViewerJoint* part_mesh = getViewerJoint(part_index++);
+ if (part_mesh)
+ {
+ part_mesh->updateFaceSizes(num_vertices, num_indices, mAdjustedPixelArea);
+ }
}
if(num_vertices < 1)//skip empty meshes
{
@@ -2089,15 +1756,20 @@ void LLVOAvatar::updateMeshData()
part_index-- ;
}
- LLFace* facep ;
+ LLFace* facep = NULL;
if(f_num < mDrawable->getNumFaces())
{
facep = mDrawable->getFace(f_num);
}
else
{
- facep = mDrawable->addFace(mDrawable->getFace(0)->getPool(), mDrawable->getFace(0)->getTexture()) ;
+ facep = mDrawable->getFace(0);
+ if (facep)
+ {
+ facep = mDrawable->addFace(facep->getPool(), facep->getTexture()) ;
+ }
}
+ if (!facep) continue;
// resize immediately
facep->setSize(num_vertices, num_indices);
@@ -2145,7 +1817,11 @@ void LLVOAvatar::updateMeshData()
rigid = true;
}
- mMeshLOD[k]->updateFaceData(facep, mAdjustedPixelArea, k == MESH_ID_HAIR, terse_update && !rigid);
+ LLViewerJoint* mesh = getViewerJoint(k);
+ if (mesh)
+ {
+ mesh->updateFaceData(facep, mAdjustedPixelArea, k == MESH_ID_HAIR, terse_update && !rigid);
+ }
}
stop_glerror();
@@ -2166,72 +1842,6 @@ void LLVOAvatar::updateMeshData()
//------------------------------------------------------------------------
//------------------------------------------------------------------------
-// The viewer can only suggest a good size for the agent,
-// the simulator will keep it inside a reasonable range.
-void LLVOAvatar::computeBodySize()
-{
- LLVector3 pelvis_scale = mPelvisp->getScale();
-
- // some of the joints have not been cached
- LLVector3 skull = mSkullp->getPosition();
- LLVector3 skull_scale = mSkullp->getScale();
-
- LLVector3 neck = mNeckp->getPosition();
- LLVector3 neck_scale = mNeckp->getScale();
-
- LLVector3 chest = mChestp->getPosition();
- LLVector3 chest_scale = mChestp->getScale();
-
- // the rest of the joints have been cached
- LLVector3 head = mHeadp->getPosition();
- LLVector3 head_scale = mHeadp->getScale();
-
- LLVector3 torso = mTorsop->getPosition();
- LLVector3 torso_scale = mTorsop->getScale();
-
- LLVector3 hip = mHipLeftp->getPosition();
- LLVector3 hip_scale = mHipLeftp->getScale();
-
- LLVector3 knee = mKneeLeftp->getPosition();
- LLVector3 knee_scale = mKneeLeftp->getScale();
-
- LLVector3 ankle = mAnkleLeftp->getPosition();
- LLVector3 ankle_scale = mAnkleLeftp->getScale();
-
- LLVector3 foot = mFootLeftp->getPosition();
-
- mPelvisToFoot = hip.mV[VZ] * pelvis_scale.mV[VZ] -
- knee.mV[VZ] * hip_scale.mV[VZ] -
- ankle.mV[VZ] * knee_scale.mV[VZ] -
- foot.mV[VZ] * ankle_scale.mV[VZ];
-
- LLVector3 new_body_size;
- new_body_size.mV[VZ] = mPelvisToFoot +
- // the sqrt(2) correction below is an approximate
- // correction to get to the top of the head
- F_SQRT2 * (skull.mV[VZ] * head_scale.mV[VZ]) +
- head.mV[VZ] * neck_scale.mV[VZ] +
- neck.mV[VZ] * chest_scale.mV[VZ] +
- chest.mV[VZ] * torso_scale.mV[VZ] +
- torso.mV[VZ] * pelvis_scale.mV[VZ];
-
- // TODO -- measure the real depth and width
- new_body_size.mV[VX] = DEFAULT_AGENT_DEPTH;
- new_body_size.mV[VY] = DEFAULT_AGENT_WIDTH;
-
- if (new_body_size != mBodySize)
- {
- mBodySize = new_body_size;
-
- if (isSelf() && !LLAppearanceMgr::instance().isInUpdateAppearanceFromCOF())
- { // notify simulator of change in size
- // but not if we are in the middle of updating appearance
- gAgent.sendAgentSetAppearance();
- }
- }
-}
-
-//------------------------------------------------------------------------
// LLVOAvatar::processUpdateMessage()
//------------------------------------------------------------------------
U32 LLVOAvatar::processUpdateMessage(LLMessageSystem *mesgsys,
@@ -2239,27 +1849,18 @@ U32 LLVOAvatar::processUpdateMessage(LLMessageSystem *mesgsys,
U32 block_num, const EObjectUpdateType update_type,
LLDataPacker *dp)
{
- LLMemType mt(LLMemType::MTYPE_AVATAR);
-
- LLVector3 old_vel = getVelocity();
const BOOL has_name = !getNVPair("FirstName");
// Do base class updates...
U32 retval = LLViewerObject::processUpdateMessage(mesgsys, user_data, block_num, update_type, dp);
// Print out arrival information once we have name of avatar.
- if (gSavedSettings.getBOOL("DebugAvatarRezTime"))
- {
if (has_name && getNVPair("FirstName"))
{
mDebugExistenceTimer.reset();
- LLSD args;
- args["EXISTENCE"] = llformat("%d",(U32)mDebugExistenceTimer.getElapsedTimeF32());
- args["NAME"] = getFullname();
- LLNotificationsUtil::add("AvatarRezArrivedNotification",args);
- llinfos << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32() << "sec ] Avatar '" << getFullname() << "' arrived." << llendl;
+ debugAvatarRezTime("AvatarRezArrivedNotification","avatar arrived");
}
- }
+
if(retval & LLViewerObject::INVALID_UPDATE)
{
if (isSelf())
@@ -2275,23 +1876,53 @@ U32 LLVOAvatar::processUpdateMessage(LLMessageSystem *mesgsys,
return retval;
}
-// virtual
-S32 LLVOAvatar::setTETexture(const U8 te, const LLUUID& uuid)
+LLViewerFetchedTexture *LLVOAvatar::getBakedTextureImage(const U8 te, const LLUUID& uuid)
+{
+ LLViewerFetchedTexture *result = NULL;
+
+ if (uuid == IMG_DEFAULT_AVATAR ||
+ uuid == IMG_DEFAULT ||
+ uuid == IMG_INVISIBLE)
+ {
+ // Should already exist, don't need to find it on sim or baked-texture host.
+ result = gTextureList.findImage(uuid);
+ }
+
+ if (!result)
{
- // The core setTETexture() method requests images, so we need
- // to redirect certain avatar texture requests to different sims.
- if (isIndexBakedTexture((ETextureIndex)te))
+ const std::string url = getImageURL(te,uuid);
+ if (!url.empty())
{
- LLHost target_host = getObjectHost();
- return setTETextureCore(te, uuid, target_host);
+ LL_DEBUGS("Avatar") << avString() << "from URL " << url << llendl;
+ result = LLViewerTextureManager::getFetchedTextureFromUrl(
+ url, FTT_SERVER_BAKE, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, uuid);
}
else
{
- return setTETextureCore(te, uuid, LLHost::invalid);
+ LL_DEBUGS("Avatar") << avString() << "from host " << uuid << llendl;
+ LLHost host = getObjectHost();
+ result = LLViewerTextureManager::getFetchedTexture(
+ uuid, FTT_HOST_BAKE, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, host);
}
}
+ return result;
+}
-static LLFastTimer::DeclareTimer FTM_AVATAR_UPDATE("Update Avatar");
+// virtual
+S32 LLVOAvatar::setTETexture(const U8 te, const LLUUID& uuid)
+{
+ if (!isIndexBakedTexture((ETextureIndex)te))
+ {
+ // Sim still sends some uuids for non-baked slots sometimes - ignore.
+ return LLViewerObject::setTETexture(te, LLUUID::null);
+ }
+
+ LLViewerFetchedTexture *image = getBakedTextureImage(te,uuid);
+ llassert(image);
+ return setTETextureCore(te, image);
+}
+
+static LLFastTimer::DeclareTimer FTM_AVATAR_UPDATE("Avatar Update");
static LLFastTimer::DeclareTimer FTM_JOINT_UPDATE("Update Joints");
//------------------------------------------------------------------------
@@ -2324,20 +1955,20 @@ void LLVOAvatar::dumpAnimationState()
//------------------------------------------------------------------------
// idleUpdate()
//------------------------------------------------------------------------
-BOOL LLVOAvatar::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
+void LLVOAvatar::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
{
- LLMemType mt(LLMemType::MTYPE_AVATAR);
LLFastTimer t(FTM_AVATAR_UPDATE);
if (isDead())
{
llinfos << "Warning! Idle on dead avatar" << llendl;
- return TRUE;
+ return;
}
- if (!(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_AVATAR)))
+ if (!(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_AVATAR))
+ && !(gSavedSettings.getBOOL("DisableAllRenderTypes")))
{
- return TRUE;
+ return;
}
checkTextureLoading() ;
@@ -2400,7 +2031,7 @@ BOOL LLVOAvatar::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
// animate the character
// store off last frame's root position to be consistent with camera position
- LLVector3 root_pos_last = mRoot.getWorldPosition();
+ LLVector3 root_pos_last = mRoot->getWorldPosition();
BOOL detailed_update = updateCharacter(agent);
static LLUICachedControl<bool> visualizers_in_calls("ShowVoiceVisualizersInCalls", false);
@@ -2420,8 +2051,6 @@ BOOL LLVOAvatar::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
idleUpdateNameTag( root_pos_last );
idleUpdateRenderCost();
-
- return TRUE;
}
void LLVOAvatar::idleUpdateVoiceVisualizer(bool voice_enabled)
@@ -2521,11 +2150,11 @@ void LLVOAvatar::idleUpdateVoiceVisualizer(bool voice_enabled)
if ( mIsSitting )
{
LLVector3 headOffset = LLVector3( 0.0f, 0.0f, mHeadOffset.mV[2] );
- mVoiceVisualizer->setVoiceSourceWorldPosition( mRoot.getWorldPosition() + headOffset );
+ mVoiceVisualizer->setVoiceSourceWorldPosition( mRoot->getWorldPosition() + headOffset );
}
else
{
- LLVector3 tagPos = mRoot.getWorldPosition();
+ LLVector3 tagPos = mRoot->getWorldPosition();
tagPos[VZ] -= mPelvisToFoot;
tagPos[VZ] += ( mBodySize[VZ] + 0.125f );
mVoiceVisualizer->setVoiceSourceWorldPosition( tagPos );
@@ -2593,7 +2222,7 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update)
if (isImpostor() && !mNeedsImpostorUpdate)
{
- LLVector4a ext[2];
+ LL_ALIGN_16(LLVector4a ext[2]);
F32 distance;
LLVector3 angle;
@@ -2765,16 +2394,16 @@ void LLVOAvatar::idleUpdateLoadingEffect()
// update visibility when avatar is partially loaded
if (updateIsFullyLoaded()) // changed?
{
- if (isFullyLoaded() && isSelf())
+ if (isFullyLoaded() && mFirstFullyVisible && isSelf())
{
- static bool first_fully_visible = true;
- if (first_fully_visible)
- {
- llinfos << "self isFullyLoaded, first_fully_visible" << llendl;
-
- first_fully_visible = false;
+ LL_INFOS("Avatar") << avString() << "self isFullyLoaded, mFirstFullyVisible" << LL_ENDL;
+ mFirstFullyVisible = FALSE;
LLAppearanceMgr::instance().onFirstFullyVisible();
}
+ if (isFullyLoaded() && mFirstFullyVisible && !isSelf())
+ {
+ LL_INFOS("Avatar") << avString() << "other isFullyLoaded, mFirstFullyVisible" << LL_ENDL;
+ mFirstFullyVisible = FALSE;
}
if (isFullyLoaded())
{
@@ -2918,43 +2547,43 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)
return;
}
- BOOL new_name = FALSE;
- if (visible_chat != mVisibleChat)
+ BOOL new_name = FALSE;
+ if (visible_chat != mVisibleChat)
+ {
+ mVisibleChat = visible_chat;
+ new_name = TRUE;
+ }
+
+ if (sRenderGroupTitles != mRenderGroupTitles)
+ {
+ mRenderGroupTitles = sRenderGroupTitles;
+ new_name = TRUE;
+ }
+
+ // First Calculate Alpha
+ // If alpha > 0, create mNameText if necessary, otherwise delete it
+ F32 alpha = 0.f;
+ if (mAppAngle > 5.f)
+ {
+ const F32 START_FADE_TIME = NAME_SHOW_TIME - FADE_DURATION;
+ if (!visible_chat && sRenderName == RENDER_NAME_FADE && time_visible > START_FADE_TIME)
{
- mVisibleChat = visible_chat;
- new_name = TRUE;
+ alpha = 1.f - (time_visible - START_FADE_TIME) / FADE_DURATION;
}
-
- if (sRenderGroupTitles != mRenderGroupTitles)
+ else
{
- mRenderGroupTitles = sRenderGroupTitles;
- new_name = TRUE;
+ // ...not fading, full alpha
+ alpha = 1.f;
}
-
- // First Calculate Alpha
- // If alpha > 0, create mNameText if necessary, otherwise delete it
- F32 alpha = 0.f;
- if (mAppAngle > 5.f)
- {
- const F32 START_FADE_TIME = NAME_SHOW_TIME - FADE_DURATION;
- if (!visible_chat && sRenderName == RENDER_NAME_FADE && time_visible > START_FADE_TIME)
- {
- alpha = 1.f - (time_visible - START_FADE_TIME) / FADE_DURATION;
- }
- else
- {
- // ...not fading, full alpha
- alpha = 1.f;
- }
- }
- else if (mAppAngle > 2.f)
- {
- // far away is faded out also
- alpha = (mAppAngle-2.f)/3.f;
- }
+ }
+ else if (mAppAngle > 2.f)
+ {
+ // far away is faded out also
+ alpha = (mAppAngle-2.f)/3.f;
+ }
if (alpha <= 0.f)
- {
+ {
if (mNameText)
{
mNameText->markDead();
@@ -2964,37 +2593,36 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)
return;
}
- if (!mNameText)
- {
+ if (!mNameText)
+ {
mNameText = static_cast<LLHUDNameTag*>( LLHUDObject::addHUDObject(
LLHUDObject::LL_HUD_NAME_TAG) );
//mNameText->setMass(10.f);
- mNameText->setSourceObject(this);
+ mNameText->setSourceObject(this);
mNameText->setVertAlignment(LLHUDNameTag::ALIGN_VERT_TOP);
- mNameText->setVisibleOffScreen(TRUE);
- mNameText->setMaxLines(11);
- mNameText->setFadeDistance(CHAT_NORMAL_RADIUS, 5.f);
- sNumVisibleChatBubbles++;
- new_name = TRUE;
- }
+ mNameText->setVisibleOffScreen(TRUE);
+ mNameText->setMaxLines(11);
+ mNameText->setFadeDistance(CHAT_NORMAL_RADIUS, 5.f);
+ sNumVisibleChatBubbles++;
+ new_name = TRUE;
+ }
- LLVector3 name_position = idleUpdateNameTagPosition(root_pos_last);
- mNameText->setPositionAgent(name_position);
+ idleUpdateNameTagPosition(root_pos_last);
idleUpdateNameTagText(new_name);
idleUpdateNameTagAlpha(new_name, alpha);
}
void LLVOAvatar::idleUpdateNameTagText(BOOL new_name)
- {
- LLNameValue *title = getNVPair("Title");
- LLNameValue* firstname = getNVPair("FirstName");
- LLNameValue* lastname = getNVPair("LastName");
+{
+ LLNameValue *title = getNVPair("Title");
+ LLNameValue* firstname = getNVPair("FirstName");
+ LLNameValue* lastname = getNVPair("LastName");
// Avatars must have a first and last name
if (!firstname || !lastname) return;
bool is_away = mSignaledAnimations.find(ANIM_AGENT_AWAY) != mSignaledAnimations.end();
- bool is_busy = mSignaledAnimations.find(ANIM_AGENT_BUSY) != mSignaledAnimations.end();
+ bool is_do_not_disturb = mSignaledAnimations.find(ANIM_AGENT_DO_NOT_DISTURB) != mSignaledAnimations.end();
bool is_appearance = mSignaledAnimations.find(ANIM_AGENT_CUSTOMIZE) != mSignaledAnimations.end();
bool is_muted;
if (isSelf())
@@ -3002,76 +2630,65 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name)
is_muted = false;
}
else
- {
+ {
is_muted = LLMuteList::getInstance()->isMuted(getID());
}
bool is_friend = LLAvatarTracker::instance().isBuddy(getID());
bool is_cloud = getIsCloud();
- if (gSavedSettings.getBOOL("DebugAvatarRezTime"))
- {
- if (is_appearance != mNameAppearance)
- {
- if (is_appearance)
- {
- LLSD args;
- args["EXISTENCE"] = llformat("%d",(U32)mDebugExistenceTimer.getElapsedTimeF32());
- args["NAME"] = getFullname();
- LLNotificationsUtil::add("AvatarRezEnteredAppearanceNotification",args);
- llinfos << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32() << "sec ] Avatar '" << getFullname() << "' entered appearance mode." << llendl;
- }
- else
- {
- LLSD args;
- args["EXISTENCE"] = llformat("%d",(U32)mDebugExistenceTimer.getElapsedTimeF32());
- args["NAME"] = getFullname();
- LLNotificationsUtil::add("AvatarRezLeftAppearanceNotification",args);
- llinfos << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32() << "sec ] Avatar '" << getFullname() << "' left appearance mode." << llendl;
- }
- }
- }
+ if (is_appearance != mNameAppearance)
+ {
+ if (is_appearance)
+ {
+ debugAvatarRezTime("AvatarRezEnteredAppearanceNotification","entered appearance mode");
+ }
+ else
+ {
+ debugAvatarRezTime("AvatarRezLeftAppearanceNotification","left appearance mode");
+ }
+ }
// Rebuild name tag if state change detected
- if (mNameString.empty()
+ if (!mNameIsSet
|| new_name
|| (!title && !mTitle.empty())
|| (title && mTitle != title->getString())
|| is_away != mNameAway
- || is_busy != mNameBusy
+ || is_do_not_disturb != mNameDoNotDisturb
|| is_muted != mNameMute
- || is_appearance != mNameAppearance
+ || is_appearance != mNameAppearance
|| is_friend != mNameFriend
|| is_cloud != mNameCloud)
- {
+ {
LLColor4 name_tag_color = getNameTagColor(is_friend);
clearNameTag();
- if (is_away || is_muted || is_busy || is_appearance)
- {
+ if (is_away || is_muted || is_do_not_disturb || is_appearance)
+ {
std::string line;
- if (is_away)
- {
- line += LLTrans::getString("AvatarAway");
+ if (is_away)
+ {
+ line += LLTrans::getString("AvatarAway");
line += ", ";
- }
- if (is_busy)
- {
- line += LLTrans::getString("AvatarBusy");
+ }
+ if (is_do_not_disturb)
+ {
+ line += LLTrans::getString("AvatarDoNotDisturb");
line += ", ";
}
if (is_muted)
- {
+ {
line += LLTrans::getString("AvatarMuted");
- line += ", ";
- }
+ line += ", ";
+ }
if (is_appearance)
{
line += LLTrans::getString("AvatarEditingAppearance");
line += ", ";
- }
+ }
if (is_cloud)
- {
+ {
line += LLTrans::getString("LoadingData");
line += ", ";
}
@@ -3083,138 +2700,134 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name)
if (sRenderGroupTitles
&& title && title->getString() && title->getString()[0] != '\0')
- {
+ {
std::string title_str = title->getString();
LLStringFn::replace_ascii_controlchars(title_str,LL_UNKNOWN_CHAR);
addNameTagLine(title_str, name_tag_color, LLFontGL::NORMAL,
LLFontGL::getFontSansSerifSmall());
- }
+ }
- static LLUICachedControl<bool> show_display_names("NameTagShowDisplayNames");
- static LLUICachedControl<bool> show_usernames("NameTagShowUsernames");
+ static LLUICachedControl<bool> show_display_names("NameTagShowDisplayNames", true);
+ static LLUICachedControl<bool> show_usernames("NameTagShowUsernames", true);
- if (LLAvatarNameCache::useDisplayNames())
+ if (LLAvatarName::useDisplayNames())
{
LLAvatarName av_name;
if (!LLAvatarNameCache::get(getID(), &av_name))
{
- // ...call this function back when the name arrives
- // and force a rebuild
- LLAvatarNameCache::get(getID(),
- boost::bind(&LLVOAvatar::clearNameTag, this));
- }
+ // Force a rebuild at next idle
+ // Note: do not connect a callback on idle().
+ clearNameTag();
+ }
// Might be blank if name not available yet, that's OK
if (show_display_names)
{
- addNameTagLine(av_name.mDisplayName, name_tag_color, LLFontGL::NORMAL,
+ addNameTagLine(av_name.getDisplayName(), name_tag_color, LLFontGL::NORMAL,
LLFontGL::getFontSansSerif());
- }
+ }
// Suppress SLID display if display name matches exactly (ugh)
- if (show_usernames && !av_name.mIsDisplayNameDefault)
- {
+ if (show_usernames && !av_name.isDisplayNameDefault())
+ {
// *HACK: Desaturate the color
LLColor4 username_color = name_tag_color * 0.83f;
- addNameTagLine(av_name.mUsername, username_color, LLFontGL::NORMAL,
+ addNameTagLine(av_name.getUserName(), username_color, LLFontGL::NORMAL,
LLFontGL::getFontSansSerifSmall());
}
- }
+ }
else
- {
+ {
const LLFontGL* font = LLFontGL::getFontSansSerif();
- std::string full_name =
- LLCacheName::buildFullName( firstname->getString(), lastname->getString() );
+ std::string full_name = LLCacheName::buildFullName( firstname->getString(), lastname->getString() );
addNameTagLine(full_name, name_tag_color, LLFontGL::NORMAL, font);
- }
+ }
- mNameAway = is_away;
- mNameBusy = is_busy;
- mNameMute = is_muted;
- mNameAppearance = is_appearance;
+ mNameAway = is_away;
+ mNameDoNotDisturb = is_do_not_disturb;
+ mNameMute = is_muted;
+ mNameAppearance = is_appearance;
mNameFriend = is_friend;
- mNameCloud = is_cloud;
- mTitle = title ? title->getString() : "";
- LLStringFn::replace_ascii_controlchars(mTitle,LL_UNKNOWN_CHAR);
- new_name = TRUE;
- }
+ mNameCloud = is_cloud;
+ mTitle = title ? title->getString() : "";
+ LLStringFn::replace_ascii_controlchars(mTitle,LL_UNKNOWN_CHAR);
+ new_name = TRUE;
+ }
if (mVisibleChat)
- {
- mNameText->setFont(LLFontGL::getFontSansSerif());
+ {
+ mNameText->setFont(LLFontGL::getFontSansSerif());
mNameText->setTextAlignment(LLHUDNameTag::ALIGN_TEXT_LEFT);
- mNameText->setFadeDistance(CHAT_NORMAL_RADIUS * 2.f, 5.f);
-
- char line[MAX_STRING]; /* Flawfinder: ignore */
- line[0] = '\0';
- std::deque<LLChat>::iterator chat_iter = mChats.begin();
- mNameText->clearString();
-
- LLColor4 new_chat = LLUIColorTable::instance().getColor( isSelf() ? "UserChatColor" : "AgentChatColor" );
- LLColor4 normal_chat = lerp(new_chat, LLColor4(0.8f, 0.8f, 0.8f, 1.f), 0.7f);
- LLColor4 old_chat = lerp(normal_chat, LLColor4(0.6f, 0.6f, 0.6f, 1.f), 0.7f);
- if (mTyping && mChats.size() >= MAX_BUBBLE_CHAT_UTTERANCES)
- {
- ++chat_iter;
- }
+ mNameText->setFadeDistance(CHAT_NORMAL_RADIUS * 2.f, 5.f);
- for(; chat_iter != mChats.end(); ++chat_iter)
- {
- F32 chat_fade_amt = llclamp((F32)((LLFrameTimer::getElapsedSeconds() - chat_iter->mTime) / CHAT_FADE_TIME), 0.f, 4.f);
- LLFontGL::StyleFlags style;
- switch(chat_iter->mChatType)
- {
- case CHAT_TYPE_WHISPER:
- style = LLFontGL::ITALIC;
- break;
- case CHAT_TYPE_SHOUT:
- style = LLFontGL::BOLD;
- break;
- default:
- style = LLFontGL::NORMAL;
- break;
- }
- if (chat_fade_amt < 1.f)
- {
- F32 u = clamp_rescale(chat_fade_amt, 0.9f, 1.f, 0.f, 1.f);
- mNameText->addLine(chat_iter->mText, lerp(new_chat, normal_chat, u), style);
- }
- else if (chat_fade_amt < 2.f)
- {
- F32 u = clamp_rescale(chat_fade_amt, 1.9f, 2.f, 0.f, 1.f);
- mNameText->addLine(chat_iter->mText, lerp(normal_chat, old_chat, u), style);
- }
- else if (chat_fade_amt < 3.f)
- {
- // *NOTE: only remove lines down to minimum number
- mNameText->addLine(chat_iter->mText, old_chat, style);
- }
- }
- mNameText->setVisibleOffScreen(TRUE);
+ std::deque<LLChat>::iterator chat_iter = mChats.begin();
+ mNameText->clearString();
- if (mTyping)
- {
- S32 dot_count = (llfloor(mTypingTimer.getElapsedTimeF32() * 3.f) + 2) % 3 + 1;
- switch(dot_count)
- {
- case 1:
- mNameText->addLine(".", new_chat);
- break;
- case 2:
- mNameText->addLine("..", new_chat);
- break;
- case 3:
- mNameText->addLine("...", new_chat);
- break;
- }
+ LLColor4 new_chat = LLUIColorTable::instance().getColor( isSelf() ? "UserChatColor" : "AgentChatColor" );
+ LLColor4 normal_chat = lerp(new_chat, LLColor4(0.8f, 0.8f, 0.8f, 1.f), 0.7f);
+ LLColor4 old_chat = lerp(normal_chat, LLColor4(0.6f, 0.6f, 0.6f, 1.f), 0.7f);
+ if (mTyping && mChats.size() >= MAX_BUBBLE_CHAT_UTTERANCES)
+ {
+ ++chat_iter;
+ }
- }
+ for(; chat_iter != mChats.end(); ++chat_iter)
+ {
+ F32 chat_fade_amt = llclamp((F32)((LLFrameTimer::getElapsedSeconds() - chat_iter->mTime) / CHAT_FADE_TIME), 0.f, 4.f);
+ LLFontGL::StyleFlags style;
+ switch(chat_iter->mChatType)
+ {
+ case CHAT_TYPE_WHISPER:
+ style = LLFontGL::ITALIC;
+ break;
+ case CHAT_TYPE_SHOUT:
+ style = LLFontGL::BOLD;
+ break;
+ default:
+ style = LLFontGL::NORMAL;
+ break;
}
- else
+ if (chat_fade_amt < 1.f)
{
+ F32 u = clamp_rescale(chat_fade_amt, 0.9f, 1.f, 0.f, 1.f);
+ mNameText->addLine(chat_iter->mText, lerp(new_chat, normal_chat, u), style);
+ }
+ else if (chat_fade_amt < 2.f)
+ {
+ F32 u = clamp_rescale(chat_fade_amt, 1.9f, 2.f, 0.f, 1.f);
+ mNameText->addLine(chat_iter->mText, lerp(normal_chat, old_chat, u), style);
+ }
+ else if (chat_fade_amt < 3.f)
+ {
+ // *NOTE: only remove lines down to minimum number
+ mNameText->addLine(chat_iter->mText, old_chat, style);
+ }
+ }
+ mNameText->setVisibleOffScreen(TRUE);
+
+ if (mTyping)
+ {
+ S32 dot_count = (llfloor(mTypingTimer.getElapsedTimeF32() * 3.f) + 2) % 3 + 1;
+ switch(dot_count)
+ {
+ case 1:
+ mNameText->addLine(".", new_chat);
+ break;
+ case 2:
+ mNameText->addLine("..", new_chat);
+ break;
+ case 3:
+ mNameText->addLine("...", new_chat);
+ break;
+ }
+
+ }
+ }
+ else
+ {
// ...not using chat bubbles, just names
mNameText->setTextAlignment(LLHUDNameTag::ALIGN_TEXT_CENTER);
- mNameText->setFadeDistance(CHAT_NORMAL_RADIUS, 5.f);
- mNameText->setVisibleOffScreen(FALSE);
+ mNameText->setFadeDistance(CHAT_NORMAL_RADIUS, 5.f);
+ mNameText->setVisibleOffScreen(FALSE);
}
}
@@ -3229,18 +2842,18 @@ void LLVOAvatar::addNameTagLine(const std::string& line, const LLColor4& color,
{
mNameText->addLine(line, color, (LLFontGL::StyleFlags)style, font);
}
- mNameString += line;
- mNameString += '\n';
+ mNameIsSet |= !line.empty();
}
void LLVOAvatar::clearNameTag()
{
- mNameString.clear();
+ mNameIsSet = false;
if (mNameText)
- {
- mNameText->setLabel("");
- mNameText->setString( "" );
+ {
+ mNameText->setLabel("");
+ mNameText->setString("");
}
+ mTimeVisible.reset();
}
//static
@@ -3266,34 +2879,45 @@ void LLVOAvatar::invalidateNameTags()
if (avatar->isDead()) continue;
avatar->clearNameTag();
-
}
}
// Compute name tag position during idle update
-LLVector3 LLVOAvatar::idleUpdateNameTagPosition(const LLVector3& root_pos_last)
+void LLVOAvatar::idleUpdateNameTagPosition(const LLVector3& root_pos_last)
{
- LLQuaternion root_rot = mRoot.getWorldRotation();
+ LLQuaternion root_rot = mRoot->getWorldRotation();
+ LLQuaternion inv_root_rot = ~root_rot;
LLVector3 pixel_right_vec;
LLVector3 pixel_up_vec;
LLViewerCamera::getInstance()->getPixelVectors(root_pos_last, pixel_up_vec, pixel_right_vec);
LLVector3 camera_to_av = root_pos_last - LLViewerCamera::getInstance()->getOrigin();
camera_to_av.normalize();
- LLVector3 local_camera_at = camera_to_av * ~root_rot;
+ LLVector3 local_camera_at = camera_to_av * inv_root_rot;
LLVector3 local_camera_up = camera_to_av % LLViewerCamera::getInstance()->getLeftAxis();
local_camera_up.normalize();
- local_camera_up = local_camera_up * ~root_rot;
+ local_camera_up = local_camera_up * inv_root_rot;
+
+ LLVector3 avatar_ellipsoid(mBodySize.mV[VX] * 0.4f,
+ mBodySize.mV[VY] * 0.4f,
+ mBodySize.mV[VZ] * NAMETAG_VERT_OFFSET_WEIGHT);
- local_camera_up.scaleVec(mBodySize * 0.5f);
- local_camera_at.scaleVec(mBodySize * 0.5f);
+ local_camera_up.scaleVec(avatar_ellipsoid);
+ local_camera_at.scaleVec(avatar_ellipsoid);
- LLVector3 name_position = mRoot.getWorldPosition();
- name_position[VZ] -= mPelvisToFoot;
- name_position[VZ] += (mBodySize[VZ]* 0.55f);
+ LLVector3 head_offset = (mHeadp->getLastWorldPosition() - mRoot->getLastWorldPosition()) * inv_root_rot;
+
+ if (dist_vec(head_offset, mTargetRootToHeadOffset) > NAMETAG_UPDATE_THRESHOLD)
+ {
+ mTargetRootToHeadOffset = head_offset;
+ }
+
+ mCurRootToHeadOffset = lerp(mCurRootToHeadOffset, mTargetRootToHeadOffset, LLCriticalDamp::getInterpolant(0.2f));
+
+ LLVector3 name_position = mRoot->getLastWorldPosition() + (mCurRootToHeadOffset * root_rot);
name_position += (local_camera_up * root_rot) - (projected_vec(local_camera_at * root_rot, camera_to_av));
- name_position += pixel_up_vec * 15.f;
+ name_position += pixel_up_vec * NAMETAG_VERTICAL_SCREEN_OFFSET;
- return name_position;
+ mNameText->setPositionAgent(name_position);
}
void LLVOAvatar::idleUpdateNameTagAlpha(BOOL new_name, F32 alpha)
@@ -3310,26 +2934,24 @@ void LLVOAvatar::idleUpdateNameTagAlpha(BOOL new_name, F32 alpha)
LLColor4 LLVOAvatar::getNameTagColor(bool is_friend)
{
- static LLUICachedControl<bool> show_friends("NameTagShowFriends");
+ static LLUICachedControl<bool> show_friends("NameTagShowFriends", false);
const char* color_name;
if (show_friends && is_friend)
{
color_name = "NameTagFriend";
}
- else if (LLAvatarNameCache::useDisplayNames())
+ else if (LLAvatarName::useDisplayNames())
{
- // ...color based on whether username "matches" a computed display
- // name
+ // ...color based on whether username "matches" a computed display name
LLAvatarName av_name;
- if (LLAvatarNameCache::get(getID(), &av_name)
- && av_name.mIsDisplayNameDefault)
+ if (LLAvatarNameCache::get(getID(), &av_name) && av_name.isDisplayNameDefault())
{
color_name = "NameTagMatch";
}
else
{
color_name = "NameTagMismatch";
- }
+ }
}
else
{
@@ -3352,35 +2974,152 @@ void LLVOAvatar::idleUpdateBelowWater()
void LLVOAvatar::slamPosition()
{
gAgent.setPositionAgent(getPositionAgent());
- mRoot.setWorldPosition(getPositionAgent()); // teleport
+ mRoot->setWorldPosition(getPositionAgent()); // teleport
setChanged(TRANSLATED);
if (mDrawable.notNull())
{
gPipeline.updateMoveNormalAsync(mDrawable);
}
- mRoot.updateWorldMatrixChildren();
+ mRoot->updateWorldMatrixChildren();
}
-bool LLVOAvatar::isVisuallyMuted() const
+bool LLVOAvatar::isVisuallyMuted()
{
- static LLCachedControl<U32> max_attachment_bytes(gSavedSettings, "RenderAutoMuteByteLimit");
- static LLCachedControl<F32> max_attachment_area(gSavedSettings, "RenderAutoMuteSurfaceAreaLimit");
-
- return LLMuteList::getInstance()->isMuted(getID()) ||
- (mAttachmentGeometryBytes > max_attachment_bytes && max_attachment_bytes > 0) ||
- (mAttachmentSurfaceArea > max_attachment_area && max_attachment_area > 0.f);
+ bool muted = false;
+
+ if (!isSelf())
+ {
+ static LLCachedControl<U32> render_auto_mute_functions(gSavedSettings, "RenderAutoMuteFunctions", 0);
+ if (render_auto_mute_functions) // Hacky debug switch for developing feature
+ {
+ // Priority order (highest priority first)
+ // * own avatar is never visually muted
+ // * if on the "always draw normally" list, draw them normally
+ // * if on the "always visually mute" list, mute them
+ // * draw them normally if they meet the following criteria:
+ // - within the closest N avatars OR on friends list OR in an IM chat
+ // - AND aren't over the thresholds
+ // * otherwise visually mute all other avatars
+
+ static LLCachedControl<U32> max_attachment_bytes(gSavedSettings, "RenderAutoMuteByteLimit", 0);
+ static LLCachedControl<F32> max_attachment_area(gSavedSettings, "RenderAutoMuteSurfaceAreaLimit", 0.0);
+ static LLCachedControl<U32> max_render_cost(gSavedSettings, "RenderAutoMuteRenderWeightLimit", 0);
+
+ if (mVisuallyMuteSetting == ALWAYS_VISUAL_MUTE)
+ { // Always want to see this AV as an impostor
+ muted = true;
+ }
+ else if (mVisuallyMuteSetting == NEVER_VISUAL_MUTE)
+ { // Never show as impostor
+ muted = false;
+ }
+ else
+ {
+ F64 now = LLFrameTimer::getTotalSeconds();
+
+ if (now < mCachedVisualMuteUpdateTime)
+ { // Use cached mute value
+ muted = mCachedVisualMute;
+ }
+ else
+ { // Determine if visually muted or not
+
+ U32 max_cost = (U32) (max_render_cost*(LLVOAvatar::sLODFactor+0.5));
+
+ muted = LLMuteList::getInstance()->isMuted(getID()) ||
+ (mAttachmentGeometryBytes > max_attachment_bytes && max_attachment_bytes > 0) ||
+ (mAttachmentSurfaceArea > max_attachment_area && max_attachment_area > 0.f) ||
+ (mVisualComplexity > max_cost && max_render_cost > 0);
+
+ // Could be part of the grand || collection above, but yanked out to make the logic visible
+ if (!muted)
+ {
+ if (sMaxVisible > 0)
+ { // They are above the visibilty rank - mute them
+ muted = (mVisibilityRank > sMaxVisible);
+ }
+
+ // Always draw friends or those in IMs. Needs UI?
+ if ((render_auto_mute_functions & 0x02) &&
+ (muted || sMaxVisible == 0)) // Don't mute friends or IMs
+ {
+ muted = !(LLAvatarTracker::instance().isBuddy(getID()));
+ if (muted)
+ { // Not a friend, so they are muted ... are they in an IM?
+ LLUUID session_id = gIMMgr->computeSessionID(IM_NOTHING_SPECIAL,getID());
+ muted = !gIMMgr->hasSession(session_id);
+ }
+ }
+ }
+
+ // Save visual mute state and set interval for updating
+ const F64 SECONDS_BETWEEN_RENDER_AUTO_MUTE_UPDATES = 1.5;
+ mCachedVisualMuteUpdateTime = now + SECONDS_BETWEEN_RENDER_AUTO_MUTE_UPDATES;
+ mCachedVisualMute = muted;
+ }
+ }
+ }
+ }
+
+ return muted;
}
+void LLVOAvatar::forceUpdateVisualMuteSettings()
+{
+ // Set the cache time so it's updated ASAP
+ mCachedVisualMuteUpdateTime = LLFrameTimer::getTotalSeconds() - 1.0;
+}
+
+
//------------------------------------------------------------------------
// updateCharacter()
// called on both your avatar and other avatars
//------------------------------------------------------------------------
BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
{
- LLMemType mt(LLMemType::MTYPE_AVATAR);
-
// clear debug text
mDebugText.clear();
+
+ if (gSavedSettings.getBOOL("DebugAvatarAppearanceMessage"))
+ {
+ S32 central_bake_version = -1;
+ if (getRegion())
+ {
+ central_bake_version = getRegion()->getCentralBakeVersion();
+ }
+ bool all_baked_downloaded = allBakedTexturesCompletelyDownloaded();
+ bool all_local_downloaded = allLocalTexturesCompletelyDownloaded();
+ std::string debug_line = llformat("%s%s - mLocal: %d, mEdit: %d, mUSB: %d, CBV: %d",
+ isSelf() ? (all_local_downloaded ? "L" : "l") : "-",
+ all_baked_downloaded ? "B" : "b",
+ mUseLocalAppearance, mIsEditingAppearance,
+ mUseServerBakes, central_bake_version);
+ std::string origin_string = bakedTextureOriginInfo();
+ debug_line += " [" + origin_string + "]";
+ S32 curr_cof_version = LLAppearanceMgr::instance().getCOFVersion();
+ S32 last_request_cof_version = mLastUpdateRequestCOFVersion;
+ S32 last_received_cof_version = mLastUpdateReceivedCOFVersion;
+ if (isSelf())
+ {
+ debug_line += llformat(" - cof: %d req: %d rcv:%d",
+ curr_cof_version, last_request_cof_version, last_received_cof_version);
+ if (gSavedSettings.getBOOL("DebugForceAppearanceRequestFailure"))
+ {
+ debug_line += " FORCING ERRS";
+ }
+ }
+ else
+ {
+ debug_line += llformat(" - cof rcv:%d", last_received_cof_version);
+ }
+ addDebugText(debug_line);
+ }
+ if (gSavedSettings.getBOOL("DebugAvatarCompositeBaked"))
+ {
+ if (!mBakedTextureDebugText.empty())
+ addDebugText(mBakedTextureDebugText);
+ }
+
if (LLVOAvatar::sShowAnimationDebug)
{
for (LLMotionController::motion_list_t::iterator iter = mMotionController.getActiveMotions().begin();
@@ -3409,8 +3148,6 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
}
}
- LLVector3d root_pos_global;
-
if (!mIsBuilt)
{
return FALSE;
@@ -3425,12 +3162,12 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
mTimeVisible.reset();
}
-
//--------------------------------------------------------------------
// the rest should only be done occasionally for far away avatars
//--------------------------------------------------------------------
- if (visible && (!isSelf() || isVisuallyMuted()) && !mIsDummy && sUseImpostors && !mNeedsAnimUpdate && !sFreezeCounter)
+ bool visually_muted = isVisuallyMuted();
+ if (visible && (!isSelf() || visually_muted) && !mIsDummy && sUseImpostors && !mNeedsAnimUpdate && !sFreezeCounter)
{
const LLVector4a* ext = mDrawable->getSpatialExtents();
LLVector4a size;
@@ -3439,8 +3176,8 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
F32 impostor_area = 256.f*512.f*(8.125f - LLVOAvatar::sLODFactor*8.f);
- if (isVisuallyMuted())
- { // muted avatars update at 16 hz
+ if (visually_muted)
+ { // visually muted avatars update at 16 hz
mUpdatePeriod = 16;
}
else if (mVisibilityRank <= LLVOAvatar::sMaxVisible ||
@@ -3520,8 +3257,6 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
xyVel.mV[VZ] = 0.0f;
speed = xyVel.length();
- BOOL throttle = TRUE;
-
if (!(mIsSitting && getParent()))
{
//--------------------------------------------------------------------
@@ -3532,11 +3267,10 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
if (mTimeLast == 0.0f)
{
mTimeLast = animation_time;
- throttle = FALSE;
// put the pelvis at slaved position/mRotation
- mRoot.setWorldPosition( getPositionAgent() ); // first frame
- mRoot.setWorldRotation( getRotation() );
+ mRoot->setWorldPosition( getPositionAgent() ); // first frame
+ mRoot->setWorldRotation( getRotation() );
}
//--------------------------------------------------------------------
@@ -3561,6 +3295,8 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
}
root_pos = gAgent.getPosGlobalFromAgent(getRenderPosition());
+ root_pos.mdV[VZ] += getVisualParamWeight(AVATAR_HOVER);
+
resolveHeightGlobal(root_pos, ground_under_pelvis, normal);
F32 foot_to_ground = (F32) (root_pos.mdV[VZ] - mPelvisToFoot - ground_under_pelvis.mdV[VZ]);
@@ -3579,10 +3315,10 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
LLVector3 newPosition = gAgent.getPosAgentFromGlobal(root_pos);
- if (newPosition != mRoot.getXform()->getWorldPosition())
+ if (newPosition != mRoot->getXform()->getWorldPosition())
{
- mRoot.touch();
- mRoot.setWorldPosition( newPosition ); // regular update
+ mRoot->touch();
+ mRoot->setWorldPosition( newPosition ); // regular update
}
@@ -3643,7 +3379,7 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
}
- LLQuaternion root_rotation = mRoot.getWorldMatrix().quaternion();
+ LLQuaternion root_rotation = mRoot->getWorldMatrix().quaternion();
F32 root_roll, root_pitch, root_yaw;
root_rotation.getEulerAngles(&root_roll, &root_pitch, &root_yaw);
@@ -3652,10 +3388,10 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
// and head turn. Once in motion, it must conform however.
BOOL self_in_mouselook = isSelf() && gAgentCamera.cameraMouselook();
- LLVector3 pelvisDir( mRoot.getWorldMatrix().getFwdRow4().mV );
+ LLVector3 pelvisDir( mRoot->getWorldMatrix().getFwdRow4().mV );
- static LLCachedControl<F32> s_pelvis_rot_threshold_slow(gSavedSettings, "AvatarRotateThresholdSlow");
- static LLCachedControl<F32> s_pelvis_rot_threshold_fast(gSavedSettings, "AvatarRotateThresholdFast");
+ static LLCachedControl<F32> s_pelvis_rot_threshold_slow(gSavedSettings, "AvatarRotateThresholdSlow", 60.0);
+ static LLCachedControl<F32> s_pelvis_rot_threshold_fast(gSavedSettings, "AvatarRotateThresholdFast", 2.0);
F32 pelvis_rot_threshold = clamp_rescale(speed, 0.1f, 1.0f, s_pelvis_rot_threshold_slow, s_pelvis_rot_threshold_fast);
@@ -3738,14 +3474,14 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
F32 u = llclamp((deltaTime / pelvis_lag_time), 0.0f, 1.0f);
- mRoot.setWorldRotation( slerp(u, mRoot.getWorldRotation(), wQv) );
+ mRoot->setWorldRotation( slerp(u, mRoot->getWorldRotation(), wQv) );
}
}
else if (mDrawable.notNull())
{
- mRoot.setPosition(mDrawable->getPosition());
- mRoot.setRotation(mDrawable->getRotation());
+ mRoot->setPosition(mDrawable->getPosition());
+ mRoot->setRotation(mDrawable->getRotation());
}
//-------------------------------------------------------------------------
@@ -3828,10 +3564,6 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
if ( playSound )
{
-// F32 gain = clamp_rescale( mSpeedAccum,
-// AUDIO_STEP_LO_SPEED, AUDIO_STEP_HI_SPEED,
-// AUDIO_STEP_LO_GAIN, AUDIO_STEP_HI_GAIN );
-
const F32 STEP_VOLUME = 0.1f;
const LLUUID& step_sound_id = getStepSound();
@@ -3845,7 +3577,7 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
}
}
- mRoot.updateWorldMatrixChildren();
+ mRoot->updateWorldMatrixChildren();
if (!mDebugText.size() && mText.notNull())
{
@@ -3869,7 +3601,7 @@ void LLVOAvatar::updateHeadOffset()
{
// since we only care about Z, just grab one of the eyes
LLVector3 midEyePt = mEyeLeftp->getWorldPosition();
- midEyePt -= mDrawable.notNull() ? mDrawable->getWorldPosition() : mRoot.getWorldPosition();
+ midEyePt -= mDrawable.notNull() ? mDrawable->getWorldPosition() : mRoot->getWorldPosition();
midEyePt.mV[VZ] = llmax(-mPelvisToFoot + LLViewerCamera::getInstance()->getNear(), midEyePt.mV[VZ]);
if (mDrawable.notNull())
@@ -3907,8 +3639,8 @@ void LLVOAvatar::setPelvisOffset( bool hasOffset, const LLVector3& offsetAmount,
void LLVOAvatar::postPelvisSetRecalc( void )
{
computeBodySize();
- mRoot.touch();
- mRoot.updateWorldMatrixChildren();
+ mRoot->touch();
+ mRoot->updateWorldMatrixChildren();
dirtyMesh();
updateHeadOffset();
}
@@ -3964,7 +3696,7 @@ void LLVOAvatar::updateVisibility()
LLNameValue* firstname = getNVPair("FirstName");
if (firstname)
{
- llinfos << "Avatar " << firstname->getString() << " updating visiblity" << llendl;
+ LL_DEBUGS("Avatar") << avString() << " updating visibility" << LL_ENDL;
}
else
{
@@ -4048,13 +3780,6 @@ void LLVOAvatar::updateVisibility()
{
releaseMeshData();
}
- // this breaks off-screen chat bubbles
- //if (mNameText)
- //{
- // mNameText->markDead();
- // mNameText = NULL;
- // sNumVisibleChatBubbles--;
- //}
}
mVisible = visible;
@@ -4063,53 +3788,13 @@ void LLVOAvatar::updateVisibility()
// private
bool LLVOAvatar::shouldAlphaMask()
{
- const bool should_alpha_mask = mSupportsAlphaLayers && !LLDrawPoolAlpha::sShowDebugAlpha // Don't alpha mask if "Highlight Transparent" checked
+ const bool should_alpha_mask = !LLDrawPoolAlpha::sShowDebugAlpha // Don't alpha mask if "Highlight Transparent" checked
&& !LLDrawPoolAvatar::sSkipTransparent;
return should_alpha_mask;
}
-U32 LLVOAvatar::renderSkinnedAttachments()
-{
- /*U32 num_indices = 0;
-
- const U32 data_mask = LLVertexBuffer::MAP_VERTEX |
- LLVertexBuffer::MAP_NORMAL |
- LLVertexBuffer::MAP_TEXCOORD0 |
- LLVertexBuffer::MAP_COLOR |
- LLVertexBuffer::MAP_WEIGHT4;
-
- for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin();
- iter != mAttachmentPoints.end();
- ++iter)
- {
- LLViewerJointAttachment* attachment = iter->second;
- for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
- attachment_iter != attachment->mAttachedObjects.end();
- ++attachment_iter)
- {
- const LLViewerObject* attached_object = (*attachment_iter);
- if (attached_object && !attached_object->isHUDAttachment())
- {
- const LLDrawable* drawable = attached_object->mDrawable;
- if (drawable)
- {
- for (S32 i = 0; i < drawable->getNumFaces(); ++i)
- {
- LLFace* face = drawable->getFace(i);
- if (face->isState(LLFace::RIGGED))
- {
-
- }
- }
- }
- }
-
- return num_indices;*/
- return 0;
-}
-
//-----------------------------------------------------------------------------
// renderSkinned()
//-----------------------------------------------------------------------------
@@ -4130,11 +3815,11 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass)
{ //LOD changed or new mesh created, allocate new vertex buffer if needed
if (needs_rebuild || mDirtyMesh >= 2 || mVisibilityRank <= 4)
{
- updateMeshData();
+ updateMeshData();
mDirtyMesh = 0;
- mNeedsSkin = TRUE;
- mDrawable->clearState(LLDrawable::REBUILD_GEOMETRY);
- }
+ mNeedsSkin = TRUE;
+ mDrawable->clearState(LLDrawable::REBUILD_GEOMETRY);
+ }
}
if (LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_AVATAR) <= 0)
@@ -4142,30 +3827,59 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass)
if (mNeedsSkin)
{
//generate animated mesh
- mMeshLOD[MESH_ID_LOWER_BODY]->updateJointGeometry();
- mMeshLOD[MESH_ID_UPPER_BODY]->updateJointGeometry();
+ LLViewerJoint* lower_mesh = getViewerJoint(MESH_ID_LOWER_BODY);
+ LLViewerJoint* upper_mesh = getViewerJoint(MESH_ID_UPPER_BODY);
+ LLViewerJoint* skirt_mesh = getViewerJoint(MESH_ID_SKIRT);
+ LLViewerJoint* eyelash_mesh = getViewerJoint(MESH_ID_EYELASH);
+ LLViewerJoint* head_mesh = getViewerJoint(MESH_ID_HEAD);
+ LLViewerJoint* hair_mesh = getViewerJoint(MESH_ID_HAIR);
+
+ if(upper_mesh)
+ {
+ upper_mesh->updateJointGeometry();
+ }
+ if (lower_mesh)
+ {
+ lower_mesh->updateJointGeometry();
+ }
if( isWearingWearableType( LLWearableType::WT_SKIRT ) )
{
- mMeshLOD[MESH_ID_SKIRT]->updateJointGeometry();
+ if(skirt_mesh)
+ {
+ skirt_mesh->updateJointGeometry();
+ }
}
if (!isSelf() || gAgent.needsRenderHead() || LLPipeline::sShadowRender)
{
- mMeshLOD[MESH_ID_EYELASH]->updateJointGeometry();
- mMeshLOD[MESH_ID_HEAD]->updateJointGeometry();
- mMeshLOD[MESH_ID_HAIR]->updateJointGeometry();
+ if(eyelash_mesh)
+ {
+ eyelash_mesh->updateJointGeometry();
+ }
+ if(head_mesh)
+ {
+ head_mesh->updateJointGeometry();
+ }
+ if(hair_mesh)
+ {
+ hair_mesh->updateJointGeometry();
+ }
}
mNeedsSkin = FALSE;
mLastSkinTime = gFrameTimeSeconds;
- LLVertexBuffer* vb = mDrawable->getFace(0)->getVertexBuffer();
+ LLFace * face = mDrawable->getFace(0);
+ if (face)
+ {
+ LLVertexBuffer* vb = face->getVertexBuffer();
if (vb)
{
vb->flush();
}
}
}
+ }
else
{
mNeedsSkin = FALSE;
@@ -4176,7 +3890,7 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass)
LLNameValue* firstname = getNVPair("FirstName");
if (firstname)
{
- llinfos << "Avatar " << firstname->getString() << " in render" << llendl;
+ LL_DEBUGS("Avatar") << avString() << " in render" << LL_ENDL;
}
else
{
@@ -4263,23 +3977,37 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass)
BOOL first_pass = TRUE;
if (!LLDrawPoolAvatar::sSkipOpaque)
{
+ bool visually_muted = isVisuallyMuted();
+
if (!isSelf() || gAgent.needsRenderHead() || LLPipeline::sShadowRender)
{
- if (isTextureVisible(TEX_HEAD_BAKED) || mIsDummy)
+ if (isTextureVisible(TEX_HEAD_BAKED) || mIsDummy || visually_muted)
{
- num_indices += mMeshLOD[MESH_ID_HEAD]->render(mAdjustedPixelArea, TRUE, mIsDummy);
+ LLViewerJoint* head_mesh = getViewerJoint(MESH_ID_HEAD);
+ if (head_mesh)
+ {
+ num_indices += head_mesh->render(mAdjustedPixelArea, TRUE, mIsDummy);
+ }
first_pass = FALSE;
}
}
- if (isTextureVisible(TEX_UPPER_BAKED) || mIsDummy)
+ if (isTextureVisible(TEX_UPPER_BAKED) || mIsDummy || visually_muted)
{
- num_indices += mMeshLOD[MESH_ID_UPPER_BODY]->render(mAdjustedPixelArea, first_pass, mIsDummy);
+ LLViewerJoint* upper_mesh = getViewerJoint(MESH_ID_UPPER_BODY);
+ if (upper_mesh)
+ {
+ num_indices += upper_mesh->render(mAdjustedPixelArea, first_pass, mIsDummy);
+ }
first_pass = FALSE;
}
- if (isTextureVisible(TEX_LOWER_BAKED) || mIsDummy)
+ if (isTextureVisible(TEX_LOWER_BAKED) || mIsDummy || visually_muted)
{
- num_indices += mMeshLOD[MESH_ID_LOWER_BODY]->render(mAdjustedPixelArea, first_pass, mIsDummy);
+ LLViewerJoint* lower_mesh = getViewerJoint(MESH_ID_LOWER_BODY);
+ if (lower_mesh)
+ {
+ num_indices += lower_mesh->render(mAdjustedPixelArea, first_pass, mIsDummy);
+ }
first_pass = FALSE;
}
}
@@ -4312,7 +4040,11 @@ U32 LLVOAvatar::renderTransparent(BOOL first_pass)
if( isWearingWearableType( LLWearableType::WT_SKIRT ) && (mIsDummy || isTextureVisible(TEX_SKIRT_BAKED)) )
{
gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.25f);
- num_indices += mMeshLOD[MESH_ID_SKIRT]->render(mAdjustedPixelArea, FALSE);
+ LLViewerJoint* skirt_mesh = getViewerJoint(MESH_ID_SKIRT);
+ if (skirt_mesh)
+ {
+ num_indices += skirt_mesh->render(mAdjustedPixelArea, FALSE);
+ }
first_pass = FALSE;
gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
}
@@ -4326,14 +4058,23 @@ U32 LLVOAvatar::renderTransparent(BOOL first_pass)
if (isTextureVisible(TEX_HEAD_BAKED))
{
- num_indices += mMeshLOD[MESH_ID_EYELASH]->render(mAdjustedPixelArea, first_pass, mIsDummy);
+ LLViewerJoint* eyelash_mesh = getViewerJoint(MESH_ID_EYELASH);
+ if (eyelash_mesh)
+ {
+ num_indices += eyelash_mesh->render(mAdjustedPixelArea, first_pass, mIsDummy);
+ }
first_pass = FALSE;
}
// Can't test for baked hair being defined, since that won't always be the case (not all viewers send baked hair)
// TODO: 1.25 will be able to switch this logic back to calling isTextureVisible();
- if (getImage(TEX_HAIR_BAKED, 0)->getID() != IMG_INVISIBLE || LLDrawPoolAlpha::sShowDebugAlpha)
+ if ( getImage(TEX_HAIR_BAKED, 0) &&
+ getImage(TEX_HAIR_BAKED, 0)->getID() != IMG_INVISIBLE || LLDrawPoolAlpha::sShowDebugAlpha)
{
- num_indices += mMeshLOD[MESH_ID_HAIR]->render(mAdjustedPixelArea, first_pass, mIsDummy);
+ LLViewerJoint* hair_mesh = getViewerJoint(MESH_ID_HAIR);
+ if (hair_mesh)
+ {
+ num_indices += hair_mesh->render(mAdjustedPixelArea, first_pass, mIsDummy);
+ }
first_pass = FALSE;
}
if (LLPipeline::sImpostorRender)
@@ -4341,7 +4082,7 @@ U32 LLVOAvatar::renderTransparent(BOOL first_pass)
gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
}
}
-
+
return num_indices;
}
@@ -4377,8 +4118,16 @@ U32 LLVOAvatar::renderRigid()
if (isTextureVisible(TEX_EYES_BAKED) || mIsDummy)
{
- num_indices += mMeshLOD[MESH_ID_EYEBALL_LEFT]->render(mAdjustedPixelArea, TRUE, mIsDummy);
- num_indices += mMeshLOD[MESH_ID_EYEBALL_RIGHT]->render(mAdjustedPixelArea, TRUE, mIsDummy);
+ LLViewerJoint* eyeball_left = getViewerJoint(MESH_ID_EYEBALL_LEFT);
+ LLViewerJoint* eyeball_right = getViewerJoint(MESH_ID_EYEBALL_RIGHT);
+ if (eyeball_left)
+ {
+ num_indices += eyeball_left->render(mAdjustedPixelArea, TRUE, mIsDummy);
+ }
+ if(eyeball_right)
+ {
+ num_indices += eyeball_right->render(mAdjustedPixelArea, TRUE, mIsDummy);
+ }
}
if (should_alpha_mask && !LLGLSLShader::sNoFixedFunction)
@@ -4425,11 +4174,224 @@ U32 LLVOAvatar::renderImpostor(LLColor4U color, S32 diffuse_channel)
return 6;
}
-//------------------------------------------------------------------------
-// LLVOAvatar::updateTextures()
-//------------------------------------------------------------------------
+bool LLVOAvatar::allTexturesCompletelyDownloaded(std::set<LLUUID>& ids) const
+{
+ for (std::set<LLUUID>::const_iterator it = ids.begin(); it != ids.end(); ++it)
+ {
+ LLViewerFetchedTexture *imagep = gTextureList.findImage(*it);
+ if (imagep && imagep->getDiscardLevel()!=0)
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool LLVOAvatar::allLocalTexturesCompletelyDownloaded() const
+{
+ std::set<LLUUID> local_ids;
+ collectLocalTextureUUIDs(local_ids);
+ return allTexturesCompletelyDownloaded(local_ids);
+}
+
+bool LLVOAvatar::allBakedTexturesCompletelyDownloaded() const
+{
+ std::set<LLUUID> baked_ids;
+ collectBakedTextureUUIDs(baked_ids);
+ return allTexturesCompletelyDownloaded(baked_ids);
+}
+
+void LLVOAvatar::bakedTextureOriginCounts(S32 &sb_count, // server-bake, has origin URL.
+ S32 &host_count, // host-based bake, has host.
+ S32 &both_count, // error - both host and URL set.
+ S32 &neither_count) // error - neither set.
+{
+ sb_count = host_count = both_count = neither_count = 0;
+
+ std::set<LLUUID> baked_ids;
+ collectBakedTextureUUIDs(baked_ids);
+ for (std::set<LLUUID>::const_iterator it = baked_ids.begin(); it != baked_ids.end(); ++it)
+ {
+ LLViewerFetchedTexture *imagep = gTextureList.findImage(*it);
+ bool has_url = false, has_host = false;
+ if (!imagep->getUrl().empty())
+ {
+ has_url = true;
+ }
+ if (imagep->getTargetHost().isOk())
+ {
+ has_host = true;
+ }
+ if (has_url && !has_host) sb_count++;
+ else if (has_host && !has_url) host_count++;
+ else if (has_host && has_url) both_count++;
+ else if (!has_host && !has_url) neither_count++;
+ }
+}
+
+std::string LLVOAvatar::bakedTextureOriginInfo()
+{
+ std::string result;
+
+ std::set<LLUUID> baked_ids;
+ collectBakedTextureUUIDs(baked_ids);
+ for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
+ {
+ ETextureIndex texture_index = mBakedTextureDatas[i].mTextureIndex;
+ LLViewerFetchedTexture *imagep =
+ LLViewerTextureManager::staticCastToFetchedTexture(getImage(texture_index,0), TRUE);
+ if (!imagep ||
+ imagep->getID() == IMG_DEFAULT ||
+ imagep->getID() == IMG_DEFAULT_AVATAR)
+
+ {
+ result += "-";
+ }
+ else
+ {
+ bool has_url = false, has_host = false;
+ if (!imagep->getUrl().empty())
+ {
+ has_url = true;
+ }
+ if (imagep->getTargetHost().isOk())
+ {
+ has_host = true;
+ }
+ S32 discard = imagep->getDiscardLevel();
+ if (has_url && !has_host) result += discard ? "u" : "U"; // server-bake texture with url
+ else if (has_host && !has_url) result += discard ? "h" : "H"; // old-style texture on sim
+ else if (has_host && has_url) result += discard ? "x" : "X"; // both origins?
+ else if (!has_host && !has_url) result += discard ? "n" : "N"; // no origin?
+ if (discard != 0)
+ {
+ result += llformat("(%d/%d)",discard,imagep->getDesiredDiscardLevel());
+ }
+ }
+
+ }
+ return result;
+}
+
+S32 LLVOAvatar::totalTextureMemForUUIDS(std::set<LLUUID>& ids)
+{
+ S32 result = 0;
+ for (std::set<LLUUID>::const_iterator it = ids.begin(); it != ids.end(); ++it)
+ {
+ LLViewerFetchedTexture *imagep = gTextureList.findImage(*it);
+ if (imagep)
+ {
+ result += imagep->getTextureMemory();
+ }
+ }
+ return result;
+}
+
+void LLVOAvatar::collectLocalTextureUUIDs(std::set<LLUUID>& ids) const
+{
+ for (U32 texture_index = 0; texture_index < getNumTEs(); texture_index++)
+ {
+ LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getTEWearableType((ETextureIndex)texture_index);
+ U32 num_wearables = gAgentWearables.getWearableCount(wearable_type);
+
+ LLViewerFetchedTexture *imagep = NULL;
+ for (U32 wearable_index = 0; wearable_index < num_wearables; wearable_index++)
+ {
+ imagep = LLViewerTextureManager::staticCastToFetchedTexture(getImage(texture_index, wearable_index), TRUE);
+ if (imagep)
+ {
+ const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearanceDictionary::getInstance()->getTexture((ETextureIndex)texture_index);
+ if (texture_dict->mIsLocalTexture)
+ {
+ ids.insert(imagep->getID());
+ }
+ }
+ }
+ }
+ ids.erase(IMG_DEFAULT);
+ ids.erase(IMG_DEFAULT_AVATAR);
+ ids.erase(IMG_INVISIBLE);
+}
+
+void LLVOAvatar::collectBakedTextureUUIDs(std::set<LLUUID>& ids) const
+{
+ for (U32 texture_index = 0; texture_index < getNumTEs(); texture_index++)
+ {
+ LLViewerFetchedTexture *imagep = NULL;
+ if (isIndexBakedTexture((ETextureIndex) texture_index))
+ {
+ imagep = LLViewerTextureManager::staticCastToFetchedTexture(getImage(texture_index,0), TRUE);
+ if (imagep)
+ {
+ ids.insert(imagep->getID());
+ }
+ }
+ }
+ ids.erase(IMG_DEFAULT);
+ ids.erase(IMG_DEFAULT_AVATAR);
+ ids.erase(IMG_INVISIBLE);
+}
+
+void LLVOAvatar::collectTextureUUIDs(std::set<LLUUID>& ids)
+{
+ collectLocalTextureUUIDs(ids);
+ collectBakedTextureUUIDs(ids);
+}
+
+void LLVOAvatar::releaseOldTextures()
+{
+ S32 current_texture_mem = 0;
+
+ // Any textures that we used to be using but are no longer using should no longer be flagged as "NO_DELETE"
+ std::set<LLUUID> baked_texture_ids;
+ collectBakedTextureUUIDs(baked_texture_ids);
+ S32 new_baked_mem = totalTextureMemForUUIDS(baked_texture_ids);
+
+ std::set<LLUUID> local_texture_ids;
+ collectLocalTextureUUIDs(local_texture_ids);
+ //S32 new_local_mem = totalTextureMemForUUIDS(local_texture_ids);
+
+ std::set<LLUUID> new_texture_ids;
+ new_texture_ids.insert(baked_texture_ids.begin(),baked_texture_ids.end());
+ new_texture_ids.insert(local_texture_ids.begin(),local_texture_ids.end());
+ S32 new_total_mem = totalTextureMemForUUIDS(new_texture_ids);
+
+ //S32 old_total_mem = totalTextureMemForUUIDS(mTextureIDs);
+ //LL_DEBUGS("Avatar") << getFullname() << " old_total_mem: " << old_total_mem << " new_total_mem (L/B): " << new_total_mem << " (" << new_local_mem <<", " << new_baked_mem << ")" << llendl;
+ if (!isSelf() && new_total_mem > new_baked_mem)
+ {
+ llwarns << "extra local textures stored for non-self av" << llendl;
+ }
+ for (std::set<LLUUID>::iterator it = mTextureIDs.begin(); it != mTextureIDs.end(); ++it)
+ {
+ if (new_texture_ids.find(*it) == new_texture_ids.end())
+ {
+ LLViewerFetchedTexture *imagep = gTextureList.findImage(*it);
+ if (imagep)
+ {
+ current_texture_mem += imagep->getTextureMemory();
+ if (imagep->getTextureState() == LLGLTexture::NO_DELETE)
+ {
+ // This will allow the texture to be deleted if not in use.
+ imagep->forceActive();
+
+ // This resets the clock to texture being flagged
+ // as unused, preventing the texture from being
+ // deleted immediately. If other avatars or
+ // objects are using it, it can still be flagged
+ // no-delete by them.
+ imagep->forceUpdateBindStats();
+ }
+ }
+ }
+ }
+ mTextureIDs = new_texture_ids;
+}
+
void LLVOAvatar::updateTextures()
{
+ releaseOldTextures();
+
BOOL render_avatar = TRUE;
if (mIsDummy)
@@ -4472,21 +4434,34 @@ void LLVOAvatar::updateTextures()
mHasGrey = FALSE; // debug
for (U32 texture_index = 0; texture_index < getNumTEs(); texture_index++)
{
- LLWearableType::EType wearable_type = LLVOAvatarDictionary::getTEWearableType((ETextureIndex)texture_index);
+ LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getTEWearableType((ETextureIndex)texture_index);
U32 num_wearables = gAgentWearables.getWearableCount(wearable_type);
const LLTextureEntry *te = getTE(texture_index);
- const F32 texel_area_ratio = fabs(te->mScaleS * te->mScaleT);
+
+ // getTE can return 0.
+ // Not sure yet why it does, but of course it crashes when te->mScale? gets used.
+ // Put safeguard in place so this corner case get better handling and does not result in a crash.
+ F32 texel_area_ratio = 1.0f;
+ if( te )
+ {
+ texel_area_ratio = fabs(te->mScaleS * te->mScaleT);
+ }
+ else
+ {
+ llwarns << "getTE( " << texture_index << " ) returned 0" <<llendl;
+ }
+
LLViewerFetchedTexture *imagep = NULL;
for (U32 wearable_index = 0; wearable_index < num_wearables; wearable_index++)
{
imagep = LLViewerTextureManager::staticCastToFetchedTexture(getImage(texture_index, wearable_index), TRUE);
if (imagep)
{
- const LLVOAvatarDictionary::TextureEntry *texture_dict = LLVOAvatarDictionary::getInstance()->getTexture((ETextureIndex)texture_index);
+ const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearanceDictionary::getInstance()->getTexture((ETextureIndex)texture_index);
const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex;
if (texture_dict->mIsLocalTexture)
{
- addLocalTextureStats((ETextureIndex)texture_index, imagep, texel_area_ratio, render_avatar, layer_baked[baked_index]);
+ addLocalTextureStats((ETextureIndex)texture_index, imagep, texel_area_ratio, render_avatar, mBakedTextureDatas[baked_index].mIsUsed);
}
}
}
@@ -4498,6 +4473,7 @@ void LLVOAvatar::updateTextures()
if (isIndexBakedTexture((ETextureIndex)texture_index)
&& imagep->getID() != IMG_DEFAULT_AVATAR
&& imagep->getID() != IMG_INVISIBLE
+ && !isUsingServerBakes()
&& !imagep->getTargetHost().isOk())
{
LL_WARNS_ONCE("Texture") << "LLVOAvatar::updateTextures No host for texture "
@@ -4518,7 +4494,7 @@ void LLVOAvatar::updateTextures()
void LLVOAvatar::addLocalTextureStats( ETextureIndex idx, LLViewerFetchedTexture* imagep,
- F32 texel_area_ratio, BOOL render_avatar, BOOL covered_by_baked, U32 index )
+ F32 texel_area_ratio, BOOL render_avatar, BOOL covered_by_baked)
{
// No local texture stats for non-self avatars
return;
@@ -4592,7 +4568,6 @@ void LLVOAvatar::addBakedTextureStats( LLViewerFetchedTexture* imagep, F32 pixel
//the texture pipeline will stop fetching this texture.
imagep->resetTextureStats();
- imagep->setCanUseHTTP(false) ; //turn off http fetching for baked textures.
imagep->setMaxVirtualSizeResetInterval(MAX_TEXTURE_VIRTURE_SIZE_RESET_INTERVAL);
imagep->resetMaxVirtualSizeResetCounter() ;
@@ -4601,7 +4576,7 @@ void LLVOAvatar::addBakedTextureStats( LLViewerFetchedTexture* imagep, F32 pixel
imagep->addTextureStats(pixel_area / texel_area_ratio);
imagep->setBoostLevel(boost_level);
- if(boost_level != LLViewerTexture::BOOST_AVATAR_BAKED_SELF)
+ if(boost_level != LLGLTexture::BOOST_AVATAR_BAKED_SELF)
{
imagep->setAdditionalDecodePriority(ADDITIONAL_PRI) ;
}
@@ -4634,6 +4609,30 @@ void LLVOAvatar::setTexEntry(const U8 index, const LLTextureEntry &te)
setTE(index, te);
}
+const std::string LLVOAvatar::getImageURL(const U8 te, const LLUUID &uuid)
+{
+ llassert(isIndexBakedTexture(ETextureIndex(te)));
+ std::string url = "";
+ if (isUsingServerBakes())
+ {
+ const std::string& appearance_service_url = LLAppearanceMgr::instance().getAppearanceServiceURL();
+ if (appearance_service_url.empty())
+ {
+ // Probably a server-side issue if we get here:
+ llwarns << "AgentAppearanceServiceURL not set - Baked texture requests will fail" << llendl;
+ return url;
+ }
+
+ const LLAvatarAppearanceDictionary::TextureEntry* texture_entry = LLAvatarAppearanceDictionary::getInstance()->getTexture((ETextureIndex)te);
+ if (texture_entry != NULL)
+ {
+ url = appearance_service_url + "texture/" + getID().asString() + "/" + texture_entry->mDefaultImageName + "/" + uuid.asString();
+ //llinfos << "baked texture url: " << url << llendl;
+ }
+ }
+ return url;
+}
+
//-----------------------------------------------------------------------------
// resolveHeight()
//-----------------------------------------------------------------------------
@@ -4703,8 +4702,6 @@ const LLUUID& LLVOAvatar::getStepSound() const
//-----------------------------------------------------------------------------
void LLVOAvatar::processAnimationStateChanges()
{
- LLMemType mt(LLMemType::MTYPE_AVATAR);
-
if ( isAnyAnimationSignaled(AGENT_WALK_ANIMS, NUM_AGENT_WALK_ANIMS) )
{
startMotion(ANIM_AGENT_WALK_ADJUST);
@@ -4795,8 +4792,6 @@ void LLVOAvatar::processAnimationStateChanges()
//-----------------------------------------------------------------------------
BOOL LLVOAvatar::processSingleAnimationStateChange( const LLUUID& anim_id, BOOL start )
{
- LLMemType mt(LLMemType::MTYPE_AVATAR);
-
BOOL result = FALSE;
if ( start ) // start animation
@@ -4931,8 +4926,6 @@ LLUUID LLVOAvatar::remapMotionID(const LLUUID& id)
//-----------------------------------------------------------------------------
BOOL LLVOAvatar::startMotion(const LLUUID& id, F32 time_offset)
{
- LLMemType mt(LLMemType::MTYPE_AVATAR);
-
lldebugs << "motion requested " << id.asString() << " " << gAnimLibrary.animationName(id) << llendl;
LLUUID remap_id = remapMotionID(id);
@@ -4981,48 +4974,6 @@ void LLVOAvatar::stopMotionFromSource(const LLUUID& source_id)
}
//-----------------------------------------------------------------------------
-// getVolumePos()
-//-----------------------------------------------------------------------------
-LLVector3 LLVOAvatar::getVolumePos(S32 joint_index, LLVector3& volume_offset)
-{
- if (joint_index > mNumCollisionVolumes)
- {
- return LLVector3::zero;
- }
-
- return mCollisionVolumes[joint_index].getVolumePos(volume_offset);
-}
-
-//-----------------------------------------------------------------------------
-// findCollisionVolume()
-//-----------------------------------------------------------------------------
-LLJoint* LLVOAvatar::findCollisionVolume(U32 volume_id)
-{
- if ((S32)volume_id > mNumCollisionVolumes)
- {
- return NULL;
- }
-
- return &mCollisionVolumes[volume_id];
-}
-
-//-----------------------------------------------------------------------------
-// findCollisionVolume()
-//-----------------------------------------------------------------------------
-S32 LLVOAvatar::getCollisionVolumeID(std::string &name)
-{
- for (S32 i = 0; i < mNumCollisionVolumes; i++)
- {
- if (mCollisionVolumes[i].getName() == name)
- {
- return i;
- }
- }
-
- return -1;
-}
-
-//-----------------------------------------------------------------------------
// addDebugText()
//-----------------------------------------------------------------------------
void LLVOAvatar::addDebugText(const std::string& text)
@@ -5045,7 +4996,20 @@ const LLUUID& LLVOAvatar::getID() const
// RN: avatar joints are multi-rooted to include screen-based attachments
LLJoint *LLVOAvatar::getJoint( const std::string &name )
{
- LLJoint* jointp = mRoot.findJoint(name);
+ joint_map_t::iterator iter = mJointMap.find(name);
+
+ LLJoint* jointp = NULL;
+
+ if (iter == mJointMap.end() || iter->second == NULL)
+ { //search for joint and cache found joint in lookup table
+ jointp = mRoot->findJoint(name);
+ mJointMap[name] = jointp;
+ }
+ else
+ { //return cached pointer
+ jointp = iter->second;
+ }
+
return jointp;
}
@@ -5054,10 +5018,12 @@ LLJoint *LLVOAvatar::getJoint( const std::string &name )
//-----------------------------------------------------------------------------
void LLVOAvatar::resetJointPositions( void )
{
- for(S32 i = 0; i < (S32)mNumJoints; ++i)
+ avatar_joint_list_t::iterator iter = mSkeleton.begin();
+ avatar_joint_list_t::iterator end = mSkeleton.end();
+ for (; iter != end; ++iter)
{
- mSkeleton[i].restoreOldXform();
- mSkeleton[i].setId( LLUUID::null );
+ (*iter)->restoreOldXform();
+ (*iter)->setId( LLUUID::null );
}
mHasPelvisOffset = false;
mPelvisFixup = mLastPelvisFixup;
@@ -5067,7 +5033,7 @@ void LLVOAvatar::resetJointPositions( void )
//-----------------------------------------------------------------------------
void LLVOAvatar::resetSpecificJointPosition( const std::string& name )
{
- LLJoint* pJoint = mRoot.findJoint( name );
+ LLJoint* pJoint = mRoot->findJoint( name );
if ( pJoint && pJoint->doesJointNeedToBeReset() )
{
@@ -5089,16 +5055,17 @@ void LLVOAvatar::resetSpecificJointPosition( const std::string& name )
//-----------------------------------------------------------------------------
void LLVOAvatar::resetJointPositionsToDefault( void )
{
-
//Subsequent joints are relative to pelvis
- for( S32 i = 0; i < (S32)mNumJoints; ++i )
+ avatar_joint_list_t::iterator iter = mSkeleton.begin();
+ avatar_joint_list_t::iterator end = mSkeleton.end();
+ for (; iter != end; ++iter)
{
- LLJoint* pJoint = (LLJoint*)&mSkeleton[i];
+ LLJoint* pJoint = (*iter);
if ( pJoint->doesJointNeedToBeReset() )
{
-
pJoint->setId( LLUUID::null );
//restore joints to default positions, however skip over the pelvis
+ // *TODO: How does this pointer check skip over pelvis?
if ( pJoint )
{
pJoint->restoreOldXform();
@@ -5197,23 +5164,6 @@ F32 LLVOAvatar::getPixelArea() const
}
-//-----------------------------------------------------------------------------
-// LLVOAvatar::getHeadMesh()
-//-----------------------------------------------------------------------------
-LLPolyMesh* LLVOAvatar::getHeadMesh()
-{
- return mMeshLOD[MESH_ID_HEAD]->mMeshParts[0]->getMesh();
-}
-
-
-//-----------------------------------------------------------------------------
-// LLVOAvatar::getUpperBodyMesh()
-//-----------------------------------------------------------------------------
-LLPolyMesh* LLVOAvatar::getUpperBodyMesh()
-{
- return mMeshLOD[MESH_ID_UPPER_BODY]->mMeshParts[0]->getMesh();
-}
-
//-----------------------------------------------------------------------------
// LLVOAvatar::getPosGlobalFromAgent()
@@ -5231,61 +5181,6 @@ LLVector3 LLVOAvatar::getPosAgentFromGlobal(const LLVector3d &position)
return gAgent.getPosAgentFromGlobal(position);
}
-//-----------------------------------------------------------------------------
-// allocateCharacterJoints()
-//-----------------------------------------------------------------------------
-BOOL LLVOAvatar::allocateCharacterJoints( U32 num )
-{
- deleteAndClearArray(mSkeleton);
- mNumJoints = 0;
-
- mSkeleton = new LLViewerJoint[num];
-
- for(S32 joint_num = 0; joint_num < (S32)num; joint_num++)
- {
- mSkeleton[joint_num].setJointNum(joint_num);
- }
-
- if (!mSkeleton)
- {
- return FALSE;
- }
-
- mNumJoints = num;
- return TRUE;
-}
-
-//-----------------------------------------------------------------------------
-// allocateCollisionVolumes()
-//-----------------------------------------------------------------------------
-BOOL LLVOAvatar::allocateCollisionVolumes( U32 num )
-{
- deleteAndClearArray(mCollisionVolumes);
- mNumCollisionVolumes = 0;
-
- mCollisionVolumes = new LLViewerJointCollisionVolume[num];
- if (!mCollisionVolumes)
- {
- return FALSE;
- }
-
- mNumCollisionVolumes = num;
- return TRUE;
-}
-
-
-//-----------------------------------------------------------------------------
-// getCharacterJoint()
-//-----------------------------------------------------------------------------
-LLJoint *LLVOAvatar::getCharacterJoint( U32 num )
-{
- if ((S32)num >= mNumJoints
- || (S32)num < 0)
- {
- return NULL;
- }
- return (LLJoint*)&mSkeleton[num];
-}
//-----------------------------------------------------------------------------
// requestStopMotion()
@@ -5297,215 +5192,24 @@ void LLVOAvatar::requestStopMotion( LLMotion* motion )
}
//-----------------------------------------------------------------------------
-// loadAvatar()
-//-----------------------------------------------------------------------------
-static LLFastTimer::DeclareTimer FTM_LOAD_AVATAR("Load Avatar");
-
-BOOL LLVOAvatar::loadAvatar()
-{
-// LLFastTimer t(FTM_LOAD_AVATAR);
-
- // avatar_skeleton.xml
- if( !buildSkeleton(sAvatarSkeletonInfo) )
- {
- llwarns << "avatar file: buildSkeleton() failed" << llendl;
- return FALSE;
- }
-
- // avatar_lad.xml : <skeleton>
- if( !loadSkeletonNode() )
- {
- llwarns << "avatar file: loadNodeSkeleton() failed" << llendl;
- return FALSE;
- }
-
- // avatar_lad.xml : <mesh>
- if( !loadMeshNodes() )
- {
- llwarns << "avatar file: loadNodeMesh() failed" << llendl;
- return FALSE;
- }
-
- // avatar_lad.xml : <global_color>
- if( sAvatarXmlInfo->mTexSkinColorInfo )
- {
- mTexSkinColor = new LLTexGlobalColor( this );
- if( !mTexSkinColor->setInfo( sAvatarXmlInfo->mTexSkinColorInfo ) )
- {
- llwarns << "avatar file: mTexSkinColor->setInfo() failed" << llendl;
- return FALSE;
- }
- }
- else
- {
- llwarns << "<global_color> name=\"skin_color\" not found" << llendl;
- return FALSE;
- }
- if( sAvatarXmlInfo->mTexHairColorInfo )
- {
- mTexHairColor = new LLTexGlobalColor( this );
- if( !mTexHairColor->setInfo( sAvatarXmlInfo->mTexHairColorInfo ) )
- {
- llwarns << "avatar file: mTexHairColor->setInfo() failed" << llendl;
- return FALSE;
- }
- }
- else
- {
- llwarns << "<global_color> name=\"hair_color\" not found" << llendl;
- return FALSE;
- }
- if( sAvatarXmlInfo->mTexEyeColorInfo )
- {
- mTexEyeColor = new LLTexGlobalColor( this );
- if( !mTexEyeColor->setInfo( sAvatarXmlInfo->mTexEyeColorInfo ) )
- {
- llwarns << "avatar file: mTexEyeColor->setInfo() failed" << llendl;
- return FALSE;
- }
- }
- else
- {
- llwarns << "<global_color> name=\"eye_color\" not found" << llendl;
- return FALSE;
- }
-
- // avatar_lad.xml : <layer_set>
- if (sAvatarXmlInfo->mLayerInfoList.empty())
- {
- llwarns << "avatar file: missing <layer_set> node" << llendl;
- return FALSE;
- }
-
- if (sAvatarXmlInfo->mMorphMaskInfoList.empty())
- {
- llwarns << "avatar file: missing <morph_masks> node" << llendl;
- return FALSE;
- }
-
- // avatar_lad.xml : <morph_masks>
- for (LLVOAvatarXmlInfo::morph_info_list_t::iterator iter = sAvatarXmlInfo->mMorphMaskInfoList.begin();
- iter != sAvatarXmlInfo->mMorphMaskInfoList.end();
- ++iter)
- {
- LLVOAvatarXmlInfo::LLVOAvatarMorphInfo *info = *iter;
-
- EBakedTextureIndex baked = LLVOAvatarDictionary::findBakedByRegionName(info->mRegion);
- if (baked != BAKED_NUM_INDICES)
- {
- LLPolyMorphTarget *morph_param;
- const std::string *name = &info->mName;
- morph_param = (LLPolyMorphTarget *)(getVisualParam(name->c_str()));
- if (morph_param)
- {
- BOOL invert = info->mInvert;
- addMaskedMorph(baked, morph_param, invert, info->mLayer);
- }
- }
-
- }
-
- loadLayersets();
-
- // avatar_lad.xml : <driver_parameters>
- for (LLVOAvatarXmlInfo::driver_info_list_t::iterator iter = sAvatarXmlInfo->mDriverInfoList.begin();
- iter != sAvatarXmlInfo->mDriverInfoList.end();
- ++iter)
- {
- LLDriverParamInfo *info = *iter;
- LLDriverParam* driver_param = new LLDriverParam( this );
- if (driver_param->setInfo(info))
- {
- addVisualParam( driver_param );
- LLVisualParam*(LLVOAvatar::*avatar_function)(S32)const = &LLVOAvatar::getVisualParam;
- if( !driver_param->linkDrivenParams(boost::bind(avatar_function,(LLVOAvatar*)this,_1 ), false))
- {
- llwarns << "could not link driven params for avatar " << this->getFullname() << " id: " << driver_param->getID() << llendl;
- continue;
- }
- }
- else
- {
- delete driver_param;
- llwarns << "avatar file: driver_param->parseData() failed" << llendl;
- return FALSE;
- }
- }
-
-
- return TRUE;
-}
-
-//-----------------------------------------------------------------------------
// loadSkeletonNode(): loads <skeleton> node from XML tree
//-----------------------------------------------------------------------------
+//virtual
BOOL LLVOAvatar::loadSkeletonNode ()
{
- mRoot.addChild( &mSkeleton[0] );
-
- for (std::vector<LLViewerJoint *>::iterator iter = mMeshLOD.begin();
- iter != mMeshLOD.end();
- ++iter)
- {
- LLViewerJoint *joint = (LLViewerJoint *) *iter;
- joint->mUpdateXform = FALSE;
- joint->setMeshesToChildren();
- }
-
- mRoot.addChild(mMeshLOD[MESH_ID_HEAD]);
- mRoot.addChild(mMeshLOD[MESH_ID_EYELASH]);
- mRoot.addChild(mMeshLOD[MESH_ID_UPPER_BODY]);
- mRoot.addChild(mMeshLOD[MESH_ID_LOWER_BODY]);
- mRoot.addChild(mMeshLOD[MESH_ID_SKIRT]);
- mRoot.addChild(mMeshLOD[MESH_ID_HEAD]);
-
- LLViewerJoint *skull = (LLViewerJoint*)mRoot.findJoint("mSkull");
- if (skull)
- {
- skull->addChild(mMeshLOD[MESH_ID_HAIR] );
- }
-
- LLViewerJoint *eyeL = (LLViewerJoint*)mRoot.findJoint("mEyeLeft");
- if (eyeL)
- {
- eyeL->addChild( mMeshLOD[MESH_ID_EYEBALL_LEFT] );
- }
-
- LLViewerJoint *eyeR = (LLViewerJoint*)mRoot.findJoint("mEyeRight");
- if (eyeR)
- {
- eyeR->addChild( mMeshLOD[MESH_ID_EYEBALL_RIGHT] );
- }
-
- // SKELETAL DISTORTIONS
+ if (!LLAvatarAppearance::loadSkeletonNode())
{
- LLVOAvatarXmlInfo::skeletal_distortion_info_list_t::iterator iter;
- for (iter = sAvatarXmlInfo->mSkeletalDistortionInfoList.begin();
- iter != sAvatarXmlInfo->mSkeletalDistortionInfoList.end();
- ++iter)
- {
- LLPolySkeletalDistortionInfo *info = *iter;
- LLPolySkeletalDistortion *param = new LLPolySkeletalDistortion(this);
- if (!param->setInfo(info))
- {
- delete param;
return FALSE;
}
- else
- {
- addVisualParam(param);
- }
- }
- }
// ATTACHMENTS
{
- LLVOAvatarXmlInfo::attachment_info_list_t::iterator iter;
+ LLAvatarXmlInfo::attachment_info_list_t::iterator iter;
for (iter = sAvatarXmlInfo->mAttachmentInfoList.begin();
iter != sAvatarXmlInfo->mAttachmentInfoList.end();
++iter)
{
- LLVOAvatarXmlInfo::LLVOAvatarAttachmentInfo *info = *iter;
+ LLAvatarXmlInfo::LLAvatarAttachmentInfo *info = *iter;
if (!isSelf() && info->mJointName == "mScreen")
{ //don't process screen joint for other avatars
continue;
@@ -5578,144 +5282,6 @@ BOOL LLVOAvatar::loadSkeletonNode ()
}
//-----------------------------------------------------------------------------
-// loadMeshNodes(): loads <mesh> nodes from XML tree
-//-----------------------------------------------------------------------------
-BOOL LLVOAvatar::loadMeshNodes()
-{
- for (LLVOAvatarXmlInfo::mesh_info_list_t::const_iterator meshinfo_iter = sAvatarXmlInfo->mMeshInfoList.begin();
- meshinfo_iter != sAvatarXmlInfo->mMeshInfoList.end();
- ++meshinfo_iter)
- {
- const LLVOAvatarXmlInfo::LLVOAvatarMeshInfo *info = *meshinfo_iter;
- const std::string &type = info->mType;
- S32 lod = info->mLOD;
-
- LLViewerJointMesh* mesh = NULL;
- U8 mesh_id = 0;
- BOOL found_mesh_id = FALSE;
-
- /* if (type == "hairMesh")
- switch(lod)
- case 0:
- mesh = &mHairMesh0; */
- for (LLVOAvatarDictionary::Meshes::const_iterator mesh_iter = LLVOAvatarDictionary::getInstance()->getMeshes().begin();
- mesh_iter != LLVOAvatarDictionary::getInstance()->getMeshes().end();
- ++mesh_iter)
- {
- const EMeshIndex mesh_index = mesh_iter->first;
- const LLVOAvatarDictionary::MeshEntry *mesh_dict = mesh_iter->second;
- if (type.compare(mesh_dict->mName) == 0)
- {
- mesh_id = mesh_index;
- found_mesh_id = TRUE;
- break;
- }
- }
-
- if (found_mesh_id)
- {
- if (lod < (S32)mMeshLOD[mesh_id]->mMeshParts.size())
- {
- mesh = mMeshLOD[mesh_id]->mMeshParts[lod];
- }
- else
- {
- llwarns << "Avatar file: <mesh> has invalid lod setting " << lod << llendl;
- return FALSE;
- }
- }
- else
- {
- llwarns << "Ignoring unrecognized mesh type: " << type << llendl;
- return FALSE;
- }
-
- // llinfos << "Parsing mesh data for " << type << "..." << llendl;
-
- // If this isn't set to white (1.0), avatars will *ALWAYS* be darker than their surroundings.
- // Do not touch!!!
- mesh->setColor( 1.0f, 1.0f, 1.0f, 1.0f );
-
- LLPolyMesh *poly_mesh = NULL;
-
- if (!info->mReferenceMeshName.empty())
- {
- polymesh_map_t::const_iterator polymesh_iter = mMeshes.find(info->mReferenceMeshName);
- if (polymesh_iter != mMeshes.end())
- {
- poly_mesh = LLPolyMesh::getMesh(info->mMeshFileName, polymesh_iter->second);
- poly_mesh->setAvatar(this);
- }
- else
- {
- // This should never happen
- LL_WARNS("Avatar") << "Could not find avatar mesh: " << info->mReferenceMeshName << LL_ENDL;
- }
- }
- else
- {
- poly_mesh = LLPolyMesh::getMesh(info->mMeshFileName);
- poly_mesh->setAvatar(this);
- }
-
- if( !poly_mesh )
- {
- llwarns << "Failed to load mesh of type " << type << llendl;
- return FALSE;
- }
-
- // Multimap insert
- mMeshes.insert(std::make_pair(info->mMeshFileName, poly_mesh));
-
- mesh->setMesh( poly_mesh );
- mesh->setLOD( info->mMinPixelArea );
-
- for (LLVOAvatarXmlInfo::LLVOAvatarMeshInfo::morph_info_list_t::const_iterator xmlinfo_iter = info->mPolyMorphTargetInfoList.begin();
- xmlinfo_iter != info->mPolyMorphTargetInfoList.end();
- ++xmlinfo_iter)
- {
- const LLVOAvatarXmlInfo::LLVOAvatarMeshInfo::morph_info_pair_t *info_pair = &(*xmlinfo_iter);
- LLPolyMorphTarget *param = new LLPolyMorphTarget(mesh->getMesh());
- if (!param->setInfo(info_pair->first))
- {
- delete param;
- return FALSE;
- }
- else
- {
- if (info_pair->second)
- {
- addSharedVisualParam(param);
- }
- else
- {
- addVisualParam(param);
- }
- }
- }
- }
-
- return TRUE;
-}
-
-//-----------------------------------------------------------------------------
-// loadLayerSets()
-//-----------------------------------------------------------------------------
-BOOL LLVOAvatar::loadLayersets()
-{
- BOOL success = TRUE;
- for (LLVOAvatarXmlInfo::layer_info_list_t::const_iterator layerset_iter = sAvatarXmlInfo->mLayerInfoList.begin();
- layerset_iter != sAvatarXmlInfo->mLayerInfoList.end();
- ++layerset_iter)
- {
- // Construct a layerset for each one specified in avatar_lad.xml and initialize it as such.
- LLTexLayerSetInfo *layerset_info = *layerset_iter;
- layerset_info->createVisualParams(this);
- }
- return success;
-}
-
-//-----------------------------------------------------------------------------
// updateVisualParams()
//-----------------------------------------------------------------------------
void LLVOAvatar::updateVisualParams()
@@ -5728,7 +5294,7 @@ void LLVOAvatar::updateVisualParams()
{
computeBodySize();
mLastSkeletonSerialNum = mSkeletonSerialNum;
- mRoot.updateWorldMatrixChildren();
+ mRoot->updateWorldMatrixChildren();
}
dirtyMesh();
@@ -5748,8 +5314,6 @@ BOOL LLVOAvatar::isActive() const
//-----------------------------------------------------------------------------
void LLVOAvatar::setPixelAreaAndAngle(LLAgent &agent)
{
- LLMemType mt(LLMemType::MTYPE_AVATAR);
-
if (mDrawable.isNull())
{
return;
@@ -5795,7 +5359,6 @@ BOOL LLVOAvatar::updateJointLODs()
F32 avatar_num_factor = clamp_rescale((F32)sNumVisibleAvatars, 8, 25, 1.f, avatar_num_min_factor);
F32 area_scale = 0.16f;
- {
if (isSelf())
{
if(gAgentCamera.cameraCustomizeAvatar() || gAgentCamera.cameraMouselook())
@@ -5818,14 +5381,18 @@ BOOL LLVOAvatar::updateJointLODs()
}
// now select meshes to render based on adjusted pixel area
- BOOL res = mRoot.updateLOD(mAdjustedPixelArea, TRUE);
+ LLViewerJoint* root = dynamic_cast<LLViewerJoint*>(mRoot);
+ BOOL res = FALSE;
+ if (root)
+ {
+ res = root->updateLOD(mAdjustedPixelArea, TRUE);
+ }
if (res)
{
sNumLODChangesThisFrame++;
dirtyMesh(2);
return TRUE;
}
- }
return FALSE;
}
@@ -5908,6 +5475,15 @@ void LLVOAvatar::dirtyMesh(S32 priority)
{
mDirtyMesh = llmax(mDirtyMesh, priority);
}
+
+//-----------------------------------------------------------------------------
+// getViewerJoint()
+//-----------------------------------------------------------------------------
+LLViewerJoint* LLVOAvatar::getViewerJoint(S32 idx)
+{
+ return dynamic_cast<LLViewerJoint*>(mMeshLOD[idx]);
+}
+
//-----------------------------------------------------------------------------
// hideSkirt()
//-----------------------------------------------------------------------------
@@ -5945,7 +5521,15 @@ void LLVOAvatar::addChild(LLViewerObject *childp)
LLViewerObject::addChild(childp);
if (childp->mDrawable)
{
- attachObject(childp);
+ if (!attachObject(childp))
+ {
+ llwarns << "addChild() failed for "
+ << childp->getID()
+ << " item " << childp->getAttachmentItemID()
+ << llendl;
+ // MAINT-3312 backout
+ // mPendingAttachment.push_back(childp);
+ }
}
else
{
@@ -5978,8 +5562,27 @@ LLViewerJointAttachment* LLVOAvatar::getTargetAttachmentPoint(LLViewerObject* vi
if (!attachment)
{
- llwarns << "Object attachment point invalid: " << attachmentID << llendl;
- attachment = get_if_there(mAttachmentPoints, 1, (LLViewerJointAttachment*)NULL); // Arbitrary using 1 (chest)
+ llwarns << "Object attachment point invalid: " << attachmentID
+ << " trying to use 1 (chest)"
+ << llendl;
+
+ attachment = get_if_there(mAttachmentPoints, 1, (LLViewerJointAttachment*)NULL); // Arbitrary using 1 (chest)
+ if (attachment)
+ {
+ llwarns << "Object attachment point invalid: " << attachmentID
+ << " on object " << viewer_object->getID()
+ << " attachment item " << viewer_object->getAttachmentItemID()
+ << " falling back to 1 (chest)"
+ << llendl;
+ }
+ else
+ {
+ llwarns << "Object attachment point invalid: " << attachmentID
+ << " on object " << viewer_object->getID()
+ << " attachment item " << viewer_object->getAttachmentItemID()
+ << "Unable to use fallback attachment point 1 (chest)"
+ << llendl;
+ }
}
return attachment;
@@ -5997,6 +5600,8 @@ const LLViewerJointAttachment *LLVOAvatar::attachObject(LLViewerObject *viewer_o
return 0;
}
+ mVisualComplexityStale = TRUE;
+
if (viewer_object->isSelected())
{
LLSelectMgr::getInstance()->updateSelectionCenter();
@@ -6048,13 +5653,22 @@ void LLVOAvatar::lazyAttach()
for (U32 i = 0; i < mPendingAttachment.size(); i++)
{
- if (mPendingAttachment[i]->mDrawable)
+ LLPointer<LLViewerObject> cur_attachment = mPendingAttachment[i];
+ if (cur_attachment->mDrawable)
{
- attachObject(mPendingAttachment[i]);
+ if (!attachObject(cur_attachment))
+ { // Drop it
+ llwarns << "attachObject() failed for "
+ << cur_attachment->getID()
+ << " item " << cur_attachment->getAttachmentItemID()
+ << llendl;
+ // MAINT-3312 backout
+ //still_pending.push_back(cur_attachment);
+ }
}
else
{
- still_pending.push_back(mPendingAttachment[i]);
+ still_pending.push_back(cur_attachment);
}
}
@@ -6114,14 +5728,9 @@ void LLVOAvatar::cleanupAttachedMesh( LLViewerObject* pVO )
if ( pVObj )
{
const LLMeshSkinInfo* pSkinData = gMeshRepo.getSkinInfo( pVObj->getVolume()->getParams().getSculptID(), pVObj );
- if ( pSkinData )
- {
- const int jointCnt = pSkinData->mJointNames.size();
- bool fullRig = ( jointCnt>=20 ) ? true : false;
- if ( fullRig )
- {
- const int bindCnt = pSkinData->mAlternateBindMatrix.size();
- if ( bindCnt > 0 )
+ if (pSkinData
+ && pSkinData->mJointNames.size() > 20 // full rig
+ && pSkinData->mAlternateBindMatrix.size() > 0)
{
LLVOAvatar::resetJointPositionsToDefault();
//Need to handle the repositioning of the cam, updating rig data etc during outfit editing
@@ -6136,8 +5745,6 @@ void LLVOAvatar::cleanupAttachedMesh( LLViewerObject* pVO )
}
}
}
- }
-}
//-----------------------------------------------------------------------------
// detachObject()
//-----------------------------------------------------------------------------
@@ -6151,6 +5758,7 @@ BOOL LLVOAvatar::detachObject(LLViewerObject *viewer_object)
if (attachment->isObjectAttached(viewer_object))
{
+ mVisualComplexityStale = TRUE;
cleanupAttachedMesh( viewer_object );
attachment->removeObject(viewer_object);
lldebugs << "Detaching object " << viewer_object->mID << " from " << attachment->getName() << llendl;
@@ -6221,9 +5829,9 @@ void LLVOAvatar::sitOnObject(LLViewerObject *sit_object)
// Notice that removing sitDown() from here causes avatars sitting on
// objects to be not rendered for new arrivals. See EXT-6835 and EXT-1655.
sitDown(TRUE);
- mRoot.getXform()->setParent(&sit_object->mDrawable->mXform); // LLVOAvatar::sitOnObject
- mRoot.setPosition(getPosition());
- mRoot.updateWorldMatrixChildren();
+ mRoot->getXform()->setParent(&sit_object->mDrawable->mXform); // LLVOAvatar::sitOnObject
+ mRoot->setPosition(getPosition());
+ mRoot->updateWorldMatrixChildren();
stopMotion(ANIM_AGENT_BODY_NOISE);
@@ -6269,10 +5877,10 @@ void LLVOAvatar::getOffObject()
sitDown(FALSE);
- mRoot.getXform()->setParent(NULL); // LLVOAvatar::getOffObject
- mRoot.setPosition(cur_position_world);
- mRoot.setRotation(cur_rotation_world);
- mRoot.getXform()->update();
+ mRoot->getXform()->setParent(NULL); // LLVOAvatar::getOffObject
+ mRoot->setPosition(cur_position_world);
+ mRoot->setRotation(cur_rotation_world);
+ mRoot->getXform()->update();
startMotion(ANIM_AGENT_BODY_NOISE);
@@ -6286,11 +5894,7 @@ void LLVOAvatar::getOffObject()
at_axis.mV[VZ] = 0.f;
at_axis.normalize();
gAgent.resetAxes(at_axis);
-
- //reset orientation
-// mRoot.setRotation(avWorldRot);
gAgentCamera.setThirdPersonHeadOffset(LLVector3(0.f, 0.f, 1.f));
-
gAgentCamera.setSitCamera(LLUUID::null);
}
}
@@ -6324,27 +5928,77 @@ S32 LLVOAvatar::getAttachmentCount()
return count;
}
-LLColor4 LLVOAvatar::getGlobalColor( const std::string& color_name ) const
+BOOL LLVOAvatar::isWearingWearableType(LLWearableType::EType type) const
{
- if (color_name=="skin_color" && mTexSkinColor)
+ if (mIsDummy) return TRUE;
+
+ if (isSelf())
{
- return mTexSkinColor->getColor();
+ return LLAvatarAppearance::isWearingWearableType(type);
}
- else if(color_name=="hair_color" && mTexHairColor)
+
+ switch(type)
{
- return mTexHairColor->getColor();
+ case LLWearableType::WT_SHAPE:
+ case LLWearableType::WT_SKIN:
+ case LLWearableType::WT_HAIR:
+ case LLWearableType::WT_EYES:
+ return TRUE; // everyone has all bodyparts
+ default:
+ break; // Do nothing
}
- if(color_name=="eye_color" && mTexEyeColor)
+
+ /* switch(type)
+ case LLWearableType::WT_SHIRT:
+ indicator_te = TEX_UPPER_SHIRT; */
+ for (LLAvatarAppearanceDictionary::Textures::const_iterator tex_iter = LLAvatarAppearanceDictionary::getInstance()->getTextures().begin();
+ tex_iter != LLAvatarAppearanceDictionary::getInstance()->getTextures().end();
+ ++tex_iter)
+ {
+ const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = tex_iter->second;
+ if (texture_dict->mWearableType == type)
{
- return mTexEyeColor->getColor();
+ // Thus, you must check to see if the corresponding baked texture is defined.
+ // NOTE: this is a poor substitute if you actually want to know about individual pieces of clothing
+ // this works for detecting a skirt (most important), but is ineffective at any piece of clothing that
+ // gets baked into a texture that always exists (upper or lower).
+ if (texture_dict->mIsUsedByBakedTexture)
+ {
+ const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex;
+ return isTextureDefined(LLAvatarAppearanceDictionary::getInstance()->getBakedTexture(baked_index)->mTextureIndex);
}
- else
+ return FALSE;
+ }
+ }
+ return FALSE;
+}
+
+
+
+LLViewerObject * LLVOAvatar::findAttachmentByID( const LLUUID & target_id ) const
+{
+ for(attachment_map_t::const_iterator attachment_points_iter = mAttachmentPoints.begin();
+ attachment_points_iter != gAgentAvatarp->mAttachmentPoints.end();
+ ++attachment_points_iter)
{
-// return LLColor4( .5f, .5f, .5f, .5f );
- return LLColor4( 0.f, 1.f, 1.f, 1.f ); // good debugging color
+ LLViewerJointAttachment* attachment = attachment_points_iter->second;
+ for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
+ attachment_iter != attachment->mAttachedObjects.end();
+ ++attachment_iter)
+ {
+ LLViewerObject *attached_object = (*attachment_iter);
+ if (attached_object &&
+ attached_object->getID() == target_id)
+ {
+ return attached_object;
+ }
+ }
}
+
+ return NULL;
}
+
// virtual
void LLVOAvatar::invalidateComposite( LLTexLayerSet* layerset, BOOL upload_result )
{
@@ -6354,6 +6008,7 @@ void LLVOAvatar::invalidateAll()
{
}
+// virtual
void LLVOAvatar::onGlobalColorChanged(const LLTexGlobalColor* global_color, BOOL upload_bake )
{
if (global_color == mTexSkinColor)
@@ -6372,9 +6027,15 @@ void LLVOAvatar::onGlobalColorChanged(const LLTexGlobalColor* global_color, BOOL
if (!isTextureDefined(mBakedTextureDatas[BAKED_HAIR].mTextureIndex))
{
LLColor4 color = mTexHairColor->getColor();
- for (U32 i = 0; i < mBakedTextureDatas[BAKED_HAIR].mMeshes.size(); i++)
+ avatar_joint_mesh_list_t::iterator iter = mBakedTextureDatas[BAKED_HAIR].mJointMeshes.begin();
+ avatar_joint_mesh_list_t::iterator end = mBakedTextureDatas[BAKED_HAIR].mJointMeshes.end();
+ for (; iter != end; ++iter)
+ {
+ LLAvatarJointMesh* mesh = (*iter);
+ if (mesh)
{
- mBakedTextureDatas[BAKED_HAIR].mMeshes[i]->setColor( color.mV[VX], color.mV[VY], color.mV[VZ], color.mV[VW] );
+ mesh->setColor( color );
+ }
}
}
}
@@ -6393,10 +6054,10 @@ BOOL LLVOAvatar::isVisible() const
}
// Determine if we have enough avatar data to render
-BOOL LLVOAvatar::getIsCloud()
+BOOL LLVOAvatar::getIsCloud() const
{
// Do we have a shape?
- if (visualParamWeightsAreDefault())
+ if ((const_cast<LLVOAvatar*>(this))->visualParamWeightsAreDefault())
{
return TRUE;
}
@@ -6415,11 +6076,181 @@ BOOL LLVOAvatar::getIsCloud()
return FALSE;
}
+void LLVOAvatar::updateRezzedStatusTimers()
+{
+ // State machine for rezzed status. Statuses are -1 on startup, 0
+ // = cloud, 1 = gray, 2 = textured, 3 = textured_and_downloaded.
+ // Purpose is to collect time data for each it takes avatar to reach
+ // various loading landmarks: gray, textured (partial), textured fully.
+
+ S32 rez_status = getRezzedStatus();
+ if (rez_status != mLastRezzedStatus)
+ {
+ LL_DEBUGS("Avatar") << avString() << "rez state change: " << mLastRezzedStatus << " -> " << rez_status << LL_ENDL;
+
+ if (mLastRezzedStatus == -1 && rez_status != -1)
+ {
+ // First time initialization, start all timers.
+ for (S32 i = 1; i < 4; i++)
+ {
+ startPhase("load_" + LLVOAvatar::rezStatusToString(i));
+ startPhase("first_load_" + LLVOAvatar::rezStatusToString(i));
+ }
+ }
+ if (rez_status < mLastRezzedStatus)
+ {
+ // load level has decreased. start phase timers for higher load levels.
+ for (S32 i = rez_status+1; i <= mLastRezzedStatus; i++)
+ {
+ startPhase("load_" + LLVOAvatar::rezStatusToString(i));
+ }
+ }
+ else if (rez_status > mLastRezzedStatus)
+ {
+ // load level has increased. stop phase timers for lower and equal load levels.
+ for (S32 i = llmax(mLastRezzedStatus+1,1); i <= rez_status; i++)
+ {
+ stopPhase("load_" + LLVOAvatar::rezStatusToString(i));
+ stopPhase("first_load_" + LLVOAvatar::rezStatusToString(i), false);
+ }
+ if (rez_status == 3)
+ {
+ // "fully loaded", mark any pending appearance change complete.
+ selfStopPhase("update_appearance_from_cof");
+ selfStopPhase("wear_inventory_category", false);
+ selfStopPhase("process_initial_wearables_update", false);
+ }
+ }
+
+ mLastRezzedStatus = rez_status;
+ }
+}
+
+void LLVOAvatar::clearPhases()
+{
+ getPhases().clearPhases();
+}
+
+void LLVOAvatar::startPhase(const std::string& phase_name)
+{
+ F32 elapsed;
+ bool completed;
+ if (getPhases().getPhaseValues(phase_name, elapsed, completed))
+ {
+ if (!completed)
+ {
+ LL_DEBUGS("Avatar") << avString() << "no-op, start when started already for " << phase_name << llendl;
+ return;
+ }
+ }
+ LL_DEBUGS("Avatar") << "started phase " << phase_name << llendl;
+ getPhases().startPhase(phase_name);
+}
+
+void LLVOAvatar::stopPhase(const std::string& phase_name, bool err_check)
+ {
+ F32 elapsed;
+ bool completed;
+ if (getPhases().getPhaseValues(phase_name, elapsed, completed))
+ {
+ if (!completed)
+ {
+ getPhases().stopPhase(phase_name);
+ completed = true;
+ logMetricsTimerRecord(phase_name, elapsed, completed);
+ LL_DEBUGS("Avatar") << avString() << "stopped phase " << phase_name << " elapsed " << elapsed << llendl;
+ }
+ else
+ {
+ if (err_check)
+ {
+ LL_DEBUGS("Avatar") << "no-op, stop when stopped already for " << phase_name << llendl;
+ }
+ }
+ }
+ else
+ {
+ if (err_check)
+ {
+ LL_DEBUGS("Avatar") << "no-op, stop when not started for " << phase_name << llendl;
+ }
+ }
+}
+
+void LLVOAvatar::logPendingPhases()
+{
+ if (!isAgentAvatarValid())
+ {
+ return;
+ }
+
+ for (LLViewerStats::phase_map_t::iterator it = getPhases().begin();
+ it != getPhases().end();
+ ++it)
+ {
+ const std::string& phase_name = it->first;
+ F32 elapsed;
+ bool completed;
+ if (getPhases().getPhaseValues(phase_name, elapsed, completed))
+ {
+ if (!completed)
+ {
+ logMetricsTimerRecord(phase_name, elapsed, completed);
+ }
+ }
+ }
+ }
+
+//static
+void LLVOAvatar::logPendingPhasesAllAvatars()
+ {
+ for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
+ iter != LLCharacter::sInstances.end(); ++iter)
+ {
+ LLVOAvatar* inst = (LLVOAvatar*) *iter;
+ if( inst->isDead() )
+ {
+ continue;
+ }
+ inst->logPendingPhases();
+ }
+ }
+
+void LLVOAvatar::logMetricsTimerRecord(const std::string& phase_name, F32 elapsed, bool completed)
+ {
+ if (!isAgentAvatarValid())
+ {
+ return;
+ }
+
+ LLSD record;
+ record["timer_name"] = phase_name;
+ record["avatar_id"] = getID();
+ record["elapsed"] = elapsed;
+ record["completed"] = completed;
+ U32 grid_x(0), grid_y(0);
+ if (getRegion())
+ {
+ record["central_bake_version"] = LLSD::Integer(getRegion()->getCentralBakeVersion());
+ grid_from_region_handle(getRegion()->getHandle(), &grid_x, &grid_y);
+ }
+ record["grid_x"] = LLSD::Integer(grid_x);
+ record["grid_y"] = LLSD::Integer(grid_y);
+ record["is_using_server_bakes"] = ((bool) isUsingServerBakes());
+ record["is_self"] = isSelf();
+
+ if (isAgentAvatarValid())
+ {
+ gAgentAvatarp->addMetricsTimerRecord(record);
+ }
+}
+
// call periodically to keep isFullyLoaded up to date.
// returns true if the value has changed.
BOOL LLVOAvatar::updateIsFullyLoaded()
{
const BOOL loading = getIsCloud();
+ updateRezzedStatusTimers();
updateRuthTimer(loading);
return processFullyLoadedChange(loading);
}
@@ -6434,27 +6265,19 @@ void LLVOAvatar::updateRuthTimer(bool loading)
if (mPreviousFullyLoaded)
{
mRuthTimer.reset();
- if (gSavedSettings.getBOOL("DebugAvatarRezTime"))
- {
- llinfos << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32() << "sec ] Avatar '" << getFullname() << "' became cloud." << llendl;
- LLSD args;
- args["EXISTENCE"] = llformat("%d",(U32)mDebugExistenceTimer.getElapsedTimeF32());
- args["TIME"] = llformat("%d",(U32)mRuthDebugTimer.getElapsedTimeF32());
- args["NAME"] = getFullname();
- LLNotificationsUtil::add("AvatarRezCloudNotification",args);
- }
- mRuthDebugTimer.reset();
+ debugAvatarRezTime("AvatarRezCloudNotification","became cloud");
}
const F32 LOADING_TIMEOUT__SECONDS = 120.f;
if (mRuthTimer.getElapsedTimeF32() > LOADING_TIMEOUT__SECONDS)
{
- llinfos << "Ruth Timer timeout: Missing texture data for '" << getFullname() << "' "
+ LL_DEBUGS("Avatar") << avString()
+ << "Ruth Timer timeout: Missing texture data for '" << getFullname() << "' "
<< "( Params loaded : " << !visualParamWeightsAreDefault() << " ) "
<< "( Lower : " << isTextureDefined(TEX_LOWER_BAKED) << " ) "
<< "( Upper : " << isTextureDefined(TEX_UPPER_BAKED) << " ) "
<< "( Head : " << isTextureDefined(TEX_HEAD_BAKED) << " )."
- << llendl;
+ << LL_ENDL;
LLAvatarPropertiesProcessor::getInstance()->sendAvatarTexturesRequest(getID());
mRuthTimer.reset();
@@ -6471,20 +6294,13 @@ BOOL LLVOAvatar::processFullyLoadedChange(bool loading)
mFullyLoaded = (mFullyLoadedTimer.getElapsedTimeF32() > PAUSE);
- if (gSavedSettings.getBOOL("DebugAvatarRezTime"))
- {
if (!mPreviousFullyLoaded && !loading && mFullyLoaded)
{
- llinfos << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32() << "sec ] Avatar '" << getFullname() << "' resolved in " << (U32)mRuthDebugTimer.getElapsedTimeF32() << " seconds." << llendl;
- LLSD args;
- args["EXISTENCE"] = llformat("%d",(U32)mDebugExistenceTimer.getElapsedTimeF32());
- args["TIME"] = llformat("%d",(U32)mRuthDebugTimer.getElapsedTimeF32());
- args["NAME"] = getFullname();
- LLNotificationsUtil::add("AvatarRezNotification",args);
- }
+ debugAvatarRezTime("AvatarRezNotification","fully loaded");
}
// did our loading state "change" from last call?
+ // runway - why are we updating every 30 calls even if nothing has changed?
const S32 UPDATE_RATE = 30;
BOOL changed =
((mFullyLoaded != mPreviousFullyLoaded) || // if the value is different from the previous call
@@ -6522,31 +6338,56 @@ LLMotion* LLVOAvatar::findMotion(const LLUUID& id) const
return mMotionController.findMotion(id);
}
+// This is a semi-deprecated debugging tool - meshes will not show as
+// colorized if using deferred rendering.
+void LLVOAvatar::debugColorizeSubMeshes(U32 i, const LLColor4& color)
+{
+ if (gSavedSettings.getBOOL("DebugAvatarCompositeBaked"))
+ {
+ avatar_joint_mesh_list_t::iterator iter = mBakedTextureDatas[i].mJointMeshes.begin();
+ avatar_joint_mesh_list_t::iterator end = mBakedTextureDatas[i].mJointMeshes.end();
+ for (; iter != end; ++iter)
+ {
+ LLAvatarJointMesh* mesh = (*iter);
+ if (mesh)
+ {
+ {
+ mesh->setColor(color);
+ }
+ }
+ }
+ }
+}
+
//-----------------------------------------------------------------------------
// updateMeshTextures()
// Uses the current TE values to set the meshes' and layersets' textures.
//-----------------------------------------------------------------------------
+// virtual
void LLVOAvatar::updateMeshTextures()
{
- // llinfos << "updateMeshTextures" << llendl;
+ static S32 update_counter = 0;
+ mBakedTextureDebugText.clear();
+
// if user has never specified a texture, assign the default
for (U32 i=0; i < getNumTEs(); i++)
{
const LLViewerTexture* te_image = getImage(i, 0);
if(!te_image || te_image->getID().isNull() || (te_image->getID() == IMG_DEFAULT))
{
- setImage(i, LLViewerTextureManager::getFetchedTexture(i == TEX_HAIR ? IMG_DEFAULT : IMG_DEFAULT_AVATAR), 0); // IMG_DEFAULT_AVATAR = a special texture that's never rendered.
+ // IMG_DEFAULT_AVATAR = a special texture that's never rendered.
+ const LLUUID& image_id = (i == TEX_HAIR ? IMG_DEFAULT : IMG_DEFAULT_AVATAR);
+ setImage(i, LLViewerTextureManager::getFetchedTexture(image_id), 0);
}
}
- const BOOL self_customizing = isSelf() && gAgentCamera.cameraCustomizeAvatar(); // During face edit mode, we don't use baked textures
const BOOL other_culled = !isSelf() && mCulled;
LLLoadedCallbackEntry::source_callback_list_t* src_callback_list = NULL ;
BOOL paused = FALSE;
if(!isSelf())
{
src_callback_list = &mCallbackTextureList ;
- paused = mLoadedCallbacksPaused ;
+ paused = !isVisible();
}
std::vector<BOOL> is_layer_baked;
@@ -6555,71 +6396,97 @@ void LLVOAvatar::updateMeshTextures()
std::vector<BOOL> use_lkg_baked_layer; // lkg = "last known good"
use_lkg_baked_layer.resize(mBakedTextureDatas.size(), false);
+ mBakedTextureDebugText += llformat("%06d\n",update_counter++);
+ mBakedTextureDebugText += "indx layerset linvld ltda ilb ulkg ltid\n";
for (U32 i=0; i < mBakedTextureDatas.size(); i++)
{
is_layer_baked[i] = isTextureDefined(mBakedTextureDatas[i].mTextureIndex);
-
+ LLViewerTexLayerSet* layerset = NULL;
+ bool layerset_invalid = false;
if (!other_culled)
{
// When an avatar is changing clothes and not in Appearance mode,
- // use the last-known good baked texture until it finish the first
+ // use the last-known good baked texture until it finishes the first
// render of the new layerset.
- const BOOL layerset_invalid = mBakedTextureDatas[i].mTexLayerSet
- && ( !mBakedTextureDatas[i].mTexLayerSet->getComposite()->isInitialized()
- || !mBakedTextureDatas[i].mTexLayerSet->isLocalTextureDataAvailable() );
+ layerset = getTexLayerSet(i);
+ layerset_invalid = layerset && ( !layerset->getViewerComposite()->isInitialized()
+ || !layerset->isLocalTextureDataAvailable() );
use_lkg_baked_layer[i] = (!is_layer_baked[i]
- && (mBakedTextureDatas[i].mLastTextureIndex != IMG_DEFAULT_AVATAR)
+ && (mBakedTextureDatas[i].mLastTextureID != IMG_DEFAULT_AVATAR)
&& layerset_invalid);
if (use_lkg_baked_layer[i])
{
- mBakedTextureDatas[i].mTexLayerSet->setUpdatesEnabled(TRUE);
+ layerset->setUpdatesEnabled(TRUE);
}
}
else
{
use_lkg_baked_layer[i] = (!is_layer_baked[i]
- && mBakedTextureDatas[i].mLastTextureIndex != IMG_DEFAULT_AVATAR);
- if (mBakedTextureDatas[i].mTexLayerSet)
- {
- mBakedTextureDatas[i].mTexLayerSet->destroyComposite();
- }
+ && mBakedTextureDatas[i].mLastTextureID != IMG_DEFAULT_AVATAR);
}
+ std::string last_id_string;
+ if (mBakedTextureDatas[i].mLastTextureID == IMG_DEFAULT_AVATAR)
+ last_id_string = "A";
+ else if (mBakedTextureDatas[i].mLastTextureID == IMG_DEFAULT)
+ last_id_string = "D";
+ else if (mBakedTextureDatas[i].mLastTextureID == IMG_INVISIBLE)
+ last_id_string = "I";
+ else
+ last_id_string = "*";
+ bool is_ltda = layerset
+ && layerset->getViewerComposite()->isInitialized()
+ && layerset->isLocalTextureDataAvailable();
+ mBakedTextureDebugText += llformat("%4d %4s %4d %4d %4d %4d %4s\n",
+ i,
+ (layerset?"*":"0"),
+ layerset_invalid,
+ is_ltda,
+ is_layer_baked[i],
+ use_lkg_baked_layer[i],
+ last_id_string.c_str());
}
- // Turn on alpha masking correctly for yourself and other avatars on 1.23+
- mSupportsAlphaLayers = isSelf() || is_layer_baked[BAKED_HAIR];
+ for (U32 i=0; i < mBakedTextureDatas.size(); i++)
+ {
+ debugColorizeSubMeshes(i, LLColor4::white);
- // Baked textures should be requested from the sim this avatar is on. JC
- const LLHost target_host = getObjectHost();
- if (!target_host.isOk())
+ LLViewerTexLayerSet* layerset = getTexLayerSet(i);
+ if (use_lkg_baked_layer[i] && !isUsingLocalAppearance() )
{
- llwarns << "updateMeshTextures: invalid host for object: " << getID() << llendl;
- }
+ LLViewerFetchedTexture* baked_img = LLViewerTextureManager::getFetchedTexture(mBakedTextureDatas[i].mLastTextureID);
+ mBakedTextureDatas[i].mIsUsed = TRUE;
+
+ debugColorizeSubMeshes(i,LLColor4::red);
- for (U32 i=0; i < mBakedTextureDatas.size(); i++)
+ avatar_joint_mesh_list_t::iterator iter = mBakedTextureDatas[i].mJointMeshes.begin();
+ avatar_joint_mesh_list_t::iterator end = mBakedTextureDatas[i].mJointMeshes.end();
+ for (; iter != end; ++iter)
{
- if (use_lkg_baked_layer[i] && !self_customizing )
+ LLAvatarJointMesh* mesh = (*iter);
+ if (mesh)
{
- LLViewerFetchedTexture* baked_img = LLViewerTextureManager::getFetchedTextureFromHost( mBakedTextureDatas[i].mLastTextureIndex, target_host );
- mBakedTextureDatas[i].mIsUsed = TRUE;
- for (U32 k=0; k < mBakedTextureDatas[i].mMeshes.size(); k++)
- {
- mBakedTextureDatas[i].mMeshes[k]->setTexture( baked_img );
+ mesh->setTexture( baked_img );
+ }
}
}
- else if (!self_customizing && is_layer_baked[i])
+ else if (!isUsingLocalAppearance() && is_layer_baked[i])
{
- LLViewerFetchedTexture* baked_img = LLViewerTextureManager::staticCastToFetchedTexture(getImage( mBakedTextureDatas[i].mTextureIndex, 0 ), TRUE) ;
- if( baked_img->getID() == mBakedTextureDatas[i].mLastTextureIndex )
+ LLViewerFetchedTexture* baked_img =
+ LLViewerTextureManager::staticCastToFetchedTexture(
+ getImage( mBakedTextureDatas[i].mTextureIndex, 0 ), TRUE) ;
+ if( baked_img->getID() == mBakedTextureDatas[i].mLastTextureID )
{
- // Even though the file may not be finished loading, we'll consider it loaded and use it (rather than doing compositing).
+ // Even though the file may not be finished loading,
+ // we'll consider it loaded and use it (rather than
+ // doing compositing).
useBakedTexture( baked_img->getID() );
}
else
{
mBakedTextureDatas[i].mIsLoaded = FALSE;
- if ( (baked_img->getID() != IMG_INVISIBLE) && ((i == BAKED_HEAD) || (i == BAKED_UPPER) || (i == BAKED_LOWER)) )
+ if ( (baked_img->getID() != IMG_INVISIBLE) &&
+ ((i == BAKED_HEAD) || (i == BAKED_UPPER) || (i == BAKED_LOWER)) )
{
baked_img->setLoadedCallback(onBakedTextureMasksLoaded, MORPH_MASK_REQUESTED_DISCARD, TRUE, TRUE, new LLTextureMaskData( mID ),
src_callback_list, paused);
@@ -6628,40 +6495,59 @@ void LLVOAvatar::updateMeshTextures()
src_callback_list, paused );
}
}
- else if (mBakedTextureDatas[i].mTexLayerSet
- && !other_culled)
+ else if (layerset && isUsingLocalAppearance())
{
- mBakedTextureDatas[i].mTexLayerSet->createComposite();
- mBakedTextureDatas[i].mTexLayerSet->setUpdatesEnabled( TRUE );
+ debugColorizeSubMeshes(i,LLColor4::yellow );
+
+ layerset->createComposite();
+ layerset->setUpdatesEnabled( TRUE );
mBakedTextureDatas[i].mIsUsed = FALSE;
- for (U32 k=0; k < mBakedTextureDatas[i].mMeshes.size(); k++)
+
+ avatar_joint_mesh_list_t::iterator iter = mBakedTextureDatas[i].mJointMeshes.begin();
+ avatar_joint_mesh_list_t::iterator end = mBakedTextureDatas[i].mJointMeshes.end();
+ for (; iter != end; ++iter)
{
- mBakedTextureDatas[i].mMeshes[k]->setLayerSet( mBakedTextureDatas[i].mTexLayerSet );
+ LLAvatarJointMesh* mesh = (*iter);
+ if (mesh)
+ {
+ mesh->setLayerSet( layerset );
+ }
}
}
+ else
+ {
+ debugColorizeSubMeshes(i,LLColor4::blue);
+ }
}
// set texture and color of hair manually if we are not using a baked image.
// This can happen while loading hair for yourself, or for clients that did not
// bake a hair texture. Still needed for yourself after 1.22 is depricated.
- if (!is_layer_baked[BAKED_HAIR] || self_customizing)
+ if (!is_layer_baked[BAKED_HAIR] || isEditingAppearance())
{
const LLColor4 color = mTexHairColor ? mTexHairColor->getColor() : LLColor4(1,1,1,1);
LLViewerTexture* hair_img = getImage( TEX_HAIR, 0 );
- for (U32 i = 0; i < mBakedTextureDatas[BAKED_HAIR].mMeshes.size(); i++)
+ avatar_joint_mesh_list_t::iterator iter = mBakedTextureDatas[BAKED_HAIR].mJointMeshes.begin();
+ avatar_joint_mesh_list_t::iterator end = mBakedTextureDatas[BAKED_HAIR].mJointMeshes.end();
+ for (; iter != end; ++iter)
+ {
+ LLAvatarJointMesh* mesh = (*iter);
+ if (mesh)
{
- mBakedTextureDatas[BAKED_HAIR].mMeshes[i]->setColor( color.mV[VX], color.mV[VY], color.mV[VZ], color.mV[VW] );
- mBakedTextureDatas[BAKED_HAIR].mMeshes[i]->setTexture( hair_img );
+ mesh->setColor( color );
+ mesh->setTexture( hair_img );
+ }
}
}
- for (LLVOAvatarDictionary::BakedTextures::const_iterator baked_iter = LLVOAvatarDictionary::getInstance()->getBakedTextures().begin();
- baked_iter != LLVOAvatarDictionary::getInstance()->getBakedTextures().end();
+ for (LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter =
+ LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().begin();
+ baked_iter != LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().end();
++baked_iter)
{
const EBakedTextureIndex baked_index = baked_iter->first;
- const LLVOAvatarDictionary::BakedEntry *baked_dict = baked_iter->second;
+ const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = baked_iter->second;
for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin();
local_tex_iter != baked_dict->mLocalTextures.end();
@@ -6689,7 +6575,7 @@ void LLVOAvatar::setLocalTexture( ETextureIndex type, LLViewerTexture* in_tex, B
}
//virtual
-void LLVOAvatar::setBakedReady(LLVOAvatarDefines::ETextureIndex type, BOOL baked_version_exists, U32 index)
+void LLVOAvatar::setBakedReady(LLAvatarAppearanceDefines::ETextureIndex type, BOOL baked_version_exists, U32 index)
{
// invalid for anyone but self
llassert(0);
@@ -6724,18 +6610,31 @@ void LLVOAvatar::clearChat()
mChats.clear();
}
-// adds a morph mask to the appropriate baked texture structure
-void LLVOAvatar::addMaskedMorph(EBakedTextureIndex index, LLPolyMorphTarget* morph_target, BOOL invert, std::string layer)
+
+void LLVOAvatar::applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_components, LLAvatarAppearanceDefines::EBakedTextureIndex index)
{
- if (index < BAKED_NUM_INDICES)
+ if (index >= BAKED_NUM_INDICES)
{
- LLMaskedMorph *morph = new LLMaskedMorph(morph_target, invert, layer);
- mBakedTextureDatas[index].mMaskedMorphs.push_front(morph);
+ llwarns << "invalid baked texture index passed to applyMorphMask" << llendl;
+ return;
+ }
+
+ for (morph_list_t::const_iterator iter = mBakedTextureDatas[index].mMaskedMorphs.begin();
+ iter != mBakedTextureDatas[index].mMaskedMorphs.end(); ++iter)
+{
+ const LLMaskedMorph* maskedMorph = (*iter);
+ LLPolyMorphTarget* morph_target = dynamic_cast<LLPolyMorphTarget*>(maskedMorph->mMorphTarget);
+ if (morph_target)
+ {
+ morph_target->applyMask(tex_data, width, height, num_components, maskedMorph->mInvert);
+}
}
}
+
+
// returns TRUE if morph masks are present and not valid for a given baked texture, FALSE otherwise
-BOOL LLVOAvatar::morphMaskNeedsUpdate(LLVOAvatarDefines::EBakedTextureIndex index)
+BOOL LLVOAvatar::morphMaskNeedsUpdate(LLAvatarAppearanceDefines::EBakedTextureIndex index)
{
if (index >= BAKED_NUM_INDICES)
{
@@ -6746,7 +6645,7 @@ BOOL LLVOAvatar::morphMaskNeedsUpdate(LLVOAvatarDefines::EBakedTextureIndex inde
{
if (isSelf())
{
- LLTexLayerSet *layer_set = mBakedTextureDatas[index].mTexLayerSet;
+ LLViewerTexLayerSet *layer_set = getTexLayerSet(index);
if (layer_set)
{
return !layer_set->isMorphValid();
@@ -6761,23 +6660,6 @@ BOOL LLVOAvatar::morphMaskNeedsUpdate(LLVOAvatarDefines::EBakedTextureIndex inde
return FALSE;
}
-void LLVOAvatar::applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_components, LLVOAvatarDefines::EBakedTextureIndex index)
-{
- if (index >= BAKED_NUM_INDICES)
- {
- llwarns << "invalid baked texture index passed to applyMorphMask" << llendl;
- return;
- }
-
- for (morph_list_t::const_iterator iter = mBakedTextureDatas[index].mMaskedMorphs.begin();
- iter != mBakedTextureDatas[index].mMaskedMorphs.end(); ++iter)
- {
- const LLMaskedMorph* maskedMorph = (*iter);
- maskedMorph->mMorphTarget->applyMask(tex_data, width, height, num_components, maskedMorph->mInvert);
- }
-}
-
-
//-----------------------------------------------------------------------------
// releaseComponentTextures()
// release any component texture UUIDs for which we have a baked texture
@@ -6800,7 +6682,7 @@ void LLVOAvatar::releaseComponentTextures()
for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++)
{
- const LLVOAvatarDictionary::BakedEntry * bakedDicEntry = LLVOAvatarDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)baked_index);
+ const LLAvatarAppearanceDictionary::BakedEntry * bakedDicEntry = LLAvatarAppearanceDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)baked_index);
// skip if this is a skirt and av is not wearing one, or if we don't have a baked texture UUID
if (!isTextureDefined(bakedDicEntry->mTextureIndex)
&& ( (baked_index != BAKED_SKIRT) || isWearingWearableType(LLWearableType::WT_SKIRT) ))
@@ -6816,187 +6698,39 @@ void LLVOAvatar::releaseComponentTextures()
}
}
-//static
-BOOL LLVOAvatar::teToColorParams( ETextureIndex te, U32 *param_name )
-{
- switch( te )
- {
- case TEX_UPPER_SHIRT:
- param_name[0] = 803; //"shirt_red";
- param_name[1] = 804; //"shirt_green";
- param_name[2] = 805; //"shirt_blue";
- break;
-
- case TEX_LOWER_PANTS:
- param_name[0] = 806; //"pants_red";
- param_name[1] = 807; //"pants_green";
- param_name[2] = 808; //"pants_blue";
- break;
-
- case TEX_LOWER_SHOES:
- param_name[0] = 812; //"shoes_red";
- param_name[1] = 813; //"shoes_green";
- param_name[2] = 817; //"shoes_blue";
- break;
-
- case TEX_LOWER_SOCKS:
- param_name[0] = 818; //"socks_red";
- param_name[1] = 819; //"socks_green";
- param_name[2] = 820; //"socks_blue";
- break;
-
- case TEX_UPPER_JACKET:
- case TEX_LOWER_JACKET:
- param_name[0] = 834; //"jacket_red";
- param_name[1] = 835; //"jacket_green";
- param_name[2] = 836; //"jacket_blue";
- break;
-
- case TEX_UPPER_GLOVES:
- param_name[0] = 827; //"gloves_red";
- param_name[1] = 829; //"gloves_green";
- param_name[2] = 830; //"gloves_blue";
- break;
-
- case TEX_UPPER_UNDERSHIRT:
- param_name[0] = 821; //"undershirt_red";
- param_name[1] = 822; //"undershirt_green";
- param_name[2] = 823; //"undershirt_blue";
- break;
-
- case TEX_LOWER_UNDERPANTS:
- param_name[0] = 824; //"underpants_red";
- param_name[1] = 825; //"underpants_green";
- param_name[2] = 826; //"underpants_blue";
- break;
-
- case TEX_SKIRT:
- param_name[0] = 921; //"skirt_red";
- param_name[1] = 922; //"skirt_green";
- param_name[2] = 923; //"skirt_blue";
- break;
-
- case TEX_HEAD_TATTOO:
- case TEX_LOWER_TATTOO:
- case TEX_UPPER_TATTOO:
- param_name[0] = 1071; //"tattoo_red";
- param_name[1] = 1072; //"tattoo_green";
- param_name[2] = 1073; //"tattoo_blue";
- break;
-
- default:
- llassert(0);
- return FALSE;
- }
-
- return TRUE;
-}
-
-void LLVOAvatar::setClothesColor( ETextureIndex te, const LLColor4& new_color, BOOL upload_bake )
-{
- U32 param_name[3];
- if( teToColorParams( te, param_name ) )
- {
- setVisualParamWeight( param_name[0], new_color.mV[VX], upload_bake );
- setVisualParamWeight( param_name[1], new_color.mV[VY], upload_bake );
- setVisualParamWeight( param_name[2], new_color.mV[VZ], upload_bake );
- }
-}
-
-LLColor4 LLVOAvatar::getClothesColor( ETextureIndex te )
-{
- LLColor4 color;
- U32 param_name[3];
- if( teToColorParams( te, param_name ) )
- {
- color.mV[VX] = getVisualParamWeight( param_name[0] );
- color.mV[VY] = getVisualParamWeight( param_name[1] );
- color.mV[VZ] = getVisualParamWeight( param_name[2] );
- }
- return color;
-}
-
-// static
-LLColor4 LLVOAvatar::getDummyColor()
-{
- return DUMMY_COLOR;
-}
-
void LLVOAvatar::dumpAvatarTEs( const std::string& context ) const
{
- llinfos << (isSelf() ? "Self: " : "Other: ") << context << llendl;
- for (LLVOAvatarDictionary::Textures::const_iterator iter = LLVOAvatarDictionary::getInstance()->getTextures().begin();
- iter != LLVOAvatarDictionary::getInstance()->getTextures().end();
+ LL_DEBUGS("Avatar") << avString() << (isSelf() ? "Self: " : "Other: ") << context << LL_ENDL;
+ for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getTextures().begin();
+ iter != LLAvatarAppearanceDictionary::getInstance()->getTextures().end();
++iter)
{
- const LLVOAvatarDictionary::TextureEntry *texture_dict = iter->second;
+ const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = iter->second;
// TODO: MULTI-WEARABLE: handle multiple textures for self
const LLViewerTexture* te_image = getImage(iter->first,0);
if( !te_image )
{
- llinfos << " " << texture_dict->mName << ": null ptr" << llendl;
+ LL_DEBUGS("Avatar") << avString() << " " << texture_dict->mName << ": null ptr" << LL_ENDL;
}
else if( te_image->getID().isNull() )
{
- llinfos << " " << texture_dict->mName << ": null UUID" << llendl;
+ LL_DEBUGS("Avatar") << avString() << " " << texture_dict->mName << ": null UUID" << LL_ENDL;
}
else if( te_image->getID() == IMG_DEFAULT )
{
- llinfos << " " << texture_dict->mName << ": IMG_DEFAULT" << llendl;
+ LL_DEBUGS("Avatar") << avString() << " " << texture_dict->mName << ": IMG_DEFAULT" << LL_ENDL;
}
else if( te_image->getID() == IMG_DEFAULT_AVATAR )
{
- llinfos << " " << texture_dict->mName << ": IMG_DEFAULT_AVATAR" << llendl;
+ LL_DEBUGS("Avatar") << avString() << " " << texture_dict->mName << ": IMG_DEFAULT_AVATAR" << LL_ENDL;
}
else
{
- llinfos << " " << texture_dict->mName << ": " << te_image->getID() << llendl;
+ LL_DEBUGS("Avatar") << avString() << " " << texture_dict->mName << ": " << te_image->getID() << LL_ENDL;
}
}
}
-// Unlike most wearable functions, this works for both self and other.
-BOOL LLVOAvatar::isWearingWearableType(LLWearableType::EType type) const
-{
- if (mIsDummy) return TRUE;
-
- switch(type)
- {
- case LLWearableType::WT_SHAPE:
- case LLWearableType::WT_SKIN:
- case LLWearableType::WT_HAIR:
- case LLWearableType::WT_EYES:
- return TRUE; // everyone has all bodyparts
- default:
- break; // Do nothing
- }
-
- /* switch(type)
- case LLWearableType::WT_SHIRT:
- indicator_te = TEX_UPPER_SHIRT; */
- for (LLVOAvatarDictionary::Textures::const_iterator tex_iter = LLVOAvatarDictionary::getInstance()->getTextures().begin();
- tex_iter != LLVOAvatarDictionary::getInstance()->getTextures().end();
- ++tex_iter)
- {
- const LLVOAvatarDictionary::TextureEntry *texture_dict = tex_iter->second;
- if (texture_dict->mWearableType == type)
- {
- // If you're checking another avatar's clothing, you don't have component textures.
- // Thus, you must check to see if the corresponding baked texture is defined.
- // NOTE: this is a poor substitute if you actually want to know about individual pieces of clothing
- // this works for detecting a skirt (most important), but is ineffective at any piece of clothing that
- // gets baked into a texture that always exists (upper or lower).
- if (texture_dict->mIsUsedByBakedTexture)
- {
- const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex;
- return isTextureDefined(LLVOAvatarDictionary::getInstance()->getBakedTexture(baked_index)->mTextureIndex);
- }
- return FALSE;
- }
- }
- return FALSE;
-}
-
//-----------------------------------------------------------------------------
// clampAttachmentPositions()
//-----------------------------------------------------------------------------
@@ -7072,15 +6806,12 @@ LLBBox LLVOAvatar::getHUDBBox() const
return bbox;
}
-void LLVOAvatar::rebuildHUD()
-{
-}
-
//-----------------------------------------------------------------------------
// onFirstTEMessageReceived()
//-----------------------------------------------------------------------------
void LLVOAvatar::onFirstTEMessageReceived()
{
+ LL_DEBUGS("Avatar") << avString() << LL_ENDL;
if( !mFirstTEMessageReceived )
{
mFirstTEMessageReceived = TRUE;
@@ -7090,7 +6821,7 @@ void LLVOAvatar::onFirstTEMessageReceived()
if(!isSelf())
{
src_callback_list = &mCallbackTextureList ;
- paused = mLoadedCallbacksPaused ;
+ paused = !isVisible();
}
for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
@@ -7102,13 +6833,14 @@ void LLVOAvatar::onFirstTEMessageReceived()
if (layer_baked)
{
LLViewerFetchedTexture* image = LLViewerTextureManager::staticCastToFetchedTexture(getImage( mBakedTextureDatas[i].mTextureIndex, 0 ), TRUE) ;
- mBakedTextureDatas[i].mLastTextureIndex = image->getID();
+ mBakedTextureDatas[i].mLastTextureID = image->getID();
// If we have more than one texture for the other baked layers, we'll want to call this for them too.
if ( (image->getID() != IMG_INVISIBLE) && ((i == BAKED_HEAD) || (i == BAKED_UPPER) || (i == BAKED_LOWER)) )
{
image->setLoadedCallback( onBakedTextureMasksLoaded, MORPH_MASK_REQUESTED_DISCARD, TRUE, TRUE, new LLTextureMaskData( mID ),
src_callback_list, paused);
}
+ LL_DEBUGS("Avatar") << avString() << "layer_baked, setting onInitialBakedTextureLoaded as callback" << LL_ENDL;
image->setLoadedCallback( onInitialBakedTextureLoaded, MAX_DISCARD_LEVEL, FALSE, FALSE, new LLUUID( mID ),
src_callback_list, paused );
}
@@ -7153,78 +6885,106 @@ bool LLVOAvatar::visualParamWeightsAreDefault()
return rtn;
}
-
-//-----------------------------------------------------------------------------
-// processAvatarAppearance()
-//-----------------------------------------------------------------------------
-void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )
-{
- if (gSavedSettings.getBOOL("BlockAvatarAppearanceMessages"))
- {
- llwarns << "Blocking AvatarAppearance message" << llendl;
- return;
+void dump_visual_param(apr_file_t* file, LLVisualParam* viewer_param, F32 value)
+{
+ std::string type_string = "unknown";
+ if (dynamic_cast<LLTexLayerParamAlpha*>(viewer_param))
+ type_string = "param_alpha";
+ if (dynamic_cast<LLTexLayerParamColor*>(viewer_param))
+ type_string = "param_color";
+ if (dynamic_cast<LLDriverParam*>(viewer_param))
+ type_string = "param_driver";
+ if (dynamic_cast<LLPolyMorphTarget*>(viewer_param))
+ type_string = "param_morph";
+ if (dynamic_cast<LLPolySkeletalDistortion*>(viewer_param))
+ type_string = "param_skeleton";
+ S32 wtype = -1;
+ LLViewerVisualParam *vparam = dynamic_cast<LLViewerVisualParam*>(viewer_param);
+ if (vparam)
+ {
+ wtype = vparam->getWearableType();
+ }
+ S32 u8_value = F32_to_U8(value,viewer_param->getMinWeight(),viewer_param->getMaxWeight());
+ apr_file_printf(file, "\t\t<param id=\"%d\" name=\"%s\" value=\"%.3f\" u8=\"%d\" type=\"%s\" wearable=\"%s\"/>\n",
+ viewer_param->getID(), viewer_param->getName().c_str(), value, u8_value, type_string.c_str(),
+ LLWearableType::getTypeName(LLWearableType::EType(wtype)).c_str()
+// param_location_name(vparam->getParamLocation()).c_str()
+ );
}
- LLMemType mt(LLMemType::MTYPE_AVATAR);
-
-// llinfos << "processAvatarAppearance start " << mID << llendl;
- BOOL is_first_appearance_message = !mFirstAppearanceMessageReceived;
-
- mFirstAppearanceMessageReceived = TRUE;
- if( isSelf() )
+void LLVOAvatar::dumpAppearanceMsgParams( const std::string& dump_prefix,
+ const LLAppearanceMessageContents& contents)
{
- llwarns << "Received AvatarAppearance for self" << llendl;
- if( mFirstTEMessageReceived )
+ std::string outfilename = get_sequential_numbered_file_name(dump_prefix,".xml");
+ const std::vector<F32>& params_for_dump = contents.mParamWeights;
+ const LLTEContents& tec = contents.mTEContents;
+
+ LLAPRFile outfile;
+ std::string fullpath = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,outfilename);
+ outfile.open(fullpath, LL_APR_WB );
+ apr_file_t* file = outfile.getFileHandle();
+ if (!file)
{
-// llinfos << "processAvatarAppearance end " << mID << llendl;
return;
}
+ else
+ {
+ LL_DEBUGS("Avatar") << "dumping appearance message to " << fullpath << llendl;
}
- ESex old_sex = getSex();
+ apr_file_printf(file, "<header>\n");
+ apr_file_printf(file, "\t\t<cof_version %i />\n", contents.mCOFVersion);
+ apr_file_printf(file, "\t\t<appearance_version %i />\n", contents.mAppearanceVersion);
+ apr_file_printf(file, "</header>\n");
-// llinfos << "LLVOAvatar::processAvatarAppearance()" << llendl;
-// dumpAvatarTEs( "PRE processAvatarAppearance()" );
- unpackTEMessage(mesgsys, _PREHASH_ObjectData);
-// dumpAvatarTEs( "POST processAvatarAppearance()" );
-
- // prevent the overwriting of valid baked textures with invalid baked textures
- for (U8 baked_index = 0; baked_index < mBakedTextureDatas.size(); baked_index++)
+ apr_file_printf(file, "\n<params>\n");
+ LLVisualParam* param = getFirstVisualParam();
+ for (S32 i = 0; i < params_for_dump.size(); i++)
{
- if (!isTextureDefined(mBakedTextureDatas[baked_index].mTextureIndex)
- && mBakedTextureDatas[baked_index].mLastTextureIndex != IMG_DEFAULT
- && baked_index != BAKED_SKIRT)
+ while( param && (param->getGroup() != VISUAL_PARAM_GROUP_TWEAKABLE) ) // should not be any of group VISUAL_PARAM_GROUP_TWEAKABLE_NO_TRANSMIT
{
- setTEImage(mBakedTextureDatas[baked_index].mTextureIndex,
- LLViewerTextureManager::getFetchedTexture(mBakedTextureDatas[baked_index].mLastTextureIndex, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE));
+ param = getNextVisualParam();
}
+ LLViewerVisualParam* viewer_param = (LLViewerVisualParam*)param;
+ F32 value = params_for_dump[i];
+ dump_visual_param(file, viewer_param, value);
+ param = getNextVisualParam();
}
+ apr_file_printf(file, "</params>\n");
-
- if( !is_first_appearance_message )
+ apr_file_printf(file, "\n<textures>\n");
+ for (U32 i = 0; i < tec.face_count; i++)
{
- onFirstTEMessageReceived();
+ std::string uuid_str;
+ ((LLUUID*)tec.image_data)[i].toString(uuid_str);
+ apr_file_printf( file, "\t\t<texture te=\"%i\" uuid=\"%s\"/>\n", i, uuid_str.c_str());
+ }
+ apr_file_printf(file, "</textures>\n");
}
- setCompositeUpdatesEnabled( FALSE );
- mMeshTexturesDirty = TRUE;
- gPipeline.markGLRebuild(this);
+void LLVOAvatar::parseAppearanceMessage(LLMessageSystem* mesgsys, LLAppearanceMessageContents& contents)
+{
+ parseTEMessage(mesgsys, _PREHASH_ObjectData, -1, contents.mTEContents);
- // ! BACKWARDS COMPATIBILITY !
- // Non-self avatars will no longer have component textures
- if (!isSelf())
+ // Parse the AppearanceData field, if any.
+ if (mesgsys->has(_PREHASH_AppearanceData))
{
- releaseComponentTextures();
+ U8 av_u8;
+ mesgsys->getU8Fast(_PREHASH_AppearanceData, _PREHASH_AppearanceVersion, av_u8, 0);
+ contents.mAppearanceVersion = av_u8;
+ LL_DEBUGS("Avatar") << "appversion set by AppearanceData field: " << contents.mAppearanceVersion << llendl;
+ mesgsys->getS32Fast(_PREHASH_AppearanceData, _PREHASH_CofVersion, contents.mCOFVersion, 0);
+ // For future use:
+ //mesgsys->getU32Fast(_PREHASH_AppearanceData, _PREHASH_Flags, appearance_flags, 0);
}
- // parse visual params
+ // Parse visual params, if any.
S32 num_blocks = mesgsys->getNumberOfBlocksFast(_PREHASH_VisualParam);
bool drop_visual_params_debug = gSavedSettings.getBOOL("BlockSomeAvatarAppearanceVisualParams") && (ll_rand(2) == 0); // pretend that ~12% of AvatarAppearance messages arrived without a VisualParam block, for testing
if( num_blocks > 1 && !drop_visual_params_debug)
{
- BOOL params_changed = FALSE;
- BOOL interp_params = FALSE;
+ LL_DEBUGS("Avatar") << avString() << " handle visual params, num_blocks " << num_blocks << LL_ENDL;
LLVisualParam* param = getFirstVisualParam();
llassert(param); // if this ever fires, we should do the same as when num_blocks<=1
@@ -7250,10 +7010,204 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )
U8 value;
mesgsys->getU8Fast(_PREHASH_VisualParam, _PREHASH_ParamValue, value, i);
F32 newWeight = U8_to_F32(value, param->getMinWeight(), param->getMaxWeight());
+ contents.mParamWeights.push_back(newWeight);
+ contents.mParams.push_back(param);
+
+ param = getNextVisualParam();
+ }
+ }
+
+ const S32 expected_tweakable_count = getVisualParamCountInGroup(VISUAL_PARAM_GROUP_TWEAKABLE); // don't worry about VISUAL_PARAM_GROUP_TWEAKABLE_NO_TRANSMIT
+ if (num_blocks != expected_tweakable_count)
+ {
+ LL_DEBUGS("Avatar") << "Number of params in AvatarAppearance msg (" << num_blocks << ") does not match number of tweakable params in avatar xml file (" << expected_tweakable_count << "). Processing what we can. object: " << getID() << llendl;
+ }
+ }
+ else
+ {
+ if (drop_visual_params_debug)
+ {
+ llinfos << "Debug-faked lack of parameters on AvatarAppearance for object: " << getID() << llendl;
+ }
+ else
+ {
+ LL_DEBUGS("Avatar") << "AvatarAppearance msg received without any parameters, object: " << getID() << llendl;
+ }
+ }
+
+ LLVisualParam* appearance_version_param = getVisualParam(11000);
+ if (appearance_version_param)
+ {
+ std::vector<LLVisualParam*>::iterator it = std::find(contents.mParams.begin(), contents.mParams.end(),appearance_version_param);
+ if (it != contents.mParams.end())
+ {
+ S32 index = it - contents.mParams.begin();
+ contents.mParamAppearanceVersion = llround(contents.mParamWeights[index]);
+ LL_DEBUGS("Avatar") << "appversion req by appearance_version param: " << contents.mParamAppearanceVersion << llendl;
+ }
+ }
+}
+
+bool resolve_appearance_version(const LLAppearanceMessageContents& contents, S32& appearance_version)
+{
+ appearance_version = -1;
+
+ if ((contents.mAppearanceVersion) >= 0 &&
+ (contents.mParamAppearanceVersion >= 0) &&
+ (contents.mAppearanceVersion != contents.mParamAppearanceVersion))
+ {
+ llwarns << "inconsistent appearance_version settings - field: " <<
+ contents.mAppearanceVersion << ", param: " << contents.mParamAppearanceVersion << llendl;
+ return false;
+ }
+ if (contents.mParamAppearanceVersion >= 0) // use visual param if available.
+ {
+ appearance_version = contents.mParamAppearanceVersion;
+ }
+ if (contents.mAppearanceVersion >= 0)
+ {
+ appearance_version = contents.mAppearanceVersion;
+ }
+ if (appearance_version < 0) // still not set, go with 0.
+ {
+ appearance_version = 0;
+ }
+ LL_DEBUGS("Avatar") << "appearance version info - field " << contents.mAppearanceVersion
+ << " param: " << contents.mParamAppearanceVersion
+ << " final: " << appearance_version << llendl;
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+// processAvatarAppearance()
+//-----------------------------------------------------------------------------
+void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )
+{
+ LL_DEBUGS("Avatar") << "starts" << llendl;
+
+ bool enable_verbose_dumps = gSavedSettings.getBOOL("DebugAvatarAppearanceMessage");
+ std::string dump_prefix = getFullname() + "_" + (isSelf()?"s":"o") + "_";
+ if (gSavedSettings.getBOOL("BlockAvatarAppearanceMessages"))
+ {
+ llwarns << "Blocking AvatarAppearance message" << llendl;
+ return;
+ }
+
+ ESex old_sex = getSex();
+
+ LLAppearanceMessageContents contents;
+ parseAppearanceMessage(mesgsys, contents);
+ if (enable_verbose_dumps)
+ {
+ dumpAppearanceMsgParams(dump_prefix + "appearance_msg", contents);
+ }
+
+ S32 appearance_version;
+ if (!resolve_appearance_version(contents, appearance_version))
+ {
+ llwarns << "bad appearance version info, discarding" << llendl;
+ return;
+ }
+ S32 this_update_cof_version = contents.mCOFVersion;
+ S32 last_update_request_cof_version = mLastUpdateRequestCOFVersion;
+
+ // Only now that we have result of appearance_version can we decide whether to bail out.
+ if( isSelf() )
+ {
+ LL_DEBUGS("Avatar") << "this_update_cof_version " << this_update_cof_version
+ << " last_update_request_cof_version " << last_update_request_cof_version
+ << " my_cof_version " << LLAppearanceMgr::instance().getCOFVersion() << llendl;
+
+ if (getRegion() && (getRegion()->getCentralBakeVersion()==0))
+ {
+ llwarns << avString() << "Received AvatarAppearance message for self in non-server-bake region" << llendl;
+ }
+ if( mFirstTEMessageReceived && (appearance_version == 0))
+ {
+ return;
+ }
+ }
+ else
+ {
+ LL_DEBUGS("Avatar") << "appearance message received" << llendl;
+ }
+
+ // Check for stale update.
+ if (isSelf()
+ && (appearance_version>0)
+ && (this_update_cof_version < last_update_request_cof_version))
+ {
+ llwarns << "Stale appearance update, wanted version " << last_update_request_cof_version
+ << ", got " << this_update_cof_version << llendl;
+ return;
+ }
+
+ if (isSelf() && isEditingAppearance())
+ {
+ LL_DEBUGS("Avatar") << "ignoring appearance message while in appearance edit" << llendl;
+ return;
+ }
+
+ S32 num_params = contents.mParamWeights.size();
+ if (num_params <= 1)
+ {
+ // In this case, we have no reliable basis for knowing
+ // appearance version, which may cause us to look for baked
+ // textures in the wrong place and flag them as missing
+ // assets.
+ LL_DEBUGS("Avatar") << "ignoring appearance message due to lack of params" << llendl;
+ return;
+ }
+
+ mLastUpdateReceivedCOFVersion = this_update_cof_version;
+
+ setIsUsingServerBakes(appearance_version > 0);
+
+ applyParsedTEMessage(contents.mTEContents);
+
+ // prevent the overwriting of valid baked textures with invalid baked textures
+ for (U8 baked_index = 0; baked_index < mBakedTextureDatas.size(); baked_index++)
+ {
+ if (!isTextureDefined(mBakedTextureDatas[baked_index].mTextureIndex)
+ && mBakedTextureDatas[baked_index].mLastTextureID != IMG_DEFAULT
+ && baked_index != BAKED_SKIRT)
+ {
+ setTEImage(mBakedTextureDatas[baked_index].mTextureIndex,
+ LLViewerTextureManager::getFetchedTexture(mBakedTextureDatas[baked_index].mLastTextureID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE));
+ }
+ }
+
+ // runway - was
+ // if (!is_first_appearance_message )
+ // which means it would be called on second appearance message - probably wrong.
+ BOOL is_first_appearance_message = !mFirstAppearanceMessageReceived;
+ mFirstAppearanceMessageReceived = TRUE;
+
+ LL_DEBUGS("Avatar") << avString() << "processAvatarAppearance start " << mID
+ << " first? " << is_first_appearance_message << " self? " << isSelf() << LL_ENDL;
+
+ if (is_first_appearance_message )
+ {
+ onFirstTEMessageReceived();
+ }
+
+ setCompositeUpdatesEnabled( FALSE );
+ gPipeline.markGLRebuild(this);
+
+ // Apply visual params
+ if( num_params > 1)
+ {
+ LL_DEBUGS("Avatar") << avString() << " handle visual params, num_params " << num_params << LL_ENDL;
+ BOOL params_changed = FALSE;
+ BOOL interp_params = FALSE;
+
+ for( S32 i = 0; i < num_params; i++ )
+ {
+ LLVisualParam* param = contents.mParams[i];
+ F32 newWeight = contents.mParamWeights[i];
if (is_first_appearance_message || (param->getWeight() != newWeight))
{
- //llinfos << "Received update for param " << param->getDisplayName() << " at value " << newWeight << llendl;
params_changed = TRUE;
if(is_first_appearance_message)
{
@@ -7265,14 +7219,11 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )
param->setAnimationTarget(newWeight, FALSE);
}
}
- param = getNextVisualParam();
- }
}
-
const S32 expected_tweakable_count = getVisualParamCountInGroup(VISUAL_PARAM_GROUP_TWEAKABLE); // don't worry about VISUAL_PARAM_GROUP_TWEAKABLE_NO_TRANSMIT
- if (num_blocks != expected_tweakable_count)
+ if (num_params != expected_tweakable_count)
{
- llinfos << "Number of params in AvatarAppearance msg (" << num_blocks << ") does not match number of tweakable params in avatar xml file (" << expected_tweakable_count << "). Processing what we can. object: " << getID() << llendl;
+ LL_DEBUGS("Avatar") << "Number of params in AvatarAppearance msg (" << num_params << ") does not match number of tweakable params in avatar xml file (" << expected_tweakable_count << "). Processing what we can. object: " << getID() << llendl;
}
if (params_changed)
@@ -7295,14 +7246,7 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )
else
{
// AvatarAppearance message arrived without visual params
- if (drop_visual_params_debug)
- {
- llinfos << "Debug-faked lack of parameters on AvatarAppearance for object: " << getID() << llendl;
- }
- else
- {
- llinfos << "AvatarAppearance msg received without any parameters, object: " << getID() << llendl;
- }
+ LL_DEBUGS("Avatar") << avString() << "no visual params" << LL_ENDL;
const F32 LOADING_TIMEOUT_SECONDS = 60.f;
// this isn't really a problem if we already have a non-default shape
@@ -7325,7 +7269,14 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )
// If all of the avatars are completely baked, release the global image caches to conserve memory.
LLVOAvatar::cullAvatarsByPixelArea();
-// llinfos << "processAvatarAppearance end " << mID << llendl;
+ if (isSelf())
+ {
+ mUseLocalAppearance = false;
+ }
+
+ updateMeshTextures();
+
+ //if (enable_verbose_dumps) dumpArchetypeXML(dump_prefix + "process_end");
}
// static
@@ -7355,12 +7306,12 @@ void LLVOAvatar::getAnimNames( LLDynamicArray<std::string>* names )
names->put( "enter_away_from_keyboard_state" );
}
+// static
void LLVOAvatar::onBakedTextureMasksLoaded( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata )
{
if (!userdata) return;
//llinfos << "onBakedTextureMasksLoaded: " << src_vi->getID() << llendl;
- const LLMemType mt(LLMemType::MTYPE_AVATAR);
const LLUUID id = src_vi->getID();
LLTextureMaskData* maskData = (LLTextureMaskData*) userdata;
@@ -7374,7 +7325,7 @@ void LLVOAvatar::onBakedTextureMasksLoaded( BOOL success, LLViewerFetchedTexture
{
if (!aux_src->getData())
{
- llerrs << "No auxiliary source data for onBakedTextureMasksLoaded" << llendl;
+ llerrs << "No auxiliary source (morph mask) data for image id " << id << llendl;
return;
}
@@ -7399,12 +7350,12 @@ void LLVOAvatar::onBakedTextureMasksLoaded( BOOL success, LLViewerFetchedTexture
self->mBakedTextureDatas[BAKED_HEAD].mTexLayerSet->applyMorphMask(aux_src->getData(), aux_src->getWidth(), aux_src->getHeight(), 1);
maskData->mLastDiscardLevel = discard_level; */
BOOL found_texture_id = false;
- for (LLVOAvatarDictionary::Textures::const_iterator iter = LLVOAvatarDictionary::getInstance()->getTextures().begin();
- iter != LLVOAvatarDictionary::getInstance()->getTextures().end();
+ for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getTextures().begin();
+ iter != LLAvatarAppearanceDictionary::getInstance()->getTextures().end();
++iter)
{
- const LLVOAvatarDictionary::TextureEntry *texture_dict = iter->second;
+ const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = iter->second;
if (texture_dict->mIsUsedByBakedTexture)
{
const ETextureIndex texture_index = iter->first;
@@ -7426,7 +7377,7 @@ void LLVOAvatar::onBakedTextureMasksLoaded( BOOL success, LLViewerFetchedTexture
}
if (!found_texture_id)
{
- llinfos << "onBakedTextureMasksLoaded(): unexpected image id: " << id << llendl;
+ llinfos << "unexpected image id: " << id << llendl;
}
self->dirtyMesh();
}
@@ -7434,7 +7385,7 @@ void LLVOAvatar::onBakedTextureMasksLoaded( BOOL success, LLViewerFetchedTexture
{
// this can happen when someone uses an old baked texture possibly provided by
// viewer-side baked texture caching
- llwarns << "Masks loaded callback but NO aux source!" << llendl;
+ llwarns << "Masks loaded callback but NO aux source, id " << id << llendl;
}
}
@@ -7447,9 +7398,16 @@ void LLVOAvatar::onBakedTextureMasksLoaded( BOOL success, LLViewerFetchedTexture
// static
void LLVOAvatar::onInitialBakedTextureLoaded( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata )
{
+
+
LLUUID *avatar_idp = (LLUUID *)userdata;
LLVOAvatar *selfp = (LLVOAvatar *)gObjectList.findObject(*avatar_idp);
+ if (selfp)
+ {
+ LL_DEBUGS("Avatar") << selfp->avString() << "discard_level " << discard_level << " success " << success << " final " << final << LL_ENDL;
+ }
+
if (!success && selfp)
{
selfp->removeMissingBakedTextures();
@@ -7460,13 +7418,20 @@ void LLVOAvatar::onInitialBakedTextureLoaded( BOOL success, LLViewerFetchedTextu
}
}
-void LLVOAvatar::onBakedTextureLoaded(BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata)
+// Static
+void LLVOAvatar::onBakedTextureLoaded(BOOL success,
+ LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src,
+ S32 discard_level, BOOL final, void* userdata)
{
- //llinfos << "onBakedTextureLoaded: " << src_vi->getID() << llendl;
+ LL_DEBUGS("Avatar") << "onBakedTextureLoaded: " << src_vi->getID() << LL_ENDL;
LLUUID id = src_vi->getID();
LLUUID *avatar_idp = (LLUUID *)userdata;
LLVOAvatar *selfp = (LLVOAvatar *)gObjectList.findObject(*avatar_idp);
+ if (selfp)
+ {
+ LL_DEBUGS("Avatar") << selfp->avString() << "discard_level " << discard_level << " success " << success << " final " << final << " id " << src_vi->getID() << LL_ENDL;
+ }
if (selfp && !success)
{
@@ -7488,28 +7453,38 @@ void LLVOAvatar::onBakedTextureLoaded(BOOL success, LLViewerFetchedTexture *src_
// Called when baked texture is loaded and also when we start up with a baked texture
void LLVOAvatar::useBakedTexture( const LLUUID& id )
{
- /* if(id == head_baked->getID())
- mHeadBakedLoaded = TRUE;
- mLastHeadBakedID = id;
- mHeadMesh0.setTexture( head_baked );
- mHeadMesh1.setTexture( head_baked ); */
for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
{
LLViewerTexture* image_baked = getImage( mBakedTextureDatas[i].mTextureIndex, 0 );
if (id == image_baked->getID())
{
+ LL_DEBUGS("Avatar") << avString() << " i " << i << " id " << id << LL_ENDL;
mBakedTextureDatas[i].mIsLoaded = true;
- mBakedTextureDatas[i].mLastTextureIndex = id;
+ mBakedTextureDatas[i].mLastTextureID = id;
mBakedTextureDatas[i].mIsUsed = true;
- for (U32 k = 0; k < mBakedTextureDatas[i].mMeshes.size(); k++)
+
+ if (isUsingLocalAppearance())
{
- mBakedTextureDatas[i].mMeshes[k]->setTexture( image_baked );
+ llinfos << "not changing to baked texture while isUsingLocalAppearance" << llendl;
}
- if (mBakedTextureDatas[i].mTexLayerSet)
+ else
{
- //mBakedTextureDatas[i].mTexLayerSet->destroyComposite();
+ debugColorizeSubMeshes(i,LLColor4::green);
+
+ avatar_joint_mesh_list_t::iterator iter = mBakedTextureDatas[i].mJointMeshes.begin();
+ avatar_joint_mesh_list_t::iterator end = mBakedTextureDatas[i].mJointMeshes.end();
+ for (; iter != end; ++iter)
+ {
+ LLAvatarJointMesh* mesh = (*iter);
+ if (mesh)
+ {
+ mesh->setTexture( image_baked );
+ }
+ }
}
- const LLVOAvatarDictionary::BakedEntry *baked_dict = LLVOAvatarDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)i);
+
+ const LLAvatarAppearanceDictionary::BakedEntry *baked_dict =
+ LLAvatarAppearanceDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)i);
for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin();
local_tex_iter != baked_dict->mLocalTextures.end();
++local_tex_iter)
@@ -7522,9 +7497,15 @@ void LLVOAvatar::useBakedTexture( const LLUUID& id )
// This is paired with similar code in updateMeshTextures that sets hair mesh color.
if (i == BAKED_HAIR)
{
- for (U32 i = 0; i < mBakedTextureDatas[BAKED_HAIR].mMeshes.size(); i++)
+ avatar_joint_mesh_list_t::iterator iter = mBakedTextureDatas[i].mJointMeshes.begin();
+ avatar_joint_mesh_list_t::iterator end = mBakedTextureDatas[i].mJointMeshes.end();
+ for (; iter != end; ++iter)
{
- mBakedTextureDatas[BAKED_HAIR].mMeshes[i]->setColor( 1.f, 1.f, 1.f, 1.f );
+ LLAvatarJointMesh* mesh = (*iter);
+ if (mesh)
+ {
+ mesh->setColor( LLColor4::white );
+ }
}
}
}
@@ -7533,11 +7514,43 @@ void LLVOAvatar::useBakedTexture( const LLUUID& id )
dirtyMesh();
}
-// static
-void LLVOAvatar::dumpArchetypeXML( void* )
+std::string get_sequential_numbered_file_name(const std::string& prefix,
+ const std::string& suffix)
+{
+ typedef std::map<std::string,S32> file_num_type;
+ static file_num_type file_nums;
+ file_num_type::iterator it = file_nums.find(prefix);
+ S32 num = 0;
+ if (it != file_nums.end())
{
+ num = it->second;
+ }
+ file_nums[prefix] = num+1;
+ std::string outfilename = prefix + " " + llformat("%04d",num) + ".xml";
+ std::replace(outfilename.begin(),outfilename.end(),' ','_');
+ return outfilename;
+}
+
+void LLVOAvatar::dumpArchetypeXML(const std::string& prefix, bool group_by_wearables )
+{
+ std::string outprefix(prefix);
+ if (outprefix.empty())
+ {
+ outprefix = getFullname() + (isSelf()?"_s":"_o");
+ }
+ if (outprefix.empty())
+{
+ outprefix = getFullname() + (isSelf()?"_s":"_o");
+ }
+ if (outprefix.empty())
+ {
+ outprefix = std::string("new_archetype");
+ }
+ std::string outfilename = get_sequential_numbered_file_name(outprefix,".xml");
+
LLAPRFile outfile;
- outfile.open(gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS,"new archetype.xml"), LL_APR_WB );
+ std::string fullpath = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,outfilename);
+ outfile.open(fullpath, LL_APR_WB );
apr_file_t* file = outfile.getFileHandle();
if (!file)
{
@@ -7545,36 +7558,36 @@ void LLVOAvatar::dumpArchetypeXML( void* )
}
else
{
- llinfos << "xmlfile write handle obtained : " << gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS,"new archetype.xml") << llendl;
+ llinfos << "xmlfile write handle obtained : " << fullpath << llendl;
}
apr_file_printf( file, "<?xml version=\"1.0\" encoding=\"US-ASCII\" standalone=\"yes\"?>\n" );
apr_file_printf( file, "<linden_genepool version=\"1.0\">\n" );
apr_file_printf( file, "\n\t<archetype name=\"???\">\n" );
- // only body parts, not clothing.
- for (S32 type = LLWearableType::WT_SHAPE; type <= LLWearableType::WT_EYES; type++)
+ if (group_by_wearables)
+ {
+ for (S32 type = LLWearableType::WT_SHAPE; type < LLWearableType::WT_COUNT; type++)
{
const std::string& wearable_name = LLWearableType::getTypeName((LLWearableType::EType)type);
apr_file_printf( file, "\n\t\t<!-- wearable: %s -->\n", wearable_name.c_str() );
- for (LLVisualParam* param = gAgentAvatarp->getFirstVisualParam(); param; param = gAgentAvatarp->getNextVisualParam())
+ for (LLVisualParam* param = getFirstVisualParam(); param; param = getNextVisualParam())
{
LLViewerVisualParam* viewer_param = (LLViewerVisualParam*)param;
if( (viewer_param->getWearableType() == type) &&
(viewer_param->isTweakable() ) )
{
- apr_file_printf(file, "\t\t<param id=\"%d\" name=\"%s\" value=\"%.3f\"/>\n",
- viewer_param->getID(), viewer_param->getName().c_str(), viewer_param->getWeight());
+ dump_visual_param(file, viewer_param, viewer_param->getWeight());
}
}
for (U8 te = 0; te < TEX_NUM_INDICES; te++)
{
- if (LLVOAvatarDictionary::getTEWearableType((ETextureIndex)te) == type)
+ if (LLAvatarAppearanceDictionary::getTEWearableType((ETextureIndex)te) == type)
{
// MULTIPLE_WEARABLES: extend to multiple wearables?
- LLViewerTexture* te_image = ((LLVOAvatar *)(gAgentAvatarp))->getImage((ETextureIndex)te, 0);
+ LLViewerTexture* te_image = getImage((ETextureIndex)te, 0);
if( te_image )
{
std::string uuid_str;
@@ -7584,13 +7597,39 @@ void LLVOAvatar::dumpArchetypeXML( void* )
}
}
}
+ }
+ else
+ {
+ // Just dump all params sequentially.
+ for (LLVisualParam* param = getFirstVisualParam(); param; param = getNextVisualParam())
+ {
+ LLViewerVisualParam* viewer_param = (LLViewerVisualParam*)param;
+ dump_visual_param(file, viewer_param, viewer_param->getWeight());
+ }
+
+ for (U8 te = 0; te < TEX_NUM_INDICES; te++)
+ {
+ // MULTIPLE_WEARABLES: extend to multiple wearables?
+ LLViewerTexture* te_image = getImage((ETextureIndex)te, 0);
+ if( te_image )
+ {
+ std::string uuid_str;
+ te_image->getID().toString( uuid_str );
+ apr_file_printf( file, "\t\t<texture te=\"%i\" uuid=\"%s\"/>\n", te, uuid_str.c_str());
+ }
+ }
+ }
+
apr_file_printf( file, "\t</archetype>\n" );
apr_file_printf( file, "\n</linden_genepool>\n" );
- //explictly close the file if it is still open which it should be
- if (file)
+
+ bool ultra_verbose = false;
+ if (isSelf() && ultra_verbose)
{
- outfile.close();
+ // show the cloned params inside the wearables as well.
+ gAgentAvatarp->dumpWearableInfo(outfile);
}
+ // File will close when handle goes out of scope
}
@@ -7672,12 +7711,9 @@ void LLVOAvatar::cullAvatarsByPixelArea()
}
}
+ // runway - this doesn't really detect gray/grey state.
S32 grey_avatars = 0;
- if (LLVOAvatar::areAllNearbyInstancesBaked(grey_avatars))
- {
- LLVOAvatar::deleteCachedImages(false);
- }
- else
+ if (!LLVOAvatar::areAllNearbyInstancesBaked(grey_avatars))
{
if (gFrameTimeSeconds != sUnbakedUpdateTime) // only update once per frame
{
@@ -7706,500 +7742,43 @@ void LLVOAvatar::startAppearanceAnimation()
}
// virtual
-void LLVOAvatar::removeMissingBakedTextures()
+void LLVOAvatar::bodySizeChanged()
{
+ if (isSelf() && !LLAppearanceMgr::instance().isInUpdateAppearanceFromCOF())
+ { // notify simulator of change in size
+ // but not if we are in the middle of updating appearance
+ gAgent.sendAgentSetAppearance();
}
-
-//-----------------------------------------------------------------------------
-// LLVOAvatarXmlInfo
-//-----------------------------------------------------------------------------
-
-LLVOAvatar::LLVOAvatarXmlInfo::LLVOAvatarXmlInfo()
- : mTexSkinColorInfo(0), mTexHairColorInfo(0), mTexEyeColorInfo(0)
-{
}
-LLVOAvatar::LLVOAvatarXmlInfo::~LLVOAvatarXmlInfo()
+BOOL LLVOAvatar::isUsingServerBakes() const
{
- std::for_each(mMeshInfoList.begin(), mMeshInfoList.end(), DeletePointer());
- std::for_each(mSkeletalDistortionInfoList.begin(), mSkeletalDistortionInfoList.end(), DeletePointer());
- std::for_each(mAttachmentInfoList.begin(), mAttachmentInfoList.end(), DeletePointer());
- deleteAndClear(mTexSkinColorInfo);
- deleteAndClear(mTexHairColorInfo);
- deleteAndClear(mTexEyeColorInfo);
- std::for_each(mLayerInfoList.begin(), mLayerInfoList.end(), DeletePointer());
- std::for_each(mDriverInfoList.begin(), mDriverInfoList.end(), DeletePointer());
- std::for_each(mMorphMaskInfoList.begin(), mMorphMaskInfoList.end(), DeletePointer());
-}
-
-//-----------------------------------------------------------------------------
-// LLVOAvatarBoneInfo::parseXml()
-//-----------------------------------------------------------------------------
-BOOL LLVOAvatarBoneInfo::parseXml(LLXmlTreeNode* node)
+#if 1
+ // Sanity check - visual param for appearance version should match mUseServerBakes
+ LLVisualParam* appearance_version_param = getVisualParam(11000);
+ llassert(appearance_version_param);
+ F32 wt = appearance_version_param->getWeight();
+ F32 expect_wt = mUseServerBakes ? 1.0 : 0.0;
+ if (!is_approx_equal(wt,expect_wt))
{
- if (node->hasName("bone"))
- {
- mIsJoint = TRUE;
- static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name");
- if (!node->getFastAttributeString(name_string, mName))
- {
- llwarns << "Bone without name" << llendl;
- return FALSE;
- }
- }
- else if (node->hasName("collision_volume"))
- {
- mIsJoint = FALSE;
- static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name");
- if (!node->getFastAttributeString(name_string, mName))
- {
- mName = "Collision Volume";
- }
- }
- else
- {
- llwarns << "Invalid node " << node->getName() << llendl;
- return FALSE;
- }
-
- static LLStdStringHandle pos_string = LLXmlTree::addAttributeString("pos");
- if (!node->getFastAttributeVector3(pos_string, mPos))
- {
- llwarns << "Bone without position" << llendl;
- return FALSE;
+ llwarns << "wt " << wt << " differs from expected " << expect_wt << llendl;
}
+#endif
- static LLStdStringHandle rot_string = LLXmlTree::addAttributeString("rot");
- if (!node->getFastAttributeVector3(rot_string, mRot))
- {
- llwarns << "Bone without rotation" << llendl;
- return FALSE;
- }
-
- static LLStdStringHandle scale_string = LLXmlTree::addAttributeString("scale");
- if (!node->getFastAttributeVector3(scale_string, mScale))
- {
- llwarns << "Bone without scale" << llendl;
- return FALSE;
- }
-
- if (mIsJoint)
- {
- static LLStdStringHandle pivot_string = LLXmlTree::addAttributeString("pivot");
- if (!node->getFastAttributeVector3(pivot_string, mPivot))
- {
- llwarns << "Bone without pivot" << llendl;
- return FALSE;
- }
- }
-
- // parse children
- LLXmlTreeNode* child;
- for( child = node->getFirstChild(); child; child = node->getNextChild() )
- {
- LLVOAvatarBoneInfo *child_info = new LLVOAvatarBoneInfo;
- if (!child_info->parseXml(child))
- {
- delete child_info;
- return FALSE;
- }
- mChildList.push_back(child_info);
- }
- return TRUE;
-}
-
-//-----------------------------------------------------------------------------
-// LLVOAvatarSkeletonInfo::parseXml()
-//-----------------------------------------------------------------------------
-BOOL LLVOAvatarSkeletonInfo::parseXml(LLXmlTreeNode* node)
-{
- static LLStdStringHandle num_bones_string = LLXmlTree::addAttributeString("num_bones");
- if (!node->getFastAttributeS32(num_bones_string, mNumBones))
- {
- llwarns << "Couldn't find number of bones." << llendl;
- return FALSE;
- }
-
- static LLStdStringHandle num_collision_volumes_string = LLXmlTree::addAttributeString("num_collision_volumes");
- node->getFastAttributeS32(num_collision_volumes_string, mNumCollisionVolumes);
-
- LLXmlTreeNode* child;
- for( child = node->getFirstChild(); child; child = node->getNextChild() )
- {
- LLVOAvatarBoneInfo *info = new LLVOAvatarBoneInfo;
- if (!info->parseXml(child))
- {
- delete info;
- llwarns << "Error parsing bone in skeleton file" << llendl;
- return FALSE;
- }
- mBoneInfoList.push_back(info);
- }
- return TRUE;
-}
-
-//-----------------------------------------------------------------------------
-// parseXmlSkeletonNode(): parses <skeleton> nodes from XML tree
-//-----------------------------------------------------------------------------
-BOOL LLVOAvatar::LLVOAvatarXmlInfo::parseXmlSkeletonNode(LLXmlTreeNode* root)
-{
- LLXmlTreeNode* node = root->getChildByName( "skeleton" );
- if( !node )
- {
- llwarns << "avatar file: missing <skeleton>" << llendl;
- return FALSE;
- }
-
- LLXmlTreeNode* child;
-
- // SKELETON DISTORTIONS
- for (child = node->getChildByName( "param" );
- child;
- child = node->getNextNamedChild())
- {
- if (!child->getChildByName("param_skeleton"))
- {
- if (child->getChildByName("param_morph"))
- {
- llwarns << "Can't specify morph param in skeleton definition." << llendl;
- }
- else
- {
- llwarns << "Unknown param type." << llendl;
- }
- continue;
- }
-
- LLPolySkeletalDistortionInfo *info = new LLPolySkeletalDistortionInfo;
- if (!info->parseXml(child))
- {
- delete info;
- return FALSE;
- }
-
- mSkeletalDistortionInfoList.push_back(info);
- }
-
- // ATTACHMENT POINTS
- for (child = node->getChildByName( "attachment_point" );
- child;
- child = node->getNextNamedChild())
- {
- LLVOAvatarAttachmentInfo* info = new LLVOAvatarAttachmentInfo();
-
- static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name");
- if (!child->getFastAttributeString(name_string, info->mName))
- {
- llwarns << "No name supplied for attachment point." << llendl;
- delete info;
- continue;
- }
-
- static LLStdStringHandle joint_string = LLXmlTree::addAttributeString("joint");
- if (!child->getFastAttributeString(joint_string, info->mJointName))
- {
- llwarns << "No bone declared in attachment point " << info->mName << llendl;
- delete info;
- continue;
- }
-
- static LLStdStringHandle position_string = LLXmlTree::addAttributeString("position");
- if (child->getFastAttributeVector3(position_string, info->mPosition))
- {
- info->mHasPosition = TRUE;
- }
-
- static LLStdStringHandle rotation_string = LLXmlTree::addAttributeString("rotation");
- if (child->getFastAttributeVector3(rotation_string, info->mRotationEuler))
- {
- info->mHasRotation = TRUE;
- }
- static LLStdStringHandle group_string = LLXmlTree::addAttributeString("group");
- if (child->getFastAttributeS32(group_string, info->mGroup))
- {
- if (info->mGroup == -1)
- info->mGroup = -1111; // -1 = none parsed, < -1 = bad value
- }
-
- static LLStdStringHandle id_string = LLXmlTree::addAttributeString("id");
- if (!child->getFastAttributeS32(id_string, info->mAttachmentID))
- {
- llwarns << "No id supplied for attachment point " << info->mName << llendl;
- delete info;
- continue;
- }
-
- static LLStdStringHandle slot_string = LLXmlTree::addAttributeString("pie_slice");
- child->getFastAttributeS32(slot_string, info->mPieMenuSlice);
-
- static LLStdStringHandle visible_in_first_person_string = LLXmlTree::addAttributeString("visible_in_first_person");
- child->getFastAttributeBOOL(visible_in_first_person_string, info->mVisibleFirstPerson);
-
- static LLStdStringHandle hud_attachment_string = LLXmlTree::addAttributeString("hud");
- child->getFastAttributeBOOL(hud_attachment_string, info->mIsHUDAttachment);
-
- mAttachmentInfoList.push_back(info);
- }
-
- return TRUE;
-}
-
-//-----------------------------------------------------------------------------
-// parseXmlMeshNodes(): parses <mesh> nodes from XML tree
-//-----------------------------------------------------------------------------
-BOOL LLVOAvatar::LLVOAvatarXmlInfo::parseXmlMeshNodes(LLXmlTreeNode* root)
-{
- for (LLXmlTreeNode* node = root->getChildByName( "mesh" );
- node;
- node = root->getNextNamedChild())
- {
- LLVOAvatarMeshInfo *info = new LLVOAvatarMeshInfo;
-
- // attribute: type
- static LLStdStringHandle type_string = LLXmlTree::addAttributeString("type");
- if( !node->getFastAttributeString( type_string, info->mType ) )
- {
- llwarns << "Avatar file: <mesh> is missing type attribute. Ignoring element. " << llendl;
- delete info;
- return FALSE; // Ignore this element
+ return mUseServerBakes;
}
- static LLStdStringHandle lod_string = LLXmlTree::addAttributeString("lod");
- if (!node->getFastAttributeS32( lod_string, info->mLOD ))
+void LLVOAvatar::setIsUsingServerBakes(BOOL newval)
{
- llwarns << "Avatar file: <mesh> is missing lod attribute. Ignoring element. " << llendl;
- delete info;
- return FALSE; // Ignore this element
+ mUseServerBakes = newval;
+ LLVisualParam* appearance_version_param = getVisualParam(11000);
+ llassert(appearance_version_param);
+ appearance_version_param->setWeight(newval ? 1.0 : 0.0, false);
}
- static LLStdStringHandle file_name_string = LLXmlTree::addAttributeString("file_name");
- if( !node->getFastAttributeString( file_name_string, info->mMeshFileName ) )
- {
- llwarns << "Avatar file: <mesh> is missing file_name attribute. Ignoring: " << info->mType << llendl;
- delete info;
- return FALSE; // Ignore this element
- }
-
- static LLStdStringHandle reference_string = LLXmlTree::addAttributeString("reference");
- node->getFastAttributeString( reference_string, info->mReferenceMeshName );
-
- // attribute: min_pixel_area
- static LLStdStringHandle min_pixel_area_string = LLXmlTree::addAttributeString("min_pixel_area");
- static LLStdStringHandle min_pixel_width_string = LLXmlTree::addAttributeString("min_pixel_width");
- if (!node->getFastAttributeF32( min_pixel_area_string, info->mMinPixelArea ))
- {
- F32 min_pixel_area = 0.1f;
- if (node->getFastAttributeF32( min_pixel_width_string, min_pixel_area ))
- {
- // this is square root of pixel area (sensible to use linear space in defining lods)
- min_pixel_area = min_pixel_area * min_pixel_area;
- }
- info->mMinPixelArea = min_pixel_area;
- }
-
- // Parse visual params for this node only if we haven't already
- for (LLXmlTreeNode* child = node->getChildByName( "param" );
- child;
- child = node->getNextNamedChild())
- {
- if (!child->getChildByName("param_morph"))
- {
- if (child->getChildByName("param_skeleton"))
- {
- llwarns << "Can't specify skeleton param in a mesh definition." << llendl;
- }
- else
- {
- llwarns << "Unknown param type." << llendl;
- }
- continue;
- }
-
- LLPolyMorphTargetInfo *morphinfo = new LLPolyMorphTargetInfo();
- if (!morphinfo->parseXml(child))
- {
- delete morphinfo;
- delete info;
- return -1;
- }
- BOOL shared = FALSE;
- static LLStdStringHandle shared_string = LLXmlTree::addAttributeString("shared");
- child->getFastAttributeBOOL(shared_string, shared);
-
- info->mPolyMorphTargetInfoList.push_back(LLVOAvatarMeshInfo::morph_info_pair_t(morphinfo, shared));
- }
-
- mMeshInfoList.push_back(info);
- }
- return TRUE;
-}
-
-//-----------------------------------------------------------------------------
-// parseXmlColorNodes(): parses <global_color> nodes from XML tree
-//-----------------------------------------------------------------------------
-BOOL LLVOAvatar::LLVOAvatarXmlInfo::parseXmlColorNodes(LLXmlTreeNode* root)
-{
- for (LLXmlTreeNode* color_node = root->getChildByName( "global_color" );
- color_node;
- color_node = root->getNextNamedChild())
- {
- std::string global_color_name;
- static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name");
- if (color_node->getFastAttributeString( name_string, global_color_name ) )
- {
- if( global_color_name == "skin_color" )
- {
- if (mTexSkinColorInfo)
- {
- llwarns << "avatar file: multiple instances of skin_color" << llendl;
- return FALSE;
- }
- mTexSkinColorInfo = new LLTexGlobalColorInfo;
- if( !mTexSkinColorInfo->parseXml( color_node ) )
- {
- deleteAndClear(mTexSkinColorInfo);
- llwarns << "avatar file: mTexSkinColor->parseXml() failed" << llendl;
- return FALSE;
- }
- }
- else if( global_color_name == "hair_color" )
- {
- if (mTexHairColorInfo)
- {
- llwarns << "avatar file: multiple instances of hair_color" << llendl;
- return FALSE;
- }
- mTexHairColorInfo = new LLTexGlobalColorInfo;
- if( !mTexHairColorInfo->parseXml( color_node ) )
- {
- deleteAndClear(mTexHairColorInfo);
- llwarns << "avatar file: mTexHairColor->parseXml() failed" << llendl;
- return FALSE;
- }
- }
- else if( global_color_name == "eye_color" )
- {
- if (mTexEyeColorInfo)
- {
- llwarns << "avatar file: multiple instances of eye_color" << llendl;
- return FALSE;
- }
- mTexEyeColorInfo = new LLTexGlobalColorInfo;
- if( !mTexEyeColorInfo->parseXml( color_node ) )
- {
- llwarns << "avatar file: mTexEyeColor->parseXml() failed" << llendl;
- return FALSE;
- }
- }
- }
- }
- return TRUE;
-}
-
-//-----------------------------------------------------------------------------
-// parseXmlLayerNodes(): parses <layer_set> nodes from XML tree
-//-----------------------------------------------------------------------------
-BOOL LLVOAvatar::LLVOAvatarXmlInfo::parseXmlLayerNodes(LLXmlTreeNode* root)
-{
- for (LLXmlTreeNode* layer_node = root->getChildByName( "layer_set" );
- layer_node;
- layer_node = root->getNextNamedChild())
- {
- LLTexLayerSetInfo* layer_info = new LLTexLayerSetInfo();
- if( layer_info->parseXml( layer_node ) )
- {
- mLayerInfoList.push_back(layer_info);
- }
- else
- {
- delete layer_info;
- llwarns << "avatar file: layer_set->parseXml() failed" << llendl;
- return FALSE;
- }
- }
- return TRUE;
-}
-
-//-----------------------------------------------------------------------------
-// parseXmlDriverNodes(): parses <driver_parameters> nodes from XML tree
-//-----------------------------------------------------------------------------
-BOOL LLVOAvatar::LLVOAvatarXmlInfo::parseXmlDriverNodes(LLXmlTreeNode* root)
-{
- LLXmlTreeNode* driver = root->getChildByName( "driver_parameters" );
- if( driver )
- {
- for (LLXmlTreeNode* grand_child = driver->getChildByName( "param" );
- grand_child;
- grand_child = driver->getNextNamedChild())
- {
- if( grand_child->getChildByName( "param_driver" ) )
+// virtual
+void LLVOAvatar::removeMissingBakedTextures()
{
- LLDriverParamInfo* driver_info = new LLDriverParamInfo();
- if( driver_info->parseXml( grand_child ) )
- {
- mDriverInfoList.push_back(driver_info);
- }
- else
- {
- delete driver_info;
- llwarns << "avatar file: driver_param->parseXml() failed" << llendl;
- return FALSE;
- }
- }
- }
- }
- return TRUE;
-}
-
-//-----------------------------------------------------------------------------
-// parseXmlDriverNodes(): parses <driver_parameters> nodes from XML tree
-//-----------------------------------------------------------------------------
-BOOL LLVOAvatar::LLVOAvatarXmlInfo::parseXmlMorphNodes(LLXmlTreeNode* root)
-{
- LLXmlTreeNode* masks = root->getChildByName( "morph_masks" );
- if( !masks )
- {
- return FALSE;
- }
-
- for (LLXmlTreeNode* grand_child = masks->getChildByName( "mask" );
- grand_child;
- grand_child = masks->getNextNamedChild())
- {
- LLVOAvatarMorphInfo* info = new LLVOAvatarMorphInfo();
-
- static LLStdStringHandle name_string = LLXmlTree::addAttributeString("morph_name");
- if (!grand_child->getFastAttributeString(name_string, info->mName))
- {
- llwarns << "No name supplied for morph mask." << llendl;
- delete info;
- continue;
- }
-
- static LLStdStringHandle region_string = LLXmlTree::addAttributeString("body_region");
- if (!grand_child->getFastAttributeString(region_string, info->mRegion))
- {
- llwarns << "No region supplied for morph mask." << llendl;
- delete info;
- continue;
- }
-
- static LLStdStringHandle layer_string = LLXmlTree::addAttributeString("layer");
- if (!grand_child->getFastAttributeString(layer_string, info->mLayer))
- {
- llwarns << "No layer supplied for morph mask." << llendl;
- delete info;
- continue;
- }
-
- // optional parameter. don't throw a warning if not present.
- static LLStdStringHandle invert_string = LLXmlTree::addAttributeString("invert");
- grand_child->getFastAttributeBOOL(invert_string, info->mInvert);
-
- mMorphMaskInfoList.push_back(info);
- }
-
- return TRUE;
}
//virtual
@@ -8262,7 +7841,7 @@ BOOL LLVOAvatar::updateLOD()
BOOL res = updateJointLODs();
LLFace* facep = mDrawable->getFace(0);
- if (!facep->getVertexBuffer())
+ if (!facep || !facep->getVertexBuffer())
{
dirtyMesh(2);
}
@@ -8308,9 +7887,9 @@ void LLVOAvatar::updateImpostors()
LLCharacter::sAllowInstancesChange = TRUE ;
}
-BOOL LLVOAvatar::isImpostor() const
+BOOL LLVOAvatar::isImpostor()
{
- return (isVisuallyMuted() || (sUseImpostors && mUpdatePeriod >= IMPOSTOR_PERIOD)) ? TRUE : FALSE;
+ return sUseImpostors && (isVisuallyMuted() || (mUpdatePeriod >= IMPOSTOR_PERIOD)) ? TRUE : FALSE;
}
@@ -8353,159 +7932,207 @@ void LLVOAvatar::getImpostorValues(LLVector4a* extents, LLVector3& angle, F32& d
angle.mV[2] = da;
}
+
void LLVOAvatar::idleUpdateRenderCost()
{
- static const U32 ARC_BODY_PART_COST = 200;
+ static LLCachedControl<U32> max_render_cost(gSavedSettings, "RenderAutoMuteRenderWeightLimit", 0);
static const U32 ARC_LIMIT = 20000;
- static std::set<LLUUID> all_textures;
-
if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_ATTACHMENT_BYTES))
{ //set debug text to attachment geometry bytes here so render cost will override
setDebugText(llformat("%.1f KB, %.2f m^2", mAttachmentGeometryBytes/1024.f, mAttachmentSurfaceArea));
}
- if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHAME))
+ if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHAME) && max_render_cost == 0)
{
return;
}
- U32 cost = 0;
- LLVOVolume::texture_cost_t textures;
+ calculateUpdateRenderCost(); // Update mVisualComplexity if needed
+
+ if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHAME))
+ {
+ std::string viz_string = LLVOAvatar::rezStatusToString(getRezzedStatus());
+ setDebugText(llformat("%s %d", viz_string.c_str(), mVisualComplexity));
+ F32 green = 1.f-llclamp(((F32) mVisualComplexity-(F32)ARC_LIMIT)/(F32)ARC_LIMIT, 0.f, 1.f);
+ F32 red = llmin((F32) mVisualComplexity/(F32)ARC_LIMIT, 1.f);
+ mText->setColor(LLColor4(red,green,0,1));
+ }
+}
- for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++)
+
+// Calculations for mVisualComplexity value
+void LLVOAvatar::calculateUpdateRenderCost()
+{
+ static const U32 ARC_BODY_PART_COST = 200;
+
+ // Diagnostic list of all textures on our avatar
+ static std::set<LLUUID> all_textures;
+
+ if (mVisualComplexityStale)
{
- const LLVOAvatarDictionary::BakedEntry *baked_dict = LLVOAvatarDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)baked_index);
- ETextureIndex tex_index = baked_dict->mTextureIndex;
- if ((tex_index != TEX_SKIRT_BAKED) || (isWearingWearableType(LLWearableType::WT_SKIRT)))
+ mVisualComplexityStale = FALSE;
+ U32 cost = 0;
+ LLVOVolume::texture_cost_t textures;
+
+ for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++)
{
- if (isTextureVisible(tex_index))
+ const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = LLAvatarAppearanceDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)baked_index);
+ ETextureIndex tex_index = baked_dict->mTextureIndex;
+ if ((tex_index != TEX_SKIRT_BAKED) || (isWearingWearableType(LLWearableType::WT_SKIRT)))
{
- cost +=ARC_BODY_PART_COST;
+ if (isTextureVisible(tex_index))
+ {
+ cost +=ARC_BODY_PART_COST;
+ }
}
}
- }
- for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin();
- iter != mAttachmentPoints.end();
- ++iter)
- {
- LLViewerJointAttachment* attachment = iter->second;
- for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
- attachment_iter != attachment->mAttachedObjects.end();
- ++attachment_iter)
+ for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin();
+ iter != mAttachmentPoints.end();
+ ++iter)
{
- const LLViewerObject* attached_object = (*attachment_iter);
- if (attached_object && !attached_object->isHUDAttachment())
+ LLViewerJointAttachment* attachment = iter->second;
+ for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
+ attachment_iter != attachment->mAttachedObjects.end();
+ ++attachment_iter)
{
- textures.clear();
- const LLDrawable* drawable = attached_object->mDrawable;
- if (drawable)
+ const LLViewerObject* attached_object = (*attachment_iter);
+ if (attached_object && !attached_object->isHUDAttachment())
{
- const LLVOVolume* volume = drawable->getVOVolume();
- if (volume)
+ textures.clear();
+ const LLDrawable* drawable = attached_object->mDrawable;
+ if (drawable)
{
- cost += volume->getRenderCost(textures);
-
- const_child_list_t children = volume->getChildren();
- for (const_child_list_t::const_iterator child_iter = children.begin();
- child_iter != children.end();
- ++child_iter)
+ const LLVOVolume* volume = drawable->getVOVolume();
+ if (volume)
{
- LLViewerObject* child_obj = *child_iter;
- LLVOVolume *child = dynamic_cast<LLVOVolume*>( child_obj );
- if (child)
+ cost += volume->getRenderCost(textures);
+
+ const_child_list_t children = volume->getChildren();
+ for (const_child_list_t::const_iterator child_iter = children.begin();
+ child_iter != children.end();
+ ++child_iter)
{
- cost += child->getRenderCost(textures);
+ LLViewerObject* child_obj = *child_iter;
+ LLVOVolume *child = dynamic_cast<LLVOVolume*>( child_obj );
+ if (child)
+ {
+ cost += child->getRenderCost(textures);
+ }
}
- }
- for (LLVOVolume::texture_cost_t::iterator iter = textures.begin(); iter != textures.end(); ++iter)
- {
- // add the cost of each individual texture in the linkset
- cost += iter->second;
+ for (LLVOVolume::texture_cost_t::iterator iter = textures.begin(); iter != textures.end(); ++iter)
+ {
+ // add the cost of each individual texture in the linkset
+ cost += iter->second;
+ }
}
}
}
}
- }
-
- }
-
+ }
- // Diagnostic output to identify all avatar-related textures.
- // Does not affect rendering cost calculation.
- // Could be wrapped in a debug option if output becomes problematic.
- if (isSelf())
- {
- // print any attachment textures we didn't already know about.
- for (LLVOVolume::texture_cost_t::iterator it = textures.begin(); it != textures.end(); ++it)
+ // Diagnostic output to identify all avatar-related textures.
+ // Does not affect rendering cost calculation.
+ // Could be wrapped in a debug option if output becomes problematic.
+ if (isSelf())
{
- LLUUID image_id = it->first;
- if( image_id.isNull() || image_id == IMG_DEFAULT || image_id == IMG_DEFAULT_AVATAR)
- continue;
- if (all_textures.find(image_id) == all_textures.end())
+ // print any attachment textures we didn't already know about.
+ for (LLVOVolume::texture_cost_t::iterator it = textures.begin(); it != textures.end(); ++it)
{
- // attachment texture not previously seen.
- llinfos << "attachment_texture: " << image_id.asString() << llendl;
- all_textures.insert(image_id);
+ LLUUID image_id = it->first;
+ if( image_id.isNull() || image_id == IMG_DEFAULT || image_id == IMG_DEFAULT_AVATAR)
+ continue;
+ if (all_textures.find(image_id) == all_textures.end())
+ {
+ // attachment texture not previously seen.
+ llinfos << "attachment_texture: " << image_id.asString() << llendl;
+ all_textures.insert(image_id);
+ }
}
- }
- // print any avatar textures we didn't already know about
- for (LLVOAvatarDictionary::Textures::const_iterator iter = LLVOAvatarDictionary::getInstance()->getTextures().begin();
- iter != LLVOAvatarDictionary::getInstance()->getTextures().end();
- ++iter)
- {
- const LLVOAvatarDictionary::TextureEntry *texture_dict = iter->second;
- // TODO: MULTI-WEARABLE: handle multiple textures for self
- const LLViewerTexture* te_image = getImage(iter->first,0);
- if (!te_image)
- continue;
- LLUUID image_id = te_image->getID();
- if( image_id.isNull() || image_id == IMG_DEFAULT || image_id == IMG_DEFAULT_AVATAR)
- continue;
- if (all_textures.find(image_id) == all_textures.end())
+ // print any avatar textures we didn't already know about
+ for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getTextures().begin();
+ iter != LLAvatarAppearanceDictionary::getInstance()->getTextures().end();
+ ++iter)
{
- llinfos << "local_texture: " << texture_dict->mName << ": " << image_id << llendl;
- all_textures.insert(image_id);
+ const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = iter->second;
+ // TODO: MULTI-WEARABLE: handle multiple textures for self
+ const LLViewerTexture* te_image = getImage(iter->first,0);
+ if (!te_image)
+ continue;
+ LLUUID image_id = te_image->getID();
+ if( image_id.isNull() || image_id == IMG_DEFAULT || image_id == IMG_DEFAULT_AVATAR)
+ continue;
+ if (all_textures.find(image_id) == all_textures.end())
+ {
+ llinfos << "local_texture: " << texture_dict->mName << ": " << image_id << llendl;
+ all_textures.insert(image_id);
+ }
}
}
+
+ mVisualComplexity = cost;
}
+}
- setDebugText(llformat("%d", cost));
- mVisualComplexity = cost;
- F32 green = 1.f-llclamp(((F32) cost-(F32)ARC_LIMIT)/(F32)ARC_LIMIT, 0.f, 1.f);
- F32 red = llmin((F32) cost/(F32)ARC_LIMIT, 1.f);
- mText->setColor(LLColor4(red,green,0,1));
+
+// static
+LLColor4 LLVOAvatar::calcMutedAVColor(F32 value, S32 range_low, S32 range_high)
+{
+ F32 clamped_value = llmin(value, (F32) range_high);
+ clamped_value = llmax(value, (F32) range_low);
+ F32 spectrum = (clamped_value / range_high); // spectrum is between 0 and 1.f
+
+ // Array of colors. These are arranged so only one RGB color changes between each step,
+ // and it loops back to red so there is an even distribution. It is not a heat map
+ const S32 NUM_SPECTRUM_COLORS = 7;
+ static LLColor4 * spectrum_color[NUM_SPECTRUM_COLORS] = { &LLColor4::red, &LLColor4::magenta, &LLColor4::blue, &LLColor4::cyan, &LLColor4::green, &LLColor4::yellow, &LLColor4::red };
+
+ spectrum = spectrum * (NUM_SPECTRUM_COLORS - 1); // Scale to range of number of colors
+ S32 spectrum_index_1 = floor(spectrum); // Desired color will be after this index
+ S32 spectrum_index_2 = spectrum_index_1 + 1; // and before this index (inclusive)
+ F32 fractBetween = spectrum - (F32)(spectrum_index_1); // distance between the two indexes (0-1)
+
+ LLColor4 new_color = lerp(*spectrum_color[spectrum_index_1], *spectrum_color[spectrum_index_2], fractBetween);
+ new_color.normalize();
+ new_color *= 0.7f; // Tone it down a bit
+
+ //llinfos << "From value " << std::setprecision(3) << value << " returning color " << new_color
+ // << " using indexes " << spectrum_index_1 << ", " << spectrum_index_2
+ // << " and fractBetween " << fractBetween
+ // << llendl;
+
+ return new_color;
}
// static
BOOL LLVOAvatar::isIndexLocalTexture(ETextureIndex index)
{
if (index < 0 || index >= TEX_NUM_INDICES) return false;
- return LLVOAvatarDictionary::getInstance()->getTexture(index)->mIsLocalTexture;
+ return LLAvatarAppearanceDictionary::getInstance()->getTexture(index)->mIsLocalTexture;
}
// static
BOOL LLVOAvatar::isIndexBakedTexture(ETextureIndex index)
{
if (index < 0 || index >= TEX_NUM_INDICES) return false;
- return LLVOAvatarDictionary::getInstance()->getTexture(index)->mIsBakedTexture;
+ return LLAvatarAppearanceDictionary::getInstance()->getTexture(index)->mIsBakedTexture;
}
const std::string LLVOAvatar::getBakedStatusForPrintout() const
{
std::string line;
- for (LLVOAvatarDictionary::Textures::const_iterator iter = LLVOAvatarDictionary::getInstance()->getTextures().begin();
- iter != LLVOAvatarDictionary::getInstance()->getTextures().end();
+ for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getTextures().begin();
+ iter != LLAvatarAppearanceDictionary::getInstance()->getTextures().end();
++iter)
{
const ETextureIndex index = iter->first;
- const LLVOAvatarDictionary::TextureEntry *texture_dict = iter->second;
+ const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = iter->second;
if (texture_dict->mIsBakedTexture)
{
line += texture_dict->mName;
@@ -8537,19 +8164,25 @@ F32 calc_bouncy_animation(F32 x)
}
//virtual
-BOOL LLVOAvatar::isTextureDefined(LLVOAvatarDefines::ETextureIndex te, U32 index ) const
+BOOL LLVOAvatar::isTextureDefined(LLAvatarAppearanceDefines::ETextureIndex te, U32 index ) const
{
if (isIndexLocalTexture(te))
{
return FALSE;
}
+ if( !getImage( te, index ) )
+ {
+ llwarns << "getImage( " << te << ", " << index << " ) returned 0" << llendl;
+ return FALSE;
+ }
+
return (getImage(te, index)->getID() != IMG_DEFAULT_AVATAR &&
getImage(te, index)->getID() != IMG_DEFAULT);
}
//virtual
-BOOL LLVOAvatar::isTextureVisible(LLVOAvatarDefines::ETextureIndex type, U32 index) const
+BOOL LLVOAvatar::isTextureVisible(LLAvatarAppearanceDefines::ETextureIndex type, U32 index) const
{
if (isIndexLocalTexture(type))
{
@@ -8565,9 +8198,11 @@ BOOL LLVOAvatar::isTextureVisible(LLVOAvatarDefines::ETextureIndex type, U32 ind
}
//virtual
-BOOL LLVOAvatar::isTextureVisible(LLVOAvatarDefines::ETextureIndex type, LLWearable *wearable) const
+BOOL LLVOAvatar::isTextureVisible(LLAvatarAppearanceDefines::ETextureIndex type, LLViewerWearable *wearable) const
{
// non-self avatars don't have wearables
return FALSE;
}
+
+
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index 6a4e09593c..9d45a74ecc 100644..100755
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -25,8 +25,8 @@
* $/LicenseInfo$
*/
-#ifndef LL_LLVOAVATAR_H
-#define LL_LLVOAVATAR_H
+#ifndef LL_VOAVATAR_H
+#define LL_VOAVATAR_H
#include <map>
#include <deque>
@@ -36,6 +36,7 @@
#include <boost/signals2.hpp>
#include "imageids.h" // IMG_INVISIBLE
+#include "llavatarappearance.h"
#include "llchat.h"
#include "lldrawpoolalpha.h"
#include "llviewerobject.h"
@@ -44,10 +45,12 @@
#include "llviewerjointmesh.h"
#include "llviewerjointattachment.h"
#include "llrendertarget.h"
-#include "llvoavatardefines.h"
+#include "llavatarappearancedefines.h"
#include "lltexglobalcolor.h"
#include "lldriverparam.h"
+#include "llviewertexlayer.h"
#include "material_codes.h" // LL_MCODE_END
+#include "llviewerstats.h"
extern const LLUUID ANIM_AGENT_BODY_NOISE;
extern const LLUUID ANIM_AGENT_BREATHE_ROT;
@@ -61,30 +64,30 @@ extern const LLUUID ANIM_AGENT_PELVIS_FIX;
extern const LLUUID ANIM_AGENT_TARGET;
extern const LLUUID ANIM_AGENT_WALK_ADJUST;
-class LLTexLayerSet;
+class LLViewerWearable;
class LLVoiceVisualizer;
class LLHUDNameTag;
class LLHUDEffectSpiral;
class LLTexGlobalColor;
-class LLVOAvatarBoneInfo;
-class LLVOAvatarSkeletonInfo;
+struct LLVOAvatarBoneInfo;
+struct LLVOAvatarChildJoint;
+//class LLViewerJoint;
+struct LLAppearanceMessageContents;
+struct LLVOAvatarSkeletonInfo;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// LLVOAvatar
//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class LLVOAvatar :
+ public LLAvatarAppearance,
public LLViewerObject,
- public LLCharacter,
public boost::signals2::trackable
{
LOG_CLASS(LLVOAvatar);
public:
friend class LLVOAvatarSelf;
-protected:
- struct LLVOAvatarXmlInfo;
- struct LLMaskedMorph;
/********************************************************************************
** **
@@ -92,6 +95,16 @@ protected:
**/
public:
+ void* operator new(size_t size)
+ {
+ return ll_aligned_malloc_16(size);
+ }
+
+ void operator delete(void* ptr)
+ {
+ ll_aligned_free_16(ptr);
+ }
+
LLVOAvatar(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp);
virtual void markDead();
static void initClass(); // Initialize data that's only init'd once per class.
@@ -99,9 +112,6 @@ public:
virtual void initInstance(); // Called after construction to initialize the class.
protected:
virtual ~LLVOAvatar();
- BOOL loadSkeletonNode();
- BOOL loadMeshNodes();
- virtual BOOL loadLayersets();
/** Initialization
** **
@@ -116,61 +126,71 @@ protected:
// LLViewerObject interface and related
//--------------------------------------------------------------------
public:
- virtual void updateGL();
- virtual LLVOAvatar* asAvatar();
+ /*virtual*/ void updateGL();
+ /*virtual*/ LLVOAvatar* asAvatar();
virtual U32 processUpdateMessage(LLMessageSystem *mesgsys,
void **user_data,
U32 block_num,
const EObjectUpdateType update_type,
LLDataPacker *dp);
- virtual BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time);
- virtual BOOL updateLOD();
+ virtual void idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time);
+ /*virtual*/ BOOL updateLOD();
BOOL updateJointLODs();
void updateLODRiggedAttachments( void );
- virtual BOOL isActive() const; // Whether this object needs to do an idleUpdate.
- virtual void updateTextures();
- virtual S32 setTETexture(const U8 te, const LLUUID& uuid); // If setting a baked texture, need to request it from a non-local sim.
- virtual void onShift(const LLVector4a& shift_vector);
- virtual U32 getPartitionType() const;
- virtual const LLVector3 getRenderPosition() const;
- virtual void updateDrawable(BOOL force_damped);
- virtual LLDrawable* createDrawable(LLPipeline *pipeline);
- virtual BOOL updateGeometry(LLDrawable *drawable);
- virtual void setPixelAreaAndAngle(LLAgent &agent);
- virtual void updateRegion(LLViewerRegion *regionp);
- virtual void updateSpatialExtents(LLVector4a& newMin, LLVector4a &newMax);
- virtual void getSpatialExtents(LLVector4a& newMin, LLVector4a& newMax);
- virtual BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end,
+ /*virtual*/ BOOL isActive() const; // Whether this object needs to do an idleUpdate.
+ S32 totalTextureMemForUUIDS(std::set<LLUUID>& ids);
+ bool allTexturesCompletelyDownloaded(std::set<LLUUID>& ids) const;
+ bool allLocalTexturesCompletelyDownloaded() const;
+ bool allBakedTexturesCompletelyDownloaded() const;
+ void bakedTextureOriginCounts(S32 &sb_count, S32 &host_count,
+ S32 &both_count, S32 &neither_count);
+ std::string bakedTextureOriginInfo();
+ void collectLocalTextureUUIDs(std::set<LLUUID>& ids) const;
+ void collectBakedTextureUUIDs(std::set<LLUUID>& ids) const;
+ void collectTextureUUIDs(std::set<LLUUID>& ids);
+ void releaseOldTextures();
+ /*virtual*/ void updateTextures();
+ LLViewerFetchedTexture* getBakedTextureImage(const U8 te, const LLUUID& uuid);
+ /*virtual*/ S32 setTETexture(const U8 te, const LLUUID& uuid); // If setting a baked texture, need to request it from a non-local sim.
+ /*virtual*/ void onShift(const LLVector4a& shift_vector);
+ /*virtual*/ U32 getPartitionType() const;
+ /*virtual*/ const LLVector3 getRenderPosition() const;
+ /*virtual*/ void updateDrawable(BOOL force_damped);
+ /*virtual*/ LLDrawable* createDrawable(LLPipeline *pipeline);
+ /*virtual*/ BOOL updateGeometry(LLDrawable *drawable);
+ /*virtual*/ void setPixelAreaAndAngle(LLAgent &agent);
+ /*virtual*/ void updateRegion(LLViewerRegion *regionp);
+ /*virtual*/ void updateSpatialExtents(LLVector4a& newMin, LLVector4a &newMax);
+ /*virtual*/ void getSpatialExtents(LLVector4a& newMin, LLVector4a& newMax);
+ /*virtual*/ BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
S32 face = -1, // which face to check, -1 = ALL_SIDES
BOOL pick_transparent = FALSE,
S32* face_hit = NULL, // which face was hit
- LLVector3* intersection = NULL, // return the intersection point
+ LLVector4a* intersection = NULL, // return the intersection point
LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
- LLVector3* normal = NULL, // return the surface normal at the intersection point
- LLVector3* bi_normal = NULL); // return the surface bi-normal at the intersection point
- LLViewerObject* lineSegmentIntersectRiggedAttachments(const LLVector3& start, const LLVector3& end,
+ LLVector4a* normal = NULL, // return the surface normal at the intersection point
+ LLVector4a* tangent = NULL); // return the surface tangent at the intersection point
+ LLViewerObject* lineSegmentIntersectRiggedAttachments(const LLVector4a& start, const LLVector4a& end,
S32 face = -1, // which face to check, -1 = ALL_SIDES
BOOL pick_transparent = FALSE,
S32* face_hit = NULL, // which face was hit
- LLVector3* intersection = NULL, // return the intersection point
+ LLVector4a* intersection = NULL, // return the intersection point
LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
- LLVector3* normal = NULL, // return the surface normal at the intersection point
- LLVector3* bi_normal = NULL); // return the surface bi-normal at the intersection point
+ LLVector4a* normal = NULL, // return the surface normal at the intersection point
+ LLVector4a* tangent = NULL); // return the surface tangent at the intersection point
//--------------------------------------------------------------------
// LLCharacter interface and related
//--------------------------------------------------------------------
public:
- virtual LLVector3 getCharacterPosition();
- virtual LLQuaternion getCharacterRotation();
- virtual LLVector3 getCharacterVelocity();
- virtual LLVector3 getCharacterAngularVelocity();
- virtual LLJoint* getCharacterJoint(U32 num);
- virtual BOOL allocateCharacterJoints(U32 num);
-
- virtual LLUUID remapMotionID(const LLUUID& id);
- virtual BOOL startMotion(const LLUUID& id, F32 time_offset = 0.f);
- virtual BOOL stopMotion(const LLUUID& id, BOOL stop_immediate = FALSE);
+ /*virtual*/ LLVector3 getCharacterPosition();
+ /*virtual*/ LLQuaternion getCharacterRotation();
+ /*virtual*/ LLVector3 getCharacterVelocity();
+ /*virtual*/ LLVector3 getCharacterAngularVelocity();
+
+ /*virtual*/ LLUUID remapMotionID(const LLUUID& id);
+ /*virtual*/ BOOL startMotion(const LLUUID& id, F32 time_offset = 0.f);
+ /*virtual*/ BOOL stopMotion(const LLUUID& id, BOOL stop_immediate = FALSE);
virtual void stopMotionFromSource(const LLUUID& source_id);
virtual void requestStopMotion(LLMotion* motion);
LLMotion* findMotion(const LLUUID& id) const;
@@ -178,25 +198,18 @@ public:
void dumpAnimationState();
virtual LLJoint* getJoint(const std::string &name);
- virtual LLJoint* getRootJoint() { return &mRoot; }
void resetJointPositions( void );
void resetJointPositionsToDefault( void );
void resetSpecificJointPosition( const std::string& name );
- virtual const char* getAnimationPrefix() { return "avatar"; }
- virtual const LLUUID& getID() const;
- virtual LLVector3 getVolumePos(S32 joint_index, LLVector3& volume_offset);
- virtual LLJoint* findCollisionVolume(U32 volume_id);
- virtual S32 getCollisionVolumeID(std::string &name);
- virtual void addDebugText(const std::string& text);
- virtual F32 getTimeDilation();
- virtual void getGround(const LLVector3 &inPos, LLVector3 &outPos, LLVector3 &outNorm);
- virtual F32 getPixelArea() const;
- virtual LLPolyMesh* getHeadMesh();
- virtual LLPolyMesh* getUpperBodyMesh();
- virtual LLVector3d getPosGlobalFromAgent(const LLVector3 &position);
- virtual LLVector3 getPosAgentFromGlobal(const LLVector3d &position);
+ /*virtual*/ const LLUUID& getID() const;
+ /*virtual*/ void addDebugText(const std::string& text);
+ /*virtual*/ F32 getTimeDilation();
+ /*virtual*/ void getGround(const LLVector3 &inPos, LLVector3 &outPos, LLVector3 &outNorm);
+ /*virtual*/ F32 getPixelArea() const;
+ /*virtual*/ LLVector3d getPosGlobalFromAgent(const LLVector3 &position);
+ /*virtual*/ LLVector3 getPosAgentFromGlobal(const LLVector3d &position);
virtual void updateVisualParams();
@@ -211,13 +224,9 @@ public:
public:
virtual bool isSelf() const { return false; } // True if this avatar is for this viewer's agent
- bool isBuilt() const { return mIsBuilt; }
private: //aligned members
- LLVector4a mImpostorExtents[2];
-
-private:
- BOOL mSupportsAlphaLayers; // For backwards compatibility, TRUE for 1.23+ clients
+ LL_ALIGN_16(LLVector4a mImpostorExtents[2]);
//--------------------------------------------------------------------
// Updates
@@ -232,7 +241,7 @@ public:
void idleUpdateWindEffect();
void idleUpdateNameTag(const LLVector3& root_pos_last);
void idleUpdateNameTagText(BOOL new_name);
- LLVector3 idleUpdateNameTagPosition(const LLVector3& root_pos_last);
+ void idleUpdateNameTagPosition(const LLVector3& root_pos_last);
void idleUpdateNameTagAlpha(BOOL new_name, F32 alpha);
LLColor4 getNameTagColor(bool is_friend);
void clearNameTag();
@@ -241,6 +250,20 @@ public:
static void invalidateNameTags();
void addNameTagLine(const std::string& line, const LLColor4& color, S32 style, const LLFontGL* font);
void idleUpdateRenderCost();
+ void calculateUpdateRenderCost();
+ void updateVisualComplexity() { mVisualComplexityStale = TRUE; }
+
+ S32 getVisualComplexity() { return mVisualComplexity; }; // Numbers calculated here by rendering AV
+ S32 getAttachmentGeometryBytes() { return mAttachmentGeometryBytes; }; // number of bytes in attached geometry
+ F32 getAttachmentSurfaceArea() { return mAttachmentSurfaceArea; }; // estimated surface area of attachments
+
+ S32 getReportedVisualComplexity() { return mReportedVisualComplexity; }; // Numbers as reported by the SL server
+ void setReportedVisualComplexity(S32 value) { mReportedVisualComplexity = value; };
+
+ S32 getUpdatePeriod() { return mUpdatePeriod; };
+ const LLColor4 & getMutedAVColor() { return mMutedAVColor; };
+
+
void idleUpdateBelowWater();
//--------------------------------------------------------------------
@@ -277,99 +300,82 @@ public:
public:
BOOL isFullyLoaded() const;
bool isTooComplex() const;
- bool visualParamWeightsAreDefault();
+ bool visualParamWeightsAreDefault();
+ virtual BOOL getIsCloud() const;
+ BOOL isFullyTextured() const;
+ BOOL hasGray() const;
+ S32 getRezzedStatus() const; // 0 = cloud, 1 = gray, 2 = textured, 3 = textured and fully downloaded.
+ void updateRezzedStatusTimers();
+
+ S32 mLastRezzedStatus;
+
+
+ void startPhase(const std::string& phase_name);
+ void stopPhase(const std::string& phase_name, bool err_check = true);
+ void clearPhases();
+ void logPendingPhases();
+ static void logPendingPhasesAllAvatars();
+ void logMetricsTimerRecord(const std::string& phase_name, F32 elapsed, bool completed);
+
+ static LLColor4 calcMutedAVColor(F32 value, S32 range_low, S32 range_high);
+
protected:
- virtual BOOL getIsCloud();
+ LLViewerStats::PhaseMap& getPhases() { return mPhases; }
BOOL updateIsFullyLoaded();
BOOL processFullyLoadedChange(bool loading);
void updateRuthTimer(bool loading);
F32 calcMorphAmount();
+
private:
+ BOOL mFirstFullyVisible;
BOOL mFullyLoaded;
BOOL mPreviousFullyLoaded;
BOOL mFullyLoadedInitialized;
S32 mFullyLoadedFrameCounter;
S32 mVisualComplexity;
+ BOOL mVisualComplexityStale;
+ LLColor4 mMutedAVColor;
LLFrameTimer mFullyLoadedTimer;
LLFrameTimer mRuthTimer;
+
+private:
+ LLViewerStats::PhaseMap mPhases;
+
protected:
LLFrameTimer mInvisibleTimer;
/** State
** **
*******************************************************************************/
-
/********************************************************************************
** **
** SKELETON
**/
+protected:
+ /*virtual*/ LLAvatarJoint* createAvatarJoint(); // Returns LLViewerJoint
+ /*virtual*/ LLAvatarJoint* createAvatarJoint(S32 joint_num); // Returns LLViewerJoint
+ /*virtual*/ LLAvatarJointMesh* createAvatarJointMesh(); // Returns LLViewerJointMesh
public:
void updateHeadOffset();
- F32 getPelvisToFoot() const { return mPelvisToFoot; }
void setPelvisOffset( bool hasOffset, const LLVector3& translation, F32 offset ) ;
bool hasPelvisOffset( void ) { return mHasPelvisOffset; }
void postPelvisSetRecalc( void );
void setPelvisOffset( F32 pelvixFixupAmount );
+ /*virtual*/ BOOL loadSkeletonNode();
+ /*virtual*/ void buildCharacter();
+
bool mHasPelvisOffset;
LLVector3 mPelvisOffset;
F32 mLastPelvisToFoot;
F32 mPelvisFixup;
F32 mLastPelvisFixup;
+ LLVector3 mCurRootToHeadOffset;
+ LLVector3 mTargetRootToHeadOffset;
- LLVector3 mHeadOffset; // current head position
- LLViewerJoint mRoot;
-protected:
- static BOOL parseSkeletonFile(const std::string& filename);
- void buildCharacter();
- virtual BOOL loadAvatar();
-
- BOOL setupBone(const LLVOAvatarBoneInfo* info, LLViewerJoint* parent, S32 &current_volume_num, S32 &current_joint_num);
- BOOL buildSkeleton(const LLVOAvatarSkeletonInfo *info);
-private:
- BOOL mIsBuilt; // state of deferred character building
- S32 mNumJoints;
- LLViewerJoint* mSkeleton;
-
- //--------------------------------------------------------------------
- // Pelvis height adjustment members.
- //--------------------------------------------------------------------
-public:
- LLVector3 mBodySize;
S32 mLastSkeletonSerialNum;
-private:
- F32 mPelvisToFoot;
- //--------------------------------------------------------------------
- // Cached pointers to well known joints
- //--------------------------------------------------------------------
-public:
- LLViewerJoint* mPelvisp;
- LLViewerJoint* mTorsop;
- LLViewerJoint* mChestp;
- LLViewerJoint* mNeckp;
- LLViewerJoint* mHeadp;
- LLViewerJoint* mSkullp;
- LLViewerJoint* mEyeLeftp;
- LLViewerJoint* mEyeRightp;
- LLViewerJoint* mHipLeftp;
- LLViewerJoint* mHipRightp;
- LLViewerJoint* mKneeLeftp;
- LLViewerJoint* mKneeRightp;
- LLViewerJoint* mAnkleLeftp;
- LLViewerJoint* mAnkleRightp;
- LLViewerJoint* mFootLeftp;
- LLViewerJoint* mFootRightp;
- LLViewerJoint* mWristLeftp;
- LLViewerJoint* mWristRightp;
-
- //--------------------------------------------------------------------
- // XML parse tree
- //--------------------------------------------------------------------
-private:
- static LLXmlTree sXMLTree; // avatar config file
- static LLXmlTree sSkeletonXMLTree; // avatar skeleton file
/** Skeleton
** **
@@ -382,22 +388,33 @@ private:
public:
U32 renderImpostor(LLColor4U color = LLColor4U(255,255,255,255), S32 diffuse_channel = 0);
- bool isVisuallyMuted() const;
+ bool isVisuallyMuted();
+ void setCachedVisualMute(bool muted) { mCachedVisualMute = muted; };
+ void forceUpdateVisualMuteSettings();
+
+ enum VisualMuteSettings
+ {
+ VISUAL_MUTE_NOT_SET = 0,
+ ALWAYS_VISUAL_MUTE = 1,
+ NEVER_VISUAL_MUTE = 2
+ };
+ void setVisualMuteSettings(VisualMuteSettings set) { mVisuallyMuteSetting = set; };
+ VisualMuteSettings getVisualMuteSettings() { return mVisuallyMuteSetting; };
U32 renderRigid();
U32 renderSkinned(EAvatarRenderPass pass);
F32 getLastSkinTime() { return mLastSkinTime; }
- U32 renderSkinnedAttachments();
U32 renderTransparent(BOOL first_pass);
void renderCollisionVolumes();
static void deleteCachedImages(bool clearAll=true);
static void destroyGL();
static void restoreGL();
- BOOL mIsDummy; // for special views
S32 mSpecialRenderMode; // special lighting
- U32 mAttachmentGeometryBytes; //number of bytes in attached geometry
+ S32 mAttachmentGeometryBytes; //number of bytes in attached geometry
F32 mAttachmentSurfaceArea; //estimated surface area of attachments
+ S32 mReportedVisualComplexity; // Numbers as reported by the SL server
+
private:
bool shouldAlphaMask();
@@ -407,13 +424,24 @@ private:
S32 mUpdatePeriod;
S32 mNumInitFaces; //number of faces generated when creating the avatar drawable, does not inculde splitted faces due to long vertex buffer.
+ bool mCachedVisualMute; // cached return value for isVisuallyMuted()
+ F64 mCachedVisualMuteUpdateTime; // Time to update mCachedVisualMute
+
+ VisualMuteSettings mVisuallyMuteSetting; // Always or never visually mute this AV
+
//--------------------------------------------------------------------
// Morph masks
//--------------------------------------------------------------------
public:
- BOOL morphMaskNeedsUpdate(LLVOAvatarDefines::EBakedTextureIndex index = LLVOAvatarDefines::BAKED_NUM_INDICES);
- void addMaskedMorph(LLVOAvatarDefines::EBakedTextureIndex index, LLPolyMorphTarget* morph_target, BOOL invert, std::string layer);
- void applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_components, LLVOAvatarDefines::EBakedTextureIndex index = LLVOAvatarDefines::BAKED_NUM_INDICES);
+ /*virtual*/ void applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_components, LLAvatarAppearanceDefines::EBakedTextureIndex index = LLAvatarAppearanceDefines::BAKED_NUM_INDICES);
+ BOOL morphMaskNeedsUpdate(LLAvatarAppearanceDefines::EBakedTextureIndex index = LLAvatarAppearanceDefines::BAKED_NUM_INDICES);
+
+
+ //--------------------------------------------------------------------
+ // Global colors
+ //--------------------------------------------------------------------
+public:
+ /*virtual*/void onGlobalColorChanged(const LLTexGlobalColor* global_color, BOOL upload_bake);
//--------------------------------------------------------------------
// Visibility
@@ -439,7 +467,7 @@ private:
// Impostors
//--------------------------------------------------------------------
public:
- BOOL isImpostor() const;
+ BOOL isImpostor();
BOOL needsImpostorUpdate() const;
const LLVector3& getImpostorOffset() const;
const LLVector2& getImpostorDim() const;
@@ -496,10 +524,10 @@ private:
// Constants
//--------------------------------------------------------------------
public:
- virtual LLViewerTexture::EBoostLevel getAvatarBoostLevel() const { return LLViewerTexture::BOOST_AVATAR; }
- virtual LLViewerTexture::EBoostLevel getAvatarBakedBoostLevel() const { return LLViewerTexture::BOOST_AVATAR_BAKED; }
+ virtual LLViewerTexture::EBoostLevel getAvatarBoostLevel() const { return LLGLTexture::BOOST_AVATAR; }
+ virtual LLViewerTexture::EBoostLevel getAvatarBakedBoostLevel() const { return LLGLTexture::BOOST_AVATAR_BAKED; }
virtual S32 getTexImageSize() const;
- virtual S32 getTexImageArea() const { return getTexImageSize()*getTexImageSize(); }
+ /*virtual*/ S32 getTexImageArea() const { return getTexImageSize()*getTexImageSize(); }
/** Rendering
** **
@@ -514,18 +542,20 @@ public:
// Loading status
//--------------------------------------------------------------------
public:
- virtual BOOL isTextureDefined(LLVOAvatarDefines::ETextureIndex type, U32 index = 0) const;
- virtual BOOL isTextureVisible(LLVOAvatarDefines::ETextureIndex type, U32 index = 0) const;
- virtual BOOL isTextureVisible(LLVOAvatarDefines::ETextureIndex type, LLWearable *wearable) const;
+ virtual BOOL isTextureDefined(LLAvatarAppearanceDefines::ETextureIndex type, U32 index = 0) const;
+ virtual BOOL isTextureVisible(LLAvatarAppearanceDefines::ETextureIndex type, U32 index = 0) const;
+ virtual BOOL isTextureVisible(LLAvatarAppearanceDefines::ETextureIndex type, LLViewerWearable *wearable) const;
-protected:
BOOL isFullyBaked();
static BOOL areAllNearbyInstancesBaked(S32& grey_avatars);
+ static void getNearbyRezzedStats(std::vector<S32>& counts);
+ static std::string rezStatusToString(S32 status);
//--------------------------------------------------------------------
// Baked textures
//--------------------------------------------------------------------
public:
+ /*virtual*/ LLTexLayerSet* createTexLayerSet(); // Return LLViewerTexLayerSet
void releaseComponentTextures(); // ! BACKWARDS COMPATIBILITY !
protected:
static void onBakedTextureMasksLoaded(BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata);
@@ -533,32 +563,20 @@ protected:
static void onBakedTextureLoaded(BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata);
virtual void removeMissingBakedTextures();
void useBakedTexture(const LLUUID& id);
+ LLViewerTexLayerSet* getTexLayerSet(const U32 index) const { return dynamic_cast<LLViewerTexLayerSet*>(mBakedTextureDatas[index].mTexLayerSet); }
+
- typedef std::deque<LLMaskedMorph *> morph_list_t;
- struct BakedTextureData
- {
- LLUUID mLastTextureIndex;
- LLTexLayerSet* mTexLayerSet; // Only exists for self
- bool mIsLoaded;
- bool mIsUsed;
- LLVOAvatarDefines::ETextureIndex mTextureIndex;
- U32 mMaskTexName;
- // Stores pointers to the joint meshes that this baked texture deals with
- std::vector< LLViewerJointMesh * > mMeshes; // std::vector<LLViewerJointMesh> mJoints[i]->mMeshParts
- morph_list_t mMaskedMorphs;
- };
- typedef std::vector<BakedTextureData> bakedtexturedata_vec_t;
- bakedtexturedata_vec_t mBakedTextureDatas;
LLLoadedCallbackEntry::source_callback_list_t mCallbackTextureList ;
BOOL mLoadedCallbacksPaused;
+ std::set<LLUUID> mTextureIDs;
//--------------------------------------------------------------------
// Local Textures
//--------------------------------------------------------------------
protected:
- virtual void setLocalTexture(LLVOAvatarDefines::ETextureIndex type, LLViewerTexture* tex, BOOL baked_version_exits, U32 index = 0);
- virtual void addLocalTextureStats(LLVOAvatarDefines::ETextureIndex type, LLViewerFetchedTexture* imagep, F32 texel_area_ratio, BOOL rendered, BOOL covered_by_baked, U32 index = 0);
+ virtual void setLocalTexture(LLAvatarAppearanceDefines::ETextureIndex type, LLViewerTexture* tex, BOOL baked_version_exits, U32 index = 0);
+ virtual void addLocalTextureStats(LLAvatarAppearanceDefines::ETextureIndex type, LLViewerFetchedTexture* imagep, F32 texel_area_ratio, BOOL rendered, BOOL covered_by_baked);
// MULTI-WEARABLE: make self-only?
- virtual void setBakedReady(LLVOAvatarDefines::ETextureIndex type, BOOL baked_version_exists, U32 index = 0);
+ virtual void setBakedReady(LLAvatarAppearanceDefines::ETextureIndex type, BOOL baked_version_exists, U32 index = 0);
//--------------------------------------------------------------------
// Texture accessors
@@ -566,6 +584,7 @@ protected:
private:
virtual void setImage(const U8 te, LLViewerTexture *imagep, const U32 index);
virtual LLViewerTexture* getImage(const U8 te, const U32 index) const;
+ const std::string getImageURL(const U8 te, const LLUUID &uuid);
virtual const LLTextureEntry* getTexEntry(const U8 te_num) const;
virtual void setTexEntry(const U8 index, const LLTextureEntry &te);
@@ -592,13 +611,11 @@ public:
// Static texture/mesh/baked dictionary
//--------------------------------------------------------------------
public:
- static BOOL isIndexLocalTexture(LLVOAvatarDefines::ETextureIndex i);
- static BOOL isIndexBakedTexture(LLVOAvatarDefines::ETextureIndex i);
+ static BOOL isIndexLocalTexture(LLAvatarAppearanceDefines::ETextureIndex i);
+ static BOOL isIndexBakedTexture(LLAvatarAppearanceDefines::ETextureIndex i);
private:
- static const LLVOAvatarDefines::LLVOAvatarDictionary *getDictionary() { return sAvatarDictionary; }
- static LLVOAvatarDefines::LLVOAvatarDictionary* sAvatarDictionary;
- static LLVOAvatarSkeletonInfo* sAvatarSkeletonInfo;
- static LLVOAvatarXmlInfo* sAvatarXmlInfo;
+ static const LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary *getDictionary() { return sAvatarDictionary; }
+ static LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary* sAvatarDictionary;
//--------------------------------------------------------------------
// Messaging
@@ -619,22 +636,20 @@ private:
**/
public:
- void updateMeshTextures();
+ void debugColorizeSubMeshes(U32 i, const LLColor4& color);
+ virtual void updateMeshTextures();
void updateSexDependentLayerSets(BOOL upload_bake);
- void dirtyMesh(); // Dirty the avatar mesh
+ virtual void dirtyMesh(); // Dirty the avatar mesh
void updateMeshData();
protected:
void releaseMeshData();
virtual void restoreMeshData();
private:
- void dirtyMesh(S32 priority); // Dirty the avatar mesh, with priority
+ virtual void dirtyMesh(S32 priority); // Dirty the avatar mesh, with priority
+ LLViewerJoint* getViewerJoint(S32 idx);
S32 mDirtyMesh; // 0 -- not dirty, 1 -- morphed, 2 -- LOD
BOOL mMeshTexturesDirty;
- typedef std::multimap<std::string, LLPolyMesh*> polymesh_map_t;
- polymesh_map_t mMeshes;
- std::vector<LLViewerJoint *> mMeshLOD;
-
//--------------------------------------------------------------------
// Destroy invisible mesh
//--------------------------------------------------------------------
@@ -652,38 +667,42 @@ protected:
**/
public:
+ void parseAppearanceMessage(LLMessageSystem* mesgsys, LLAppearanceMessageContents& msg);
void processAvatarAppearance(LLMessageSystem* mesgsys);
void hideSkirt();
void startAppearanceAnimation();
+ /*virtual*/ void bodySizeChanged();
//--------------------------------------------------------------------
// Appearance morphing
//--------------------------------------------------------------------
public:
BOOL getIsAppearanceAnimating() const { return mAppearanceAnimating; }
+
+ // True if we are computing our appearance via local compositing
+ // instead of baked textures, as for example during wearable
+ // editing or when waiting for a subsequent server rebake.
+ /*virtual*/ BOOL isUsingLocalAppearance() const { return mUseLocalAppearance; }
+
+ // True if this avatar should fetch its baked textures via the new
+ // appearance mechanism.
+ BOOL isUsingServerBakes() const;
+ void setIsUsingServerBakes(BOOL newval);
+
+
+ // True if we are currently in appearance editing mode. Often but
+ // not always the same as isUsingLocalAppearance().
+ /*virtual*/ BOOL isEditingAppearance() const { return mIsEditingAppearance; }
+
+ // FIXME review isUsingLocalAppearance uses, some should be isEditing instead.
+
private:
BOOL mAppearanceAnimating;
LLFrameTimer mAppearanceMorphTimer;
F32 mLastAppearanceBlendTime;
-
- //--------------------------------------------------------------------
- // Clothing colors (convenience functions to access visual parameters)
- //--------------------------------------------------------------------
-public:
- void setClothesColor(LLVOAvatarDefines::ETextureIndex te, const LLColor4& new_color, BOOL upload_bake);
- LLColor4 getClothesColor(LLVOAvatarDefines::ETextureIndex te);
- static BOOL teToColorParams(LLVOAvatarDefines::ETextureIndex te, U32 *param_name);
-
- //--------------------------------------------------------------------
- // Global colors
- //--------------------------------------------------------------------
-public:
- LLColor4 getGlobalColor(const std::string& color_name ) const;
- void onGlobalColorChanged(const LLTexGlobalColor* global_color, BOOL upload_bake);
-private:
- LLTexGlobalColor* mTexSkinColor;
- LLTexGlobalColor* mTexHairColor;
- LLTexGlobalColor* mTexEyeColor;
+ BOOL mIsEditingAppearance; // flag for if we're actively in appearance editing mode
+ BOOL mUseLocalAppearance; // flag for if we're using a local composite
+ BOOL mUseServerBakes; // flag for if baked textures should be fetched from baking service (false if they're temporary uploads)
//--------------------------------------------------------------------
// Visibility
@@ -693,7 +712,6 @@ public:
void setVisibilityRank(U32 rank);
U32 getVisibilityRank() const { return mVisibilityRank; } // unused
static S32 sNumVisibleAvatars; // Number of instances of this class
- static LLColor4 getDummyColor();
/** Appearance
** **
*******************************************************************************/
@@ -703,9 +721,6 @@ public:
** WEARABLES
**/
-public:
- virtual BOOL isWearingWearableType(LLWearableType::EType type ) const;
-
//--------------------------------------------------------------------
// Attachments
//--------------------------------------------------------------------
@@ -715,6 +730,9 @@ public:
virtual BOOL detachObject(LLViewerObject *viewer_object);
void cleanupAttachedMesh( LLViewerObject* pVO );
static LLVOAvatar* findAvatarFromAttachment(LLViewerObject* obj);
+ /*virtual*/ BOOL isWearingWearableType(LLWearableType::EType type ) const;
+ LLViewerObject * findAttachmentByID( const LLUUID & target_id ) const;
+
protected:
LLViewerJointAttachment* getTargetAttachmentPoint(LLViewerObject* viewer_object);
void lazyAttach();
@@ -735,7 +753,6 @@ public:
public:
BOOL hasHUDAttachment() const;
LLBBox getHUDBBox() const;
- void rebuildHUD();
void resetHUDAttachments();
BOOL canAttachMoreObjects() const;
BOOL canAttachMoreObjects(U32 n) const;
@@ -817,15 +834,6 @@ private:
F32 mSpeed; // misc. animation repeated state
//--------------------------------------------------------------------
- // Collision volumes
- //--------------------------------------------------------------------
-public:
- S32 mNumCollisionVolumes;
- LLViewerJointCollisionVolume* mCollisionVolumes;
-protected:
- BOOL allocateCollisionVolumes(U32 num);
-
- //--------------------------------------------------------------------
// Dimensions
//--------------------------------------------------------------------
public:
@@ -835,7 +843,6 @@ public:
void resolveRayCollisionAgent(const LLVector3d start_pt, const LLVector3d end_pt, LLVector3d &out_pos, LLVector3 &out_norm);
void slamPosition(); // Slam position to transmitted position (for teleport);
protected:
- void computeBodySize();
//--------------------------------------------------------------------
// Material being stepped on
@@ -855,9 +862,9 @@ private:
**/
public:
- virtual BOOL setParent(LLViewerObject* parent);
- virtual void addChild(LLViewerObject *childp);
- virtual void removeChild(LLViewerObject *childp);
+ /*virtual*/ BOOL setParent(LLViewerObject* parent);
+ /*virtual*/ void addChild(LLViewerObject *childp);
+ /*virtual*/ void removeChild(LLViewerObject *childp);
//--------------------------------------------------------------------
// Sitting
@@ -882,14 +889,15 @@ private:
public:
std::string getFullname() const; // Returns "FirstName LastName"
+ std::string avString() const; // Frequently used string in log messages "Avatar '<full name'"
protected:
static void getAnimLabels(LLDynamicArray<std::string>* labels);
static void getAnimNames(LLDynamicArray<std::string>* names);
private:
- std::string mNameString; // UTF-8 title + name + status
+ bool mNameIsSet;
std::string mTitle;
bool mNameAway;
- bool mNameBusy;
+ bool mNameDoNotDisturb;
bool mNameMute;
bool mNameAppearance;
bool mNameFriend;
@@ -960,7 +968,9 @@ private:
// General
//--------------------------------------------------------------------
public:
- static void dumpArchetypeXML(void*);
+ void dumpArchetypeXML(const std::string& prefix, bool group_by_wearables = false);
+ void dumpAppearanceMsgParams( const std::string& dump_prefix,
+ const LLAppearanceMessageContents& contents);
static void dumpBakedStatus();
const std::string getBakedStatusForPrintout() const;
void dumpAvatarTEs(const std::string& context) const;
@@ -977,17 +987,31 @@ private:
F32 mMaxPixelArea;
F32 mAdjustedPixelArea;
std::string mDebugText;
+ std::string mBakedTextureDebugText;
//--------------------------------------------------------------------
// Avatar Rez Metrics
//--------------------------------------------------------------------
public:
+ void debugAvatarRezTime(std::string notification_name, std::string comment = "");
F32 debugGetExistenceTimeElapsedF32() const { return mDebugExistenceTimer.getElapsedTimeF32(); }
+
protected:
LLFrameTimer mRuthDebugTimer; // For tracking how long it takes for av to rez
LLFrameTimer mDebugExistenceTimer; // Debugging for how long the avatar has been in memory.
+ //--------------------------------------------------------------------
+ // COF monitoring
+ //--------------------------------------------------------------------
+
+public:
+ // COF version of last viewer-initiated appearance update request. For non-self avs, this will remain at default.
+ S32 mLastUpdateRequestCOFVersion;
+
+ // COF version of last appearance message received for this av.
+ S32 mLastUpdateReceivedCOFVersion;
+
/** Diagnostics
** **
*******************************************************************************/
@@ -999,105 +1023,6 @@ protected:
protected: // Shared with LLVOAvatarSelf
- struct LLVOAvatarXmlInfo
- {
- LLVOAvatarXmlInfo();
- ~LLVOAvatarXmlInfo();
-
- BOOL parseXmlSkeletonNode(LLXmlTreeNode* root);
- BOOL parseXmlMeshNodes(LLXmlTreeNode* root);
- BOOL parseXmlColorNodes(LLXmlTreeNode* root);
- BOOL parseXmlLayerNodes(LLXmlTreeNode* root);
- BOOL parseXmlDriverNodes(LLXmlTreeNode* root);
- BOOL parseXmlMorphNodes(LLXmlTreeNode* root);
-
- struct LLVOAvatarMeshInfo
- {
- typedef std::pair<LLPolyMorphTargetInfo*,BOOL> morph_info_pair_t;
- typedef std::vector<morph_info_pair_t> morph_info_list_t;
-
- LLVOAvatarMeshInfo() : mLOD(0), mMinPixelArea(.1f) {}
- ~LLVOAvatarMeshInfo()
- {
- morph_info_list_t::iterator iter;
- for (iter = mPolyMorphTargetInfoList.begin(); iter != mPolyMorphTargetInfoList.end(); iter++)
- {
- delete iter->first;
- }
- mPolyMorphTargetInfoList.clear();
- }
-
- std::string mType;
- S32 mLOD;
- std::string mMeshFileName;
- std::string mReferenceMeshName;
- F32 mMinPixelArea;
- morph_info_list_t mPolyMorphTargetInfoList;
- };
- typedef std::vector<LLVOAvatarMeshInfo*> mesh_info_list_t;
- mesh_info_list_t mMeshInfoList;
-
- typedef std::vector<LLPolySkeletalDistortionInfo*> skeletal_distortion_info_list_t;
- skeletal_distortion_info_list_t mSkeletalDistortionInfoList;
-
- struct LLVOAvatarAttachmentInfo
- {
- LLVOAvatarAttachmentInfo()
- : mGroup(-1), mAttachmentID(-1), mPieMenuSlice(-1), mVisibleFirstPerson(FALSE),
- mIsHUDAttachment(FALSE), mHasPosition(FALSE), mHasRotation(FALSE) {}
- std::string mName;
- std::string mJointName;
- LLVector3 mPosition;
- LLVector3 mRotationEuler;
- S32 mGroup;
- S32 mAttachmentID;
- S32 mPieMenuSlice;
- BOOL mVisibleFirstPerson;
- BOOL mIsHUDAttachment;
- BOOL mHasPosition;
- BOOL mHasRotation;
- };
- typedef std::vector<LLVOAvatarAttachmentInfo*> attachment_info_list_t;
- attachment_info_list_t mAttachmentInfoList;
-
- LLTexGlobalColorInfo *mTexSkinColorInfo;
- LLTexGlobalColorInfo *mTexHairColorInfo;
- LLTexGlobalColorInfo *mTexEyeColorInfo;
-
- typedef std::vector<LLTexLayerSetInfo*> layer_info_list_t;
- layer_info_list_t mLayerInfoList;
-
- typedef std::vector<LLDriverParamInfo*> driver_info_list_t;
- driver_info_list_t mDriverInfoList;
-
- struct LLVOAvatarMorphInfo
- {
- LLVOAvatarMorphInfo()
- : mInvert(FALSE) {}
- std::string mName;
- std::string mRegion;
- std::string mLayer;
- BOOL mInvert;
- };
-
- typedef std::vector<LLVOAvatarMorphInfo*> morph_info_list_t;
- morph_info_list_t mMorphMaskInfoList;
- };
-
- struct LLMaskedMorph
- {
- LLMaskedMorph(LLPolyMorphTarget *morph_target, BOOL invert, std::string layer) :
- mMorphTarget(morph_target),
- mInvert(invert),
- mLayer(layer)
- {
- morph_target->addPendingMorphMask();
- }
-
- LLPolyMorphTarget *mMorphTarget;
- BOOL mInvert;
- std::string mLayer;
- };
/** Support classes
** **
@@ -1107,4 +1032,9 @@ protected: // Shared with LLVOAvatarSelf
extern const F32 SELF_ADDITIONAL_PRI;
extern const S32 MAX_TEXTURE_VIRTURE_SIZE_RESET_INTERVAL;
-#endif // LL_VO_AVATAR_H
+std::string get_sequential_numbered_file_name(const std::string& prefix,
+ const std::string& suffix);
+void dump_visual_param(apr_file_t* file, LLVisualParam* viewer_param, F32 value);
+
+#endif // LL_VOAVATAR_H
+
diff --git a/indra/newview/llvoavatardefines.cpp b/indra/newview/llvoavatardefines.cpp
deleted file mode 100644
index 1ed4e3b61c..0000000000
--- a/indra/newview/llvoavatardefines.cpp
+++ /dev/null
@@ -1,262 +0,0 @@
-/**
- * @file llvoavatar.cpp
- * @brief Implementation of LLVOAvatar class which is a derivation fo LLViewerObject
- *
- * $LicenseInfo:firstyear=2001&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 "llviewerprecompiledheaders.h"
-#include "llvoavatardefines.h"
-#include "llviewercontrol.h" // gSavedSettings
-
-const S32 LLVOAvatarDefines::SCRATCH_TEX_WIDTH = 512;
-const S32 LLVOAvatarDefines::SCRATCH_TEX_HEIGHT = 512;
-const S32 LLVOAvatarDefines::IMPOSTOR_PERIOD = 2;
-
-using namespace LLVOAvatarDefines;
-
-/*********************************************************************************
- * Edit this function to add/remove/change textures and mesh definitions for avatars.
- */
-
-LLVOAvatarDictionary::Textures::Textures()
-{
- addEntry(TEX_HEAD_BODYPAINT, new TextureEntry("head_bodypaint", TRUE, BAKED_NUM_INDICES, "", LLWearableType::WT_SKIN));
- addEntry(TEX_UPPER_SHIRT, new TextureEntry("upper_shirt", TRUE, BAKED_NUM_INDICES, "UIImgDefaultShirtUUID", LLWearableType::WT_SHIRT));
- addEntry(TEX_LOWER_PANTS, new TextureEntry("lower_pants", TRUE, BAKED_NUM_INDICES, "UIImgDefaultPantsUUID", LLWearableType::WT_PANTS));
- addEntry(TEX_EYES_IRIS, new TextureEntry("eyes_iris", TRUE, BAKED_NUM_INDICES, "UIImgDefaultEyesUUID", LLWearableType::WT_EYES));
- addEntry(TEX_HAIR, new TextureEntry("hair_grain", TRUE, BAKED_NUM_INDICES, "UIImgDefaultHairUUID", LLWearableType::WT_HAIR));
- addEntry(TEX_UPPER_BODYPAINT, new TextureEntry("upper_bodypaint", TRUE, BAKED_NUM_INDICES, "", LLWearableType::WT_SKIN));
- addEntry(TEX_LOWER_BODYPAINT, new TextureEntry("lower_bodypaint", TRUE, BAKED_NUM_INDICES, "", LLWearableType::WT_SKIN));
- addEntry(TEX_LOWER_SHOES, new TextureEntry("lower_shoes", TRUE, BAKED_NUM_INDICES, "UIImgDefaultShoesUUID", LLWearableType::WT_SHOES));
- addEntry(TEX_LOWER_SOCKS, new TextureEntry("lower_socks", TRUE, BAKED_NUM_INDICES, "UIImgDefaultSocksUUID", LLWearableType::WT_SOCKS));
- addEntry(TEX_UPPER_JACKET, new TextureEntry("upper_jacket", TRUE, BAKED_NUM_INDICES, "UIImgDefaultJacketUUID", LLWearableType::WT_JACKET));
- addEntry(TEX_LOWER_JACKET, new TextureEntry("lower_jacket", TRUE, BAKED_NUM_INDICES, "UIImgDefaultJacketUUID", LLWearableType::WT_JACKET));
- addEntry(TEX_UPPER_GLOVES, new TextureEntry("upper_gloves", TRUE, BAKED_NUM_INDICES, "UIImgDefaultGlovesUUID", LLWearableType::WT_GLOVES));
- addEntry(TEX_UPPER_UNDERSHIRT, new TextureEntry("upper_undershirt", TRUE, BAKED_NUM_INDICES, "UIImgDefaultUnderwearUUID", LLWearableType::WT_UNDERSHIRT));
- addEntry(TEX_LOWER_UNDERPANTS, new TextureEntry("lower_underpants", TRUE, BAKED_NUM_INDICES, "UIImgDefaultUnderwearUUID", LLWearableType::WT_UNDERPANTS));
- addEntry(TEX_SKIRT, new TextureEntry("skirt", TRUE, BAKED_NUM_INDICES, "UIImgDefaultSkirtUUID", LLWearableType::WT_SKIRT));
-
- addEntry(TEX_LOWER_ALPHA, new TextureEntry("lower_alpha", TRUE, BAKED_NUM_INDICES, "UIImgDefaultAlphaUUID", LLWearableType::WT_ALPHA));
- addEntry(TEX_UPPER_ALPHA, new TextureEntry("upper_alpha", TRUE, BAKED_NUM_INDICES, "UIImgDefaultAlphaUUID", LLWearableType::WT_ALPHA));
- addEntry(TEX_HEAD_ALPHA, new TextureEntry("head_alpha", TRUE, BAKED_NUM_INDICES, "UIImgDefaultAlphaUUID", LLWearableType::WT_ALPHA));
- addEntry(TEX_EYES_ALPHA, new TextureEntry("eyes_alpha", TRUE, BAKED_NUM_INDICES, "UIImgDefaultAlphaUUID", LLWearableType::WT_ALPHA));
- addEntry(TEX_HAIR_ALPHA, new TextureEntry("hair_alpha", TRUE, BAKED_NUM_INDICES, "UIImgDefaultAlphaUUID", LLWearableType::WT_ALPHA));
-
- addEntry(TEX_HEAD_TATTOO, new TextureEntry("head_tattoo", TRUE, BAKED_NUM_INDICES, "", LLWearableType::WT_TATTOO));
- addEntry(TEX_UPPER_TATTOO, new TextureEntry("upper_tattoo", TRUE, BAKED_NUM_INDICES, "", LLWearableType::WT_TATTOO));
- addEntry(TEX_LOWER_TATTOO, new TextureEntry("lower_tattoo", TRUE, BAKED_NUM_INDICES, "", LLWearableType::WT_TATTOO));
-
- addEntry(TEX_HEAD_BAKED, new TextureEntry("head-baked", FALSE, BAKED_HEAD));
- addEntry(TEX_UPPER_BAKED, new TextureEntry("upper-baked", FALSE, BAKED_UPPER));
- addEntry(TEX_LOWER_BAKED, new TextureEntry("lower-baked", FALSE, BAKED_LOWER));
- addEntry(TEX_EYES_BAKED, new TextureEntry("eyes-baked", FALSE, BAKED_EYES));
- addEntry(TEX_HAIR_BAKED, new TextureEntry("hair-baked", FALSE, BAKED_HAIR));
- addEntry(TEX_SKIRT_BAKED, new TextureEntry("skirt-baked", FALSE, BAKED_SKIRT));
-}
-
-LLVOAvatarDictionary::BakedTextures::BakedTextures()
-{
- // Baked textures
- addEntry(BAKED_HEAD, new BakedEntry(TEX_HEAD_BAKED,
- "head", "a4b9dc38-e13b-4df9-b284-751efb0566ff",
- 3, TEX_HEAD_BODYPAINT, TEX_HEAD_TATTOO, TEX_HEAD_ALPHA,
- 5, LLWearableType::WT_SHAPE, LLWearableType::WT_SKIN, LLWearableType::WT_HAIR, LLWearableType::WT_TATTOO, LLWearableType::WT_ALPHA));
-
- addEntry(BAKED_UPPER, new BakedEntry(TEX_UPPER_BAKED,
- "upper_body", "5943ff64-d26c-4a90-a8c0-d61f56bd98d4",
- 7, TEX_UPPER_SHIRT,TEX_UPPER_BODYPAINT, TEX_UPPER_JACKET,
- TEX_UPPER_GLOVES, TEX_UPPER_UNDERSHIRT, TEX_UPPER_TATTOO, TEX_UPPER_ALPHA,
- 8, LLWearableType::WT_SHAPE, LLWearableType::WT_SKIN, LLWearableType::WT_SHIRT, LLWearableType::WT_JACKET, LLWearableType::WT_GLOVES, LLWearableType::WT_UNDERSHIRT, LLWearableType::WT_TATTOO, LLWearableType::WT_ALPHA));
-
- addEntry(BAKED_LOWER, new BakedEntry(TEX_LOWER_BAKED,
- "lower_body", "2944ee70-90a7-425d-a5fb-d749c782ed7d",
- 8, TEX_LOWER_PANTS,TEX_LOWER_BODYPAINT,TEX_LOWER_SHOES, TEX_LOWER_SOCKS,
- TEX_LOWER_JACKET, TEX_LOWER_UNDERPANTS, TEX_LOWER_TATTOO, TEX_LOWER_ALPHA,
- 9, LLWearableType::WT_SHAPE, LLWearableType::WT_SKIN, LLWearableType::WT_PANTS, LLWearableType::WT_SHOES, LLWearableType::WT_SOCKS, LLWearableType::WT_JACKET, LLWearableType::WT_UNDERPANTS, LLWearableType::WT_TATTOO, LLWearableType::WT_ALPHA));
-
- addEntry(BAKED_EYES, new BakedEntry(TEX_EYES_BAKED,
- "eyes", "27b1bc0f-979f-4b13-95fe-b981c2ba9788",
- 2, TEX_EYES_IRIS, TEX_EYES_ALPHA,
- 2, LLWearableType::WT_EYES, LLWearableType::WT_ALPHA));
-
- addEntry(BAKED_SKIRT, new BakedEntry(TEX_SKIRT_BAKED,
- "skirt", "03e7e8cb-1368-483b-b6f3-74850838ba63",
- 1, TEX_SKIRT,
- 1, LLWearableType::WT_SKIRT));
-
- addEntry(BAKED_HAIR, new BakedEntry(TEX_HAIR_BAKED,
- "hair", "a60e85a9-74e8-48d8-8a2d-8129f28d9b61",
- 2, TEX_HAIR, TEX_HAIR_ALPHA,
- 2, LLWearableType::WT_HAIR, LLWearableType::WT_ALPHA));
-}
-
-LLVOAvatarDictionary::Meshes::Meshes()
-{
- // Meshes
- addEntry(MESH_ID_HAIR, new MeshEntry(BAKED_HAIR, "hairMesh", 6, LLViewerJoint::PN_4));
- addEntry(MESH_ID_HEAD, new MeshEntry(BAKED_HEAD, "headMesh", 5, LLViewerJoint::PN_5));
- addEntry(MESH_ID_EYELASH, new MeshEntry(BAKED_HEAD, "eyelashMesh", 1, LLViewerJoint::PN_0)); // no baked mesh associated currently
- addEntry(MESH_ID_UPPER_BODY, new MeshEntry(BAKED_UPPER, "upperBodyMesh", 5, LLViewerJoint::PN_1));
- addEntry(MESH_ID_LOWER_BODY, new MeshEntry(BAKED_LOWER, "lowerBodyMesh", 5, LLViewerJoint::PN_2));
- addEntry(MESH_ID_EYEBALL_LEFT, new MeshEntry(BAKED_EYES, "eyeBallLeftMesh", 2, LLViewerJoint::PN_3));
- addEntry(MESH_ID_EYEBALL_RIGHT, new MeshEntry(BAKED_EYES, "eyeBallRightMesh", 2, LLViewerJoint::PN_3));
- addEntry(MESH_ID_SKIRT, new MeshEntry(BAKED_SKIRT, "skirtMesh", 5, LLViewerJoint::PN_5));
-}
-
-/*
- *
- *********************************************************************************/
-
-LLVOAvatarDictionary::LLVOAvatarDictionary()
-{
- createAssociations();
-}
-
-//virtual
-LLVOAvatarDictionary::~LLVOAvatarDictionary()
-{
-}
-
-// Baked textures are composites of textures; for each such composited texture,
-// map it to the baked texture.
-void LLVOAvatarDictionary::createAssociations()
-{
- for (BakedTextures::const_iterator iter = mBakedTextures.begin(); iter != mBakedTextures.end(); iter++)
- {
- const EBakedTextureIndex baked_index = (iter->first);
- const BakedEntry *dict = (iter->second);
-
- // For each texture that this baked texture index affects, associate those textures
- // with this baked texture index.
- for (texture_vec_t::const_iterator local_texture_iter = dict->mLocalTextures.begin();
- local_texture_iter != dict->mLocalTextures.end();
- local_texture_iter++)
- {
- const ETextureIndex local_texture_index = (ETextureIndex) *local_texture_iter;
- mTextures[local_texture_index]->mIsUsedByBakedTexture = true;
- mTextures[local_texture_index]->mBakedTextureIndex = baked_index;
- }
- }
-
-}
-
-LLVOAvatarDictionary::TextureEntry::TextureEntry(const std::string &name,
- bool is_local_texture,
- EBakedTextureIndex baked_texture_index,
- const std::string &default_image_name,
- LLWearableType::EType wearable_type) :
- LLDictionaryEntry(name),
- mIsLocalTexture(is_local_texture),
- mIsBakedTexture(!is_local_texture),
- mIsUsedByBakedTexture(baked_texture_index != BAKED_NUM_INDICES),
- mBakedTextureIndex(baked_texture_index),
- mDefaultImageName(default_image_name),
- mWearableType(wearable_type)
-{
-}
-
-LLVOAvatarDictionary::MeshEntry::MeshEntry(EBakedTextureIndex baked_index,
- const std::string &name,
- U8 level,
- LLViewerJoint::PickName pick) :
- LLDictionaryEntry(name),
- mBakedID(baked_index),
- mLOD(level),
- mPickName(pick)
-{
-}
-LLVOAvatarDictionary::BakedEntry::BakedEntry(ETextureIndex tex_index,
- const std::string &name,
- const std::string &hash_name,
- U32 num_local_textures,
- ... ) :
- LLDictionaryEntry(name),
- mWearablesHashID(LLUUID(hash_name)),
- mTextureIndex(tex_index)
-{
- va_list argp;
-
- va_start(argp, num_local_textures);
-
- // Read in local textures
- for (U8 i=0; i < num_local_textures; i++)
- {
- ETextureIndex t = (ETextureIndex)va_arg(argp,int);
- mLocalTextures.push_back(t);
- }
-
- // Read in number of wearables
- const U32 num_wearables = (U32)va_arg(argp,int);
- // Read in wearables
- for (U8 i=0; i < num_wearables; i++)
- {
- LLWearableType::EType t = (LLWearableType::EType)va_arg(argp,int);
- mWearables.push_back(t);
- }
-}
-
-// static
-ETextureIndex LLVOAvatarDictionary::bakedToLocalTextureIndex(EBakedTextureIndex index)
-{
- return LLVOAvatarDictionary::getInstance()->getBakedTexture(index)->mTextureIndex;
-}
-
-//static
-EBakedTextureIndex LLVOAvatarDictionary::findBakedByRegionName(std::string name)
-{
- U8 index = 0;
- while (index < BAKED_NUM_INDICES)
- {
- const BakedEntry *be = LLVOAvatarDictionary::getInstance()->getBakedTexture((EBakedTextureIndex) index);
- if (be && be->mName.compare(name) == 0)
- {
- // baked texture found
- return (EBakedTextureIndex) index;
- }
- index++;
- }
- // baked texture could not be found
- return BAKED_NUM_INDICES;
-}
-
-//static
-const LLUUID LLVOAvatarDictionary::getDefaultTextureImageID(ETextureIndex index)
-{
- const TextureEntry *texture_dict = getInstance()->getTexture(index);
- const std::string &default_image_name = texture_dict->mDefaultImageName;
- if (default_image_name == "")
- {
- return IMG_DEFAULT_AVATAR;
- }
- else
- {
- return LLUUID(gSavedSettings.getString(default_image_name));
- }
-}
-
-// static
-LLWearableType::EType LLVOAvatarDictionary::getTEWearableType(ETextureIndex index )
-{
- return getInstance()->getTexture(index)->mWearableType;
-}
-
diff --git a/indra/newview/llvoavatardefines.h b/indra/newview/llvoavatardefines.h
deleted file mode 100644
index 35bb37463a..0000000000
--- a/indra/newview/llvoavatardefines.h
+++ /dev/null
@@ -1,228 +0,0 @@
-/**
- * @file llvoavatar.h
- * @brief Declaration of LLVOAvatar class which is a derivation fo
- * LLViewerObject
- *
- * $LicenseInfo:firstyear=2001&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$
- */
-
-#ifndef LLVOAVATAR_DEFINES_H
-#define LLVOAVATAR_DEFINES_H
-
-#include <vector>
-#include "llwearable.h"
-#include "llviewerjoint.h"
-#include "lldictionary.h"
-
-namespace LLVOAvatarDefines
-{
-
-extern const S32 SCRATCH_TEX_WIDTH;
-extern const S32 SCRATCH_TEX_HEIGHT;
-extern const S32 IMPOSTOR_PERIOD;
-
-//--------------------------------------------------------------------
-// Enums
-//--------------------------------------------------------------------
-enum ETextureIndex
-{
- TEX_HEAD_BODYPAINT = 0,
- TEX_UPPER_SHIRT,
- TEX_LOWER_PANTS,
- TEX_EYES_IRIS,
- TEX_HAIR,
- TEX_UPPER_BODYPAINT,
- TEX_LOWER_BODYPAINT,
- TEX_LOWER_SHOES,
- TEX_HEAD_BAKED, // Pre-composited
- TEX_UPPER_BAKED, // Pre-composited
- TEX_LOWER_BAKED, // Pre-composited
- TEX_EYES_BAKED, // Pre-composited
- TEX_LOWER_SOCKS,
- TEX_UPPER_JACKET,
- TEX_LOWER_JACKET,
- TEX_UPPER_GLOVES,
- TEX_UPPER_UNDERSHIRT,
- TEX_LOWER_UNDERPANTS,
- TEX_SKIRT,
- TEX_SKIRT_BAKED, // Pre-composited
- TEX_HAIR_BAKED, // Pre-composited
- TEX_LOWER_ALPHA,
- TEX_UPPER_ALPHA,
- TEX_HEAD_ALPHA,
- TEX_EYES_ALPHA,
- TEX_HAIR_ALPHA,
- TEX_HEAD_TATTOO,
- TEX_UPPER_TATTOO,
- TEX_LOWER_TATTOO,
- TEX_NUM_INDICES
-};
-
-enum EBakedTextureIndex
-{
- BAKED_HEAD = 0,
- BAKED_UPPER,
- BAKED_LOWER,
- BAKED_EYES,
- BAKED_SKIRT,
- BAKED_HAIR,
- BAKED_NUM_INDICES
-};
-
-// Reference IDs for each mesh. Used as indices for vector of joints
-enum EMeshIndex
-{
- MESH_ID_HAIR = 0,
- MESH_ID_HEAD,
- MESH_ID_EYELASH,
- MESH_ID_UPPER_BODY,
- MESH_ID_LOWER_BODY,
- MESH_ID_EYEBALL_LEFT,
- MESH_ID_EYEBALL_RIGHT,
- MESH_ID_SKIRT,
- MESH_ID_NUM_INDICES
-};
-
-//--------------------------------------------------------------------
-// Vector Types
-//--------------------------------------------------------------------
-typedef std::vector<ETextureIndex> texture_vec_t;
-typedef std::vector<EBakedTextureIndex> bakedtexture_vec_t;
-typedef std::vector<EMeshIndex> mesh_vec_t;
-typedef std::vector<LLWearableType::EType> wearables_vec_t;
-
-//------------------------------------------------------------------------
-// LLVOAvatarDictionary
-//
-// Holds dictionary static entries for textures, baked textures, meshes, etc.; i.e.
-// information that is common to all avatars.
-//
-// This holds const data - it is initialized once and the contents never change after that.
-//------------------------------------------------------------------------
-class LLVOAvatarDictionary : public LLSingleton<LLVOAvatarDictionary>
-{
- //--------------------------------------------------------------------
- // Constructors and Destructors
- //--------------------------------------------------------------------
-public:
- LLVOAvatarDictionary();
- virtual ~LLVOAvatarDictionary();
-private:
- void createAssociations();
-
- //--------------------------------------------------------------------
- // Local and baked textures
- //--------------------------------------------------------------------
-public:
- struct TextureEntry : public LLDictionaryEntry
- {
- TextureEntry(const std::string &name, // this must match the xml name used by LLTexLayerInfo::parseXml
- bool is_local_texture,
- EBakedTextureIndex baked_texture_index = BAKED_NUM_INDICES,
- const std::string& default_image_name = "",
- LLWearableType::EType wearable_type = LLWearableType::WT_INVALID);
- const std::string mDefaultImageName;
- const LLWearableType::EType mWearableType;
- // It's either a local texture xor baked
- BOOL mIsLocalTexture;
- BOOL mIsBakedTexture;
- // If it's a local texture, it may be used by a baked texture
- BOOL mIsUsedByBakedTexture;
- EBakedTextureIndex mBakedTextureIndex;
- };
-
- struct Textures : public LLDictionary<ETextureIndex, TextureEntry>
- {
- Textures();
- } mTextures;
- const TextureEntry* getTexture(ETextureIndex index) const { return mTextures.lookup(index); }
- const Textures& getTextures() const { return mTextures; }
-
- //--------------------------------------------------------------------
- // Meshes
- //--------------------------------------------------------------------
-public:
- struct MeshEntry : public LLDictionaryEntry
- {
- MeshEntry(EBakedTextureIndex baked_index,
- const std::string &name, // names of mesh types as they are used in avatar_lad.xml
- U8 level,
- LLViewerJoint::PickName pick);
- // Levels of Detail for each mesh. Must match levels of detail present in avatar_lad.xml
- // Otherwise meshes will be unable to be found, or levels of detail will be ignored
- const U8 mLOD;
- const EBakedTextureIndex mBakedID;
- const LLViewerJoint::PickName mPickName;
- };
-
- struct Meshes : public LLDictionary<EMeshIndex, MeshEntry>
- {
- Meshes();
- } mMeshes;
- const MeshEntry* getMesh(EMeshIndex index) const { return mMeshes.lookup(index); }
- const Meshes& getMeshes() const { return mMeshes; }
-
- //--------------------------------------------------------------------
- // Baked Textures
- //--------------------------------------------------------------------
-public:
- struct BakedEntry : public LLDictionaryEntry
- {
- BakedEntry(ETextureIndex tex_index,
- const std::string &name, // unused, but necessary for templating.
- const std::string &hash_name,
- U32 num_local_textures, ... ); // # local textures, local texture list, # wearables, wearable list
- // Local Textures
- const ETextureIndex mTextureIndex;
- texture_vec_t mLocalTextures;
- // Wearables
- const LLUUID mWearablesHashID;
- wearables_vec_t mWearables;
- };
-
- struct BakedTextures: public LLDictionary<EBakedTextureIndex, BakedEntry>
- {
- BakedTextures();
- } mBakedTextures;
- const BakedEntry* getBakedTexture(EBakedTextureIndex index) const { return mBakedTextures.lookup(index); }
- const BakedTextures& getBakedTextures() const { return mBakedTextures; }
-
- //--------------------------------------------------------------------
- // Convenience Functions
- //--------------------------------------------------------------------
-public:
- // Convert from baked texture to associated texture; e.g. BAKED_HEAD -> TEX_HEAD_BAKED
- static ETextureIndex bakedToLocalTextureIndex(EBakedTextureIndex t);
-
- // find a baked texture index based on its name
- static EBakedTextureIndex findBakedByRegionName(std::string name);
-
- static const LLUUID getDefaultTextureImageID(ETextureIndex index);
-
- // Given a texture entry, determine which wearable type owns it.
- static LLWearableType::EType getTEWearableType(ETextureIndex index);
-
-}; // End LLVOAvatarDictionary
-
-} // End namespace LLVOAvatarDefines
-
-#endif //LL_VO_AVATARDEFINES_H
diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp
index f063653cc5..9ce99444d9 100644..100755
--- a/indra/newview/llvoavatarself.cpp
+++ b/indra/newview/llvoavatarself.cpp
@@ -55,9 +55,14 @@
#include "llviewerobjectlist.h"
#include "llviewerstats.h"
#include "llviewerregion.h"
+#include "llviewertexlayer.h"
+#include "llviewerwearable.h"
#include "llappearancemgr.h"
#include "llmeshrepository.h"
#include "llvovolume.h"
+#include "llsdutil.h"
+#include "llstartup.h"
+#include "llsdserialize.h"
#if LL_MSVC
// disable boost::lexical_cast warning
@@ -70,12 +75,34 @@ LLPointer<LLVOAvatarSelf> gAgentAvatarp = NULL;
BOOL isAgentAvatarValid()
{
- return (gAgentAvatarp.notNull() &&
- (gAgentAvatarp->getRegion() != NULL) &&
- (!gAgentAvatarp->isDead()));
+ return (gAgentAvatarp.notNull() && gAgentAvatarp->isValid());
}
-using namespace LLVOAvatarDefines;
+void selfStartPhase(const std::string& phase_name)
+{
+ if (isAgentAvatarValid())
+ {
+ gAgentAvatarp->startPhase(phase_name);
+ }
+}
+
+void selfStopPhase(const std::string& phase_name, bool err_check)
+{
+ if (isAgentAvatarValid())
+ {
+ gAgentAvatarp->stopPhase(phase_name, err_check);
+ }
+}
+
+void selfClearPhases()
+{
+ if (isAgentAvatarValid())
+ {
+ gAgentAvatarp->clearPhases();
+ }
+}
+
+using namespace LLAvatarAppearanceDefines;
/*********************************************************************************
** **
@@ -131,7 +158,8 @@ LLVOAvatarSelf::LLVOAvatarSelf(const LLUUID& id,
LLVOAvatar(id, pcode, regionp),
mScreenp(NULL),
mLastRegionHandle(0),
- mRegionCrossingCount(0)
+ mRegionCrossingCount(0),
+ mInitialBakesLoaded(false)
{
gAgentWearables.setAvatarObject(this);
@@ -140,6 +168,35 @@ LLVOAvatarSelf::LLVOAvatarSelf(const LLUUID& id,
lldebugs << "Marking avatar as self " << id << llendl;
}
+// Called periodically for diagnostics, return true when done.
+bool output_self_av_texture_diagnostics()
+{
+ if (!isAgentAvatarValid())
+ return true; // done checking
+
+ gAgentAvatarp->outputRezDiagnostics();
+
+ return false;
+}
+
+bool update_avatar_rez_metrics()
+{
+ if (!isAgentAvatarValid())
+ return true;
+
+ gAgentAvatarp->updateAvatarRezMetrics(false);
+ return false;
+}
+
+bool check_for_unsupported_baked_appearance()
+{
+ if (!isAgentAvatarValid())
+ return true;
+
+ gAgentAvatarp->checkForUnsupportedServerBakeAppearance();
+ return false;
+}
+
void LLVOAvatarSelf::initInstance()
{
BOOL status = TRUE;
@@ -152,7 +209,7 @@ void LLVOAvatarSelf::initInstance()
llinfos << "Self avatar object created. Starting timer." << llendl;
mDebugSelfLoadTimer.reset();
// clear all times to -1 for debugging
- for (U32 i =0; i < LLVOAvatarDefines::TEX_NUM_INDICES; ++i)
+ for (U32 i =0; i < LLAvatarAppearanceDefines::TEX_NUM_INDICES; ++i)
{
for (U32 j = 0; j <= MAX_DISCARD_LEVEL; ++j)
{
@@ -160,10 +217,11 @@ void LLVOAvatarSelf::initInstance()
}
}
- for (U32 i =0; i < LLVOAvatarDefines::BAKED_NUM_INDICES; ++i)
+ for (U32 i =0; i < LLAvatarAppearanceDefines::BAKED_NUM_INDICES; ++i)
{
mDebugBakedTextureTimes[i][0] = -1.0f;
mDebugBakedTextureTimes[i][1] = -1.0f;
+ mInitialBakeIDs[i] = LLUUID::null;
}
status &= buildMenus();
@@ -172,6 +230,10 @@ void LLVOAvatarSelf::initInstance()
llerrs << "Unable to load user's avatar" << llendl;
return;
}
+
+ //doPeriodically(output_self_av_texture_diagnostics, 30.0);
+ doPeriodically(update_avatar_rez_metrics, 5.0);
+ doPeriodically(check_for_unsupported_baked_appearance, 120.0);
}
// virtual
@@ -212,16 +274,12 @@ BOOL LLVOAvatarSelf::loadAvatarSelf()
llwarns << "avatar file: buildSkeleton() failed" << llendl;
return FALSE;
}
- // TODO: make loadLayersets() called only by self.
- //success &= loadLayersets();
return success;
}
-BOOL LLVOAvatarSelf::buildSkeletonSelf(const LLVOAvatarSkeletonInfo *info)
+BOOL LLVOAvatarSelf::buildSkeletonSelf(const LLAvatarSkeletonInfo *info)
{
- LLMemType mt(LLMemType::MTYPE_AVATAR);
-
// add special-purpose "screen" joint
mScreenp = new LLViewerJoint("mScreen", NULL);
// for now, put screen at origin, as it is only used during special
@@ -306,7 +364,6 @@ BOOL LLVOAvatarSelf::buildMenus()
}
else
{
- BOOL attachment_found = FALSE;
for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
iter != mAttachmentPoints.end();
++iter)
@@ -334,7 +391,6 @@ BOOL LLVOAvatarSelf::buildMenus()
gAttachPieMenu->addChild(item);
- attachment_found = TRUE;
break;
}
@@ -347,7 +403,6 @@ BOOL LLVOAvatarSelf::buildMenus()
}
else
{
- BOOL attachment_found = FALSE;
for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
iter != mAttachmentPoints.end();
++iter)
@@ -374,7 +429,6 @@ BOOL LLVOAvatarSelf::buildMenus()
gDetachPieMenu->addChild(item);
- attachment_found = TRUE;
break;
}
}
@@ -549,74 +603,8 @@ LLVOAvatarSelf::~LLVOAvatarSelf()
*********************************************************************************/
//virtual
-BOOL LLVOAvatarSelf::loadLayersets()
-{
- BOOL success = TRUE;
- for (LLVOAvatarXmlInfo::layer_info_list_t::const_iterator iter = sAvatarXmlInfo->mLayerInfoList.begin();
- iter != sAvatarXmlInfo->mLayerInfoList.end();
- ++iter)
- {
- // Construct a layerset for each one specified in avatar_lad.xml and initialize it as such.
- const LLTexLayerSetInfo *info = *iter;
- LLTexLayerSet* layer_set = new LLTexLayerSet( this );
-
- if (!layer_set->setInfo(info))
- {
- stop_glerror();
- delete layer_set;
- llwarns << "avatar file: layer_set->parseData() failed" << llendl;
- return FALSE;
- }
-
- // scan baked textures and associate the layerset with the appropriate one
- EBakedTextureIndex baked_index = BAKED_NUM_INDICES;
- for (LLVOAvatarDictionary::BakedTextures::const_iterator baked_iter = LLVOAvatarDictionary::getInstance()->getBakedTextures().begin();
- baked_iter != LLVOAvatarDictionary::getInstance()->getBakedTextures().end();
- ++baked_iter)
- {
- const LLVOAvatarDictionary::BakedEntry *baked_dict = baked_iter->second;
- if (layer_set->isBodyRegion(baked_dict->mName))
- {
- baked_index = baked_iter->first;
- // ensure both structures are aware of each other
- mBakedTextureDatas[baked_index].mTexLayerSet = layer_set;
- layer_set->setBakedTexIndex(baked_index);
- break;
- }
- }
- // if no baked texture was found, warn and cleanup
- if (baked_index == BAKED_NUM_INDICES)
- {
- llwarns << "<layer_set> has invalid body_region attribute" << llendl;
- delete layer_set;
- return FALSE;
- }
-
- // scan morph masks and let any affected layers know they have an associated morph
- for (LLVOAvatar::morph_list_t::const_iterator morph_iter = mBakedTextureDatas[baked_index].mMaskedMorphs.begin();
- morph_iter != mBakedTextureDatas[baked_index].mMaskedMorphs.end();
- ++morph_iter)
- {
- LLMaskedMorph *morph = *morph_iter;
- LLTexLayerInterface* layer = layer_set->findLayerByName(morph->mLayer);
- if (layer)
- {
- layer->setHasMorph(TRUE);
- }
- else
- {
- llwarns << "Could not find layer named " << morph->mLayer << " to set morph flag" << llendl;
- success = FALSE;
- }
- }
- }
- return success;
-}
-// virtual
BOOL LLVOAvatarSelf::updateCharacter(LLAgent &agent)
{
- LLMemType mt(LLMemType::MTYPE_AVATAR);
-
// update screen joint size
if (mScreenp)
{
@@ -631,15 +619,19 @@ BOOL LLVOAvatarSelf::updateCharacter(LLAgent &agent)
}
// virtual
-BOOL LLVOAvatarSelf::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
+BOOL LLVOAvatarSelf::isValid() const
{
- if (!isAgentAvatarValid())
+ return ((getRegion() != NULL) && !isDead());
+}
+
+// virtual
+void LLVOAvatarSelf::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
+{
+ if (isValid())
{
- return TRUE;
+ LLVOAvatar::idleUpdate(agent, world, time);
+ idleUpdateTractorBeam();
}
- LLVOAvatar::idleUpdate(agent, world, time);
- idleUpdateTractorBeam();
- return TRUE;
}
// virtual
@@ -658,7 +650,7 @@ void LLVOAvatarSelf::resetJointPositions( void )
return LLVOAvatar::resetJointPositions();
}
// virtual
-BOOL LLVOAvatarSelf::setVisualParamWeight(LLVisualParam *which_param, F32 weight, BOOL upload_bake )
+BOOL LLVOAvatarSelf::setVisualParamWeight(const LLVisualParam *which_param, F32 weight, BOOL upload_bake )
{
if (!which_param)
{
@@ -686,20 +678,28 @@ BOOL LLVOAvatarSelf::setVisualParamWeight(S32 index, F32 weight, BOOL upload_bak
return setParamWeight(param,weight,upload_bake);
}
-BOOL LLVOAvatarSelf::setParamWeight(LLViewerVisualParam *param, F32 weight, BOOL upload_bake )
+BOOL LLVOAvatarSelf::setParamWeight(const LLViewerVisualParam *param, F32 weight, BOOL upload_bake )
{
if (!param)
{
return FALSE;
}
+#if 0
+ // FIXME DRANO - kludgy way to avoid overwriting avatar state from wearables.
+ if (isUsingServerBakes() && !isUsingLocalAppearance())
+ {
+ return FALSE;
+ }
+#endif
+
if (param->getCrossWearable())
{
LLWearableType::EType type = (LLWearableType::EType)param->getWearableType();
U32 size = gAgentWearables.getWearableCount(type);
for (U32 count = 0; count < size; ++count)
{
- LLWearable *wearable = gAgentWearables.getWearable(type,count);
+ LLViewerWearable *wearable = gAgentWearables.getViewerWearable(type,count);
if (wearable)
{
wearable->setVisualParamWeight(param->getID(), weight, upload_bake);
@@ -728,7 +728,7 @@ void LLVOAvatarSelf::idleUpdateAppearanceAnimation()
LLWearable *wearable = gAgentWearables.getTopWearable((LLWearableType::EType)type);
if (wearable)
{
- wearable->writeToAvatar();
+ wearable->writeToAvatar(this);
}
}
@@ -758,10 +758,58 @@ void LLVOAvatarSelf::stopMotionFromSource(const LLUUID& source_id)
LLViewerObject* object = gObjectList.findObject(source_id);
if (object)
{
- object->mFlags &= ~FLAGS_ANIM_SOURCE;
+ object->setFlagsWithoutUpdate(FLAGS_ANIM_SOURCE, FALSE);
}
}
+//virtual
+U32 LLVOAvatarSelf::processUpdateMessage(LLMessageSystem *mesgsys,
+ void **user_data,
+ U32 block_num,
+ const EObjectUpdateType update_type,
+ LLDataPacker *dp)
+{
+ U32 retval = LLVOAvatar::processUpdateMessage(mesgsys,user_data,block_num,update_type,dp);
+
+#if 0
+ // DRANO - it's not clear this does anything useful. If we wait
+ // until an appearance message has been received, we already have
+ // the texture ids. If we don't wait, we don't yet know where to
+ // look for baked textures, because we haven't received the
+ // appearance version data from the appearance message. This looks
+ // like an old optimization that's incompatible with server-side
+ // texture baking.
+
+ // FIXME DRANO - skipping in the case of !mFirstAppearanceMessageReceived prevents us from trying to
+ // load textures before we know where they come from (ie, from baking service or not);
+ // unknown impact on performance.
+ if (mInitialBakesLoaded == false && retval == 0x0 && mFirstAppearanceMessageReceived)
+ {
+ // call update textures to force the images to be created
+ updateMeshTextures();
+
+ // unpack the texture UUIDs to the texture slots
+ retval = unpackTEMessage(mesgsys, _PREHASH_ObjectData, (S32) block_num);
+
+ // need to trigger a few operations to get the avatar to use the new bakes
+ for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
+ {
+ const LLAvatarAppearanceDefines::ETextureIndex te = mBakedTextureDatas[i].mTextureIndex;
+ LLUUID texture_id = getTEImage(te)->getID();
+ setNewBakedTexture(te, texture_id);
+ mInitialBakeIDs[i] = texture_id;
+ }
+
+ onFirstTEMessageReceived();
+
+ mInitialBakesLoaded = true;
+ }
+#endif
+
+ return retval;
+}
+
+
void LLVOAvatarSelf::setLocalTextureTE(U8 te, LLViewerTexture* image, U32 index)
{
if (te >= TEX_NUM_INDICES)
@@ -811,13 +859,17 @@ void LLVOAvatarSelf::removeMissingBakedTextures()
{
for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
{
- mBakedTextureDatas[i].mTexLayerSet->setUpdatesEnabled(TRUE);
- invalidateComposite(mBakedTextureDatas[i].mTexLayerSet, FALSE);
+ LLViewerTexLayerSet *layerset = getTexLayerSet(i);
+ layerset->setUpdatesEnabled(TRUE);
+ invalidateComposite(layerset, FALSE);
}
updateMeshTextures();
+ if (getRegion() && !getRegion()->getCentralBakeVersion())
+ {
requestLayerSetUploads();
}
}
+}
//virtual
void LLVOAvatarSelf::updateRegion(LLViewerRegion *regionp)
@@ -872,7 +924,7 @@ void LLVOAvatarSelf::updateRegion(LLViewerRegion *regionp)
void LLVOAvatarSelf::idleUpdateTractorBeam()
{
// This is only done for yourself (maybe it should be in the agent?)
- if (!needsRenderBeam() || !mIsBuilt)
+ if (!needsRenderBeam() || !isBuilt())
{
mBeam = NULL;
}
@@ -938,8 +990,6 @@ void LLVOAvatarSelf::idleUpdateTractorBeam()
// virtual
void LLVOAvatarSelf::restoreMeshData()
{
- LLMemType mt(LLMemType::MTYPE_AVATAR);
-
//llinfos << "Restoring" << llendl;
mMeshValid = TRUE;
updateJointLODs();
@@ -987,11 +1037,6 @@ void LLVOAvatarSelf::updateAttachmentVisibility(U32 camera_mode)
}
}
-/*virtual*/ BOOL LLVOAvatarSelf::isWearingWearableType(LLWearableType::EType type ) const
-{
- return gAgentWearables.getWearableCount(type) > 0;
-}
-
//-----------------------------------------------------------------------------
// updatedWearable( LLWearableType::EType type )
// forces an update to any baked textures relevant to type.
@@ -999,26 +1044,27 @@ void LLVOAvatarSelf::updateAttachmentVisibility(U32 camera_mode)
//-----------------------------------------------------------------------------
void LLVOAvatarSelf::wearableUpdated( LLWearableType::EType type, BOOL upload_result )
{
- for (LLVOAvatarDictionary::BakedTextures::const_iterator baked_iter = LLVOAvatarDictionary::getInstance()->getBakedTextures().begin();
- baked_iter != LLVOAvatarDictionary::getInstance()->getBakedTextures().end();
+ for (LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().begin();
+ baked_iter != LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().end();
++baked_iter)
{
- const LLVOAvatarDictionary::BakedEntry *baked_dict = baked_iter->second;
- const LLVOAvatarDefines::EBakedTextureIndex index = baked_iter->first;
+ const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = baked_iter->second;
+ const LLAvatarAppearanceDefines::EBakedTextureIndex index = baked_iter->first;
if (baked_dict)
{
- for (LLVOAvatarDefines::wearables_vec_t::const_iterator type_iter = baked_dict->mWearables.begin();
+ for (LLAvatarAppearanceDefines::wearables_vec_t::const_iterator type_iter = baked_dict->mWearables.begin();
type_iter != baked_dict->mWearables.end();
++type_iter)
{
const LLWearableType::EType comp_type = *type_iter;
if (comp_type == type)
{
- if (mBakedTextureDatas[index].mTexLayerSet)
+ LLViewerTexLayerSet *layerset = getLayerSet(index);
+ if (layerset)
{
- mBakedTextureDatas[index].mTexLayerSet->setUpdatesEnabled(true);
- invalidateComposite(mBakedTextureDatas[index].mTexLayerSet, upload_result);
+ layerset->setUpdatesEnabled(true);
+ invalidateComposite(layerset, upload_result);
}
break;
}
@@ -1182,7 +1228,7 @@ BOOL LLVOAvatarSelf::detachObject(LLViewerObject *viewer_object)
// Make sure the inventory is in sync with the avatar.
// Update COF contents, don't trigger appearance update.
- if (!isAgentAvatarValid())
+ if (!isValid())
{
llinfos << "removeItemLinks skipped, avatar is under destruction" << llendl;
}
@@ -1223,7 +1269,7 @@ BOOL LLVOAvatarSelf::detachAttachmentIntoInventory(const LLUUID &item_id)
const LLViewerObject *attached_obj = gAgentAvatarp->getWornAttachment(item_id);
if (!attached_obj)
{
- LLAppearanceMgr::instance().removeCOFItemLinks(item_id, false);
+ LLAppearanceMgr::instance().removeCOFItemLinks(item_id);
}
}
return TRUE;
@@ -1231,9 +1277,9 @@ BOOL LLVOAvatarSelf::detachAttachmentIntoInventory(const LLUUID &item_id)
return FALSE;
}
-U32 LLVOAvatarSelf::getNumWearables(LLVOAvatarDefines::ETextureIndex i) const
+U32 LLVOAvatarSelf::getNumWearables(LLAvatarAppearanceDefines::ETextureIndex i) const
{
- LLWearableType::EType type = LLVOAvatarDictionary::getInstance()->getTEWearableType(i);
+ LLWearableType::EType type = LLAvatarAppearanceDictionary::getInstance()->getTEWearableType(i);
return gAgentWearables.getWearableCount(type);
}
@@ -1264,11 +1310,8 @@ void LLVOAvatarSelf::localTextureLoaded(BOOL success, LLViewerFetchedTexture *sr
discard_level < local_tex_obj->getDiscard())
{
local_tex_obj->setDiscard(discard_level);
- if (isUsingBakedTextures())
- {
requestLayerSetUpdate(index);
- }
- else
+ if (isEditingAppearance())
{
LLVisualParamHint::requestHintUpdates();
}
@@ -1302,11 +1345,11 @@ BOOL LLVOAvatarSelf::getLocalTextureGL(ETextureIndex type, LLViewerTexture** tex
{
return FALSE;
}
- *tex_pp = local_tex_obj->getImage();
+ *tex_pp = dynamic_cast<LLViewerTexture*> (local_tex_obj->getImage());
return TRUE;
}
-LLViewerFetchedTexture* LLVOAvatarSelf::getLocalTextureGL(LLVOAvatarDefines::ETextureIndex type, U32 index) const
+LLViewerFetchedTexture* LLVOAvatarSelf::getLocalTextureGL(LLAvatarAppearanceDefines::ETextureIndex type, U32 index) const
{
if (!isIndexLocalTexture(type))
{
@@ -1322,7 +1365,7 @@ LLViewerFetchedTexture* LLVOAvatarSelf::getLocalTextureGL(LLVOAvatarDefines::ETe
{
return LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT_AVATAR);
}
- return local_tex_obj->getImage();
+ return dynamic_cast<LLViewerFetchedTexture*> (local_tex_obj->getImage());
}
const LLUUID& LLVOAvatarSelf::getLocalTextureID(ETextureIndex type, U32 index) const
@@ -1343,29 +1386,30 @@ const LLUUID& LLVOAvatarSelf::getLocalTextureID(ETextureIndex type, U32 index) c
// Returns true if at least the lowest quality discard level exists for every texture
// in the layerset.
//-----------------------------------------------------------------------------
-BOOL LLVOAvatarSelf::isLocalTextureDataAvailable(const LLTexLayerSet* layerset) const
+BOOL LLVOAvatarSelf::isLocalTextureDataAvailable(const LLViewerTexLayerSet* layerset) const
{
/* if (layerset == mBakedTextureDatas[BAKED_HEAD].mTexLayerSet)
return getLocalDiscardLevel(TEX_HEAD_BODYPAINT) >= 0; */
- for (LLVOAvatarDictionary::BakedTextures::const_iterator baked_iter = LLVOAvatarDictionary::getInstance()->getBakedTextures().begin();
- baked_iter != LLVOAvatarDictionary::getInstance()->getBakedTextures().end();
+ for (LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().begin();
+ baked_iter != LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().end();
++baked_iter)
{
const EBakedTextureIndex baked_index = baked_iter->first;
if (layerset == mBakedTextureDatas[baked_index].mTexLayerSet)
{
BOOL ret = true;
- const LLVOAvatarDictionary::BakedEntry *baked_dict = baked_iter->second;
+ const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = baked_iter->second;
for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin();
local_tex_iter != baked_dict->mLocalTextures.end();
++local_tex_iter)
{
const ETextureIndex tex_index = *local_tex_iter;
- const LLWearableType::EType wearable_type = LLVOAvatarDictionary::getTEWearableType(tex_index);
+ const LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getTEWearableType(tex_index);
const U32 wearable_count = gAgentWearables.getWearableCount(wearable_type);
for (U32 wearable_index = 0; wearable_index < wearable_count; wearable_index++)
{
- ret &= (getLocalDiscardLevel(tex_index, wearable_index) >= 0);
+ BOOL tex_avail = (getLocalDiscardLevel(tex_index, wearable_index) >= 0);
+ ret &= tex_avail;
}
}
return ret;
@@ -1381,7 +1425,7 @@ BOOL LLVOAvatarSelf::isLocalTextureDataAvailable(const LLTexLayerSet* layerset)
// Returns true if the highest quality discard level exists for every texture
// in the layerset.
//-----------------------------------------------------------------------------
-BOOL LLVOAvatarSelf::isLocalTextureDataFinal(const LLTexLayerSet* layerset) const
+BOOL LLVOAvatarSelf::isLocalTextureDataFinal(const LLViewerTexLayerSet* layerset) const
{
const U32 desired_tex_discard_level = gSavedSettings.getU32("TextureDiscardLevel");
// const U32 desired_tex_discard_level = 0; // hack to not bake textures on lower discard levels.
@@ -1390,17 +1434,19 @@ BOOL LLVOAvatarSelf::isLocalTextureDataFinal(const LLTexLayerSet* layerset) cons
{
if (layerset == mBakedTextureDatas[i].mTexLayerSet)
{
- const LLVOAvatarDictionary::BakedEntry *baked_dict = LLVOAvatarDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)i);
+ const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = LLAvatarAppearanceDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)i);
for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin();
local_tex_iter != baked_dict->mLocalTextures.end();
++local_tex_iter)
{
const ETextureIndex tex_index = *local_tex_iter;
- const LLWearableType::EType wearable_type = LLVOAvatarDictionary::getTEWearableType(tex_index);
+ const LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getTEWearableType(tex_index);
const U32 wearable_count = gAgentWearables.getWearableCount(wearable_type);
for (U32 wearable_index = 0; wearable_index < wearable_count; wearable_index++)
{
- if (getLocalDiscardLevel(*local_tex_iter, wearable_index) > (S32)(desired_tex_discard_level))
+ S32 local_discard_level = getLocalDiscardLevel(*local_tex_iter, wearable_index);
+ if ((local_discard_level > (S32)(desired_tex_discard_level)) ||
+ (local_discard_level < 0 ))
{
return FALSE;
}
@@ -1413,6 +1459,7 @@ BOOL LLVOAvatarSelf::isLocalTextureDataFinal(const LLTexLayerSet* layerset) cons
return FALSE;
}
+
BOOL LLVOAvatarSelf::isAllLocalTextureDataFinal() const
{
const U32 desired_tex_discard_level = gSavedSettings.getU32("TextureDiscardLevel");
@@ -1420,17 +1467,19 @@ BOOL LLVOAvatarSelf::isAllLocalTextureDataFinal() const
for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
{
- const LLVOAvatarDictionary::BakedEntry *baked_dict = LLVOAvatarDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)i);
+ const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = LLAvatarAppearanceDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)i);
for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin();
local_tex_iter != baked_dict->mLocalTextures.end();
++local_tex_iter)
{
const ETextureIndex tex_index = *local_tex_iter;
- const LLWearableType::EType wearable_type = LLVOAvatarDictionary::getTEWearableType(tex_index);
+ const LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getTEWearableType(tex_index);
const U32 wearable_count = gAgentWearables.getWearableCount(wearable_type);
for (U32 wearable_index = 0; wearable_index < wearable_count; wearable_index++)
{
- if (getLocalDiscardLevel(*local_tex_iter, wearable_index) > (S32)(desired_tex_discard_level))
+ S32 local_discard_level = getLocalDiscardLevel(*local_tex_iter, wearable_index);
+ if ((local_discard_level > (S32)(desired_tex_discard_level)) ||
+ (local_discard_level < 0 ))
{
return FALSE;
}
@@ -1440,22 +1489,22 @@ BOOL LLVOAvatarSelf::isAllLocalTextureDataFinal() const
return TRUE;
}
-BOOL LLVOAvatarSelf::isBakedTextureFinal(const LLVOAvatarDefines::EBakedTextureIndex index) const
+BOOL LLVOAvatarSelf::isBakedTextureFinal(const LLAvatarAppearanceDefines::EBakedTextureIndex index) const
{
- const LLTexLayerSet *layerset = mBakedTextureDatas[index].mTexLayerSet;
+ const LLViewerTexLayerSet *layerset = getLayerSet(index);
if (!layerset) return FALSE;
- const LLTexLayerSetBuffer *layerset_buffer = layerset->getComposite();
+ const LLViewerTexLayerSetBuffer *layerset_buffer = layerset->getViewerComposite();
if (!layerset_buffer) return FALSE;
return !layerset_buffer->uploadNeeded();
}
-BOOL LLVOAvatarSelf::isTextureDefined(LLVOAvatarDefines::ETextureIndex type, U32 index) const
+BOOL LLVOAvatarSelf::isTextureDefined(LLAvatarAppearanceDefines::ETextureIndex type, U32 index) const
{
LLUUID id;
BOOL isDefined = TRUE;
if (isIndexLocalTexture(type))
{
- const LLWearableType::EType wearable_type = LLVOAvatarDictionary::getTEWearableType(type);
+ const LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getTEWearableType(type);
const U32 wearable_count = gAgentWearables.getWearableCount(wearable_type);
if (index >= wearable_count)
{
@@ -1482,7 +1531,7 @@ BOOL LLVOAvatarSelf::isTextureDefined(LLVOAvatarDefines::ETextureIndex type, U32
}
//virtual
-BOOL LLVOAvatarSelf::isTextureVisible(LLVOAvatarDefines::ETextureIndex type, U32 index) const
+BOOL LLVOAvatarSelf::isTextureVisible(LLAvatarAppearanceDefines::ETextureIndex type, U32 index) const
{
if (isIndexBakedTexture(type))
{
@@ -1495,7 +1544,7 @@ BOOL LLVOAvatarSelf::isTextureVisible(LLVOAvatarDefines::ETextureIndex type, U32
}
//virtual
-BOOL LLVOAvatarSelf::isTextureVisible(LLVOAvatarDefines::ETextureIndex type, LLWearable *wearable) const
+BOOL LLVOAvatarSelf::isTextureVisible(LLAvatarAppearanceDefines::ETextureIndex type, LLViewerWearable *wearable) const
{
if (isIndexBakedTexture(type))
{
@@ -1518,13 +1567,14 @@ void LLVOAvatarSelf::requestLayerSetUploads()
}
}
-void LLVOAvatarSelf::requestLayerSetUpload(LLVOAvatarDefines::EBakedTextureIndex i)
+void LLVOAvatarSelf::requestLayerSetUpload(LLAvatarAppearanceDefines::EBakedTextureIndex i)
{
ETextureIndex tex_index = mBakedTextureDatas[i].mTextureIndex;
const BOOL layer_baked = isTextureDefined(tex_index, gAgentWearables.getWearableCount(tex_index));
- if (!layer_baked && mBakedTextureDatas[i].mTexLayerSet)
+ LLViewerTexLayerSet *layerset = getLayerSet(i);
+ if (!layer_baked && layerset)
{
- mBakedTextureDatas[i].mTexLayerSet->requestUpload();
+ layerset->requestUpload();
}
}
@@ -1538,8 +1588,8 @@ bool LLVOAvatarSelf::hasPendingBakedUploads() const
{
for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
{
- LLTexLayerSet* layerset = mBakedTextureDatas[i].mTexLayerSet;
- if (layerset && layerset->getComposite() && layerset->getComposite()->uploadPending())
+ LLViewerTexLayerSet* layerset = getTexLayerSet(i);
+ if (layerset && layerset->getViewerComposite() && layerset->getViewerComposite()->uploadPending())
{
return true;
}
@@ -1549,22 +1599,23 @@ bool LLVOAvatarSelf::hasPendingBakedUploads() const
void LLVOAvatarSelf::invalidateComposite( LLTexLayerSet* layerset, BOOL upload_result )
{
- if( !layerset || !layerset->getUpdatesEnabled() )
+ LLViewerTexLayerSet *layer_set = dynamic_cast<LLViewerTexLayerSet*>(layerset);
+ if( !layer_set || !layer_set->getUpdatesEnabled() )
{
return;
}
// llinfos << "LLVOAvatar::invalidComposite() " << layerset->getBodyRegionName() << llendl;
- layerset->requestUpdate();
- layerset->invalidateMorphMasks();
+ layer_set->requestUpdate();
+ layer_set->invalidateMorphMasks();
- if( upload_result )
+ if( upload_result && (getRegion() && !getRegion()->getCentralBakeVersion()))
{
llassert(isSelf());
- ETextureIndex baked_te = getBakedTE( layerset );
+ ETextureIndex baked_te = getBakedTE( layer_set );
setTEImage( baked_te, LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT_AVATAR) );
- layerset->requestUpload();
+ layer_set->requestUpload();
updateMeshTextures();
}
}
@@ -1573,7 +1624,8 @@ void LLVOAvatarSelf::invalidateAll()
{
for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
{
- invalidateComposite(mBakedTextureDatas[i].mTexLayerSet, TRUE);
+ LLViewerTexLayerSet *layerset = getTexLayerSet(i);
+ invalidateComposite(layerset, TRUE);
}
//mDebugSelfLoadTimer.reset();
}
@@ -1591,17 +1643,19 @@ void LLVOAvatarSelf::setCompositeUpdatesEnabled( bool b )
void LLVOAvatarSelf::setCompositeUpdatesEnabled(U32 index, bool b)
{
- if (mBakedTextureDatas[index].mTexLayerSet )
+ LLViewerTexLayerSet *layerset = getTexLayerSet(index);
+ if (layerset )
{
- mBakedTextureDatas[index].mTexLayerSet->setUpdatesEnabled( b );
+ layerset->setUpdatesEnabled( b );
}
}
bool LLVOAvatarSelf::isCompositeUpdateEnabled(U32 index)
{
- if (mBakedTextureDatas[index].mTexLayerSet)
+ LLViewerTexLayerSet *layerset = getTexLayerSet(index);
+ if (layerset)
{
- return mBakedTextureDatas[index].mTexLayerSet->getUpdatesEnabled();
+ return layerset->getUpdatesEnabled();
}
return false;
}
@@ -1612,9 +1666,10 @@ void LLVOAvatarSelf::setupComposites()
{
ETextureIndex tex_index = mBakedTextureDatas[i].mTextureIndex;
BOOL layer_baked = isTextureDefined(tex_index, gAgentWearables.getWearableCount(tex_index));
- if (mBakedTextureDatas[i].mTexLayerSet)
+ LLViewerTexLayerSet *layerset = getTexLayerSet(i);
+ if (layerset)
{
- mBakedTextureDatas[i].mTexLayerSet->setUpdatesEnabled(!layer_baked);
+ layerset->setUpdatesEnabled(!layer_baked);
}
}
}
@@ -1623,10 +1678,11 @@ void LLVOAvatarSelf::updateComposites()
{
for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
{
- if (mBakedTextureDatas[i].mTexLayerSet
+ LLViewerTexLayerSet *layerset = getTexLayerSet(i);
+ if (layerset
&& ((i != BAKED_SKIRT) || isWearingWearableType(LLWearableType::WT_SKIRT)))
{
- mBakedTextureDatas[i].mTexLayerSet->updateComposite();
+ layerset->updateComposite();
}
}
}
@@ -1639,11 +1695,12 @@ S32 LLVOAvatarSelf::getLocalDiscardLevel(ETextureIndex type, U32 wearable_index)
const LLLocalTextureObject *local_tex_obj = getLocalTextureObject(type, wearable_index);
if (local_tex_obj)
{
+ const LLViewerFetchedTexture* image = dynamic_cast<LLViewerFetchedTexture*>( local_tex_obj->getImage() );
if (type >= 0
&& local_tex_obj->getID() != IMG_DEFAULT_AVATAR
- && !local_tex_obj->getImage()->isMissingAsset())
+ && !image->isMissingAsset())
{
- return local_tex_obj->getImage()->getDiscardLevel();
+ return image->getDiscardLevel();
}
else
{
@@ -1668,7 +1725,7 @@ void LLVOAvatarSelf::getLocalTextureByteCount(S32* gl_bytes) const
const LLLocalTextureObject *local_tex_obj = getLocalTextureObject((ETextureIndex) type, num);
if (local_tex_obj)
{
- const LLViewerFetchedTexture* image_gl = local_tex_obj->getImage();
+ const LLViewerFetchedTexture* image_gl = dynamic_cast<LLViewerFetchedTexture*>( local_tex_obj->getImage() );
if (image_gl)
{
S32 bytes = (S32)image_gl->getWidth() * image_gl->getHeight() * image_gl->getComponents();
@@ -1703,8 +1760,8 @@ void LLVOAvatarSelf::setLocalTexture(ETextureIndex type, LLViewerTexture* src_te
llerrs << "Tried to set local texture with invalid type: (" << (U32) type << ", " << index << ")" << llendl;
return;
}
- LLWearableType::EType wearable_type = LLVOAvatarDictionary::getInstance()->getTEWearableType(type);
- if (!gAgentWearables.getWearable(wearable_type,index))
+ LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getInstance()->getTEWearableType(type);
+ if (!gAgentWearables.getViewerWearable(wearable_type,index))
{
// no wearable is loaded, cannot set the texture.
return;
@@ -1717,10 +1774,10 @@ void LLVOAvatarSelf::setLocalTexture(ETextureIndex type, LLViewerTexture* src_te
return;
}
- LLTexLayerSet *layer_set = getLayerSet(type);
+ LLViewerTexLayerSet *layer_set = getLayerSet(type);
if (layer_set)
{
- layer_set->cloneTemplates(local_tex_obj, type, gAgentWearables.getWearable(wearable_type,index));
+ layer_set->cloneTemplates(local_tex_obj, type, gAgentWearables.getViewerWearable(wearable_type,index));
}
}
@@ -1740,11 +1797,8 @@ void LLVOAvatarSelf::setLocalTexture(ETextureIndex type, LLViewerTexture* src_te
local_tex_obj->setDiscard(tex_discard);
if (isSelf())
{
- if (gAgentAvatarp->isUsingBakedTextures())
- {
requestLayerSetUpdate(type);
- }
- else
+ if (isEditingAppearance())
{
LLVisualParamHint::requestHintUpdates();
}
@@ -1762,8 +1816,9 @@ void LLVOAvatarSelf::setLocalTexture(ETextureIndex type, LLViewerTexture* src_te
local_tex_obj->setID(tex->getID());
setBakedReady(type,baked_version_ready,index);
}
+
//virtual
-void LLVOAvatarSelf::setBakedReady(LLVOAvatarDefines::ETextureIndex type, BOOL baked_version_exists, U32 index)
+void LLVOAvatarSelf::setBakedReady(LLAvatarAppearanceDefines::ETextureIndex type, BOOL baked_version_exists, U32 index)
{
if (!isIndexLocalTexture(type)) return;
LLLocalTextureObject *local_tex_obj = getLocalTextureObject(type,index);
@@ -1782,16 +1837,16 @@ void LLVOAvatarSelf::dumpLocalTextures() const
/* ETextureIndex baked_equiv[] = {
TEX_UPPER_BAKED,
if (isTextureDefined(baked_equiv[i])) */
- for (LLVOAvatarDictionary::Textures::const_iterator iter = LLVOAvatarDictionary::getInstance()->getTextures().begin();
- iter != LLVOAvatarDictionary::getInstance()->getTextures().end();
+ for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getTextures().begin();
+ iter != LLAvatarAppearanceDictionary::getInstance()->getTextures().end();
++iter)
{
- const LLVOAvatarDictionary::TextureEntry *texture_dict = iter->second;
+ const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = iter->second;
if (!texture_dict->mIsLocalTexture || !texture_dict->mIsUsedByBakedTexture)
continue;
const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex;
- const ETextureIndex baked_equiv = LLVOAvatarDictionary::getInstance()->getBakedTexture(baked_index)->mTextureIndex;
+ const ETextureIndex baked_equiv = LLAvatarAppearanceDictionary::getInstance()->getBakedTexture(baked_index)->mTextureIndex;
const std::string &name = texture_dict->mName;
const LLLocalTextureObject *local_tex_obj = getLocalTextureObject(iter->first, 0);
@@ -1814,7 +1869,7 @@ void LLVOAvatarSelf::dumpLocalTextures() const
}
else
{
- const LLViewerFetchedTexture* image = local_tex_obj->getImage();
+ const LLViewerFetchedTexture* image = dynamic_cast<LLViewerFetchedTexture*>( local_tex_obj->getImage() );
llinfos << "LocTex " << name << ": "
<< "Discard " << image->getDiscardLevel() << ", "
@@ -1889,37 +1944,65 @@ void LLVOAvatarSelf::dumpTotalLocalTextureByteCount()
llinfos << "Total Avatar LocTex GL:" << (gl_bytes/1024) << "KB" << llendl;
}
-BOOL LLVOAvatarSelf::getIsCloud()
+BOOL LLVOAvatarSelf::getIsCloud() const
{
+ // Let people know why they're clouded without spamming them into oblivion.
+ bool do_warn = false;
+ static LLTimer time_since_notice;
+ F32 update_freq = 30.0;
+ if (time_since_notice.getElapsedTimeF32() > update_freq)
+ {
+ time_since_notice.reset();
+ do_warn = true;
+ }
+
// do we have our body parts?
- if (gAgentWearables.getWearableCount(LLWearableType::WT_SHAPE) == 0 ||
- gAgentWearables.getWearableCount(LLWearableType::WT_HAIR) == 0 ||
- gAgentWearables.getWearableCount(LLWearableType::WT_EYES) == 0 ||
- gAgentWearables.getWearableCount(LLWearableType::WT_SKIN) == 0)
+ S32 shape_count = gAgentWearables.getWearableCount(LLWearableType::WT_SHAPE);
+ S32 hair_count = gAgentWearables.getWearableCount(LLWearableType::WT_HAIR);
+ S32 eye_count = gAgentWearables.getWearableCount(LLWearableType::WT_EYES);
+ S32 skin_count = gAgentWearables.getWearableCount(LLWearableType::WT_SKIN);
+ if (!shape_count || !hair_count || !eye_count || !skin_count)
{
- lldebugs << "No body parts" << llendl;
+ if (do_warn)
+ {
+ llinfos << "Self is clouded due to missing one or more required body parts: "
+ << (shape_count ? "" : "SHAPE ")
+ << (hair_count ? "" : "HAIR ")
+ << (eye_count ? "" : "EYES ")
+ << (skin_count ? "" : "SKIN ")
+ << llendl;
+ }
return TRUE;
}
if (!isTextureDefined(TEX_HAIR, 0))
{
- lldebugs << "No hair texture" << llendl;
+ if (do_warn)
+ {
+ llinfos << "Self is clouded because of no hair texture" << llendl;
+ }
return TRUE;
}
if (!mPreviousFullyLoaded)
{
- if (!isLocalTextureDataAvailable(mBakedTextureDatas[BAKED_LOWER].mTexLayerSet) &&
+ if (!isLocalTextureDataAvailable(getLayerSet(BAKED_LOWER)) &&
(!isTextureDefined(TEX_LOWER_BAKED, 0)))
{
- lldebugs << "Lower textures not baked" << llendl;
+ if (do_warn)
+ {
+ llinfos << "Self is clouded because lower textures not baked" << llendl;
+ }
return TRUE;
}
- if (!isLocalTextureDataAvailable(mBakedTextureDatas[BAKED_UPPER].mTexLayerSet) &&
+ if (!isLocalTextureDataAvailable(getLayerSet(BAKED_UPPER)) &&
(!isTextureDefined(TEX_UPPER_BAKED, 0)))
{
- lldebugs << "Upper textures not baked" << llendl;
+ if (do_warn)
+ {
+ llinfos << "Self is clouded because upper textures not baked" << llendl;
+ }
return TRUE;
}
@@ -1936,7 +2019,11 @@ BOOL LLVOAvatarSelf::getIsCloud()
const LLViewerTexture* baked_img = getImage( texture_data.mTextureIndex, 0 );
if (!baked_img || !baked_img->hasGLTexture())
{
- lldebugs << "Texture at index " << i << " (texture index is " << texture_data.mTextureIndex << ") is not loaded" << llendl;
+ if (do_warn)
+ {
+ llinfos << "Self is clouded because texture at index " << i
+ << " (texture index is " << texture_data.mTextureIndex << ") is not loaded" << llendl;
+ }
return TRUE;
}
}
@@ -1987,7 +2074,85 @@ void LLVOAvatarSelf::debugBakedTextureUpload(EBakedTextureIndex index, BOOL fini
mDebugBakedTextureTimes[index][done] = mDebugSelfLoadTimer.getElapsedTimeF32();
}
-const std::string LLVOAvatarSelf::debugDumpLocalTextureDataInfo(const LLTexLayerSet* layerset) const
+const std::string LLVOAvatarSelf::verboseDebugDumpLocalTextureDataInfo(const LLViewerTexLayerSet* layerset) const
+{
+ std::ostringstream outbuf;
+ for (LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter =
+ LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().begin();
+ baked_iter != LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().end();
+ ++baked_iter)
+ {
+ const EBakedTextureIndex baked_index = baked_iter->first;
+ if (layerset == mBakedTextureDatas[baked_index].mTexLayerSet)
+ {
+ outbuf << "baked_index: " << baked_index << "\n";
+ const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = baked_iter->second;
+ for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin();
+ local_tex_iter != baked_dict->mLocalTextures.end();
+ ++local_tex_iter)
+ {
+ const ETextureIndex tex_index = *local_tex_iter;
+ const std::string tex_name = LLAvatarAppearanceDictionary::getInstance()->getTexture(tex_index)->mName;
+ outbuf << " tex_index " << (S32) tex_index << " name " << tex_name << "\n";
+ const LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getTEWearableType(tex_index);
+ const U32 wearable_count = gAgentWearables.getWearableCount(wearable_type);
+ if (wearable_count > 0)
+ {
+ for (U32 wearable_index = 0; wearable_index < wearable_count; wearable_index++)
+ {
+ outbuf << " " << LLWearableType::getTypeName(wearable_type) << " " << wearable_index << ":";
+ const LLLocalTextureObject *local_tex_obj = getLocalTextureObject(tex_index, wearable_index);
+ if (local_tex_obj)
+ {
+ LLViewerFetchedTexture* image = dynamic_cast<LLViewerFetchedTexture*>( local_tex_obj->getImage() );
+ if (tex_index >= 0
+ && local_tex_obj->getID() != IMG_DEFAULT_AVATAR
+ && !image->isMissingAsset())
+ {
+ outbuf << " id: " << image->getID()
+ << " refs: " << image->getNumRefs()
+ << " glocdisc: " << getLocalDiscardLevel(tex_index, wearable_index)
+ << " discard: " << image->getDiscardLevel()
+ << " desired: " << image->getDesiredDiscardLevel()
+ << " decode: " << image->getDecodePriority()
+ << " addl: " << image->getAdditionalDecodePriority()
+ << " ts: " << image->getTextureState()
+ << " bl: " << image->getBoostLevel()
+ << " fl: " << image->isFullyLoaded() // this is not an accessor for mFullyLoaded - see comment there.
+ << " cl: " << (image->isFullyLoaded() && image->getDiscardLevel()==0) // "completely loaded"
+ << " mvs: " << image->getMaxVirtualSize()
+ << " mvsc: " << image->getMaxVirtualSizeResetCounter()
+ << " mem: " << image->getTextureMemory();
+ }
+ }
+ outbuf << "\n";
+ }
+ }
+ }
+ break;
+ }
+ }
+ return outbuf.str();
+}
+
+void LLVOAvatarSelf::dumpAllTextures() const
+{
+ std::string vd_text = "Local textures per baked index and wearable:\n";
+ for (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().begin();
+ baked_iter != LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().end();
+ ++baked_iter)
+ {
+ const LLAvatarAppearanceDefines::EBakedTextureIndex baked_index = baked_iter->first;
+ const LLViewerTexLayerSet *layerset = debugGetLayerSet(baked_index);
+ if (!layerset) continue;
+ const LLViewerTexLayerSetBuffer *layerset_buffer = layerset->getViewerComposite();
+ if (!layerset_buffer) continue;
+ vd_text += verboseDebugDumpLocalTextureDataInfo(layerset);
+ }
+ LL_DEBUGS("Avatar") << vd_text << llendl;
+}
+
+const std::string LLVOAvatarSelf::debugDumpLocalTextureDataInfo(const LLViewerTexLayerSet* layerset) const
{
std::string text="";
@@ -1995,21 +2160,21 @@ const std::string LLVOAvatarSelf::debugDumpLocalTextureDataInfo(const LLTexLayer
/* if (layerset == mBakedTextureDatas[BAKED_HEAD].mTexLayerSet)
return getLocalDiscardLevel(TEX_HEAD_BODYPAINT) >= 0; */
- for (LLVOAvatarDictionary::BakedTextures::const_iterator baked_iter = LLVOAvatarDictionary::getInstance()->getBakedTextures().begin();
- baked_iter != LLVOAvatarDictionary::getInstance()->getBakedTextures().end();
+ for (LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().begin();
+ baked_iter != LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().end();
++baked_iter)
{
const EBakedTextureIndex baked_index = baked_iter->first;
if (layerset == mBakedTextureDatas[baked_index].mTexLayerSet)
{
- const LLVOAvatarDictionary::BakedEntry *baked_dict = baked_iter->second;
+ const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = baked_iter->second;
text += llformat("%d-%s ( ",baked_index, baked_dict->mName.c_str());
for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin();
local_tex_iter != baked_dict->mLocalTextures.end();
++local_tex_iter)
{
const ETextureIndex tex_index = *local_tex_iter;
- const LLWearableType::EType wearable_type = LLVOAvatarDictionary::getTEWearableType(tex_index);
+ const LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getTEWearableType(tex_index);
const U32 wearable_count = gAgentWearables.getWearableCount(wearable_type);
if (wearable_count > 0)
{
@@ -2036,14 +2201,14 @@ const std::string LLVOAvatarSelf::debugDumpAllLocalTextureDataInfo() const
for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
{
- const LLVOAvatarDictionary::BakedEntry *baked_dict = LLVOAvatarDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)i);
+ const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = LLAvatarAppearanceDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)i);
BOOL is_texture_final = TRUE;
for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin();
local_tex_iter != baked_dict->mLocalTextures.end();
++local_tex_iter)
{
const ETextureIndex tex_index = *local_tex_iter;
- const LLWearableType::EType wearable_type = LLVOAvatarDictionary::getTEWearableType(tex_index);
+ const LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getTEWearableType(tex_index);
const U32 wearable_count = gAgentWearables.getWearableCount(wearable_type);
for (U32 wearable_index = 0; wearable_index < wearable_count; wearable_index++)
{
@@ -2055,11 +2220,271 @@ const std::string LLVOAvatarSelf::debugDumpAllLocalTextureDataInfo() const
return text;
}
+
+#if 0
+// Dump avatar metrics data.
+LLSD LLVOAvatarSelf::metricsData()
+{
+ // runway - add region info
+ LLSD result;
+ result["rez_status"] = LLVOAvatar::rezStatusToString(getRezzedStatus());
+ result["timers"]["debug_existence"] = mDebugExistenceTimer.getElapsedTimeF32();
+ result["timers"]["ruth_debug"] = mRuthDebugTimer.getElapsedTimeF32();
+ result["timers"]["ruth"] = mRuthTimer.getElapsedTimeF32();
+ result["timers"]["invisible"] = mInvisibleTimer.getElapsedTimeF32();
+ result["timers"]["fully_loaded"] = mFullyLoadedTimer.getElapsedTimeF32();
+ result["startup"] = LLStartUp::getPhases().dumpPhases();
+
+ return result;
+}
+#endif
+
+class ViewerAppearanceChangeMetricsResponder: public LLCurl::Responder
+{
+public:
+ ViewerAppearanceChangeMetricsResponder( S32 expected_sequence,
+ volatile const S32 & live_sequence,
+ volatile bool & reporting_started):
+ mExpectedSequence(expected_sequence),
+ mLiveSequence(live_sequence),
+ mReportingStarted(reporting_started)
+ {
+ }
+
+ virtual void completed(U32 status,
+ const std::string& reason,
+ const LLSD& content)
+ {
+ gPendingMetricsUploads--; // if we add retry, this should be moved to the isGoodStatus case.
+ if (isGoodStatus(status))
+ {
+ LL_DEBUGS("Avatar") << "OK" << LL_ENDL;
+ result(content);
+ }
+ else
+ {
+ LL_WARNS("Avatar") << "Failed " << status << " reason " << reason << LL_ENDL;
+ errorWithContent(status,reason,content);
+ }
+ }
+
+ // virtual
+ void result(const LLSD & content)
+ {
+ if (mLiveSequence == mExpectedSequence)
+ {
+ mReportingStarted = true;
+ }
+ }
+
+private:
+ S32 mExpectedSequence;
+ volatile const S32 & mLiveSequence;
+ volatile bool & mReportingStarted;
+};
+
+bool LLVOAvatarSelf::updateAvatarRezMetrics(bool force_send)
+{
+ const F32 AV_METRICS_INTERVAL_QA = 30.0;
+ F32 send_period = 300.0;
+ if (gSavedSettings.getBOOL("QAModeMetrics"))
+ {
+ send_period = AV_METRICS_INTERVAL_QA;
+ }
+
+ if (force_send || mTimeSinceLastRezMessage.getElapsedTimeF32() > send_period)
+ {
+ // Stats for completed phases have been getting logged as they
+ // complete. This will give us stats for any timers that
+ // haven't finished as of the metric's being sent.
+
+ if (force_send)
+ {
+ LLVOAvatar::logPendingPhasesAllAvatars();
+ }
+ sendViewerAppearanceChangeMetrics();
+ }
+
+ return false;
+}
+
+void LLVOAvatarSelf::addMetricsTimerRecord(const LLSD& record)
+{
+ mPendingTimerRecords.push_back(record);
+}
+
+bool operator<(const LLSD& a, const LLSD& b)
+{
+ std::ostringstream aout, bout;
+ aout << LLSDNotationStreamer(a);
+ bout << LLSDNotationStreamer(b);
+ std::string astring = aout.str();
+ std::string bstring = bout.str();
+
+ return astring < bstring;
+
+}
+
+// Given a vector of LLSD records, return an LLSD array of bucketed stats for val_field.
+LLSD summarize_by_buckets(std::vector<LLSD> in_records,
+ std::vector<std::string> by_fields,
+ std::string val_field)
+{
+ LLSD result = LLSD::emptyArray();
+ std::map<LLSD,LLViewerStats::StatsAccumulator> accum;
+ for (std::vector<LLSD>::iterator in_record_iter = in_records.begin();
+ in_record_iter != in_records.end(); ++in_record_iter)
+ {
+ LLSD& record = *in_record_iter;
+ LLSD key;
+ for (std::vector<std::string>::iterator field_iter = by_fields.begin();
+ field_iter != by_fields.end(); ++field_iter)
+ {
+ const std::string& field = *field_iter;
+ key[field] = record[field];
+ }
+ LLViewerStats::StatsAccumulator& stats = accum[key];
+ F32 value = record[val_field].asReal();
+ stats.push(value);
+ }
+ for (std::map<LLSD,LLViewerStats::StatsAccumulator>::iterator accum_it = accum.begin();
+ accum_it != accum.end(); ++accum_it)
+ {
+ LLSD out_record = accum_it->first;
+ out_record["stats"] = accum_it->second.getData();
+ result.append(out_record);
+ }
+ return result;
+}
+
+void LLVOAvatarSelf::sendViewerAppearanceChangeMetrics()
+{
+ // gAgentAvatarp->stopAllPhases();
+ static volatile bool reporting_started(false);
+ static volatile S32 report_sequence(0);
+
+ LLSD msg; // = metricsData();
+ msg["message"] = "ViewerAppearanceChangeMetrics";
+ msg["session_id"] = gAgentSessionID;
+ msg["agent_id"] = gAgentID;
+ msg["sequence"] = report_sequence;
+ msg["initial"] = !reporting_started;
+ msg["break"] = false;
+ msg["duration"] = mTimeSinceLastRezMessage.getElapsedTimeF32();
+
+ // Status of our own rezzing.
+ msg["rez_status"] = LLVOAvatar::rezStatusToString(getRezzedStatus());
+
+ // Status of all nearby avs including ourself.
+ msg["nearby"] = LLSD::emptyArray();
+ std::vector<S32> rez_counts;
+ LLVOAvatar::getNearbyRezzedStats(rez_counts);
+ for (S32 rez_stat=0; rez_stat < rez_counts.size(); ++rez_stat)
+ {
+ std::string rez_status_name = LLVOAvatar::rezStatusToString(rez_stat);
+ msg["nearby"][rez_status_name] = rez_counts[rez_stat];
+ }
+
+ // std::vector<std::string> bucket_fields("timer_name","is_self","grid_x","grid_y","is_using_server_bake");
+ std::vector<std::string> by_fields;
+ by_fields.push_back("timer_name");
+ by_fields.push_back("completed");
+ by_fields.push_back("grid_x");
+ by_fields.push_back("grid_y");
+ by_fields.push_back("is_using_server_bakes");
+ by_fields.push_back("is_self");
+ by_fields.push_back("central_bake_version");
+ LLSD summary = summarize_by_buckets(mPendingTimerRecords, by_fields, std::string("elapsed"));
+ msg["timers"] = summary;
+
+ mPendingTimerRecords.clear();
+
+ // Update sequence number
+ if (S32_MAX == ++report_sequence)
+ report_sequence = 0;
+
+ LL_DEBUGS("Avatar") << avString() << "message: " << ll_pretty_print_sd(msg) << LL_ENDL;
+ std::string caps_url;
+ if (getRegion())
+ {
+ // runway - change here to activate.
+ caps_url = getRegion()->getCapability("ViewerMetrics");
+ }
+ if (!caps_url.empty())
+ {
+ gPendingMetricsUploads++;
+ LLCurlRequest::headers_t headers;
+ LLHTTPClient::post(caps_url,
+ msg,
+ new ViewerAppearanceChangeMetricsResponder(report_sequence,
+ report_sequence,
+ reporting_started));
+ mTimeSinceLastRezMessage.reset();
+ }
+}
+
+class CheckAgentAppearanceServiceResponder: public LLHTTPClient::Responder
+{
+public:
+ CheckAgentAppearanceServiceResponder()
+ {
+ }
+
+ virtual ~CheckAgentAppearanceServiceResponder()
+ {
+ }
+
+ /* virtual */ void result(const LLSD& content)
+ {
+ LL_DEBUGS("Avatar") << "status OK" << llendl;
+ }
+
+ // Error
+ /*virtual*/ void errorWithContent(U32 status, const std::string& reason, const LLSD& content)
+ {
+ if (isAgentAvatarValid())
+ {
+ LL_DEBUGS("Avatar") << "failed, will rebake [status:"
+ << status << "]: " << content << llendl;
+ forceAppearanceUpdate();
+ }
+ }
+
+ static void forceAppearanceUpdate()
+ {
+ // Trying to rebake immediately after crossing region boundary
+ // seems to be failure prone; adding a delay factor. Yes, this
+ // fix is ad-hoc and not guaranteed to work in all cases.
+ doAfterInterval(boost::bind(&LLVOAvatarSelf::forceBakeAllTextures,
+ gAgentAvatarp.get(), true), 5.0);
+ }
+};
+
+void LLVOAvatarSelf::checkForUnsupportedServerBakeAppearance()
+{
+ // Need to check only if we have a server baked appearance and are
+ // in a non-baking region.
+ if (!gAgentAvatarp->isUsingServerBakes())
+ return;
+ if (!gAgent.getRegion() || gAgent.getRegion()->getCentralBakeVersion()!=0)
+ return;
+
+ // if baked image service is unknown, need to refresh.
+ if (LLAppearanceMgr::instance().getAppearanceServiceURL().empty())
+ {
+ CheckAgentAppearanceServiceResponder::forceAppearanceUpdate();
+ }
+ // query baked image service to check status.
+ std::string image_url = gAgentAvatarp->getImageURL(TEX_HEAD_BAKED,
+ getTE(TEX_HEAD_BAKED)->getID());
+ LLHTTPClient::head(image_url, new CheckAgentAppearanceServiceResponder);
+}
+
const LLUUID& LLVOAvatarSelf::grabBakedTexture(EBakedTextureIndex baked_index) const
{
if (canGrabBakedTexture(baked_index))
{
- ETextureIndex tex_index = LLVOAvatarDictionary::bakedToLocalTextureIndex(baked_index);
+ ETextureIndex tex_index = LLAvatarAppearanceDictionary::bakedToLocalTextureIndex(baked_index);
if (tex_index == TEX_NUM_INDICES)
{
return LLUUID::null;
@@ -2071,7 +2496,7 @@ const LLUUID& LLVOAvatarSelf::grabBakedTexture(EBakedTextureIndex baked_index) c
BOOL LLVOAvatarSelf::canGrabBakedTexture(EBakedTextureIndex baked_index) const
{
- ETextureIndex tex_index = LLVOAvatarDictionary::bakedToLocalTextureIndex(baked_index);
+ ETextureIndex tex_index = LLAvatarAppearanceDictionary::bakedToLocalTextureIndex(baked_index);
if (tex_index == TEX_NUM_INDICES)
{
return FALSE;
@@ -2090,19 +2515,19 @@ BOOL LLVOAvatarSelf::canGrabBakedTexture(EBakedTextureIndex baked_index) const
// baked texture. We don't want people copying people's
// work via baked textures.
- const LLVOAvatarDictionary::BakedEntry *baked_dict = LLVOAvatarDictionary::getInstance()->getBakedTexture(baked_index);
+ const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = LLAvatarAppearanceDictionary::getInstance()->getBakedTexture(baked_index);
for (texture_vec_t::const_iterator iter = baked_dict->mLocalTextures.begin();
iter != baked_dict->mLocalTextures.end();
++iter)
{
const ETextureIndex t_index = (*iter);
- LLWearableType::EType wearable_type = LLVOAvatarDictionary::getTEWearableType(t_index);
+ LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getTEWearableType(t_index);
U32 count = gAgentWearables.getWearableCount(wearable_type);
lldebugs << "Checking index " << (U32) t_index << " count: " << count << llendl;
for (U32 wearable_index = 0; wearable_index < count; ++wearable_index)
{
- LLWearable *wearable = gAgentWearables.getWearable(wearable_type, wearable_index);
+ LLViewerWearable *wearable = gAgentWearables.getViewerWearable(wearable_type, wearable_index);
if (wearable)
{
const LLLocalTextureObject *texture = wearable->getLocalTextureObject((S32)t_index);
@@ -2144,28 +2569,36 @@ BOOL LLVOAvatarSelf::canGrabBakedTexture(EBakedTextureIndex baked_index) const
}
void LLVOAvatarSelf::addLocalTextureStats( ETextureIndex type, LLViewerFetchedTexture* imagep,
- F32 texel_area_ratio, BOOL render_avatar, BOOL covered_by_baked, U32 index )
+ F32 texel_area_ratio, BOOL render_avatar, BOOL covered_by_baked)
{
if (!isIndexLocalTexture(type)) return;
- if (!covered_by_baked)
+ // Sunshine - ignoring covered_by_baked will force local textures
+ // to always load. Fix for SH-4001 and many related issues. Do
+ // not restore this without some more targetted fix for the local
+ // textures failing to load issue.
+ //if (!covered_by_baked)
{
- if (getLocalTextureID(type, index) != IMG_DEFAULT_AVATAR && imagep->getDiscardLevel() != 0)
+ if (imagep->getID() != IMG_DEFAULT_AVATAR)
+ {
+ imagep->setNoDelete();
+ if (imagep->getDiscardLevel() != 0)
{
F32 desired_pixels;
desired_pixels = llmin(mPixelArea, (F32)getTexImageArea());
- imagep->setBoostLevel(getAvatarBoostLevel());
+ imagep->setBoostLevel(getAvatarBoostLevel());
+ imagep->setAdditionalDecodePriority(SELF_ADDITIONAL_PRI) ;
imagep->resetTextureStats();
imagep->setMaxVirtualSizeResetInterval(MAX_TEXTURE_VIRTURE_SIZE_RESET_INTERVAL);
imagep->addTextureStats( desired_pixels / texel_area_ratio );
- imagep->setAdditionalDecodePriority(SELF_ADDITIONAL_PRI) ;
imagep->forceUpdateBindStats() ;
if (imagep->getDiscardLevel() < 0)
{
mHasGrey = TRUE; // for statistics gathering
}
}
+ }
else
{
// texture asset is missing
@@ -2174,10 +2607,10 @@ void LLVOAvatarSelf::addLocalTextureStats( ETextureIndex type, LLViewerFetchedTe
}
}
-LLLocalTextureObject* LLVOAvatarSelf::getLocalTextureObject(LLVOAvatarDefines::ETextureIndex i, U32 wearable_index) const
+LLLocalTextureObject* LLVOAvatarSelf::getLocalTextureObject(LLAvatarAppearanceDefines::ETextureIndex i, U32 wearable_index) const
{
- LLWearableType::EType type = LLVOAvatarDictionary::getInstance()->getTEWearableType(i);
- LLWearable* wearable = gAgentWearables.getWearable(type, wearable_index);
+ LLWearableType::EType type = LLAvatarAppearanceDictionary::getInstance()->getTEWearableType(i);
+ LLViewerWearable* wearable = gAgentWearables.getViewerWearable(type, wearable_index);
if (wearable)
{
return wearable->getLocalTextureObject(i);
@@ -2190,7 +2623,7 @@ LLLocalTextureObject* LLVOAvatarSelf::getLocalTextureObject(LLVOAvatarDefines::E
// getBakedTE()
// Used by the LayerSet. (Layer sets don't in general know what textures depend on them.)
//-----------------------------------------------------------------------------
-ETextureIndex LLVOAvatarSelf::getBakedTE( const LLTexLayerSet* layerset ) const
+ETextureIndex LLVOAvatarSelf::getBakedTE( const LLViewerTexLayerSet* layerset ) const
{
for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
{
@@ -2204,9 +2637,9 @@ ETextureIndex LLVOAvatarSelf::getBakedTE( const LLTexLayerSet* layerset ) const
}
-void LLVOAvatarSelf::setNewBakedTexture(LLVOAvatarDefines::EBakedTextureIndex i, const LLUUID &uuid)
+void LLVOAvatarSelf::setNewBakedTexture(LLAvatarAppearanceDefines::EBakedTextureIndex i, const LLUUID &uuid)
{
- ETextureIndex index = LLVOAvatarDictionary::bakedToLocalTextureIndex(i);
+ ETextureIndex index = LLAvatarAppearanceDictionary::bakedToLocalTextureIndex(i);
setNewBakedTexture(index, uuid);
}
@@ -2219,7 +2652,7 @@ void LLVOAvatarSelf::setNewBakedTexture( ETextureIndex te, const LLUUID& uuid )
{
// Baked textures live on other sims.
LLHost target_host = getObjectHost();
- setTEImage( te, LLViewerTextureManager::getFetchedTextureFromHost( uuid, target_host ) );
+ setTEImage( te, LLViewerTextureManager::getFetchedTextureFromHost( uuid, FTT_HOST_BAKE, target_host ) );
updateMeshTextures();
dirtyMesh();
@@ -2228,7 +2661,7 @@ void LLVOAvatarSelf::setNewBakedTexture( ETextureIndex te, const LLUUID& uuid )
/* switch(te)
case TEX_HEAD_BAKED:
llinfos << "New baked texture: HEAD" << llendl; */
- const LLVOAvatarDictionary::TextureEntry *texture_dict = LLVOAvatarDictionary::getInstance()->getTexture(te);
+ const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearanceDictionary::getInstance()->getTexture(te);
if (texture_dict->mIsBakedTexture)
{
debugBakedTextureUpload(texture_dict->mBakedTextureIndex, TRUE); // FALSE for start of upload, TRUE for finish.
@@ -2253,11 +2686,25 @@ void LLVOAvatarSelf::setNewBakedTexture( ETextureIndex te, const LLUUID& uuid )
if (isAllLocalTextureDataFinal())
{
LLNotificationsUtil::add("AvatarRezSelfBakedDoneNotification",args);
+ LL_DEBUGS("Avatar") << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32()
+ << "sec ]"
+ << avString()
+ << "RuthTimer " << (U32)mRuthDebugTimer.getElapsedTimeF32()
+ << " SelfLoadTimer " << (U32)mDebugSelfLoadTimer.getElapsedTimeF32()
+ << " Notification " << "AvatarRezSelfBakedDoneNotification"
+ << llendl;
}
else
{
args["STATUS"] = debugDumpAllLocalTextureDataInfo();
LLNotificationsUtil::add("AvatarRezSelfBakedUpdateNotification",args);
+ LL_DEBUGS("Avatar") << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32()
+ << "sec ]"
+ << avString()
+ << "RuthTimer " << (U32)mRuthDebugTimer.getElapsedTimeF32()
+ << " SelfLoadTimer " << (U32)mDebugSelfLoadTimer.getElapsedTimeF32()
+ << " Notification " << "AvatarRezSelfBakedUpdateNotification"
+ << llendl;
}
}
@@ -2265,7 +2712,7 @@ void LLVOAvatarSelf::setNewBakedTexture( ETextureIndex te, const LLUUID& uuid )
}
}
-// FIXME: This is never called. Something may be broken.
+// FIXME: This is not called consistently. Something may be broken.
void LLVOAvatarSelf::outputRezDiagnostics() const
{
if(!gSavedSettings.getBOOL("DebugAvatarLocalTexLoadedTime"))
@@ -2274,12 +2721,12 @@ void LLVOAvatarSelf::outputRezDiagnostics() const
}
const F32 final_time = mDebugSelfLoadTimer.getElapsedTimeF32();
- llinfos << "REZTIME: Myself rez stats:" << llendl;
- llinfos << "\t Time from avatar creation to load wearables: " << (S32)mDebugTimeWearablesLoaded << llendl;
- llinfos << "\t Time from avatar creation to de-cloud: " << (S32)mDebugTimeAvatarVisible << llendl;
- llinfos << "\t Time from avatar creation to de-cloud for others: " << (S32)final_time << llendl;
- llinfos << "\t Load time for each texture: " << llendl;
- for (U32 i = 0; i < LLVOAvatarDefines::TEX_NUM_INDICES; ++i)
+ LL_DEBUGS("Avatar") << "REZTIME: Myself rez stats:" << llendl;
+ LL_DEBUGS("Avatar") << "\t Time from avatar creation to load wearables: " << (S32)mDebugTimeWearablesLoaded << llendl;
+ LL_DEBUGS("Avatar") << "\t Time from avatar creation to de-cloud: " << (S32)mDebugTimeAvatarVisible << llendl;
+ LL_DEBUGS("Avatar") << "\t Time from avatar creation to de-cloud for others: " << (S32)final_time << llendl;
+ LL_DEBUGS("Avatar") << "\t Load time for each texture: " << llendl;
+ for (U32 i = 0; i < LLAvatarAppearanceDefines::TEX_NUM_INDICES; ++i)
{
std::stringstream out;
out << "\t\t (" << i << ") ";
@@ -2302,32 +2749,37 @@ void LLVOAvatarSelf::outputRezDiagnostics() const
// Don't print out non-existent textures.
if (j != 0)
- llinfos << out.str() << llendl;
+ {
+ LL_DEBUGS("Avatar") << out.str() << LL_ENDL;
+ }
}
- llinfos << "\t Time points for each upload (start / finish)" << llendl;
- for (U32 i = 0; i < LLVOAvatarDefines::BAKED_NUM_INDICES; ++i)
+ LL_DEBUGS("Avatar") << "\t Time points for each upload (start / finish)" << llendl;
+ for (U32 i = 0; i < LLAvatarAppearanceDefines::BAKED_NUM_INDICES; ++i)
{
- llinfos << "\t\t (" << i << ") \t" << (S32)mDebugBakedTextureTimes[i][0] << " / " << (S32)mDebugBakedTextureTimes[i][1] << llendl;
+ LL_DEBUGS("Avatar") << "\t\t (" << i << ") \t" << (S32)mDebugBakedTextureTimes[i][0] << " / " << (S32)mDebugBakedTextureTimes[i][1] << llendl;
}
- for (LLVOAvatarDefines::LLVOAvatarDictionary::BakedTextures::const_iterator baked_iter = LLVOAvatarDefines::LLVOAvatarDictionary::getInstance()->getBakedTextures().begin();
- baked_iter != LLVOAvatarDefines::LLVOAvatarDictionary::getInstance()->getBakedTextures().end();
+ for (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().begin();
+ baked_iter != LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().end();
++baked_iter)
{
- const LLVOAvatarDefines::EBakedTextureIndex baked_index = baked_iter->first;
- const LLTexLayerSet *layerset = debugGetLayerSet(baked_index);
+ const LLAvatarAppearanceDefines::EBakedTextureIndex baked_index = baked_iter->first;
+ const LLViewerTexLayerSet *layerset = debugGetLayerSet(baked_index);
if (!layerset) continue;
- const LLTexLayerSetBuffer *layerset_buffer = layerset->getComposite();
+ const LLViewerTexLayerSetBuffer *layerset_buffer = layerset->getViewerComposite();
if (!layerset_buffer) continue;
- llinfos << layerset_buffer->dumpTextureInfo() << llendl;
+ LL_DEBUGS("Avatar") << layerset_buffer->dumpTextureInfo() << llendl;
}
+
+ dumpAllTextures();
}
void LLVOAvatarSelf::outputRezTiming(const std::string& msg) const
{
- LL_DEBUGS("Avatar Rez")
+ LL_DEBUGS("Avatar")
+ << avString()
<< llformat("%s. Time from avatar creation: %.2f", msg.c_str(), mDebugSelfLoadTimer.getElapsedTimeF32())
- << llendl;
+ << LL_ENDL;
}
void LLVOAvatarSelf::reportAvatarRezTime() const
@@ -2349,9 +2801,22 @@ void LLVOAvatarSelf::setCachedBakedTexture( ETextureIndex te, const LLUUID& uuid
mHeadLayerSet->cancelUpload(); */
for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
{
- if ( mBakedTextureDatas[i].mTextureIndex == te && mBakedTextureDatas[i].mTexLayerSet)
+ LLViewerTexLayerSet *layerset = getTexLayerSet(i);
+ if ( mBakedTextureDatas[i].mTextureIndex == te && layerset)
{
- mBakedTextureDatas[i].mTexLayerSet->cancelUpload();
+ if (mInitialBakeIDs[i] != LLUUID::null)
+ {
+ if (mInitialBakeIDs[i] == uuid)
+ {
+ llinfos << "baked texture correctly loaded at login! " << i << llendl;
+ }
+ else
+ {
+ llwarns << "baked texture does not match id loaded at login!" << i << llendl;
+ }
+ mInitialBakeIDs[i] = LLUUID::null;
+ }
+ layerset->cancelUpload();
}
}
}
@@ -2370,17 +2835,17 @@ void LLVOAvatarSelf::processRebakeAvatarTextures(LLMessageSystem* msg, void**)
/* ETextureIndex baked_texture_indices[BAKED_NUM_INDICES] =
TEX_HEAD_BAKED,
TEX_UPPER_BAKED, */
- for (LLVOAvatarDictionary::Textures::const_iterator iter = LLVOAvatarDictionary::getInstance()->getTextures().begin();
- iter != LLVOAvatarDictionary::getInstance()->getTextures().end();
+ for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getTextures().begin();
+ iter != LLAvatarAppearanceDictionary::getInstance()->getTextures().end();
++iter)
{
const ETextureIndex index = iter->first;
- const LLVOAvatarDictionary::TextureEntry *texture_dict = iter->second;
+ const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = iter->second;
if (texture_dict->mIsBakedTexture)
{
if (texture_id == gAgentAvatarp->getTEImage(index)->getID())
{
- LLTexLayerSet* layer_set = gAgentAvatarp->getLayerSet(index);
+ LLViewerTexLayerSet* layer_set = gAgentAvatarp->getLayerSet(index);
if (layer_set)
{
llinfos << "TAT: rebake - matched entry " << (S32)index << llendl;
@@ -2404,15 +2869,6 @@ void LLVOAvatarSelf::processRebakeAvatarTextures(LLMessageSystem* msg, void**)
}
}
-BOOL LLVOAvatarSelf::isUsingBakedTextures() const
-{
- // Composite textures are used during appearance mode.
- if (gAgentCamera.cameraCustomizeAvatar())
- return FALSE;
-
- return TRUE;
-}
-
void LLVOAvatarSelf::forceBakeAllTextures(bool slam_for_debug)
{
@@ -2421,7 +2877,7 @@ void LLVOAvatarSelf::forceBakeAllTextures(bool slam_for_debug)
for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
{
ETextureIndex baked_index = mBakedTextureDatas[i].mTextureIndex;
- LLTexLayerSet* layer_set = getLayerSet(baked_index);
+ LLViewerTexLayerSet* layer_set = getLayerSet(baked_index);
if (layer_set)
{
if (slam_for_debug)
@@ -2453,7 +2909,7 @@ void LLVOAvatarSelf::requestLayerSetUpdate(ETextureIndex index )
case LOCTEX_UPPER_SHIRT:
if( mUpperBodyLayerSet )
mUpperBodyLayerSet->requestUpdate(); */
- const LLVOAvatarDictionary::TextureEntry *texture_dict = LLVOAvatarDictionary::getInstance()->getTexture(index);
+ const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearanceDictionary::getInstance()->getTexture(index);
if (!texture_dict->mIsLocalTexture || !texture_dict->mIsUsedByBakedTexture)
return;
const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex;
@@ -2463,35 +2919,83 @@ void LLVOAvatarSelf::requestLayerSetUpdate(ETextureIndex index )
}
}
-LLTexLayerSet* LLVOAvatarSelf::getLayerSet(ETextureIndex index) const
+LLViewerTexLayerSet* LLVOAvatarSelf::getLayerSet(ETextureIndex index) const
{
/* switch(index)
case TEX_HEAD_BAKED:
case TEX_HEAD_BODYPAINT:
return mHeadLayerSet; */
- const LLVOAvatarDictionary::TextureEntry *texture_dict = LLVOAvatarDictionary::getInstance()->getTexture(index);
+ const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearanceDictionary::getInstance()->getTexture(index);
if (texture_dict->mIsUsedByBakedTexture)
{
const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex;
- return mBakedTextureDatas[baked_index].mTexLayerSet;
+ return getLayerSet(baked_index);
}
return NULL;
}
+LLViewerTexLayerSet* LLVOAvatarSelf::getLayerSet(EBakedTextureIndex baked_index) const
+{
+ /* switch(index)
+ case TEX_HEAD_BAKED:
+ case TEX_HEAD_BODYPAINT:
+ return mHeadLayerSet; */
+ if (baked_index >= 0 && baked_index < BAKED_NUM_INDICES)
+ {
+ return getTexLayerSet(baked_index);
+ }
+ return NULL;
+}
+
+
+
+
// static
-void LLVOAvatarSelf::onCustomizeStart()
+void LLVOAvatarSelf::onCustomizeStart(bool disable_camera_switch)
+{
+ if (isAgentAvatarValid())
+ {
+ gAgentAvatarp->mIsEditingAppearance = true;
+ gAgentAvatarp->mUseLocalAppearance = true;
+
+ if (gSavedSettings.getBOOL("AppearanceCameraMovement") && !disable_camera_switch)
{
- // We're no longer doing any baking or invalidating on entering
- // appearance editing mode. Leaving function in place in case
- // further changes require us to do something at this point - Nyx
+ gAgentCamera.changeCameraToCustomizeAvatar();
+ }
+
+#if 0
+ gAgentAvatarp->clearVisualParamWeights();
+ gAgentAvatarp->idleUpdateAppearanceAnimation();
+#endif
+
+ gAgentAvatarp->invalidateAll(); // mark all bakes as dirty, request updates
+ gAgentAvatarp->updateMeshTextures(); // make sure correct textures are applied to the avatar mesh.
+ gAgentAvatarp->updateTextures(); // call updateTextureStats
+ }
}
// static
-void LLVOAvatarSelf::onCustomizeEnd()
+void LLVOAvatarSelf::onCustomizeEnd(bool disable_camera_switch)
{
+
if (isAgentAvatarValid())
{
+ gAgentAvatarp->mIsEditingAppearance = false;
+ if (gAgentAvatarp->getRegion() && !gAgentAvatarp->getRegion()->getCentralBakeVersion())
+ {
+ // FIXME DRANO - move to sendAgentSetAppearance, make conditional on upload complete.
+ gAgentAvatarp->mUseLocalAppearance = false;
+ }
+
gAgentAvatarp->invalidateAll();
+
+ if (gSavedSettings.getBOOL("AppearanceCameraMovement") && !disable_camera_switch)
+ {
+ gAgentCamera.changeCameraToDefault();
+ gAgentCamera.resetView();
+ }
+
+ LLAppearanceMgr::instance().updateAppearanceFromCOF();
}
}
@@ -2504,12 +3008,12 @@ bool LLVOAvatarSelf::sendAppearanceMessage(LLMessageSystem *mesgsys) const
{
LLUUID texture_id[TEX_NUM_INDICES];
// pack away current TEs to make sure we don't send them out
- for (LLVOAvatarDictionary::Textures::const_iterator iter = LLVOAvatarDictionary::getInstance()->getTextures().begin();
- iter != LLVOAvatarDictionary::getInstance()->getTextures().end();
+ for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getTextures().begin();
+ iter != LLAvatarAppearanceDictionary::getInstance()->getTextures().end();
++iter)
{
const ETextureIndex index = iter->first;
- const LLVOAvatarDictionary::TextureEntry *texture_dict = iter->second;
+ const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = iter->second;
if (!texture_dict->mIsBakedTexture)
{
LLTextureEntry* entry = getTE((U8) index);
@@ -2521,12 +3025,12 @@ bool LLVOAvatarSelf::sendAppearanceMessage(LLMessageSystem *mesgsys) const
bool success = packTEMessage(mesgsys);
// unpack TEs to make sure we don't re-trigger a bake
- for (LLVOAvatarDictionary::Textures::const_iterator iter = LLVOAvatarDictionary::getInstance()->getTextures().begin();
- iter != LLVOAvatarDictionary::getInstance()->getTextures().end();
+ for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getTextures().begin();
+ iter != LLAvatarAppearanceDictionary::getInstance()->getTextures().end();
++iter)
{
const ETextureIndex index = iter->first;
- const LLVOAvatarDictionary::TextureEntry *texture_dict = iter->second;
+ const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = iter->second;
if (!texture_dict->mIsBakedTexture)
{
LLTextureEntry* entry = getTE((U8) index);
@@ -2558,49 +3062,6 @@ BOOL LLVOAvatarSelf::needsRenderBeam()
// static
void LLVOAvatarSelf::deleteScratchTextures()
{
- if(gAuditTexture)
- {
- S32 total_tex_size = sScratchTexBytes ;
- S32 tex_size = SCRATCH_TEX_WIDTH * SCRATCH_TEX_HEIGHT ;
-
- if( sScratchTexNames.checkData( GL_LUMINANCE ) )
- {
- LLImageGL::decTextureCounter(tex_size, 1, LLViewerTexture::AVATAR_SCRATCH_TEX) ;
- total_tex_size -= tex_size ;
- }
- if( sScratchTexNames.checkData( GL_ALPHA ) )
- {
- LLImageGL::decTextureCounter(tex_size, 1, LLViewerTexture::AVATAR_SCRATCH_TEX) ;
- total_tex_size -= tex_size ;
- }
- if( sScratchTexNames.checkData( GL_COLOR_INDEX ) )
- {
- LLImageGL::decTextureCounter(tex_size, 1, LLViewerTexture::AVATAR_SCRATCH_TEX) ;
- total_tex_size -= tex_size ;
- }
- if( sScratchTexNames.checkData( LLRender::sGLCoreProfile ? GL_RG : GL_LUMINANCE_ALPHA ) )
- {
- LLImageGL::decTextureCounter(tex_size, 2, LLViewerTexture::AVATAR_SCRATCH_TEX) ;
- total_tex_size -= 2 * tex_size ;
- }
- if( sScratchTexNames.checkData( GL_RGB ) )
- {
- LLImageGL::decTextureCounter(tex_size, 3, LLViewerTexture::AVATAR_SCRATCH_TEX) ;
- total_tex_size -= 3 * tex_size ;
- }
- if( sScratchTexNames.checkData( GL_RGBA ) )
- {
- LLImageGL::decTextureCounter(tex_size, 4, LLViewerTexture::AVATAR_SCRATCH_TEX) ;
- total_tex_size -= 4 * tex_size ;
- }
- //others
- while(total_tex_size > 0)
- {
- LLImageGL::decTextureCounter(tex_size, 4, LLViewerTexture::AVATAR_SCRATCH_TEX) ;
- total_tex_size -= 4 * tex_size ;
- }
- }
-
for( LLGLuint* namep = sScratchTexNames.getFirstData();
namep;
namep = sScratchTexNames.getNextData() )
@@ -2625,3 +3086,36 @@ void LLVOAvatarSelf::dumpScratchTextureByteCount()
{
llinfos << "Scratch Texture GL: " << (sScratchTexBytes/1024) << "KB" << llendl;
}
+
+void LLVOAvatarSelf::dumpWearableInfo(LLAPRFile& outfile)
+{
+ apr_file_t* file = outfile.getFileHandle();
+ if (!file)
+ {
+ return;
+ }
+
+
+ apr_file_printf( file, "\n<wearable_info>\n" );
+
+ LLWearableData *wd = getWearableData();
+ for (S32 type = 0; type < LLWearableType::WT_COUNT; type++)
+ {
+ const std::string& type_name = LLWearableType::getTypeName((LLWearableType::EType)type);
+ for (U32 j=0; j< wd->getWearableCount((LLWearableType::EType)type); j++)
+ {
+ LLViewerWearable *wearable = gAgentWearables.getViewerWearable((LLWearableType::EType)type,j);
+ apr_file_printf( file, "\n\t <wearable type=\"%s\" name=\"%s\"/>\n",
+ type_name.c_str(), wearable->getName().c_str() );
+ LLWearable::visual_param_vec_t v_params;
+ wearable->getVisualParams(v_params);
+ for (LLWearable::visual_param_vec_t::iterator it = v_params.begin();
+ it != v_params.end(); ++it)
+ {
+ LLVisualParam *param = *it;
+ dump_visual_param(file, param, param->getWeight());
+ }
+ }
+ }
+ apr_file_printf( file, "\n</wearable_info>\n" );
+}
diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h
index 655fb3a012..3b7b6bac64 100644..100755
--- a/indra/newview/llvoavatarself.h
+++ b/indra/newview/llvoavatarself.h
@@ -49,6 +49,16 @@ class LLVOAvatarSelf :
**/
public:
+ void* operator new(size_t size)
+ {
+ return ll_aligned_malloc_16(size);
+ }
+
+ void operator delete(void* ptr)
+ {
+ ll_aligned_free_16(ptr);
+ }
+
LLVOAvatarSelf(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp);
virtual ~LLVOAvatarSelf();
virtual void markDead();
@@ -57,9 +67,8 @@ public:
protected:
/*virtual*/ BOOL loadAvatar();
BOOL loadAvatarSelf();
- BOOL buildSkeletonSelf(const LLVOAvatarSkeletonInfo *info);
+ BOOL buildSkeletonSelf(const LLAvatarSkeletonInfo *info);
BOOL buildMenus();
- /*virtual*/ BOOL loadLayersets();
/** Initialization
** **
@@ -75,7 +84,7 @@ protected:
//--------------------------------------------------------------------
public:
/*virtual*/ void updateRegion(LLViewerRegion *regionp);
- /*virtual*/ BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time);
+ /*virtual*/ void idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time);
//--------------------------------------------------------------------
// LLCharacter interface and related
@@ -87,21 +96,33 @@ public:
void resetJointPositions( void );
- /*virtual*/ BOOL setVisualParamWeight(LLVisualParam *which_param, F32 weight, BOOL upload_bake = FALSE );
+ /*virtual*/ BOOL setVisualParamWeight(const LLVisualParam *which_param, F32 weight, BOOL upload_bake = FALSE );
/*virtual*/ BOOL setVisualParamWeight(const char* param_name, F32 weight, BOOL upload_bake = FALSE );
/*virtual*/ BOOL setVisualParamWeight(S32 index, F32 weight, BOOL upload_bake = FALSE );
/*virtual*/ void updateVisualParams();
/*virtual*/ void idleUpdateAppearanceAnimation();
+ /*virtual*/ U32 processUpdateMessage(LLMessageSystem *mesgsys,
+ void **user_data,
+ U32 block_num,
+ const EObjectUpdateType update_type,
+ LLDataPacker *dp);
+
private:
// helper function. Passed in param is assumed to be in avatar's parameter list.
- BOOL setParamWeight(LLViewerVisualParam *param, F32 weight, BOOL upload_bake = FALSE );
+ BOOL setParamWeight(const LLViewerVisualParam *param, F32 weight, BOOL upload_bake = FALSE );
+
/** Initialization
** **
*******************************************************************************/
+private:
+ LLUUID mInitialBakeIDs[6];
+ bool mInitialBakesLoaded;
+
+
/********************************************************************************
** **
** STATE
@@ -109,6 +130,7 @@ private:
public:
/*virtual*/ bool isSelf() const { return true; }
+ /*virtual*/ BOOL isValid() const;
//--------------------------------------------------------------------
// Updates
@@ -121,7 +143,7 @@ public:
// Loading state
//--------------------------------------------------------------------
public:
- /*virtual*/ BOOL getIsCloud();
+ /*virtual*/ BOOL getIsCloud() const;
//--------------------------------------------------------------------
// Region state
@@ -155,8 +177,8 @@ private:
// LLVOAvatar Constants
//--------------------------------------------------------------------
public:
- /*virtual*/ LLViewerTexture::EBoostLevel getAvatarBoostLevel() const { return LLViewerTexture::BOOST_AVATAR_SELF; }
- /*virtual*/ LLViewerTexture::EBoostLevel getAvatarBakedBoostLevel() const { return LLViewerTexture::BOOST_AVATAR_BAKED_SELF; }
+ /*virtual*/ LLViewerTexture::EBoostLevel getAvatarBoostLevel() const { return LLGLTexture::BOOST_AVATAR_SELF; }
+ /*virtual*/ LLViewerTexture::EBoostLevel getAvatarBakedBoostLevel() const { return LLGLTexture::BOOST_AVATAR_BAKED_SELF; }
/*virtual*/ S32 getTexImageSize() const { return LLVOAvatar::getTexImageSize()*4; }
/** Rendering
@@ -173,32 +195,32 @@ public:
//--------------------------------------------------------------------
public:
/*virtual*/ bool hasPendingBakedUploads() const;
- S32 getLocalDiscardLevel(LLVOAvatarDefines::ETextureIndex type, U32 index) const;
+ S32 getLocalDiscardLevel(LLAvatarAppearanceDefines::ETextureIndex type, U32 index) const;
bool areTexturesCurrent() const;
- BOOL isLocalTextureDataAvailable(const LLTexLayerSet* layerset) const;
- BOOL isLocalTextureDataFinal(const LLTexLayerSet* layerset) const;
- BOOL isBakedTextureFinal(const LLVOAvatarDefines::EBakedTextureIndex index) const;
+ BOOL isLocalTextureDataAvailable(const LLViewerTexLayerSet* layerset) const;
+ BOOL isLocalTextureDataFinal(const LLViewerTexLayerSet* layerset) const;
+ BOOL isBakedTextureFinal(const LLAvatarAppearanceDefines::EBakedTextureIndex index) const;
// If you want to check all textures of a given type, pass gAgentWearables.getWearableCount() for index
- /*virtual*/ BOOL isTextureDefined(LLVOAvatarDefines::ETextureIndex type, U32 index) const;
- /*virtual*/ BOOL isTextureVisible(LLVOAvatarDefines::ETextureIndex type, U32 index = 0) const;
- /*virtual*/ BOOL isTextureVisible(LLVOAvatarDefines::ETextureIndex type, LLWearable *wearable) const;
+ /*virtual*/ BOOL isTextureDefined(LLAvatarAppearanceDefines::ETextureIndex type, U32 index) const;
+ /*virtual*/ BOOL isTextureVisible(LLAvatarAppearanceDefines::ETextureIndex type, U32 index = 0) const;
+ /*virtual*/ BOOL isTextureVisible(LLAvatarAppearanceDefines::ETextureIndex type, LLViewerWearable *wearable) const;
//--------------------------------------------------------------------
// Local Textures
//--------------------------------------------------------------------
public:
- BOOL getLocalTextureGL(LLVOAvatarDefines::ETextureIndex type, LLViewerTexture** image_gl_pp, U32 index) const;
- LLViewerFetchedTexture* getLocalTextureGL(LLVOAvatarDefines::ETextureIndex type, U32 index) const;
- const LLUUID& getLocalTextureID(LLVOAvatarDefines::ETextureIndex type, U32 index) const;
+ BOOL getLocalTextureGL(LLAvatarAppearanceDefines::ETextureIndex type, LLViewerTexture** image_gl_pp, U32 index) const;
+ LLViewerFetchedTexture* getLocalTextureGL(LLAvatarAppearanceDefines::ETextureIndex type, U32 index) const;
+ const LLUUID& getLocalTextureID(LLAvatarAppearanceDefines::ETextureIndex type, U32 index) const;
void setLocalTextureTE(U8 te, LLViewerTexture* image, U32 index);
- /*virtual*/ void setLocalTexture(LLVOAvatarDefines::ETextureIndex type, LLViewerTexture* tex, BOOL baked_version_exits, U32 index);
+ /*virtual*/ void setLocalTexture(LLAvatarAppearanceDefines::ETextureIndex type, LLViewerTexture* tex, BOOL baked_version_exits, U32 index);
protected:
- /*virtual*/ void setBakedReady(LLVOAvatarDefines::ETextureIndex type, BOOL baked_version_exists, U32 index);
+ /*virtual*/ void setBakedReady(LLAvatarAppearanceDefines::ETextureIndex type, BOOL baked_version_exists, U32 index);
void localTextureLoaded(BOOL succcess, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata);
void getLocalTextureByteCount(S32* gl_byte_count) const;
- /*virtual*/ void addLocalTextureStats(LLVOAvatarDefines::ETextureIndex i, LLViewerFetchedTexture* imagep, F32 texel_area_ratio, BOOL rendered, BOOL covered_by_baked, U32 index);
- LLLocalTextureObject* getLocalTextureObject(LLVOAvatarDefines::ETextureIndex i, U32 index) const;
+ /*virtual*/ void addLocalTextureStats(LLAvatarAppearanceDefines::ETextureIndex i, LLViewerFetchedTexture* imagep, F32 texel_area_ratio, BOOL rendered, BOOL covered_by_baked);
+ LLLocalTextureObject* getLocalTextureObject(LLAvatarAppearanceDefines::ETextureIndex i, U32 index) const;
private:
static void onLocalTextureLoaded(BOOL succcess, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata);
@@ -211,13 +233,12 @@ private:
// Baked textures
//--------------------------------------------------------------------
public:
- LLVOAvatarDefines::ETextureIndex getBakedTE(const LLTexLayerSet* layerset ) const;
- void setNewBakedTexture(LLVOAvatarDefines::EBakedTextureIndex i, const LLUUID &uuid);
- void setNewBakedTexture(LLVOAvatarDefines::ETextureIndex i, const LLUUID& uuid);
- void setCachedBakedTexture(LLVOAvatarDefines::ETextureIndex i, const LLUUID& uuid);
+ LLAvatarAppearanceDefines::ETextureIndex getBakedTE(const LLViewerTexLayerSet* layerset ) const;
+ void setNewBakedTexture(LLAvatarAppearanceDefines::EBakedTextureIndex i, const LLUUID &uuid);
+ void setNewBakedTexture(LLAvatarAppearanceDefines::ETextureIndex i, const LLUUID& uuid);
+ void setCachedBakedTexture(LLAvatarAppearanceDefines::ETextureIndex i, const LLUUID& uuid);
void forceBakeAllTextures(bool slam_for_debug = false);
static void processRebakeAvatarTextures(LLMessageSystem* msg, void**);
- BOOL isUsingBakedTextures() const; // e.g. false if in appearance edit mode
protected:
/*virtual*/ void removeMissingBakedTextures();
@@ -226,9 +247,11 @@ protected:
//--------------------------------------------------------------------
public:
void requestLayerSetUploads();
- void requestLayerSetUpload(LLVOAvatarDefines::EBakedTextureIndex i);
- void requestLayerSetUpdate(LLVOAvatarDefines::ETextureIndex i);
- LLTexLayerSet* getLayerSet(LLVOAvatarDefines::ETextureIndex index) const;
+ void requestLayerSetUpload(LLAvatarAppearanceDefines::EBakedTextureIndex i);
+ void requestLayerSetUpdate(LLAvatarAppearanceDefines::ETextureIndex i);
+ LLViewerTexLayerSet* getLayerSet(LLAvatarAppearanceDefines::EBakedTextureIndex baked_index) const;
+ LLViewerTexLayerSet* getLayerSet(LLAvatarAppearanceDefines::ETextureIndex index) const;
+
//--------------------------------------------------------------------
// Composites
@@ -242,8 +265,8 @@ public:
void setupComposites();
void updateComposites();
- const LLUUID& grabBakedTexture(LLVOAvatarDefines::EBakedTextureIndex baked_index) const;
- BOOL canGrabBakedTexture(LLVOAvatarDefines::EBakedTextureIndex baked_index) const;
+ const LLUUID& grabBakedTexture(LLAvatarAppearanceDefines::EBakedTextureIndex baked_index) const;
+ BOOL canGrabBakedTexture(LLAvatarAppearanceDefines::EBakedTextureIndex baked_index) const;
//--------------------------------------------------------------------
@@ -277,10 +300,9 @@ protected:
**/
public:
- /*virtual*/ BOOL isWearingWearableType(LLWearableType::EType type) const;
void wearableUpdated(LLWearableType::EType type, BOOL upload_result);
protected:
- U32 getNumWearables(LLVOAvatarDefines::ETextureIndex i) const;
+ U32 getNumWearables(LLAvatarAppearanceDefines::ETextureIndex i) const;
//--------------------------------------------------------------------
// Attachments
@@ -317,8 +339,8 @@ private:
**/
public:
- static void onCustomizeStart();
- static void onCustomizeEnd();
+ static void onCustomizeStart(bool disable_camera_switch = false);
+ static void onCustomizeEnd(bool disable_camera_switch = false);
//--------------------------------------------------------------------
// Visibility
@@ -342,6 +364,7 @@ public:
static void dumpTotalLocalTextureByteCount();
void dumpLocalTextures() const;
static void dumpScratchTextureByteCount();
+ void dumpWearableInfo(LLAPRFile& outfile);
//--------------------------------------------------------------------
// Avatar Rez Metrics
@@ -349,32 +372,43 @@ public:
public:
struct LLAvatarTexData
{
- LLAvatarTexData(const LLUUID& id, LLVOAvatarDefines::ETextureIndex index) :
+ LLAvatarTexData(const LLUUID& id, LLAvatarAppearanceDefines::ETextureIndex index) :
mAvatarID(id),
mIndex(index)
{}
LLUUID mAvatarID;
- LLVOAvatarDefines::ETextureIndex mIndex;
+ LLAvatarAppearanceDefines::ETextureIndex mIndex;
};
+
+ LLTimer mTimeSinceLastRezMessage;
+ bool updateAvatarRezMetrics(bool force_send);
+
+ std::vector<LLSD> mPendingTimerRecords;
+ void addMetricsTimerRecord(const LLSD& record);
+
void debugWearablesLoaded() { mDebugTimeWearablesLoaded = mDebugSelfLoadTimer.getElapsedTimeF32(); }
void debugAvatarVisible() { mDebugTimeAvatarVisible = mDebugSelfLoadTimer.getElapsedTimeF32(); }
void outputRezDiagnostics() const;
void outputRezTiming(const std::string& msg) const;
void reportAvatarRezTime() const;
- void debugBakedTextureUpload(LLVOAvatarDefines::EBakedTextureIndex index, BOOL finished);
+ void debugBakedTextureUpload(LLAvatarAppearanceDefines::EBakedTextureIndex index, BOOL finished);
static void debugOnTimingLocalTexLoaded(BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata);
BOOL isAllLocalTextureDataFinal() const;
- const LLTexLayerSet* debugGetLayerSet(LLVOAvatarDefines::EBakedTextureIndex index) const { return mBakedTextureDatas[index].mTexLayerSet; }
- const std::string debugDumpLocalTextureDataInfo(const LLTexLayerSet* layerset) const; // Lists out state of this particular baked texture layer
+ const LLViewerTexLayerSet* debugGetLayerSet(LLAvatarAppearanceDefines::EBakedTextureIndex index) const { return (LLViewerTexLayerSet*)(mBakedTextureDatas[index].mTexLayerSet); }
+ const std::string verboseDebugDumpLocalTextureDataInfo(const LLViewerTexLayerSet* layerset) const; // Lists out state of this particular baked texture layer
+ void dumpAllTextures() const;
+ const std::string debugDumpLocalTextureDataInfo(const LLViewerTexLayerSet* layerset) const; // Lists out state of this particular baked texture layer
const std::string debugDumpAllLocalTextureDataInfo() const; // Lists out which baked textures are at highest LOD
+ void sendViewerAppearanceChangeMetrics(); // send data associated with completing a change.
+ void checkForUnsupportedServerBakeAppearance();
private:
LLFrameTimer mDebugSelfLoadTimer;
F32 mDebugTimeWearablesLoaded;
F32 mDebugTimeAvatarVisible;
- F32 mDebugTextureLoadTimes[LLVOAvatarDefines::TEX_NUM_INDICES][MAX_DISCARD_LEVEL+1]; // load time for each texture at each discard level
- F32 mDebugBakedTextureTimes[LLVOAvatarDefines::BAKED_NUM_INDICES][2]; // time to start upload and finish upload of each baked texture
+ F32 mDebugTextureLoadTimes[LLAvatarAppearanceDefines::TEX_NUM_INDICES][MAX_DISCARD_LEVEL+1]; // load time for each texture at each discard level
+ F32 mDebugBakedTextureTimes[LLAvatarAppearanceDefines::BAKED_NUM_INDICES][2]; // time to start upload and finish upload of each baked texture
void debugTimingLocalTexLoaded(BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata);
/** Diagnostics
@@ -387,4 +421,8 @@ extern LLPointer<LLVOAvatarSelf> gAgentAvatarp;
BOOL isAgentAvatarValid();
+void selfStartPhase(const std::string& phase_name);
+void selfStopPhase(const std::string& phase_name, bool err_check = true);
+void selfClearPhases();
+
#endif // LL_VO_AVATARSELF_H
diff --git a/indra/newview/llvocache.cpp b/indra/newview/llvocache.cpp
index 7db19c5c1b..7db19c5c1b 100644..100755
--- a/indra/newview/llvocache.cpp
+++ b/indra/newview/llvocache.cpp
diff --git a/indra/newview/llvocache.h b/indra/newview/llvocache.h
index 14e3b4c793..14e3b4c793 100644..100755
--- a/indra/newview/llvocache.h
+++ b/indra/newview/llvocache.h
diff --git a/indra/newview/llvograss.cpp b/indra/newview/llvograss.cpp
index 8a79d564d3..591d5cae0b 100644..100755
--- a/indra/newview/llvograss.cpp
+++ b/indra/newview/llvograss.cpp
@@ -34,6 +34,7 @@
#include "llagentcamera.h"
#include "llnotificationsutil.h"
#include "lldrawable.h"
+#include "lldrawpoolalpha.h"
#include "llface.h"
#include "llsky.h"
#include "llsurface.h"
@@ -101,7 +102,7 @@ void LLVOGrass::updateSpecies()
SpeciesMap::const_iterator it = sSpeciesTable.begin();
mSpecies = (*it).first;
}
- setTEImage(0, LLViewerTextureManager::getFetchedTexture(sSpeciesTable[mSpecies]->mTextureID, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE));
+ setTEImage(0, LLViewerTextureManager::getFetchedTexture(sSpeciesTable[mSpecies]->mTextureID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE));
}
@@ -276,17 +277,17 @@ BOOL LLVOGrass::isActive() const
return TRUE;
}
-BOOL LLVOGrass::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
+void LLVOGrass::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
{
if (mDead || !(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_GRASS)))
{
- return TRUE;
+ return;
}
if (!mDrawable)
{
// So drones work.
- return TRUE;
+ return;
}
if(LLVOTree::isTreeRenderingStopped()) //stop rendering grass
@@ -296,14 +297,14 @@ BOOL LLVOGrass::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
mNumBlades = 0 ;
gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE);
}
- return TRUE ;
+ return;
}
else if(!mNumBlades)//restart grass rendering
{
mNumBlades = GRASS_MAX_BLADES ;
gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE);
- return TRUE ;
+ return;
}
if (mPatch && (mLastPatchUpdateTime != mPatch->getLastUpdateTime()))
@@ -311,7 +312,7 @@ BOOL LLVOGrass::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE);
}
- return TRUE;
+ return;
}
@@ -380,8 +381,10 @@ BOOL LLVOGrass::updateLOD()
{
mNumBlades <<= 1;
}
-
- face->setSize(mNumBlades*8, mNumBlades*12);
+ if (face)
+ {
+ face->setSize(mNumBlades*8, mNumBlades*12);
+ }
gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE);
}
else if (num_blades <= (mNumBlades >> 1))
@@ -391,7 +394,10 @@ BOOL LLVOGrass::updateLOD()
mNumBlades >>=1;
}
- face->setSize(mNumBlades*8, mNumBlades*12);
+ if (face)
+ {
+ face->setSize(mNumBlades*8, mNumBlades*12);
+ }
gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE);
return TRUE;
}
@@ -449,14 +455,16 @@ void LLVOGrass::plantBlades()
}
LLFace *face = mDrawable->getFace(0);
+ if (face)
+ {
+ face->setTexture(getTEImage(0));
+ face->setState(LLFace::GLOBAL);
+ face->setSize(mNumBlades * 8, mNumBlades * 12);
+ face->setVertexBuffer(NULL);
+ face->setTEOffset(0);
+ face->mCenterLocal = mPosition + mRegionp->getOriginAgent();
+ }
- face->setTexture(getTEImage(0));
- face->setState(LLFace::GLOBAL);
- face->setSize(mNumBlades * 8, mNumBlades * 12);
- face->setVertexBuffer(NULL);
- face->setTEOffset(0);
- face->mCenterLocal = mPosition + mRegionp->getOriginAgent();
-
mDepth = (face->mCenterLocal - LLViewerCamera::getInstance()->getOrigin())*LLViewerCamera::getInstance()->getAtAxis();
mDrawable->setPosition(face->mCenterLocal);
mDrawable->movePartition();
@@ -468,6 +476,7 @@ void LLVOGrass::getGeometry(S32 idx,
LLStrider<LLVector3>& normalsp,
LLStrider<LLVector2>& texcoordsp,
LLStrider<LLColor4U>& colorsp,
+ LLStrider<LLColor4U>& emissivep,
LLStrider<U16>& indicesp)
{
if(!mNumBlades)//stop rendering grass
@@ -486,6 +495,8 @@ void LLVOGrass::getGeometry(S32 idx,
LLColor4U color(255,255,255,255);
LLFace *face = mDrawable->getFace(idx);
+ if (!face)
+ return;
F32 width = sSpeciesTable[mSpecies]->mBladeSizeX;
F32 height = sSpeciesTable[mSpecies]->mBladeSizeY;
@@ -594,6 +605,7 @@ U32 LLVOGrass::getPartitionType() const
}
LLGrassPartition::LLGrassPartition()
+: LLSpatialPartition(LLDrawPoolAlpha::VERTEX_DATA_MASK | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, GL_STREAM_DRAW_ARB)
{
mDrawableType = LLPipeline::RENDER_TYPE_GRASS;
mPartitionType = LLViewerRegion::PARTITION_GRASS;
@@ -604,6 +616,146 @@ LLGrassPartition::LLGrassPartition()
mBufferUsage = GL_DYNAMIC_DRAW_ARB;
}
+void LLGrassPartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_count, U32& index_count)
+{
+ group->mBufferUsage = mBufferUsage;
+
+ mFaceList.clear();
+
+ LLViewerCamera* camera = LLViewerCamera::getInstance();
+ for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)
+ {
+ LLDrawable* drawablep = *i;
+
+ if (drawablep->isDead())
+ {
+ continue;
+ }
+
+ LLAlphaObject* obj = (LLAlphaObject*) drawablep->getVObj().get();
+ obj->mDepth = 0.f;
+
+ if (drawablep->isAnimating())
+ {
+ group->mBufferUsage = GL_STREAM_DRAW_ARB;
+ }
+
+ U32 count = 0;
+ for (S32 j = 0; j < drawablep->getNumFaces(); ++j)
+ {
+ drawablep->updateFaceSize(j);
+
+ LLFace* facep = drawablep->getFace(j);
+ if ( !facep || !facep->hasGeometry())
+ {
+ continue;
+ }
+
+ if ((facep->getGeomCount() + vertex_count) <= 65536)
+ {
+ count++;
+ facep->mDistance = (facep->mCenterLocal - camera->getOrigin()) * camera->getAtAxis();
+ obj->mDepth += facep->mDistance;
+
+ mFaceList.push_back(facep);
+ vertex_count += facep->getGeomCount();
+ index_count += facep->getIndicesCount();
+ llassert(facep->getIndicesCount() < 65536);
+ }
+ else
+ {
+ facep->clearVertexBuffer();
+ }
+ }
+
+ obj->mDepth /= count;
+ }
+}
+
+static LLFastTimer::DeclareTimer FTM_REBUILD_GRASS_VB("Grass VB");
+
+void LLGrassPartition::getGeometry(LLSpatialGroup* group)
+{
+ LLFastTimer ftm(FTM_REBUILD_GRASS_VB);
+
+ std::sort(mFaceList.begin(), mFaceList.end(), LLFace::CompareDistanceGreater());
+
+ U32 index_count = 0;
+ U32 vertex_count = 0;
+
+ group->clearDrawMap();
+
+ LLVertexBuffer* buffer = group->mVertexBuffer;
+
+ LLStrider<U16> indicesp;
+ LLStrider<LLVector4a> verticesp;
+ LLStrider<LLVector3> normalsp;
+ LLStrider<LLVector2> texcoordsp;
+ LLStrider<LLColor4U> colorsp;
+
+ buffer->getVertexStrider(verticesp);
+ buffer->getNormalStrider(normalsp);
+ buffer->getColorStrider(colorsp);
+ buffer->getTexCoord0Strider(texcoordsp);
+ buffer->getIndexStrider(indicesp);
+
+ LLSpatialGroup::drawmap_elem_t& draw_vec = group->mDrawMap[mRenderPass];
+
+ for (std::vector<LLFace*>::iterator i = mFaceList.begin(); i != mFaceList.end(); ++i)
+ {
+ LLFace* facep = *i;
+ LLAlphaObject* object = (LLAlphaObject*) facep->getViewerObject();
+ facep->setGeomIndex(vertex_count);
+ facep->setIndicesIndex(index_count);
+ facep->setVertexBuffer(buffer);
+ facep->setPoolType(LLDrawPool::POOL_ALPHA);
+
+ //dummy parameter (unused by this implementation)
+ LLStrider<LLColor4U> emissivep;
+
+ object->getGeometry(facep->getTEOffset(), verticesp, normalsp, texcoordsp, colorsp, emissivep, indicesp);
+
+ vertex_count += facep->getGeomCount();
+ index_count += facep->getIndicesCount();
+
+ S32 idx = draw_vec.size()-1;
+
+ BOOL fullbright = facep->isState(LLFace::FULLBRIGHT);
+ F32 vsize = facep->getVirtualSize();
+
+ if (idx >= 0 && draw_vec[idx]->mEnd == facep->getGeomIndex()-1 &&
+ draw_vec[idx]->mTexture == facep->getTexture() &&
+ (U16) (draw_vec[idx]->mEnd - draw_vec[idx]->mStart + facep->getGeomCount()) <= (U32) gGLManager.mGLMaxVertexRange &&
+ //draw_vec[idx]->mCount + facep->getIndicesCount() <= (U32) gGLManager.mGLMaxIndexRange &&
+ draw_vec[idx]->mEnd - draw_vec[idx]->mStart + facep->getGeomCount() < 4096 &&
+ draw_vec[idx]->mFullbright == fullbright)
+ {
+ draw_vec[idx]->mCount += facep->getIndicesCount();
+ draw_vec[idx]->mEnd += facep->getGeomCount();
+ draw_vec[idx]->mVSize = llmax(draw_vec[idx]->mVSize, vsize);
+ }
+ else
+ {
+ U32 start = facep->getGeomIndex();
+ U32 end = start + facep->getGeomCount()-1;
+ U32 offset = facep->getIndicesStart();
+ U32 count = facep->getIndicesCount();
+ LLDrawInfo* info = new LLDrawInfo(start,end,count,offset,facep->getTexture(),
+ //facep->getTexture(),
+ buffer, fullbright);
+ info->mExtents[0] = group->mObjectExtents[0];
+ info->mExtents[1] = group->mObjectExtents[1];
+ info->mVSize = vsize;
+ draw_vec.push_back(info);
+ //for alpha sorting
+ facep->setDrawInfo(info);
+ }
+ }
+
+ buffer->flush();
+ mFaceList.clear();
+}
+
// virtual
void LLVOGrass::updateDrawable(BOOL force_damped)
{
@@ -617,8 +769,8 @@ void LLVOGrass::updateDrawable(BOOL force_damped)
}
// virtual
-BOOL LLVOGrass::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, S32 face, BOOL pick_transparent, S32 *face_hitp,
- LLVector3* intersection,LLVector2* tex_coord, LLVector3* normal, LLVector3* bi_normal)
+BOOL LLVOGrass::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face, BOOL pick_transparent, S32 *face_hitp,
+ LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent)
{
BOOL ret = FALSE;
@@ -629,7 +781,8 @@ BOOL LLVOGrass::lineSegmentIntersect(const LLVector3& start, const LLVector3& en
return FALSE;
}
- LLVector3 dir = end-start;
+ LLVector4a dir;
+ dir.setSub(end, start);
mPatch = mRegionp->getLand().resolvePatchRegion(getPositionRegion());
@@ -697,23 +850,31 @@ BOOL LLVOGrass::lineSegmentIntersect(const LLVector3& start, const LLVector3& en
U32 idx0 = 0,idx1 = 0,idx2 = 0;
- if (LLTriangleRayIntersect(v[0], v[1], v[2], start, dir, a, b, t, FALSE))
+ LLVector4a v0a,v1a,v2a,v3a;
+
+ v0a.load3(v[0].mV);
+ v1a.load3(v[1].mV);
+ v2a.load3(v[2].mV);
+ v3a.load3(v[3].mV);
+
+
+ if (LLTriangleRayIntersect(v0a, v1a, v2a, start, dir, a, b, t))
{
hit = TRUE;
idx0 = 0; idx1 = 1; idx2 = 2;
}
- else if (LLTriangleRayIntersect(v[1], v[3], v[2], start, dir, a, b, t, FALSE))
+ else if (LLTriangleRayIntersect(v1a, v3a, v2a, start, dir, a, b, t))
{
hit = TRUE;
idx0 = 1; idx1 = 3; idx2 = 2;
}
- else if (LLTriangleRayIntersect(v[2], v[1], v[0], start, dir, a, b, t, FALSE))
+ else if (LLTriangleRayIntersect(v2a, v1a, v0a, start, dir, a, b, t))
{
normal1 = -normal1;
hit = TRUE;
idx0 = 2; idx1 = 1; idx2 = 0;
}
- else if (LLTriangleRayIntersect(v[2], v[3], v[1], start, dir, a, b, t, FALSE))
+ else if (LLTriangleRayIntersect(v2a, v3a, v1a, start, dir, a, b, t))
{
normal1 = -normal1;
hit = TRUE;
@@ -736,7 +897,8 @@ BOOL LLVOGrass::lineSegmentIntersect(const LLVector3& start, const LLVector3& en
closest_t = t;
if (intersection != NULL)
{
- *intersection = start+dir*closest_t;
+ dir.mul(closest_t);
+ intersection->setAdd(start, dir);
}
if (tex_coord != NULL)
@@ -746,7 +908,7 @@ BOOL LLVOGrass::lineSegmentIntersect(const LLVector3& start, const LLVector3& en
if (normal != NULL)
{
- *normal = normal1;
+ normal->load3(normal1.mV);
}
ret = TRUE;
}
diff --git a/indra/newview/llvograss.h b/indra/newview/llvograss.h
index 00a59facf7..e54de85412 100644..100755
--- a/indra/newview/llvograss.h
+++ b/indra/newview/llvograss.h
@@ -63,6 +63,7 @@ public:
LLStrider<LLVector3>& normalsp,
LLStrider<LLVector2>& texcoordsp,
LLStrider<LLColor4U>& colorsp,
+ LLStrider<LLColor4U>& emissivep,
LLStrider<U16>& indicesp);
void updateFaceSize(S32 idx) { }
@@ -73,16 +74,16 @@ public:
void plantBlades();
/*virtual*/ BOOL isActive() const; // Whether this object needs to do an idleUpdate.
- BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time);
+ /*virtual*/ void idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time);
- /*virtual*/ BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end,
+ /*virtual*/ BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
S32 face = -1, // which face to check, -1 = ALL_SIDES
BOOL pick_transparent = FALSE,
S32* face_hit = NULL, // which face was hit
- LLVector3* intersection = NULL, // return the intersection point
+ LLVector4a* intersection = NULL, // return the intersection point
LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
- LLVector3* normal = NULL, // return the surface normal at the intersection point
- LLVector3* bi_normal = NULL // return the surface bi-normal at the intersection point
+ LLVector4a* normal = NULL, // return the surface normal at the intersection point
+ LLVector4a* tangent = NULL // return the surface tangent at the intersection point
);
static S32 sMaxGrassSpecies;
diff --git a/indra/newview/llvoground.cpp b/indra/newview/llvoground.cpp
index 0060f81ab5..97b7418b40 100644..100755
--- a/indra/newview/llvoground.cpp
+++ b/indra/newview/llvoground.cpp
@@ -49,18 +49,8 @@ LLVOGround::~LLVOGround()
{
}
-BOOL LLVOGround::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
+void LLVOGround::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
{
- if (mDead || !(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_GROUND)))
- {
- return TRUE;
- }
-
- /*if (mDrawable)
- {
- gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE);
- }*/
- return TRUE;
}
@@ -82,6 +72,7 @@ LLDrawable *LLVOGround::createDrawable(LLPipeline *pipeline)
return mDrawable;
}
+// TO DO - this always returns TRUE,
BOOL LLVOGround::updateGeometry(LLDrawable *drawable)
{
LLStrider<LLVector3> verticesp;
@@ -96,6 +87,8 @@ BOOL LLVOGround::updateGeometry(LLDrawable *drawable)
if (drawable->getNumFaces() < 1)
drawable->addFace(poolp, NULL);
face = drawable->getFace(0);
+ if (!face)
+ return TRUE;
if (!face->getVertexBuffer())
{
diff --git a/indra/newview/llvoground.h b/indra/newview/llvoground.h
index 73b097327e..290579b4da 100644..100755
--- a/indra/newview/llvoground.h
+++ b/indra/newview/llvoground.h
@@ -41,7 +41,7 @@ protected:
public:
LLVOGround(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp);
- /*virtual*/ BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time);
+ /*virtual*/ void idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time);
// Graphical stuff for objects - maybe broken out into render class
// later?
diff --git a/indra/newview/llvoicecallhandler.cpp b/indra/newview/llvoicecallhandler.cpp
index 2050dab689..2050dab689 100644..100755
--- a/indra/newview/llvoicecallhandler.cpp
+++ b/indra/newview/llvoicecallhandler.cpp
diff --git a/indra/newview/llvoicechannel.cpp b/indra/newview/llvoicechannel.cpp
index bd12328a6b..ac2a34ba1e 100644..100755
--- a/indra/newview/llvoicechannel.cpp
+++ b/indra/newview/llvoicechannel.cpp
@@ -56,7 +56,8 @@ class LLVoiceCallCapResponder : public LLHTTPClient::Responder
public:
LLVoiceCallCapResponder(const LLUUID& session_id) : mSessionID(session_id) {};
- virtual void error(U32 status, const std::string& reason); // called with bad status codes
+ // called with bad status codes
+ virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content);
virtual void result(const LLSD& content);
private:
@@ -64,11 +65,10 @@ private:
};
-void LLVoiceCallCapResponder::error(U32 status, const std::string& reason)
+void LLVoiceCallCapResponder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)
{
- LL_WARNS("Voice") << "LLVoiceCallCapResponder::error("
- << status << ": " << reason << ")"
- << LL_ENDL;
+ LL_WARNS("Voice") << "LLVoiceCallCapResponder error [status:"
+ << status << "]: " << content << LL_ENDL;
LLVoiceChannel* channelp = LLVoiceChannel::getChannelByID(mSessionID);
if ( channelp )
{
@@ -414,7 +414,7 @@ void LLVoiceChannel::doSetState(const EState& new_state)
mState = new_state;
if (!mStateChangedCallback.empty())
- mStateChangedCallback(old_state, mState, mCallDirection, mCallEndedByAgent);
+ mStateChangedCallback(old_state, mState, mCallDirection, mCallEndedByAgent, mSessionID);
}
//static
diff --git a/indra/newview/llvoicechannel.h b/indra/newview/llvoicechannel.h
index b8597ee5cb..fed44974fd 100644..100755
--- a/indra/newview/llvoicechannel.h
+++ b/indra/newview/llvoicechannel.h
@@ -52,7 +52,7 @@ public:
OUTGOING_CALL
} EDirection;
- typedef boost::signals2::signal<void(const EState& old_state, const EState& new_state, const EDirection& direction, bool ended_by_agent)> state_changed_signal_t;
+ typedef boost::signals2::signal<void(const EState& old_state, const EState& new_state, const EDirection& direction, bool ended_by_agent, const LLUUID& session_id)> state_changed_signal_t;
// on current channel changed signal
typedef boost::function<void(const LLUUID& session_id)> channel_changed_callback_t;
diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp
index 730f022c50..815965fb0a 100644..100755
--- a/indra/newview/llvoiceclient.cpp
+++ b/indra/newview/llvoiceclient.cpp
@@ -113,8 +113,8 @@ LLVoiceClient::LLVoiceClient()
:
mVoiceModule(NULL),
m_servicePump(NULL),
- mVoiceEffectEnabled(LLCachedControl<bool>(gSavedSettings, "VoiceMorphingEnabled")),
- mVoiceEffectDefault(LLCachedControl<std::string>(gSavedPerAccountSettings, "VoiceEffectDefault")),
+ mVoiceEffectEnabled(LLCachedControl<bool>(gSavedSettings, "VoiceMorphingEnabled", true)),
+ mVoiceEffectDefault(LLCachedControl<std::string>(gSavedPerAccountSettings, "VoiceEffectDefault", "00000000-0000-0000-0000-000000000000")),
mPTTDirty(true),
mPTT(true),
mUsePTT(true),
@@ -541,6 +541,7 @@ void LLVoiceClient::setMuteMic(bool muted)
{
mMuteMic = muted;
updateMicMuteLogic();
+ mMicroChangedSignal();
}
@@ -551,6 +552,7 @@ void LLVoiceClient::setUserPTTState(bool ptt)
{
mUserPTTState = ptt;
updateMicMuteLogic();
+ mMicroChangedSignal();
}
bool LLVoiceClient::getUserPTTState()
@@ -712,14 +714,7 @@ BOOL LLVoiceClient::isParticipantAvatar(const LLUUID& id)
BOOL LLVoiceClient::isOnlineSIP(const LLUUID& id)
{
- if (mVoiceModule)
- {
- return mVoiceModule->isOnlineSIP(id);
- }
- else
- {
return FALSE;
- }
}
BOOL LLVoiceClient::getIsSpeaking(const LLUUID& id)
diff --git a/indra/newview/llvoiceclient.h b/indra/newview/llvoiceclient.h
index c9aeea35a9..e17da9cecd 100644..100755
--- a/indra/newview/llvoiceclient.h
+++ b/indra/newview/llvoiceclient.h
@@ -199,7 +199,6 @@ public:
//@{
virtual BOOL getVoiceEnabled(const LLUUID& id)=0; // true if we've received data for this avatar
virtual std::string getDisplayName(const LLUUID& id)=0;
- virtual BOOL isOnlineSIP(const LLUUID &id)=0;
virtual BOOL isParticipantAvatar(const LLUUID &id)=0;
virtual BOOL getIsSpeaking(const LLUUID& id)=0;
virtual BOOL getIsModeratorMuted(const LLUUID& id)=0;
@@ -303,6 +302,9 @@ public:
LLVoiceClient();
~LLVoiceClient();
+ typedef boost::signals2::signal<void(void)> micro_changed_signal_t;
+ micro_changed_signal_t mMicroChangedSignal;
+
void init(LLPumpIO *pump); // Call this once at application startup (creates connector)
void terminate(); // Call this to clean up during shutdown
@@ -401,6 +403,8 @@ public:
void keyUp(KEY key, MASK mask);
void middleMouseState(bool down);
+ boost::signals2::connection MicroChangedCallback(const micro_changed_signal_t::slot_type& cb ) { return mMicroChangedSignal.connect(cb); }
+
/////////////////////////////
// Accessors for data related to nearby speakers
@@ -456,6 +460,7 @@ protected:
LLVoiceModuleInterface* mVoiceModule;
LLPumpIO *m_servicePump;
+
LLCachedControl<bool> mVoiceEffectEnabled;
LLCachedControl<std::string> mVoiceEffectDefault;
diff --git a/indra/newview/llvoicevisualizer.cpp b/indra/newview/llvoicevisualizer.cpp
index 47060720e7..9281334d81 100644..100755
--- a/indra/newview/llvoicevisualizer.cpp
+++ b/indra/newview/llvoicevisualizer.cpp
@@ -73,17 +73,6 @@ const F32 DEFAULT_MAXIMUM_GESTICULATION_AMPLITUDE = 1.0f;
const F32 ONE_HALF = 1.0f; // to clarify intent and reduce magic numbers in the code.
const LLVector3 WORLD_UPWARD_DIRECTION = LLVector3( 0.0f, 0.0f, 1.0f ); // Z is up in SL
-
-//------------------------------------------------------------------
-// handles parameter updates
-//------------------------------------------------------------------
-static bool handleVoiceVisualizerPrefsChanged(const LLSD& newvalue)
-{
- // Note: Ignore the specific event value, we look up the ones we want
- LLVoiceVisualizer::setPreferences();
- return true;
-}
-
//------------------------------------------------------------------
// Initialize the statics
//------------------------------------------------------------------
@@ -106,7 +95,7 @@ F32 LLVoiceVisualizer::sAahPowerTransfersf = 0.0f;
// constructor
//-----------------------------------------------
LLVoiceVisualizer::LLVoiceVisualizer( const U8 type )
-:LLHUDEffect( type )
+ : LLHUDEffect(type)
{
mCurrentTime = mTimer.getTotalSeconds();
mPreviousTime = mCurrentTime;
@@ -136,7 +125,7 @@ LLVoiceVisualizer::LLVoiceVisualizer( const U8 type )
for (int i=0; i<NUM_VOICE_SYMBOL_WAVES; i++)
{
mSoundSymbol.mWaveFadeOutStartTime [i] = mCurrentTime;
- mSoundSymbol.mTexture [i] = LLViewerTextureManager::getFetchedTextureFromFile(sound_level_img[i], FALSE, LLViewerTexture::BOOST_UI);
+ mSoundSymbol.mTexture [i] = LLViewerTextureManager::getFetchedTextureFromFile(sound_level_img[i], FTT_LOCAL_FILE, FALSE, LLGLTexture::BOOST_UI);
mSoundSymbol.mWaveActive [i] = false;
mSoundSymbol.mWaveOpacity [i] = 1.0f;
mSoundSymbol.mWaveExpansion [i] = 1.0f;
@@ -150,12 +139,12 @@ LLVoiceVisualizer::LLVoiceVisualizer( const U8 type )
setPreferences();
// Set up our listener to get updates on all prefs values we care about.
- gSavedSettings.getControl("LipSyncEnabled")->getSignal()->connect(boost::bind(&handleVoiceVisualizerPrefsChanged, _2));
- gSavedSettings.getControl("LipSyncOohAahRate")->getSignal()->connect(boost::bind(&handleVoiceVisualizerPrefsChanged, _2));
- gSavedSettings.getControl("LipSyncOoh")->getSignal()->connect(boost::bind(&handleVoiceVisualizerPrefsChanged, _2));
- gSavedSettings.getControl("LipSyncAah")->getSignal()->connect(boost::bind(&handleVoiceVisualizerPrefsChanged, _2));
- gSavedSettings.getControl("LipSyncOohPowerTransfer")->getSignal()->connect(boost::bind(&handleVoiceVisualizerPrefsChanged, _2));
- gSavedSettings.getControl("LipSyncAahPowerTransfer")->getSignal()->connect(boost::bind(&handleVoiceVisualizerPrefsChanged, _2));
+ gSavedSettings.getControl("LipSyncEnabled")->getSignal()->connect(boost::bind(&LLVoiceVisualizer::handleVoiceVisualizerPrefsChanged, _2));
+ gSavedSettings.getControl("LipSyncOohAahRate")->getSignal()->connect(boost::bind(&LLVoiceVisualizer::handleVoiceVisualizerPrefsChanged, _2));
+ gSavedSettings.getControl("LipSyncOoh")->getSignal()->connect(boost::bind(&LLVoiceVisualizer::handleVoiceVisualizerPrefsChanged, _2));
+ gSavedSettings.getControl("LipSyncAah")->getSignal()->connect(boost::bind(&LLVoiceVisualizer::handleVoiceVisualizerPrefsChanged, _2));
+ gSavedSettings.getControl("LipSyncOohPowerTransfer")->getSignal()->connect(boost::bind(&LLVoiceVisualizer::handleVoiceVisualizerPrefsChanged, _2));
+ gSavedSettings.getControl("LipSyncAahPowerTransfer")->getSignal()->connect(boost::bind(&LLVoiceVisualizer::handleVoiceVisualizerPrefsChanged, _2));
sPrefsInitialized = true;
}
@@ -217,6 +206,15 @@ void LLVoiceVisualizer::setSpeakingAmplitude( F32 a )
}//---------------------------------------------------
+//------------------------------------------------------------------
+// handles parameter updates
+//------------------------------------------------------------------
+bool LLVoiceVisualizer::handleVoiceVisualizerPrefsChanged(const LLSD& newvalue)
+{
+ // Note: Ignore the specific event value, we look up the ones we want
+ LLVoiceVisualizer::setPreferences();
+ return true;
+}
//---------------------------------------------------
void LLVoiceVisualizer::setPreferences( )
@@ -526,10 +524,6 @@ void LLVoiceVisualizer::render()
}//---------------------------------------------------
-
-
-
-
//---------------------------------------------------
void LLVoiceVisualizer::setVoiceSourceWorldPosition( const LLVector3 &p )
{
@@ -615,11 +609,3 @@ void LLVoiceVisualizer::markDead()
LLHUDEffect::markDead();
}//------------------------------------------------------------------
-
-
-
-
-
-
-
-
diff --git a/indra/newview/llvoicevisualizer.h b/indra/newview/llvoicevisualizer.h
index e434c7f3f1..36c78252d1 100644..100755
--- a/indra/newview/llvoicevisualizer.h
+++ b/indra/newview/llvoicevisualizer.h
@@ -71,10 +71,8 @@ class LLVoiceVisualizer : public LLHUDEffect
// public methods
//---------------------------------------------------
public:
- LLVoiceVisualizer ( const U8 type ); //constructor
+ LLVoiceVisualizer( const U8 type ); //constructor
~LLVoiceVisualizer(); //destructor
-
- friend class LLHUDObject;
void setVoiceSourceWorldPosition( const LLVector3 &p ); // this should be the position of the speaking avatar's head
void setMinGesticulationAmplitude( F32 ); // the lower range of meaningful amplitude for setting gesticulation level
@@ -85,8 +83,6 @@ class LLVoiceVisualizer : public LLHUDEffect
void setStopSpeaking(); // tell me when the av stops speaking
bool getCurrentlySpeaking(); // the get for the above set
VoiceGesticulationLevel getCurrentGesticulationLevel(); // based on voice amplitude, I'll give you the current "energy level" of avatar speech
- static void setPreferences( );
- static void lipStringToF32s ( std::string& in_string, F32*& out_F32s, U32& count_F32s ); // convert a string of digits to an array of floats
void lipSyncOohAah( F32& ooh, F32& aah );
void render(); // inherited from HUD Effect
void packData(LLMessageSystem *mesgsys); // inherited from HUD Effect
@@ -108,7 +104,10 @@ class LLVoiceVisualizer : public LLHUDEffect
// private members
//---------------------------------------------------
private:
-
+ static bool handleVoiceVisualizerPrefsChanged(const LLSD& newvalue);
+ static void setPreferences( );
+ static void lipStringToF32s ( std::string& in_string, F32*& out_F32s, U32& count_F32s ); // convert a string of digits to an array of floats
+
struct SoundSymbol
{
F32 mWaveExpansion [ NUM_VOICE_SYMBOL_WAVES ];
diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp
index df1d3f2955..9497041482 100644..100755
--- a/indra/newview/llvoicevivox.cpp
+++ b/indra/newview/llvoicevivox.cpp
@@ -27,8 +27,6 @@
#include "llviewerprecompiledheaders.h"
#include "llvoicevivox.h"
-#include <boost/tokenizer.hpp>
-
#include "llsdutil.h"
// Linden library includes
@@ -36,6 +34,7 @@
#include "llvoavatarself.h"
#include "llbufferstream.h"
#include "llfile.h"
+#include "llmenugl.h"
#ifdef LL_STANDALONE
# include "expat.h"
#else
@@ -47,6 +46,7 @@
#include "llbase64.h"
#include "llviewercontrol.h"
#include "llappviewer.h" // for gDisconnected, gDisableVoice
+#include "llprocess.h"
// Viewer includes
#include "llmutelist.h" // to check for muted avatars
@@ -71,6 +71,9 @@
#define USE_SESSION_GROUPS 0
+extern LLMenuBarGL* gMenuBarView;
+extern void handle_voice_morphing_subscribe();
+
const F32 VOLUME_SCALE_VIVOX = 0.01f;
const F32 SPEAKING_TIMEOUT = 1.f;
@@ -127,17 +130,18 @@ public:
mRetries = retries;
}
- virtual void error(U32 status, const std::string& reason)
+ virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content)
{
+ LL_WARNS("Voice") << "ProvisionVoiceAccountRequest returned an error, "
+ << ( (mRetries > 0) ? "retrying" : "too many retries (giving up)" )
+ << status << "]: " << content << LL_ENDL;
+
if ( mRetries > 0 )
{
- LL_WARNS("Voice") << "ProvisionVoiceAccountRequest returned an error, retrying. status = " << status << ", reason = \"" << reason << "\"" << LL_ENDL;
- LLVivoxVoiceClient::getInstance()->requestVoiceAccountProvision(
- mRetries - 1);
+ LLVivoxVoiceClient::getInstance()->requestVoiceAccountProvision(mRetries - 1);
}
else
{
- LL_WARNS("Voice") << "ProvisionVoiceAccountRequest returned an error, too many retries (giving up). status = " << status << ", reason = \"" << reason << "\"" << LL_ENDL;
LLVivoxVoiceClient::getInstance()->giveUp();
}
}
@@ -178,17 +182,10 @@ class LLVivoxVoiceClientMuteListObserver : public LLMuteListObserver
/* virtual */ void onChange() { LLVivoxVoiceClient::getInstance()->muteListChanged();}
};
-class LLVivoxVoiceClientFriendsObserver : public LLFriendObserver
-{
-public:
- /* virtual */ void changed(U32 mask) { LLVivoxVoiceClient::getInstance()->updateFriends(mask);}
-};
static LLVivoxVoiceClientMuteListObserver mutelist_listener;
static bool sMuteListListener_listening = false;
-static LLVivoxVoiceClientFriendsObserver *friendslist_listener = NULL;
-
///////////////////////////////////////////////////////////////////////////////////////////////
class LLVivoxVoiceClientCapResponder : public LLHTTPClient::Responder
@@ -196,18 +193,18 @@ class LLVivoxVoiceClientCapResponder : public LLHTTPClient::Responder
public:
LLVivoxVoiceClientCapResponder(LLVivoxVoiceClient::state requesting_state) : mRequestingState(requesting_state) {};
- virtual void error(U32 status, const std::string& reason); // called with bad status codes
+ // called with bad status codes
+ virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content);
virtual void result(const LLSD& content);
private:
LLVivoxVoiceClient::state mRequestingState; // state
};
-void LLVivoxVoiceClientCapResponder::error(U32 status, const std::string& reason)
+void LLVivoxVoiceClientCapResponder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)
{
- LL_WARNS("Voice") << "LLVivoxVoiceClientCapResponder::error("
- << status << ": " << reason << ")"
- << LL_ENDL;
+ LL_WARNS("Voice") << "LLVivoxVoiceClientCapResponder error [status:"
+ << status << "]: " << content << LL_ENDL;
LLVivoxVoiceClient::getInstance()->sessionTerminate();
}
@@ -242,59 +239,21 @@ void LLVivoxVoiceClientCapResponder::result(const LLSD& content)
}
}
-
-
-#if LL_WINDOWS
-static HANDLE sGatewayHandle = 0;
+static LLProcessPtr sGatewayPtr;
static bool isGatewayRunning()
{
- bool result = false;
- if(sGatewayHandle != 0)
- {
- DWORD waitresult = WaitForSingleObject(sGatewayHandle, 0);
- if(waitresult != WAIT_OBJECT_0)
- {
- result = true;
- }
- }
- return result;
-}
-static void killGateway()
-{
- if(sGatewayHandle != 0)
- {
- TerminateProcess(sGatewayHandle,0);
- }
-}
-
-#else // Mac and linux
-
-static pid_t sGatewayPID = 0;
-static bool isGatewayRunning()
-{
- bool result = false;
- if(sGatewayPID != 0)
- {
- // A kill with signal number 0 has no effect, just does error checking. It should return an error if the process no longer exists.
- if(kill(sGatewayPID, 0) == 0)
- {
- result = true;
- }
- }
- return result;
+ return sGatewayPtr && sGatewayPtr->isRunning();
}
static void killGateway()
{
- if(sGatewayPID != 0)
+ if (sGatewayPtr)
{
- kill(sGatewayPID, SIGTERM);
+ sGatewayPtr->kill();
}
}
-#endif
-
///////////////////////////////////////////////////////////////////////////////////////////////
LLVivoxVoiceClient::LLVivoxVoiceClient() :
@@ -330,6 +289,7 @@ LLVivoxVoiceClient::LLVivoxVoiceClient() :
mCaptureDeviceDirty(false),
mRenderDeviceDirty(false),
mSpatialCoordsDirty(false),
+ mIsInitialized(false),
mMuteMic(false),
mMuteMicDirty(false),
@@ -354,7 +314,9 @@ LLVivoxVoiceClient::LLVivoxVoiceClient() :
mCaptureBufferRecording(false),
mCaptureBufferRecorded(false),
mCaptureBufferPlaying(false),
- mPlayRequestCount(0)
+ mPlayRequestCount(0),
+
+ mAvatarNameCacheConnection()
{
mSpeakerVolume = scale_speaker_volume(0);
@@ -387,6 +349,10 @@ LLVivoxVoiceClient::LLVivoxVoiceClient() :
LLVivoxVoiceClient::~LLVivoxVoiceClient()
{
+ if (mAvatarNameCacheConnection.connected())
+ {
+ mAvatarNameCacheConnection.disconnect();
+ }
}
//---------------------------------------------------
@@ -417,7 +383,6 @@ void LLVivoxVoiceClient::terminate()
void LLVivoxVoiceClient::cleanUp()
{
deleteAllSessions();
- deleteAllBuddies();
deleteAllVoiceFonts();
deleteVoiceFontTemplates();
}
@@ -503,10 +468,10 @@ void LLVivoxVoiceClient::connectorCreate()
std::string savedLogLevel = gSavedSettings.getString("VivoxDebugLevel");
- if(savedLogLevel != "-1")
+ if(savedLogLevel != "-0")
{
LL_DEBUGS("Voice") << "creating connector with logging enabled" << LL_ENDL;
- loglevel = "10";
+ loglevel = "0";
}
stream
@@ -559,25 +524,25 @@ void LLVivoxVoiceClient::requestVoiceAccountProvision(S32 retries)
{
LLViewerRegion *region = gAgent.getRegion();
- if ( region && mVoiceEnabled )
+ // If we've not received the capability yet, return.
+ // the password will remain empty, so we'll remain in
+ // stateIdle
+ if ( region &&
+ region->capabilitiesReceived() &&
+ (mVoiceEnabled || !mIsInitialized))
{
std::string url =
region->getCapability("ProvisionVoiceAccountRequest");
- if ( url.empty() )
+ if ( !url.empty() )
{
- // we've not received the capability yet, so return.
- // the password will remain empty, so we'll remain in
- // stateIdle
- return;
- }
-
- LLHTTPClient::post(
- url,
- LLSD(),
- new LLVivoxVoiceAccountProvisionResponder(retries));
+ LLHTTPClient::post(
+ url,
+ LLSD(),
+ new LLVivoxVoiceAccountProvisionResponder(retries));
- setState(stateConnectorStart);
+ setState(stateConnectorStart);
+ }
}
}
@@ -730,7 +695,7 @@ void LLVivoxVoiceClient::stateMachine()
setVoiceEnabled(false);
}
- if(mVoiceEnabled)
+ if(mVoiceEnabled || !mIsInitialized)
{
updatePosition();
}
@@ -775,7 +740,7 @@ void LLVivoxVoiceClient::stateMachine()
//MARK: stateDisabled
case stateDisabled:
- if(mTuningMode || (mVoiceEnabled && !mAccountName.empty()))
+ if(mTuningMode || ((mVoiceEnabled || !mIsInitialized) && !mAccountName.empty()))
{
setState(stateStart);
}
@@ -790,7 +755,7 @@ void LLVivoxVoiceClient::stateMachine()
}
else if(!isGatewayRunning())
{
- if(true)
+ if (true) // production build, not test
{
// Launch the voice daemon
@@ -809,102 +774,32 @@ void LLVivoxVoiceClient::stateMachine()
#endif
// See if the vivox executable exists
llstat s;
- if(!LLFile::stat(exe_path, &s))
+ if (!LLFile::stat(exe_path, &s))
{
// vivox executable exists. Build the command line and launch the daemon.
+ LLProcess::Params params;
+ params.executable = exe_path;
// SLIM SDK: these arguments are no longer necessary.
// std::string args = " -p tcp -h -c";
- std::string args;
- std::string cmd;
std::string loglevel = gSavedSettings.getString("VivoxDebugLevel");
-
if(loglevel.empty())
{
- loglevel = "-1"; // turn logging off completely
+ loglevel = "0"; // turn logging off completely
}
-
- args += " -ll ";
- args += loglevel;
-
- LL_DEBUGS("Voice") << "Args for SLVoice: " << args << LL_ENDL;
+ params.args.add("-ll");
+ params.args.add(loglevel);
+ params.cwd = gDirUtilp->getAppRODataDir();
+ sGatewayPtr = LLProcess::create(params);
-#if LL_WINDOWS
- PROCESS_INFORMATION pinfo;
- STARTUPINFOA sinfo;
-
- memset(&sinfo, 0, sizeof(sinfo));
-
- std::string exe_dir = gDirUtilp->getAppRODataDir();
- cmd = "SLVoice.exe";
- cmd += args;
-
- // So retarded. Windows requires that the second parameter to CreateProcessA be writable (non-const) string...
- char *args2 = new char[args.size() + 1];
- strcpy(args2, args.c_str());
- if(!CreateProcessA(exe_path.c_str(), args2, NULL, NULL, FALSE, 0, NULL, exe_dir.c_str(), &sinfo, &pinfo))
- {
-// DWORD dwErr = GetLastError();
- }
- else
- {
- // foo = pinfo.dwProcessId; // get your pid here if you want to use it later on
- // CloseHandle(pinfo.hProcess); // stops leaks - nothing else
- sGatewayHandle = pinfo.hProcess;
- CloseHandle(pinfo.hThread); // stops leaks - nothing else
- }
-
- delete[] args2;
-#else // LL_WINDOWS
- // This should be the same for mac and linux
- {
- std::vector<std::string> arglist;
- arglist.push_back(exe_path);
-
- // Split the argument string into separate strings for each argument
- typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
- boost::char_separator<char> sep(" ");
- tokenizer tokens(args, sep);
- tokenizer::iterator token_iter;
-
- for(token_iter = tokens.begin(); token_iter != tokens.end(); ++token_iter)
- {
- arglist.push_back(*token_iter);
- }
-
- // create an argv vector for the child process
- char **fakeargv = new char*[arglist.size() + 1];
- int i;
- for(i=0; i < arglist.size(); i++)
- fakeargv[i] = const_cast<char*>(arglist[i].c_str());
-
- fakeargv[i] = NULL;
-
- fflush(NULL); // flush all buffers before the child inherits them
- pid_t id = vfork();
- if(id == 0)
- {
- // child
- execv(exe_path.c_str(), fakeargv);
-
- // If we reach this point, the exec failed.
- // Use _exit() instead of exit() per the vfork man page.
- _exit(0);
- }
-
- // parent
- delete[] fakeargv;
- sGatewayPID = id;
- }
-#endif // LL_WINDOWS
mDaemonHost = LLHost(gSavedSettings.getString("VivoxVoiceHost").c_str(), gSavedSettings.getU32("VivoxVoicePort"));
- }
+ }
else
{
LL_INFOS("Voice") << exe_path << " not found." << LL_ENDL;
- }
+ }
}
else
- {
+ {
// SLIM SDK: port changed from 44124 to 44125.
// We can connect to a client gateway running on another host. This is useful for testing.
// To do this, launch the gateway on a nearby host like this:
@@ -999,7 +894,7 @@ void LLVivoxVoiceClient::stateMachine()
mTuningExitState = stateIdle;
setState(stateMicTuningStart);
}
- else if(!mVoiceEnabled)
+ else if(!mVoiceEnabled && mIsInitialized)
{
// We never started up the connector. This will shut down the daemon.
setState(stateConnectorStopped);
@@ -1193,7 +1088,7 @@ void LLVivoxVoiceClient::stateMachine()
//MARK: stateConnectorStart
case stateConnectorStart:
- if(!mVoiceEnabled)
+ if(!mVoiceEnabled && mIsInitialized)
{
// We were never logged in. This will shut down the connector.
setState(stateLoggedOut);
@@ -1211,7 +1106,7 @@ void LLVivoxVoiceClient::stateMachine()
//MARK: stateConnectorStarted
case stateConnectorStarted: // connector handle received
- if(!mVoiceEnabled)
+ if(!mVoiceEnabled && mIsInitialized)
{
// We were never logged in. This will shut down the connector.
setState(stateLoggedOut);
@@ -1298,25 +1193,12 @@ void LLVivoxVoiceClient::stateMachine()
setState(stateVoiceFontsReceived);
}
- // request the current set of block rules (we'll need them when updating the friends list)
- accountListBlockRulesSendMessage();
-
- // request the current set of auto-accept rules
- accountListAutoAcceptRulesSendMessage();
-
// Set up the mute list observer if it hasn't been set up already.
if((!sMuteListListener_listening))
{
LLMuteList::getInstance()->addObserver(&mutelist_listener);
sMuteListListener_listening = true;
}
-
- // Set up the friends list observer if it hasn't been set up already.
- if(friendslist_listener == NULL)
- {
- friendslist_listener = new LLVivoxVoiceClientFriendsObserver;
- LLAvatarTracker::instance().addObserver(friendslist_listener);
- }
// Set the initial state of mic mute, local speaker volume, etc.
{
@@ -1355,7 +1237,7 @@ void LLVivoxVoiceClient::stateMachine()
//MARK: stateCreatingSessionGroup
case stateCreatingSessionGroup:
- if(mSessionTerminateRequested || !mVoiceEnabled)
+ if(mSessionTerminateRequested || (!mVoiceEnabled && mIsInitialized))
{
// *TODO: Question: is this the right way out of this state
setState(stateSessionTerminated);
@@ -1371,7 +1253,7 @@ void LLVivoxVoiceClient::stateMachine()
//MARK: stateRetrievingParcelVoiceInfo
case stateRetrievingParcelVoiceInfo:
// wait until parcel voice info is received.
- if(mSessionTerminateRequested || !mVoiceEnabled)
+ if(mSessionTerminateRequested || (!mVoiceEnabled && mIsInitialized))
{
// if a terminate request has been received,
// bail and go to the stateSessionTerminated
@@ -1387,11 +1269,9 @@ void LLVivoxVoiceClient::stateMachine()
case stateNoChannel:
LL_DEBUGS("Voice") << "State No Channel" << LL_ENDL;
mSpatialJoiningNum = 0;
- // Do this here as well as inside sendPositionalUpdate().
- // Otherwise, if you log in but don't join a proximal channel (such as when your login location has voice disabled), your friends list won't sync.
- sendFriendsListUpdates();
+
- if(mSessionTerminateRequested || !mVoiceEnabled)
+ if(mSessionTerminateRequested || (!mVoiceEnabled && mIsInitialized))
{
// TODO: Question: Is this the right way out of this state?
setState(stateSessionTerminated);
@@ -1472,7 +1352,7 @@ void LLVivoxVoiceClient::stateMachine()
}
// joinedAudioSession() will transition from here to stateSessionJoined.
- if(!mVoiceEnabled)
+ if(!mVoiceEnabled && mIsInitialized)
{
// User bailed out during connect -- jump straight to teardown.
setState(stateSessionTerminated);
@@ -1519,7 +1399,7 @@ void LLVivoxVoiceClient::stateMachine()
notifyStatusObservers(LLVoiceClientStatusObserver::STATUS_JOINED);
}
- else if(!mVoiceEnabled)
+ else if(!mVoiceEnabled && mIsInitialized)
{
// User bailed out during connect -- jump straight to teardown.
setState(stateSessionTerminated);
@@ -1539,7 +1419,7 @@ void LLVivoxVoiceClient::stateMachine()
//MARK: stateRunning
case stateRunning: // steady state
// Disabling voice or disconnect requested.
- if(!mVoiceEnabled || mSessionTerminateRequested)
+ if((!mVoiceEnabled && mIsInitialized) || mSessionTerminateRequested)
{
leaveAudioSession();
}
@@ -1586,6 +1466,7 @@ void LLVivoxVoiceClient::stateMachine()
mUpdateTimer.setTimerExpirySec(UPDATE_THROTTLE_SECONDS);
sendPositionalUpdate();
}
+ mIsInitialized = true;
}
break;
@@ -1619,7 +1500,7 @@ void LLVivoxVoiceClient::stateMachine()
// Always reset the terminate request flag when we get here.
mSessionTerminateRequested = false;
- if(mVoiceEnabled && !mRelogRequested)
+ if((mVoiceEnabled || !mIsInitialized) && !mRelogRequested)
{
// Just leaving a channel, go back to stateNoChannel (the "logged in but have no channel" state).
setState(stateNoChannel);
@@ -1647,7 +1528,7 @@ void LLVivoxVoiceClient::stateMachine()
mAccountHandle.clear();
cleanUp();
- if(mVoiceEnabled && !mRelogRequested)
+ if((mVoiceEnabled || !mIsInitialized) && !mRelogRequested)
{
// User was logged out, but wants to be logged in. Send a new login request.
setState(stateNeedsLogin);
@@ -1742,7 +1623,7 @@ void LLVivoxVoiceClient::stateMachine()
void LLVivoxVoiceClient::closeSocket(void)
{
mSocket.reset();
- mConnected = false;
+ mConnected = false;
mConnectorHandle.clear();
mAccountHandle.clear();
}
@@ -1759,7 +1640,7 @@ void LLVivoxVoiceClient::loginSendMessage()
<< "<AccountName>" << mAccountName << "</AccountName>"
<< "<AccountPassword>" << mAccountPassword << "</AccountPassword>"
<< "<AudioSessionAnswerMode>VerifyAnswer</AudioSessionAnswerMode>"
- << "<EnableBuddiesAndPresence>true</EnableBuddiesAndPresence>"
+ << "<EnableBuddiesAndPresence>false</EnableBuddiesAndPresence>"
<< "<BuddyManagementMode>Application</BuddyManagementMode>"
<< "<ParticipantPropertyFrequency>5</ParticipantPropertyFrequency>"
<< (autoPostCrashDumps?"<AutopostCrashDumps>true</AutopostCrashDumps>":"")
@@ -1795,42 +1676,6 @@ void LLVivoxVoiceClient::logoutSendMessage()
}
}
-void LLVivoxVoiceClient::accountListBlockRulesSendMessage()
-{
- if(!mAccountHandle.empty())
- {
- std::ostringstream stream;
-
- LL_DEBUGS("Voice") << "requesting block rules" << LL_ENDL;
-
- stream
- << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Account.ListBlockRules.1\">"
- << "<AccountHandle>" << mAccountHandle << "</AccountHandle>"
- << "</Request>"
- << "\n\n\n";
-
- writeString(stream.str());
- }
-}
-
-void LLVivoxVoiceClient::accountListAutoAcceptRulesSendMessage()
-{
- if(!mAccountHandle.empty())
- {
- std::ostringstream stream;
-
- LL_DEBUGS("Voice") << "requesting auto-accept rules" << LL_ENDL;
-
- stream
- << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Account.ListAutoAcceptRules.1\">"
- << "<AccountHandle>" << mAccountHandle << "</AccountHandle>"
- << "</Request>"
- << "\n\n\n";
-
- writeString(stream.str());
- }
-}
-
void LLVivoxVoiceClient::sessionGroupCreateSendMessage()
{
if(!mAccountHandle.empty())
@@ -2344,7 +2189,8 @@ void LLVivoxVoiceClient::giveUp()
static void oldSDKTransform (LLVector3 &left, LLVector3 &up, LLVector3 &at, LLVector3d &pos, LLVector3 &vel)
{
- F32 nat[3], nup[3], nl[3], nvel[3]; // the new at, up, left vectors and the new position and velocity
+ F32 nat[3], nup[3], nl[3]; // the new at, up, left vectors and the new position and velocity
+// F32 nvel[3];
F64 npos[3];
// The original XML command was sent like this:
@@ -2394,9 +2240,9 @@ static void oldSDKTransform (LLVector3 &left, LLVector3 &up, LLVector3 &at, LLVe
npos[1] = pos.mdV[VZ];
npos[2] = pos.mdV[VY];
- nvel[0] = vel.mV[VX];
- nvel[1] = vel.mV[VZ];
- nvel[2] = vel.mV[VY];
+// nvel[0] = vel.mV[VX];
+// nvel[1] = vel.mV[VZ];
+// nvel[2] = vel.mV[VY];
for(int i=0;i<3;++i) {
at.mV[i] = nat[i];
@@ -2661,10 +2507,7 @@ void LLVivoxVoiceClient::sendPositionalUpdate(void)
{
writeString(stream.str());
}
-
- // Friends list updates can be huge, especially on the first voice login of an account with lots of friends.
- // Batching them all together can choke SLVoice, so send them in separate writes.
- sendFriendsListUpdates();
+
}
void LLVivoxVoiceClient::buildSetCaptureDevice(std::ostringstream &stream)
@@ -2762,291 +2605,6 @@ void LLVivoxVoiceClient::buildLocalAudioUpdates(std::ostringstream &stream)
}
-void LLVivoxVoiceClient::checkFriend(const LLUUID& id)
-{
- buddyListEntry *buddy = findBuddy(id);
-
- // Make sure we don't add a name before it's been looked up.
- LLAvatarName av_name;
- if(LLAvatarNameCache::get(id, &av_name))
- {
- // *NOTE: For now, we feed legacy names to Vivox because I don't know
- // if their service can support a mix of new and old clients with
- // different sorts of names.
- std::string name = av_name.getLegacyName();
-
- const LLRelationship* relationInfo = LLAvatarTracker::instance().getBuddyInfo(id);
- bool canSeeMeOnline = false;
- if(relationInfo && relationInfo->isRightGrantedTo(LLRelationship::GRANT_ONLINE_STATUS))
- canSeeMeOnline = true;
-
- // When we get here, mNeedsSend is true and mInSLFriends is false. Change them as necessary.
-
- if(buddy)
- {
- // This buddy is already in both lists.
-
- if(name != buddy->mDisplayName)
- {
- // The buddy is in the list with the wrong name. Update it with the correct name.
- LL_WARNS("Voice") << "Buddy " << id << " has wrong name (\"" << buddy->mDisplayName << "\" should be \"" << name << "\"), updating."<< LL_ENDL;
- buddy->mDisplayName = name;
- buddy->mNeedsNameUpdate = true; // This will cause the buddy to be resent.
- }
- }
- else
- {
- // This buddy was not in the vivox list, needs to be added.
- buddy = addBuddy(sipURIFromID(id), name);
- buddy->mUUID = id;
- }
-
- // In all the above cases, the buddy is in the SL friends list (which is how we got here).
- buddy->mInSLFriends = true;
- buddy->mCanSeeMeOnline = canSeeMeOnline;
- buddy->mNameResolved = true;
-
- }
- else
- {
- // This name hasn't been looked up yet. Don't do anything with this buddy list entry until it has.
- if(buddy)
- {
- buddy->mNameResolved = false;
- }
-
- // Initiate a lookup.
- // The "lookup completed" callback will ensure that the friends list is rechecked after it completes.
- lookupName(id);
- }
-}
-
-void LLVivoxVoiceClient::clearAllLists()
-{
- // FOR TESTING ONLY
-
- // This will send the necessary commands to delete ALL buddies, autoaccept rules, and block rules SLVoice tells us about.
- buddyListMap::iterator buddy_it;
- for(buddy_it = mBuddyListMap.begin(); buddy_it != mBuddyListMap.end();)
- {
- buddyListEntry *buddy = buddy_it->second;
- buddy_it++;
-
- std::ostringstream stream;
-
- if(buddy->mInVivoxBuddies)
- {
- // delete this entry from the vivox buddy list
- buddy->mInVivoxBuddies = false;
- LL_DEBUGS("Voice") << "delete " << buddy->mURI << " (" << buddy->mDisplayName << ")" << LL_ENDL;
- stream << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Account.BuddyDelete.1\">"
- << "<AccountHandle>" << mAccountHandle << "</AccountHandle>"
- << "<BuddyURI>" << buddy->mURI << "</BuddyURI>"
- << "</Request>\n\n\n";
- }
-
- if(buddy->mHasBlockListEntry)
- {
- // Delete the associated block list entry (so the block list doesn't fill up with junk)
- buddy->mHasBlockListEntry = false;
- stream << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Account.DeleteBlockRule.1\">"
- << "<AccountHandle>" << mAccountHandle << "</AccountHandle>"
- << "<BlockMask>" << buddy->mURI << "</BlockMask>"
- << "</Request>\n\n\n";
- }
- if(buddy->mHasAutoAcceptListEntry)
- {
- // Delete the associated auto-accept list entry (so the auto-accept list doesn't fill up with junk)
- buddy->mHasAutoAcceptListEntry = false;
- stream << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Account.DeleteAutoAcceptRule.1\">"
- << "<AccountHandle>" << mAccountHandle << "</AccountHandle>"
- << "<AutoAcceptMask>" << buddy->mURI << "</AutoAcceptMask>"
- << "</Request>\n\n\n";
- }
-
- writeString(stream.str());
-
- }
-}
-
-void LLVivoxVoiceClient::sendFriendsListUpdates()
-{
- if(mBuddyListMapPopulated && mBlockRulesListReceived && mAutoAcceptRulesListReceived && mFriendsListDirty)
- {
- mFriendsListDirty = false;
-
- if(0)
- {
- // FOR TESTING ONLY -- clear all buddy list, block list, and auto-accept list entries.
- clearAllLists();
- return;
- }
-
- LL_INFOS("Voice") << "Checking vivox buddy list against friends list..." << LL_ENDL;
-
- buddyListMap::iterator buddy_it;
- for(buddy_it = mBuddyListMap.begin(); buddy_it != mBuddyListMap.end(); buddy_it++)
- {
- // reset the temp flags in the local buddy list
- buddy_it->second->mInSLFriends = false;
- }
-
- // correlate with the friends list
- {
- LLCollectAllBuddies collect;
- LLAvatarTracker::instance().applyFunctor(collect);
- LLCollectAllBuddies::buddy_map_t::const_iterator it = collect.mOnline.begin();
- LLCollectAllBuddies::buddy_map_t::const_iterator end = collect.mOnline.end();
-
- for ( ; it != end; ++it)
- {
- checkFriend(it->second);
- }
- it = collect.mOffline.begin();
- end = collect.mOffline.end();
- for ( ; it != end; ++it)
- {
- checkFriend(it->second);
- }
- }
-
- LL_INFOS("Voice") << "Sending friend list updates..." << LL_ENDL;
-
- for(buddy_it = mBuddyListMap.begin(); buddy_it != mBuddyListMap.end();)
- {
- buddyListEntry *buddy = buddy_it->second;
- buddy_it++;
-
- // Ignore entries that aren't resolved yet.
- if(buddy->mNameResolved)
- {
- std::ostringstream stream;
-
- if(buddy->mInSLFriends && (!buddy->mInVivoxBuddies || buddy->mNeedsNameUpdate))
- {
- if(mNumberOfAliases > 0)
- {
- // Add (or update) this entry in the vivox buddy list
- buddy->mInVivoxBuddies = true;
- buddy->mNeedsNameUpdate = false;
- LL_DEBUGS("Voice") << "add/update " << buddy->mURI << " (" << buddy->mDisplayName << ")" << LL_ENDL;
- stream
- << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Account.BuddySet.1\">"
- << "<AccountHandle>" << mAccountHandle << "</AccountHandle>"
- << "<BuddyURI>" << buddy->mURI << "</BuddyURI>"
- << "<DisplayName>" << buddy->mDisplayName << "</DisplayName>"
- << "<BuddyData></BuddyData>" // Without this, SLVoice doesn't seem to parse the command.
- << "<GroupID>0</GroupID>"
- << "</Request>\n\n\n";
- }
- }
- else if(!buddy->mInSLFriends)
- {
- // This entry no longer exists in your SL friends list. Remove all traces of it from the Vivox buddy list.
- if(buddy->mInVivoxBuddies)
- {
- // delete this entry from the vivox buddy list
- buddy->mInVivoxBuddies = false;
- LL_DEBUGS("Voice") << "delete " << buddy->mURI << " (" << buddy->mDisplayName << ")" << LL_ENDL;
- stream << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Account.BuddyDelete.1\">"
- << "<AccountHandle>" << mAccountHandle << "</AccountHandle>"
- << "<BuddyURI>" << buddy->mURI << "</BuddyURI>"
- << "</Request>\n\n\n";
- }
-
- if(buddy->mHasBlockListEntry)
- {
- // Delete the associated block list entry, if any
- buddy->mHasBlockListEntry = false;
- stream << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Account.DeleteBlockRule.1\">"
- << "<AccountHandle>" << mAccountHandle << "</AccountHandle>"
- << "<BlockMask>" << buddy->mURI << "</BlockMask>"
- << "</Request>\n\n\n";
- }
- if(buddy->mHasAutoAcceptListEntry)
- {
- // Delete the associated auto-accept list entry, if any
- buddy->mHasAutoAcceptListEntry = false;
- stream << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Account.DeleteAutoAcceptRule.1\">"
- << "<AccountHandle>" << mAccountHandle << "</AccountHandle>"
- << "<AutoAcceptMask>" << buddy->mURI << "</AutoAcceptMask>"
- << "</Request>\n\n\n";
- }
- }
-
- if(buddy->mInSLFriends)
- {
-
- if(buddy->mCanSeeMeOnline)
- {
- // Buddy should not be blocked.
-
- // If this buddy doesn't already have either a block or autoaccept list entry, we'll update their status when we receive a SubscriptionEvent.
-
- // If the buddy has a block list entry, delete it.
- if(buddy->mHasBlockListEntry)
- {
- buddy->mHasBlockListEntry = false;
- stream << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Account.DeleteBlockRule.1\">"
- << "<AccountHandle>" << mAccountHandle << "</AccountHandle>"
- << "<BlockMask>" << buddy->mURI << "</BlockMask>"
- << "</Request>\n\n\n";
-
-
- // If we just deleted a block list entry, add an auto-accept entry.
- if(!buddy->mHasAutoAcceptListEntry)
- {
- buddy->mHasAutoAcceptListEntry = true;
- stream << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Account.CreateAutoAcceptRule.1\">"
- << "<AccountHandle>" << mAccountHandle << "</AccountHandle>"
- << "<AutoAcceptMask>" << buddy->mURI << "</AutoAcceptMask>"
- << "<AutoAddAsBuddy>0</AutoAddAsBuddy>"
- << "</Request>\n\n\n";
- }
- }
- }
- else
- {
- // Buddy should be blocked.
-
- // If this buddy doesn't already have either a block or autoaccept list entry, we'll update their status when we receive a SubscriptionEvent.
-
- // If this buddy has an autoaccept entry, delete it
- if(buddy->mHasAutoAcceptListEntry)
- {
- buddy->mHasAutoAcceptListEntry = false;
- stream << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Account.DeleteAutoAcceptRule.1\">"
- << "<AccountHandle>" << mAccountHandle << "</AccountHandle>"
- << "<AutoAcceptMask>" << buddy->mURI << "</AutoAcceptMask>"
- << "</Request>\n\n\n";
-
- // If we just deleted an auto-accept entry, add a block list entry.
- if(!buddy->mHasBlockListEntry)
- {
- buddy->mHasBlockListEntry = true;
- stream << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Account.CreateBlockRule.1\">"
- << "<AccountHandle>" << mAccountHandle << "</AccountHandle>"
- << "<BlockMask>" << buddy->mURI << "</BlockMask>"
- << "<PresenceOnly>1</PresenceOnly>"
- << "</Request>\n\n\n";
- }
- }
- }
-
- if(!buddy->mInSLFriends && !buddy->mInVivoxBuddies)
- {
- // Delete this entry from the local buddy list. This should NOT invalidate the iterator,
- // since it has already been incremented to the next entry.
- deleteBuddy(buddy->mURI);
- }
-
- }
- writeString(stream.str());
- }
- }
- }
-}
-
/////////////////////////////
// Response/Event handlers
@@ -3820,8 +3378,7 @@ void LLVivoxVoiceClient::participantUpdatedEvent(
voice participant mIsModeratorMuted is changed after speakers are updated in Speaker Manager
and event is not fired.
- So, we have to call LLSpeakerMgr::update() here. In any case it is better than call it
- in LLCallFloater::draw()
+ So, we have to call LLSpeakerMgr::update() here.
*/
LLVoiceChannel* voice_cnl = LLVoiceChannel::getCurrentVoiceChannel();
@@ -3853,83 +3410,6 @@ void LLVivoxVoiceClient::participantUpdatedEvent(
}
}
-void LLVivoxVoiceClient::buddyPresenceEvent(
- std::string &uriString,
- std::string &alias,
- std::string &statusString,
- std::string &applicationString)
-{
- buddyListEntry *buddy = findBuddy(uriString);
-
- if(buddy)
- {
- LL_DEBUGS("Voice") << "Presence event for " << buddy->mDisplayName << " status \"" << statusString << "\", application \"" << applicationString << "\""<< LL_ENDL;
- LL_DEBUGS("Voice") << "before: mOnlineSL = " << (buddy->mOnlineSL?"true":"false") << ", mOnlineSLim = " << (buddy->mOnlineSLim?"true":"false") << LL_ENDL;
-
- if(applicationString.empty())
- {
- // This presence event is from a client that doesn't set up the Application string. Do things the old-skool way.
- // NOTE: this will be needed to support people who aren't on the 3010-class SDK yet.
-
- if ( stricmp("Unknown", statusString.c_str())== 0)
- {
- // User went offline with a non-SLim-enabled viewer.
- buddy->mOnlineSL = false;
- }
- else if ( stricmp("Online", statusString.c_str())== 0)
- {
- // User came online with a non-SLim-enabled viewer.
- buddy->mOnlineSL = true;
- }
- else
- {
- // If the user is online through SLim, their status will be "Online-slc", "Away", or something else.
- // NOTE: we should never see this unless someone is running an OLD version of SLim -- the versions that should be in use now all set the application string.
- buddy->mOnlineSLim = true;
- }
- }
- else if(applicationString.find("SecondLifeViewer") != std::string::npos)
- {
- // This presence event is from a viewer that sets the application string
- if ( stricmp("Unknown", statusString.c_str())== 0)
- {
- // Viewer says they're offline
- buddy->mOnlineSL = false;
- }
- else
- {
- // Viewer says they're online
- buddy->mOnlineSL = true;
- }
- }
- else
- {
- // This presence event is from something which is NOT the SL viewer (assume it's SLim).
- if ( stricmp("Unknown", statusString.c_str())== 0)
- {
- // SLim says they're offline
- buddy->mOnlineSLim = false;
- }
- else
- {
- // SLim says they're online
- buddy->mOnlineSLim = true;
- }
- }
-
- LL_DEBUGS("Voice") << "after: mOnlineSL = " << (buddy->mOnlineSL?"true":"false") << ", mOnlineSLim = " << (buddy->mOnlineSLim?"true":"false") << LL_ENDL;
-
- // HACK -- increment the internal change serial number in the LLRelationship (without changing the actual status), so the UI notices the change.
- LLAvatarTracker::instance().setBuddyOnline(buddy->mUUID,LLAvatarTracker::instance().isBuddyOnline(buddy->mUUID));
-
- notifyFriendObservers();
- }
- else
- {
- LL_DEBUGS("Voice") << "Presence for unknown buddy " << uriString << LL_ENDL;
- }
-}
-
void LLVivoxVoiceClient::messageEvent(
std::string &sessionHandle,
std::string &uriString,
@@ -4047,10 +3527,9 @@ void LLVivoxVoiceClient::messageEvent(
sessionState *session = findSession(sessionHandle);
if(session)
{
- bool is_busy = gAgent.getBusy();
+ bool is_do_not_disturb = gAgent.isDoNotDisturb();
bool is_muted = LLMuteList::getInstance()->isMuted(session->mCallerID, session->mName, LLMute::flagTextChat);
bool is_linden = LLMuteList::getInstance()->isLinden(session->mName);
- bool quiet_chat = false;
LLChat chat;
chat.mMuted = is_muted && !is_linden;
@@ -4061,10 +3540,9 @@ void LLVivoxVoiceClient::messageEvent(
chat.mFromName = session->mName;
chat.mSourceType = CHAT_SOURCE_AGENT;
- if(is_busy && !is_linden)
+ if(is_do_not_disturb && !is_linden)
{
- quiet_chat = true;
- // TODO: Question: Return busy mode response here? Or maybe when session is started instead?
+ // TODO: Question: Return do not disturb mode response here? Or maybe when session is started instead?
}
LL_DEBUGS("Voice") << "adding message, name " << session->mName << " session " << session->mIMSessionID << ", target " << session->mCallerID << LL_ENDL;
@@ -4072,6 +3550,7 @@ void LLVivoxVoiceClient::messageEvent(
session->mCallerID,
session->mName.c_str(),
message.c_str(),
+ false,
LLStringUtil::null, // default arg
IM_NOTHING_SPECIAL, // default arg
0, // default arg
@@ -4121,70 +3600,12 @@ void LLVivoxVoiceClient::sessionNotificationEvent(std::string &sessionHandle, st
}
}
-void LLVivoxVoiceClient::subscriptionEvent(std::string &buddyURI, std::string &subscriptionHandle, std::string &alias, std::string &displayName, std::string &applicationString, std::string &subscriptionType)
-{
- buddyListEntry *buddy = findBuddy(buddyURI);
-
- if(!buddy)
- {
- // Couldn't find buddy by URI, try converting the alias...
- if(!alias.empty())
- {
- LLUUID id;
- if(IDFromName(alias, id))
- {
- buddy = findBuddy(id);
- }
- }
- }
-
- if(buddy)
- {
- std::ostringstream stream;
-
- if(buddy->mCanSeeMeOnline)
- {
- // Sending the response will create an auto-accept rule
- buddy->mHasAutoAcceptListEntry = true;
- }
- else
- {
- // Sending the response will create a block rule
- buddy->mHasBlockListEntry = true;
- }
-
- if(buddy->mInSLFriends)
- {
- buddy->mInVivoxBuddies = true;
- }
-
- stream
- << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Account.SendSubscriptionReply.1\">"
- << "<AccountHandle>" << mAccountHandle << "</AccountHandle>"
- << "<BuddyURI>" << buddy->mURI << "</BuddyURI>"
- << "<RuleType>" << (buddy->mCanSeeMeOnline?"Allow":"Hide") << "</RuleType>"
- << "<AutoAccept>"<< (buddy->mInSLFriends?"1":"0")<< "</AutoAccept>"
- << "<SubscriptionHandle>" << subscriptionHandle << "</SubscriptionHandle>"
- << "</Request>"
- << "\n\n\n";
-
- writeString(stream.str());
- }
-}
-
void LLVivoxVoiceClient::auxAudioPropertiesEvent(F32 energy)
{
LL_DEBUGS("Voice") << "got energy " << energy << LL_ENDL;
mTuningEnergy = energy;
}
-void LLVivoxVoiceClient::buddyListChanged()
-{
- // This is called after we receive a BuddyAndGroupListChangedEvent.
- mBuddyListMapPopulated = true;
- mFriendsListDirty = true;
-}
-
void LLVivoxVoiceClient::muteListChanged()
{
// The user's mute list has been updated. Go through the current participant list and sync it with the mute list.
@@ -4203,15 +3624,6 @@ void LLVivoxVoiceClient::muteListChanged()
}
}
-void LLVivoxVoiceClient::updateFriends(U32 mask)
-{
- if(mask & (LLFriendObserver::ADD | LLFriendObserver::REMOVE | LLFriendObserver::POWERS))
- {
- // Just resend the whole friend list to the daemon
- mFriendsListDirty = true;
- }
-}
-
/////////////////////////////
// Managing list of participants
LLVivoxVoiceClient::participantState::participantState(const std::string &uri) :
@@ -4810,34 +4222,6 @@ bool LLVivoxVoiceClient::answerInvite(std::string &sessionHandle)
return false;
}
-BOOL LLVivoxVoiceClient::isOnlineSIP(const LLUUID &id)
-{
- bool result = false;
- buddyListEntry *buddy = findBuddy(id);
- if(buddy)
- {
- result = buddy->mOnlineSLim;
- LL_DEBUGS("Voice") << "Buddy " << buddy->mDisplayName << " is SIP " << (result?"online":"offline") << LL_ENDL;
- }
-
- if(!result)
- {
- // This user isn't on the buddy list or doesn't show online status through the buddy list, but could be a participant in an existing session if they initiated a text IM.
- sessionState *session = findSession(id);
- if(session && !session->mHandle.empty())
- {
- if((session->mTextStreamState != streamStateUnknown) || (session->mMediaStreamState > streamStateIdle))
- {
- LL_DEBUGS("Voice") << "Open session with " << id << " found, returning SIP online state" << LL_ENDL;
- // we have a p2p text session open with this user, so by definition they're online.
- result = true;
- }
- }
- }
-
- return result;
-}
-
bool LLVivoxVoiceClient::isVoiceWorking() const
{
//Added stateSessionTerminated state to avoid problems with call in parcels with disabled voice (EXT-4758)
@@ -4894,7 +4278,7 @@ BOOL LLVivoxVoiceClient::isSessionCallBackPossible(const LLUUID &session_id)
// Currently this will be false only for PSTN P2P calls.
BOOL LLVivoxVoiceClient::isSessionTextIMPossible(const LLUUID &session_id)
{
- bool result = TRUE;
+ bool result = TRUE;
sessionState *session = findSession(session_id);
if(session != NULL)
@@ -5943,229 +5327,6 @@ void LLVivoxVoiceClient::verifySessionState(void)
}
}
-LLVivoxVoiceClient::buddyListEntry::buddyListEntry(const std::string &uri) :
- mURI(uri)
-{
- mOnlineSL = false;
- mOnlineSLim = false;
- mCanSeeMeOnline = true;
- mHasBlockListEntry = false;
- mHasAutoAcceptListEntry = false;
- mNameResolved = false;
- mInVivoxBuddies = false;
- mInSLFriends = false;
- mNeedsNameUpdate = false;
-}
-
-void LLVivoxVoiceClient::processBuddyListEntry(const std::string &uri, const std::string &displayName)
-{
- buddyListEntry *buddy = addBuddy(uri, displayName);
- buddy->mInVivoxBuddies = true;
-}
-
-LLVivoxVoiceClient::buddyListEntry *LLVivoxVoiceClient::addBuddy(const std::string &uri)
-{
- std::string empty;
- buddyListEntry *buddy = addBuddy(uri, empty);
- if(buddy->mDisplayName.empty())
- {
- buddy->mNameResolved = false;
- }
- return buddy;
-}
-
-LLVivoxVoiceClient::buddyListEntry *LLVivoxVoiceClient::addBuddy(const std::string &uri, const std::string &displayName)
-{
- buddyListEntry *result = NULL;
- buddyListMap::iterator iter = mBuddyListMap.find(uri);
-
- if(iter != mBuddyListMap.end())
- {
- // Found a matching buddy already in the map.
- LL_DEBUGS("Voice") << "adding existing buddy " << uri << LL_ENDL;
- result = iter->second;
- }
-
- if(!result)
- {
- // participant isn't already in one list or the other.
- LL_DEBUGS("Voice") << "adding new buddy " << uri << LL_ENDL;
- result = new buddyListEntry(uri);
- result->mDisplayName = displayName;
-
- if(IDFromName(uri, result->mUUID))
- {
- // Extracted UUID from name successfully.
- }
- else
- {
- LL_DEBUGS("Voice") << "Couldn't find ID for buddy " << uri << " (\"" << displayName << "\")" << LL_ENDL;
- }
-
- mBuddyListMap.insert(buddyListMap::value_type(result->mURI, result));
- }
-
- return result;
-}
-
-LLVivoxVoiceClient::buddyListEntry *LLVivoxVoiceClient::findBuddy(const std::string &uri)
-{
- buddyListEntry *result = NULL;
- buddyListMap::iterator iter = mBuddyListMap.find(uri);
- if(iter != mBuddyListMap.end())
- {
- result = iter->second;
- }
-
- return result;
-}
-
-LLVivoxVoiceClient::buddyListEntry *LLVivoxVoiceClient::findBuddy(const LLUUID &id)
-{
- buddyListEntry *result = NULL;
- buddyListMap::iterator iter;
-
- for(iter = mBuddyListMap.begin(); iter != mBuddyListMap.end(); iter++)
- {
- if(iter->second->mUUID == id)
- {
- result = iter->second;
- break;
- }
- }
-
- return result;
-}
-
-LLVivoxVoiceClient::buddyListEntry *LLVivoxVoiceClient::findBuddyByDisplayName(const std::string &name)
-{
- buddyListEntry *result = NULL;
- buddyListMap::iterator iter;
-
- for(iter = mBuddyListMap.begin(); iter != mBuddyListMap.end(); iter++)
- {
- if(iter->second->mDisplayName == name)
- {
- result = iter->second;
- break;
- }
- }
-
- return result;
-}
-
-void LLVivoxVoiceClient::deleteBuddy(const std::string &uri)
-{
- buddyListMap::iterator iter = mBuddyListMap.find(uri);
- if(iter != mBuddyListMap.end())
- {
- LL_DEBUGS("Voice") << "deleting buddy " << uri << LL_ENDL;
- buddyListEntry *buddy = iter->second;
- mBuddyListMap.erase(iter);
- delete buddy;
- }
- else
- {
- LL_DEBUGS("Voice") << "attempt to delete nonexistent buddy " << uri << LL_ENDL;
- }
-
-}
-
-void LLVivoxVoiceClient::deleteAllBuddies(void)
-{
- while(!mBuddyListMap.empty())
- {
- deleteBuddy(mBuddyListMap.begin()->first);
- }
-
- // Don't want to correlate with friends list when we've emptied the buddy list.
- mBuddyListMapPopulated = false;
-
- // Don't want to correlate with friends list when we've reset the block rules.
- mBlockRulesListReceived = false;
- mAutoAcceptRulesListReceived = false;
-}
-
-void LLVivoxVoiceClient::deleteAllBlockRules(void)
-{
- // Clear the block list entry flags from all local buddy list entries
- buddyListMap::iterator buddy_it;
- for(buddy_it = mBuddyListMap.begin(); buddy_it != mBuddyListMap.end(); buddy_it++)
- {
- buddy_it->second->mHasBlockListEntry = false;
- }
-}
-
-void LLVivoxVoiceClient::deleteAllAutoAcceptRules(void)
-{
- // Clear the auto-accept list entry flags from all local buddy list entries
- buddyListMap::iterator buddy_it;
- for(buddy_it = mBuddyListMap.begin(); buddy_it != mBuddyListMap.end(); buddy_it++)
- {
- buddy_it->second->mHasAutoAcceptListEntry = false;
- }
-}
-
-void LLVivoxVoiceClient::addBlockRule(const std::string &blockMask, const std::string &presenceOnly)
-{
- buddyListEntry *buddy = NULL;
-
- // blockMask is the SIP URI of a friends list entry
- buddyListMap::iterator iter = mBuddyListMap.find(blockMask);
- if(iter != mBuddyListMap.end())
- {
- LL_DEBUGS("Voice") << "block list entry for " << blockMask << LL_ENDL;
- buddy = iter->second;
- }
-
- if(buddy == NULL)
- {
- LL_DEBUGS("Voice") << "block list entry for unknown buddy " << blockMask << LL_ENDL;
- buddy = addBuddy(blockMask);
- }
-
- if(buddy != NULL)
- {
- buddy->mHasBlockListEntry = true;
- }
-}
-
-void LLVivoxVoiceClient::addAutoAcceptRule(const std::string &autoAcceptMask, const std::string &autoAddAsBuddy)
-{
- buddyListEntry *buddy = NULL;
-
- // blockMask is the SIP URI of a friends list entry
- buddyListMap::iterator iter = mBuddyListMap.find(autoAcceptMask);
- if(iter != mBuddyListMap.end())
- {
- LL_DEBUGS("Voice") << "auto-accept list entry for " << autoAcceptMask << LL_ENDL;
- buddy = iter->second;
- }
-
- if(buddy == NULL)
- {
- LL_DEBUGS("Voice") << "auto-accept list entry for unknown buddy " << autoAcceptMask << LL_ENDL;
- buddy = addBuddy(autoAcceptMask);
- }
-
- if(buddy != NULL)
- {
- buddy->mHasAutoAcceptListEntry = true;
- }
-}
-
-void LLVivoxVoiceClient::accountListBlockRulesResponse(int statusCode, const std::string &statusString)
-{
- // Block list entries were updated via addBlockRule() during parsing. Just flag that we're done.
- mBlockRulesListReceived = true;
-}
-
-void LLVivoxVoiceClient::accountListAutoAcceptRulesResponse(int statusCode, const std::string &statusString)
-{
- // Block list entries were updated via addBlockRule() during parsing. Just flag that we're done.
- mAutoAcceptRulesListReceived = true;
-}
-
void LLVivoxVoiceClient::addObserver(LLVoiceClientParticipantObserver* observer)
{
mParticipantObservers.insert(observer);
@@ -6297,27 +5458,23 @@ void LLVivoxVoiceClient::notifyFriendObservers()
void LLVivoxVoiceClient::lookupName(const LLUUID &id)
{
- LLAvatarNameCache::get(id,
- boost::bind(&LLVivoxVoiceClient::onAvatarNameCache,
- this, _1, _2));
+ if (mAvatarNameCacheConnection.connected())
+ {
+ mAvatarNameCacheConnection.disconnect();
+ }
+ mAvatarNameCacheConnection = LLAvatarNameCache::get(id, boost::bind(&LLVivoxVoiceClient::onAvatarNameCache, this, _1, _2));
}
void LLVivoxVoiceClient::onAvatarNameCache(const LLUUID& agent_id,
const LLAvatarName& av_name)
{
- // For Vivox, we use the legacy name because I'm uncertain whether or
- // not their service can tolerate switching to Username or Display Name
- std::string legacy_name = av_name.getLegacyName();
- avatarNameResolved(agent_id, legacy_name);
+ mAvatarNameCacheConnection.disconnect();
+ std::string display_name = av_name.getDisplayName();
+ avatarNameResolved(agent_id, display_name);
}
void LLVivoxVoiceClient::avatarNameResolved(const LLUUID &id, const std::string &name)
{
- // If the avatar whose name just resolved is on our friends list, resync the friends list.
- if(LLAvatarTracker::instance().getBuddyInfo(id) != NULL)
- {
- mFriendsListDirty = true;
- }
// Iterate over all sessions.
for(sessionIterator iter = sessionsBegin(); iter != sessionsEnd(); iter++)
{
@@ -6837,10 +5994,105 @@ void LLVivoxVoiceClient::removeObserver(LLVoiceEffectObserver* observer)
mVoiceFontObservers.erase(observer);
}
+// method checks the item in VoiceMorphing menu for appropriate current voice font
+bool LLVivoxVoiceClient::onCheckVoiceEffect(const std::string& voice_effect_name)
+{
+ LLVoiceEffectInterface * effect_interfacep = LLVoiceClient::instance().getVoiceEffectInterface();
+ if (NULL != effect_interfacep)
+ {
+ const LLUUID& currect_voice_effect_id = effect_interfacep->getVoiceEffect();
+
+ if (currect_voice_effect_id.isNull())
+ {
+ if (voice_effect_name == "NoVoiceMorphing")
+ {
+ return true;
+ }
+ }
+ else
+ {
+ const LLSD& voice_effect_props = effect_interfacep->getVoiceEffectProperties(currect_voice_effect_id);
+ if (voice_effect_props["name"].asString() == voice_effect_name)
+ {
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+// method changes voice font for selected VoiceMorphing menu item
+void LLVivoxVoiceClient::onClickVoiceEffect(const std::string& voice_effect_name)
+{
+ LLVoiceEffectInterface * effect_interfacep = LLVoiceClient::instance().getVoiceEffectInterface();
+ if (NULL != effect_interfacep)
+ {
+ if (voice_effect_name == "NoVoiceMorphing")
+ {
+ effect_interfacep->setVoiceEffect(LLUUID());
+ return;
+ }
+ const voice_effect_list_t& effect_list = effect_interfacep->getVoiceEffectList();
+ if (!effect_list.empty())
+ {
+ for (voice_effect_list_t::const_iterator it = effect_list.begin(); it != effect_list.end(); ++it)
+ {
+ if (voice_effect_name == it->first)
+ {
+ effect_interfacep->setVoiceEffect(it->second);
+ return;
+ }
+ }
+ }
+ }
+}
+
+// it updates VoiceMorphing menu items in accordance with purchased properties
+void LLVivoxVoiceClient::updateVoiceMorphingMenu()
+{
+ if (mVoiceFontListDirty)
+ {
+ LLVoiceEffectInterface * effect_interfacep = LLVoiceClient::instance().getVoiceEffectInterface();
+ if (effect_interfacep)
+ {
+ const voice_effect_list_t& effect_list = effect_interfacep->getVoiceEffectList();
+ if (!effect_list.empty())
+ {
+ LLMenuGL * voice_morphing_menup = gMenuBarView->findChildMenuByName("VoiceMorphing", TRUE);
+
+ if (NULL != voice_morphing_menup)
+ {
+ S32 items = voice_morphing_menup->getItemCount();
+ if (items > 0)
+ {
+ voice_morphing_menup->erase(1, items - 3, false);
+
+ S32 pos = 1;
+ for (voice_effect_list_t::const_iterator it = effect_list.begin(); it != effect_list.end(); ++it)
+ {
+ LLMenuItemCheckGL::Params p;
+ p.name = it->first;
+ p.label = it->first;
+ p.on_check.function(boost::bind(&LLVivoxVoiceClient::onCheckVoiceEffect, this, it->first));
+ p.on_click.function(boost::bind(&LLVivoxVoiceClient::onClickVoiceEffect, this, it->first));
+ LLMenuItemCheckGL * voice_effect_itemp = LLUICtrlFactory::create<LLMenuItemCheckGL>(p);
+ voice_morphing_menup->insert(pos++, voice_effect_itemp, false);
+ }
+
+ voice_morphing_menup->needsArrange();
+ }
+ }
+ }
+ }
+ }
+}
void LLVivoxVoiceClient::notifyVoiceFontObservers()
{
LL_DEBUGS("Voice") << "Notifying voice effect observers. Lists changed: " << mVoiceFontListDirty << LL_ENDL;
+ updateVoiceMorphingMenu();
+
for (voice_font_observer_set_t::iterator it = mVoiceFontObservers.begin();
it != mVoiceFontObservers.end();
)
@@ -7224,18 +6476,6 @@ void LLVivoxProtocolParser::StartTag(const char *tag, const char **attr)
{
deviceString.clear();
}
- else if (!stricmp("Buddies", tag))
- {
- LLVivoxVoiceClient::getInstance()->deleteAllBuddies();
- }
- else if (!stricmp("BlockRules", tag))
- {
- LLVivoxVoiceClient::getInstance()->deleteAllBlockRules();
- }
- else if (!stricmp("AutoAcceptRules", tag))
- {
- LLVivoxVoiceClient::getInstance()->deleteAllAutoAcceptRules();
- }
else if (!stricmp("SessionFont", tag))
{
id = 0;
@@ -7367,22 +6607,10 @@ void LLVivoxProtocolParser::EndTag(const char *tag)
{
LLVivoxVoiceClient::getInstance()->addRenderDevice(deviceString);
}
- else if (!stricmp("Buddy", tag))
- {
- LLVivoxVoiceClient::getInstance()->processBuddyListEntry(uriString, displayNameString);
- }
- else if (!stricmp("BlockRule", tag))
- {
- LLVivoxVoiceClient::getInstance()->addBlockRule(blockMask, presenceOnly);
- }
else if (!stricmp("BlockMask", tag))
blockMask = string;
else if (!stricmp("PresenceOnly", tag))
presenceOnly = string;
- else if (!stricmp("AutoAcceptRule", tag))
- {
- LLVivoxVoiceClient::getInstance()->addAutoAcceptRule(autoAcceptMask, autoAddAsBuddy);
- }
else if (!stricmp("AutoAcceptMask", tag))
autoAcceptMask = string;
else if (!stricmp("AutoAddAsBuddy", tag))
@@ -7614,16 +6842,6 @@ void LLVivoxProtocolParser::processResponse(std::string tag)
LLVivoxVoiceClient::getInstance()->auxAudioPropertiesEvent(energy);
}
- else if (!stricmp(eventTypeCstr, "BuddyPresenceEvent"))
- {
- LLVivoxVoiceClient::getInstance()->buddyPresenceEvent(uriString, alias, statusString, applicationString);
- }
- else if (!stricmp(eventTypeCstr, "BuddyAndGroupListChangedEvent"))
- {
- // The buddy list was updated during parsing.
- // Need to recheck against the friends list.
- LLVivoxVoiceClient::getInstance()->buddyListChanged();
- }
else if (!stricmp(eventTypeCstr, "BuddyChangedEvent"))
{
/*
@@ -7646,11 +6864,7 @@ void LLVivoxProtocolParser::processResponse(std::string tag)
{
LLVivoxVoiceClient::getInstance()->sessionNotificationEvent(sessionHandle, uriString, notificationType);
}
- else if (!stricmp(eventTypeCstr, "SubscriptionEvent"))
- {
- LLVivoxVoiceClient::getInstance()->subscriptionEvent(uriString, subscriptionHandle, alias, displayNameString, applicationString, subscriptionType);
- }
- else if (!stricmp(eventTypeCstr, "SessionUpdatedEvent"))
+ else if (!stricmp(eventTypeCstr, "SessionUpdatedEvent"))
{
/*
<Event type="SessionUpdatedEvent">
@@ -7677,6 +6891,9 @@ void LLVivoxProtocolParser::processResponse(std::string tag)
*/
// We don't need to process this, but we also shouldn't warn on it, since that confuses people.
}
+ else if (!stricmp(eventTypeCstr, "VoiceServiceConnectionStateChangedEvent"))
+ { // Yet another ignored event
+ }
else
{
LL_WARNS("VivoxProtocolParser") << "Unknown event type " << eventTypeString << LL_ENDL;
@@ -7713,14 +6930,6 @@ void LLVivoxProtocolParser::processResponse(std::string tag)
{
LLVivoxVoiceClient::getInstance()->connectorShutdownResponse(statusCode, statusString);
}
- else if (!stricmp(actionCstr, "Account.ListBlockRules.1"))
- {
- LLVivoxVoiceClient::getInstance()->accountListBlockRulesResponse(statusCode, statusString);
- }
- else if (!stricmp(actionCstr, "Account.ListAutoAcceptRules.1"))
- {
- LLVivoxVoiceClient::getInstance()->accountListAutoAcceptRulesResponse(statusCode, statusString);
- }
else if (!stricmp(actionCstr, "Session.Set3DPosition.1"))
{
// We don't need to process these, but they're so spammy we don't want to log them.
diff --git a/indra/newview/llvoicevivox.h b/indra/newview/llvoicevivox.h
index 1142a1a49c..e2d1585c15 100644..100755
--- a/indra/newview/llvoicevivox.h
+++ b/indra/newview/llvoicevivox.h
@@ -48,7 +48,6 @@ class LLVivoxProtocolParser;
class LLAvatarName;
class LLVivoxVoiceAccountProvisionResponder;
class LLVivoxVoiceClientMuteListObserver;
-class LLVivoxVoiceClientFriendsObserver;
class LLVivoxVoiceClient : public LLSingleton<LLVivoxVoiceClient>,
@@ -181,7 +180,6 @@ public:
//@{
virtual BOOL getVoiceEnabled(const LLUUID& id); // true if we've received data for this avatar
virtual std::string getDisplayName(const LLUUID& id);
- virtual BOOL isOnlineSIP(const LLUUID &id);
virtual BOOL isParticipantAvatar(const LLUUID &id);
virtual BOOL getIsSpeaking(const LLUUID& id);
virtual BOOL getIsModeratorMuted(const LLUUID& id);
@@ -246,6 +244,8 @@ public:
//@}
+ bool onCheckVoiceEffect(const std::string& voice_effect_name);
+ void onClickVoiceEffect(const std::string& voice_effect_name);
protected:
//////////////////////
@@ -488,14 +488,10 @@ protected:
void participantRemovedEvent(std::string &sessionHandle, std::string &sessionGroupHandle, std::string &uriString, std::string &alias, std::string &nameString);
void participantUpdatedEvent(std::string &sessionHandle, std::string &sessionGroupHandle, std::string &uriString, std::string &alias, bool isModeratorMuted, bool isSpeaking, int volume, F32 energy);
void auxAudioPropertiesEvent(F32 energy);
- void buddyPresenceEvent(std::string &uriString, std::string &alias, std::string &statusString, std::string &applicationString);
void messageEvent(std::string &sessionHandle, std::string &uriString, std::string &alias, std::string &messageHeader, std::string &messageBody, std::string &applicationString);
void sessionNotificationEvent(std::string &sessionHandle, std::string &uriString, std::string &notificationType);
- void subscriptionEvent(std::string &buddyURI, std::string &subscriptionHandle, std::string &alias, std::string &displayName, std::string &applicationString, std::string &subscriptionType);
- void buddyListChanged();
void muteListChanged();
- void updateFriends(U32 mask);
/////////////////////////////
// Sending updates of current state
@@ -582,29 +578,10 @@ protected:
bool mNameResolved;
bool mInSLFriends;
bool mInVivoxBuddies;
- bool mNeedsNameUpdate;
};
typedef std::map<std::string, buddyListEntry*> buddyListMap;
- // This should be called when parsing a buddy list entry sent by SLVoice.
- void processBuddyListEntry(const std::string &uri, const std::string &displayName);
-
- buddyListEntry *addBuddy(const std::string &uri);
- buddyListEntry *addBuddy(const std::string &uri, const std::string &displayName);
- buddyListEntry *findBuddy(const std::string &uri);
- buddyListEntry *findBuddy(const LLUUID &id);
- buddyListEntry *findBuddyByDisplayName(const std::string &name);
- void deleteBuddy(const std::string &uri);
- void deleteAllBuddies(void);
-
- void deleteAllBlockRules(void);
- void addBlockRule(const std::string &blockMask, const std::string &presenceOnly);
- void deleteAllAutoAcceptRules(void);
- void addAutoAcceptRule(const std::string &autoAcceptMask, const std::string &autoAddAsBuddy);
- void accountListBlockRulesResponse(int statusCode, const std::string &statusString);
- void accountListAutoAcceptRulesResponse(int statusCode, const std::string &statusString);
-
/////////////////////////////
// session control messages
@@ -641,6 +618,7 @@ protected:
void lookupName(const LLUUID &id);
void onAvatarNameCache(const LLUUID& id, const LLAvatarName& av_name);
void avatarNameResolved(const LLUUID &id, const std::string &name);
+ boost::signals2::connection mAvatarNameCacheConnection;
/////////////////////////////
// Voice fonts
@@ -741,6 +719,8 @@ private:
std::string mRenderDevice;
bool mCaptureDeviceDirty;
bool mRenderDeviceDirty;
+
+ bool mIsInitialized;
bool checkParcelChanged(bool update = false);
@@ -770,8 +750,7 @@ private:
void buildSetCaptureDevice(std::ostringstream &stream);
void buildSetRenderDevice(std::ostringstream &stream);
- void clearAllLists();
- void checkFriend(const LLUUID& id);
+
void sendFriendsListUpdates();
// start a text IM session with the specified user
@@ -851,6 +830,7 @@ private:
void accountGetTemplateFontsSendMessage();
void sessionSetVoiceFontSendMessage(sessionState *session);
+ void updateVoiceMorphingMenu();
void notifyVoiceFontObservers();
typedef enum e_voice_font_type
diff --git a/indra/newview/llvoinventorylistener.cpp b/indra/newview/llvoinventorylistener.cpp
index 1ea90c6a98..1ea90c6a98 100644..100755
--- a/indra/newview/llvoinventorylistener.cpp
+++ b/indra/newview/llvoinventorylistener.cpp
diff --git a/indra/newview/llvoinventorylistener.h b/indra/newview/llvoinventorylistener.h
index bf14d19b01..bf14d19b01 100644..100755
--- a/indra/newview/llvoinventorylistener.h
+++ b/indra/newview/llvoinventorylistener.h
diff --git a/indra/newview/llvopartgroup.cpp b/indra/newview/llvopartgroup.cpp
index 5c10a80b07..9f4f11b317 100644..100755
--- a/indra/newview/llvopartgroup.cpp
+++ b/indra/newview/llvopartgroup.cpp
@@ -48,6 +48,113 @@ const F32 MAX_PART_LIFETIME = 120.f;
extern U64 gFrameTime;
+LLPointer<LLVertexBuffer> LLVOPartGroup::sVB = NULL;
+S32 LLVOPartGroup::sVBSlotCursor = 0;
+
+void LLVOPartGroup::initClass()
+{
+
+}
+
+//static
+void LLVOPartGroup::restoreGL()
+{
+
+ //TODO: optimize out binormal mask here. Specular and normal coords as well.
+ sVB = new LLVertexBuffer(VERTEX_DATA_MASK | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2, GL_STREAM_DRAW_ARB);
+ U32 count = LL_MAX_PARTICLE_COUNT;
+ sVB->allocateBuffer(count*4, count*6, true);
+
+ //indices and texcoords are always the same, set once
+ LLStrider<U16> indicesp;
+
+ LLStrider<LLVector4a> verticesp;
+
+ sVB->getIndexStrider(indicesp);
+ sVB->getVertexStrider(verticesp);
+
+ LLVector4a v;
+ v.set(0,0,0,0);
+
+
+ U16 vert_offset = 0;
+
+ for (U32 i = 0; i < LL_MAX_PARTICLE_COUNT; i++)
+ {
+ *indicesp++ = vert_offset + 0;
+ *indicesp++ = vert_offset + 1;
+ *indicesp++ = vert_offset + 2;
+
+ *indicesp++ = vert_offset + 1;
+ *indicesp++ = vert_offset + 3;
+ *indicesp++ = vert_offset + 2;
+
+ *verticesp++ = v;
+
+ vert_offset += 4;
+ }
+
+ LLStrider<LLVector2> texcoordsp;
+ sVB->getTexCoord0Strider(texcoordsp);
+
+ for (U32 i = 0; i < LL_MAX_PARTICLE_COUNT; i++)
+ {
+ *texcoordsp++ = LLVector2(0.f, 1.f);
+ *texcoordsp++ = LLVector2(0.f, 0.f);
+ *texcoordsp++ = LLVector2(1.f, 1.f);
+ *texcoordsp++ = LLVector2(1.f, 0.f);
+ }
+
+ sVB->flush();
+
+}
+
+//static
+void LLVOPartGroup::destroyGL()
+{
+ sVB = NULL;
+}
+
+//static
+S32 LLVOPartGroup::findAvailableVBSlot()
+{
+ if (sVBSlotCursor >= LL_MAX_PARTICLE_COUNT)
+ { //no more available slots
+ return -1;
+ }
+
+ return sVBSlotCursor++;
+}
+
+bool ll_is_part_idx_allocated(S32 idx, S32* start, S32* end)
+{
+ /*while (start < end)
+ {
+ if (*start == idx)
+ { //not allocated (in free list)
+ return false;
+ }
+ ++start;
+ }*/
+
+ //allocated (not in free list)
+ return false;
+}
+
+//static
+void LLVOPartGroup::freeVBSlot(S32 idx)
+{
+ /*llassert(idx < LL_MAX_PARTICLE_COUNT && idx >= 0);
+ //llassert(sVBSlotCursor > sVBSlotFree);
+ //llassert(ll_is_part_idx_allocated(idx, sVBSlotCursor, sVBSlotFree+LL_MAX_PARTICLE_COUNT));
+
+ if (sVBSlotCursor > sVBSlotFree)
+ {
+ sVBSlotCursor--;
+ *sVBSlotCursor = idx;
+ }*/
+}
+
LLVOPartGroup::LLVOPartGroup(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp)
: LLAlphaObject(id, pcode, regionp),
mViewerPartGroupp(NULL)
@@ -62,7 +169,6 @@ LLVOPartGroup::~LLVOPartGroup()
{
}
-
BOOL LLVOPartGroup::isActive() const
{
return FALSE;
@@ -70,22 +176,32 @@ BOOL LLVOPartGroup::isActive() const
F32 LLVOPartGroup::getBinRadius()
{
- return mScale.mV[0]*2.f;
+ return mViewerPartGroupp->getBoxSide();
}
void LLVOPartGroup::updateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax)
{
const LLVector3& pos_agent = getPositionAgent();
- newMin.load3( (pos_agent - mScale).mV);
- newMax.load3( (pos_agent + mScale).mV);
- LLVector4a pos;
- pos.load3(pos_agent.mV);
- mDrawable->setPositionGroup(pos);
+
+ LLVector4a scale;
+ LLVector4a p;
+
+ p.load3(pos_agent.mV);
+
+ scale.splat(mScale.mV[0]+mViewerPartGroupp->getBoxSide()*0.5f);
+
+ newMin.setSub(p, scale);
+ newMax.setAdd(p,scale);
+
+ llassert(newMin.isFinite3());
+ llassert(newMax.isFinite3());
+
+ llassert(p.isFinite3());
+ mDrawable->setPositionGroup(p);
}
-BOOL LLVOPartGroup::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
+void LLVOPartGroup::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
{
- return TRUE;
}
void LLVOPartGroup::setPixelAreaAndAngle(LLAgent &agent)
@@ -120,6 +236,37 @@ LLDrawable* LLVOPartGroup::createDrawable(LLPipeline *pipeline)
const F32 MAX_PARTICLE_AREA_SCALE = 0.02f; // some tuned constant, limits on how much particle area to draw
+ LLUUID LLVOPartGroup::getPartOwner(S32 idx)
+ {
+ LLUUID ret = LLUUID::null;
+
+ if (idx < (S32) mViewerPartGroupp->mParticles.size())
+ {
+ ret = mViewerPartGroupp->mParticles[idx]->mPartSourcep->getOwnerUUID();
+ }
+
+ return ret;
+ }
+
+ LLUUID LLVOPartGroup::getPartSource(S32 idx)
+ {
+ LLUUID ret = LLUUID::null;
+
+ if (idx < (S32) mViewerPartGroupp->mParticles.size())
+ {
+ LLViewerPart* part = mViewerPartGroupp->mParticles[idx];
+ if (part && part->mPartSourcep.notNull() &&
+ part->mPartSourcep->mSourceObjectp.notNull())
+ {
+ LLViewerObject* source = part->mPartSourcep->mSourceObjectp;
+ ret = source->getID();
+ }
+ }
+
+ return ret;
+ }
+
+
F32 LLVOPartGroup::getPartSize(S32 idx)
{
if (idx < (S32) mViewerPartGroupp->mParticles.size())
@@ -130,6 +277,16 @@ F32 LLVOPartGroup::getPartSize(S32 idx)
return 0.f;
}
+void LLVOPartGroup::getBlendFunc(S32 idx, U32& src, U32& dst)
+{
+ if (idx < (S32) mViewerPartGroupp->mParticles.size())
+ {
+ LLViewerPart* part = mViewerPartGroupp->mParticles[idx];
+ src = part->mBlendFuncSource;
+ dst = part->mBlendFuncDest;
+ }
+}
+
LLVector3 LLVOPartGroup::getCameraPosition() const
{
return gAgentCamera.getCameraPositionAgent();
@@ -189,19 +346,52 @@ BOOL LLVOPartGroup::updateGeometry(LLDrawable *drawable)
mDepth = 0.f;
S32 i = 0 ;
LLVector3 camera_agent = getCameraPosition();
+
+ F32 max_scale = 0.f;
+
+
for (i = 0 ; i < (S32)mViewerPartGroupp->mParticles.size(); i++)
{
const LLViewerPart *part = mViewerPartGroupp->mParticles[i];
+
+ //remember the largest particle
+ max_scale = llmax(max_scale, part->mScale.mV[0], part->mScale.mV[1]);
+
+ if (part->mFlags & LLPartData::LL_PART_RIBBON_MASK)
+ { //include ribbon segment length in scale
+ const LLVector3* pos_agent = NULL;
+ if (part->mParent)
+ {
+ pos_agent = &(part->mParent->mPosAgent);
+ }
+ else if (part->mPartSourcep.notNull())
+ {
+ pos_agent = &(part->mPartSourcep->mPosAgent);
+ }
+
+ if (pos_agent)
+ {
+ F32 dist = (*pos_agent-part->mPosAgent).length();
+
+ max_scale = llmax(max_scale, dist);
+ }
+ }
+
LLVector3 part_pos_agent(part->mPosAgent);
LLVector3 at(part_pos_agent - camera_agent);
+
F32 camera_dist_squared = at.lengthSquared();
F32 inv_camera_dist_squared;
if (camera_dist_squared > 1.f)
inv_camera_dist_squared = 1.f / camera_dist_squared;
else
inv_camera_dist_squared = 1.f;
+
+ llassert(llfinite(inv_camera_dist_squared));
+ llassert(!llisnan(inv_camera_dist_squared));
+
F32 area = part->mScale.mV[0] * part->mScale.mV[1] * inv_camera_dist_squared;
tot_area = llmax(tot_area, area);
@@ -268,126 +458,263 @@ BOOL LLVOPartGroup::updateGeometry(LLDrawable *drawable)
facep->setSize(0, 0);
}
+ //record max scale (used to stretch bounding box for visibility culling)
+
+ mScale.set(max_scale, max_scale, max_scale);
+
mDrawable->movePartition();
LLPipeline::sCompiles++;
return TRUE;
}
-void LLVOPartGroup::getGeometry(S32 idx,
- LLStrider<LLVector4a>& verticesp,
- LLStrider<LLVector3>& normalsp,
- LLStrider<LLVector2>& texcoordsp,
- LLStrider<LLColor4U>& colorsp,
- LLStrider<U16>& indicesp)
+
+BOOL LLVOPartGroup::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
+ S32 face,
+ BOOL pick_transparent,
+ S32* face_hit,
+ LLVector4a* intersection,
+ LLVector2* tex_coord,
+ LLVector4a* normal,
+ LLVector4a* bi_normal)
{
- if (idx >= (S32) mViewerPartGroupp->mParticles.size())
+ LLVector4a dir;
+ dir.setSub(end, start);
+
+ F32 closest_t = 2.f;
+ BOOL ret = FALSE;
+
+ for (U32 idx = 0; idx < mViewerPartGroupp->mParticles.size(); ++idx)
{
- return;
+ const LLViewerPart &part = *((LLViewerPart*) (mViewerPartGroupp->mParticles[idx]));
+
+ LLVector4a v[4];
+ LLStrider<LLVector4a> verticesp;
+ verticesp = v;
+
+ getGeometry(part, verticesp);
+
+ F32 a,b,t;
+ if (LLTriangleRayIntersect(v[0], v[1], v[2], start, dir, a,b,t) ||
+ LLTriangleRayIntersect(v[1], v[3], v[2], start, dir, a,b,t))
+ {
+ if (t >= 0.f &&
+ t <= 1.f &&
+ t < closest_t)
+ {
+ ret = TRUE;
+ closest_t = t;
+ if (face_hit)
+ {
+ *face_hit = idx;
+ }
+
+ if (intersection)
+ {
+ LLVector4a intersect = dir;
+ intersect.mul(closest_t);
+ intersection->setAdd(intersect, start);
+ }
+ }
+ }
}
- const LLViewerPart &part = *((LLViewerPart*) (mViewerPartGroupp->mParticles[idx]));
+ return ret;
+}
+
+void LLVOPartGroup::getGeometry(const LLViewerPart& part,
+ LLStrider<LLVector4a>& verticesp)
+{
+ if (part.mFlags & LLPartData::LL_PART_RIBBON_MASK)
+ {
+ LLVector4a axis, pos, paxis, ppos;
+ F32 scale, pscale;
+
+ pos.load3(part.mPosAgent.mV);
+ axis.load3(part.mAxis.mV);
+ scale = part.mScale.mV[0];
+
+ if (part.mParent)
+ {
+ ppos.load3(part.mParent->mPosAgent.mV);
+ paxis.load3(part.mParent->mAxis.mV);
+ pscale = part.mParent->mScale.mV[0];
+ }
+ else
+ { //use source object as position
+
+ if (part.mPartSourcep->mSourceObjectp.notNull())
+ {
+ LLVector3 v = LLVector3(0,0,1);
+ v *= part.mPartSourcep->mSourceObjectp->getRenderRotation();
+ paxis.load3(v.mV);
+ ppos.load3(part.mPartSourcep->mPosAgent.mV);
+ pscale = part.mStartScale.mV[0];
+ }
+ else
+ { //no source object, no parent, nothing to draw
+ ppos = pos;
+ pscale = scale;
+ paxis = axis;
+ }
+ }
- U32 vert_offset = mDrawable->getFace(idx)->getGeomIndex();
+ LLVector4a p0, p1, p2, p3;
-
- LLVector4a part_pos_agent;
- part_pos_agent.load3(part.mPosAgent.mV);
- LLVector4a camera_agent;
- camera_agent.load3(getCameraPosition().mV);
- LLVector4a at;
- at.setSub(part_pos_agent, camera_agent);
- LLVector4a up(0, 0, 1);
- LLVector4a right;
-
- right.setCross3(at, up);
- right.normalize3fast();
- up.setCross3(right, at);
- up.normalize3fast();
-
- if (part.mFlags & LLPartData::LL_PART_FOLLOW_VELOCITY_MASK)
+ scale *= 0.5f;
+ pscale *= 0.5f;
+
+ axis.mul(scale);
+ paxis.mul(pscale);
+
+ p0.setAdd(pos, axis);
+ p1.setSub(pos,axis);
+ p2.setAdd(ppos, paxis);
+ p3.setSub(ppos, paxis);
+
+ (*verticesp++) = p2;
+ (*verticesp++) = p3;
+ (*verticesp++) = p0;
+ (*verticesp++) = p1;
+ }
+ else
{
- LLVector4a normvel;
- normvel.load3(part.mVelocity.mV);
- normvel.normalize3fast();
- LLVector2 up_fracs;
- up_fracs.mV[0] = normvel.dot3(right).getF32();
- up_fracs.mV[1] = normvel.dot3(up).getF32();
- up_fracs.normalize();
- LLVector4a new_up;
- LLVector4a new_right;
-
- //new_up = up_fracs.mV[0] * right + up_fracs.mV[1]*up;
- LLVector4a t = right;
- t.mul(up_fracs.mV[0]);
- new_up = up;
- new_up.mul(up_fracs.mV[1]);
- new_up.add(t);
-
- //new_right = up_fracs.mV[1] * right - up_fracs.mV[0]*up;
- t = right;
- t.mul(up_fracs.mV[1]);
- new_right = up;
- new_right.mul(up_fracs.mV[0]);
- t.sub(new_right);
-
- up = new_up;
- right = t;
- up.normalize3fast();
+ LLVector4a part_pos_agent;
+ part_pos_agent.load3(part.mPosAgent.mV);
+ LLVector4a camera_agent;
+ camera_agent.load3(getCameraPosition().mV);
+ LLVector4a at;
+ at.setSub(part_pos_agent, camera_agent);
+ LLVector4a up(0, 0, 1);
+ LLVector4a right;
+
+ right.setCross3(at, up);
right.normalize3fast();
- }
- right.mul(0.5f*part.mScale.mV[0]);
- up.mul(0.5f*part.mScale.mV[1]);
+ up.setCross3(right, at);
+ up.normalize3fast();
+
+ if (part.mFlags & LLPartData::LL_PART_FOLLOW_VELOCITY_MASK)
+ {
+ LLVector4a normvel;
+ normvel.load3(part.mVelocity.mV);
+ normvel.normalize3fast();
+ LLVector2 up_fracs;
+ up_fracs.mV[0] = normvel.dot3(right).getF32();
+ up_fracs.mV[1] = normvel.dot3(up).getF32();
+ up_fracs.normalize();
+ LLVector4a new_up;
+ LLVector4a new_right;
+
+ //new_up = up_fracs.mV[0] * right + up_fracs.mV[1]*up;
+ LLVector4a t = right;
+ t.mul(up_fracs.mV[0]);
+ new_up = up;
+ new_up.mul(up_fracs.mV[1]);
+ new_up.add(t);
+
+ //new_right = up_fracs.mV[1] * right - up_fracs.mV[0]*up;
+ t = right;
+ t.mul(up_fracs.mV[1]);
+ new_right = up;
+ new_right.mul(up_fracs.mV[0]);
+ t.sub(new_right);
+
+ up = new_up;
+ right = t;
+ up.normalize3fast();
+ right.normalize3fast();
+ }
+
+ right.mul(0.5f*part.mScale.mV[0]);
+ up.mul(0.5f*part.mScale.mV[1]);
- LLVector3 normal = -LLViewerCamera::getInstance()->getXAxis();
+ //HACK -- the verticesp->mV[3] = 0.f here are to set the texture index to 0 (particles don't use texture batching, maybe they should)
+ // this works because there is actually a 4th float stored after the vertex position which is used as a texture index
+ // also, somebody please VECTORIZE THIS
- //HACK -- the verticesp->mV[3] = 0.f here are to set the texture index to 0 (particles don't use texture batching, maybe they should)
- // this works because there is actually a 4th float stored after the vertex position which is used as a texture index
- // also, somebody please VECTORIZE THIS
+ LLVector4a ppapu;
+ LLVector4a ppamu;
+
+ ppapu.setAdd(part_pos_agent, up);
+ ppamu.setSub(part_pos_agent, up);
+
+ verticesp->setSub(ppapu, right);
+ (*verticesp++).getF32ptr()[3] = 0.f;
+ verticesp->setSub(ppamu, right);
+ (*verticesp++).getF32ptr()[3] = 0.f;
+ verticesp->setAdd(ppapu, right);
+ (*verticesp++).getF32ptr()[3] = 0.f;
+ verticesp->setAdd(ppamu, right);
+ (*verticesp++).getF32ptr()[3] = 0.f;
+ }
+}
- LLVector4a ppapu;
- LLVector4a ppamu;
- ppapu.setAdd(part_pos_agent, up);
- ppamu.setSub(part_pos_agent, up);
+
+void LLVOPartGroup::getGeometry(S32 idx,
+ LLStrider<LLVector4a>& verticesp,
+ LLStrider<LLVector3>& normalsp,
+ LLStrider<LLVector2>& texcoordsp,
+ LLStrider<LLColor4U>& colorsp,
+ LLStrider<LLColor4U>& emissivep,
+ LLStrider<U16>& indicesp)
+{
+ if (idx >= (S32) mViewerPartGroupp->mParticles.size())
+ {
+ return;
+ }
+
+ const LLViewerPart &part = *((LLViewerPart*) (mViewerPartGroupp->mParticles[idx]));
- verticesp->setSub(ppapu, right);
- (*verticesp++).getF32ptr()[3] = 0.f;
- verticesp->setSub(ppamu, right);
- (*verticesp++).getF32ptr()[3] = 0.f;
- verticesp->setAdd(ppapu, right);
- (*verticesp++).getF32ptr()[3] = 0.f;
- verticesp->setAdd(ppamu, right);
- (*verticesp++).getF32ptr()[3] = 0.f;
+ getGeometry(part, verticesp);
- //*verticesp++ = part_pos_agent + up - right;
- //*verticesp++ = part_pos_agent - up - right;
- //*verticesp++ = part_pos_agent + up + right;
- //*verticesp++ = part_pos_agent - up + right;
+ LLColor4U pcolor;
+ LLColor4U color = part.mColor;
- *colorsp++ = part.mColor;
- *colorsp++ = part.mColor;
- *colorsp++ = part.mColor;
- *colorsp++ = part.mColor;
+ LLColor4U pglow;
- *texcoordsp++ = LLVector2(0.f, 1.f);
- *texcoordsp++ = LLVector2(0.f, 0.f);
- *texcoordsp++ = LLVector2(1.f, 1.f);
- *texcoordsp++ = LLVector2(1.f, 0.f);
+ if (part.mFlags & LLPartData::LL_PART_RIBBON_MASK)
+ { //make sure color blends properly
+ if (part.mParent)
+ {
+ pglow = part.mParent->mGlow;
+ pcolor = part.mParent->mColor;
+ }
+ else
+ {
+ pglow = LLColor4U(0, 0, 0, (U8) llround(255.f*part.mStartGlow));
+ pcolor = part.mStartColor;
+ }
+ }
+ else
+ {
+ pglow = part.mGlow;
+ pcolor = color;
+ }
- *normalsp++ = normal;
- *normalsp++ = normal;
- *normalsp++ = normal;
- *normalsp++ = normal;
+ *colorsp++ = pcolor;
+ *colorsp++ = pcolor;
+ *colorsp++ = color;
+ *colorsp++ = color;
+
+ //if (pglow.mV[3] || part.mGlow.mV[3])
+ { //only write glow if it is not zero
+ *emissivep++ = pglow;
+ *emissivep++ = pglow;
+ *emissivep++ = part.mGlow;
+ *emissivep++ = part.mGlow;
+ }
- *indicesp++ = vert_offset + 0;
- *indicesp++ = vert_offset + 1;
- *indicesp++ = vert_offset + 2;
- *indicesp++ = vert_offset + 1;
- *indicesp++ = vert_offset + 3;
- *indicesp++ = vert_offset + 2;
+ if (!(part.mFlags & LLPartData::LL_PART_EMISSIVE_MASK))
+ { //not fullbright, needs normal
+ LLVector3 normal = -LLViewerCamera::getInstance()->getXAxis();
+ *normalsp++ = normal;
+ *normalsp++ = normal;
+ *normalsp++ = normal;
+ *normalsp++ = normal;
+ }
}
U32 LLVOPartGroup::getPartitionType() const
@@ -412,6 +739,49 @@ LLHUDParticlePartition::LLHUDParticlePartition() :
mPartitionType = LLViewerRegion::PARTITION_HUD_PARTICLE;
}
+static LLFastTimer::DeclareTimer FTM_REBUILD_PARTICLE_VBO("Particle VBO");
+
+void LLParticlePartition::rebuildGeom(LLSpatialGroup* group)
+{
+ if (group->isDead() || !group->isState(LLSpatialGroup::GEOM_DIRTY))
+ {
+ return;
+ }
+
+ if (group->changeLOD())
+ {
+ group->mLastUpdateDistance = group->mDistance;
+ group->mLastUpdateViewAngle = group->mViewAngle;
+ }
+
+ LLFastTimer ftm(FTM_REBUILD_PARTICLE_VBO);
+
+ group->clearDrawMap();
+
+ //get geometry count
+ U32 index_count = 0;
+ U32 vertex_count = 0;
+
+ addGeometryCount(group, vertex_count, index_count);
+
+
+ if (vertex_count > 0 && index_count > 0)
+ {
+ group->mBuilt = 1.f;
+ //use one vertex buffer for all groups
+ group->mVertexBuffer = LLVOPartGroup::sVB;
+ getGeometry(group);
+ }
+ else
+ {
+ group->mVertexBuffer = NULL;
+ group->mBufferMap.clear();
+ }
+
+ group->mLastUpdateTime = gFrameTimeSeconds;
+ group->clearState(LLSpatialGroup::GEOM_DIRTY);
+}
+
void LLParticlePartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_count, U32& index_count)
{
group->mBufferUsage = mBufferUsage;
@@ -419,7 +789,7 @@ void LLParticlePartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_co
mFaceList.clear();
LLViewerCamera* camera = LLViewerCamera::getInstance();
- for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i)
+ for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)
{
LLDrawable* drawablep = *i;
@@ -431,11 +801,6 @@ void LLParticlePartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_co
LLAlphaObject* obj = (LLAlphaObject*) drawablep->getVObj().get();
obj->mDepth = 0.f;
- if (drawablep->isAnimating())
- {
- group->mBufferUsage = GL_STREAM_DRAW_ARB;
- }
-
U32 count = 0;
for (S32 j = 0; j < drawablep->getNumFaces(); ++j)
{
@@ -447,13 +812,14 @@ void LLParticlePartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_co
continue;
}
+ vertex_count += facep->getGeomCount();
+ index_count += facep->getIndicesCount();
+
count++;
facep->mDistance = (facep->mCenterLocal - camera->getOrigin()) * camera->getAtAxis();
obj->mDepth += facep->mDistance;
mFaceList.push_back(facep);
- vertex_count += facep->getGeomCount();
- index_count += facep->getIndicesCount();
llassert(facep->getIndicesCount() < 65536);
}
@@ -461,15 +827,12 @@ void LLParticlePartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_co
}
}
-static LLFastTimer::DeclareTimer FTM_REBUILD_GRASS_VB("Grass VB");
-static LLFastTimer::DeclareTimer FTM_REBUILD_PARTICLE_VB("Particle VB");
+
+static LLFastTimer::DeclareTimer FTM_REBUILD_PARTICLE_GEOM("Particle Geom");
void LLParticlePartition::getGeometry(LLSpatialGroup* group)
{
- LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
- LLFastTimer ftm(mDrawableType == LLPipeline::RENDER_TYPE_GRASS ?
- FTM_REBUILD_GRASS_VB :
- FTM_REBUILD_PARTICLE_VB);
+ LLFastTimer ftm(FTM_REBUILD_PARTICLE_GEOM);
std::sort(mFaceList.begin(), mFaceList.end(), LLFace::CompareDistanceGreater());
@@ -485,25 +848,62 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group)
LLStrider<LLVector3> normalsp;
LLStrider<LLVector2> texcoordsp;
LLStrider<LLColor4U> colorsp;
+ LLStrider<LLColor4U> emissivep;
buffer->getVertexStrider(verticesp);
buffer->getNormalStrider(normalsp);
buffer->getColorStrider(colorsp);
- buffer->getTexCoord0Strider(texcoordsp);
- buffer->getIndexStrider(indicesp);
+ buffer->getEmissiveStrider(emissivep);
+
LLSpatialGroup::drawmap_elem_t& draw_vec = group->mDrawMap[mRenderPass];
for (std::vector<LLFace*>::iterator i = mFaceList.begin(); i != mFaceList.end(); ++i)
{
LLFace* facep = *i;
LLAlphaObject* object = (LLAlphaObject*) facep->getViewerObject();
- facep->setGeomIndex(vertex_count);
- facep->setIndicesIndex(index_count);
- facep->setVertexBuffer(buffer);
- facep->setPoolType(LLDrawPool::POOL_ALPHA);
- object->getGeometry(facep->getTEOffset(), verticesp, normalsp, texcoordsp, colorsp, indicesp);
+
+ //if (!facep->isState(LLFace::PARTICLE))
+ { //set the indices of this face
+ S32 idx = LLVOPartGroup::findAvailableVBSlot();
+ if (idx >= 0)
+ {
+ facep->setGeomIndex(idx*4);
+ facep->setIndicesIndex(idx*6);
+ facep->setVertexBuffer(LLVOPartGroup::sVB);
+ facep->setPoolType(LLDrawPool::POOL_ALPHA);
+ //facep->setState(LLFace::PARTICLE);
+ }
+ else
+ {
+ continue; //out of space in particle buffer
+ }
+ }
+
+ S32 geom_idx = (S32) facep->getGeomIndex();
+
+ LLStrider<U16> cur_idx = indicesp + facep->getIndicesStart();
+ LLStrider<LLVector4a> cur_vert = verticesp + geom_idx;
+ LLStrider<LLVector3> cur_norm = normalsp + geom_idx;
+ LLStrider<LLVector2> cur_tc = texcoordsp + geom_idx;
+ LLStrider<LLColor4U> cur_col = colorsp + geom_idx;
+ LLStrider<LLColor4U> cur_glow = emissivep + geom_idx;
+
+ LLColor4U* start_glow = cur_glow.get();
+
+ object->getGeometry(facep->getTEOffset(), cur_vert, cur_norm, cur_tc, cur_col, cur_glow, cur_idx);
+ BOOL has_glow = FALSE;
+
+ if (cur_glow.get() != start_glow)
+ {
+ has_glow = TRUE;
+ }
+
+ llassert(facep->getGeomCount() == 4);
+ llassert(facep->getIndicesCount() == 6);
+
+
vertex_count += facep->getGeomCount();
index_count += facep->getIndicesCount();
@@ -512,18 +912,44 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group)
BOOL fullbright = facep->isState(LLFace::FULLBRIGHT);
F32 vsize = facep->getVirtualSize();
- if (idx >= 0 && draw_vec[idx]->mEnd == facep->getGeomIndex()-1 &&
- draw_vec[idx]->mTexture == facep->getTexture() &&
- (U16) (draw_vec[idx]->mEnd - draw_vec[idx]->mStart + facep->getGeomCount()) <= (U32) gGLManager.mGLMaxVertexRange &&
- //draw_vec[idx]->mCount + facep->getIndicesCount() <= (U32) gGLManager.mGLMaxIndexRange &&
- draw_vec[idx]->mEnd - draw_vec[idx]->mStart + facep->getGeomCount() < 4096 &&
- draw_vec[idx]->mFullbright == fullbright)
+ bool batched = false;
+
+ U32 bf_src = LLRender::BF_SOURCE_ALPHA;
+ U32 bf_dst = LLRender::BF_ONE_MINUS_SOURCE_ALPHA;
+
+ object->getBlendFunc(facep->getTEOffset(), bf_src, bf_dst);
+
+
+ if (idx >= 0)
{
- draw_vec[idx]->mCount += facep->getIndicesCount();
- draw_vec[idx]->mEnd += facep->getGeomCount();
- draw_vec[idx]->mVSize = llmax(draw_vec[idx]->mVSize, vsize);
+ LLDrawInfo* info = draw_vec[idx];
+
+ if (info->mTexture == facep->getTexture() &&
+ info->mHasGlow == has_glow &&
+ info->mFullbright == fullbright &&
+ info->mBlendFuncDst == bf_dst &&
+ info->mBlendFuncSrc == bf_src)
+ {
+ if (draw_vec[idx]->mEnd == facep->getGeomIndex()-1)
+ {
+ batched = true;
+ info->mCount += facep->getIndicesCount();
+ info->mEnd += facep->getGeomCount();
+ info->mVSize = llmax(draw_vec[idx]->mVSize, vsize);
+ }
+ else if (draw_vec[idx]->mStart == facep->getGeomIndex()+facep->getGeomCount()+1)
+ {
+ batched = true;
+ info->mCount += facep->getIndicesCount();
+ info->mStart -= facep->getGeomCount();
+ info->mOffset = facep->getIndicesStart();
+ info->mVSize = llmax(draw_vec[idx]->mVSize, vsize);
+ }
+ }
}
- else
+
+
+ if (!batched)
{
U32 start = facep->getGeomIndex();
U32 end = start + facep->getGeomCount()-1;
@@ -535,13 +961,16 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group)
info->mExtents[0] = group->mObjectExtents[0];
info->mExtents[1] = group->mObjectExtents[1];
info->mVSize = vsize;
+ info->mBlendFuncDst = bf_dst;
+ info->mBlendFuncSrc = bf_src;
+ info->mHasGlow = has_glow;
+ info->mParticle = TRUE;
draw_vec.push_back(info);
//for alpha sorting
facep->setDrawInfo(info);
}
}
- buffer->flush();
mFaceList.clear();
}
diff --git a/indra/newview/llvopartgroup.h b/indra/newview/llvopartgroup.h
index e58fed86d9..724e915d02 100644..100755
--- a/indra/newview/llvopartgroup.h
+++ b/indra/newview/llvopartgroup.h
@@ -31,43 +31,75 @@
#include "v3math.h"
#include "v3color.h"
#include "llframetimer.h"
+#include "llviewerpartsim.h"
+#include "llvertexbuffer.h"
class LLViewerPartGroup;
class LLVOPartGroup : public LLAlphaObject
{
public:
+
+ //vertex buffer for holding all particles
+ static LLPointer<LLVertexBuffer> sVB;
+ static S32 sVBSlotCursor;
+
+ static void initClass();
+ static void restoreGL();
+ static void destroyGL();
+ static S32 findAvailableVBSlot();
+ static void freeVBSlot(S32 idx);
+
enum
{
- VERTEX_DATA_MASK = (1 << LLVertexBuffer::TYPE_VERTEX) |
- (1 << LLVertexBuffer::TYPE_NORMAL) |
- (1 << LLVertexBuffer::TYPE_TEXCOORD0) |
- (1 << LLVertexBuffer::TYPE_COLOR)
+ VERTEX_DATA_MASK = LLVertexBuffer::MAP_VERTEX |
+ LLVertexBuffer::MAP_NORMAL |
+ LLVertexBuffer::MAP_TEXCOORD0 |
+ LLVertexBuffer::MAP_COLOR |
+ LLVertexBuffer::MAP_EMISSIVE |
+ LLVertexBuffer::MAP_TEXTURE_INDEX
};
LLVOPartGroup(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp);
/*virtual*/ BOOL isActive() const; // Whether this object needs to do an idleUpdate.
- BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time);
+ void idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time);
virtual F32 getBinRadius();
virtual void updateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax);
virtual U32 getPartitionType() const;
+ /*virtual*/ BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
+ S32 face,
+ BOOL pick_transparent,
+ S32* face_hit,
+ LLVector4a* intersection,
+ LLVector2* tex_coord,
+ LLVector4a* normal,
+ LLVector4a* tangent);
+
/*virtual*/ void setPixelAreaAndAngle(LLAgent &agent);
/*virtual*/ void updateTextures();
/*virtual*/ LLDrawable* createDrawable(LLPipeline *pipeline);
/*virtual*/ BOOL updateGeometry(LLDrawable *drawable);
+ void getGeometry(const LLViewerPart& part,
+ LLStrider<LLVector4a>& verticesp);
+
void getGeometry(S32 idx,
LLStrider<LLVector4a>& verticesp,
LLStrider<LLVector3>& normalsp,
LLStrider<LLVector2>& texcoordsp,
LLStrider<LLColor4U>& colorsp,
+ LLStrider<LLColor4U>& emissivep,
LLStrider<U16>& indicesp);
void updateFaceSize(S32 idx) { }
F32 getPartSize(S32 idx);
+ void getBlendFunc(S32 idx, U32& src, U32& dst);
+ LLUUID getPartOwner(S32 idx);
+ LLUUID getPartSource(S32 idx);
+
void setViewerPartGroup(LLViewerPartGroup *part_groupp) { mViewerPartGroupp = part_groupp; }
LLViewerPartGroup* getViewerPartGroup() { return mViewerPartGroupp; }
diff --git a/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp
index 312034022e..36793017ed 100644..100755
--- a/indra/newview/llvosky.cpp
+++ b/indra/newview/llvosky.cpp
@@ -298,7 +298,7 @@ void LLSkyTex::create(const F32 brightness)
void LLSkyTex::createGLImage(S32 which)
{
- mTexture[which]->createGLTexture(0, mImageRaw[which], 0, TRUE, LLViewerTexture::LOCAL);
+ mTexture[which]->createGLTexture(0, mImageRaw[which], 0, TRUE, LLGLTexture::LOCAL);
mTexture[which]->setAddressMode(LLTexUnit::TAM_CLAMP);
}
@@ -384,9 +384,9 @@ LLVOSky::LLVOSky(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp)
mSun.setIntensity(SUN_INTENSITY);
mMoon.setIntensity(0.1f * SUN_INTENSITY);
- mSunTexturep = LLViewerTextureManager::getFetchedTexture(gSunTextureID, TRUE, LLViewerTexture::BOOST_UI);
+ mSunTexturep = LLViewerTextureManager::getFetchedTexture(gSunTextureID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);
mSunTexturep->setAddressMode(LLTexUnit::TAM_CLAMP);
- mMoonTexturep = LLViewerTextureManager::getFetchedTexture(gMoonTextureID, TRUE, LLViewerTexture::BOOST_UI);
+ mMoonTexturep = LLViewerTextureManager::getFetchedTexture(gMoonTextureID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);
mMoonTexturep->setAddressMode(LLTexUnit::TAM_CLAMP);
mBloomTexturep = LLViewerTextureManager::getFetchedTexture(IMG_BLOOM1);
mBloomTexturep->setNoDelete() ;
@@ -478,9 +478,9 @@ void LLVOSky::restoreGL()
{
mSkyTex[i].restoreGL();
}
- mSunTexturep = LLViewerTextureManager::getFetchedTexture(gSunTextureID, TRUE, LLViewerTexture::BOOST_UI);
+ mSunTexturep = LLViewerTextureManager::getFetchedTexture(gSunTextureID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);
mSunTexturep->setAddressMode(LLTexUnit::TAM_CLAMP);
- mMoonTexturep = LLViewerTextureManager::getFetchedTexture(gMoonTextureID, TRUE, LLViewerTexture::BOOST_UI);
+ mMoonTexturep = LLViewerTextureManager::getFetchedTexture(gMoonTextureID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);
mMoonTexturep->setAddressMode(LLTexUnit::TAM_CLAMP);
mBloomTexturep = LLViewerTextureManager::getFetchedTexture(IMG_BLOOM1);
mBloomTexturep->setNoDelete() ;
@@ -1052,9 +1052,8 @@ void LLVOSky::calcAtmospherics(void)
mFadeColor.setAlpha(0);
}
-BOOL LLVOSky::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
+void LLVOSky::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
{
- return TRUE;
}
BOOL LLVOSky::updateSky()
diff --git a/indra/newview/llvosky.h b/indra/newview/llvosky.h
index 6e6898d80a..2a150eccb9 100644..100755
--- a/indra/newview/llvosky.h
+++ b/indra/newview/llvosky.h
@@ -461,7 +461,7 @@ public:
void cleanupGL();
void restoreGL();
- /*virtual*/ BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time);
+ /*virtual*/ void idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time);
BOOL updateSky();
// Graphical stuff for objects - maybe broken out into render class
diff --git a/indra/newview/llvosurfacepatch.cpp b/indra/newview/llvosurfacepatch.cpp
index bf6158eeaf..9a5c5831ca 100644..100755
--- a/indra/newview/llvosurfacepatch.cpp
+++ b/indra/newview/llvosurfacepatch.cpp
@@ -80,9 +80,9 @@ public:
glNormalPointer(GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_NORMAL], (void*)(base + mOffsets[TYPE_NORMAL]));
}
if (data_mask & MAP_TEXCOORD3)
- { //substitute tex coord 0 for tex coord 3
+ { //substitute tex coord 1 for tex coord 3
glClientActiveTextureARB(GL_TEXTURE3_ARB);
- glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD0], (void*)(base + mOffsets[TYPE_TEXCOORD0]));
+ glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], (void*)(base + mOffsets[TYPE_TEXCOORD1]));
glClientActiveTextureARB(GL_TEXTURE0_ARB);
}
if (data_mask & MAP_TEXCOORD2)
@@ -97,10 +97,10 @@ public:
glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], (void*)(base + mOffsets[TYPE_TEXCOORD1]));
glClientActiveTextureARB(GL_TEXTURE0_ARB);
}
- if (data_mask & MAP_BINORMAL)
+ if (data_mask & MAP_TANGENT)
{
glClientActiveTextureARB(GL_TEXTURE2_ARB);
- glTexCoordPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_BINORMAL], (void*)(base + mOffsets[TYPE_BINORMAL]));
+ glTexCoordPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TANGENT], (void*)(base + mOffsets[TYPE_TANGENT]));
glClientActiveTextureARB(GL_TEXTURE0_ARB);
}
if (data_mask & MAP_TEXCOORD0)
@@ -296,18 +296,20 @@ void LLVOSurfacePatch::updateFaceSize(S32 idx)
}
LLFace* facep = mDrawable->getFace(idx);
-
- S32 num_vertices = 0;
- S32 num_indices = 0;
-
- if (mLastStride)
+ if (facep)
{
- getGeomSizesMain(mLastStride, num_vertices, num_indices);
- getGeomSizesNorth(mLastStride, mLastNorthStride, num_vertices, num_indices);
- getGeomSizesEast(mLastStride, mLastEastStride, num_vertices, num_indices);
- }
+ S32 num_vertices = 0;
+ S32 num_indices = 0;
+
+ if (mLastStride)
+ {
+ getGeomSizesMain(mLastStride, num_vertices, num_indices);
+ getGeomSizesNorth(mLastStride, mLastNorthStride, num_vertices, num_indices);
+ getGeomSizesEast(mLastStride, mLastEastStride, num_vertices, num_indices);
+ }
- facep->setSize(num_vertices, num_indices);
+ facep->setSize(num_vertices, num_indices);
+ }
}
BOOL LLVOSurfacePatch::updateLOD()
@@ -322,30 +324,32 @@ void LLVOSurfacePatch::getGeometry(LLStrider<LLVector3> &verticesp,
LLStrider<U16> &indicesp)
{
LLFace* facep = mDrawable->getFace(0);
+ if (facep)
+ {
+ U32 index_offset = facep->getGeomIndex();
- U32 index_offset = facep->getGeomIndex();
-
- updateMainGeometry(facep,
- verticesp,
- normalsp,
- texCoords0p,
- texCoords1p,
- indicesp,
- index_offset);
- updateNorthGeometry(facep,
- verticesp,
- normalsp,
- texCoords0p,
- texCoords1p,
- indicesp,
- index_offset);
- updateEastGeometry(facep,
+ updateMainGeometry(facep,
verticesp,
normalsp,
texCoords0p,
texCoords1p,
indicesp,
index_offset);
+ updateNorthGeometry(facep,
+ verticesp,
+ normalsp,
+ texCoords0p,
+ texCoords1p,
+ indicesp,
+ index_offset);
+ updateEastGeometry(facep,
+ verticesp,
+ normalsp,
+ texCoords0p,
+ texCoords1p,
+ indicesp,
+ index_offset);
+ }
}
void LLVOSurfacePatch::updateMainGeometry(LLFace *facep,
@@ -463,7 +467,7 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep,
S32 vertex_count = 0;
S32 i, x, y;
- S32 num_vertices, num_indices;
+ S32 num_vertices;
U32 render_stride = mLastStride;
S32 patch_size = mPatchp->getSurface()->getGridsPerPatchEdge();
@@ -481,7 +485,6 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep,
if (north_stride == render_stride)
{
num_vertices = 2 * length + 1;
- num_indices = length * 6 - 3;
facep->mCenterAgent = (mPatchp->getPointAgent(8, 15) + mPatchp->getPointAgent(8, 16))*0.5f;
@@ -532,7 +535,6 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep,
{
// North stride is longer (has less vertices)
num_vertices = length + length/2 + 1;
- num_indices = half_length*9 - 3;
facep->mCenterAgent = (mPatchp->getPointAgent(7, 15) + mPatchp->getPointAgent(8, 16))*0.5f;
@@ -591,7 +593,6 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep,
length = patch_size / north_stride;
half_length = length / 2;
num_vertices = length + half_length + 1;
- num_indices = 9*half_length - 3;
facep->mCenterAgent = (mPatchp->getPointAgent(15, 7) + mPatchp->getPointAgent(16, 8))*0.5f;
@@ -662,7 +663,7 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep,
{
S32 i, x, y;
- S32 num_vertices, num_indices;
+ S32 num_vertices;
U32 render_stride = mLastStride;
S32 patch_size = mPatchp->getSurface()->getGridsPerPatchEdge();
@@ -675,7 +676,6 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep,
if (east_stride == render_stride)
{
num_vertices = 2 * length + 1;
- num_indices = length * 6 - 3;
facep->mCenterAgent = (mPatchp->getPointAgent(8, 15) + mPatchp->getPointAgent(8, 16))*0.5f;
@@ -724,7 +724,6 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep,
{
// East stride is longer (has less vertices)
num_vertices = length + half_length + 1;
- num_indices = half_length*9 - 3;
facep->mCenterAgent = (mPatchp->getPointAgent(7, 15) + mPatchp->getPointAgent(8, 16))*0.5f;
@@ -779,7 +778,6 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep,
length = patch_size / east_stride;
half_length = length / 2;
num_vertices = length + length/2 + 1;
- num_indices = 9*(length/2) - 3;
facep->mCenterAgent = (mPatchp->getPointAgent(15, 7) + mPatchp->getPointAgent(16, 8))*0.5f;
@@ -864,7 +862,11 @@ void LLVOSurfacePatch::dirtyGeom()
if (mDrawable)
{
gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE);
- mDrawable->getFace(0)->setVertexBuffer(NULL);
+ LLFace* facep = mDrawable->getFace(0);
+ if (facep)
+ {
+ facep->setVertexBuffer(NULL);
+ }
mDrawable->movePartition();
}
}
@@ -934,8 +936,8 @@ void LLVOSurfacePatch::getGeomSizesEast(const S32 stride, const S32 east_stride,
}
}
-BOOL LLVOSurfacePatch::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, S32 face, BOOL pick_transparent, S32 *face_hitp,
- LLVector3* intersection,LLVector2* tex_coord, LLVector3* normal, LLVector3* bi_normal)
+BOOL LLVOSurfacePatch::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face, BOOL pick_transparent, S32 *face_hitp,
+ LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent)
{
@@ -944,7 +946,9 @@ BOOL LLVOSurfacePatch::lineSegmentIntersect(const LLVector3& start, const LLVect
return FALSE;
}
- LLVector3 delta = end-start;
+ LLVector4a da;
+ da.setSub(end, start);
+ LLVector3 delta(da.getF32ptr());
LLVector3 pdelta = delta;
pdelta.mV[2] = 0;
@@ -953,7 +957,9 @@ BOOL LLVOSurfacePatch::lineSegmentIntersect(const LLVector3& start, const LLVect
F32 tdelta = 1.f/plength;
- LLVector3 origin = start - mRegionp->getOriginAgent();
+ LLVector3 v_start(start.getF32ptr());
+
+ LLVector3 origin = v_start - mRegionp->getOriginAgent();
if (mRegionp->getLandHeightRegion(origin) > origin.mV[2])
{
@@ -1008,12 +1014,12 @@ BOOL LLVOSurfacePatch::lineSegmentIntersect(const LLVector3& start, const LLVect
{
sample.mV[2] = mRegionp->getLandHeightRegion(sample);
}
- *intersection = sample + mRegionp->getOriginAgent();
+ intersection->load3((sample + mRegionp->getOriginAgent()).mV);
}
if (normal)
{
- *normal = mRegionp->getLand().resolveNormalGlobal(mRegionp->getPosGlobalFromRegion(sample));
+ normal->load3((mRegionp->getLand().resolveNormalGlobal(mRegionp->getPosGlobalFromRegion(sample))).mV);
}
return TRUE;
diff --git a/indra/newview/llvosurfacepatch.h b/indra/newview/llvosurfacepatch.h
index a15878368e..7b53219be8 100644..100755
--- a/indra/newview/llvosurfacepatch.h
+++ b/indra/newview/llvosurfacepatch.h
@@ -79,14 +79,14 @@ public:
void dirtyPatch();
void dirtyGeom();
- /*virtual*/ BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end,
+ /*virtual*/ BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
S32 face = -1, // which face to check, -1 = ALL_SIDES
BOOL pick_transparent = FALSE,
S32* face_hit = NULL, // which face was hit
- LLVector3* intersection = NULL, // return the intersection point
+ LLVector4a* intersection = NULL, // return the intersection point
LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
- LLVector3* normal = NULL, // return the surface normal at the intersection point
- LLVector3* bi_normal = NULL // return the surface bi-normal at the intersection point
+ LLVector4a* normal = NULL, // return the surface normal at the intersection point
+ LLVector4a* tangent = NULL // return the surface tangent at the intersection point
);
BOOL mDirtiedPatch;
diff --git a/indra/newview/llvotree.cpp b/indra/newview/llvotree.cpp
index 4564207da4..cd12cd9552 100644..100755
--- a/indra/newview/llvotree.cpp
+++ b/indra/newview/llvotree.cpp
@@ -316,7 +316,7 @@ U32 LLVOTree::processUpdateMessage(LLMessageSystem *mesgsys,
// Load Species-Specific data
//
static const S32 MAX_TREE_TEXTURE_VIRTURE_SIZE_RESET_INTERVAL = 32 ; //frames.
- mTreeImagep = LLViewerTextureManager::getFetchedTexture(sSpeciesTable[mSpecies]->mTextureID, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
+ mTreeImagep = LLViewerTextureManager::getFetchedTexture(sSpeciesTable[mSpecies]->mTextureID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
mTreeImagep->setMaxVirtualSizeResetInterval(MAX_TREE_TEXTURE_VIRTURE_SIZE_RESET_INTERVAL); //allow to wait for at most 16 frames to reset virtual size.
mBranchLength = sSpeciesTable[mSpecies]->mBranchLength;
@@ -339,11 +339,11 @@ U32 LLVOTree::processUpdateMessage(LLMessageSystem *mesgsys,
return retval;
}
-BOOL LLVOTree::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
+void LLVOTree::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
{
if (mDead || !(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_TREE)))
{
- return TRUE;
+ return;
}
S32 trunk_LOD = sMAX_NUM_TREE_LOD_LEVELS ;
@@ -374,7 +374,7 @@ BOOL LLVOTree::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
// *TODO: I don't know what's so special about trees
// that they don't get REBUILD_POSITION automatically
// at a higher level.
- const LLVector3 &this_position = getPositionAgent();
+ const LLVector3 &this_position = getPositionRegion();
if (this_position != mLastPosition)
{
gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_POSITION);
@@ -393,8 +393,6 @@ BOOL LLVOTree::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
}
mTrunkLOD = trunk_LOD;
-
- return TRUE;
}
const F32 TREE_BLEND_MIN = 1.f;
@@ -490,11 +488,16 @@ BOOL LLVOTree::updateGeometry(LLDrawable *drawable)
if(mTrunkLOD >= sMAX_NUM_TREE_LOD_LEVELS) //do not display the tree.
{
mReferenceBuffer = NULL ;
- mDrawable->getFace(0)->setVertexBuffer(NULL);
+ LLFace * facep = drawable->getFace(0);
+ if (facep)
+ {
+ facep->setVertexBuffer(NULL);
+ }
return TRUE ;
}
- if (mReferenceBuffer.isNull() || !mDrawable->getFace(0)->getVertexBuffer())
+ if (mDrawable->getFace(0) &&
+ (mReferenceBuffer.isNull() || !mDrawable->getFace(0)->getVertexBuffer()))
{
const F32 SRR3 = 0.577350269f; // sqrt(1/3)
const F32 SRR2 = 0.707106781f; // sqrt(1/2)
@@ -507,6 +510,7 @@ BOOL LLVOTree::updateGeometry(LLDrawable *drawable)
S32 lod;
LLFace *face = drawable->getFace(0);
+ if (!face) return TRUE;
face->mCenterAgent = getPositionAgent();
face->mCenterLocal = face->mCenterAgent;
@@ -837,10 +841,10 @@ void LLVOTree::updateMesh()
LLMatrix4 matrix;
// Translate to tree base HACK - adjustment in Z plants tree underground
- const LLVector3 &pos_agent = getPositionAgent();
+ const LLVector3 &pos_region = getPositionRegion();
//gGL.translatef(pos_agent.mV[VX], pos_agent.mV[VY], pos_agent.mV[VZ] - 0.1f);
LLMatrix4 trans_mat;
- trans_mat.setTranslation(pos_agent.mV[VX], pos_agent.mV[VY], pos_agent.mV[VZ] - 0.1f);
+ trans_mat.setTranslation(pos_region.mV[VX], pos_region.mV[VY], pos_region.mV[VZ] - 0.1f);
trans_mat *= matrix;
// Rotate to tree position and bend for current trunk/wind
@@ -879,6 +883,7 @@ void LLVOTree::updateMesh()
calcNumVerts(vert_count, index_count, mTrunkLOD, stop_depth, mDepth, mTrunkDepth, mBranches);
LLFace* facep = mDrawable->getFace(0);
+ if (!facep) return;
LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolTree::VERTEX_DATA_MASK, GL_STATIC_DRAW_ARB);
buff->allocateBuffer(vert_count, index_count, TRUE);
facep->setVertexBuffer(buff);
@@ -1080,132 +1085,6 @@ void LLVOTree::calcNumVerts(U32& vert_count, U32& index_count, S32 trunk_LOD, S3
}
}
-U32 LLVOTree::drawBranchPipeline(LLMatrix4& matrix, U16* indicesp, S32 trunk_LOD, S32 stop_level, U16 depth, U16 trunk_depth, F32 scale, F32 twist, F32 droop, F32 branches, F32 alpha)
-{
- U32 ret = 0;
- //
- // Draws a tree by recursing, drawing branches and then a 'leaf' texture.
- // If stop_level = -1, simply draws the whole tree as a billboarded texture
- //
-
- static F32 constant_twist;
- static F32 width = 0;
-
- //F32 length = ((scale == 1.f)? mTrunkLength:mBranchLength);
- //F32 aspect = ((scale == 1.f)? mTrunkAspect:mBranchAspect);
- F32 length = ((trunk_depth || (scale == 1.f))? mTrunkLength:mBranchLength);
- F32 aspect = ((trunk_depth || (scale == 1.f))? mTrunkAspect:mBranchAspect);
-
- constant_twist = 360.f/branches;
-
- if (!LLPipeline::sReflectionRender && stop_level >= 0)
- {
- //
- // Draw the tree using recursion
- //
- if (depth > stop_level)
- {
- {
- llassert(sLODIndexCount[trunk_LOD] > 0);
- width = scale * length * aspect;
- LLMatrix4 scale_mat;
- scale_mat.mMatrix[0][0] = width;
- scale_mat.mMatrix[1][1] = width;
- scale_mat.mMatrix[2][2] = scale*length;
- scale_mat *= matrix;
-
- gGL.loadMatrix((F32*) scale_mat.mMatrix);
- gGL.syncMatrices();
- glDrawElements(GL_TRIANGLES, sLODIndexCount[trunk_LOD], GL_UNSIGNED_SHORT, indicesp + sLODIndexOffset[trunk_LOD]);
- gPipeline.addTrianglesDrawn(LEAF_INDICES);
- stop_glerror();
- ret += sLODIndexCount[trunk_LOD];
- }
-
- // Recurse to create more branches
- for (S32 i=0; i < (S32)branches; i++)
- {
- LLMatrix4 trans_mat;
- trans_mat.setTranslation(0,0,scale*length);
- trans_mat *= matrix;
-
- LLQuaternion rot =
- LLQuaternion(20.f*DEG_TO_RAD, LLVector4(0.f, 0.f, 1.f)) *
- LLQuaternion(droop*DEG_TO_RAD, LLVector4(0.f, 1.f, 0.f)) *
- LLQuaternion(((constant_twist + ((i%2==0)?twist:-twist))*i)*DEG_TO_RAD, LLVector4(0.f, 0.f, 1.f));
-
- LLMatrix4 rot_mat(rot);
- rot_mat *= trans_mat;
-
- ret += drawBranchPipeline(rot_mat, indicesp, trunk_LOD, stop_level, depth - 1, 0, scale*mScaleStep, twist, droop, branches, alpha);
- }
- // Recurse to continue trunk
- if (trunk_depth)
- {
- LLMatrix4 trans_mat;
- trans_mat.setTranslation(0,0,scale*length);
- trans_mat *= matrix;
-
- LLMatrix4 rot_mat(70.5f*DEG_TO_RAD, LLVector4(0,0,1));
- rot_mat *= trans_mat; // rotate a bit around Z when ascending
- ret += drawBranchPipeline(rot_mat, indicesp, trunk_LOD, stop_level, depth, trunk_depth-1, scale*mScaleStep, twist, droop, branches, alpha);
- }
- }
- else
- {
- //
- // Draw leaves as two 90 deg crossed quads with leaf textures
- //
- {
- LLMatrix4 scale_mat;
- scale_mat.mMatrix[0][0] =
- scale_mat.mMatrix[1][1] =
- scale_mat.mMatrix[2][2] = scale*mLeafScale;
-
- scale_mat *= matrix;
-
-
- gGL.loadMatrix((F32*) scale_mat.mMatrix);
- gGL.syncMatrices();
- glDrawElements(GL_TRIANGLES, LEAF_INDICES, GL_UNSIGNED_SHORT, indicesp);
- gPipeline.addTrianglesDrawn(LEAF_INDICES);
- stop_glerror();
- ret += LEAF_INDICES;
- }
- }
- }
- else
- {
- //
- // Draw the tree as a single billboard texture
- //
-
- LLMatrix4 scale_mat;
- scale_mat.mMatrix[0][0] =
- scale_mat.mMatrix[1][1] =
- scale_mat.mMatrix[2][2] = mBillboardScale*mBillboardRatio;
-
- scale_mat *= matrix;
-
- gGL.matrixMode(LLRender::MM_TEXTURE);
- gGL.translatef(0.0, -0.5, 0.0);
- gGL.matrixMode(LLRender::MM_MODELVIEW);
-
- gGL.loadMatrix((F32*) scale_mat.mMatrix);
- gGL.syncMatrices();
- glDrawElements(GL_TRIANGLES, LEAF_INDICES, GL_UNSIGNED_SHORT, indicesp);
- gPipeline.addTrianglesDrawn(LEAF_INDICES);
- stop_glerror();
- ret += LEAF_INDICES;
-
- gGL.matrixMode(LLRender::MM_TEXTURE);
- gGL.loadIdentity();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- }
-
- return ret;
-}
-
void LLVOTree::updateRadius()
{
if (mDrawable.isNull())
@@ -1233,8 +1112,8 @@ void LLVOTree::updateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax)
mDrawable->setPositionGroup(pos);
}
-BOOL LLVOTree::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, S32 face, BOOL pick_transparent, S32 *face_hitp,
- LLVector3* intersection,LLVector2* tex_coord, LLVector3* normal, LLVector3* bi_normal)
+BOOL LLVOTree::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face, BOOL pick_transparent, S32 *face_hitp,
+ LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent)
{
@@ -1263,16 +1142,19 @@ BOOL LLVOTree::lineSegmentIntersect(const LLVector3& start, const LLVector3& end
LLVector3 pos, norm;
- if (linesegment_tetrahedron(start, end, center, size, quat, pos, norm))
+ LLVector3 start3(start.getF32ptr());
+ LLVector3 end3(end.getF32ptr());
+
+ if (linesegment_tetrahedron(start3, end3, center, size, quat, pos, norm))
{
if (intersection)
{
- *intersection = pos;
+ intersection->load3(pos.mV);
}
if (normal)
{
- *normal = norm;
+ normal->load3(norm.mV);
}
return TRUE;
}
diff --git a/indra/newview/llvotree.h b/indra/newview/llvotree.h
index 0554935539..2ecb0303a1 100644..100755
--- a/indra/newview/llvotree.h
+++ b/indra/newview/llvotree.h
@@ -59,7 +59,7 @@ public:
void **user_data,
U32 block_num, const EObjectUpdateType update_type,
LLDataPacker *dp);
- /*virtual*/ BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time);
+ /*virtual*/ void idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time);
// Graphical stuff for objects - maybe broken out into render class later?
/*virtual*/ void render(LLAgent &agent);
@@ -104,19 +104,16 @@ public:
F32 twist,
F32 droop,
F32 branches,
- F32 alpha);
+ F32 alpha);
- U32 drawBranchPipeline(LLMatrix4& matrix, U16* indicesp, S32 trunk_LOD, S32 stop_level, U16 depth, U16 trunk_depth, F32 scale, F32 twist, F32 droop, F32 branches, F32 alpha);
-
-
- /*virtual*/ BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end,
+ /*virtual*/ BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
S32 face = -1, // which face to check, -1 = ALL_SIDES
BOOL pick_transparent = FALSE,
S32* face_hit = NULL, // which face was hit
- LLVector3* intersection = NULL, // return the intersection point
+ LLVector4a* intersection = NULL, // return the intersection point
LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
- LLVector3* normal = NULL, // return the surface normal at the intersection point
- LLVector3* bi_normal = NULL // return the surface bi-normal at the intersection point
+ LLVector4a* normal = NULL, // return the surface normal at the intersection point
+ LLVector4a* tangent = NULL // return the surface tangent at the intersection point
);
static S32 sMaxTreeSpecies;
diff --git a/indra/newview/llvotreenew.h b/indra/newview/llvotreenew.h
index 0bb07008ca..0bb07008ca 100644..100755
--- a/indra/newview/llvotreenew.h
+++ b/indra/newview/llvotreenew.h
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index e7c35d8220..dfac77857c 100644..100755
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -36,6 +36,7 @@
#include "lldir.h"
#include "llflexibleobject.h"
#include "llfloatertools.h"
+#include "llmaterialid.h"
#include "llmaterialtable.h"
#include "llprimitive.h"
#include "llvolume.h"
@@ -76,6 +77,7 @@
#include "llviewershadermgr.h"
#include "llvoavatar.h"
#include "llvocache.h"
+#include "llmaterialmgr.h"
const S32 MIN_QUIET_FRAMES_COALESCE = 30;
const F32 FORCE_SIMPLE_RENDER_AREA = 512.f;
@@ -99,6 +101,8 @@ static LLFastTimer::DeclareTimer FTM_GEN_TRIANGLES("Generate Triangles");
static LLFastTimer::DeclareTimer FTM_GEN_VOLUME("Generate Volumes");
static LLFastTimer::DeclareTimer FTM_VOLUME_TEXTURES("Volume Textures");
+extern BOOL gGLDebugLoggingEnabled;
+
// Implementation class of LLMediaDataClientObject. See llmediadataclient.h
class LLMediaDataClientObjectImpl : public LLMediaDataClientObject
{
@@ -329,7 +333,7 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys,
{
if (!mTextureAnimp)
{
- mTextureAnimp = new LLViewerTextureAnim();
+ mTextureAnimp = new LLViewerTextureAnim(this);
}
else
{
@@ -339,6 +343,7 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys,
}
}
mTexAnimMode = 0;
+
mTextureAnimp->unpackTAMessage(mesgsys, block_num);
}
else
@@ -370,7 +375,7 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys,
// Unpack texture entry data
//
- S32 result = unpackTEMessage(mesgsys, _PREHASH_ObjectData, block_num);
+ S32 result = unpackTEMessage(mesgsys, _PREHASH_ObjectData, (S32) block_num);
if (result & teDirtyBits)
{
updateTEData();
@@ -382,7 +387,6 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys,
}
else
{
- // CORY TO DO: Figure out how to get the value here
if (update_type != OUT_TERSE_IMPROVED)
{
LLVolumeParams volume_params;
@@ -431,7 +435,7 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys,
{
if (!mTextureAnimp)
{
- mTextureAnimp = new LLViewerTextureAnim();
+ mTextureAnimp = new LLViewerTextureAnim(this);
}
else
{
@@ -451,6 +455,11 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys,
mFaceMappingChanged = TRUE;
mTexAnimMode = 0;
}
+
+ if (value & 0x400)
+ { //particle system (new)
+ unpackParticleSource(*dp, mOwnerID, false);
+ }
}
else
{
@@ -499,191 +508,140 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys,
void LLVOVolume::animateTextures()
{
- F32 off_s = 0.f, off_t = 0.f, scale_s = 1.f, scale_t = 1.f, rot = 0.f;
- S32 result = mTextureAnimp->animateTextures(off_s, off_t, scale_s, scale_t, rot);
-
- if (result)
+ if (!mDead)
{
- if (!mTexAnimMode)
- {
- mFaceMappingChanged = TRUE;
- gPipeline.markTextured(mDrawable);
- }
- mTexAnimMode = result | mTextureAnimp->mMode;
-
- S32 start=0, end=mDrawable->getNumFaces()-1;
- if (mTextureAnimp->mFace >= 0 && mTextureAnimp->mFace <= end)
- {
- start = end = mTextureAnimp->mFace;
- }
-
- for (S32 i = start; i <= end; i++)
+ F32 off_s = 0.f, off_t = 0.f, scale_s = 1.f, scale_t = 1.f, rot = 0.f;
+ S32 result = mTextureAnimp->animateTextures(off_s, off_t, scale_s, scale_t, rot);
+
+ if (result)
{
- LLFace* facep = mDrawable->getFace(i);
- if(facep->getVirtualSize() <= MIN_TEX_ANIM_SIZE && facep->mTextureMatrix) continue;
-
- const LLTextureEntry* te = facep->getTextureEntry();
-
- if (!te)
+ if (!mTexAnimMode)
{
- continue;
- }
-
- if (!(result & LLViewerTextureAnim::ROTATE))
- {
- te->getRotation(&rot);
- }
- if (!(result & LLViewerTextureAnim::TRANSLATE))
- {
- te->getOffset(&off_s,&off_t);
- }
- if (!(result & LLViewerTextureAnim::SCALE))
- {
- te->getScale(&scale_s, &scale_t);
+ mFaceMappingChanged = TRUE;
+ gPipeline.markTextured(mDrawable);
}
-
- if (!facep->mTextureMatrix)
+ mTexAnimMode = result | mTextureAnimp->mMode;
+
+ S32 start=0, end=mDrawable->getNumFaces()-1;
+ if (mTextureAnimp->mFace >= 0 && mTextureAnimp->mFace <= end)
{
- facep->mTextureMatrix = new LLMatrix4();
+ start = end = mTextureAnimp->mFace;
}
-
- LLMatrix4& tex_mat = *facep->mTextureMatrix;
- tex_mat.setIdentity();
- LLVector3 trans ;
-
- if(facep->isAtlasInUse())
+
+ for (S32 i = start; i <= end; i++)
{
- //
- //if use atlas for animated texture
- //apply the following transform to the animation matrix.
- //
+ LLFace* facep = mDrawable->getFace(i);
+ if (!facep) continue;
+ if(facep->getVirtualSize() <= MIN_TEX_ANIM_SIZE && facep->mTextureMatrix) continue;
- F32 tcoord_xoffset = 0.f ;
- F32 tcoord_yoffset = 0.f ;
- F32 tcoord_xscale = 1.f ;
- F32 tcoord_yscale = 1.f ;
- if(facep->isAtlasInUse())
+ const LLTextureEntry* te = facep->getTextureEntry();
+
+ if (!te)
+ {
+ continue;
+ }
+
+ if (!(result & LLViewerTextureAnim::ROTATE))
{
- const LLVector2* tmp = facep->getTexCoordOffset() ;
- tcoord_xoffset = tmp->mV[0] ;
- tcoord_yoffset = tmp->mV[1] ;
+ te->getRotation(&rot);
+ }
+ if (!(result & LLViewerTextureAnim::TRANSLATE))
+ {
+ te->getOffset(&off_s,&off_t);
+ }
+ if (!(result & LLViewerTextureAnim::SCALE))
+ {
+ te->getScale(&scale_s, &scale_t);
+ }
- tmp = facep->getTexCoordScale() ;
- tcoord_xscale = tmp->mV[0] ;
- tcoord_yscale = tmp->mV[1] ;
+ if (!facep->mTextureMatrix)
+ {
+ facep->mTextureMatrix = new LLMatrix4();
}
- trans.set(LLVector3(tcoord_xoffset + tcoord_xscale * (off_s+0.5f), tcoord_yoffset + tcoord_yscale * (off_t+0.5f), 0.f));
- tex_mat.translate(LLVector3(-(tcoord_xoffset + tcoord_xscale * 0.5f), -(tcoord_yoffset + tcoord_yscale * 0.5f), 0.f));
- }
- else //non atlas
- {
+ LLMatrix4& tex_mat = *facep->mTextureMatrix;
+ tex_mat.setIdentity();
+ LLVector3 trans ;
+
trans.set(LLVector3(off_s+0.5f, off_t+0.5f, 0.f));
tex_mat.translate(LLVector3(-0.5f, -0.5f, 0.f));
- }
-
- LLVector3 scale(scale_s, scale_t, 1.f);
- LLQuaternion quat;
- quat.setQuat(rot, 0, 0, -1.f);
+
+ LLVector3 scale(scale_s, scale_t, 1.f);
+ LLQuaternion quat;
+ quat.setQuat(rot, 0, 0, -1.f);
- tex_mat.rotate(quat);
+ tex_mat.rotate(quat);
- LLMatrix4 mat;
- mat.initAll(scale, LLQuaternion(), LLVector3());
- tex_mat *= mat;
+ LLMatrix4 mat;
+ mat.initAll(scale, LLQuaternion(), LLVector3());
+ tex_mat *= mat;
- tex_mat.translate(trans);
+ tex_mat.translate(trans);
+ }
}
- }
- else
- {
- if (mTexAnimMode && mTextureAnimp->mRate == 0)
+ else
{
- U8 start, count;
-
- if (mTextureAnimp->mFace == -1)
+ if (mTexAnimMode && mTextureAnimp->mRate == 0)
{
- start = 0;
- count = getNumTEs();
- }
- else
- {
- start = (U8) mTextureAnimp->mFace;
- count = 1;
- }
+ U8 start, count;
- for (S32 i = start; i < start + count; i++)
- {
- if (mTexAnimMode & LLViewerTextureAnim::TRANSLATE)
+ if (mTextureAnimp->mFace == -1)
{
- setTEOffset(i, mTextureAnimp->mOffS, mTextureAnimp->mOffT);
+ start = 0;
+ count = getNumTEs();
}
- if (mTexAnimMode & LLViewerTextureAnim::SCALE)
+ else
{
- setTEScale(i, mTextureAnimp->mScaleS, mTextureAnimp->mScaleT);
+ start = (U8) mTextureAnimp->mFace;
+ count = 1;
}
- if (mTexAnimMode & LLViewerTextureAnim::ROTATE)
+
+ for (S32 i = start; i < start + count; i++)
{
- setTERotation(i, mTextureAnimp->mRot);
+ if (mTexAnimMode & LLViewerTextureAnim::TRANSLATE)
+ {
+ setTEOffset(i, mTextureAnimp->mOffS, mTextureAnimp->mOffT);
+ }
+ if (mTexAnimMode & LLViewerTextureAnim::SCALE)
+ {
+ setTEScale(i, mTextureAnimp->mScaleS, mTextureAnimp->mScaleT);
+ }
+ if (mTexAnimMode & LLViewerTextureAnim::ROTATE)
+ {
+ setTERotation(i, mTextureAnimp->mRot);
+ }
}
- }
- gPipeline.markTextured(mDrawable);
- mFaceMappingChanged = TRUE;
- mTexAnimMode = 0;
+ gPipeline.markTextured(mDrawable);
+ mFaceMappingChanged = TRUE;
+ mTexAnimMode = 0;
+ }
}
}
}
-BOOL LLVOVolume::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
-{
- LLViewerObject::idleUpdate(agent, world, time);
-
- static LLFastTimer::DeclareTimer ftm("Volume");
- LLFastTimer t(ftm);
-
- if (mDead || mDrawable.isNull())
- {
- return TRUE;
- }
-
- ///////////////////////
- //
- // Do texture animation stuff
- //
- if (mTextureAnimp && gAnimateTextures)
- {
- animateTextures();
- }
-
- // Dispatch to implementation
- if (mVolumeImpl)
+void LLVOVolume::updateTextures()
+{
+ const F32 TEXTURE_AREA_REFRESH_TIME = 5.f; // seconds
+ if (mTextureUpdateTimer.getElapsedTimeF32() > TEXTURE_AREA_REFRESH_TIME)
{
- mVolumeImpl->doIdleUpdate(agent, world, time);
- }
+ updateTextureVirtualSize();
- const S32 MAX_ACTIVE_OBJECT_QUIET_FRAMES = 40;
+ if (mDrawable.notNull() && !isVisible() && !mDrawable->isActive())
+ { //delete vertex buffer to free up some VRAM
+ LLSpatialGroup* group = mDrawable->getSpatialGroup();
+ if (group)
+ {
+ group->destroyGL(true);
- if (mDrawable->isActive())
- {
- if (mDrawable->isRoot() &&
- mDrawable->mQuietCount++ > MAX_ACTIVE_OBJECT_QUIET_FRAMES &&
- (!mDrawable->getParent() || !mDrawable->getParent()->isActive()))
- {
- mDrawable->makeStatic();
+ //flag the group as having changed geometry so it gets a rebuild next time
+ //it becomes visible
+ group->setState(LLSpatialGroup::GEOM_DIRTY | LLSpatialGroup::MESH_DIRTY | LLSpatialGroup::NEW_DRAWINFO);
+ }
}
- }
- return TRUE;
-}
-void LLVOVolume::updateTextures()
-{
- const F32 TEXTURE_AREA_REFRESH_TIME = 5.f; // seconds
- if (mTextureUpdateTimer.getElapsedTimeF32() > TEXTURE_AREA_REFRESH_TIME)
- {
- updateTextureVirtualSize();
- }
+ }
}
BOOL LLVOVolume::isVisible() const
@@ -715,7 +673,18 @@ void LLVOVolume::updateTextureVirtualSize(bool forced)
if(!forced)
{
if(!isVisible())
- {
+ { //don't load textures for non-visible faces
+ const S32 num_faces = mDrawable->getNumFaces();
+ for (S32 i = 0; i < num_faces; i++)
+ {
+ LLFace* face = mDrawable->getFace(i);
+ if (face)
+ {
+ face->setPixelArea(0.f);
+ face->setVirtualSize(0.f);
+ }
+ }
+
return ;
}
@@ -725,7 +694,7 @@ void LLVOVolume::updateTextureVirtualSize(bool forced)
}
}
- static LLCachedControl<bool> dont_load_textures(gSavedSettings,"TextureDisable");
+ static LLCachedControl<bool> dont_load_textures(gSavedSettings,"TextureDisable", false);
if (dont_load_textures || LLAppViewer::getTextureFetch()->mDebugPause) // || !mDrawable->isVisible())
{
@@ -743,6 +712,7 @@ void LLVOVolume::updateTextureVirtualSize(bool forced)
for (S32 i = 0; i < num_faces; i++)
{
LLFace* face = mDrawable->getFace(i);
+ if (!face) continue;
const LLTextureEntry *te = face->getTextureEntry();
LLViewerTexture *imagep = face->getTexture();
if (!imagep || !te ||
@@ -758,7 +728,7 @@ void LLVOVolume::updateTextureVirtualSize(bool forced)
{
F32 area = (F32) camera->getScreenPixelArea();
vsize = area;
- imagep->setBoostLevel(LLViewerTexture::BOOST_HUD);
+ imagep->setBoostLevel(LLGLTexture::BOOST_HUD);
face->setPixelArea(area); // treat as full screen
face->setVirtualSize(vsize);
}
@@ -814,7 +784,7 @@ void LLVOVolume::updateTextureVirtualSize(bool forced)
if (mSculptTexture.notNull())
{
mSculptTexture->setBoostLevel(llmax((S32)mSculptTexture->getBoostLevel(),
- (S32)LLViewerTexture::BOOST_SCULPTED));
+ (S32)LLGLTexture::BOOST_SCULPTED));
mSculptTexture->setForSculpt() ;
if(!mSculptTexture->isCachedRawImageReady())
@@ -833,7 +803,7 @@ void LLVOVolume::updateTextureVirtualSize(bool forced)
}
}
- S32 texture_discard = mSculptTexture->getDiscardLevel(); //try to match the texture
+ S32 texture_discard = mSculptTexture->getCachedRawImageLevel(); //try to match the texture
S32 current_discard = getVolume() ? getVolume()->getSculptLevel() : -2 ;
if (texture_discard >= 0 && //texture has some data available
@@ -889,8 +859,7 @@ void LLVOVolume::updateTextureVirtualSize(bool forced)
BOOL LLVOVolume::isActive() const
{
- return !mStatic || mTextureAnimp || (mVolumeImpl && mVolumeImpl->isActive()) ||
- (mDrawable.notNull() && mDrawable->isActive());
+ return !mStatic;
}
BOOL LLVOVolume::setMaterial(const U8 material)
@@ -930,6 +899,12 @@ LLFace* LLVOVolume::addFace(S32 f)
{
const LLTextureEntry* te = getTE(f);
LLViewerTexture* imagep = getTEImage(f);
+ if (te->getMaterialParams().notNull())
+ {
+ LLViewerTexture* normalp = getTENormalMap(f);
+ LLViewerTexture* specularp = getTESpecularMap(f);
+ return mDrawable->addFace(te, imagep, normalp, specularp);
+ }
return mDrawable->addFace(te, imagep);
}
@@ -1018,7 +993,7 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams &params_in, const S32 detail, bo
if (is404)
{
- setIcon(LLViewerTextureManager::getFetchedTextureFromFile("icons/Inv_Mesh.png", TRUE, LLViewerTexture::BOOST_UI));
+ setIcon(LLViewerTextureManager::getFetchedTextureFromFile("icons/Inv_Mesh.png", FTT_LOCAL_FILE, TRUE, LLGLTexture::BOOST_UI));
//render prim proxy when mesh loading attempts give up
volume_params.setSculptID(LLUUID::null, LL_SCULPT_TYPE_NONE);
@@ -1062,9 +1037,32 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams &params_in, const S32 detail, bo
}
}
+ static LLCachedControl<bool> use_transform_feedback(gSavedSettings, "RenderUseTransformFeedback", false);
+
+ bool cache_in_vram = use_transform_feedback && gTransformPositionProgram.mProgramObject &&
+ (!mVolumeImpl || !mVolumeImpl->isVolumeUnique());
+
+ if (cache_in_vram)
+ { //this volume might be used as source data for a transform object, put it in vram
+ LLVolume* volume = getVolume();
+ for (S32 i = 0; i < volume->getNumFaces(); ++i)
+ {
+ const LLVolumeFace& face = volume->getVolumeFace(i);
+ if (face.mVertexBuffer.notNull())
+ { //already cached
+ break;
+ }
+ volume->genTangents(i);
+ LLFace::cacheFaceInVRAM(face);
+ }
+ }
+
+
return TRUE;
}
+
+
return FALSE;
}
@@ -1078,7 +1076,7 @@ void LLVOVolume::updateSculptTexture()
LLUUID id = sculpt_params->getSculptTexture();
if (id.notNull())
{
- mSculptTexture = LLViewerTextureManager::getFetchedTexture(id, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
+ mSculptTexture = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
}
}
else
@@ -1104,6 +1102,12 @@ void LLVOVolume::notifyMeshLoaded()
{
mSculptChanged = TRUE;
gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_GEOMETRY, TRUE);
+
+ LLVOAvatar* avatar = getAvatar();
+ if (avatar)
+ {
+ avatar->updateVisualComplexity();
+ }
}
// sculpt replaces generate() for sculpted surfaces
@@ -1116,27 +1120,55 @@ void LLVOVolume::sculpt()
S8 sculpt_components = 0;
const U8* sculpt_data = NULL;
- S32 discard_level = mSculptTexture->getDiscardLevel() ;
+ S32 discard_level = mSculptTexture->getCachedRawImageLevel() ;
LLImageRaw* raw_image = mSculptTexture->getCachedRawImage() ;
S32 max_discard = mSculptTexture->getMaxDiscardLevel();
if (discard_level > max_discard)
- discard_level = max_discard; // clamp to the best we can do
+ {
+ discard_level = max_discard; // clamp to the best we can do
+ }
+ if(discard_level > MAX_DISCARD_LEVEL)
+ {
+ return; //we think data is not ready yet.
+ }
S32 current_discard = getVolume()->getSculptLevel() ;
if(current_discard < -2)
{
- llwarns << "WARNING!!: Current discard of sculpty at " << current_discard
- << " is less than -2." << llendl;
+ static S32 low_sculpty_discard_warning_count = 1;
+ S32 exponent = llmax(1, llfloor( log10((F64) low_sculpty_discard_warning_count) ));
+ S32 interval = pow(10.0, exponent);
+ if ( low_sculpty_discard_warning_count < 10 ||
+ (low_sculpty_discard_warning_count % interval) == 0)
+ { // Log first 10 time, then decreasing intervals afterwards otherwise this can flood the logs
+ llwarns << "WARNING!!: Current discard for sculpty " << mSculptTexture->getID()
+ << " at " << current_discard
+ << " is less than -2."
+ << " Hit this " << low_sculpty_discard_warning_count << " times"
+ << llendl;
+ }
+ low_sculpty_discard_warning_count++;
// corrupted volume... don't update the sculpty
return;
}
else if (current_discard > MAX_DISCARD_LEVEL)
{
- llwarns << "WARNING!!: Current discard of sculpty at " << current_discard
- << " is more than than allowed max of " << MAX_DISCARD_LEVEL << llendl;
-
+ static S32 high_sculpty_discard_warning_count = 1;
+ S32 exponent = llmax(1, llfloor( log10((F64) high_sculpty_discard_warning_count) ));
+ S32 interval = pow(10.0, exponent);
+ if ( high_sculpty_discard_warning_count < 10 ||
+ (high_sculpty_discard_warning_count % interval) == 0)
+ { // Log first 10 time, then decreasing intervals afterwards otherwise this can flood the logs
+ llwarns << "WARNING!!: Current discard for sculpty " << mSculptTexture->getID()
+ << " at " << current_discard
+ << " is more than than allowed max of " << MAX_DISCARD_LEVEL
+ << ". Hit this " << high_sculpty_discard_warning_count << " times"
+ << llendl;
+ }
+ high_sculpty_discard_warning_count++;
+
// corrupted volume... don't update the sculpty
return;
}
@@ -1215,13 +1247,20 @@ BOOL LLVOVolume::calcLOD()
if (mDrawable->isState(LLDrawable::RIGGED))
{
LLVOAvatar* avatar = getAvatar();
+
+ // Not sure how this can really happen, but alas it does. Better exit here than crashing.
+ if( !avatar || !avatar->mDrawable )
+ {
+ return FALSE;
+ }
+
distance = avatar->mDrawable->mDistanceWRTCamera;
radius = avatar->getBinRadius();
}
else
{
distance = mDrawable->mDistanceWRTCamera;
- radius = getVolume()->mLODScaleBias.scaledVec(getScale()).length();
+ radius = getVolume() ? getVolume()->mLODScaleBias.scaledVec(getScale()).length() : getScale().length();
}
//hold onto unmodified distance for debugging
@@ -1246,11 +1285,12 @@ BOOL LLVOVolume::calcLOD()
llround(radius, 0.01f));
- if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_LOD_INFO))
+ if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_LOD_INFO) &&
+ mDrawable->getFace(0))
{
//setDebugText(llformat("%.2f:%.2f, %d", debug_distance, radius, cur_detail));
- setDebugText(llformat("%d", mDrawable->getFace(0)->getTextureIndex()));
+ //setDebugText(llformat("%d", mDrawable->getFace(0)->getTextureIndex()));
}
if (cur_detail != mLOD)
@@ -1322,28 +1362,27 @@ BOOL LLVOVolume::setDrawableParent(LLDrawable* parentp)
void LLVOVolume::updateFaceFlags()
{
- for (S32 i = 0; i < getVolume()->getNumFaces(); i++)
+ // There's no guarantee that getVolume()->getNumFaces() == mDrawable->getNumFaces()
+ for (S32 i = 0; i < getVolume()->getNumFaces() && i < mDrawable->getNumFaces(); i++)
{
LLFace *face = mDrawable->getFace(i);
- if (!face)
+ if (face)
{
- return;
- }
-
- BOOL fullbright = getTE(i)->getFullbright();
- face->clearState(LLFace::FULLBRIGHT | LLFace::HUD_RENDER | LLFace::LIGHT);
+ BOOL fullbright = getTE(i)->getFullbright();
+ face->clearState(LLFace::FULLBRIGHT | LLFace::HUD_RENDER | LLFace::LIGHT);
- if (fullbright || (mMaterial == LL_MCODE_LIGHT))
- {
- face->setState(LLFace::FULLBRIGHT);
- }
- if (mDrawable->isLight())
- {
- face->setState(LLFace::LIGHT);
- }
- if (isHUDAttachment())
- {
- face->setState(LLFace::HUD_RENDER);
+ if (fullbright || (mMaterial == LL_MCODE_LIGHT))
+ {
+ face->setState(LLFace::FULLBRIGHT);
+ }
+ if (mDrawable->isLight())
+ {
+ face->setState(LLFace::LIGHT);
+ }
+ if (isHUDAttachment())
+ {
+ face->setState(LLFace::HUD_RENDER);
+ }
}
}
}
@@ -1380,8 +1419,15 @@ void LLVOVolume::regenFaces()
for (S32 i = 0; i < mNumFaces; i++)
{
LLFace* facep = count_changed ? addFace(i) : mDrawable->getFace(i);
+ if (!facep) continue;
+
facep->setTEOffset(i);
facep->setTexture(getTEImage(i));
+ if (facep->getTextureEntry()->getMaterialParams().notNull())
+ {
+ facep->setNormalMap(getTENormalMap(i));
+ facep->setSpecularMap(getTESpecularMap(i));
+ }
facep->setViewerObject(this);
// If the face had media on it, this will have broken the link between the LLViewerMediaTexture and the face.
@@ -1416,14 +1462,17 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global)
BOOL rebuild = mDrawable->isState(LLDrawable::REBUILD_VOLUME | LLDrawable::REBUILD_POSITION | LLDrawable::REBUILD_RIGGED);
-// bool rigged = false;
+ // bool rigged = false;
LLVolume* volume = mRiggedVolume;
if (!volume)
{
volume = getVolume();
}
- for (S32 i = 0; i < getVolume()->getNumVolumeFaces(); i++)
+ // There's no guarantee that getVolume()->getNumFaces() == mDrawable->getNumFaces()
+ for (S32 i = 0;
+ i < getVolume()->getNumVolumeFaces() && i < mDrawable->getNumFaces() && i < getNumTEs();
+ i++)
{
LLFace *face = mDrawable->getFace(i);
if (!face)
@@ -1431,7 +1480,7 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global)
continue;
}
res &= face->genVolumeBBoxes(*volume, i,
- mRelativeXform, mRelativeXformInvTrans,
+ mRelativeXform,
(mVolumeImpl && mVolumeImpl->isVolumeGlobal()) || force_global);
if (rebuild)
@@ -1459,7 +1508,7 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global)
updateRadius();
mDrawable->movePartition();
-
+
return res;
}
@@ -1471,11 +1520,11 @@ void LLVOVolume::preRebuild()
}
}
-void LLVOVolume::updateRelativeXform()
+void LLVOVolume::updateRelativeXform(bool force_identity)
{
if (mVolumeImpl)
{
- mVolumeImpl->updateRelativeXform();
+ mVolumeImpl->updateRelativeXform(force_identity);
return;
}
@@ -1495,15 +1544,16 @@ void LLVOVolume::updateRelativeXform()
mRelativeXform.invert();
mRelativeXformInvTrans.transpose();
}
- else if (drawable->isActive())
+ else if (drawable->isActive() || force_identity)
{
// setup relative transforms
LLQuaternion delta_rot;
LLVector3 delta_pos, delta_scale;
//matrix from local space to parent relative/global space
- delta_rot = drawable->isSpatialRoot() ? LLQuaternion() : mDrawable->getRotation();
- delta_pos = drawable->isSpatialRoot() ? LLVector3(0,0,0) : mDrawable->getPosition();
+ bool use_identity = force_identity || drawable->isSpatialRoot();
+ delta_rot = use_identity ? LLQuaternion() : mDrawable->getRotation();
+ delta_pos = use_identity ? LLVector3(0,0,0) : mDrawable->getPosition();
delta_scale = mDrawable->getScale();
// Vertex transform (4x4)
@@ -1604,7 +1654,11 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable)
return res;
}
- dirtySpatialGroup(drawable->isState(LLDrawable::IN_REBUILD_Q1));
+ LLSpatialGroup* group = drawable->getSpatialGroup();
+ if (group)
+ {
+ group->dirtyMesh();
+ }
BOOL compiled = FALSE;
@@ -1617,6 +1671,8 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable)
if (mVolumeChanged || mFaceMappingChanged )
{
+ dirtySpatialGroup(drawable->isState(LLDrawable::IN_REBUILD_Q1));
+
compiled = TRUE;
if (mVolumeChanged)
@@ -1635,6 +1691,8 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable)
}
else if ((mLODChanged) || (mSculptChanged))
{
+ dirtySpatialGroup(drawable->isState(LLDrawable::IN_REBUILD_Q1));
+
LLVolume *old_volumep, *new_volumep;
F32 old_lod, new_lod;
S32 old_num_faces, new_num_faces ;
@@ -1715,17 +1773,25 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable)
void LLVOVolume::updateFaceSize(S32 idx)
{
- LLFace* facep = mDrawable->getFace(idx);
- if (idx >= getVolume()->getNumVolumeFaces())
+ if( mDrawable->getNumFaces() <= idx )
{
- facep->setSize(0,0, true);
+ return;
}
- else
+
+ LLFace* facep = mDrawable->getFace(idx);
+ if (facep)
{
- const LLVolumeFace& vol_face = getVolume()->getVolumeFace(idx);
- facep->setSize(vol_face.mNumVertices, vol_face.mNumIndices,
- true); // <--- volume faces should be padded for 16-byte alignment
+ if (idx >= getVolume()->getNumVolumeFaces())
+ {
+ facep->setSize(0,0, true);
+ }
+ else
+ {
+ const LLVolumeFace& vol_face = getVolume()->getVolumeFace(idx);
+ facep->setSize(vol_face.mNumVertices, vol_face.mNumIndices,
+ true); // <--- volume faces should be padded for 16-byte alignment
+ }
}
}
@@ -1778,6 +1844,18 @@ void LLVOVolume::setNumTEs(const U8 num_tes)
return ;
}
+//virtual
+void LLVOVolume::changeTEImage(S32 index, LLViewerTexture* imagep)
+{
+ BOOL changed = (mTEImages[index] != imagep);
+ LLViewerObject::changeTEImage(index, imagep);
+ if (changed)
+ {
+ gPipeline.markTextured(mDrawable);
+ mFaceMappingChanged = TRUE;
+ }
+}
+
void LLVOVolume::setTEImage(const U8 te, LLViewerTexture *imagep)
{
BOOL changed = (mTEImages[te] != imagep);
@@ -1811,13 +1889,17 @@ S32 LLVOVolume::setTEColor(const U8 te, const LLColor4& color)
const LLTextureEntry *tep = getTE(te);
if (!tep)
{
- llwarns << "No texture entry for te " << (S32)te << ", object " << mID << llendl;
+ LL_WARNS("MaterialTEs") << "No texture entry for te " << (S32)te << ", object " << mID << LL_ENDL;
}
else if (color != tep->getColor())
{
- if (color.mV[3] != tep->getColor().mV[3])
+ F32 old_alpha = tep->getColor().mV[3];
+ if (color.mV[3] != old_alpha)
{
gPipeline.markTextured(mDrawable);
+ //treat this alpha change as an LoD update since render batches may need to get rebuilt
+ mLODChanged = TRUE;
+ gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, FALSE);
}
retval = LLPrimitive::setTEColor(te, color);
if (mDrawable.notNull() && retval)
@@ -1919,6 +2001,62 @@ S32 LLVOVolume::setTEGlow(const U8 te, const F32 glow)
return res;
}
+void LLVOVolume::setTEMaterialParamsCallbackTE(const LLUUID& objectID, const LLMaterialID &pMaterialID, const LLMaterialPtr pMaterialParams, U32 te)
+{
+ LLVOVolume* pVol = (LLVOVolume*)gObjectList.findObject(objectID);
+ if (pVol)
+ {
+ LL_DEBUGS("MaterialTEs") << "materialid " << pMaterialID.asString() << " to TE " << te << LL_ENDL;
+ if (te >= pVol->getNumTEs())
+ return;
+
+ LLTextureEntry* texture_entry = pVol->getTE(te);
+ if (texture_entry && (texture_entry->getMaterialID() == pMaterialID))
+ {
+ pVol->setTEMaterialParams(te, pMaterialParams);
+ }
+ }
+}
+
+S32 LLVOVolume::setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID)
+{
+ S32 res = LLViewerObject::setTEMaterialID(te, pMaterialID);
+ LL_DEBUGS("MaterialTEs") << "te "<< (S32)te << " materialid " << pMaterialID.asString() << " res " << res
+ << ( LLSelectMgr::getInstance()->getSelection()->contains(const_cast<LLVOVolume*>(this), te) ? " selected" : " not selected" )
+ << LL_ENDL;
+
+ LL_DEBUGS("MaterialTEs") << " " << pMaterialID.asString() << LL_ENDL;
+ if (res)
+ {
+ LLMaterialMgr::instance().getTE(getRegion()->getRegionID(), pMaterialID, te, boost::bind(&LLVOVolume::setTEMaterialParamsCallbackTE, getID(), _1, _2, _3));
+
+ setChanged(ALL_CHANGED);
+ if (!mDrawable.isNull())
+ {
+ gPipeline.markTextured(mDrawable);
+ gPipeline.markRebuild(mDrawable,LLDrawable::REBUILD_ALL);
+ }
+ mFaceMappingChanged = TRUE;
+ }
+ return res;
+}
+
+S32 LLVOVolume::setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams)
+{
+ S32 res = LLViewerObject::setTEMaterialParams(te, pMaterialParams);
+ LL_DEBUGS("MaterialTEs") << "te " << (S32)te << " material " << ((pMaterialParams) ? pMaterialParams->asLLSD() : LLSD("null")) << " res " << res
+ << ( LLSelectMgr::getInstance()->getSelection()->contains(const_cast<LLVOVolume*>(this), te) ? " selected" : " not selected" )
+ << LL_ENDL;
+ setChanged(ALL_CHANGED);
+ if (!mDrawable.isNull())
+ {
+ gPipeline.markTextured(mDrawable);
+ gPipeline.markRebuild(mDrawable,LLDrawable::REBUILD_ALL);
+ }
+ mFaceMappingChanged = TRUE;
+ return TEM_CHANGE_TEXTURE;
+}
+
S32 LLVOVolume::setTEScale(const U8 te, const F32 s, const F32 t)
{
S32 res = LLViewerObject::setTEScale(te, s, t);
@@ -2386,7 +2524,12 @@ void LLVOVolume::addMediaImpl(LLViewerMediaImpl* media_impl, S32 texture_index)
//add the face to show the media if it is in playing
if(mDrawable)
{
- LLFace* facep = mDrawable->getFace(texture_index) ;
+ LLFace* facep(NULL);
+ if( texture_index < mDrawable->getNumFaces() )
+ {
+ facep = mDrawable->getFace(texture_index) ;
+ }
+
if(facep)
{
LLViewerMediaTexture* media_tex = LLViewerTextureManager::findMediaTexture(mMediaImplList[texture_index]->getMediaTextureID()) ;
@@ -2669,7 +2812,7 @@ void LLVOVolume::updateSpotLightPriority()
if (mLightTexture.notNull())
{
mLightTexture->addTextureStats(mSpotLightPriority);
- mLightTexture->setBoostLevel(LLViewerTexture::BOOST_CLOUDS);
+ mLightTexture->setBoostLevel(LLGLTexture::BOOST_CLOUDS);
}
}
@@ -2900,7 +3043,7 @@ void LLVOVolume::generateSilhouette(LLSelectNode* nodep, const LLVector3& view_p
//transform view vector into volume space
view_vector -= getRenderPosition();
- mDrawable->mDistanceWRTCamera = view_vector.length();
+ //mDrawable->mDistanceWRTCamera = view_vector.length();
LLQuaternion worldRot = getRenderRotation();
view_vector = view_vector * ~worldRot;
if (!isVolumeGlobal())
@@ -3098,6 +3241,7 @@ U32 LLVOVolume::getRenderCost(texture_cost_t &textures) const
for (S32 i = 0; i < num_faces; ++i)
{
const LLFace* face = drawablep->getFace(i);
+ if (!face) continue;
const LLTextureEntry* te = face->getTextureEntry();
const LLViewerTexture* img = face->getTexture();
@@ -3369,6 +3513,7 @@ F32 LLVOVolume::getBinRadius()
for (S32 i = 0; i < mDrawable->getNumFaces(); i++)
{
LLFace* face = mDrawable->getFace(i);
+ if (!face) continue;
if (face->getPoolType() == LLDrawPool::POOL_ALPHA &&
!face->canRenderAsMask())
{
@@ -3400,7 +3545,12 @@ F32 LLVOVolume::getBinRadius()
}
else if (mDrawable->isStatic())
{
- radius = llmax((S32) mDrawable->getRadius(), 1)*size_factor;
+ F32 szf = size_factor;
+
+ radius = llmax(mDrawable->getRadius(), szf);
+
+ radius = powf(radius, 1.f+szf/radius);
+
radius *= 1.f + mDrawable->mDistanceWRTCamera * distance_factor[1];
radius += mDrawable->mDistanceWRTCamera * distance_factor[0];
}
@@ -3450,9 +3600,12 @@ LLVector3 LLVOVolume::agentPositionToVolume(const LLVector3& pos) const
{
LLVector3 ret = pos - getRenderPosition();
ret = ret * ~getRenderRotation();
- LLVector3 objScale = isVolumeGlobal() ? LLVector3(1,1,1) : getScale();
- LLVector3 invObjScale(1.f / objScale.mV[VX], 1.f / objScale.mV[VY], 1.f / objScale.mV[VZ]);
- ret.scaleVec(invObjScale);
+ if (!isVolumeGlobal())
+ {
+ LLVector3 objScale = getScale();
+ LLVector3 invObjScale(1.f / objScale.mV[VX], 1.f / objScale.mV[VY], 1.f / objScale.mV[VZ]);
+ ret.scaleVec(invObjScale);
+ }
return ret;
}
@@ -3470,8 +3623,12 @@ LLVector3 LLVOVolume::agentDirectionToVolume(const LLVector3& dir) const
LLVector3 LLVOVolume::volumePositionToAgent(const LLVector3& dir) const
{
LLVector3 ret = dir;
- LLVector3 objScale = isVolumeGlobal() ? LLVector3(1,1,1) : getScale();
- ret.scaleVec(objScale);
+ if (!isVolumeGlobal())
+ {
+ LLVector3 objScale = getScale();
+ ret.scaleVec(objScale);
+ }
+
ret = ret * getRenderRotation();
ret += getRenderPosition();
@@ -3490,8 +3647,8 @@ LLVector3 LLVOVolume::volumeDirectionToAgent(const LLVector3& dir) const
}
-BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, S32 face, BOOL pick_transparent, S32 *face_hitp,
- LLVector3* intersection,LLVector2* tex_coord, LLVector3* normal, LLVector3* bi_normal)
+BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face, BOOL pick_transparent, S32 *face_hitp,
+ LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent)
{
if (!mbCanSelect
@@ -3512,7 +3669,6 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e
if (LLFloater::isVisible(gFloaterTools) && getAvatar()->isSelf())
{
updateRiggedVolume();
- genBBoxes(FALSE);
volume = mRiggedVolume;
transform = false;
}
@@ -3524,23 +3680,25 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e
if (volume)
{
- LLVector3 v_start, v_end, v_dir;
-
+ LLVector4a local_start = start;
+ LLVector4a local_end = end;
+
if (transform)
{
- v_start = agentPositionToVolume(start);
- v_end = agentPositionToVolume(end);
- }
- else
- {
- v_start = start;
- v_end = end;
- }
+ LLVector3 v_start(start.getF32ptr());
+ LLVector3 v_end(end.getF32ptr());
- LLVector3 p;
- LLVector3 n;
+ v_start = agentPositionToVolume(v_start);
+ v_end = agentPositionToVolume(v_end);
+
+ local_start.load3(v_start.mV);
+ local_end.load3(v_end.mV);
+ }
+
+ LLVector4a p;
+ LLVector4a n;
LLVector2 tc;
- LLVector3 bn;
+ LLVector4a tn;
if (intersection != NULL)
{
@@ -3557,9 +3715,9 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e
n = *normal;
}
- if (bi_normal != NULL)
+ if (tangent != NULL)
{
- bn = *bi_normal;
+ tn = *tangent;
}
S32 face_hit = -1;
@@ -3585,16 +3743,17 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e
continue;
}
- face_hit = volume->lineSegmentIntersect(v_start, v_end, i,
- &p, &tc, &n, &bn);
+ face_hit = volume->lineSegmentIntersect(local_start, local_end, i,
+ &p, &tc, &n, &tn);
if (face_hit >= 0 && mDrawable->getNumFaces() > face_hit)
{
LLFace* face = mDrawable->getFace(face_hit);
- if (pick_transparent || !face->getTexture() || !face->getTexture()->hasGLTexture() || face->getTexture()->getMask(face->surfaceToTexture(tc, p, n)))
+ if (face &&
+ (pick_transparent || !face->getTexture() || !face->getTexture()->hasGLTexture() || face->getTexture()->getMask(face->surfaceToTexture(tc, p, n))))
{
- v_end = p;
+ local_end = p;
if (face_hitp != NULL)
{
*face_hitp = face_hit;
@@ -3604,7 +3763,9 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e
{
if (transform)
{
- *intersection = volumePositionToAgent(p); // must map back to agent space
+ LLVector3 v_p(p.getF32ptr());
+
+ intersection->load3(volumePositionToAgent(v_p).mV); // must map back to agent space
}
else
{
@@ -3616,27 +3777,36 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e
{
if (transform)
{
- *normal = volumeDirectionToAgent(n);
+ LLVector3 v_n(n.getF32ptr());
+ normal->load3(volumeDirectionToAgent(v_n).mV);
}
else
{
*normal = n;
}
-
- (*normal).normVec();
+ (*normal).normalize3fast();
}
- if (bi_normal != NULL)
+ if (tangent != NULL)
{
if (transform)
{
- *bi_normal = volumeDirectionToAgent(bn);
+ LLVector3 v_tn(tn.getF32ptr());
+
+ LLVector4a trans_tangent;
+ trans_tangent.load3(volumeDirectionToAgent(v_tn).mV);
+
+ LLVector4Logical mask;
+ mask.clear();
+ mask.setElement<3>();
+
+ tangent->setSelectWithMask(mask, tn, trans_tangent);
}
else
{
- *bi_normal = bn;
+ *tangent = tn;
}
- (*bi_normal).normVec();
+ (*tangent).normalize3fast();
}
if (tex_coord != NULL)
@@ -3747,10 +3917,13 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons
}
//build matrix palette
- LLMatrix4a mp[64];
+ static const size_t kMaxJoints = 64;
+
+ LLMatrix4a mp[kMaxJoints];
LLMatrix4* mat = (LLMatrix4*) mp;
- for (U32 j = 0; j < skin->mJointNames.size(); ++j)
+ U32 maxJoints = llmin(skin->mJointNames.size(), kMaxJoints);
+ for (U32 j = 0; j < maxJoints; ++j)
{
LLJoint* joint = avatar->getJoint(skin->mJointNames[j]);
if (joint)
@@ -3768,82 +3941,88 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons
LLVector4a* weight = vol_face.mWeights;
- LLMatrix4a bind_shape_matrix;
- bind_shape_matrix.loadu(skin->mBindShapeMatrix);
-
- LLVector4a* pos = dst_face.mPositions;
-
+ if ( weight )
{
- LLFastTimer t(FTM_SKIN_RIGGED);
-
- for (U32 j = 0; j < dst_face.mNumVertices; ++j)
- {
- LLMatrix4a final_mat;
- final_mat.clear();
+ LLMatrix4a bind_shape_matrix;
+ bind_shape_matrix.loadu(skin->mBindShapeMatrix);
- S32 idx[4];
+ LLVector4a* pos = dst_face.mPositions;
- LLVector4 wght;
+ if( pos && weight && dst_face.mExtents )
+ {
+ LLFastTimer t(FTM_SKIN_RIGGED);
- F32 scale = 0.f;
- for (U32 k = 0; k < 4; k++)
+ for (U32 j = 0; j < dst_face.mNumVertices; ++j)
{
- F32 w = weight[j][k];
+ LLMatrix4a final_mat;
+ final_mat.clear();
- idx[k] = (S32) floorf(w);
- wght[k] = w - floorf(w);
- scale += wght[k];
- }
+ S32 idx[4];
- wght *= 1.f/scale;
+ LLVector4 wght;
- for (U32 k = 0; k < 4; k++)
- {
- F32 w = wght[k];
+ F32 scale = 0.f;
+ for (U32 k = 0; k < 4; k++)
+ {
+ F32 w = weight[j][k];
- LLMatrix4a src;
- src.setMul(mp[idx[k]], w);
+ idx[k] = (S32) floorf(w);
+ wght[k] = w - floorf(w);
+ scale += wght[k];
+ }
- final_mat.add(src);
- }
+ wght *= 1.f/scale;
+
+ for (U32 k = 0; k < 4; k++)
+ {
+ F32 w = wght[k];
+
+ LLMatrix4a src;
+ // Insure ref'd bone is in our clamped array of mats
+ llassert(idx[k] < kMaxJoints);
+ // clamp k to kMaxJoints to avoid reading garbage off stack in release
+ src.setMul(mp[idx[(k < kMaxJoints) ? k : 0]], w);
+ final_mat.add(src);
+ }
- LLVector4a& v = vol_face.mPositions[j];
- LLVector4a t;
- LLVector4a dst;
- bind_shape_matrix.affineTransform(v, t);
- final_mat.affineTransform(t, dst);
- pos[j] = dst;
- }
+ LLVector4a& v = vol_face.mPositions[j];
+ LLVector4a t;
+ LLVector4a dst;
+ bind_shape_matrix.affineTransform(v, t);
+ final_mat.affineTransform(t, dst);
+ pos[j] = dst;
+ }
- //update bounding box
- LLVector4a& min = dst_face.mExtents[0];
- LLVector4a& max = dst_face.mExtents[1];
+ //update bounding box
+ LLVector4a& min = dst_face.mExtents[0];
+ LLVector4a& max = dst_face.mExtents[1];
- min = pos[0];
- max = pos[1];
+ min = pos[0];
+ max = pos[1];
- for (U32 j = 1; j < dst_face.mNumVertices; ++j)
- {
- min.setMin(min, pos[j]);
- max.setMax(max, pos[j]);
- }
+ for (U32 j = 1; j < dst_face.mNumVertices; ++j)
+ {
+ min.setMin(min, pos[j]);
+ max.setMax(max, pos[j]);
+ }
- dst_face.mCenter->setAdd(dst_face.mExtents[0], dst_face.mExtents[1]);
- dst_face.mCenter->mul(0.5f);
+ dst_face.mCenter->setAdd(dst_face.mExtents[0], dst_face.mExtents[1]);
+ dst_face.mCenter->mul(0.5f);
- }
+ }
- {
- LLFastTimer t(FTM_RIGGED_OCTREE);
- delete dst_face.mOctree;
- dst_face.mOctree = NULL;
+ {
+ LLFastTimer t(FTM_RIGGED_OCTREE);
+ delete dst_face.mOctree;
+ dst_face.mOctree = NULL;
- LLVector4a size;
- size.setSub(dst_face.mExtents[1], dst_face.mExtents[0]);
- size.splat(size.getLength3().getF32()*0.5f);
+ LLVector4a size;
+ size.setSub(dst_face.mExtents[1], dst_face.mExtents[0]);
+ size.splat(size.getLength3().getF32()*0.5f);
- dst_face.createOctree(1.f);
+ dst_face.createOctree(1.f);
+ }
}
}
}
@@ -3889,6 +4068,11 @@ bool can_batch_texture(LLFace* facep)
return false;
}
+ if (facep->getTextureEntry()->getMaterialParams().notNull())
+ { //materials don't work with texture batching yet
+ return false;
+ }
+
if (facep->getTexture() && facep->getTexture()->getPrimaryFormat() == GL_ALPHA)
{ //can't batch invisiprims
return false;
@@ -3902,10 +4086,16 @@ bool can_batch_texture(LLFace* facep)
return true;
}
+static LLFastTimer::DeclareTimer FTM_REGISTER_FACE("Register Face");
+
void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, U32 type)
{
- LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
-
+ LLFastTimer t(FTM_REGISTER_FACE);
+ if (type == LLRenderPass::PASS_ALPHA && facep->getTextureEntry()->getMaterialParams().notNull() && !facep->getVertexBuffer()->hasDataType(LLVertexBuffer::TYPE_TANGENT))
+ {
+ LL_WARNS("RenderMaterials") << "Oh no! No binormals for this alpha blended face!" << LL_ENDL;
+ }
+
if (facep->getViewerObject()->isSelected() && LLSelectMgr::getInstance()->mHideSelectedObjects)
{
return;
@@ -3918,7 +4108,9 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
BOOL fullbright = (type == LLRenderPass::PASS_FULLBRIGHT) ||
(type == LLRenderPass::PASS_INVISIBLE) ||
- (type == LLRenderPass::PASS_ALPHA && facep->isState(LLFace::FULLBRIGHT));
+ (type == LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK) ||
+ (type == LLRenderPass::PASS_ALPHA && facep->isState(LLFace::FULLBRIGHT)) ||
+ (facep->getTextureEntry()->getFullbright());
if (!fullbright && type != LLRenderPass::PASS_GLOW && !facep->getVertexBuffer()->hasDataType(LLVertexBuffer::TYPE_NORMAL))
{
@@ -3935,30 +4127,56 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
const LLMatrix4* model_mat = NULL;
LLDrawable* drawable = facep->getDrawable();
- if (drawable->isActive())
+
+ if (drawable->isState(LLDrawable::ANIMATED_CHILD))
+ {
+ model_mat = &drawable->getWorldMatrix();
+ }
+ else if (drawable->isActive())
{
- model_mat = &(drawable->getRenderMatrix());
+ model_mat = &drawable->getRenderMatrix();
}
else
{
model_mat = &(drawable->getRegion()->mRenderMatrix);
- if (model_mat->isIdentity())
- {
- model_mat = NULL;
- }
}
+ //drawable->getVObj()->setDebugText(llformat("%d", drawable->isState(LLDrawable::ANIMATED_CHILD)));
+
U8 bump = (type == LLRenderPass::PASS_BUMP || type == LLRenderPass::PASS_POST_BUMP) ? facep->getTextureEntry()->getBumpmap() : 0;
-
+ U8 shiny = facep->getTextureEntry()->getShiny();
+
LLViewerTexture* tex = facep->getTexture();
U8 index = facep->getTextureIndex();
+
+ LLMaterial* mat = facep->getTextureEntry()->getMaterialParams().get();
+ LLMaterialID mat_id = facep->getTextureEntry()->getMaterialID();
bool batchable = false;
+ U32 shader_mask = 0xFFFFFFFF; //no shader
+
+ if (mat)
+ {
+ if (type == LLRenderPass::PASS_ALPHA)
+ {
+ shader_mask = mat->getShaderMask(LLMaterial::DIFFUSE_ALPHA_MODE_BLEND);
+ }
+ else
+ {
+ shader_mask = mat->getShaderMask();
+ }
+ }
+
+
if (index < 255 && idx >= 0)
{
- if (index < draw_vec[idx]->mTextureList.size())
+ if (mat || draw_vec[idx]->mMaterial)
+ { //can't batch textures when materials are present (yet)
+ batchable = false;
+ }
+ else if (index < draw_vec[idx]->mTextureList.size())
{
if (draw_vec[idx]->mTextureList[index].isNull())
{
@@ -3984,16 +4202,20 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
draw_vec[idx]->mEnd - draw_vec[idx]->mStart + facep->getGeomCount() <= (U32) gGLManager.mGLMaxVertexRange &&
draw_vec[idx]->mCount + facep->getIndicesCount() <= (U32) gGLManager.mGLMaxIndexRange &&
#endif
+ draw_vec[idx]->mMaterial == mat &&
+ draw_vec[idx]->mMaterialID == mat_id &&
draw_vec[idx]->mFullbright == fullbright &&
- draw_vec[idx]->mBump == bump &&
+ draw_vec[idx]->mBump == bump &&
+ (!mat || (draw_vec[idx]->mShiny == shiny)) && // need to break batches when a material is shared, but legacy settings are different
draw_vec[idx]->mTextureMatrix == tex_mat &&
- draw_vec[idx]->mModelMatrix == model_mat)
+ draw_vec[idx]->mModelMatrix == model_mat &&
+ draw_vec[idx]->mShaderMask == shader_mask)
{
draw_vec[idx]->mCount += facep->getIndicesCount();
draw_vec[idx]->mEnd += facep->getGeomCount();
draw_vec[idx]->mVSize = llmax(draw_vec[idx]->mVSize, facep->getVirtualSize());
- if (index >= draw_vec[idx]->mTextureList.size())
+ if (index < 255 && index >= draw_vec[idx]->mTextureList.size())
{
draw_vec[idx]->mTextureList.resize(index+1);
draw_vec[idx]->mTextureList[index] = tex;
@@ -4009,12 +4231,66 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
U32 offset = facep->getIndicesStart();
U32 count = facep->getIndicesCount();
LLPointer<LLDrawInfo> draw_info = new LLDrawInfo(start,end,count,offset, tex,
- facep->getVertexBuffer(), fullbright, bump);
+ facep->getVertexBuffer(), fullbright, bump);
draw_info->mGroup = group;
draw_info->mVSize = facep->getVirtualSize();
draw_vec.push_back(draw_info);
draw_info->mTextureMatrix = tex_mat;
draw_info->mModelMatrix = model_mat;
+
+ draw_info->mBump = bump;
+ draw_info->mShiny = shiny;
+
+ float alpha[4] =
+ {
+ 0.00f,
+ 0.25f,
+ 0.5f,
+ 0.75f
+ };
+ float spec = alpha[shiny & TEM_SHINY_MASK];
+ LLVector4 specColor(spec, spec, spec, spec);
+ draw_info->mSpecColor = specColor;
+ draw_info->mEnvIntensity = spec;
+ draw_info->mSpecularMap = NULL;
+ draw_info->mMaterial = mat;
+ draw_info->mShaderMask = shader_mask;
+
+ if (mat)
+ {
+ draw_info->mMaterialID = mat_id;
+
+ // We have a material. Update our draw info accordingly.
+
+ if (!mat->getSpecularID().isNull())
+ {
+ LLVector4 specColor;
+ specColor.mV[0] = mat->getSpecularLightColor().mV[0] * (1.f / 255.f);
+ specColor.mV[1] = mat->getSpecularLightColor().mV[1] * (1.f / 255.f);
+ specColor.mV[2] = mat->getSpecularLightColor().mV[2] * (1.f / 255.f);
+ specColor.mV[3] = mat->getSpecularLightExponent() * (1.f / 255.f);
+ draw_info->mSpecColor = specColor;
+ draw_info->mEnvIntensity = mat->getEnvironmentIntensity() * (1.f / 255.f);
+ draw_info->mSpecularMap = facep->getViewerObject()->getTESpecularMap(facep->getTEOffset());
+ }
+
+ draw_info->mAlphaMaskCutoff = mat->getAlphaMaskCutoff() * (1.f / 255.f);
+ draw_info->mDiffuseAlphaMode = mat->getDiffuseAlphaMode();
+ draw_info->mNormalMap = facep->getViewerObject()->getTENormalMap(facep->getTEOffset());
+
+ }
+ else
+ {
+ if (type == LLRenderPass::PASS_GRASS)
+ {
+ draw_info->mAlphaMaskCutoff = 0.5f;
+ }
+ else
+ {
+ draw_info->mAlphaMaskCutoff = 0.33f;
+ }
+ }
+
if (type == LLRenderPass::PASS_ALPHA)
{ //for alpha sorting
facep->setDrawInfo(draw_info);
@@ -4041,8 +4317,9 @@ void LLVolumeGeometryManager::getGeometry(LLSpatialGroup* group)
}
-static LLFastTimer::DeclareTimer FTM_REBUILD_VOLUME_VB("Volume");
-static LLFastTimer::DeclareTimer FTM_REBUILD_VBO("VBO Rebuilt");
+static LLFastTimer::DeclareTimer FTM_REBUILD_VOLUME_VB("Volume VB");
+static LLFastTimer::DeclareTimer FTM_REBUILD_VOLUME_FACE_LIST("Build Face List");
+static LLFastTimer::DeclareTimer FTM_REBUILD_VOLUME_GEN_DRAW_INFO("Gen Draw Info");
static LLDrawPoolAvatar* get_avatar_drawpool(LLViewerObject* vobj)
{
@@ -4073,6 +4350,8 @@ static LLDrawPoolAvatar* get_avatar_drawpool(LLViewerObject* vobj)
void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
{
+
+
if (group->changeLOD())
{
group->mLastUpdateDistance = group->mDistance;
@@ -4084,19 +4363,15 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
{
if (group->isState(LLSpatialGroup::MESH_DIRTY) && !LLPipeline::sDelayVBUpdate)
{
- LLFastTimer ftm(FTM_REBUILD_VBO);
- LLFastTimer ftm2(FTM_REBUILD_VOLUME_VB);
-
rebuildMesh(group);
}
return;
}
- group->mBuilt = 1.f;
- LLFastTimer ftm(FTM_REBUILD_VBO);
-
- LLFastTimer ftm2(FTM_REBUILD_VOLUME_VB);
+ LLFastTimer ftm(FTM_REBUILD_VOLUME_VB);
+ group->mBuilt = 1.f;
+
LLVOAvatar* pAvatarVO = NULL;
LLSpatialBridge* bridge = group->mSpatialPartition->asBridge();
@@ -4117,21 +4392,40 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
if (pAvatarVO)
{
pAvatarVO->mAttachmentGeometryBytes -= group->mGeometryBytes;
+ pAvatarVO->mAttachmentGeometryBytes = llmax(pAvatarVO->mAttachmentGeometryBytes, 0);
pAvatarVO->mAttachmentSurfaceArea -= group->mSurfaceArea;
+ pAvatarVO->mAttachmentSurfaceArea = llmax(pAvatarVO->mAttachmentSurfaceArea, 0.f);
}
group->mGeometryBytes = 0;
group->mSurfaceArea = 0;
+ //cache object box size since it might be used for determining visibility
+ group->mObjectBoxSize = group->mObjectBounds[1].getLength3().getF32();
+
group->clearDrawMap();
mFaceList.clear();
- std::vector<LLFace*> fullbright_faces;
- std::vector<LLFace*> bump_faces;
- std::vector<LLFace*> simple_faces;
+ const U32 MAX_FACE_COUNT = 4096;
+
+ static LLFace** fullbright_faces = (LLFace**) ll_aligned_malloc(MAX_FACE_COUNT*sizeof(LLFace*),64);
+ static LLFace** bump_faces = (LLFace**) ll_aligned_malloc(MAX_FACE_COUNT*sizeof(LLFace*),64);
+ static LLFace** simple_faces = (LLFace**) ll_aligned_malloc(MAX_FACE_COUNT*sizeof(LLFace*),64);
+ static LLFace** norm_faces = (LLFace**) ll_aligned_malloc(MAX_FACE_COUNT*sizeof(LLFace*), 64);
+ static LLFace** spec_faces = (LLFace**) ll_aligned_malloc(MAX_FACE_COUNT*sizeof(LLFace*), 64);
+ static LLFace** normspec_faces = (LLFace**) ll_aligned_malloc(MAX_FACE_COUNT*sizeof(LLFace*), 64);
+ static LLFace** alpha_faces = (LLFace**) ll_aligned_malloc(MAX_FACE_COUNT*sizeof(LLFace*),64);
+
+ U32 fullbright_count = 0;
+ U32 bump_count = 0;
+ U32 simple_count = 0;
+ U32 alpha_count = 0;
+ U32 norm_count = 0;
+ U32 spec_count = 0;
+ U32 normspec_count = 0;
+
- std::vector<LLFace*> alpha_faces;
U32 useage = group->mSpatialPartition->mBufferUsage;
U32 max_vertices = (gSavedSettings.getS32("RenderMaxVBOSize")*1024)/LLVertexBuffer::calcVertexSize(group->mSpatialPartition->mVertexDataMask);
@@ -4142,359 +4436,500 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
bool emissive = false;
- //get all the faces into a list
- for (LLSpatialGroup::element_iter drawable_iter = group->getData().begin(); drawable_iter != group->getData().end(); ++drawable_iter)
+
+
{
- LLDrawable* drawablep = *drawable_iter;
-
- if (drawablep->isDead() || drawablep->isState(LLDrawable::FORCE_INVISIBLE) )
+ LLFastTimer t(FTM_REBUILD_VOLUME_FACE_LIST);
+
+ //get all the faces into a list
+ for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter)
{
- continue;
- }
+ LLDrawable* drawablep = *drawable_iter;
+
+ if (drawablep->isDead() || drawablep->isState(LLDrawable::FORCE_INVISIBLE) )
+ {
+ continue;
+ }
- if (drawablep->isAnimating())
- { //fall back to stream draw for animating verts
- useage = GL_STREAM_DRAW_ARB;
- }
+ if (drawablep->isAnimating())
+ { //fall back to stream draw for animating verts
+ useage = GL_STREAM_DRAW_ARB;
+ }
- LLVOVolume* vobj = drawablep->getVOVolume();
+ LLVOVolume* vobj = drawablep->getVOVolume();
- if (!vobj)
- {
- continue;
- }
+ if (!vobj)
+ {
+ continue;
+ }
- if (vobj->isMesh() &&
- (vobj->getVolume() && !vobj->getVolume()->isMeshAssetLoaded() || !gMeshRepo.meshRezEnabled()))
- {
- continue;
- }
+ if (vobj->isMesh() &&
+ ((vobj->getVolume() && !vobj->getVolume()->isMeshAssetLoaded()) || !gMeshRepo.meshRezEnabled()))
+ {
+ continue;
+ }
- LLVolume* volume = vobj->getVolume();
- if (volume)
- {
- const LLVector3& scale = vobj->getScale();
- group->mSurfaceArea += volume->getSurfaceArea() * llmax(llmax(scale.mV[0], scale.mV[1]), scale.mV[2]);
- }
+ LLVolume* volume = vobj->getVolume();
+ if (volume)
+ {
+ const LLVector3& scale = vobj->getScale();
+ group->mSurfaceArea += volume->getSurfaceArea() * llmax(llmax(scale.mV[0], scale.mV[1]), scale.mV[2]);
+ }
- llassert_always(vobj);
- vobj->updateTextureVirtualSize(true);
- vobj->preRebuild();
+ llassert_always(vobj);
+ vobj->updateTextureVirtualSize(true);
+ vobj->preRebuild();
- drawablep->clearState(LLDrawable::HAS_ALPHA);
+ drawablep->clearState(LLDrawable::HAS_ALPHA);
- bool rigged = vobj->isAttachment() &&
- vobj->isMesh() &&
- gMeshRepo.getSkinInfo(vobj->getVolume()->getParams().getSculptID(), vobj);
+ bool rigged = vobj->isAttachment() &&
+ vobj->isMesh() &&
+ gMeshRepo.getSkinInfo(vobj->getVolume()->getParams().getSculptID(), vobj);
- bool bake_sunlight = LLPipeline::sBakeSunlight && drawablep->isStatic();
+ bool bake_sunlight = LLPipeline::sBakeSunlight && drawablep->isStatic();
- bool is_rigged = false;
+ bool is_rigged = false;
- //for each face
- for (S32 i = 0; i < drawablep->getNumFaces(); i++)
- {
- LLFace* facep = drawablep->getFace(i);
+ //for each face
+ for (S32 i = 0; i < drawablep->getNumFaces(); i++)
+ {
+ LLFace* facep = drawablep->getFace(i);
+ if (!facep)
+ {
+ continue;
+ }
- //ALWAYS null out vertex buffer on rebuild -- if the face lands in a render
- // batch, it will recover its vertex buffer reference from the spatial group
- facep->setVertexBuffer(NULL);
+ //ALWAYS null out vertex buffer on rebuild -- if the face lands in a render
+ // batch, it will recover its vertex buffer reference from the spatial group
+ facep->setVertexBuffer(NULL);
- //sum up face verts and indices
- drawablep->updateFaceSize(i);
+ //sum up face verts and indices
+ drawablep->updateFaceSize(i);
- if (rigged)
- {
- if (!facep->isState(LLFace::RIGGED))
- { //completely reset vertex buffer
- facep->clearVertexBuffer();
- }
+ if (rigged)
+ {
+ if (!facep->isState(LLFace::RIGGED))
+ { //completely reset vertex buffer
+ facep->clearVertexBuffer();
+ }
- facep->setState(LLFace::RIGGED);
- is_rigged = true;
+ facep->setState(LLFace::RIGGED);
+ is_rigged = true;
- //get drawpool of avatar with rigged face
- LLDrawPoolAvatar* pool = get_avatar_drawpool(vobj);
+ //get drawpool of avatar with rigged face
+ LLDrawPoolAvatar* pool = get_avatar_drawpool(vobj);
- //Determine if we've received skininfo that contains an
- //alternate bind matrix - if it does then apply the translational component
- //to the joints of the avatar.
- bool pelvisGotSet = false;
+ //Determine if we've received skininfo that contains an
+ //alternate bind matrix - if it does then apply the translational component
+ //to the joints of the avatar.
+ bool pelvisGotSet = false;
- if ( pAvatarVO )
- {
- LLUUID currentId = vobj->getVolume()->getParams().getSculptID();
- const LLMeshSkinInfo* pSkinData = gMeshRepo.getSkinInfo( currentId, vobj );
-
- if ( pSkinData )
+ if ( pAvatarVO )
{
- const int bindCnt = pSkinData->mAlternateBindMatrix.size();
- if ( bindCnt > 0 )
- {
- const int jointCnt = pSkinData->mJointNames.size();
- const F32 pelvisZOffset = pSkinData->mPelvisOffset;
- bool fullRig = (jointCnt>=20) ? true : false;
- if ( fullRig )
- {
- for ( int i=0; i<jointCnt; ++i )
+ LLUUID currentId = vobj->getVolume()->getParams().getSculptID();
+ const LLMeshSkinInfo* pSkinData = gMeshRepo.getSkinInfo( currentId, vobj );
+
+ if ( pSkinData )
+ {
+ const int bindCnt = pSkinData->mAlternateBindMatrix.size();
+ if ( bindCnt > 0 )
+ {
+ const int jointCnt = pSkinData->mJointNames.size();
+ const F32 pelvisZOffset = pSkinData->mPelvisOffset;
+ bool fullRig = (jointCnt>=20) ? true : false;
+ if ( fullRig )
{
- std::string lookingForJoint = pSkinData->mJointNames[i].c_str();
- //llinfos<<"joint name "<<lookingForJoint.c_str()<<llendl;
- LLJoint* pJoint = pAvatarVO->getJoint( lookingForJoint );
- if ( pJoint && pJoint->getId() != currentId )
- {
- pJoint->setId( currentId );
- const LLVector3& jointPos = pSkinData->mAlternateBindMatrix[i].getTranslation();
- //Set the joint position
- pJoint->storeCurrentXform( jointPos );
- //If joint is a pelvis then handle old/new pelvis to foot values
- if ( lookingForJoint == "mPelvis" )
- {
+ for ( int i=0; i<jointCnt; ++i )
+ {
+ std::string lookingForJoint = pSkinData->mJointNames[i].c_str();
+ //llinfos<<"joint name "<<lookingForJoint.c_str()<<llendl;
+ LLJoint* pJoint = pAvatarVO->getJoint( lookingForJoint );
+ if ( pJoint && pJoint->getId() != currentId )
+ {
+ pJoint->setId( currentId );
+ const LLVector3& jointPos = pSkinData->mAlternateBindMatrix[i].getTranslation();
+ //Set the joint position
pJoint->storeCurrentXform( jointPos );
- if ( !pAvatarVO->hasPelvisOffset() )
- {
- pAvatarVO->setPelvisOffset( true, jointPos, pelvisZOffset );
- //Trigger to rebuild viewer AV
- pelvisGotSet = true;
+ //If joint is a pelvis then handle old/new pelvis to foot values
+ if ( lookingForJoint == "mPelvis" )
+ {
+ pJoint->storeCurrentXform( jointPos );
+ if ( !pAvatarVO->hasPelvisOffset() )
+ {
+ pAvatarVO->setPelvisOffset( true, jointPos, pelvisZOffset );
+ //Trigger to rebuild viewer AV
+ pelvisGotSet = true;
+ }
}
- }
+ }
}
- }
- }
+ }
+ }
}
}
- }
- //If we've set the pelvis to a new position we need to also rebuild some information that the
- //viewer does at launch (e.g. body size etc.)
- if ( pelvisGotSet )
- {
- pAvatarVO->postPelvisSetRecalc();
- }
-
- if (pool)
- {
- const LLTextureEntry* te = facep->getTextureEntry();
-
- //remove face from old pool if it exists
- LLDrawPool* old_pool = facep->getPool();
- if (old_pool && old_pool->getType() == LLDrawPool::POOL_AVATAR)
+ //If we've set the pelvis to a new position we need to also rebuild some information that the
+ //viewer does at launch (e.g. body size etc.)
+ if ( pelvisGotSet )
{
- ((LLDrawPoolAvatar*) old_pool)->removeRiggedFace(facep);
+ pAvatarVO->postPelvisSetRecalc();
}
- //add face to new pool
- LLViewerTexture* tex = facep->getTexture();
- U32 type = gPipeline.getPoolTypeFromTE(te, tex);
-
- if (type == LLDrawPool::POOL_ALPHA)
+ if (pool)
{
- if (te->getColor().mV[3] > 0.f)
+ const LLTextureEntry* te = facep->getTextureEntry();
+
+ //remove face from old pool if it exists
+ LLDrawPool* old_pool = facep->getPool();
+ if (old_pool && old_pool->getType() == LLDrawPool::POOL_AVATAR)
{
- if (te->getFullbright())
- {
- pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT_ALPHA);
- }
- else
- {
- pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_ALPHA);
- }
+ ((LLDrawPoolAvatar*) old_pool)->removeRiggedFace(facep);
}
- }
- else if (te->getShiny())
- {
- if (te->getFullbright())
+
+ //add face to new pool
+ LLViewerTexture* tex = facep->getTexture();
+ U32 type = gPipeline.getPoolTypeFromTE(te, tex);
+
+
+ if (te->getGlow())
{
- pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT_SHINY);
+ pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_GLOW);
}
- else
+
+ LLMaterial* mat = te->getMaterialParams().get();
+
+ if (mat && LLPipeline::sRenderDeferred)
{
- if (LLPipeline::sRenderDeferred)
+ U8 alpha_mode = mat->getDiffuseAlphaMode();
+
+ bool is_alpha = type == LLDrawPool::POOL_ALPHA &&
+ (alpha_mode == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND ||
+ te->getColor().mV[3] < 0.999f);
+
+ if (is_alpha)
+ { //this face needs alpha blending, override alpha mode
+ alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_BLEND;
+ }
+
+ if (!is_alpha || te->getColor().mV[3] > 0.f) // //only add the face if it will actually be visible
+ {
+ U32 mask = mat->getShaderMask(alpha_mode);
+ pool->addRiggedFace(facep, mask);
+ }
+ }
+ else if (mat)
+ {
+ bool fullbright = te->getFullbright();
+ bool is_alpha = type == LLDrawPool::POOL_ALPHA;
+ U8 mode = mat->getDiffuseAlphaMode();
+ bool can_be_shiny = mode == LLMaterial::DIFFUSE_ALPHA_MODE_NONE ||
+ mode == LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE;
+
+ if (mode == LLMaterial::DIFFUSE_ALPHA_MODE_MASK && te->getColor().mV[3] >= 0.999f)
{
- pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SIMPLE);
+ pool->addRiggedFace(facep, fullbright ? LLDrawPoolAvatar::RIGGED_FULLBRIGHT : LLDrawPoolAvatar::RIGGED_SIMPLE);
+ }
+ else if (is_alpha || (te->getColor().mV[3] < 0.999f))
+ {
+ if (te->getColor().mV[3] > 0.f)
+ {
+ pool->addRiggedFace(facep, fullbright ? LLDrawPoolAvatar::RIGGED_FULLBRIGHT_ALPHA : LLDrawPoolAvatar::RIGGED_ALPHA);
+ }
+ }
+ else if (gPipeline.canUseVertexShaders()
+ && LLPipeline::sRenderBump
+ && te->getShiny()
+ && can_be_shiny)
+ {
+ pool->addRiggedFace(facep, fullbright ? LLDrawPoolAvatar::RIGGED_FULLBRIGHT_SHINY : LLDrawPoolAvatar::RIGGED_SHINY);
}
else
{
- pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SHINY);
+ pool->addRiggedFace(facep, fullbright ? LLDrawPoolAvatar::RIGGED_FULLBRIGHT : LLDrawPoolAvatar::RIGGED_SIMPLE);
}
}
- }
- else
- {
- if (te->getFullbright())
- {
- pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT);
- }
else
{
- pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SIMPLE);
- }
- }
-
- if (te->getGlow())
- {
- pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_GLOW);
- }
-
- if (LLPipeline::sRenderDeferred)
- {
- if (type != LLDrawPool::POOL_ALPHA && !te->getFullbright())
- {
- if (te->getBumpmap())
+ if (type == LLDrawPool::POOL_ALPHA)
{
- pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_DEFERRED_BUMP);
+ if (te->getColor().mV[3] > 0.f)
+ {
+ if (te->getFullbright())
+ {
+ pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT_ALPHA);
+ }
+ else
+ {
+ pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_ALPHA);
+ }
+ }
+ }
+ else if (te->getShiny())
+ {
+ if (te->getFullbright())
+ {
+ pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT_SHINY);
+ }
+ else
+ {
+ if (LLPipeline::sRenderDeferred)
+ {
+ pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SIMPLE);
+ }
+ else
+ {
+ pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SHINY);
+ }
+ }
}
else
{
- pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_DEFERRED_SIMPLE);
+ if (te->getFullbright())
+ {
+ pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT);
+ }
+ else
+ {
+ pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SIMPLE);
+ }
+ }
+
+
+ if (LLPipeline::sRenderDeferred)
+ {
+ if (type != LLDrawPool::POOL_ALPHA && !te->getFullbright())
+ {
+ if (te->getBumpmap())
+ {
+ pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_DEFERRED_BUMP);
+ }
+ else
+ {
+ pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_DEFERRED_SIMPLE);
+ }
+ }
}
}
}
- }
- continue;
- }
- else
- {
- if (facep->isState(LLFace::RIGGED))
- { //face is not rigged but used to be, remove from rigged face pool
- LLDrawPoolAvatar* pool = (LLDrawPoolAvatar*) facep->getPool();
- if (pool)
- {
- pool->removeRiggedFace(facep);
+ continue;
+ }
+ else
+ {
+ if (facep->isState(LLFace::RIGGED))
+ { //face is not rigged but used to be, remove from rigged face pool
+ LLDrawPoolAvatar* pool = (LLDrawPoolAvatar*) facep->getPool();
+ if (pool)
+ {
+ pool->removeRiggedFace(facep);
+ }
+ facep->clearState(LLFace::RIGGED);
}
- facep->clearState(LLFace::RIGGED);
}
- }
- if (cur_total > max_total || facep->getIndicesCount() <= 0 || facep->getGeomCount() <= 0)
- {
- facep->clearVertexBuffer();
- continue;
- }
-
- cur_total += facep->getGeomCount();
-
- if (facep->hasGeometry() && facep->getPixelArea() > FORCE_CULL_AREA)
- {
- const LLTextureEntry* te = facep->getTextureEntry();
- LLViewerTexture* tex = facep->getTexture();
-
- if (te->getGlow() >= 1.f/255.f)
+ if (cur_total > max_total || facep->getIndicesCount() <= 0 || facep->getGeomCount() <= 0)
{
- emissive = true;
+ facep->clearVertexBuffer();
+ continue;
}
- if (facep->isState(LLFace::TEXTURE_ANIM))
- {
- if (!vobj->mTexAnimMode)
- {
- facep->clearState(LLFace::TEXTURE_ANIM);
- }
- }
+ cur_total += facep->getGeomCount();
- BOOL force_simple = (facep->getPixelArea() < FORCE_SIMPLE_RENDER_AREA);
- U32 type = gPipeline.getPoolTypeFromTE(te, tex);
- if (type != LLDrawPool::POOL_ALPHA && force_simple)
+ if (facep->hasGeometry() && facep->getPixelArea() > FORCE_CULL_AREA)
{
- type = LLDrawPool::POOL_SIMPLE;
- }
- facep->setPoolType(type);
+ const LLTextureEntry* te = facep->getTextureEntry();
+ LLViewerTexture* tex = facep->getTexture();
- if (vobj->isHUDAttachment())
- {
- facep->setState(LLFace::FULLBRIGHT);
- }
+ if (te->getGlow() >= 1.f/255.f)
+ {
+ emissive = true;
+ }
- if (vobj->mTextureAnimp && vobj->mTexAnimMode)
- {
- if (vobj->mTextureAnimp->mFace <= -1)
+ if (facep->isState(LLFace::TEXTURE_ANIM))
{
- S32 face;
- for (face = 0; face < vobj->getNumTEs(); face++)
+ if (!vobj->mTexAnimMode)
{
- drawablep->getFace(face)->setState(LLFace::TEXTURE_ANIM);
+ facep->clearState(LLFace::TEXTURE_ANIM);
}
}
- else if (vobj->mTextureAnimp->mFace < vobj->getNumTEs())
+
+ BOOL force_simple = (facep->getPixelArea() < FORCE_SIMPLE_RENDER_AREA);
+ U32 type = gPipeline.getPoolTypeFromTE(te, tex);
+ if (type != LLDrawPool::POOL_ALPHA && force_simple)
{
- drawablep->getFace(vobj->mTextureAnimp->mFace)->setState(LLFace::TEXTURE_ANIM);
+ type = LLDrawPool::POOL_SIMPLE;
}
- }
+ facep->setPoolType(type);
- if (type == LLDrawPool::POOL_ALPHA)
- {
- if (facep->canRenderAsMask())
- { //can be treated as alpha mask
- simple_faces.push_back(facep);
- }
- else
+ if (vobj->isHUDAttachment())
{
- if (te->getColor().mV[3] > 0.f)
- { //only treat as alpha in the pipeline if < 100% transparent
- drawablep->setState(LLDrawable::HAS_ALPHA);
- }
- alpha_faces.push_back(facep);
+ facep->setState(LLFace::FULLBRIGHT);
}
- }
- else
- {
- if (drawablep->isState(LLDrawable::REBUILD_VOLUME))
+
+ if (vobj->mTextureAnimp && vobj->mTexAnimMode)
{
- facep->mLastUpdateTime = gFrameTimeSeconds;
+ if (vobj->mTextureAnimp->mFace <= -1)
+ {
+ S32 face;
+ for (face = 0; face < vobj->getNumTEs(); face++)
+ {
+ LLFace * facep = drawablep->getFace(face);
+ if (facep)
+ {
+ facep->setState(LLFace::TEXTURE_ANIM);
+ }
+ }
+ }
+ else if (vobj->mTextureAnimp->mFace < vobj->getNumTEs())
+ {
+ LLFace * facep = drawablep->getFace(vobj->mTextureAnimp->mFace);
+ if (facep)
+ {
+ facep->setState(LLFace::TEXTURE_ANIM);
+ }
+ }
}
- if (gPipeline.canUseWindLightShadersOnObjects()
- && LLPipeline::sRenderBump)
+ if (type == LLDrawPool::POOL_ALPHA)
{
- if (te->getBumpmap())
- { //needs normal + binormal
- bump_faces.push_back(facep);
- }
- else if (te->getShiny() || !te->getFullbright())
- { //needs normal
- simple_faces.push_back(facep);
+ if (facep->canRenderAsMask())
+ { //can be treated as alpha mask
+ if (simple_count < MAX_FACE_COUNT)
+ {
+ simple_faces[simple_count++] = facep;
+ }
}
- else
- { //doesn't need normal
- facep->setState(LLFace::FULLBRIGHT);
- fullbright_faces.push_back(facep);
+ else
+ {
+ if (te->getColor().mV[3] > 0.f)
+ { //only treat as alpha in the pipeline if < 100% transparent
+ drawablep->setState(LLDrawable::HAS_ALPHA);
+ }
+ if (alpha_count < MAX_FACE_COUNT)
+ {
+ alpha_faces[alpha_count++] = facep;
+ }
}
}
else
{
- if (te->getBumpmap() && LLPipeline::sRenderBump)
- { //needs normal + binormal
- bump_faces.push_back(facep);
+ if (drawablep->isState(LLDrawable::REBUILD_VOLUME))
+ {
+ facep->mLastUpdateTime = gFrameTimeSeconds;
}
- else if ((te->getShiny() && LLPipeline::sRenderBump) ||
- !(te->getFullbright() || bake_sunlight))
- { //needs normal
- simple_faces.push_back(facep);
+
+ if (gPipeline.canUseWindLightShadersOnObjects()
+ && LLPipeline::sRenderBump)
+ {
+ if (LLPipeline::sRenderDeferred && te->getMaterialParams().notNull() && !te->getMaterialID().isNull())
+ {
+ LLMaterial* mat = te->getMaterialParams().get();
+ if (mat->getNormalID().notNull())
+ {
+ if (mat->getSpecularID().notNull())
+ { //has normal and specular maps (needs texcoord1, texcoord2, and tangent)
+ if (normspec_count < MAX_FACE_COUNT)
+ {
+ normspec_faces[normspec_count++] = facep;
+ }
+ }
+ else
+ { //has normal map (needs texcoord1 and tangent)
+ if (norm_count < MAX_FACE_COUNT)
+ {
+ norm_faces[norm_count++] = facep;
+ }
+ }
+ }
+ else if (mat->getSpecularID().notNull())
+ { //has specular map but no normal map, needs texcoord2
+ if (spec_count < MAX_FACE_COUNT)
+ {
+ spec_faces[spec_count++] = facep;
+ }
+ }
+ else
+ { //has neither specular map nor normal map, only needs texcoord0
+ if (simple_count < MAX_FACE_COUNT)
+ {
+ simple_faces[simple_count++] = facep;
+ }
+ }
+ }
+ else if (te->getBumpmap())
+ { //needs normal + tangent
+ if (bump_count < MAX_FACE_COUNT)
+ {
+ bump_faces[bump_count++] = facep;
+ }
+ }
+ else if (te->getShiny() || !te->getFullbright())
+ { //needs normal
+ if (simple_count < MAX_FACE_COUNT)
+ {
+ simple_faces[simple_count++] = facep;
+ }
+ }
+ else
+ { //doesn't need normal
+ facep->setState(LLFace::FULLBRIGHT);
+ if (fullbright_count < MAX_FACE_COUNT)
+ {
+ fullbright_faces[fullbright_count++] = facep;
+ }
+ }
}
- else
- { //doesn't need normal
- facep->setState(LLFace::FULLBRIGHT);
- fullbright_faces.push_back(facep);
+ else
+ {
+ if (te->getBumpmap() && LLPipeline::sRenderBump)
+ { //needs normal + tangent
+ if (bump_count < MAX_FACE_COUNT)
+ {
+ bump_faces[bump_count++] = facep;
+ }
+ }
+ else if ((te->getShiny() && LLPipeline::sRenderBump) ||
+ !(te->getFullbright() || bake_sunlight))
+ { //needs normal
+ if (simple_count < MAX_FACE_COUNT)
+ {
+ simple_faces[simple_count++] = facep;
+ }
+ }
+ else
+ { //doesn't need normal
+ facep->setState(LLFace::FULLBRIGHT);
+ if (fullbright_count < MAX_FACE_COUNT)
+ {
+ fullbright_faces[fullbright_count++] = facep;
+ }
+ }
}
}
}
+ else
+ { //face has no renderable geometry
+ facep->clearVertexBuffer();
+ }
}
- else
- { //face has no renderable geometry
- facep->clearVertexBuffer();
- }
- }
- if (is_rigged)
- {
- drawablep->setState(LLDrawable::RIGGED);
- }
- else
- {
- drawablep->clearState(LLDrawable::RIGGED);
+ if (is_rigged)
+ {
+ if (!drawablep->isState(LLDrawable::RIGGED))
+ {
+ drawablep->setState(LLDrawable::RIGGED);
+
+ //first time this is drawable is being marked as rigged,
+ // do another LoD update to use avatar bounding box
+ vobj->updateLOD();
+ }
+ }
+ else
+ {
+ drawablep->clearState(LLDrawable::RIGGED);
+ }
}
}
@@ -4506,37 +4941,43 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
U32 bump_mask = LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR;
U32 fullbright_mask = LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR;
+ U32 norm_mask = simple_mask | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TANGENT;
+ U32 normspec_mask = norm_mask | LLVertexBuffer::MAP_TEXCOORD2;
+ U32 spec_mask = simple_mask | LLVertexBuffer::MAP_TEXCOORD2;
+
if (emissive)
{ //emissive faces are present, include emissive byte to preserve batching
simple_mask = simple_mask | LLVertexBuffer::MAP_EMISSIVE;
alpha_mask = alpha_mask | LLVertexBuffer::MAP_EMISSIVE;
bump_mask = bump_mask | LLVertexBuffer::MAP_EMISSIVE;
fullbright_mask = fullbright_mask | LLVertexBuffer::MAP_EMISSIVE;
+ norm_mask = norm_mask | LLVertexBuffer::MAP_EMISSIVE;
+ normspec_mask = normspec_mask | LLVertexBuffer::MAP_EMISSIVE;
+ spec_mask = spec_mask | LLVertexBuffer::MAP_EMISSIVE;
}
- bool batch_textures = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 1;
+ BOOL batch_textures = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 1;
if (batch_textures)
{
- bump_mask |= LLVertexBuffer::MAP_BINORMAL;
- genDrawInfo(group, simple_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, simple_faces, FALSE, TRUE);
- genDrawInfo(group, fullbright_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, fullbright_faces, FALSE, TRUE);
- genDrawInfo(group, bump_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, bump_faces, FALSE, TRUE);
- genDrawInfo(group, alpha_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, alpha_faces, TRUE, TRUE);
- }
- else
- {
- genDrawInfo(group, simple_mask, simple_faces);
- genDrawInfo(group, fullbright_mask, fullbright_faces);
- genDrawInfo(group, bump_mask, bump_faces, FALSE, TRUE);
- genDrawInfo(group, alpha_mask, alpha_faces, TRUE);
+ bump_mask = bump_mask | LLVertexBuffer::MAP_TANGENT;
+ simple_mask = simple_mask | LLVertexBuffer::MAP_TEXTURE_INDEX;
+ alpha_mask = alpha_mask | LLVertexBuffer::MAP_TEXTURE_INDEX | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2;
+ fullbright_mask = fullbright_mask | LLVertexBuffer::MAP_TEXTURE_INDEX;
}
-
+
+ genDrawInfo(group, simple_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, simple_faces, simple_count, FALSE, batch_textures, FALSE);
+ genDrawInfo(group, fullbright_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, fullbright_faces, fullbright_count, FALSE, batch_textures);
+ genDrawInfo(group, alpha_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, alpha_faces, alpha_count, TRUE, batch_textures);
+ genDrawInfo(group, bump_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, bump_faces, bump_count, FALSE, FALSE);
+ genDrawInfo(group, norm_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, norm_faces, norm_count, FALSE, FALSE);
+ genDrawInfo(group, spec_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, spec_faces, spec_count, FALSE, FALSE);
+ genDrawInfo(group, normspec_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, normspec_faces, normspec_count, FALSE, FALSE);
if (!LLPipeline::sDelayVBUpdate)
{
//drawables have been rebuilt, clear rebuild status
- for (LLSpatialGroup::element_iter drawable_iter = group->getData().begin(); drawable_iter != group->getData().end(); ++drawable_iter)
+ for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter)
{
LLDrawable* drawablep = *drawable_iter;
drawablep->clearState(LLDrawable::REBUILD_ALL);
@@ -4556,36 +4997,58 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
if (pAvatarVO)
{
+ if (pAvatarVO->mAttachmentGeometryBytes < 0)
+ { // First time through value is -1
+ pAvatarVO->mAttachmentGeometryBytes = group->mGeometryBytes;
+ }
+ else
+ {
pAvatarVO->mAttachmentGeometryBytes += group->mGeometryBytes;
+ }
+ if (pAvatarVO->mAttachmentSurfaceArea < 0.f)
+ { // First time through value is -1
+ pAvatarVO->mAttachmentSurfaceArea = group->mSurfaceArea;
+ }
+ else
+ {
pAvatarVO->mAttachmentSurfaceArea += group->mSurfaceArea;
}
}
+}
-static LLFastTimer::DeclareTimer FTM_VOLUME_GEOM("Volume Geometry");
-static LLFastTimer::DeclareTimer FTM_VOLUME_GEOM_PARTIAL("Terse Rebuild");
+static LLFastTimer::DeclareTimer FTM_REBUILD_MESH_FLUSH("Flush Mesh");
void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
{
llassert(group);
if (group && group->isState(LLSpatialGroup::MESH_DIRTY) && !group->isState(LLSpatialGroup::GEOM_DIRTY))
{
- LLFastTimer tm(FTM_VOLUME_GEOM);
- S32 num_mapped_veretx_buffer = LLVertexBuffer::sMappedCount ;
+ LLFastTimer ftm(FTM_REBUILD_VOLUME_VB);
+ LLFastTimer t(FTM_REBUILD_VOLUME_GEN_DRAW_INFO); //make sure getgeometryvolume shows up in the right place in timers
group->mBuilt = 1.f;
- std::set<LLVertexBuffer*> mapped_buffers;
+ S32 num_mapped_vertex_buffer = LLVertexBuffer::sMappedCount ;
+
+ const U32 MAX_BUFFER_COUNT = 4096;
+ LLVertexBuffer* locked_buffer[MAX_BUFFER_COUNT];
+
+ U32 buffer_count = 0;
- for (LLSpatialGroup::element_iter drawable_iter = group->getData().begin(); drawable_iter != group->getData().end(); ++drawable_iter)
+ for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter)
{
- LLFastTimer t(FTM_VOLUME_GEOM_PARTIAL);
LLDrawable* drawablep = *drawable_iter;
- if (!drawablep->isDead() && drawablep->isState(LLDrawable::REBUILD_ALL) )
+ if (!drawablep->isDead() && drawablep->isState(LLDrawable::REBUILD_ALL) && !drawablep->isState(LLDrawable::RIGGED) )
{
LLVOVolume* vobj = drawablep->getVOVolume();
vobj->preRebuild();
+ if (drawablep->isState(LLDrawable::ANIMATED_CHILD))
+ {
+ vobj->updateRelativeXform(true);
+ }
+
LLVolume* volume = vobj->getVolume();
for (S32 i = 0; i < drawablep->getNumFaces(); ++i)
{
@@ -4595,22 +5058,37 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
LLVertexBuffer* buff = face->getVertexBuffer();
if (buff)
{
- face->getGeometryVolume(*volume, face->getTEOffset(),
- vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), face->getGeomIndex());
+ llassert(!face->isState(LLFace::RIGGED));
- if (buff->isLocked())
+ if (!face->getGeometryVolume(*volume, face->getTEOffset(),
+ vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), face->getGeomIndex()))
+ { //something's gone wrong with the vertex buffer accounting, rebuild this group
+ group->dirtyGeom();
+ gPipeline.markRebuild(group, TRUE);
+ }
+
+
+ if (buff->isLocked() && buffer_count < MAX_BUFFER_COUNT)
{
- mapped_buffers.insert(buff);
+ locked_buffer[buffer_count++] = buff;
}
}
}
}
+
+ if (drawablep->isState(LLDrawable::ANIMATED_CHILD))
+ {
+ vobj->updateRelativeXform();
+ }
+
drawablep->clearState(LLDrawable::REBUILD_ALL);
}
}
- for (std::set<LLVertexBuffer*>::iterator iter = mapped_buffers.begin(); iter != mapped_buffers.end(); ++iter)
+ {
+ LLFastTimer t(FTM_REBUILD_MESH_FLUSH);
+ for (LLVertexBuffer** iter = locked_buffer, ** end_iter = locked_buffer+buffer_count; iter != end_iter; ++iter)
{
(*iter)->flush();
}
@@ -4622,21 +5100,25 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
{
group->mVertexBuffer->flush();
}
+ }
//if not all buffers are unmapped
- if(num_mapped_veretx_buffer != LLVertexBuffer::sMappedCount)
+ if(num_mapped_vertex_buffer != LLVertexBuffer::sMappedCount)
{
llwarns << "Not all mapped vertex buffers are unmapped!" << llendl ;
- for (LLSpatialGroup::element_iter drawable_iter = group->getData().begin(); drawable_iter != group->getData().end(); ++drawable_iter)
+ for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter)
{
LLDrawable* drawablep = *drawable_iter;
for (S32 i = 0; i < drawablep->getNumFaces(); ++i)
{
LLFace* face = drawablep->getFace(i);
- LLVertexBuffer* buff = face->getVertexBuffer();
- if (face && buff && buff->isLocked())
+ if (face)
{
- buff->flush();
+ LLVertexBuffer* buff = face->getVertexBuffer();
+ if (buff && buff->isLocked())
+ {
+ buff->flush();
+ }
}
}
}
@@ -4645,7 +5127,7 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
group->clearState(LLSpatialGroup::MESH_DIRTY | LLSpatialGroup::NEW_DRAWINFO);
}
- llassert(!group || !group->isState(LLSpatialGroup::NEW_DRAWINFO));
+// llassert(!group || !group->isState(LLSpatialGroup::NEW_DRAWINFO));
}
struct CompareBatchBreakerModified
@@ -4663,18 +5145,47 @@ struct CompareBatchBreakerModified
{
return lte->getFullbright() < rte->getFullbright();
}
+ else if (LLPipeline::sRenderDeferred && lte->getMaterialParams() != rte->getMaterialParams())
+ {
+ return lte->getMaterialParams() < rte->getMaterialParams();
+ }
+ else if (LLPipeline::sRenderDeferred && (lte->getMaterialParams() == rte->getMaterialParams()) && (lte->getShiny() != rte->getShiny()))
+ {
+ return lte->getShiny() < rte->getShiny();
+ }
else
{
return lhs->getTexture() < rhs->getTexture();
}
-
}
};
-void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::vector<LLFace*>& faces, BOOL distance_sort, BOOL batch_textures)
+static LLFastTimer::DeclareTimer FTM_GEN_DRAW_INFO_SORT("Draw Info Face Sort");
+static LLFastTimer::DeclareTimer FTM_GEN_DRAW_INFO_FACE_SIZE("Face Sizing");
+static LLFastTimer::DeclareTimer FTM_GEN_DRAW_INFO_ALLOCATE("Allocate VB");
+static LLFastTimer::DeclareTimer FTM_GEN_DRAW_INFO_FIND_VB("Find VB");
+static LLFastTimer::DeclareTimer FTM_GEN_DRAW_INFO_RESIZE_VB("Resize VB");
+
+
+
+
+
+void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace** faces, U32 face_count, BOOL distance_sort, BOOL batch_textures, BOOL no_materials)
{
+ LLFastTimer t(FTM_REBUILD_VOLUME_GEN_DRAW_INFO);
+
U32 buffer_usage = group->mBufferUsage;
+ static LLCachedControl<bool> use_transform_feedback(gSavedSettings, "RenderUseTransformFeedback", false);
+
+ if (use_transform_feedback &&
+ gTransformPositionProgram.mProgramObject && //transform shaders are loaded
+ buffer_usage == GL_DYNAMIC_DRAW_ARB && //target buffer is in VRAM
+ !(mask & LLVertexBuffer::MAP_WEIGHT4)) //TODO: add support for weights
+ {
+ buffer_usage = GL_DYNAMIC_COPY_ARB;
+ }
+
#if LL_DARWIN
// HACK from Leslie:
// Disable VBO usage for alpha on Mac OS X because it kills the framerate
@@ -4690,19 +5201,23 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
U32 max_vertices = (gSavedSettings.getS32("RenderMaxVBOSize")*1024)/LLVertexBuffer::calcVertexSize(group->mSpatialPartition->mVertexDataMask);
max_vertices = llmin(max_vertices, (U32) 65535);
- if (!distance_sort)
- {
- //sort faces by things that break batches
- std::sort(faces.begin(), faces.end(), CompareBatchBreakerModified());
- }
- else
{
- //sort faces by distance
- std::sort(faces.begin(), faces.end(), LLFace::CompareDistanceGreater());
+ LLFastTimer t(FTM_GEN_DRAW_INFO_SORT);
+ if (!distance_sort)
+ {
+ //sort faces by things that break batches
+ std::sort(faces, faces+face_count, CompareBatchBreakerModified());
+ }
+ else
+ {
+ //sort faces by distance
+ std::sort(faces, faces+face_count, LLFace::CompareDistanceGreater());
+ }
}
bool hud_group = group->isHUDGroup() ;
- std::vector<LLFace*>::iterator face_iter = faces.begin();
+ LLFace** face_iter = faces;
+ LLFace** end_faces = faces+face_count;
LLSpatialGroup::buffer_map_t buffer_map;
@@ -4731,11 +5246,14 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
//NEVER use more than 16 texture index channels (workaround for prevalent driver bug)
texture_index_channels = llmin(texture_index_channels, 16);
- while (face_iter != faces.end())
+ bool flexi = false;
+
+ while (face_iter != end_faces)
{
//pull off next face
LLFace* facep = *face_iter;
LLViewerTexture* tex = facep->getTexture();
+ LLMaterialPtr mat = facep->getTextureEntry()->getMaterialParams();
if (distance_sort)
{
@@ -4757,63 +5275,116 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
U32 index_count = facep->getIndicesCount();
U32 geom_count = facep->getGeomCount();
+ flexi = flexi || facep->getViewerObject()->getVolume()->isUnique();
+
//sum up vertices needed for this render batch
- std::vector<LLFace*>::iterator i = face_iter;
+ LLFace** i = face_iter;
++i;
- std::vector<LLViewerTexture*> texture_list;
+ const U32 MAX_TEXTURE_COUNT = 32;
+ LLViewerTexture* texture_list[MAX_TEXTURE_COUNT];
+
+ U32 texture_count = 0;
- if (batch_textures)
{
- U8 cur_tex = 0;
- facep->setTextureIndex(cur_tex);
- texture_list.push_back(tex);
-
- //if (can_batch_texture(facep))
+ LLFastTimer t(FTM_GEN_DRAW_INFO_FACE_SIZE);
+ if (batch_textures)
{
- while (i != faces.end())
+ U8 cur_tex = 0;
+ facep->setTextureIndex(cur_tex);
+ if (texture_count < MAX_TEXTURE_COUNT)
{
- facep = *i;
- if (facep->getTexture() != tex)
+ texture_list[texture_count++] = tex;
+ }
+
+ if (can_batch_texture(facep))
+ { //populate texture_list with any textures that can be batched
+ //move i to the next unbatchable face
+ while (i != end_faces)
{
- if (distance_sort)
- { //textures might be out of order, see if texture exists in current batch
- bool found = false;
- for (U32 tex_idx = 0; tex_idx < texture_list.size(); ++tex_idx)
- {
- if (facep->getTexture() == texture_list[tex_idx])
+ facep = *i;
+
+ if (!can_batch_texture(facep))
+ { //face is bump mapped or has an animated texture matrix -- can't
+ //batch more than 1 texture at a time
+ facep->setTextureIndex(0);
+ break;
+ }
+
+ if (facep->getTexture() != tex)
+ {
+ if (distance_sort)
+ { //textures might be out of order, see if texture exists in current batch
+ bool found = false;
+ for (U32 tex_idx = 0; tex_idx < texture_count; ++tex_idx)
+ {
+ if (facep->getTexture() == texture_list[tex_idx])
+ {
+ cur_tex = tex_idx;
+ found = true;
+ break;
+ }
+ }
+
+ if (!found)
{
- cur_tex = tex_idx;
- found = true;
- break;
+ cur_tex = texture_count;
}
}
+ else
+ {
+ cur_tex++;
+ }
- if (!found)
+ if (cur_tex >= texture_index_channels)
+ { //cut batches when index channels are depleted
+ break;
+ }
+
+ tex = facep->getTexture();
+
+ if (texture_count < MAX_TEXTURE_COUNT)
{
- cur_tex = texture_list.size();
+ texture_list[texture_count++] = tex;
}
}
- else
- {
- cur_tex++;
- }
- if (!can_batch_texture(facep))
- { //face is bump mapped or has an animated texture matrix -- can't
- //batch more than 1 texture at a time
+ if (geom_count + facep->getGeomCount() > max_vertices)
+ { //cut batches on geom count too big
break;
}
- if (cur_tex >= texture_index_channels)
- { //cut batches when index channels are depleted
- break;
- }
+ ++i;
+
+ flexi = flexi || facep->getViewerObject()->getVolume()->isUnique();
- tex = facep->getTexture();
+ index_count += facep->getIndicesCount();
+ geom_count += facep->getGeomCount();
- texture_list.push_back(tex);
+ facep->setTextureIndex(cur_tex);
}
+ }
+ else
+ {
+ facep->setTextureIndex(0);
+ }
+
+ tex = texture_list[0];
+ }
+ else
+ {
+ while (i != end_faces &&
+ (LLPipeline::sTextureBindTest ||
+ (distance_sort ||
+ ((*i)->getTexture() == tex &&
+ ((*i)->getTextureEntry()->getMaterialParams() == mat)))))
+ {
+ facep = *i;
+
+
+ //face has no texture index
+ facep->mDrawInfo = NULL;
+ facep->setTextureIndex(255);
if (geom_count + facep->getGeomCount() > max_vertices)
{ //cut batches on geom count too big
@@ -4824,68 +5395,25 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
index_count += facep->getIndicesCount();
geom_count += facep->getGeomCount();
- facep->setTextureIndex(cur_tex);
+ flexi = flexi || facep->getViewerObject()->getVolume()->isUnique();
+ }
}
}
- tex = texture_list[0];
- }
- else
- {
- while (i != faces.end() &&
- (LLPipeline::sTextureBindTest || (distance_sort || (*i)->getTexture() == tex)))
- {
- facep = *i;
-
-
- //face has no texture index
- facep->mDrawInfo = NULL;
- facep->setTextureIndex(255);
-
- if (geom_count + facep->getGeomCount() > max_vertices)
- { //cut batches on geom count too big
- break;
- }
- ++i;
- index_count += facep->getIndicesCount();
- geom_count += facep->getGeomCount();
- }
+ if (flexi && buffer_usage && buffer_usage != GL_STREAM_DRAW_ARB)
+ {
+ buffer_usage = GL_STREAM_DRAW_ARB;
}
-
- //create/delete/resize vertex buffer if needed
+
+ //create vertex buffer
LLVertexBuffer* buffer = NULL;
- { //try to find a buffer to reuse
- LLSpatialGroup::buffer_texture_map_t::iterator found_iter = group->mBufferMap[mask].find(*face_iter);
-
- if (found_iter != group->mBufferMap[mask].end())
- {
- if ((U32) buffer_index < found_iter->second.size())
- {
- buffer = found_iter->second[buffer_index];
- }
- }
- }
-
- if (!buffer || !buffer->isWriteable())
- { //create new buffer if needed
+ {
+ LLFastTimer t(FTM_GEN_DRAW_INFO_ALLOCATE);
buffer = createVertexBuffer(mask, buffer_usage);
buffer->allocateBuffer(geom_count, index_count, TRUE);
}
- else
- { //resize pre-existing buffer
- if (LLVertexBuffer::sEnableVBOs && buffer->getUsage() != buffer_usage ||
- buffer->getTypeMask() != mask)
- {
- buffer = createVertexBuffer(mask, buffer_usage);
- buffer->allocateBuffer(geom_count, index_count, TRUE);
- }
- else
- {
- buffer->resizeBuffer(geom_count, index_count);
- }
- }
group->mGeometryBytes += buffer->getSize() + buffer->getIndicesSize();
@@ -4919,17 +5447,31 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
LLVOVolume* vobj = drawablep->getVOVolume();
LLVolume* volume = vobj->getVolume();
+ if (drawablep->isState(LLDrawable::ANIMATED_CHILD))
+ {
+ vobj->updateRelativeXform(true);
+ }
+
U32 te_idx = facep->getTEOffset();
- facep->getGeometryVolume(*volume, te_idx,
- vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), index_offset);
+ llassert(!facep->isState(LLFace::RIGGED));
+
+ if (!facep->getGeometryVolume(*volume, te_idx,
+ vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), index_offset,true))
+ {
+ llwarns << "Failed to get geometry for face!" << llendl;
+ }
+
+ if (drawablep->isState(LLDrawable::ANIMATED_CHILD))
+ {
+ vobj->updateRelativeXform(false);
+ }
}
}
index_offset += facep->getGeomCount();
indices_index += facep->getIndicesCount();
-
-
+
//append face to appropriate render batch
BOOL force_simple = facep->getPixelArea() < FORCE_SIMPLE_RENDER_AREA;
@@ -4949,7 +5491,135 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
BOOL is_alpha = (facep->getPoolType() == LLDrawPool::POOL_ALPHA) ? TRUE : FALSE;
- if (is_alpha)
+ LLMaterial* mat = te->getMaterialParams().get();
+
+ bool can_be_shiny = true;
+ if (mat)
+ {
+ U8 mode = mat->getDiffuseAlphaMode();
+ can_be_shiny = mode == LLMaterial::DIFFUSE_ALPHA_MODE_NONE ||
+ mode == LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE;
+ }
+
+ bool use_legacy_bump = te->getBumpmap() && (te->getBumpmap() < 18) && (!mat || mat->getNormalID().isNull());
+ bool opaque = te->getColor().mV[3] >= 0.999f;
+
+ if (mat && LLPipeline::sRenderDeferred && !hud_group)
+ {
+ bool material_pass = false;
+
+ // do NOT use 'fullbright' for this logic or you risk sending
+ // things without normals down the materials pipeline and will
+ // render poorly if not crash NORSPEC-240,314
+ //
+ if (te->getFullbright())
+ {
+ if (mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK)
+ {
+ if (opaque)
+ {
+ registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK);
+ }
+ else
+ {
+ registerFace(group, facep, LLRenderPass::PASS_ALPHA);
+ }
+ }
+ else if (is_alpha)
+ {
+ registerFace(group, facep, LLRenderPass::PASS_ALPHA);
+ }
+ else
+ {
+ if (mat->getEnvironmentIntensity() > 0 ||
+ te->getShiny() > 0)
+ {
+ material_pass = true;
+ }
+ else
+ {
+ registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT);
+ }
+ }
+ }
+ else if (no_materials)
+ {
+ registerFace(group, facep, LLRenderPass::PASS_SIMPLE);
+ }
+ else if (te->getColor().mV[3] < 0.999f)
+ {
+ registerFace(group, facep, LLRenderPass::PASS_ALPHA);
+ }
+ else if (use_legacy_bump)
+ {
+ // we have a material AND legacy bump settings, but no normal map
+ registerFace(group, facep, LLRenderPass::PASS_BUMP);
+ }
+ else
+ {
+ material_pass = true;
+ }
+
+ if (material_pass)
+ {
+ U32 pass[] =
+ {
+ LLRenderPass::PASS_MATERIAL,
+ LLRenderPass::PASS_ALPHA, //LLRenderPass::PASS_MATERIAL_ALPHA,
+ LLRenderPass::PASS_MATERIAL_ALPHA_MASK,
+ LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE,
+ LLRenderPass::PASS_SPECMAP,
+ LLRenderPass::PASS_ALPHA, //LLRenderPass::PASS_SPECMAP_BLEND,
+ LLRenderPass::PASS_SPECMAP_MASK,
+ LLRenderPass::PASS_SPECMAP_EMISSIVE,
+ LLRenderPass::PASS_NORMMAP,
+ LLRenderPass::PASS_ALPHA, //LLRenderPass::PASS_NORMMAP_BLEND,
+ LLRenderPass::PASS_NORMMAP_MASK,
+ LLRenderPass::PASS_NORMMAP_EMISSIVE,
+ LLRenderPass::PASS_NORMSPEC,
+ LLRenderPass::PASS_ALPHA, //LLRenderPass::PASS_NORMSPEC_BLEND,
+ LLRenderPass::PASS_NORMSPEC_MASK,
+ LLRenderPass::PASS_NORMSPEC_EMISSIVE,
+ };
+
+ U32 mask = mat->getShaderMask();
+
+ llassert(mask < sizeof(pass)/sizeof(U32));
+
+ mask = llmin(mask, (U32)(sizeof(pass)/sizeof(U32)-1));
+
+ registerFace(group, facep, pass[mask]);
+ }
+ }
+ else if (mat)
+ {
+ U8 mode = mat->getDiffuseAlphaMode();
+ if (te->getColor().mV[3] < 0.999f)
+ {
+ mode = LLMaterial::DIFFUSE_ALPHA_MODE_BLEND;
+ }
+
+ if (mode == LLMaterial::DIFFUSE_ALPHA_MODE_MASK)
+ {
+ registerFace(group, facep, fullbright ? LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK : LLRenderPass::PASS_ALPHA_MASK);
+ }
+ else if (is_alpha || (te->getColor().mV[3] < 0.999f))
+ {
+ registerFace(group, facep, LLRenderPass::PASS_ALPHA);
+ }
+ else if (gPipeline.canUseVertexShaders()
+ && LLPipeline::sRenderBump
+ && te->getShiny()
+ && can_be_shiny)
+ {
+ registerFace(group, facep, fullbright ? LLRenderPass::PASS_FULLBRIGHT_SHINY : LLRenderPass::PASS_SHINY);
+ }
+ else
+ {
+ registerFace(group, facep, fullbright ? LLRenderPass::PASS_FULLBRIGHT : LLRenderPass::PASS_SIMPLE);
+ }
+ }
+ else if (is_alpha)
{
// can we safely treat this as an alpha mask?
if (facep->getFaceColor().mV[3] <= 0.f)
@@ -4974,7 +5644,8 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
}
else if (gPipeline.canUseVertexShaders()
&& LLPipeline::sRenderBump
- && te->getShiny())
+ && te->getShiny()
+ && can_be_shiny)
{ //shiny
if (tex->getPrimaryFormat() == GL_ALPHA)
{ //invisiprim+shiny
@@ -4991,7 +5662,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
registerFace(group, facep, LLRenderPass::PASS_POST_BUMP);
}
}
- else if (te->getBumpmap())
+ else if (use_legacy_bump)
{ //register in deferred bump pass
registerFace(group, facep, LLRenderPass::PASS_BUMP);
}
@@ -5018,22 +5689,36 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
}
else if (fullbright || bake_sunlight)
{ //fullbright
- registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT);
- if (LLPipeline::sRenderDeferred && !hud_group && LLPipeline::sRenderBump && te->getBumpmap())
+ if (mat && mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK)
+ {
+ registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK);
+ }
+ else
+ {
+ registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT);
+ }
+ if (LLPipeline::sRenderDeferred && !hud_group && LLPipeline::sRenderBump && use_legacy_bump)
{ //if this is the deferred render and a bump map is present, register in post deferred bump
registerFace(group, facep, LLRenderPass::PASS_POST_BUMP);
}
}
else
{
- if (LLPipeline::sRenderDeferred && LLPipeline::sRenderBump && te->getBumpmap())
+ if (LLPipeline::sRenderDeferred && LLPipeline::sRenderBump && use_legacy_bump)
{ //non-shiny or fullbright deferred bump
registerFace(group, facep, LLRenderPass::PASS_BUMP);
}
else
{ //all around simple
llassert(mask & LLVertexBuffer::MAP_NORMAL);
- registerFace(group, facep, LLRenderPass::PASS_SIMPLE);
+ if (mat && mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK)
+ { //material alpha mask can be respected in non-deferred
+ registerFace(group, facep, LLRenderPass::PASS_ALPHA_MASK);
+ }
+ else
+ {
+ registerFace(group, facep, LLRenderPass::PASS_SIMPLE);
+ }
}
}
@@ -5053,7 +5738,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
llassert((mask & LLVertexBuffer::MAP_NORMAL) || fullbright);
facep->setPoolType((fullbright) ? LLDrawPool::POOL_FULLBRIGHT : LLDrawPool::POOL_SIMPLE);
- if (!force_simple && te->getBumpmap() && LLPipeline::sRenderBump)
+ if (!force_simple && LLPipeline::sRenderBump && use_legacy_bump)
{
registerFace(group, facep, LLRenderPass::PASS_BUMP);
}
@@ -5086,7 +5771,8 @@ void LLGeometryManager::addGeometryCount(LLSpatialGroup* group, U32 &vertex_coun
mFaceList.clear();
//for each drawable
- for (LLSpatialGroup::element_iter drawable_iter = group->getData().begin(); drawable_iter != group->getData().end(); ++drawable_iter)
+
+ for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter)
{
LLDrawable* drawablep = *drawable_iter;
@@ -5106,17 +5792,21 @@ void LLGeometryManager::addGeometryCount(LLSpatialGroup* group, U32 &vertex_coun
//sum up face verts and indices
drawablep->updateFaceSize(i);
LLFace* facep = drawablep->getFace(i);
- if (facep->hasGeometry() && facep->getPixelArea() > FORCE_CULL_AREA)
+ if (facep)
{
- vertex_count += facep->getGeomCount();
- index_count += facep->getIndicesCount();
- llassert(facep->getIndicesCount() < 65536);
- //remember face (for sorting)
- mFaceList.push_back(facep);
- }
- else
- {
- facep->clearVertexBuffer();
+ if (facep->hasGeometry() && facep->getPixelArea() > FORCE_CULL_AREA &&
+ facep->getGeomCount() + vertex_count <= 65536)
+ {
+ vertex_count += facep->getGeomCount();
+ index_count += facep->getIndicesCount();
+
+ //remember face (for sorting)
+ mFaceList.push_back(facep);
+ }
+ else
+ {
+ facep->clearVertexBuffer();
+ }
}
}
}
@@ -5137,4 +5827,3 @@ void LLHUDPartition::shift(const LLVector4a &offset)
//HUD objects don't shift with region crossing. That would be silly.
}
-
diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h
index 3cf434dc26..7503f8c5aa 100644..100755
--- a/indra/newview/llvovolume.h
+++ b/indra/newview/llvovolume.h
@@ -31,12 +31,14 @@
#include "llviewertexture.h"
#include "llviewermedia.h"
#include "llframetimer.h"
+#include "lllocalbitmaps.h"
#include "m3math.h" // LLMatrix3
#include "m4math.h" // LLMatrix4
#include <map>
class LLViewerTextureAnim;
class LLDrawPool;
+class LLMaterialID;
class LLSelectNode;
class LLObjectMediaDataClient;
class LLObjectMediaNavigateClient;
@@ -68,7 +70,7 @@ class LLVolumeInterface
public:
virtual ~LLVolumeInterface() { }
virtual LLVolumeInterfaceType getInterfaceType() const = 0;
- virtual BOOL doIdleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) = 0;
+ virtual void doIdleUpdate() = 0;
virtual BOOL doUpdateGeometry(LLDrawable *drawable) = 0;
virtual LLVector3 getPivotPosition() const = 0;
virtual void onSetVolume(const LLVolumeParams &volume_params, const S32 detail) = 0;
@@ -79,7 +81,7 @@ public:
virtual bool isVolumeGlobal() const = 0; // Are we in global space?
virtual bool isActive() const = 0; // Is this object currently active?
virtual const LLMatrix4& getWorldMatrix(LLXformMatrix* xform) const = 0;
- virtual void updateRelativeXform() = 0;
+ virtual void updateRelativeXform(bool force_identity = false) = 0;
virtual U32 getID() const = 0;
virtual void preRebuild() = 0;
};
@@ -114,8 +116,7 @@ public:
void deleteFaces();
void animateTextures();
- /*virtual*/ BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time);
-
+
BOOL isVisible() const ;
/*virtual*/ BOOL isActive() const;
/*virtual*/ BOOL isAttachment() const;
@@ -136,14 +137,14 @@ public:
/*virtual*/ U32 getTriangleCount(S32* vcount = NULL) const;
/*virtual*/ U32 getHighLODTriangleCount();
- /*virtual*/ BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end,
+ /*virtual*/ BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
S32 face = -1, // which face to check, -1 = ALL_SIDES
BOOL pick_transparent = FALSE,
S32* face_hit = NULL, // which face was hit
- LLVector3* intersection = NULL, // return the intersection point
+ LLVector4a* intersection = NULL, // return the intersection point
LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
- LLVector3* normal = NULL, // return the surface normal at the intersection point
- LLVector3* bi_normal = NULL // return the surface bi-normal at the intersection point
+ LLVector4a* normal = NULL, // return the surface normal at the intersection point
+ LLVector4a* tangent = NULL // return the surface tangent at the intersection point
);
LLVector3 agentPositionToVolume(const LLVector3& pos) const;
@@ -158,6 +159,7 @@ public:
const LLMatrix4& getWorldMatrix(LLXformMatrix* xform) const;
void markForUpdate(BOOL priority) { LLViewerObject::markForUpdate(priority); mVolumeChanged = TRUE; }
+ void faceMappingChanged() { mFaceMappingChanged=TRUE; };
/*virtual*/ void onShift(const LLVector4a &shift_vector); // Called when the drawable shifts
@@ -174,6 +176,7 @@ public:
/*virtual*/ void setScale(const LLVector3 &scale, BOOL damped);
+ /*virtual*/ void changeTEImage(S32 index, LLViewerTexture* new_image) ;
/*virtual*/ void setNumTEs(const U8 num_tes);
/*virtual*/ void setTEImage(const U8 te, LLViewerTexture *imagep);
/*virtual*/ S32 setTETexture(const U8 te, const LLUUID &uuid);
@@ -185,6 +188,11 @@ public:
/*virtual*/ S32 setTEBumpShinyFullbright(const U8 te, const U8 bump);
/*virtual*/ S32 setTEMediaFlags(const U8 te, const U8 media_flags);
/*virtual*/ S32 setTEGlow(const U8 te, const F32 glow);
+ /*virtual*/ S32 setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID);
+
+ static void setTEMaterialParamsCallbackTE(const LLUUID& objectID, const LLMaterialID& pMaterialID, const LLMaterialPtr pMaterialParams, U32 te);
+
+ /*virtual*/ S32 setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams);
/*virtual*/ S32 setTEScale(const U8 te, const F32 s, const F32 t);
/*virtual*/ S32 setTEScaleS(const U8 te, const F32 s);
/*virtual*/ S32 setTEScaleT(const U8 te, const F32 t);
@@ -203,7 +211,7 @@ public:
LLAssetType::EType type,
void* user_data, S32 status, LLExtStat ext_status);
- void updateRelativeXform();
+ void updateRelativeXform(bool force_identity = false);
/*virtual*/ BOOL updateGeometry(LLDrawable *drawable);
/*virtual*/ void updateFaceSize(S32 idx);
/*virtual*/ BOOL updateLOD();
@@ -340,7 +348,8 @@ public:
U8 mTexAnimMode;
private:
friend class LLDrawable;
-
+ friend class LLFace;
+
BOOL mFaceMappingChanged;
LLFrameTimer mTextureUpdateTimer;
S32 mLOD;
@@ -377,3 +386,4 @@ protected:
};
#endif // LL_LLVOVOLUME_H
+
diff --git a/indra/newview/llvowater.cpp b/indra/newview/llvowater.cpp
index cd78157944..e8a1c3d1d6 100644..100755
--- a/indra/newview/llvowater.cpp
+++ b/indra/newview/llvowater.cpp
@@ -100,17 +100,8 @@ void LLVOWater::updateTextures()
}
// Never gets called
-BOOL LLVOWater::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
+void LLVOWater::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
{
- /*if (mDead || !(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_WATER)))
- {
- return TRUE;
- }
- if (mDrawable)
- {
- gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE);
- }*/
- return TRUE;
}
LLDrawable *LLVOWater::createDrawable(LLPipeline *pipeline)
@@ -146,6 +137,10 @@ BOOL LLVOWater::updateGeometry(LLDrawable *drawable)
drawable->addFace(poolp, NULL);
}
face = drawable->getFace(0);
+ if (!face)
+ {
+ return TRUE;
+ }
// LLVector2 uvs[4];
// LLVector3 vtx[4];
diff --git a/indra/newview/llvowater.h b/indra/newview/llvowater.h
index ed709dd840..cf9323ef2e 100644..100755
--- a/indra/newview/llvowater.h
+++ b/indra/newview/llvowater.h
@@ -58,7 +58,7 @@ public:
static void initClass();
static void cleanupClass();
- /*virtual*/ BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time);
+ /*virtual*/ void idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time);
/*virtual*/ LLDrawable* createDrawable(LLPipeline *pipeline);
/*virtual*/ BOOL updateGeometry(LLDrawable *drawable);
/*virtual*/ void updateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax);
diff --git a/indra/newview/llvowlsky.cpp b/indra/newview/llvowlsky.cpp
index afd902201b..4e26587184 100644..100755
--- a/indra/newview/llvowlsky.cpp
+++ b/indra/newview/llvowlsky.cpp
@@ -92,9 +92,9 @@ void LLVOWLSky::initSunDirection(LLVector3 const & sun_direction,
{
}
-BOOL LLVOWLSky::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
+void LLVOWLSky::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
{
- return TRUE;
+
}
BOOL LLVOWLSky::isActive(void) const
@@ -301,7 +301,7 @@ void LLVOWLSky::restoreGL()
gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE);
}
-static LLFastTimer::DeclareTimer FTM_GEO_SKY("Sky Geometry");
+static LLFastTimer::DeclareTimer FTM_GEO_SKY("Windlight Sky Geometry");
BOOL LLVOWLSky::updateGeometry(LLDrawable * drawable)
{
@@ -724,8 +724,8 @@ void LLVOWLSky::updateStarColors()
const F32 var = 0.15f;
const F32 min = 0.5f; //0.75f;
- const F32 sunclose_max = 0.6f;
- const F32 sunclose_range = 1 - sunclose_max;
+ //const F32 sunclose_max = 0.6f;
+ //const F32 sunclose_range = 1 - sunclose_max;
//F32 below_horizon = - llmin(0.0f, gSky.mVOSkyp->getToSunLast().mV[2]);
//F32 brightness_factor = llmin(1.0f, below_horizon * 20);
@@ -739,14 +739,14 @@ void LLVOWLSky::updateStarColors()
U32 x;
for (x = 0; x < getStarsNumVerts(); ++x)
{
- F32 sundir_factor = 1;
+ //F32 sundir_factor = 1;
LLVector3 tostar = *v_p;
tostar.normVec();
- const F32 how_close_to_sun = tostar * gSky.mVOSkyp->getToSunLast();
- if (how_close_to_sun > sunclose_max)
- {
- sundir_factor = (1 - how_close_to_sun) / sunclose_range;
- }
+ //const F32 how_close_to_sun = tostar * gSky.mVOSkyp->getToSunLast();
+ //if (how_close_to_sun > sunclose_max)
+ //{
+ // sundir_factor = (1 - how_close_to_sun) / sunclose_range;
+ //}
intensity = *(v_i);
F32 alpha = v_c->mV[VALPHA] + (ll_frand() - 0.5f) * var * intensity;
if (alpha < min * intensity)
diff --git a/indra/newview/llvowlsky.h b/indra/newview/llvowlsky.h
index 825e13a203..729dced15e 100644..100755
--- a/indra/newview/llvowlsky.h
+++ b/indra/newview/llvowlsky.h
@@ -53,7 +53,7 @@ public:
void initSunDirection(LLVector3 const & sun_direction,
LLVector3 const & sun_angular_velocity);
- /*virtual*/ BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time);
+ /*virtual*/ void idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time);
/*virtual*/ BOOL isActive(void) const;
/*virtual*/ LLDrawable * createDrawable(LLPipeline *pipeline);
/*virtual*/ BOOL updateGeometry(LLDrawable *drawable);
diff --git a/indra/newview/llwatchdog.cpp b/indra/newview/llwatchdog.cpp
index 4f582fc2db..4f582fc2db 100644..100755
--- a/indra/newview/llwatchdog.cpp
+++ b/indra/newview/llwatchdog.cpp
diff --git a/indra/newview/llwatchdog.h b/indra/newview/llwatchdog.h
index fee3ec6f20..fee3ec6f20 100644..100755
--- a/indra/newview/llwatchdog.h
+++ b/indra/newview/llwatchdog.h
diff --git a/indra/newview/llwaterparammanager.cpp b/indra/newview/llwaterparammanager.cpp
index e386112334..72d628fb88 100644..100755
--- a/indra/newview/llwaterparammanager.cpp
+++ b/indra/newview/llwaterparammanager.cpp
@@ -100,7 +100,7 @@ void LLWaterParamManager::loadPresetsFromDir(const std::string& dir)
break; // no more files
}
- std::string path = dir + file;
+ std::string path = gDirUtilp->add(dir, file);
if (!loadPreset(path))
{
llwarns << "Error loading water preset from " << path << llendl;
@@ -188,13 +188,12 @@ void LLWaterParamManager::updateShaderUniforms(LLGLSLShader * shader)
if (shader->mShaderGroup == LLGLSLShader::SG_WATER)
{
shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, 1, LLWLParamManager::getInstance()->getRotatedLightDir().mV);
- shader->uniform3fv("camPosLocal", 1, LLViewerCamera::getInstance()->getOrigin().mV);
- shader->uniform4fv("waterFogColor", 1, LLDrawPoolWater::sWaterFogColor.mV);
- shader->uniform1f("waterFogEnd", LLDrawPoolWater::sWaterFogEnd);
- shader->uniform4fv("waterPlane", 1, mWaterPlane.mV);
- shader->uniform1f("waterFogDensity", getFogDensity());
- shader->uniform1f("waterFogKS", mWaterFogKS);
- shader->uniform1f("distance_multiplier", 0);
+shader->uniform3fv(LLShaderMgr::WL_CAMPOSLOCAL, 1, LLViewerCamera::getInstance()->getOrigin().mV);
+ shader->uniform4fv(LLShaderMgr::WATER_FOGCOLOR, 1, LLDrawPoolWater::sWaterFogColor.mV);
+ shader->uniform4fv(LLShaderMgr::WATER_WATERPLANE, 1, mWaterPlane.mV);
+ shader->uniform1f(LLShaderMgr::WATER_FOGDENSITY, getFogDensity());
+ shader->uniform1f(LLShaderMgr::WATER_FOGKS, mWaterFogKS);
+ shader->uniform1f(LLViewerShaderMgr::DISTANCE_MULTIPLIER, 0);
}
}
diff --git a/indra/newview/llwaterparammanager.h b/indra/newview/llwaterparammanager.h
index dc7d41be2a..dc7d41be2a 100644..100755
--- a/indra/newview/llwaterparammanager.h
+++ b/indra/newview/llwaterparammanager.h
diff --git a/indra/newview/llwaterparamset.cpp b/indra/newview/llwaterparamset.cpp
index 39d366b023..9cc91d2246 100644..100755
--- a/indra/newview/llwaterparamset.cpp
+++ b/indra/newview/llwaterparamset.cpp
@@ -185,8 +185,6 @@ LLVector3 LLWaterParamSet::getVector3(const std::string& paramName, bool& error)
LLVector2 LLWaterParamSet::getVector2(const std::string& paramName, bool& error)
{
// test to see if right type
- int ttest;
- ttest = mParamValues.size();
LLSD cur_val = mParamValues.get(paramName);
if (!cur_val.isArray() || cur_val.size() != 2)
{
diff --git a/indra/newview/llwaterparamset.h b/indra/newview/llwaterparamset.h
index b28585af59..368cb0ccba 100644..100755
--- a/indra/newview/llwaterparamset.h
+++ b/indra/newview/llwaterparamset.h
@@ -33,6 +33,7 @@
#include "v4math.h"
#include "v4color.h"
#include "llviewershadermgr.h"
+#include "llstringtable.h"
class LLWaterParamSet;
@@ -47,6 +48,9 @@ public:
private:
LLSD mParamValues;
+ std::vector<LLStaticHashedString> mParamHashedNames;
+
+ void updateHashedNames();
public:
@@ -140,6 +144,17 @@ inline void LLWaterParamSet::setAll(const LLSD& val)
mParamValues[mIt->first] = mIt->second;
}
}
+ updateHashedNames();
+}
+
+inline void LLWaterParamSet::updateHashedNames()
+{
+ mParamHashedNames.clear();
+ // Iterate through values
+ for(LLSD::map_iterator iter = mParamValues.beginMap(); iter != mParamValues.endMap(); ++iter)
+ {
+ mParamHashedNames.push_back(LLStaticHashedString(iter->first));
+ }
}
inline const LLSD& LLWaterParamSet::getAll()
diff --git a/indra/newview/llwearable.cpp b/indra/newview/llwearable.cpp
deleted file mode 100644
index 402504933c..0000000000
--- a/indra/newview/llwearable.cpp
+++ /dev/null
@@ -1,1285 +0,0 @@
-/**
- * @file llwearable.cpp
- * @brief LLWearable class implementation
- *
- * $LicenseInfo:firstyear=2002&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 "llviewerprecompiledheaders.h"
-
-#include "llagent.h"
-#include "llagentcamera.h"
-#include "llagentwearables.h"
-#include "lldictionary.h"
-#include "llfloatersidepanelcontainer.h"
-#include "lllocaltextureobject.h"
-#include "llnotificationsutil.h"
-#include "llviewertexturelist.h"
-#include "llinventorymodel.h"
-#include "llinventoryobserver.h"
-#include "llsidepanelappearance.h"
-#include "lltexlayer.h"
-#include "lltexglobalcolor.h"
-#include "lltrans.h"
-#include "llviewerregion.h"
-#include "llvisualparam.h"
-#include "llvoavatar.h"
-#include "llvoavatarself.h"
-#include "llvoavatardefines.h"
-#include "llwearable.h"
-#include "llviewercontrol.h"
-
-using namespace LLVOAvatarDefines;
-
-// static
-S32 LLWearable::sCurrentDefinitionVersion = 1;
-
-// support class - remove for 2.1 (hackity hack hack)
-class LLOverrideBakedTextureUpdate
-{
-public:
- LLOverrideBakedTextureUpdate(bool temp_state)
- {
- U32 num_bakes = (U32) LLVOAvatarDefines::BAKED_NUM_INDICES;
- for( U32 index = 0; index < num_bakes; ++index )
- {
- composite_enabled[index] = gAgentAvatarp->isCompositeUpdateEnabled(index);
- }
- gAgentAvatarp->setCompositeUpdatesEnabled(temp_state);
- }
-
- ~LLOverrideBakedTextureUpdate()
- {
- U32 num_bakes = (U32)LLVOAvatarDefines::BAKED_NUM_INDICES;
- for( U32 index = 0; index < num_bakes; ++index )
- {
- gAgentAvatarp->setCompositeUpdatesEnabled(index, composite_enabled[index]);
- }
- }
-private:
- bool composite_enabled[LLVOAvatarDefines::BAKED_NUM_INDICES];
-};
-
-// Private local functions
-static std::string terse_F32_to_string(F32 f);
-static std::string asset_id_to_filename(const LLUUID &asset_id);
-
-LLWearable::LLWearable(const LLTransactionID& transaction_id) :
- mDefinitionVersion(LLWearable::sCurrentDefinitionVersion),
- mType(LLWearableType::WT_INVALID)
-{
- mTransactionID = transaction_id;
- mAssetID = mTransactionID.makeAssetID(gAgent.getSecureSessionID());
-}
-
-LLWearable::LLWearable(const LLAssetID& asset_id) :
- mDefinitionVersion( LLWearable::sCurrentDefinitionVersion ),
- mType(LLWearableType::WT_INVALID)
-{
- mAssetID = asset_id;
- mTransactionID.setNull();
-}
-
-LLWearable::~LLWearable()
-{
-}
-
-const std::string& LLWearable::getTypeLabel() const
-{
- return LLWearableType::getTypeLabel(mType);
-}
-
-const std::string& LLWearable::getTypeName() const
-{
- return LLWearableType::getTypeName(mType);
-}
-
-LLAssetType::EType LLWearable::getAssetType() const
-{
- return LLWearableType::getAssetType(mType);
-}
-
-BOOL LLWearable::exportFile(LLFILE* file) const
-{
- // header and version
- if( fprintf( file, "LLWearable version %d\n", mDefinitionVersion ) < 0 )
- {
- return FALSE;
- }
-
- // name
- if( fprintf( file, "%s\n", mName.c_str() ) < 0 )
- {
- return FALSE;
- }
-
- // description
- if( fprintf( file, "%s\n", mDescription.c_str() ) < 0 )
- {
- return FALSE;
- }
-
- // permissions
- if( !mPermissions.exportFile( file ) )
- {
- return FALSE;
- }
-
- // sale info
- if( !mSaleInfo.exportFile( file ) )
- {
- return FALSE;
- }
-
- // wearable type
- S32 type = (S32)mType;
- if( fprintf( file, "type %d\n", type ) < 0 )
- {
- return FALSE;
- }
-
- // parameters
- S32 num_parameters = mVisualParamIndexMap.size();
- if( fprintf( file, "parameters %d\n", num_parameters ) < 0 )
- {
- return FALSE;
- }
-
- for (visual_param_index_map_t::const_iterator iter = mVisualParamIndexMap.begin();
- iter != mVisualParamIndexMap.end();
- ++iter)
- {
- S32 param_id = iter->first;
- const LLVisualParam* param = iter->second;
- F32 param_weight = param->getWeight();
- if( fprintf( file, "%d %s\n", param_id, terse_F32_to_string( param_weight ).c_str() ) < 0 )
- {
- return FALSE;
- }
- }
-
- // texture entries
- S32 num_textures = mTEMap.size();
- if( fprintf( file, "textures %d\n", num_textures ) < 0 )
- {
- return FALSE;
- }
-
- for (te_map_t::const_iterator iter = mTEMap.begin(); iter != mTEMap.end(); ++iter)
- {
- S32 te = iter->first;
- const LLUUID& image_id = iter->second->getID();
- if( fprintf( file, "%d %s\n", te, image_id.asString().c_str()) < 0 )
- {
- return FALSE;
- }
- }
- return TRUE;
-}
-
-
-void LLWearable::createVisualParams()
-{
- for (LLViewerVisualParam* param = (LLViewerVisualParam*) gAgentAvatarp->getFirstVisualParam();
- param;
- param = (LLViewerVisualParam*) gAgentAvatarp->getNextVisualParam())
- {
- if (param->getWearableType() == mType)
- {
- addVisualParam(param->cloneParam(this));
- }
- }
-
- // resync driver parameters to point to the newly cloned driven parameters
- for (visual_param_index_map_t::iterator param_iter = mVisualParamIndexMap.begin();
- param_iter != mVisualParamIndexMap.end();
- ++param_iter)
- {
- LLVisualParam* param = param_iter->second;
- LLVisualParam*(LLWearable::*wearable_function)(S32)const = &LLWearable::getVisualParam;
- // need this line to disambiguate between versions of LLCharacter::getVisualParam()
- LLVisualParam*(LLVOAvatarSelf::*avatar_function)(S32)const = &LLVOAvatarSelf::getVisualParam;
- param->resetDrivenParams();
- if(!param->linkDrivenParams(boost::bind(wearable_function,(LLWearable*)this, _1), false))
- {
- if( !param->linkDrivenParams(boost::bind(avatar_function,gAgentAvatarp.get(),_1 ), true))
- {
- llwarns << "could not link driven params for wearable " << getName() << " id: " << param->getID() << llendl;
- continue;
- }
- }
- }
-}
-
-BOOL LLWearable::importFile( LLFILE* file )
-{
- // *NOTE: changing the type or size of this buffer will require
- // changes in the fscanf() code below. You would be better off
- // rewriting this to use streams and not require an open FILE.
- char text_buffer[2048]; /* Flawfinder: ignore */
- S32 fields_read = 0;
-
- // suppress texlayerset updates while wearables are being imported. Layersets will be updated
- // when the wearables are "worn", not loaded. Note state will be restored when this object is destroyed.
- LLOverrideBakedTextureUpdate stop_bakes(false);
-
- // read header and version
- fields_read = fscanf( file, "LLWearable version %d\n", &mDefinitionVersion );
- if( fields_read != 1 )
- {
- // Shouldn't really log the asset id for security reasons, but
- // we need it in this case.
- llwarns << "Bad Wearable asset header: " << mAssetID << llendl;
- //gVFS->dumpMap();
- return FALSE;
- }
-
-
- // Temoprary hack to allow wearables with definition version 24 to still load.
- // This should only affect lindens and NDA'd testers who have saved wearables in 2.0
- // the extra check for version == 24 can be removed before release, once internal testers
- // have loaded these wearables again. See hack pt 2 at bottom of function to ensure that
- // these wearables get re-saved with version definition 22.
- if( mDefinitionVersion > LLWearable::sCurrentDefinitionVersion && mDefinitionVersion != 24 )
- {
- llwarns << "Wearable asset has newer version (" << mDefinitionVersion << ") than XML (" << LLWearable::sCurrentDefinitionVersion << ")" << llendl;
- return FALSE;
- }
-
- // name
- int next_char = fgetc( file ); /* Flawfinder: ignore */
- if( '\n' == next_char )
- {
- // no name
- mName = "";
- }
- else
- {
- ungetc( next_char, file );
- fields_read = fscanf( /* Flawfinder: ignore */
- file,
- "%2047[^\n]",
- text_buffer);
- if( (1 != fields_read) || (fgetc( file ) != '\n') ) /* Flawfinder: ignore */
- {
- llwarns << "Bad Wearable asset: early end of file" << llendl;
- return FALSE;
- }
- mName = text_buffer;
- LLStringUtil::truncate(mName, DB_INV_ITEM_NAME_STR_LEN );
- }
-
- // description
- next_char = fgetc( file ); /* Flawfinder: ignore */
- if( '\n' == next_char )
- {
- // no description
- mDescription = "";
- }
- else
- {
- ungetc( next_char, file );
- fields_read = fscanf( /* Flawfinder: ignore */
- file,
- "%2047[^\n]",
- text_buffer );
- if( (1 != fields_read) || (fgetc( file ) != '\n') ) /* Flawfinder: ignore */
- {
- llwarns << "Bad Wearable asset: early end of file" << llendl;
- return FALSE;
- }
- mDescription = text_buffer;
- LLStringUtil::truncate(mDescription, DB_INV_ITEM_DESC_STR_LEN );
- }
-
- // permissions
- S32 perm_version;
- fields_read = fscanf( file, " permissions %d\n", &perm_version );
- if( (fields_read != 1) || (perm_version != 0) )
- {
- llwarns << "Bad Wearable asset: missing permissions" << llendl;
- return FALSE;
- }
- if( !mPermissions.importFile( file ) )
- {
- return FALSE;
- }
-
- // sale info
- S32 sale_info_version;
- fields_read = fscanf( file, " sale_info %d\n", &sale_info_version );
- if( (fields_read != 1) || (sale_info_version != 0) )
- {
- llwarns << "Bad Wearable asset: missing sale_info" << llendl;
- return FALSE;
- }
- // Sale info used to contain next owner perm. It is now in the
- // permissions. Thus, we read that out, and fix legacy
- // objects. It's possible this op would fail, but it should pick
- // up the vast majority of the tasks.
- BOOL has_perm_mask = FALSE;
- U32 perm_mask = 0;
- if( !mSaleInfo.importFile(file, has_perm_mask, perm_mask) )
- {
- return FALSE;
- }
- if(has_perm_mask)
- {
- // fair use fix.
- if(!(perm_mask & PERM_COPY))
- {
- perm_mask |= PERM_TRANSFER;
- }
- mPermissions.setMaskNext(perm_mask);
- }
-
- // wearable type
- S32 type = -1;
- fields_read = fscanf( file, "type %d\n", &type );
- if( fields_read != 1 )
- {
- llwarns << "Bad Wearable asset: bad type" << llendl;
- return FALSE;
- }
- if( 0 <= type && type < LLWearableType::WT_COUNT )
- {
- setType((LLWearableType::EType)type);
- }
- else
- {
- mType = LLWearableType::WT_COUNT;
- llwarns << "Bad Wearable asset: bad type #" << type << llendl;
- return FALSE;
- }
-
- // parameters header
- S32 num_parameters = 0;
- fields_read = fscanf( file, "parameters %d\n", &num_parameters );
- if( fields_read != 1 )
- {
- llwarns << "Bad Wearable asset: missing parameters block" << llendl;
- return FALSE;
- }
-
- if( num_parameters != mVisualParamIndexMap.size() )
- {
- llwarns << "Wearable parameter mismatch. Reading in " << num_parameters << " from file, but created " << mVisualParamIndexMap.size() << " from avatar parameters. type: " << mType << llendl;
- }
-
- // parameters
- S32 i;
- for( i = 0; i < num_parameters; i++ )
- {
- S32 param_id = 0;
- F32 param_weight = 0.f;
- fields_read = fscanf( file, "%d %f\n", &param_id, &param_weight );
- if( fields_read != 2 )
- {
- llwarns << "Bad Wearable asset: bad parameter, #" << i << llendl;
- return FALSE;
- }
- mSavedVisualParamMap[param_id] = param_weight;
- }
-
- // textures header
- S32 num_textures = 0;
- fields_read = fscanf( file, "textures %d\n", &num_textures);
- if( fields_read != 1 )
- {
- llwarns << "Bad Wearable asset: missing textures block" << llendl;
- return FALSE;
- }
-
- // textures
- for( i = 0; i < num_textures; i++ )
- {
- S32 te = 0;
- fields_read = fscanf( /* Flawfinder: ignore */
- file,
- "%d %2047s\n",
- &te, text_buffer);
- if( fields_read != 2 )
- {
- llwarns << "Bad Wearable asset: bad texture, #" << i << llendl;
- return FALSE;
- }
-
- if( !LLUUID::validate( text_buffer ) )
- {
- llwarns << "Bad Wearable asset: bad texture uuid: " << text_buffer << llendl;
- return FALSE;
- }
- LLUUID id = LLUUID(text_buffer);
- LLViewerFetchedTexture* image = LLViewerTextureManager::getFetchedTexture( id );
- if( mTEMap.find(te) != mTEMap.end() )
- {
- delete mTEMap[te];
- }
- if( mSavedTEMap.find(te) != mSavedTEMap.end() )
- {
- delete mSavedTEMap[te];
- }
-
- if(gSavedSettings.getBOOL("DebugAvatarLocalTexLoadedTime"))
- {
- image->setLoadedCallback(LLVOAvatarSelf::debugOnTimingLocalTexLoaded,0,TRUE,FALSE, new LLVOAvatarSelf::LLAvatarTexData(id, (LLVOAvatarDefines::ETextureIndex)te), NULL);
- }
- LLUUID textureid(text_buffer);
- mTEMap[te] = new LLLocalTextureObject(image, textureid);
- mSavedTEMap[te] = new LLLocalTextureObject(image, textureid);
- createLayers(te);
- }
-
- // copy all saved param values to working params
- revertValues();
-
- return TRUE;
-}
-
-
-// Avatar parameter and texture definitions can change over time.
-// This function returns true if parameters or textures have been added or removed
-// since this wearable was created.
-BOOL LLWearable::isOldVersion() const
-{
- if (!isAgentAvatarValid()) return FALSE;
-
- if( LLWearable::sCurrentDefinitionVersion < mDefinitionVersion )
- {
- llwarns << "Wearable asset has newer version (" << mDefinitionVersion << ") than XML (" << LLWearable::sCurrentDefinitionVersion << ")" << llendl;
- llassert(0);
- }
-
- if( LLWearable::sCurrentDefinitionVersion != mDefinitionVersion )
- {
- return TRUE;
- }
-
- S32 param_count = 0;
- for( LLViewerVisualParam* param = (LLViewerVisualParam*) gAgentAvatarp->getFirstVisualParam();
- param;
- param = (LLViewerVisualParam*) gAgentAvatarp->getNextVisualParam() )
- {
- if( (param->getWearableType() == mType) && (param->isTweakable() ) )
- {
- param_count++;
- if( !is_in_map(mVisualParamIndexMap, param->getID() ) )
- {
- return TRUE;
- }
- }
- }
- if( param_count != mVisualParamIndexMap.size() )
- {
- return TRUE;
- }
-
-
- S32 te_count = 0;
- for( S32 te = 0; te < TEX_NUM_INDICES; te++ )
- {
- if (LLVOAvatarDictionary::getTEWearableType((ETextureIndex) te) == mType)
- {
- te_count++;
- if( !is_in_map(mTEMap, te ) )
- {
- return TRUE;
- }
- }
- }
- if( te_count != mTEMap.size() )
- {
- return TRUE;
- }
-
- return FALSE;
-}
-
-// Avatar parameter and texture definitions can change over time.
-// * If parameters or textures have been REMOVED since the wearable was created,
-// they're just ignored, so we consider the wearable clean even though isOldVersion()
-// will return true.
-// * If parameters or textures have been ADDED since the wearable was created,
-// they are taken to have default values, so we consider the wearable clean
-// only if those values are the same as the defaults.
-BOOL LLWearable::isDirty() const
-{
- if (!isAgentAvatarValid()) return FALSE;
-
- for( LLViewerVisualParam* param = (LLViewerVisualParam*) gAgentAvatarp->getFirstVisualParam();
- param;
- param = (LLViewerVisualParam*) gAgentAvatarp->getNextVisualParam() )
- {
- if( (param->getWearableType() == mType)
- && (param->isTweakable() )
- && !param->getCrossWearable())
- {
- F32 current_weight = getVisualParamWeight(param->getID());
- current_weight = llclamp( current_weight, param->getMinWeight(), param->getMaxWeight() );
- F32 saved_weight = get_if_there(mSavedVisualParamMap, param->getID(), param->getDefaultWeight());
- saved_weight = llclamp( saved_weight, param->getMinWeight(), param->getMaxWeight() );
-
- U8 a = F32_to_U8( saved_weight, param->getMinWeight(), param->getMaxWeight() );
- U8 b = F32_to_U8( current_weight, param->getMinWeight(), param->getMaxWeight() );
- if( a != b )
- {
- return TRUE;
- }
- }
- }
-
- for( S32 te = 0; te < TEX_NUM_INDICES; te++ )
- {
- if (LLVOAvatarDictionary::getTEWearableType((ETextureIndex) te) == mType)
- {
- te_map_t::const_iterator current_iter = mTEMap.find(te);
- if(current_iter != mTEMap.end())
- {
- const LLUUID& current_image_id = current_iter->second->getID();
- te_map_t::const_iterator saved_iter = mSavedTEMap.find(te);
- if(saved_iter != mSavedTEMap.end())
- {
- const LLUUID& saved_image_id = saved_iter->second->getID();
- if (saved_image_id != current_image_id)
- {
- // saved vs current images are different, wearable is dirty
- return TRUE;
- }
- }
- else
- {
- // image found in current image list but not saved image list
- return TRUE;
- }
- }
- }
- }
-
- return FALSE;
-}
-
-
-void LLWearable::setParamsToDefaults()
-{
- if (!isAgentAvatarValid()) return;
-
- for( LLVisualParam* param = gAgentAvatarp->getFirstVisualParam(); param; param = gAgentAvatarp->getNextVisualParam() )
- {
- if( (((LLViewerVisualParam*)param)->getWearableType() == mType ) && (param->isTweakable() ) )
- {
- setVisualParamWeight(param->getID(),param->getDefaultWeight(), FALSE);
- }
- }
-}
-
-void LLWearable::setTexturesToDefaults()
-{
- for( S32 te = 0; te < TEX_NUM_INDICES; te++ )
- {
- if (LLVOAvatarDictionary::getTEWearableType((ETextureIndex) te) == mType)
- {
- LLUUID id = LLVOAvatarDictionary::getDefaultTextureImageID((ETextureIndex) te);
- LLViewerFetchedTexture * image = LLViewerTextureManager::getFetchedTexture( id );
- if( mTEMap.find(te) == mTEMap.end() )
- {
- mTEMap[te] = new LLLocalTextureObject(image, id);
- createLayers(te);
- }
- else
- {
- // Local Texture Object already created, just set image and UUID
- LLLocalTextureObject *lto = mTEMap[te];
- lto->setID(id);
- lto->setImage(image);
- }
- }
- }
-}
-
-// Updates the user's avatar's appearance
-void LLWearable::writeToAvatar()
-{
- if (!isAgentAvatarValid()) return;
-
- ESex old_sex = gAgentAvatarp->getSex();
-
- // Pull params
- for( LLVisualParam* param = gAgentAvatarp->getFirstVisualParam(); param; param = gAgentAvatarp->getNextVisualParam() )
- {
- // cross-wearable parameters are not authoritative, as they are driven by a different wearable. So don't copy the values to the
- // avatar object if cross wearable. Cross wearable params get their values from the avatar, they shouldn't write the other way.
- if( (((LLViewerVisualParam*)param)->getWearableType() == mType) && (!((LLViewerVisualParam*)param)->getCrossWearable()) )
- {
- S32 param_id = param->getID();
- F32 weight = getVisualParamWeight(param_id);
-
- gAgentAvatarp->setVisualParamWeight( param_id, weight, FALSE );
- }
- }
-
- // Pull texture entries
- for( S32 te = 0; te < TEX_NUM_INDICES; te++ )
- {
- if (LLVOAvatarDictionary::getTEWearableType((ETextureIndex) te) == mType)
- {
- te_map_t::const_iterator iter = mTEMap.find(te);
- LLUUID image_id;
- if(iter != mTEMap.end())
- {
- image_id = iter->second->getID();
- }
- else
- {
- image_id = LLVOAvatarDictionary::getDefaultTextureImageID((ETextureIndex) te);
- }
- LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture( image_id, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE );
- // MULTI-WEARABLE: assume index 0 will be used when writing to avatar. TODO: eliminate the need for this.
- gAgentAvatarp->setLocalTextureTE(te, image, 0);
- }
- }
-
- ESex new_sex = gAgentAvatarp->getSex();
- if( old_sex != new_sex )
- {
- gAgentAvatarp->updateSexDependentLayerSets( FALSE );
- }
-
-// if( upload_bake )
-// {
-// gAgent.sendAgentSetAppearance();
-// }
-}
-
-
-// Updates the user's avatar's appearance, replacing this wearables' parameters and textures with default values.
-// static
-void LLWearable::removeFromAvatar( LLWearableType::EType type, BOOL upload_bake )
-{
- if (!isAgentAvatarValid()) return;
-
- // You can't just remove body parts.
- if( (type == LLWearableType::WT_SHAPE) ||
- (type == LLWearableType::WT_SKIN) ||
- (type == LLWearableType::WT_HAIR) ||
- (type == LLWearableType::WT_EYES) )
- {
- return;
- }
-
- // Pull params
- for( LLVisualParam* param = gAgentAvatarp->getFirstVisualParam(); param; param = gAgentAvatarp->getNextVisualParam() )
- {
- if( (((LLViewerVisualParam*)param)->getWearableType() == type) && (param->isTweakable() ) )
- {
- S32 param_id = param->getID();
- gAgentAvatarp->setVisualParamWeight( param_id, param->getDefaultWeight(), upload_bake );
- }
- }
-
- if(gAgentCamera.cameraCustomizeAvatar())
- {
- LLFloaterSidePanelContainer::showPanel("appearance", LLSD().with("type", "edit_outfit"));
- }
-
- gAgentAvatarp->updateVisualParams();
- gAgentAvatarp->wearableUpdated(type, FALSE);
-
-// if( upload_bake )
-// {
-// gAgent.sendAgentSetAppearance();
-// }
-}
-
-// Does not copy mAssetID.
-// Definition version is current: removes obsolete enties and creates default values for new ones.
-void LLWearable::copyDataFrom(const LLWearable* src)
-{
- if (!isAgentAvatarValid()) return;
-
- mDefinitionVersion = LLWearable::sCurrentDefinitionVersion;
-
- mName = src->mName;
- mDescription = src->mDescription;
- mPermissions = src->mPermissions;
- mSaleInfo = src->mSaleInfo;
-
- setType(src->mType);
-
- mSavedVisualParamMap.clear();
- // Deep copy of mVisualParamMap (copies only those params that are current, filling in defaults where needed)
- for (LLViewerVisualParam* param = (LLViewerVisualParam*) gAgentAvatarp->getFirstVisualParam();
- param;
- param = (LLViewerVisualParam*) gAgentAvatarp->getNextVisualParam() )
- {
- if( (param->getWearableType() == mType) )
- {
- S32 id = param->getID();
- F32 weight = src->getVisualParamWeight(id);
- mSavedVisualParamMap[id] = weight;
- }
- }
-
- destroyTextures();
- // Deep copy of mTEMap (copies only those tes that are current, filling in defaults where needed)
- for (S32 te = 0; te < TEX_NUM_INDICES; te++)
- {
- if (LLVOAvatarDictionary::getTEWearableType((ETextureIndex) te) == mType)
- {
- te_map_t::const_iterator iter = src->mTEMap.find(te);
- LLUUID image_id;
- LLViewerFetchedTexture *image = NULL;
- if(iter != src->mTEMap.end())
- {
- image = src->getLocalTextureObject(te)->getImage();
- image_id = src->getLocalTextureObject(te)->getID();
- mTEMap[te] = new LLLocalTextureObject(image, image_id);
- mSavedTEMap[te] = new LLLocalTextureObject(image, image_id);
- mTEMap[te]->setBakedReady(src->getLocalTextureObject(te)->getBakedReady());
- mTEMap[te]->setDiscard(src->getLocalTextureObject(te)->getDiscard());
- }
- else
- {
- image_id = LLVOAvatarDictionary::getDefaultTextureImageID((ETextureIndex) te);
- image = LLViewerTextureManager::getFetchedTexture( image_id );
- mTEMap[te] = new LLLocalTextureObject(image, image_id);
- mSavedTEMap[te] = new LLLocalTextureObject(image, image_id);
- }
- createLayers(te);
- }
- }
-
- // Probably reduntant, but ensure that the newly created wearable is not dirty by setting current value of params in new wearable
- // to be the same as the saved values (which were loaded from src at param->cloneParam(this))
- revertValues();
-}
-
-void LLWearable::setItemID(const LLUUID& item_id)
-{
- mItemID = item_id;
-}
-
-const LLUUID& LLWearable::getItemID() const
-{
- return mItemID;
-}
-
-void LLWearable::setType(LLWearableType::EType type)
-{
- mType = type;
- createVisualParams();
-}
-
-LLLocalTextureObject* LLWearable::getLocalTextureObject(S32 index)
-{
- te_map_t::iterator iter = mTEMap.find(index);
- if( iter != mTEMap.end() )
- {
- LLLocalTextureObject* lto = iter->second;
- return lto;
- }
- return NULL;
-}
-
-const LLLocalTextureObject* LLWearable::getLocalTextureObject(S32 index) const
-{
- te_map_t::const_iterator iter = mTEMap.find(index);
- if( iter != mTEMap.end() )
- {
- const LLLocalTextureObject* lto = iter->second;
- return lto;
- }
- return NULL;
-}
-
-std::vector<LLLocalTextureObject*> LLWearable::getLocalTextureListSeq()
-{
- std::vector<LLLocalTextureObject*> result;
-
- for(te_map_t::const_iterator iter = mTEMap.begin();
- iter != mTEMap.end(); iter++)
- {
- LLLocalTextureObject* lto = iter->second;
- result.push_back(lto);
- }
-
- return result;
-}
-
-void LLWearable::setLocalTextureObject(S32 index, LLLocalTextureObject &lto)
-{
- if( mTEMap.find(index) != mTEMap.end() )
- {
- mTEMap.erase(index);
- }
- mTEMap[index] = new LLLocalTextureObject(lto);
-}
-
-
-void LLWearable::addVisualParam(LLVisualParam *param)
-{
- if( mVisualParamIndexMap[param->getID()] )
- {
- delete mVisualParamIndexMap[param->getID()];
- }
- param->setIsDummy(FALSE);
- mVisualParamIndexMap[param->getID()] = param;
- mSavedVisualParamMap[param->getID()] = param->getDefaultWeight();
-}
-
-void LLWearable::setVisualParams()
-{
- for (visual_param_index_map_t::const_iterator iter = mVisualParamIndexMap.begin(); iter != mVisualParamIndexMap.end(); iter++)
- {
- S32 id = iter->first;
- LLVisualParam *wearable_param = iter->second;
- F32 value = wearable_param->getWeight();
- gAgentAvatarp->setVisualParamWeight(id, value, FALSE);
- }
-}
-
-
-void LLWearable::setVisualParamWeight(S32 param_index, F32 value, BOOL upload_bake)
-{
- if( is_in_map(mVisualParamIndexMap, param_index ) )
- {
- LLVisualParam *wearable_param = mVisualParamIndexMap[param_index];
- wearable_param->setWeight(value, upload_bake);
- }
- else
- {
- llerrs << "LLWearable::setVisualParam passed invalid parameter index: " << param_index << " for wearable type: " << this->getName() << llendl;
- }
-}
-
-F32 LLWearable::getVisualParamWeight(S32 param_index) const
-{
- if( is_in_map(mVisualParamIndexMap, param_index ) )
- {
- const LLVisualParam *wearable_param = mVisualParamIndexMap.find(param_index)->second;
- return wearable_param->getWeight();
- }
- else
- {
- llwarns << "LLWerable::getVisualParam passed invalid parameter index: " << param_index << " for wearable type: " << this->getName() << llendl;
- }
- return (F32)-1.0;
-}
-
-LLVisualParam* LLWearable::getVisualParam(S32 index) const
-{
- visual_param_index_map_t::const_iterator iter = mVisualParamIndexMap.find(index);
- return (iter == mVisualParamIndexMap.end()) ? NULL : iter->second;
-}
-
-
-void LLWearable::getVisualParams(visual_param_vec_t &list)
-{
- visual_param_index_map_t::iterator iter = mVisualParamIndexMap.begin();
- visual_param_index_map_t::iterator end = mVisualParamIndexMap.end();
-
- // add all visual params to the passed-in vector
- for( ; iter != end; ++iter )
- {
- list.push_back(iter->second);
- }
-}
-
-void LLWearable::animateParams(F32 delta, BOOL upload_bake)
-{
- for(visual_param_index_map_t::iterator iter = mVisualParamIndexMap.begin();
- iter != mVisualParamIndexMap.end();
- ++iter)
- {
- LLVisualParam *param = (LLVisualParam*) iter->second;
- param->animate(delta, upload_bake);
- }
-}
-
-LLColor4 LLWearable::getClothesColor(S32 te) const
-{
- LLColor4 color;
- U32 param_name[3];
- if( LLVOAvatar::teToColorParams( (LLVOAvatarDefines::ETextureIndex)te, param_name ) )
- {
- for( U8 index = 0; index < 3; index++ )
- {
- color.mV[index] = getVisualParamWeight(param_name[index]);
- }
- }
- return color;
-}
-
-void LLWearable::setClothesColor( S32 te, const LLColor4& new_color, BOOL upload_bake )
-{
- U32 param_name[3];
- if( LLVOAvatar::teToColorParams( (LLVOAvatarDefines::ETextureIndex)te, param_name ) )
- {
- for( U8 index = 0; index < 3; index++ )
- {
- setVisualParamWeight(param_name[index], new_color.mV[index], upload_bake);
- }
- }
-}
-
-void LLWearable::revertValues()
-{
- //update saved settings so wearable is no longer dirty
- // non-driver params first
- for (param_map_t::const_iterator iter = mSavedVisualParamMap.begin(); iter != mSavedVisualParamMap.end(); iter++)
- {
- S32 id = iter->first;
- F32 value = iter->second;
- LLVisualParam *param = getVisualParam(id);
- if(param && !dynamic_cast<LLDriverParam*>(param) )
- {
- setVisualParamWeight(id, value, TRUE);
- }
- }
-
- //then driver params
- for (param_map_t::const_iterator iter = mSavedVisualParamMap.begin(); iter != mSavedVisualParamMap.end(); iter++)
- {
- S32 id = iter->first;
- F32 value = iter->second;
- LLVisualParam *param = getVisualParam(id);
- if(param && dynamic_cast<LLDriverParam*>(param) )
- {
- setVisualParamWeight(id, value, TRUE);
- }
- }
-
- // make sure that saved values are sane
- for (param_map_t::const_iterator iter = mSavedVisualParamMap.begin(); iter != mSavedVisualParamMap.end(); iter++)
- {
- S32 id = iter->first;
- LLVisualParam *param = getVisualParam(id);
- if( param )
- {
- mSavedVisualParamMap[id] = param->getWeight();
- }
- }
-
- syncImages(mSavedTEMap, mTEMap);
-
-
- LLSidepanelAppearance *panel = dynamic_cast<LLSidepanelAppearance*>(LLFloaterSidePanelContainer::getPanel("appearance"));
- if( panel )
- {
- panel->updateScrollingPanelList();
- }
-}
-
-BOOL LLWearable::isOnTop() const
-{
- return (this == gAgentWearables.getTopWearable(mType));
-}
-
-void LLWearable::createLayers(S32 te)
-{
- LLTexLayerSet *layer_set = gAgentAvatarp->getLayerSet((ETextureIndex)te);
- if (layer_set)
- {
- layer_set->cloneTemplates(mTEMap[te], (ETextureIndex)te, this);
- }
- else
- {
- llerrs << "could not find layerset for LTO in wearable!" << llendl;
- }
-}
-
-void LLWearable::saveValues()
-{
- //update saved settings so wearable is no longer dirty
- mSavedVisualParamMap.clear();
- for (visual_param_index_map_t::const_iterator iter = mVisualParamIndexMap.begin(); iter != mVisualParamIndexMap.end(); ++iter)
- {
- S32 id = iter->first;
- LLVisualParam *wearable_param = iter->second;
- F32 value = wearable_param->getWeight();
- mSavedVisualParamMap[id] = value;
- }
-
- // Deep copy of mTEMap (copies only those tes that are current, filling in defaults where needed)
- syncImages(mTEMap, mSavedTEMap);
-
-
- LLSidepanelAppearance *panel = dynamic_cast<LLSidepanelAppearance*>(LLFloaterSidePanelContainer::getPanel("appearance"));
- if( panel )
- {
- panel->updateScrollingPanelList();
- }
-}
-
-void LLWearable::syncImages(te_map_t &src, te_map_t &dst)
-{
- // Deep copy of src (copies only those tes that are current, filling in defaults where needed)
- for( S32 te = 0; te < TEX_NUM_INDICES; te++ )
- {
- if (LLVOAvatarDictionary::getTEWearableType((ETextureIndex) te) == mType)
- {
- te_map_t::const_iterator iter = src.find(te);
- LLUUID image_id;
- LLViewerFetchedTexture *image = NULL;
- LLLocalTextureObject *lto = NULL;
- if(iter != src.end())
- {
- // there's a Local Texture Object in the source image map. Use this to populate the values to store in the destination image map.
- lto = iter->second;
- image = lto->getImage();
- image_id = lto->getID();
- }
- else
- {
- // there is no Local Texture Object in the source image map. Get defaults values for populating the destination image map.
- image_id = LLVOAvatarDictionary::getDefaultTextureImageID((ETextureIndex) te);
- image = LLViewerTextureManager::getFetchedTexture( image_id );
- }
-
- if( dst.find(te) != dst.end() )
- {
- // there's already an entry in the destination map for the texture. Just update its values.
- dst[te]->setImage(image);
- dst[te]->setID(image_id);
- }
- else
- {
- // no entry found in the destination map, we need to create a new Local Texture Object
- dst[te] = new LLLocalTextureObject(image, image_id);
- }
-
- if( lto )
- {
- // If we pulled values from a Local Texture Object in the source map, make sure the proper flags are set in the new (or updated) entry in the destination map.
- dst[te]->setBakedReady(lto->getBakedReady());
- dst[te]->setDiscard(lto->getDiscard());
- }
- }
- }
-}
-
-void LLWearable::destroyTextures()
-{
- for( te_map_t::iterator iter = mTEMap.begin(); iter != mTEMap.end(); ++iter )
- {
- LLLocalTextureObject *lto = iter->second;
- delete lto;
- }
- mTEMap.clear();
- for( te_map_t::iterator iter = mSavedTEMap.begin(); iter != mSavedTEMap.end(); ++iter )
- {
- LLLocalTextureObject *lto = iter->second;
- delete lto;
- }
- mSavedTEMap.clear();
-}
-
-void LLWearable::pullCrossWearableValues()
-{
- // scan through all of the avatar's visual parameters
- for (LLViewerVisualParam* param = (LLViewerVisualParam*) gAgentAvatarp->getFirstVisualParam();
- param;
- param = (LLViewerVisualParam*) gAgentAvatarp->getNextVisualParam())
- {
- if( param )
- {
- LLDriverParam *driver_param = dynamic_cast<LLDriverParam*>(param);
- if(driver_param)
- {
- // parameter is a driver parameter, have it update its
- driver_param->updateCrossDrivenParams(getType());
- }
- }
- }
-}
-
-
-void LLWearable::setLabelUpdated() const
-{
- gInventory.addChangedMask(LLInventoryObserver::LABEL, getItemID());
-}
-
-void LLWearable::refreshName()
-{
- LLUUID item_id = getItemID();
- LLInventoryItem* item = gInventory.getItem(item_id);
- if( item )
- {
- mName = item->getName();
- }
-}
-
-struct LLWearableSaveData
-{
- LLWearableType::EType mType;
-};
-
-void LLWearable::saveNewAsset() const
-{
-// llinfos << "LLWearable::saveNewAsset() type: " << getTypeName() << llendl;
- //llinfos << *this << llendl;
-
- const std::string filename = asset_id_to_filename(mAssetID);
- LLFILE* fp = LLFile::fopen(filename, "wb"); /* Flawfinder: ignore */
- BOOL successful_save = FALSE;
- if(fp && exportFile(fp))
- {
- successful_save = TRUE;
- }
- if(fp)
- {
- fclose(fp);
- fp = NULL;
- }
- if(!successful_save)
- {
- std::string buffer = llformat("Unable to save '%s' to wearable file.", mName.c_str());
- llwarns << buffer << llendl;
-
- LLSD args;
- args["NAME"] = mName;
- LLNotificationsUtil::add("CannotSaveWearableOutOfSpace", args);
- return;
- }
-
- // save it out to database
- if( gAssetStorage )
- {
- /*
- std::string url = gAgent.getRegion()->getCapability("NewAgentInventory");
- if (!url.empty())
- {
- llinfos << "Update Agent Inventory via capability" << llendl;
- LLSD body;
- body["folder_id"] = gInventory.findCategoryUUIDForType(LLFolderType::assetToFolderType(getAssetType()));
- body["asset_type"] = LLAssetType::lookup(getAssetType());
- body["inventory_type"] = LLInventoryType::lookup(LLInventoryType::IT_WEARABLE);
- body["name"] = getName();
- body["description"] = getDescription();
- LLHTTPClient::post(url, body, new LLNewAgentInventoryResponder(body, filename));
- }
- else
- {
- }
- */
- LLWearableSaveData* data = new LLWearableSaveData;
- data->mType = mType;
- gAssetStorage->storeAssetData(filename, mTransactionID, getAssetType(),
- &LLWearable::onSaveNewAssetComplete,
- (void*)data);
- }
-}
-
-// static
-void LLWearable::onSaveNewAssetComplete(const LLUUID& new_asset_id, void* userdata, S32 status, LLExtStat ext_status) // StoreAssetData callback (fixed)
-{
- LLWearableSaveData* data = (LLWearableSaveData*)userdata;
- const std::string& type_name = LLWearableType::getTypeName(data->mType);
- if(0 == status)
- {
- // Success
- llinfos << "Saved wearable " << type_name << llendl;
- }
- else
- {
- std::string buffer = llformat("Unable to save %s to central asset store.", type_name.c_str());
- llwarns << buffer << " Status: " << status << llendl;
- LLSD args;
- args["NAME"] = type_name;
- LLNotificationsUtil::add("CannotSaveToAssetStore", args);
- }
-
- // Delete temp file
- const std::string src_filename = asset_id_to_filename(new_asset_id);
- LLFile::remove(src_filename);
-
- // delete the context data
- delete data;
-
-}
-
-std::ostream& operator<<(std::ostream &s, const LLWearable &w)
-{
- s << "wearable " << LLWearableType::getTypeName(w.mType) << "\n";
- s << " Name: " << w.mName << "\n";
- s << " Desc: " << w.mDescription << "\n";
- //w.mPermissions
- //w.mSaleInfo
-
- s << " Params:" << "\n";
- for (LLWearable::visual_param_index_map_t::const_iterator iter = w.mVisualParamIndexMap.begin();
- iter != w.mVisualParamIndexMap.end(); ++iter)
- {
- S32 param_id = iter->first;
- LLVisualParam *wearable_param = iter->second;
- F32 param_weight = wearable_param->getWeight();
- s << " " << param_id << " " << param_weight << "\n";
- }
-
- s << " Textures:" << "\n";
- for (LLWearable::te_map_t::const_iterator iter = w.mTEMap.begin();
- iter != w.mTEMap.end(); ++iter)
- {
- S32 te = iter->first;
- const LLUUID& image_id = iter->second->getID();
- s << " " << te << " " << image_id << "\n";
- }
- return s;
-}
-
-
-std::string terse_F32_to_string(F32 f)
-{
- std::string r = llformat("%.2f", f);
- S32 len = r.length();
-
- // "1.20" -> "1.2"
- // "24.00" -> "24."
- while (len > 0 && ('0' == r[len - 1]))
- {
- r.erase(len-1, 1);
- len--;
- }
- if ('.' == r[len - 1])
- {
- // "24." -> "24"
- r.erase(len-1, 1);
- }
- else if (('-' == r[0]) && ('0' == r[1]))
- {
- // "-0.59" -> "-.59"
- r.erase(1, 1);
- }
- else if ('0' == r[0])
- {
- // "0.59" -> ".59"
- r.erase(0, 1);
- }
- return r;
-}
-
-std::string asset_id_to_filename(const LLUUID &asset_id)
-{
- std::string asset_id_string;
- asset_id.toString(asset_id_string);
- std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,asset_id_string) + ".wbl";
- return filename;
-}
diff --git a/indra/newview/llwearable.h b/indra/newview/llwearable.h
deleted file mode 100644
index 3d8c53a755..0000000000
--- a/indra/newview/llwearable.h
+++ /dev/null
@@ -1,165 +0,0 @@
-/**
- * @file llwearable.h
- * @brief LLWearable class header file
- *
- * $LicenseInfo:firstyear=2002&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$
- */
-
-#ifndef LL_LLWEARABLE_H
-#define LL_LLWEARABLE_H
-
-#include "lluuid.h"
-#include "llstring.h"
-#include "llpermissions.h"
-#include "llsaleinfo.h"
-#include "llassetstorage.h"
-#include "llwearabletype.h"
-#include "llfile.h"
-#include "lllocaltextureobject.h"
-
-class LLViewerInventoryItem;
-class LLVisualParam;
-class LLTexGlobalColorInfo;
-class LLTexGlobalColor;
-
-class LLWearable
-{
- friend class LLWearableList;
-
- //--------------------------------------------------------------------
- // Constructors and destructors
- //--------------------------------------------------------------------
-private:
- // Private constructors used by LLWearableList
- LLWearable(const LLTransactionID& transactionID);
- LLWearable(const LLAssetID& assetID);
-public:
- virtual ~LLWearable();
-
- //--------------------------------------------------------------------
- // Accessors
- //--------------------------------------------------------------------
-public:
- const LLUUID& getItemID() const;
- const LLAssetID& getAssetID() const { return mAssetID; }
- const LLTransactionID& getTransactionID() const { return mTransactionID; }
- LLWearableType::EType getType() const { return mType; }
- void setType(LLWearableType::EType type);
- const std::string& getName() const { return mName; }
- void setName(const std::string& name) { mName = name; }
- const std::string& getDescription() const { return mDescription; }
- void setDescription(const std::string& desc) { mDescription = desc; }
- const LLPermissions& getPermissions() const { return mPermissions; }
- void setPermissions(const LLPermissions& p) { mPermissions = p; }
- const LLSaleInfo& getSaleInfo() const { return mSaleInfo; }
- void setSaleInfo(const LLSaleInfo& info) { mSaleInfo = info; }
- const std::string& getTypeLabel() const;
- const std::string& getTypeName() const;
- LLAssetType::EType getAssetType() const;
- S32 getDefinitionVersion() const { return mDefinitionVersion; }
- void setDefinitionVersion( S32 new_version ) { mDefinitionVersion = new_version; }
-
-public:
- typedef std::vector<LLVisualParam*> visual_param_vec_t;
-
- BOOL isDirty() const;
- BOOL isOldVersion() const;
-
- void writeToAvatar();
- void removeFromAvatar( BOOL upload_bake ) { LLWearable::removeFromAvatar( mType, upload_bake ); }
- static void removeFromAvatar( LLWearableType::EType type, BOOL upload_bake );
-
- BOOL exportFile(LLFILE* file) const;
- BOOL importFile(LLFILE* file);
-
- void setParamsToDefaults();
- void setTexturesToDefaults();
-
- void saveNewAsset() const;
- static void onSaveNewAssetComplete( const LLUUID& asset_uuid, void* user_data, S32 status, LLExtStat ext_status );
-
- void copyDataFrom(const LLWearable* src);
-
- static void setCurrentDefinitionVersion( S32 version ) { LLWearable::sCurrentDefinitionVersion = version; }
-
- friend std::ostream& operator<<(std::ostream &s, const LLWearable &w);
- void setItemID(const LLUUID& item_id);
-
- LLLocalTextureObject* getLocalTextureObject(S32 index);
- const LLLocalTextureObject* getLocalTextureObject(S32 index) const;
- std::vector<LLLocalTextureObject*> getLocalTextureListSeq();
-
- void setLocalTextureObject(S32 index, LLLocalTextureObject &lto);
- void addVisualParam(LLVisualParam *param);
- void setVisualParams();
- void setVisualParamWeight(S32 index, F32 value, BOOL upload_bake);
- F32 getVisualParamWeight(S32 index) const;
- LLVisualParam* getVisualParam(S32 index) const;
- void getVisualParams(visual_param_vec_t &list);
- void animateParams(F32 delta, BOOL upload_bake);
-
- LLColor4 getClothesColor(S32 te) const;
- void setClothesColor( S32 te, const LLColor4& new_color, BOOL upload_bake );
-
- void revertValues();
- void saveValues();
- void pullCrossWearableValues();
-
- BOOL isOnTop() const;
-
- // Something happened that requires the wearable's label to be updated (e.g. worn/unworn).
- void setLabelUpdated() const;
-
- // the wearable was worn. make sure the name of the wearable object matches the LLViewerInventoryItem,
- // not the wearable asset itself.
- void refreshName();
-
-private:
- typedef std::map<S32, LLLocalTextureObject*> te_map_t;
- typedef std::map<S32, LLVisualParam *> visual_param_index_map_t;
-
- void createLayers(S32 te);
- void createVisualParams();
- void syncImages(te_map_t &src, te_map_t &dst);
- void destroyTextures();
-
- static S32 sCurrentDefinitionVersion; // Depends on the current state of the avatar_lad.xml.
- S32 mDefinitionVersion; // Depends on the state of the avatar_lad.xml when this asset was created.
- std::string mName;
- std::string mDescription;
- LLPermissions mPermissions;
- LLSaleInfo mSaleInfo;
- LLAssetID mAssetID;
- LLTransactionID mTransactionID;
- LLWearableType::EType mType;
-
- typedef std::map<S32, F32> param_map_t;
- param_map_t mSavedVisualParamMap; // last saved version of visual params
-
- visual_param_index_map_t mVisualParamIndexMap;
-
- te_map_t mTEMap; // maps TE to LocalTextureObject
- te_map_t mSavedTEMap; // last saved version of TEMap
- LLUUID mItemID; // ID of the inventory item in the agent's inventory
-};
-
-#endif // LL_LLWEARABLE_H
diff --git a/indra/newview/llwearableitemslist.cpp b/indra/newview/llwearableitemslist.cpp
index 92697fb2eb..c196d70617 100644..100755
--- a/indra/newview/llwearableitemslist.cpp
+++ b/indra/newview/llwearableitemslist.cpp
@@ -34,6 +34,7 @@
#include "llagentwearables.h"
#include "llappearancemgr.h"
#include "llinventoryfunctions.h"
+#include "llinventoryicon.h"
#include "lltransutil.h"
#include "llviewerattachmenu.h"
#include "llvoavatarself.h"
@@ -788,23 +789,24 @@ LLContextMenu* LLWearableItemsList::ContextMenu::createMenu()
const uuid_vec_t& ids = mUUIDs; // selected items IDs
LLUUID selected_id = ids.front(); // ID of the first selected item
- functor_t take_off = boost::bind(&LLAppearanceMgr::removeItemFromAvatar, LLAppearanceMgr::getInstance(), _1);
-
// Register handlers common for all wearable types.
registrar.add("Wearable.Wear", boost::bind(wear_multiple, ids, true));
registrar.add("Wearable.Add", boost::bind(wear_multiple, ids, false));
registrar.add("Wearable.Edit", boost::bind(handleMultiple, LLAgentWearables::editWearable, ids));
registrar.add("Wearable.CreateNew", boost::bind(createNewWearable, selected_id));
registrar.add("Wearable.ShowOriginal", boost::bind(show_item_original, selected_id));
- registrar.add("Wearable.TakeOffDetach", boost::bind(handleMultiple, take_off, ids));
+ registrar.add("Wearable.TakeOffDetach",
+ boost::bind(&LLAppearanceMgr::removeItemsFromAvatar, LLAppearanceMgr::getInstance(), ids));
// Register handlers for clothing.
- registrar.add("Clothing.TakeOff", boost::bind(handleMultiple, take_off, ids));
+ registrar.add("Clothing.TakeOff",
+ boost::bind(&LLAppearanceMgr::removeItemsFromAvatar, LLAppearanceMgr::getInstance(), ids));
// Register handlers for body parts.
// Register handlers for attachments.
- registrar.add("Attachment.Detach", boost::bind(handleMultiple, take_off, ids));
+ registrar.add("Attachment.Detach",
+ boost::bind(&LLAppearanceMgr::removeItemsFromAvatar, LLAppearanceMgr::getInstance(), ids));
registrar.add("Attachment.Profile", boost::bind(show_item_profile, selected_id));
registrar.add("Object.Attach", boost::bind(LLViewerAttachMenu::attachObjects, ids, _2));
diff --git a/indra/newview/llwearableitemslist.h b/indra/newview/llwearableitemslist.h
index a8a5ef3117..a8a5ef3117 100644..100755
--- a/indra/newview/llwearableitemslist.h
+++ b/indra/newview/llwearableitemslist.h
diff --git a/indra/newview/llwearablelist.cpp b/indra/newview/llwearablelist.cpp
index 6f6411ce3c..ef1a953f59 100644..100755
--- a/indra/newview/llwearablelist.cpp
+++ b/indra/newview/llwearablelist.cpp
@@ -42,20 +42,23 @@ struct LLWearableArrivedData
{
LLWearableArrivedData(LLAssetType::EType asset_type,
const std::string& wearable_name,
- void(*asset_arrived_callback)(LLWearable*, void* userdata),
+ LLAvatarAppearance* avatarp,
+ void(*asset_arrived_callback)(LLViewerWearable*, void* userdata),
void* userdata) :
mAssetType( asset_type ),
mCallback( asset_arrived_callback ),
mUserdata( userdata ),
mName( wearable_name ),
- mRetries(0)
+ mRetries(0),
+ mAvatarp(avatarp)
{}
LLAssetType::EType mAssetType;
- void (*mCallback)(LLWearable*, void* userdata);
+ void (*mCallback)(LLViewerWearable*, void* userdata);
void* mUserdata;
std::string mName;
S32 mRetries;
+ LLAvatarAppearance *mAvatarp;
};
////////////////////////////////////////////////////////////////////////////
@@ -72,10 +75,10 @@ void LLWearableList::cleanup()
mList.clear();
}
-void LLWearableList::getAsset(const LLAssetID& assetID, const std::string& wearable_name, LLAssetType::EType asset_type, void(*asset_arrived_callback)(LLWearable*, void* userdata), void* userdata)
+void LLWearableList::getAsset(const LLAssetID& assetID, const std::string& wearable_name, LLAvatarAppearance* avatarp, LLAssetType::EType asset_type, void(*asset_arrived_callback)(LLViewerWearable*, void* userdata), void* userdata)
{
llassert( (asset_type == LLAssetType::AT_CLOTHING) || (asset_type == LLAssetType::AT_BODYPART) );
- LLWearable* instance = get_if_there(mList, assetID, (LLWearable*)NULL );
+ LLViewerWearable* instance = get_if_there(mList, assetID, (LLViewerWearable*)NULL );
if( instance )
{
asset_arrived_callback( instance, userdata );
@@ -85,7 +88,7 @@ void LLWearableList::getAsset(const LLAssetID& assetID, const std::string& weara
gAssetStorage->getAssetData(assetID,
asset_type,
LLWearableList::processGetAssetReply,
- (void*)new LLWearableArrivedData( asset_type, wearable_name, asset_arrived_callback, userdata ),
+ (void*)new LLWearableArrivedData( asset_type, wearable_name, avatarp, asset_arrived_callback, userdata ),
TRUE);
}
}
@@ -95,25 +98,31 @@ void LLWearableList::processGetAssetReply( const char* filename, const LLAssetID
{
BOOL isNewWearable = FALSE;
LLWearableArrivedData* data = (LLWearableArrivedData*) userdata;
- LLWearable* wearable = NULL; // NULL indicates failure
+ LLViewerWearable* wearable = NULL; // NULL indicates failure
+ LLAvatarAppearance *avatarp = data->mAvatarp;
if( !filename )
{
LL_WARNS("Wearable") << "Bad Wearable Asset: missing file." << LL_ENDL;
}
+ else if(!avatarp)
+ {
+ LL_WARNS("Wearable") << "Bad asset request: missing avatar pointer." << LL_ENDL;
+ }
else if (status >= 0)
{
// read the file
- LLFILE* fp = LLFile::fopen(std::string(filename), "rb"); /*Flawfinder: ignore*/
- if( !fp )
+ llifstream ifs(filename, llifstream::binary);
+ if( !ifs.is_open() )
{
LL_WARNS("Wearable") << "Bad Wearable Asset: unable to open file: '" << filename << "'" << LL_ENDL;
}
else
{
- wearable = new LLWearable(uuid);
- bool res = wearable->importFile( fp );
- if (!res)
+ wearable = new LLViewerWearable(uuid);
+ LLWearable::EImportResult result = wearable->importStream(
+ ifs, avatarp );
+ if (LLWearable::SUCCESS != result)
{
if (wearable->getType() == LLWearableType::WT_COUNT)
{
@@ -123,9 +132,12 @@ void LLWearableList::processGetAssetReply( const char* filename, const LLAssetID
wearable = NULL;
}
- fclose( fp );
if(filename)
{
+ if (ifs.is_open())
+ {
+ ifs.close();
+ }
LLFile::remove(std::string(filename));
}
}
@@ -203,11 +215,11 @@ void LLWearableList::processGetAssetReply( const char* filename, const LLAssetID
}
-LLWearable* LLWearableList::createCopy(const LLWearable* old_wearable, const std::string& new_name)
+LLViewerWearable* LLWearableList::createCopy(const LLViewerWearable* old_wearable, const std::string& new_name)
{
lldebugs << "LLWearableList::createCopy()" << llendl;
- LLWearable *wearable = generateNewWearable();
+ LLViewerWearable *wearable = generateNewWearable();
wearable->copyDataFrom(old_wearable);
LLPermissions perm(old_wearable->getPermissions());
@@ -222,12 +234,12 @@ LLWearable* LLWearableList::createCopy(const LLWearable* old_wearable, const std
return wearable;
}
-LLWearable* LLWearableList::createNewWearable( LLWearableType::EType type )
+LLViewerWearable* LLWearableList::createNewWearable( LLWearableType::EType type, LLAvatarAppearance *avatarp )
{
lldebugs << "LLWearableList::createNewWearable()" << llendl;
- LLWearable *wearable = generateNewWearable();
- wearable->setType( type );
+ LLViewerWearable *wearable = generateNewWearable();
+ wearable->setType( type, avatarp );
std::string name = LLTrans::getString( LLWearableType::getTypeDefaultNewName(wearable->getType()) );
wearable->setName( name );
@@ -237,6 +249,8 @@ LLWearable* LLWearableList::createNewWearable( LLWearableType::EType type )
perm.initMasks(PERM_ALL, PERM_ALL, PERM_NONE, PERM_NONE, PERM_MOVE | PERM_TRANSFER);
wearable->setPermissions(perm);
+ wearable->setDefinitionVersion(LLWearable::getCurrentDefinitionVersion());
+
// Description and sale info have default values.
wearable->setParamsToDefaults();
wearable->setTexturesToDefaults();
@@ -251,13 +265,13 @@ LLWearable* LLWearableList::createNewWearable( LLWearableType::EType type )
return wearable;
}
-LLWearable *LLWearableList::generateNewWearable()
+LLViewerWearable *LLWearableList::generateNewWearable()
{
LLTransactionID tid;
tid.generate();
LLAssetID new_asset_id = tid.makeAssetID(gAgent.getSecureSessionID());
- LLWearable* wearable = new LLWearable(tid);
+ LLViewerWearable* wearable = new LLViewerWearable(tid);
mList[new_asset_id] = wearable;
return wearable;
}
diff --git a/indra/newview/llwearablelist.h b/indra/newview/llwearablelist.h
index 12d0037aee..d6f0fd09a6 100644..100755
--- a/indra/newview/llwearablelist.h
+++ b/indra/newview/llwearablelist.h
@@ -28,7 +28,7 @@
#define LL_LLWEARABLELIST_H
#include "llmemory.h"
-#include "llwearable.h"
+#include "llviewerwearable.h"
#include "lluuid.h"
#include "llassetstorage.h"
@@ -50,20 +50,21 @@ public:
void getAsset(const LLAssetID& assetID,
const std::string& wearable_name,
+ LLAvatarAppearance *avatarp,
LLAssetType::EType asset_type,
- void(*asset_arrived_callback)(LLWearable*, void* userdata),
+ void(*asset_arrived_callback)(LLViewerWearable*, void* userdata),
void* userdata);
- LLWearable* createCopy(const LLWearable* old_wearable, const std::string& new_name = std::string());
- LLWearable* createNewWearable(LLWearableType::EType type);
+ LLViewerWearable* createCopy(const LLViewerWearable* old_wearable, const std::string& new_name = std::string());
+ LLViewerWearable* createNewWearable(LLWearableType::EType type, LLAvatarAppearance *avatarp);
// Callback
static void processGetAssetReply(const char* filename, const LLAssetID& assetID, void* user_data, S32 status, LLExtStat ext_status);
protected:
- LLWearable* generateNewWearable(); // used for the create... functions
+ LLViewerWearable* generateNewWearable(); // used for the create... functions
private:
- std::map<LLUUID, LLWearable*> mList;
+ std::map<LLUUID, LLViewerWearable*> mList;
};
#endif // LL_LLWEARABLELIST_H
diff --git a/indra/newview/llwearabletype.cpp b/indra/newview/llwearabletype.cpp
deleted file mode 100644
index c090ab5c3d..0000000000
--- a/indra/newview/llwearabletype.cpp
+++ /dev/null
@@ -1,159 +0,0 @@
-/**
- * @file llwearabletype.cpp
- * @brief LLWearableType class implementation
- *
- * $LicenseInfo:firstyear=2002&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 "llviewerprecompiledheaders.h"
-#include "llwearabletype.h"
-#include "llinventoryfunctions.h"
-#include "lltrans.h"
-
-struct WearableEntry : public LLDictionaryEntry
-{
- WearableEntry(const std::string &name,
- const std::string& default_new_name,
- LLAssetType::EType assetType,
- LLInventoryIcon::EIconName iconName,
- BOOL disable_camera_switch = FALSE,
- BOOL allow_multiwear = TRUE) :
- LLDictionaryEntry(name),
- mAssetType(assetType),
- mDefaultNewName(default_new_name),
- mLabel(LLTrans::getString(name)),
- mIconName(iconName),
- mDisableCameraSwitch(disable_camera_switch),
- mAllowMultiwear(allow_multiwear)
- {
-
- }
- const LLAssetType::EType mAssetType;
- const std::string mLabel;
- const std::string mDefaultNewName; //keep mLabel for backward compatibility
- LLInventoryIcon::EIconName mIconName;
- BOOL mDisableCameraSwitch;
- BOOL mAllowMultiwear;
-};
-
-class LLWearableDictionary : public LLSingleton<LLWearableDictionary>,
- public LLDictionary<LLWearableType::EType, WearableEntry>
-{
-public:
- LLWearableDictionary();
-};
-
-LLWearableDictionary::LLWearableDictionary()
-{
- addEntry(LLWearableType::WT_SHAPE, new WearableEntry("shape", "New Shape", LLAssetType::AT_BODYPART, LLInventoryIcon::ICONNAME_BODYPART_SHAPE, FALSE, FALSE));
- addEntry(LLWearableType::WT_SKIN, new WearableEntry("skin", "New Skin", LLAssetType::AT_BODYPART, LLInventoryIcon::ICONNAME_BODYPART_SKIN, FALSE, FALSE));
- addEntry(LLWearableType::WT_HAIR, new WearableEntry("hair", "New Hair", LLAssetType::AT_BODYPART, LLInventoryIcon::ICONNAME_BODYPART_HAIR, FALSE, FALSE));
- addEntry(LLWearableType::WT_EYES, new WearableEntry("eyes", "New Eyes", LLAssetType::AT_BODYPART, LLInventoryIcon::ICONNAME_BODYPART_EYES, FALSE, FALSE));
- addEntry(LLWearableType::WT_SHIRT, new WearableEntry("shirt", "New Shirt", LLAssetType::AT_CLOTHING, LLInventoryIcon::ICONNAME_CLOTHING_SHIRT, FALSE, TRUE));
- addEntry(LLWearableType::WT_PANTS, new WearableEntry("pants", "New Pants", LLAssetType::AT_CLOTHING, LLInventoryIcon::ICONNAME_CLOTHING_PANTS, FALSE, TRUE));
- addEntry(LLWearableType::WT_SHOES, new WearableEntry("shoes", "New Shoes", LLAssetType::AT_CLOTHING, LLInventoryIcon::ICONNAME_CLOTHING_SHOES, FALSE, TRUE));
- addEntry(LLWearableType::WT_SOCKS, new WearableEntry("socks", "New Socks", LLAssetType::AT_CLOTHING, LLInventoryIcon::ICONNAME_CLOTHING_SOCKS, FALSE, TRUE));
- addEntry(LLWearableType::WT_JACKET, new WearableEntry("jacket", "New Jacket", LLAssetType::AT_CLOTHING, LLInventoryIcon::ICONNAME_CLOTHING_JACKET, FALSE, TRUE));
- addEntry(LLWearableType::WT_GLOVES, new WearableEntry("gloves", "New Gloves", LLAssetType::AT_CLOTHING, LLInventoryIcon::ICONNAME_CLOTHING_GLOVES, FALSE, TRUE));
- addEntry(LLWearableType::WT_UNDERSHIRT, new WearableEntry("undershirt", "New Undershirt", LLAssetType::AT_CLOTHING, LLInventoryIcon::ICONNAME_CLOTHING_UNDERSHIRT, FALSE, TRUE));
- addEntry(LLWearableType::WT_UNDERPANTS, new WearableEntry("underpants", "New Underpants", LLAssetType::AT_CLOTHING, LLInventoryIcon::ICONNAME_CLOTHING_UNDERPANTS, FALSE, TRUE));
- addEntry(LLWearableType::WT_SKIRT, new WearableEntry("skirt", "New Skirt", LLAssetType::AT_CLOTHING, LLInventoryIcon::ICONNAME_CLOTHING_SKIRT, FALSE, TRUE));
- addEntry(LLWearableType::WT_ALPHA, new WearableEntry("alpha", "New Alpha", LLAssetType::AT_CLOTHING, LLInventoryIcon::ICONNAME_CLOTHING_ALPHA, FALSE, TRUE));
- addEntry(LLWearableType::WT_TATTOO, new WearableEntry("tattoo", "New Tattoo", LLAssetType::AT_CLOTHING, LLInventoryIcon::ICONNAME_CLOTHING_TATTOO, FALSE, TRUE));
-
- addEntry(LLWearableType::WT_PHYSICS, new WearableEntry("physics", "New Physics", LLAssetType::AT_CLOTHING, LLInventoryIcon::ICONNAME_CLOTHING_PHYSICS, TRUE, TRUE));
-
- addEntry(LLWearableType::WT_INVALID, new WearableEntry("invalid", "Invalid Wearable", LLAssetType::AT_NONE, LLInventoryIcon::ICONNAME_NONE, FALSE, FALSE));
- addEntry(LLWearableType::WT_NONE, new WearableEntry("none", "Invalid Wearable", LLAssetType::AT_NONE, LLInventoryIcon::ICONNAME_NONE, FALSE, FALSE));
-}
-
-// static
-LLWearableType::EType LLWearableType::typeNameToType(const std::string& type_name)
-{
- const LLWearableDictionary *dict = LLWearableDictionary::getInstance();
- const LLWearableType::EType wearable = dict->lookup(type_name);
- return wearable;
-}
-
-// static
-const std::string& LLWearableType::getTypeName(LLWearableType::EType type)
-{
- const LLWearableDictionary *dict = LLWearableDictionary::getInstance();
- const WearableEntry *entry = dict->lookup(type);
- if (!entry) return getTypeName(WT_INVALID);
- return entry->mName;
-}
-
-//static
-const std::string& LLWearableType::getTypeDefaultNewName(LLWearableType::EType type)
-{
- const LLWearableDictionary *dict = LLWearableDictionary::getInstance();
- const WearableEntry *entry = dict->lookup(type);
- if (!entry) return getTypeDefaultNewName(WT_INVALID);
- return entry->mDefaultNewName;
-}
-
-// static
-const std::string& LLWearableType::getTypeLabel(LLWearableType::EType type)
-{
- const LLWearableDictionary *dict = LLWearableDictionary::getInstance();
- const WearableEntry *entry = dict->lookup(type);
- if (!entry) return getTypeLabel(WT_INVALID);
- return entry->mLabel;
-}
-
-// static
-LLAssetType::EType LLWearableType::getAssetType(LLWearableType::EType type)
-{
- const LLWearableDictionary *dict = LLWearableDictionary::getInstance();
- const WearableEntry *entry = dict->lookup(type);
- if (!entry) return getAssetType(WT_INVALID);
- return entry->mAssetType;
-}
-
-// static
-LLInventoryIcon::EIconName LLWearableType::getIconName(LLWearableType::EType type)
-{
- const LLWearableDictionary *dict = LLWearableDictionary::getInstance();
- const WearableEntry *entry = dict->lookup(type);
- if (!entry) return getIconName(WT_INVALID);
- return entry->mIconName;
-}
-
-// static
-BOOL LLWearableType::getDisableCameraSwitch(LLWearableType::EType type)
-{
- const LLWearableDictionary *dict = LLWearableDictionary::getInstance();
- const WearableEntry *entry = dict->lookup(type);
- if (!entry) return FALSE;
- return entry->mDisableCameraSwitch;
-}
-
-// static
-BOOL LLWearableType::getAllowMultiwear(LLWearableType::EType type)
-{
- const LLWearableDictionary *dict = LLWearableDictionary::getInstance();
- const WearableEntry *entry = dict->lookup(type);
- if (!entry) return FALSE;
- return entry->mAllowMultiwear;
-}
-
diff --git a/indra/newview/llwearabletype.h b/indra/newview/llwearabletype.h
deleted file mode 100644
index d633b4807e..0000000000
--- a/indra/newview/llwearabletype.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/**
- * @file llwearabletype.h
- * @brief LLWearableType class header file
- *
- * $LicenseInfo:firstyear=2002&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$
- */
-
-#ifndef LL_LLWEARABLETYPE_H
-#define LL_LLWEARABLETYPE_H
-
-#include "llassettype.h"
-#include "lldictionary.h"
-#include "llinventoryicon.h"
-#include "llsingleton.h"
-
-class LLWearableType
-{
-public:
- enum EType
- {
- WT_SHAPE = 0,
- WT_SKIN = 1,
- WT_HAIR = 2,
- WT_EYES = 3,
- WT_SHIRT = 4,
- WT_PANTS = 5,
- WT_SHOES = 6,
- WT_SOCKS = 7,
- WT_JACKET = 8,
- WT_GLOVES = 9,
- WT_UNDERSHIRT = 10,
- WT_UNDERPANTS = 11,
- WT_SKIRT = 12,
- WT_ALPHA = 13,
- WT_TATTOO = 14,
- WT_PHYSICS = 15,
- WT_COUNT = 16,
-
- WT_INVALID = 255,
- WT_NONE = -1,
- };
-
- static const std::string& getTypeName(EType type);
- static const std::string& getTypeDefaultNewName(EType type);
- static const std::string& getTypeLabel(EType type);
- static LLAssetType::EType getAssetType(EType type);
- static EType typeNameToType(const std::string& type_name);
- static LLInventoryIcon::EIconName getIconName(EType type);
- static BOOL getDisableCameraSwitch(EType type);
- static BOOL getAllowMultiwear(EType type);
-
-protected:
- LLWearableType() {}
- ~LLWearableType() {}
-};
-
-#endif // LL_LLWEARABLETYPE_H
diff --git a/indra/newview/llweb.cpp b/indra/newview/llweb.cpp
index d2d48dc68f..83337b386d 100644..100755
--- a/indra/newview/llweb.cpp
+++ b/indra/newview/llweb.cpp
@@ -185,8 +185,8 @@ std::string LLWeb::expandURLSubstitutions(const std::string &url,
substitution["VERSION_PATCH"] = LLVersionInfo::getPatch();
substitution["VERSION_BUILD"] = LLVersionInfo::getBuild();
substitution["CHANNEL"] = LLVersionInfo::getChannel();
- substitution["GRID"] = LLGridManager::getInstance()->getGridLabel();
- substitution["GRID_LOWERCASE"] = utf8str_tolower(LLGridManager::getInstance()->getGridLabel());
+ substitution["GRID"] = LLGridManager::getInstance()->getGridId();
+ substitution["GRID_LOWERCASE"] = utf8str_tolower(LLGridManager::getInstance()->getGridId());
substitution["OS"] = LLAppViewer::instance()->getOSInfo().getOSStringSimple();
substitution["SESSION_ID"] = gAgent.getSessionID();
substitution["FIRST_LOGIN"] = gAgent.isFirstLogin();
diff --git a/indra/newview/llweb.h b/indra/newview/llweb.h
index 0b95f664d6..0b95f664d6 100644..100755
--- a/indra/newview/llweb.h
+++ b/indra/newview/llweb.h
diff --git a/indra/newview/llwebprofile.cpp b/indra/newview/llwebprofile.cpp
index 641f338f2c..69255af179 100644..100755
--- a/indra/newview/llwebprofile.cpp
+++ b/indra/newview/llwebprofile.cpp
@@ -148,9 +148,6 @@ public:
LL_DEBUGS("Snapshots") << "Uploading image succeeded. Response: [" << body << "]" << llendl;
LLWebProfile::reportImageUploadStatus(true);
}
-
-private:
- LLPointer<LLImageFormatted> mImagep;
};
@@ -172,7 +169,7 @@ public:
headers["Cookie"] = LLWebProfile::getAuthCookie();
const std::string& redir_url = content["location"];
LL_DEBUGS("Snapshots") << "Got redirection URL: " << redir_url << llendl;
- LLHTTPClient::get(redir_url, new LLWebProfileResponders::PostImageRedirectResponder, headers);
+ LLHTTPClient::get(redir_url, new LLWebProfileResponders::PostImageRedirectResponder(), headers);
}
else
{
diff --git a/indra/newview/llwebprofile.h b/indra/newview/llwebprofile.h
index 10279bffac..10279bffac 100644..100755
--- a/indra/newview/llwebprofile.h
+++ b/indra/newview/llwebprofile.h
diff --git a/indra/newview/llwebsharing.cpp b/indra/newview/llwebsharing.cpp
index 43b1a320c3..3a80051b9b 100644..100755
--- a/indra/newview/llwebsharing.cpp
+++ b/indra/newview/llwebsharing.cpp
@@ -68,9 +68,9 @@ public:
}
}
- virtual void error(U32 status, const std::string& reason)
+ virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content)
{
- LL_WARNS("WebSharing") << "Error [" << status << "]: " << reason << LL_ENDL;
+ LL_WARNS("WebSharing") << "Error [status:" << status << "]: " << content << LL_ENDL;
}
virtual void result(const LLSD& content)
@@ -99,7 +99,7 @@ public:
/// Left empty to override the default LLSD parsing behaviour.
}
- virtual void error(U32 status, const std::string& reason)
+ virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content)
{
if (HTTP_UNAUTHORIZED == status)
{
@@ -108,7 +108,7 @@ public:
}
else
{
- LL_WARNS("WebSharing") << "Error [" << status << "]: " << reason << LL_ENDL;
+ LL_WARNS("WebSharing") << "Error [status:" << status << "]: " << content << LL_ENDL;
LLWebSharing::instance().retryOpenIDAuth();
}
@@ -152,9 +152,9 @@ public:
}
}
- virtual void error(U32 status, const std::string& reason)
+ virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content)
{
- LL_WARNS("WebSharing") << "Error [" << status << "]: " << reason << LL_ENDL;
+ LL_WARNS("WebSharing") << "Error [status:" << status << "]: " << content << LL_ENDL;
LLWebSharing::instance().retryOpenIDAuth();
}
@@ -221,9 +221,9 @@ public:
}
}
- virtual void error(U32 status, const std::string& reason)
+ virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content)
{
- LL_WARNS("WebSharing") << "Error [" << status << "]: " << reason << LL_ENDL;
+ LL_WARNS("WebSharing") << "Error [status:" << status << "]: " << content << LL_ENDL;
}
virtual void result(const LLSD& content)
diff --git a/indra/newview/llwebsharing.h b/indra/newview/llwebsharing.h
index ad9c99c224..ad9c99c224 100644..100755
--- a/indra/newview/llwebsharing.h
+++ b/indra/newview/llwebsharing.h
diff --git a/indra/newview/llwind.cpp b/indra/newview/llwind.cpp
index 4c39fb5b74..4c39fb5b74 100644..100755
--- a/indra/newview/llwind.cpp
+++ b/indra/newview/llwind.cpp
diff --git a/indra/newview/llwind.h b/indra/newview/llwind.h
index 3b57f07124..3b57f07124 100644..100755
--- a/indra/newview/llwind.h
+++ b/indra/newview/llwind.h
diff --git a/indra/newview/llwindebug.cpp b/indra/newview/llwindebug.cpp
index 551d0be8d7..551d0be8d7 100644..100755
--- a/indra/newview/llwindebug.cpp
+++ b/indra/newview/llwindebug.cpp
diff --git a/indra/newview/llwindebug.h b/indra/newview/llwindebug.h
index 3837825d31..3837825d31 100644..100755
--- a/indra/newview/llwindebug.h
+++ b/indra/newview/llwindebug.h
diff --git a/indra/newview/llwindowlistener.cpp b/indra/newview/llwindowlistener.cpp
index 28f959eb71..a8e06511d7 100644..100755
--- a/indra/newview/llwindowlistener.cpp
+++ b/indra/newview/llwindowlistener.cpp
@@ -265,7 +265,9 @@ void LLWindowListener::getPaths(LLSD const & request)
void LLWindowListener::keyDown(LLSD const & evt)
{
Response response(LLSD(), evt);
-
+ KEY key = getKEY(evt);
+ MASK mask = getMask(evt);
+
if (evt.has("path"))
{
std::string path(evt["path"]);
@@ -280,8 +282,6 @@ void LLWindowListener::keyDown(LLSD const & evt)
response.setResponse(target_view->getInfo());
gFocusMgr.setKeyboardFocus(target_view);
- KEY key = getKEY(evt);
- MASK mask = getMask(evt);
gViewerKeyboard.handleKey(key, mask, false);
if(key < 0x80) mWindow->handleUnicodeChar(key, mask);
}
@@ -294,7 +294,8 @@ void LLWindowListener::keyDown(LLSD const & evt)
}
else
{
- mKbGetter()->handleTranslatedKeyDown(getKEY(evt), getMask(evt));
+ gViewerKeyboard.handleKey(key, mask, false);
+ if(key < 0x80) mWindow->handleUnicodeChar(key, mask);
}
}
diff --git a/indra/newview/llwindowlistener.h b/indra/newview/llwindowlistener.h
index 7af5ab3b9f..7af5ab3b9f 100644..100755
--- a/indra/newview/llwindowlistener.h
+++ b/indra/newview/llwindowlistener.h
diff --git a/indra/newview/llwlanimator.cpp b/indra/newview/llwlanimator.cpp
index e568638cf6..e568638cf6 100644..100755
--- a/indra/newview/llwlanimator.cpp
+++ b/indra/newview/llwlanimator.cpp
diff --git a/indra/newview/llwlanimator.h b/indra/newview/llwlanimator.h
index 5223b45343..810f4cf7e5 100644..100755
--- a/indra/newview/llwlanimator.h
+++ b/indra/newview/llwlanimator.h
@@ -137,3 +137,4 @@ private:
};
#endif // LL_WL_ANIMATOR_H
+
diff --git a/indra/newview/llwldaycycle.cpp b/indra/newview/llwldaycycle.cpp
index 4c0cb7c0f4..4c0cb7c0f4 100644..100755
--- a/indra/newview/llwldaycycle.cpp
+++ b/indra/newview/llwldaycycle.cpp
diff --git a/indra/newview/llwldaycycle.h b/indra/newview/llwldaycycle.h
index c8585564ed..c8585564ed 100644..100755
--- a/indra/newview/llwldaycycle.h
+++ b/indra/newview/llwldaycycle.h
diff --git a/indra/newview/llwlhandlers.cpp b/indra/newview/llwlhandlers.cpp
index 2425b96678..93eba5b604 100644..100755
--- a/indra/newview/llwlhandlers.cpp
+++ b/indra/newview/llwlhandlers.cpp
@@ -105,19 +105,27 @@ LLEnvironmentRequestResponder::LLEnvironmentRequestResponder()
return;
}
- if (unvalidated_content[0]["regionID"].asUUID() != gAgent.getRegion()->getRegionID())
+ LLUUID regionId;
+ if( gAgent.getRegion() )
+ {
+ regionId = gAgent.getRegion()->getRegionID();
+ }
+
+ if (unvalidated_content[0]["regionID"].asUUID() != regionId )
{
LL_WARNS("WindlightCaps") << "Not in the region from where this data was received (wanting "
- << gAgent.getRegion()->getRegionID() << " but got " << unvalidated_content[0]["regionID"].asUUID()
+ << regionId << " but got " << unvalidated_content[0]["regionID"].asUUID()
<< ") - ignoring..." << LL_ENDL;
return;
}
LLEnvManagerNew::getInstance()->onRegionSettingsResponse(unvalidated_content);
}
-/*virtual*/ void LLEnvironmentRequestResponder::error(U32 status, const std::string& reason)
+/*virtual*/
+void LLEnvironmentRequestResponder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)
{
- LL_INFOS("WindlightCaps") << "Got an error, not using region windlight..." << LL_ENDL;
+ LL_INFOS("WindlightCaps") << "Got an error, not using region windlight... [status:"
+ << status << "]: " << content << LL_ENDL;
LLEnvManagerNew::getInstance()->onRegionSettingsResponse(LLSD());
}
@@ -184,14 +192,15 @@ bool LLEnvironmentApply::initiateRequest(const LLSD& content)
LLEnvManagerNew::instance().onRegionSettingsApplyResponse(false);
}
}
-/*virtual*/ void LLEnvironmentApplyResponder::error(U32 status, const std::string& reason)
+/*virtual*/
+void LLEnvironmentApplyResponder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)
{
- std::stringstream msg;
- msg << reason << " (Code " << status << ")";
-
- LL_WARNS("WindlightCaps") << "Couldn't apply windlight settings to region! Reason: " << msg << LL_ENDL;
+ LL_WARNS("WindlightCaps") << "Couldn't apply windlight settings to region! [status:"
+ << status << "]: " << content << LL_ENDL;
LLSD args(LLSD::emptyMap());
+ std::stringstream msg;
+ msg << reason << " (Code " << status << ")";
args["FAIL_REASON"] = msg.str();
LLNotificationsUtil::add("WLRegionApplyFail", args);
}
diff --git a/indra/newview/llwlhandlers.h b/indra/newview/llwlhandlers.h
index 23558876da..598ce6d52a 100644..100755
--- a/indra/newview/llwlhandlers.h
+++ b/indra/newview/llwlhandlers.h
@@ -47,7 +47,7 @@ class LLEnvironmentRequestResponder: public LLHTTPClient::Responder
LOG_CLASS(LLEnvironmentRequestResponder);
public:
virtual void result(const LLSD& content);
- virtual void error(U32 status, const std::string& reason);
+ virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content);
private:
friend class LLEnvironmentRequest;
@@ -89,7 +89,8 @@ public:
*/
virtual void result(const LLSD& content);
- virtual void error(U32 status, const std::string& reason); // non-200 errors only
+ // non-200 errors only
+ virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content);
private:
friend class LLEnvironmentApply;
diff --git a/indra/newview/llwlparammanager.cpp b/indra/newview/llwlparammanager.cpp
index 49d9d44d74..ce9f61c0af 100644..100755
--- a/indra/newview/llwlparammanager.cpp
+++ b/indra/newview/llwlparammanager.cpp
@@ -283,7 +283,7 @@ void LLWLParamManager::loadPresetsFromDir(const std::string& dir)
break; // no more files
}
- std::string path = dir + file;
+ std::string path = gDirUtilp->add(dir, file);
if (!loadPreset(path))
{
llwarns << "Error loading sky preset from " << path << llendl;
@@ -351,8 +351,8 @@ void LLWLParamManager::updateShaderUniforms(LLGLSLShader * shader)
if (shader->mShaderGroup == LLGLSLShader::SG_DEFAULT)
{
- shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, 1, mRotatedLightDir.mV);
- shader->uniform3fv("camPosLocal", 1, LLViewerCamera::getInstance()->getOrigin().mV);
+ shader->uniform4fv(LLShaderMgr::LIGHTNORM, 1, mRotatedLightDir.mV);
+ shader->uniform3fv(LLShaderMgr::WL_CAMPOSLOCAL, 1, LLViewerCamera::getInstance()->getOrigin().mV);
}
else if (shader->mShaderGroup == LLGLSLShader::SG_SKY)
@@ -360,7 +360,7 @@ void LLWLParamManager::updateShaderUniforms(LLGLSLShader * shader)
shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, 1, mClampedLightDir.mV);
}
- shader->uniform1f("scene_light_strength", mSceneLightStrength);
+ shader->uniform1f(LLShaderMgr::SCENE_LIGHT_STRENGTH, mSceneLightStrength);
}
diff --git a/indra/newview/llwlparammanager.h b/indra/newview/llwlparammanager.h
index 72422500fc..e13aed98ed 100644..100755
--- a/indra/newview/llwlparammanager.h
+++ b/indra/newview/llwlparammanager.h
@@ -412,3 +412,4 @@ inline LLVector4 LLWLParamManager::getRotatedLightDir(void) const
}
#endif
+
diff --git a/indra/newview/llwlparamset.cpp b/indra/newview/llwlparamset.cpp
index b04d30db55..8529a4614b 100644..100755
--- a/indra/newview/llwlparamset.cpp
+++ b/indra/newview/llwlparamset.cpp
@@ -33,11 +33,28 @@
#include "llglslshader.h"
#include "lluictrlfactory.h"
#include "llsliderctrl.h"
+#include "pipeline.h"
#include <llgl.h>
#include <sstream>
+static LLStaticHashedString sStarBrightness("star_brightness");
+static LLStaticHashedString sPresetNum("preset_num");
+static LLStaticHashedString sSunAngle("sun_angle");
+static LLStaticHashedString sEastAngle("east_angle");
+static LLStaticHashedString sEnableCloudScroll("enable_cloud_scroll");
+static LLStaticHashedString sCloudScrollRate("cloud_scroll_rate");
+static LLStaticHashedString sLightNorm("lightnorm");
+static LLStaticHashedString sCloudDensity("cloud_pos_density1");
+static LLStaticHashedString sCloudScale("cloud_scale");
+static LLStaticHashedString sCloudShadow("cloud_shadow");
+static LLStaticHashedString sDensityMultiplier("density_multiplier");
+static LLStaticHashedString sDistanceMultiplier("distance_multiplier");
+static LLStaticHashedString sHazeDensity("haze_density");
+static LLStaticHashedString sHazeHorizon("haze_horizon");
+static LLStaticHashedString sMaxY("max_y");
+
LLWLParamSet::LLWLParamSet(void) :
mName("Unnamed Preset"),
mCloudScrollXOffset(0.f), mCloudScrollYOffset(0.f)
@@ -48,21 +65,24 @@ static LLFastTimer::DeclareTimer FTM_WL_PARAM_UPDATE("WL Param Update");
void LLWLParamSet::update(LLGLSLShader * shader) const
{
LLFastTimer t(FTM_WL_PARAM_UPDATE);
-
- for(LLSD::map_const_iterator i = mParamValues.beginMap();
- i != mParamValues.endMap();
- ++i)
+ LLSD::map_const_iterator i = mParamValues.beginMap();
+ std::vector<LLStaticHashedString>::const_iterator n = mParamHashedNames.begin();
+ for(;(i != mParamValues.endMap()) && (n != mParamHashedNames.end());++i, n++)
{
- const std::string& param = i->first;
+ const LLStaticHashedString& param = *n;
- if (param == "star_brightness" || param == "preset_num" || param == "sun_angle" ||
- param == "east_angle" || param == "enable_cloud_scroll" ||
- param == "cloud_scroll_rate" || param == "lightnorm" )
+ // check that our pre-hashed names are still tracking the mParamValues map correctly
+ //
+ llassert(param.String() == i->first);
+
+ if (param == sStarBrightness || param == sPresetNum || param == sSunAngle ||
+ param == sEastAngle || param == sEnableCloudScroll ||
+ param == sCloudScrollRate || param == sLightNorm )
{
continue;
}
- if (param == "cloud_pos_density1")
+ if (param == sCloudDensity)
{
LLVector4 val;
val.mV[0] = F32(i->second[0].asReal()) + mCloudScrollXOffset;
@@ -74,10 +94,10 @@ void LLWLParamSet::update(LLGLSLShader * shader) const
shader->uniform4fv(param, 1, val.mV);
stop_glerror();
}
- else if (param == "cloud_scale" || param == "cloud_shadow" ||
- param == "density_multiplier" || param == "distance_multiplier" ||
- param == "haze_density" || param == "haze_horizon" ||
- param == "max_y" )
+ else if (param == sCloudScale || param == sCloudShadow ||
+ param == sDensityMultiplier || param == sDistanceMultiplier ||
+ param == sHazeDensity || param == sHazeHorizon ||
+ param == sMaxY )
{
F32 val = (F32) i->second[0].asReal();
@@ -127,6 +147,13 @@ void LLWLParamSet::update(LLGLSLShader * shader) const
}
}
}
+
+ if (LLPipeline::sRenderDeferred && !LLPipeline::sReflectionRender && !LLPipeline::sUnderWaterRender)
+ {
+ shader->uniform1f(LLShaderMgr::GLOBAL_GAMMA, 2.2);
+ } else {
+ shader->uniform1f(LLShaderMgr::GLOBAL_GAMMA, 1.0);
+ }
}
void LLWLParamSet::set(const std::string& paramName, float x)
@@ -378,3 +405,14 @@ void LLWLParamSet::updateCloudScrolling(void)
mCloudScrollYOffset += F32(delta_t * (getCloudScrollY() - 10.f) / 100.f);
}
}
+
+void LLWLParamSet::updateHashedNames()
+{
+ mParamHashedNames.clear();
+ // Iterate through values
+ for(LLSD::map_iterator iter = mParamValues.beginMap(); iter != mParamValues.endMap(); ++iter)
+ {
+ mParamHashedNames.push_back(LLStaticHashedString(iter->first));
+ }
+}
+
diff --git a/indra/newview/llwlparamset.h b/indra/newview/llwlparamset.h
index b087119dd5..6e5f1d3a4b 100644..100755
--- a/indra/newview/llwlparamset.h
+++ b/indra/newview/llwlparamset.h
@@ -29,9 +29,11 @@
#include <string>
#include <map>
+#include <vector>
#include "v4math.h"
#include "v4color.h"
+#include "llstaticstringtable.h"
class LLWLParamSet;
class LLGLSLShader;
@@ -47,9 +49,12 @@ public:
private:
LLSD mParamValues;
-
+ std::vector<LLStaticHashedString> mParamHashedNames;
+
float mCloudScrollXOffset, mCloudScrollYOffset;
+ void updateHashedNames();
+
public:
LLWLParamSet();
@@ -177,6 +182,8 @@ inline void LLWLParamSet::setAll(const LLSD& val)
if(val.isMap()) {
mParamValues = val;
}
+
+ updateHashedNames();
}
inline const LLSD& LLWLParamSet::getAll()
@@ -236,3 +243,4 @@ inline F32 LLWLParamSet::getCloudScrollY() {
#endif // LL_WLPARAM_SET_H
+
diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp
index 3d971e738e..103668d051 100644..100755
--- a/indra/newview/llworld.cpp
+++ b/indra/newview/llworld.cpp
@@ -138,9 +138,9 @@ void LLWorld::destroyClass()
LLViewerRegion* LLWorld::addRegion(const U64 &region_handle, const LLHost &host)
{
- LLMemType mt(LLMemType::MTYPE_REGIONS);
llinfos << "Add region with handle: " << region_handle << " on host " << host << llendl;
LLViewerRegion *regionp = getRegionFromHandle(region_handle);
+ std::string seedUrl;
if (regionp)
{
llinfos << "Region exists, removing it " << llendl;
@@ -162,6 +162,9 @@ LLViewerRegion* LLWorld::addRegion(const U64 &region_handle, const LLHost &host)
llwarns << "LLWorld::addRegion exists, but isn't alive" << llendl;
}
+ // Save capabilities seed URL
+ seedUrl = regionp->getCapability("Seed");
+
// Kill the old host, and then we can continue on and add the new host. We have to kill even if the host
// matches, because all the agent state for the new camera is completely different.
removeRegion(old_host);
@@ -189,6 +192,11 @@ LLViewerRegion* LLWorld::addRegion(const U64 &region_handle, const LLHost &host)
llerrs << "Unable to create new region!" << llendl;
}
+ if ( !seedUrl.empty() )
+ {
+ regionp->setCapability("Seed", seedUrl);
+ }
+
mRegionList.push_back(regionp);
mActiveRegionList.push_back(regionp);
mCulledRegionList.push_back(regionp);
@@ -275,7 +283,9 @@ void LLWorld::removeRegion(const LLHost &host)
mActiveRegionList.remove(regionp);
mCulledRegionList.remove(regionp);
mVisibleRegionList.remove(regionp);
-
+
+ mRegionRemovedSignal(regionp);
+
delete regionp;
updateWaterObjects();
@@ -403,6 +413,19 @@ LLViewerRegion* LLWorld::getRegionFromHandle(const U64 &handle)
return NULL;
}
+LLViewerRegion* LLWorld::getRegionFromID(const LLUUID& region_id)
+{
+ for (region_list_t::iterator iter = mRegionList.begin();
+ iter != mRegionList.end(); ++iter)
+ {
+ LLViewerRegion* regionp = *iter;
+ if (regionp->getRegionID() == region_id)
+ {
+ return regionp;
+ }
+ }
+ return NULL;
+}
void LLWorld::updateAgentOffset(const LLVector3d &offset_global)
{
@@ -644,7 +667,6 @@ void LLWorld::updateVisibilities()
void LLWorld::updateRegions(F32 max_update_time)
{
- LLMemType mt_ur(LLMemType::MTYPE_IDLE_UPDATE_REGIONS);
LLTimer update_timer;
BOOL did_one = FALSE;
@@ -657,7 +679,10 @@ void LLWorld::updateRegions(F32 max_update_time)
if (did_one && max_time <= 0.f)
break;
max_time = llmin(max_time, max_update_time*.1f);
- did_one |= regionp->idleUpdate(max_update_time);
+ if (regionp->idleUpdate(max_update_time))
+ {
+ did_one = TRUE;
+ }
}
}
@@ -837,21 +862,23 @@ void LLWorld::updateWaterObjects()
}
mHoleWaterObjects.clear();
+ // Use the water height of the region we're on for areas where there is no region
+ F32 water_height = gAgent.getRegion()->getWaterHeight();
+
// Now, get a list of the holes
S32 x, y;
- F32 water_height = gAgent.getRegion()->getWaterHeight() + 256.f;
for (x = min_x; x <= max_x; x += rwidth)
{
for (y = min_y; y <= max_y; y += rwidth)
{
U64 region_handle = to_region_handle(x, y);
if (!getRegionFromHandle(region_handle))
- {
+ { // No region at that area, so make water
LLVOWater* waterp = (LLVOWater *)gObjectList.createObjectViewer(LLViewerObject::LL_VO_WATER, gAgent.getRegion());
waterp->setUseTexture(FALSE);
waterp->setPositionGlobal(LLVector3d(x + rwidth/2,
y + rwidth/2,
- water_height));
+ 256.f + water_height));
waterp->setScale(LLVector3((F32)rwidth, (F32)rwidth, 512.f));
gPipeline.createObject(waterp);
mHoleWaterObjects.push_back(waterp);
@@ -908,7 +935,7 @@ void LLWorld::updateWaterObjects()
}
waterp->setRegion(gAgent.getRegion());
- LLVector3d water_pos(water_center_x, water_center_y, water_height) ;
+ LLVector3d water_pos(water_center_x, water_center_y, 256.f + water_height) ;
LLVector3 water_scale((F32) dim[0], (F32) dim[1], 512.f);
//stretch out to horizon
@@ -1189,7 +1216,7 @@ void LLWorld::getAvatars(uuid_vec_t* avatar_ids, std::vector<LLVector3d>* positi
{
LLVOAvatar* pVOAvatar = (LLVOAvatar*) *iter;
- if (!pVOAvatar->isDead() && !pVOAvatar->isSelf())
+ if (!pVOAvatar->isDead() && !pVOAvatar->mIsDummy)
{
LLVector3d pos_global = pVOAvatar->getPositionGlobal();
LLUUID uuid = pVOAvatar->getID();
@@ -1241,6 +1268,11 @@ bool LLWorld::isRegionListed(const LLViewerRegion* region) const
return it != mRegionList.end();
}
+boost::signals2::connection LLWorld::setRegionRemovedCallback(const region_remove_signal_t::slot_type& cb)
+{
+ return mRegionRemovedSignal.connect(cb);
+}
+
LLHTTPRegistration<LLEstablishAgentCommunication>
gHTTPRegistrationEstablishAgentCommunication(
"/message/EstablishAgentCommunication");
diff --git a/indra/newview/llworld.h b/indra/newview/llworld.h
index f350009d10..d0b001ba44 100644..100755
--- a/indra/newview/llworld.h
+++ b/indra/newview/llworld.h
@@ -76,6 +76,7 @@ public:
LLViewerRegion* getRegionFromPosGlobal(const LLVector3d &pos);
LLViewerRegion* getRegionFromPosAgent(const LLVector3 &pos);
LLViewerRegion* getRegionFromHandle(const U64 &handle);
+ LLViewerRegion* getRegionFromID(const LLUUID& region_id);
BOOL positionRegionValidGlobal(const LLVector3d& pos); // true if position is in valid region
LLVector3d clipToVisibleRegions(const LLVector3d &start_pos, const LLVector3d &end_pos);
@@ -149,6 +150,9 @@ public:
typedef std::list<LLViewerRegion*> region_list_t;
const region_list_t& getRegionList() const { return mActiveRegionList; }
+ typedef boost::signals2::signal<void(LLViewerRegion*)> region_remove_signal_t;
+ boost::signals2::connection setRegionRemovedCallback(const region_remove_signal_t::slot_type& cb);
+
// Returns lists of avatar IDs and their world-space positions within a given distance of a point.
// All arguments are optional. Given containers will be emptied and then filled.
// Not supplying origin or radius input returns data on all avatars in the known regions.
@@ -168,6 +172,8 @@ private:
region_list_t mVisibleRegionList;
region_list_t mCulledRegionList;
+ region_remove_signal_t mRegionRemovedSignal;
+
// Number of points on edge
static const U32 mWidth;
diff --git a/indra/newview/llworldmap.cpp b/indra/newview/llworldmap.cpp
index 350ba39b45..bfae142812 100644..100755
--- a/indra/newview/llworldmap.cpp
+++ b/indra/newview/llworldmap.cpp
@@ -34,6 +34,7 @@
#include "lluistring.h"
#include "llviewertexturelist.h"
#include "lltrans.h"
+#include "llgltexture.h"
// Timers to temporise database requests
const F32 AGENTS_UPDATE_TIMER = 60.0; // Seconds between 2 agent requests for a region
@@ -78,7 +79,7 @@ void LLSimInfo::setLandForSaleImage (LLUUID image_id)
// Fetch the image
if (mMapImageID.notNull())
{
- mOverlayImage = LLViewerTextureManager::getFetchedTexture(mMapImageID, MIPMAP_TRUE, LLViewerTexture::BOOST_MAP, LLViewerTexture::LOD_TEXTURE);
+ mOverlayImage = LLViewerTextureManager::getFetchedTexture(mMapImageID, FTT_DEFAULT, MIPMAP_TRUE, LLGLTexture::BOOST_MAP, LLViewerTexture::LOD_TEXTURE);
mOverlayImage->setAddressMode(LLTexUnit::TAM_CLAMP);
}
else
@@ -92,13 +93,13 @@ LLPointer<LLViewerFetchedTexture> LLSimInfo::getLandForSaleImage ()
if (mOverlayImage.isNull() && mMapImageID.notNull())
{
// Fetch the image if it hasn't been done yet (unlikely but...)
- mOverlayImage = LLViewerTextureManager::getFetchedTexture(mMapImageID, MIPMAP_TRUE, LLViewerTexture::BOOST_MAP, LLViewerTexture::LOD_TEXTURE);
+ mOverlayImage = LLViewerTextureManager::getFetchedTexture(mMapImageID, FTT_DEFAULT, MIPMAP_TRUE, LLGLTexture::BOOST_MAP, LLViewerTexture::LOD_TEXTURE);
mOverlayImage->setAddressMode(LLTexUnit::TAM_CLAMP);
}
if (!mOverlayImage.isNull())
{
// Boost the fetch level when we try to access that image
- mOverlayImage->setBoostLevel(LLViewerTexture::BOOST_MAP);
+ mOverlayImage->setBoostLevel(LLGLTexture::BOOST_MAP);
}
return mOverlayImage;
}
@@ -521,6 +522,17 @@ bool LLWorldMap::insertItem(U32 x_world, U32 y_world, std::string& name, LLUUID&
tooltip_fmt.setArg("[AREA]", llformat("%d", extra));
tooltip_fmt.setArg("[PRICE]", llformat("%d", extra2));
+
+ // Check for division by zero
+ if (extra != 0)
+ {
+ tooltip_fmt.setArg("[SQMPRICE]", llformat("%.1f", (F32)extra2 / (F32)extra));
+ }
+ else
+ {
+ tooltip_fmt.setArg("[SQMPRICE]", LLTrans::getString("Unknown"));
+ }
+
new_item.setTooltip(tooltip_fmt.getString());
if (type == MAP_ITEM_LAND_FOR_SALE)
diff --git a/indra/newview/llworldmap.h b/indra/newview/llworldmap.h
index 73530b9694..d514b2f14c 100644..100755
--- a/indra/newview/llworldmap.h
+++ b/indra/newview/llworldmap.h
@@ -36,6 +36,7 @@
#include "llsingleton.h"
#include "llviewerregion.h"
#include "llviewertexture.h"
+#include "llgltexture.h"
// Description of objects like hubs, events, land for sale, people and more (TBD).
// Note: we don't store a "type" in there so we need to store instances of this class in
diff --git a/indra/newview/llworldmapmessage.cpp b/indra/newview/llworldmapmessage.cpp
index 8307d32336..8307d32336 100644..100755
--- a/indra/newview/llworldmapmessage.cpp
+++ b/indra/newview/llworldmapmessage.cpp
diff --git a/indra/newview/llworldmapmessage.h b/indra/newview/llworldmapmessage.h
index 12b6ef4792..12b6ef4792 100644..100755
--- a/indra/newview/llworldmapmessage.h
+++ b/indra/newview/llworldmapmessage.h
diff --git a/indra/newview/llworldmapview.cpp b/indra/newview/llworldmapview.cpp
index a3ccf87cfc..ae334d4bd2 100644..100755
--- a/indra/newview/llworldmapview.cpp
+++ b/indra/newview/llworldmapview.cpp
@@ -421,7 +421,7 @@ void LLWorldMapView::draw()
{
// Inform the fetch mechanism of the size we need
S32 draw_size = llround(sMapScale);
- overlayimage->setKnownDrawSize(llround(draw_size * LLUI::sGLScaleFactor.mV[VX]), llround(draw_size * LLUI::sGLScaleFactor.mV[VY]));
+ overlayimage->setKnownDrawSize(llround(draw_size * LLUI::getScaleFactor().mV[VX]), llround(draw_size * LLUI::getScaleFactor().mV[VY]));
// Draw something whenever we have enough info
if (overlayimage->hasGLTexture())
{
@@ -965,8 +965,6 @@ void LLWorldMapView::drawTracking(const LLVector3d& pos_global, const LLColor4&
S32 text_x = x;
S32 text_y = (S32)(y - sTrackCircleImage->getHeight()/2 - font->getLineHeight());
- BOOL is_in_window = true;
-
if( x < 0
|| y < 0
|| x >= getRect().getWidth()
@@ -979,7 +977,6 @@ void LLWorldMapView::drawTracking(const LLVector3d& pos_global, const LLColor4&
text_x = sTrackingArrowX;
text_y = sTrackingArrowY;
}
- is_in_window = false;
}
else if (LLTracker::getTrackingStatus() == LLTracker::TRACKING_LOCATION &&
LLTracker::getTrackedLocationType() != LLTracker::LOCATION_NOTHING)
@@ -1320,7 +1317,7 @@ void LLWorldMapView::drawTrackingCircle( const LLRect& rect, S32 x, S32 y, const
gGL.matrixMode(LLRender::MM_MODELVIEW);
gGL.pushMatrix();
- gGL.translatef((F32)x, (F32)y, 0.f);
+ gGL.translatef((F32)x * LLUI::getScaleFactor().mV[VX], (F32)y * LLUI::getScaleFactor().mV[VY], 0.f);
gl_washer_segment_2d(inner_radius, outer_radius, start_theta, end_theta, 40, color, color);
gGL.popMatrix();
@@ -1795,3 +1792,5 @@ BOOL LLWorldMapView::handleDoubleClick( S32 x, S32 y, MASK mask )
}
return FALSE;
}
+
+
diff --git a/indra/newview/llworldmapview.h b/indra/newview/llworldmapview.h
index a2a6dc53fb..a2a6dc53fb 100644..100755
--- a/indra/newview/llworldmapview.h
+++ b/indra/newview/llworldmapview.h
diff --git a/indra/newview/llworldmipmap.cpp b/indra/newview/llworldmipmap.cpp
index 74ed844376..895ccaef5a 100644..100755
--- a/indra/newview/llworldmipmap.cpp
+++ b/indra/newview/llworldmipmap.cpp
@@ -74,21 +74,21 @@ void LLWorldMipmap::equalizeBoostLevels()
{
LLPointer<LLViewerFetchedTexture> img = iter->second;
S32 current_boost_level = img->getBoostLevel();
- if (current_boost_level == LLViewerTexture::BOOST_MAP_VISIBLE)
+ if (current_boost_level == LLGLTexture::BOOST_MAP_VISIBLE)
{
// If level was BOOST_MAP_VISIBLE, the tile has been used in the last draw so keep it high
- img->setBoostLevel(LLViewerTexture::BOOST_MAP);
+ img->setBoostLevel(LLGLTexture::BOOST_MAP);
}
else
{
// If level was BOOST_MAP only (or anything else...), the tile wasn't used in the last draw
// so we drop its boost level to BOOST_NONE.
- img->setBoostLevel(LLViewerTexture::BOOST_NONE);
+ img->setBoostLevel(LLGLTexture::BOOST_NONE);
}
#if DEBUG_TILES_STAT
// Increment some stats if compile option on
nb_tiles++;
- if (current_boost_level == LLViewerTexture::BOOST_MAP_VISIBLE)
+ if (current_boost_level == LLGLTexture::BOOST_MAP_VISIBLE)
{
nb_visible++;
}
@@ -115,7 +115,7 @@ void LLWorldMipmap::dropBoostLevels()
for (sublevel_tiles_t::iterator iter = level_mipmap.begin(); iter != level_mipmap.end(); iter++)
{
LLPointer<LLViewerFetchedTexture> img = iter->second;
- img->setBoostLevel(LLViewerTexture::BOOST_NONE);
+ img->setBoostLevel(LLGLTexture::BOOST_NONE);
}
}
}
@@ -172,7 +172,7 @@ LLPointer<LLViewerFetchedTexture> LLWorldMipmap::getObjectsTile(U32 grid_x, U32
// Boost the tile level so to mark it's in use *if* load on
if (load)
{
- img->setBoostLevel(LLViewerTexture::BOOST_MAP_VISIBLE);
+ img->setBoostLevel(LLGLTexture::BOOST_MAP_VISIBLE);
}
return img;
}
@@ -189,8 +189,8 @@ LLPointer<LLViewerFetchedTexture> LLWorldMipmap::loadObjectsTile(U32 grid_x, U32
// END DEBUG
//LL_INFOS("World Map") << "LLWorldMipmap::loadObjectsTile(), URL = " << imageurl << LL_ENDL;
- LLPointer<LLViewerFetchedTexture> img = LLViewerTextureManager::getFetchedTextureFromUrl(imageurl, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
- img->setBoostLevel(LLViewerTexture::BOOST_MAP);
+ LLPointer<LLViewerFetchedTexture> img = LLViewerTextureManager::getFetchedTextureFromUrl(imageurl, FTT_MAP_TILE, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
+ img->setBoostLevel(LLGLTexture::BOOST_MAP);
// Return the smart pointer
return img;
diff --git a/indra/newview/llworldmipmap.h b/indra/newview/llworldmipmap.h
index 963aac1403..963aac1403 100644..100755
--- a/indra/newview/llworldmipmap.h
+++ b/indra/newview/llworldmipmap.h
diff --git a/indra/newview/llxmlrpclistener.cpp b/indra/newview/llxmlrpclistener.cpp
index 97a9eb7f5f..97a9eb7f5f 100644..100755
--- a/indra/newview/llxmlrpclistener.cpp
+++ b/indra/newview/llxmlrpclistener.cpp
diff --git a/indra/newview/llxmlrpclistener.h b/indra/newview/llxmlrpclistener.h
index 58b38ce1cf..58b38ce1cf 100644..100755
--- a/indra/newview/llxmlrpclistener.h
+++ b/indra/newview/llxmlrpclistener.h
diff --git a/indra/newview/llxmlrpctransaction.cpp b/indra/newview/llxmlrpctransaction.cpp
index 0da70d398b..0da70d398b 100644..100755
--- a/indra/newview/llxmlrpctransaction.cpp
+++ b/indra/newview/llxmlrpctransaction.cpp
diff --git a/indra/newview/llxmlrpctransaction.h b/indra/newview/llxmlrpctransaction.h
index f2589c7f41..f2589c7f41 100644..100755
--- a/indra/newview/llxmlrpctransaction.h
+++ b/indra/newview/llxmlrpctransaction.h
diff --git a/indra/newview/macmain.h b/indra/newview/macmain.h
index 11c909a8c3..11c909a8c3 100644..100755
--- a/indra/newview/macmain.h
+++ b/indra/newview/macmain.h
diff --git a/indra/newview/macutil_Prefix.h b/indra/newview/macutil_Prefix.h
index fd8e927a08..b8df961cac 100644..100755
--- a/indra/newview/macutil_Prefix.h
+++ b/indra/newview/macutil_Prefix.h
@@ -32,8 +32,7 @@
*
*/
-#include <Carbon/Carbon.h>
+#include "fix_macros.h"
-#undef check
#undef verify
#undef require
diff --git a/indra/newview/macview.r b/indra/newview/macview.r
index 8124232cf1..8124232cf1 100644..100755
--- a/indra/newview/macview.r
+++ b/indra/newview/macview.r
diff --git a/indra/newview/macview_Prefix.h b/indra/newview/macview_Prefix.h
index 5936197a85..5936197a85 100644..100755
--- a/indra/newview/macview_Prefix.h
+++ b/indra/newview/macview_Prefix.h
diff --git a/indra/newview/nl.lproj/language.txt b/indra/newview/nl.lproj/language.txt
index d5f5c2a19c..d5f5c2a19c 100644..100755
--- a/indra/newview/nl.lproj/language.txt
+++ b/indra/newview/nl.lproj/language.txt
diff --git a/indra/newview/noise.cpp b/indra/newview/noise.cpp
index 5f2c718b49..5f2c718b49 100644..100755
--- a/indra/newview/noise.cpp
+++ b/indra/newview/noise.cpp
diff --git a/indra/newview/noise.h b/indra/newview/noise.h
index 0923bffcf2..b3efad73c5 100644..100755
--- a/indra/newview/noise.h
+++ b/indra/newview/noise.h
@@ -310,6 +310,8 @@ static void normalize3(F32 v[3])
static void init(void)
{
+ // we want repeatable noise (e.g. for stable terrain texturing), so seed with known value
+ srand(42);
int i, j, k;
for (i = 0 ; i < B ; i++) {
@@ -340,6 +342,9 @@ static void init(void)
for (j = 0 ; j < 3 ; j++)
g3[B + i][j] = g3[i][j];
}
+
+ // reintroduce entropy
+ srand(time(NULL)); // Flawfinder: ignore
}
#undef B
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index ab994c71cb..5da8a78b1b 100644..100755
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -35,7 +35,6 @@
#include "llviewercontrol.h"
#include "llfasttimer.h"
#include "llfontgl.h"
-#include "llmemtype.h"
#include "llnamevalue.h"
#include "llpointer.h"
#include "llprimitive.h"
@@ -51,6 +50,10 @@
// newview includes
#include "llagent.h"
#include "llagentcamera.h"
+#include "llappviewer.h"
+#include "lltexturecache.h"
+#include "lltexturefetch.h"
+#include "llimageworker.h"
#include "lldrawable.h"
#include "lldrawpoolalpha.h"
#include "lldrawpoolavatar.h"
@@ -68,6 +71,7 @@
#include "llhudtext.h"
#include "lllightconstants.h"
#include "llmeshrepository.h"
+#include "llpipelinelistener.h"
#include "llresmgr.h"
#include "llselectmgr.h"
#include "llsky.h"
@@ -104,7 +108,12 @@
#include "lltoolpie.h"
#include "llcurl.h"
#include "llnotifications.h"
-
+#include "llpathinglib.h"
+#include "llfloaterpathfindingconsole.h"
+#include "llfloaterpathfindingcharacters.h"
+#include "llfloatertools.h"
+#include "llpanelface.h"
+#include "llpathfindingpathtool.h"
#ifdef _DEBUG
// Debug indices is disabled for now for debug performance - djs 4/24/02
@@ -113,6 +122,12 @@
//#define DEBUG_INDICES
#endif
+// Expensive and currently broken
+//
+#define MATERIALS_IN_REFLECTIONS 0
+
+bool gShiftFrame = false;
+
//cached settings
BOOL LLPipeline::RenderAvatarVP;
BOOL LLPipeline::VertexShaderEnable;
@@ -154,6 +169,7 @@ S32 LLPipeline::RenderGlowIterations;
F32 LLPipeline::RenderGlowWidth;
F32 LLPipeline::RenderGlowStrength;
BOOL LLPipeline::RenderDepthOfField;
+BOOL LLPipeline::RenderDepthOfFieldInEditMode;
F32 LLPipeline::CameraFocusTransitionTime;
F32 LLPipeline::CameraFNumber;
F32 LLPipeline::CameraFocalLength;
@@ -187,6 +203,7 @@ F32 LLPipeline::RenderShadowFOVCutoff;
BOOL LLPipeline::CameraOffset;
F32 LLPipeline::CameraMaxCoF;
F32 LLPipeline::CameraDoFResScale;
+F32 LLPipeline::RenderAutoHideSurfaceAreaLimit;
const F32 BACKLIGHT_DAY_MAGNITUDE_AVATAR = 0.2f;
const F32 BACKLIGHT_NIGHT_MAGNITUDE_AVATAR = 0.1f;
@@ -209,7 +226,7 @@ BOOL gDebugPipeline = FALSE;
LLPipeline gPipeline;
const LLMatrix4* gGLLastMatrix = NULL;
-LLFastTimer::DeclareTimer FTM_RENDER_GEOMETRY("Geometry");
+LLFastTimer::DeclareTimer FTM_RENDER_GEOMETRY("Render Geometry");
LLFastTimer::DeclareTimer FTM_RENDER_GRASS("Grass");
LLFastTimer::DeclareTimer FTM_RENDER_INVISIBLE("Invisible");
LLFastTimer::DeclareTimer FTM_RENDER_OCCLUSION("Occlusion");
@@ -223,11 +240,17 @@ LLFastTimer::DeclareTimer FTM_RENDER_WL_SKY("Windlight Sky");
LLFastTimer::DeclareTimer FTM_RENDER_ALPHA("Alpha Objects");
LLFastTimer::DeclareTimer FTM_RENDER_CHARACTERS("Avatars");
LLFastTimer::DeclareTimer FTM_RENDER_BUMP("Bump");
+LLFastTimer::DeclareTimer FTM_RENDER_MATERIALS("Materials");
LLFastTimer::DeclareTimer FTM_RENDER_FULLBRIGHT("Fullbright");
LLFastTimer::DeclareTimer FTM_RENDER_GLOW("Glow");
LLFastTimer::DeclareTimer FTM_GEO_UPDATE("Geo Update");
+LLFastTimer::DeclareTimer FTM_PIPELINE_CREATE("Pipeline Create");
LLFastTimer::DeclareTimer FTM_POOLRENDER("RenderPool");
LLFastTimer::DeclareTimer FTM_POOLS("Pools");
+LLFastTimer::DeclareTimer FTM_DEFERRED_POOLRENDER("RenderPool (Deferred)");
+LLFastTimer::DeclareTimer FTM_DEFERRED_POOLS("Pools (Deferred)");
+LLFastTimer::DeclareTimer FTM_POST_DEFERRED_POOLRENDER("RenderPool (Post)");
+LLFastTimer::DeclareTimer FTM_POST_DEFERRED_POOLS("Pools (Post)");
LLFastTimer::DeclareTimer FTM_RENDER_BLOOM_FBO("First FBO");
LLFastTimer::DeclareTimer FTM_STATESORT("Sort Draw State");
LLFastTimer::DeclareTimer FTM_PIPELINE("Pipeline");
@@ -238,6 +261,17 @@ LLFastTimer::DeclareTimer FTM_RENDER_DEFERRED("Deferred Shading");
static LLFastTimer::DeclareTimer FTM_STATESORT_DRAWABLE("Sort Drawables");
static LLFastTimer::DeclareTimer FTM_STATESORT_POSTSORT("Post Sort");
+static LLStaticHashedString sTint("tint");
+static LLStaticHashedString sAmbiance("ambiance");
+static LLStaticHashedString sAlphaScale("alpha_scale");
+static LLStaticHashedString sNormMat("norm_mat");
+static LLStaticHashedString sOffset("offset");
+static LLStaticHashedString sScreenRes("screenRes");
+static LLStaticHashedString sDelta("delta");
+static LLStaticHashedString sDistFactor("dist_factor");
+static LLStaticHashedString sKern("kern");
+static LLStaticHashedString sKernScale("kern_scale");
+
//----------------------------------------
std::string gPoolNames[] =
{
@@ -247,10 +281,13 @@ std::string gPoolNames[] =
"POOL_GROUND",
"POOL_FULLBRIGHT",
"POOL_BUMP",
+ "POOL_MATERIALS",
"POOL_TERRAIN,"
"POOL_SKY",
"POOL_WL_SKY",
"POOL_TREE",
+ "POOL_ALPHA_MASK",
+ "POOL_FULLBRIGHT_ALPHA_MASK",
"POOL_GRASS",
"POOL_INVISIBLE",
"POOL_AVATAR",
@@ -260,9 +297,10 @@ std::string gPoolNames[] =
"POOL_ALPHA"
};
-void drawBox(const LLVector3& c, const LLVector3& r);
+void drawBox(const LLVector4a& c, const LLVector4a& r);
void drawBoxOutline(const LLVector3& pos, const LLVector3& size);
U32 nhpo2(U32 v);
+LLVertexBuffer* ll_create_cube_vb(U32 type_mask, U32 usage);
glh::matrix4f glh_copy_matrix(F32* src)
{
@@ -336,6 +374,7 @@ BOOL LLPipeline::sRenderParticleBeacons = FALSE;
BOOL LLPipeline::sRenderSoundBeacons = FALSE;
BOOL LLPipeline::sRenderBeacons = FALSE;
BOOL LLPipeline::sRenderHighlight = TRUE;
+LLRender::eTexIndex LLPipeline::sRenderHighlightTextureChannel = LLRender::DIFFUSE_MAP;
BOOL LLPipeline::sForceOldBakedUpload = FALSE;
S32 LLPipeline::sUseOcclusion = 0;
BOOL LLPipeline::sDelayVBUpdate = TRUE;
@@ -352,6 +391,7 @@ BOOL LLPipeline::sWaterReflections = FALSE;
BOOL LLPipeline::sRenderGlow = FALSE;
BOOL LLPipeline::sReflectionRender = FALSE;
BOOL LLPipeline::sImpostorRender = FALSE;
+BOOL LLPipeline::sImpostorRenderAlphaDepthPass = FALSE;
BOOL LLPipeline::sUnderWaterRender = FALSE;
BOOL LLPipeline::sTextureBindTest = FALSE;
BOOL LLPipeline::sRenderFrameTest = FALSE;
@@ -361,7 +401,10 @@ BOOL LLPipeline::sRenderDeferred = FALSE;
BOOL LLPipeline::sMemAllocationThrottled = FALSE;
S32 LLPipeline::sVisibleLightCount = 0;
F32 LLPipeline::sMinRenderSize = 0.f;
+BOOL LLPipeline::sRenderingHUDs;
+// EventHost API LLPipeline listener.
+static LLPipelineListener sPipelineListener;
static LLCullResult* sCull = NULL;
@@ -380,8 +423,8 @@ void validate_framebuffer_object();
bool addDeferredAttachments(LLRenderTarget& target)
{
- return target.addColorAttachment(GL_RGBA) && //specular
- target.addColorAttachment(GL_RGBA); //normal+z
+ return target.addColorAttachment(GL_SRGB8_ALPHA8) && //specular
+ target.addColorAttachment(GL_RGB10_A2); //normal+z
}
LLPipeline::LLPipeline() :
@@ -402,9 +445,11 @@ LLPipeline::LLPipeline() :
mInitialized(FALSE),
mVertexShadersEnabled(FALSE),
mVertexShadersLoaded(0),
+ mTransformFeedbackPrimitives(0),
mRenderDebugFeatureMask(0),
mRenderDebugMask(0),
mOldRenderDebugMask(0),
+ mMeshDirtyQueryObject(0),
mGroupQ1Locked(false),
mGroupQ2Locked(false),
mResetVertexBuffers(false),
@@ -415,10 +460,14 @@ LLPipeline::LLPipeline() :
mWaterPool(NULL),
mGroundPool(NULL),
mSimplePool(NULL),
+ mGrassPool(NULL),
+ mAlphaMaskPool(NULL),
+ mFullbrightAlphaMaskPool(NULL),
mFullbrightPool(NULL),
mInvisiblePool(NULL),
mGlowPool(NULL),
mBumpPool(NULL),
+ mMaterialsPool(NULL),
mWLSkyPool(NULL),
mLightMask(0),
mLightMovingMask(0),
@@ -431,10 +480,21 @@ LLPipeline::LLPipeline() :
mLightFunc = 0;
}
-void LLPipeline::init()
+void LLPipeline::connectRefreshCachedSettingsSafe(const std::string name)
{
- LLMemType mt(LLMemType::MTYPE_PIPELINE_INIT);
+ LLPointer<LLControlVariable> cntrl_ptr = gSavedSettings.getControl(name);
+ if ( cntrl_ptr.isNull() )
+ {
+ llwarns << "Global setting name not found:" << name << llendl;
+ }
+ else
+ {
+ cntrl_ptr->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
+ }
+}
+void LLPipeline::init()
+{
refreshCachedSettings();
gOctreeMaxCapacity = gSavedSettings.getU32("OctreeMaxNodeCapacity");
@@ -454,28 +514,41 @@ void LLPipeline::init()
//create render pass pools
getPool(LLDrawPool::POOL_ALPHA);
getPool(LLDrawPool::POOL_SIMPLE);
+ getPool(LLDrawPool::POOL_ALPHA_MASK);
+ getPool(LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK);
getPool(LLDrawPool::POOL_GRASS);
getPool(LLDrawPool::POOL_FULLBRIGHT);
getPool(LLDrawPool::POOL_INVISIBLE);
getPool(LLDrawPool::POOL_BUMP);
+ getPool(LLDrawPool::POOL_MATERIALS);
getPool(LLDrawPool::POOL_GLOW);
LLViewerStats::getInstance()->mTrianglesDrawnStat.reset();
resetFrameStats();
- for (U32 i = 0; i < NUM_RENDER_TYPES; ++i)
+ if (gSavedSettings.getBOOL("DisableAllRenderFeatures"))
{
- mRenderTypeEnabled[i] = TRUE; //all rendering types start enabled
+ clearAllRenderDebugFeatures();
}
+ else
+ {
+ setAllRenderDebugFeatures(); // By default, all debugging features on
+ }
+ clearAllRenderDebugDisplays(); // All debug displays off
- mRenderDebugFeatureMask = 0xffffffff; // All debugging features on
- mRenderDebugMask = 0; // All debug starts off
-
- // Don't turn on ground when this is set
- // Mac Books with intel 950s need this
- if(!gSavedSettings.getBOOL("RenderGround"))
+ if (gSavedSettings.getBOOL("DisableAllRenderTypes"))
{
- toggleRenderType(RENDER_TYPE_GROUND);
+ clearAllRenderTypes();
+ }
+ else
+ {
+ setAllRenderTypes(); // By default, all rendering types start enabled
+ // Don't turn on ground when this is set
+ // Mac Books with intel 950s need this
+ if(!gSavedSettings.getBOOL("RenderGround"))
+ {
+ toggleRenderType(RENDER_TYPE_GROUND);
+ }
}
// make sure RenderPerformanceTest persists (hackity hack hack)
@@ -503,6 +576,11 @@ void LLPipeline::init()
mSpotLightFade[i] = 1.f;
}
+ if (mCubeVB.isNull())
+ {
+ mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX, GL_STATIC_DRAW_ARB);
+ }
+
mDeferredVB = new LLVertexBuffer(DEFERRED_VB_MASK, 0);
mDeferredVB->allocateBuffer(8, 0, true);
setLightingDetail(-1);
@@ -510,88 +588,88 @@ void LLPipeline::init()
//
// Update all settings to trigger a cached settings refresh
//
-
- gSavedSettings.getControl("RenderAutoMaskAlphaDeferred")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
- gSavedSettings.getControl("RenderAutoMaskAlphaNonDeferred")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
- gSavedSettings.getControl("RenderUseFarClip")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
- gSavedSettings.getControl("RenderAvatarMaxVisible")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
- gSavedSettings.getControl("RenderDelayVBUpdate")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
-
- gSavedSettings.getControl("UseOcclusion")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
-
- gSavedSettings.getControl("VertexShaderEnable")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
- gSavedSettings.getControl("RenderAvatarVP")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
- gSavedSettings.getControl("WindLightUseAtmosShaders")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
- gSavedSettings.getControl("RenderDeferred")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
- gSavedSettings.getControl("RenderDeferredSunWash")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
- gSavedSettings.getControl("RenderFSAASamples")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
- gSavedSettings.getControl("RenderResolutionDivisor")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
- gSavedSettings.getControl("RenderUIBuffer")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
- gSavedSettings.getControl("RenderShadowDetail")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
- gSavedSettings.getControl("RenderDeferredSSAO")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
- gSavedSettings.getControl("RenderShadowResolutionScale")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
- gSavedSettings.getControl("RenderLocalLights")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
- gSavedSettings.getControl("RenderDelayCreation")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
- gSavedSettings.getControl("RenderAnimateRes")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
- gSavedSettings.getControl("FreezeTime")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
- gSavedSettings.getControl("DebugBeaconLineWidth")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
- gSavedSettings.getControl("RenderHighlightBrightness")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
- gSavedSettings.getControl("RenderHighlightColor")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
- gSavedSettings.getControl("RenderHighlightThickness")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
- gSavedSettings.getControl("RenderSpotLightsInNondeferred")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
- gSavedSettings.getControl("PreviewAmbientColor")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
- gSavedSettings.getControl("PreviewDiffuse0")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
- gSavedSettings.getControl("PreviewSpecular0")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
- gSavedSettings.getControl("PreviewDiffuse1")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
- gSavedSettings.getControl("PreviewSpecular1")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
- gSavedSettings.getControl("PreviewDiffuse2")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
- gSavedSettings.getControl("PreviewSpecular2")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
- gSavedSettings.getControl("PreviewDirection0")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
- gSavedSettings.getControl("PreviewDirection1")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
- gSavedSettings.getControl("PreviewDirection2")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
- gSavedSettings.getControl("RenderGlowMinLuminance")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
- gSavedSettings.getControl("RenderGlowMaxExtractAlpha")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
- gSavedSettings.getControl("RenderGlowWarmthAmount")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
- gSavedSettings.getControl("RenderGlowLumWeights")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
- gSavedSettings.getControl("RenderGlowWarmthWeights")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
- gSavedSettings.getControl("RenderGlowResolutionPow")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
- gSavedSettings.getControl("RenderGlowIterations")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
- gSavedSettings.getControl("RenderGlowWidth")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
- gSavedSettings.getControl("RenderGlowStrength")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
- gSavedSettings.getControl("RenderDepthOfField")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
- gSavedSettings.getControl("CameraFocusTransitionTime")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
- gSavedSettings.getControl("CameraFNumber")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
- gSavedSettings.getControl("CameraFocalLength")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
- gSavedSettings.getControl("CameraFieldOfView")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
- gSavedSettings.getControl("RenderShadowNoise")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
- gSavedSettings.getControl("RenderShadowBlurSize")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
- gSavedSettings.getControl("RenderSSAOScale")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
- gSavedSettings.getControl("RenderSSAOMaxScale")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
- gSavedSettings.getControl("RenderSSAOFactor")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
- gSavedSettings.getControl("RenderSSAOEffect")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
- gSavedSettings.getControl("RenderShadowOffsetError")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
- gSavedSettings.getControl("RenderShadowBiasError")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
- gSavedSettings.getControl("RenderShadowOffset")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
- gSavedSettings.getControl("RenderShadowBias")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
- gSavedSettings.getControl("RenderSpotShadowOffset")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
- gSavedSettings.getControl("RenderSpotShadowBias")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
- gSavedSettings.getControl("RenderEdgeDepthCutoff")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
- gSavedSettings.getControl("RenderEdgeNormCutoff")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
- gSavedSettings.getControl("RenderShadowGaussian")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
- gSavedSettings.getControl("RenderShadowBlurDistFactor")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
- gSavedSettings.getControl("RenderDeferredAtmospheric")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
- gSavedSettings.getControl("RenderReflectionDetail")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
- gSavedSettings.getControl("RenderHighlightFadeTime")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
- gSavedSettings.getControl("RenderShadowClipPlanes")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
- gSavedSettings.getControl("RenderShadowOrthoClipPlanes")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
- gSavedSettings.getControl("RenderShadowNearDist")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
- gSavedSettings.getControl("RenderFarClip")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
- gSavedSettings.getControl("RenderShadowSplitExponent")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
- gSavedSettings.getControl("RenderShadowErrorCutoff")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
- gSavedSettings.getControl("RenderShadowFOVCutoff")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
- gSavedSettings.getControl("CameraOffset")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
- gSavedSettings.getControl("CameraMaxCoF")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
- gSavedSettings.getControl("CameraDoFResScale")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
+ connectRefreshCachedSettingsSafe("RenderAutoMaskAlphaDeferred");
+ connectRefreshCachedSettingsSafe("RenderAutoMaskAlphaNonDeferred");
+ connectRefreshCachedSettingsSafe("RenderUseFarClip");
+ connectRefreshCachedSettingsSafe("RenderAvatarMaxVisible");
+ connectRefreshCachedSettingsSafe("RenderDelayVBUpdate");
+ connectRefreshCachedSettingsSafe("UseOcclusion");
+ connectRefreshCachedSettingsSafe("VertexShaderEnable");
+ connectRefreshCachedSettingsSafe("RenderAvatarVP");
+ connectRefreshCachedSettingsSafe("WindLightUseAtmosShaders");
+ connectRefreshCachedSettingsSafe("RenderDeferred");
+ connectRefreshCachedSettingsSafe("RenderDeferredSunWash");
+ connectRefreshCachedSettingsSafe("RenderFSAASamples");
+ connectRefreshCachedSettingsSafe("RenderResolutionDivisor");
+ connectRefreshCachedSettingsSafe("RenderUIBuffer");
+ connectRefreshCachedSettingsSafe("RenderShadowDetail");
+ connectRefreshCachedSettingsSafe("RenderDeferredSSAO");
+ connectRefreshCachedSettingsSafe("RenderShadowResolutionScale");
+ connectRefreshCachedSettingsSafe("RenderLocalLights");
+ connectRefreshCachedSettingsSafe("RenderDelayCreation");
+ connectRefreshCachedSettingsSafe("RenderAnimateRes");
+ connectRefreshCachedSettingsSafe("FreezeTime");
+ connectRefreshCachedSettingsSafe("DebugBeaconLineWidth");
+ connectRefreshCachedSettingsSafe("RenderHighlightBrightness");
+ connectRefreshCachedSettingsSafe("RenderHighlightColor");
+ connectRefreshCachedSettingsSafe("RenderHighlightThickness");
+ connectRefreshCachedSettingsSafe("RenderSpotLightsInNondeferred");
+ connectRefreshCachedSettingsSafe("PreviewAmbientColor");
+ connectRefreshCachedSettingsSafe("PreviewDiffuse0");
+ connectRefreshCachedSettingsSafe("PreviewSpecular0");
+ connectRefreshCachedSettingsSafe("PreviewDiffuse1");
+ connectRefreshCachedSettingsSafe("PreviewSpecular1");
+ connectRefreshCachedSettingsSafe("PreviewDiffuse2");
+ connectRefreshCachedSettingsSafe("PreviewSpecular2");
+ connectRefreshCachedSettingsSafe("PreviewDirection0");
+ connectRefreshCachedSettingsSafe("PreviewDirection1");
+ connectRefreshCachedSettingsSafe("PreviewDirection2");
+ connectRefreshCachedSettingsSafe("RenderGlowMinLuminance");
+ connectRefreshCachedSettingsSafe("RenderGlowMaxExtractAlpha");
+ connectRefreshCachedSettingsSafe("RenderGlowWarmthAmount");
+ connectRefreshCachedSettingsSafe("RenderGlowLumWeights");
+ connectRefreshCachedSettingsSafe("RenderGlowWarmthWeights");
+ connectRefreshCachedSettingsSafe("RenderGlowResolutionPow");
+ connectRefreshCachedSettingsSafe("RenderGlowIterations");
+ connectRefreshCachedSettingsSafe("RenderGlowWidth");
+ connectRefreshCachedSettingsSafe("RenderGlowStrength");
+ connectRefreshCachedSettingsSafe("RenderDepthOfField");
+ connectRefreshCachedSettingsSafe("RenderDepthOfFieldInEditMode");
+ connectRefreshCachedSettingsSafe("CameraFocusTransitionTime");
+ connectRefreshCachedSettingsSafe("CameraFNumber");
+ connectRefreshCachedSettingsSafe("CameraFocalLength");
+ connectRefreshCachedSettingsSafe("CameraFieldOfView");
+ connectRefreshCachedSettingsSafe("RenderShadowNoise");
+ connectRefreshCachedSettingsSafe("RenderShadowBlurSize");
+ connectRefreshCachedSettingsSafe("RenderSSAOScale");
+ connectRefreshCachedSettingsSafe("RenderSSAOMaxScale");
+ connectRefreshCachedSettingsSafe("RenderSSAOFactor");
+ connectRefreshCachedSettingsSafe("RenderSSAOEffect");
+ connectRefreshCachedSettingsSafe("RenderShadowOffsetError");
+ connectRefreshCachedSettingsSafe("RenderShadowBiasError");
+ connectRefreshCachedSettingsSafe("RenderShadowOffset");
+ connectRefreshCachedSettingsSafe("RenderShadowBias");
+ connectRefreshCachedSettingsSafe("RenderSpotShadowOffset");
+ connectRefreshCachedSettingsSafe("RenderSpotShadowBias");
+ connectRefreshCachedSettingsSafe("RenderEdgeDepthCutoff");
+ connectRefreshCachedSettingsSafe("RenderEdgeNormCutoff");
+ connectRefreshCachedSettingsSafe("RenderShadowGaussian");
+ connectRefreshCachedSettingsSafe("RenderShadowBlurDistFactor");
+ connectRefreshCachedSettingsSafe("RenderDeferredAtmospheric");
+ connectRefreshCachedSettingsSafe("RenderReflectionDetail");
+ connectRefreshCachedSettingsSafe("RenderHighlightFadeTime");
+ connectRefreshCachedSettingsSafe("RenderShadowClipPlanes");
+ connectRefreshCachedSettingsSafe("RenderShadowOrthoClipPlanes");
+ connectRefreshCachedSettingsSafe("RenderShadowNearDist");
+ connectRefreshCachedSettingsSafe("RenderFarClip");
+ connectRefreshCachedSettingsSafe("RenderShadowSplitExponent");
+ connectRefreshCachedSettingsSafe("RenderShadowErrorCutoff");
+ connectRefreshCachedSettingsSafe("RenderShadowFOVCutoff");
+ connectRefreshCachedSettingsSafe("CameraOffset");
+ connectRefreshCachedSettingsSafe("CameraMaxCoF");
+ connectRefreshCachedSettingsSafe("CameraDoFResScale");
+ connectRefreshCachedSettingsSafe("RenderAutoHideSurfaceAreaLimit");
+ gSavedSettings.getControl("RenderAutoHideSurfaceAreaLimit")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
}
LLPipeline::~LLPipeline()
@@ -671,6 +749,8 @@ void LLPipeline::cleanup()
mInitialized = FALSE;
mDeferredVB = NULL;
+
+ mCubeVB = NULL;
}
//============================================================================
@@ -691,6 +771,12 @@ void LLPipeline::destroyGL()
{
LLVertexBuffer::sEnableVBOs = FALSE;
}
+
+ if (mMeshDirtyQueryObject)
+ {
+ glDeleteQueriesARB(1, &mMeshDirtyQueryObject);
+ mMeshDirtyQueryObject = 0;
+ }
}
static LLFastTimer::DeclareTimer FTM_RESIZE_SCREEN_TEXTURE("Resize Screen Texture");
@@ -721,7 +807,24 @@ void LLPipeline::resizeScreenTexture()
GLuint resX = gViewerWindow->getWorldViewWidthRaw();
GLuint resY = gViewerWindow->getWorldViewHeightRaw();
- allocateScreenBuffer(resX,resY);
+ if ((resX != mScreen.getWidth()) || (resY != mScreen.getHeight()))
+ {
+ releaseScreenBuffers();
+ if (!allocateScreenBuffer(resX,resY))
+ {
+#if PROBABLE_FALSE_DISABLES_OF_ALM_HERE
+ //FAILSAFE: screen buffer allocation failed, disable deferred rendering if it's enabled
+ //NOTE: if the session closes successfully after this call, deferred rendering will be
+ // disabled on future sessions
+ if (LLPipeline::sRenderDeferred)
+ {
+ gSavedSettings.setBOOL("RenderDeferred", FALSE);
+ LLPipeline::refreshCachedSettings();
+
+ }
+#endif
+ }
+ }
}
}
@@ -736,18 +839,57 @@ void LLPipeline::allocatePhysicsBuffer()
}
}
-void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)
+bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)
{
refreshCachedSettings();
- U32 samples = RenderFSAASamples;
+
+ bool save_settings = sRenderDeferred;
+ if (save_settings)
+ {
+ // Set this flag in case we crash while resizing window or allocating space for deferred rendering targets
+ gSavedSettings.setBOOL("RenderInitError", TRUE);
+ gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile"), TRUE );
+ }
- //try to allocate screen buffers at requested resolution and samples
+ eFBOStatus ret = doAllocateScreenBuffer(resX, resY);
+
+ if (save_settings)
+ {
+ // don't disable shaders on next session
+ gSavedSettings.setBOOL("RenderInitError", FALSE);
+ gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile"), TRUE );
+ }
+
+ if (ret == FBO_FAILURE)
+ { //FAILSAFE: screen buffer allocation failed, disable deferred rendering if it's enabled
+ //NOTE: if the session closes successfully after this call, deferred rendering will be
+ // disabled on future sessions
+ if (LLPipeline::sRenderDeferred)
+ {
+ gSavedSettings.setBOOL("RenderDeferred", FALSE);
+ LLPipeline::refreshCachedSettings();
+ }
+ }
+
+ return ret == FBO_SUCCESS_FULLRES;
+}
+
+
+LLPipeline::eFBOStatus LLPipeline::doAllocateScreenBuffer(U32 resX, U32 resY)
+{
+ // try to allocate screen buffers at requested resolution and samples
// - on failure, shrink number of samples and try again
// - if not multisampled, shrink resolution and try again (favor X resolution over Y)
// Make sure to call "releaseScreenBuffers" after each failure to cleanup the partially loaded state
+ U32 samples = RenderFSAASamples;
+
+ eFBOStatus ret = FBO_SUCCESS_FULLRES;
if (!allocateScreenBuffer(resX, resY, samples))
{
+ //failed to allocate at requested specification, return false
+ ret = FBO_FAILURE;
+
releaseScreenBuffers();
//reduce number of samples
while (samples > 0)
@@ -755,7 +897,7 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)
samples /= 2;
if (allocateScreenBuffer(resX, resY, samples))
{ //success
- return;
+ return FBO_SUCCESS_LOWRES;
}
releaseScreenBuffers();
}
@@ -768,22 +910,23 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)
resY /= 2;
if (allocateScreenBuffer(resX, resY, samples))
{
- return;
+ return FBO_SUCCESS_LOWRES;
}
releaseScreenBuffers();
resX /= 2;
if (allocateScreenBuffer(resX, resY, samples))
{
- return;
+ return FBO_SUCCESS_LOWRES;
}
releaseScreenBuffers();
}
llwarns << "Unable to allocate screen buffer at any resolution!" << llendl;
}
-}
+ return ret;
+}
bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
{
@@ -811,22 +954,32 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
if (LLPipeline::sRenderDeferred)
{
- // Set this flag in case we crash while resizing window or allocating space for deferred rendering targets
- gSavedSettings.setBOOL("RenderInitError", TRUE);
- gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile"), TRUE );
-
S32 shadow_detail = RenderShadowDetail;
BOOL ssao = RenderDeferredSSAO;
+ const U32 occlusion_divisor = 3;
+
//allocate deferred rendering color buffers
- if (!mDeferredScreen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;
+ if (!mDeferredScreen.allocate(resX, resY, GL_SRGB8_ALPHA8, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;
if (!mDeferredDepth.allocate(resX, resY, 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;
+ if (!mOcclusionDepth.allocate(resX/occlusion_divisor, resY/occlusion_divisor, 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;
if (!addDeferredAttachments(mDeferredScreen)) return false;
-
- if (!mScreen.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;
+
+ GLuint screenFormat = GL_RGBA16;
+ if (gGLManager.mIsATI)
+ {
+ screenFormat = GL_RGBA12;
+ }
+
+ if (gGLManager.mGLVersion < 4.f && gGLManager.mIsNVIDIA)
+ {
+ screenFormat = GL_RGBA16F_ARB;
+ }
+
+ if (!mScreen.allocate(resX, resY, screenFormat, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;
if (samples > 0)
{
- if (!mFXAABuffer.allocate(nhpo2(resX), nhpo2(resY), GL_RGBA, FALSE, FALSE, LLTexUnit::TT_TEXTURE, FALSE, samples)) return false;
+ if (!mFXAABuffer.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_TEXTURE, FALSE, samples)) return false;
}
else
{
@@ -846,9 +999,11 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
if (shadow_detail > 0)
{ //allocate 4 sun shadow maps
+ U32 sun_shadow_map_width = ((U32(resX*scale)+1)&~1); // must be even to avoid a stripe in the horizontal shadow blur
for (U32 i = 0; i < 4; i++)
{
- if (!mShadow[i].allocate(U32(resX*scale),U32(resY*scale), 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE)) return false;
+ if (!mShadow[i].allocate(sun_shadow_map_width,U32(resY*scale), 0, TRUE, FALSE, LLTexUnit::TT_TEXTURE)) return false;
+ if (!mShadowOcclusion[i].allocate(mShadow[i].getWidth()/occlusion_divisor, mShadow[i].getHeight()/occlusion_divisor, 0, TRUE, FALSE, LLTexUnit::TT_TEXTURE)) return false;
}
}
else
@@ -856,17 +1011,20 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
for (U32 i = 0; i < 4; i++)
{
mShadow[i].release();
+ mShadowOcclusion[i].release();
}
}
- U32 width = nhpo2(U32(resX*scale))/2;
+ U32 width = (U32) (resX*scale);
U32 height = width;
if (shadow_detail > 1)
{ //allocate two spot shadow maps
+ U32 spot_shadow_map_width = width;
for (U32 i = 4; i < 6; i++)
{
- if (!mShadow[i].allocate(width, height, 0, TRUE, FALSE)) return false;
+ if (!mShadow[i].allocate(spot_shadow_map_width, height, 0, TRUE, FALSE)) return false;
+ if (!mShadowOcclusion[i].allocate(mShadow[i].getWidth()/occlusion_divisor, mShadow[i].getHeight()/occlusion_divisor, 0, TRUE, FALSE)) return false;
}
}
else
@@ -874,12 +1032,15 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
for (U32 i = 4; i < 6; i++)
{
mShadow[i].release();
+ mShadowOcclusion[i].release();
}
}
- // don't disable shaders on next session
- gSavedSettings.setBOOL("RenderInitError", FALSE);
- gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile"), TRUE );
+ //HACK make screenbuffer allocations start failing after 30 seconds
+ if (gSavedSettings.getBOOL("SimulateFBOFailure"))
+ {
+ return false;
+ }
}
else
{
@@ -888,11 +1049,13 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
for (U32 i = 0; i < 6; i++)
{
mShadow[i].release();
+ mShadowOcclusion[i].release();
}
mFXAABuffer.release();
mScreen.release();
mDeferredScreen.release(); //make sure to release any render targets that share a depth buffer with mDeferredScreen first
mDeferredDepth.release();
+ mOcclusionDepth.release();
if (!mScreen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE)) return false;
}
@@ -910,11 +1073,18 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
}
//static
+void LLPipeline::updateRenderBump()
+{
+ sRenderBump = gSavedSettings.getBOOL("RenderObjectBump");
+}
+
+//static
void LLPipeline::updateRenderDeferred()
{
BOOL deferred = ((RenderDeferred &&
LLRenderTarget::sUseFBO &&
- LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&
+ LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&
+ LLPipeline::sRenderBump &&
VertexShaderEnable &&
RenderAvatarVP &&
WindLightUseAtmosShaders) ? TRUE : FALSE) &&
@@ -938,6 +1108,7 @@ void LLPipeline::refreshCachedSettings()
LLPipeline::sUseOcclusion =
(!gUseWireframe
+ && LLGLSLShader::sNoFixedFunction
&& LLFeatureManager::getInstance()->isFeatureAvailable("UseOcclusion")
&& gSavedSettings.getBOOL("UseOcclusion")
&& gGLManager.mHasOcclusionQuery) ? 2 : 0;
@@ -982,6 +1153,7 @@ void LLPipeline::refreshCachedSettings()
RenderGlowWidth = gSavedSettings.getF32("RenderGlowWidth");
RenderGlowStrength = gSavedSettings.getF32("RenderGlowStrength");
RenderDepthOfField = gSavedSettings.getBOOL("RenderDepthOfField");
+ RenderDepthOfFieldInEditMode = gSavedSettings.getBOOL("RenderDepthOfFieldInEditMode");
CameraFocusTransitionTime = gSavedSettings.getF32("CameraFocusTransitionTime");
CameraFNumber = gSavedSettings.getF32("CameraFNumber");
CameraFocalLength = gSavedSettings.getF32("CameraFocalLength");
@@ -1015,6 +1187,7 @@ void LLPipeline::refreshCachedSettings()
CameraOffset = gSavedSettings.getBOOL("CameraOffset");
CameraMaxCoF = gSavedSettings.getF32("CameraMaxCoF");
CameraDoFResScale = gSavedSettings.getF32("CameraDoFResScale");
+ RenderAutoHideSurfaceAreaLimit = gSavedSettings.getF32("RenderAutoHideSurfaceAreaLimit");
updateRenderDeferred();
}
@@ -1039,6 +1212,7 @@ void LLPipeline::releaseGLBuffers()
mWaterRef.release();
mWaterDis.release();
+ mHighlight.release();
for (U32 i = 0; i < 3; i++)
{
@@ -1069,12 +1243,12 @@ void LLPipeline::releaseScreenBuffers()
mDeferredScreen.release();
mDeferredDepth.release();
mDeferredLight.release();
-
- mHighlight.release();
+ mOcclusionDepth.release();
for (U32 i = 0; i < 6; i++)
{
mShadow[i].release();
+ mShadowOcclusion[i].release();
}
}
@@ -1082,19 +1256,35 @@ void LLPipeline::releaseScreenBuffers()
void LLPipeline::createGLBuffers()
{
stop_glerror();
- LLMemType mt_cb(LLMemType::MTYPE_PIPELINE_CREATE_BUFFERS);
assertInitialized();
updateRenderDeferred();
+ bool materials_in_water = false;
+
+#if MATERIALS_IN_REFLECTIONS
+ materials_in_water = gSavedSettings.getS32("RenderWaterMaterials");
+#endif
+
if (LLPipeline::sWaterReflections)
{ //water reflection texture
U32 res = (U32) llmax(gSavedSettings.getS32("RenderWaterRefResolution"), 512);
+ // Set up SRGB targets if we're doing deferred-path reflection rendering
+ //
+ if (LLPipeline::sRenderDeferred && materials_in_water)
+ {
+ mWaterRef.allocate(res,res,GL_SRGB8_ALPHA8,TRUE,FALSE);
+ //always use FBO for mWaterDis so it can be used for avatar texture bakes
+ mWaterDis.allocate(res,res,GL_SRGB8_ALPHA8,TRUE,FALSE,LLTexUnit::TT_TEXTURE, true);
+ }
+ else
+ {
mWaterRef.allocate(res,res,GL_RGBA,TRUE,FALSE);
//always use FBO for mWaterDis so it can be used for avatar texture bakes
mWaterDis.allocate(res,res,GL_RGBA,TRUE,FALSE,LLTexUnit::TT_TEXTURE, true);
}
+ }
mHighlight.allocate(256,256,GL_RGBA, FALSE, FALSE);
@@ -1110,7 +1300,7 @@ void LLPipeline::createGLBuffers()
for (U32 i = 0; i < 3; i++)
{
- mGlow[i].allocate(512,glow_res,GL_RGBA,FALSE,FALSE);
+ mGlow[i].allocate(512,glow_res, GL_RGBA,FALSE,FALSE);
}
allocateScreenBuffer(resX,resY);
@@ -1136,7 +1326,7 @@ void LLPipeline::createGLBuffers()
LLImageGL::generateTextures(1, &mNoiseMap);
gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mNoiseMap);
- LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_RGB16F_ARB, noiseRes, noiseRes, GL_RGB, GL_FLOAT, noise);
+ LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_RGB16F_ARB, noiseRes, noiseRes, GL_RGB, GL_FLOAT, noise, false);
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
}
@@ -1151,7 +1341,7 @@ void LLPipeline::createGLBuffers()
LLImageGL::generateTextures(1, &mTrueNoiseMap);
gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mTrueNoiseMap);
- LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_RGB16F_ARB, noiseRes, noiseRes, GL_RGB,GL_FLOAT, noise);
+ LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_RGB16F_ARB, noiseRes, noiseRes, GL_RGB,GL_FLOAT, noise, false);
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
}
@@ -1161,13 +1351,18 @@ void LLPipeline::createGLBuffers()
gBumpImageList.restoreGL();
}
+F32 lerpf(F32 a, F32 b, F32 w)
+{
+ return a + w * (b - a);
+}
+
void LLPipeline::createLUTBuffers()
{
if (sRenderDeferred)
{
if (!mLightFunc)
{
- U32 lightResX = gSavedSettings.getU32("RenderSpecularResX");
+ /*U32 lightResX = gSavedSettings.getU32("RenderSpecularResX");
U32 lightResY = gSavedSettings.getU32("RenderSpecularResY");
U8* ls = new U8[lightResX*lightResY];
F32 specExp = gSavedSettings.getF32("RenderSpecularExponent");
@@ -1203,13 +1398,68 @@ void LLPipeline::createLUTBuffers()
// Combined with a bit of noise and trilinear filtering, the banding is hardly noticable.
ls[y*lightResX+x] = (U8)(llclamp(spec * (1.f / 6), 0.f, 1.f) * 255);
}
+ }*/
+
+
+ U32 lightResX = gSavedSettings.getU32("RenderSpecularResX");
+ U32 lightResY = gSavedSettings.getU32("RenderSpecularResY");
+ F32* ls = new F32[lightResX*lightResY];
+ //F32 specExp = gSavedSettings.getF32("RenderSpecularExponent"); // Note: only use this when creating new specular lighting functions.
+ // Calculate the (normalized) blinn-phong specular lookup texture. (with a few tweaks)
+ for (U32 y = 0; y < lightResY; ++y)
+ {
+ for (U32 x = 0; x < lightResX; ++x)
+ {
+ ls[y*lightResX+x] = 0;
+ F32 sa = (F32) x/(lightResX-1);
+ F32 spec = (F32) y/(lightResY-1);
+ F32 n = spec * spec * 368;
+
+ // Nothing special here. Just your typical blinn-phong term.
+ spec = powf(sa, n);
+
+ // Apply our normalization function.
+ // Note: This is the full equation that applies the full normalization curve, not an approximation.
+ // This is fine, given we only need to create our LUT once per buffer initialization.
+ spec *= (((n + 2) * (n + 4)) / (8 * F_PI * (powf(2, -n/2) + n)));
+
+ // Since we use R16F, we no longer have a dynamic range issue we need to work around here.
+ // Though some older drivers may not like this, newer drivers shouldn't have this problem.
+ ls[y*lightResX+x] = spec;
+
+
+ //beckmann distribution
+ /*F32 alpha = acosf((F32) x/(lightResX-1));
+ F32 m = 1.f - (F32) y/(lightResY-1);
+
+ F32 cos4_alpha = cosf(alpha);
+ cos4_alpha *= cos4_alpha;
+ cos4_alpha *= cos4_alpha;
+
+ F32 tan_alpha = tanf(alpha);
+ F32 tan2_alpha = tan_alpha*tan_alpha;
+
+ F32 k = expf(-(tan2_alpha)/(m*m)) /
+ (3.14159f*m*m*cos4_alpha);
+
+ ls[y*lightResX+x] = k;*/
+ }
}
+ U32 pix_format = GL_R16F;
+#if LL_DARWIN
+ // Need to work around limited precision with 10.6.8 and older drivers
+ //
+ pix_format = GL_R32F;
+#endif
LLImageGL::generateTextures(1, &mLightFunc);
gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mLightFunc);
- LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_R8, lightResX, lightResY, GL_RED, GL_UNSIGNED_BYTE, ls);
+ LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, pix_format, lightResX, lightResY, GL_RED, GL_FLOAT, ls, false);
+ //LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_UNSIGNED_BYTE, lightResX, lightResY, GL_RED, GL_UNSIGNED_BYTE, ls, false);
gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_TRILINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
delete [] ls;
}
@@ -1219,7 +1469,6 @@ void LLPipeline::createLUTBuffers()
void LLPipeline::restoreGL()
{
- LLMemType mt_cb(LLMemType::MTYPE_PIPELINE_RESTORE_GL);
assertInitialized();
if (mVertexShadersEnabled)
@@ -1281,7 +1530,6 @@ BOOL LLPipeline::canUseAntiAliasing() const
void LLPipeline::unloadShaders()
{
- LLMemType mt_us(LLMemType::MTYPE_PIPELINE_UNLOAD_SHADERS);
LLViewerShaderMgr::instance()->unloadShaders();
mVertexShadersLoaded = 0;
@@ -1313,7 +1561,6 @@ S32 LLPipeline::getMaxLightingDetail() const
S32 LLPipeline::setLightingDetail(S32 level)
{
- LLMemType mt_ld(LLMemType::MTYPE_PIPELINE_LIGHTING_DETAIL);
refreshCachedSettings();
if (level < 0)
@@ -1344,7 +1591,7 @@ public:
{
LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0);
- if (!group->isState(LLSpatialGroup::GEOM_DIRTY) && !group->getData().empty())
+ if (!group->isState(LLSpatialGroup::GEOM_DIRTY) && !group->isEmpty())
{
for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i)
{
@@ -1416,6 +1663,14 @@ LLDrawPool *LLPipeline::findPool(const U32 type, LLViewerTexture *tex0)
poolp = mGrassPool;
break;
+ case LLDrawPool::POOL_ALPHA_MASK:
+ poolp = mAlphaMaskPool;
+ break;
+
+ case LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK:
+ poolp = mFullbrightAlphaMaskPool;
+ break;
+
case LLDrawPool::POOL_FULLBRIGHT:
poolp = mFullbrightPool;
break;
@@ -1439,7 +1694,9 @@ LLDrawPool *LLPipeline::findPool(const U32 type, LLViewerTexture *tex0)
case LLDrawPool::POOL_BUMP:
poolp = mBumpPool;
break;
-
+ case LLDrawPool::POOL_MATERIALS:
+ poolp = mMaterialsPool;
+ break;
case LLDrawPool::POOL_ALPHA:
poolp = mAlphaPool;
break;
@@ -1475,7 +1732,6 @@ LLDrawPool *LLPipeline::findPool(const U32 type, LLViewerTexture *tex0)
LLDrawPool *LLPipeline::getPool(const U32 type, LLViewerTexture *tex0)
{
- LLMemType mt(LLMemType::MTYPE_PIPELINE);
LLDrawPool *poolp = findPool(type, tex0);
if (poolp)
{
@@ -1492,7 +1748,6 @@ LLDrawPool *LLPipeline::getPool(const U32 type, LLViewerTexture *tex0)
// static
LLDrawPool* LLPipeline::getPoolFromTE(const LLTextureEntry* te, LLViewerTexture* imagep)
{
- LLMemType mt(LLMemType::MTYPE_PIPELINE);
U32 type = getPoolTypeFromTE(te, imagep);
return gPipeline.getPool(type, imagep);
}
@@ -1500,27 +1755,49 @@ LLDrawPool* LLPipeline::getPoolFromTE(const LLTextureEntry* te, LLViewerTexture*
//static
U32 LLPipeline::getPoolTypeFromTE(const LLTextureEntry* te, LLViewerTexture* imagep)
{
- LLMemType mt_gpt(LLMemType::MTYPE_PIPELINE_GET_POOL_TYPE);
-
if (!te || !imagep)
{
return 0;
}
- bool alpha = te->getColor().mV[3] < 0.999f;
+ LLMaterial* mat = te->getMaterialParams().get();
+
+ bool color_alpha = te->getColor().mV[3] < 0.999f;
+ bool alpha = color_alpha;
if (imagep)
{
alpha = alpha || (imagep->getComponents() == 4 && imagep->getType() != LLViewerTexture::MEDIA_TEXTURE) || (imagep->getComponents() == 2);
}
-
+
+ if (alpha && mat)
+ {
+ switch (mat->getDiffuseAlphaMode())
+ {
+ case 1:
+ alpha = true; // Material's alpha mode is set to blend. Toss it into the alpha draw pool.
+ break;
+ case 0: //alpha mode set to none, never go to alpha pool
+ case 3: //alpha mode set to emissive, never go to alpha pool
+ alpha = color_alpha;
+ break;
+ default: //alpha mode set to "mask", go to alpha pool if fullbright
+ alpha = color_alpha; // Material's alpha mode is set to none, mask, or emissive. Toss it into the opaque material draw pool.
+ break;
+ }
+ }
+
if (alpha)
{
return LLDrawPool::POOL_ALPHA;
}
- else if ((te->getBumpmap() || te->getShiny()))
+ else if ((te->getBumpmap() || te->getShiny()) && (!mat || mat->getNormalID().isNull()))
{
return LLDrawPool::POOL_BUMP;
}
+ else if (mat && !alpha)
+ {
+ return LLDrawPool::POOL_MATERIALS;
+ }
else
{
return LLDrawPool::POOL_SIMPLE;
@@ -1530,7 +1807,6 @@ U32 LLPipeline::getPoolTypeFromTE(const LLTextureEntry* te, LLViewerTexture* ima
void LLPipeline::addPool(LLDrawPool *new_poolp)
{
- LLMemType mt_a(LLMemType::MTYPE_PIPELINE_ADD_POOL);
assertInitialized();
mPools.insert(new_poolp);
addToQuickLookup( new_poolp );
@@ -1538,7 +1814,6 @@ void LLPipeline::addPool(LLDrawPool *new_poolp)
void LLPipeline::allocDrawable(LLViewerObject *vobj)
{
- LLMemType mt_ad(LLMemType::MTYPE_PIPELINE_ALLOCATE_DRAWABLE);
LLDrawable *drawable = new LLDrawable();
vobj->mDrawable = drawable;
@@ -1635,10 +1910,23 @@ void LLPipeline::unlinkDrawable(LLDrawable *drawable)
}
-U32 LLPipeline::addObject(LLViewerObject *vobj)
+//static
+void LLPipeline::removeMutedAVsLights(LLVOAvatar* muted_avatar)
{
- LLMemType mt_ao(LLMemType::MTYPE_PIPELINE_ADD_OBJECT);
+ LLFastTimer t(FTM_REMOVE_FROM_LIGHT_SET);
+ for (light_set_t::iterator iter = gPipeline.mNearbyLights.begin();
+ iter != gPipeline.mNearbyLights.end(); iter++)
+ {
+ if (iter->drawable->getVObj()->isAttachment() && iter->drawable->getVObj()->getAvatar() == muted_avatar)
+ {
+ gPipeline.mLights.erase(iter->drawable);
+ gPipeline.mNearbyLights.erase(iter);
+ }
+ }
+}
+U32 LLPipeline::addObject(LLViewerObject *vobj)
+{
if (RenderDelayCreation)
{
mCreateQ.push_back(vobj);
@@ -1653,8 +1941,7 @@ U32 LLPipeline::addObject(LLViewerObject *vobj)
void LLPipeline::createObjects(F32 max_dtime)
{
- LLFastTimer ftm(FTM_GEO_UPDATE);
- LLMemType mt(LLMemType::MTYPE_PIPELINE_CREATE_OBJECTS);
+ LLFastTimer ftm(FTM_PIPELINE_CREATE);
LLTimer update_timer;
@@ -1814,7 +2101,21 @@ void LLPipeline::updateMovedList(LLDrawable::drawable_vector_t& moved_list)
drawablep->clearState(LLDrawable::EARLY_MOVE | LLDrawable::MOVE_UNDAMPED);
if (done)
{
+ if (drawablep->isRoot())
+ {
+ drawablep->makeStatic();
+ }
drawablep->clearState(LLDrawable::ON_MOVE_LIST);
+ if (drawablep->isState(LLDrawable::ANIMATED_CHILD))
+ { //will likely not receive any future world matrix updates
+ // -- this keeps attachments from getting stuck in space and falling off your avatar
+ drawablep->clearState(LLDrawable::ANIMATED_CHILD);
+ markRebuild(drawablep, LLDrawable::REBUILD_VOLUME, TRUE);
+ if (drawablep->getVObj())
+ {
+ drawablep->getVObj()->dirtySpatialGroup(TRUE);
+ }
+ }
iter = moved_list.erase(curiter);
}
}
@@ -1826,7 +2127,6 @@ static LLFastTimer::DeclareTimer FTM_UPDATE_MOVE("Update Move");
void LLPipeline::updateMove()
{
LLFastTimer t(FTM_UPDATE_MOVE);
- LLMemType mt_um(LLMemType::MTYPE_PIPELINE_UPDATE_MOVE);
if (FreezeTime)
{
@@ -1935,11 +2235,12 @@ void LLPipeline::grabReferences(LLCullResult& result)
void LLPipeline::clearReferences()
{
sCull = NULL;
+ mGroupSaveQ1.clear();
}
void check_references(LLSpatialGroup* group, LLDrawable* drawable)
{
- for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i)
+ for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)
{
if (drawable == *i)
{
@@ -1961,7 +2262,7 @@ void check_references(LLDrawable* drawable, LLFace* face)
void check_references(LLSpatialGroup* group, LLFace* face)
{
- for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i)
+ for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)
{
LLDrawable* drawable = *i;
check_references(drawable, face);
@@ -1973,25 +2274,25 @@ void LLPipeline::checkReferences(LLFace* face)
#if 0
if (sCull)
{
- for (LLCullResult::sg_list_t::iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter)
+ for (LLCullResult::sg_iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter)
{
LLSpatialGroup* group = *iter;
check_references(group, face);
}
- for (LLCullResult::sg_list_t::iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter)
+ for (LLCullResult::sg_iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter)
{
LLSpatialGroup* group = *iter;
check_references(group, face);
}
- for (LLCullResult::sg_list_t::iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter)
+ for (LLCullResult::sg_iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter)
{
LLSpatialGroup* group = *iter;
check_references(group, face);
}
- for (LLCullResult::drawable_list_t::iterator iter = sCull->beginVisibleList(); iter != sCull->endVisibleList(); ++iter)
+ for (LLCullResult::drawable_iterator iter = sCull->beginVisibleList(); iter != sCull->endVisibleList(); ++iter)
{
LLDrawable* drawable = *iter;
check_references(drawable, face);
@@ -2005,25 +2306,25 @@ void LLPipeline::checkReferences(LLDrawable* drawable)
#if 0
if (sCull)
{
- for (LLCullResult::sg_list_t::iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter)
+ for (LLCullResult::sg_iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter)
{
LLSpatialGroup* group = *iter;
check_references(group, drawable);
}
- for (LLCullResult::sg_list_t::iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter)
+ for (LLCullResult::sg_iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter)
{
LLSpatialGroup* group = *iter;
check_references(group, drawable);
}
- for (LLCullResult::sg_list_t::iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter)
+ for (LLCullResult::sg_iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter)
{
LLSpatialGroup* group = *iter;
check_references(group, drawable);
}
- for (LLCullResult::drawable_list_t::iterator iter = sCull->beginVisibleList(); iter != sCull->endVisibleList(); ++iter)
+ for (LLCullResult::drawable_iterator iter = sCull->beginVisibleList(); iter != sCull->endVisibleList(); ++iter)
{
if (drawable == *iter)
{
@@ -2056,19 +2357,19 @@ void LLPipeline::checkReferences(LLDrawInfo* draw_info)
#if 0
if (sCull)
{
- for (LLCullResult::sg_list_t::iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter)
+ for (LLCullResult::sg_iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter)
{
LLSpatialGroup* group = *iter;
check_references(group, draw_info);
}
- for (LLCullResult::sg_list_t::iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter)
+ for (LLCullResult::sg_iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter)
{
LLSpatialGroup* group = *iter;
check_references(group, draw_info);
}
- for (LLCullResult::sg_list_t::iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter)
+ for (LLCullResult::sg_iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter)
{
LLSpatialGroup* group = *iter;
check_references(group, draw_info);
@@ -2082,7 +2383,7 @@ void LLPipeline::checkReferences(LLSpatialGroup* group)
#if 0
if (sCull)
{
- for (LLCullResult::sg_list_t::iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter)
+ for (LLCullResult::sg_iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter)
{
if (group == *iter)
{
@@ -2090,7 +2391,7 @@ void LLPipeline::checkReferences(LLSpatialGroup* group)
}
}
- for (LLCullResult::sg_list_t::iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter)
+ for (LLCullResult::sg_iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter)
{
if (group == *iter)
{
@@ -2098,7 +2399,7 @@ void LLPipeline::checkReferences(LLSpatialGroup* group)
}
}
- for (LLCullResult::sg_list_t::iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter)
+ for (LLCullResult::sg_iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter)
{
if (group == *iter)
{
@@ -2179,7 +2480,6 @@ static LLFastTimer::DeclareTimer FTM_CULL("Object Culling");
void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_clip, LLPlane* planep)
{
LLFastTimer t(FTM_CULL);
- LLMemType mt_uc(LLMemType::MTYPE_PIPELINE_UPDATE_CULL);
grabReferences(result);
@@ -2193,7 +2493,14 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl
if (to_texture)
{
- mScreen.bindTarget();
+ if (LLPipeline::sRenderDeferred)
+ {
+ mOcclusionDepth.bindTarget();
+ }
+ else
+ {
+ mScreen.bindTarget();
+ }
}
if (sUseOcclusion > 1)
@@ -2209,8 +2516,6 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl
gGLLastMatrix = NULL;
gGL.loadMatrix(gGLLastModelView);
-
- LLVertexBuffer::unbind();
LLGLDisable blend(GL_BLEND);
LLGLDisable test(GL_ALPHA_TEST);
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
@@ -2254,7 +2559,16 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl
{ //if no shader is currently bound, use the occlusion shader instead of fixed function if we can
// (shadow render uses a special shader that clamps to clip planes)
bound_shader = true;
- gOcclusionProgram.bind();
+ gOcclusionCubeProgram.bind();
+ }
+
+ if (sUseOcclusion > 1)
+ {
+ if (mCubeVB.isNull())
+ { //cube VB will be used for issuing occlusion queries
+ mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX, GL_STATIC_DRAW_ARB);
+ }
+ mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
}
for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
@@ -2286,7 +2600,7 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl
if (bound_shader)
{
- gOcclusionProgram.unbind();
+ gOcclusionCubeProgram.unbind();
}
camera.disableUserClipPlane();
@@ -2324,13 +2638,20 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl
if (to_texture)
{
- mScreen.flush();
+ if (LLPipeline::sRenderDeferred)
+ {
+ mOcclusionDepth.flush();
+ }
+ else
+ {
+ mScreen.flush();
+ }
}
}
void LLPipeline::markNotCulled(LLSpatialGroup* group, LLCamera& camera)
{
- if (group->getData().empty())
+ if (group->isEmpty())
{
return;
}
@@ -2392,6 +2713,73 @@ void LLPipeline::markOccluder(LLSpatialGroup* group)
}
}
+void LLPipeline::downsampleDepthBuffer(LLRenderTarget& source, LLRenderTarget& dest, LLRenderTarget* scratch_space)
+{
+ LLGLSLShader* last_shader = LLGLSLShader::sCurBoundShaderPtr;
+
+ LLGLSLShader* shader = NULL;
+
+ if (scratch_space)
+ {
+ scratch_space->copyContents(source,
+ 0, 0, source.getWidth(), source.getHeight(),
+ 0, 0, scratch_space->getWidth(), scratch_space->getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST);
+ }
+
+ dest.bindTarget();
+ dest.clear(GL_DEPTH_BUFFER_BIT);
+
+ LLStrider<LLVector3> vert;
+ mDeferredVB->getVertexStrider(vert);
+ LLStrider<LLVector2> tc0;
+
+ vert[0].set(-1,1,0);
+ vert[1].set(-1,-3,0);
+ vert[2].set(3,1,0);
+
+ if (source.getUsage() == LLTexUnit::TT_RECT_TEXTURE)
+ {
+ shader = &gDownsampleDepthRectProgram;
+ shader->bind();
+ shader->uniform2f(sDelta, 1.f, 1.f);
+ shader->uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, source.getWidth(), source.getHeight());
+ }
+ else
+ {
+ shader = &gDownsampleDepthProgram;
+ shader->bind();
+ shader->uniform2f(sDelta, 1.f/source.getWidth(), 1.f/source.getHeight());
+ shader->uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, 1.f, 1.f);
+ }
+
+ gGL.getTexUnit(0)->bind(scratch_space ? scratch_space : &source, TRUE);
+
+ {
+ LLGLDepthTest depth(GL_TRUE, GL_TRUE, GL_ALWAYS);
+ mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+ mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+ }
+
+ dest.flush();
+
+ if (last_shader)
+ {
+ last_shader->bind();
+ }
+ else
+ {
+ shader->unbind();
+ }
+}
+
+void LLPipeline::doOcclusion(LLCamera& camera, LLRenderTarget& source, LLRenderTarget& dest, LLRenderTarget* scratch_space)
+{
+ downsampleDepthBuffer(source, dest, scratch_space);
+ dest.bindTarget();
+ doOcclusion(camera);
+ dest.flush();
+}
+
void LLPipeline::doOcclusion(LLCamera& camera)
{
if (LLPipeline::sUseOcclusion > 1 && sCull->hasOcclusionGroups())
@@ -2419,15 +2807,21 @@ void LLPipeline::doOcclusion(LLCamera& camera)
{
if (LLPipeline::sShadowRender)
{
- gDeferredShadowProgram.bind();
+ gDeferredShadowCubeProgram.bind();
}
else
{
- gOcclusionProgram.bind();
+ gOcclusionCubeProgram.bind();
}
}
- for (LLCullResult::sg_list_t::iterator iter = sCull->beginOcclusionGroups(); iter != sCull->endOcclusionGroups(); ++iter)
+ if (mCubeVB.isNull())
+ { //cube VB will be used for issuing occlusion queries
+ mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX, GL_STATIC_DRAW_ARB);
+ }
+ mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+
+ for (LLCullResult::sg_iterator iter = sCull->beginOcclusionGroups(); iter != sCull->endOcclusionGroups(); ++iter)
{
LLSpatialGroup* group = *iter;
group->doOcclusion(&camera);
@@ -2438,11 +2832,11 @@ void LLPipeline::doOcclusion(LLCamera& camera)
{
if (LLPipeline::sShadowRender)
{
- gDeferredShadowProgram.unbind();
+ gDeferredShadowCubeProgram.unbind();
}
else
{
- gOcclusionProgram.unbind();
+ gOcclusionCubeProgram.unbind();
}
}
@@ -2461,22 +2855,93 @@ BOOL LLPipeline::updateDrawableGeom(LLDrawable* drawablep, BOOL priority)
return update_complete;
}
+static LLFastTimer::DeclareTimer FTM_SEED_VBO_POOLS("Seed VBO Pool");
+
+static LLFastTimer::DeclareTimer FTM_UPDATE_GL("Update GL");
+
void LLPipeline::updateGL()
{
- while (!LLGLUpdate::sGLQ.empty())
{
- LLGLUpdate* glu = LLGLUpdate::sGLQ.front();
- glu->updateGL();
- glu->mInQ = FALSE;
- LLGLUpdate::sGLQ.pop_front();
+ LLFastTimer t(FTM_UPDATE_GL);
+ while (!LLGLUpdate::sGLQ.empty())
+ {
+ LLGLUpdate* glu = LLGLUpdate::sGLQ.front();
+ glu->updateGL();
+ glu->mInQ = FALSE;
+ LLGLUpdate::sGLQ.pop_front();
+ }
+ }
+
+ { //seed VBO Pools
+ LLFastTimer t(FTM_SEED_VBO_POOLS);
+ LLVertexBuffer::seedPools();
+ }
+}
+
+static LLFastTimer::DeclareTimer FTM_REBUILD_PRIORITY_GROUPS("Rebuild Priority Groups");
+
+void LLPipeline::clearRebuildGroups()
+{
+ LLSpatialGroup::sg_vector_t hudGroups;
+
+ mGroupQ1Locked = true;
+ // Iterate through all drawables on the priority build queue,
+ for (LLSpatialGroup::sg_vector_t::iterator iter = mGroupQ1.begin();
+ iter != mGroupQ1.end(); ++iter)
+ {
+ LLSpatialGroup* group = *iter;
+
+ // If the group contains HUD objects, save the group
+ if (group->isHUDGroup())
+ {
+ hudGroups.push_back(group);
+ }
+ // Else, no HUD objects so clear the build state
+ else
+ {
+ group->clearState(LLSpatialGroup::IN_BUILD_Q1);
+ }
}
+
+ // Clear the group
+ mGroupQ1.clear();
+
+ // Copy the saved HUD groups back in
+ mGroupQ1.assign(hudGroups.begin(), hudGroups.end());
+ mGroupQ1Locked = false;
+
+ // Clear the HUD groups
+ hudGroups.clear();
+
+ mGroupQ2Locked = true;
+ for (LLSpatialGroup::sg_vector_t::iterator iter = mGroupQ2.begin();
+ iter != mGroupQ2.end(); ++iter)
+ {
+ LLSpatialGroup* group = *iter;
+
+ // If the group contains HUD objects, save the group
+ if (group->isHUDGroup())
+ {
+ hudGroups.push_back(group);
+ }
+ // Else, no HUD objects so clear the build state
+ else
+ {
+ group->clearState(LLSpatialGroup::IN_BUILD_Q2);
+ }
+ }
+ // Clear the group
+ mGroupQ2.clear();
+
+ // Copy the saved HUD groups back in
+ mGroupQ2.assign(hudGroups.begin(), hudGroups.end());
+ mGroupQ2Locked = false;
}
void LLPipeline::rebuildPriorityGroups()
{
+ LLFastTimer t(FTM_REBUILD_PRIORITY_GROUPS);
LLTimer update_timer;
- LLMemType mt(LLMemType::MTYPE_PIPELINE);
-
assertInitialized();
gMeshRepo.notifyLoadedMeshes();
@@ -2491,11 +2956,14 @@ void LLPipeline::rebuildPriorityGroups()
group->clearState(LLSpatialGroup::IN_BUILD_Q1);
}
+ mGroupSaveQ1 = mGroupQ1;
mGroupQ1.clear();
mGroupQ1Locked = false;
}
-
+
+static LLFastTimer::DeclareTimer FTM_REBUILD_GROUPS("Rebuild Groups");
+
void LLPipeline::rebuildGroups()
{
if (mGroupQ2.empty())
@@ -2503,6 +2971,7 @@ void LLPipeline::rebuildGroups()
return;
}
+ LLFastTimer t(FTM_REBUILD_GROUPS);
mGroupQ2Locked = true;
// Iterate through some drawables on the non-priority build queue
S32 size = (S32) mGroupQ2.size();
@@ -2544,7 +3013,6 @@ void LLPipeline::rebuildGroups()
void LLPipeline::updateGeom(F32 max_dtime)
{
LLTimer update_timer;
- LLMemType mt(LLMemType::MTYPE_PIPELINE_UPDATE_GEOM);
LLPointer<LLDrawable> drawablep;
LLFastTimer t(FTM_GEO_UPDATE);
@@ -2638,14 +3106,13 @@ void LLPipeline::updateGeom(F32 max_dtime)
void LLPipeline::markVisible(LLDrawable *drawablep, LLCamera& camera)
{
- LLMemType mt(LLMemType::MTYPE_PIPELINE_MARK_VISIBLE);
-
if(drawablep && !drawablep->isDead())
{
if (drawablep->isSpatialBridge())
{
const LLDrawable* root = ((LLSpatialBridge*) drawablep)->mDrawable;
llassert(root); // trying to catch a bad assumption
+
if (root && // // this test may not be needed, see above
root->getVObj()->isAttachment())
{
@@ -2656,7 +3123,7 @@ void LLPipeline::markVisible(LLDrawable *drawablep, LLCamera& camera)
llassert(vobj); // trying to catch a bad assumption
if (vobj) // this test may not be needed, see above
{
- const LLVOAvatar* av = vobj->asAvatar();
+ LLVOAvatar* av = vobj->asAvatar();
if (av && av->isImpostor())
{
return;
@@ -2668,6 +3135,7 @@ void LLPipeline::markVisible(LLDrawable *drawablep, LLCamera& camera)
}
else
{
+
sCull->pushDrawable(drawablep);
}
@@ -2677,8 +3145,6 @@ void LLPipeline::markVisible(LLDrawable *drawablep, LLCamera& camera)
void LLPipeline::markMoved(LLDrawable *drawablep, BOOL damped_motion)
{
- LLMemType mt_mm(LLMemType::MTYPE_PIPELINE_MARK_MOVED);
-
if (!drawablep)
{
//llerrs << "Sending null drawable to moved list!" << llendl;
@@ -2723,8 +3189,6 @@ void LLPipeline::markMoved(LLDrawable *drawablep, BOOL damped_motion)
void LLPipeline::markShift(LLDrawable *drawablep)
{
- LLMemType mt(LLMemType::MTYPE_PIPELINE_MARK_SHIFT);
-
if (!drawablep || drawablep->isDead())
{
return;
@@ -2744,10 +3208,12 @@ void LLPipeline::markShift(LLDrawable *drawablep)
}
}
+static LLFastTimer::DeclareTimer FTM_SHIFT_DRAWABLE("Shift Drawable");
+static LLFastTimer::DeclareTimer FTM_SHIFT_OCTREE("Shift Octree");
+static LLFastTimer::DeclareTimer FTM_SHIFT_HUD("Shift HUD");
+
void LLPipeline::shiftObjects(const LLVector3 &offset)
{
- LLMemType mt(LLMemType::MTYPE_PIPELINE_SHIFT_OBJECTS);
-
assertInitialized();
glClear(GL_DEPTH_BUFFER_BIT);
@@ -2756,42 +3222,51 @@ void LLPipeline::shiftObjects(const LLVector3 &offset)
LLVector4a offseta;
offseta.load3(offset.mV);
- for (LLDrawable::drawable_vector_t::iterator iter = mShiftList.begin();
- iter != mShiftList.end(); iter++)
{
- LLDrawable *drawablep = *iter;
- if (drawablep->isDead())
+ LLFastTimer t(FTM_SHIFT_DRAWABLE);
+
+ for (LLDrawable::drawable_vector_t::iterator iter = mShiftList.begin();
+ iter != mShiftList.end(); iter++)
{
- continue;
- }
- drawablep->shiftPos(offseta);
- drawablep->clearState(LLDrawable::ON_SHIFT_LIST);
+ LLDrawable *drawablep = *iter;
+ if (drawablep->isDead())
+ {
+ continue;
+ }
+ drawablep->shiftPos(offseta);
+ drawablep->clearState(LLDrawable::ON_SHIFT_LIST);
+ }
+ mShiftList.resize(0);
}
- mShiftList.resize(0);
- for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
- iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
+
{
- LLViewerRegion* region = *iter;
- for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++)
+ LLFastTimer t(FTM_SHIFT_OCTREE);
+ for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
+ iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
{
- LLSpatialPartition* part = region->getSpatialPartition(i);
- if (part)
+ LLViewerRegion* region = *iter;
+ for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++)
{
- part->shift(offseta);
+ LLSpatialPartition* part = region->getSpatialPartition(i);
+ if (part)
+ {
+ part->shift(offseta);
+ }
}
}
}
- LLHUDText::shiftAll(offset);
- LLHUDNameTag::shiftAll(offset);
+ {
+ LLFastTimer t(FTM_SHIFT_HUD);
+ LLHUDText::shiftAll(offset);
+ LLHUDNameTag::shiftAll(offset);
+ }
display_update_camera();
}
void LLPipeline::markTextured(LLDrawable *drawablep)
{
- LLMemType mt(LLMemType::MTYPE_PIPELINE_MARK_TEXTURED);
-
if (drawablep && !drawablep->isDead() && assertInitialized())
{
mRetexturedList.insert(drawablep);
@@ -2817,8 +3292,10 @@ void LLPipeline::markPartitionMove(LLDrawable* drawable)
}
}
+static LLFastTimer::DeclareTimer FTM_PROCESS_PARTITIONQ("PartitionQ");
void LLPipeline::processPartitionQ()
{
+ LLFastTimer t(FTM_PROCESS_PARTITIONQ);
for (LLDrawable::drawable_list_t::iterator iter = mPartitionQ.begin(); iter != mPartitionQ.end(); ++iter)
{
LLDrawable* drawable = *iter;
@@ -2833,10 +3310,13 @@ void LLPipeline::processPartitionQ()
mPartitionQ.clear();
}
+void LLPipeline::markMeshDirty(LLSpatialGroup* group)
+{
+ mMeshDirtyGroup.push_back(group);
+}
+
void LLPipeline::markRebuild(LLSpatialGroup* group, BOOL priority)
{
- LLMemType mt(LLMemType::MTYPE_PIPELINE);
-
if (group && !group->isDead() && group->mSpatialPartition)
{
if (group->mSpatialPartition->mPartitionType == LLViewerRegion::PARTITION_HUD)
@@ -2876,8 +3356,6 @@ void LLPipeline::markRebuild(LLSpatialGroup* group, BOOL priority)
void LLPipeline::markRebuild(LLDrawable *drawablep, LLDrawable::EDrawableFlags flag, BOOL priority)
{
- LLMemType mt(LLMemType::MTYPE_PIPELINE_MARK_REBUILD);
-
if (drawablep && !drawablep->isDead() && assertInitialized())
{
if (!drawablep->isState(LLDrawable::BUILT))
@@ -2924,12 +3402,11 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result)
}
LLFastTimer ftm(FTM_STATESORT);
- LLMemType mt(LLMemType::MTYPE_PIPELINE_STATE_SORT);
//LLVertexBuffer::unbind();
grabReferences(result);
- for (LLCullResult::sg_list_t::iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter)
+ for (LLCullResult::sg_iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter)
{
LLSpatialGroup* group = *iter;
group->checkOcclusion();
@@ -2940,7 +3417,7 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result)
else
{
group->setVisible();
- for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i)
+ for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)
{
markVisible(*i, camera);
}
@@ -2955,9 +3432,9 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result)
if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD)
{
LLSpatialGroup* last_group = NULL;
- for (LLCullResult::bridge_list_t::iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i)
+ for (LLCullResult::bridge_iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i)
{
- LLCullResult::bridge_list_t::iterator cur_iter = i;
+ LLCullResult::bridge_iterator cur_iter = i;
LLSpatialBridge* bridge = *cur_iter;
LLSpatialGroup* group = bridge->getSpatialGroup();
@@ -2987,7 +3464,7 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result)
}
}
- for (LLCullResult::sg_list_t::iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter)
+ for (LLCullResult::sg_iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter)
{
LLSpatialGroup* group = *iter;
group->checkOcclusion();
@@ -3009,7 +3486,7 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result)
{
LLFastTimer ftm(FTM_STATESORT_DRAWABLE);
- for (LLCullResult::drawable_list_t::iterator iter = sCull->beginVisibleList();
+ for (LLCullResult::drawable_iterator iter = sCull->beginVisibleList();
iter != sCull->endVisibleList(); ++iter)
{
LLDrawable *drawablep = *iter;
@@ -3025,10 +3502,9 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result)
void LLPipeline::stateSort(LLSpatialGroup* group, LLCamera& camera)
{
- LLMemType mt(LLMemType::MTYPE_PIPELINE_STATE_SORT);
if (group->changeLOD())
{
- for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i)
+ for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)
{
LLDrawable* drawablep = *i;
stateSort(drawablep, camera);
@@ -3044,7 +3520,6 @@ void LLPipeline::stateSort(LLSpatialGroup* group, LLCamera& camera)
void LLPipeline::stateSort(LLSpatialBridge* bridge, LLCamera& camera)
{
- LLMemType mt(LLMemType::MTYPE_PIPELINE_STATE_SORT);
if (bridge->getSpatialGroup()->changeLOD())
{
bool force_update = false;
@@ -3054,8 +3529,6 @@ void LLPipeline::stateSort(LLSpatialBridge* bridge, LLCamera& camera)
void LLPipeline::stateSort(LLDrawable* drawablep, LLCamera& camera)
{
- LLMemType mt(LLMemType::MTYPE_PIPELINE_STATE_SORT);
-
if (!drawablep
|| drawablep->isDead()
|| !hasRenderType(drawablep->getRenderType()))
@@ -3095,11 +3568,6 @@ void LLPipeline::stateSort(LLDrawable* drawablep, LLCamera& camera)
{
drawablep->setVisible(camera, NULL, FALSE);
}
- else if (drawablep->isState(LLDrawable::CLEAR_INVISIBLE))
- {
- // clear invisible flag here to avoid single frame glitch
- drawablep->clearState(LLDrawable::FORCE_INVISIBLE|LLDrawable::CLEAR_INVISIBLE);
- }
}
if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD)
@@ -3145,13 +3613,13 @@ void LLPipeline::stateSort(LLDrawable* drawablep, LLCamera& camera)
}
-void forAllDrawables(LLCullResult::sg_list_t::iterator begin,
- LLCullResult::sg_list_t::iterator end,
+void forAllDrawables(LLCullResult::sg_iterator begin,
+ LLCullResult::sg_iterator end,
void (*func)(LLDrawable*))
{
- for (LLCullResult::sg_list_t::iterator i = begin; i != end; ++i)
+ for (LLCullResult::sg_iterator i = begin; i != end; ++i)
{
- for (LLSpatialGroup::element_iter j = (*i)->getData().begin(); j != (*i)->getData().end(); ++j)
+ for (LLSpatialGroup::element_iter j = (*i)->getDataBegin(); j != (*i)->getDataEnd(); ++j)
{
func(*j);
}
@@ -3184,7 +3652,11 @@ void renderScriptedBeacons(LLDrawable* drawablep)
S32 count = drawablep->getNumFaces();
for (face_id = 0; face_id < count; face_id++)
{
- gPipeline.mHighlightFaces.push_back(drawablep->getFace(face_id) );
+ LLFace * facep = drawablep->getFace(face_id);
+ if (facep)
+ {
+ gPipeline.mHighlightFaces.push_back(facep);
+ }
}
}
}
@@ -3210,11 +3682,15 @@ void renderScriptedTouchBeacons(LLDrawable* drawablep)
S32 count = drawablep->getNumFaces();
for (face_id = 0; face_id < count; face_id++)
{
- gPipeline.mHighlightFaces.push_back(drawablep->getFace(face_id) );
+ LLFace * facep = drawablep->getFace(face_id);
+ if (facep)
+ {
+ gPipeline.mHighlightFaces.push_back(facep);
}
}
}
}
+}
void renderPhysicalBeacons(LLDrawable* drawablep)
{
@@ -3222,7 +3698,7 @@ void renderPhysicalBeacons(LLDrawable* drawablep)
if (vobj
&& !vobj->isAvatar()
//&& !vobj->getParent()
- && vobj->usePhysics())
+ && vobj->flagUsePhysics())
{
if (gPipeline.sRenderBeacons)
{
@@ -3235,11 +3711,15 @@ void renderPhysicalBeacons(LLDrawable* drawablep)
S32 count = drawablep->getNumFaces();
for (face_id = 0; face_id < count; face_id++)
{
- gPipeline.mHighlightFaces.push_back(drawablep->getFace(face_id) );
+ LLFace * facep = drawablep->getFace(face_id);
+ if (facep)
+ {
+ gPipeline.mHighlightFaces.push_back(facep);
}
}
}
}
+}
void renderMOAPBeacons(LLDrawable* drawablep)
{
@@ -3271,11 +3751,15 @@ void renderMOAPBeacons(LLDrawable* drawablep)
S32 count = drawablep->getNumFaces();
for (face_id = 0; face_id < count; face_id++)
{
- gPipeline.mHighlightFaces.push_back(drawablep->getFace(face_id) );
+ LLFace * facep = drawablep->getFace(face_id);
+ if (facep)
+ {
+ gPipeline.mHighlightFaces.push_back(facep);
}
}
}
}
+}
void renderParticleBeacons(LLDrawable* drawablep)
{
@@ -3296,11 +3780,15 @@ void renderParticleBeacons(LLDrawable* drawablep)
S32 count = drawablep->getNumFaces();
for (face_id = 0; face_id < count; face_id++)
{
- gPipeline.mHighlightFaces.push_back(drawablep->getFace(face_id) );
+ LLFace * facep = drawablep->getFace(face_id);
+ if (facep)
+ {
+ gPipeline.mHighlightFaces.push_back(facep);
}
}
}
}
+}
void renderSoundHighlights(LLDrawable* drawablep)
{
@@ -3314,22 +3802,25 @@ void renderSoundHighlights(LLDrawable* drawablep)
S32 count = drawablep->getNumFaces();
for (face_id = 0; face_id < count; face_id++)
{
- gPipeline.mHighlightFaces.push_back(drawablep->getFace(face_id) );
+ LLFace * facep = drawablep->getFace(face_id);
+ if (facep)
+ {
+ gPipeline.mHighlightFaces.push_back(facep);
}
}
}
}
+}
void LLPipeline::postSort(LLCamera& camera)
{
- LLMemType mt(LLMemType::MTYPE_PIPELINE_POST_SORT);
LLFastTimer ftm(FTM_STATESORT_POSTSORT);
assertInitialized();
llpushcallstacks ;
//rebuild drawable geometry
- for (LLCullResult::sg_list_t::iterator i = sCull->beginDrawableGroups(); i != sCull->endDrawableGroups(); ++i)
+ for (LLCullResult::sg_iterator i = sCull->beginDrawableGroups(); i != sCull->endDrawableGroups(); ++i)
{
LLSpatialGroup* group = *i;
if (!sUseOcclusion ||
@@ -3345,27 +3836,15 @@ void LLPipeline::postSort(LLCamera& camera)
rebuildPriorityGroups();
llpushcallstacks ;
- const S32 bin_count = 1024*8;
-
- static LLCullResult::drawinfo_list_t alpha_bins[bin_count];
- static U32 bin_size[bin_count];
-
- //clear one bin per frame to avoid memory bloat
- static S32 clear_idx = 0;
- clear_idx = (1+clear_idx)%bin_count;
- alpha_bins[clear_idx].clear();
-
- for (U32 j = 0; j < bin_count; j++)
- {
- bin_size[j] = 0;
- }
-
+
//build render map
- for (LLCullResult::sg_list_t::iterator i = sCull->beginVisibleGroups(); i != sCull->endVisibleGroups(); ++i)
+ for (LLCullResult::sg_iterator i = sCull->beginVisibleGroups(); i != sCull->endVisibleGroups(); ++i)
{
LLSpatialGroup* group = *i;
- if (sUseOcclusion &&
- group->isOcclusionState(LLSpatialGroup::OCCLUDED))
+ if ((sUseOcclusion &&
+ group->isOcclusionState(LLSpatialGroup::OCCLUDED)) ||
+ (RenderAutoHideSurfaceAreaLimit > 0.f &&
+ group->mSurfaceArea > RenderAutoHideSurfaceAreaLimit*llmax(group->mObjectBoxSize, 10.f)))
{
continue;
}
@@ -3429,11 +3908,43 @@ void LLPipeline::postSort(LLCamera& camera)
}
}
}
+
+ //flush particle VB
+ LLVOPartGroup::sVB->flush();
+
+ /*bool use_transform_feedback = gTransformPositionProgram.mProgramObject && !mMeshDirtyGroup.empty();
+
+ if (use_transform_feedback)
+ { //place a query around potential transform feedback code for synchronization
+ mTransformFeedbackPrimitives = 0;
+
+ if (!mMeshDirtyQueryObject)
+ {
+ glGenQueriesARB(1, &mMeshDirtyQueryObject);
+ }
+
+ glBeginQueryARB(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, mMeshDirtyQueryObject);
+ }*/
+
+ //pack vertex buffers for groups that chose to delay their updates
+ for (LLSpatialGroup::sg_vector_t::iterator iter = mMeshDirtyGroup.begin(); iter != mMeshDirtyGroup.end(); ++iter)
+ {
+ (*iter)->rebuildMesh();
+ }
+
+ /*if (use_transform_feedback)
+ {
+ glEndQueryARB(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN);
+ }*/
+
+ mMeshDirtyGroup.clear();
+
if (!sShadowRender)
{
std::sort(sCull->beginAlphaGroups(), sCull->endAlphaGroups(), LLSpatialGroup::CompareDepthGreater());
}
+
llpushcallstacks ;
// only render if the flag is set. The flag is only set if we are in edit mode or the toggle is set in the menus
if (LLFloaterReg::instanceVisible("beacons") && !sShadowRender)
@@ -3497,7 +4008,9 @@ void LLPipeline::postSort(LLCamera& camera)
if (!sShadowRender)
{
mSelectedFaces.clear();
-
+
+ LLPipeline::setRenderHighlightTextureChannel(gFloaterTools->getPanelFace()->getTextureChannelToEdit());
+
// Draw face highlights for selected faces.
if (LLSelectMgr::getInstance()->getTEMode())
{
@@ -3507,7 +4020,11 @@ void LLPipeline::postSort(LLCamera& camera)
{
if (object->mDrawable)
{
- gPipeline.mSelectedFaces.push_back(object->mDrawable->getFace(te));
+ LLFace * facep = object->mDrawable->getFace(te);
+ if (facep)
+ {
+ gPipeline.mSelectedFaces.push_back(facep);
+ }
}
return true;
}
@@ -3516,6 +4033,33 @@ void LLPipeline::postSort(LLCamera& camera)
}
}
+ /*static LLFastTimer::DeclareTimer FTM_TRANSFORM_WAIT("Transform Fence");
+ static LLFastTimer::DeclareTimer FTM_TRANSFORM_DO_WORK("Transform Work");
+ if (use_transform_feedback)
+ { //using transform feedback, wait for transform feedback to complete
+ LLFastTimer t(FTM_TRANSFORM_WAIT);
+
+ S32 done = 0;
+ //glGetQueryivARB(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, GL_CURRENT_QUERY, &count);
+
+ glGetQueryObjectivARB(mMeshDirtyQueryObject, GL_QUERY_RESULT_AVAILABLE, &done);
+
+ while (!done)
+ {
+ {
+ LLFastTimer t(FTM_TRANSFORM_DO_WORK);
+ F32 max_time = llmin(gFrameIntervalSeconds*10.f, 1.f);
+ //do some useful work while we wait
+ LLAppViewer::getTextureCache()->update(max_time); // unpauses the texture cache thread
+ LLAppViewer::getImageDecodeThread()->update(max_time); // unpauses the image thread
+ LLAppViewer::getTextureFetch()->update(max_time); // unpauses the texture fetch thread
+ }
+ glGetQueryObjectivARB(mMeshDirtyQueryObject, GL_QUERY_RESULT_AVAILABLE, &done);
+ }
+
+ mTransformFeedbackPrimitives = 0;
+ }*/
+
//LLSpatialGroup::sNoDelete = FALSE;
llpushcallstacks ;
}
@@ -3523,7 +4067,6 @@ void LLPipeline::postSort(LLCamera& camera)
void render_hud_elements()
{
- LLMemType mt_rhe(LLMemType::MTYPE_PIPELINE_RENDER_HUD_ELS);
LLFastTimer t(FTM_RENDER_UI);
gPipeline.disableLights();
@@ -3578,8 +4121,6 @@ void render_hud_elements()
void LLPipeline::renderHighlights()
{
- LLMemType mt(LLMemType::MTYPE_PIPELINE_RENDER_HL);
-
assertInitialized();
// Draw 3D UI elements here (before we clear the Z buffer in POOL_HUD)
@@ -3692,13 +4233,14 @@ void LLPipeline::renderHighlights()
gGL.diffuseColor4f(1,1,1,0.5f);
}
- if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED))
+ if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED) && !mFaceSelectImagep)
+ {
+ mFaceSelectImagep = LLViewerTextureManager::getFetchedTexture(IMG_FACE_SELECT);
+ }
+
+ if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED) && (sRenderHighlightTextureChannel == LLRender::DIFFUSE_MAP))
{
// Make sure the selection image gets downloaded and decoded
- if (!mFaceSelectImagep)
- {
- mFaceSelectImagep = LLViewerTextureManager::getFetchedTexture(IMG_FACE_SELECT);
- }
mFaceSelectImagep->addTextureStats((F32)MAX_IMAGE_AREA);
U32 count = mSelectedFaces.size();
@@ -3714,7 +4256,7 @@ void LLPipeline::renderHighlights()
facep->renderSelected(mFaceSelectImagep, color);
}
}
-
+
if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED))
{
// Paint 'em red!
@@ -3736,6 +4278,67 @@ void LLPipeline::renderHighlights()
{
gHighlightProgram.unbind();
}
+
+
+ if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED) && (sRenderHighlightTextureChannel == LLRender::NORMAL_MAP))
+ {
+ color.setVec(1.0f, 0.5f, 0.5f, 0.5f);
+ if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0))
+ {
+ gHighlightNormalProgram.bind();
+ gGL.diffuseColor4f(1,1,1,0.5f);
+ }
+
+ mFaceSelectImagep->addTextureStats((F32)MAX_IMAGE_AREA);
+
+ U32 count = mSelectedFaces.size();
+ for (U32 i = 0; i < count; i++)
+ {
+ LLFace *facep = mSelectedFaces[i];
+ if (!facep || facep->getDrawable()->isDead())
+ {
+ llerrs << "Bad face on selection" << llendl;
+ return;
+ }
+
+ facep->renderSelected(mFaceSelectImagep, color);
+ }
+
+ if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0))
+ {
+ gHighlightNormalProgram.unbind();
+ }
+ }
+
+ if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED) && (sRenderHighlightTextureChannel == LLRender::SPECULAR_MAP))
+ {
+ color.setVec(0.0f, 0.3f, 1.0f, 0.8f);
+ if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0))
+ {
+ gHighlightSpecularProgram.bind();
+ gGL.diffuseColor4f(1,1,1,0.5f);
+ }
+
+ mFaceSelectImagep->addTextureStats((F32)MAX_IMAGE_AREA);
+
+ U32 count = mSelectedFaces.size();
+ for (U32 i = 0; i < count; i++)
+ {
+ LLFace *facep = mSelectedFaces[i];
+ if (!facep || facep->getDrawable()->isDead())
+ {
+ llerrs << "Bad face on selection" << llendl;
+ return;
+ }
+
+ facep->renderSelected(mFaceSelectImagep, color);
+ }
+
+ if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0))
+ {
+ gHighlightSpecularProgram.unbind();
+ }
+ }
}
//debug use
@@ -3743,7 +4346,6 @@ U32 LLPipeline::sCurRenderPoolType = 0 ;
void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate)
{
- LLMemType mt(LLMemType::MTYPE_PIPELINE_RENDER_GEOM);
LLFastTimer t(FTM_RENDER_GEOMETRY);
assertInitialized();
@@ -3811,6 +4413,7 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate)
gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sDefaultImagep);
LLViewerFetchedTexture::sDefaultImagep->setAddressMode(LLTexUnit::TAM_WRAP);
+
//////////////////////////////////////////////
//
// Actually render all of the geometry
@@ -3883,7 +4486,7 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate)
break;
}
- p->render(i);
+ if ( !p->getSkipRenderFlag() ) { p->render(i); }
}
poolp->endRenderPass(i);
LLVertexBuffer::unbind();
@@ -3995,10 +4598,9 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera)
{
LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderGeomDeferred");
- LLMemType mt_rgd(LLMemType::MTYPE_PIPELINE_RENDER_GEOM_DEFFERRED);
LLFastTimer t(FTM_RENDER_GEOMETRY);
- LLFastTimer t2(FTM_POOLS);
+ LLFastTimer t2(FTM_DEFERRED_POOLS);
LLGLEnable cull(GL_CULL_FACE);
@@ -4040,7 +4642,7 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera)
pool_set_t::iterator iter2 = iter1;
if (hasRenderType(poolp->getType()) && poolp->getNumDeferredPasses() > 0)
{
- LLFastTimer t(FTM_POOLRENDER);
+ LLFastTimer t(FTM_DEFERRED_POOLRENDER);
gGLLastMatrix = NULL;
gGL.loadMatrix(gGLModelView);
@@ -4057,7 +4659,7 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera)
break;
}
- p->renderDeferred(i);
+ if ( !p->getSkipRenderFlag() ) { p->renderDeferred(i); }
}
poolp->endDeferredPass(i);
LLVertexBuffer::unbind();
@@ -4090,10 +4692,9 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera)
gGL.setColorMask(true, false);
}
-void LLPipeline::renderGeomPostDeferred(LLCamera& camera)
+void LLPipeline::renderGeomPostDeferred(LLCamera& camera, bool do_occlusion)
{
- LLMemType mt_rgpd(LLMemType::MTYPE_PIPELINE_RENDER_GEOM_POST_DEF);
- LLFastTimer t(FTM_POOLS);
+ LLFastTimer t(FTM_POST_DEFERRED_POOLS);
U32 cur_type = 0;
LLGLEnable cull(GL_CULL_FACE);
@@ -4106,7 +4707,7 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera)
gGL.setColorMask(true, false);
pool_set_t::iterator iter1 = mPools.begin();
- BOOL occlude = LLPipeline::sUseOcclusion > 1;
+ BOOL occlude = LLPipeline::sUseOcclusion > 1 && do_occlusion;
while ( iter1 != mPools.end() )
{
@@ -4120,14 +4721,14 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera)
gGLLastMatrix = NULL;
gGL.loadMatrix(gGLModelView);
LLGLSLShader::bindNoShader();
- doOcclusion(camera);
+ doOcclusion(camera, mScreen, mOcclusionDepth, &mDeferredDepth);
gGL.setColorMask(true, false);
}
pool_set_t::iterator iter2 = iter1;
if (hasRenderType(poolp->getType()) && poolp->getNumPostDeferredPasses() > 0)
{
- LLFastTimer t(FTM_POOLRENDER);
+ LLFastTimer t(FTM_POST_DEFERRED_POOLRENDER);
gGLLastMatrix = NULL;
gGL.loadMatrix(gGLModelView);
@@ -4188,7 +4789,6 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera)
void LLPipeline::renderGeomShadow(LLCamera& camera)
{
- LLMemType mt_rgs(LLMemType::MTYPE_PIPELINE_RENDER_GEOM_SHADOW);
U32 cur_type = 0;
LLGLEnable cull(GL_CULL_FACE);
@@ -4317,18 +4917,6 @@ void LLPipeline::renderPhysicsDisplay()
}
}
- for (LLCullResult::bridge_list_t::const_iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i)
- {
- LLSpatialBridge* bridge = *i;
- if (!bridge->isDead() && hasRenderType(bridge->mDrawableType))
- {
- gGL.pushMatrix();
- gGL.multMatrix((F32*)bridge->mDrawable->getRenderMatrix().mMatrix);
- bridge->renderPhysicsShapes();
- gGL.popMatrix();
- }
- }
-
gGL.flush();
if (LLGLSLShader::sNoFixedFunction)
@@ -4339,21 +4927,347 @@ void LLPipeline::renderPhysicsDisplay()
mPhysicsDisplay.flush();
}
+extern std::set<LLSpatialGroup*> visible_selected_groups;
void LLPipeline::renderDebug()
{
- LLMemType mt(LLMemType::MTYPE_PIPELINE);
-
assertInitialized();
+ bool hud_only = hasRenderType(LLPipeline::RENDER_TYPE_HUD);
+
+ if (!hud_only )
+ {
+ //Render any navmesh geometry
+ LLPathingLib *llPathingLibInstance = LLPathingLib::getInstance();
+ if ( llPathingLibInstance != NULL )
+ {
+ //character floater renderables
+
+ LLHandle<LLFloaterPathfindingCharacters> pathfindingCharacterHandle = LLFloaterPathfindingCharacters::getInstanceHandle();
+ if ( !pathfindingCharacterHandle.isDead() )
+ {
+ LLFloaterPathfindingCharacters *pathfindingCharacter = pathfindingCharacterHandle.get();
+
+ if ( pathfindingCharacter->getVisible() || gAgentCamera.cameraMouselook() )
+ {
+ if (LLGLSLShader::sNoFixedFunction)
+ {
+ gPathfindingProgram.bind();
+ gPathfindingProgram.uniform1f(sTint, 1.f);
+ gPathfindingProgram.uniform1f(sAmbiance, 1.f);
+ gPathfindingProgram.uniform1f(sAlphaScale, 1.f);
+ }
+
+ //Requried character physics capsule render parameters
+ LLUUID id;
+ LLVector3 pos;
+ LLQuaternion rot;
+
+ if ( pathfindingCharacter->isPhysicsCapsuleEnabled( id, pos, rot ) )
+ {
+ if (LLGLSLShader::sNoFixedFunction)
+ {
+ //remove blending artifacts
+ gGL.setColorMask(false, false);
+ llPathingLibInstance->renderSimpleShapeCapsuleID( gGL, id, pos, rot );
+ gGL.setColorMask(true, false);
+ LLGLEnable blend(GL_BLEND);
+ gPathfindingProgram.uniform1f(sAlphaScale, 0.90f);
+ llPathingLibInstance->renderSimpleShapeCapsuleID( gGL, id, pos, rot );
+ gPathfindingProgram.bind();
+ }
+ else
+ {
+ llPathingLibInstance->renderSimpleShapeCapsuleID( gGL, id, pos, rot );
+ }
+ }
+ }
+ }
+
+
+ //pathing console renderables
+ LLHandle<LLFloaterPathfindingConsole> pathfindingConsoleHandle = LLFloaterPathfindingConsole::getInstanceHandle();
+ if (!pathfindingConsoleHandle.isDead())
+ {
+ LLFloaterPathfindingConsole *pathfindingConsole = pathfindingConsoleHandle.get();
+
+ if ( pathfindingConsole->getVisible() || gAgentCamera.cameraMouselook() )
+ {
+ F32 ambiance = gSavedSettings.getF32("PathfindingAmbiance");
+
+ if (LLGLSLShader::sNoFixedFunction)
+ {
+ gPathfindingProgram.bind();
+
+ gPathfindingProgram.uniform1f(sTint, 1.f);
+ gPathfindingProgram.uniform1f(sAmbiance, ambiance);
+ gPathfindingProgram.uniform1f(sAlphaScale, 1.f);
+ }
+
+ if ( !pathfindingConsole->isRenderWorld() )
+ {
+ const LLColor4 clearColor = gSavedSettings.getColor4("PathfindingNavMeshClear");
+ gGL.setColorMask(true, true);
+ glClearColor(clearColor.mV[0],clearColor.mV[1],clearColor.mV[2],0);
+ glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+ gGL.setColorMask(true, false);
+ glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
+ }
+
+ //NavMesh
+ if ( pathfindingConsole->isRenderNavMesh() )
+ {
+ gGL.flush();
+ glLineWidth(2.0f);
+ LLGLEnable cull(GL_CULL_FACE);
+ LLGLDisable blend(GL_BLEND);
+
+ if ( pathfindingConsole->isRenderWorld() )
+ {
+ LLGLEnable blend(GL_BLEND);
+ gPathfindingProgram.uniform1f(sAlphaScale, 0.66f);
+ llPathingLibInstance->renderNavMesh();
+ }
+ else
+ {
+ llPathingLibInstance->renderNavMesh();
+ }
+
+ //render edges
+ if (LLGLSLShader::sNoFixedFunction)
+ {
+ gPathfindingNoNormalsProgram.bind();
+ gPathfindingNoNormalsProgram.uniform1f(sTint, 1.f);
+ gPathfindingNoNormalsProgram.uniform1f(sAlphaScale, 1.f);
+ llPathingLibInstance->renderNavMeshEdges();
+ gPathfindingProgram.bind();
+ }
+ else
+ {
+ llPathingLibInstance->renderNavMeshEdges();
+ }
+
+ gGL.flush();
+ glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
+ glLineWidth(1.0f);
+ gGL.flush();
+ }
+ //User designated path
+ if ( LLPathfindingPathTool::getInstance()->isRenderPath() )
+ {
+ //The path
+ if (LLGLSLShader::sNoFixedFunction)
+ {
+ gUIProgram.bind();
+ gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sWhiteImagep);
+ llPathingLibInstance->renderPath();
+ gPathfindingProgram.bind();
+ }
+ else
+ {
+ llPathingLibInstance->renderPath();
+ }
+ //The bookends
+ if (LLGLSLShader::sNoFixedFunction)
+ {
+ //remove blending artifacts
+ gGL.setColorMask(false, false);
+ llPathingLibInstance->renderPathBookend( gGL, LLPathingLib::LLPL_START );
+ llPathingLibInstance->renderPathBookend( gGL, LLPathingLib::LLPL_END );
+
+ gGL.setColorMask(true, false);
+ //render the bookends
+ LLGLEnable blend(GL_BLEND);
+ gPathfindingProgram.uniform1f(sAlphaScale, 0.90f);
+ llPathingLibInstance->renderPathBookend( gGL, LLPathingLib::LLPL_START );
+ llPathingLibInstance->renderPathBookend( gGL, LLPathingLib::LLPL_END );
+ gPathfindingProgram.bind();
+ }
+ else
+ {
+ llPathingLibInstance->renderPathBookend( gGL, LLPathingLib::LLPL_START );
+ llPathingLibInstance->renderPathBookend( gGL, LLPathingLib::LLPL_END );
+ }
+
+ }
+
+ if ( pathfindingConsole->isRenderWaterPlane() )
+ {
+ if (LLGLSLShader::sNoFixedFunction)
+ {
+ LLGLEnable blend(GL_BLEND);
+ gPathfindingProgram.uniform1f(sAlphaScale, 0.90f);
+ llPathingLibInstance->renderSimpleShapes( gGL, gAgent.getRegion()->getWaterHeight() );
+ }
+ else
+ {
+ llPathingLibInstance->renderSimpleShapes( gGL, gAgent.getRegion()->getWaterHeight() );
+ }
+ }
+ //physics/exclusion shapes
+ if ( pathfindingConsole->isRenderAnyShapes() )
+ {
+ U32 render_order[] = {
+ 1 << LLPathingLib::LLST_ObstacleObjects,
+ 1 << LLPathingLib::LLST_WalkableObjects,
+ 1 << LLPathingLib::LLST_ExclusionPhantoms,
+ 1 << LLPathingLib::LLST_MaterialPhantoms,
+ };
+
+ U32 flags = pathfindingConsole->getRenderShapeFlags();
+
+ for (U32 i = 0; i < 4; i++)
+ {
+ if (!(flags & render_order[i]))
+ {
+ continue;
+ }
+
+ //turn off backface culling for volumes so they are visible when camera is inside volume
+ LLGLDisable cull(i >= 2 ? GL_CULL_FACE : 0);
+
+ gGL.flush();
+ glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
+
+ //get rid of some z-fighting
+ LLGLEnable polyOffset(GL_POLYGON_OFFSET_FILL);
+ glPolygonOffset(1.0f, 1.0f);
+
+ //render to depth first to avoid blending artifacts
+ gGL.setColorMask(false, false);
+ llPathingLibInstance->renderNavMeshShapesVBO( render_order[i] );
+ gGL.setColorMask(true, false);
+
+ //get rid of some z-fighting
+ glPolygonOffset(0.f, 0.f);
+
+ LLGLEnable blend(GL_BLEND);
+
+ {
+ gPathfindingProgram.uniform1f(sAmbiance, ambiance);
+
+ { //draw solid overlay
+ LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_LEQUAL);
+ llPathingLibInstance->renderNavMeshShapesVBO( render_order[i] );
+ gGL.flush();
+ }
+
+ LLGLEnable lineOffset(GL_POLYGON_OFFSET_LINE);
+ glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
+
+ F32 offset = gSavedSettings.getF32("PathfindingLineOffset");
+
+ if (pathfindingConsole->isRenderXRay())
+ {
+ gPathfindingProgram.uniform1f(sTint, gSavedSettings.getF32("PathfindingXRayTint"));
+ gPathfindingProgram.uniform1f(sAlphaScale, gSavedSettings.getF32("PathfindingXRayOpacity"));
+ LLGLEnable blend(GL_BLEND);
+ LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_GREATER);
+
+ glPolygonOffset(offset, -offset);
+
+ if (gSavedSettings.getBOOL("PathfindingXRayWireframe"))
+ { //draw hidden wireframe as darker and less opaque
+ gPathfindingProgram.uniform1f(sAmbiance, 1.f);
+ llPathingLibInstance->renderNavMeshShapesVBO( render_order[i] );
+ }
+ else
+ {
+ glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
+ gPathfindingProgram.uniform1f(sAmbiance, ambiance);
+ llPathingLibInstance->renderNavMeshShapesVBO( render_order[i] );
+ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+ }
+ }
+
+ { //draw visible wireframe as brighter, thicker and more opaque
+ glPolygonOffset(offset, offset);
+ gPathfindingProgram.uniform1f(sAmbiance, 1.f);
+ gPathfindingProgram.uniform1f(sTint, 1.f);
+ gPathfindingProgram.uniform1f(sAlphaScale, 1.f);
+
+ glLineWidth(gSavedSettings.getF32("PathfindingLineWidth"));
+ LLGLDisable blendOut(GL_BLEND);
+ llPathingLibInstance->renderNavMeshShapesVBO( render_order[i] );
+ gGL.flush();
+ glLineWidth(1.f);
+ }
+
+ glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
+ }
+ }
+ }
+
+ glPolygonOffset(0.f, 0.f);
+
+ if ( pathfindingConsole->isRenderNavMesh() && pathfindingConsole->isRenderXRay() )
+ { //render navmesh xray
+ F32 ambiance = gSavedSettings.getF32("PathfindingAmbiance");
+
+ LLGLEnable lineOffset(GL_POLYGON_OFFSET_LINE);
+ LLGLEnable polyOffset(GL_POLYGON_OFFSET_FILL);
+
+ F32 offset = gSavedSettings.getF32("PathfindingLineOffset");
+ glPolygonOffset(offset, -offset);
+
+ LLGLEnable blend(GL_BLEND);
+ LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_GREATER);
+ gGL.flush();
+ glLineWidth(2.0f);
+ LLGLEnable cull(GL_CULL_FACE);
+
+ gPathfindingProgram.uniform1f(sTint, gSavedSettings.getF32("PathfindingXRayTint"));
+ gPathfindingProgram.uniform1f(sAlphaScale, gSavedSettings.getF32("PathfindingXRayOpacity"));
+
+ if (gSavedSettings.getBOOL("PathfindingXRayWireframe"))
+ { //draw hidden wireframe as darker and less opaque
+ glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
+ gPathfindingProgram.uniform1f(sAmbiance, 1.f);
+ llPathingLibInstance->renderNavMesh();
+ glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
+ }
+ else
+ {
+ gPathfindingProgram.uniform1f(sAmbiance, ambiance);
+ llPathingLibInstance->renderNavMesh();
+ }
+
+ //render edges
+ if (LLGLSLShader::sNoFixedFunction)
+ {
+ gPathfindingNoNormalsProgram.bind();
+ gPathfindingNoNormalsProgram.uniform1f(sTint, gSavedSettings.getF32("PathfindingXRayTint"));
+ gPathfindingNoNormalsProgram.uniform1f(sAlphaScale, gSavedSettings.getF32("PathfindingXRayOpacity"));
+ llPathingLibInstance->renderNavMeshEdges();
+ gPathfindingProgram.bind();
+ }
+ else
+ {
+ llPathingLibInstance->renderNavMeshEdges();
+ }
+
+ gGL.flush();
+ glLineWidth(1.0f);
+ }
+
+ glPolygonOffset(0.f, 0.f);
+
+ gGL.flush();
+ if (LLGLSLShader::sNoFixedFunction)
+ {
+ gPathfindingProgram.unbind();
+ }
+ }
+ }
+ }
+ }
+
gGL.color4f(1,1,1,1);
gGLLastMatrix = NULL;
gGL.loadMatrix(gGLModelView);
gGL.setColorMask(true, false);
- bool hud_only = hasRenderType(LLPipeline::RENDER_TYPE_HUD);
-
if (!hud_only && !mDebugBlips.empty())
{ //render debug blips
@@ -4403,8 +5317,8 @@ void LLPipeline::renderDebug()
LLSpatialPartition* part = region->getSpatialPartition(i);
if (part)
{
- if ( hud_only && (part->mDrawableType == RENDER_TYPE_HUD || part->mDrawableType == RENDER_TYPE_HUD_PARTICLES) ||
- !hud_only && hasRenderType(part->mDrawableType) )
+ if ( (hud_only && (part->mDrawableType == RENDER_TYPE_HUD || part->mDrawableType == RENDER_TYPE_HUD_PARTICLES)) ||
+ (!hud_only && hasRenderType(part->mDrawableType)) )
{
part->renderDebug();
}
@@ -4412,7 +5326,7 @@ void LLPipeline::renderDebug()
}
}
- for (LLCullResult::bridge_list_t::const_iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i)
+ for (LLCullResult::bridge_iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i)
{
LLSpatialBridge* bridge = *i;
if (!bridge->isDead() && hasRenderType(bridge->mDrawableType))
@@ -4424,11 +5338,68 @@ void LLPipeline::renderDebug()
}
}
+ if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCCLUSION) && LLGLSLShader::sNoFixedFunction)
+ { //render visible selected group occlusion geometry
+ gDebugProgram.bind();
+ LLGLDepthTest depth(GL_TRUE, GL_FALSE);
+ gGL.diffuseColor3f(1,0,1);
+ for (std::set<LLSpatialGroup*>::iterator iter = visible_selected_groups.begin(); iter != visible_selected_groups.end(); ++iter)
+ {
+ LLSpatialGroup* group = *iter;
+
+ LLVector4a fudge;
+ fudge.splat(0.25f); //SG_OCCLUSION_FUDGE
+
+ LLVector4a size;
+ size.setAdd(fudge, group->mBounds[1]);
+
+ drawBox(group->mBounds[0], size);
+ }
+ }
+
+ visible_selected_groups.clear();
+
if (LLGLSLShader::sNoFixedFunction)
{
gUIProgram.bind();
}
+ if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_RAYCAST) && !hud_only)
+ { //draw crosshairs on particle intersection
+ if (gDebugRaycastParticle)
+ {
+ if (LLGLSLShader::sNoFixedFunction)
+ { //this debug display requires shaders
+ gDebugProgram.bind();
+
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+ LLVector3 center(gDebugRaycastParticleIntersection.getF32ptr());
+ LLVector3 size(0.1f, 0.1f, 0.1f);
+
+ LLVector3 p[6];
+
+ p[0] = center + size.scaledVec(LLVector3(1,0,0));
+ p[1] = center + size.scaledVec(LLVector3(-1,0,0));
+ p[2] = center + size.scaledVec(LLVector3(0,1,0));
+ p[3] = center + size.scaledVec(LLVector3(0,-1,0));
+ p[4] = center + size.scaledVec(LLVector3(0,0,1));
+ p[5] = center + size.scaledVec(LLVector3(0,0,-1));
+
+ gGL.begin(LLRender::LINES);
+ gGL.diffuseColor3f(1.f, 1.f, 0.f);
+ for (U32 i = 0; i < 6; i++)
+ {
+ gGL.vertex3fv(p[i].mV);
+ }
+ gGL.end();
+ gGL.flush();
+
+ gDebugProgram.unbind();
+ }
+ }
+ }
+
if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA))
{
LLVertexBuffer::unbind();
@@ -4462,7 +5433,7 @@ void LLPipeline::renderDebug()
if (i > 3)
{ //render shadow frusta as volumes
if (mShadowFrustPoints[i-4].empty())
- {
+ {
continue;
}
@@ -4664,9 +5635,11 @@ void LLPipeline::renderDebug()
}
}
+static LLFastTimer::DeclareTimer FTM_REBUILD_POOLS("Rebuild Pools");
+
void LLPipeline::rebuildPools()
{
- LLMemType mt(LLMemType::MTYPE_PIPELINE_REBUILD_POOLS);
+ LLFastTimer t(FTM_REBUILD_POOLS);
assertInitialized();
@@ -4697,17 +5670,10 @@ void LLPipeline::rebuildPools()
}
max_count--;
}
-
- if (isAgentAvatarValid())
- {
- gAgentAvatarp->rebuildHUD();
- }
}
void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp )
{
- LLMemType mt(LLMemType::MTYPE_PIPELINE_QUICK_LOOKUP);
-
assertInitialized();
switch( new_poolp->getType() )
@@ -4724,6 +5690,32 @@ void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp )
}
break;
+ case LLDrawPool::POOL_ALPHA_MASK:
+ if (mAlphaMaskPool)
+ {
+ llassert(0);
+ llwarns << "Ignoring duplicate alpha mask pool." << llendl;
+ break;
+ }
+ else
+ {
+ mAlphaMaskPool = (LLRenderPass*) new_poolp;
+ }
+ break;
+
+ case LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK:
+ if (mFullbrightAlphaMaskPool)
+ {
+ llassert(0);
+ llwarns << "Ignoring duplicate alpha mask pool." << llendl;
+ break;
+ }
+ else
+ {
+ mFullbrightAlphaMaskPool = (LLRenderPass*) new_poolp;
+ }
+ break;
+
case LLDrawPool::POOL_GRASS:
if (mGrassPool)
{
@@ -4791,7 +5783,17 @@ void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp )
mBumpPool = new_poolp;
}
break;
-
+ case LLDrawPool::POOL_MATERIALS:
+ if (mMaterialsPool)
+ {
+ llassert(0);
+ llwarns << "Ignorning duplicate materials pool." << llendl;
+ }
+ else
+ {
+ mMaterialsPool = new_poolp;
+ }
+ break;
case LLDrawPool::POOL_ALPHA:
if( mAlphaPool )
{
@@ -4800,7 +5802,7 @@ void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp )
}
else
{
- mAlphaPool = new_poolp;
+ mAlphaPool = (LLDrawPoolAlpha*) new_poolp;
}
break;
@@ -4873,7 +5875,6 @@ void LLPipeline::removePool( LLDrawPool* poolp )
void LLPipeline::removeFromQuickLookup( LLDrawPool* poolp )
{
assertInitialized();
- LLMemType mt(LLMemType::MTYPE_PIPELINE);
switch( poolp->getType() )
{
case LLDrawPool::POOL_SIMPLE:
@@ -4881,6 +5882,16 @@ void LLPipeline::removeFromQuickLookup( LLDrawPool* poolp )
mSimplePool = NULL;
break;
+ case LLDrawPool::POOL_ALPHA_MASK:
+ llassert(mAlphaMaskPool == poolp);
+ mAlphaMaskPool = NULL;
+ break;
+
+ case LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK:
+ llassert(mFullbrightAlphaMaskPool == poolp);
+ mFullbrightAlphaMaskPool = NULL;
+ break;
+
case LLDrawPool::POOL_GRASS:
llassert(mGrassPool == poolp);
mGrassPool = NULL;
@@ -4932,7 +5943,12 @@ void LLPipeline::removeFromQuickLookup( LLDrawPool* poolp )
llassert( poolp == mBumpPool );
mBumpPool = NULL;
break;
-
+
+ case LLDrawPool::POOL_MATERIALS:
+ llassert(poolp == mMaterialsPool);
+ mMaterialsPool = NULL;
+ break;
+
case LLDrawPool::POOL_ALPHA:
llassert( poolp == mAlphaPool );
mAlphaPool = NULL;
@@ -4995,8 +6011,15 @@ void LLPipeline::setupAvatarLights(BOOL for_edit)
LLLightState* light = gGL.getLight(1);
- mHWLightColors[1] = diffuse;
+ if (LLPipeline::sRenderDeferred)
+ {
+ /*diffuse.mV[0] = powf(diffuse.mV[0], 2.2f);
+ diffuse.mV[1] = powf(diffuse.mV[1], 2.2f);
+ diffuse.mV[2] = powf(diffuse.mV[2], 2.2f);*/
+ }
+ mHWLightColors[1] = diffuse;
+
light->setDiffuse(diffuse);
light->setAmbient(LLColor4::black);
light->setSpecular(LLColor4::black);
@@ -5035,6 +6058,13 @@ void LLPipeline::setupAvatarLights(BOOL for_edit)
}
backlight_diffuse *= backlight_mag / max_component;
+ if (LLPipeline::sRenderDeferred)
+ {
+ /*backlight_diffuse.mV[0] = powf(backlight_diffuse.mV[0], 2.2f);
+ backlight_diffuse.mV[1] = powf(backlight_diffuse.mV[1], 2.2f);
+ backlight_diffuse.mV[2] = powf(backlight_diffuse.mV[2], 2.2f);*/
+ }
+
mHWLightColors[1] = backlight_diffuse;
LLLightState* light = gGL.getLight(1);
@@ -5189,7 +6219,7 @@ void LLPipeline::calcNearbyLights(LLCamera& camera)
// crazy cast so that we can overwrite the fade value
// even though gcc enforces sets as const
// (fade value doesn't affect sort so this is safe)
- Light* farthest_light = ((Light*) (&(*(mNearbyLights.rbegin()))));
+ Light* farthest_light = (const_cast<Light*>(&(*(mNearbyLights.rbegin()))));
if (light->dist < farthest_light->dist)
{
if (farthest_light->fade >= 0.f)
@@ -5241,6 +6271,14 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
LLVector4 light_pos(mSunDir, 0.0f);
LLColor4 light_diffuse = mSunDiffuse;
+
+ if (LLPipeline::sRenderDeferred)
+ {
+ /*light_diffuse.mV[0] = powf(light_diffuse.mV[0], 2.2f);
+ light_diffuse.mV[1] = powf(light_diffuse.mV[1], 2.2f);
+ light_diffuse.mV[2] = powf(light_diffuse.mV[2], 2.2f);*/
+ }
+
mHWLightColors[0] = light_diffuse;
LLLightState* light = gGL.getLight(0);
@@ -5319,7 +6357,7 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
if (sRenderDeferred)
{
F32 size = light_radius*1.5f;
- light_state->setLinearAttenuation(size*size);
+ light_state->setLinearAttenuation(size);
light_state->setQuadraticAttenuation(light->getLightFalloff()*0.5f+1.f);
}
else
@@ -5332,7 +6370,6 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
if (light->isLightSpotlight() // directional (spot-)light
&& (LLPipeline::sRenderDeferred || RenderSpotLightsInNondeferred)) // these are only rendered as GL spotlights if we're in deferred rendering mode *or* the setting forces them on
{
- LLVector3 spotparams = light->getSpotLightParams();
LLQuaternion quat = light->getRenderRotation();
LLVector3 at_axis(0,0,-1); // this matches deferred rendering's object light direction
at_axis *= quat;
@@ -5383,6 +6420,13 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
F32 x = 3.f;
float linatten = x / (light_radius); // % of brightness at radius
+ if (LLPipeline::sRenderDeferred)
+ {
+ /*light_color.mV[0] = powf(light_color.mV[0], 2.2f);
+ light_color.mV[1] = powf(light_color.mV[1], 2.2f);
+ light_color.mV[2] = powf(light_color.mV[2], 2.2f);*/
+ }
+
mHWLightColors[2] = light_color;
LLLightState* light = gGL.getLight(2);
@@ -5532,7 +6576,7 @@ void LLPipeline::enableLightsPreview()
LLVector4 light_pos(dir0, 0.0f);
- LLLightState* light = gGL.getLight(0);
+ LLLightState* light = gGL.getLight(1);
light->enable();
light->setPosition(light_pos);
@@ -5544,7 +6588,7 @@ void LLPipeline::enableLightsPreview()
light_pos = LLVector4(dir1, 0.f);
- light = gGL.getLight(1);
+ light = gGL.getLight(2);
light->enable();
light->setPosition(light_pos);
light->setDiffuse(diffuse1);
@@ -5554,7 +6598,7 @@ void LLPipeline::enableLightsPreview()
light->setSpotCutoff(180.f);
light_pos = LLVector4(dir2, 0.f);
- light = gGL.getLight(2);
+ light = gGL.getLight(3);
light->enable();
light->setPosition(light_pos);
light->setDiffuse(diffuse2);
@@ -5863,6 +6907,22 @@ void LLPipeline::setRenderDebugFeatureControl(U32 bit, bool value)
}
}
+void LLPipeline::pushRenderDebugFeatureMask()
+{
+ mRenderDebugFeatureStack.push(mRenderDebugFeatureMask);
+}
+
+void LLPipeline::popRenderDebugFeatureMask()
+{
+ if (mRenderDebugFeatureStack.empty())
+ {
+ llerrs << "Depleted render feature stack." << llendl;
+ }
+
+ mRenderDebugFeatureMask = mRenderDebugFeatureStack.top();
+ mRenderDebugFeatureStack.pop();
+}
+
// static
void LLPipeline::setRenderScriptedBeacons(BOOL val)
{
@@ -6007,20 +7067,68 @@ BOOL LLPipeline::getRenderHighlights(void*)
return sRenderHighlight;
}
-LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start, const LLVector3& end,
+// static
+void LLPipeline::setRenderHighlightTextureChannel(LLRender::eTexIndex channel)
+{
+ sRenderHighlightTextureChannel = channel;
+}
+
+LLVOPartGroup* LLPipeline::lineSegmentIntersectParticle(const LLVector4a& start, const LLVector4a& end, LLVector4a* intersection,
+ S32* face_hit)
+{
+ LLVector4a local_end = end;
+
+ LLVector4a position;
+
+ LLDrawable* drawable = NULL;
+
+ for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
+ iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
+ {
+ LLViewerRegion* region = *iter;
+
+ LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_PARTICLE);
+ if (part && hasRenderType(part->mDrawableType))
+ {
+ LLDrawable* hit = part->lineSegmentIntersect(start, local_end, TRUE, face_hit, &position, NULL, NULL, NULL);
+ if (hit)
+ {
+ drawable = hit;
+ local_end = position;
+ }
+ }
+ }
+
+ LLVOPartGroup* ret = NULL;
+ if (drawable)
+ {
+ //make sure we're returning an LLVOPartGroup
+ llassert(drawable->getVObj()->getPCode() == LLViewerObject::LL_VO_PART_GROUP);
+ ret = (LLVOPartGroup*) drawable->getVObj().get();
+ }
+
+ if (intersection)
+ {
+ *intersection = position;
+ }
+
+ return ret;
+}
+
+LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector4a& start, const LLVector4a& end,
BOOL pick_transparent,
S32* face_hit,
- LLVector3* intersection, // return the intersection point
+ LLVector4a* intersection, // return the intersection point
LLVector2* tex_coord, // return the texture coordinates of the intersection point
- LLVector3* normal, // return the surface normal at the intersection point
- LLVector3* bi_normal // return the surface bi-normal at the intersection point
+ LLVector4a* normal, // return the surface normal at the intersection point
+ LLVector4a* tangent // return the surface tangent at the intersection point
)
{
LLDrawable* drawable = NULL;
- LLVector3 local_end = end;
+ LLVector4a local_end = end;
- LLVector3 position;
+ LLVector4a position;
sPickAvatar = FALSE; //LLToolMgr::getInstance()->inBuildMode() ? FALSE : TRUE;
@@ -6040,7 +7148,7 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start,
LLSpatialPartition* part = region->getSpatialPartition(j);
if (part && hasRenderType(part->mDrawableType))
{
- LLDrawable* hit = part->lineSegmentIntersect(start, local_end, pick_transparent, face_hit, &position, tex_coord, normal, bi_normal);
+ LLDrawable* hit = part->lineSegmentIntersect(start, local_end, pick_transparent, face_hit, &position, tex_coord, normal, tangent);
if (hit)
{
drawable = hit;
@@ -6055,8 +7163,8 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start,
{
//save hit info in case we need to restore
//due to attachment override
- LLVector3 local_normal;
- LLVector3 local_binormal;
+ LLVector4a local_normal;
+ LLVector4a local_tangent;
LLVector2 local_texcoord;
S32 local_face_hit = -1;
@@ -6068,14 +7176,22 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start,
{
local_texcoord = *tex_coord;
}
- if (bi_normal)
+ if (tangent)
+ {
+ local_tangent = *tangent;
+ }
+ else
{
- local_binormal = *bi_normal;
+ local_tangent.clear();
}
if (normal)
{
local_normal = *normal;
}
+ else
+ {
+ local_normal.clear();
+ }
const F32 ATTACHMENT_OVERRIDE_DIST = 0.1f;
@@ -6089,12 +7205,15 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start,
LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_BRIDGE);
if (part && hasRenderType(part->mDrawableType))
{
- LLDrawable* hit = part->lineSegmentIntersect(start, local_end, pick_transparent, face_hit, &position, tex_coord, normal, bi_normal);
+ LLDrawable* hit = part->lineSegmentIntersect(start, local_end, pick_transparent, face_hit, &position, tex_coord, normal, tangent);
if (hit)
{
+ LLVector4a delta;
+ delta.setSub(position, local_end);
+
if (!drawable ||
!drawable->getVObj()->isAttachment() ||
- (position-local_end).magVec() > ATTACHMENT_OVERRIDE_DIST)
+ delta.getLength3().getF32() > ATTACHMENT_OVERRIDE_DIST)
{ //avatar overrides if previously hit drawable is not an attachment or
//attachment is far enough away from detected intersection
drawable = hit;
@@ -6112,9 +7231,9 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start,
{
*tex_coord = local_texcoord;
}
- if (bi_normal)
+ if (tangent)
{
- *bi_normal = local_binormal;
+ *tangent = local_tangent;
}
if (normal)
{
@@ -6148,13 +7267,13 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start,
return drawable ? drawable->getVObj().get() : NULL;
}
-LLViewerObject* LLPipeline::lineSegmentIntersectInHUD(const LLVector3& start, const LLVector3& end,
+LLViewerObject* LLPipeline::lineSegmentIntersectInHUD(const LLVector4a& start, const LLVector4a& end,
BOOL pick_transparent,
S32* face_hit,
- LLVector3* intersection, // return the intersection point
+ LLVector4a* intersection, // return the intersection point
LLVector2* tex_coord, // return the texture coordinates of the intersection point
- LLVector3* normal, // return the surface normal at the intersection point
- LLVector3* bi_normal // return the surface bi-normal at the intersection point
+ LLVector4a* normal, // return the surface normal at the intersection point
+ LLVector4a* tangent // return the surface tangent at the intersection point
)
{
LLDrawable* drawable = NULL;
@@ -6174,7 +7293,7 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInHUD(const LLVector3& start, co
LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_HUD);
if (part)
{
- LLDrawable* hit = part->lineSegmentIntersect(start, end, pick_transparent, face_hit, intersection, tex_coord, normal, bi_normal);
+ LLDrawable* hit = part->lineSegmentIntersect(start, end, pick_transparent, face_hit, intersection, tex_coord, normal, tangent);
if (hit)
{
drawable = hit;
@@ -6212,24 +7331,32 @@ void LLPipeline::resetVertexBuffers(LLDrawable* drawable)
for (S32 i = 0; i < drawable->getNumFaces(); i++)
{
LLFace* facep = drawable->getFace(i);
- facep->clearVertexBuffer();
+ if (facep)
+ {
+ facep->clearVertexBuffer();
+ }
}
}
void LLPipeline::resetVertexBuffers()
-{
+{
mResetVertexBuffers = true;
}
+static LLFastTimer::DeclareTimer FTM_RESET_VB("Reset VB");
+
void LLPipeline::doResetVertexBuffers()
{
if (!mResetVertexBuffers)
{
return;
}
-
+
+ LLFastTimer t(FTM_RESET_VB);
mResetVertexBuffers = false;
+ mCubeVB = NULL;
+
for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
{
@@ -6248,11 +7375,21 @@ void LLPipeline::doResetVertexBuffers()
gSky.resetVertexBuffers();
+ LLVOPartGroup::destroyGL();
+
+ if ( LLPathingLib::getInstance() )
+ {
+ LLPathingLib::getInstance()->cleanupVBOManager();
+ }
+ LLVOPartGroup::destroyGL();
+
LLVertexBuffer::cleanupClass();
//delete all name pool caches
LLGLNamePool::cleanupPools();
+
+
if (LLVertexBuffer::sGLCount > 0)
{
llwarns << "VBO wipe failed -- " << LLVertexBuffer::sGLCount << " buffers remaining." << llendl;
@@ -6260,7 +7397,9 @@ void LLPipeline::doResetVertexBuffers()
LLVertexBuffer::unbind();
- sRenderBump = gSavedSettings.getBOOL("RenderObjectBump");
+ updateRenderBump();
+ updateRenderDeferred();
+
sUseTriStrips = gSavedSettings.getBOOL("RenderUseTriStrips");
LLVertexBuffer::sUseStreamDraw = gSavedSettings.getBOOL("RenderUseStreamVBO");
LLVertexBuffer::sUseVAO = gSavedSettings.getBOOL("RenderUseVAO");
@@ -6272,11 +7411,12 @@ void LLPipeline::doResetVertexBuffers()
LLPipeline::sTextureBindTest = gSavedSettings.getBOOL("RenderDebugTextureBind");
LLVertexBuffer::initClass(LLVertexBuffer::sEnableVBOs, LLVertexBuffer::sDisableVBOMapping);
+
+ LLVOPartGroup::restoreGL();
}
void LLPipeline::renderObjects(U32 type, U32 mask, BOOL texture, BOOL batch_texture)
{
- LLMemType mt_ro(LLMemType::MTYPE_PIPELINE_RENDER_OBJECTS);
assertInitialized();
gGL.loadMatrix(gGLModelView);
gGLLastMatrix = NULL;
@@ -6285,6 +7425,17 @@ void LLPipeline::renderObjects(U32 type, U32 mask, BOOL texture, BOOL batch_text
gGLLastMatrix = NULL;
}
+void LLPipeline::renderMaskedObjects(U32 type, U32 mask, BOOL texture, BOOL batch_texture)
+{
+ assertInitialized();
+ gGL.loadMatrix(gGLModelView);
+ gGLLastMatrix = NULL;
+ mAlphaMaskPool->pushMaskBatches(type, mask, texture, batch_texture);
+ gGL.loadMatrix(gGLModelView);
+ gGLLastMatrix = NULL;
+}
+
+
void apply_cube_face_rotation(U32 face)
{
switch (face)
@@ -6349,7 +7500,6 @@ static LLFastTimer::DeclareTimer FTM_RENDER_BLOOM("Bloom");
void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
{
- LLMemType mt_ru(LLMemType::MTYPE_PIPELINE_RENDER_BLOOM);
if (!(gPipeline.canUseVertexShaders() &&
sRenderGlow))
{
@@ -6387,10 +7537,10 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
gGL.loadIdentity();
LLGLDisable test(GL_ALPHA_TEST);
-
+
gGL.setColorMask(true, true);
glClearColor(0,0,0,0);
-
+
{
{
LLFastTimer ftm(FTM_RENDER_BLOOM_FBO);
@@ -6501,11 +7651,11 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
gGlowProgram.unbind();
- if (LLRenderTarget::sUseFBO)
+ /*if (LLRenderTarget::sUseFBO)
{
LLFastTimer ftm(FTM_RENDER_BLOOM_FBO);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
- }
+ }*/
gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft;
gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom;
@@ -6524,7 +7674,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
{
bool dof_enabled = !LLViewerCamera::getInstance()->cameraUnderWater() &&
- !LLToolMgr::getInstance()->inBuildMode() &&
+ (RenderDepthOfFieldInEditMode || !LLToolMgr::getInstance()->inBuildMode()) &&
RenderDepthOfField;
@@ -6562,24 +7712,26 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
{
if (LLViewerJoystick::getInstance()->getOverrideCamera())
{ //focus on point under cursor
- focus_point = gDebugRaycastIntersection;
+ focus_point.set(gDebugRaycastIntersection.getF32ptr());
}
else if (gAgentCamera.cameraMouselook())
{ //focus on point under mouselook crosshairs
+ LLVector4a result;
+ result.clear();
+
gViewerWindow->cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE,
NULL,
- &focus_point);
+ &result);
+
+ focus_point.set(result.getF32ptr());
}
else
{
- LLViewerObject* obj = gAgentCamera.getFocusObject();
- if (obj)
- { //focus on alt-zoom target
- focus_point = LLVector3(gAgentCamera.getFocusGlobal()-gAgent.getRegion()->getOriginGlobal());
- }
- else
- { //focus on your avatar
- focus_point = gAgent.getPositionAgent();
+ //focus on alt-zoom target
+ LLViewerRegion* region = gAgent.getRegion();
+ if (region)
+ {
+ focus_point = LLVector3(gAgentCamera.getFocusGlobal()-region->getOriginGlobal());
}
}
}
@@ -6735,6 +7887,13 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
mScreen.bindTexture(0, channel);
gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
}
+
+ if (!LLViewerCamera::getInstance()->cameraUnderWater())
+ {
+ shader->uniform1f(LLShaderMgr::GLOBAL_GAMMA, 2.2);
+ } else {
+ shader->uniform1f(LLShaderMgr::GLOBAL_GAMMA, 1.0);
+ }
shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF);
shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale);
@@ -6776,6 +7935,13 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
{
mScreen.bindTexture(0, channel);
}
+
+ if (!LLViewerCamera::getInstance()->cameraUnderWater())
+ {
+ shader->uniform1f(LLShaderMgr::GLOBAL_GAMMA, 2.2);
+ } else {
+ shader->uniform1f(LLShaderMgr::GLOBAL_GAMMA, 1.0);
+ }
gGL.begin(LLRender::TRIANGLE_STRIP);
gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
@@ -7081,7 +8247,7 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, U32 n
for (U32 i = 0; i < 4; i++)
{
- channel = shader.enableTexture(LLShaderMgr::DEFERRED_SHADOW0+i, LLTexUnit::TT_RECT_TEXTURE);
+ channel = shader.enableTexture(LLShaderMgr::DEFERRED_SHADOW0+i, LLTexUnit::TT_TEXTURE);
stop_glerror();
if (channel > -1)
{
@@ -7091,8 +8257,8 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, U32 n
gGL.getTexUnit(channel)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
stop_glerror();
- glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB);
- glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
stop_glerror();
}
}
@@ -7172,13 +8338,13 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, U32 n
matrix_nondiag, matrix_nondiag, matrix_diag};
shader.uniformMatrix3fv(LLShaderMgr::DEFERRED_SSAO_EFFECT_MAT, 1, GL_FALSE, ssao_effect_mat);
- F32 shadow_offset_error = 1.f + RenderShadowOffsetError * fabsf(LLViewerCamera::getInstance()->getOrigin().mV[2]);
- F32 shadow_bias_error = 1.f + RenderShadowBiasError * fabsf(LLViewerCamera::getInstance()->getOrigin().mV[2]);
+ //F32 shadow_offset_error = 1.f + RenderShadowOffsetError * fabsf(LLViewerCamera::getInstance()->getOrigin().mV[2]);
+ F32 shadow_bias_error = RenderShadowBiasError * fabsf(LLViewerCamera::getInstance()->getOrigin().mV[2])/3000.f;
shader.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, mDeferredScreen.getWidth(), mDeferredScreen.getHeight());
shader.uniform1f(LLShaderMgr::DEFERRED_NEAR_CLIP, LLViewerCamera::getInstance()->getNear()*2.f);
- shader.uniform1f (LLShaderMgr::DEFERRED_SHADOW_OFFSET, RenderShadowOffset*shadow_offset_error);
- shader.uniform1f(LLShaderMgr::DEFERRED_SHADOW_BIAS, RenderShadowBias*shadow_bias_error);
+ shader.uniform1f (LLShaderMgr::DEFERRED_SHADOW_OFFSET, RenderShadowOffset); //*shadow_offset_error);
+ shader.uniform1f(LLShaderMgr::DEFERRED_SHADOW_BIAS, RenderShadowBias+shadow_bias_error);
shader.uniform1f(LLShaderMgr::DEFERRED_SPOT_SHADOW_OFFSET, RenderSpotShadowOffset);
shader.uniform1f(LLShaderMgr::DEFERRED_SPOT_SHADOW_BIAS, RenderSpotShadowBias);
@@ -7189,13 +8355,29 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, U32 n
shader.uniform1f(LLShaderMgr::DEFERRED_NORM_CUTOFF, RenderEdgeNormCutoff);
- if (shader.getUniformLocation("norm_mat") >= 0)
+ if (shader.getUniformLocation(LLShaderMgr::DEFERRED_NORM_MATRIX) >= 0)
{
glh::matrix4f norm_mat = glh_get_current_modelview().inverse().transpose();
- shader.uniformMatrix4fv("norm_mat", 1, FALSE, norm_mat.m);
+ shader.uniformMatrix4fv(LLShaderMgr::DEFERRED_NORM_MATRIX, 1, FALSE, norm_mat.m);
}
}
+LLColor3 pow3f(LLColor3 v, F32 f)
+{
+ v.mV[0] = powf(v.mV[0], f);
+ v.mV[1] = powf(v.mV[1], f);
+ v.mV[2] = powf(v.mV[2], f);
+ return v;
+}
+
+LLVector4 pow4fsrgb(LLVector4 v, F32 f)
+{
+ v.mV[0] = powf(v.mV[0], f);
+ v.mV[1] = powf(v.mV[1], f);
+ v.mV[2] = powf(v.mV[2], f);
+ return v;
+}
+
static LLFastTimer::DeclareTimer FTM_GI_TRACE("Trace");
static LLFastTimer::DeclareTimer FTM_GI_GATHER("Gather");
static LLFastTimer::DeclareTimer FTM_SUN_SHADOW("Shadow Map");
@@ -7249,11 +8431,7 @@ void LLPipeline::renderDeferredLighting()
LLStrider<LLVector3> vert;
mDeferredVB->getVertexStrider(vert);
- LLStrider<LLVector2> tc0;
- LLStrider<LLVector2> tc1;
- mDeferredVB->getTexCoord0Strider(tc0);
- mDeferredVB->getTexCoord1Strider(tc1);
-
+
vert[0].set(-1,1,0);
vert[1].set(-1,-3,0);
vert[2].set(3,1,0);
@@ -7302,8 +8480,8 @@ void LLPipeline::renderDeferredLighting()
}
}
- gDeferredSunProgram.uniform3fv("offset", slice, offset);
- gDeferredSunProgram.uniform2f("screenRes", mDeferredLight.getWidth(), mDeferredLight.getHeight());
+ gDeferredSunProgram.uniform3fv(sOffset, slice, offset);
+ gDeferredSunProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, mDeferredLight.getWidth(), mDeferredLight.getHeight());
{
LLGLDisable blend(GL_BLEND);
@@ -7347,10 +8525,10 @@ void LLPipeline::renderDeferredLighting()
x += 1.f;
}
- gDeferredBlurLightProgram.uniform2f("delta", 1.f, 0.f);
- gDeferredBlurLightProgram.uniform1f("dist_factor", dist_factor);
- gDeferredBlurLightProgram.uniform3fv("kern", kern_length, gauss[0].mV);
- gDeferredBlurLightProgram.uniform1f("kern_scale", blur_size * (kern_length/2.f - 0.5f));
+ gDeferredBlurLightProgram.uniform2f(sDelta, 1.f, 0.f);
+ gDeferredBlurLightProgram.uniform1f(sDistFactor, dist_factor);
+ gDeferredBlurLightProgram.uniform3fv(sKern, kern_length, gauss[0].mV);
+ gDeferredBlurLightProgram.uniform1f(sKernScale, blur_size * (kern_length/2.f - 0.5f));
{
LLGLDisable blend(GL_BLEND);
@@ -7367,7 +8545,7 @@ void LLPipeline::renderDeferredLighting()
mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
mDeferredLight.bindTarget();
- gDeferredBlurLightProgram.uniform2f("delta", 0.f, 1.f);
+ gDeferredBlurLightProgram.uniform2f(sDelta, 0.f, 1.f);
{
LLGLDisable blend(GL_BLEND);
@@ -7388,10 +8566,6 @@ void LLPipeline::renderDeferredLighting()
gGL.popMatrix();
stop_glerror();
- //copy depth and stencil from deferred screen
- //mScreen.copyContents(mDeferredScreen, 0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight(),
- // 0, 0, mScreen.getWidth(), mScreen.getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
-
mScreen.bindTarget();
// clear color buffer here - zeroing alpha (glow) is important or it will accumulate against sky
glClearColor(0,0,0,0);
@@ -7400,7 +8574,7 @@ void LLPipeline::renderDeferredLighting()
if (RenderDeferredAtmospheric)
{ //apply sunlight contribution
LLFastTimer ftm(FTM_ATMOSPHERICS);
- bindDeferredShader(gDeferredSoftenProgram);
+ bindDeferredShader(LLPipeline::sUnderWaterRender ? gDeferredSoftenWaterProgram : gDeferredSoftenProgram);
{
LLGLDepthTest depth(GL_FALSE);
LLGLDisable blend(GL_BLEND);
@@ -7422,7 +8596,7 @@ void LLPipeline::renderDeferredLighting()
gGL.popMatrix();
}
- unbindDeferredShader(gDeferredSoftenProgram);
+ unbindDeferredShader(LLPipeline::sUnderWaterRender ? gDeferredSoftenWaterProgram : gDeferredSoftenProgram);
}
{ //render non-deferred geometry (fullbright, alpha, etc)
@@ -7438,7 +8612,7 @@ void LLPipeline::renderDeferredLighting()
LLPipeline::END_RENDER_TYPES);
- renderGeomPostDeferred(*LLViewerCamera::getInstance());
+ renderGeomPostDeferred(*LLViewerCamera::getInstance(), false);
gPipeline.popRenderTypeMask();
}
@@ -7459,12 +8633,17 @@ void LLPipeline::renderDeferredLighting()
std::list<LLVector4> light_colors;
LLVertexBuffer::unbind();
- LLVector4a* v = (LLVector4a*) vert.get();
{
bindDeferredShader(gDeferredLightProgram);
- mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+
+ if (mCubeVB.isNull())
+ {
+ mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX, GL_STATIC_DRAW_ARB);
+ }
+ mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+
LLGLDepthTest depth(GL_TRUE, GL_FALSE);
for (LLDrawable::drawable_set_t::iterator iter = mLights.begin(); iter != mLights.end(); ++iter)
{
@@ -7510,25 +8689,7 @@ void LLPipeline::renderDeferredLighting()
}
sVisibleLightCount++;
-
- glh::vec3f tc(c);
- mat.mult_matrix_vec(tc);
-
- //vertex positions are encoded so the 3 bits of their vertex index
- //correspond to their axis facing, with bit position 3,2,1 matching
- //axis facing x,y,z, bit set meaning positive facing, bit clear
- //meaning negative facing
- mDeferredVB->getVertexStrider(vert);
- v[0].set(c[0]-s,c[1]-s,c[2]-s); // 0 - 0000
- v[1].set(c[0]-s,c[1]-s,c[2]+s); // 1 - 0001
- v[2].set(c[0]-s,c[1]+s,c[2]-s); // 2 - 0010
- v[3].set(c[0]-s,c[1]+s,c[2]+s); // 3 - 0011
-
- v[4].set(c[0]+s,c[1]-s,c[2]-s); // 4 - 0100
- v[5].set(c[0]+s,c[1]-s,c[2]+s); // 5 - 0101
- v[6].set(c[0]+s,c[1]+s,c[2]-s); // 6 - 0110
- v[7].set(c[0]+s,c[1]+s,c[2]+s); // 7 - 0111
-
+
if (camera->getOrigin().mV[0] > c[0] + s + 0.2f ||
camera->getOrigin().mV[0] < c[0] - s - 0.2f ||
camera->getOrigin().mV[1] > c[1] + s + 0.2f ||
@@ -7545,17 +8706,18 @@ void LLPipeline::renderDeferredLighting()
continue;
}
+ /*col.mV[0] = powf(col.mV[0], 2.2f);
+ col.mV[1] = powf(col.mV[1], 2.2f);
+ col.mV[2] = powf(col.mV[2], 2.2f);*/
+
LLFastTimer ftm(FTM_LOCAL_LIGHTS);
- //glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], s*s);
- gDeferredLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, tc.v);
- gDeferredLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s*s);
+ gDeferredLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, c);
+ gDeferredLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s);
gDeferredLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV);
gDeferredLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, volume->getLightFalloff()*0.5f);
- //gGL.diffuseColor4f(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f);
gGL.syncMatrices();
- mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
- glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8,
- GL_UNSIGNED_SHORT, get_box_fan_indices_ptr(camera, center));
+
+ mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, center));
stop_glerror();
}
}
@@ -7568,7 +8730,10 @@ void LLPipeline::renderDeferredLighting()
continue;
}
- fullscreen_lights.push_back(LLVector4(tc.v[0], tc.v[1], tc.v[2], s*s));
+ glh::vec3f tc(c);
+ mat.mult_matrix_vec(tc);
+
+ fullscreen_lights.push_back(LLVector4(tc.v[0], tc.v[1], tc.v[2], s));
light_colors.push_back(LLVector4(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f));
}
}
@@ -7580,7 +8745,7 @@ void LLPipeline::renderDeferredLighting()
LLGLDepthTest depth(GL_TRUE, GL_FALSE);
bindDeferredShader(gDeferredSpotLightProgram);
- mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+ mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
gDeferredSpotLightProgram.enableTexture(LLShaderMgr::DEFERRED_PROJECTION);
@@ -7598,36 +8763,20 @@ void LLPipeline::renderDeferredLighting()
sVisibleLightCount++;
- glh::vec3f tc(c);
- mat.mult_matrix_vec(tc);
-
setupSpotLight(gDeferredSpotLightProgram, drawablep);
LLColor3 col = volume->getLightColor();
+ /*col.mV[0] = powf(col.mV[0], 2.2f);
+ col.mV[1] = powf(col.mV[1], 2.2f);
+ col.mV[2] = powf(col.mV[2], 2.2f);*/
- //vertex positions are encoded so the 3 bits of their vertex index
- //correspond to their axis facing, with bit position 3,2,1 matching
- //axis facing x,y,z, bit set meaning positive facing, bit clear
- //meaning negative facing
- mDeferredVB->getVertexStrider(vert);
- v[0].set(c[0]-s,c[1]-s,c[2]-s); // 0 - 0000
- v[1].set(c[0]-s,c[1]-s,c[2]+s); // 1 - 0001
- v[2].set(c[0]-s,c[1]+s,c[2]-s); // 2 - 0010
- v[3].set(c[0]-s,c[1]+s,c[2]+s); // 3 - 0011
-
- v[4].set(c[0]+s,c[1]-s,c[2]-s); // 4 - 0100
- v[5].set(c[0]+s,c[1]-s,c[2]+s); // 5 - 0101
- v[6].set(c[0]+s,c[1]+s,c[2]-s); // 6 - 0110
- v[7].set(c[0]+s,c[1]+s,c[2]+s); // 7 - 0111
-
- gDeferredSpotLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, tc.v);
- gDeferredSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s*s);
+ gDeferredSpotLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, c);
+ gDeferredSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s);
gDeferredSpotLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV);
gDeferredSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, volume->getLightFalloff()*0.5f);
gGL.syncMatrices();
- mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
- glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8,
- GL_UNSIGNED_SHORT, get_box_fan_indices_ptr(camera, center));
+
+ mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, center));
}
gDeferredSpotLightProgram.disableTexture(LLShaderMgr::DEFERRED_PROJECTION);
unbindDeferredShader(gDeferredSpotLightProgram);
@@ -7640,10 +8789,6 @@ void LLPipeline::renderDeferredLighting()
vert[2].set(3,1,0);
{
- bindDeferredShader(gDeferredMultiLightProgram);
-
- mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
-
LLGLDepthTest depth(GL_FALSE);
//full screen blit
@@ -7655,12 +8800,10 @@ void LLPipeline::renderDeferredLighting()
U32 count = 0;
- const U32 max_count = 8;
+ const U32 max_count = LL_DEFERRED_MULTI_LIGHT_COUNT;
LLVector4 light[max_count];
LLVector4 col[max_count];
-// glVertexPointer(2, GL_FLOAT, 0, vert);
-
F32 far_z = 0.f;
while (!fullscreen_lights.empty())
@@ -7670,24 +8813,30 @@ void LLPipeline::renderDeferredLighting()
fullscreen_lights.pop_front();
col[count] = light_colors.front();
light_colors.pop_front();
-
- far_z = llmin(light[count].mV[2]-sqrtf(light[count].mV[3]), far_z);
-
+
+ /*col[count].mV[0] = powf(col[count].mV[0], 2.2f);
+ col[count].mV[1] = powf(col[count].mV[1], 2.2f);
+ col[count].mV[2] = powf(col[count].mV[2], 2.2f);*/
+
+ far_z = llmin(light[count].mV[2]-light[count].mV[3], far_z);
+ //col[count] = pow4fsrgb(col[count], 2.2f);
count++;
if (count == max_count || fullscreen_lights.empty())
{
- gDeferredMultiLightProgram.uniform1i(LLShaderMgr::MULTI_LIGHT_COUNT, count);
- gDeferredMultiLightProgram.uniform4fv(LLShaderMgr::MULTI_LIGHT, count, (GLfloat*) light);
- gDeferredMultiLightProgram.uniform4fv(LLShaderMgr::MULTI_LIGHT_COL, count, (GLfloat*) col);
- gDeferredMultiLightProgram.uniform1f(LLShaderMgr::MULTI_LIGHT_FAR_Z, far_z);
+ U32 idx = count-1;
+ bindDeferredShader(gDeferredMultiLightProgram[idx]);
+ gDeferredMultiLightProgram[idx].uniform1i(LLShaderMgr::MULTI_LIGHT_COUNT, count);
+ gDeferredMultiLightProgram[idx].uniform4fv(LLShaderMgr::MULTI_LIGHT, count, (GLfloat*) light);
+ gDeferredMultiLightProgram[idx].uniform4fv(LLShaderMgr::MULTI_LIGHT_COL, count, (GLfloat*) col);
+ gDeferredMultiLightProgram[idx].uniform1f(LLShaderMgr::MULTI_LIGHT_FAR_Z, far_z);
far_z = 0.f;
count = 0;
+ mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+ unbindDeferredShader(gDeferredMultiLightProgram[idx]);
}
}
- unbindDeferredShader(gDeferredMultiLightProgram);
-
bindDeferredShader(gDeferredMultiSpotLightProgram);
gDeferredMultiSpotLightProgram.enableTexture(LLShaderMgr::DEFERRED_PROJECTION);
@@ -7714,8 +8863,12 @@ void LLPipeline::renderDeferredLighting()
LLColor3 col = volume->getLightColor();
+ /*col.mV[0] = powf(col.mV[0], 2.2f);
+ col.mV[1] = powf(col.mV[1], 2.2f);
+ col.mV[2] = powf(col.mV[2], 2.2f);*/
+
gDeferredMultiSpotLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, tc.v);
- gDeferredMultiSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s*s);
+ gDeferredMultiSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s);
gDeferredMultiSpotLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV);
gDeferredMultiSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, volume->getLightFalloff()*0.5f);
mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
@@ -7733,6 +8886,65 @@ void LLPipeline::renderDeferredLighting()
gGL.setColorMask(true, true);
}
+ mScreen.flush();
+
+ //gamma correct lighting
+ gGL.matrixMode(LLRender::MM_PROJECTION);
+ gGL.pushMatrix();
+ gGL.loadIdentity();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.pushMatrix();
+ gGL.loadIdentity();
+
+ {
+ LLGLDepthTest depth(GL_FALSE, GL_FALSE);
+
+ LLVector2 tc1(0,0);
+ LLVector2 tc2((F32) mScreen.getWidth()*2,
+ (F32) mScreen.getHeight()*2);
+
+ mScreen.bindTarget();
+ // Apply gamma correction to the frame here.
+ gDeferredPostGammaCorrectProgram.bind();
+ //mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+ S32 channel = 0;
+ channel = gDeferredPostGammaCorrectProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage());
+ if (channel > -1)
+ {
+ mScreen.bindTexture(0,channel);
+ gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
+ }
+
+ gDeferredPostGammaCorrectProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, mScreen.getWidth(), mScreen.getHeight());
+
+ F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma");
+
+ gDeferredPostGammaCorrectProgram.uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f));
+
+ gGL.begin(LLRender::TRIANGLE_STRIP);
+ gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
+ gGL.vertex2f(-1,-1);
+
+ gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
+ gGL.vertex2f(-1,3);
+
+ gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
+ gGL.vertex2f(3,-1);
+
+ gGL.end();
+
+ gGL.getTexUnit(channel)->unbind(mScreen.getUsage());
+ gDeferredPostGammaCorrectProgram.unbind();
+ mScreen.flush();
+ }
+
+ gGL.matrixMode(LLRender::MM_PROJECTION);
+ gGL.popMatrix();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.popMatrix();
+
+ mScreen.bindTarget();
+
{ //render non-deferred geometry (alpha, fullbright, glow)
LLGLDisable blend(GL_BLEND);
LLGLDisable stencil(GL_STENCIL_TEST);
@@ -7757,6 +8969,8 @@ void LLPipeline::renderDeferredLighting()
LLPipeline::RENDER_TYPE_PASS_INVISIBLE,
LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY,
LLPipeline::RENDER_TYPE_AVATAR,
+ LLPipeline::RENDER_TYPE_ALPHA_MASK,
+ LLPipeline::RENDER_TYPE_FULLBRIGHT_ALPHA_MASK,
END_RENDER_TYPES);
renderGeomPostDeferred(*LLViewerCamera::getInstance());
@@ -7784,6 +8998,537 @@ void LLPipeline::renderDeferredLighting()
}
+void LLPipeline::renderDeferredLightingToRT(LLRenderTarget* target)
+{
+ if (!sCull)
+ {
+ return;
+ }
+
+ {
+ LLFastTimer ftm(FTM_RENDER_DEFERRED);
+
+ LLViewerCamera* camera = LLViewerCamera::getInstance();
+
+ {
+ LLGLDepthTest depth(GL_TRUE);
+ mDeferredDepth.copyContents(mDeferredScreen, 0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight(),
+ 0, 0, mDeferredDepth.getWidth(), mDeferredDepth.getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST);
+ }
+
+ LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0);
+
+ if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD))
+ {
+ gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD);
+ }
+
+ //ati doesn't seem to love actually using the stencil buffer on FBO's
+ LLGLDisable stencil(GL_STENCIL_TEST);
+ //glStencilFunc(GL_EQUAL, 1, 0xFFFFFFFF);
+ //glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
+
+ gGL.setColorMask(true, true);
+
+ //draw a cube around every light
+ LLVertexBuffer::unbind();
+
+ LLGLEnable cull(GL_CULL_FACE);
+ LLGLEnable blend(GL_BLEND);
+
+ glh::matrix4f mat = glh_copy_matrix(gGLModelView);
+
+ LLStrider<LLVector3> vert;
+ mDeferredVB->getVertexStrider(vert);
+
+ vert[0].set(-1,1,0);
+ vert[1].set(-1,-3,0);
+ vert[2].set(3,1,0);
+
+ {
+ setupHWLights(NULL); //to set mSunDir;
+ LLVector4 dir(mSunDir, 0.f);
+ glh::vec4f tc(dir.mV);
+ mat.mult_matrix_vec(tc);
+ mTransformedSunDir.set(tc.v);
+ }
+
+ gGL.pushMatrix();
+ gGL.loadIdentity();
+ gGL.matrixMode(LLRender::MM_PROJECTION);
+ gGL.pushMatrix();
+ gGL.loadIdentity();
+
+ if (RenderDeferredSSAO || RenderShadowDetail > 0)
+ {
+ mDeferredLight.bindTarget();
+ { //paint shadow/SSAO light map (direct lighting lightmap)
+ LLFastTimer ftm(FTM_SUN_SHADOW);
+ bindDeferredShader(gDeferredSunProgram);
+ mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+ glClearColor(1,1,1,1);
+ mDeferredLight.clear(GL_COLOR_BUFFER_BIT);
+ glClearColor(0,0,0,0);
+
+ glh::matrix4f inv_trans = glh_get_current_modelview().inverse().transpose();
+
+ const U32 slice = 32;
+ F32 offset[slice*3];
+ for (U32 i = 0; i < 4; i++)
+ {
+ for (U32 j = 0; j < 8; j++)
+ {
+ glh::vec3f v;
+ v.set_value(sinf(6.284f/8*j), cosf(6.284f/8*j), -(F32) i);
+ v.normalize();
+ inv_trans.mult_matrix_vec(v);
+ v.normalize();
+ offset[(i*8+j)*3+0] = v.v[0];
+ offset[(i*8+j)*3+1] = v.v[2];
+ offset[(i*8+j)*3+2] = v.v[1];
+ }
+ }
+
+ gDeferredSunProgram.uniform3fv(LLShaderMgr::DEFERRED_SHADOW_OFFSET, slice, offset);
+ gDeferredSunProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, mDeferredLight.getWidth(), mDeferredLight.getHeight());
+
+ {
+ LLGLDisable blend(GL_BLEND);
+ LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS);
+ stop_glerror();
+ mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+ stop_glerror();
+ }
+
+ unbindDeferredShader(gDeferredSunProgram);
+ }
+ mDeferredLight.flush();
+ }
+
+ stop_glerror();
+ gGL.popMatrix();
+ stop_glerror();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ stop_glerror();
+ gGL.popMatrix();
+ stop_glerror();
+
+ target->bindTarget();
+
+ //clear color buffer here - zeroing alpha (glow) is important or it will accumulate against sky
+ glClearColor(0,0,0,0);
+ target->clear(GL_COLOR_BUFFER_BIT);
+
+ if (RenderDeferredAtmospheric)
+ { //apply sunlight contribution
+ LLFastTimer ftm(FTM_ATMOSPHERICS);
+ bindDeferredShader(gDeferredSoftenProgram);
+ {
+ LLGLDepthTest depth(GL_FALSE);
+ LLGLDisable blend(GL_BLEND);
+ LLGLDisable test(GL_ALPHA_TEST);
+
+ //full screen blit
+ gGL.pushMatrix();
+ gGL.loadIdentity();
+ gGL.matrixMode(LLRender::MM_PROJECTION);
+ gGL.pushMatrix();
+ gGL.loadIdentity();
+
+ mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+
+ mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+
+ gGL.popMatrix();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.popMatrix();
+ }
+
+ unbindDeferredShader(gDeferredSoftenProgram);
+ }
+
+ { //render non-deferred geometry (fullbright, alpha, etc)
+ LLGLDisable blend(GL_BLEND);
+ LLGLDisable stencil(GL_STENCIL_TEST);
+ gGL.setSceneBlendType(LLRender::BT_ALPHA);
+
+ gPipeline.pushRenderTypeMask();
+
+ gPipeline.andRenderTypeMask(LLPipeline::RENDER_TYPE_SKY,
+ LLPipeline::RENDER_TYPE_CLOUDS,
+ LLPipeline::RENDER_TYPE_WL_SKY,
+ LLPipeline::END_RENDER_TYPES);
+
+
+ renderGeomPostDeferred(*LLViewerCamera::getInstance(), false);
+ gPipeline.popRenderTypeMask();
+ }
+
+ BOOL render_local = RenderLocalLights;
+
+ if (render_local)
+ {
+ gGL.setSceneBlendType(LLRender::BT_ADD);
+ std::list<LLVector4> fullscreen_lights;
+ LLDrawable::drawable_list_t spot_lights;
+ LLDrawable::drawable_list_t fullscreen_spot_lights;
+
+ for (U32 i = 0; i < 2; i++)
+ {
+ mTargetShadowSpotLight[i] = NULL;
+ }
+
+ std::list<LLVector4> light_colors;
+
+ LLVertexBuffer::unbind();
+
+ {
+ bindDeferredShader(gDeferredLightProgram);
+
+ if (mCubeVB.isNull())
+ {
+ mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX, GL_STATIC_DRAW_ARB);
+ }
+
+ mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+
+ LLGLDepthTest depth(GL_TRUE, GL_FALSE);
+ for (LLDrawable::drawable_set_t::iterator iter = mLights.begin(); iter != mLights.end(); ++iter)
+ {
+ LLDrawable* drawablep = *iter;
+
+ LLVOVolume* volume = drawablep->getVOVolume();
+ if (!volume)
+ {
+ continue;
+ }
+
+ if (volume->isAttachment())
+ {
+ if (!sRenderAttachedLights)
+ {
+ continue;
+ }
+ }
+
+
+ LLVector4a center;
+ center.load3(drawablep->getPositionAgent().mV);
+ const F32* c = center.getF32ptr();
+ F32 s = volume->getLightRadius()*1.5f;
+
+ LLColor3 col = volume->getLightColor();
+
+ if (col.magVecSquared() < 0.001f)
+ {
+ continue;
+ }
+
+ if (s <= 0.001f)
+ {
+ continue;
+ }
+
+ LLVector4a sa;
+ sa.splat(s);
+ if (camera->AABBInFrustumNoFarClip(center, sa) == 0)
+ {
+ continue;
+ }
+
+ sVisibleLightCount++;
+
+ if (camera->getOrigin().mV[0] > c[0] + s + 0.2f ||
+ camera->getOrigin().mV[0] < c[0] - s - 0.2f ||
+ camera->getOrigin().mV[1] > c[1] + s + 0.2f ||
+ camera->getOrigin().mV[1] < c[1] - s - 0.2f ||
+ camera->getOrigin().mV[2] > c[2] + s + 0.2f ||
+ camera->getOrigin().mV[2] < c[2] - s - 0.2f)
+ { //draw box if camera is outside box
+ if (render_local)
+ {
+ if (volume->isLightSpotlight())
+ {
+ drawablep->getVOVolume()->updateSpotLightPriority();
+ spot_lights.push_back(drawablep);
+ continue;
+ }
+
+ /*col.mV[0] = powf(col.mV[0], 2.2f);
+ col.mV[1] = powf(col.mV[1], 2.2f);
+ col.mV[2] = powf(col.mV[2], 2.2f);*/
+
+ LLFastTimer ftm(FTM_LOCAL_LIGHTS);
+ gDeferredLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, c);
+ gDeferredLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s);
+ gDeferredLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV);
+ gDeferredLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, volume->getLightFalloff()*0.5f);
+ gGL.syncMatrices();
+
+ mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, center));
+ stop_glerror();
+ }
+ }
+ else
+ {
+ if (volume->isLightSpotlight())
+ {
+ drawablep->getVOVolume()->updateSpotLightPriority();
+ fullscreen_spot_lights.push_back(drawablep);
+ continue;
+ }
+
+ glh::vec3f tc(c);
+ mat.mult_matrix_vec(tc);
+
+ fullscreen_lights.push_back(LLVector4(tc.v[0], tc.v[1], tc.v[2], s));
+ light_colors.push_back(LLVector4(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f));
+ }
+ }
+ unbindDeferredShader(gDeferredLightProgram);
+ }
+
+ if (!spot_lights.empty())
+ {
+ LLGLDepthTest depth(GL_TRUE, GL_FALSE);
+ bindDeferredShader(gDeferredSpotLightProgram);
+
+ mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+
+ gDeferredSpotLightProgram.enableTexture(LLShaderMgr::DEFERRED_PROJECTION);
+
+ for (LLDrawable::drawable_list_t::iterator iter = spot_lights.begin(); iter != spot_lights.end(); ++iter)
+ {
+ LLFastTimer ftm(FTM_PROJECTORS);
+ LLDrawable* drawablep = *iter;
+
+ LLVOVolume* volume = drawablep->getVOVolume();
+
+ LLVector4a center;
+ center.load3(drawablep->getPositionAgent().mV);
+ const F32* c = center.getF32ptr();
+ F32 s = volume->getLightRadius()*1.5f;
+
+ sVisibleLightCount++;
+
+ setupSpotLight(gDeferredSpotLightProgram, drawablep);
+
+ LLColor3 col = volume->getLightColor();
+ /*col.mV[0] = powf(col.mV[0], 2.2f);
+ col.mV[1] = powf(col.mV[1], 2.2f);
+ col.mV[2] = powf(col.mV[2], 2.2f);*/
+
+ gDeferredSpotLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, c);
+ gDeferredSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s);
+ gDeferredSpotLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV);
+ gDeferredSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, volume->getLightFalloff()*0.5f);
+ gGL.syncMatrices();
+
+ mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, center));
+ }
+ gDeferredSpotLightProgram.disableTexture(LLShaderMgr::DEFERRED_PROJECTION);
+ unbindDeferredShader(gDeferredSpotLightProgram);
+ }
+
+ //reset mDeferredVB to fullscreen triangle
+ mDeferredVB->getVertexStrider(vert);
+ vert[0].set(-1,1,0);
+ vert[1].set(-1,-3,0);
+ vert[2].set(3,1,0);
+
+ {
+ LLGLDepthTest depth(GL_FALSE);
+
+ //full screen blit
+ gGL.pushMatrix();
+ gGL.loadIdentity();
+ gGL.matrixMode(LLRender::MM_PROJECTION);
+ gGL.pushMatrix();
+ gGL.loadIdentity();
+
+ U32 count = 0;
+
+ const U32 max_count = LL_DEFERRED_MULTI_LIGHT_COUNT;
+ LLVector4 light[max_count];
+ LLVector4 col[max_count];
+
+ F32 far_z = 0.f;
+
+ while (!fullscreen_lights.empty())
+ {
+ LLFastTimer ftm(FTM_FULLSCREEN_LIGHTS);
+ light[count] = fullscreen_lights.front();
+ fullscreen_lights.pop_front();
+ col[count] = light_colors.front();
+ light_colors.pop_front();
+
+ /*col[count].mV[0] = powf(col[count].mV[0], 2.2f);
+ col[count].mV[1] = powf(col[count].mV[1], 2.2f);
+ col[count].mV[2] = powf(col[count].mV[2], 2.2f);*/
+
+ far_z = llmin(light[count].mV[2]-light[count].mV[3], far_z);
+ //col[count] = pow4fsrgb(col[count], 2.2f);
+ count++;
+ if (count == max_count || fullscreen_lights.empty())
+ {
+ U32 idx = count-1;
+ bindDeferredShader(gDeferredMultiLightProgram[idx]);
+ gDeferredMultiLightProgram[idx].uniform1i(LLShaderMgr::MULTI_LIGHT_COUNT, count);
+ gDeferredMultiLightProgram[idx].uniform4fv(LLShaderMgr::MULTI_LIGHT, count, (GLfloat*) light);
+ gDeferredMultiLightProgram[idx].uniform4fv(LLShaderMgr::MULTI_LIGHT_COL, count, (GLfloat*) col);
+ gDeferredMultiLightProgram[idx].uniform1f(LLShaderMgr::MULTI_LIGHT_FAR_Z, far_z);
+ far_z = 0.f;
+ count = 0;
+ mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+ mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+ }
+ }
+
+ unbindDeferredShader(gDeferredMultiLightProgram[0]);
+
+ bindDeferredShader(gDeferredMultiSpotLightProgram);
+
+ gDeferredMultiSpotLightProgram.enableTexture(LLShaderMgr::DEFERRED_PROJECTION);
+
+ mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+
+ for (LLDrawable::drawable_list_t::iterator iter = fullscreen_spot_lights.begin(); iter != fullscreen_spot_lights.end(); ++iter)
+ {
+ LLFastTimer ftm(FTM_PROJECTORS);
+ LLDrawable* drawablep = *iter;
+
+ LLVOVolume* volume = drawablep->getVOVolume();
+
+ LLVector3 center = drawablep->getPositionAgent();
+ F32* c = center.mV;
+ F32 s = volume->getLightRadius()*1.5f;
+
+ sVisibleLightCount++;
+
+ glh::vec3f tc(c);
+ mat.mult_matrix_vec(tc);
+
+ setupSpotLight(gDeferredMultiSpotLightProgram, drawablep);
+
+ LLColor3 col = volume->getLightColor();
+
+ /*col.mV[0] = powf(col.mV[0], 2.2f);
+ col.mV[1] = powf(col.mV[1], 2.2f);
+ col.mV[2] = powf(col.mV[2], 2.2f);*/
+
+ gDeferredMultiSpotLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, tc.v);
+ gDeferredMultiSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s);
+ gDeferredMultiSpotLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV);
+ gDeferredMultiSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, volume->getLightFalloff()*0.5f);
+ mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+ }
+
+ gDeferredMultiSpotLightProgram.disableTexture(LLShaderMgr::DEFERRED_PROJECTION);
+ unbindDeferredShader(gDeferredMultiSpotLightProgram);
+
+ gGL.popMatrix();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.popMatrix();
+ }
+ }
+
+ gGL.setColorMask(true, true);
+ }
+
+ /*target->flush();
+
+ //gamma correct lighting
+ gGL.matrixMode(LLRender::MM_PROJECTION);
+ gGL.pushMatrix();
+ gGL.loadIdentity();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.pushMatrix();
+ gGL.loadIdentity();
+
+ {
+ LLGLDepthTest depth(GL_FALSE, GL_FALSE);
+
+ LLVector2 tc1(0,0);
+ LLVector2 tc2((F32) target->getWidth()*2,
+ (F32) target->getHeight()*2);
+
+ target->bindTarget();
+ // Apply gamma correction to the frame here.
+ gDeferredPostGammaCorrectProgram.bind();
+ //mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+ S32 channel = 0;
+ channel = gDeferredPostGammaCorrectProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, target->getUsage());
+ if (channel > -1)
+ {
+ target->bindTexture(0,channel);
+ gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
+ }
+
+ gDeferredPostGammaCorrectProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, target->getWidth(), target->getHeight());
+
+ F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma");
+
+ gDeferredPostGammaCorrectProgram.uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f));
+
+ gGL.begin(LLRender::TRIANGLE_STRIP);
+ gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
+ gGL.vertex2f(-1,-1);
+
+ gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
+ gGL.vertex2f(-1,3);
+
+ gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
+ gGL.vertex2f(3,-1);
+
+ gGL.end();
+
+ gGL.getTexUnit(channel)->unbind(target->getUsage());
+ gDeferredPostGammaCorrectProgram.unbind();
+ target->flush();
+ }
+
+ gGL.matrixMode(LLRender::MM_PROJECTION);
+ gGL.popMatrix();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.popMatrix();
+
+ target->bindTarget();*/
+
+ { //render non-deferred geometry (alpha, fullbright, glow)
+ LLGLDisable blend(GL_BLEND);
+ LLGLDisable stencil(GL_STENCIL_TEST);
+
+ pushRenderTypeMask();
+ andRenderTypeMask(LLPipeline::RENDER_TYPE_ALPHA,
+ LLPipeline::RENDER_TYPE_FULLBRIGHT,
+ LLPipeline::RENDER_TYPE_VOLUME,
+ LLPipeline::RENDER_TYPE_GLOW,
+ LLPipeline::RENDER_TYPE_BUMP,
+ LLPipeline::RENDER_TYPE_PASS_SIMPLE,
+ LLPipeline::RENDER_TYPE_PASS_ALPHA,
+ LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK,
+ LLPipeline::RENDER_TYPE_PASS_BUMP,
+ LLPipeline::RENDER_TYPE_PASS_POST_BUMP,
+ LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT,
+ LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK,
+ LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY,
+ LLPipeline::RENDER_TYPE_PASS_GLOW,
+ LLPipeline::RENDER_TYPE_PASS_GRASS,
+ LLPipeline::RENDER_TYPE_PASS_SHINY,
+ LLPipeline::RENDER_TYPE_PASS_INVISIBLE,
+ LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY,
+ LLPipeline::RENDER_TYPE_AVATAR,
+ LLPipeline::RENDER_TYPE_ALPHA_MASK,
+ LLPipeline::RENDER_TYPE_FULLBRIGHT_ALPHA_MASK,
+ END_RENDER_TYPES);
+
+ renderGeomPostDeferred(*LLViewerCamera::getInstance());
+ popRenderTypeMask();
+ }
+
+ //target->flush();
+}
+
void LLPipeline::setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep)
{
//construct frustum
@@ -7936,9 +9681,9 @@ void LLPipeline::unbindDeferredShader(LLGLSLShader &shader)
for (U32 i = 0; i < 4; i++)
{
- if (shader.disableTexture(LLShaderMgr::DEFERRED_SHADOW0+i, LLTexUnit::TT_RECT_TEXTURE) > -1)
+ if (shader.disableTexture(LLShaderMgr::DEFERRED_SHADOW0+i) > -1)
{
- glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);
}
}
@@ -8030,6 +9775,12 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
water_clip = 1;
}
+ bool materials_in_water = false;
+
+#if MATERIALS_IN_REFLECTIONS
+ materials_in_water = gSavedSettings.getS32("RenderWaterMaterials");
+#endif
+
if (!LLViewerCamera::getInstance()->cameraUnderWater())
{ //generate planar reflection map
@@ -8038,7 +9789,9 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
LLPipeline::sUseOcclusion = 0;
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
glClearColor(0,0,0,0);
+
mWaterRef.bindTarget();
+
LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WATER0;
gGL.setColorMask(true, true);
mWaterRef.clear();
@@ -8087,11 +9840,27 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
updateCull(camera, result);
stateSort(camera, result);
+ if (LLPipeline::sRenderDeferred && materials_in_water)
+ {
+ mWaterRef.flush();
+
+ gPipeline.grabReferences(result);
+ gPipeline.mDeferredScreen.bindTarget();
+ gGL.setColorMask(true, true);
+ glClearColor(0,0,0,0);
+ gPipeline.mDeferredScreen.clear();
+
+ renderGeomDeferred(camera);
+ }
+ else
+ {
renderGeom(camera, TRUE);
+ }
gPipeline.popRenderTypeMask();
}
+ gGL.setColorMask(true, false);
gPipeline.pushRenderTypeMask();
clearRenderTypeMask(LLPipeline::RENDER_TYPE_WATER,
@@ -8129,9 +9898,23 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
{
gPipeline.grabReferences(ref_result);
LLGLUserClipPlane clip_plane(plane, mat, projection);
+
+ if (LLPipeline::sRenderDeferred && materials_in_water)
+ {
+ renderGeomDeferred(camera);
+ }
+ else
+ {
renderGeom(camera);
}
}
+ }
+
+ if (LLPipeline::sRenderDeferred && materials_in_water)
+ {
+ gPipeline.mDeferredScreen.flush();
+ renderDeferredLightingToRT(&mWaterRef);
+ }
gPipeline.popRenderTypeMask();
}
@@ -8167,10 +9950,12 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
LLViewerCamera::updateFrustumPlanes(camera);
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
LLColor4& col = LLDrawPoolWater::sWaterFogColor;
glClearColor(col.mV[0], col.mV[1], col.mV[2], 0.f);
mWaterDis.bindTarget();
LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WATER1;
+
mWaterDis.getViewport(gGLViewport);
if (!LLPipeline::sUnderWaterRender || LLDrawPoolWater::sNeedsReflectionUpdate)
@@ -8186,18 +9971,39 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
gGL.setColorMask(true, true);
mWaterDis.clear();
+
+
gGL.setColorMask(true, false);
+
+ if (LLPipeline::sRenderDeferred && materials_in_water)
+ {
+ mWaterDis.flush();
+ gPipeline.mDeferredScreen.bindTarget();
+ gGL.setColorMask(true, true);
+ glClearColor(0,0,0,0);
+ gPipeline.mDeferredScreen.clear();
+ gPipeline.grabReferences(result);
+ renderGeomDeferred(camera);
+ }
+ else
+ {
renderGeom(camera);
+ }
+
+ if (LLPipeline::sRenderDeferred && materials_in_water)
+ {
+ gPipeline.mDeferredScreen.flush();
+ renderDeferredLightingToRT(&mWaterDis);
+ }
}
- LLPipeline::sUnderWaterRender = FALSE;
mWaterDis.flush();
+ LLPipeline::sUnderWaterRender = FALSE;
+
}
last_update = LLDrawPoolWater::sNeedsReflectionUpdate && LLDrawPoolWater::sNeedsDistortionUpdate;
- LLRenderTarget::unbindTarget();
-
LLPipeline::sReflectionRender = FALSE;
if (!LLRenderTarget::sUseFBO)
@@ -8293,7 +10099,7 @@ static LLFastTimer::DeclareTimer FTM_SHADOW_RENDER("Render Shadows");
static LLFastTimer::DeclareTimer FTM_SHADOW_ALPHA("Alpha Shadow");
static LLFastTimer::DeclareTimer FTM_SHADOW_SIMPLE("Simple Shadow");
-void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera& shadow_cam, LLCullResult &result, BOOL use_shader, BOOL use_occlusion)
+void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera& shadow_cam, LLCullResult &result, BOOL use_shader, BOOL use_occlusion, U32 target_width)
{
LLFastTimer t(FTM_SHADOW_RENDER);
@@ -8310,19 +10116,36 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
LLRenderPass::PASS_FULLBRIGHT,
LLRenderPass::PASS_SHINY,
LLRenderPass::PASS_BUMP,
- LLRenderPass::PASS_FULLBRIGHT_SHINY
+ LLRenderPass::PASS_FULLBRIGHT_SHINY ,
+ LLRenderPass::PASS_MATERIAL,
+ LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE,
+ LLRenderPass::PASS_SPECMAP,
+ LLRenderPass::PASS_SPECMAP_EMISSIVE,
+ LLRenderPass::PASS_NORMMAP,
+ LLRenderPass::PASS_NORMMAP_EMISSIVE,
+ LLRenderPass::PASS_NORMSPEC,
+ LLRenderPass::PASS_NORMSPEC_EMISSIVE,
};
LLGLEnable cull(GL_CULL_FACE);
+ //enable depth clamping if available
+ LLGLEnable depth_clamp(gGLManager.mHasDepthClamp ? GL_DEPTH_CLAMP : 0);
+
if (use_shader)
{
- gDeferredShadowProgram.bind();
+ gDeferredShadowCubeProgram.bind();
}
+ LLRenderTarget& occlusion_target = mShadowOcclusion[LLViewerCamera::sCurCameraID-1];
+
+ occlusion_target.bindTarget();
updateCull(shadow_cam, result);
+ occlusion_target.flush();
+
stateSort(shadow_cam, result);
+
//generate shadow map
gGL.matrixMode(LLRender::MM_PROJECTION);
gGL.pushMatrix();
@@ -8334,17 +10157,10 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
stop_glerror();
gGLLastMatrix = NULL;
- {
- //LLGLDepthTest depth(GL_TRUE);
- //glClear(GL_DEPTH_BUFFER_BIT);
- }
-
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
stop_glerror();
- //glCullFace(GL_FRONT);
-
LLVertexBuffer::unbind();
{
@@ -8352,11 +10168,16 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
{ //occlusion program is general purpose depth-only no-textures
gOcclusionProgram.bind();
}
+ else
+ {
+ gDeferredShadowProgram.bind();
+ }
gGL.diffuseColor4f(1,1,1,1);
gGL.setColorMask(false, false);
LLFastTimer ftm(FTM_SHADOW_SIMPLE);
+
gGL.getTexUnit(0)->disable();
for (U32 i = 0; i < sizeof(types)/sizeof(U32); ++i)
{
@@ -8383,27 +10204,39 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
{
LLFastTimer ftm(FTM_SHADOW_ALPHA);
gDeferredShadowAlphaMaskProgram.bind();
- gDeferredShadowAlphaMaskProgram.setMinimumAlpha(0.598f);
-
+ gDeferredShadowAlphaMaskProgram.uniform1f(LLShaderMgr::DEFERRED_SHADOW_TARGET_WIDTH, (float)target_width);
+
U32 mask = LLVertexBuffer::MAP_VERTEX |
LLVertexBuffer::MAP_TEXCOORD0 |
LLVertexBuffer::MAP_COLOR |
LLVertexBuffer::MAP_TEXTURE_INDEX;
- renderObjects(LLRenderPass::PASS_ALPHA_MASK, mask, TRUE, TRUE);
- renderObjects(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, mask, TRUE, TRUE);
+ renderMaskedObjects(LLRenderPass::PASS_ALPHA_MASK, mask, TRUE, TRUE);
+ renderMaskedObjects(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, mask, TRUE, TRUE);
+ gDeferredShadowAlphaMaskProgram.setMinimumAlpha(0.598f);
renderObjects(LLRenderPass::PASS_ALPHA, mask, TRUE, TRUE);
+
+ mask = mask & ~LLVertexBuffer::MAP_TEXTURE_INDEX;
+
gDeferredTreeShadowProgram.bind();
+ renderMaskedObjects(LLRenderPass::PASS_NORMSPEC_MASK, mask);
+ renderMaskedObjects(LLRenderPass::PASS_MATERIAL_ALPHA_MASK, mask);
+ renderMaskedObjects(LLRenderPass::PASS_SPECMAP_MASK, mask);
+ renderMaskedObjects(LLRenderPass::PASS_NORMMAP_MASK, mask);
+
gDeferredTreeShadowProgram.setMinimumAlpha(0.598f);
renderObjects(LLRenderPass::PASS_GRASS, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, TRUE);
}
//glCullFace(GL_BACK);
- gDeferredShadowProgram.bind();
+ gDeferredShadowCubeProgram.bind();
gGLLastMatrix = NULL;
gGL.loadMatrix(gGLModelView);
- doOcclusion(shadow_cam);
+
+ LLRenderTarget& occlusion_source = mShadow[LLViewerCamera::sCurCameraID-1];
+
+ doOcclusion(shadow_cam, occlusion_source, occlusion_target);
if (use_shader)
{
@@ -8456,7 +10289,7 @@ BOOL LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector
pp.push_back(LLVector3(max.mV[0], max.mV[1], max.mV[2]));
//add corners of camera frustum
- for (U32 i = 0; i < 8; i++)
+ for (U32 i = 0; i < LLCamera::AGENT_FRUSTRUM_NUM; i++)
{
pp.push_back(camera.mAgentFrustum[i]);
}
@@ -8483,7 +10316,7 @@ BOOL LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector
for (U32 i = 0; i < 12; i++)
{ //for each line segment in bounding box
- for (U32 j = 0; j < 6; j++)
+ for (U32 j = 0; j < LLCamera::AGENT_PLANE_NO_USER_CLIP_NUM; j++)
{ //for each plane in camera frustum
const LLPlane& cp = camera.getAgentPlane(j);
const LLVector3& v1 = pp[bs[i*2+0]];
@@ -8525,9 +10358,6 @@ BOOL LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector
3,7
};
- LLVector3 center = (max+min)*0.5f;
- LLVector3 size = (max-min)*0.5f;
-
for (U32 i = 0; i < 12; i++)
{
for (U32 j = 0; j < 6; ++j)
@@ -8572,19 +10402,19 @@ BOOL LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector
}
}
- for (U32 j = 0; j < 6; ++j)
+ for (U32 j = 0; j < LLCamera::AGENT_PLANE_NO_USER_CLIP_NUM; ++j)
{
const LLPlane& cp = camera.getAgentPlane(j);
F32 dist = cp.dist(pp[i]);
if (dist > 0.05f) //point is above some plane, not contained
- {
+ {
found = false;
break;
- }
- }
+ }
+ }
- if (found)
- {
+ if (found)
+ {
fp.push_back(pp[i]);
}
}
@@ -8675,6 +10505,8 @@ void LLPipeline::generateHighlight(LLCamera& camera)
}
+static LLFastTimer::DeclareTimer FTM_GEN_SUN_SHADOW("Gen Sun Shadow");
+
void LLPipeline::generateSunShadow(LLCamera& camera)
{
if (!sRenderDeferred || RenderShadowDetail <= 0)
@@ -8682,6 +10514,8 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
return;
}
+ LLFastTimer t(FTM_GEN_SUN_SHADOW);
+
BOOL skip_avatar_update = FALSE;
if (!isAgentAvatarValid() || gAgentCamera.getCameraAnimating() || gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK || !LLVOAvatar::sVisibleInFirstPerson)
{
@@ -8723,6 +10557,22 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT,
LLPipeline::RENDER_TYPE_PASS_SHINY,
LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY,
+ LLPipeline::RENDER_TYPE_PASS_MATERIAL,
+ LLPipeline::RENDER_TYPE_PASS_MATERIAL_ALPHA,
+ LLPipeline::RENDER_TYPE_PASS_MATERIAL_ALPHA_MASK,
+ LLPipeline::RENDER_TYPE_PASS_MATERIAL_ALPHA_EMISSIVE,
+ LLPipeline::RENDER_TYPE_PASS_SPECMAP,
+ LLPipeline::RENDER_TYPE_PASS_SPECMAP_BLEND,
+ LLPipeline::RENDER_TYPE_PASS_SPECMAP_MASK,
+ LLPipeline::RENDER_TYPE_PASS_SPECMAP_EMISSIVE,
+ LLPipeline::RENDER_TYPE_PASS_NORMMAP,
+ LLPipeline::RENDER_TYPE_PASS_NORMMAP_BLEND,
+ LLPipeline::RENDER_TYPE_PASS_NORMMAP_MASK,
+ LLPipeline::RENDER_TYPE_PASS_NORMMAP_EMISSIVE,
+ LLPipeline::RENDER_TYPE_PASS_NORMSPEC,
+ LLPipeline::RENDER_TYPE_PASS_NORMSPEC_BLEND,
+ LLPipeline::RENDER_TYPE_PASS_NORMSPEC_MASK,
+ LLPipeline::RENDER_TYPE_PASS_NORMSPEC_EMISSIVE,
END_RENDER_TYPES);
gGL.setColorMask(false, false);
@@ -8749,7 +10599,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
mSunOrthoClipPlanes = LLVector4(clip, clip.mV[2]*clip.mV[2]/clip.mV[1]);
//currently used for amount to extrude frusta corners for constructing shadow frusta
- LLVector3 n = RenderShadowNearDist;
+ //LLVector3 n = RenderShadowNearDist;
//F32 nearDist[] = { n.mV[0], n.mV[1], n.mV[2], n.mV[2] };
//put together a universal "near clip" plane for shadow frusta
@@ -9237,11 +11087,12 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
mShadow[j].getViewport(gGLViewport);
mShadow[j].clear();
+ U32 target_width = mShadow[j].getWidth();
+
{
static LLCullResult result[4];
- //LLGLEnable enable(GL_DEPTH_CLAMP_NV);
- renderShadow(view[j], proj[j], shadow_cam, result[j], TRUE);
+ renderShadow(view[j], proj[j], shadow_cam, result[j], TRUE, TRUE, target_width);
}
mShadow[j].flush();
@@ -9380,11 +11231,13 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
mShadow[i+4].getViewport(gGLViewport);
mShadow[i+4].clear();
+ U32 target_width = mShadow[i+4].getWidth();
+
static LLCullResult result[2];
LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_SHADOW0+i+4;
- renderShadow(view[i+4], proj[i+4], shadow_cam, result[i], FALSE, FALSE);
+ renderShadow(view[i+4], proj[i+4], shadow_cam, result[i], FALSE, FALSE, target_width);
mShadow[i+4].flush();
}
@@ -9427,7 +11280,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
void LLPipeline::renderGroups(LLRenderPass* pass, U32 type, U32 mask, BOOL texture)
{
- for (LLCullResult::sg_list_t::iterator i = sCull->beginVisibleGroups(); i != sCull->endVisibleGroups(); ++i)
+ for (LLCullResult::sg_iterator i = sCull->beginVisibleGroups(); i != sCull->endVisibleGroups(); ++i)
{
LLSpatialGroup* group = *i;
if (!group->isDead() &&
@@ -9440,9 +11293,14 @@ void LLPipeline::renderGroups(LLRenderPass* pass, U32 type, U32 mask, BOOL textu
}
}
+static LLFastTimer::DeclareTimer FTM_IMPOSTOR_MARK_VISIBLE("Impostor Mark Visible");
+static LLFastTimer::DeclareTimer FTM_IMPOSTOR_SETUP("Impostor Setup");
+static LLFastTimer::DeclareTimer FTM_IMPOSTOR_BACKGROUND("Impostor Background");
+static LLFastTimer::DeclareTimer FTM_IMPOSTOR_ALLOCATE("Impostor Allocate");
+static LLFastTimer::DeclareTimer FTM_IMPOSTOR_RESIZE("Impostor Resize");
+
void LLPipeline::generateImpostor(LLVOAvatar* avatar)
{
- LLMemType mt_gi(LLMemType::MTYPE_PIPELINE_GENERATE_IMPOSTOR);
LLGLState::checkStates();
LLGLState::checkTextureChannels();
LLGLState::checkClientArrays();
@@ -9458,144 +11316,194 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
assertInitialized();
- bool muted = avatar->isVisuallyMuted();
+ bool visually_muted = avatar->isVisuallyMuted();
pushRenderTypeMask();
- if (muted)
+ if (visually_muted)
{
andRenderTypeMask(LLPipeline::RENDER_TYPE_AVATAR, END_RENDER_TYPES);
}
else
{
- andRenderTypeMask(LLPipeline::RENDER_TYPE_VOLUME,
- LLPipeline::RENDER_TYPE_AVATAR,
+ andRenderTypeMask(LLPipeline::RENDER_TYPE_ALPHA,
+ LLPipeline::RENDER_TYPE_FULLBRIGHT,
+ LLPipeline::RENDER_TYPE_VOLUME,
+ LLPipeline::RENDER_TYPE_GLOW,
LLPipeline::RENDER_TYPE_BUMP,
- LLPipeline::RENDER_TYPE_GRASS,
- LLPipeline::RENDER_TYPE_SIMPLE,
- LLPipeline::RENDER_TYPE_FULLBRIGHT,
- LLPipeline::RENDER_TYPE_ALPHA,
- LLPipeline::RENDER_TYPE_INVISIBLE,
LLPipeline::RENDER_TYPE_PASS_SIMPLE,
LLPipeline::RENDER_TYPE_PASS_ALPHA,
LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK,
+ LLPipeline::RENDER_TYPE_PASS_BUMP,
+ LLPipeline::RENDER_TYPE_PASS_POST_BUMP,
LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT,
LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK,
LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY,
+ LLPipeline::RENDER_TYPE_PASS_GLOW,
+ LLPipeline::RENDER_TYPE_PASS_GRASS,
LLPipeline::RENDER_TYPE_PASS_SHINY,
LLPipeline::RENDER_TYPE_PASS_INVISIBLE,
LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY,
+ LLPipeline::RENDER_TYPE_AVATAR,
+ LLPipeline::RENDER_TYPE_ALPHA_MASK,
+ LLPipeline::RENDER_TYPE_FULLBRIGHT_ALPHA_MASK,
+ LLPipeline::RENDER_TYPE_INVISIBLE,
+ LLPipeline::RENDER_TYPE_SIMPLE,
END_RENDER_TYPES);
}
S32 occlusion = sUseOcclusion;
sUseOcclusion = 0;
+
sReflectionRender = sRenderDeferred ? FALSE : TRUE;
+
sShadowRender = TRUE;
sImpostorRender = TRUE;
LLViewerCamera* viewer_camera = LLViewerCamera::getInstance();
- markVisible(avatar->mDrawable, *viewer_camera);
- LLVOAvatar::sUseImpostors = FALSE;
- LLVOAvatar::attachment_map_t::iterator iter;
- for (iter = avatar->mAttachmentPoints.begin();
- iter != avatar->mAttachmentPoints.end();
- ++iter)
{
- LLViewerJointAttachment *attachment = iter->second;
- for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
- attachment_iter != attachment->mAttachedObjects.end();
- ++attachment_iter)
+ LLFastTimer t(FTM_IMPOSTOR_MARK_VISIBLE);
+ markVisible(avatar->mDrawable, *viewer_camera);
+ LLVOAvatar::sUseImpostors = FALSE;
+
+ LLVOAvatar::attachment_map_t::iterator iter;
+ for (iter = avatar->mAttachmentPoints.begin();
+ iter != avatar->mAttachmentPoints.end();
+ ++iter)
{
- if (LLViewerObject* attached_object = (*attachment_iter))
+ LLViewerJointAttachment *attachment = iter->second;
+ for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
+ attachment_iter != attachment->mAttachedObjects.end();
+ ++attachment_iter)
{
- markVisible(attached_object->mDrawable->getSpatialBridge(), *viewer_camera);
+ if (LLViewerObject* attached_object = (*attachment_iter))
+ {
+ markVisible(attached_object->mDrawable->getSpatialBridge(), *viewer_camera);
+ }
}
}
}
stateSort(*LLViewerCamera::getInstance(), result);
- const LLVector4a* ext = avatar->mDrawable->getSpatialExtents();
- LLVector3 pos(avatar->getRenderPosition()+avatar->getImpostorOffset());
-
LLCamera camera = *viewer_camera;
-
- camera.lookAt(viewer_camera->getOrigin(), pos, viewer_camera->getUpAxis());
-
LLVector2 tdim;
+ U32 resY = 0;
+ U32 resX = 0;
+ {
+ LLFastTimer t(FTM_IMPOSTOR_SETUP);
+ const LLVector4a* ext = avatar->mDrawable->getSpatialExtents();
+ LLVector3 pos(avatar->getRenderPosition()+avatar->getImpostorOffset());
- LLVector4a half_height;
- half_height.setSub(ext[1], ext[0]);
- half_height.mul(0.5f);
+ camera.lookAt(viewer_camera->getOrigin(), pos, viewer_camera->getUpAxis());
+
+ LLVector4a half_height;
+ half_height.setSub(ext[1], ext[0]);
+ half_height.mul(0.5f);
- LLVector4a left;
- left.load3(camera.getLeftAxis().mV);
- left.mul(left);
- left.normalize3fast();
+ LLVector4a left;
+ left.load3(camera.getLeftAxis().mV);
+ left.mul(left);
+ llassert(left.dot3(left).getF32() > F_APPROXIMATELY_ZERO);
+ left.normalize3fast();
- LLVector4a up;
- up.load3(camera.getUpAxis().mV);
- up.mul(up);
- up.normalize3fast();
+ LLVector4a up;
+ up.load3(camera.getUpAxis().mV);
+ up.mul(up);
+ llassert(up.dot3(up).getF32() > F_APPROXIMATELY_ZERO);
+ up.normalize3fast();
- tdim.mV[0] = fabsf(half_height.dot3(left).getF32());
- tdim.mV[1] = fabsf(half_height.dot3(up).getF32());
+ tdim.mV[0] = fabsf(half_height.dot3(left).getF32());
+ tdim.mV[1] = fabsf(half_height.dot3(up).getF32());
- gGL.matrixMode(LLRender::MM_PROJECTION);
- gGL.pushMatrix();
+ gGL.matrixMode(LLRender::MM_PROJECTION);
+ gGL.pushMatrix();
- F32 distance = (pos-camera.getOrigin()).length();
- F32 fov = atanf(tdim.mV[1]/distance)*2.f*RAD_TO_DEG;
- F32 aspect = tdim.mV[0]/tdim.mV[1];
- glh::matrix4f persp = gl_perspective(fov, aspect, 1.f, 256.f);
- glh_set_current_projection(persp);
- gGL.loadMatrix(persp.m);
+ F32 distance = (pos-camera.getOrigin()).length();
+ F32 fov = atanf(tdim.mV[1]/distance)*2.f*RAD_TO_DEG;
+ F32 aspect = tdim.mV[0]/tdim.mV[1];
+ glh::matrix4f persp = gl_perspective(fov, aspect, 1.f, 256.f);
+ glh_set_current_projection(persp);
+ gGL.loadMatrix(persp.m);
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.pushMatrix();
- glh::matrix4f mat;
- camera.getOpenGLTransform(mat.m);
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.pushMatrix();
+ glh::matrix4f mat;
+ camera.getOpenGLTransform(mat.m);
- mat = glh::matrix4f((GLfloat*) OGL_TO_CFR_ROTATION) * mat;
+ mat = glh::matrix4f((GLfloat*) OGL_TO_CFR_ROTATION) * mat;
- gGL.loadMatrix(mat.m);
- glh_set_current_modelview(mat);
+ gGL.loadMatrix(mat.m);
+ glh_set_current_modelview(mat);
- glClearColor(0.0f,0.0f,0.0f,0.0f);
- gGL.setColorMask(true, true);
+ glClearColor(0.0f,0.0f,0.0f,0.0f);
+ gGL.setColorMask(true, true);
- // get the number of pixels per angle
- F32 pa = gViewerWindow->getWindowHeightRaw() / (RAD_TO_DEG * viewer_camera->getView());
+ // get the number of pixels per angle
+ F32 pa = gViewerWindow->getWindowHeightRaw() / (RAD_TO_DEG * viewer_camera->getView());
- //get resolution based on angle width and height of impostor (double desired resolution to prevent aliasing)
- U32 resY = llmin(nhpo2((U32) (fov*pa)), (U32) 512);
- U32 resX = llmin(nhpo2((U32) (atanf(tdim.mV[0]/distance)*2.f*RAD_TO_DEG*pa)), (U32) 512);
+ //get resolution based on angle width and height of impostor (double desired resolution to prevent aliasing)
+ resY = llmin(nhpo2((U32) (fov*pa)), (U32) 512);
+ resX = llmin(nhpo2((U32) (atanf(tdim.mV[0]/distance)*2.f*RAD_TO_DEG*pa)), (U32) 512);
- if (!avatar->mImpostor.isComplete() || resX != avatar->mImpostor.getWidth() ||
- resY != avatar->mImpostor.getHeight())
- {
- avatar->mImpostor.allocate(resX,resY,GL_RGBA,TRUE,FALSE);
+ if (!avatar->mImpostor.isComplete())
+ {
+ LLFastTimer t(FTM_IMPOSTOR_ALLOCATE);
+
+
+ if (LLPipeline::sRenderDeferred)
+ {
+ avatar->mImpostor.allocate(resX,resY,GL_SRGB8_ALPHA8,TRUE,FALSE);
+ addDeferredAttachments(avatar->mImpostor);
+ }
+ else
+ {
+ avatar->mImpostor.allocate(resX,resY,GL_RGBA,TRUE,FALSE);
+ }
- if (LLPipeline::sRenderDeferred)
+ gGL.getTexUnit(0)->bind(&avatar->mImpostor);
+ gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ }
+ else if(resX != avatar->mImpostor.getWidth() || resY != avatar->mImpostor.getHeight())
{
- addDeferredAttachments(avatar->mImpostor);
+ LLFastTimer t(FTM_IMPOSTOR_RESIZE);
+ avatar->mImpostor.resize(resX,resY);
}
-
- gGL.getTexUnit(0)->bind(&avatar->mImpostor);
- gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+ avatar->mImpostor.bindTarget();
}
- avatar->mImpostor.bindTarget();
+ F32 old_alpha = LLDrawPoolAvatar::sMinimumAlpha;
+
+ if (visually_muted)
+ { //disable alpha masking for muted avatars (get whole skin silhouette)
+ LLDrawPoolAvatar::sMinimumAlpha = 0.f;
+ }
if (LLPipeline::sRenderDeferred)
{
avatar->mImpostor.clear();
renderGeomDeferred(camera);
+
+ renderGeomPostDeferred(camera);
+
+ // Shameless hack time: render it all again,
+ // this time writing the depth
+ // values we need to generate the alpha mask below
+ // while preserving the alpha-sorted color rendering
+ // from the previous pass
+ //
+ sImpostorRenderAlphaDepthPass = true;
+ // depth-only here...
+ //
+ gGL.setColorMask(false,false);
renderGeomPostDeferred(camera);
+
+ sImpostorRenderAlphaDepthPass = false;
+
}
else
{
@@ -9603,9 +11511,28 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
glScissor(0, 0, resX, resY);
avatar->mImpostor.clear();
renderGeom(camera);
+
+ // Shameless hack time: render it all again,
+ // this time writing the depth
+ // values we need to generate the alpha mask below
+ // while preserving the alpha-sorted color rendering
+ // from the previous pass
+ //
+ sImpostorRenderAlphaDepthPass = true;
+
+ // depth-only here...
+ //
+ gGL.setColorMask(false,false);
+ renderGeom(camera);
+
+ sImpostorRenderAlphaDepthPass = false;
}
-
+
+ LLDrawPoolAvatar::sMinimumAlpha = old_alpha;
+
{ //create alpha mask based on depth buffer (grey out if muted)
+ LLFastTimer t(FTM_IMPOSTOR_BACKGROUND);
+
if (LLPipeline::sRenderDeferred)
{
GLuint buff = GL_COLOR_ATTACHMENT0;
@@ -9614,7 +11541,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
LLGLDisable blend(GL_BLEND);
- if (muted)
+ if (visually_muted)
{
gGL.setColorMask(true, true);
}
@@ -9639,10 +11566,20 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
if (LLGLSLShader::sNoFixedFunction)
{
- gUIProgram.bind();
+ gDebugProgram.bind();
}
- gGL.color4ub(64,64,64,255);
+
+ if (LLMuteList::getInstance()->isMuted(avatar->getID()))
+ { //grey muted avatar
+ gGL.diffuseColor4ub(64,64,64,255);
+ }
+ else
+ { // Visually muted avatar
+ gGL.diffuseColor4fv( avatar->getMutedAVColor().mV );
+ }
+
+ {
gGL.begin(LLRender::QUADS);
gGL.vertex3f(-1, -1, clip_plane);
gGL.vertex3f(1, -1, clip_plane);
@@ -9650,10 +11587,11 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
gGL.vertex3f(-1, 1, clip_plane);
gGL.end();
gGL.flush();
+ }
if (LLGLSLShader::sNoFixedFunction)
{
- gUIProgram.unbind();
+ gDebugProgram.unbind();
}
gGL.popMatrix();
@@ -9691,22 +11629,22 @@ BOOL LLPipeline::hasRenderBatches(const U32 type) const
return sCull->getRenderMapSize(type) > 0;
}
-LLCullResult::drawinfo_list_t::iterator LLPipeline::beginRenderMap(U32 type)
+LLCullResult::drawinfo_iterator LLPipeline::beginRenderMap(U32 type)
{
return sCull->beginRenderMap(type);
}
-LLCullResult::drawinfo_list_t::iterator LLPipeline::endRenderMap(U32 type)
+LLCullResult::drawinfo_iterator LLPipeline::endRenderMap(U32 type)
{
return sCull->endRenderMap(type);
}
-LLCullResult::sg_list_t::iterator LLPipeline::beginAlphaGroups()
+LLCullResult::sg_iterator LLPipeline::beginAlphaGroups()
{
return sCull->beginAlphaGroups();
}
-LLCullResult::sg_list_t::iterator LLPipeline::endAlphaGroups()
+LLCullResult::sg_iterator LLPipeline::endAlphaGroups()
{
return sCull->endAlphaGroups();
}
@@ -9831,9 +11769,162 @@ void LLPipeline::clearRenderTypeMask(U32 type, ...)
}
}
+void LLPipeline::setAllRenderTypes()
+{
+ for (U32 i = 0; i < NUM_RENDER_TYPES; ++i)
+ {
+ mRenderTypeEnabled[i] = TRUE;
+ }
+}
+
+void LLPipeline::clearAllRenderTypes()
+{
+ for (U32 i = 0; i < NUM_RENDER_TYPES; ++i)
+ {
+ mRenderTypeEnabled[i] = FALSE;
+ }
+}
+
void LLPipeline::addDebugBlip(const LLVector3& position, const LLColor4& color)
{
DebugBlip blip(position, color);
mDebugBlips.push_back(blip);
}
+void LLPipeline::hidePermanentObjects( std::vector<U32>& restoreList )
+{
+ //This method is used to hide any vo's from the object list that may have
+ //the permanent flag set.
+
+ U32 objCnt = gObjectList.getNumObjects();
+ for (U32 i = 0; i < objCnt; ++i)
+ {
+ LLViewerObject* pObject = gObjectList.getObject(i);
+ if ( pObject && pObject->flagObjectPermanent() )
+ {
+ LLDrawable *pDrawable = pObject->mDrawable;
+
+ if ( pDrawable )
+ {
+ restoreList.push_back( i );
+ hideDrawable( pDrawable );
+ }
+ }
+ }
+
+ skipRenderingOfTerrain( true );
+}
+
+void LLPipeline::restorePermanentObjects( const std::vector<U32>& restoreList )
+{
+ //This method is used to restore(unhide) any vo's from the object list that may have
+ //been hidden because their permanency flag was set.
+
+ std::vector<U32>::const_iterator itCurrent = restoreList.begin();
+ std::vector<U32>::const_iterator itEnd = restoreList.end();
+
+ U32 objCnt = gObjectList.getNumObjects();
+
+ while ( itCurrent != itEnd )
+ {
+ U32 index = *itCurrent;
+ LLViewerObject* pObject = NULL;
+ if ( index < objCnt )
+ {
+ pObject = gObjectList.getObject( index );
+ }
+ if ( pObject )
+ {
+ LLDrawable *pDrawable = pObject->mDrawable;
+ if ( pDrawable )
+ {
+ pDrawable->clearState( LLDrawable::FORCE_INVISIBLE );
+ unhideDrawable( pDrawable );
+ }
+ }
+ ++itCurrent;
+ }
+
+ skipRenderingOfTerrain( false );
+}
+
+void LLPipeline::skipRenderingOfTerrain( BOOL flag )
+{
+ pool_set_t::iterator iter = mPools.begin();
+ while ( iter != mPools.end() )
+ {
+ LLDrawPool* pPool = *iter;
+ U32 poolType = pPool->getType();
+ if ( hasRenderType( pPool->getType() ) && poolType == LLDrawPool::POOL_TERRAIN )
+ {
+ pPool->setSkipRenderFlag( flag );
+ }
+ ++iter;
+ }
+}
+
+void LLPipeline::hideObject( const LLUUID& id )
+{
+ LLViewerObject *pVO = gObjectList.findObject( id );
+
+ if ( pVO )
+ {
+ LLDrawable *pDrawable = pVO->mDrawable;
+
+ if ( pDrawable )
+ {
+ hideDrawable( pDrawable );
+ }
+ }
+}
+
+void LLPipeline::hideDrawable( LLDrawable *pDrawable )
+{
+ pDrawable->setState( LLDrawable::FORCE_INVISIBLE );
+ markRebuild( pDrawable, LLDrawable::REBUILD_ALL, TRUE );
+ //hide the children
+ LLViewerObject::const_child_list_t& child_list = pDrawable->getVObj()->getChildren();
+ for ( LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
+ iter != child_list.end(); iter++ )
+ {
+ LLViewerObject* child = *iter;
+ LLDrawable* drawable = child->mDrawable;
+ if ( drawable )
+ {
+ drawable->setState( LLDrawable::FORCE_INVISIBLE );
+ markRebuild( drawable, LLDrawable::REBUILD_ALL, TRUE );
+ }
+ }
+}
+void LLPipeline::unhideDrawable( LLDrawable *pDrawable )
+{
+ pDrawable->clearState( LLDrawable::FORCE_INVISIBLE );
+ markRebuild( pDrawable, LLDrawable::REBUILD_ALL, TRUE );
+ //restore children
+ LLViewerObject::const_child_list_t& child_list = pDrawable->getVObj()->getChildren();
+ for ( LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
+ iter != child_list.end(); iter++)
+ {
+ LLViewerObject* child = *iter;
+ LLDrawable* drawable = child->mDrawable;
+ if ( drawable )
+ {
+ drawable->clearState( LLDrawable::FORCE_INVISIBLE );
+ markRebuild( drawable, LLDrawable::REBUILD_ALL, TRUE );
+ }
+ }
+}
+void LLPipeline::restoreHiddenObject( const LLUUID& id )
+{
+ LLViewerObject *pVO = gObjectList.findObject( id );
+
+ if ( pVO )
+ {
+ LLDrawable *pDrawable = pVO->mDrawable;
+ if ( pDrawable )
+ {
+ unhideDrawable( pDrawable );
+ }
+ }
+}
+
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index b8b4f164fe..9aeb2d4978 100644..100755
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -35,7 +35,8 @@
#include "llspatialpartition.h"
#include "m4math.h"
#include "llpointer.h"
-#include "lldrawpool.h"
+#include "lldrawpoolalpha.h"
+#include "lldrawpoolmaterials.h"
#include "llgl.h"
#include "lldrawable.h"
#include "llrendertarget.h"
@@ -57,8 +58,10 @@ class LLRenderFunc;
class LLCubeMap;
class LLCullResult;
class LLVOAvatar;
+class LLVOPartGroup;
class LLGLSLShader;
class LLCurlRequest;
+class LLDrawPoolAlpha;
class LLMeshResponder;
@@ -95,6 +98,7 @@ extern LLFastTimer::DeclareTimer FTM_RENDER_WL_SKY;
extern LLFastTimer::DeclareTimer FTM_RENDER_ALPHA;
extern LLFastTimer::DeclareTimer FTM_RENDER_CHARACTERS;
extern LLFastTimer::DeclareTimer FTM_RENDER_BUMP;
+extern LLFastTimer::DeclareTimer FTM_RENDER_MATERIALS;
extern LLFastTimer::DeclareTimer FTM_RENDER_FULLBRIGHT;
extern LLFastTimer::DeclareTimer FTM_RENDER_GLOW;
extern LLFastTimer::DeclareTimer FTM_STATESORT;
@@ -119,8 +123,25 @@ public:
void createGLBuffers();
void createLUTBuffers();
- void allocateScreenBuffer(U32 resX, U32 resY);
+ //allocate the largest screen buffer possible up to resX, resY
+ //returns true if full size buffer allocated, false if some other size is allocated
+ bool allocateScreenBuffer(U32 resX, U32 resY);
+
+ typedef enum {
+ FBO_SUCCESS_FULLRES = 0,
+ FBO_SUCCESS_LOWRES,
+ FBO_FAILURE
+ } eFBOStatus;
+
+private:
+ //implementation of above, wrapped for easy error handling
+ eFBOStatus doAllocateScreenBuffer(U32 resX, U32 resY);
+public:
+
+ //attempt to allocate screen buffers at resX, resY
+ //returns true if allocation successful, false otherwise
bool allocateScreenBuffer(U32 resX, U32 resY, U32 samples);
+
void allocatePhysicsBuffer();
void resetVertexBuffers(LLDrawable* drawable);
@@ -151,9 +172,17 @@ public:
void unlinkDrawable(LLDrawable*);
+ static void removeMutedAVsLights(LLVOAvatar*);
+
// Object related methods
void markVisible(LLDrawable *drawablep, LLCamera& camera);
void markOccluder(LLSpatialGroup* group);
+
+ //downsample source to dest, taking the maximum depth value per pixel in source and writing to dest
+ // if source's depth buffer cannot be bound for reading, a scratch space depth buffer must be provided
+ void downsampleDepthBuffer(LLRenderTarget& source, LLRenderTarget& dest, LLRenderTarget* scratch_space = NULL);
+
+ void doOcclusion(LLCamera& camera, LLRenderTarget& source, LLRenderTarget& dest, LLRenderTarget* scratch_space = NULL);
void doOcclusion(LLCamera& camera);
void markNotCulled(LLSpatialGroup* group, LLCamera &camera);
void markMoved(LLDrawable *drawablep, BOOL damped_motion = FALSE);
@@ -163,23 +192,30 @@ public:
void markRebuild(LLSpatialGroup* group, BOOL priority = FALSE);
void markRebuild(LLDrawable *drawablep, LLDrawable::EDrawableFlags flag = LLDrawable::REBUILD_ALL, BOOL priority = FALSE);
void markPartitionMove(LLDrawable* drawablep);
+ void markMeshDirty(LLSpatialGroup* group);
//get the object between start and end that's closest to start.
- LLViewerObject* lineSegmentIntersectInWorld(const LLVector3& start, const LLVector3& end,
+ LLViewerObject* lineSegmentIntersectInWorld(const LLVector4a& start, const LLVector4a& end,
BOOL pick_transparent,
S32* face_hit, // return the face hit
- LLVector3* intersection = NULL, // return the intersection point
+ LLVector4a* intersection = NULL, // return the intersection point
LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
- LLVector3* normal = NULL, // return the surface normal at the intersection point
- LLVector3* bi_normal = NULL // return the surface bi-normal at the intersection point
+ LLVector4a* normal = NULL, // return the surface normal at the intersection point
+ LLVector4a* tangent = NULL // return the surface tangent at the intersection point
);
- LLViewerObject* lineSegmentIntersectInHUD(const LLVector3& start, const LLVector3& end,
+
+ //get the closest particle to start between start and end, returns the LLVOPartGroup and particle index
+ LLVOPartGroup* lineSegmentIntersectParticle(const LLVector4a& start, const LLVector4a& end, LLVector4a* intersection,
+ S32* face_hit);
+
+
+ LLViewerObject* lineSegmentIntersectInHUD(const LLVector4a& start, const LLVector4a& end,
BOOL pick_transparent,
S32* face_hit, // return the face hit
- LLVector3* intersection = NULL, // return the intersection point
+ LLVector4a* intersection = NULL, // return the intersection point
LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
- LLVector3* normal = NULL, // return the surface normal at the intersection point
- LLVector3* bi_normal = NULL // return the surface bi-normal at the intersection point
+ LLVector4a* normal = NULL, // return the surface normal at the intersection point
+ LLVector4a* tangent = NULL // return the surface tangent at the intersection point
);
// Something about these textures has changed. Dirty them.
@@ -222,6 +258,7 @@ public:
void updateGL();
void rebuildPriorityGroups();
void rebuildGroups();
+ void clearRebuildGroups();
//calculate pixel area of given box from vantage point of given camera
static F32 calcPixelArea(LLVector3 center, LLVector3 size, LLCamera& camera);
@@ -235,6 +272,8 @@ public:
void forAllVisibleDrawables(void (*func)(LLDrawable*));
void renderObjects(U32 type, U32 mask, BOOL texture = TRUE, BOOL batch_texture = FALSE);
+ void renderMaskedObjects(U32 type, U32 mask, BOOL texture = TRUE, BOOL batch_texture = FALSE);
+
void renderGroups(LLRenderPass* pass, U32 type, U32 mask, BOOL texture);
void grabReferences(LLCullResult& result);
@@ -249,13 +288,14 @@ public:
void renderGeom(LLCamera& camera, BOOL forceVBOUpdate = FALSE);
void renderGeomDeferred(LLCamera& camera);
- void renderGeomPostDeferred(LLCamera& camera);
+ void renderGeomPostDeferred(LLCamera& camera, bool do_occlusion=true);
void renderGeomShadow(LLCamera& camera);
void bindDeferredShader(LLGLSLShader& shader, U32 light_index = 0, U32 noise_map = 0xFFFFFFFF);
void setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep);
void unbindDeferredShader(LLGLSLShader& shader);
void renderDeferredLighting();
+ void renderDeferredLightingToRT(LLRenderTarget* target);
void generateWaterReflection(LLCamera& camera);
void generateSunShadow(LLCamera& camera);
@@ -264,7 +304,7 @@ public:
void setHighlightObject(LLDrawable* obj) { mHighlightObject = obj; }
- void renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera& camera, LLCullResult& result, BOOL use_shader = TRUE, BOOL use_occlusion = TRUE);
+ void renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera& camera, LLCullResult& result, BOOL use_shader, BOOL use_occlusion, U32 target_width);
void renderHighlights();
void renderDebug();
void renderPhysicsDisplay();
@@ -293,30 +333,38 @@ public:
void setLight(LLDrawable *drawablep, BOOL is_light);
BOOL hasRenderBatches(const U32 type) const;
- LLCullResult::drawinfo_list_t::iterator beginRenderMap(U32 type);
- LLCullResult::drawinfo_list_t::iterator endRenderMap(U32 type);
- LLCullResult::sg_list_t::iterator beginAlphaGroups();
- LLCullResult::sg_list_t::iterator endAlphaGroups();
+ LLCullResult::drawinfo_iterator beginRenderMap(U32 type);
+ LLCullResult::drawinfo_iterator endRenderMap(U32 type);
+ LLCullResult::sg_iterator beginAlphaGroups();
+ LLCullResult::sg_iterator endAlphaGroups();
void addTrianglesDrawn(S32 index_count, U32 render_type = LLRender::TRIANGLES);
BOOL hasRenderDebugFeatureMask(const U32 mask) const { return (mRenderDebugFeatureMask & mask) ? TRUE : FALSE; }
BOOL hasRenderDebugMask(const U32 mask) const { return (mRenderDebugMask & mask) ? TRUE : FALSE; }
-
-
+ void setAllRenderDebugFeatures() { mRenderDebugFeatureMask = 0xffffffff; }
+ void clearAllRenderDebugFeatures() { mRenderDebugFeatureMask = 0x0; }
+ void setAllRenderDebugDisplays() { mRenderDebugMask = 0xffffffff; }
+ void clearAllRenderDebugDisplays() { mRenderDebugMask = 0x0; }
BOOL hasRenderType(const U32 type) const;
BOOL hasAnyRenderType(const U32 type, ...) const;
void setRenderTypeMask(U32 type, ...);
- void orRenderTypeMask(U32 type, ...);
+ // This is equivalent to 'setRenderTypeMask'
+ //void orRenderTypeMask(U32 type, ...);
void andRenderTypeMask(U32 type, ...);
void clearRenderTypeMask(U32 type, ...);
+ void setAllRenderTypes();
+ void clearAllRenderTypes();
void pushRenderTypeMask();
void popRenderTypeMask();
+ void pushRenderDebugFeatureMask();
+ void popRenderDebugFeatureMask();
+
static void toggleRenderType(U32 type);
// For UI control of render features
@@ -360,14 +408,24 @@ public:
static void setRenderHighlights(BOOL val);
static void toggleRenderHighlights(void* data);
static BOOL getRenderHighlights(void* data);
+ static void setRenderHighlightTextureChannel(LLRender::eTexIndex channel); // sets which UV setup to display in highlight overlay
+ static void updateRenderBump();
static void updateRenderDeferred();
static void refreshCachedSettings();
static void throttleNewMemoryAllocation(BOOL disable);
+
+
void addDebugBlip(const LLVector3& position, const LLColor4& color);
+ void hidePermanentObjects( std::vector<U32>& restoreList );
+ void restorePermanentObjects( const std::vector<U32>& restoreList );
+ void skipRenderingOfTerrain( BOOL flag );
+ void hideObject( const LLUUID& id );
+ void restoreHiddenObject( const LLUUID& id );
+
private:
void unloadShaders();
void addToQuickLookup( LLDrawPool* new_poolp );
@@ -375,7 +433,9 @@ private:
BOOL updateDrawableGeom(LLDrawable* drawable, BOOL priority);
void assertInitializedDoError();
bool assertInitialized() { const bool is_init = isInit(); if (!is_init) assertInitializedDoError(); return is_init; };
-
+ void connectRefreshCachedSettingsSafe(const std::string name);
+ void hideDrawable( LLDrawable *pDrawable );
+ void unhideDrawable( LLDrawable *pDrawable );
public:
enum {GPU_CLASS_MAX = 3 };
@@ -388,8 +448,11 @@ public:
RENDER_TYPE_TERRAIN = LLDrawPool::POOL_TERRAIN,
RENDER_TYPE_SIMPLE = LLDrawPool::POOL_SIMPLE,
RENDER_TYPE_GRASS = LLDrawPool::POOL_GRASS,
+ RENDER_TYPE_ALPHA_MASK = LLDrawPool::POOL_ALPHA_MASK,
+ RENDER_TYPE_FULLBRIGHT_ALPHA_MASK = LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK,
RENDER_TYPE_FULLBRIGHT = LLDrawPool::POOL_FULLBRIGHT,
RENDER_TYPE_BUMP = LLDrawPool::POOL_BUMP,
+ RENDER_TYPE_MATERIALS = LLDrawPool::POOL_MATERIALS,
RENDER_TYPE_AVATAR = LLDrawPool::POOL_AVATAR,
RENDER_TYPE_TREE = LLDrawPool::POOL_TREE,
RENDER_TYPE_INVISIBLE = LLDrawPool::POOL_INVISIBLE,
@@ -410,6 +473,22 @@ public:
RENDER_TYPE_PASS_ALPHA = LLRenderPass::PASS_ALPHA,
RENDER_TYPE_PASS_ALPHA_MASK = LLRenderPass::PASS_ALPHA_MASK,
RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK = LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK,
+ RENDER_TYPE_PASS_MATERIAL = LLRenderPass::PASS_MATERIAL,
+ RENDER_TYPE_PASS_MATERIAL_ALPHA = LLRenderPass::PASS_MATERIAL_ALPHA,
+ RENDER_TYPE_PASS_MATERIAL_ALPHA_MASK = LLRenderPass::PASS_MATERIAL_ALPHA_MASK,
+ RENDER_TYPE_PASS_MATERIAL_ALPHA_EMISSIVE= LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE,
+ RENDER_TYPE_PASS_SPECMAP = LLRenderPass::PASS_SPECMAP,
+ RENDER_TYPE_PASS_SPECMAP_BLEND = LLRenderPass::PASS_SPECMAP_BLEND,
+ RENDER_TYPE_PASS_SPECMAP_MASK = LLRenderPass::PASS_SPECMAP_MASK,
+ RENDER_TYPE_PASS_SPECMAP_EMISSIVE = LLRenderPass::PASS_SPECMAP_EMISSIVE,
+ RENDER_TYPE_PASS_NORMMAP = LLRenderPass::PASS_NORMMAP,
+ RENDER_TYPE_PASS_NORMMAP_BLEND = LLRenderPass::PASS_NORMMAP_BLEND,
+ RENDER_TYPE_PASS_NORMMAP_MASK = LLRenderPass::PASS_NORMMAP_MASK,
+ RENDER_TYPE_PASS_NORMMAP_EMISSIVE = LLRenderPass::PASS_NORMMAP_EMISSIVE,
+ RENDER_TYPE_PASS_NORMSPEC = LLRenderPass::PASS_NORMSPEC,
+ RENDER_TYPE_PASS_NORMSPEC_BLEND = LLRenderPass::PASS_NORMSPEC_BLEND,
+ RENDER_TYPE_PASS_NORMSPEC_MASK = LLRenderPass::PASS_NORMSPEC_MASK,
+ RENDER_TYPE_PASS_NORMSPEC_EMISSIVE = LLRenderPass::PASS_NORMSPEC_EMISSIVE,
// Following are object types (only used in drawable mRenderType)
RENDER_TYPE_HUD = LLRenderPass::NUM_RENDER_TYPES,
RENDER_TYPE_VOLUME,
@@ -464,6 +543,7 @@ public:
RENDER_DEBUG_LOD_INFO = 0x04000000,
RENDER_DEBUG_RENDER_COMPLEXITY = 0x08000000,
RENDER_DEBUG_ATTACHMENT_BYTES = 0x10000000,
+ RENDER_DEBUG_TEXEL_DENSITY = 0x20000000
};
public:
@@ -515,6 +595,7 @@ public:
static BOOL sPickAvatar;
static BOOL sReflectionRender;
static BOOL sImpostorRender;
+ static BOOL sImpostorRenderAlphaDepthPass;
static BOOL sUnderWaterRender;
static BOOL sRenderGlow;
static BOOL sTextureBindTest;
@@ -524,7 +605,8 @@ public:
static BOOL sRenderDeferred;
static BOOL sMemAllocationThrottled;
static S32 sVisibleLightCount;
- static F32 sMinRenderSize;
+ static F32 sMinRenderSize;
+ static BOOL sRenderingHUDs;
//screen texture
U32 mScreenWidth;
@@ -536,6 +618,7 @@ public:
LLRenderTarget mFXAABuffer;
LLRenderTarget mEdgeMap;
LLRenderTarget mDeferredDepth;
+ LLRenderTarget mOcclusionDepth;
LLRenderTarget mDeferredLight;
LLRenderTarget mHighlight;
LLRenderTarget mPhysicsDisplay;
@@ -543,8 +626,12 @@ public:
//utility buffer for rendering post effects, gets abused by renderDeferredLighting
LLPointer<LLVertexBuffer> mDeferredVB;
+ //utility buffer for rendering cubes, 8 vertices are corners of a cube [-1, 1]
+ LLPointer<LLVertexBuffer> mCubeVB;
+
//sun shadow map
LLRenderTarget mShadow[6];
+ LLRenderTarget mShadowOcclusion[6];
std::vector<LLVector3> mShadowFrustPoints[4];
LLVector4 mShadowError;
LLVector4 mShadowFOV;
@@ -594,12 +681,14 @@ public:
BOOL mVertexShadersEnabled;
S32 mVertexShadersLoaded; // 0 = no, 1 = yes, -1 = failed
+ U32 mTransformFeedbackPrimitives; //number of primitives expected to be generated by transform feedback
protected:
BOOL mRenderTypeEnabled[NUM_RENDER_TYPES];
std::stack<std::string> mRenderTypeEnableStack;
U32 mRenderDebugFeatureMask;
U32 mRenderDebugMask;
+ std::stack<U32> mRenderDebugFeatureStack;
U32 mOldRenderDebugMask;
@@ -651,6 +740,11 @@ protected:
LLSpatialGroup::sg_vector_t mGroupQ1; //priority
LLSpatialGroup::sg_vector_t mGroupQ2; // non-priority
+ LLSpatialGroup::sg_vector_t mGroupSaveQ1; // a place to save mGroupQ1 until it is safe to unref
+
+ LLSpatialGroup::sg_vector_t mMeshDirtyGroup; //groups that need rebuildMesh called
+ U32 mMeshDirtyQueryObject;
+
LLDrawable::drawable_list_t mPartitionQ; //drawables that need to update their spatial partition radius
bool mGroupQ2Locked;
@@ -725,17 +819,20 @@ protected:
// For quick-lookups into mPools (mapped by texture pointer)
std::map<uintptr_t, LLDrawPool*> mTerrainPools;
std::map<uintptr_t, LLDrawPool*> mTreePools;
- LLDrawPool* mAlphaPool;
+ LLDrawPoolAlpha* mAlphaPool;
LLDrawPool* mSkyPool;
LLDrawPool* mTerrainPool;
LLDrawPool* mWaterPool;
LLDrawPool* mGroundPool;
LLRenderPass* mSimplePool;
LLRenderPass* mGrassPool;
+ LLRenderPass* mAlphaMaskPool;
+ LLRenderPass* mFullbrightAlphaMaskPool;
LLRenderPass* mFullbrightPool;
LLDrawPool* mInvisiblePool;
LLDrawPool* mGlowPool;
LLDrawPool* mBumpPool;
+ LLDrawPool* mMaterialsPool;
LLDrawPool* mWLSkyPool;
// Note: no need to keep an quick-lookup to avatar pools, since there's only one per avatar
@@ -774,6 +871,10 @@ public:
static BOOL sRenderBeacons;
static BOOL sRenderHighlight;
+ // Determines which set of UVs to use in highlight display
+ //
+ static LLRender::eTexIndex sRenderHighlightTextureChannel;
+
//debug use
static U32 sCurRenderPoolType ;
@@ -818,6 +919,7 @@ public:
static F32 RenderGlowWidth;
static F32 RenderGlowStrength;
static BOOL RenderDepthOfField;
+ static BOOL RenderDepthOfFieldInEditMode;
static F32 CameraFocusTransitionTime;
static F32 CameraFNumber;
static F32 CameraFocalLength;
@@ -851,6 +953,7 @@ public:
static BOOL CameraOffset;
static F32 CameraMaxCoF;
static F32 CameraDoFResScale;
+ static F32 RenderAutoHideSurfaceAreaLimit;
};
void render_bbox(const LLVector3 &min, const LLVector3 &max);
diff --git a/indra/newview/pl.lproj/language.txt b/indra/newview/pl.lproj/language.txt
index 55239f3c18..55239f3c18 100644..100755
--- a/indra/newview/pl.lproj/language.txt
+++ b/indra/newview/pl.lproj/language.txt
diff --git a/indra/newview/pt.lproj/language.txt b/indra/newview/pt.lproj/language.txt
index 9e3340eca2..9e3340eca2 100644..100755
--- a/indra/newview/pt.lproj/language.txt
+++ b/indra/newview/pt.lproj/language.txt
diff --git a/indra/newview/res-sdl/arrow.BMP b/indra/newview/res-sdl/arrow.BMP
index a8f6da64b5..a8f6da64b5 100644..100755
--- a/indra/newview/res-sdl/arrow.BMP
+++ b/indra/newview/res-sdl/arrow.BMP
Binary files differ
diff --git a/indra/newview/res-sdl/arrowcop.BMP b/indra/newview/res-sdl/arrowcop.BMP
index 1a26a0df34..1a26a0df34 100644..100755
--- a/indra/newview/res-sdl/arrowcop.BMP
+++ b/indra/newview/res-sdl/arrowcop.BMP
Binary files differ
diff --git a/indra/newview/res-sdl/arrowcopmulti.BMP b/indra/newview/res-sdl/arrowcopmulti.BMP
index 48f153cef6..48f153cef6 100644..100755
--- a/indra/newview/res-sdl/arrowcopmulti.BMP
+++ b/indra/newview/res-sdl/arrowcopmulti.BMP
Binary files differ
diff --git a/indra/newview/res-sdl/arrowdrag.BMP b/indra/newview/res-sdl/arrowdrag.BMP
index cd868eec20..cd868eec20 100644..100755
--- a/indra/newview/res-sdl/arrowdrag.BMP
+++ b/indra/newview/res-sdl/arrowdrag.BMP
Binary files differ
diff --git a/indra/newview/res-sdl/circleandline.BMP b/indra/newview/res-sdl/circleandline.BMP
index 284ae8b7d5..284ae8b7d5 100644..100755
--- a/indra/newview/res-sdl/circleandline.BMP
+++ b/indra/newview/res-sdl/circleandline.BMP
Binary files differ
diff --git a/indra/newview/res-sdl/cross.BMP b/indra/newview/res-sdl/cross.BMP
index 0b4672d4d6..0b4672d4d6 100644..100755
--- a/indra/newview/res-sdl/cross.BMP
+++ b/indra/newview/res-sdl/cross.BMP
Binary files differ
diff --git a/indra/newview/res-sdl/hand.BMP b/indra/newview/res-sdl/hand.BMP
index 2a092fbb7f..2a092fbb7f 100644..100755
--- a/indra/newview/res-sdl/hand.BMP
+++ b/indra/newview/res-sdl/hand.BMP
Binary files differ
diff --git a/indra/newview/res-sdl/ibeam.BMP b/indra/newview/res-sdl/ibeam.BMP
index 820904a228..820904a228 100644..100755
--- a/indra/newview/res-sdl/ibeam.BMP
+++ b/indra/newview/res-sdl/ibeam.BMP
Binary files differ
diff --git a/indra/newview/res-sdl/llarrow.BMP b/indra/newview/res-sdl/llarrow.BMP
index a8f6da64b5..a8f6da64b5 100644..100755
--- a/indra/newview/res-sdl/llarrow.BMP
+++ b/indra/newview/res-sdl/llarrow.BMP
Binary files differ
diff --git a/indra/newview/res-sdl/llarrowdrag.BMP b/indra/newview/res-sdl/llarrowdrag.BMP
index cd868eec20..cd868eec20 100644..100755
--- a/indra/newview/res-sdl/llarrowdrag.BMP
+++ b/indra/newview/res-sdl/llarrowdrag.BMP
Binary files differ
diff --git a/indra/newview/res-sdl/llarrowdragmulti.BMP b/indra/newview/res-sdl/llarrowdragmulti.BMP
index fb528bc92d..fb528bc92d 100644..100755
--- a/indra/newview/res-sdl/llarrowdragmulti.BMP
+++ b/indra/newview/res-sdl/llarrowdragmulti.BMP
Binary files differ
diff --git a/indra/newview/res-sdl/llarrowlocked.BMP b/indra/newview/res-sdl/llarrowlocked.BMP
index 0aaa441ab1..0aaa441ab1 100644..100755
--- a/indra/newview/res-sdl/llarrowlocked.BMP
+++ b/indra/newview/res-sdl/llarrowlocked.BMP
Binary files differ
diff --git a/indra/newview/res-sdl/llgrablocked.BMP b/indra/newview/res-sdl/llgrablocked.BMP
index 847439670f..847439670f 100644..100755
--- a/indra/newview/res-sdl/llgrablocked.BMP
+++ b/indra/newview/res-sdl/llgrablocked.BMP
Binary files differ
diff --git a/indra/newview/res-sdl/llno.BMP b/indra/newview/res-sdl/llno.BMP
index 284ae8b7d5..284ae8b7d5 100644..100755
--- a/indra/newview/res-sdl/llno.BMP
+++ b/indra/newview/res-sdl/llno.BMP
Binary files differ
diff --git a/indra/newview/res-sdl/llnolocked.BMP b/indra/newview/res-sdl/llnolocked.BMP
index 61f0170cb3..61f0170cb3 100644..100755
--- a/indra/newview/res-sdl/llnolocked.BMP
+++ b/indra/newview/res-sdl/llnolocked.BMP
Binary files differ
diff --git a/indra/newview/res-sdl/lltoolcamera.BMP b/indra/newview/res-sdl/lltoolcamera.BMP
index c961d7a49c..c961d7a49c 100644..100755
--- a/indra/newview/res-sdl/lltoolcamera.BMP
+++ b/indra/newview/res-sdl/lltoolcamera.BMP
Binary files differ
diff --git a/indra/newview/res-sdl/lltoolcreate.BMP b/indra/newview/res-sdl/lltoolcreate.BMP
index 08a4a9322d..08a4a9322d 100644..100755
--- a/indra/newview/res-sdl/lltoolcreate.BMP
+++ b/indra/newview/res-sdl/lltoolcreate.BMP
Binary files differ
diff --git a/indra/newview/res-sdl/lltoolfocus.BMP b/indra/newview/res-sdl/lltoolfocus.BMP
index afb90a95e3..afb90a95e3 100644..100755
--- a/indra/newview/res-sdl/lltoolfocus.BMP
+++ b/indra/newview/res-sdl/lltoolfocus.BMP
Binary files differ
diff --git a/indra/newview/res-sdl/lltoolgrab.BMP b/indra/newview/res-sdl/lltoolgrab.BMP
index f2ac68bf3c..f2ac68bf3c 100644..100755
--- a/indra/newview/res-sdl/lltoolgrab.BMP
+++ b/indra/newview/res-sdl/lltoolgrab.BMP
Binary files differ
diff --git a/indra/newview/res-sdl/lltoolland.BMP b/indra/newview/res-sdl/lltoolland.BMP
index 64e6365625..64e6365625 100644..100755
--- a/indra/newview/res-sdl/lltoolland.BMP
+++ b/indra/newview/res-sdl/lltoolland.BMP
Binary files differ
diff --git a/indra/newview/res-sdl/lltoolpan.BMP b/indra/newview/res-sdl/lltoolpan.BMP
index ffbef21ec7..ffbef21ec7 100644..100755
--- a/indra/newview/res-sdl/lltoolpan.BMP
+++ b/indra/newview/res-sdl/lltoolpan.BMP
Binary files differ
diff --git a/indra/newview/res-sdl/lltoolpathfinding.BMP b/indra/newview/res-sdl/lltoolpathfinding.BMP
new file mode 100755
index 0000000000..a567951b7a
--- /dev/null
+++ b/indra/newview/res-sdl/lltoolpathfinding.BMP
Binary files differ
diff --git a/indra/newview/res-sdl/lltoolpathfindingpathend.BMP b/indra/newview/res-sdl/lltoolpathfindingpathend.BMP
new file mode 100755
index 0000000000..aacea8237f
--- /dev/null
+++ b/indra/newview/res-sdl/lltoolpathfindingpathend.BMP
Binary files differ
diff --git a/indra/newview/res-sdl/lltoolpathfindingpathendadd.BMP b/indra/newview/res-sdl/lltoolpathfindingpathendadd.BMP
new file mode 100755
index 0000000000..fa19f3f105
--- /dev/null
+++ b/indra/newview/res-sdl/lltoolpathfindingpathendadd.BMP
Binary files differ
diff --git a/indra/newview/res-sdl/lltoolpathfindingpathstart.BMP b/indra/newview/res-sdl/lltoolpathfindingpathstart.BMP
new file mode 100755
index 0000000000..912b7f931a
--- /dev/null
+++ b/indra/newview/res-sdl/lltoolpathfindingpathstart.BMP
Binary files differ
diff --git a/indra/newview/res-sdl/lltoolpathfindingpathstartadd.BMP b/indra/newview/res-sdl/lltoolpathfindingpathstartadd.BMP
new file mode 100755
index 0000000000..4e8999ae0b
--- /dev/null
+++ b/indra/newview/res-sdl/lltoolpathfindingpathstartadd.BMP
Binary files differ
diff --git a/indra/newview/res-sdl/lltoolpipette.BMP b/indra/newview/res-sdl/lltoolpipette.BMP
index 2d27118289..2d27118289 100644..100755
--- a/indra/newview/res-sdl/lltoolpipette.BMP
+++ b/indra/newview/res-sdl/lltoolpipette.BMP
Binary files differ
diff --git a/indra/newview/res-sdl/lltoolrotate.BMP b/indra/newview/res-sdl/lltoolrotate.BMP
index dd84673018..dd84673018 100644..100755
--- a/indra/newview/res-sdl/lltoolrotate.BMP
+++ b/indra/newview/res-sdl/lltoolrotate.BMP
Binary files differ
diff --git a/indra/newview/res-sdl/lltoolscale.BMP b/indra/newview/res-sdl/lltoolscale.BMP
index 882515e5e3..882515e5e3 100644..100755
--- a/indra/newview/res-sdl/lltoolscale.BMP
+++ b/indra/newview/res-sdl/lltoolscale.BMP
Binary files differ
diff --git a/indra/newview/res-sdl/lltooltranslate.BMP b/indra/newview/res-sdl/lltooltranslate.BMP
index d084f6a026..d084f6a026 100644..100755
--- a/indra/newview/res-sdl/lltooltranslate.BMP
+++ b/indra/newview/res-sdl/lltooltranslate.BMP
Binary files differ
diff --git a/indra/newview/res-sdl/lltoolzoomin.BMP b/indra/newview/res-sdl/lltoolzoomin.BMP
index e4e46cc702..e4e46cc702 100644..100755
--- a/indra/newview/res-sdl/lltoolzoomin.BMP
+++ b/indra/newview/res-sdl/lltoolzoomin.BMP
Binary files differ
diff --git a/indra/newview/res-sdl/lltoolzoomout.BMP b/indra/newview/res-sdl/lltoolzoomout.BMP
index 7f958383ab..7f958383ab 100644..100755
--- a/indra/newview/res-sdl/lltoolzoomout.BMP
+++ b/indra/newview/res-sdl/lltoolzoomout.BMP
Binary files differ
diff --git a/indra/newview/res-sdl/sizenesw.BMP b/indra/newview/res-sdl/sizenesw.BMP
index 559579f40e..559579f40e 100644..100755
--- a/indra/newview/res-sdl/sizenesw.BMP
+++ b/indra/newview/res-sdl/sizenesw.BMP
Binary files differ
diff --git a/indra/newview/res-sdl/sizens.BMP b/indra/newview/res-sdl/sizens.BMP
index 8373077dff..8373077dff 100644..100755
--- a/indra/newview/res-sdl/sizens.BMP
+++ b/indra/newview/res-sdl/sizens.BMP
Binary files differ
diff --git a/indra/newview/res-sdl/sizenwse.BMP b/indra/newview/res-sdl/sizenwse.BMP
index 6d069fa765..6d069fa765 100644..100755
--- a/indra/newview/res-sdl/sizenwse.BMP
+++ b/indra/newview/res-sdl/sizenwse.BMP
Binary files differ
diff --git a/indra/newview/res-sdl/sizewe.BMP b/indra/newview/res-sdl/sizewe.BMP
index 878df453a4..878df453a4 100644..100755
--- a/indra/newview/res-sdl/sizewe.BMP
+++ b/indra/newview/res-sdl/sizewe.BMP
Binary files differ
diff --git a/indra/newview/res-sdl/toolbuy.BMP b/indra/newview/res-sdl/toolbuy.BMP
index 07e9273721..07e9273721 100644..100755
--- a/indra/newview/res-sdl/toolbuy.BMP
+++ b/indra/newview/res-sdl/toolbuy.BMP
Binary files differ
diff --git a/indra/newview/res-sdl/toolmediaopen.BMP b/indra/newview/res-sdl/toolmediaopen.BMP
index ac4b231994..ac4b231994 100644..100755
--- a/indra/newview/res-sdl/toolmediaopen.BMP
+++ b/indra/newview/res-sdl/toolmediaopen.BMP
Binary files differ
diff --git a/indra/newview/res-sdl/toolopen.BMP b/indra/newview/res-sdl/toolopen.BMP
index 5b87979304..5b87979304 100644..100755
--- a/indra/newview/res-sdl/toolopen.BMP
+++ b/indra/newview/res-sdl/toolopen.BMP
Binary files differ
diff --git a/indra/newview/res-sdl/toolpause.BMP b/indra/newview/res-sdl/toolpause.BMP
index dd2c6857d2..dd2c6857d2 100644..100755
--- a/indra/newview/res-sdl/toolpause.BMP
+++ b/indra/newview/res-sdl/toolpause.BMP
Binary files differ
diff --git a/indra/newview/res-sdl/toolpickobject.BMP b/indra/newview/res-sdl/toolpickobject.BMP
index 25469fc3a8..25469fc3a8 100644..100755
--- a/indra/newview/res-sdl/toolpickobject.BMP
+++ b/indra/newview/res-sdl/toolpickobject.BMP
Binary files differ
diff --git a/indra/newview/res-sdl/toolpickobject2.BMP b/indra/newview/res-sdl/toolpickobject2.BMP
index 09df69e675..09df69e675 100644..100755
--- a/indra/newview/res-sdl/toolpickobject2.BMP
+++ b/indra/newview/res-sdl/toolpickobject2.BMP
Binary files differ
diff --git a/indra/newview/res-sdl/toolpickobject3.BMP b/indra/newview/res-sdl/toolpickobject3.BMP
index fc28698050..fc28698050 100644..100755
--- a/indra/newview/res-sdl/toolpickobject3.BMP
+++ b/indra/newview/res-sdl/toolpickobject3.BMP
Binary files differ
diff --git a/indra/newview/res-sdl/toolplay.BMP b/indra/newview/res-sdl/toolplay.BMP
index 9c40d7dbec..9c40d7dbec 100644..100755
--- a/indra/newview/res-sdl/toolplay.BMP
+++ b/indra/newview/res-sdl/toolplay.BMP
Binary files differ
diff --git a/indra/newview/res-sdl/toolsit.BMP b/indra/newview/res-sdl/toolsit.BMP
index 8ce59ae97a..8ce59ae97a 100644..100755
--- a/indra/newview/res-sdl/toolsit.BMP
+++ b/indra/newview/res-sdl/toolsit.BMP
Binary files differ
diff --git a/indra/newview/res-sdl/wait.BMP b/indra/newview/res-sdl/wait.BMP
index 26dec59afe..26dec59afe 100644..100755
--- a/indra/newview/res-sdl/wait.BMP
+++ b/indra/newview/res-sdl/wait.BMP
Binary files differ
diff --git a/indra/newview/res-sdl/working.BMP b/indra/newview/res-sdl/working.BMP
index 26dec59afe..26dec59afe 100644..100755
--- a/indra/newview/res-sdl/working.BMP
+++ b/indra/newview/res-sdl/working.BMP
Binary files differ
diff --git a/indra/newview/res/arrow.cur b/indra/newview/res/arrow.cur
index d11b68867f..d11b68867f 100644..100755
--- a/indra/newview/res/arrow.cur
+++ b/indra/newview/res/arrow.cur
Binary files differ
diff --git a/indra/newview/res/arrowcop.cur b/indra/newview/res/arrowcop.cur
index 8b5902c13d..8b5902c13d 100644..100755
--- a/indra/newview/res/arrowcop.cur
+++ b/indra/newview/res/arrowcop.cur
Binary files differ
diff --git a/indra/newview/res/arrowcopmulti.cur b/indra/newview/res/arrowcopmulti.cur
index 2620522616..2620522616 100644..100755
--- a/indra/newview/res/arrowcopmulti.cur
+++ b/indra/newview/res/arrowcopmulti.cur
Binary files differ
diff --git a/indra/newview/res/arrowdrag.cur b/indra/newview/res/arrowdrag.cur
index 77b2d1a0fb..77b2d1a0fb 100644..100755
--- a/indra/newview/res/arrowdrag.cur
+++ b/indra/newview/res/arrowdrag.cur
Binary files differ
diff --git a/indra/newview/res/bitmap2.bmp b/indra/newview/res/bitmap2.bmp
index 770b07558c..770b07558c 100644..100755
--- a/indra/newview/res/bitmap2.bmp
+++ b/indra/newview/res/bitmap2.bmp
Binary files differ
diff --git a/indra/newview/res/circleandline.cur b/indra/newview/res/circleandline.cur
index 00050f5501..00050f5501 100644..100755
--- a/indra/newview/res/circleandline.cur
+++ b/indra/newview/res/circleandline.cur
Binary files differ
diff --git a/indra/newview/res/have_artwork_bundle.marker b/indra/newview/res/have_artwork_bundle.marker
index 1dbb238d53..1dbb238d53 100644..100755
--- a/indra/newview/res/have_artwork_bundle.marker
+++ b/indra/newview/res/have_artwork_bundle.marker
diff --git a/indra/newview/res/icon1.ico b/indra/newview/res/icon1.ico
index ad607598fa..ad607598fa 100644..100755
--- a/indra/newview/res/icon1.ico
+++ b/indra/newview/res/icon1.ico
Binary files differ
diff --git a/indra/newview/res/install_icon.BMP b/indra/newview/res/install_icon.BMP
index 09df573870..09df573870 100644..100755
--- a/indra/newview/res/install_icon.BMP
+++ b/indra/newview/res/install_icon.BMP
Binary files differ
diff --git a/indra/newview/res/llarrow.cur b/indra/newview/res/llarrow.cur
index 8a922d7f3f..8a922d7f3f 100644..100755
--- a/indra/newview/res/llarrow.cur
+++ b/indra/newview/res/llarrow.cur
Binary files differ
diff --git a/indra/newview/res/llarrowdrag.cur b/indra/newview/res/llarrowdrag.cur
index 77b2d1a0fb..77b2d1a0fb 100644..100755
--- a/indra/newview/res/llarrowdrag.cur
+++ b/indra/newview/res/llarrowdrag.cur
Binary files differ
diff --git a/indra/newview/res/llarrowdragmulti.cur b/indra/newview/res/llarrowdragmulti.cur
index f0853b899c..f0853b899c 100644..100755
--- a/indra/newview/res/llarrowdragmulti.cur
+++ b/indra/newview/res/llarrowdragmulti.cur
Binary files differ
diff --git a/indra/newview/res/llarrowlocked.cur b/indra/newview/res/llarrowlocked.cur
index 5b81f147ef..5b81f147ef 100644..100755
--- a/indra/newview/res/llarrowlocked.cur
+++ b/indra/newview/res/llarrowlocked.cur
Binary files differ
diff --git a/indra/newview/res/llgrablocked.cur b/indra/newview/res/llgrablocked.cur
index 73dea154e6..73dea154e6 100644..100755
--- a/indra/newview/res/llgrablocked.cur
+++ b/indra/newview/res/llgrablocked.cur
Binary files differ
diff --git a/indra/newview/res/llno.cur b/indra/newview/res/llno.cur
index 00050f5501..00050f5501 100644..100755
--- a/indra/newview/res/llno.cur
+++ b/indra/newview/res/llno.cur
Binary files differ
diff --git a/indra/newview/res/llnolocked.cur b/indra/newview/res/llnolocked.cur
index dfa4a05509..dfa4a05509 100644..100755
--- a/indra/newview/res/llnolocked.cur
+++ b/indra/newview/res/llnolocked.cur
Binary files differ
diff --git a/indra/newview/res/lltoolcamera.cur b/indra/newview/res/lltoolcamera.cur
index e0f19461c7..e0f19461c7 100644..100755
--- a/indra/newview/res/lltoolcamera.cur
+++ b/indra/newview/res/lltoolcamera.cur
Binary files differ
diff --git a/indra/newview/res/lltoolcreate.cur b/indra/newview/res/lltoolcreate.cur
index 716f328211..716f328211 100644..100755
--- a/indra/newview/res/lltoolcreate.cur
+++ b/indra/newview/res/lltoolcreate.cur
Binary files differ
diff --git a/indra/newview/res/lltoolfocus.cur b/indra/newview/res/lltoolfocus.cur
index 7b38ad3af9..7b38ad3af9 100644..100755
--- a/indra/newview/res/lltoolfocus.cur
+++ b/indra/newview/res/lltoolfocus.cur
Binary files differ
diff --git a/indra/newview/res/lltoolgrab.cur b/indra/newview/res/lltoolgrab.cur
index 4484001357..4484001357 100644..100755
--- a/indra/newview/res/lltoolgrab.cur
+++ b/indra/newview/res/lltoolgrab.cur
Binary files differ
diff --git a/indra/newview/res/lltoolland.cur b/indra/newview/res/lltoolland.cur
index e22ef6c73d..e22ef6c73d 100644..100755
--- a/indra/newview/res/lltoolland.cur
+++ b/indra/newview/res/lltoolland.cur
Binary files differ
diff --git a/indra/newview/res/lltoolpan.cur b/indra/newview/res/lltoolpan.cur
index 0a348669b6..0a348669b6 100644..100755
--- a/indra/newview/res/lltoolpan.cur
+++ b/indra/newview/res/lltoolpan.cur
Binary files differ
diff --git a/indra/newview/res/lltoolpathfinding.cur b/indra/newview/res/lltoolpathfinding.cur
new file mode 100755
index 0000000000..2aba2daa45
--- /dev/null
+++ b/indra/newview/res/lltoolpathfinding.cur
Binary files differ
diff --git a/indra/newview/res/lltoolpathfindingpathend.cur b/indra/newview/res/lltoolpathfindingpathend.cur
new file mode 100755
index 0000000000..e951a6956b
--- /dev/null
+++ b/indra/newview/res/lltoolpathfindingpathend.cur
Binary files differ
diff --git a/indra/newview/res/lltoolpathfindingpathendadd.cur b/indra/newview/res/lltoolpathfindingpathendadd.cur
new file mode 100755
index 0000000000..0bf3201b23
--- /dev/null
+++ b/indra/newview/res/lltoolpathfindingpathendadd.cur
Binary files differ
diff --git a/indra/newview/res/lltoolpathfindingpathstart.cur b/indra/newview/res/lltoolpathfindingpathstart.cur
new file mode 100755
index 0000000000..fecc716990
--- /dev/null
+++ b/indra/newview/res/lltoolpathfindingpathstart.cur
Binary files differ
diff --git a/indra/newview/res/lltoolpathfindingpathstartadd.cur b/indra/newview/res/lltoolpathfindingpathstartadd.cur
new file mode 100755
index 0000000000..45e23e5161
--- /dev/null
+++ b/indra/newview/res/lltoolpathfindingpathstartadd.cur
Binary files differ
diff --git a/indra/newview/res/lltoolpipette.cur b/indra/newview/res/lltoolpipette.cur
index b4780967f9..b4780967f9 100644..100755
--- a/indra/newview/res/lltoolpipette.cur
+++ b/indra/newview/res/lltoolpipette.cur
Binary files differ
diff --git a/indra/newview/res/lltoolrotate.cur b/indra/newview/res/lltoolrotate.cur
index adbadaee84..adbadaee84 100644..100755
--- a/indra/newview/res/lltoolrotate.cur
+++ b/indra/newview/res/lltoolrotate.cur
Binary files differ
diff --git a/indra/newview/res/lltoolscale.cur b/indra/newview/res/lltoolscale.cur
index 4b6d20bfad..4b6d20bfad 100644..100755
--- a/indra/newview/res/lltoolscale.cur
+++ b/indra/newview/res/lltoolscale.cur
Binary files differ
diff --git a/indra/newview/res/lltooltranslate.cur b/indra/newview/res/lltooltranslate.cur
index 2df80de0a6..2df80de0a6 100644..100755
--- a/indra/newview/res/lltooltranslate.cur
+++ b/indra/newview/res/lltooltranslate.cur
Binary files differ
diff --git a/indra/newview/res/lltoolzoomin.cur b/indra/newview/res/lltoolzoomin.cur
index 0b5d80101e..0b5d80101e 100644..100755
--- a/indra/newview/res/lltoolzoomin.cur
+++ b/indra/newview/res/lltoolzoomin.cur
Binary files differ
diff --git a/indra/newview/res/lltoolzoomout.cur b/indra/newview/res/lltoolzoomout.cur
index b33e68d1a6..b33e68d1a6 100644..100755
--- a/indra/newview/res/lltoolzoomout.cur
+++ b/indra/newview/res/lltoolzoomout.cur
Binary files differ
diff --git a/indra/newview/res/loginbackground.bmp b/indra/newview/res/loginbackground.bmp
index 288a0b0398..288a0b0398 100644..100755
--- a/indra/newview/res/loginbackground.bmp
+++ b/indra/newview/res/loginbackground.bmp
Binary files differ
diff --git a/indra/newview/res/resource.h b/indra/newview/res/resource.h
index 01d90da971..01d90da971 100644..100755
--- a/indra/newview/res/resource.h
+++ b/indra/newview/res/resource.h
diff --git a/indra/newview/res/toolbuy.cur b/indra/newview/res/toolbuy.cur
index 65bbf01d45..65bbf01d45 100644..100755
--- a/indra/newview/res/toolbuy.cur
+++ b/indra/newview/res/toolbuy.cur
Binary files differ
diff --git a/indra/newview/res/toolmediaopen.cur b/indra/newview/res/toolmediaopen.cur
index 7609989ba7..7609989ba7 100644..100755
--- a/indra/newview/res/toolmediaopen.cur
+++ b/indra/newview/res/toolmediaopen.cur
Binary files differ
diff --git a/indra/newview/res/toolopen.cur b/indra/newview/res/toolopen.cur
index 22ecbd5228..22ecbd5228 100644..100755
--- a/indra/newview/res/toolopen.cur
+++ b/indra/newview/res/toolopen.cur
Binary files differ
diff --git a/indra/newview/res/toolpause.cur b/indra/newview/res/toolpause.cur
index 7a6e85566b..7a6e85566b 100644..100755
--- a/indra/newview/res/toolpause.cur
+++ b/indra/newview/res/toolpause.cur
Binary files differ
diff --git a/indra/newview/res/toolpickobject.cur b/indra/newview/res/toolpickobject.cur
index ba482b5445..ba482b5445 100644..100755
--- a/indra/newview/res/toolpickobject.cur
+++ b/indra/newview/res/toolpickobject.cur
Binary files differ
diff --git a/indra/newview/res/toolpickobject2.cur b/indra/newview/res/toolpickobject2.cur
index b168f8d691..b168f8d691 100644..100755
--- a/indra/newview/res/toolpickobject2.cur
+++ b/indra/newview/res/toolpickobject2.cur
Binary files differ
diff --git a/indra/newview/res/toolpickobject3.cur b/indra/newview/res/toolpickobject3.cur
index 457c3a6555..457c3a6555 100644..100755
--- a/indra/newview/res/toolpickobject3.cur
+++ b/indra/newview/res/toolpickobject3.cur
Binary files differ
diff --git a/indra/newview/res/toolpipette.cur b/indra/newview/res/toolpipette.cur
index b4780967f9..b4780967f9 100644..100755
--- a/indra/newview/res/toolpipette.cur
+++ b/indra/newview/res/toolpipette.cur
Binary files differ
diff --git a/indra/newview/res/toolplay.cur b/indra/newview/res/toolplay.cur
index 0776a17bbc..0776a17bbc 100644..100755
--- a/indra/newview/res/toolplay.cur
+++ b/indra/newview/res/toolplay.cur
Binary files differ
diff --git a/indra/newview/res/toolsit.cur b/indra/newview/res/toolsit.cur
index d26b6f8638..d26b6f8638 100644..100755
--- a/indra/newview/res/toolsit.cur
+++ b/indra/newview/res/toolsit.cur
Binary files differ
diff --git a/indra/newview/res/uninstall_icon.BMP b/indra/newview/res/uninstall_icon.BMP
index 562b56676a..562b56676a 100644..100755
--- a/indra/newview/res/uninstall_icon.BMP
+++ b/indra/newview/res/uninstall_icon.BMP
Binary files differ
diff --git a/indra/newview/res/viewerRes.rc b/indra/newview/res/viewerRes.rc
index a53dece422..8587243791 100644..100755
--- a/indra/newview/res/viewerRes.rc
+++ b/indra/newview/res/viewerRes.rc
@@ -122,6 +122,12 @@ TOOLMEDIAOPEN CURSOR "toolmediaopen.cur"
TOOLBUY CURSOR "toolbuy.cur"
TOOLOPEN CURSOR "toolopen.cur"
TOOLSIT CURSOR "toolsit.cur"
+TOOLPATHFINDING CURSOR "lltoolpathfinding.cur"
+TOOLPATHFINDINGPATHSTART CURSOR "lltoolpathfindingpathstart.cur"
+TOOLPATHFINDINGPATHSTARTADD CURSOR "lltoolpathfindingpathstartadd.cur"
+TOOLPATHFINDINGPATHEND CURSOR "lltoolpathfindingpathend.cur"
+TOOLPATHFINDINGPATHENDADD CURSOR "lltoolpathfindingpathendadd.cur"
+TOOLNO CURSOR "llno.cur"
/////////////////////////////////////////////////////////////////////////////
//
@@ -129,8 +135,8 @@ TOOLSIT CURSOR "toolsit.cur"
//
VS_VERSION_INFO VERSIONINFO
- FILEVERSION 2,1,1,0
- PRODUCTVERSION 2,1,1,0
+ FILEVERSION ${VIEWER_VERSION_MAJOR},${VIEWER_VERSION_MINOR},${VIEWER_VERSION_PATCH},${VIEWER_VERSION_REVISION}
+ PRODUCTVERSION ${VIEWER_VERSION_MAJOR},${VIEWER_VERSION_MINOR},${VIEWER_VERSION_PATCH},${VIEWER_VERSION_REVISION}
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -147,12 +153,12 @@ BEGIN
BEGIN
VALUE "CompanyName", "Linden Lab"
VALUE "FileDescription", "Second Life"
- VALUE "FileVersion", "2.1.1.0"
+ VALUE "FileVersion", "${VIEWER_VERSION_MAJOR}.${VIEWER_VERSION_MINOR}.${VIEWER_VERSION_PATCH}.${VIEWER_VERSION_REVISION}"
VALUE "InternalName", "Second Life"
- VALUE "LegalCopyright", "Copyright � 2001-2010, Linden Research, Inc."
+ VALUE "LegalCopyright", "Copyright � 2001, Linden Research, Inc."
VALUE "OriginalFilename", "SecondLife.exe"
VALUE "ProductName", "Second Life"
- VALUE "ProductVersion", "2.1.1.0"
+ VALUE "ProductVersion", "${VIEWER_VERSION_MAJOR}.${VIEWER_VERSION_MINOR}.${VIEWER_VERSION_PATCH}.${VIEWER_VERSION_REVISION}"
END
END
BLOCK "VarFileInfo"
diff --git a/indra/newview/ru.lproj/language.txt b/indra/newview/ru.lproj/language.txt
index adc719b423..adc719b423 100644..100755
--- a/indra/newview/ru.lproj/language.txt
+++ b/indra/newview/ru.lproj/language.txt
diff --git a/indra/newview/secondlife-i686.supp b/indra/newview/secondlife-i686.supp
index 863c8364ab..863c8364ab 100644..100755
--- a/indra/newview/secondlife-i686.supp
+++ b/indra/newview/secondlife-i686.supp
diff --git a/indra/newview/secondlife.icns b/indra/newview/secondlife.icns
index 4560d4bb24..4560d4bb24 100644..100755
--- a/indra/newview/secondlife.icns
+++ b/indra/newview/secondlife.icns
Binary files differ
diff --git a/indra/newview/secondlife_firstlook.icns b/indra/newview/secondlife_firstlook.icns
index 30497915c8..30497915c8 100644..100755
--- a/indra/newview/secondlife_firstlook.icns
+++ b/indra/newview/secondlife_firstlook.icns
Binary files differ
diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml
index b616e2327b..f53995732f 100644..100755
--- a/indra/newview/skins/default/colors.xml
+++ b/indra/newview/skins/default/colors.xml
@@ -12,6 +12,9 @@
name="EmphasisColor_35"
value="0.38 0.694 0.573 0.35" />
<color
+ name="BeaconColor"
+ value="0.749 0.298 0 1" />
+ <color
name="White"
value="1 1 1 1" />
<color
@@ -98,6 +101,27 @@
<color
name="MdBlue"
value=".07 .38 .51 1" />
+ <color
+ name="DkBlue"
+ value=".06 .06 .3 1" />
+ <color
+ name="LtRed"
+ value="1 0.2 0.2 1" />
+ <color
+ name="LtGreen"
+ value="0.2 1 0.2 1" />
+ <color
+ name="Red_80"
+ value="1 0 0 0.8" />
+ <color
+ name="DkRed"
+ value="0.3 0.06 0.06 1" />
+ <color
+ name="Green_80"
+ value="0 1 0 0.8" />
+ <color
+ name="Blue_80"
+ value="0 0 1 0.8" />
<!-- This color name makes potentially unused colors show up bright purple.
Leave this here until all Unused? are removed below, otherwise
@@ -508,6 +532,9 @@
name="MenuItemHighlightBgColor"
reference="EmphasisColor_35" />
<color
+ name="MenuItemFlashBgColor"
+ reference="BeaconColor" />
+ <color
name="MenuItemHighlightFgColor"
reference="White" />
<color
@@ -621,6 +648,36 @@
name="ParcelHoverColor"
reference="White" />
<color
+ name="PathfindingErrorColor"
+ reference="LtRed" />
+ <color
+ name="PathfindingWarningColor"
+ reference="DrYellow" />
+ <color
+ name="PathfindingGoodColor"
+ reference="LtGreen" />
+ <color
+ name="MaterialErrorColor"
+ reference="LtRed" />
+ <color
+ name="MaterialWarningColor"
+ reference="DrYellow" />
+ <color
+ name="MaterialGoodColor"
+ reference="LtGreen" />
+ <color
+ name="PathfindingDefaultBeaconColor"
+ reference="Red_80" />
+ <color
+ name="PathfindingDefaultBeaconTextColor"
+ reference="White" />
+ <color
+ name="PathfindingLinksetBeaconColor"
+ reference="Blue_80" />
+ <color
+ name="PathfindingCharacterBeaconColor"
+ reference="Red_80" />
+ <color
name="PieMenuBgColor"
value="0.24 0.24 0.24 0.59" />
<color
@@ -766,7 +823,7 @@
reference="LtGray" />
<color
name="UserChatColor"
- reference="White" />
+ reference="Yellow" />
<color
name="llOwnerSayChatColor"
reference="LtYellow" />
@@ -788,9 +845,14 @@
name="ChatTimestampColor"
reference="White" />
<color
+ name="MenuBarBetaBgColor"
+ reference="DkBlue" />
+ <color
name="MenuBarProjectBgColor"
reference="MdBlue" />
-
+ <color
+ name="MenuBarTestBgColor"
+ reference="DkRed" />
<color
name="MeshImportTableNormalColor"
value="1 1 1 1"/>
@@ -822,4 +884,19 @@
<color
name="blue"
value="0 0 1 1"/>
+
+ <!--Resize bar colors -->
+
+ <color
+ name="ResizebarBorderLight"
+ value="0.231 0.231 0.231 1"/>
+
+ <color
+ name="ResizebarBorderDark"
+ value="0.133 0.133 0.133 1"/>
+
+ <color
+ name="ResizebarBody"
+ value="0.208 0.208 0.208 1"/>
+
</colors>
diff --git a/indra/newview/skins/default/html/btn_purplepill_bg.png b/indra/newview/skins/default/html/btn_purplepill_bg.png
index b78127ae30..b78127ae30 100644..100755
--- a/indra/newview/skins/default/html/btn_purplepill_bg.png
+++ b/indra/newview/skins/default/html/btn_purplepill_bg.png
Binary files differ
diff --git a/indra/newview/skins/default/html/da/loading/loading.html b/indra/newview/skins/default/html/da/loading/loading.html
index 5f3426eb60..5f3426eb60 100644..100755
--- a/indra/newview/skins/default/html/da/loading/loading.html
+++ b/indra/newview/skins/default/html/da/loading/loading.html
diff --git a/indra/newview/skins/default/html/de/loading-error/index.html b/indra/newview/skins/default/html/de/loading-error/index.html
index fbde825b4a..fbde825b4a 100644..100755
--- a/indra/newview/skins/default/html/de/loading-error/index.html
+++ b/indra/newview/skins/default/html/de/loading-error/index.html
diff --git a/indra/newview/skins/default/html/de/loading/loading.html b/indra/newview/skins/default/html/de/loading/loading.html
index 44a621b216..44a621b216 100644..100755
--- a/indra/newview/skins/default/html/de/loading/loading.html
+++ b/indra/newview/skins/default/html/de/loading/loading.html
diff --git a/indra/newview/skins/default/html/en-us/help-offline/index.html b/indra/newview/skins/default/html/en-us/help-offline/index.html
index bf3677603e..bf3677603e 100644..100755
--- a/indra/newview/skins/default/html/en-us/help-offline/index.html
+++ b/indra/newview/skins/default/html/en-us/help-offline/index.html
diff --git a/indra/newview/skins/default/html/en-us/loading-error/index.html b/indra/newview/skins/default/html/en-us/loading-error/index.html
index 71f9c86f76..71f9c86f76 100644..100755
--- a/indra/newview/skins/default/html/en-us/loading-error/index.html
+++ b/indra/newview/skins/default/html/en-us/loading-error/index.html
diff --git a/indra/newview/skins/default/html/en-us/loading/loading.html b/indra/newview/skins/default/html/en-us/loading/loading.html
index 1c62d2f73e..1c62d2f73e 100644..100755
--- a/indra/newview/skins/default/html/en-us/loading/loading.html
+++ b/indra/newview/skins/default/html/en-us/loading/loading.html
diff --git a/indra/newview/skins/default/html/en-us/loading/sl_logo_rotate_black.gif b/indra/newview/skins/default/html/en-us/loading/sl_logo_rotate_black.gif
index e3ccc7c769..e3ccc7c769 100644..100755
--- a/indra/newview/skins/default/html/en-us/loading/sl_logo_rotate_black.gif
+++ b/indra/newview/skins/default/html/en-us/loading/sl_logo_rotate_black.gif
Binary files differ
diff --git a/indra/newview/skins/default/html/es/loading-error/index.html b/indra/newview/skins/default/html/es/loading-error/index.html
index c1e75bc475..c1e75bc475 100644..100755
--- a/indra/newview/skins/default/html/es/loading-error/index.html
+++ b/indra/newview/skins/default/html/es/loading-error/index.html
diff --git a/indra/newview/skins/default/html/es/loading/loading.html b/indra/newview/skins/default/html/es/loading/loading.html
index c4260b34c0..c4260b34c0 100644..100755
--- a/indra/newview/skins/default/html/es/loading/loading.html
+++ b/indra/newview/skins/default/html/es/loading/loading.html
diff --git a/indra/newview/skins/default/html/fr/loading-error/index.html b/indra/newview/skins/default/html/fr/loading-error/index.html
index 69c796cb55..69c796cb55 100644..100755
--- a/indra/newview/skins/default/html/fr/loading-error/index.html
+++ b/indra/newview/skins/default/html/fr/loading-error/index.html
diff --git a/indra/newview/skins/default/html/fr/loading/loading.html b/indra/newview/skins/default/html/fr/loading/loading.html
index b3953448e9..b3953448e9 100644..100755
--- a/indra/newview/skins/default/html/fr/loading/loading.html
+++ b/indra/newview/skins/default/html/fr/loading/loading.html
diff --git a/indra/newview/skins/default/html/hu/loading/loading.html b/indra/newview/skins/default/html/hu/loading/loading.html
index ab15a073ba..ab15a073ba 100644..100755
--- a/indra/newview/skins/default/html/hu/loading/loading.html
+++ b/indra/newview/skins/default/html/hu/loading/loading.html
diff --git a/indra/newview/skins/default/html/it/loading/loading.html b/indra/newview/skins/default/html/it/loading/loading.html
index ab37e41f04..ab37e41f04 100644..100755
--- a/indra/newview/skins/default/html/it/loading/loading.html
+++ b/indra/newview/skins/default/html/it/loading/loading.html
diff --git a/indra/newview/skins/default/html/ja/loading-error/index.html b/indra/newview/skins/default/html/ja/loading-error/index.html
index d969c03098..d969c03098 100644..100755
--- a/indra/newview/skins/default/html/ja/loading-error/index.html
+++ b/indra/newview/skins/default/html/ja/loading-error/index.html
diff --git a/indra/newview/skins/default/html/ja/loading/loading.html b/indra/newview/skins/default/html/ja/loading/loading.html
index 35cf74a35f..35cf74a35f 100644..100755
--- a/indra/newview/skins/default/html/ja/loading/loading.html
+++ b/indra/newview/skins/default/html/ja/loading/loading.html
diff --git a/indra/newview/skins/default/html/ko/loading-error/index.html b/indra/newview/skins/default/html/ko/loading-error/index.html
index 02b87132b9..02b87132b9 100644..100755
--- a/indra/newview/skins/default/html/ko/loading-error/index.html
+++ b/indra/newview/skins/default/html/ko/loading-error/index.html
diff --git a/indra/newview/skins/default/html/nl/loading/loading.html b/indra/newview/skins/default/html/nl/loading/loading.html
index 0215bd7e47..0215bd7e47 100644..100755
--- a/indra/newview/skins/default/html/nl/loading/loading.html
+++ b/indra/newview/skins/default/html/nl/loading/loading.html
diff --git a/indra/newview/skins/default/html/pl/loading/loading.html b/indra/newview/skins/default/html/pl/loading/loading.html
index 50f3dfb0c5..50f3dfb0c5 100644..100755
--- a/indra/newview/skins/default/html/pl/loading/loading.html
+++ b/indra/newview/skins/default/html/pl/loading/loading.html
diff --git a/indra/newview/skins/default/html/pt/loading-error/index.html b/indra/newview/skins/default/html/pt/loading-error/index.html
index 7f17b3a7bf..7f17b3a7bf 100644..100755
--- a/indra/newview/skins/default/html/pt/loading-error/index.html
+++ b/indra/newview/skins/default/html/pt/loading-error/index.html
diff --git a/indra/newview/skins/default/html/pt/loading/loading.html b/indra/newview/skins/default/html/pt/loading/loading.html
index a83e1123d0..a83e1123d0 100644..100755
--- a/indra/newview/skins/default/html/pt/loading/loading.html
+++ b/indra/newview/skins/default/html/pt/loading/loading.html
diff --git a/indra/newview/skins/default/html/ru/loading/loading.html b/indra/newview/skins/default/html/ru/loading/loading.html
index 892c0b9f7f..892c0b9f7f 100644..100755
--- a/indra/newview/skins/default/html/ru/loading/loading.html
+++ b/indra/newview/skins/default/html/ru/loading/loading.html
diff --git a/indra/newview/skins/default/html/tr/loading/loading.html b/indra/newview/skins/default/html/tr/loading/loading.html
index 1ac07bff34..1ac07bff34 100644..100755
--- a/indra/newview/skins/default/html/tr/loading/loading.html
+++ b/indra/newview/skins/default/html/tr/loading/loading.html
diff --git a/indra/newview/skins/default/html/uk/loading/loading.html b/indra/newview/skins/default/html/uk/loading/loading.html
index 3b5b8679b4..3b5b8679b4 100644..100755
--- a/indra/newview/skins/default/html/uk/loading/loading.html
+++ b/indra/newview/skins/default/html/uk/loading/loading.html
diff --git a/indra/newview/skins/default/html/unabletoconnect.png b/indra/newview/skins/default/html/unabletoconnect.png
index 1383516509..1383516509 100644..100755
--- a/indra/newview/skins/default/html/unabletoconnect.png
+++ b/indra/newview/skins/default/html/unabletoconnect.png
Binary files differ
diff --git a/indra/newview/skins/default/html/zh/loading-error/index.html b/indra/newview/skins/default/html/zh/loading-error/index.html
index 97201318ff..97201318ff 100644..100755
--- a/indra/newview/skins/default/html/zh/loading-error/index.html
+++ b/indra/newview/skins/default/html/zh/loading-error/index.html
diff --git a/indra/newview/skins/default/html/zh/loading/loading.html b/indra/newview/skins/default/html/zh/loading/loading.html
index d1d5d25c92..d1d5d25c92 100644..100755
--- a/indra/newview/skins/default/html/zh/loading/loading.html
+++ b/indra/newview/skins/default/html/zh/loading/loading.html
diff --git a/indra/newview/skins/default/textures/Blank.png b/indra/newview/skins/default/textures/Blank.png
index f38e9f9100..f38e9f9100 100644..100755
--- a/indra/newview/skins/default/textures/Blank.png
+++ b/indra/newview/skins/default/textures/Blank.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/Rounded_Rect.png b/indra/newview/skins/default/textures/Rounded_Rect.png
index c270c28039..c270c28039 100644..100755
--- a/indra/newview/skins/default/textures/Rounded_Rect.png
+++ b/indra/newview/skins/default/textures/Rounded_Rect.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/alpha_gradient.tga b/indra/newview/skins/default/textures/alpha_gradient.tga
index 6fdba25d4e..6fdba25d4e 100644..100755
--- a/indra/newview/skins/default/textures/alpha_gradient.tga
+++ b/indra/newview/skins/default/textures/alpha_gradient.tga
Binary files differ
diff --git a/indra/newview/skins/default/textures/alpha_gradient_2d.j2c b/indra/newview/skins/default/textures/alpha_gradient_2d.j2c
index 5de5a80a65..5de5a80a65 100644..100755
--- a/indra/newview/skins/default/textures/alpha_gradient_2d.j2c
+++ b/indra/newview/skins/default/textures/alpha_gradient_2d.j2c
Binary files differ
diff --git a/indra/newview/skins/default/textures/arrow_down.tga b/indra/newview/skins/default/textures/arrow_down.tga
index 81dc9d3b6c..81dc9d3b6c 100644..100755
--- a/indra/newview/skins/default/textures/arrow_down.tga
+++ b/indra/newview/skins/default/textures/arrow_down.tga
Binary files differ
diff --git a/indra/newview/skins/default/textures/arrow_up.tga b/indra/newview/skins/default/textures/arrow_up.tga
index 22195cf7fb..22195cf7fb 100644..100755
--- a/indra/newview/skins/default/textures/arrow_up.tga
+++ b/indra/newview/skins/default/textures/arrow_up.tga
Binary files differ
diff --git a/indra/newview/skins/default/textures/avatar_thumb_bkgrnd.png b/indra/newview/skins/default/textures/avatar_thumb_bkgrnd.png
index 84cc2159c1..84cc2159c1 100644..100755
--- a/indra/newview/skins/default/textures/avatar_thumb_bkgrnd.png
+++ b/indra/newview/skins/default/textures/avatar_thumb_bkgrnd.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/badge_note.j2c b/indra/newview/skins/default/textures/badge_note.j2c
index 1ab5233faf..1ab5233faf 100644..100755
--- a/indra/newview/skins/default/textures/badge_note.j2c
+++ b/indra/newview/skins/default/textures/badge_note.j2c
Binary files differ
diff --git a/indra/newview/skins/default/textures/badge_ok.j2c b/indra/newview/skins/default/textures/badge_ok.j2c
index f85b880f1d..f85b880f1d 100644..100755
--- a/indra/newview/skins/default/textures/badge_ok.j2c
+++ b/indra/newview/skins/default/textures/badge_ok.j2c
Binary files differ
diff --git a/indra/newview/skins/default/textures/badge_warn.j2c b/indra/newview/skins/default/textures/badge_warn.j2c
index 26437ca426..26437ca426 100644..100755
--- a/indra/newview/skins/default/textures/badge_warn.j2c
+++ b/indra/newview/skins/default/textures/badge_warn.j2c
Binary files differ
diff --git a/indra/newview/skins/default/textures/bottomtray/Cam_Avatar_Off.png b/indra/newview/skins/default/textures/bottomtray/Cam_Avatar_Off.png
index 6b725e153a..6b725e153a 100644..100755
--- a/indra/newview/skins/default/textures/bottomtray/Cam_Avatar_Off.png
+++ b/indra/newview/skins/default/textures/bottomtray/Cam_Avatar_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/bottomtray/Cam_FreeCam_Off.png b/indra/newview/skins/default/textures/bottomtray/Cam_FreeCam_Off.png
index 9f22080d13..9f22080d13 100644..100755
--- a/indra/newview/skins/default/textures/bottomtray/Cam_FreeCam_Off.png
+++ b/indra/newview/skins/default/textures/bottomtray/Cam_FreeCam_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/bottomtray/Cam_Orbit_Off.png b/indra/newview/skins/default/textures/bottomtray/Cam_Orbit_Off.png
index 5b2a8eb339..5b2a8eb339 100644..100755
--- a/indra/newview/skins/default/textures/bottomtray/Cam_Orbit_Off.png
+++ b/indra/newview/skins/default/textures/bottomtray/Cam_Orbit_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/bottomtray/Cam_Pan_Off.png b/indra/newview/skins/default/textures/bottomtray/Cam_Pan_Off.png
index 9acf7053d5..9acf7053d5 100644..100755
--- a/indra/newview/skins/default/textures/bottomtray/Cam_Pan_Off.png
+++ b/indra/newview/skins/default/textures/bottomtray/Cam_Pan_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/bottomtray/Cam_Preset_Back_Off.png b/indra/newview/skins/default/textures/bottomtray/Cam_Preset_Back_Off.png
index 00158a7bc2..00158a7bc2 100644..100755
--- a/indra/newview/skins/default/textures/bottomtray/Cam_Preset_Back_Off.png
+++ b/indra/newview/skins/default/textures/bottomtray/Cam_Preset_Back_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/bottomtray/Cam_Preset_Back_On.png b/indra/newview/skins/default/textures/bottomtray/Cam_Preset_Back_On.png
index 3748f5e190..3748f5e190 100644..100755
--- a/indra/newview/skins/default/textures/bottomtray/Cam_Preset_Back_On.png
+++ b/indra/newview/skins/default/textures/bottomtray/Cam_Preset_Back_On.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/bottomtray/Cam_Preset_Eye_Off.png b/indra/newview/skins/default/textures/bottomtray/Cam_Preset_Eye_Off.png
index 2b50986780..2b50986780 100644..100755
--- a/indra/newview/skins/default/textures/bottomtray/Cam_Preset_Eye_Off.png
+++ b/indra/newview/skins/default/textures/bottomtray/Cam_Preset_Eye_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/bottomtray/Cam_Preset_Front_Off.png b/indra/newview/skins/default/textures/bottomtray/Cam_Preset_Front_Off.png
index c49b8f9a27..c49b8f9a27 100644..100755
--- a/indra/newview/skins/default/textures/bottomtray/Cam_Preset_Front_Off.png
+++ b/indra/newview/skins/default/textures/bottomtray/Cam_Preset_Front_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/bottomtray/Cam_Preset_Front_On.png b/indra/newview/skins/default/textures/bottomtray/Cam_Preset_Front_On.png
index bc8c4db04d..bc8c4db04d 100644..100755
--- a/indra/newview/skins/default/textures/bottomtray/Cam_Preset_Front_On.png
+++ b/indra/newview/skins/default/textures/bottomtray/Cam_Preset_Front_On.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/bottomtray/Cam_Preset_Side_Off.png b/indra/newview/skins/default/textures/bottomtray/Cam_Preset_Side_Off.png
index b919a0a152..b919a0a152 100644..100755
--- a/indra/newview/skins/default/textures/bottomtray/Cam_Preset_Side_Off.png
+++ b/indra/newview/skins/default/textures/bottomtray/Cam_Preset_Side_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/bottomtray/Cam_Preset_Side_On.png b/indra/newview/skins/default/textures/bottomtray/Cam_Preset_Side_On.png
index de9da359a0..de9da359a0 100644..100755
--- a/indra/newview/skins/default/textures/bottomtray/Cam_Preset_Side_On.png
+++ b/indra/newview/skins/default/textures/bottomtray/Cam_Preset_Side_On.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/bottomtray/Cam_Rotate_In.png b/indra/newview/skins/default/textures/bottomtray/Cam_Rotate_In.png
index c8560c0869..c8560c0869 100644..100755
--- a/indra/newview/skins/default/textures/bottomtray/Cam_Rotate_In.png
+++ b/indra/newview/skins/default/textures/bottomtray/Cam_Rotate_In.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/bottomtray/Cam_Rotate_Out.png b/indra/newview/skins/default/textures/bottomtray/Cam_Rotate_Out.png
index b09f7c64d3..b09f7c64d3 100644..100755
--- a/indra/newview/skins/default/textures/bottomtray/Cam_Rotate_Out.png
+++ b/indra/newview/skins/default/textures/bottomtray/Cam_Rotate_Out.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/bottomtray/Cam_Tracking_In.png b/indra/newview/skins/default/textures/bottomtray/Cam_Tracking_In.png
index ae2c57c207..ae2c57c207 100644..100755
--- a/indra/newview/skins/default/textures/bottomtray/Cam_Tracking_In.png
+++ b/indra/newview/skins/default/textures/bottomtray/Cam_Tracking_In.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/bottomtray/Cam_Tracking_Out.png b/indra/newview/skins/default/textures/bottomtray/Cam_Tracking_Out.png
index c5cd8cca92..c5cd8cca92 100644..100755
--- a/indra/newview/skins/default/textures/bottomtray/Cam_Tracking_Out.png
+++ b/indra/newview/skins/default/textures/bottomtray/Cam_Tracking_Out.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/bottomtray/ChatBarHandle.png b/indra/newview/skins/default/textures/bottomtray/ChatBarHandle.png
index 8b58db0cba..8b58db0cba 100644..100755
--- a/indra/newview/skins/default/textures/bottomtray/ChatBarHandle.png
+++ b/indra/newview/skins/default/textures/bottomtray/ChatBarHandle.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/bottomtray/DownArrow.png b/indra/newview/skins/default/textures/bottomtray/DownArrow.png
index 82f58b22b9..82f58b22b9 100644..100755
--- a/indra/newview/skins/default/textures/bottomtray/DownArrow.png
+++ b/indra/newview/skins/default/textures/bottomtray/DownArrow.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/bottomtray/Mouselook_View_Off.png b/indra/newview/skins/default/textures/bottomtray/Mouselook_View_Off.png
index 8d32cad95f..8d32cad95f 100644..100755
--- a/indra/newview/skins/default/textures/bottomtray/Mouselook_View_Off.png
+++ b/indra/newview/skins/default/textures/bottomtray/Mouselook_View_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/bottomtray/Mouselook_View_On.png b/indra/newview/skins/default/textures/bottomtray/Mouselook_View_On.png
index 4c98e35868..4c98e35868 100644..100755
--- a/indra/newview/skins/default/textures/bottomtray/Mouselook_View_On.png
+++ b/indra/newview/skins/default/textures/bottomtray/Mouselook_View_On.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/bottomtray/Move_Fly_Off.png b/indra/newview/skins/default/textures/bottomtray/Move_Fly_Off.png
index 9e7291d6fb..9e7291d6fb 100644..100755
--- a/indra/newview/skins/default/textures/bottomtray/Move_Fly_Off.png
+++ b/indra/newview/skins/default/textures/bottomtray/Move_Fly_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/bottomtray/Move_Run_Off.png b/indra/newview/skins/default/textures/bottomtray/Move_Run_Off.png
index e2eb38e12d..e2eb38e12d 100644..100755
--- a/indra/newview/skins/default/textures/bottomtray/Move_Run_Off.png
+++ b/indra/newview/skins/default/textures/bottomtray/Move_Run_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/bottomtray/Move_Walk_Off.png b/indra/newview/skins/default/textures/bottomtray/Move_Walk_Off.png
index f314d4e001..f314d4e001 100644..100755
--- a/indra/newview/skins/default/textures/bottomtray/Move_Walk_Off.png
+++ b/indra/newview/skins/default/textures/bottomtray/Move_Walk_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/bottomtray/Movement_Backward_Off.png b/indra/newview/skins/default/textures/bottomtray/Movement_Backward_Off.png
index 4dddc2b391..4dddc2b391 100644..100755
--- a/indra/newview/skins/default/textures/bottomtray/Movement_Backward_Off.png
+++ b/indra/newview/skins/default/textures/bottomtray/Movement_Backward_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/bottomtray/Movement_Backward_On.png b/indra/newview/skins/default/textures/bottomtray/Movement_Backward_On.png
index 9f31d461b5..9f31d461b5 100644..100755
--- a/indra/newview/skins/default/textures/bottomtray/Movement_Backward_On.png
+++ b/indra/newview/skins/default/textures/bottomtray/Movement_Backward_On.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/bottomtray/Movement_Down_Off.png b/indra/newview/skins/default/textures/bottomtray/Movement_Down_Off.png
index 2893c9a9f1..2893c9a9f1 100644..100755
--- a/indra/newview/skins/default/textures/bottomtray/Movement_Down_Off.png
+++ b/indra/newview/skins/default/textures/bottomtray/Movement_Down_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/bottomtray/Movement_Down_On.png b/indra/newview/skins/default/textures/bottomtray/Movement_Down_On.png
index f7ed4c25fb..f7ed4c25fb 100644..100755
--- a/indra/newview/skins/default/textures/bottomtray/Movement_Down_On.png
+++ b/indra/newview/skins/default/textures/bottomtray/Movement_Down_On.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/bottomtray/Movement_Forward_Off.png b/indra/newview/skins/default/textures/bottomtray/Movement_Forward_Off.png
index 80d227b6a7..80d227b6a7 100644..100755
--- a/indra/newview/skins/default/textures/bottomtray/Movement_Forward_Off.png
+++ b/indra/newview/skins/default/textures/bottomtray/Movement_Forward_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/bottomtray/Movement_Forward_On.png b/indra/newview/skins/default/textures/bottomtray/Movement_Forward_On.png
index d0a825a682..d0a825a682 100644..100755
--- a/indra/newview/skins/default/textures/bottomtray/Movement_Forward_On.png
+++ b/indra/newview/skins/default/textures/bottomtray/Movement_Forward_On.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/bottomtray/Movement_Left_Off.png b/indra/newview/skins/default/textures/bottomtray/Movement_Left_Off.png
index 3602efa9d9..3602efa9d9 100644..100755
--- a/indra/newview/skins/default/textures/bottomtray/Movement_Left_Off.png
+++ b/indra/newview/skins/default/textures/bottomtray/Movement_Left_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/bottomtray/Movement_Left_On.png b/indra/newview/skins/default/textures/bottomtray/Movement_Left_On.png
index 2f81fb1588..2f81fb1588 100644..100755
--- a/indra/newview/skins/default/textures/bottomtray/Movement_Left_On.png
+++ b/indra/newview/skins/default/textures/bottomtray/Movement_Left_On.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/bottomtray/Movement_Right_Off.png b/indra/newview/skins/default/textures/bottomtray/Movement_Right_Off.png
index 9c3fc37dfe..9c3fc37dfe 100644..100755
--- a/indra/newview/skins/default/textures/bottomtray/Movement_Right_Off.png
+++ b/indra/newview/skins/default/textures/bottomtray/Movement_Right_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/bottomtray/Movement_Right_On.png b/indra/newview/skins/default/textures/bottomtray/Movement_Right_On.png
index 4f86e81a15..4f86e81a15 100644..100755
--- a/indra/newview/skins/default/textures/bottomtray/Movement_Right_On.png
+++ b/indra/newview/skins/default/textures/bottomtray/Movement_Right_On.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/bottomtray/Movement_TurnLeft_Off.png b/indra/newview/skins/default/textures/bottomtray/Movement_TurnLeft_Off.png
index 282e8d62de..282e8d62de 100644..100755
--- a/indra/newview/skins/default/textures/bottomtray/Movement_TurnLeft_Off.png
+++ b/indra/newview/skins/default/textures/bottomtray/Movement_TurnLeft_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/bottomtray/Movement_TurnLeft_On.png b/indra/newview/skins/default/textures/bottomtray/Movement_TurnLeft_On.png
index b211371e64..b211371e64 100644..100755
--- a/indra/newview/skins/default/textures/bottomtray/Movement_TurnLeft_On.png
+++ b/indra/newview/skins/default/textures/bottomtray/Movement_TurnLeft_On.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/bottomtray/Movement_TurnRight_Off.png b/indra/newview/skins/default/textures/bottomtray/Movement_TurnRight_Off.png
index 5039e57c32..5039e57c32 100644..100755
--- a/indra/newview/skins/default/textures/bottomtray/Movement_TurnRight_Off.png
+++ b/indra/newview/skins/default/textures/bottomtray/Movement_TurnRight_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/bottomtray/Movement_TurnRight_On.png b/indra/newview/skins/default/textures/bottomtray/Movement_TurnRight_On.png
index e937c3f012..e937c3f012 100644..100755
--- a/indra/newview/skins/default/textures/bottomtray/Movement_TurnRight_On.png
+++ b/indra/newview/skins/default/textures/bottomtray/Movement_TurnRight_On.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/bottomtray/Movement_Up_Off.png b/indra/newview/skins/default/textures/bottomtray/Movement_Up_Off.png
index a49c43c2cf..a49c43c2cf 100644..100755
--- a/indra/newview/skins/default/textures/bottomtray/Movement_Up_Off.png
+++ b/indra/newview/skins/default/textures/bottomtray/Movement_Up_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/bottomtray/Movement_Up_On.png b/indra/newview/skins/default/textures/bottomtray/Movement_Up_On.png
index ed4902f3ee..ed4902f3ee 100644..100755
--- a/indra/newview/skins/default/textures/bottomtray/Movement_Up_On.png
+++ b/indra/newview/skins/default/textures/bottomtray/Movement_Up_On.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/bottomtray/Notices_Unread.png b/indra/newview/skins/default/textures/bottomtray/Notices_Unread.png
index 0ac5b72b8f..0ac5b72b8f 100644..100755
--- a/indra/newview/skins/default/textures/bottomtray/Notices_Unread.png
+++ b/indra/newview/skins/default/textures/bottomtray/Notices_Unread.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/bottomtray/Object_View_Off.png b/indra/newview/skins/default/textures/bottomtray/Object_View_Off.png
index e9dea7e17e..e9dea7e17e 100644..100755
--- a/indra/newview/skins/default/textures/bottomtray/Object_View_Off.png
+++ b/indra/newview/skins/default/textures/bottomtray/Object_View_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/bottomtray/Object_View_On.png b/indra/newview/skins/default/textures/bottomtray/Object_View_On.png
index 7a348ba22e..7a348ba22e 100644..100755
--- a/indra/newview/skins/default/textures/bottomtray/Object_View_On.png
+++ b/indra/newview/skins/default/textures/bottomtray/Object_View_On.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/bottomtray/PanOrbit_Off.png b/indra/newview/skins/default/textures/bottomtray/PanOrbit_Off.png
index 53efa3a9a9..53efa3a9a9 100644..100755
--- a/indra/newview/skins/default/textures/bottomtray/PanOrbit_Off.png
+++ b/indra/newview/skins/default/textures/bottomtray/PanOrbit_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/bottomtray/Snapshot_Off.png b/indra/newview/skins/default/textures/bottomtray/Snapshot_Off.png
index d7ec04237b..d7ec04237b 100644..100755
--- a/indra/newview/skins/default/textures/bottomtray/Snapshot_Off.png
+++ b/indra/newview/skins/default/textures/bottomtray/Snapshot_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/bottomtray/Unread_Chiclet.png b/indra/newview/skins/default/textures/bottomtray/Unread_Chiclet.png
index e8fe243dc7..e8fe243dc7 100644..100755
--- a/indra/newview/skins/default/textures/bottomtray/Unread_Chiclet.png
+++ b/indra/newview/skins/default/textures/bottomtray/Unread_Chiclet.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/bottomtray/Unread_IM.png b/indra/newview/skins/default/textures/bottomtray/Unread_IM.png
deleted file mode 100644
index 5c0c85b864..0000000000
--- a/indra/newview/skins/default/textures/bottomtray/Unread_IM.png
+++ /dev/null
Binary files differ
diff --git a/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl1.png b/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl1.png
index cd18ae310d..cd18ae310d 100644..100755
--- a/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl1.png
+++ b/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl1.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl1_Dark.png b/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl1_Dark.png
deleted file mode 100644
index 857fa1e047..0000000000
--- a/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl1_Dark.png
+++ /dev/null
Binary files differ
diff --git a/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl2.png b/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl2.png
index b0ed6ee8eb..b0ed6ee8eb 100644..100755
--- a/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl2.png
+++ b/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl2.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl2_Dark.png b/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl2_Dark.png
deleted file mode 100644
index 453bb53673..0000000000
--- a/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl2_Dark.png
+++ /dev/null
Binary files differ
diff --git a/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl3.png b/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl3.png
index 14ec77b99a..14ec77b99a 100644..100755
--- a/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl3.png
+++ b/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl3.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl3_Dark.png b/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl3_Dark.png
deleted file mode 100644
index 135a66ca0d..0000000000
--- a/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl3_Dark.png
+++ /dev/null
Binary files differ
diff --git a/indra/newview/skins/default/textures/bottomtray/VoicePTT_Off.png b/indra/newview/skins/default/textures/bottomtray/VoicePTT_Off.png
index 48be51e9af..48be51e9af 100644..100755
--- a/indra/newview/skins/default/textures/bottomtray/VoicePTT_Off.png
+++ b/indra/newview/skins/default/textures/bottomtray/VoicePTT_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/bottomtray/VoicePTT_Off_Dark.png b/indra/newview/skins/default/textures/bottomtray/VoicePTT_Off_Dark.png
deleted file mode 100644
index a63aec5e6d..0000000000
--- a/indra/newview/skins/default/textures/bottomtray/VoicePTT_Off_Dark.png
+++ /dev/null
Binary files differ
diff --git a/indra/newview/skins/default/textures/bottomtray/VoicePTT_On.png b/indra/newview/skins/default/textures/bottomtray/VoicePTT_On.png
index be4881b64c..be4881b64c 100644..100755
--- a/indra/newview/skins/default/textures/bottomtray/VoicePTT_On.png
+++ b/indra/newview/skins/default/textures/bottomtray/VoicePTT_On.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/bottomtray/VoicePTT_On_Dark.png b/indra/newview/skins/default/textures/bottomtray/VoicePTT_On_Dark.png
deleted file mode 100644
index 1719eb3e84..0000000000
--- a/indra/newview/skins/default/textures/bottomtray/VoicePTT_On_Dark.png
+++ /dev/null
Binary files differ
diff --git a/indra/newview/skins/default/textures/bottomtray/WellButton_Lit.png b/indra/newview/skins/default/textures/bottomtray/WellButton_Lit.png
index 6cb33efb93..6cb33efb93 100644..100755
--- a/indra/newview/skins/default/textures/bottomtray/WellButton_Lit.png
+++ b/indra/newview/skins/default/textures/bottomtray/WellButton_Lit.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/bottomtray/WellButton_Lit_Selected.png b/indra/newview/skins/default/textures/bottomtray/WellButton_Lit_Selected.png
index 6cb33efb93..6cb33efb93 100644..100755
--- a/indra/newview/skins/default/textures/bottomtray/WellButton_Lit_Selected.png
+++ b/indra/newview/skins/default/textures/bottomtray/WellButton_Lit_Selected.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/build/Object_Cone.png b/indra/newview/skins/default/textures/build/Object_Cone.png
index 5167f1a820..5167f1a820 100644..100755
--- a/indra/newview/skins/default/textures/build/Object_Cone.png
+++ b/indra/newview/skins/default/textures/build/Object_Cone.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/build/Object_Cone_Selected.png b/indra/newview/skins/default/textures/build/Object_Cone_Selected.png
index d50dc69ffe..d50dc69ffe 100644..100755
--- a/indra/newview/skins/default/textures/build/Object_Cone_Selected.png
+++ b/indra/newview/skins/default/textures/build/Object_Cone_Selected.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/build/Object_Cube.png b/indra/newview/skins/default/textures/build/Object_Cube.png
index e82af1ca82..e82af1ca82 100644..100755
--- a/indra/newview/skins/default/textures/build/Object_Cube.png
+++ b/indra/newview/skins/default/textures/build/Object_Cube.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/build/Object_Cube_Selected.png b/indra/newview/skins/default/textures/build/Object_Cube_Selected.png
index 3d6964530d..3d6964530d 100644..100755
--- a/indra/newview/skins/default/textures/build/Object_Cube_Selected.png
+++ b/indra/newview/skins/default/textures/build/Object_Cube_Selected.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/build/Object_Cylinder.png b/indra/newview/skins/default/textures/build/Object_Cylinder.png
index fe1041d4c7..fe1041d4c7 100644..100755
--- a/indra/newview/skins/default/textures/build/Object_Cylinder.png
+++ b/indra/newview/skins/default/textures/build/Object_Cylinder.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/build/Object_Cylinder_Selected.png b/indra/newview/skins/default/textures/build/Object_Cylinder_Selected.png
index 3ed0389961..3ed0389961 100644..100755
--- a/indra/newview/skins/default/textures/build/Object_Cylinder_Selected.png
+++ b/indra/newview/skins/default/textures/build/Object_Cylinder_Selected.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/build/Object_Grass.png b/indra/newview/skins/default/textures/build/Object_Grass.png
index a88efd5f3e..a88efd5f3e 100644..100755
--- a/indra/newview/skins/default/textures/build/Object_Grass.png
+++ b/indra/newview/skins/default/textures/build/Object_Grass.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/build/Object_Grass_Selected.png b/indra/newview/skins/default/textures/build/Object_Grass_Selected.png
index 3ebd5ea7a1..3ebd5ea7a1 100644..100755
--- a/indra/newview/skins/default/textures/build/Object_Grass_Selected.png
+++ b/indra/newview/skins/default/textures/build/Object_Grass_Selected.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/build/Object_Hemi_Cone.png b/indra/newview/skins/default/textures/build/Object_Hemi_Cone.png
index 595f64d480..595f64d480 100644..100755
--- a/indra/newview/skins/default/textures/build/Object_Hemi_Cone.png
+++ b/indra/newview/skins/default/textures/build/Object_Hemi_Cone.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/build/Object_Hemi_Cone_Selected.png b/indra/newview/skins/default/textures/build/Object_Hemi_Cone_Selected.png
index 3bdc4d1fd5..3bdc4d1fd5 100644..100755
--- a/indra/newview/skins/default/textures/build/Object_Hemi_Cone_Selected.png
+++ b/indra/newview/skins/default/textures/build/Object_Hemi_Cone_Selected.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/build/Object_Hemi_Cylinder.png b/indra/newview/skins/default/textures/build/Object_Hemi_Cylinder.png
index dd41d56fb3..dd41d56fb3 100644..100755
--- a/indra/newview/skins/default/textures/build/Object_Hemi_Cylinder.png
+++ b/indra/newview/skins/default/textures/build/Object_Hemi_Cylinder.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/build/Object_Hemi_Cylinder_Selected.png b/indra/newview/skins/default/textures/build/Object_Hemi_Cylinder_Selected.png
index 0912442e29..0912442e29 100644..100755
--- a/indra/newview/skins/default/textures/build/Object_Hemi_Cylinder_Selected.png
+++ b/indra/newview/skins/default/textures/build/Object_Hemi_Cylinder_Selected.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/build/Object_Hemi_Sphere.png b/indra/newview/skins/default/textures/build/Object_Hemi_Sphere.png
index 1489630624..1489630624 100644..100755
--- a/indra/newview/skins/default/textures/build/Object_Hemi_Sphere.png
+++ b/indra/newview/skins/default/textures/build/Object_Hemi_Sphere.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/build/Object_Hemi_Sphere_Selected.png b/indra/newview/skins/default/textures/build/Object_Hemi_Sphere_Selected.png
index 33db4a2de8..33db4a2de8 100644..100755
--- a/indra/newview/skins/default/textures/build/Object_Hemi_Sphere_Selected.png
+++ b/indra/newview/skins/default/textures/build/Object_Hemi_Sphere_Selected.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/build/Object_Prism.png b/indra/newview/skins/default/textures/build/Object_Prism.png
index 51c6c161a0..51c6c161a0 100644..100755
--- a/indra/newview/skins/default/textures/build/Object_Prism.png
+++ b/indra/newview/skins/default/textures/build/Object_Prism.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/build/Object_Prism_Selected.png b/indra/newview/skins/default/textures/build/Object_Prism_Selected.png
index 9e80fe2b84..9e80fe2b84 100644..100755
--- a/indra/newview/skins/default/textures/build/Object_Prism_Selected.png
+++ b/indra/newview/skins/default/textures/build/Object_Prism_Selected.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/build/Object_Pyramid.png b/indra/newview/skins/default/textures/build/Object_Pyramid.png
index a147b59553..a147b59553 100644..100755
--- a/indra/newview/skins/default/textures/build/Object_Pyramid.png
+++ b/indra/newview/skins/default/textures/build/Object_Pyramid.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/build/Object_Pyramid_Selected.png b/indra/newview/skins/default/textures/build/Object_Pyramid_Selected.png
index d36bfa55d4..d36bfa55d4 100644..100755
--- a/indra/newview/skins/default/textures/build/Object_Pyramid_Selected.png
+++ b/indra/newview/skins/default/textures/build/Object_Pyramid_Selected.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/build/Object_Ring.png b/indra/newview/skins/default/textures/build/Object_Ring.png
index a9790fd60c..a9790fd60c 100644..100755
--- a/indra/newview/skins/default/textures/build/Object_Ring.png
+++ b/indra/newview/skins/default/textures/build/Object_Ring.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/build/Object_Ring_Selected.png b/indra/newview/skins/default/textures/build/Object_Ring_Selected.png
index 962f6efb93..962f6efb93 100644..100755
--- a/indra/newview/skins/default/textures/build/Object_Ring_Selected.png
+++ b/indra/newview/skins/default/textures/build/Object_Ring_Selected.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/build/Object_Sphere.png b/indra/newview/skins/default/textures/build/Object_Sphere.png
index 8e2dd92a82..8e2dd92a82 100644..100755
--- a/indra/newview/skins/default/textures/build/Object_Sphere.png
+++ b/indra/newview/skins/default/textures/build/Object_Sphere.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/build/Object_Sphere_Selected.png b/indra/newview/skins/default/textures/build/Object_Sphere_Selected.png
index 715d597144..715d597144 100644..100755
--- a/indra/newview/skins/default/textures/build/Object_Sphere_Selected.png
+++ b/indra/newview/skins/default/textures/build/Object_Sphere_Selected.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/build/Object_Tetrahedron.png b/indra/newview/skins/default/textures/build/Object_Tetrahedron.png
index 23e22b1796..23e22b1796 100644..100755
--- a/indra/newview/skins/default/textures/build/Object_Tetrahedron.png
+++ b/indra/newview/skins/default/textures/build/Object_Tetrahedron.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/build/Object_Tetrahedron_Selected.png b/indra/newview/skins/default/textures/build/Object_Tetrahedron_Selected.png
index b2ea680f23..b2ea680f23 100644..100755
--- a/indra/newview/skins/default/textures/build/Object_Tetrahedron_Selected.png
+++ b/indra/newview/skins/default/textures/build/Object_Tetrahedron_Selected.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/build/Object_Torus.png b/indra/newview/skins/default/textures/build/Object_Torus.png
index 15c62423a9..15c62423a9 100644..100755
--- a/indra/newview/skins/default/textures/build/Object_Torus.png
+++ b/indra/newview/skins/default/textures/build/Object_Torus.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/build/Object_Torus_Selected.png b/indra/newview/skins/default/textures/build/Object_Torus_Selected.png
index 1fc22686eb..1fc22686eb 100644..100755
--- a/indra/newview/skins/default/textures/build/Object_Torus_Selected.png
+++ b/indra/newview/skins/default/textures/build/Object_Torus_Selected.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/build/Object_Tree.png b/indra/newview/skins/default/textures/build/Object_Tree.png
index 82c422419b..82c422419b 100644..100755
--- a/indra/newview/skins/default/textures/build/Object_Tree.png
+++ b/indra/newview/skins/default/textures/build/Object_Tree.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/build/Object_Tree_Selected.png b/indra/newview/skins/default/textures/build/Object_Tree_Selected.png
index 5bd87f8a2f..5bd87f8a2f 100644..100755
--- a/indra/newview/skins/default/textures/build/Object_Tree_Selected.png
+++ b/indra/newview/skins/default/textures/build/Object_Tree_Selected.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/build/Object_Tube.png b/indra/newview/skins/default/textures/build/Object_Tube.png
index e47fce7511..e47fce7511 100644..100755
--- a/indra/newview/skins/default/textures/build/Object_Tube.png
+++ b/indra/newview/skins/default/textures/build/Object_Tube.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/build/Object_Tube_Selected.png b/indra/newview/skins/default/textures/build/Object_Tube_Selected.png
index a4c3f39e14..a4c3f39e14 100644..100755
--- a/indra/newview/skins/default/textures/build/Object_Tube_Selected.png
+++ b/indra/newview/skins/default/textures/build/Object_Tube_Selected.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/build/Tool_Create.png b/indra/newview/skins/default/textures/build/Tool_Create.png
index 1f1097def5..1f1097def5 100644..100755
--- a/indra/newview/skins/default/textures/build/Tool_Create.png
+++ b/indra/newview/skins/default/textures/build/Tool_Create.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/build/Tool_Dozer.png b/indra/newview/skins/default/textures/build/Tool_Dozer.png
index 61744666f4..61744666f4 100644..100755
--- a/indra/newview/skins/default/textures/build/Tool_Dozer.png
+++ b/indra/newview/skins/default/textures/build/Tool_Dozer.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/build/Tool_Face.png b/indra/newview/skins/default/textures/build/Tool_Face.png
index 5ab42a4ad6..5ab42a4ad6 100644..100755
--- a/indra/newview/skins/default/textures/build/Tool_Face.png
+++ b/indra/newview/skins/default/textures/build/Tool_Face.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/build/Tool_Grab.png b/indra/newview/skins/default/textures/build/Tool_Grab.png
index 5c58288d5e..5c58288d5e 100644..100755
--- a/indra/newview/skins/default/textures/build/Tool_Grab.png
+++ b/indra/newview/skins/default/textures/build/Tool_Grab.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/build/Tool_Zoom.png b/indra/newview/skins/default/textures/build/Tool_Zoom.png
index ad493b0d66..ad493b0d66 100644..100755
--- a/indra/newview/skins/default/textures/build/Tool_Zoom.png
+++ b/indra/newview/skins/default/textures/build/Tool_Zoom.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/button_anim_pause.tga b/indra/newview/skins/default/textures/button_anim_pause.tga
index 577f9195d0..577f9195d0 100644..100755
--- a/indra/newview/skins/default/textures/button_anim_pause.tga
+++ b/indra/newview/skins/default/textures/button_anim_pause.tga
Binary files differ
diff --git a/indra/newview/skins/default/textures/button_anim_pause_selected.tga b/indra/newview/skins/default/textures/button_anim_pause_selected.tga
index 21384316a8..21384316a8 100644..100755
--- a/indra/newview/skins/default/textures/button_anim_pause_selected.tga
+++ b/indra/newview/skins/default/textures/button_anim_pause_selected.tga
Binary files differ
diff --git a/indra/newview/skins/default/textures/button_anim_play.tga b/indra/newview/skins/default/textures/button_anim_play.tga
index 9ed55f829d..9ed55f829d 100644..100755
--- a/indra/newview/skins/default/textures/button_anim_play.tga
+++ b/indra/newview/skins/default/textures/button_anim_play.tga
Binary files differ
diff --git a/indra/newview/skins/default/textures/button_anim_play_selected.tga b/indra/newview/skins/default/textures/button_anim_play_selected.tga
index b166a4178d..b166a4178d 100644..100755
--- a/indra/newview/skins/default/textures/button_anim_play_selected.tga
+++ b/indra/newview/skins/default/textures/button_anim_play_selected.tga
Binary files differ
diff --git a/indra/newview/skins/default/textures/checker.png b/indra/newview/skins/default/textures/checker.png
index 1ab87e3f02..1ab87e3f02 100644..100755
--- a/indra/newview/skins/default/textures/checker.png
+++ b/indra/newview/skins/default/textures/checker.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/cloud-particle.j2c b/indra/newview/skins/default/textures/cloud-particle.j2c
index 6c03bf6d05..6c03bf6d05 100644..100755
--- a/indra/newview/skins/default/textures/cloud-particle.j2c
+++ b/indra/newview/skins/default/textures/cloud-particle.j2c
Binary files differ
diff --git a/indra/newview/skins/default/textures/color_swatch_alpha.tga b/indra/newview/skins/default/textures/color_swatch_alpha.tga
index 814a004e62..814a004e62 100644..100755
--- a/indra/newview/skins/default/textures/color_swatch_alpha.tga
+++ b/indra/newview/skins/default/textures/color_swatch_alpha.tga
Binary files differ
diff --git a/indra/newview/skins/default/textures/containers/Accordion_ArrowClosed_Off.png b/indra/newview/skins/default/textures/containers/Accordion_ArrowClosed_Off.png
index 19c842b816..19c842b816 100644..100755
--- a/indra/newview/skins/default/textures/containers/Accordion_ArrowClosed_Off.png
+++ b/indra/newview/skins/default/textures/containers/Accordion_ArrowClosed_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/containers/Accordion_ArrowClosed_Press.png b/indra/newview/skins/default/textures/containers/Accordion_ArrowClosed_Press.png
index b9879dcc8a..b9879dcc8a 100644..100755
--- a/indra/newview/skins/default/textures/containers/Accordion_ArrowClosed_Press.png
+++ b/indra/newview/skins/default/textures/containers/Accordion_ArrowClosed_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/containers/Accordion_ArrowOpened_Off.png b/indra/newview/skins/default/textures/containers/Accordion_ArrowOpened_Off.png
index d506cda5c9..d506cda5c9 100644..100755
--- a/indra/newview/skins/default/textures/containers/Accordion_ArrowOpened_Off.png
+++ b/indra/newview/skins/default/textures/containers/Accordion_ArrowOpened_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/containers/Accordion_ArrowOpened_Press.png b/indra/newview/skins/default/textures/containers/Accordion_ArrowOpened_Press.png
index 08f7493a02..08f7493a02 100644..100755
--- a/indra/newview/skins/default/textures/containers/Accordion_ArrowOpened_Press.png
+++ b/indra/newview/skins/default/textures/containers/Accordion_ArrowOpened_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/containers/Accordion_Off.png b/indra/newview/skins/default/textures/containers/Accordion_Off.png
index 414f4509c6..414f4509c6 100644..100755
--- a/indra/newview/skins/default/textures/containers/Accordion_Off.png
+++ b/indra/newview/skins/default/textures/containers/Accordion_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/containers/Accordion_Over.png b/indra/newview/skins/default/textures/containers/Accordion_Over.png
index 5416d73310..5416d73310 100644..100755
--- a/indra/newview/skins/default/textures/containers/Accordion_Over.png
+++ b/indra/newview/skins/default/textures/containers/Accordion_Over.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/containers/Accordion_Press.png b/indra/newview/skins/default/textures/containers/Accordion_Press.png
index 1578e0dfc5..1578e0dfc5 100644..100755
--- a/indra/newview/skins/default/textures/containers/Accordion_Press.png
+++ b/indra/newview/skins/default/textures/containers/Accordion_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/containers/Accordion_Selected.png b/indra/newview/skins/default/textures/containers/Accordion_Selected.png
index 0616dea6a3..0616dea6a3 100644..100755
--- a/indra/newview/skins/default/textures/containers/Accordion_Selected.png
+++ b/indra/newview/skins/default/textures/containers/Accordion_Selected.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/containers/Container.png b/indra/newview/skins/default/textures/containers/Container.png
index 511eb94386..511eb94386 100644..100755
--- a/indra/newview/skins/default/textures/containers/Container.png
+++ b/indra/newview/skins/default/textures/containers/Container.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/containers/TabTop_Left_Off.png b/indra/newview/skins/default/textures/containers/TabTop_Left_Off.png
index 1951413f8d..1951413f8d 100644..100755
--- a/indra/newview/skins/default/textures/containers/TabTop_Left_Off.png
+++ b/indra/newview/skins/default/textures/containers/TabTop_Left_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/containers/TabTop_Left_Selected.png b/indra/newview/skins/default/textures/containers/TabTop_Left_Selected.png
index 8364716e02..8364716e02 100644..100755
--- a/indra/newview/skins/default/textures/containers/TabTop_Left_Selected.png
+++ b/indra/newview/skins/default/textures/containers/TabTop_Left_Selected.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/containers/TabTop_Middle_Off.png b/indra/newview/skins/default/textures/containers/TabTop_Middle_Off.png
index 21f1c2d8a8..21f1c2d8a8 100644..100755
--- a/indra/newview/skins/default/textures/containers/TabTop_Middle_Off.png
+++ b/indra/newview/skins/default/textures/containers/TabTop_Middle_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/containers/TabTop_Middle_Selected.png b/indra/newview/skins/default/textures/containers/TabTop_Middle_Selected.png
index 3946917c7c..3946917c7c 100644..100755
--- a/indra/newview/skins/default/textures/containers/TabTop_Middle_Selected.png
+++ b/indra/newview/skins/default/textures/containers/TabTop_Middle_Selected.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/containers/TabTop_Right_Off.png b/indra/newview/skins/default/textures/containers/TabTop_Right_Off.png
index eeef28e5a5..eeef28e5a5 100644..100755
--- a/indra/newview/skins/default/textures/containers/TabTop_Right_Off.png
+++ b/indra/newview/skins/default/textures/containers/TabTop_Right_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/containers/TabTop_Right_Selected.png b/indra/newview/skins/default/textures/containers/TabTop_Right_Selected.png
index b0f1f16398..b0f1f16398 100644..100755
--- a/indra/newview/skins/default/textures/containers/TabTop_Right_Selected.png
+++ b/indra/newview/skins/default/textures/containers/TabTop_Right_Selected.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/containers/Toolbar_Left_Flash.png b/indra/newview/skins/default/textures/containers/Toolbar_Left_Flash.png
index 9f1e2a469d..9f1e2a469d 100644..100755
--- a/indra/newview/skins/default/textures/containers/Toolbar_Left_Flash.png
+++ b/indra/newview/skins/default/textures/containers/Toolbar_Left_Flash.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/containers/Toolbar_Left_Off.png b/indra/newview/skins/default/textures/containers/Toolbar_Left_Off.png
index 41b5d24d87..41b5d24d87 100644..100755
--- a/indra/newview/skins/default/textures/containers/Toolbar_Left_Off.png
+++ b/indra/newview/skins/default/textures/containers/Toolbar_Left_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/containers/Toolbar_Left_Over.png b/indra/newview/skins/default/textures/containers/Toolbar_Left_Over.png
index 083acc0156..083acc0156 100644..100755
--- a/indra/newview/skins/default/textures/containers/Toolbar_Left_Over.png
+++ b/indra/newview/skins/default/textures/containers/Toolbar_Left_Over.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/containers/Toolbar_Left_Selected.png b/indra/newview/skins/default/textures/containers/Toolbar_Left_Selected.png
index ee4649a8f9..ee4649a8f9 100644..100755
--- a/indra/newview/skins/default/textures/containers/Toolbar_Left_Selected.png
+++ b/indra/newview/skins/default/textures/containers/Toolbar_Left_Selected.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/containers/Toolbar_Middle_Flash.png b/indra/newview/skins/default/textures/containers/Toolbar_Middle_Flash.png
index dd73d655e9..dd73d655e9 100644..100755
--- a/indra/newview/skins/default/textures/containers/Toolbar_Middle_Flash.png
+++ b/indra/newview/skins/default/textures/containers/Toolbar_Middle_Flash.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/containers/Toolbar_Middle_Off.png b/indra/newview/skins/default/textures/containers/Toolbar_Middle_Off.png
index 55c02160e3..55c02160e3 100644..100755
--- a/indra/newview/skins/default/textures/containers/Toolbar_Middle_Off.png
+++ b/indra/newview/skins/default/textures/containers/Toolbar_Middle_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/containers/Toolbar_Middle_Over.png b/indra/newview/skins/default/textures/containers/Toolbar_Middle_Over.png
index 2f6ea90196..2f6ea90196 100644..100755
--- a/indra/newview/skins/default/textures/containers/Toolbar_Middle_Over.png
+++ b/indra/newview/skins/default/textures/containers/Toolbar_Middle_Over.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/containers/Toolbar_Middle_Selected.png b/indra/newview/skins/default/textures/containers/Toolbar_Middle_Selected.png
index 642113b135..642113b135 100644..100755
--- a/indra/newview/skins/default/textures/containers/Toolbar_Middle_Selected.png
+++ b/indra/newview/skins/default/textures/containers/Toolbar_Middle_Selected.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/containers/Toolbar_Right_Flash.png b/indra/newview/skins/default/textures/containers/Toolbar_Right_Flash.png
index f6b775c2a0..f6b775c2a0 100644..100755
--- a/indra/newview/skins/default/textures/containers/Toolbar_Right_Flash.png
+++ b/indra/newview/skins/default/textures/containers/Toolbar_Right_Flash.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/containers/Toolbar_Right_Off.png b/indra/newview/skins/default/textures/containers/Toolbar_Right_Off.png
index 01fd765c3d..01fd765c3d 100644..100755
--- a/indra/newview/skins/default/textures/containers/Toolbar_Right_Off.png
+++ b/indra/newview/skins/default/textures/containers/Toolbar_Right_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/containers/Toolbar_Right_Over.png b/indra/newview/skins/default/textures/containers/Toolbar_Right_Over.png
index 74e00635f1..74e00635f1 100644..100755
--- a/indra/newview/skins/default/textures/containers/Toolbar_Right_Over.png
+++ b/indra/newview/skins/default/textures/containers/Toolbar_Right_Over.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/containers/Toolbar_Right_Selected.png b/indra/newview/skins/default/textures/containers/Toolbar_Right_Selected.png
index 8a0d98a780..8a0d98a780 100644..100755
--- a/indra/newview/skins/default/textures/containers/Toolbar_Right_Selected.png
+++ b/indra/newview/skins/default/textures/containers/Toolbar_Right_Selected.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/crosshairs.tga b/indra/newview/skins/default/textures/crosshairs.tga
index ac4d63dc59..ac4d63dc59 100644..100755
--- a/indra/newview/skins/default/textures/crosshairs.tga
+++ b/indra/newview/skins/default/textures/crosshairs.tga
Binary files differ
diff --git a/indra/newview/skins/default/textures/default_land_picture.j2c b/indra/newview/skins/default/textures/default_land_picture.j2c
index 34df0291ae..34df0291ae 100644..100755
--- a/indra/newview/skins/default/textures/default_land_picture.j2c
+++ b/indra/newview/skins/default/textures/default_land_picture.j2c
Binary files differ
diff --git a/indra/newview/skins/default/textures/default_profile_picture.j2c b/indra/newview/skins/default/textures/default_profile_picture.j2c
index f21742cf09..f21742cf09 100644..100755
--- a/indra/newview/skins/default/textures/default_profile_picture.j2c
+++ b/indra/newview/skins/default/textures/default_profile_picture.j2c
Binary files differ
diff --git a/indra/newview/skins/default/textures/direction_arrow.tga b/indra/newview/skins/default/textures/direction_arrow.tga
index f3ef1068c4..f3ef1068c4 100644..100755
--- a/indra/newview/skins/default/textures/direction_arrow.tga
+++ b/indra/newview/skins/default/textures/direction_arrow.tga
Binary files differ
diff --git a/indra/newview/skins/default/textures/down_arrow.png b/indra/newview/skins/default/textures/down_arrow.png
index 155f80c97e..155f80c97e 100644..100755
--- a/indra/newview/skins/default/textures/down_arrow.png
+++ b/indra/newview/skins/default/textures/down_arrow.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/eye_button_active.tga b/indra/newview/skins/default/textures/eye_button_active.tga
index 014f785a7b..014f785a7b 100644..100755
--- a/indra/newview/skins/default/textures/eye_button_active.tga
+++ b/indra/newview/skins/default/textures/eye_button_active.tga
Binary files differ
diff --git a/indra/newview/skins/default/textures/eye_button_inactive.tga b/indra/newview/skins/default/textures/eye_button_inactive.tga
index 8666f0bbe6..8666f0bbe6 100644..100755
--- a/indra/newview/skins/default/textures/eye_button_inactive.tga
+++ b/indra/newview/skins/default/textures/eye_button_inactive.tga
Binary files differ
diff --git a/indra/newview/skins/default/textures/flatnormal.tga b/indra/newview/skins/default/textures/flatnormal.tga
new file mode 100644
index 0000000000..6d5abd1782
--- /dev/null
+++ b/indra/newview/skins/default/textures/flatnormal.tga
Binary files differ
diff --git a/indra/newview/skins/default/textures/folder_arrow.tga b/indra/newview/skins/default/textures/folder_arrow.tga
index 77d470731b..77d470731b 100644..100755
--- a/indra/newview/skins/default/textures/folder_arrow.tga
+++ b/indra/newview/skins/default/textures/folder_arrow.tga
Binary files differ
diff --git a/indra/newview/skins/default/textures/foot_shadow.j2c b/indra/newview/skins/default/textures/foot_shadow.j2c
index f9ce9da7d1..f9ce9da7d1 100644..100755
--- a/indra/newview/skins/default/textures/foot_shadow.j2c
+++ b/indra/newview/skins/default/textures/foot_shadow.j2c
Binary files differ
diff --git a/indra/newview/skins/default/textures/green_checkmark.png b/indra/newview/skins/default/textures/green_checkmark.png
index d2a5b348dc..d2a5b348dc 100644..100755
--- a/indra/newview/skins/default/textures/green_checkmark.png
+++ b/indra/newview/skins/default/textures/green_checkmark.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icn_media_movie.tga b/indra/newview/skins/default/textures/icn_media_movie.tga
index 43dd342c9d..43dd342c9d 100644..100755
--- a/indra/newview/skins/default/textures/icn_media_movie.tga
+++ b/indra/newview/skins/default/textures/icn_media_movie.tga
Binary files differ
diff --git a/indra/newview/skins/default/textures/icn_media_web.tga b/indra/newview/skins/default/textures/icn_media_web.tga
index 7c9131dfff..7c9131dfff 100644..100755
--- a/indra/newview/skins/default/textures/icn_media_web.tga
+++ b/indra/newview/skins/default/textures/icn_media_web.tga
Binary files differ
diff --git a/indra/newview/skins/default/textures/icon_avatar_offline.tga b/indra/newview/skins/default/textures/icon_avatar_offline.tga
index cfa95eb00e..cfa95eb00e 100644..100755
--- a/indra/newview/skins/default/textures/icon_avatar_offline.tga
+++ b/indra/newview/skins/default/textures/icon_avatar_offline.tga
Binary files differ
diff --git a/indra/newview/skins/default/textures/icon_avatar_online.tga b/indra/newview/skins/default/textures/icon_avatar_online.tga
index 45221213eb..45221213eb 100644..100755
--- a/indra/newview/skins/default/textures/icon_avatar_online.tga
+++ b/indra/newview/skins/default/textures/icon_avatar_online.tga
Binary files differ
diff --git a/indra/newview/skins/default/textures/icon_diurnal.tga b/indra/newview/skins/default/textures/icon_diurnal.tga
index fc720c8269..fc720c8269 100644..100755
--- a/indra/newview/skins/default/textures/icon_diurnal.tga
+++ b/indra/newview/skins/default/textures/icon_diurnal.tga
Binary files differ
diff --git a/indra/newview/skins/default/textures/icon_for_sale_adult.tga b/indra/newview/skins/default/textures/icon_for_sale_adult.tga
index 6a99188f87..6a99188f87 100644..100755
--- a/indra/newview/skins/default/textures/icon_for_sale_adult.tga
+++ b/indra/newview/skins/default/textures/icon_for_sale_adult.tga
Binary files differ
diff --git a/indra/newview/skins/default/textures/icon_top_pick.tga b/indra/newview/skins/default/textures/icon_top_pick.tga
index 0b34882d2f..0b34882d2f 100644..100755
--- a/indra/newview/skins/default/textures/icon_top_pick.tga
+++ b/indra/newview/skins/default/textures/icon_top_pick.tga
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/AddItem_Disabled.png b/indra/newview/skins/default/textures/icons/AddItem_Disabled.png
index cf88c89ae5..cf88c89ae5 100644..100755
--- a/indra/newview/skins/default/textures/icons/AddItem_Disabled.png
+++ b/indra/newview/skins/default/textures/icons/AddItem_Disabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/AddItem_Off.png b/indra/newview/skins/default/textures/icons/AddItem_Off.png
index 52d4f9bc80..52d4f9bc80 100644..100755
--- a/indra/newview/skins/default/textures/icons/AddItem_Off.png
+++ b/indra/newview/skins/default/textures/icons/AddItem_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/AddItem_Press.png b/indra/newview/skins/default/textures/icons/AddItem_Press.png
index acc898e5f4..acc898e5f4 100644..100755
--- a/indra/newview/skins/default/textures/icons/AddItem_Press.png
+++ b/indra/newview/skins/default/textures/icons/AddItem_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/AudioMute_Off.png b/indra/newview/skins/default/textures/icons/AudioMute_Off.png
index 938aaef491..938aaef491 100644..100755
--- a/indra/newview/skins/default/textures/icons/AudioMute_Off.png
+++ b/indra/newview/skins/default/textures/icons/AudioMute_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/AudioMute_Over.png b/indra/newview/skins/default/textures/icons/AudioMute_Over.png
index 7bd1b12aae..7bd1b12aae 100644..100755
--- a/indra/newview/skins/default/textures/icons/AudioMute_Over.png
+++ b/indra/newview/skins/default/textures/icons/AudioMute_Over.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Audio_Off.png b/indra/newview/skins/default/textures/icons/Audio_Off.png
index ef746aab92..ef746aab92 100644..100755
--- a/indra/newview/skins/default/textures/icons/Audio_Off.png
+++ b/indra/newview/skins/default/textures/icons/Audio_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Audio_Press.png b/indra/newview/skins/default/textures/icons/Audio_Press.png
index 25a669224a..25a669224a 100644..100755
--- a/indra/newview/skins/default/textures/icons/Audio_Press.png
+++ b/indra/newview/skins/default/textures/icons/Audio_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/BackArrow_Off.png b/indra/newview/skins/default/textures/icons/BackArrow_Off.png
index ff32192856..ff32192856 100644..100755
--- a/indra/newview/skins/default/textures/icons/BackArrow_Off.png
+++ b/indra/newview/skins/default/textures/icons/BackArrow_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Conv_log_inbox.png b/indra/newview/skins/default/textures/icons/Conv_log_inbox.png
new file mode 100755
index 0000000000..bb6ca28147
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/Conv_log_inbox.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Conv_toolbar_add_person.png b/indra/newview/skins/default/textures/icons/Conv_toolbar_add_person.png
new file mode 100644
index 0000000000..0631f16f3b
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/Conv_toolbar_add_person.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Conv_toolbar_arrow_ne.png b/indra/newview/skins/default/textures/icons/Conv_toolbar_arrow_ne.png
new file mode 100644
index 0000000000..578482f5ed
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/Conv_toolbar_arrow_ne.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Conv_toolbar_arrow_sw.png b/indra/newview/skins/default/textures/icons/Conv_toolbar_arrow_sw.png
new file mode 100644
index 0000000000..7676131790
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/Conv_toolbar_arrow_sw.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Conv_toolbar_call_log.png b/indra/newview/skins/default/textures/icons/Conv_toolbar_call_log.png
new file mode 100644
index 0000000000..2880eb766a
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/Conv_toolbar_call_log.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Conv_toolbar_close.png b/indra/newview/skins/default/textures/icons/Conv_toolbar_close.png
new file mode 100644
index 0000000000..d009c8f446
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/Conv_toolbar_close.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Conv_toolbar_collapse.png b/indra/newview/skins/default/textures/icons/Conv_toolbar_collapse.png
new file mode 100644
index 0000000000..8d82960e28
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/Conv_toolbar_collapse.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Conv_toolbar_expand.png b/indra/newview/skins/default/textures/icons/Conv_toolbar_expand.png
new file mode 100644
index 0000000000..f718d3fc60
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/Conv_toolbar_expand.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Conv_toolbar_hang_up.png b/indra/newview/skins/default/textures/icons/Conv_toolbar_hang_up.png
new file mode 100644
index 0000000000..315e2c581a
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/Conv_toolbar_hang_up.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Conv_toolbar_open_call.png b/indra/newview/skins/default/textures/icons/Conv_toolbar_open_call.png
new file mode 100644
index 0000000000..732ab02a20
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/Conv_toolbar_open_call.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Conv_toolbar_plus.png b/indra/newview/skins/default/textures/icons/Conv_toolbar_plus.png
new file mode 100644
index 0000000000..25a32cb2ba
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/Conv_toolbar_plus.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Conv_toolbar_sort.png b/indra/newview/skins/default/textures/icons/Conv_toolbar_sort.png
new file mode 100644
index 0000000000..08debeb91f
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/Conv_toolbar_sort.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Copy.png b/indra/newview/skins/default/textures/icons/Copy.png
index d45134e9dd..d45134e9dd 100644..100755
--- a/indra/newview/skins/default/textures/icons/Copy.png
+++ b/indra/newview/skins/default/textures/icons/Copy.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/DownArrow_Off.png b/indra/newview/skins/default/textures/icons/DownArrow_Off.png
index 60f62eed4a..60f62eed4a 100644..100755
--- a/indra/newview/skins/default/textures/icons/DownArrow_Off.png
+++ b/indra/newview/skins/default/textures/icons/DownArrow_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Edit_Wrench.png b/indra/newview/skins/default/textures/icons/Edit_Wrench.png
index edb40b9c96..edb40b9c96 100644..100755
--- a/indra/newview/skins/default/textures/icons/Edit_Wrench.png
+++ b/indra/newview/skins/default/textures/icons/Edit_Wrench.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/ExternalBrowser_Off.png b/indra/newview/skins/default/textures/icons/ExternalBrowser_Off.png
index 69646ce473..69646ce473 100644..100755
--- a/indra/newview/skins/default/textures/icons/ExternalBrowser_Off.png
+++ b/indra/newview/skins/default/textures/icons/ExternalBrowser_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Facebook.png b/indra/newview/skins/default/textures/icons/Facebook.png
new file mode 100644
index 0000000000..8287d56f88
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/Facebook.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Female.png b/indra/newview/skins/default/textures/icons/Female.png
index 67b5653a94..67b5653a94 100644..100755
--- a/indra/newview/skins/default/textures/icons/Female.png
+++ b/indra/newview/skins/default/textures/icons/Female.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/ForSale_Badge.png b/indra/newview/skins/default/textures/icons/ForSale_Badge.png
index 5bee570cee..5bee570cee 100644..100755
--- a/indra/newview/skins/default/textures/icons/ForSale_Badge.png
+++ b/indra/newview/skins/default/textures/icons/ForSale_Badge.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/ForwardArrow_Off.png b/indra/newview/skins/default/textures/icons/ForwardArrow_Off.png
index e9b72b0401..e9b72b0401 100644..100755
--- a/indra/newview/skins/default/textures/icons/ForwardArrow_Off.png
+++ b/indra/newview/skins/default/textures/icons/ForwardArrow_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/ForwardArrow_Press.png b/indra/newview/skins/default/textures/icons/ForwardArrow_Press.png
index c7b2c769ae..c7b2c769ae 100644..100755
--- a/indra/newview/skins/default/textures/icons/ForwardArrow_Press.png
+++ b/indra/newview/skins/default/textures/icons/ForwardArrow_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Generic_Group.png b/indra/newview/skins/default/textures/icons/Generic_Group.png
index 9d76f75d0f..9d76f75d0f 100644..100755
--- a/indra/newview/skins/default/textures/icons/Generic_Group.png
+++ b/indra/newview/skins/default/textures/icons/Generic_Group.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Generic_Group_Large.png b/indra/newview/skins/default/textures/icons/Generic_Group_Large.png
index 75833eccf3..75833eccf3 100644..100755
--- a/indra/newview/skins/default/textures/icons/Generic_Group_Large.png
+++ b/indra/newview/skins/default/textures/icons/Generic_Group_Large.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Generic_Object_Small.png b/indra/newview/skins/default/textures/icons/Generic_Object_Small.png
index 223874e631..223874e631 100644..100755
--- a/indra/newview/skins/default/textures/icons/Generic_Object_Small.png
+++ b/indra/newview/skins/default/textures/icons/Generic_Object_Small.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Generic_Person.png b/indra/newview/skins/default/textures/icons/Generic_Person.png
index 45b491ab59..45b491ab59 100644..100755
--- a/indra/newview/skins/default/textures/icons/Generic_Person.png
+++ b/indra/newview/skins/default/textures/icons/Generic_Person.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Generic_Person_Large.png b/indra/newview/skins/default/textures/icons/Generic_Person_Large.png
index 532288b430..532288b430 100644..100755
--- a/indra/newview/skins/default/textures/icons/Generic_Person_Large.png
+++ b/indra/newview/skins/default/textures/icons/Generic_Person_Large.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Hierarchy_View_Disabled.png b/indra/newview/skins/default/textures/icons/Hierarchy_View_Disabled.png
index fb370f98d5..fb370f98d5 100644..100755
--- a/indra/newview/skins/default/textures/icons/Hierarchy_View_Disabled.png
+++ b/indra/newview/skins/default/textures/icons/Hierarchy_View_Disabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Hierarchy_View_On.png b/indra/newview/skins/default/textures/icons/Hierarchy_View_On.png
index 296311e797..296311e797 100644..100755
--- a/indra/newview/skins/default/textures/icons/Hierarchy_View_On.png
+++ b/indra/newview/skins/default/textures/icons/Hierarchy_View_On.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Icon_For_Sale.png b/indra/newview/skins/default/textures/icons/Icon_For_Sale.png
index 3dec6b989c..3dec6b989c 100644..100755
--- a/indra/newview/skins/default/textures/icons/Icon_For_Sale.png
+++ b/indra/newview/skins/default/textures/icons/Icon_For_Sale.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Info.png b/indra/newview/skins/default/textures/icons/Info.png
index e52560281b..e52560281b 100644..100755
--- a/indra/newview/skins/default/textures/icons/Info.png
+++ b/indra/newview/skins/default/textures/icons/Info.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Info_Over.png b/indra/newview/skins/default/textures/icons/Info_Over.png
index be1cd0706f..be1cd0706f 100644..100755
--- a/indra/newview/skins/default/textures/icons/Info_Over.png
+++ b/indra/newview/skins/default/textures/icons/Info_Over.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Info_Small.png b/indra/newview/skins/default/textures/icons/Info_Small.png
index 81078c32dc..81078c32dc 100644..100755
--- a/indra/newview/skins/default/textures/icons/Info_Small.png
+++ b/indra/newview/skins/default/textures/icons/Info_Small.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Inv_Alpha.png b/indra/newview/skins/default/textures/icons/Inv_Alpha.png
index b65dc1929d..b65dc1929d 100644..100755
--- a/indra/newview/skins/default/textures/icons/Inv_Alpha.png
+++ b/indra/newview/skins/default/textures/icons/Inv_Alpha.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Inv_Animation.png b/indra/newview/skins/default/textures/icons/Inv_Animation.png
index ab42c61a92..ab42c61a92 100644..100755
--- a/indra/newview/skins/default/textures/icons/Inv_Animation.png
+++ b/indra/newview/skins/default/textures/icons/Inv_Animation.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Inv_BodyShape.png b/indra/newview/skins/default/textures/icons/Inv_BodyShape.png
index 97e874d70d..97e874d70d 100644..100755
--- a/indra/newview/skins/default/textures/icons/Inv_BodyShape.png
+++ b/indra/newview/skins/default/textures/icons/Inv_BodyShape.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Inv_CallingCard.png b/indra/newview/skins/default/textures/icons/Inv_CallingCard.png
index 1de96475f7..1de96475f7 100644..100755
--- a/indra/newview/skins/default/textures/icons/Inv_CallingCard.png
+++ b/indra/newview/skins/default/textures/icons/Inv_CallingCard.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Inv_Clothing.png b/indra/newview/skins/default/textures/icons/Inv_Clothing.png
index e8d246c6fa..e8d246c6fa 100644..100755
--- a/indra/newview/skins/default/textures/icons/Inv_Clothing.png
+++ b/indra/newview/skins/default/textures/icons/Inv_Clothing.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Inv_Eye.png b/indra/newview/skins/default/textures/icons/Inv_Eye.png
index e619f56c2b..e619f56c2b 100644..100755
--- a/indra/newview/skins/default/textures/icons/Inv_Eye.png
+++ b/indra/newview/skins/default/textures/icons/Inv_Eye.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Inv_FolderClosed.png b/indra/newview/skins/default/textures/icons/Inv_FolderClosed.png
index 342a973d00..342a973d00 100644..100755
--- a/indra/newview/skins/default/textures/icons/Inv_FolderClosed.png
+++ b/indra/newview/skins/default/textures/icons/Inv_FolderClosed.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Inv_FolderOpen.png b/indra/newview/skins/default/textures/icons/Inv_FolderOpen.png
index 0507c2cbaf..0507c2cbaf 100644..100755
--- a/indra/newview/skins/default/textures/icons/Inv_FolderOpen.png
+++ b/indra/newview/skins/default/textures/icons/Inv_FolderOpen.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Inv_Gesture.png b/indra/newview/skins/default/textures/icons/Inv_Gesture.png
index 52695ec19b..52695ec19b 100644..100755
--- a/indra/newview/skins/default/textures/icons/Inv_Gesture.png
+++ b/indra/newview/skins/default/textures/icons/Inv_Gesture.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Inv_Gloves.png b/indra/newview/skins/default/textures/icons/Inv_Gloves.png
index d6a2113aaf..d6a2113aaf 100644..100755
--- a/indra/newview/skins/default/textures/icons/Inv_Gloves.png
+++ b/indra/newview/skins/default/textures/icons/Inv_Gloves.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Inv_Hair.png b/indra/newview/skins/default/textures/icons/Inv_Hair.png
index ae941b0dd5..ae941b0dd5 100644..100755
--- a/indra/newview/skins/default/textures/icons/Inv_Hair.png
+++ b/indra/newview/skins/default/textures/icons/Inv_Hair.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Inv_Invalid.png b/indra/newview/skins/default/textures/icons/Inv_Invalid.png
index 328be104ee..328be104ee 100644..100755
--- a/indra/newview/skins/default/textures/icons/Inv_Invalid.png
+++ b/indra/newview/skins/default/textures/icons/Inv_Invalid.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Inv_Jacket.png b/indra/newview/skins/default/textures/icons/Inv_Jacket.png
index 3859666f7c..3859666f7c 100644..100755
--- a/indra/newview/skins/default/textures/icons/Inv_Jacket.png
+++ b/indra/newview/skins/default/textures/icons/Inv_Jacket.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Inv_Landmark.png b/indra/newview/skins/default/textures/icons/Inv_Landmark.png
index 76df984596..76df984596 100644..100755
--- a/indra/newview/skins/default/textures/icons/Inv_Landmark.png
+++ b/indra/newview/skins/default/textures/icons/Inv_Landmark.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Inv_Link.png b/indra/newview/skins/default/textures/icons/Inv_Link.png
index c1543dacb5..c1543dacb5 100644..100755
--- a/indra/newview/skins/default/textures/icons/Inv_Link.png
+++ b/indra/newview/skins/default/textures/icons/Inv_Link.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Inv_LinkFolder.png b/indra/newview/skins/default/textures/icons/Inv_LinkFolder.png
index 73a708782c..73a708782c 100644..100755
--- a/indra/newview/skins/default/textures/icons/Inv_LinkFolder.png
+++ b/indra/newview/skins/default/textures/icons/Inv_LinkFolder.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Inv_LinkItem.png b/indra/newview/skins/default/textures/icons/Inv_LinkItem.png
index 73a708782c..73a708782c 100644..100755
--- a/indra/newview/skins/default/textures/icons/Inv_LinkItem.png
+++ b/indra/newview/skins/default/textures/icons/Inv_LinkItem.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Inv_LookFolderClosed.png b/indra/newview/skins/default/textures/icons/Inv_LookFolderClosed.png
index f2ae828efc..f2ae828efc 100644..100755
--- a/indra/newview/skins/default/textures/icons/Inv_LookFolderClosed.png
+++ b/indra/newview/skins/default/textures/icons/Inv_LookFolderClosed.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Inv_LookFolderOpen.png b/indra/newview/skins/default/textures/icons/Inv_LookFolderOpen.png
index d454d4cd48..d454d4cd48 100644..100755
--- a/indra/newview/skins/default/textures/icons/Inv_LookFolderOpen.png
+++ b/indra/newview/skins/default/textures/icons/Inv_LookFolderOpen.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Inv_LostClosed.png b/indra/newview/skins/default/textures/icons/Inv_LostClosed.png
index a800217e0d..a800217e0d 100644..100755
--- a/indra/newview/skins/default/textures/icons/Inv_LostClosed.png
+++ b/indra/newview/skins/default/textures/icons/Inv_LostClosed.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Inv_LostOpen.png b/indra/newview/skins/default/textures/icons/Inv_LostOpen.png
index 8c4a1a9ac0..8c4a1a9ac0 100644..100755
--- a/indra/newview/skins/default/textures/icons/Inv_LostOpen.png
+++ b/indra/newview/skins/default/textures/icons/Inv_LostOpen.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Inv_Mesh.png b/indra/newview/skins/default/textures/icons/Inv_Mesh.png
index f1f21f7941..f1f21f7941 100644..100755
--- a/indra/newview/skins/default/textures/icons/Inv_Mesh.png
+++ b/indra/newview/skins/default/textures/icons/Inv_Mesh.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Inv_Notecard.png b/indra/newview/skins/default/textures/icons/Inv_Notecard.png
index 4645ab8e91..4645ab8e91 100644..100755
--- a/indra/newview/skins/default/textures/icons/Inv_Notecard.png
+++ b/indra/newview/skins/default/textures/icons/Inv_Notecard.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Inv_Object.png b/indra/newview/skins/default/textures/icons/Inv_Object.png
index f883696a82..f883696a82 100644..100755
--- a/indra/newview/skins/default/textures/icons/Inv_Object.png
+++ b/indra/newview/skins/default/textures/icons/Inv_Object.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Inv_Object_Multi.png b/indra/newview/skins/default/textures/icons/Inv_Object_Multi.png
index 11f4871ad8..11f4871ad8 100644..100755
--- a/indra/newview/skins/default/textures/icons/Inv_Object_Multi.png
+++ b/indra/newview/skins/default/textures/icons/Inv_Object_Multi.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Inv_Pants.png b/indra/newview/skins/default/textures/icons/Inv_Pants.png
index fe2389f074..fe2389f074 100644..100755
--- a/indra/newview/skins/default/textures/icons/Inv_Pants.png
+++ b/indra/newview/skins/default/textures/icons/Inv_Pants.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Inv_Physics.png b/indra/newview/skins/default/textures/icons/Inv_Physics.png
index 360baec46d..360baec46d 100644..100755
--- a/indra/newview/skins/default/textures/icons/Inv_Physics.png
+++ b/indra/newview/skins/default/textures/icons/Inv_Physics.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Inv_Script.png b/indra/newview/skins/default/textures/icons/Inv_Script.png
index 0fba27a7aa..0fba27a7aa 100644..100755
--- a/indra/newview/skins/default/textures/icons/Inv_Script.png
+++ b/indra/newview/skins/default/textures/icons/Inv_Script.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Inv_Shirt.png b/indra/newview/skins/default/textures/icons/Inv_Shirt.png
index 81c1538dd2..81c1538dd2 100644..100755
--- a/indra/newview/skins/default/textures/icons/Inv_Shirt.png
+++ b/indra/newview/skins/default/textures/icons/Inv_Shirt.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Inv_Shoe.png b/indra/newview/skins/default/textures/icons/Inv_Shoe.png
index 1f52b0a6b6..1f52b0a6b6 100644..100755
--- a/indra/newview/skins/default/textures/icons/Inv_Shoe.png
+++ b/indra/newview/skins/default/textures/icons/Inv_Shoe.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Inv_Skin.png b/indra/newview/skins/default/textures/icons/Inv_Skin.png
index b7da922046..b7da922046 100644..100755
--- a/indra/newview/skins/default/textures/icons/Inv_Skin.png
+++ b/indra/newview/skins/default/textures/icons/Inv_Skin.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Inv_Skirt.png b/indra/newview/skins/default/textures/icons/Inv_Skirt.png
index 246e9a87aa..246e9a87aa 100644..100755
--- a/indra/newview/skins/default/textures/icons/Inv_Skirt.png
+++ b/indra/newview/skins/default/textures/icons/Inv_Skirt.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Inv_Snapshot.png b/indra/newview/skins/default/textures/icons/Inv_Snapshot.png
index 39efd2be1b..39efd2be1b 100644..100755
--- a/indra/newview/skins/default/textures/icons/Inv_Snapshot.png
+++ b/indra/newview/skins/default/textures/icons/Inv_Snapshot.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Inv_Socks.png b/indra/newview/skins/default/textures/icons/Inv_Socks.png
index 30d7d7c239..30d7d7c239 100644..100755
--- a/indra/newview/skins/default/textures/icons/Inv_Socks.png
+++ b/indra/newview/skins/default/textures/icons/Inv_Socks.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Inv_Sound.png b/indra/newview/skins/default/textures/icons/Inv_Sound.png
index 44c271c868..44c271c868 100644..100755
--- a/indra/newview/skins/default/textures/icons/Inv_Sound.png
+++ b/indra/newview/skins/default/textures/icons/Inv_Sound.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Inv_SysClosed.png b/indra/newview/skins/default/textures/icons/Inv_SysClosed.png
index dcf998449f..dcf998449f 100644..100755
--- a/indra/newview/skins/default/textures/icons/Inv_SysClosed.png
+++ b/indra/newview/skins/default/textures/icons/Inv_SysClosed.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Inv_SysOpen.png b/indra/newview/skins/default/textures/icons/Inv_SysOpen.png
index 0efd403c95..0efd403c95 100644..100755
--- a/indra/newview/skins/default/textures/icons/Inv_SysOpen.png
+++ b/indra/newview/skins/default/textures/icons/Inv_SysOpen.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Inv_Tattoo.png b/indra/newview/skins/default/textures/icons/Inv_Tattoo.png
index a632197eb5..a632197eb5 100644..100755
--- a/indra/newview/skins/default/textures/icons/Inv_Tattoo.png
+++ b/indra/newview/skins/default/textures/icons/Inv_Tattoo.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Inv_Texture.png b/indra/newview/skins/default/textures/icons/Inv_Texture.png
index dbc41c5e99..dbc41c5e99 100644..100755
--- a/indra/newview/skins/default/textures/icons/Inv_Texture.png
+++ b/indra/newview/skins/default/textures/icons/Inv_Texture.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Inv_TrashClosed.png b/indra/newview/skins/default/textures/icons/Inv_TrashClosed.png
index c5201e6f9a..c5201e6f9a 100644..100755
--- a/indra/newview/skins/default/textures/icons/Inv_TrashClosed.png
+++ b/indra/newview/skins/default/textures/icons/Inv_TrashClosed.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Inv_TrashOpen.png b/indra/newview/skins/default/textures/icons/Inv_TrashOpen.png
index 4a886a3f37..4a886a3f37 100644..100755
--- a/indra/newview/skins/default/textures/icons/Inv_TrashOpen.png
+++ b/indra/newview/skins/default/textures/icons/Inv_TrashOpen.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Inv_Underpants.png b/indra/newview/skins/default/textures/icons/Inv_Underpants.png
index b1e7c2a55f..b1e7c2a55f 100644..100755
--- a/indra/newview/skins/default/textures/icons/Inv_Underpants.png
+++ b/indra/newview/skins/default/textures/icons/Inv_Underpants.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Inv_Undershirt.png b/indra/newview/skins/default/textures/icons/Inv_Undershirt.png
index 9340dbb975..9340dbb975 100644..100755
--- a/indra/newview/skins/default/textures/icons/Inv_Undershirt.png
+++ b/indra/newview/skins/default/textures/icons/Inv_Undershirt.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/List_View_Disabled.png b/indra/newview/skins/default/textures/icons/List_View_Disabled.png
index 155dee5047..155dee5047 100644..100755
--- a/indra/newview/skins/default/textures/icons/List_View_Disabled.png
+++ b/indra/newview/skins/default/textures/icons/List_View_Disabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/List_View_On.png b/indra/newview/skins/default/textures/icons/List_View_On.png
index 9127c92c3b..9127c92c3b 100644..100755
--- a/indra/newview/skins/default/textures/icons/List_View_On.png
+++ b/indra/newview/skins/default/textures/icons/List_View_On.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Lock.png b/indra/newview/skins/default/textures/icons/Lock.png
index eb5b5ae7a9..eb5b5ae7a9 100644..100755
--- a/indra/newview/skins/default/textures/icons/Lock.png
+++ b/indra/newview/skins/default/textures/icons/Lock.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Locked_Icon.png b/indra/newview/skins/default/textures/icons/Locked_Icon.png
index 8ead280794..8ead280794 100644..100755
--- a/indra/newview/skins/default/textures/icons/Locked_Icon.png
+++ b/indra/newview/skins/default/textures/icons/Locked_Icon.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Male.png b/indra/newview/skins/default/textures/icons/Male.png
index f3fad77fd0..f3fad77fd0 100644..100755
--- a/indra/newview/skins/default/textures/icons/Male.png
+++ b/indra/newview/skins/default/textures/icons/Male.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Microphone_On.png b/indra/newview/skins/default/textures/icons/Microphone_On.png
index c96b500fa1..c96b500fa1 100644..100755
--- a/indra/newview/skins/default/textures/icons/Microphone_On.png
+++ b/indra/newview/skins/default/textures/icons/Microphone_On.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/MinusItem_Disabled.png b/indra/newview/skins/default/textures/icons/MinusItem_Disabled.png
index 75bd73cef1..75bd73cef1 100644..100755
--- a/indra/newview/skins/default/textures/icons/MinusItem_Disabled.png
+++ b/indra/newview/skins/default/textures/icons/MinusItem_Disabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/MinusItem_Off.png b/indra/newview/skins/default/textures/icons/MinusItem_Off.png
index 6f285f3546..6f285f3546 100644..100755
--- a/indra/newview/skins/default/textures/icons/MinusItem_Off.png
+++ b/indra/newview/skins/default/textures/icons/MinusItem_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/MinusItem_Press.png b/indra/newview/skins/default/textures/icons/MinusItem_Press.png
index 50f65765d5..50f65765d5 100644..100755
--- a/indra/newview/skins/default/textures/icons/MinusItem_Press.png
+++ b/indra/newview/skins/default/textures/icons/MinusItem_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/OptionsMenu_Disabled.png b/indra/newview/skins/default/textures/icons/OptionsMenu_Disabled.png
index fb341e9c83..fb341e9c83 100644..100755
--- a/indra/newview/skins/default/textures/icons/OptionsMenu_Disabled.png
+++ b/indra/newview/skins/default/textures/icons/OptionsMenu_Disabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/OptionsMenu_Off.png b/indra/newview/skins/default/textures/icons/OptionsMenu_Off.png
index 25b055bfc0..25b055bfc0 100644..100755
--- a/indra/newview/skins/default/textures/icons/OptionsMenu_Off.png
+++ b/indra/newview/skins/default/textures/icons/OptionsMenu_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/OptionsMenu_Press.png b/indra/newview/skins/default/textures/icons/OptionsMenu_Press.png
index 6e91dd7159..6e91dd7159 100644..100755
--- a/indra/newview/skins/default/textures/icons/OptionsMenu_Press.png
+++ b/indra/newview/skins/default/textures/icons/OptionsMenu_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Disabled.png b/indra/newview/skins/default/textures/icons/OutboxPush_Disabled.png
index be58114aa1..be58114aa1 100644..100755
--- a/indra/newview/skins/default/textures/icons/OutboxPush_Disabled.png
+++ b/indra/newview/skins/default/textures/icons/OutboxPush_Disabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Off.png b/indra/newview/skins/default/textures/icons/OutboxPush_Off.png
index e6b9480ab1..e6b9480ab1 100644..100755
--- a/indra/newview/skins/default/textures/icons/OutboxPush_Off.png
+++ b/indra/newview/skins/default/textures/icons/OutboxPush_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_On.png b/indra/newview/skins/default/textures/icons/OutboxPush_On.png
index ffda2e92d4..ffda2e92d4 100644..100755
--- a/indra/newview/skins/default/textures/icons/OutboxPush_On.png
+++ b/indra/newview/skins/default/textures/icons/OutboxPush_On.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_On_Over.png b/indra/newview/skins/default/textures/icons/OutboxPush_On_Over.png
index 6b5911014f..6b5911014f 100644..100755
--- a/indra/newview/skins/default/textures/icons/OutboxPush_On_Over.png
+++ b/indra/newview/skins/default/textures/icons/OutboxPush_On_Over.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Over.png b/indra/newview/skins/default/textures/icons/OutboxPush_Over.png
index 9c26b92e73..9c26b92e73 100644..100755
--- a/indra/newview/skins/default/textures/icons/OutboxPush_Over.png
+++ b/indra/newview/skins/default/textures/icons/OutboxPush_Over.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Press.png b/indra/newview/skins/default/textures/icons/OutboxPush_Press.png
index 3b5d462975..3b5d462975 100644..100755
--- a/indra/newview/skins/default/textures/icons/OutboxPush_Press.png
+++ b/indra/newview/skins/default/textures/icons/OutboxPush_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Progress_1.png b/indra/newview/skins/default/textures/icons/OutboxPush_Progress_1.png
index f85be047b0..f85be047b0 100644..100755
--- a/indra/newview/skins/default/textures/icons/OutboxPush_Progress_1.png
+++ b/indra/newview/skins/default/textures/icons/OutboxPush_Progress_1.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Progress_2.png b/indra/newview/skins/default/textures/icons/OutboxPush_Progress_2.png
index cd4e482216..cd4e482216 100644..100755
--- a/indra/newview/skins/default/textures/icons/OutboxPush_Progress_2.png
+++ b/indra/newview/skins/default/textures/icons/OutboxPush_Progress_2.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Progress_3.png b/indra/newview/skins/default/textures/icons/OutboxPush_Progress_3.png
index d212a871ce..d212a871ce 100644..100755
--- a/indra/newview/skins/default/textures/icons/OutboxPush_Progress_3.png
+++ b/indra/newview/skins/default/textures/icons/OutboxPush_Progress_3.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Progress_4.png b/indra/newview/skins/default/textures/icons/OutboxPush_Progress_4.png
index e5b6023e36..e5b6023e36 100644..100755
--- a/indra/newview/skins/default/textures/icons/OutboxPush_Progress_4.png
+++ b/indra/newview/skins/default/textures/icons/OutboxPush_Progress_4.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Progress_5.png b/indra/newview/skins/default/textures/icons/OutboxPush_Progress_5.png
index e1911a092f..e1911a092f 100644..100755
--- a/indra/newview/skins/default/textures/icons/OutboxPush_Progress_5.png
+++ b/indra/newview/skins/default/textures/icons/OutboxPush_Progress_5.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Progress_6.png b/indra/newview/skins/default/textures/icons/OutboxPush_Progress_6.png
index 9e59f7843a..9e59f7843a 100644..100755
--- a/indra/newview/skins/default/textures/icons/OutboxPush_Progress_6.png
+++ b/indra/newview/skins/default/textures/icons/OutboxPush_Progress_6.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Selected.png b/indra/newview/skins/default/textures/icons/OutboxPush_Selected.png
index 51e8bff646..51e8bff646 100644..100755
--- a/indra/newview/skins/default/textures/icons/OutboxPush_Selected.png
+++ b/indra/newview/skins/default/textures/icons/OutboxPush_Selected.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Selected_Disabled.png b/indra/newview/skins/default/textures/icons/OutboxPush_Selected_Disabled.png
index 300e2e69e1..300e2e69e1 100644..100755
--- a/indra/newview/skins/default/textures/icons/OutboxPush_Selected_Disabled.png
+++ b/indra/newview/skins/default/textures/icons/OutboxPush_Selected_Disabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Selected_Over.png b/indra/newview/skins/default/textures/icons/OutboxPush_Selected_Over.png
index 32fb236381..32fb236381 100644..100755
--- a/indra/newview/skins/default/textures/icons/OutboxPush_Selected_Over.png
+++ b/indra/newview/skins/default/textures/icons/OutboxPush_Selected_Over.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Selected_Press.png b/indra/newview/skins/default/textures/icons/OutboxPush_Selected_Press.png
index 827f343b1e..827f343b1e 100644..100755
--- a/indra/newview/skins/default/textures/icons/OutboxPush_Selected_Press.png
+++ b/indra/newview/skins/default/textures/icons/OutboxPush_Selected_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Parcel_BuildNo_Dark.png b/indra/newview/skins/default/textures/icons/Parcel_BuildNo_Dark.png
index fb1f7d3a6d..fb1f7d3a6d 100644..100755
--- a/indra/newview/skins/default/textures/icons/Parcel_BuildNo_Dark.png
+++ b/indra/newview/skins/default/textures/icons/Parcel_BuildNo_Dark.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Parcel_BuildNo_Light.png b/indra/newview/skins/default/textures/icons/Parcel_BuildNo_Light.png
index e6f614b844..e6f614b844 100644..100755
--- a/indra/newview/skins/default/textures/icons/Parcel_BuildNo_Light.png
+++ b/indra/newview/skins/default/textures/icons/Parcel_BuildNo_Light.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Parcel_Build_Dark.png b/indra/newview/skins/default/textures/icons/Parcel_Build_Dark.png
index 84a96a60cb..84a96a60cb 100644..100755
--- a/indra/newview/skins/default/textures/icons/Parcel_Build_Dark.png
+++ b/indra/newview/skins/default/textures/icons/Parcel_Build_Dark.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Parcel_DamageNo_Dark.png b/indra/newview/skins/default/textures/icons/Parcel_DamageNo_Dark.png
index d55ebd7c67..d55ebd7c67 100644..100755
--- a/indra/newview/skins/default/textures/icons/Parcel_DamageNo_Dark.png
+++ b/indra/newview/skins/default/textures/icons/Parcel_DamageNo_Dark.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Parcel_Damage_Dark.png b/indra/newview/skins/default/textures/icons/Parcel_Damage_Dark.png
index ae4077488b..ae4077488b 100644..100755
--- a/indra/newview/skins/default/textures/icons/Parcel_Damage_Dark.png
+++ b/indra/newview/skins/default/textures/icons/Parcel_Damage_Dark.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Parcel_Exp_Color.png b/indra/newview/skins/default/textures/icons/Parcel_Exp_Color.png
index 4813d37198..4813d37198 100644..100755
--- a/indra/newview/skins/default/textures/icons/Parcel_Exp_Color.png
+++ b/indra/newview/skins/default/textures/icons/Parcel_Exp_Color.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Parcel_FlyNo_Dark.png b/indra/newview/skins/default/textures/icons/Parcel_FlyNo_Dark.png
index e0b18b2451..e0b18b2451 100644..100755
--- a/indra/newview/skins/default/textures/icons/Parcel_FlyNo_Dark.png
+++ b/indra/newview/skins/default/textures/icons/Parcel_FlyNo_Dark.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Parcel_FlyNo_Light.png b/indra/newview/skins/default/textures/icons/Parcel_FlyNo_Light.png
index 101aaa42b1..101aaa42b1 100644..100755
--- a/indra/newview/skins/default/textures/icons/Parcel_FlyNo_Light.png
+++ b/indra/newview/skins/default/textures/icons/Parcel_FlyNo_Light.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Parcel_Fly_Dark.png b/indra/newview/skins/default/textures/icons/Parcel_Fly_Dark.png
index c27f18e3c7..c27f18e3c7 100644..100755
--- a/indra/newview/skins/default/textures/icons/Parcel_Fly_Dark.png
+++ b/indra/newview/skins/default/textures/icons/Parcel_Fly_Dark.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Parcel_ForSale_Light.png b/indra/newview/skins/default/textures/icons/Parcel_ForSale_Light.png
index d28e5357df..d28e5357df 100644..100755
--- a/indra/newview/skins/default/textures/icons/Parcel_ForSale_Light.png
+++ b/indra/newview/skins/default/textures/icons/Parcel_ForSale_Light.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Parcel_Health_Dark.png b/indra/newview/skins/default/textures/icons/Parcel_Health_Dark.png
index d72f02f708..d72f02f708 100644..100755
--- a/indra/newview/skins/default/textures/icons/Parcel_Health_Dark.png
+++ b/indra/newview/skins/default/textures/icons/Parcel_Health_Dark.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Parcel_M_Dark.png b/indra/newview/skins/default/textures/icons/Parcel_M_Dark.png
index 60e6a00a25..60e6a00a25 100644..100755
--- a/indra/newview/skins/default/textures/icons/Parcel_M_Dark.png
+++ b/indra/newview/skins/default/textures/icons/Parcel_M_Dark.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Parcel_M_Light.png b/indra/newview/skins/default/textures/icons/Parcel_M_Light.png
index 55f97f3b4e..55f97f3b4e 100644..100755
--- a/indra/newview/skins/default/textures/icons/Parcel_M_Light.png
+++ b/indra/newview/skins/default/textures/icons/Parcel_M_Light.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Parcel_PG_Dark.png b/indra/newview/skins/default/textures/icons/Parcel_PG_Dark.png
index 11ab1f1e60..11ab1f1e60 100644..100755
--- a/indra/newview/skins/default/textures/icons/Parcel_PG_Dark.png
+++ b/indra/newview/skins/default/textures/icons/Parcel_PG_Dark.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Parcel_PG_Light.png b/indra/newview/skins/default/textures/icons/Parcel_PG_Light.png
index b536762ddc..b536762ddc 100644..100755
--- a/indra/newview/skins/default/textures/icons/Parcel_PG_Light.png
+++ b/indra/newview/skins/default/textures/icons/Parcel_PG_Light.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Parcel_PushNo_Dark.png b/indra/newview/skins/default/textures/icons/Parcel_PushNo_Dark.png
index 8f0fe6a04d..8f0fe6a04d 100644..100755
--- a/indra/newview/skins/default/textures/icons/Parcel_PushNo_Dark.png
+++ b/indra/newview/skins/default/textures/icons/Parcel_PushNo_Dark.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Parcel_PushNo_Light.png b/indra/newview/skins/default/textures/icons/Parcel_PushNo_Light.png
index eba7070b4d..eba7070b4d 100644..100755
--- a/indra/newview/skins/default/textures/icons/Parcel_PushNo_Light.png
+++ b/indra/newview/skins/default/textures/icons/Parcel_PushNo_Light.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Parcel_Push_Dark.png b/indra/newview/skins/default/textures/icons/Parcel_Push_Dark.png
index 08c2a18ac3..08c2a18ac3 100644..100755
--- a/indra/newview/skins/default/textures/icons/Parcel_Push_Dark.png
+++ b/indra/newview/skins/default/textures/icons/Parcel_Push_Dark.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Parcel_R_Dark.png b/indra/newview/skins/default/textures/icons/Parcel_R_Dark.png
index bf618752f6..bf618752f6 100644..100755
--- a/indra/newview/skins/default/textures/icons/Parcel_R_Dark.png
+++ b/indra/newview/skins/default/textures/icons/Parcel_R_Dark.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Parcel_R_Light.png b/indra/newview/skins/default/textures/icons/Parcel_R_Light.png
index a67bbd0cc5..a67bbd0cc5 100644..100755
--- a/indra/newview/skins/default/textures/icons/Parcel_R_Light.png
+++ b/indra/newview/skins/default/textures/icons/Parcel_R_Light.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Parcel_ScriptsNo_Dark.png b/indra/newview/skins/default/textures/icons/Parcel_ScriptsNo_Dark.png
index 8f9f37a1bf..8f9f37a1bf 100644..100755
--- a/indra/newview/skins/default/textures/icons/Parcel_ScriptsNo_Dark.png
+++ b/indra/newview/skins/default/textures/icons/Parcel_ScriptsNo_Dark.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Parcel_Scripts_Dark.png b/indra/newview/skins/default/textures/icons/Parcel_Scripts_Dark.png
index 8b1d6c5e14..8b1d6c5e14 100644..100755
--- a/indra/newview/skins/default/textures/icons/Parcel_Scripts_Dark.png
+++ b/indra/newview/skins/default/textures/icons/Parcel_Scripts_Dark.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Parcel_SeeAVsOff_Dark.png b/indra/newview/skins/default/textures/icons/Parcel_SeeAVsOff_Dark.png
index 956e02b14d..956e02b14d 100644..100755
--- a/indra/newview/skins/default/textures/icons/Parcel_SeeAVsOff_Dark.png
+++ b/indra/newview/skins/default/textures/icons/Parcel_SeeAVsOff_Dark.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Parcel_SeeAVsOff_Light.png b/indra/newview/skins/default/textures/icons/Parcel_SeeAVsOff_Light.png
index 434caeda8b..434caeda8b 100644..100755
--- a/indra/newview/skins/default/textures/icons/Parcel_SeeAVsOff_Light.png
+++ b/indra/newview/skins/default/textures/icons/Parcel_SeeAVsOff_Light.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Parcel_SeeAVsOn_Dark.png b/indra/newview/skins/default/textures/icons/Parcel_SeeAVsOn_Dark.png
index 064687ed0f..064687ed0f 100644..100755
--- a/indra/newview/skins/default/textures/icons/Parcel_SeeAVsOn_Dark.png
+++ b/indra/newview/skins/default/textures/icons/Parcel_SeeAVsOn_Dark.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Parcel_SeeAVsOn_Light.png b/indra/newview/skins/default/textures/icons/Parcel_SeeAVsOn_Light.png
index 5465650d0c..5465650d0c 100644..100755
--- a/indra/newview/skins/default/textures/icons/Parcel_SeeAVsOn_Light.png
+++ b/indra/newview/skins/default/textures/icons/Parcel_SeeAVsOn_Light.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Parcel_VoiceNo_Dark.png b/indra/newview/skins/default/textures/icons/Parcel_VoiceNo_Dark.png
index eace54ae79..eace54ae79 100644..100755
--- a/indra/newview/skins/default/textures/icons/Parcel_VoiceNo_Dark.png
+++ b/indra/newview/skins/default/textures/icons/Parcel_VoiceNo_Dark.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Parcel_VoiceNo_Light.png b/indra/newview/skins/default/textures/icons/Parcel_VoiceNo_Light.png
index 0d07e552b1..0d07e552b1 100644..100755
--- a/indra/newview/skins/default/textures/icons/Parcel_VoiceNo_Light.png
+++ b/indra/newview/skins/default/textures/icons/Parcel_VoiceNo_Light.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Parcel_Voice_Dark.png b/indra/newview/skins/default/textures/icons/Parcel_Voice_Dark.png
index b36a9bd2f0..b36a9bd2f0 100644..100755
--- a/indra/newview/skins/default/textures/icons/Parcel_Voice_Dark.png
+++ b/indra/newview/skins/default/textures/icons/Parcel_Voice_Dark.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Parcel_Voice_Light.png b/indra/newview/skins/default/textures/icons/Parcel_Voice_Light.png
index 86ce19474a..86ce19474a 100644..100755
--- a/indra/newview/skins/default/textures/icons/Parcel_Voice_Light.png
+++ b/indra/newview/skins/default/textures/icons/Parcel_Voice_Light.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Pathfinding_Dirty.png b/indra/newview/skins/default/textures/icons/Pathfinding_Dirty.png
new file mode 100755
index 0000000000..cfa12cb7cc
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/Pathfinding_Dirty.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Pathfinding_Disabled.png b/indra/newview/skins/default/textures/icons/Pathfinding_Disabled.png
new file mode 100755
index 0000000000..0622141848
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/Pathfinding_Disabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Pause_Off.png b/indra/newview/skins/default/textures/icons/Pause_Off.png
index 77f6be569d..77f6be569d 100644..100755
--- a/indra/newview/skins/default/textures/icons/Pause_Off.png
+++ b/indra/newview/skins/default/textures/icons/Pause_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Pause_Over.png b/indra/newview/skins/default/textures/icons/Pause_Over.png
index 580808bf7e..580808bf7e 100644..100755
--- a/indra/newview/skins/default/textures/icons/Pause_Over.png
+++ b/indra/newview/skins/default/textures/icons/Pause_Over.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Pause_Press.png b/indra/newview/skins/default/textures/icons/Pause_Press.png
index 859db34cae..859db34cae 100644..100755
--- a/indra/newview/skins/default/textures/icons/Pause_Press.png
+++ b/indra/newview/skins/default/textures/icons/Pause_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Person_Check.png b/indra/newview/skins/default/textures/icons/Person_Check.png
index f8638540d4..f8638540d4 100644..100755
--- a/indra/newview/skins/default/textures/icons/Person_Check.png
+++ b/indra/newview/skins/default/textures/icons/Person_Check.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Person_Star.png b/indra/newview/skins/default/textures/icons/Person_Star.png
index ad10580ac4..ad10580ac4 100644..100755
--- a/indra/newview/skins/default/textures/icons/Person_Star.png
+++ b/indra/newview/skins/default/textures/icons/Person_Star.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Play_Off.png b/indra/newview/skins/default/textures/icons/Play_Off.png
index e594c1a4cb..e594c1a4cb 100644..100755
--- a/indra/newview/skins/default/textures/icons/Play_Off.png
+++ b/indra/newview/skins/default/textures/icons/Play_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Play_Over.png b/indra/newview/skins/default/textures/icons/Play_Over.png
index 70ab94e8c2..70ab94e8c2 100644..100755
--- a/indra/newview/skins/default/textures/icons/Play_Over.png
+++ b/indra/newview/skins/default/textures/icons/Play_Over.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Play_Press.png b/indra/newview/skins/default/textures/icons/Play_Press.png
index b52742c6da..b52742c6da 100644..100755
--- a/indra/newview/skins/default/textures/icons/Play_Press.png
+++ b/indra/newview/skins/default/textures/icons/Play_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Progress_1.png b/indra/newview/skins/default/textures/icons/Progress_1.png
index 5d6efbfa2a..5d6efbfa2a 100644..100755
--- a/indra/newview/skins/default/textures/icons/Progress_1.png
+++ b/indra/newview/skins/default/textures/icons/Progress_1.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Progress_10.png b/indra/newview/skins/default/textures/icons/Progress_10.png
index 28203324f1..28203324f1 100644..100755
--- a/indra/newview/skins/default/textures/icons/Progress_10.png
+++ b/indra/newview/skins/default/textures/icons/Progress_10.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Progress_11.png b/indra/newview/skins/default/textures/icons/Progress_11.png
index 6b87be0c3f..6b87be0c3f 100644..100755
--- a/indra/newview/skins/default/textures/icons/Progress_11.png
+++ b/indra/newview/skins/default/textures/icons/Progress_11.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Progress_12.png b/indra/newview/skins/default/textures/icons/Progress_12.png
index 089d58b090..089d58b090 100644..100755
--- a/indra/newview/skins/default/textures/icons/Progress_12.png
+++ b/indra/newview/skins/default/textures/icons/Progress_12.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Progress_2.png b/indra/newview/skins/default/textures/icons/Progress_2.png
index 94cb73b1f7..94cb73b1f7 100644..100755
--- a/indra/newview/skins/default/textures/icons/Progress_2.png
+++ b/indra/newview/skins/default/textures/icons/Progress_2.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Progress_3.png b/indra/newview/skins/default/textures/icons/Progress_3.png
index a04a5b5263..a04a5b5263 100644..100755
--- a/indra/newview/skins/default/textures/icons/Progress_3.png
+++ b/indra/newview/skins/default/textures/icons/Progress_3.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Progress_4.png b/indra/newview/skins/default/textures/icons/Progress_4.png
index a467098d82..a467098d82 100644..100755
--- a/indra/newview/skins/default/textures/icons/Progress_4.png
+++ b/indra/newview/skins/default/textures/icons/Progress_4.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Progress_5.png b/indra/newview/skins/default/textures/icons/Progress_5.png
index ea64f1d907..ea64f1d907 100644..100755
--- a/indra/newview/skins/default/textures/icons/Progress_5.png
+++ b/indra/newview/skins/default/textures/icons/Progress_5.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Progress_6.png b/indra/newview/skins/default/textures/icons/Progress_6.png
index fe4447935f..fe4447935f 100644..100755
--- a/indra/newview/skins/default/textures/icons/Progress_6.png
+++ b/indra/newview/skins/default/textures/icons/Progress_6.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Progress_7.png b/indra/newview/skins/default/textures/icons/Progress_7.png
index 64fa294771..64fa294771 100644..100755
--- a/indra/newview/skins/default/textures/icons/Progress_7.png
+++ b/indra/newview/skins/default/textures/icons/Progress_7.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Progress_8.png b/indra/newview/skins/default/textures/icons/Progress_8.png
index a1c9a7f2eb..a1c9a7f2eb 100644..100755
--- a/indra/newview/skins/default/textures/icons/Progress_8.png
+++ b/indra/newview/skins/default/textures/icons/Progress_8.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Progress_9.png b/indra/newview/skins/default/textures/icons/Progress_9.png
index f3e9723184..f3e9723184 100644..100755
--- a/indra/newview/skins/default/textures/icons/Progress_9.png
+++ b/indra/newview/skins/default/textures/icons/Progress_9.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Refresh_Off.png b/indra/newview/skins/default/textures/icons/Refresh_Off.png
index a8acfda741..a8acfda741 100644..100755
--- a/indra/newview/skins/default/textures/icons/Refresh_Off.png
+++ b/indra/newview/skins/default/textures/icons/Refresh_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/SL_Logo.png b/indra/newview/skins/default/textures/icons/SL_Logo.png
index 8342d7cfee..8342d7cfee 100644..100755
--- a/indra/newview/skins/default/textures/icons/SL_Logo.png
+++ b/indra/newview/skins/default/textures/icons/SL_Logo.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Search_Icon.png b/indra/newview/skins/default/textures/icons/Search_Icon.png
index 541aa8f52a..541aa8f52a 100644..100755
--- a/indra/newview/skins/default/textures/icons/Search_Icon.png
+++ b/indra/newview/skins/default/textures/icons/Search_Icon.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Shirt_Large.png b/indra/newview/skins/default/textures/icons/Shirt_Large.png
index 0f3846bccc..0f3846bccc 100644..100755
--- a/indra/newview/skins/default/textures/icons/Shirt_Large.png
+++ b/indra/newview/skins/default/textures/icons/Shirt_Large.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Shop.png b/indra/newview/skins/default/textures/icons/Shop.png
index 81c13eeabd..81c13eeabd 100644..100755
--- a/indra/newview/skins/default/textures/icons/Shop.png
+++ b/indra/newview/skins/default/textures/icons/Shop.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/SkipBackward_Off.png b/indra/newview/skins/default/textures/icons/SkipBackward_Off.png
index 8fc10e6583..8fc10e6583 100644..100755
--- a/indra/newview/skins/default/textures/icons/SkipBackward_Off.png
+++ b/indra/newview/skins/default/textures/icons/SkipBackward_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/SkipForward_Off.png b/indra/newview/skins/default/textures/icons/SkipForward_Off.png
index 2892e3cfa9..2892e3cfa9 100644..100755
--- a/indra/newview/skins/default/textures/icons/SkipForward_Off.png
+++ b/indra/newview/skins/default/textures/icons/SkipForward_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/StopReload_Off.png b/indra/newview/skins/default/textures/icons/StopReload_Off.png
index 698569a540..698569a540 100644..100755
--- a/indra/newview/skins/default/textures/icons/StopReload_Off.png
+++ b/indra/newview/skins/default/textures/icons/StopReload_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/StopReload_Over.png b/indra/newview/skins/default/textures/icons/StopReload_Over.png
index 251b38630a..251b38630a 100644..100755
--- a/indra/newview/skins/default/textures/icons/StopReload_Over.png
+++ b/indra/newview/skins/default/textures/icons/StopReload_Over.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Stop_Off.png b/indra/newview/skins/default/textures/icons/Stop_Off.png
index 3ee215d36f..3ee215d36f 100644..100755
--- a/indra/newview/skins/default/textures/icons/Stop_Off.png
+++ b/indra/newview/skins/default/textures/icons/Stop_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Sync_Disabled.png b/indra/newview/skins/default/textures/icons/Sync_Disabled.png
index ca2e8def97..ca2e8def97 100644..100755
--- a/indra/newview/skins/default/textures/icons/Sync_Disabled.png
+++ b/indra/newview/skins/default/textures/icons/Sync_Disabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Sync_Enabled.png b/indra/newview/skins/default/textures/icons/Sync_Enabled.png
index bc236c8b98..bc236c8b98 100644..100755
--- a/indra/newview/skins/default/textures/icons/Sync_Enabled.png
+++ b/indra/newview/skins/default/textures/icons/Sync_Enabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Sync_Progress_1.png b/indra/newview/skins/default/textures/icons/Sync_Progress_1.png
index 624e556376..624e556376 100644..100755
--- a/indra/newview/skins/default/textures/icons/Sync_Progress_1.png
+++ b/indra/newview/skins/default/textures/icons/Sync_Progress_1.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Sync_Progress_2.png b/indra/newview/skins/default/textures/icons/Sync_Progress_2.png
index 5769803b3f..5769803b3f 100644..100755
--- a/indra/newview/skins/default/textures/icons/Sync_Progress_2.png
+++ b/indra/newview/skins/default/textures/icons/Sync_Progress_2.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Sync_Progress_3.png b/indra/newview/skins/default/textures/icons/Sync_Progress_3.png
index 92d4bfb020..92d4bfb020 100644..100755
--- a/indra/newview/skins/default/textures/icons/Sync_Progress_3.png
+++ b/indra/newview/skins/default/textures/icons/Sync_Progress_3.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Sync_Progress_4.png b/indra/newview/skins/default/textures/icons/Sync_Progress_4.png
index 6d43eb3a9f..6d43eb3a9f 100644..100755
--- a/indra/newview/skins/default/textures/icons/Sync_Progress_4.png
+++ b/indra/newview/skins/default/textures/icons/Sync_Progress_4.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Sync_Progress_5.png b/indra/newview/skins/default/textures/icons/Sync_Progress_5.png
index 766d063c99..766d063c99 100644..100755
--- a/indra/newview/skins/default/textures/icons/Sync_Progress_5.png
+++ b/indra/newview/skins/default/textures/icons/Sync_Progress_5.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Sync_Progress_6.png b/indra/newview/skins/default/textures/icons/Sync_Progress_6.png
index dfe7f68b72..dfe7f68b72 100644..100755
--- a/indra/newview/skins/default/textures/icons/Sync_Progress_6.png
+++ b/indra/newview/skins/default/textures/icons/Sync_Progress_6.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/TrashItem_Disabled.png b/indra/newview/skins/default/textures/icons/TrashItem_Disabled.png
index caaf45a99f..caaf45a99f 100644..100755
--- a/indra/newview/skins/default/textures/icons/TrashItem_Disabled.png
+++ b/indra/newview/skins/default/textures/icons/TrashItem_Disabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/TrashItem_Off.png b/indra/newview/skins/default/textures/icons/TrashItem_Off.png
index bb64920ec4..bb64920ec4 100644..100755
--- a/indra/newview/skins/default/textures/icons/TrashItem_Off.png
+++ b/indra/newview/skins/default/textures/icons/TrashItem_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/TrashItem_Press.png b/indra/newview/skins/default/textures/icons/TrashItem_Press.png
index c62f833d86..c62f833d86 100644..100755
--- a/indra/newview/skins/default/textures/icons/TrashItem_Press.png
+++ b/indra/newview/skins/default/textures/icons/TrashItem_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/UnZoom_Off.png b/indra/newview/skins/default/textures/icons/UnZoom_Off.png
index c794113755..c794113755 100644..100755
--- a/indra/newview/skins/default/textures/icons/UnZoom_Off.png
+++ b/indra/newview/skins/default/textures/icons/UnZoom_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/UpArrow_Off.png b/indra/newview/skins/default/textures/icons/UpArrow_Off.png
index 00015bce20..00015bce20 100644..100755
--- a/indra/newview/skins/default/textures/icons/UpArrow_Off.png
+++ b/indra/newview/skins/default/textures/icons/UpArrow_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/VoicePTT_Lvl1.png b/indra/newview/skins/default/textures/icons/VoicePTT_Lvl1.png
index cd18ae310d..cd18ae310d 100644..100755
--- a/indra/newview/skins/default/textures/icons/VoicePTT_Lvl1.png
+++ b/indra/newview/skins/default/textures/icons/VoicePTT_Lvl1.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/VoicePTT_Lvl2.png b/indra/newview/skins/default/textures/icons/VoicePTT_Lvl2.png
index b0ed6ee8eb..b0ed6ee8eb 100644..100755
--- a/indra/newview/skins/default/textures/icons/VoicePTT_Lvl2.png
+++ b/indra/newview/skins/default/textures/icons/VoicePTT_Lvl2.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/VoicePTT_Lvl3.png b/indra/newview/skins/default/textures/icons/VoicePTT_Lvl3.png
index 14ec77b99a..14ec77b99a 100644..100755
--- a/indra/newview/skins/default/textures/icons/VoicePTT_Lvl3.png
+++ b/indra/newview/skins/default/textures/icons/VoicePTT_Lvl3.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/VoicePTT_Off.png b/indra/newview/skins/default/textures/icons/VoicePTT_Off.png
index 48be51e9af..48be51e9af 100644..100755
--- a/indra/newview/skins/default/textures/icons/VoicePTT_Off.png
+++ b/indra/newview/skins/default/textures/icons/VoicePTT_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/VoicePTT_On.png b/indra/newview/skins/default/textures/icons/VoicePTT_On.png
index be4881b64c..be4881b64c 100644..100755
--- a/indra/newview/skins/default/textures/icons/VoicePTT_On.png
+++ b/indra/newview/skins/default/textures/icons/VoicePTT_On.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Web_Profile_Off.png b/indra/newview/skins/default/textures/icons/Web_Profile_Off.png
index f5fb774a6f..f5fb774a6f 100644..100755
--- a/indra/newview/skins/default/textures/icons/Web_Profile_Off.png
+++ b/indra/newview/skins/default/textures/icons/Web_Profile_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/YouAreHere_Badge.png b/indra/newview/skins/default/textures/icons/YouAreHere_Badge.png
index c057e9743d..c057e9743d 100644..100755
--- a/indra/newview/skins/default/textures/icons/YouAreHere_Badge.png
+++ b/indra/newview/skins/default/textures/icons/YouAreHere_Badge.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Zoom_Off.png b/indra/newview/skins/default/textures/icons/Zoom_Off.png
index d096720c9c..d096720c9c 100644..100755
--- a/indra/newview/skins/default/textures/icons/Zoom_Off.png
+++ b/indra/newview/skins/default/textures/icons/Zoom_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/avaline_default_icon.jpg b/indra/newview/skins/default/textures/icons/avaline_default_icon.jpg
index 3bb7f7183c..3bb7f7183c 100644..100755
--- a/indra/newview/skins/default/textures/icons/avaline_default_icon.jpg
+++ b/indra/newview/skins/default/textures/icons/avaline_default_icon.jpg
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/back_arrow_off.png b/indra/newview/skins/default/textures/icons/back_arrow_off.png
index 422f67cf83..422f67cf83 100644..100755
--- a/indra/newview/skins/default/textures/icons/back_arrow_off.png
+++ b/indra/newview/skins/default/textures/icons/back_arrow_off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/back_arrow_over.png b/indra/newview/skins/default/textures/icons/back_arrow_over.png
index b4cc170f37..b4cc170f37 100644..100755
--- a/indra/newview/skins/default/textures/icons/back_arrow_over.png
+++ b/indra/newview/skins/default/textures/icons/back_arrow_over.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/back_arrow_press.png b/indra/newview/skins/default/textures/icons/back_arrow_press.png
index a9e2f326a7..a9e2f326a7 100644..100755
--- a/indra/newview/skins/default/textures/icons/back_arrow_press.png
+++ b/indra/newview/skins/default/textures/icons/back_arrow_press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/check_mark.png b/indra/newview/skins/default/textures/icons/check_mark.png
index 2c05297f4f..2c05297f4f 100644..100755
--- a/indra/newview/skins/default/textures/icons/check_mark.png
+++ b/indra/newview/skins/default/textures/icons/check_mark.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/collapse_to_one_line.png b/indra/newview/skins/default/textures/icons/collapse_to_one_line.png
new file mode 100755
index 0000000000..d57144a645
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/collapse_to_one_line.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/edit_mine.png b/indra/newview/skins/default/textures/icons/edit_mine.png
index a0bc7efd25..a0bc7efd25 100644..100755
--- a/indra/newview/skins/default/textures/icons/edit_mine.png
+++ b/indra/newview/skins/default/textures/icons/edit_mine.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/edit_theirs.png b/indra/newview/skins/default/textures/icons/edit_theirs.png
index ed36ad7cfc..ed36ad7cfc 100644..100755
--- a/indra/newview/skins/default/textures/icons/edit_theirs.png
+++ b/indra/newview/skins/default/textures/icons/edit_theirs.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/expand_one_liner.png b/indra/newview/skins/default/textures/icons/expand_one_liner.png
new file mode 100755
index 0000000000..58b7d90131
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/expand_one_liner.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/map_placeholder.png b/indra/newview/skins/default/textures/icons/map_placeholder.png
new file mode 100644
index 0000000000..31e457aa75
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/map_placeholder.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/nearby_chat_icon.png b/indra/newview/skins/default/textures/icons/nearby_chat_icon.png
new file mode 100755
index 0000000000..5ac4258b9d
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/nearby_chat_icon.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/object_icon.png b/indra/newview/skins/default/textures/icons/object_icon.png
index 223874e631..223874e631 100644..100755
--- a/indra/newview/skins/default/textures/icons/object_icon.png
+++ b/indra/newview/skins/default/textures/icons/object_icon.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/pop_up_caution.png b/indra/newview/skins/default/textures/icons/pop_up_caution.png
index 78b681cb33..78b681cb33 100644..100755
--- a/indra/newview/skins/default/textures/icons/pop_up_caution.png
+++ b/indra/newview/skins/default/textures/icons/pop_up_caution.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/see_me_online.png b/indra/newview/skins/default/textures/icons/see_me_online.png
index 52dc2ae74f..52dc2ae74f 100644..100755
--- a/indra/newview/skins/default/textures/icons/see_me_online.png
+++ b/indra/newview/skins/default/textures/icons/see_me_online.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/see_on_map.png b/indra/newview/skins/default/textures/icons/see_on_map.png
index 200e649818..200e649818 100644..100755
--- a/indra/newview/skins/default/textures/icons/see_on_map.png
+++ b/indra/newview/skins/default/textures/icons/see_on_map.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/unknown_icon.png b/indra/newview/skins/default/textures/icons/unknown_icon.png
index 8441d86596..8441d86596 100644..100755
--- a/indra/newview/skins/default/textures/icons/unknown_icon.png
+++ b/indra/newview/skins/default/textures/icons/unknown_icon.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/jump_left_in.tga b/indra/newview/skins/default/textures/jump_left_in.tga
index e0656c901d..e0656c901d 100644..100755
--- a/indra/newview/skins/default/textures/jump_left_in.tga
+++ b/indra/newview/skins/default/textures/jump_left_in.tga
Binary files differ
diff --git a/indra/newview/skins/default/textures/jump_left_out.tga b/indra/newview/skins/default/textures/jump_left_out.tga
index fb6dac0c3d..fb6dac0c3d 100644..100755
--- a/indra/newview/skins/default/textures/jump_left_out.tga
+++ b/indra/newview/skins/default/textures/jump_left_out.tga
Binary files differ
diff --git a/indra/newview/skins/default/textures/jump_right_in.tga b/indra/newview/skins/default/textures/jump_right_in.tga
index 010c748c2a..010c748c2a 100644..100755
--- a/indra/newview/skins/default/textures/jump_right_in.tga
+++ b/indra/newview/skins/default/textures/jump_right_in.tga
Binary files differ
diff --git a/indra/newview/skins/default/textures/jump_right_out.tga b/indra/newview/skins/default/textures/jump_right_out.tga
index 33355262d4..33355262d4 100644..100755
--- a/indra/newview/skins/default/textures/jump_right_out.tga
+++ b/indra/newview/skins/default/textures/jump_right_out.tga
Binary files differ
diff --git a/indra/newview/skins/default/textures/lag_status_critical.tga b/indra/newview/skins/default/textures/lag_status_critical.tga
index bbc71d9e77..bbc71d9e77 100644..100755
--- a/indra/newview/skins/default/textures/lag_status_critical.tga
+++ b/indra/newview/skins/default/textures/lag_status_critical.tga
Binary files differ
diff --git a/indra/newview/skins/default/textures/lag_status_good.tga b/indra/newview/skins/default/textures/lag_status_good.tga
index 680ba90f17..680ba90f17 100644..100755
--- a/indra/newview/skins/default/textures/lag_status_good.tga
+++ b/indra/newview/skins/default/textures/lag_status_good.tga
Binary files differ
diff --git a/indra/newview/skins/default/textures/lag_status_warning.tga b/indra/newview/skins/default/textures/lag_status_warning.tga
index 13ce3cc396..13ce3cc396 100644..100755
--- a/indra/newview/skins/default/textures/lag_status_warning.tga
+++ b/indra/newview/skins/default/textures/lag_status_warning.tga
Binary files differ
diff --git a/indra/newview/skins/default/textures/legend.tga b/indra/newview/skins/default/textures/legend.tga
index 0dbb8fda4f..0dbb8fda4f 100644..100755
--- a/indra/newview/skins/default/textures/legend.tga
+++ b/indra/newview/skins/default/textures/legend.tga
Binary files differ
diff --git a/indra/newview/skins/default/textures/locked_image.j2c b/indra/newview/skins/default/textures/locked_image.j2c
index 9e8998d675..9e8998d675 100644..100755
--- a/indra/newview/skins/default/textures/locked_image.j2c
+++ b/indra/newview/skins/default/textures/locked_image.j2c
Binary files differ
diff --git a/indra/newview/skins/default/textures/map_avatar_16.tga b/indra/newview/skins/default/textures/map_avatar_16.tga
index f59e9e9193..f59e9e9193 100644..100755
--- a/indra/newview/skins/default/textures/map_avatar_16.tga
+++ b/indra/newview/skins/default/textures/map_avatar_16.tga
Binary files differ
diff --git a/indra/newview/skins/default/textures/map_avatar_32.tga b/indra/newview/skins/default/textures/map_avatar_32.tga
index aebeab4093..aebeab4093 100644..100755
--- a/indra/newview/skins/default/textures/map_avatar_32.tga
+++ b/indra/newview/skins/default/textures/map_avatar_32.tga
Binary files differ
diff --git a/indra/newview/skins/default/textures/map_avatar_8.tga b/indra/newview/skins/default/textures/map_avatar_8.tga
index 8500eadeba..8500eadeba 100644..100755
--- a/indra/newview/skins/default/textures/map_avatar_8.tga
+++ b/indra/newview/skins/default/textures/map_avatar_8.tga
Binary files differ
diff --git a/indra/newview/skins/default/textures/map_avatar_above_32.tga b/indra/newview/skins/default/textures/map_avatar_above_32.tga
index 65bd0561a7..65bd0561a7 100644..100755
--- a/indra/newview/skins/default/textures/map_avatar_above_32.tga
+++ b/indra/newview/skins/default/textures/map_avatar_above_32.tga
Binary files differ
diff --git a/indra/newview/skins/default/textures/map_avatar_below_32.tga b/indra/newview/skins/default/textures/map_avatar_below_32.tga
index 496c44b369..496c44b369 100644..100755
--- a/indra/newview/skins/default/textures/map_avatar_below_32.tga
+++ b/indra/newview/skins/default/textures/map_avatar_below_32.tga
Binary files differ
diff --git a/indra/newview/skins/default/textures/map_avatar_unknown_32.tga b/indra/newview/skins/default/textures/map_avatar_unknown_32.tga
index d1192478c6..d1192478c6 100644..100755
--- a/indra/newview/skins/default/textures/map_avatar_unknown_32.tga
+++ b/indra/newview/skins/default/textures/map_avatar_unknown_32.tga
Binary files differ
diff --git a/indra/newview/skins/default/textures/map_avatar_you_32.tga b/indra/newview/skins/default/textures/map_avatar_you_32.tga
index 782207efd6..782207efd6 100644..100755
--- a/indra/newview/skins/default/textures/map_avatar_you_32.tga
+++ b/indra/newview/skins/default/textures/map_avatar_you_32.tga
Binary files differ
diff --git a/indra/newview/skins/default/textures/map_event.tga b/indra/newview/skins/default/textures/map_event.tga
index 2c06d08fd2..2c06d08fd2 100644..100755
--- a/indra/newview/skins/default/textures/map_event.tga
+++ b/indra/newview/skins/default/textures/map_event.tga
Binary files differ
diff --git a/indra/newview/skins/default/textures/map_home.tga b/indra/newview/skins/default/textures/map_home.tga
index acaaa3db44..acaaa3db44 100644..100755
--- a/indra/newview/skins/default/textures/map_home.tga
+++ b/indra/newview/skins/default/textures/map_home.tga
Binary files differ
diff --git a/indra/newview/skins/default/textures/map_infohub.tga b/indra/newview/skins/default/textures/map_infohub.tga
index d0134fa5fe..d0134fa5fe 100644..100755
--- a/indra/newview/skins/default/textures/map_infohub.tga
+++ b/indra/newview/skins/default/textures/map_infohub.tga
Binary files differ
diff --git a/indra/newview/skins/default/textures/map_telehub.tga b/indra/newview/skins/default/textures/map_telehub.tga
index 545b8e532c..545b8e532c 100644..100755
--- a/indra/newview/skins/default/textures/map_telehub.tga
+++ b/indra/newview/skins/default/textures/map_telehub.tga
Binary files differ
diff --git a/indra/newview/skins/default/textures/map_track_16.tga b/indra/newview/skins/default/textures/map_track_16.tga
index 451ce24cf0..451ce24cf0 100644..100755
--- a/indra/newview/skins/default/textures/map_track_16.tga
+++ b/indra/newview/skins/default/textures/map_track_16.tga
Binary files differ
diff --git a/indra/newview/skins/default/textures/materials_ui_x_24.png b/indra/newview/skins/default/textures/materials_ui_x_24.png
new file mode 100644
index 0000000000..6d88554914
--- /dev/null
+++ b/indra/newview/skins/default/textures/materials_ui_x_24.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/menu_separator.png b/indra/newview/skins/default/textures/menu_separator.png
index 89dcdcdff5..89dcdcdff5 100644..100755
--- a/indra/newview/skins/default/textures/menu_separator.png
+++ b/indra/newview/skins/default/textures/menu_separator.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/missing_asset.tga b/indra/newview/skins/default/textures/missing_asset.tga
index 9a43f4db5d..9a43f4db5d 100644..100755
--- a/indra/newview/skins/default/textures/missing_asset.tga
+++ b/indra/newview/skins/default/textures/missing_asset.tga
Binary files differ
diff --git a/indra/newview/skins/default/textures/model_wizard/progress_bar_bg.png b/indra/newview/skins/default/textures/model_wizard/progress_bar_bg.png
index d0b213cdc5..d0b213cdc5 100644..100755
--- a/indra/newview/skins/default/textures/model_wizard/progress_bar_bg.png
+++ b/indra/newview/skins/default/textures/model_wizard/progress_bar_bg.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/model_wizard/progress_light.png b/indra/newview/skins/default/textures/model_wizard/progress_light.png
index 019344f812..019344f812 100644..100755
--- a/indra/newview/skins/default/textures/model_wizard/progress_light.png
+++ b/indra/newview/skins/default/textures/model_wizard/progress_light.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/navbar/Arrow_Left_Off.png b/indra/newview/skins/default/textures/navbar/Arrow_Left_Off.png
index 19569501fe..19569501fe 100644..100755
--- a/indra/newview/skins/default/textures/navbar/Arrow_Left_Off.png
+++ b/indra/newview/skins/default/textures/navbar/Arrow_Left_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/navbar/Arrow_Right_Off.png b/indra/newview/skins/default/textures/navbar/Arrow_Right_Off.png
index 3648c42656..3648c42656 100644..100755
--- a/indra/newview/skins/default/textures/navbar/Arrow_Right_Off.png
+++ b/indra/newview/skins/default/textures/navbar/Arrow_Right_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/navbar/BuyArrow_Over.png b/indra/newview/skins/default/textures/navbar/BuyArrow_Over.png
index 0b3f252ccf..0b3f252ccf 100644..100755
--- a/indra/newview/skins/default/textures/navbar/BuyArrow_Over.png
+++ b/indra/newview/skins/default/textures/navbar/BuyArrow_Over.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/navbar/BuyArrow_Press.png b/indra/newview/skins/default/textures/navbar/BuyArrow_Press.png
index 5c4c150bed..5c4c150bed 100644..100755
--- a/indra/newview/skins/default/textures/navbar/BuyArrow_Press.png
+++ b/indra/newview/skins/default/textures/navbar/BuyArrow_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/navbar/Favorite_Link_Over.png b/indra/newview/skins/default/textures/navbar/Favorite_Link_Over.png
index d4f126f969..d4f126f969 100644..100755
--- a/indra/newview/skins/default/textures/navbar/Favorite_Link_Over.png
+++ b/indra/newview/skins/default/textures/navbar/Favorite_Link_Over.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/navbar/Favorite_Star_Active.png b/indra/newview/skins/default/textures/navbar/Favorite_Star_Active.png
index e27dbe2cad..e27dbe2cad 100644..100755
--- a/indra/newview/skins/default/textures/navbar/Favorite_Star_Active.png
+++ b/indra/newview/skins/default/textures/navbar/Favorite_Star_Active.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/navbar/Favorite_Star_Off.png b/indra/newview/skins/default/textures/navbar/Favorite_Star_Off.png
index 82d044d817..82d044d817 100644..100755
--- a/indra/newview/skins/default/textures/navbar/Favorite_Star_Off.png
+++ b/indra/newview/skins/default/textures/navbar/Favorite_Star_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/navbar/Favorite_Star_Over.png b/indra/newview/skins/default/textures/navbar/Favorite_Star_Over.png
index 7909d54f2b..7909d54f2b 100644..100755
--- a/indra/newview/skins/default/textures/navbar/Favorite_Star_Over.png
+++ b/indra/newview/skins/default/textures/navbar/Favorite_Star_Over.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/navbar/Favorite_Star_Press.png b/indra/newview/skins/default/textures/navbar/Favorite_Star_Press.png
index 6670667022..6670667022 100644..100755
--- a/indra/newview/skins/default/textures/navbar/Favorite_Star_Press.png
+++ b/indra/newview/skins/default/textures/navbar/Favorite_Star_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/navbar/FileMenu_Divider.png b/indra/newview/skins/default/textures/navbar/FileMenu_Divider.png
index 5ab4abc5b8..5ab4abc5b8 100644..100755
--- a/indra/newview/skins/default/textures/navbar/FileMenu_Divider.png
+++ b/indra/newview/skins/default/textures/navbar/FileMenu_Divider.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/navbar/Flag.png b/indra/newview/skins/default/textures/navbar/Flag.png
index df53c89224..df53c89224 100644..100755
--- a/indra/newview/skins/default/textures/navbar/Flag.png
+++ b/indra/newview/skins/default/textures/navbar/Flag.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/navbar/Help_Press.png b/indra/newview/skins/default/textures/navbar/Help_Press.png
index ed3695f9d5..ed3695f9d5 100644..100755
--- a/indra/newview/skins/default/textures/navbar/Help_Press.png
+++ b/indra/newview/skins/default/textures/navbar/Help_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/navbar/Home_Off.png b/indra/newview/skins/default/textures/navbar/Home_Off.png
index fe3bc63b77..fe3bc63b77 100644..100755
--- a/indra/newview/skins/default/textures/navbar/Home_Off.png
+++ b/indra/newview/skins/default/textures/navbar/Home_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/navbar/Info_Off.png b/indra/newview/skins/default/textures/navbar/Info_Off.png
index 64722255a3..64722255a3 100644..100755
--- a/indra/newview/skins/default/textures/navbar/Info_Off.png
+++ b/indra/newview/skins/default/textures/navbar/Info_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/navbar/Info_Over.png b/indra/newview/skins/default/textures/navbar/Info_Over.png
index 84f1d03129..84f1d03129 100644..100755
--- a/indra/newview/skins/default/textures/navbar/Info_Over.png
+++ b/indra/newview/skins/default/textures/navbar/Info_Over.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/navbar/Info_Press.png b/indra/newview/skins/default/textures/navbar/Info_Press.png
index 169105829e..169105829e 100644..100755
--- a/indra/newview/skins/default/textures/navbar/Info_Press.png
+++ b/indra/newview/skins/default/textures/navbar/Info_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/navbar/Lock.png b/indra/newview/skins/default/textures/navbar/Lock.png
index cf569d6ad2..cf569d6ad2 100644..100755
--- a/indra/newview/skins/default/textures/navbar/Lock.png
+++ b/indra/newview/skins/default/textures/navbar/Lock.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/navbar/NavBar_BG.png b/indra/newview/skins/default/textures/navbar/NavBar_BG.png
index 38eea783e6..38eea783e6 100644..100755
--- a/indra/newview/skins/default/textures/navbar/NavBar_BG.png
+++ b/indra/newview/skins/default/textures/navbar/NavBar_BG.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/navbar/NavBar_BG_NoFav_Bevel.png b/indra/newview/skins/default/textures/navbar/NavBar_BG_NoFav_Bevel.png
index a79d999932..a79d999932 100644..100755
--- a/indra/newview/skins/default/textures/navbar/NavBar_BG_NoFav_Bevel.png
+++ b/indra/newview/skins/default/textures/navbar/NavBar_BG_NoFav_Bevel.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/navbar/NavBar_BG_NoNav_Bevel.png b/indra/newview/skins/default/textures/navbar/NavBar_BG_NoNav_Bevel.png
index b692ed92da..b692ed92da 100644..100755
--- a/indra/newview/skins/default/textures/navbar/NavBar_BG_NoNav_Bevel.png
+++ b/indra/newview/skins/default/textures/navbar/NavBar_BG_NoNav_Bevel.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/navbar/Row_Selection.png b/indra/newview/skins/default/textures/navbar/Row_Selection.png
index fc4f0c07ef..fc4f0c07ef 100644..100755
--- a/indra/newview/skins/default/textures/navbar/Row_Selection.png
+++ b/indra/newview/skins/default/textures/navbar/Row_Selection.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/navbar/Search.png b/indra/newview/skins/default/textures/navbar/Search.png
index 0d0e330bc7..0d0e330bc7 100644..100755
--- a/indra/newview/skins/default/textures/navbar/Search.png
+++ b/indra/newview/skins/default/textures/navbar/Search.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/navbar/separator.png b/indra/newview/skins/default/textures/navbar/separator.png
index b93e5791a7..b93e5791a7 100644..100755
--- a/indra/newview/skins/default/textures/navbar/separator.png
+++ b/indra/newview/skins/default/textures/navbar/separator.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/notify_caution_icon.tga b/indra/newview/skins/default/textures/notify_caution_icon.tga
index abc23d1d7a..abc23d1d7a 100644..100755
--- a/indra/newview/skins/default/textures/notify_caution_icon.tga
+++ b/indra/newview/skins/default/textures/notify_caution_icon.tga
Binary files differ
diff --git a/indra/newview/skins/default/textures/pixiesmall.j2c b/indra/newview/skins/default/textures/pixiesmall.j2c
index a1ff64014b..a1ff64014b 100644..100755
--- a/indra/newview/skins/default/textures/pixiesmall.j2c
+++ b/indra/newview/skins/default/textures/pixiesmall.j2c
Binary files differ
diff --git a/indra/newview/skins/default/textures/red_x.png b/indra/newview/skins/default/textures/red_x.png
index a61202f09b..a61202f09b 100644..100755
--- a/indra/newview/skins/default/textures/red_x.png
+++ b/indra/newview/skins/default/textures/red_x.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/rounded_square.j2c b/indra/newview/skins/default/textures/rounded_square.j2c
index c8bb572fa9..c8bb572fa9 100644..100755
--- a/indra/newview/skins/default/textures/rounded_square.j2c
+++ b/indra/newview/skins/default/textures/rounded_square.j2c
Binary files differ
diff --git a/indra/newview/skins/default/textures/script_error.j2c b/indra/newview/skins/default/textures/script_error.j2c
index 893cb642e7..893cb642e7 100644..100755
--- a/indra/newview/skins/default/textures/script_error.j2c
+++ b/indra/newview/skins/default/textures/script_error.j2c
Binary files differ
diff --git a/indra/newview/skins/default/textures/silhouette.j2c b/indra/newview/skins/default/textures/silhouette.j2c
index 3859d4cb34..3859d4cb34 100644..100755
--- a/indra/newview/skins/default/textures/silhouette.j2c
+++ b/indra/newview/skins/default/textures/silhouette.j2c
Binary files differ
diff --git a/indra/newview/skins/default/textures/slim_icon_16_viewer.tga b/indra/newview/skins/default/textures/slim_icon_16_viewer.tga
index 552181d36a..552181d36a 100644..100755
--- a/indra/newview/skins/default/textures/slim_icon_16_viewer.tga
+++ b/indra/newview/skins/default/textures/slim_icon_16_viewer.tga
Binary files differ
diff --git a/indra/newview/skins/default/textures/snapshot_download.png b/indra/newview/skins/default/textures/snapshot_download.png
index 6aa1abded5..6aa1abded5 100644..100755
--- a/indra/newview/skins/default/textures/snapshot_download.png
+++ b/indra/newview/skins/default/textures/snapshot_download.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/snapshot_email.png b/indra/newview/skins/default/textures/snapshot_email.png
index dee784a9bf..dee784a9bf 100644..100755
--- a/indra/newview/skins/default/textures/snapshot_email.png
+++ b/indra/newview/skins/default/textures/snapshot_email.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/spacer24.tga b/indra/newview/skins/default/textures/spacer24.tga
index c7cab6b38c..c7cab6b38c 100644..100755
--- a/indra/newview/skins/default/textures/spacer24.tga
+++ b/indra/newview/skins/default/textures/spacer24.tga
Binary files differ
diff --git a/indra/newview/skins/default/textures/tabarea.tga b/indra/newview/skins/default/textures/tabarea.tga
index 5517aebfc8..5517aebfc8 100644..100755
--- a/indra/newview/skins/default/textures/tabarea.tga
+++ b/indra/newview/skins/default/textures/tabarea.tga
Binary files differ
diff --git a/indra/newview/skins/default/textures/taskpanel/Activate_Checkmark.png b/indra/newview/skins/default/textures/taskpanel/Activate_Checkmark.png
index 213acbe87b..213acbe87b 100644..100755
--- a/indra/newview/skins/default/textures/taskpanel/Activate_Checkmark.png
+++ b/indra/newview/skins/default/textures/taskpanel/Activate_Checkmark.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/taskpanel/Sidebar_Icon_Dock_Foreground.png b/indra/newview/skins/default/textures/taskpanel/Sidebar_Icon_Dock_Foreground.png
index 50c01062a5..50c01062a5 100644..100755
--- a/indra/newview/skins/default/textures/taskpanel/Sidebar_Icon_Dock_Foreground.png
+++ b/indra/newview/skins/default/textures/taskpanel/Sidebar_Icon_Dock_Foreground.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/taskpanel/Sidebar_Icon_Dock_Press.png b/indra/newview/skins/default/textures/taskpanel/Sidebar_Icon_Dock_Press.png
index bf2065cd37..bf2065cd37 100644..100755
--- a/indra/newview/skins/default/textures/taskpanel/Sidebar_Icon_Dock_Press.png
+++ b/indra/newview/skins/default/textures/taskpanel/Sidebar_Icon_Dock_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/taskpanel/Sidebar_Icon_Undock_Foreground.png b/indra/newview/skins/default/textures/taskpanel/Sidebar_Icon_Undock_Foreground.png
index 8b48258142..8b48258142 100644..100755
--- a/indra/newview/skins/default/textures/taskpanel/Sidebar_Icon_Undock_Foreground.png
+++ b/indra/newview/skins/default/textures/taskpanel/Sidebar_Icon_Undock_Foreground.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/taskpanel/Sidebar_Icon_Undock_Press.png b/indra/newview/skins/default/textures/taskpanel/Sidebar_Icon_Undock_Press.png
index 09efe779fe..09efe779fe 100644..100755
--- a/indra/newview/skins/default/textures/taskpanel/Sidebar_Icon_Undock_Press.png
+++ b/indra/newview/skins/default/textures/taskpanel/Sidebar_Icon_Undock_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/taskpanel/TabIcon_Close_Off.png b/indra/newview/skins/default/textures/taskpanel/TabIcon_Close_Off.png
index bc4e00c646..bc4e00c646 100644..100755
--- a/indra/newview/skins/default/textures/taskpanel/TabIcon_Close_Off.png
+++ b/indra/newview/skins/default/textures/taskpanel/TabIcon_Close_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/taskpanel/TabIcon_Home_Selected.png b/indra/newview/skins/default/textures/taskpanel/TabIcon_Home_Selected.png
index 293aeef5e6..293aeef5e6 100644..100755
--- a/indra/newview/skins/default/textures/taskpanel/TabIcon_Home_Selected.png
+++ b/indra/newview/skins/default/textures/taskpanel/TabIcon_Home_Selected.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/taskpanel/TabIcon_Me_Off.png b/indra/newview/skins/default/textures/taskpanel/TabIcon_Me_Off.png
index 760db9360d..760db9360d 100644..100755
--- a/indra/newview/skins/default/textures/taskpanel/TabIcon_Me_Off.png
+++ b/indra/newview/skins/default/textures/taskpanel/TabIcon_Me_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/taskpanel/TabIcon_Open_Off.png b/indra/newview/skins/default/textures/taskpanel/TabIcon_Open_Off.png
index 4556602f58..4556602f58 100644..100755
--- a/indra/newview/skins/default/textures/taskpanel/TabIcon_Open_Off.png
+++ b/indra/newview/skins/default/textures/taskpanel/TabIcon_Open_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/taskpanel/TabIcon_People_Off.png b/indra/newview/skins/default/textures/taskpanel/TabIcon_People_Off.png
index 691b600510..691b600510 100644..100755
--- a/indra/newview/skins/default/textures/taskpanel/TabIcon_People_Off.png
+++ b/indra/newview/skins/default/textures/taskpanel/TabIcon_People_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/taskpanel/TabIcon_Places_Off.png b/indra/newview/skins/default/textures/taskpanel/TabIcon_Places_Off.png
index f5a5f7a846..f5a5f7a846 100644..100755
--- a/indra/newview/skins/default/textures/taskpanel/TabIcon_Places_Off.png
+++ b/indra/newview/skins/default/textures/taskpanel/TabIcon_Places_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/taskpanel/TabIcon_Things_Off.png b/indra/newview/skins/default/textures/taskpanel/TabIcon_Things_Off.png
index e56eda9802..e56eda9802 100644..100755
--- a/indra/newview/skins/default/textures/taskpanel/TabIcon_Things_Off.png
+++ b/indra/newview/skins/default/textures/taskpanel/TabIcon_Things_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/taskpanel/TaskPanel_Tab_Off.png b/indra/newview/skins/default/textures/taskpanel/TaskPanel_Tab_Off.png
index 4ed7a2b183..4ed7a2b183 100644..100755
--- a/indra/newview/skins/default/textures/taskpanel/TaskPanel_Tab_Off.png
+++ b/indra/newview/skins/default/textures/taskpanel/TaskPanel_Tab_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/taskpanel/TaskPanel_Tab_Selected.png b/indra/newview/skins/default/textures/taskpanel/TaskPanel_Tab_Selected.png
index b3316386b9..b3316386b9 100644..100755
--- a/indra/newview/skins/default/textures/taskpanel/TaskPanel_Tab_Selected.png
+++ b/indra/newview/skins/default/textures/taskpanel/TaskPanel_Tab_Selected.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/tearoff_pressed.tga b/indra/newview/skins/default/textures/tearoff_pressed.tga
index 620d109de0..620d109de0 100644..100755
--- a/indra/newview/skins/default/textures/tearoff_pressed.tga
+++ b/indra/newview/skins/default/textures/tearoff_pressed.tga
Binary files differ
diff --git a/indra/newview/skins/default/textures/tearoffbox.tga b/indra/newview/skins/default/textures/tearoffbox.tga
index 0670d2e91b..0670d2e91b 100644..100755
--- a/indra/newview/skins/default/textures/tearoffbox.tga
+++ b/indra/newview/skins/default/textures/tearoffbox.tga
Binary files differ
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index eabcc68916..bb891996c9 100644..100755
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -54,6 +54,8 @@ with the same filename but different name
<texture name="Arrow_Down" file_name="widgets/Arrow_Down.png" preload="true" />
<texture name="Arrow_Up" file_name="widgets/Arrow_Up.png" preload="true" />
+ <texture name="Arrow_Left" file_name="widgets/Arrow_Left.png" preload="true" />
+ <texture name="Arrow_Right" file_name="widgets/Arrow_Right.png" preload="true" />
<texture name="AudioMute_Off" file_name="icons/AudioMute_Off.png" preload="false" />
<texture name="AudioMute_Over" file_name="icons/AudioMute_Over.png" preload="false" />
@@ -146,10 +148,13 @@ with the same filename but different name
<texture name="Command_Preferences_Icon" file_name="toolbar_icons/preferences.png" preload="true" />
<texture name="Command_Profile_Icon" file_name="toolbar_icons/profile.png" preload="true" />
<texture name="Command_Search_Icon" file_name="toolbar_icons/search.png" preload="true" />
+ <texture name="Command_Social_Icon" file_name="toolbar_icons/facebook.png" preload="true" />
<texture name="Command_Snapshot_Icon" file_name="toolbar_icons/snapshot.png" preload="true" />
<texture name="Command_Speak_Icon" file_name="toolbar_icons/speak.png" preload="true" />
<texture name="Command_View_Icon" file_name="toolbar_icons/view.png" preload="true" />
<texture name="Command_Voice_Icon" file_name="toolbar_icons/nearbyvoice.png" preload="true" />
+ <texture name="Command_Highlighting_Icon" file_name="toolbar_icons/highlighting.png" preload="true" scale.left="4" scale.top="19" scale.right="28" scale.bottom="4" />
+ <texture name="Command_Highlighting_Selected_Icon" file_name="toolbar_icons/highlighting_selected.png" preload="true" scale.left="4" scale.top="19" scale.right="28" scale.bottom="4" />
<texture name="Caret_Bottom_Icon" file_name="toolbar_icons/caret_bottom.png" preload="true" scale.left="1" scale.top="23" scale.right="15" scale.bottom="1" />
<texture name="Caret_Right_Icon" file_name="toolbar_icons/caret_right.png" preload="true" scale.left="5" scale.top="15" scale.right="28" scale.bottom="1" />
<texture name="Caret_Left_Icon" file_name="toolbar_icons/caret_left.png" preload="true" scale.left="1" scale.top="15" scale.right="23" scale.bottom="1" />
@@ -160,7 +165,25 @@ with the same filename but different name
<texture name="ComboButton_On" file_name="widgets/ComboButton_On.png" preload="true" scale.left="2" scale.top="19" scale.right="18" scale.bottom="2" />
<texture name="ComboButton_Off" file_name="widgets/ComboButton_Off.png" preload="true" scale.left="2" scale.top="19" scale.right="18" scale.bottom="2" />
<texture name="ComboButton_UpOff" file_name="widgets/ComboButton_UpOff.png" preload="true" scale.left="2" scale.top="19" scale.right="18" scale.bottom="2" />
+ <texture name="ComboButton_Hovered" file_name="widgets/ComboButton_Hover.png" preload="true" scale.left="2" scale.top="19" scale.right="18" scale.bottom="2" />
+
<texture name="Container" file_name="containers/Container.png" preload="false" />
+
+ <texture name="Conv_toolbar_add_person" file_name="icons/Conv_toolbar_add_person.png" preload="false" />
+ <texture name="Conv_toolbar_arrow_ne" file_name="icons/Conv_toolbar_arrow_ne.png" preload="false" />
+ <texture name="Conv_toolbar_arrow_sw" file_name="icons/Conv_toolbar_arrow_sw.png" preload="false" />
+ <texture name="Conv_toolbar_call_log" file_name="icons/Conv_toolbar_call_log.png" preload="false" />
+ <texture name="Conv_toolbar_close" file_name="icons/Conv_toolbar_close.png" preload="false" />
+ <texture name="Conv_toolbar_collapse" file_name="icons/Conv_toolbar_collapse.png" preload="false" />
+ <texture name="Conv_collapse_to_one_line" file_name="icons/collapse_to_one_line.png" preload="false" />
+ <texture name="Conv_expand_one_line" file_name="icons/expand_one_liner.png" preload="false" />
+ <texture name="Conv_toolbar_expand" file_name="icons/Conv_toolbar_expand.png" preload="false" />
+ <texture name="Conv_toolbar_hang_up" file_name="icons/Conv_toolbar_hang_up.png" preload="false" />
+ <texture name="Conv_toolbar_open_call" file_name="icons/Conv_toolbar_open_call.png" preload="false" />
+ <texture name="Conv_toolbar_plus" file_name="icons/Conv_toolbar_plus.png" preload="false" />
+ <texture name="Conv_toolbar_sort" file_name="icons/Conv_toolbar_sort.png" preload="false" />
+ <texture name="Conv_log_inbox" file_name="icons/Conv_log_inbox.png" preload="false" />
+
<texture name="Copy" file_name="icons/Copy.png" preload="false" />
<texture name="DisclosureArrow_Opened_Off" file_name="widgets/DisclosureArrow_Opened_Off.png" preload="true" />
@@ -180,6 +203,8 @@ with the same filename but different name
<texture name="ExternalBrowser_Off" file_name="icons/ExternalBrowser_Off.png" preload="false" />
<texture name="Edit_Wrench" file_name="icons/Edit_Wrench.png" preload="false" />
+ <texture name="Facebook_Icon" file_name="icons/Facebook.png" preload="false" />
+
<texture name="Favorite_Star_Active" file_name="navbar/Favorite_Star_Active.png" preload="false" />
<texture name="Favorite_Star_Off" file_name="navbar/Favorite_Star_Off.png" preload="false" />
<texture name="Favorite_Star_Press" file_name="navbar/Favorite_Star_Press.png" preload="false" />
@@ -304,6 +329,8 @@ with the same filename but different name
<texture name="Locked_Icon" file_name="icons/Locked_Icon.png" preload="false" />
+ <texture name="Map_Placeholder_Icon" file_name="icons/map_placeholder.png" preload="true" />
+
<texture name="MarketplaceBtn_Off" file_name="widgets/MarketplaceBtn_Off.png" preload="true" scale.left="30" scale.top="19" scale.right="35" scale.bottom="4" />
<texture name="MarketplaceBtn_Selected" file_name="widgets/MarketplaceBtn_Selected.png" preload="true" scale.left="30" scale.top="19" scale.right="35" scale.bottom="4" />
@@ -346,6 +373,8 @@ with the same filename but different name
<texture name="NavBar_BG_NoFav_Bevel" file_name="navbar/NavBar_BG_NoFav_Bevel.png" preload="true" scale.left="1" scale.top="1" scale.right="0" scale.bottom="0" />
<texture name="NavBar_BG_NoNav_Bevel" file_name="navbar/NavBar_BG_NoNav_Bevel.png" preload="true" scale.left="1" scale.top="1" scale.right="0" scale.bottom="0" />
+ <texture name="Nearby_chat_icon" file_name="icons/nearby_chat_icon.png" preload="false" />
+
<texture name="Notices_Unread" file_name="bottomtray/Notices_Unread.png" preload="true" />
<texture name="NoEntryLines" file_name="world/NoEntryLines.png" use_mips="true" preload="false" />
@@ -429,6 +458,9 @@ with the same filename but different name
<texture name="Parcel_Voice_Light" file_name="icons/Parcel_Voice_Light.png" preload="false" />
<texture name="Parcel_VoiceNo_Light" file_name="icons/Parcel_VoiceNo_Light.png" preload="false" />
+ <texture name="Pathfinding_Dirty" file_name="icons/Pathfinding_Dirty.png" preload="false" />
+ <texture name="Pathfinding_Disabled" file_name="icons/Pathfinding_Disabled.png" preload="false" />
+
<texture name="Pause_Off" file_name="icons/Pause_Off.png" preload="false" />
<texture name="Pause_Over" file_name="icons/Pause_Over.png" preload="false" />
<texture name="Pause_Press" file_name="icons/Pause_Press.png" preload="false" />
@@ -541,6 +573,7 @@ with the same filename but different name
<texture name="Snapshot_Email" file_name="snapshot_email.png" preload="false" />
<texture name="Snapshot_Inventory" file_name="toolbar_icons/inventory.png" preload="false" />
<texture name="Snapshot_Profile" file_name="toolbar_icons/profile.png" preload="false" />
+ <texture name="Snapshot_Facebook" file_name="toolbar_icons/facebook.png" preload="false" />
<texture name="startup_logo" file_name="windows/startup_logo.png" preload="true" />
@@ -620,7 +653,6 @@ with the same filename but different name
<texture name="TrashItem_Press" file_name="icons/TrashItem_Press.png" preload="false" />
<texture name="Unread_Chiclet" file_name="bottomtray/Unread_Chiclet.png" preload="false" />
- <texture name="Unread_IM" file_name="bottomtray/Unread_IM.png" preload="false" />
<texture name="UpArrow_Off" file_name="icons/UpArrow_Off.png" preload="false" />
@@ -633,12 +665,6 @@ with the same filename but different name
<texture name="VoicePTT_Off" file_name="bottomtray/VoicePTT_Off.png" preload="false" />
<texture name="VoicePTT_On" file_name="bottomtray/VoicePTT_On.png" preload="false" />
- <texture name="VoicePTT_Lvl1_Dark" file_name="bottomtray/VoicePTT_Lvl1_Dark.png" preload="false" />
- <texture name="VoicePTT_Lvl2_Dark" file_name="bottomtray/VoicePTT_Lvl2_Dark.png" preload="false" />
- <texture name="VoicePTT_Lvl3_Dark" file_name="bottomtray/VoicePTT_Lvl3_Dark.png" preload="false" />
- <texture name="VoicePTT_Off_Dark" file_name="bottomtray/VoicePTT_Off_Dark.png" preload="false" />
- <texture name="VoicePTT_On_Dark" file_name="bottomtray/VoicePTT_On_Dark.png" preload="false" />
-
<texture name="Wearables_Divider" file_name="windows/Wearables_Divider.png" preload="false" />
<texture name="Web_Profile_Off" file_name="icons/Web_Profile_Off.png" preload="false" />
@@ -707,9 +733,6 @@ with the same filename but different name
<texture name="icon_for_sale.tga" file_name="icons/Icon_For_Sale.png" />
<texture name="icon_top_pick.tga" />
- <texture name="inv_folder_mesh.tga"/>
- <texture name="inv_item_mesh.tga"/>
-
<texture name="lag_status_critical.tga" />
<texture name="lag_status_good.tga" />
<texture name="lag_status_warning.tga" />
@@ -729,6 +752,7 @@ with the same filename but different name
<texture name="default_land_picture.j2c" />
<texture name="default_profile_picture.j2c" />
<texture name="locked_image.j2c" />
+ <texture name="materials_ui_x_24.png" />
<texture name="Progress_1" file_name="icons/Progress_1.png" preload="true" />
<texture name="Progress_2" file_name="icons/Progress_2.png" preload="true" />
@@ -759,4 +783,7 @@ with the same filename but different name
<texture name="Popup_Caution" file_name="icons/pop_up_caution.png"/>
<texture name="Camera_Drag_Dot" file_name="world/CameraDragDot.png"/>
<texture name="NavBar Separator" file_name="navbar/separator.png"/>
+
+ <texture name="Horizontal Drag Handle" file_name="widgets/horizontal_drag_handle.png"/>
+ <texture name="Vertical Drag Handle" file_name="widgets/vertical_drag_handle.png"/>
</textures>
diff --git a/indra/newview/skins/default/textures/toolbar_icons/appearance.png b/indra/newview/skins/default/textures/toolbar_icons/appearance.png
index e6b1365388..e6b1365388 100644..100755
--- a/indra/newview/skins/default/textures/toolbar_icons/appearance.png
+++ b/indra/newview/skins/default/textures/toolbar_icons/appearance.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/toolbar_icons/avatars.png b/indra/newview/skins/default/textures/toolbar_icons/avatars.png
index 8fa0600cee..8fa0600cee 100644..100755
--- a/indra/newview/skins/default/textures/toolbar_icons/avatars.png
+++ b/indra/newview/skins/default/textures/toolbar_icons/avatars.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/toolbar_icons/build.png b/indra/newview/skins/default/textures/toolbar_icons/build.png
index e21ab3f0e4..e21ab3f0e4 100644..100755
--- a/indra/newview/skins/default/textures/toolbar_icons/build.png
+++ b/indra/newview/skins/default/textures/toolbar_icons/build.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/toolbar_icons/caret_bottom.png b/indra/newview/skins/default/textures/toolbar_icons/caret_bottom.png
index 5f6a01eaa1..5f6a01eaa1 100644..100755
--- a/indra/newview/skins/default/textures/toolbar_icons/caret_bottom.png
+++ b/indra/newview/skins/default/textures/toolbar_icons/caret_bottom.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/toolbar_icons/caret_left.png b/indra/newview/skins/default/textures/toolbar_icons/caret_left.png
index 0b8090314c..0b8090314c 100644..100755
--- a/indra/newview/skins/default/textures/toolbar_icons/caret_left.png
+++ b/indra/newview/skins/default/textures/toolbar_icons/caret_left.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/toolbar_icons/caret_right.png b/indra/newview/skins/default/textures/toolbar_icons/caret_right.png
index 044751560f..044751560f 100644..100755
--- a/indra/newview/skins/default/textures/toolbar_icons/caret_right.png
+++ b/indra/newview/skins/default/textures/toolbar_icons/caret_right.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/toolbar_icons/chat.png b/indra/newview/skins/default/textures/toolbar_icons/chat.png
index e0dbac495f..e0dbac495f 100644..100755
--- a/indra/newview/skins/default/textures/toolbar_icons/chat.png
+++ b/indra/newview/skins/default/textures/toolbar_icons/chat.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/toolbar_icons/destinations.png b/indra/newview/skins/default/textures/toolbar_icons/destinations.png
index e2325f083a..e2325f083a 100644..100755
--- a/indra/newview/skins/default/textures/toolbar_icons/destinations.png
+++ b/indra/newview/skins/default/textures/toolbar_icons/destinations.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/toolbar_icons/facebook.png b/indra/newview/skins/default/textures/toolbar_icons/facebook.png
new file mode 100644
index 0000000000..b960b834dc
--- /dev/null
+++ b/indra/newview/skins/default/textures/toolbar_icons/facebook.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/toolbar_icons/gestures.png b/indra/newview/skins/default/textures/toolbar_icons/gestures.png
index 2404bb4e25..2404bb4e25 100644..100755
--- a/indra/newview/skins/default/textures/toolbar_icons/gestures.png
+++ b/indra/newview/skins/default/textures/toolbar_icons/gestures.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/toolbar_icons/highlighting.png b/indra/newview/skins/default/textures/toolbar_icons/highlighting.png
new file mode 100644
index 0000000000..c227f07513
--- /dev/null
+++ b/indra/newview/skins/default/textures/toolbar_icons/highlighting.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/toolbar_icons/highlighting_selected.png b/indra/newview/skins/default/textures/toolbar_icons/highlighting_selected.png
new file mode 100644
index 0000000000..aa1bb26a56
--- /dev/null
+++ b/indra/newview/skins/default/textures/toolbar_icons/highlighting_selected.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/toolbar_icons/howto.png b/indra/newview/skins/default/textures/toolbar_icons/howto.png
index 8594d71113..8594d71113 100644..100755
--- a/indra/newview/skins/default/textures/toolbar_icons/howto.png
+++ b/indra/newview/skins/default/textures/toolbar_icons/howto.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/toolbar_icons/inventory.png b/indra/newview/skins/default/textures/toolbar_icons/inventory.png
index ab3191255e..ab3191255e 100644..100755
--- a/indra/newview/skins/default/textures/toolbar_icons/inventory.png
+++ b/indra/newview/skins/default/textures/toolbar_icons/inventory.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/toolbar_icons/land.png b/indra/newview/skins/default/textures/toolbar_icons/land.png
index 89ea7604a4..89ea7604a4 100644..100755
--- a/indra/newview/skins/default/textures/toolbar_icons/land.png
+++ b/indra/newview/skins/default/textures/toolbar_icons/land.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/toolbar_icons/map.png b/indra/newview/skins/default/textures/toolbar_icons/map.png
index ed1049b7db..ed1049b7db 100644..100755
--- a/indra/newview/skins/default/textures/toolbar_icons/map.png
+++ b/indra/newview/skins/default/textures/toolbar_icons/map.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/toolbar_icons/marketplace.png b/indra/newview/skins/default/textures/toolbar_icons/marketplace.png
index 62bad20be6..62bad20be6 100644..100755
--- a/indra/newview/skins/default/textures/toolbar_icons/marketplace.png
+++ b/indra/newview/skins/default/textures/toolbar_icons/marketplace.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/toolbar_icons/mini_cart.png b/indra/newview/skins/default/textures/toolbar_icons/mini_cart.png
index 9fcf46794d..9fcf46794d 100644..100755
--- a/indra/newview/skins/default/textures/toolbar_icons/mini_cart.png
+++ b/indra/newview/skins/default/textures/toolbar_icons/mini_cart.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/toolbar_icons/mini_map.png b/indra/newview/skins/default/textures/toolbar_icons/mini_map.png
index ab0a654056..ab0a654056 100644..100755
--- a/indra/newview/skins/default/textures/toolbar_icons/mini_map.png
+++ b/indra/newview/skins/default/textures/toolbar_icons/mini_map.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/toolbar_icons/move.png b/indra/newview/skins/default/textures/toolbar_icons/move.png
index 5c2ced7375..5c2ced7375 100644..100755
--- a/indra/newview/skins/default/textures/toolbar_icons/move.png
+++ b/indra/newview/skins/default/textures/toolbar_icons/move.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/toolbar_icons/nearbyvoice.png b/indra/newview/skins/default/textures/toolbar_icons/nearbyvoice.png
index 77a7cd5f44..77a7cd5f44 100644..100755
--- a/indra/newview/skins/default/textures/toolbar_icons/nearbyvoice.png
+++ b/indra/newview/skins/default/textures/toolbar_icons/nearbyvoice.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/toolbar_icons/outbox.png b/indra/newview/skins/default/textures/toolbar_icons/outbox.png
index 0f3db1c47c..0f3db1c47c 100644..100755
--- a/indra/newview/skins/default/textures/toolbar_icons/outbox.png
+++ b/indra/newview/skins/default/textures/toolbar_icons/outbox.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/toolbar_icons/people.png b/indra/newview/skins/default/textures/toolbar_icons/people.png
index 7228ae8e2f..7228ae8e2f 100644..100755
--- a/indra/newview/skins/default/textures/toolbar_icons/people.png
+++ b/indra/newview/skins/default/textures/toolbar_icons/people.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/toolbar_icons/picks.png b/indra/newview/skins/default/textures/toolbar_icons/picks.png
index befda04b42..befda04b42 100644..100755
--- a/indra/newview/skins/default/textures/toolbar_icons/picks.png
+++ b/indra/newview/skins/default/textures/toolbar_icons/picks.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/toolbar_icons/places.png b/indra/newview/skins/default/textures/toolbar_icons/places.png
index 97d9fa066c..97d9fa066c 100644..100755
--- a/indra/newview/skins/default/textures/toolbar_icons/places.png
+++ b/indra/newview/skins/default/textures/toolbar_icons/places.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/toolbar_icons/preferences.png b/indra/newview/skins/default/textures/toolbar_icons/preferences.png
index 4ccd7b8ae1..4ccd7b8ae1 100644..100755
--- a/indra/newview/skins/default/textures/toolbar_icons/preferences.png
+++ b/indra/newview/skins/default/textures/toolbar_icons/preferences.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/toolbar_icons/profile.png b/indra/newview/skins/default/textures/toolbar_icons/profile.png
index 32fe2bf8ac..32fe2bf8ac 100644..100755
--- a/indra/newview/skins/default/textures/toolbar_icons/profile.png
+++ b/indra/newview/skins/default/textures/toolbar_icons/profile.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/toolbar_icons/search.png b/indra/newview/skins/default/textures/toolbar_icons/search.png
index bcb11e950d..bcb11e950d 100644..100755
--- a/indra/newview/skins/default/textures/toolbar_icons/search.png
+++ b/indra/newview/skins/default/textures/toolbar_icons/search.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/toolbar_icons/snapshot.png b/indra/newview/skins/default/textures/toolbar_icons/snapshot.png
index d26da9b1d2..d26da9b1d2 100644..100755
--- a/indra/newview/skins/default/textures/toolbar_icons/snapshot.png
+++ b/indra/newview/skins/default/textures/toolbar_icons/snapshot.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/toolbar_icons/speak.png b/indra/newview/skins/default/textures/toolbar_icons/speak.png
index 10cd354c5c..10cd354c5c 100644..100755
--- a/indra/newview/skins/default/textures/toolbar_icons/speak.png
+++ b/indra/newview/skins/default/textures/toolbar_icons/speak.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/toolbar_icons/view.png b/indra/newview/skins/default/textures/toolbar_icons/view.png
index ddf0df7c26..ddf0df7c26 100644..100755
--- a/indra/newview/skins/default/textures/toolbar_icons/view.png
+++ b/indra/newview/skins/default/textures/toolbar_icons/view.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/transparent.j2c b/indra/newview/skins/default/textures/transparent.j2c
index 1068e940b9..1068e940b9 100644..100755
--- a/indra/newview/skins/default/textures/transparent.j2c
+++ b/indra/newview/skins/default/textures/transparent.j2c
Binary files differ
diff --git a/indra/newview/skins/default/textures/up_arrow.png b/indra/newview/skins/default/textures/up_arrow.png
index fe68ad49dc..fe68ad49dc 100644..100755
--- a/indra/newview/skins/default/textures/up_arrow.png
+++ b/indra/newview/skins/default/textures/up_arrow.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/uv_test1.j2c b/indra/newview/skins/default/textures/uv_test1.j2c
index 3d5b541796..3d5b541796 100644..100755
--- a/indra/newview/skins/default/textures/uv_test1.j2c
+++ b/indra/newview/skins/default/textures/uv_test1.j2c
Binary files differ
diff --git a/indra/newview/skins/default/textures/uv_test2.tga b/indra/newview/skins/default/textures/uv_test2.tga
index a16000d1e4..a16000d1e4 100644..100755
--- a/indra/newview/skins/default/textures/uv_test2.tga
+++ b/indra/newview/skins/default/textures/uv_test2.tga
Binary files differ
diff --git a/indra/newview/skins/default/textures/voice_meter_dot.j2c b/indra/newview/skins/default/textures/voice_meter_dot.j2c
index e536c3338a..e536c3338a 100644..100755
--- a/indra/newview/skins/default/textures/voice_meter_dot.j2c
+++ b/indra/newview/skins/default/textures/voice_meter_dot.j2c
Binary files differ
diff --git a/indra/newview/skins/default/textures/voice_meter_rings.j2c b/indra/newview/skins/default/textures/voice_meter_rings.j2c
index 17e7c6c6a1..17e7c6c6a1 100644..100755
--- a/indra/newview/skins/default/textures/voice_meter_rings.j2c
+++ b/indra/newview/skins/default/textures/voice_meter_rings.j2c
Binary files differ
diff --git a/indra/newview/skins/default/textures/white.tga b/indra/newview/skins/default/textures/white.tga
index 9fe68631cf..9fe68631cf 100644..100755
--- a/indra/newview/skins/default/textures/white.tga
+++ b/indra/newview/skins/default/textures/white.tga
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/Arrow_Down.png b/indra/newview/skins/default/textures/widgets/Arrow_Down.png
index e10f6472eb..e10f6472eb 100644..100755
--- a/indra/newview/skins/default/textures/widgets/Arrow_Down.png
+++ b/indra/newview/skins/default/textures/widgets/Arrow_Down.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/Arrow_Left.png b/indra/newview/skins/default/textures/widgets/Arrow_Left.png
new file mode 100755
index 0000000000..a424282839
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/Arrow_Left.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/Arrow_Right.png b/indra/newview/skins/default/textures/widgets/Arrow_Right.png
new file mode 100755
index 0000000000..e32bee8f34
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/Arrow_Right.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/Arrow_Small_Left.png b/indra/newview/skins/default/textures/widgets/Arrow_Small_Left.png
index 2d624c3779..2d624c3779 100644..100755
--- a/indra/newview/skins/default/textures/widgets/Arrow_Small_Left.png
+++ b/indra/newview/skins/default/textures/widgets/Arrow_Small_Left.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/Arrow_Small_Right.png b/indra/newview/skins/default/textures/widgets/Arrow_Small_Right.png
index 91c03c426e..91c03c426e 100644..100755
--- a/indra/newview/skins/default/textures/widgets/Arrow_Small_Right.png
+++ b/indra/newview/skins/default/textures/widgets/Arrow_Small_Right.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/Arrow_Small_Up.png b/indra/newview/skins/default/textures/widgets/Arrow_Small_Up.png
index 38aac0e5ca..38aac0e5ca 100644..100755
--- a/indra/newview/skins/default/textures/widgets/Arrow_Small_Up.png
+++ b/indra/newview/skins/default/textures/widgets/Arrow_Small_Up.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/Arrow_Up.png b/indra/newview/skins/default/textures/widgets/Arrow_Up.png
index 48df69d82e..48df69d82e 100644..100755
--- a/indra/newview/skins/default/textures/widgets/Arrow_Up.png
+++ b/indra/newview/skins/default/textures/widgets/Arrow_Up.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/Badge_Background.png b/indra/newview/skins/default/textures/widgets/Badge_Background.png
index 5089c30312..5089c30312 100644..100755
--- a/indra/newview/skins/default/textures/widgets/Badge_Background.png
+++ b/indra/newview/skins/default/textures/widgets/Badge_Background.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/Badge_Border.png b/indra/newview/skins/default/textures/widgets/Badge_Border.png
index 4b086a63fb..4b086a63fb 100644..100755
--- a/indra/newview/skins/default/textures/widgets/Badge_Border.png
+++ b/indra/newview/skins/default/textures/widgets/Badge_Border.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Left_Disabled.png b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Left_Disabled.png
index c7c0eaa96b..c7c0eaa96b 100644..100755
--- a/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Left_Disabled.png
+++ b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Left_Disabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Left_Off.png b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Left_Off.png
index 4a73c254fc..4a73c254fc 100644..100755
--- a/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Left_Off.png
+++ b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Left_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Left_Over.png b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Left_Over.png
index 6fb5c432de..6fb5c432de 100644..100755
--- a/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Left_Over.png
+++ b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Left_Over.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Left_Press.png b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Left_Press.png
index fa18517933..fa18517933 100644..100755
--- a/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Left_Press.png
+++ b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Left_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Middle_Disabled.png b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Middle_Disabled.png
index bed1a701bd..bed1a701bd 100644..100755
--- a/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Middle_Disabled.png
+++ b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Middle_Disabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Middle_Off.png b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Middle_Off.png
index 57ce9af574..57ce9af574 100644..100755
--- a/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Middle_Off.png
+++ b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Middle_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Middle_Over.png b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Middle_Over.png
index 2c43022f0e..2c43022f0e 100644..100755
--- a/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Middle_Over.png
+++ b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Middle_Over.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Middle_Press.png b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Middle_Press.png
index 6b8c1baca4..6b8c1baca4 100644..100755
--- a/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Middle_Press.png
+++ b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Middle_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Right_Disabled.png b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Right_Disabled.png
index 51505e80c5..51505e80c5 100644..100755
--- a/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Right_Disabled.png
+++ b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Right_Disabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Right_Off.png b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Right_Off.png
index 9f93efbd93..9f93efbd93 100644..100755
--- a/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Right_Off.png
+++ b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Right_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Right_Over.png b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Right_Over.png
index 3a4ec1a315..3a4ec1a315 100644..100755
--- a/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Right_Over.png
+++ b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Right_Over.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Right_Press.png b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Right_Press.png
index 1f1b4c2ed5..1f1b4c2ed5 100644..100755
--- a/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Right_Press.png
+++ b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Right_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/Checkbox_Disabled.png b/indra/newview/skins/default/textures/widgets/Checkbox_Disabled.png
index c1ee210099..c1ee210099 100644..100755
--- a/indra/newview/skins/default/textures/widgets/Checkbox_Disabled.png
+++ b/indra/newview/skins/default/textures/widgets/Checkbox_Disabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/Checkbox_Off.png b/indra/newview/skins/default/textures/widgets/Checkbox_Off.png
index 2525405f37..2525405f37 100644..100755
--- a/indra/newview/skins/default/textures/widgets/Checkbox_Off.png
+++ b/indra/newview/skins/default/textures/widgets/Checkbox_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/Checkbox_On.png b/indra/newview/skins/default/textures/widgets/Checkbox_On.png
index 2d9dba1592..2d9dba1592 100644..100755
--- a/indra/newview/skins/default/textures/widgets/Checkbox_On.png
+++ b/indra/newview/skins/default/textures/widgets/Checkbox_On.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/Checkbox_On_Disabled.png b/indra/newview/skins/default/textures/widgets/Checkbox_On_Disabled.png
index beaa7bcbf6..beaa7bcbf6 100644..100755
--- a/indra/newview/skins/default/textures/widgets/Checkbox_On_Disabled.png
+++ b/indra/newview/skins/default/textures/widgets/Checkbox_On_Disabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/Checkbox_On_Press.png b/indra/newview/skins/default/textures/widgets/Checkbox_On_Press.png
index 5bced95a89..5bced95a89 100644..100755
--- a/indra/newview/skins/default/textures/widgets/Checkbox_On_Press.png
+++ b/indra/newview/skins/default/textures/widgets/Checkbox_On_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/Checkbox_Press.png b/indra/newview/skins/default/textures/widgets/Checkbox_Press.png
index 44be193678..44be193678 100644..100755
--- a/indra/newview/skins/default/textures/widgets/Checkbox_Press.png
+++ b/indra/newview/skins/default/textures/widgets/Checkbox_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/ComboButton_Disabled.png b/indra/newview/skins/default/textures/widgets/ComboButton_Disabled.png
index d0fff1b3c3..d0fff1b3c3 100644..100755
--- a/indra/newview/skins/default/textures/widgets/ComboButton_Disabled.png
+++ b/indra/newview/skins/default/textures/widgets/ComboButton_Disabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/ComboButton_Hover.png b/indra/newview/skins/default/textures/widgets/ComboButton_Hover.png
new file mode 100644
index 0000000000..d492b30b40
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/ComboButton_Hover.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/ComboButton_Off.png b/indra/newview/skins/default/textures/widgets/ComboButton_Off.png
index 80402458b7..80402458b7 100644..100755
--- a/indra/newview/skins/default/textures/widgets/ComboButton_Off.png
+++ b/indra/newview/skins/default/textures/widgets/ComboButton_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/ComboButton_On.png b/indra/newview/skins/default/textures/widgets/ComboButton_On.png
index b42cc7542e..b42cc7542e 100644..100755
--- a/indra/newview/skins/default/textures/widgets/ComboButton_On.png
+++ b/indra/newview/skins/default/textures/widgets/ComboButton_On.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/ComboButton_Selected.png b/indra/newview/skins/default/textures/widgets/ComboButton_Selected.png
index bbc0657487..bbc0657487 100644..100755
--- a/indra/newview/skins/default/textures/widgets/ComboButton_Selected.png
+++ b/indra/newview/skins/default/textures/widgets/ComboButton_Selected.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/ComboButton_UpOff.png b/indra/newview/skins/default/textures/widgets/ComboButton_UpOff.png
index 2330cb420b..2330cb420b 100644..100755
--- a/indra/newview/skins/default/textures/widgets/ComboButton_UpOff.png
+++ b/indra/newview/skins/default/textures/widgets/ComboButton_UpOff.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/ComboButton_UpSelected.png b/indra/newview/skins/default/textures/widgets/ComboButton_UpSelected.png
index b7b5c2e1d4..b7b5c2e1d4 100644..100755
--- a/indra/newview/skins/default/textures/widgets/ComboButton_UpSelected.png
+++ b/indra/newview/skins/default/textures/widgets/ComboButton_UpSelected.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/DisclosureArrow_Opened_Off.png b/indra/newview/skins/default/textures/widgets/DisclosureArrow_Opened_Off.png
index 75057938d2..75057938d2 100644..100755
--- a/indra/newview/skins/default/textures/widgets/DisclosureArrow_Opened_Off.png
+++ b/indra/newview/skins/default/textures/widgets/DisclosureArrow_Opened_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/DropDown_Disabled.png b/indra/newview/skins/default/textures/widgets/DropDown_Disabled.png
index b295752ea9..b295752ea9 100644..100755
--- a/indra/newview/skins/default/textures/widgets/DropDown_Disabled.png
+++ b/indra/newview/skins/default/textures/widgets/DropDown_Disabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/DropDown_Off.png b/indra/newview/skins/default/textures/widgets/DropDown_Off.png
index 4764ed4ee2..4764ed4ee2 100644..100755
--- a/indra/newview/skins/default/textures/widgets/DropDown_Off.png
+++ b/indra/newview/skins/default/textures/widgets/DropDown_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/DropDown_On.png b/indra/newview/skins/default/textures/widgets/DropDown_On.png
index 10262d3979..10262d3979 100644..100755
--- a/indra/newview/skins/default/textures/widgets/DropDown_On.png
+++ b/indra/newview/skins/default/textures/widgets/DropDown_On.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/DropDown_Press.png b/indra/newview/skins/default/textures/widgets/DropDown_Press.png
index 16cb25cc77..16cb25cc77 100644..100755
--- a/indra/newview/skins/default/textures/widgets/DropDown_Press.png
+++ b/indra/newview/skins/default/textures/widgets/DropDown_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/DropTarget.png b/indra/newview/skins/default/textures/widgets/DropTarget.png
index 3740c98cbc..3740c98cbc 100644..100755
--- a/indra/newview/skins/default/textures/widgets/DropTarget.png
+++ b/indra/newview/skins/default/textures/widgets/DropTarget.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/Error_Tag_Background.png b/indra/newview/skins/default/textures/widgets/Error_Tag_Background.png
index c8dbc8e87a..c8dbc8e87a 100644..100755
--- a/indra/newview/skins/default/textures/widgets/Error_Tag_Background.png
+++ b/indra/newview/skins/default/textures/widgets/Error_Tag_Background.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/Linden_Dollar_Alert.png b/indra/newview/skins/default/textures/widgets/Linden_Dollar_Alert.png
index a1f21e8194..a1f21e8194 100644..100755
--- a/indra/newview/skins/default/textures/widgets/Linden_Dollar_Alert.png
+++ b/indra/newview/skins/default/textures/widgets/Linden_Dollar_Alert.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/Linden_Dollar_Background.png b/indra/newview/skins/default/textures/widgets/Linden_Dollar_Background.png
index 61f9b076ce..61f9b076ce 100644..100755
--- a/indra/newview/skins/default/textures/widgets/Linden_Dollar_Background.png
+++ b/indra/newview/skins/default/textures/widgets/Linden_Dollar_Background.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/ListItem_Over.png b/indra/newview/skins/default/textures/widgets/ListItem_Over.png
index 4b2b9ab3e5..4b2b9ab3e5 100644..100755
--- a/indra/newview/skins/default/textures/widgets/ListItem_Over.png
+++ b/indra/newview/skins/default/textures/widgets/ListItem_Over.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/ListItem_Select.png b/indra/newview/skins/default/textures/widgets/ListItem_Select.png
index 317c672441..317c672441 100644..100755
--- a/indra/newview/skins/default/textures/widgets/ListItem_Select.png
+++ b/indra/newview/skins/default/textures/widgets/ListItem_Select.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/MarketplaceBtn_Off.png b/indra/newview/skins/default/textures/widgets/MarketplaceBtn_Off.png
index e603c44384..e603c44384 100644..100755
--- a/indra/newview/skins/default/textures/widgets/MarketplaceBtn_Off.png
+++ b/indra/newview/skins/default/textures/widgets/MarketplaceBtn_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/MarketplaceBtn_Selected.png b/indra/newview/skins/default/textures/widgets/MarketplaceBtn_Selected.png
index fbc164123f..fbc164123f 100644..100755
--- a/indra/newview/skins/default/textures/widgets/MarketplaceBtn_Selected.png
+++ b/indra/newview/skins/default/textures/widgets/MarketplaceBtn_Selected.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/New_Tag_Background.png b/indra/newview/skins/default/textures/widgets/New_Tag_Background.png
index cd639dd80f..cd639dd80f 100644..100755
--- a/indra/newview/skins/default/textures/widgets/New_Tag_Background.png
+++ b/indra/newview/skins/default/textures/widgets/New_Tag_Background.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/New_Tag_Border.png b/indra/newview/skins/default/textures/widgets/New_Tag_Border.png
index 56df0d0127..56df0d0127 100644..100755
--- a/indra/newview/skins/default/textures/widgets/New_Tag_Border.png
+++ b/indra/newview/skins/default/textures/widgets/New_Tag_Border.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/ProgressBar.png b/indra/newview/skins/default/textures/widgets/ProgressBar.png
index 3f0e4eba28..3f0e4eba28 100644..100755
--- a/indra/newview/skins/default/textures/widgets/ProgressBar.png
+++ b/indra/newview/skins/default/textures/widgets/ProgressBar.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/ProgressTrack.png b/indra/newview/skins/default/textures/widgets/ProgressTrack.png
index bb6d9f4144..bb6d9f4144 100644..100755
--- a/indra/newview/skins/default/textures/widgets/ProgressTrack.png
+++ b/indra/newview/skins/default/textures/widgets/ProgressTrack.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/PushButton_Disabled.png b/indra/newview/skins/default/textures/widgets/PushButton_Disabled.png
index 04e91bdaab..04e91bdaab 100644..100755
--- a/indra/newview/skins/default/textures/widgets/PushButton_Disabled.png
+++ b/indra/newview/skins/default/textures/widgets/PushButton_Disabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/PushButton_Off.png b/indra/newview/skins/default/textures/widgets/PushButton_Off.png
index 1ee0329e66..1ee0329e66 100644..100755
--- a/indra/newview/skins/default/textures/widgets/PushButton_Off.png
+++ b/indra/newview/skins/default/textures/widgets/PushButton_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/PushButton_On.png b/indra/newview/skins/default/textures/widgets/PushButton_On.png
index 661d1c5611..661d1c5611 100644..100755
--- a/indra/newview/skins/default/textures/widgets/PushButton_On.png
+++ b/indra/newview/skins/default/textures/widgets/PushButton_On.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/PushButton_On_Selected.png b/indra/newview/skins/default/textures/widgets/PushButton_On_Selected.png
index 48e8aa2eab..48e8aa2eab 100644..100755
--- a/indra/newview/skins/default/textures/widgets/PushButton_On_Selected.png
+++ b/indra/newview/skins/default/textures/widgets/PushButton_On_Selected.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/PushButton_Over.png b/indra/newview/skins/default/textures/widgets/PushButton_Over.png
index c227f07513..c227f07513 100644..100755
--- a/indra/newview/skins/default/textures/widgets/PushButton_Over.png
+++ b/indra/newview/skins/default/textures/widgets/PushButton_Over.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/PushButton_Press.png b/indra/newview/skins/default/textures/widgets/PushButton_Press.png
index 0a4a3a6ad9..0a4a3a6ad9 100644..100755
--- a/indra/newview/skins/default/textures/widgets/PushButton_Press.png
+++ b/indra/newview/skins/default/textures/widgets/PushButton_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/PushButton_Selected.png b/indra/newview/skins/default/textures/widgets/PushButton_Selected.png
index 0a4a3a6ad9..0a4a3a6ad9 100644..100755
--- a/indra/newview/skins/default/textures/widgets/PushButton_Selected.png
+++ b/indra/newview/skins/default/textures/widgets/PushButton_Selected.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/PushButton_Selected_Disabled.png b/indra/newview/skins/default/textures/widgets/PushButton_Selected_Disabled.png
index 661d1c5611..661d1c5611 100644..100755
--- a/indra/newview/skins/default/textures/widgets/PushButton_Selected_Disabled.png
+++ b/indra/newview/skins/default/textures/widgets/PushButton_Selected_Disabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/PushButton_Selected_Press.png b/indra/newview/skins/default/textures/widgets/PushButton_Selected_Press.png
index 48e8aa2eab..48e8aa2eab 100644..100755
--- a/indra/newview/skins/default/textures/widgets/PushButton_Selected_Press.png
+++ b/indra/newview/skins/default/textures/widgets/PushButton_Selected_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/RadioButton_Disabled.png b/indra/newview/skins/default/textures/widgets/RadioButton_Disabled.png
index a1052684b9..a1052684b9 100644..100755
--- a/indra/newview/skins/default/textures/widgets/RadioButton_Disabled.png
+++ b/indra/newview/skins/default/textures/widgets/RadioButton_Disabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/RadioButton_Off.png b/indra/newview/skins/default/textures/widgets/RadioButton_Off.png
index c58e0305ef..c58e0305ef 100644..100755
--- a/indra/newview/skins/default/textures/widgets/RadioButton_Off.png
+++ b/indra/newview/skins/default/textures/widgets/RadioButton_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/RadioButton_On.png b/indra/newview/skins/default/textures/widgets/RadioButton_On.png
index c09a2197c7..c09a2197c7 100644..100755
--- a/indra/newview/skins/default/textures/widgets/RadioButton_On.png
+++ b/indra/newview/skins/default/textures/widgets/RadioButton_On.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/RadioButton_On_Disabled.png b/indra/newview/skins/default/textures/widgets/RadioButton_On_Disabled.png
index d7d444fd0c..d7d444fd0c 100644..100755
--- a/indra/newview/skins/default/textures/widgets/RadioButton_On_Disabled.png
+++ b/indra/newview/skins/default/textures/widgets/RadioButton_On_Disabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/RadioButton_On_Press.png b/indra/newview/skins/default/textures/widgets/RadioButton_On_Press.png
index a707e8ceb8..a707e8ceb8 100644..100755
--- a/indra/newview/skins/default/textures/widgets/RadioButton_On_Press.png
+++ b/indra/newview/skins/default/textures/widgets/RadioButton_On_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/RadioButton_Press.png b/indra/newview/skins/default/textures/widgets/RadioButton_Press.png
index 33eaa14030..33eaa14030 100644..100755
--- a/indra/newview/skins/default/textures/widgets/RadioButton_Press.png
+++ b/indra/newview/skins/default/textures/widgets/RadioButton_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/ScrollArrow_Down.png b/indra/newview/skins/default/textures/widgets/ScrollArrow_Down.png
index 186822da43..186822da43 100644..100755
--- a/indra/newview/skins/default/textures/widgets/ScrollArrow_Down.png
+++ b/indra/newview/skins/default/textures/widgets/ScrollArrow_Down.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/ScrollArrow_Down_Opaque.png b/indra/newview/skins/default/textures/widgets/ScrollArrow_Down_Opaque.png
index a396380fb2..a396380fb2 100644..100755
--- a/indra/newview/skins/default/textures/widgets/ScrollArrow_Down_Opaque.png
+++ b/indra/newview/skins/default/textures/widgets/ScrollArrow_Down_Opaque.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/ScrollArrow_Down_Over_Opaque.png b/indra/newview/skins/default/textures/widgets/ScrollArrow_Down_Over_Opaque.png
index 9568dea78a..9568dea78a 100644..100755
--- a/indra/newview/skins/default/textures/widgets/ScrollArrow_Down_Over_Opaque.png
+++ b/indra/newview/skins/default/textures/widgets/ScrollArrow_Down_Over_Opaque.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/ScrollArrow_Left.png b/indra/newview/skins/default/textures/widgets/ScrollArrow_Left.png
index 42f999a451..42f999a451 100644..100755
--- a/indra/newview/skins/default/textures/widgets/ScrollArrow_Left.png
+++ b/indra/newview/skins/default/textures/widgets/ScrollArrow_Left.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/ScrollArrow_Left_Opaque.png b/indra/newview/skins/default/textures/widgets/ScrollArrow_Left_Opaque.png
index 549b3980f6..549b3980f6 100644..100755
--- a/indra/newview/skins/default/textures/widgets/ScrollArrow_Left_Opaque.png
+++ b/indra/newview/skins/default/textures/widgets/ScrollArrow_Left_Opaque.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/ScrollArrow_Left_Over_Opaque.png b/indra/newview/skins/default/textures/widgets/ScrollArrow_Left_Over_Opaque.png
index a74abd5d8a..a74abd5d8a 100644..100755
--- a/indra/newview/skins/default/textures/widgets/ScrollArrow_Left_Over_Opaque.png
+++ b/indra/newview/skins/default/textures/widgets/ScrollArrow_Left_Over_Opaque.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/ScrollArrow_Right.png b/indra/newview/skins/default/textures/widgets/ScrollArrow_Right.png
index 176ffcdbb9..176ffcdbb9 100644..100755
--- a/indra/newview/skins/default/textures/widgets/ScrollArrow_Right.png
+++ b/indra/newview/skins/default/textures/widgets/ScrollArrow_Right.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/ScrollArrow_Right_Opaque.png b/indra/newview/skins/default/textures/widgets/ScrollArrow_Right_Opaque.png
index 36056d0ad9..36056d0ad9 100644..100755
--- a/indra/newview/skins/default/textures/widgets/ScrollArrow_Right_Opaque.png
+++ b/indra/newview/skins/default/textures/widgets/ScrollArrow_Right_Opaque.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/ScrollArrow_Right_Over_Opaque.png b/indra/newview/skins/default/textures/widgets/ScrollArrow_Right_Over_Opaque.png
index 0c1fd6956b..0c1fd6956b 100644..100755
--- a/indra/newview/skins/default/textures/widgets/ScrollArrow_Right_Over_Opaque.png
+++ b/indra/newview/skins/default/textures/widgets/ScrollArrow_Right_Over_Opaque.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/ScrollArrow_Up.png b/indra/newview/skins/default/textures/widgets/ScrollArrow_Up.png
index 4d245eb57a..4d245eb57a 100644..100755
--- a/indra/newview/skins/default/textures/widgets/ScrollArrow_Up.png
+++ b/indra/newview/skins/default/textures/widgets/ScrollArrow_Up.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/ScrollArrow_Up_Opaque.png b/indra/newview/skins/default/textures/widgets/ScrollArrow_Up_Opaque.png
index 67a7a5568b..67a7a5568b 100644..100755
--- a/indra/newview/skins/default/textures/widgets/ScrollArrow_Up_Opaque.png
+++ b/indra/newview/skins/default/textures/widgets/ScrollArrow_Up_Opaque.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/ScrollArrow_Up_Over_Opaque.png b/indra/newview/skins/default/textures/widgets/ScrollArrow_Up_Over_Opaque.png
index 0cc8c4404b..0cc8c4404b 100644..100755
--- a/indra/newview/skins/default/textures/widgets/ScrollArrow_Up_Over_Opaque.png
+++ b/indra/newview/skins/default/textures/widgets/ScrollArrow_Up_Over_Opaque.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/ScrollThumb_Horiz.png b/indra/newview/skins/default/textures/widgets/ScrollThumb_Horiz.png
index 8a085aa966..8a085aa966 100644..100755
--- a/indra/newview/skins/default/textures/widgets/ScrollThumb_Horiz.png
+++ b/indra/newview/skins/default/textures/widgets/ScrollThumb_Horiz.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/ScrollThumb_Vert.png b/indra/newview/skins/default/textures/widgets/ScrollThumb_Vert.png
index fc7fd93e7a..fc7fd93e7a 100644..100755
--- a/indra/newview/skins/default/textures/widgets/ScrollThumb_Vert.png
+++ b/indra/newview/skins/default/textures/widgets/ScrollThumb_Vert.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/ScrollTrack_Horiz.png b/indra/newview/skins/default/textures/widgets/ScrollTrack_Horiz.png
index 4f31c48c02..4f31c48c02 100644..100755
--- a/indra/newview/skins/default/textures/widgets/ScrollTrack_Horiz.png
+++ b/indra/newview/skins/default/textures/widgets/ScrollTrack_Horiz.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/ScrollTrack_Vert.png b/indra/newview/skins/default/textures/widgets/ScrollTrack_Vert.png
index f89ee3f68f..f89ee3f68f 100644..100755
--- a/indra/newview/skins/default/textures/widgets/ScrollTrack_Vert.png
+++ b/indra/newview/skins/default/textures/widgets/ScrollTrack_Vert.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Disabled.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Disabled.png
index 3b39c51a77..3b39c51a77 100644..100755
--- a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Disabled.png
+++ b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Disabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Off.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Off.png
index 57ed79d733..57ed79d733 100644..100755
--- a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Off.png
+++ b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Over.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Over.png
index 5b8878e0cb..5b8878e0cb 100644..100755
--- a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Over.png
+++ b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Over.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Press.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Press.png
index 379953216b..379953216b 100644..100755
--- a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Press.png
+++ b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Selected.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Selected.png
index 379953216b..379953216b 100644..100755
--- a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Selected.png
+++ b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Selected.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Selected_Disabled.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Selected_Disabled.png
index 77c4224539..77c4224539 100644..100755
--- a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Selected_Disabled.png
+++ b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Selected_Disabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Selected_Over.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Selected_Over.png
index 8b93dd551e..8b93dd551e 100644..100755
--- a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Selected_Over.png
+++ b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Selected_Over.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Selected_Press.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Selected_Press.png
index 3f207cbea2..3f207cbea2 100644..100755
--- a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Selected_Press.png
+++ b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Left_Selected_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_Disabled.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_Disabled.png
index deb87c8489..deb87c8489 100644..100755
--- a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_Disabled.png
+++ b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_Disabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_Selected.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_Selected.png
index ca7027da91..ca7027da91 100644..100755
--- a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_Selected.png
+++ b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_Selected.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_Selected_Disabled.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_Selected_Disabled.png
index 220df9db25..220df9db25 100644..100755
--- a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_Selected_Disabled.png
+++ b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_Selected_Disabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_Selected_Press.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_Selected_Press.png
index dde367f05e..dde367f05e 100644..100755
--- a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_Selected_Press.png
+++ b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Middle_Selected_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Disabled.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Disabled.png
index 8e6b9c8c6f..8e6b9c8c6f 100644..100755
--- a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Disabled.png
+++ b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Disabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Off.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Off.png
index b1521199ff..b1521199ff 100644..100755
--- a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Off.png
+++ b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_On_Selected.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_On_Selected.png
index 1574f48b28..1574f48b28 100644..100755
--- a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_On_Selected.png
+++ b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_On_Selected.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Over.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Over.png
index 2717e7d7b0..2717e7d7b0 100644..100755
--- a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Over.png
+++ b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Over.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Press.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Press.png
index 3883518033..3883518033 100644..100755
--- a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Press.png
+++ b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Selected.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Selected.png
index 3883518033..3883518033 100644..100755
--- a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Selected.png
+++ b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Selected.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Selected_Disabled.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Selected_Disabled.png
index ab31f6ded7..ab31f6ded7 100644..100755
--- a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Selected_Disabled.png
+++ b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Selected_Disabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Selected_Press.png b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Selected_Press.png
index 1574f48b28..1574f48b28 100644..100755
--- a/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Selected_Press.png
+++ b/indra/newview/skins/default/textures/widgets/SegmentedBtn_Right_Selected_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/SliderThumb_Disabled.png b/indra/newview/skins/default/textures/widgets/SliderThumb_Disabled.png
index b627232012..b627232012 100644..100755
--- a/indra/newview/skins/default/textures/widgets/SliderThumb_Disabled.png
+++ b/indra/newview/skins/default/textures/widgets/SliderThumb_Disabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/SliderThumb_Off.png b/indra/newview/skins/default/textures/widgets/SliderThumb_Off.png
index b627232012..b627232012 100644..100755
--- a/indra/newview/skins/default/textures/widgets/SliderThumb_Off.png
+++ b/indra/newview/skins/default/textures/widgets/SliderThumb_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/SliderThumb_Press.png b/indra/newview/skins/default/textures/widgets/SliderThumb_Press.png
index 7081f9cfe0..7081f9cfe0 100644..100755
--- a/indra/newview/skins/default/textures/widgets/SliderThumb_Press.png
+++ b/indra/newview/skins/default/textures/widgets/SliderThumb_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/SliderTrack_Horiz.png b/indra/newview/skins/default/textures/widgets/SliderTrack_Horiz.png
index 232006ee5a..232006ee5a 100644..100755
--- a/indra/newview/skins/default/textures/widgets/SliderTrack_Horiz.png
+++ b/indra/newview/skins/default/textures/widgets/SliderTrack_Horiz.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/SliderTrack_Vert.png b/indra/newview/skins/default/textures/widgets/SliderTrack_Vert.png
index cd002b3973..cd002b3973 100644..100755
--- a/indra/newview/skins/default/textures/widgets/SliderTrack_Vert.png
+++ b/indra/newview/skins/default/textures/widgets/SliderTrack_Vert.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/Stepper_Down_Off.png b/indra/newview/skins/default/textures/widgets/Stepper_Down_Off.png
index cf0d8ee2c1..cf0d8ee2c1 100644..100755
--- a/indra/newview/skins/default/textures/widgets/Stepper_Down_Off.png
+++ b/indra/newview/skins/default/textures/widgets/Stepper_Down_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/Stepper_Down_Press.png b/indra/newview/skins/default/textures/widgets/Stepper_Down_Press.png
index fe3a7beafd..fe3a7beafd 100644..100755
--- a/indra/newview/skins/default/textures/widgets/Stepper_Down_Press.png
+++ b/indra/newview/skins/default/textures/widgets/Stepper_Down_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/Stepper_Up_Off.png b/indra/newview/skins/default/textures/widgets/Stepper_Up_Off.png
index 133589b8a6..133589b8a6 100644..100755
--- a/indra/newview/skins/default/textures/widgets/Stepper_Up_Off.png
+++ b/indra/newview/skins/default/textures/widgets/Stepper_Up_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/Stepper_Up_Press.png b/indra/newview/skins/default/textures/widgets/Stepper_Up_Press.png
index e83babc519..e83babc519 100644..100755
--- a/indra/newview/skins/default/textures/widgets/Stepper_Up_Press.png
+++ b/indra/newview/skins/default/textures/widgets/Stepper_Up_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/TextField_Active.png b/indra/newview/skins/default/textures/widgets/TextField_Active.png
index ca6daab4e0..ca6daab4e0 100644..100755
--- a/indra/newview/skins/default/textures/widgets/TextField_Active.png
+++ b/indra/newview/skins/default/textures/widgets/TextField_Active.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/TextField_Disabled.png b/indra/newview/skins/default/textures/widgets/TextField_Disabled.png
index 3d205a3f2e..3d205a3f2e 100644..100755
--- a/indra/newview/skins/default/textures/widgets/TextField_Disabled.png
+++ b/indra/newview/skins/default/textures/widgets/TextField_Disabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/TextField_Off.png b/indra/newview/skins/default/textures/widgets/TextField_Off.png
index 911d907acc..911d907acc 100644..100755
--- a/indra/newview/skins/default/textures/widgets/TextField_Off.png
+++ b/indra/newview/skins/default/textures/widgets/TextField_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/TextField_Search_Active.png b/indra/newview/skins/default/textures/widgets/TextField_Search_Active.png
index fa79cb6260..fa79cb6260 100644..100755
--- a/indra/newview/skins/default/textures/widgets/TextField_Search_Active.png
+++ b/indra/newview/skins/default/textures/widgets/TextField_Search_Active.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/TextField_Search_Disabled.png b/indra/newview/skins/default/textures/widgets/TextField_Search_Disabled.png
index 8b504af101..8b504af101 100644..100755
--- a/indra/newview/skins/default/textures/widgets/TextField_Search_Disabled.png
+++ b/indra/newview/skins/default/textures/widgets/TextField_Search_Disabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/TextField_Search_Off.png b/indra/newview/skins/default/textures/widgets/TextField_Search_Off.png
index 862b13d219..862b13d219 100644..100755
--- a/indra/newview/skins/default/textures/widgets/TextField_Search_Off.png
+++ b/indra/newview/skins/default/textures/widgets/TextField_Search_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/Tooltip.png b/indra/newview/skins/default/textures/widgets/Tooltip.png
index f989ac9083..f989ac9083 100644..100755
--- a/indra/newview/skins/default/textures/widgets/Tooltip.png
+++ b/indra/newview/skins/default/textures/widgets/Tooltip.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/bevel_background.png b/indra/newview/skins/default/textures/widgets/bevel_background.png
index fb5067503d..fb5067503d 100644..100755
--- a/indra/newview/skins/default/textures/widgets/bevel_background.png
+++ b/indra/newview/skins/default/textures/widgets/bevel_background.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/buy_off.png b/indra/newview/skins/default/textures/widgets/buy_off.png
index ee5979046f..ee5979046f 100644..100755
--- a/indra/newview/skins/default/textures/widgets/buy_off.png
+++ b/indra/newview/skins/default/textures/widgets/buy_off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/buy_over.png b/indra/newview/skins/default/textures/widgets/buy_over.png
index 93adb68c86..93adb68c86 100644..100755
--- a/indra/newview/skins/default/textures/widgets/buy_over.png
+++ b/indra/newview/skins/default/textures/widgets/buy_over.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/buy_press.png b/indra/newview/skins/default/textures/widgets/buy_press.png
index 3f442d6eaa..3f442d6eaa 100644..100755
--- a/indra/newview/skins/default/textures/widgets/buy_press.png
+++ b/indra/newview/skins/default/textures/widgets/buy_press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/horizontal_drag_handle.png b/indra/newview/skins/default/textures/widgets/horizontal_drag_handle.png
new file mode 100644
index 0000000000..642eac4065
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/horizontal_drag_handle.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/jump_left_in.png b/indra/newview/skins/default/textures/widgets/jump_left_in.png
index a1425ccfa0..a1425ccfa0 100644..100755
--- a/indra/newview/skins/default/textures/widgets/jump_left_in.png
+++ b/indra/newview/skins/default/textures/widgets/jump_left_in.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/jump_left_out.png b/indra/newview/skins/default/textures/widgets/jump_left_out.png
index 38edf47d19..38edf47d19 100644..100755
--- a/indra/newview/skins/default/textures/widgets/jump_left_out.png
+++ b/indra/newview/skins/default/textures/widgets/jump_left_out.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/jump_right_in.png b/indra/newview/skins/default/textures/widgets/jump_right_in.png
index 39359ab2e2..39359ab2e2 100644..100755
--- a/indra/newview/skins/default/textures/widgets/jump_right_in.png
+++ b/indra/newview/skins/default/textures/widgets/jump_right_in.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/jump_right_out.png b/indra/newview/skins/default/textures/widgets/jump_right_out.png
index 3f76bbffac..3f76bbffac 100644..100755
--- a/indra/newview/skins/default/textures/widgets/jump_right_out.png
+++ b/indra/newview/skins/default/textures/widgets/jump_right_out.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/widgets/vertical_drag_handle.png b/indra/newview/skins/default/textures/widgets/vertical_drag_handle.png
new file mode 100644
index 0000000000..b06b70cf36
--- /dev/null
+++ b/indra/newview/skins/default/textures/widgets/vertical_drag_handle.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/windows/Dragbar.png b/indra/newview/skins/default/textures/windows/Dragbar.png
index d94dda1aae..d94dda1aae 100644..100755
--- a/indra/newview/skins/default/textures/windows/Dragbar.png
+++ b/indra/newview/skins/default/textures/windows/Dragbar.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/windows/Flyout_Left.png b/indra/newview/skins/default/textures/windows/Flyout_Left.png
index 6ac9fe2efd..6ac9fe2efd 100644..100755
--- a/indra/newview/skins/default/textures/windows/Flyout_Left.png
+++ b/indra/newview/skins/default/textures/windows/Flyout_Left.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/windows/Flyout_Pointer.png b/indra/newview/skins/default/textures/windows/Flyout_Pointer.png
index 69fc08ceaa..69fc08ceaa 100644..100755
--- a/indra/newview/skins/default/textures/windows/Flyout_Pointer.png
+++ b/indra/newview/skins/default/textures/windows/Flyout_Pointer.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/windows/Flyout_Right.png b/indra/newview/skins/default/textures/windows/Flyout_Right.png
index aa1f0625aa..aa1f0625aa 100644..100755
--- a/indra/newview/skins/default/textures/windows/Flyout_Right.png
+++ b/indra/newview/skins/default/textures/windows/Flyout_Right.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/windows/Icon_Close_Foreground.png b/indra/newview/skins/default/textures/windows/Icon_Close_Foreground.png
index 2292b79eda..2292b79eda 100644..100755
--- a/indra/newview/skins/default/textures/windows/Icon_Close_Foreground.png
+++ b/indra/newview/skins/default/textures/windows/Icon_Close_Foreground.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/windows/Icon_Close_Press.png b/indra/newview/skins/default/textures/windows/Icon_Close_Press.png
index ea547fca6f..ea547fca6f 100644..100755
--- a/indra/newview/skins/default/textures/windows/Icon_Close_Press.png
+++ b/indra/newview/skins/default/textures/windows/Icon_Close_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/windows/Icon_Close_Toast.png b/indra/newview/skins/default/textures/windows/Icon_Close_Toast.png
index ecf01c617a..ecf01c617a 100644..100755
--- a/indra/newview/skins/default/textures/windows/Icon_Close_Toast.png
+++ b/indra/newview/skins/default/textures/windows/Icon_Close_Toast.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/windows/Icon_Dock_Foreground.png b/indra/newview/skins/default/textures/windows/Icon_Dock_Foreground.png
index 4207ba68e5..4207ba68e5 100644..100755
--- a/indra/newview/skins/default/textures/windows/Icon_Dock_Foreground.png
+++ b/indra/newview/skins/default/textures/windows/Icon_Dock_Foreground.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/windows/Icon_Dock_Press.png b/indra/newview/skins/default/textures/windows/Icon_Dock_Press.png
index 2d09475783..2d09475783 100644..100755
--- a/indra/newview/skins/default/textures/windows/Icon_Dock_Press.png
+++ b/indra/newview/skins/default/textures/windows/Icon_Dock_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/windows/Icon_Gear_Background.png b/indra/newview/skins/default/textures/windows/Icon_Gear_Background.png
index 93d62a8d4f..93d62a8d4f 100644..100755
--- a/indra/newview/skins/default/textures/windows/Icon_Gear_Background.png
+++ b/indra/newview/skins/default/textures/windows/Icon_Gear_Background.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/windows/Icon_Gear_Foreground.png b/indra/newview/skins/default/textures/windows/Icon_Gear_Foreground.png
index b2b2a77a88..b2b2a77a88 100644..100755
--- a/indra/newview/skins/default/textures/windows/Icon_Gear_Foreground.png
+++ b/indra/newview/skins/default/textures/windows/Icon_Gear_Foreground.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/windows/Icon_Gear_Press.png b/indra/newview/skins/default/textures/windows/Icon_Gear_Press.png
index 6fc3744d6b..6fc3744d6b 100644..100755
--- a/indra/newview/skins/default/textures/windows/Icon_Gear_Press.png
+++ b/indra/newview/skins/default/textures/windows/Icon_Gear_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/windows/Icon_Help_Foreground.png b/indra/newview/skins/default/textures/windows/Icon_Help_Foreground.png
index 1a514742d3..1a514742d3 100644..100755
--- a/indra/newview/skins/default/textures/windows/Icon_Help_Foreground.png
+++ b/indra/newview/skins/default/textures/windows/Icon_Help_Foreground.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/windows/Icon_Help_Press.png b/indra/newview/skins/default/textures/windows/Icon_Help_Press.png
index 7478644b6a..7478644b6a 100644..100755
--- a/indra/newview/skins/default/textures/windows/Icon_Help_Press.png
+++ b/indra/newview/skins/default/textures/windows/Icon_Help_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/windows/Icon_Minimize_Foreground.png b/indra/newview/skins/default/textures/windows/Icon_Minimize_Foreground.png
index 9f72a5422b..9f72a5422b 100644..100755
--- a/indra/newview/skins/default/textures/windows/Icon_Minimize_Foreground.png
+++ b/indra/newview/skins/default/textures/windows/Icon_Minimize_Foreground.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/windows/Icon_Minimize_Press.png b/indra/newview/skins/default/textures/windows/Icon_Minimize_Press.png
index 07db8be1b0..07db8be1b0 100644..100755
--- a/indra/newview/skins/default/textures/windows/Icon_Minimize_Press.png
+++ b/indra/newview/skins/default/textures/windows/Icon_Minimize_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/windows/Icon_Restore_Foreground.png b/indra/newview/skins/default/textures/windows/Icon_Restore_Foreground.png
index 1e753aaf1d..1e753aaf1d 100644..100755
--- a/indra/newview/skins/default/textures/windows/Icon_Restore_Foreground.png
+++ b/indra/newview/skins/default/textures/windows/Icon_Restore_Foreground.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/windows/Icon_Restore_Press.png b/indra/newview/skins/default/textures/windows/Icon_Restore_Press.png
index be66b05230..be66b05230 100644..100755
--- a/indra/newview/skins/default/textures/windows/Icon_Restore_Press.png
+++ b/indra/newview/skins/default/textures/windows/Icon_Restore_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/windows/Icon_Undock_Foreground.png b/indra/newview/skins/default/textures/windows/Icon_Undock_Foreground.png
index 9a71d16a3f..9a71d16a3f 100644..100755
--- a/indra/newview/skins/default/textures/windows/Icon_Undock_Foreground.png
+++ b/indra/newview/skins/default/textures/windows/Icon_Undock_Foreground.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/windows/Inspector_Background.png b/indra/newview/skins/default/textures/windows/Inspector_Background.png
index 4c2a728ac5..4c2a728ac5 100644..100755
--- a/indra/newview/skins/default/textures/windows/Inspector_Background.png
+++ b/indra/newview/skins/default/textures/windows/Inspector_Background.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/windows/Inspector_Hover.png b/indra/newview/skins/default/textures/windows/Inspector_Hover.png
index feeee78033..feeee78033 100644..100755
--- a/indra/newview/skins/default/textures/windows/Inspector_Hover.png
+++ b/indra/newview/skins/default/textures/windows/Inspector_Hover.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/windows/Inspector_I.png b/indra/newview/skins/default/textures/windows/Inspector_I.png
index b4875fd638..b4875fd638 100644..100755
--- a/indra/newview/skins/default/textures/windows/Inspector_I.png
+++ b/indra/newview/skins/default/textures/windows/Inspector_I.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/windows/Resize_Corner.png b/indra/newview/skins/default/textures/windows/Resize_Corner.png
index 16ed63e428..16ed63e428 100644..100755
--- a/indra/newview/skins/default/textures/windows/Resize_Corner.png
+++ b/indra/newview/skins/default/textures/windows/Resize_Corner.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/windows/Toast_Background.png b/indra/newview/skins/default/textures/windows/Toast_Background.png
index f27d1a12ec..f27d1a12ec 100644..100755
--- a/indra/newview/skins/default/textures/windows/Toast_Background.png
+++ b/indra/newview/skins/default/textures/windows/Toast_Background.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/windows/Toast_CloseBtn.png b/indra/newview/skins/default/textures/windows/Toast_CloseBtn.png
index 78b137cdaf..78b137cdaf 100644..100755
--- a/indra/newview/skins/default/textures/windows/Toast_CloseBtn.png
+++ b/indra/newview/skins/default/textures/windows/Toast_CloseBtn.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/windows/Toast_Over.png b/indra/newview/skins/default/textures/windows/Toast_Over.png
index 807e8e553c..807e8e553c 100644..100755
--- a/indra/newview/skins/default/textures/windows/Toast_Over.png
+++ b/indra/newview/skins/default/textures/windows/Toast_Over.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/windows/Volume_Background.png b/indra/newview/skins/default/textures/windows/Volume_Background.png
index 43aaa441f5..43aaa441f5 100644..100755
--- a/indra/newview/skins/default/textures/windows/Volume_Background.png
+++ b/indra/newview/skins/default/textures/windows/Volume_Background.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/windows/Wearables_Divider.png b/indra/newview/skins/default/textures/windows/Wearables_Divider.png
index 9dce7bf45c..9dce7bf45c 100644..100755
--- a/indra/newview/skins/default/textures/windows/Wearables_Divider.png
+++ b/indra/newview/skins/default/textures/windows/Wearables_Divider.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/windows/Window_Background.png b/indra/newview/skins/default/textures/windows/Window_Background.png
index db253900af..db253900af 100644..100755
--- a/indra/newview/skins/default/textures/windows/Window_Background.png
+++ b/indra/newview/skins/default/textures/windows/Window_Background.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/windows/Window_Foreground.png b/indra/newview/skins/default/textures/windows/Window_Foreground.png
index b81ec5b43c..b81ec5b43c 100644..100755
--- a/indra/newview/skins/default/textures/windows/Window_Foreground.png
+++ b/indra/newview/skins/default/textures/windows/Window_Foreground.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/windows/Window_NoTitle_Background.png b/indra/newview/skins/default/textures/windows/Window_NoTitle_Background.png
index a570ac06bd..a570ac06bd 100644..100755
--- a/indra/newview/skins/default/textures/windows/Window_NoTitle_Background.png
+++ b/indra/newview/skins/default/textures/windows/Window_NoTitle_Background.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/windows/Window_NoTitle_Foreground.png b/indra/newview/skins/default/textures/windows/Window_NoTitle_Foreground.png
index d573e8c69a..d573e8c69a 100644..100755
--- a/indra/newview/skins/default/textures/windows/Window_NoTitle_Foreground.png
+++ b/indra/newview/skins/default/textures/windows/Window_NoTitle_Foreground.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/windows/hint_arrow_down.png b/indra/newview/skins/default/textures/windows/hint_arrow_down.png
index ddadef0978..ddadef0978 100644..100755
--- a/indra/newview/skins/default/textures/windows/hint_arrow_down.png
+++ b/indra/newview/skins/default/textures/windows/hint_arrow_down.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/windows/hint_arrow_left.png b/indra/newview/skins/default/textures/windows/hint_arrow_left.png
index 2794b967e8..2794b967e8 100644..100755
--- a/indra/newview/skins/default/textures/windows/hint_arrow_left.png
+++ b/indra/newview/skins/default/textures/windows/hint_arrow_left.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/windows/hint_arrow_lower_left.png b/indra/newview/skins/default/textures/windows/hint_arrow_lower_left.png
index 0dfc99898d..0dfc99898d 100644..100755
--- a/indra/newview/skins/default/textures/windows/hint_arrow_lower_left.png
+++ b/indra/newview/skins/default/textures/windows/hint_arrow_lower_left.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/windows/hint_arrow_right.png b/indra/newview/skins/default/textures/windows/hint_arrow_right.png
index 7ac57f805b..7ac57f805b 100644..100755
--- a/indra/newview/skins/default/textures/windows/hint_arrow_right.png
+++ b/indra/newview/skins/default/textures/windows/hint_arrow_right.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/windows/hint_arrow_up.png b/indra/newview/skins/default/textures/windows/hint_arrow_up.png
index bb3e1c07fa..bb3e1c07fa 100644..100755
--- a/indra/newview/skins/default/textures/windows/hint_arrow_up.png
+++ b/indra/newview/skins/default/textures/windows/hint_arrow_up.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/windows/hint_background.png b/indra/newview/skins/default/textures/windows/hint_background.png
index cfac5deacb..cfac5deacb 100644..100755
--- a/indra/newview/skins/default/textures/windows/hint_background.png
+++ b/indra/newview/skins/default/textures/windows/hint_background.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/windows/startup_logo.png b/indra/newview/skins/default/textures/windows/startup_logo.png
index b89449692b..b89449692b 100644..100755
--- a/indra/newview/skins/default/textures/windows/startup_logo.png
+++ b/indra/newview/skins/default/textures/windows/startup_logo.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/windows/yellow_gradient.png b/indra/newview/skins/default/textures/windows/yellow_gradient.png
index 5fd847aaef..5fd847aaef 100644..100755
--- a/indra/newview/skins/default/textures/windows/yellow_gradient.png
+++ b/indra/newview/skins/default/textures/windows/yellow_gradient.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/world/BeaconArrow.png b/indra/newview/skins/default/textures/world/BeaconArrow.png
index 54934f738a..54934f738a 100644..100755
--- a/indra/newview/skins/default/textures/world/BeaconArrow.png
+++ b/indra/newview/skins/default/textures/world/BeaconArrow.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/world/CameraDragDot.png b/indra/newview/skins/default/textures/world/CameraDragDot.png
index 57698e1956..57698e1956 100644..100755
--- a/indra/newview/skins/default/textures/world/CameraDragDot.png
+++ b/indra/newview/skins/default/textures/world/CameraDragDot.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/world/NoEntryLines.png b/indra/newview/skins/default/textures/world/NoEntryLines.png
index 18e270bde5..18e270bde5 100644..100755
--- a/indra/newview/skins/default/textures/world/NoEntryLines.png
+++ b/indra/newview/skins/default/textures/world/NoEntryLines.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/world/NoEntryPassLines.png b/indra/newview/skins/default/textures/world/NoEntryPassLines.png
index e4b8fc6ae2..e4b8fc6ae2 100644..100755
--- a/indra/newview/skins/default/textures/world/NoEntryPassLines.png
+++ b/indra/newview/skins/default/textures/world/NoEntryPassLines.png
Binary files differ
diff --git a/indra/newview/skins/default/xui/da/floater_about.xml b/indra/newview/skins/default/xui/da/floater_about.xml
index fc8bc33096..9206690c8f 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_about.xml
+++ b/indra/newview/skins/default/xui/da/floater_about.xml
@@ -8,7 +8,7 @@
Bygget med [COMPILER] version [COMPILER_VERSION]
</floater.string>
<floater.string name="AboutPosition">
- Du er ved [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1] i regionen [REGION] lokaliseret ved &lt;nolink&gt;[HOSTNAME]&lt;/nolink&gt; ([HOSTIP])
+ Du er ved [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] i regionen [REGION] lokaliseret ved &lt;nolink&gt;[HOSTNAME]&lt;/nolink&gt; ([HOSTIP])
[SERVER_VERSION]
[SERVER_RELEASE_NOTES_URL]
</floater.string>
diff --git a/indra/newview/skins/default/xui/da/floater_about_land.xml b/indra/newview/skins/default/xui/da/floater_about_land.xml
index 5b9e618666..5b9e618666 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/da/floater_about_land.xml
diff --git a/indra/newview/skins/default/xui/da/floater_activeim.xml b/indra/newview/skins/default/xui/da/floater_activeim.xml
index 6fdac8d880..6fdac8d880 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_activeim.xml
+++ b/indra/newview/skins/default/xui/da/floater_activeim.xml
diff --git a/indra/newview/skins/default/xui/da/floater_animation_preview.xml b/indra/newview/skins/default/xui/da/floater_animation_preview.xml
index adf96841c0..adf96841c0 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_animation_preview.xml
+++ b/indra/newview/skins/default/xui/da/floater_animation_preview.xml
diff --git a/indra/newview/skins/default/xui/da/floater_auction.xml b/indra/newview/skins/default/xui/da/floater_auction.xml
index e74e8a991b..e74e8a991b 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_auction.xml
+++ b/indra/newview/skins/default/xui/da/floater_auction.xml
diff --git a/indra/newview/skins/default/xui/da/floater_avatar_picker.xml b/indra/newview/skins/default/xui/da/floater_avatar_picker.xml
index e97089f61e..e97089f61e 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_avatar_picker.xml
+++ b/indra/newview/skins/default/xui/da/floater_avatar_picker.xml
diff --git a/indra/newview/skins/default/xui/da/floater_avatar_textures.xml b/indra/newview/skins/default/xui/da/floater_avatar_textures.xml
index d0d766eaab..d0d766eaab 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_avatar_textures.xml
+++ b/indra/newview/skins/default/xui/da/floater_avatar_textures.xml
diff --git a/indra/newview/skins/default/xui/da/floater_beacons.xml b/indra/newview/skins/default/xui/da/floater_beacons.xml
index 5100a6df1f..5100a6df1f 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_beacons.xml
+++ b/indra/newview/skins/default/xui/da/floater_beacons.xml
diff --git a/indra/newview/skins/default/xui/da/floater_build_options.xml b/indra/newview/skins/default/xui/da/floater_build_options.xml
index d3c3ac1899..d3c3ac1899 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_build_options.xml
+++ b/indra/newview/skins/default/xui/da/floater_build_options.xml
diff --git a/indra/newview/skins/default/xui/da/floater_bulk_perms.xml b/indra/newview/skins/default/xui/da/floater_bulk_perms.xml
index 58a1c1b73e..58a1c1b73e 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_bulk_perms.xml
+++ b/indra/newview/skins/default/xui/da/floater_bulk_perms.xml
diff --git a/indra/newview/skins/default/xui/da/floater_bumps.xml b/indra/newview/skins/default/xui/da/floater_bumps.xml
index 6b265832cd..6b265832cd 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_bumps.xml
+++ b/indra/newview/skins/default/xui/da/floater_bumps.xml
diff --git a/indra/newview/skins/default/xui/da/floater_buy_contents.xml b/indra/newview/skins/default/xui/da/floater_buy_contents.xml
index 085fa2f9cc..085fa2f9cc 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_buy_contents.xml
+++ b/indra/newview/skins/default/xui/da/floater_buy_contents.xml
diff --git a/indra/newview/skins/default/xui/da/floater_buy_currency.xml b/indra/newview/skins/default/xui/da/floater_buy_currency.xml
index 3c0428b2b0..3c0428b2b0 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_buy_currency.xml
+++ b/indra/newview/skins/default/xui/da/floater_buy_currency.xml
diff --git a/indra/newview/skins/default/xui/da/floater_buy_currency_html.xml b/indra/newview/skins/default/xui/da/floater_buy_currency_html.xml
index e32b25ca17..e32b25ca17 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_buy_currency_html.xml
+++ b/indra/newview/skins/default/xui/da/floater_buy_currency_html.xml
diff --git a/indra/newview/skins/default/xui/da/floater_buy_land.xml b/indra/newview/skins/default/xui/da/floater_buy_land.xml
index f6ee78fa6d..f6ee78fa6d 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_buy_land.xml
+++ b/indra/newview/skins/default/xui/da/floater_buy_land.xml
diff --git a/indra/newview/skins/default/xui/da/floater_buy_object.xml b/indra/newview/skins/default/xui/da/floater_buy_object.xml
index 7eb4787139..7eb4787139 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_buy_object.xml
+++ b/indra/newview/skins/default/xui/da/floater_buy_object.xml
diff --git a/indra/newview/skins/default/xui/da/floater_camera.xml b/indra/newview/skins/default/xui/da/floater_camera.xml
index b5d5e8bc08..b5d5e8bc08 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_camera.xml
+++ b/indra/newview/skins/default/xui/da/floater_camera.xml
diff --git a/indra/newview/skins/default/xui/da/floater_choose_group.xml b/indra/newview/skins/default/xui/da/floater_choose_group.xml
index 1ccda4f1d7..1ccda4f1d7 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_choose_group.xml
+++ b/indra/newview/skins/default/xui/da/floater_choose_group.xml
diff --git a/indra/newview/skins/default/xui/da/floater_color_picker.xml b/indra/newview/skins/default/xui/da/floater_color_picker.xml
index f744b06277..f744b06277 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_color_picker.xml
+++ b/indra/newview/skins/default/xui/da/floater_color_picker.xml
diff --git a/indra/newview/skins/default/xui/da/floater_critical.xml b/indra/newview/skins/default/xui/da/floater_critical.xml
index 8c2672f39f..8c2672f39f 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_critical.xml
+++ b/indra/newview/skins/default/xui/da/floater_critical.xml
diff --git a/indra/newview/skins/default/xui/da/floater_display_name.xml b/indra/newview/skins/default/xui/da/floater_display_name.xml
index e848006d8b..e848006d8b 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_display_name.xml
+++ b/indra/newview/skins/default/xui/da/floater_display_name.xml
diff --git a/indra/newview/skins/default/xui/da/floater_event.xml b/indra/newview/skins/default/xui/da/floater_event.xml
index a9eddaaf8d..a9eddaaf8d 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_event.xml
+++ b/indra/newview/skins/default/xui/da/floater_event.xml
diff --git a/indra/newview/skins/default/xui/da/floater_font_test.xml b/indra/newview/skins/default/xui/da/floater_font_test.xml
index 591d07188c..591d07188c 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_font_test.xml
+++ b/indra/newview/skins/default/xui/da/floater_font_test.xml
diff --git a/indra/newview/skins/default/xui/da/floater_gesture.xml b/indra/newview/skins/default/xui/da/floater_gesture.xml
index b7075e356a..b7075e356a 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_gesture.xml
+++ b/indra/newview/skins/default/xui/da/floater_gesture.xml
diff --git a/indra/newview/skins/default/xui/da/floater_god_tools.xml b/indra/newview/skins/default/xui/da/floater_god_tools.xml
index 5d3453e327..5d3453e327 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_god_tools.xml
+++ b/indra/newview/skins/default/xui/da/floater_god_tools.xml
diff --git a/indra/newview/skins/default/xui/da/floater_hardware_settings.xml b/indra/newview/skins/default/xui/da/floater_hardware_settings.xml
index a5942eb625..a5942eb625 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_hardware_settings.xml
+++ b/indra/newview/skins/default/xui/da/floater_hardware_settings.xml
diff --git a/indra/newview/skins/default/xui/da/floater_help_browser.xml b/indra/newview/skins/default/xui/da/floater_help_browser.xml
index 4eba4aee1f..4eba4aee1f 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_help_browser.xml
+++ b/indra/newview/skins/default/xui/da/floater_help_browser.xml
diff --git a/indra/newview/skins/default/xui/da/floater_hud.xml b/indra/newview/skins/default/xui/da/floater_hud.xml
index c70da45955..c70da45955 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_hud.xml
+++ b/indra/newview/skins/default/xui/da/floater_hud.xml
diff --git a/indra/newview/skins/default/xui/da/floater_im_container.xml b/indra/newview/skins/default/xui/da/floater_im_container.xml
index 28b2f7f7eb..28b2f7f7eb 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_im_container.xml
+++ b/indra/newview/skins/default/xui/da/floater_im_container.xml
diff --git a/indra/newview/skins/default/xui/da/floater_im_session.xml b/indra/newview/skins/default/xui/da/floater_im_session.xml
index 16df7e4b03..16df7e4b03 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/da/floater_im_session.xml
diff --git a/indra/newview/skins/default/xui/da/floater_image_preview.xml b/indra/newview/skins/default/xui/da/floater_image_preview.xml
index 5355127ef5..5355127ef5 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_image_preview.xml
+++ b/indra/newview/skins/default/xui/da/floater_image_preview.xml
diff --git a/indra/newview/skins/default/xui/da/floater_import_collada.xml b/indra/newview/skins/default/xui/da/floater_import_collada.xml
index ebc7c86388..ebc7c86388 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_import_collada.xml
+++ b/indra/newview/skins/default/xui/da/floater_import_collada.xml
diff --git a/indra/newview/skins/default/xui/da/floater_incoming_call.xml b/indra/newview/skins/default/xui/da/floater_incoming_call.xml
index dd8cb6f97a..dd8cb6f97a 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_incoming_call.xml
+++ b/indra/newview/skins/default/xui/da/floater_incoming_call.xml
diff --git a/indra/newview/skins/default/xui/da/floater_inspect.xml b/indra/newview/skins/default/xui/da/floater_inspect.xml
index d0dca8863a..d0dca8863a 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_inspect.xml
+++ b/indra/newview/skins/default/xui/da/floater_inspect.xml
diff --git a/indra/newview/skins/default/xui/da/floater_inventory.xml b/indra/newview/skins/default/xui/da/floater_inventory.xml
index 3a4b0fbd6b..3a4b0fbd6b 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_inventory.xml
+++ b/indra/newview/skins/default/xui/da/floater_inventory.xml
diff --git a/indra/newview/skins/default/xui/da/floater_inventory_item_properties.xml b/indra/newview/skins/default/xui/da/floater_inventory_item_properties.xml
index 59dcc87140..59dcc87140 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_inventory_item_properties.xml
+++ b/indra/newview/skins/default/xui/da/floater_inventory_item_properties.xml
diff --git a/indra/newview/skins/default/xui/da/floater_inventory_view_finder.xml b/indra/newview/skins/default/xui/da/floater_inventory_view_finder.xml
index 655701bb96..655701bb96 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_inventory_view_finder.xml
+++ b/indra/newview/skins/default/xui/da/floater_inventory_view_finder.xml
diff --git a/indra/newview/skins/default/xui/da/floater_joystick.xml b/indra/newview/skins/default/xui/da/floater_joystick.xml
index 49e1397e9f..49e1397e9f 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_joystick.xml
+++ b/indra/newview/skins/default/xui/da/floater_joystick.xml
diff --git a/indra/newview/skins/default/xui/da/floater_lagmeter.xml b/indra/newview/skins/default/xui/da/floater_lagmeter.xml
index 149d174c34..149d174c34 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_lagmeter.xml
+++ b/indra/newview/skins/default/xui/da/floater_lagmeter.xml
diff --git a/indra/newview/skins/default/xui/da/floater_land_holdings.xml b/indra/newview/skins/default/xui/da/floater_land_holdings.xml
index b3c12627f7..b3c12627f7 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_land_holdings.xml
+++ b/indra/newview/skins/default/xui/da/floater_land_holdings.xml
diff --git a/indra/newview/skins/default/xui/da/floater_live_lsleditor.xml b/indra/newview/skins/default/xui/da/floater_live_lsleditor.xml
index 0cc13fd736..0cc13fd736 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_live_lsleditor.xml
+++ b/indra/newview/skins/default/xui/da/floater_live_lsleditor.xml
diff --git a/indra/newview/skins/default/xui/da/floater_lsl_guide.xml b/indra/newview/skins/default/xui/da/floater_lsl_guide.xml
index 2594d6bb9d..2594d6bb9d 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_lsl_guide.xml
+++ b/indra/newview/skins/default/xui/da/floater_lsl_guide.xml
diff --git a/indra/newview/skins/default/xui/da/floater_map.xml b/indra/newview/skins/default/xui/da/floater_map.xml
index 4912d73ba0..4912d73ba0 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_map.xml
+++ b/indra/newview/skins/default/xui/da/floater_map.xml
diff --git a/indra/newview/skins/default/xui/da/floater_media_browser.xml b/indra/newview/skins/default/xui/da/floater_media_browser.xml
index d3028c32f9..d3028c32f9 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_media_browser.xml
+++ b/indra/newview/skins/default/xui/da/floater_media_browser.xml
diff --git a/indra/newview/skins/default/xui/da/floater_media_settings.xml b/indra/newview/skins/default/xui/da/floater_media_settings.xml
index 67c122b9d5..67c122b9d5 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_media_settings.xml
+++ b/indra/newview/skins/default/xui/da/floater_media_settings.xml
diff --git a/indra/newview/skins/default/xui/da/floater_mem_leaking.xml b/indra/newview/skins/default/xui/da/floater_mem_leaking.xml
index 60bb3149a5..60bb3149a5 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_mem_leaking.xml
+++ b/indra/newview/skins/default/xui/da/floater_mem_leaking.xml
diff --git a/indra/newview/skins/default/xui/da/floater_model_preview.xml b/indra/newview/skins/default/xui/da/floater_model_preview.xml
index a98c70ff52..a98c70ff52 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_model_preview.xml
+++ b/indra/newview/skins/default/xui/da/floater_model_preview.xml
diff --git a/indra/newview/skins/default/xui/da/floater_model_wizard.xml b/indra/newview/skins/default/xui/da/floater_model_wizard.xml
deleted file mode 100644
index 8ad443581a..0000000000
--- a/indra/newview/skins/default/xui/da/floater_model_wizard.xml
+++ /dev/null
@@ -1,241 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Model Wizard" title="UPLOAD MODEL WIZARD">
- <button label="5. Upload" name="upload_btn"/>
- <button label="4. Review" name="review_btn"/>
- <button label="3. Physics" name="physics2_btn"/>
- <button label="3. Physics" name="physics_btn"/>
- <button label="2. Optimize" name="optimize_btn"/>
- <button label="1. Choose File" name="choose_file_btn"/>
- <panel name="choose_file_panel">
- <panel name="header_panel">
- <text name="header_text">
- Upload Model
- </text>
- </panel>
- <text name="description">
- This wizard will help you import mesh models to Second Life. First specify a file containing the model you wish to import. Second Life supports COLLADA (.dae) files.
- </text>
- <panel name="content">
- <text name="Cache location">
- Filename:
- </text>
- <button label="Browse..." label_selected="Browse..." name="browse"/>
- <text name="dimensions">
- X: Y: Z:
- </text>
- <text name="dimension_dividers">
- | |
- </text>
- </panel>
- </panel>
- <panel name="optimize_panel">
- <panel name="header_panel">
- <text name="header_text">
- Optimize
- </text>
- </panel>
- <text name="description">
- This wizard has optimized your model to improve performance. You may adjust the results of the optimization process bellow or click Next to continue.
- </text>
- <panel name="content">
- <text name="high_detail_text">
- Generate Level of Detail: High
- </text>
- <text name="medium_detail_text">
- Generate Level of Detail: Medium
- </text>
- <text name="low_detail_text">
- Generate Level of Detail: Low
- </text>
- <text name="lowest_detail_text">
- Generate Level of Detail: Lowest
- </text>
- </panel>
- <panel name="content2">
- <text name="lod_label">
- Model Preview:
- </text>
- <combo_box name="preview_lod_combo2" tool_tip="LOD to view in preview render">
- <combo_item name="high">
- High
- </combo_item>
- <combo_item name="medium">
- Medium
- </combo_item>
- <combo_item name="low">
- Low
- </combo_item>
- <combo_item name="lowest">
- Lowest
- </combo_item>
- </combo_box>
- <text name="streaming cost">
- Resource Cost: [COST]
- </text>
- <text name="dimensions">
- X: Y: Z:
- </text>
- <text name="dimension_dividers">
- | |
- </text>
- </panel>
- </panel>
- <panel name="physics_panel">
- <panel name="header_panel">
- <text name="header_text">
- Physics
- </text>
- </panel>
- <text name="description">
- The wizard will create a physical shape, which determines how the object interacts with other objects and avatars. Set the slider to the detail level most appropriate for how your object will be used:
- </text>
- <panel name="content">
- <text name="streaming cost">
- Resource Cost: [COST]
- </text>
- </panel>
- </panel>
- <panel name="physics2_panel">
- <panel name="header_panel">
- <text name="header_text">
- Physics
- </text>
- </panel>
- <text name="description">
- Preview the physics shape below then click Next to continue. To modify the physics shape, click the Back button.
- </text>
- <panel name="content">
- <text name="lod_label">
- Model Preview:
- </text>
- <combo_box name="preview_lod_combo3" tool_tip="LOD to view in preview render">
- <combo_item name="high">
- High
- </combo_item>
- <combo_item name="medium">
- Medium
- </combo_item>
- <combo_item name="low">
- Low
- </combo_item>
- <combo_item name="lowest">
- Lowest
- </combo_item>
- </combo_box>
- <text name="dimensions">
- X: Y: Z:
- </text>
- <text name="dimension_dividers">
- | |
- </text>
- <text name="streaming cost">
- Resource Cost: [COST]
- </text>
- </panel>
- </panel>
- <panel name="review_panel">
- <panel name="header_panel">
- <text name="header_text">
- Review
- </text>
- </panel>
- <text name="description">
- Review the details below then click. Upload to upload your model. Your L$ balance will be charged when you click Upload.
- </text>
- <panel name="content">
- <text name="lod_label">
- Model Preview:
- </text>
- <combo_box name="preview_lod_combo" tool_tip="LOD to view in preview render">
- <combo_item name="high">
- High
- </combo_item>
- <combo_item name="medium">
- Medium
- </combo_item>
- <combo_item name="low">
- Low
- </combo_item>
- <combo_item name="lowest">
- Lowest
- </combo_item>
- </combo_box>
- <text name="dimensions">
- X: Y: Z:
- </text>
- <text name="dimension_dividers">
- | |
- </text>
- </panel>
- <text name="streaming cost">
- Resource Cost: [COST]
- </text>
- <text name="physics cost">
- Physics Cost: [COST]
- </text>
- </panel>
- <panel name="upload_panel">
- <panel name="header_panel">
- <text name="header_text">
- Upload Complete!
- </text>
- </panel>
- <text name="description">
- Congratulations! Your model has been sucessfully uploaded. You will find the model in the Objects folder in your inventory.
- </text>
- </panel>
- <button label="&lt;&lt; Back" name="back"/>
- <button label="Next &gt;&gt;" name="next"/>
- <button label="Upload" name="upload" tool_tip="Upload to simulator"/>
- <button label="Cancel" name="cancel"/>
- <button label="Close" name="close"/>
- <spinner name="import_scale" value="1.0"/>
- <string name="status_idle">
- Idle
- </string>
- <string name="status_reading_file">
- Loading...
- </string>
- <string name="status_generating_meshes">
- Generating Meshes...
- </string>
- <string name="status_vertex_number_overflow">
- Error: Vertex number is more than 65534, aborted!
- </string>
- <string name="high">
- High
- </string>
- <string name="medium">
- Medium
- </string>
- <string name="low">
- Low
- </string>
- <string name="lowest">
- Lowest
- </string>
- <string name="mesh_status_good">
- Ship it!
- </string>
- <string name="mesh_status_na">
- N/A
- </string>
- <string name="mesh_status_none">
- None
- </string>
- <string name="mesh_status_submesh_mismatch">
- Levels of detail have a different number of textureable faces.
- </string>
- <string name="mesh_status_mesh_mismatch">
- Levels of detail have a different number of mesh instances.
- </string>
- <string name="mesh_status_too_many_vertices">
- Level of detail has too many vertices.
- </string>
- <string name="mesh_status_missing_lod">
- Missing required level of detail.
- </string>
- <string name="layer_all">
- All
- </string>
-</floater>
diff --git a/indra/newview/skins/default/xui/da/floater_moveview.xml b/indra/newview/skins/default/xui/da/floater_moveview.xml
index 14d3604b43..14d3604b43 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_moveview.xml
+++ b/indra/newview/skins/default/xui/da/floater_moveview.xml
diff --git a/indra/newview/skins/default/xui/da/floater_mute_object.xml b/indra/newview/skins/default/xui/da/floater_mute_object.xml
index 3b3f670792..3b3f670792 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_mute_object.xml
+++ b/indra/newview/skins/default/xui/da/floater_mute_object.xml
diff --git a/indra/newview/skins/default/xui/da/floater_nearby_chat.xml b/indra/newview/skins/default/xui/da/floater_nearby_chat.xml
index 76bc40edac..76bc40edac 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_nearby_chat.xml
+++ b/indra/newview/skins/default/xui/da/floater_nearby_chat.xml
diff --git a/indra/newview/skins/default/xui/da/floater_openobject.xml b/indra/newview/skins/default/xui/da/floater_openobject.xml
index 92fdd1e0a6..92fdd1e0a6 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_openobject.xml
+++ b/indra/newview/skins/default/xui/da/floater_openobject.xml
diff --git a/indra/newview/skins/default/xui/da/floater_outgoing_call.xml b/indra/newview/skins/default/xui/da/floater_outgoing_call.xml
index a5545668a2..a5545668a2 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_outgoing_call.xml
+++ b/indra/newview/skins/default/xui/da/floater_outgoing_call.xml
diff --git a/indra/newview/skins/default/xui/da/floater_pay.xml b/indra/newview/skins/default/xui/da/floater_pay.xml
index 96ec106803..96ec106803 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_pay.xml
+++ b/indra/newview/skins/default/xui/da/floater_pay.xml
diff --git a/indra/newview/skins/default/xui/da/floater_pay_object.xml b/indra/newview/skins/default/xui/da/floater_pay_object.xml
index 260b257c33..260b257c33 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_pay_object.xml
+++ b/indra/newview/skins/default/xui/da/floater_pay_object.xml
diff --git a/indra/newview/skins/default/xui/da/floater_perm_prefs.xml b/indra/newview/skins/default/xui/da/floater_perm_prefs.xml
index eecddbcdb0..eecddbcdb0 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_perm_prefs.xml
+++ b/indra/newview/skins/default/xui/da/floater_perm_prefs.xml
diff --git a/indra/newview/skins/default/xui/da/floater_postcard.xml b/indra/newview/skins/default/xui/da/floater_postcard.xml
index 44b0fd4faa..44b0fd4faa 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_postcard.xml
+++ b/indra/newview/skins/default/xui/da/floater_postcard.xml
diff --git a/indra/newview/skins/default/xui/da/floater_preferences.xml b/indra/newview/skins/default/xui/da/floater_preferences.xml
index 6caac14cf5..6caac14cf5 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_preferences.xml
+++ b/indra/newview/skins/default/xui/da/floater_preferences.xml
diff --git a/indra/newview/skins/default/xui/da/floater_preview_animation.xml b/indra/newview/skins/default/xui/da/floater_preview_animation.xml
index 436843decc..436843decc 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_preview_animation.xml
+++ b/indra/newview/skins/default/xui/da/floater_preview_animation.xml
diff --git a/indra/newview/skins/default/xui/da/floater_preview_gesture.xml b/indra/newview/skins/default/xui/da/floater_preview_gesture.xml
index bd2b194717..bd2b194717 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_preview_gesture.xml
+++ b/indra/newview/skins/default/xui/da/floater_preview_gesture.xml
diff --git a/indra/newview/skins/default/xui/da/floater_preview_notecard.xml b/indra/newview/skins/default/xui/da/floater_preview_notecard.xml
index 5a0f5a32c0..5a0f5a32c0 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_preview_notecard.xml
+++ b/indra/newview/skins/default/xui/da/floater_preview_notecard.xml
diff --git a/indra/newview/skins/default/xui/da/floater_preview_sound.xml b/indra/newview/skins/default/xui/da/floater_preview_sound.xml
index 21f7656462..21f7656462 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_preview_sound.xml
+++ b/indra/newview/skins/default/xui/da/floater_preview_sound.xml
diff --git a/indra/newview/skins/default/xui/da/floater_preview_texture.xml b/indra/newview/skins/default/xui/da/floater_preview_texture.xml
index 48cf53f563..48cf53f563 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_preview_texture.xml
+++ b/indra/newview/skins/default/xui/da/floater_preview_texture.xml
diff --git a/indra/newview/skins/default/xui/da/floater_price_for_listing.xml b/indra/newview/skins/default/xui/da/floater_price_for_listing.xml
index b091fa09b5..b091fa09b5 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_price_for_listing.xml
+++ b/indra/newview/skins/default/xui/da/floater_price_for_listing.xml
diff --git a/indra/newview/skins/default/xui/da/floater_publish_classified.xml b/indra/newview/skins/default/xui/da/floater_publish_classified.xml
index 0f65e6c18a..0f65e6c18a 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_publish_classified.xml
+++ b/indra/newview/skins/default/xui/da/floater_publish_classified.xml
diff --git a/indra/newview/skins/default/xui/da/floater_region_debug_console.xml b/indra/newview/skins/default/xui/da/floater_region_debug_console.xml
index 71313f4fea..71313f4fea 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_region_debug_console.xml
+++ b/indra/newview/skins/default/xui/da/floater_region_debug_console.xml
diff --git a/indra/newview/skins/default/xui/da/floater_region_info.xml b/indra/newview/skins/default/xui/da/floater_region_info.xml
index ae00f90f16..ae00f90f16 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_region_info.xml
+++ b/indra/newview/skins/default/xui/da/floater_region_info.xml
diff --git a/indra/newview/skins/default/xui/da/floater_report_abuse.xml b/indra/newview/skins/default/xui/da/floater_report_abuse.xml
index 07978792b9..07978792b9 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_report_abuse.xml
+++ b/indra/newview/skins/default/xui/da/floater_report_abuse.xml
diff --git a/indra/newview/skins/default/xui/da/floater_script_debug.xml b/indra/newview/skins/default/xui/da/floater_script_debug.xml
index df60a2e23f..df60a2e23f 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_script_debug.xml
+++ b/indra/newview/skins/default/xui/da/floater_script_debug.xml
diff --git a/indra/newview/skins/default/xui/da/floater_script_debug_panel.xml b/indra/newview/skins/default/xui/da/floater_script_debug_panel.xml
index e70a30fa24..e70a30fa24 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_script_debug_panel.xml
+++ b/indra/newview/skins/default/xui/da/floater_script_debug_panel.xml
diff --git a/indra/newview/skins/default/xui/da/floater_script_limits.xml b/indra/newview/skins/default/xui/da/floater_script_limits.xml
index a7f86a782a..a7f86a782a 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_script_limits.xml
+++ b/indra/newview/skins/default/xui/da/floater_script_limits.xml
diff --git a/indra/newview/skins/default/xui/da/floater_script_preview.xml b/indra/newview/skins/default/xui/da/floater_script_preview.xml
index 1aacab6915..1aacab6915 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_script_preview.xml
+++ b/indra/newview/skins/default/xui/da/floater_script_preview.xml
diff --git a/indra/newview/skins/default/xui/da/floater_script_queue.xml b/indra/newview/skins/default/xui/da/floater_script_queue.xml
index 1ff5494458..1ff5494458 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_script_queue.xml
+++ b/indra/newview/skins/default/xui/da/floater_script_queue.xml
diff --git a/indra/newview/skins/default/xui/da/floater_script_search.xml b/indra/newview/skins/default/xui/da/floater_script_search.xml
index f1605cac34..f1605cac34 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_script_search.xml
+++ b/indra/newview/skins/default/xui/da/floater_script_search.xml
diff --git a/indra/newview/skins/default/xui/da/floater_search.xml b/indra/newview/skins/default/xui/da/floater_search.xml
index 80a30b1aa1..80a30b1aa1 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_search.xml
+++ b/indra/newview/skins/default/xui/da/floater_search.xml
diff --git a/indra/newview/skins/default/xui/da/floater_select_key.xml b/indra/newview/skins/default/xui/da/floater_select_key.xml
index 9f7aad5e03..9f7aad5e03 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_select_key.xml
+++ b/indra/newview/skins/default/xui/da/floater_select_key.xml
diff --git a/indra/newview/skins/default/xui/da/floater_sell_land.xml b/indra/newview/skins/default/xui/da/floater_sell_land.xml
index 873e6d7995..873e6d7995 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_sell_land.xml
+++ b/indra/newview/skins/default/xui/da/floater_sell_land.xml
diff --git a/indra/newview/skins/default/xui/da/floater_settings_debug.xml b/indra/newview/skins/default/xui/da/floater_settings_debug.xml
index f7eda56e48..f7eda56e48 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_settings_debug.xml
+++ b/indra/newview/skins/default/xui/da/floater_settings_debug.xml
diff --git a/indra/newview/skins/default/xui/da/floater_snapshot.xml b/indra/newview/skins/default/xui/da/floater_snapshot.xml
index 926c2429ac..926c2429ac 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_snapshot.xml
+++ b/indra/newview/skins/default/xui/da/floater_snapshot.xml
diff --git a/indra/newview/skins/default/xui/da/floater_sound_devices.xml b/indra/newview/skins/default/xui/da/floater_sound_devices.xml
index cb4cbba570..cb4cbba570 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_sound_devices.xml
+++ b/indra/newview/skins/default/xui/da/floater_sound_devices.xml
diff --git a/indra/newview/skins/default/xui/da/floater_sound_preview.xml b/indra/newview/skins/default/xui/da/floater_sound_preview.xml
index 5f74f28a23..5f74f28a23 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_sound_preview.xml
+++ b/indra/newview/skins/default/xui/da/floater_sound_preview.xml
diff --git a/indra/newview/skins/default/xui/da/floater_stats.xml b/indra/newview/skins/default/xui/da/floater_stats.xml
index fe3fa9626e..fe3fa9626e 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_stats.xml
+++ b/indra/newview/skins/default/xui/da/floater_stats.xml
diff --git a/indra/newview/skins/default/xui/da/floater_sys_well.xml b/indra/newview/skins/default/xui/da/floater_sys_well.xml
index f203c2504f..f203c2504f 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_sys_well.xml
+++ b/indra/newview/skins/default/xui/da/floater_sys_well.xml
diff --git a/indra/newview/skins/default/xui/da/floater_telehub.xml b/indra/newview/skins/default/xui/da/floater_telehub.xml
index 5a0e89aa98..5a0e89aa98 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_telehub.xml
+++ b/indra/newview/skins/default/xui/da/floater_telehub.xml
diff --git a/indra/newview/skins/default/xui/da/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/da/floater_texture_ctrl.xml
index fbc7fe2319..fbc7fe2319 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_texture_ctrl.xml
+++ b/indra/newview/skins/default/xui/da/floater_texture_ctrl.xml
diff --git a/indra/newview/skins/default/xui/da/floater_tools.xml b/indra/newview/skins/default/xui/da/floater_tools.xml
index 815bde456e..9be129bbf6 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_tools.xml
+++ b/indra/newview/skins/default/xui/da/floater_tools.xml
@@ -462,10 +462,6 @@
<combo_box.item label="Rør" name="suction"/>
<combo_box.item label="Væv" name="weave"/>
</combo_box>
- <check_box initial_value="falsk" label="Flugt planare overflader" name="checkbox planar align" tool_tip="Flugt teksuter på alle valgte overflader med den sidst valgte overflade. Kræver at planar tekstur-mapning er valgt."/>
- <text name="rpt">
- Gentagelser / overflade
- </text>
<spinner label="Vandret (U)" name="TexScaleU"/>
<check_box label="Vend" name="checkbox flip s"/>
<spinner label="Lodret (V)" name="TexScaleV"/>
diff --git a/indra/newview/skins/default/xui/da/floater_top_objects.xml b/indra/newview/skins/default/xui/da/floater_top_objects.xml
index 86c24d2c19..86c24d2c19 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_top_objects.xml
+++ b/indra/newview/skins/default/xui/da/floater_top_objects.xml
diff --git a/indra/newview/skins/default/xui/da/floater_tos.xml b/indra/newview/skins/default/xui/da/floater_tos.xml
index af9ee0bd06..af9ee0bd06 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_tos.xml
+++ b/indra/newview/skins/default/xui/da/floater_tos.xml
diff --git a/indra/newview/skins/default/xui/da/floater_url_entry.xml b/indra/newview/skins/default/xui/da/floater_url_entry.xml
index 30b3b7184b..30b3b7184b 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_url_entry.xml
+++ b/indra/newview/skins/default/xui/da/floater_url_entry.xml
diff --git a/indra/newview/skins/default/xui/da/floater_voice_controls.xml b/indra/newview/skins/default/xui/da/floater_voice_controls.xml
index 69de696bf5..69de696bf5 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_voice_controls.xml
+++ b/indra/newview/skins/default/xui/da/floater_voice_controls.xml
diff --git a/indra/newview/skins/default/xui/da/floater_voice_effect.xml b/indra/newview/skins/default/xui/da/floater_voice_effect.xml
index 86ad251103..86ad251103 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_voice_effect.xml
+++ b/indra/newview/skins/default/xui/da/floater_voice_effect.xml
diff --git a/indra/newview/skins/default/xui/da/floater_web_content.xml b/indra/newview/skins/default/xui/da/floater_web_content.xml
index 74092e88ec..74092e88ec 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_web_content.xml
+++ b/indra/newview/skins/default/xui/da/floater_web_content.xml
diff --git a/indra/newview/skins/default/xui/da/floater_whitelist_entry.xml b/indra/newview/skins/default/xui/da/floater_whitelist_entry.xml
index 443e84b64a..443e84b64a 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_whitelist_entry.xml
+++ b/indra/newview/skins/default/xui/da/floater_whitelist_entry.xml
diff --git a/indra/newview/skins/default/xui/da/floater_window_size.xml b/indra/newview/skins/default/xui/da/floater_window_size.xml
index db8ead21bd..db8ead21bd 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_window_size.xml
+++ b/indra/newview/skins/default/xui/da/floater_window_size.xml
diff --git a/indra/newview/skins/default/xui/da/floater_world_map.xml b/indra/newview/skins/default/xui/da/floater_world_map.xml
index 97364e0f9f..97364e0f9f 100644..100755
--- a/indra/newview/skins/default/xui/da/floater_world_map.xml
+++ b/indra/newview/skins/default/xui/da/floater_world_map.xml
diff --git a/indra/newview/skins/default/xui/da/inspect_avatar.xml b/indra/newview/skins/default/xui/da/inspect_avatar.xml
index dc1ed562eb..dc1ed562eb 100644..100755
--- a/indra/newview/skins/default/xui/da/inspect_avatar.xml
+++ b/indra/newview/skins/default/xui/da/inspect_avatar.xml
diff --git a/indra/newview/skins/default/xui/da/inspect_group.xml b/indra/newview/skins/default/xui/da/inspect_group.xml
index 486c5d8784..486c5d8784 100644..100755
--- a/indra/newview/skins/default/xui/da/inspect_group.xml
+++ b/indra/newview/skins/default/xui/da/inspect_group.xml
diff --git a/indra/newview/skins/default/xui/da/inspect_object.xml b/indra/newview/skins/default/xui/da/inspect_object.xml
index 78ccc5b869..78ccc5b869 100644..100755
--- a/indra/newview/skins/default/xui/da/inspect_object.xml
+++ b/indra/newview/skins/default/xui/da/inspect_object.xml
diff --git a/indra/newview/skins/default/xui/da/inspect_remote_object.xml b/indra/newview/skins/default/xui/da/inspect_remote_object.xml
index a06452afe6..a06452afe6 100644..100755
--- a/indra/newview/skins/default/xui/da/inspect_remote_object.xml
+++ b/indra/newview/skins/default/xui/da/inspect_remote_object.xml
diff --git a/indra/newview/skins/default/xui/da/language_settings.xml b/indra/newview/skins/default/xui/da/language_settings.xml
index 0e3cbfd2d2..0e3cbfd2d2 100644..100755
--- a/indra/newview/skins/default/xui/da/language_settings.xml
+++ b/indra/newview/skins/default/xui/da/language_settings.xml
diff --git a/indra/newview/skins/default/xui/da/menu_add_wearable_gear.xml b/indra/newview/skins/default/xui/da/menu_add_wearable_gear.xml
index 1e8301dc4c..1e8301dc4c 100644..100755
--- a/indra/newview/skins/default/xui/da/menu_add_wearable_gear.xml
+++ b/indra/newview/skins/default/xui/da/menu_add_wearable_gear.xml
diff --git a/indra/newview/skins/default/xui/da/menu_attachment_other.xml b/indra/newview/skins/default/xui/da/menu_attachment_other.xml
index ca7b184942..ca7b184942 100644..100755
--- a/indra/newview/skins/default/xui/da/menu_attachment_other.xml
+++ b/indra/newview/skins/default/xui/da/menu_attachment_other.xml
diff --git a/indra/newview/skins/default/xui/da/menu_attachment_self.xml b/indra/newview/skins/default/xui/da/menu_attachment_self.xml
index 35ba27f9e2..35ba27f9e2 100644..100755
--- a/indra/newview/skins/default/xui/da/menu_attachment_self.xml
+++ b/indra/newview/skins/default/xui/da/menu_attachment_self.xml
diff --git a/indra/newview/skins/default/xui/da/menu_avatar_icon.xml b/indra/newview/skins/default/xui/da/menu_avatar_icon.xml
index 26b58ce1ab..26b58ce1ab 100644..100755
--- a/indra/newview/skins/default/xui/da/menu_avatar_icon.xml
+++ b/indra/newview/skins/default/xui/da/menu_avatar_icon.xml
diff --git a/indra/newview/skins/default/xui/da/menu_avatar_other.xml b/indra/newview/skins/default/xui/da/menu_avatar_other.xml
index a778dedf0b..a778dedf0b 100644..100755
--- a/indra/newview/skins/default/xui/da/menu_avatar_other.xml
+++ b/indra/newview/skins/default/xui/da/menu_avatar_other.xml
diff --git a/indra/newview/skins/default/xui/da/menu_avatar_self.xml b/indra/newview/skins/default/xui/da/menu_avatar_self.xml
index 4e6b42a744..4e6b42a744 100644..100755
--- a/indra/newview/skins/default/xui/da/menu_avatar_self.xml
+++ b/indra/newview/skins/default/xui/da/menu_avatar_self.xml
diff --git a/indra/newview/skins/default/xui/da/menu_bottomtray.xml b/indra/newview/skins/default/xui/da/menu_bottomtray.xml
index a0d74db36d..a0d74db36d 100644..100755
--- a/indra/newview/skins/default/xui/da/menu_bottomtray.xml
+++ b/indra/newview/skins/default/xui/da/menu_bottomtray.xml
diff --git a/indra/newview/skins/default/xui/da/menu_cof_attachment.xml b/indra/newview/skins/default/xui/da/menu_cof_attachment.xml
index 9d7fc0f223..9d7fc0f223 100644..100755
--- a/indra/newview/skins/default/xui/da/menu_cof_attachment.xml
+++ b/indra/newview/skins/default/xui/da/menu_cof_attachment.xml
diff --git a/indra/newview/skins/default/xui/da/menu_cof_body_part.xml b/indra/newview/skins/default/xui/da/menu_cof_body_part.xml
index 0e90d5a3ae..0e90d5a3ae 100644..100755
--- a/indra/newview/skins/default/xui/da/menu_cof_body_part.xml
+++ b/indra/newview/skins/default/xui/da/menu_cof_body_part.xml
diff --git a/indra/newview/skins/default/xui/da/menu_cof_clothing.xml b/indra/newview/skins/default/xui/da/menu_cof_clothing.xml
index 16c225b7d9..16c225b7d9 100644..100755
--- a/indra/newview/skins/default/xui/da/menu_cof_clothing.xml
+++ b/indra/newview/skins/default/xui/da/menu_cof_clothing.xml
diff --git a/indra/newview/skins/default/xui/da/menu_cof_gear.xml b/indra/newview/skins/default/xui/da/menu_cof_gear.xml
index f44369fd84..f44369fd84 100644..100755
--- a/indra/newview/skins/default/xui/da/menu_cof_gear.xml
+++ b/indra/newview/skins/default/xui/da/menu_cof_gear.xml
diff --git a/indra/newview/skins/default/xui/da/menu_edit.xml b/indra/newview/skins/default/xui/da/menu_edit.xml
index 3752f42b1c..3752f42b1c 100644..100755
--- a/indra/newview/skins/default/xui/da/menu_edit.xml
+++ b/indra/newview/skins/default/xui/da/menu_edit.xml
diff --git a/indra/newview/skins/default/xui/da/menu_favorites.xml b/indra/newview/skins/default/xui/da/menu_favorites.xml
index a4793e294c..a4793e294c 100644..100755
--- a/indra/newview/skins/default/xui/da/menu_favorites.xml
+++ b/indra/newview/skins/default/xui/da/menu_favorites.xml
diff --git a/indra/newview/skins/default/xui/da/menu_gesture_gear.xml b/indra/newview/skins/default/xui/da/menu_gesture_gear.xml
index a9010e99b6..a9010e99b6 100644..100755
--- a/indra/newview/skins/default/xui/da/menu_gesture_gear.xml
+++ b/indra/newview/skins/default/xui/da/menu_gesture_gear.xml
diff --git a/indra/newview/skins/default/xui/da/menu_group_plus.xml b/indra/newview/skins/default/xui/da/menu_group_plus.xml
index 97fbec1ed1..97fbec1ed1 100644..100755
--- a/indra/newview/skins/default/xui/da/menu_group_plus.xml
+++ b/indra/newview/skins/default/xui/da/menu_group_plus.xml
diff --git a/indra/newview/skins/default/xui/da/menu_hide_navbar.xml b/indra/newview/skins/default/xui/da/menu_hide_navbar.xml
index d96a8a8a17..d96a8a8a17 100644..100755
--- a/indra/newview/skins/default/xui/da/menu_hide_navbar.xml
+++ b/indra/newview/skins/default/xui/da/menu_hide_navbar.xml
diff --git a/indra/newview/skins/default/xui/da/menu_im_well_button.xml b/indra/newview/skins/default/xui/da/menu_im_well_button.xml
deleted file mode 100644
index 4889230919..0000000000
--- a/indra/newview/skins/default/xui/da/menu_im_well_button.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<context_menu name="IM Well Button Context Menu">
- <menu_item_call label="Luk alle" name="Close All"/>
-</context_menu>
diff --git a/indra/newview/skins/default/xui/da/menu_imchiclet_adhoc.xml b/indra/newview/skins/default/xui/da/menu_imchiclet_adhoc.xml
index f64a6ad455..f64a6ad455 100644..100755
--- a/indra/newview/skins/default/xui/da/menu_imchiclet_adhoc.xml
+++ b/indra/newview/skins/default/xui/da/menu_imchiclet_adhoc.xml
diff --git a/indra/newview/skins/default/xui/da/menu_imchiclet_group.xml b/indra/newview/skins/default/xui/da/menu_imchiclet_group.xml
index b89d9a5789..b89d9a5789 100644..100755
--- a/indra/newview/skins/default/xui/da/menu_imchiclet_group.xml
+++ b/indra/newview/skins/default/xui/da/menu_imchiclet_group.xml
diff --git a/indra/newview/skins/default/xui/da/menu_imchiclet_p2p.xml b/indra/newview/skins/default/xui/da/menu_imchiclet_p2p.xml
index 6ebc40a8dd..6ebc40a8dd 100644..100755
--- a/indra/newview/skins/default/xui/da/menu_imchiclet_p2p.xml
+++ b/indra/newview/skins/default/xui/da/menu_imchiclet_p2p.xml
diff --git a/indra/newview/skins/default/xui/da/menu_inspect_avatar_gear.xml b/indra/newview/skins/default/xui/da/menu_inspect_avatar_gear.xml
index 8da35adb1b..8da35adb1b 100644..100755
--- a/indra/newview/skins/default/xui/da/menu_inspect_avatar_gear.xml
+++ b/indra/newview/skins/default/xui/da/menu_inspect_avatar_gear.xml
diff --git a/indra/newview/skins/default/xui/da/menu_inspect_object_gear.xml b/indra/newview/skins/default/xui/da/menu_inspect_object_gear.xml
index e28842836d..e28842836d 100644..100755
--- a/indra/newview/skins/default/xui/da/menu_inspect_object_gear.xml
+++ b/indra/newview/skins/default/xui/da/menu_inspect_object_gear.xml
diff --git a/indra/newview/skins/default/xui/da/menu_inspect_self_gear.xml b/indra/newview/skins/default/xui/da/menu_inspect_self_gear.xml
index 887c6484bc..887c6484bc 100644..100755
--- a/indra/newview/skins/default/xui/da/menu_inspect_self_gear.xml
+++ b/indra/newview/skins/default/xui/da/menu_inspect_self_gear.xml
diff --git a/indra/newview/skins/default/xui/da/menu_inv_offer_chiclet.xml b/indra/newview/skins/default/xui/da/menu_inv_offer_chiclet.xml
index c3b03232bf..c3b03232bf 100644..100755
--- a/indra/newview/skins/default/xui/da/menu_inv_offer_chiclet.xml
+++ b/indra/newview/skins/default/xui/da/menu_inv_offer_chiclet.xml
diff --git a/indra/newview/skins/default/xui/da/menu_inventory.xml b/indra/newview/skins/default/xui/da/menu_inventory.xml
index f9bdf36f1f..f9bdf36f1f 100644..100755
--- a/indra/newview/skins/default/xui/da/menu_inventory.xml
+++ b/indra/newview/skins/default/xui/da/menu_inventory.xml
diff --git a/indra/newview/skins/default/xui/da/menu_inventory_add.xml b/indra/newview/skins/default/xui/da/menu_inventory_add.xml
index eca03d3ee9..eca03d3ee9 100644..100755
--- a/indra/newview/skins/default/xui/da/menu_inventory_add.xml
+++ b/indra/newview/skins/default/xui/da/menu_inventory_add.xml
diff --git a/indra/newview/skins/default/xui/da/menu_inventory_gear_default.xml b/indra/newview/skins/default/xui/da/menu_inventory_gear_default.xml
index 4809b24463..4809b24463 100644..100755
--- a/indra/newview/skins/default/xui/da/menu_inventory_gear_default.xml
+++ b/indra/newview/skins/default/xui/da/menu_inventory_gear_default.xml
diff --git a/indra/newview/skins/default/xui/da/menu_land.xml b/indra/newview/skins/default/xui/da/menu_land.xml
index 1548f18f89..1548f18f89 100644..100755
--- a/indra/newview/skins/default/xui/da/menu_land.xml
+++ b/indra/newview/skins/default/xui/da/menu_land.xml
diff --git a/indra/newview/skins/default/xui/da/menu_landmark.xml b/indra/newview/skins/default/xui/da/menu_landmark.xml
index 3cf2ffe375..3cf2ffe375 100644..100755
--- a/indra/newview/skins/default/xui/da/menu_landmark.xml
+++ b/indra/newview/skins/default/xui/da/menu_landmark.xml
diff --git a/indra/newview/skins/default/xui/da/menu_login.xml b/indra/newview/skins/default/xui/da/menu_login.xml
index 0b7a5040ae..0b7a5040ae 100644..100755
--- a/indra/newview/skins/default/xui/da/menu_login.xml
+++ b/indra/newview/skins/default/xui/da/menu_login.xml
diff --git a/indra/newview/skins/default/xui/da/menu_media_ctrl.xml b/indra/newview/skins/default/xui/da/menu_media_ctrl.xml
index 788b1c4b59..788b1c4b59 100644..100755
--- a/indra/newview/skins/default/xui/da/menu_media_ctrl.xml
+++ b/indra/newview/skins/default/xui/da/menu_media_ctrl.xml
diff --git a/indra/newview/skins/default/xui/da/menu_mini_map.xml b/indra/newview/skins/default/xui/da/menu_mini_map.xml
index 186dbd476a..186dbd476a 100644..100755
--- a/indra/newview/skins/default/xui/da/menu_mini_map.xml
+++ b/indra/newview/skins/default/xui/da/menu_mini_map.xml
diff --git a/indra/newview/skins/default/xui/da/menu_model_import_gear_default.xml b/indra/newview/skins/default/xui/da/menu_model_import_gear_default.xml
index d9626692d5..d9626692d5 100644..100755
--- a/indra/newview/skins/default/xui/da/menu_model_import_gear_default.xml
+++ b/indra/newview/skins/default/xui/da/menu_model_import_gear_default.xml
diff --git a/indra/newview/skins/default/xui/da/menu_navbar.xml b/indra/newview/skins/default/xui/da/menu_navbar.xml
index c04206824a..c04206824a 100644..100755
--- a/indra/newview/skins/default/xui/da/menu_navbar.xml
+++ b/indra/newview/skins/default/xui/da/menu_navbar.xml
diff --git a/indra/newview/skins/default/xui/da/menu_nearby_chat.xml b/indra/newview/skins/default/xui/da/menu_nearby_chat.xml
index be532ad406..be532ad406 100644..100755
--- a/indra/newview/skins/default/xui/da/menu_nearby_chat.xml
+++ b/indra/newview/skins/default/xui/da/menu_nearby_chat.xml
diff --git a/indra/newview/skins/default/xui/da/menu_notification_well_button.xml b/indra/newview/skins/default/xui/da/menu_notification_well_button.xml
index 40b35b5fdd..40b35b5fdd 100644..100755
--- a/indra/newview/skins/default/xui/da/menu_notification_well_button.xml
+++ b/indra/newview/skins/default/xui/da/menu_notification_well_button.xml
diff --git a/indra/newview/skins/default/xui/da/menu_object.xml b/indra/newview/skins/default/xui/da/menu_object.xml
index ba62ccf90c..ba62ccf90c 100644..100755
--- a/indra/newview/skins/default/xui/da/menu_object.xml
+++ b/indra/newview/skins/default/xui/da/menu_object.xml
diff --git a/indra/newview/skins/default/xui/da/menu_object_icon.xml b/indra/newview/skins/default/xui/da/menu_object_icon.xml
index 08aeb633b6..08aeb633b6 100644..100755
--- a/indra/newview/skins/default/xui/da/menu_object_icon.xml
+++ b/indra/newview/skins/default/xui/da/menu_object_icon.xml
diff --git a/indra/newview/skins/default/xui/da/menu_outfit_gear.xml b/indra/newview/skins/default/xui/da/menu_outfit_gear.xml
index 0b0fff3b93..0b0fff3b93 100644..100755
--- a/indra/newview/skins/default/xui/da/menu_outfit_gear.xml
+++ b/indra/newview/skins/default/xui/da/menu_outfit_gear.xml
diff --git a/indra/newview/skins/default/xui/da/menu_outfit_tab.xml b/indra/newview/skins/default/xui/da/menu_outfit_tab.xml
index d6a6f2724f..d6a6f2724f 100644..100755
--- a/indra/newview/skins/default/xui/da/menu_outfit_tab.xml
+++ b/indra/newview/skins/default/xui/da/menu_outfit_tab.xml
diff --git a/indra/newview/skins/default/xui/da/menu_participant_list.xml b/indra/newview/skins/default/xui/da/menu_participant_list.xml
index 5951d3ffb9..5951d3ffb9 100644..100755
--- a/indra/newview/skins/default/xui/da/menu_participant_list.xml
+++ b/indra/newview/skins/default/xui/da/menu_participant_list.xml
diff --git a/indra/newview/skins/default/xui/da/menu_people_friends_view_sort.xml b/indra/newview/skins/default/xui/da/menu_people_friends_view_sort.xml
index 32c5e6a6c7..32c5e6a6c7 100644..100755
--- a/indra/newview/skins/default/xui/da/menu_people_friends_view_sort.xml
+++ b/indra/newview/skins/default/xui/da/menu_people_friends_view_sort.xml
diff --git a/indra/newview/skins/default/xui/da/menu_people_groups.xml b/indra/newview/skins/default/xui/da/menu_people_groups.xml
index 841f58b619..841f58b619 100644..100755
--- a/indra/newview/skins/default/xui/da/menu_people_groups.xml
+++ b/indra/newview/skins/default/xui/da/menu_people_groups.xml
diff --git a/indra/newview/skins/default/xui/da/menu_people_groups_view_sort.xml b/indra/newview/skins/default/xui/da/menu_people_groups_view_sort.xml
index 0b9a791530..0b9a791530 100644..100755
--- a/indra/newview/skins/default/xui/da/menu_people_groups_view_sort.xml
+++ b/indra/newview/skins/default/xui/da/menu_people_groups_view_sort.xml
diff --git a/indra/newview/skins/default/xui/da/menu_people_nearby.xml b/indra/newview/skins/default/xui/da/menu_people_nearby.xml
index 5470c32761..5470c32761 100644..100755
--- a/indra/newview/skins/default/xui/da/menu_people_nearby.xml
+++ b/indra/newview/skins/default/xui/da/menu_people_nearby.xml
diff --git a/indra/newview/skins/default/xui/da/menu_people_nearby_multiselect.xml b/indra/newview/skins/default/xui/da/menu_people_nearby_multiselect.xml
index 9318a0e340..9318a0e340 100644..100755
--- a/indra/newview/skins/default/xui/da/menu_people_nearby_multiselect.xml
+++ b/indra/newview/skins/default/xui/da/menu_people_nearby_multiselect.xml
diff --git a/indra/newview/skins/default/xui/da/menu_people_nearby_view_sort.xml b/indra/newview/skins/default/xui/da/menu_people_nearby_view_sort.xml
index 2f35ff3c92..2f35ff3c92 100644..100755
--- a/indra/newview/skins/default/xui/da/menu_people_nearby_view_sort.xml
+++ b/indra/newview/skins/default/xui/da/menu_people_nearby_view_sort.xml
diff --git a/indra/newview/skins/default/xui/da/menu_people_recent_view_sort.xml b/indra/newview/skins/default/xui/da/menu_people_recent_view_sort.xml
index d081f637f2..d081f637f2 100644..100755
--- a/indra/newview/skins/default/xui/da/menu_people_recent_view_sort.xml
+++ b/indra/newview/skins/default/xui/da/menu_people_recent_view_sort.xml
diff --git a/indra/newview/skins/default/xui/da/menu_picks.xml b/indra/newview/skins/default/xui/da/menu_picks.xml
index 81ee900773..81ee900773 100644..100755
--- a/indra/newview/skins/default/xui/da/menu_picks.xml
+++ b/indra/newview/skins/default/xui/da/menu_picks.xml
diff --git a/indra/newview/skins/default/xui/da/menu_picks_plus.xml b/indra/newview/skins/default/xui/da/menu_picks_plus.xml
index d95071fbbb..d95071fbbb 100644..100755
--- a/indra/newview/skins/default/xui/da/menu_picks_plus.xml
+++ b/indra/newview/skins/default/xui/da/menu_picks_plus.xml
diff --git a/indra/newview/skins/default/xui/da/menu_place.xml b/indra/newview/skins/default/xui/da/menu_place.xml
index b87964ac14..b87964ac14 100644..100755
--- a/indra/newview/skins/default/xui/da/menu_place.xml
+++ b/indra/newview/skins/default/xui/da/menu_place.xml
diff --git a/indra/newview/skins/default/xui/da/menu_place_add_button.xml b/indra/newview/skins/default/xui/da/menu_place_add_button.xml
index 7ad2253550..7ad2253550 100644..100755
--- a/indra/newview/skins/default/xui/da/menu_place_add_button.xml
+++ b/indra/newview/skins/default/xui/da/menu_place_add_button.xml
diff --git a/indra/newview/skins/default/xui/da/menu_places_gear_folder.xml b/indra/newview/skins/default/xui/da/menu_places_gear_folder.xml
index 5f573c2363..5f573c2363 100644..100755
--- a/indra/newview/skins/default/xui/da/menu_places_gear_folder.xml
+++ b/indra/newview/skins/default/xui/da/menu_places_gear_folder.xml
diff --git a/indra/newview/skins/default/xui/da/menu_places_gear_landmark.xml b/indra/newview/skins/default/xui/da/menu_places_gear_landmark.xml
index 13dbcdd42e..13dbcdd42e 100644..100755
--- a/indra/newview/skins/default/xui/da/menu_places_gear_landmark.xml
+++ b/indra/newview/skins/default/xui/da/menu_places_gear_landmark.xml
diff --git a/indra/newview/skins/default/xui/da/menu_profile_overflow.xml b/indra/newview/skins/default/xui/da/menu_profile_overflow.xml
index 6745007c99..6745007c99 100644..100755
--- a/indra/newview/skins/default/xui/da/menu_profile_overflow.xml
+++ b/indra/newview/skins/default/xui/da/menu_profile_overflow.xml
diff --git a/indra/newview/skins/default/xui/da/menu_save_outfit.xml b/indra/newview/skins/default/xui/da/menu_save_outfit.xml
index 188229b586..188229b586 100644..100755
--- a/indra/newview/skins/default/xui/da/menu_save_outfit.xml
+++ b/indra/newview/skins/default/xui/da/menu_save_outfit.xml
diff --git a/indra/newview/skins/default/xui/da/menu_script_chiclet.xml b/indra/newview/skins/default/xui/da/menu_script_chiclet.xml
index cdd3212373..cdd3212373 100644..100755
--- a/indra/newview/skins/default/xui/da/menu_script_chiclet.xml
+++ b/indra/newview/skins/default/xui/da/menu_script_chiclet.xml
diff --git a/indra/newview/skins/default/xui/da/menu_slurl.xml b/indra/newview/skins/default/xui/da/menu_slurl.xml
index a9302e111e..a9302e111e 100644..100755
--- a/indra/newview/skins/default/xui/da/menu_slurl.xml
+++ b/indra/newview/skins/default/xui/da/menu_slurl.xml
diff --git a/indra/newview/skins/default/xui/da/menu_teleport_history_gear.xml b/indra/newview/skins/default/xui/da/menu_teleport_history_gear.xml
index a1c25fea69..a1c25fea69 100644..100755
--- a/indra/newview/skins/default/xui/da/menu_teleport_history_gear.xml
+++ b/indra/newview/skins/default/xui/da/menu_teleport_history_gear.xml
diff --git a/indra/newview/skins/default/xui/da/menu_teleport_history_item.xml b/indra/newview/skins/default/xui/da/menu_teleport_history_item.xml
index dbaec62087..dbaec62087 100644..100755
--- a/indra/newview/skins/default/xui/da/menu_teleport_history_item.xml
+++ b/indra/newview/skins/default/xui/da/menu_teleport_history_item.xml
diff --git a/indra/newview/skins/default/xui/da/menu_teleport_history_tab.xml b/indra/newview/skins/default/xui/da/menu_teleport_history_tab.xml
index c4d4bb4b5b..c4d4bb4b5b 100644..100755
--- a/indra/newview/skins/default/xui/da/menu_teleport_history_tab.xml
+++ b/indra/newview/skins/default/xui/da/menu_teleport_history_tab.xml
diff --git a/indra/newview/skins/default/xui/da/menu_text_editor.xml b/indra/newview/skins/default/xui/da/menu_text_editor.xml
index 3ff31ea232..3ff31ea232 100644..100755
--- a/indra/newview/skins/default/xui/da/menu_text_editor.xml
+++ b/indra/newview/skins/default/xui/da/menu_text_editor.xml
diff --git a/indra/newview/skins/default/xui/da/menu_topinfobar.xml b/indra/newview/skins/default/xui/da/menu_topinfobar.xml
index 08d1c25d6f..08d1c25d6f 100644..100755
--- a/indra/newview/skins/default/xui/da/menu_topinfobar.xml
+++ b/indra/newview/skins/default/xui/da/menu_topinfobar.xml
diff --git a/indra/newview/skins/default/xui/da/menu_url_agent.xml b/indra/newview/skins/default/xui/da/menu_url_agent.xml
index 491586f3b4..491586f3b4 100644..100755
--- a/indra/newview/skins/default/xui/da/menu_url_agent.xml
+++ b/indra/newview/skins/default/xui/da/menu_url_agent.xml
diff --git a/indra/newview/skins/default/xui/da/menu_url_group.xml b/indra/newview/skins/default/xui/da/menu_url_group.xml
index c776159b0a..c776159b0a 100644..100755
--- a/indra/newview/skins/default/xui/da/menu_url_group.xml
+++ b/indra/newview/skins/default/xui/da/menu_url_group.xml
diff --git a/indra/newview/skins/default/xui/da/menu_url_http.xml b/indra/newview/skins/default/xui/da/menu_url_http.xml
index 4398777a39..4398777a39 100644..100755
--- a/indra/newview/skins/default/xui/da/menu_url_http.xml
+++ b/indra/newview/skins/default/xui/da/menu_url_http.xml
diff --git a/indra/newview/skins/default/xui/da/menu_url_inventory.xml b/indra/newview/skins/default/xui/da/menu_url_inventory.xml
index 9a7de23e06..9a7de23e06 100644..100755
--- a/indra/newview/skins/default/xui/da/menu_url_inventory.xml
+++ b/indra/newview/skins/default/xui/da/menu_url_inventory.xml
diff --git a/indra/newview/skins/default/xui/da/menu_url_map.xml b/indra/newview/skins/default/xui/da/menu_url_map.xml
index ff4a4d5174..ff4a4d5174 100644..100755
--- a/indra/newview/skins/default/xui/da/menu_url_map.xml
+++ b/indra/newview/skins/default/xui/da/menu_url_map.xml
diff --git a/indra/newview/skins/default/xui/da/menu_url_objectim.xml b/indra/newview/skins/default/xui/da/menu_url_objectim.xml
index e27cf84959..e27cf84959 100644..100755
--- a/indra/newview/skins/default/xui/da/menu_url_objectim.xml
+++ b/indra/newview/skins/default/xui/da/menu_url_objectim.xml
diff --git a/indra/newview/skins/default/xui/da/menu_url_parcel.xml b/indra/newview/skins/default/xui/da/menu_url_parcel.xml
index 0f21e14f66..0f21e14f66 100644..100755
--- a/indra/newview/skins/default/xui/da/menu_url_parcel.xml
+++ b/indra/newview/skins/default/xui/da/menu_url_parcel.xml
diff --git a/indra/newview/skins/default/xui/da/menu_url_slapp.xml b/indra/newview/skins/default/xui/da/menu_url_slapp.xml
index dd25db2aa7..dd25db2aa7 100644..100755
--- a/indra/newview/skins/default/xui/da/menu_url_slapp.xml
+++ b/indra/newview/skins/default/xui/da/menu_url_slapp.xml
diff --git a/indra/newview/skins/default/xui/da/menu_url_slurl.xml b/indra/newview/skins/default/xui/da/menu_url_slurl.xml
index 8d84a138bb..8d84a138bb 100644..100755
--- a/indra/newview/skins/default/xui/da/menu_url_slurl.xml
+++ b/indra/newview/skins/default/xui/da/menu_url_slurl.xml
diff --git a/indra/newview/skins/default/xui/da/menu_url_teleport.xml b/indra/newview/skins/default/xui/da/menu_url_teleport.xml
index e0ca7b920d..e0ca7b920d 100644..100755
--- a/indra/newview/skins/default/xui/da/menu_url_teleport.xml
+++ b/indra/newview/skins/default/xui/da/menu_url_teleport.xml
diff --git a/indra/newview/skins/default/xui/da/menu_viewer.xml b/indra/newview/skins/default/xui/da/menu_viewer.xml
index d695cd1f89..f2ed7c2e64 100644..100755
--- a/indra/newview/skins/default/xui/da/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/da/menu_viewer.xml
@@ -245,7 +245,7 @@
<menu label="Gengivelse" name="Rendering">
<menu_item_check label="Akser" name="Axes"/>
<menu_item_check label="Wireframe" name="Wireframe"/>
- <menu_item_check label="Lys og skygger" name="Lighting and Shadows"/>
+ <menu_item_check label="Lys og skygger" name="Advanced Lighting Model"/>
<menu_item_check label="Skygger fra sol/måne/andre lyskilder" name="Shadows from Sun/Moon/Projectors"/>
<menu_item_check label="SSAO og skygge udjævning" name="SSAO and Shadow Smoothing"/>
<menu_item_check label="Globalt lys (eksperimentiel)" name="Global Illumination"/>
diff --git a/indra/newview/skins/default/xui/da/menu_wearable_list_item.xml b/indra/newview/skins/default/xui/da/menu_wearable_list_item.xml
index 63f4b0b388..63f4b0b388 100644..100755
--- a/indra/newview/skins/default/xui/da/menu_wearable_list_item.xml
+++ b/indra/newview/skins/default/xui/da/menu_wearable_list_item.xml
diff --git a/indra/newview/skins/default/xui/da/menu_wearing_gear.xml b/indra/newview/skins/default/xui/da/menu_wearing_gear.xml
index 515a15b287..515a15b287 100644..100755
--- a/indra/newview/skins/default/xui/da/menu_wearing_gear.xml
+++ b/indra/newview/skins/default/xui/da/menu_wearing_gear.xml
diff --git a/indra/newview/skins/default/xui/da/menu_wearing_tab.xml b/indra/newview/skins/default/xui/da/menu_wearing_tab.xml
index c0db7b6842..c0db7b6842 100644..100755
--- a/indra/newview/skins/default/xui/da/menu_wearing_tab.xml
+++ b/indra/newview/skins/default/xui/da/menu_wearing_tab.xml
diff --git a/indra/newview/skins/default/xui/da/mime_types.xml b/indra/newview/skins/default/xui/da/mime_types.xml
index 0b00a29f07..0b00a29f07 100644..100755
--- a/indra/newview/skins/default/xui/da/mime_types.xml
+++ b/indra/newview/skins/default/xui/da/mime_types.xml
diff --git a/indra/newview/skins/default/xui/da/mime_types_linux.xml b/indra/newview/skins/default/xui/da/mime_types_linux.xml
index 69a0fb23f6..69a0fb23f6 100644..100755
--- a/indra/newview/skins/default/xui/da/mime_types_linux.xml
+++ b/indra/newview/skins/default/xui/da/mime_types_linux.xml
diff --git a/indra/newview/skins/default/xui/da/mime_types_mac.xml b/indra/newview/skins/default/xui/da/mime_types_mac.xml
index bd9981b045..bd9981b045 100644..100755
--- a/indra/newview/skins/default/xui/da/mime_types_mac.xml
+++ b/indra/newview/skins/default/xui/da/mime_types_mac.xml
diff --git a/indra/newview/skins/default/xui/da/notifications.xml b/indra/newview/skins/default/xui/da/notifications.xml
index cf6f1ccdd9..33b876bdb9 100644..100755
--- a/indra/newview/skins/default/xui/da/notifications.xml
+++ b/indra/newview/skins/default/xui/da/notifications.xml
@@ -481,7 +481,6 @@ Du kan bruge [SECOND_LIFE] normalt og andre personer vil se dig korrekt.
[APP_NAME] installationen er færdig.
Hvis det er første gang du bruger [SECOND_LIFE], skal du først oprette en konto for at logge på.
-Vend tilbage til [http://join.secondlife.com secondlife.com] for at oprette en ny konto?
</notification>
<notification name="LoginPacketNeverReceived">
Der er problemer med at koble på. Der kan være et problem med din Internet forbindelse eller [SECOND_LIFE_GRID].
diff --git a/indra/newview/skins/default/xui/da/outfit_accordion_tab.xml b/indra/newview/skins/default/xui/da/outfit_accordion_tab.xml
index e2d1f26d42..e2d1f26d42 100644..100755
--- a/indra/newview/skins/default/xui/da/outfit_accordion_tab.xml
+++ b/indra/newview/skins/default/xui/da/outfit_accordion_tab.xml
diff --git a/indra/newview/skins/default/xui/da/panel_active_object_row.xml b/indra/newview/skins/default/xui/da/panel_active_object_row.xml
index 9c27ea7fe2..9c27ea7fe2 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_active_object_row.xml
+++ b/indra/newview/skins/default/xui/da/panel_active_object_row.xml
diff --git a/indra/newview/skins/default/xui/da/panel_adhoc_control_panel.xml b/indra/newview/skins/default/xui/da/panel_adhoc_control_panel.xml
index 1953fad31f..1953fad31f 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_adhoc_control_panel.xml
+++ b/indra/newview/skins/default/xui/da/panel_adhoc_control_panel.xml
diff --git a/indra/newview/skins/default/xui/da/panel_avatar_list_item.xml b/indra/newview/skins/default/xui/da/panel_avatar_list_item.xml
index 890f4a2f0a..890f4a2f0a 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_avatar_list_item.xml
+++ b/indra/newview/skins/default/xui/da/panel_avatar_list_item.xml
diff --git a/indra/newview/skins/default/xui/da/panel_block_list_sidetray.xml b/indra/newview/skins/default/xui/da/panel_block_list_sidetray.xml
index 4f5041ad54..4f5041ad54 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_block_list_sidetray.xml
+++ b/indra/newview/skins/default/xui/da/panel_block_list_sidetray.xml
diff --git a/indra/newview/skins/default/xui/da/panel_body_parts_list_item.xml b/indra/newview/skins/default/xui/da/panel_body_parts_list_item.xml
index d2ade170d1..d2ade170d1 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_body_parts_list_item.xml
+++ b/indra/newview/skins/default/xui/da/panel_body_parts_list_item.xml
diff --git a/indra/newview/skins/default/xui/da/panel_bodyparts_list_button_bar.xml b/indra/newview/skins/default/xui/da/panel_bodyparts_list_button_bar.xml
index 4cbcdebbe4..4cbcdebbe4 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_bodyparts_list_button_bar.xml
+++ b/indra/newview/skins/default/xui/da/panel_bodyparts_list_button_bar.xml
diff --git a/indra/newview/skins/default/xui/da/panel_bottomtray.xml b/indra/newview/skins/default/xui/da/panel_bottomtray.xml
index 3cd9d55dd0..3cd9d55dd0 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_bottomtray.xml
+++ b/indra/newview/skins/default/xui/da/panel_bottomtray.xml
diff --git a/indra/newview/skins/default/xui/da/panel_bottomtray_lite.xml b/indra/newview/skins/default/xui/da/panel_bottomtray_lite.xml
index bd31253ca4..bd31253ca4 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_bottomtray_lite.xml
+++ b/indra/newview/skins/default/xui/da/panel_bottomtray_lite.xml
diff --git a/indra/newview/skins/default/xui/da/panel_classified_info.xml b/indra/newview/skins/default/xui/da/panel_classified_info.xml
index a54d320ffd..a54d320ffd 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_classified_info.xml
+++ b/indra/newview/skins/default/xui/da/panel_classified_info.xml
diff --git a/indra/newview/skins/default/xui/da/panel_clothing_list_button_bar.xml b/indra/newview/skins/default/xui/da/panel_clothing_list_button_bar.xml
index c08d095c66..c08d095c66 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_clothing_list_button_bar.xml
+++ b/indra/newview/skins/default/xui/da/panel_clothing_list_button_bar.xml
diff --git a/indra/newview/skins/default/xui/da/panel_clothing_list_item.xml b/indra/newview/skins/default/xui/da/panel_clothing_list_item.xml
index 88b0636e9e..88b0636e9e 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_clothing_list_item.xml
+++ b/indra/newview/skins/default/xui/da/panel_clothing_list_item.xml
diff --git a/indra/newview/skins/default/xui/da/panel_cof_wearables.xml b/indra/newview/skins/default/xui/da/panel_cof_wearables.xml
index 92d78b01a2..92d78b01a2 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_cof_wearables.xml
+++ b/indra/newview/skins/default/xui/da/panel_cof_wearables.xml
diff --git a/indra/newview/skins/default/xui/da/panel_deletable_wearable_list_item.xml b/indra/newview/skins/default/xui/da/panel_deletable_wearable_list_item.xml
index 700ad4fa14..700ad4fa14 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_deletable_wearable_list_item.xml
+++ b/indra/newview/skins/default/xui/da/panel_deletable_wearable_list_item.xml
diff --git a/indra/newview/skins/default/xui/da/panel_dummy_clothing_list_item.xml b/indra/newview/skins/default/xui/da/panel_dummy_clothing_list_item.xml
index dd8d86cfbf..dd8d86cfbf 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_dummy_clothing_list_item.xml
+++ b/indra/newview/skins/default/xui/da/panel_dummy_clothing_list_item.xml
diff --git a/indra/newview/skins/default/xui/da/panel_edit_alpha.xml b/indra/newview/skins/default/xui/da/panel_edit_alpha.xml
index 0f60a6df51..0f60a6df51 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_edit_alpha.xml
+++ b/indra/newview/skins/default/xui/da/panel_edit_alpha.xml
diff --git a/indra/newview/skins/default/xui/da/panel_edit_classified.xml b/indra/newview/skins/default/xui/da/panel_edit_classified.xml
index fc4780a34e..fc4780a34e 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_edit_classified.xml
+++ b/indra/newview/skins/default/xui/da/panel_edit_classified.xml
diff --git a/indra/newview/skins/default/xui/da/panel_edit_eyes.xml b/indra/newview/skins/default/xui/da/panel_edit_eyes.xml
index d801118cea..d801118cea 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_edit_eyes.xml
+++ b/indra/newview/skins/default/xui/da/panel_edit_eyes.xml
diff --git a/indra/newview/skins/default/xui/da/panel_edit_gloves.xml b/indra/newview/skins/default/xui/da/panel_edit_gloves.xml
index 36f58428a6..36f58428a6 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_edit_gloves.xml
+++ b/indra/newview/skins/default/xui/da/panel_edit_gloves.xml
diff --git a/indra/newview/skins/default/xui/da/panel_edit_hair.xml b/indra/newview/skins/default/xui/da/panel_edit_hair.xml
index e91e6324e8..e91e6324e8 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_edit_hair.xml
+++ b/indra/newview/skins/default/xui/da/panel_edit_hair.xml
diff --git a/indra/newview/skins/default/xui/da/panel_edit_jacket.xml b/indra/newview/skins/default/xui/da/panel_edit_jacket.xml
index 4e7336747d..4e7336747d 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_edit_jacket.xml
+++ b/indra/newview/skins/default/xui/da/panel_edit_jacket.xml
diff --git a/indra/newview/skins/default/xui/da/panel_edit_pants.xml b/indra/newview/skins/default/xui/da/panel_edit_pants.xml
index 61056e9e6c..61056e9e6c 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_edit_pants.xml
+++ b/indra/newview/skins/default/xui/da/panel_edit_pants.xml
diff --git a/indra/newview/skins/default/xui/da/panel_edit_physics.xml b/indra/newview/skins/default/xui/da/panel_edit_physics.xml
index 16c9b16fa3..16c9b16fa3 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_edit_physics.xml
+++ b/indra/newview/skins/default/xui/da/panel_edit_physics.xml
diff --git a/indra/newview/skins/default/xui/da/panel_edit_pick.xml b/indra/newview/skins/default/xui/da/panel_edit_pick.xml
index 3036f30240..3036f30240 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_edit_pick.xml
+++ b/indra/newview/skins/default/xui/da/panel_edit_pick.xml
diff --git a/indra/newview/skins/default/xui/da/panel_edit_profile.xml b/indra/newview/skins/default/xui/da/panel_edit_profile.xml
index 14fd48ba2f..14fd48ba2f 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_edit_profile.xml
+++ b/indra/newview/skins/default/xui/da/panel_edit_profile.xml
diff --git a/indra/newview/skins/default/xui/da/panel_edit_shape.xml b/indra/newview/skins/default/xui/da/panel_edit_shape.xml
index 7c1ffe5cfa..7c1ffe5cfa 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_edit_shape.xml
+++ b/indra/newview/skins/default/xui/da/panel_edit_shape.xml
diff --git a/indra/newview/skins/default/xui/da/panel_edit_shirt.xml b/indra/newview/skins/default/xui/da/panel_edit_shirt.xml
index 4dfb47aab2..4dfb47aab2 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_edit_shirt.xml
+++ b/indra/newview/skins/default/xui/da/panel_edit_shirt.xml
diff --git a/indra/newview/skins/default/xui/da/panel_edit_shoes.xml b/indra/newview/skins/default/xui/da/panel_edit_shoes.xml
index 653ea421b5..653ea421b5 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_edit_shoes.xml
+++ b/indra/newview/skins/default/xui/da/panel_edit_shoes.xml
diff --git a/indra/newview/skins/default/xui/da/panel_edit_skin.xml b/indra/newview/skins/default/xui/da/panel_edit_skin.xml
index 608e1d6e0b..608e1d6e0b 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_edit_skin.xml
+++ b/indra/newview/skins/default/xui/da/panel_edit_skin.xml
diff --git a/indra/newview/skins/default/xui/da/panel_edit_skirt.xml b/indra/newview/skins/default/xui/da/panel_edit_skirt.xml
index e80e60efd8..e80e60efd8 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_edit_skirt.xml
+++ b/indra/newview/skins/default/xui/da/panel_edit_skirt.xml
diff --git a/indra/newview/skins/default/xui/da/panel_edit_socks.xml b/indra/newview/skins/default/xui/da/panel_edit_socks.xml
index 82a7341317..82a7341317 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_edit_socks.xml
+++ b/indra/newview/skins/default/xui/da/panel_edit_socks.xml
diff --git a/indra/newview/skins/default/xui/da/panel_edit_tattoo.xml b/indra/newview/skins/default/xui/da/panel_edit_tattoo.xml
index d4a12209db..d4a12209db 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_edit_tattoo.xml
+++ b/indra/newview/skins/default/xui/da/panel_edit_tattoo.xml
diff --git a/indra/newview/skins/default/xui/da/panel_edit_underpants.xml b/indra/newview/skins/default/xui/da/panel_edit_underpants.xml
index aacfae79e1..aacfae79e1 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_edit_underpants.xml
+++ b/indra/newview/skins/default/xui/da/panel_edit_underpants.xml
diff --git a/indra/newview/skins/default/xui/da/panel_edit_undershirt.xml b/indra/newview/skins/default/xui/da/panel_edit_undershirt.xml
index a9db5d2ab0..a9db5d2ab0 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_edit_undershirt.xml
+++ b/indra/newview/skins/default/xui/da/panel_edit_undershirt.xml
diff --git a/indra/newview/skins/default/xui/da/panel_edit_wearable.xml b/indra/newview/skins/default/xui/da/panel_edit_wearable.xml
index 906870e6d9..906870e6d9 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_edit_wearable.xml
+++ b/indra/newview/skins/default/xui/da/panel_edit_wearable.xml
diff --git a/indra/newview/skins/default/xui/da/panel_group_control_panel.xml b/indra/newview/skins/default/xui/da/panel_group_control_panel.xml
index 26fe4f6ebe..26fe4f6ebe 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_group_control_panel.xml
+++ b/indra/newview/skins/default/xui/da/panel_group_control_panel.xml
diff --git a/indra/newview/skins/default/xui/da/panel_group_general.xml b/indra/newview/skins/default/xui/da/panel_group_general.xml
index eccddb55c8..eccddb55c8 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_group_general.xml
+++ b/indra/newview/skins/default/xui/da/panel_group_general.xml
diff --git a/indra/newview/skins/default/xui/da/panel_group_info_sidetray.xml b/indra/newview/skins/default/xui/da/panel_group_info_sidetray.xml
index 3d561f1e5b..3d561f1e5b 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_group_info_sidetray.xml
+++ b/indra/newview/skins/default/xui/da/panel_group_info_sidetray.xml
diff --git a/indra/newview/skins/default/xui/da/panel_group_invite.xml b/indra/newview/skins/default/xui/da/panel_group_invite.xml
index 49daf6c9f2..49daf6c9f2 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_group_invite.xml
+++ b/indra/newview/skins/default/xui/da/panel_group_invite.xml
diff --git a/indra/newview/skins/default/xui/da/panel_group_land_money.xml b/indra/newview/skins/default/xui/da/panel_group_land_money.xml
index 49d415e515..49d415e515 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_group_land_money.xml
+++ b/indra/newview/skins/default/xui/da/panel_group_land_money.xml
diff --git a/indra/newview/skins/default/xui/da/panel_group_list_item.xml b/indra/newview/skins/default/xui/da/panel_group_list_item.xml
index e77e548340..e77e548340 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_group_list_item.xml
+++ b/indra/newview/skins/default/xui/da/panel_group_list_item.xml
diff --git a/indra/newview/skins/default/xui/da/panel_group_notices.xml b/indra/newview/skins/default/xui/da/panel_group_notices.xml
index 0a0b8f5e04..0a0b8f5e04 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_group_notices.xml
+++ b/indra/newview/skins/default/xui/da/panel_group_notices.xml
diff --git a/indra/newview/skins/default/xui/da/panel_group_notify.xml b/indra/newview/skins/default/xui/da/panel_group_notify.xml
index 8a684ca031..8a684ca031 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_group_notify.xml
+++ b/indra/newview/skins/default/xui/da/panel_group_notify.xml
diff --git a/indra/newview/skins/default/xui/da/panel_group_roles.xml b/indra/newview/skins/default/xui/da/panel_group_roles.xml
index ebc773f7ed..ebc773f7ed 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_group_roles.xml
+++ b/indra/newview/skins/default/xui/da/panel_group_roles.xml
diff --git a/indra/newview/skins/default/xui/da/panel_im_control_panel.xml b/indra/newview/skins/default/xui/da/panel_im_control_panel.xml
index 5cecb93d40..5cecb93d40 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_im_control_panel.xml
+++ b/indra/newview/skins/default/xui/da/panel_im_control_panel.xml
diff --git a/indra/newview/skins/default/xui/da/panel_inventory_item.xml b/indra/newview/skins/default/xui/da/panel_inventory_item.xml
index d18047fbcf..d18047fbcf 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_inventory_item.xml
+++ b/indra/newview/skins/default/xui/da/panel_inventory_item.xml
diff --git a/indra/newview/skins/default/xui/da/panel_landmark_info.xml b/indra/newview/skins/default/xui/da/panel_landmark_info.xml
index 8503a41763..8503a41763 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_landmark_info.xml
+++ b/indra/newview/skins/default/xui/da/panel_landmark_info.xml
diff --git a/indra/newview/skins/default/xui/da/panel_landmarks.xml b/indra/newview/skins/default/xui/da/panel_landmarks.xml
index e9e5e506fd..e9e5e506fd 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_landmarks.xml
+++ b/indra/newview/skins/default/xui/da/panel_landmarks.xml
diff --git a/indra/newview/skins/default/xui/da/panel_login.xml b/indra/newview/skins/default/xui/da/panel_login.xml
index 2e0f726e1a..b7cb76d4cb 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_login.xml
+++ b/indra/newview/skins/default/xui/da/panel_login.xml
@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel name="panel_login">
- <panel.string name="create_account_url">
- http://join.secondlife.com/
- </panel.string>
<panel.string name="forgot_password_url">
http://secondlife.com/account/request.php
</panel.string>
<layout_stack name="login_widgets">
<layout_panel name="login">
+ <text name="log_in_text">
+ LOG PÃ…
+ </text>
<text name="username_text">
Brugernavn:
</text>
@@ -15,15 +15,8 @@
<text name="password_text">
Password:
</text>
- <check_box label="Husk password" name="remember_check"/>
- <button label="Log på" name="connect_btn"/>
- <text name="mode_selection_text">
- Tilstand:
- </text>
- <combo_box name="mode_combo" tool_tip="Vælg ønsket tilstand. Vælg basis for hurtig og nem udforskning og chat. Vælg avanceret for at få adgang til flere muligheder.">
- <combo_box.item label="Basis" name="Basic"/>
- <combo_box.item label="Avanceret" name="Advanced"/>
- </combo_box>
+ </layout_panel>
+ <layout_panel name="start_location_panel">
<text name="start_location_text">
Start ved:
</text>
@@ -33,16 +26,21 @@
<combo_box.item label="&lt;Indtast regionnavn&gt;" name="Typeregionname"/>
</combo_box>
</layout_panel>
- <layout_panel name="links">
- <text name="create_new_account_text">
- Opret bruger
+ <layout_panel name="links_login_panel">
+ <text name="login_help">
+ Hjælp til login
</text>
<text name="forgot_password_text">
Har du glemt brugernavn eller password?
</text>
- <text name="login_help">
- Hjælp til login
+ <button label="Log på" name="connect_btn"/>
+ <check_box label="Husk password" name="remember_check"/>
+ </layout_panel>
+ <layout_panel name="links">
+ <text name="create_account_text">
+ CREATE YǾUR ACCǾUNT
</text>
+ <button name="create_new_account_btn" label="Opret bruger"/>
</layout_panel>
</layout_stack>
</panel>
diff --git a/indra/newview/skins/default/xui/da/panel_main_inventory.xml b/indra/newview/skins/default/xui/da/panel_main_inventory.xml
index d6406939c1..d6406939c1 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_main_inventory.xml
+++ b/indra/newview/skins/default/xui/da/panel_main_inventory.xml
diff --git a/indra/newview/skins/default/xui/da/panel_me.xml b/indra/newview/skins/default/xui/da/panel_me.xml
index f98ced5f91..f98ced5f91 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_me.xml
+++ b/indra/newview/skins/default/xui/da/panel_me.xml
diff --git a/indra/newview/skins/default/xui/da/panel_media_settings_general.xml b/indra/newview/skins/default/xui/da/panel_media_settings_general.xml
index 48f08b9dfd..48f08b9dfd 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_media_settings_general.xml
+++ b/indra/newview/skins/default/xui/da/panel_media_settings_general.xml
diff --git a/indra/newview/skins/default/xui/da/panel_media_settings_permissions.xml b/indra/newview/skins/default/xui/da/panel_media_settings_permissions.xml
index 84468eb2a7..84468eb2a7 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_media_settings_permissions.xml
+++ b/indra/newview/skins/default/xui/da/panel_media_settings_permissions.xml
diff --git a/indra/newview/skins/default/xui/da/panel_media_settings_security.xml b/indra/newview/skins/default/xui/da/panel_media_settings_security.xml
index 1b64888271..1b64888271 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_media_settings_security.xml
+++ b/indra/newview/skins/default/xui/da/panel_media_settings_security.xml
diff --git a/indra/newview/skins/default/xui/da/panel_navigation_bar.xml b/indra/newview/skins/default/xui/da/panel_navigation_bar.xml
index 2ee87433a4..2ee87433a4 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_navigation_bar.xml
+++ b/indra/newview/skins/default/xui/da/panel_navigation_bar.xml
diff --git a/indra/newview/skins/default/xui/da/panel_nearby_chat_bar.xml b/indra/newview/skins/default/xui/da/panel_nearby_chat_bar.xml
index 949cbcbd7b..eb104201f8 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_nearby_chat_bar.xml
+++ b/indra/newview/skins/default/xui/da/panel_nearby_chat_bar.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel name="chat_bar">
+<panel name="nearby_chat">
<line_editor label="Klik her for at chatte." name="chat_box" tool_tip="Tryk på enter for at tale, Ctrl-Enter for at råbe."/>
<button name="show_nearby_chat" tool_tip="Viser/skjuler log for chat nærved"/>
</panel>
diff --git a/indra/newview/skins/default/xui/da/panel_nearby_media.xml b/indra/newview/skins/default/xui/da/panel_nearby_media.xml
index ef8ed3ad07..ef8ed3ad07 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_nearby_media.xml
+++ b/indra/newview/skins/default/xui/da/panel_nearby_media.xml
diff --git a/indra/newview/skins/default/xui/da/panel_notify_textbox.xml b/indra/newview/skins/default/xui/da/panel_notify_textbox.xml
index 30ad4ff9f6..30ad4ff9f6 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_notify_textbox.xml
+++ b/indra/newview/skins/default/xui/da/panel_notify_textbox.xml
diff --git a/indra/newview/skins/default/xui/da/panel_online_status_toast.xml b/indra/newview/skins/default/xui/da/panel_online_status_toast.xml
index fdc489f375..fdc489f375 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_online_status_toast.xml
+++ b/indra/newview/skins/default/xui/da/panel_online_status_toast.xml
diff --git a/indra/newview/skins/default/xui/da/panel_outfit_edit.xml b/indra/newview/skins/default/xui/da/panel_outfit_edit.xml
index 3736ea06ba..3736ea06ba 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_outfit_edit.xml
+++ b/indra/newview/skins/default/xui/da/panel_outfit_edit.xml
diff --git a/indra/newview/skins/default/xui/da/panel_outfits_inventory.xml b/indra/newview/skins/default/xui/da/panel_outfits_inventory.xml
index 055c42c003..055c42c003 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_outfits_inventory.xml
+++ b/indra/newview/skins/default/xui/da/panel_outfits_inventory.xml
diff --git a/indra/newview/skins/default/xui/da/panel_outfits_inventory_gear_default.xml b/indra/newview/skins/default/xui/da/panel_outfits_inventory_gear_default.xml
index 7b6469023b..7b6469023b 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_outfits_inventory_gear_default.xml
+++ b/indra/newview/skins/default/xui/da/panel_outfits_inventory_gear_default.xml
diff --git a/indra/newview/skins/default/xui/da/panel_outfits_list.xml b/indra/newview/skins/default/xui/da/panel_outfits_list.xml
index 72caedb461..72caedb461 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_outfits_list.xml
+++ b/indra/newview/skins/default/xui/da/panel_outfits_list.xml
diff --git a/indra/newview/skins/default/xui/da/panel_outfits_wearing.xml b/indra/newview/skins/default/xui/da/panel_outfits_wearing.xml
index 8d25efa97b..8d25efa97b 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_outfits_wearing.xml
+++ b/indra/newview/skins/default/xui/da/panel_outfits_wearing.xml
diff --git a/indra/newview/skins/default/xui/da/panel_people.xml b/indra/newview/skins/default/xui/da/panel_people.xml
index 66a128cd13..66a128cd13 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_people.xml
+++ b/indra/newview/skins/default/xui/da/panel_people.xml
diff --git a/indra/newview/skins/default/xui/da/panel_pick_info.xml b/indra/newview/skins/default/xui/da/panel_pick_info.xml
index 8a5141f967..8a5141f967 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_pick_info.xml
+++ b/indra/newview/skins/default/xui/da/panel_pick_info.xml
diff --git a/indra/newview/skins/default/xui/da/panel_picks.xml b/indra/newview/skins/default/xui/da/panel_picks.xml
index 8af68ee69a..8af68ee69a 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_picks.xml
+++ b/indra/newview/skins/default/xui/da/panel_picks.xml
diff --git a/indra/newview/skins/default/xui/da/panel_place_profile.xml b/indra/newview/skins/default/xui/da/panel_place_profile.xml
index 8dd0fb2d21..8dd0fb2d21 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_place_profile.xml
+++ b/indra/newview/skins/default/xui/da/panel_place_profile.xml
diff --git a/indra/newview/skins/default/xui/da/panel_places.xml b/indra/newview/skins/default/xui/da/panel_places.xml
index c555f2fb09..c555f2fb09 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_places.xml
+++ b/indra/newview/skins/default/xui/da/panel_places.xml
diff --git a/indra/newview/skins/default/xui/da/panel_preferences_advanced.xml b/indra/newview/skins/default/xui/da/panel_preferences_advanced.xml
index 48106c7dfe..48106c7dfe 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_preferences_advanced.xml
+++ b/indra/newview/skins/default/xui/da/panel_preferences_advanced.xml
diff --git a/indra/newview/skins/default/xui/da/panel_preferences_alerts.xml b/indra/newview/skins/default/xui/da/panel_preferences_alerts.xml
index 7caa17d514..7caa17d514 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_preferences_alerts.xml
+++ b/indra/newview/skins/default/xui/da/panel_preferences_alerts.xml
diff --git a/indra/newview/skins/default/xui/da/panel_preferences_chat.xml b/indra/newview/skins/default/xui/da/panel_preferences_chat.xml
index 890a3038ef..890a3038ef 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/da/panel_preferences_chat.xml
diff --git a/indra/newview/skins/default/xui/da/panel_preferences_colors.xml b/indra/newview/skins/default/xui/da/panel_preferences_colors.xml
index cc3dc480bc..cc3dc480bc 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_preferences_colors.xml
+++ b/indra/newview/skins/default/xui/da/panel_preferences_colors.xml
diff --git a/indra/newview/skins/default/xui/da/panel_preferences_general.xml b/indra/newview/skins/default/xui/da/panel_preferences_general.xml
index 5702d48e97..5702d48e97 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_preferences_general.xml
+++ b/indra/newview/skins/default/xui/da/panel_preferences_general.xml
diff --git a/indra/newview/skins/default/xui/da/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/da/panel_preferences_graphics1.xml
index 72200a07ad..e494b2b755 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_preferences_graphics1.xml
+++ b/indra/newview/skins/default/xui/da/panel_preferences_graphics1.xml
@@ -26,14 +26,14 @@
<text name="ShadersText">
Overflader:
</text>
- <check_box initial_value="sand" label="Gennemsigtig vand" name="TransparentWater"/>
+ <check_box initial_value="true" label="Gennemsigtig vand" name="TransparentWater"/>
<check_box initial_value="true" label="Glatte flader og skin" name="BumpShiny"/>
- <check_box initial_value="sand" label="Lokale lys" name="LocalLights"/>
+ <check_box initial_value="true" label="Lokale lys" name="LocalLights"/>
<check_box initial_value="true" label="Basale flader" name="BasicShaders" tool_tip="Ved at slå dette valg fra, kan det forhindres at visse grafikkort drivere crasher."/>
<check_box initial_value="true" label="Atmosfæriske flader" name="WindLightUseAtmosShaders"/>
- <check_box initial_value="sand" label="Lys og skygger" name="UseLightShaders"/>
- <check_box initial_value="sand" label="&quot;Ambient Occlusion&quot;" name="UseSSAO"/>
- <check_box initial_value="sand" label="Skarphedsdybde" name="UseDoF"/>
+ <check_box initial_value="true" label="Lys og skygger" name="UseLightShaders"/>
+ <check_box initial_value="true" label="&quot;Ambient Occlusion&quot;" name="UseSSAO"/>
+ <check_box initial_value="true" label="Skarphedsdybde" name="UseDoF"/>
<text name="shadows_label">
Skygger:
</text>
diff --git a/indra/newview/skins/default/xui/da/panel_preferences_move.xml b/indra/newview/skins/default/xui/da/panel_preferences_move.xml
index 98dfed92c1..98dfed92c1 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_preferences_move.xml
+++ b/indra/newview/skins/default/xui/da/panel_preferences_move.xml
diff --git a/indra/newview/skins/default/xui/da/panel_preferences_privacy.xml b/indra/newview/skins/default/xui/da/panel_preferences_privacy.xml
index 0df330b016..0df330b016 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_preferences_privacy.xml
+++ b/indra/newview/skins/default/xui/da/panel_preferences_privacy.xml
diff --git a/indra/newview/skins/default/xui/da/panel_preferences_setup.xml b/indra/newview/skins/default/xui/da/panel_preferences_setup.xml
index 479e98817e..7be9a9d555 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_preferences_setup.xml
+++ b/indra/newview/skins/default/xui/da/panel_preferences_setup.xml
@@ -26,14 +26,13 @@
Web:
</text>
<radio_group name="use_external_browser">
- <radio_item label="Benyt min browser(IE, Firefox, Safari)" name="external" tool_tip="Brug systemets standard web browser til hjælp, web links, m.v. Ikke anbefalet hvis du kører i fuld-skærm." value="1"/>
+ <radio_item label="Benyt min browser(IE, Firefox, Safari)" name="external" tool_tip="Brug systemets standard web browser til hjælp, web links, m.v. Ikke anbefalet hvis du kører i fuld-skærm." value="true"/>
<radio_item label="Benyt den indbyggede browser" name="internal" tool_tip="Brug den indbyggede web browser til hjælp, web links m.v. Denne browser åbner et nyt vindue i [APP_NAME]." value=""/>
</radio_group>
<check_box initial_value="true" label="Aktivér plugins" name="browser_plugins_enabled"/>
<check_box initial_value="true" label="Acceptér cookies" name="cookies_enabled"/>
<check_box initial_value="true" label="Aktivér Javascript" name="browser_javascript_enabled"/>
- <check_box initial_value="fra" label="Tilad media browser pop-ups" name="media_popup_enabled"/>
- <check_box initial_value="false" label="Aktivér web proxy" name="web_proxy_enabled"/>
+ <check_box initial_value="false" label="Tilad media browser pop-ups" name="media_popup_enabled"/>
<text name="Proxy location">
Proxy placering:
</text>
diff --git a/indra/newview/skins/default/xui/da/panel_preferences_sound.xml b/indra/newview/skins/default/xui/da/panel_preferences_sound.xml
index 26d2ae4abd..26d2ae4abd 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_preferences_sound.xml
+++ b/indra/newview/skins/default/xui/da/panel_preferences_sound.xml
diff --git a/indra/newview/skins/default/xui/da/panel_prim_media_controls.xml b/indra/newview/skins/default/xui/da/panel_prim_media_controls.xml
index cfb32500c6..cfb32500c6 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_prim_media_controls.xml
+++ b/indra/newview/skins/default/xui/da/panel_prim_media_controls.xml
diff --git a/indra/newview/skins/default/xui/da/panel_region_covenant.xml b/indra/newview/skins/default/xui/da/panel_region_covenant.xml
index 4b9c7539ea..4b9c7539ea 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_region_covenant.xml
+++ b/indra/newview/skins/default/xui/da/panel_region_covenant.xml
diff --git a/indra/newview/skins/default/xui/da/panel_region_debug.xml b/indra/newview/skins/default/xui/da/panel_region_debug.xml
index 08e2d1e263..08e2d1e263 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_region_debug.xml
+++ b/indra/newview/skins/default/xui/da/panel_region_debug.xml
diff --git a/indra/newview/skins/default/xui/da/panel_region_estate.xml b/indra/newview/skins/default/xui/da/panel_region_estate.xml
index 65948ce481..65948ce481 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_region_estate.xml
+++ b/indra/newview/skins/default/xui/da/panel_region_estate.xml
diff --git a/indra/newview/skins/default/xui/da/panel_region_general.xml b/indra/newview/skins/default/xui/da/panel_region_general.xml
index 667c88c5b1..667c88c5b1 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_region_general.xml
+++ b/indra/newview/skins/default/xui/da/panel_region_general.xml
diff --git a/indra/newview/skins/default/xui/da/panel_region_terrain.xml b/indra/newview/skins/default/xui/da/panel_region_terrain.xml
index 14ef0060b1..14ef0060b1 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_region_terrain.xml
+++ b/indra/newview/skins/default/xui/da/panel_region_terrain.xml
diff --git a/indra/newview/skins/default/xui/da/panel_region_texture.xml b/indra/newview/skins/default/xui/da/panel_region_texture.xml
index 45946fd222..45946fd222 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_region_texture.xml
+++ b/indra/newview/skins/default/xui/da/panel_region_texture.xml
diff --git a/indra/newview/skins/default/xui/da/panel_script_ed.xml b/indra/newview/skins/default/xui/da/panel_script_ed.xml
index 3dec4bf101..3dec4bf101 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_script_ed.xml
+++ b/indra/newview/skins/default/xui/da/panel_script_ed.xml
diff --git a/indra/newview/skins/default/xui/da/panel_script_limits_my_avatar.xml b/indra/newview/skins/default/xui/da/panel_script_limits_my_avatar.xml
index 821c82ccda..821c82ccda 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_script_limits_my_avatar.xml
+++ b/indra/newview/skins/default/xui/da/panel_script_limits_my_avatar.xml
diff --git a/indra/newview/skins/default/xui/da/panel_script_limits_region_memory.xml b/indra/newview/skins/default/xui/da/panel_script_limits_region_memory.xml
index 91fc76dbb4..91fc76dbb4 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_script_limits_region_memory.xml
+++ b/indra/newview/skins/default/xui/da/panel_script_limits_region_memory.xml
diff --git a/indra/newview/skins/default/xui/da/panel_scrolling_param.xml b/indra/newview/skins/default/xui/da/panel_scrolling_param.xml
index 99f61b938b..99f61b938b 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_scrolling_param.xml
+++ b/indra/newview/skins/default/xui/da/panel_scrolling_param.xml
diff --git a/indra/newview/skins/default/xui/da/panel_scrolling_param_base.xml b/indra/newview/skins/default/xui/da/panel_scrolling_param_base.xml
index fa659040ea..fa659040ea 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_scrolling_param_base.xml
+++ b/indra/newview/skins/default/xui/da/panel_scrolling_param_base.xml
diff --git a/indra/newview/skins/default/xui/da/panel_side_tray.xml b/indra/newview/skins/default/xui/da/panel_side_tray.xml
index 66c3e69904..66c3e69904 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_side_tray.xml
+++ b/indra/newview/skins/default/xui/da/panel_side_tray.xml
diff --git a/indra/newview/skins/default/xui/da/panel_side_tray_tab_caption.xml b/indra/newview/skins/default/xui/da/panel_side_tray_tab_caption.xml
index ce3a1d8b4e..ce3a1d8b4e 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_side_tray_tab_caption.xml
+++ b/indra/newview/skins/default/xui/da/panel_side_tray_tab_caption.xml
diff --git a/indra/newview/skins/default/xui/da/panel_sound_devices.xml b/indra/newview/skins/default/xui/da/panel_sound_devices.xml
index 27b7666a1f..27b7666a1f 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_sound_devices.xml
+++ b/indra/newview/skins/default/xui/da/panel_sound_devices.xml
diff --git a/indra/newview/skins/default/xui/da/panel_stand_stop_flying.xml b/indra/newview/skins/default/xui/da/panel_stand_stop_flying.xml
index f25639d56f..f25639d56f 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_stand_stop_flying.xml
+++ b/indra/newview/skins/default/xui/da/panel_stand_stop_flying.xml
diff --git a/indra/newview/skins/default/xui/da/panel_status_bar.xml b/indra/newview/skins/default/xui/da/panel_status_bar.xml
index 6e7bdfc188..6e7bdfc188 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_status_bar.xml
+++ b/indra/newview/skins/default/xui/da/panel_status_bar.xml
diff --git a/indra/newview/skins/default/xui/da/panel_teleport_history.xml b/indra/newview/skins/default/xui/da/panel_teleport_history.xml
index e6e78028f5..e6e78028f5 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_teleport_history.xml
+++ b/indra/newview/skins/default/xui/da/panel_teleport_history.xml
diff --git a/indra/newview/skins/default/xui/da/panel_teleport_history_item.xml b/indra/newview/skins/default/xui/da/panel_teleport_history_item.xml
index 8148588c86..8148588c86 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_teleport_history_item.xml
+++ b/indra/newview/skins/default/xui/da/panel_teleport_history_item.xml
diff --git a/indra/newview/skins/default/xui/da/panel_voice_effect.xml b/indra/newview/skins/default/xui/da/panel_voice_effect.xml
index 50f561ec7f..50f561ec7f 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_voice_effect.xml
+++ b/indra/newview/skins/default/xui/da/panel_voice_effect.xml
diff --git a/indra/newview/skins/default/xui/da/panel_world_map.xml b/indra/newview/skins/default/xui/da/panel_world_map.xml
index 138b922df1..138b922df1 100644..100755
--- a/indra/newview/skins/default/xui/da/panel_world_map.xml
+++ b/indra/newview/skins/default/xui/da/panel_world_map.xml
diff --git a/indra/newview/skins/default/xui/da/role_actions.xml b/indra/newview/skins/default/xui/da/role_actions.xml
index 7e581200a5..7e581200a5 100644..100755
--- a/indra/newview/skins/default/xui/da/role_actions.xml
+++ b/indra/newview/skins/default/xui/da/role_actions.xml
diff --git a/indra/newview/skins/default/xui/da/sidepanel_appearance.xml b/indra/newview/skins/default/xui/da/sidepanel_appearance.xml
index c5caefe070..c5caefe070 100644..100755
--- a/indra/newview/skins/default/xui/da/sidepanel_appearance.xml
+++ b/indra/newview/skins/default/xui/da/sidepanel_appearance.xml
diff --git a/indra/newview/skins/default/xui/da/sidepanel_inventory.xml b/indra/newview/skins/default/xui/da/sidepanel_inventory.xml
index b3293b981e..b3293b981e 100644..100755
--- a/indra/newview/skins/default/xui/da/sidepanel_inventory.xml
+++ b/indra/newview/skins/default/xui/da/sidepanel_inventory.xml
diff --git a/indra/newview/skins/default/xui/da/sidepanel_item_info.xml b/indra/newview/skins/default/xui/da/sidepanel_item_info.xml
index d52845160b..d52845160b 100644..100755
--- a/indra/newview/skins/default/xui/da/sidepanel_item_info.xml
+++ b/indra/newview/skins/default/xui/da/sidepanel_item_info.xml
diff --git a/indra/newview/skins/default/xui/da/sidepanel_task_info.xml b/indra/newview/skins/default/xui/da/sidepanel_task_info.xml
index f80d5aeb15..f80d5aeb15 100644..100755
--- a/indra/newview/skins/default/xui/da/sidepanel_task_info.xml
+++ b/indra/newview/skins/default/xui/da/sidepanel_task_info.xml
diff --git a/indra/newview/skins/default/xui/da/strings.xml b/indra/newview/skins/default/xui/da/strings.xml
index 11d100eeff..11d100eeff 100644..100755
--- a/indra/newview/skins/default/xui/da/strings.xml
+++ b/indra/newview/skins/default/xui/da/strings.xml
diff --git a/indra/newview/skins/default/xui/da/teleport_strings.xml b/indra/newview/skins/default/xui/da/teleport_strings.xml
index 0d89fae986..0d89fae986 100644..100755
--- a/indra/newview/skins/default/xui/da/teleport_strings.xml
+++ b/indra/newview/skins/default/xui/da/teleport_strings.xml
diff --git a/indra/newview/skins/default/xui/da/xui_version.xml b/indra/newview/skins/default/xui/da/xui_version.xml
index 0e777751d3..0e777751d3 100644..100755
--- a/indra/newview/skins/default/xui/da/xui_version.xml
+++ b/indra/newview/skins/default/xui/da/xui_version.xml
diff --git a/indra/newview/skins/default/xui/de/floater_about.xml b/indra/newview/skins/default/xui/de/floater_about.xml
index b4c28daac9..bc0eae7c5d 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_about.xml
+++ b/indra/newview/skins/default/xui/de/floater_about.xml
@@ -8,7 +8,9 @@
Kompiliert mit [COMPILER] version [COMPILER_VERSION]
</floater.string>
<floater.string name="AboutPosition">
- Sie befinden sich in [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1] in [REGION] auf &lt;nolink&gt;[HOSTNAME]&lt;/nolink&gt; ([HOSTIP])
+ Sie befinden sich an [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] in [REGION] auf &lt;nolink&gt;[HOSTNAME]&lt;/nolink&gt; ([HOSTIP])
+SLURL: &lt;nolink&gt;[SLURL]&lt;/nolink&gt;
+(globale Koordinaten [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1])
[SERVER_VERSION]
[SERVER_RELEASE_NOTES_URL]
</floater.string>
@@ -66,27 +68,26 @@ Voice-Serverversion: [VOICE_VERSION]
</panel>
<panel label="Lizenzen" name="licenses_panel">
<text_editor name="credits_editor">
- 3Dconnexion SDK Copyright (C) 1992-2007 3Dconnexion.
- APR Copyright (C) 2000-2004 The Apache Software Foundation.
- Collada DOM Copyright 2005 Sony Computer Entertainment Inc.
- cURL Copyright (C) 1996-2002, Daniel Stenberg (daniel@haxx.se).
+ 3Dconnexion SDK Copyright (C) 1992-2009 3Dconnexion.
+ APR Copyright (C) 2011 The Apache Software Foundation
+ Collada DOM Copyright 2006 Sony Computer Entertainment Inc.
+ cURL Copyright (C) 1996-2010, Daniel Stenberg (daniel@haxx.se).
DBus/dbus-glib Copyright (C) 2002, 2003 CodeFactory AB / Copyright (C) 2003, 2004 Red Hat, Inc.
expat Copyright (C) 1998, 1999, 2000 Thai Open Source Software Center Ltd.
- FreeType Copyright (C) 1996-2002, The FreeType Project (www.freetype.org).
+ FreeType Copyright (C) 1996-2002, 2006 David Turner, Robert Wilhelm und Werner Lemberg.
GL Copyright (C) 1999-2004 Brian Paul.
GLOD Copyright (C) 2003-04 Jonathan Cohen, Nat Duca, Chris Niski, Johns Hopkins University sowie David Luebke, Brenden Schubert, University of Virginia.
google-perftools Copyright (c) 2005, Google Inc.
Havok.com(TM) Copyright (C) 1999-2001, Telekinesys Research Limited.
jpeg2000 Copyright (C) 2001, David Taubman, The University of New South Wales (UNSW).
jpeglib Copyright (C) 1991-1998, Thomas G. Lane.
- ogg/vorbis Copyright (C) 2001, Xiphophorus.
- OpenSSL Copyright (C) 1998-2002 The OpenSSL Project.
- PCRE Copyright (c) 1997-2008 University of Cambridge.
+ ogg/vorbis Copyright (C) 2002, Xiphophorus.
+ OpenSSL Copyright (C) 1998-2008 The OpenSSL Project.
+ PCRE Copyright (c) 1997-2012 University of Cambridge.
SDL Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga.
SSLeay Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com).
xmlrpc-epi Copyright (C) 2000 Epinions, Inc.
- zlib Copyright (C) 1995-2002 Jean-loup Gailly und Mark Adler.
- google-perftools Copyright (c) 2005, Google Inc.
+ zlib Copyright (C) 1995-2012 Jean-loup Gailly und Mark Adler.
Second Life Viewer verwendet Havok (TM) Physics. (c)Copyright 1999-2010 Havok.com Inc. (und Lizenzgeber). Alle Rechte vorbehalten. Details siehe www.havok.com.
diff --git a/indra/newview/skins/default/xui/de/floater_about_land.xml b/indra/newview/skins/default/xui/de/floater_about_land.xml
index 9e330f9766..44922fbe78 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/de/floater_about_land.xml
@@ -463,7 +463,7 @@ Nur große Parzellen können in der Suche aufgeführt werden.
Zugang nur Einwohnern gestatten, die:
</text>
<check_box label="Zahlungsinformationen hinterlegt haben [ESTATE_PAYMENT_LIMIT]" name="limit_payment" tool_tip="Um diese Parzelle besuchen zu können, müssen Einwohner Zahlungsinformationen hinterlegt haben. Weitere Informationen finden Sie auf [SUPPORT_SITE]."/>
- <check_box label="ihr Alter bestätigt haben [ESTATE_AGE_LIMIT]" name="limit_age_verified" tool_tip="Um diese Parzelle besuchen zu können, müssen Einwohner ihr Alter bestätigt haben. Weitere Informationen finden Sie auf [SUPPORT_SITE]."/>
+ <check_box label="Sind mindestens 18 Jahre alt [ESTATE_AGE_LIMIT]" name="limit_age_verified" tool_tip="Nur Einwohner, die mindestens 18 Jahre alt sind, können diese Parzelle betreten. Weitere Informationen finden Sie unter [SUPPORT_SITE]."/>
<check_box label="Gruppenzugang erlauben: [GROUP]" name="GroupCheck" tool_tip="Gruppe im Register „Allgemein“ festlegen."/>
<check_box label="Pässe verkaufen an:" name="PassCheck" tool_tip="Ermöglicht befristeten Zugang zu dieser Parzelle"/>
<combo_box name="pass_combo">
diff --git a/indra/newview/skins/default/xui/de/floater_activeim.xml b/indra/newview/skins/default/xui/de/floater_activeim.xml
index 416e31b2d6..416e31b2d6 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_activeim.xml
+++ b/indra/newview/skins/default/xui/de/floater_activeim.xml
diff --git a/indra/newview/skins/default/xui/de/floater_animation_anim_preview.xml b/indra/newview/skins/default/xui/de/floater_animation_anim_preview.xml
index 3dc554b120..3dc554b120 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_animation_anim_preview.xml
+++ b/indra/newview/skins/default/xui/de/floater_animation_anim_preview.xml
diff --git a/indra/newview/skins/default/xui/de/floater_animation_bvh_preview.xml b/indra/newview/skins/default/xui/de/floater_animation_bvh_preview.xml
index 9a6f5e0166..9a6f5e0166 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_animation_bvh_preview.xml
+++ b/indra/newview/skins/default/xui/de/floater_animation_bvh_preview.xml
diff --git a/indra/newview/skins/default/xui/de/floater_animation_preview.xml b/indra/newview/skins/default/xui/de/floater_animation_preview.xml
deleted file mode 100644
index 82a4a51d07..0000000000
--- a/indra/newview/skins/default/xui/de/floater_animation_preview.xml
+++ /dev/null
@@ -1,188 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Animation Preview" title="">
- <floater.string name="failed_to_initialize">
- Bewegung konnte nicht initialisiert werden
- </floater.string>
- <floater.string name="anim_too_long">
- Animationsdatei ist [LENGTH] Sekunden lang.
-
-Maximal erlaubt sind [MAX_LENGTH] Sekunden.
- </floater.string>
- <floater.string name="failed_file_read">
- Animationsdatei konnte nicht gelesen werden.
-
-[STATUS]
- </floater.string>
- <floater.string name="E_ST_OK">
- OK
- </floater.string>
- <floater.string name="E_ST_EOF">
- Unvollständige Datei
- </floater.string>
- <floater.string name="E_ST_NO_CONSTRAINT">
- Constraint-Definition kann nicht gelesen werden.
- </floater.string>
- <floater.string name="E_ST_NO_FILE">
- BVH-Datei kann nicht geöffnet werden
- </floater.string>
- <floater.string name="E_ST_NO_HIER">
- Ungültiger HIERARCHY-Titel.
- </floater.string>
- <floater.string name="E_ST_NO_JOINT">
- ROOT oder JOINT nicht gefunden.
- </floater.string>
- <floater.string name="E_ST_NO_NAME">
- JOINT-Name nicht erfasst.
- </floater.string>
- <floater.string name="E_ST_NO_OFFSET">
- VERSATZ nicht gefunden.
- </floater.string>
- <floater.string name="E_ST_NO_CHANNELS">
- CHANNELS nicht gefunden.
- </floater.string>
- <floater.string name="E_ST_NO_ROTATION">
- Kann Rotations-Reihenfolge nicht erfassen.
- </floater.string>
- <floater.string name="E_ST_NO_AXIS">
- Kann Rotations-Achse nicht erfassen.
- </floater.string>
- <floater.string name="E_ST_NO_MOTION">
- MOTION nicht gefunden.
- </floater.string>
- <floater.string name="E_ST_NO_FRAMES">
- Anzahl der Bilder kann nicht erfasst werden.
- </floater.string>
- <floater.string name="E_ST_NO_FRAME_TIME">
- Bildzeit kann nicht erfasst werden.
- </floater.string>
- <floater.string name="E_ST_NO_POS">
- Positions-Werte können nicht erfasst werden.
- </floater.string>
- <floater.string name="E_ST_NO_ROT">
- Kann Rotations-Werte nicht erfassen.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_FILE">
- Datei kann nicht geöffnet werden
- </floater.string>
- <floater.string name="E_ST_NO_XLT_HEADER">
- Ãœbersetzungstitel kann nicht gelesen werden.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_NAME">
- Übersetzungsnamen können nicht geladen werden.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_IGNORE">
- Ignorier-Wert kann nicht gelesen werden.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_RELATIVE">
- Ãœbersetzungs-Wert kann nicht gelesen werden.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_OUTNAME">
- Outname-Wert kann nicht gelesen werden.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_MATRIX">
- Ãœbersetzungsmatrix kann nicht geladen werden.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_MERGECHILD">
- Mergechild-Name nicht erfasst.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_MERGEPARENT">
- Mergeparent-Name nicht erfasst.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_PRIORITY">
- Prioritätswert kann nicht erfasst werden.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_LOOP">
- Loop-Wert kann nicht erfasst werden.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_EASEIN">
- Easeln-Wert kann nicht erfasst werden.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_EASEOUT">
- easeOut-Wert kann nicht erfasst werden.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_HAND">
- Hand-Morph-Wert nicht erfasst.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_EMOTE">
- Emote-Name kann nicht gelesen werden.
- </floater.string>
- <floater.string name="E_ST_BAD_ROOT">
- Falscher Root-Joint-Name, &quot;hip&quot; verwenden.
- </floater.string>
- <text name="name_label">
- Name:
- </text>
- <line_editor name="name_form"/>
- <text name="description_label">
- Beschreibung:
- </text>
- <spinner label="Priorität" name="priority" tool_tip="Steuert, welche Animationen von dieser Animation überschrieben werden können"/>
- <check_box bottom_delta="-18" label="Schleife" name="loop_check" tool_tip="Erzeugt eine Animationsschleife"/>
- <spinner label="In (%)" name="loop_in_point" tool_tip="Anfang einer Animationsschleife festlegen"/>
- <spinner label="Aus (%)" name="loop_out_point" tool_tip="Ende einer Animationsschleife festlegen"/>
- <text name="hand_label">
- Handhaltung
- </text>
- <combo_box label="" name="hand_pose_combo" tool_tip="Steuert während der Animation die Bewegung der Hände">
- <combo_box.item label="Dehnen" name="Spread"/>
- <combo_box.item label="Entspannt" name="Relaxed"/>
- <combo_box.item label="Beide zeigen" name="PointBoth"/>
- <combo_box.item label="Faust" name="Fist"/>
- <combo_box.item label="Links entspannt" name="RelaxedLeft"/>
- <combo_box.item label="Nach links zeigen" name="PointLeft"/>
- <combo_box.item label="Linke Faust" name="FistLeft"/>
- <combo_box.item label="Rechts entspannt" name="RelaxedRight"/>
- <combo_box.item label="Nach rechts zeigen" name="PointRight"/>
- <combo_box.item label="Rechte Faust" name="FistRight"/>
- <combo_box.item label="Rechts salutieren" name="SaluteRight"/>
- <combo_box.item label="Tippt" name="Typing"/>
- <combo_box.item label="Friedensrecht" name="PeaceRight"/>
- </combo_box>
- <text name="emote_label">
- Ausdruck
- </text>
- <combo_box label="" name="emote_combo" tool_tip="Steuert Gesichtsregungen während der Animation">
- <item label="(Keiner)" name="[None]" value=""/>
- <item label="Aaaaah" name="Aaaaah" value="Aaaaah"/>
- <item label="Ängstlich" name="Afraid" value="Ängstlich"/>
- <item label="Verärgert" name="Angry" value="Verärgert"/>
- <item label="Grinst" name="BigSmile" value="Grinsend"/>
- <item label="Gelangweilt" name="Bored" value="Gelangweilt"/>
- <item label="Weinen" name="Cry" value="Weinen"/>
- <item label="Verachten" name="Disdain" value="Verachten"/>
- <item label="Verlegen" name="Embarrassed" value="Verlegen"/>
- <item label="Stirnrunzeln" name="Frown" value="Stirnrunzeln"/>
- <item label="Küssen" name="Kiss" value="Küssen"/>
- <item label="Lachen" name="Laugh" value="Lachen"/>
- <item label="Bäääh" name="Plllppt" value="Bäääh"/>
- <item label="Angewidert" name="Repulsed" value="Angewidert"/>
- <item label="Traurig" name="Sad" value="Traurig"/>
- <item label="Schulterzucken" name="Shrug" value="Schulterzucken"/>
- <item label="Lächeln" name="Smile" value="Lächeln"/>
- <item label="Ãœberraschung" name="Surprise" value="Ãœberraschung"/>
- <item label="Zwinkern" name="Wink" value="Zwinkern"/>
- <item label="Sorgenvoll" name="Worry" value="Sorgenvoll"/>
- </combo_box>
- <text name="preview_label" width="97">
- Vorschau während:
- </text>
- <combo_box label="" left_delta="107" name="preview_base_anim" tool_tip="Hiermit können Sie das Verhalten Ihres Avatars testen, während Ihr Avatar normale Bewegungen ausführt.">
- <item label="Stehend" name="Standing" value="Stehend"/>
- <item label="Geht" name="Walking" value="Gehend"/>
- <item label="Sitzt" name="Sitting" value="Sitzend"/>
- <item label="Fliegen" name="Flying" value="Fliegen"/>
- </combo_box>
- <spinner label="Eingang glätten (s)" label_width="105" name="ease_in_time" tool_tip="Einblendungsgeschwindigkeit von Animationen (in Sekunden)" width="175"/>
- <spinner bottom_delta="-20" label="Ausgang glätten (s)" label_width="105" left="10" name="ease_out_time" tool_tip="Ausblendegeschwindigkeit von Animationen (in Sekunden)" width="175"/>
- <button bottom_delta="-32" label="" name="play_btn" tool_tip="Ihre Animation abspielen"/>
- <button name="pause_btn" tool_tip="Ihre Animation pausieren"/>
- <button label="" name="stop_btn" tool_tip="Animation anhalten"/>
- <slider label="" name="playback_slider"/>
- <text name="bad_animation_text">
- Animationsdatei konnte nicht gelesen werden.
-
-Wir empfehlen exportierte BVH-Dateien aus Poser 4.
- </text>
- <button label="Hochladen ([AMOUNT] L$)" name="ok_btn" width="160"/>
- <button label="Abbrechen" left="180" name="cancel_btn" width="88"/>
-</floater>
diff --git a/indra/newview/skins/default/xui/de/floater_auction.xml b/indra/newview/skins/default/xui/de/floater_auction.xml
index 8ededff319..8ededff319 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_auction.xml
+++ b/indra/newview/skins/default/xui/de/floater_auction.xml
diff --git a/indra/newview/skins/default/xui/de/floater_autoreplace.xml b/indra/newview/skins/default/xui/de/floater_autoreplace.xml
new file mode 100755
index 0000000000..0c774990ef
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/floater_autoreplace.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="autoreplace_floater" title="Einstellungen für automatische Ersetzung...">
+ <check_box label="Automatische Ersetzung aktivieren..." name="autoreplace_enable" tool_tip="Eines oder mehrere Schlüsselwörter bei der Eingabe von Chat-Text durch die entsprechende Ersetzung substituieren"/>
+ <button label="Liste importieren..." name="autoreplace_import_list" tool_tip="Exportierte Liste aus einer Datei laden."/>
+ <button label="Liste exportieren..." name="autoreplace_export_list" tool_tip="Ausgewählte Liste zur Weitergabe in einer Datei speichern."/>
+ <button label="Neue Liste..." name="autoreplace_new_list" tool_tip="Neue Liste erstellen."/>
+ <button label="Liste löschen" name="autoreplace_delete_list" tool_tip="Ausgewählte Liste löschen."/>
+ <button name="autoreplace_list_up" tool_tip="Dieser Liste eine höhere Priorität einräumen."/>
+ <button name="autoreplace_list_down" tool_tip="Dieser Liste eine niedrigere Priorität einräumen."/>
+ <scroll_list name="autoreplace_list_replacements">
+ <scroll_list.columns label="Schlüsselwort" name="keyword"/>
+ <scroll_list.columns label="Ersetzung" name="replacement"/>
+ </scroll_list>
+ <button label="Hinzufügen..." name="autoreplace_add_entry"/>
+ <button label="Entfernen" name="autoreplace_delete_entry"/>
+ <button label="Eintrag speichern" name="autoreplace_save_entry" tool_tip="Diesen Eintrag speichern."/>
+ <button label="Änderungen speichern" name="autoreplace_save_changes" tool_tip="Alle Änderungen speichern."/>
+ <button label="Abbrechen" name="autoreplace_cancel" tool_tip="Alle Änderungen löschen."/>
+</floater>
+<!--
+ <text
+ top_pad="10"
+ left="10"
+ height="16"
+ width="260"
+ follows="left|top"
+ halign="center"
+ mouse_opaque="true"
+ name="autoreplace_text2">
+ Entries
+ </text>
+-->
diff --git a/indra/newview/skins/default/xui/de/floater_avatar.xml b/indra/newview/skins/default/xui/de/floater_avatar.xml
index ba0dd54d96..ba0dd54d96 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_avatar.xml
+++ b/indra/newview/skins/default/xui/de/floater_avatar.xml
diff --git a/indra/newview/skins/default/xui/de/floater_avatar_picker.xml b/indra/newview/skins/default/xui/de/floater_avatar_picker.xml
index f66b87b76c..f66b87b76c 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_avatar_picker.xml
+++ b/indra/newview/skins/default/xui/de/floater_avatar_picker.xml
diff --git a/indra/newview/skins/default/xui/de/floater_avatar_textures.xml b/indra/newview/skins/default/xui/de/floater_avatar_textures.xml
index 8235eacde0..8235eacde0 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_avatar_textures.xml
+++ b/indra/newview/skins/default/xui/de/floater_avatar_textures.xml
diff --git a/indra/newview/skins/default/xui/de/floater_beacons.xml b/indra/newview/skins/default/xui/de/floater_beacons.xml
index 1a052bd814..1a052bd814 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_beacons.xml
+++ b/indra/newview/skins/default/xui/de/floater_beacons.xml
diff --git a/indra/newview/skins/default/xui/de/floater_build_options.xml b/indra/newview/skins/default/xui/de/floater_build_options.xml
index 939fd5dee4..939fd5dee4 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_build_options.xml
+++ b/indra/newview/skins/default/xui/de/floater_build_options.xml
diff --git a/indra/newview/skins/default/xui/de/floater_bulk_perms.xml b/indra/newview/skins/default/xui/de/floater_bulk_perms.xml
index 8f99fc933c..27a74c874e 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_bulk_perms.xml
+++ b/indra/newview/skins/default/xui/de/floater_bulk_perms.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floaterbulkperms" title="BERECHTIGUNGEN BEARBEITEN">
+<floater name="floaterbulkperms" title="INHALTSBERECHTIGUNGEN ÄNDERN">
<floater.string name="nothing_to_modify_text">
Auswahl enthält keinen Inhalt, der bearbeitet werden kann.
</floater.string>
@@ -33,7 +33,7 @@
<button label="√ Alle" label_selected="Alle" name="check_all"/>
<button label="Löschen" label_selected="Keine" name="check_none"/>
<text name="newperms">
- Neue Inhalts-Berechtigungen
+ Inhaltsberechtigungen ändern in
</text>
<text name="GroupLabel">
Gruppe:
@@ -49,6 +49,7 @@
<check_box label="Bearbeiten" name="next_owner_modify"/>
<check_box label="Kopieren" name="next_owner_copy"/>
<check_box initial_value="true" label="Transferieren" name="next_owner_transfer" tool_tip="Nächster Eigentümer kann dieses Objekt weitergeben oder -verkaufen"/>
- <button label="OK" name="apply"/>
+ <button label="OK" name="ok"/>
+ <button label="Anwenden" name="apply"/>
<button label="Abbrechen" name="close"/>
</floater>
diff --git a/indra/newview/skins/default/xui/de/floater_bumps.xml b/indra/newview/skins/default/xui/de/floater_bumps.xml
index 5d02511ab1..5d02511ab1 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_bumps.xml
+++ b/indra/newview/skins/default/xui/de/floater_bumps.xml
diff --git a/indra/newview/skins/default/xui/de/floater_buy_contents.xml b/indra/newview/skins/default/xui/de/floater_buy_contents.xml
index bd6ace6bda..bd6ace6bda 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_buy_contents.xml
+++ b/indra/newview/skins/default/xui/de/floater_buy_contents.xml
diff --git a/indra/newview/skins/default/xui/de/floater_buy_currency.xml b/indra/newview/skins/default/xui/de/floater_buy_currency.xml
index 65926c088c..65926c088c 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_buy_currency.xml
+++ b/indra/newview/skins/default/xui/de/floater_buy_currency.xml
diff --git a/indra/newview/skins/default/xui/de/floater_buy_currency_html.xml b/indra/newview/skins/default/xui/de/floater_buy_currency_html.xml
index 38d3bdd77f..38d3bdd77f 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_buy_currency_html.xml
+++ b/indra/newview/skins/default/xui/de/floater_buy_currency_html.xml
diff --git a/indra/newview/skins/default/xui/de/floater_buy_land.xml b/indra/newview/skins/default/xui/de/floater_buy_land.xml
index ca4ee8981b..ca4ee8981b 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_buy_land.xml
+++ b/indra/newview/skins/default/xui/de/floater_buy_land.xml
diff --git a/indra/newview/skins/default/xui/de/floater_buy_object.xml b/indra/newview/skins/default/xui/de/floater_buy_object.xml
index 29b49f57b3..29b49f57b3 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_buy_object.xml
+++ b/indra/newview/skins/default/xui/de/floater_buy_object.xml
diff --git a/indra/newview/skins/default/xui/de/floater_camera.xml b/indra/newview/skins/default/xui/de/floater_camera.xml
index 163ef87d8c..163ef87d8c 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_camera.xml
+++ b/indra/newview/skins/default/xui/de/floater_camera.xml
diff --git a/indra/newview/skins/default/xui/de/floater_chat_bar.xml b/indra/newview/skins/default/xui/de/floater_chat_bar.xml
index 2464a55665..ab77d4dae5 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_chat_bar.xml
+++ b/indra/newview/skins/default/xui/de/floater_chat_bar.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="chat_bar" title="CHAT IN DER NÄHE">
+<floater name="nearby_chat" title="CHAT IN DER NÄHE">
<panel name="bottom_panel">
<line_editor label="Zum Chatten hier klicken." name="chat_box" tool_tip="Eingabetaste zum Sprechen, Strg+Eingabe zum Rufen"/>
<button name="show_nearby_chat" tool_tip="Chatprotokoll in der Nähe ein-/ausblenden"/>
diff --git a/indra/newview/skins/default/xui/de/floater_choose_group.xml b/indra/newview/skins/default/xui/de/floater_choose_group.xml
index 3d76b645fe..3d76b645fe 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_choose_group.xml
+++ b/indra/newview/skins/default/xui/de/floater_choose_group.xml
diff --git a/indra/newview/skins/default/xui/de/floater_color_picker.xml b/indra/newview/skins/default/xui/de/floater_color_picker.xml
index 0fe154b531..0fe154b531 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_color_picker.xml
+++ b/indra/newview/skins/default/xui/de/floater_color_picker.xml
diff --git a/indra/newview/skins/default/xui/de/floater_conversation_log.xml b/indra/newview/skins/default/xui/de/floater_conversation_log.xml
new file mode 100644
index 0000000000..19620a0fc9
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/floater_conversation_log.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="floater_conversation_log" title="UNTERHALTUNGSPROTOKOLL">
+ <panel name="buttons_panel">
+ <filter_editor label="Nach Personen filtern" name="people_filter_input"/>
+ <menu_button name="conversation_view_btn" tool_tip="Anzeige-/Sortieroptionen"/>
+ <menu_button name="conversations_gear_btn" tool_tip="Aktionen für ausgewählte Person/Gruppe"/>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/de/floater_conversation_preview.xml b/indra/newview/skins/default/xui/de/floater_conversation_preview.xml
new file mode 100644
index 0000000000..010ad19076
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/floater_conversation_preview.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="preview_conversation" title="UNTERHALTUNG:">
+ <floater.string name="Title">
+ UNTERHALTUNG: [NAME]
+ </floater.string>
+ <text name="page_label" value="Seite"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/de/floater_critical.xml b/indra/newview/skins/default/xui/de/floater_critical.xml
index 0b147926dd..0b147926dd 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_critical.xml
+++ b/indra/newview/skins/default/xui/de/floater_critical.xml
diff --git a/indra/newview/skins/default/xui/de/floater_delete_env_preset.xml b/indra/newview/skins/default/xui/de/floater_delete_env_preset.xml
index cc14ce640d..cc14ce640d 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_delete_env_preset.xml
+++ b/indra/newview/skins/default/xui/de/floater_delete_env_preset.xml
diff --git a/indra/newview/skins/default/xui/de/floater_destinations.xml b/indra/newview/skins/default/xui/de/floater_destinations.xml
index 57881488fd..57881488fd 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_destinations.xml
+++ b/indra/newview/skins/default/xui/de/floater_destinations.xml
diff --git a/indra/newview/skins/default/xui/de/floater_display_name.xml b/indra/newview/skins/default/xui/de/floater_display_name.xml
index 4c2914fccb..4c2914fccb 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_display_name.xml
+++ b/indra/newview/skins/default/xui/de/floater_display_name.xml
diff --git a/indra/newview/skins/default/xui/de/floater_edit_day_cycle.xml b/indra/newview/skins/default/xui/de/floater_edit_day_cycle.xml
index 8b29428c24..8b29428c24 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_edit_day_cycle.xml
+++ b/indra/newview/skins/default/xui/de/floater_edit_day_cycle.xml
diff --git a/indra/newview/skins/default/xui/de/floater_edit_sky_preset.xml b/indra/newview/skins/default/xui/de/floater_edit_sky_preset.xml
index ea4c5f7ebc..ea4c5f7ebc 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_edit_sky_preset.xml
+++ b/indra/newview/skins/default/xui/de/floater_edit_sky_preset.xml
diff --git a/indra/newview/skins/default/xui/de/floater_edit_water_preset.xml b/indra/newview/skins/default/xui/de/floater_edit_water_preset.xml
index 9b9d5e7d77..9b9d5e7d77 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_edit_water_preset.xml
+++ b/indra/newview/skins/default/xui/de/floater_edit_water_preset.xml
diff --git a/indra/newview/skins/default/xui/de/floater_environment_settings.xml b/indra/newview/skins/default/xui/de/floater_environment_settings.xml
index 946416980a..946416980a 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_environment_settings.xml
+++ b/indra/newview/skins/default/xui/de/floater_environment_settings.xml
diff --git a/indra/newview/skins/default/xui/de/floater_event.xml b/indra/newview/skins/default/xui/de/floater_event.xml
index 5b3267d7c9..5b3267d7c9 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_event.xml
+++ b/indra/newview/skins/default/xui/de/floater_event.xml
diff --git a/indra/newview/skins/default/xui/de/floater_fast_timers.xml b/indra/newview/skins/default/xui/de/floater_fast_timers.xml
index e61e542688..e61e542688 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_fast_timers.xml
+++ b/indra/newview/skins/default/xui/de/floater_fast_timers.xml
diff --git a/indra/newview/skins/default/xui/de/floater_font_test.xml b/indra/newview/skins/default/xui/de/floater_font_test.xml
index 29357b8ee0..29357b8ee0 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_font_test.xml
+++ b/indra/newview/skins/default/xui/de/floater_font_test.xml
diff --git a/indra/newview/skins/default/xui/de/floater_gesture.xml b/indra/newview/skins/default/xui/de/floater_gesture.xml
index 7b35da8d5c..7b35da8d5c 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_gesture.xml
+++ b/indra/newview/skins/default/xui/de/floater_gesture.xml
diff --git a/indra/newview/skins/default/xui/de/floater_god_tools.xml b/indra/newview/skins/default/xui/de/floater_god_tools.xml
index 8cb1af9f7d..8cb1af9f7d 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_god_tools.xml
+++ b/indra/newview/skins/default/xui/de/floater_god_tools.xml
diff --git a/indra/newview/skins/default/xui/de/floater_goto_line.xml b/indra/newview/skins/default/xui/de/floater_goto_line.xml
new file mode 100644
index 0000000000..02550ec398
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/floater_goto_line.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="script goto" title="GEHE ZU ZEILE">
+ <button label="OK" label_selected="OK" name="goto_btn"/>
+ <text name="txt">
+ Gehe zu Zeile
+ </text>
+</floater>
diff --git a/indra/newview/skins/default/xui/de/floater_hardware_settings.xml b/indra/newview/skins/default/xui/de/floater_hardware_settings.xml
index ca081aafae..fd6c9a0875 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_hardware_settings.xml
+++ b/indra/newview/skins/default/xui/de/floater_hardware_settings.xml
@@ -25,6 +25,10 @@
VBO aktivieren:
</text>
<check_box initial_value="true" label="OpenGL Vertex-Buffer-Objekte aktivieren" name="vbo" tool_tip="Wenn Sie über moderne Grafikhardware verfügen, können Sie durch Aktivieren dieser Option die Geschwindigkeit verbessern. Bei alter Hardware sind die VBO oft schlecht implementiert, was zu Abstürzen führen kann, wenn diese Option aktiviert ist."/>
+ <text name="tc label">
+ S3TC aktivieren:
+ </text>
+ <check_box initial_value="true" label="Texturkomprimierung aktivieren (Neustart erforderlich)" name="texture compression" tool_tip="Komprimiert Texturen im Videospeicher, damit höher auflösende Texturen geladen werden können (leichte Beeinträchtigung der Farbqualität)."/>
<slider label="Texturen-Cache (MB):" name="GraphicsCardTextureMemory" tool_tip="Speicherplatz, der für Texturen zur Verfügung steht. In der Regel handelt es sich um Grafikkartenspeicher. Ein kleinerer Wert kann die Geschwindigkeit erhöhen, aber auch zu Texturunschärfen führen."/>
<spinner label="Nebeldistanzverhältnis:" name="fog"/>
<button label="OK" label_selected="OK" name="OK"/>
diff --git a/indra/newview/skins/default/xui/de/floater_help_browser.xml b/indra/newview/skins/default/xui/de/floater_help_browser.xml
index d55a3b0a26..d55a3b0a26 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_help_browser.xml
+++ b/indra/newview/skins/default/xui/de/floater_help_browser.xml
diff --git a/indra/newview/skins/default/xui/de/floater_how_to.xml b/indra/newview/skins/default/xui/de/floater_how_to.xml
index caea221f83..caea221f83 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_how_to.xml
+++ b/indra/newview/skins/default/xui/de/floater_how_to.xml
diff --git a/indra/newview/skins/default/xui/de/floater_hud.xml b/indra/newview/skins/default/xui/de/floater_hud.xml
index 8a10eccabe..8a10eccabe 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_hud.xml
+++ b/indra/newview/skins/default/xui/de/floater_hud.xml
diff --git a/indra/newview/skins/default/xui/de/floater_im_container.xml b/indra/newview/skins/default/xui/de/floater_im_container.xml
index 95eda97938..5bf916c8e9 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_im_container.xml
+++ b/indra/newview/skins/default/xui/de/floater_im_container.xml
@@ -1,2 +1,29 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<multi_floater name="floater_im_box" title="GESPRÄCHE"/>
+<multi_floater name="floater_im_box" title="GESPRÄCHE">
+ <string name="collapse_icon" value="Conv_toolbar_collapse"/>
+ <string name="expand_icon" value="Conv_toolbar_expand"/>
+ <layout_stack name="conversations_stack">
+ <layout_panel name="conversations_layout_panel">
+ <layout_stack name="conversations_pane_buttons_stack">
+ <layout_panel name="conversations_pane_buttons_expanded">
+ <menu_button name="sort_btn" tool_tip="Anzeige-/Sortieroptionen"/>
+ <button name="add_btn" tool_tip="Neue Unterhaltung starten"/>
+ <button name="speak_btn" tool_tip="Ãœber Ihr Mikrofon mit anderen sprechen"/>
+ </layout_panel>
+ <layout_panel name="conversations_pane_buttons_collapsed">
+ <button name="expand_collapse_btn" tool_tip="Diese Liste schließen/erweitern"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ <layout_panel name="messages_layout_panel">
+ <panel_container name="im_box_tab_container">
+ <panel name="stub_panel">
+ <button name="stub_collapse_btn" tool_tip="Dieses Fenster schließen"/>
+ <text name="stub_textbox">
+ Diese Unterhaltung erscheint in einem separaten Fenster. [secondlife:/// Zurückholen.]
+ </text>
+ </panel>
+ </panel_container>
+ </layout_panel>
+ </layout_stack>
+</multi_floater>
diff --git a/indra/newview/skins/default/xui/de/floater_im_session.xml b/indra/newview/skins/default/xui/de/floater_im_session.xml
index abaf275651..b07b74bf4a 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/de/floater_im_session.xml
@@ -1,8 +1,57 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="panel_im">
- <layout_stack name="im_panels">
- <layout_panel>
- <line_editor label="An" name="chat_editor"/>
- </layout_panel>
- </layout_stack>
+ <floater.string name="call_btn_start">
+ Conv_toolbar_open_call
+ </floater.string>
+ <floater.string name="call_btn_stop">
+ Conv_toolbar_hang_up
+ </floater.string>
+ <floater.string name="collapseline_icon" value="Conv_collapse_to_one_line"/>
+ <floater.string name="expandline_icon" value="Conv_expand_one_line"/>
+ <floater.string name="collapse_icon" value="Conv_toolbar_collapse"/>
+ <floater.string name="expand_icon" value="Conv_toolbar_expand"/>
+ <floater.string name="tear_off_icon" value="Conv_toolbar_arrow_ne"/>
+ <floater.string name="return_icon" value="Conv_toolbar_arrow_sw"/>
+ <floater.string name="participant_added" value="[NAME] wurde zur Unterhaltung eingeladen."/>
+ <floater.string name="multiple_participants_added" value="[NAME] wurden zur Unterhaltung eingeladen."/>
+ <floater.string name="tooltip_to_separate_window" value="Diese Unterhaltung in separates Fenster verschieben"/>
+ <floater.string name="tooltip_to_main_window" value="Diese Unterhaltung zurück ins Hauptfenster verschieben"/>
+ <floater.string name="start_call_button_tooltip" value="Voice-Verbindung öffnen"/>
+ <floater.string name="end_call_button_tooltip" value="Voice-Verbindung schließen"/>
+ <floater.string name="expcol_button_not_tearoff_tooltip" value="Dieses Fenster schließen"/>
+ <floater.string name="expcol_button_tearoff_and_expanded_tooltip" value="Teilnehmerliste schließen"/>
+ <floater.string name="expcol_button_tearoff_and_collapsed_tooltip" value="Teilnehmerliste erweitern"/>
+ <view name="contents_view">
+ <layout_stack name="main_stack">
+ <layout_panel name="toolbar_panel">
+ <menu_button name="view_options_btn" tool_tip="Anzeige-/Sortieroptionen"/>
+ <menu_button name="gear_btn" tool_tip="Aktionen für ausgewählte Person"/>
+ <button name="add_btn" tool_tip="Jemanden zu dieser Unterhaltung hinzufügen"/>
+ <button name="voice_call_btn" tool_tip="Voice-Verbindung öffnen"/>
+ <button name="close_btn" tool_tip="Diese Unterhaltung beenden"/>
+ <button name="expand_collapse_btn" tool_tip="Dieses Fenster schließen/erweitern"/>
+ </layout_panel>
+ <layout_panel name="body_panel">
+ <layout_stack name="im_panels">
+ <layout_panel name="right_part_holder">
+ <layout_stack name="translate_and_chat_stack">
+ <layout_panel name="translate_chat_checkbox_lp">
+ <check_box label="Chat übersetzen" name="translate_chat_checkbox"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ <layout_panel name="chat_layout_panel">
+ <layout_stack name="input_panels">
+ <layout_panel name="input_editor_layout_panel">
+ <chat_editor label="An" name="chat_editor"/>
+ </layout_panel>
+ <layout_panel name="input_button_layout_panel">
+ <button name="minz_btn" tool_tip="Nachrichtenfenster anzeigen/ausblenden"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
+ </view>
</floater>
diff --git a/indra/newview/skins/default/xui/de/floater_image_preview.xml b/indra/newview/skins/default/xui/de/floater_image_preview.xml
index d581c6051b..d581c6051b 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_image_preview.xml
+++ b/indra/newview/skins/default/xui/de/floater_image_preview.xml
diff --git a/indra/newview/skins/default/xui/de/floater_import_collada.xml b/indra/newview/skins/default/xui/de/floater_import_collada.xml
index 8b1313c7b5..8b1313c7b5 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_import_collada.xml
+++ b/indra/newview/skins/default/xui/de/floater_import_collada.xml
diff --git a/indra/newview/skins/default/xui/de/floater_incoming_call.xml b/indra/newview/skins/default/xui/de/floater_incoming_call.xml
index 213d9f54f5..f13842f479 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_incoming_call.xml
+++ b/indra/newview/skins/default/xui/de/floater_incoming_call.xml
@@ -10,7 +10,7 @@
Anonym
</floater.string>
<floater.string name="VoiceInviteP2P">
- ruft an.
+ ruft Sie an.
</floater.string>
<floater.string name="VoiceInviteAdHoc">
ist einem Voice-Konferenz-Chat beigetreten.
@@ -25,9 +25,9 @@
Möchten Sie [CURRENT_CHAT] verlassen und diesem Voice-Chat beitreten?
</floater.string>
<text name="question">
- Möchten Sie [CURRENT_CHAT] verlassen und diesem Voice-Chat beitreten?
+ Wenn Sie antworten, wird Ihre aktuelle Voice-Unterhaltung beendet.
</text>
- <button label="Akzeptieren" label_selected="Akzeptieren" name="Accept"/>
- <button label="Ablehnen" label_selected="Ablehnen" name="Reject"/>
- <button label="IM starten" name="Start IM"/>
+ <button label="Annehmen" label_selected="Annehmen" name="Accept"/>
+ <button label="Ignorieren" label_selected="Ignorieren" name="Reject"/>
+ <button label="Stattdessen IM öffnen" name="Start IM"/>
</floater>
diff --git a/indra/newview/skins/default/xui/de/floater_inspect.xml b/indra/newview/skins/default/xui/de/floater_inspect.xml
index da97ceb2d8..da97ceb2d8 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_inspect.xml
+++ b/indra/newview/skins/default/xui/de/floater_inspect.xml
diff --git a/indra/newview/skins/default/xui/de/floater_inventory.xml b/indra/newview/skins/default/xui/de/floater_inventory.xml
deleted file mode 100644
index d9b7c30fd2..0000000000
--- a/indra/newview/skins/default/xui/de/floater_inventory.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Inventory" title="MEIN INVENTAR">
- <floater.string name="Title">
- MEIN INVENTAR
- </floater.string>
- <floater.string name="TitleFetching">
- MEIN INVENTAR ([ITEM_COUNT] Objekte werden abgerufen...) [FILTER]
- </floater.string>
- <floater.string name="TitleCompleted">
- MEIN INVENTAR ([ITEM_COUNT] Objekte) [FILTER]
- </floater.string>
- <floater.string name="Fetched">
- Abgerufen
- </floater.string>
- <panel label="Inventar" name="Inventory Panel"/>
-</floater>
diff --git a/indra/newview/skins/default/xui/de/floater_inventory_item_properties.xml b/indra/newview/skins/default/xui/de/floater_inventory_item_properties.xml
index 7f48105460..7f48105460 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_inventory_item_properties.xml
+++ b/indra/newview/skins/default/xui/de/floater_inventory_item_properties.xml
diff --git a/indra/newview/skins/default/xui/de/floater_inventory_view_finder.xml b/indra/newview/skins/default/xui/de/floater_inventory_view_finder.xml
index d63426d684..d63426d684 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_inventory_view_finder.xml
+++ b/indra/newview/skins/default/xui/de/floater_inventory_view_finder.xml
diff --git a/indra/newview/skins/default/xui/de/floater_joystick.xml b/indra/newview/skins/default/xui/de/floater_joystick.xml
index 2efc11df29..2efc11df29 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_joystick.xml
+++ b/indra/newview/skins/default/xui/de/floater_joystick.xml
diff --git a/indra/newview/skins/default/xui/de/floater_lagmeter.xml b/indra/newview/skins/default/xui/de/floater_lagmeter.xml
index 45ff37c147..45ff37c147 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_lagmeter.xml
+++ b/indra/newview/skins/default/xui/de/floater_lagmeter.xml
diff --git a/indra/newview/skins/default/xui/de/floater_land_holdings.xml b/indra/newview/skins/default/xui/de/floater_land_holdings.xml
index 73559407a9..73559407a9 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_land_holdings.xml
+++ b/indra/newview/skins/default/xui/de/floater_land_holdings.xml
diff --git a/indra/newview/skins/default/xui/de/floater_live_lsleditor.xml b/indra/newview/skins/default/xui/de/floater_live_lsleditor.xml
index 3b42a8b741..3b42a8b741 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_live_lsleditor.xml
+++ b/indra/newview/skins/default/xui/de/floater_live_lsleditor.xml
diff --git a/indra/newview/skins/default/xui/de/floater_lsl_guide.xml b/indra/newview/skins/default/xui/de/floater_lsl_guide.xml
index 73c21edc67..73c21edc67 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_lsl_guide.xml
+++ b/indra/newview/skins/default/xui/de/floater_lsl_guide.xml
diff --git a/indra/newview/skins/default/xui/de/floater_map.xml b/indra/newview/skins/default/xui/de/floater_map.xml
index c4c42af66d..c4c42af66d 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_map.xml
+++ b/indra/newview/skins/default/xui/de/floater_map.xml
diff --git a/indra/newview/skins/default/xui/de/floater_media_browser.xml b/indra/newview/skins/default/xui/de/floater_media_browser.xml
index 2d438dfe21..2d438dfe21 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_media_browser.xml
+++ b/indra/newview/skins/default/xui/de/floater_media_browser.xml
diff --git a/indra/newview/skins/default/xui/de/floater_media_settings.xml b/indra/newview/skins/default/xui/de/floater_media_settings.xml
index 1b98ed7973..1b98ed7973 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_media_settings.xml
+++ b/indra/newview/skins/default/xui/de/floater_media_settings.xml
diff --git a/indra/newview/skins/default/xui/de/floater_mem_leaking.xml b/indra/newview/skins/default/xui/de/floater_mem_leaking.xml
index fdc9b950b6..fdc9b950b6 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_mem_leaking.xml
+++ b/indra/newview/skins/default/xui/de/floater_mem_leaking.xml
diff --git a/indra/newview/skins/default/xui/de/floater_merchant_outbox.xml b/indra/newview/skins/default/xui/de/floater_merchant_outbox.xml
index a412b530a4..a412b530a4 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_merchant_outbox.xml
+++ b/indra/newview/skins/default/xui/de/floater_merchant_outbox.xml
diff --git a/indra/newview/skins/default/xui/de/floater_model_preview.xml b/indra/newview/skins/default/xui/de/floater_model_preview.xml
index 4af8d67686..4285462bc8 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_model_preview.xml
+++ b/indra/newview/skins/default/xui/de/floater_model_preview.xml
@@ -92,19 +92,54 @@
<text initial_value="Dreiecke" name="triangles" value="Dreiecke"/>
<text initial_value="Scheitelpunkte" name="vertices" value="Scheitelpunkte"/>
<text initial_value="Hoch" name="high_label" value="Hoch"/>
+ <combo_box name="lod_source_high">
+ <item name="Load from file" value="Aus Datei laden"/>
+ <item name="Generate" value="Generieren"/>
+ </combo_box>
<button label="Durchsuchen..." name="lod_browse_high"/>
+ <combo_box name="lod_mode_high">
+ <item name="Triangle Limit" value="Dreiecklimit"/>
+ <item name="Error Threshold" value="Fehlerschwelle"/>
+ </combo_box>
<text initial_value="0" name="high_triangles" value="0"/>
<text initial_value="0" name="high_vertices" value="0"/>
<text initial_value="Mittel" name="medium_label" value="Mittel"/>
+ <combo_box name="lod_source_medium">
+ <item name="Load from file" value="Aus Datei laden"/>
+ <item name="Generate" value="Generieren"/>
+ <item name="Use LoD above" value="Detailstufe oben verwenden"/>
+ </combo_box>
<button label="Durchsuchen..." name="lod_browse_medium"/>
+ <combo_box name="lod_mode_medium">
+ <item name="Triangle Limit" value="Dreiecklimit"/>
+ <item name="Error Threshold" value="Fehlerschwelle"/>
+ </combo_box>
<text initial_value="0" name="medium_triangles" value="0"/>
<text initial_value="0" name="medium_vertices" value="0"/>
<text initial_value="Niedrig" name="low_label" value="Niedrig"/>
+ <combo_box name="lod_source_low">
+ <item name="Load from file" value="Aus Datei laden"/>
+ <item name="Generate" value="Generieren"/>
+ <item name="Use LoD above" value="Detailstufe oben verwenden"/>
+ </combo_box>
<button label="Durchsuchen..." name="lod_browse_low"/>
+ <combo_box name="lod_mode_low">
+ <item name="Triangle Limit" value="Dreiecklimit"/>
+ <item name="Error Threshold" value="Fehlerschwelle"/>
+ </combo_box>
<text initial_value="0" name="low_triangles" value="0"/>
<text initial_value="0" name="low_vertices" value="0"/>
<text initial_value="Niedrigste" name="lowest_label" value="Niedrigste"/>
+ <combo_box name="lod_source_lowest">
+ <item name="Load from file" value="Aus Datei laden"/>
+ <item name="Generate" value="Generieren"/>
+ <item name="Use LoD above" value="Detailstufe oben verwenden"/>
+ </combo_box>
<button label="Durchsuchen..." name="lod_browse_lowest"/>
+ <combo_box name="lod_mode_lowest">
+ <item name="Triangle Limit" value="Dreiecklimit"/>
+ <item name="Error Threshold" value="Fehlerschwelle"/>
+ </combo_box>
<text initial_value="0" name="lowest_triangles" value="0"/>
<text initial_value="0" name="lowest_vertices" value="0"/>
<check_box label="Normalen generieren" name="gen_normals"/>
diff --git a/indra/newview/skins/default/xui/de/floater_model_wizard.xml b/indra/newview/skins/default/xui/de/floater_model_wizard.xml
deleted file mode 100644
index ee26d51d32..0000000000
--- a/indra/newview/skins/default/xui/de/floater_model_wizard.xml
+++ /dev/null
@@ -1,208 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Model Wizard" title="ASSISTENT ZUM HOCHLADEN VON MODELLEN">
- <button label="5. Hochladen" name="upload_btn"/>
- <button label="4. Überprüfen" name="review_btn"/>
- <button label="3. Physik" name="physics_btn"/>
- <button label="2. Optimieren" name="optimize_btn"/>
- <button label="1. Datei auswählen" name="choose_file_btn"/>
- <panel name="choose_file_panel">
- <panel name="choose_file_header_panel">
- <text name="choose_file_header_text">
- Modelldatei auswählen
- </text>
- </panel>
- <panel name="choose_file_content">
- <text name="advanced_users_text">
- Fortgeschrittene Benutzer: Wenn Sie bereits mit Tools zur Erstellung von 3D-Inhalten vertraut sind, können Sie den erweiterten Uploader verwenden.
- </text>
- <button label="Auf Erweitert wechseln" name="switch_to_advanced"/>
- <text name="Cache location">
- Hochzuladende Modelldatei auswählen
- </text>
- <button label="Durchsuchen..." label_selected="Durchsuchen..." name="browse"/>
- <text name="Model types">
- Second Life unterstützt COLLADA-Dateien (.dae).
- </text>
- <text name="dimensions">
- X Y Z
- </text>
- <text name="warning_label">
- ACHTUNG:
- </text>
- <text name="warning_text">
- Sie können den letzten Schritt nicht abschließen (Modell auf Second Life-Server hochladen). [secondlife:///app/floater/learn_more Weitere Infos], wie Sie Ihr Konto zum Hochladen von Netzmodellen einrichten.
- </text>
- </panel>
- </panel>
- <panel name="optimize_panel">
- <panel name="optimize_header_panel">
- <text name="optimize_header_text">
- Modell optimieren
- </text>
- </panel>
- <text name="optimize_description">
- Wir haben das Modell auf Leistung optimiert. Sie können es bei Bedarf weiter anpassen.
- </text>
- <panel name="optimize_content">
- <text name="high_detail_text">
- Detailstufe generieren: hoch
- </text>
- <text name="medium_detail_text">
- Detailstufe generieren: mittel
- </text>
- <text name="low_detail_text">
- Detailstufe generieren: niedrig
- </text>
- <text name="lowest_detail_text">
- Detailstufe generieren: niedrigste
- </text>
- </panel>
- <panel name="content2">
- <button label="Geometrie neu berechnen" name="recalculate_geometry_btn"/>
- <text name="lod_label">
- Geometrievorschau
- </text>
- <combo_box name="preview_lod_combo" tool_tip="Detailstufe zur Anzeige in Vorschaudarstellung">
- <combo_item name="high">
- Viel Details
- </combo_item>
- <combo_item name="medium">
- Mittlere Details
- </combo_item>
- <combo_item name="low">
- Wenig Details
- </combo_item>
- <combo_item name="lowest">
- Wenigste Details
- </combo_item>
- </combo_box>
- </panel>
- </panel>
- <panel name="physics_panel">
- <panel name="physics_header_panel">
- <text name="physics_header_text">
- Physik anpassen
- </text>
- </panel>
- <text name="physics_description">
- Wir erstellen eine Form für die Außenhülle des Modells. Passen Sie die Detailstufe der Form wie für den beabsichtigten Zweck erforderlich an.
- </text>
- <panel name="physics_content">
- <button label="Physik neu berechnen" name="recalculate_physics_btn"/>
- <button label="Neu berechnen..." name="recalculating_physics_btn"/>
- <text name="lod_label">
- Physikvorschau
- </text>
- <combo_box name="preview_lod_combo2" tool_tip="Detailstufe zur Anzeige in Vorschaudarstellung">
- <combo_item name="high">
- Viel Details
- </combo_item>
- <combo_item name="medium">
- Mittlere Details
- </combo_item>
- <combo_item name="low">
- Wenig Details
- </combo_item>
- <combo_item name="lowest">
- Wenigste Details
- </combo_item>
- </combo_box>
- </panel>
- </panel>
- <panel name="review_panel">
- <panel name="review_header_panel">
- <text name="review_header_text">
- Überprüfen
- </text>
- </panel>
- <panel name="review_content">
- <text name="review_prim_equiv">
- Auswirkung auf Parzelle/Region: Prim-Äquivalenzwert [EQUIV]
- </text>
- <text name="review_fee">
- Die für das Hochladen anfallende Gebühr in Höhe von L$ [FEE] wird von Ihrem Konto abgebucht.
- </text>
- <text name="review_confirmation">
- Durch Klicken auf „Hochladen“ bestätigen Sie, dass Sie die erforderlichen Rechte für das im Modell enthaltene Material besitzen.
- </text>
- </panel>
- </panel>
- <panel name="upload_panel">
- <panel name="upload_header_panel">
- <text name="upload_header_text">
- Upload abgeschlossen
- </text>
- </panel>
- <text name="model_uploaded_text">
- Ihr Modell wurde hochgeladen.
- </text>
- <text name="inventory_text">
- Sie finden das Modell im Objektordner Ihres Inventars.
- </text>
- <text name="charged_fee">
- Von Ihrem Konto wurden [FEE] L$ abgebucht.
- </text>
- </panel>
- <button label="&lt;&lt; Zurück" name="back"/>
- <button label="Weiter &gt;&gt;" name="next"/>
- <button label="Gewichte und Gebühr berechnen &gt;&gt;" name="calculate"/>
- <button label="Berechnen..." name="calculating"/>
- <button label="Hochladen" name="upload" tool_tip="An Simulator hochladen"/>
- <button label="Abbrechen" name="cancel"/>
- <button label="Schließen" name="close"/>
- <spinner name="import_scale" value="1,0"/>
- <string name="status_idle">
- Inaktiv
- </string>
- <string name="status_parse_error">
- DAE-Parsing-Fehler. Details siehe Protokoll.
- </string>
- <string name="status_reading_file">
- Laden...
- </string>
- <string name="status_generating_meshes">
- Netze werden generiert...
- </string>
- <string name="status_vertex_number_overflow">
- Fehler: Anzahl von Vertices überschreitet 65534. Operation abgebrochen.
- </string>
- <string name="bad_element">
- Fehler: ungültiges Element.
- </string>
- <string name="high">
- Hoch
- </string>
- <string name="medium">
- Mittel
- </string>
- <string name="low">
- Niedrig
- </string>
- <string name="lowest">
- Niedrigste
- </string>
- <string name="mesh_status_good">
- Ausliefern
- </string>
- <string name="mesh_status_na">
- --
- </string>
- <string name="mesh_status_none">
- Keine
- </string>
- <string name="mesh_status_submesh_mismatch">
- Detailstufen haben unterschiedliche Anzahl texturfähiger Flächen.
- </string>
- <string name="mesh_status_mesh_mismatch">
- Detailstufen haben unterschiedliche Anzahl von Netzinstanzen.
- </string>
- <string name="mesh_status_too_many_vertices">
- Detailstufe hat zu viele Vertices.
- </string>
- <string name="mesh_status_missing_lod">
- Erforderliche Detailstufe fehlt.
- </string>
- <string name="layer_all">
- Alle
- </string>
-</floater>
diff --git a/indra/newview/skins/default/xui/de/floater_moveview.xml b/indra/newview/skins/default/xui/de/floater_moveview.xml
index c1c8271310..c1c8271310 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_moveview.xml
+++ b/indra/newview/skins/default/xui/de/floater_moveview.xml
diff --git a/indra/newview/skins/default/xui/de/floater_mute_object.xml b/indra/newview/skins/default/xui/de/floater_mute_object.xml
index 3f1af3dc63..3f1af3dc63 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_mute_object.xml
+++ b/indra/newview/skins/default/xui/de/floater_mute_object.xml
diff --git a/indra/newview/skins/default/xui/de/floater_my_appearance.xml b/indra/newview/skins/default/xui/de/floater_my_appearance.xml
index e26b2434cc..e26b2434cc 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_my_appearance.xml
+++ b/indra/newview/skins/default/xui/de/floater_my_appearance.xml
diff --git a/indra/newview/skins/default/xui/de/floater_my_inventory.xml b/indra/newview/skins/default/xui/de/floater_my_inventory.xml
index 0cfa17562e..0cfa17562e 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_my_inventory.xml
+++ b/indra/newview/skins/default/xui/de/floater_my_inventory.xml
diff --git a/indra/newview/skins/default/xui/de/floater_nearby_chat.xml b/indra/newview/skins/default/xui/de/floater_nearby_chat.xml
deleted file mode 100644
index 2aabbb18f2..0000000000
--- a/indra/newview/skins/default/xui/de/floater_nearby_chat.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="nearby_chat" title="CHAT IN DER NÄHE">
- <check_box label="Chat übersetzen" name="translate_chat_checkbox"/>
-</floater>
diff --git a/indra/newview/skins/default/xui/de/floater_notification.xml b/indra/newview/skins/default/xui/de/floater_notification.xml
index 7752d22b52..7752d22b52 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_notification.xml
+++ b/indra/newview/skins/default/xui/de/floater_notification.xml
diff --git a/indra/newview/skins/default/xui/de/floater_notifications_console.xml b/indra/newview/skins/default/xui/de/floater_notifications_console.xml
index e271cdace2..e271cdace2 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_notifications_console.xml
+++ b/indra/newview/skins/default/xui/de/floater_notifications_console.xml
diff --git a/indra/newview/skins/default/xui/de/floater_object_weights.xml b/indra/newview/skins/default/xui/de/floater_object_weights.xml
index e6641d3d18..e6641d3d18 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_object_weights.xml
+++ b/indra/newview/skins/default/xui/de/floater_object_weights.xml
diff --git a/indra/newview/skins/default/xui/de/floater_openobject.xml b/indra/newview/skins/default/xui/de/floater_openobject.xml
index c3e7052283..c3e7052283 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_openobject.xml
+++ b/indra/newview/skins/default/xui/de/floater_openobject.xml
diff --git a/indra/newview/skins/default/xui/de/floater_outfit_save_as.xml b/indra/newview/skins/default/xui/de/floater_outfit_save_as.xml
index 7481e6d4b7..7481e6d4b7 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_outfit_save_as.xml
+++ b/indra/newview/skins/default/xui/de/floater_outfit_save_as.xml
diff --git a/indra/newview/skins/default/xui/de/floater_outgoing_call.xml b/indra/newview/skins/default/xui/de/floater_outgoing_call.xml
index 81079a3c52..81079a3c52 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_outgoing_call.xml
+++ b/indra/newview/skins/default/xui/de/floater_outgoing_call.xml
diff --git a/indra/newview/skins/default/xui/de/floater_pathfinding_characters.xml b/indra/newview/skins/default/xui/de/floater_pathfinding_characters.xml
new file mode 100755
index 0000000000..7096dbc156
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/floater_pathfinding_characters.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="floater_pathfinding_characters" title="Pathfinding-Figuren">
+ <floater.string name="messaging_get_inprogress">
+ Pathfinding-Figuren werden abgerufen...
+ </floater.string>
+ <floater.string name="messaging_get_error">
+ Fehler beim Abrufen von Pathfinding-Figuren.
+ </floater.string>
+ <floater.string name="messaging_complete_none_found">
+ Keine Pathfinding-Figuren.
+ </floater.string>
+ <floater.string name="messaging_complete_available">
+ [NUM_SELECTED] Figuren von [NUM_TOTAL] ausgewählt.
+ </floater.string>
+ <floater.string name="messaging_not_enabled">
+ Pathfinding ist in dieser Region nicht aktiviert.
+ </floater.string>
+ <floater.string name="character_cpu_time">
+ [CPU_TIME] µs
+ </floater.string>
+ <floater.string name="character_owner_loading">
+ [Laden]
+ </floater.string>
+ <floater.string name="character_owner_unknown">
+ [Unbekannt]
+ </floater.string>
+ <floater.string name="character_owner_group">
+ [Gruppe]
+ </floater.string>
+ <panel>
+ <scroll_list name="objects_scroll_list">
+ <scroll_list.columns label="Name" name="name"/>
+ <scroll_list.columns label="Beschreibung" name="description"/>
+ <scroll_list.columns label="Eigentümer" name="owner"/>
+ <scroll_list.columns label="CPU" name="cpu_time"/>
+ <scroll_list.columns label="Höhe" name="altitude"/>
+ </scroll_list>
+ <text name="messaging_status">
+ Figuren:
+ </text>
+ <button label="Liste aktualisieren" name="refresh_objects_list"/>
+ <button label="Alle auswählen" name="select_all_objects"/>
+ <button label="Keine auswählen" name="select_none_objects"/>
+ </panel>
+ <panel>
+ <text name="actions_label">
+ Aktionen für ausgewählte Figuren:
+ </text>
+ <check_box label="Beacon anzeigen" name="show_beacon"/>
+ <check_box label="Physikkapsel anzeigen" name="show_physics_capsule"/>
+ <button label="Nehmen" name="take_objects"/>
+ <button label="Kopie nehmen" name="take_copy_objects"/>
+ <button label="Dorthin teleportieren" name="teleport_me_to_object" tool_tip="Nur aktiviert, wenn eine Figur ausgewählt ist."/>
+ <button label="Zurückgeben" name="return_objects"/>
+ <button label="Löschen" name="delete_objects"/>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/de/floater_pathfinding_console.xml b/indra/newview/skins/default/xui/de/floater_pathfinding_console.xml
new file mode 100755
index 0000000000..ebf8f01632
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/floater_pathfinding_console.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="floater_pathfinding_console" title="Pathfinding-Ansicht/-Test">
+ <floater.string name="navmesh_viewer_status_library_not_implemented">
+ Pathfinding-Bibliotheksimplementierung nicht gefunden.
+ </floater.string>
+ <floater.string name="navmesh_viewer_status_region_not_enabled">
+ Pathfinding ist in dieser Region nicht aktiviert.
+ </floater.string>
+ <floater.string name="navmesh_viewer_status_region_loading">
+ Warten, bis Region geladen ist.
+ </floater.string>
+ <floater.string name="navmesh_viewer_status_checking_version">
+ Navmesh-Status wird geprüft.
+ </floater.string>
+ <floater.string name="navmesh_viewer_status_downloading">
+ Navmesh wird heruntergeladen.
+ </floater.string>
+ <floater.string name="navmesh_viewer_status_updating">
+ Navmesh hat sich auf dem Server geändert. Neuestes Navmesh wird heruntergeladen.
+ </floater.string>
+ <floater.string name="navmesh_viewer_status_has_navmesh">
+ Neuestes Navmesh wurde heruntergeladen.
+ </floater.string>
+ <floater.string name="navmesh_viewer_status_error">
+ Navmesh kann nicht heruntergeladen werden.
+ </floater.string>
+ <floater.string name="navmesh_simulator_status_pending">
+ Navmesh weist ausstehende Änderungen auf.
+ </floater.string>
+ <floater.string name="navmesh_simulator_status_building">
+ Navmesh wird erstellt.
+ </floater.string>
+ <floater.string name="navmesh_simulator_status_some_pending">
+ Einige Navmesh-Regionen weisen ausstehende Änderungen auf.
+ </floater.string>
+ <floater.string name="navmesh_simulator_status_some_building">
+ Einige Navmesh-Regionen werden erstellt.
+ </floater.string>
+ <floater.string name="navmesh_simulator_status_pending_and_building">
+ Einige Navmesh-Regionen weisen ausstehende Änderungen auf und andere werden erstellt.
+ </floater.string>
+ <floater.string name="navmesh_simulator_status_complete">
+ Navmesh ist aktuell.
+ </floater.string>
+ <floater.string name="pathing_library_not_implemented">
+ Pathfinding-Bibliotheksimplementierung nicht gefunden.
+ </floater.string>
+ <floater.string name="pathing_region_not_enabled">
+ Pathfinding ist in dieser Region nicht aktiviert.
+ </floater.string>
+ <floater.string name="pathing_choose_start_and_end_points">
+ Bitte wählen Sie Anfangs- und Endpunkte aus.
+ </floater.string>
+ <floater.string name="pathing_choose_start_point">
+ Bitte wählen Sie einen Anfangspunkt aus.
+ </floater.string>
+ <floater.string name="pathing_choose_end_point">
+ Bitte wählen Sie einen Endpunkt aus.
+ </floater.string>
+ <floater.string name="pathing_path_valid">
+ Pfad wird orange dargestellt.
+ </floater.string>
+ <floater.string name="pathing_path_invalid">
+ Zwischen den gewählten Punkten wurde kein Pfad gefunden.
+ </floater.string>
+ <floater.string name="pathing_error">
+ Fehler bei der Pfaderstellung aufgetreten.
+ </floater.string>
+ <tab_container name="view_test_tab_container">
+ <panel label="Anzeigen" name="view_panel">
+ <text name="show_label">
+ Anzeigen:
+ </text>
+ <check_box label="Welt" name="show_world"/>
+ <check_box label="Nur bewegliche Objekte" name="show_world_movables_only"/>
+ <check_box label="Navmesh" name="show_navmesh"/>
+ <text name="show_walkability_label">
+ Begehbarkeitskarte anzeigen:
+ </text>
+ <combo_box name="show_heatmap_mode">
+ <combo_box.item label="Nicht anzeigen" name="show_heatmap_mode_none"/>
+ <combo_box.item label="Figurentyp A" name="show_heatmap_mode_a"/>
+ <combo_box.item label="Figurentyp B" name="show_heatmap_mode_b"/>
+ <combo_box.item label="Figurentyp C" name="show_heatmap_mode_c"/>
+ <combo_box.item label="Figurentyp D" name="show_heatmap_mode_d"/>
+ </combo_box>
+ <check_box label="Begehbare Objekte" name="show_walkables"/>
+ <check_box label="Materialvolumen" name="show_material_volumes"/>
+ <check_box label="Statische Hinternisse" name="show_static_obstacles"/>
+ <check_box label="Ausschlussvolumen" name="show_exclusion_volumes"/>
+ <check_box label="Wasserebene" name="show_water_plane"/>
+ <check_box label="Mit Röntgenblick" name="show_xray"/>
+ </panel>
+ <panel label="Pfad testen" name="test_panel">
+ <text name="ctrl_click_label">
+ Bei gedrückter Strg-Taste klicken, um Anfangspunkt auszuwählen.
+ </text>
+ <text name="shift_click_label">
+ Bei gedrückter Umschalttaste klicken, um Endpunkt auszuwählen.
+ </text>
+ <text name="character_width_label">
+ Figurenbreite
+ </text>
+ <slider name="character_width" value="1"/>
+ <text name="character_width_unit_label">
+ m
+ </text>
+ <text name="character_type_label">
+ Figurentyp
+ </text>
+ <combo_box name="path_character_type">
+ <combo_box.item label="Keine" name="path_character_type_none"/>
+ <combo_box.item label="A" name="path_character_type_a"/>
+ <combo_box.item label="B" name="path_character_type_b"/>
+ <combo_box.item label="C" name="path_character_type_c"/>
+ <combo_box.item label="D" name="path_character_type_d"/>
+ </combo_box>
+ <button label="Pfad löschen" name="clear_path"/>
+ </panel>
+ </tab_container>
+</floater>
diff --git a/indra/newview/skins/default/xui/de/floater_pathfinding_linksets.xml b/indra/newview/skins/default/xui/de/floater_pathfinding_linksets.xml
new file mode 100755
index 0000000000..0d3ba59efb
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/floater_pathfinding_linksets.xml
@@ -0,0 +1,167 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="floater_pathfinding_linksets" title="Pathfinding-Linksets">
+ <floater.string name="messaging_get_inprogress">
+ Pathfinding-Linksets werden abgerufen...
+ </floater.string>
+ <floater.string name="messaging_get_error">
+ Fehler beim Abrufen von Pathfinding-Linksets.
+ </floater.string>
+ <floater.string name="messaging_set_inprogress">
+ Ausgewählte Pathfinding-Linksets werden geändert...
+ </floater.string>
+ <floater.string name="messaging_set_error">
+ Fehler beim Ändern der ausgewählten Pathfinding-Linksets.
+ </floater.string>
+ <floater.string name="messaging_complete_none_found">
+ Keine Pathfinding-Linksets.
+ </floater.string>
+ <floater.string name="messaging_complete_available">
+ [NUM_SELECTED] Linksets von [NUM_TOTAL] ausgewählt.
+ </floater.string>
+ <floater.string name="messaging_not_enabled">
+ Pathfinding ist in dieser Region nicht aktiviert.
+ </floater.string>
+ <floater.string name="linkset_terrain_name">
+ [Terrain]
+ </floater.string>
+ <floater.string name="linkset_terrain_description">
+ --
+ </floater.string>
+ <floater.string name="linkset_terrain_owner">
+ --
+ </floater.string>
+ <floater.string name="linkset_terrain_scripted">
+ --
+ </floater.string>
+ <floater.string name="linkset_terrain_land_impact">
+ --
+ </floater.string>
+ <floater.string name="linkset_terrain_dist_from_you">
+ --
+ </floater.string>
+ <floater.string name="linkset_owner_loading">
+ [Laden]
+ </floater.string>
+ <floater.string name="linkset_owner_unknown">
+ [Unbekannt]
+ </floater.string>
+ <floater.string name="linkset_owner_group">
+ [Gruppe]
+ </floater.string>
+ <floater.string name="linkset_is_scripted">
+ Ja
+ </floater.string>
+ <floater.string name="linkset_is_not_scripted">
+ Nein
+ </floater.string>
+ <floater.string name="linkset_is_unknown_scripted">
+ Unbekannt
+ </floater.string>
+ <floater.string name="linkset_use_walkable">
+ Begehbar
+ </floater.string>
+ <floater.string name="linkset_use_static_obstacle">
+ Statisches Hinternis
+ </floater.string>
+ <floater.string name="linkset_use_dynamic_obstacle">
+ Bewegliches Hinternis
+ </floater.string>
+ <floater.string name="linkset_use_material_volume">
+ Materialvolumen
+ </floater.string>
+ <floater.string name="linkset_use_exclusion_volume">
+ Ausschlussvolumen
+ </floater.string>
+ <floater.string name="linkset_use_dynamic_phantom">
+ Bewegliches Phantom
+ </floater.string>
+ <floater.string name="linkset_is_terrain">
+ [nicht änderbar]
+ </floater.string>
+ <floater.string name="linkset_is_restricted_state">
+ [beschränkt]
+ </floater.string>
+ <floater.string name="linkset_is_non_volume_state">
+ [konkav]
+ </floater.string>
+ <floater.string name="linkset_is_restricted_non_volume_state">
+ [beschränkt,konkav]
+ </floater.string>
+ <floater.string name="linkset_choose_use">
+ Linkset-Nutzung auswählen...
+ </floater.string>
+ <panel>
+ <combo_box name="filter_by_linkset_use">
+ <combo_box.item label="Nach Linkset-Nutzung filtern..." name="filter_by_linkset_use_none"/>
+ <combo_box.item label="Begehbar" name="filter_by_linkset_use_walkable"/>
+ <combo_box.item label="Statisches Hinternis" name="filter_by_linkset_use_static_obstacle"/>
+ <combo_box.item label="Bewegliches Hinternis" name="filter_by_linkset_use_dynamic_obstacle"/>
+ <combo_box.item label="Materialvolumen" name="filter_by_linkset_use_material_volume"/>
+ <combo_box.item label="Ausschlussvolumen" name="filter_by_linkset_use_exclusion_volume"/>
+ <combo_box.item label="Bewegliches Phantom" name="filter_by_linkset_use_dynamic_phantom"/>
+ </combo_box>
+ <button label="Anwenden" name="apply_filters"/>
+ <button label="Entfernen" name="clear_filters"/>
+ <scroll_list name="objects_scroll_list">
+ <scroll_list.columns label="Name (Hauptprim)" name="name"/>
+ <scroll_list.columns label="Beschreibung (Hauptprim)" name="description"/>
+ <scroll_list.columns label="Eigentümer" name="owner"/>
+ <scroll_list.columns label="Geskriptet" name="scripted"/>
+ <scroll_list.columns label="Belastung" name="land_impact"/>
+ <scroll_list.columns label="Abstand" name="dist_from_you"/>
+ <scroll_list.columns label="Linkset-Nutzung" name="linkset_use"/>
+ <scroll_list.columns label="A %" name="a_percent"/>
+ <scroll_list.columns label="B %" name="b_percent"/>
+ <scroll_list.columns label="C %" name="c_percent"/>
+ <scroll_list.columns label="D %" name="d_percent"/>
+ </scroll_list>
+ <text name="messaging_status">
+ Linksets:
+ </text>
+ <button label="Liste aktualisieren" name="refresh_objects_list"/>
+ <button label="Alle auswählen" name="select_all_objects"/>
+ <button label="Keine auswählen" name="select_none_objects"/>
+ </panel>
+ <panel>
+ <check_box label="Beacon anzeigen" name="show_beacon"/>
+ <button label="Nehmen" name="take_objects"/>
+ <button label="Kopie nehmen" name="take_copy_objects"/>
+ <button label="Dorthin teleportieren" name="teleport_me_to_object"/>
+ <button label="Zurückgeben" name="return_objects"/>
+ <button label="Löschen" name="delete_objects"/>
+ </panel>
+ <panel>
+ <text name="walkability_coefficients_label">
+ Begehbarkeit:
+ </text>
+ <text name="edit_a_label">
+ A
+ </text>
+ <line_editor name="edit_a_value" tool_tip="Begehbarkeit für Figuren vom Typ A. Ein Beispiel für diesen Typ wäre „Humanoid“."/>
+ <text name="edit_b_label">
+ B
+ </text>
+ <line_editor name="edit_b_value" tool_tip="Begehbarkeit für Figuren vom Typ B. Ein Beispiel für diesen Typ wäre „Kreatur“."/>
+ <text name="edit_c_label">
+ C
+ </text>
+ <line_editor name="edit_c_value" tool_tip="Begehbarkeit für Figuren vom Typ C. Ein Beispiel für diesen Typ wäre „Mechanisch“."/>
+ <text name="edit_d_label">
+ D
+ </text>
+ <line_editor name="edit_d_value" tool_tip="Begehbarkeit für Figuren vom Typ D. Ein Beispiel für diesen Typ wäre „Anderer“."/>
+ <button label="Änderungen übernehmen" name="apply_edit_values"/>
+ <text name="suggested_use_a_label">
+ (Humanoid)
+ </text>
+ <text name="suggested_use_b_label">
+ (Kreatur)
+ </text>
+ <text name="suggested_use_c_label">
+ (Mechanisch)
+ </text>
+ <text name="suggested_use_d_label">
+ (Anderer)
+ </text>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/de/floater_pay.xml b/indra/newview/skins/default/xui/de/floater_pay.xml
index a0a622ecbc..a0a622ecbc 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_pay.xml
+++ b/indra/newview/skins/default/xui/de/floater_pay.xml
diff --git a/indra/newview/skins/default/xui/de/floater_pay_object.xml b/indra/newview/skins/default/xui/de/floater_pay_object.xml
index 7159bbadb3..7159bbadb3 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_pay_object.xml
+++ b/indra/newview/skins/default/xui/de/floater_pay_object.xml
diff --git a/indra/newview/skins/default/xui/de/floater_people.xml b/indra/newview/skins/default/xui/de/floater_people.xml
index fd1db148ac..fd1db148ac 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_people.xml
+++ b/indra/newview/skins/default/xui/de/floater_people.xml
diff --git a/indra/newview/skins/default/xui/de/floater_perm_prefs.xml b/indra/newview/skins/default/xui/de/floater_perm_prefs.xml
index 9be22f3ccb..9be22f3ccb 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_perm_prefs.xml
+++ b/indra/newview/skins/default/xui/de/floater_perm_prefs.xml
diff --git a/indra/newview/skins/default/xui/de/floater_picks.xml b/indra/newview/skins/default/xui/de/floater_picks.xml
index 2521920e83..2521920e83 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_picks.xml
+++ b/indra/newview/skins/default/xui/de/floater_picks.xml
diff --git a/indra/newview/skins/default/xui/de/floater_places.xml b/indra/newview/skins/default/xui/de/floater_places.xml
index 80a1490afd..80a1490afd 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_places.xml
+++ b/indra/newview/skins/default/xui/de/floater_places.xml
diff --git a/indra/newview/skins/default/xui/de/floater_post_process.xml b/indra/newview/skins/default/xui/de/floater_post_process.xml
index a6ed8cc3df..a6ed8cc3df 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_post_process.xml
+++ b/indra/newview/skins/default/xui/de/floater_post_process.xml
diff --git a/indra/newview/skins/default/xui/de/floater_postcard.xml b/indra/newview/skins/default/xui/de/floater_postcard.xml
deleted file mode 100644
index 28af0183cb..0000000000
--- a/indra/newview/skins/default/xui/de/floater_postcard.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Postcard" title="FOTO EMAILEN">
- <text name="to_label">
- E-Mail des Empfängers:
- </text>
- <text name="from_label">
- Ihre E-Mail:
- </text>
- <text name="name_label">
- Ihr Name:
- </text>
- <text name="subject_label">
- Betreff:
- </text>
- <line_editor label="Betreff hier eingeben." name="subject_form"/>
- <text name="msg_label">
- Nachricht:
- </text>
- <text_editor name="msg_form">
- Nachricht hier eingeben.
- </text_editor>
- <text name="fine_print">
- Wenn sich der Empfänger bei SL anmeldet, erhalten Sie einen Empfehlungsbonus.
- </text>
- <button label="Abbrechen" name="cancel_btn"/>
- <button label="Senden" name="send_btn"/>
- <text name="default_subject">
- Postkarte aus [SECOND_LIFE].
- </text>
- <text name="default_message">
- Sehen Sie hier!
- </text>
- <string name="upload_message">
- Wird gesendet...
- </string>
-</floater>
diff --git a/indra/newview/skins/default/xui/de/floater_preferences.xml b/indra/newview/skins/default/xui/de/floater_preferences.xml
index 3624c4c968..3624c4c968 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_preferences.xml
+++ b/indra/newview/skins/default/xui/de/floater_preferences.xml
diff --git a/indra/newview/skins/default/xui/de/floater_preferences_proxy.xml b/indra/newview/skins/default/xui/de/floater_preferences_proxy.xml
index cdefb470c2..cdefb470c2 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_preferences_proxy.xml
+++ b/indra/newview/skins/default/xui/de/floater_preferences_proxy.xml
diff --git a/indra/newview/skins/default/xui/de/floater_preview_animation.xml b/indra/newview/skins/default/xui/de/floater_preview_animation.xml
index 2dd47a27ad..2dd47a27ad 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_preview_animation.xml
+++ b/indra/newview/skins/default/xui/de/floater_preview_animation.xml
diff --git a/indra/newview/skins/default/xui/de/floater_preview_gesture.xml b/indra/newview/skins/default/xui/de/floater_preview_gesture.xml
index 76dc623ca4..76dc623ca4 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_preview_gesture.xml
+++ b/indra/newview/skins/default/xui/de/floater_preview_gesture.xml
diff --git a/indra/newview/skins/default/xui/de/floater_preview_notecard.xml b/indra/newview/skins/default/xui/de/floater_preview_notecard.xml
index 14e666fd22..14e666fd22 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_preview_notecard.xml
+++ b/indra/newview/skins/default/xui/de/floater_preview_notecard.xml
diff --git a/indra/newview/skins/default/xui/de/floater_preview_sound.xml b/indra/newview/skins/default/xui/de/floater_preview_sound.xml
index 4629ec4a04..4629ec4a04 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_preview_sound.xml
+++ b/indra/newview/skins/default/xui/de/floater_preview_sound.xml
diff --git a/indra/newview/skins/default/xui/de/floater_preview_texture.xml b/indra/newview/skins/default/xui/de/floater_preview_texture.xml
index 526c0813bd..526c0813bd 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_preview_texture.xml
+++ b/indra/newview/skins/default/xui/de/floater_preview_texture.xml
diff --git a/indra/newview/skins/default/xui/de/floater_price_for_listing.xml b/indra/newview/skins/default/xui/de/floater_price_for_listing.xml
index bdd772a9c2..bdd772a9c2 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_price_for_listing.xml
+++ b/indra/newview/skins/default/xui/de/floater_price_for_listing.xml
diff --git a/indra/newview/skins/default/xui/de/floater_publish_classified.xml b/indra/newview/skins/default/xui/de/floater_publish_classified.xml
index d91535ebc3..d91535ebc3 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_publish_classified.xml
+++ b/indra/newview/skins/default/xui/de/floater_publish_classified.xml
diff --git a/indra/newview/skins/default/xui/de/floater_region_debug_console.xml b/indra/newview/skins/default/xui/de/floater_region_debug_console.xml
index b8a1a89c30..b8a1a89c30 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_region_debug_console.xml
+++ b/indra/newview/skins/default/xui/de/floater_region_debug_console.xml
diff --git a/indra/newview/skins/default/xui/de/floater_region_info.xml b/indra/newview/skins/default/xui/de/floater_region_info.xml
index c0dc47a67d..c0dc47a67d 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_region_info.xml
+++ b/indra/newview/skins/default/xui/de/floater_region_info.xml
diff --git a/indra/newview/skins/default/xui/de/floater_report_abuse.xml b/indra/newview/skins/default/xui/de/floater_report_abuse.xml
index e37e298478..e37e298478 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_report_abuse.xml
+++ b/indra/newview/skins/default/xui/de/floater_report_abuse.xml
diff --git a/indra/newview/skins/default/xui/de/floater_script_debug.xml b/indra/newview/skins/default/xui/de/floater_script_debug.xml
index 585a6c36ea..585a6c36ea 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_script_debug.xml
+++ b/indra/newview/skins/default/xui/de/floater_script_debug.xml
diff --git a/indra/newview/skins/default/xui/de/floater_script_debug_panel.xml b/indra/newview/skins/default/xui/de/floater_script_debug_panel.xml
index e70a30fa24..e70a30fa24 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_script_debug_panel.xml
+++ b/indra/newview/skins/default/xui/de/floater_script_debug_panel.xml
diff --git a/indra/newview/skins/default/xui/de/floater_script_limits.xml b/indra/newview/skins/default/xui/de/floater_script_limits.xml
index 94a24a97ae..94a24a97ae 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_script_limits.xml
+++ b/indra/newview/skins/default/xui/de/floater_script_limits.xml
diff --git a/indra/newview/skins/default/xui/de/floater_script_preview.xml b/indra/newview/skins/default/xui/de/floater_script_preview.xml
index e0bcd42523..e0bcd42523 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_script_preview.xml
+++ b/indra/newview/skins/default/xui/de/floater_script_preview.xml
diff --git a/indra/newview/skins/default/xui/de/floater_script_queue.xml b/indra/newview/skins/default/xui/de/floater_script_queue.xml
index f267fe4b7c..f267fe4b7c 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_script_queue.xml
+++ b/indra/newview/skins/default/xui/de/floater_script_queue.xml
diff --git a/indra/newview/skins/default/xui/de/floater_script_search.xml b/indra/newview/skins/default/xui/de/floater_script_search.xml
index ffae96f6a1..ffae96f6a1 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_script_search.xml
+++ b/indra/newview/skins/default/xui/de/floater_script_search.xml
diff --git a/indra/newview/skins/default/xui/de/floater_search.xml b/indra/newview/skins/default/xui/de/floater_search.xml
index bd39bf2bce..bd39bf2bce 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_search.xml
+++ b/indra/newview/skins/default/xui/de/floater_search.xml
diff --git a/indra/newview/skins/default/xui/de/floater_select_key.xml b/indra/newview/skins/default/xui/de/floater_select_key.xml
index 8ab9db520a..8ab9db520a 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_select_key.xml
+++ b/indra/newview/skins/default/xui/de/floater_select_key.xml
diff --git a/indra/newview/skins/default/xui/de/floater_sell_land.xml b/indra/newview/skins/default/xui/de/floater_sell_land.xml
index 646138eaad..646138eaad 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_sell_land.xml
+++ b/indra/newview/skins/default/xui/de/floater_sell_land.xml
diff --git a/indra/newview/skins/default/xui/de/floater_settings_debug.xml b/indra/newview/skins/default/xui/de/floater_settings_debug.xml
index 004e54a339..004e54a339 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_settings_debug.xml
+++ b/indra/newview/skins/default/xui/de/floater_settings_debug.xml
diff --git a/indra/newview/skins/default/xui/de/floater_snapshot.xml b/indra/newview/skins/default/xui/de/floater_snapshot.xml
index 798461c007..798461c007 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_snapshot.xml
+++ b/indra/newview/skins/default/xui/de/floater_snapshot.xml
diff --git a/indra/newview/skins/default/xui/de/floater_sound_devices.xml b/indra/newview/skins/default/xui/de/floater_sound_devices.xml
index 22ccb2c1a2..22ccb2c1a2 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_sound_devices.xml
+++ b/indra/newview/skins/default/xui/de/floater_sound_devices.xml
diff --git a/indra/newview/skins/default/xui/de/floater_sound_preview.xml b/indra/newview/skins/default/xui/de/floater_sound_preview.xml
index 1070c93405..1070c93405 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_sound_preview.xml
+++ b/indra/newview/skins/default/xui/de/floater_sound_preview.xml
diff --git a/indra/newview/skins/default/xui/de/floater_spellcheck.xml b/indra/newview/skins/default/xui/de/floater_spellcheck.xml
new file mode 100755
index 0000000000..213db277b6
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/floater_spellcheck.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="spellcheck_floater" title="Einstellungen für Rechtschreibprüfung">
+ <check_box label="Rechtschreibprüfung aktivieren" name="spellcheck_enable"/>
+ <text name="spellcheck_main">
+ Hauptwörterbuch:
+ </text>
+ <text label="Protokolle:" name="spellcheck_additional">
+ Zusätzliche Wörterbücher:
+ </text>
+ <text name="spellcheck_available">
+ Verfügbar
+ </text>
+ <text name="spellcheck_active">
+ Aktiv
+ </text>
+ <button label="Entfernen" name="spellcheck_remove_btn"/>
+ <button label="Importieren..." name="spellcheck_import_btn"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/de/floater_spellcheck_import.xml b/indra/newview/skins/default/xui/de/floater_spellcheck_import.xml
new file mode 100755
index 0000000000..374c0fc0d2
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/floater_spellcheck_import.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="spellcheck_import" title="Wörterbuch importieren">
+ <button label="Durchsuchen" label_selected="Durchsuchen" name="dictionary_path_browse"/>
+ <button label="Importieren" name="ok_btn"/>
+ <button label="Abbrechen" name="cancel_btn"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/de/floater_stats.xml b/indra/newview/skins/default/xui/de/floater_stats.xml
index f6dc9fe15d..f3239f73c7 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_stats.xml
+++ b/indra/newview/skins/default/xui/de/floater_stats.xml
@@ -14,8 +14,11 @@
<stat_bar label="Pro Sek. gezeichnete KTris" name="ktrissec"/>
<stat_bar label="Objektanzahl" name="objs"/>
<stat_bar label="Neue Objekte" name="newobjs"/>
+ <stat_bar label="Objektcache-Trefferrate" name="object_cache_hits"/>
</stat_view>
<stat_view label="Textur" name="texture">
+ <stat_bar label="Cache-Trefferrate" name="texture_cache_hits"/>
+ <stat_bar label="Cache-Leselatenz" name="texture_cache_read_latency"/>
<stat_bar label="Zählen" name="numimagesstat"/>
<stat_bar label="Rohanzahl" name="numrawimagesstat"/>
<stat_bar label="GL Sp" name="gltexmemstat"/>
@@ -50,7 +53,13 @@
<stat_bar label="Objekte" name="simobjects"/>
<stat_bar label="Aktive Objekte" name="simactiveobjects"/>
<stat_bar label="Aktive Skripts" name="simactivescripts"/>
+ <stat_bar label="Skripts ausgeführt" name="simpctscriptsrun"/>
<stat_bar label="Skript-Events" name="simscripteps"/>
+ <stat_view label="Pathfinding" name="simpathfinding">
+ <stat_bar label="AI-Schrittzeit" name="simsimaistepmsec"/>
+ <stat_bar label="Ãœbersprungene Silhouettenschritte" name="simsimskippedsilhouettesteps"/>
+ <stat_bar label="Figuren aktualisiert" name="simsimpctsteppedcharacters"/>
+ </stat_view>
<stat_bar label="Paketeingang" name="siminpps"/>
<stat_bar label="Paketausgang" name="simoutpps"/>
<stat_bar label="Ausstehende Downloads" name="simpendingdownloads"/>
diff --git a/indra/newview/skins/default/xui/de/floater_sys_well.xml b/indra/newview/skins/default/xui/de/floater_sys_well.xml
index ec79b862b4..ec79b862b4 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_sys_well.xml
+++ b/indra/newview/skins/default/xui/de/floater_sys_well.xml
diff --git a/indra/newview/skins/default/xui/de/floater_telehub.xml b/indra/newview/skins/default/xui/de/floater_telehub.xml
index 83d37b2ce4..83d37b2ce4 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_telehub.xml
+++ b/indra/newview/skins/default/xui/de/floater_telehub.xml
diff --git a/indra/newview/skins/default/xui/de/floater_test_layout_stacks.xml b/indra/newview/skins/default/xui/de/floater_test_layout_stacks.xml
index 429447c378..429447c378 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_test_layout_stacks.xml
+++ b/indra/newview/skins/default/xui/de/floater_test_layout_stacks.xml
diff --git a/indra/newview/skins/default/xui/de/floater_test_text_vertical_aligment.xml b/indra/newview/skins/default/xui/de/floater_test_text_vertical_aligment.xml
index 506d2b013a..506d2b013a 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_test_text_vertical_aligment.xml
+++ b/indra/newview/skins/default/xui/de/floater_test_text_vertical_aligment.xml
diff --git a/indra/newview/skins/default/xui/de/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/de/floater_texture_ctrl.xml
index 8944c79c7d..b794d879f0 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_texture_ctrl.xml
+++ b/indra/newview/skins/default/xui/de/floater_texture_ctrl.xml
@@ -1,24 +1,36 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="texture picker" title="TEXTUR AUSWÄHLEN">
- <string name="choose_picture">
+ <floater.string name="choose_picture">
Zum Auswählen eines Bildes hier klicken
- </string>
+ </floater.string>
+ <floater.string name="pick title">
+ Auswählen:
+ </floater.string>
<text name="Multiple">
Mehrere Texturen
</text>
+ <radio_group name="mode_selection">
+ <radio_item label="Inventar" name="inventory" value="0"/>
+ <radio_item label="Lokal" name="local" value="1"/>
+ </radio_group>
<text name="unknown">
Größe: [DIMENSIONS]
</text>
<button label="Standard" label_selected="Standard" name="Default"/>
- <button label="Keine" label_selected="Keine" name="None"/>
<button label="Leer" label_selected="Leer" name="Blank"/>
- <check_box label="Ordner anzeigen" name="show_folders_check"/>
- <search_editor label="Texturen filtern" name="inventory search editor"/>
- <check_box label="Jetzt übernehmen" name="apply_immediate_check"/>
+ <button label="Keine" label_selected="Keine" name="None"/>
<button label="" label_selected="" name="Pipette"/>
- <button label="Abbrechen" label_selected="Abbrechen" name="Cancel"/>
+ <check_box initial_value="true" label="Jetzt übernehmen" name="apply_immediate_check"/>
+ <text name="preview_disabled" value="Vorschau deaktiviert"/>
+ <filter_editor label="Texturen filtern" name="inventory search editor"/>
+ <check_box initial_value="false" label="Ordner anzeigen" name="show_folders_check"/>
+ <button label="Hinzufügen" label_selected="Hinzufügen" name="l_add_btn"/>
+ <button label="Entfernen" label_selected="Entfernen" name="l_rem_btn"/>
+ <button label="Hochladen" label_selected="Hochladen" name="l_upl_btn"/>
+ <scroll_list name="l_name_list">
+ <column label="Name" name="unit_name"/>
+ <column label="ID" name="unit_id_HIDDEN"/>
+ </scroll_list>
<button label="OK" label_selected="OK" name="Select"/>
- <text name="pick title">
- Auswählen:
- </text>
+ <button label="Abbrechen" label_selected="Abbrechen" name="Cancel"/>
</floater>
diff --git a/indra/newview/skins/default/xui/de/floater_texture_fetch_debugger.xml b/indra/newview/skins/default/xui/de/floater_texture_fetch_debugger.xml
new file mode 100755
index 0000000000..97b0364832
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/floater_texture_fetch_debugger.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="TexFetchDebugger" title="Debugger für Texturabruffehler">
+ <text name="total_num_fetched_label">
+ 1, Gesamtzahl abgerufener Texturen: [NUM]
+ </text>
+ <text name="total_num_fetching_requests_label">
+ 2, Gesamtzahl von Abrufanforderungen: [NUM]
+ </text>
+ <text name="total_num_cache_hits_label">
+ 3, Gesamtzahl von Cachetreffern: [NUM]
+ </text>
+ <text name="total_num_visible_tex_label">
+ 4, Gesamtzahl sichtbarer Texturen: [NUM]
+ </text>
+ <text name="total_num_visible_tex_fetch_req_label">
+ 5, Gesamtzahl von Abrufanforderungen für sichtbare Texturen: [NUM]
+ </text>
+ <text name="total_fetched_data_label">
+ 6, Gesamtmenge abgerufener Daten: [SIZE1] KB, decodierte Daten: [SIZE2] KB, [PIXEL] MPixel
+ </text>
+ <text name="total_fetched_vis_data_label">
+ 7, Gesamtmenge sichtbarer Daten: [SIZE1] KB, decodierte Daten: [SIZE2] KB
+ </text>
+ <text name="total_fetched_rendered_data_label">
+ 8, Gesamtmenge dargestellter Daten: [SIZE1] KB, decodierte Daten: [SIZE2] KB, [PIXEL] MPixel
+ </text>
+ <text name="total_time_cache_read_label">
+ 9, Gesamtzeit Cache-Lesezugriffe: [TIME] s
+ </text>
+ <text name="total_time_cache_write_label">
+ 10, Gesamtzeit Cache-Schreibzugriffe: [TIME] s
+ </text>
+ <text name="total_time_decode_label">
+ 11, Gesamtzeit Decodierung: [TIME] s
+ </text>
+ <text name="total_time_gl_label">
+ 12, Gesamtzeit GL-Texturerstellung: [TIME] s
+ </text>
+ <text name="total_time_http_label">
+ 13, Gesamtzeit HTTP-Abrufe: [TIME] s
+ </text>
+ <text name="total_time_fetch_label">
+ 14, Gesamtzeit für alle Abrufe: [TIME] s
+ </text>
+ <text name="total_time_refetch_vis_cache_label">
+ 15, Neuabruf sichtbarer Texturen aus Cache, Zeit: [TIME] s, Abrufmenge: [SIZE2] KB, [PIXEL] MPixel
+ </text>
+ <text name="total_time_refetch_all_cache_label">
+ 16, Neuabruf aller Texturen aus Cache, Zeit: [TIME] s, Abrufmenge: [SIZE2] KB, [PIXEL] MPixel
+ </text>
+ <text name="total_time_refetch_vis_http_label">
+ 17, Neuabruf sichtbarer Texturen von HTTP, Zeit: [TIME] s, Abrufmenge: [SIZE2] KB, [PIXEL] MPixel
+ </text>
+ <text name="total_time_refetch_all_http_label">
+ 18, Neuabruf aller Texturen von HTTP, Zeit: [TIME] s, Abrufmenge: [SIZE2] KB, [PIXEL] MPixel
+ </text>
+ <spinner label="19, Verhältnis Texel/Pixel:" name="texel_pixel_ratio"/>
+ <text name="texture_source_label">
+ 20, Texturquelle:
+ </text>
+ <radio_group name="texture_source">
+ <radio_item label="Cache + HTTP" name="0"/>
+ <radio_item label="Nur HTTP" name="1"/>
+ </radio_group>
+ <button label="Starten" name="start_btn"/>
+ <button label="Zurücksetzen" name="clear_btn"/>
+ <button label="Schließen" name="close_btn"/>
+ <button label="Cache-Lesezugriff" name="cacheread_btn"/>
+ <button label="Cache-Schreibzugriff" name="cachewrite_btn"/>
+ <button label="HTTP" name="http_btn"/>
+ <button label="Decodieren" name="decode_btn"/>
+ <button label="GL-Textur" name="gl_btn"/>
+ <button label="Neuabruf sichtbarer Texturen (Cache)" name="refetchviscache_btn"/>
+ <button label="Neuabruf des gesamten Cache" name="refetchallcache_btn"/>
+ <button label="Neuabruf sichtbarer Texturen (HTTP)" name="refetchvishttp_btn"/>
+ <button label="Neuabruf des gesamten HTTP" name="refetchallhttp_btn"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/de/floater_tools.xml b/indra/newview/skins/default/xui/de/floater_tools.xml
index dee89b28e5..6634a4bd90 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_tools.xml
+++ b/indra/newview/skins/default/xui/de/floater_tools.xml
@@ -148,6 +148,12 @@
<panel.string name="text modify info 4">
Sie können diese Objekte nicht bearbeiten.
</panel.string>
+ <panel.string name="text modify info 5">
+ Dieses Objekt kann nicht über eine Regionsgrenze hinweg geändert werden
+ </panel.string>
+ <panel.string name="text modify info 6">
+ Diese Objekte können nicht über eine Regionsgrenze hinweg geändert werden
+ </panel.string>
<panel.string name="text modify warning">
Gesamtes Objekt wählen, um Berechtigungen festzulegen.
</panel.string>
@@ -197,12 +203,12 @@
<combo_box.item label="Zoom" name="Zoom"/>
</combo_box>
<check_box label="Zum Verkauf:" name="checkbox for sale"/>
+ <spinner label="L$" name="Edit Cost"/>
<combo_box name="sale type">
<combo_box.item label="Kopie" name="Copy"/>
<combo_box.item label="Inhalt" name="Contents"/>
<combo_box.item label="Original" name="Original"/>
</combo_box>
- <spinner label="Preis: L$" name="Edit Cost"/>
<check_box label="In Suche anzeigen" name="search_check" tool_tip="Dieses Objekt in Suchergebnissen anzeigen"/>
<panel name="perms_build">
<text name="perm_modify">
@@ -238,6 +244,11 @@
F:
</text>
</panel>
+ <panel name="pathfinding_attrs_panel">
+ <text name="pathfinding_attributes_label">
+ Pathfinding-Attribute:
+ </text>
+ </panel>
</panel>
<panel label="Objekt" name="Object">
<check_box label="Gesperrt" name="checkbox locked" tool_tip="Verhindert, dass das Objekt verschoben oder gelöscht wird. Oft beim Bauen nützlich, um unbeabsichtigte Bearbeitungen zu vermeiden."/>
@@ -455,16 +466,11 @@
<combo_box.item label="Saugen" name="suction"/>
<combo_box.item label="gewoben" name="weave"/>
</combo_box>
- <check_box initial_value="falsch" label="Flache Oberflächen ausrichten" name="checkbox planar align" tool_tip="Texturen auf allen ausgewählten Oberflächen an der zuletzt ausgewählten Oberfläche ausrichten. Planar Texture Mapping erforderlich."/>
- <text name="rpt">
- Wiederholungen / Oberfläche
- </text>
<spinner label="Horizontal (U)" name="TexScaleU"/>
<check_box label="Umkehren" name="checkbox flip s"/>
<spinner label="Vertikal (V)" name="TexScaleV"/>
<check_box label="Umkehren" name="checkbox flip t"/>
<spinner label="RotationËš" name="TexRot"/>
- <spinner label="Wiederholungen / Meter" name="rptctrl"/>
<button label="Ãœbernehmen" label_selected="Ãœbernehmen" name="button apply"/>
<text name="tex offset">
Texture-Versatz
diff --git a/indra/newview/skins/default/xui/de/floater_top_objects.xml b/indra/newview/skins/default/xui/de/floater_top_objects.xml
index d2055a53db..f8130c6379 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_top_objects.xml
+++ b/indra/newview/skins/default/xui/de/floater_top_objects.xml
@@ -9,9 +9,6 @@
<floater.string name="scripts_score_label">
Zeit
</floater.string>
- <floater.string name="scripts_mono_time_label">
- Mono-Uhrzeit:
- </floater.string>
<floater.string name="top_colliders_title">
Top-Kollisionsobjekte
</floater.string>
@@ -32,9 +29,10 @@
<scroll_list.columns label="Name" name="name" width="135"/>
<scroll_list.columns label="Eigentümer" name="owner"/>
<scroll_list.columns label="Position" name="location" width="125"/>
+ <scroll_list.columns label="Parzelle" name="parcel"/>
<scroll_list.columns label="Uhrzeit" name="time"/>
- <scroll_list.columns label="Mono-Uhrzeit:" name="mono_time"/>
<scroll_list.columns label="URLs" name="URLs"/>
+ <scroll_list.columns label="Speicher (KB)" name="memory"/>
</scroll_list>
<text name="id_text">
Objekt-ID:
@@ -42,12 +40,16 @@
<button label="Beacon anzeigen" name="show_beacon_btn"/>
<text name="obj_name_text">
Objektname:
- </text>
+ </text>
<button label="Filter" name="filter_object_btn"/>
<text name="owner_name_text">
Eigentümer:
- </text>
+ </text>
<button label="Filter" name="filter_owner_btn"/>
+ <text name="parcel_name_text">
+ Parzelle:
+ </text>
+ <button label="Filtern" name="filter_parcel_btn"/>
<button label="Aktualisieren" name="refresh_btn"/>
<button label="Auswahl zurückgeben" name="return_selected_btn" width="134"/>
<button label="Alle zurückgeben" left="150" name="return_all_btn" width="134"/>
diff --git a/indra/newview/skins/default/xui/de/floater_tos.xml b/indra/newview/skins/default/xui/de/floater_tos.xml
index ba329371f8..ba329371f8 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_tos.xml
+++ b/indra/newview/skins/default/xui/de/floater_tos.xml
diff --git a/indra/newview/skins/default/xui/de/floater_toybox.xml b/indra/newview/skins/default/xui/de/floater_toybox.xml
index 90e50804d6..90e50804d6 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_toybox.xml
+++ b/indra/newview/skins/default/xui/de/floater_toybox.xml
diff --git a/indra/newview/skins/default/xui/de/floater_translation_settings.xml b/indra/newview/skins/default/xui/de/floater_translation_settings.xml
index 3d5d1d46a8..3d5d1d46a8 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_translation_settings.xml
+++ b/indra/newview/skins/default/xui/de/floater_translation_settings.xml
diff --git a/indra/newview/skins/default/xui/de/floater_url_entry.xml b/indra/newview/skins/default/xui/de/floater_url_entry.xml
index f5fa449c85..f5fa449c85 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_url_entry.xml
+++ b/indra/newview/skins/default/xui/de/floater_url_entry.xml
diff --git a/indra/newview/skins/default/xui/de/floater_voice_chat_volume.xml b/indra/newview/skins/default/xui/de/floater_voice_chat_volume.xml
new file mode 100644
index 0000000000..15259639e8
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/floater_voice_chat_volume.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="floater_voice_volume" title="VOICE-CHAT-LAUTSTÄRKE">
+ <slider label="Voice-Chat" name="chat_voice_volume"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/de/floater_voice_controls.xml b/indra/newview/skins/default/xui/de/floater_voice_controls.xml
index 5efda4136e..5efda4136e 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_voice_controls.xml
+++ b/indra/newview/skins/default/xui/de/floater_voice_controls.xml
diff --git a/indra/newview/skins/default/xui/de/floater_voice_effect.xml b/indra/newview/skins/default/xui/de/floater_voice_effect.xml
index 413a46525c..8d37950480 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_voice_effect.xml
+++ b/indra/newview/skins/default/xui/de/floater_voice_effect.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater label="Orte" name="voice_effects" title="VOICE MORPHING">
+<floater label="Orte" name="voice_effects" title="VOICE-MORPHING-VORSCHAU">
<string name="no_voice_effect">
(Kein Voice-Morphing)
</string>
diff --git a/indra/newview/skins/default/xui/de/floater_voice_volume.xml b/indra/newview/skins/default/xui/de/floater_voice_volume.xml
new file mode 100644
index 0000000000..258627c94f
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/floater_voice_volume.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<!--
+ Not can_close / no title to avoid window chrome
+ Single instance - only have one at a time, recycle it each spawn
+-->
+<floater name="floater_voice_volume" title="LAUTSTÄRKE">
+ <slider name="volume_slider" tool_tip="Lautstärke" value="0.5"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/de/floater_web_content.xml b/indra/newview/skins/default/xui/de/floater_web_content.xml
index 6ab119eeab..6ab119eeab 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_web_content.xml
+++ b/indra/newview/skins/default/xui/de/floater_web_content.xml
diff --git a/indra/newview/skins/default/xui/de/floater_whitelist_entry.xml b/indra/newview/skins/default/xui/de/floater_whitelist_entry.xml
index 1332509529..1332509529 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_whitelist_entry.xml
+++ b/indra/newview/skins/default/xui/de/floater_whitelist_entry.xml
diff --git a/indra/newview/skins/default/xui/de/floater_window_size.xml b/indra/newview/skins/default/xui/de/floater_window_size.xml
index a2a53e0567..6502f002a1 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_window_size.xml
+++ b/indra/newview/skins/default/xui/de/floater_window_size.xml
@@ -7,10 +7,17 @@
Fenstergröße einstellen:
</text>
<combo_box name="window_size_combo" tool_tip="Breite x Höhe">
- <combo_box.item label="1000 x 700 (Standard)" name="item0"/>
- <combo_box.item label="1024 x 768" name="item1"/>
- <combo_box.item label="1280 x 720 (720p)" name="item2"/>
- <combo_box.item label="1920 x 1080 (1080p)" name="item3"/>
+ <combo_box.item label="1000 x 700 (Standard)" name="item1"/>
+ <combo_box.item label="1024 x 768 (4:3 XGA)" name="item2"/>
+ <combo_box.item label="1280 x 720 (16:9 HDTV)" name="item3"/>
+ <combo_box.item label="1280 x 800 (5:8 WXGA)" name="item4"/>
+ <combo_box.item label="1280 x 1024 (5:4 SXGA)" name="item5"/>
+ <combo_box.item label="1440 x 900 (8:5 WSXGA)" name="item7"/>
+ <combo_box.item label="1600 x 900 (16:9 HD+)" name="item8"/>
+ <combo_box.item label="1600 x 1200 (4:3 UXGA)" name="item9"/>
+ <combo_box.item label="1680 x 1050 (8:5 WSXGA+)" name="item10"/>
+ <combo_box.item label="1920 x 1080 (16:9 HDTV)" name="item11"/>
+ <combo_box.item label="1920 x 1200 (8:5 WUXGA)" name="item12"/>
</combo_box>
<button label="Festlegen" name="set_btn"/>
<button label="Abbrechen" name="cancel_btn"/>
diff --git a/indra/newview/skins/default/xui/de/floater_world_map.xml b/indra/newview/skins/default/xui/de/floater_world_map.xml
index befa46651a..befa46651a 100644..100755
--- a/indra/newview/skins/default/xui/de/floater_world_map.xml
+++ b/indra/newview/skins/default/xui/de/floater_world_map.xml
diff --git a/indra/newview/skins/default/xui/de/inspect_avatar.xml b/indra/newview/skins/default/xui/de/inspect_avatar.xml
index 4b8fd8a0ad..4b8fd8a0ad 100644..100755
--- a/indra/newview/skins/default/xui/de/inspect_avatar.xml
+++ b/indra/newview/skins/default/xui/de/inspect_avatar.xml
diff --git a/indra/newview/skins/default/xui/de/inspect_group.xml b/indra/newview/skins/default/xui/de/inspect_group.xml
index 60fa8ff0d8..60fa8ff0d8 100644..100755
--- a/indra/newview/skins/default/xui/de/inspect_group.xml
+++ b/indra/newview/skins/default/xui/de/inspect_group.xml
diff --git a/indra/newview/skins/default/xui/de/inspect_object.xml b/indra/newview/skins/default/xui/de/inspect_object.xml
index 72b8235828..72b8235828 100644..100755
--- a/indra/newview/skins/default/xui/de/inspect_object.xml
+++ b/indra/newview/skins/default/xui/de/inspect_object.xml
diff --git a/indra/newview/skins/default/xui/de/inspect_remote_object.xml b/indra/newview/skins/default/xui/de/inspect_remote_object.xml
index 9fe05455eb..9fe05455eb 100644..100755
--- a/indra/newview/skins/default/xui/de/inspect_remote_object.xml
+++ b/indra/newview/skins/default/xui/de/inspect_remote_object.xml
diff --git a/indra/newview/skins/default/xui/de/language_settings.xml b/indra/newview/skins/default/xui/de/language_settings.xml
index f9346eef7d..f9346eef7d 100644..100755
--- a/indra/newview/skins/default/xui/de/language_settings.xml
+++ b/indra/newview/skins/default/xui/de/language_settings.xml
diff --git a/indra/newview/skins/default/xui/de/menu_add_wearable_gear.xml b/indra/newview/skins/default/xui/de/menu_add_wearable_gear.xml
index f3775a05ec..f3775a05ec 100644..100755
--- a/indra/newview/skins/default/xui/de/menu_add_wearable_gear.xml
+++ b/indra/newview/skins/default/xui/de/menu_add_wearable_gear.xml
diff --git a/indra/newview/skins/default/xui/de/menu_attachment_other.xml b/indra/newview/skins/default/xui/de/menu_attachment_other.xml
index 237c92f7d2..4c125c8b5d 100644..100755
--- a/indra/newview/skins/default/xui/de/menu_attachment_other.xml
+++ b/indra/newview/skins/default/xui/de/menu_attachment_other.xml
@@ -11,7 +11,9 @@
<menu_item_call label="Einfrieren" name="Freeze..."/>
<menu_item_call label="Hinauswerfen" name="Eject..."/>
<menu_item_call label="Fehler in Texturen beseitigen" name="Debug..."/>
+ <menu_item_call label="XML ausgeben" name="Dump XML"/>
<menu_item_call label="Hineinzoomen" name="Zoom In"/>
<menu_item_call label="Bezahlen" name="Pay..."/>
<menu_item_call label="Objektprofil" name="Object Inspect"/>
+ <menu_item_call label="Partikeleigentümer blockieren" name="Mute Particle"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/de/menu_attachment_self.xml b/indra/newview/skins/default/xui/de/menu_attachment_self.xml
index 325d52a22e..7888c7b0a1 100644..100755
--- a/indra/newview/skins/default/xui/de/menu_attachment_self.xml
+++ b/indra/newview/skins/default/xui/de/menu_attachment_self.xml
@@ -12,5 +12,7 @@
<menu_item_call label="Meine Gruppen" name="Groups..."/>
<menu_item_call label="Mein Profil" name="Profile..."/>
<menu_item_call label="Fehler in Texturen beseitigen" name="Debug..."/>
+ <menu_item_call label="XML ausgeben" name="Dump XML"/>
<menu_item_call label="Fallen lassen" name="Drop"/>
+ <menu_item_call label="Partikeleigentümer blockieren" name="Mute Particle"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/de/menu_avatar_icon.xml b/indra/newview/skins/default/xui/de/menu_avatar_icon.xml
index c036cf5515..c036cf5515 100644..100755
--- a/indra/newview/skins/default/xui/de/menu_avatar_icon.xml
+++ b/indra/newview/skins/default/xui/de/menu_avatar_icon.xml
diff --git a/indra/newview/skins/default/xui/de/menu_avatar_other.xml b/indra/newview/skins/default/xui/de/menu_avatar_other.xml
index 8aee0be3d2..65dc054ed5 100644..100755
--- a/indra/newview/skins/default/xui/de/menu_avatar_other.xml
+++ b/indra/newview/skins/default/xui/de/menu_avatar_other.xml
@@ -11,6 +11,8 @@
<menu_item_call label="Einfrieren" name="Freeze..."/>
<menu_item_call label="Hinauswerfen" name="Eject..."/>
<menu_item_call label="Fehler in Texturen beseitigen" name="Debug..."/>
+ <menu_item_call label="XML ausgeben" name="Dump XML"/>
<menu_item_call label="Hineinzoomen" name="Zoom In"/>
<menu_item_call label="Bezahlen" name="Pay..."/>
+ <menu_item_call label="Partikeleigentümer blockieren" name="Mute Particle"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/de/menu_avatar_self.xml b/indra/newview/skins/default/xui/de/menu_avatar_self.xml
index c49f4b198b..022cd8c3ca 100644..100755
--- a/indra/newview/skins/default/xui/de/menu_avatar_self.xml
+++ b/indra/newview/skins/default/xui/de/menu_avatar_self.xml
@@ -29,4 +29,6 @@
<menu_item_call label="Meine Gruppen" name="Groups..."/>
<menu_item_call label="Mein Profil" name="Profile..."/>
<menu_item_call label="Fehler in Texturen beseitigen" name="Debug..."/>
+ <menu_item_call label="XML ausgeben" name="Dump XML"/>
+ <menu_item_call label="Partikeleigentümer blockieren" name="Mute Particle"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/de/menu_bottomtray.xml b/indra/newview/skins/default/xui/de/menu_bottomtray.xml
deleted file mode 100644
index cb0082f944..0000000000
--- a/indra/newview/skins/default/xui/de/menu_bottomtray.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<menu name="hide_camera_move_controls_menu">
- <menu_item_check label="Schaltfläche „Sprechen“" name="EnableVoiceChat"/>
- <menu_item_check label="Schaltfläche Gesten" name="ShowGestureButton"/>
- <menu_item_check label="Schaltfläche Bewegungssteuerung" name="ShowMoveButton"/>
- <menu_item_check label="Schaltfläche Ansicht" name="ShowCameraButton"/>
- <menu_item_check label="Schaltfläche Foto" name="ShowSnapshotButton"/>
- <menu_item_check label="Schaltfläche „Bauen“" name="ShowBuildButton"/>
- <menu_item_check label="Schaltfläche „Suchen“" name="ShowSearchButton"/>
- <menu_item_check label="Schaltfläche „Karte“" name="ShowWorldMapButton"/>
- <menu_item_check label="Minikarten-Schaltfläche" name="ShowMiniMapButton"/>
- <menu_item_call label="Ausschneiden" name="NearbyChatBar_Cut"/>
- <menu_item_call label="Kopieren" name="NearbyChatBar_Copy"/>
- <menu_item_call label="Einfügen" name="NearbyChatBar_Paste"/>
- <menu_item_call label="Löschen" name="NearbyChatBar_Delete"/>
- <menu_item_call label="Alle auswählen" name="NearbyChatBar_Select_All"/>
-</menu>
diff --git a/indra/newview/skins/default/xui/de/menu_cof_attachment.xml b/indra/newview/skins/default/xui/de/menu_cof_attachment.xml
index 05d3dfca9d..05d3dfca9d 100644..100755
--- a/indra/newview/skins/default/xui/de/menu_cof_attachment.xml
+++ b/indra/newview/skins/default/xui/de/menu_cof_attachment.xml
diff --git a/indra/newview/skins/default/xui/de/menu_cof_body_part.xml b/indra/newview/skins/default/xui/de/menu_cof_body_part.xml
index 07960a525c..07960a525c 100644..100755
--- a/indra/newview/skins/default/xui/de/menu_cof_body_part.xml
+++ b/indra/newview/skins/default/xui/de/menu_cof_body_part.xml
diff --git a/indra/newview/skins/default/xui/de/menu_cof_clothing.xml b/indra/newview/skins/default/xui/de/menu_cof_clothing.xml
index 7fced273a7..7fced273a7 100644..100755
--- a/indra/newview/skins/default/xui/de/menu_cof_clothing.xml
+++ b/indra/newview/skins/default/xui/de/menu_cof_clothing.xml
diff --git a/indra/newview/skins/default/xui/de/menu_cof_gear.xml b/indra/newview/skins/default/xui/de/menu_cof_gear.xml
index 54b218d22f..2dd871b2ea 100644..100755
--- a/indra/newview/skins/default/xui/de/menu_cof_gear.xml
+++ b/indra/newview/skins/default/xui/de/menu_cof_gear.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<menu name="Gear COF">
+<toggleable_menu name="Gear COF">
<menu label="Neue Kleider" name="COF.Gear.New_Clothes"/>
- <menu label="Neue Körperteile" name="COF.Geear.New_Body_Parts"/>
-</menu>
+ <menu label="Neue Körperteile" name="COF.Gear.New_Body_Parts"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/de/menu_conversation.xml b/indra/newview/skins/default/xui/de/menu_conversation.xml
new file mode 100644
index 0000000000..bdfa66c23b
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/menu_conversation.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_conversation_participant">
+ <menu_item_call label="Unterhaltung schließen" name="close_conversation"/>
+ <menu_item_call label="Unterhaltung öffnen" name="open_voice_conversation"/>
+ <menu_item_call label="Voice-Verbindung trennen" name="disconnect_from_voice"/>
+ <menu_item_call label="Ausgewählte schließen" name="close_selected_conversations"/>
+ <menu_item_call label="Profil anzeigen" name="view_profile"/>
+ <menu_item_call label="IM" name="im"/>
+ <menu_item_call label="Teleport anbieten" name="offer_teleport"/>
+ <menu_item_call label="Voice-Anruf" name="voice_call"/>
+ <menu_item_call label="Chatverlauf..." name="chat_history"/>
+ <menu_item_call label="Freund hinzufügen" name="add_friend"/>
+ <menu_item_call label="Freund entfernen" name="remove_friend"/>
+ <menu_item_call label="Freunde entfernen" name="remove_friends"/>
+ <menu_item_call label="In Gruppe einladen..." name="invite_to_group"/>
+ <menu_item_call label="Hineinzoomen" name="zoom_in"/>
+ <menu_item_call label="Karte" name="map"/>
+ <menu_item_call label="Freigeben" name="share"/>
+ <menu_item_call label="Bezahlen" name="pay"/>
+ <menu_item_check label="Voice ignorieren" name="block_unblock"/>
+ <menu_item_check label="Text ignorieren" name="MuteText"/>
+ <menu_item_call label="Gruppenprofil" name="group_profile"/>
+ <menu_item_call label="Gruppe aktivieren" name="activate_group"/>
+ <menu_item_call label="Gruppe verlassen" name="leave_group"/>
+ <context_menu label="Moderatoroptionen" name="Moderator Options">
+ <menu_item_check label="Text-Chat zulassen" name="AllowTextChat"/>
+ <menu_item_call label="Diesen Teilnehmer stummschalten" name="ModerateVoiceMuteSelected"/>
+ <menu_item_call label="Stummschaltung für diesen Teilnehmer aufheben" name="ModerateVoiceUnMuteSelected"/>
+ <menu_item_call label="Alle stummschalten" name="ModerateVoiceMute"/>
+ <menu_item_call label="Stummschaltung für alle aufheben" name="ModerateVoiceUnmute"/>
+ </context_menu>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/de/menu_conversation_log_gear.xml b/indra/newview/skins/default/xui/de/menu_conversation_log_gear.xml
new file mode 100644
index 0000000000..2ef8762128
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/menu_conversation_log_gear.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="Conversation Context Menu">
+ <menu_item_call label="IM..." name="IM"/>
+ <menu_item_call label="Voice-Anruf..." name="Call"/>
+ <menu_item_call label="Chatverlauf öffnen..." name="Chat history"/>
+ <menu_item_call label="Profil anzeigen" name="View Profile"/>
+ <menu_item_call label="Teleport anbieten" name="teleport"/>
+ <menu_item_call label="Freund hinzufügen" name="add_friend"/>
+ <menu_item_call label="Freund entfernen" name="remove_friend"/>
+ <menu_item_call label="In Gruppe einladen..." name="Invite"/>
+ <menu_item_call label="Karte" name="Map"/>
+ <menu_item_call label="Freigeben" name="Share"/>
+ <menu_item_call label="Bezahlen" name="Pay"/>
+ <menu_item_check label="Ignorieren/Nicht mehr ignorieren" name="Block/Unblock"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/de/menu_conversation_log_view.xml b/indra/newview/skins/default/xui/de/menu_conversation_log_view.xml
new file mode 100644
index 0000000000..ae3cc5bc97
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/menu_conversation_log_view.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_conversation_view">
+ <menu_item_check label="Nach Namen sortieren" name="sort_by_name"/>
+ <menu_item_check label="Nach Datum sortieren" name="sort_by_date"/>
+ <menu_item_check label="Freunde oben anzeigen" name="sort_by_friends"/>
+ <menu_item_call label="Verlaufsliste für „Chat in der Nähe“ anzeigen..." name="view_nearby_chat_history"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/de/menu_edit.xml b/indra/newview/skins/default/xui/de/menu_edit.xml
index 37f68d68d5..37f68d68d5 100644..100755
--- a/indra/newview/skins/default/xui/de/menu_edit.xml
+++ b/indra/newview/skins/default/xui/de/menu_edit.xml
diff --git a/indra/newview/skins/default/xui/de/menu_favorites.xml b/indra/newview/skins/default/xui/de/menu_favorites.xml
index 0d0491d2eb..0d0491d2eb 100644..100755
--- a/indra/newview/skins/default/xui/de/menu_favorites.xml
+++ b/indra/newview/skins/default/xui/de/menu_favorites.xml
diff --git a/indra/newview/skins/default/xui/de/menu_gesture_gear.xml b/indra/newview/skins/default/xui/de/menu_gesture_gear.xml
index 953c0eeed5..953c0eeed5 100644..100755
--- a/indra/newview/skins/default/xui/de/menu_gesture_gear.xml
+++ b/indra/newview/skins/default/xui/de/menu_gesture_gear.xml
diff --git a/indra/newview/skins/default/xui/de/menu_group_plus.xml b/indra/newview/skins/default/xui/de/menu_group_plus.xml
index 583ee793be..583ee793be 100644..100755
--- a/indra/newview/skins/default/xui/de/menu_group_plus.xml
+++ b/indra/newview/skins/default/xui/de/menu_group_plus.xml
diff --git a/indra/newview/skins/default/xui/de/menu_hide_navbar.xml b/indra/newview/skins/default/xui/de/menu_hide_navbar.xml
index 33d55e85bd..33d55e85bd 100644..100755
--- a/indra/newview/skins/default/xui/de/menu_hide_navbar.xml
+++ b/indra/newview/skins/default/xui/de/menu_hide_navbar.xml
diff --git a/indra/newview/skins/default/xui/de/menu_im_conversation.xml b/indra/newview/skins/default/xui/de/menu_im_conversation.xml
new file mode 100644
index 0000000000..875524b19d
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/menu_im_conversation.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="Conversation Gear Menu">
+ <menu_item_call label="Profil anzeigen" name="View Profile"/>
+ <menu_item_call label="Freund hinzufügen" name="Add Friend"/>
+ <menu_item_call label="Freund entfernen" name="remove_friend"/>
+ <menu_item_call label="Teleport anbieten" name="offer_teleport"/>
+ <menu_item_call label="In Gruppe einladen..." name="invite_to_group"/>
+ <menu_item_call label="Chatverlauf..." name="chat_history"/>
+ <menu_item_call label="Hineinzoomen" name="zoom_in"/>
+ <menu_item_call label="Karte" name="map"/>
+ <menu_item_call label="Freigeben" name="Share"/>
+ <menu_item_call label="Bezahlen" name="Pay"/>
+ <menu_item_check label="Voice ignorieren" name="Block/Unblock"/>
+ <menu_item_check label="Text ignorieren" name="MuteText"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/de/menu_im_session_showmodes.xml b/indra/newview/skins/default/xui/de/menu_im_session_showmodes.xml
new file mode 100644
index 0000000000..48f62d29a1
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/menu_im_session_showmodes.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_modes">
+ <menu_item_check label="Kompaktansicht" name="compact_view"/>
+ <menu_item_check label="Erweiterte Ansicht" name="expanded_view"/>
+ <menu_item_check label="Zeit anzeigen" name="IMShowTime"/>
+ <menu_item_check label="Namen in privaten Unterhaltungen anzeigen" name="IMShowNamesForP2PConv"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/de/menu_im_well_button.xml b/indra/newview/skins/default/xui/de/menu_im_well_button.xml
deleted file mode 100644
index f464b71f4a..0000000000
--- a/indra/newview/skins/default/xui/de/menu_im_well_button.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<context_menu name="IM Well Button Context Menu">
- <menu_item_call label="Alle schließen" name="Close All"/>
-</context_menu>
diff --git a/indra/newview/skins/default/xui/de/menu_imchiclet_adhoc.xml b/indra/newview/skins/default/xui/de/menu_imchiclet_adhoc.xml
index 11f93f47b4..11f93f47b4 100644..100755
--- a/indra/newview/skins/default/xui/de/menu_imchiclet_adhoc.xml
+++ b/indra/newview/skins/default/xui/de/menu_imchiclet_adhoc.xml
diff --git a/indra/newview/skins/default/xui/de/menu_imchiclet_group.xml b/indra/newview/skins/default/xui/de/menu_imchiclet_group.xml
index 81ef3b6569..81ef3b6569 100644..100755
--- a/indra/newview/skins/default/xui/de/menu_imchiclet_group.xml
+++ b/indra/newview/skins/default/xui/de/menu_imchiclet_group.xml
diff --git a/indra/newview/skins/default/xui/de/menu_imchiclet_p2p.xml b/indra/newview/skins/default/xui/de/menu_imchiclet_p2p.xml
index d123238246..d123238246 100644..100755
--- a/indra/newview/skins/default/xui/de/menu_imchiclet_p2p.xml
+++ b/indra/newview/skins/default/xui/de/menu_imchiclet_p2p.xml
diff --git a/indra/newview/skins/default/xui/de/menu_inspect_avatar_gear.xml b/indra/newview/skins/default/xui/de/menu_inspect_avatar_gear.xml
index 641a0ceebe..641a0ceebe 100644..100755
--- a/indra/newview/skins/default/xui/de/menu_inspect_avatar_gear.xml
+++ b/indra/newview/skins/default/xui/de/menu_inspect_avatar_gear.xml
diff --git a/indra/newview/skins/default/xui/de/menu_inspect_object_gear.xml b/indra/newview/skins/default/xui/de/menu_inspect_object_gear.xml
index 73e0029b76..73e0029b76 100644..100755
--- a/indra/newview/skins/default/xui/de/menu_inspect_object_gear.xml
+++ b/indra/newview/skins/default/xui/de/menu_inspect_object_gear.xml
diff --git a/indra/newview/skins/default/xui/de/menu_inspect_self_gear.xml b/indra/newview/skins/default/xui/de/menu_inspect_self_gear.xml
index 5979194bfb..5979194bfb 100644..100755
--- a/indra/newview/skins/default/xui/de/menu_inspect_self_gear.xml
+++ b/indra/newview/skins/default/xui/de/menu_inspect_self_gear.xml
diff --git a/indra/newview/skins/default/xui/de/menu_inv_offer_chiclet.xml b/indra/newview/skins/default/xui/de/menu_inv_offer_chiclet.xml
index 71cff7136b..71cff7136b 100644..100755
--- a/indra/newview/skins/default/xui/de/menu_inv_offer_chiclet.xml
+++ b/indra/newview/skins/default/xui/de/menu_inv_offer_chiclet.xml
diff --git a/indra/newview/skins/default/xui/de/menu_inventory.xml b/indra/newview/skins/default/xui/de/menu_inventory.xml
index 39b3099336..cd2fca313e 100644..100755
--- a/indra/newview/skins/default/xui/de/menu_inventory.xml
+++ b/indra/newview/skins/default/xui/de/menu_inventory.xml
@@ -68,6 +68,7 @@
<menu_item_call label="Systemordner löschen" name="Delete System Folder"/>
<menu_item_call label="Konferenz-Chat starten" name="Conference Chat Folder"/>
<menu_item_call label="Wiedergeben/Abspielen" name="Sound Play"/>
+ <menu_item_call label="SLurl kopieren" name="url_copy"/>
<menu_item_call label="Landmarken-Info" name="About Landmark"/>
<menu_item_call label="Inworld abspielen" name="Animation Play"/>
<menu_item_call label="Lokal abspielen" name="Animation Audition"/>
diff --git a/indra/newview/skins/default/xui/de/menu_inventory_add.xml b/indra/newview/skins/default/xui/de/menu_inventory_add.xml
index af70c08ba1..af70c08ba1 100644..100755
--- a/indra/newview/skins/default/xui/de/menu_inventory_add.xml
+++ b/indra/newview/skins/default/xui/de/menu_inventory_add.xml
diff --git a/indra/newview/skins/default/xui/de/menu_inventory_gear_default.xml b/indra/newview/skins/default/xui/de/menu_inventory_gear_default.xml
index 48dec3e856..48dec3e856 100644..100755
--- a/indra/newview/skins/default/xui/de/menu_inventory_gear_default.xml
+++ b/indra/newview/skins/default/xui/de/menu_inventory_gear_default.xml
diff --git a/indra/newview/skins/default/xui/de/menu_land.xml b/indra/newview/skins/default/xui/de/menu_land.xml
index de679da3d8..0bbf8c666e 100644..100755
--- a/indra/newview/skins/default/xui/de/menu_land.xml
+++ b/indra/newview/skins/default/xui/de/menu_land.xml
@@ -6,4 +6,5 @@
<menu_item_call label="Pass kaufen" name="Land Buy Pass"/>
<menu_item_call label="Bauen" name="Create"/>
<menu_item_call label="Land bearbeiten" name="Edit Terrain"/>
+ <menu_item_call label="Partikeleigentümer blockieren" name="Mute Particle"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/de/menu_landmark.xml b/indra/newview/skins/default/xui/de/menu_landmark.xml
index 2aff0eec95..2aff0eec95 100644..100755
--- a/indra/newview/skins/default/xui/de/menu_landmark.xml
+++ b/indra/newview/skins/default/xui/de/menu_landmark.xml
diff --git a/indra/newview/skins/default/xui/de/menu_login.xml b/indra/newview/skins/default/xui/de/menu_login.xml
index b43b41a5dc..62358cc5a8 100644..100755
--- a/indra/newview/skins/default/xui/de/menu_login.xml
+++ b/indra/newview/skins/default/xui/de/menu_login.xml
@@ -18,7 +18,13 @@
<menu_item_call label="Servicebedingungen anzeigen" name="TOS"/>
<menu_item_call label="Wichtige Meldung anzeigen" name="Critical"/>
<menu_item_call label="Web Content Floater Debug Test" name="Web Content Floater Debug Test"/>
- <menu label="Protokollierungsstufe festlegen" name="Set Logging Level"/>
+ <menu label="Protokollierungsstufe festlegen" name="Set Logging Level">
+ <menu_item_check label="Debug" name="Debug"/>
+ <menu_item_check label="Info" name="Info"/>
+ <menu_item_check label="Warnung" name="Warning"/>
+ <menu_item_check label="Fehler" name="Error"/>
+ <menu_item_check label="Keine" name="None"/>
+ </menu>
<menu_item_check label="Grid-Auswahl anzeigen" name="Show Grid Picker"/>
<menu_item_call label="Benachrichtigungs-Konsole anzeigen" name="Show Notifications Console"/>
</menu>
diff --git a/indra/newview/skins/default/xui/de/menu_media_ctrl.xml b/indra/newview/skins/default/xui/de/menu_media_ctrl.xml
index 59c1c2ee86..59c1c2ee86 100644..100755
--- a/indra/newview/skins/default/xui/de/menu_media_ctrl.xml
+++ b/indra/newview/skins/default/xui/de/menu_media_ctrl.xml
diff --git a/indra/newview/skins/default/xui/de/menu_mini_map.xml b/indra/newview/skins/default/xui/de/menu_mini_map.xml
index 2e0d72c40c..2e0d72c40c 100644..100755
--- a/indra/newview/skins/default/xui/de/menu_mini_map.xml
+++ b/indra/newview/skins/default/xui/de/menu_mini_map.xml
diff --git a/indra/newview/skins/default/xui/de/menu_mode_change.xml b/indra/newview/skins/default/xui/de/menu_mode_change.xml
deleted file mode 100644
index b8090018b7..0000000000
--- a/indra/newview/skins/default/xui/de/menu_mode_change.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<toggleable_menu name="Mode Change">
- <menu_item_check label="Basis" name="BasicMode"/>
- <menu_item_check label="Erweitert" name="AdvancedMode"/>
-</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/de/menu_model_import_gear_default.xml b/indra/newview/skins/default/xui/de/menu_model_import_gear_default.xml
index e1faeedcde..e1faeedcde 100644..100755
--- a/indra/newview/skins/default/xui/de/menu_model_import_gear_default.xml
+++ b/indra/newview/skins/default/xui/de/menu_model_import_gear_default.xml
diff --git a/indra/newview/skins/default/xui/de/menu_mute_particle.xml b/indra/newview/skins/default/xui/de/menu_mute_particle.xml
new file mode 100644
index 0000000000..ea8ae03ee0
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/menu_mute_particle.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<!-- *NOTE: See also menu_attachment_other.xml -->
+<context_menu name="Mute Particle Pie">
+ <menu_item_call label="Partikeleigentümer blockieren" name="Mute Particle"/>
+</context_menu>
diff --git a/indra/newview/skins/default/xui/de/menu_navbar.xml b/indra/newview/skins/default/xui/de/menu_navbar.xml
index 5175f34b41..5175f34b41 100644..100755
--- a/indra/newview/skins/default/xui/de/menu_navbar.xml
+++ b/indra/newview/skins/default/xui/de/menu_navbar.xml
diff --git a/indra/newview/skins/default/xui/de/menu_nearby_chat.xml b/indra/newview/skins/default/xui/de/menu_nearby_chat.xml
index 99d6428c3f..99d6428c3f 100644..100755
--- a/indra/newview/skins/default/xui/de/menu_nearby_chat.xml
+++ b/indra/newview/skins/default/xui/de/menu_nearby_chat.xml
diff --git a/indra/newview/skins/default/xui/de/menu_notification_well_button.xml b/indra/newview/skins/default/xui/de/menu_notification_well_button.xml
index 0f2784f160..0f2784f160 100644..100755
--- a/indra/newview/skins/default/xui/de/menu_notification_well_button.xml
+++ b/indra/newview/skins/default/xui/de/menu_notification_well_button.xml
diff --git a/indra/newview/skins/default/xui/de/menu_object.xml b/indra/newview/skins/default/xui/de/menu_object.xml
index 412bd3ac04..de2b409678 100644..100755
--- a/indra/newview/skins/default/xui/de/menu_object.xml
+++ b/indra/newview/skins/default/xui/de/menu_object.xml
@@ -10,6 +10,8 @@
<menu_item_call label="Aufstehen" name="Object Stand Up"/>
<menu_item_call label="Objektprofil" name="Object Inspect"/>
<menu_item_call label="Hineinzoomen" name="Zoom In"/>
+ <menu_item_call label="In Linksets anzeigen" name="show_in_linksets"/>
+ <menu_item_call label="In Figuren anzeigen" name="show_in_characters"/>
<context_menu label="Anziehen" name="Put On">
<menu_item_call label="Anziehen" name="Wear"/>
<menu_item_call label="Hinzufügen" name="Add"/>
@@ -26,4 +28,5 @@
<menu_item_call label="Bezahlen" name="Pay..."/>
<menu_item_call label="Kaufen" name="Buy..."/>
<menu_item_call label="Löschen" name="Delete"/>
+ <menu_item_call label="Partikeleigentümer blockieren" name="Mute Particle"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/de/menu_object_icon.xml b/indra/newview/skins/default/xui/de/menu_object_icon.xml
index 8b6c558416..f92fa0f82b 100644..100755
--- a/indra/newview/skins/default/xui/de/menu_object_icon.xml
+++ b/indra/newview/skins/default/xui/de/menu_object_icon.xml
@@ -2,4 +2,6 @@
<menu name="Object Icon Menu">
<menu_item_call label="Objektprofil..." name="Object Profile"/>
<menu_item_call label="Ignorieren..." name="Block"/>
+ <menu_item_call label="Auf Karte anzeigen" name="show_on_map"/>
+ <menu_item_call label="Zu Objektposition teleportieren" name="teleport_to_object"/>
</menu>
diff --git a/indra/newview/skins/default/xui/de/menu_outfit_gear.xml b/indra/newview/skins/default/xui/de/menu_outfit_gear.xml
index d56c93533c..0cf3c09882 100644..100755
--- a/indra/newview/skins/default/xui/de/menu_outfit_gear.xml
+++ b/indra/newview/skins/default/xui/de/menu_outfit_gear.xml
@@ -23,6 +23,8 @@
<menu_item_call label="Neues Haar" name="New Hair"/>
<menu_item_call label="Neue Augen" name="New Eyes"/>
</menu>
+ <menu_item_call label="Alle Ordner erweitern" name="expand"/>
+ <menu_item_call label="Alle Ordner schließen" name="collapse"/>
<menu_item_call label="Outfit neu benennen" name="rename"/>
<menu_item_call label="Outfit löschen" name="delete_outfit"/>
</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/de/menu_outfit_tab.xml b/indra/newview/skins/default/xui/de/menu_outfit_tab.xml
index 32a65c96fc..32a65c96fc 100644..100755
--- a/indra/newview/skins/default/xui/de/menu_outfit_tab.xml
+++ b/indra/newview/skins/default/xui/de/menu_outfit_tab.xml
diff --git a/indra/newview/skins/default/xui/de/menu_participant_list.xml b/indra/newview/skins/default/xui/de/menu_participant_list.xml
index 160f2f97be..160f2f97be 100644..100755
--- a/indra/newview/skins/default/xui/de/menu_participant_list.xml
+++ b/indra/newview/skins/default/xui/de/menu_participant_list.xml
diff --git a/indra/newview/skins/default/xui/de/menu_participant_view.xml b/indra/newview/skins/default/xui/de/menu_participant_view.xml
new file mode 100644
index 0000000000..6ceb9ac4c5
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/menu_participant_view.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="participant_manu_view">
+ <menu_item_check label="Unterhaltungen nach Typ sortieren" name="sort_sessions_by_type"/>
+ <menu_item_check label="Unterhaltungen nach Namen sortieren" name="sort_sessions_by_name"/>
+ <menu_item_check label="Unterhaltungen nach jüngster Aktivität sortieren" name="sort_sessions_by_recent"/>
+ <menu_item_check label="Teilnehmer nach Namen sortieren" name="sort_participants_by_name"/>
+ <menu_item_check label="Teilnehmer nach jüngster Aktivität sortieren" name="sort_participants_by_recent"/>
+ <menu_item_call label="Chat-Einstellungen..." name="chat_preferences"/>
+ <menu_item_call label="Privatsphäre-Einstellungen..." name="privacy_preferences"/>
+ <menu_item_check label="Unterhaltungsprotokoll..." name="Conversation"/>
+ <menu_item_check label="Chat in der Nähe übersetzen" name="Translate_chat"/>
+ <menu_item_check label="Ãœbersetzungseinstellungen..." name="Translation_settings"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/de/menu_people_blocked_gear.xml b/indra/newview/skins/default/xui/de/menu_people_blocked_gear.xml
new file mode 100644
index 0000000000..f69a453e58
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/menu_people_blocked_gear.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_blocked_gear">
+ <menu_item_call label="Nicht mehr ignorieren" name="unblock"/>
+ <menu_item_call label="Profil..." name="profile"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/de/menu_people_blocked_plus.xml b/indra/newview/skins/default/xui/de/menu_people_blocked_plus.xml
new file mode 100644
index 0000000000..041fde139d
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/menu_people_blocked_plus.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_blocked_plus">
+ <menu_item_call label="Einwohner nach Namen ignorieren..." name="block_resident_by_name"/>
+ <menu_item_call label="Objekt nach Namen ignorieren" name="block_object_by_name"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/de/menu_people_blocked_view.xml b/indra/newview/skins/default/xui/de/menu_people_blocked_view.xml
new file mode 100644
index 0000000000..1dae593ebe
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/menu_people_blocked_view.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_blocked_view">
+ <menu_item_check label="Nach Namen sortieren" name="sort_by_name"/>
+ <menu_item_check label="Nach Typ sortieren" name="sort_by_type"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/de/menu_people_friends_view.xml b/indra/newview/skins/default/xui/de/menu_people_friends_view.xml
new file mode 100644
index 0000000000..da4890fe96
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/menu_people_friends_view.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_group_plus">
+ <menu_item_check label="Nach Namen sortieren" name="sort_name"/>
+ <menu_item_check label="Nach Status sortieren" name="sort_status"/>
+ <menu_item_check label="Symbole für Personen anzeigen" name="view_icons"/>
+ <menu_item_check label="Erteilte Genehmigungen anzeigen" name="view_permissions"/>
+ <menu_item_check label="Unterhaltungsprotokoll anzeigen..." name="view_conversation"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/de/menu_people_friends_view_sort.xml b/indra/newview/skins/default/xui/de/menu_people_friends_view_sort.xml
index 84d9d8938c..84d9d8938c 100644..100755
--- a/indra/newview/skins/default/xui/de/menu_people_friends_view_sort.xml
+++ b/indra/newview/skins/default/xui/de/menu_people_friends_view_sort.xml
diff --git a/indra/newview/skins/default/xui/de/menu_people_groups.xml b/indra/newview/skins/default/xui/de/menu_people_groups.xml
index 76225ba241..a69c82d3d8 100644..100755
--- a/indra/newview/skins/default/xui/de/menu_people_groups.xml
+++ b/indra/newview/skins/default/xui/de/menu_people_groups.xml
@@ -2,7 +2,7 @@
<menu name="menu_group_plus">
<menu_item_call label="Info anzeigen" name="View Info"/>
<menu_item_call label="Chat" name="Chat"/>
- <menu_item_call label="Anrufen" name="Call"/>
+ <menu_item_call label="Voice-Anruf" name="Call"/>
<menu_item_call label="Aktivieren" name="Activate"/>
<menu_item_call label="Verlassen" name="Leave"/>
</menu>
diff --git a/indra/newview/skins/default/xui/de/menu_people_groups_view.xml b/indra/newview/skins/default/xui/de/menu_people_groups_view.xml
new file mode 100644
index 0000000000..20386bba56
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/menu_people_groups_view.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_group_plus">
+ <menu_item_check label="Gruppensymbole anzeigen" name="Display Group Icons"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/de/menu_people_groups_view_sort.xml b/indra/newview/skins/default/xui/de/menu_people_groups_view_sort.xml
index b68597d8aa..b68597d8aa 100644..100755
--- a/indra/newview/skins/default/xui/de/menu_people_groups_view_sort.xml
+++ b/indra/newview/skins/default/xui/de/menu_people_groups_view_sort.xml
diff --git a/indra/newview/skins/default/xui/de/menu_people_nearby.xml b/indra/newview/skins/default/xui/de/menu_people_nearby.xml
index 1db964357f..cdbb3ae917 100644..100755
--- a/indra/newview/skins/default/xui/de/menu_people_nearby.xml
+++ b/indra/newview/skins/default/xui/de/menu_people_nearby.xml
@@ -1,13 +1,16 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Avatar Context Menu">
- <menu_item_call label="Profil anzeigen" name="View Profile"/>
- <menu_item_call label="Freund hinzufügen" name="Add Friend"/>
- <menu_item_call label="Freund entfernen" name="Remove Friend"/>
- <menu_item_call label="IM" name="IM"/>
- <menu_item_call label="Anrufen" name="Call"/>
- <menu_item_call label="Karte" name="Map"/>
- <menu_item_call label="Teilen" name="Share"/>
- <menu_item_call label="Bezahlen" name="Pay"/>
- <menu_item_check label="Ignorieren/Freischalten" name="Block/Unblock"/>
- <menu_item_call label="Teleport anbieten" name="teleport"/>
+ <menu_item_call label="Profil anzeigen" name="view_profile"/>
+ <menu_item_call label="IM" name="im"/>
+ <menu_item_call label="Teleport anbieten" name="offer_teleport"/>
+ <menu_item_call label="Voice-Anruf" name="voice_call"/>
+ <menu_item_call label="Chatverlauf anzeigen..." name="chat_history"/>
+ <menu_item_call label="Freund hinzufügen" name="add_friend"/>
+ <menu_item_call label="Freund entfernen" name="remove_friend"/>
+ <menu_item_call label="In Gruppe einladen..." name="invite_to_group"/>
+ <menu_item_call label="Hineinzoomen" name="zoom_in"/>
+ <menu_item_call label="Karte" name="map"/>
+ <menu_item_call label="Freigeben" name="share"/>
+ <menu_item_call label="Bezahlen" name="pay"/>
+ <menu_item_check label="Ignorieren/Nicht mehr ignorieren" name="block_unblock"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/de/menu_people_nearby_multiselect.xml b/indra/newview/skins/default/xui/de/menu_people_nearby_multiselect.xml
index b6e99edfe1..ba6578e2d1 100644..100755
--- a/indra/newview/skins/default/xui/de/menu_people_nearby_multiselect.xml
+++ b/indra/newview/skins/default/xui/de/menu_people_nearby_multiselect.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Multi-Selected People Context Menu">
- <menu_item_call label="Freunde hinzufügen" name="Add Friends"/>
- <menu_item_call label="Freunde entfernen" name="Remove Friend"/>
- <menu_item_call label="IM" name="IM"/>
- <menu_item_call label="Anrufen" name="Call"/>
- <menu_item_call label="Teilen" name="Share"/>
- <menu_item_call label="Bezahlen" name="Pay"/>
- <menu_item_call label="Teleport anbieten" name="teleport"/>
+ <menu_item_call label="Freunde hinzufügen" name="add_friends"/>
+ <menu_item_call label="Freunde entfernen" name="remove_friends"/>
+ <menu_item_call label="IM" name="im"/>
+ <menu_item_call label="Anrufen" name="call"/>
+ <menu_item_call label="Freigeben" name="share"/>
+ <menu_item_call label="Bezahlen" name="pay"/>
+ <menu_item_call label="Teleport anbieten" name="offer_teleport"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/de/menu_people_nearby_view.xml b/indra/newview/skins/default/xui/de/menu_people_nearby_view.xml
new file mode 100644
index 0000000000..d38ec65037
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/menu_people_nearby_view.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_group_plus">
+ <menu_item_check label="Nach letzten Sprechern sortieren" name="sort_by_recent_speakers"/>
+ <menu_item_check label="Nach Namen sortieren" name="sort_name"/>
+ <menu_item_check label="Nach Nähe sortieren" name="sort_distance"/>
+ <menu_item_check label="Symbole für Personen anzeigen" name="view_icons"/>
+ <menu_item_check label="Karte anzeigen" name="view_map"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/de/menu_people_nearby_view_sort.xml b/indra/newview/skins/default/xui/de/menu_people_nearby_view_sort.xml
index a001544f3e..a001544f3e 100644..100755
--- a/indra/newview/skins/default/xui/de/menu_people_nearby_view_sort.xml
+++ b/indra/newview/skins/default/xui/de/menu_people_nearby_view_sort.xml
diff --git a/indra/newview/skins/default/xui/de/menu_people_recent_view.xml b/indra/newview/skins/default/xui/de/menu_people_recent_view.xml
new file mode 100644
index 0000000000..a116ad0bc1
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/menu_people_recent_view.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_group_plus">
+ <menu_item_check label="Nach jüngsten sortieren" name="sort_most"/>
+ <menu_item_check label="Nach Namen sortieren" name="sort_name"/>
+ <menu_item_check label="Symbole für Personen anzeigen" name="view_icons"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/de/menu_people_recent_view_sort.xml b/indra/newview/skins/default/xui/de/menu_people_recent_view_sort.xml
index 1ef020f5e1..1ef020f5e1 100644..100755
--- a/indra/newview/skins/default/xui/de/menu_people_recent_view_sort.xml
+++ b/indra/newview/skins/default/xui/de/menu_people_recent_view_sort.xml
diff --git a/indra/newview/skins/default/xui/de/menu_picks.xml b/indra/newview/skins/default/xui/de/menu_picks.xml
index 9aec4c83b0..9aec4c83b0 100644..100755
--- a/indra/newview/skins/default/xui/de/menu_picks.xml
+++ b/indra/newview/skins/default/xui/de/menu_picks.xml
diff --git a/indra/newview/skins/default/xui/de/menu_picks_plus.xml b/indra/newview/skins/default/xui/de/menu_picks_plus.xml
index 385ff25b95..385ff25b95 100644..100755
--- a/indra/newview/skins/default/xui/de/menu_picks_plus.xml
+++ b/indra/newview/skins/default/xui/de/menu_picks_plus.xml
diff --git a/indra/newview/skins/default/xui/de/menu_place.xml b/indra/newview/skins/default/xui/de/menu_place.xml
index d9c85f5b92..d9c85f5b92 100644..100755
--- a/indra/newview/skins/default/xui/de/menu_place.xml
+++ b/indra/newview/skins/default/xui/de/menu_place.xml
diff --git a/indra/newview/skins/default/xui/de/menu_place_add_button.xml b/indra/newview/skins/default/xui/de/menu_place_add_button.xml
index 7c0ff4a46a..7c0ff4a46a 100644..100755
--- a/indra/newview/skins/default/xui/de/menu_place_add_button.xml
+++ b/indra/newview/skins/default/xui/de/menu_place_add_button.xml
diff --git a/indra/newview/skins/default/xui/de/menu_places_gear_folder.xml b/indra/newview/skins/default/xui/de/menu_places_gear_folder.xml
index 892f075d3c..892f075d3c 100644..100755
--- a/indra/newview/skins/default/xui/de/menu_places_gear_folder.xml
+++ b/indra/newview/skins/default/xui/de/menu_places_gear_folder.xml
diff --git a/indra/newview/skins/default/xui/de/menu_places_gear_landmark.xml b/indra/newview/skins/default/xui/de/menu_places_gear_landmark.xml
index 8955f797a2..8955f797a2 100644..100755
--- a/indra/newview/skins/default/xui/de/menu_places_gear_landmark.xml
+++ b/indra/newview/skins/default/xui/de/menu_places_gear_landmark.xml
diff --git a/indra/newview/skins/default/xui/de/menu_profile_overflow.xml b/indra/newview/skins/default/xui/de/menu_profile_overflow.xml
index 9f3fcbca1d..9f3fcbca1d 100644..100755
--- a/indra/newview/skins/default/xui/de/menu_profile_overflow.xml
+++ b/indra/newview/skins/default/xui/de/menu_profile_overflow.xml
diff --git a/indra/newview/skins/default/xui/de/menu_save_outfit.xml b/indra/newview/skins/default/xui/de/menu_save_outfit.xml
index 986c78b318..986c78b318 100644..100755
--- a/indra/newview/skins/default/xui/de/menu_save_outfit.xml
+++ b/indra/newview/skins/default/xui/de/menu_save_outfit.xml
diff --git a/indra/newview/skins/default/xui/de/menu_script_chiclet.xml b/indra/newview/skins/default/xui/de/menu_script_chiclet.xml
index 3256aa1a87..3256aa1a87 100644..100755
--- a/indra/newview/skins/default/xui/de/menu_script_chiclet.xml
+++ b/indra/newview/skins/default/xui/de/menu_script_chiclet.xml
diff --git a/indra/newview/skins/default/xui/de/menu_slurl.xml b/indra/newview/skins/default/xui/de/menu_slurl.xml
index b2ec017f9f..b2ec017f9f 100644..100755
--- a/indra/newview/skins/default/xui/de/menu_slurl.xml
+++ b/indra/newview/skins/default/xui/de/menu_slurl.xml
diff --git a/indra/newview/skins/default/xui/de/menu_teleport_history_gear.xml b/indra/newview/skins/default/xui/de/menu_teleport_history_gear.xml
index 68b8e21802..68b8e21802 100644..100755
--- a/indra/newview/skins/default/xui/de/menu_teleport_history_gear.xml
+++ b/indra/newview/skins/default/xui/de/menu_teleport_history_gear.xml
diff --git a/indra/newview/skins/default/xui/de/menu_teleport_history_item.xml b/indra/newview/skins/default/xui/de/menu_teleport_history_item.xml
index ff8fb0b181..ff8fb0b181 100644..100755
--- a/indra/newview/skins/default/xui/de/menu_teleport_history_item.xml
+++ b/indra/newview/skins/default/xui/de/menu_teleport_history_item.xml
diff --git a/indra/newview/skins/default/xui/de/menu_teleport_history_tab.xml b/indra/newview/skins/default/xui/de/menu_teleport_history_tab.xml
index 194dd16fd1..194dd16fd1 100644..100755
--- a/indra/newview/skins/default/xui/de/menu_teleport_history_tab.xml
+++ b/indra/newview/skins/default/xui/de/menu_teleport_history_tab.xml
diff --git a/indra/newview/skins/default/xui/de/menu_text_editor.xml b/indra/newview/skins/default/xui/de/menu_text_editor.xml
index c00186c13e..2e33ed3416 100644..100755
--- a/indra/newview/skins/default/xui/de/menu_text_editor.xml
+++ b/indra/newview/skins/default/xui/de/menu_text_editor.xml
@@ -1,5 +1,12 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Text editor context menu">
+ <menu_item_call label="(unbekannt)" name="Suggestion 1"/>
+ <menu_item_call label="(unbekannt)" name="Suggestion 2"/>
+ <menu_item_call label="(unbekannt)" name="Suggestion 3"/>
+ <menu_item_call label="(unbekannt)" name="Suggestion 4"/>
+ <menu_item_call label="(unbekannt)" name="Suggestion 5"/>
+ <menu_item_call label="Zum Wörterbuch hinzufügen" name="Add to Dictionary"/>
+ <menu_item_call label="Zur Ignorieren-Liste hinzufügen" name="Add to Ignore"/>
<menu_item_call label="Ausschneiden" name="Cut"/>
<menu_item_call label="Kopieren" name="Copy"/>
<menu_item_call label="Einfügen" name="Paste"/>
diff --git a/indra/newview/skins/default/xui/de/menu_toolbars.xml b/indra/newview/skins/default/xui/de/menu_toolbars.xml
index 3fb48e26b2..3fb48e26b2 100644..100755
--- a/indra/newview/skins/default/xui/de/menu_toolbars.xml
+++ b/indra/newview/skins/default/xui/de/menu_toolbars.xml
diff --git a/indra/newview/skins/default/xui/de/menu_topinfobar.xml b/indra/newview/skins/default/xui/de/menu_topinfobar.xml
index 5b0a724244..5b0a724244 100644..100755
--- a/indra/newview/skins/default/xui/de/menu_topinfobar.xml
+++ b/indra/newview/skins/default/xui/de/menu_topinfobar.xml
diff --git a/indra/newview/skins/default/xui/de/menu_url_agent.xml b/indra/newview/skins/default/xui/de/menu_url_agent.xml
index 9a808088fb..ddb072ba8f 100644..100755
--- a/indra/newview/skins/default/xui/de/menu_url_agent.xml
+++ b/indra/newview/skins/default/xui/de/menu_url_agent.xml
@@ -1,6 +1,9 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Url Popup">
- <menu_item_call label="Einwohnerprofil anzeigen" name="show_agent"/>
+ <menu_item_call label="Profil anzeigen" name="show_agent"/>
+ <menu_item_call label="IM senden..." name="send_im"/>
+ <menu_item_call label="Freund hinzufügen..." name="add_friend"/>
+ <menu_item_call label="Freund entfernen..." name="remove_friend"/>
<menu_item_call label="Name in Zwischenablage kopieren" name="url_copy_label"/>
<menu_item_call label="SLurl in die Zwischenablage kopieren" name="url_copy"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/de/menu_url_group.xml b/indra/newview/skins/default/xui/de/menu_url_group.xml
index 6bd86414bc..6bd86414bc 100644..100755
--- a/indra/newview/skins/default/xui/de/menu_url_group.xml
+++ b/indra/newview/skins/default/xui/de/menu_url_group.xml
diff --git a/indra/newview/skins/default/xui/de/menu_url_http.xml b/indra/newview/skins/default/xui/de/menu_url_http.xml
index 30eb1668a5..30eb1668a5 100644..100755
--- a/indra/newview/skins/default/xui/de/menu_url_http.xml
+++ b/indra/newview/skins/default/xui/de/menu_url_http.xml
diff --git a/indra/newview/skins/default/xui/de/menu_url_inventory.xml b/indra/newview/skins/default/xui/de/menu_url_inventory.xml
index dc069df02b..dc069df02b 100644..100755
--- a/indra/newview/skins/default/xui/de/menu_url_inventory.xml
+++ b/indra/newview/skins/default/xui/de/menu_url_inventory.xml
diff --git a/indra/newview/skins/default/xui/de/menu_url_map.xml b/indra/newview/skins/default/xui/de/menu_url_map.xml
index 2f6ffcd450..2f6ffcd450 100644..100755
--- a/indra/newview/skins/default/xui/de/menu_url_map.xml
+++ b/indra/newview/skins/default/xui/de/menu_url_map.xml
diff --git a/indra/newview/skins/default/xui/de/menu_url_objectim.xml b/indra/newview/skins/default/xui/de/menu_url_objectim.xml
index 90d3763d9c..fc01ea8444 100644..100755
--- a/indra/newview/skins/default/xui/de/menu_url_objectim.xml
+++ b/indra/newview/skins/default/xui/de/menu_url_objectim.xml
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Url Popup">
- <menu_item_call label="Objektinformationen anzeigen" name="show_object"/>
+ <menu_item_call label="Objektprofil..." name="show_object"/>
+ <menu_item_call label="Blockieren..." name="block_object"/>
<menu_item_call label="Auf Karte zeigen" name="show_on_map"/>
<menu_item_call label="Zu Objekt-Position teleportieren" name="teleport_to_object"/>
<menu_item_call label="Objektname in Zwischenablage kopieren" name="url_copy_label"/>
diff --git a/indra/newview/skins/default/xui/de/menu_url_parcel.xml b/indra/newview/skins/default/xui/de/menu_url_parcel.xml
index 9169bca24f..9169bca24f 100644..100755
--- a/indra/newview/skins/default/xui/de/menu_url_parcel.xml
+++ b/indra/newview/skins/default/xui/de/menu_url_parcel.xml
diff --git a/indra/newview/skins/default/xui/de/menu_url_slapp.xml b/indra/newview/skins/default/xui/de/menu_url_slapp.xml
index 72e916b902..72e916b902 100644..100755
--- a/indra/newview/skins/default/xui/de/menu_url_slapp.xml
+++ b/indra/newview/skins/default/xui/de/menu_url_slapp.xml
diff --git a/indra/newview/skins/default/xui/de/menu_url_slurl.xml b/indra/newview/skins/default/xui/de/menu_url_slurl.xml
index 5d48230ebf..5d48230ebf 100644..100755
--- a/indra/newview/skins/default/xui/de/menu_url_slurl.xml
+++ b/indra/newview/skins/default/xui/de/menu_url_slurl.xml
diff --git a/indra/newview/skins/default/xui/de/menu_url_teleport.xml b/indra/newview/skins/default/xui/de/menu_url_teleport.xml
index 4cc1ecc70e..4cc1ecc70e 100644..100755
--- a/indra/newview/skins/default/xui/de/menu_url_teleport.xml
+++ b/indra/newview/skins/default/xui/de/menu_url_teleport.xml
diff --git a/indra/newview/skins/default/xui/de/menu_viewer.xml b/indra/newview/skins/default/xui/de/menu_viewer.xml
index d011c7295c..be5d4891d7 100644..100755
--- a/indra/newview/skins/default/xui/de/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/de/menu_viewer.xml
@@ -17,8 +17,8 @@
<menu_item_call label="Gehen/Rennen/Fliegen..." name="Walk / run / fly"/>
</menu>
<menu label="Status" name="Status">
- <menu_item_call label="Abwesend" name="Set Away"/>
- <menu_item_call label="Beschäftigt" name="Set Busy"/>
+ <menu_item_check label="Abwesend" name="Away"/>
+ <menu_item_check label="Nicht stören" name="Do Not Disturb"/>
</menu>
<menu_item_call label="L$ kaufen..." name="Buy and Sell L$"/>
<menu_item_call label="Händler-Outbox..." name="MerchantOutbox"/>
@@ -28,17 +28,25 @@
<menu_item_call label="Einstellungen..." name="Preferences"/>
<menu_item_call label="Symbolleistenschaltflächen..." name="Toolbars"/>
<menu_item_call label="Alle Steuerelemente ausblenden" name="Hide UI"/>
+ <menu_item_check label="HUD-Anhänge anzeigen" name="Show HUD Attachments"/>
<menu_item_call label="[APP_NAME] schließen" name="Quit"/>
</menu>
<menu label="Unterhalten" name="Communicate">
- <menu_item_check label="Chat..." name="Nearby Chat"/>
+ <menu_item_check label="Unterhaltungen..." name="Conversations"/>
+ <menu_item_check label="Chat in der Nähe..." name="Nearby Chat"/>
<menu_item_check label="Sprechen" name="Speak"/>
- <menu_item_check label="Voice-Einstellungen..." name="Nearby Voice"/>
- <menu_item_check label="Voice-Morphing..." name="ShowVoice"/>
+ <menu_item_check label="Unterhaltungsprotokoll..." name="Conversation Log..."/>
+ <menu label="Voice-Morphing" name="VoiceMorphing">
+ <menu_item_check label="Kein Voice-Morphing" name="NoVoiceMorphing"/>
+ <menu_item_check label="Vorschau..." name="Preview"/>
+ <menu_item_call label="Abonnieren..." name="Subscribe"/>
+ </menu>
<menu_item_check label="Gesten..." name="Gestures"/>
- <menu_item_call label="Freunde" name="My Friends"/>
- <menu_item_call label="Gruppen" name="My Groups"/>
- <menu_item_call label="Leute in der Nähe" name="Active Speakers"/>
+ <menu_item_check label="Freunde" name="My Friends"/>
+ <menu_item_check label="Gruppen" name="My Groups"/>
+ <menu_item_check label="Leute in der Nähe" name="Active Speakers"/>
+ <menu_item_call label="Blockierliste" name="Block List"/>
+ <menu_item_check label="Nicht stören" name="Do Not Disturb"/>
</menu>
<menu label="Welt" name="World">
<menu_item_call label="Landmarke für diesen Ort setzen" name="Create Landmark Here"/>
@@ -107,13 +115,13 @@
<menu_item_call label="Nächsten Teil mit einsschließen" name="Include Next Part"/>
<menu_item_call label="Vorherige Teile mit einschließen" name="Include Previous Part"/>
</menu>
+ <menu_item_call label="Linksets..." name="pathfinding_linkset_menu_item"/>
<menu_item_call label="Fokus auf Auswahl" name="Focus on Selection"/>
<menu_item_call label="Auf Auswahl zoomen" name="Zoom to Selection"/>
<menu label="Objekt" name="Object">
<menu_item_call label="Kaufen" name="Menu Object Buy"/>
<menu_item_call label="Nehmen" name="Menu Object Take"/>
<menu_item_call label="Kopie nehmen" name="Take Copy"/>
- <menu_item_call label="Objekt wieder in meinem Inventar speichern" name="Save Object Back to My Inventory"/>
<menu_item_call label="Wieder in Objektinhalt speichern" name="Save Object Back to Object Contents"/>
<menu_item_call label="Objekt zurückgeben" name="Return Object back to Owner"/>
</menu>
@@ -124,6 +132,12 @@
<menu_item_call label="Skripts auf ausführen einstellen" name="Set Scripts to Running"/>
<menu_item_call label="Skripts auf nicht ausführen einstellen" name="Set Scripts to Not Running"/>
</menu>
+ <menu label="Pathfinding" name="Pathfinding">
+ <menu_item_call label="Linksets..." name="pathfinding_linksets_menu_item"/>
+ <menu_item_call label="Figuren..." name="pathfinding_characters_menu_item"/>
+ <menu_item_call label="Anzeigen/Testen..." name="pathfinding_console_menu_item"/>
+ <menu_item_call label="Region neu formen" name="pathfinding_rebake_navmesh_item"/>
+ </menu>
<menu label="Optionen" name="Options">
<menu_item_check label="Erweiterte Berechtigungen anzeigen" name="DebugPermissions"/>
<menu_item_check label="Nur meine Objekte auswählen" name="Select Only My Objects"/>
@@ -152,6 +166,13 @@
<menu label="Hilfe" name="Help">
<menu_item_call label="Anweisungen..." name="How To"/>
<menu_item_call label="[SECOND_LIFE]-Hilfe" name="Second Life Help"/>
+ <menu_item_call label="Benutzerhandbuch" name="User’s guide"/>
+ <menu_item_call label="Knowledge Base" name="Knowledge Base"/>
+ <menu_item_call label="Wiki" name="Wiki"/>
+ <menu_item_call label="Community-Foren" name="Community Forums"/>
+ <menu_item_call label="Support-Portal" name="Support portal"/>
+ <menu_item_call label="[SECOND_LIFE]-Neuigkeiten" name="Second Life News"/>
+ <menu_item_call label="[SECOND_LIFE]-Blogs" name="Second Life Blogs"/>
<menu_item_call label="Missbrauch melden" name="Report Abuse"/>
<menu_item_call label="Fehler melden" name="Report Bug"/>
<menu_item_call label="INFO ÃœBER [APP_NAME]" name="About Second Life"/>
@@ -174,7 +195,6 @@
<menu_item_check label="Partikel ausblenden" name="Hide Particles"/>
<menu_item_check label="Auswahl ausblenden" name="Hide Selected"/>
<menu_item_check label="Durchsichtig hervorheben" name="Highlight Transparent"/>
- <menu_item_check label="HUD-Anhänge anzeigen" name="Show HUD Attachments"/>
<menu_item_check label="Fadenkreuz für Mouselook anzeigen" name="ShowCrosshairs"/>
</menu>
<menu label="Darstellungstypen" name="Rendering Types">
@@ -227,11 +247,10 @@
<menu_item_check label="Textur" name="Texture Console"/>
<menu_item_check label="Fehler beseitigen" name="Debug Console"/>
<menu_item_call label="Meldungen" name="Notifications"/>
- <menu_item_check label="Texturgröße" name="Texture Size"/>
- <menu_item_check label="Texture-Kategorie" name="Texture Category"/>
<menu_item_check label="Schnelle Timer" name="Fast Timers"/>
<menu_item_check label="Speicher" name="Memory"/>
<menu_item_check label="Szenestatistiken" name="Scene Statistics"/>
+ <menu_item_call label="Debug-Konsole für Texturabruffehler" name="Texture Fetch Debug Console"/>
<menu_item_call label="Info zu Region in Fenster Fehler beseitigen" name="Region Info to Debug Console"/>
<menu_item_call label="Gruppeninfo in Fenster Fehler beseitigen" name="Group Info to Debug Console"/>
<menu_item_call label="Info zu Fähigkeiten in Fenster Fehler beseitigen" name="Capabilities Info to Debug Console"/>
@@ -266,6 +285,7 @@
<menu_item_check label="Framerate randomisieren" name="Randomize Framerate"/>
<menu_item_check label="Periodic Slow Frame" name="Periodic Slow Frame"/>
<menu_item_check label="Frame-Test" name="Frame Test"/>
+ <menu_item_call label="Rahmenprofil" name="Frame Profile"/>
</menu>
<menu label="Metadaten darstellen" name="Render Metadata">
<menu_item_check label="Bonding Boxes" name="Bounding Boxes"/>
@@ -289,14 +309,21 @@
<menu_item_check label="Komplexität beim Rendern" name="rendercomplexity"/>
<menu_item_check label="Byte in Anhängen" name="attachment bytes"/>
<menu_item_check label="Formen" name="Sculpt"/>
+ <menu label="Texturdichte" name="Texture Density">
+ <menu_item_check label="Keine" name="None"/>
+ <menu_item_check label="Aktuelle" name="Current"/>
+ <menu_item_check label="Gewünschte" name="Desired"/>
+ <menu_item_check label="Volle" name="Full"/>
+ </menu>
</menu>
<menu label="Rendering" name="Rendering">
<menu_item_check label="Achsen" name="Axes"/>
<menu_item_check label="Tangentenbasis" name="Tangent Basis"/>
<menu_item_call label="Texturinfo für ausgewähltes Objekt" name="Selected Texture Info Basis"/>
+ <menu_item_call label="Ausgewählte Materialinfos" name="Selected Material Info"/>
<menu_item_check label="Wireframe" name="Wireframe"/>
<menu_item_check label="Objekt-Objekt Okklusion" name="Object-Object Occlusion"/>
- <menu_item_check label="Licht und Schatten" name="Lighting and Shadows"/>
+ <menu_item_check label="Erweitertes Beleuchtungsmodell" name="Advanced Lighting Model"/>
<menu_item_check label="Schatten von Sonne-/Mond-Projektoren" name="Shadows from Sun/Moon/Projectors"/>
<menu_item_check label="SSAO und Schattenglättung" name="SSAO and Shadow Smoothing"/>
<menu_item_check label="Fehler in GL beseitigen" name="Debug GL"/>
@@ -306,8 +333,6 @@
<menu_item_check label="Animationstexturen" name="Animation Textures"/>
<menu_item_check label="Texturen deaktivieren" name="Disable Textures"/>
<menu_item_check label="Voll-Res-Texturen" name="Rull Res Textures"/>
- <menu_item_check label="Texturen prüfen" name="Audit Textures"/>
- <menu_item_check label="Textur-Atlas (experimentell)" name="Texture Atlas"/>
<menu_item_check label="Angehängte Lichter rendern" name="Render Attached Lights"/>
<menu_item_check label="Angehängte Partikel rendern" name="Render Attached Particles"/>
<menu_item_check label="Leucht-Objekte schweben lassen" name="Hover Glow Objects"/>
@@ -343,7 +368,6 @@
<menu_item_call label="Fokus ausgeben" name="Dump Focus Holder"/>
<menu_item_call label="Ausgewählte Objektinfo drucken" name="Print Selected Object Info"/>
<menu_item_call label="Agent-Info drucken" name="Print Agent Info"/>
- <menu_item_call label="Speicher-Stats" name="Memory Stats"/>
<menu_item_check label="Regions-Debug-Konsole" name="Region Debug Console"/>
<menu_item_check label="Fehler in SelectMgr beseitigen" name="Debug SelectMgr"/>
<menu_item_check label="Fehler in Klicks beseitigen" name="Debug Clicks"/>
@@ -373,12 +397,10 @@
<menu_item_call label="Avatargeometry ein-/ausschalten" name="Toggle Character Geometry"/>
<menu_item_call label="Männlich testen" name="Test Male"/>
<menu_item_call label="Weiblich testen" name="Test Female"/>
- <menu_item_call label="PG ein-/ausschalten" name="Toggle PG"/>
<menu_item_check label="Avatarauswahl zulassen" name="Allow Select Avatar"/>
</menu>
<menu_item_call label="Param auf Standard erzwingen" name="Force Params to Default"/>
<menu_item_check label="Animations-Info" name="Animation Info"/>
- <menu_item_check label="Zeitlupen-Animationen" name="Slow Motion Animations"/>
<menu_item_check label="Kamerafokus anzeigen" name="Show Look At"/>
<menu_item_check label="Klickpunkt anzeigen??" name="Show Point At"/>
<menu_item_check label="Fehler in Landaktualisierung beseitigen" name="Debug Joint Updates"/>
diff --git a/indra/newview/skins/default/xui/de/menu_wearable_list_item.xml b/indra/newview/skins/default/xui/de/menu_wearable_list_item.xml
index 283e454a06..283e454a06 100644..100755
--- a/indra/newview/skins/default/xui/de/menu_wearable_list_item.xml
+++ b/indra/newview/skins/default/xui/de/menu_wearable_list_item.xml
diff --git a/indra/newview/skins/default/xui/de/menu_wearing_gear.xml b/indra/newview/skins/default/xui/de/menu_wearing_gear.xml
index dacf898b6a..dacf898b6a 100644..100755
--- a/indra/newview/skins/default/xui/de/menu_wearing_gear.xml
+++ b/indra/newview/skins/default/xui/de/menu_wearing_gear.xml
diff --git a/indra/newview/skins/default/xui/de/menu_wearing_tab.xml b/indra/newview/skins/default/xui/de/menu_wearing_tab.xml
index 695451a105..695451a105 100644..100755
--- a/indra/newview/skins/default/xui/de/menu_wearing_tab.xml
+++ b/indra/newview/skins/default/xui/de/menu_wearing_tab.xml
diff --git a/indra/newview/skins/default/xui/de/mime_types.xml b/indra/newview/skins/default/xui/de/mime_types.xml
index de93107e94..de93107e94 100644..100755
--- a/indra/newview/skins/default/xui/de/mime_types.xml
+++ b/indra/newview/skins/default/xui/de/mime_types.xml
diff --git a/indra/newview/skins/default/xui/de/mime_types_linux.xml b/indra/newview/skins/default/xui/de/mime_types_linux.xml
index e4b5c53292..e4b5c53292 100644..100755
--- a/indra/newview/skins/default/xui/de/mime_types_linux.xml
+++ b/indra/newview/skins/default/xui/de/mime_types_linux.xml
diff --git a/indra/newview/skins/default/xui/de/mime_types_mac.xml b/indra/newview/skins/default/xui/de/mime_types_mac.xml
index e4b5c53292..e4b5c53292 100644..100755
--- a/indra/newview/skins/default/xui/de/mime_types_mac.xml
+++ b/indra/newview/skins/default/xui/de/mime_types_mac.xml
diff --git a/indra/newview/skins/default/xui/de/notifications.xml b/indra/newview/skins/default/xui/de/notifications.xml
index ac068fcd4e..b3ae98f633 100644..100755
--- a/indra/newview/skins/default/xui/de/notifications.xml
+++ b/indra/newview/skins/default/xui/de/notifications.xml
@@ -37,6 +37,12 @@
<button name="Help" text="$helptext"/>
</form>
</template>
+ <template name="okhelpignore">
+ <form>
+ <button name="OK_okhelpignore" text="$yestext"/>
+ <button name="Help_okhelpignore" text="$helptext"/>
+ </form>
+ </template>
<template name="yesnocancelbuttons">
<form>
<button name="Yes" text="$yestext"/>
@@ -140,7 +146,7 @@ Wählen Sie ein einzelnes Objekt aus und versuchen Sie es erneut.
<usetemplate canceltext="Abbrechen" name="yesnocancelbuttons" notext="Nicht speichern" yestext="Alles speichern"/>
</notification>
<notification name="FriendsAndGroupsOnly">
- Leute, die nicht auf Ihrer Freundesliste stehen, werden nicht wissen, dass Sie deren Anrufe oder Sofortnachrichten ignoriert haben.
+ Personen, die nicht auf Ihrer Freundesliste stehen, werden nicht informiert, dass Sie ihre Anrufe und Instant Messages ignorieren.
<usetemplate name="okbutton" yestext="Ja"/>
</notification>
<notification name="FavoritesOnLogin">
@@ -210,6 +216,14 @@ Der Rolle „[ROLE_NAME]“ diese Fähigkeit zuweisen?
Der Rolle „[ROLE_NAME]“ diese Fähigkeit zuweisen?
<usetemplate name="okcancelbuttons" notext="Nein" yestext="Ja"/>
</notification>
+ <notification name="EjectGroupMemberWarning">
+ Sie sind dabei, [AVATAR_NAME] aus der Gruppe hinauszuwerfen.
+ <usetemplate ignoretext="Hinauswerfen eines einzelnen Gruppenmitglieds bestätigen" name="okcancelignore" notext="Abbrechen" yestext="Hinauswerfen"/>
+ </notification>
+ <notification name="EjectGroupMembersWarning">
+ Sie sind dabei, [COUNT] Mitglieder aus der Gruppe hinauszuwerfen.
+ <usetemplate ignoretext="Hinauswerfen mehrerer Gruppenmitglieder bestätigen" name="okcancelignore" notext="Abbrechen" yestext="Hinauswerfen"/>
+ </notification>
<notification name="AttachmentDrop">
Sie möchten Ihren Anhang wirklich fallen lassen?
Möchten Sie fortfahren?
@@ -367,13 +381,19 @@ Sie müssen den Benutzernamen Ihres Avatars eingeben.
Sie benötigen ein Konto, um [SECOND_LIFE] betreten zu können. Möchten Sie jetzt ein Konto erstellen?
<url name="url">
- https://join.secondlife.com/index.php?lang=de-DE
+ [create_account_url]
</url>
<usetemplate name="okcancelbuttons" notext="Erneut versuchen" yestext="Neues Benutzerkonto anlegen"/>
</notification>
<notification name="InvalidCredentialFormat">
Sie müssen entweder den Benutzernamen oder den Vor- und Nachnamen Ihres Avatars in das Feld „Benutzername“ eingeben und die Anmeldung dann erneut versuchen.
</notification>
+ <notification name="InvalidGrid">
+ „[GRID]“ ist keine gültige Grid-ID.
+ </notification>
+ <notification name="InvalidLocationSLURL">
+ Ihre Startposition gibt kein gültiges Grid an.
+ </notification>
<notification name="DeleteClassified">
Anzeige „[NAME]“ löschen?
Gebühren werden nicht rückerstattet.
@@ -479,8 +499,8 @@ Das Objekt ist möglicherweise außer Reichweite oder wurde gelöscht.
Ein kompiliertes Skript konnte aus folgendem Grund nicht gespeichert werden: [REASON]. Speichern Sie das Skript bitte später.
</notification>
<notification name="StartRegionEmpty">
- Sie haben keine Start-Region festgelegt.
-Bitte geben Sie den Namen der Region im Feld „Startposition“ ein oder wählen Sie „Mein letzter Standort“ oder „Mein Zuhause“ als Startposition aus.
+ Ihre Startregion ist nicht definiert.
+Geben Sie den Namen der Region im Feld „Startposition“ ein oder wählen Sie „Mein letzter Standort“ oder „Mein Zuhause“ als Startposition aus.
<usetemplate name="okbutton" yestext="OK"/>
</notification>
<notification name="CouldNotStartStopScript">
@@ -502,6 +522,33 @@ Weitere Informationen finden Sie auf [_URL].
</url>
<usetemplate ignoretext="Meine Hardware wird nicht unterstützt" name="okcancelignore" notext="Nein" yestext="Ja"/>
</notification>
+ <notification name="IntelOldDriver">
+ Wahrscheinlich gibt es einen neueren Treiber für Ihren Grafikchip. Durch Aktualisieren der Grafiktreiber lässt sich die Leistung u. U. beträchtlich verbessern.
+
+ Unter [_URL] nach aktualisierten Treibern suchen?
+ <url name="url">
+ http://www.intel.com/p/de_DE/support/detect/graphics
+ </url>
+ <usetemplate ignoretext="Mein Grafiktreiber ist veraltet" name="okcancelignore" notext="Nein" yestext="Ja"/>
+ </notification>
+ <notification name="AMDOldDriver">
+ Wahrscheinlich gibt es einen neueren Treiber für Ihren Grafikchip. Durch Aktualisieren der Grafiktreiber lässt sich die Leistung u. U. beträchtlich verbessern.
+
+ Unter [_URL] nach aktualisierten Treibern suchen?
+ <url name="url">
+ http://support.amd.com/de/Pages/AMDSupportHub.aspx
+ </url>
+ <usetemplate ignoretext="Mein Grafiktreiber ist veraltet" name="okcancelignore" notext="Nein" yestext="Ja"/>
+ </notification>
+ <notification name="NVIDIAOldDriver">
+ Wahrscheinlich gibt es einen neueren Treiber für Ihren Grafikchip. Durch Aktualisieren der Grafiktreiber lässt sich die Leistung u. U. beträchtlich verbessern.
+
+ Unter [_URL] nach aktualisierten Treibern suchen?
+ <url name="url">
+ http://www.nvidia.com/Download/index.aspx?lang=de-de
+ </url>
+ <usetemplate ignoretext="Mein Grafiktreiber ist veraltet" name="okcancelignore" notext="Nein" yestext="Ja"/>
+ </notification>
<notification name="UnknownGPU">
Ihr System verwendet eine Grafikkarte, die [APP_NAME] nicht erkennt.
Dies passiert dann, wenn die neue Hardware noch nicht mit [APP_NAME] getestet wurde. Wahrscheinlich wird das Programm richtig ausgeführt, aber Sie müssen eventuell ein paar Grafikeinstellungen vornehmen.
@@ -598,6 +645,9 @@ Sie können maximal [MAX] Objekte verknüpfen.
Stellen Sie sicher, dass kein Objekt gesperrt ist und alle Objekte Ihnen gehören.
</notification>
+ <notification name="CannotLinkPermanent">
+ Objekte können nicht über Regionsgrenzen hinweg verknüpft werden.
+ </notification>
<notification name="CannotLinkDifferentOwners">
Verknüpfung nicht möglich, da nicht alle Objekte denselben Eigentümer haben.
@@ -982,6 +1032,41 @@ Sie sind nicht berechtigt, Land für die aktive Gruppe zu kaufen.
<button name="Cancel" text="Abbrechen"/>
</form>
</notification>
+ <notification label="Automatische Ersetzungsliste hinzufügen" name="AddAutoReplaceList">
+ Name für neue Liste:
+ <form name="form">
+ <button name="SetName" text="OK"/>
+ </form>
+ </notification>
+ <notification label="Automatische Ersetzungsliste umbenennen" name="RenameAutoReplaceList">
+ Der Name „[DUPNAME]“ wird bereits verwendet.
+ Geben Sie einen neuen eindeutigen Namen ein:
+ <form name="form">
+ <button name="ReplaceList" text="Aktuelle Liste ersetzen"/>
+ <button name="SetName" text="Neuen Namen verwenden"/>
+ </form>
+ </notification>
+ <notification name="InvalidAutoReplaceEntry">
+ Das Schlüsselwort muss ein einziges Wort sein; die Ersetzungszeichenfolge darf nicht leer sein.
+ </notification>
+ <notification name="InvalidAutoReplaceList">
+ Diese Ersetzungsliste ist nicht gültig.
+ </notification>
+ <notification name="SpellingDictImportRequired">
+ Sie müssen eine Datei, einen Namen und eine Sprache angeben.
+ </notification>
+ <notification name="SpellingDictIsSecondary">
+ Das Wörterbuch [DIC_NAME] scheint keine „aff“-Datei zu haben und ist deshalb ein sekundäres Wörterbuch.
+Es kann als zusätzliches Wörterbuch verwendet werden, aber nicht als Hauptwörterbuch.
+
+Weitere Informationen finden Sie unter https://wiki.secondlife.com/wiki/Adding_Spelling_Dictionaries.
+ </notification>
+ <notification name="SpellingDictImportFailed">
+ Kopieren nicht möglich:
+ [FROM_NAME]
+ in
+ [TO_NAME]
+ </notification>
<notification label="Outfit speichern" name="SaveOutfitAs">
Mein aktuelles Outfit als neues Outfit speichern:
<form name="form">
@@ -1047,7 +1132,7 @@ auf ALLEN LÄNDERN in diesem Sim LÖSCHEN?
Geben sie einen höheren Betrag ein.
</notification>
<notification name="ConfirmItemDeleteHasLinks">
- Mindestens eines Ihrer ausgewählten Objekte verfügt über verknüpfte Objekte. Wenn Sie dieses Objekt löschen, funktionieren die Verknüpfungen nicht mehr. Wir empfehlen Ihnen daher, diese Verknüpfungen zuerst zu löschen.
+ Auf mindestens eines der Objekte wird über Verknüpfungen Bezug genommen. Wenn Sie dieses Objekt löschen, funktionieren die Verknüpfungen nicht mehr. Wir empfehlen daher, diese Verknüpfungen zuerst zu löschen.
Möchten Sie diese Objekte wirklich löschen?
<usetemplate name="okcancelbuttons" notext="Abbrechen" yestext="OK"/>
@@ -1065,9 +1150,9 @@ Möchten Sie diese Objekte löschen?
<usetemplate name="okcancelbuttons" notext="Abbrechen" yestext="OK"/>
</notification>
<notification name="ConfirmObjectDeleteNoOwn">
- Mindestens eines der ausgewählten Objekt gehört nicht Ihnen.
+ Mindestens eines der ausgewählten Objekte gehört nicht Ihnen.
-Möchten Sie diese Objekte löschen?
+Möchten Sie diese Objekte wirklich löschen?
<usetemplate name="okcancelbuttons" notext="Abbrechen" yestext="OK"/>
</notification>
<notification name="ConfirmObjectDeleteLockNoCopy">
@@ -1081,14 +1166,14 @@ Möchten Sie diese Objekte löschen?
Mindestens ein Objekt ist gesperrt.
Mindestens ein Objekt gehört nicht Ihnen.
-Möchten Sie diese Objekte löschen?
+Möchten Sie diese Objekte wirklich löschen?
<usetemplate name="okcancelbuttons" notext="Abbrechen" yestext="OK"/>
</notification>
<notification name="ConfirmObjectDeleteNoCopyNoOwn">
Mindestens ein Objekt kann nicht kopiert werden.
Mindestens ein Objekt gehört nicht Ihnen.
-Möchten Sie diese Objekte löschen?
+Möchten Sie diese Objekte wirklich löschen?
<usetemplate name="okcancelbuttons" notext="Abbrechen" yestext="OK"/>
</notification>
<notification name="ConfirmObjectDeleteLockNoCopyNoOwn">
@@ -1096,7 +1181,7 @@ Möchten Sie diese Objekte löschen?
Mindestens ein Objekt kann nicht kopiert werden.
Mindestens ein Objekt gehört nicht Ihnen.
-Möchten Sie diese Objekte löschen?
+Möchten Sie diese Objekte wirklich löschen?
<usetemplate name="okcancelbuttons" notext="Abbrechen" yestext="OK"/>
</notification>
<notification name="ConfirmObjectTakeLock">
@@ -1162,7 +1247,7 @@ in „[THIS_GPU]“
Sie wurden zur nächstgelegenen Region teleportiert.
</notification>
<notification name="AvatarMovedLast">
- Ihr letzter Standort ist zurzeit nicht verfügbar.
+ Ihr angeforderter Standort ist zurzeit nicht verfügbar.
Sie wurden zur nächstgelegenen Region teleportiert.
</notification>
<notification name="AvatarMovedHome">
@@ -1181,8 +1266,7 @@ Sie können [SECOND_LIFE] normal verwenden. Andere Benutzer können Sie korrekt
Installation von [APP_NAME] vollständig abgeschlossen.
Falls Sie [SECOND_LIFE] zum ersten Mal verwenden, müssen Sie zuerst ein Konto erstellen, bevor Sie sich anmelden können.
-Zurück zu [http://join.secondlife.com secondlife.com], um ein neues Konto zu erstellen?
- <usetemplate name="okcancelbuttons" notext="Weiter" yestext="Neues Konto..."/>
+ <usetemplate name="okcancelbuttons" notext="Weiter" yestext="Konto erstellen..."/>
</notification>
<notification name="LoginPacketNeverReceived">
Es gibt Probleme mit der Verbindung. Möglicherweise besteht ein Problem mit Ihrer Internetverbindung oder dem [SECOND_LIFE_GRID].
@@ -1416,13 +1500,43 @@ Version [VERSION] [[RELEASE_NOTES_FULL_URL] Informationen zu diesem Update]
</notification>
<notification name="RequiredUpdateDownloadedVerboseDialog">
Ein erforderliches Softwareupdate wurde heruntergeladen.
-Version [VERSION]
+Version [VERSION] [[INFO_URL] Infos zu diesem Update]
Zur Installation des Updates muss [APP_NAME] neu gestartet werden.
<usetemplate name="okbutton" yestext="OK"/>
</notification>
<notification name="RequiredUpdateDownloadedDialog">
Zur Installation des Updates muss [APP_NAME] neu gestartet werden.
+[[INFO_URL] Infos zu diesem Update]
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
+ <notification name="OtherChannelDownloadBackgroundTip">
+ Für Ihre [APP_NAME]-Installation wurde ein Update heruntergeladen.
+Version [VERSION]
+Dieser experimentelle Viewer wurde durch einen [NEW_CHANNEL] Viewer ersetzt;
+weitere Details zu diesem Update finden Sie [[INFO_URL] hier].
+ <usetemplate name="okcancelbuttons" notext="Später..." yestext="Jetzt installieren und [APP_NAME] neu starten"/>
+ </notification>
+ <notification name="OtherChannelDownloadBackgroundDialog">
+ Für Ihre [APP_NAME]-Installation wurde ein Update heruntergeladen.
+Version [VERSION]
+Dieser experimentelle Viewer wurde durch einen [NEW_CHANNEL] Viewer ersetzt;
+weitere Infos zu diesem Update finden Sie [[INFO_URL] hier].
+ <usetemplate name="okcancelbuttons" notext="Später..." yestext="Jetzt installieren und [APP_NAME] neu starten"/>
+ </notification>
+ <notification name="OtherChannelRequiredUpdateDownloadedVerboseDialog">
+ Ein erforderliches Softwareupdate wurde heruntergeladen.
+Version [VERSION]
+Dieser experimentelle Viewer wurde durch einen [NEW_CHANNEL] Viewer ersetzt;
+weitere Infos zu diesem Update finden Sie [[INFO_URL] hier].
+
+Zur Installation des Updates muss [APP_NAME] neu gestartet werden.
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
+ <notification name="OtherChannelRequiredUpdateDownloadedDialog">
+ Zur Installation des Updates muss [APP_NAME] neu gestartet werden.
+Dieser experimentelle Viewer wurde durch einen [NEW_CHANNEL] Viewer ersetzt;
+weitere Infos zu diesem Update finden Sie [[INFO_URL] hier].
<usetemplate name="okbutton" yestext="OK"/>
</notification>
<notification name="DeedObjectToGroup">
@@ -1473,6 +1587,10 @@ Zur Installation des Updates muss [APP_NAME] neu gestartet werden.
Diese Gruppe verlassen?
<usetemplate name="okcancelbuttons" notext="Abbrechen" yestext="OK"/>
</notification>
+ <notification name="OwnerCannotLeaveGroup">
+ Sie können die Gruppe nicht verlassen, da Sie der letzte Besitzer der Gruppe sind. Weisen Sie die Besitzerrolle zuerst einem anderen Mitglied zu.
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
<notification name="ConfirmKick">
Möchten Sie WIRKLICH alle Benutzer aus dem Grid werfen?
<usetemplate name="okcancelbuttons" notext="Abbrechen" yestext="Alle Benutzer hinauswerfen"/>
@@ -1500,10 +1618,13 @@ Diese Gruppe verlassen?
Sie können gerade keine Freundschaft anbieten. Warten Sie kurz und versuchen Sie es dann noch einmal.
<usetemplate name="okbutton" yestext="OK"/>
</notification>
- <notification name="BusyModeSet">
- Beschäftigt-Modus ist aktiviert.
-Chat und Instant Messages werden ausgeblendet. Instant Messages (Sofortnachrichten) erhalten Ihre Beschäftigt-Antwort. Alle Teleport-Angebote werden abgelehnt. Alle Inventar-Angebote werden in Ihren Papierkorb geschoben.
- <usetemplate ignoretext="Ich ändere meinen Status zu Beschäftigt" name="okignore" yestext="OK"/>
+ <notification name="DoNotDisturbModeSet">
+ Nicht-stören-Modus ist aktiviert: Sie erhalten keine Benachrichtigung über eingehende Kommunikation.
+
+- Andere Einwohner erhalten Ihre Nicht-stören-Antwort (festgelegt in Einstellungen &gt; Allgemein).
+- Teleport-Angebote werden abgelehnt.
+- Voice-Anrufe werden abgelehnt.
+ <usetemplate ignoretext="Ich ändere meinen Status zu „Nicht stören“" name="okignore" yestext="OK"/>
</notification>
<notification name="JoinedTooManyGroupsMember">
Sie haben die maximale Anzahl an Gruppen erreicht. Bitte verlassen Sie eine andere Gruppe, um dieser beitreten zu können oder lehnen Sie das Angebot ab.
@@ -1699,83 +1820,128 @@ Tausende Regionen werden verändert und der Spaceserver wird dadurch stark belas
<usetemplate name="okcancelbuttons" notext="Abbrechen" yestext="OK"/>
</notification>
<notification name="RegionEntryAccessBlocked">
- Sie dürfen diese Region aufgrund Ihrer Alterseinstufung nicht betreten. Der Grund hierfür ist möglicherweise, dass Sie nicht altersüberprüft sind.
-
-Bitte vergewissern Sie sich, dass Sie den aktuellsten Viewer installiert haben und besuchen Sie unsere Knowledgebase, um mehr über Regionen mit dieser Altereinstufung zu erfahren.
+ Die Region, die Sie besuchen möchten, enthält Inhalte, die Ihre aktuellen Einstellungen überschreiten. Sie können Ihre Einstellungen unter „Ich“ &gt; „Einstellungen“ &gt; „Allgemein“ ändern.
<usetemplate name="okbutton" yestext="OK"/>
</notification>
- <notification name="RegionEntryAccessBlocked_KB">
- Sie dürfen diese Region aufgrund Ihrer Alterseinstufung nicht betreten.
-
-Möchten Sie unsere Knowledgebase besuchen, um mehr Informationen über Altereinstufung zu erhalten?
+ <notification name="RegionEntryAccessBlocked_AdultsOnlyContent">
+ Die Region, die Sie besuchen möchten, enthält [REGIONMATURITY]-Inhalte, die nur für Erwachsene zugänglich sind.
<url name="url">
http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview/de
</url>
- <usetemplate ignoretext="Ich kann diese Region aufgrund der Alterseinstufung nicht betreten" name="okcancelignore" notext="Schließen" yestext="Zur Knowledgbase"/>
+ <usetemplate ignoretext="Regionswechsel: Die Region, die Sie besuchen möchten, enthält Inhalte, die nur für Erwachsene zugänglich sind." name="okcancelignore" notext="Schließen" yestext="Zur Knowledge Base gehen"/>
</notification>
<notification name="RegionEntryAccessBlocked_Notify">
- Aufgrund Ihrer Alterseinstufung dürfen Sie diese Region nicht betreten.
+ Die Region, die Sie besuchen möchten, enthält [REGIONMATURITY]-Inhalte, doch aufgrund Ihrer aktuellen Einstellungen werden [REGIONMATURITY]-Inhalte nicht dargestellt.
+ </notification>
+ <notification name="RegionEntryAccessBlocked_NotifyAdultsOnly">
+ Die Region, die Sie besuchen möchten, enthält [REGIONMATURITY]-Inhalte, die nur für Erwachsene zugänglich sind.
</notification>
<notification name="RegionEntryAccessBlocked_Change">
- Sie dürfen diese Region aufgrund der Einstellung Ihrer Inhaltseinstufung nicht betreten.
-
-Bitte ändern Sie Ihre Einstellungen bezüglich der Inhaltseinstufung, um die gewünschte Region zu betreten. Danach können Sie nach [REGIONMATURITY]-Inhalt suchen und auf diesen zugreifen. Um die Veränderungen rückgängig zu machen, gehen Sie zu Ich &gt; Einstellungen &gt; Allgemein.
+ Die Region, die Sie besuchen möchten, enthält [REGIONMATURITY]-Inhalte, doch aufgrund Ihrer aktuellen Einstellungen werden [REGIONMATURITY]-Inhalte nicht dargestellt. Sie können Ihre Einstellungen ändern oder diesen Vorgang abbrechen. Nachdem Sie Ihre Einstellungen geändert haben, können Sie erneut versuchen, die Region zu betreten.
+ <form name="form">
+ <button name="OK" text="Einstellungen ändern"/>
+ <button name="Cancel" text="Abbrechen"/>
+ <ignore name="ignore" text="Regionswechsel: Die Region, die Sie besuchen möchten, enthält Inhalte, die aufgrund Ihrer Einstellungen nicht dargestellt werden können."/>
+ </form>
+ </notification>
+ <notification name="RegionEntryAccessBlocked_PreferencesOutOfSync">
+ Wir haben technische Probleme mit Ihrem Teleport, da Ihre Einstellungen nicht mit dem Server synchronisiert sind.
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
+ <notification name="TeleportEntryAccessBlocked">
+ Die Region, die Sie besuchen möchten, enthält Inhalte, die Ihre aktuellen Einstellungen überschreiten. Sie können Ihre Einstellungen unter „Ich“ &gt; „Einstellungen“ &gt; „Allgemein“ ändern.
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
+ <notification name="TeleportEntryAccessBlocked_AdultsOnlyContent">
+ Die Region, die Sie besuchen möchten, enthält [REGIONMATURITY]-Inhalte, die nur für Erwachsene zugänglich sind.
+ <url name="url">
+ http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview/de
+ </url>
+ <usetemplate ignoretext="Teleport: Die Region, die Sie besuchen möchten, enthält Inhalte, die nur für Erwachsene zugänglich sind." name="okcancelignore" notext="Schließen" yestext="Zur Knowledge Base gehen"/>
+ </notification>
+ <notification name="TeleportEntryAccessBlocked_Notify">
+ Die Region, die Sie besuchen möchten, enthält [REGIONMATURITY]-Inhalte, doch aufgrund Ihrer aktuellen Einstellungen werden [REGIONMATURITY]-Inhalte nicht dargestellt.
+ </notification>
+ <notification name="TeleportEntryAccessBlocked_NotifyAdultsOnly">
+ Die Region, die Sie besuchen möchten, enthält [REGIONMATURITY]-Inhalte, die nur für Erwachsene zugänglich sind.
+ </notification>
+ <notification name="TeleportEntryAccessBlocked_ChangeAndReTeleport">
+ Die Region, die Sie besuchen möchten, enthält [REGIONMATURITY]-Inhalte, doch aufgrund Ihrer aktuellen Einstellungen werden [REGIONMATURITY]-Inhalte nicht dargestellt. Sie können Ihre Einstellungen ändern und den Teleport fortsetzen oder Sie können den Teleport abbrechen.
<form name="form">
- <button name="OK" text="Einstellung ändern"/>
- <button name="Cancel" text="Schließen"/>
- <ignore name="ignore" text="Meine Alterseinstufung lässt nicht zu, dass ich eine Region betrete."/>
+ <button name="OK" text="Ändern und fortfahren"/>
+ <button name="Cancel" text="Abbrechen"/>
+ <ignore name="ignore" text="Teleport (kann neu gestartet werden): Die Region, die Sie besuchen möchten, enthält Inhalte, die aufgrund Ihrer Einstellungen nicht dargestellt werden können."/>
</form>
</notification>
+ <notification name="TeleportEntryAccessBlocked_Change">
+ Die Region, die Sie besuchen möchten, enthält [REGIONMATURITY]-Inhalte, doch aufgrund Ihrer aktuellen Einstellungen werden [REGIONMATURITY]-Inhalte nicht dargestellt. Sie können Ihre Einstellungen ändern oder den Teleport abbrechen. Nachdem Sie Ihre Einstellungen geändert haben, können Sie den Teleport erneut versuchen.
+ <form name="form">
+ <button name="OK" text="Einstellungen ändern"/>
+ <button name="Cancel" text="Abbrechen"/>
+ <ignore name="ignore" text="Teleport (kann nicht neu gestartet werden): Die Region, die Sie besuchen möchten, enthält Inhalte, die aufgrund Ihrer Einstellungen nicht dargestellt werden können."/>
+ </form>
+ </notification>
+ <notification name="TeleportEntryAccessBlocked_PreferencesOutOfSync">
+ Wir haben technische Probleme mit Ihrem Teleport, da Ihre Einstellungen nicht mit dem Server synchronisiert sind.
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
<notification name="PreferredMaturityChanged">
- Ihre Inhaltseinstufung ist jetzt [RATING].
+ Sie erhalten keine Benachrichtigungen mehr, wenn Sie eine Region der Inhaltseinstufung „[RATING]“ besuchen. Sie können Ihre Inhaltseinstellungen von der Menüleiste aus ändern („Ich“ &gt; „Einstellungen“ &gt; „Allgemein“).
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
+ <notification name="MaturityChangeError">
+ Wir konnten Ihre Einstellungen zur Anzeige von [PREFERRED_MATURITY]-Inhalten leider nicht ändern. Ihre Einstellungen wurden auf [ACTUAL_MATURITY]-Inhalte zurückgesetzt. Sie können erneut versuchen, Ihre Inhaltseinstellungen von der Menüleiste aus zu ändern („Ich“ &gt; „Einstellungen“ &gt; „Allgemein“).
+ <usetemplate name="okbutton" yestext="OK"/>
</notification>
<notification name="LandClaimAccessBlocked">
- Sie haben aufgrund Ihrer Alterseinstufung keinen Anspruch auf dieses Land. Der Grund hierfür ist möglicherweise, dass Sie nicht altersüberprüft sind.
-
-Bitte vergewissern Sie sich, dass Sie den aktuellsten Viewer installiert haben und besuchen Sie unsere Knowledgebase, um mehr über Regionen mit dieser Altereinstufung zu erfahren.
+ Die Inhaltseinstufung des Landes, das Sie in Besitz nehmen möchten, überschreitet Ihre aktuellen Einstellungen. Sie können Ihre Einstellungen unter „Ich“ &gt; „Einstellungen“ &gt; „Allgemein“ ändern.
<usetemplate name="okbutton" yestext="OK"/>
</notification>
- <notification name="LandClaimAccessBlocked_KB">
- Sie haben aufgrund Ihrer Alterseinstufung keinen Anspruch auf dieses Land.
-
-Möchten Sie unsere Knowledgebase besuchen, um mehr Informationen über Altereinstufung zu erhalten?
+ <notification name="LandClaimAccessBlocked_AdultsOnlyContent">
+ Nur Erwachsene können dieses Land in Besitz nehmen.
<url name="url">
http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview/de
</url>
- <usetemplate ignoretext="Ich habe aufgrund der Alterseinstufung keinen Anspruch auf dieses Land" name="okcancelignore" notext="Schließen" yestext="Zur Knowledgbase"/>
+ <usetemplate ignoretext="Nur Erwachsene können dieses Land in Besitz nehmen." name="okcancelignore" notext="Schließen" yestext="Zur Knowledge Base gehen"/>
</notification>
<notification name="LandClaimAccessBlocked_Notify">
- Sie haben aufgrund Ihrer Alterseinstufung keinen Anspruch auf dieses Land.
+ Das Land, das Sie besuchen möchten, enthält [REGIONMATURITY]-Inhalte, doch aufgrund Ihrer aktuellen Einstellungen werden [REGIONMATURITY]-Inhalte nicht dargestellt.
+ </notification>
+ <notification name="LandClaimAccessBlocked_NotifyAdultsOnly">
+ Das Land, das Sie in Besitz nehmen möchten, enthält [REGIONMATURITY]-Inhalte, die nur für Erwachsene zugänglich sind.
</notification>
<notification name="LandClaimAccessBlocked_Change">
- Sie haben aufgrund der Einstellung Ihrer Alterseinstufung keinen Anspruch auf dieses Land.
-
-Klicken Sie auf „Einstellung ändern“, um Ihre Einstellung für Altereinstufung sofort zu ändern und Zugang zu erhalten. Sie können ab sofort [REGIONMATURITY]-Inhalt suchen und auf diesen zugreifen. Falls Sie diese Einstellung später rückgängig machen möchten, gehen Sie zu Bearbeiten &gt; Einstellungen &gt; Allgemein.
- <usetemplate ignoretext="Meine Alterseinstufung lässt nicht zu, dass ich auf Land Anspruch erhebe" name="okcancelignore" notext="Schließen" yestext="Einstellung ändern"/>
+ Das Land, das Sie besuchen möchten, enthält [REGIONMATURITY]-Inhalte, doch aufgrund Ihrer aktuellen Einstellungen werden [REGIONMATURITY]-Inhalte nicht dargestellt. Sie können Ihre Einstellungen ändern und anschließend erneut versuchen, das Land in Besitz zu nehmen.
+ <form name="form">
+ <button name="OK" text="Einstellungen ändern"/>
+ <button name="Cancel" text="Abbrechen"/>
+ <ignore name="ignore" text="Das Land, das Sie in Besitz nehmen möchten, enthält Inhalte, die aufgrund Ihrer Einstellungen nicht dargestellt werden können."/>
+ </form>
</notification>
<notification name="LandBuyAccessBlocked">
- Sie können aufgrund Ihrer Alterseinstufung dieses Land nicht kaufen. Der Grund hierfür ist möglicherweise, dass Sie nicht altersüberprüft sind.
-
-Bitte vergewissern Sie sich, dass Sie den aktuellsten Viewer installiert haben und besuchen Sie unsere Knowledgebase, um mehr über Regionen mit dieser Altereinstufung zu erfahren.
+ Die Inhaltseinstufung des Landes, das Sie kaufen möchten, überschreitet Ihre aktuellen Einstellungen. Sie können Ihre Einstellungen unter „Ich“ &gt; „Einstellungen“ &gt; „Allgemein“ ändern.
<usetemplate name="okbutton" yestext="OK"/>
</notification>
- <notification name="LandBuyAccessBlocked_KB">
- Sie können aufgrund Ihrer Alterseinstufung dieses Land nicht kaufen.
-
-Möchten Sie unsere Knowledgebase besuchen, um mehr Informationen über Altereinstufung zu erhalten?
+ <notification name="LandBuyAccessBlocked_AdultsOnlyContent">
+ Nur Erwachsene können dieses Land kaufen.
<url name="url">
http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview/de
</url>
- <usetemplate ignoretext="Ich kann aufgrund der Alterseinstufung dieses Land nicht kaufen" name="okcancelignore" notext="Schließen" yestext="Zur Knowledgbase"/>
+ <usetemplate ignoretext="Nur Erwachsene können dieses Land kaufen." name="okcancelignore" notext="Schließen" yestext="Zur Knowledge Base gehen"/>
</notification>
<notification name="LandBuyAccessBlocked_Notify">
- Sie können aufgrund Ihrer Alterseinstufung dieses Land nicht kaufen.
+ Das Land, das Sie kaufen möchten, enthält [REGIONMATURITY]-Inhalte, doch aufgrund Ihrer aktuellen Einstellungen werden [REGIONMATURITY]-Inhalte nicht dargestellt.
+ </notification>
+ <notification name="LandBuyAccessBlocked_NotifyAdultsOnly">
+ Das Land, das Sie kaufen möchten, enthält Inhalte der Einstufung „[REGIONMATURITY]“, die nur für Erwachsene zugänglich sind.
</notification>
<notification name="LandBuyAccessBlocked_Change">
- Sie können aufgrund Ihrer Einstellung für Alterseinstufung dieses Land nicht kaufen.
-
-Klicken Sie auf „Einstellung ändern“, um Ihre Einstellung für Altereinstufung sofort zu ändern und Zugang zu erhalten. Sie können ab sofort [REGIONMATURITY]-Inhalt suchen und auf diesen zugreifen. Falls Sie diese Einstellung später rückgängig machen möchten, gehen Sie zu Bearbeiten &gt; Einstellungen &gt; Allgemein.
- <usetemplate ignoretext="Meine Alterseinstufung lässt nicht zu, dass ich Land kaufe" name="okcancelignore" notext="Schließen" yestext="Einstellung ändern"/>
+ Das Land, das Sie kaufen möchten, enthält [REGIONMATURITY]-Inhalte, doch aufgrund Ihrer aktuellen Einstellungen werden [REGIONMATURITY]-Inhalte nicht dargestellt. Sie können Ihre Einstellungen ändern und anschließend erneut versuchen, das Land zu kaufen.
+ <form name="form">
+ <button name="OK" text="Einstellungen ändern"/>
+ <button name="Cancel" text="Abbrechen"/>
+ <ignore name="ignore" text="Das Land, das Sie kaufen möchten, enthält Inhalte, die aufgrund Ihrer Einstellungen nicht dargestellt werden können."/>
+ </form>
</notification>
<notification name="TooManyPrimsSelected">
Zu viele Prims wurden ausgewählt. Bitte wählen Sie höchstens [MAX_PRIM_COUNT] Prims aus und versuchen Sie es erneut.
@@ -1830,10 +1996,9 @@ Anzeige für [AMOUNT] L$ veröffentlichen?
</form>
</notification>
<notification label="Alterseinstufung der Region ändern" name="RegionMaturityChange">
- Die Alterseinstufung dieser Region wurde aktualisiert.
+ Die Inhaltseinstufung dieser Region wurde geändert.
Es kann eine Weile dauern, bis diese Änderung auf der Karte angezeigt wird.
-
-Um Regionen der Alterseinstufung „Adult&quot; zu betreten, müssen Einwohner altersüberprüft sein. Dies kann entweder über die Alterverifizierung oder Zahlungsverifizierung geschehen.
+ <usetemplate name="okbutton" yestext="OK"/>
</notification>
<notification label="Falsche Voice-Version" name="VoiceVersionMismatch">
Diese Version von [APP_NAME] ist mit der Voice-Chat-Funktion in dieser Region nicht kompatibel. Damit Voice-Chat funktioniert, müssen Sie [APP_NAME] aktualisieren.
@@ -1947,6 +2112,10 @@ Inventarobjekt(e) verschieben?
Möchten Sie Ihre [http://secondlife.com/account/ Startseite] aufrufen, um Ihre Konto-Statistik anzuzeigen?
<usetemplate ignoretext="Meinen Browser starten, um meine Konto-Statistik anzuzeigen" name="okcancelignore" notext="Abbrechen" yestext="Gehe zu Seite"/>
</notification>
+ <notification name="ConfirmAddingChatParticipants">
+ Wenn Sie eine Person zu einer vorhandenen Unterhaltung hinzufügen, wird eine neue Unterhaltung erstellt. Alle Teilnehmer erhalten neue Unterhaltungsbenachrichtigungen.
+ <usetemplate ignoretext="Hinzufügen von Chat-Teilnehmern bestätigen" name="okcancelignore" notext="Abbrechen" yestext="OK"/>
+ </notification>
<notification name="ConfirmQuit">
Wirklich beenden?
<usetemplate ignoretext="Bestätigen, bevor Sitzung beendet wird" name="okcancelignore" notext="Nicht beenden" yestext="Beenden"/>
@@ -2020,14 +2189,14 @@ Möchten Sie es mit dem ausgewählten Objekt ersetzen?
<button ignore="Nie ersetzen" name="No" text="Abbrechen"/>
</form>
</notification>
- <notification label="Beschäftigt-Modus-Warnung" name="BusyModePay">
- Sie sind im Beschäftigt-Modus, sodass Sie im Austausch für diese Zahlung keine Objekte erhalten können.
+ <notification label="Warnung für Nicht-stören-Modus" name="DoNotDisturbModePay">
+ Sie haben den Nicht-stören-Modus aktiviert. Sie erhalten keine Artikel, die im Gegenzug für diese Zahlung angeboten werden.
-Möchten Sie den Bechäftigt-Modus verlassen, bevor Sie diese Transaktion abschließen?
+Möchten Sie den Nicht-stören-Modus deaktivieren, bevor Sie diese Transaktion abschließen?
<form name="form">
- <ignore name="ignore" save_option="true" text="Ich bin im Begriff eine Person oder ein Objekt zu bezahlen, während ich im Modus Beschäftigt bin."/>
- <button ignore="Beschäftigt-Modus immer deaktivieren" name="Yes" text="OK"/>
- <button ignore="Beschäftigt-Modus aktiviert lassen" name="No" text="Abbrechen"/>
+ <ignore name="ignore" text="Ich bin im Begriff eine Person oder ein Objekt zu bezahlen, während ich im Nicht-stören-Modus bin."/>
+ <button ignore="„Nicht stören“-Modus immer verlassen" name="Yes" text="OK"/>
+ <button ignore="„Nicht stören“-Modus nie verlassen" name="No" text="Abbrechen"/>
</form>
</notification>
<notification name="ConfirmDeleteProtectedCategory">
@@ -2123,14 +2292,11 @@ Von einer Webseite zu diesem Formular linken, um anderen leichten Zugang zu dies
<usetemplate ignoretext="Die Kleidung, die während dem Bearbeiten meines Aussehens erstellt wird, sofort anziehen" name="okcancelignore" notext="Nein" yestext="Ja"/>
</notification>
<notification name="NotAgeVerified">
- Um auf Adult-Inhalte und –Bereiche in Second Life zuzugreifen, müssen Sie mindestens 18 Jahre alt sein. Bitte besuchen Sie die Altersüberprüfungsseite, um zu bestätigen, dass Sie mindestens 18 Jahre alt sind.
-Hierzu wird Ihr Webbrowser geöffnet.
-
-[_URL]
- <url name="url" option="0">
- https://secondlife.com/my/account/verification.php
- </url>
- <usetemplate ignoretext="Ich habe mein Alter nicht verifizieren lassen" name="okcancelignore" notext="Abbrechen" yestext="Zur Altersüberprüfung"/>
+ Der Ort, den Sie besuchen möchten, ist nur für Bewohner zugänglich, die mindestens 18 Jahre alt sind.
+ <usetemplate ignoretext="Ich bin nicht alt genug, um beschränkte Bereiche zu besuchen." name="okignore" yestext="OK"/>
+ </notification>
+ <notification name="NotAgeVerified_Notify">
+ Ort auf Einwohner beschränkt, die mindestens 18 Jahre alt sind.
</notification>
<notification name="Cannot enter parcel: no payment info on file">
Um diesen Bereich besuchen zu können, müssen Ihre Zahlungsinformationen gespeichert sein. Möchten Sie diese Einstellung auf der [SECOND_LIFE]-Webseite einrichten?
@@ -2165,11 +2331,8 @@ Hierzu wird Ihr Webbrowser geöffnet.
<notification name="GroupNotice">
Betreff: [SUBJECT], Nachricht: [MESSAGE]
</notification>
- <notification name="FriendOnline">
- &lt;nolink&gt;[NAME]&lt;/nolink&gt; ist online
- </notification>
- <notification name="FriendOffline">
- &lt;nolink&gt;[NAME]&lt;/nolink&gt; ist offline
+ <notification name="FriendOnlineOffline">
+ &lt;nolink&gt;[NAME]&lt;/nolink&gt; ist [STATUS]
</notification>
<notification name="AddSelfFriend">
Obwohl Sie ein sehr netter Mensch sind, können Sie sich nicht selbst als Freund hinzufügen.
@@ -2191,7 +2354,7 @@ Hierzu wird Ihr Webbrowser geöffnet.
Terrain.raw heruntergeladen
</notification>
<notification name="GestureMissing">
- Hmm. Geste [NAME] fehlt in Datenbank.
+ Geste [NAME] fehlt in Datenbank.
</notification>
<notification name="UnableToLoadGesture">
Geste [NAME] konnte nicht geladen werden.
@@ -2289,9 +2452,7 @@ Wählen Sie ein einzelnes Objekt aus.
„Teleportieren“ wählen.)
</notification>
<notification name="TeleportToPerson">
- Um Einwohner wie „[NAME]“ zu kontaktieren, klicken Sie auf die Schaltfläche „Leute“, wählen Sie eingeblendeten Fenster einen Einwohner aus
- und klicken Sie unten im Fenster auf „IM“.
- (Sie können auch auf den Namen doppelklicken bzw. ihn mit der rechten Maustaste anklicken und dann „IM“ wählen.)
+ Um eine private Unterhaltung zu beginnen, klicken Sie mit der rechten Maustaste auf den gewünschten Avatar und wählen Sie im Menü „IM“ aus.
</notification>
<notification name="CantSelectLandFromMultipleRegions">
Land kann nicht über Servergrenzen hinweg ausgewählt werden.
@@ -2391,6 +2552,16 @@ Fliegen ist hier nicht möglich.
<notification name="NoBuild">
In diesem Bereich ist das Bauen deaktiviert. Sie können keine Objekte bauen oder rezzen.
</notification>
+ <notification name="PathfindingDirty">
+ Diese Region weist ausstehende Pathfinding-Änderungen auf. Wenn Sie Baurechte besitzen, können Sie die Region durch Klicken auf die Schaltfläche „Region neu formen“ neu formen.
+ </notification>
+ <notification name="DynamicPathfindingDisabled">
+ Dynamisches Pathfinding ist in dieser Region nicht aktiviert. Geskriptete Objekte, die Pathfinding-LSL-Aufrufe verwenden, funktionieren in dieser Region u. U. nicht wie erwartet.
+ </notification>
+ <notification name="PathfindingCannotRebakeNavmesh">
+ Fehler aufgetreten. Möglicherweise ist ein Netzwerk- oder Serverproblem aufgetreten oder Sie haben nicht die erforderlichen Baurechte. Dieses Problem lässt sich manchmal durch Ab- und Anmelden lösen.
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
<notification name="SeeAvatars">
Diese Parzelle verbirgt Avatare und Text-Chat vor einer anderen Parzelle. Sie können Einwohner außerhalb dieser Parzelle weder sehen noch von ihnen gesehen werden. Regulärer Text-Chat auf Kanal 0 ist ebenfalls blockiert.
</notification>
@@ -2409,9 +2580,7 @@ Hier funktionieren nur Skripts, die dem Landeigentümer gehören.
Öffentliches Land kann nur in der Region in Besitz genommen werden, in der Sie sich befinden.
</notification>
<notification name="RegionTPAccessBlocked">
- Sie dürfen diese Region aufgrund Ihrer Alterseinstufung nicht betreten. Sie müssen eventuell eine Altersüberprüfung vornehmen und/oder den aktuellsten Viewer installieren.
-
-Bitte besuchen Sie unsere Knowledgebase, um mehr Details über Zugang zu Regionen mit dieser Alterseinstufung zu erhalten.
+ Die Region, die Sie besuchen möchten, enthält Inhalte, die Ihre aktuellen Einstellungen überschreiten. Sie können Ihre Einstellungen unter „Ich“ &gt; „Einstellungen“ &gt; „Allgemein“ ändern.
</notification>
<notification name="URBannedFromRegion">
Sie dürfen diese Region nicht betreten.
@@ -2422,11 +2591,11 @@ Bitte besuchen Sie unsere Knowledgebase, um mehr Details über Zugang zu Regione
<notification name="ImproperPaymentStatus">
Die für den Zutritt zu dieser Region erforderlichen Zahlungsinformationen liegen nicht vor.
</notification>
- <notification name="MustGetAgeRgion">
- Sie müssen altersüberprüft sein, um diese Region betreten zu können.
+ <notification name="MustGetAgeRegion">
+ Sie müssen mindestens 18 Jahre alt sein, um diese Region betreten zu können.
</notification>
<notification name="MustGetAgeParcel">
- Sie müssen altersüberprüft sein, um diese Parzelle betreten zu können.
+ Sie müssen mindestens 18 Jahre alt sein, um diese Parzelle betreten zu können.
</notification>
<notification name="NoDestRegion">
Keine Zielregion gefunden.
@@ -2526,14 +2695,35 @@ Versuchen Sie es in einigen Minuten erneut.
</form>
</notification>
<notification name="TeleportOffered">
- [NAME_SLURL] hat Ihnen einen Teleport an seine/ihre Position angeboten:
+ [NAME_SLURL] hat Ihnen den Teleport an seinen/ihren Standort angeboten:
-[MESSAGE] - [MATURITY_STR] &lt;icon&gt;[MATURITY_ICON]&lt;/icon&gt;
+„[MESSAGE]“
+&lt;icon&gt;[MATURITY_ICON]&lt;/icon&gt; – [MATURITY_STR]
<form name="form">
<button name="Teleport" text="Teleportieren"/>
<button name="Cancel" text="Abbrechen"/>
</form>
</notification>
+ <notification name="TeleportOffered_MaturityExceeded">
+ [NAME_SLURL] hat Ihnen den Teleport an seinen/ihren Standort angeboten:
+
+„[MESSAGE]“
+&lt;icon&gt;[MATURITY_ICON]&lt;/icon&gt; – [MATURITY_STR]
+
+Diese Region enthält [REGION_CONTENT_MATURITY]-Inhalte, doch aufgrund Ihrer aktuellen Einstellungen werden [REGION_CONTENT_MATURITY]-Inhalte nicht dargestellt. Sie können Ihre Einstellungen ändern und den Teleport fortsetzen oder Sie können den Teleport abbrechen.
+ <form name="form">
+ <button name="Teleport" text="Ändern und fortfahren"/>
+ <button name="Cancel" text="Abbrechen"/>
+ </form>
+ </notification>
+ <notification name="TeleportOffered_MaturityBlocked">
+ [NAME_SLURL] hat Ihnen den Teleport an seinen/ihren Standort angeboten:
+
+„[MESSAGE]“
+&lt;icon&gt;[MATURITY_ICON]&lt;/icon&gt; – [MATURITY_STR]
+
+Diese Region enthält jedoch Inhalte, die nur für Erwachsene zugänglich sind.
+ </notification>
<notification name="TeleportOfferSent">
Ein Teleportangebot wurde an [TO_NAME] geschickt
</notification>
@@ -2628,16 +2818,21 @@ Ist das OK?
</form>
</notification>
<notification name="ScriptQuestionCaution">
- Das Objekt „&lt;nolink&gt;[OBJECTNAME]&lt;/nolink&gt;“, das „[NAME]“ gehört, stellt folgende Anfrage:
-
-[QUESTIONS]
-Wenn Sie diesem Objekt und seinem Ersteller nicht vertrauen, sollten Sie diese Anfrage ablehnen.
-
-Anfrage gestatten?
+ Achtung: Das Objekt „&lt;nolink&gt;[OBJECTNAME]&lt;/nolink&gt;“ fordert uneingeschränkten Zugriff auf Ihr Linden-Dollar-Konto an. Wenn Sie Zugriff gewähren, kann dieses Objekt jederzeit und ohne weitere Warnung Ihr Konto belasten bzw. ganz leeren.
+
+Gewähren Sie dem Objekt nur dann Zugriff, wenn Sie genau verstehen, wieso ein solcher Zugriff auf Ihr Konto erforderlich ist.
<form name="form">
- <button name="Grant" text="Gewähren"/>
+ <button name="Grant" text="Uneingeschränkten Zugriff gewähren"/>
<button name="Deny" text="Verweigern"/>
- <button name="Details" text="Info..."/>
+ </form>
+ </notification>
+ <notification name="UnknownScriptQuestion">
+ Die Runtime-Skript-Berechtigung, die von „&lt;nolink&gt;[OBJECTNAME]&lt;/nolink&gt;“ (Besitzer: „[NAME]“) angefordert wurde, wird vom Viewer nicht erkannt und kann nicht gewährt werden.
+
+Um diese Berechtigung zu gewähren, laden Sie die neueste Version des Viewers von [DOWNLOADURL] herunter.
+ <form name="form">
+ <button name="Deny" text="OK"/>
+ <button name="Mute" text="Blockieren"/>
</form>
</notification>
<notification name="ScriptDialog">
@@ -2942,6 +3137,10 @@ Sie haben eine [RESOLUTION]-gebackene Textur für „[BODYREGION]“ nach [TIME]
( [EXISTENCE] Sekunden am Leben)
Sie haben lokal eine [RESOLUTION]-gebackene Textur für „[BODYREGION]“ nach [TIME] Sekunden aktualisiert.
</notification>
+ <notification name="LivePreviewUnavailable">
+ Wir können keine Vorschau dieser Textur anzeigen, da sie nicht kopier- und/oder übertragungsfähig ist.
+ <usetemplate ignoretext="Hinweis anzeigen, wenn bei nicht kopier- und/oder übertragungsfähigen Texturen keine Live-Vorschau möglich ist" name="okignore" yestext="OK"/>
+ </notification>
<notification name="ConfirmLeaveCall">
Möchten Sie dieses Gespräch wirklich verlassen ?
<usetemplate ignoretext="Bestätigen, bevor ich den Anruf verlasse." name="okcancelignore" notext="Nein" yestext="Ja"/>
@@ -3111,6 +3310,62 @@ Durch Ausblenden der Schaltfläche „Sprechen“ wird die Sprechfunktion deakti
Durch diese Aktion werden alle Menüelemente und Schaltflächen ausgeblendet. Um sie wieder anzuzeigen, klicken Sie erneut auf [SHORTCUT].
<usetemplate ignoretext="Vor Ausblenden der UI bestätigen" name="okcancelignore" notext="Abbrechen" yestext="OK"/>
</notification>
+ <notification name="PathfindingLinksets_WarnOnPhantom">
+ Bei einigen ausgewählten Linksets wird die Phantom-Markierung umgeschaltet.
+
+Möchten Sie fortfahren?
+ <usetemplate ignoretext="Bei einigen ausgewählten Linksets wird die Phantom-Markierung umgeschaltet." name="okcancelignore" notext="Abbrechen" yestext="OK"/>
+ </notification>
+ <notification name="PathfindingLinksets_MismatchOnRestricted">
+ Einige der ausgewählten Linksets können aufgrund von Berechtigungseinschränkungen nicht auf „[REQUESTED_TYPE]“ gesetzt werden. Diese Linksets werden stattdessen auf „[RESTRICTED_TYPE]“ gesetzt.
+
+Möchten Sie fortfahren?
+ <usetemplate ignoretext="Einige der ausgewählten Linksets können aufgrund von Berechtigungseinschränkungen nicht gesetzt werden." name="okcancelignore" notext="Abbrechen" yestext="OK"/>
+ </notification>
+ <notification name="PathfindingLinksets_MismatchOnVolume">
+ Einige der ausgewählten Linksets können nicht auf „[REQUESTED_TYPE]“ gesetzt werden, da die Form nicht konvex ist.
+
+Möchten Sie fortfahren?
+ <usetemplate ignoretext="Einige der ausgewählten Linksets können nicht gesetzt werden, da die Form nicht konvex ist." name="okcancelignore" notext="Abbrechen" yestext="OK"/>
+ </notification>
+ <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnRestricted">
+ Bei einigen ausgewählten Linksets wird die Phantom-Markierung umgeschaltet.
+
+Einige der ausgewählten Linksets können aufgrund von Berechtigungseinschränkungen nicht auf „[REQUESTED_TYPE]“ gesetzt werden. Diese Linksets werden stattdessen auf „[RESTRICTED_TYPE]“ gesetzt.
+
+Möchten Sie fortfahren?
+ <usetemplate ignoretext="Bei einigen ausgewählten Linksets wird die Phantom-Markierung umgeschaltet und andere können aufgrund von Berechtigungseinschränkungen nicht gesetzt werden." name="okcancelignore" notext="Abbrechen" yestext="OK"/>
+ </notification>
+ <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnVolume">
+ Bei einigen ausgewählten Linksets wird die Phantom-Markierung umgeschaltet.
+
+Einige der ausgewählten Linksets können nicht auf „[REQUESTED_TYPE]“ gesetzt werden, da die Form nicht konvex ist.
+
+Möchten Sie fortfahren?
+ <usetemplate ignoretext="Bei einigen ausgewählten Linksets wird die Phantom-Markierung umgeschaltet und andere können nicht gesetzt werden, da die Form nicht konvex ist." name="okcancelignore" notext="Abbrechen" yestext="OK"/>
+ </notification>
+ <notification name="PathfindingLinksets_MismatchOnRestricted_MismatchOnVolume">
+ Einige der ausgewählten Linksets können aufgrund von Berechtigungseinschränkungen nicht auf „[REQUESTED_TYPE]“ gesetzt werden. Diese Linksets werden stattdessen auf „[RESTRICTED_TYPE]“ gesetzt.
+
+Einige der ausgewählten Linksets können nicht auf „[REQUESTED_TYPE]“ gesetzt werden, da die Form nicht konvex ist. Die Nutzungsarten dieser Linksets bleiben unverändert.
+
+Möchten Sie fortfahren?
+ <usetemplate ignoretext="Einige der ausgewählten Linksets können nicht gesetzt werden, da die Berechtigungen eingeschränkt sind und die Form nicht konvex ist." name="okcancelignore" notext="Abbrechen" yestext="OK"/>
+ </notification>
+ <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnRestricted_MismatchOnVolume">
+ Bei einigen ausgewählten Linksets wird die Phantom-Markierung umgeschaltet.
+
+Einige der ausgewählten Linksets können aufgrund von Berechtigungseinschränkungen nicht auf „[REQUESTED_TYPE]“ gesetzt werden. Diese Linksets werden stattdessen auf „[RESTRICTED_TYPE]“ gesetzt.
+
+Einige der ausgewählten Linksets können nicht auf „[REQUESTED_TYPE]“ gesetzt werden, da die Form nicht konvex ist. Die Nutzungsarten dieser Linksets bleiben unverändert.
+
+Möchten Sie fortfahren?
+ <usetemplate ignoretext="Bei einigen ausgewählten Linksets wird die Phantom-Markierung umgeschaltet und andere können nicht gesetzt werden, da die Berechtigungen für das Linkset eingeschränkt sind und die Form nicht konvex ist." name="okcancelignore" notext="Abbrechen" yestext="OK"/>
+ </notification>
+ <notification name="PathfindingLinksets_ChangeToFlexiblePath">
+ Das ausgewählte Objekt wirkt sich auf das Navmesh aus. Wenn Sie es in einen flexiblen Pfad ändern, wird es aus dem Navmesh entfernt.
+ <usetemplate ignoretext="Das ausgewählte Objekt wirkt sich auf das Navmesh aus. Wenn Sie es in einen flexiblen Pfad ändern, wird es aus dem Navmesh entfernt." name="okcancelignore" notext="Abbrechen" yestext="OK"/>
+ </notification>
<global name="UnsupportedGLRequirements">
Ihr Computer entspricht nicht den Hardwareanforderungen von [APP_NAME]. [APP_NAME] setzt eine OpenGL-Grafikkarte mit Multitextur-Unterstützung voraus. Falls Ihre Grafikkarte diese Funktion unterstützt, installieren Sie die neuesten Treiber sowie die aktuellen Service Packs und Patches für Ihr Betriebssystem.
@@ -3135,4 +3390,653 @@ Ansonsten können Sie auf der Karte nachsehen und dort Ort suchen, die als „In
<global name="You died and have been teleported to your home location">
Sie sind gestorben und wurden zu Ihrem Zuhause teleportiert.
</global>
+ <notification name="LocalBitmapsUpdateFileNotFound">
+ [FNAME] wurde nicht gefunden und konnte deshalb nicht aktualisiert werden.
+Zukünftige Aktualisierungen dieser Datei werden deaktiviert.
+ </notification>
+ <notification name="LocalBitmapsUpdateFailedFinal">
+ [FNAME] konnte auch nach [NRETRIES] Versuchen nicht geöffnet oder decodiert werden und gilt als beschädigt.
+Zukünftige Aktualisierungen dieser Datei werden deaktiviert.
+ </notification>
+ <notification name="LocalBitmapsVerifyFail">
+ Versuch, eine ungültige oder nicht lesbare Bilddatei ([FNAME]) hinzuzufügen, die nicht geöffnet oder decodiert werden konnte.
+Versuch abgebrochen.
+ </notification>
+ <notification name="PathfindingReturnMultipleItems">
+ Sie sind dabei, [NUM_ITEMS] Objekte zurückzugeben. Möchten Sie diesen Vorgang wirklich fortsetzen?
+ <usetemplate ignoretext="Möchten Sie wirklich mehrere Objekte zurückgeben?" name="okcancelignore" notext="Nein" yestext="Ja"/>
+ </notification>
+ <notification name="PathfindingDeleteMultipleItems">
+ Sie sind dabei, [NUM_ITEMS] Objekte zu löschen. Möchten Sie diesen Vorgang wirklich fortsetzen?
+ <usetemplate ignoretext="Möchten Sie wirklich mehrere Objekte löschen?" name="okcancelignore" notext="Nein" yestext="Ja"/>
+ </notification>
+ <notification name="AvatarFrozen">
+ [AV_FREEZER] hat Sie eingefroren. Sie können sich nicht bewegen oder mit der Welt interagieren.
+ </notification>
+ <notification name="AvatarFrozenDuration">
+ [AV_FREEZER] hat Sie [AV_FREEZE_TIME] Sekunden lang eingefroren. Sie können sich nicht bewegen oder mit der Welt interagieren.
+ </notification>
+ <notification name="YouFrozeAvatar">
+ Avatar eingefroren.
+ </notification>
+ <notification name="AvatarHasUnFrozenYou">
+ [AV_FREEZER] hat Sie aufgetaut.
+ </notification>
+ <notification name="AvatarUnFrozen">
+ Avatar aufgetaut.
+ </notification>
+ <notification name="AvatarFreezeFailure">
+ Einfrieren fehlgeschlagen, da Sie keine Berechtigung für diese Parzelle haben.
+ </notification>
+ <notification name="AvatarFreezeThaw">
+ Sie sind nicht mehr eingefroren und können sich frei bewegen.
+ </notification>
+ <notification name="AvatarCantFreeze">
+ Dieser Benutzer kann nicht eingefroren werden.
+ </notification>
+ <notification name="NowOwnObject">
+ Sie sind jetzt Eigentümer des Objekts [OBJECT_NAME]
+ </notification>
+ <notification name="CantRezOnLand">
+ Objekt kann nicht an [OBJECT_POS] gerezzt werden, da der Landeigentümer dies nicht zulässt. Machen Sie den Landeigentümer mit dem Landwerkzeug ausfindig.
+ </notification>
+ <notification name="RezFailTooManyRequests">
+ Objekt kann nicht gerezzt werden, da zu viele Anforderungen vorliegen.
+ </notification>
+ <notification name="SitFailCantMove">
+ Sie können sich nicht hinsetzen, da Sie zur Zeit unbeweglich sind.
+ </notification>
+ <notification name="SitFailNotAllowedOnLand">
+ Sie können sich nicht hinsetzen, da Sie auf diesem Land keine Berechtigung dazu haben.
+ </notification>
+ <notification name="SitFailNotSameRegion">
+ Kommen Sie näher heran. Sitzen auf Objekt nicht möglich, da
+es sich nicht in der gleichen Region befindet wie Sie.
+ </notification>
+ <notification name="NoNewObjectRegionFull">
+ Neues Objekt kann nicht erstellt werden. Die Region ist voll.
+ </notification>
+ <notification name="FailedToPlaceObject">
+ Objekt konnte nicht an festgelegtem Ort platziert werden. Versuchen Sie es erneut.
+ </notification>
+ <notification name="NoOwnNoGardening">
+ Auf Land, das Sie nicht besitzen, können Sie keine Bäume und Gräser erstellen.
+ </notification>
+ <notification name="NoCopyPermsNoObject">
+ Kopieren fehlgeschlagen, da Sie keine Berechtigung zum Kopieren des Objekts „OBJ_NAME]“ besitzen.
+ </notification>
+ <notification name="NoTransPermsNoObject">
+ Kopieren fehlgeschlagen, weil Objekt „[OBJ_NAME]“ nicht an Sie übertragen werden kann.
+ </notification>
+ <notification name="AddToNavMeshNoCopy">
+ Kopieren fehlgeschlagen, weil Objekt „[OBJ_NAME]“ zum Navmesh beiträgt.
+ </notification>
+ <notification name="DupeWithNoRootsSelected">
+ Ohne ausgewählte Hauptobjekte duplizieren.
+ </notification>
+ <notification name="CantDupeCuzRegionIsFull">
+ Objekte können nicht dupliziert werden, da die Region voll ist.
+ </notification>
+ <notification name="CantDupeCuzParcelNotFound">
+ Objekte können nicht dupliziert werden, da die Parzelle, in der sie sich befinden, nicht auffindbar ist.
+ </notification>
+ <notification name="CantCreateCuzParcelFull">
+ Objekt kann nicht erstellt werden, da
+die Parzelle voll ist.
+ </notification>
+ <notification name="RezAttemptFailed">
+ Versuch zum Rezzen eines Objekts fehlgeschlagen.
+ </notification>
+ <notification name="ToxicInvRezAttemptFailed">
+ Objekt, das in dieser Region zu Problemen geführt hat, kann nicht erstellt werden.
+ </notification>
+ <notification name="InvItemIsBlacklisted">
+ Dieses Inventarobjekt ist auf der schwarzen Liste.
+ </notification>
+ <notification name="NoCanRezObjects">
+ Sie können gegenwärtig keine Objekte erstellen.
+ </notification>
+ <notification name="LandSearchBlocked">
+ Landsuche blockiert.
+Sie haben zu viele Landsuchen in zu kurzer Zeit durchgeführt.
+Warten Sie kurz und versuchen Sie es noch einmal.
+ </notification>
+ <notification name="NotEnoughResourcesToAttach">
+ Nicht genügend Skriptressourcen verfügbar, um Objekt anzuhängen.
+ </notification>
+ <notification name="YouDiedAndGotTPHome">
+ Sie sind gestorben und wurden nach Hause teleportiert
+ </notification>
+ <notification name="EjectComingSoon">
+ Sie nicht hier nicht mehr zugelassen und haben [EJECT_TIME] Sekunden Zeit, um zu gehen.
+ </notification>
+ <notification name="NoEnterServerFull">
+ Sie können diese Region nicht betreten, da
+der Server voll ist.
+ </notification>
+ <notification name="SaveBackToInvDisabled">
+ Erneutes Speichern im Inventar ist deaktiviert.
+ </notification>
+ <notification name="NoExistNoSaveToContents">
+ „[OBJ_NAME]“ kann nicht im Objektinhalt gespeichert werden, da das Objekt, aus dem es gerezzt wurde, nicht mehr existiert.
+ </notification>
+ <notification name="NoModNoSaveToContents">
+ „[OBJ_NAME]“ kann nicht in Objektinhalt gespeichert werden, da Sie nicht die Berechtigung zum Modifizieren des Objekts „[DEST_NAME]“ besitzen.
+ </notification>
+ <notification name="NoSaveBackToInvDisabled">
+ „[OBJ_NAME]“ kann nicht erneut im Inventar gespeichert werden – dieser Vorgang wurde deaktiviert.
+ </notification>
+ <notification name="NoCopyNoSelCopy">
+ Sie können Ihre Auswahl nicht kopieren, da Sie nicht die Berechtigung zum Kopieren des Objekts „[OBJ_NAME]“ haben.
+ </notification>
+ <notification name="NoTransNoSelCopy">
+ Sie können Ihre Auswahl nicht kopieren, da das Objekt „[OBJ_NAME]“ nicht übertragbar ist.
+ </notification>
+ <notification name="NoTransNoCopy">
+ Sie können Ihre Auswahl nicht kopieren, da das Objekt „[OBJ_NAME]“ nicht übertragbar ist.
+ </notification>
+ <notification name="NoPermsNoRemoval">
+ Entfernen des Objekts „[OBJ_NAME]“ aus dem Simulator wird vom Berechtigungssystem nicht gestattet.
+ </notification>
+ <notification name="NoModNoSaveSelection">
+ Sie können Ihre Auswahl nicht speichern, da Sie keine Berechtigung zum Modifizieren des Objekts „[OBJ_NAME]“ besitzen.
+ </notification>
+ <notification name="NoCopyNoSaveSelection">
+ Ihre Auswahl kann nicht gespeichert werden, da das Objekt „[OBJ_NAME]“ nicht kopiert werden kann.
+ </notification>
+ <notification name="NoModNoTaking">
+ Sie können Ihre Auswahl nicht in Empfang nehmen, da Sie nicht die Berechtigung zum Modifizieren des Objekts „[OBJ_NAME]“ haben.
+ </notification>
+ <notification name="RezDestInternalError">
+ Interner Fehler: Unbekannter Zielttyp.
+ </notification>
+ <notification name="DeleteFailObjNotFound">
+ Löschen fehlgeschlagen, da Objekt nicht gefunden wurde
+ </notification>
+ <notification name="SorryCantEjectUser">
+ Dieser Benutzer kann nicht hinausgeworfen werden.
+ </notification>
+ <notification name="RegionSezNotAHome">
+ Diese Region gestattet nicht, dass Sie hier Ihr Zuhause festlegen.
+ </notification>
+ <notification name="HomeLocationLimits">
+ Ihr Zuhause kann sich nur auf Ihrem eigenen Land oder in einem Infohub auf dem Mainland befinden.
+ </notification>
+ <notification name="HomePositionSet">
+ Position für Zuhause festgelegt.
+ </notification>
+ <notification name="AvatarEjected">
+ Avatar hinausgeworfen.
+ </notification>
+ <notification name="AvatarEjectFailed">
+ Hinauswerfen fehlgeschlagen, da Sie keine Admin-Berechtigung für diese Parzelle haben.
+ </notification>
+ <notification name="CantMoveObjectParcelFull">
+ Objekt „[OBJECT_NAME]“ kann nicht nach
+[OBJ_POSITION] in Region [REGION_NAME] verschoben werden, da die Parzelle voll ist.
+ </notification>
+ <notification name="CantMoveObjectParcelPerms">
+ Objekt „[OBJECT_NAME]“ kann nicht nach
+[OBJ_POSITION] in Region [REGION_NAME] verschoben werden, da Ihre Objekte auf dieser Parzelle nicht gestattet sind.
+ </notification>
+ <notification name="CantMoveObjectParcelResources">
+ Objekt „[OBJECT_NAME]“ kann nicht nach
+[OBJ_POSITION] in Region [REGION_NAME] verschoben werden, da nicht genügend Ressourcen für dieses Objekt auf dieser Parzelle vorhanden sind.
+ </notification>
+ <notification name="CantMoveObjectRegionVersion">
+ Objekt „[OBJECT_NAME]“ kann nicht nach
+[OBJ_POSITION] in Region [REGION_NAME] verschoben werden, da die andere Region eine ältere Version verwendet, die das Empfangen dieses Objekts per Regionswechsel nicht unterstützt.
+ </notification>
+ <notification name="CantMoveObjectNavMesh">
+ Objekt „[OBJECT_NAME]“ kann nicht nach
+[OBJ_POSITION] in Region [REGION_NAME] verschoben werden, da Sie das Navmesh nicht regionsübergreifend modifizieren können.
+ </notification>
+ <notification name="CantMoveObjectWTF">
+ Objekt „[OBJECT_NAME]“ kann nicht nach
+[OBJ_POSITION] in Region [REGION_NAME] verschoben werden, da ein unbekannter Fehler vorliegt. ([FAILURE_TYPE])
+ </notification>
+ <notification name="NoPermModifyObject">
+ Ihnen fehlt die Berechtigung zum Modifizieren dieses Objekts.
+ </notification>
+ <notification name="CantEnablePhysObjContributesToNav">
+ Physik kann nicht für ein Objekt aktiviert werden, das zum Navmesh beiträgt.
+ </notification>
+ <notification name="CantEnablePhysKeyframedObj">
+ Physik für Keyframe-Objekte kann nicht aktiviert werden.
+ </notification>
+ <notification name="CantEnablePhysNotEnoughLandResources">
+ Physik für Objekte kann nicht aktiviert werden – nicht genügend Landressourcen.
+ </notification>
+ <notification name="CantEnablePhysCostTooGreat">
+ Physik für Objekt mit Physikressourcenkosten höher als [MAX_OBJECTS] kann nicht aktiviert werden.
+ </notification>
+ <notification name="PhantomWithConcavePiece">
+ Dieses Objekt kann kein konkaves Teil enthalten, da es ein Phantom ist und zum Navmesh beiträgt.
+ </notification>
+ <notification name="UnableAddItem">
+ Objekt konnte nicht hinzugefügt werden.
+ </notification>
+ <notification name="UnableEditItem">
+ Kein Bearbeiten möglich.
+ </notification>
+ <notification name="NoPermToEdit">
+ Bearbeiten nicht gestattet.
+ </notification>
+ <notification name="NoPermToCopyInventory">
+ Kopieren dieses Inventars nicht gestattet.
+ </notification>
+ <notification name="CantSaveItemDoesntExist">
+ Kein Speichern in Objektinhalt möglich: Objekt nicht mehr vorhanden.
+ </notification>
+ <notification name="CantSaveItemAlreadyExists">
+ Kein Speichern in Objektinhalt möglich: Artikel mit diesem Namen ist bereits im Inventar vorhanden.
+ </notification>
+ <notification name="CantSaveModifyAttachment">
+ Kein Speichern in Objektinhalt möglich: Dadurch würden die Anhängeberechtigungen geändert.
+ </notification>
+ <notification name="TooManyScripts">
+ Zu viele Skripts.
+ </notification>
+ <notification name="UnableAddScript">
+ Skript konnte nicht hinzugefügt werden.
+ </notification>
+ <notification name="AssetServerTimeoutObjReturn">
+ Asset-Server hat nicht rechtzeitig reagiert. Objekt wurde zum Sim zurückübertragen.
+ </notification>
+ <notification name="RegionDisablePhysicsShapes">
+ In dieser Region sind keine Physikformen aktiviert.
+ </notification>
+ <notification name="NoModNavmeshAcrossRegions">
+ Sie können das Navmesh nicht regionsübergreifend modifizieren.
+ </notification>
+ <notification name="NoSetPhysicsPropertiesOnObjectType">
+ Für diesen Objekttyp können keine Physikeigenschaften gesetzt werden.
+ </notification>
+ <notification name="NoSetRootPrimWithNoShape">
+ Hauptprim kann nicht auf formlos eingestellt werden.
+ </notification>
+ <notification name="NoRegionSupportPhysMats">
+ In dieser Region sind keine Physikmaterialien aktiviert.
+ </notification>
+ <notification name="OnlyRootPrimPhysMats">
+ Nur bei Hauptprims können die Physikmaterialien angepasst werden.
+ </notification>
+ <notification name="NoSupportCharacterPhysMats">
+ Die Anwendung von Physikmaterialien auf Personen wird noch nicht unterstützt.
+ </notification>
+ <notification name="InvalidPhysMatProperty">
+ Eine oder mehrere der angegebenen Eigenschaften für Physikmaterialien waren ungültig.
+ </notification>
+ <notification name="NoPermsAlterStitchingMeshObj">
+ Sie können den Nahttyp eines Mesh-Objekts nicht ändern.
+ </notification>
+ <notification name="NoPermsAlterShapeMeshObj">
+ Sie können die Form eines Mesh-Objekts nicht ändern.
+ </notification>
+ <notification name="FullRegionCantEnter">
+ Sie können diese Region nicht betreten, \nda die Region voll ist.
+ </notification>
+ <notification name="LinkFailedOwnersDiffer">
+ Verknüpfungsfehler – Eigentümer sind unterschiedlich
+ </notification>
+ <notification name="LinkFailedNoModNavmeshAcrossRegions">
+ Verknüpfungsfehler – Navmesh kann nicht regionsübergreifend modifiziert werden.
+ </notification>
+ <notification name="LinkFailedNoPermToEdit">
+ Verknüpfungsfehler, da Sie keine Berechtigung zum Bearbeiten haben.
+ </notification>
+ <notification name="LinkFailedTooManyPrims">
+ Verknüpfungsfehler – zu viele Primitive
+ </notification>
+ <notification name="LinkFailedCantLinkNoCopyNoTrans">
+ Verknüpfungsfehler – nichtkopierfähige Objekte können nicht mit nichtübertragungsfähigen Objekten verknüpft werden
+ </notification>
+ <notification name="LinkFailedNothingLinkable">
+ Verknüpfungsfehler – nichts zum Verknüpfen vorhanden.
+ </notification>
+ <notification name="LinkFailedTooManyPathfindingChars">
+ Verknüpfungsfehler – zu viele Pathfinding-Figuren
+ </notification>
+ <notification name="LinkFailedInsufficientLand">
+ Verknüpfungsfehler – nicht genügend Landressourcen
+ </notification>
+ <notification name="LinkFailedTooMuchPhysics">
+ Objekt verwendet zu viele Physikressourcen – seine Dynamik wurde deaktiviert.
+ </notification>
+ <notification name="TeleportedHomeByObjectOnParcel">
+ Sie wurden vom Objekt „[OBJECT_NAME]“ auf der Parzelle „[PARCEL_NAME]“ nach Hause teleportiert
+ </notification>
+ <notification name="TeleportedHomeByObject">
+ Sie wurden von Objekt „[OBJECT_NAME]“ nach Hause teleportiert.
+ </notification>
+ <notification name="TeleportedByAttachment">
+ Sie wurden von einem Anhang an [ITEM_ID] teleportiert
+ </notification>
+ <notification name="TeleportedByObjectOnParcel">
+ Sie wurden von Objekt „[OBJECT_NAME]“ auf der Parzelle „[PARCEL_NAME]“ teleportiert
+ </notification>
+ <notification name="TeleportedByObjectOwnedBy">
+ Sie wurden von Objekt „[OBJECT_NAME]“, das [OWNER_ID] gehört, teleportiert
+ </notification>
+ <notification name="TeleportedByObjectUnknownUser">
+ Sie wurden von Objekt „[OBJECT_NAME]“, das einem unbekannten Benutzer gehört, teleportiert.
+ </notification>
+ <notification name="CantCreateObjectRegionFull">
+ Angefordertes Objekt kann nicht erstellt werden. Die Region ist voll.
+ </notification>
+ <notification name="CantAttackMultipleObjOneSpot">
+ Sie können nicht mehrere Objekte an ein und derselben Stelle anhängen.
+ </notification>
+ <notification name="CantCreateMultipleObjAtLoc">
+ Sie können hier nicht mehrere Objekte erstellen.
+ </notification>
+ <notification name="UnableToCreateObjTimeOut">
+ Angefordertes Objekt kann nicht erstellt werden. Objekt fehlt in Datenbank.
+ </notification>
+ <notification name="UnableToCreateObjUnknown">
+ Angefordertes Objekt kann nicht erstellt werden. Zeitüberschreitung bei Anforderung. Versuchen Sie es erneut.
+ </notification>
+ <notification name="UnableToCreateObjMissingFromDB">
+ Angefordertes Objekt kann nicht erstellt werden. Versuchen Sie es erneut.
+ </notification>
+ <notification name="RezFailureTookTooLong">
+ Fehler beim Rezzen; Laden des angeforderten Objekts hat zu lang gedauert.
+ </notification>
+ <notification name="FailedToPlaceObjAtLoc">
+ Objekt konnte nicht an angegebenem Ort platziert werden. Versuchen Sie es erneut.
+ </notification>
+ <notification name="CantCreatePlantsOnLand">
+ Auf diesem Land können keine Pflanzen erstellt werden.
+ </notification>
+ <notification name="CantRestoreObjectNoWorldPos">
+ Objekt kann nicht wiederhergestellt werden. Keine Weltposition gefunden.
+ </notification>
+ <notification name="CantRezObjectInvalidMeshData">
+ Objekt kann nicht gerezzt werden, da seine Meshdaten ungültig sind.
+ </notification>
+ <notification name="CantRezObjectTooManyScripts">
+ Objekt kann nicht gerezzt werden, da die Region bereits zu viele Skripts aufweist.
+ </notification>
+ <notification name="CantCreateObjectNoAccess">
+ Ihr Zugangsberechtigungen gestatten nicht das Erstellen von Objekten an dieser Stelle.
+ </notification>
+ <notification name="CantCreateObject">
+ Sie können gegenwärtig keine Objekte erstellen.
+ </notification>
+ <notification name="InvalidObjectParams">
+ Ungültige Objektparameter
+ </notification>
+ <notification name="CantDuplicateObjectNoAcess">
+ Ihre Zugangsberechtigungen gestatten nicht das Duplizieren von Objekten an dieser Stelle.
+ </notification>
+ <notification name="CantChangeShape">
+ Sie können diese Form nicht ändern.
+ </notification>
+ <notification name="NoAccessToClaimObjects">
+ Ihr Zugangsberechtigungen gestatten nicht das Beanspruchen von Objekten an dieser Stelle.
+ </notification>
+ <notification name="DeedFailedNoPermToDeedForGroup">
+ Übertragung fehlgeschlagen, da Sie keine Berechtigung zum Übertragen von Objekten für Ihre Gruppe haben.
+ </notification>
+ <notification name="NoPrivsToBuyObject">
+ Ihr Zugangsberechtigungen gestatten nicht das Kaufen von Objekten an dieser Stelle.
+ </notification>
+ <notification name="CantAttachObjectAvatarSittingOnIt">
+ Objekt kann nicht angehängt werden, da ein Avatar darauf sitzt.
+ </notification>
+ <notification name="WhyAreYouTryingToWearShrubbery">
+ Bäume und Gräser können nicht als Anhänge getragen werden.
+ </notification>
+ <notification name="CantAttachGroupOwnedObjs">
+ Objekte im Gruppenbesitz können nicht angehängt werden.
+ </notification>
+ <notification name="CantAttachObjectsNotOwned">
+ Objekte, die Ihnen nicht gehören, können nicht angehängt werden.
+ </notification>
+ <notification name="CantAttachNavmeshObjects">
+ Objekte, die zum Navmesh beitragen, können nicht angehängt werden.
+ </notification>
+ <notification name="CantAttachObjectNoMovePermissions">
+ Objekt kann nicht angehängt werden, weil Sie es nicht verschieben dürfen.
+ </notification>
+ <notification name="CantAttachNotEnoughScriptResources">
+ Nicht genügend Skriptressourcen verfügbar, um Objekt anzuhängen.
+ </notification>
+ <notification name="CantDropItemTrialUser">
+ Ablegen von Objekten hier nicht möglich; versuchen Sie es mit dem kostenlosen Testbereich.
+ </notification>
+ <notification name="CantDropMeshAttachment">
+ Sie können keine Mesh-Anhänge ablegen. In Inventar zurückführen und inworld rezzen.
+ </notification>
+ <notification name="CantDropAttachmentNoPermission">
+ Anhang konnte nicht abgelegt werden: Ihnen fehlt die Berechtigung zum Ablegen an dieser Stelle.
+ </notification>
+ <notification name="CantDropAttachmentInsufficientLandResources">
+ Anhang konnte nicht abgelegt werden: nicht genügend Landressourcen verfügbar.
+ </notification>
+ <notification name="CantDropAttachmentInsufficientResources">
+ Anhänge konnten nicht abgelegt werden: nicht genügend Ressourcen.
+ </notification>
+ <notification name="CantDropObjectFullParcel">
+ Objekt kann nicht hier abgelegt werden. Die Parzelle ist voll.
+ </notification>
+ <notification name="CantTouchObjectBannedFromParcel">
+ Dieses Objekt kann nicht berührt/angefasst werden, da Sie von der Landparzelle verbannt sind.
+ </notification>
+ <notification name="PlzNarrowDeleteParams">
+ Grenzen Sie Ihre Löschparameter ein.
+ </notification>
+ <notification name="UnableToUploadAsset">
+ Asset kann nicht hochgeladen werden.
+ </notification>
+ <notification name="CantTeleportCouldNotFindUser">
+ Keinen Benutzer zum Teleportieren nach Hause gefunden
+ </notification>
+ <notification name="GodlikeRequestFailed">
+ Anforderdung nach übernatürlichen Kräften fehlgeschlagen
+ </notification>
+ <notification name="GenericRequestFailed">
+ generische Anforderdung fehlgeschlagen
+ </notification>
+ <notification name="CantUploadPostcard">
+ Postkarte kann nicht hochgeladen werden. Versuchen Sie es später erneut.
+ </notification>
+ <notification name="CantFetchInventoryForGroupNotice">
+ Inventardetails für Gruppenmitteilung kann nicht abgerufen werden.
+ </notification>
+ <notification name="CantSendGroupNoticeNotPermitted">
+ Gruppenmitteilung kann nicht gesendet werden – Vorgang nicht gestattet.
+ </notification>
+ <notification name="CantSendGroupNoticeCantConstructInventory">
+ Gruppenmitteilung kann nicht gesendet werden – Bauen von Inventar nicht möglich.
+ </notification>
+ <notification name="CantParceInventoryInNotice">
+ Inventar in Mitteilung kann nicht geparst werden.
+ </notification>
+ <notification name="TerrainUploadFailed">
+ Fehler beim Hochladen von Terrain.
+ </notification>
+ <notification name="TerrainFileWritten">
+ Terraindatei geschrieben.
+ </notification>
+ <notification name="TerrainFileWrittenStartingDownload">
+ Terraindatei geschrieben, Download beginnt...
+ </notification>
+ <notification name="TerrainBaked">
+ Terrain geformt.
+ </notification>
+ <notification name="TenObjectsDisabledPlzRefresh">
+ Nur die ersten 10 ausgewählten Objekte wurden deaktiviert. Aktualisieren Sie die Anzeige und wählen Sie ggf. weitere Objekte aus.
+ </notification>
+ <notification name="UpdateViewerBuyParcel">
+ Um diese Parzelle zu kaufen, müssen Sie Ihren Viewer aktualisieren.
+ </notification>
+ <notification name="CantBuyParcelNotForSale">
+ Kein Kauf möglich; die ausgewählte Parzelle steht nicht zum Verkauf.
+ </notification>
+ <notification name="CantBuySalePriceOrLandAreaChanged">
+ Kein Kauf möglich, da sich der Verkaufspreis oder die Fläche geändert haben.
+ </notification>
+ <notification name="CantBuyParcelNotAuthorized">
+ Sie sind nicht der autorisierte Käufer dieser Parzelle.
+ </notification>
+ <notification name="CantBuyParcelAwaitingPurchaseAuth">
+ Sie können diese Parzelle nicht kaufen, da sie bereits auf Kaufauthorisierung wartet.
+ </notification>
+ <notification name="CantBuildOverflowParcel">
+ Sie können hier keine Objekte bauen, denn dies würde den Rahmen der Parzelle sprengen.
+ </notification>
+ <notification name="SelectedMultipleOwnedLand">
+ Sie haben Land mit unterschiedlichen Besitzern ausgewählt. Wählen Sie ein kleineres Gebiet aus und versuchen Sie es erneut.
+ </notification>
+ <notification name="CantJoinTooFewLeasedParcels">
+ Auswahl enthält nicht genügend gemietete Parzellen zum Zusammenlegen.
+ </notification>
+ <notification name="CantDivideLandMultipleParcelsSelected">
+ Land kann nicht geteilt werden.\nMehr als eine Parzelle ist ausgewählt.\nWählen Sie ein kleineres Stück Land aus.
+ </notification>
+ <notification name="CantDivideLandCantFindParcel">
+ Land kann nicht geteilt werden.\nParzelle nicht auffindbar.\nMelden Sie das Problem über „Hilfe“ -&gt; „Fehler melden“...
+ </notification>
+ <notification name="CantDivideLandWholeParcelSelected">
+ Land kann nicht geteilt werden. Die gesamte Parzelle ist ausgewählt.\nWählen Sie ein kleineres Stück Land aus.
+ </notification>
+ <notification name="LandHasBeenDivided">
+ Land wurde geteilt.
+ </notification>
+ <notification name="PassPurchased">
+ Sie haben einen Pass gekauft.
+ </notification>
+ <notification name="RegionDisallowsClassifieds">
+ Region lässt keine Werbung zu.
+ </notification>
+ <notification name="LandPassExpireSoon">
+ Ihr Pass für dieses Land läuft demnächst ab.
+ </notification>
+ <notification name="CantSitNoSuitableSurface">
+ Keine geeignete Oberfläche zum Sitzen; probieren Sie es an einer anderen Stelle.
+ </notification>
+ <notification name="CantSitNoRoom">
+ Kein Platz zum Hinsetzen; probieren Sie es an einer anderen Stelle.
+ </notification>
+ <notification name="ClaimObjectFailedNoPermission">
+ Objektbeanspruchung fehlgeschlagen, da Sie keine Berechtigung haben.
+ </notification>
+ <notification name="ClaimObjectFailedNoMoney">
+ Objektbeanspruchung fehlgeschlagen, da Sie nicht genügend L$ haben.
+ </notification>
+ <notification name="CantDeedGroupLand">
+ Land in Gruppenbesitz kann nicht übertragen werden.
+ </notification>
+ <notification name="BuyObjectFailedNoMoney">
+ Objektkauf fehlgeschlagen, da Sie nicht genügend L$ haben.
+ </notification>
+ <notification name="BuyInventoryFailedNoMoney">
+ Inventarkauf fehlgeschlagen, da Sie nicht genügend L$ haben.
+ </notification>
+ <notification name="BuyPassFailedNoMoney">
+ Sie haben nicht genügend L$, um einen Pass für dieses Land zu kaufen.
+ </notification>
+ <notification name="CantBuyPassTryAgain">
+ Passkauf momentan nicht möglich. Versuchen Sie es später erneut.
+ </notification>
+ <notification name="CantCreateObjectParcelFull">
+ Objekt kann nicht erstellt werden, \nda die Parzelle voll ist.
+ </notification>
+ <notification name="FailedPlacingObject">
+ Objekt konnte nicht an festgelegtem Ort platziert werden. Versuchen Sie es erneut.
+ </notification>
+ <notification name="CantCreateLandmarkForEvent">
+ Landmarke für dieses Ereignis kann nicht erstellt werden.
+ </notification>
+ <notification name="GodBeatsFreeze">
+ Ihre übernatürlichen Kräfte heben das Einfrieren auf!
+ </notification>
+ <notification name="SpecialPowersRequestFailedLogged">
+ Anforderung nach Superpower fehlgeschlagen. Diese Anforderung wurde protokolliert.
+ </notification>
+ <notification name="ExpireExplanation">
+ Das System kann Ihre Anfrage momentan nicht verarbeiten. Zeitüberschreitung bei Anforderung.
+ </notification>
+ <notification name="DieExplanation">
+ Das System kann Ihre Anfrage nicht verarbeiten.
+ </notification>
+ <notification name="AddPrimitiveFailure">
+ Sie haben nicht genügend Geld, um Primitive zu erstellen.
+ </notification>
+ <notification name="RezObjectFailure">
+ Sie haben nicht genügend Geld, um Objekt zu erstellen.
+ </notification>
+ <notification name="ResetHomePositionNotLegal">
+ Zuhause-Position neu festlegen, da Zuhause nicht zulässig war.
+ </notification>
+ <notification name="CantInviteRegionFull">
+ Sie können gegenwärtig niemanden an Ihren Standort einladen, da die Region voll ist. Versuchen Sie es später erneut.
+ </notification>
+ <notification name="CantSetHomeAtRegion">
+ Diese Region gestattet nicht, dass Sie hier Ihr Zuhause festlegen.
+ </notification>
+ <notification name="ListValidHomeLocations">
+ Ihr Zuhause kann sich nur auf Ihrem eigenen Land oder in einem Infohub auf dem Mainland befinden.
+ </notification>
+ <notification name="SetHomePosition">
+ Position für Zuhause festgelegt.
+ </notification>
+ <notification name="CantDerezInventoryError">
+ Aufgrund eines Inventarfehlers kann das Rezzen dieses Objekts nicht aufgehoben werden.
+ </notification>
+ <notification name="CantCreateRequestedInv">
+ Angefordertes Inventar kann nicht erstellt werden.
+ </notification>
+ <notification name="CantCreateRequestedInvFolder">
+ Angeforderter Inventarordner kann nicht erstellt werden.
+ </notification>
+ <notification name="CantCreateInventory">
+ Dieses Inventar kann nicht erstellt werden.
+ </notification>
+ <notification name="CantCreateLandmark">
+ Landmarke kann nicht erstellt werden.
+ </notification>
+ <notification name="CantCreateOutfit">
+ Im Moment kann kein Outfit erstellt werden. Versuchen Sie es gleich noch einmal.
+ </notification>
+ <notification name="InventoryNotForSale">
+ Inventar steht nicht zum Verkauf.
+ </notification>
+ <notification name="CantFindInvItem">
+ Inventarobjekt kann nicht gefunden werden.
+ </notification>
+ <notification name="CantFindObject">
+ Objekt kann nicht gefunden werden.
+ </notification>
+ <notification name="CantTransfterMoneyRegionDisabled">
+ Geldüberweisungen an Objekte sind in dieser Region gegenwärtig deaktiviert.
+ </notification>
+ <notification name="CantPayNoAgent">
+ Nicht ersichtlich, wer bezahlt werden muss.
+ </notification>
+ <notification name="CantDonateToPublicObjects">
+ Sie können öffentlichen Objekten keine L$ geben.
+ </notification>
+ <notification name="InventoryCreationInWorldObjectFailed">
+ Inventarerstellung für Inworld-Objekt fehlgeschlagen.
+ </notification>
+ <notification name="UserBalanceOrLandUsageError">
+ Aufgrund eines internen Fehlers konnte Ihr Viewer nicht ordnungsgemäß aktualisiert werden. Der in Ihrem Viewer angezeigte L$-Kontostand oder Parzellenbesitz stimmt möglicherweise nicht mit dem aktuellen Stand auf den Servern überein.
+ </notification>
+ <notification name="LargePrimAgentIntersect">
+ Große Prims, die sich mit anderen Spielern überschneiden, können nicht erstellt werden. Bitte erneut versuchen, wenn sich die anderen Spieler bewegt haben.
+ </notification>
+ <notification name="PreferenceChatClearLog">
+ Dadurch werden die Protokolle vorheriger Unterhaltungen und alle Backups dieser Datei gelöscht.
+ <usetemplate ignoretext="Löschen des Protokolls vorheriger Unterhaltungen bestätigen." name="okcancelignore" notext="Abbrechen" yestext="OK"/>
+ </notification>
+ <notification name="PreferenceChatDeleteTranscripts">
+ Dadurch werden die Transkripte aller vorherigen Unterhaltungen gelöscht. Die Liste vergangener Unterhaltungen ist davon nicht betroffen. Alle Dateien mit den Suffixen .txt und txt.backup im Order [FOLDER] werden gelöscht.
+ <usetemplate ignoretext="Um Bestätigung bitten, bevor ich Transkripte lösche." name="okcancelignore" notext="Abbrechen" yestext="OK"/>
+ </notification>
+ <notification name="PreferenceChatPathChanged">
+ Dateien können nicht verschoben werden. Vorheriger Pfad wurde wiederhergestellt.
+ <usetemplate ignoretext="Dateien können nicht verschoben werden. Vorheriger Pfad wurde wiederhergestellt." name="okignore" yestext="OK"/>
+ </notification>
</notifications>
diff --git a/indra/newview/skins/default/xui/de/outfit_accordion_tab.xml b/indra/newview/skins/default/xui/de/outfit_accordion_tab.xml
index bac885e5d8..bac885e5d8 100644..100755
--- a/indra/newview/skins/default/xui/de/outfit_accordion_tab.xml
+++ b/indra/newview/skins/default/xui/de/outfit_accordion_tab.xml
diff --git a/indra/newview/skins/default/xui/de/panel_active_object_row.xml b/indra/newview/skins/default/xui/de/panel_active_object_row.xml
index 00de705a30..00de705a30 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_active_object_row.xml
+++ b/indra/newview/skins/default/xui/de/panel_active_object_row.xml
diff --git a/indra/newview/skins/default/xui/de/panel_adhoc_control_panel.xml b/indra/newview/skins/default/xui/de/panel_adhoc_control_panel.xml
index 6ad18781f5..6ad18781f5 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_adhoc_control_panel.xml
+++ b/indra/newview/skins/default/xui/de/panel_adhoc_control_panel.xml
diff --git a/indra/newview/skins/default/xui/de/panel_avatar_list_item.xml b/indra/newview/skins/default/xui/de/panel_avatar_list_item.xml
index dcfcffa6e2..79a2ebe9df 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_avatar_list_item.xml
+++ b/indra/newview/skins/default/xui/de/panel_avatar_list_item.xml
@@ -27,5 +27,6 @@
<icon name="permission_edit_mine_icon" tool_tip="Dieser Freund kann Ihre Objekte bearbeiten, löschen und an sich nehmen"/>
<icon name="permission_map_icon" tool_tip="Dieser Freund kann Sie auf der Karte finden"/>
<icon name="permission_online_icon" tool_tip="Dieser Freund kann sehen, wenn Sie online sind"/>
+ <button name="info_btn" tool_tip="Mehr Infos"/>
<button name="profile_btn" tool_tip="Profil anzeigen"/>
</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_avatar_tag.xml b/indra/newview/skins/default/xui/de/panel_avatar_tag.xml
index 09f930ec01..09f930ec01 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_avatar_tag.xml
+++ b/indra/newview/skins/default/xui/de/panel_avatar_tag.xml
diff --git a/indra/newview/skins/default/xui/de/panel_block_list_sidetray.xml b/indra/newview/skins/default/xui/de/panel_block_list_sidetray.xml
index 2d140515d4..c105a5b8a3 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_block_list_sidetray.xml
+++ b/indra/newview/skins/default/xui/de/panel_block_list_sidetray.xml
@@ -1,10 +1,11 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel name="block_list_panel" width="300">
- <text left_pad="5" name="title_text" width="260">
- Liste der ignorierten Einwohner
- </text>
- <scroll_list name="blocked" tool_tip="Liste der zur Zeit ignorierten Einwohner" width="290"/>
- <button label="Einwohner ignorieren" label_selected="Einwohner ignorieren..." name="Block resident..." tool_tip="Wählen Sie einen Einwohner, um ihn zu ignorieren"/>
- <button label="Objekt nach Name ignorieren" label_selected="Objekt nach Name ignorieren..." name="Block object by name..." tool_tip="Ein Objekt auswählen, um nach Namen zu ignorieren."/>
- <button label="Freischalten" label_selected="Freischalten" name="Unblock" tool_tip="Einwohner oder Objekt von der Liste der ignorierten Einwohner oder Objekte entfernen"/>
+ <panel label="bottom_panel" name="blocked_buttons_panel">
+ <filter_editor label="Filtern" name="blocked_filter_input"/>
+ <menu_button name="blocked_gear_btn" tool_tip="Aktionen für ausgewählte(s) Person/Objekt"/>
+ <menu_button name="view_btn" tool_tip="Sortieroptionen"/>
+ <menu_button name="plus_btn" tool_tip="Einwohner oder Objekt zum ignorieren auswählen"/>
+ <button name="unblock_btn" tool_tip="Einwohner oder Objekt aus der Liste der ignorierten Einwohner oder Objekte entfernen"/>
+ </panel>
+ <block_list name="blocked" tool_tip="Liste der zur Zeit ignorierten Einwohner" width="290"/>
</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_body_parts_list_item.xml b/indra/newview/skins/default/xui/de/panel_body_parts_list_item.xml
index 799586f021..799586f021 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_body_parts_list_item.xml
+++ b/indra/newview/skins/default/xui/de/panel_body_parts_list_item.xml
diff --git a/indra/newview/skins/default/xui/de/panel_bodyparts_list_button_bar.xml b/indra/newview/skins/default/xui/de/panel_bodyparts_list_button_bar.xml
index 4d7e65405a..4d7e65405a 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_bodyparts_list_button_bar.xml
+++ b/indra/newview/skins/default/xui/de/panel_bodyparts_list_button_bar.xml
diff --git a/indra/newview/skins/default/xui/de/panel_bottomtray.xml b/indra/newview/skins/default/xui/de/panel_bottomtray.xml
deleted file mode 100644
index afe9836401..0000000000
--- a/indra/newview/skins/default/xui/de/panel_bottomtray.xml
+++ /dev/null
@@ -1,47 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel name="bottom_tray">
- <string name="DragIndicationImageName" value="Accordion_ArrowOpened_Off"/>
- <string name="SpeakBtnToolTip" value="Schaltet Mikrofon ein/aus"/>
- <string name="VoiceControlBtnToolTip" value="Voice-Chat-Steuerung anzeigen/ausblenden"/>
- <layout_stack name="toolbar_stack">
- <layout_panel name="speak_panel">
- <talk_button name="talk">
- <speak_button label="Sprechen" label_selected="Sprechen" name="speak_btn"/>
- </talk_button>
- </layout_panel>
- <layout_panel name="gesture_panel">
- <gesture_combo_list label="Gesten" name="Gesture" tool_tip="Gesten anzeigen/ausblenden"/>
- </layout_panel>
- <layout_panel name="movement_panel">
- <bottomtray_button label="Bewegen" name="movement_btn" tool_tip="Bewegungssteuerung anzeigen/ausblenden"/>
- </layout_panel>
- <layout_panel name="cam_panel">
- <bottomtray_button label="Ansicht" name="camera_btn" tool_tip="Kamerasteuerung anzeigen/ausblenden"/>
- </layout_panel>
- <layout_panel name="snapshot_panel">
- <bottomtray_button label="" name="snapshots" tool_tip="Foto machen"/>
- </layout_panel>
- <layout_panel name="build_btn_panel">
- <bottomtray_button label="Bauen" name="build_btn" tool_tip="Bauwerkzeuge ein-/ausblenden"/>
- </layout_panel>
- <layout_panel name="search_btn_panel">
- <bottomtray_button label="Suche" name="search_btn" tool_tip="Suche anzeigen/ausblenden"/>
- </layout_panel>
- <layout_panel name="world_map_btn_panel">
- <bottomtray_button label="Karte" name="world_map_btn" tool_tip="Karte ein-/ausblenden"/>
- </layout_panel>
- <layout_panel name="mini_map_btn_panel">
- <bottomtray_button label="Minikarte" name="mini_map_btn" tool_tip="Minikarte ein-/ausblenden"/>
- </layout_panel>
- <layout_panel name="im_well_panel">
- <chiclet_im_well name="im_well">
- <button name="Unread IM messages" tool_tip="IMs"/>
- </chiclet_im_well>
- </layout_panel>
- <layout_panel name="notification_well_panel">
- <chiclet_notification name="notification_well">
- <button name="Unread" tool_tip="Benachrichtigungen"/>
- </chiclet_notification>
- </layout_panel>
- </layout_stack>
-</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_bottomtray_lite.xml b/indra/newview/skins/default/xui/de/panel_bottomtray_lite.xml
index 9c84105254..9c84105254 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_bottomtray_lite.xml
+++ b/indra/newview/skins/default/xui/de/panel_bottomtray_lite.xml
diff --git a/indra/newview/skins/default/xui/de/panel_chat_header.xml b/indra/newview/skins/default/xui/de/panel_chat_header.xml
index 7916bf5155..7916bf5155 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_chat_header.xml
+++ b/indra/newview/skins/default/xui/de/panel_chat_header.xml
diff --git a/indra/newview/skins/default/xui/de/panel_chiclet_bar.xml b/indra/newview/skins/default/xui/de/panel_chiclet_bar.xml
index bcc6772bb9..bcc6772bb9 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_chiclet_bar.xml
+++ b/indra/newview/skins/default/xui/de/panel_chiclet_bar.xml
diff --git a/indra/newview/skins/default/xui/de/panel_classified_info.xml b/indra/newview/skins/default/xui/de/panel_classified_info.xml
index 007e9d69f0..007e9d69f0 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_classified_info.xml
+++ b/indra/newview/skins/default/xui/de/panel_classified_info.xml
diff --git a/indra/newview/skins/default/xui/de/panel_clothing_list_button_bar.xml b/indra/newview/skins/default/xui/de/panel_clothing_list_button_bar.xml
index fc45c9ce79..fc45c9ce79 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_clothing_list_button_bar.xml
+++ b/indra/newview/skins/default/xui/de/panel_clothing_list_button_bar.xml
diff --git a/indra/newview/skins/default/xui/de/panel_clothing_list_item.xml b/indra/newview/skins/default/xui/de/panel_clothing_list_item.xml
index 945acb02d7..945acb02d7 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_clothing_list_item.xml
+++ b/indra/newview/skins/default/xui/de/panel_clothing_list_item.xml
diff --git a/indra/newview/skins/default/xui/de/panel_cof_wearables.xml b/indra/newview/skins/default/xui/de/panel_cof_wearables.xml
index 12294a43ce..12294a43ce 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_cof_wearables.xml
+++ b/indra/newview/skins/default/xui/de/panel_cof_wearables.xml
diff --git a/indra/newview/skins/default/xui/de/panel_conversation_list_item.xml b/indra/newview/skins/default/xui/de/panel_conversation_list_item.xml
new file mode 100644
index 0000000000..a9bfe4754e
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/panel_conversation_list_item.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="conversation_list_item">
+ <layout_stack name="conversation_item_stack">
+ <layout_panel name="conversation_title_panel">
+ <text name="conversation_title" value="(laden)"/>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_conversation_log_list_item.xml b/indra/newview/skins/default/xui/de/panel_conversation_log_list_item.xml
new file mode 100644
index 0000000000..afeaa14e81
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/panel_conversation_log_list_item.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="conversation_log_list_item">
+ <icon name="voice_session_icon" tool_tip="Enthielt eine Voice-Unterhaltung"/>
+ <icon name="unread_ims_icon" tool_tip="Nachrichten trafen ein, während Sie abgemeldet waren"/>
+ <button name="delete_btn" tool_tip="Diesen Eintrag entfernen"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_deletable_wearable_list_item.xml b/indra/newview/skins/default/xui/de/panel_deletable_wearable_list_item.xml
index a27252e23e..a27252e23e 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_deletable_wearable_list_item.xml
+++ b/indra/newview/skins/default/xui/de/panel_deletable_wearable_list_item.xml
diff --git a/indra/newview/skins/default/xui/de/panel_dummy_clothing_list_item.xml b/indra/newview/skins/default/xui/de/panel_dummy_clothing_list_item.xml
index b7ad1bdc1b..b7ad1bdc1b 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_dummy_clothing_list_item.xml
+++ b/indra/newview/skins/default/xui/de/panel_dummy_clothing_list_item.xml
diff --git a/indra/newview/skins/default/xui/de/panel_edit_alpha.xml b/indra/newview/skins/default/xui/de/panel_edit_alpha.xml
index 4c6facf5e3..4c6facf5e3 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_edit_alpha.xml
+++ b/indra/newview/skins/default/xui/de/panel_edit_alpha.xml
diff --git a/indra/newview/skins/default/xui/de/panel_edit_classified.xml b/indra/newview/skins/default/xui/de/panel_edit_classified.xml
index bd270697ea..bd270697ea 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_edit_classified.xml
+++ b/indra/newview/skins/default/xui/de/panel_edit_classified.xml
diff --git a/indra/newview/skins/default/xui/de/panel_edit_eyes.xml b/indra/newview/skins/default/xui/de/panel_edit_eyes.xml
index 69bcf2fb71..69bcf2fb71 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_edit_eyes.xml
+++ b/indra/newview/skins/default/xui/de/panel_edit_eyes.xml
diff --git a/indra/newview/skins/default/xui/de/panel_edit_gloves.xml b/indra/newview/skins/default/xui/de/panel_edit_gloves.xml
index fb7d18f66c..fb7d18f66c 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_edit_gloves.xml
+++ b/indra/newview/skins/default/xui/de/panel_edit_gloves.xml
diff --git a/indra/newview/skins/default/xui/de/panel_edit_hair.xml b/indra/newview/skins/default/xui/de/panel_edit_hair.xml
index d6efde8306..d6efde8306 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_edit_hair.xml
+++ b/indra/newview/skins/default/xui/de/panel_edit_hair.xml
diff --git a/indra/newview/skins/default/xui/de/panel_edit_jacket.xml b/indra/newview/skins/default/xui/de/panel_edit_jacket.xml
index 1b7c1d79a5..1b7c1d79a5 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_edit_jacket.xml
+++ b/indra/newview/skins/default/xui/de/panel_edit_jacket.xml
diff --git a/indra/newview/skins/default/xui/de/panel_edit_pants.xml b/indra/newview/skins/default/xui/de/panel_edit_pants.xml
index 533cf20412..533cf20412 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_edit_pants.xml
+++ b/indra/newview/skins/default/xui/de/panel_edit_pants.xml
diff --git a/indra/newview/skins/default/xui/de/panel_edit_physics.xml b/indra/newview/skins/default/xui/de/panel_edit_physics.xml
index bd9c84577a..bd9c84577a 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_edit_physics.xml
+++ b/indra/newview/skins/default/xui/de/panel_edit_physics.xml
diff --git a/indra/newview/skins/default/xui/de/panel_edit_pick.xml b/indra/newview/skins/default/xui/de/panel_edit_pick.xml
index aafffc7ae3..aafffc7ae3 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_edit_pick.xml
+++ b/indra/newview/skins/default/xui/de/panel_edit_pick.xml
diff --git a/indra/newview/skins/default/xui/de/panel_edit_profile.xml b/indra/newview/skins/default/xui/de/panel_edit_profile.xml
index 03974e7f7f..03974e7f7f 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_edit_profile.xml
+++ b/indra/newview/skins/default/xui/de/panel_edit_profile.xml
diff --git a/indra/newview/skins/default/xui/de/panel_edit_shape.xml b/indra/newview/skins/default/xui/de/panel_edit_shape.xml
index 80d3b29cad..80d3b29cad 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_edit_shape.xml
+++ b/indra/newview/skins/default/xui/de/panel_edit_shape.xml
diff --git a/indra/newview/skins/default/xui/de/panel_edit_shirt.xml b/indra/newview/skins/default/xui/de/panel_edit_shirt.xml
index 4f140a2b01..4f140a2b01 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_edit_shirt.xml
+++ b/indra/newview/skins/default/xui/de/panel_edit_shirt.xml
diff --git a/indra/newview/skins/default/xui/de/panel_edit_shoes.xml b/indra/newview/skins/default/xui/de/panel_edit_shoes.xml
index abedb8d89e..abedb8d89e 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_edit_shoes.xml
+++ b/indra/newview/skins/default/xui/de/panel_edit_shoes.xml
diff --git a/indra/newview/skins/default/xui/de/panel_edit_skin.xml b/indra/newview/skins/default/xui/de/panel_edit_skin.xml
index 60f6919485..60f6919485 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_edit_skin.xml
+++ b/indra/newview/skins/default/xui/de/panel_edit_skin.xml
diff --git a/indra/newview/skins/default/xui/de/panel_edit_skirt.xml b/indra/newview/skins/default/xui/de/panel_edit_skirt.xml
index 07ce8a7436..07ce8a7436 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_edit_skirt.xml
+++ b/indra/newview/skins/default/xui/de/panel_edit_skirt.xml
diff --git a/indra/newview/skins/default/xui/de/panel_edit_socks.xml b/indra/newview/skins/default/xui/de/panel_edit_socks.xml
index 4e72b63f49..4e72b63f49 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_edit_socks.xml
+++ b/indra/newview/skins/default/xui/de/panel_edit_socks.xml
diff --git a/indra/newview/skins/default/xui/de/panel_edit_tattoo.xml b/indra/newview/skins/default/xui/de/panel_edit_tattoo.xml
index 075a9d752a..075a9d752a 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_edit_tattoo.xml
+++ b/indra/newview/skins/default/xui/de/panel_edit_tattoo.xml
diff --git a/indra/newview/skins/default/xui/de/panel_edit_underpants.xml b/indra/newview/skins/default/xui/de/panel_edit_underpants.xml
index 1fad0ccedb..1fad0ccedb 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_edit_underpants.xml
+++ b/indra/newview/skins/default/xui/de/panel_edit_underpants.xml
diff --git a/indra/newview/skins/default/xui/de/panel_edit_undershirt.xml b/indra/newview/skins/default/xui/de/panel_edit_undershirt.xml
index 9d193ffedb..9d193ffedb 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_edit_undershirt.xml
+++ b/indra/newview/skins/default/xui/de/panel_edit_undershirt.xml
diff --git a/indra/newview/skins/default/xui/de/panel_edit_wearable.xml b/indra/newview/skins/default/xui/de/panel_edit_wearable.xml
index 94a79a0bbd..94a79a0bbd 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_edit_wearable.xml
+++ b/indra/newview/skins/default/xui/de/panel_edit_wearable.xml
diff --git a/indra/newview/skins/default/xui/de/panel_group_control_panel.xml b/indra/newview/skins/default/xui/de/panel_group_control_panel.xml
index 9cb72fafff..9cb72fafff 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_group_control_panel.xml
+++ b/indra/newview/skins/default/xui/de/panel_group_control_panel.xml
diff --git a/indra/newview/skins/default/xui/de/panel_group_general.xml b/indra/newview/skins/default/xui/de/panel_group_general.xml
index 9d4301de73..9d4301de73 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_group_general.xml
+++ b/indra/newview/skins/default/xui/de/panel_group_general.xml
diff --git a/indra/newview/skins/default/xui/de/panel_group_info_sidetray.xml b/indra/newview/skins/default/xui/de/panel_group_info_sidetray.xml
index bf4d44af52..bf4d44af52 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_group_info_sidetray.xml
+++ b/indra/newview/skins/default/xui/de/panel_group_info_sidetray.xml
diff --git a/indra/newview/skins/default/xui/de/panel_group_invite.xml b/indra/newview/skins/default/xui/de/panel_group_invite.xml
index 5f323d80dd..c32d2fe4bf 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_group_invite.xml
+++ b/indra/newview/skins/default/xui/de/panel_group_invite.xml
@@ -9,6 +9,9 @@
<panel.string name="already_in_group">
Einige der ausgewählten Einwohner sind bereits Gruppenmitglieder und haben aus diesem Grund keine Einladung erhalten.
</panel.string>
+ <panel.string name="invite_selection_too_large">
+ Gruppeneinladungen nicht gesendet: zu viele Einwohner ausgewählt. Gruppeneinladungen sind auf 100 Einwohner pro Anfrage beschränkt.
+ </panel.string>
<text name="help_text">
Sie können mehrere Einwohner in Ihre Gruppe einladen. Klicken Sie hierzu auf „Einwohnerliste öffnen“.
</text>
diff --git a/indra/newview/skins/default/xui/de/panel_group_land_money.xml b/indra/newview/skins/default/xui/de/panel_group_land_money.xml
index d9d237be2e..d9d237be2e 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_group_land_money.xml
+++ b/indra/newview/skins/default/xui/de/panel_group_land_money.xml
diff --git a/indra/newview/skins/default/xui/de/panel_group_list_item.xml b/indra/newview/skins/default/xui/de/panel_group_list_item.xml
index d097a2b18c..fc911a64df 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_group_list_item.xml
+++ b/indra/newview/skins/default/xui/de/panel_group_list_item.xml
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel name="group_list_item">
<text name="group_name" value="Unbekannt"/>
+ <button name="info_btn" tool_tip="Mehr Infos"/>
<button name="profile_btn" tool_tip="Profil anzeigen"/>
</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_group_notices.xml b/indra/newview/skins/default/xui/de/panel_group_notices.xml
index df423cc69a..df423cc69a 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_group_notices.xml
+++ b/indra/newview/skins/default/xui/de/panel_group_notices.xml
diff --git a/indra/newview/skins/default/xui/de/panel_group_notify.xml b/indra/newview/skins/default/xui/de/panel_group_notify.xml
index 9c05e99786..9c05e99786 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_group_notify.xml
+++ b/indra/newview/skins/default/xui/de/panel_group_notify.xml
diff --git a/indra/newview/skins/default/xui/de/panel_group_roles.xml b/indra/newview/skins/default/xui/de/panel_group_roles.xml
index f297d32a91..f297d32a91 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_group_roles.xml
+++ b/indra/newview/skins/default/xui/de/panel_group_roles.xml
diff --git a/indra/newview/skins/default/xui/de/panel_im_control_panel.xml b/indra/newview/skins/default/xui/de/panel_im_control_panel.xml
index abf8011d9d..abf8011d9d 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_im_control_panel.xml
+++ b/indra/newview/skins/default/xui/de/panel_im_control_panel.xml
diff --git a/indra/newview/skins/default/xui/de/panel_instant_message.xml b/indra/newview/skins/default/xui/de/panel_instant_message.xml
index 372def78ca..372def78ca 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_instant_message.xml
+++ b/indra/newview/skins/default/xui/de/panel_instant_message.xml
diff --git a/indra/newview/skins/default/xui/de/panel_inventory_item.xml b/indra/newview/skins/default/xui/de/panel_inventory_item.xml
index d18047fbcf..d18047fbcf 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_inventory_item.xml
+++ b/indra/newview/skins/default/xui/de/panel_inventory_item.xml
diff --git a/indra/newview/skins/default/xui/de/panel_landmark_info.xml b/indra/newview/skins/default/xui/de/panel_landmark_info.xml
index 10cf34c170..10cf34c170 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_landmark_info.xml
+++ b/indra/newview/skins/default/xui/de/panel_landmark_info.xml
diff --git a/indra/newview/skins/default/xui/de/panel_landmarks.xml b/indra/newview/skins/default/xui/de/panel_landmarks.xml
index c1f8a20728..c1f8a20728 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_landmarks.xml
+++ b/indra/newview/skins/default/xui/de/panel_landmarks.xml
diff --git a/indra/newview/skins/default/xui/de/panel_login.xml b/indra/newview/skins/default/xui/de/panel_login.xml
index 553bd3e2ff..8cc467185c 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_login.xml
+++ b/indra/newview/skins/default/xui/de/panel_login.xml
@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel name="panel_login">
- <panel.string name="create_account_url">
- http://de.secondlife.com/registration/
- </panel.string>
<panel.string name="forgot_password_url">
http://secondlife.com/account/request.php?lang=de
</panel.string>
<layout_stack name="login_widgets">
<layout_panel name="login">
+ <text name="log_in_text">
+ ANMELDEN
+ </text>
<text name="username_text">
Benutzername:
</text>
@@ -15,17 +15,10 @@
<text name="password_text">
Kennwort:
</text>
- <check_box label="Kennwort merken" name="remember_check"/>
- <button label="Anmelden" name="connect_btn"/>
- <text name="mode_selection_text">
- Modus:
- </text>
- <combo_box name="mode_combo" tool_tip="Wählen Sie den gewünschten Modus aus. Basis: Second Life schnell und einfach erkunden und chatten. Erweitert: Zugriff auf zusätzliche Funktionen.">
- <combo_box.item label="Basis" name="Basic"/>
- <combo_box.item label="Erweitert" name="Advanced"/>
- </combo_box>
+ </layout_panel>
+ <layout_panel name="start_location_panel">
<text name="start_location_text">
- Hier anfangen:
+ Hier starten:
</text>
<combo_box name="start_location_combo">
<combo_box.item label="Mein letzter Standort" name="MyLastLocation"/>
@@ -33,16 +26,21 @@
<combo_box.item label="&lt;Region eingeben&gt;" name="Typeregionname"/>
</combo_box>
</layout_panel>
- <layout_panel name="links">
- <text name="create_new_account_text">
- Registrieren
+ <layout_panel name="links_login_panel">
+ <text name="login_help">
+ Brauchen Sie Hilfe beim Anmelden?
</text>
<text name="forgot_password_text">
Benutzernamen oder Kennwort vergessen?
</text>
- <text name="login_help">
- Sie brauchen Hilfe?
+ <button label="Anmelden" name="connect_btn"/>
+ <check_box label="Kennwort speichern" name="remember_check"/>
+ </layout_panel>
+ <layout_panel name="links">
+ <text name="create_account_text">
+ IHR KONTO ERSTELLEN
</text>
+ <button label="Jetzt starten" name="create_new_account_btn"/>
</layout_panel>
</layout_stack>
</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_main_inventory.xml b/indra/newview/skins/default/xui/de/panel_main_inventory.xml
index 2f00782ef0..2f00782ef0 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_main_inventory.xml
+++ b/indra/newview/skins/default/xui/de/panel_main_inventory.xml
diff --git a/indra/newview/skins/default/xui/de/panel_me.xml b/indra/newview/skins/default/xui/de/panel_me.xml
index f49446fbbf..f49446fbbf 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_me.xml
+++ b/indra/newview/skins/default/xui/de/panel_me.xml
diff --git a/indra/newview/skins/default/xui/de/panel_media_settings_general.xml b/indra/newview/skins/default/xui/de/panel_media_settings_general.xml
index 75c9057571..75c9057571 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_media_settings_general.xml
+++ b/indra/newview/skins/default/xui/de/panel_media_settings_general.xml
diff --git a/indra/newview/skins/default/xui/de/panel_media_settings_permissions.xml b/indra/newview/skins/default/xui/de/panel_media_settings_permissions.xml
index dd408b8275..dd408b8275 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_media_settings_permissions.xml
+++ b/indra/newview/skins/default/xui/de/panel_media_settings_permissions.xml
diff --git a/indra/newview/skins/default/xui/de/panel_media_settings_security.xml b/indra/newview/skins/default/xui/de/panel_media_settings_security.xml
index adc0d22ce6..adc0d22ce6 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_media_settings_security.xml
+++ b/indra/newview/skins/default/xui/de/panel_media_settings_security.xml
diff --git a/indra/newview/skins/default/xui/de/panel_navigation_bar.xml b/indra/newview/skins/default/xui/de/panel_navigation_bar.xml
index 53794b6619..53794b6619 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_navigation_bar.xml
+++ b/indra/newview/skins/default/xui/de/panel_navigation_bar.xml
diff --git a/indra/newview/skins/default/xui/de/panel_nearby_chat.xml b/indra/newview/skins/default/xui/de/panel_nearby_chat.xml
index 07ad761791..07ad761791 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_nearby_chat.xml
+++ b/indra/newview/skins/default/xui/de/panel_nearby_chat.xml
diff --git a/indra/newview/skins/default/xui/de/panel_nearby_chat_bar.xml b/indra/newview/skins/default/xui/de/panel_nearby_chat_bar.xml
index 08cc0b0ec8..69cf6d98de 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_nearby_chat_bar.xml
+++ b/indra/newview/skins/default/xui/de/panel_nearby_chat_bar.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel name="chat_bar">
+<panel name="nearby_chat">
<line_editor label="Zum Chatten hier klicken." name="chat_box" tool_tip="Eingabe drücken, um zu sprechen, Strg-Eingabe drücken, um zu Rufen."/>
<button name="show_nearby_chat" tool_tip="Protokoll des Chats in der Nähe anzeigen/ausblenden"/>
</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_nearby_media.xml b/indra/newview/skins/default/xui/de/panel_nearby_media.xml
index 90885c7192..90885c7192 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_nearby_media.xml
+++ b/indra/newview/skins/default/xui/de/panel_nearby_media.xml
diff --git a/indra/newview/skins/default/xui/de/panel_notifications_channel.xml b/indra/newview/skins/default/xui/de/panel_notifications_channel.xml
index 35bd76ce70..35bd76ce70 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_notifications_channel.xml
+++ b/indra/newview/skins/default/xui/de/panel_notifications_channel.xml
diff --git a/indra/newview/skins/default/xui/de/panel_notify_textbox.xml b/indra/newview/skins/default/xui/de/panel_notify_textbox.xml
index da672a0309..da672a0309 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_notify_textbox.xml
+++ b/indra/newview/skins/default/xui/de/panel_notify_textbox.xml
diff --git a/indra/newview/skins/default/xui/de/panel_online_status_toast.xml b/indra/newview/skins/default/xui/de/panel_online_status_toast.xml
index 7c7448c061..7c7448c061 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_online_status_toast.xml
+++ b/indra/newview/skins/default/xui/de/panel_online_status_toast.xml
diff --git a/indra/newview/skins/default/xui/de/panel_outbox_inventory.xml b/indra/newview/skins/default/xui/de/panel_outbox_inventory.xml
index 4006022ffc..4006022ffc 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_outbox_inventory.xml
+++ b/indra/newview/skins/default/xui/de/panel_outbox_inventory.xml
diff --git a/indra/newview/skins/default/xui/de/panel_outfit_edit.xml b/indra/newview/skins/default/xui/de/panel_outfit_edit.xml
index 1af0492aa1..1af0492aa1 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_outfit_edit.xml
+++ b/indra/newview/skins/default/xui/de/panel_outfit_edit.xml
diff --git a/indra/newview/skins/default/xui/de/panel_outfits_inventory.xml b/indra/newview/skins/default/xui/de/panel_outfits_inventory.xml
index d5158b2d97..d5158b2d97 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_outfits_inventory.xml
+++ b/indra/newview/skins/default/xui/de/panel_outfits_inventory.xml
diff --git a/indra/newview/skins/default/xui/de/panel_outfits_inventory_gear_default.xml b/indra/newview/skins/default/xui/de/panel_outfits_inventory_gear_default.xml
index ad0e039070..ad0e039070 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_outfits_inventory_gear_default.xml
+++ b/indra/newview/skins/default/xui/de/panel_outfits_inventory_gear_default.xml
diff --git a/indra/newview/skins/default/xui/de/panel_outfits_list.xml b/indra/newview/skins/default/xui/de/panel_outfits_list.xml
index ea3a938be9..ea3a938be9 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_outfits_list.xml
+++ b/indra/newview/skins/default/xui/de/panel_outfits_list.xml
diff --git a/indra/newview/skins/default/xui/de/panel_outfits_wearing.xml b/indra/newview/skins/default/xui/de/panel_outfits_wearing.xml
index 27141796a8..27141796a8 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_outfits_wearing.xml
+++ b/indra/newview/skins/default/xui/de/panel_outfits_wearing.xml
diff --git a/indra/newview/skins/default/xui/de/panel_people.xml b/indra/newview/skins/default/xui/de/panel_people.xml
index 4e76147746..2d56d6b7d2 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_people.xml
+++ b/indra/newview/skins/default/xui/de/panel_people.xml
@@ -14,81 +14,56 @@ Sie suchen nach Leuten? Verwenden Sie die [secondlife:///app/worldmap Karte].
<string name="no_filtered_friends_msg">
Sie haben nicht das Richtige gefunden? Versuchen Sie es mit der [secondlife:///app/search/people/[SEARCH_TERM] Suche].
</string>
- <string name="people_filter_label" value="Nach Leuten filtern"/>
- <string name="groups_filter_label" value="Nach Gruppen filtern"/>
<string name="no_filtered_groups_msg" value="Sie haben nicht das Richtige gefunden? Versuchen Sie es mit der [secondlife:///app/search/groups/[SEARCH_TERM] Suche]."/>
<string name="no_groups_msg" value="Suchen Sie nach Gruppen? Versuchen Sie es mit der [secondlife:///app/search/groups Suche]."/>
<string name="MiniMapToolTipMsg" value="[REGION](Doppelklicken, um Karte zu öffnen; Umschalttaste gedrückt halten und ziehen, um zu schwenken)"/>
<string name="AltMiniMapToolTipMsg" value="[REGION](Doppelklicken, um zu teleportieren; Umschalttaste gedrückt halten und ziehen, um zu schwenken)"/>
- <filter_editor label="Filter" name="filter_input"/>
<tab_container name="tabs">
<panel label="IN DER NÄHE" name="nearby_panel">
- <panel label="bottom_panel" name="bottom_panel">
- <menu_button name="nearby_view_sort_btn" tool_tip="Optionen"/>
- <button name="add_friend_btn" tool_tip="Ausgewählten Einwohner zur Freundeliste hinzufügen"/>
+ <panel label="bottom_panel" name="nearby_buttons_panel">
+ <filter_editor label="Nach Personen filtern" name="nearby_filter_input"/>
+ <button name="gear_btn" tool_tip="Aktionen für ausgewählte Person"/>
+ <menu_button name="nearby_view_btn" tool_tip="Anzeige-/Sortieroptionen"/>
+ <button name="add_friend_btn" tool_tip="Einem Einwohner die Freundschaft anbieten"/>
+ <dnd_button name="nearby_del_btn" tool_tip="Ausgewählte Person als Freund entfernen"/>
</panel>
</panel>
- <panel label="MEINE FREUNDE" name="friends_panel">
+ <panel label="FREUNDE" name="friends_panel">
+ <panel label="bottom_panel" name="friends_buttons_panel">
+ <filter_editor label="Nach Personen filtern" name="friends_filter_input"/>
+ <button name="gear_btn" tool_tip="Aktionen für ausgewählte Person"/>
+ <menu_button name="friends_view_btn" tool_tip="Anzeige-/Sortieroptionen"/>
+ <button name="friends_add_btn" tool_tip="Einem Einwohner die Freundschaft anbieten"/>
+ <dnd_button name="friends_del_btn" tool_tip="Ausgewählte Person als Freund entfernen"/>
+ </panel>
<accordion name="friends_accordion">
<accordion_tab name="tab_online" title="Online"/>
<accordion_tab name="tab_all" title="Alle"/>
</accordion>
- <panel label="bottom_panel" name="bottom_panel">
- <layout_stack name="bottom_panel">
- <layout_panel name="options_gear_btn_panel">
- <menu_button name="friends_viewsort_btn" tool_tip="Zusätzliche Optionen anzeigen"/>
- </layout_panel>
- <layout_panel name="add_btn_panel">
- <button name="add_btn" tool_tip="Bieten Sie einem Einwohner die Freundschaft an"/>
- </layout_panel>
- <layout_panel name="trash_btn_panel">
- <dnd_button name="del_btn" tool_tip="Ausgewählte Person aus Ihrer Freundesliste entfernen"/>
- </layout_panel>
- </layout_stack>
- </panel>
</panel>
- <panel label="MEINE GRUPPEN" name="groups_panel">
- <panel label="bottom_panel" name="bottom_panel">
- <menu_button name="groups_viewsort_btn" tool_tip="Optionen"/>
- <button name="plus_btn" tool_tip="Gruppe beitreten/Neue Gruppe erstellen"/>
- <button name="activate_btn" tool_tip="Ausgewählte Gruppe aktivieren"/>
+ <panel label="GRUPPEN" name="groups_panel">
+ <panel label="bottom_panel" name="groups_buttons_panel">
+ <filter_editor label="Nach Gruppen filtern" name="groups_filter_input"/>
+ <menu_button name="groups_gear_btn" tool_tip="Aktionen für ausgewählte Gruppe"/>
+ <menu_button name="groups_view_btn" tool_tip="Anzeige-/Sortieroptionen"/>
+ <menu_button name="plus_btn" tool_tip="Gruppe beitreten/Neue Gruppe erstellen"/>
+ <dnd_button name="minus_btn" tool_tip="Ausgewählte Gruppe verlassen"/>
</panel>
+ <text name="groupcount">
+ Sie gehören [COUNT] Gruppen an und können [REMAINING] weiteren beitreten.
+ </text>
</panel>
<panel label="AKTUELL" name="recent_panel">
- <panel label="bottom_panel" name="bottom_panel">
- <menu_button name="recent_viewsort_btn" tool_tip="Optionen"/>
- <button name="add_friend_btn" tool_tip="Ausgewählten Einwohner zur Freundeliste hinzufügen"/>
+ <panel label="bottom_panel" name="recent_buttons_panel">
+ <filter_editor label="Nach Personen filtern" name="recent_filter_input"/>
+ <button name="gear_btn" tool_tip="Aktionen für ausgewählte Person"/>
+ <menu_button name="recent_view_btn" tool_tip="Anzeige-/Sortieroptionen"/>
+ <button name="add_friend_btn" tool_tip="Einem Einwohner die Freundschaft anbieten"/>
+ <dnd_button name="recent_del_btn" tool_tip="Ausgewählte Person als Freund entfernen"/>
</panel>
</panel>
+ <panel label="IGNORIERT" name="blocked_panel">
+ <panel label="Ignorierte Einwohner und Objekte" name="panel_block_list_sidetray"/>
+ </panel>
</tab_container>
- <panel name="button_bar">
- <layout_stack name="bottom_bar_ls">
- <layout_panel name="view_profile_btn_lp">
- <button label="Profil" name="view_profile_btn" tool_tip="Bilder, Gruppen und andere Einwohner-Informationen anzeigen"/>
- </layout_panel>
- <layout_panel name="im_btn_lp">
- <button label="IM" name="im_btn" tool_tip="IM-Sitzung öffnen"/>
- </layout_panel>
- <layout_panel name="call_btn_lp">
- <button label="Anrufen" name="call_btn" tool_tip="Diesen Einwohner anrufen"/>
- </layout_panel>
- <layout_panel name="share_btn_lp">
- <button label="Freigeben" name="share_btn" tool_tip="Inventarobjekt freigeben"/>
- </layout_panel>
- <layout_panel name="teleport_btn_lp">
- <button label="Teleportieren" name="teleport_btn" tool_tip="Teleport anbieten"/>
- </layout_panel>
- </layout_stack>
- <layout_stack name="bottom_bar_ls1">
- <layout_panel name="group_info_btn_lp">
- <button label="Gruppenprofil" name="group_info_btn" tool_tip="Gruppeninformationen anzeigen"/>
- </layout_panel>
- <layout_panel name="chat_btn_lp">
- <button label="Gruppen-Chat" name="chat_btn" tool_tip="Chat öffnen"/>
- </layout_panel>
- <layout_panel name="group_call_btn_lp">
- <button label="Gruppe anrufen" name="group_call_btn" tool_tip="Diese Gruppe anrufen"/>
- </layout_panel>
- </layout_stack>
- </panel>
</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_pick_info.xml b/indra/newview/skins/default/xui/de/panel_pick_info.xml
index f215c43a3d..f215c43a3d 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_pick_info.xml
+++ b/indra/newview/skins/default/xui/de/panel_pick_info.xml
diff --git a/indra/newview/skins/default/xui/de/panel_picks.xml b/indra/newview/skins/default/xui/de/panel_picks.xml
index 6aaa3151a8..6aaa3151a8 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_picks.xml
+++ b/indra/newview/skins/default/xui/de/panel_picks.xml
diff --git a/indra/newview/skins/default/xui/de/panel_place_profile.xml b/indra/newview/skins/default/xui/de/panel_place_profile.xml
index 4077fdab36..4077fdab36 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_place_profile.xml
+++ b/indra/newview/skins/default/xui/de/panel_place_profile.xml
diff --git a/indra/newview/skins/default/xui/de/panel_places.xml b/indra/newview/skins/default/xui/de/panel_places.xml
index 602ffff94d..602ffff94d 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_places.xml
+++ b/indra/newview/skins/default/xui/de/panel_places.xml
diff --git a/indra/newview/skins/default/xui/de/panel_postcard_message.xml b/indra/newview/skins/default/xui/de/panel_postcard_message.xml
index 6eeef8af71..6eeef8af71 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_postcard_message.xml
+++ b/indra/newview/skins/default/xui/de/panel_postcard_message.xml
diff --git a/indra/newview/skins/default/xui/de/panel_postcard_settings.xml b/indra/newview/skins/default/xui/de/panel_postcard_settings.xml
index c1a1c0cc46..c1a1c0cc46 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_postcard_settings.xml
+++ b/indra/newview/skins/default/xui/de/panel_postcard_settings.xml
diff --git a/indra/newview/skins/default/xui/de/panel_preferences_advanced.xml b/indra/newview/skins/default/xui/de/panel_preferences_advanced.xml
index 8a5c175f2f..8a5c175f2f 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_preferences_advanced.xml
+++ b/indra/newview/skins/default/xui/de/panel_preferences_advanced.xml
diff --git a/indra/newview/skins/default/xui/de/panel_preferences_alerts.xml b/indra/newview/skins/default/xui/de/panel_preferences_alerts.xml
index fcb45e26be..fcb45e26be 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_preferences_alerts.xml
+++ b/indra/newview/skins/default/xui/de/panel_preferences_alerts.xml
diff --git a/indra/newview/skins/default/xui/de/panel_preferences_chat.xml b/indra/newview/skins/default/xui/de/panel_preferences_chat.xml
index 746a561e6c..8eb815fd1b 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/de/panel_preferences_chat.xml
@@ -1,33 +1,99 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel label="Text-Chat" name="chat">
- <text name="font_size">
- Schriftgröße:
- </text>
- <radio_group name="chat_font_size">
- <radio_item label="Klein" name="radio" value="0"/>
- <radio_item label="Mittel" name="radio2" value="1"/>
- <radio_item label="Groß" name="radio3" value="2"/>
- </radio_group>
- <check_box initial_value="true" label="Beim Chatten Tippanimation abspielen" name="play_typing_animation"/>
- <check_box label="IMs per Email zuschicken, wenn ich offline bin" name="send_im_to_email"/>
- <check_box label="Kompakten IM- und Text-Chatverlauf aktivieren" name="plain_text_chat_history"/>
- <check_box label="Blasen-Chat" name="bubble_text_chat"/>
- <text name="show_ims_in_label">
- IMs anzeigen in:
- </text>
- <text name="requires_restart_label">
- (Neustart erforderlich)
- </text>
- <radio_group name="chat_window" tool_tip="Zeigen Sie Ihre Sofortnachrichten (Instant Messages) in einem anderen Fenster oder in einem einzigen Fenster mit vielen Registerkarten an (Neustart erforderlich).">
- <radio_item label="Getrennte Fenster" name="radio" value="0"/>
- <radio_item label="Registerkarten" name="radio2" value="1"/>
- </radio_group>
- <text name="disable_toast_label">
- Popups für eingehende Chats aktivieren:
- </text>
- <check_box label="Gruppen-Chats" name="EnableGroupChatPopups" tool_tip="Markieren, um Popups zu sehen, wenn Gruppen-Chat-Message eintrifft"/>
- <check_box label="IM-Chats" name="EnableIMChatPopups" tool_tip="Markieren, um Popups zu sehen, wenn Instant Message eintrifft"/>
- <spinner label="Lebenszeit von Toasts für Chat in der Nähe:" name="nearby_toasts_lifetime"/>
- <spinner label="Ein-/Ausblenddauer von Toasts für Chat in der Nähe:" name="nearby_toasts_fadingtime"/>
- <button label="Übersetzungseinstellungen für Chats" name="ok_btn"/>
+ <panel name="general_chat_settings">
+ <check_box initial_value="true" label="Beim Chatten Tippanimation abspielen" name="play_typing_animation"/>
+ <check_box label="IMs per E-Mail zustellen, wenn ich offline bin" name="send_im_to_email"/>
+ <check_box label="Nur IMs und Anrufe von Freunden oder Gruppen durchstellen" name="voice_call_friends_only_check"/>
+ <text name="font_size">
+ Schriftgröße:
+ </text>
+ <combo_box name="chat_font_size">
+ <item label="Klein" name="Small" value="0"/>
+ <item label="Mittel" name="Medium" value="1"/>
+ <item label="Groß" name="Large" value="2"/>
+ </combo_box>
+ <check_box label="Blasen-Chat" name="bubble_text_chat"/>
+ </panel>
+ <panel name="im_notification_settings">
+ <text name="friend_ims">
+ IMs von Freunden:
+ </text>
+ <combo_box name="FriendIMOptions">
+ <item label="Unterhaltungsfenster öffnen" name="OpenConversationsWindow" value="openconversations"/>
+ <item label="Nachricht in Popup anzeigen" name="PopUpMessage" value="toast"/>
+ <item label="Flash-Symbolleistenschaltfläche" name="FlashToolbarButton" value="flash"/>
+ <item label="Keine Aktion" name="NoAction" value="noaction"/>
+ </combo_box>
+ <check_box label="Sound abspielen" name="play_sound_friend_im"/>
+ <text name="non_friend_ims">
+ IMs von anderen:
+ </text>
+ <combo_box name="NonFriendIMOptions">
+ <item label="Unterhaltungsfenster öffnen" name="OpenConversationsWindow" value="openconversations"/>
+ <item label="Nachricht in Popup anzeigen" name="PopUpMessage" value="toast"/>
+ <item label="Flash-Symbolleistenschaltfläche" name="FlashToolbarButton" value="flash"/>
+ <item label="Keine Aktion" name="NoAction" value="noaction"/>
+ </combo_box>
+ <check_box label="Sound abspielen" name="play_sound_non_friend_im"/>
+ <text name="conference_ims">
+ Konferenz-IMs:
+ </text>
+ <combo_box name="ConferenceIMOptions">
+ <item label="Unterhaltungsfenster öffnen" name="OpenConversationsWindow" value="openconversations"/>
+ <item label="Nachricht in Popup anzeigen" name="PopUpMessage" value="toast"/>
+ <item label="Flash-Symbolleistenschaltfläche" name="FlashToolbarButton" value="flash"/>
+ <item label="Keine Aktion" name="NoAction" value="noaction"/>
+ </combo_box>
+ <check_box label="Sound abspielen" name="play_sound_conference_im"/>
+ <text name="group_chat">
+ Gruppen-Chat:
+ </text>
+ <combo_box name="GroupChatOptions">
+ <item label="Unterhaltungsfenster öffnen" name="OpenConversationsWindow" value="openconversations"/>
+ <item label="Nachricht in Popup anzeigen" name="PopUpMessage" value="toast"/>
+ <item label="Flash-Symbolleistenschaltfläche" name="FlashToolbarButton" value="flash"/>
+ <item label="Keine Aktion" name="NoAction" value="noaction"/>
+ </combo_box>
+ <check_box label="Sound abspielen" name="play_sound_group_chat_im"/>
+ <text name="nearby_chat">
+ Chat in der Nähe:
+ </text>
+ <combo_box name="NearbyChatOptions">
+ <item label="Unterhaltungsfenster öffnen" name="OpenConversationsWindow" value="openconversations"/>
+ <item label="Nachricht in Popup anzeigen" name="PopUpMessage" value="toast"/>
+ <item label="Flash-Symbolleistenschaltfläche" name="FlashToolBarButton" value="flash"/>
+ <item label="Keine Aktion" name="NoAction" value="noaction"/>
+ </combo_box>
+ <check_box label="Sound abspielen" name="play_sound_nearby_chat_im"/>
+ <text name="object_ims">
+ IMs von Objekten:
+ </text>
+ <combo_box name="ObjectIMOptions">
+ <item label="Unterhaltungsfenster öffnen" name="OpenConversationsWindow" value="openconversations"/>
+ <item label="Nachricht in Popup anzeigen" name="PopUpMessage" value="toast"/>
+ <item label="Flash-Symbolleistenschaltfläche" name="FlashToolBarButton" value="flash"/>
+ <item label="Keine Aktion" name="NoAction" value="noaction"/>
+ </combo_box>
+ <check_box label="Sound abspielen" name="play_sound_object_im"/>
+ <text name="notifications_alert">
+ Um vorübergehend alle Benachrichtigungen zu stoppen, wählen Sie „Unterhalten“ &gt; „Nicht stören“.
+ </text>
+ </panel>
+ <panel name="play_sound_settings">
+ <text name="play_sound">
+ Sound abspielen:
+ </text>
+ <check_box label="Neue Unterhaltung" name="new_conversation"/>
+ <check_box label="Eingehender Anruf" name="incoming_voice_call"/>
+ <check_box label="Teleport-Angebot" name="teleport_offer"/>
+ <check_box label="Inventarangebot" name="inventory_offer"/>
+ </panel>
+ <panel name="log_settings">
+ <button label="Protokoll löschen..." name="clear_log"/>
+ <button label="Transkripte löschen..." name="delete_transcripts"/>
+ <button label="Durchsuchen..." label_selected="Durchblättern" name="log_path_button"/>
+ </panel>
+ <button label="Ãœbersetzen..." name="ok_btn"/>
+ <button label="Automatisch ersetzen..." name="autoreplace_showgui"/>
+ <button label="Rechtschreibprüfung..." name="spellcheck_showgui"/>
</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_preferences_colors.xml b/indra/newview/skins/default/xui/de/panel_preferences_colors.xml
index 19c5efcb05..19c5efcb05 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_preferences_colors.xml
+++ b/indra/newview/skins/default/xui/de/panel_preferences_colors.xml
diff --git a/indra/newview/skins/default/xui/de/panel_preferences_general.xml b/indra/newview/skins/default/xui/de/panel_preferences_general.xml
index 979ccba48d..4e453b6969 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_preferences_general.xml
+++ b/indra/newview/skins/default/xui/de/panel_preferences_general.xml
@@ -69,9 +69,9 @@
<combo_box.item label="nie" name="item4"/>
</combo_box>
<text name="text_box3">
- Antwort, wenn im „Beschäftigt“-Modus:
+ Nicht-stören-Antwort:
</text>
- <text_editor name="busy_response">
+ <text_editor name="do_not_disturb_response">
log_in_to_change
</text_editor>
</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/de/panel_preferences_graphics1.xml
index 9175ea0bae..f3746a7c82 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_preferences_graphics1.xml
+++ b/indra/newview/skins/default/xui/de/panel_preferences_graphics1.xml
@@ -30,7 +30,7 @@
<check_box initial_value="true" label="Lokale Lichtquellen" name="LocalLights"/>
<check_box initial_value="true" label="Einfache Shader" name="BasicShaders" tool_tip="Deaktivieren Sie diese Option, wenn der Grafikkartentreiber Abstürze verursacht"/>
<check_box initial_value="true" label="Atmosphären-Shader" name="WindLightUseAtmosShaders"/>
- <check_box initial_value="true" label="Licht und Schatten" name="UseLightShaders"/>
+ <check_box initial_value="true" label="Erweitertes Beleuchtungsmodell" name="UseLightShaders"/>
<check_box initial_value="true" label="Ambient Occlusion" name="UseSSAO"/>
<check_box initial_value="true" label="Schärfentiefe" name="UseDoF"/>
<text name="shadows_label">
diff --git a/indra/newview/skins/default/xui/de/panel_preferences_move.xml b/indra/newview/skins/default/xui/de/panel_preferences_move.xml
index 3e248f0bf0..3e248f0bf0 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_preferences_move.xml
+++ b/indra/newview/skins/default/xui/de/panel_preferences_move.xml
diff --git a/indra/newview/skins/default/xui/de/panel_preferences_privacy.xml b/indra/newview/skins/default/xui/de/panel_preferences_privacy.xml
index e21bed6bb5..e21bed6bb5 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_preferences_privacy.xml
+++ b/indra/newview/skins/default/xui/de/panel_preferences_privacy.xml
diff --git a/indra/newview/skins/default/xui/de/panel_preferences_setup.xml b/indra/newview/skins/default/xui/de/panel_preferences_setup.xml
index 8c7ea688d7..24e5033bfc 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_preferences_setup.xml
+++ b/indra/newview/skins/default/xui/de/panel_preferences_setup.xml
@@ -29,6 +29,7 @@
<combo_box.item label="Automatisch installieren" name="Install_automatically"/>
<combo_box.item label="Updates manuell herunterladen und installieren" name="Install_manual"/>
</combo_box>
+ <check_box label="Bereit, Release-Kandidaten zu verwenden" name="update_willing_to_test"/>
<text name="Proxy Settings:">
Proxy-Einstellungen:
</text>
diff --git a/indra/newview/skins/default/xui/de/panel_preferences_sound.xml b/indra/newview/skins/default/xui/de/panel_preferences_sound.xml
index 1e6a03c99f..1e6a03c99f 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_preferences_sound.xml
+++ b/indra/newview/skins/default/xui/de/panel_preferences_sound.xml
diff --git a/indra/newview/skins/default/xui/de/panel_prim_media_controls.xml b/indra/newview/skins/default/xui/de/panel_prim_media_controls.xml
index c85f2762b1..c85f2762b1 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_prim_media_controls.xml
+++ b/indra/newview/skins/default/xui/de/panel_prim_media_controls.xml
diff --git a/indra/newview/skins/default/xui/de/panel_region_covenant.xml b/indra/newview/skins/default/xui/de/panel_region_covenant.xml
index 225c98b84f..225c98b84f 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_region_covenant.xml
+++ b/indra/newview/skins/default/xui/de/panel_region_covenant.xml
diff --git a/indra/newview/skins/default/xui/de/panel_region_debug.xml b/indra/newview/skins/default/xui/de/panel_region_debug.xml
index d1b8f0d78a..a03a0b8b7b 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_region_debug.xml
+++ b/indra/newview/skins/default/xui/de/panel_region_debug.xml
@@ -36,5 +36,5 @@
<button label="?" name="top_scripts_help"/>
<button label="Region neu starten" name="restart_btn" tool_tip="2-Minuten-Countdown und Region neu starten"/>
<button label="?" name="restart_help"/>
- <button label="Neustart verzögern" name="cancel_restart_btn" tool_tip="Regionsneustart um eine Stunde verschieben"/>
+ <button label="Neustart abbrechen" name="cancel_restart_btn" tool_tip="Regionsneustart abbrechen"/>
</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_region_environment.xml b/indra/newview/skins/default/xui/de/panel_region_environment.xml
index daadd30f62..daadd30f62 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_region_environment.xml
+++ b/indra/newview/skins/default/xui/de/panel_region_environment.xml
diff --git a/indra/newview/skins/default/xui/de/panel_region_estate.xml b/indra/newview/skins/default/xui/de/panel_region_estate.xml
index aecf6f62fc..b087451391 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_region_estate.xml
+++ b/indra/newview/skins/default/xui/de/panel_region_estate.xml
@@ -19,7 +19,7 @@
Zugang nur Einwohnern gestatten, die:
</text>
<check_box label="Zahlungsinformationen hinterlegt haben" name="limit_payment" tool_tip="Um diesen Grundbesitz besuchen zu können, müssen Einwohner Zahlungsinformationen hinterlegt haben. Weitere Informationen finden Sie auf [SUPPORT_SITE]."/>
- <check_box label="ihr Alter bestätigt haben" name="limit_age_verified" tool_tip="Um diesen Grundbesitz besuchen zu können, müssen Einwohner ihr Alter bestätigt haben. Weitere Informationen finden Sie auf [SUPPORT_SITE]."/>
+ <check_box label="Sind mindestens 18 Jahre alt" name="limit_age_verified" tool_tip="Nur Einwohner, die mindestens 18 Jahre alt sind, können diesen Grundbesitz betreten. Weitere Informationen finden Sie unter [SUPPORT_SITE]."/>
<check_box label="Voice-Chat erlauben" name="voice_chat_check"/>
<button label="?" name="voice_chat_help"/>
<text name="abuse_email_text" width="222">
diff --git a/indra/newview/skins/default/xui/de/panel_region_general.xml b/indra/newview/skins/default/xui/de/panel_region_general.xml
index f383be992b..f383be992b 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_region_general.xml
+++ b/indra/newview/skins/default/xui/de/panel_region_general.xml
diff --git a/indra/newview/skins/default/xui/de/panel_region_terrain.xml b/indra/newview/skins/default/xui/de/panel_region_terrain.xml
index 7801be30e4..7801be30e4 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_region_terrain.xml
+++ b/indra/newview/skins/default/xui/de/panel_region_terrain.xml
diff --git a/indra/newview/skins/default/xui/de/panel_region_texture.xml b/indra/newview/skins/default/xui/de/panel_region_texture.xml
deleted file mode 100644
index 2f4904730b..0000000000
--- a/indra/newview/skins/default/xui/de/panel_region_texture.xml
+++ /dev/null
@@ -1,57 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel label="Bodentexturen" name="Textures">
- <text name="region_text_lbl">
- Region:
- </text>
- <text name="region_text">
- unbekannt
- </text>
- <text name="detail_texture_text">
- Terraintexturen (erfordert 512x512, 24-Bit-.tga-Dateien)
- </text>
- <text name="height_text_lbl">
- 1 (niedrig)
- </text>
- <text name="height_text_lbl2">
- 2
- </text>
- <text name="height_text_lbl3">
- 3
- </text>
- <text name="height_text_lbl4">
- 4 (Hoch)
- </text>
- <text name="height_text_lbl5">
- Texturhöhenbereich
- </text>
- <text name="height_text_lbl6">
- Nordwest
- </text>
- <text name="height_text_lbl7">
- Nordost
- </text>
- <text name="height_text_lbl8">
- Südwest
- </text>
- <text name="height_text_lbl9">
- Südost
- </text>
- <spinner label="Niedrig" label_width="40" name="height_start_spin_0"/>
- <spinner label="Niedrig" label_width="40" name="height_start_spin_1"/>
- <spinner label="Niedrig" label_width="40" name="height_start_spin_2"/>
- <spinner label="Niedrig" label_width="40" name="height_start_spin_3"/>
- <spinner label="Hoch" label_width="40" name="height_range_spin_0"/>
- <spinner label="Hoch" label_width="40" name="height_range_spin_1"/>
- <spinner label="Hoch" label_width="40" name="height_range_spin_2"/>
- <spinner label="Hoch" label_width="40" name="height_range_spin_3"/>
- <text name="height_text_lbl10">
- Diese Werte geben den Mischungsgrad für die obigen Texturen an.
- </text>
- <text name="height_text_lbl11">
- In Metern gemessen. Der NIEDRIG-Wert ist die MAXIMALE Höhe der Textur #1, der HÖCHST-Wert ist die MINDEST-Höhe von Textur #4.
- </text>
- <text name="height_text_lbl12">
- und der OBERE WERT die MINIMALE Höhe von Textur 4.
- </text>
- <button label="Ãœbernehmen" name="apply_btn"/>
-</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_script_ed.xml b/indra/newview/skins/default/xui/de/panel_script_ed.xml
index 7e03aeff15..d688bedd5c 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_script_ed.xml
+++ b/indra/newview/skins/default/xui/de/panel_script_ed.xml
@@ -34,6 +34,7 @@
<menu_item_call label="Alle auswählen" name="Select All"/>
<menu_item_call label="Auswahl aufheben" name="Deselect"/>
<menu_item_call label="Suchen / Ersetzen..." name="Search / Replace..."/>
+ <menu_item_call label="Gehe zu Zeile..." name="Go to line..."/>
</menu>
<menu label="Hilfe" name="Help">
<menu_item_call label="Hilfe..." name="Help..."/>
diff --git a/indra/newview/skins/default/xui/de/panel_script_limits_my_avatar.xml b/indra/newview/skins/default/xui/de/panel_script_limits_my_avatar.xml
index c91eb98e9c..c91eb98e9c 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_script_limits_my_avatar.xml
+++ b/indra/newview/skins/default/xui/de/panel_script_limits_my_avatar.xml
diff --git a/indra/newview/skins/default/xui/de/panel_script_limits_region_memory.xml b/indra/newview/skins/default/xui/de/panel_script_limits_region_memory.xml
index 8d7cc1bf9a..8d7cc1bf9a 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_script_limits_region_memory.xml
+++ b/indra/newview/skins/default/xui/de/panel_script_limits_region_memory.xml
diff --git a/indra/newview/skins/default/xui/de/panel_script_question_toast.xml b/indra/newview/skins/default/xui/de/panel_script_question_toast.xml
new file mode 100755
index 0000000000..a2d0237da0
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/panel_script_question_toast.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<panel label="script_question_panel" name="panel_script_question_toast">
+ <panel label="buttons_panel" name="buttons_panel"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_scrolling_param.xml b/indra/newview/skins/default/xui/de/panel_scrolling_param.xml
index 50590b8d73..50590b8d73 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_scrolling_param.xml
+++ b/indra/newview/skins/default/xui/de/panel_scrolling_param.xml
diff --git a/indra/newview/skins/default/xui/de/panel_scrolling_param_base.xml b/indra/newview/skins/default/xui/de/panel_scrolling_param_base.xml
index fa659040ea..fa659040ea 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_scrolling_param_base.xml
+++ b/indra/newview/skins/default/xui/de/panel_scrolling_param_base.xml
diff --git a/indra/newview/skins/default/xui/de/panel_side_tray.xml b/indra/newview/skins/default/xui/de/panel_side_tray.xml
deleted file mode 100644
index 3c81636fa0..0000000000
--- a/indra/newview/skins/default/xui/de/panel_side_tray.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<!-- Side tray cannot show background because it is always
- partially on screen to hold tab buttons. -->
-<side_tray name="sidebar">
- <sidetray_tab description="Seitenleiste auf-/zuklappen." name="sidebar_openclose" tab_title="Seitenleiste auf-/zuklappen"/>
- <sidetray_tab description="Startseite." name="sidebar_home" tab_title="Startseite">
- <panel label="Startseite" name="panel_home"/>
- </sidetray_tab>
- <sidetray_tab description="Ihr öffentliches Profil und Auswahl bearbeiten." name="sidebar_me" tab_title="Mein Profil">
- <panel_container name="panel_container">
- <panel label="Ich" name="panel_me"/>
- </panel_container>
- </sidetray_tab>
- <sidetray_tab description="Freunde, Kontakte und Leute in Ihrer Nähe finden." name="sidebar_people" tab_title="Leute">
- <panel_container name="panel_container">
- <panel label="Gruppenprofil" name="panel_group_info_sidetray"/>
- <panel label="Ignorierte Einwohner &amp; Objekte" name="panel_block_list_sidetray"/>
- </panel_container>
- </sidetray_tab>
- <sidetray_tab description="Hier finden Sie neue Orte und Orte, die Sie bereits besucht haben." label="Orte" name="sidebar_places" tab_title="Orte">
- <panel label="Orte" name="panel_places"/>
- </sidetray_tab>
- <sidetray_tab description="Inventar durchsuchen." name="sidebar_inventory" tab_title="Mein Inventar">
- <panel label="Inventar bearbeiten" name="sidepanel_inventory"/>
- </sidetray_tab>
- <sidetray_tab description="Ändern Sie Ihr Aussehen und Ihren aktuellen Look." name="sidebar_appearance" tab_title="Mein Aussehen">
- <panel label="Aussehen bearbeiten" name="sidepanel_appearance"/>
- </sidetray_tab>
-</side_tray>
diff --git a/indra/newview/skins/default/xui/de/panel_side_tray_tab_caption.xml b/indra/newview/skins/default/xui/de/panel_side_tray_tab_caption.xml
index 652fb7c836..652fb7c836 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_side_tray_tab_caption.xml
+++ b/indra/newview/skins/default/xui/de/panel_side_tray_tab_caption.xml
diff --git a/indra/newview/skins/default/xui/de/panel_sidetray_home_tab.xml b/indra/newview/skins/default/xui/de/panel_sidetray_home_tab.xml
index cf3080a4f9..cf3080a4f9 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_sidetray_home_tab.xml
+++ b/indra/newview/skins/default/xui/de/panel_sidetray_home_tab.xml
diff --git a/indra/newview/skins/default/xui/de/panel_snapshot_inventory.xml b/indra/newview/skins/default/xui/de/panel_snapshot_inventory.xml
index 10827ce6f2..10827ce6f2 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_snapshot_inventory.xml
+++ b/indra/newview/skins/default/xui/de/panel_snapshot_inventory.xml
diff --git a/indra/newview/skins/default/xui/de/panel_snapshot_local.xml b/indra/newview/skins/default/xui/de/panel_snapshot_local.xml
index 3aeae80388..3aeae80388 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_snapshot_local.xml
+++ b/indra/newview/skins/default/xui/de/panel_snapshot_local.xml
diff --git a/indra/newview/skins/default/xui/de/panel_snapshot_options.xml b/indra/newview/skins/default/xui/de/panel_snapshot_options.xml
index e1d8a5dc6d..e1d8a5dc6d 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_snapshot_options.xml
+++ b/indra/newview/skins/default/xui/de/panel_snapshot_options.xml
diff --git a/indra/newview/skins/default/xui/de/panel_snapshot_postcard.xml b/indra/newview/skins/default/xui/de/panel_snapshot_postcard.xml
index c9afe86d7f..c9afe86d7f 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_snapshot_postcard.xml
+++ b/indra/newview/skins/default/xui/de/panel_snapshot_postcard.xml
diff --git a/indra/newview/skins/default/xui/de/panel_snapshot_profile.xml b/indra/newview/skins/default/xui/de/panel_snapshot_profile.xml
index 8d1c52dea8..8d1c52dea8 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_snapshot_profile.xml
+++ b/indra/newview/skins/default/xui/de/panel_snapshot_profile.xml
diff --git a/indra/newview/skins/default/xui/de/panel_sound_devices.xml b/indra/newview/skins/default/xui/de/panel_sound_devices.xml
index b739b6197f..b739b6197f 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_sound_devices.xml
+++ b/indra/newview/skins/default/xui/de/panel_sound_devices.xml
diff --git a/indra/newview/skins/default/xui/de/panel_stand_stop_flying.xml b/indra/newview/skins/default/xui/de/panel_stand_stop_flying.xml
index be21429007..be21429007 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_stand_stop_flying.xml
+++ b/indra/newview/skins/default/xui/de/panel_stand_stop_flying.xml
diff --git a/indra/newview/skins/default/xui/de/panel_status_bar.xml b/indra/newview/skins/default/xui/de/panel_status_bar.xml
index 14ace0ac3a..14ace0ac3a 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_status_bar.xml
+++ b/indra/newview/skins/default/xui/de/panel_status_bar.xml
diff --git a/indra/newview/skins/default/xui/de/panel_sys_well_item.xml b/indra/newview/skins/default/xui/de/panel_sys_well_item.xml
index 504f1727e2..504f1727e2 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_sys_well_item.xml
+++ b/indra/newview/skins/default/xui/de/panel_sys_well_item.xml
diff --git a/indra/newview/skins/default/xui/de/panel_teleport_history.xml b/indra/newview/skins/default/xui/de/panel_teleport_history.xml
index 4d721f2af6..4d721f2af6 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_teleport_history.xml
+++ b/indra/newview/skins/default/xui/de/panel_teleport_history.xml
diff --git a/indra/newview/skins/default/xui/de/panel_teleport_history_item.xml b/indra/newview/skins/default/xui/de/panel_teleport_history_item.xml
index 4b57aa69b6..4b57aa69b6 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_teleport_history_item.xml
+++ b/indra/newview/skins/default/xui/de/panel_teleport_history_item.xml
diff --git a/indra/newview/skins/default/xui/de/panel_tools_texture.xml b/indra/newview/skins/default/xui/de/panel_tools_texture.xml
new file mode 100644
index 0000000000..18517d7a7d
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/panel_tools_texture.xml
@@ -0,0 +1,116 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Textur" name="Texture">
+ <panel.string name="string repeats per meter">
+ Wiederholungen pro Meter
+ </panel.string>
+ <panel.string name="string repeats per face">
+ Wiederholungen pro Fläche
+ </panel.string>
+ <text name="color label">
+ Farbe
+ </text>
+ <color_swatch label="" name="colorswatch" tool_tip="Klicken Sie hier, um die Farbauswahl zu öffnen"/>
+ <text name="color trans">
+ Transparenz %
+ </text>
+ <text name="glow label">
+ Leuchten
+ </text>
+ <check_box label="Ganz hell" name="checkbox fullbright"/>
+ <combo_box name="combobox matmedia">
+ <combo_box.item label="Material" name="Materials"/>
+ <combo_box.item label="Medien" name="Media"/>
+ </combo_box>
+ <combo_box name="combobox mattype">
+ <combo_box.item label="Textur (diffus)" name="Texture (diffuse)"/>
+ <combo_box.item label="Unebenheit (normal)" name="Bumpiness (normal)"/>
+ <combo_box.item label="Glanzlicht (Spiegel)" name="Shininess (specular)"/>
+ </combo_box>
+ <texture_picker label="Textur" name="texture control" tool_tip="Klicken, um ein Bild zu wählen"/>
+ <text name="label alphamode">
+ Alpha-Modus
+ </text>
+ <combo_box name="combobox alphamode">
+ <combo_box.item label="Keiner" name="None"/>
+ <combo_box.item label="Alpha-Mischung" name="Alpha blending"/>
+ <combo_box.item label="Alpha-Maske" name="Alpha masking"/>
+ <combo_box.item label="Selbststrahlende Maske" name="Emissive mask"/>
+ </combo_box>
+ <text name="label maskcutoff">
+ Maskenabgrenzung
+ </text>
+ <texture_picker label="Textur" name="bumpytexture control" tool_tip="Klicken, um ein Bild auszuwählen"/>
+ <text name="label bumpiness">
+ Unebenheit
+ </text>
+ <combo_box name="combobox bumpiness">
+ <combo_box.item label="Keine" name="None"/>
+ <combo_box.item label="Helligkeit" name="Brightness"/>
+ <combo_box.item label="Dunkelheit" name="Darkness"/>
+ <combo_box.item label="Holzmaserung" name="woodgrain"/>
+ <combo_box.item label="Rinde" name="bark"/>
+ <combo_box.item label="Backsteine" name="bricks"/>
+ <combo_box.item label="Schachbrett" name="checker"/>
+ <combo_box.item label="Beton" name="concrete"/>
+ <combo_box.item label="Rostkachel" name="crustytile"/>
+ <combo_box.item label="Steinfliesen" name="cutstone"/>
+ <combo_box.item label="Scheiben" name="discs"/>
+ <combo_box.item label="Kies" name="gravel"/>
+ <combo_box.item label="Petrischale" name="petridish"/>
+ <combo_box.item label="Verkleidung" name="siding"/>
+ <combo_box.item label="Steinkachel" name="stonetile"/>
+ <combo_box.item label="Stuck" name="stucco"/>
+ <combo_box.item label="Saugkraft" name="suction"/>
+ <combo_box.item label="Gewebe" name="weave"/>
+ </combo_box>
+ <texture_picker label="Textur" name="shinytexture control" tool_tip="Klicken, um ein Bild auszuwählen"/>
+ <text name="label shininess">
+ Glanz
+ </text>
+ <combo_box name="combobox shininess">
+ <combo_box.item label="Keiner" name="None"/>
+ <combo_box.item label="Niedrig" name="Low"/>
+ <combo_box.item label="Mittel" name="Medium"/>
+ <combo_box.item label="Hoch" name="High"/>
+ </combo_box>
+ <text name="label glossiness">
+ Glanz
+ </text>
+ <text name="label environment">
+ Umgebung
+ </text>
+ <text name="label shinycolor">
+ Farbe
+ </text>
+ <color_swatch label="" name="shinycolorswatch" tool_tip="Klicken Sie hier, um die Farbauswahl zu öffnen"/>
+ <text name="media_info">
+ URL der ausgewählten Medien ggf. hier angeben
+ </text>
+ <button label="Auswählen..." name="add_media" tool_tip="Medien hinzufügen"/>
+ <button label="Entfernen" name="delete_media" tool_tip="Diese Medientextur löschen"/>
+ <button label="Ausrichten" label_selected="Medien ausrichten" name="button align" tool_tip="Medientextur ausrichten (muss zuerst geladen werden)"/>
+ <text name="tex gen">
+ Zuordnung
+ </text>
+ <combo_box name="combobox texgen">
+ <combo_box.item label="Standard" name="Default"/>
+ <combo_box.item label="Planar" name="Planar"/>
+ </combo_box>
+ <spinner label="Horizontale Skalierung" name="TexScaleU"/>
+ <spinner label="Vertikale Skalierung" name="TexScaleV"/>
+ <spinner label="Wiederholungen pro Meter" name="rptctrl"/>
+ <spinner label="Drehung (Grad)" name="TexRot"/>
+ <spinner label="Horizontaler Versatz" name="TexOffsetU"/>
+ <spinner label="Vertikaler Versatz" name="TexOffsetV"/>
+ <spinner label="Horizontale Skalierung" name="bumpyScaleU"/>
+ <spinner label="Vertikale Skalierung" name="bumpyScaleV"/>
+ <spinner label="Drehung (Grad)" name="bumpyRot"/>
+ <spinner label="Horizontaler Versatz" name="bumpyOffsetU"/>
+ <spinner label="Vertikaler Versatz" name="bumpyOffsetV"/>
+ <spinner label="Horizontale Skalierung" name="shinyScaleU"/>
+ <spinner label="Vertikale Skalierung" name="shinyScaleV"/>
+ <spinner label="Drehung (Grad)" name="shinyRot"/>
+ <spinner label="Horizontaler Versatz" name="shinyOffsetU"/>
+ <spinner label="Vertikaler Versatz" name="shinyOffsetV"/>
+ <check_box initial_value="false" label="Planare Flächen ausrichten" name="checkbox planar align" tool_tip="Texturen auf allen ausgewählten Flächen an der zuletzt ausgewählten Fläche ausrichten. Erfordert planares Texture Mapping."/>
+</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_voice_effect.xml b/indra/newview/skins/default/xui/de/panel_voice_effect.xml
index 533deb8597..533deb8597 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_voice_effect.xml
+++ b/indra/newview/skins/default/xui/de/panel_voice_effect.xml
diff --git a/indra/newview/skins/default/xui/de/panel_volume_pulldown.xml b/indra/newview/skins/default/xui/de/panel_volume_pulldown.xml
new file mode 100755
index 0000000000..3d43200e48
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/panel_volume_pulldown.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="volumepulldown_floater" width="240">
+ <button left="217" name="prefs_btn"/>
+ <slider label="Master" label_width="80" name="System Volume" width="180"/>
+ <slider label="Schaltflächen" label_width="80" name="UI Volume" width="180"/>
+ <slider label="Umgebung" label_width="80" name="Wind Volume" width="180"/>
+ <slider label="Sounds" label_width="80" name="SFX Volume" width="180"/>
+ <check_box name="gesture_audio_play_btn" tool_tip="Sounds von Gesten aktivieren"/>
+ <slider label="Musik" label_width="80" name="Music Volume" width="180"/>
+ <check_box name="enable_music" tool_tip="Streaming-Musik aktivieren"/>
+ <slider label="Medien" label_width="80" name="Media Volume" width="180"/>
+ <check_box name="enable_media" tool_tip="Streaming-Medien aktivieren"/>
+ <slider label="Voice" label_width="80" name="Voice Volume" width="180"/>
+ <check_box name="enable_voice_check" tool_tip="Voice-Chat aktivieren"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_world_map.xml b/indra/newview/skins/default/xui/de/panel_world_map.xml
index 35fe3d3ffc..35fe3d3ffc 100644..100755
--- a/indra/newview/skins/default/xui/de/panel_world_map.xml
+++ b/indra/newview/skins/default/xui/de/panel_world_map.xml
diff --git a/indra/newview/skins/default/xui/de/role_actions.xml b/indra/newview/skins/default/xui/de/role_actions.xml
index 5d9dcacd51..3e9d406e5f 100644..100755
--- a/indra/newview/skins/default/xui/de/role_actions.xml
+++ b/indra/newview/skins/default/xui/de/role_actions.xml
@@ -25,7 +25,7 @@
</action_set>
<action_set description="Diese Fähigkeiten ermöglichen es, den Parzellennamen und die Veröffentlichungseinstellungen sowie die Anzeige des Suchverzeichnisses, den Landepunkt und die TP-Routenoptionen festzulegen." name="Parcel Identity">
<action description="„Ort in Suche anzeigen&quot; ein-/ausschalten und Kategorie festlegen." longdescription="Auf der Registerkarte „Optionen“ unter „Land-Info“ können Sie „Ort in Suche anzeigen“ ein- und ausschalten und die Parzellenkategorie festlegen." name="land find places" value="17"/>
- <action description="Parzellenname, Beschreibung und Einstellung für „Ort in Suche anzeigen&quot; ändern" longdescription="Parzellenname, Beschreibung und Einstellung für „Ort in Suche anzeigen&quot; ändern Diese Einstellungen finden Sie unter „Land-Info“ &gt; Registerkarte „Optionen“." name="land change identity" value="18"/>
+ <action description="Parzellenname, Beschreibung und Einstelllungen für „Moderater Inhalt“ ändern" longdescription="Parzellenname, Beschreibung und Einstelllungen für „Moderater Inhalt“ ändern. Diese Einstellungen finden Sie unter „Land-Info“ &gt; Registerkarte „Optionen“." name="land change identity" value="18"/>
<action description="Landepunkt und Teleport-Route festlegen" longdescription="Mitglieder in einer Rolle mit dieser Fähigkeit können auf einer gruppeneigenen Parzelle einen Landepunkt für ankommende Teleports und Teleport-Routen festlegen. Diese Einstellungen finden Sie unter „Land-Info“ &gt; „Optionen“." name="land set landing point" value="19"/>
</action_set>
<action_set description="Diese Fähigkeiten ermöglichen es, Parzellenoptionen wie „Objekte erstellen“, „Terrain bearbeiten“ sowie Musik- und Medieneinstellungen zu ändern." name="Parcel Settings">
diff --git a/indra/newview/skins/default/xui/de/sidepanel_appearance.xml b/indra/newview/skins/default/xui/de/sidepanel_appearance.xml
index 7fb9b34e0a..7fb9b34e0a 100644..100755
--- a/indra/newview/skins/default/xui/de/sidepanel_appearance.xml
+++ b/indra/newview/skins/default/xui/de/sidepanel_appearance.xml
diff --git a/indra/newview/skins/default/xui/de/sidepanel_inventory.xml b/indra/newview/skins/default/xui/de/sidepanel_inventory.xml
index 18aad64f96..18aad64f96 100644..100755
--- a/indra/newview/skins/default/xui/de/sidepanel_inventory.xml
+++ b/indra/newview/skins/default/xui/de/sidepanel_inventory.xml
diff --git a/indra/newview/skins/default/xui/de/sidepanel_item_info.xml b/indra/newview/skins/default/xui/de/sidepanel_item_info.xml
index 18241dea32..1b67eaf03b 100644..100755
--- a/indra/newview/skins/default/xui/de/sidepanel_item_info.xml
+++ b/indra/newview/skins/default/xui/de/sidepanel_item_info.xml
@@ -3,6 +3,9 @@
<panel.string name="unknown">
(unbekannt)
</panel.string>
+ <panel.string name="unknown_multiple">
+ (unbekannt/mehrere)
+ </panel.string>
<panel.string name="public">
(öffentlich)
</panel.string>
diff --git a/indra/newview/skins/default/xui/de/sidepanel_task_info.xml b/indra/newview/skins/default/xui/de/sidepanel_task_info.xml
index 7b46ee7c9b..29239033fe 100644..100755
--- a/indra/newview/skins/default/xui/de/sidepanel_task_info.xml
+++ b/indra/newview/skins/default/xui/de/sidepanel_task_info.xml
@@ -18,6 +18,12 @@
<panel.string name="text modify info 4">
Sie können diese Objekte nicht bearbeiten.
</panel.string>
+ <panel.string name="text modify info 5">
+ Dieses Objekt kann nicht über eine Regionsgrenze hinweg geändert werden
+ </panel.string>
+ <panel.string name="text modify info 6">
+ Diese Objekte können nicht über eine Regionsgrenze hinweg geändert werden
+ </panel.string>
<panel.string name="text modify warning">
Diese Objekt verfügt über verknüpfte Teile
</panel.string>
@@ -66,6 +72,7 @@
<combo_box.item label="Objekt kaufen" name="Buyobject"/>
<combo_box.item label="Objekt bezahlen" name="Payobject"/>
<combo_box.item label="Öffnen" name="Open"/>
+ <combo_box.item label="Zoomen" name="Zoom"/>
</combo_box>
<panel name="perms_inv">
<text name="perm_modify">
@@ -95,6 +102,9 @@
</combo_box>
<spinner label="Preis: L$" name="Edit Cost"/>
<check_box label="In Suche anzeigen" name="search_check" tool_tip="Dieses Objekt in Suchergebnissen anzeigen"/>
+ <text name="pathfinding_attributes_label">
+ Pathfinding-Attribute:
+ </text>
<text name="B:">
B:
</text>
diff --git a/indra/newview/skins/default/xui/de/strings.xml b/indra/newview/skins/default/xui/de/strings.xml
index d917d33d12..4268b95370 100644..100755
--- a/indra/newview/skins/default/xui/de/strings.xml
+++ b/indra/newview/skins/default/xui/de/strings.xml
@@ -137,7 +137,10 @@
Beenden
</string>
<string name="create_account_url">
- http://join.secondlife.com/index.php?lang=de-DE
+ http://join.secondlife.com/?sourceid=[sourceid]
+ </string>
+ <string name="ViewerDownloadURL">
+ http://secondlife.com/download
</string>
<string name="LoginFailedViewerNotPermitted">
Mit dem von Ihnen verwendeten Viewer ist der Zugriff auf Second Life nicht mehr möglich. Laden Sie von den folgenden Seite einen neuen Viewer herunter:
@@ -448,6 +451,9 @@ Warten Sie kurz und versuchen Sie dann noch einmal, sich anzumelden.
<string name="SLappAgentRequestFriend">
Freundschaftsangebot
</string>
+ <string name="SLappAgentRemoveFriend">
+ Entfernen von Freunden
+ </string>
<string name="BUTTON_CLOSE_DARWIN">
Schließen (⌘W)
</string>
@@ -622,8 +628,8 @@ Warten Sie kurz und versuchen Sie dann noch einmal, sich anzumelden.
<string name="AvatarAway">
Abwesend
</string>
- <string name="AvatarBusy">
- Beschäftigt
+ <string name="AvatarDoNotDisturb">
+ Nicht stören
</string>
<string name="AvatarMuted">
Ignoriert
@@ -838,6 +844,9 @@ Warten Sie kurz und versuchen Sie dann noch einmal, sich anzumelden.
<string name="multiple_textures">
Mehrfach
</string>
+ <string name="use_texture">
+ Textur verwenden
+ </string>
<string name="texture_loading">
Wird geladen...
</string>
@@ -859,6 +868,12 @@ Warten Sie kurz und versuchen Sie dann noch einmal, sich anzumelden.
<string name="ST_NO_JOINT">
HAUPTVERZEICHNIS oder VERBINDUNG nicht gefunden.
</string>
+ <string name="NearbyChatTitle">
+ Chat in der Nähe
+ </string>
+ <string name="NearbyChatLabel">
+ (Chat in der Nähe)
+ </string>
<string name="whisper">
flüstert:
</string>
@@ -886,6 +901,9 @@ Warten Sie kurz und versuchen Sie dann noch einmal, sich anzumelden.
<string name="ScriptQuestionCautionChatDenied">
Dem Objekt „[OBJECTNAME]“, ein Objekt von „[OWNERNAME]“, in [REGIONNAME] [REGIONPOS], wurde folgende Berechtigung verweigert: [PERMISSIONS].
</string>
+ <string name="AdditionalPermissionsRequestHeader">
+ Wenn Sie dem Objekt Zugriff auf Ihr Konto gewähren, kann dieses außerdem:
+ </string>
<string name="ScriptTakeMoney">
Linden-Dollar (L$) von Ihnen nehmen
</string>
@@ -922,6 +940,27 @@ Warten Sie kurz und versuchen Sie dann noch einmal, sich anzumelden.
<string name="NotConnected">
Nicht verbunden
</string>
+ <string name="AgentNameSubst">
+ (Sie)
+ </string>
+ <string name="TeleportYourAgent">
+ Sie teleportieren
+ </string>
+ <string name="JoinAnExperience">
+ Bei einem Erlebnis mitmachen
+ </string>
+ <string name="SilentlyManageEstateAccess">
+ Beim Verwalten von Grundbesitzzugangslisten Warnhinweise unterdrücken
+ </string>
+ <string name="OverrideYourAnimations">
+ Ihre Standardanimationen ersetzen
+ </string>
+ <string name="ScriptReturnObjects">
+ Objekte in Ihrem Namen zurückgeben
+ </string>
+ <string name="UnknownScriptPermission">
+ (unbekannt)
+ </string>
<string name="SIM_ACCESS_PG">
Generell
</string>
@@ -1000,17 +1039,8 @@ Warten Sie kurz und versuchen Sie dann noch einmal, sich anzumelden.
<string name="script_files">
Skripts
</string>
- <string name="AvatarSetNotAway">
- Nicht abwesend
- </string>
- <string name="AvatarSetAway">
- Abwesend
- </string>
- <string name="AvatarSetNotBusy">
- Nicht beschäftigt
- </string>
- <string name="AvatarSetBusy">
- Beschäftigt
+ <string name="dictionary_files">
+ Wörterbücher
</string>
<string name="shape">
Form
@@ -1244,7 +1274,7 @@ Warten Sie kurz und versuchen Sie dann noch einmal, sich anzumelden.
https://marketplace.[MARKETPLACE_DOMAIN_NAME]/
</string>
<string name="MarketplaceURL_CreateStore">
- http://community.secondlife.com/t5/English-Knowledge-Base/Selling-in-the-Marketplace/ta-p/700193#Section_.4
+ http://community.secondlife.com/t5/English-Knowledge-Base/Selling-in-the-Marketplace/ta-p/700193#Section_.3
</string>
<string name="MarketplaceURL_Dashboard">
https://marketplace.[MARKETPLACE_DOMAIN_NAME]/merchants/store/dashboard
@@ -1405,6 +1435,12 @@ Warten Sie kurz und versuchen Sie dann noch einmal, sich anzumelden.
<string name="InvFolder favorite">
Meine Favoriten
</string>
+ <string name="InvFolder Favorites">
+ Meine Favoriten
+ </string>
+ <string name="InvFolder favorites">
+ Meine Favoriten
+ </string>
<string name="InvFolder Current Outfit">
Aktuelles Outfit
</string>
@@ -1420,6 +1456,12 @@ Warten Sie kurz und versuchen Sie dann noch einmal, sich anzumelden.
<string name="InvFolder Meshes">
Netze
</string>
+ <string name="InvFolder Received Items">
+ Erhaltene Artikel
+ </string>
+ <string name="InvFolder Merchant Outbox">
+ Händler-Outbox
+ </string>
<string name="InvFolder Friends">
Freunde
</string>
@@ -1950,6 +1992,12 @@ Warten Sie kurz und versuchen Sie dann noch einmal, sich anzumelden.
<string name="ATTACH_HUD_BOTTOM_RIGHT">
HUD unten rechts
</string>
+ <string name="ATTACH_NECK">
+ Hals
+ </string>
+ <string name="ATTACH_AVATAR_CENTER">
+ Avatar-Mitte
+ </string>
<string name="CursorPos">
Zeile [LINE], Spalte [COLUMN]
</string>
@@ -1968,8 +2016,8 @@ Warten Sie kurz und versuchen Sie dann noch einmal, sich anzumelden.
<string name="PanelContentsNewScript">
Neues Skript
</string>
- <string name="BusyModeResponseDefault">
- Der Einwohner/Die Einwohnerin ist „beschäftigtâ€, d.h. er/sie möchte im Moment nicht gestört werden. Ihre Nachricht wird dem Einwohner/der Einwohnerin als IM angezeigt, und kann später beantwortet werden.
+ <string name="DoNotDisturbModeResponseDefault">
+ Dieser Einwohner hat den Nicht-stören-Modus aktiviert und wird Ihre Nachricht später sehen.
</string>
<string name="MuteByName">
(Nach Namen)
@@ -2082,9 +2130,6 @@ Warten Sie kurz und versuchen Sie dann noch einmal, sich anzumelden.
<string name="GroupMoneyDate">
[weekday,datetime,utc] [mth,datetime,utc] [day,datetime,utc], [year,datetime,utc]
</string>
- <string name="ViewerObjectContents">
- Inhalte
- </string>
<string name="AcquiredItems">
Erworbene Artikel
</string>
@@ -2982,6 +3027,9 @@ Falls diese Meldung weiterhin angezeigt wird, wenden Sie sich bitte an [SUPPORT_
<string name="Hip Width">
Breite der Hüfte
</string>
+ <string name="Hover">
+ Schweben
+ </string>
<string name="In">
In
</string>
@@ -3856,7 +3904,13 @@ Falls diese Meldung weiterhin angezeigt wird, wenden Sie sich bitte an [SUPPORT_
Generelle Region
</string>
<string name="LocationCtrlSeeAVsTooltip">
- Avatare sichtbar; Chat außerhalb dieser Parzelle gestattet
+ Avatare in dieser Parzelle können von Avataren außerhalb dieser Parzelle weder gesehen noch gehört werden
+ </string>
+ <string name="LocationCtrlPathfindingDirtyTooltip">
+ Bewegliche Objekte verhalten sich in dieser Region u. U. erst dann korrekt, wenn die Region neu geformt wird.
+ </string>
+ <string name="LocationCtrlPathfindingDisabledTooltip">
+ Dynamisches Pathfinding ist in dieser Region nicht aktiviert.
</string>
<string name="UpdaterWindowTitle">
[APP_NAME] Aktualisierung
@@ -3927,6 +3981,12 @@ Falls diese Meldung weiterhin angezeigt wird, wenden Sie sich bitte an [SUPPORT_
<string name="IM_unblock_only_groups_friends">
Wenn Sie diese Meldung sehen, müssen Sie unter „Einstellungen“ &gt; „Privatsphäre“ die Option „Nur IMs und Anrufe von Freunden oder Gruppen durchstellen“ deaktivieren.
</string>
+ <string name="OnlineStatus">
+ Online
+ </string>
+ <string name="OfflineStatus">
+ Offline
+ </string>
<string name="answered_call">
Ihr Anruf wurde entgegengenommen
</string>
@@ -3936,6 +3996,9 @@ Falls diese Meldung weiterhin angezeigt wird, wenden Sie sich bitte an [SUPPORT_
<string name="you_joined_call">
Sie sind dem Gespräch beigetreten
</string>
+ <string name="you_auto_rejected_call-im">
+ Sie haben den Voice-Anruf automatisch abgelehnt, während der Nicht-stören-Modus aktiviert war.
+ </string>
<string name="name_started_call">
[NAME] hat einen Voice-Anruf begonnen
</string>
@@ -3952,7 +4015,7 @@ Falls diese Meldung weiterhin angezeigt wird, wenden Sie sich bitte an [SUPPORT_
Wird verbunden...
</string>
<string name="conference-title">
- Ad-hoc-Konferenz
+ Chat mit mehreren Personen
</string>
<string name="conference-title-incoming">
Konferenz mit [AGENT_NAME]
@@ -4832,6 +4895,9 @@ Setzen Sie den Editorpfad in Anführungszeichen
<string name="Command_Chat_Label">
Chat
</string>
+ <string name="Command_Conversations_Label">
+ Unterhaltungen
+ </string>
<string name="Command_Compass_Label">
Kompass
</string>
@@ -4907,6 +4973,9 @@ Setzen Sie den Editorpfad in Anführungszeichen
<string name="Command_Chat_Tooltip">
Mit Leuten in der Nähe chatten
</string>
+ <string name="Command_Conversations_Tooltip">
+ Mit allen unterhalten
+ </string>
<string name="Command_Compass_Tooltip">
Kompass
</string>
@@ -5000,6 +5069,21 @@ Setzen Sie den Editorpfad in Anführungszeichen
<string name="Normal">
Normal
</string>
+ <string name="Pathfinding_Wiki_URL">
+ http://wiki.secondlife.com/wiki/Pathfinding_Tools_in_the_Second_Life_Viewer
+ </string>
+ <string name="Pathfinding_Object_Attr_None">
+ Keine
+ </string>
+ <string name="Pathfinding_Object_Attr_Permanent">
+ Wirkt sich auf Navmesh aus
+ </string>
+ <string name="Pathfinding_Object_Attr_Character">
+ Figur
+ </string>
+ <string name="Pathfinding_Object_Attr_MultiSelect">
+ (mehrere)
+ </string>
<string name="snapshot_quality_very_low">
Sehr niedrig
</string>
@@ -5015,4 +5099,22 @@ Setzen Sie den Editorpfad in Anführungszeichen
<string name="snapshot_quality_very_high">
Sehr hoch
</string>
+ <string name="TeleportMaturityExceeded">
+ Der Einwohner kann diese Region nicht besuchen.
+ </string>
+ <string name="UserDictionary">
+ [Benutzer]
+ </string>
+ <string name="logging_calls_disabled_log_empty">
+ Unterhaltungen werden nicht protokolliert. Um ein Protokoll zu starten, wählen Sie „Speichern: nur Protokoll“ oder „Speichern: Protokoll und Transkripte“ unter „Einstellungen“ &gt; „Chat“.
+ </string>
+ <string name="logging_calls_disabled_log_not_empty">
+ Es werden keine Unterhaltungen mehr protokolliert. Um weiterhin ein Protokoll zu führen, wählen Sie „Speichern: nur Protokoll“ oder „Speichern: Protokoll und Transkripte“ unter „Einstellungen“ &gt; „Chat“.
+ </string>
+ <string name="logging_calls_enabled_log_empty">
+ Keine protokollierten Unterhaltungen verfügbar. Hier erscheint ein Protokolleintrag, wenn Sie eine Person kontaktieren oder von einer Person kontaktiert werden.
+ </string>
+ <string name="loading_chat_logs">
+ Laden...
+ </string>
</strings>
diff --git a/indra/newview/skins/default/xui/de/teleport_strings.xml b/indra/newview/skins/default/xui/de/teleport_strings.xml
index 9cf381bacc..8062633df6 100644..100755
--- a/indra/newview/skins/default/xui/de/teleport_strings.xml
+++ b/indra/newview/skins/default/xui/de/teleport_strings.xml
@@ -46,6 +46,9 @@ Ihre Teleport-Anfrage kann nicht sofort bearbeitet werden. Versuchen Sie es in e
<message name="no_inventory_host">
Das Inventarsystem ist zurzeit nicht verfügbar.
</message>
+ <message name="MustGetAgeRegion">
+ Sie müssen mindestens 18 Jahre alt sein, um diese Region betreten zu können.
+ </message>
</message_set>
<message_set name="progress">
<message name="sending_dest">
@@ -81,5 +84,8 @@ Ihre Teleport-Anfrage kann nicht sofort bearbeitet werden. Versuchen Sie es in e
<message name="requesting">
Teleport wird initialisiert...
</message>
+ <message name="pending">
+ Anstehender Teleport...
+ </message>
</message_set>
</teleport_messages>
diff --git a/indra/newview/skins/default/xui/de/xui_version.xml b/indra/newview/skins/default/xui/de/xui_version.xml
index 0e777751d3..0e777751d3 100644..100755
--- a/indra/newview/skins/default/xui/de/xui_version.xml
+++ b/indra/newview/skins/default/xui/de/xui_version.xml
diff --git a/indra/newview/skins/default/xui/en/accordion_drag.xml b/indra/newview/skins/default/xui/en/accordion_drag.xml
index e8a705e744..e8a705e744 100644..100755
--- a/indra/newview/skins/default/xui/en/accordion_drag.xml
+++ b/indra/newview/skins/default/xui/en/accordion_drag.xml
diff --git a/indra/newview/skins/default/xui/en/accordion_parent.xml b/indra/newview/skins/default/xui/en/accordion_parent.xml
index e17a0dd351..e17a0dd351 100644..100755
--- a/indra/newview/skins/default/xui/en/accordion_parent.xml
+++ b/indra/newview/skins/default/xui/en/accordion_parent.xml
diff --git a/indra/newview/skins/default/xui/en/alert_button.xml b/indra/newview/skins/default/xui/en/alert_button.xml
index a60e9afab1..a60e9afab1 100644..100755
--- a/indra/newview/skins/default/xui/en/alert_button.xml
+++ b/indra/newview/skins/default/xui/en/alert_button.xml
diff --git a/indra/newview/skins/default/xui/en/alert_check_box.xml b/indra/newview/skins/default/xui/en/alert_check_box.xml
index 5535a5dc2a..5535a5dc2a 100644..100755
--- a/indra/newview/skins/default/xui/en/alert_check_box.xml
+++ b/indra/newview/skins/default/xui/en/alert_check_box.xml
diff --git a/indra/newview/skins/default/xui/en/alert_icon.xml b/indra/newview/skins/default/xui/en/alert_icon.xml
index b0886fce06..b0886fce06 100644..100755
--- a/indra/newview/skins/default/xui/en/alert_icon.xml
+++ b/indra/newview/skins/default/xui/en/alert_icon.xml
diff --git a/indra/newview/skins/default/xui/en/alert_line_editor.xml b/indra/newview/skins/default/xui/en/alert_line_editor.xml
index 54dbc698c8..54dbc698c8 100644..100755
--- a/indra/newview/skins/default/xui/en/alert_line_editor.xml
+++ b/indra/newview/skins/default/xui/en/alert_line_editor.xml
diff --git a/indra/newview/skins/default/xui/en/favorites_bar_button.xml b/indra/newview/skins/default/xui/en/favorites_bar_button.xml
index e7dd62eb64..e7dd62eb64 100644..100755
--- a/indra/newview/skins/default/xui/en/favorites_bar_button.xml
+++ b/indra/newview/skins/default/xui/en/favorites_bar_button.xml
diff --git a/indra/newview/skins/default/xui/en/floater_aaa.xml b/indra/newview/skins/default/xui/en/floater_aaa.xml
index d11373ce1d..d11373ce1d 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_aaa.xml
+++ b/indra/newview/skins/default/xui/en/floater_aaa.xml
diff --git a/indra/newview/skins/default/xui/en/floater_about.xml b/indra/newview/skins/default/xui/en/floater_about.xml
index 060d889003..703015af20 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_about.xml
+++ b/indra/newview/skins/default/xui/en/floater_about.xml
@@ -22,7 +22,9 @@ Built with [COMPILER] version [COMPILER_VERSION]
</floater.string>
<floater.string
name="AboutPosition">
-You are at [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1] in [REGION] located at &lt;nolink&gt;[HOSTNAME]&lt;/nolink&gt; ([HOSTIP])
+You are at [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] in [REGION] located at &lt;nolink&gt;[HOSTNAME]&lt;/nolink&gt; ([HOSTIP])
+SLURL: &lt;nolink&gt;[SLURL]&lt;/nolink&gt;
+(global coordinates [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1])
[SERVER_VERSION]
[SERVER_RELEASE_NOTES_URL]
@@ -196,27 +198,26 @@ Dummy Name replaced at run time
top="5"
width="435"
word_wrap="true">
- 3Dconnexion SDK Copyright (C) 1992-2007 3Dconnexion
- APR Copyright (C) 2000-2004 The Apache Software Foundation
- Collada DOM Copyright 2005 Sony Computer Entertainment Inc.
- cURL Copyright (C) 1996-2002, Daniel Stenberg, (daniel@haxx.se)
+ 3Dconnexion SDK Copyright (C) 1992-2009 3Dconnexion
+ APR Copyright (C) 2011 The Apache Software Foundation
+ Collada DOM Copyright 2006 Sony Computer Entertainment Inc.
+ cURL Copyright (C) 1996-2010, Daniel Stenberg, (daniel@haxx.se)
DBus/dbus-glib Copyright (C) 2002, 2003 CodeFactory AB / Copyright (C) 2003, 2004 Red Hat, Inc.
expat Copyright (C) 1998, 1999, 2000 Thai Open Source Software Center Ltd.
- FreeType Copyright (C) 1996-2002, The FreeType Project (www.freetype.org).
+ FreeType Copyright (C) 1996-2002, 2006 David Turner, Robert Wilhelm, and Werner Lemberg.
GL Copyright (C) 1999-2004 Brian Paul.
GLOD Copyright (C) 2003-04 Jonathan Cohen, Nat Duca, Chris Niski, Johns Hopkins University and David Luebke, Brenden Schubert, University of Virginia.
google-perftools Copyright (c) 2005, Google Inc.
Havok.com(TM) Copyright (C) 1999-2001, Telekinesys Research Limited.
jpeg2000 Copyright (C) 2001, David Taubman, The University of New South Wales (UNSW)
jpeglib Copyright (C) 1991-1998, Thomas G. Lane.
- ogg/vorbis Copyright (C) 2001, Xiphophorus
- OpenSSL Copyright (C) 1998-2002 The OpenSSL Project.
- PCRE Copyright (c) 1997-2008 University of Cambridge
+ ogg/vorbis Copyright (C) 2002, Xiphophorus
+ OpenSSL Copyright (C) 1998-2008 The OpenSSL Project.
+ PCRE Copyright (c) 1997-2012 University of Cambridge
SDL Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga
SSLeay Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
xmlrpc-epi Copyright (C) 2000 Epinions, Inc.
- zlib Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler.
- google-perftools Copyright (c) 2005, Google Inc.
+ zlib Copyright (C) 1995-2012 Jean-loup Gailly and Mark Adler.
Second Life Viewer uses Havok (TM) Physics. (c)Copyright 1999-2010 Havok.com Inc. (and its Licensors). All Rights Reserved. See www.havok.com for details.
diff --git a/indra/newview/skins/default/xui/en/floater_about_land.xml b/indra/newview/skins/default/xui/en/floater_about_land.xml
index fb123ec4d1..a660e812cc 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/en/floater_about_land.xml
@@ -1354,84 +1354,18 @@ Only large parcels can be listed in search.
top="150"
width="430" />
<combo_box
- enabled="false"
- height="23"
- layout="topleft"
- left="20"
- top="194"
- name="land category with adult"
- visible="false"
- width="140">
- <combo_box.item
- label="Any Category"
- name="item0"
- value="any" />
- <combo_box.item
- label="Linden Location"
- name="item1"
- value="linden" />
- <combo_box.item
- label="Adult"
- name="item2"
- value="adult" />
- <combo_box.item
- label="Arts &amp; Culture"
- name="item3"
- value="arts" />
- <combo_box.item
- label="Business"
- name="item4"
- value="store" />
- <combo_box.item
- label="Educational"
- name="item5"
- value="educational" />
- <combo_box.item
- label="Gaming"
- name="item6"
- value="game" />
- <combo_box.item
- label="Hangout"
- name="item7"
- value="gather" />
- <combo_box.item
- label="Newcomer Friendly"
- name="item8"
- value="newcomer" />
- <combo_box.item
- label="Parks &amp; Nature"
- name="item9"
- value="park" />
- <combo_box.item
- label="Residential"
- name="item10"
- value="home" />
- <combo_box.item
- label="Shopping"
- name="item11"
- value="shopping" />
- <combo_box.item
- label="Rental"
- name="item13"
- value="rental" />
- <combo_box.item
- label="Other"
- name="item12"
- value="other" />
- </combo_box>
- <combo_box
- enabled="false"
+ enabled="true"
height="23"
layout="topleft"
left="20"
top="194"
name="land category"
- visible="false"
+ visible="true"
width="140">
<combo_box.item
label="Any Category"
name="item0"
- value="any" />
+ value="none" />
<combo_box.item
label="Linden Location"
name="item1"
@@ -1989,11 +1923,11 @@ Only large parcels can be listed in search.
<check_box
follows="top|left"
height="16"
- label="Have been age-verified [ESTATE_AGE_LIMIT]"
+ label="Are age 18 or older [ESTATE_AGE_LIMIT]"
layout="topleft"
left_delta="0"
name="limit_age_verified"
- tool_tip="Residents must be age verified to access this parcel. See the [SUPPORT_SITE] for more information."
+ tool_tip="Residents must be age 18 or older to access this parcel. See the [SUPPORT_SITE] for more information."
top_pad="4"
width="278" />
<check_box
diff --git a/indra/newview/skins/default/xui/en/floater_activeim.xml b/indra/newview/skins/default/xui/en/floater_activeim.xml
index b79c5d9a19..b79c5d9a19 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_activeim.xml
+++ b/indra/newview/skins/default/xui/en/floater_activeim.xml
diff --git a/indra/newview/skins/default/xui/en/floater_animation_anim_preview.xml b/indra/newview/skins/default/xui/en/floater_animation_anim_preview.xml
index b5538a511c..b5538a511c 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_animation_anim_preview.xml
+++ b/indra/newview/skins/default/xui/en/floater_animation_anim_preview.xml
diff --git a/indra/newview/skins/default/xui/en/floater_animation_bvh_preview.xml b/indra/newview/skins/default/xui/en/floater_animation_bvh_preview.xml
index cb6b2f6ebc..cb6b2f6ebc 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_animation_bvh_preview.xml
+++ b/indra/newview/skins/default/xui/en/floater_animation_bvh_preview.xml
diff --git a/indra/newview/skins/default/xui/en/floater_auction.xml b/indra/newview/skins/default/xui/en/floater_auction.xml
index 9c6d114c4c..9c6d114c4c 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_auction.xml
+++ b/indra/newview/skins/default/xui/en/floater_auction.xml
diff --git a/indra/newview/skins/default/xui/en/floater_autoreplace.xml b/indra/newview/skins/default/xui/en/floater_autoreplace.xml
new file mode 100755
index 0000000000..0bfefc8abe
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_autoreplace.xml
@@ -0,0 +1,289 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ border="true"
+ can_close="true"
+ can_minimize="true"
+ can_resize="false"
+ help_topic="autoreplace_settings"
+ save_rect="true"
+ height="455"
+ width="490"
+ name="autoreplace_floater"
+ title="Auto-Replace Settings">
+ <check_box
+ bottom_delta="30"
+ left_delta="15"
+ height="16"
+ width="100"
+ follows="left|top"
+ label="Enable Auto-Replace"
+ name="autoreplace_enable"
+ tool_tip="As you enter chat text, replace any of the keywords entered with the corresponding replacement"/>
+ <view_border
+ top_pad="15"
+ left="2"
+ height="0"
+ width="491"
+ follows="left|top"
+ bevel_style="none"
+ border_thickness="1"
+ mouse_opaque="false"
+ name="divisor1"/>
+ <button
+ top_pad="10"
+ left="10"
+ height="22"
+ width="110"
+ enabled="true"
+ follows="left|top"
+ mouse_opaque="true"
+ halign="center"
+ scale_image="true"
+ name="autoreplace_import_list"
+ label="Import List..."
+ tool_tip="Load a previously exported list from a file."/>
+ <button
+ top_delta="0"
+ left_pad="10"
+ height="22"
+ width="110"
+ enabled="true"
+ follows="left|top"
+ mouse_opaque="true"
+ halign="center"
+ scale_image="true"
+ name="autoreplace_export_list"
+ label="Export List..."
+ tool_tip="Save the selected list to a file so you can share it."/>
+ <button
+ top_delta="0"
+ left_pad="10"
+ height="22"
+ width="110"
+ enabled="true"
+ follows="left|top"
+ mouse_opaque="true"
+ halign="center"
+ scale_image="true"
+ name="autoreplace_new_list"
+ label="New List..."
+ tool_tip="Create a new list."/>
+ <button
+ top_delta="0"
+ left_pad="10"
+ height="22"
+ width="110"
+ enabled="true"
+ follows="left|top"
+ mouse_opaque="true"
+ halign="center"
+ scale_image="true"
+ name="autoreplace_delete_list"
+ label="Delete List"
+ tool_tip="Delete the selected list."/>
+ <scroll_list
+ top_pad="10"
+ left="10"
+ height="100"
+ width="370"
+ follows="left|top"
+ column_padding="0"
+ draw_heading="false"
+ multi_select="false"
+ name="autoreplace_list_name"
+ search_column="0">
+ </scroll_list>
+ <button
+ top_delta="23"
+ left_pad="10"
+ height="22"
+ width="90"
+ enabled="true"
+ follows="left|top"
+ mouse_opaque="true"
+ halign="center"
+ scale_image="true"
+ name="autoreplace_list_up"
+ image_overlay="Arrow_Up"
+ tool_tip="Move this list up in priority."/>
+ <button
+ top_pad="10"
+ left_delta="0"
+ height="22"
+ width="90"
+ enabled="true"
+ follows="left|top"
+ mouse_opaque="true"
+ halign="center"
+ scale_image="true"
+ name="autoreplace_list_down"
+ image_overlay="Arrow_Down"
+ tool_tip="Move this list down in priority."/>
+ <view_border
+ top_pad="36"
+ left="2"
+ height="0"
+ width="491"
+ follows="left|top"
+ bevel_style="none"
+ border_thickness="1"
+ mouse_opaque="false"
+ name="divisor2"/>
+ <scroll_list
+ top_pad="10"
+ left="10"
+ height="120"
+ width="370"
+ follows="left|top"
+ column_padding="0"
+ draw_heading="true"
+ multi_select="true"
+ name="autoreplace_list_replacements"
+ search_column="0">
+ <scroll_list.columns
+ label="Keyword"
+ name="keyword"
+ relative_width="0.30" />
+ <scroll_list.columns
+ label="Replacement"
+ name="replacement"
+ relative_width="0.70" />
+ </scroll_list>
+ <button
+ top_delta="41"
+ left_pad="10"
+ height="22"
+ width="90"
+ enabled="true"
+ follows="left|top"
+ mouse_opaque="true"
+ halign="center"
+ scale_image="true"
+ name="autoreplace_add_entry"
+ label="Add..."/>
+ <button
+ top_pad="10"
+ left_delta="0"
+ height="22"
+ width="90"
+ enabled="true"
+ follows="left|top"
+ mouse_opaque="true"
+ halign="center"
+ scale_image="true"
+ name="autoreplace_delete_entry"
+ label="Remove"/>
+ <view_border
+ top_pad="38"
+ left="2"
+ height="0"
+ width="491"
+ follows="left|top"
+ bevel_style="none"
+ border_thickness="1"
+ mouse_opaque="false"
+ name="divisor3"/>
+ <text
+ type="string"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="10"
+ top_pad="13"
+ width="50">
+ Keyword:
+ </text>
+ <line_editor
+ name="autoreplace_keyword"
+ follows="left|top"
+ height="23"
+ layout="topleft"
+ left="100"
+ max_length_bytes="255"
+ top_delta="-5"
+ width="150"
+ />
+ <text
+ type="string"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="10"
+ right="90"
+ top_pad="10"
+ >
+ Replacement:
+ </text>
+ <line_editor
+ name="autoreplace_replacement"
+ follows="left|top"
+ height="23"
+ layout="topleft"
+ left="100"
+ max_length_bytes="255"
+ top_delta="-5"
+ width="280"
+ />
+ <button
+ top_delta="0"
+ right="-10"
+ height="22"
+ width="90"
+ enabled="false"
+ follows="left|top"
+ mouse_opaque="true"
+ halign="center"
+ scale_image="true"
+ name="autoreplace_save_entry"
+ label="Save Entry"
+ tool_tip="Save this entry."/>
+ <view_border
+ top_pad="10"
+ left="2"
+ height="0"
+ width="491"
+ follows="left|top"
+ bevel_style="none"
+ border_thickness="1"
+ mouse_opaque="false"
+ name="divisor4"/>
+ <button
+ top_pad="10"
+ right="380"
+ height="22"
+ width="90"
+ enabled="true"
+ follows="left|top"
+ mouse_opaque="true"
+ halign="center"
+ scale_image="true"
+ name="autoreplace_save_changes"
+ label="Save Changes"
+ tool_tip="Save all changes."/>
+ <button
+ top_delta="0"
+ right="480"
+ height="22"
+ width="90"
+ enabled="true"
+ follows="left|top"
+ mouse_opaque="true"
+ halign="center"
+ scale_image="true"
+ name="autoreplace_cancel"
+ label="Cancel"
+ tool_tip="Discard all changes."/>
+</floater>
+<!--
+ <text
+ top_pad="10"
+ left="10"
+ height="16"
+ width="260"
+ follows="left|top"
+ halign="center"
+ mouse_opaque="true"
+ name="autoreplace_text2">
+ Entries
+ </text>
+-->
diff --git a/indra/newview/skins/default/xui/en/floater_avatar.xml b/indra/newview/skins/default/xui/en/floater_avatar.xml
index cd5cca02bd..cd5cca02bd 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_avatar.xml
+++ b/indra/newview/skins/default/xui/en/floater_avatar.xml
diff --git a/indra/newview/skins/default/xui/en/floater_avatar_picker.xml b/indra/newview/skins/default/xui/en/floater_avatar_picker.xml
index 1a55dc2e2c..1a55dc2e2c 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_avatar_picker.xml
+++ b/indra/newview/skins/default/xui/en/floater_avatar_picker.xml
diff --git a/indra/newview/skins/default/xui/en/floater_avatar_textures.xml b/indra/newview/skins/default/xui/en/floater_avatar_textures.xml
index bac3ea86f1..bac3ea86f1 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_avatar_textures.xml
+++ b/indra/newview/skins/default/xui/en/floater_avatar_textures.xml
diff --git a/indra/newview/skins/default/xui/en/floater_beacons.xml b/indra/newview/skins/default/xui/en/floater_beacons.xml
index 3d29356b22..3d29356b22 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_beacons.xml
+++ b/indra/newview/skins/default/xui/en/floater_beacons.xml
diff --git a/indra/newview/skins/default/xui/en/floater_build_options.xml b/indra/newview/skins/default/xui/en/floater_build_options.xml
index 38428b36fc..38428b36fc 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_build_options.xml
+++ b/indra/newview/skins/default/xui/en/floater_build_options.xml
diff --git a/indra/newview/skins/default/xui/en/floater_bulk_perms.xml b/indra/newview/skins/default/xui/en/floater_bulk_perms.xml
index 4e0cfb0cd4..e7ab3cacdc 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_bulk_perms.xml
+++ b/indra/newview/skins/default/xui/en/floater_bulk_perms.xml
@@ -6,7 +6,7 @@
layout="topleft"
name="floaterbulkperms"
help_topic="floaterbulkperms"
- title="EDIT CONTENT PERMISSIONS"
+ title="ADJUST CONTENT PERMISSIONS"
width="410">
<floater.string
name="nothing_to_modify_text">
@@ -192,7 +192,7 @@
name="newperms"
top="90"
width="250">
- New Content Permissions
+ Adjust Content Permissions To
</text>
<text
type="string"
@@ -292,11 +292,22 @@
height="23"
label="OK"
layout="topleft"
- left="205"
- name="apply"
+ left="110"
+ name="ok"
top_pad="10"
width="90">
<button.commit_callback
+ function="BulkPermission.Ok"/>
+ </button>
+ <button
+ follows="left|top"
+ height="23"
+ label="Apply"
+ layout="topleft"
+ left_pad="5"
+ name="apply"
+ width="90">
+ <button.commit_callback
function="BulkPermission.Apply"/>
</button>
<button
diff --git a/indra/newview/skins/default/xui/en/floater_bumps.xml b/indra/newview/skins/default/xui/en/floater_bumps.xml
index 1f2fe62b3c..1f2fe62b3c 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_bumps.xml
+++ b/indra/newview/skins/default/xui/en/floater_bumps.xml
diff --git a/indra/newview/skins/default/xui/en/floater_buy_contents.xml b/indra/newview/skins/default/xui/en/floater_buy_contents.xml
index ac96a70805..ac96a70805 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_buy_contents.xml
+++ b/indra/newview/skins/default/xui/en/floater_buy_contents.xml
diff --git a/indra/newview/skins/default/xui/en/floater_buy_currency.xml b/indra/newview/skins/default/xui/en/floater_buy_currency.xml
index 553c5d51d0..553c5d51d0 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_buy_currency.xml
+++ b/indra/newview/skins/default/xui/en/floater_buy_currency.xml
diff --git a/indra/newview/skins/default/xui/en/floater_buy_currency_html.xml b/indra/newview/skins/default/xui/en/floater_buy_currency_html.xml
index 0637eedfb2..0637eedfb2 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_buy_currency_html.xml
+++ b/indra/newview/skins/default/xui/en/floater_buy_currency_html.xml
diff --git a/indra/newview/skins/default/xui/en/floater_buy_land.xml b/indra/newview/skins/default/xui/en/floater_buy_land.xml
index 22cc058e46..22cc058e46 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_buy_land.xml
+++ b/indra/newview/skins/default/xui/en/floater_buy_land.xml
diff --git a/indra/newview/skins/default/xui/en/floater_buy_object.xml b/indra/newview/skins/default/xui/en/floater_buy_object.xml
index 5fdd4aa49d..5fdd4aa49d 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_buy_object.xml
+++ b/indra/newview/skins/default/xui/en/floater_buy_object.xml
diff --git a/indra/newview/skins/default/xui/en/floater_camera.xml b/indra/newview/skins/default/xui/en/floater_camera.xml
index 22bc488a92..521389d7b3 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_camera.xml
+++ b/indra/newview/skins/default/xui/en/floater_camera.xml
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<floater
positioning="specified"
- left="458"
- bottom="-80"
+ right="-460"
+ bottom="-50"
follows="left|bottom"
legacy_header_height="18"
can_minimize="true"
diff --git a/indra/newview/skins/default/xui/en/floater_chat_bar.xml b/indra/newview/skins/default/xui/en/floater_chat_bar.xml
deleted file mode 100644
index 688a01ce7b..0000000000
--- a/indra/newview/skins/default/xui/en/floater_chat_bar.xml
+++ /dev/null
@@ -1,84 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<floater
- positioning="specified"
- left="10"
- bottom="-10"
- height="60"
- layout="topleft"
- legacy_header_height="25"
- single_instance="true"
- title="NEARBY CHAT"
- save_rect="true"
- save_visibility="true"
- can_close="true"
- can_minimize="true"
- help_topic="chat_bar"
- min_height="60"
- min_width="150"
- can_resize="true"
- default_tab_group="1"
- name="chat_bar"
- width="300">
- <panel
- top="20"
- class="panel_nearby_chat"
- follow="all"
- width="300"
- height="0"
- visible="false"
- filename="panel_nearby_chat.xml"
- name="nearby_chat" />
- <panel width="300"
- height="31"
- left="0"
- name="bottom_panel"
- bottom="-1"
- follows="left|right|bottom"
- tab_group="1">
- <line_editor
- border_style="line"
- border_thickness="1"
- follows="left|right"
- height="23"
- label="Click here to chat."
- layout="topleft"
- left_delta="7"
- left="0"
- max_length_bytes="1023"
- name="chat_box"
- text_pad_left="5"
- text_pad_right="25"
- tool_tip="Press Enter to say, Ctrl+Enter to shout"
- top="2"
- width="255" />
- <output_monitor
- auto_update="true"
- follows="right"
- draw_border="false"
- height="16"
- layout="topleft"
- left_pad="-24"
- mouse_opaque="true"
- name="chat_zone_indicator"
- top="6"
- visible="true"
- width="20" />
- <button
- follows="right"
- is_toggle="true"
- width="20"
- top="2"
- layout="topleft"
- left_pad="12"
- image_disabled="ComboButton_UpOff"
- image_unselected="ComboButton_UpOff"
- image_selected="ComboButton_On"
- image_pressed="ComboButton_UpSelected"
- image_pressed_selected="ComboButton_Selected"
- height="23"
- chrome="true"
- name="show_nearby_chat"
- tool_tip="Shows/hides nearby chat log">
- </button>
- </panel>
-</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_choose_group.xml b/indra/newview/skins/default/xui/en/floater_choose_group.xml
index 2cf6e682fd..2cf6e682fd 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_choose_group.xml
+++ b/indra/newview/skins/default/xui/en/floater_choose_group.xml
diff --git a/indra/newview/skins/default/xui/en/floater_color_picker.xml b/indra/newview/skins/default/xui/en/floater_color_picker.xml
index e06d10606a..e06d10606a 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_color_picker.xml
+++ b/indra/newview/skins/default/xui/en/floater_color_picker.xml
diff --git a/indra/newview/skins/default/xui/en/floater_conversation_log.xml b/indra/newview/skins/default/xui/en/floater_conversation_log.xml
new file mode 100755
index 0000000000..19a4cbc119
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_conversation_log.xml
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+
+<floater
+ can_resize="true"
+ positioning="cascading"
+ help_topic="conversation_log"
+ height="200"
+ min_height="100"
+ min_width="230"
+ layout="topleft"
+ name="floater_conversation_log"
+ save_rect="true"
+ single_instance="true"
+ reuse_instance="true"
+ title="CONVERSATION LOG"
+ width="300">
+ <panel
+ follows="left|top|right"
+ height="32"
+ left="0"
+ name="buttons_panel"
+ top="0">
+ <filter_editor
+ follows="left|top|right"
+ height="23"
+ layout="topleft"
+ left="8"
+ label="Filter People"
+ max_length_chars="300"
+ name="people_filter_input"
+ text_color="Black"
+ text_pad_left="10"
+ top="4"
+ width="204" />
+ <menu_button
+ follows="top|right"
+ height="25"
+ image_hover_unselected="Toolbar_Middle_Over"
+ image_overlay="Conv_toolbar_sort"
+ image_selected="Toolbar_Middle_Selected"
+ image_unselected="Toolbar_Middle_Off"
+ layout="topleft"
+ left_pad="8"
+ menu_filename="menu_conversation_log_view.xml"
+ menu_position="bottomleft"
+ name="conversation_view_btn"
+ tool_tip="View/sort options"
+ top="3"
+ width="31" />
+ <menu_button
+ follows="top|right"
+ height="25"
+ image_hover_unselected="Toolbar_Middle_Over"
+ image_overlay="OptionsMenu_Off"
+ image_selected="Toolbar_Middle_Selected"
+ image_unselected="Toolbar_Middle_Off"
+ layout="topleft"
+ left_pad="8"
+ name="conversations_gear_btn"
+ tool_tip="Actions on selected person or group"
+ top="3"
+ width="31" />
+ </panel>
+ <panel
+ bottom="-1"
+ follows="all"
+ left="0"
+ name="log_panel"
+ right="-1"
+ top="32">
+ <conversation_log_list
+ allow_select="true"
+ bottom="-8"
+ opaque="true"
+ follows="all"
+ left="8"
+ keep_selection_visible_on_reshape="true"
+ item_pad="2"
+ multi_select="false"
+ name="conversation_log_list"
+ right="-8"
+ top="0" />
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_conversation_preview.xml b/indra/newview/skins/default/xui/en/floater_conversation_preview.xml
new file mode 100755
index 0000000000..764b9d8385
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_conversation_preview.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ legacy_header_height="18"
+ can_resize="true"
+ default_tab_group="1"
+ help_topic="conversation_preview"
+ height="391"
+ layout="topleft"
+ min_height="243"
+ min_width="234"
+ name="preview_conversation"
+ title="CONVERSATION:"
+ width="400">
+ <floater.string
+ name="Title">
+ CONVERSATION: [NAME]
+ </floater.string>
+ <chat_history
+ font="SansSerifSmall"
+ follows="all"
+ visible="true"
+ height="330"
+ name="chat_history"
+ notify_unread_msg="false"
+ parse_highlights="true"
+ parse_urls="true"
+ left="5"
+ top_pad="25"
+ width="390">
+ </chat_history>
+ <text
+ follows="bottom|right"
+ font="SansSerif"
+ height="22"
+ layout="topleft"
+ name="page_label"
+ right="-110"
+ top_pad="7"
+ value="Page"
+ width="35">
+ </text>
+ <spinner
+ allow_digits_only="true"
+ decimal_digits="0"
+ follows="bottom|right"
+ height="23"
+ increment="1"
+ label_width="40"
+ layout="topleft"
+ left_pad="0"
+ name="history_page_spin"
+ top_delta="-3"
+ width="50"/>
+ <text
+ follows="bottom|right"
+ font="SansSerif"
+ height="22"
+ layout="topleft"
+ name="page_num_label"
+ left_pad="5"
+ top_delta="4"
+ width="40">
+ </text>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_critical.xml b/indra/newview/skins/default/xui/en/floater_critical.xml
index 143bcb4430..143bcb4430 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_critical.xml
+++ b/indra/newview/skins/default/xui/en/floater_critical.xml
diff --git a/indra/newview/skins/default/xui/en/floater_delete_env_preset.xml b/indra/newview/skins/default/xui/en/floater_delete_env_preset.xml
index b5de4166f6..b5de4166f6 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_delete_env_preset.xml
+++ b/indra/newview/skins/default/xui/en/floater_delete_env_preset.xml
diff --git a/indra/newview/skins/default/xui/en/floater_destinations.xml b/indra/newview/skins/default/xui/en/floater_destinations.xml
index 39aa8e07bb..94ebaa9cb2 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_destinations.xml
+++ b/indra/newview/skins/default/xui/en/floater_destinations.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<floater
- positioning="cascading"
+ positioning="cascading"
ignore_ui_scale="false"
legacy_header_height="225"
can_minimize="true"
@@ -17,11 +17,11 @@
save_rect="true"
save_visibility="true"
title="DESTINATIONS"
- width="840">
+ width="550">
<web_browser
top="25"
height="200"
- width="840"
+ width="550"
follows="all"
name="destination_guide_contents"
trusted_content="true"/>
diff --git a/indra/newview/skins/default/xui/en/floater_display_name.xml b/indra/newview/skins/default/xui/en/floater_display_name.xml
index 9a9fd32a77..9a9fd32a77 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_display_name.xml
+++ b/indra/newview/skins/default/xui/en/floater_display_name.xml
diff --git a/indra/newview/skins/default/xui/en/floater_edit_day_cycle.xml b/indra/newview/skins/default/xui/en/floater_edit_day_cycle.xml
index d9a3ad0c4b..d9a3ad0c4b 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_edit_day_cycle.xml
+++ b/indra/newview/skins/default/xui/en/floater_edit_day_cycle.xml
diff --git a/indra/newview/skins/default/xui/en/floater_edit_sky_preset.xml b/indra/newview/skins/default/xui/en/floater_edit_sky_preset.xml
index 56233d91ee..56233d91ee 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_edit_sky_preset.xml
+++ b/indra/newview/skins/default/xui/en/floater_edit_sky_preset.xml
diff --git a/indra/newview/skins/default/xui/en/floater_edit_water_preset.xml b/indra/newview/skins/default/xui/en/floater_edit_water_preset.xml
index 905983e7fa..905983e7fa 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_edit_water_preset.xml
+++ b/indra/newview/skins/default/xui/en/floater_edit_water_preset.xml
diff --git a/indra/newview/skins/default/xui/en/floater_environment_settings.xml b/indra/newview/skins/default/xui/en/floater_environment_settings.xml
index 1b1cafaca6..1b1cafaca6 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_environment_settings.xml
+++ b/indra/newview/skins/default/xui/en/floater_environment_settings.xml
diff --git a/indra/newview/skins/default/xui/en/floater_event.xml b/indra/newview/skins/default/xui/en/floater_event.xml
index cf61b7d24d..cf61b7d24d 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_event.xml
+++ b/indra/newview/skins/default/xui/en/floater_event.xml
diff --git a/indra/newview/skins/default/xui/en/floater_fast_timers.xml b/indra/newview/skins/default/xui/en/floater_fast_timers.xml
index 77adb5524e..77adb5524e 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_fast_timers.xml
+++ b/indra/newview/skins/default/xui/en/floater_fast_timers.xml
diff --git a/indra/newview/skins/default/xui/en/floater_fbc_web.xml b/indra/newview/skins/default/xui/en/floater_fbc_web.xml
new file mode 100644
index 0000000000..0d35e22a19
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_fbc_web.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater name="floater_fbc_web"
+ help_topic="fbc_web"
+ width="780"
+ height="775"
+ save_rect="true"
+ single_instance="true"
+ reuse_instance="false"
+ filename="floater_web_content.xml"/>
diff --git a/indra/newview/skins/default/xui/en/floater_font_test.xml b/indra/newview/skins/default/xui/en/floater_font_test.xml
index 3ab19ec9d9..3ab19ec9d9 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_font_test.xml
+++ b/indra/newview/skins/default/xui/en/floater_font_test.xml
diff --git a/indra/newview/skins/default/xui/en/floater_gesture.xml b/indra/newview/skins/default/xui/en/floater_gesture.xml
index 200e9b9537..200e9b9537 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_gesture.xml
+++ b/indra/newview/skins/default/xui/en/floater_gesture.xml
diff --git a/indra/newview/skins/default/xui/en/floater_god_tools.xml b/indra/newview/skins/default/xui/en/floater_god_tools.xml
index e7131e20cb..e7131e20cb 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_god_tools.xml
+++ b/indra/newview/skins/default/xui/en/floater_god_tools.xml
diff --git a/indra/newview/skins/default/xui/en/floater_goto_line.xml b/indra/newview/skins/default/xui/en/floater_goto_line.xml
new file mode 100644
index 0000000000..b236888219
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_goto_line.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ legacy_header_height="18"
+ default_tab_group="1"
+ height="90"
+ layout="topleft"
+ name="script goto"
+ help_topic="script_goto"
+ title="GO TO LINE"
+ width="200">
+ <button
+ height="24"
+ label="OK"
+ label_selected="OK"
+ layout="topleft"
+ left="55"
+ name="goto_btn"
+ top="53"
+ width="90" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="10"
+ name="txt"
+ top="21"
+ width="65">
+ Go to line
+ </text>
+ <line_editor
+ border_style="line"
+ border_thickness="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="75"
+ max_length_bytes="9"
+ name="goto_line"
+ tab_group="1"
+ top="21"
+ width="85" />
+</floater> \ No newline at end of file
diff --git a/indra/newview/skins/default/xui/en/floater_hardware_settings.xml b/indra/newview/skins/default/xui/en/floater_hardware_settings.xml
index 66bb9d3cea..9deb0d2030 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_hardware_settings.xml
+++ b/indra/newview/skins/default/xui/en/floater_hardware_settings.xml
@@ -132,6 +132,28 @@
name="vbo"
tool_tip="Enabling this on modern hardware gives a performance gain. However, older hardware often has poor implementations of VBOs and you may get crashes when this is enabled."
width="315" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="10"
+ name="tc label"
+ top_pad="10"
+ width="188">
+ Enable S3TC:
+ </text>
+ <check_box
+ control_name="RenderCompressTextures"
+ height="16"
+ initial_value="true"
+ label="Enable Texture Compression (requires restart)"
+ layout="topleft"
+ left_pad="10"
+ name="texture compression"
+ tool_tip="Compresses textures in video memory, allowing for higher resolution textures to be loaded at the cost of some color quality."
+ width="315" />
<slider
control_name="TextureMemory"
decimal_digits="0"
diff --git a/indra/newview/skins/default/xui/en/floater_help_browser.xml b/indra/newview/skins/default/xui/en/floater_help_browser.xml
index c06cb63f8a..c06cb63f8a 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_help_browser.xml
+++ b/indra/newview/skins/default/xui/en/floater_help_browser.xml
diff --git a/indra/newview/skins/default/xui/en/floater_how_to.xml b/indra/newview/skins/default/xui/en/floater_how_to.xml
index 8c0077a8cc..8c0077a8cc 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_how_to.xml
+++ b/indra/newview/skins/default/xui/en/floater_how_to.xml
diff --git a/indra/newview/skins/default/xui/en/floater_hud.xml b/indra/newview/skins/default/xui/en/floater_hud.xml
index e2d860881a..e2d860881a 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_hud.xml
+++ b/indra/newview/skins/default/xui/en/floater_hud.xml
diff --git a/indra/newview/skins/default/xui/en/floater_im_container.xml b/indra/newview/skins/default/xui/en/floater_im_container.xml
index e123de46c2..28c89868bd 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_im_container.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_container.xml
@@ -1,49 +1,183 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<multi_floater
- can_close="false"
+ can_close="true"
can_minimize="true"
can_resize="true"
- height="390"
+ height="210"
+ min_height="210"
layout="topleft"
name="floater_im_box"
help_topic="floater_im_box"
save_rect="true"
save_visibility="true"
single_instance="true"
+ reuse_instance="true"
title="CONVERSATIONS"
- width="396">
- <tab_container
- follows="left|right|top|bottom"
- height="390"
+ bottom="-50"
+ right="-5"
+ width="450"
+ min_width="38">
+ <string
+ name="collapse_icon"
+ value="Conv_toolbar_collapse"/>
+ <string
+ name="expand_icon"
+ value="Conv_toolbar_expand"/>
+ <layout_stack
+ animate="true"
+ bottom="-5"
+ drag_handle_gap="6"
+ drag_handle_first_indent="27"
+ drag_handle_second_indent="10"
+ follows="all"
layout="topleft"
- left="1"
- name="im_box_tab_container"
- tab_position="bottom"
- tab_width="64"
- tab_max_width = "134"
- tab_height="16"
- use_custom_icon_ctrl="true"
- tab_icon_ctrl_pad="2"
- halign="left"
- use_ellipses="true"
- top="0"
- width="394">
- <first_tab
- tab_bottom_image_flash="Toolbar_Left_Flash"/>
- <middle_tab
- tab_bottom_image_flash="Toolbar_Middle_Flash"/>
- <last_tab
- tab_bottom_image_flash="Toolbar_Right_Flash"/>
- </tab_container>
- <icon
- color="DefaultShadowLight"
- enabled="false"
- follows="left|right|bottom"
- height="17"
- image_name="tabarea.tga"
- layout="bottomleft"
- left="1"
- name="im_box_tab_container_icon"
- bottom="10"
- width="394" />
+ left="0"
+ name="conversations_stack"
+ orientation="horizontal"
+ right="-1"
+ show_drag_handle="true"
+ top="0">
+ <layout_panel
+ auto_resize="false"
+ user_resize="true"
+ name="conversations_layout_panel"
+ min_dim="43"
+ expanded_min_dim="140">
+ <layout_stack
+ animate="false"
+ follows="left|top|right"
+ height="27"
+ layout="topleft"
+ left="0"
+ name="conversations_pane_buttons_stack"
+ orientation="horizontal"
+ right="-1"
+ top="0">
+ <layout_panel
+ auto_resize="true"
+ name="conversations_pane_buttons_expanded">
+ <menu_button
+ follows="top|left"
+ height="25"
+ image_hover_unselected="Toolbar_Middle_Over"
+ image_overlay="Conv_toolbar_sort"
+ image_selected="Toolbar_Middle_Selected"
+ image_unselected="Toolbar_Middle_Off"
+ menu_filename="menu_participant_view.xml"
+ layout="topleft"
+ left="5"
+ name="sort_btn"
+ tool_tip="View/sort options"
+ top="1"
+ width="31" />
+ <button
+ follows="top|left"
+ height="25"
+ image_hover_unselected="Toolbar_Middle_Over"
+ image_overlay="Conv_toolbar_plus"
+ image_selected="Toolbar_Middle_Selected"
+ image_unselected="Toolbar_Middle_Off"
+ layout="topleft"
+ top="1"
+ left_pad="2"
+ name="add_btn"
+ tool_tip="Start a new conversation"
+ width="31"/>
+ <button
+ follows="top|left"
+ height="25"
+ image_hover_unselected="Toolbar_Middle_Over"
+ image_overlay="Command_Speak_Icon"
+ image_selected="Toolbar_Middle_Selected"
+ image_unselected="Toolbar_Middle_Off"
+ layout="topleft"
+ top="1"
+ left_pad="2"
+ name="speak_btn"
+ tool_tip="Speak with people using your microphone"
+ width="31"/>
+ </layout_panel>
+ <layout_panel
+ auto_resize="false"
+ name="conversations_pane_buttons_collapsed"
+ width="35">
+ <button
+ follows="right|top"
+ height="25"
+ image_hover_unselected="Toolbar_Middle_Over"
+ image_overlay="Conv_toolbar_collapse"
+ image_selected="Toolbar_Middle_Selected"
+ image_unselected="Toolbar_Middle_Off"
+ layout="topleft"
+ top="1"
+ left="4"
+ name="expand_collapse_btn"
+ tool_tip="Collapse/Expand this list"
+ width="35" />
+ </layout_panel>
+ </layout_stack>
+ <panel
+ bottom="-1"
+ follows="all"
+ layout="topleft"
+ name="conversations_list_panel"
+ opaque="true"
+ top_pad="0"
+ left="5"
+ right="-1"/>
+ </layout_panel>
+ <layout_panel
+ auto_resize="true"
+ user_resize="true"
+ name="messages_layout_panel"
+ expanded_min_dim="212">
+ <panel_container
+ bottom="-1"
+ follows="all"
+ layout="topleft"
+ left="0"
+ name="im_box_tab_container"
+ right="-1"
+ top="0">
+ <panel
+ bottom="-1"
+ follows="all"
+ layout="topleft"
+ name="stub_panel"
+ opaque="true"
+ top_pad="0"
+ left="0"
+ right="-1">
+ <button
+ follows="right|top"
+ height="25"
+ image_hover_unselected="Toolbar_Middle_Over"
+ image_overlay="Conv_toolbar_collapse"
+ image_selected="Toolbar_Middle_Selected"
+ image_unselected="Toolbar_Middle_Off"
+ layout="topleft"
+ top="1"
+ right="-10"
+ name="stub_collapse_btn"
+ tool_tip="Collapse this pane"
+ width="31" />
+ <text
+ type="string"
+ clip_partial="false"
+ follows="left|top|right"
+ layout="topleft"
+ left="15"
+ right="-15"
+ name="stub_textbox"
+ top="25"
+ height="40"
+ valign="center"
+ parse_urls="true"
+ wrap="true">
+ This conversation is in a separate window. [secondlife:/// Bring it back.]
+ </text>
+ </panel>
+ </panel_container>
+ </layout_panel>
+ </layout_stack>
</multi_floater>
diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml
index ca73883e53..43d0f2fb18 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_session.xml
@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<floater
- legacy_header_height="18"
background_visible="true"
default_tab_group="1"
height="355"
@@ -10,82 +9,302 @@
can_dock="false"
can_minimize="true"
can_close="true"
+ save_rect="true"
visible="false"
width="394"
can_resize="true"
- min_width="250"
- min_height="190">
- <layout_stack
- animate="true"
- default_tab_group="2"
- follows="all"
- height="320"
- width="394"
- layout="topleft"
- orientation="horizontal"
- name="im_panels"
- tab_group="1"
- top="20"
- left="0">
- <layout_panel
- name="im_control_panel_holder"
- min_width="115"
- width="150"
- height="320"
- auto_resize="false">
- <panel
- name="panel_im_control_panel"
- layout="topleft"
- height="320"
- width="150"
- follows="all"/>
- </layout_panel>
- <layout_panel
- default_tab_group="3"
- left="0"
- tab_group="2"
- top="0"
- height="200"
- width="254"
- user_resize="true">
- <button
- height="20"
- follows="left|top"
- top="0"
- left="2"
- image_overlay="TabIcon_Open_Off"
- layout="topleft"
- width="25"
- name="slide_left_btn" />
- <button
- height="20"
- follows="left|top"
- top="0"
- left="2"
- image_overlay="TabIcon_Close_Off"
- width="25"
- name="slide_right_btn" />
- <chat_history
- font="SansSerifSmall"
- follows="left|right|top|bottom"
- height="150"
- name="chat_history"
- parse_highlights="true"
- parse_urls="true"
- left="1"
- width="249">
- </chat_history>
- <line_editor
- bottom="0"
- follows="left|right|bottom"
- font="SansSerifSmall"
- height="20"
- label="To"
- layout="bottomleft"
- name="chat_editor"
- tab_group="3"
- width="249">
- </line_editor>
- </layout_panel>
- </layout_stack>
+ can_tear_off="false"
+ min_height="190"
+ positioning="relative">
+ <floater.string name="call_btn_start">Conv_toolbar_open_call</floater.string>
+ <floater.string name="call_btn_stop">Conv_toolbar_hang_up</floater.string>
+ <floater.string
+ name="collapseline_icon"
+ value="Conv_collapse_to_one_line"/>
+ <floater.string
+ name="expandline_icon"
+ value="Conv_expand_one_line"/>
+ <floater.string
+ name="collapse_icon"
+ value="Conv_toolbar_collapse"/>
+ <floater.string
+ name="expand_icon"
+ value="Conv_toolbar_expand"/>
+ <floater.string
+ name="tear_off_icon"
+ value="Conv_toolbar_arrow_ne"/>
+ <floater.string
+ name="return_icon"
+ value="Conv_toolbar_arrow_sw"/>
+ <floater.string
+ name="participant_added"
+ value="[NAME] was invited to the conversation."/>
+ <floater.string
+ name="multiple_participants_added"
+ value="[NAME] were invited to the conversation."/>
+ <floater.string
+ name="tooltip_to_separate_window"
+ value="Move this conversation to a separate window"/>
+ <floater.string
+ name="tooltip_to_main_window"
+ value="Move this conversation back to main window"/>
+ <floater.string
+ name="start_call_button_tooltip"
+ value="Open voice connection"/>
+ <floater.string
+ name="end_call_button_tooltip"
+ value="Close voice connection"/>
+ <floater.string
+ name="expcol_button_not_tearoff_tooltip"
+ value="Collapse this pane"/>
+ <floater.string
+ name="expcol_button_tearoff_and_expanded_tooltip"
+ value="Collapse participant list"/>
+ <floater.string
+ name="expcol_button_tearoff_and_collapsed_tooltip"
+ value="Expand participant list"/>
+ <view
+ follows="all"
+ layout="topleft"
+ name="contents_view"
+ top="0"
+ left="0"
+ right="-1"
+ bottom="-1">
+ <layout_stack
+ animate="false"
+ bottom="-1"
+ default_tab_group="2"
+ follows="all"
+ left="3"
+ layout="topleft"
+ name="main_stack"
+ right="-3"
+ orientation="vertical"
+ tab_group="1"
+ top="0">
+ <layout_panel
+ auto_resize="false"
+ name="toolbar_panel"
+ height="25">
+ <menu_button
+ menu_filename="menu_im_session_showmodes.xml"
+ follows="top|left"
+ height="25"
+ image_hover_unselected="Toolbar_Middle_Over"
+ image_overlay="Conv_toolbar_sort"
+ image_selected="Toolbar_Middle_Selected"
+ image_unselected="Toolbar_Middle_Off"
+ layout="topleft"
+ left="5"
+ name="view_options_btn"
+ tool_tip="View/sort options"
+ top="1"
+ width="31" />
+ <menu_button
+ menu_filename="menu_im_conversation.xml"
+ follows="top|left"
+ height="25"
+ image_hover_unselected="Toolbar_Middle_Over"
+ image_overlay="OptionsMenu_Off"
+ image_selected="Toolbar_Middle_Selected"
+ image_unselected="Toolbar_Middle_Off"
+ layout="topleft"
+ top="1"
+ left_pad="2"
+ name="gear_btn"
+ visible="false"
+ tool_tip="Actions on selected person"
+ width="31"/>
+ <button
+ enabled="false"
+ follows="top|left"
+ height="25"
+ image_hover_unselected="Toolbar_Middle_Over"
+ image_overlay="Conv_toolbar_add_person"
+ image_selected="Toolbar_Middle_Selected"
+ image_unselected="Toolbar_Middle_Off"
+ layout="topleft"
+ top="1"
+ left_pad="2"
+ name="add_btn"
+ tool_tip="Add someone to this conversation"
+ width="31"/>
+ <button
+ follows="top|left"
+ height="25"
+ image_hover_unselected="Toolbar_Middle_Over"
+ image_overlay="Conv_toolbar_open_call"
+ image_selected="Toolbar_Middle_Selected"
+ image_unselected="Toolbar_Middle_Off"
+ layout="topleft"
+ top="1"
+ left_pad="2"
+ name="voice_call_btn"
+ tool_tip="Open voice connection"
+ width="31"/>
+ <button
+ follows="right|top"
+ height="25"
+ image_hover_unselected="Toolbar_Middle_Over"
+ image_overlay="Conv_toolbar_close"
+ image_selected="Toolbar_Middle_Selected"
+ image_unselected="Toolbar_Middle_Off"
+ layout="topleft"
+ top="1"
+ right="-70"
+ name="close_btn"
+ tool_tip="End this conversation"
+ width="31" />
+ <button
+ follows="right|top"
+ height="25"
+ image_hover_unselected="Toolbar_Middle_Over"
+ image_overlay="Conv_toolbar_collapse"
+ image_selected="Toolbar_Middle_Selected"
+ image_unselected="Toolbar_Middle_Off"
+ layout="topleft"
+ top="1"
+ left_pad="2"
+ name="expand_collapse_btn"
+ tool_tip="Collapse/Expand this pane"
+ width="31" />
+ <button
+ follows="right|top"
+ height="25"
+ image_hover_unselected="Toolbar_Middle_Over"
+ image_overlay="Conv_toolbar_arrow_ne"
+ image_selected="Toolbar_Middle_Selected"
+ image_unselected="Toolbar_Middle_Off"
+ layout="topleft"
+ left_pad="2"
+ name="tear_off_btn"
+ top="1"
+ width="31" />
+ </layout_panel>
+ <layout_panel
+ name="body_panel"
+ height="235">
+ <layout_stack
+ default_tab_group="2"
+ drag_handle_gap="6"
+ drag_handle_first_indent="0"
+ drag_handle_second_indent="1"
+ follows="all"
+ orientation="horizontal"
+ name="im_panels"
+ show_drag_handle="true"
+ tab_group="1"
+ top="0"
+ right="-1"
+ bottom="-1"
+ left="0">
+ <layout_panel
+ name="speakers_list_panel"
+ expanded_min_dim="115"
+ min_dim="0"
+ width="150"
+ user_resize="true"
+ auto_resize="false" />
+ <layout_panel
+ default_tab_group="3"
+ tab_group="2"
+ name="right_part_holder"
+ min_width="172">
+ <layout_stack
+ animate="true"
+ default_tab_group="2"
+ follows="all"
+ orientation="vertical"
+ name="translate_and_chat_stack"
+ tab_group="1"
+ top="0"
+ left="1"
+ right="-1"
+ bottom="-1">
+ <layout_panel
+ auto_resize="false"
+ height="26"
+ name="translate_chat_checkbox_lp">
+ <check_box
+ top="10"
+ control_name="TranslateChat"
+ enabled="true"
+ height="16"
+ label="Translate chat"
+ left="5"
+ name="translate_chat_checkbox"
+ width="230" />
+ </layout_panel>
+ <layout_panel
+ name="chat_holder">
+ <chat_history
+ font="SansSerifSmall"
+ follows="all"
+ name="chat_history"
+ parse_highlights="true"
+ parse_urls="true"
+ right="-1"
+ left="0"
+ top="0"
+ bottom="-1" />
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ <layout_panel
+ height="35"
+ auto_resize="false"
+ name="chat_layout_panel">
+ <layout_stack
+ animate="false"
+ default_tab_group="2"
+ follows="all"
+ orientation="horizontal"
+ name="input_panels"
+ top="0"
+ bottom="-1"
+ left="0"
+ right="-1">
+ <layout_panel
+ name="input_editor_layout_panel">
+ <chat_editor
+ layout="topleft"
+ expand_lines_count="5"
+ follows="left|right|bottom"
+ font="SansSerifSmall"
+ height="20"
+ is_expandable="true"
+ text_tentative_color="TextFgTentativeColor"
+ name="chat_editor"
+ max_length="1023"
+ spellcheck="true"
+ tab_group="3"
+ bottom="-8"
+ left="5"
+ right="-5"
+ wrap="true" />
+ </layout_panel>
+ <layout_panel
+ auto_resize="false"
+ name="input_button_layout_panel"
+ width="32">
+ <button
+ left="1"
+ top="4"
+ height="25"
+ follows="left|right|top"
+ image_hover_unselected="Toolbar_Middle_Over"
+ image_overlay="Conv_expand_one_line"
+ image_selected="Toolbar_Middle_Selected"
+ image_unselected="Toolbar_Middle_Off"
+ name="minz_btn"
+ tool_tip="Shows/hides message panel"
+ width="28" />
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
+ </view>
</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_image_preview.xml b/indra/newview/skins/default/xui/en/floater_image_preview.xml
index 44d2c14cc8..44d2c14cc8 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_image_preview.xml
+++ b/indra/newview/skins/default/xui/en/floater_image_preview.xml
diff --git a/indra/newview/skins/default/xui/en/floater_import_collada.xml b/indra/newview/skins/default/xui/en/floater_import_collada.xml
index 441ab6a2de..441ab6a2de 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_import_collada.xml
+++ b/indra/newview/skins/default/xui/en/floater_import_collada.xml
diff --git a/indra/newview/skins/default/xui/en/floater_incoming_call.xml b/indra/newview/skins/default/xui/en/floater_incoming_call.xml
index 81194f61cf..a7864381a9 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_incoming_call.xml
+++ b/indra/newview/skins/default/xui/en/floater_incoming_call.xml
@@ -8,8 +8,8 @@
layout="topleft"
name="incoming call"
help_topic="incoming_call"
- title="Incoming call"
- width="410">
+ sound_flags="0"
+ width="550">
<floater.string
name="lifetime">
5
@@ -24,7 +24,7 @@
</floater.string>
<floater.string
name="VoiceInviteP2P">
- is calling.
+ is calling you.
</floater.string>
<floater.string
name="VoiceInviteAdHoc">
@@ -49,14 +49,14 @@
image_name="icon_avatar_online.tga"
layout="topleft"
left_delta="19"
- top="35"
+ top="20"
width="36" />
<group_icon
enabled="false"
follows="left|top"
height="36"
layout="topleft"
- top="35"
+ top="20"
width="36" />
<text
clip_partial="true"
@@ -67,43 +67,43 @@
name="caller name"
top="20"
use_ellipses="true"
- width="315"
+ width="475"
word_wrap="true" />
- <text
- clip_partial="true"
- font="SansSerif"
- height="30"
- layout="topleft"
- left="77"
- name="question"
- top_pad="5"
- use_ellipses="true"
- width="315"
- word_wrap="true">
- Do you want to leave [CURRENT_CHAT] and join this voice chat?
- </text>
- <button
+ <button
height="24"
- label="Accept"
- label_selected="Accept"
+ label="Answer"
+ label_selected="Answer"
layout="topleft"
left="70"
name="Accept"
- top="92"
- width="100" />
+ top_pad="5"
+ width="120" />
<button
height="24"
- label="Reject"
- label_selected="Reject"
+ label="Ignore"
+ label_selected="Ignore"
layout="topleft"
name="Reject"
left_pad="10"
- width="100" />
+ width="120" />
<button
height="24"
- label="Start IM"
+ label="Open IM instead"
layout="topleft"
name="Start IM"
left_pad="10"
- width="100" />
+ width="120" />
+ <text
+ clip_partial="true"
+ font="SansSerif"
+ height="30"
+ layout="topleft"
+ left="77"
+ name="question"
+ top_pad="5"
+ use_ellipses="true"
+ width="475"
+ word_wrap="true">
+ If you answer, you will be disconnected from your current voice conversation.
+ </text>
</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_inspect.xml b/indra/newview/skins/default/xui/en/floater_inspect.xml
index bea35e5fc1..bea35e5fc1 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_inspect.xml
+++ b/indra/newview/skins/default/xui/en/floater_inspect.xml
diff --git a/indra/newview/skins/default/xui/en/floater_inventory_item_properties.xml b/indra/newview/skins/default/xui/en/floater_inventory_item_properties.xml
index adef066aef..adef066aef 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_inventory_item_properties.xml
+++ b/indra/newview/skins/default/xui/en/floater_inventory_item_properties.xml
diff --git a/indra/newview/skins/default/xui/en/floater_inventory_view_finder.xml b/indra/newview/skins/default/xui/en/floater_inventory_view_finder.xml
index c86ed595a7..c86ed595a7 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_inventory_view_finder.xml
+++ b/indra/newview/skins/default/xui/en/floater_inventory_view_finder.xml
diff --git a/indra/newview/skins/default/xui/en/floater_joystick.xml b/indra/newview/skins/default/xui/en/floater_joystick.xml
index 59f6a9434c..59f6a9434c 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_joystick.xml
+++ b/indra/newview/skins/default/xui/en/floater_joystick.xml
diff --git a/indra/newview/skins/default/xui/en/floater_lagmeter.xml b/indra/newview/skins/default/xui/en/floater_lagmeter.xml
index b24c745bdd..b24c745bdd 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_lagmeter.xml
+++ b/indra/newview/skins/default/xui/en/floater_lagmeter.xml
diff --git a/indra/newview/skins/default/xui/en/floater_land_holdings.xml b/indra/newview/skins/default/xui/en/floater_land_holdings.xml
index 390ec9ab7d..390ec9ab7d 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_land_holdings.xml
+++ b/indra/newview/skins/default/xui/en/floater_land_holdings.xml
diff --git a/indra/newview/skins/default/xui/en/floater_live_lsleditor.xml b/indra/newview/skins/default/xui/en/floater_live_lsleditor.xml
index 5cd7cd196d..5cd7cd196d 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_live_lsleditor.xml
+++ b/indra/newview/skins/default/xui/en/floater_live_lsleditor.xml
diff --git a/indra/newview/skins/default/xui/en/floater_lsl_guide.xml b/indra/newview/skins/default/xui/en/floater_lsl_guide.xml
index e9676777f4..e9676777f4 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_lsl_guide.xml
+++ b/indra/newview/skins/default/xui/en/floater_lsl_guide.xml
diff --git a/indra/newview/skins/default/xui/en/floater_map.xml b/indra/newview/skins/default/xui/en/floater_map.xml
index b8893e11d9..b8893e11d9 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_map.xml
+++ b/indra/newview/skins/default/xui/en/floater_map.xml
diff --git a/indra/newview/skins/default/xui/en/floater_media_browser.xml b/indra/newview/skins/default/xui/en/floater_media_browser.xml
index ce788654aa..ce788654aa 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_media_browser.xml
+++ b/indra/newview/skins/default/xui/en/floater_media_browser.xml
diff --git a/indra/newview/skins/default/xui/en/floater_media_settings.xml b/indra/newview/skins/default/xui/en/floater_media_settings.xml
index 0e03c0ab6d..0e03c0ab6d 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_media_settings.xml
+++ b/indra/newview/skins/default/xui/en/floater_media_settings.xml
diff --git a/indra/newview/skins/default/xui/en/floater_mem_leaking.xml b/indra/newview/skins/default/xui/en/floater_mem_leaking.xml
index fb7d09a21e..fb7d09a21e 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_mem_leaking.xml
+++ b/indra/newview/skins/default/xui/en/floater_mem_leaking.xml
diff --git a/indra/newview/skins/default/xui/en/floater_merchant_outbox.xml b/indra/newview/skins/default/xui/en/floater_merchant_outbox.xml
index b98f280b56..b98f280b56 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_merchant_outbox.xml
+++ b/indra/newview/skins/default/xui/en/floater_merchant_outbox.xml
diff --git a/indra/newview/skins/default/xui/en/floater_model_preview.xml b/indra/newview/skins/default/xui/en/floater_model_preview.xml
index 0e211551e6..5e92a12251 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_model_preview.xml
+++ b/indra/newview/skins/default/xui/en/floater_model_preview.xml
@@ -1,8 +1,16 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<floater can_close="true" can_drag_on_left="false" can_minimize="false"
- can_resize="false" height="480" min_height="480" min_width="940"
- name="Model Preview" title="UPLOAD MODEL" width="940"
- help_topic="upload_model" >
+<floater
+ can_close="true"
+ can_drag_on_left="false"
+ can_minimize="false"
+ can_resize="false"
+ height="480"
+ min_height="480"
+ width="980"
+ min_width="980"
+ name="Model Preview"
+ title="UPLOAD MODEL"
+ help_topic="upload_model" >
<string name="status_idle"></string>
<string name="status_parse_error">Error: Dae parsing issue - see log for details.</string>
@@ -98,7 +106,7 @@
top_pad="15"
left="0"
height="300"
- width="625"
+ width="635"
name="import_tab"
tab_position="top">
<!-- LOD PANEL -->
@@ -116,13 +124,13 @@
left="3"
name="lod_tab_border"
top_pad="0"
- width="619" />
+ width="629" />
<text
follows="left|top"
height="18"
initial_value="Source"
layout="topleft"
- left="75"
+ left="85"
name="source"
text_color="ModelUploaderLabels"
top="15"
@@ -165,7 +173,7 @@
top_pad="10"
valign="top"
value="High"
- width="65" />
+ width="75" />
<combo_box
follows="top|left"
height="20"
@@ -175,10 +183,10 @@
top_delta="-3"
width="135">
<item
- id="Load from file"
+ name="Load from file"
value="Load from file" />
<item
- id="Generate"
+ name="Generate"
value="Generate" />
</combo_box>
<line_editor
@@ -210,10 +218,10 @@
visible="false"
width="135">
<item
- id="Triangle Limit"
+ name="Triangle Limit"
value="Triangle Limit" />
<item
- id="Error Threshold"
+ name="Error Threshold"
value="Error Threshold" />
</combo_box>
<spinner
@@ -290,7 +298,7 @@
top_pad="15"
valign="top"
value="Medium"
- width="65" />
+ width="75" />
<combo_box
follows="top|left"
height="20"
@@ -300,13 +308,13 @@
top_delta="-3"
width="135">
<item
- id="Load from file"
+ name="Load from file"
value="Load from file" />
<item
- id="Generate"
+ name="Generate"
value="Generate" />
<item
- id="Use LoD above"
+ name="Use LoD above"
value="Use LoD above" />
</combo_box>
<line_editor
@@ -339,10 +347,10 @@
top_delta="0"
width="135">
<item
- id="Triangle Limit"
+ name="Triangle Limit"
value="Triangle Limit" />
<item
- id="Error Threshold"
+ name="Error Threshold"
value="Error Threshold" />
</combo_box>
<spinner
@@ -418,7 +426,7 @@
top_pad="15"
valign="top"
value="Low"
- width="65" />
+ width="75" />
<combo_box
follows="top|left"
height="20"
@@ -428,13 +436,13 @@
top_delta="-3"
width="135">
<item
- id="Load from file"
+ name="Load from file"
value="Load from file" />
<item
- id="Generate"
+ name="Generate"
value="Generate" />
<item
- id="Use LoD above"
+ name="Use LoD above"
value="Use LoD above" />
</combo_box>
<line_editor
@@ -467,10 +475,10 @@
top_delta="0"
width="135">
<item
- id="Triangle Limit"
+ name="Triangle Limit"
value="Triangle Limit" />
<item
- id="Error Threshold"
+ name="Error Threshold"
value="Error Threshold" />
</combo_box>
<spinner
@@ -546,7 +554,7 @@
top_pad="15"
valign="top"
value="Lowest"
- width="65" />
+ width="75" />
<combo_box
follows="top|left"
height="20"
@@ -556,13 +564,13 @@
top_delta="-3"
width="135">
<item
- id="Load from file"
+ name="Load from file"
value="Load from file" />
<item
- id="Generate"
+ name="Generate"
value="Generate" />
<item
- id="Use LoD above"
+ name="Use LoD above"
value="Use LoD above" />
</combo_box>
<line_editor
@@ -595,10 +603,10 @@
top_delta="0"
width="135">
<item
- id="Triangle Limit"
+ name="Triangle Limit"
value="Triangle Limit" />
<item
- id="Error Threshold"
+ name="Error Threshold"
value="Error Threshold" />
</combo_box>
<spinner
@@ -1201,7 +1209,7 @@
name="calculate_btn"
top="3"
height="20"
- width="150"
+ width="165"
tool_tip="Calculate weights &amp;fee"/>
<button
follows="top|left"
@@ -1234,7 +1242,7 @@
right="-2"
top="3"
height="20"
- width="155"/>
+ width="275"/>
<!-- ========== WEIGHTS ==========-->
<text
follows="top|left"
@@ -1343,7 +1351,7 @@
layout="topleft"
name="right_panel"
top_pad="5"
- width="290">
+ width="340">
<combo_box
top_pad="3"
follows="left|top"
diff --git a/indra/newview/skins/default/xui/en/floater_model_wizard.xml b/indra/newview/skins/default/xui/en/floater_model_wizard.xml
deleted file mode 100644
index 62b8c5f96e..0000000000
--- a/indra/newview/skins/default/xui/en/floater_model_wizard.xml
+++ /dev/null
@@ -1,841 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<floater
- legacy_header_height="18"
- layout="topleft"
- name="Model Wizard"
- help_topic="model_wizard"
- bg_opaque_image_overlay="0.5 0.5 0.5 1"
- height="480"
- save_rect="true"
- title="UPLOAD MODEL WIZARD"
- width="535">
- <button
- top="32"
- tab_stop="false"
- left="410"
- height="32"
- name="upload_btn"
- enabled="false"
- label="5. Upload"
- border="false"
- image_unselected="BreadCrumbBtn_Right_Off"
- image_selected="BreadCrumbBtn_Right_Press"
- image_hover_unselected="BreadCrumbBtn_Right_Over"
- image_disabled="BreadCrumbBtn_Right_Disabled"
- image_disabled_selected="BreadCrumbBtn_Right_Disabled"
- width="110">
- <button.commit_callback
- function="Wizard.Upload"/>
- </button>
- <button
- top="32"
- left="310"
- height="32"
- tab_stop="false"
- name="review_btn"
- label="4. Review"
- enabled="false"
- border="false"
- image_unselected="BreadCrumbBtn_Middle_Off"
- image_selected="BreadCrumbBtn_Middle_Press"
- image_hover_unselected="BreadCrumbBtn_Middle_Over"
- image_disabled="BreadCrumbBtn_Middle_Disabled"
- image_disabled_selected="BreadCrumbBtn_Middle_Disabled"
- width="110">
- <button.commit_callback
- function="Wizard.Review"/>
- </button>
- <button
- top="32"
- left="210"
- height="32"
- name="physics_btn"
- label="3. Physics"
- tab_stop="false"
- enabled="false"
- border="false"
- image_unselected="BreadCrumbBtn_Middle_Off"
- image_selected="BreadCrumbBtn_Middle_Press"
- image_hover_unselected="BreadCrumbBtn_Middle_Over"
- image_disabled="BreadCrumbBtn_Middle_Disabled"
- image_disabled_selected="BreadCrumbBtn_Middle_Disabled"
- width="110">
- <button.commit_callback
- function="Wizard.Physics"/>
- </button>
- <button
- top="32"
- left="115"
- name="optimize_btn"
- label="2. Optimize"
- tab_stop="false"
- height="32"
- border="false"
- image_unselected="BreadCrumbBtn_Middle_Off"
- image_selected="BreadCrumbBtn_Middle_Press"
- image_hover_unselected="BreadCrumbBtn_Middle_Over"
- image_disabled="BreadCrumbBtn_Middle_Disabled"
- image_disabled_selected="BreadCrumbBtn_Middle_Disabled"
- width="110">
- <button.commit_callback
- function="Wizard.Optimize"/>
- </button>
- <button
- top="32"
- left="15"
- name="choose_file_btn"
- tab_stop="false"
- enabled="false"
- label="1. Choose File"
- height="32"
- image_unselected="BreadCrumbBtn_Left_Off"
- image_selected="BreadCrumbBtn_Left_Press"
- image_hover_unselected="BreadCrumbBtn_Left_Over"
- image_disabled="BreadCrumbBtn_Left_Disabled"
- image_disabled_selected="BreadCrumbBtn_Left_Disabled"
- width="110">
- <button.commit_callback
- function="Wizard.Choose"/>
- </button>
- <panel
- height="388"
- top_pad="0"
- name="choose_file_panel"
- visible="false"
- width="535"
- left="0">
- <panel
- height="22"
- top_pad="15"
- width="505"
- name="choose_file_header_panel"
- bg_opaque_color="DkGray2"
- background_visible="true"
- background_opaque="true"
- left="15">
- <text
- width="200"
- left="10"
- top="3"
- name="choose_file_header_text"
- text_color="White"
- height="10"
- font="SansSerifBig"
- layout="topleft">
- Choose model file
- </text>
- </panel>
- <panel
- top_pad="14"
- left="15"
- height="310"
- width="505"
- name="choose_file_content"
- bg_opaque_color="DkGray2"
- background_visible="true"
- background_opaque="true">
- <text
- height="32"
- left="10"
- name="advanced_users_text"
- text_color="White"
- top="15"
- width="320"
- word_wrap="true">
- Advanced users: If you are familiar with 3D content creation tools you may wish to use the Advanced Uploader.
- </text>
- <button
- follows="left|top"
- height="20"
- label="Switch to Advanced"
- layout="topleft"
- left_delta="0"
- name="switch_to_advanced"
- top_pad="5"
- width="130">
- </button>
- <text
- type="string"
- length="1"
- text_color="White"
- follows="left|top"
- top_pad="30"
- height="10"
- layout="topleft"
- left_delta="0"
- name="Cache location"
- width="320">
- Choose model file to upload
- </text>
- <line_editor
- border_style="line"
- border_thickness="1"
- follows="left|top"
- font="SansSerifSmall"
- height="20"
- layout="topleft"
- left_delta="0"
- max_length="4096"
- name="lod_file"
- top_pad="5"
- width="230" />
- <button
- follows="left|top"
- height="23"
- label="Browse..."
- label_selected="Browse..."
- layout="topleft"
- left_pad="5"
- name="browse"
- top_delta="-1"
- width="85">
- </button>
- <text
- type="string"
- length="1"
- text_color="White"
- follows="left|top"
- top_pad="5"
- height="10"
- layout="topleft"
- left="10"
- name="Model types"
- width="320">
- Second Life supports COLLADA (.dae) files
- </text>
- <!-- Placeholder panel for 3D preview render -->
- <panel
- top="30"
- right="-10"
- name="choose_file_preview_panel"
- bevel_style="none"
- highlight_light_color="0.09 0.09 0.09 1"
- border="true"
- border_style="line"
- height="150"
- follows="all"
- width="150">
- </panel>
- <text
- top_pad="10"
- width="130"
- height="14"
- left_delta="0"
- text_color="White"
- word_wrap="true">
- Dimensions (meters):
- </text>
- <text
- top_pad="0"
- width="160"
- height="15"
- font="SansSerifSmallBold"
- text_color="White"
- name="dimensions"
- left_delta="0">
- X Y Z
- </text>
- <text
- top_delta="0"
- width="160"
- height="15"
- name="dimension_x"
- left="356"/>
- <text
- top_delta="0"
- width="160"
- height="15"
- name="dimension_y"
- left="403"/>
- <text
- top_delta="0"
- width="160"
- height="15"
- name="dimension_z"
- left="450"/>
- <text
- height="16"
- left="10"
- name="warning_label"
- text_color="Yellow"
- top="200"
- visible="false"
- width="320">
- WARNING:
- </text>
- <text
- height="50"
- left="10"
- name="warning_text"
- top_pad="0"
- visible="false"
- width="320"
- word_wrap="true">
- You will not be able to complete the final step of uploading this model to the Second Life servers. [secondlife:///app/floater/learn_more Find out how] to set up your account for mesh model uploads.
- </text>
- </panel>
- </panel>
-
-
- <panel
- height="388"
- top_delta="0"
- name="optimize_panel"
- visible="true"
- width="535"
- left="0">
- <panel
- height="22"
- top_pad="15"
- name="optimize_header_panel"
- width="505"
- bg_opaque_color="DkGray2"
- background_visible="true"
- background_opaque="true"
- left="15">
- <text
- width="200"
- left="10"
- name="optimize_header_text"
- top="3"
- text_color="White"
- height="10"
- font="SansSerifBig"
- layout="topleft">
- Optimize model
- </text>
- </panel>
- <text
- top_pad="14"
- width="460"
- height="20"
- font="SansSerifSmall"
- layout="topleft"
- name="optimize_description"
- word_wrap="true"
- left_delta="5">
- We have optimized the model for performance. Adjust it further if you wish.
- </text>
- <panel
- top_delta="40"
- visible="false"
- left="15"
- height="270"
- width="505"
- name="optimize_content"
- bg_opaque_color="DkGray2"
- background_visible="true"
- background_opaque="true">
- <text
- top="20"
- width="300"
- height="12"
- font="SansSerifBold"
- left="112">Generating Level of Detail</text>
- <progress_bar
- name="optimize_progress_bar"
- image_fill="model_wizard\progress_light.png"
- color_bg="1 1 1 1"
- color_bar="1 1 1 0.96"
- follows="left|right|top"
- width="260"
- height="16"
- image_bar="model_wizard\progress_bar_bg.png"
- top_pad="14"
- left="110"/>
- <icon
- top_pad="10"
- left_delta="0"
- width="13"
- height="12"
- image_name="model_wizard\check_mark.png"/>
- <text
- top_delta="0"
- left_delta="18"
- name="high_detail_text"
- width="200"
- height="14">Generate Level of Detail: High</text>
- <icon
- top_pad="10"
- left_delta="-18"
- width="13"
- height="12"
- image_name="model_wizard\check_mark.png"/>
- <text
- top_delta="0"
- left_delta="18"
- name="medium_detail_text"
- width="200"
- height="14">Generate Level of Detail: Medium</text>
- <icon
- top_pad="10"
- left_delta="-18"
- width="13"
- height="12"
- image_name="model_wizard\check_mark.png"/>
- <text
- top_delta="0"
- left_delta="18"
- name="low_detail_text"
- width="200"
- height="14">Generate Level of Detail: Low</text>
- <icon
- top_pad="10"
- left_delta="-18"
- width="13"
- height="12"
- image_name="model_wizard\check_mark.png"/>
- <text
- top_delta="0"
- left_delta="18"
- name="lowest_detail_text"
- width="200"
- height="14">Generate Level of Detail: Lowest</text>
- </panel>
- <panel
- top_delta="0"
- left_delta="0"
- height="270"
- width="505"
- name="content2"
- bg_opaque_color="DkGray2"
- background_visible="true"
- background_opaque="true">
- <text top="69" left="10" text_color="White" font="SansSerifSmallBold" width="120" height="16" wrap="true">Performance</text>
- <text top="85" left="10" width="120" word_wrap="true" font="SansSerifSmall" height="40">Faster rendering
-Less detail
-Lower prim weight</text>
- <text top="69" left="184" text_color="White" font="SansSerifSmallBold" width="120" height="16" wrap="true">Accuracy</text>
- <text top="85" left="184" width="120" word_wrap="true" font="SansSerifSmall" height="40">Slower rendering
-More detail
-Higher prim weight</text>
-
- <slider
- follows="left|top"
- height="20"
- increment="1"
- layout="topleft"
- left="10"
- max_val="2"
- initial_value="1"
- min_val="0"
- name="accuracy_slider"
- show_text="false"
- top="130"
- width="290" />
- <text
- font="SansSerifSmall"
- top_pad="0"
- width="5"
- left_delta="6"
- height="4">'
- </text>
- <text
- font="SansSerifSmall"
- top_delta="0"
- width="5"
- left_delta="137"
- height="4">'
- </text>
- <text
- font="SansSerifSmall"
- top_delta="0"
- width="5"
- left_delta="137"
- height="4">'
- </text>
- <button
- follows="left|top"
- height="20"
- label="Recalculate Geometry"
- layout="topleft"
- left="80"
- name="recalculate_geometry_btn"
- top_pad="15"
- width="150">
- </button>
- <text top="10" right="-10" width="185" text_color="White" follows="left|top" height="15" name="lod_label">
- Geometry preview
- </text>
- <panel
- right="-10"
- top="32"
- name="optimize_preview_panel"
- bevel_style="none"
- highlight_light_color="0.09 0.09 0.09 1"
- border_style="line"
- border="true"
- height="185"
- follows="all"
- width="185">
- </panel>
- <combo_box left_delta="75" top_pad="10" follows="left|top" list_position="below" height="22"
- name="preview_lod_combo" width="110" tool_tip="LOD to view in preview render">
- <combo_item name="high">
- High detail
- </combo_item>
- <combo_item name="medium">
- Medium detail
- </combo_item>
- <combo_item name="low">
- Low detail
- </combo_item>
- <combo_item name="lowest">
- Lowest detail
- </combo_item>
- </combo_box>
- </panel>
- </panel>
-
- <panel
- height="388"
- top_delta="0"
- name="physics_panel"
- visible="false"
- width="535"
- left="0">
- <panel
- height="22"
- top_pad="15"
- name="physics_header_panel"
- width="505"
- bg_opaque_color="DkGray2"
- background_visible="true"
- background_opaque="true"
- left="15">
- <text
- width="200"
- left="10"
- name="physics_header_text"
- top="3"
- height="10"
- font="SansSerifBig"
- text_color="White"
- layout="topleft">
- Adjust physics
- </text>
- </panel>
- <text
- top_pad="10"
- width="474"
- height="50"
- font="SansSerifSmall"
- layout="topleft"
- name="physics_description"
- word_wrap="true"
- left_delta="5">
- We will create a shape for the outer hull of the model. Adjust the shape's detail level as needed for the intended purpose of your model.
- </text>
- <panel
- top_delta="44"
- left="15"
- height="270"
- width="505"
- name="physics_content"
- bg_opaque_color="DkGray2"
- background_visible="true"
- background_opaque="true">
- <text top="10" left="10" text_color="White" font="SansSerifSmallBold" width="120" halign="right" height="16" wrap="true">Performance</text>
- <text top="26" left="10" width="120" word_wrap="true" font="SansSerifSmall" halign="right" height="40">Faster rendering
-Less detail
-Lower prim weight</text>
- <text top="174" left="10" text_color="White" font="SansSerifSmallBold" width="120" halign="right" height="16" wrap="true">Accuracy</text>
- <text top="190" left="10" width="120" word_wrap="true" font="SansSerifSmall" halign="right" height="40">Slower rendering
-More detail
-Higher prim weight</text>
-
- <slider
- follows="left|top"
- height="190"
- increment=".1"
- layout="topleft"
- left="140"
- max_val="1"
- initial_value="0.5"
- min_val="0"
- name="physics_slider"
- orientation="vertical"
- show_text="false"
- top="25"
- width="22" />
- <text top="10" width="120" word_wrap="true" left_pad="10" height="50">Examples:
-Moving objects
-Flying objects
-Vehicles</text>
- <text top="95" width="120" word_wrap="true" left_delta="0" height="50">Examples:
-Small static objects
-Less detailed objects
-Simple furniture</text>
- <text top="180" width="120" word_wrap="true" left_delta="0" height="50">Examples:
-Static objects
-Detailed objects
-Buildings</text>
- <button
- follows="left|top"
- height="20"
- label="Recalculate physics"
- layout="topleft"
- left="80"
- name="recalculate_physics_btn"
- top_pad="10"
- width="150">
- </button>
- <button
- enabled="false"
- follows="left|top"
- height="20"
- label="Recalculating..."
- layout="topleft"
- left_delta="0"
- name="recalculating_physics_btn"
- top_delta="0"
- visible="false"
- width="150">
- </button>
- <text top="10" right="-10" width="185" text_color="White" follows="left|top" height="15" name="lod_label">
- Physics preview
- </text>
- <panel
- right="-10"
- top="32"
- name="physics_preview_panel"
- bevel_style="none"
- highlight_light_color="0.09 0.09 0.09 1"
- border_style="line"
- border="true"
- height="185"
- follows="all"
- width="185">
- </panel>
- <combo_box left_delta="75" top_pad="10" follows="left|top" list_position="below" height="22"
- name="preview_lod_combo2" width="110" tool_tip="LOD to view in preview render">
- <combo_item name="high">
- High detail
- </combo_item>
- <combo_item name="medium">
- Medium detail
- </combo_item>
- <combo_item name="low">
- Low detail
- </combo_item>
- <combo_item name="lowest">
- Lowest detail
- </combo_item>
- </combo_box>
- </panel>
- </panel>
-
- <panel
- height="388"
- top_delta="0"
- name="review_panel"
- visible="false"
- width="535"
- left="0">
- <panel
- height="22"
- top_pad="15"
- name="review_header_panel"
- width="505"
- bg_opaque_color="DkGray2"
- background_visible="true"
- background_opaque="true"
- left="15">
- <text
- width="200"
- left="10"
- name="review_header_text"
- text_color="White"
- top="3"
- height="10"
- font="SansSerifBig"
- layout="topleft">
- Review
- </text>
- </panel>
- <panel
- top_pad="14"
- left="15"
- height="310"
- width="505"
- name="review_content"
- bg_opaque_color="DkGray2"
- background_visible="true"
- background_opaque="true">
- <text
- top="20"
- width="485"
- font="SansSerifMedium"
- text_color="White"
- left="10"
- name="review_prim_equiv"
- height="16">Impact to parcel/region: [EQUIV] prim equivalents
- </text>
- <text
- top_pad="20"
- width="485"
- font="SansSerifMedium"
- text_color="White"
- left="10"
- name="review_fee"
- height="16">Your account will be charged an upload fee of L$ [FEE].
- </text>
- <text
- top_pad="20"
- width="485"
- font="SansSerifMedium"
- text_color="White"
- left="10"
- name="review_confirmation"
- height="32"
- word_wrap="true">By clicking the upload button, you confirm that you have the appropriate rights to the material contained in the model.
- </text>
- </panel>
- </panel>
-
-
-
-
- <panel
- height="388"
- top_delta="0"
- name="upload_panel"
- visible="false"
- width="535"
- left="0">
- <panel
- height="22"
- top_pad="15"
- name="upload_header_panel"
- width="505"
- bg_opaque_color="DkGray2"
- background_visible="true"
- background_opaque="true"
- left="15">
- <text
- width="200"
- left="10"
- name="upload_header_text"
- top="3"
- text_color="White"
- height="10"
- font="SansSerifBig"
- layout="topleft">
- Upload complete
- </text>
- </panel>
- <text
- top_pad="14"
- width="495"
- height="16"
- font="SansSerifMedium"
- layout="topleft"
- name="model_uploaded_text"
- text_color="White"
- word_wrap="true"
- left="25">
- Your model has been uploaded.
- </text>
- <text
- top_pad="5"
- width="495"
- height="16"
- font="SansSerifMedium"
- layout="topleft"
- name="inventory_text"
- text_color="White"
- word_wrap="true"
- left="25">
- You will find it in the Objects folder in your inventory.
- </text>
- <text
- top_pad="20"
- width="495"
- font="SansSerifMedium"
- text_color="White"
- left="25"
- name="charged_fee"
- height="16">Your account has been charged L$ [FEE].
- </text>
- </panel>
-
-
-
- <button
- top="440"
- right="-285"
- width="90"
- height="22"
- name="back"
- label="&lt;&lt; Back" />
- <button
- top_delta="0"
- right="-190"
- width="90"
- height="22"
- name="next"
- label="Next &gt;&gt; " />
- <button
- top_delta="0"
- left_delta="0"
- width="160"
- height="22"
- name="calculate"
- label="Calculate weights &amp; fee &gt;&gt; " />
- <button
- enabled="false"
- visible="false"
- top_delta="0"
- left_delta="0"
- width="160"
- height="22"
- name="calculating"
- label="Calculating... " />
- <button
- enabled="false"
- top_delta="0"
- right="-150"
- width="90"
- height="22"
- visible="false"
- name="upload"
- tool_tip="Upload to simulator"
- label="Upload" />
- <button
- top_delta="0"
- right="-15"
- width="90"
- height="22"
- name="cancel"
- label="Cancel" />
- <button
- top_delta="0"
- right="-15"
- width="90"
- height="22"
- name="close"
- visible="false"
- label="Close" />
- <spinner visible="false" left="10" height="20" follows="top|left" width="80" top_pad="-50" value="1.0" min_val="0.01" max_val="64.0" name="import_scale"/>
-
- <string name="status_idle">Idle</string>
- <string name="status_parse_error">Dae parsing issue - see log for details.</string>
- <string name="status_reading_file">Loading...</string>
- <string name="status_generating_meshes">Generating Meshes...</string>
- <string name="status_vertex_number_overflow">Error: Vertex number is more than 65534, aborted!</string>
- <string name="bad_element">Error: element is invalid</string>
- <string name="high">High</string>
- <string name="medium">Medium</string>
- <string name="low">Low</string>
- <string name="lowest">Lowest</string>
- <string name="mesh_status_good">Ship it!</string>
- <string name="mesh_status_na">N/A</string>
- <string name="mesh_status_none">None</string>
- <string name="mesh_status_submesh_mismatch">Levels of detail have a different number of textureable faces.</string>
- <string name="mesh_status_mesh_mismatch">Levels of detail have a different number of mesh instances.</string>
- <string name="mesh_status_too_many_vertices">Level of detail has too many vertices.</string>
- <string name="mesh_status_missing_lod">Missing required level of detail.</string>
- <string name="layer_all">All</string>
- <!-- Text to display in physics layer combo box for "all layers" -->
-
-</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_moveview.xml b/indra/newview/skins/default/xui/en/floater_moveview.xml
index 4e7ee7913f..5e84283ab0 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_moveview.xml
+++ b/indra/newview/skins/default/xui/en/floater_moveview.xml
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<floater
positioning="specified"
- left="320"
- bottom="-80"
+ right="-693"
+ bottom="-50"
legacy_header_height="18"
can_dock="false"
can_minimize="true"
diff --git a/indra/newview/skins/default/xui/en/floater_mute_object.xml b/indra/newview/skins/default/xui/en/floater_mute_object.xml
index 22b0a1783f..22b0a1783f 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_mute_object.xml
+++ b/indra/newview/skins/default/xui/en/floater_mute_object.xml
diff --git a/indra/newview/skins/default/xui/en/floater_my_appearance.xml b/indra/newview/skins/default/xui/en/floater_my_appearance.xml
index fdea7a821a..fdea7a821a 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_my_appearance.xml
+++ b/indra/newview/skins/default/xui/en/floater_my_appearance.xml
diff --git a/indra/newview/skins/default/xui/en/floater_my_inventory.xml b/indra/newview/skins/default/xui/en/floater_my_inventory.xml
index 184f296255..178987962b 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_my_inventory.xml
+++ b/indra/newview/skins/default/xui/en/floater_my_inventory.xml
@@ -6,7 +6,7 @@
height="570"
help_topic="sidebar_inventory"
min_width="333"
- min_height="440"
+ min_height="570"
name="floater_my_inventory"
save_rect="true"
save_visibility="true"
diff --git a/indra/newview/skins/default/xui/en/floater_my_web_profile.xml b/indra/newview/skins/default/xui/en/floater_my_web_profile.xml
index df46fc198f..df46fc198f 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_my_web_profile.xml
+++ b/indra/newview/skins/default/xui/en/floater_my_web_profile.xml
diff --git a/indra/newview/skins/default/xui/en/floater_notification.xml b/indra/newview/skins/default/xui/en/floater_notification.xml
index 1f9ddecac2..1f9ddecac2 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_notification.xml
+++ b/indra/newview/skins/default/xui/en/floater_notification.xml
diff --git a/indra/newview/skins/default/xui/en/floater_notifications_console.xml b/indra/newview/skins/default/xui/en/floater_notifications_console.xml
index e243ccd2f9..e243ccd2f9 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_notifications_console.xml
+++ b/indra/newview/skins/default/xui/en/floater_notifications_console.xml
diff --git a/indra/newview/skins/default/xui/en/floater_object_weights.xml b/indra/newview/skins/default/xui/en/floater_object_weights.xml
index eb283a1043..eb283a1043 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_object_weights.xml
+++ b/indra/newview/skins/default/xui/en/floater_object_weights.xml
diff --git a/indra/newview/skins/default/xui/en/floater_openobject.xml b/indra/newview/skins/default/xui/en/floater_openobject.xml
index f526970ad0..f526970ad0 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_openobject.xml
+++ b/indra/newview/skins/default/xui/en/floater_openobject.xml
diff --git a/indra/newview/skins/default/xui/en/floater_outfit_save_as.xml b/indra/newview/skins/default/xui/en/floater_outfit_save_as.xml
index bbe280582b..bbe280582b 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_outfit_save_as.xml
+++ b/indra/newview/skins/default/xui/en/floater_outfit_save_as.xml
diff --git a/indra/newview/skins/default/xui/en/floater_outgoing_call.xml b/indra/newview/skins/default/xui/en/floater_outgoing_call.xml
index ffbb6aa28b..ffbb6aa28b 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_outgoing_call.xml
+++ b/indra/newview/skins/default/xui/en/floater_outgoing_call.xml
diff --git a/indra/newview/skins/default/xui/en/floater_pathfinding_characters.xml b/indra/newview/skins/default/xui/en/floater_pathfinding_characters.xml
new file mode 100755
index 0000000000..46ee113b69
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_pathfinding_characters.xml
@@ -0,0 +1,209 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ positioning="cascading"
+ can_resize="true"
+ can_tear_off="false"
+ height="273"
+ width="635"
+ min_height="273"
+ min_width="635"
+ layout="topleft"
+ name="floater_pathfinding_characters"
+ help_topic="floater_pathfinding_characters"
+ reuse_instance="true"
+ save_rect="false"
+ single_instance="true"
+ title="Pathfinding characters">
+ <floater.string name="messaging_initial"></floater.string>
+ <floater.string name="messaging_get_inprogress">Querying for pathfinding characters ...</floater.string>
+ <floater.string name="messaging_get_error">Error detected while querying for pathfinding characters.</floater.string>
+ <floater.string name="messaging_set_inprogress"></floater.string>
+ <floater.string name="messaging_set_error"></floater.string>
+ <floater.string name="messaging_complete_none_found">No pathfinding characters.</floater.string>
+ <floater.string name="messaging_complete_available">[NUM_SELECTED] characters selected out of [NUM_TOTAL].</floater.string>
+ <floater.string name="messaging_not_enabled">This region is not enabled for pathfinding.</floater.string>
+ <floater.string name="character_cpu_time">[CPU_TIME] µs</floater.string>
+ <floater.string name="character_owner_loading">[Loading]</floater.string>
+ <floater.string name="character_owner_unknown">[Unknown]</floater.string>
+ <floater.string name="character_owner_group">[group]</floater.string>
+ <panel
+ border="false"
+ bevel_style="none"
+ follows="left|top|right|bottom"
+ layout="topleft"
+ height="191"
+ width="635">
+ <scroll_list
+ column_padding="0"
+ draw_heading="true"
+ follows="all"
+ height="135"
+ layout="topleft"
+ left="18"
+ top_pad="10"
+ tab_stop="false"
+ multi_select="true"
+ name="objects_scroll_list"
+ width="600">
+ <scroll_list.columns
+ label="Name"
+ name="name"
+ dynamic_width="true" />
+ <scroll_list.columns
+ label="Description"
+ name="description"
+ width="172" />
+ <scroll_list.columns
+ label="Owner"
+ name="owner"
+ width="141" />
+ <scroll_list.columns
+ label="CPU"
+ name="cpu_time"
+ width="60" />
+ <scroll_list.columns
+ label="Altitude"
+ name="altitude"
+ width="64" />
+ </scroll_list>
+ <text
+ height="26"
+ word_wrap="true"
+ use_ellipses="false"
+ type="string"
+ text_color="LabelTextColor"
+ length="1"
+ follows="left|bottom|right"
+ layout="topleft"
+ name="messaging_status"
+ top_pad="17"
+ width="238">
+ Characters:
+ </text>
+ <button
+ follows="right|bottom"
+ height="21"
+ label="Refresh list"
+ layout="topleft"
+ name="refresh_objects_list"
+ top_pad="-29"
+ left_pad="0"
+ width="115"/>
+ <button
+ follows="right|bottom"
+ height="21"
+ label="Select all"
+ layout="topleft"
+ name="select_all_objects"
+ top_pad="-21"
+ left_pad="8"
+ width="115"/>
+ <button
+ follows="right|bottom"
+ height="21"
+ label="Select none"
+ layout="topleft"
+ name="select_none_objects"
+ top_pad="-21"
+ left_pad="8"
+ width="115"/>
+ </panel>
+ <view_border
+ bevel_style="none"
+ follows="left|right|bottom"
+ height="0"
+ layout="topleft"
+ name="horiz_separator"
+ top_pad="0"
+ left="18"
+ width="600"/>
+ <panel
+ border="false"
+ bevel_style="none"
+ follows="left|right|bottom"
+ layout="topleft"
+ left="0"
+ height="67"
+ width="635">
+ <text
+ height="13"
+ word_wrap="false"
+ use_ellipses="false"
+ type="string"
+ text_color="LabelTextColor"
+ text_readonly_color="LabelDisabledColor"
+ length="1"
+ follows="left|bottom|right"
+ layout="topleft"
+ name="actions_label"
+ left="18"
+ top_pad="8"
+ width="242">
+ Actions on selected characters:
+ </text>
+ <check_box
+ height="19"
+ follows="left|bottom"
+ label="Show beacon"
+ layout="topleft"
+ name="show_beacon"
+ top_pad="-16"
+ left_pad="0"
+ width="150" />
+ <check_box
+ height="19"
+ follows="left|bottom"
+ label="Show physics capsule"
+ layout="topleft"
+ name="show_physics_capsule"
+ top_pad="-19"
+ left_pad="0"
+ width="150" />
+ <button
+ follows="left|bottom"
+ height="22"
+ label="Take"
+ layout="topleft"
+ name="take_objects"
+ top_pad="9"
+ left="18"
+ width="94"/>
+ <button
+ follows="left|bottom"
+ height="22"
+ label="Take copy"
+ layout="topleft"
+ name="take_copy_objects"
+ top_pad="-22"
+ left_pad="6"
+ width="94"/>
+ <button
+ follows="left|bottom"
+ height="22"
+ label="Teleport me to it"
+ layout="topleft"
+ name="teleport_me_to_object"
+ tool_tip="Enabled only when one character is selected."
+ top_pad="-22"
+ left_pad="26"
+ width="159"/>
+ <button
+ follows="right|bottom"
+ height="22"
+ label="Return"
+ layout="topleft"
+ name="return_objects"
+ top_pad="-22"
+ left_pad="26"
+ width="94"/>
+ <button
+ follows="right|bottom"
+ height="22"
+ label="Delete"
+ layout="topleft"
+ name="delete_objects"
+ top_pad="-22"
+ left_pad="6"
+ width="94"/>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_pathfinding_console.xml b/indra/newview/skins/default/xui/en/floater_pathfinding_console.xml
new file mode 100755
index 0000000000..2629313069
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_pathfinding_console.xml
@@ -0,0 +1,419 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ positioning="cascading"
+ can_tear_off="false"
+ height="498"
+ layout="topleft"
+ name="floater_pathfinding_console"
+ help_topic="floater_pathfinding_console"
+ reuse_instance="true"
+ save_rect="true"
+ single_instance="true"
+ title="Pathfinding view / test"
+ width="240">
+ <floater.string name="navmesh_viewer_status_unknown"></floater.string>
+ <floater.string name="navmesh_viewer_status_library_not_implemented">Cannot find pathing library implementation.</floater.string>
+ <floater.string name="navmesh_viewer_status_region_not_enabled">This region is not enabled for pathfinding.</floater.string>
+ <floater.string name="navmesh_viewer_status_region_loading">Waiting for the region to finish loading.</floater.string>
+ <floater.string name="navmesh_viewer_status_checking_version">Checking the status of the navmesh.</floater.string>
+ <floater.string name="navmesh_viewer_status_downloading">Downloading the navmesh.</floater.string>
+ <floater.string name="navmesh_viewer_status_updating">The navmesh has changed on the server. Downloading the latest navmesh.</floater.string>
+ <floater.string name="navmesh_viewer_status_has_navmesh">Latest navmesh has been downloaded.</floater.string>
+ <floater.string name="navmesh_viewer_status_error">Unable to download navmesh successfully.</floater.string>
+ <floater.string name="navmesh_simulator_status_unknown"></floater.string>
+ <floater.string name="navmesh_simulator_status_pending">Navmesh has pending changes.</floater.string>
+ <floater.string name="navmesh_simulator_status_building">Navmesh is building.</floater.string>
+ <floater.string name="navmesh_simulator_status_some_pending">Some navmesh regions have pending changes.</floater.string>
+ <floater.string name="navmesh_simulator_status_some_building">Some navmesh regions are building.</floater.string>
+ <floater.string name="navmesh_simulator_status_pending_and_building">Some navmesh regions have pending changes and others are building.</floater.string>
+ <floater.string name="navmesh_simulator_status_complete">Navmesh is up-to-date.</floater.string>
+ <floater.string name="pathing_unknown"></floater.string>
+ <floater.string name="pathing_library_not_implemented">Cannot find pathing library implementation.</floater.string>
+ <floater.string name="pathing_region_not_enabled">This region is not enabled for pathfinding.</floater.string>
+ <floater.string name="pathing_choose_start_and_end_points">Please choose start and end points.</floater.string>
+ <floater.string name="pathing_choose_start_point">Please choose start point.</floater.string>
+ <floater.string name="pathing_choose_end_point">Please choose end point.</floater.string>
+ <floater.string name="pathing_path_valid">Path is shown in orange.</floater.string>
+ <floater.string name="pathing_path_invalid">A path between the chosen points cannot be found.</floater.string>
+ <floater.string name="pathing_error">An error occurred during path generation.</floater.string>
+ <panel
+ border="false"
+ bevel_style="none"
+ follows="left|top"
+ layout="topleft"
+ left="12"
+ top_pad="10"
+ height="61"
+ width="214">
+ <text
+ height="13"
+ word_wrap="true"
+ use_ellipses="false"
+ type="string"
+ text_color="LabelTextColor"
+ length="1"
+ layout="topleft"
+ left="0"
+ top_pad="0"
+ width="214">
+ Viewer status
+ </text>
+ <text
+ height="40"
+ word_wrap="true"
+ use_ellipses="false"
+ type="string"
+ text_color="PathfindingGoodColor"
+ length="1"
+ follows="left|top"
+ layout="topleft"
+ left="0"
+ name="pathfinding_viewer_status"
+ top_pad="8"
+ width="214">
+ </text>
+ </panel>
+ <panel
+ border="false"
+ bevel_style="none"
+ follows="left|top"
+ layout="topleft"
+ left="12"
+ height="66"
+ width="214">
+ <text
+ height="13"
+ word_wrap="true"
+ use_ellipses="false"
+ type="string"
+ text_color="LabelTextColor"
+ length="1"
+ layout="topleft"
+ left="0"
+ top_pad="5"
+ width="214">
+ Simulator status
+ </text>
+ <text
+ height="40"
+ word_wrap="true"
+ use_ellipses="false"
+ type="string"
+ text_color="PathfindingGoodColor"
+ length="1"
+ follows="left|top"
+ layout="topleft"
+ left="0"
+ name="pathfinding_simulator_status"
+ top_pad="8"
+ width="214">
+ </text>
+ </panel>
+ <view_border
+ bevel_style="none"
+ follows="top|left"
+ layout="topleft"
+ left="12"
+ top="179"
+ height="305"
+ width="213"
+ visible="true" />
+ <tab_container
+ follows="left|top"
+ layout="topleft"
+ tab_position="top"
+ name="view_test_tab_container"
+ left="12"
+ top="157"
+ height="328"
+ width="214">
+ <panel
+ border="false"
+ bevel_style="none"
+ follows="left|top"
+ layout="topleft"
+ name="view_panel"
+ label="View">
+ <text
+ height="13"
+ word_wrap="true"
+ use_ellipses="false"
+ type="string"
+ text_color="LabelTextColor"
+ text_readonly_color="LabelDisabledColor"
+ name="show_label"
+ length="1"
+ follows="left|top"
+ layout="topleft"
+ top_pad="20"
+ left="12"
+ width="200">
+ Show:
+ </text>
+ <check_box
+ height="19"
+ label="World"
+ layout="topleft"
+ name="show_world"
+ top_pad="4"
+ width="90" />
+ <check_box
+ height="19"
+ label="Movables only"
+ layout="topleft"
+ left="32"
+ name="show_world_movables_only"
+ top_pad="4"
+ width="90" />
+ <check_box
+ height="19"
+ label="Navmesh"
+ left="12"
+ layout="topleft"
+ name="show_navmesh"
+ top_pad="7"
+ width="90" />
+ <text
+ height="13"
+ word_wrap="true"
+ use_ellipses="false"
+ type="string"
+ text_color="LabelTextColor"
+ text_readonly_color="LabelDisabledColor"
+ name="show_walkability_label"
+ length="1"
+ follows="left|top"
+ layout="topleft"
+ left="32"
+ width="180">
+ Show walkability map:
+ </text>
+ <combo_box
+ height="19"
+ layout="topleft"
+ left="32"
+ name="show_heatmap_mode"
+ top_pad="8"
+ width="156">
+ <combo_box.item
+ label="Do not show"
+ name="show_heatmap_mode_none"
+ value="0" />
+ <combo_box.item
+ label="Character type A"
+ name="show_heatmap_mode_a"
+ value="1" />
+ <combo_box.item
+ label="Character type B"
+ name="show_heatmap_mode_b"
+ value="2" />
+ <combo_box.item
+ label="Character type C"
+ name="show_heatmap_mode_c"
+ value="3" />
+ <combo_box.item
+ label="Character type D"
+ name="show_heatmap_mode_d"
+ value="4" />
+ </combo_box>
+ <check_box
+ height="19"
+ label="Walkables"
+ layout="topleft"
+ left="12"
+ name="show_walkables"
+ top_pad="10"
+ width="90" />
+ <check_box
+ height="19"
+ label="Material volumes"
+ layout="topleft"
+ name="show_material_volumes"
+ top_pad="4"
+ width="90" />
+ <check_box
+ height="19"
+ label="Static obstacles"
+ layout="topleft"
+ name="show_static_obstacles"
+ top_pad="4"
+ width="90" />
+ <check_box
+ height="19"
+ label="Exclusion volumes"
+ layout="topleft"
+ name="show_exclusion_volumes"
+ top_pad="4"
+ width="90" />
+ <check_box
+ height="19"
+ label="Water plane"
+ layout="topleft"
+ name="show_water_plane"
+ top_pad="4"
+ width="90" />
+ <check_box
+ height="19"
+ label="With X-ray vision"
+ layout="topleft"
+ name="show_xray"
+ top_pad="4"
+ width="90" />
+ </panel>
+ <panel
+ border="false"
+ bevel_style="none"
+ follows="left|top"
+ layout="topleft"
+ name="test_panel"
+ label="Test path">
+ <text
+ height="14"
+ word_wrap="true"
+ use_ellipses="false"
+ type="string"
+ text_color="LabelTextColor"
+ text_readonly_color="LabelDisabledColor"
+ name="ctrl_click_label"
+ length="1"
+ left="12"
+ follows="left|top"
+ layout="topleft"
+ top_pad="20"
+ width="202">
+ Ctrl-click to select start point.
+ </text>
+ <text
+ height="14"
+ word_wrap="true"
+ use_ellipses="false"
+ type="string"
+ text_color="LabelTextColor"
+ text_readonly_color="LabelDisabledColor"
+ name="shift_click_label"
+ length="1"
+ follows="left|top"
+ layout="topleft"
+ top_pad="5"
+ width="202">
+ Shift-click to select end point.
+ </text>
+ <view_border
+ bevel_style="none"
+ follows="top|left"
+ layout="topleft"
+ height="0"
+ width="185"
+ top_pad="13"
+ visible="true" />
+ <text
+ height="14"
+ word_wrap="true"
+ use_ellipses="false"
+ type="string"
+ text_color="LabelTextColor"
+ text_readonly_color="LabelDisabledColor"
+ name="character_width_label"
+ length="1"
+ follows="left|top"
+ layout="topleft"
+ top_pad="14"
+ width="202">
+ Character width
+ </text>
+ <slider
+ decimal_digits="1"
+ height="14"
+ increment="0.1"
+ layout="topleft"
+ follows="left|top"
+ max_val="2"
+ min_val="0.2"
+ name="character_width"
+ top_pad="5"
+ value="1"
+ width="145" />
+ <text
+ height="14"
+ word_wrap="false"
+ use_ellipses="false"
+ type="string"
+ text_color="LabelTextColor"
+ text_readonly_color="LabelDisabledColor"
+ name="character_width_unit_label"
+ length="1"
+ follows="left|top"
+ layout="topleft"
+ top_pad="-14"
+ left_pad="0"
+ width="20">
+ m
+ </text>
+ <text
+ height="14"
+ word_wrap="true"
+ use_ellipses="false"
+ type="string"
+ text_color="LabelTextColor"
+ text_readonly_color="LabelDisabledColor"
+ name="character_type_label"
+ length="1"
+ follows="left|top"
+ layout="topleft"
+ left_pad="-165"
+ top_pad="13"
+ width="202">
+ Character type
+ </text>
+ <combo_box
+ follows="top|left"
+ layout="topleft"
+ height="19"
+ width="156"
+ top_pad="5"
+ name="path_character_type">
+ <combo_box.item
+ label="None"
+ name="path_character_type_none"
+ value="0" />
+ <combo_box.item
+ label="A"
+ name="path_character_type_a"
+ value="1" />
+ <combo_box.item
+ label="B"
+ name="path_character_type_b"
+ value="2" />
+ <combo_box.item
+ label="C"
+ name="path_character_type_c"
+ value="3" />
+ <combo_box.item
+ label="D"
+ name="path_character_type_d"
+ value="4" />
+ </combo_box>
+ <text
+ height="14"
+ word_wrap="true"
+ use_ellipses="false"
+ type="string"
+ text_color="PathfindingGoodColor"
+ length="1"
+ follows="left|top"
+ layout="topleft"
+ name="path_test_status"
+ top_pad="11"
+ width="202">
+ </text>
+ <button
+ follows="left|top"
+ height="22"
+ label="Clear path"
+ layout="topleft"
+ name="clear_path"
+ top_pad="27"
+ width="96"/>
+ </panel>
+ </tab_container>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_pathfinding_linksets.xml b/indra/newview/skins/default/xui/en/floater_pathfinding_linksets.xml
new file mode 100755
index 0000000000..4a457fb929
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_pathfinding_linksets.xml
@@ -0,0 +1,597 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ positioning="cascading"
+ can_resize="true"
+ can_tear_off="false"
+ height="395"
+ width="1075"
+ min_height="395"
+ min_width="990"
+ layout="topleft"
+ name="floater_pathfinding_linksets"
+ help_topic="floater_pathfinding_linksets"
+ reuse_instance="true"
+ save_rect="false"
+ single_instance="true"
+ title="Pathfinding linksets">
+ <floater.string name="messaging_initial"></floater.string>
+ <floater.string name="messaging_get_inprogress">Querying for pathfinding linksets ...</floater.string>
+ <floater.string name="messaging_get_error">Error detected while querying for pathfinding linksets.</floater.string>
+ <floater.string name="messaging_set_inprogress">Modifying selected pathfinding linksets ...</floater.string>
+ <floater.string name="messaging_set_error">Error detected while modifying selected pathfinding linksets.</floater.string>
+ <floater.string name="messaging_complete_none_found">No pathfinding linksets.</floater.string>
+ <floater.string name="messaging_complete_available">[NUM_SELECTED] linksets selected out of [NUM_TOTAL].</floater.string>
+ <floater.string name="messaging_not_enabled">This region is not enabled for pathfinding.</floater.string>
+ <floater.string name="linkset_terrain_name">[Terrain]</floater.string>
+ <floater.string name="linkset_terrain_description">--</floater.string>
+ <floater.string name="linkset_terrain_owner">--</floater.string>
+ <floater.string name="linkset_terrain_scripted">--</floater.string>
+ <floater.string name="linkset_terrain_land_impact">--</floater.string>
+ <floater.string name="linkset_terrain_dist_from_you">--</floater.string>
+ <floater.string name="linkset_owner_loading">[Loading]</floater.string>
+ <floater.string name="linkset_owner_unknown">[Unknown]</floater.string>
+ <floater.string name="linkset_owner_group">[group]</floater.string>
+ <floater.string name="linkset_is_scripted">Yes</floater.string>
+ <floater.string name="linkset_is_not_scripted">No</floater.string>
+ <floater.string name="linkset_is_unknown_scripted">Unknown</floater.string>
+ <floater.string name="linkset_use_walkable">Walkable</floater.string>
+ <floater.string name="linkset_use_static_obstacle">Static obstacle</floater.string>
+ <floater.string name="linkset_use_dynamic_obstacle">Movable obstacle</floater.string>
+ <floater.string name="linkset_use_material_volume">Material volume</floater.string>
+ <floater.string name="linkset_use_exclusion_volume">Exclusion volume</floater.string>
+ <floater.string name="linkset_use_dynamic_phantom">Movable phantom</floater.string>
+ <floater.string name="linkset_is_terrain">[unmodifiable]</floater.string>
+ <floater.string name="linkset_is_restricted_state">[restricted]</floater.string>
+ <floater.string name="linkset_is_non_volume_state">[concave]</floater.string>
+ <floater.string name="linkset_is_restricted_non_volume_state">[restricted,concave]</floater.string>
+ <floater.string name="linkset_choose_use">Choose linkset use...</floater.string>
+ <panel
+ border="false"
+ bevel_style="none"
+ follows="left|top|right|bottom"
+ layout="topleft"
+ height="226"
+ width="1059">
+ <text
+ height="13"
+ word_wrap="false"
+ use_ellipses="false"
+ type="string"
+ text_color="LabelTextColor"
+ length="1"
+ follows="left|top"
+ layout="topleft"
+ left="20"
+ top_pad="14"
+ width="67">
+ Filter by:
+ </text>
+ <text
+ height="13"
+ word_wrap="false"
+ use_ellipses="false"
+ type="string"
+ text_color="LabelTextColor"
+ length="1"
+ follows="left|top"
+ layout="topleft"
+ left_pad="0"
+ width="62">
+ Name
+ </text>
+ <line_editor
+ border_style="line"
+ border_thickness="1"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left_pad="0"
+ top_pad="-18"
+ max_length_chars="255"
+ name="filter_by_name"
+ width="161" />
+ <text
+ height="13"
+ word_wrap="false"
+ use_ellipses="false"
+ type="string"
+ text_color="LabelTextColor"
+ length="1"
+ follows="left|top"
+ layout="topleft"
+ left_pad="22"
+ top_pad="-15"
+ width="88">
+ Description
+ </text>
+ <line_editor
+ border_style="line"
+ border_thickness="1"
+ follows="left|top"
+ height="20"
+ layout="topleft"
+ left_pad="0"
+ top_pad="-17"
+ max_length_chars="255"
+ name="filter_by_description"
+ width="162" />
+ <combo_box
+ height="20"
+ layout="topleft"
+ follows="left|top"
+ name="filter_by_linkset_use"
+ left_pad="32"
+ top_pad="-20"
+ width="199">
+ <combo_box.item
+ label="Filter by linkset use..."
+ name="filter_by_linkset_use_none"
+ value="0" />
+ <combo_box.item
+ label="Walkable"
+ name="filter_by_linkset_use_walkable"
+ value="1" />
+ <combo_box.item
+ label="Static obstacle"
+ name="filter_by_linkset_use_static_obstacle"
+ value="2" />
+ <combo_box.item
+ label="Movable obstacle"
+ name="filter_by_linkset_use_dynamic_obstacle"
+ value="3" />
+ <combo_box.item
+ label="Material volume"
+ name="filter_by_linkset_use_material_volume"
+ value="4" />
+ <combo_box.item
+ label="Exclusion volume"
+ name="filter_by_linkset_use_exclusion_volume"
+ value="5" />
+ <combo_box.item
+ label="Movable phantom"
+ name="filter_by_linkset_use_dynamic_phantom"
+ value="6" />
+ </combo_box>
+ <button
+ follows="right|top"
+ height="21"
+ label="Apply"
+ layout="topleft"
+ name="apply_filters"
+ top_pad="-21"
+ left_pad="91"
+ width="73"/>
+ <button
+ follows="right|top"
+ height="21"
+ label="Clear"
+ layout="topleft"
+ name="clear_filters"
+ top_pad="-21"
+ left_pad="8"
+ width="73"/>
+ <scroll_list
+ column_padding="0"
+ draw_heading="true"
+ follows="all"
+ height="135"
+ layout="topleft"
+ left="18"
+ top_pad="15"
+ tab_stop="false"
+ multi_select="true"
+ name="objects_scroll_list"
+ width="1040">
+ <scroll_list.columns
+ label="Name (root prim)"
+ name="name"
+ dynamic_width="true" />
+ <scroll_list.columns
+ label="Description (root prim)"
+ name="description"
+ width="158" />
+ <scroll_list.columns
+ label="Owner"
+ name="owner"
+ width="141" />
+ <scroll_list.columns
+ label="Scripted"
+ name="scripted"
+ width="60" />
+ <scroll_list.columns
+ label="Impact"
+ name="land_impact"
+ width="55" />
+ <scroll_list.columns
+ label="Distance"
+ name="dist_from_you"
+ width="65" />
+ <scroll_list.columns
+ label="Linkset use"
+ name="linkset_use"
+ width="236" />
+ <scroll_list.columns
+ label="A %"
+ name="a_percent"
+ width="41" />
+ <scroll_list.columns
+ label="B %"
+ name="b_percent"
+ width="41" />
+ <scroll_list.columns
+ label="C %"
+ name="c_percent"
+ width="41" />
+ <scroll_list.columns
+ label="D %"
+ name="d_percent"
+ width="41" />
+ </scroll_list>
+ <text
+ height="13"
+ word_wrap="false"
+ use_ellipses="false"
+ type="string"
+ text_color="LabelTextColor"
+ length="1"
+ follows="left|bottom|right"
+ layout="topleft"
+ name="messaging_status"
+ top_pad="17"
+ width="679">
+ Linksets:
+ </text>
+ <button
+ follows="right|bottom"
+ height="21"
+ label="Refresh list"
+ layout="topleft"
+ name="refresh_objects_list"
+ top_pad="-16"
+ left_pad="0"
+ width="115"/>
+ <button
+ follows="right|bottom"
+ height="21"
+ label="Select all"
+ layout="topleft"
+ name="select_all_objects"
+ top_pad="-21"
+ left_pad="8"
+ width="115"/>
+ <button
+ follows="right|bottom"
+ height="21"
+ label="Select none"
+ layout="topleft"
+ name="select_none_objects"
+ top_pad="-21"
+ left_pad="8"
+ width="115"/>
+ </panel>
+ <view_border
+ bevel_style="none"
+ follows="left|bottom|right"
+ height="0"
+ layout="topleft"
+ name="horiz_separator"
+ top_pad="0"
+ left="18"
+ width="1039"/>
+ <panel
+ border="false"
+ bevel_style="none"
+ follows="left|right|bottom"
+ layout="topleft"
+ left="0"
+ height="67"
+ width="1010">
+ <text
+ height="13"
+ word_wrap="false"
+ use_ellipses="false"
+ type="string"
+ text_color="LabelTextColor"
+ text_readonly_color="LabelDisabledColor"
+ length="1"
+ left="18"
+ follows="left|bottom|right"
+ layout="topleft"
+ top_pad="8"
+ width="580">
+ Actions on selected linksets (If a linkset is removed from the world, its attributes may be lost):
+ </text>
+ <check_box
+ height="19"
+ follows="left|bottom"
+ label="Show beacon"
+ layout="topleft"
+ name="show_beacon"
+ left_pad="0"
+ top_pad="-16"
+ width="90" />
+ <button
+ follows="left|bottom"
+ height="21"
+ label="Take"
+ layout="topleft"
+ name="take_objects"
+ top_pad="9"
+ left="18"
+ width="95"/>
+ <button
+ follows="left|bottom"
+ height="21"
+ label="Take copy"
+ layout="topleft"
+ name="take_copy_objects"
+ top_pad="-21"
+ left_pad="6"
+ width="95"/>
+ <button
+ follows="left|bottom"
+ height="21"
+ label="Teleport me to it"
+ layout="topleft"
+ name="teleport_me_to_object"
+ top_pad="-21"
+ left_pad="239"
+ width="160"/>
+ <button
+ follows="right|bottom"
+ height="21"
+ label="Return"
+ layout="topleft"
+ name="return_objects"
+ top_pad="-21"
+ left_pad="252"
+ width="95"/>
+ <button
+ follows="right|bottom"
+ height="21"
+ label="Delete"
+ layout="topleft"
+ name="delete_objects"
+ top_pad="-21"
+ left_pad="6"
+ width="95"/>
+ </panel>
+ <view_border
+ bevel_style="none"
+ follows="left|bottom|right"
+ height="0"
+ layout="topleft"
+ name="horiz_separator"
+ top_pad="0"
+ left="18"
+ width="1039"/>
+ <panel
+ border="false"
+ bevel_style="none"
+ follows="left|right|bottom"
+ layout="topleft"
+ left="0"
+ height="75"
+ width="1010">
+ <text
+ height="13"
+ word_wrap="false"
+ use_ellipses="false"
+ type="string"
+ text_color="LabelTextColor"
+ length="1"
+ follows="left|bottom"
+ layout="topleft"
+ left="18"
+ top_pad="8"
+ width="972">
+ Edit attributes of selected linksets and press the button to apply changes
+ </text>
+ <combo_box
+ height="20"
+ layout="topleft"
+ follows="left|top"
+ name="edit_linkset_use"
+ left="18"
+ top_pad="17"
+ width="199">
+ </combo_box>
+ <text
+ height="13"
+ word_wrap="false"
+ use_ellipses="false"
+ type="string"
+ text_color="LabelTextColor"
+ text_readonly_color="LabelDisabledColor"
+ name="walkability_coefficients_label"
+ length="1"
+ follows="left|bottom"
+ layout="topleft"
+ left_pad="36"
+ top_pad="-17"
+ width="110">
+ Walkability:
+ </text>
+ <text
+ height="13"
+ word_wrap="false"
+ use_ellipses="false"
+ type="string"
+ text_color="LabelTextColor"
+ text_readonly_color="LabelDisabledColor"
+ name="edit_a_label"
+ length="1"
+ follows="left|bottom"
+ layout="topleft"
+ left_pad="0"
+ width="18">
+ A
+ </text>
+ <line_editor
+ border_style="line"
+ border_thickness="1"
+ follows="left|bottom"
+ height="21"
+ layout="topleft"
+ left_pad="0"
+ top_pad="-19"
+ max_length_chars="3"
+ name="edit_a_value"
+ tool_tip="Walkability for characters of type A. Example character type is humanoid."
+ width="45" />
+ <text
+ height="13"
+ word_wrap="false"
+ use_ellipses="false"
+ type="string"
+ text_color="LabelTextColor"
+ text_readonly_color="LabelDisabledColor"
+ name="edit_b_label"
+ length="1"
+ follows="left|bottom"
+ layout="topleft"
+ left_pad="44"
+ top_pad="-15"
+ width="18">
+ B
+ </text>
+ <line_editor
+ border_style="line"
+ border_thickness="1"
+ follows="left|bottom"
+ height="21"
+ layout="topleft"
+ left_pad="0"
+ top_pad="-19"
+ max_length_chars="3"
+ name="edit_b_value"
+ tool_tip="Walkability for characters of type B. Example character type is creature."
+ width="45" />
+ <text
+ height="13"
+ word_wrap="false"
+ use_ellipses="false"
+ type="string"
+ text_color="LabelTextColor"
+ text_readonly_color="LabelDisabledColor"
+ name="edit_c_label"
+ length="1"
+ follows="left|bottom"
+ layout="topleft"
+ left_pad="44"
+ top_pad="-15"
+ width="18">
+ C
+ </text>
+ <line_editor
+ border_style="line"
+ border_thickness="1"
+ follows="left|bottom"
+ height="21"
+ layout="topleft"
+ left_pad="0"
+ top_pad="-19"
+ max_length_chars="3"
+ name="edit_c_value"
+ tool_tip="Walkability for characters of type C. Example character type is mechanical."
+ width="45" />
+ <text
+ height="13"
+ word_wrap="false"
+ use_ellipses="false"
+ type="string"
+ text_color="LabelTextColor"
+ text_readonly_color="LabelDisabledColor"
+ name="edit_d_label"
+ length="1"
+ follows="left|bottom"
+ layout="topleft"
+ left_pad="44"
+ top_pad="-15"
+ width="18">
+ D
+ </text>
+ <line_editor
+ border_style="line"
+ border_thickness="1"
+ follows="left|bottom"
+ height="21"
+ layout="topleft"
+ left_pad="0"
+ top_pad="-19"
+ max_length_chars="3"
+ name="edit_d_value"
+ tool_tip="Walkability for characters of type D. Example character type is other."
+ width="45" />
+ <button
+ follows="left|bottom"
+ height="21"
+ label="Apply changes"
+ layout="topleft"
+ name="apply_edit_values"
+ top_pad="-21"
+ left_pad="40"
+ width="140"/>
+ <text
+ height="13"
+ word_wrap="false"
+ use_ellipses="false"
+ type="string"
+ text_color="LabelTextColor"
+ text_readonly_color="LabelDisabledColor"
+ name="suggested_use_a_label"
+ length="1"
+ follows="left|bottom"
+ layout="topleft"
+ left="363"
+ top_pad="5"
+ width="107">
+ (Humanoid)
+ </text>
+ <text
+ height="13"
+ word_wrap="false"
+ use_ellipses="false"
+ type="string"
+ text_color="LabelTextColor"
+ text_readonly_color="LabelDisabledColor"
+ name="suggested_use_b_label"
+ length="1"
+ follows="left|bottom"
+ layout="topleft"
+ left_pad="0"
+ width="107">
+ (Creature)
+ </text>
+ <text
+ height="13"
+ word_wrap="false"
+ use_ellipses="false"
+ type="string"
+ text_color="LabelTextColor"
+ text_readonly_color="LabelDisabledColor"
+ name="suggested_use_c_label"
+ length="1"
+ follows="left|bottom"
+ layout="topleft"
+ left_pad="0"
+ width="107">
+ (Mechanical)
+ </text>
+ <text
+ height="13"
+ word_wrap="false"
+ use_ellipses="false"
+ type="string"
+ text_color="LabelTextColor"
+ text_readonly_color="LabelDisabledColor"
+ name="suggested_use_d_label"
+ length="1"
+ follows="left|bottom"
+ layout="topleft"
+ left_pad="0"
+ width="107">
+ (Other)
+ </text>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_pay.xml b/indra/newview/skins/default/xui/en/floater_pay.xml
index 41a7134b1d..41a7134b1d 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_pay.xml
+++ b/indra/newview/skins/default/xui/en/floater_pay.xml
diff --git a/indra/newview/skins/default/xui/en/floater_pay_object.xml b/indra/newview/skins/default/xui/en/floater_pay_object.xml
index d3a35c2051..d3a35c2051 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_pay_object.xml
+++ b/indra/newview/skins/default/xui/en/floater_pay_object.xml
diff --git a/indra/newview/skins/default/xui/en/floater_people.xml b/indra/newview/skins/default/xui/en/floater_people.xml
index 08d0b00a83..701233ba4a 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_people.xml
+++ b/indra/newview/skins/default/xui/en/floater_people.xml
@@ -6,21 +6,21 @@
can_resize="true"
height="570"
help_topic="sidebar_people"
- min_height="440"
- min_width="333"
+ min_height="220"
+ min_width="260"
layout="topleft"
name="floater_people"
save_rect="true"
single_instance="true"
reuse_instance="true"
title="PEOPLE"
- width="333">
+ width="370">
<panel_container
default_panel_name="panel_people"
follows="all"
height="570"
name="main_panel"
- width="333">
+ width="370">
<panel
class="panel_people"
name="panel_people"
@@ -31,11 +31,5 @@
filename="panel_group_info_sidetray.xml"
label="Group Profile"
font="SansSerifBold"/>
- <panel
- class="panel_block_list_sidetray"
- name="panel_block_list_sidetray"
- filename="panel_block_list_sidetray.xml"
- label="Blocked Residents &amp; Objects"
- font="SansSerifBold"/>
</panel_container>
</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_picks.xml b/indra/newview/skins/default/xui/en/floater_picks.xml
index 984894b016..984894b016 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_picks.xml
+++ b/indra/newview/skins/default/xui/en/floater_picks.xml
diff --git a/indra/newview/skins/default/xui/en/floater_places.xml b/indra/newview/skins/default/xui/en/floater_places.xml
index b241e265a9..b241e265a9 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_places.xml
+++ b/indra/newview/skins/default/xui/en/floater_places.xml
diff --git a/indra/newview/skins/default/xui/en/floater_post_process.xml b/indra/newview/skins/default/xui/en/floater_post_process.xml
index 05943a10d3..05943a10d3 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_post_process.xml
+++ b/indra/newview/skins/default/xui/en/floater_post_process.xml
diff --git a/indra/newview/skins/default/xui/en/floater_preferences.xml b/indra/newview/skins/default/xui/en/floater_preferences.xml
index bd6faf4ed8..bd6faf4ed8 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_preferences.xml
+++ b/indra/newview/skins/default/xui/en/floater_preferences.xml
diff --git a/indra/newview/skins/default/xui/en/floater_preferences_proxy.xml b/indra/newview/skins/default/xui/en/floater_preferences_proxy.xml
index 93bfe53aae..93bfe53aae 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_preferences_proxy.xml
+++ b/indra/newview/skins/default/xui/en/floater_preferences_proxy.xml
diff --git a/indra/newview/skins/default/xui/en/floater_preview_animation.xml b/indra/newview/skins/default/xui/en/floater_preview_animation.xml
index 3ea5f54f2c..3ea5f54f2c 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_preview_animation.xml
+++ b/indra/newview/skins/default/xui/en/floater_preview_animation.xml
diff --git a/indra/newview/skins/default/xui/en/floater_preview_gesture.xml b/indra/newview/skins/default/xui/en/floater_preview_gesture.xml
index 8baa0a56f7..8baa0a56f7 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_preview_gesture.xml
+++ b/indra/newview/skins/default/xui/en/floater_preview_gesture.xml
diff --git a/indra/newview/skins/default/xui/en/floater_preview_notecard.xml b/indra/newview/skins/default/xui/en/floater_preview_notecard.xml
index be3b2d179d..2e1c8ce670 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_preview_notecard.xml
+++ b/indra/newview/skins/default/xui/en/floater_preview_notecard.xml
@@ -70,6 +70,7 @@
max_length="65536"
name="Notecard Editor"
parse_urls="false"
+ spellcheck="true"
tab_group="1"
top="46"
width="392"
diff --git a/indra/newview/skins/default/xui/en/floater_preview_sound.xml b/indra/newview/skins/default/xui/en/floater_preview_sound.xml
index 83a1f5a96f..83a1f5a96f 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_preview_sound.xml
+++ b/indra/newview/skins/default/xui/en/floater_preview_sound.xml
diff --git a/indra/newview/skins/default/xui/en/floater_preview_texture.xml b/indra/newview/skins/default/xui/en/floater_preview_texture.xml
index 137e278ddc..137e278ddc 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_preview_texture.xml
+++ b/indra/newview/skins/default/xui/en/floater_preview_texture.xml
diff --git a/indra/newview/skins/default/xui/en/floater_price_for_listing.xml b/indra/newview/skins/default/xui/en/floater_price_for_listing.xml
index 6312366b86..6312366b86 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_price_for_listing.xml
+++ b/indra/newview/skins/default/xui/en/floater_price_for_listing.xml
diff --git a/indra/newview/skins/default/xui/en/floater_publish_classified.xml b/indra/newview/skins/default/xui/en/floater_publish_classified.xml
index 322e34272c..322e34272c 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_publish_classified.xml
+++ b/indra/newview/skins/default/xui/en/floater_publish_classified.xml
diff --git a/indra/newview/skins/default/xui/en/floater_region_debug_console.xml b/indra/newview/skins/default/xui/en/floater_region_debug_console.xml
index 7c7ee2df4c..7c7ee2df4c 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_region_debug_console.xml
+++ b/indra/newview/skins/default/xui/en/floater_region_debug_console.xml
diff --git a/indra/newview/skins/default/xui/en/floater_region_info.xml b/indra/newview/skins/default/xui/en/floater_region_info.xml
index 3b58cd08f6..3b58cd08f6 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_region_info.xml
+++ b/indra/newview/skins/default/xui/en/floater_region_info.xml
diff --git a/indra/newview/skins/default/xui/en/floater_report_abuse.xml b/indra/newview/skins/default/xui/en/floater_report_abuse.xml
index e6d749a3f0..9561f67941 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_report_abuse.xml
+++ b/indra/newview/skins/default/xui/en/floater_report_abuse.xml
@@ -155,6 +155,7 @@
name="object_name"
top_delta="0"
translate="false"
+ parse_urls="false"
use_ellipses="true"
width="185">
Consetetur Sadipscing
diff --git a/indra/newview/skins/default/xui/en/floater_script.xml b/indra/newview/skins/default/xui/en/floater_script.xml
index bd4edb81c8..bd4edb81c8 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_script.xml
+++ b/indra/newview/skins/default/xui/en/floater_script.xml
diff --git a/indra/newview/skins/default/xui/en/floater_script_debug.xml b/indra/newview/skins/default/xui/en/floater_script_debug.xml
index 53d4925214..53d4925214 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_script_debug.xml
+++ b/indra/newview/skins/default/xui/en/floater_script_debug.xml
diff --git a/indra/newview/skins/default/xui/en/floater_script_debug_panel.xml b/indra/newview/skins/default/xui/en/floater_script_debug_panel.xml
index b5dd2f97b9..b5dd2f97b9 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_script_debug_panel.xml
+++ b/indra/newview/skins/default/xui/en/floater_script_debug_panel.xml
diff --git a/indra/newview/skins/default/xui/en/floater_script_limits.xml b/indra/newview/skins/default/xui/en/floater_script_limits.xml
index 6b36cdfcc5..6b36cdfcc5 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_script_limits.xml
+++ b/indra/newview/skins/default/xui/en/floater_script_limits.xml
diff --git a/indra/newview/skins/default/xui/en/floater_script_preview.xml b/indra/newview/skins/default/xui/en/floater_script_preview.xml
index 91a9e67e4c..91a9e67e4c 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_script_preview.xml
+++ b/indra/newview/skins/default/xui/en/floater_script_preview.xml
diff --git a/indra/newview/skins/default/xui/en/floater_script_queue.xml b/indra/newview/skins/default/xui/en/floater_script_queue.xml
index f4aca7bb3d..f4aca7bb3d 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_script_queue.xml
+++ b/indra/newview/skins/default/xui/en/floater_script_queue.xml
diff --git a/indra/newview/skins/default/xui/en/floater_script_search.xml b/indra/newview/skins/default/xui/en/floater_script_search.xml
index ade0156bc7..ade0156bc7 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_script_search.xml
+++ b/indra/newview/skins/default/xui/en/floater_script_search.xml
diff --git a/indra/newview/skins/default/xui/en/floater_search.xml b/indra/newview/skins/default/xui/en/floater_search.xml
index c3e7028dc5..c3e7028dc5 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_search.xml
+++ b/indra/newview/skins/default/xui/en/floater_search.xml
diff --git a/indra/newview/skins/default/xui/en/floater_select_key.xml b/indra/newview/skins/default/xui/en/floater_select_key.xml
index 4e89df5a73..4e89df5a73 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_select_key.xml
+++ b/indra/newview/skins/default/xui/en/floater_select_key.xml
diff --git a/indra/newview/skins/default/xui/en/floater_sell_land.xml b/indra/newview/skins/default/xui/en/floater_sell_land.xml
index 52de9ddd47..52de9ddd47 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_sell_land.xml
+++ b/indra/newview/skins/default/xui/en/floater_sell_land.xml
diff --git a/indra/newview/skins/default/xui/en/floater_settings_debug.xml b/indra/newview/skins/default/xui/en/floater_settings_debug.xml
index 3ed2bd7206..3ed2bd7206 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_settings_debug.xml
+++ b/indra/newview/skins/default/xui/en/floater_settings_debug.xml
diff --git a/indra/newview/skins/default/xui/en/floater_side_bar_tab.xml b/indra/newview/skins/default/xui/en/floater_side_bar_tab.xml
index 9f14e9ae0a..9f14e9ae0a 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_side_bar_tab.xml
+++ b/indra/newview/skins/default/xui/en/floater_side_bar_tab.xml
diff --git a/indra/newview/skins/default/xui/en/floater_snapshot.xml b/indra/newview/skins/default/xui/en/floater_snapshot.xml
index 49d64767cc..853c209bca 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_snapshot.xml
+++ b/indra/newview/skins/default/xui/en/floater_snapshot.xml
@@ -21,7 +21,11 @@
Sending Email
</string>
<string
- name="profile_progress_str">
+ name="facebook_progress_str">
+ Posting to Facebook
+ </string>
+ <string
+ name="profile_progress_str">
Posting
</string>
<string
@@ -33,7 +37,11 @@
Saving to Computer
</string>
<string
- name="profile_succeeded_str">
+ name="facebook_succeeded_str">
+ Image uploaded
+ </string>
+ <string
+ name="profile_succeeded_str">
Image uploaded
</string>
<string
@@ -49,7 +57,11 @@
Saved to Computer!
</string>
<string
- name="profile_failed_str">
+ name="facebook_failed_str">
+ Failed to upload image to your Facebook timeline.
+ </string>
+ <string
+ name="profile_failed_str">
Failed to upload image to your Profile Feed.
</string>
<string
diff --git a/indra/newview/skins/default/xui/en/floater_social.xml b/indra/newview/skins/default/xui/en/floater_social.xml
new file mode 100644
index 0000000000..b7ff374d5f
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_social.xml
@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<floater
+ positioning="cascading"
+ can_close="true"
+ can_resize="false"
+ help_topic="floater_social"
+ layout="topleft"
+ name="floater_social"
+ save_rect="true"
+ single_instance="true"
+ reuse_instance="true"
+ title="POST TO FACEBOOK"
+ height="482"
+ width="304">
+ <panel
+ height="482"
+ width="304"
+ visible="true"
+ name="background"
+ follows="all"
+ top="0"
+ left="0">
+ <tab_container
+ name="tabs"
+ tab_group="1"
+ tab_min_width="70"
+ tab_height="30"
+ tab_position="top"
+ top="7"
+ height="437"
+ halign="center">
+ <panel
+ filename="panel_social_status.xml"
+ class="llsocialstatuspanel"
+ follows="all"
+ label="STATUS"
+ name="panel_social_status"/>
+ <panel
+ filename="panel_social_photo.xml"
+ class="llsocialphotopanel"
+ follows="all"
+ label="PHOTO"
+ name="panel_social_photo"/>
+ <panel
+ filename="panel_social_place.xml"
+ class="llsocialcheckinpanel"
+ follows="all"
+ label="CHECK IN"
+ name="panel_social_place"/>
+ <panel
+ filename="panel_social_account.xml"
+ class="llsocialaccountpanel"
+ follows="all"
+ label="ACCOUNT"
+ name="panel_social_account"/>
+ </tab_container>
+ <panel
+ name="connection_status_panel"
+ follows="left|bottom|right"
+ height="24">
+ <text
+ name="connection_error_text"
+ type="string"
+ follows="left|bottom|right"
+ top="5"
+ left="9"
+ width="250"
+ height="20"
+ wrap="true"
+ halign="left"
+ valign="center"
+ text_color="DrYellow"
+ font="SansSerif">
+ Error
+ </text>
+ <loading_indicator
+ follows="left|bottom|right"
+ height="24"
+ width="24"
+ name="connection_loading_indicator"
+ top="2"
+ left="9"
+ visible="true"/>
+ <text
+ name="connection_loading_text"
+ type="string"
+ follows="left|bottom|right"
+ top="5"
+ left_pad="5"
+ width="250"
+ height="20"
+ wrap="true"
+ halign="left"
+ valign="center"
+ text_color="EmphasisColor"
+ font="SansSerif">
+ Loading...
+ </text>
+ </panel>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_sound_devices.xml b/indra/newview/skins/default/xui/en/floater_sound_devices.xml
index dec0e9b6c6..dec0e9b6c6 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_sound_devices.xml
+++ b/indra/newview/skins/default/xui/en/floater_sound_devices.xml
diff --git a/indra/newview/skins/default/xui/en/floater_sound_preview.xml b/indra/newview/skins/default/xui/en/floater_sound_preview.xml
index af791466b6..af791466b6 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_sound_preview.xml
+++ b/indra/newview/skins/default/xui/en/floater_sound_preview.xml
diff --git a/indra/newview/skins/default/xui/en/floater_spellcheck.xml b/indra/newview/skins/default/xui/en/floater_spellcheck.xml
new file mode 100755
index 0000000000..76a350dd29
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_spellcheck.xml
@@ -0,0 +1,160 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ border="true"
+ can_close="true"
+ can_minimize="true"
+ save_rect="true"
+ help_topic="spelling_settings"
+ can_resize="false"
+ height="315"
+ width="490"
+ name="spellcheck_floater"
+ title="Spell Checker Settings">
+ <check_box
+ bottom_delta="30"
+ control_name="SpellCheck"
+ left_delta="15"
+ height="16"
+ width="100"
+ follows="left|top"
+ label="Enable spell checker"
+ name="spellcheck_enable" />
+ <view_border
+ top_pad="10"
+ left="2"
+ height="0"
+ width="491"
+ follows="left|top"
+ bevel_style="none"
+ border_thickness="1"
+ mouse_opaque="false"
+ name="divisor1"/>
+ <text
+ enabled_control="SpellCheck"
+ follows="top|left"
+ height="10"
+ layout="topleft"
+ left="38"
+ mouse_opaque="false"
+ name="spellcheck_main"
+ top_pad="15"
+ type="string"
+ width="90"
+ >
+ Main dictionary :
+ </text>
+ <combo_box
+ enabled_control="SpellCheck"
+ follows="top|left"
+ height="23"
+ layout="topleft"
+ left_pad="10"
+ name="spellcheck_main_combo"
+ top_pad="-15"
+ width="175"
+ />
+ <text
+ enabled_control="SpellCheck"
+ follows="top|left"
+ height="10"
+ label="Logs:"
+ layout="topleft"
+ left="38"
+ mouse_opaque="false"
+ name="spellcheck_additional"
+ top_pad="15"
+ type="string"
+ width="190"
+ >
+ Additional dictionaries :
+ </text>
+ <text
+ follows="top|left"
+ height="12"
+ layout="topleft"
+ left="55"
+ length="1"
+ name="spellcheck_available"
+ top_pad="10"
+ type="string"
+ width="175">
+ Available
+ </text>
+ <text
+ follows="top|left"
+ height="12"
+ type="string"
+ left_pad="45"
+ length="1"
+ layout="topleft"
+ name="spellcheck_active"
+ width="175">
+ Active
+ </text>
+ <scroll_list
+ enabled_control="SpellCheck"
+ follows="top|left"
+ height="155"
+ layout="topleft"
+ left="55"
+ multi_select="true"
+ name="spellcheck_available_list"
+ sort_column="0"
+ sort_ascending="true"
+ width="175" />
+ <button
+ enabled_control="SpellCheck"
+ follows="top|left"
+ height="26"
+ image_overlay="Arrow_Right"
+ hover_glow_amount="0.15"
+ layout="topleft"
+ left_pad="10"
+ name="spellcheck_moveright_btn"
+ top_delta="50"
+ width="25">
+ </button>
+ <button
+ enabled_control="SpellCheck"
+ follows="top|left"
+ height="26"
+ image_overlay="Arrow_Left"
+ hover_glow_amount="0.15"
+ layout="topleft"
+ name="spellcheck_moveleft_btn"
+ top_delta="30"
+ width="25">
+ </button>
+ <scroll_list
+ enabled_control="SpellCheck"
+ follows="top|left"
+ height="155"
+ layout="topleft"
+ left_pad="10"
+ multi_select="true"
+ name="spellcheck_active_list"
+ sort_column="0"
+ sort_ascending="true"
+ top_pad="-105"
+ width="175"
+ />
+ <button
+ enabled="false"
+ follows="left|top"
+ height="23"
+ label="Remove"
+ layout="topleft"
+ left="55"
+ name="spellcheck_remove_btn"
+ top_pad="5"
+ width="80" />
+ <button
+ follows="left|top"
+ height="23"
+ label="Import..."
+ layout="topleft"
+ left_pad="15"
+ name="spellcheck_import_btn"
+ top_delta="0"
+ width="80" />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_spellcheck_import.xml b/indra/newview/skins/default/xui/en/floater_spellcheck_import.xml
new file mode 100755
index 0000000000..b54090015d
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_spellcheck_import.xml
@@ -0,0 +1,116 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ border="true"
+ can_close="true"
+ can_minimize="true"
+ bottom="275"
+ left="300"
+ can_resize="false"
+ height="140"
+ width="400"
+ name="spellcheck_import"
+ title="Import Dictionary">
+ <text
+ follows="top|left"
+ height="16"
+ layout="topleft"
+ left="25"
+ top="15"
+ type="string"
+ width="65">
+ Dictionary:
+ </text>
+ <line_editor
+ enabled="false"
+ follows="left|top"
+ height="23"
+ layout="topleft"
+ left_pad="10"
+ max_length_bytes="255"
+ name="dictionary_path"
+ top_delta="-5"
+ width="200" />
+ <button
+ follows="left|top"
+ height="23"
+ label="Browse"
+ label_selected="Browse"
+ layout="topleft"
+ left_pad="5"
+ name="dictionary_path_browse"
+ top_delta="0"
+ width="75" />
+ <text
+ follows="top|left"
+ height="16"
+ layout="topleft"
+ left="25"
+ top_pad="8"
+ type="string"
+ width="65">
+ Name:
+ </text>
+ <line_editor
+ enabled="false"
+ follows="left|top"
+ height="23"
+ layout="topleft"
+ left_pad="10"
+ max_length_bytes="255"
+ name="dictionary_name"
+ top_delta="-5"
+ width="200" />
+ <text
+ follows="top|left"
+ height="16"
+ layout="topleft"
+ left="25"
+ top_pad="8"
+ type="string"
+ width="65">
+ Language:
+ </text>
+ <line_editor
+ follows="left|top"
+ height="23"
+ layout="topleft"
+ left_pad="10"
+ max_length_bytes="255"
+ name="dictionary_language"
+ top_delta="-5"
+ width="200" />
+ <view_border
+ top_pad="10"
+ left="2"
+ height="0"
+ width="396"
+ follows="left|top"
+ bevel_style="none"
+ border_thickness="1"
+ mouse_opaque="false"
+ name="divisor"/>
+ <button
+ top_pad="10"
+ right="280"
+ height="22"
+ width="90"
+ enabled="true"
+ follows="left|top"
+ mouse_opaque="true"
+ halign="center"
+ scale_image="true"
+ name="ok_btn"
+ label="Import" />
+ <button
+ top_delta="0"
+ right="380"
+ height="22"
+ width="90"
+ enabled="true"
+ follows="left|top"
+ mouse_opaque="true"
+ halign="center"
+ scale_image="true"
+ name="cancel_btn"
+ label="Cancel" />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_stats.xml b/indra/newview/skins/default/xui/en/floater_stats.xml
index 2fd932786b..f9eb16d224 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_stats.xml
+++ b/indra/newview/skins/default/xui/en/floater_stats.xml
@@ -149,6 +149,19 @@
show_per_sec="true"
show_bar="false">
</stat_bar>
+ <stat_bar
+ name="object_cache_hits"
+ label="Object Cache Hit Rate"
+ stat="object_cache_hits"
+ bar_min="0"
+ bar_max="100"
+ unit_label="%"
+ tick_spacing="20"
+ label_spacing="20"
+ show_history="true"
+ show_per_sec="false"
+ show_bar="false">
+ </stat_bar>
</stat_view>
<!--Texture Stats-->
<stat_view
@@ -156,6 +169,32 @@
label="Texture"
show_label="true">
<stat_bar
+ name="texture_cache_hits"
+ label="Cache Hit Rate"
+ stat="texture_cache_hits"
+ bar_min="0.f"
+ bar_max="100.f"
+ unit_label="%"
+ tick_spacing="20"
+ label_spacing="20"
+ show_history="true"
+ show_per_sec="false"
+ show_bar="false">
+ </stat_bar>
+ <stat_bar
+ name="texture_cache_read_latency"
+ label="Cache Read Latency"
+ unit_label="msec"
+ stat="texture_cache_read_latency"
+ bar_min="0.f"
+ bar_max="1000.f"
+ tick_spacing="100"
+ label_spacing="200"
+ show_history="true"
+ show_per_sec="false"
+ show_bar="false">
+ </stat_bar>
+ <stat_bar
name="numimagesstat"
label="Count"
stat="numimagesstat"
@@ -532,6 +571,20 @@
show_bar="false"
show_mean="false" >
</stat_bar>
+ <stat_bar
+ name="simpctscriptsrun"
+ label="Scripts Run"
+ unit_label=" %"
+ stat="simpctscriptsrun"
+ bar_min="0"
+ bar_max="100"
+ tick_spacing="10"
+ label_spacing="20"
+ precision="3"
+ show_per_sec="false"
+ show_bar="false"
+ show_mean="true">
+ </stat_bar>
<stat_bar
name="simscripteps"
@@ -548,6 +601,53 @@
show_mean="false" >
</stat_bar>
+ <stat_view
+ name="simpathfinding"
+ label="Pathfinding"
+ show_label="true">
+ <stat_bar
+ name="simsimaistepmsec"
+ label=" AI Step Time"
+ stat="simsimaistepmsec"
+ unit_label="ms"
+ precision="3"
+ bar_min="0.f"
+ bar_max="40.f"
+ tick_spacing="10.f"
+ label_spacing="20.f"
+ show_per_sec="false"
+ show_bar="false"
+ show_mean="false" >
+ </stat_bar>
+ <stat_bar
+ name="simsimskippedsilhouettesteps"
+ label=" Skipped Silhouette Steps"
+ stat="simsimskippedsilhouettesteps"
+ unit_label="/sec"
+ precision="0"
+ bar_min="0"
+ bar_max="45"
+ tick_spacing="4"
+ label_spacing="8"
+ show_per_sec="false"
+ show_bar="false">
+ </stat_bar>
+ <stat_bar
+ name="simsimpctsteppedcharacters"
+ label=" Characters Updated"
+ unit_label=" %"
+ stat="simsimpctsteppedcharacters"
+ bar_min="0"
+ bar_max="100"
+ tick_spacing="10"
+ label_spacing="20"
+ precision="1"
+ show_per_sec="false"
+ show_bar="false"
+ show_mean="true">
+ </stat_bar>
+ </stat_view>
+
<stat_bar
name="siminpps"
label="Packets In"
diff --git a/indra/newview/skins/default/xui/en/floater_sys_well.xml b/indra/newview/skins/default/xui/en/floater_sys_well.xml
index ecedb27438..ecedb27438 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_sys_well.xml
+++ b/indra/newview/skins/default/xui/en/floater_sys_well.xml
diff --git a/indra/newview/skins/default/xui/en/floater_telehub.xml b/indra/newview/skins/default/xui/en/floater_telehub.xml
index 547613fb67..547613fb67 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_telehub.xml
+++ b/indra/newview/skins/default/xui/en/floater_telehub.xml
diff --git a/indra/newview/skins/default/xui/en/floater_test_button.xml b/indra/newview/skins/default/xui/en/floater_test_button.xml
index 9bc05107a2..9bc05107a2 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_test_button.xml
+++ b/indra/newview/skins/default/xui/en/floater_test_button.xml
diff --git a/indra/newview/skins/default/xui/en/floater_test_checkbox.xml b/indra/newview/skins/default/xui/en/floater_test_checkbox.xml
index 95aaadfcf3..95aaadfcf3 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_test_checkbox.xml
+++ b/indra/newview/skins/default/xui/en/floater_test_checkbox.xml
diff --git a/indra/newview/skins/default/xui/en/floater_test_combobox.xml b/indra/newview/skins/default/xui/en/floater_test_combobox.xml
index 45e2e34da7..45e2e34da7 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_test_combobox.xml
+++ b/indra/newview/skins/default/xui/en/floater_test_combobox.xml
diff --git a/indra/newview/skins/default/xui/en/floater_test_inspectors.xml b/indra/newview/skins/default/xui/en/floater_test_inspectors.xml
index 209285da2e..209285da2e 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_test_inspectors.xml
+++ b/indra/newview/skins/default/xui/en/floater_test_inspectors.xml
diff --git a/indra/newview/skins/default/xui/en/floater_test_layout.xml b/indra/newview/skins/default/xui/en/floater_test_layout.xml
index 94f7e0b798..94f7e0b798 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_test_layout.xml
+++ b/indra/newview/skins/default/xui/en/floater_test_layout.xml
diff --git a/indra/newview/skins/default/xui/en/floater_test_layout_stacks.xml b/indra/newview/skins/default/xui/en/floater_test_layout_stacks.xml
index a04050e7eb..a04050e7eb 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_test_layout_stacks.xml
+++ b/indra/newview/skins/default/xui/en/floater_test_layout_stacks.xml
diff --git a/indra/newview/skins/default/xui/en/floater_test_line_editor.xml b/indra/newview/skins/default/xui/en/floater_test_line_editor.xml
index 2894ad2a32..2894ad2a32 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_test_line_editor.xml
+++ b/indra/newview/skins/default/xui/en/floater_test_line_editor.xml
diff --git a/indra/newview/skins/default/xui/en/floater_test_list_view.xml b/indra/newview/skins/default/xui/en/floater_test_list_view.xml
index 32ccc31dfd..32ccc31dfd 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_test_list_view.xml
+++ b/indra/newview/skins/default/xui/en/floater_test_list_view.xml
diff --git a/indra/newview/skins/default/xui/en/floater_test_navigation_bar.xml b/indra/newview/skins/default/xui/en/floater_test_navigation_bar.xml
index f4a50ecc96..f4a50ecc96 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_test_navigation_bar.xml
+++ b/indra/newview/skins/default/xui/en/floater_test_navigation_bar.xml
diff --git a/indra/newview/skins/default/xui/en/floater_test_radiogroup.xml b/indra/newview/skins/default/xui/en/floater_test_radiogroup.xml
index db14ecae83..db14ecae83 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_test_radiogroup.xml
+++ b/indra/newview/skins/default/xui/en/floater_test_radiogroup.xml
diff --git a/indra/newview/skins/default/xui/en/floater_test_slider.xml b/indra/newview/skins/default/xui/en/floater_test_slider.xml
index 20bd555a03..20bd555a03 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_test_slider.xml
+++ b/indra/newview/skins/default/xui/en/floater_test_slider.xml
diff --git a/indra/newview/skins/default/xui/en/floater_test_spinner.xml b/indra/newview/skins/default/xui/en/floater_test_spinner.xml
index acd49aa492..acd49aa492 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_test_spinner.xml
+++ b/indra/newview/skins/default/xui/en/floater_test_spinner.xml
diff --git a/indra/newview/skins/default/xui/en/floater_test_text_editor.xml b/indra/newview/skins/default/xui/en/floater_test_text_editor.xml
index e1fefc3631..e1fefc3631 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_test_text_editor.xml
+++ b/indra/newview/skins/default/xui/en/floater_test_text_editor.xml
diff --git a/indra/newview/skins/default/xui/en/floater_test_text_vertical_aligment.xml b/indra/newview/skins/default/xui/en/floater_test_text_vertical_aligment.xml
index d11373ce1d..d11373ce1d 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_test_text_vertical_aligment.xml
+++ b/indra/newview/skins/default/xui/en/floater_test_text_vertical_aligment.xml
diff --git a/indra/newview/skins/default/xui/en/floater_test_textbox.xml b/indra/newview/skins/default/xui/en/floater_test_textbox.xml
index 1d31fbd6dc..1d31fbd6dc 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_test_textbox.xml
+++ b/indra/newview/skins/default/xui/en/floater_test_textbox.xml
diff --git a/indra/newview/skins/default/xui/en/floater_test_toolbar.xml b/indra/newview/skins/default/xui/en/floater_test_toolbar.xml
index 067c1fed82..067c1fed82 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_test_toolbar.xml
+++ b/indra/newview/skins/default/xui/en/floater_test_toolbar.xml
diff --git a/indra/newview/skins/default/xui/en/floater_test_widgets.xml b/indra/newview/skins/default/xui/en/floater_test_widgets.xml
index 10854f5a49..10854f5a49 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_test_widgets.xml
+++ b/indra/newview/skins/default/xui/en/floater_test_widgets.xml
diff --git a/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml
index ffb8b842f0..6021ba0a5a 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml
+++ b/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml
@@ -134,6 +134,16 @@
top_delta="-25"
name="Pipette"
width="28" />
+ <text
+ follows="left|bottom"
+ height="20"
+ layout="topleft"
+ left="8"
+ name="preview_disabled"
+ top="266"
+ value="Preview Disabled"
+ visible="false"
+ width="120" />
<filter_editor
follows="left|top|right"
height="23"
diff --git a/indra/newview/skins/default/xui/en/floater_texture_fetch_debugger.xml b/indra/newview/skins/default/xui/en/floater_texture_fetch_debugger.xml
new file mode 100755
index 0000000000..1ea256b8b3
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_texture_fetch_debugger.xml
@@ -0,0 +1,428 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ legacy_header_height="18"
+ can_minimize="false"
+ height="600"
+ layout="topleft"
+ name="TexFetchDebugger"
+ help_topic="texfetchdebugger"
+ title="Texture Fetching Debugger"
+ width="540">
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="25"
+ layout="topleft"
+ left="10"
+ name="total_num_fetched_label"
+ top="30"
+ width="400">
+ 1, Total number of fetched textures: [NUM]
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="25"
+ layout="topleft"
+ left_delta="0"
+ name="total_num_fetching_requests_label"
+ top_delta="25"
+ width="400">
+ 2, Total number of fetching requests: [NUM]
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="25"
+ layout="topleft"
+ left_delta="0"
+ name="total_num_cache_hits_label"
+ top_delta="25"
+ width="400">
+ 3, Total number of cache hits: [NUM]
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="25"
+ layout="topleft"
+ left_delta="0"
+ name="total_num_visible_tex_label"
+ top_delta="25"
+ width="400">
+ 4, Total number of visible textures: [NUM]
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="25"
+ layout="topleft"
+ left_delta="0"
+ name="total_num_visible_tex_fetch_req_label"
+ top_delta="25"
+ width="450">
+ 5, Total number of visible texture fetching requests: [NUM]
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="25"
+ layout="topleft"
+ left_delta="0"
+ name="total_fetched_data_label"
+ top_delta="25"
+ width="530">
+ 6, Total number of fetched data: [SIZE1]KB, Decoded Data: [SIZE2]KB, [PIXEL]MPixels
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="25"
+ layout="topleft"
+ left_delta="0"
+ name="total_fetched_vis_data_label"
+ top_delta="25"
+ width="480">
+ 7, Total number of visible data: [SIZE1]KB, Decoded Data: [SIZE2]KB
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="25"
+ layout="topleft"
+ left_delta="0"
+ name="total_fetched_rendered_data_label"
+ top_delta="25"
+ width="530">
+ 8, Total number of rendered data: [SIZE1]KB, Decoded Data: [SIZE2]KB, [PIXEL]MPixels
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="25"
+ layout="topleft"
+ left_delta="0"
+ name="total_time_cache_read_label"
+ top_delta="25"
+ width="400">
+ 9, Total time on cache readings: [TIME] seconds
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="25"
+ layout="topleft"
+ left_delta="0"
+ name="total_time_cache_write_label"
+ top_delta="25"
+ width="400">
+ 10, Total time on cache writings: [TIME] seconds
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="25"
+ layout="topleft"
+ left_delta="0"
+ name="total_time_decode_label"
+ top_delta="25"
+ width="400">
+ 11, Total time on decodings: [TIME] seconds
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="25"
+ layout="topleft"
+ left_delta="0"
+ name="total_time_gl_label"
+ top_delta="25"
+ width="400">
+ 12, Total time on gl texture creation: [TIME] seconds
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="25"
+ layout="topleft"
+ left_delta="0"
+ name="total_time_http_label"
+ top_delta="25"
+ width="400">
+ 13, Total time on HTTP fetching: [TIME] seconds
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="25"
+ layout="topleft"
+ left_delta="0"
+ name="total_time_fetch_label"
+ top_delta="25"
+ width="400">
+ 14, Total time on entire fetching: [TIME] seconds
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="25"
+ layout="topleft"
+ left_delta="0"
+ name="total_time_refetch_vis_cache_label"
+ top_delta="25"
+ width="540">
+ 15, Refetching visibles from cache, Time: [TIME] seconds, Fetched: [SIZE]KB, [PIXEL]MPixels
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="25"
+ layout="topleft"
+ left_delta="0"
+ name="total_time_refetch_all_cache_label"
+ top_delta="25"
+ width="540">
+ 16, Refetching all textures from cache, Time: [TIME] seconds, Fetched: [SIZE]KB, [PIXEL]MPixels
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="25"
+ layout="topleft"
+ left_delta="0"
+ name="total_time_refetch_vis_http_label"
+ top_delta="25"
+ width="540">
+ 17, Refetching visibles from HTTP, Time: [TIME] seconds, Fetched: [SIZE]KB, [PIXEL]MPixels
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="25"
+ layout="topleft"
+ left_delta="0"
+ name="total_time_refetch_all_http_label"
+ top_delta="25"
+ width="540">
+ 18, Refetching all textures from HTTP, Time: [TIME] seconds, Fetched: [SIZE]KB, [PIXEL]MPixels
+ </text>
+ <spinner
+ decimal_digits="2"
+ follows="left|top"
+ height="20"
+ increment="0.01"
+ initial_value="1.0"
+ label="19, Ratio of Texel/Pixel:"
+ label_width="130"
+ layout="topleft"
+ left_delta="0"
+ max_val="10.0"
+ min_val="0.01"
+ name="texel_pixel_ratio"
+ top_delta="30"
+ width="200">
+ <spinner.commit_callback
+ function="TexFetchDebugger.ChangeTexelPixelRatio" />
+ </spinner>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="25"
+ layout="topleft"
+ left_delta="0"
+ name="texture_source_label"
+ top_delta="30"
+ width="110">
+ 20, Texture Source:
+ </text>
+ <radio_group
+ control_name="TextureFetchSource"
+ follows="top|left"
+ draw_border="false"
+ height="25"
+ layout="topleft"
+ left_pad="0"
+ name="texture_source"
+ top_delta="0"
+ width="264">
+ <radio_item
+ height="16"
+ label="Cache + HTTP"
+ layout="topleft"
+ left="3"
+ name="0"
+ top="0"
+ width="100" />
+ <radio_item
+ height="16"
+ label="HTTP Only"
+ layout="topleft"
+ left_delta="100"
+ name="1"
+ top_delta="0"
+ width="200" />
+ </radio_group>
+ <button
+ follows="left|top"
+ height="20"
+ label="Start"
+ layout="topleft"
+ left="10"
+ name="start_btn"
+ top_delta="20"
+ width="70">
+ <button.commit_callback
+ function="TexFetchDebugger.Start" />
+ </button>
+ <button
+ follows="left|top"
+ height="20"
+ label="Reset"
+ layout="topleft"
+ left_pad="7"
+ name="clear_btn"
+ top_delta="0"
+ width="70">
+ <button.commit_callback
+ function="TexFetchDebugger.Clear" />
+ </button>
+ <button
+ follows="left|top"
+ height="20"
+ label="Close"
+ layout="topleft"
+ left_pad="7"
+ name="close_btn"
+ top_delta="0"
+ width="70">
+ <button.commit_callback
+ function="TexFetchDebugger.Close" />
+ </button>
+ <button
+ follows="left|top"
+ height="20"
+ label="Cache Read"
+ layout="topleft"
+ left="10"
+ name="cacheread_btn"
+ top_delta="20"
+ width="80">
+ <button.commit_callback
+ function="TexFetchDebugger.CacheRead" />
+ </button>
+ <button
+ follows="left|top"
+ height="20"
+ label="Cache Write"
+ layout="topleft"
+ left_pad="7"
+ name="cachewrite_btn"
+ top_delta="0"
+ width="80">
+ <button.commit_callback
+ function="TexFetchDebugger.CacheWrite" />
+ </button>
+ <button
+ follows="left|top"
+ height="20"
+ label="HTTP"
+ layout="topleft"
+ left_pad="7"
+ name="http_btn"
+ top_delta="0"
+ width="70">
+ <button.commit_callback
+ function="TexFetchDebugger.HTTPLoad" />
+ </button>
+ <button
+ follows="left|top"
+ height="20"
+ label="Decode"
+ layout="topleft"
+ left_pad="7"
+ name="decode_btn"
+ top_delta="0"
+ width="70">
+ <button.commit_callback
+ function="TexFetchDebugger.Decode" />
+ </button>
+ <button
+ follows="left|top"
+ height="20"
+ label="GL Texture"
+ layout="topleft"
+ left_pad="7"
+ name="gl_btn"
+ top_delta="0"
+ width="70">
+ <button.commit_callback
+ function="TexFetchDebugger.GLTexture" />
+ </button>
+ <button
+ follows="left|top"
+ height="20"
+ label="Refetch Vis Cache"
+ layout="topleft"
+ left="10"
+ name="refetchviscache_btn"
+ top_delta="20"
+ width="120">
+ <button.commit_callback
+ function="TexFetchDebugger.RefetchVisCache" />
+ </button>
+ <button
+ follows="left|top"
+ height="20"
+ label="Refetch All Cache"
+ layout="topleft"
+ left_pad="7"
+ name="refetchallcache_btn"
+ top_delta="0"
+ width="120">
+ <button.commit_callback
+ function="TexFetchDebugger.RefetchAllCache" />
+ </button>
+ <button
+ follows="left|top"
+ height="20"
+ label="Refetch Vis HTTP"
+ layout="topleft"
+ left_pad="7"
+ name="refetchvishttp_btn"
+ top_delta="0"
+ width="120">
+ <button.commit_callback
+ function="TexFetchDebugger.RefetchVisHTTP" />
+ </button>
+ <button
+ follows="left|top"
+ height="20"
+ label="Refetch All HTTP"
+ layout="topleft"
+ left_pad="7"
+ name="refetchallhttp_btn"
+ top_delta="0"
+ width="120">
+ <button.commit_callback
+ function="TexFetchDebugger.RefetchAllHTTP" />
+ </button>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml
index e37740d20c..8b9733df17 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_tools.xml
+++ b/indra/newview/skins/default/xui/en/floater_tools.xml
@@ -2,7 +2,7 @@
<floater
positioning="cascading"
legacy_header_height="18"
- height="580"
+ height="590"
layout="topleft"
bg_opaque_image="Window_NoTitle_Foreground"
bg_alpha_image="Window_NoTitle_Background"
@@ -877,6 +877,14 @@
You can't modify these objects
</panel.string>
<panel.string
+ name="text modify info 5">
+ You can't modify this object across a region boundary
+ </panel.string>
+ <panel.string
+ name="text modify info 6">
+ You can't modify these objects across a region boundary
+ </panel.string>
+ <panel.string
name="text modify warning">
You must select entire object to set permissions
</panel.string>
@@ -941,7 +949,7 @@
left="10"
length="1"
follows="left|top"
- height="19"
+ height="29"
layout="topleft"
name="Creator:"
top_pad="7"
@@ -954,7 +962,7 @@
length="1"
follows="left|top"
left_pad="0"
- height="20"
+ height="29"
layout="topleft"
name="Creator Name"
top_delta="0"
@@ -969,10 +977,10 @@
length="1"
left="10"
follows="left|top"
- height="19"
+ height="29"
layout="topleft"
name="Owner:"
- top_pad="13"
+ top_pad="3"
width="90">
Owner:
</text>
@@ -981,7 +989,7 @@
type="string"
length="1"
follows="left|top"
- height="20"
+ height="29"
layout="topleft"
name="Owner Name"
left_pad="0"
@@ -1000,7 +1008,7 @@
left="10"
height="18"
name="Group:"
- top_pad="17"
+ top_pad="3"
width="75">
Group:
</text>
@@ -1029,7 +1037,7 @@
layout="topleft"
name="checkbox share with group"
tool_tip="Allow all members of the set group to share your modify permissions for this object. You must Deed to enable role restrictions."
- top_pad="10"
+ top_pad="5"
left="100"
width="87" />
<button
@@ -1051,7 +1059,7 @@
top_pad="10"
left="10"
name="label click action"
- width="118">
+ width="82">
Click to:
</text>
<combo_box
@@ -1059,7 +1067,7 @@
height="23"
layout="topleft"
name="clickaction"
- width="148"
+ width="130"
left_pad="10">
<combo_box.item
label="Touch (default)"
@@ -1092,19 +1100,39 @@
layout="topleft"
name="checkbox for sale"
left="7"
- width="100" />
-<!-- NEW SALE TYPE COMBO BOX -->
+ width="97" />
+ <!-- NEW PRICE SPINNER
+Objects are allowed to be for sale for L$0 to invoke buy UI behavior
+even though the user gets a free copy.
+-->
+ <spinner
+ follows="left|top"
+ decimal_digits="0"
+ increment="1"
+ left_pad="0"
+ control_name="Edit Cost"
+ name="Edit Cost"
+ label="L$"
+ label_width="15"
+ label_text.valign="center"
+ valign="center"
+ width="85"
+ min_val="0"
+ height="20"
+ max_val="999999999" />
+ <!-- NEW SALE TYPE COMBO BOX -->
<combo_box
- left_pad="10"
+ left_pad="8"
layout="topleft"
follows="left|top"
allow_text_entry="false"
height="23"
+ top_pad="-23"
initial_value="2"
max_chars="20"
mouse_opaque="true"
name="sale type"
- width="168">
+ width="89">
<combo_box.item
name="Copy"
label="Copy"
@@ -1118,31 +1146,13 @@
label="Original"
value="1" />
</combo_box>
-<!-- NEW PRICE SPINNER
-Objects are allowed to be for sale for L$0 to invoke buy UI behavior
-even though the user gets a free copy.
--->
- <spinner
- follows="left|top"
- decimal_digits="0"
- increment="1"
- top_pad="8"
- left="118"
- control_name="Edit Cost"
- name="Edit Cost"
- label="Price: L$"
- label_width="65"
- width="165"
- min_val="0"
- height="20"
- max_val="999999999" />
<check_box
height="15"
width="110"
top_pad="5"
label="Show in search"
layout="topleft"
- left="100"
+ left="7"
name="search_check"
tool_tip="Let people see this object in search results" />
<panel
@@ -1155,15 +1165,16 @@ even though the user gets a free copy.
name="perms_build"
left="0"
top_pad="4"
- height="105"
+ height="121"
width="290">
<text
type="string"
length="1"
left="10"
+ word_wrap="true"
top_pad="9"
text_color="EmphasisColor"
- height="16"
+ height="32"
follows="left|top|right"
layout="topleft"
name="perm_modify"
@@ -1233,7 +1244,7 @@ even though the user gets a free copy.
type="string"
text_color="EmphasisColor"
length="1"
- top="9"
+ top="23"
follows="left|top"
layout="topleft"
left="230"
@@ -1308,7 +1319,36 @@ even though the user gets a free copy.
F:
</text>
</panel>
- </panel>
+ <panel
+ border="false"
+ follows="left|top"
+ layout="topleft"
+ mouse_opaque="false"
+ name="pathfinding_attrs_panel"
+ left="0"
+ top_pad="0"
+ height="25"
+ width="290">
+ <text
+ type="string"
+ follows="left|top"
+ name="pathfinding_attributes_label"
+ top_pad="4"
+ width="150"
+ left="10">
+ Pathfinding attributes:
+ </text>
+ <text
+ type="string"
+ follows="left|top"
+ text_color="EmphasisColor"
+ name="pathfinding_attributes_value"
+ width="130"
+ word_wrap="false"
+ left_pad="0">
+ </text>
+ </panel>
+ </panel>
<!-- Object tab -->
<panel
border="false"
@@ -1355,8 +1395,7 @@ even though the user gets a free copy.
tool_tip="Causes object to not collide with other objects or avatars"
top_pad="0"
width="123" />
-
- <text
+ <text
type="string"
length="1"
follows="left|top"
@@ -2452,534 +2491,10 @@ even though the user gets a free copy.
width="132" />
</panel>
<panel
- border="false"
- follows="all"
- height="367"
label="Texture"
- layout="topleft"
- left_delta="0"
- mouse_opaque="false"
help_topic="toolbox_texture_tab"
name="Texture"
- top_delta="0"
- width="295">
- <panel.string
- name="string repeats per meter">
- Repeats Per Meter
- </panel.string>
- <panel.string
- name="string repeats per face">
- Repeats Per Face
- </panel.string>
- <texture_picker
- can_apply_immediately="true"
- default_image_name="Default"
- fallback_image="locked_image.j2c"
- follows="left|top"
- height="80"
- label="Texture"
- layout="topleft"
- left="10"
- name="texture control"
- tool_tip="Click to choose a picture"
- top="8"
- width="64" />
- <color_swatch
- can_apply_immediately="true"
- follows="left|top"
- height="80"
- label="Color"
- layout="topleft"
- left_pad="15"
- name="colorswatch"
- tool_tip="Click to open color picker"
- top_delta="0"
- width="64" />
- <text
- type="string"
- length="1"
- follows="left|top"
- height="10"
- layout="topleft"
- left_pad="15"
- name="color trans"
- text_readonly_color="LabelDisabledColor"
- top="6"
- width="110">
- Transparency %
- </text>
- <spinner
- decimal_digits="0"
- follows="left|top"
- height="19"
- increment="2"
- initial_value="0"
- layout="topleft"
- left_delta="0"
- max_val="100"
- name="ColorTrans"
- top_pad="4"
- width="80" />
- <text
- type="string"
- length="1"
- follows="left|top"
- height="10"
- layout="topleft"
- left_delta="0"
- name="glow label"
- text_readonly_color="LabelDisabledColor"
- top_pad="8"
- width="80">
- Glow
- </text>
- <spinner
- decimal_digits="2"
- follows="left|top"
- height="19"
- initial_value="0"
- layout="topleft"
- left_delta="0"
- name="glow"
- top_pad="4"
- width="80" />
- <check_box
- height="19"
- label="Full Bright"
- layout="topleft"
- left_delta="-5"
- name="checkbox fullbright"
- top_pad="4"
- width="81" />
- <text
- type="string"
- length="1"
- follows="left|top"
- height="10"
- layout="topleft"
- left="10"
- name="tex gen"
- text_readonly_color="LabelDisabledColor"
- top_pad="5"
- width="90">
- Mapping
- </text>
- <combo_box
- height="23"
- layout="topleft"
- left_delta="0"
- name="combobox texgen"
- top_pad="4"
- width="90">
- <combo_box.item
- label="Default"
- name="Default"
- value="Default" />
- <combo_box.item
- label="Planar"
- name="Planar"
- value="Planar" />
- </combo_box>
- <text
- type="string"
- length="1"
- follows="left|top"
- height="10"
- layout="topleft"
- name="label shininess"
- left_pad="4"
- text_readonly_color="LabelDisabledColor"
- top_pad="-37"
- width="90">
- Shininess
- </text>
- <combo_box
- height="23"
- layout="topleft"
- left_delta="0"
- name="combobox shininess"
- top_pad="4"
- width="90">
- <combo_box.item
- label="None"
- name="None"
- value="None" />
- <combo_box.item
- label="Low"
- name="Low"
- value="Low" />
- <combo_box.item
- label="Medium"
- name="Medium"
- value="Medium" />
- <combo_box.item
- label="High"
- name="High"
- value="High" />
- </combo_box>
- <text
- type="string"
- length="1"
- follows="left|top"
- height="10"
- layout="topleft"
- left_pad="4"
- name="label bumpiness"
- text_readonly_color="LabelDisabledColor"
- top_pad="-37"
- width="90">
- Bumpiness
- </text>
- <combo_box
- height="23"
- layout="topleft"
- left_delta="0"
- name="combobox bumpiness"
- top_pad="4"
- width="90">
- <combo_box.item
- label="None"
- name="None"
- value="None" />
- <combo_box.item
- label="Brightness"
- name="Brightness"
- value="Brightness" />
- <combo_box.item
- label="Darkness"
- name="Darkness"
- value="Darkness" />
- <combo_box.item
- label="woodgrain"
- name="woodgrain"
- value="woodgrain" />
- <combo_box.item
- label="bark"
- name="bark"
- value="bark" />
- <combo_box.item
- label="bricks"
- name="bricks"
- value="bricks" />
- <combo_box.item
- label="checker"
- name="checker"
- value="checker" />
- <combo_box.item
- label="concrete"
- name="concrete"
- value="concrete" />
- <combo_box.item
- label="crustytile"
- name="crustytile"
- value="crustytile" />
- <combo_box.item
- label="cutstone"
- name="cutstone"
- value="cutstone" />
- <combo_box.item
- label="discs"
- name="discs"
- value="discs" />
- <combo_box.item
- label="gravel"
- name="gravel"
- value="gravel" />
- <combo_box.item
- label="petridish"
- name="petridish"
- value="petridish" />
- <combo_box.item
- label="siding"
- name="siding"
- value="siding" />
- <combo_box.item
- label="stonetile"
- name="stonetile"
- value="stonetile" />
- <combo_box.item
- label="stucco"
- name="stucco"
- value="stucco" />
- <combo_box.item
- label="suction"
- name="suction"
- value="suction" />
- <combo_box.item
- label="weave"
- name="weave"
- value="weave" />
- </combo_box>
- <!--
- <line_editor
- bevel_style="in"
- border_style="line"
- border_thickness="1"
- follows="left|top"
- height="16"
- layout="topleft"
- left="10"
- max_length_bytes="63"
- name="Home Url"
- select_on_focus="true"
- top="134"
- width="250" />
- <check_box
- height="16"
- label="Media Face"
- layout="topleft"
- left_delta="0"
- name="has media"
- top_pad="6"
- width="70" />
- <button
- follows="left|top"
- font="SansSerifSmall"
- height="20"
- label="Set Media Info"
- label_selected="Set Media Info"
- layout="topleft"
- left_pad="60"
- name="media info set"
- top_delta="-4"
- width="120" />
--->
- <check_box
- follows="top|left"
- height="16"
- initial_value="false"
- label="Align planar faces"
- layout="topleft"
- left="17"
- name="checkbox planar align"
- tool_tip="Align textures on all selected faces with the last selected face. Requires Planar texture mapping."
- top_delta="26"
- width="140" />
- <text
- type="string"
- length="1"
- follows="left|top"
- height="10"
- layout="topleft"
- left="10"
- name="rpt"
- text_readonly_color="LabelDisabledColor"
- top_pad="2"
- width="140">
- Repeats / Face
- </text>
- <spinner
- follows="left|top"
- height="19"
- initial_value="0"
- label="Horizontal (U)"
- label_width="125"
- layout="topleft"
- left="20"
- max_val="100"
- name="TexScaleU"
- top_pad="5"
- width="185" />
- <check_box
- height="19"
- label="Flip"
- layout="topleft"
- left_pad="5"
- name="checkbox flip s"
- top_delta="0"
- width="70" />
- <spinner
- follows="left|top"
- height="19"
- initial_value="0"
- label="Vertical (V)"
- label_width="125"
- layout="topleft"
- left="20"
- max_val="100"
- name="TexScaleV"
- width="185" />
- <check_box
- height="19"
- label="Flip"
- layout="topleft"
- left_pad="5"
- name="checkbox flip t"
- top_delta="0"
- width="70" />
- <spinner
- decimal_digits="2"
- follows="left|top"
- height="19"
- increment="1"
- initial_value="0"
- label="RotationËš"
- layout="topleft"
- label_width="135"
- left="10"
- max_val="9999"
- min_val="-9999"
- name="TexRot"
- width="195" />
-
- <spinner
- decimal_digits="1"
- follows="left|top"
- height="23"
- initial_value="1"
- label="Repeats / Meter"
- layout="topleft"
- label_width="135"
- left="10"
- max_val="10"
- min_val="0.1"
- name="rptctrl"
- width="195" />
- <button
- follows="left|top"
- height="23"
- label="Apply"
- label_selected="Apply"
- layout="topleft"
- left_pad="5"
- name="button apply"
- width="75" />
- <text
- type="string"
- length="1"
- follows="left|top"
- height="10"
- layout="topleft"
- left="10"
- name="tex offset"
- text_readonly_color="LabelDisabledColor"
- width="200">
- Texture Offset
- </text>
- <spinner
- follows="left|top"
- height="19"
- initial_value="0"
- label="Horizontal (U)"
- label_width="125"
- layout="topleft"
- left="20"
- min_val="-1"
- name="TexOffsetU"
- width="185" />
- <spinner
- follows="left|top"
- height="19"
- initial_value="0"
- label="Vertical (V)"
- label_width="125"
- layout="topleft"
- left_delta="0"
- min_val="-1"
- name="TexOffsetV"
- top_pad="1"
- width="185" />
- <panel
- border="false"
- follows="left|top"
- layout="topleft"
- mouse_opaque="false"
- background_visible="true"
- bg_alpha_color="DkGray"
- name="Add_Media"
- left="0"
- height="47"
- width="290">
- <text
- type="string"
- length="1"
- follows="left|top"
- height="18"
- layout="topleft"
- left="10"
- top_pad="3"
- name="media_tex"
- width="190">
- Media
- </text>
- <button
- follows="top|left"
- height="18"
- image_selected="AddItem_Press"
- image_unselected="AddItem_Off"
- image_disabled="AddItem_Disabled"
- layout="topleft"
- left_pad="0"
- name="add_media"
- tab_stop="false"
- top_delta="0"
- tool_tip="Add Media"
- width="18">
- <button.commit_callback
- function="BuildTool.AddMedia"/>
- </button>
- <button
- follows="top|left"
- height="18"
- image_selected="TrashItem_Press"
- image_unselected="TrashItem_Off"
- layout="topleft"
- left_pad="5"
- name="delete_media"
- tool_tip="Delete this media texture"
- top_delta="0"
- width="18">
- <button.commit_callback
- function="BuildTool.DeleteMedia"/>
- </button>
- <button
- follows="top|left"
- tool_tip="Edit this Media"
- height="12"
- image_disabled="Icon_Gear_Background"
- image_selected="Icon_Gear_Press"
- image_unselected="Icon_Gear_Foreground"
- layout="topleft"
- left_pad="10"
- name="edit_media"
- top_delta="3"
- width="12">
- <button.commit_callback
- function="BuildTool.EditMedia"/>
- </button>
- <text
- follows="left|top|right"
- height="9"
- layout="topleft"
- left="10"
- use_ellipses="true"
- read_only="true"
- name="media_info"
- width="280" />
- <web_browser
- visible="false"
- enabled="false"
- border_visible="true"
- bottom_delta="0"
- follows="top|left"
- left="0"
- name="title_media"
- width="4"
- height="4"
- start_url="about:blank"
- decouple_texture_size="true" />
- <button
- follows="right|top"
- height="22"
- label="Align"
- label_selected="Align Media"
- layout="topleft"
- right="-16"
- name="button align"
- top_delta="-4"
- tool_tip="Align media texture (must load first)"
- width="80" />
- </panel>
+ filename="panel_tools_texture.xml">
</panel>
<panel
border="false"
diff --git a/indra/newview/skins/default/xui/en/floater_top_objects.xml b/indra/newview/skins/default/xui/en/floater_top_objects.xml
index 4dfdcd15c7..0b71177345 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_top_objects.xml
+++ b/indra/newview/skins/default/xui/en/floater_top_objects.xml
@@ -2,7 +2,7 @@
<floater
legacy_header_height="18"
can_resize="true"
- height="350"
+ height="372"
layout="topleft"
min_height="300"
min_width="450"
@@ -23,10 +23,6 @@
Time
</floater.string>
<floater.string
- name="scripts_mono_time_label">
- Mono Time
- </floater.string>
- <floater.string
name="top_colliders_title">
Top Colliders
</floater.string>
@@ -68,31 +64,35 @@
<scroll_list.columns
label="Score"
name="score"
- width="55" />
+ width="45" />
<scroll_list.columns
label="Name"
name="name"
- width="140" />
+ width="130" />
<scroll_list.columns
label="Owner"
name="owner"
- width="105" />
+ width="100" />
<scroll_list.columns
label="Location"
name="location"
- width="130" />
+ width="120" />
+ <scroll_list.columns
+ label="Parcel"
+ name="parcel"
+ width="120" />
<scroll_list.columns
label="Time"
name="time"
- width="150" />
- <scroll_list.columns
- label="Mono Time"
- name="mono_time"
- width="100" />
+ width="130" />
<scroll_list.columns
label="URLs"
name="URLs"
- width="100" />
+ width="40" />
+ <scroll_list.columns
+ label="Memory (KB)"
+ name="memory"
+ width="40" />
<scroll_list.commit_callback
function="TopObjects.CommitObjectsList" />
</scroll_list>
@@ -193,6 +193,38 @@
<button.commit_callback
function="TopObjects.GetByOwnerName" />
</button>
+ <text
+ type="string"
+ length="1"
+ follows="left|bottom"
+ height="20"
+ layout="topleft"
+ left="10"
+ top_pad="5"
+ name="parcel_name_text"
+ width="107">
+ Parcel:
+ </text>
+ <line_editor
+ follows="left|bottom|right"
+ height="20"
+ layout="topleft"
+ left_pad="3"
+ name="parcel_name_editor"
+ top_delta="-3"
+ width="568" />
+ <button
+ follows="bottom|right"
+ height="23"
+ label="Filter"
+ layout="topleft"
+ left_pad="5"
+ name="filter_parcel_btn"
+ top_delta="0"
+ width="100">
+ <button.commit_callback
+ function="TopObjects.GetByParcelName" />
+ </button>
<button
follows="bottom|right"
height="22"
diff --git a/indra/newview/skins/default/xui/en/floater_tos.xml b/indra/newview/skins/default/xui/en/floater_tos.xml
index af1617eb39..af1617eb39 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_tos.xml
+++ b/indra/newview/skins/default/xui/en/floater_tos.xml
diff --git a/indra/newview/skins/default/xui/en/floater_toybox.xml b/indra/newview/skins/default/xui/en/floater_toybox.xml
index d8211c24a7..d8211c24a7 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_toybox.xml
+++ b/indra/newview/skins/default/xui/en/floater_toybox.xml
diff --git a/indra/newview/skins/default/xui/en/floater_translation_settings.xml b/indra/newview/skins/default/xui/en/floater_translation_settings.xml
index a212ce7889..a212ce7889 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_translation_settings.xml
+++ b/indra/newview/skins/default/xui/en/floater_translation_settings.xml
diff --git a/indra/newview/skins/default/xui/en/floater_ui_preview.xml b/indra/newview/skins/default/xui/en/floater_ui_preview.xml
index 06d4327293..eb01294831 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_ui_preview.xml
+++ b/indra/newview/skins/default/xui/en/floater_ui_preview.xml
@@ -5,7 +5,7 @@
height="640"
layout="topleft"
min_height="230"
- min_width="650"
+ min_width="750"
name="gui_preview_tool"
help_topic="gui_preview_tool"
single_instance="true"
diff --git a/indra/newview/skins/default/xui/en/floater_url_entry.xml b/indra/newview/skins/default/xui/en/floater_url_entry.xml
index 29fb29fabf..29fb29fabf 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_url_entry.xml
+++ b/indra/newview/skins/default/xui/en/floater_url_entry.xml
diff --git a/indra/newview/skins/default/xui/en/floater_voice_chat_volume.xml b/indra/newview/skins/default/xui/en/floater_voice_chat_volume.xml
new file mode 100755
index 0000000000..5c71fd3bc6
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_voice_chat_volume.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+
+<floater
+ legacy_header_height="25"
+ bevel_style="in"
+ bg_opaque_image="Inspector_Background"
+ can_close="false"
+ can_minimize="false"
+ height="90"
+ layout="topleft"
+ name="floater_voice_volume"
+ single_instance="true"
+ sound_flags="0"
+ title="VOICE CHAT VOLUME"
+ visible="true"
+ width="245">
+ <slider
+ control_name="AudioLevelVoice"
+ disabled_control="MuteAudio"
+ follows="left|top"
+ height="16"
+ increment="0.025"
+ initial_value="0.5"
+ label="Voice Chat"
+ label_width="50"
+ layout="topleft"
+ left="15"
+ top="50"
+ name="chat_voice_volume"
+ show_text="false"
+ slider_label.halign="right"
+ volume="true"
+ width="200">
+ </slider>
+ <button
+ control_name="MuteVoice"
+ disabled_control="MuteAudio"
+ follows="top|left"
+ height="16"
+ image_selected="AudioMute_Off"
+ image_unselected="Audio_Off"
+ is_toggle="true"
+ layout="topleft"
+ left_pad="5"
+ name="mute_audio"
+ tab_stop="false"
+ width="16" />
+</floater> \ No newline at end of file
diff --git a/indra/newview/skins/default/xui/en/floater_voice_controls.xml b/indra/newview/skins/default/xui/en/floater_voice_controls.xml
deleted file mode 100644
index dce2720cf8..0000000000
--- a/indra/newview/skins/default/xui/en/floater_voice_controls.xml
+++ /dev/null
@@ -1,155 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<floater
- positioning="cascading"
- can_resize="true"
- can_minimize="true"
- can_close="true"
- chrome="true"
- height="205"
- layout="topleft"
- min_height="124"
- min_width="190"
- name="floater_voice_controls"
- help_topic="floater_voice_controls"
- title="VOICE CONTROLS"
- save_dock_state="true"
- save_visibility="true"
- save_rect="true"
- single_instance="true"
- width="282">
- <string
- name="title_nearby">
- VOICE SETTINGS
- </string>
- <string
- name="title_group">
- GROUP CALL WITH [GROUP]
- </string>
- <string
- name="title_adhoc">
- CONFERENCE CALL
- </string>
- <string
- name="title_peer_2_peer">
- CALL WITH [NAME]
- </string>
- <string
- name="no_one_near">
- No one near has voice enabled
- </string>
- <layout_stack
- clip="false"
- follows="all"
- height="189"
- layout="topleft"
- left="10"
- mouse_opaque="false"
- name="my_call_stack"
- orientation="vertical"
- width="263">
- <layout_panel
- follows="top|left|right"
- auto_resize="false"
- layout="topleft"
- min_height="20"
- height="20"
- name="my_panel">
- <avatar_icon
- enabled="false"
- follows="left|top"
- height="18"
- default_icon_name="Generic_Person"
- layout="topleft"
- left="5"
- name="user_icon"
- top="0"
- width="18" />
- <text
- follows="top|left|right"
- font="SansSerifSmallBold"
- height="16"
- layout="topleft"
- left_pad="10"
- name="user_text"
- text_color="White"
- top="4"
- use_ellipses="true"
- value="My Avatar:"
- width="210" />
- <output_monitor
- auto_update="true"
- draw_border="false"
- follows="top|right"
- height="16"
- layout="topleft"
- right="-3"
- name="speaking_indicator"
- left_pad="5"
- visible="true"
- width="20" />
- </layout_panel>
- <layout_panel name="leave_call_panel" height="26" min_height="26" auto_resize="false">
- <layout_stack
- clip="true"
- follows="left|top|right"
- height="26"
- layout="topleft"
- mouse_opaque="false"
- name="voice_effect_and_leave_call_stack"
- orientation="horizontal"
- width="262">
- <layout_panel
- height="26"
- width="200">
- <panel
- class="panel_voice_effect"
- name="panel_voice_effect"
- visiblity_control="VoiceMorphingEnabled"
- filename="panel_voice_effect.xml" />
- </layout_panel>
- <layout_panel
- auto_resize="false"
- follows="top|right"
- height="23"
- visible="true"
- layout="topleft"
- name="leave_call_btn_panel"
- width="100">
- <button
- follows="right|top"
- height="23"
- label="Leave Call"
- name="leave_call_btn"
- width="100" />
- </layout_panel>
- </layout_stack>
- </layout_panel>
- <layout_panel
- follows="all"
- layout="topleft"
- left="2"
- top_pad="0"
- height="132"
- name="callers_panel"
- auto_resize="true"
- width="280">
- <avatar_list
- follows="all"
- height="132"
- ignore_online_status="true"
- layout="topleft"
- multi_select="true"
- name="speakers_list"
- width="280" />
- <panel
- filename="panel_avatar_list_item.xml"
- follows="left|right|top"
- height="24"
- layout="topleft"
- left="0"
- name="non_avatar_caller"
- top="10"
- width="276" />
- </layout_panel>
- </layout_stack>
-</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_voice_effect.xml b/indra/newview/skins/default/xui/en/floater_voice_effect.xml
index 35cb2670d0..146c3d7e30 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_voice_effect.xml
+++ b/indra/newview/skins/default/xui/en/floater_voice_effect.xml
@@ -5,12 +5,13 @@
height="500"
name="voice_effects"
help_topic="voice_effects"
- title="VOICE MORPHING"
+ title="VOICE MORPHING PREVIEW"
background_visible="true"
label="Places"
layout="topleft"
min_height="360"
min_width="200"
+ save_rect="true"
width="300">
<string name="no_voice_effect">
(No Voice Morph)
diff --git a/indra/newview/skins/default/xui/en/floater_voice_volume.xml b/indra/newview/skins/default/xui/en/floater_voice_volume.xml
new file mode 100755
index 0000000000..9346295d5b
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_voice_volume.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<!--
+ Not can_close / no title to avoid window chrome
+ Single instance - only have one at a time, recycle it each spawn
+-->
+<floater
+ legacy_header_height="25"
+ bevel_style="in"
+ bg_opaque_image="Inspector_Background"
+ can_close="false"
+ can_minimize="false"
+ height="90"
+ layout="topleft"
+ name="floater_voice_volume"
+ single_instance="true"
+ sound_flags="0"
+ title="VOICE VOLUME"
+ visible="true"
+ width="245">
+ <text
+ follows="top|left|right"
+ font="SansSerifSmall"
+ height="21"
+ left="10"
+ name="avatar_name"
+ parse_urls="false"
+ top="35"
+ text_color="White"
+ translate="false"
+ use_ellipses="true"
+ value="TestString PleaseIgnore"
+ width="225" />
+ <slider
+ follows="top|left"
+ height="23"
+ increment="0.01"
+ left="1"
+ max_val="0.95"
+ min_val="0.05"
+ name="volume_slider"
+ show_text="false"
+ tool_tip="Voice volume"
+ top_pad="0"
+ value="0.5"
+ width="200" />
+ <button
+ follows="top|left"
+ height="16"
+ image_disabled="Audio_Off"
+ image_disabled_selected="AudioMute_Off"
+ image_hover_selected="AudioMute_Over"
+ image_selected="AudioMute_Off"
+ image_unselected="Audio_Off"
+ is_toggle="true"
+ left_pad="0"
+ top_delta="4"
+ name="mute_btn"
+ width="16" />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_web_content.xml b/indra/newview/skins/default/xui/en/floater_web_content.xml
index cea10adca8..a80440e844 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_web_content.xml
+++ b/indra/newview/skins/default/xui/en/floater_web_content.xml
@@ -125,10 +125,10 @@
<icon
name="media_secure_lock_flag"
height="16"
- follows="top|right"
+ follows="top|left"
image_name="Lock2"
layout="topleft"
- left_delta="620"
+ left_delta="2"
top_delta="2"
visible="false"
tool_tip="Secured Browsing"
diff --git a/indra/newview/skins/default/xui/en/floater_web_profile.xml b/indra/newview/skins/default/xui/en/floater_web_profile.xml
index d0225f78a9..d0225f78a9 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_web_profile.xml
+++ b/indra/newview/skins/default/xui/en/floater_web_profile.xml
diff --git a/indra/newview/skins/default/xui/en/floater_whitelist_entry.xml b/indra/newview/skins/default/xui/en/floater_whitelist_entry.xml
index 897d959b98..897d959b98 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_whitelist_entry.xml
+++ b/indra/newview/skins/default/xui/en/floater_whitelist_entry.xml
diff --git a/indra/newview/skins/default/xui/en/floater_window_size.xml b/indra/newview/skins/default/xui/en/floater_window_size.xml
index 115fe413f3..115fe413f3 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_window_size.xml
+++ b/indra/newview/skins/default/xui/en/floater_window_size.xml
diff --git a/indra/newview/skins/default/xui/en/floater_world_map.xml b/indra/newview/skins/default/xui/en/floater_world_map.xml
index 83407069d2..83407069d2 100644..100755
--- a/indra/newview/skins/default/xui/en/floater_world_map.xml
+++ b/indra/newview/skins/default/xui/en/floater_world_map.xml
diff --git a/indra/newview/skins/default/xui/en/fonts.xml b/indra/newview/skins/default/xui/en/fonts.xml
index ebbb53729d..ebbb53729d 100644..100755
--- a/indra/newview/skins/default/xui/en/fonts.xml
+++ b/indra/newview/skins/default/xui/en/fonts.xml
diff --git a/indra/newview/skins/default/xui/en/inspect_avatar.xml b/indra/newview/skins/default/xui/en/inspect_avatar.xml
index bc3bcd331b..ef4f19cd4c 100644..100755
--- a/indra/newview/skins/default/xui/en/inspect_avatar.xml
+++ b/indra/newview/skins/default/xui/en/inspect_avatar.xml
@@ -2,14 +2,14 @@
<!--
Not can_close / no title to avoid window chrome
Single instance - only have one at a time, recycle it each spawn
--->
+-->
<floater
legacy_header_height="25"
bevel_style="in"
bg_opaque_image="Inspector_Background"
can_close="false"
can_minimize="false"
- height="164"
+ height="160"
layout="topleft"
name="inspect_avatar"
single_instance="true"
@@ -98,13 +98,13 @@
follows="top|left"
height="23"
increment="0.01"
- left="1"
+ left="10"
max_val="0.95"
min_val="0.05"
name="volume_slider"
show_text="false"
tool_tip="Voice volume"
- top_pad="0"
+ top_pad="5"
value="0.5"
width="200" />
<button
@@ -116,10 +116,21 @@
image_selected="AudioMute_Off"
image_unselected="Audio_Off"
is_toggle="true"
- left_pad="0"
+ left_pad="5"
top_delta="4"
name="mute_btn"
width="16" />
+ <text
+ follows="top|left"
+ height="16"
+ left="8"
+ name="avatar_profile_link"
+ font="SansSerifSmall"
+ text_color="White"
+ top_pad="5"
+ translate="false"
+ value="[[LINK] View full profile]"
+ width="175" />
<avatar_icon
follows="top|left"
height="38"
@@ -130,83 +141,4 @@
name="avatar_icon"
top="10"
width="38" />
-<!-- Overlapping buttons for default actions
- llinspectavatar.cpp makes visible the most likely default action
--->
- <button
- follows="top|left"
- height="20"
- label="Add Friend"
- left="8"
- top="135"
- name="add_friend_btn"
- width="90" />
- <button
- follows="top|left"
- height="20"
- label="IM"
- left_delta="0"
- top_delta="0"
- name="im_btn"
- width="80"
- commit_callback.function="InspectAvatar.IM"/>
- <button
- follows="top|left"
- height="20"
- label="Profile"
- layout="topleft"
- name="view_profile_btn"
- left_delta="96"
- top_delta="0"
- tab_stop="false"
- width="80" />
- <!-- gear buttons here -->
- <menu_button
- follows="top|left"
- height="20"
- layout="topleft"
- image_overlay="OptionsMenu_Off"
- menu_filename="menu_inspect_avatar_gear.xml"
- name="gear_btn"
- right="-5"
- top_delta="0"
- width="35" />
- <menu_button
- follows="top|left"
- height="20"
- image_overlay="OptionsMenu_Off"
- menu_filename="menu_inspect_self_gear.xml"
- name="gear_self_btn"
- right="-5"
- top_delta="0"
- width="35" />
- <panel
- follows="top|left"
- top="164"
- left="0"
- height="60"
- width="228"
- visible="false"
- background_visible="true"
- name="moderator_panel"
- background_opaque="true"
- bg_opaque_color="MouseGray">
- <button
- name="disable_voice"
- label="Disable Voice"
- top="20"
- width="95"
- height="20"
- left="10"
- commit_callback.function="InspectAvatar.DisableVoice"/>
- <button
- name="enable_voice"
- label="Enable Voice"
- top="20"
- width="95"
- height="20"
- left="10"
- visible="false"
- commit_callback.function="InspectAvatar.EnableVoice"/>
- </panel>
</floater>
diff --git a/indra/newview/skins/default/xui/en/inspect_group.xml b/indra/newview/skins/default/xui/en/inspect_group.xml
index 324ff3eabd..324ff3eabd 100644..100755
--- a/indra/newview/skins/default/xui/en/inspect_group.xml
+++ b/indra/newview/skins/default/xui/en/inspect_group.xml
diff --git a/indra/newview/skins/default/xui/en/inspect_object.xml b/indra/newview/skins/default/xui/en/inspect_object.xml
index bfeb8fc470..bfeb8fc470 100644..100755
--- a/indra/newview/skins/default/xui/en/inspect_object.xml
+++ b/indra/newview/skins/default/xui/en/inspect_object.xml
diff --git a/indra/newview/skins/default/xui/en/inspect_remote_object.xml b/indra/newview/skins/default/xui/en/inspect_remote_object.xml
index e83257d2a0..e83257d2a0 100644..100755
--- a/indra/newview/skins/default/xui/en/inspect_remote_object.xml
+++ b/indra/newview/skins/default/xui/en/inspect_remote_object.xml
diff --git a/indra/newview/skins/default/xui/en/inspect_toast.xml b/indra/newview/skins/default/xui/en/inspect_toast.xml
index 0221397a8c..0221397a8c 100644..100755
--- a/indra/newview/skins/default/xui/en/inspect_toast.xml
+++ b/indra/newview/skins/default/xui/en/inspect_toast.xml
diff --git a/indra/newview/skins/default/xui/en/inspector_info_ctrl.xml b/indra/newview/skins/default/xui/en/inspector_info_ctrl.xml
index a7ecc39ed8..a7ecc39ed8 100644..100755
--- a/indra/newview/skins/default/xui/en/inspector_info_ctrl.xml
+++ b/indra/newview/skins/default/xui/en/inspector_info_ctrl.xml
diff --git a/indra/newview/skins/default/xui/en/language_settings.xml b/indra/newview/skins/default/xui/en/language_settings.xml
index 51779e4bfd..51779e4bfd 100644..100755
--- a/indra/newview/skins/default/xui/en/language_settings.xml
+++ b/indra/newview/skins/default/xui/en/language_settings.xml
diff --git a/indra/newview/skins/default/xui/en/main_view.xml b/indra/newview/skins/default/xui/en/main_view.xml
index a87027a113..a87027a113 100644..100755
--- a/indra/newview/skins/default/xui/en/main_view.xml
+++ b/indra/newview/skins/default/xui/en/main_view.xml
diff --git a/indra/newview/skins/default/xui/en/menu_add_wearable_gear.xml b/indra/newview/skins/default/xui/en/menu_add_wearable_gear.xml
index 5033ea9546..5033ea9546 100644..100755
--- a/indra/newview/skins/default/xui/en/menu_add_wearable_gear.xml
+++ b/indra/newview/skins/default/xui/en/menu_add_wearable_gear.xml
diff --git a/indra/newview/skins/default/xui/en/menu_attachment_other.xml b/indra/newview/skins/default/xui/en/menu_attachment_other.xml
index b46b62ec4d..ba91b0b5d9 100644..100755
--- a/indra/newview/skins/default/xui/en/menu_attachment_other.xml
+++ b/indra/newview/skins/default/xui/en/menu_attachment_other.xml
@@ -79,6 +79,14 @@
<menu_item_call.on_visible
function="IsGodCustomerService"/>
</menu_item_call>
+ <menu_item_call
+ label="Dump XML"
+ name="Dump XML">
+ <menu_item_call.on_click
+ function="Advanced.AppearanceToXML" />
+ <menu_item_call.on_visible
+ function="Advanced.EnableAppearanceToXML"/>
+ </menu_item_call>
<menu_item_call
label="Zoom In"
name="Zoom In">
@@ -104,4 +112,50 @@
<menu_item_call.on_enable
function="Object.EnableInspect" />
</menu_item_call>
+
+ <menu_item_separator />
+
+ <menu_item_check
+ name="Normal"
+ label="Normal Rendering">
+ <menu_item_check.on_check
+ function="Avatar.CheckImpostorMode"
+ parameter="0" />
+ <menu_item_check.on_click
+ function="Avatar.SetImpostorMode"
+ parameter="0" />
+ </menu_item_check>
+ <menu_item_check
+ name="Always use impostor"
+ label="Always use impostor">
+ <menu_item_check.on_check
+ function="Avatar.CheckImpostorMode"
+ parameter="1" />
+ <menu_item_check.on_click
+ function="Avatar.SetImpostorMode"
+ parameter="1" />
+ </menu_item_check>
+ <menu_item_check
+ name="Never use impostor"
+ label="Never use impostor">
+ <menu_item_check.on_check
+ function="Avatar.CheckImpostorMode"
+ parameter="2" />
+ <menu_item_check.on_click
+ function="Avatar.SetImpostorMode"
+ parameter="2" />
+ </menu_item_check>
+
+ <menu_item_separator
+ layout="topleft" name="Impostor seperator"/>
+
+ <menu_item_call
+ enabled="false"
+ label="Block Particle Owner"
+ name="Mute Particle">
+ <menu_item_call.on_click
+ function="Particle.Mute" />
+ <menu_item_call.on_enable
+ function="EnableMuteParticle" />
+ </menu_item_call>
</context_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_attachment_self.xml b/indra/newview/skins/default/xui/en/menu_attachment_self.xml
index b8128da358..bcbc8d5b86 100644..100755
--- a/indra/newview/skins/default/xui/en/menu_attachment_self.xml
+++ b/indra/newview/skins/default/xui/en/menu_attachment_self.xml
@@ -123,6 +123,14 @@ name="Edit Outfit">
<menu_item_call.on_visible
function="IsGodCustomerService"/>
</menu_item_call>
+ <menu_item_call
+ label="Dump XML"
+ name="Dump XML">
+ <menu_item_call.on_click
+ function="Advanced.AppearanceToXML" />
+ <menu_item_call.on_visible
+ function="Advanced.EnableAppearanceToXML"/>
+ </menu_item_call>
<menu_item_separator
layout="topleft" />
<menu_item_call
@@ -135,4 +143,15 @@ name="Edit Outfit">
<menu_item_call.on_enable
function="Attachment.EnableDrop" />
</menu_item_call>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_call
+ enabled="false"
+ label="Block Particle Owner"
+ name="Mute Particle">
+ <menu_item_call.on_click
+ function="Particle.Mute" />
+ <menu_item_call.on_enable
+ function="EnableMuteParticle" />
+ </menu_item_call>
</context_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_avatar_icon.xml b/indra/newview/skins/default/xui/en/menu_avatar_icon.xml
index 50910dff32..77b9095f7c 100644..100755
--- a/indra/newview/skins/default/xui/en/menu_avatar_icon.xml
+++ b/indra/newview/skins/default/xui/en/menu_avatar_icon.xml
@@ -17,7 +17,7 @@
parameter="profile" />
</menu_item_call>
<menu_item_call
- label="Send IM..."
+ label="IM"
layout="topleft"
name="Send IM">
<menu_item_call.on_click
@@ -25,7 +25,26 @@
parameter="im" />
</menu_item_call>
<menu_item_call
- label="Add Friend..."
+ label="Offer teleport"
+ layout="topleft"
+ name="Offer Teleport">
+ <on_click function="AvatarIcon.Action" parameter="teleport"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Voice call"
+ layout="topleft"
+ name="Voice Call">
+ <on_click function="AvatarIcon.Action" parameter="voice_call"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Chat history..."
+ layout="topleft"
+ name="Chat History">
+ <on_click function="AvatarIcon.Action" parameter="chat_history"/>
+ </menu_item_call>
+ <menu_item_separator layout="topleft" name="separator_chat_history"/>
+ <menu_item_call
+ label="Add friend"
layout="topleft"
name="Add Friend">
<menu_item_call.on_click
@@ -33,11 +52,56 @@
parameter="add" />
</menu_item_call>
<menu_item_call
- label="Remove Friend..."
+ label="Remove friend"
layout="topleft"
name="Remove Friend">
<menu_item_call.on_click
function="AvatarIcon.Action"
parameter="remove" />
</menu_item_call>
+ <menu_item_call
+ label="Invite to group..."
+ layout="topleft"
+ name="Invite Group">
+ <on_click function="AvatarIcon.Action" parameter="invite_to_group" />
+ </menu_item_call>
+ <menu_item_separator layout="topleft" name="separator_invite_to_group"/>
+ <menu_item_call
+ label="Zoom In"
+ layout="topleft"
+ name="Zoom In">
+ <on_click function="AvatarIcon.Action" parameter="zoom_in" />
+ </menu_item_call>
+ <menu_item_call
+ label="Map"
+ layout="topleft"
+ name="Map">
+ <on_click function="AvatarIcon.Action" parameter="map" />
+ </menu_item_call>
+ <menu_item_call
+ label="Share"
+ layout="topleft"
+ name="Share">
+ <on_click function="AvatarIcon.Action" parameter="share" />
+ </menu_item_call>
+ <menu_item_call
+ label="Pay"
+ layout="topleft"
+ name="Pay">
+ <on_click function="AvatarIcon.Action" parameter="pay" />
+ </menu_item_call>
+ <menu_item_check
+ label="Block Voice"
+ layout="topleft"
+ name="Block Unblock">
+ <on_click function="AvatarIcon.Action" parameter="block_unblock" />
+ <on_check function="AvatarIcon.Check" parameter="is_blocked" />
+ </menu_item_check>
+ <menu_item_check
+ label="Block Text"
+ layout="topleft"
+ name="Mute Text">
+ <on_click function="AvatarIcon.Action" parameter="mute_unmute" />
+ <on_check function="AvatarIcon.Check" parameter="is_muted" />
+ </menu_item_check>
</menu>
diff --git a/indra/newview/skins/default/xui/en/menu_avatar_other.xml b/indra/newview/skins/default/xui/en/menu_avatar_other.xml
index 276b5f106f..8bd013f14b 100644..100755
--- a/indra/newview/skins/default/xui/en/menu_avatar_other.xml
+++ b/indra/newview/skins/default/xui/en/menu_avatar_other.xml
@@ -39,8 +39,10 @@
<menu_item_call.on_click
function="Avatar.InviteToGroup" />
</menu_item_call>
+
<menu_item_separator />
- <menu_item_call
+
+ <menu_item_call
enabled="false"
label="Block"
name="Avatar Mute">
@@ -79,6 +81,14 @@
<menu_item_call.on_visible
function="IsGodCustomerService"/>
</menu_item_call>
+ <menu_item_call
+ label="Dump XML"
+ name="Dump XML">
+ <menu_item_call.on_click
+ function="Advanced.AppearanceToXML" />
+ <menu_item_call.on_visible
+ function="Advanced.EnableAppearanceToXML"/>
+ </menu_item_call>
<menu_item_call
label="Zoom In"
name="Zoom In">
@@ -95,4 +105,50 @@
<menu_item_call.on_enable
function="EnablePayAvatar" />
</menu_item_call>
+
+ <menu_item_separator />
+
+ <menu_item_check
+ name="Normal"
+ label="Normal Rendering">
+ <menu_item_check.on_check
+ function="Avatar.CheckImpostorMode"
+ parameter="0" />
+ <menu_item_check.on_click
+ function="Avatar.SetImpostorMode"
+ parameter="0" />
+ </menu_item_check>
+ <menu_item_check
+ name="Always use impostor"
+ label="Always use impostor">
+ <menu_item_check.on_check
+ function="Avatar.CheckImpostorMode"
+ parameter="1" />
+ <menu_item_check.on_click
+ function="Avatar.SetImpostorMode"
+ parameter="1" />
+ </menu_item_check>
+ <menu_item_check
+ name="Never use impostor"
+ label="Never use impostor">
+ <menu_item_check.on_check
+ function="Avatar.CheckImpostorMode"
+ parameter="2" />
+ <menu_item_check.on_click
+ function="Avatar.SetImpostorMode"
+ parameter="2" />
+ </menu_item_check>
+
+ <menu_item_separator
+ layout="topleft" name="Impostor seperator"/>
+
+ <menu_item_call
+ enabled="false"
+ label="Block Particle Owner"
+ name="Mute Particle">
+ <menu_item_call.on_click
+ function="Particle.Mute" />
+ <menu_item_call.on_enable
+ function="EnableMuteParticle" />
+ </menu_item_call>
</context_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_avatar_self.xml b/indra/newview/skins/default/xui/en/menu_avatar_self.xml
index d9bdfece38..ca0c9bd5e4 100644..100755
--- a/indra/newview/skins/default/xui/en/menu_avatar_self.xml
+++ b/indra/newview/skins/default/xui/en/menu_avatar_self.xml
@@ -261,4 +261,24 @@
<menu_item_call.on_visible
function="IsGodCustomerService"/>
</menu_item_call>
+ <menu_item_call
+ label="Dump XML"
+ name="Dump XML">
+ <menu_item_call.on_click
+ function="Advanced.AppearanceToXML" />
+ <menu_item_call.on_visible
+ function="Advanced.EnableAppearanceToXML"/>
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_call
+ enabled="false"
+ label="Block Particle Owner"
+ name="Mute Particle">
+ <menu_item_call.on_click
+ function="Particle.Mute" />
+
+ <menu_item_call.on_enable
+ function="EnableMuteParticle" />
+ </menu_item_call>
</context_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_cof_attachment.xml b/indra/newview/skins/default/xui/en/menu_cof_attachment.xml
index c402100fb1..c402100fb1 100644..100755
--- a/indra/newview/skins/default/xui/en/menu_cof_attachment.xml
+++ b/indra/newview/skins/default/xui/en/menu_cof_attachment.xml
diff --git a/indra/newview/skins/default/xui/en/menu_cof_body_part.xml b/indra/newview/skins/default/xui/en/menu_cof_body_part.xml
index f0e8461360..f0e8461360 100644..100755
--- a/indra/newview/skins/default/xui/en/menu_cof_body_part.xml
+++ b/indra/newview/skins/default/xui/en/menu_cof_body_part.xml
diff --git a/indra/newview/skins/default/xui/en/menu_cof_clothing.xml b/indra/newview/skins/default/xui/en/menu_cof_clothing.xml
index 206d49e8c7..206d49e8c7 100644..100755
--- a/indra/newview/skins/default/xui/en/menu_cof_clothing.xml
+++ b/indra/newview/skins/default/xui/en/menu_cof_clothing.xml
diff --git a/indra/newview/skins/default/xui/en/menu_cof_gear.xml b/indra/newview/skins/default/xui/en/menu_cof_gear.xml
index a6e9a40e31..45cf780557 100644..100755
--- a/indra/newview/skins/default/xui/en/menu_cof_gear.xml
+++ b/indra/newview/skins/default/xui/en/menu_cof_gear.xml
@@ -9,5 +9,5 @@
<menu
label="New Body Parts"
layout="topleft"
- name="COF.Geear.New_Body_Parts" />
+ name="COF.Gear.New_Body_Parts" />
</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_conversation.xml b/indra/newview/skins/default/xui/en/menu_conversation.xml
new file mode 100755
index 0000000000..31b1d091ee
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_conversation.xml
@@ -0,0 +1,216 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu
+ bottom="806"
+ layout="topleft"
+ left="0"
+ mouse_opaque="false"
+ name="menu_conversation_participant"
+ visible="false">
+ <menu_item_call
+ label="Close conversation"
+ layout="topleft"
+ name="close_conversation">
+ <on_click function="Avatar.DoToSelected" parameter="close_conversation"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Open voice conversation"
+ layout="topleft"
+ name="open_voice_conversation">
+ <on_click function="Avatar.DoToSelected" parameter="open_voice_conversation"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Disconnect from voice"
+ layout="topleft"
+ name="disconnect_from_voice">
+ <on_click function="Avatar.DoToSelected" parameter="disconnect_from_voice"/>
+ </menu_item_call>
+ <menu_item_separator layout="topleft" name="separator_disconnect_from_voice"/>
+ <menu_item_call
+ label="Close Selected"
+ layout="topleft"
+ name="close_selected_conversations">
+ <on_click function="Avatar.DoToSelected" parameter="close_selected_conversations"/>
+ </menu_item_call>
+ <menu_item_call
+ label="View Profile"
+ layout="topleft"
+ name="view_profile">
+ <on_click function="Avatar.DoToSelected" parameter="view_profile"/>
+ <on_enable function="Avatar.EnableItem" parameter="can_view_profile"/>
+ </menu_item_call>
+ <menu_item_call
+ label="IM"
+ layout="topleft"
+ name="im">
+ <on_click function="Avatar.DoToSelected" parameter="im"/>
+ <on_enable function="Avatar.EnableItem" parameter="can_im"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Offer teleport"
+ layout="topleft"
+ name="offer_teleport">
+ <on_click function="Avatar.DoToSelected" parameter="offer_teleport"/>
+ <on_enable function="Avatar.EnableItem" parameter="can_offer_teleport"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Request teleport"
+ layout="topleft"
+ name="request_teleport">
+ <on_click function="Avatar.DoToSelected" parameter="request_teleport"/>
+ <on_enable function="Avatar.EnableItem" parameter="can_offer_teleport"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Voice call"
+ layout="topleft"
+ name="voice_call">
+ <on_click function="Avatar.DoToSelected" parameter="voice_call"/>
+ <on_enable function="Avatar.EnableItem" parameter="can_call" />
+ </menu_item_call>
+ <menu_item_call
+ label="Chat history..."
+ layout="topleft"
+ name="chat_history">
+ <on_click function="Avatar.DoToSelected" parameter="chat_history"/>
+ <on_enable function="Avatar.EnableItem" parameter="can_chat_history"/>
+ </menu_item_call>
+ <menu_item_separator layout="topleft" name="separator_chat_history"/>
+ <menu_item_call
+ label="Add friend"
+ layout="topleft"
+ name="add_friend">
+ <on_click function="Avatar.DoToSelected" parameter="add_friend"/>
+ <on_enable function="Avatar.EnableItem" parameter="can_add" />
+ </menu_item_call>
+ <menu_item_call
+ label="Remove friend"
+ layout="topleft"
+ name="remove_friend">
+ <on_click function="Avatar.DoToSelected" parameter="remove_friend" />
+ <on_enable function="Avatar.EnableItem" parameter="can_delete" />
+ </menu_item_call>
+ <menu_item_call
+ label="Remove friends"
+ layout="topleft"
+ name="remove_friends">
+ <on_click function="Avatar.DoToSelected" parameter="remove_friend" />
+ <on_enable function="Avatar.EnableItem" parameter="can_delete" />
+ </menu_item_call>
+ <menu_item_call
+ label="Invite to group..."
+ layout="topleft"
+ name="invite_to_group">
+ <on_click function="Avatar.DoToSelected" parameter="invite_to_group" />
+ <on_enable function="Avatar.EnableItem" parameter="can_invite" />
+ </menu_item_call>
+ <menu_item_separator layout="topleft" name="separator_invite_to_group"/>
+ <menu_item_call
+ label="Zoom In"
+ layout="topleft"
+ name="zoom_in">
+ <on_click function="Avatar.DoToSelected" parameter="zoom_in" />
+ <on_enable function="Avatar.EnableItem" parameter="can_zoom_in" />
+ </menu_item_call>
+ <menu_item_call
+ label="Map"
+ layout="topleft"
+ name="map">
+ <on_click function="Avatar.DoToSelected" parameter="map" />
+ <on_enable function="Avatar.EnableItem" parameter="can_show_on_map" />
+ </menu_item_call>
+ <menu_item_call
+ label="Share"
+ layout="topleft"
+ name="share">
+ <on_click function="Avatar.DoToSelected" parameter="share" />
+ <on_enable function="Avatar.EnableItem" parameter="can_share" />
+ </menu_item_call>
+ <menu_item_call
+ label="Pay"
+ layout="topleft"
+ name="pay">
+ <on_click function="Avatar.DoToSelected" parameter="pay" />
+ <on_enable function="Avatar.EnableItem" parameter="can_pay" />
+ </menu_item_call>
+ <menu_item_check
+ label="Block Voice"
+ layout="topleft"
+ name="block_unblock">
+ <on_click function="Avatar.DoToSelected" parameter="block_unblock" />
+ <on_check function="Avatar.CheckItem" parameter="is_blocked" />
+ <on_enable function="Avatar.EnableItem" parameter="can_block" />
+ </menu_item_check>
+ <menu_item_check
+ label="Block Text"
+ layout="topleft"
+ name="MuteText">
+ <on_click function="Avatar.DoToSelected" parameter="mute_unmute" />
+ <on_check function="Avatar.CheckItem" parameter="is_muted" />
+ <on_enable function="Avatar.EnableItem" parameter="can_block" />
+ </menu_item_check>
+ <menu_item_call
+ label="Group Profile"
+ layout="topleft"
+ name="group_profile">
+ <on_click function="Group.DoToSelected" parameter="group_profile"/>
+ <on_enable function="Avatar.EnableItem" parameter="can_group_profile" />
+ </menu_item_call>
+ <menu_item_call
+ label="Activate Group"
+ layout="topleft"
+ name="activate_group">
+ <on_click function="Group.DoToSelected" parameter="activate_group"/>
+ <on_enable function="Avatar.EnableItem" parameter="can_activate_group" />
+ </menu_item_call>
+ <menu_item_call
+ label="Leave Group"
+ layout="topleft"
+ name="leave_group">
+ <on_click function="Group.DoToSelected" parameter="leave_group"/>
+ <on_enable function="Avatar.EnableItem" parameter="can_leave_group" />
+ </menu_item_call>
+ <menu_item_separator layout="topleft" name="Moderator Options Separator"/>
+ <context_menu
+ label="Moderator Options"
+ layout="topleft"
+ name="Moderator Options">
+ <menu_item_check
+ label="Allow text chat"
+ layout="topleft"
+ name="AllowTextChat">
+ <on_check function="Avatar.CheckItem" parameter="is_allowed_text_chat" />
+ <on_click function="Avatar.DoToSelected" parameter="toggle_allow_text_chat" />
+ <on_enable function="Avatar.EnableItem" parameter="can_allow_text_chat" />
+ </menu_item_check>
+ <menu_item_separator layout="topleft" name="moderate_voice_separator" />
+ <menu_item_call
+ label="Mute this participant"
+ layout="topleft"
+ name="ModerateVoiceMuteSelected">
+ <on_click function="Avatar.DoToSelected" parameter="selected" />
+ <on_enable function="Avatar.EnableItem" parameter="can_mute" />
+ <on_visible function="Avatar.VisibleItem" parameter="show_mute" />
+ </menu_item_call>
+ <menu_item_call
+ label="Unmute this participant"
+ layout="topleft"
+ name="ModerateVoiceUnMuteSelected">
+ <on_click function="Avatar.DoToSelected" parameter="selected" />
+ <on_enable function="Avatar.EnableItem" parameter="can_unmute" />
+ <on_visible function="Avatar.VisibleItem" parameter="show_unmute" />
+ </menu_item_call>
+ <menu_item_call
+ label="Mute everyone"
+ layout="topleft"
+ name="ModerateVoiceMute">
+ <on_click function="Avatar.DoToSelected" parameter="mute_all" />
+ <on_enable function="Avatar.EnableItem" parameter="can_moderate_voice" />
+ </menu_item_call>
+ <menu_item_call
+ label="Unmute everyone"
+ layout="topleft"
+ name="ModerateVoiceUnmute">
+ <on_click function="Avatar.DoToSelected" parameter="unmute_all" />
+ <on_enable function="Avatar.EnableItem" parameter="can_moderate_voice" />
+ </menu_item_call>
+ </context_menu>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_conversation_log_gear.xml b/indra/newview/skins/default/xui/en/menu_conversation_log_gear.xml
new file mode 100755
index 0000000000..a1a3afbf68
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_conversation_log_gear.xml
@@ -0,0 +1,152 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu
+ layout="topleft"
+ name="Conversation Context Menu">
+ <menu_item_call
+ label="IM..."
+ layout="topleft"
+ name="IM">
+ <on_click
+ function="Calllog.Action"
+ parameter="im" />
+ <on_enable
+ function="Calllog.Enable"
+ parameter="can_im" />
+ </menu_item_call>
+ <menu_item_call
+ label="Voice call..."
+ layout="topleft"
+ name="Call">
+ <on_click
+ function="Calllog.Action"
+ parameter="call" />
+ <on_enable
+ function="Calllog.Enable"
+ parameter="can_call" />
+ </menu_item_call>
+ <menu_item_call
+ label="Open chat history..."
+ layout="topleft"
+ name="Chat history">
+ <on_click
+ function="Calllog.Action"
+ parameter="chat_history" />
+ <on_enable
+ function="Calllog.Enable"
+ parameter="can_view_chat_history" />
+ </menu_item_call>
+ <menu_item_call
+ label="View Profile"
+ layout="topleft"
+ name="View Profile">
+ <on_click
+ function="Calllog.Action"
+ parameter="view_profile" />
+ <on_enable
+ function="Calllog.Enable"
+ parameter="can_view_profile" />
+ </menu_item_call>
+ <menu_item_call
+ label="Offer Teleport"
+ name="teleport">
+ <on_click
+ function="Calllog.Action"
+ parameter="offer_teleport"/>
+ <on_enable
+ function="Calllog.Enable"
+ parameter="can_offer_teleport"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Request Teleport"
+ name="request_teleport">
+ <on_click
+ function="Calllog.Action"
+ parameter="request_teleport"/>
+ <on_enable
+ function="Calllog.Enable"
+ parameter="can_offer_teleport"/>
+ </menu_item_call>
+ <menu_item_separator />
+ <menu_item_call
+ label="Add Friend"
+ layout="topleft"
+ name="add_friend">
+ <on_click
+ function="Calllog.Action"
+ parameter="add_friend"/>
+ <on_visible
+ function="Calllog.Check"
+ parameter="is_not_friend" />
+ </menu_item_call>
+ <menu_item_call
+ label="Remove Friend"
+ layout="topleft"
+ name="remove_friend">
+ <on_click
+ function="Calllog.Action"
+ parameter="remove_friend"/>
+ <on_visible
+ function="Calllog.Check"
+ parameter="is_friend" />
+ </menu_item_call>
+ <menu_item_call
+ label="Invite to group..."
+ layout="topleft"
+ name="Invite">
+ <on_click
+ function="Calllog.Action"
+ parameter="invite_to_group"/>
+ <on_enable
+ function="Calllog.Enable"
+ parameter="can_invite_to_group" />
+ </menu_item_call>
+ <menu_item_separator />
+ <menu_item_call
+ label="Map"
+ layout="topleft"
+ name="Map">
+ <on_click
+ function="Calllog.Action"
+ parameter="show_on_map" />
+ <on_enable
+ function="Calllog.Enable"
+ parameter="can_show_on_map" />
+ </menu_item_call>
+ <menu_item_call
+ label="Share"
+ layout="topleft"
+ name="Share">
+ <on_click
+ function="Calllog.Action"
+ parameter="share" />
+ <on_enable
+ function="Calllog.Enable"
+ parameter="can_share" />
+ </menu_item_call>
+ <menu_item_call
+ label="Pay"
+ layout="topleft"
+ name="Pay">
+ <on_click
+ function="Calllog.Action"
+ parameter="pay" />
+ <on_enable
+ function="Calllog.Enable"
+ parameter="can_pay" />
+ </menu_item_call>
+ <menu_item_check
+ label="Block/Unblock"
+ layout="topleft"
+ name="Block/Unblock">
+ <menu_item_check.on_click
+ function="Calllog.Action"
+ parameter="block"/>
+ <menu_item_check.on_check
+ function="Calllog.Check"
+ parameter="is_blocked" />
+ <menu_item_check.on_enable
+ function="Calllog.Enable"
+ parameter="can_block" />
+ </menu_item_check>
+
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_conversation_log_view.xml b/indra/newview/skins/default/xui/en/menu_conversation_log_view.xml
new file mode 100755
index 0000000000..ce65b23971
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_conversation_log_view.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu
+ name="menu_conversation_view"
+ left="0" bottom="0" visible="false"
+ mouse_opaque="false">
+ <menu_item_check
+ label="Sort by name"
+ name="sort_by_name">
+ <on_click
+ function="CallLog.Action"
+ parameter="sort_by_name"/>
+ <on_check
+ function="CallLog.Check"
+ parameter="sort_by_name"/>
+ </menu_item_check>
+ <menu_item_check
+ label="Sort by date"
+ name="sort_by_date">
+ <on_click
+ function="CallLog.Action"
+ parameter="sort_by_date" />
+ <on_check
+ function="CallLog.Check"
+ parameter="sort_by_date" />
+ </menu_item_check>
+ <menu_item_separator />
+ <menu_item_check
+ label="Sort friends on top"
+ name="sort_by_friends">
+ <on_click
+ function="CallLog.Action"
+ parameter="sort_friends_on_top" />
+ <on_check
+ function="CallLog.Check"
+ parameter="sort_friends_on_top" />
+ </menu_item_check>
+ <menu_item_separator />
+ <menu_item_call
+ label="View Nearby chat history..."
+ name="view_nearby_chat_history">
+ <on_click
+ function="CallLog.Action"
+ parameter="view_nearby_chat_history" />
+ </menu_item_call>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_edit.xml b/indra/newview/skins/default/xui/en/menu_edit.xml
index 99061e089a..99061e089a 100644..100755
--- a/indra/newview/skins/default/xui/en/menu_edit.xml
+++ b/indra/newview/skins/default/xui/en/menu_edit.xml
diff --git a/indra/newview/skins/default/xui/en/menu_favorites.xml b/indra/newview/skins/default/xui/en/menu_favorites.xml
index be380e11e5..be380e11e5 100644..100755
--- a/indra/newview/skins/default/xui/en/menu_favorites.xml
+++ b/indra/newview/skins/default/xui/en/menu_favorites.xml
diff --git a/indra/newview/skins/default/xui/en/menu_gesture_gear.xml b/indra/newview/skins/default/xui/en/menu_gesture_gear.xml
index b08d21e8f4..b08d21e8f4 100644..100755
--- a/indra/newview/skins/default/xui/en/menu_gesture_gear.xml
+++ b/indra/newview/skins/default/xui/en/menu_gesture_gear.xml
diff --git a/indra/newview/skins/default/xui/en/menu_group_plus.xml b/indra/newview/skins/default/xui/en/menu_group_plus.xml
index fce7414d80..eca9e7f3c9 100644..100755
--- a/indra/newview/skins/default/xui/en/menu_group_plus.xml
+++ b/indra/newview/skins/default/xui/en/menu_group_plus.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<menu name="menu_group_plus"
+<toggleable_menu name="menu_group_plus"
left="0" bottom="0" visible="false"
mouse_opaque="false">
<menu_item_call name="item_join" label="Join Group...">
@@ -8,4 +8,4 @@
<menu_item_call name="item_new" label="New Group...">
<menu_item_call.on_click function="People.Group.Plus.Action" userdata="new_group" />
</menu_item_call>
-</menu>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_hide_navbar.xml b/indra/newview/skins/default/xui/en/menu_hide_navbar.xml
index b517fd7957..b517fd7957 100644..100755
--- a/indra/newview/skins/default/xui/en/menu_hide_navbar.xml
+++ b/indra/newview/skins/default/xui/en/menu_hide_navbar.xml
diff --git a/indra/newview/skins/default/xui/en/menu_im_conversation.xml b/indra/newview/skins/default/xui/en/menu_im_conversation.xml
new file mode 100755
index 0000000000..43287c6ec3
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_im_conversation.xml
@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu
+ layout="topleft"
+ name="Conversation Gear Menu">
+ <menu_item_call
+ label="View Profile"
+ layout="topleft"
+ name="View Profile">
+ <on_click function="Avatar.GearDoToSelected" parameter="view_profile" />
+ <on_enable function="Avatar.EnableGearItem" parameter="can_view_profile" />
+ </menu_item_call>
+ <menu_item_call
+ label="Add Friend"
+ layout="topleft"
+ name="Add Friend">
+ <on_click function="Avatar.GearDoToSelected" parameter="add_friend" />
+ <on_enable function="Avatar.EnableGearItem" parameter="can_add" />
+ </menu_item_call>
+ <menu_item_call
+ label="Remove friend"
+ layout="topleft"
+ name="remove_friend">
+ <on_click function="Avatar.GearDoToSelected" parameter="remove_friend" />
+ <on_enable function="Avatar.EnableGearItem" parameter="can_delete" />
+ </menu_item_call>
+ <menu_item_call
+ label="Offer teleport"
+ layout="topleft"
+ name="offer_teleport">
+ <on_click function="Avatar.GearDoToSelected" parameter="offer_teleport"/>
+ <on_enable function="Avatar.EnableGearItem" parameter="can_offer_teleport"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Invite to group..."
+ layout="topleft"
+ name="invite_to_group">
+ <on_click function="Avatar.GearDoToSelected" parameter="invite_to_group" />
+ <on_enable function="Avatar.EnableGearItem" parameter="can_invite" />
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft"
+ name="View Icons Separator" />
+ <menu_item_call
+ label="Chat history..."
+ layout="topleft"
+ name="chat_history">
+ <on_click function="Avatar.GearDoToSelected" parameter="chat_history"/>
+ <on_enable function="Avatar.EnableGearItem" parameter="can_chat_history"/>
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft"/>
+ <menu_item_call
+ label="Zoom In"
+ layout="topleft"
+ name="zoom_in">
+ <on_click function="Avatar.DoToSelected" parameter="zoom_in" />
+ <on_enable function="Avatar.EnableItem" parameter="can_zoom_in" />
+ </menu_item_call>
+ <menu_item_call
+ label="Map"
+ layout="topleft"
+ name="map">
+ <on_click function="Avatar.GearDoToSelected" parameter="map" />
+ <on_enable function="Avatar.EnableGearItem" parameter="can_show_on_map" />
+ </menu_item_call>
+ <menu_item_call
+ label="Share"
+ layout="topleft"
+ name="Share">
+ <on_click function="Avatar.GearDoToSelected" parameter="share" />
+ <on_enable function="Avatar.EnableGearItem" parameter="can_share" />
+ </menu_item_call>
+ <menu_item_call
+ label="Pay"
+ layout="topleft"
+ name="Pay">
+ <on_click function="Avatar.GearDoToSelected" parameter="pay" />
+ <on_enable function="Avatar.EnableGearItem" parameter="can_pay" />
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft"/>
+ <menu_item_check
+ label="Block Voice"
+ layout="topleft"
+ name="Block/Unblock">
+ <on_check function="Avatar.CheckGearItem" parameter="is_blocked" />
+ <on_click function="Avatar.GearDoToSelected" parameter="block_unblock" />
+ <on_enable function="Avatar.EnableGearItem" parameter="can_block" />
+ </menu_item_check>
+ <menu_item_check
+ label="Block Text"
+ layout="topleft"
+ name="MuteText">
+ <on_check function="Avatar.CheckGearItem" parameter="is_muted" />
+ <on_click function="Avatar.GearDoToSelected" parameter="mute_unmute" />
+ <on_enable function="Avatar.EnableGearItem" parameter="can_block" />
+ </menu_item_check>
+ <menu_item_separator
+ layout="topleft"/>
+</toggleable_menu>
+
diff --git a/indra/newview/skins/default/xui/en/menu_im_session_showmodes.xml b/indra/newview/skins/default/xui/en/menu_im_session_showmodes.xml
new file mode 100755
index 0000000000..b0adca0e0e
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_im_session_showmodes.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu
+ name="menu_modes"
+ left="0" bottom="0" visible="false"
+ mouse_opaque="false">
+ <menu_item_check
+ label="Compact view"
+ name="compact_view">
+ <menu_item_check.on_click
+ function="IMSession.Menu.Action"
+ parameter="compact_view"/>
+ <menu_item_check.on_check
+ function="IMSession.Menu.CompactExpandedModes.CheckItem"
+ parameter="compact_view"/>
+ </menu_item_check>
+ <menu_item_check
+ label="Expanded view"
+ name="expanded_view">
+ <menu_item_check.on_click
+ function="IMSession.Menu.Action"
+ parameter="expanded_view"/>
+ <menu_item_check.on_check
+ function="IMSession.Menu.CompactExpandedModes.CheckItem"
+ parameter="expanded_view"/>
+ </menu_item_check>
+ <menu_item_separator layout="topleft" />
+ <menu_item_check name="IMShowTime" label="Show time">
+ <menu_item_check.on_click
+ function="IMSession.Menu.Action"
+ parameter="IMShowTime" />
+ <menu_item_check.on_check
+ function="IMSession.Menu.ShowModes.CheckItem"
+ parameter="IMShowTime" />
+ <menu_item_check.on_enable
+ function="IMSession.Menu.ShowModes.Enable"
+ parameter="IMShowTime" />
+ </menu_item_check>
+ <menu_item_check name="IMShowNamesForP2PConv" label="Show names in one-to-one conversations">
+ <menu_item_check.on_click
+ function="IMSession.Menu.Action"
+ parameter="IMShowNamesForP2PConv" />
+ <menu_item_check.on_check
+ function="IMSession.Menu.ShowModes.CheckItem"
+ parameter="IMShowNamesForP2PConv" />
+ <menu_item_check.on_enable
+ function="IMSession.Menu.ShowModes.Enable"
+ parameter="IMShowNamesForP2PConv" />
+ </menu_item_check>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_im_well_button.xml b/indra/newview/skins/default/xui/en/menu_im_well_button.xml
deleted file mode 100644
index f8dfba91ff..0000000000
--- a/indra/newview/skins/default/xui/en/menu_im_well_button.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<context_menu
- layout="topleft"
- name="IM Well Button Context Menu">
- <menu_item_call
- label="Close All"
- layout="topleft"
- name="Close All">
- <menu_item_call.on_click
- function="IMWellChicletMenu.Action"
- parameter="close all" />
- <menu_item_call.on_enable
- function="IMWellChicletMenu.EnableItem"
- parameter="can close all" />
- </menu_item_call>
-</context_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_imchiclet_adhoc.xml b/indra/newview/skins/default/xui/en/menu_imchiclet_adhoc.xml
index eb5e31b57d..eb5e31b57d 100644..100755
--- a/indra/newview/skins/default/xui/en/menu_imchiclet_adhoc.xml
+++ b/indra/newview/skins/default/xui/en/menu_imchiclet_adhoc.xml
diff --git a/indra/newview/skins/default/xui/en/menu_imchiclet_group.xml b/indra/newview/skins/default/xui/en/menu_imchiclet_group.xml
index 8cbe62cfb0..8cbe62cfb0 100644..100755
--- a/indra/newview/skins/default/xui/en/menu_imchiclet_group.xml
+++ b/indra/newview/skins/default/xui/en/menu_imchiclet_group.xml
diff --git a/indra/newview/skins/default/xui/en/menu_imchiclet_p2p.xml b/indra/newview/skins/default/xui/en/menu_imchiclet_p2p.xml
index 038b8328cb..038b8328cb 100644..100755
--- a/indra/newview/skins/default/xui/en/menu_imchiclet_p2p.xml
+++ b/indra/newview/skins/default/xui/en/menu_imchiclet_p2p.xml
diff --git a/indra/newview/skins/default/xui/en/menu_inspect_avatar_gear.xml b/indra/newview/skins/default/xui/en/menu_inspect_avatar_gear.xml
deleted file mode 100644
index 76b188220d..0000000000
--- a/indra/newview/skins/default/xui/en/menu_inspect_avatar_gear.xml
+++ /dev/null
@@ -1,143 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<toggleable_menu
- create_jump_keys="true"
- layout="topleft"
- mouse_opaque="false"
- visible="false"
- name="Gear Menu">
- <menu_item_call
- label="View Profile"
- enabled="true"
- name="view_profile">
- <menu_item_call.on_click
- function="InspectAvatar.ViewProfile"/>
- </menu_item_call>
- <menu_item_call
- label="Add Friend"
- name="add_friend">
- <menu_item_call.on_click
- function="InspectAvatar.AddFriend"/>
- <menu_item_call.on_enable
- function="InspectAvatar.Gear.Enable"/>
- </menu_item_call>
- <menu_item_call
- label="IM"
- name="im">
- <menu_item_call.on_click
- function="InspectAvatar.IM"/>
- </menu_item_call>
- <menu_item_call
- label="Call"
- enabled="true"
- name="call">
- <menu_item_call.on_click
- function="InspectAvatar.Call"/>
- <menu_item_call.on_enable
- function="InspectAvatar.Gear.EnableCall"/>
- </menu_item_call>
- <menu_item_call
- label="Teleport"
- name="teleport">
- <menu_item_call.on_click
- function="InspectAvatar.Teleport"/>
- <menu_item_call.on_enable
- function="InspectAvatar.Gear.EnableTeleportOffer"/>
- </menu_item_call>
- <menu_item_call
- label="Invite to Group"
- name="invite_to_group">
- <menu_item_call.on_click
- function="InspectAvatar.InviteToGroup"/>
- </menu_item_call>
- <menu_item_separator />
- <menu_item_call
- label="Block"
- name="block">
- <menu_item_call.on_click
- function="InspectAvatar.ToggleMute"/>
- <menu_item_call.on_visible
- function="InspectAvatar.EnableMute" />
- </menu_item_call>
- <menu_item_call
- label="Unblock"
- name="unblock">
- <menu_item_call.on_click
- function="InspectAvatar.ToggleMute"/>
- <menu_item_call.on_visible
- function="InspectAvatar.EnableUnmute" />
- </menu_item_call>
- <menu_item_call
- label="Report"
- name="report">
- <menu_item_call.on_click
- function="InspectAvatar.Report"/>
- </menu_item_call>
- <menu_item_call
- label="Freeze"
- name="freeze">
- <menu_item_call.on_click
- function="InspectAvatar.Freeze"/>
- <menu_item_call.on_visible
- function="InspectAvatar.VisibleFreeze"/>
- </menu_item_call>
- <menu_item_call
- label="Eject"
- name="eject">
- <menu_item_call.on_click
- function="InspectAvatar.Eject"/>
- <menu_item_call.on_visible
- function="InspectAvatar.VisibleEject"/>
- </menu_item_call>
- <menu_item_call
- label="Kick"
- name="kick">
- <menu_item_call.on_click
- function="InspectAvatar.Kick"/>
- <menu_item_call.on_visible
- function="InspectAvatar.EnableGod"/>
- </menu_item_call>
- <menu_item_call
- label="CSR"
- name="csr">
- <menu_item_call.on_click
- function="InspectAvatar.CSR" />
- <menu_item_call.on_visible
- function="InspectAvatar.EnableGod" />
- </menu_item_call>
- <menu_item_call
- label="Debug Textures"
- name="debug">
- <menu_item_call.on_click
- function="Avatar.Debug"/>
- <menu_item_call.on_visible
- function="IsGodCustomerService"/>
- </menu_item_call>
- <menu_item_call
- label="Find On Map"
- name="find_on_map">
- <menu_item_call.on_click
- function="InspectAvatar.FindOnMap"/>
- <menu_item_call.on_visible
- function="InspectAvatar.VisibleFindOnMap"/>
- </menu_item_call>
- <menu_item_call
- label="Zoom In"
- name="zoom_in">
- <menu_item_call.on_click
- function="InspectAvatar.ZoomIn"/>
- <menu_item_call.on_visible
- function="InspectAvatar.VisibleZoomIn"/>
- </menu_item_call>
- <menu_item_call
- label="Pay"
- name="pay">
- <menu_item_call.on_click
- function="InspectAvatar.Pay"/>
- </menu_item_call>
- <menu_item_call
- label="Share"
- name="share">
- <menu_item_call.on_click
- function="InspectAvatar.Share"/>
- </menu_item_call>
-</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_inspect_object_gear.xml b/indra/newview/skins/default/xui/en/menu_inspect_object_gear.xml
index 63e154697b..2c420aa1e3 100644..100755
--- a/indra/newview/skins/default/xui/en/menu_inspect_object_gear.xml
+++ b/indra/newview/skins/default/xui/en/menu_inspect_object_gear.xml
@@ -57,7 +57,7 @@
layout="topleft"
name="take_copy">
<menu_item_call.on_click
- function="InspectObject.TakeFreeCopy"/>
+ function="Tools.TakeCopy"/>
<menu_item_call.on_visible
function="Tools.EnableTakeCopy"/>
</menu_item_call>
diff --git a/indra/newview/skins/default/xui/en/menu_inspect_self_gear.xml b/indra/newview/skins/default/xui/en/menu_inspect_self_gear.xml
deleted file mode 100644
index 5e7b16ed4a..0000000000
--- a/indra/newview/skins/default/xui/en/menu_inspect_self_gear.xml
+++ /dev/null
@@ -1,252 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<toggleable_menu
- layout="topleft"
- name="Self Pie">
- <menu_item_call
- label="Sit Down"
- layout="topleft"
- name="Sit Down Here">
- <menu_item_call.on_click
- function="Self.SitDown"
- parameter="" />
- <menu_item_call.on_enable
- function="Self.EnableSitDown" />
- </menu_item_call>
- <menu_item_call
- label="Stand Up"
- layout="topleft"
- name="Stand Up">
- <menu_item_call.on_click
- function="Self.StandUp"
- parameter="" />
- <menu_item_call.on_enable
- function="Self.EnableStandUp" />
- </menu_item_call>
- <context_menu
- label="Take Off"
- layout="topleft"
- name="Take Off &gt;">
- <context_menu
- label="Clothes"
- layout="topleft"
- name="Clothes &gt;">
- <menu_item_call
- enabled="false"
- label="Shirt"
- layout="topleft"
- name="Shirt">
- <menu_item_call.on_click
- function="Edit.TakeOff"
- parameter="shirt" />
- <menu_item_call.on_enable
- function="Edit.EnableTakeOff"
- parameter="shirt" />
- </menu_item_call>
- <menu_item_call
- enabled="false"
- label="Pants"
- layout="topleft"
- name="Pants">
- <menu_item_call.on_click
- function="Edit.TakeOff"
- parameter="pants" />
- <menu_item_call.on_enable
- function="Edit.EnableTakeOff"
- parameter="pants" />
- </menu_item_call>
- <menu_item_call
- enabled="false"
- label="Skirt"
- layout="topleft"
- name="Skirt">
- <menu_item_call.on_click
- function="Edit.TakeOff"
- parameter="skirt" />
- <menu_item_call.on_enable
- function="Edit.EnableTakeOff"
- parameter="skirt" />
- </menu_item_call>
- <menu_item_call
- enabled="false"
- label="Shoes"
- layout="topleft"
- name="Shoes">
- <menu_item_call.on_click
- function="Edit.TakeOff"
- parameter="shoes" />
- <menu_item_call.on_enable
- function="Edit.EnableTakeOff"
- parameter="shoes" />
- </menu_item_call>
- <menu_item_call
- enabled="false"
- label="Socks"
- layout="topleft"
- name="Socks">
- <menu_item_call.on_click
- function="Edit.TakeOff"
- parameter="socks" />
- <menu_item_call.on_enable
- function="Edit.EnableTakeOff"
- parameter="socks" />
- </menu_item_call>
- <menu_item_call
- enabled="false"
- label="Jacket"
- layout="topleft"
- name="Jacket">
- <menu_item_call.on_click
- function="Edit.TakeOff"
- parameter="jacket" />
- <menu_item_call.on_enable
- function="Edit.EnableTakeOff"
- parameter="jacket" />
- </menu_item_call>
- <menu_item_call
- enabled="false"
- label="Gloves"
- layout="topleft"
- name="Gloves">
- <menu_item_call.on_click
- function="Edit.TakeOff"
- parameter="gloves" />
- <menu_item_call.on_enable
- function="Edit.EnableTakeOff"
- parameter="gloves" />
- </menu_item_call>
- <menu_item_call
- enabled="false"
- label="Undershirt"
- layout="topleft"
- name="Self Undershirt">
- <menu_item_call.on_click
- function="Edit.TakeOff"
- parameter="undershirt" />
- <menu_item_call.on_enable
- function="Edit.EnableTakeOff"
- parameter="undershirt" />
- </menu_item_call>
- <menu_item_call
- enabled="false"
- label="Underpants"
- layout="topleft"
- name="Self Underpants">
- <menu_item_call.on_click
- function="Edit.TakeOff"
- parameter="underpants" />
- <menu_item_call.on_enable
- function="Edit.EnableTakeOff"
- parameter="underpants" />
- </menu_item_call>
- <menu_item_call
- enabled="false"
- label="Tattoo"
- layout="topleft"
- name="Self Tattoo">
- <menu_item_call.on_click
- function="Edit.TakeOff"
- parameter="tattoo" />
- <menu_item_call.on_enable
- function="Edit.EnableTakeOff"
- parameter="tattoo" />
- </menu_item_call>
- <menu_item_call
- enabled="false"
- label="Alpha"
- layout="topleft"
- name="Self Alpha">
- <menu_item_call.on_click
- function="Edit.TakeOff"
- parameter="alpha" />
- <menu_item_call.on_enable
- function="Edit.EnableTakeOff"
- parameter="alpha" />
- </menu_item_call>
- <menu_item_separator
- layout="topleft" />
- <menu_item_call
- label="All Clothes"
- layout="topleft"
- name="All Clothes">
- <menu_item_call.on_click
- function="Edit.TakeOff"
- parameter="all" />
- </menu_item_call>
- </context_menu>
- <context_menu
- label="HUD"
- layout="topleft"
- name="Object Detach HUD" />
- <context_menu
- label="Detach"
- layout="topleft"
- name="Object Detach" />
- <menu_item_call
- label="Detach All"
- layout="topleft"
- name="Detach All">
- <menu_item_call.on_click
- function="Self.RemoveAllAttachments"
- parameter="" />
- <menu_item_call.on_enable
- function="Self.EnableRemoveAllAttachments" />
- </menu_item_call>
- </context_menu>
- <menu_item_call
- label="Change Outfit"
- layout="topleft"
- name="Chenge Outfit">
- <menu_item_call.on_click
- function="CustomizeAvatar" />
- <menu_item_call.on_enable
- function="Edit.EnableCustomizeAvatar" />
- </menu_item_call>
- <menu_item_call label="Edit My Outfit"
- layout="topleft"
- name="Edit Outfit">
- <menu_item_call.on_click
- function="EditOutfit" />
- <menu_item_call.on_enable
- function="Edit.EnableCustomizeAvatar" />
- </menu_item_call>
- <menu_item_call label="Edit My Shape"
- layout="topleft"
- name="Edit My Shape">
- <menu_item_call.on_click
- function="EditShape" />
- <menu_item_call.on_enable
- function="Edit.EnableEditShape" />
- </menu_item_call>
- <menu_item_call
- label="My Friends"
- layout="topleft"
- name="Friends...">
- <menu_item_call.on_click
- function="SideTray.PanelPeopleTab"
- parameter="friends_panel" />
- </menu_item_call>
- <menu_item_call
- label="My Groups"
- layout="topleft"
- name="Groups...">
- <menu_item_call.on_click
- function="SideTray.PanelPeopleTab"
- parameter="groups_panel" />
- </menu_item_call>
- <menu_item_call
- label="My Profile"
- layout="topleft"
- name="Profile...">
- <menu_item_call.on_click
- function="ShowAgentProfile"
- parameter="agent" />
- </menu_item_call>
- <menu_item_call
- label="Debug Textures"
- name="Debug...">
- <menu_item_call.on_click
- function="Avatar.Debug" />
- <menu_item_call.on_visible
- function="IsGodCustomerService"/>
- </menu_item_call>
-</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_inv_offer_chiclet.xml b/indra/newview/skins/default/xui/en/menu_inv_offer_chiclet.xml
index 45a0a6635b..45a0a6635b 100644..100755
--- a/indra/newview/skins/default/xui/en/menu_inv_offer_chiclet.xml
+++ b/indra/newview/skins/default/xui/en/menu_inv_offer_chiclet.xml
diff --git a/indra/newview/skins/default/xui/en/menu_inventory.xml b/indra/newview/skins/default/xui/en/menu_inventory.xml
index b13bf5b508..512205ba43 100644..100755
--- a/indra/newview/skins/default/xui/en/menu_inventory.xml
+++ b/indra/newview/skins/default/xui/en/menu_inventory.xml
@@ -537,6 +537,14 @@
layout="topleft"
name="Landmark Separator" />
<menu_item_call
+ label="Copy SLurl"
+ layout="topleft"
+ name="url_copy">
+ <menu_item_call.on_click
+ function="Inventory.DoToSelected"
+ parameter="copy_slurl" />
+ </menu_item_call>
+ <menu_item_call
label="About Landmark"
layout="topleft"
name="About Landmark">
@@ -583,6 +591,14 @@
parameter="lure" />
</menu_item_call>
<menu_item_call
+ label="Request Teleport..."
+ layout="topleft"
+ name="Request Teleport...">
+ <menu_item_call.on_click
+ function="Inventory.DoToSelected"
+ parameter="request_lure" />
+ </menu_item_call>
+ <menu_item_call
label="Start Conference Chat"
layout="topleft"
name="Conference Chat">
diff --git a/indra/newview/skins/default/xui/en/menu_inventory_add.xml b/indra/newview/skins/default/xui/en/menu_inventory_add.xml
index 8bc4df6c79..afeb1bf226 100644..100755
--- a/indra/newview/skins/default/xui/en/menu_inventory_add.xml
+++ b/indra/newview/skins/default/xui/en/menu_inventory_add.xml
@@ -3,7 +3,7 @@
layout="topleft"
left="0"
mouse_opaque="false"
- can_tear_off="true"
+ can_tear_off="false"
name="menu_inventory_add"
visible="false">
<menu
diff --git a/indra/newview/skins/default/xui/en/menu_inventory_gear_default.xml b/indra/newview/skins/default/xui/en/menu_inventory_gear_default.xml
index d2519a5aa4..d2519a5aa4 100644..100755
--- a/indra/newview/skins/default/xui/en/menu_inventory_gear_default.xml
+++ b/indra/newview/skins/default/xui/en/menu_inventory_gear_default.xml
diff --git a/indra/newview/skins/default/xui/en/menu_land.xml b/indra/newview/skins/default/xui/en/menu_land.xml
index cc6d8ad9c1..2ad5cbbe95 100644..100755
--- a/indra/newview/skins/default/xui/en/menu_land.xml
+++ b/indra/newview/skins/default/xui/en/menu_land.xml
@@ -61,4 +61,15 @@
<menu_item_call.on_enable
function="EnableEdit" />
</menu_item_call>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_call
+ enabled="false"
+ label="Block Particle Owner"
+ name="Mute Particle">
+ <menu_item_call.on_click
+ function="Particle.Mute" />
+ <menu_item_call.on_enable
+ function="EnableMuteParticle" />
+ </menu_item_call>
</context_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_landmark.xml b/indra/newview/skins/default/xui/en/menu_landmark.xml
index 93b6db222a..93b6db222a 100644..100755
--- a/indra/newview/skins/default/xui/en/menu_landmark.xml
+++ b/indra/newview/skins/default/xui/en/menu_landmark.xml
diff --git a/indra/newview/skins/default/xui/en/menu_login.xml b/indra/newview/skins/default/xui/en/menu_login.xml
index 101e104eab..52c4fb1613 100644..100755
--- a/indra/newview/skins/default/xui/en/menu_login.xml
+++ b/indra/newview/skins/default/xui/en/menu_login.xml
@@ -180,7 +180,8 @@
name="Set Logging Level"
tear_off="true">
<menu_item_check
- label="Debug">
+ name="Debug"
+ label="Debug">
<menu_item_check.on_check
function="Develop.CheckLoggingLevel"
parameter="0" />
@@ -189,7 +190,8 @@
parameter="0" />
</menu_item_check>
<menu_item_check
- label="Info">
+ name="Info"
+ label="Info">
<menu_item_check.on_check
function="Develop.CheckLoggingLevel"
parameter="1" />
@@ -198,7 +200,8 @@
parameter="1" />
</menu_item_check>
<menu_item_check
- label="Warning">
+ name="Warning"
+ label="Warning">
<menu_item_check.on_check
function="Develop.CheckLoggingLevel"
parameter="2" />
@@ -207,7 +210,8 @@
parameter="2" />
</menu_item_check>
<menu_item_check
- label="Error">
+ name="Error"
+ label="Error">
<menu_item_check.on_check
function="Develop.CheckLoggingLevel"
parameter="3" />
@@ -216,7 +220,8 @@
parameter="3" />
</menu_item_check>
<menu_item_check
- label="None">
+ name="None"
+ label="None">
<menu_item_check.on_check
function="Develop.CheckLoggingLevel"
parameter="4" />
diff --git a/indra/newview/skins/default/xui/en/menu_media_ctrl.xml b/indra/newview/skins/default/xui/en/menu_media_ctrl.xml
index 960da4bd7a..960da4bd7a 100644..100755
--- a/indra/newview/skins/default/xui/en/menu_media_ctrl.xml
+++ b/indra/newview/skins/default/xui/en/menu_media_ctrl.xml
diff --git a/indra/newview/skins/default/xui/en/menu_mini_map.xml b/indra/newview/skins/default/xui/en/menu_mini_map.xml
index ea263d05ce..ea263d05ce 100644..100755
--- a/indra/newview/skins/default/xui/en/menu_mini_map.xml
+++ b/indra/newview/skins/default/xui/en/menu_mini_map.xml
diff --git a/indra/newview/skins/default/xui/en/menu_model_import_gear_default.xml b/indra/newview/skins/default/xui/en/menu_model_import_gear_default.xml
index 2650903f88..2650903f88 100644..100755
--- a/indra/newview/skins/default/xui/en/menu_model_import_gear_default.xml
+++ b/indra/newview/skins/default/xui/en/menu_model_import_gear_default.xml
diff --git a/indra/newview/skins/default/xui/en/menu_mute_particle.xml b/indra/newview/skins/default/xui/en/menu_mute_particle.xml
new file mode 100644
index 0000000000..a4261bf39e
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_mute_particle.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<!-- *NOTE: See also menu_attachment_other.xml -->
+<context_menu
+ layout="topleft"
+ name="Mute Particle Pie">
+ <menu_item_call
+ enabled="false"
+ label="Block Particle Owner"
+ name="Mute Particle">
+ <menu_item_call.on_click
+ function="Particle.Mute" />
+ <menu_item_call.on_enable
+ function="EnableMuteParticle" />
+ </menu_item_call>
+</context_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_navbar.xml b/indra/newview/skins/default/xui/en/menu_navbar.xml
index b71b866c4b..b71b866c4b 100644..100755
--- a/indra/newview/skins/default/xui/en/menu_navbar.xml
+++ b/indra/newview/skins/default/xui/en/menu_navbar.xml
diff --git a/indra/newview/skins/default/xui/en/menu_nearby_chat.xml b/indra/newview/skins/default/xui/en/menu_nearby_chat.xml
index ff89e20ea5..ff89e20ea5 100644..100755
--- a/indra/newview/skins/default/xui/en/menu_nearby_chat.xml
+++ b/indra/newview/skins/default/xui/en/menu_nearby_chat.xml
diff --git a/indra/newview/skins/default/xui/en/menu_notification_well_button.xml b/indra/newview/skins/default/xui/en/menu_notification_well_button.xml
index 263ac40f4e..263ac40f4e 100644..100755
--- a/indra/newview/skins/default/xui/en/menu_notification_well_button.xml
+++ b/indra/newview/skins/default/xui/en/menu_notification_well_button.xml
diff --git a/indra/newview/skins/default/xui/en/menu_object.xml b/indra/newview/skins/default/xui/en/menu_object.xml
index 719509301b..52ab7da515 100644..100755
--- a/indra/newview/skins/default/xui/en/menu_object.xml
+++ b/indra/newview/skins/default/xui/en/menu_object.xml
@@ -1,179 +1,210 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<context_menu
- layout="topleft"
- name="Object Pie">
- <menu_item_call
- enabled="false"
- label="Touch"
- name="Object Touch">
- <menu_item_call.on_click
- function="Object.Touch" />
- <menu_item_call.on_enable
- function="Object.EnableTouch"
- name="EnableTouch"
- parameter="Touch" />
- </menu_item_call>
- <menu_item_call
- label="Edit"
- name="Edit...">
- <menu_item_call.on_click
- function="Object.Edit" />
+ layout="topleft"
+ name="Object Pie">
+ <menu_item_call
+ enabled="false"
+ label="Touch"
+ name="Object Touch">
+ <menu_item_call.on_click
+ function="Object.Touch" />
<menu_item_call.on_enable
- function="EnableEdit"/>
- </menu_item_call>
- <menu_item_call
+ function="Object.EnableTouch"
+ name="EnableTouch"
+ parameter="Touch" />
+ </menu_item_call>
+ <menu_item_call
+ label="Edit"
+ name="Edit...">
+ <menu_item_call.on_click
+ function="Object.Edit" />
+ <menu_item_call.on_enable
+ function="EnableEdit"/>
+ </menu_item_call>
+ <menu_item_call
label="Build"
name="Build">
- <menu_item_call.on_click
+ <menu_item_call.on_click
function="Object.Build" />
- <menu_item_call.on_enable
- function="EnableEdit"/>
- </menu_item_call>
- <menu_item_call
- enabled="false"
- label="Open"
- name="Open">
- <menu_item_call.on_click
- function="Object.Open" />
- <menu_item_call.on_enable
- function="Object.EnableOpen" />
- </menu_item_call>
- <menu_item_call
- enabled="false"
- label="Sit Here"
- name="Object Sit">
- <menu_item_call.on_click
- function="Object.SitOrStand" />
- <menu_item_call.on_enable
- function="Object.EnableSit" />
- </menu_item_call>
- <menu_item_call
- enabled="false"
- label="Stand Up"
- name="Object Stand Up">
- <menu_item_call.on_click
- function="Object.SitOrStand" />
- <menu_item_call.on_enable
- function="Object.EnableStandUp" />
- </menu_item_call>
- <menu_item_call
- label="Object Profile"
- name="Object Inspect">
- <menu_item_call.on_click
- function="Object.Inspect" />
- <menu_item_call.on_enable
- function="Object.EnableInspect" />
- </menu_item_call>
- <menu_item_call
- label="Zoom In"
- name="Zoom In">
- <menu_item_call.on_click
- function="Object.ZoomIn" />
- </menu_item_call>
-<menu_item_separator layout="topleft" />
- <context_menu
- label="Put On"
- name="Put On" >
- <menu_item_call
+ <menu_item_call.on_enable
+ function="EnableEdit"/>
+ </menu_item_call>
+ <menu_item_call
enabled="false"
- label="Wear"
- name="Wear">
- <menu_item_call.on_click
- function="Object.AttachToAvatar" />
- <menu_item_call.on_enable
- function="Object.EnableWear" />
- </menu_item_call>
- <menu_item_call
+ label="Open"
+ name="Open">
+ <menu_item_call.on_click
+ function="Object.Open" />
+ <menu_item_call.on_enable
+ function="Object.EnableOpen" />
+ </menu_item_call>
+ <menu_item_call
enabled="false"
- label="Add"
- name="Add">
- <menu_item_call.on_click
- function="Object.AttachAddToAvatar" />
- <menu_item_call.on_enable
- function="Object.EnableWear" />
- </menu_item_call>
- <context_menu
- label="Attach"
- name="Object Attach" />
- <context_menu
- label="Attach HUD"
- name="Object Attach HUD" />
- </context_menu>
- <context_menu
- label="Manage"
- name="Remove">
- <menu_item_call
- enabled="false"
- label="Report Abuse"
- name="Report Abuse...">
- <menu_item_call.on_click
- function="Object.ReportAbuse" />
- <menu_item_call.on_enable
- function="Object.EnableReportAbuse" />
- </menu_item_call>
- <menu_item_call
- enabled="false"
- label="Block"
- name="Object Mute">
- <menu_item_call.on_click
- function="Object.Mute" />
- <menu_item_call.on_enable
- function="Object.EnableMute" />
- </menu_item_call>
- <menu_item_call
+ label="Sit Here"
+ name="Object Sit">
+ <menu_item_call.on_click
+ function="Object.SitOrStand" />
+ <menu_item_call.on_enable
+ function="Object.EnableSit" />
+ </menu_item_call>
+ <menu_item_call
enabled="false"
- label="Return"
- name="Return...">
- <menu_item_call.on_click
- function="Object.Return" />
- <menu_item_call.on_enable
- function="Object.EnableReturn" />
- </menu_item_call>
- </context_menu>
- <menu_item_separator layout="topleft" />
- <menu_item_call
- label="Take"
- layout="topleft"
- name="Pie Object Take">
+ label="Stand Up"
+ name="Object Stand Up">
+ <menu_item_call.on_click
+ function="Object.SitOrStand" />
+ <menu_item_call.on_enable
+ function="Object.EnableStandUp" />
+ </menu_item_call>
+ <menu_item_call
+ label="Object Profile"
+ name="Object Inspect">
+ <menu_item_call.on_click
+ function="Object.Inspect" />
+ <menu_item_call.on_enable
+ function="Object.EnableInspect" />
+ </menu_item_call>
+ <menu_item_call
+ label="Zoom In"
+ name="Zoom In">
+ <menu_item_call.on_click
+ function="Object.ZoomIn" />
+ </menu_item_call>
+ <menu_item_call
+ label="Show in linksets"
+ name="show_in_linksets">
+ <menu_item_call.on_click
+ function="Pathfinding.Linksets.Select" />
+ <menu_item_call.on_enable
+ function="EnableSelectInPathfindingLinksets"/>
+ <menu_item_call.on_visible
+ function="EnableSelectInPathfindingLinksets"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Show in characters"
+ name="show_in_characters">
+ <menu_item_call.on_click
+ function="Pathfinding.Characters.Select" />
+ <menu_item_call.on_enable
+ function="EnableSelectInPathfindingCharacters"/>
+ <menu_item_call.on_visible
+ function="EnableSelectInPathfindingCharacters"/>
+ </menu_item_call>
+ <menu_item_separator layout="topleft" />
+ <context_menu
+ label="Put On"
+ name="Put On" >
+ <menu_item_call
+ enabled="false"
+ label="Wear"
+ name="Wear">
<menu_item_call.on_click
- function="Object.Take"/>
+ function="Object.AttachToAvatar" />
<menu_item_call.on_enable
- function="Object.VisibleTake"/>
- </menu_item_call>
- <menu_item_call
- enabled="false"
- label="Take Copy"
- name="Take Copy">
+ function="Object.EnableWear" />
+ </menu_item_call>
+ <menu_item_call
+ enabled="false"
+ label="Add"
+ name="Add">
<menu_item_call.on_click
- function="Tools.TakeCopy" />
+ function="Object.AttachAddToAvatar" />
<menu_item_call.on_enable
- function="Tools.EnableTakeCopy" />
- </menu_item_call>
- <menu_item_call
- enabled="false"
- label="Pay"
- name="Pay...">
- <menu_item_call.on_click
- function="PayObject" />
- <menu_item_call.on_enable
- function="EnablePayObject" />
-</menu_item_call>
- <menu_item_call
- enabled="false"
- label="Buy"
- name="Buy...">
+ function="Object.EnableWear" />
+ </menu_item_call>
+ <context_menu
+ label="Attach"
+ name="Object Attach" />
+ <context_menu
+ label="Attach HUD"
+ name="Object Attach HUD" />
+ </context_menu>
+ <context_menu
+ label="Manage"
+ name="Remove">
+ <menu_item_call
+ enabled="false"
+ label="Report Abuse"
+ name="Report Abuse...">
<menu_item_call.on_click
- function="Object.Buy" />
+ function="Object.ReportAbuse" />
<menu_item_call.on_enable
- function="Object.EnableBuy" />
- </menu_item_call>
- <menu_item_call
- enabled="false"
- label="Delete"
- name="Delete">
+ function="Object.EnableReportAbuse" />
+ </menu_item_call>
+ <menu_item_call
+ enabled="false"
+ label="Block"
+ name="Object Mute">
<menu_item_call.on_click
- function="Object.Delete" />
+ function="Object.Mute" />
<menu_item_call.on_enable
- function="Object.EnableDelete" />
+ function="Object.EnableMute" />
+ </menu_item_call>
+ <menu_item_call
+ enabled="false"
+ label="Return"
+ name="Return...">
+ <menu_item_call.on_click
+ function="Object.Return" />
+ <menu_item_call.on_enable
+ function="Object.EnableReturn" />
+ </menu_item_call>
+ </context_menu>
+ <menu_item_separator layout="topleft" />
+ <menu_item_call
+ label="Take"
+ layout="topleft"
+ name="Pie Object Take">
+ <menu_item_call.on_click
+ function="Object.Take"/>
+ <menu_item_call.on_enable
+ function="Object.VisibleTake"/>
+ </menu_item_call>
+ <menu_item_call
+ enabled="false"
+ label="Take Copy"
+ name="Take Copy">
+ <menu_item_call.on_click
+ function="Tools.TakeCopy" />
+ <menu_item_call.on_enable
+ function="Tools.EnableTakeCopy" />
+ </menu_item_call>
+ <menu_item_call
+ enabled="false"
+ label="Pay"
+ name="Pay...">
+ <menu_item_call.on_click
+ function="PayObject" />
+ <menu_item_call.on_enable
+ function="EnablePayObject" />
+ </menu_item_call>
+ <menu_item_call
+ enabled="false"
+ label="Buy"
+ name="Buy...">
+ <menu_item_call.on_click
+ function="Object.Buy" />
+ <menu_item_call.on_enable
+ function="Object.EnableBuy" />
+ </menu_item_call>
+ <menu_item_call
+ enabled="false"
+ label="Delete"
+ name="Delete">
+ <menu_item_call.on_click
+ function="Object.Delete" />
+ <menu_item_call.on_enable
+ function="Object.EnableDelete" />
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_call
+ enabled="false"
+ label="Block Particle Owner"
+ name="Mute Particle">
+ <menu_item_call.on_click
+ function="Particle.Mute" />
+ <menu_item_call.on_enable
+ function="EnableMuteParticle" />
</menu_item_call>
</context_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_object_icon.xml b/indra/newview/skins/default/xui/en/menu_object_icon.xml
index 0c8a2af002..2d4f1792c2 100644..100755
--- a/indra/newview/skins/default/xui/en/menu_object_icon.xml
+++ b/indra/newview/skins/default/xui/en/menu_object_icon.xml
@@ -24,4 +24,22 @@
function="ObjectIcon.Action"
parameter="block" />
</menu_item_call>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_call
+ label="Show on Map"
+ layout="topleft"
+ name="show_on_map">
+ <menu_item_call.on_click
+ function="ObjectIcon.Action"
+ parameter="map" />
+ </menu_item_call>
+ <menu_item_call
+ label="Teleport to Object Location"
+ layout="topleft"
+ name="teleport_to_object">
+ <menu_item_call.on_click
+ function="ObjectIcon.Action"
+ parameter="teleport" />
+ </menu_item_call>
</menu>
diff --git a/indra/newview/skins/default/xui/en/menu_outfit_gear.xml b/indra/newview/skins/default/xui/en/menu_outfit_gear.xml
index fc7272b904..3b8ace6308 100644..100755
--- a/indra/newview/skins/default/xui/en/menu_outfit_gear.xml
+++ b/indra/newview/skins/default/xui/en/menu_outfit_gear.xml
@@ -195,6 +195,20 @@
<menu_item_separator name="sepatator2" />
<menu_item_call
+ label="Expand all folders"
+ layout="topleft"
+ name="expand">
+ <on_click
+ function="Gear.Expand" />
+ </menu_item_call>
+ <menu_item_call
+ label="Collapse all folders"
+ layout="topleft"
+ name="collapse">
+ <on_click
+ function="Gear.Collapse" />
+ </menu_item_call>
+ <menu_item_call
label="Rename Outfit"
layout="topleft"
name="rename">
diff --git a/indra/newview/skins/default/xui/en/menu_outfit_tab.xml b/indra/newview/skins/default/xui/en/menu_outfit_tab.xml
index 8c8bb29baf..8c8bb29baf 100644..100755
--- a/indra/newview/skins/default/xui/en/menu_outfit_tab.xml
+++ b/indra/newview/skins/default/xui/en/menu_outfit_tab.xml
diff --git a/indra/newview/skins/default/xui/en/menu_participant_list.xml b/indra/newview/skins/default/xui/en/menu_participant_list.xml
index 2c32d9d303..2c32d9d303 100644..100755
--- a/indra/newview/skins/default/xui/en/menu_participant_list.xml
+++ b/indra/newview/skins/default/xui/en/menu_participant_list.xml
diff --git a/indra/newview/skins/default/xui/en/menu_participant_view.xml b/indra/newview/skins/default/xui/en/menu_participant_view.xml
new file mode 100755
index 0000000000..7ea87ee05c
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_participant_view.xml
@@ -0,0 +1,112 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu
+ layout="topleft"
+ name="participant_manu_view">
+ <menu_item_check
+ label="Sort conversations by type"
+ layout="topleft"
+ name="sort_sessions_by_type">
+ <on_click
+ function="IMFloaterContainer.Action"
+ parameter="sort_sessions_by_type" />
+ <on_check
+ function="IMFloaterContainer.Check"
+ parameter="sort_sessions_by_type" />
+ </menu_item_check>
+ <menu_item_check
+ label="Sort conversations by name"
+ layout="topleft"
+ name="sort_sessions_by_name">
+ <on_click
+ function="IMFloaterContainer.Action"
+ parameter="sort_sessions_by_name" />
+ <on_check
+ function="IMFloaterContainer.Check"
+ parameter="sort_sessions_by_name" />
+ </menu_item_check>
+ <menu_item_check
+ label="Sort conversations by recent activity"
+ layout="topleft"
+ name="sort_sessions_by_recent">
+ <on_click
+ function="IMFloaterContainer.Action"
+ parameter="sort_sessions_by_recent" />
+ <on_check
+ function="IMFloaterContainer.Check"
+ parameter="sort_sessions_by_recent" />
+ </menu_item_check>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_check
+ label="Sort participants by name"
+ layout="topleft"
+ name="sort_participants_by_name">
+ <on_click
+ function="IMFloaterContainer.Action"
+ parameter="sort_participants_by_name" />
+ <on_check
+ function="IMFloaterContainer.Check"
+ parameter="sort_participants_by_name" />
+ </menu_item_check>
+ <menu_item_check
+ label="Sort participants by recent activity"
+ layout="topleft"
+ name="sort_participants_by_recent">
+ <on_click
+ function="IMFloaterContainer.Action"
+ parameter="sort_participants_by_recent" />
+ <on_check
+ function="IMFloaterContainer.Check"
+ parameter="sort_participants_by_recent" />
+ </menu_item_check>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_call
+ label="Chat preferences..."
+ name="chat_preferences">
+ <on_click
+ function="IMFloaterContainer.Action"
+ parameter="chat_preferences" />
+ </menu_item_call>
+ <menu_item_call
+ label="Privacy preferences..."
+ name="privacy_preferences">
+ <on_click
+ function="IMFloaterContainer.Action"
+ parameter="privacy_preferences" />
+ </menu_item_call>
+ <menu_item_check
+ label="Conversation log..."
+ name="Conversation"
+ visible="true">
+ <menu_item_check.on_check
+ function="Floater.Visible"
+ parameter="conversation" />
+ <menu_item_check.on_click
+ function="Floater.Toggle"
+ parameter="conversation" />
+ <menu_item_check.on_enable
+ function="Avatar.EnableItem"
+ parameter="conversation_log" />
+ </menu_item_check>
+ <menu_item_separator layout="topleft" />
+ <menu_item_check name="Translate_chat" label="Translate Nearby chat">
+ <menu_item_check.on_click
+ function="IMFloaterContainer.Action"
+ parameter="Translating.Toggle" />
+ <menu_item_check.on_check
+ function="IMFloaterContainer.Check"
+ parameter="Translating.On" />
+ <menu_item_check.on_enable
+ function="IMFloaterContainer.Check"
+ parameter="Translating.Enabled" />
+ </menu_item_check>
+ <menu_item_check name="Translation_settings" label="Translation settings...">
+ <menu_item_check.on_check
+ function="Floater.Visible"
+ parameter="prefs_translation" />
+ <menu_item_check.on_click
+ function="Floater.Toggle"
+ parameter="prefs_translation" />
+ </menu_item_check>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_people_blocked_gear.xml b/indra/newview/skins/default/xui/en/menu_people_blocked_gear.xml
new file mode 100755
index 0000000000..63295ea27b
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_people_blocked_gear.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu
+ name="menu_blocked_gear"
+ left="0" bottom="0" visible="false"
+ mouse_opaque="false">
+ <menu_item_call
+ label="Unblock"
+ name="unblock">
+ <on_click
+ function="Block.Action"
+ parameter="unblock_item" />
+ <on_enable
+ function="Block.Enable"
+ parameter="unblock_item" />
+ </menu_item_call>
+ <menu_item_call
+ label="Profile..."
+ name="profile">
+ <on_click
+ function="Block.Action"
+ parameter="profile_item"/>
+ <on_enable
+ function="Block.Enable"
+ parameter="profile_item" />
+ </menu_item_call>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_people_blocked_plus.xml b/indra/newview/skins/default/xui/en/menu_people_blocked_plus.xml
new file mode 100755
index 0000000000..0c7155667e
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_people_blocked_plus.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu
+ name="menu_blocked_plus"
+ left="0" bottom="0" visible="false"
+ mouse_opaque="false">
+ <menu_item_call
+ label="Block Resident by name..."
+ name="block_resident_by_name">
+ <on_click
+ function="Block.Action"
+ parameter="block_res_by_name"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Block object by name"
+ name="block_object_by_name">
+ <on_click
+ function="Block.Action"
+ parameter="block_obj_by_name"/>
+ </menu_item_call>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_people_blocked_view.xml b/indra/newview/skins/default/xui/en/menu_people_blocked_view.xml
new file mode 100755
index 0000000000..2efb70ee37
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_people_blocked_view.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu
+ name="menu_blocked_view"
+ left="0" bottom="0" visible="false"
+ mouse_opaque="false">
+ <menu_item_check
+ label="Sort by name"
+ name="sort_by_name">
+ <on_click
+ function="Block.Action"
+ parameter="sort_by_name"/>
+ <on_check
+ function="Block.Check"
+ parameter="sort_by_name"/>
+ </menu_item_check>
+ <menu_item_check
+ label="Sort by type"
+ name="sort_by_type">
+ <on_click
+ function="Block.Action"
+ parameter="sort_by_type" />
+ <on_check
+ function="Block.Check"
+ parameter="sort_by_type" />
+ </menu_item_check>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_people_friends_view.xml b/indra/newview/skins/default/xui/en/menu_people_friends_view.xml
new file mode 100755
index 0000000000..8790fde7c5
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_people_friends_view.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu
+ name="menu_group_plus"
+ left="0" bottom="0" visible="false"
+ mouse_opaque="false">
+ <menu_item_check
+ label="Sort by Name"
+ name="sort_name">
+ <menu_item_check.on_click
+ function="People.Friends.ViewSort.Action"
+ parameter="sort_name" />
+ <menu_item_check.on_check
+ function="People.Friends.ViewSort.CheckItem"
+ parameter="sort_name" />
+ </menu_item_check>
+ <menu_item_check
+ label="Sort by Status"
+ name="sort_status">
+ <menu_item_check.on_click
+ function="People.Friends.ViewSort.Action"
+ parameter="sort_status" />
+ <menu_item_check.on_check
+ function="People.Friends.ViewSort.CheckItem"
+ parameter="sort_status" />
+ </menu_item_check>
+ <menu_item_separator layout="topleft" />
+ <menu_item_check name="view_icons" label="View People Icons">
+ <menu_item_check.on_click
+ function="People.Friends.ViewSort.Action"
+ parameter="view_icons" />
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="FriendsListShowIcons" />
+ </menu_item_check>
+ <menu_item_check name="view_permissions" label="View Permissions Granted">
+ <menu_item_check.on_click
+ function="People.Friends.ViewSort.Action"
+ parameter="view_permissions" />
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="FriendsListShowPermissions" />
+ </menu_item_check>
+ <menu_item_check name="view_conversation" label="View Conversation Log...">
+ <menu_item_check.on_check
+ function="Floater.Visible"
+ parameter="conversation" />
+ <menu_item_check.on_enable
+ function="Conversation.IsConversationLoggingAllowed" />
+ <menu_item_check.on_click
+ function="Floater.Toggle"
+ parameter="conversation" />
+ </menu_item_check>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_people_friends_view_sort.xml b/indra/newview/skins/default/xui/en/menu_people_friends_view_sort.xml
deleted file mode 100644
index b452f96e7a..0000000000
--- a/indra/newview/skins/default/xui/en/menu_people_friends_view_sort.xml
+++ /dev/null
@@ -1,47 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<toggleable_menu
- name="menu_group_plus"
- left="0" bottom="0" visible="false"
- mouse_opaque="false">
- <menu_item_check
- label="Sort by Name"
- name="sort_name">
- <menu_item_check.on_click
- function="People.Friends.ViewSort.Action"
- parameter="sort_name" />
- <menu_item_check.on_check
- function="People.Friends.ViewSort.CheckItem"
- parameter="sort_name" />
- </menu_item_check>
- <menu_item_check
- label="Sort by Status"
- name="sort_status">
- <menu_item_check.on_click
- function="People.Friends.ViewSort.Action"
- parameter="sort_status" />
- <menu_item_check.on_check
- function="People.Friends.ViewSort.CheckItem"
- parameter="sort_status" />
- </menu_item_check>
- <menu_item_separator layout="topleft" />
- <menu_item_check name="view_icons" label="View People Icons">
- <menu_item_check.on_click
- function="People.Friends.ViewSort.Action"
- parameter="view_icons" />
- <menu_item_check.on_check
- function="CheckControl"
- parameter="FriendsListShowIcons" />
- </menu_item_check>
- <menu_item_check name="view_permissions" label="View Permissions Granted">
- <menu_item_check.on_click
- function="People.Friends.ViewSort.Action"
- parameter="view_permissions" />
- <menu_item_check.on_check
- function="CheckControl"
- parameter="FriendsListShowPermissions" />
- </menu_item_check>
- <menu_item_separator layout="topleft" />
- <menu_item_call name="show_blocked_list" label="Show Blocked Residents &amp; Objects">
- <menu_item_call.on_click function="People.Friends.ViewSort.Action" parameter="panel_block_list_sidetray" />
- </menu_item_call>
-</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_people_groups.xml b/indra/newview/skins/default/xui/en/menu_people_groups.xml
index 8f89d37dbb..1e0364b84e 100644..100755
--- a/indra/newview/skins/default/xui/en/menu_people_groups.xml
+++ b/indra/newview/skins/default/xui/en/menu_people_groups.xml
@@ -1,8 +1,18 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<menu name="menu_group_plus"
+<toggleable_menu name="menu_group_plus"
left="0" bottom="0" visible="false"
mouse_opaque="false" opaque="true" color="MenuDefaultBgColor">
<menu_item_call
+ label="Activate"
+ name="Activate">
+ <menu_item_call.on_click
+ function="People.Groups.Action"
+ parameter="activate" />
+ <menu_item_call.on_enable
+ function="People.Groups.Enable"
+ parameter="activate" />
+ </menu_item_call>
+ <menu_item_call
label="View Info"
name="View Info">
<menu_item_call.on_click
@@ -23,7 +33,7 @@
parameter="chat" />
</menu_item_call>
<menu_item_call
- label="Call"
+ label="Voice call"
name="Call">
<menu_item_call.on_click
function="People.Groups.Action"
@@ -34,17 +44,6 @@
</menu_item_call>
<menu_item_separator />
<menu_item_call
- label="Activate"
- name="Activate">
- <menu_item_call.on_click
- function="People.Groups.Action"
- parameter="activate" />
- <menu_item_call.on_enable
- function="People.Groups.Enable"
- parameter="activate" />
- </menu_item_call>
- <menu_item_separator />
- <menu_item_call
label="Leave"
name="Leave">
<menu_item_call.on_click
@@ -54,4 +53,4 @@
function="People.Groups.Enable"
parameter="leave" />
</menu_item_call>
-</menu>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_people_groups_view.xml b/indra/newview/skins/default/xui/en/menu_people_groups_view.xml
new file mode 100755
index 0000000000..73f79f1e70
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_people_groups_view.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu
+ name="menu_group_plus"
+ left="0" bottom="0" visible="false"
+ mouse_opaque="false">
+ <menu_item_check
+ label="Display Group Icons"
+ layout="topleft"
+ name="Display Group Icons">
+ <menu_item_check.on_click
+ function="People.Groups.ViewSort.Action"
+ parameter="show_icons" />
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="GroupListShowIcons" />
+ </menu_item_check>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_people_groups_view_sort.xml b/indra/newview/skins/default/xui/en/menu_people_groups_view_sort.xml
deleted file mode 100644
index c710fe3b9b..0000000000
--- a/indra/newview/skins/default/xui/en/menu_people_groups_view_sort.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<toggleable_menu
- name="menu_group_plus"
- left="0" bottom="0" visible="false"
- mouse_opaque="false">
- <menu_item_check
- label="Display Group Icons"
- layout="topleft"
- name="Display Group Icons">
- <menu_item_check.on_click
- function="People.Groups.ViewSort.Action"
- parameter="show_icons" />
- <menu_item_check.on_check
- function="CheckControl"
- parameter="GroupListShowIcons" />
- </menu_item_check>
- <menu_item_call
- label="Leave Selected Group"
- layout="topleft"
- name="Leave Selected Group">
- <menu_item_call.on_click
- function="People.Group.Minus.Action"/>
- <menu_item_call.on_enable
- function="People.Group.Minus.Enable"/>
- </menu_item_call>
-</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_people_nearby.xml b/indra/newview/skins/default/xui/en/menu_people_nearby.xml
index d2e35e4cc0..f12226ebeb 100644..100755
--- a/indra/newview/skins/default/xui/en/menu_people_nearby.xml
+++ b/indra/newview/skins/default/xui/en/menu_people_nearby.xml
@@ -1,28 +1,78 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<context_menu
layout="topleft"
- name="Avatar Context Menu">
+ name="Nearby People Context Menu">
<menu_item_call
label="View Profile"
layout="topleft"
- name="View Profile">
+ name="view_profile">
<menu_item_call.on_click
function="Avatar.Profile" />
</menu_item_call>
<menu_item_call
+ label="IM"
+ layout="topleft"
+ name="im">
+ <menu_item_call.on_click
+ function="Avatar.IM" />
+ <menu_item_call.on_enable
+ function="Avatar.EnableItem"
+ parameter="can_im"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Offer Teleport"
+ name="offer_teleport">
+ <menu_item_call.on_click
+ function="Avatar.OfferTeleport"/>
+ <menu_item_call.on_enable
+ function="Avatar.EnableItem"
+ parameter="can_offer_teleport"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Request Teleport"
+ name="request_teleport">
+ <menu_item_call.on_click
+ function="Avatar.TeleportRequest"/>
+ <menu_item_call.on_enable
+ function="Avatar.EnableItem"
+ parameter="can_offer_teleport"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Voice call"
+ layout="topleft"
+ name="voice_call">
+ <menu_item_call.on_click
+ function="Avatar.Call" />
+ <menu_item_call.on_enable
+ function="Avatar.EnableItem"
+ parameter="can_call" />
+ </menu_item_call>
+ <menu_item_separator />
+ <menu_item_call
+ label="View chat history..."
+ layout="topleft"
+ name="chat_history">
+ <menu_item_call.on_click
+ function="Avatar.Calllog" />
+ <menu_item_call.on_enable
+ function="Avatar.EnableItem"
+ parameter="can_callog"/>
+ </menu_item_call>
+ <menu_item_separator name="separator_chat_history"/>
+ <menu_item_call
label="Add Friend"
layout="topleft"
- name="Add Friend">
+ name="add_friend">
<menu_item_call.on_click
function="Avatar.AddFriend" />
- <menu_item_call.on_enable
+ <menu_item_call.on_visible
function="Avatar.EnableItem"
parameter="can_add" />
</menu_item_call>
<menu_item_call
label="Remove Friend"
layout="topleft"
- name="Remove Friend">
+ name="remove_friend">
<menu_item_call.on_click
function="Avatar.RemoveFriend" />
<menu_item_call.on_enable
@@ -30,26 +80,30 @@
parameter="can_delete" />
</menu_item_call>
<menu_item_call
- label="IM"
+ label="Invite to group..."
layout="topleft"
- name="IM">
+ name="invite_to_group">
<menu_item_call.on_click
- function="Avatar.IM" />
+ function="Avatar.InviteToGroup" />
+ <menu_item_call.on_enable
+ function="Avatar.EnableItem"
+ parameter="can_invite"/>
</menu_item_call>
+ <menu_item_separator name="separator_invite_to_group"/>
<menu_item_call
- label="Call"
+ label="Zoom In"
layout="topleft"
- name="Call">
- <menu_item_call.on_click
- function="Avatar.Call" />
- <menu_item_call.on_enable
- function="Avatar.EnableItem"
- parameter="can_call" />
+ name="zoom_in">
+ <menu_item_call.on_click
+ function="Avatar.ZoomIn" />
+ <menu_item_call.on_enable
+ function="Avatar.EnableItem"
+ parameter="can_zoom_in"/>
</menu_item_call>
<menu_item_call
label="Map"
layout="topleft"
- name="Map">
+ name="map">
<menu_item_call.on_click
function="Avatar.ShowOnMap" />
<menu_item_call.on_enable
@@ -59,21 +113,27 @@
<menu_item_call
label="Share"
layout="topleft"
- name="Share">
+ name="share">
<menu_item_call.on_click
function="Avatar.Share" />
+ <menu_item_call.on_enable
+ function="Avatar.EnableItem"
+ parameter="can_share"/>
</menu_item_call>
<menu_item_call
label="Pay"
layout="topleft"
- name="Pay">
+ name="pay">
<menu_item_call.on_click
function="Avatar.Pay" />
+ <menu_item_call.on_enable
+ function="Avatar.EnableItem"
+ parameter="can_pay"/>
</menu_item_call>
<menu_item_check
label="Block/Unblock"
layout="topleft"
- name="Block/Unblock">
+ name="block_unblock">
<menu_item_check.on_click
function="Avatar.BlockUnblock" />
<menu_item_check.on_check
@@ -83,13 +143,4 @@
function="Avatar.EnableItem"
parameter="can_block" />
</menu_item_check>
- <menu_item_call
- label="Offer Teleport"
- name="teleport">
- <menu_item_call.on_click
- function="Avatar.OfferTeleport"/>
- <menu_item_call.on_enable
- function="Avatar.EnableItem"
- parameter="can_offer_teleport"/>
- </menu_item_call>
</context_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_people_nearby_multiselect.xml b/indra/newview/skins/default/xui/en/menu_people_nearby_multiselect.xml
index 5d58a9d289..5f973088fd 100644..100755
--- a/indra/newview/skins/default/xui/en/menu_people_nearby_multiselect.xml
+++ b/indra/newview/skins/default/xui/en/menu_people_nearby_multiselect.xml
@@ -6,7 +6,7 @@
enabled="false"
label="Add Friends"
layout="topleft"
- name="Add Friends">
+ name="add_friends">
<on_click
function="Avatar.AddFriends" />
<on_enable
@@ -16,7 +16,7 @@
<menu_item_call
label="Remove Friends"
layout="topleft"
- name="Remove Friend">
+ name="remove_friends">
<menu_item_call.on_click
function="Avatar.RemoveFriend" />
<menu_item_call.on_enable
@@ -26,7 +26,7 @@
<menu_item_call
label="IM"
layout="topleft"
- name="IM">
+ name="im">
<on_click
function="Avatar.IM" />
</menu_item_call>
@@ -34,7 +34,7 @@
enabled="false"
label="Call"
layout="topleft"
- name="Call">
+ name="call">
<on_click
function="Avatar.Call" />
<on_enable
@@ -45,7 +45,7 @@
enabled="false"
label="Share"
layout="topleft"
- name="Share">
+ name="share">
<on_click
function="Avatar.Share" />
</menu_item_call>
@@ -53,13 +53,13 @@
enabled="false"
label="Pay"
layout="topleft"
- name="Pay">
+ name="pay">
<on_click
function="Avatar.Pay" />
</menu_item_call>
<menu_item_call
label="Offer Teleport"
- name="teleport">
+ name="offer_teleport">
<menu_item_call.on_click
function="Avatar.OfferTeleport"/>
<menu_item_call.on_enable
diff --git a/indra/newview/skins/default/xui/en/menu_people_nearby_view.xml b/indra/newview/skins/default/xui/en/menu_people_nearby_view.xml
new file mode 100755
index 0000000000..da88ca9f4d
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_people_nearby_view.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu
+ name="menu_group_plus"
+ left="0" bottom="0" visible="false"
+ mouse_opaque="false">
+ <menu_item_check
+ label="Sort by Recent Speakers"
+ name="sort_by_recent_speakers">
+ <menu_item_check.on_click
+ function="People.Nearby.ViewSort.Action"
+ parameter="sort_by_recent_speakers"/>
+ <menu_item_check.on_check
+ function="People.Nearby.ViewSort.CheckItem"
+ parameter="sort_by_recent_speakers"/>
+ </menu_item_check>
+ <menu_item_check
+ label="Sort by Name"
+ name="sort_name">
+ <menu_item_check.on_click
+ function="People.Nearby.ViewSort.Action"
+ parameter="sort_name"/>
+ <menu_item_check.on_check
+ function="People.Nearby.ViewSort.CheckItem"
+ parameter="sort_name"/>
+ </menu_item_check>
+ <menu_item_check
+ label="Sort by Distance"
+ name="sort_distance">
+ <menu_item_check.on_click
+ function="People.Nearby.ViewSort.Action"
+ parameter="sort_distance"/>
+ <menu_item_check.on_check
+ function="People.Nearby.ViewSort.CheckItem"
+ parameter="sort_distance"/>
+ </menu_item_check>
+ <menu_item_separator layout="topleft" />
+ <menu_item_check name="view_icons" label="View People Icons">
+ <menu_item_check.on_click
+ function="People.Nearby.ViewSort.Action"
+ parameter="view_icons" />
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="NearbyListShowIcons" />
+ </menu_item_check>
+ <menu_item_check name ="view_map" label="View Map">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="NearbyListShowMap" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="NearbyListShowMap" />
+ </menu_item_check>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_people_nearby_view_sort.xml b/indra/newview/skins/default/xui/en/menu_people_nearby_view_sort.xml
deleted file mode 100644
index 614dd693c5..0000000000
--- a/indra/newview/skins/default/xui/en/menu_people_nearby_view_sort.xml
+++ /dev/null
@@ -1,57 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<toggleable_menu
- name="menu_group_plus"
- left="0" bottom="0" visible="false"
- mouse_opaque="false">
- <menu_item_check
- label="Sort by Recent Speakers"
- name="sort_by_recent_speakers">
- <menu_item_check.on_click
- function="People.Nearby.ViewSort.Action"
- parameter="sort_by_recent_speakers"/>
- <menu_item_check.on_check
- function="People.Nearby.ViewSort.CheckItem"
- parameter="sort_by_recent_speakers"/>
- </menu_item_check>
- <menu_item_check
- label="Sort by Name"
- name="sort_name">
- <menu_item_check.on_click
- function="People.Nearby.ViewSort.Action"
- parameter="sort_name"/>
- <menu_item_check.on_check
- function="People.Nearby.ViewSort.CheckItem"
- parameter="sort_name"/>
- </menu_item_check>
- <menu_item_check
- label="Sort by Distance"
- name="sort_distance">
- <menu_item_check.on_click
- function="People.Nearby.ViewSort.Action"
- parameter="sort_distance"/>
- <menu_item_check.on_check
- function="People.Nearby.ViewSort.CheckItem"
- parameter="sort_distance"/>
- </menu_item_check>
- <menu_item_separator layout="topleft" />
- <menu_item_check name="view_icons" label="View People Icons">
- <menu_item_check.on_click
- function="People.Nearby.ViewSort.Action"
- parameter="view_icons" />
- <menu_item_check.on_check
- function="CheckControl"
- parameter="NearbyListShowIcons" />
- </menu_item_check>
- <menu_item_check name ="view_map" label="View Map">
- <menu_item_check.on_check
- function="CheckControl"
- parameter="NearbyListShowMap" />
- <menu_item_check.on_click
- function="ToggleControl"
- parameter="NearbyListShowMap" />
- </menu_item_check>
- <menu_item_separator layout="topleft" />
- <menu_item_call name="show_blocked_list" label="Show Blocked Residents &amp; Objects">
- <menu_item_call.on_click function="People.Nearby.ViewSort.Action" userdata="panel_block_list_sidetray" />
- </menu_item_call>
-</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_people_recent_view.xml b/indra/newview/skins/default/xui/en/menu_people_recent_view.xml
new file mode 100755
index 0000000000..1dbc90dd2b
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_people_recent_view.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu
+ name="menu_group_plus"
+ left="0" bottom="0" visible="false"
+ mouse_opaque="false">
+ <menu_item_check
+ label="Sort by Most Recent"
+ name="sort_most">
+ <menu_item_check.on_click
+ function="People.Recent.ViewSort.Action"
+ parameter="sort_recent" />
+ <menu_item_check.on_check
+ function="People.Recent.ViewSort.CheckItem"
+ parameter="sort_recent" />
+ </menu_item_check>
+ <menu_item_check
+ label="Sort by Name"
+ name="sort_name">
+ <menu_item_check.on_click
+ function="People.Recent.ViewSort.Action"
+ parameter="sort_name" />
+ <menu_item_check.on_check
+ function="People.Recent.ViewSort.CheckItem"
+ parameter="sort_name" />
+ </menu_item_check>
+ <menu_item_separator layout="topleft" />
+ <menu_item_check name="view_icons" label="View People Icons">
+ <menu_item_check.on_click
+ function="People.Recent.ViewSort.Action"
+ parameter="view_icons" />
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="RecentListShowIcons" />
+ </menu_item_check>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_people_recent_view_sort.xml b/indra/newview/skins/default/xui/en/menu_people_recent_view_sort.xml
deleted file mode 100644
index 485a5a658c..0000000000
--- a/indra/newview/skins/default/xui/en/menu_people_recent_view_sort.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<toggleable_menu
- name="menu_group_plus"
- left="0" bottom="0" visible="false"
- mouse_opaque="false">
- <menu_item_check
- label="Sort by Most Recent"
- name="sort_most">
- <menu_item_check.on_click
- function="People.Recent.ViewSort.Action"
- parameter="sort_recent" />
- <menu_item_check.on_check
- function="People.Recent.ViewSort.CheckItem"
- parameter="sort_recent" />
- </menu_item_check>
- <menu_item_check
- label="Sort by Name"
- name="sort_name">
- <menu_item_check.on_click
- function="People.Recent.ViewSort.Action"
- parameter="sort_name" />
- <menu_item_check.on_check
- function="People.Recent.ViewSort.CheckItem"
- parameter="sort_name" />
- </menu_item_check>
- <menu_item_separator layout="topleft" />
- <menu_item_check name="view_icons" label="View People Icons">
- <menu_item_check.on_click
- function="People.Recent.ViewSort.Action"
- parameter="view_icons" />
- <menu_item_check.on_check
- function="CheckControl"
- parameter="RecentListShowIcons" />
- </menu_item_check>
- <menu_item_separator layout="topleft" />
- <menu_item_call name="show_blocked_list" label="Show Blocked Residents &amp; Objects">
- <menu_item_call.on_click function="People.Recent.ViewSort.Action" userdata="panel_block_list_sidetray" />
- </menu_item_call>
-</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_picks.xml b/indra/newview/skins/default/xui/en/menu_picks.xml
index ebb49c9004..ebb49c9004 100644..100755
--- a/indra/newview/skins/default/xui/en/menu_picks.xml
+++ b/indra/newview/skins/default/xui/en/menu_picks.xml
diff --git a/indra/newview/skins/default/xui/en/menu_picks_plus.xml b/indra/newview/skins/default/xui/en/menu_picks_plus.xml
index f3b207e36c..f3b207e36c 100644..100755
--- a/indra/newview/skins/default/xui/en/menu_picks_plus.xml
+++ b/indra/newview/skins/default/xui/en/menu_picks_plus.xml
diff --git a/indra/newview/skins/default/xui/en/menu_place.xml b/indra/newview/skins/default/xui/en/menu_place.xml
index 288811d2f6..288811d2f6 100644..100755
--- a/indra/newview/skins/default/xui/en/menu_place.xml
+++ b/indra/newview/skins/default/xui/en/menu_place.xml
diff --git a/indra/newview/skins/default/xui/en/menu_place_add_button.xml b/indra/newview/skins/default/xui/en/menu_place_add_button.xml
index e3a39a1242..e3a39a1242 100644..100755
--- a/indra/newview/skins/default/xui/en/menu_place_add_button.xml
+++ b/indra/newview/skins/default/xui/en/menu_place_add_button.xml
diff --git a/indra/newview/skins/default/xui/en/menu_places_gear_folder.xml b/indra/newview/skins/default/xui/en/menu_places_gear_folder.xml
index 1aeb166e01..1aeb166e01 100644..100755
--- a/indra/newview/skins/default/xui/en/menu_places_gear_folder.xml
+++ b/indra/newview/skins/default/xui/en/menu_places_gear_folder.xml
diff --git a/indra/newview/skins/default/xui/en/menu_places_gear_landmark.xml b/indra/newview/skins/default/xui/en/menu_places_gear_landmark.xml
index ff5fdd3795..ff5fdd3795 100644..100755
--- a/indra/newview/skins/default/xui/en/menu_places_gear_landmark.xml
+++ b/indra/newview/skins/default/xui/en/menu_places_gear_landmark.xml
diff --git a/indra/newview/skins/default/xui/en/menu_profile_overflow.xml b/indra/newview/skins/default/xui/en/menu_profile_overflow.xml
index b0b7b554b0..b0b7b554b0 100644..100755
--- a/indra/newview/skins/default/xui/en/menu_profile_overflow.xml
+++ b/indra/newview/skins/default/xui/en/menu_profile_overflow.xml
diff --git a/indra/newview/skins/default/xui/en/menu_save_outfit.xml b/indra/newview/skins/default/xui/en/menu_save_outfit.xml
index 6285bf7417..6285bf7417 100644..100755
--- a/indra/newview/skins/default/xui/en/menu_save_outfit.xml
+++ b/indra/newview/skins/default/xui/en/menu_save_outfit.xml
diff --git a/indra/newview/skins/default/xui/en/menu_script_chiclet.xml b/indra/newview/skins/default/xui/en/menu_script_chiclet.xml
index db29d9cebc..db29d9cebc 100644..100755
--- a/indra/newview/skins/default/xui/en/menu_script_chiclet.xml
+++ b/indra/newview/skins/default/xui/en/menu_script_chiclet.xml
diff --git a/indra/newview/skins/default/xui/en/menu_slurl.xml b/indra/newview/skins/default/xui/en/menu_slurl.xml
index ee37d49946..ee37d49946 100644..100755
--- a/indra/newview/skins/default/xui/en/menu_slurl.xml
+++ b/indra/newview/skins/default/xui/en/menu_slurl.xml
diff --git a/indra/newview/skins/default/xui/en/menu_teleport_history_gear.xml b/indra/newview/skins/default/xui/en/menu_teleport_history_gear.xml
index bc7d4fe33b..bc7d4fe33b 100644..100755
--- a/indra/newview/skins/default/xui/en/menu_teleport_history_gear.xml
+++ b/indra/newview/skins/default/xui/en/menu_teleport_history_gear.xml
diff --git a/indra/newview/skins/default/xui/en/menu_teleport_history_item.xml b/indra/newview/skins/default/xui/en/menu_teleport_history_item.xml
index 0160d52b17..0160d52b17 100644..100755
--- a/indra/newview/skins/default/xui/en/menu_teleport_history_item.xml
+++ b/indra/newview/skins/default/xui/en/menu_teleport_history_item.xml
diff --git a/indra/newview/skins/default/xui/en/menu_teleport_history_tab.xml b/indra/newview/skins/default/xui/en/menu_teleport_history_tab.xml
index ecc1d8a954..ecc1d8a954 100644..100755
--- a/indra/newview/skins/default/xui/en/menu_teleport_history_tab.xml
+++ b/indra/newview/skins/default/xui/en/menu_teleport_history_tab.xml
diff --git a/indra/newview/skins/default/xui/en/menu_text_editor.xml b/indra/newview/skins/default/xui/en/menu_text_editor.xml
index fe8489166b..70b40dd89b 100644..100755
--- a/indra/newview/skins/default/xui/en/menu_text_editor.xml
+++ b/indra/newview/skins/default/xui/en/menu_text_editor.xml
@@ -2,6 +2,85 @@
<context_menu
name="Text editor context menu">
<menu_item_call
+ label="(unknown)"
+ layout="topleft"
+ name="Suggestion 1">
+ <menu_item_call.on_click
+ function="SpellCheck.ReplaceWithSuggestion"
+ parameter="0" />
+ <menu_item_call.on_visible
+ function="SpellCheck.VisibleSuggestion"
+ parameter="0" />
+ </menu_item_call>
+ <menu_item_call
+ label="(unknown)"
+ layout="topleft"
+ name="Suggestion 2">
+ <menu_item_call.on_click
+ function="SpellCheck.ReplaceWithSuggestion"
+ parameter="1" />
+ <menu_item_call.on_visible
+ function="SpellCheck.VisibleSuggestion"
+ parameter="1" />
+ </menu_item_call>
+ <menu_item_call
+ label="(unknown)"
+ layout="topleft"
+ name="Suggestion 3">
+ <menu_item_call.on_click
+ function="SpellCheck.ReplaceWithSuggestion"
+ parameter="2" />
+ <menu_item_call.on_visible
+ function="SpellCheck.VisibleSuggestion"
+ parameter="2" />
+ </menu_item_call>
+ <menu_item_call
+ label="(unknown)"
+ layout="topleft"
+ name="Suggestion 4">
+ <menu_item_call.on_click
+ function="SpellCheck.ReplaceWithSuggestion"
+ parameter="3" />
+ <menu_item_call.on_visible
+ function="SpellCheck.VisibleSuggestion"
+ parameter="3" />
+ </menu_item_call>
+ <menu_item_call
+ label="(unknown)"
+ layout="topleft"
+ name="Suggestion 5">
+ <menu_item_call.on_click
+ function="SpellCheck.ReplaceWithSuggestion"
+ parameter="4" />
+ <menu_item_call.on_visible
+ function="SpellCheck.VisibleSuggestion"
+ parameter="4" />
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft"
+ name="Suggestion Separator" />
+ <menu_item_call
+ label="Add to Dictionary"
+ layout="topleft"
+ name="Add to Dictionary">
+ <menu_item_call.on_click
+ function="SpellCheck.AddToDictionary" />
+ <menu_item_call.on_enable
+ function="SpellCheck.EnableAddToDictionary" />
+ </menu_item_call>
+ <menu_item_call
+ label="Add to Ignore"
+ layout="topleft"
+ name="Add to Ignore">
+ <menu_item_call.on_click
+ function="SpellCheck.AddToIgnore" />
+ <menu_item_call.on_enable
+ function="SpellCheck.EnableAddToIgnore" />
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft"
+ name="Spellcheck Separator" />
+ <menu_item_call
label="Cut"
layout="topleft"
name="Cut">
diff --git a/indra/newview/skins/default/xui/en/menu_toolbars.xml b/indra/newview/skins/default/xui/en/menu_toolbars.xml
index fbe40a7244..fbe40a7244 100644..100755
--- a/indra/newview/skins/default/xui/en/menu_toolbars.xml
+++ b/indra/newview/skins/default/xui/en/menu_toolbars.xml
diff --git a/indra/newview/skins/default/xui/en/menu_topinfobar.xml b/indra/newview/skins/default/xui/en/menu_topinfobar.xml
index cbe249ed4d..cbe249ed4d 100644..100755
--- a/indra/newview/skins/default/xui/en/menu_topinfobar.xml
+++ b/indra/newview/skins/default/xui/en/menu_topinfobar.xml
diff --git a/indra/newview/skins/default/xui/en/menu_url_agent.xml b/indra/newview/skins/default/xui/en/menu_url_agent.xml
index 73f0fa7979..e8b6116026 100644..100755
--- a/indra/newview/skins/default/xui/en/menu_url_agent.xml
+++ b/indra/newview/skins/default/xui/en/menu_url_agent.xml
@@ -1,14 +1,35 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<context_menu
layout="topleft"
- name="Url Popup">
+ name="Url Popup">
<menu_item_call
- label="Show Resident Profile"
+ label="View Profile"
layout="topleft"
name="show_agent">
<menu_item_call.on_click
- function="Url.ShowProfile" />
+ function="Url.ShowProfile" />
</menu_item_call>
+ <menu_item_call
+ label="Send IM..."
+ layout="topleft"
+ name="send_im">
+ <menu_item_call.on_click
+ function="Url.SendIM" />
+ </menu_item_call>
+ <menu_item_call
+ label="Add Friend..."
+ layout="topleft"
+ name="add_friend">
+ <menu_item_call.on_click
+ function="Url.AddFriend" />
+ </menu_item_call>
+ <menu_item_call
+ label="Remove Friend..."
+ layout="topleft"
+ name="remove_friend">
+ <menu_item_call.on_click
+ function="Url.RemoveFriend" />
+ </menu_item_call>
<menu_item_separator
layout="topleft" />
<menu_item_call
diff --git a/indra/newview/skins/default/xui/en/menu_url_group.xml b/indra/newview/skins/default/xui/en/menu_url_group.xml
index 2cb125ce09..2cb125ce09 100644..100755
--- a/indra/newview/skins/default/xui/en/menu_url_group.xml
+++ b/indra/newview/skins/default/xui/en/menu_url_group.xml
diff --git a/indra/newview/skins/default/xui/en/menu_url_http.xml b/indra/newview/skins/default/xui/en/menu_url_http.xml
index 7a4b1e619b..7a4b1e619b 100644..100755
--- a/indra/newview/skins/default/xui/en/menu_url_http.xml
+++ b/indra/newview/skins/default/xui/en/menu_url_http.xml
diff --git a/indra/newview/skins/default/xui/en/menu_url_inventory.xml b/indra/newview/skins/default/xui/en/menu_url_inventory.xml
index cf9d1d5881..cf9d1d5881 100644..100755
--- a/indra/newview/skins/default/xui/en/menu_url_inventory.xml
+++ b/indra/newview/skins/default/xui/en/menu_url_inventory.xml
diff --git a/indra/newview/skins/default/xui/en/menu_url_map.xml b/indra/newview/skins/default/xui/en/menu_url_map.xml
index 2ca9e3b3fe..2ca9e3b3fe 100644..100755
--- a/indra/newview/skins/default/xui/en/menu_url_map.xml
+++ b/indra/newview/skins/default/xui/en/menu_url_map.xml
diff --git a/indra/newview/skins/default/xui/en/menu_url_objectim.xml b/indra/newview/skins/default/xui/en/menu_url_objectim.xml
index 35c2269b0d..b9d003b841 100644..100755
--- a/indra/newview/skins/default/xui/en/menu_url_objectim.xml
+++ b/indra/newview/skins/default/xui/en/menu_url_objectim.xml
@@ -3,12 +3,19 @@
layout="topleft"
name="Url Popup">
<menu_item_call
- label="Show Object Information"
+ label="Object Profile..."
layout="topleft"
name="show_object">
<menu_item_call.on_click
function="Url.Execute" />
</menu_item_call>
+ <menu_item_call
+ label="Block..."
+ layout="topleft"
+ name="block_object">
+ <menu_item_call.on_click
+ function="Url.Block" />
+ </menu_item_call>
<menu_item_separator
layout="topleft" />
<menu_item_call
diff --git a/indra/newview/skins/default/xui/en/menu_url_parcel.xml b/indra/newview/skins/default/xui/en/menu_url_parcel.xml
index f477c310fb..f477c310fb 100644..100755
--- a/indra/newview/skins/default/xui/en/menu_url_parcel.xml
+++ b/indra/newview/skins/default/xui/en/menu_url_parcel.xml
diff --git a/indra/newview/skins/default/xui/en/menu_url_slapp.xml b/indra/newview/skins/default/xui/en/menu_url_slapp.xml
index 6d1060b633..6d1060b633 100644..100755
--- a/indra/newview/skins/default/xui/en/menu_url_slapp.xml
+++ b/indra/newview/skins/default/xui/en/menu_url_slapp.xml
diff --git a/indra/newview/skins/default/xui/en/menu_url_slurl.xml b/indra/newview/skins/default/xui/en/menu_url_slurl.xml
index 98abc206a5..98abc206a5 100644..100755
--- a/indra/newview/skins/default/xui/en/menu_url_slurl.xml
+++ b/indra/newview/skins/default/xui/en/menu_url_slurl.xml
diff --git a/indra/newview/skins/default/xui/en/menu_url_teleport.xml b/indra/newview/skins/default/xui/en/menu_url_teleport.xml
index 289e32bcf4..289e32bcf4 100644..100755
--- a/indra/newview/skins/default/xui/en/menu_url_teleport.xml
+++ b/indra/newview/skins/default/xui/en/menu_url_teleport.xml
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index c660ef13ae..554c7c95e4 100644..100755
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -16,6 +16,14 @@
parameter="agent" />
</menu_item_call>
<menu_item_call
+ label="Post to Facebook..."
+ name="PostToFacebook">
+ <menu_item_call.on_click
+ function="Floater.Toggle"
+ parameter="social"/>
+ </menu_item_call>
+ <menu_item_separator/>
+ <menu_item_call
label="Appearance..."
name="ChangeOutfit">
<menu_item_call.on_click
@@ -93,7 +101,7 @@
<menu_item_check
label="Fly"
name="Fly"
- shortcut="Home">
+ shortcut="HOME">
<menu_item_check.on_check
function="Agent.getFlying" />
<menu_item_check.on_click
@@ -101,6 +109,15 @@
<menu_item_check.on_enable
function="Agent.enableFlying" />
</menu_item_check>
+ <menu_item_call
+ label="Stop flying"
+ name="Stop flying"
+ shortcut="HOME">
+ <menu_item_call.on_click
+ function="Agent.toggleFlying" />
+ <menu_item_call.on_enable
+ function="Agent.getFlying" />
+ </menu_item_call>
<menu_item_check
label="Always Run"
name="Always Run"
@@ -130,19 +147,24 @@
label="Status"
name="Status"
tear_off="true">
- <menu_item_call
- label="Away"
- name="Set Away">
- <menu_item_call.on_click
+ <menu_item_check
+ name="Away"
+ label="Away">
+ <menu_item_check.on_check
+ function="View.Status.CheckAway" />
+ <menu_item_check.on_click
function="World.SetAway" />
- </menu_item_call>
- <menu_item_call
- label="Busy"
- name="Set Busy">
- <menu_item_call.on_click
- function="World.SetBusy"/>
- </menu_item_call>
- </menu>
+ </menu_item_check>
+ <menu_item_check
+ name="Do Not Disturb"
+ label="Do Not Disturb">
+ <menu_item_check.on_check
+ function="View.Status.CheckDoNotDisturb" />
+ <menu_item_check.on_click
+ function="World.SetDoNotDisturb"/>
+ </menu_item_check>
+
+ </menu>
<menu_item_separator/>
@@ -175,13 +197,12 @@
name="Preferences"
shortcut="control|P">
<menu_item_call.on_click
- function="Floater.Show"
+ function="Floater.Toggle"
parameter="preferences" />
</menu_item_call>
<menu_item_call
label="Toolbar buttons..."
- name="Toolbars"
- shortcut="control|T">
+ name="Toolbars">
<menu_item_call.on_click
function="Floater.Toggle"
parameter="toybox" />
@@ -193,6 +214,15 @@
<menu_item_call.on_click
function="View.ToggleUI" />
</menu_item_call>
+ <menu_item_check
+ label="Show HUD Attachments"
+ name="Show HUD Attachments"
+ shortcut="alt|shift|H">
+ <menu_item_check.on_check
+ function="View.CheckHUDAttachments" />
+ <menu_item_check.on_click
+ function="View.ShowHUDAttachments" />
+ </menu_item_check>
<menu_item_separator/>
@@ -209,17 +239,28 @@
label="Communicate"
name="Communicate"
tear_off="true">
- <menu_item_check
- label="Chat..."
+ <menu_item_check
+ label="Conversations..."
+ name="Conversations"
+ shortcut="control|T">
+ <menu_item_check.on_check
+ function="Floater.IsOpen"
+ parameter="im_container" />
+ <menu_item_check.on_click
+ function="Floater.ToggleOrBringToFront"
+ parameter="im_container" />
+ </menu_item_check>
+ <menu_item_check
+ label="Nearby Chat..."
name="Nearby Chat"
shortcut="control|H"
use_mac_ctrl="true">
<menu_item_check.on_check
function="Floater.Visible"
- parameter="chat_bar" />
+ parameter="nearby_chat" />
<menu_item_check.on_click
- function="Floater.Toggle"
- parameter="chat_bar" />
+ function="Floater.ToggleOrBringToFront"
+ parameter="nearby_chat" />
</menu_item_check>
<menu_item_check
label="Speak"
@@ -235,26 +276,48 @@
parameter="speak" />
</menu_item_check>
<menu_item_check
- label="Voice settings..."
- name="Nearby Voice">
+ name="Conversation Log..."
+ label="Conversation Log...">
<menu_item_check.on_check
function="Floater.Visible"
- parameter="voice_controls" />
+ parameter="conversation" />
+ <menu_item_check.on_enable
+ function="Conversation.IsConversationLoggingAllowed" />
<menu_item_check.on_click
function="Floater.Toggle"
- parameter="voice_controls" />
+ parameter="conversation" />
</menu_item_check>
- <menu_item_check
- label="Voice morphing..."
- name="ShowVoice"
+ <menu_item_separator/>
+ <menu
+ label="Voice morphing"
+ name="VoiceMorphing"
visibility_control="VoiceMorphingEnabled">
- <menu_item_check.on_check
- function="Floater.Visible"
- parameter="voice_effect" />
- <menu_item_check.on_click
- function="Floater.Toggle"
- parameter="voice_effect" />
- </menu_item_check>
+ <menu_item_check
+ label="No voice morphing"
+ name="NoVoiceMorphing">
+ <menu_item_check.on_check
+ function="Communicate.VoiceMorphing.NoVoiceMorphing.Check" />
+ <menu_item_check.on_click
+ function="Communicate.VoiceMorphing.NoVoiceMorphing.Click" />
+ </menu_item_check>
+ <menu_item_separator/>
+ <menu_item_check
+ label="Preview..."
+ name="Preview">
+ <menu_item_check.on_check
+ function="Floater.Visible"
+ parameter="voice_effect" />
+ <menu_item_check.on_click
+ function="Floater.Toggle"
+ parameter="voice_effect" />
+ </menu_item_check>
+ <menu_item_call
+ label="Subscribe..."
+ name="Subscribe">
+ <menu_item_call.on_click
+ function="Communicate.VoiceMorphing.Subscribe" />
+ </menu_item_call>
+ </menu>
<menu_item_check
label="Gestures..."
name="Gestures"
@@ -267,30 +330,56 @@
parameter="gestures" />
</menu_item_check>
<menu_item_separator/>
- <menu_item_call
+ <menu_item_check
label="Friends"
name="My Friends"
shortcut="control|shift|F">
- <menu_item_call.on_click
+ <menu_item_check.on_check
+ function="SideTray.CheckPanelPeopleTab"
+ parameter="friends_panel" />
+ <menu_item_check.on_click
function="SideTray.PanelPeopleTab"
parameter="friends_panel" />
- </menu_item_call>
- <menu_item_call
+ </menu_item_check>
+ <menu_item_check
label="Groups"
name="My Groups"
shortcut="control|shift|G">
- <menu_item_call.on_click
+ <menu_item_check.on_check
+ function="SideTray.CheckPanelPeopleTab"
+ parameter="groups_panel" />
+ <menu_item_check.on_click
function="SideTray.PanelPeopleTab"
parameter="groups_panel" />
- </menu_item_call>
- <menu_item_call
+ </menu_item_check>
+ <menu_item_check
label="Nearby people"
name="Active Speakers"
shortcut="control|shift|A">
- <menu_item_call.on_click
+ <menu_item_check.on_check
+ function="SideTray.CheckPanelPeopleTab"
+ parameter="nearby_panel" />
+ <menu_item_check.on_click
function="SideTray.PanelPeopleTab"
parameter="nearby_panel" />
+ </menu_item_check>
+ <menu_item_call
+ label="Block List"
+ name="Block List">
+ <menu_item_call.on_click
+ function="SideTray.PanelPeopleTab"
+ parameter="blocked_panel" />
</menu_item_call>
+ <menu_item_separator/>
+ <menu_item_check
+ name="Do Not Disturb"
+ label="Do Not Disturb">
+ <menu_item_check.on_check
+ function="View.Status.CheckDoNotDisturb" />
+ <menu_item_check.on_click
+ function="World.SetDoNotDisturb"/>
+ </menu_item_check>
+
</menu>
<menu
create_jump_keys="true"
@@ -802,6 +891,15 @@
function="Tools.EnableSelectNextPart" />
</menu_item_call>
</menu>
+ <menu_item_call
+ label="Linksets..."
+ name="pathfinding_linkset_menu_item">
+ <menu_item_call.on_click
+ function="Floater.ToggleOrBringToFront"
+ parameter="pathfinding_linksets" />
+ <menu_item_call.on_enable
+ function="Tools.EnablePathfinding" />
+ </menu_item_call>
<menu_item_separator/>
<menu_item_call
@@ -824,7 +922,7 @@
<menu_item_call.on_enable
function="Tools.SomethingSelectedNoHUD" />
</menu_item_call>
-
+
<menu_item_separator/>
<menu
@@ -861,14 +959,6 @@
function="Tools.EnableTakeCopy" />
</menu_item_call>
<menu_item_call
- label="Save Back to My Inventory"
- name="Save Object Back to My Inventory">
- <menu_item_call.on_click
- function="Tools.SaveToInventory" />
- <menu_item_call.on_enable
- function="Tools.EnableSaveToInventory" />
- </menu_item_call>
- <menu_item_call
label="Save Back to Object Contents"
name="Save Object Back to Object Contents">
<menu_item_call.on_click
@@ -937,7 +1027,50 @@
</menu_item_call>
</menu>
- <menu_item_separator/>
+ <menu
+ create_jump_keys="true"
+ label="Pathfinding"
+ name="Pathfinding"
+ tear_off="true">
+ <menu_item_call
+ label="Linksets..."
+ name="pathfinding_linksets_menu_item">
+ <menu_item_call.on_click
+ function="Floater.ToggleOrBringToFront"
+ parameter="pathfinding_linksets" />
+ <menu_item_call.on_enable
+ function="Tools.EnablePathfinding" />
+ </menu_item_call>
+ <menu_item_call
+ label="Characters..."
+ name="pathfinding_characters_menu_item">
+ <menu_item_call.on_click
+ function="Floater.ToggleOrBringToFront"
+ parameter="pathfinding_characters" />
+ <menu_item_call.on_enable
+ function="Tools.EnablePathfinding" />
+ </menu_item_call>
+ <menu_item_call
+ label="View / test..."
+ name="pathfinding_console_menu_item">
+ <menu_item_call.on_click
+ function="Floater.ToggleOrBringToFront"
+ parameter="pathfinding_console" />
+ <menu_item_call.on_enable
+ function="Tools.EnablePathfindingView" />
+ </menu_item_call>
+ <menu_item_call
+ label="Rebake region"
+ name="pathfinding_rebake_navmesh_item">
+ <menu_item_call.on_click
+ function="Tools.DoPathfindingRebakeRegion"/>
+ <menu_item_call.on_enable
+ function="Tools.EnablePathfindingRebakeRegion" />
+ </menu_item_call>
+ </menu>
+
+
+ <menu_item_separator/>
<menu
create_jump_keys="true"
@@ -1165,19 +1298,19 @@
tear_off="true">
<menu_item_call
label="How to..."
- name="How To">
+ name="How To"
+ shortcut="F1">
<menu_item_call.on_click
function="Help.ToggleHowTo"
parameter="" />
</menu_item_call>
<menu_item_call
- label="[SECOND_LIFE] Help"
- name="Second Life Help"
- shortcut="F1">
- <menu_item_call.on_click
- function="ShowHelp"
- parameter="f1_help" />
- </menu_item_call>
+ label="Quickstart"
+ name="Quickstart">
+ <menu_item_call.on_click
+ function="Advanced.ShowURL"
+ parameter="http://community.secondlife.com/t5/English-Knowledge-Base/Second-Life-Quickstart/ta-p/1087919"/>
+ </menu_item_call>
<!-- <menu_item_call
label="Tutorial"
name="Tutorial">
@@ -1185,7 +1318,50 @@
function="Floater.Show"
parameter="hud" />
</menu_item_call>-->
-
+ <menu_item_separator/>
+ <menu_item_call
+ label="Knowledge Base"
+ name="Knowledge Base">
+ <menu_item_call.on_click
+ function="Advanced.ShowURL"
+ parameter="http://community.secondlife.com/t5/English-Knowledge-Base/Second-Life-User-s-Guide/ta-p/1244857"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Wiki"
+ name="Wiki">
+ <menu_item_call.on_click
+ function="Advanced.ShowURL"
+ parameter="http://wiki.secondlife.com"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Community Forums"
+ name="Community Forums">
+ <menu_item_call.on_click
+ function="Advanced.ShowURL"
+ parameter="http://community.secondlife.com/t5/Forums/ct-p/Forums"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Support portal"
+ name="Support portal">
+ <menu_item_call.on_click
+ function="Advanced.ShowURL"
+ parameter="https://support.secondlife.com/"/>
+ </menu_item_call>
+ <menu_item_separator/>
+ <menu_item_call
+ label="[SECOND_LIFE] News"
+ name="Second Life News">
+ <menu_item_call.on_click
+ function="Advanced.ShowURL"
+ parameter="http://community.secondlife.com/t5/Featured-News/bg-p/blog_feature_news"/>
+ </menu_item_call>
+ <menu_item_call
+ label="[SECOND_LIFE] Blogs"
+ name="Second Life Blogs">
+ <menu_item_call.on_click
+ function="Advanced.ShowURL"
+ parameter="http://community.secondlife.com/t5/Blogs/ct-p/Blogs"/>
+ </menu_item_call>
<menu_item_separator/>
<menu_item_call
@@ -1367,15 +1543,6 @@
function="View.HighlightTransparent" />
</menu_item_check>
<menu_item_check
- label="Show HUD Attachments"
- name="Show HUD Attachments"
- shortcut="alt|shift|H">
- <menu_item_check.on_check
- function="View.CheckHUDAttachments" />
- <menu_item_check.on_click
- function="View.ShowHUDAttachments" />
- </menu_item_check>
- <menu_item_check
label="Show Mouselook Crosshairs"
name="ShowCrosshairs">
<menu_item_check.on_check
@@ -1869,7 +2036,7 @@
<menu_item_check.on_click
function="Advanced.ToggleConsole"
parameter="texture" />
- </menu_item_check>
+ </menu_item_check>
<menu_item_check
label="Debug Console"
name="Debug Console"
@@ -1891,28 +2058,6 @@
parameter="notifications_console" />
</menu_item_call>
<menu_item_check
- label="Texture Size Console"
- name="Texture Size"
- shortcut="control|shift|6">
- <menu_item_check.on_check
- function="Advanced.CheckConsole"
- parameter="texture size" />
- <menu_item_check.on_click
- function="Advanced.ToggleConsole"
- parameter="texture size" />
- </menu_item_check>
- <menu_item_check
- label="Texture Category Console"
- name="Texture Category"
- shortcut="control|shift|7">
- <menu_item_check.on_check
- function="Advanced.CheckConsole"
- parameter="texture category" />
- <menu_item_check.on_click
- function="Advanced.ToggleConsole"
- parameter="texture category" />
- </menu_item_check>
- <menu_item_check
label="Fast Timers"
name="Fast Timers"
shortcut="control|shift|9"
@@ -1946,7 +2091,20 @@
function="Advanced.ToggleConsole"
parameter="scene view" />
</menu_item_check>
-
+ <menu_item_call
+ enabled="false"
+ visible="false"
+ label="Texture Fetch Debug Console"
+ name="Texture Fetch Debug Console">
+ <menu_item_call.on_click
+ function="Floater.Show"
+ parameter="tex_fetch_debugger" />
+ <on_enable
+ function="Develop.SetTexFetchDebugger" />
+ <on_visible
+ function="Develop.SetTexFetchDebugger" />
+ </menu_item_call>
+
<menu_item_separator/>
<menu_item_call
@@ -2050,6 +2208,16 @@
function="ToggleControl"
parameter="DebugShowRenderInfo" />
</menu_item_check>
+ <menu_item_check
+ label="Show Avatar Render Info"
+ name="Show Avatar Render Info">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="DebugShowAvatarRenderInfo" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="DebugShowAvatarRenderInfo" />
+ </menu_item_check>
<menu_item_check
label="Show Texture Info"
name="Show Texture Info">
@@ -2216,6 +2384,12 @@
<menu_item_check.on_click
function="Advanced.ToggleFrameTest" />
</menu_item_check>
+ <menu_item_call
+ label="Frame Profile"
+ name="Frame Profile">
+ <menu_item_call.on_click
+ function="Advanced.ClickRenderProfile" />
+ </menu_item_call>
</menu>
<menu
create_jump_keys="true"
@@ -2432,6 +2606,52 @@
function="Advanced.ToggleInfoDisplay"
parameter="sculpt" />
</menu_item_check>
+ <menu
+ create_jump_keys="true"
+ label="Texture Density"
+ name="Texture Density"
+ tear_off="true">
+ <menu_item_check
+ label="None"
+ name="None">
+ <menu_item_check.on_check
+ function="Advanced.CheckDisplayTextureDensity"
+ parameter="none" />
+ <menu_item_check.on_click
+ function="Advanced.SetDisplayTextureDensity"
+ parameter="none" />
+ </menu_item_check>
+ <menu_item_check
+ label="Current"
+ name="Current">
+ <menu_item_check.on_check
+ function="Advanced.CheckDisplayTextureDensity"
+ parameter="current" />
+ <menu_item_check.on_click
+ function="Advanced.SetDisplayTextureDensity"
+ parameter="current" />
+ </menu_item_check>
+ <menu_item_check
+ label="Desired"
+ name="Desired">
+ <menu_item_check.on_check
+ function="Advanced.CheckDisplayTextureDensity"
+ parameter="desired" />
+ <menu_item_check.on_click
+ function="Advanced.SetDisplayTextureDensity"
+ parameter="desired" />
+ </menu_item_check>
+ <menu_item_check
+ label="Full"
+ name="Full">
+ <menu_item_check.on_check
+ function="Advanced.CheckDisplayTextureDensity"
+ parameter="full" />
+ <menu_item_check.on_click
+ function="Advanced.SetDisplayTextureDensity"
+ parameter="full" />
+ </menu_item_check>
+ </menu>
</menu>
<menu
create_jump_keys="true"
@@ -2465,6 +2685,13 @@
<menu_item_call.on_click
function="Advanced.SelectedTextureInfo" />
</menu_item_call>
+ <menu_item_call
+ label="Selected Material Info"
+ name="Selected Material Info"
+ shortcut="control|alt|shift|M">
+ <menu_item_call.on_click
+ function="Advanced.SelectedMaterialInfo" />
+ </menu_item_call>
<menu_item_check
label="Wireframe"
name="Wireframe"
@@ -2491,8 +2718,8 @@
<menu_item_separator />
<menu_item_check
- label="Lighting and Shadows"
- name="Lighting and Shadows">
+ label="Advanced Lighting Model"
+ name="Advanced Lighting Model">
<menu_item_check.on_check
function="CheckControl"
parameter="RenderDeferred" />
@@ -2599,26 +2826,6 @@
parameter="TextureLoadFullRes" />
</menu_item_check>
<menu_item_check
- label="Audit Textures"
- name="Audit Textures">
- <menu_item_check.on_check
- function="CheckControl"
- parameter="AuditTexture" />
- <menu_item_check.on_click
- function="ToggleControl"
- parameter="AuditTexture" />
- </menu_item_check>
- <menu_item_check
- label="Texture Atlas (experimental)"
- name="Texture Atlas">
- <menu_item_check.on_check
- function="CheckControl"
- parameter="EnableTextureAtlas" />
- <menu_item_check.on_click
- function="ToggleControl"
- parameter="EnableTextureAtlas" />
- </menu_item_check>
- <menu_item_check
label="Render Attached Lights"
name="Render Attached Lights">
<menu_item_check.on_check
@@ -2733,6 +2940,34 @@
label="Recorder"
name="Recorder"
tear_off="true">
+ <menu_item_call visible="false"
+ label="Start event recording"
+ name="Start event recording">
+ <menu_item_call.on_visible
+ function="displayViewerEventRecorderMenuItems" />
+ <menu_item_call.on_click
+ function="Advanced.EventRecorder"
+ parameter="start recording" />
+ </menu_item_call>
+ <menu_item_call visible="false"
+ label="Stop event recording"
+ name="Stop event recording">
+ <menu_item_call.on_visible
+ function="displayViewerEventRecorderMenuItems" />
+ <menu_item_call.on_click
+ function="Advanced.EventRecorder"
+ parameter="stop recording" />
+ </menu_item_call>
+ <menu_item_call visible="false"
+ label="Playback event recording"
+ name="Playback event recording">
+ <menu_item_call.on_visible
+ function="displayViewerEventRecorderMenuItems" />
+ <menu_item_call.on_click
+ function="Advanced.EventRecorder"
+ parameter="start playback" />
+ </menu_item_call>
+
<menu_item_call
label="Start Playback"
name="Start Playback">
@@ -2835,6 +3070,13 @@
parameter="http://google.com"/>
</menu_item_call>
<menu_item_call
+ label="FB Connect Test"
+ name="FB Connect Test">
+ <menu_item_call.on_click
+ function="Advanced.WebContentTest"
+ parameter="https://cryptic-ridge-1632.herokuapp.com/"/>
+ </menu_item_call>
+ <menu_item_call
label="Dump SelectMgr"
name="Dump SelectMgr">
<menu_item_call.on_click
@@ -2872,13 +3114,6 @@
<menu_item_call.on_click
function="Advanced.PrintAgentInfo" />
</menu_item_call>
- <menu_item_call
- label="Memory Stats"
- name="Memory Stats"
- shortcut="control|alt|shift|M">
- <menu_item_call.on_click
- function="Advanced.PrintTextureMemoryStats" />
- </menu_item_call>
<menu_item_check
label="Region Debug Console"
name="Region Debug Console"
@@ -3091,12 +3326,6 @@
<menu_item_call.on_click
function="Advanced.TestFemale" />
</menu_item_call>
- <menu_item_call
- label="Toggle PG"
- name="Toggle PG">
- <menu_item_call.on_click
- function="Advanced.TogglePG" />
- </menu_item_call>
<menu_item_check
label="Allow Select Avatar"
name="Allow Select Avatar">
@@ -3108,6 +3337,40 @@
parameter="AllowSelectAvatar" />
</menu_item_check>
</menu>
+ <menu
+ create_jump_keys="true"
+ label="Animation Speed"
+ name="Animation Speed"
+ tear_off="true">
+ <menu_item_call
+ label="All Animations 10% Faster"
+ name="All Animations 10 Faster">
+ <menu_item_call.on_click
+ function="Advanced.AnimTenFaster" />
+ </menu_item_call>
+ <menu_item_call
+ label="All Animations 10% Slower"
+ name="All Animations 10 Slower">
+ <menu_item_call.on_click
+ function="Advanced.AnimTenSlower" />
+ </menu_item_call>
+ <menu_item_call
+ label="Reset All Animation Speed"
+ name="Reset All Animation Speed">
+ <menu_item_call.on_click
+ function="Advanced.AnimResetAll" />
+ </menu_item_call>
+ <menu_item_check
+ label="Slow Motion Animations"
+ name="Slow Motion Animations">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="SlowMotionAnimation" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="SlowMotionAnimation" />
+ </menu_item_check>
+ </menu>
<menu_item_call
label="Force Params to Default"
name="Force Params to Default">
@@ -3125,16 +3388,6 @@
parameter="" />
</menu_item_check>
<menu_item_check
- label="Slow Motion Animations"
- name="Slow Motion Animations">
- <menu_item_check.on_check
- function="CheckControl"
- parameter="SlowMotionAnimation" />
- <menu_item_check.on_click
- function="ToggleControl"
- parameter="SlowMotionAnimation" />
- </menu_item_check>
- <menu_item_check
label="Show Look At"
name="Show Look At">
<menu_item_check.on_check
diff --git a/indra/newview/skins/default/xui/en/menu_wearable_list_item.xml b/indra/newview/skins/default/xui/en/menu_wearable_list_item.xml
index aa56b4ba63..aa56b4ba63 100644..100755
--- a/indra/newview/skins/default/xui/en/menu_wearable_list_item.xml
+++ b/indra/newview/skins/default/xui/en/menu_wearable_list_item.xml
diff --git a/indra/newview/skins/default/xui/en/menu_wearing_gear.xml b/indra/newview/skins/default/xui/en/menu_wearing_gear.xml
index 0e858ccf10..0e858ccf10 100644..100755
--- a/indra/newview/skins/default/xui/en/menu_wearing_gear.xml
+++ b/indra/newview/skins/default/xui/en/menu_wearing_gear.xml
diff --git a/indra/newview/skins/default/xui/en/menu_wearing_tab.xml b/indra/newview/skins/default/xui/en/menu_wearing_tab.xml
index 2d54e69601..2d54e69601 100644..100755
--- a/indra/newview/skins/default/xui/en/menu_wearing_tab.xml
+++ b/indra/newview/skins/default/xui/en/menu_wearing_tab.xml
diff --git a/indra/newview/skins/default/xui/en/mime_types.xml b/indra/newview/skins/default/xui/en/mime_types.xml
index a585069faa..a585069faa 100644..100755
--- a/indra/newview/skins/default/xui/en/mime_types.xml
+++ b/indra/newview/skins/default/xui/en/mime_types.xml
diff --git a/indra/newview/skins/default/xui/en/mime_types_linux.xml b/indra/newview/skins/default/xui/en/mime_types_linux.xml
index e95b371d00..e95b371d00 100644..100755
--- a/indra/newview/skins/default/xui/en/mime_types_linux.xml
+++ b/indra/newview/skins/default/xui/en/mime_types_linux.xml
diff --git a/indra/newview/skins/default/xui/en/mime_types_mac.xml b/indra/newview/skins/default/xui/en/mime_types_mac.xml
index 7931e55c0a..7931e55c0a 100644..100755
--- a/indra/newview/skins/default/xui/en/mime_types_mac.xml
+++ b/indra/newview/skins/default/xui/en/mime_types_mac.xml
diff --git a/indra/newview/skins/default/xui/en/notification_visibility.xml b/indra/newview/skins/default/xui/en/notification_visibility.xml
index db292100d7..db292100d7 100644..100755
--- a/indra/newview/skins/default/xui/en/notification_visibility.xml
+++ b/indra/newview/skins/default/xui/en/notification_visibility.xml
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index a46cce996b..1ab665edd4 100644..100755
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -77,6 +77,21 @@
</form>
</template>
+ <template name="okhelpignore">
+ <form>
+ <button
+ default="true"
+ index="0"
+ name="OK_okhelpignore"
+ text="$yestext"/>
+ <button
+ index="1"
+ name="Help_okhelpignore"
+ text="$helptext"/>
+ <ignore text="$ignoretext"/>
+ </form>
+ </template>
+
<template name="yesnocancelbuttons">
<form>
<button
@@ -337,7 +352,7 @@ Save all changes to clothing/body parts?
icon="alertmodal.tga"
name="FriendsAndGroupsOnly"
type="alertmodal">
- Non-friends won't know that you've choosen to ignore their calls and instant messages.
+ Non-friends won't know that you've chosen to ignore their calls and instant messages.
<usetemplate
name="okbutton"
yestext="OK"/>
@@ -491,6 +506,33 @@ Add this Ability to &apos;[ROLE_NAME]&apos;?
notext="No"
yestext="Yes"/>
</notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="EjectGroupMemberWarning"
+ type="alertmodal">
+ You are about to eject [AVATAR_NAME] from the group.
+ <tag>group</tag>
+ <tag>confirm</tag>
+ <usetemplate
+ ignoretext="Confirm ejecting a participant from group"
+ name="okcancelignore"
+ notext="Cancel"
+ yestext="Eject"/>
+ </notification>
+ <notification
+ icon="alertmodal.tga"
+ name="EjectGroupMembersWarning"
+ type="alertmodal">
+ You are about to eject [COUNT] members from the group.
+ <tag>group</tag>
+ <tag>confirm</tag>
+ <usetemplate
+ ignoretext="Confirm ejecting multiple members from group"
+ name="okcancelignore"
+ notext="Cancel"
+ yestext="Eject"/>
+ </notification>
<notification
icon="alertmodal.tga"
@@ -881,8 +923,7 @@ You need an account to enter [SECOND_LIFE]. Would you like to create one now?
option="0"
name="url"
target = "_external">
-
- http://join.secondlife.com/
+ [create_account_url]
</url>
<usetemplate
name="okcancelbuttons"
@@ -898,7 +939,22 @@ You need an account to enter [SECOND_LIFE]. Would you like to create one now?
You need to enter either the Username or both the First and Last name of your avatar into the Username field, then login again.
</notification>
-
+ <notification
+ icon="alertmodal.tga"
+ name="InvalidGrid"
+ type="alertmodal">
+ <tag>fail</tag>
+'[GRID]' is not a valid grid identifier.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="InvalidLocationSLURL"
+ type="alertmodal">
+ <tag>fail</tag>
+Your start location did not specify a valid grid.
+ </notification>
+
<notification
icon="alertmodal.tga"
name="DeleteClassified"
@@ -1190,7 +1246,7 @@ There was a problem saving a compiled script due to the following reason: [REASO
icon="alertmodal.tga"
name="StartRegionEmpty"
type="alertmodal">
-Oops, Your Start Region is not defined.
+Your Start Region is not defined.
Please type the Region name in Start Location box or choose My Last Location or My Home as your Start Location.
<tag>fail</tag>
<usetemplate
@@ -1245,6 +1301,64 @@ Visit [_URL] for more information?
<notification
icon="alertmodal.tga"
+ name="IntelOldDriver"
+ type="alertmodal">
+ There is likely a newer driver for your graphics chip. Updating graphics drivers can substantially improve performance.
+
+ Visit [_URL] to check for driver updates?
+ <tag>confirm</tag>
+ <url option="0" name="url">
+ http://www.intel.com/p/en_US/support/detect/graphics
+ </url>
+ <usetemplate
+ ignoretext="My graphics driver is out of date"
+ name="okcancelignore"
+ notext="No"
+ yestext="Yes"/>
+ <tag>fail</tag>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="AMDOldDriver"
+ type="alertmodal">
+ There is likely a newer driver for your graphics chip. Updating graphics drivers can substantially improve performance.
+
+ Visit [_URL] to check for driver updates?
+ <tag>confirm</tag>
+ <url option="0" name="url">
+ http://support.amd.com/us/Pages/AMDSupportHub.aspx
+ </url>
+ <usetemplate
+ ignoretext="My graphics driver is out of date"
+ name="okcancelignore"
+ notext="No"
+ yestext="Yes"/>
+ <tag>fail</tag>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="NVIDIAOldDriver"
+ type="alertmodal">
+ There is likely a newer driver for your graphics chip. Updating graphics drivers can substantially improve performance.
+
+ Visit [_URL] to check for driver updates?
+ <tag>confirm</tag>
+ <url option="0" name="url">
+ http://www.nvidia.com/Download/index.aspx?lang=en-us
+ </url>
+ <usetemplate
+ ignoretext="My graphics driver is out of date"
+ name="okcancelignore"
+ notext="No"
+ yestext="Yes"/>
+ <tag>fail</tag>
+ </notification>
+
+
+ <notification
+ icon="alertmodal.tga"
name="UnknownGPU"
type="alertmodal">
Your system contains a graphics card that [APP_NAME] doesn't recognize.
@@ -1482,6 +1596,14 @@ Please make sure none are locked, and that you own all of them.
<notification
icon="alertmodal.tga"
+ name="CannotLinkPermanent"
+ type="alertmodal">
+ Objects cannot be linked across region boundaries.
+ <tag>fail</tag>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
name="CannotLinkDifferentOwners"
type="alertmodal">
Unable to link because not all of the objects have the same owner.
@@ -2340,6 +2462,93 @@ Would you be my friend?
</notification>
<notification
+ icon="alertmodal.tga"
+ label="Add Auto-Replace List"
+ name="AddAutoReplaceList"
+ type="alertmodal">
+ <tag>addlist</tag>
+ Name for the new list:
+ <tag>confirm</tag>
+ <form name="form">
+ <input name="listname" type="text"/>
+ <button
+ default="true"
+ index="0"
+ name="SetName"
+ text="OK"/>
+ </form>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ label="Rename Auto-Replace List"
+ name="RenameAutoReplaceList"
+ type="alertmodal">
+ The name '[DUPNAME]' is in use
+ Enter a new unique name:
+ <tag>confirm</tag>
+ <form name="form">
+ <input name="listname" type="text"/>
+ <button
+ default="false"
+ index="0"
+ name="ReplaceList"
+ text="Replace Current List"/>
+ <button
+ default="true"
+ index="1"
+ name="SetName"
+ text="Use New Name"/>
+ </form>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="InvalidAutoReplaceEntry"
+ type="alertmodal">
+ The keyword must be a single word, and the replacement may not be empty.
+ <tag>fail</tag>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="InvalidAutoReplaceList"
+ type="alertmodal">
+ That replacement list is not valid.
+ <tag>fail</tag>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="SpellingDictImportRequired"
+ type="alertmodal">
+ You must specify a file, a name, and a language.
+ <tag>fail</tag>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="SpellingDictIsSecondary"
+ type="alertmodal">
+The dictionary [DIC_NAME] does not appear to have an "aff" file; this means that it is a "secondary" dictionary.
+It can be used as an additional dictionary, but not as your Main dictionary.
+
+See https://wiki.secondlife.com/wiki/Adding_Spelling_Dictionaries
+ <tag>confirm</tag>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="SpellingDictImportFailed"
+ type="alertmodal">
+ Unable to copy
+ [FROM_NAME]
+ to
+ [TO_NAME]
+ <tag>fail</tag>
+ </notification>
+
+ <notification
icon="alertmodal.tga"
label="Save Outfit"
name="SaveOutfitAs"
@@ -2500,7 +2709,7 @@ Please enter a higher price.
icon="alertmodal.tga"
name="ConfirmItemDeleteHasLinks"
type="alertmodal">
-At least one of the items you has link items that point to it. If you delete this item, its links will permanently stop working. It is strongly advised to delete the links first.
+At least one of the items has links that point to it. If you delete this item, its links will permanently stop working. It is strongly advised to delete the links first.
Are you sure you want to delete these items?
<tag>confirm</tag>
@@ -2542,7 +2751,7 @@ Are you sure you want to delete these items?
icon="alertmodal.tga"
name="ConfirmObjectDeleteNoOwn"
type="alertmodal">
-You do not own least one of the items you have selected.
+You do not own at least one of the items you have selected.
Are you sure you want to delete these items?
<tag>confirm</tag>
@@ -2572,7 +2781,7 @@ Are you sure you want to delete these items?
name="ConfirmObjectDeleteLockNoOwn"
type="alertmodal">
At least one object is locked.
-You do not own least one object.
+You do not own at least one object.
Are you sure you want to delete these items?
<tag>confirm</tag>
@@ -2587,7 +2796,7 @@ Are you sure you want to delete these items?
name="ConfirmObjectDeleteNoCopyNoOwn"
type="alertmodal">
At least one object is not copyable.
-You do not own least one object.
+You do not own at least one object.
Are you sure you want to delete these items?
<tag>confirm</tag>
@@ -2603,13 +2812,13 @@ Are you sure you want to delete these items?
type="alertmodal">
At least one object is locked.
At least one object is not copyable.
-You do not own least one object.
+You do not own at least one object.
Are you sure you want to delete these items?
<tag>confirm</tag>
<usetemplate
name="okcancelbuttons"
- notext="cancel"
+ notext="Cancel"
yestext="OK"/>
</notification>
@@ -2750,7 +2959,7 @@ You have been moved into a nearby region.
name="AvatarMovedLast"
type="alertmodal">
<tag>fail</tag>
-Your last location is not currently available.
+Your requested location is not currently available.
You have been moved into a nearby region.
</notification>
@@ -2785,12 +2994,11 @@ You can use [SECOND_LIFE] normally and other people will see you correctly.
[APP_NAME] installation is complete.
If this is your first time using [SECOND_LIFE], you will need to create an account before you can log in.
-Return to [http://join.secondlife.com secondlife.com] to create a new account?
<tag>confirm</tag>
<usetemplate
name="okcancelbuttons"
notext="Continue"
- yestext="New Account..."/>
+ yestext="Create Account..."/>
</notification>
<notification
@@ -2904,6 +3112,7 @@ Would you like to trust this authority?
icon="alertmodal.tga"
name="GrantedModifyRights"
persist="true"
+ log_to_im="true"
type="notify">
[NAME] has given you permission to edit their objects.
</notification>
@@ -2912,6 +3121,7 @@ Would you like to trust this authority?
icon="alertmodal.tga"
name="RevokedModifyRights"
persist="true"
+ log_to_im="true"
type="notify">
Your privilege to modify [NAME]&apos;s objects has been revoked
</notification>
@@ -3271,7 +3481,7 @@ or you can install it now.
name="DownloadBackgroundTip"
type="notify">
We have downloaded an update to your [APP_NAME] installation.
-Version [VERSION] [[RELEASE_NOTES_FULL_URL] Information about this update]
+Version [VERSION] [[INFO_URL] Information about this update]
<tag>confirm</tag>
<usetemplate
name="okcancelbuttons"
@@ -3283,8 +3493,8 @@ Version [VERSION] [[RELEASE_NOTES_FULL_URL] Information about this update]
icon="alertmodal.tga"
name="DownloadBackgroundDialog"
type="alertmodal">
-We have downloaded an update to your [APP_NAME] installation.
-Version [VERSION] [[RELEASE_NOTES_FULL_URL] Information about this update]
+ We have downloaded an update to your [APP_NAME] installation.
+ Version [VERSION] [[INFO_URL] Information about this update]
<tag>confirm</tag>
<usetemplate
name="okcancelbuttons"
@@ -3297,7 +3507,7 @@ Version [VERSION] [[RELEASE_NOTES_FULL_URL] Information about this update]
name="RequiredUpdateDownloadedVerboseDialog"
type="alertmodal">
We have downloaded a required software update.
-Version [VERSION]
+Version [VERSION] [[INFO_URL] Information about this update]
We must restart [APP_NAME] to install the update.
<tag>confirm</tag>
@@ -3311,6 +3521,66 @@ We must restart [APP_NAME] to install the update.
name="RequiredUpdateDownloadedDialog"
type="alertmodal">
We must restart [APP_NAME] to install the update.
+[[INFO_URL] Information about this update]
+ <tag>confirm</tag>
+ <usetemplate
+ name="okbutton"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="OtherChannelDownloadBackgroundTip"
+ type="notify">
+We have downloaded an update to your [APP_NAME] installation.
+Version [VERSION]
+This experimental viewer has been replaced by a [NEW_CHANNEL] viewer;
+see [[INFO_URL] for details about this update]
+ <tag>confirm</tag>
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Later..."
+ yestext="Install now and restart [APP_NAME]"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="OtherChannelDownloadBackgroundDialog"
+ type="alertmodal">
+We have downloaded an update to your [APP_NAME] installation.
+Version [VERSION]
+This experimental viewer has been replaced by a [NEW_CHANNEL] viewer;
+see [[INFO_URL] Information about this update]
+ <tag>confirm</tag>
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Later..."
+ yestext="Install now and restart [APP_NAME]"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="OtherChannelRequiredUpdateDownloadedVerboseDialog"
+ type="alertmodal">
+We have downloaded a required software update.
+Version [VERSION]
+This experimental viewer has been replaced by a [NEW_CHANNEL] viewer;
+see [[INFO_URL] Information about this update]
+
+We must restart [APP_NAME] to install the update.
+ <tag>confirm</tag>
+ <usetemplate
+ name="okbutton"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="OtherChannelRequiredUpdateDownloadedDialog"
+ type="alertmodal">
+We must restart [APP_NAME] to install the update.
+This experimental viewer has been replaced by a [NEW_CHANNEL] viewer;
+see [[INFO_URL] Information about this update]
<tag>confirm</tag>
<usetemplate
name="okbutton"
@@ -3466,6 +3736,17 @@ Leave Group?
</notification>
<notification
+ icon="alertmodal.tga"
+ name="OwnerCannotLeaveGroup"
+ type="alertmodal">
+ Unable to leave group. You cannot leave the group because you are the last owner of the group. Please assign another member to the owner role first.
+ <tag>group</tag>
+ <usetemplate
+ name="okbutton"
+ yestext="OK"/>
+ </notification>
+
+ <notification
icon="alert.tga"
name="ConfirmKick"
type="alert">
@@ -3545,12 +3826,15 @@ Cannot offer friendship at this time. Please try again in a moment.
<notification
icon="alert.tga"
- name="BusyModeSet"
+ name="DoNotDisturbModeSet"
type="alert">
-Busy mode is set.
-Chat and instant messages will be hidden. Instant messages will get your Busy mode response. All teleportation offers will be declined. All inventory offers will go to your Trash.
+Do Not Disturb is on. You will not be notified of incoming communications.
+
+- Other residents will receive your Do Not Disturb response (set in Preferences &gt; General).
+- Teleportation offers will be declined.
+- Voice calls will be rejected.
<usetemplate
- ignoretext="I change my status to Busy mode"
+ ignoretext="I change my status to Do Not Disturb mode"
name="okignore"
yestext="OK"/>
</notification>
@@ -3787,6 +4071,27 @@ Join me in [REGION]
<notification
icon="alertmodal.tga"
+ name="TeleportRequestPrompt"
+ type="alertmodal">
+Request a teleport to [NAME] with the following message
+ <tag>confirm</tag>
+ <form name="form">
+ <input name="message" type="text">
+
+ </input>
+ <button
+ default="true"
+ index="0"
+ name="OK"
+ text="OK"/>
+ <button
+ index="1"
+ name="Cancel"
+ text="Cancel"/>
+ </form>
+ </notification>
+ <notification
+ icon="alertmodal.tga"
name="TooManyTeleportOffers"
type="alertmodal">
You attempted to make [OFFERS] teleport offers
@@ -4070,9 +4375,7 @@ Are you sure you want to change the Estate Covenant?
name="RegionEntryAccessBlocked"
type="alertmodal">
<tag>fail</tag>
-You are not allowed in that Region due to your maturity Rating. This may be a result of a lack of information validating your age.
-
-Please verify you have the latest Viewer installed, and go to the Knowledge Base for details on accessing areas with this maturity rating.
+ The region you're trying to visit contains content exceeding your current preferences. You can change your preferences using Me &gt; Preferences &gt; General.
<usetemplate
name="okbutton"
yestext="OK"/>
@@ -4080,13 +4383,11 @@ Please verify you have the latest Viewer installed, and go to the Knowledge Base
<notification
icon="alertmodal.tga"
- name="RegionEntryAccessBlocked_KB"
+ name="RegionEntryAccessBlocked_AdultsOnlyContent"
type="alertmodal">
<tag>fail</tag>
<tag>confirm</tag>
-You are not allowed in that region due to your maturity Rating.
-
-Go to the Knowledge Base for more information about maturity Ratings?
+ The region you're trying to visit contains [REGIONMATURITY] content, which is accessible to adults only.
<url option="0" name="url">
http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview
</url>
@@ -4094,55 +4395,172 @@ Go to the Knowledge Base for more information about maturity Ratings?
name="okcancelignore"
yestext="Go to Knowledge Base"
notext="Close"
- ignoretext="I can&apos;t enter this Region, due to restrictions of the maturity Rating"/>
+ ignoretext="Region crossing: The region you&apos;re trying to visit contains content which is accessible to adults only."/>
</notification>
<notification
icon="notifytip.tga"
name="RegionEntryAccessBlocked_Notify"
+ log_to_im="false"
+ log_to_chat="true"
type="notifytip">
<tag>fail</tag>
-You are not allowed in that region due to your maturity Rating.
+The region you're trying to visit contains [REGIONMATURITY] content, but your current preferences are set to exclude [REGIONMATURITY] content.
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
+ name="RegionEntryAccessBlocked_NotifyAdultsOnly"
+ log_to_im="false"
+ log_to_chat="true"
+ type="notifytip">
+ <tag>fail</tag>
+ The region you're trying to visit contains [REGIONMATURITY] content, which is accessible to adults only.
</notification>
<notification
icon="alertmodal.tga"
name="RegionEntryAccessBlocked_Change"
type="alertmodal">
- <tag>fail</tag>
+ <tag>fail</tag>
<tag>confirm</tag>
-You are not allowed in that Region due to your maturity Rating preference.
-
-To enter the desired region, please change your maturity Rating preference. This will allow you to search for and access [REGIONMATURITY] content. To undo any changes, go to Me &gt; Preferences &gt; General.
- <form name="form">
+The region you're trying to visit contains [REGIONMATURITY] content, but your current preferences are set to exclude [REGIONMATURITY] content. We can change your preferences, or you can cancel. After your preferences are changed, you may attempt to enter the region again.
+ <form name="form">
<button
index="0"
name="OK"
- text="Change Preference"/>
- <button
+ text="Change preferences"/>
+ <button
default="true"
index="1"
name="Cancel"
- text="Close"/>
- <ignore name="ignore" text="My chosen Rating preference prevents me from entering a Region"/>
+ text="Cancel"/>
+ <ignore name="ignore" text="Region crossing: The region you&apos;re trying to visit contains content excluded by your preferences."/>
</form>
</notification>
<notification
+ icon="alertmodal.tga"
+ name="RegionEntryAccessBlocked_PreferencesOutOfSync"
+ type="alertmodal">
+ <tag>fail</tag>
+ We are having technical difficulties with your teleport because your preferences are out of sync with the server.
+ <usetemplate
+ name="okbutton"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="TeleportEntryAccessBlocked"
+ type="alertmodal">
+ <tag>fail</tag>
+ The region you're trying to visit contains content exceeding your current preferences. You can change your preferences using Me &gt; Preferences &gt; General.
+ <usetemplate
+ name="okbutton"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="TeleportEntryAccessBlocked_AdultsOnlyContent"
+ type="alertmodal">
+ <unique>
+ <context>REGIONMATURITY</context>
+ </unique>
+ <tag>fail</tag>
+ <tag>confirm</tag>
+ The region you're trying to visit contains [REGIONMATURITY] content, which is accessible to adults only.
+ <url option="0" name="url">
+ http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview
+ </url>
+ <usetemplate
+ name="okcancelignore"
+ yestext="Go to Knowledge Base"
+ notext="Close"
+ ignoretext="Teleport: The region you&apos;re trying to visit contains content which is accessible to adults only."/>
+ </notification>
+
+ <notification
icon="notifytip.tga"
- name="PreferredMaturityChanged"
+ name="TeleportEntryAccessBlocked_Notify"
+ log_to_im="false"
+ log_to_chat="true"
type="notifytip">
-Your maturity Rating preference is now [RATING].
+ <unique>
+ <context>REGIONMATURITY</context>
+ </unique>
+ <tag>fail</tag>
+ The region you're trying to visit contains [REGIONMATURITY] content, but your current preferences are set to exclude [REGIONMATURITY] content.
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
+ name="TeleportEntryAccessBlocked_NotifyAdultsOnly"
+ log_to_im="false"
+ log_to_chat="true"
+ type="notifytip">
+ <unique>
+ <context>REGIONMATURITY</context>
+ </unique>
+ <tag>fail</tag>
+ The region you're trying to visit contains [REGIONMATURITY] content, which is accessible to adults only.
</notification>
<notification
icon="alertmodal.tga"
- name="LandClaimAccessBlocked"
+ name="TeleportEntryAccessBlocked_ChangeAndReTeleport"
type="alertmodal">
-You cannot claim this land due to your maturity Rating. This may be a result of a lack of information validating your age.
+ <unique>
+ <context>REGIONMATURITY</context>
+ </unique>
+ <tag>fail</tag>
+ <tag>confirm</tag>
+ The region you're trying to visit contains [REGIONMATURITY] content, but your current preferences are set to exclude [REGIONMATURITY] content. We can change your preferences and continue with the teleport, or you can cancel this teleport.
+ <form name="form">
+ <button
+ index="0"
+ name="OK"
+ text="Change and continue"/>
+ <button
+ default="true"
+ index="1"
+ name="Cancel"
+ text="Cancel"/>
+ <ignore name="ignore" text="Teleport (restartable): The region you&apos;re trying to visit contains content excluded by your preferences."/>
+ </form>
+ </notification>
-Please verify you have the latest Viewer installed, and go to the Knowledge Base for details on accessing areas with this maturity rating.
- <tag>fail</tag>
+ <notification
+ icon="alertmodal.tga"
+ name="TeleportEntryAccessBlocked_Change"
+ type="alertmodal">
+ <unique>
+ <context>REGIONMATURITY</context>
+ </unique>
+ <tag>fail</tag>
+ <tag>confirm</tag>
+ The region you're trying to visit contains [REGIONMATURITY] content, but your current preferences are set to exclude [REGIONMATURITY] content. We can change your preferences, or you can cancel the teleport. After your preferences are changed, you will need to attempt the teleport again.
+ <form name="form">
+ <button
+ index="0"
+ name="OK"
+ text="Change preferences"/>
+ <button
+ default="true"
+ index="1"
+ name="Cancel"
+ text="Cancel"/>
+ <ignore name="ignore" text="Teleport (non-restartable): The region you&apos;re trying to visit contains content excluded by your preferences."/>
+ </form>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="TeleportEntryAccessBlocked_PreferencesOutOfSync"
+ type="alertmodal">
+ <tag>fail</tag>
+ We are having technical difficulties with your teleport because your preferences are out of sync with the server.
<usetemplate
name="okbutton"
yestext="OK"/>
@@ -4150,12 +4568,43 @@ Please verify you have the latest Viewer installed, and go to the Knowledge Base
<notification
icon="alertmodal.tga"
- name="LandClaimAccessBlocked_KB"
+ name="PreferredMaturityChanged"
type="alertmodal">
-You cannot claim this land due to your maturity Rating.
+You won't receive any more notifications that you're about to visit a region with [RATING] content. You may change your content preferences in the future by using Me &gt; Preferences &gt; General from the menu bar.
+ <tag>confirm</tag>
+ <usetemplate
+ name="okbutton"
+ yestext="OK"/>
+ </notification>
-Go to the Knowledge Base for more information about maturity Ratings?
- <tag>fail</tag>
+ <notification
+ icon="alertmodal.tga"
+ name="MaturityChangeError"
+ type="alertmodal">
+ We were unable to change your preferences to view [PREFERRED_MATURITY] content at this time. Your preferences have been reset to view [ACTUAL_MATURITY] content. You may attempt to change your preferences again by using Me &gt; Preferences &gt; General from the menu bar.
+ <tag>confirm</tag>
+ <usetemplate
+ name="okbutton"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="LandClaimAccessBlocked"
+ type="alertmodal">
+ The land you're trying to claim has a maturity rating exceeding your current preferences. You can change your preferences using Me &gt; Preferences &gt; General.
+ <tag>fail</tag>
+ <usetemplate
+ name="okbutton"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="LandClaimAccessBlocked_AdultsOnlyContent"
+ type="alertmodal">
+ Only adults can claim this land.
+ <tag>fail</tag>
<tag>confirm</tag>
<url option="0" name="url">
http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview
@@ -4164,41 +4613,56 @@ Go to the Knowledge Base for more information about maturity Ratings?
name="okcancelignore"
yestext="Go to Knowledge Base"
notext="Close"
- ignoretext="I can&apos;t claim this Land, due to restrictions of the maturity Rating"/>
+ ignoretext="Only adults can claim this land."/>
</notification>
<notification
icon="notifytip.tga"
name="LandClaimAccessBlocked_Notify"
+ log_to_im="false"
+ log_to_chat="true"
type="notifytip">
-You cannot claim this land due to your maturity Rating.
- <tag>fail</tag>
+ The land you're trying to claim contains [REGIONMATURITY] content, but your current preferences are set to exclude [REGIONMATURITY] content.
+ <tag>fail</tag>
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
+ name="LandClaimAccessBlocked_NotifyAdultsOnly"
+ log_to_im="false"
+ log_to_chat="true"
+ type="notifytip">
+ <tag>fail</tag>
+ The land you're trying to claim contains [REGIONMATURITY] content, which is accessible to adults only.
</notification>
<notification
icon="alertmodal.tga"
name="LandClaimAccessBlocked_Change"
type="alertmodal">
-You cannot claim this land due to your maturity Rating preference.
-
-You can click &apos;Change Preference&apos; to raise your maturity Rating preference now and allow you to enter. You will be able to search and access [REGIONMATURITY] content from now on. If you later want to change this setting back, go to Me &gt; Preferences &gt; General.
+ The land you're trying to claim contains [REGIONMATURITY] content, but your current preferences are set to exclude [REGIONMATURITY] content. We can change your preferences, then you can try claiming the land again.
<tag>fail</tag>
<tag>confirm</tag>
- <usetemplate
- name="okcancelignore"
- yestext="Change Preference"
- notext="Close"
- ignoretext="My chosen Rating preference prevents me from claiming Land"/>
+ <form name="form">
+ <button
+ index="0"
+ name="OK"
+ text="Change preferences"/>
+ <button
+ default="true"
+ index="1"
+ name="Cancel"
+ text="Cancel"/>
+ <ignore name="ignore" text="The land you&apos;re trying to claim contains content excluded by your preferences."/>
+ </form>
</notification>
<notification
icon="alertmodal.tga"
name="LandBuyAccessBlocked"
type="alertmodal">
-You cannot buy this land due to your maturity Rating. This may be a result of a lack of information validating your age.
-
-Please verify you have the latest Viewer installed, and go to the Knowledge Base for details on accessing areas with this maturity rating.
- <tag>fail</tag>
+ The land you're trying to buy has a maturity rating exceeding your current preferences. You can change your preferences using Me &gt; Preferences &gt; General.
+ <tag>fail</tag>
<usetemplate
name="okbutton"
yestext="OK"/>
@@ -4206,11 +4670,9 @@ Please verify you have the latest Viewer installed, and go to the Knowledge Base
<notification
icon="alertmodal.tga"
- name="LandBuyAccessBlocked_KB"
+ name="LandBuyAccessBlocked_AdultsOnlyContent"
type="alertmodal">
-You cannot buy this land due to your maturity Rating.
-
-Go to the Knowledge Base for more information about maturity Ratings?
+ Only adults can buy this land.
<tag>confirm</tag>
<tag>fail</tag>
<url option="0" name="url">
@@ -4220,31 +4682,48 @@ Go to the Knowledge Base for more information about maturity Ratings?
name="okcancelignore"
yestext="Go to Knowledge Base"
notext="Close"
- ignoretext="I can&apos;t buy this Land, due to restrictions of the maturity Rating"/>
+ ignoretext="Only adults can buy this land."/>
</notification>
<notification
icon="notifytip.tga"
name="LandBuyAccessBlocked_Notify"
+ log_to_im="false"
+ log_to_chat="true"
type="notifytip">
-You cannot buy this land due to your maturity Rating.
- <tag>fail</tag>
+ The land you're trying to buy contains [REGIONMATURITY] content, but your current preferences are set to exclude [REGIONMATURITY] content.
+ <tag>fail</tag>
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
+ name="LandBuyAccessBlocked_NotifyAdultsOnly"
+ log_to_im="false"
+ log_to_chat="true"
+ type="notifytip">
+ <tag>fail</tag>
+ The land you're trying to buy contains [REGIONMATURITY] content, which is accessible to adults only.
</notification>
<notification
icon="alertmodal.tga"
name="LandBuyAccessBlocked_Change"
type="alertmodal">
-You cannot buy this land due to your maturity Rating preference.
-
-You can click &apos;Change Preference&apos; to raise your maturity Rating preference now and allow you to enter. You will be able to search and access [REGIONMATURITY] content from now on. If you later want to change this setting back, go to Me &gt; Preferences &gt; General.
+ The land you're trying to buy contains [REGIONMATURITY] content, but your current preferences are set to exclude [REGIONMATURITY] content. We can change your preferences, then you can try buying the land again.
<tag>confirm</tag>
<tag>fail</tag>
- <usetemplate
- name="okcancelignore"
- yestext="Change Preference"
- notext="Close"
- ignoretext="My chosen Rating preference prevents me from buying Land"/>
+ <form name="form">
+ <button
+ index="0"
+ name="OK"
+ text="Change preferences"/>
+ <button
+ default="true"
+ index="1"
+ name="Cancel"
+ text="Cancel"/>
+ <ignore name="ignore" text="The land you&apos;re trying to buy contains content excluded by your preferences."/>
+ </form>
</notification>
<notification
@@ -4399,10 +4878,11 @@ Type a short announcement which will be sent to everyone in this region.
label="Changed Region Maturity"
name="RegionMaturityChange"
type="alertmodal">
-The maturity rating for this region has been updated.
-It may take some time for the change to be reflected on the map.
-
-To enter Adult regions, Residents must be Account Verified, either by age-verification or payment-verification.
+The maturity rating for this region has been changed.
+It may take some time for this change to be reflected on the map.
+ <usetemplate
+ name="okbutton"
+ yestext="OK"/>
</notification>
<notification
@@ -4665,6 +5145,20 @@ Go to your [http://secondlife.com/account/ Dashboard] to see your account histor
<notification
icon="alertmodal.tga"
+ name="ConfirmAddingChatParticipants"
+ type="alertmodal">
+ <unique/>
+When you add a person to an existing conversation, a new conversation will be created. All participants will receive new conversation notifications.
+ <tag>confirm</tag>
+ <usetemplate
+ ignoretext="Confirm adding chat paticipants"
+ name="okcancelignore"
+ notext="Cancel"
+ yestext="Ok"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
name="ConfirmQuit"
type="alertmodal">
<unique/>
@@ -4832,25 +5326,25 @@ Do you want to replace it with the selected object?
<notification
icon="alert.tga"
- label="Busy Mode Warning"
- name="BusyModePay"
+ label="Do Not Disturb Mode Warning"
+ name="DoNotDisturbModePay"
type="alert">
-You are in Busy Mode, which means you will not receive any items offered in exchange for this payment.
+You have turned on Do Not Disturb. You will not receive any items offered in exchange for this payment.
-Would you like to leave Busy Mode before completing this transaction?
+Would you like to turn off Do Not Disturb before completing this transaction?
<tag>confirm</tag>
<form name="form">
<ignore name="ignore"
save_option="true"
- text="I am about to pay a person or object while I am in Busy mode"/>
+ text="I am about to pay a person or object while I am in Do Not Disturb mode"/>
<button
default="true"
- ignore="Always leave Busy Mode"
+ ignore="Always leave Do Not Disturb Mode"
index="0"
name="Yes"
text="OK"/>
<button
- ignore="Never leave Busy Mode"
+ ignore="Never leave Do Not Disturb Mode"
index="1"
name="No"
text="Cancel"/>
@@ -5108,20 +5602,20 @@ Would you like to automatically wear the clothing you are about to create?
icon="alertmodal.tga"
name="NotAgeVerified"
type="alertmodal">
- <tag>fail</tag>
-To access adult content and areas in Second Life you must be at least 18 years old. Please visit our age verification page to confirm you are over 18.
-Note this will launch your web browser.
-
-[_URL]
- <tag>confirm</tag>
- <url option="0" name="url">
- https://secondlife.com/my/account/verification.php
- </url>
+ The location you're trying to visit is restricted to residents age 18 and over.
+ <tag>fail</tag>
<usetemplate
- ignoretext="I have not verified my age"
- name="okcancelignore"
- notext="Cancel"
- yestext="Go to Age Verification"/>
+ ignoretext="I am not old enough to visit age restricted areas."
+ name="okignore"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
+ name="NotAgeVerified_Notify"
+ type="notifytip">
+ Location restricted to age 18 and over.
+ <tag>fail</tag>
</notification>
<notification
@@ -5161,6 +5655,8 @@ The string [STRING_NAME] is missing from strings.xml
<notification
icon="notifytip.tga"
name="IMSystemMessageTip"
+ log_to_im="true"
+ log_to_chat="false"
type="notifytip">
[MESSAGE]
</notification>
@@ -5204,18 +5700,14 @@ Topic: [SUBJECT], Message: [MESSAGE]
<notification
icon="notifytip.tga"
- name="FriendOnline"
- type="notifytip">
- <tag>friendship</tag>
-&lt;nolink&gt;[NAME]&lt;/nolink&gt; is Online
- </notification>
-
- <notification
- icon="notifytip.tga"
- name="FriendOffline"
+ name="FriendOnlineOffline"
+ log_to_chat="false"
type="notifytip">
<tag>friendship</tag>
-&lt;nolink&gt;[NAME]&lt;/nolink&gt; is Offline
+&lt;nolink&gt;[NAME]&lt;/nolink&gt; is [STATUS]
+ <unique combine="cancel_old">
+ <context>NAME</context>
+ </unique>
</notification>
<notification
@@ -5268,7 +5760,7 @@ Terrain.raw downloaded
icon="notifytip.tga"
name="GestureMissing"
type="notifytip">
-Hmm. Gesture [NAME] is missing from the database.
+Gesture [NAME] is missing from the database.
<tag>fail</tag>
</notification>
@@ -5459,6 +5951,8 @@ You don&apos;t have permission to copy this.
<notification
icon="notifytip.tga"
name="InventoryAccepted"
+ log_to_im="true"
+ log_to_chat="false"
type="notifytip">
[NAME] received your inventory offer.
</notification>
@@ -5466,6 +5960,8 @@ You don&apos;t have permission to copy this.
<notification
icon="notifytip.tga"
name="InventoryDeclined"
+ log_to_im="true"
+ log_to_chat="false"
type="notifytip">
[NAME] declined your inventory offer.
</notification>
@@ -5506,9 +6002,7 @@ Your calling card was declined.
icon="notifytip.tga"
name="TeleportToPerson"
type="notifytip">
- To contact Residents like &apos;[NAME]&apos;, click on the &quot;People&quot; button , select a Resident from the window that opens, then click &apos;IM&apos; at the
- bottom of the window.
- (You can also double-click on their name in the list, or right-click and choose &apos;IM&apos;).
+ To open a private conversation with someone, right-click on their avatar and choose &apos;IM&apos; from the menu.
</notification>
<notification
@@ -5544,9 +6038,17 @@ Please select at least one type of content to search (General, Moderate, or Adul
[MESSAGE]
</notification>
+ <notification
+ icon="notify.tga"
+ name="FacebookConnect"
+ type="notifytip">
+[MESSAGE]
+ </notification>
+
<notification
icon="notify.tga"
name="PaymentReceived"
+ log_to_im="true"
persist="true"
type="notify">
<tag>funds</tag>
@@ -5556,6 +6058,7 @@ Please select at least one type of content to search (General, Moderate, or Adul
<notification
icon="notify.tga"
name="PaymentSent"
+ log_to_im="true"
persist="true"
type="notify">
<tag>funds</tag>
@@ -5700,6 +6203,7 @@ The objects on the selected parcel that are NOT owned by you have been returned
<notification
icon="notify.tga"
name="ServerObjectMessage"
+ log_to_im="true"
persist="true"
type="notify">
Message from [NAME]:
@@ -5756,6 +6260,36 @@ This area has building disabled. You can&apos;t build or rez objects here.
</notification>
<notification
+ icon="notify.tga"
+ name="PathfindingDirty"
+ persist="true"
+ type="notify">
+ <unique/>
+ The region has pending pathfinding changes. If you have build rights, you may rebake the region by clicking on the “Rebake region†button.
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="DynamicPathfindingDisabled"
+ persist="true"
+ type="notify">
+ <unique/>
+ Dynamic pathfinding is not enabled on this region. Scripted objects using pathfinding LSL calls may not operate as expected on this region.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="PathfindingCannotRebakeNavmesh"
+ type="alertmodal">
+ <unique/>
+ An error occurred. There may be a network or server problem, or you may not have build rights. Sometimes logging out and back in will solve this problem.
+ <usetemplate
+ name="okbutton"
+ yestext="OK"
+ />
+ </notification>
+
+ <notification
icon="notify.tga"
name="SeeAvatars"
persist="true"
@@ -5803,15 +6337,22 @@ You can only claim public land in the Region you&apos;re in.
<notification
icon="notify.tga"
name="RegionTPAccessBlocked"
- persist="true"
+ persist="false"
type="notify">
<tag>fail</tag>
-You aren&apos;t allowed in that Region due to your maturity Rating. You may need to validate your age and/or install the latest Viewer.
-
-Please go to the Knowledge Base for details on accessing areas with this maturity Rating.
+ The region you're trying to visit contains content exceeding your current preferences. You can change your preferences using Me &gt; Preferences &gt; General.
</notification>
<notification
+ icon="notify.tga"
+ name="RegionAboutToShutdown"
+ persist="false"
+ type="notify">
+ <tag>fail</tag>
+ The region you're trying to enter is about to shut down.
+ </notification>
+
+ <notification
icon="notify.tga"
name="URBannedFromRegion"
persist="true"
@@ -5840,11 +6381,11 @@ You do not have proper payment status to enter this region.
<notification
icon="notify.tga"
- name="MustGetAgeRgion"
+ name="MustGetAgeRegion"
persist="true"
type="notify">
<tag>fail</tag>
-You must be age-verified to enter this region.
+You must be age 18 or over to enter this region.
</notification>
<notification
@@ -5853,7 +6394,7 @@ You must be age-verified to enter this region.
persist="true"
type="notify">
<tag>fail</tag>
-You must be age-verified to enter this parcel.
+ You must be age 18 or over to enter this parcel.
</notification>
<notification
@@ -6070,7 +6611,9 @@ Your object named &lt;nolink&gt;[OBJECTFROMNAME]&lt;/nolink&gt; has given you th
<notification
icon="notify.tga"
name="UserGiveItem"
- type="offer">
+ log_to_im ="true"
+ type="offer"
+ sound="UISndNewIncomingIMSession">
[NAME_SLURL] has given you this [OBJECTTYPE]:
[ITEM_SLURL]
<form name="form">
@@ -6103,7 +6646,7 @@ Your object named &lt;nolink&gt;[OBJECTFROMNAME]&lt;/nolink&gt; has given you th
icon="notify.tga"
name="JoinGroup"
persist="true"
- type="notify">
+ type="offer">
<tag>group</tag>
[MESSAGE]
<form name="form">
@@ -6125,10 +6668,14 @@ Your object named &lt;nolink&gt;[OBJECTFROMNAME]&lt;/nolink&gt; has given you th
<notification
icon="notify.tga"
name="TeleportOffered"
- type="offer">
+ log_to_im="true"
+ log_to_chat="false"
+ type="offer"
+ sound="UISndNewIncomingIMSession">
[NAME_SLURL] has offered to teleport you to their location:
-[MESSAGE] - [MATURITY_STR] &lt;icon&gt;[MATURITY_ICON]&lt;/icon&gt;
+"[MESSAGE]â€
+&lt;icon&gt;[MATURITY_ICON]&lt;/icon&gt; - [MATURITY_STR]
<tag>confirm</tag>
<form name="form">
<button
@@ -6144,11 +6691,75 @@ Your object named &lt;nolink&gt;[OBJECTFROMNAME]&lt;/nolink&gt; has given you th
<notification
icon="notify.tga"
- name="TeleportOfferSent"
+ name="TeleportOffered_MaturityExceeded"
+ log_to_im="true"
+ log_to_chat="false"
type="offer">
+[NAME_SLURL] has offered to teleport you to their location:
+
+“[MESSAGE]â€
+&lt;icon&gt;[MATURITY_ICON]&lt;/icon&gt; - [MATURITY_STR]
+
+This region contains [REGION_CONTENT_MATURITY] content, but your current preferences are set to exclude [REGION_CONTENT_MATURITY] content. We can change your preferences and continue with the teleport, or you can cancel this teleport.
+ <tag>confirm</tag>
+ <form name="form">
+ <button
+ index="0"
+ name="Teleport"
+ text="Change and Continue"/>
+ <button
+ index="1"
+ name="Cancel"
+ text="Cancel"/>
+ </form>
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="TeleportOffered_MaturityBlocked"
+ log_to_im="true"
+ log_to_chat="false"
+ type="notifytip">
+[NAME_SLURL] has offered to teleport you to their location:
+
+“[MESSAGE]â€
+&lt;icon&gt;[MATURITY_ICON]&lt;/icon&gt; - [MATURITY_STR]
+
+However, this region contains content accessible to adults only.
+ <tag>fail</tag>
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="TeleportOfferSent"
+ log_to_im="true"
+ log_to_chat="false"
+ show_toast="false"
+ type="notify">
Teleport offer sent to [TO_NAME]
</notification>
+ <notification
+ icon="notify.tga"
+ name="TeleportRequest"
+ log_to_im="true"
+ type="offer">
+[NAME_SLURL] is requesting to be teleported to your location.
+[MESSAGE]
+
+Offer a teleport?
+ <tag>confirm</tag>
+ <form name="form">
+ <button
+ index="0"
+ name="Yes"
+ text="Yes"/>
+ <button
+ index="1"
+ name="No"
+ text="No"/>
+ </form>
+ </notification>
<notification
icon="notify.tga"
@@ -6172,6 +6783,7 @@ Your object named &lt;nolink&gt;[OBJECTFROMNAME]&lt;/nolink&gt; has given you th
<notification
icon="notify.tga"
name="OfferFriendship"
+ log_to_im="true"
type="offer">
<tag>friendship</tag>
<tag>confirm</tag>
@@ -6195,7 +6807,8 @@ Your object named &lt;nolink&gt;[OBJECTFROMNAME]&lt;/nolink&gt; has given you th
<notification
icon="notify.tga"
name="FriendshipOffered"
- type="offer">
+ log_to_im="true"
+ type="notify">
<tag>friendship</tag>
You have offered friendship to [TO_NAME]
</notification>
@@ -6224,7 +6837,8 @@ Your object named &lt;nolink&gt;[OBJECTFROMNAME]&lt;/nolink&gt; has given you th
<notification
icon="notify.tga"
name="FriendshipAccepted"
- type="offer">
+ log_to_im="true"
+ type="notify">
<tag>friendship</tag>
&lt;nolink&gt;[NAME]&lt;/nolink&gt; accepted your friendship offer.
</notification>
@@ -6232,6 +6846,7 @@ Your object named &lt;nolink&gt;[OBJECTFROMNAME]&lt;/nolink&gt; has given you th
<notification
icon="notify.tga"
name="FriendshipDeclined"
+ log_to_im="true"
persist="true"
type="notify">
<tag>friendship</tag>
@@ -6241,7 +6856,8 @@ Your object named &lt;nolink&gt;[OBJECTFROMNAME]&lt;/nolink&gt; has given you th
<notification
icon="notify.tga"
name="FriendshipAcceptedByMe"
- type="offer">
+ log_to_im="true"
+ type="notify">
<tag>friendship</tag>
Friendship offer accepted.
</notification>
@@ -6249,7 +6865,8 @@ Friendship offer accepted.
<notification
icon="notify.tga"
name="FriendshipDeclinedByMe"
- type="offer">
+ log_to_im="true"
+ type="notify">
<tag>friendship</tag>
Friendship offer declined.
</notification>
@@ -6278,9 +6895,8 @@ This will add a bookmark in your inventory so you can quickly IM this Resident.
name="RegionRestartMinutes"
priority="high"
sound="UISndAlert"
- persist="true"
type="notify">
-This region will restart in [MINUTES] minutes.
+The region "[NAME]" will restart in [MINUTES] minutes.
If you stay in this region you will be logged out.
</notification>
@@ -6289,15 +6905,15 @@ If you stay in this region you will be logged out.
name="RegionRestartSeconds"
priority="high"
sound="UISndAlert"
- persist="true"
type="notify">
-This region will restart in [SECONDS] seconds.
+The region "[NAME]" will restart in [SECONDS] seconds.
If you stay in this region you will be logged out.
</notification>
<notification
icon="notify.tga"
name="LoadWebPage"
+ show_toast="false"
type="notify">
Load web page [URL]?
@@ -6373,36 +6989,56 @@ Is this OK?
<notification
icon="notify.tga"
name="ScriptQuestionCaution"
- priority="high"
+ priority="critical"
persist="true"
type="notify">
-An object named &apos;&lt;nolink&gt;[OBJECTNAME]&lt;/nolink&gt;&apos;, owned by &apos;[NAME]&apos; would like to:
-
-[QUESTIONS]
-If you do not trust this object and its creator, you should deny the request.
+Warning: The object &apos;&lt;nolink&gt;[OBJECTNAME]&lt;/nolink&gt;&apos; wants total access to your Linden Dollars account. If you allow access, it can remove funds from your account at any time, or empty your account completely, on an ongoing basis with no additional warnings.
+
+Do not allow access if you do not fully understand why it wants access to your account.
-Grant this request?
<tag>confirm</tag>
<form name="form">
<button
index="0"
name="Grant"
- text="Grant"/>
+ text="Allow total access"/>
<button
default="true"
index="1"
name="Deny"
text="Deny"/>
- <button
- index="2"
- name="Details"
- text="Details..."/>
</form>
+ <footer>
+[FOOTERTEXT]
+ </footer>
</notification>
<notification
icon="notify.tga"
+ name="UnknownScriptQuestion"
+ persist="false"
+ type="notify">
+The runtime script permission requested by &apos;&lt;nolink&gt;[OBJECTNAME]&lt;/nolink&gt;&apos;, an object owned by &apos;[NAME]&apos;, isn&apos;t recognized by the viewer and can&apos;t be granted.
+
+To grant this permission please update your viewer to the latest version from [DOWNLOADURL].
+ <tag>confirm</tag>
+ <form name="form">
+ <button
+ default="true"
+ index="1"
+ name="Deny"
+ text="Ok"/>
+ <button
+ index="2"
+ name="Mute"
+ text="Block"/>
+ </form>
+ </notification>
+
+ <notification
+ icon="notify.tga"
name="ScriptDialog"
+ show_toast="false"
type="notify">
[NAME]&apos;s &apos;&lt;nolink&gt;[TITLE]&lt;/nolink&gt;&apos;
[MESSAGE]
@@ -6421,6 +7057,7 @@ Grant this request?
<notification
icon="notify.tga"
name="ScriptDialogGroup"
+ show_toast="false"
type="notify">
<tag>group</tag>
[GROUPNAME]&apos;s &apos;&lt;nolink&gt;[TITLE]&lt;/nolink&gt;&apos;
@@ -7181,6 +7818,18 @@ You locally updated a [RESOLUTION] baked texture for '[BODYREGION]' after [TIME]
<notification
icon="alertmodal.tga"
+ name="LivePreviewUnavailable"
+ type="alert">
+
+We cannot display a preview of this texture because it is no-copy and/or no-transfer.
+ <usetemplate
+ ignoretext="Warn me that Live Preview mode is not available for no-copy and/or no-transfer textures"
+ name="okignore"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
name="ConfirmLeaveCall"
type="alert">
Are you sure you want to leave this call?
@@ -7663,7 +8312,135 @@ The site at &apos;&lt;nolink&gt;[HOST_NAME]&lt;/nolink&gt;&apos; in realm &apos;
notext="Cancel"
ignoretext="Confirm before hiding UI"/>
</notification>
-
+
+ <notification
+ icon="alertmodal.tga"
+ name="PathfindingLinksets_WarnOnPhantom"
+ type="alertmodal">
+Some selected linksets will have the Phantom flag toggled.
+
+Do you wish to continue?
+ <tag>confirm</tag>
+ <usetemplate
+ ignoretext="Some selected linksets phantom flag will be toggled."
+ name="okcancelignore"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="PathfindingLinksets_MismatchOnRestricted"
+ type="alertmodal">
+Some selected linksets cannot be set to be '[REQUESTED_TYPE]' because of permission restrictions on the linkset. These linksets will be set to be '[RESTRICTED_TYPE]' instead.
+
+Do you wish to continue?
+ <tag>confirm</tag>
+ <usetemplate
+ ignoretext="Some selected linksets cannot be set because of permission restrictions on the linkset."
+ name="okcancelignore"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="PathfindingLinksets_MismatchOnVolume"
+ type="alertmodal">
+Some selected linksets cannot be set to be '[REQUESTED_TYPE]' because the shape is non-convex.
+
+Do you wish to continue?
+ <tag>confirm</tag>
+ <usetemplate
+ ignoretext="Some selected linksets cannot be set because the shape is non-convex"
+ name="okcancelignore"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="PathfindingLinksets_WarnOnPhantom_MismatchOnRestricted"
+ type="alertmodal">
+Some selected linksets will have the Phantom flag toggled.
+
+Some selected linksets cannot be set to be '[REQUESTED_TYPE]' because of permission restrictions on the linkset. These linksets will be set to be '[RESTRICTED_TYPE]' instead.
+
+Do you wish to continue?
+ <tag>confirm</tag>
+ <usetemplate
+ ignoretext="Some selected linksets phantom flag will be toggled and others cannot be set because of permission restrictions on the linkset."
+ name="okcancelignore"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="PathfindingLinksets_WarnOnPhantom_MismatchOnVolume"
+ type="alertmodal">
+Some selected linksets will have the Phantom flag toggled.
+
+Some selected linksets cannot be set to be '[REQUESTED_TYPE]' because the shape is non-convex.
+
+Do you wish to continue?
+ <tag>confirm</tag>
+ <usetemplate
+ ignoretext="Some selected linksets phantom flag will be toggled and others cannot be set because the shape is non-convex"
+ name="okcancelignore"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="PathfindingLinksets_MismatchOnRestricted_MismatchOnVolume"
+ type="alertmodal">
+Some selected linksets cannot be set to be '[REQUESTED_TYPE]' because of permission restrictions on the linkset. These linksets will be set to be '[RESTRICTED_TYPE]' instead.
+
+Some selected linksets cannot be set to be '[REQUESTED_TYPE]' because the shape is non-convex. These linksets&apos; use types will not change.
+
+Do you wish to continue?
+ <tag>confirm</tag>
+ <usetemplate
+ ignoretext="Some selected linksets cannot be set because of permission restrictions on the linkset and because the shape is non-convex."
+ name="okcancelignore"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="PathfindingLinksets_WarnOnPhantom_MismatchOnRestricted_MismatchOnVolume"
+ type="alertmodal">
+Some selected linksets will have the Phantom flag toggled.
+
+Some selected linksets cannot be set to be '[REQUESTED_TYPE]' because of permission restrictions on the linkset. These linksets will be set to be '[RESTRICTED_TYPE]' instead.
+
+Some selected linksets cannot be set to be '[REQUESTED_TYPE]' because the shape is non-convex. These linksets&apos; use types will not change.
+
+Do you wish to continue?
+ <tag>confirm</tag>
+ <usetemplate
+ ignoretext="Some selected linksets phantom flag will be toggled and others cannot be set because of permission restrictions on the linkset and because the shape is non-convex."
+ name="okcancelignore"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="PathfindingLinksets_ChangeToFlexiblePath"
+ type="alertmodal">
+ The selected object affects the navmesh. Changing it to a Flexible Path will remove it from the navmesh.
+ <tag>confirm</tag>
+ <usetemplate
+ ignoretext="The selected object affects the navmesh. Changing it to a Flexible Path will remove it from the navmesh."
+ name="okcancelignore"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
<global name="UnsupportedGLRequirements">
You do not appear to have the proper hardware requirements for [APP_NAME]. [APP_NAME] requires an OpenGL graphics card that has multitexture support. If this is the case, you may want to make sure that you have the latest drivers for your graphics card, and service packs and patches for your operating system.
@@ -7725,6 +8502,1716 @@ Attempt cancelled.
<notification
icon="alertmodal.tga"
+ name="PathfindingReturnMultipleItems"
+ type="alertmodal">
+ You are returning [NUM_ITEMS] items. Are you sure you want to continue?
+ <tag>confirm</tag>
+ <usetemplate
+ ignoretext="Are you sure you want to return multiple items?"
+ name="okcancelignore"
+ notext="No"
+ yestext="Yes"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="PathfindingDeleteMultipleItems"
+ type="alertmodal">
+ You are deleting [NUM_ITEMS] items. Are you sure you want to continue?
+ <tag>confirm</tag>
+ <usetemplate
+ ignoretext="Are you sure you want to delete multiple items?"
+ name="okcancelignore"
+ notext="No"
+ yestext="Yes"/>
+ </notification>
+
+
+ <notification
+ icon="alertmodal.tga"
+ name="AvatarFrozen"
+ type="notify">
+ <tag>fail</tag>
+[AV_FREEZER] has frozen you. You cannot move or interact with the world.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="AvatarFrozenDuration"
+ type="notify">
+ <tag>fail</tag>
+[AV_FREEZER] has frozen you for [AV_FREEZE_TIME] seconds. You cannot move or interact with the world.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="YouFrozeAvatar"
+ type="notify">
+ <tag>fail</tag>
+Avatar frozen.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="AvatarHasUnFrozenYou"
+ type="notify">
+ <tag>fail</tag>
+[AV_FREEZER] has unfrozen you.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="AvatarUnFrozen"
+ type="notify">
+ <tag>fail</tag>
+Avatar unfrozen.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="AvatarFreezeFailure"
+ type="notify">
+ <tag>fail</tag>
+Freeze failed because you don't have admin permission for that parcel.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="AvatarFreezeThaw"
+ type="notify">
+ <tag>fail</tag>
+Your freeze expired, go about your business.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="AvatarCantFreeze"
+ type="notify">
+ <tag>fail</tag>
+Sorry, can't freeze that user.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="NowOwnObject"
+ type="notify">
+ <tag>fail</tag>
+You are now the owner of object [OBJECT_NAME]
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantRezOnLand"
+ type="notify">
+ <tag>fail</tag>
+Can't rez object at [OBJECT_POS] because the owner of this land does not allow it. Use the land tool to see land ownership.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="RezFailTooManyRequests"
+ type="notify">
+ <tag>fail</tag>
+Object can not be rezzed because there are too many requests.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="SitFailCantMove"
+ type="notify">
+ <tag>fail</tag>
+You cannot sit because you cannot move at this time.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="SitFailNotAllowedOnLand"
+ type="notify">
+ <tag>fail</tag>
+You cannot sit because you are not allowed on that land.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="SitFailNotSameRegion"
+ type="notify">
+ <tag>fail</tag>
+Try moving closer. Can't sit on object because
+it is not in the same region as you.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="NoNewObjectRegionFull"
+ type="notify">
+ <tag>fail</tag>
+Unable to create new object. The region is full.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="FailedToPlaceObject"
+ type="notify">
+ <tag>fail</tag>
+Failed to place object at specified location. Please try again.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="NoOwnNoGardening"
+ type="notify">
+ <tag>fail</tag>
+You Can't create trees and grass on land you don't own.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="NoCopyPermsNoObject"
+ type="notify">
+ <tag>fail</tag>
+Copy failed because you lack permission to copy the object '[OBJ_NAME]'.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="NoTransPermsNoObject"
+ type="notify">
+ <tag>fail</tag>
+Copy failed because the object '[OBJ_NAME]' cannot be transferred to you.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="AddToNavMeshNoCopy"
+ type="notify">
+ <tag>fail</tag>
+Copy failed because the object '[OBJ_NAME]' contributes to navmesh.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="DupeWithNoRootsSelected"
+ type="notify">
+ <tag>fail</tag>
+Duplicate with no root objects selected.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantDupeCuzRegionIsFull"
+ type="notify">
+ <tag>fail</tag>
+Can't duplicate objects because the region is full.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantDupeCuzParcelNotFound"
+ type="notify">
+ <tag>fail</tag>
+Can't duplicate objects - Can't find the parcel they are on.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantCreateCuzParcelFull"
+ type="notify">
+ <tag>fail</tag>
+Can't create object because
+the parcel is full.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="RezAttemptFailed"
+ type="notify">
+ <tag>fail</tag>
+Attempt to rez an object failed.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ToxicInvRezAttemptFailed"
+ type="notify">
+ <tag>fail</tag>
+Unable to create item that has caused problems on this region.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="InvItemIsBlacklisted"
+ type="notify">
+ <tag>fail</tag>
+That inventory item has been blacklisted.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="NoCanRezObjects"
+ type="notify">
+ <tag>fail</tag>
+You are not currently allowed to create objects.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="LandSearchBlocked"
+ type="notify">
+ <tag>fail</tag>
+Land Search Blocked.
+You have performed too many land searches too quickly.
+Please try again in a minute.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="NotEnoughResourcesToAttach"
+ type="notify">
+ <tag>fail</tag>
+Not enough script resources available to attach object!
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="YouDiedAndGotTPHome"
+ type="notify">
+ <tag>fail</tag>
+You died and have been teleported to your home location
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="EjectComingSoon"
+ type="notify">
+ <tag>fail</tag>
+You are no longer allowed here and have [EJECT_TIME] seconds to leave.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="NoEnterRegionMaybeFull"
+ type="notify">
+ <tag>fail</tag>
+You can't enter region "[NAME]".
+It may be full or restarting soon.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="SaveBackToInvDisabled"
+ type="notify">
+ <tag>fail</tag>
+Save Back To Inventory has been disabled.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="NoExistNoSaveToContents"
+ type="notify">
+ <tag>fail</tag>
+Cannot save '[OBJ_NAME]' to object contents because the object it was rezzed from no longer exists.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="NoModNoSaveToContents"
+ type="notify">
+ <tag>fail</tag>
+Cannot save '[OBJ_NAME]' to object contents because you do not have permission to modify the object '[DEST_NAME]'.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="NoSaveBackToInvDisabled"
+ type="notify">
+ <tag>fail</tag>
+Cannot save '[OBJ_NAME]' back to inventory -- this operation has been disabled.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="NoCopyNoSelCopy"
+ type="notify">
+ <tag>fail</tag>
+You cannot copy your selection because you do not have permission to copy the object '[OBJ_NAME]'.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="NoTransNoSelCopy"
+ type="notify">
+ <tag>fail</tag>
+You cannot copy your selection because the object '[OBJ_NAME]' is not transferrable.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="NoTransNoCopy"
+ type="notify">
+ <tag>fail</tag>
+You cannot copy your selection because the object '[OBJ_NAME]' is not transferrable.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="NoPermsNoRemoval"
+ type="notify">
+ <tag>fail</tag>
+Removal of the object '[OBJ_NAME]' from the simulator is disallowed by the permissions system.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="NoModNoSaveSelection"
+ type="notify">
+ <tag>fail</tag>
+Cannot save your selection because you do not have permission to modify the object '[OBJ_NAME]'.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="NoCopyNoSaveSelection"
+ type="notify">
+ <tag>fail</tag>
+Cannot save your selection because the object '[OBJ_NAME]' is not copyable.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="NoModNoTaking"
+ type="notify">
+ <tag>fail</tag>
+You cannot take your selection because you do not have permission to modify the object '[OBJ_NAME]'.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="RezDestInternalError"
+ type="notify">
+ <tag>fail</tag>
+Internal Error: Unknown destination type.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="DeleteFailObjNotFound"
+ type="notify">
+ <tag>fail</tag>
+Delete failed because object not found
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="SorryCantEjectUser"
+ type="notify">
+ <tag>fail</tag>
+Sorry, can't eject that user.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="RegionSezNotAHome"
+ type="notify">
+ <tag>fail</tag>
+This region does not allow you to set your home location here.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="HomeLocationLimits"
+ type="notify">
+ <tag>fail</tag>
+You can only set your 'Home Location' on your land or at a mainland Infohub.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="HomePositionSet"
+ type="notify">
+ <tag>fail</tag>
+Home position set.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="AvatarEjected"
+ type="notify">
+ <tag>fail</tag>
+Avatar ejected.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="AvatarEjectFailed"
+ type="notify">
+ <tag>fail</tag>
+Eject failed because you don't have admin permission for that parcel.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantMoveObjectParcelFull"
+ type="notify">
+ <tag>fail</tag>
+Can't move object '[OBJECT_NAME]' to
+[OBJ_POSITION] in region [REGION_NAME] because the parcel is full.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantMoveObjectParcelPerms"
+ type="notify">
+ <tag>fail</tag>
+Can't move object '[OBJECT_NAME]' to
+[OBJ_POSITION] in region [REGION_NAME] because your objects are not allowed on this parcel.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantMoveObjectParcelResources"
+ type="notify">
+ <tag>fail</tag>
+Can't move object '[OBJECT_NAME]' to
+[OBJ_POSITION] in region [REGION_NAME] because there are not enough resources for this object on this parcel.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantMoveObjectRegionVersion"
+ type="notify">
+ <tag>fail</tag>
+Can't move object '[OBJECT_NAME]' to
+[OBJ_POSITION] in region [REGION_NAME] because the other region is running an older version which does not support receiving this object via region crossing.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantMoveObjectNavMesh"
+ type="notify">
+ <tag>fail</tag>
+Can't move object '[OBJECT_NAME]' to
+[OBJ_POSITION] in region [REGION_NAME] because you cannot modify the navmesh across region boundaries.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantMoveObjectWTF"
+ type="notify">
+ <tag>fail</tag>
+Can't move object '[OBJECT_NAME]' to
+[OBJ_POSITION] in region [REGION_NAME] because of an unknown reason. ([FAILURE_TYPE])
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="NoPermModifyObject"
+ type="notify">
+ <tag>fail</tag>
+You don't have permission to modify that object
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantEnablePhysObjContributesToNav"
+ type="notify">
+ <tag>fail</tag>
+Can't enable physics for an object that contributes to the navmesh.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantEnablePhysKeyframedObj"
+ type="notify">
+ <tag>fail</tag>
+Can't enable physics for keyframed objects.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantEnablePhysNotEnoughLandResources"
+ type="notify">
+ <tag>fail</tag>
+Can't enable physics for object -- insufficient land resources.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantEnablePhysCostTooGreat"
+ persist="true"
+ type="notify">
+ <tag>fail</tag>
+Can't enable physics for object with physics resource cost greater than [MAX_OBJECTS]
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="PhantomWithConcavePiece"
+ type="notify">
+ <tag>fail</tag>
+This object cannot have a concave piece because it is phantom and contributes to the navmesh.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="UnableAddItem"
+ type="notify">
+ <tag>fail</tag>
+Unable to add item!
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="UnableEditItem"
+ type="notify">
+ <tag>fail</tag>
+Unable to edit this!
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="NoPermToEdit"
+ type="notify">
+ <tag>fail</tag>
+Not permitted to edit this.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="NoPermToCopyInventory"
+ type="notify">
+ <tag>fail</tag>
+Not permitted to copy that inventory.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantSaveItemDoesntExist"
+ type="notify">
+ <tag>fail</tag>
+Cannot save to object contents: Item no longer exists.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantSaveItemAlreadyExists"
+ type="notify">
+ <tag>fail</tag>
+Cannot save to object contents: Item with that name already exists in inventory
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantSaveModifyAttachment"
+ type="notify">
+ <tag>fail</tag>
+Cannot save to object contents: This would modify the attachment permissions.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="TooManyScripts"
+ type="notify">
+ <tag>fail</tag>
+Too many scripts.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="UnableAddScript"
+ type="notify">
+ <tag>fail</tag>
+Unable to add script!
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="AssetServerTimeoutObjReturn"
+ type="notify">
+ <tag>fail</tag>
+Asset server didn't respond in a timely fashion. Object returned to sim.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="RegionDisablePhysicsShapes"
+ type="notify">
+ <tag>fail</tag>
+This region does not have physics shapes enabled.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="NoModNavmeshAcrossRegions"
+ type="notify">
+ <tag>fail</tag>
+You cannot modify the navmesh across region boundaries.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="NoSetPhysicsPropertiesOnObjectType"
+ type="notify">
+ <tag>fail</tag>
+Cannot set physics properties on that object type.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="NoSetRootPrimWithNoShape"
+ type="notify">
+ <tag>fail</tag>
+Cannot set root prim to have no shape.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="NoRegionSupportPhysMats"
+ type="notify">
+ <tag>fail</tag>
+This region does not have physics materials enabled.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="OnlyRootPrimPhysMats"
+ type="notify">
+ <tag>fail</tag>
+Only root prims may have their physics materials adjusted.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="NoSupportCharacterPhysMats"
+ type="notify">
+ <tag>fail</tag>
+Setting physics materials on characters is not yet supported.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="InvalidPhysMatProperty"
+ type="notify">
+ <tag>fail</tag>
+One or more of the specified physics material properties was invalid.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="NoPermsAlterStitchingMeshObj"
+ type="notify">
+ <tag>fail</tag>
+You may not alter the stitching type of a mesh object.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="NoPermsAlterShapeMeshObj"
+ type="notify">
+ <tag>fail</tag>
+You may not alter the shape of a mesh object
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="FullRegionCantEnter"
+ type="notify">
+ <tag>fail</tag>
+You can't enter this region because \nthe region is full.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="LinkFailedOwnersDiffer"
+ type="notify">
+ <tag>fail</tag>
+Link failed -- owners differ
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="LinkFailedNoModNavmeshAcrossRegions"
+ type="notify">
+ <tag>fail</tag>
+Link failed -- cannot modify the navmesh across region boundaries.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="LinkFailedNoPermToEdit"
+ type="notify">
+ <tag>fail</tag>
+Link failed because you do not have edit permission.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="LinkFailedTooManyPrims"
+ type="notify">
+ <tag>fail</tag>
+Link failed -- too many primitives
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="LinkFailedCantLinkNoCopyNoTrans"
+ type="notify">
+ <tag>fail</tag>
+Link failed -- cannot link no-copy with no-transfer
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="LinkFailedNothingLinkable"
+ type="notify">
+ <tag>fail</tag>
+Link failed -- nothing linkable.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="LinkFailedTooManyPathfindingChars"
+ type="notify">
+ <tag>fail</tag>
+Link failed -- too many pathfinding characters
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="LinkFailedInsufficientLand"
+ type="notify">
+ <tag>fail</tag>
+Link failed -- insufficient land resources
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="LinkFailedTooMuchPhysics"
+ type="notify">
+ <tag>fail</tag>
+Object uses too many physics resources -- its dynamics have been disabled.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="TeleportedHomeByObjectOnParcel"
+ persist="true"
+ type="notify">
+ <tag>fail</tag>
+You have been teleported home by the object '[OBJECT_NAME]' on the parcel '[PARCEL_NAME]'
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="TeleportedHomeByObject"
+ persist="true"
+ type="notify">
+ <tag>fail</tag>
+You have been teleported home by the object '[OBJECT_NAME]'
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="TeleportedByAttachment"
+ type="notify">
+ <tag>fail</tag>
+You have been teleported by an attachment on [ITEM_ID]
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="TeleportedByObjectOnParcel"
+ type="notify">
+ <tag>fail</tag>
+You have been teleported by the object '[OBJECT_NAME]' on the parcel '[PARCEL_NAME]'
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="TeleportedByObjectOwnedBy"
+ type="notify">
+ <tag>fail</tag>
+You have been teleported by the object '[OBJECT_NAME]' owned by [OWNER_ID]
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="TeleportedByObjectUnknownUser"
+ type="notify">
+ <tag>fail</tag>
+You have been teleported by the object '[OBJECT_NAME]' owned by an unknown user.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantCreateObjectRegionFull"
+ type="notify">
+ <tag>fail</tag>
+Unable to create requested object. The region is full.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantAttackMultipleObjOneSpot"
+ type="notify">
+ <tag>fail</tag>
+You can't attach multiple objects to one spot.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantCreateMultipleObjAtLoc"
+ type="notify">
+ <tag>fail</tag>
+You can't create multiple objects here.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="UnableToCreateObjTimeOut"
+ type="notify">
+ <tag>fail</tag>
+Unable to create requested object. Object is missing from database.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="UnableToCreateObjUnknown"
+ type="notify">
+ <tag>fail</tag>
+Unable to create requested object. The request timed out. Please try again.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="UnableToCreateObjMissingFromDB"
+ type="notify">
+ <tag>fail</tag>
+Unable to create requested object. Please try again.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="RezFailureTookTooLong"
+ type="notify">
+ <tag>fail</tag>
+Rez failed, requested object took too long to load.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="FailedToPlaceObjAtLoc"
+ type="notify">
+ <tag>fail</tag>
+Failed to place object at specified location. Please try again.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantCreatePlantsOnLand"
+ type="notify">
+ <tag>fail</tag>
+You cannot create plants on this land.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantRestoreObjectNoWorldPos"
+ type="notify">
+ <tag>fail</tag>
+Cannot restore object. No world position found.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantRezObjectInvalidMeshData"
+ type="notify">
+ <tag>fail</tag>
+Unable to rez object because its mesh data is invalid.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantRezObjectTooManyScripts"
+ type="notify">
+ <tag>fail</tag>
+Unable to rez object because there are already too many scripts in this region.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantCreateObjectNoAccess"
+ type="notify">
+ <tag>fail</tag>
+Your access privileges don't allow you to create objects there.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantCreateObject"
+ type="notify">
+ <tag>fail</tag>
+You are not currently allowed to create objects.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="InvalidObjectParams"
+ type="notify">
+ <tag>fail</tag>
+Invalid object parameters
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantDuplicateObjectNoAcess"
+ type="notify">
+ <tag>fail</tag>
+Your access privileges don't allow you to duplicate objects here.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantChangeShape"
+ type="notify">
+ <tag>fail</tag>
+You are not allowed to change this shape.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="NoAccessToClaimObjects"
+ type="notify">
+ <tag>fail</tag>
+Your access privileges don't allow you to claim objects here.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="DeedFailedNoPermToDeedForGroup"
+ type="notify">
+ <tag>fail</tag>
+Deed failed because you do not have permission to deed objects for your group.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="NoPrivsToBuyObject"
+ type="notify">
+ <tag>fail</tag>
+Your access privileges don't allow you to buy objects here.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantAttachObjectAvatarSittingOnIt"
+ type="notify">
+ <tag>fail</tag>
+Cannot attach object because an avatar is sitting on it.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="WhyAreYouTryingToWearShrubbery"
+ type="notify">
+ <tag>fail</tag>
+Trees and grasses cannot be worn as attachments.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantAttachGroupOwnedObjs"
+ type="notify">
+ <tag>fail</tag>
+Cannot attach group-owned objects.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantAttachObjectsNotOwned"
+ type="notify">
+ <tag>fail</tag>
+Cannot attach objects that you don't own.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantAttachNavmeshObjects"
+ type="notify">
+ <tag>fail</tag>
+Cannot attach objects that contribute to navmesh.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantAttachObjectNoMovePermissions"
+ type="notify">
+ <tag>fail</tag>
+Cannot attach object because you do not have permission to move it.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantAttachNotEnoughScriptResources"
+ type="notify">
+ <tag>fail</tag>
+Not enough script resources available to attach object!
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantAttachObjectBeingRemoved"
+ type="notify">
+ <tag>fail</tag>
+ Cannot attach object because it is already being removed.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantDropItemTrialUser"
+ type="notify">
+ <tag>fail</tag>
+You can't drop objects here; try the Free Trial area.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantDropMeshAttachment"
+ type="notify">
+ <tag>fail</tag>
+You can't drop mesh attachments. Detach to inventory and then rez in world.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantDropAttachmentNoPermission"
+ type="notify">
+ <tag>fail</tag>
+Failed to drop attachment: you don't have permission to drop there.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantDropAttachmentInsufficientLandResources"
+ type="notify">
+ <tag>fail</tag>
+Failed to drop attachment: insufficient available land resource.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantDropAttachmentInsufficientResources"
+ type="notify">
+ <tag>fail</tag>
+Failed to drop attachments: insufficient available resources.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantDropObjectFullParcel"
+ type="notify">
+ <tag>fail</tag>
+Cannot drop object here. Parcel is full.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantTouchObjectBannedFromParcel"
+ type="notify">
+ <tag>fail</tag>
+Can't touch/grab this object because you are banned from the land parcel.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="PlzNarrowDeleteParams"
+ type="notify">
+ <tag>fail</tag>
+Please narrow your delete parameters.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="UnableToUploadAsset"
+ type="notify">
+ <tag>fail</tag>
+Unable to upload asset.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantTeleportCouldNotFindUser"
+ type="notify">
+ <tag>fail</tag>
+Could not find user to teleport home
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="GodlikeRequestFailed"
+ type="notify">
+ <tag>fail</tag>
+godlike request failed
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="GenericRequestFailed"
+ type="notify">
+ <tag>fail</tag>
+generic request failed
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantUploadPostcard"
+ type="notify">
+ <tag>fail</tag>
+Unable to upload postcard. Try again later.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantFetchInventoryForGroupNotice"
+ type="notify">
+ <tag>fail</tag>
+Unable to fetch inventory details for the group notice.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantSendGroupNoticeNotPermitted"
+ type="notify">
+ <tag>fail</tag>
+Unable to send group notice -- not permitted.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantSendGroupNoticeCantConstructInventory"
+ type="notify">
+ <tag>fail</tag>
+Unable to send group notice -- could not construct inventory.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantParceInventoryInNotice"
+ type="notify">
+ <tag>fail</tag>
+Unable to parse inventory in notice.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="TerrainUploadFailed"
+ type="notify">
+ <tag>fail</tag>
+Terrain upload failed.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="TerrainFileWritten"
+ type="notify">
+ <tag>fail</tag>
+Terrain file written.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="TerrainFileWrittenStartingDownload"
+ type="notify">
+ <tag>fail</tag>
+Terrain file written, starting download...
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="TerrainBaked"
+ type="notify">
+ <tag>fail</tag>
+Terrain baked.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="TenObjectsDisabledPlzRefresh"
+ type="notify">
+ <tag>fail</tag>
+Only the first 10 selected objects have been disabled. Refresh and make additional selections if required.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="UpdateViewerBuyParcel"
+ type="notify">
+ <tag>fail</tag>
+You need to update your viewer to buy this parcel.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="LandBuyAccessBlocked"
+ type="notify">
+ <tag>fail</tag>
+You can't buy this land due to your maturity Rating. You may need to validate your age and/or install the latest Viewer. Please go to the Knowledge Base for details on accessing areas with this maturity Rating.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantBuyParcelNotForSale"
+ type="notify">
+ <tag>fail</tag>
+Unable to buy, this parcel is not for sale.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantBuySalePriceOrLandAreaChanged"
+ type="notify">
+ <tag>fail</tag>
+Unable to buy, the sale price or land area has changed.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantBuyParcelNotAuthorized"
+ type="notify">
+ <tag>fail</tag>
+You are not the authorized buyer for this parcel.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantBuyParcelAwaitingPurchaseAuth"
+ type="notify">
+ <tag>fail</tag>
+You cannot purchase this parcel because it is already awaiting purchase aut
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantBuildOverflowParcel"
+ type="notify">
+ <tag>fail</tag>
+You cannot build objects here because doing so would overflow the parcel.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="SelectedMultipleOwnedLand"
+ type="notify">
+ <tag>fail</tag>
+You selected land with different owners. Please select a smaller area and try again.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantJoinTooFewLeasedParcels"
+ type="notify">
+ <tag>fail</tag>
+Not enough leased parcels in selection to join.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantDivideLandMultipleParcelsSelected"
+ type="notify">
+ <tag>fail</tag>
+Can't divide land.\nThere is more than one parcel selected.\nTry selecting a smaller piece of land.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantDivideLandCantFindParcel"
+ type="notify">
+ <tag>fail</tag>
+Can't divide land.\nCan't find the parcel.\nPlease report with Help -> Reprt Bug...
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantDivideLandWholeParcelSelected"
+ type="notify">
+ <tag>fail</tag>
+Can't divide land. Whole parcel is selected.\nTry selecting a smaller piece of land.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="LandHasBeenDivided"
+ type="notify">
+ <tag>fail</tag>
+Land has been divided.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="PassPurchased"
+ type="notify">
+ <tag>fail</tag>
+You purchased a pass.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="RegionDisallowsClassifieds"
+ type="notify">
+ <tag>fail</tag>
+Region does not allow classified advertisements.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="LandPassExpireSoon"
+ type="notify">
+ <tag>fail</tag>
+Your pass to this land is about to expire.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantSitNoSuitableSurface"
+ type="notify">
+ <tag>fail</tag>
+There is no suitable surface to sit on, try another spot.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantSitNoRoom"
+ type="notify">
+ <tag>fail</tag>
+No room to sit here, try another spot.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ClaimObjectFailedNoPermission"
+ type="notify">
+ <tag>fail</tag>
+Claim object failed because you don't have permission
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ClaimObjectFailedNoMoney"
+ type="notify">
+ <tag>fail</tag>
+Claim object failed because you don't have enough L$.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantDeedGroupLand"
+ type="notify">
+ <tag>fail</tag>
+Cannot deed group-owned land.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="BuyObjectFailedNoMoney"
+ type="notify">
+ <tag>fail</tag>
+Buy object failed because you don't have enough L$.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="BuyInventoryFailedNoMoney"
+ type="notify">
+ <tag>fail</tag>
+Buy inventory failed because you do not have enough L$
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="BuyPassFailedNoMoney"
+ type="notify">
+ <tag>fail</tag>
+You don't have enough L$ to buy a pass to this land.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantBuyPassTryAgain"
+ type="notify">
+ <tag>fail</tag>
+Unable to buy pass right now. Try again later.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantCreateObjectParcelFull"
+ type="notify">
+ <tag>fail</tag>
+Can't create object because \nthe parcel is full.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="FailedPlacingObject"
+ type="notify">
+ <tag>fail</tag>
+Failed to place object at specified location. Please try again.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantCreateLandmarkForEvent"
+ type="notify">
+ <tag>fail</tag>
+Unable to create landmark for event.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="GodBeatsFreeze"
+ type="notify">
+ <tag>fail</tag>
+Your godlike powers break the freeze!
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="SpecialPowersRequestFailedLogged"
+ type="notify">
+ <tag>fail</tag>
+Request for special powers failed. This request has been logged.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ExpireExplanation"
+ type="notify">
+ <tag>fail</tag>
+The system is currently unable to process your request. The request timed out.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="DieExplanation"
+ type="notify">
+ <tag>fail</tag>
+The system is unable to process your request.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="AddPrimitiveFailure"
+ type="notify">
+ <tag>fail</tag>
+Insufficient funds to create primitve.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="RezObjectFailure"
+ type="notify">
+ <tag>fail</tag>
+Insufficient funds to create object.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ResetHomePositionNotLegal"
+ type="notify">
+ <tag>fail</tag>
+Reset Home position since Home wasn't legal.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantInviteRegionFull"
+ type="notify">
+ <tag>fail</tag>
+You cannot currently invite anyone to your location because the region is full. Try again later.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantSetHomeAtRegion"
+ type="notify">
+ <tag>fail</tag>
+This region does not allow you to set your home location here.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ListValidHomeLocations"
+ type="notify">
+ <tag>fail</tag>
+You can only set your 'Home Location' on your land or at a mainland Infohub.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="SetHomePosition"
+ type="notify">
+ <tag>fail</tag>
+Home position set.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantDerezInventoryError"
+ type="notify">
+ <tag>fail</tag>
+Cannot derez object due to inventory fault.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantCreateRequestedInv"
+ type="notify">
+ <tag>fail</tag>
+Cannot create requested inventory.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantCreateRequestedInvFolder"
+ type="notify">
+ <tag>fail</tag>
+Cannot create requested inventory folder.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantCreateInventory"
+ type="notify">
+ <tag>fail</tag>
+Cannot create that inventory.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantCreateLandmark"
+ type="notify">
+ <tag>fail</tag>
+Cannot create landmark.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantCreateOutfit"
+ type="notify">
+ <tag>fail</tag>
+Cannot create outfit right now. Try again in a minute.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="InventoryNotForSale"
+ type="notify">
+ <tag>fail</tag>
+Inventory is not for sale.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantFindInvItem"
+ type="notify">
+ <tag>fail</tag>
+Unable to find inventory item.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantFindObject"
+ type="notify">
+ <tag>fail</tag>
+Unable to find object.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantTransfterMoneyRegionDisabled"
+ type="notify">
+ <tag>fail</tag>
+Money transfers to objects are currently disabled in this region.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantPayNoAgent"
+ type="notify">
+ <tag>fail</tag>
+Could not figure out who to pay.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantDonateToPublicObjects"
+ type="notify">
+ <tag>fail</tag>
+You cannot give L$ to public objects.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="InventoryCreationInWorldObjectFailed"
+ type="notify">
+ <tag>fail</tag>
+Inventory creation on in-world object failed.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="UserBalanceOrLandUsageError"
+ type="notify">
+ <tag>fail</tag>
+An internal error prevented us from properly updating your viewer. The L$ balance or parcel holdings displayed in your viewer may not reflect your actual balance on the servers.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="LargePrimAgentIntersect"
+ type="notify">
+ <tag>fail</tag>
+Cannot create large prims that intersect other players. Please re-try when other players have moved.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="PreferenceChatClearLog"
+ type="alertmodal">
+ This will delete the logs of previous conversations, and any backups of that file.
+ <tag>confirm</tag>
+ <usetemplate
+ ignoretext="Confirm before I delete the log of previous conversations."
+ name="okcancelignore"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="PreferenceChatDeleteTranscripts"
+ type="alertmodal">
+ This will delete the transcripts for all previous conversations. The list of past conversations will not be affected. All files with the suffixes .txt and txt.backup in the folder [FOLDER] will be deleted.
+ <tag>confirm</tag>
+ <usetemplate
+ ignoretext="Confirm before I delete transcripts."
+ name="okcancelignore"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alert.tga"
+ name="PreferenceChatPathChanged"
+ type="alert">
+ Unable to move files. Restored previous path.
+ <usetemplate
+ ignoretext="Unable to move files. Restored previous path."
+ name="okignore"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
name="DefaultObjectPermissions"
type="alert">
There was a problem saving the default permissions due to the following reason: [REASON]. Please try setting the default permissions later.
diff --git a/indra/newview/skins/default/xui/en/outfit_accordion_tab.xml b/indra/newview/skins/default/xui/en/outfit_accordion_tab.xml
index 2a24c74feb..2a24c74feb 100644..100755
--- a/indra/newview/skins/default/xui/en/outfit_accordion_tab.xml
+++ b/indra/newview/skins/default/xui/en/outfit_accordion_tab.xml
diff --git a/indra/newview/skins/default/xui/en/panel_active_object_row.xml b/indra/newview/skins/default/xui/en/panel_active_object_row.xml
index 3e3271b181..3e3271b181 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_active_object_row.xml
+++ b/indra/newview/skins/default/xui/en/panel_active_object_row.xml
diff --git a/indra/newview/skins/default/xui/en/panel_activeim_row.xml b/indra/newview/skins/default/xui/en/panel_activeim_row.xml
deleted file mode 100644
index 9369d1b5cf..0000000000
--- a/indra/newview/skins/default/xui/en/panel_activeim_row.xml
+++ /dev/null
@@ -1,97 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<panel
- name="panel_activeim_row"
- layout="topleft"
- follows="left|right"
- top="0"
- left="0"
- height="35"
- width="318"
- background_opaque="false"
- background_visible="true"
- bg_alpha_color="0.0 0.0 0.0 0.0" >
- <chiclet_im_p2p
- name="p2p_chiclet"
- layout="topleft"
- follows="left"
- top="3"
- left="5"
- height="25"
- width="25"
- visible="false"
- speaker.name="speaker_p2p"
- speaker.width="20"
- speaker.height="25"
- speaker.left="25"
- speaker.top="25"
- speaker.auto_update="true"
- speaker.draw_border="false"
- speaker.visible="false">
- </chiclet_im_p2p>
- <chiclet_im_group
- name="group_chiclet"
- layout="topleft"
- follows="left"
- top="3"
- left="5"
- height="25"
- width="25"
- visible="false"
- speaker.name="speaker_grp"
- speaker.width="20"
- speaker.height="25"
- speaker.left="25"
- speaker.top="25"
- speaker.auto_update="true"
- speaker.draw_border="false"
- speaker.visible="false">
- </chiclet_im_group>
- <chiclet_im_adhoc
- name="adhoc_chiclet"
- layout="topleft"
- follows="left"
- top="3"
- left="5"
- height="25"
- width="25"
- visible="false"
- speaker.name="speaker_hoc"
- speaker.width="20"
- speaker.height="25"
- speaker.left="25"
- speaker.top="25"
- speaker.auto_update="true"
- speaker.draw_border="false"
- speaker.visible="false">
- </chiclet_im_adhoc>
- <text
- translate="false"
- type="string"
- name="contact_name"
- layout="topleft"
- top="10"
- left_pad="10"
- height="14"
- width="250"
- length="1"
- follows="right|left"
- parse_urls="false"
- use_ellipses="true"
- font="SansSerifBold">
- TestString PleaseIgnore
- </text>
- <button
- top="10"
- right="-5"
- width="17"
- height="17"
- layout="topleft"
- follows="right"
- name="hide_btn"
- mouse_opaque="true"
- label=""
- tab_stop="false"
- image_unselected="Toast_CloseBtn"
- image_selected="Toast_CloseBtn"
- />
-</panel> \ No newline at end of file
diff --git a/indra/newview/skins/default/xui/en/panel_adhoc_control_panel.xml b/indra/newview/skins/default/xui/en/panel_adhoc_control_panel.xml
deleted file mode 100644
index d68fa6ca6c..0000000000
--- a/indra/newview/skins/default/xui/en/panel_adhoc_control_panel.xml
+++ /dev/null
@@ -1,95 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<panel
- border="false"
- follows="all"
- height="215"
- name="panel_im_control_panel"
- width="150">
- <layout_stack
- mouse_opaque="false"
- border_size="0"
- clip="false"
- follows="all"
- height="215"
- layout="topleft"
- left="3"
- name="vertical_stack"
- orientation="vertical"
- top="0"
- width="147">
- <layout_panel
- auto_resize="true"
- follows="top|left"
- height="130"
- layout="topleft"
- left="0"
- min_height="0"
- mouse_opaque="false"
- width="147"
- top="0"
- name="speakers_list_panel">
- <avatar_list
- color="DkGray2"
- follows="all"
- height="130"
- ignore_online_status="true"
- layout="topleft"
- name="speakers_list"
- opaque="false"
- show_info_btn="true"
- show_profile_btn="false"
- show_speaking_indicator="false"
- width="147" />
- </layout_panel>
- <layout_panel
- auto_resize="false"
- follows="top|left|right"
- height="25"
- layout="topleft"
- min_height="25"
- width="130"
- name="call_btn_panel"
- visible="false">
- <button
- follows="all"
- height="20"
- label="Call"
- name="call_btn"
- width="130"
- top="0" />
- </layout_panel>
- <layout_panel
- auto_resize="false"
- follows="top|left|right"
- height="25"
- layout="topleft"
- min_height="25"
- width="130"
- name="end_call_btn_panel"
- visible="false">
- <button
- follows="all"
- height="20"
- label="Leave Call"
- name="end_call_btn"
- top="0"/>
- </layout_panel>
- <layout_panel
- auto_resize="false"
- follows="top|left|right"
- height="25"
- layout="topleft"
- min_height="25"
- width="130"
- name="voice_ctrls_btn_panel"
- visible="false">
- <button
- follows="all"
- height="20"
- label="Voice Controls"
- name="voice_ctrls_btn"
- top="0"
- use_ellipses="true" />
- </layout_panel>
- </layout_stack>
-</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml b/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml
index b7c58eb6ab..aa1b929412 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml
+++ b/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml
@@ -129,6 +129,7 @@
left_pad="3"
right="-53"
name="info_btn"
+ tool_tip="More info"
tab_stop="false"
top_delta="0"
width="16" />
diff --git a/indra/newview/skins/default/xui/en/panel_avatar_tag.xml b/indra/newview/skins/default/xui/en/panel_avatar_tag.xml
index b779b08a63..b779b08a63 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_avatar_tag.xml
+++ b/indra/newview/skins/default/xui/en/panel_avatar_tag.xml
diff --git a/indra/newview/skins/default/xui/en/panel_block_list_sidetray.xml b/indra/newview/skins/default/xui/en/panel_block_list_sidetray.xml
index 7c67fd7f83..53d0252215 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_block_list_sidetray.xml
+++ b/indra/newview/skins/default/xui/en/panel_block_list_sidetray.xml
@@ -4,88 +4,99 @@
follows="left|top|right|bottom"
height="305"
layout="topleft"
+ left="0"
name="block_list_panel"
help_topic="blocked_list"
min_height="350"
min_width="240"
- width="280">
- <button
- follows="top|left"
- height="24"
- image_hover_unselected="BackButton_Over"
- image_pressed="BackButton_Press"
- image_unselected="BackButton_Off"
- layout="topleft"
- name="back"
- left="4"
- tab_stop="false"
- top="1"
- width="30"/>
- <text
- follows="top|left|right"
- font="SansSerifLargeBold"
- height="20"
- layout="topleft"
- left_pad="10"
- name="title_text"
- text_color="White"
- top="5"
- width="250">
- Block List
- </text>
- <scroll_list
+ width="323">
+ <panel
+ follows="left|top|right"
+ height="27"
+ label="bottom_panel"
+ layout="topleft"
+ left="0"
+ name="blocked_buttons_panel"
+ right="-1"
+ top="0">
+ <filter_editor
+ follows="left|top|right"
+ height="23"
+ layout="topleft"
+ left="6"
+ label="Filter"
+ max_length_chars="300"
+ name="blocked_filter_input"
+ text_color="Black"
+ text_pad_left="10"
+ top="4"
+ width="177" />
+ <menu_button
+ follows="right"
+ height="25"
+ image_hover_unselected="Toolbar_Middle_Over"
+ image_overlay="OptionsMenu_Off"
+ image_selected="Toolbar_Middle_Selected"
+ image_unselected="Toolbar_Middle_Off"
+ layout="topleft"
+ left_pad="8"
+ menu_filename="menu_people_blocked_gear.xml"
+ menu_position="bottomleft"
+ name="blocked_gear_btn"
+ tool_tip="Actions on selected person or object"
+ top="3"
+ width="31" />
+ <menu_button
+ follows="right"
+ height="25"
+ image_hover_unselected="Toolbar_Middle_Over"
+ image_overlay="Conv_toolbar_sort"
+ image_selected="Toolbar_Middle_Selected"
+ image_unselected="Toolbar_Middle_Off"
+ layout="topleft"
+ left_pad="2"
+ menu_filename="menu_people_blocked_view.xml"
+ menu_position="bottomleft"
+ name="view_btn"
+ tool_tip="Sort options"
+ top_delta="0"
+ width="31" />
+ <menu_button
+ follows="right"
+ height="25"
+ image_hover_unselected="Toolbar_Middle_Over"
+ image_overlay="AddItem_Off"
+ image_selected="Toolbar_Middle_Selected"
+ image_unselected="Toolbar_Middle_Off"
+ layout="topleft"
+ left_pad="2"
+ menu_filename="menu_people_blocked_plus.xml"
+ menu_position="bottomleft"
+ name="plus_btn"
+ tool_tip="Pick a Resident or an object to block"
+ top_delta="0"
+ width="31"/>
+ <button
+ follows="right"
+ height="25"
+ image_hover_unselected="Toolbar_Middle_Over"
+ image_overlay="TrashItem_Off"
+ image_selected="Toolbar_Middle_Selected"
+ image_unselected="Toolbar_Middle_Off"
+ left_pad="2"
+ layout="topleft"
+ name="unblock_btn"
+ tool_tip="Remove Resident or object from blocked list"
+ top_delta="0"
+ width="31"/>
+ </panel>
+ <block_list
follows="all"
- height="190"
+ height="273"
layout="topleft"
- left="5"
+ left="3"
name="blocked"
tool_tip="List of currently blocked Residents"
- top="30"
- width="270">
- <scroll_list.columns
- name="item_name" />
- <scroll_list.columns
- name="item_type"
- width="96" />
- </scroll_list>
- <button
- follows="left|bottom"
- height="23"
- label="Block person"
- layout="topleft"
- left_delta="0"
- name="Block resident..."
- tool_tip="Pick a Resident to block"
- top_pad="4"
- width="210">
- <button.commit_callback
- function="Block.ClickPick" />
- </button>
- <button
- follows="left|bottom"
- height="23"
- label="Block object by name"
- layout="topleft"
- left_delta="0"
- name="Block object by name..."
- tool_tip="Pick an object to block by name"
- top_pad="4"
- width="210" >
- <button.commit_callback
- function="Block.ClickBlockByName" />
- </button>
- <button
- enabled="false"
- follows="left|bottom"
- height="23"
- label="Unblock"
- layout="topleft"
- left_delta="0"
- name="Unblock"
- tool_tip="Remove Resident or object from blocked list"
- top_pad="4"
- width="210" >
- <button.commit_callback
- function="Block.ClickRemove" />
- </button>
+ top="31"
+ right="-1"/>
</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_blocked_list_item.xml b/indra/newview/skins/default/xui/en/panel_blocked_list_item.xml
new file mode 100755
index 0000000000..752321b949
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_blocked_list_item.xml
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ follows="top|right|left"
+ height="23"
+ layout="topleft"
+ left="0"
+ name="blocked_list_item"
+ top="0"
+ width="380">
+ <icon
+ height="24"
+ follows="top|right|left"
+ image_name="ListItem_Select"
+ layout="topleft"
+ left="0"
+ name="selected_icon"
+ top="0"
+ visible="false"
+ width="380" />
+ <icon
+ follows="top|right|left"
+ height="24"
+ image_name="ListItem_Over"
+ layout="topleft"
+ left="0"
+ name="hovered_icon"
+ top="0"
+ visible="false"
+ width="380" />
+ <avatar_icon
+ default_icon_name="Generic_Person"
+ follows="top|left"
+ height="20"
+ layout="topleft"
+ left="5"
+ mouse_opaque="true"
+ top="2"
+ visible="false"
+ width="20" />
+ <group_icon
+ default_icon_name="Generic_Group"
+ follows="top|left"
+ height="20"
+ layout="topleft"
+ left="5"
+ mouse_opaque="true"
+ top="2"
+ visible="false"
+ width="20" />
+ <icon
+ follows="top|left"
+ height="16"
+ image_name="Inv_Object"
+ layout="topleft"
+ left="7"
+ name="object_icon"
+ top="4"
+ visible="false"
+ width="16" />
+ <text
+ follows="left|right"
+ font="SansSerifSmall"
+ height="15"
+ layout="topleft"
+ left_pad="5"
+ name="item_name"
+ parse_urls="false"
+ top="6"
+ use_ellipses="true"
+ width="180" />
+</panel> \ No newline at end of file
diff --git a/indra/newview/skins/default/xui/en/panel_body_parts_list_item.xml b/indra/newview/skins/default/xui/en/panel_body_parts_list_item.xml
index 216a265164..216a265164 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_body_parts_list_item.xml
+++ b/indra/newview/skins/default/xui/en/panel_body_parts_list_item.xml
diff --git a/indra/newview/skins/default/xui/en/panel_bodyparts_list_button_bar.xml b/indra/newview/skins/default/xui/en/panel_bodyparts_list_button_bar.xml
index dc123f13f4..dc123f13f4 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_bodyparts_list_button_bar.xml
+++ b/indra/newview/skins/default/xui/en/panel_bodyparts_list_button_bar.xml
diff --git a/indra/newview/skins/default/xui/en/panel_bottomtray_lite.xml b/indra/newview/skins/default/xui/en/panel_bottomtray_lite.xml
index f4722b05d6..27a27473d8 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_bottomtray_lite.xml
+++ b/indra/newview/skins/default/xui/en/panel_bottomtray_lite.xml
@@ -46,7 +46,7 @@
follows="left|right"
top="4"
width="310"
- name="chat_bar"
+ name="nearby_chat"
mouse_opaque="false"/>
</layout_panel>
<layout_panel
diff --git a/indra/newview/skins/default/xui/en/panel_chat_header.xml b/indra/newview/skins/default/xui/en/panel_chat_header.xml
index 5c5c718bdf..5c5c718bdf 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_chat_header.xml
+++ b/indra/newview/skins/default/xui/en/panel_chat_header.xml
diff --git a/indra/newview/skins/default/xui/en/panel_chat_item.xml b/indra/newview/skins/default/xui/en/panel_chat_item.xml
index 1ef99649e6..1ef99649e6 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_chat_item.xml
+++ b/indra/newview/skins/default/xui/en/panel_chat_item.xml
diff --git a/indra/newview/skins/default/xui/en/panel_chat_separator.xml b/indra/newview/skins/default/xui/en/panel_chat_separator.xml
index 357dbc07cc..357dbc07cc 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_chat_separator.xml
+++ b/indra/newview/skins/default/xui/en/panel_chat_separator.xml
diff --git a/indra/newview/skins/default/xui/en/panel_chiclet_bar.xml b/indra/newview/skins/default/xui/en/panel_chiclet_bar.xml
index ff0146490b..fc321fdd23 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_chiclet_bar.xml
+++ b/indra/newview/skins/default/xui/en/panel_chiclet_bar.xml
@@ -87,54 +87,6 @@
layout="topleft"
min_height="28"
min_width="37"
- name="im_well_panel"
- top="0"
- width="37">
- <chiclet_im_well
- follows="right"
- height="28"
- layout="topleft"
- left="0"
- max_displayed_count="99"
- name="im_well"
- top="0"
- width="35">
- <!--
-Emulate 4 states of button by background images, see details in EXT-3147. The same should be for notification_well button
-xml attribute Description
-image_unselected "Unlit" - there are no new messages
-image_selected "Unlit" + "Selected" - there are no new messages and the Well is open
-image_pressed "Lit" - there are new messages
-image_pressed_selected "Lit" + "Selected" - there are new messages and the Well is open
- -->
- <button
- auto_resize="false"
- follows="right"
- halign="center"
- height="23"
- image_overlay="Unread_IM"
- image_overlay_alignment="center"
- image_pressed="WellButton_Lit"
- image_pressed_selected="WellButton_Lit_Selected"
- image_selected="PushButton_Press"
- label_color="Black"
- left="0"
- name="Unread IM messages"
- tool_tip="Conversations"
- width="34">
- <init_callback
- function="Button.SetDockableFloaterToggle"
- parameter="im_well_window" />
- </button>
- </chiclet_im_well>
- </layout_panel>
- <layout_panel
- auto_resize="false"
- follows="right"
- height="28"
- layout="topleft"
- min_height="28"
- min_width="37"
name="notification_well_panel"
top="0"
width="37">
diff --git a/indra/newview/skins/default/xui/en/panel_classified_info.xml b/indra/newview/skins/default/xui/en/panel_classified_info.xml
index d4a2745d1d..d4a2745d1d 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_classified_info.xml
+++ b/indra/newview/skins/default/xui/en/panel_classified_info.xml
diff --git a/indra/newview/skins/default/xui/en/panel_classifieds_list_item.xml b/indra/newview/skins/default/xui/en/panel_classifieds_list_item.xml
index 27c653bc35..27c653bc35 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_classifieds_list_item.xml
+++ b/indra/newview/skins/default/xui/en/panel_classifieds_list_item.xml
diff --git a/indra/newview/skins/default/xui/en/panel_clothing_list_button_bar.xml b/indra/newview/skins/default/xui/en/panel_clothing_list_button_bar.xml
index 5b3f0b17a9..5b3f0b17a9 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_clothing_list_button_bar.xml
+++ b/indra/newview/skins/default/xui/en/panel_clothing_list_button_bar.xml
diff --git a/indra/newview/skins/default/xui/en/panel_clothing_list_item.xml b/indra/newview/skins/default/xui/en/panel_clothing_list_item.xml
index cc0541e65c..cc0541e65c 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_clothing_list_item.xml
+++ b/indra/newview/skins/default/xui/en/panel_clothing_list_item.xml
diff --git a/indra/newview/skins/default/xui/en/panel_cof_wearables.xml b/indra/newview/skins/default/xui/en/panel_cof_wearables.xml
index aa8e3d07a6..aa8e3d07a6 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_cof_wearables.xml
+++ b/indra/newview/skins/default/xui/en/panel_cof_wearables.xml
diff --git a/indra/newview/skins/default/xui/en/panel_conversation_list_item.xml b/indra/newview/skins/default/xui/en/panel_conversation_list_item.xml
new file mode 100755
index 0000000000..4372cf69bf
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_conversation_list_item.xml
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ follows="left|top|right"
+ height="24"
+ layout="topleft"
+ name="conversation_list_item"
+ mouse_opaque="false"
+ width="120">
+ <avatar_icon
+ follows="top|left"
+ height="20"
+ default_icon_name="Generic_Person"
+ layout="topleft"
+ left="9"
+ top="2"
+ visible="false"
+ width="20" />
+ <group_icon
+ follows="top|left"
+ height="20"
+ default_icon_name="Generic_Group"
+ layout="topleft"
+ left="9"
+ top="2"
+ visible="false"
+ width="20" />
+ <icon
+ follows="top|left"
+ height="20"
+ image_name="Nearby_chat_icon"
+ layout="topleft"
+ left="10"
+ name="nearby_chat_icon"
+ top="3"
+ visible="false"
+ width="20"/>
+ <layout_stack
+ animate="false"
+ follows="all"
+ height="24"
+ layout="topleft"
+ left="30"
+ mouse_opaque="false"
+ name="conversation_item_stack"
+ orientation="horizontal"
+ top="0"
+ width="90">
+ <layout_panel
+ auto_resize="false"
+ user_resize="false"
+ height="24"
+ mouse_opaque="false"
+ name="call_icon_panel"
+ visible="false"
+ width="20">
+ <icon
+ height="18"
+ follows="top|right|left"
+ image_name="Conv_toolbar_open_call"
+ layout="topleft"
+ left="0"
+ name="selected_icon"
+ top="3"
+ width="18" />
+ </layout_panel>
+ <layout_panel
+ auto_resize="true"
+ user_resize="false"
+ height="24"
+ mouse_opaque="false"
+ name="conversation_title_panel"
+ width="70">
+ <text
+ follows="left|top|right"
+ font="SansSerifSmall"
+ height="15"
+ layout="topleft"
+ left="5"
+ name="conversation_title"
+ parse_urls="false"
+ top="6"
+ use_ellipses="true"
+ value="(loading)"
+ width="35" />
+ <output_monitor
+ auto_update="true"
+ follows="top|right"
+ draw_border="false"
+ height="16"
+ layout="topleft"
+ left_pad="5"
+ mouse_opaque="true"
+ name="speaking_indicator"
+ visible="false"
+ width="20" />
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_conversation_log_list_item.xml b/indra/newview/skins/default/xui/en/panel_conversation_log_list_item.xml
new file mode 100755
index 0000000000..78d4c174d2
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_conversation_log_list_item.xml
@@ -0,0 +1,107 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ follows="top|right|left"
+ height="23"
+ layout="topleft"
+ left="0"
+ name="conversation_log_list_item"
+ top="0"
+ width="380">
+ <icon
+ height="24"
+ follows="top|right|left"
+ image_name="ListItem_Select"
+ layout="topleft"
+ left="0"
+ name="selected_icon"
+ top="0"
+ visible="false"
+ width="380" />
+ <icon
+ follows="top|right|left"
+ height="24"
+ image_name="ListItem_Over"
+ layout="topleft"
+ left="0"
+ name="hovered_icon"
+ top="0"
+ visible="false"
+ width="380" />
+ <icon
+ follows="top|left"
+ height="20"
+ layout="topleft"
+ left="5"
+ image_name="Conv_toolbar_open_call"
+ mouse_opaque="true"
+ name="voice_session_icon"
+ tool_tip="Included a voice conversation"
+ top="2"
+ visible="false"
+ width="20" />
+ <icon
+ follows="top|left"
+ height="20"
+ layout="topleft"
+ left="5"
+ image_name="Conv_log_inbox"
+ mouse_opaque="false"
+ name="unread_ims_icon"
+ tool_tip="Messages arrived while you were logged out"
+ top="2"
+ visible="false"
+ width="20" />
+ <avatar_icon
+ default_icon_name="Generic_Person"
+ follows="top|left"
+ height="20"
+ layout="topleft"
+ left_pad="5"
+ mouse_opaque="true"
+ top="2"
+ visible="false"
+ width="20" />
+ <group_icon
+ default_icon_name="Generic_Group"
+ follows="top|left"
+ height="20"
+ layout="topleft"
+ mouse_opaque="true"
+ top="2"
+ visible="false"
+ width="20" />
+ <text
+ follows="left|right"
+ font="SansSerifSmall"
+ height="15"
+ layout="topleft"
+ left_pad="5"
+ name="conversation_name"
+ parse_urls="false"
+ top="6"
+ use_ellipses="true"
+ width="180" />
+ <text
+ follows="right"
+ font="SansSerifSmall"
+ height="15"
+ layout="topleft"
+ left_pad="5"
+ name="date_time"
+ parse_urls="false"
+ top="6"
+ use_ellipses="true"
+ width="110"/>
+ <button
+ name="delete_btn"
+ tool_tip="Remove this entry"
+ layout="topleft"
+ follows="top|right"
+ image_unselected="Conv_toolbar_close"
+ image_selected="Conv_toolbar_close"
+ top="5"
+ left_pad="0"
+ height="14"
+ width="14"
+ tab_stop="false"/>
+</panel> \ No newline at end of file
diff --git a/indra/newview/skins/default/xui/en/panel_deletable_wearable_list_item.xml b/indra/newview/skins/default/xui/en/panel_deletable_wearable_list_item.xml
index de2ff0afc9..de2ff0afc9 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_deletable_wearable_list_item.xml
+++ b/indra/newview/skins/default/xui/en/panel_deletable_wearable_list_item.xml
diff --git a/indra/newview/skins/default/xui/en/panel_dummy_clothing_list_item.xml b/indra/newview/skins/default/xui/en/panel_dummy_clothing_list_item.xml
index 4b05ab27e4..4b05ab27e4 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_dummy_clothing_list_item.xml
+++ b/indra/newview/skins/default/xui/en/panel_dummy_clothing_list_item.xml
diff --git a/indra/newview/skins/default/xui/en/panel_edit_alpha.xml b/indra/newview/skins/default/xui/en/panel_edit_alpha.xml
index 813aa5d7a9..813aa5d7a9 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_edit_alpha.xml
+++ b/indra/newview/skins/default/xui/en/panel_edit_alpha.xml
diff --git a/indra/newview/skins/default/xui/en/panel_edit_classified.xml b/indra/newview/skins/default/xui/en/panel_edit_classified.xml
index 3509eaa285..3509eaa285 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_edit_classified.xml
+++ b/indra/newview/skins/default/xui/en/panel_edit_classified.xml
diff --git a/indra/newview/skins/default/xui/en/panel_edit_eyes.xml b/indra/newview/skins/default/xui/en/panel_edit_eyes.xml
index f173a2f3cb..f173a2f3cb 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_edit_eyes.xml
+++ b/indra/newview/skins/default/xui/en/panel_edit_eyes.xml
diff --git a/indra/newview/skins/default/xui/en/panel_edit_gloves.xml b/indra/newview/skins/default/xui/en/panel_edit_gloves.xml
index 8c0c543d71..8c0c543d71 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_edit_gloves.xml
+++ b/indra/newview/skins/default/xui/en/panel_edit_gloves.xml
diff --git a/indra/newview/skins/default/xui/en/panel_edit_hair.xml b/indra/newview/skins/default/xui/en/panel_edit_hair.xml
index 6bb5d2fa9b..6bb5d2fa9b 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_edit_hair.xml
+++ b/indra/newview/skins/default/xui/en/panel_edit_hair.xml
diff --git a/indra/newview/skins/default/xui/en/panel_edit_jacket.xml b/indra/newview/skins/default/xui/en/panel_edit_jacket.xml
index 0f8c37c691..0f8c37c691 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_edit_jacket.xml
+++ b/indra/newview/skins/default/xui/en/panel_edit_jacket.xml
diff --git a/indra/newview/skins/default/xui/en/panel_edit_pants.xml b/indra/newview/skins/default/xui/en/panel_edit_pants.xml
index dd749a9259..dd749a9259 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_edit_pants.xml
+++ b/indra/newview/skins/default/xui/en/panel_edit_pants.xml
diff --git a/indra/newview/skins/default/xui/en/panel_edit_physics.xml b/indra/newview/skins/default/xui/en/panel_edit_physics.xml
index 0092ceb0dd..0092ceb0dd 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_edit_physics.xml
+++ b/indra/newview/skins/default/xui/en/panel_edit_physics.xml
diff --git a/indra/newview/skins/default/xui/en/panel_edit_pick.xml b/indra/newview/skins/default/xui/en/panel_edit_pick.xml
index 0faa1598b1..553c112e6f 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_edit_pick.xml
+++ b/indra/newview/skins/default/xui/en/panel_edit_pick.xml
@@ -134,6 +134,7 @@
top_pad="2"
max_length="1023"
name="pick_desc"
+ spellcheck="true"
text_color="black"
word_wrap="true" />
<text
diff --git a/indra/newview/skins/default/xui/en/panel_edit_profile.xml b/indra/newview/skins/default/xui/en/panel_edit_profile.xml
index 2c7c8133d1..2c7c8133d1 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_edit_profile.xml
+++ b/indra/newview/skins/default/xui/en/panel_edit_profile.xml
diff --git a/indra/newview/skins/default/xui/en/panel_edit_shape.xml b/indra/newview/skins/default/xui/en/panel_edit_shape.xml
index d295f5fe4a..d295f5fe4a 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_edit_shape.xml
+++ b/indra/newview/skins/default/xui/en/panel_edit_shape.xml
diff --git a/indra/newview/skins/default/xui/en/panel_edit_shirt.xml b/indra/newview/skins/default/xui/en/panel_edit_shirt.xml
index 5424b805e1..5424b805e1 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_edit_shirt.xml
+++ b/indra/newview/skins/default/xui/en/panel_edit_shirt.xml
diff --git a/indra/newview/skins/default/xui/en/panel_edit_shoes.xml b/indra/newview/skins/default/xui/en/panel_edit_shoes.xml
index 859e7454a4..859e7454a4 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_edit_shoes.xml
+++ b/indra/newview/skins/default/xui/en/panel_edit_shoes.xml
diff --git a/indra/newview/skins/default/xui/en/panel_edit_skin.xml b/indra/newview/skins/default/xui/en/panel_edit_skin.xml
index b61f65a3d1..b61f65a3d1 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_edit_skin.xml
+++ b/indra/newview/skins/default/xui/en/panel_edit_skin.xml
diff --git a/indra/newview/skins/default/xui/en/panel_edit_skirt.xml b/indra/newview/skins/default/xui/en/panel_edit_skirt.xml
index 76d66cc5dc..76d66cc5dc 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_edit_skirt.xml
+++ b/indra/newview/skins/default/xui/en/panel_edit_skirt.xml
diff --git a/indra/newview/skins/default/xui/en/panel_edit_socks.xml b/indra/newview/skins/default/xui/en/panel_edit_socks.xml
index 5f978174b3..5f978174b3 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_edit_socks.xml
+++ b/indra/newview/skins/default/xui/en/panel_edit_socks.xml
diff --git a/indra/newview/skins/default/xui/en/panel_edit_tattoo.xml b/indra/newview/skins/default/xui/en/panel_edit_tattoo.xml
index 97f1a1a658..97f1a1a658 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_edit_tattoo.xml
+++ b/indra/newview/skins/default/xui/en/panel_edit_tattoo.xml
diff --git a/indra/newview/skins/default/xui/en/panel_edit_underpants.xml b/indra/newview/skins/default/xui/en/panel_edit_underpants.xml
index 16f28377fb..16f28377fb 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_edit_underpants.xml
+++ b/indra/newview/skins/default/xui/en/panel_edit_underpants.xml
diff --git a/indra/newview/skins/default/xui/en/panel_edit_undershirt.xml b/indra/newview/skins/default/xui/en/panel_edit_undershirt.xml
index 059485cfb4..059485cfb4 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_edit_undershirt.xml
+++ b/indra/newview/skins/default/xui/en/panel_edit_undershirt.xml
diff --git a/indra/newview/skins/default/xui/en/panel_edit_wearable.xml b/indra/newview/skins/default/xui/en/panel_edit_wearable.xml
index f34b913218..f34b913218 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_edit_wearable.xml
+++ b/indra/newview/skins/default/xui/en/panel_edit_wearable.xml
diff --git a/indra/newview/skins/default/xui/en/panel_generic_tip.xml b/indra/newview/skins/default/xui/en/panel_generic_tip.xml
index eea92895f5..eea92895f5 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_generic_tip.xml
+++ b/indra/newview/skins/default/xui/en/panel_generic_tip.xml
diff --git a/indra/newview/skins/default/xui/en/panel_group_control_panel.xml b/indra/newview/skins/default/xui/en/panel_group_control_panel.xml
deleted file mode 100644
index ad10e53a4e..0000000000
--- a/indra/newview/skins/default/xui/en/panel_group_control_panel.xml
+++ /dev/null
@@ -1,109 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<panel
- border="false"
- follows="all"
- height="238"
- name="panel_im_control_panel"
- width="150">
- <layout_stack
- mouse_opaque="false"
- border_size="0"
- clip="false"
- follows="all"
- height="238"
- layout="topleft"
- left="5"
- name="vertical_stack"
- orientation="vertical"
- top="0"
- width="145">
- <layout_panel
- auto_resize="true"
- follows="top|left"
- height="100"
- layout="topleft"
- min_height="0"
- mouse_opaque="false"
- width="145"
- top="0"
- name="speakers_list_panel">
- <avatar_list
- color="DkGray2"
- follows="all"
- height="100"
- ignore_online_status="true"
- layout="topleft"
- name="speakers_list"
- opaque="false"
- show_info_btn="true"
- show_profile_btn="false"
- show_speaking_indicator="false"
- width="145" />
- </layout_panel>
- <layout_panel
- auto_resize="false"
- follows="top|left|right"
- height="28"
- layout="topleft"
- min_height="28"
- width="130"
- name="group_info_btn_panel">
- <button
- follows="left|right|bottom"
- height="23"
- label="Group Profile"
- name="group_info_btn"
- use_ellipses="true"
- top="5"
- width="130" />
- </layout_panel>
- <layout_panel
- auto_resize="false"
- follows="top|left|right"
- height="28"
- layout="topleft"
- min_height="28"
- width="130"
- name="call_btn_panel">
- <button
- follows="all"
- height="23"
- label="Call Group"
- name="call_btn"
- use_ellipses="true"
- width="130" />
- </layout_panel>
- <layout_panel
- auto_resize="false"
- follows="top|left|right"
- height="28"
- layout="topleft"
- min_height="28"
- width="130"
- name="end_call_btn_panel"
- visible="false">
- <button
- follows="all"
- height="23"
- label="Leave Call"
- name="end_call_btn"
- use_ellipses="true" />
- </layout_panel>
- <layout_panel
- auto_resize="false"
- follows="top|left|right"
- height="28"
- layout="topleft"
- min_height="28"
- width="130"
- name="voice_ctrls_btn_panel"
- visible="false">
- <button
- follows="all"
- height="23"
- label="Open Voice Controls"
- name="voice_ctrls_btn"
- use_ellipses="true" />
- </layout_panel>
- </layout_stack>
-</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_group_general.xml b/indra/newview/skins/default/xui/en/panel_group_general.xml
index 38b680ba86..38b680ba86 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_group_general.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_general.xml
diff --git a/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml b/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml
index 206496cc0e..206496cc0e 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml
diff --git a/indra/newview/skins/default/xui/en/panel_group_invite.xml b/indra/newview/skins/default/xui/en/panel_group_invite.xml
index cd834b61ce..124c0596c3 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_group_invite.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_invite.xml
@@ -19,6 +19,10 @@
name="already_in_group">
Some Residents you chose are already in the group, and so were not sent an invitation.
</panel.string>
+ <panel.string
+ name="invite_selection_too_large">
+ Group Invitations not sent: too many Residents selected. Group Invitations are limited to 100 per request.
+ </panel.string>
<text
type="string"
length="1"
diff --git a/indra/newview/skins/default/xui/en/panel_group_land_money.xml b/indra/newview/skins/default/xui/en/panel_group_land_money.xml
index d4da55e32e..d4da55e32e 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_group_land_money.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_land_money.xml
diff --git a/indra/newview/skins/default/xui/en/panel_group_list_item.xml b/indra/newview/skins/default/xui/en/panel_group_list_item.xml
index 12735026fa..cfe3aeb7c9 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_group_list_item.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_list_item.xml
@@ -56,6 +56,7 @@
left_pad="3"
right="-31"
name="info_btn"
+ tool_tip="More info"
tab_stop="false"
top_delta="-2"
width="16" />
diff --git a/indra/newview/skins/default/xui/en/panel_group_notices.xml b/indra/newview/skins/default/xui/en/panel_group_notices.xml
index 607e1bb213..c8ce5cdebf 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_group_notices.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_notices.xml
@@ -141,6 +141,7 @@ Maximum 200 per group daily
max_length_bytes="63"
name="create_subject"
prevalidate_callback="ascii"
+ spellcheck="true"
width="218" />
<text
follows="left|top"
@@ -161,6 +162,7 @@ Maximum 200 per group daily
left_pad="3"
max_length="511"
name="create_message"
+ spellcheck="true"
top_delta="0"
width="218"
word_wrap="true" />
@@ -200,14 +202,14 @@ Maximum 200 per group daily
Drag and drop item here to attach it:
</text>
<icon
- height="72"
+ height="48"
image_name="DropTarget"
layout="topleft"
left_pad="10"
mouse_opaque="true"
name="drop_icon"
top_delta="-10"
- width="72" />
+ width="110" />
<button
follows="left|top"
layout="topleft"
@@ -309,6 +311,7 @@ Maximum 200 per group daily
left_pad="3"
max_length_bytes="63"
name="view_subject"
+ spellcheck="true"
top_delta="-1"
visible="false"
width="200" />
@@ -333,6 +336,7 @@ Maximum 200 per group daily
right="-1"
max_length="511"
name="view_message"
+ spellcheck="true"
top_delta="-40"
width="313"
word_wrap="true" />
diff --git a/indra/newview/skins/default/xui/en/panel_group_notify.xml b/indra/newview/skins/default/xui/en/panel_group_notify.xml
index cded4cf31a..cded4cf31a 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_group_notify.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_notify.xml
diff --git a/indra/newview/skins/default/xui/en/panel_group_roles.xml b/indra/newview/skins/default/xui/en/panel_group_roles.xml
index eea2606125..df91ad8b5e 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_group_roles.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_roles.xml
@@ -254,7 +254,7 @@ things in this group. There&apos;s a broad variety of Abilities.
column_padding="0"
draw_stripes="true"
height="200"
- follows="left|top"
+ follows="left|top|right"
layout="topleft"
left="0"
right="-1"
diff --git a/indra/newview/skins/default/xui/en/panel_hint.xml b/indra/newview/skins/default/xui/en/panel_hint.xml
index f7434f0330..f7434f0330 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_hint.xml
+++ b/indra/newview/skins/default/xui/en/panel_hint.xml
diff --git a/indra/newview/skins/default/xui/en/panel_hint_image.xml b/indra/newview/skins/default/xui/en/panel_hint_image.xml
index df05d50dc5..df05d50dc5 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_hint_image.xml
+++ b/indra/newview/skins/default/xui/en/panel_hint_image.xml
diff --git a/indra/newview/skins/default/xui/en/panel_hud.xml b/indra/newview/skins/default/xui/en/panel_hud.xml
index 3e9614a9b7..3e9614a9b7 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_hud.xml
+++ b/indra/newview/skins/default/xui/en/panel_hud.xml
diff --git a/indra/newview/skins/default/xui/en/panel_im_control_panel.xml b/indra/newview/skins/default/xui/en/panel_im_control_panel.xml
deleted file mode 100644
index 8fcd6ccbaf..0000000000
--- a/indra/newview/skins/default/xui/en/panel_im_control_panel.xml
+++ /dev/null
@@ -1,166 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<panel
- border="false"
- height="300"
- name="panel_im_control_panel"
- width="150">
- <avatar_icon
- follows="left|top"
- height="105"
- left_delta="20"
- name="avatar_icon"
- top="-5"
- width="114"/>
- <layout_stack
- mouse_opaque="false"
- border_size="0"
- clip="false"
- follows="all"
- height="183"
- layout="topleft"
- left="5"
- name="button_stack"
- orientation="vertical"
- top_pad="5"
- width="145">
- <layout_panel
- auto_resize="false"
- follows="top|left|right"
- height="20"
- layout="topleft"
- left="2"
- min_height="20"
- width="140"
- name="view_profile_btn_panel"
- top="0" >
- <button
- follows="left|top|right"
- height="23"
- label="Profile"
- name="view_profile_btn"
- top="0"
- width="140" />
- </layout_panel>
- <layout_panel
- auto_resize="false"
- follows="top|left|right"
- height="25"
- layout="topleft"
- min_height="25"
- width="140"
- name="add_friend_btn_panel">
- <button
- follows="left|top|right"
- height="23"
- label="Add Friend"
- name="add_friend_btn"
- top="5"
- width="140" />
- </layout_panel>
- <layout_panel
- auto_resize="false"
- follows="top|left|right"
- height="25"
- layout="topleft"
- min_height="25"
- width="140"
- name="teleport_btn_panel">
- <button
- auto_resize="false"
- follows="left|top|right"
- height="23"
- label="Teleport"
- name="teleport_btn"
- tool_tip = "Offer to teleport this person"
- width="140" />
- </layout_panel>
- <layout_panel
- auto_resize="false"
- follows="top|left|right"
- height="25"
- layout="topleft"
- min_height="25"
- width="140"
- name="share_btn_panel">
- <button
- auto_resize="true"
- follows="left|top|right"
- height="23"
- label="Share"
- name="share_btn"
- width="140" />
- </layout_panel>
- <layout_panel
- auto_resize="false"
- follows="top|left|right"
- height="25"
- layout="topleft"
- min_height="25"
- width="140"
- name="pay_btn_panel">
- <button
- auto_resize="true"
- follows="left|top|right"
- height="23"
- label="Pay"
- name="pay_btn"
- width="140" />
- </layout_panel>
- <layout_panel
- auto_resize="false"
- follows="top|left|right"
- height="25"
- layout="topleft"
- min_height="25"
- width="140"
- name="call_btn_panel">
- <button
- follows="left|top|right"
- height="23"
- label="Call"
- name="call_btn"
- width="140" />
- </layout_panel>
- <layout_panel
- auto_resize="false"
- follows="top|left|right"
- height="25"
- layout="topleft"
- min_height="25"
- width="140"
- name="end_call_btn_panel"
- visible="false">
- <button
- follows="left|top|right"
- height="23"
- label="End Call"
- name="end_call_btn"
- width="140" />
- </layout_panel>
- <layout_panel
- auto_resize="false"
- follows="top|left|right"
- height="25"
- layout="topleft"
- min_height="25"
- width="140"
- name="voice_ctrls_btn_panel"
- visible="false">
- <button
- follows="left|top|right"
- height="23"
- label="Voice Controls"
- name="voice_ctrls_btn"
- width="140" />
- </layout_panel>
- <layout_panel
- mouse_opaque="false"
- auto_resize="true"
- follows="top|left"
- height="0"
- layout="topleft"
- min_height="0"
- width="140"
- name="spacer"/>
- </layout_stack>
-</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_inbox_inventory.xml b/indra/newview/skins/default/xui/en/panel_inbox_inventory.xml
index 413e22e444..433a3181cd 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_inbox_inventory.xml
+++ b/indra/newview/skins/default/xui/en/panel_inbox_inventory.xml
@@ -2,7 +2,7 @@
<inbox_inventory_panel
accepts_drag_and_drop="false"
name="inventory_inbox"
- start_folder="Received Items"
+ start_folder.type="inbox"
follows="all" layout="topleft"
top="0" left="0" height="165" width="308"
top_pad="0"
diff --git a/indra/newview/skins/default/xui/en/panel_instant_message.xml b/indra/newview/skins/default/xui/en/panel_instant_message.xml
index 2e5d650902..2e5d650902 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_instant_message.xml
+++ b/indra/newview/skins/default/xui/en/panel_instant_message.xml
diff --git a/indra/newview/skins/default/xui/en/panel_inventory_item.xml b/indra/newview/skins/default/xui/en/panel_inventory_item.xml
index 2e38835810..2e38835810 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_inventory_item.xml
+++ b/indra/newview/skins/default/xui/en/panel_inventory_item.xml
diff --git a/indra/newview/skins/default/xui/en/panel_landmark_info.xml b/indra/newview/skins/default/xui/en/panel_landmark_info.xml
index fd6e96b9a7..fd6e96b9a7 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_landmark_info.xml
+++ b/indra/newview/skins/default/xui/en/panel_landmark_info.xml
diff --git a/indra/newview/skins/default/xui/en/panel_landmarks.xml b/indra/newview/skins/default/xui/en/panel_landmarks.xml
index 2a5933e3e9..67a09949ce 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_landmarks.xml
+++ b/indra/newview/skins/default/xui/en/panel_landmarks.xml
@@ -35,7 +35,9 @@
left="0"
mouse_opaque="true"
name="favorites_list"
- start_folder="Favorites"
+ scroll.hide_scrollbar="true"
+ folder_view.use_ellipses="true"
+ start_folder.name="Favorites"
width="307"/>
</accordion_tab>
<accordion_tab
@@ -51,7 +53,9 @@
left="0"
mouse_opaque="true"
name="landmarks_list"
- start_folder="Landmarks"
+ scroll.hide_scrollbar="true"
+ folder_view.use_ellipses="true"
+ start_folder.name="Landmarks"
width="307"/>
</accordion_tab>
<accordion_tab
@@ -67,7 +71,9 @@
left="0"
mouse_opaque="true"
name="my_inventory_list"
- start_folder="My Inventory"
+ scroll.hide_scrollbar="true"
+ folder_view.use_ellipses="true"
+ start_folder.name="My Inventory"
width="307"/>
</accordion_tab>
<accordion_tab
@@ -83,7 +89,9 @@
left="0"
mouse_opaque="true"
name="library_list"
- start_folder="LIBRARY"
+ scroll.hide_scrollbar="true"
+ folder_view.use_ellipses="true"
+ start_folder.name="LIBRARY"
width="313"/>
</accordion_tab>
</accordion>
diff --git a/indra/newview/skins/default/xui/en/panel_login.xml b/indra/newview/skins/default/xui/en/panel_login.xml
index 223326dd06..134ca75018 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_login.xml
+++ b/indra/newview/skins/default/xui/en/panel_login.xml
@@ -1,216 +1,265 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<panel
-follows="all"
-height="600"
-layout="topleft"
-left="0"
-name="panel_login"
-focus_root="true"
-top="600"
- width="996">
-<panel.string
- name="create_account_url">
- http://join.secondlife.com/
-</panel.string>
-<string name="reg_in_client_url" translate="false">
- http://secondlife.eniac15.lindenlab.com/reg-in-client/
-</string>
-<panel.string
- name="forgot_password_url">
- http://secondlife.com/account/request.php
-</panel.string>
-<!-- *NOTE: Custom resize logic for login_html in llpanellogin.cpp -->
-<web_browser
- tab_stop="false"
- trusted_content="true"
- bg_opaque_color="Black"
- border_visible="false"
- bottom="600"
- follows="all"
- left="0"
- name="login_html"
- start_url=""
- top="0"
- height="600"
- width="980"/>
-<layout_stack
-follows="left|bottom|right"
-name="login_widgets"
-layout="topleft"
-orientation="horizontal"
-top="519"
-width="996"
-height="80">
-<layout_panel
-auto_resize="false"
-follows="left|bottom"
-name="login"
-layout="topleft"
-width="705"
-min_width="705"
-height="80">
-<text
-follows="left|bottom"
-font="SansSerifSmall"
-height="16"
-name="username_text"
-top="20"
-left="20"
-width="150">
-Username:
-</text>
-<combo_box
-allow_text_entry="true"
-follows="left|bottom"
-height="22"
-left_delta="0"
-max_chars="128"
-combo_editor.prevalidate_callback="ascii"
-tool_tip="The username you chose when you registered, like bobsmith12 or Steller Sunshine"
-top_pad="0"
-name="username_combo"
-width="178">
- <combo_box.combo_button
- visible ="false"/>
- <combo_box.drop_down_button
- visible ="false"/>
-</combo_box>
-<text
-follows="left|bottom"
-font="SansSerifSmall"
-height="15"
-left_pad="-19"
-name="password_text"
-top="20"
- width="150">
- Password:
-</text>
-<line_editor
-follows="left|bottom"
- height="22"
- max_length_bytes="16"
-name="password_edit"
-is_password="true"
-select_on_focus="true"
- top_pad="0"
- width="135" />
- <check_box
-control_name="RememberPassword"
-follows="left|bottom"
-font="SansSerifSmall"
-height="16"
-label="Remember password"
- top_pad="3"
- name="remember_check"
- width="135" />
-<button
- follows="left|bottom"
- height="23"
- image_unselected="PushButton_On"
- image_selected="PushButton_On_Selected"
- label="Log In"
- label_color="White"
- layout="topleft"
- left_pad="10"
- name="connect_btn"
- top="35"
- width="90" />
- <text
- follows="left|bottom"
- font="SansSerifSmall"
- height="15"
- left_pad="8"
- name="start_location_text"
- top="20"
- width="130">
- Start at:
- </text>
-<combo_box
-allow_text_entry="true"
-control_name="NextLoginLocation"
- follows="left|bottom"
- height="23"
-max_chars="128"
-top_pad="0"
-name="start_location_combo"
- width="165">
-<combo_box.item
-label="My last location"
-name="MyLastLocation"
- value="last" />
-<combo_box.item
-label="My home"
-name="MyHome"
- value="home" />
-<combo_box.item
-label="&lt;Type region name&gt;"
-name="Typeregionname" value="" />
-</combo_box>
-<combo_box
-allow_text_entry="true"
-font="SansSerifSmall"
- follows="left|right|bottom"
- height="23"
- max_chars="256"
-layout="topleft"
-top_pad="2"
-name="server_combo"
-width="135"
- visible="false" />
-</layout_panel>
-<layout_panel
-tab_stop="false"
-follows="right|bottom"
-name="links"
-width="205"
-min_width="205"
-height="80">
- <text
-follows="right|bottom"
-font="SansSerifSmall"
-text_color="EmphasisColor"
-halign="right"
-height="16"
-top="12"
-right="-10"
-name="create_new_account_text"
- width="200">
- Sign up
- </text>
-<text
-follows="right|bottom"
-font="SansSerifSmall"
-text_color="EmphasisColor"
-halign="right"
-height="16"
-name="forgot_password_text"
-top_pad="12"
-right="-10"
- width="200">
- Forgot your username or password?
-</text>
-<text
-follows="right|bottom"
-font="SansSerifSmall"
-text_color="EmphasisColor"
-halign="right"
-height="16"
-name="login_help"
-top_pad="2"
-right="-10"
- width="200">
- Need help logging in? </text>
-<!-- <text
- follows="right|bottom"
- font="SansSerifSmall"
- halign="right"
- height="28"
- top_pad="2"
- name="channel_text"
- width="180"
- word_wrap="true">
- [VERSION]
- </text>-->
- </layout_panel>
-</layout_stack>
+ follows="all"
+ height="600"
+ layout="topleft"
+ left="0"
+ name="panel_login"
+ focus_root="true"
+ top="600"
+ width="1130">
+ <string name="reg_in_client_url" translate="false">
+ http://secondlife.eniac15.lindenlab.com/reg-in-client/
+ </string>
+ <panel.string
+ name="forgot_password_url">
+ http://secondlife.com/account/request.php
+ </panel.string>
+ <!-- *NOTE: Custom resize logic for login_html in llpanellogin.cpp -->
+ <web_browser
+ tab_stop="false"
+ trusted_content="true"
+ bg_opaque_color="Black"
+ border_visible="false"
+ bottom="600"
+ follows="all"
+ left="0"
+ name="login_html"
+ start_url=""
+ top="0"
+ height="600"
+ width="996"/>
+ <layout_stack
+ animate="false"
+ clip="false"
+ follows="left|bottom|right"
+ name="login_widgets"
+ layout="topleft"
+ orientation="horizontal"
+ top="519"
+ width="1130"
+ height="80">
+ <layout_panel
+ auto_resize="false"
+ follows="left|bottom"
+ name="login"
+ layout="topleft"
+ width="310"
+ min_width="310"
+ height="80">
+ <text
+ follows="left|bottom"
+ font="SansSerif"
+ font.style="BOLD"
+ font.size="Large"
+ height="16"
+ name="log_in_text"
+ top="8"
+ left="15"
+ width="150">
+ LOG IN
+ </text>
+ <text
+ follows="left|bottom"
+ font="SansSerifSmall"
+ height="16"
+ name="username_text"
+ top="35"
+ left="15"
+ width="150">
+ Username:
+ </text>
+ <!-- STEAM-14: Turn off commit_on_focus_lost so if user presses Enter
+ with focus in this combo_box, we can use commit action to initiate
+ login -->
+ <combo_box
+ allow_text_entry="true"
+ follows="left|bottom"
+ height="22"
+ left_delta="0"
+ max_chars="128"
+ commit_on_focus_lost="false"
+ combo_editor.prevalidate_callback="ascii"
+ tool_tip="The username you chose when you registered, like bobsmith12 or Steller Sunshine"
+ top_pad="0"
+ name="username_combo"
+ width="178">
+<!-- empirically, displayed width is 150 anyway?!? -->
+ <combo_box.combo_button
+ visible ="false"/>
+ <combo_box.drop_down_button
+ visible ="false"/>
+ </combo_box>
+<!-- left="175" based on actual "username_combo" width of 150 vs. 178 -->
+ <text
+ follows="left|bottom"
+ font="SansSerifSmall"
+ height="16"
+ name="password_text"
+ top="35"
+ left="175"
+ width="150">
+ Password:
+ </text>
+ <!-- STEAM-14: Turn off commit_on_focus_lost so if user presses Enter
+ with focus in this line_editor, we can use commit action to
+ initiate login -->
+ <line_editor
+ follows="left|bottom"
+ height="22"
+ max_length_bytes="16"
+ name="password_edit"
+ is_password="true"
+ select_on_focus="true"
+ commit_on_focus_lost="false"
+ top_pad="0"
+ width="135" />
+ </layout_panel>
+ <layout_panel
+ auto_resize="false"
+ follows="left|bottom"
+ name="start_location_panel"
+ layout="topleft"
+ width="175"
+ min_width="175"
+ height="80">
+ <text
+ follows="left|bottom"
+ font="SansSerifSmall"
+ height="16"
+ left="10"
+ name="start_location_text"
+ top="35"
+ width="130">
+ Start at:
+ </text>
+ <combo_box
+ allow_text_entry="true"
+ control_name="NextLoginLocation"
+ follows="left|bottom"
+ height="22"
+ max_chars="128"
+ top_pad="0"
+ name="start_location_combo"
+ width="165">
+ <combo_box.item
+ label="My last location"
+ name="MyLastLocation"
+ value="last" />
+ <combo_box.item
+ label="My home"
+ name="MyHome"
+ value="home" />
+ <combo_box.item
+ label="&lt;Type region name&gt;"
+ name="Typeregionname" value="" />
+ </combo_box>
+ </layout_panel>
+ <layout_panel
+ auto_resize="false"
+ follows="left|bottom"
+ name="grid_panel"
+ layout="topleft"
+ width="145"
+ height="80"
+ visible="false">
+ <combo_box
+ allow_text_entry="false"
+ font="SansSerifSmall"
+ follows="left|right|bottom"
+ height="23"
+ max_chars="256"
+ left="10"
+ top="51"
+ layout="topleft"
+ top_pad="2"
+ name="server_combo"
+ width="135" />
+ </layout_panel>
+ <layout_panel
+ auto_resize="false"
+ follows="left|bottom"
+ name="links_login_panel"
+ layout="topleft"
+ width="290"
+ height="80">
+ <text
+ follows="left|bottom"
+ font="SansSerifSmall"
+ text_color="EmphasisColor"
+ left="10"
+ height="16"
+ name="login_help"
+ top="19"
+ width="280">
+ Need help logging in?
+ </text>
+ <text
+ follows="left|bottom"
+ font="SansSerifSmall"
+ text_color="EmphasisColor"
+ height="16"
+ name="forgot_password_text"
+ top="35"
+ width="280">
+ Forgot your username or password?
+ </text>
+ <button
+ follows="left|bottom"
+ top_pad="0"
+ height="23"
+ image_unselected="PushButton_On"
+ image_selected="PushButton_On_Selected"
+ label="Log In"
+ label_color="White"
+ layout="topleft"
+ name="connect_btn"
+ width="90" />
+ <check_box
+ control_name="RememberPassword"
+ follows="left|bottom"
+ font="SansSerifSmall"
+ left="110"
+ top="56"
+ height="16"
+ label="Remember password"
+ top_pad="3"
+ name="remember_check"
+ width="145" />
+ </layout_panel>
+ <layout_panel
+ tab_stop="false"
+ follows="right|bottom"
+ name="links"
+ width="210"
+ min_width="100"
+ height="80">
+ <text
+ follows="right|bottom"
+ font="SansSerif"
+ font.style="BOLD"
+ font.size="Large"
+ halign="right"
+ height="16"
+ name="create_account_text"
+ top="8"
+ right="-15"
+ width="200">
+ CREATE YOUR ACCOUNT
+ </text>
+ <button
+ follows="right|bottom"
+ top="35"
+ right="-15"
+ height="23"
+ image_unselected="PushButton_On"
+ image_selected="PushButton_On_Selected"
+ label="Start now"
+ label_color="White"
+ layout="topleft"
+ left_pad="10"
+ name="create_new_account_btn"
+ width="90" />
+ </layout_panel>
+ </layout_stack>
</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_main_inventory.xml b/indra/newview/skins/default/xui/en/panel_main_inventory.xml
index 1c882bb099..1c882bb099 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_main_inventory.xml
+++ b/indra/newview/skins/default/xui/en/panel_main_inventory.xml
diff --git a/indra/newview/skins/default/xui/en/panel_me.xml b/indra/newview/skins/default/xui/en/panel_me.xml
index 23e7814cad..23e7814cad 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_me.xml
+++ b/indra/newview/skins/default/xui/en/panel_me.xml
diff --git a/indra/newview/skins/default/xui/en/panel_media_settings_general.xml b/indra/newview/skins/default/xui/en/panel_media_settings_general.xml
index cdf14572fe..e844a15118 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_media_settings_general.xml
+++ b/indra/newview/skins/default/xui/en/panel_media_settings_general.xml
@@ -30,7 +30,7 @@
(This page does not pass the specified whitelist)
</text>
<line_editor
- max_length="1024"
+ max_length_bytes="1024"
bottom_delta="-24"
enabled="true"
follows="left|top"
diff --git a/indra/newview/skins/default/xui/en/panel_media_settings_permissions.xml b/indra/newview/skins/default/xui/en/panel_media_settings_permissions.xml
index d3a58fed58..d3a58fed58 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_media_settings_permissions.xml
+++ b/indra/newview/skins/default/xui/en/panel_media_settings_permissions.xml
diff --git a/indra/newview/skins/default/xui/en/panel_media_settings_security.xml b/indra/newview/skins/default/xui/en/panel_media_settings_security.xml
index 1f580831f9..1f580831f9 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_media_settings_security.xml
+++ b/indra/newview/skins/default/xui/en/panel_media_settings_security.xml
diff --git a/indra/newview/skins/default/xui/en/panel_navigation_bar.xml b/indra/newview/skins/default/xui/en/panel_navigation_bar.xml
index 3edeb9aa36..c7edba21f8 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_navigation_bar.xml
+++ b/indra/newview/skins/default/xui/en/panel_navigation_bar.xml
@@ -87,6 +87,7 @@
direction="down"
height="23"
image_overlay="Arrow_Left_Off"
+ image_hover_unselected="PushButton_Over"
image_bottom_pad="1"
layout="topleft"
left="10"
@@ -99,6 +100,7 @@
direction="down"
height="23"
image_overlay="Arrow_Right_Off"
+ image_hover_unselected="PushButton_Over"
image_bottom_pad="1"
layout="topleft"
left_pad="0"
@@ -111,6 +113,7 @@
height="23"
image_bottom_pad="1"
image_overlay="Home_Off"
+ image_hover_unselected="PushButton_Over"
layout="topleft"
left_pad="7"
name="home_btn"
diff --git a/indra/newview/skins/default/xui/en/panel_nearby_chat.xml b/indra/newview/skins/default/xui/en/panel_nearby_chat.xml
index d683116eb8..4de56b424e 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_nearby_chat.xml
+++ b/indra/newview/skins/default/xui/en/panel_nearby_chat.xml
@@ -1,20 +1,22 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel
follows="all"
- height="300"
+ top="0"
+ bottom_delta="10"
help_topic="nearby_chat"
layout="topleft"
name="nearby_chat"
- width="320">
+ width="242"
+ height="169">
<layout_stack
follows="all"
- height="295"
+ height="164"
layout="topleft"
left="0"
name="stack"
top="5"
orientation="vertical"
- width="320">
+ width="242">
<layout_panel
auto_resize="false"
height="26"
@@ -23,7 +25,7 @@
name="translate_chat_checkbox_lp"
top_delta="0"
visible="true"
- width="313">
+ width="230">
<check_box
top="10"
control_name="TranslateChat"
@@ -33,15 +35,15 @@
layout="topleft"
left="5"
name="translate_chat_checkbox"
- width="300" />
+ width="230" />
</layout_panel>
<layout_panel
auto_resize="true"
- height="277"
+ height="138"
left_delta="0"
layout="topleft"
name="chat_history_lp"
- width="318">
+ width="242">
<chat_history
bg_readonly_color="ChatHistoryBgColor"
bg_writeable_color="ChatHistoryBgColor"
@@ -49,7 +51,7 @@
layout="topleft"
left="5"
left_widget_pad="0"
- height="272"
+ height="138"
name="chat_history"
parse_highlights="true"
parse_urls="true"
@@ -57,7 +59,7 @@
text_color="ChatHistoryTextColor"
text_readonly_color="ChatHistoryTextColor"
top="0"
- width="313" />
+ width="237" />
</layout_panel>
</layout_stack>
</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml b/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml
index 21c627cdfb..19143cef89 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml
+++ b/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml
@@ -5,7 +5,7 @@
height="25"
layout="topleft"
left="0"
- name="chat_bar"
+ name="nearby_chat"
top="21"
width="308">
<line_editor
@@ -19,6 +19,7 @@
left="0"
max_length_bytes="1023"
name="chat_box"
+ spellcheck="true"
text_pad_left="5"
text_pad_right="25"
tool_tip="Press Enter to say, Ctrl+Enter to shout"
diff --git a/indra/newview/skins/default/xui/en/panel_nearby_media.xml b/indra/newview/skins/default/xui/en/panel_nearby_media.xml
index d1cb64f7ad..d1cb64f7ad 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_nearby_media.xml
+++ b/indra/newview/skins/default/xui/en/panel_nearby_media.xml
diff --git a/indra/newview/skins/default/xui/en/panel_notification.xml b/indra/newview/skins/default/xui/en/panel_notification.xml
index 94c468e1bb..94c468e1bb 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_notification.xml
+++ b/indra/newview/skins/default/xui/en/panel_notification.xml
diff --git a/indra/newview/skins/default/xui/en/panel_notifications_channel.xml b/indra/newview/skins/default/xui/en/panel_notifications_channel.xml
index c3dc588ba2..c3dc588ba2 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_notifications_channel.xml
+++ b/indra/newview/skins/default/xui/en/panel_notifications_channel.xml
diff --git a/indra/newview/skins/default/xui/en/panel_notify_textbox.xml b/indra/newview/skins/default/xui/en/panel_notify_textbox.xml
index d5b6057233..d5b6057233 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_notify_textbox.xml
+++ b/indra/newview/skins/default/xui/en/panel_notify_textbox.xml
diff --git a/indra/newview/skins/default/xui/en/panel_online_status_toast.xml b/indra/newview/skins/default/xui/en/panel_online_status_toast.xml
index dadbd9c9ab..dadbd9c9ab 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_online_status_toast.xml
+++ b/indra/newview/skins/default/xui/en/panel_online_status_toast.xml
diff --git a/indra/newview/skins/default/xui/en/panel_outbox_inventory.xml b/indra/newview/skins/default/xui/en/panel_outbox_inventory.xml
index a3d39e55af..c80e5b168a 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_outbox_inventory.xml
+++ b/indra/newview/skins/default/xui/en/panel_outbox_inventory.xml
@@ -1,7 +1,10 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<outbox_inventory_panel
+<inventory_panel
name="inventory_outbox"
- start_folder="Outbox"
+ start_folder.name="Outbox"
+ show_empty_message="false"
+ show_load_status="false"
+ start_folder.type="outbox"
follows="all" layout="topleft"
top="0" left="0" height="165" width="308"
top_pad="0"
@@ -12,6 +15,18 @@
bevel_style="none"
show_item_link_overlays="true"
tool_tip="Drag and drop items here to prepare them for sale on your storefront"
- >
- <scroll reserve_scroll_corner="false" />
-</outbox_inventory_panel>
+ scroll.reserve_scroll_corner="false">
+ <folder folder_arrow_image="Folder_Arrow"
+ folder_indentation="8"
+ item_height="20"
+ item_top_pad="4"
+ selection_image="Rounded_Square"
+ left_pad="5"
+ icon_pad="2"
+ icon_width="16"
+ text_pad="1"
+ text_pad_right="4"
+ arrow_size="12"
+ max_folder_item_overlap="2"/>
+ <item allow_open="false"/>
+</inventory_panel>
diff --git a/indra/newview/skins/default/xui/en/panel_outfit_edit.xml b/indra/newview/skins/default/xui/en/panel_outfit_edit.xml
index b61f110e32..b61f110e32 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_outfit_edit.xml
+++ b/indra/newview/skins/default/xui/en/panel_outfit_edit.xml
diff --git a/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml b/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml
index 405d9513db..405d9513db 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml
+++ b/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml
diff --git a/indra/newview/skins/default/xui/en/panel_outfits_inventory_gear_default.xml b/indra/newview/skins/default/xui/en/panel_outfits_inventory_gear_default.xml
index 2c7a51f0e7..2c7a51f0e7 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_outfits_inventory_gear_default.xml
+++ b/indra/newview/skins/default/xui/en/panel_outfits_inventory_gear_default.xml
diff --git a/indra/newview/skins/default/xui/en/panel_outfits_list.xml b/indra/newview/skins/default/xui/en/panel_outfits_list.xml
index a0096adc01..a0096adc01 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_outfits_list.xml
+++ b/indra/newview/skins/default/xui/en/panel_outfits_list.xml
diff --git a/indra/newview/skins/default/xui/en/panel_outfits_wearing.xml b/indra/newview/skins/default/xui/en/panel_outfits_wearing.xml
index d85b778db2..d85b778db2 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_outfits_wearing.xml
+++ b/indra/newview/skins/default/xui/en/panel_outfits_wearing.xml
diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml
index 98c7c49ff4..3caf2b3d7e 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_people.xml
+++ b/indra/newview/skins/default/xui/en/panel_people.xml
@@ -38,12 +38,6 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
name="no_filtered_friends_msg">
Didn't find what you're looking for? Try [secondlife:///app/search/people/[SEARCH_TERM] Search].
</string>
- <string
- name="people_filter_label"
- value="Filter People" />
- <string
- name="groups_filter_label"
- value="Filter Groups" />
<!--
*WORKAROUND: for group_list.no_items_msg & group_list.no_filtered_items_msg attributes.
They are not defined as translatable in VLT. See EXT-5931
@@ -60,21 +54,9 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
<string
name="AltMiniMapToolTipMsg"
value="[REGION](Double-click to teleport, shift-drag to pan)"/>
- <filter_editor
- follows="left|top|right"
- height="23"
- layout="topleft"
- left="10"
- label="Filter"
- max_length_chars="300"
- name="filter_input"
- text_color="Black"
- text_pad_left="10"
- top="3"
- width="303" />
<tab_container
+ bottom="-10"
follows="all"
- height="383"
layout="topleft"
left="3"
name="tabs"
@@ -82,31 +64,121 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
tab_min_width="70"
tab_height="30"
tab_position="top"
- top_pad="10"
+ top="0"
halign="center"
- width="319">
- <panel
+ right="-5"
+ use_highlighting_on_hover="true">
+
+<!-- ================================= NEARBY tab =========================== -->
+
+ <panel
background_opaque="true"
background_visible="true"
bg_alpha_color="DkGray"
bg_opaque_color="DkGray"
+ bottom="-1"
follows="all"
- height="383"
label="NEARBY"
layout="topleft"
left="0"
help_topic="people_nearby_tab"
name="nearby_panel"
- top="0"
- width="313">
+ right="-1"
+ top="0">
+ <panel
+ follows="left|top|right"
+ height="27"
+ label="bottom_panel"
+ layout="topleft"
+ left="0"
+ name="nearby_buttons_panel"
+ right="-1"
+ top="0">
+ <filter_editor
+ follows="left|top|right"
+ height="23"
+ layout="topleft"
+ left="6"
+ label="Filter People"
+ max_length_chars="300"
+ name="nearby_filter_input"
+ text_color="Black"
+ text_pad_left="10"
+ top="4"
+ width="178" />
+ <button
+ commit_callback.function="People.Gear"
+ follows="right"
+ height="25"
+ image_hover_unselected="Toolbar_Middle_Over"
+ image_overlay="OptionsMenu_Off"
+ image_selected="Toolbar_Middle_Selected"
+ image_unselected="Toolbar_Middle_Off"
+ layout="topleft"
+ left_pad="7"
+ name="gear_btn"
+ tool_tip="Actions on selected person"
+ top="3"
+ width="31" />
+ <menu_button
+ follows="right"
+ height="25"
+ image_hover_unselected="Toolbar_Middle_Over"
+ image_overlay="Conv_toolbar_sort"
+ image_selected="Toolbar_Middle_Selected"
+ image_unselected="Toolbar_Middle_Off"
+ layout="topleft"
+ left_pad="2"
+ menu_filename="menu_people_nearby_view.xml"
+ menu_position="bottomleft"
+ name="nearby_view_btn"
+ tool_tip="View/sort options"
+ top_delta="0"
+ width="31" />
+ <button
+ follows="right"
+ height="25"
+ image_hover_unselected="Toolbar_Middle_Over"
+ image_overlay="AddItem_Off"
+ image_selected="Toolbar_Middle_Selected"
+ image_unselected="Toolbar_Middle_Off"
+ layout="topleft"
+ left_pad="2"
+ name="add_friend_btn"
+ tool_tip="Offer friendship to a resident"
+ top_delta="0"
+ width="31">
+ <commit_callback
+ function="People.AddFriend" />
+ </button>
+ <dnd_button
+ enabled="false"
+ follows="right"
+ height="25"
+ image_hover_unselected="Toolbar_Middle_Over"
+ image_overlay="TrashItem_Off"
+ image_selected="Toolbar_Middle_Selected"
+ image_unselected="Toolbar_Middle_Off"
+ left_pad="2"
+ layout="topleft"
+ name="nearby_del_btn"
+ tool_tip="Remove selected person as a friend"
+ top_delta="0"
+ width="31">
+ <commit_callback
+ function="People.DelFriend" />
+ </dnd_button>
+ </panel>
<layout_stack
clip="false"
follows="all"
- height="355"
+ height="410"
layout="topleft"
+ left="0"
mouse_opaque="false"
orientation="vertical"
- width="313">
+ right="-1"
+ top_pad="0">
<layout_panel
height="142"
layout="topleft"
@@ -123,16 +195,16 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
left="3"
mouse_opaque="false"
name="Net Map"
- top="4"
- width="305"/>
+ right="-1"
+ top="4" />
</layout_panel>
<layout_panel
height="213"
layout="topleft"
min_dim="100"
mouse_opaque="false"
- user_resize="true"
- width="313">
+ right="-1"
+ user_resize="true">
<avatar_list
allow_select="true"
follows="all"
@@ -143,84 +215,122 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
keep_one_selected="false"
multi_select="true"
name="avatar_list"
- top="2"
- width="306" />
+ right="-1"
+ top="2" />
</layout_panel>
</layout_stack>
- <panel
- background_visible="true"
- follows="left|right|bottom"
- height="27"
- label="bottom_panel"
- layout="topleft"
- left="3"
- name="bottom_panel"
- top_pad="0"
- width="313">
- <menu_button
- follows="bottom|left"
- height="25"
- image_hover_unselected="Toolbar_Left_Over"
- image_overlay="OptionsMenu_Off"
- image_selected="Toolbar_Left_Selected"
- image_unselected="Toolbar_Left_Off"
- layout="topleft"
- left="0"
- name="nearby_view_sort_btn"
- tool_tip="Options"
- top="1"
- width="31" />
- <button
- follows="bottom|left"
- height="25"
- image_hover_unselected="Toolbar_Middle_Over"
- image_overlay="AddItem_Off"
- image_selected="Toolbar_Middle_Selected"
- image_unselected="Toolbar_Middle_Off"
- layout="topleft"
- left_pad="1"
- name="add_friend_btn"
- tool_tip="Add selected Resident to your friends List"
- width="31">
- <commit_callback
- function="People.addFriend" />
- </button>
- <icon
- follows="bottom|left|right"
- height="25"
- image_name="Toolbar_Right_Off"
- layout="topleft"
- left_pad="1"
- name="dummy_icon"
- width="243"
- />
- </panel>
</panel>
+
+<!-- ================================= FRIENDS tab ========================== -->
+
<panel
background_opaque="true"
background_visible="true"
bg_alpha_color="DkGray"
bg_opaque_color="DkGray"
+ bottom="-1"
follows="all"
- height="383"
- label="MY FRIENDS"
+ label="FRIENDS"
layout="topleft"
left="0"
help_topic="people_friends_tab"
name="friends_panel"
- top="0"
- width="313">
+ right="-1"
+ top="0">
+ <panel
+ follows="left|top|right"
+ height="27"
+ label="bottom_panel"
+ layout="topleft"
+ left="0"
+ name="friends_buttons_panel"
+ right="-1"
+ top="0">
+ <filter_editor
+ follows="left|top|right"
+ height="23"
+ layout="topleft"
+ left="6"
+ label="Filter People"
+ max_length_chars="300"
+ name="friends_filter_input"
+ text_color="Black"
+ text_pad_left="10"
+ top="4"
+ width="177" />
+ <button
+ commit_callback.function="People.Gear"
+ follows="right"
+ height="25"
+ image_hover_unselected="Toolbar_Middle_Over"
+ image_overlay="OptionsMenu_Off"
+ image_selected="Toolbar_Middle_Selected"
+ image_unselected="Toolbar_Middle_Off"
+ layout="topleft"
+ left_pad="8"
+ name="gear_btn"
+ tool_tip="Actions on selected person"
+ top="3"
+ width="31" />
+ <menu_button
+ follows="right"
+ height="25"
+ image_hover_unselected="Toolbar_Middle_Over"
+ image_overlay="Conv_toolbar_sort"
+ image_selected="Toolbar_Middle_Selected"
+ image_unselected="Toolbar_Middle_Off"
+ layout="topleft"
+ left_pad="2"
+ menu_filename="menu_people_friends_view.xml"
+ menu_position="bottomleft"
+ name="friends_view_btn"
+ tool_tip="View/sort options"
+ top_delta="0"
+ width="31" />
+ <button
+ follows="right"
+ height="25"
+ image_hover_unselected="Toolbar_Middle_Over"
+ image_overlay="AddItem_Off"
+ image_selected="Toolbar_Middle_Selected"
+ image_unselected="Toolbar_Middle_Off"
+ layout="topleft"
+ left_pad="2"
+ name="friends_add_btn"
+ tool_tip="Offer friendship to a resident"
+ top_delta="0"
+ width="31">
+ <commit_callback
+ function="People.AddFriendWizard" />
+ </button>
+ <dnd_button
+ follows="right"
+ height="25"
+ image_hover_unselected="Toolbar_Middle_Over"
+ image_overlay="TrashItem_Off"
+ image_selected="Toolbar_Middle_Selected"
+ image_unselected="Toolbar_Middle_Off"
+ left_pad="2"
+ layout="topleft"
+ name="friends_del_btn"
+ tool_tip="Remove selected person as a friend"
+ top_delta="0"
+ width="31">
+ <commit_callback
+ function="People.DelFriend" />
+ </dnd_button>
+ </panel>
<accordion
background_visible="true"
bg_alpha_color="DkGray2"
bg_opaque_color="DkGray2"
follows="all"
- height="356"
+ height="408"
layout="topleft"
left="3"
name="friends_accordion"
- top="0"
- width="307">
+ right="-2"
+ top_pad="2">
<accordion_tab
layout="topleft"
height="172"
@@ -256,248 +366,163 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
top="0"
width="307" />
</accordion_tab>
- </accordion>
- <panel
- background_visible="true"
- follows="left|right|bottom"
- height="27"
- label="bottom_panel"
- layout="topleft"
- left="3"
- name="bottom_panel"
- top_pad="0"
- width="313">
-
- <layout_stack
- animate="false"
- border_size="0"
- follows="left|right|bottom"
- height="25"
- layout="topleft"
- orientation="horizontal"
- top_pad="1"
- left="0"
- name="bottom_panel"
- width="308">
- <layout_panel
- auto_resize="false"
- height="25"
- layout="topleft"
- name="options_gear_btn_panel"
- width="32">
- <menu_button
- follows="bottom|left"
- tool_tip="Show additional options"
- height="25"
- image_hover_unselected="Toolbar_Left_Over"
- image_overlay="OptionsMenu_Off"
- image_selected="Toolbar_Left_Selected"
- image_unselected="Toolbar_Left_Off"
- layout="topleft"
- left="0"
- name="friends_viewsort_btn"
- top="0"
- width="31" />
- </layout_panel>
- <layout_panel
- auto_resize="false"
- height="25"
- layout="topleft"
- name="add_btn_panel"
- width="32">
- <button
- follows="bottom|left"
- height="25"
- image_hover_unselected="Toolbar_Middle_Over"
- image_overlay="AddItem_Off"
- image_selected="Toolbar_Middle_Selected"
- image_unselected="Toolbar_Middle_Off"
- layout="topleft"
- left="0"
- name="add_btn"
- tool_tip="Offer friendship to a Resident"
- top="0"
- width="31" />
- </layout_panel>
- <layout_panel
- auto_resize="true"
- height="25"
- layout="topleft"
- name="dummy_panel"
- width="210">
- <icon
- follows="bottom|left|right"
- height="25"
- image_name="Toolbar_Middle_Off"
- layout="topleft"
- left="0"
- top="0"
- name="dummy_icon"
- width="210" />
- </layout_panel>
- <layout_panel
- auto_resize="false"
- height="25"
- layout="topleft"
- name="trash_btn_panel"
- width="31">
- <dnd_button
- follows="bottom|left"
- height="25"
- image_hover_unselected="Toolbar_Right_Over"
- image_overlay="TrashItem_Off"
- image_selected="Toolbar_Right_Selected"
- image_unselected="Toolbar_Right_Off"
- left="0"
- layout="topleft"
- name="del_btn"
- tool_tip="Remove selected person from your Friends list"
- top="0"
- width="31"/>
- </layout_panel>
- </layout_stack><!--
-
- <button
- follows="bottom|left"
- tool_tip="Options"
- height="25"
- image_hover_unselected="Toolbar_Left_Over"
- image_overlay="OptionsMenu_Off"
- image_selected="Toolbar_Left_Selected"
- image_unselected="Toolbar_Left_Off"
+ <accordion_tab
layout="topleft"
- left="0"
- name="friends_viewsort_btn"
- top="1"
- width="31" />
- <button
- follows="bottom|left"
- height="25"
- image_hover_unselected="Toolbar_Middle_Over"
- image_overlay="AddItem_Off"
- image_selected="Toolbar_Middle_Selected"
- image_unselected="Toolbar_Middle_Off"
- layout="topleft"
- left_pad="1"
- name="add_btn"
- tool_tip="Offer friendship to a Resident"
- width="31" />
- <icon
- follows="bottom|left|right"
- height="25"
- image_name="Toolbar_Middle_Off"
- layout="topleft"
- left_pad="1"
- name="dummy_icon"
- width="209"
- />
- <button
- follows="bottom|left"
- height="25"
- image_hover_unselected="Toolbar_Right_Over"
- image_overlay="TrashItem_Off"
- image_selected="Toolbar_Right_Selected"
- image_unselected="Toolbar_Right_Off"
+ height="173"
+ name="tab_suggested_friends"
+ title="People you may want to friend">
+ <avatar_list
+ ignore_online_status="true"
+ allow_select="true"
+ follows="all"
+ height="173"
layout="topleft"
- left_pad="1"
- name="del_btn"
- tool_tip="Remove selected person from your Friends list"
- width="31" />
- --></panel>
+ left="0"
+ name="suggested_friends"
+ show_permissions_granted="true"
+ top="0"
+ width="307" />
+ </accordion_tab>
+ </accordion>
<text
follows="all"
height="450"
left="13"
name="no_friends_help_text"
- top="10"
- width="293"
+ right="-13"
+ top="37"
wrap="true" />
</panel>
+
+<!-- ================================= GROUPS tab =========================== -->
+
<panel
background_opaque="true"
background_visible="true"
bg_alpha_color="DkGray"
bg_opaque_color="DkGray"
+ bottom="-1"
follows="all"
- height="383"
- label="MY GROUPS"
+ label="GROUPS"
layout="topleft"
left="0"
help_topic="people_groups_tab"
name="groups_panel"
- top="0"
- width="313">
+ right="-1"
+ top="0">
<!--
*NOTE: no_groups_msg & group_list attributes are not defined as translatable in VLT. See EXT-5931
Values are set from appropriate strings at the top of file via LLPeoplePanel::postBuild()
-->
- <group_list
- allow_select="true"
- follows="all"
- height="356"
- layout="topleft"
- left="3"
- name="group_list"
- top="0"
- width="307" />
<panel
- background_visible="true"
- follows="left|right|bottom"
+ follows="left|top|right"
height="27"
label="bottom_panel"
layout="topleft"
left="0"
- name="bottom_panel"
- top_pad="0"
- width="313">
- <menu_button
- follows="bottom|left"
- tool_tip="Options"
- height="25"
- image_hover_unselected="Toolbar_Left_Over"
- image_overlay="OptionsMenu_Off"
- image_selected="Toolbar_Left_Selected"
- image_unselected="Toolbar_Left_Off"
- layout="topleft"
- left="3"
- name="groups_viewsort_btn"
- top="1"
- width="31" />
- <button
- follows="bottom|left"
+ name="groups_buttons_panel"
+ right="-1"
+ top="0">
+ <filter_editor
+ follows="left|top|right"
+ height="23"
+ layout="topleft"
+ left="6"
+ label="Filter Groups"
+ max_length_chars="300"
+ name="groups_filter_input"
+ text_color="Black"
+ text_pad_left="10"
+ top="4"
+ width="177" />
+ <menu_button
+ follows="right"
+ height="25"
+ image_hover_unselected="Toolbar_Middle_Over"
+ image_overlay="OptionsMenu_Off"
+ image_selected="Toolbar_Middle_Selected"
+ image_unselected="Toolbar_Middle_Off"
+ layout="topleft"
+ left_pad="8"
+ name="groups_gear_btn"
+ tool_tip="Actions on selected group"
+ top="3"
+ width="31" />
+ <menu_button
+ follows="right"
+ height="25"
+ image_hover_unselected="Toolbar_Middle_Over"
+ image_overlay="Conv_toolbar_sort"
+ image_selected="Toolbar_Middle_Selected"
+ image_unselected="Toolbar_Middle_Off"
+ layout="topleft"
+ left_pad="2"
+ menu_filename="menu_people_groups_view.xml"
+ menu_position="bottomleft"
+ name="groups_view_btn"
+ tool_tip="View/sort options"
+ top_delta="0"
+ width="31" />
+ <menu_button
+ follows="right"
height="25"
image_hover_unselected="Toolbar_Middle_Over"
image_overlay="AddItem_Off"
image_selected="Toolbar_Middle_Selected"
image_unselected="Toolbar_Middle_Off"
layout="topleft"
- left_pad="1"
+ left_pad="2"
+ menu_filename="menu_group_plus.xml"
+ menu_position="bottomleft"
name="plus_btn"
tool_tip="Join group/Create new group"
- width="31" />
- <button
- follows="bottom|left"
+ top_delta="0"
+ width="31">
+ <validate_callback
+ function="People.Group.Plus.Validate" />
+ </menu_button>
+ <dnd_button
+ follows="right"
height="25"
image_hover_unselected="Toolbar_Middle_Over"
- image_overlay="Activate_Checkmark"
+ image_overlay="TrashItem_Off"
image_selected="Toolbar_Middle_Selected"
image_unselected="Toolbar_Middle_Off"
+ left_pad="2"
layout="topleft"
- left_pad="1"
- name="activate_btn"
- tool_tip="Activate selected group"
- width="31" />
- <icon
- follows="bottom|left|right"
- height="25"
- image_name="Toolbar_Right_Off"
- layout="topleft"
- left_pad="1"
- name="dummy_icon"
- width="212"
- />
+ name="minus_btn"
+ tool_tip="Leave selected group"
+ top_delta="0"
+ width="31">
+ <commit_callback
+ function="People.Group.Minus" />
+ </dnd_button>
</panel>
+ <text
+ type="string"
+ length="1"
+ follows="left|top|right"
+ height="14"
+ layout="topleft"
+ right="-10"
+ top_pad="4"
+ left="3"
+ name="groupcount">
+ You belong to [COUNT] groups, and can join [REMAINING] more.
+ </text>
+ <group_list
+ allow_select="true"
+ follows="all"
+ height="388"
+ layout="topleft"
+ left="3"
+ name="group_list"
+ right="-2"
+ top_pad="4" />
</panel>
+
+<!-- ================================= RECENT tab =========================== -->
+
<panel
background_opaque="true"
background_visible="true"
@@ -510,265 +535,133 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
left="0"
help_topic="people_recent_tab"
name="recent_panel"
- top="0"
- width="313">
- <avatar_list
- allow_select="true"
- follows="all"
- height="356"
- layout="topleft"
- left="3"
- multi_select="true"
- name="avatar_list"
- show_last_interaction_time="true"
- top="0"
- width="307" />
+ right="-1"
+ top="0">
<panel
- background_visible="true"
- follows="left|right|bottom"
+ follows="left|top|right"
height="27"
label="bottom_panel"
layout="topleft"
- left="3"
- name="bottom_panel"
- top_pad="0"
- width="313">
- <menu_button
- follows="bottom|left"
- tool_tip="Options"
- height="25"
- image_hover_unselected="Toolbar_Left_Over"
- image_overlay="OptionsMenu_Off"
- image_selected="Toolbar_Left_Selected"
- image_unselected="Toolbar_Left_Off"
- layout="topleft"
- name="recent_viewsort_btn"
- top="1"
- width="31" />
- <button
- follows="bottom|left"
+ left="0"
+ name="recent_buttons_panel"
+ right="-1"
+ top="0">
+ <filter_editor
+ follows="left|top|right"
+ height="23"
+ layout="topleft"
+ left="6"
+ label="Filter People"
+ max_length_chars="300"
+ name="recent_filter_input"
+ text_color="Black"
+ text_pad_left="10"
+ top="4"
+ width="177" />
+ <button
+ commit_callback.function="People.Gear"
+ follows="right"
+ height="25"
+ image_hover_unselected="Toolbar_Middle_Over"
+ image_overlay="OptionsMenu_Off"
+ image_selected="Toolbar_Middle_Selected"
+ image_unselected="Toolbar_Middle_Off"
+ layout="topleft"
+ left_pad="8"
+ name="gear_btn"
+ tool_tip="Actions on selected person"
+ top="3"
+ width="31" />
+ <menu_button
+ follows="right"
+ height="25"
+ image_hover_unselected="Toolbar_Middle_Over"
+ image_overlay="Conv_toolbar_sort"
+ image_selected="Toolbar_Middle_Selected"
+ image_unselected="Toolbar_Middle_Off"
+ layout="topleft"
+ left_pad="2"
+ menu_filename="menu_people_recent_view.xml"
+ menu_position="bottomleft"
+ name="recent_view_btn"
+ tool_tip="View/sort options"
+ top_delta="0"
+ width="31" />
+ <button
+ follows="right"
height="25"
image_hover_unselected="Toolbar_Middle_Over"
image_overlay="AddItem_Off"
image_selected="Toolbar_Middle_Selected"
image_unselected="Toolbar_Middle_Off"
layout="topleft"
- left_pad="1"
+ left_pad="2"
name="add_friend_btn"
- tool_tip="Add selected Resident to your friends List"
+ tool_tip="Offer friendship to a resident"
+ top_delta="0"
width="31">
- <commit_callback
- function="People.addFriend" />
- </button>
- <icon
- follows="bottom|left|right"
- height="25"
- image_name="Toolbar_Right_Off"
- layout="topleft"
- left_pad="1"
- name="dummy_icon"
- width="244"
- />
+ <commit_callback
+ function="People.AddFriend" />
+ </button>
+ <dnd_button
+ enabled="false"
+ follows="right"
+ height="25"
+ image_hover_unselected="Toolbar_Middle_Over"
+ image_overlay="TrashItem_Off"
+ image_selected="Toolbar_Middle_Selected"
+ image_unselected="Toolbar_Middle_Off"
+ left_pad="2"
+ layout="topleft"
+ name="recent_del_btn"
+ tool_tip="Remove selected person as a friend"
+ top_delta="0"
+ width="31">
+ <commit_callback
+ function="People.DelFriend" />
+ </dnd_button>
</panel>
+ <avatar_list
+ allow_select="true"
+ follows="all"
+ height="351"
+ layout="topleft"
+ left="3"
+ multi_select="true"
+ name="avatar_list"
+ show_last_interaction_time="true"
+ right="-2"
+ top_pad="4" />
</panel>
- </tab_container>
- <panel
- follows="bottom|left|right"
- height="23"
- layout="topleft"
- left="8"
- top_pad="4"
- name="button_bar"
- width="313">
-<!--********************************Profile; IM; Call, Share, Teleport********************************-->
- <layout_stack
- follows="bottom|left|right"
- height="23"
- layout="topleft"
- name="bottom_bar_ls"
- left="0"
- orientation="horizontal"
- top_pad="0"
- width="313">
+<!-- ================================= BLOCKED tab ========================== -->
- <layout_panel
- follows="bottom|left|right"
- height="23"
- layout="bottomleft"
- left="0"
- name="view_profile_btn_lp"
- auto_resize="true"
- width="68">
- <button
- follows="bottom|left|right"
- height="23"
- label="Profile"
- layout="topleft"
- left="1"
- name="view_profile_btn"
- tool_tip="Show picture, groups, and other Residents information"
- top="0"
- width="67" />
- </layout_panel>
-
- <layout_panel
- follows="bottom|left|right"
- height="23"
- layout="bottomleft"
- left_pad="3"
- name="im_btn_lp"
- auto_resize="true"
- width="41">
- <button
- follows="bottom|left|right"
- left="1"
- height="23"
- label="IM"
- layout="topleft"
- name="im_btn"
- tool_tip="Open instant message session"
- top="0"
- width="40" />
- </layout_panel>
-
- <layout_panel
- follows="bottom|left|right"
- height="23"
- layout="bottomleft"
- left_pad="3"
- name="call_btn_lp"
- auto_resize="true"
- width="52">
- <button
- follows="bottom|left|right"
- left="1"
- height="23"
- label="Call"
- layout="topleft"
- name="call_btn"
- tool_tip="Call this Resident"
- top="0"
- width="51" />
- </layout_panel>
-
- <layout_panel
- follows="bottom|left|right"
- height="23"
- layout="bottomleft"
- left_pad="3"
- name="share_btn_lp"
- auto_resize="true"
- width="66">
- <button
- follows="bottom|left|right"
- left="1"
- height="23"
- label="Share"
- layout="topleft"
- name="share_btn"
- tool_tip="Share an inventory item"
- top="0"
- width="65" />
- </layout_panel>
-
- <layout_panel
- follows="bottom|left|right"
- height="23"
- layout="bottomleft"
- left_pad="3"
- name="teleport_btn_lp"
- auto_resize="true"
- width="77">
- <button
- follows="bottom|left|right"
- left="1"
- height="23"
- label="Teleport"
- layout="topleft"
- name="teleport_btn"
- tool_tip="Offer teleport"
- top="0"
- width="76" />
- </layout_panel>
- </layout_stack>
-
-<!--********************************Group Profile; Group Chat; Group Call buttons************************-->
- <layout_stack
- follows="bottom|left|right"
- height="23"
- layout="topleft"
- mouse_opaque="false"
- name="bottom_bar_ls1"
- left="0"
- orientation="horizontal"
- top="0"
- width="313">
- <layout_panel
- follows="bottom|left|right"
- height="23"
- layout="bottomleft"
- left="0"
- mouse_opaque="false"
- name="group_info_btn_lp"
- auto_resize="true"
- width="108">
- <button
- follows="bottom|left|right"
- left="1"
- height="23"
- label="Group Profile"
- layout="topleft"
- mouse_opaque="false"
- name="group_info_btn"
- tool_tip="Show group information"
- top="0"
- width="107" />
- </layout_panel>
-
- <layout_panel
- follows="bottom|left|right"
- height="23"
- layout="bottomleft"
- left_pad="3"
- mouse_opaque="false"
- name="chat_btn_lp"
- auto_resize="true"
- width="101">
- <button
- follows="bottom|left|right"
- left="1"
- height="23"
- label="Group Chat"
- layout="topleft"
- mouse_opaque="false"
- name="chat_btn"
- tool_tip="Open chat session"
- top="0"
- width="100" />
- </layout_panel>
-
- <layout_panel
- follows="bottom|left|right"
- height="23"
- layout="bottomleft"
- left_pad="3"
- mouse_opaque="false"
- name="group_call_btn_lp"
- auto_resize="true"
- width="96">
- <button
- follows="bottom|left|right"
- left="1"
- height="23"
- label="Group Call"
- layout="topleft"
- mouse_opaque="false"
- name="group_call_btn"
- tool_tip="Call this group"
- top="0"
- width="95" />
- </layout_panel>
- </layout_stack>
- </panel>
+ <panel
+ background_opaque="true"
+ background_visible="true"
+ bg_alpha_color="DkGray"
+ bg_opaque_color="DkGray"
+ follows="all"
+ height="383"
+ label="BLOCKED"
+ layout="topleft"
+ left="0"
+ help_topic="people_blocked_tab"
+ name="blocked_panel"
+ right="-1"
+ top="0">
+ <panel
+ class="panel_block_list_sidetray"
+ height="383"
+ name="panel_block_list_sidetray"
+ filename="panel_block_list_sidetray.xml"
+ follows="all"
+ label="Blocked Residents &amp; Objects"
+ layout="topleft"
+ left="0"
+ font="SansSerifBold"
+ top="0"
+ right="-1" />
+ </panel>
+ </tab_container>
</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_pick_info.xml b/indra/newview/skins/default/xui/en/panel_pick_info.xml
index 79d190e1e0..79d190e1e0 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_pick_info.xml
+++ b/indra/newview/skins/default/xui/en/panel_pick_info.xml
diff --git a/indra/newview/skins/default/xui/en/panel_pick_list_item.xml b/indra/newview/skins/default/xui/en/panel_pick_list_item.xml
index 43d580844f..43d580844f 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_pick_list_item.xml
+++ b/indra/newview/skins/default/xui/en/panel_pick_list_item.xml
diff --git a/indra/newview/skins/default/xui/en/panel_picks.xml b/indra/newview/skins/default/xui/en/panel_picks.xml
index 8def96cada..8def96cada 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_picks.xml
+++ b/indra/newview/skins/default/xui/en/panel_picks.xml
diff --git a/indra/newview/skins/default/xui/en/panel_place_profile.xml b/indra/newview/skins/default/xui/en/panel_place_profile.xml
index 308acf0c0c..308acf0c0c 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_place_profile.xml
+++ b/indra/newview/skins/default/xui/en/panel_place_profile.xml
diff --git a/indra/newview/skins/default/xui/en/panel_places.xml b/indra/newview/skins/default/xui/en/panel_places.xml
index f169dbb702..f169dbb702 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_places.xml
+++ b/indra/newview/skins/default/xui/en/panel_places.xml
diff --git a/indra/newview/skins/default/xui/en/panel_postcard_message.xml b/indra/newview/skins/default/xui/en/panel_postcard_message.xml
index ab2a42ea01..ab2a42ea01 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_postcard_message.xml
+++ b/indra/newview/skins/default/xui/en/panel_postcard_message.xml
diff --git a/indra/newview/skins/default/xui/en/panel_postcard_settings.xml b/indra/newview/skins/default/xui/en/panel_postcard_settings.xml
index 3f67a48b14..3f67a48b14 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_postcard_settings.xml
+++ b/indra/newview/skins/default/xui/en/panel_postcard_settings.xml
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml b/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml
index b6985f911e..335f1614d8 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml
@@ -138,7 +138,7 @@
initial_value="1"
layout="topleft"
left_pad="0"
- max_val="1.4"
+ max_val="1.5"
min_val="0.75"
name="ui_scale_slider"
top_pad="-14"
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_alerts.xml b/indra/newview/skins/default/xui/en/panel_preferences_alerts.xml
index 714dca7fac..714dca7fac 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_preferences_alerts.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_alerts.xml
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
index caf7fc85f5..8e867259c5 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
@@ -1,219 +1,583 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<panel
- border="true"
- follows="left|top|right|bottom"
- height="408"
- label="Text Chat"
- layout="topleft"
- left="102"
- name="chat"
- top="1"
- width="517">
- <text
- follows="left|top"
- layout="topleft"
- left="30"
- height="12"
- name="font_size"
- width="120"
- top="10">
- Font size:
- </text>
- <radio_group
- height="30"
- layout="topleft"
- left="40"
- control_name="ChatFontSize"
- name="chat_font_size"
- top_pad="0"
- width="440">
- <radio_item
- height="16"
- label="Small"
- layout="topleft"
- left="0"
- name="radio"
- value="0"
- top="10"
- width="125" />
- <radio_item
- height="16"
- label="Medium"
- layout="topleft"
- left_delta="145"
- name="radio2"
- value="1"
- top_delta="0"
- width="125" />
- <radio_item
- height="16"
- label="Large"
- layout="topleft"
- left_delta="170"
- name="radio3"
- value="2"
- top_delta="0"
- width="125" />
- </radio_group>
-
+ border="true"
+ has_border="true"
+ height="408"
+ label="Text Chat"
+ layout="topleft"
+ left="102"
+ name="chat"
+ top="1"
+ width="517">
+
+ <panel
+ border="false"
+ height="60"
+ layout="topleft"
+ name="general_chat_settings"
+ top="10"
+ left="13"
+ width="517">
+
<check_box
- control_name="PlayTypingAnim"
- height="16"
- initial_value="true"
- label="Play typing animation when chatting"
- layout="topleft"
- left="30"
- name="play_typing_animation"
- top_pad="10"
- width="400" />
+ control_name="PlayTypingAnim"
+ height="16"
+ initial_value="true"
+ label="Play typing animation when chatting"
+ layout="topleft"
+ top="0"
+ name="play_typing_animation"
+ width="330">
+ </check_box>
+
<check_box
- enabled="false"
- height="16"
- label="Email me IMs when I'm offline"
- layout="topleft"
- left_delta="0"
- name="send_im_to_email"
- top_pad="5"
- width="400" />
+ enabled="false"
+ height="16"
+ label="Email me IMs when I'm offline"
+ layout="topleft"
+ name="send_im_to_email"
+ top_pad="6"
+ width="330">
+ </check_box>
+
<check_box
- enabled="false"
- height="16"
- label="Enable plain text IM and chat history"
- layout="topleft"
- left_delta="0"
- name="plain_text_chat_history"
- top_pad="5"
- width="400" />
+ control_name="VoiceCallsFriendsOnly"
+ height="16"
+ label="Only friends and groups can call or IM me"
+ layout="topleft"
+ name="voice_call_friends_only_check"
+ top_pad="6"
+ width="350">
+ </check_box>
+
+ <text
+ layout="topleft"
+ left="345"
+ height="12"
+ name="font_size"
+ width="120"
+ top="0">
+ Font size:
+ </text>
+
+ <combo_box
+ control_name="ChatFontSize"
+ height="23"
+ layout="topleft"
+ left="341"
+ name="chat_font_size"
+ top_pad="5"
+ width="100">
+ <item
+ label="Small"
+ name="Small"
+ value="0"/>
+ <item
+ label="Medium"
+ name="Medium"
+ value="1"/>
+ <item
+ label="Large"
+ name="Large"
+ value="2"/>
+ </combo_box>
+
+ <check_box
+ control_name="UseChatBubbles"
+ height="16"
+ label="Bubble Chat"
+ layout="topleft"
+ top_pad="4"
+ name="bubble_text_chat"
+ width="330">
+ </check_box>
+
+ </panel>
+
+ <panel
+ border="false"
+ height="165"
+ layout="topleft"
+ name="im_notification_settings"
+ left="13"
+ width="517">
+
+ <text
+ layout="topleft"
+ height="12"
+ name="friend_ims"
+ width="145"
+ left="0"
+ top_pad="13">
+ Friend IMs:
+ </text>
+ <combo_box
+ control_name="NotificationFriendIMOptions"
+ height="23"
+ layout="topleft"
+ left_pad="5"
+ top_delta="-6"
+ name="FriendIMOptions"
+ width="223">
+ <item
+ label="Open Conversations window"
+ name="OpenConversationsWindow"
+ value="openconversations"/>
+ <item
+ label="Pop up the message"
+ name="PopUpMessage"
+ value="toast"/>
+ <item
+ label="Flash toolbar button"
+ name="FlashToolbarButton"
+ value="flash"/>
+ <item
+ label="No action"
+ name="NoAction"
+ value="noaction"/>
+ </combo_box>
<check_box
- control_name="UseChatBubbles"
- follows="left|top"
- height="16"
- label="Bubble Chat"
- layout="topleft"
- left_delta="0"
- top_pad="5"
- name="bubble_text_chat"
- width="150" />
+ control_name="PlaySoundFriendIM"
+ height="23"
+ label="Play sound"
+ layout="topleft"
+ name="play_sound_friend_im"
+ left_pad="7"
+ top_delta="-3"
+ width="28">
+ </check_box>
<text
- name="show_ims_in_label"
- follows="left|top"
- layout="topleft"
- left="30"
- height="20"
- width="170"
- top_pad="15">
- Show IMs in:
+ layout="topleft"
+ height="12"
+ name="non_friend_ims"
+ width="145"
+ left="0"
+ top_pad="11">
+ Non-friend IMs:
</text>
+ <combo_box
+ control_name="NotificationNonFriendIMOptions"
+ height="23"
+ layout="topleft"
+ left_pad="5"
+ top_delta="-6"
+ name="NonFriendIMOptions"
+ width="223">
+ <item
+ label="Open Conversations window"
+ name="OpenConversationsWindow"
+ value="openconversations"/>
+ <item
+ label="Pop up the message"
+ name="PopUpMessage"
+ value="toast"/>
+ <item
+ label="Flash toolbar button"
+ name="FlashToolbarButton"
+ value="flash"/>
+ <item
+ label="No action"
+ name="NoAction"
+ value="noaction"/>
+ </combo_box>
+ <check_box
+ control_name="PlaySoundNonFriendIM"
+ height="23"
+ label="Play sound"
+ layout="topleft"
+ name="play_sound_non_friend_im"
+ left_pad="7"
+ top_delta="-3"
+ width="28">
+ </check_box>
<text
- name="requires_restart_label"
- follows="left|top"
- layout="topleft"
- top_delta="0"
- left="170"
- height="20"
- width="130"
- text_color="White_25">
- (requires restart)
- </text>
- <radio_group
- follows="left|top"
- height="30"
- left="40"
- control_name="ChatWindow"
- name="chat_window"
- top_pad="0"
- tool_tip="Show your Instant Messages in separate floaters, or in one floater with many tabs (Requires restart)"
- width="150">
- <radio_item
- height="16"
- label="Separate Windows"
- layout="topleft"
- left="0"
- name="radio"
- value="0"
- top="0"
- width="150" />
- <radio_item
- height="16"
- label="Tabs"
+ layout="topleft"
+ left="0"
+ height="13"
+ name="conference_ims"
+ width="145"
+ top_pad="11">
+ Conference IMs:
+ </text>
+ <combo_box
+ control_name="NotificationConferenceIMOptions"
+ height="23"
+ layout="topleft"
+ left_pad="5"
+ top_delta="-6"
+ name="ConferenceIMOptions"
+ width="223">
+ <item
+ label="Open Conversations window"
+ name="OpenConversationsWindow"
+ value="openconversations"/>
+ <item
+ label="Pop up the message"
+ name="PopUpMessage"
+ value="toast"/>
+ <item
+ label="Flash toolbar button"
+ name="FlashToolbarButton"
+ value="flash"/>
+ <item
+ label="No action"
+ name="NoAction"
+ value="noaction"/>
+ </combo_box>
+ <check_box
+ control_name="PlaySoundConferenceIM"
+ height="23"
+ label="Play sound"
+ layout="topleft"
+ name="play_sound_conference_im"
+ left_pad="7"
+ top_delta="-3"
+ width="28">
+ </check_box>
+ <text
+ layout="topleft"
+ left="0"
+ height="13"
+ name="group_chat"
+ width="145"
+ top_pad="11">
+ Group chat:
+ </text>
+ <combo_box
+ control_name="NotificationGroupChatOptions"
+ height="23"
+ layout="topleft"
+ left_pad="5"
+ top_delta="-6"
+ name="GroupChatOptions"
+ width="223">
+ <item
+ label="Open Conversations window"
+ name="OpenConversationsWindow"
+ value="openconversations"/>
+ <item
+ label="Pop up the message"
+ name="PopUpMessage"
+ value="toast"/>
+ <item
+ label="Flash toolbar button"
+ name="FlashToolbarButton"
+ value="flash"/>
+ <item
+ label="No action"
+ name="NoAction"
+ value="noaction"/>
+ </combo_box>
+ <check_box
+ control_name="PlaySoundGroupChatIM"
+ height="23"
+ label="Play sound"
+ layout="topleft"
+ name="play_sound_group_chat_im"
+ left_pad="7"
+ top_delta="-3"
+ width="28">
+ </check_box>
+ <text
+ layout="topleft"
+ left="0"
+ height="12"
+ name="nearby_chat"
+ width="145"
+ top_pad="11">
+ Nearby chat:
+ </text>
+ <combo_box
+ control_name="NotificationNearbyChatOptions"
+ height="23"
+ layout="topleft"
+ left_pad="5"
+ top_delta="-6"
+ name="NearbyChatOptions"
+ width="223">
+ <item
+ label="Open Conversations window"
+ name="OpenConversationsWindow"
+ value="openconversations"/>
+ <item
+ label="Pop up the message"
+ name="PopUpMessage"
+ value="toast"/>
+ <item
+ label="Flash toolbar button"
+ name="FlashToolBarButton"
+ value="flash"/>
+ <item
+ label="No action"
+ name="NoAction"
+ value="noaction"/>
+ </combo_box>
+ <check_box
+ control_name="PlaySoundNearbyChatIM"
+ height="23"
+ label="Play sound"
+ layout="topleft"
+ name="play_sound_nearby_chat_im"
+ left_pad="7"
+ top_delta="-3"
+ width="28">
+ </check_box>
+ <text
+ layout="topleft"
+ left="0"
+ height="12"
+ name="object_ims"
+ width="145"
+ top_pad="11">
+ Object IMs:
+ </text>
+ <combo_box
+ control_name="NotificationObjectIMOptions"
+ height="23"
+ layout="topleft"
+ left_pad="5"
+ top_delta="-6"
+ name="ObjectIMOptions"
+ width="223">
+ <item
+ label="Open Conversations window"
+ name="OpenConversationsWindow"
+ value="openconversations"/>
+ <item
+ label="Pop up the message"
+ name="PopUpMessage"
+ value="toast"/>
+ <item
+ label="Flash toolbar button"
+ name="FlashToolBarButton"
+ value="flash"/>
+ <item
+ label="No action"
+ name="NoAction"
+ value="noaction"/>
+ </combo_box>
+ <check_box
+ control_name="PlaySoundObjectIM"
+ height="23"
+ label="Play sound"
+ layout="topleft"
+ name="play_sound_object_im"
+ left_pad="7"
+ top_delta="-3"
+ width="28">
+ </check_box>
+ <text
+ layout="topleft"
+ left="0"
+ height="13"
+ name="notifications_alert"
+ width="500"
+ top_pad="9"
+ visible="true"
+ text_color="DrYellow">
+ To temporarily stop all notifications, use Communicate &gt; Do Not Disturb.
+ </text>
+
+ </panel>
+
+ <panel
+ border="false"
+ height="50"
layout="topleft"
- left_delta="0"
- name="radio2"
- value="1"
- top_pad="5"
- width="150" />
- </radio_group>
+ name="play_sound_settings"
+ left="13"
+ top_pad="10"
+ width="517">
+
<text
- name="disable_toast_label"
- follows="left|top"
- layout="topleft"
- top_pad="20"
- left="30"
- height="10"
- width="400">
- Enable incoming chat popups:
- </text>
+ layout="topleft"
+ left="0"
+ name="play_sound"
+ width="100"
+ top_pad="8"
+ visible="true">
+ Play sound:
+ </text>
+ <check_box
+ control_name="PlaySoundNewConversation"
+ height="16"
+ label="New conversation"
+ layout="topleft"
+ left_pad="15"
+ top_pad="-10"
+ name="new_conversation"
+ width="150" />
<check_box
- control_name="EnableGroupChatPopups"
- name="EnableGroupChatPopups"
- label="Group Chats"
- layout="topleft"
- top_pad="5"
- left_delta="10"
- height="20"
- tool_tip="Check to see popups when a Group Chat message arrives"
- width="400" />
+ control_name="PlaySoundIncomingVoiceCall"
+ height="16"
+ label="Incoming voice call"
+ layout="topleft"
+ top_pad="6"
+ name="incoming_voice_call"
+ width="150" />
<check_box
- control_name="EnableIMChatPopups"
- name="EnableIMChatPopups"
- label="IM Chats"
- layout="topleft"
- top_pad="5"
- height="16"
- tool_tip="Check to see popups when an instant message arrives"
- width="400" />
- <spinner
- control_name="NearbyToastLifeTime"
- decimal_digits="0"
- follows="left|top"
- height="23"
- increment="1"
- initial_value="23"
- label="Nearby chat toasts life time:"
- label_width="285"
- layout="topleft"
- left="45"
- max_val="60"
- min_val="1"
- name="nearby_toasts_lifetime"
- top_pad="10"
- width="325" />
- <spinner
- control_name="NearbyToastFadingTime"
- decimal_digits="0"
- follows="left|top"
- height="23"
- increment="1"
- initial_value="3"
- label="Nearby chat toasts fading time:"
- label_width="285"
- layout="topleft"
- left_delta="0"
- max_val="60"
- min_val="0"
- name="nearby_toasts_fadingtime"
- top_pad="3"
- width="325" />
+ control_name="PlaySoundTeleportOffer"
+ height="16"
+ label="Teleport offer"
+ layout="topleft"
+ left_pad="35"
+ top_pad="-38"
+ name="teleport_offer"
+ width="150" />
+ <check_box
+ control_name="PlaySoundInventoryOffer"
+ height="16"
+ label="Inventory offer"
+ layout="topleft"
+ top_pad="6"
+ name="inventory_offer"
+ width="150" />
+
+ </panel>
+
+ <view_border
+ bevel_style="none"
+ height="0"
+ layout="topleft"
+ left="13"
+ name="cost_text_border"
+ top_pad="5"
+ width="495"/>
+
+ <panel
+ height="50"
+ layout="topleft"
+ name="log_settings"
+ left="13"
+ top_pad="10"
+ width="505">
+
+ <text
+ layout="topleft"
+ left="0"
+ text_color="White"
+ height="12"
+ top="5"
+ width="55">
+ Save:
+ </text>
+
+ <combo_box
+ enabled="false"
+ control_name="KeepConversationLogTranscripts"
+ height="23"
+ layout="topleft"
+ left_pad="5"
+ name="chat_font_size"
+ top="0"
+ width="165">
+ <item
+ label="Log and transcripts"
+ value="2"/>
+ <item
+ label="Log only"
+ value="1"/>
+ <item
+ label="No log or transcripts"
+ value="0"/>
+ </combo_box>
+
+ <button
+ enabled="false"
+ height="23"
+ label="Clear log..."
+ layout="topleft"
+ left_pad="5"
+ top="0"
+ name="clear_log"
+ width="110">
+ <commit_callback
+ function="Pref.ClearLog" />
+ </button>
+
+ <button
+ enabled="false"
+ height="23"
+ label="Delete transcripts..."
+ layout="topleft"
+ left_pad="5"
+ top="0"
+ name="delete_transcripts"
+ width="147">
+ <button.commit_callback
+ function="Pref.DeleteTranscripts" />
+ </button>
+
+ <text
+ layout="topleft"
+ left="0"
+ text_color="White"
+ height="12"
+ top_pad="15"
+ width="55">
+ Location:
+ </text>
+
+ <line_editor
+ control_name="InstantMessageLogPath"
+ border_style="line"
+ border_thickness="1"
+ font="SansSerif"
+ height="23"
+ layout="topleft"
+ left_pad="55"
+ max_length="4096"
+ name="log_path_string"
+ top_delta="-5"
+ width="185">
+ </line_editor>
+
+ <button
+ enabled="false"
+ follows="left|top"
+ height="23"
+ label="Browse..."
+ label_selected="Browse"
+ layout="topleft"
+ left_pad="5"
+ name="log_path_button"
+ top_delta="0"
+ width="112">
+ <commit_callback function="Pref.LogPath" />
+ </button>
+
+ </panel>
+
+ <button
+ height="23"
+ label="Translation..."
+ layout="topleft"
+ left="9"
+ name="ok_btn"
+ top="-29"
+ width="170">
+ <commit_callback
+ function="Pref.TranslationSettings" />
+ </button>
<button
- follows="left|top"
- height="23"
- label="Chat Translation Settings"
- layout="topleft"
- left="30"
- name="ok_btn"
- top="-40"
- width="170">
- <button.commit_callback
- function="Pref.TranslationSettings" />
+ height="23"
+ layout="topleft"
+ top_pad="-23"
+ left_pad="5"
+ name="autoreplace_showgui"
+ commit_callback.function="Pref.AutoReplace"
+ label="Auto-Replace..."
+ width="150">
+ </button>
+ <button
+ height="23"
+ layout="topleft"
+ top_pad="-23"
+ left_pad="5"
+ name="spellcheck_showgui"
+ commit_callback.function="Pref.SpellChecker"
+ label="Spell Checking..."
+ width="150">
</button>
-</panel> \ No newline at end of file
+
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_colors.xml b/indra/newview/skins/default/xui/en/panel_preferences_colors.xml
index 2b22f0d6e3..9e825fe516 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_preferences_colors.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_colors.xml
@@ -362,7 +362,7 @@
follows="left|top"
height="16"
increment="0.01"
- initial_value="0.8"
+ initial_value="1.0"
layout="topleft"
label_width="115"
label="Active:"
@@ -380,7 +380,7 @@
follows="left|top"
height="16"
increment="0.01"
- initial_value="0.5"
+ initial_value="0.95"
layout="topleft"
label_width="115"
label="Inactive:"
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_general.xml b/indra/newview/skins/default/xui/en/panel_preferences_general.xml
index 24882988b0..ea0f7d8593 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_preferences_general.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_general.xml
@@ -409,10 +409,10 @@
name="text_box3"
top_pad="3"
width="240">
- Busy mode response:
+ Do Not Disturb response:
</text>
<text_editor
- control_name="BusyModeResponse"
+ control_name="DoNotDisturbModeResponse"
text_readonly_color="LabelDisabledColor"
bg_writeable_color="LtGray"
use_ellipses="false"
@@ -421,7 +421,7 @@
height="29"
layout="topleft"
left="30"
- name="busy_response"
+ name="do_not_disturb_response"
width="470"
word_wrap="true">
log_in_to_change
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
index f7666bdc4c..6c485c0595 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
@@ -47,7 +47,7 @@
Better
</text>
<icon
- color="0.12 0.12 0.12 1"
+ color="DkGray"
height="14"
image_name="Rounded_Square"
layout="topleft"
@@ -55,30 +55,56 @@
name="LowGraphicsDivet"
top_delta="-2"
width="2" />
+ <icon
+ color="DkGray"
+ height="14"
+ image_name="Rounded_Square"
+ layout="topleft"
+ left_pad="41"
+ name="LowMidGraphicsDivet"
+ width="2" />
<icon
- color="0.12 0.12 0.12 1"
+ color="DkGray"
height="14"
image_name="Rounded_Square"
layout="topleft"
- left_pad="83"
+ left_pad="41"
name="MidGraphicsDivet"
top_delta="0"
width="2" />
+ <icon
+ color="DkGray"
+ height="14"
+ image_name="Rounded_Square"
+ layout="topleft"
+ left_pad="41"
+ name="MidHighGraphicsDivet"
+ top_delta="0"
+ width="2" />
<icon
- color="0.12 0.12 0.12 1"
+ color="DkGray"
height="14"
image_name="Rounded_Square"
layout="topleft"
- left_pad="85"
+ left_pad="41"
name="HighGraphicsDivet"
top_delta="0"
width="2" />
+ <icon
+ color="DkGray"
+ height="14"
+ image_name="Rounded_Square"
+ layout="topleft"
+ left_pad="41"
+ name="HighUltraGraphicsDivet"
+ top_delta="0"
+ width="2" />
<icon
- color="0.12 0.12 0.12 1"
+ color="DkGray"
height="14"
image_name="Rounded_Square"
layout="topleft"
- left_pad="83"
+ left_pad="41"
name="UltraGraphicsDivet"
top_delta="0"
width="2" />
@@ -91,7 +117,7 @@
initial_value="0"
layout="topleft"
left="120"
- max_val="3"
+ max_val="6"
name="QualityPerformanceSelection"
show_text="false"
top_delta="-2"
@@ -151,10 +177,86 @@
width="80">
Ultra
</text>
+ <slider
+ control_name="RenderAvatarLODFactor"
+ invisiblity_control="ShowAdvancedGraphicsSettings"
+ follows="left|top"
+ height="16"
+ increment="0.125"
+ initial_value="160"
+ label="Avatar detail:"
+ label_width="90"
+ layout="topleft"
+ left="30"
+ name="AvatarMeshDetail2"
+ show_text="false"
+ top="72"
+ width="300">
+ <slider.commit_callback
+ function="Pref.UpdateSliderText"
+ parameter="AvatarMeshDetailText2" />
+ </slider>
+ <text
+ type="string"
+ invisiblity_control="ShowAdvancedGraphicsSettings"
+ length="1"
+ follows="left|top"
+ height="12"
+ layout="topleft"
+ name="AvatarMeshDetailText2"
+ top_delta="0"
+ left_delta="304"
+ width="128">
+ Low
+ </text>
+ <slider
+ control_name="RenderFarClip"
+ invisiblity_control="ShowAdvancedGraphicsSettings"
+ decimal_digits="0"
+ follows="left|top"
+ height="16"
+ increment="8"
+ initial_value="160"
+ label="Draw distance:"
+ label_width="90"
+ layout="topleft"
+ left="30"
+ max_val="512"
+ min_val="64"
+ name="DrawDistance"
+ top="110"
+ width="330" />
+ <text
+ type="string"
+ invisiblity_control="ShowAdvancedGraphicsSettings"
+ length="1"
+ follows="left|top"
+ height="12"
+ layout="topleft"
+ left_delta="330"
+ name="DrawDistanceMeterText2"
+ top_delta="0"
+ width="128">
+ m
+ </text>
+ <check_box
+ control_name="RenderDeferred"
+ invisiblity_control="ShowAdvancedGraphicsSettings"
+ height="16"
+ initial_value="true"
+ label="Advanced Lighting Model"
+ layout="topleft"
+ left="30"
+ name="UseLightShaders2"
+ top="148"
+ width="256">
+ <check_box.commit_callback
+ function="Pref.VertexShaderEnable" />
+ </check_box>
<panel
- visiblity_control="ShowAdvancedGraphicsSettings"
+ visiblity_control="ShowAdvancedGraphicsSettings"
border="false"
- follows="top|left"
+ follows="top|left"
height="300"
label="CustomGraphics"
layout="topleft"
@@ -184,24 +286,27 @@
name="TransparentWater"
top_pad="7"
width="256" />
- <check_box
- control_name="RenderObjectBump"
+ <check_box
+ control_name="RenderObjectBump"
+ height="16"
+ initial_value="true"
+ label="Bump mapping and shiny"
+ layout="topleft"
+ left_delta="0"
+ name="BumpShiny"
+ top_pad="1"
+ width="256">
+ <check_box.commit_callback
+ function="Pref.VertexShaderEnable" />
+ </check_box>
+ <check_box
+ control_name="RenderLocalLights"
height="16"
initial_value="true"
- label="Bump mapping and shiny"
+ label="Local Lights"
layout="topleft"
left_delta="0"
- name="BumpShiny"
- top_pad="1"
- width="256" />
- <check_box
- control_name="RenderLocalLights"
- height="16"
- initial_value="true"
- label="Local Lights"
- layout="topleft"
- left_delta="0"
- name="LocalLights"
+ name="LocalLights"
top_pad="1"
width="256" />
<check_box
@@ -235,7 +340,7 @@
control_name="RenderDeferred"
height="16"
initial_value="true"
- label="Lighting and Shadows"
+ label="Advanced Lighting Model"
layout="topleft"
left_delta="0"
name="UseLightShaders"
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_move.xml b/indra/newview/skins/default/xui/en/panel_preferences_move.xml
index d9067b41c7..8794e3bf95 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_preferences_move.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_move.xml
@@ -129,6 +129,16 @@
name="tap_tap_hold_to_run"
width="237"
top_pad="0"/>
+ <check_box
+ control_name="AutomaticFly"
+ follows="left|top"
+ height="20"
+ label="Hold jump or crouch key to start or stop flying"
+ layout="topleft"
+ left_delta="0"
+ name="automatic_fly"
+ width="237"
+ top_pad="0"/>
<text
follows="left|top"
type="string"
@@ -260,4 +270,4 @@
function="Floater.Show"
parameter="pref_joystick" />
</button>
-</panel> \ No newline at end of file
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml b/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml
index 587c461bee..78743d26bb 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml
@@ -1,72 +1,69 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<panel
- border="true"
- follows="left|top|right|bottom"
- height="408"
- label="Communication"
- layout="topleft"
- left="102"
- name="im"
- top="1"
- width="517">
- <panel.string
- name="log_in_to_change">
- log in to change
- </panel.string>
- <button
- follows="left|bottom"
- height="23"
- label="Clear History"
- tool_tip="Clear login image, last location, teleport history, web, and texture cache"
- layout="topleft"
- left="30"
- name="clear_cache"
- top="10"
- width="145">
- <button.commit_callback
- function="Pref.WebClearCache" />
- </button>
- <text
- type="string"
- length="1"
- follows="left|top"
- height="10"
- layout="topleft"
- left_pad="10"
- mouse_opaque="false"
- name="cache_size_label_l"
- top_delta="3"
- text_color="LtGray_50"
- width="300">
- (Locations, images, web, search history)
- </text>
- <check_box
- height="16"
- enabled="false"
- label="Show me in Search results"
- layout="topleft"
- left="30"
- name="online_searchresults"
- top_pad="20"
- width="350" />
- <check_box
- height="16"
- enabled="false"
- label="Only friends and groups know I'm online"
- layout="topleft"
- left="30"
- name="online_visibility"
- top_pad="30"
- width="350" />
- <check_box
- control_name="VoiceCallsFriendsOnly"
- height="16"
- label="Only friends and groups can call or IM me"
- layout="topleft"
- left="30"
- name="voice_call_friends_only_check"
- top_pad="10"
- width="350" />
+ border="true"
+ follows="left|top|right|bottom"
+ height="408"
+ label="Communication"
+ layout="topleft"
+ left="102"
+ name="im"
+ top="1"
+ width="517">
+
+ <panel.string
+ name="log_in_to_change">
+ log in to change
+ </panel.string>
+
+ <button
+ follows="left|bottom"
+ height="23"
+ label="Clear History"
+ tool_tip="Clear login image, last location, teleport history, web, and texture cache"
+ layout="topleft"
+ left="30"
+ name="clear_cache"
+ top="10"
+ width="145">
+ <button.commit_callback
+ function="Pref.WebClearCache" />
+ </button>
+
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_pad="10"
+ mouse_opaque="false"
+ name="cache_size_label_l"
+ top_delta="3"
+ text_color="LtGray_50"
+ width="300">
+ (Locations, images, web, search history)
+ </text>
+
+ <check_box
+ height="16"
+ enabled="false"
+ label="Show me in Search results"
+ layout="topleft"
+ left="30"
+ name="online_searchresults"
+ top_pad="20"
+ width="350" />
+
+ <check_box
+ height="16"
+ enabled="false"
+ label="Only friends and groups know I'm online"
+ layout="topleft"
+ left="30"
+ name="online_visibility"
+ top_pad="30"
+ width="350" />
+
<check_box
enabled_control="EnableVoiceChat"
control_name="AutoDisengageMic"
@@ -87,100 +84,7 @@
name="favorites_on_login_check"
top_pad="10"
width="350" />
- <text
- type="string"
- length="1"
- follows="left|top"
- height="10"
- layout="topleft"
- left="30"
- mouse_opaque="false"
- name="Logs:"
- top_pad="20"
- width="350">
- Chat Logs:
- </text>
- <check_box
- enabled="false"
- control_name="LogNearbyChat"
- height="16"
- label="Save nearby chat logs on my computer"
- layout="topleft"
- left="30"
- name="log_nearby_chat"
- top_pad="10"
- width="350">
- </check_box>
- <check_box
- enabled="false"
- control_name="LogInstantMessages"
- height="16"
- label="Save IM logs on my computer"
- layout="topleft"
- left="30"
- name="log_instant_messages"
- top_pad="10"
- width="350">
- </check_box>
- <check_box
- control_name="LogTimestamp"
- enabled="false"
- height="16"
- label="Add timestamp to each line in chat log"
- layout="topleft"
- left_delta="0"
- name="show_timestamps_check_im"
- top_pad="10"
- width="237" />
- <check_box
- control_name="LogFileNamewithDate"
- enabled="false"
- height="16"
- label="Add datestamp to log file name."
- layout="topleft"
- left_delta="5"
- name="logfile_name_datestamp"
- top_pad="10"
- width="350"/>
- <text
- type="string"
- length="1"
- follows="left|top"
- height="10"
- layout="topleft"
- left_delta="0"
- mouse_opaque="false"
- name="log_path_desc"
- top_pad="30"
- width="128">
- Location of logs:
- </text>
- <line_editor
- bottom="366"
- control_name="InstantMessageLogPath"
- follows="top|left|right"
- halign="right"
- height="23"
- layout="topleft"
- left_delta="0"
- mouse_opaque="false"
- name="log_path_string"
- top_pad="5"
- width="250"/>
- <button
- enabled="false"
- follows="right|bottom"
- height="23"
- label="Browse"
- label_selected="Browse"
- layout="topleft"
- left_pad="5"
- name="log_path_button"
- top_delta="0"
- width="145">
- <button.commit_callback
- function="Pref.LogPath" />
- </button>
+
<button
follows="left|bottom"
height="23"
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_setup.xml b/indra/newview/skins/default/xui/en/panel_preferences_setup.xml
index 4aeea8823e..dd4533ae74 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_preferences_setup.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_setup.xml
@@ -232,6 +232,18 @@
name="Install_manual"
value="0" />
</combo_box>
+ <check_box
+ top_delta="4"
+ enabled="true"
+ follows="left|top"
+ height="14"
+ control_name="UpdaterWillingToTest"
+ label="Willing to update to release candidates"
+ left_delta="0"
+ mouse_opaque="true"
+ name="update_willing_to_test"
+ width="400"
+ top_pad="5"/>
<text
type="string"
length="1"
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_sound.xml b/indra/newview/skins/default/xui/en/panel_preferences_sound.xml
index b71586aab1..b71586aab1 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_preferences_sound.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_sound.xml
diff --git a/indra/newview/skins/default/xui/en/panel_prim_media_controls.xml b/indra/newview/skins/default/xui/en/panel_prim_media_controls.xml
index 198ccd6e2f..8f90521bb2 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_prim_media_controls.xml
+++ b/indra/newview/skins/default/xui/en/panel_prim_media_controls.xml
@@ -315,7 +315,18 @@
<line_editor.commit_callback
function="MediaCtrl.CommitURL"/>
</line_editor>
- <layout_stack
+ <icon
+ name="media_secure_lock_flag"
+ height="16"
+ follows="top|left"
+ image_name="Lock2"
+ layout="topleft"
+ left_delta="2"
+ top_delta="2"
+ visible="false"
+ tool_tip="Secured Browsing"
+ width="16" />
+ <layout_stack
name="media_address_url_icons"
animate="false"
follows="top|right"
@@ -340,19 +351,6 @@
tool_tip="White List enabled"
width="16" />
</layout_panel>
- <layout_panel
- layout="topleft"
- width="16"
- mouse_opaque="false"
- auto_resize="false">
- <icon
- name="media_secure_lock_flag"
- height="16"
- image_name="Lock2"
- layout="topleft"
- tool_tip="Secured Browsing"
- width="16" />
- </layout_panel>
</layout_stack>
</layout_panel>
<layout_panel
diff --git a/indra/newview/skins/default/xui/en/panel_progress.xml b/indra/newview/skins/default/xui/en/panel_progress.xml
index 860caf2d21..860caf2d21 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_progress.xml
+++ b/indra/newview/skins/default/xui/en/panel_progress.xml
diff --git a/indra/newview/skins/default/xui/en/panel_region_covenant.xml b/indra/newview/skins/default/xui/en/panel_region_covenant.xml
index 112f12500d..112f12500d 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_region_covenant.xml
+++ b/indra/newview/skins/default/xui/en/panel_region_covenant.xml
diff --git a/indra/newview/skins/default/xui/en/panel_region_debug.xml b/indra/newview/skins/default/xui/en/panel_region_debug.xml
index 4550603134..81b2281adb 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_region_debug.xml
+++ b/indra/newview/skins/default/xui/en/panel_region_debug.xml
@@ -194,11 +194,11 @@
<button
follows="left|top"
height="20"
- label="Delay Restart"
+ label="Cancel Restart"
layout="topleft"
left_pad="155"
name="cancel_restart_btn"
- tool_tip="Delay region restart by one hour"
+ tool_tip="Cancel region restart"
top_delta="0"
width="150" />
</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_region_environment.xml b/indra/newview/skins/default/xui/en/panel_region_environment.xml
index aa38c49fae..aa38c49fae 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_region_environment.xml
+++ b/indra/newview/skins/default/xui/en/panel_region_environment.xml
diff --git a/indra/newview/skins/default/xui/en/panel_region_estate.xml b/indra/newview/skins/default/xui/en/panel_region_estate.xml
index bfd796a62b..76a82212ae 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_region_estate.xml
+++ b/indra/newview/skins/default/xui/en/panel_region_estate.xml
@@ -149,11 +149,11 @@
<check_box
follows="top|left"
height="16"
- label="Have been age-verified"
+ label="Are age 18 or older"
layout="topleft"
left_delta="0"
name="limit_age_verified"
- tool_tip="Residents must be age verified to access this estate. See the [SUPPORT_SITE] for more information."
+ tool_tip="Residents must be age 18 or older to access this estate. See the [SUPPORT_SITE] for more information."
top_pad="2"
width="278" />
diff --git a/indra/newview/skins/default/xui/en/panel_region_general.xml b/indra/newview/skins/default/xui/en/panel_region_general.xml
index 44c84e69a1..44c84e69a1 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_region_general.xml
+++ b/indra/newview/skins/default/xui/en/panel_region_general.xml
diff --git a/indra/newview/skins/default/xui/en/panel_region_terrain.xml b/indra/newview/skins/default/xui/en/panel_region_terrain.xml
index 5d060c0a0d..5d060c0a0d 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_region_terrain.xml
+++ b/indra/newview/skins/default/xui/en/panel_region_terrain.xml
diff --git a/indra/newview/skins/default/xui/en/panel_script_ed.xml b/indra/newview/skins/default/xui/en/panel_script_ed.xml
index f6a8af0973..bcdef96138 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_script_ed.xml
+++ b/indra/newview/skins/default/xui/en/panel_script_ed.xml
@@ -125,6 +125,10 @@
label="Search / Replace..."
layout="topleft"
name="Search / Replace..." />
+ <menu_item_call
+ label="Go to line..."
+ layout="topleft"
+ name="Go to line..." />
</menu>
<menu
top="0"
@@ -158,6 +162,7 @@
text_readonly_color="DkGray"
width="487"
show_line_numbers="true"
+ enable_tooltip_paste="true"
word_wrap="true">
Loading...
</text_editor>
diff --git a/indra/newview/skins/default/xui/en/panel_script_limits_my_avatar.xml b/indra/newview/skins/default/xui/en/panel_script_limits_my_avatar.xml
index 629d8567d1..629d8567d1 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_script_limits_my_avatar.xml
+++ b/indra/newview/skins/default/xui/en/panel_script_limits_my_avatar.xml
diff --git a/indra/newview/skins/default/xui/en/panel_script_limits_region_memory.xml b/indra/newview/skins/default/xui/en/panel_script_limits_region_memory.xml
index c5e8bf5803..c5e8bf5803 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_script_limits_region_memory.xml
+++ b/indra/newview/skins/default/xui/en/panel_script_limits_region_memory.xml
diff --git a/indra/newview/skins/default/xui/en/panel_script_question_toast.xml b/indra/newview/skins/default/xui/en/panel_script_question_toast.xml
new file mode 100755
index 0000000000..b0436bb6dc
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_script_question_toast.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<panel
+ background_opaque="false"
+ border_visible="false"
+ background_visible="true"
+ bg_alpha_color="PanelNotificationBackground"
+ bg_opaque_color="PanelNotificationBackground"
+ chrome="true"
+ height="270"
+ label="script_question_panel"
+ layout="topleft"
+ left="0"
+ name="panel_script_question_toast"
+ top="0"
+ width="305">
+ <text
+ follows="left|right|top"
+ font="SansSerifBold"
+ height="160"
+ layout="topleft"
+ left="10"
+ mouse_opaque="false"
+ name="top_info_message"
+ parse_highlights="true"
+ parse_urls="true"
+ text_color="NotifyCautionBoxColor"
+ top="10"
+ value=""
+ width="285"
+ wrap="true"/>
+ <panel
+ background_visible="false"
+ follows="left|right|top"
+ height="30"
+ label="buttons_panel"
+ layout="topleft"
+ name="buttons_panel"
+ top_pad="10"
+ width="285">
+ </panel>
+ <text
+ follows="all"
+ font="SansSerifBold"
+ height="55"
+ layout="topleft"
+ mouse_opaque="false"
+ name="bottom_info_message"
+ parse_highlights="true"
+ parse_urls="true"
+ text_color="NotifyCautionBoxColor"
+ top_pad="5"
+ value=""
+ width="285"
+ wrap="true"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_scrolling_param.xml b/indra/newview/skins/default/xui/en/panel_scrolling_param.xml
index a8cd380f20..a8cd380f20 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_scrolling_param.xml
+++ b/indra/newview/skins/default/xui/en/panel_scrolling_param.xml
diff --git a/indra/newview/skins/default/xui/en/panel_scrolling_param_base.xml b/indra/newview/skins/default/xui/en/panel_scrolling_param_base.xml
index 1351f75623..1351f75623 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_scrolling_param_base.xml
+++ b/indra/newview/skins/default/xui/en/panel_scrolling_param_base.xml
diff --git a/indra/newview/skins/default/xui/en/panel_side_tray_tab_caption.xml b/indra/newview/skins/default/xui/en/panel_side_tray_tab_caption.xml
index 557b04d281..557b04d281 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_side_tray_tab_caption.xml
+++ b/indra/newview/skins/default/xui/en/panel_side_tray_tab_caption.xml
diff --git a/indra/newview/skins/default/xui/en/panel_sidetray_home_tab.xml b/indra/newview/skins/default/xui/en/panel_sidetray_home_tab.xml
index 912f81f915..912f81f915 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_sidetray_home_tab.xml
+++ b/indra/newview/skins/default/xui/en/panel_sidetray_home_tab.xml
diff --git a/indra/newview/skins/default/xui/en/panel_snapshot_inventory.xml b/indra/newview/skins/default/xui/en/panel_snapshot_inventory.xml
index 71d808fa4b..71d808fa4b 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_snapshot_inventory.xml
+++ b/indra/newview/skins/default/xui/en/panel_snapshot_inventory.xml
diff --git a/indra/newview/skins/default/xui/en/panel_snapshot_local.xml b/indra/newview/skins/default/xui/en/panel_snapshot_local.xml
index 781ab17403..781ab17403 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_snapshot_local.xml
+++ b/indra/newview/skins/default/xui/en/panel_snapshot_local.xml
diff --git a/indra/newview/skins/default/xui/en/panel_snapshot_options.xml b/indra/newview/skins/default/xui/en/panel_snapshot_options.xml
index d2f29ade44..61c8c971c2 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_snapshot_options.xml
+++ b/indra/newview/skins/default/xui/en/panel_snapshot_options.xml
@@ -16,11 +16,11 @@
imgoverlay_label_space="10"
label="Post to My Profile Feed"
layout="topleft"
- left="10"
+ left_delta="0"
name="save_to_profile_btn"
pad_left="10"
right="-10"
- top="5">
+ top_pad="10">
<button.commit_callback
function="Snapshot.SaveToProfile" />
</button>
diff --git a/indra/newview/skins/default/xui/en/panel_snapshot_postcard.xml b/indra/newview/skins/default/xui/en/panel_snapshot_postcard.xml
index ebba292a93..ebba292a93 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_snapshot_postcard.xml
+++ b/indra/newview/skins/default/xui/en/panel_snapshot_postcard.xml
diff --git a/indra/newview/skins/default/xui/en/panel_snapshot_profile.xml b/indra/newview/skins/default/xui/en/panel_snapshot_profile.xml
index 0dd357aa1a..0dd357aa1a 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_snapshot_profile.xml
+++ b/indra/newview/skins/default/xui/en/panel_snapshot_profile.xml
diff --git a/indra/newview/skins/default/xui/en/panel_social_account.xml b/indra/newview/skins/default/xui/en/panel_social_account.xml
new file mode 100644
index 0000000000..d7235396fe
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_social_account.xml
@@ -0,0 +1,75 @@
+<panel
+ height="400"
+ width="304"
+ layout="topleft"
+ name="panel_social_account">
+ <string
+ name="facebook_connected"
+ value="You are connected to Facebook as:" />
+ <string
+ name="facebook_disconnected"
+ value="Not connected to Facebook" />
+ <text
+ layout="topleft"
+ length="1"
+ follows="top|left"
+ font="SansSerif"
+ height="16"
+ left="9"
+ name="account_caption_label"
+ top="21"
+ type="string">
+ Not connected to Facebook.
+ </text>
+ <text
+ layout="topleft"
+ top_pad="2"
+ length="1"
+ follows="top|left"
+ font="SansSerif"
+ height="16"
+ left="9"
+ name="account_name_label"
+ parse_urls="true"
+ type="string"/>
+ <panel
+ layout="topleft"
+ name="panel_buttons"
+ height="345"
+ left="9">
+ <button
+ layout="topleft"
+ follows="left|top"
+ top_pad="9"
+ visible="true"
+ height="23"
+ label="Connect..."
+ name="connect_btn"
+ width="210">
+ <commit_callback function="SocialSharing.Connect"/>
+ </button>
+
+ <button
+ layout="topleft"
+ follows="left|top"
+ top_delta="0"
+ height="23"
+ label="Disconnect"
+ name="disconnect_btn"
+ width="210"
+ visible="false">
+ <commit_callback function="SocialSharing.Disconnect"/>
+ </button>
+ <text
+ layout="topleft"
+ length="1"
+ follows="top|left"
+ height="16"
+ left="0"
+ name="account_learn_more_label"
+ top_pad="20"
+ type="string">
+ [http://community.secondlife.com/t5/English-Knowledge-Base/Second-Life-Share/ta-p/2149711 Learn about posting to Facebook]
+ </text>
+ </panel>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_social_photo.xml b/indra/newview/skins/default/xui/en/panel_social_photo.xml
new file mode 100644
index 0000000000..a55613b52a
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_social_photo.xml
@@ -0,0 +1,152 @@
+ <panel
+ height="400"
+ width="304"
+ layout="topleft"
+ name="panel_social_photo">
+ <layout_stack
+ layout="topleft"
+ border_size="0"
+ height="392"
+ follows="all"
+ orientation="vertical"
+ name="stack_photo"
+ top="8">
+ <layout_panel
+ name="snapshot_panel"
+ height="367">
+ <combo_box
+ control_name="SocialPhotoResolution"
+ follows="left|top"
+ top="6"
+ left="9"
+ name="resolution_combobox"
+ tool_tip="Image resolution"
+ height="21"
+ width="135">
+ <combo_box.item
+ label="Current Window"
+ name="CurrentWindow"
+ value="[i0,i0]" />
+ <combo_box.item
+ label="640x480"
+ name="640x480"
+ value="[i640,i480]" />
+ <combo_box.item
+ label="800x600"
+ name="800x600"
+ value="[i800,i600]" />
+ <combo_box.item
+ label="1024x768"
+ name="1024x768"
+ value="[i1024,i768]" />
+ </combo_box>
+ <text
+ follows="left|top"
+ font="SansSerifSmall"
+ height="14"
+ left="208"
+ length="1"
+ halign="right"
+ name="file_size_label"
+ top="9"
+ type="string"
+ width="50">
+ [SIZE] KB
+ </text>
+ <panel
+ height="150"
+ width="250"
+ visible="true"
+ name="thumbnail_placeholder"
+ top="33"
+ follows="left|top"
+ left="9">
+ </panel>
+ <button
+ follows="left|top"
+ height="23"
+ label="Refresh"
+ left="9"
+ top_pad="5"
+ name="new_snapshot_btn"
+ tool_tip="Click to refresh"
+ visible="true"
+ width="100" >
+ <button.commit_callback
+ function="SocialSharing.RefreshPhoto" />
+ </button>
+ <text
+ follows="left|top"
+ font="SansSerif"
+ text_color="EmphasisColor"
+ height="14"
+ top_pad="-19"
+ left_pad="-20"
+ length="1"
+ halign="center"
+ name="working_lbl"
+ translate="false"
+ type="string"
+ visible="true"
+ width="150">
+ Refreshing...
+ </text>
+ <text
+ length="1"
+ follows="top|left|right"
+ font="SansSerif"
+ height="16"
+ left="9"
+ name="caption_label"
+ top_pad="20"
+ type="string">
+ Comment (optional):
+ </text>
+ <text_editor
+ follows="left|top"
+ height="87"
+ width="250"
+ left="9"
+ length="1"
+ max_length="700"
+ name="photo_caption"
+ type="string"
+ word_wrap="true">
+ </text_editor>
+ <check_box
+ follows="left|top"
+ initial_value="true"
+ label="Include location in posting"
+ name="add_location_cb"
+ left="9"
+ height="16"
+ top_pad="8"/>
+ </layout_panel>
+ <layout_panel
+ name="photo_button_panel"
+ height="25">
+ <button
+ follows="left|top"
+ top="0"
+ left="9"
+ height="23"
+ label="Post"
+ name="post_photo_btn"
+ width="100">
+ <button.commit_callback
+ function="SocialSharing.SendPhoto" />
+ </button>
+ <button
+ follows="left|top"
+ height="23"
+ label="Cancel"
+ name="cancel_photo_btn"
+ left_pad="15"
+ top_delta="0"
+ width="100">
+ <button.commit_callback
+ function="SocialSharing.Cancel" />
+ </button>
+ </layout_panel>
+ </layout_stack>
+ </panel>
diff --git a/indra/newview/skins/default/xui/en/panel_social_place.xml b/indra/newview/skins/default/xui/en/panel_social_place.xml
new file mode 100644
index 0000000000..13e94f6998
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_social_place.xml
@@ -0,0 +1,132 @@
+ <panel
+ height="400"
+ width="304"
+ layout="topleft"
+ name="panel_social_place">
+ <layout_stack
+ layout="topleft"
+ border_size="0"
+ height="392"
+ follows="all"
+ orientation="vertical"
+ name="stack_place"
+ top="8">
+ <layout_panel
+ name="place_detail_panel"
+ height="181">
+ <text
+ length="1"
+ follows="top|left|right"
+ font="SansSerif"
+ height="16"
+ left="9"
+ name="place_caption_label"
+ top="13"
+ type="string">
+ Say something about where you are:
+ </text>
+ <text_editor
+ follows="top|left"
+ height="150"
+ width="250"
+ left="9"
+ length="1"
+ max_length="700"
+ name="place_caption"
+ type="string"
+ word_wrap="true">
+ </text_editor>
+ </layout_panel>
+ <layout_panel
+ name="place_map_panel"
+ height="186">
+ <panel
+ follows="left|top"
+ height="128"
+ width="128"
+ background_visible="true"
+ bg_opaque_color="Black"
+ bg_alpha_color="Black"
+ top="20"
+ left="9"
+ visible="true"
+ name="map_border">
+ </panel>
+ <loading_indicator
+ follows="left|top"
+ height="24"
+ width="24"
+ name="map_loading_indicator"
+ top="77"
+ left="61"
+ visible="true"/>
+ <icon
+ follows="left|top"
+ height="128"
+ width="128"
+ image_name="Map_Placeholder_Icon"
+ layout="topleft"
+ top="20"
+ left="9"
+ visible="true"
+ name="map_placeholder">
+ </icon>
+ <icon
+ follows="left|top"
+ height="128"
+ width="128"
+ image_name="Map_Placeholder_Icon"
+ layout="topleft"
+ top="20"
+ left="9"
+ visible="true"
+ name="map_default">
+ </icon>
+ <check_box
+ follows="left|top"
+ initial_value="false"
+ top_delta="8"
+ width="8"
+ label=""
+ name="add_place_view_cb"
+ left_pad="5"/>
+ <text
+ follows="left|top"
+ font="SansSerif"
+ height="32"
+ width="130"
+ word_wrap="true"
+ left_pad="12"
+ top_delta="-8"
+ type="string">
+ Include overhead view of location
+ </text>
+ </layout_panel>
+ <layout_panel
+ name="place_button_panel"
+ height="25">
+ <button
+ follows="left|top"
+ top="0"
+ left="9"
+ height="23"
+ label="Post"
+ name="post_place_btn"
+ width="100">
+ <button.commit_callback
+ function="SocialSharing.SendCheckin" />
+ </button>
+ <button
+ follows="left|top"
+ height="23"
+ label="Cancel"
+ name="cancel_place_btn"
+ left_pad="15"
+ top_delta="0"
+ width="100">
+ <button.commit_callback
+ function="SocialSharing.Cancel" />
+ </button>
+ </layout_panel>
+ </layout_stack>
+ </panel>
diff --git a/indra/newview/skins/default/xui/en/panel_social_status.xml b/indra/newview/skins/default/xui/en/panel_social_status.xml
new file mode 100644
index 0000000000..54cfa3f524
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_social_status.xml
@@ -0,0 +1,67 @@
+ <panel
+ height="400"
+ width="304"
+ layout="topleft"
+ name="panel_social_status">
+ <layout_stack
+ layout="topleft"
+ border_size="0"
+ height="392"
+ follows="all"
+ orientation="vertical"
+ name="stack_status"
+ top="8">
+ <layout_panel
+ name="status_detail_panel"
+ height="367">
+ <text
+ length="1"
+ follows="top|left|right"
+ font="SansSerif"
+ height="16"
+ left="9"
+ name="status_caption_label"
+ top="13"
+ type="string">
+ What's on your mind?
+ </text>
+ <text_editor
+ follows="left|top"
+ height="150"
+ width="250"
+ left="9"
+ length="1"
+ max_length="700"
+ name="status_message"
+ type="string"
+ word_wrap="true">
+ </text_editor>
+ </layout_panel>
+ <layout_panel
+ name="status_button_panel"
+ height="25">
+ <button
+ follows="left|top"
+ top="0"
+ left="9"
+ height="23"
+ label="Post"
+ name="post_status_btn"
+ width="100">
+ <button.commit_callback
+ function="SocialSharing.SendStatus" />
+ </button>
+ <button
+ follows="left|top"
+ height="23"
+ label="Cancel"
+ name="cancel_status_btn"
+ left_pad="15"
+ top_delta="0"
+ width="100">
+ <button.commit_callback
+ function="SocialSharing.Cancel" />
+ </button>
+ </layout_panel>
+ </layout_stack>
+ </panel>
diff --git a/indra/newview/skins/default/xui/en/panel_sound_devices.xml b/indra/newview/skins/default/xui/en/panel_sound_devices.xml
index 46cbc1e87f..46cbc1e87f 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_sound_devices.xml
+++ b/indra/newview/skins/default/xui/en/panel_sound_devices.xml
diff --git a/indra/newview/skins/default/xui/en/panel_stand_stop_flying.xml b/indra/newview/skins/default/xui/en/panel_stand_stop_flying.xml
index 07642946f8..07642946f8 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_stand_stop_flying.xml
+++ b/indra/newview/skins/default/xui/en/panel_stand_stop_flying.xml
diff --git a/indra/newview/skins/default/xui/en/panel_status_bar.xml b/indra/newview/skins/default/xui/en/panel_status_bar.xml
index 3aa34439f1..064ece6e4b 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_status_bar.xml
+++ b/indra/newview/skins/default/xui/en/panel_status_bar.xml
@@ -113,7 +113,7 @@
image_pressed="Pause_Press"
image_pressed_selected="Play_Press"
is_toggle="true"
- left_pad="15"
+ left_pad="5"
top="1"
name="media_toggle_btn"
tool_tip="Start/Stop All Media (Music, Video, Web pages)"
@@ -129,6 +129,5 @@
left_pad="5"
top="2"
name="volume_btn"
- tool_tip="Global Volume Control"
width="16" />
</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_sys_well_item.xml b/indra/newview/skins/default/xui/en/panel_sys_well_item.xml
index 007b73a4bc..007b73a4bc 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_sys_well_item.xml
+++ b/indra/newview/skins/default/xui/en/panel_sys_well_item.xml
diff --git a/indra/newview/skins/default/xui/en/panel_teleport_history.xml b/indra/newview/skins/default/xui/en/panel_teleport_history.xml
index 768efc2f3f..768efc2f3f 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_teleport_history.xml
+++ b/indra/newview/skins/default/xui/en/panel_teleport_history.xml
diff --git a/indra/newview/skins/default/xui/en/panel_teleport_history_item.xml b/indra/newview/skins/default/xui/en/panel_teleport_history_item.xml
index c5b0be0616..c5b0be0616 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_teleport_history_item.xml
+++ b/indra/newview/skins/default/xui/en/panel_teleport_history_item.xml
diff --git a/indra/newview/skins/default/xui/en/panel_toast.xml b/indra/newview/skins/default/xui/en/panel_toast.xml
index 37a904bca8..37a904bca8 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_toast.xml
+++ b/indra/newview/skins/default/xui/en/panel_toast.xml
diff --git a/indra/newview/skins/default/xui/en/panel_toolbar_view.xml b/indra/newview/skins/default/xui/en/panel_toolbar_view.xml
index 58911bed56..f5c559fe1d 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_toolbar_view.xml
+++ b/indra/newview/skins/default/xui/en/panel_toolbar_view.xml
@@ -93,11 +93,11 @@
left="0"
mouse_opaque="false"
tab_stop="false"
- name="stand_stop_flying_container"
+ name="state_management_buttons_container"
visible="false"
width="200"/>
</layout_panel>
- <layout_panel name="right_toolbar_panel"
+ <layout_panel name="right_toolbar_panel"
auto_resize="false"
height="500"
width="30"
diff --git a/indra/newview/skins/default/xui/en/panel_tools_texture.xml b/indra/newview/skins/default/xui/en/panel_tools_texture.xml
new file mode 100644
index 0000000000..426c0c4915
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_tools_texture.xml
@@ -0,0 +1,766 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ border="false"
+ follows="all"
+ height="420"
+ label="Texture"
+ layout="topleft"
+ left="0"
+ mouse_opaque="false"
+ help_topic="toolbox_texture_tab"
+ name="Texture"
+ top="0"
+ width="295">
+ <panel.string
+ name="string repeats per meter">
+ Repeats Per Meter
+ </panel.string>
+ <panel.string
+ name="string repeats per face">
+ Repeats Per Face
+ </panel.string>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left="10"
+ name="color label"
+ text_readonly_color="LabelDisabledColor"
+ top="6"
+ width="64">
+ Color
+ </text>
+ <!-- label is blank because control places it below the box -->
+ <color_swatch
+ can_apply_immediately="true"
+ follows="left|top"
+ height="45"
+ label=""
+ layout="topleft"
+ left="10"
+ name="colorswatch"
+ tool_tip="Click to open color picker"
+ top="20"
+ width="64" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_pad="15"
+ name="color trans"
+ text_readonly_color="LabelDisabledColor"
+ top="6"
+ width="110">
+ Transparency %
+ </text>
+ <spinner
+ decimal_digits="0"
+ follows="left|top"
+ height="19"
+ increment="2"
+ initial_value="0"
+ layout="topleft"
+ left_delta="0"
+ max_val="100"
+ name="ColorTrans"
+ top_pad="4"
+ width="80" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_pad="15"
+ name="glow label"
+ text_readonly_color="LabelDisabledColor"
+ top="6"
+ width="80">
+ Glow
+ </text>
+ <spinner
+ decimal_digits="2"
+ follows="left|top"
+ height="19"
+ initial_value="0"
+ layout="topleft"
+ left_delta="0"
+ name="glow"
+ top_pad="4"
+ width="80" />
+ <check_box
+ height="19"
+ label="Full Bright"
+ layout="topleft"
+ left="7"
+ name="checkbox fullbright"
+ top_pad="4"
+ width="81" />
+ <combo_box
+ height="23"
+ layout="topleft"
+ left="10"
+ name="combobox matmedia"
+ top_pad="5"
+ width="100">
+ <combo_box.item
+ label="Materials"
+ name="Materials"
+ value="Materials" />
+ <combo_box.item
+ label="Media"
+ name="Media"
+ value="Media" />
+ </combo_box>
+ <combo_box
+ height="23"
+ layout="topleft"
+ left_pad="10"
+ name="combobox mattype"
+ top_delta="0"
+ width="155">
+ <combo_box.item
+ label="Texture (diffuse)"
+ name="Texture (diffuse)"
+ value="Texture (diffuse)" />
+ <combo_box.item
+ label="Bumpiness (normal)"
+ name="Bumpiness (normal)"
+ value="Bumpiness (normal)" />
+ <combo_box.item
+ label="Shininess (specular)"
+ name="Shininess (specular)"
+ value="Shininess (specular)" />
+ </combo_box>
+ <texture_picker
+ can_apply_immediately="true"
+ default_image_name="Default"
+ fallback_image="materials_ui_x_24.png"
+ follows="left|top"
+ height="80"
+ label="Texture "
+ layout="topleft"
+ left="10"
+ name="texture control"
+ tool_tip="Click to choose a picture"
+ top_pad="8"
+ width="64" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_pad="10"
+ name="label alphamode"
+ text_readonly_color="LabelDisabledColor"
+ top_delta="0"
+ width="90">
+ Alpha mode
+ </text>
+ <combo_box
+ height="23"
+ layout="topleft"
+ left_delta="0"
+ name="combobox alphamode"
+ top_pad="4"
+ width="120">
+ <combo_box.item
+ label="None"
+ name="None"
+ value="None" />
+ <combo_box.item
+ label="Alpha blending"
+ name="Alpha blending"
+ value="Alpha blending" />
+ <combo_box.item
+ label="Alpha masking"
+ name="Alpha masking"
+ value="Alpha masking" />
+ <combo_box.item
+ label="Emissive mask"
+ name="Emissive mask"
+ value="Emissive mask" />
+ </combo_box>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="0"
+ name="label maskcutoff"
+ text_readonly_color="LabelDisabledColor"
+ top_pad="4"
+ width="90">
+ Mask cutoff
+ </text>
+ <spinner
+ decimal_digits="0"
+ min_val="0"
+ max_val="255"
+ follows="left|top"
+ height="19"
+ initial_value="55"
+ layout="topleft"
+ top_pad="4"
+ left_delta="0"
+ increment="1"
+ name="maskcutoff"
+ width="80" />
+ <texture_picker
+ allow_no_texture="true"
+ can_apply_immediately="true"
+ default_image_name="Default"
+ fallback_image="materials_ui_x_24.png"
+ follows="left|top"
+ height="80"
+ label="Texture "
+ layout="topleft"
+ left="10"
+ name="bumpytexture control"
+ tool_tip="Click to choose a picture"
+ top_delta="-55"
+ width="64" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_pad="10"
+ name="label bumpiness"
+ text_readonly_color="LabelDisabledColor"
+ top_delta="0"
+ width="90">
+ Bumpiness
+ </text>
+ <combo_box
+ height="23"
+ layout="topleft"
+ left_delta="0"
+ name="combobox bumpiness"
+ top_pad="4"
+ width="90">
+ <combo_box.item
+ label="None"
+ name="None"
+ value="None" />
+ <combo_box.item
+ label="Brightness"
+ name="Brightness"
+ value="Brightness" />
+ <combo_box.item
+ label="Darkness"
+ name="Darkness"
+ value="Darkness" />
+ <combo_box.item
+ label="woodgrain"
+ name="woodgrain"
+ value="woodgrain" />
+ <combo_box.item
+ label="bark"
+ name="bark"
+ value="bark" />
+ <combo_box.item
+ label="bricks"
+ name="bricks"
+ value="bricks" />
+ <combo_box.item
+ label="checker"
+ name="checker"
+ value="checker" />
+ <combo_box.item
+ label="concrete"
+ name="concrete"
+ value="concrete" />
+ <combo_box.item
+ label="crustytile"
+ name="crustytile"
+ value="crustytile" />
+ <combo_box.item
+ label="cutstone"
+ name="cutstone"
+ value="cutstone" />
+ <combo_box.item
+ label="discs"
+ name="discs"
+ value="discs" />
+ <combo_box.item
+ label="gravel"
+ name="gravel"
+ value="gravel" />
+ <combo_box.item
+ label="petridish"
+ name="petridish"
+ value="petridish" />
+ <combo_box.item
+ label="siding"
+ name="siding"
+ value="siding" />
+ <combo_box.item
+ label="stonetile"
+ name="stonetile"
+ value="stonetile" />
+ <combo_box.item
+ label="stucco"
+ name="stucco"
+ value="stucco" />
+ <combo_box.item
+ label="suction"
+ name="suction"
+ value="suction" />
+ <combo_box.item
+ label="weave"
+ name="weave"
+ value="weave" />
+ <!--
+ NORSPEC-182, ensure item doesn't show up in menu until it should
+ <combo_box.item
+ label="Use texture"
+ name="Use texture"
+ value="Use texture" />
+ -->
+ </combo_box>
+ <texture_picker
+ allow_no_texture="true"
+ can_apply_immediately="true"
+ default_image_name="Default"
+ fallback_image="materials_ui_x_24.png"
+ follows="left|top"
+ height="80"
+ label="Texture "
+ layout="topleft"
+ left="10"
+ name="shinytexture control"
+ tool_tip="Click to choose a picture"
+ top_delta="-14"
+ width="64" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ name="label shininess"
+ left_pad="10"
+ text_readonly_color="LabelDisabledColor"
+ top_delta="6"
+ width="90">
+ Shininess
+ </text>
+ <combo_box
+ height="23"
+ layout="topleft"
+ left_pad="10"
+ name="combobox shininess"
+ top_delta="-6"
+ width="90">
+ <combo_box.item
+ label="None"
+ name="None"
+ value="None" />
+ <combo_box.item
+ label="Low"
+ name="Low"
+ value="Low" />
+ <combo_box.item
+ label="Medium"
+ name="Medium"
+ value="Medium" />
+ <combo_box.item
+ label="High"
+ name="High"
+ value="High" />
+ <!--
+ NORSPEC-182, ensure item doesn't show up in menu until it should
+ <combo_box.item
+ label="Use texture"
+ name="Use texture"
+ value="Use texture" />
+ -->
+ </combo_box>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="-100"
+ name="label glossiness"
+ text_readonly_color="LabelDisabledColor"
+ top_pad="8"
+ width="116">
+ Glossiness
+ </text>
+ <spinner
+ decimal_digits="0"
+ min_val="0"
+ max_val="255"
+ follows="left|top"
+ height="19"
+ initial_value="51"
+ increment="1"
+ layout="topleft"
+ top_delta="-4"
+ left_pad="10"
+ name="glossiness"
+ width="64" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="-126"
+ name="label environment"
+ text_readonly_color="LabelDisabledColor"
+ top_pad="8"
+ width="116">
+ Environment
+ </text>
+ <spinner
+ decimal_digits="0"
+ min_val="0"
+ max_val="255"
+ increment="1"
+ follows="left|top"
+ height="19"
+ initial_value="0"
+ layout="topleft"
+ top_delta="-4"
+ left_pad="10"
+ name="environment"
+ width="64" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="-126"
+ name="label shinycolor"
+ text_readonly_color="LabelDisabledColor"
+ top_pad="8"
+ width="116">
+ Color
+ </text>
+ <!-- label is blank because control places it below the box -->
+ <color_swatch
+ can_apply_immediately="true"
+ follows="left|top"
+ height="45"
+ label=""
+ layout="topleft"
+ left_pad="10"
+ name="shinycolorswatch"
+ tool_tip="Click to open color picker"
+ top_delta="-4"
+ width="64" />
+ <text
+ follows="left|top|right"
+ height="9"
+ layout="topleft"
+ left="10"
+ top_delta="-50"
+ use_ellipses="true"
+ read_only="true"
+ name="media_info"
+ width="280">
+ URL of chosen media, if any, goes here
+ </text>
+ <button
+ follows="top|left"
+ height="18"
+ layout="topleft"
+ left="10"
+ name="add_media"
+ top_pad="4"
+ tool_tip="Add Media"
+ label="Choose..."
+ width="85">
+ <button.commit_callback
+ function="BuildTool.AddMedia"/>
+ </button>
+ <button
+ follows="top|left"
+ height="18"
+ layout="topleft"
+ left_pad="5"
+ name="delete_media"
+ tool_tip="Delete this media texture"
+ top_delta="0"
+ label="Remove"
+ width="85">
+ <button.commit_callback
+ function="BuildTool.DeleteMedia"/>
+ </button>
+ <button
+ follows="left|top"
+ height="18"
+ label="Align"
+ label_selected="Align Media"
+ layout="topleft"
+ left_pad="5"
+ name="button align"
+ top_delta="0"
+ tool_tip="Align media texture (must load first)"
+ width="85" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left="10"
+ name="tex gen"
+ text_readonly_color="LabelDisabledColor"
+ top_pad="60"
+ width="140">
+ Mapping
+ </text>
+ <combo_box
+ height="23"
+ layout="topleft"
+ left_pad="0"
+ name="combobox texgen"
+ top_pad="-13"
+ width="125">
+ <combo_box.item
+ label="Default"
+ name="Default"
+ value="Default" />
+ <combo_box.item
+ label="Planar"
+ name="Planar"
+ value="Planar" />
+ </combo_box>
+ <spinner
+ follows="left|top"
+ height="19"
+ initial_value="0"
+ label="Horizontal scale"
+ label_width="205"
+ layout="topleft"
+ left="10"
+ min_val="-100"
+ max_val="100"
+ name="TexScaleU"
+ top_pad="5"
+ width="265" />
+ <spinner
+ follows="left|top"
+ height="19"
+ initial_value="0"
+ label="Vertical scale"
+ label_width="205"
+ layout="topleft"
+ left="10"
+ min_val="-100"
+ max_val="100"
+ name="TexScaleV"
+ width="265" />
+ <spinner
+ decimal_digits="1"
+ follows="left|top"
+ height="19"
+ initial_value=""
+ label="Repeats per meter"
+ layout="topleft"
+ label_width="205"
+ left="10"
+ max_val="100"
+ min_val="0.1"
+ name="rptctrl"
+ width="265" />
+ <spinner
+ decimal_digits="2"
+ follows="left|top"
+ height="19"
+ increment="1"
+ initial_value="0"
+ label="Rotation degrees"
+ layout="topleft"
+ label_width="205"
+ left="10"
+ max_val="9999"
+ min_val="-9999"
+ name="TexRot"
+ width="265" />
+
+ <spinner
+ follows="left|top"
+ height="19"
+ initial_value="0"
+ label="Horizontal offset"
+ label_width="205"
+ layout="topleft"
+ left="10"
+ min_val="-1"
+ name="TexOffsetU"
+ width="265" />
+ <spinner
+ follows="left|top"
+ height="19"
+ initial_value="0"
+ label="Vertical offset"
+ label_width="205"
+ layout="topleft"
+ left="10"
+ min_val="-1"
+ name="TexOffsetV"
+ width="265" />
+ <spinner
+ follows="left|top"
+ height="19"
+ initial_value="0"
+ label="Horizontal scale"
+ label_width="205"
+ layout="topleft"
+ left="10"
+ min_val="-100"
+ max_val="100"
+ name="bumpyScaleU"
+ top_delta="-115"
+ width="265" />
+ <spinner
+ follows="left|top"
+ height="19"
+ initial_value="0"
+ label="Vertical scale"
+ label_width="205"
+ layout="topleft"
+ left="10"
+ min_val="-100"
+ max_val="100"
+ name="bumpyScaleV"
+ width="265" />
+ <spinner
+ decimal_digits="2"
+ follows="left|top"
+ height="19"
+ top_pad="27"
+ increment="1"
+ initial_value="0"
+ label="Rotation degrees"
+ layout="topleft"
+ label_width="205"
+ left="10"
+ max_val="360"
+ min_val="0"
+ name="bumpyRot"
+ width="265" />
+
+ <spinner
+ follows="left|top"
+ height="19"
+ initial_value="0"
+ label="Horizontal offset"
+ label_width="205"
+ layout="topleft"
+ left="10"
+ min_val="0"
+ name="bumpyOffsetU"
+ width="265" />
+ <spinner
+ follows="left|top"
+ height="19"
+ initial_value="0"
+ label="Vertical offset"
+ label_width="205"
+ layout="topleft"
+ left="10"
+ min_val="0"
+ name="bumpyOffsetV"
+ width="265" />
+ <spinner
+ follows="left|top"
+ height="19"
+ initial_value="0"
+ label="Horizontal scale"
+ label_width="205"
+ layout="topleft"
+ left="10"
+ min_val="-100"
+ max_val="100"
+ name="shinyScaleU"
+ top_delta="-115"
+ width="265" />
+ <spinner
+ follows="left|top"
+ height="19"
+ initial_value="0"
+ label="Vertical scale"
+ label_width="205"
+ layout="topleft"
+ left="10"
+ min_val="-100"
+ max_val="100"
+ name="shinyScaleV"
+ width="265" />
+ <spinner
+ decimal_digits="2"
+ follows="left|top"
+ height="19"
+ top_pad="27"
+ increment="1"
+ initial_value="0"
+ label="Rotation degrees"
+ layout="topleft"
+ label_width="205"
+ left="10"
+ max_val="360"
+ min_val="0"
+ name="shinyRot"
+ width="265" />
+
+ <spinner
+ follows="left|top"
+ height="19"
+ initial_value="0"
+ label="Horizontal offset"
+ label_width="205"
+ layout="topleft"
+ left="10"
+ min_val="0"
+ name="shinyOffsetU"
+ width="265" />
+ <spinner
+ follows="left|top"
+ height="19"
+ initial_value="0"
+ label="Vertical offset"
+ label_width="205"
+ layout="topleft"
+ left="10"
+ min_val="0"
+ name="shinyOffsetV"
+ width="265" />
+ <check_box
+ follows="top|left"
+ height="16"
+ initial_value="false"
+ label="Align planar faces"
+ layout="topleft"
+ left="7"
+ name="checkbox planar align"
+ tool_tip="Align textures on all selected faces with the last selected face. Requires Planar texture mapping."
+ top_delta="16"
+ width="260" />
+ <web_browser
+ visible="false"
+ enabled="false"
+ border_visible="true"
+ bottom_delta="0"
+ follows="top|left"
+ left="0"
+ name="title_media"
+ width="4"
+ height="4"
+ start_url="about:blank"
+ decouple_texture_size="true" />
+ </panel>
diff --git a/indra/newview/skins/default/xui/en/panel_topinfo_bar.xml b/indra/newview/skins/default/xui/en/panel_topinfo_bar.xml
index fc527f5f9d..fc527f5f9d 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_topinfo_bar.xml
+++ b/indra/newview/skins/default/xui/en/panel_topinfo_bar.xml
diff --git a/indra/newview/skins/default/xui/en/panel_voice_effect.xml b/indra/newview/skins/default/xui/en/panel_voice_effect.xml
index 93e79b7328..93e79b7328 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_voice_effect.xml
+++ b/indra/newview/skins/default/xui/en/panel_voice_effect.xml
diff --git a/indra/newview/skins/default/xui/en/panel_volume_pulldown.xml b/indra/newview/skins/default/xui/en/panel_volume_pulldown.xml
index 7b22b2cce1..6adede0362 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_volume_pulldown.xml
+++ b/indra/newview/skins/default/xui/en/panel_volume_pulldown.xml
@@ -8,41 +8,289 @@
border="false"
chrome="true"
follows="bottom"
- height="150"
+ height="155"
layout="topleft"
name="volumepulldown_floater"
- width="32">
- <slider
- control_name="AudioLevelMaster"
- follows="left|top"
- left="0"
- top="1"
- orientation="vertical"
- height="120"
- increment="0.05"
- initial_value="0.5"
- layout="topleft"
- name="mastervolume"
- show_text="false"
- slider_label.halign="right"
- top_pad="2"
- volume="true">
- <slider.commit_callback
- function="Vol.setControlFalse"
- parameter="MuteAudio" />
- </slider>
- <button
- left="10"
- top_pad="9"
- width="12"
- height="12"
- follows="top|left"
- name="prefs_btn"
- image_unselected="Icon_Gear_Foreground"
- image_disabled="Icon_Gear_Background"
- image_pressed="Icon_Gear_Press"
- scale_image="false">
- <button.commit_callback
- function="Vol.GoAudioPrefs" />
- </button>
+ width="225">
+ <slider
+ control_name="AudioLevelMaster"
+ follows="top|left"
+ font.style="BOLD"
+ height="15"
+ increment="0.025"
+ initial_value="0.5"
+ label="Master"
+ label_width="60"
+ left="10"
+ width="160"
+ layout="topleft"
+ name="System Volume"
+ show_text="false"
+ top="10"
+ volume="true">
+ <slider.commit_callback
+ function="Pref.setControlFalse"
+ parameter="MuteAudio" />
+ </slider>
+ <button
+ control_name="MuteAudio"
+ follows="top|left"
+ height="16"
+ image_selected="AudioMute_Off"
+ image_unselected="Audio_Off"
+ is_toggle="true"
+ layout="topleft"
+ left_pad="5"
+ name="mute_audio"
+ tab_stop="false"
+ width="16" />
+ <slider
+ control_name="AudioLevelUI"
+ disabled_control="MuteAudio"
+ follows="left|top"
+ height="15"
+ increment="0.025"
+ initial_value="0.5"
+ label="Buttons"
+ label_width="60"
+ left="10"
+ width="160"
+ layout="topleft"
+ name="UI Volume"
+ show_text="false"
+ top_pad="4"
+ volume="true">
+ <slider.commit_callback
+ function="Pref.setControlFalse"
+ parameter="MuteUI" />
+ </slider>
+ <button
+ control_name="MuteUI"
+ disabled_control="MuteAudio"
+ follows="top|left"
+ height="16"
+ image_selected="AudioMute_Off"
+ image_unselected="Audio_Off"
+ is_toggle="true"
+ layout="topleft"
+ left_pad="5"
+ name="mute_audio"
+ tab_stop="false"
+ width="16" />
+ <slider
+ control_name="AudioLevelAmbient"
+ disabled_control="MuteAudio"
+ follows="left|top"
+ height="15"
+ increment="0.025"
+ initial_value="0.5"
+ label="Ambient"
+ label_width="60"
+ left="10"
+ width="160"
+ layout="topleft"
+ name="Wind Volume"
+ show_text="false"
+ top_pad="4"
+ volume="true">
+ <slider.commit_callback
+ function="Pref.setControlFalse"
+ parameter="MuteAmbient" />
+ </slider>
+ <button
+ control_name="MuteAmbient"
+ disabled_control="MuteAudio"
+ follows="top|left"
+ height="16"
+ image_selected="AudioMute_Off"
+ image_unselected="Audio_Off"
+ is_toggle="true"
+ layout="topleft"
+ left_pad="5"
+ name="mute_audio"
+ tab_stop="false"
+ width="16" />
+ <slider
+ control_name="AudioLevelSFX"
+ disabled_control="MuteAudio"
+ follows="left|top"
+ height="15"
+ increment="0.025"
+ initial_value="0.5"
+ label="Sounds"
+ label_width="60"
+ left="10"
+ width="160"
+ layout="topleft"
+ name="SFX Volume"
+ show_text="false"
+ top_pad="4"
+ volume="true">
+ <slider.commit_callback
+ function="Pref.setControlFalse"
+ parameter="MuteSounds" />
+ </slider>
+ <button
+ control_name="MuteSounds"
+ disabled_control="MuteAudio"
+ follows="top|left"
+ height="16"
+ image_selected="AudioMute_Off"
+ image_unselected="Audio_Off"
+ is_toggle="true"
+ layout="topleft"
+ left_pad="5"
+ name="mute_audio"
+ tab_stop="false"
+ width="16">
+ <button.commit_callback
+ function="Pref.SetSounds"/>
+ </button>
+ <check_box
+ name="gesture_audio_play_btn"
+ control_name="EnableGestureSounds"
+ disabled_control="MuteAudio"
+ height="16"
+ layout="topleft"
+ left_pad="5"
+ tool_tip="Enable sounds from gestures"
+ top_delta="2"
+ width="350"/>
+ <slider
+ control_name="AudioLevelMusic"
+ disabled_control="MuteAudio"
+ follows="left|top"
+ height="15"
+ increment="0.025"
+ initial_value="0.5"
+ label="Music"
+ label_width="60"
+ left="10"
+ width="160"
+ layout="topleft"
+ name="Music Volume"
+ show_text="false"
+ top_pad="4"
+ volume="true">
+ <slider.commit_callback
+ function="Pref.setControlFalse"
+ parameter="MuteMusic" />
+ </slider>
+ <button
+ control_name="MuteMusic"
+ disabled_control="MuteAudio"
+ follows="top|left"
+ height="16"
+ image_selected="AudioMute_Off"
+ image_unselected="Audio_Off"
+ is_toggle="true"
+ layout="topleft"
+ left_pad="5"
+ name="mute_audio"
+ tab_stop="false"
+ width="16" />
+ <check_box
+ control_name="AudioStreamingMusic"
+ height="16"
+ tool_tip="Enable Streaming Music"
+ layout="topleft"
+ left_pad="5"
+ name="enable_music"
+ top_delta="2"
+ width="350">
+ <check_box.commit_callback
+ function="Pref.updateMediaAutoPlayCheckbox"/>
+ </check_box>
+ <slider
+ control_name="AudioLevelMedia"
+ disabled_control="MuteAudio"
+ follows="left|top"
+ height="16"
+ increment="0.025"
+ initial_value="0.5"
+ label="Media"
+ label_width="60"
+ left="10"
+ width="160"
+ layout="topleft"
+ name="Media Volume"
+ show_text="false"
+ top_pad="4"
+ volume="true">
+ <slider.commit_callback
+ function="Pref.setControlFalse"
+ parameter="MuteMedia" />
+ </slider>
+ <button
+ control_name="MuteMedia"
+ disabled_control="MuteAudio"
+ follows="top|left"
+ height="16"
+ image_selected="AudioMute_Off"
+ image_unselected="Audio_Off"
+ is_toggle="true"
+ layout="topleft"
+ left_pad="5"
+ name="mute_audio"
+ tab_stop="false"
+ width="16" />
+ <check_box
+ label_text.halign="left"
+ follows="left|top"
+ height="16"
+ control_name ="AudioStreamingMedia"
+ tool_tip="Enable Streaming Media"
+ layout="topleft"
+ top_delta="2"
+ left_pad="5"
+ name="enable_media"
+ width="110">
+ <check_box.commit_callback
+ function="Pref.updateMediaAutoPlayCheckbox"/>
+ </check_box>
+ <slider
+ control_name="AudioLevelVoice"
+ disabled_control="MuteAudio"
+ follows="left|top"
+ height="16"
+ increment="0.025"
+ initial_value="0.5"
+ label="Voice"
+ label_width="60"
+ left="10"
+ width="160"
+ layout="topleft"
+ top_pad="4"
+ name="Voice Volume"
+ show_text="false"
+ volume="true">
+ <slider.commit_callback
+ function="Pref.setControlFalse"
+ parameter="MuteVoice" />
+ </slider>
+ <button
+ control_name="MuteVoice"
+ disabled_control="MuteAudio"
+ follows="top|left"
+ height="16"
+ image_selected="AudioMute_Off"
+ image_unselected="Audio_Off"
+ is_toggle="true"
+ layout="topleft"
+ left_pad="5"
+ name="mute_audio"
+ tab_stop="false"
+ width="16" />
+ <check_box
+ label_text.halign="left"
+ follows="left|top"
+ height="16"
+ control_name ="EnableVoiceChat"
+ disabled_control="CmdLineDisableVoice"
+ tool_tip="Enable Voice Chat"
+ layout="topleft"
+ top_delta="2"
+ left_pad="5"
+ name="enable_voice_check"
+ width="110"/>
</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_world_map.xml b/indra/newview/skins/default/xui/en/panel_world_map.xml
index 16860a6117..16860a6117 100644..100755
--- a/indra/newview/skins/default/xui/en/panel_world_map.xml
+++ b/indra/newview/skins/default/xui/en/panel_world_map.xml
diff --git a/indra/newview/skins/default/xui/en/role_actions.xml b/indra/newview/skins/default/xui/en/role_actions.xml
index 89aef57cca..0eeccbeac5 100644..100755
--- a/indra/newview/skins/default/xui/en/role_actions.xml
+++ b/indra/newview/skins/default/xui/en/role_actions.xml
@@ -70,8 +70,8 @@
longdescription="Toggle &apos;Show Place in Search&apos; and setting a parcel&apos;s category in About Land &gt; Options tab."
name="land find places" value="17" />
<action
- description="Change parcel name, description, and &apos;Show Place in Search&apos; settings"
- longdescription="Change parcel name, description, and &apos;Show Place in Search&apos; settings. This is done in About Land &gt; Options tab."
+ description="Change parcel name, description, and &apos;Moderate Content&apos; settings"
+ longdescription="Change parcel name, description, and &apos;Moderate Content&apos; settings. This is done in About Land &gt; Options tab."
name="land change identity" value="18" />
<action description="Set landing point and set teleport routing"
longdescription="On a group-owned parcel, Members in a Role with this Ability can set a landing point to specify where incoming teleports arrive, and also set teleport routing for further control. This is done in About Land &gt; Options tab."
diff --git a/indra/newview/skins/default/xui/en/sidepanel_appearance.xml b/indra/newview/skins/default/xui/en/sidepanel_appearance.xml
index 1d98a84e25..1d98a84e25 100644..100755
--- a/indra/newview/skins/default/xui/en/sidepanel_appearance.xml
+++ b/indra/newview/skins/default/xui/en/sidepanel_appearance.xml
diff --git a/indra/newview/skins/default/xui/en/sidepanel_inventory.xml b/indra/newview/skins/default/xui/en/sidepanel_inventory.xml
index 6ecb57b41d..14bd349480 100644..100755
--- a/indra/newview/skins/default/xui/en/sidepanel_inventory.xml
+++ b/indra/newview/skins/default/xui/en/sidepanel_inventory.xml
@@ -48,7 +48,7 @@
height="300"
width="330" />
</layout_panel>
- <layout_panel
+ <layout_panel
width="330"
layout="topleft"
auto_resize="false"
diff --git a/indra/newview/skins/default/xui/en/sidepanel_item_info.xml b/indra/newview/skins/default/xui/en/sidepanel_item_info.xml
index 54a312bd59..c5dfb703e5 100644..100755
--- a/indra/newview/skins/default/xui/en/sidepanel_item_info.xml
+++ b/indra/newview/skins/default/xui/en/sidepanel_item_info.xml
@@ -11,6 +11,10 @@
name="unknown">
(unknown)
</panel.string>
+ <panel.string
+ name="unknown_multiple">
+ (unknown / multiple)
+ </panel.string>
<panel.string
name="public">
(public)
diff --git a/indra/newview/skins/default/xui/en/sidepanel_task_info.xml b/indra/newview/skins/default/xui/en/sidepanel_task_info.xml
index 6600339ad7..6ee8fc3a4c 100644..100755
--- a/indra/newview/skins/default/xui/en/sidepanel_task_info.xml
+++ b/indra/newview/skins/default/xui/en/sidepanel_task_info.xml
@@ -31,6 +31,14 @@
You can't modify these objects
</panel.string>
<panel.string
+ name="text modify info 5">
+ You can't modify this object across a region boundary
+ </panel.string>
+ <panel.string
+ name="text modify info 6">
+ You can't modify these objects across a region boundary
+ </panel.string>
+ <panel.string
name="text modify warning">
This object has linked parts
</panel.string>
@@ -267,23 +275,27 @@
<combo_box.item
label="Touch (default)"
name="Touch/grab(default)"
- value="Touch/grab (default)" />
+ value="Touch" />
<combo_box.item
label="Sit on object"
name="Sitonobject"
- value="Sit on object" />
+ value="Sit" />
<combo_box.item
label="Buy object"
name="Buyobject"
- value="Buy object" />
+ value="Buy" />
<combo_box.item
label="Pay object"
name="Payobject"
- value="Pay object" />
+ value="Pay" />
<combo_box.item
label="Open"
name="Open"
value="Open" />
+ <combo_box.item
+ label="Zoom"
+ name="Zoom"
+ value="Zoom" />
</combo_box>
<panel
border="false"
@@ -300,7 +312,7 @@
<text
type="string"
length="1"
- left="10"
+ left="5"
top_pad="15"
text_color="EmphasisColor"
height="15"
@@ -448,9 +460,27 @@
tool_tip="Let people see this object in search results" />
<text
type="string"
+ follows="left|top"
+ name="pathfinding_attributes_label"
+ top_pad="6"
+ width="150"
+ left="5">
+ Pathfinding attributes:
+ </text>
+ <text
+ type="string"
+ follows="left|top"
text_color="EmphasisColor"
+ name="pathfinding_attributes_value"
+ width="130"
+ word_wrap="false"
+ left_pad="0">
+ </text>
+ <text
+ type="string"
+ text_color="EmphasisColor"
length="1"
- top_pad="15"
+ top_pad="10"
follows="left|top"
layout="topleft"
left="10"
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index 4ccec4838a..7e79d297ef 100644..100755
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -59,8 +59,9 @@
<string name="LoginFailedNoNetwork">Network error: Could not establish connection, please check your network connection.</string>
<string name="LoginFailed">Login failed.</string>
<string name="Quit">Quit</string>
- <string name="create_account_url">http://join.secondlife.com/</string>
+ <string name="create_account_url">http://join.secondlife.com/?sourceid=[sourceid]</string>
+ <string name="ViewerDownloadURL">http://secondlife.com/download</string>
<string name="LoginFailedViewerNotPermitted">
The viewer you are using can no longer access Second Life. Please visit the following page to download a new viewer:
http://secondlife.com/download
@@ -147,6 +148,14 @@ Please try logging in again in a minute.</string>
<string name="SentToInvalidRegion">You were sent to an invalid region.</string>
<string name="TestingDisconnect">Testing viewer disconnect</string>
+ <!-- Facebook Connect and, eventually, other Social Network -->
+ <string name="SocialFacebookConnecting">Connecting to Facebook...</string>
+ <string name="SocialFacebookPosting">Posting...</string>
+ <string name="SocialFacebookDisconnecting">Disconnecting from Facebook...</string>
+ <string name="SocialFacebookErrorConnecting">Problem connecting to Facebook</string>
+ <string name="SocialFacebookErrorPosting">Problem posting to Facebook</string>
+ <string name="SocialFacebookErrorDisconnecting">Problem disconnecting from Facebook</string>
+
<!-- Tooltip -->
<string name="TooltipPerson">Person</string><!-- Object under mouse pointer is an avatar -->
<string name="TooltipNoName">(no name)</string> <!-- No name on an object -->
@@ -208,7 +217,8 @@ Please try logging in again in a minute.</string>
<string name="SLappAgentIM">IM</string>
<string name="SLappAgentPay">Pay</string>
<string name="SLappAgentOfferTeleport">Offer Teleport to </string>
- <string name="SLappAgentRequestFriend">Friend Request </string>
+ <string name="SLappAgentRequestFriend">Friend Request</string>
+ <string name="SLappAgentRemoveFriend">Friend Removal</string>
<!-- ButtonToolTips, llfloater.cpp -->
<string name="BUTTON_CLOSE_DARWIN">Close (&#8984;W)</string>
@@ -295,7 +305,7 @@ Please try logging in again in a minute.</string>
<!-- llvoavatar. Displayed in the avatar chat bubble -->
<string name="AvatarEditingAppearance">(Editing Appearance)</string>
<string name="AvatarAway">Away</string>
- <string name="AvatarBusy">Busy</string>
+ <string name="AvatarDoNotDisturb">Do Not Disturb</string>
<string name="AvatarMuted">Blocked</string>
<!-- animations -->
@@ -372,10 +382,12 @@ Please try logging in again in a minute.</string>
<!-- build floater -->
<string name="multiple_textures">Multiple</string>
+<string name="use_texture">Use texture</string>
+
<!-- world map -->
<string name="texture_loading">Loading...</string>
<string name="worldmap_offline">Offline</string>
- <string name="worldmap_item_tooltip_format">[AREA] m² L$[PRICE]</string>
+ <string name="worldmap_item_tooltip_format">[AREA] m² L$[PRICE] ([SQMPRICE] L$/m²)</string>
<string name="worldmap_results_none_found">None found.</string>
<!-- animations uploading status codes -->
@@ -384,6 +396,8 @@ Please try logging in again in a minute.</string>
<string name="ST_NO_JOINT">Can't find ROOT or JOINT.</string>
<!-- Chat -->
+ <string name="NearbyChatTitle">Nearby chat</string>
+ <string name="NearbyChatLabel">(Nearby chat)</string>
<string name="whisper">whispers:</string>
<string name="shout">shouts:</string>
<string name="ringing">Connecting to in-world Voice Chat...</string>
@@ -393,6 +407,7 @@ Please try logging in again in a minute.</string>
<string name="reconnect_nearby">You will now be reconnected to Nearby Voice Chat</string>
<string name="ScriptQuestionCautionChatGranted">'[OBJECTNAME]', an object owned by '[OWNERNAME]', located in [REGIONNAME] at [REGIONPOS], has been granted permission to: [PERMISSIONS].</string>
<string name="ScriptQuestionCautionChatDenied">'[OBJECTNAME]', an object owned by '[OWNERNAME]', located in [REGIONNAME] at [REGIONPOS], has been denied permission to: [PERMISSIONS].</string>
+ <string name="AdditionalPermissionsRequestHeader">If you allow access to your account, you will also be allowing the object to:</string>
<string name="ScriptTakeMoney">Take Linden dollars (L$) from you</string>
<string name="ActOnControlInputs">Act on your control inputs</string>
<string name="RemapControlInputs">Remap your control inputs</string>
@@ -403,9 +418,18 @@ Please try logging in again in a minute.</string>
<string name="AddAndRemoveJoints">Add and remove joints with other objects</string>
<string name="ChangePermissions">Change its permissions</string>
<string name="TrackYourCamera">Track your camera</string>
- <string name="ControlYourCamera">Control your camera</string>
- <string name="TeleportYourAgent">Teleport you</string>
- <string name="NotConnected">Not Connected</string>
+ <string name="ControlYourCamera">Control your camera</string>
+ <string name="TeleportYourAgent">Teleport you</string>
+ <string name="ManageEstateSilently">Manage your estates silently</string>
+ <string name="ChangeYourDefaultAnimations">Change your default animations</string>
+
+ <string name="NotConnected">Not Connected</string>
+ <string name="AgentNameSubst">(You)</string> <!-- Substitution for agent name -->
+ <string name="JoinAnExperience">Join an experience</string> <!-- not used -->
+ <string name="SilentlyManageEstateAccess">Suppress alerts when managing estate access lists</string>
+ <string name="OverrideYourAnimations">Replace your default animations</string>
+ <string name="ScriptReturnObjects">Return objects on your behalf</string>
+ <string name="UnknownScriptPermission">(unknown)!</string>
<!-- Sim Access labels -->
<string name="SIM_ACCESS_PG">General</string>
@@ -432,6 +456,8 @@ Please try logging in again in a minute.</string>
<string name="load_file_verb">Load</string>
<string name="targa_image_files">Targa Images</string>
<string name="bitmap_image_files">Bitmap Images</string>
+ <string name="png_image_files">PNG Images</string>
+ <string name="save_texture_image_files">Targa or PNG Images</string>
<string name="avi_movie_file">AVI Movie File</string>
<string name="xaf_animation_file">XAF Anim File</string>
<string name="xml_file">XML File</string>
@@ -440,6 +466,7 @@ Please try logging in again in a minute.</string>
<string name="load_files">Load Files</string>
<string name="choose_the_directory">Choose Directory</string>
<string name="script_files">Scripts</string>
+ <string name="dictionary_files">Dictionaries</string>
<!-- LSL Usage Hover Tips -->
<!-- NOTE: For now these are set as translate="false", until DEV-40761 is implemented (to internationalize the rest of tooltips in the same window).
@@ -630,11 +657,11 @@ Returns the wind velocity at the object position + offset
</string>
<string name="LSLTipText_llSetStatus" translate="false">
llSetStatus(integer status, integer value)
-Sets status (STATUS_PHYSICS, STATUS_PHANTOM, STATUS_BLOCK_GRAB, STATUS_ROTATE_X, STATUS_ROTATE_Y, and/or STATUS_ROTATE_Z) to value
+Sets status (STATUS_PHYSICS, STATUS_PHANTOM, STATUS_BLOCK_GRAB, STATUS_BLOCK_GRAB_OBJECT, STATUS_ROTATE_X, STATUS_ROTATE_Y, and/or STATUS_ROTATE_Z) to value
</string>
<string name="LSLTipText_llGetStatus" translate="false">
integer llGetStatus(integer status)
-Returns value of status (STATUS_PHYSICS, STATUS_PHANTOM, STATUS_BLOCK_GRAB, STATUS_ROTATE_X, STATUS_ROTATE_Y, and/or STATUS_ROTATE_Z)
+Returns the boolean value of status (STATUS_PHYSICS, STATUS_PHANTOM, STATUS_BLOCK_GRAB, STATUS_BLOCK_GRAB_OBJECT, STATUS_ROTATE_X, STATUS_ROTATE_Y, or STATUS_ROTATE_Z)
</string>
<string name="LSLTipText_llSetScale" translate="false">
llSetScale(vector scale)
@@ -670,7 +697,7 @@ Sets the texture u &amp; v scales for the chosen face or ALL_SIDES
</string>
<string name="LSLTipText_llOffsetTexture" translate="false">
llOffsetTexture(float u, float v, integer face)
-Sets the texture u &amp; v offsets for the chosen face or ALL_SIDES
+Sets the texture u &amp; v offsets for the chosen face or ALL_SIDES
</string>
<string name="LSLTipText_llRotateTexture" translate="false">
llRotateTexture(float rotation, integer face)
@@ -788,9 +815,9 @@ Sets the script timer to zero
float llGetAndResetTime()
Returns the script time in seconds and then resets the script timer to zero
</string>
- <string name="LSLTipText_llSoplayund" translate="false">
+ <string name="LSLTipText_llSound" translate="false">
llSound(string sound, float volume, integer queue, integer loop)
-Plays sound at volume and whether it should loop or not
+Plays sound at volume and whether it should loop or not.
</string>
<string name="LSLTipText_llPlaySound" translate="false">
llPlaySound(string sound, float volume)
@@ -1445,7 +1472,7 @@ integer llScriptDanger(vector pos)
Returns TRUE if pos is over public land, sandbox land, land that doesn&apos;t allow everyone to edit and build, or land that doesn&apos;t allow outside scripts
</string>
<string name="LSLTipText_llDialog" translate="false">
-llDialog(key avatar, string message, list buttons, integer chat_channel
+llDialog(key avatar, string message, list buttons, integer chat_channel)
Shows a dialog box on the avatar&apos;s screen with a message and up to 12 buttons.
If a button is pressed, the avatar says the text of the button label on chat_channel.
</string>
@@ -1666,7 +1693,7 @@ Returns a list containing results of the sent query
</string>
<string name="LSLTipText_llModPow" translate="false">
integer llModPow(integer a, integer b, integer c)
-Returns a raised to the b power, mod c. ( (a**b)%c )
+Returns a raised to the b power, mod c. ( (a**b)%c )
b is capped at 0xFFFF (16 bits).
</string>
<string name="LSLTipText_llGetInventoryType" translate="false">
@@ -1779,10 +1806,10 @@ integer llGetParcelMaxPrims(vector pos, integer sim_wide)
Returns the maximum number of prims allowed on the parcel at pos
</string>
<string name="LSLTipText_llGetParcelDetails" translate="false">
- list llGetParcelDetails(vector pos, list params)
- Returns the parcel details specified in params for the parcel at pos.
- Params is one or more of: PARCEL_DETAILS_NAME, _DESC, _OWNER, _GROUP, _AREA, _ID, _SEE_AVATARS
- </string>
+list llGetParcelDetails(vector pos, list params)
+Returns the parcel details specified in params for the parcel at pos.
+Params is one or more of: PARCEL_DETAILS_NAME, _DESC, _OWNER, _GROUP, _AREA, _ID, _SEE_AVATARS
+ </string>
<string name="LSLTipText_llSetLinkPrimitiveParams" translate="false">
llSetLinkPrimitiveParams(integer linknumber, list rules)
Sets primitive parameters for linknumber based on rules
@@ -1871,78 +1898,203 @@ Releases the specified URL, it will no longer be usable
<string name="LSLTipText_llHTTPResponse" translate="false">
llHTTPResponse(key request_id, integer status, string body)
Responds to request_id with status and body
- </string>
+ </string>
<string name="LSLTipText_llGetHTTPHeader" translate="false">
string llGetHTTPHeader(key request_id, string header)
Returns the value for header for request_id
</string>
- <string name="LSLTipText_llSetPrimMediaParams" translate="false">
+ <string name="LSLTipText_llSetPrimMediaParams" translate="false">
llSetPrimMediaParams(integer face, list params)
Sets the media params for a particular face on an object. If media is not already on this object, add it.
List is a set of name/value pairs in no particular order. Params not specified are unchanged, or if new media is added then set to the default specified.
The possible names are below, along with the types of values and what they mean.
- </string>
- <string name="LSLTipText_llGetPrimMediaParams" translate="false">
+ </string>
+ <string name="LSLTipText_llGetPrimMediaParams" translate="false">
list llGetPrimMediaParams(integer face, list params)
Returns the media params for a particular face on an object, given the desired list of names, in the order requested.
(Returns an empty list if no media exists on the face.)
- </string>
- <string name="LSLTipText_llClearPrimMedia" translate="false">
+ </string>
+ <string name="LSLTipText_llClearPrimMedia" translate="false">
llClearPrimMedia(integer face)
Clears (deletes) the media and all params from the given face.
- </string>
-<string name="LSLTipText_llSetLinkPrimitiveParamsFast" translate="false">
+ </string>
+ <string name="LSLTipText_llSetLinkPrimitiveParamsFast" translate="false">
llSetLinkPrimitiveParamsFast(integer linknumber,list rules)
Set primitive parameters for linknumber based on rules.
-</string>
-<string name="LSLTipText_llGetLinkPrimitiveParams" translate="false">
+ </string>
+ <string name="LSLTipText_llGetLinkPrimitiveParams" translate="false">
llGetLinkPrimitiveParams(integer linknumber,list rules)
Get primitive parameters for linknumber based on rules.
-</string>
-<string name="LSLTipText_llLinkParticleSystem" translate="false">
+ </string>
+ <string name="LSLTipText_llLinkParticleSystem" translate="false">
llLinkParticleSystem(integer linknumber,list rules)
Creates a particle system based on rules. Empty list removes particle system from object.
List format is [ rule1, data1, rule2, data2 . . . rulen, datan ].
-</string>
-<string name="LSLTipText_llSetLinkTextureAnim" translate="false">
+ </string>
+ <string name="LSLTipText_llSetLinkTextureAnim" translate="false">
llSetLinkTextureAnim(integer link, integer mode, integer face, integer sizex, integer sizey, float start, float length, float rate)
-Animate the texture on the specified prim's face/faces.
-</string>
-<string name="LSLTipText_llGetLinkNumberOfSides" translate="false">
+Animate the texture on the specified prim&apos;s face/faces.
+ </string>
+ <string name="LSLTipText_llGetLinkNumberOfSides" translate="false">
integer llGetLinkNumberOfSides(integer link)
Returns the number of sides of the specified linked prim.
-</string>
-<string name="LSLTipText_llGetUsername" translate="false">
+ </string>
+ <string name="LSLTipText_llGetUsername" translate="false">
string llGetUsername(key id)
Returns the single-word username of an avatar, iff the avatar is in the current region, otherwise the empty string.
-</string>
-<string name="LSLTipText_llRequestUsername" translate="false">
+ </string>
+ <string name="LSLTipText_llRequestUsername" translate="false">
key llRequestUsername(key id)
Requests single-word username of an avatar. When data is available the dataserver event will be raised.
-</string>
-<string name="LSLTipText_llGetDisplayName" translate="false">
- string llGetDisplayName(key id)
- Returns the name of an avatar, iff the avatar is in the current simulator, and the name has been cached, otherwise the same as llGetUsername. Use llRequestDisplayName if you absolutely must have the display name.
-</string>
-<string name="LSLTipText_llRequestDisplayName" translate="false">
+ </string>
+ <string name="LSLTipText_llGetDisplayName" translate="false">
+string llGetDisplayName(key id)
+Returns the name of an avatar, iff the avatar is in the current simulator, and the name has been cached, otherwise the same as llGetUsername. Use llRequestDisplayName if you absolutely must have the display name.
+ </string>
+ <string name="LSLTipText_llRequestDisplayName" translate="false">
key llRequestDisplayName(key id)
Requests name of an avatar. When data is available the dataserver event will be raised.
-</string>
-<string name="LSLTipText_llRegionSayTo" translate="false">
-llRegionSayTo(key target, integer channel, string msg)
-Sends msg on channel (not DEBUG_CHANNEL) directly to prim or avatar target anywhere within the region
-</string>
-<string name="LSLTipText_llGetEnv" translate="false">
+ </string>
+ <string name="LSLTipText_llGetEnv" translate="false">
llGetEnv(string name)
Returns a string with the requested data about the region
-</string>
-
+ </string>
+ <string name="LSLTipText_llCastRay" translate="false">
+llCastRay(vector start, vector end, list params)
+Casts a ray into the physics world from &apos;start&apos; to &apos;end&apos; and returns data according to details in params.
+ </string>
+ <string name="LSLTipText_llRegionSayTo" translate="false">
+llRegionSayTo(key target, integer channel, string msg)
+Sends msg on channel (not DEBUG_CHANNEL) directly to prim or avatar target anywhere within the region.
+ </string>
+ <string name="LSLTipText_llGetSPMaxMemory" translate="false">
+integer llGetSPMaxMemory()
+Returns the maximum used memory for the current script. Only valid after using PROFILE_SCRIPT_MEMORY. Non-mono scripts always use 16k.
+ </string>
+ <string name="LSLTipText_llGetUsedMemory" translate="false">
+integer llGetUsedMemory()
+Returns the current used memory for the current script. Non-mono scripts always use 16k.
+ </string>
+ <string name="LSLTipText_llScriptProfiler" translate="false">
+llScriptProfiler(integer flags)
+Enabled or disables script profiling options. Currently only supports PROFILE_SCRIPT_MEMORY (mono only) and PROFILE_NONE.
+MAY SIGNIFICANTLY REDUCE SCRIPT PERFORMANCE!
+ </string>
+ <string name="LSLTipText_llSetMemoryLimit" translate="false">
+integer llSetMemoryLimit(integer mem)
+ </string>
+ <string name="LSLTipText_llGetMemoryLimit" translate="false">
+integer llGetMemoryLimit()
+ </string>
+ <string name="LSLTipText_llSetLinkMedia" translate="false">
+llSetLinkMedia(integer link, integer face, list params)
+Set the media params for a particular face on linked prim. List is a set of name/value pairs (in no particular order). The possible names are below, along with the types of values and what they mean. If media is not already on this object, add it. Params not specified are unchanged, or if new media is added set to the default specified.
+ </string>
+ <string name="LSLTipText_llGetLinkMedia" translate="false">
+list llGetLinkMedia(integer link, integer face, list params)
+Get the media params for a particular face on linked prim, given the desired list of names. Returns a list of values in the order requested. Returns an empty list if no media exists on the face.
+ </string>
+ <string name="LSLTipText_llClearLinkMedia" translate="false">
+llClearLinkMedia(integer link, integer face)
+Clears (deletes) the media and all params from the given face on linked prim.
+ </string>
+ <string name="LSLTipText_llSetContentType" translate="false">
+llSetContentType(key id, integer content_type)
+ </string>
+ <string name="LSLTipText_llLinkSitTarget" translate="false">
+llLinkSitTarget(integer link, vector offset, rotation rot)
+Set the sit location for this object (if offset == &lt;0,0,0&gt; clear it)
+ </string>
+ <string name="LSLTipText_llAvatarOnLinkSitTarget" translate="false">
+key llAvatarOnLinkSitTarget(integer link)
+If an avatar is sitting on the sit target, return the avatar&apos;s key, NULL_KEY otherwise
+ </string>
+ <string name="LSLTipText_llSetLinkCamera" translate="false">
+llSetLinkCamera(integer link, vector eye, vector at)
+ </string>
+ <string name="LSLTipText_llSetVelocity" translate="false">
+llSetVelocity(vector velocity, integer local)
+Sets an objects velocity, in local coords if local == TRUE (if the script is physical)
+ </string>
+ <string name="LSLTipText_llSetAngularVelocity" translate="false">
+llSetAngularVelocity(vector angular_velocity, integer local)
+Sets an objects angular velocity, in local coords if local == TRUE (if the script is physical)
+ </string>
+ <string name="LSLTipText_llSetPhysicsMaterial" translate="false">
+llSetPhysicsMaterial(integer flags, float gravity_multiplier, float restitution, float friction, float density )
+Sets the requested attributes of the root object&apos;s physics material.
+ </string>
+ <string name="LSLTipText_llGetPhysicsMaterial" translate="false">
+llGetPhysicsMaterial() returns the gravity multiplier, restitution, friction, and density of the linkset as a list in that order.
+ </string>
+ <string name="LSLTipText_llGetMassMKS" translate="false">
+llGetMassMKS() returns the mass of the linkset in kilograms.
+ </string>
+ <string name="LSLTipText_llGenerateKey" translate="false">
+llGenerateKey()
+Retun a unique generated key
+ </string>
+ <string name="LSLTipText_llSetKeyframedMotion" translate="false">
+llSetKeyframedMotion(list keyframes, list options)
+Requests that a nonphysical object be keyframed according to keyframe list.
+ </string>
+ <string name="LSLTipText_llTransferLindenDollars" translate="false">
+key llTransferLindenDollars(key destination, integer amount)
+Transfer amount of linden dollars (L$) from script owner to destination. Returns a key to a corresponding transaction_result event for the success of the transfer.
+ </string>
+ <string name="LSLTipText_llGetParcelMusicURL" translate="false">
+string llGetParcelMusicURL()
+Gets the streaming audio URL for the parcel of land on which the object is located.
+ </string>
+ <string name="LSLTipText_llSetRegionPos" translate="false">
+integer llSetRegionPos(vector pos)
+Sets the position anywhere within the region (if the object isn&apos;t physical)
+ </string>
+ <string name="LSLTipText_llNavigateTo" translate="false">
+llNavigateTo(vector point, list options)
+For AI Character: Navigate to destination.
+ </string>
+ <string name="LSLTipText_llCreateCharacter" translate="false">
+llCreateCharacter(list options)
+Convert linkset to AI Character which can navigate the world.
+ </string>
+ <string name="LSLTipText_llPursue" translate="false">
+llPursue(key target, list options)
+For AI Character: Chase after a target.
+ </string>
+ <string name="LSLTipText_llWanderWithin" translate="false">
+llWanderWithin(vector center, float radius, list options)
+For AI Character: Wander within a specified volume.
+ </string>
+ <string name="LSLTipText_llFleeFrom" translate="false">
+llFleeFrom(vector source, float radius, list options)
+For AI Character: Flee from a point.
+ </string>
+ <string name="LSLTipText_llPatrolPoints" translate="false">
+llPatrolPoints(list points, list options)
+For AI Character: Patrol a list of points.
+ </string>
+ <string name="LSLTipText_llExecCharacterCmd" translate="false">
+llExecCharacterCmd(integer cmd, list options)
+For AI Character: Execute a character command.
+ </string>
+ <string name="LSLTipText_llDeleteCharacter" translate="false">
+llDeleteCharacter()
+Convert linkset from AI Character to Physics object.
+ </string>
+ <string name="LSLTipText_llUpdateCharacter" translate="false">
+llUpdateCharacter(list options)
+Change the AI Character&apos;s settings.
+ </string>
+ <string name="LSLTipText_llEvade" translate="false">
+llEvade(key target, list options)
+For AI Character: Evade a specified target.
+ </string>
+ <string name="LSLTipText_llGetClosestNavPoint" translate="false">
+list llGetClosestNavPoint(vector point, list options)
+For AI Character: Get the closest navigable point to the point provided.
+ </string>
- <!-- Avatar busy/away mode -->
- <string name="AvatarSetNotAway">Not Away</string>
- <string name="AvatarSetAway">Away</string>
- <string name="AvatarSetNotBusy">Not Busy</string>
- <string name="AvatarSetBusy">Busy</string>
<!-- Wearable Types -->
<string name="shape">Shape</string>
@@ -2043,7 +2195,7 @@ Returns a string with the requested data about the region
<string name="InventoryNoTexture">You do not have a copy of this texture in your inventory</string>
<string name="InventoryInboxNoItems">Your Marketplace purchases will appear here. You may then drag them into your inventory to use them.</string>
<string name="MarketplaceURL">https://marketplace.[MARKETPLACE_DOMAIN_NAME]/</string>
- <string name="MarketplaceURL_CreateStore">http://community.secondlife.com/t5/English-Knowledge-Base/Selling-in-the-Marketplace/ta-p/700193#Section_.4</string>
+ <string name="MarketplaceURL_CreateStore">http://community.secondlife.com/t5/English-Knowledge-Base/Selling-in-the-Marketplace/ta-p/700193#Section_.3</string>
<string name="MarketplaceURL_Dashboard">https://marketplace.[MARKETPLACE_DOMAIN_NAME]/merchants/store/dashboard</string>
<string name="MarketplaceURL_Imports">https://marketplace.[MARKETPLACE_DOMAIN_NAME]/merchants/store/imports</string>
<string name="MarketplaceURL_LearnMore">https://marketplace.[MARKETPLACE_DOMAIN_NAME]/learn_more</string>
@@ -2137,16 +2289,22 @@ Drag folders to this area and click "Send to Marketplace" to list them for sale
<string name="InvFolder Gestures">Gestures</string>
<string name="InvFolder Favorite">My Favorites</string>
<!-- historically default name of the Favorites folder can start from either "f" or "F" letter.
- We should localize both of them with the same value -->
+ Also, it can be written as "Favorite" or "Favorites".
+ We should localize all variants of them with the same value -->
<string name="InvFolder favorite">My Favorites</string>
+ <string name="InvFolder Favorites">My Favorites</string>
+ <string name="InvFolder favorites">My Favorites</string>
<string name="InvFolder Current Outfit">Current Outfit</string>
<string name="InvFolder Initial Outfits">Initial Outfits</string>
<string name="InvFolder My Outfits">My Outfits</string>
<string name="InvFolder Accessories">Accessories</string>
<string name="InvFolder Meshes">Meshes</string>
+ <string name="InvFolder Received Items">Received Items</string>
+ <string name="InvFolder Merchant Outbox">Merchant Outbox</string>
<!-- are used for Friends and Friends/All folders in Inventory "Calling cards" folder. See EXT-694-->
<string name="InvFolder Friends">Friends</string>
+ <string name="InvFolder Received Items">Received Items</string>
<string name="InvFolder All">All</string>
<string name="no_attachments">No attachments worn</string>
@@ -2316,7 +2474,11 @@ Drag folders to this area and click "Send to Marketplace" to list them for sale
all estates that you manage for [OWNER]
</string>
<string name="RegionInfoAllowedResidents">Allowed Residents: ([ALLOWEDAGENTS], max [MAXACCESS])</string>
- <string name="RegionInfoAllowedGroups">Allowed groups: ([ALLOWEDGROUPS], max [MAXACCESS])</string>
+ <string name="RegionInfoAllowedGroups">Allowed Groups: ([ALLOWEDGROUPS], max [MAXACCESS])</string>
+ <string name="RegionInfoEstateManagers">Estate Managers: ([ESTATEMANAGERS], max [MAXMANAGERS])</string>
+ <string name="RegionInfoBannedResidents">Banned Residents: ([BANNEDAGENTS], max [MAXBANNED])</string>
+ <string name="RegionInfoListTypeAllowedAgents">Allowed Residents</string>
+ <string name="RegionInfoListTypeBannedAgents">Banned Residents</string>
<!-- script limits floater -->
<string name="ScriptLimitsParcelScriptMemory">Parcel Script Memory</string>
@@ -2371,6 +2533,8 @@ Drag folders to this area and click "Send to Marketplace" to list them for sale
<string name="ATTACH_HUD_BOTTOM_LEFT">HUD Bottom Left</string>
<string name="ATTACH_HUD_BOTTOM">HUD Bottom</string>
<string name="ATTACH_HUD_BOTTOM_RIGHT">HUD Bottom Right</string>
+ <string name="ATTACH_NECK">Neck</string>
+ <string name="ATTACH_AVATAR_CENTER">Avatar Center</string>
<!-- script editor -->
<string name="CursorPos">Line [LINE], Column [COLUMN]</string>
@@ -2387,7 +2551,7 @@ Drag folders to this area and click "Send to Marketplace" to list them for sale
<string name="PanelContentsNewScript">New Script</string>
<!-- panel preferences general -->
- <string name="BusyModeResponseDefault">The Resident you messaged is in &apos;busy mode&apos; which means they have requested not to be disturbed. Your message will still be shown in their IM panel for later viewing.</string>
+ <string name="DoNotDisturbModeResponseDefault">This resident has turned on &apos;Do Not Disturb&apos; and will see your message later.</string>
<!-- Mute -->
<string name="MuteByName">(By name)</string>
@@ -2446,9 +2610,6 @@ Drag folders to this area and click "Send to Marketplace" to list them for sale
<string name="GroupMoneyDebits">Debits</string>
<string name="GroupMoneyDate">[weekday,datetime,utc] [mth,datetime,utc] [day,datetime,utc], [year,datetime,utc]</string>
- <!-- viewer object -->
- <string name="ViewerObjectContents">Contents</string>
-
<!-- Viewer menu -->
<string name="AcquiredItems">Acquired Items</string>
<string name="Cancel">Cancel</string>
@@ -2854,6 +3015,7 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
<string name="Higher">Higher</string>
<string name="Hip Length">Hip Length</string>
<string name="Hip Width">Hip Width</string>
+<string name="Hover">Hover</string>
<string name="In">In</string>
<string name="In Shdw Color">Inner Shadow Color</string>
<string name="In Shdw Opacity">Inner Shadow Opacity</string>
@@ -3193,8 +3355,9 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
<string name="LocationCtrlAdultIconTooltip">Adult Region</string>
<string name="LocationCtrlModerateIconTooltip">Moderate Region</string>
<string name="LocationCtrlGeneralIconTooltip">General Region</string>
- <string name="LocationCtrlSeeAVsTooltip">Avatars visible and chat allowed outside of this parcel</string>
-
+ <string name="LocationCtrlSeeAVsTooltip">Avatars inside this parcel cannot be seen or heard by avatars outside this parcel</string>
+ <string name="LocationCtrlPathfindingDirtyTooltip">Objects that move may not behave correctly in this region until the region is rebaked.</string>
+ <string name="LocationCtrlPathfindingDisabledTooltip">Dynamic pathfinding is not enabled on this region.</string>
<!-- Strings used by the (currently Linux) auto-updater app -->
<string name="UpdaterWindowTitle">
[APP_NAME] Update
@@ -3243,12 +3406,15 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
<string name="IM_moderator_label">(Moderator)</string>
<string name="Saved_message">(Saved [LONG_TIMESTAMP])</string>
<string name="IM_unblock_only_groups_friends">To see this message, you must uncheck &apos;Only friends and groups can call or IM me&apos; in Preferences/Privacy.</string>
+ <string name="OnlineStatus">Online</string>
+ <string name="OfflineStatus">Offline</string>
<!-- voice calls -->
<string name="answered_call">Your call has been answered</string>
<string name="you_started_call">You started a voice call</string>
<string name="you_joined_call">You joined the voice call</string>
- <string name="name_started_call">[NAME] started a voice call</string>
+ <string name="you_auto_rejected_call-im">You automatically rejected the voice call while &apos;Do Not Disturb&apos; was on.</string>
+ <string name="name_started_call">[NAME] started a voice call</string>
<string name="ringing-im">
Joining voice call...
@@ -3263,7 +3429,7 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
Connecting...
</string>
<string name="conference-title">
- Ad-hoc Conference
+ Multi-person chat
</string>
<string name="conference-title-incoming">
Conference with [AGENT_NAME]
@@ -3275,6 +3441,9 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
Drag items from inventory here
</string>
+ <string name="facebook_post_success">
+ You posted to Facebook.
+ </string>
<string name="no_session_message">
(IM Session Doesn't Exist)
@@ -3689,6 +3858,7 @@ Try enclosing path to the editor with double quotes.
<string name="Command_Avatar_Label">Avatar</string>
<string name="Command_Build_Label">Build</string>
<string name="Command_Chat_Label">Chat</string>
+ <string name="Command_Conversations_Label">Conversations</string>
<string name="Command_Compass_Label">Compass</string>
<string name="Command_Destinations_Label">Destinations</string>
<string name="Command_Gestures_Label">Gestures</string>
@@ -3706,6 +3876,7 @@ Try enclosing path to the editor with double quotes.
<string name="Command_Profile_Label">Profile</string>
<string name="Command_Search_Label">Search</string>
<string name="Command_Snapshot_Label">Snapshot</string>
+ <string name="Command_Social_Label">Facebook</string>
<string name="Command_Speak_Label">Speak</string>
<string name="Command_View_Label">Camera controls</string>
<string name="Command_Voice_Label">Voice settings</string>
@@ -3715,6 +3886,7 @@ Try enclosing path to the editor with double quotes.
<string name="Command_Avatar_Tooltip">Choose a complete avatar</string>
<string name="Command_Build_Tooltip">Building objects and reshaping terrain</string>
<string name="Command_Chat_Tooltip">Chat with people nearby using text</string>
+ <string name="Command_Conversations_Tooltip">Converse with everyone</string>
<string name="Command_Compass_Tooltip">Compass</string>
<string name="Command_Destinations_Tooltip">Destinations of interest</string>
<string name="Command_Gestures_Tooltip">Gestures for your avatar</string>
@@ -3732,6 +3904,7 @@ Try enclosing path to the editor with double quotes.
<string name="Command_Profile_Tooltip">Edit or view your profile</string>
<string name="Command_Search_Tooltip">Find places, events, people</string>
<string name="Command_Snapshot_Tooltip">Take a picture</string>
+ <string name="Command_Social_Tooltip">Post to Facebook</string>
<string name="Command_Speak_Tooltip">Speak with people nearby using your microphone</string>
<string name="Command_View_Tooltip">Changing camera angle</string>
<string name="Command_Voice_Tooltip">Volume controls for calls and people near you in world</string>
@@ -3750,6 +3923,13 @@ Try enclosing path to the editor with double quotes.
<string name="Preview">Preview</string>
<string name="Normal">Normal</string>
+ <!-- Pathfinding -->
+ <string name="Pathfinding_Wiki_URL">http://wiki.secondlife.com/wiki/Pathfinding_Tools_in_the_Second_Life_Viewer</string>
+ <string name="Pathfinding_Object_Attr_None">None</string>
+ <string name="Pathfinding_Object_Attr_Permanent">Affects navmesh</string>
+ <string name="Pathfinding_Object_Attr_Character">Character</string>
+ <string name="Pathfinding_Object_Attr_MultiSelect">(Multiple)</string>
+
<!-- Snapshot image quality levels -->
<string name="snapshot_quality_very_low">Very Low</string>
<string name="snapshot_quality_low">Low</string>
@@ -3757,4 +3937,23 @@ Try enclosing path to the editor with double quotes.
<string name="snapshot_quality_high">High</string>
<string name="snapshot_quality_very_high">Very High</string>
+ <string name="TeleportMaturityExceeded">The Resident cannot visit this region.</string>
+
+ <!-- Spell check settings floater -->
+ <string name="UserDictionary">[User]</string>
+
+ <!-- Conversation log messages -->
+ <string name="logging_calls_disabled_log_empty">
+ Conversations are not being logged. To begin keeping a log, choose "Save: Log only" or "Save: Log and transcripts" under Preferences > Chat.
+ </string>
+ <string name="logging_calls_disabled_log_not_empty">
+ No more conversations will be logged. To resume keeping a log, choose "Save: Log only" or "Save: Log and transcripts" under Preferences > Chat.
+ </string>
+ <string name="logging_calls_enabled_log_empty">
+ There are no logged conversations. After you contact someone, or someone contacts you, a log entry will be shown here.
+ </string>
+ <string name="loading_chat_logs">
+ Loading...
+ </string>
+
</strings>
diff --git a/indra/newview/skins/default/xui/en/teleport_strings.xml b/indra/newview/skins/default/xui/en/teleport_strings.xml
index dce6b8dd6d..fdf41991cd 100644..100755
--- a/indra/newview/skins/default/xui/en/teleport_strings.xml
+++ b/indra/newview/skins/default/xui/en/teleport_strings.xml
@@ -45,6 +45,9 @@ Go to &apos;Welcome Island Public&apos; to repeat the tutorial.
<message name="no_inventory_host">
The inventory system is currently unavailable.
</message>
+ <message name="MustGetAgeRegion">
+ You must be age 18 or over to enter this region.
+ </message>
</message_set>
<message_set name="progress">
<message name="sending_dest">
@@ -80,5 +83,8 @@ Go to &apos;Welcome Island Public&apos; to repeat the tutorial.
<message name="requesting">
Requesting Teleport...
</message>
- </message_set>
+ <message name="pending">
+ Pending Teleport...
+ </message>
+ </message_set>
</teleport_messages>
diff --git a/indra/newview/skins/default/xui/en/widgets/accordion.xml b/indra/newview/skins/default/xui/en/widgets/accordion.xml
index 55dde492ca..55dde492ca 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/accordion.xml
+++ b/indra/newview/skins/default/xui/en/widgets/accordion.xml
diff --git a/indra/newview/skins/default/xui/en/widgets/accordion_tab.xml b/indra/newview/skins/default/xui/en/widgets/accordion_tab.xml
index 6f68c99021..6f68c99021 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/accordion_tab.xml
+++ b/indra/newview/skins/default/xui/en/widgets/accordion_tab.xml
diff --git a/indra/newview/skins/default/xui/en/widgets/avatar_icon.xml b/indra/newview/skins/default/xui/en/widgets/avatar_icon.xml
index 4d69dda7eb..4d69dda7eb 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/avatar_icon.xml
+++ b/indra/newview/skins/default/xui/en/widgets/avatar_icon.xml
diff --git a/indra/newview/skins/default/xui/en/widgets/avatar_list_item.xml b/indra/newview/skins/default/xui/en/widgets/avatar_list_item.xml
index 8a4ccb19f9..8a4ccb19f9 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/avatar_list_item.xml
+++ b/indra/newview/skins/default/xui/en/widgets/avatar_list_item.xml
diff --git a/indra/newview/skins/default/xui/en/widgets/badge.xml b/indra/newview/skins/default/xui/en/widgets/badge.xml
index 738d150f64..738d150f64 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/badge.xml
+++ b/indra/newview/skins/default/xui/en/widgets/badge.xml
diff --git a/indra/newview/skins/default/xui/en/widgets/bodyparts_list_item.xml b/indra/newview/skins/default/xui/en/widgets/bodyparts_list_item.xml
index 0016a8cf53..0016a8cf53 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/bodyparts_list_item.xml
+++ b/indra/newview/skins/default/xui/en/widgets/bodyparts_list_item.xml
diff --git a/indra/newview/skins/default/xui/en/widgets/button.xml b/indra/newview/skins/default/xui/en/widgets/button.xml
index 2b2c3faf91..2b2c3faf91 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/button.xml
+++ b/indra/newview/skins/default/xui/en/widgets/button.xml
diff --git a/indra/newview/skins/default/xui/en/widgets/chat_editor.xml b/indra/newview/skins/default/xui/en/widgets/chat_editor.xml
new file mode 100755
index 0000000000..f9facb593a
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/chat_editor.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<chat_editor
+ name="chat_editor"
+ show_context_menu="true"/>
diff --git a/indra/newview/skins/default/xui/en/widgets/chat_history.xml b/indra/newview/skins/default/xui/en/widgets/chat_history.xml
index c0a948931c..c0a948931c 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/chat_history.xml
+++ b/indra/newview/skins/default/xui/en/widgets/chat_history.xml
diff --git a/indra/newview/skins/default/xui/en/widgets/check_box.xml b/indra/newview/skins/default/xui/en/widgets/check_box.xml
index 8947024e45..8947024e45 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/check_box.xml
+++ b/indra/newview/skins/default/xui/en/widgets/check_box.xml
diff --git a/indra/newview/skins/default/xui/en/widgets/chiclet_im_adhoc.xml b/indra/newview/skins/default/xui/en/widgets/chiclet_im_adhoc.xml
deleted file mode 100644
index 0e29ed0d0b..0000000000
--- a/indra/newview/skins/default/xui/en/widgets/chiclet_im_adhoc.xml
+++ /dev/null
@@ -1,55 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<chiclet_im_adhoc
- height="23"
- name="im_adhoc_chiclet"
- show_speaker="false"
- width="25">
- <chiclet_im_adhoc.chiclet_button
- height="25"
- image_selected="PushButton_On"
- image_unselected="PushButton_Off"
- name="chiclet_button"
- tab_stop="false"
- width="25" />
- <chiclet_im_adhoc.speaker
- image_mute="Parcel_VoiceNo_Light"
- image_off="VoicePTT_Off_Dark"
- image_on="VoicePTT_On_Dark"
- image_level_1="VoicePTT_Lvl1_Dark"
- image_level_2="VoicePTT_Lvl2_Dark"
- image_level_3="VoicePTT_Lvl3_Dark"
- auto_update="true"
- draw_border="false"
- height="24"
- left="25"
- bottom="1"
- name="speaker"
- visible="false"
- width="20" />
- <chiclet_im_adhoc.avatar_icon
- bottom="3"
- follows="left|top|bottom"
- height="20"
- left="2"
- mouse_opaque="false"
- name="adhoc_icon"
- width="21" />
- <chiclet_im_adhoc.unread_notifications
- halign="center"
- height="23"
- left="25"
- mouse_opaque="false"
- name="unread"
- text_color="white"
- v_pad="3"
- visible="false"
- width="20" />
- <chiclet_im_adhoc.new_message_icon
- bottom="11"
- height="14"
- image_name="Unread_Chiclet"
- left="12"
- name="new_message_icon"
- visible="false"
- width="14" />
-</chiclet_im_adhoc> \ No newline at end of file
diff --git a/indra/newview/skins/default/xui/en/widgets/chiclet_im_group.xml b/indra/newview/skins/default/xui/en/widgets/chiclet_im_group.xml
deleted file mode 100644
index 77011139bf..0000000000
--- a/indra/newview/skins/default/xui/en/widgets/chiclet_im_group.xml
+++ /dev/null
@@ -1,56 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<chiclet_im_group
- height="23"
- name="im_group_chiclet"
- show_speaker="false"
- width="25">
- <chiclet_im_group.chiclet_button
- height="25"
- image_selected="PushButton_On"
- image_unselected="PushButton_Off"
- name="chiclet_button"
- tab_stop="false"
- width="25" />
- <chiclet_im_group.speaker
- image_mute="Parcel_VoiceNo_Light"
- image_off="VoicePTT_Off_Dark"
- image_on="VoicePTT_On_Dark"
- image_level_1="VoicePTT_Lvl1_Dark"
- image_level_2="VoicePTT_Lvl2_Dark"
- image_level_3="VoicePTT_Lvl3_Dark"
- auto_update="true"
- draw_border="false"
- height="24"
- left="25"
- bottom="1"
- name="speaker"
- visible="false"
- width="20" />
- <chiclet_im_group.group_icon
- bottom="3"
- default_icon="Generic_Group"
- follows="left|top|bottom"
- height="20"
- left="2"
- mouse_opaque="false"
- name="group_icon"
- width="21" />
- <chiclet_im_group.unread_notifications
- height="23"
- halign="center"
- left="25"
- mouse_opaque="false"
- name="unread"
- text_color="white"
- v_pad="3"
- visible="false"
- width="20"/>
- <chiclet_im_group.new_message_icon
-bottom="11"
- height="14"
- image_name="Unread_Chiclet"
- left="12"
- name="new_message_icon"
- visible="false"
- width="14" />
-</chiclet_im_group> \ No newline at end of file
diff --git a/indra/newview/skins/default/xui/en/widgets/chiclet_im_p2p.xml b/indra/newview/skins/default/xui/en/widgets/chiclet_im_p2p.xml
deleted file mode 100644
index 8b56a8f0f6..0000000000
--- a/indra/newview/skins/default/xui/en/widgets/chiclet_im_p2p.xml
+++ /dev/null
@@ -1,56 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<chiclet_im_p2p
- height="23"
- name="im_p2p_chiclet"
- show_speaker="false"
- width="25">
- <chiclet_im_p2p.chiclet_button
- height="25"
- image_selected="PushButton_On"
- image_unselected="PushButton_Off"
- name="chiclet_button"
- tab_stop="false"
- width="25"/>
- <chiclet_im_p2p.speaker
- image_mute="Parcel_VoiceNo_Light"
- image_off="VoicePTT_Off_Dark"
- image_on="VoicePTT_On_Dark"
- image_level_1="VoicePTT_Lvl1_Dark"
- image_level_2="VoicePTT_Lvl2_Dark"
- image_level_3="VoicePTT_Lvl3_Dark"
- auto_update="true"
- draw_border="false"
- height="24"
- left="25"
- bottom="1"
- name="speaker"
- visible="false"
- width="20" />
- <chiclet_im_p2p.avatar_icon
- bottom="3"
- color="white"
- follows="left|top|bottom"
- height="20"
- left="2"
- mouse_opaque="false"
- name="avatar_icon"
- width="21" />
- <chiclet_im_p2p.unread_notifications
- height="23"
- halign="center"
- left="25"
- mouse_opaque="false"
- name="unread"
- text_color="white"
- v_pad="3"
- visible="false"
- width="20"/>
- <chiclet_im_p2p.new_message_icon
- bottom="11"
- height="14"
- image_name="Unread_Chiclet"
- left="12"
- name="new_message_icon"
- visible="false"
- width="14" />
-</chiclet_im_p2p>
diff --git a/indra/newview/skins/default/xui/en/widgets/chiclet_offer.xml b/indra/newview/skins/default/xui/en/widgets/chiclet_offer.xml
index 4bc295f747..4bc295f747 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/chiclet_offer.xml
+++ b/indra/newview/skins/default/xui/en/widgets/chiclet_offer.xml
diff --git a/indra/newview/skins/default/xui/en/widgets/chiclet_panel.xml b/indra/newview/skins/default/xui/en/widgets/chiclet_panel.xml
index 5f51f4afd9..5f51f4afd9 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/chiclet_panel.xml
+++ b/indra/newview/skins/default/xui/en/widgets/chiclet_panel.xml
diff --git a/indra/newview/skins/default/xui/en/widgets/chiclet_script.xml b/indra/newview/skins/default/xui/en/widgets/chiclet_script.xml
index db6a9434df..db6a9434df 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/chiclet_script.xml
+++ b/indra/newview/skins/default/xui/en/widgets/chiclet_script.xml
diff --git a/indra/newview/skins/default/xui/en/widgets/clothing_list_item.xml b/indra/newview/skins/default/xui/en/widgets/clothing_list_item.xml
index d83f44737e..d83f44737e 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/clothing_list_item.xml
+++ b/indra/newview/skins/default/xui/en/widgets/clothing_list_item.xml
diff --git a/indra/newview/skins/default/xui/en/widgets/color_swatch.xml b/indra/newview/skins/default/xui/en/widgets/color_swatch.xml
index ab3de1eaab..ab3de1eaab 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/color_swatch.xml
+++ b/indra/newview/skins/default/xui/en/widgets/color_swatch.xml
diff --git a/indra/newview/skins/default/xui/en/widgets/combo_box.xml b/indra/newview/skins/default/xui/en/widgets/combo_box.xml
index 82d620d1e6..82d620d1e6 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/combo_box.xml
+++ b/indra/newview/skins/default/xui/en/widgets/combo_box.xml
diff --git a/indra/newview/skins/default/xui/en/widgets/context_menu.xml b/indra/newview/skins/default/xui/en/widgets/context_menu.xml
index 459706c689..459706c689 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/context_menu.xml
+++ b/indra/newview/skins/default/xui/en/widgets/context_menu.xml
diff --git a/indra/newview/skins/default/xui/en/widgets/conversation_view_participant.xml b/indra/newview/skins/default/xui/en/widgets/conversation_view_participant.xml
new file mode 100644
index 0000000000..b83d9122f7
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/conversation_view_participant.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<conversation_view_participant
+ folder_arrow_image="Folder_Arrow"
+ item_height="24"
+ item_top_pad="0"
+ selection_image="Rounded_Square"
+ mouse_opaque="true"
+ follows="left|top|right"
+ left_pad="0"
+ icon_pad="10"
+ icon_width="20"
+ text_pad="7"
+ text_pad_right="4"
+ arrow_size="12"
+ max_folder_item_overlap="2"
+>
+<avatar_icon
+ follows="left"
+ height="20"
+ default_icon_name="Generic_Person"
+ layout="topleft"
+ top="2"
+ width="20" />
+<info_button
+ follows="right"
+ height="16"
+ image_pressed="Info_Press"
+ image_unselected="Info_Over"
+ right="-28"
+ name="info_btn"
+ width="16" />
+<output_monitor
+ follows="right"
+ auto_update="true"
+ draw_border="false"
+ height="16"
+ right="-3"
+ mouse_opaque="true"
+ name="speaking_indicator"
+ visible="true"
+ width="20" />
+</conversation_view_participant>
diff --git a/indra/newview/skins/default/xui/en/widgets/conversation_view_session.xml b/indra/newview/skins/default/xui/en/widgets/conversation_view_session.xml
new file mode 100755
index 0000000000..b8c39eec1d
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/conversation_view_session.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<conversation_view_session
+ folder_arrow_image="Folder_Arrow"
+ folder_indentation="8"
+ item_height="24"
+ item_top_pad="4"
+ selection_image="Rounded_Square"
+ mouse_opaque="true"
+ follows="left|top|right"
+ left_pad="5"
+ icon_pad="2"
+ icon_width="16"
+ text_pad="1"
+ text_pad_right="4"
+ arrow_size="12"
+ max_folder_item_overlap="2"/>
diff --git a/indra/newview/skins/default/xui/en/widgets/deletable_wearable_list_item.xml b/indra/newview/skins/default/xui/en/widgets/deletable_wearable_list_item.xml
index 0534485ddd..0534485ddd 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/deletable_wearable_list_item.xml
+++ b/indra/newview/skins/default/xui/en/widgets/deletable_wearable_list_item.xml
diff --git a/indra/newview/skins/default/xui/en/widgets/drop_down.xml b/indra/newview/skins/default/xui/en/widgets/drop_down.xml
index 602250ace6..602250ace6 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/drop_down.xml
+++ b/indra/newview/skins/default/xui/en/widgets/drop_down.xml
diff --git a/indra/newview/skins/default/xui/en/widgets/dummy_clothing_list_item.xml b/indra/newview/skins/default/xui/en/widgets/dummy_clothing_list_item.xml
index 8c805da048..8c805da048 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/dummy_clothing_list_item.xml
+++ b/indra/newview/skins/default/xui/en/widgets/dummy_clothing_list_item.xml
diff --git a/indra/newview/skins/default/xui/en/widgets/expandable_text.xml b/indra/newview/skins/default/xui/en/widgets/expandable_text.xml
index c6331ec87b..c6331ec87b 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/expandable_text.xml
+++ b/indra/newview/skins/default/xui/en/widgets/expandable_text.xml
diff --git a/indra/newview/skins/default/xui/en/widgets/filter_editor.xml b/indra/newview/skins/default/xui/en/widgets/filter_editor.xml
index 2cc4abdd30..2cc4abdd30 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/filter_editor.xml
+++ b/indra/newview/skins/default/xui/en/widgets/filter_editor.xml
diff --git a/indra/newview/skins/default/xui/en/widgets/flat_list_view.xml b/indra/newview/skins/default/xui/en/widgets/flat_list_view.xml
index e05ddf9815..e05ddf9815 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/flat_list_view.xml
+++ b/indra/newview/skins/default/xui/en/widgets/flat_list_view.xml
diff --git a/indra/newview/skins/default/xui/en/widgets/floater.xml b/indra/newview/skins/default/xui/en/widgets/floater.xml
index 97a5ae7d4e..97a5ae7d4e 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/floater.xml
+++ b/indra/newview/skins/default/xui/en/widgets/floater.xml
diff --git a/indra/newview/skins/default/xui/en/widgets/flyout_button.xml b/indra/newview/skins/default/xui/en/widgets/flyout_button.xml
index 83df10e417..83df10e417 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/flyout_button.xml
+++ b/indra/newview/skins/default/xui/en/widgets/flyout_button.xml
diff --git a/indra/newview/skins/default/xui/en/widgets/folder_view_item.xml b/indra/newview/skins/default/xui/en/widgets/folder_view_item.xml
index 6fa74f403d..bbd53ccb12 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/folder_view_item.xml
+++ b/indra/newview/skins/default/xui/en/widgets/folder_view_item.xml
@@ -7,4 +7,10 @@
selection_image="Rounded_Square"
mouse_opaque="true"
follows="left|top|right"
- />
+ left_pad="5"
+ icon_pad="2"
+ icon_width="16"
+ text_pad="1"
+ text_pad_right="4"
+ arrow_size="12"
+ max_folder_item_overlap="2"/>
diff --git a/indra/newview/skins/default/xui/en/widgets/gesture_combo_list.xml b/indra/newview/skins/default/xui/en/widgets/gesture_combo_list.xml
index 808683864d..808683864d 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/gesture_combo_list.xml
+++ b/indra/newview/skins/default/xui/en/widgets/gesture_combo_list.xml
diff --git a/indra/newview/skins/default/xui/en/widgets/group_icon.xml b/indra/newview/skins/default/xui/en/widgets/group_icon.xml
index 36ee6dd7eb..36ee6dd7eb 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/group_icon.xml
+++ b/indra/newview/skins/default/xui/en/widgets/group_icon.xml
diff --git a/indra/newview/skins/default/xui/en/widgets/hint_popup.xml b/indra/newview/skins/default/xui/en/widgets/hint_popup.xml
index 92080df154..92080df154 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/hint_popup.xml
+++ b/indra/newview/skins/default/xui/en/widgets/hint_popup.xml
diff --git a/indra/newview/skins/default/xui/en/widgets/icon.xml b/indra/newview/skins/default/xui/en/widgets/icon.xml
index cf8edfcedb..cf8edfcedb 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/icon.xml
+++ b/indra/newview/skins/default/xui/en/widgets/icon.xml
diff --git a/indra/newview/skins/default/xui/en/widgets/inbox_folder_view_folder.xml b/indra/newview/skins/default/xui/en/widgets/inbox_folder_view_folder.xml
index 77d8024cb2..590a4730a9 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/inbox_folder_view_folder.xml
+++ b/indra/newview/skins/default/xui/en/widgets/inbox_folder_view_folder.xml
@@ -5,7 +5,13 @@
item_height="20"
item_top_pad="4"
selection_image="Rounded_Square"
- >
+ left_pad="5"
+ icon_pad="2"
+ icon_width="16"
+ text_pad="1"
+ text_pad_right="4"
+ arrow_size="12"
+ max_folder_item_overlap="2">
<new_badge
label="New"
label_offset_horiz="-1"
diff --git a/indra/newview/skins/default/xui/en/widgets/inbox_folder_view_item.xml b/indra/newview/skins/default/xui/en/widgets/inbox_folder_view_item.xml
index 7a7a6e9a09..7a7a6e9a09 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/inbox_folder_view_item.xml
+++ b/indra/newview/skins/default/xui/en/widgets/inbox_folder_view_item.xml
diff --git a/indra/newview/skins/default/xui/en/widgets/inbox_inventory_panel.xml b/indra/newview/skins/default/xui/en/widgets/inbox_inventory_panel.xml
index 830c27bdac..d5b10e7f51 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/inbox_inventory_panel.xml
+++ b/indra/newview/skins/default/xui/en/widgets/inbox_inventory_panel.xml
@@ -1,2 +1,3 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<inbox_inventory_panel show_load_status="false" />
+<inbox_inventory_panel show_load_status="false"
+ start_folder.type="inbox"/>
diff --git a/indra/newview/skins/default/xui/en/widgets/inspector.xml b/indra/newview/skins/default/xui/en/widgets/inspector.xml
index 8c171c387f..8c171c387f 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/inspector.xml
+++ b/indra/newview/skins/default/xui/en/widgets/inspector.xml
diff --git a/indra/newview/skins/default/xui/en/widgets/inventory_list_item.xml b/indra/newview/skins/default/xui/en/widgets/inventory_list_item.xml
index da9059c819..da9059c819 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/inventory_list_item.xml
+++ b/indra/newview/skins/default/xui/en/widgets/inventory_list_item.xml
diff --git a/indra/newview/skins/default/xui/en/widgets/inventory_panel.xml b/indra/newview/skins/default/xui/en/widgets/inventory_panel.xml
index eaf148c5e4..eaf148c5e4 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/inventory_panel.xml
+++ b/indra/newview/skins/default/xui/en/widgets/inventory_panel.xml
diff --git a/indra/newview/skins/default/xui/en/widgets/joystick_rotate.xml b/indra/newview/skins/default/xui/en/widgets/joystick_rotate.xml
index a190da3909..a190da3909 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/joystick_rotate.xml
+++ b/indra/newview/skins/default/xui/en/widgets/joystick_rotate.xml
diff --git a/indra/newview/skins/default/xui/en/widgets/layout_stack.xml b/indra/newview/skins/default/xui/en/widgets/layout_stack.xml
index 48bcb46533..48bcb46533 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/layout_stack.xml
+++ b/indra/newview/skins/default/xui/en/widgets/layout_stack.xml
diff --git a/indra/newview/skins/default/xui/en/widgets/line_editor.xml b/indra/newview/skins/default/xui/en/widgets/line_editor.xml
index a054960bf8..a054960bf8 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/line_editor.xml
+++ b/indra/newview/skins/default/xui/en/widgets/line_editor.xml
diff --git a/indra/newview/skins/default/xui/en/widgets/list_view.xml b/indra/newview/skins/default/xui/en/widgets/list_view.xml
index 2e976bc755..2e976bc755 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/list_view.xml
+++ b/indra/newview/skins/default/xui/en/widgets/list_view.xml
diff --git a/indra/newview/skins/default/xui/en/widgets/loading_indicator.xml b/indra/newview/skins/default/xui/en/widgets/loading_indicator.xml
index ea1d89c975..ea1d89c975 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/loading_indicator.xml
+++ b/indra/newview/skins/default/xui/en/widgets/loading_indicator.xml
diff --git a/indra/newview/skins/default/xui/en/widgets/location_input.xml b/indra/newview/skins/default/xui/en/widgets/location_input.xml
index 44436fb6f2..4ea1aa6efb 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/location_input.xml
+++ b/indra/newview/skins/default/xui/en/widgets/location_input.xml
@@ -112,6 +112,22 @@
follows="right|top"
image_name="Parcel_Health_Dark"
/>
+ <pathfinding_dirty_icon
+ name="pathfinding_dirty_icon"
+ width="22"
+ height="18"
+ top="21"
+ follows="right|top"
+ image_name="Pathfinding_Dirty"
+ />
+ <pathfinding_disabled_icon
+ name="pathfinding_disabled_icon"
+ width="22"
+ height="18"
+ top="21"
+ follows="right|top"
+ image_name="Pathfinding_Disabled"
+ />
<!-- Default text color is invisible on top of nav bar background -->
<damage_text
name="damage_text"
@@ -134,6 +150,7 @@
<combo_button
name="Location History"
label=""
+ image_hover_unselected="ComboButton_Hovered"
pad_right="0"/>
<combo_list
bg_writeable_color="MenuDefaultBgColor"
diff --git a/indra/newview/skins/default/xui/en/widgets/menu.xml b/indra/newview/skins/default/xui/en/widgets/menu.xml
index 13ac84beb2..13ac84beb2 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/menu.xml
+++ b/indra/newview/skins/default/xui/en/widgets/menu.xml
diff --git a/indra/newview/skins/default/xui/en/widgets/menu_bar.xml b/indra/newview/skins/default/xui/en/widgets/menu_bar.xml
index 27efa72563..27efa72563 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/menu_bar.xml
+++ b/indra/newview/skins/default/xui/en/widgets/menu_bar.xml
diff --git a/indra/newview/skins/default/xui/en/widgets/menu_item.xml b/indra/newview/skins/default/xui/en/widgets/menu_item.xml
index 563f3dc5c2..563f3dc5c2 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/menu_item.xml
+++ b/indra/newview/skins/default/xui/en/widgets/menu_item.xml
diff --git a/indra/newview/skins/default/xui/en/widgets/menu_item_call.xml b/indra/newview/skins/default/xui/en/widgets/menu_item_call.xml
index 24bda97f44..24bda97f44 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/menu_item_call.xml
+++ b/indra/newview/skins/default/xui/en/widgets/menu_item_call.xml
diff --git a/indra/newview/skins/default/xui/en/widgets/menu_item_check.xml b/indra/newview/skins/default/xui/en/widgets/menu_item_check.xml
index f6b06cb50b..f6b06cb50b 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/menu_item_check.xml
+++ b/indra/newview/skins/default/xui/en/widgets/menu_item_check.xml
diff --git a/indra/newview/skins/default/xui/en/widgets/menu_item_separator.xml b/indra/newview/skins/default/xui/en/widgets/menu_item_separator.xml
index 7452d685eb..7452d685eb 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/menu_item_separator.xml
+++ b/indra/newview/skins/default/xui/en/widgets/menu_item_separator.xml
diff --git a/indra/newview/skins/default/xui/en/widgets/menu_item_tear_off.xml b/indra/newview/skins/default/xui/en/widgets/menu_item_tear_off.xml
index 72af3924c1..72af3924c1 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/menu_item_tear_off.xml
+++ b/indra/newview/skins/default/xui/en/widgets/menu_item_tear_off.xml
diff --git a/indra/newview/skins/default/xui/en/widgets/multi_slider.xml b/indra/newview/skins/default/xui/en/widgets/multi_slider.xml
index 90b0625982..90b0625982 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/multi_slider.xml
+++ b/indra/newview/skins/default/xui/en/widgets/multi_slider.xml
diff --git a/indra/newview/skins/default/xui/en/widgets/multi_slider_bar.xml b/indra/newview/skins/default/xui/en/widgets/multi_slider_bar.xml
index bbcb008df4..bbcb008df4 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/multi_slider_bar.xml
+++ b/indra/newview/skins/default/xui/en/widgets/multi_slider_bar.xml
diff --git a/indra/newview/skins/default/xui/en/widgets/name_editor.xml b/indra/newview/skins/default/xui/en/widgets/name_editor.xml
index 21ba5c77f8..21ba5c77f8 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/name_editor.xml
+++ b/indra/newview/skins/default/xui/en/widgets/name_editor.xml
diff --git a/indra/newview/skins/default/xui/en/widgets/name_list.xml b/indra/newview/skins/default/xui/en/widgets/name_list.xml
index 3ae0f68227..3ae0f68227 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/name_list.xml
+++ b/indra/newview/skins/default/xui/en/widgets/name_list.xml
diff --git a/indra/newview/skins/default/xui/en/widgets/outbox_folder_view_folder.xml b/indra/newview/skins/default/xui/en/widgets/outbox_folder_view_folder.xml
deleted file mode 100644
index d19c47f54f..0000000000
--- a/indra/newview/skins/default/xui/en/widgets/outbox_folder_view_folder.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<outbox_folder_view_folder
- folder_arrow_image="Folder_Arrow"
- folder_indentation="8"
- item_height="20"
- item_top_pad="4"
- selection_image="Rounded_Square"
- >
-</outbox_folder_view_folder>
diff --git a/indra/newview/skins/default/xui/en/widgets/outbox_inventory_panel.xml b/indra/newview/skins/default/xui/en/widgets/outbox_inventory_panel.xml
deleted file mode 100644
index 3964569da2..0000000000
--- a/indra/newview/skins/default/xui/en/widgets/outbox_inventory_panel.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<outbox_inventory_panel show_empty_message="false" show_load_status="false" />
diff --git a/indra/newview/skins/default/xui/en/widgets/output_monitor.xml b/indra/newview/skins/default/xui/en/widgets/output_monitor.xml
index 9d71ceca2f..9d71ceca2f 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/output_monitor.xml
+++ b/indra/newview/skins/default/xui/en/widgets/output_monitor.xml
diff --git a/indra/newview/skins/default/xui/en/widgets/panel.xml b/indra/newview/skins/default/xui/en/widgets/panel.xml
index b36f723831..b36f723831 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/panel.xml
+++ b/indra/newview/skins/default/xui/en/widgets/panel.xml
diff --git a/indra/newview/skins/default/xui/en/widgets/panel_camera_item.xml b/indra/newview/skins/default/xui/en/widgets/panel_camera_item.xml
index 98707b8495..98707b8495 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/panel_camera_item.xml
+++ b/indra/newview/skins/default/xui/en/widgets/panel_camera_item.xml
diff --git a/indra/newview/skins/default/xui/en/widgets/person_tab_view.xml b/indra/newview/skins/default/xui/en/widgets/person_tab_view.xml
new file mode 100644
index 0000000000..af5aec2c34
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/person_tab_view.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<person_tab_view
+ folder_arrow_image="Folder_Arrow"
+ folder_indentation="5"
+ item_height="24"
+ item_top_pad="3"
+ mouse_opaque="true"
+ follows="left|top|right"
+ text_pad="6"
+ text_pad_left="4"
+ text_pad_right="4"
+ arrow_size="10"
+ max_folder_item_overlap="2"/>
diff --git a/indra/newview/skins/default/xui/en/widgets/person_view.xml b/indra/newview/skins/default/xui/en/widgets/person_view.xml
new file mode 100644
index 0000000000..46c1b7ff75
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/person_view.xml
@@ -0,0 +1,127 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<person_view
+ folder_arrow_image="Folder_Arrow"
+ folder_indentation="5"
+ item_height="24"
+ item_top_pad="3"
+ mouse_opaque="true"
+ follows="left|top|right"
+ icon_pad="4"
+ icon_width="20"
+ text_pad="6"
+ text_pad_left="4"
+ text_pad_right="4"
+ arrow_size="10"
+ max_folder_item_overlap="2">
+ <facebook_icon
+ follows="left"
+ height="14"
+ image_name="Facebook_Icon"
+ left="5"
+ bottom="6"
+ name="facebook_icon"
+ tool_tip="Facebook User"
+ visible="false"
+ width="14" />
+ <avatar_icon
+ follows="left"
+ layout="topleft"
+ height="20"
+ default_icon_name="Generic_Person"
+ left="5"
+ top="2"
+ visible="false"
+ width="20" />
+ <last_interaction_time_textbox
+ layout="topleft"
+ follows="right"
+ font="SansSerifSmall"
+ height="15"
+ left_pad="5"
+ right="-164"
+ name="last_interaction_time_textbox"
+ text_color="LtGray_50"
+ value="0s"
+ visible="false"
+ width="35" />
+ <permission_edit_theirs_icon
+ layout="topleft"
+ height="16"
+ follows="right"
+ image_name="Permission_Edit_Objects_Theirs"
+ left_pad="3"
+ right="-129"
+ name="permission_edit_theirs_icon"
+ tool_tip="You can edit this friend&apos;s objects"
+ top="4"
+ visible="false"
+ width="16" />
+ <permission_edit_mine_icon
+ layout="topleft"
+ height="16"
+ follows="right"
+ image_name="Permission_Edit_Objects_Mine"
+ left_pad="3"
+ right="-110"
+ name="permission_edit_mine_icon"
+ tool_tip="This friend can edit, delete or take your objects"
+ top="4"
+ visible="false"
+ width="16" />
+ <permission_map_icon
+ height="16"
+ follows="right"
+ image_name="Permission_Visible_Map"
+ left_pad="3"
+ tool_tip="This friend can locate you on the map"
+ right="-91"
+ name="permission_map_icon"
+ visible="false"
+ width="16" />
+ <permission_online_icon
+ height="16"
+ follows="right"
+ image_name="Permission_Visible_Online"
+ left_pad="3"
+ right="-72"
+ name="permission_online_icon"
+ tool_tip="This friend can see when you&apos;re online"
+ visible="false"
+ width="16" />
+ <info_btn
+ follows="right"
+ height="16"
+ image_pressed="Info_Press"
+ image_unselected="Info_Over"
+ left_pad="3"
+ right="-53"
+ name="info_btn"
+ tool_tip="More info"
+ tab_stop="false"
+ visible="false"
+ width="16" />
+ <profile_btn
+ layout="topleft"
+ follows="right"
+ height="20"
+ image_overlay="Web_Profile_Off"
+ left_pad="5"
+ right="-28"
+ name="profile_btn"
+ tab_stop="false"
+ tool_tip="View profile"
+ top="2"
+ visible="false"
+ width="20" />
+ <output_monitor
+ auto_update="true"
+ follows="right"
+ draw_border="false"
+ height="16"
+ right="-3"
+ mouse_opaque="true"
+ name="speaking_indicator"
+ visible="false"
+ width="20" />
+ </person_view>
+
diff --git a/indra/newview/skins/default/xui/en/widgets/progress_bar.xml b/indra/newview/skins/default/xui/en/widgets/progress_bar.xml
index 339e53fbb8..339e53fbb8 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/progress_bar.xml
+++ b/indra/newview/skins/default/xui/en/widgets/progress_bar.xml
diff --git a/indra/newview/skins/default/xui/en/widgets/radio_group.xml b/indra/newview/skins/default/xui/en/widgets/radio_group.xml
index ab3184d34b..ab3184d34b 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/radio_group.xml
+++ b/indra/newview/skins/default/xui/en/widgets/radio_group.xml
diff --git a/indra/newview/skins/default/xui/en/widgets/radio_item.xml b/indra/newview/skins/default/xui/en/widgets/radio_item.xml
index 3ddf18b2cb..3ddf18b2cb 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/radio_item.xml
+++ b/indra/newview/skins/default/xui/en/widgets/radio_item.xml
diff --git a/indra/newview/skins/default/xui/en/widgets/scroll_bar.xml b/indra/newview/skins/default/xui/en/widgets/scroll_bar.xml
index 682dcf40d8..682dcf40d8 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/scroll_bar.xml
+++ b/indra/newview/skins/default/xui/en/widgets/scroll_bar.xml
diff --git a/indra/newview/skins/default/xui/en/widgets/scroll_column_header.xml b/indra/newview/skins/default/xui/en/widgets/scroll_column_header.xml
index 8a48fcb32d..8a48fcb32d 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/scroll_column_header.xml
+++ b/indra/newview/skins/default/xui/en/widgets/scroll_column_header.xml
diff --git a/indra/newview/skins/default/xui/en/widgets/scroll_container.xml b/indra/newview/skins/default/xui/en/widgets/scroll_container.xml
index a6d096a964..a6d096a964 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/scroll_container.xml
+++ b/indra/newview/skins/default/xui/en/widgets/scroll_container.xml
diff --git a/indra/newview/skins/default/xui/en/widgets/scroll_list.xml b/indra/newview/skins/default/xui/en/widgets/scroll_list.xml
index e43989c6c7..e43989c6c7 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/scroll_list.xml
+++ b/indra/newview/skins/default/xui/en/widgets/scroll_list.xml
diff --git a/indra/newview/skins/default/xui/en/widgets/scrolling_panel_list.xml b/indra/newview/skins/default/xui/en/widgets/scrolling_panel_list.xml
index 40cbf5977a..40cbf5977a 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/scrolling_panel_list.xml
+++ b/indra/newview/skins/default/xui/en/widgets/scrolling_panel_list.xml
diff --git a/indra/newview/skins/default/xui/en/widgets/search_combo_box.xml b/indra/newview/skins/default/xui/en/widgets/search_combo_box.xml
index ce84cfedc0..ce84cfedc0 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/search_combo_box.xml
+++ b/indra/newview/skins/default/xui/en/widgets/search_combo_box.xml
diff --git a/indra/newview/skins/default/xui/en/widgets/search_editor.xml b/indra/newview/skins/default/xui/en/widgets/search_editor.xml
index faa0404b35..faa0404b35 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/search_editor.xml
+++ b/indra/newview/skins/default/xui/en/widgets/search_editor.xml
diff --git a/indra/newview/skins/default/xui/en/widgets/side_tray.xml b/indra/newview/skins/default/xui/en/widgets/side_tray.xml
index 022564c12f..022564c12f 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/side_tray.xml
+++ b/indra/newview/skins/default/xui/en/widgets/side_tray.xml
diff --git a/indra/newview/skins/default/xui/en/widgets/sidetray_tab.xml b/indra/newview/skins/default/xui/en/widgets/sidetray_tab.xml
index aa8461d367..aa8461d367 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/sidetray_tab.xml
+++ b/indra/newview/skins/default/xui/en/widgets/sidetray_tab.xml
diff --git a/indra/newview/skins/default/xui/en/widgets/simple_text_editor.xml b/indra/newview/skins/default/xui/en/widgets/simple_text_editor.xml
index a120b1aec8..a120b1aec8 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/simple_text_editor.xml
+++ b/indra/newview/skins/default/xui/en/widgets/simple_text_editor.xml
diff --git a/indra/newview/skins/default/xui/en/widgets/slider.xml b/indra/newview/skins/default/xui/en/widgets/slider.xml
index f735d09476..f735d09476 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/slider.xml
+++ b/indra/newview/skins/default/xui/en/widgets/slider.xml
diff --git a/indra/newview/skins/default/xui/en/widgets/slider_bar.xml b/indra/newview/skins/default/xui/en/widgets/slider_bar.xml
index 0335213ed6..0335213ed6 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/slider_bar.xml
+++ b/indra/newview/skins/default/xui/en/widgets/slider_bar.xml
diff --git a/indra/newview/skins/default/xui/en/widgets/spinner.xml b/indra/newview/skins/default/xui/en/widgets/spinner.xml
index d7af6077e5..d7af6077e5 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/spinner.xml
+++ b/indra/newview/skins/default/xui/en/widgets/spinner.xml
diff --git a/indra/newview/skins/default/xui/en/widgets/split_button.xml b/indra/newview/skins/default/xui/en/widgets/split_button.xml
index 2ff9ada90a..2ff9ada90a 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/split_button.xml
+++ b/indra/newview/skins/default/xui/en/widgets/split_button.xml
diff --git a/indra/newview/skins/default/xui/en/widgets/tab_container.xml b/indra/newview/skins/default/xui/en/widgets/tab_container.xml
index 0586119681..9559be214a 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/tab_container.xml
+++ b/indra/newview/skins/default/xui/en/widgets/tab_container.xml
@@ -24,17 +24,26 @@ label_pad_left - padding to the left of tab button labels
tab_bottom_image_unselected="Toolbar_Left_Off"
tab_bottom_image_selected="Toolbar_Left_Selected"
tab_left_image_unselected="SegmentedBtn_Left_Disabled"
- tab_left_image_selected="SegmentedBtn_Left_Selected_Over"/>
+ tab_left_image_selected="SegmentedBtn_Left_Selected_Over"
+ tab_top_image_hovered="TabTop_Left_Selected"
+ tab_button_image_hovered="Toolbar_Left_Selected"
+ tab_left_image_hovered="SegmentedBtn_Left_Selected_Over"/>
<middle_tab tab_top_image_unselected="TabTop_Middle_Off"
tab_top_image_selected="TabTop_Middle_Selected"
tab_bottom_image_unselected="Toolbar_Middle_Off"
tab_bottom_image_selected="Toolbar_Middle_Selected"
tab_left_image_unselected="SegmentedBtn_Left_Disabled"
- tab_left_image_selected="SegmentedBtn_Left_Selected_Over"/>
+ tab_left_image_selected="SegmentedBtn_Left_Selected_Over"
+ tab_top_image_hovered="TabTop_Middle_Selected"
+ tab_button_image_hovered="Toolbar_Middle_Selected"
+ tab_left_image_hovered="SegmentedBtn_Left_Selected_Over"/>
<last_tab tab_top_image_unselected="TabTop_Right_Off"
tab_top_image_selected="TabTop_Right_Selected"
tab_bottom_image_unselected="Toolbar_Right_Off"
tab_bottom_image_selected="Toolbar_Right_Selected"
tab_left_image_unselected="SegmentedBtn_Left_Disabled"
- tab_left_image_selected="SegmentedBtn_Left_Selected_Over"/>
+ tab_left_image_selected="SegmentedBtn_Left_Selected_Over"
+ tab_top_image_hovered="TabTop_Right_Selected"
+ tab_button_image_hovered="Toolbar_Right_Selected"
+ tab_left_image_hovered="SegmentedBtn_Left_Selected_Over"/>
</tab_container>
diff --git a/indra/newview/skins/default/xui/en/widgets/talk_button.xml b/indra/newview/skins/default/xui/en/widgets/talk_button.xml
index d792e9f29c..d792e9f29c 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/talk_button.xml
+++ b/indra/newview/skins/default/xui/en/widgets/talk_button.xml
diff --git a/indra/newview/skins/default/xui/en/widgets/teleport_history_menu_item.xml b/indra/newview/skins/default/xui/en/widgets/teleport_history_menu_item.xml
index 4f574d75d5..4f574d75d5 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/teleport_history_menu_item.xml
+++ b/indra/newview/skins/default/xui/en/widgets/teleport_history_menu_item.xml
diff --git a/indra/newview/skins/default/xui/en/widgets/text.xml b/indra/newview/skins/default/xui/en/widgets/text.xml
index 134f2d7522..2102074674 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/text.xml
+++ b/indra/newview/skins/default/xui/en/widgets/text.xml
@@ -9,6 +9,7 @@
h_pad="0"
allow_scroll="false"
text_readonly_color="LabelTextColor"
+ text_tentative_color="TextFgTentativeColor"
bg_writeable_color="FloaterDefaultBackgroundColor"
use_ellipses="false"
bg_visible="false"
diff --git a/indra/newview/skins/default/xui/en/widgets/text_editor.xml b/indra/newview/skins/default/xui/en/widgets/text_editor.xml
index 100571cc01..100571cc01 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/text_editor.xml
+++ b/indra/newview/skins/default/xui/en/widgets/text_editor.xml
diff --git a/indra/newview/skins/default/xui/en/widgets/textbase.xml b/indra/newview/skins/default/xui/en/widgets/textbase.xml
index b2da2147c1..b2da2147c1 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/textbase.xml
+++ b/indra/newview/skins/default/xui/en/widgets/textbase.xml
diff --git a/indra/newview/skins/default/xui/en/widgets/texture_picker.xml b/indra/newview/skins/default/xui/en/widgets/texture_picker.xml
index ba2fdf4f1f..ba2fdf4f1f 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/texture_picker.xml
+++ b/indra/newview/skins/default/xui/en/widgets/texture_picker.xml
diff --git a/indra/newview/skins/default/xui/en/widgets/time.xml b/indra/newview/skins/default/xui/en/widgets/time.xml
index b5bdd564a6..b5bdd564a6 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/time.xml
+++ b/indra/newview/skins/default/xui/en/widgets/time.xml
diff --git a/indra/newview/skins/default/xui/en/widgets/toggleable_menu.xml b/indra/newview/skins/default/xui/en/widgets/toggleable_menu.xml
index 48950a98ad..48950a98ad 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/toggleable_menu.xml
+++ b/indra/newview/skins/default/xui/en/widgets/toggleable_menu.xml
diff --git a/indra/newview/skins/default/xui/en/widgets/tool_tip.xml b/indra/newview/skins/default/xui/en/widgets/tool_tip.xml
index 9ca15ae50d..9ca15ae50d 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/tool_tip.xml
+++ b/indra/newview/skins/default/xui/en/widgets/tool_tip.xml
diff --git a/indra/newview/skins/default/xui/en/widgets/toolbar.xml b/indra/newview/skins/default/xui/en/widgets/toolbar.xml
index 0aa478ace9..0ace37a5dc 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/toolbar.xml
+++ b/indra/newview/skins/default/xui/en/widgets/toolbar.xml
@@ -30,9 +30,9 @@
image_overlay_alignment="left"
use_ellipses="true"
auto_resize="true"
- button_flash_count="99999"
- button_flash_rate="1.0"
- flash_color="EmphasisColor"/>
+ button_flash_count="4"
+ button_flash_rate="0.5"
+ flash_color="BeaconColor"/>
<button_icon pad_left="10"
pad_right="10"
image_bottom_pad="10"
@@ -51,7 +51,7 @@
chrome="true"
use_ellipses="true"
auto_resize="true"
- button_flash_count="99999"
- button_flash_rate="1.0"
- flash_color="EmphasisColor"/>
+ button_flash_count="4"
+ button_flash_rate="0.5"
+ flash_color="BeaconColor"/>
</toolbar>
diff --git a/indra/newview/skins/default/xui/en/widgets/ui_ctrl.xml b/indra/newview/skins/default/xui/en/widgets/ui_ctrl.xml
index f4dbb8f404..f4dbb8f404 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/ui_ctrl.xml
+++ b/indra/newview/skins/default/xui/en/widgets/ui_ctrl.xml
diff --git a/indra/newview/skins/default/xui/en/widgets/view_border.xml b/indra/newview/skins/default/xui/en/widgets/view_border.xml
index bf40e3086b..bf40e3086b 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/view_border.xml
+++ b/indra/newview/skins/default/xui/en/widgets/view_border.xml
diff --git a/indra/newview/skins/default/xui/en/widgets/web_browser.xml b/indra/newview/skins/default/xui/en/widgets/web_browser.xml
index 676fafd828..676fafd828 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/web_browser.xml
+++ b/indra/newview/skins/default/xui/en/widgets/web_browser.xml
diff --git a/indra/newview/skins/default/xui/en/widgets/window_shade.xml b/indra/newview/skins/default/xui/en/widgets/window_shade.xml
index 23eb2f13fb..23eb2f13fb 100644..100755
--- a/indra/newview/skins/default/xui/en/widgets/window_shade.xml
+++ b/indra/newview/skins/default/xui/en/widgets/window_shade.xml
diff --git a/indra/newview/skins/default/xui/en/xui_version.xml b/indra/newview/skins/default/xui/en/xui_version.xml
index 0e777751d3..0e777751d3 100644..100755
--- a/indra/newview/skins/default/xui/en/xui_version.xml
+++ b/indra/newview/skins/default/xui/en/xui_version.xml
diff --git a/indra/newview/skins/default/xui/es/floater_about.xml b/indra/newview/skins/default/xui/es/floater_about.xml
index 307b61133f..e0a2375067 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_about.xml
+++ b/indra/newview/skins/default/xui/es/floater_about.xml
@@ -8,7 +8,9 @@
Compilado con [COMPILER], versión [COMPILER_VERSION]
</floater.string>
<floater.string name="AboutPosition">
- Estás en la posición [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1], de [REGION], alojada en &lt;nolink&gt;[HOSTNAME]&lt;/nolink&gt; ([HOSTIP])
+ Estás en la posición [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] de [REGION], alojada en &lt;nolink&gt;[HOSTNAME]&lt;/nolink&gt; ([HOSTIP])
+SLURL: &lt;nolink&gt;[SLURL]&lt;/nolink&gt;
+(coordenadas globales [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1])
[SERVER_VERSION]
[SERVER_RELEASE_NOTES_URL]
</floater.string>
@@ -66,27 +68,26 @@ Versión del servidor de voz: [VOICE_VERSION]
</panel>
<panel label="Licencias" name="licenses_panel">
<text_editor name="credits_editor">
- 3Dconnexion SDK Copyright (C) 1992-2007 3Dconnexion
- APR Copyright (C) 2000-2004 The Apache Software Foundation
- Collada DOM Copyright 2005 Sony Computer Entertainment Inc.
- cURL Copyright (C) 1996-2002, Daniel Stenberg, (daniel@haxx.se)
+ 3Dconnexion SDK Copyright (C) 1992-2009 3Dconnexion
+ APR Copyright (C) 2011 The Apache Software Foundation
+ Collada DOM Copyright 2006 Sony Computer Entertainment Inc.
+ cURL Copyright (C) 1996-2010, Daniel Stenberg, (daniel@haxx.se)
DBus/dbus-glib Copyright (C) 2002, 2003 CodeFactory AB / Copyright (C) 2003, 2004 Red Hat, Inc.
expat Copyright (C) 1998, 1999, 2000 Thai Open Source Software Center Ltd.
- FreeType Copyright (C) 1996-2002, The FreeType Project (www.freetype.org).
+ FreeType Copyright (C) 1996-2002, 2006 David Turner, Robert Wilhelm, and Werner Lemberg.
GL Copyright (C) 1999-2004 Brian Paul.
GLOD Copyright (C) 2003-04 Jonathan Cohen, Nat Duca, Chris Niski, Johns Hopkins University and David Luebke, Brenden Schubert, University of Virginia.
google-perftools Copyright (c) 2005, Google Inc.
Havok.com(TM) Copyright (C) 1999-2001, Telekinesys Research Limited.
jpeg2000 Copyright (C) 2001, David Taubman, The University of New South Wales (UNSW)
jpeglib Copyright (C) 1991-1998, Thomas G. Lane.
- ogg/vorbis Copyright (C) 2001, Xiphophorus
- OpenSSL Copyright (C) 1998-2002 The OpenSSL Project.
- PCRE Copyright (c) 1997-2008 University of Cambridge
+ ogg/vorbis Copyright (C) 2002, Xiphophorus
+ OpenSSL Copyright (C) 1998-2008 The OpenSSL Project.
+ PCRE Copyright (c) 1997-2012 University of Cambridge
SDL Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga
SSLeay Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
xmlrpc-epi Copyright (C) 2000 Epinions, Inc.
- zlib Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler.
- google-perftools Copyright (c) 2005, Google Inc.
+ zlib Copyright (C) 1995-2012 Jean-loup Gailly and Mark Adler.
El visor de Second Life usa Havok (TM) Physics. (c)Copyright 1999-2010 Havok.com Inc. (y sus licenciadores). Reservados todos los derechos. Vea los detalles en www.havok.com.
diff --git a/indra/newview/skins/default/xui/es/floater_about_land.xml b/indra/newview/skins/default/xui/es/floater_about_land.xml
index fd54d74af2..f8c40d798a 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/es/floater_about_land.xml
@@ -465,7 +465,7 @@ los media:
Permitir únicamente el acceso a los Residentes que:
</text>
<check_box label="Han aportado información de pago [ESTATE_PAYMENT_LIMIT]" name="limit_payment" tool_tip="Para poder acceder a esta parcela los Residentes deben haber aportado información de pago en su cuenta. Para más información, ver [SUPPORT_SITE]."/>
- <check_box label="Han verificado su edad [ESTATE_AGE_LIMIT]" name="limit_age_verified" tool_tip="Para poder acceder a esta parcela los Residentes deben haber verificado su edad. Para más información, ver [SUPPORT_SITE]."/>
+ <check_box label="Son mayores de 18 años [ESTATE_AGE_LIMIT]" name="limit_age_verified" tool_tip="Para poder acceder a esta parcela los Residentes deben ser mayores de 18 años. Para más información, consulta [SUPPORT_SITE]."/>
<check_box label="Acceso permitido al grupo: [GROUP]" name="GroupCheck" tool_tip="Elija el grupo en la pestaña General."/>
<check_box label="Vender pases a:" name="PassCheck" tool_tip="Permitir acceso temporal a esta parcela"/>
<combo_box name="pass_combo">
diff --git a/indra/newview/skins/default/xui/es/floater_activeim.xml b/indra/newview/skins/default/xui/es/floater_activeim.xml
index 988786c1ae..988786c1ae 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_activeim.xml
+++ b/indra/newview/skins/default/xui/es/floater_activeim.xml
diff --git a/indra/newview/skins/default/xui/es/floater_animation_preview.xml b/indra/newview/skins/default/xui/es/floater_animation_preview.xml
deleted file mode 100644
index d57405f7e5..0000000000
--- a/indra/newview/skins/default/xui/es/floater_animation_preview.xml
+++ /dev/null
@@ -1,187 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Animation Preview" title="">
- <floater.string name="failed_to_initialize">
- Fallo al iniciar el movimiento
- </floater.string>
- <floater.string name="anim_too_long">
- El archivo de la animación dura [LENGTH] segundos.
-
-La duración máxima de una animación es de [MAX_LENGTH] segundos.
- </floater.string>
- <floater.string name="failed_file_read">
- No se ha podido leer el archivo de la animación.
-
-[STATUS]
- </floater.string>
- <floater.string name="E_ST_OK">
- OK
- </floater.string>
- <floater.string name="E_ST_EOF">
- Fin prematuro del archivo.
- </floater.string>
- <floater.string name="E_ST_NO_CONSTRAINT">
- No se puede leer la definición de la restricción.
- </floater.string>
- <floater.string name="E_ST_NO_FILE">
- No se puede abrir el archivo BVH.
- </floater.string>
- <floater.string name="E_ST_NO_HIER">
- &apos;HIERARCHY header&apos; inválido.
- </floater.string>
- <floater.string name="E_ST_NO_JOINT">
- No se pueden encontrar &apos;ROOT&apos; o &apos;JOINT&apos;.
- </floater.string>
- <floater.string name="E_ST_NO_NAME">
- No se puede obtener el nombre &apos;JOINT&apos;.
- </floater.string>
- <floater.string name="E_ST_NO_OFFSET">
- No se puede encontrar &apos;OFFSET&apos;.
- </floater.string>
- <floater.string name="E_ST_NO_CHANNELS">
- No se puede encontrar &apos;CHANNELS&apos;.
- </floater.string>
- <floater.string name="E_ST_NO_ROTATION">
- No se puede conseguir el orden de la rotación.
- </floater.string>
- <floater.string name="E_ST_NO_AXIS">
- No se puede encontrar el eje de rotación.
- </floater.string>
- <floater.string name="E_ST_NO_MOTION">
- No se puede encontrar &apos;MOTION&apos;.
- </floater.string>
- <floater.string name="E_ST_NO_FRAMES">
- No se puede conseguir el número de frames.
- </floater.string>
- <floater.string name="E_ST_NO_FRAME_TIME">
- No se puede conseguir el tiempo del frame.
- </floater.string>
- <floater.string name="E_ST_NO_POS">
- No se pueden conseguir los valores de la posición.
- </floater.string>
- <floater.string name="E_ST_NO_ROT">
- No se pueden conseguir los valores de la rotación.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_FILE">
- No se puede abrir el archivo de traducción.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_HEADER">
- No se puede leer el encabezamiento de la traducción.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_NAME">
- No se puede leer la traducción de los nombres.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_IGNORE">
- No se puede leer la traducción de los valores ignorados.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_RELATIVE">
- No se puede leer el valor relativo de la traducción.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_OUTNAME">
- No se puede leer la traducción del valor &apos;outname&apos;
- </floater.string>
- <floater.string name="E_ST_NO_XLT_MATRIX">
- No se puede leer la matriz de traducciones.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_MERGECHILD">
- No se puede conseguir el nombre &apos;mergechild&apos;.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_MERGEPARENT">
- No se puede conseguir el nombre &apos;mergeparent&apos;.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_PRIORITY">
- No se puede obtener el valor prioritario.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_LOOP">
- No se puede conseguir el valor del bucle.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_EASEIN">
- No se pueden conseguir los valores &apos;easeIn&apos;.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_EASEOUT">
- No se pueden conseguir los valores &apos;easeOut&apos;.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_HAND">
- No se puede conseguir el valor de &apos;hand morph&apos;.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_EMOTE">
- No se puede leer el nombre del gesto.
- </floater.string>
- <floater.string name="E_ST_BAD_ROOT">
- Nombre incorrecto de &apos;root joint&apos;, usa &quot;hip&quot;.
- </floater.string>
- <text name="name_label">
- Nombre:
- </text>
- <text name="description_label">
- Descripción:
- </text>
- <spinner label="Prioridad:" name="priority" tool_tip="Controla qué otras animaciones pueden ser anuladas por ésta"/>
- <check_box label="Bucle:" name="loop_check" tool_tip="Hace esta animación en bucle"/>
- <spinner label="Empieza(%)" name="loop_in_point" tool_tip="Indica el punto en el que la animación vuelve a empezar"/>
- <spinner label="Acaba(%)" name="loop_out_point" tool_tip="Indica el punto en el que la animación acaba el bucle"/>
- <text name="hand_label">
- Posición de las manos
- </text>
- <combo_box name="hand_pose_combo" tool_tip="Controla qué hacen las manos durante la animación">
- <combo_box.item label="Extendidas" name="Spread"/>
- <combo_box.item label="Relajadas" name="Relaxed"/>
- <combo_box.item label="Ambas señalan" name="PointBoth"/>
- <combo_box.item label="Puño" name="Fist"/>
- <combo_box.item label="La izq. relajada" name="RelaxedLeft"/>
- <combo_box.item label="La izq. señala" name="PointLeft"/>
- <combo_box.item label="Puño izq." name="FistLeft"/>
- <combo_box.item label="La der. relajada" name="RelaxedRight"/>
- <combo_box.item label="La der. señala" name="PointRight"/>
- <combo_box.item label="Puño der." name="FistRight"/>
- <combo_box.item label="La derecha saluda" name="SaluteRight"/>
- <combo_box.item label="Escribiendo" name="Typing"/>
- <combo_box.item label="&apos;Paz&apos; en la der." name="PeaceRight"/>
- </combo_box>
- <text name="emote_label">
- Expresión
- </text>
- <combo_box name="emote_combo" tool_tip="Controla qué hace la cara durante la animación">
- <item label="(ninguno)" name="[None]" value=""/>
- <item label="Aaaaah" name="Aaaaah" value="Aaaaah"/>
- <item label="Con miedo" name="Afraid" value="Miedo"/>
- <item label="Enfado" name="Angry" value="Enfado"/>
- <item label="Gran sonrisa" name="BigSmile" value="Gran sonrisa"/>
- <item label="Aburrimiento" name="Bored" value="Aburrimiento"/>
- <item label="Llorar" name="Cry" value="Lloro"/>
- <item label="Desdén" name="Disdain" value="Desdén"/>
- <item label="Avergonzarse" name="Embarrassed" value="Vergüenza"/>
- <item label="Fruncir el ceño" name="Frown" value="Fruncir el ceño"/>
- <item label="Beso" name="Kiss" value="Beso"/>
- <item label="Reír" name="Laugh" value="Risa"/>
- <item label="Sacar la lengua" name="Plllppt" value="Sacar la lengua"/>
- <item label="Rechazo" name="Repulsed" value="Rechazo"/>
- <item label="Triste" name="Sad" value="Tristeza"/>
- <item label="Encogerse de hombros" name="Shrug" value="Encogerse de hombros"/>
- <item label="Sonrisa" name="Smile" value="Sonrisa"/>
- <item label="Sorpresa" name="Surprise" value="Sorpresa"/>
- <item label="Guiño" name="Wink" value="Guiño"/>
- <item label="Preocupación" name="Worry" value="Preocupación"/>
- </combo_box>
- <text name="preview_label">
- Vista previa mientras
- </text>
- <combo_box name="preview_base_anim" tool_tip="Compruebe cómo se comporta su animación a la vez que el avatar realiza acciones comunes.">
- <item label="De pie" name="Standing" value="De pie"/>
- <item label="Caminando" name="Walking" value="Caminando"/>
- <item label="Sentado/a" name="Sitting" value="Sentado"/>
- <item label="Volando" name="Flying" value="Volando"/>
- </combo_box>
- <spinner label="Combinar (sec)" name="ease_in_time" tool_tip="Tiempo (en segundos) en el que se combinan las animaciones"/>
- <spinner label="Dejar de combinar (sec)" name="ease_out_time" tool_tip="Tiempo (en segundos) en el que dejan de combinarse las animaciones"/>
- <button bottom_delta="-32" name="play_btn" tool_tip="Ejecutar tu animación"/>
- <button name="pause_btn" tool_tip="Pausar tu animación"/>
- <button label="" name="stop_btn" tool_tip="Parar la repetición de la animación"/>
- <slider label="" name="playback_slider"/>
- <text name="bad_animation_text">
- No se ha podido leer el archivo de la animación.
-
-Recomendamos usar archivos BVH exportados de Poser 4.
- </text>
- <button label="Subir ([AMOUNT] L$)" name="ok_btn"/>
- <button label="Cancelar" name="cancel_btn"/>
-</floater>
diff --git a/indra/newview/skins/default/xui/es/floater_auction.xml b/indra/newview/skins/default/xui/es/floater_auction.xml
index 6faf19dbb5..6faf19dbb5 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_auction.xml
+++ b/indra/newview/skins/default/xui/es/floater_auction.xml
diff --git a/indra/newview/skins/default/xui/es/floater_autoreplace.xml b/indra/newview/skins/default/xui/es/floater_autoreplace.xml
new file mode 100755
index 0000000000..15abccc376
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/floater_autoreplace.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="autoreplace_floater" title="Configuración de reemplazo automático">
+ <check_box label="Habilitar el reemplazo automático" name="autoreplace_enable" tool_tip="Al escribir el texto del chat, reemplaza las palabras clave especificadas con la sustitución correspondiente"/>
+ <button label="Importar lista..." name="autoreplace_import_list" tool_tip="Carga una lista previamente exportada desde un archivo."/>
+ <button label="Exportar lista..." name="autoreplace_export_list" tool_tip="Guarda la lista seleccionada en un archivo para poder compartirla."/>
+ <button label="Lista nueva..." name="autoreplace_new_list" tool_tip="Crea una lista nueva."/>
+ <button label="Eliminar lista" name="autoreplace_delete_list" tool_tip="Elimina la lista seleccionada."/>
+ <button name="autoreplace_list_up" tool_tip="Aumenta la prioridad de esta lista."/>
+ <button name="autoreplace_list_down" tool_tip="Baja la prioridad de esta lista."/>
+ <scroll_list name="autoreplace_list_replacements">
+ <scroll_list.columns label="Palabra clave" name="keyword"/>
+ <scroll_list.columns label="Reemplazo" name="replacement"/>
+ </scroll_list>
+ <button label="Añadir..." name="autoreplace_add_entry"/>
+ <button label="Eliminar" name="autoreplace_delete_entry"/>
+ <button label="Guardar entrada" name="autoreplace_save_entry" tool_tip="Guarda esta entrada."/>
+ <button label="Guardar cambios" name="autoreplace_save_changes" tool_tip="Guarda todos los cambios."/>
+ <button label="Cancelar" name="autoreplace_cancel" tool_tip="Descarta todos los cambios."/>
+</floater>
+<!--
+ <text
+ top_pad="10"
+ left="10"
+ height="16"
+ width="260"
+ follows="left|top"
+ halign="center"
+ mouse_opaque="true"
+ name="autoreplace_text2">
+ Entries
+ </text>
+-->
diff --git a/indra/newview/skins/default/xui/es/floater_avatar.xml b/indra/newview/skins/default/xui/es/floater_avatar.xml
index 21d202309f..21d202309f 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_avatar.xml
+++ b/indra/newview/skins/default/xui/es/floater_avatar.xml
diff --git a/indra/newview/skins/default/xui/es/floater_avatar_picker.xml b/indra/newview/skins/default/xui/es/floater_avatar_picker.xml
index 49fce5d4ec..49fce5d4ec 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_avatar_picker.xml
+++ b/indra/newview/skins/default/xui/es/floater_avatar_picker.xml
diff --git a/indra/newview/skins/default/xui/es/floater_avatar_textures.xml b/indra/newview/skins/default/xui/es/floater_avatar_textures.xml
index 54ef34264c..54ef34264c 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_avatar_textures.xml
+++ b/indra/newview/skins/default/xui/es/floater_avatar_textures.xml
diff --git a/indra/newview/skins/default/xui/es/floater_beacons.xml b/indra/newview/skins/default/xui/es/floater_beacons.xml
index 49f990c84d..49f990c84d 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_beacons.xml
+++ b/indra/newview/skins/default/xui/es/floater_beacons.xml
diff --git a/indra/newview/skins/default/xui/es/floater_build_options.xml b/indra/newview/skins/default/xui/es/floater_build_options.xml
index a3e656cc17..a3e656cc17 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_build_options.xml
+++ b/indra/newview/skins/default/xui/es/floater_build_options.xml
diff --git a/indra/newview/skins/default/xui/es/floater_bulk_perms.xml b/indra/newview/skins/default/xui/es/floater_bulk_perms.xml
index f1948220b4..5cd8b3c01f 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_bulk_perms.xml
+++ b/indra/newview/skins/default/xui/es/floater_bulk_perms.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floaterbulkperms" title="EDITAR LOS PERMISOS DEL CONTENIDO">
+<floater name="floaterbulkperms" title="AJUSTAR LOS PERMISOS DEL CONTENIDO">
<floater.string name="nothing_to_modify_text">
Lo seleccionado tiene contenidos no editables.
</floater.string>
@@ -33,7 +33,7 @@
<button label="√ Todos" label_selected="Todo" name="check_all"/>
<button label="Limpiar" label_selected="Ninguno" name="check_none"/>
<text name="newperms">
- Permisos nuevos del contenido
+ Ajustar los permisos del contenido a
</text>
<text name="GroupLabel">
Grupo:
@@ -49,6 +49,7 @@
<check_box label="Modificarlo" name="next_owner_modify"/>
<check_box label="Copiarlo" name="next_owner_copy"/>
<check_box initial_value="true" label="Transferirlo" name="next_owner_transfer" tool_tip="El próximo propietario puede dar o revender este objeto"/>
- <button label="OK" name="apply"/>
+ <button label="OK" name="ok"/>
+ <button label="Aplicar" name="apply"/>
<button label="Cancelar" name="close"/>
</floater>
diff --git a/indra/newview/skins/default/xui/es/floater_bumps.xml b/indra/newview/skins/default/xui/es/floater_bumps.xml
index 6d4196ca7c..6d4196ca7c 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_bumps.xml
+++ b/indra/newview/skins/default/xui/es/floater_bumps.xml
diff --git a/indra/newview/skins/default/xui/es/floater_buy_contents.xml b/indra/newview/skins/default/xui/es/floater_buy_contents.xml
index 3563d4bd0f..3563d4bd0f 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_buy_contents.xml
+++ b/indra/newview/skins/default/xui/es/floater_buy_contents.xml
diff --git a/indra/newview/skins/default/xui/es/floater_buy_currency.xml b/indra/newview/skins/default/xui/es/floater_buy_currency.xml
index 2c8848265f..2c8848265f 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_buy_currency.xml
+++ b/indra/newview/skins/default/xui/es/floater_buy_currency.xml
diff --git a/indra/newview/skins/default/xui/es/floater_buy_currency_html.xml b/indra/newview/skins/default/xui/es/floater_buy_currency_html.xml
index 08ea67d4cb..08ea67d4cb 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_buy_currency_html.xml
+++ b/indra/newview/skins/default/xui/es/floater_buy_currency_html.xml
diff --git a/indra/newview/skins/default/xui/es/floater_buy_land.xml b/indra/newview/skins/default/xui/es/floater_buy_land.xml
index 005fe90318..005fe90318 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_buy_land.xml
+++ b/indra/newview/skins/default/xui/es/floater_buy_land.xml
diff --git a/indra/newview/skins/default/xui/es/floater_buy_object.xml b/indra/newview/skins/default/xui/es/floater_buy_object.xml
index a774bc6d05..a774bc6d05 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_buy_object.xml
+++ b/indra/newview/skins/default/xui/es/floater_buy_object.xml
diff --git a/indra/newview/skins/default/xui/es/floater_camera.xml b/indra/newview/skins/default/xui/es/floater_camera.xml
index b0704ab788..b0704ab788 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_camera.xml
+++ b/indra/newview/skins/default/xui/es/floater_camera.xml
diff --git a/indra/newview/skins/default/xui/es/floater_chat_bar.xml b/indra/newview/skins/default/xui/es/floater_chat_bar.xml
index 2e94805057..02369c9a43 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_chat_bar.xml
+++ b/indra/newview/skins/default/xui/es/floater_chat_bar.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="chat_bar" title="CHAT">
+<floater name="nearby_chat" title="CHAT">
<panel name="bottom_panel">
<line_editor label="Pulsa aquí para chatear." name="chat_box" tool_tip="Pulsa Enter para decirlo o Ctrl+Enter para gritarlo"/>
<button name="show_nearby_chat" tool_tip="Muestra o esconde el registro del chat"/>
diff --git a/indra/newview/skins/default/xui/es/floater_choose_group.xml b/indra/newview/skins/default/xui/es/floater_choose_group.xml
index a5967b814e..a5967b814e 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_choose_group.xml
+++ b/indra/newview/skins/default/xui/es/floater_choose_group.xml
diff --git a/indra/newview/skins/default/xui/es/floater_color_picker.xml b/indra/newview/skins/default/xui/es/floater_color_picker.xml
index ed168c09d5..ed168c09d5 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_color_picker.xml
+++ b/indra/newview/skins/default/xui/es/floater_color_picker.xml
diff --git a/indra/newview/skins/default/xui/es/floater_conversation_log.xml b/indra/newview/skins/default/xui/es/floater_conversation_log.xml
new file mode 100644
index 0000000000..9202fab92d
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/floater_conversation_log.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="floater_conversation_log" title="REGISTRO DE CONVERSACIONES">
+ <panel name="buttons_panel">
+ <filter_editor label="Filtrar la gente" name="people_filter_input"/>
+ <menu_button name="conversation_view_btn" tool_tip="Opciones de vista/orden"/>
+ <menu_button name="conversations_gear_btn" tool_tip="Acciones en la persona o el grupo seleccionado"/>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/es/floater_conversation_preview.xml b/indra/newview/skins/default/xui/es/floater_conversation_preview.xml
new file mode 100644
index 0000000000..f579e720fb
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/floater_conversation_preview.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="preview_conversation" title="CONVERSACIÓN:">
+ <floater.string name="Title">
+ CONVERSACIÓN: [NAME]
+ </floater.string>
+ <text name="page_label" value="Página"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/es/floater_critical.xml b/indra/newview/skins/default/xui/es/floater_critical.xml
index e5cbea8810..e5cbea8810 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_critical.xml
+++ b/indra/newview/skins/default/xui/es/floater_critical.xml
diff --git a/indra/newview/skins/default/xui/es/floater_delete_env_preset.xml b/indra/newview/skins/default/xui/es/floater_delete_env_preset.xml
index 5e7df8530e..5e7df8530e 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_delete_env_preset.xml
+++ b/indra/newview/skins/default/xui/es/floater_delete_env_preset.xml
diff --git a/indra/newview/skins/default/xui/es/floater_destinations.xml b/indra/newview/skins/default/xui/es/floater_destinations.xml
index df18698d2f..df18698d2f 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_destinations.xml
+++ b/indra/newview/skins/default/xui/es/floater_destinations.xml
diff --git a/indra/newview/skins/default/xui/es/floater_display_name.xml b/indra/newview/skins/default/xui/es/floater_display_name.xml
index f1a31a6776..f1a31a6776 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_display_name.xml
+++ b/indra/newview/skins/default/xui/es/floater_display_name.xml
diff --git a/indra/newview/skins/default/xui/es/floater_edit_day_cycle.xml b/indra/newview/skins/default/xui/es/floater_edit_day_cycle.xml
index 6ac46351db..6ac46351db 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_edit_day_cycle.xml
+++ b/indra/newview/skins/default/xui/es/floater_edit_day_cycle.xml
diff --git a/indra/newview/skins/default/xui/es/floater_edit_sky_preset.xml b/indra/newview/skins/default/xui/es/floater_edit_sky_preset.xml
index d2197b80fa..d2197b80fa 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_edit_sky_preset.xml
+++ b/indra/newview/skins/default/xui/es/floater_edit_sky_preset.xml
diff --git a/indra/newview/skins/default/xui/es/floater_edit_water_preset.xml b/indra/newview/skins/default/xui/es/floater_edit_water_preset.xml
index f90ad59f78..f90ad59f78 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_edit_water_preset.xml
+++ b/indra/newview/skins/default/xui/es/floater_edit_water_preset.xml
diff --git a/indra/newview/skins/default/xui/es/floater_environment_settings.xml b/indra/newview/skins/default/xui/es/floater_environment_settings.xml
index a9c5705d52..a9c5705d52 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_environment_settings.xml
+++ b/indra/newview/skins/default/xui/es/floater_environment_settings.xml
diff --git a/indra/newview/skins/default/xui/es/floater_event.xml b/indra/newview/skins/default/xui/es/floater_event.xml
index d2724bf8b0..d2724bf8b0 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_event.xml
+++ b/indra/newview/skins/default/xui/es/floater_event.xml
diff --git a/indra/newview/skins/default/xui/es/floater_fast_timers.xml b/indra/newview/skins/default/xui/es/floater_fast_timers.xml
index eeb39583ef..eeb39583ef 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_fast_timers.xml
+++ b/indra/newview/skins/default/xui/es/floater_fast_timers.xml
diff --git a/indra/newview/skins/default/xui/es/floater_font_test.xml b/indra/newview/skins/default/xui/es/floater_font_test.xml
index 9a665321a4..9a665321a4 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_font_test.xml
+++ b/indra/newview/skins/default/xui/es/floater_font_test.xml
diff --git a/indra/newview/skins/default/xui/es/floater_gesture.xml b/indra/newview/skins/default/xui/es/floater_gesture.xml
index d90de8c9f4..d90de8c9f4 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_gesture.xml
+++ b/indra/newview/skins/default/xui/es/floater_gesture.xml
diff --git a/indra/newview/skins/default/xui/es/floater_god_tools.xml b/indra/newview/skins/default/xui/es/floater_god_tools.xml
index 218a5effe8..218a5effe8 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_god_tools.xml
+++ b/indra/newview/skins/default/xui/es/floater_god_tools.xml
diff --git a/indra/newview/skins/default/xui/es/floater_goto_line.xml b/indra/newview/skins/default/xui/es/floater_goto_line.xml
new file mode 100644
index 0000000000..ef3ed80fcb
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/floater_goto_line.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="script goto" title="IR A LA LÃNEA">
+ <button label="OK" label_selected="OK" name="goto_btn"/>
+ <text name="txt">
+ Ir a la línea
+ </text>
+</floater>
diff --git a/indra/newview/skins/default/xui/es/floater_hardware_settings.xml b/indra/newview/skins/default/xui/es/floater_hardware_settings.xml
index b96076836b..c2327c96c4 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_hardware_settings.xml
+++ b/indra/newview/skins/default/xui/es/floater_hardware_settings.xml
@@ -25,6 +25,10 @@
Activar VBO:
</text>
<check_box initial_value="true" label="Activar OpenGL Vertex Buffer Objects" name="vbo" tool_tip="En hardware moderno, habilitar esta opción mejora el rendimiento. Pero en hardware antiguo, el habilitarlo hace que, frecuentemente, se obtenga una implementación pobre de VBO, lo que puede provocarle caídas."/>
+ <text name="tc label">
+ Activar S3TC:
+ </text>
+ <check_box initial_value="true" label="Activar la compresión de texturas (requiere reiniciar)" name="texture compression" tool_tip="Comprime las texturas de la memoria de vídeo, lo cual permite cargar texturas de una resolución más alta, pero con una cierta pérdida de calidad del color."/>
<slider label="Memoria para texturas (MB):" name="GraphicsCardTextureMemory" tool_tip="Cantidad de memoria asignada a las texturas. Por defecto es la memoria de la tarjeta de vídeo. Reducir esta cantidad puede mejorar el rendimiento, pero también hacer que las texturas se vean borrosas."/>
<spinner label="Intensidad de la niebla:" name="fog"/>
<button label="OK" label_selected="OK" name="OK"/>
diff --git a/indra/newview/skins/default/xui/es/floater_help_browser.xml b/indra/newview/skins/default/xui/es/floater_help_browser.xml
index 5ebd7ad6e0..5ebd7ad6e0 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_help_browser.xml
+++ b/indra/newview/skins/default/xui/es/floater_help_browser.xml
diff --git a/indra/newview/skins/default/xui/es/floater_how_to.xml b/indra/newview/skins/default/xui/es/floater_how_to.xml
index 4a57dc3643..4a57dc3643 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_how_to.xml
+++ b/indra/newview/skins/default/xui/es/floater_how_to.xml
diff --git a/indra/newview/skins/default/xui/es/floater_hud.xml b/indra/newview/skins/default/xui/es/floater_hud.xml
index e458913452..e458913452 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_hud.xml
+++ b/indra/newview/skins/default/xui/es/floater_hud.xml
diff --git a/indra/newview/skins/default/xui/es/floater_im_container.xml b/indra/newview/skins/default/xui/es/floater_im_container.xml
index 1cd752e6ec..f772441141 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_im_container.xml
+++ b/indra/newview/skins/default/xui/es/floater_im_container.xml
@@ -1,2 +1,29 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<multi_floater name="floater_im_box" title="CONVERSACIONES"/>
+<multi_floater name="floater_im_box" title="CONVERSACIONES">
+ <string name="collapse_icon" value="Conv_toolbar_collapse"/>
+ <string name="expand_icon" value="Conv_toolbar_expand"/>
+ <layout_stack name="conversations_stack">
+ <layout_panel name="conversations_layout_panel">
+ <layout_stack name="conversations_pane_buttons_stack">
+ <layout_panel name="conversations_pane_buttons_expanded">
+ <menu_button name="sort_btn" tool_tip="Opciones de vista/orden"/>
+ <button name="add_btn" tool_tip="Iniciar una conversación nueva"/>
+ <button name="speak_btn" tool_tip="Utiliza el micrófono para hablar con las personas"/>
+ </layout_panel>
+ <layout_panel name="conversations_pane_buttons_collapsed">
+ <button name="expand_collapse_btn" tool_tip="Cerrar/expandir esta lista"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ <layout_panel name="messages_layout_panel">
+ <panel_container name="im_box_tab_container">
+ <panel name="stub_panel">
+ <button name="stub_collapse_btn" tool_tip="Cerrar este panel"/>
+ <text name="stub_textbox">
+ Esta conversación está en una ventana aparte. [secondlife:/// Traerla de vuelta.]
+ </text>
+ </panel>
+ </panel_container>
+ </layout_panel>
+ </layout_stack>
+</multi_floater>
diff --git a/indra/newview/skins/default/xui/es/floater_im_session.xml b/indra/newview/skins/default/xui/es/floater_im_session.xml
index 3d9d17fc81..e5f48e3fd5 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/es/floater_im_session.xml
@@ -1,8 +1,57 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="panel_im">
- <layout_stack name="im_panels">
- <layout_panel>
- <line_editor label="A" name="chat_editor"/>
- </layout_panel>
- </layout_stack>
+ <floater.string name="call_btn_start">
+ Conv_toolbar_open_call
+ </floater.string>
+ <floater.string name="call_btn_stop">
+ Conv_toolbar_hang_up
+ </floater.string>
+ <floater.string name="collapseline_icon" value="Conv_collapse_to_one_line"/>
+ <floater.string name="expandline_icon" value="Conv_expand_one_line"/>
+ <floater.string name="collapse_icon" value="Conv_toolbar_collapse"/>
+ <floater.string name="expand_icon" value="Conv_toolbar_expand"/>
+ <floater.string name="tear_off_icon" value="Conv_toolbar_arrow_ne"/>
+ <floater.string name="return_icon" value="Conv_toolbar_arrow_sw"/>
+ <floater.string name="participant_added" value="[NAME] ha sido invitado a la conversación."/>
+ <floater.string name="multiple_participants_added" value="[NAME] han sido invitados a la conversación."/>
+ <floater.string name="tooltip_to_separate_window" value="Mover esta conversación a otra ventana"/>
+ <floater.string name="tooltip_to_main_window" value="Volver a poner esta conversación en la ventana principal"/>
+ <floater.string name="start_call_button_tooltip" value="Abrir conexión de voz"/>
+ <floater.string name="end_call_button_tooltip" value="Cerrar la conexión de voz"/>
+ <floater.string name="expcol_button_not_tearoff_tooltip" value="Cerrar este panel"/>
+ <floater.string name="expcol_button_tearoff_and_expanded_tooltip" value="Cerrar la lista de participantes"/>
+ <floater.string name="expcol_button_tearoff_and_collapsed_tooltip" value="Expandir la lista de participantes"/>
+ <view name="contents_view">
+ <layout_stack name="main_stack">
+ <layout_panel name="toolbar_panel">
+ <menu_button name="view_options_btn" tool_tip="Opciones de vista/orden"/>
+ <menu_button name="gear_btn" tool_tip="Acciones en la persona seleccionada"/>
+ <button name="add_btn" tool_tip="Añadir alguien a esta conversación"/>
+ <button name="voice_call_btn" tool_tip="Abrir conexión de voz"/>
+ <button name="close_btn" tool_tip="Finalizar esta conversación"/>
+ <button name="expand_collapse_btn" tool_tip="Cerrar/expandir este panel"/>
+ </layout_panel>
+ <layout_panel name="body_panel">
+ <layout_stack name="im_panels">
+ <layout_panel name="right_part_holder">
+ <layout_stack name="translate_and_chat_stack">
+ <layout_panel name="translate_chat_checkbox_lp">
+ <check_box label="Traducir el chat" name="translate_chat_checkbox"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ <layout_panel name="chat_layout_panel">
+ <layout_stack name="input_panels">
+ <layout_panel name="input_editor_layout_panel">
+ <chat_editor label="A" name="chat_editor"/>
+ </layout_panel>
+ <layout_panel name="input_button_layout_panel">
+ <button name="minz_btn" tool_tip="Muestra/oculta el panel de mensajes"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
+ </view>
</floater>
diff --git a/indra/newview/skins/default/xui/es/floater_image_preview.xml b/indra/newview/skins/default/xui/es/floater_image_preview.xml
index 84c5bfc824..84c5bfc824 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_image_preview.xml
+++ b/indra/newview/skins/default/xui/es/floater_image_preview.xml
diff --git a/indra/newview/skins/default/xui/es/floater_import_collada.xml b/indra/newview/skins/default/xui/es/floater_import_collada.xml
index 7e9a00797a..7e9a00797a 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_import_collada.xml
+++ b/indra/newview/skins/default/xui/es/floater_import_collada.xml
diff --git a/indra/newview/skins/default/xui/es/floater_incoming_call.xml b/indra/newview/skins/default/xui/es/floater_incoming_call.xml
index b5b756abb6..acbb25b713 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_incoming_call.xml
+++ b/indra/newview/skins/default/xui/es/floater_incoming_call.xml
@@ -10,7 +10,7 @@
anónimo
</floater.string>
<floater.string name="VoiceInviteP2P">
- está llamando.
+ te está llamando.
</floater.string>
<floater.string name="VoiceInviteAdHoc">
ha entrado en un chat de voz en multiconferencia.
@@ -25,9 +25,9 @@
¿Quieres dejar [CURRENT_CHAT] y entrar en este chat de voz?
</floater.string>
<text name="question">
- ¿Quieres dejar [CURRENT_CHAT] y entrar a este chat de voz?
+ Si respondes, te desconectarás de la conversación de voz actual.
</text>
- <button label="Aceptar" label_selected="Aceptar" name="Accept"/>
- <button label="Rechazar" label_selected="Rechazar" name="Reject"/>
- <button label="Comenzar un MI" name="Start IM"/>
+ <button label="Responder" label_selected="Responder" name="Accept"/>
+ <button label="Ignorar" label_selected="Ignorar" name="Reject"/>
+ <button label="Abrir MI en su lugar" name="Start IM"/>
</floater>
diff --git a/indra/newview/skins/default/xui/es/floater_inspect.xml b/indra/newview/skins/default/xui/es/floater_inspect.xml
index d95653ddd0..d95653ddd0 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_inspect.xml
+++ b/indra/newview/skins/default/xui/es/floater_inspect.xml
diff --git a/indra/newview/skins/default/xui/es/floater_inventory.xml b/indra/newview/skins/default/xui/es/floater_inventory.xml
deleted file mode 100644
index 0f0ba2fce6..0000000000
--- a/indra/newview/skins/default/xui/es/floater_inventory.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Inventory" title="MI INVENTARIO">
- <floater.string name="Title">
- MI INVENTARIO
- </floater.string>
- <floater.string name="TitleFetching">
- MI INVENTARIO (obteniendo [ITEM_COUNT] ítems...) [FILTER]
- </floater.string>
- <floater.string name="TitleCompleted">
- MI INVENTARIO ([ITEM_COUNT] ítems) [FILTER]
- </floater.string>
- <floater.string name="Fetched">
- Obtenido
- </floater.string>
- <panel label="Panel del inventario" name="Inventory Panel"/>
-</floater>
diff --git a/indra/newview/skins/default/xui/es/floater_inventory_item_properties.xml b/indra/newview/skins/default/xui/es/floater_inventory_item_properties.xml
index bf84c3d808..bf84c3d808 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_inventory_item_properties.xml
+++ b/indra/newview/skins/default/xui/es/floater_inventory_item_properties.xml
diff --git a/indra/newview/skins/default/xui/es/floater_inventory_view_finder.xml b/indra/newview/skins/default/xui/es/floater_inventory_view_finder.xml
index 6004034504..6004034504 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_inventory_view_finder.xml
+++ b/indra/newview/skins/default/xui/es/floater_inventory_view_finder.xml
diff --git a/indra/newview/skins/default/xui/es/floater_joystick.xml b/indra/newview/skins/default/xui/es/floater_joystick.xml
index 2c1804bd90..2c1804bd90 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_joystick.xml
+++ b/indra/newview/skins/default/xui/es/floater_joystick.xml
diff --git a/indra/newview/skins/default/xui/es/floater_lagmeter.xml b/indra/newview/skins/default/xui/es/floater_lagmeter.xml
index 227689a194..227689a194 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_lagmeter.xml
+++ b/indra/newview/skins/default/xui/es/floater_lagmeter.xml
diff --git a/indra/newview/skins/default/xui/es/floater_land_holdings.xml b/indra/newview/skins/default/xui/es/floater_land_holdings.xml
index ed7055b3a1..ed7055b3a1 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_land_holdings.xml
+++ b/indra/newview/skins/default/xui/es/floater_land_holdings.xml
diff --git a/indra/newview/skins/default/xui/es/floater_live_lsleditor.xml b/indra/newview/skins/default/xui/es/floater_live_lsleditor.xml
index 4ff54bccb5..4ff54bccb5 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_live_lsleditor.xml
+++ b/indra/newview/skins/default/xui/es/floater_live_lsleditor.xml
diff --git a/indra/newview/skins/default/xui/es/floater_lsl_guide.xml b/indra/newview/skins/default/xui/es/floater_lsl_guide.xml
index 43a7ede030..43a7ede030 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_lsl_guide.xml
+++ b/indra/newview/skins/default/xui/es/floater_lsl_guide.xml
diff --git a/indra/newview/skins/default/xui/es/floater_map.xml b/indra/newview/skins/default/xui/es/floater_map.xml
index 69f638418e..69f638418e 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_map.xml
+++ b/indra/newview/skins/default/xui/es/floater_map.xml
diff --git a/indra/newview/skins/default/xui/es/floater_media_browser.xml b/indra/newview/skins/default/xui/es/floater_media_browser.xml
index 9c4ef1eb2f..9c4ef1eb2f 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_media_browser.xml
+++ b/indra/newview/skins/default/xui/es/floater_media_browser.xml
diff --git a/indra/newview/skins/default/xui/es/floater_media_settings.xml b/indra/newview/skins/default/xui/es/floater_media_settings.xml
index 3f7cef5785..3f7cef5785 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_media_settings.xml
+++ b/indra/newview/skins/default/xui/es/floater_media_settings.xml
diff --git a/indra/newview/skins/default/xui/es/floater_mem_leaking.xml b/indra/newview/skins/default/xui/es/floater_mem_leaking.xml
index da8ba780bc..da8ba780bc 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_mem_leaking.xml
+++ b/indra/newview/skins/default/xui/es/floater_mem_leaking.xml
diff --git a/indra/newview/skins/default/xui/es/floater_merchant_outbox.xml b/indra/newview/skins/default/xui/es/floater_merchant_outbox.xml
index a7c17fc136..a7c17fc136 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_merchant_outbox.xml
+++ b/indra/newview/skins/default/xui/es/floater_merchant_outbox.xml
diff --git a/indra/newview/skins/default/xui/es/floater_model_preview.xml b/indra/newview/skins/default/xui/es/floater_model_preview.xml
index ab3ba5aed7..e2313bce99 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_model_preview.xml
+++ b/indra/newview/skins/default/xui/es/floater_model_preview.xml
@@ -92,19 +92,54 @@
<text initial_value="Triángulos" name="triangles" value="Triángulos"/>
<text initial_value="Vértices" name="vertices" value="Vértices"/>
<text initial_value="Alto" name="high_label" value="Alto"/>
+ <combo_box name="lod_source_high">
+ <item name="Load from file" value="Cargar desde archivo"/>
+ <item name="Generate" value="Generar"/>
+ </combo_box>
<button label="Buscar..." name="lod_browse_high"/>
+ <combo_box name="lod_mode_high">
+ <item name="Triangle Limit" value="Límite de triángulo"/>
+ <item name="Error Threshold" value="Margen de error"/>
+ </combo_box>
<text initial_value="0" name="high_triangles" value="0"/>
<text initial_value="0" name="high_vertices" value="0"/>
<text initial_value="Medio" name="medium_label" value="Medio"/>
+ <combo_box name="lod_source_medium">
+ <item name="Load from file" value="Cargar desde archivo"/>
+ <item name="Generate" value="Generar"/>
+ <item name="Use LoD above" value="Usar nivel de detalle superior"/>
+ </combo_box>
<button label="Buscar..." name="lod_browse_medium"/>
+ <combo_box name="lod_mode_medium">
+ <item name="Triangle Limit" value="Límite de triángulo"/>
+ <item name="Error Threshold" value="Margen de error"/>
+ </combo_box>
<text initial_value="0" name="medium_triangles" value="0"/>
<text initial_value="0" name="medium_vertices" value="0"/>
<text initial_value="Bajo" name="low_label" value="Bajo"/>
+ <combo_box name="lod_source_low">
+ <item name="Load from file" value="Cargar desde archivo"/>
+ <item name="Generate" value="Generar"/>
+ <item name="Use LoD above" value="Usar nivel de detalle superior"/>
+ </combo_box>
<button label="Buscar..." name="lod_browse_low"/>
+ <combo_box name="lod_mode_low">
+ <item name="Triangle Limit" value="Límite de triángulo"/>
+ <item name="Error Threshold" value="Margen de error"/>
+ </combo_box>
<text initial_value="0" name="low_triangles" value="0"/>
<text initial_value="0" name="low_vertices" value="0"/>
<text initial_value="Mínimo" name="lowest_label" value="Mínimo"/>
+ <combo_box name="lod_source_lowest">
+ <item name="Load from file" value="Cargar desde archivo"/>
+ <item name="Generate" value="Generar"/>
+ <item name="Use LoD above" value="Usar nivel de detalle superior"/>
+ </combo_box>
<button label="Buscar..." name="lod_browse_lowest"/>
+ <combo_box name="lod_mode_lowest">
+ <item name="Triangle Limit" value="Límite de triángulo"/>
+ <item name="Error Threshold" value="Margen de error"/>
+ </combo_box>
<text initial_value="0" name="lowest_triangles" value="0"/>
<text initial_value="0" name="lowest_vertices" value="0"/>
<check_box label="Generar normales" name="gen_normals"/>
diff --git a/indra/newview/skins/default/xui/es/floater_model_wizard.xml b/indra/newview/skins/default/xui/es/floater_model_wizard.xml
deleted file mode 100644
index 5bd6b5e0e5..0000000000
--- a/indra/newview/skins/default/xui/es/floater_model_wizard.xml
+++ /dev/null
@@ -1,208 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Model Wizard" title="CARGAR ASISTENTE DE MODELO">
- <button label="5. Subir" name="upload_btn"/>
- <button label="4. Revisar" name="review_btn"/>
- <button label="3. Física" name="physics_btn"/>
- <button label="2. Optimizar" name="optimize_btn"/>
- <button label="1. Seleccionar archivo" name="choose_file_btn"/>
- <panel name="choose_file_panel">
- <panel name="choose_file_header_panel">
- <text name="choose_file_header_text">
- Elige el archivo de modelo
- </text>
- </panel>
- <panel name="choose_file_content">
- <text name="advanced_users_text">
- Usuarios avanzados: si tienes experiencia con las herramientas de creación de contenidos 3D, quizá te interese utilizar la función de subida avanzada.
- </text>
- <button label="Cambiar al modo Avanzado" name="switch_to_advanced"/>
- <text name="Cache location">
- Elige el archivo de modelo que deseas subir
- </text>
- <button label="Examinar..." label_selected="Examinar..." name="browse"/>
- <text name="Model types">
- ‎Second Life admite los archivos COLLADA (.dae)
- </text>
- <text name="dimensions">
- X Y Z
- </text>
- <text name="warning_label">
- ATENCIÓN:
- </text>
- <text name="warning_text">
- No podrás completar el paso final de la subida de este modelo a los servidores de Second Life. [secondlife:///app/floater/learn_more Averigua cómo] configurar tu cuenta para subir modelos de malla.
- </text>
- </panel>
- </panel>
- <panel name="optimize_panel">
- <panel name="optimize_header_panel">
- <text name="optimize_header_text">
- Optimizar el modelo
- </text>
- </panel>
- <text name="optimize_description">
- Hemos optimizado el rendimiento del modelo, pero puedes ajustarlo más si lo deseas.
- </text>
- <panel name="optimize_content">
- <text name="high_detail_text">
- Generar el nivel de detalle: Alto
- </text>
- <text name="medium_detail_text">
- Generar el nivel de detalle: Medio
- </text>
- <text name="low_detail_text">
- Generar el nivel de detalle: Bajo
- </text>
- <text name="lowest_detail_text">
- Generar el nivel de detalle: Mínimo
- </text>
- </panel>
- <panel name="content2">
- <button label="Recalcular la geometría" name="recalculate_geometry_btn"/>
- <text name="lod_label">
- Vista previa de geometría
- </text>
- <combo_box name="preview_lod_combo" tool_tip="LOD para ver en renderizado de prueba">
- <combo_item name="high">
- Detalle alto
- </combo_item>
- <combo_item name="medium">
- Detalles medios
- </combo_item>
- <combo_item name="low">
- Detalle bajo
- </combo_item>
- <combo_item name="lowest">
- Detalles mínimos
- </combo_item>
- </combo_box>
- </panel>
- </panel>
- <panel name="physics_panel">
- <panel name="physics_header_panel">
- <text name="physics_header_text">
- Ajustar la física
- </text>
- </panel>
- <text name="physics_description">
- Crearemos una forma para la apariencia exterior del modelo. Ajusta el nivel de detalle de la forma según se necesite para el propósito proyectado del modelo.
- </text>
- <panel name="physics_content">
- <button label="Recalcular física" name="recalculate_physics_btn"/>
- <button label="Recalculando..." name="recalculating_physics_btn"/>
- <text name="lod_label">
- Prueba de física
- </text>
- <combo_box name="preview_lod_combo2" tool_tip="LOD para ver en renderizado de prueba">
- <combo_item name="high">
- Detalle alto
- </combo_item>
- <combo_item name="medium">
- Detalles medios
- </combo_item>
- <combo_item name="low">
- Detalle bajo
- </combo_item>
- <combo_item name="lowest">
- Detalles mínimos
- </combo_item>
- </combo_box>
- </panel>
- </panel>
- <panel name="review_panel">
- <panel name="review_header_panel">
- <text name="review_header_text">
- Revisar
- </text>
- </panel>
- <panel name="review_content">
- <text name="review_prim_equiv">
- Impacto en la parcela/región: [EQUIV] equivalentes en prim
- </text>
- <text name="review_fee">
- Cargaremos en tu cuenta el precio de subida de L$ [FEE].
- </text>
- <text name="review_confirmation">
- Al pulsar en el botón de subida, confirmas que posees los derechos necesarios sobre el material que contiene el modelo.
- </text>
- </panel>
- </panel>
- <panel name="upload_panel">
- <panel name="upload_header_panel">
- <text name="upload_header_text">
- Subida finalizada
- </text>
- </panel>
- <text name="model_uploaded_text">
- Se ha subido tu modelo.
- </text>
- <text name="inventory_text">
- Puedes buscar la carpeta Objetos en tu inventario.
- </text>
- <text name="charged_fee">
- Se han cargado [FEE] L$ en tu cuenta.
- </text>
- </panel>
- <button label="&lt;&lt; Atrás" name="back"/>
- <button label="Siguiente &gt;&gt;" name="next"/>
- <button label="Calcular pesos y precio &gt;&gt;" name="calculate"/>
- <button label="Calculando..." name="calculating"/>
- <button label="Subir" name="upload" tool_tip="Cargar al simulador"/>
- <button label="Cancelar" name="cancel"/>
- <button label="Cerrar" name="close"/>
- <spinner name="import_scale" value="1.0"/>
- <string name="status_idle">
- Inactivo
- </string>
- <string name="status_parse_error">
- Problema de análisis de DAE - consulta los datos en el registro.
- </string>
- <string name="status_reading_file">
- Cargando...
- </string>
- <string name="status_generating_meshes">
- Generando redes...
- </string>
- <string name="status_vertex_number_overflow">
- Error: El número de intersección es superior a 65534. Cancelado.
- </string>
- <string name="bad_element">
- Error: el elemento no es válido
- </string>
- <string name="high">
- Alto
- </string>
- <string name="medium">
- Media
- </string>
- <string name="low">
- Bajo
- </string>
- <string name="lowest">
- Mínimo
- </string>
- <string name="mesh_status_good">
- Factúralo.
- </string>
- <string name="mesh_status_na">
- N/A
- </string>
- <string name="mesh_status_none">
- Ninguno
- </string>
- <string name="mesh_status_submesh_mismatch">
- Los niveles de detalle poseen un número distinto de caras a las que se pueden aplicar texturas.
- </string>
- <string name="mesh_status_mesh_mismatch">
- Los niveles de detalle poseen un número distinto de ejemplos de red.
- </string>
- <string name="mesh_status_too_many_vertices">
- El nivel de detalle posee demasiadas intersecciones.
- </string>
- <string name="mesh_status_missing_lod">
- Falta un nivel de detalle requerido.
- </string>
- <string name="layer_all">
- Todo
- </string>
-</floater>
diff --git a/indra/newview/skins/default/xui/es/floater_moveview.xml b/indra/newview/skins/default/xui/es/floater_moveview.xml
index 0e7b950bd3..0e7b950bd3 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_moveview.xml
+++ b/indra/newview/skins/default/xui/es/floater_moveview.xml
diff --git a/indra/newview/skins/default/xui/es/floater_mute_object.xml b/indra/newview/skins/default/xui/es/floater_mute_object.xml
index 4cd16a59ed..4cd16a59ed 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_mute_object.xml
+++ b/indra/newview/skins/default/xui/es/floater_mute_object.xml
diff --git a/indra/newview/skins/default/xui/es/floater_my_appearance.xml b/indra/newview/skins/default/xui/es/floater_my_appearance.xml
index 774babf04e..774babf04e 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_my_appearance.xml
+++ b/indra/newview/skins/default/xui/es/floater_my_appearance.xml
diff --git a/indra/newview/skins/default/xui/es/floater_my_inventory.xml b/indra/newview/skins/default/xui/es/floater_my_inventory.xml
index 0efd9f1c6d..0efd9f1c6d 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_my_inventory.xml
+++ b/indra/newview/skins/default/xui/es/floater_my_inventory.xml
diff --git a/indra/newview/skins/default/xui/es/floater_nearby_chat.xml b/indra/newview/skins/default/xui/es/floater_nearby_chat.xml
deleted file mode 100644
index b3b8cdcfff..0000000000
--- a/indra/newview/skins/default/xui/es/floater_nearby_chat.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="nearby_chat" title="CHAT">
- <check_box label="Traducir chat" name="translate_chat_checkbox"/>
-</floater>
diff --git a/indra/newview/skins/default/xui/es/floater_object_weights.xml b/indra/newview/skins/default/xui/es/floater_object_weights.xml
index 50c4f0518d..50c4f0518d 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_object_weights.xml
+++ b/indra/newview/skins/default/xui/es/floater_object_weights.xml
diff --git a/indra/newview/skins/default/xui/es/floater_openobject.xml b/indra/newview/skins/default/xui/es/floater_openobject.xml
index b8b688df60..b8b688df60 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_openobject.xml
+++ b/indra/newview/skins/default/xui/es/floater_openobject.xml
diff --git a/indra/newview/skins/default/xui/es/floater_outfit_save_as.xml b/indra/newview/skins/default/xui/es/floater_outfit_save_as.xml
index f48d0d2d0c..f48d0d2d0c 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_outfit_save_as.xml
+++ b/indra/newview/skins/default/xui/es/floater_outfit_save_as.xml
diff --git a/indra/newview/skins/default/xui/es/floater_outgoing_call.xml b/indra/newview/skins/default/xui/es/floater_outgoing_call.xml
index 5fd9dba9ac..5fd9dba9ac 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_outgoing_call.xml
+++ b/indra/newview/skins/default/xui/es/floater_outgoing_call.xml
diff --git a/indra/newview/skins/default/xui/es/floater_pathfinding_characters.xml b/indra/newview/skins/default/xui/es/floater_pathfinding_characters.xml
new file mode 100755
index 0000000000..e3ee0563d2
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/floater_pathfinding_characters.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="floater_pathfinding_characters" title="Personajes de pathfinding">
+ <floater.string name="messaging_get_inprogress">
+ Consultando los personajes de pathfinding...
+ </floater.string>
+ <floater.string name="messaging_get_error">
+ Se ha detectado un error al consultar los personajes de pathfinding.
+ </floater.string>
+ <floater.string name="messaging_complete_none_found">
+ No hay personajes de pathfinding.
+ </floater.string>
+ <floater.string name="messaging_complete_available">
+ [NUM_SELECTED] personajes seleccionados de [NUM_TOTAL].
+ </floater.string>
+ <floater.string name="messaging_not_enabled">
+ En esta región no está permitido el pathfinding.
+ </floater.string>
+ <floater.string name="character_cpu_time">
+ [CPU_TIME] µs
+ </floater.string>
+ <floater.string name="character_owner_loading">
+ [Cargando]
+ </floater.string>
+ <floater.string name="character_owner_unknown">
+ [Desconocido]
+ </floater.string>
+ <floater.string name="character_owner_group">
+ [grupo]
+ </floater.string>
+ <panel>
+ <scroll_list name="objects_scroll_list">
+ <scroll_list.columns label="Nombre" name="name"/>
+ <scroll_list.columns label="Descripción" name="description"/>
+ <scroll_list.columns label="Propietario" name="owner"/>
+ <scroll_list.columns label="CPU" name="cpu_time"/>
+ <scroll_list.columns label="Altitud" name="altitude"/>
+ </scroll_list>
+ <text name="messaging_status">
+ Personajes:
+ </text>
+ <button label="Actualizar la lista" name="refresh_objects_list"/>
+ <button label="Seleccionar todo" name="select_all_objects"/>
+ <button label="No seleccionar ninguno" name="select_none_objects"/>
+ </panel>
+ <panel>
+ <text name="actions_label">
+ Acciones en los personajes seleccionados:
+ </text>
+ <check_box label="Mostrar baliza" name="show_beacon"/>
+ <check_box label="Mostrar la cápsula de física" name="show_physics_capsule"/>
+ <button label="Tomar" name="take_objects"/>
+ <button label="Tomar una copia" name="take_copy_objects"/>
+ <button label="Teleportarme a él" name="teleport_me_to_object" tool_tip="Se habilita solo cuando está seleccionado un personaje."/>
+ <button label="Devolver" name="return_objects"/>
+ <button label="Eliminar" name="delete_objects"/>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/es/floater_pathfinding_console.xml b/indra/newview/skins/default/xui/es/floater_pathfinding_console.xml
new file mode 100755
index 0000000000..e93ecc9e10
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/floater_pathfinding_console.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="floater_pathfinding_console" title="Vista/prueba de pathfinding">
+ <floater.string name="navmesh_viewer_status_library_not_implemented">
+ No se encuentra la implementación de la biblioteca de localización de rutas.
+ </floater.string>
+ <floater.string name="navmesh_viewer_status_region_not_enabled">
+ En esta región no está permitido el pathfinding.
+ </floater.string>
+ <floater.string name="navmesh_viewer_status_region_loading">
+ Esperando a que termine la carga de la región.
+ </floater.string>
+ <floater.string name="navmesh_viewer_status_checking_version">
+ Comprobando el estado del navmesh.
+ </floater.string>
+ <floater.string name="navmesh_viewer_status_downloading">
+ Descargando el navmesh.
+ </floater.string>
+ <floater.string name="navmesh_viewer_status_updating">
+ El navmesh se ha modificado en el servidor. Descargando el último navmesh.
+ </floater.string>
+ <floater.string name="navmesh_viewer_status_has_navmesh">
+ Se ha descargado el último navmesh.
+ </floater.string>
+ <floater.string name="navmesh_viewer_status_error">
+ No se puede descargar el navmesh correctamente.
+ </floater.string>
+ <floater.string name="navmesh_simulator_status_pending">
+ El navmesh tiene cambios pendientes.
+ </floater.string>
+ <floater.string name="navmesh_simulator_status_building">
+ El navmesh se está construyendo.
+ </floater.string>
+ <floater.string name="navmesh_simulator_status_some_pending">
+ Algunas regiones del navmesh tienen cambios pendientes.
+ </floater.string>
+ <floater.string name="navmesh_simulator_status_some_building">
+ Algunas regiones del navmesh se están construyendo.
+ </floater.string>
+ <floater.string name="navmesh_simulator_status_pending_and_building">
+ Algunas regiones del navmesh tienen cambios pendientes y otras se están construyendo.
+ </floater.string>
+ <floater.string name="navmesh_simulator_status_complete">
+ El navmesh está actualizado.
+ </floater.string>
+ <floater.string name="pathing_library_not_implemented">
+ No se encuentra la implementación de la biblioteca de localización de rutas.
+ </floater.string>
+ <floater.string name="pathing_region_not_enabled">
+ En esta región no está permitido el pathfinding.
+ </floater.string>
+ <floater.string name="pathing_choose_start_and_end_points">
+ Elige los puntos inicial y final.
+ </floater.string>
+ <floater.string name="pathing_choose_start_point">
+ Elige el punto inicial.
+ </floater.string>
+ <floater.string name="pathing_choose_end_point">
+ Elige el punto final.
+ </floater.string>
+ <floater.string name="pathing_path_valid">
+ La ruta se muestra de color naranja.
+ </floater.string>
+ <floater.string name="pathing_path_invalid">
+ No se encuentra una ruta entre los puntos seleccionados.
+ </floater.string>
+ <floater.string name="pathing_error">
+ Error durante la generación de la ruta.
+ </floater.string>
+ <tab_container name="view_test_tab_container">
+ <panel label="Vista" name="view_panel">
+ <text name="show_label">
+ Mostrar:
+ </text>
+ <check_box label="Mundo virtual" name="show_world"/>
+ <check_box label="Solamente los objetos movibles" name="show_world_movables_only"/>
+ <check_box label="Navmesh" name="show_navmesh"/>
+ <text name="show_walkability_label">
+ Mostrar el mapa de transitabilidad:
+ </text>
+ <combo_box name="show_heatmap_mode">
+ <combo_box.item label="No mostrar" name="show_heatmap_mode_none"/>
+ <combo_box.item label="Personaje de tipo A" name="show_heatmap_mode_a"/>
+ <combo_box.item label="Personaje de tipo B" name="show_heatmap_mode_b"/>
+ <combo_box.item label="Personaje de tipo C" name="show_heatmap_mode_c"/>
+ <combo_box.item label="Personaje de tipo D" name="show_heatmap_mode_d"/>
+ </combo_box>
+ <check_box label="Objetos transitables" name="show_walkables"/>
+ <check_box label="Volúmenes materiales" name="show_material_volumes"/>
+ <check_box label="Obstáculos estáticos" name="show_static_obstacles"/>
+ <check_box label="Volúmenes de exclusión" name="show_exclusion_volumes"/>
+ <check_box label="Plano de agua" name="show_water_plane"/>
+ <check_box label="Con visión de rayos X" name="show_xray"/>
+ </panel>
+ <panel label="Probar ruta" name="test_panel">
+ <text name="ctrl_click_label">
+ Ctrl-clic para seleccionar el punto inicial.
+ </text>
+ <text name="shift_click_label">
+ Mayús-clic para seleccionar el punto final.
+ </text>
+ <text name="character_width_label">
+ Ancho del personaje
+ </text>
+ <slider name="character_width" value="1"/>
+ <text name="character_width_unit_label">
+ m
+ </text>
+ <text name="character_type_label">
+ Tipo de personaje
+ </text>
+ <combo_box name="path_character_type">
+ <combo_box.item label="Ninguno" name="path_character_type_none"/>
+ <combo_box.item label="A" name="path_character_type_a"/>
+ <combo_box.item label="B" name="path_character_type_b"/>
+ <combo_box.item label="C" name="path_character_type_c"/>
+ <combo_box.item label="D" name="path_character_type_d"/>
+ </combo_box>
+ <button label="Borrar ruta" name="clear_path"/>
+ </panel>
+ </tab_container>
+</floater>
diff --git a/indra/newview/skins/default/xui/es/floater_pathfinding_linksets.xml b/indra/newview/skins/default/xui/es/floater_pathfinding_linksets.xml
new file mode 100755
index 0000000000..e6f864eef5
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/floater_pathfinding_linksets.xml
@@ -0,0 +1,167 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="floater_pathfinding_linksets" title="Linksets de pathfinding">
+ <floater.string name="messaging_get_inprogress">
+ Consultando los linksets de pathfinding...
+ </floater.string>
+ <floater.string name="messaging_get_error">
+ Se ha detectado un error al consultar los linksets de pathfinding.
+ </floater.string>
+ <floater.string name="messaging_set_inprogress">
+ Modificando los linksets de pathfinding seleccionados...
+ </floater.string>
+ <floater.string name="messaging_set_error">
+ Se ha detectado un error al modificar los linksets de pathfinding seleccionados.
+ </floater.string>
+ <floater.string name="messaging_complete_none_found">
+ No hay linksets de pathfinding.
+ </floater.string>
+ <floater.string name="messaging_complete_available">
+ [NUM_SELECTED] linksets seleccionados de [NUM_TOTAL].
+ </floater.string>
+ <floater.string name="messaging_not_enabled">
+ En esta región no está permitido el pathfinding.
+ </floater.string>
+ <floater.string name="linkset_terrain_name">
+ [Terreno]
+ </floater.string>
+ <floater.string name="linkset_terrain_description">
+ --
+ </floater.string>
+ <floater.string name="linkset_terrain_owner">
+ --
+ </floater.string>
+ <floater.string name="linkset_terrain_scripted">
+ --
+ </floater.string>
+ <floater.string name="linkset_terrain_land_impact">
+ --
+ </floater.string>
+ <floater.string name="linkset_terrain_dist_from_you">
+ --
+ </floater.string>
+ <floater.string name="linkset_owner_loading">
+ [Cargando]
+ </floater.string>
+ <floater.string name="linkset_owner_unknown">
+ [Desconocido]
+ </floater.string>
+ <floater.string name="linkset_owner_group">
+ [grupo]
+ </floater.string>
+ <floater.string name="linkset_is_scripted">
+ Sí
+ </floater.string>
+ <floater.string name="linkset_is_not_scripted">
+ No
+ </floater.string>
+ <floater.string name="linkset_is_unknown_scripted">
+ Desconocido
+ </floater.string>
+ <floater.string name="linkset_use_walkable">
+ Objeto transitable
+ </floater.string>
+ <floater.string name="linkset_use_static_obstacle">
+ Obstáculo estático
+ </floater.string>
+ <floater.string name="linkset_use_dynamic_obstacle">
+ Obstáculo móvil
+ </floater.string>
+ <floater.string name="linkset_use_material_volume">
+ Volumen material
+ </floater.string>
+ <floater.string name="linkset_use_exclusion_volume">
+ Volumen de exclusión
+ </floater.string>
+ <floater.string name="linkset_use_dynamic_phantom">
+ Inmaterial móvil
+ </floater.string>
+ <floater.string name="linkset_is_terrain">
+ [no modificable]
+ </floater.string>
+ <floater.string name="linkset_is_restricted_state">
+ [restringido]
+ </floater.string>
+ <floater.string name="linkset_is_non_volume_state">
+ [cóncavo]
+ </floater.string>
+ <floater.string name="linkset_is_restricted_non_volume_state">
+ [restringido,cóncavo]
+ </floater.string>
+ <floater.string name="linkset_choose_use">
+ Elegir la utilización del linkset...
+ </floater.string>
+ <panel>
+ <combo_box name="filter_by_linkset_use">
+ <combo_box.item label="Filtrar por utilización de linkset..." name="filter_by_linkset_use_none"/>
+ <combo_box.item label="Objeto transitable" name="filter_by_linkset_use_walkable"/>
+ <combo_box.item label="Obstáculo estático" name="filter_by_linkset_use_static_obstacle"/>
+ <combo_box.item label="Obstáculo móvil" name="filter_by_linkset_use_dynamic_obstacle"/>
+ <combo_box.item label="Volumen material" name="filter_by_linkset_use_material_volume"/>
+ <combo_box.item label="Volumen de exclusión" name="filter_by_linkset_use_exclusion_volume"/>
+ <combo_box.item label="Inmaterial móvil" name="filter_by_linkset_use_dynamic_phantom"/>
+ </combo_box>
+ <button label="Aplicar" name="apply_filters"/>
+ <button label="Limpiar" name="clear_filters"/>
+ <scroll_list name="objects_scroll_list">
+ <scroll_list.columns label="Nombre (prim raíz)" name="name"/>
+ <scroll_list.columns label="Descripción (prim raíz)" name="description"/>
+ <scroll_list.columns label="Propietario" name="owner"/>
+ <scroll_list.columns label="Con scripts" name="scripted"/>
+ <scroll_list.columns label="Impacto" name="land_impact"/>
+ <scroll_list.columns label="Distancia" name="dist_from_you"/>
+ <scroll_list.columns label="Utilización de linkset" name="linkset_use"/>
+ <scroll_list.columns label="A %" name="a_percent"/>
+ <scroll_list.columns label="B %" name="b_percent"/>
+ <scroll_list.columns label="C %" name="c_percent"/>
+ <scroll_list.columns label="D %" name="d_percent"/>
+ </scroll_list>
+ <text name="messaging_status">
+ Linksets:
+ </text>
+ <button label="Actualizar la lista" name="refresh_objects_list"/>
+ <button label="Seleccionar todo" name="select_all_objects"/>
+ <button label="No seleccionar ninguno" name="select_none_objects"/>
+ </panel>
+ <panel>
+ <check_box label="Mostrar baliza" name="show_beacon"/>
+ <button label="Tomar" name="take_objects"/>
+ <button label="Tomar una copia" name="take_copy_objects"/>
+ <button label="Teleportarme a él" name="teleport_me_to_object"/>
+ <button label="Devolver" name="return_objects"/>
+ <button label="Eliminar" name="delete_objects"/>
+ </panel>
+ <panel>
+ <text name="walkability_coefficients_label">
+ Transitabilidad:
+ </text>
+ <text name="edit_a_label">
+ A
+ </text>
+ <line_editor name="edit_a_value" tool_tip="Transitabilidad de los personajes de tipo A. El tipo del personaje del ejemplo es humanoide."/>
+ <text name="edit_b_label">
+ B
+ </text>
+ <line_editor name="edit_b_value" tool_tip="Transitabilidad de los personajes de tipo B. El tipo del personaje del ejemplo es criatura."/>
+ <text name="edit_c_label">
+ C
+ </text>
+ <line_editor name="edit_c_value" tool_tip="Transitabilidad de los personajes de tipo C. El tipo del personaje del ejemplo es mecánico."/>
+ <text name="edit_d_label">
+ D
+ </text>
+ <line_editor name="edit_d_value" tool_tip="Transitabilidad de los personajes de tipo D. El tipo del personaje del ejemplo es otro."/>
+ <button label="Aplicar cambios" name="apply_edit_values"/>
+ <text name="suggested_use_a_label">
+ (Humanoide)
+ </text>
+ <text name="suggested_use_b_label">
+ (Criatura)
+ </text>
+ <text name="suggested_use_c_label">
+ (Mecánico)
+ </text>
+ <text name="suggested_use_d_label">
+ (Otro)
+ </text>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/es/floater_pay.xml b/indra/newview/skins/default/xui/es/floater_pay.xml
index ad9a43ad71..ad9a43ad71 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_pay.xml
+++ b/indra/newview/skins/default/xui/es/floater_pay.xml
diff --git a/indra/newview/skins/default/xui/es/floater_pay_object.xml b/indra/newview/skins/default/xui/es/floater_pay_object.xml
index 4767f4dfa0..4767f4dfa0 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_pay_object.xml
+++ b/indra/newview/skins/default/xui/es/floater_pay_object.xml
diff --git a/indra/newview/skins/default/xui/es/floater_people.xml b/indra/newview/skins/default/xui/es/floater_people.xml
index f5a3eab008..f5a3eab008 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_people.xml
+++ b/indra/newview/skins/default/xui/es/floater_people.xml
diff --git a/indra/newview/skins/default/xui/es/floater_perm_prefs.xml b/indra/newview/skins/default/xui/es/floater_perm_prefs.xml
index 93e2088aba..93e2088aba 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_perm_prefs.xml
+++ b/indra/newview/skins/default/xui/es/floater_perm_prefs.xml
diff --git a/indra/newview/skins/default/xui/es/floater_picks.xml b/indra/newview/skins/default/xui/es/floater_picks.xml
index 255aa5dcdc..255aa5dcdc 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_picks.xml
+++ b/indra/newview/skins/default/xui/es/floater_picks.xml
diff --git a/indra/newview/skins/default/xui/es/floater_places.xml b/indra/newview/skins/default/xui/es/floater_places.xml
index 12c6548205..12c6548205 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_places.xml
+++ b/indra/newview/skins/default/xui/es/floater_places.xml
diff --git a/indra/newview/skins/default/xui/es/floater_post_process.xml b/indra/newview/skins/default/xui/es/floater_post_process.xml
index 5c62ccde36..5c62ccde36 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_post_process.xml
+++ b/indra/newview/skins/default/xui/es/floater_post_process.xml
diff --git a/indra/newview/skins/default/xui/es/floater_postcard.xml b/indra/newview/skins/default/xui/es/floater_postcard.xml
deleted file mode 100644
index b5b9805fe2..0000000000
--- a/indra/newview/skins/default/xui/es/floater_postcard.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Postcard" title="FOTO POR CORREO">
- <text name="to_label">
- Correo del destinatario:
- </text>
- <text name="from_label">
- Su correo:
- </text>
- <text name="name_label">
- Su nombre:
- </text>
- <text name="subject_label">
- Asunto:
- </text>
- <line_editor label="Escriba aquí el asunto." name="subject_form"/>
- <text name="msg_label">
- Mensaje:
- </text>
- <text_editor name="msg_form">
- Escriba aquí el mensaje.
- </text_editor>
- <text name="fine_print">
- Si su destinatario se registra en [SECOND_LIFE],
-usted conseguirá un bono de referido.
- </text>
- <button label="Cancelar" name="cancel_btn"/>
- <button label="Enviar" name="send_btn"/>
- <string name="default_subject">
- Postal desde [SECOND_LIFE].
- </string>
- <string name="default_message">
- ¡Mira esto!
- </string>
- <string name="upload_message">
- Enviando...
- </string>
-</floater>
diff --git a/indra/newview/skins/default/xui/es/floater_preferences.xml b/indra/newview/skins/default/xui/es/floater_preferences.xml
index 372680f55d..372680f55d 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_preferences.xml
+++ b/indra/newview/skins/default/xui/es/floater_preferences.xml
diff --git a/indra/newview/skins/default/xui/es/floater_preferences_proxy.xml b/indra/newview/skins/default/xui/es/floater_preferences_proxy.xml
index f656f5d662..f656f5d662 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_preferences_proxy.xml
+++ b/indra/newview/skins/default/xui/es/floater_preferences_proxy.xml
diff --git a/indra/newview/skins/default/xui/es/floater_preview_animation.xml b/indra/newview/skins/default/xui/es/floater_preview_animation.xml
index c3f377a71a..c3f377a71a 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_preview_animation.xml
+++ b/indra/newview/skins/default/xui/es/floater_preview_animation.xml
diff --git a/indra/newview/skins/default/xui/es/floater_preview_gesture.xml b/indra/newview/skins/default/xui/es/floater_preview_gesture.xml
index bd13262dcd..bd13262dcd 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_preview_gesture.xml
+++ b/indra/newview/skins/default/xui/es/floater_preview_gesture.xml
diff --git a/indra/newview/skins/default/xui/es/floater_preview_notecard.xml b/indra/newview/skins/default/xui/es/floater_preview_notecard.xml
index d05a023279..d05a023279 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_preview_notecard.xml
+++ b/indra/newview/skins/default/xui/es/floater_preview_notecard.xml
diff --git a/indra/newview/skins/default/xui/es/floater_preview_sound.xml b/indra/newview/skins/default/xui/es/floater_preview_sound.xml
index 62525c9536..62525c9536 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_preview_sound.xml
+++ b/indra/newview/skins/default/xui/es/floater_preview_sound.xml
diff --git a/indra/newview/skins/default/xui/es/floater_preview_texture.xml b/indra/newview/skins/default/xui/es/floater_preview_texture.xml
index 4012191c78..4012191c78 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_preview_texture.xml
+++ b/indra/newview/skins/default/xui/es/floater_preview_texture.xml
diff --git a/indra/newview/skins/default/xui/es/floater_price_for_listing.xml b/indra/newview/skins/default/xui/es/floater_price_for_listing.xml
index 8d6cdc86c0..8d6cdc86c0 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_price_for_listing.xml
+++ b/indra/newview/skins/default/xui/es/floater_price_for_listing.xml
diff --git a/indra/newview/skins/default/xui/es/floater_publish_classified.xml b/indra/newview/skins/default/xui/es/floater_publish_classified.xml
index a1645f0c64..a1645f0c64 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_publish_classified.xml
+++ b/indra/newview/skins/default/xui/es/floater_publish_classified.xml
diff --git a/indra/newview/skins/default/xui/es/floater_region_debug_console.xml b/indra/newview/skins/default/xui/es/floater_region_debug_console.xml
index 40851f897e..40851f897e 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_region_debug_console.xml
+++ b/indra/newview/skins/default/xui/es/floater_region_debug_console.xml
diff --git a/indra/newview/skins/default/xui/es/floater_region_info.xml b/indra/newview/skins/default/xui/es/floater_region_info.xml
index 46d0839238..46d0839238 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_region_info.xml
+++ b/indra/newview/skins/default/xui/es/floater_region_info.xml
diff --git a/indra/newview/skins/default/xui/es/floater_report_abuse.xml b/indra/newview/skins/default/xui/es/floater_report_abuse.xml
index dc5d430375..dc5d430375 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_report_abuse.xml
+++ b/indra/newview/skins/default/xui/es/floater_report_abuse.xml
diff --git a/indra/newview/skins/default/xui/es/floater_script_debug.xml b/indra/newview/skins/default/xui/es/floater_script_debug.xml
index e7eddfd9f3..e7eddfd9f3 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_script_debug.xml
+++ b/indra/newview/skins/default/xui/es/floater_script_debug.xml
diff --git a/indra/newview/skins/default/xui/es/floater_script_debug_panel.xml b/indra/newview/skins/default/xui/es/floater_script_debug_panel.xml
index db9fd5f36e..db9fd5f36e 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_script_debug_panel.xml
+++ b/indra/newview/skins/default/xui/es/floater_script_debug_panel.xml
diff --git a/indra/newview/skins/default/xui/es/floater_script_limits.xml b/indra/newview/skins/default/xui/es/floater_script_limits.xml
index 410f7b5e36..410f7b5e36 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_script_limits.xml
+++ b/indra/newview/skins/default/xui/es/floater_script_limits.xml
diff --git a/indra/newview/skins/default/xui/es/floater_script_preview.xml b/indra/newview/skins/default/xui/es/floater_script_preview.xml
index 5c190a4682..5c190a4682 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_script_preview.xml
+++ b/indra/newview/skins/default/xui/es/floater_script_preview.xml
diff --git a/indra/newview/skins/default/xui/es/floater_script_queue.xml b/indra/newview/skins/default/xui/es/floater_script_queue.xml
index 39c84103c4..39c84103c4 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_script_queue.xml
+++ b/indra/newview/skins/default/xui/es/floater_script_queue.xml
diff --git a/indra/newview/skins/default/xui/es/floater_script_search.xml b/indra/newview/skins/default/xui/es/floater_script_search.xml
index 1ab6682023..1ab6682023 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_script_search.xml
+++ b/indra/newview/skins/default/xui/es/floater_script_search.xml
diff --git a/indra/newview/skins/default/xui/es/floater_search.xml b/indra/newview/skins/default/xui/es/floater_search.xml
index e24d8064a1..e24d8064a1 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_search.xml
+++ b/indra/newview/skins/default/xui/es/floater_search.xml
diff --git a/indra/newview/skins/default/xui/es/floater_select_key.xml b/indra/newview/skins/default/xui/es/floater_select_key.xml
index 6503a3d5cb..6503a3d5cb 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_select_key.xml
+++ b/indra/newview/skins/default/xui/es/floater_select_key.xml
diff --git a/indra/newview/skins/default/xui/es/floater_sell_land.xml b/indra/newview/skins/default/xui/es/floater_sell_land.xml
index d883683945..d883683945 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_sell_land.xml
+++ b/indra/newview/skins/default/xui/es/floater_sell_land.xml
diff --git a/indra/newview/skins/default/xui/es/floater_settings_debug.xml b/indra/newview/skins/default/xui/es/floater_settings_debug.xml
index 1da2e491e1..1da2e491e1 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_settings_debug.xml
+++ b/indra/newview/skins/default/xui/es/floater_settings_debug.xml
diff --git a/indra/newview/skins/default/xui/es/floater_snapshot.xml b/indra/newview/skins/default/xui/es/floater_snapshot.xml
index 23078b3a55..23078b3a55 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_snapshot.xml
+++ b/indra/newview/skins/default/xui/es/floater_snapshot.xml
diff --git a/indra/newview/skins/default/xui/es/floater_sound_devices.xml b/indra/newview/skins/default/xui/es/floater_sound_devices.xml
index 0291f9e796..0291f9e796 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_sound_devices.xml
+++ b/indra/newview/skins/default/xui/es/floater_sound_devices.xml
diff --git a/indra/newview/skins/default/xui/es/floater_sound_preview.xml b/indra/newview/skins/default/xui/es/floater_sound_preview.xml
index 8b8d9f13ce..8b8d9f13ce 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_sound_preview.xml
+++ b/indra/newview/skins/default/xui/es/floater_sound_preview.xml
diff --git a/indra/newview/skins/default/xui/es/floater_spellcheck.xml b/indra/newview/skins/default/xui/es/floater_spellcheck.xml
new file mode 100755
index 0000000000..b664b96928
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/floater_spellcheck.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="spellcheck_floater" title="Configuración del corrector ortográfico">
+ <check_box label="Habilitar la revisión ortográfica" name="spellcheck_enable"/>
+ <text name="spellcheck_main">
+ Diccionario principal:
+ </text>
+ <text label="Registros:" name="spellcheck_additional">
+ Diccionarios adicionales:
+ </text>
+ <text name="spellcheck_available">
+ Disponibles
+ </text>
+ <text name="spellcheck_active">
+ Activos
+ </text>
+ <button label="Eliminar" name="spellcheck_remove_btn"/>
+ <button label="Importar..." name="spellcheck_import_btn"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/es/floater_spellcheck_import.xml b/indra/newview/skins/default/xui/es/floater_spellcheck_import.xml
new file mode 100755
index 0000000000..bd86ed00da
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/floater_spellcheck_import.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="spellcheck_import" title="Importar diccionario">
+ <button label="Examinar" label_selected="Examinar" name="dictionary_path_browse"/>
+ <button label="Importar" name="ok_btn"/>
+ <button label="Cancelar" name="cancel_btn"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/es/floater_stats.xml b/indra/newview/skins/default/xui/es/floater_stats.xml
index ba4af2e866..00601920f2 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_stats.xml
+++ b/indra/newview/skins/default/xui/es/floater_stats.xml
@@ -14,8 +14,11 @@
<stat_bar label="KTris generados por segundo" name="ktrissec"/>
<stat_bar label="Objetos en total" name="objs"/>
<stat_bar label="Objetos nuevos" name="newobjs"/>
+ <stat_bar label="Ãndice de aciertos de caché de objetos" name="object_cache_hits"/>
</stat_view>
<stat_view label="Textura" name="texture">
+ <stat_bar label="Ãndice de aciertos de caché" name="texture_cache_hits"/>
+ <stat_bar label="Latencia de lectura de caché" name="texture_cache_read_latency"/>
<stat_bar label="Número" name="numimagesstat"/>
<stat_bar label="Raw: número" name="numrawimagesstat"/>
<stat_bar label="GL Mem" name="gltexmemstat"/>
@@ -44,6 +47,12 @@
<stat_bar label="Objetos con bajo nivel de detalle" name="physicslodtasks"/>
<stat_bar label="Memoria asignada" name="physicsmemoryallocated"/>
</stat_view>
+ <stat_bar label="Scripts ejecutados" name="simpctscriptsrun"/>
+ <stat_view label="Pathfinding" name="simpathfinding">
+ <stat_bar label="Tiempo de paso de IA" name="simsimaistepmsec"/>
+ <stat_bar label="Pasos de silueta omitidos" name="simsimskippedsilhouettesteps"/>
+ <stat_bar label="Personajes actualizados" name="simsimpctsteppedcharacters"/>
+ </stat_view>
<stat_view label="Tiempo (ms)" name="simperf">
<stat_bar label="Tiempo total de los frames" name="simframemsec"/>
<stat_bar label="Tiempo de red" name="simnetmsec"/>
diff --git a/indra/newview/skins/default/xui/es/floater_sys_well.xml b/indra/newview/skins/default/xui/es/floater_sys_well.xml
index 8c8190be55..8c8190be55 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_sys_well.xml
+++ b/indra/newview/skins/default/xui/es/floater_sys_well.xml
diff --git a/indra/newview/skins/default/xui/es/floater_telehub.xml b/indra/newview/skins/default/xui/es/floater_telehub.xml
index 87cc9c1659..87cc9c1659 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_telehub.xml
+++ b/indra/newview/skins/default/xui/es/floater_telehub.xml
diff --git a/indra/newview/skins/default/xui/es/floater_test_layout_stacks.xml b/indra/newview/skins/default/xui/es/floater_test_layout_stacks.xml
index b479d5f6d6..b479d5f6d6 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_test_layout_stacks.xml
+++ b/indra/newview/skins/default/xui/es/floater_test_layout_stacks.xml
diff --git a/indra/newview/skins/default/xui/es/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/es/floater_texture_ctrl.xml
index ed2787ea60..01b024bc3e 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_texture_ctrl.xml
+++ b/indra/newview/skins/default/xui/es/floater_texture_ctrl.xml
@@ -1,24 +1,36 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="texture picker" title="DESTACADO: TEXTURA">
- <string name="choose_picture">
+ <floater.string name="choose_picture">
Pulse para elegir una imagen
- </string>
+ </floater.string>
+ <floater.string name="pick title">
+ Elegir:
+ </floater.string>
<text name="Multiple">
Texturas múltiples
</text>
+ <radio_group name="mode_selection">
+ <radio_item label="Inventario" name="inventory" value="0"/>
+ <radio_item label="Local" name="local" value="1"/>
+ </radio_group>
<text name="unknown">
Tamaño: [DIMENSIONS]
</text>
<button label="Por defecto" label_selected="Por defecto" name="Default" width="84"/>
- <button label="Ninguna" label_selected="Ninguna" left="90" name="None"/>
<button label="Blanca" label_selected="Blanca" name="Blank"/>
- <check_box label="Ver las carpetas" name="show_folders_check"/>
- <search_editor label="Filtrar las texturas" name="inventory search editor"/>
- <check_box label="Aplicarlo ahora" name="apply_immediate_check"/>
+ <button label="Ninguna" label_selected="Ninguna" left="90" name="None"/>
<button label="" label_selected="" name="Pipette"/>
- <button label="Cancelar" label_selected="Cancelar" name="Cancel"/>
+ <check_box initial_value="true" label="Aplicarlo ahora" name="apply_immediate_check"/>
+ <text name="preview_disabled" value="Vista previa inhabilitada"/>
+ <filter_editor label="Filtrar las texturas" name="inventory search editor"/>
+ <check_box initial_value="false" label="Ver las carpetas" name="show_folders_check"/>
+ <button label="Añadir" label_selected="Añadir" name="l_add_btn"/>
+ <button label="Eliminar" label_selected="Eliminar" name="l_rem_btn"/>
+ <button label="Subir" label_selected="Subir" name="l_upl_btn"/>
+ <scroll_list name="l_name_list">
+ <column label="Nombre" name="unit_name"/>
+ <column label="ID" name="unit_id_HIDDEN"/>
+ </scroll_list>
<button label="OK" label_selected="OK" name="Select"/>
- <string name="pick title">
- Elegir:
- </string>
+ <button label="Cancelar" label_selected="Cancelar" name="Cancel"/>
</floater>
diff --git a/indra/newview/skins/default/xui/es/floater_texture_fetch_debugger.xml b/indra/newview/skins/default/xui/es/floater_texture_fetch_debugger.xml
new file mode 100755
index 0000000000..59aaf7f74a
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/floater_texture_fetch_debugger.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="TexFetchDebugger" title="Depurador de obtención de texturas">
+ <text name="total_num_fetched_label">
+ 1, Número total de texturas obtenidas: [NUM]
+ </text>
+ <text name="total_num_fetching_requests_label">
+ 2, Número total de solicitudes de obtención: [NUM]
+ </text>
+ <text name="total_num_cache_hits_label">
+ 3, Número total de aciertos de caché: [NUM]
+ </text>
+ <text name="total_num_visible_tex_label">
+ 4, Número total de texturas visibles: [NUM]
+ </text>
+ <text name="total_num_visible_tex_fetch_req_label">
+ 5, Número total de solicitudes de obtención de texturas visibles: [NUM]
+ </text>
+ <text name="total_fetched_data_label">
+ 6, Número total de datos obtenidos: [SIZE1] KB, Datos descodificados: [SIZE2] KB, [PIXEL] MPíxeles
+ </text>
+ <text name="total_fetched_vis_data_label">
+ 7, Número total de datos visibles: [SIZE1] KB, Datos descodificados: [SIZE2] KB
+ </text>
+ <text name="total_fetched_rendered_data_label">
+ 8, Número total de datos representados: [SIZE1] KB, Datos descodificados: [SIZE2] KB, [PIXEL] MPíxeles
+ </text>
+ <text name="total_time_cache_read_label">
+ 9, Tiempo total en lecturas de caché: [TIME] segundos
+ </text>
+ <text name="total_time_cache_write_label">
+ 10, Tiempo total en escrituras de caché: [TIME] segundos
+ </text>
+ <text name="total_time_decode_label">
+ 11, Tiempo total en descodificaciones: [TIME] segundos
+ </text>
+ <text name="total_time_gl_label">
+ 12, Tiempo total en la creación de texturas gl: [TIME] segundos
+ </text>
+ <text name="total_time_http_label">
+ 13, Tiempo total en obtención de HTTP: [TIME] segundos
+ </text>
+ <text name="total_time_fetch_label">
+ 14, Tiempo total en obtención completa: [TIME] segundos
+ </text>
+ <text name="total_time_refetch_vis_cache_label">
+ 15, Volviendo a obtener visibles de la caché, Tiempo: [TIME] segundos, Obtenidos: [SIZE] KB, [PIXEL] MPíxeles
+ </text>
+ <text name="total_time_refetch_all_cache_label">
+ 16, Volviendo a obtener todas las texturas de caché, Tiempo: [TIME] segundos, Obtenidos: [SIZE] KB, [PIXEL] MPíxeles
+ </text>
+ <text name="total_time_refetch_vis_http_label">
+ 17, Volviendo a obtener visibles de HTTP, Tiempo: [TIME] segundos, Obtenidos: [SIZE] KB, [PIXEL] MPíxeles
+ </text>
+ <text name="total_time_refetch_all_http_label">
+ 18, Volviendo a obtener todas las texturas de HTTP, Tiempo: [TIME] segundos, Obtenidos: [SIZE] KB, [PIXEL] MPíxeles
+ </text>
+ <spinner label="19, Proporción de texeles/píxeles:" name="texel_pixel_ratio"/>
+ <text name="texture_source_label">
+ 20, Fuente de texturas:
+ </text>
+ <radio_group name="texture_source">
+ <radio_item label="Caché + HTTP" name="0"/>
+ <radio_item label="Solo HTTP" name="1"/>
+ </radio_group>
+ <button label="Iniciar" name="start_btn"/>
+ <button label="Restablecer" name="clear_btn"/>
+ <button label="Cerrar" name="close_btn"/>
+ <button label="Lectura de caché" name="cacheread_btn"/>
+ <button label="Escritura de caché" name="cachewrite_btn"/>
+ <button label="HTTP" name="http_btn"/>
+ <button label="Descodificar" name="decode_btn"/>
+ <button label="Textura GL" name="gl_btn"/>
+ <button label="Volver a obtener caché de vis." name="refetchviscache_btn"/>
+ <button label="Volver a obtener toda la caché" name="refetchallcache_btn"/>
+ <button label="Volver a obtener HTTP de vis." name="refetchvishttp_btn"/>
+ <button label="Volver a obtener todo el HTTP" name="refetchallhttp_btn"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/es/floater_tools.xml b/indra/newview/skins/default/xui/es/floater_tools.xml
index 650b4b457d..32baa5bb7d 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_tools.xml
+++ b/indra/newview/skins/default/xui/es/floater_tools.xml
@@ -128,6 +128,12 @@
<panel.string name="text modify info 4">
No puedes modificar estos objetos
</panel.string>
+ <panel.string name="text modify info 5">
+ No se puede modificar este objeto a través del límite de una región
+ </panel.string>
+ <panel.string name="text modify info 6">
+ No se pueden modificar estos objetos a través del límite de una región
+ </panel.string>
<panel.string name="text modify warning">
Para configurar los permisos, debes seleccionar el objeto completo
</panel.string>
@@ -177,12 +183,12 @@
<combo_box.item label="Zoom" name="Zoom"/>
</combo_box>
<check_box label="En venta:" name="checkbox for sale"/>
+ <spinner label="L$" name="Edit Cost"/>
<combo_box name="sale type">
<combo_box.item label="Copia" name="Copy"/>
<combo_box.item label="Contenidos" name="Contents"/>
<combo_box.item label="Original" name="Original"/>
</combo_box>
- <spinner label="Precio: L$" name="Edit Cost"/>
<check_box label="Mostrar en la búsqueda" name="search_check" tool_tip="Dejar que la gente vea este objeto en los resultados de la búsqueda"/>
<panel name="perms_build">
<text name="perm_modify">
@@ -218,6 +224,11 @@
F:
</text>
</panel>
+ <panel name="pathfinding_attrs_panel">
+ <text name="pathfinding_attributes_label">
+ Atributos de pathfinding:
+ </text>
+ </panel>
</panel>
<panel label="Objeto" name="Object">
<check_box label="Bloqueado" name="checkbox locked" tool_tip="Previene que el objeto sea movido o borrado. Suele ser útil mientras se construye, para prevenir que se modifique sin querer."/>
@@ -432,16 +443,11 @@
<combo_box.item label="succión" name="suction"/>
<combo_box.item label="tejido" name="weave"/>
</combo_box>
- <check_box initial_value="falso" label="Alinear caras del plano" name="checkbox planar align" tool_tip="Alinear texturas en todas las caras seleccionadas con la última cara seleccionada. Requiere la representación de texturas en el plano."/>
- <text name="rpt">
- Repeticiones por cara
- </text>
<spinner label="Horizontal (U)" name="TexScaleU"/>
<check_box label="Voltear" name="checkbox flip s"/>
<spinner label="Vertical (V)" name="TexScaleV"/>
<check_box label="Voltear" name="checkbox flip t"/>
<spinner label="Rotación" name="TexRot"/>
- <spinner label="Repeticiones / Metro" name="rptctrl"/>
<button label="Aplicar" label_selected="Aplicar" name="button apply"/>
<text name="tex offset">
Desplazar
diff --git a/indra/newview/skins/default/xui/es/floater_top_objects.xml b/indra/newview/skins/default/xui/es/floater_top_objects.xml
index 033633bd22..bb53f116c2 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_top_objects.xml
+++ b/indra/newview/skins/default/xui/es/floater_top_objects.xml
@@ -9,9 +9,6 @@
<floater.string name="scripts_score_label">
Tiempo
</floater.string>
- <floater.string name="scripts_mono_time_label">
- Tiempo en Mono
- </floater.string>
<floater.string name="top_colliders_title">
Objetos que colisionan
</floater.string>
@@ -32,9 +29,10 @@
<scroll_list.columns label="Nombre" name="name"/>
<scroll_list.columns label="Propietario" name="owner"/>
<scroll_list.columns label="Posición" name="location"/>
+ <scroll_list.columns label="Parcela" name="parcel"/>
<scroll_list.columns label="Tiempo" name="time"/>
- <scroll_list.columns label="Tiempo en Mono" name="mono_time"/>
<scroll_list.columns label="URLs" name="URLs"/>
+ <scroll_list.columns label="Memoria (KB)" name="memory"/>
</scroll_list>
<text name="id_text">
ID del objeto:
@@ -48,6 +46,10 @@
Propietario:
</text>
<button label="Filtro" name="filter_owner_btn"/>
+ <text name="parcel_name_text">
+ Parcela:
+ </text>
+ <button label="Filtro" name="filter_parcel_btn"/>
<button label="Actualizar" name="refresh_btn"/>
<button label="Devolver lo seleccionado" name="return_selected_btn" width="170"/>
<button label="Devolver todo" left="190" name="return_all_btn"/>
diff --git a/indra/newview/skins/default/xui/es/floater_tos.xml b/indra/newview/skins/default/xui/es/floater_tos.xml
index 89092201d9..89092201d9 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_tos.xml
+++ b/indra/newview/skins/default/xui/es/floater_tos.xml
diff --git a/indra/newview/skins/default/xui/es/floater_toybox.xml b/indra/newview/skins/default/xui/es/floater_toybox.xml
index 7275b0546b..7275b0546b 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_toybox.xml
+++ b/indra/newview/skins/default/xui/es/floater_toybox.xml
diff --git a/indra/newview/skins/default/xui/es/floater_translation_settings.xml b/indra/newview/skins/default/xui/es/floater_translation_settings.xml
index 765c9a05a2..765c9a05a2 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_translation_settings.xml
+++ b/indra/newview/skins/default/xui/es/floater_translation_settings.xml
diff --git a/indra/newview/skins/default/xui/es/floater_url_entry.xml b/indra/newview/skins/default/xui/es/floater_url_entry.xml
index f7c85ff068..f7c85ff068 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_url_entry.xml
+++ b/indra/newview/skins/default/xui/es/floater_url_entry.xml
diff --git a/indra/newview/skins/default/xui/es/floater_voice_chat_volume.xml b/indra/newview/skins/default/xui/es/floater_voice_chat_volume.xml
new file mode 100644
index 0000000000..1115d67239
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/floater_voice_chat_volume.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="floater_voice_volume" title="VOLUMEN DE CHAT DE VOZ">
+ <slider label="Chat de voz" name="chat_voice_volume"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/es/floater_voice_controls.xml b/indra/newview/skins/default/xui/es/floater_voice_controls.xml
index eff21239be..eff21239be 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_voice_controls.xml
+++ b/indra/newview/skins/default/xui/es/floater_voice_controls.xml
diff --git a/indra/newview/skins/default/xui/es/floater_voice_effect.xml b/indra/newview/skins/default/xui/es/floater_voice_effect.xml
index 1a265845af..02ebe80ff7 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_voice_effect.xml
+++ b/indra/newview/skins/default/xui/es/floater_voice_effect.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater label="Lugares" name="voice_effects" title="TRANSFORMACIÓN DE VOZ">
+<floater label="Lugares" name="voice_effects" title="PROBAR TRANSFORMACIÓN DE VOZ">
<string name="no_voice_effect">
(Sin transformación de voz)
</string>
diff --git a/indra/newview/skins/default/xui/es/floater_voice_volume.xml b/indra/newview/skins/default/xui/es/floater_voice_volume.xml
new file mode 100644
index 0000000000..0ebc511887
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/floater_voice_volume.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<!--
+ Not can_close / no title to avoid window chrome
+ Single instance - only have one at a time, recycle it each spawn
+-->
+<floater name="floater_voice_volume" title="VOLUMEN DE VOZ">
+ <slider name="volume_slider" tool_tip="Volumen de la voz" value="0.5"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/es/floater_web_content.xml b/indra/newview/skins/default/xui/es/floater_web_content.xml
index 5e02fad2dd..5e02fad2dd 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_web_content.xml
+++ b/indra/newview/skins/default/xui/es/floater_web_content.xml
diff --git a/indra/newview/skins/default/xui/es/floater_whitelist_entry.xml b/indra/newview/skins/default/xui/es/floater_whitelist_entry.xml
index 7dc47ca367..7dc47ca367 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_whitelist_entry.xml
+++ b/indra/newview/skins/default/xui/es/floater_whitelist_entry.xml
diff --git a/indra/newview/skins/default/xui/es/floater_window_size.xml b/indra/newview/skins/default/xui/es/floater_window_size.xml
index f57ce08eac..6c1ad02319 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_window_size.xml
+++ b/indra/newview/skins/default/xui/es/floater_window_size.xml
@@ -7,10 +7,17 @@
Definir el tamaño de la ventana:
</text>
<combo_box name="window_size_combo" tool_tip="ancho x alto">
- <combo_box.item label="1000 x 700 (por defecto)" name="item0"/>
- <combo_box.item label="1024 x 768" name="item1"/>
- <combo_box.item label="1280 x 720 (720 p)" name="item2"/>
- <combo_box.item label="1920 x 1080 (1080 p)" name="item3"/>
+ <combo_box.item label="1000 x 700 (por defecto)" name="item1"/>
+ <combo_box.item label="1024 x 768 (4:3 XGA)" name="item2"/>
+ <combo_box.item label="1280 x 720 (16:9 HDTV)" name="item3"/>
+ <combo_box.item label="1280 x 800 (5:8 WXGA)" name="item4"/>
+ <combo_box.item label="1280 x 1024 (5:4 SXGA)" name="item5"/>
+ <combo_box.item label="1440 x 900 (8:5 WSXGA)" name="item7"/>
+ <combo_box.item label="1600 x 900 (16:9 HD+)" name="item8"/>
+ <combo_box.item label="1600 x 1200 (4:3 UXGA)" name="item9"/>
+ <combo_box.item label="1680 x 1050 (8:5 WSXGA+)" name="item10"/>
+ <combo_box.item label="1920 x 1080 (16:9 HDTV)" name="item11"/>
+ <combo_box.item label="1920 x 1200 (8:5 WUXGA)" name="item12"/>
</combo_box>
<button label="Configurar" name="set_btn"/>
<button label="Cancelar" name="cancel_btn"/>
diff --git a/indra/newview/skins/default/xui/es/floater_world_map.xml b/indra/newview/skins/default/xui/es/floater_world_map.xml
index acc63e52a0..acc63e52a0 100644..100755
--- a/indra/newview/skins/default/xui/es/floater_world_map.xml
+++ b/indra/newview/skins/default/xui/es/floater_world_map.xml
diff --git a/indra/newview/skins/default/xui/es/inspect_avatar.xml b/indra/newview/skins/default/xui/es/inspect_avatar.xml
index 1d70fa6a90..1d70fa6a90 100644..100755
--- a/indra/newview/skins/default/xui/es/inspect_avatar.xml
+++ b/indra/newview/skins/default/xui/es/inspect_avatar.xml
diff --git a/indra/newview/skins/default/xui/es/inspect_group.xml b/indra/newview/skins/default/xui/es/inspect_group.xml
index ba10b19f41..ba10b19f41 100644..100755
--- a/indra/newview/skins/default/xui/es/inspect_group.xml
+++ b/indra/newview/skins/default/xui/es/inspect_group.xml
diff --git a/indra/newview/skins/default/xui/es/inspect_object.xml b/indra/newview/skins/default/xui/es/inspect_object.xml
index d608b4a0f7..d608b4a0f7 100644..100755
--- a/indra/newview/skins/default/xui/es/inspect_object.xml
+++ b/indra/newview/skins/default/xui/es/inspect_object.xml
diff --git a/indra/newview/skins/default/xui/es/inspect_remote_object.xml b/indra/newview/skins/default/xui/es/inspect_remote_object.xml
index f814e84a6f..f814e84a6f 100644..100755
--- a/indra/newview/skins/default/xui/es/inspect_remote_object.xml
+++ b/indra/newview/skins/default/xui/es/inspect_remote_object.xml
diff --git a/indra/newview/skins/default/xui/es/language_settings.xml b/indra/newview/skins/default/xui/es/language_settings.xml
index 997293a741..997293a741 100644..100755
--- a/indra/newview/skins/default/xui/es/language_settings.xml
+++ b/indra/newview/skins/default/xui/es/language_settings.xml
diff --git a/indra/newview/skins/default/xui/es/menu_add_wearable_gear.xml b/indra/newview/skins/default/xui/es/menu_add_wearable_gear.xml
index f2367c72a3..f2367c72a3 100644..100755
--- a/indra/newview/skins/default/xui/es/menu_add_wearable_gear.xml
+++ b/indra/newview/skins/default/xui/es/menu_add_wearable_gear.xml
diff --git a/indra/newview/skins/default/xui/es/menu_attachment_other.xml b/indra/newview/skins/default/xui/es/menu_attachment_other.xml
index 00bdb74881..7698348c00 100644..100755
--- a/indra/newview/skins/default/xui/es/menu_attachment_other.xml
+++ b/indra/newview/skins/default/xui/es/menu_attachment_other.xml
@@ -11,7 +11,9 @@
<menu_item_call label="Congelar" name="Freeze..."/>
<menu_item_call label="Expulsar" name="Eject..."/>
<menu_item_call label="Depurar las texturas" name="Debug..."/>
+ <menu_item_call label="Volcar XML" name="Dump XML"/>
<menu_item_call label="Acercar el zoom" name="Zoom In"/>
<menu_item_call label="Pagar" name="Pay..."/>
<menu_item_call label="Perfil del objeto" name="Object Inspect"/>
+ <menu_item_call label="Ignorar al propietario de la partícula" name="Mute Particle"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/es/menu_attachment_self.xml b/indra/newview/skins/default/xui/es/menu_attachment_self.xml
index 0ba39378bb..5acd0c327a 100644..100755
--- a/indra/newview/skins/default/xui/es/menu_attachment_self.xml
+++ b/indra/newview/skins/default/xui/es/menu_attachment_self.xml
@@ -12,5 +12,7 @@
<menu_item_call label="Mis grupos" name="Groups..."/>
<menu_item_call label="Mi perfil" name="Profile..."/>
<menu_item_call label="Depurar las texturas" name="Debug..."/>
+ <menu_item_call label="Volcar XML" name="Dump XML"/>
<menu_item_call label="Soltar" name="Drop"/>
+ <menu_item_call label="Ignorar al propietario de la partícula" name="Mute Particle"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/es/menu_avatar_icon.xml b/indra/newview/skins/default/xui/es/menu_avatar_icon.xml
index fe7331a108..fe7331a108 100644..100755
--- a/indra/newview/skins/default/xui/es/menu_avatar_icon.xml
+++ b/indra/newview/skins/default/xui/es/menu_avatar_icon.xml
diff --git a/indra/newview/skins/default/xui/es/menu_avatar_other.xml b/indra/newview/skins/default/xui/es/menu_avatar_other.xml
index 7df2d7c4e0..244099214a 100644..100755
--- a/indra/newview/skins/default/xui/es/menu_avatar_other.xml
+++ b/indra/newview/skins/default/xui/es/menu_avatar_other.xml
@@ -11,6 +11,8 @@
<menu_item_call label="Congelar" name="Freeze..."/>
<menu_item_call label="Expulsar" name="Eject..."/>
<menu_item_call label="Depurar las texturas" name="Debug..."/>
+ <menu_item_call label="Volcar XML" name="Dump XML"/>
<menu_item_call label="Acercar el zoom" name="Zoom In"/>
<menu_item_call label="Pagar" name="Pay..."/>
+ <menu_item_call label="Ignorar al propietario de la partícula" name="Mute Particle"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/es/menu_avatar_self.xml b/indra/newview/skins/default/xui/es/menu_avatar_self.xml
index 268d6f70ab..717b46ac74 100644..100755
--- a/indra/newview/skins/default/xui/es/menu_avatar_self.xml
+++ b/indra/newview/skins/default/xui/es/menu_avatar_self.xml
@@ -29,4 +29,6 @@
<menu_item_call label="Mis grupos" name="Groups..."/>
<menu_item_call label="Mi perfil" name="Profile..."/>
<menu_item_call label="Depurar las texturas" name="Debug..."/>
+ <menu_item_call label="Volcar XML" name="Dump XML"/>
+ <menu_item_call label="Ignorar al propietario de la partícula" name="Mute Particle"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/es/menu_bottomtray.xml b/indra/newview/skins/default/xui/es/menu_bottomtray.xml
deleted file mode 100644
index 40058a1749..0000000000
--- a/indra/newview/skins/default/xui/es/menu_bottomtray.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<menu name="hide_camera_move_controls_menu">
- <menu_item_check label="Botón Hablar" name="EnableVoiceChat"/>
- <menu_item_check label="Botón Gestos" name="ShowGestureButton"/>
- <menu_item_check label="Botón Moverse" name="ShowMoveButton"/>
- <menu_item_check label="Botón Vista" name="ShowCameraButton"/>
- <menu_item_check label="Botón Foto" name="ShowSnapshotButton"/>
- <menu_item_check label="Botón Construir" name="ShowBuildButton"/>
- <menu_item_check label="Botón Buscar" name="ShowSearchButton"/>
- <menu_item_check label="Botón Mapa" name="ShowWorldMapButton"/>
- <menu_item_check label="Botón Minimapa" name="ShowMiniMapButton"/>
- <menu_item_call label="Cortar" name="NearbyChatBar_Cut"/>
- <menu_item_call label="Copiar" name="NearbyChatBar_Copy"/>
- <menu_item_call label="Pegar" name="NearbyChatBar_Paste"/>
- <menu_item_call label="Borrar" name="NearbyChatBar_Delete"/>
- <menu_item_call label="Seleccionar todo" name="NearbyChatBar_Select_All"/>
-</menu>
diff --git a/indra/newview/skins/default/xui/es/menu_cof_attachment.xml b/indra/newview/skins/default/xui/es/menu_cof_attachment.xml
index 7541530601..7541530601 100644..100755
--- a/indra/newview/skins/default/xui/es/menu_cof_attachment.xml
+++ b/indra/newview/skins/default/xui/es/menu_cof_attachment.xml
diff --git a/indra/newview/skins/default/xui/es/menu_cof_body_part.xml b/indra/newview/skins/default/xui/es/menu_cof_body_part.xml
index 56b95bdc3b..56b95bdc3b 100644..100755
--- a/indra/newview/skins/default/xui/es/menu_cof_body_part.xml
+++ b/indra/newview/skins/default/xui/es/menu_cof_body_part.xml
diff --git a/indra/newview/skins/default/xui/es/menu_cof_clothing.xml b/indra/newview/skins/default/xui/es/menu_cof_clothing.xml
index 3c0c588284..3c0c588284 100644..100755
--- a/indra/newview/skins/default/xui/es/menu_cof_clothing.xml
+++ b/indra/newview/skins/default/xui/es/menu_cof_clothing.xml
diff --git a/indra/newview/skins/default/xui/es/menu_cof_gear.xml b/indra/newview/skins/default/xui/es/menu_cof_gear.xml
index ff8ad0977a..a889992b8a 100644..100755
--- a/indra/newview/skins/default/xui/es/menu_cof_gear.xml
+++ b/indra/newview/skins/default/xui/es/menu_cof_gear.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<menu name="Gear COF">
+<toggleable_menu name="Gear COF">
<menu label="Ropas nuevas" name="COF.Gear.New_Clothes"/>
- <menu label="Nuevas partes del cuerpo" name="COF.Geear.New_Body_Parts"/>
-</menu>
+ <menu label="Nuevas partes del cuerpo" name="COF.Gear.New_Body_Parts"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/es/menu_conversation.xml b/indra/newview/skins/default/xui/es/menu_conversation.xml
new file mode 100644
index 0000000000..b63711589d
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/menu_conversation.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_conversation_participant">
+ <menu_item_call label="Cerrar conversación" name="close_conversation"/>
+ <menu_item_call label="Abrir conversación de voz" name="open_voice_conversation"/>
+ <menu_item_call label="Desconectar de voz" name="disconnect_from_voice"/>
+ <menu_item_call label="Cerrar seleccionados" name="close_selected_conversations"/>
+ <menu_item_call label="Ver el perfil" name="view_profile"/>
+ <menu_item_call label="MI" name="im"/>
+ <menu_item_call label="Ofrecer teleporte" name="offer_teleport"/>
+ <menu_item_call label="Llamada de voz" name="voice_call"/>
+ <menu_item_call label="Historial del chat..." name="chat_history"/>
+ <menu_item_call label="Añadir como amigo" name="add_friend"/>
+ <menu_item_call label="Quitarle como amigo" name="remove_friend"/>
+ <menu_item_call label="Quitar amigos" name="remove_friends"/>
+ <menu_item_call label="Invitar al grupo..." name="invite_to_group"/>
+ <menu_item_call label="Acercar el zoom" name="zoom_in"/>
+ <menu_item_call label="Mapa" name="map"/>
+ <menu_item_call label="Compartir" name="share"/>
+ <menu_item_call label="Pagar" name="pay"/>
+ <menu_item_check label="Ignorar la voz" name="block_unblock"/>
+ <menu_item_check label="Ignorar el texto" name="MuteText"/>
+ <menu_item_call label="Perfil del grupo" name="group_profile"/>
+ <menu_item_call label="Activar el grupo" name="activate_group"/>
+ <menu_item_call label="Abandonar el grupo" name="leave_group"/>
+ <context_menu label="Opciones del moderador" name="Moderator Options">
+ <menu_item_check label="Permitir el chat de texto" name="AllowTextChat"/>
+ <menu_item_call label="Ignorar a este participante" name="ModerateVoiceMuteSelected"/>
+ <menu_item_call label="Quitar el silencio a este participante" name="ModerateVoiceUnMuteSelected"/>
+ <menu_item_call label="Silenciar a todos" name="ModerateVoiceMute"/>
+ <menu_item_call label="Quitar el silencio a todos" name="ModerateVoiceUnmute"/>
+ </context_menu>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/es/menu_conversation_log_gear.xml b/indra/newview/skins/default/xui/es/menu_conversation_log_gear.xml
new file mode 100644
index 0000000000..090e6fb0bf
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/menu_conversation_log_gear.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="Conversation Context Menu">
+ <menu_item_call label="MI..." name="IM"/>
+ <menu_item_call label="Llamada de voz..." name="Call"/>
+ <menu_item_call label="Abrir el historial de chat..." name="Chat history"/>
+ <menu_item_call label="Ver el perfil" name="View Profile"/>
+ <menu_item_call label="Ofrecer teleporte" name="teleport"/>
+ <menu_item_call label="Añadir como amigo" name="add_friend"/>
+ <menu_item_call label="Quitarle como amigo" name="remove_friend"/>
+ <menu_item_call label="Invitar al grupo..." name="Invite"/>
+ <menu_item_call label="Mapa" name="Map"/>
+ <menu_item_call label="Compartir" name="Share"/>
+ <menu_item_call label="Pagar" name="Pay"/>
+ <menu_item_check label="Ignorar / No ignorar" name="Block/Unblock"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/es/menu_conversation_log_view.xml b/indra/newview/skins/default/xui/es/menu_conversation_log_view.xml
new file mode 100644
index 0000000000..b8b4616b2d
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/menu_conversation_log_view.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_conversation_view">
+ <menu_item_check label="Ordenar alfabéticamente" name="sort_by_name"/>
+ <menu_item_check label="Ordenar por fecha" name="sort_by_date"/>
+ <menu_item_check label="Ordenar con los amigos al principio" name="sort_by_friends"/>
+ <menu_item_call label="Ver el historial de chat..." name="view_nearby_chat_history"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/es/menu_edit.xml b/indra/newview/skins/default/xui/es/menu_edit.xml
index 96fc9d8881..96fc9d8881 100644..100755
--- a/indra/newview/skins/default/xui/es/menu_edit.xml
+++ b/indra/newview/skins/default/xui/es/menu_edit.xml
diff --git a/indra/newview/skins/default/xui/es/menu_favorites.xml b/indra/newview/skins/default/xui/es/menu_favorites.xml
index 85210d5c49..85210d5c49 100644..100755
--- a/indra/newview/skins/default/xui/es/menu_favorites.xml
+++ b/indra/newview/skins/default/xui/es/menu_favorites.xml
diff --git a/indra/newview/skins/default/xui/es/menu_gesture_gear.xml b/indra/newview/skins/default/xui/es/menu_gesture_gear.xml
index 24706eb2c8..24706eb2c8 100644..100755
--- a/indra/newview/skins/default/xui/es/menu_gesture_gear.xml
+++ b/indra/newview/skins/default/xui/es/menu_gesture_gear.xml
diff --git a/indra/newview/skins/default/xui/es/menu_group_plus.xml b/indra/newview/skins/default/xui/es/menu_group_plus.xml
index 6b26ba42c4..6b26ba42c4 100644..100755
--- a/indra/newview/skins/default/xui/es/menu_group_plus.xml
+++ b/indra/newview/skins/default/xui/es/menu_group_plus.xml
diff --git a/indra/newview/skins/default/xui/es/menu_hide_navbar.xml b/indra/newview/skins/default/xui/es/menu_hide_navbar.xml
index 9945908c4f..9945908c4f 100644..100755
--- a/indra/newview/skins/default/xui/es/menu_hide_navbar.xml
+++ b/indra/newview/skins/default/xui/es/menu_hide_navbar.xml
diff --git a/indra/newview/skins/default/xui/es/menu_im_conversation.xml b/indra/newview/skins/default/xui/es/menu_im_conversation.xml
new file mode 100644
index 0000000000..5ba0fb898e
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/menu_im_conversation.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="Conversation Gear Menu">
+ <menu_item_call label="Ver el perfil" name="View Profile"/>
+ <menu_item_call label="Añadir como amigo" name="Add Friend"/>
+ <menu_item_call label="Quitarle como amigo" name="remove_friend"/>
+ <menu_item_call label="Ofrecer teleporte" name="offer_teleport"/>
+ <menu_item_call label="Invitar al grupo..." name="invite_to_group"/>
+ <menu_item_call label="Historial del chat..." name="chat_history"/>
+ <menu_item_call label="Acercar el zoom" name="zoom_in"/>
+ <menu_item_call label="Mapa" name="map"/>
+ <menu_item_call label="Compartir" name="Share"/>
+ <menu_item_call label="Pagar" name="Pay"/>
+ <menu_item_check label="Ignorar la voz" name="Block/Unblock"/>
+ <menu_item_check label="Ignorar el texto" name="MuteText"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/es/menu_im_session_showmodes.xml b/indra/newview/skins/default/xui/es/menu_im_session_showmodes.xml
new file mode 100644
index 0000000000..6ea970b826
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/menu_im_session_showmodes.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_modes">
+ <menu_item_check label="Vista compacta" name="compact_view"/>
+ <menu_item_check label="Vista ampliada" name="expanded_view"/>
+ <menu_item_check label="Mostrar tiempo" name="IMShowTime"/>
+ <menu_item_check label="Mostrar los nombres en las conversaciones individuales" name="IMShowNamesForP2PConv"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/es/menu_im_well_button.xml b/indra/newview/skins/default/xui/es/menu_im_well_button.xml
deleted file mode 100644
index c8f6c217cc..0000000000
--- a/indra/newview/skins/default/xui/es/menu_im_well_button.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<context_menu name="IM Well Button Context Menu">
- <menu_item_call label="Cerrar todo" name="Close All"/>
-</context_menu>
diff --git a/indra/newview/skins/default/xui/es/menu_imchiclet_adhoc.xml b/indra/newview/skins/default/xui/es/menu_imchiclet_adhoc.xml
index e11e9bdc58..e11e9bdc58 100644..100755
--- a/indra/newview/skins/default/xui/es/menu_imchiclet_adhoc.xml
+++ b/indra/newview/skins/default/xui/es/menu_imchiclet_adhoc.xml
diff --git a/indra/newview/skins/default/xui/es/menu_imchiclet_group.xml b/indra/newview/skins/default/xui/es/menu_imchiclet_group.xml
index a5e60ea40b..a5e60ea40b 100644..100755
--- a/indra/newview/skins/default/xui/es/menu_imchiclet_group.xml
+++ b/indra/newview/skins/default/xui/es/menu_imchiclet_group.xml
diff --git a/indra/newview/skins/default/xui/es/menu_imchiclet_p2p.xml b/indra/newview/skins/default/xui/es/menu_imchiclet_p2p.xml
index 492801026c..492801026c 100644..100755
--- a/indra/newview/skins/default/xui/es/menu_imchiclet_p2p.xml
+++ b/indra/newview/skins/default/xui/es/menu_imchiclet_p2p.xml
diff --git a/indra/newview/skins/default/xui/es/menu_inspect_avatar_gear.xml b/indra/newview/skins/default/xui/es/menu_inspect_avatar_gear.xml
index 82fc8ddd39..82fc8ddd39 100644..100755
--- a/indra/newview/skins/default/xui/es/menu_inspect_avatar_gear.xml
+++ b/indra/newview/skins/default/xui/es/menu_inspect_avatar_gear.xml
diff --git a/indra/newview/skins/default/xui/es/menu_inspect_object_gear.xml b/indra/newview/skins/default/xui/es/menu_inspect_object_gear.xml
index 9d0a8c50ef..9d0a8c50ef 100644..100755
--- a/indra/newview/skins/default/xui/es/menu_inspect_object_gear.xml
+++ b/indra/newview/skins/default/xui/es/menu_inspect_object_gear.xml
diff --git a/indra/newview/skins/default/xui/es/menu_inspect_self_gear.xml b/indra/newview/skins/default/xui/es/menu_inspect_self_gear.xml
index 29ad718fdd..29ad718fdd 100644..100755
--- a/indra/newview/skins/default/xui/es/menu_inspect_self_gear.xml
+++ b/indra/newview/skins/default/xui/es/menu_inspect_self_gear.xml
diff --git a/indra/newview/skins/default/xui/es/menu_inv_offer_chiclet.xml b/indra/newview/skins/default/xui/es/menu_inv_offer_chiclet.xml
index 20d99afde1..20d99afde1 100644..100755
--- a/indra/newview/skins/default/xui/es/menu_inv_offer_chiclet.xml
+++ b/indra/newview/skins/default/xui/es/menu_inv_offer_chiclet.xml
diff --git a/indra/newview/skins/default/xui/es/menu_inventory.xml b/indra/newview/skins/default/xui/es/menu_inventory.xml
index 4a8f37dee4..803d3f1331 100644..100755
--- a/indra/newview/skins/default/xui/es/menu_inventory.xml
+++ b/indra/newview/skins/default/xui/es/menu_inventory.xml
@@ -67,6 +67,7 @@
<menu_item_call label="Borrar carpeta del sistema" name="Delete System Folder"/>
<menu_item_call label="Empezar multiconferencia" name="Conference Chat Folder"/>
<menu_item_call label="Escuchar" name="Sound Play"/>
+ <menu_item_call label="Copiar la SLurl" name="url_copy"/>
<menu_item_call label="Acerca del hito" name="About Landmark"/>
<menu_item_call label="Escuchar en el mundo" name="Animation Play"/>
<menu_item_call label="Ejecutarla para usted" name="Animation Audition"/>
diff --git a/indra/newview/skins/default/xui/es/menu_inventory_add.xml b/indra/newview/skins/default/xui/es/menu_inventory_add.xml
index f17cfe4ceb..f17cfe4ceb 100644..100755
--- a/indra/newview/skins/default/xui/es/menu_inventory_add.xml
+++ b/indra/newview/skins/default/xui/es/menu_inventory_add.xml
diff --git a/indra/newview/skins/default/xui/es/menu_inventory_gear_default.xml b/indra/newview/skins/default/xui/es/menu_inventory_gear_default.xml
index 0e9644629e..0e9644629e 100644..100755
--- a/indra/newview/skins/default/xui/es/menu_inventory_gear_default.xml
+++ b/indra/newview/skins/default/xui/es/menu_inventory_gear_default.xml
diff --git a/indra/newview/skins/default/xui/es/menu_land.xml b/indra/newview/skins/default/xui/es/menu_land.xml
index b0f15be1b6..2097628356 100644..100755
--- a/indra/newview/skins/default/xui/es/menu_land.xml
+++ b/indra/newview/skins/default/xui/es/menu_land.xml
@@ -6,4 +6,5 @@
<menu_item_call label="Comprar un pase" name="Land Buy Pass"/>
<menu_item_call label="Construir" name="Create"/>
<menu_item_call label="Modificar el terreno" name="Edit Terrain"/>
+ <menu_item_call label="Ignorar al propietario de la partícula" name="Mute Particle"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/es/menu_landmark.xml b/indra/newview/skins/default/xui/es/menu_landmark.xml
index f69b1539b8..f69b1539b8 100644..100755
--- a/indra/newview/skins/default/xui/es/menu_landmark.xml
+++ b/indra/newview/skins/default/xui/es/menu_landmark.xml
diff --git a/indra/newview/skins/default/xui/es/menu_login.xml b/indra/newview/skins/default/xui/es/menu_login.xml
index 289ac3f075..2286d0527a 100644..100755
--- a/indra/newview/skins/default/xui/es/menu_login.xml
+++ b/indra/newview/skins/default/xui/es/menu_login.xml
@@ -17,7 +17,13 @@
<menu_item_call label="Mostrar los &apos;TOS&apos;" name="TOS"/>
<menu_item_call label="Mostrar mensaje crítico" name="Critical"/>
<menu_item_call label="Prueba de depuración de ventanas de contenido web" name="Web Content Floater Debug Test"/>
- <menu label="Configurar el nivel de registro" name="Set Logging Level"/>
+ <menu label="Configurar el nivel de registro" name="Set Logging Level">
+ <menu_item_check label="Depurar" name="Debug"/>
+ <menu_item_check label="Información" name="Info"/>
+ <menu_item_check label="¡Atención!" name="Warning"/>
+ <menu_item_check label="Error" name="Error"/>
+ <menu_item_check label="Ninguno" name="None"/>
+ </menu>
<menu_item_check label="Mostrar el selector de Grid" name="Show Grid Picker"/>
<menu_item_call label="Mostrar la consola de notificaciones" name="Show Notifications Console"/>
</menu>
diff --git a/indra/newview/skins/default/xui/es/menu_media_ctrl.xml b/indra/newview/skins/default/xui/es/menu_media_ctrl.xml
index b4dfe9907a..b4dfe9907a 100644..100755
--- a/indra/newview/skins/default/xui/es/menu_media_ctrl.xml
+++ b/indra/newview/skins/default/xui/es/menu_media_ctrl.xml
diff --git a/indra/newview/skins/default/xui/es/menu_mini_map.xml b/indra/newview/skins/default/xui/es/menu_mini_map.xml
index 07d1b08572..07d1b08572 100644..100755
--- a/indra/newview/skins/default/xui/es/menu_mini_map.xml
+++ b/indra/newview/skins/default/xui/es/menu_mini_map.xml
diff --git a/indra/newview/skins/default/xui/es/menu_mode_change.xml b/indra/newview/skins/default/xui/es/menu_mode_change.xml
deleted file mode 100644
index 608505d192..0000000000
--- a/indra/newview/skins/default/xui/es/menu_mode_change.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<toggleable_menu name="Mode Change">
- <menu_item_check label="Básico" name="BasicMode"/>
- <menu_item_check label="Avanzado" name="AdvancedMode"/>
-</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/es/menu_model_import_gear_default.xml b/indra/newview/skins/default/xui/es/menu_model_import_gear_default.xml
index 0d4f1314c9..0d4f1314c9 100644..100755
--- a/indra/newview/skins/default/xui/es/menu_model_import_gear_default.xml
+++ b/indra/newview/skins/default/xui/es/menu_model_import_gear_default.xml
diff --git a/indra/newview/skins/default/xui/es/menu_mute_particle.xml b/indra/newview/skins/default/xui/es/menu_mute_particle.xml
new file mode 100644
index 0000000000..daddf982de
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/menu_mute_particle.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<!-- *NOTE: See also menu_attachment_other.xml -->
+<context_menu name="Mute Particle Pie">
+ <menu_item_call label="Ignorar al propietario de la partícula" name="Mute Particle"/>
+</context_menu>
diff --git a/indra/newview/skins/default/xui/es/menu_navbar.xml b/indra/newview/skins/default/xui/es/menu_navbar.xml
index 63e5468020..63e5468020 100644..100755
--- a/indra/newview/skins/default/xui/es/menu_navbar.xml
+++ b/indra/newview/skins/default/xui/es/menu_navbar.xml
diff --git a/indra/newview/skins/default/xui/es/menu_nearby_chat.xml b/indra/newview/skins/default/xui/es/menu_nearby_chat.xml
index 94b281b6c7..94b281b6c7 100644..100755
--- a/indra/newview/skins/default/xui/es/menu_nearby_chat.xml
+++ b/indra/newview/skins/default/xui/es/menu_nearby_chat.xml
diff --git a/indra/newview/skins/default/xui/es/menu_notification_well_button.xml b/indra/newview/skins/default/xui/es/menu_notification_well_button.xml
index 0562d35be7..0562d35be7 100644..100755
--- a/indra/newview/skins/default/xui/es/menu_notification_well_button.xml
+++ b/indra/newview/skins/default/xui/es/menu_notification_well_button.xml
diff --git a/indra/newview/skins/default/xui/es/menu_object.xml b/indra/newview/skins/default/xui/es/menu_object.xml
index d8c75eaf47..e75c7283af 100644..100755
--- a/indra/newview/skins/default/xui/es/menu_object.xml
+++ b/indra/newview/skins/default/xui/es/menu_object.xml
@@ -10,6 +10,8 @@
<menu_item_call label="Levantarme" name="Object Stand Up"/>
<menu_item_call label="Perfil del objeto" name="Object Inspect"/>
<menu_item_call label="Acercar el zoom" name="Zoom In"/>
+ <menu_item_call label="Mostrar en linksets" name="show_in_linksets"/>
+ <menu_item_call label="Mostrar en personajes" name="show_in_characters"/>
<context_menu label="Ponerme" name="Put On">
<menu_item_call label="Ponerme" name="Wear"/>
<menu_item_call label="Añadir" name="Add"/>
@@ -26,4 +28,5 @@
<menu_item_call label="Pagar" name="Pay..."/>
<menu_item_call label="Comprar" name="Buy..."/>
<menu_item_call label="Borrar" name="Delete"/>
+ <menu_item_call label="Ignorar al propietario de la partícula" name="Mute Particle"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/es/menu_object_icon.xml b/indra/newview/skins/default/xui/es/menu_object_icon.xml
index 7e4578b950..a99c889bb0 100644..100755
--- a/indra/newview/skins/default/xui/es/menu_object_icon.xml
+++ b/indra/newview/skins/default/xui/es/menu_object_icon.xml
@@ -2,4 +2,6 @@
<menu name="Object Icon Menu">
<menu_item_call label="Perfil del objeto..." name="Object Profile"/>
<menu_item_call label="Ignorar..." name="Block"/>
+ <menu_item_call label="Mostrar en el mapa" name="show_on_map"/>
+ <menu_item_call label="Teleportarse a la posición del objeto" name="teleport_to_object"/>
</menu>
diff --git a/indra/newview/skins/default/xui/es/menu_outfit_gear.xml b/indra/newview/skins/default/xui/es/menu_outfit_gear.xml
index 558ff6afd3..56e64c729f 100644..100755
--- a/indra/newview/skins/default/xui/es/menu_outfit_gear.xml
+++ b/indra/newview/skins/default/xui/es/menu_outfit_gear.xml
@@ -23,6 +23,8 @@
<menu_item_call label="Pelo nuevo" name="New Hair"/>
<menu_item_call label="Ojos nuevos" name="New Eyes"/>
</menu>
+ <menu_item_call label="Abrir todas las carpetas" name="expand"/>
+ <menu_item_call label="Cerrar todas las carpetas" name="collapse"/>
<menu_item_call label="Renombrar el vestuario" name="rename"/>
<menu_item_call label="Borrar el vestuario" name="delete_outfit"/>
</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/es/menu_outfit_tab.xml b/indra/newview/skins/default/xui/es/menu_outfit_tab.xml
index 4136082a62..4136082a62 100644..100755
--- a/indra/newview/skins/default/xui/es/menu_outfit_tab.xml
+++ b/indra/newview/skins/default/xui/es/menu_outfit_tab.xml
diff --git a/indra/newview/skins/default/xui/es/menu_participant_list.xml b/indra/newview/skins/default/xui/es/menu_participant_list.xml
index f6eedd1170..f6eedd1170 100644..100755
--- a/indra/newview/skins/default/xui/es/menu_participant_list.xml
+++ b/indra/newview/skins/default/xui/es/menu_participant_list.xml
diff --git a/indra/newview/skins/default/xui/es/menu_participant_view.xml b/indra/newview/skins/default/xui/es/menu_participant_view.xml
new file mode 100644
index 0000000000..fcfeeb922b
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/menu_participant_view.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="participant_manu_view">
+ <menu_item_check label="Ordenar las conversaciones por tipo" name="sort_sessions_by_type"/>
+ <menu_item_check label="Ordenar las conversaciones por nombre" name="sort_sessions_by_name"/>
+ <menu_item_check label="Ordenar las conversaciones por actividad reciente" name="sort_sessions_by_recent"/>
+ <menu_item_check label="Ordenar los participantes por nombre" name="sort_participants_by_name"/>
+ <menu_item_check label="Ordenar los participantes por actividad reciente" name="sort_participants_by_recent"/>
+ <menu_item_call label="Preferencias de chat..." name="chat_preferences"/>
+ <menu_item_call label="Preferencias de privacidad..." name="privacy_preferences"/>
+ <menu_item_check label="Registro de conversaciones..." name="Conversation"/>
+ <menu_item_check label="Traducir el chat" name="Translate_chat"/>
+ <menu_item_check label="Configuración de traducción..." name="Translation_settings"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/es/menu_people_blocked_gear.xml b/indra/newview/skins/default/xui/es/menu_people_blocked_gear.xml
new file mode 100644
index 0000000000..986389a4fe
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/menu_people_blocked_gear.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_blocked_gear">
+ <menu_item_call label="No ignorar" name="unblock"/>
+ <menu_item_call label="Perfil..." name="profile"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/es/menu_people_blocked_plus.xml b/indra/newview/skins/default/xui/es/menu_people_blocked_plus.xml
new file mode 100644
index 0000000000..10f6a3fc14
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/menu_people_blocked_plus.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_blocked_plus">
+ <menu_item_call label="Ignorar residentes según el nombre..." name="block_resident_by_name"/>
+ <menu_item_call label="Ignorar objetos según el nombre" name="block_object_by_name"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/es/menu_people_blocked_view.xml b/indra/newview/skins/default/xui/es/menu_people_blocked_view.xml
new file mode 100644
index 0000000000..bc557c7ec1
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/menu_people_blocked_view.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_blocked_view">
+ <menu_item_check label="Ordenar alfabéticamente" name="sort_by_name"/>
+ <menu_item_check label="Ordenar por tipo" name="sort_by_type"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/es/menu_people_friends_view.xml b/indra/newview/skins/default/xui/es/menu_people_friends_view.xml
new file mode 100644
index 0000000000..ad896c1b74
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/menu_people_friends_view.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_group_plus">
+ <menu_item_check label="Ordenar alfabéticamente" name="sort_name"/>
+ <menu_item_check label="Ordenar por estatus" name="sort_status"/>
+ <menu_item_check label="Ver los iconos de la gente" name="view_icons"/>
+ <menu_item_check label="Ver permisos concedidos" name="view_permissions"/>
+ <menu_item_check label="Ver el registro de conversaciones..." name="view_conversation"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/es/menu_people_friends_view_sort.xml b/indra/newview/skins/default/xui/es/menu_people_friends_view_sort.xml
index 3899ad9e96..3899ad9e96 100644..100755
--- a/indra/newview/skins/default/xui/es/menu_people_friends_view_sort.xml
+++ b/indra/newview/skins/default/xui/es/menu_people_friends_view_sort.xml
diff --git a/indra/newview/skins/default/xui/es/menu_people_groups.xml b/indra/newview/skins/default/xui/es/menu_people_groups.xml
index 51bd2c7208..125e25cd1a 100644..100755
--- a/indra/newview/skins/default/xui/es/menu_people_groups.xml
+++ b/indra/newview/skins/default/xui/es/menu_people_groups.xml
@@ -2,7 +2,7 @@
<menu name="menu_group_plus">
<menu_item_call label="Ver la información" name="View Info"/>
<menu_item_call label="Chat" name="Chat"/>
- <menu_item_call label="Llamar" name="Call"/>
+ <menu_item_call label="Llamada de voz" name="Call"/>
<menu_item_call label="Activar" name="Activate"/>
<menu_item_call label="Dejar" name="Leave"/>
</menu>
diff --git a/indra/newview/skins/default/xui/es/menu_people_groups_view.xml b/indra/newview/skins/default/xui/es/menu_people_groups_view.xml
new file mode 100644
index 0000000000..c3973625b0
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/menu_people_groups_view.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_group_plus">
+ <menu_item_check label="Mostrar los iconos de grupo" name="Display Group Icons"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/es/menu_people_groups_view_sort.xml b/indra/newview/skins/default/xui/es/menu_people_groups_view_sort.xml
index 1bd3efb611..1bd3efb611 100644..100755
--- a/indra/newview/skins/default/xui/es/menu_people_groups_view_sort.xml
+++ b/indra/newview/skins/default/xui/es/menu_people_groups_view_sort.xml
diff --git a/indra/newview/skins/default/xui/es/menu_people_nearby.xml b/indra/newview/skins/default/xui/es/menu_people_nearby.xml
index dc1486d879..09bb119d5a 100644..100755
--- a/indra/newview/skins/default/xui/es/menu_people_nearby.xml
+++ b/indra/newview/skins/default/xui/es/menu_people_nearby.xml
@@ -1,13 +1,16 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Avatar Context Menu">
- <menu_item_call label="Ver el perfil" name="View Profile"/>
- <menu_item_call label="Añadir como amigo" name="Add Friend"/>
- <menu_item_call label="Quitarle como amigo" name="Remove Friend"/>
- <menu_item_call label="MI" name="IM"/>
- <menu_item_call label="Llamar" name="Call"/>
- <menu_item_call label="Mapa" name="Map"/>
- <menu_item_call label="Compartir" name="Share"/>
- <menu_item_call label="Pagar" name="Pay"/>
- <menu_item_check label="Ignorar / No ignorar" name="Block/Unblock"/>
- <menu_item_call label="Ofrecer teleporte" name="teleport"/>
+ <menu_item_call label="Ver el perfil" name="view_profile"/>
+ <menu_item_call label="MI" name="im"/>
+ <menu_item_call label="Ofrecer teleporte" name="offer_teleport"/>
+ <menu_item_call label="Llamada de voz" name="voice_call"/>
+ <menu_item_call label="Ver el historial de chat..." name="chat_history"/>
+ <menu_item_call label="Añadir como amigo" name="add_friend"/>
+ <menu_item_call label="Quitarle como amigo" name="remove_friend"/>
+ <menu_item_call label="Invitar al grupo..." name="invite_to_group"/>
+ <menu_item_call label="Acercar el zoom" name="zoom_in"/>
+ <menu_item_call label="Mapa" name="map"/>
+ <menu_item_call label="Compartir" name="share"/>
+ <menu_item_call label="Pagar" name="pay"/>
+ <menu_item_check label="Ignorar / No ignorar" name="block_unblock"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/es/menu_people_nearby_multiselect.xml b/indra/newview/skins/default/xui/es/menu_people_nearby_multiselect.xml
index 227c5ebe58..9df160f5ad 100644..100755
--- a/indra/newview/skins/default/xui/es/menu_people_nearby_multiselect.xml
+++ b/indra/newview/skins/default/xui/es/menu_people_nearby_multiselect.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Multi-Selected People Context Menu">
- <menu_item_call label="Añadir como amigos" name="Add Friends"/>
- <menu_item_call label="Quitar amigos" name="Remove Friend"/>
- <menu_item_call label="MI" name="IM"/>
- <menu_item_call label="Llamar" name="Call"/>
- <menu_item_call label="Compartir" name="Share"/>
- <menu_item_call label="Pagar" name="Pay"/>
- <menu_item_call label="Ofrecer teleporte" name="teleport"/>
+ <menu_item_call label="Añadir como amigos" name="add_friends"/>
+ <menu_item_call label="Quitar amigos" name="remove_friends"/>
+ <menu_item_call label="MI" name="im"/>
+ <menu_item_call label="Visita" name="call"/>
+ <menu_item_call label="Compartir" name="share"/>
+ <menu_item_call label="Pagar" name="pay"/>
+ <menu_item_call label="Ofrecer teleporte" name="offer_teleport"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/es/menu_people_nearby_view.xml b/indra/newview/skins/default/xui/es/menu_people_nearby_view.xml
new file mode 100644
index 0000000000..c2fb360dd1
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/menu_people_nearby_view.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_group_plus">
+ <menu_item_check label="Ordenar según las intervenciones recientes" name="sort_by_recent_speakers"/>
+ <menu_item_check label="Ordenar alfabéticamente" name="sort_name"/>
+ <menu_item_check label="Ordenar según distancia" name="sort_distance"/>
+ <menu_item_check label="Ver los iconos de la gente" name="view_icons"/>
+ <menu_item_check label="Ver mapa" name="view_map"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/es/menu_people_nearby_view_sort.xml b/indra/newview/skins/default/xui/es/menu_people_nearby_view_sort.xml
index 1403e4db01..1403e4db01 100644..100755
--- a/indra/newview/skins/default/xui/es/menu_people_nearby_view_sort.xml
+++ b/indra/newview/skins/default/xui/es/menu_people_nearby_view_sort.xml
diff --git a/indra/newview/skins/default/xui/es/menu_people_recent_view.xml b/indra/newview/skins/default/xui/es/menu_people_recent_view.xml
new file mode 100644
index 0000000000..f0ffd14024
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/menu_people_recent_view.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_group_plus">
+ <menu_item_check label="Ordenar por más reciente" name="sort_most"/>
+ <menu_item_check label="Ordenar alfabéticamente" name="sort_name"/>
+ <menu_item_check label="Ver los iconos de la gente" name="view_icons"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/es/menu_people_recent_view_sort.xml b/indra/newview/skins/default/xui/es/menu_people_recent_view_sort.xml
index e4aaa89110..e4aaa89110 100644..100755
--- a/indra/newview/skins/default/xui/es/menu_people_recent_view_sort.xml
+++ b/indra/newview/skins/default/xui/es/menu_people_recent_view_sort.xml
diff --git a/indra/newview/skins/default/xui/es/menu_picks.xml b/indra/newview/skins/default/xui/es/menu_picks.xml
index 9da68d7c9b..9da68d7c9b 100644..100755
--- a/indra/newview/skins/default/xui/es/menu_picks.xml
+++ b/indra/newview/skins/default/xui/es/menu_picks.xml
diff --git a/indra/newview/skins/default/xui/es/menu_picks_plus.xml b/indra/newview/skins/default/xui/es/menu_picks_plus.xml
index cc59bf1d29..cc59bf1d29 100644..100755
--- a/indra/newview/skins/default/xui/es/menu_picks_plus.xml
+++ b/indra/newview/skins/default/xui/es/menu_picks_plus.xml
diff --git a/indra/newview/skins/default/xui/es/menu_place.xml b/indra/newview/skins/default/xui/es/menu_place.xml
index 675f0699e9..675f0699e9 100644..100755
--- a/indra/newview/skins/default/xui/es/menu_place.xml
+++ b/indra/newview/skins/default/xui/es/menu_place.xml
diff --git a/indra/newview/skins/default/xui/es/menu_place_add_button.xml b/indra/newview/skins/default/xui/es/menu_place_add_button.xml
index 4b2f908a06..4b2f908a06 100644..100755
--- a/indra/newview/skins/default/xui/es/menu_place_add_button.xml
+++ b/indra/newview/skins/default/xui/es/menu_place_add_button.xml
diff --git a/indra/newview/skins/default/xui/es/menu_places_gear_folder.xml b/indra/newview/skins/default/xui/es/menu_places_gear_folder.xml
index 4051ff4075..4051ff4075 100644..100755
--- a/indra/newview/skins/default/xui/es/menu_places_gear_folder.xml
+++ b/indra/newview/skins/default/xui/es/menu_places_gear_folder.xml
diff --git a/indra/newview/skins/default/xui/es/menu_places_gear_landmark.xml b/indra/newview/skins/default/xui/es/menu_places_gear_landmark.xml
index c92bd19787..c92bd19787 100644..100755
--- a/indra/newview/skins/default/xui/es/menu_places_gear_landmark.xml
+++ b/indra/newview/skins/default/xui/es/menu_places_gear_landmark.xml
diff --git a/indra/newview/skins/default/xui/es/menu_profile_overflow.xml b/indra/newview/skins/default/xui/es/menu_profile_overflow.xml
index 5ee8c50949..5ee8c50949 100644..100755
--- a/indra/newview/skins/default/xui/es/menu_profile_overflow.xml
+++ b/indra/newview/skins/default/xui/es/menu_profile_overflow.xml
diff --git a/indra/newview/skins/default/xui/es/menu_save_outfit.xml b/indra/newview/skins/default/xui/es/menu_save_outfit.xml
index a04ec75b60..a04ec75b60 100644..100755
--- a/indra/newview/skins/default/xui/es/menu_save_outfit.xml
+++ b/indra/newview/skins/default/xui/es/menu_save_outfit.xml
diff --git a/indra/newview/skins/default/xui/es/menu_script_chiclet.xml b/indra/newview/skins/default/xui/es/menu_script_chiclet.xml
index f517baf566..f517baf566 100644..100755
--- a/indra/newview/skins/default/xui/es/menu_script_chiclet.xml
+++ b/indra/newview/skins/default/xui/es/menu_script_chiclet.xml
diff --git a/indra/newview/skins/default/xui/es/menu_slurl.xml b/indra/newview/skins/default/xui/es/menu_slurl.xml
index ca19acec6e..ca19acec6e 100644..100755
--- a/indra/newview/skins/default/xui/es/menu_slurl.xml
+++ b/indra/newview/skins/default/xui/es/menu_slurl.xml
diff --git a/indra/newview/skins/default/xui/es/menu_teleport_history_gear.xml b/indra/newview/skins/default/xui/es/menu_teleport_history_gear.xml
index b708f3bc20..b708f3bc20 100644..100755
--- a/indra/newview/skins/default/xui/es/menu_teleport_history_gear.xml
+++ b/indra/newview/skins/default/xui/es/menu_teleport_history_gear.xml
diff --git a/indra/newview/skins/default/xui/es/menu_teleport_history_item.xml b/indra/newview/skins/default/xui/es/menu_teleport_history_item.xml
index c482907812..c482907812 100644..100755
--- a/indra/newview/skins/default/xui/es/menu_teleport_history_item.xml
+++ b/indra/newview/skins/default/xui/es/menu_teleport_history_item.xml
diff --git a/indra/newview/skins/default/xui/es/menu_teleport_history_tab.xml b/indra/newview/skins/default/xui/es/menu_teleport_history_tab.xml
index 17e90422a5..17e90422a5 100644..100755
--- a/indra/newview/skins/default/xui/es/menu_teleport_history_tab.xml
+++ b/indra/newview/skins/default/xui/es/menu_teleport_history_tab.xml
diff --git a/indra/newview/skins/default/xui/es/menu_text_editor.xml b/indra/newview/skins/default/xui/es/menu_text_editor.xml
index 095e461734..6253463725 100644..100755
--- a/indra/newview/skins/default/xui/es/menu_text_editor.xml
+++ b/indra/newview/skins/default/xui/es/menu_text_editor.xml
@@ -1,5 +1,12 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Text editor context menu">
+ <menu_item_call label="(desconocido)" name="Suggestion 1"/>
+ <menu_item_call label="(desconocido)" name="Suggestion 2"/>
+ <menu_item_call label="(desconocido)" name="Suggestion 3"/>
+ <menu_item_call label="(desconocido)" name="Suggestion 4"/>
+ <menu_item_call label="(desconocido)" name="Suggestion 5"/>
+ <menu_item_call label="Añadir al diccionario" name="Add to Dictionary"/>
+ <menu_item_call label="Añadir a ignorados" name="Add to Ignore"/>
<menu_item_call label="Cortar" name="Cut"/>
<menu_item_call label="Copiar" name="Copy"/>
<menu_item_call label="Pegar" name="Paste"/>
diff --git a/indra/newview/skins/default/xui/es/menu_toolbars.xml b/indra/newview/skins/default/xui/es/menu_toolbars.xml
index 63f3dc43bd..63f3dc43bd 100644..100755
--- a/indra/newview/skins/default/xui/es/menu_toolbars.xml
+++ b/indra/newview/skins/default/xui/es/menu_toolbars.xml
diff --git a/indra/newview/skins/default/xui/es/menu_topinfobar.xml b/indra/newview/skins/default/xui/es/menu_topinfobar.xml
index 2125fd51b2..2125fd51b2 100644..100755
--- a/indra/newview/skins/default/xui/es/menu_topinfobar.xml
+++ b/indra/newview/skins/default/xui/es/menu_topinfobar.xml
diff --git a/indra/newview/skins/default/xui/es/menu_url_agent.xml b/indra/newview/skins/default/xui/es/menu_url_agent.xml
index a089c8f68e..610d65465d 100644..100755
--- a/indra/newview/skins/default/xui/es/menu_url_agent.xml
+++ b/indra/newview/skins/default/xui/es/menu_url_agent.xml
@@ -1,6 +1,9 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Url Popup">
- <menu_item_call label="Mostrar el perfil del Residente" name="show_agent"/>
+ <menu_item_call label="Ver el perfil" name="show_agent"/>
+ <menu_item_call label="Enviar un MI..." name="send_im"/>
+ <menu_item_call label="Añadir como amigo..." name="add_friend"/>
+ <menu_item_call label="Quitar de los amigos..." name="remove_friend"/>
<menu_item_call label="Copiar el nombre al portapapeles" name="url_copy_label"/>
<menu_item_call label="Copiar la SLurl al portapapeles" name="url_copy"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/es/menu_url_group.xml b/indra/newview/skins/default/xui/es/menu_url_group.xml
index 79374b9739..79374b9739 100644..100755
--- a/indra/newview/skins/default/xui/es/menu_url_group.xml
+++ b/indra/newview/skins/default/xui/es/menu_url_group.xml
diff --git a/indra/newview/skins/default/xui/es/menu_url_http.xml b/indra/newview/skins/default/xui/es/menu_url_http.xml
index 585c059ff3..585c059ff3 100644..100755
--- a/indra/newview/skins/default/xui/es/menu_url_http.xml
+++ b/indra/newview/skins/default/xui/es/menu_url_http.xml
diff --git a/indra/newview/skins/default/xui/es/menu_url_inventory.xml b/indra/newview/skins/default/xui/es/menu_url_inventory.xml
index 13a8711c76..13a8711c76 100644..100755
--- a/indra/newview/skins/default/xui/es/menu_url_inventory.xml
+++ b/indra/newview/skins/default/xui/es/menu_url_inventory.xml
diff --git a/indra/newview/skins/default/xui/es/menu_url_map.xml b/indra/newview/skins/default/xui/es/menu_url_map.xml
index f96a0c7170..f96a0c7170 100644..100755
--- a/indra/newview/skins/default/xui/es/menu_url_map.xml
+++ b/indra/newview/skins/default/xui/es/menu_url_map.xml
diff --git a/indra/newview/skins/default/xui/es/menu_url_objectim.xml b/indra/newview/skins/default/xui/es/menu_url_objectim.xml
index 8791a290af..c3c8439ea2 100644..100755
--- a/indra/newview/skins/default/xui/es/menu_url_objectim.xml
+++ b/indra/newview/skins/default/xui/es/menu_url_objectim.xml
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Url Popup">
- <menu_item_call label="Mostrar la información del objeto" name="show_object"/>
+ <menu_item_call label="Perfil del objeto..." name="show_object"/>
+ <menu_item_call label="Ignorar..." name="block_object"/>
<menu_item_call label="Mostrar en el mapa" name="show_on_map"/>
<menu_item_call label="Teleportarse a la posición del objeto" name="teleport_to_object"/>
<menu_item_call label="Copiar el nombre del objeto al portapapeles" name="url_copy_label"/>
diff --git a/indra/newview/skins/default/xui/es/menu_url_parcel.xml b/indra/newview/skins/default/xui/es/menu_url_parcel.xml
index 9e789ef8ee..9e789ef8ee 100644..100755
--- a/indra/newview/skins/default/xui/es/menu_url_parcel.xml
+++ b/indra/newview/skins/default/xui/es/menu_url_parcel.xml
diff --git a/indra/newview/skins/default/xui/es/menu_url_slapp.xml b/indra/newview/skins/default/xui/es/menu_url_slapp.xml
index 7147dcd3cf..7147dcd3cf 100644..100755
--- a/indra/newview/skins/default/xui/es/menu_url_slapp.xml
+++ b/indra/newview/skins/default/xui/es/menu_url_slapp.xml
diff --git a/indra/newview/skins/default/xui/es/menu_url_slurl.xml b/indra/newview/skins/default/xui/es/menu_url_slurl.xml
index 4ab47c2f61..4ab47c2f61 100644..100755
--- a/indra/newview/skins/default/xui/es/menu_url_slurl.xml
+++ b/indra/newview/skins/default/xui/es/menu_url_slurl.xml
diff --git a/indra/newview/skins/default/xui/es/menu_url_teleport.xml b/indra/newview/skins/default/xui/es/menu_url_teleport.xml
index 8f86a91be3..8f86a91be3 100644..100755
--- a/indra/newview/skins/default/xui/es/menu_url_teleport.xml
+++ b/indra/newview/skins/default/xui/es/menu_url_teleport.xml
diff --git a/indra/newview/skins/default/xui/es/menu_viewer.xml b/indra/newview/skins/default/xui/es/menu_viewer.xml
index 9522d4eac6..e4fe871683 100644..100755
--- a/indra/newview/skins/default/xui/es/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/es/menu_viewer.xml
@@ -17,8 +17,8 @@
<menu_item_call label="Caminar / Correr / Volar..." name="Walk / run / fly"/>
</menu>
<menu label="Estado" name="Status">
- <menu_item_call label="Ausente" name="Set Away"/>
- <menu_item_call label="Ocupado" name="Set Busy"/>
+ <menu_item_check label="Ausente" name="Away"/>
+ <menu_item_check label="No molestar" name="Do Not Disturb"/>
</menu>
<menu_item_call label="Comprar L$..." name="Buy and Sell L$"/>
<menu_item_call label="Panel de control de la cuenta..." name="Manage My Account">
@@ -27,17 +27,25 @@
<menu_item_call label="Preferencias..." name="Preferences"/>
<menu_item_call label="Botones de la barra de herramientas..." name="Toolbars"/>
<menu_item_call label="Ocultar todos los controles" name="Hide UI"/>
+ <menu_item_check label="Mostrar los HUD anexados" name="Show HUD Attachments"/>
<menu_item_call label="Salir de [APP_NAME]" name="Quit"/>
</menu>
<menu label="Comunicarme" name="Communicate">
+ <menu_item_check label="Conversaciones..." name="Conversations"/>
<menu_item_check label="Chat..." name="Nearby Chat"/>
<menu_item_check label="Hablar" name="Speak"/>
- <menu_item_check label="Configuración de voz..." name="Nearby Voice"/>
- <menu_item_check label="Transformación de voz..." name="ShowVoice"/>
+ <menu_item_check label="Registro de conversación..." name="Conversation Log..."/>
+ <menu label="Transformación de voz" name="VoiceMorphing">
+ <menu_item_check label="Sin transformación de voz" name="NoVoiceMorphing"/>
+ <menu_item_check label="Probar..." name="Preview"/>
+ <menu_item_call label="Suscribir..." name="Subscribe"/>
+ </menu>
<menu_item_check label="Gestos..." name="Gestures"/>
- <menu_item_call label="Amigos" name="My Friends"/>
- <menu_item_call label="Grupos" name="My Groups"/>
- <menu_item_call label="Gente cerca" name="Active Speakers"/>
+ <menu_item_check label="Amigos" name="My Friends"/>
+ <menu_item_check label="Grupos" name="My Groups"/>
+ <menu_item_check label="Gente cerca" name="Active Speakers"/>
+ <menu_item_call label="Lista de ignorados" name="Block List"/>
+ <menu_item_check label="No molestar" name="Do Not Disturb"/>
</menu>
<menu label="Mundo" name="World">
<menu_item_call label="Crear un hito de este sitio" name="Create Landmark Here"/>
@@ -106,13 +114,13 @@
<menu_item_call label="Incluir la parte siguiente" name="Include Next Part"/>
<menu_item_call label="Incluir la parte previa" name="Include Previous Part"/>
</menu>
+ <menu_item_call label="Linksets..." name="pathfinding_linkset_menu_item"/>
<menu_item_call label="Visión en lo seleccionado" name="Focus on Selection"/>
<menu_item_call label="Zoom en lo seleccionado" name="Zoom to Selection"/>
<menu label="Objeto" name="Object">
<menu_item_call label="Comprar" name="Menu Object Buy"/>
<menu_item_call label="Tomar" name="Menu Object Take"/>
<menu_item_call label="Coger una copia" name="Take Copy"/>
- <menu_item_call label="Guardar una copia en mi inventario" name="Save Object Back to My Inventory"/>
<menu_item_call label="Guardar una copia del objeto en los contenidos de donde salió" name="Save Object Back to Object Contents"/>
<menu_item_call label="Devolver objeto" name="Return Object back to Owner"/>
</menu>
@@ -123,6 +131,12 @@
<menu_item_call label="Definir los scripts a ejecutar" name="Set Scripts to Running"/>
<menu_item_call label="Configurar scripts como no ejecutándose" name="Set Scripts to Not Running"/>
</menu>
+ <menu label="Pathfinding" name="Pathfinding">
+ <menu_item_call label="Linksets..." name="pathfinding_linksets_menu_item"/>
+ <menu_item_call label="Personajes..." name="pathfinding_characters_menu_item"/>
+ <menu_item_call label="Ver/probar..." name="pathfinding_console_menu_item"/>
+ <menu_item_call label="Recargar la región" name="pathfinding_rebake_navmesh_item"/>
+ </menu>
<menu label="Opciones" name="Options">
<menu_item_check label="Mostrar los permisos avanzados" name="DebugPermissions"/>
<menu_item_check label="Seleccionar sólo mis objetos" name="Select Only My Objects"/>
@@ -151,6 +165,13 @@
<menu label="Ayuda" name="Help">
<menu_item_call label="Cómo..." name="How To"/>
<menu_item_call label="Ayuda de [SECOND_LIFE]" name="Second Life Help"/>
+ <menu_item_call label="Guía del usuario" name="User’s guide"/>
+ <menu_item_call label="Base de Conocimientos" name="Knowledge Base"/>
+ <menu_item_call label="Wiki" name="Wiki"/>
+ <menu_item_call label="Foros comunitarios" name="Community Forums"/>
+ <menu_item_call label="Portal de soporte" name="Support portal"/>
+ <menu_item_call label="Noticias de [SECOND_LIFE]" name="Second Life News"/>
+ <menu_item_call label="Blogs de [SECOND_LIFE]" name="Second Life Blogs"/>
<menu_item_call label="Denunciar una infracción" name="Report Abuse"/>
<menu_item_call label="Informar de un fallo" name="Report Bug"/>
<menu_item_call label="Acerca de [APP_NAME]" name="About Second Life"/>
@@ -173,7 +194,6 @@
<menu_item_check label="Ocultar las partículas" name="Hide Particles"/>
<menu_item_check label="Ocultar lo seleccionado" name="Hide Selected"/>
<menu_item_check label="Realzar las transparencias" name="Highlight Transparent"/>
- <menu_item_check label="Mostrar los HUD anexados" name="Show HUD Attachments"/>
<menu_item_check label="Mostrar el Punto de Mira en la vista subjetiva" name="ShowCrosshairs"/>
</menu>
<menu label="Objetos representados" name="Rendering Types">
@@ -225,11 +245,10 @@
<menu_item_check label="Texture Console" name="Texture Console"/>
<menu_item_check label="Debug Console" name="Debug Console"/>
<menu_item_call label="Notifications Console" name="Notifications"/>
- <menu_item_check label="Texture Size Console" name="Texture Size"/>
- <menu_item_check label="Texture Category Console" name="Texture Category"/>
<menu_item_check label="Fast Timers" name="Fast Timers"/>
<menu_item_check label="Memory" name="Memory"/>
<menu_item_check label="Datos de la escena" name="Scene Statistics"/>
+ <menu_item_call label="Consola de depuración de obtención de texturas" name="Texture Fetch Debug Console"/>
<menu_item_call label="Region Info to Debug Console" name="Region Info to Debug Console"/>
<menu_item_check label="Camera" name="Camera"/>
<menu_item_check label="Wind" name="Wind"/>
@@ -259,6 +278,7 @@
<menu_item_check label="Camera Offset" name="Camera Offset"/>
<menu_item_check label="Randomize Framerate" name="Randomize Framerate"/>
<menu_item_check label="Frame Test" name="Frame Test"/>
+ <menu_item_call label="Perfil del fotograma" name="Frame Profile"/>
</menu>
<menu label="Render Metadata" name="Render Metadata">
<menu_item_check label="Normales" name="Normals"/>
@@ -270,18 +290,24 @@
<menu_item_check label="Complejidad del renderizado" name="rendercomplexity"/>
<menu_item_check label="Bytes de adjunto" name="attachment bytes"/>
<menu_item_check label="Esculpir" name="Sculpt"/>
+ <menu label="Densidad de textura" name="Texture Density">
+ <menu_item_check label="Ninguna" name="None"/>
+ <menu_item_check label="Actual" name="Current"/>
+ <menu_item_check label="Deseada" name="Desired"/>
+ <menu_item_check label="Completa" name="Full"/>
+ </menu>
</menu>
<menu label="Rendering" name="Rendering">
<menu_item_check label="Axes" name="Axes"/>
+ <menu_item_call label="Información sobre el material seleccionado" name="Selected Material Info"/>
<menu_item_check label="Wireframe" name="Wireframe"/>
- <menu_item_check label="Luces y sombras" name="Lighting and Shadows"/>
+ <menu_item_check label="Modelo de iluminación avanzado" name="Advanced Lighting Model"/>
<menu_item_check label="Sombras del sol/la luna/proyectores" name="Shadows from Sun/Moon/Projectors"/>
<menu_item_check label="SSAO y sombras suavizadas" name="SSAO and Shadow Smoothing"/>
<menu_item_check label="Capas alfa automáticas (deferidas)" name="Automatic Alpha Masks (deferred)"/>
<menu_item_check label="Capas alfa automáticas (no deferidas)" name="Automatic Alpha Masks (non-deferred)"/>
<menu_item_check label="Animation Textures" name="Animation Textures"/>
<menu_item_check label="Disable Textures" name="Disable Textures"/>
- <menu_item_check label="Atlas de texturas (experimental)" name="Texture Atlas"/>
<menu_item_check label="Render Attached Lights" name="Render Attached Lights"/>
<menu_item_check label="Render Attached Particles" name="Render Attached Particles"/>
<menu_item_check label="Hover Glow Objects" name="Hover Glow Objects"/>
@@ -300,7 +326,6 @@
<menu_item_call label="Prueba de navegadores de medios" name="Web Browser Test"/>
<menu_item_call label="Navegador de contenido web" name="Web Content Browser"/>
<menu_item_call label="Print Selected Object Info" name="Print Selected Object Info"/>
- <menu_item_call label="Memory Stats" name="Memory Stats"/>
<menu_item_check label="Consola de depuración de región" name="Region Debug Console"/>
<menu_item_check label="Debug Clicks" name="Debug Clicks"/>
<menu_item_check label="Debug Mouse Events" name="Debug Mouse Events"/>
@@ -324,9 +349,14 @@
<menu_item_call label="Toggle Character Geometry" name="Toggle Character Geometry"/>
<menu_item_check label="Allow Select Avatar" name="Allow Select Avatar"/>
</menu>
+ <menu label="Velocidad de animación" name="Animation Speed">
+ <menu_item_call label="Acelerar todas las animaciones un 10%" name="All Animations 10 Faster"/>
+ <menu_item_call label="Ralentizar todas las animaciones un 10%" name="All Animations 10 Slower"/>
+ <menu_item_call label="Restablecer la velocidad de todas las animaciones" name="Reset All Animation Speed"/>
+ <menu_item_check label="Animaciones a cámara lenta" name="Slow Motion Animations"/>
+ </menu>
<menu_item_call label="Force Params to Default" name="Force Params to Default"/>
<menu_item_check label="Animation Info" name="Animation Info"/>
- <menu_item_check label="Slow Motion Animations" name="Slow Motion Animations"/>
<menu_item_check label="Disable Level Of Detail" name="Disable LOD"/>
<menu_item_check label="Show Collision Skeleton" name="Show Collision Skeleton"/>
<menu_item_check label="Display Agent Target" name="Display Agent Target"/>
diff --git a/indra/newview/skins/default/xui/es/menu_wearable_list_item.xml b/indra/newview/skins/default/xui/es/menu_wearable_list_item.xml
index 4bffa689e7..4bffa689e7 100644..100755
--- a/indra/newview/skins/default/xui/es/menu_wearable_list_item.xml
+++ b/indra/newview/skins/default/xui/es/menu_wearable_list_item.xml
diff --git a/indra/newview/skins/default/xui/es/menu_wearing_gear.xml b/indra/newview/skins/default/xui/es/menu_wearing_gear.xml
index ec13f99a01..ec13f99a01 100644..100755
--- a/indra/newview/skins/default/xui/es/menu_wearing_gear.xml
+++ b/indra/newview/skins/default/xui/es/menu_wearing_gear.xml
diff --git a/indra/newview/skins/default/xui/es/menu_wearing_tab.xml b/indra/newview/skins/default/xui/es/menu_wearing_tab.xml
index 64fd7ce4cf..64fd7ce4cf 100644..100755
--- a/indra/newview/skins/default/xui/es/menu_wearing_tab.xml
+++ b/indra/newview/skins/default/xui/es/menu_wearing_tab.xml
diff --git a/indra/newview/skins/default/xui/es/mime_types.xml b/indra/newview/skins/default/xui/es/mime_types.xml
index 85ff4cfb48..85ff4cfb48 100644..100755
--- a/indra/newview/skins/default/xui/es/mime_types.xml
+++ b/indra/newview/skins/default/xui/es/mime_types.xml
diff --git a/indra/newview/skins/default/xui/es/mime_types_linux.xml b/indra/newview/skins/default/xui/es/mime_types_linux.xml
index 77d05934f4..77d05934f4 100644..100755
--- a/indra/newview/skins/default/xui/es/mime_types_linux.xml
+++ b/indra/newview/skins/default/xui/es/mime_types_linux.xml
diff --git a/indra/newview/skins/default/xui/es/mime_types_mac.xml b/indra/newview/skins/default/xui/es/mime_types_mac.xml
index 77d05934f4..77d05934f4 100644..100755
--- a/indra/newview/skins/default/xui/es/mime_types_mac.xml
+++ b/indra/newview/skins/default/xui/es/mime_types_mac.xml
diff --git a/indra/newview/skins/default/xui/es/notifications.xml b/indra/newview/skins/default/xui/es/notifications.xml
index d47c3d7ad8..d4451ad251 100644..100755
--- a/indra/newview/skins/default/xui/es/notifications.xml
+++ b/indra/newview/skins/default/xui/es/notifications.xml
@@ -37,6 +37,12 @@
<button name="Help" text="$helptext"/>
</form>
</template>
+ <template name="okhelpignore">
+ <form>
+ <button name="OK_okhelpignore" text="$yestext"/>
+ <button name="Help_okhelpignore" text="$helptext"/>
+ </form>
+ </template>
<template name="yesnocancelbuttons">
<form>
<button name="Yes" text="$yestext"/>
@@ -200,6 +206,14 @@ No podrás removérseles de ese rol, sino que deberán renunciar a él por sí m
¿Añadir esta capacidad a &apos;[ROLE_NAME]&apos;?
<usetemplate name="okcancelbuttons" notext="No" yestext="Sí"/>
</notification>
+ <notification name="EjectGroupMemberWarning">
+ Estás a punto de expulsar a [AVATAR_NAME] del grupo.
+ <usetemplate ignoretext="Confirmar la expulsión de un miembro del grupo" name="okcancelignore" notext="Cancelar" yestext="Expulsar"/>
+ </notification>
+ <notification name="EjectGroupMembersWarning">
+ Estás a punto de expulsar a [COUNT] miembros del grupo.
+ <usetemplate ignoretext="Confirmar la expulsión de varios miembros del grupo" name="okcancelignore" notext="Cancelar" yestext="Expulsar"/>
+ </notification>
<notification name="AttachmentDrop">
Vas a soltar tu anexado.
¿Estás seguro de que quieres continuar?
@@ -357,13 +371,19 @@ Tienes que volver a introducir el nombre de usuario de tu avatar.
Necesitas una cuenta para acceder a [SECOND_LIFE]. ¿Te gustaría crear una ahora?
<url name="url">
- https://join.secondlife.com/index.php?lang=es-ES
+ [create_account_url]
</url>
<usetemplate name="okcancelbuttons" notext="Volver a intentarlo" yestext="Crear una cuenta nueva"/>
</notification>
<notification name="InvalidCredentialFormat">
Escribe el nombre de usuario o el nombre y el apellido de tu avatar en el campo Nombre de usuario e inicia sesión otra vez.
</notification>
+ <notification name="InvalidGrid">
+ &apos;[GRID]&apos; no es un identificador de cuadrícula válido.
+ </notification>
+ <notification name="InvalidLocationSLURL">
+ Tu localización inicial no especifica una cuadrícula válida.
+ </notification>
<notification name="DeleteClassified">
¿Borrar el clasificado &apos;[NAME]&apos;?
No se reembolsan las cuotas pagadas.
@@ -467,8 +487,8 @@ El objeto debe de haber sido borrado o estar fuera de rango (&apos;out of range&
Al guardar un script compilado, hubo un problema por: [REASON]. Por favor, vuelve a intentar guardarlo más tarde..
</notification>
<notification name="StartRegionEmpty">
- Perdón, no está definida tu Posición inicial.
-Por favor, escribe el nombre de la región en el cajetín de Posición inicial, o elige para esa posición Mi Base o Mi última posición.
+ No está definida tu región inicial.
+Por favor, escribe el nombre de la región en el cuadro de Posición inicial o elige para esa posición Mi Base o Mi última posición.
<usetemplate name="okbutton" yestext="OK"/>
</notification>
<notification name="CouldNotStartStopScript">
@@ -490,6 +510,33 @@ El objeto debe de haber sido borrado o estar fuera de rango (&apos;out of range&
</url>
<usetemplate ignoretext="El hardware de mi ordenador no está admitido" name="okcancelignore" notext="No" yestext="Sí"/>
</notification>
+ <notification name="IntelOldDriver">
+ Probablemente ya existe un controlador más reciente para tu procesador de gráficos. La actualización del controlador de gráficos puede mejorar sustancialmente el rendimiento.
+
+ ¿Deseas visitar [_URL] para comprobar si hay controladores actualizados?
+ <url name="url">
+ http://www.intel.com/p/es_XL/support/detect/graphics
+ </url>
+ <usetemplate ignoretext="Mi controlador de gráficos no está actualizado" name="okcancelignore" notext="No" yestext="Sí"/>
+ </notification>
+ <notification name="AMDOldDriver">
+ Probablemente ya existe un controlador más reciente para tu procesador de gráficos. La actualización del controlador de gráficos puede mejorar sustancialmente el rendimiento.
+
+ ¿Deseas visitar [_URL] para comprobar si hay controladores actualizados?
+ <url name="url">
+ http://support.amd.com/us/Pages/AMDSupportHub.aspx
+ </url>
+ <usetemplate ignoretext="Mi controlador de gráficos no está actualizado" name="okcancelignore" notext="No" yestext="Sí"/>
+ </notification>
+ <notification name="NVIDIAOldDriver">
+ Probablemente ya existe un controlador más reciente para tu procesador de gráficos. La actualización del controlador de gráficos puede mejorar sustancialmente el rendimiento.
+
+ ¿Deseas visitar [_URL] para comprobar si hay controladores actualizados?
+ <url name="url">
+ http://www.nvidia.com/Download/index.aspx?lang=es
+ </url>
+ <usetemplate ignoretext="Mi controlador de gráficos no está actualizado" name="okcancelignore" notext="No" yestext="Sí"/>
+ </notification>
<notification name="UnknownGPU">
Tu sistema usa una tarjeta gráfica que [APP_NAME] no reconoce.
Suele suceder con hardware nuevo que todavía no ha sido probado con [APP_NAME]. Probablemente todo irá bien, pero deberás ajustar tus configuraciones gráficas.
@@ -590,6 +637,9 @@ todos los objetos.
Por favor, asegúrate de que no hay ninguno bloqueado, y de que eres el propietario de todos.
</notification>
+ <notification name="CannotLinkPermanent">
+ No se pueden vincular objetos a través de límites de región.
+ </notification>
<notification name="CannotLinkDifferentOwners">
Imposible enlazarlos, porque hay objetos de distintos propietarios.
@@ -971,6 +1021,41 @@ no tienes el permiso de comprar terreno para el grupo que tienes activado actual
<button name="Cancel" text="Cancelar"/>
</form>
</notification>
+ <notification label="Añadir lista de reemplazo automático" name="AddAutoReplaceList">
+ Nombre de la nueva lista:
+ <form name="form">
+ <button name="SetName" text="OK"/>
+ </form>
+ </notification>
+ <notification label="Cambiar nombre de la lista de reemplazo automático" name="RenameAutoReplaceList">
+ El nombre &apos;[DUPNAME]&apos; ya se está utilizando.
+ Escribe un nombre nuevo que sea único:
+ <form name="form">
+ <button name="ReplaceList" text="Reemplazar la lista actual"/>
+ <button name="SetName" text="Usar un nombre nuevo"/>
+ </form>
+ </notification>
+ <notification name="InvalidAutoReplaceEntry">
+ La palabra clave debe ser una palabra única y el reemplazo no puede estar vacío.
+ </notification>
+ <notification name="InvalidAutoReplaceList">
+ La lista de reemplazo no es válida.
+ </notification>
+ <notification name="SpellingDictImportRequired">
+ Debes especificar un archivo, un nombre y un idioma.
+ </notification>
+ <notification name="SpellingDictIsSecondary">
+ El diccionario [DIC_NAME] aparentemente no contiene un archivo &quot;aff&quot;, lo cual significa que es un diccionario &quot;secundario&quot;.
+Puedes utilizarlo como un diccionario adicional, pero no como el diccionario principal.
+
+Consulta https://wiki.secondlife.com/wiki/Adding_Spelling_Dictionaries
+ </notification>
+ <notification name="SpellingDictImportFailed">
+ No se puede copiar
+ [FROM_NAME]
+ a
+ [TO_NAME]
+ </notification>
<notification label="Guardar el vestuario" name="SaveOutfitAs">
Guardar como un nuevo vestuario lo que estoy llevando:
<form name="form">
@@ -1036,7 +1121,7 @@ en TODO EL TERRENO de este sim?
Por favor, elige un pago mayor.
</notification>
<notification name="ConfirmItemDeleteHasLinks">
- Por lo menos uno de los elementos seleccionados contiene vínculos que le señalan. Si eliminas este elemento, los vínculos dejarán de funcionar permanentemente. Lo más recomendable es eliminar primero los vínculos.
+ Por lo menos uno de los elementos contiene vínculos que lo señalan. Si eliminas este elemento, los vínculos dejarán de funcionar permanentemente. Lo más recomendable es eliminar primero los vínculos.
¿Estás seguro de que quieres eliminar los elementos?
<usetemplate name="okcancelbuttons" notext="Cancelar" yestext="OK"/>
@@ -1054,9 +1139,9 @@ Por favor, elige un pago mayor.
<usetemplate name="okcancelbuttons" notext="Cancelar" yestext="OK"/>
</notification>
<notification name="ConfirmObjectDeleteNoOwn">
- No eres el propietario de, al menos, uno de los ítems que has seleccionado.
+ Uno o más de los elementos seleccionados no son tuyos.
-¿Estás seguro de que quieres borrar estos ítems?
+¿Estás seguro de que quieres eliminar los elementos?
<usetemplate name="okcancelbuttons" notext="Cancelar" yestext="OK"/>
</notification>
<notification name="ConfirmObjectDeleteLockNoCopy">
@@ -1067,25 +1152,25 @@ Al menos un objeto no es copiable.
<usetemplate name="okcancelbuttons" notext="Cancelar" yestext="OK"/>
</notification>
<notification name="ConfirmObjectDeleteLockNoOwn">
- Al menos un objeto está bloqueado.
-No eres propietario de, al menos, un objeto.
+ Hay un objeto bloqueado como mínimo.
+No eres propietario de al menos un objeto.
-¿Estás seguro de que quieres borrar estos ítems?
+¿Estás seguro de que quieres eliminar los elementos?
<usetemplate name="okcancelbuttons" notext="Cancelar" yestext="OK"/>
</notification>
<notification name="ConfirmObjectDeleteNoCopyNoOwn">
- Al menos un objeto no es copiable.
-No eres propietario de, al menos, un objeto.
+ No se puede copiar un objeto como mínimo.
+No eres propietario de al menos un objeto.
-¿Estás seguro de que quieres borrar estos ítems?
+¿Estás seguro de que quieres eliminar los elementos?
<usetemplate name="okcancelbuttons" notext="Cancelar" yestext="OK"/>
</notification>
<notification name="ConfirmObjectDeleteLockNoCopyNoOwn">
- Al menos un objeto está bloqueado.
-Al menos un objeto no es copiable.
-No eres propietario de, al menos, un objeto.
+ Hay un objeto bloqueado como mínimo.
+No se puede copiar un objeto como mínimo.
+No eres propietario de al menos un objeto.
-¿Estás seguro de que quieres borrar estos ítems?
+¿Estás seguro de que quieres eliminar los elementos?
<usetemplate name="okcancelbuttons" notext="Cancelar" yestext="OK"/>
</notification>
<notification name="ConfirmObjectTakeLock">
@@ -1152,7 +1237,7 @@ a &apos;[THIS_GPU]&apos;
Se te ha llevado a una región cercana.
</notification>
<notification name="AvatarMovedLast">
- En estos momentos no está disponible tu última posición.
+ En estos momentos no está disponible la posición solicitada.
Se te ha llevado a una región cercana.
</notification>
<notification name="AvatarMovedHome">
@@ -1170,9 +1255,8 @@ Puedes usar [SECOND_LIFE] de forma normal; los demás residentes te verán corre
<notification name="FirstRun">
Se ha completado la instalación de [SECOND_LIFE].
-Si es la primera vez que usas [SECOND_LIFE], debes crear una cuenta antes de poder iniciar una sesión.
-¿Volver a [http://join.secondlife.com secondlife.com] para crear una cuenta nueva?
- <usetemplate name="okcancelbuttons" notext="Continuar" yestext="Cuenta nueva..."/>
+Si es la primera vez que usas [SECOND_LIFE], debes crear una cuenta para poder iniciar una sesión.
+ <usetemplate name="okcancelbuttons" notext="Continuar" yestext="Crear cuenta..."/>
</notification>
<notification name="LoginPacketNeverReceived">
Tenemos problemas de conexión. Puede deberse a un problema de tu conexión a Internet o de [SECOND_LIFE_GRID].
@@ -1410,13 +1494,43 @@ Versión [VERSION] [[RELEASE_NOTES_FULL_URL]; información acerca de esta actual
</notification>
<notification name="RequiredUpdateDownloadedVerboseDialog">
Hemos descargado una actualización de software necesaria.
-Versión [VERSION]
+Versión [VERSION] [[INFO_URL] Información sobre esta actualización]
-Debemos reiniciar [APP_NAME] para instalar la actualización.
+Para instalar la actualización, hay que reiniciar [APP_NAME].
<usetemplate name="okbutton" yestext="OK"/>
</notification>
<notification name="RequiredUpdateDownloadedDialog">
- Debemos reiniciar [APP_NAME] para instalar la actualización.
+ Para instalar la actualización, hay que reiniciar [APP_NAME].
+[[INFO_URL] Información sobre esta actualización]
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
+ <notification name="OtherChannelDownloadBackgroundTip">
+ Hemos descargado una actualización aplicable a tu instalación de [APP_NAME].
+Versión [VERSION]
+Este visor experimental se ha sustituido por un visor de [NEW_CHANNEL].
+Consulta [[INFO_URL] para informarte sobre esta actualización.]
+ <usetemplate name="okcancelbuttons" notext="Más tarde..." yestext="Instalar ahora y reiniciar [APP_NAME]"/>
+ </notification>
+ <notification name="OtherChannelDownloadBackgroundDialog">
+ Hemos descargado una actualización aplicable a tu instalación de [APP_NAME].
+Versión [VERSION]
+Este visor experimental se ha sustituido por un visor de [NEW_CHANNEL].
+Consulta [[INFO_URL] Información sobre esta actualización].
+ <usetemplate name="okcancelbuttons" notext="Más tarde..." yestext="Instalar ahora y reiniciar [APP_NAME]"/>
+ </notification>
+ <notification name="OtherChannelRequiredUpdateDownloadedVerboseDialog">
+ Hemos descargado una actualización de software necesaria.
+Versión [VERSION]
+Este visor experimental se ha sustituido por un visor de [NEW_CHANNEL].
+Consulta [[INFO_URL] Información sobre esta actualización].
+
+Para instalar la actualización, hay que reiniciar [APP_NAME].
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
+ <notification name="OtherChannelRequiredUpdateDownloadedDialog">
+ Para instalar la actualización, hay que reiniciar [APP_NAME].
+Este visor experimental se ha sustituido por un visor de [NEW_CHANNEL].
+Consulta [[INFO_URL] Información sobre esta actualización].
<usetemplate name="okbutton" yestext="OK"/>
</notification>
<notification name="DeedObjectToGroup">
@@ -1467,6 +1581,10 @@ Debemos reiniciar [APP_NAME] para instalar la actualización.
¿Deseas abandonar el grupo?
<usetemplate name="okcancelbuttons" notext="Cancelar" yestext="OK"/>
</notification>
+ <notification name="OwnerCannotLeaveGroup">
+ No es posible abandonar el grupo. No puedes abandonarlo porque eres su último propietario. Antes tienes que asignar el papel de propietario a otro miembro.
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
<notification name="ConfirmKick">
¿Quieres realmente expulsar a todos los residentes de la cuadrícula?
<usetemplate name="okcancelbuttons" notext="Cancelar" yestext="Expulsar a todos los Residentes"/>
@@ -1495,10 +1613,13 @@ Debemos reiniciar [APP_NAME] para instalar la actualización.
En este momento, no se puede ofrecer el ser amigo. Por favor, vuelve a intentarlo en un momento.
<usetemplate name="okbutton" yestext="OK"/>
</notification>
- <notification name="BusyModeSet">
- Pasar al modo ocupado.
-Se ocultará el chat y los mensajes instantáneos (éstos recibirán tu Respuesta en el modo ocupado). Se rehusarán todos los ofrecimientos de teleporte. Todas las ofertas de inventario irán a tu Papelera.
- <usetemplate ignoretext="Cambio mi estado al modo ocupado" name="okignore" yestext="OK"/>
+ <notification name="DoNotDisturbModeSet">
+ Está activado No molestar. No obtendrás un aviso cuando recibas comunicaciones.
+
+- Los otros residentes recibirán tu respuesta de No molestar (se configura en Preferencias &gt; General).
+- Se rehusarán los ofrecimientos de teleporte.
+- Se rechazarán las llamadas de voz.
+ <usetemplate ignoretext="Cambio mi estado al modo No molestar" name="okignore" yestext="OK"/>
</notification>
<notification name="JoinedTooManyGroupsMember">
Has superado tu número máximo de grupos. Por favor, sal de al menos uno antes de entrar en éste, o rehúsa la oferta.
@@ -1694,83 +1815,128 @@ Se cambiarán miles de regiones, y se provocará un colapso en el espacio del se
<usetemplate name="okcancelbuttons" notext="Cancelar" yestext="OK"/>
</notification>
<notification name="RegionEntryAccessBlocked">
- No estás autorizado en esa región por su nivel de calificación. Puede deberse a que no hay información validada de tu edad.
-
-Por favor, comprueba que tienes instalado el último visor, y dirígete a la Base de Conocimientos para más detalles sobre el acceso a zonas con este nivel de calificación.
+ Tus preferencias de contenido actuales te impiden visitar la región que has seleccionado. Puedes cambiar las preferencias en Yo &gt; Preferencias &gt; General.
<usetemplate name="okbutton" yestext="OK"/>
</notification>
- <notification name="RegionEntryAccessBlocked_KB">
- No estás autorizado en esa región por su nivel de calificación.
-
-¿Quieres ir a la Base de Conocimientos para aprender más sobre el nivel de calificación?
+ <notification name="RegionEntryAccessBlocked_AdultsOnlyContent">
+ La región que intentas visitar tiene un contenido [REGIONMATURITY], que solo es accesible para los adultos.
<url name="url">
- http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview/es
+ http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview
</url>
- <usetemplate ignoretext="No puedo entrar a esta región dado el nivel de calificación" name="okcancelignore" notext="Cerrar" yestext="Ir a la Base de Conocimientos"/>
+ <usetemplate ignoretext="Paso a otra región: la región que intentas visitar tiene un contenido solo accesible para los adultos." name="okcancelignore" notext="Cerrar" yestext="Ir a la Base de Conocimientos"/>
</notification>
<notification name="RegionEntryAccessBlocked_Notify">
- No estás autorizado en esa región por su nivel de calificación.
+ La región que intentas visitar tiene un contenido [REGIONMATURITY], pero tus preferencias actuales no te autorizan a ver este tipo de contenidos.
+ </notification>
+ <notification name="RegionEntryAccessBlocked_NotifyAdultsOnly">
+ La región que intentas visitar tiene un contenido [REGIONMATURITY], que solo es accesible para los adultos.
</notification>
<notification name="RegionEntryAccessBlocked_Change">
- No estás autorizado en esta región por tus preferencias sobre el nivel de calificación.
-
-Para entrar en la región que deseas, cambia tu preferencia de nivel de calificación. Esto te permitirá buscar contenidos [REGIONMATURITY] y tener acceso a ellos. Para deshacer los cambios, elige Yo &gt; Preferencias &gt; General.
+ La región que intentas visitar tiene un contenido [REGIONMATURITY], pero tus preferencias actuales no te autorizan a ver este tipo de contenidos. Podemos cambiar tus preferencias o tú puedes cancelar la visita. Después de cambiar tus preferencias, intenta otra vez acceder a la región.
+ <form name="form">
+ <button name="OK" text="Cambiar preferencias"/>
+ <button default="true" name="Cancel" text="Cancelar"/>
+ <ignore name="ignore" text="Paso a otra región: tus preferencias de contenido no te permiten visitar la región que has seleccionado."/>
+ </form>
+ </notification>
+ <notification name="RegionEntryAccessBlocked_PreferencesOutOfSync">
+ Estamos experimentando dificultades técnicas con el teleporte porque tus preferencias no están sincronizadas con el servidor.
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
+ <notification name="TeleportEntryAccessBlocked">
+ Tus preferencias de contenido actuales te impiden visitar la región que has seleccionado. Puedes cambiar las preferencias en Yo &gt; Preferencias &gt; General.
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
+ <notification name="TeleportEntryAccessBlocked_AdultsOnlyContent">
+ La región que intentas visitar tiene un contenido [REGIONMATURITY], que solo es accesible para los adultos.
+ <url name="url">
+ http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview
+ </url>
+ <usetemplate ignoretext="Teleportarme: la región que intentas visitar tiene un contenido solo accesible para los adultos." name="okcancelignore" notext="Cerrar" yestext="Ir a la Base de Conocimientos"/>
+ </notification>
+ <notification name="TeleportEntryAccessBlocked_Notify">
+ La región que intentas visitar tiene un contenido [REGIONMATURITY], pero tus preferencias actuales no te autorizan a ver este tipo de contenidos.
+ </notification>
+ <notification name="TeleportEntryAccessBlocked_NotifyAdultsOnly">
+ La región que intentas visitar tiene un contenido [REGIONMATURITY], que solo es accesible para los adultos.
+ </notification>
+ <notification name="TeleportEntryAccessBlocked_ChangeAndReTeleport">
+ La región que intentas visitar tiene un contenido [REGIONMATURITY], pero tus preferencias actuales no te autorizan a ver este tipo de contenidos. Podemos cambiar tus preferencias y proceder a teleportarte o bien tú puedes cancelar el teleporte.
<form name="form">
- <button name="OK" text="Cambiar las preferencias"/>
- <button default="true" name="Cancel" text="Cerrar"/>
- <ignore name="ignore" text="Mis preferencias sobre nivel de calificación me impiden entrar a esta región"/>
+ <button name="OK" text="Cambiar y continuar"/>
+ <button name="Cancel" text="Cancelar"/>
+ <ignore name="ignore" text="Teleportar (reiniciable): tus preferencias de contenido no te permiten visitar la región que has seleccionado."/>
+ </form>
+ </notification>
+ <notification name="TeleportEntryAccessBlocked_Change">
+ La región que intentas visitar tiene un contenido [REGIONMATURITY], pero tus preferencias actuales no te autorizan a ver este tipo de contenidos. Puedes cambiar tus preferencias o bien cancelar el teleporte. Después de cambiar tus preferencias, intenta teleportarte otra vez.
+ <form name="form">
+ <button name="OK" text="Cambiar preferencias"/>
+ <button name="Cancel" text="Cancelar"/>
+ <ignore name="ignore" text="Teleportar (no reiniciable): tus preferencias de contenido no te permiten visitar la región que has seleccionado."/>
</form>
</notification>
+ <notification name="TeleportEntryAccessBlocked_PreferencesOutOfSync">
+ Estamos experimentando dificultades técnicas con el teleporte porque tus preferencias no están sincronizadas con el servidor.
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
<notification name="PreferredMaturityChanged">
- Tu preferencia de nivel de calificación actual es [RATING].
+ No recibirás más notificaciones cuando vayas a visitar una región con un contenido [RATING]. En el futuro, puedes cambiar tus preferencias de contenido en Yo &gt; Preferencias &gt; General en la barra de menús.
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
+ <notification name="MaturityChangeError">
+ En este momento no se pueden cambiar tus preferencias para ver el contenido [PREFERRED_MATURITY]. Tus preferencias se han restablecido para que puedas ver el contenido [ACTUAL_MATURITY]. Si deseas cambiar las preferencias otra vez, en la barra de menús, selecciona Yo &gt; Preferencias &gt; General.
+ <usetemplate name="okbutton" yestext="OK"/>
</notification>
<notification name="LandClaimAccessBlocked">
- No puedes reclamar este terreno por su nivel de calificación. Puede deberse a que no hay información validada de tu edad.
-
-Por favor, comprueba que tienes instalado el último visor, y dirígete a la Base de Conocimientos para más detalles sobre el acceso a zonas con este nivel de calificación.
+ Tus preferencias actuales de calificación de contenido te impiden reclamar el terreno que has seleccionado. Puedes cambiar las preferencias en Yo &gt; Preferencias &gt; General.
<usetemplate name="okbutton" yestext="OK"/>
</notification>
- <notification name="LandClaimAccessBlocked_KB">
- No puedes reclamar este terreno por su nivel de calificación.
-
-¿Quieres ir a la Base de Conocimientos para más información sobre el nivel de calificación?
+ <notification name="LandClaimAccessBlocked_AdultsOnlyContent">
+ Solo los adultos pueden reclamar este terreno.
<url name="url">
- http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview/es
+ http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview
</url>
- <usetemplate ignoretext="No puedo reclamar este terreno dado el nivel de calificación" name="okcancelignore" notext="Cerrar" yestext="Ir a la Base de Conocimientos"/>
+ <usetemplate ignoretext="Solo los adultos pueden reclamar este terreno." name="okcancelignore" notext="Cerrar" yestext="Ir a la Base de Conocimientos"/>
</notification>
<notification name="LandClaimAccessBlocked_Notify">
- No puedes reclamar este terreno debido a su nivel de calificación.
+ El terreno que intentas reclamar tiene un contenido [REGIONMATURITY], pero tus preferencias actuales no te autorizan a ver este tipo de contenidos.
+ </notification>
+ <notification name="LandClaimAccessBlocked_NotifyAdultsOnly">
+ El terreno que intentas reclamar tiene un contenido [REGIONMATURITY], que solo es accesible para los adultos.
</notification>
<notification name="LandClaimAccessBlocked_Change">
- No puedes reclamar este terreno por tus preferencias sobre el nivel de calificación.
-
-Puedes pulsar &apos;Cambiar las Preferencias&apos; para incrementar las preferencias del nivel de calificación y, así, poder entrar. En adelante, podrás buscar y acceder a contenido [REGIONMATURITY]. Si más adelante quieres deshacer este cambio, ve a Yo &gt; Preferencias &gt; General.
- <usetemplate ignoretext="Mis preferencias sobre el nivel de calificación me impiden reclamar este terreno" name="okcancelignore" notext="Cerrar" yestext="Cambiar preferencia"/>
+ El terreno que intentas reclamar tiene un contenido [REGIONMATURITY], pero tus preferencias actuales no te autorizan a ver este tipo de contenidos. Podemos cambiar tus preferencias y después puedes volver a intentar reclamar el terreno.
+ <form name="form">
+ <button name="OK" text="Cambiar preferencias"/>
+ <button name="Cancel" text="Cancelar"/>
+ <ignore name="ignore" text="Tus preferencias de contenido no te permiten reclamar el terreno que has seleccionado."/>
+ </form>
</notification>
<notification name="LandBuyAccessBlocked">
- No puedes comprar este terreno por su nivel de calificación. Puede deberse a que no hay información validada de tu edad.
-
-Por favor, comprueba que tienes instalado el último visor, y dirígete a la Base de Conocimientos para más detalles sobre el acceso a zonas con este nivel de calificación.
+ Tus preferencias actuales de calificación de contenido te impiden comprar el terreno que has seleccionado. Puedes cambiar las preferencias en Yo &gt; Preferencias &gt; General.
<usetemplate name="okbutton" yestext="OK"/>
</notification>
- <notification name="LandBuyAccessBlocked_KB">
- No puedes comprar este terreno por tus preferencias de nivel de calificación.
-
-¿Quieres ir a la Base de Conocimientos para más información sobre el nivel de calificación?
+ <notification name="LandBuyAccessBlocked_AdultsOnlyContent">
+ Solo los adultos pueden comprar este terreno.
<url name="url">
- http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview/es
+ http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview
</url>
- <usetemplate ignoretext="No puedo comprar este terreno dado el nivel de calificación" name="okcancelignore" notext="Cerrar" yestext="Ir a la Base de Conocimientos"/>
+ <usetemplate ignoretext="Solo los adultos pueden comprar este terreno." name="okcancelignore" notext="Cerrar" yestext="Ir a la Base de Conocimientos"/>
</notification>
<notification name="LandBuyAccessBlocked_Notify">
- No puedes comprar este terreno por su nivel de calificación.
+ El terreno que intentas comprar tiene un contenido [REGIONMATURITY], pero tus preferencias actuales no te autorizan a ver este tipo de contenidos.
+ </notification>
+ <notification name="LandBuyAccessBlocked_NotifyAdultsOnly">
+ El terreno que intentas comprar tiene un contenido [REGIONMATURITY], que solo es accesible para los adultos.
</notification>
<notification name="LandBuyAccessBlocked_Change">
- No puedes comprar este terreno por tus preferencias sobre el nivel de calificación.
-
-Puedes pulsar &apos;Cambiar las Preferencias&apos; para incrementar las preferencias del nivel de calificación y, así, poder entrar. En adelante, podrás buscar y acceder a contenido [REGIONMATURITY]. Si más adelante quieres deshacer este cambio, ve a Yo &gt; Preferencias &gt; General.
- <usetemplate ignoretext="Mis preferencias sobre el nivel de calificación me impiden comprar el terreno" name="okcancelignore" notext="Cerrar" yestext="Cambiar preferencia"/>
+ El terreno que intentas comprar tiene un contenido [REGIONMATURITY], pero tus preferencias actuales no te autorizan a ver este tipo de contenidos. Podemos cambiar tus preferencias y después puedes volver a intentar comprar el terreno.
+ <form name="form">
+ <button name="OK" text="Cambiar preferencias"/>
+ <button name="Cancel" text="Cancelar"/>
+ <ignore name="ignore" text="Tus preferencias de contenido no te permiten comprar el terreno que has seleccionado."/>
+ </form>
</notification>
<notification name="TooManyPrimsSelected">
Hay demasiados prims seleccionados. Por favor, selecciona [MAX_PRIM_COUNT] o menos y vuelve a intentarlo
@@ -1825,10 +1991,9 @@ Puedes pulsar &apos;Cambiar las Preferencias&apos; para incrementar las preferen
</form>
</notification>
<notification label="Cambiada la calificación de la región" name="RegionMaturityChange">
- Se ha actualizado el nivel de calificación de esta región.
+ Se ha cambiando el nivel de calificación de esta región.
Puede que lleve algún tiempo hasta que el cambio se vea reflejado en el mapa.
-
-Para entrar a regiones Adultas, los Residentes deben haber verificado su cuenta, bien verificando la edad o bien verificando una forma de pago.
+ <usetemplate name="okbutton" yestext="OK"/>
</notification>
<notification label="Desajuste en la versión de voz" name="VoiceVersionMismatch">
Esta versión de [APP_NAME] no es compatible con la prestación de voz de esta región. Para que el chat de voz funcione correctamente debes actualizar [APP_NAME].
@@ -1941,6 +2106,10 @@ Dado que estos objetos tienen scripts, moverlos a tu inventario puede provocar u
¿Ir a tu [http://secondlife.com/account/ Panel de Control] para ver el historial de tu cuenta?
<usetemplate ignoretext="Abrir mi navegador para ver el historial de mi cuenta" name="okcancelignore" notext="Cancelar" yestext="Ir a la página"/>
</notification>
+ <notification name="ConfirmAddingChatParticipants">
+ Si agregas una persona a una conversación en curso, se creará una conversación nueva. Todos los participantes recibirán notificaciones de la nueva conversación.
+ <usetemplate ignoretext="Confirmar agregar participantes al chat" name="okcancelignore" notext="Cancelar" yestext="Aceptar"/>
+ </notification>
<notification name="ConfirmQuit">
¿Estás seguro de que quieres salir?
<usetemplate ignoretext="Confirmar antes de salir" name="okcancelignore" notext="No salir" yestext="Salir"/>
@@ -2014,14 +2183,14 @@ Linden Lab
<button ignore="Nunca reemplazar" name="No" text="Cancelar"/>
</form>
</notification>
- <notification label="¡Aviso! Modo Ocupado" name="BusyModePay">
- Estás en el modo Ocupado. Por tanto, no recibirás ningún ítem a cambio de este pago.
+ <notification label="Advertencia del modo No molestar" name="DoNotDisturbModePay">
+ Tienes activado No molestar. No podrás recibir ningún objeto ofrecido a cambio de este pago.
-¿Quieres salir del modo Ocupado antes de completar esta transacción?
+¿Deseas desactivar No molestar antes de finalizar esta transacción?
<form name="form">
- <ignore name="ignore" save_option="true" text="Voy a pagar a una persona u objeto mientras estoy en el modo ocupado"/>
- <button ignore="Siempre salir del modo Ocupado" name="Yes" text="OK"/>
- <button ignore="Nunca salir del modo Ocupado" name="No" text="Cancelar"/>
+ <ignore name="ignore" text="Voy a pagar a una persona u objeto mientras estoy en el modo No molestar"/>
+ <button ignore="Salir siempre del modo No molestar" name="Yes" text="OK"/>
+ <button ignore="No salir nunca del modo No molestar" name="No" text="Cancelar"/>
</form>
</notification>
<notification name="ConfirmDeleteProtectedCategory">
@@ -2117,14 +2286,11 @@ Publícala en una página web para que otros puedan acceder fácilmente a esta p
<usetemplate ignoretext="Ponerme la ropa que estoy creando mientras modifico mi apariencia" name="okcancelignore" notext="No" yestext="Sí"/>
</notification>
<notification name="NotAgeVerified">
- Para acceder al contenido Adulto y los lugares de Second Life con dicho carácter, debes tener por lo menos 18 años. Visita la página de verificación de edad para confirmar que tienes más de 18 años.
-Al hacerlo se iniciará el navegador web.
-
-[_URL]
- <url name="url" option="0">
- https://secondlife.com/my/account/verification.php
- </url>
- <usetemplate ignoretext="No he verificado mi edad" name="okcancelignore" notext="Cancelar" yestext="Ir a Verificación de la edad"/>
+ El lugar que intentas visitar tiene el acceso restringido a los Residentes mayores de 18 años.
+ <usetemplate ignoretext="No tengo la edad suficiente para visitar áreas restringidas por edad." name="okignore" yestext="OK"/>
+ </notification>
+ <notification name="NotAgeVerified_Notify">
+ Localización restringida para mayores de 18 años.
</notification>
<notification name="Cannot enter parcel: no payment info on file">
Para visitar este sitio debes haber aportado información de pago en tu cuenta. ¿Quieres ir al sitio web de [SECOND_LIFE] y configurar esto?
@@ -2159,11 +2325,8 @@ Al hacerlo se iniciará el navegador web.
<notification name="GroupNotice">
Asunto: [SUBJECT], Mensaje: [MESSAGE]
</notification>
- <notification name="FriendOnline">
- &lt;nolink&gt;[NAME]&lt;/nolink&gt; está conectado
- </notification>
- <notification name="FriendOffline">
- &lt;nolink&gt;[NAME]&lt;/nolink&gt; está desconectado
+ <notification name="FriendOnlineOffline">
+ &lt;nolink&gt;[NAME]&lt;/nolink&gt; está [STATUS]
</notification>
<notification name="AddSelfFriend">
Aunque eres muy agradable, no puedes añadirte como amigo a ti mismo.
@@ -2283,9 +2446,7 @@ Por favor, selecciona un sólo objeto.
elegir &apos;Teleportar&apos;.)
</notification>
<notification name="TeleportToPerson">
- Para ponerte en contacto con Residentes como &apos;[NAME]&apos;, pulsa el botón &quot;Gente&quot;, selecciona un Residente en la ventana que se abre y después pulsa en &apos;MI&apos; en
- la parte inferior de la ventana.
- (También puedes pulsar dos veces en su nombre o pulsarlo con el botón derecho y elegir &apos;MI&apos;).
+ Para abrir una conversación privada con alguien, pulsa con el botón derecho en su avatar y selecciona &apos;MI&apos; en el menú.
</notification>
<notification name="CantSelectLandFromMultipleRegions">
No puedes seleccionar un terreno que cruce las fronteras entre servidores.
@@ -2385,6 +2546,16 @@ Aquí no puedes volar.
<notification name="NoBuild">
Este terreno tiene desactivado el poder construir. Aquí no puedes ni construir ni crear objetos.
</notification>
+ <notification name="PathfindingDirty">
+ La región contiene cambios de pathfinding pendientes. Si tienes derechos de construcción, puedes recargarla pulsando el botón “Recargar regiónâ€.
+ </notification>
+ <notification name="DynamicPathfindingDisabled">
+ Esta región no tiene activado el pathfinding dinámico. Los objetos programados que utilicen llamadas LSL de pathfinding pueden tener un comportamiento inesperado en ella.
+ </notification>
+ <notification name="PathfindingCannotRebakeNavmesh">
+ Se ha producido un error. Puede haber ocurrido un problema en la red o el servidor, o quizás no tengas derechos de construcción. Este problema podría resolverse cerrando la sesión e iniciando una sesión nueva.
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
<notification name="SeeAvatars">
Esta parcela oculta los avatares y el chat de texto de otras parcelas. No podrás ver a los residentes que estén fuera la parcela ni ellos podrán verte a ti. El chat de texto regular del canal 0 también está bloqueado.
</notification>
@@ -2403,9 +2574,7 @@ Los scripts no funcionan aquí, excepto los pertenecientes al propietario del te
Sólo puedes reclamar terreno público de la región en que estás.
</notification>
<notification name="RegionTPAccessBlocked">
- No estás autorizado en esa región por su nivel de calificación. Debes validar tu edad y/o instalar el último visor.
-
-Por favor, dirígete a la Base de Conocimientos para más detalles sobre el acceso a zonas con este nivel de calificación.
+ Tus preferencias de contenido actuales te impiden visitar la región que has seleccionado. Puedes cambiar las preferencias en Yo &gt; Preferencias &gt; General.
</notification>
<notification name="URBannedFromRegion">
Se te ha prohibido el acceso a la región.
@@ -2416,11 +2585,11 @@ Por favor, dirígete a la Base de Conocimientos para más detalles sobre el acce
<notification name="ImproperPaymentStatus">
No tienes el estado de pago adecuado para entrar a esta región.
</notification>
- <notification name="MustGetAgeRgion">
- Debes tener verificada la edad para entrar a esta región
+ <notification name="MustGetAgeRegion">
+ Solo pueden acceder a esta región los mayores de 18 años.
</notification>
<notification name="MustGetAgeParcel">
- Debes haber verificado tu edad para entrar a esta parcela.
+ Para acceder a esta parcela debes ser mayor de 18 años.
</notification>
<notification name="NoDestRegion">
No se ha encontrada la región de destino.
@@ -2520,14 +2689,35 @@ Por favor, vuelve a intentarlo en unos momentos.
</form>
</notification>
<notification name="TeleportOffered">
- [NAME_SLURL] te ha ofrecido teleportarte a su posición:
+ [NAME_SLURL] te ofrece teleportarte a su localización:
-[MESSAGE] - [MATURITY_STR] &lt;icon&gt;[MATURITY_ICON]&lt;/icon&gt;
+“[MESSAGE]â€
+&lt;icon&gt;[MATURITY_ICON]&lt;/icon&gt; - [MATURITY_STR]
<form name="form">
<button name="Teleport" text="Teleportar"/>
<button name="Cancel" text="Cancelar"/>
</form>
</notification>
+ <notification name="TeleportOffered_MaturityExceeded">
+ [NAME_SLURL] te ofrece teleportarte a su localización:
+
+“[MESSAGE]â€
+&lt;icon&gt;[MATURITY_ICON]&lt;/icon&gt; - [MATURITY_STR]
+
+Esta región tiene un contenido [REGION_CONTENT_MATURITY, pero tus preferencias actuales no te autorizan a ver los contenidos [REGION_CONTENT_MATURITY]. Podemos cambiar tus preferencias y proceder a teleportarte o bien tú puedes cancelar el teleporte.
+ <form name="form">
+ <button name="Teleport" text="Cambiar y continuar"/>
+ <button name="Cancel" text="Cancelar"/>
+ </form>
+ </notification>
+ <notification name="TeleportOffered_MaturityBlocked">
+ [NAME_SLURL] te ofrece teleportarte a su localización:
+
+“[MESSAGE]â€
+&lt;icon&gt;[MATURITY_ICON]&lt;/icon&gt; - [MATURITY_STR]
+
+No obstante, el contenido de esta región solo es accesible para los adultos.
+ </notification>
<notification name="TeleportOfferSent">
Teleporte ofrecido a [TO_NAME]
</notification>
@@ -2622,33 +2812,32 @@ Del objeto: &lt;nolink&gt;[OBJECTNAME]&lt;/nolink&gt;, propietario: [NAME]?
</form>
</notification>
<notification name="ScriptQuestionCaution">
- Un objeto de nombre &apos;&lt;nolink&gt;[OBJECTNAME]&lt;/nolink&gt;&apos;, propiedad de &apos;[NAME]&apos;, quiere:
-
-[QUESTIONS]
-Si no confias en este objeto y en su creador, deberías rehusar esta petición.
-
-¿Autorizar esta petición?
+ Atención: El objeto &apos;&lt;nolink&gt;[OBJECTNAME]&lt;/nolink&gt;&apos; solicita un acceso pleno a tu cuenta de dólares Linden. Si le autorizas el acceso, podrá retirar fondos de tu cuenta en cualquier momento o vaciarla por completo, cuando lo desee y sin más advertencias.
+
+No autorices el acceso a tu cuenta si no conoces cuál es la razón exacta.
<form name="form">
- <button name="Grant" text="Autorizar"/>
+ <button name="Grant" text="Permitir acceso total"/>
<button name="Deny" text="Denegar"/>
- <button name="Details" text="Detalles..."/>
</form>
</notification>
- <notification name="ScriptDialog">
- &apos;&lt;nolink&gt;[TITLE]&lt;/nolink&gt;&apos; de [NAME]
-[MESSAGE]
+ <notification name="UnknownScriptQuestion">
+ &apos;&lt;nolink&gt;[OBJECTNAME]&lt;/nolink&gt;&apos;, un objeto propiedad de &apos;[NAME]&apos;, ha solicitado un permiso de script en tiempo de ejecución que el visor no reconoce ni puede conceder.
+
+Para obtener el permiso, descárgate aquí la última versión: [DOWNLOADURL].
<form name="form">
+ <button name="Deny" text="Aceptar"/>
<button name="Mute" text="Ignorar"/>
- <button name="Ignore" text="Ignorar"/>
</form>
</notification>
+ <notification name="ScriptDialog">
+ &apos;&lt;nolink&gt;[TITLE]&lt;/nolink&gt;&apos; de [NAME]
+[MESSAGE]
+ <form name="form"/>
+ </notification>
<notification name="ScriptDialogGroup">
&apos;&lt;nolink&gt;[TITLE]&lt;/nolink&gt;&apos; de [GROUPNAME]
[MESSAGE]
- <form name="form">
- <button name="Mute" text="Ignorar"/>
- <button name="Ignore" text="Ignorar"/>
- </form>
+ <form name="form"/>
</notification>
<notification name="BuyLindenDollarSuccess">
¡Gracias por tu pago!
@@ -2934,6 +3123,10 @@ Has actualizado una textura obtenida mediante bake de [RESOLUTION] para &apos;[B
( [EXISTENCE] segundos con vida )
Has actualizado de manera local una textura obtenida mediante bake de [RESOLUTION] para &apos;[BODYREGION]&apos; después de [TIME] segundos.
</notification>
+ <notification name="LivePreviewUnavailable">
+ No se puede mostrar una vista previa de esta textura porque es de tipo &apos;no copiable&apos; y/o &apos;no transferible&apos;.
+ <usetemplate ignoretext="Advertirme si el modo Vista previa inmediata no está disponible para las texturas &apos;no copiable&apos; y/o &apos;no transferible&apos;" name="okignore" yestext="OK"/>
+ </notification>
<notification name="ConfirmLeaveCall">
¿Estás seguro de que deseas salir de esta multiconferencia?
<usetemplate ignoretext="Confirma antes de salir de la llamada" name="okcancelignore" notext="No" yestext="Sí"/>
@@ -3102,6 +3295,62 @@ Al ocultar el botón Hablar se desactiva la función de voz.
Esta acción ocultará todos los botones y elementos de menú. Para restaurarlos, pulsa otra vez en [SHORTCUT].
<usetemplate ignoretext="Confirmar antes de ocultar la IU" name="okcancelignore" notext="Cancelar" yestext="OK"/>
</notification>
+ <notification name="PathfindingLinksets_WarnOnPhantom">
+ El indicador de inmaterial de algunos linksets seleccionados se conmutará.
+
+¿Quieres continuar?
+ <usetemplate ignoretext="El indicador de inmaterial de algunos linksets seleccionados se conmutará." name="okcancelignore" notext="Cancelar" yestext="OK"/>
+ </notification>
+ <notification name="PathfindingLinksets_MismatchOnRestricted">
+ Algunos de los linksets seleccionados no pueden configurarse como &apos;[REQUESTED_TYPE]&apos; debido a restricciones de los permisos del linkset. Estos linksets se configurarán como &apos;[RESTRICTED_TYPE]&apos;.
+
+¿Quieres continuar?
+ <usetemplate ignoretext="Algunos de los linksets seleccionados no pueden configurarse debido a restricciones de los permisos del linkset." name="okcancelignore" notext="Cancelar" yestext="OK"/>
+ </notification>
+ <notification name="PathfindingLinksets_MismatchOnVolume">
+ Algunos de los linksets seleccionados no pueden configurarse como &apos;[REQUESTED_TYPE]&apos; porque su forma no es convexa.
+
+¿Quieres continuar?
+ <usetemplate ignoretext="Algunos de los linksets seleccionados no pueden configurarse porque su forma no es convexa." name="okcancelignore" notext="Cancelar" yestext="OK"/>
+ </notification>
+ <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnRestricted">
+ El indicador de inmaterial de algunos linksets seleccionados se conmutará.
+
+Algunos de los linksets seleccionados no pueden configurarse como &apos;[REQUESTED_TYPE]&apos; debido a restricciones de los permisos del linkset. Estos linksets se configurarán como &apos;[RESTRICTED_TYPE]&apos;.
+
+¿Quieres continuar?
+ <usetemplate ignoretext="El indicador de inmaterial de algunos linksets seleccionados se conmutará y otros no se podrán establecer debido a restricciones de los permisos del linkset." name="okcancelignore" notext="Cancelar" yestext="OK"/>
+ </notification>
+ <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnVolume">
+ El indicador de inmaterial de algunos linksets seleccionados se conmutará.
+
+Algunos de los linksets seleccionados no pueden configurarse como &apos;[REQUESTED_TYPE]&apos; porque su forma no es convexa.
+
+¿Quieres continuar?
+ <usetemplate ignoretext="El indicador de inmaterial de algunos linksets seleccionados se conmutará y otros no se podrán establecer porque la forma no es convexa" name="okcancelignore" notext="Cancelar" yestext="OK"/>
+ </notification>
+ <notification name="PathfindingLinksets_MismatchOnRestricted_MismatchOnVolume">
+ Algunos de los linksets seleccionados no pueden configurarse como &apos;[REQUESTED_TYPE]&apos; debido a restricciones de los permisos del linkset. Estos linksets se configurarán como &apos;[RESTRICTED_TYPE]&apos;.
+
+Algunos de los linksets seleccionados no pueden configurarse como &apos;[REQUESTED_TYPE]&apos; porque su forma no es convexa. Los tipos de utilización de estos linksets no cambiarán.
+
+¿Quieres continuar?
+ <usetemplate ignoretext="Algunos de los linksets seleccionados no pueden configurarse debido a restricciones de los permisos del linkset y porque su forma no es convexa." name="okcancelignore" notext="Cancelar" yestext="OK"/>
+ </notification>
+ <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnRestricted_MismatchOnVolume">
+ El indicador de inmaterial de algunos linksets seleccionados se conmutará.
+
+Algunos de los linksets seleccionados no pueden configurarse como &apos;[REQUESTED_TYPE]&apos; debido a restricciones de los permisos del linkset. Estos linksets se configurarán como &apos;[RESTRICTED_TYPE]&apos;.
+
+Algunos de los linksets seleccionados no pueden configurarse como &apos;[REQUESTED_TYPE]&apos; porque su forma no es convexa. Los tipos de utilización de estos linksets no cambiarán.
+
+¿Quieres continuar?
+ <usetemplate ignoretext="El indicador de inmaterial de algunos linksets seleccionados se conmutará y otros no se podrán establecer debido a restricciones de los permisos del linkset y porque su forma no es convexa." name="okcancelignore" notext="Cancelar" yestext="OK"/>
+ </notification>
+ <notification name="PathfindingLinksets_ChangeToFlexiblePath">
+ El objeto que has seleccionado afecta al navmesh. Al cambiarlo a una Ruta flexible se eliminará del navmesh.
+ <usetemplate ignoretext="El objeto que has seleccionado afecta al navmesh. Al cambiarlo a una Ruta flexible se eliminará del navmesh." name="okcancelignore" notext="Cancelar" yestext="OK"/>
+ </notification>
<global name="UnsupportedGLRequirements">
Parece que no tienes el hardware apropiado para [APP_NAME]. [APP_NAME] requiere una tarjeta gráfica OpenGL que admita texturas múltiples (&apos;multitexture support&apos;). Si la tienes, comprueba que tienes los últimos &apos;drivers&apos; para tu tarjeta gráfica, así como los últimos parches y &apos;service packs&apos; para tu sistema operativo.
@@ -3126,4 +3375,653 @@ También puedes buscar en el Mapa lugares marcados como &quot;Puntos de Informac
<global name="You died and have been teleported to your home location">
Has muerto y te has teleportado a tu Base.
</global>
+ <notification name="LocalBitmapsUpdateFileNotFound">
+ [FNAME] no se ha podido actualizar porque el archivo ya no se encuentra.
+Desactivando futuras actualizaciones de este archivo.
+ </notification>
+ <notification name="LocalBitmapsUpdateFailedFinal">
+ [FNAME] se ha intentado abrir o descodificar durante [NRETRIES] intentos sin éxito, y ahora se considera roto.
+Desactivando futuras actualizaciones de este archivo.
+ </notification>
+ <notification name="LocalBitmapsVerifyFail">
+ Se ha intentado añadir un archivo de imagen [FNAME] no válido o ilegible, que no se puede abrir ni descodificar.
+Intento cancelado.
+ </notification>
+ <notification name="PathfindingReturnMultipleItems">
+ Vas a devolver [NUM_ITEMS] objetos. ¿Estás seguro de que deseas continuar?
+ <usetemplate ignoretext="¿Estás seguro de que quieres devolver varios objetos?" name="okcancelignore" notext="No" yestext="Sí"/>
+ </notification>
+ <notification name="PathfindingDeleteMultipleItems">
+ Vas a eliminar [NUM_ITEMS] objetos. ¿Estás seguro de que deseas continuar?
+ <usetemplate ignoretext="¿Estás seguro de que quieres eliminar varios elementos?" name="okcancelignore" notext="No" yestext="Sí"/>
+ </notification>
+ <notification name="AvatarFrozen">
+ [AV_FREEZER] te ha congelado. No puedes moverte ni interactuar con el mundo.
+ </notification>
+ <notification name="AvatarFrozenDuration">
+ [AV_FREEZER] te ha congelado durante [AV_FREEZE_TIME] segundos. No puedes moverte ni interactuar con el mundo.
+ </notification>
+ <notification name="YouFrozeAvatar">
+ Avatar congelado.
+ </notification>
+ <notification name="AvatarHasUnFrozenYou">
+ [AV_FREEZER] te ha descongelado.
+ </notification>
+ <notification name="AvatarUnFrozen">
+ Avatar descongelado.
+ </notification>
+ <notification name="AvatarFreezeFailure">
+ Error al congelar: no tienes permisos de administrador en esa parcela.
+ </notification>
+ <notification name="AvatarFreezeThaw">
+ La congelación ha terminado, puedes seguir con tus asuntos.
+ </notification>
+ <notification name="AvatarCantFreeze">
+ Lo sentimos, ese usuario no se puede congelar.
+ </notification>
+ <notification name="NowOwnObject">
+ Ahora eres el propietario del objeto [OBJECT_NAME]
+ </notification>
+ <notification name="CantRezOnLand">
+ No se puede colocar el objeto en [OBJECT_POS] porque el propietario de ese terreno no lo permite. Usa la herramienta de terreno para ver quién es el propietario.
+ </notification>
+ <notification name="RezFailTooManyRequests">
+ El objeto no se puede colocar porque hay demasiadas solicitudes.
+ </notification>
+ <notification name="SitFailCantMove">
+ No te puedes sentar porque en este momento no puedes desplazarte.
+ </notification>
+ <notification name="SitFailNotAllowedOnLand">
+ No te puedes sentar porque no tienes permiso para estar en ese terreno.
+ </notification>
+ <notification name="SitFailNotSameRegion">
+ Acércate. No te puedes sentar en el objeto porque
+no está en la misma región que tú.
+ </notification>
+ <notification name="NoNewObjectRegionFull">
+ No se puede crear el nuevo objeto. La región está llena.
+ </notification>
+ <notification name="FailedToPlaceObject">
+ Error al colocar el objeto en el lugar especificado. Vuelve a intentarlo.
+ </notification>
+ <notification name="NoOwnNoGardening">
+ No puedes crear árboles y hierba en un terreno que no es tuyo.
+ </notification>
+ <notification name="NoCopyPermsNoObject">
+ Error al copiar: careces de permiso para copiar el objeto &apos;[OBJ_NAME]&apos;.
+ </notification>
+ <notification name="NoTransPermsNoObject">
+ Error al copiar: no se te puede transferir el objeto &apos;[OBJ_NAME]&apos;.
+ </notification>
+ <notification name="AddToNavMeshNoCopy">
+ Error al copiar porque el objeto &apos;[OBJ_NAME]&apos; contribuye al navmesh.
+ </notification>
+ <notification name="DupeWithNoRootsSelected">
+ Duplicación sin objetos raíz seleccionados.
+ </notification>
+ <notification name="CantDupeCuzRegionIsFull">
+ No se pueden duplicar objetos porque la región está llena.
+ </notification>
+ <notification name="CantDupeCuzParcelNotFound">
+ No se pueden duplicar los objetos: no se encuentra la parcela en la que se hallan.
+ </notification>
+ <notification name="CantCreateCuzParcelFull">
+ No se puede crear el objeto porque
+la parcela está llena.
+ </notification>
+ <notification name="RezAttemptFailed">
+ Error al intentar colocar un objeto.
+ </notification>
+ <notification name="ToxicInvRezAttemptFailed">
+ No se puede crear un objeto que ha causado problemas en esta región.
+ </notification>
+ <notification name="InvItemIsBlacklisted">
+ Ese objeto de inventario está en la lista negra.
+ </notification>
+ <notification name="NoCanRezObjects">
+ Actualmente no tienes autorización para crear objetos.
+ </notification>
+ <notification name="LandSearchBlocked">
+ Búsqueda de terrenos bloqueada.
+Has realizado demasiadas búsquedas de terreno con excesiva rapidez.
+Prueba otra vez dentro de un minuto.
+ </notification>
+ <notification name="NotEnoughResourcesToAttach">
+ No hay suficientes recursos de script disponibles para anexar el objeto
+ </notification>
+ <notification name="YouDiedAndGotTPHome">
+ Has muerto y te has teleportado a tu lugar de origen
+ </notification>
+ <notification name="EjectComingSoon">
+ Te han expulsado de aquí y tienes [EJECT_TIME] segundos para salir.
+ </notification>
+ <notification name="NoEnterServerFull">
+ No puedes entrar en esta región porque
+el servidor está lleno.
+ </notification>
+ <notification name="SaveBackToInvDisabled">
+ Se ha deshabilitado Devolver el objeto a mi inventario.
+ </notification>
+ <notification name="NoExistNoSaveToContents">
+ No se puede guardar &apos;[OBJ_NAME]&apos; en el contenido del objeto porque el objeto desde el cual ha sido colocado ya no existe.
+ </notification>
+ <notification name="NoModNoSaveToContents">
+ No se puede guardar &apos;[OBJ_NAME]&apos; en el contenido del objeto porque no tienes permiso para modificar el objeto &apos;[DEST_NAME]&apos;.
+ </notification>
+ <notification name="NoSaveBackToInvDisabled">
+ No se puede guardar &apos;[OBJ_NAME]&apos; de nuevo en el inventario; esta operación está desactivada.
+ </notification>
+ <notification name="NoCopyNoSelCopy">
+ No se puede copiar tu selección porque no tienes permiso para copiar el objeto &apos;[OBJ_NAME]&apos;.
+ </notification>
+ <notification name="NoTransNoSelCopy">
+ No se puede copiar tu selección porque el objeto &apos;[OBJ_NAME]&apos; es intransferible.
+ </notification>
+ <notification name="NoTransNoCopy">
+ No se puede copiar tu selección porque el objeto &apos;[OBJ_NAME]&apos; es intransferible.
+ </notification>
+ <notification name="NoPermsNoRemoval">
+ El sistema de permisos no admite la eliminación del objeto &apos;[OBJ_NAME]&apos; del simulador.
+ </notification>
+ <notification name="NoModNoSaveSelection">
+ No se puede guardar tu selección porque no tienes permiso para modificar el objeto &apos;[OBJ_NAME]&apos;.
+ </notification>
+ <notification name="NoCopyNoSaveSelection">
+ No se puede guardar tu selección porque el objeto &apos;[OBJ_NAME]&apos; no se puede copiar.
+ </notification>
+ <notification name="NoModNoTaking">
+ No se puede aceptar tu selección porque no tienes permiso para modificar el objeto &apos;[OBJ_NAME]&apos;.
+ </notification>
+ <notification name="RezDestInternalError">
+ Error interno: tipo de destino desconocido.
+ </notification>
+ <notification name="DeleteFailObjNotFound">
+ Error al borrar: el objeto no se encuentra
+ </notification>
+ <notification name="SorryCantEjectUser">
+ Lo sentimos, ese usuario no se puede expulsar.
+ </notification>
+ <notification name="RegionSezNotAHome">
+ Esta región no te permite configurar aquí tu lugar de origen.
+ </notification>
+ <notification name="HomeLocationLimits">
+ Tu &apos;Lugar de origen&apos; solo se puede configurar en tu terreno o en un punto de información del continente.
+ </notification>
+ <notification name="HomePositionSet">
+ Posición de origen ajustada.
+ </notification>
+ <notification name="AvatarEjected">
+ Avatar expulsado.
+ </notification>
+ <notification name="AvatarEjectFailed">
+ Error al expulsar: no tienes permiso de administrador en esa parcela.
+ </notification>
+ <notification name="CantMoveObjectParcelFull">
+ No se puede mover el objeto &apos;[OBJECT_NAME]&apos; a
+[OBJ_POSITION] en la región [REGION_NAME] porque la parcela está llena.
+ </notification>
+ <notification name="CantMoveObjectParcelPerms">
+ No se puede mover el objeto &apos;[OBJECT_NAME]&apos; a
+[OBJ_POSITION] de la región [REGION_NAME] porque tus objetos no están permitidos en esta parcela.
+ </notification>
+ <notification name="CantMoveObjectParcelResources">
+ No se puede mover el objeto &apos;[OBJECT_NAME]&apos; a
+[OBJ_POSITION] de la región [REGION_NAME] porque no hay suficientes recursos para este objeto en esta parcela.
+ </notification>
+ <notification name="CantMoveObjectRegionVersion">
+ No se puede mover el objeto &apos;[OBJECT_NAME]&apos; a
+[OBJ_POSITION] de la región [REGION_NAME] porque la otra región ejecuta una versión más antigua que no admite la recepción de este objeto atravesando regiones.
+ </notification>
+ <notification name="CantMoveObjectNavMesh">
+ No se puede mover el objeto &apos;[OBJECT_NAME]&apos; a
+[OBJ_POSITION] en la región [REGION_NAME] porque no puedes modificar el navmesh a través de límites de región.
+ </notification>
+ <notification name="CantMoveObjectWTF">
+ No se puede mover el objeto &apos;[OBJECT_NAME]&apos; a
+[OBJ_POSITION] en la región [REGION_NAME] por un motivo desconocido. ([FAILURE_TYPE])
+ </notification>
+ <notification name="NoPermModifyObject">
+ No tienes permiso para modificar ese objeto
+ </notification>
+ <notification name="CantEnablePhysObjContributesToNav">
+ No se puede habilitar la física para un objeto que contribuye al navmesh.
+ </notification>
+ <notification name="CantEnablePhysKeyframedObj">
+ No se puede activar la física para los objetos con fotogramas clave.
+ </notification>
+ <notification name="CantEnablePhysNotEnoughLandResources">
+ No se puede habilitar la física para el objeto: recursos de terreno insuficientes.
+ </notification>
+ <notification name="CantEnablePhysCostTooGreat">
+ No se puede activar la física para un objeto con un coste de recursos de física mayor que [MAX_OBJECTS]
+ </notification>
+ <notification name="PhantomWithConcavePiece">
+ Este objeto no puede tener una pieza cóncava porque es inmaterial y contribuye al navmesh.
+ </notification>
+ <notification name="UnableAddItem">
+ ¡No se puede añadir un objeto!
+ </notification>
+ <notification name="UnableEditItem">
+ ¡No se puede editar esto!
+ </notification>
+ <notification name="NoPermToEdit">
+ No puedes editar esto.
+ </notification>
+ <notification name="NoPermToCopyInventory">
+ No está permitido copiar ese inventario.
+ </notification>
+ <notification name="CantSaveItemDoesntExist">
+ No se puede guardar en el contenido del objeto: el objeto ya no existe.
+ </notification>
+ <notification name="CantSaveItemAlreadyExists">
+ No se puede guardar en el contenido del objeto: el inventario ya contiene un objeto con ese nombre
+ </notification>
+ <notification name="CantSaveModifyAttachment">
+ No se puede guardar en el contenido del objeto: se modificarían los permisos de anexo.
+ </notification>
+ <notification name="TooManyScripts">
+ Demasiados scripts.
+ </notification>
+ <notification name="UnableAddScript">
+ ¡No se puede añadir un script!
+ </notification>
+ <notification name="AssetServerTimeoutObjReturn">
+ El servidor de objetos no respondió puntualmente. El objeto se ha devuelto al sim.
+ </notification>
+ <notification name="RegionDisablePhysicsShapes">
+ Esta región no tiene habilitadas las formas de física.
+ </notification>
+ <notification name="NoModNavmeshAcrossRegions">
+ No se puede modificar el navmesh a través de límites de región.
+ </notification>
+ <notification name="NoSetPhysicsPropertiesOnObjectType">
+ No se pueden establecer propiedades de física en ese tipo de objeto.
+ </notification>
+ <notification name="NoSetRootPrimWithNoShape">
+ No se puede establecer que un prim raíz no tenga forma.
+ </notification>
+ <notification name="NoRegionSupportPhysMats">
+ Esta región no tiene habilitados los materiales de física.
+ </notification>
+ <notification name="OnlyRootPrimPhysMats">
+ Solo se pueden ajustar los materiales de física de las prims raíces.
+ </notification>
+ <notification name="NoSupportCharacterPhysMats">
+ Aun no es posible configurar materiales de física para los personajes.
+ </notification>
+ <notification name="InvalidPhysMatProperty">
+ Una o varias de las propiedades de los materiales de física especificados no son válidas.
+ </notification>
+ <notification name="NoPermsAlterStitchingMeshObj">
+ No se puede cambiar el tipo de unión de un objeto de la malla.
+ </notification>
+ <notification name="NoPermsAlterShapeMeshObj">
+ No se puede cambiar la forma de un objeto de la malla
+ </notification>
+ <notification name="FullRegionCantEnter">
+ No puedes entrar en esta región porque \nla región está llena.
+ </notification>
+ <notification name="LinkFailedOwnersDiffer">
+ Error de vínculo: los propietarios son diferentes
+ </notification>
+ <notification name="LinkFailedNoModNavmeshAcrossRegions">
+ Error de vínculo: no se puede modificar el navmesh a través de límites de región.
+ </notification>
+ <notification name="LinkFailedNoPermToEdit">
+ Error de vínculo: no tienes permiso de edición.
+ </notification>
+ <notification name="LinkFailedTooManyPrims">
+ Error de vínculo: demasiadas primitivas
+ </notification>
+ <notification name="LinkFailedCantLinkNoCopyNoTrans">
+ Error de vínculo: no se pueden vincular &apos;no copiable&apos; y &apos;no transferible&apos;
+ </notification>
+ <notification name="LinkFailedNothingLinkable">
+ Error de vínculo: no hay objetos que se puedan vincular.
+ </notification>
+ <notification name="LinkFailedTooManyPathfindingChars">
+ Error de vínculo: demasiados personajes de pathfinding
+ </notification>
+ <notification name="LinkFailedInsufficientLand">
+ Error de vínculo: recursos de terreno insuficientes
+ </notification>
+ <notification name="LinkFailedTooMuchPhysics">
+ El objeto utiliza una cantidad excesiva de recursos de física; se ha desactivado su dinámica.
+ </notification>
+ <notification name="TeleportedHomeByObjectOnParcel">
+ Has sido teleportado al origen por el objeto &apos;[OBJECT_NAME]&apos; de la parcela &apos;[PARCEL_NAME]&apos;
+ </notification>
+ <notification name="TeleportedHomeByObject">
+ Has sido teleportado a tu origen por el objeto &apos;[OBJECT_NAME]&apos;
+ </notification>
+ <notification name="TeleportedByAttachment">
+ Has sido teleportado por un anexo de [ITEM_ID]
+ </notification>
+ <notification name="TeleportedByObjectOnParcel">
+ Has sido teleportado por el objeto &apos;[OBJECT_NAME]&apos; de la parcela &apos;[PARCEL_NAME]&apos;
+ </notification>
+ <notification name="TeleportedByObjectOwnedBy">
+ Has sido teleportado por el objeto &apos;[OBJECT_NAME]&apos; que es propiedad de [OWNER_ID]
+ </notification>
+ <notification name="TeleportedByObjectUnknownUser">
+ Has sido teleportado por el objeto &apos;[OBJECT_NAME]&apos; cuyo propietario es un usuario desconocido.
+ </notification>
+ <notification name="CantCreateObjectRegionFull">
+ No se puede crear el objeto solicitado. La región está llena.
+ </notification>
+ <notification name="CantAttackMultipleObjOneSpot">
+ No puedes anexar varios objetos a un solo lugar.
+ </notification>
+ <notification name="CantCreateMultipleObjAtLoc">
+ Aquí no se pueden crear varios objetos.
+ </notification>
+ <notification name="UnableToCreateObjTimeOut">
+ No se puede crear el objeto solicitado. El objeto no se encuentra en la base de datos.
+ </notification>
+ <notification name="UnableToCreateObjUnknown">
+ No se puede crear el objeto solicitado. Ha expirado el tiempo de la solicitud. Vuelve a intentarlo.
+ </notification>
+ <notification name="UnableToCreateObjMissingFromDB">
+ No se puede crear el objeto solicitado. Vuelve a intentarlo.
+ </notification>
+ <notification name="RezFailureTookTooLong">
+ Error al colocar: la carga del objeto solicitado ha tardado demasiado.
+ </notification>
+ <notification name="FailedToPlaceObjAtLoc">
+ Error al colocar el objeto en el lugar especificado. Vuelve a intentarlo.
+ </notification>
+ <notification name="CantCreatePlantsOnLand">
+ No se pueden crear plantas en este terreno.
+ </notification>
+ <notification name="CantRestoreObjectNoWorldPos">
+ No se puede restaurar el objeto. No se ha encontrado una posición del mundo.
+ </notification>
+ <notification name="CantRezObjectInvalidMeshData">
+ No se puede colocar el objeto porque sus datos de malla no son válidos.
+ </notification>
+ <notification name="CantRezObjectTooManyScripts">
+ No se puede colocar el objeto porque la región ya contiene demasiados scripts.
+ </notification>
+ <notification name="CantCreateObjectNoAccess">
+ Tus privilegios de acceso no te permiten crear objetos allí.
+ </notification>
+ <notification name="CantCreateObject">
+ Actualmente no tienes autorización para crear objetos.
+ </notification>
+ <notification name="InvalidObjectParams">
+ Los parámetros de objeto no son válidos
+ </notification>
+ <notification name="CantDuplicateObjectNoAcess">
+ Tus privilegios de acceso no te permiten duplicar objetos aquí.
+ </notification>
+ <notification name="CantChangeShape">
+ No tienes permiso para cambiar esta forma.
+ </notification>
+ <notification name="NoAccessToClaimObjects">
+ Tus privilegios de acceso no te permiten reclamar objetos aquí.
+ </notification>
+ <notification name="DeedFailedNoPermToDeedForGroup">
+ Error de transferencia: no tienes permiso para transferir objetos para tu grupo.
+ </notification>
+ <notification name="NoPrivsToBuyObject">
+ Tus privilegios de acceso no te autorizan a comprar objetos aquí.
+ </notification>
+ <notification name="CantAttachObjectAvatarSittingOnIt">
+ No se puede anexar el objeto porque un avatar está sentado en él.
+ </notification>
+ <notification name="WhyAreYouTryingToWearShrubbery">
+ No te puedes poner árboles y hierba como anexos.
+ </notification>
+ <notification name="CantAttachGroupOwnedObjs">
+ No se pueden anexar objetos que son propiedad de grupos.
+ </notification>
+ <notification name="CantAttachObjectsNotOwned">
+ No puedes anexar objetos de los que no eres propietario.
+ </notification>
+ <notification name="CantAttachNavmeshObjects">
+ No se pueden anexar objetos que contribuyen al navmesh.
+ </notification>
+ <notification name="CantAttachObjectNoMovePermissions">
+ No se puede anexar el objeto porque no tienes permiso para moverlo.
+ </notification>
+ <notification name="CantAttachNotEnoughScriptResources">
+ No hay suficientes recursos de script disponibles para anexar el objeto
+ </notification>
+ <notification name="CantDropItemTrialUser">
+ No se pueden soltar objetos aquí; inténtalo en la zona de prueba gratuita.
+ </notification>
+ <notification name="CantDropMeshAttachment">
+ No se pueden soltar anexos de la malla. Quítalos en el inventario y después colócalos en el mundo.
+ </notification>
+ <notification name="CantDropAttachmentNoPermission">
+ Error al soltar el anexo: no tienes permiso para soltarlo allí.
+ </notification>
+ <notification name="CantDropAttachmentInsufficientLandResources">
+ Error al soltar el anexo: recurso de terreno disponible insuficiente.
+ </notification>
+ <notification name="CantDropAttachmentInsufficientResources">
+ Error al soltar los anexos: los recursos disponibles son insuficientes.
+ </notification>
+ <notification name="CantDropObjectFullParcel">
+ No se puede soltar el objeto aquí. La parcela está llena.
+ </notification>
+ <notification name="CantTouchObjectBannedFromParcel">
+ No puedes tocar/agarrar este objeto porque tienes prohibida la entrada en la parcela de terreno.
+ </notification>
+ <notification name="PlzNarrowDeleteParams">
+ Acota los parámetros de eliminación.
+ </notification>
+ <notification name="UnableToUploadAsset">
+ No se puede subir el activo.
+ </notification>
+ <notification name="CantTeleportCouldNotFindUser">
+ No se ha podido encontrar el usuario para teleportarlo al origen
+ </notification>
+ <notification name="GodlikeRequestFailed">
+ error en la solicitud de superpoderes
+ </notification>
+ <notification name="GenericRequestFailed">
+ error de solicitud genérico
+ </notification>
+ <notification name="CantUploadPostcard">
+ No se puede subir la postal. Vuelve a intentarlo más tarde.
+ </notification>
+ <notification name="CantFetchInventoryForGroupNotice">
+ No se pueden obtener los datos de inventario del aviso de grupo.
+ </notification>
+ <notification name="CantSendGroupNoticeNotPermitted">
+ No se puede enviar el aviso de grupo: no está permitido.
+ </notification>
+ <notification name="CantSendGroupNoticeCantConstructInventory">
+ No se puede enviar el aviso del grupo: el inventario no se puede construir.
+ </notification>
+ <notification name="CantParceInventoryInNotice">
+ No se puede analizar el inventario del aviso.
+ </notification>
+ <notification name="TerrainUploadFailed">
+ Error al subir terreno.
+ </notification>
+ <notification name="TerrainFileWritten">
+ Se ha registrado el archivo de terreno.
+ </notification>
+ <notification name="TerrainFileWrittenStartingDownload">
+ Archivo de terreno registrado, iniciando la descarga...
+ </notification>
+ <notification name="TerrainBaked">
+ Terreno predeterminado.
+ </notification>
+ <notification name="TenObjectsDisabledPlzRefresh">
+ Solamente se han desactivado los 10 primeros objetos seleccionados. Si es preciso, actualiza y selecciona otros objetos.
+ </notification>
+ <notification name="UpdateViewerBuyParcel">
+ Para comprar esta parcela debes actualizar el visor.
+ </notification>
+ <notification name="CantBuyParcelNotForSale">
+ Error al comprar: esta parcela no está en venta.
+ </notification>
+ <notification name="CantBuySalePriceOrLandAreaChanged">
+ No se puede comprar: el precio de venta o la superficie del terreno han cambiado.
+ </notification>
+ <notification name="CantBuyParcelNotAuthorized">
+ No eres el comprador autorizado de esta parcela.
+ </notification>
+ <notification name="CantBuyParcelAwaitingPurchaseAuth">
+ No puedes comprar esta parcela porque ya está en espera de una autorización de compra
+ </notification>
+ <notification name="CantBuildOverflowParcel">
+ No se pueden construir objetos aquí porque se desbordaría la parcela.
+ </notification>
+ <notification name="SelectedMultipleOwnedLand">
+ Has seleccionado un terreno con propietarios diferentes. Selecciona un área más pequeña y repite la operación.
+ </notification>
+ <notification name="CantJoinTooFewLeasedParcels">
+ La selección no contiene suficientes parcelas alquiladas para unirlas.
+ </notification>
+ <notification name="CantDivideLandMultipleParcelsSelected">
+ No se puede dividir el terreno.\nHay varias parcelas seleccionadas.\nPrueba a seleccionar un terreno más pequeño.
+ </notification>
+ <notification name="CantDivideLandCantFindParcel">
+ No se puede dividir el terreno.\nNo se encuentra la parcela.\nAvísanos con Ayuda -&gt; Notificar fallo...
+ </notification>
+ <notification name="CantDivideLandWholeParcelSelected">
+ No se puede dividir el terreno. Está seleccionada la parcela completa.\nPrueba a seleccionar un terreno más pequeño.
+ </notification>
+ <notification name="LandHasBeenDivided">
+ El terreno se ha dividido.
+ </notification>
+ <notification name="PassPurchased">
+ Has comprado un pase.
+ </notification>
+ <notification name="RegionDisallowsClassifieds">
+ La región no permite anuncios.
+ </notification>
+ <notification name="LandPassExpireSoon">
+ Tu pase para este terreno está a punto de caducar.
+ </notification>
+ <notification name="CantSitNoSuitableSurface">
+ Esta superficie no es adecuada para sentarse, prueba en otro sitio.
+ </notification>
+ <notification name="CantSitNoRoom">
+ No hay sitio para sentarse aquí, prueba en otro lugar.
+ </notification>
+ <notification name="ClaimObjectFailedNoPermission">
+ Error al reclamar el objeto: no tienes permiso
+ </notification>
+ <notification name="ClaimObjectFailedNoMoney">
+ Error al reclamar el objeto: no tienes suficientes L$.
+ </notification>
+ <notification name="CantDeedGroupLand">
+ No se puede transferir un terreno propiedad de un grupo.
+ </notification>
+ <notification name="BuyObjectFailedNoMoney">
+ Error al comprar el objeto, no tienes suficientes L$.
+ </notification>
+ <notification name="BuyInventoryFailedNoMoney">
+ Error al comprar el inventario: no tienes suficientes L$.
+ </notification>
+ <notification name="BuyPassFailedNoMoney">
+ No tienes suficientes L$ para comprar un pase a este terreno.
+ </notification>
+ <notification name="CantBuyPassTryAgain">
+ No se puede comprar el pase ahora mismo. Vuelve a intentarlo más tarde.
+ </notification>
+ <notification name="CantCreateObjectParcelFull">
+ No se puede crear el objeto porque \nla parcela está llena.
+ </notification>
+ <notification name="FailedPlacingObject">
+ Error al colocar el objeto en el lugar especificado. Vuelve a intentarlo.
+ </notification>
+ <notification name="CantCreateLandmarkForEvent">
+ No se puede crear un hito para el evento.
+ </notification>
+ <notification name="GodBeatsFreeze">
+ ¡Tus superpoderes anulan la congelación!
+ </notification>
+ <notification name="SpecialPowersRequestFailedLogged">
+ Error en la solicitud de poderes especiales. Esta solicitud se ha registrado.
+ </notification>
+ <notification name="ExpireExplanation">
+ El sistema actualmente no puede procesar tu solicitud. Ha expirado el tiempo de la solicitud.
+ </notification>
+ <notification name="DieExplanation">
+ El sistema no puede procesar tu solicitud.
+ </notification>
+ <notification name="AddPrimitiveFailure">
+ Dinero insuficiente para crear la primitiva.
+ </notification>
+ <notification name="RezObjectFailure">
+ Dinero insuficiente para crear el objeto.
+ </notification>
+ <notification name="ResetHomePositionNotLegal">
+ Se ha restaurado la posición de origen, puesto que dicha posición no era válida.
+ </notification>
+ <notification name="CantInviteRegionFull">
+ Actualmente no puedes invitar a nadie a tu ubicación, puesto que la región está llena. Vuelve a intentarlo más tarde.
+ </notification>
+ <notification name="CantSetHomeAtRegion">
+ Esta región no te permite configurar aquí tu lugar de origen.
+ </notification>
+ <notification name="ListValidHomeLocations">
+ Tu &apos;Lugar de origen&apos; solo se puede configurar en tu terreno o en un punto de información del continente.
+ </notification>
+ <notification name="SetHomePosition">
+ Posición de origen ajustada.
+ </notification>
+ <notification name="CantDerezInventoryError">
+ No se puede quitar el objeto por un error del inventario.
+ </notification>
+ <notification name="CantCreateRequestedInv">
+ No se puede crear el inventario solicitado.
+ </notification>
+ <notification name="CantCreateRequestedInvFolder">
+ No se puede crear la carpeta de inventario solicitada.
+ </notification>
+ <notification name="CantCreateInventory">
+ No se puede crear el inventario.
+ </notification>
+ <notification name="CantCreateLandmark">
+ No se puede crear un hito.
+ </notification>
+ <notification name="CantCreateOutfit">
+ No se puede crear el vestuario en este momento. Prueba otra vez dentro de un minuto.
+ </notification>
+ <notification name="InventoryNotForSale">
+ El inventario no está en venta.
+ </notification>
+ <notification name="CantFindInvItem">
+ No se encuentra el objeto del inventario.
+ </notification>
+ <notification name="CantFindObject">
+ No se puede encontrar el objeto.
+ </notification>
+ <notification name="CantTransfterMoneyRegionDisabled">
+ En esta región actualmente no están activadas las transferencias de dinero a los objetos.
+ </notification>
+ <notification name="CantPayNoAgent">
+ No se ha averiguado a quién se debe pagar.
+ </notification>
+ <notification name="CantDonateToPublicObjects">
+ No se pueden dar L$ a los objetos públicos.
+ </notification>
+ <notification name="InventoryCreationInWorldObjectFailed">
+ Error al crear un inventario de objeto del mundo virtual.
+ </notification>
+ <notification name="UserBalanceOrLandUsageError">
+ Un error interno nos ha impedido actualizar tu visor correctamente. El saldo en L$ o las parcelas en propiedad presentadas en el visor podrían no coincidir con tu saldo real en los servidores.
+ </notification>
+ <notification name="LargePrimAgentIntersect">
+ No se pueden crear prims grandes que intersectan a otros jugadores. Reinténtalo cuando se hayan movido otros jugadores.
+ </notification>
+ <notification name="PreferenceChatClearLog">
+ Esto eliminará los registros de conversaciones anteriores y las copias de seguridad de ese archivo.
+ <usetemplate ignoretext="Confirmar antes de eliminar el registro de conversaciones anteriores." name="okcancelignore" notext="Cancelar" yestext="OK"/>
+ </notification>
+ <notification name="PreferenceChatDeleteTranscripts">
+ Esta acción eliminará las transcripciones de todas las conversaciones anteriores. La lista de conversaciones pasadas no resultará afectada. Se eliminarán de la carpeta [FOLDER] todos los archivos que tengan el sufijo .txt y txt.backup.
+ <usetemplate ignoretext="Confirmar antes de eliminar transcripciones." name="okcancelignore" notext="Cancelar" yestext="OK"/>
+ </notification>
+ <notification name="PreferenceChatPathChanged">
+ No se pueden mover los archivos. Ruta anterior restaurada.
+ <usetemplate ignoretext="No se pueden mover los archivos. Ruta anterior restaurada." name="okignore" yestext="OK"/>
+ </notification>
</notifications>
diff --git a/indra/newview/skins/default/xui/es/outfit_accordion_tab.xml b/indra/newview/skins/default/xui/es/outfit_accordion_tab.xml
index bac885e5d8..bac885e5d8 100644..100755
--- a/indra/newview/skins/default/xui/es/outfit_accordion_tab.xml
+++ b/indra/newview/skins/default/xui/es/outfit_accordion_tab.xml
diff --git a/indra/newview/skins/default/xui/es/panel_active_object_row.xml b/indra/newview/skins/default/xui/es/panel_active_object_row.xml
index 8d4fadb101..8d4fadb101 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_active_object_row.xml
+++ b/indra/newview/skins/default/xui/es/panel_active_object_row.xml
diff --git a/indra/newview/skins/default/xui/es/panel_adhoc_control_panel.xml b/indra/newview/skins/default/xui/es/panel_adhoc_control_panel.xml
index c64a93e0e5..c64a93e0e5 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_adhoc_control_panel.xml
+++ b/indra/newview/skins/default/xui/es/panel_adhoc_control_panel.xml
diff --git a/indra/newview/skins/default/xui/es/panel_avatar_list_item.xml b/indra/newview/skins/default/xui/es/panel_avatar_list_item.xml
index 5220df5d21..c73e34b299 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_avatar_list_item.xml
+++ b/indra/newview/skins/default/xui/es/panel_avatar_list_item.xml
@@ -26,5 +26,6 @@
<icon name="permission_edit_mine_icon" tool_tip="Este amigo puede editar, eliminar o manipular tus objetos"/>
<icon name="permission_map_icon" tool_tip="Este amigo puede encontrarte en el mapa"/>
<icon name="permission_online_icon" tool_tip="Este amigo puede ver cuándo estás conectado"/>
+ <button name="info_btn" tool_tip="Más información"/>
<button name="profile_btn" tool_tip="Ver el perfil"/>
</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_block_list_sidetray.xml b/indra/newview/skins/default/xui/es/panel_block_list_sidetray.xml
index cddbad1195..a3de14ae67 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_block_list_sidetray.xml
+++ b/indra/newview/skins/default/xui/es/panel_block_list_sidetray.xml
@@ -1,10 +1,11 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel name="block_list_panel">
- <text name="title_text">
- Lista de ignorados
- </text>
- <scroll_list name="blocked" tool_tip="Lista de los residentes ignorados actualmente"/>
- <button label="Ignorar al residente..." label_selected="Ignorar al residente..." name="Block resident..." tool_tip="Elige a un Residente para ignorarle"/>
- <button label="Ignorar objetos según el nombre..." label_selected="Ignorar objetos según el nombre..." name="Block object by name..."/>
- <button label="No ignorar" label_selected="No ignorar" name="Unblock" tool_tip="Quita al Residente o al objeto de la lista de ignorados"/>
+ <panel label="bottom_panel" name="blocked_buttons_panel">
+ <filter_editor label="Filtro" name="blocked_filter_input"/>
+ <menu_button name="blocked_gear_btn" tool_tip="Acciones en la persona o el objeto seleccionado"/>
+ <menu_button name="view_btn" tool_tip="Opciones de clasificación"/>
+ <menu_button name="plus_btn" tool_tip="Elige un residente o un objeto para ignorarlo"/>
+ <button name="unblock_btn" tool_tip="Quita al Residente o al objeto de la lista de ignorados"/>
+ </panel>
+ <block_list name="blocked" tool_tip="Lista de los residentes ignorados actualmente"/>
</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_body_parts_list_item.xml b/indra/newview/skins/default/xui/es/panel_body_parts_list_item.xml
index 8f4e0101aa..8f4e0101aa 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_body_parts_list_item.xml
+++ b/indra/newview/skins/default/xui/es/panel_body_parts_list_item.xml
diff --git a/indra/newview/skins/default/xui/es/panel_bodyparts_list_button_bar.xml b/indra/newview/skins/default/xui/es/panel_bodyparts_list_button_bar.xml
index 66ae7d868b..66ae7d868b 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_bodyparts_list_button_bar.xml
+++ b/indra/newview/skins/default/xui/es/panel_bodyparts_list_button_bar.xml
diff --git a/indra/newview/skins/default/xui/es/panel_bottomtray.xml b/indra/newview/skins/default/xui/es/panel_bottomtray.xml
deleted file mode 100644
index 2b1d017a2d..0000000000
--- a/indra/newview/skins/default/xui/es/panel_bottomtray.xml
+++ /dev/null
@@ -1,47 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel name="bottom_tray">
- <string name="DragIndicationImageName" value="Accordion_ArrowOpened_Off"/>
- <string name="SpeakBtnToolTip" value="Activa/Desactiva el micrófono"/>
- <string name="VoiceControlBtnToolTip" value="Muestra/Oculta el panel del control de voz"/>
- <layout_stack name="toolbar_stack">
- <layout_panel name="speak_panel">
- <talk_button name="talk">
- <speak_button label="Hablar" label_selected="Hablar" name="speak_btn"/>
- </talk_button>
- </layout_panel>
- <layout_panel name="gesture_panel">
- <gesture_combo_list label="Gestos" name="Gesture" tool_tip="Muestra/Oculta los gestos"/>
- </layout_panel>
- <layout_panel name="movement_panel">
- <bottomtray_button label="Moverme" name="movement_btn" tool_tip="Muestra/Oculta los controles del movimiento"/>
- </layout_panel>
- <layout_panel name="cam_panel">
- <bottomtray_button label="Visión" name="camera_btn" tool_tip="Muestra/Oculta los controles de la cámara"/>
- </layout_panel>
- <layout_panel name="snapshot_panel">
- <bottomtray_button label="" name="snapshots" tool_tip="Hacer una foto"/>
- </layout_panel>
- <layout_panel name="build_btn_panel">
- <bottomtray_button label="Construir" name="build_btn" tool_tip="Muestra/Oculta las herramientas de construcción"/>
- </layout_panel>
- <layout_panel name="search_btn_panel">
- <bottomtray_button label="Buscar" name="search_btn" tool_tip="Muestra/Oculta la búsqueda"/>
- </layout_panel>
- <layout_panel name="world_map_btn_panel">
- <bottomtray_button label="Mapa" name="world_map_btn" tool_tip="Muestra/Oculta el mapa del mundo"/>
- </layout_panel>
- <layout_panel name="mini_map_btn_panel">
- <bottomtray_button label="Minimapa" name="mini_map_btn" tool_tip="Muestra/Oculta el minimapa"/>
- </layout_panel>
- <layout_panel name="im_well_panel">
- <chiclet_im_well name="im_well">
- <button name="Unread IM messages" tool_tip="Conversaciones"/>
- </chiclet_im_well>
- </layout_panel>
- <layout_panel name="notification_well_panel">
- <chiclet_notification name="notification_well">
- <button name="Unread" tool_tip="Notificaciones"/>
- </chiclet_notification>
- </layout_panel>
- </layout_stack>
-</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_bottomtray_lite.xml b/indra/newview/skins/default/xui/es/panel_bottomtray_lite.xml
index 8d1b84a5fd..8d1b84a5fd 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_bottomtray_lite.xml
+++ b/indra/newview/skins/default/xui/es/panel_bottomtray_lite.xml
diff --git a/indra/newview/skins/default/xui/es/panel_chiclet_bar.xml b/indra/newview/skins/default/xui/es/panel_chiclet_bar.xml
index eaaa5dbe78..eaaa5dbe78 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_chiclet_bar.xml
+++ b/indra/newview/skins/default/xui/es/panel_chiclet_bar.xml
diff --git a/indra/newview/skins/default/xui/es/panel_classified_info.xml b/indra/newview/skins/default/xui/es/panel_classified_info.xml
index 3c168b9e53..3c168b9e53 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_classified_info.xml
+++ b/indra/newview/skins/default/xui/es/panel_classified_info.xml
diff --git a/indra/newview/skins/default/xui/es/panel_clothing_list_button_bar.xml b/indra/newview/skins/default/xui/es/panel_clothing_list_button_bar.xml
index d3b3d31bd9..d3b3d31bd9 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_clothing_list_button_bar.xml
+++ b/indra/newview/skins/default/xui/es/panel_clothing_list_button_bar.xml
diff --git a/indra/newview/skins/default/xui/es/panel_clothing_list_item.xml b/indra/newview/skins/default/xui/es/panel_clothing_list_item.xml
index 959b83d658..959b83d658 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_clothing_list_item.xml
+++ b/indra/newview/skins/default/xui/es/panel_clothing_list_item.xml
diff --git a/indra/newview/skins/default/xui/es/panel_cof_wearables.xml b/indra/newview/skins/default/xui/es/panel_cof_wearables.xml
index a2994894c1..a2994894c1 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_cof_wearables.xml
+++ b/indra/newview/skins/default/xui/es/panel_cof_wearables.xml
diff --git a/indra/newview/skins/default/xui/es/panel_conversation_list_item.xml b/indra/newview/skins/default/xui/es/panel_conversation_list_item.xml
new file mode 100644
index 0000000000..cc4a7e951d
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/panel_conversation_list_item.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="conversation_list_item">
+ <layout_stack name="conversation_item_stack">
+ <layout_panel name="conversation_title_panel">
+ <text name="conversation_title" value="(cargando)"/>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_conversation_log_list_item.xml b/indra/newview/skins/default/xui/es/panel_conversation_log_list_item.xml
new file mode 100644
index 0000000000..2fc8cd3aff
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/panel_conversation_log_list_item.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="conversation_log_list_item">
+ <icon name="voice_session_icon" tool_tip="La conversación incluía voz"/>
+ <icon name="unread_ims_icon" tool_tip="Han llegado mensajes mientras no tenías conexión"/>
+ <button name="delete_btn" tool_tip="Quitar esta entrada"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_deletable_wearable_list_item.xml b/indra/newview/skins/default/xui/es/panel_deletable_wearable_list_item.xml
index d1d7d8ec82..d1d7d8ec82 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_deletable_wearable_list_item.xml
+++ b/indra/newview/skins/default/xui/es/panel_deletable_wearable_list_item.xml
diff --git a/indra/newview/skins/default/xui/es/panel_dummy_clothing_list_item.xml b/indra/newview/skins/default/xui/es/panel_dummy_clothing_list_item.xml
index bc3046978c..bc3046978c 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_dummy_clothing_list_item.xml
+++ b/indra/newview/skins/default/xui/es/panel_dummy_clothing_list_item.xml
diff --git a/indra/newview/skins/default/xui/es/panel_edit_alpha.xml b/indra/newview/skins/default/xui/es/panel_edit_alpha.xml
index 829c206ae1..829c206ae1 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_edit_alpha.xml
+++ b/indra/newview/skins/default/xui/es/panel_edit_alpha.xml
diff --git a/indra/newview/skins/default/xui/es/panel_edit_classified.xml b/indra/newview/skins/default/xui/es/panel_edit_classified.xml
index ffad843732..ffad843732 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_edit_classified.xml
+++ b/indra/newview/skins/default/xui/es/panel_edit_classified.xml
diff --git a/indra/newview/skins/default/xui/es/panel_edit_eyes.xml b/indra/newview/skins/default/xui/es/panel_edit_eyes.xml
index 29a416f698..29a416f698 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_edit_eyes.xml
+++ b/indra/newview/skins/default/xui/es/panel_edit_eyes.xml
diff --git a/indra/newview/skins/default/xui/es/panel_edit_gloves.xml b/indra/newview/skins/default/xui/es/panel_edit_gloves.xml
index d536a862f5..d536a862f5 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_edit_gloves.xml
+++ b/indra/newview/skins/default/xui/es/panel_edit_gloves.xml
diff --git a/indra/newview/skins/default/xui/es/panel_edit_hair.xml b/indra/newview/skins/default/xui/es/panel_edit_hair.xml
index 25af1ea8cb..25af1ea8cb 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_edit_hair.xml
+++ b/indra/newview/skins/default/xui/es/panel_edit_hair.xml
diff --git a/indra/newview/skins/default/xui/es/panel_edit_jacket.xml b/indra/newview/skins/default/xui/es/panel_edit_jacket.xml
index 22a46a2f75..22a46a2f75 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_edit_jacket.xml
+++ b/indra/newview/skins/default/xui/es/panel_edit_jacket.xml
diff --git a/indra/newview/skins/default/xui/es/panel_edit_pants.xml b/indra/newview/skins/default/xui/es/panel_edit_pants.xml
index fb35e0953b..fb35e0953b 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_edit_pants.xml
+++ b/indra/newview/skins/default/xui/es/panel_edit_pants.xml
diff --git a/indra/newview/skins/default/xui/es/panel_edit_physics.xml b/indra/newview/skins/default/xui/es/panel_edit_physics.xml
index dfb5ab330a..dfb5ab330a 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_edit_physics.xml
+++ b/indra/newview/skins/default/xui/es/panel_edit_physics.xml
diff --git a/indra/newview/skins/default/xui/es/panel_edit_pick.xml b/indra/newview/skins/default/xui/es/panel_edit_pick.xml
index cda465da9c..cda465da9c 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_edit_pick.xml
+++ b/indra/newview/skins/default/xui/es/panel_edit_pick.xml
diff --git a/indra/newview/skins/default/xui/es/panel_edit_profile.xml b/indra/newview/skins/default/xui/es/panel_edit_profile.xml
index 8e5e09cfec..8e5e09cfec 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_edit_profile.xml
+++ b/indra/newview/skins/default/xui/es/panel_edit_profile.xml
diff --git a/indra/newview/skins/default/xui/es/panel_edit_shape.xml b/indra/newview/skins/default/xui/es/panel_edit_shape.xml
index 368be35ed9..368be35ed9 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_edit_shape.xml
+++ b/indra/newview/skins/default/xui/es/panel_edit_shape.xml
diff --git a/indra/newview/skins/default/xui/es/panel_edit_shirt.xml b/indra/newview/skins/default/xui/es/panel_edit_shirt.xml
index 73b712374e..73b712374e 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_edit_shirt.xml
+++ b/indra/newview/skins/default/xui/es/panel_edit_shirt.xml
diff --git a/indra/newview/skins/default/xui/es/panel_edit_shoes.xml b/indra/newview/skins/default/xui/es/panel_edit_shoes.xml
index 5e457612d5..5e457612d5 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_edit_shoes.xml
+++ b/indra/newview/skins/default/xui/es/panel_edit_shoes.xml
diff --git a/indra/newview/skins/default/xui/es/panel_edit_skin.xml b/indra/newview/skins/default/xui/es/panel_edit_skin.xml
index 8d895a6152..8d895a6152 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_edit_skin.xml
+++ b/indra/newview/skins/default/xui/es/panel_edit_skin.xml
diff --git a/indra/newview/skins/default/xui/es/panel_edit_skirt.xml b/indra/newview/skins/default/xui/es/panel_edit_skirt.xml
index 416d174298..416d174298 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_edit_skirt.xml
+++ b/indra/newview/skins/default/xui/es/panel_edit_skirt.xml
diff --git a/indra/newview/skins/default/xui/es/panel_edit_socks.xml b/indra/newview/skins/default/xui/es/panel_edit_socks.xml
index ac9b2a773e..ac9b2a773e 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_edit_socks.xml
+++ b/indra/newview/skins/default/xui/es/panel_edit_socks.xml
diff --git a/indra/newview/skins/default/xui/es/panel_edit_tattoo.xml b/indra/newview/skins/default/xui/es/panel_edit_tattoo.xml
index 8776dd6c10..8776dd6c10 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_edit_tattoo.xml
+++ b/indra/newview/skins/default/xui/es/panel_edit_tattoo.xml
diff --git a/indra/newview/skins/default/xui/es/panel_edit_underpants.xml b/indra/newview/skins/default/xui/es/panel_edit_underpants.xml
index aac8af44b9..aac8af44b9 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_edit_underpants.xml
+++ b/indra/newview/skins/default/xui/es/panel_edit_underpants.xml
diff --git a/indra/newview/skins/default/xui/es/panel_edit_undershirt.xml b/indra/newview/skins/default/xui/es/panel_edit_undershirt.xml
index c26c554c1a..c26c554c1a 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_edit_undershirt.xml
+++ b/indra/newview/skins/default/xui/es/panel_edit_undershirt.xml
diff --git a/indra/newview/skins/default/xui/es/panel_edit_wearable.xml b/indra/newview/skins/default/xui/es/panel_edit_wearable.xml
index 799512968d..799512968d 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_edit_wearable.xml
+++ b/indra/newview/skins/default/xui/es/panel_edit_wearable.xml
diff --git a/indra/newview/skins/default/xui/es/panel_group_control_panel.xml b/indra/newview/skins/default/xui/es/panel_group_control_panel.xml
index b398293175..b398293175 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_group_control_panel.xml
+++ b/indra/newview/skins/default/xui/es/panel_group_control_panel.xml
diff --git a/indra/newview/skins/default/xui/es/panel_group_general.xml b/indra/newview/skins/default/xui/es/panel_group_general.xml
index b00c300c85..b00c300c85 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_group_general.xml
+++ b/indra/newview/skins/default/xui/es/panel_group_general.xml
diff --git a/indra/newview/skins/default/xui/es/panel_group_info_sidetray.xml b/indra/newview/skins/default/xui/es/panel_group_info_sidetray.xml
index 09c4eec4d9..09c4eec4d9 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_group_info_sidetray.xml
+++ b/indra/newview/skins/default/xui/es/panel_group_info_sidetray.xml
diff --git a/indra/newview/skins/default/xui/es/panel_group_invite.xml b/indra/newview/skins/default/xui/es/panel_group_invite.xml
index 0d877f78f2..319e9d0f1b 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_group_invite.xml
+++ b/indra/newview/skins/default/xui/es/panel_group_invite.xml
@@ -9,6 +9,9 @@
<panel.string name="already_in_group">
Alguno de los Residentes que has elegido ya están en el grupo: no se les enviará la invitación.
</panel.string>
+ <panel.string name="invite_selection_too_large">
+ Las invitaciones al grupo no se han enviado: has seleccionado demasiados Residentes. Solo se permiten 100 invitaciones al grupo por solicitud.
+ </panel.string>
<text bottom_delta="-96" height="72" name="help_text" width="214">
Puedes elegir a varios Residentes para invitarles a tu grupo. Para empezar, pulsa &apos;Abrir el selector de residentes&apos;.
</text>
diff --git a/indra/newview/skins/default/xui/es/panel_group_land_money.xml b/indra/newview/skins/default/xui/es/panel_group_land_money.xml
index 3afb0f5665..3afb0f5665 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_group_land_money.xml
+++ b/indra/newview/skins/default/xui/es/panel_group_land_money.xml
diff --git a/indra/newview/skins/default/xui/es/panel_group_list_item.xml b/indra/newview/skins/default/xui/es/panel_group_list_item.xml
index 5c9f1c3688..4d682068d7 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_group_list_item.xml
+++ b/indra/newview/skins/default/xui/es/panel_group_list_item.xml
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel name="group_list_item">
<text name="group_name" value="Desconocido"/>
+ <button name="info_btn" tool_tip="Más información"/>
<button name="profile_btn" tool_tip="Ver el perfil"/>
</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_group_notices.xml b/indra/newview/skins/default/xui/es/panel_group_notices.xml
index 1eaa69abff..1eaa69abff 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_group_notices.xml
+++ b/indra/newview/skins/default/xui/es/panel_group_notices.xml
diff --git a/indra/newview/skins/default/xui/es/panel_group_notify.xml b/indra/newview/skins/default/xui/es/panel_group_notify.xml
index 7bdacbd1e0..7bdacbd1e0 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_group_notify.xml
+++ b/indra/newview/skins/default/xui/es/panel_group_notify.xml
diff --git a/indra/newview/skins/default/xui/es/panel_group_roles.xml b/indra/newview/skins/default/xui/es/panel_group_roles.xml
index 390b4e2e9d..390b4e2e9d 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_group_roles.xml
+++ b/indra/newview/skins/default/xui/es/panel_group_roles.xml
diff --git a/indra/newview/skins/default/xui/es/panel_im_control_panel.xml b/indra/newview/skins/default/xui/es/panel_im_control_panel.xml
index f218324d50..f218324d50 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_im_control_panel.xml
+++ b/indra/newview/skins/default/xui/es/panel_im_control_panel.xml
diff --git a/indra/newview/skins/default/xui/es/panel_inventory_item.xml b/indra/newview/skins/default/xui/es/panel_inventory_item.xml
index d18047fbcf..d18047fbcf 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_inventory_item.xml
+++ b/indra/newview/skins/default/xui/es/panel_inventory_item.xml
diff --git a/indra/newview/skins/default/xui/es/panel_landmark_info.xml b/indra/newview/skins/default/xui/es/panel_landmark_info.xml
index 1a0ac3ba79..1a0ac3ba79 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_landmark_info.xml
+++ b/indra/newview/skins/default/xui/es/panel_landmark_info.xml
diff --git a/indra/newview/skins/default/xui/es/panel_landmarks.xml b/indra/newview/skins/default/xui/es/panel_landmarks.xml
index b92685f0ae..b92685f0ae 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_landmarks.xml
+++ b/indra/newview/skins/default/xui/es/panel_landmarks.xml
diff --git a/indra/newview/skins/default/xui/es/panel_login.xml b/indra/newview/skins/default/xui/es/panel_login.xml
index 0e94cbe70b..1d7f077fe7 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_login.xml
+++ b/indra/newview/skins/default/xui/es/panel_login.xml
@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel name="panel_login">
- <panel.string name="create_account_url">
- http://join.secondlife.com/index.php?lang=es-ES
- </panel.string>
<panel.string name="forgot_password_url">
http://secondlife.com/account/request.php?lang=es
</panel.string>
<layout_stack name="login_widgets">
<layout_panel name="login">
+ <text name="log_in_text">
+ INICIAR SESIÓN
+ </text>
<text name="username_text">
Nombre de usuario:
</text>
@@ -15,34 +15,32 @@
<text name="password_text">
Contraseña:
</text>
- <check_box label="Recordar la contraseña" name="remember_check"/>
- <button label="Iniciar sesión" name="connect_btn"/>
- <text name="mode_selection_text">
- Modo:
- </text>
- <combo_box name="mode_combo" tool_tip="Selecciona el modo. Elige Básico para una exploración rápida y fácil y para chatear. Elige Avanzado para tener acceso a más funciones.">
- <combo_box.item label="Básico" name="Basic"/>
- <combo_box.item label="Avanzado" name="Advanced"/>
- </combo_box>
+ </layout_panel>
+ <layout_panel name="start_location_panel">
<text name="start_location_text">
Empezar en:
</text>
<combo_box name="start_location_combo">
<combo_box.item label="Mi última posición" name="MyLastLocation"/>
<combo_box.item label="Mi Base" name="MyHome"/>
- <combo_box.item label="&lt;Escribe en qué región&gt;" name="Typeregionname"/>
+ <combo_box.item label="&lt;Escribe el nombre de la región&gt;" name="Typeregionname"/>
</combo_box>
</layout_panel>
- <layout_panel name="links">
- <text name="create_new_account_text">
- Registrarme
+ <layout_panel name="links_login_panel">
+ <text name="login_help">
+ ¿Necesitas ayuda para conectarte?
</text>
<text name="forgot_password_text">
¿Olvidaste el nombre de usuario o la contraseña?
</text>
- <text name="login_help">
- ¿Necesitas ayuda para conectarte?
+ <button label="Iniciar sesión" name="connect_btn"/>
+ <check_box label="Recordar la contraseña" name="remember_check"/>
+ </layout_panel>
+ <layout_panel name="links">
+ <text name="create_account_text">
+ CREA TU CUENTA
</text>
+ <button label="Iniciar ahora" name="create_new_account_btn"/>
</layout_panel>
</layout_stack>
</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_main_inventory.xml b/indra/newview/skins/default/xui/es/panel_main_inventory.xml
index 7e318a150b..7e318a150b 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_main_inventory.xml
+++ b/indra/newview/skins/default/xui/es/panel_main_inventory.xml
diff --git a/indra/newview/skins/default/xui/es/panel_me.xml b/indra/newview/skins/default/xui/es/panel_me.xml
index 850cd6ec71..850cd6ec71 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_me.xml
+++ b/indra/newview/skins/default/xui/es/panel_me.xml
diff --git a/indra/newview/skins/default/xui/es/panel_media_settings_general.xml b/indra/newview/skins/default/xui/es/panel_media_settings_general.xml
index afc11a4250..afc11a4250 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_media_settings_general.xml
+++ b/indra/newview/skins/default/xui/es/panel_media_settings_general.xml
diff --git a/indra/newview/skins/default/xui/es/panel_media_settings_permissions.xml b/indra/newview/skins/default/xui/es/panel_media_settings_permissions.xml
index ec9edbfa15..ec9edbfa15 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_media_settings_permissions.xml
+++ b/indra/newview/skins/default/xui/es/panel_media_settings_permissions.xml
diff --git a/indra/newview/skins/default/xui/es/panel_media_settings_security.xml b/indra/newview/skins/default/xui/es/panel_media_settings_security.xml
index a1a3ec86cf..a1a3ec86cf 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_media_settings_security.xml
+++ b/indra/newview/skins/default/xui/es/panel_media_settings_security.xml
diff --git a/indra/newview/skins/default/xui/es/panel_navigation_bar.xml b/indra/newview/skins/default/xui/es/panel_navigation_bar.xml
index d36c6283bc..d36c6283bc 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_navigation_bar.xml
+++ b/indra/newview/skins/default/xui/es/panel_navigation_bar.xml
diff --git a/indra/newview/skins/default/xui/es/panel_nearby_chat.xml b/indra/newview/skins/default/xui/es/panel_nearby_chat.xml
index 4220ab3c9f..4220ab3c9f 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_nearby_chat.xml
+++ b/indra/newview/skins/default/xui/es/panel_nearby_chat.xml
diff --git a/indra/newview/skins/default/xui/es/panel_nearby_chat_bar.xml b/indra/newview/skins/default/xui/es/panel_nearby_chat_bar.xml
index af2b6e920b..e6ca59f912 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_nearby_chat_bar.xml
+++ b/indra/newview/skins/default/xui/es/panel_nearby_chat_bar.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel name="chat_bar">
+<panel name="nearby_chat">
<line_editor label="Pulsa aquí para chatear." name="chat_box" tool_tip="Pulsa Enter para decirlo o Ctrl+Enter para gritarlo"/>
<button name="show_nearby_chat" tool_tip="Muestra o esconde el registro del chat"/>
</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_nearby_media.xml b/indra/newview/skins/default/xui/es/panel_nearby_media.xml
index 8d4f9eda18..8d4f9eda18 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_nearby_media.xml
+++ b/indra/newview/skins/default/xui/es/panel_nearby_media.xml
diff --git a/indra/newview/skins/default/xui/es/panel_notify_textbox.xml b/indra/newview/skins/default/xui/es/panel_notify_textbox.xml
index dc7c873303..dc7c873303 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_notify_textbox.xml
+++ b/indra/newview/skins/default/xui/es/panel_notify_textbox.xml
diff --git a/indra/newview/skins/default/xui/es/panel_online_status_toast.xml b/indra/newview/skins/default/xui/es/panel_online_status_toast.xml
index fdc489f375..fdc489f375 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_online_status_toast.xml
+++ b/indra/newview/skins/default/xui/es/panel_online_status_toast.xml
diff --git a/indra/newview/skins/default/xui/es/panel_outbox_inventory.xml b/indra/newview/skins/default/xui/es/panel_outbox_inventory.xml
index 9e2f3c3adc..9e2f3c3adc 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_outbox_inventory.xml
+++ b/indra/newview/skins/default/xui/es/panel_outbox_inventory.xml
diff --git a/indra/newview/skins/default/xui/es/panel_outfit_edit.xml b/indra/newview/skins/default/xui/es/panel_outfit_edit.xml
index 9e669995aa..9e669995aa 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_outfit_edit.xml
+++ b/indra/newview/skins/default/xui/es/panel_outfit_edit.xml
diff --git a/indra/newview/skins/default/xui/es/panel_outfits_inventory.xml b/indra/newview/skins/default/xui/es/panel_outfits_inventory.xml
index 1107e72b54..1107e72b54 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_outfits_inventory.xml
+++ b/indra/newview/skins/default/xui/es/panel_outfits_inventory.xml
diff --git a/indra/newview/skins/default/xui/es/panel_outfits_inventory_gear_default.xml b/indra/newview/skins/default/xui/es/panel_outfits_inventory_gear_default.xml
index 8f805c3d18..8f805c3d18 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_outfits_inventory_gear_default.xml
+++ b/indra/newview/skins/default/xui/es/panel_outfits_inventory_gear_default.xml
diff --git a/indra/newview/skins/default/xui/es/panel_outfits_list.xml b/indra/newview/skins/default/xui/es/panel_outfits_list.xml
index 3f8057f242..3f8057f242 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_outfits_list.xml
+++ b/indra/newview/skins/default/xui/es/panel_outfits_list.xml
diff --git a/indra/newview/skins/default/xui/es/panel_outfits_wearing.xml b/indra/newview/skins/default/xui/es/panel_outfits_wearing.xml
index 8cea619bd5..8cea619bd5 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_outfits_wearing.xml
+++ b/indra/newview/skins/default/xui/es/panel_outfits_wearing.xml
diff --git a/indra/newview/skins/default/xui/es/panel_people.xml b/indra/newview/skins/default/xui/es/panel_people.xml
index a9d38dca25..06150f7619 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_people.xml
+++ b/indra/newview/skins/default/xui/es/panel_people.xml
@@ -14,81 +14,56 @@
<string name="no_filtered_friends_msg">
¿No encuentras lo que buscas? Prueba con [secondlife:///app/search/people/[SEARCH_TERM] Buscar].
</string>
- <string name="people_filter_label" value="Filtrar a la gente"/>
- <string name="groups_filter_label" value="Filtrar a los grupos"/>
<string name="no_filtered_groups_msg" value="¿No encuentras lo que buscas? Prueba con [secondlife:///app/search/groups/[SEARCH_TERM] Buscar]."/>
<string name="no_groups_msg" value="¿Buscas grupos en que participar? Prueba la [secondlife:///app/search/groups Búsqueda]."/>
<string name="MiniMapToolTipMsg" value="[REGION](Pulsa dos veces para abrir el mapa, pulsa mayús y arrastra para obtener una panorámica)"/>
<string name="AltMiniMapToolTipMsg" value="[REGION](Pulsa dos veces para teleportarte, pulsa mayús y arrastra para obtener una panorámica)"/>
- <filter_editor label="Filtrar" name="filter_input"/>
<tab_container name="tabs">
<panel label="CERCANA" name="nearby_panel">
- <panel label="bottom_panel" name="bottom_panel">
- <menu_button name="nearby_view_sort_btn" tool_tip="Opciones"/>
- <button name="add_friend_btn" tool_tip="Añadir al Residente seleccionado a la lista de tus amigos"/>
+ <panel label="bottom_panel" name="nearby_buttons_panel">
+ <filter_editor label="Filtrar la gente" name="nearby_filter_input"/>
+ <button name="gear_btn" tool_tip="Acciones en la persona seleccionada"/>
+ <menu_button name="nearby_view_btn" tool_tip="Opciones de vista/orden"/>
+ <button name="add_friend_btn" tool_tip="Ofrecer amistad a un residente"/>
+ <dnd_button name="nearby_del_btn" tool_tip="Quitar la persona seleccionada de la lista de amigos"/>
</panel>
</panel>
- <panel label="MIS AMIGOS" name="friends_panel">
+ <panel label="AMIGOS" name="friends_panel">
+ <panel label="bottom_panel" name="friends_buttons_panel">
+ <filter_editor label="Filtrar la gente" name="friends_filter_input"/>
+ <button name="gear_btn" tool_tip="Acciones en la persona seleccionada"/>
+ <menu_button name="friends_view_btn" tool_tip="Opciones de vista/orden"/>
+ <button name="friends_add_btn" tool_tip="Ofrecer amistad a un residente"/>
+ <dnd_button name="friends_del_btn" tool_tip="Quitar la persona seleccionada de la lista de amigos"/>
+ </panel>
<accordion name="friends_accordion">
<accordion_tab name="tab_online" title="Conectado"/>
<accordion_tab name="tab_all" title="Todos"/>
</accordion>
- <panel label="bottom_panel" name="bottom_panel">
- <layout_stack name="bottom_panel">
- <layout_panel name="options_gear_btn_panel">
- <menu_button name="friends_viewsort_btn" tool_tip="Ver más opciones"/>
- </layout_panel>
- <layout_panel name="add_btn_panel">
- <button name="add_btn" tool_tip="Ofrecer amistad a un Residente"/>
- </layout_panel>
- <layout_panel name="trash_btn_panel">
- <dnd_button name="del_btn" tool_tip="Quitar a la persona seleccionada de tu lista de amigos"/>
- </layout_panel>
- </layout_stack>
- </panel>
</panel>
- <panel label="MIS GRUPOS" name="groups_panel">
- <panel label="bottom_panel" name="bottom_panel">
- <menu_button name="groups_viewsort_btn" tool_tip="Opciones"/>
- <button name="plus_btn" tool_tip="Entrar en un grupo o crear uno"/>
- <button name="activate_btn" tool_tip="Activar el grupo seleccionado"/>
+ <panel label="GRUPOS" name="groups_panel">
+ <panel label="bottom_panel" name="groups_buttons_panel">
+ <filter_editor label="Filtrar los grupos" name="groups_filter_input"/>
+ <menu_button name="groups_gear_btn" tool_tip="Acciones en el grupo seleccionado"/>
+ <menu_button name="groups_view_btn" tool_tip="Opciones de vista/orden"/>
+ <menu_button name="plus_btn" tool_tip="Entrar en un grupo o crear uno"/>
+ <dnd_button name="minus_btn" tool_tip="Dejar el grupo seleccionado"/>
</panel>
+ <text name="groupcount">
+ Formas parte de [COUNT] grupos y puedes unirte a [REMAINING] más.
+ </text>
</panel>
<panel label="RECIENTE" name="recent_panel">
- <panel label="bottom_panel" name="bottom_panel">
- <menu_button name="recent_viewsort_btn" tool_tip="Opciones"/>
- <button name="add_friend_btn" tool_tip="Añadir al Residente seleccionado a la lista de tus amigos"/>
+ <panel label="bottom_panel" name="recent_buttons_panel">
+ <filter_editor label="Filtrar la gente" name="recent_filter_input"/>
+ <button name="gear_btn" tool_tip="Acciones en la persona seleccionada"/>
+ <menu_button name="recent_view_btn" tool_tip="Opciones de vista/orden"/>
+ <button name="add_friend_btn" tool_tip="Ofrecer amistad a un residente"/>
+ <dnd_button name="recent_del_btn" tool_tip="Quitar la persona seleccionada de la lista de amigos"/>
</panel>
</panel>
+ <panel label="BLOQUEADO" name="blocked_panel">
+ <panel label="Residentes y objetos ignorados" name="panel_block_list_sidetray"/>
+ </panel>
</tab_container>
- <panel name="button_bar">
- <layout_stack name="bottom_bar_ls">
- <layout_panel name="view_profile_btn_lp">
- <button label="Perfil" name="view_profile_btn" tool_tip="Mostrar imágenes, grupos y otra información del Residente"/>
- </layout_panel>
- <layout_panel name="im_btn_lp">
- <button label="MI" name="im_btn" tool_tip="Abrir una sesión de mensajes instantáneos"/>
- </layout_panel>
- <layout_panel name="call_btn_lp">
- <button label="Llamar" name="call_btn" tool_tip="Llamar a este Residente"/>
- </layout_panel>
- <layout_panel name="share_btn_lp">
- <button label="Compartir" name="share_btn" tool_tip="Compartir un objeto del inventario"/>
- </layout_panel>
- <layout_panel name="teleport_btn_lp">
- <button label="Teleporte" name="teleport_btn" tool_tip="Ofrecer teleporte"/>
- </layout_panel>
- </layout_stack>
- <layout_stack name="bottom_bar_ls1">
- <layout_panel name="group_info_btn_lp">
- <button label="Perfil del grupo" name="group_info_btn" tool_tip="Ver la información del grupo"/>
- </layout_panel>
- <layout_panel name="chat_btn_lp">
- <button label="Chat de grupo" name="chat_btn" tool_tip="Abrir el chat"/>
- </layout_panel>
- <layout_panel name="group_call_btn_lp">
- <button label="Llamar al grupo" name="group_call_btn" tool_tip="Llama a este grupo"/>
- </layout_panel>
- </layout_stack>
- </panel>
</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_pick_info.xml b/indra/newview/skins/default/xui/es/panel_pick_info.xml
index 3450279b4a..3450279b4a 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_pick_info.xml
+++ b/indra/newview/skins/default/xui/es/panel_pick_info.xml
diff --git a/indra/newview/skins/default/xui/es/panel_picks.xml b/indra/newview/skins/default/xui/es/panel_picks.xml
index 904cdd12f1..904cdd12f1 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_picks.xml
+++ b/indra/newview/skins/default/xui/es/panel_picks.xml
diff --git a/indra/newview/skins/default/xui/es/panel_place_profile.xml b/indra/newview/skins/default/xui/es/panel_place_profile.xml
index e1cf1332e2..e1cf1332e2 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_place_profile.xml
+++ b/indra/newview/skins/default/xui/es/panel_place_profile.xml
diff --git a/indra/newview/skins/default/xui/es/panel_places.xml b/indra/newview/skins/default/xui/es/panel_places.xml
index e9984b4512..e9984b4512 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_places.xml
+++ b/indra/newview/skins/default/xui/es/panel_places.xml
diff --git a/indra/newview/skins/default/xui/es/panel_postcard_message.xml b/indra/newview/skins/default/xui/es/panel_postcard_message.xml
index 7316d91f5c..7316d91f5c 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_postcard_message.xml
+++ b/indra/newview/skins/default/xui/es/panel_postcard_message.xml
diff --git a/indra/newview/skins/default/xui/es/panel_postcard_settings.xml b/indra/newview/skins/default/xui/es/panel_postcard_settings.xml
index 3931319447..3931319447 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_postcard_settings.xml
+++ b/indra/newview/skins/default/xui/es/panel_postcard_settings.xml
diff --git a/indra/newview/skins/default/xui/es/panel_preferences_advanced.xml b/indra/newview/skins/default/xui/es/panel_preferences_advanced.xml
index 620a95de4d..620a95de4d 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_preferences_advanced.xml
+++ b/indra/newview/skins/default/xui/es/panel_preferences_advanced.xml
diff --git a/indra/newview/skins/default/xui/es/panel_preferences_alerts.xml b/indra/newview/skins/default/xui/es/panel_preferences_alerts.xml
index f34edf149e..f34edf149e 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_preferences_alerts.xml
+++ b/indra/newview/skins/default/xui/es/panel_preferences_alerts.xml
diff --git a/indra/newview/skins/default/xui/es/panel_preferences_chat.xml b/indra/newview/skins/default/xui/es/panel_preferences_chat.xml
index aea9b9ce4a..7feff9005c 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/es/panel_preferences_chat.xml
@@ -1,33 +1,99 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel label="Chat de texto" name="chat">
- <text name="font_size">
- Tamaño de la fuente:
- </text>
- <radio_group name="chat_font_size">
- <radio_item label="Disminuir" name="radio" value="0"/>
- <radio_item label="Medio" name="radio2" value="1"/>
- <radio_item label="Aumentar" name="radio3" value="2"/>
- </radio_group>
- <check_box initial_value="true" label="Ejecutar la animación de escribir al hacerlo en el chat" name="play_typing_animation"/>
- <check_box label="Cuando estoy desconectado, enviarme los MI al correo-e" name="send_im_to_email"/>
- <check_box label="Permitir el historial de MI y chat en texto sin formato" name="plain_text_chat_history"/>
- <check_box label="Bocadillos del chat" name="bubble_text_chat"/>
- <text name="show_ims_in_label">
- Mostrar los MI en:
- </text>
- <text name="requires_restart_label">
- (requiere reiniciar)
- </text>
- <radio_group name="chat_window" tool_tip="Muestra tus mensajes instantáneos en varias ventanas flotantes o en una sola con varias pestañas (requiere que reinicies)">
- <radio_item label="Ventanas distintas" name="radio" value="0"/>
- <radio_item label="Pestañas" name="radio2" value="1"/>
- </radio_group>
- <text name="disable_toast_label">
- Permitir ventanas de chat emergentes:
- </text>
- <check_box label="Chats de grupo" name="EnableGroupChatPopups" tool_tip="Activa esta casilla para ver una ventana emergente cada vez que recibas un mensaje de un grupo de chat"/>
- <check_box label="Chats de MI" name="EnableIMChatPopups" tool_tip="Activa esta casilla para ver una ventana emergente cada vez que recibas un mensaje instantáneo"/>
- <spinner label="Duración de los interlocutores favoritos:" name="nearby_toasts_lifetime"/>
- <spinner label="Tiempo de los otros interlocutores:" name="nearby_toasts_fadingtime"/>
- <button label="Configuración de la traducción del chat" name="ok_btn"/>
+ <panel name="general_chat_settings">
+ <check_box initial_value="true" label="Ejecutar la animación de escribir al hacerlo en el chat" name="play_typing_animation"/>
+ <check_box label="Cuando estoy desconectado, enviarme los MI al correo-e" name="send_im_to_email"/>
+ <check_box label="Sólo pueden llamarme o mandarme un MI mis amigos y grupos" name="voice_call_friends_only_check"/>
+ <text name="font_size">
+ Tamaño de la fuente:
+ </text>
+ <combo_box name="chat_font_size">
+ <item label="Pequeño" name="Small" value="0"/>
+ <item label="Medio" name="Medium" value="1"/>
+ <item label="Grande" name="Large" value="2"/>
+ </combo_box>
+ <check_box label="Bocadillos del chat" name="bubble_text_chat"/>
+ </panel>
+ <panel name="im_notification_settings">
+ <text name="friend_ims">
+ MI de amigos:
+ </text>
+ <combo_box name="FriendIMOptions">
+ <item label="Abrir ventana de conversaciones" name="OpenConversationsWindow" value="openconversations"/>
+ <item label="Abrir el mensaje en una ventana emergente" name="PopUpMessage" value="toast"/>
+ <item label="Botón de la barra de herramientas de Flash" name="FlashToolbarButton" value="flash"/>
+ <item label="Ninguna acción" name="NoAction" value="noaction"/>
+ </combo_box>
+ <check_box label="Reproducir sonido" name="play_sound_friend_im"/>
+ <text name="non_friend_ims">
+ MI de no amigos:
+ </text>
+ <combo_box name="NonFriendIMOptions">
+ <item label="Abrir ventana de conversaciones" name="OpenConversationsWindow" value="openconversations"/>
+ <item label="Abrir el mensaje en una ventana emergente" name="PopUpMessage" value="toast"/>
+ <item label="Botón de la barra de herramientas de Flash" name="FlashToolbarButton" value="flash"/>
+ <item label="Ninguna acción" name="NoAction" value="noaction"/>
+ </combo_box>
+ <check_box label="Reproducir sonido" name="play_sound_non_friend_im"/>
+ <text name="conference_ims">
+ MI de conferencias:
+ </text>
+ <combo_box name="ConferenceIMOptions">
+ <item label="Abrir ventana de conversaciones" name="OpenConversationsWindow" value="openconversations"/>
+ <item label="Abrir el mensaje en una ventana emergente" name="PopUpMessage" value="toast"/>
+ <item label="Botón de la barra de herramientas de Flash" name="FlashToolbarButton" value="flash"/>
+ <item label="Ninguna acción" name="NoAction" value="noaction"/>
+ </combo_box>
+ <check_box label="Reproducir sonido" name="play_sound_conference_im"/>
+ <text name="group_chat">
+ Chat de grupo:
+ </text>
+ <combo_box name="GroupChatOptions">
+ <item label="Abrir ventana de conversaciones" name="OpenConversationsWindow" value="openconversations"/>
+ <item label="Abrir el mensaje en una ventana emergente" name="PopUpMessage" value="toast"/>
+ <item label="Botón de la barra de herramientas de Flash" name="FlashToolbarButton" value="flash"/>
+ <item label="Ninguna acción" name="NoAction" value="noaction"/>
+ </combo_box>
+ <check_box label="Reproducir sonido" name="play_sound_group_chat_im"/>
+ <text name="nearby_chat">
+ Chat con gente cercana:
+ </text>
+ <combo_box name="NearbyChatOptions">
+ <item label="Abrir ventana de conversaciones" name="OpenConversationsWindow" value="openconversations"/>
+ <item label="Abrir el mensaje en una ventana emergente" name="PopUpMessage" value="toast"/>
+ <item label="Botón de la barra de herramientas de Flash" name="FlashToolBarButton" value="flash"/>
+ <item label="Ninguna acción" name="NoAction" value="noaction"/>
+ </combo_box>
+ <check_box label="Reproducir sonido" name="play_sound_nearby_chat_im"/>
+ <text name="object_ims">
+ MI de objetos:
+ </text>
+ <combo_box name="ObjectIMOptions">
+ <item label="Abrir ventana de conversaciones" name="OpenConversationsWindow" value="openconversations"/>
+ <item label="Abrir el mensaje en una ventana emergente" name="PopUpMessage" value="toast"/>
+ <item label="Botón de la barra de herramientas de Flash" name="FlashToolBarButton" value="flash"/>
+ <item label="Ninguna acción" name="NoAction" value="noaction"/>
+ </combo_box>
+ <check_box label="Reproducir sonido" name="play_sound_object_im"/>
+ <text name="notifications_alert">
+ Para dejar de recibir avisos durante un tiempo, usa Comunicarme &gt; No molestar.
+ </text>
+ </panel>
+ <panel name="play_sound_settings">
+ <text name="play_sound">
+ Reproducir sonido:
+ </text>
+ <check_box label="Nueva conversación" name="new_conversation"/>
+ <check_box label="Llamada de voz entrante" name="incoming_voice_call"/>
+ <check_box label="Oferta de teleporte" name="teleport_offer"/>
+ <check_box label="Oferta de inventario" name="inventory_offer"/>
+ </panel>
+ <panel name="log_settings">
+ <button label="Borrar registro..." name="clear_log"/>
+ <button label="Borrar grabaciones..." name="delete_transcripts"/>
+ <button label="Examinar..." label_selected="Examinar" name="log_path_button"/>
+ </panel>
+ <button label="Traducción…" name="ok_btn"/>
+ <button label="Reemplazo automático..." name="autoreplace_showgui"/>
+ <button label="Revisión ortográfica..." name="spellcheck_showgui"/>
</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_preferences_colors.xml b/indra/newview/skins/default/xui/es/panel_preferences_colors.xml
index d47a6d718a..d47a6d718a 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_preferences_colors.xml
+++ b/indra/newview/skins/default/xui/es/panel_preferences_colors.xml
diff --git a/indra/newview/skins/default/xui/es/panel_preferences_general.xml b/indra/newview/skins/default/xui/es/panel_preferences_general.xml
index 4fc163f5b6..98b0081da9 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_preferences_general.xml
+++ b/indra/newview/skins/default/xui/es/panel_preferences_general.xml
@@ -69,6 +69,9 @@
<combo_box.item label="nunca" name="item4"/>
</combo_box>
<text name="text_box3">
- Respuesta cuando estoy en modo ocupado:
+ Respuesta de No molestar:
</text>
+ <text_editor name="do_not_disturb_response">
+ log_in_to_change
+ </text_editor>
</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/es/panel_preferences_graphics1.xml
index 281b871fed..a9eab74e2b 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_preferences_graphics1.xml
+++ b/indra/newview/skins/default/xui/es/panel_preferences_graphics1.xml
@@ -25,14 +25,14 @@
<text name="ShadersText">
Shaders:
</text>
- <check_box initial_value="verdadero" label="Agua transparente" name="TransparentWater"/>
+ <check_box initial_value="true" label="Agua transparente" name="TransparentWater"/>
<check_box initial_value="true" label="Efecto de relieve y brillo" name="BumpShiny"/>
- <check_box initial_value="verdadero" label="Luces locales" name="LocalLights"/>
+ <check_box initial_value="true" label="Luces locales" name="LocalLights"/>
<check_box initial_value="true" label="Shaders básicos" name="BasicShaders" tool_tip="Desactivando esta opción puede prevenir fallos en algunos controladores de la tarjeta gráfica."/>
<check_box initial_value="true" label="Shaders de la atmósfera" name="WindLightUseAtmosShaders"/>
- <check_box initial_value="verdadero" label="Luces y sombras" name="UseLightShaders"/>
- <check_box initial_value="verdadero" label="Oclusión del ambiente" name="UseSSAO"/>
- <check_box initial_value="verdadero" label="Profundidad del campo" name="UseDoF"/>
+ <check_box initial_value="true" label="Modelo de iluminación avanzado" name="UseLightShaders"/>
+ <check_box initial_value="true" label="Oclusión del ambiente" name="UseSSAO"/>
+ <check_box initial_value="true" label="Profundidad del campo" name="UseDoF"/>
<text name="shadows_label">
Sombras:
</text>
diff --git a/indra/newview/skins/default/xui/es/panel_preferences_move.xml b/indra/newview/skins/default/xui/es/panel_preferences_move.xml
index b2ff6b61c2..b2ff6b61c2 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_preferences_move.xml
+++ b/indra/newview/skins/default/xui/es/panel_preferences_move.xml
diff --git a/indra/newview/skins/default/xui/es/panel_preferences_privacy.xml b/indra/newview/skins/default/xui/es/panel_preferences_privacy.xml
index c162130af6..c162130af6 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_preferences_privacy.xml
+++ b/indra/newview/skins/default/xui/es/panel_preferences_privacy.xml
diff --git a/indra/newview/skins/default/xui/es/panel_preferences_setup.xml b/indra/newview/skins/default/xui/es/panel_preferences_setup.xml
index 81a29dae5a..508bfbcd32 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_preferences_setup.xml
+++ b/indra/newview/skins/default/xui/es/panel_preferences_setup.xml
@@ -21,7 +21,7 @@
<check_box initial_value="true" label="Activar plugins" name="browser_plugins_enabled"/>
<check_box initial_value="true" label="Aceptar las &apos;cookies&apos;" name="cookies_enabled"/>
<check_box initial_value="true" label="Activar Javascript" name="browser_javascript_enabled"/>
- <check_box initial_value="falso" label="Permitir las ventanas emergentes en el navegador" name="media_popup_enabled"/>
+ <check_box initial_value="false" label="Permitir las ventanas emergentes en el navegador" name="media_popup_enabled"/>
<text name="Software updates:">
Actualizaciones de software:
</text>
@@ -29,6 +29,7 @@
<combo_box.item label="Instalar automáticamente" name="Install_automatically"/>
<combo_box.item label="Descargar e instalar actualizaciones manualmente" name="Install_manual"/>
</combo_box>
+ <check_box label="Admitir candidatos a la versión comercial a la hora de realizar actualizaciones" name="update_willing_to_test"/>
<text name="Proxy Settings:">
Configuración de proxy:
</text>
diff --git a/indra/newview/skins/default/xui/es/panel_preferences_sound.xml b/indra/newview/skins/default/xui/es/panel_preferences_sound.xml
index 5cb1654c70..dcd6984715 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_preferences_sound.xml
+++ b/indra/newview/skins/default/xui/es/panel_preferences_sound.xml
@@ -19,7 +19,7 @@
<check_box label="Activado" name="enable_voice_check"/>
<check_box label="Permitir la ejecución automática de los media" name="media_auto_play_btn" tool_tip="Marcar esto para permitir la ejecución automática de los media" value="true"/>
<check_box label="Ejecutar para otros avatares los media anexados" name="media_show_on_others_btn" tool_tip="Al desmarcar esto se esconderán los media anexados a otros avatares cercanos" value="true"/>
- <check_box label="Reproducir sonidos de los gestos" name="gesture_audio_play_btn" tool_tip="Selecciona esta opción para escuchar los sonidos de los gestos" value="verdadero"/>
+ <check_box label="Reproducir sonidos de los gestos" name="gesture_audio_play_btn" tool_tip="Selecciona esta opción para escuchar los sonidos de los gestos" value="true"/>
<text name="voice_chat_settings">
Configuración del chat de voz
</text>
diff --git a/indra/newview/skins/default/xui/es/panel_prim_media_controls.xml b/indra/newview/skins/default/xui/es/panel_prim_media_controls.xml
index 90b9e475e7..90b9e475e7 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_prim_media_controls.xml
+++ b/indra/newview/skins/default/xui/es/panel_prim_media_controls.xml
diff --git a/indra/newview/skins/default/xui/es/panel_region_covenant.xml b/indra/newview/skins/default/xui/es/panel_region_covenant.xml
index 2beacda235..2beacda235 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_region_covenant.xml
+++ b/indra/newview/skins/default/xui/es/panel_region_covenant.xml
diff --git a/indra/newview/skins/default/xui/es/panel_region_debug.xml b/indra/newview/skins/default/xui/es/panel_region_debug.xml
index 64162220a6..71bdba1a25 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_region_debug.xml
+++ b/indra/newview/skins/default/xui/es/panel_region_debug.xml
@@ -36,5 +36,5 @@
<button label="?" left="297" name="top_scripts_help"/>
<button label="Reiniciar la región" name="restart_btn" tool_tip="Cuenta atrás de 2 minutos y reiniciar la región"/>
<button label="?" name="restart_help"/>
- <button label="Retrasar el reinicio" name="cancel_restart_btn" tool_tip="Retrasar una hora el reinicio de la región"/>
+ <button label="Cancelar reinicio" name="cancel_restart_btn" tool_tip="Cancelar el reinicio de región"/>
</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_region_environment.xml b/indra/newview/skins/default/xui/es/panel_region_environment.xml
index a73f1deed4..a73f1deed4 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_region_environment.xml
+++ b/indra/newview/skins/default/xui/es/panel_region_environment.xml
diff --git a/indra/newview/skins/default/xui/es/panel_region_estate.xml b/indra/newview/skins/default/xui/es/panel_region_estate.xml
index 84c1ed7686..6089dfb8db 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_region_estate.xml
+++ b/indra/newview/skins/default/xui/es/panel_region_estate.xml
@@ -26,7 +26,7 @@
Permitir únicamente el acceso a los Residentes que:
</text>
<check_box label="Han aportado la información de pago." name="limit_payment" tool_tip="Para poder acceder a este estado los Residentes deben haber aportado información de pago en su cuenta. Para más información, ver [SUPPORT_SITE]."/>
- <check_box label="Han verificado su edad" name="limit_age_verified" tool_tip="Para poder acceder a este estado los Residentes deben haber verificado su edad. Para más información, ver [SUPPORT_SITE]."/>
+ <check_box label="Son mayores de 18 años" name="limit_age_verified" tool_tip="Para poder acceder a este estado, los Residentes deben ser mayores de 18 años. Para más información, consulta [SUPPORT_SITE]."/>
<check_box label="Permitir el chat de voz" name="voice_chat_check"/>
<button label="?" name="voice_chat_help"/>
<check_box label="Permitir el teleporte a cualquier punto" name="allow_direct_teleport"/>
diff --git a/indra/newview/skins/default/xui/es/panel_region_general.xml b/indra/newview/skins/default/xui/es/panel_region_general.xml
index 453d1fe43c..453d1fe43c 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_region_general.xml
+++ b/indra/newview/skins/default/xui/es/panel_region_general.xml
diff --git a/indra/newview/skins/default/xui/es/panel_region_terrain.xml b/indra/newview/skins/default/xui/es/panel_region_terrain.xml
index cb6c03dbb5..cb6c03dbb5 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_region_terrain.xml
+++ b/indra/newview/skins/default/xui/es/panel_region_terrain.xml
diff --git a/indra/newview/skins/default/xui/es/panel_region_texture.xml b/indra/newview/skins/default/xui/es/panel_region_texture.xml
deleted file mode 100644
index 047e8f2f30..0000000000
--- a/indra/newview/skins/default/xui/es/panel_region_texture.xml
+++ /dev/null
@@ -1,57 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel label="Texturas del terreno" name="Textures">
- <text name="region_text_lbl">
- Región:
- </text>
- <text name="region_text">
- desconocida
- </text>
- <text name="detail_texture_text" width="380">
- Texturas del terreno (se requieren archivos .tga de 512x512 y 24 bites)
- </text>
- <text name="height_text_lbl">
- 1 (Baja)
- </text>
- <text name="height_text_lbl2">
- 2
- </text>
- <text name="height_text_lbl3">
- 3
- </text>
- <text name="height_text_lbl4">
- 4 (Alta)
- </text>
- <text name="height_text_lbl5">
- Rangos de la elevación de la textura
- </text>
- <text name="height_text_lbl6">
- Noroeste
- </text>
- <text name="height_text_lbl7">
- Noreste
- </text>
- <text name="height_text_lbl8">
- Suroeste
- </text>
- <text name="height_text_lbl9">
- Sureste
- </text>
- <spinner label="Baja" name="height_start_spin_0"/>
- <spinner label="Baja" name="height_start_spin_1"/>
- <spinner label="Baja" name="height_start_spin_2"/>
- <spinner label="Baja" name="height_start_spin_3"/>
- <spinner label="Alta" name="height_range_spin_0"/>
- <spinner label="Alta" name="height_range_spin_1"/>
- <spinner label="Alta" name="height_range_spin_2"/>
- <spinner label="Alta" name="height_range_spin_3"/>
- <text name="height_text_lbl10">
- Estos valores representan la gama de mezclas para las texturas superiores.
- </text>
- <text name="height_text_lbl11">
- Midiendo en metros, el valor BAJA es la altura MÃXIMA de la textura #1, y el valor ALTA es la altura MÃNIMA de la textura #4.
- </text>
- <text name="height_text_lbl12">
- y el valor ALTA es la altura MÃNIMA de la textura #4.
- </text>
- <button label="Aplicar" name="apply_btn"/>
-</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_script_ed.xml b/indra/newview/skins/default/xui/es/panel_script_ed.xml
index 4c4077b96f..87314820a6 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_script_ed.xml
+++ b/indra/newview/skins/default/xui/es/panel_script_ed.xml
@@ -34,6 +34,7 @@
<menu_item_call label="Seleccionar todo" name="Select All"/>
<menu_item_call label="Deseleccionar" name="Deselect"/>
<menu_item_call label="Buscar / Reemplazar..." name="Search / Replace..."/>
+ <menu_item_call label="Ir a la línea..." name="Go to line..."/>
</menu>
<menu label="Ayuda" name="Help">
<menu_item_call label="Ayuda..." name="Help..."/>
diff --git a/indra/newview/skins/default/xui/es/panel_script_limits_my_avatar.xml b/indra/newview/skins/default/xui/es/panel_script_limits_my_avatar.xml
index 9334d58af2..9334d58af2 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_script_limits_my_avatar.xml
+++ b/indra/newview/skins/default/xui/es/panel_script_limits_my_avatar.xml
diff --git a/indra/newview/skins/default/xui/es/panel_script_limits_region_memory.xml b/indra/newview/skins/default/xui/es/panel_script_limits_region_memory.xml
index 37dc0a576c..37dc0a576c 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_script_limits_region_memory.xml
+++ b/indra/newview/skins/default/xui/es/panel_script_limits_region_memory.xml
diff --git a/indra/newview/skins/default/xui/es/panel_script_question_toast.xml b/indra/newview/skins/default/xui/es/panel_script_question_toast.xml
new file mode 100755
index 0000000000..a2d0237da0
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/panel_script_question_toast.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<panel label="script_question_panel" name="panel_script_question_toast">
+ <panel label="buttons_panel" name="buttons_panel"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_scrolling_param.xml b/indra/newview/skins/default/xui/es/panel_scrolling_param.xml
index bafd4e5e55..bafd4e5e55 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_scrolling_param.xml
+++ b/indra/newview/skins/default/xui/es/panel_scrolling_param.xml
diff --git a/indra/newview/skins/default/xui/es/panel_scrolling_param_base.xml b/indra/newview/skins/default/xui/es/panel_scrolling_param_base.xml
index fa659040ea..fa659040ea 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_scrolling_param_base.xml
+++ b/indra/newview/skins/default/xui/es/panel_scrolling_param_base.xml
diff --git a/indra/newview/skins/default/xui/es/panel_side_tray.xml b/indra/newview/skins/default/xui/es/panel_side_tray.xml
deleted file mode 100644
index cf5afb3cd1..0000000000
--- a/indra/newview/skins/default/xui/es/panel_side_tray.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<!-- Side tray cannot show background because it is always
- partially on screen to hold tab buttons. -->
-<side_tray name="sidebar">
- <sidetray_tab description="Manejar la barra lateral." name="sidebar_openclose" tab_title="Barra lateral"/>
- <sidetray_tab description="Inicio." name="sidebar_home" tab_title="Inicio">
- <panel label="Inicio" name="panel_home"/>
- </sidetray_tab>
- <sidetray_tab description="Edita tu perfil público y tus destacados." name="sidebar_me" tab_title="Mi perfil">
- <panel_container name="panel_container">
- <panel label="Yo" name="panel_me"/>
- </panel_container>
- </sidetray_tab>
- <sidetray_tab description="Encuentra a tus amigos, contactos y gente que esté cerca." name="sidebar_people" tab_title="Gente">
- <panel_container name="panel_container">
- <panel label="Perfil del grupo" name="panel_group_info_sidetray"/>
- <panel label="Residentes y objetos ignorados" name="panel_block_list_sidetray"/>
- </panel_container>
- </sidetray_tab>
- <sidetray_tab description="Encontrar lugares donde ir o que ya visitaste." label="Lugares" name="sidebar_places" tab_title="Lugares">
- <panel label="Lugares" name="panel_places"/>
- </sidetray_tab>
- <sidetray_tab description="Mira tu inventario." name="sidebar_inventory" tab_title="Mi inventario">
- <panel label="Modificar el inventario" name="sidepanel_inventory"/>
- </sidetray_tab>
- <sidetray_tab description="Cambia tu apariencia y tu &apos;look&apos; actual." name="sidebar_appearance" tab_title="Mi apariencia">
- <panel label="Modificar la apariencia" name="sidepanel_appearance"/>
- </sidetray_tab>
-</side_tray>
diff --git a/indra/newview/skins/default/xui/es/panel_side_tray_tab_caption.xml b/indra/newview/skins/default/xui/es/panel_side_tray_tab_caption.xml
index 775e343dc9..775e343dc9 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_side_tray_tab_caption.xml
+++ b/indra/newview/skins/default/xui/es/panel_side_tray_tab_caption.xml
diff --git a/indra/newview/skins/default/xui/es/panel_snapshot_inventory.xml b/indra/newview/skins/default/xui/es/panel_snapshot_inventory.xml
index 12c74b5cd1..12c74b5cd1 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_snapshot_inventory.xml
+++ b/indra/newview/skins/default/xui/es/panel_snapshot_inventory.xml
diff --git a/indra/newview/skins/default/xui/es/panel_snapshot_local.xml b/indra/newview/skins/default/xui/es/panel_snapshot_local.xml
index 08c45d2e76..08c45d2e76 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_snapshot_local.xml
+++ b/indra/newview/skins/default/xui/es/panel_snapshot_local.xml
diff --git a/indra/newview/skins/default/xui/es/panel_snapshot_options.xml b/indra/newview/skins/default/xui/es/panel_snapshot_options.xml
index 2b2584f66c..2b2584f66c 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_snapshot_options.xml
+++ b/indra/newview/skins/default/xui/es/panel_snapshot_options.xml
diff --git a/indra/newview/skins/default/xui/es/panel_snapshot_postcard.xml b/indra/newview/skins/default/xui/es/panel_snapshot_postcard.xml
index 649d547ba0..649d547ba0 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_snapshot_postcard.xml
+++ b/indra/newview/skins/default/xui/es/panel_snapshot_postcard.xml
diff --git a/indra/newview/skins/default/xui/es/panel_snapshot_profile.xml b/indra/newview/skins/default/xui/es/panel_snapshot_profile.xml
index 6a0bc22d68..6a0bc22d68 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_snapshot_profile.xml
+++ b/indra/newview/skins/default/xui/es/panel_snapshot_profile.xml
diff --git a/indra/newview/skins/default/xui/es/panel_sound_devices.xml b/indra/newview/skins/default/xui/es/panel_sound_devices.xml
index 9531b99cc8..9531b99cc8 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_sound_devices.xml
+++ b/indra/newview/skins/default/xui/es/panel_sound_devices.xml
diff --git a/indra/newview/skins/default/xui/es/panel_stand_stop_flying.xml b/indra/newview/skins/default/xui/es/panel_stand_stop_flying.xml
index 350aec9c69..350aec9c69 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_stand_stop_flying.xml
+++ b/indra/newview/skins/default/xui/es/panel_stand_stop_flying.xml
diff --git a/indra/newview/skins/default/xui/es/panel_status_bar.xml b/indra/newview/skins/default/xui/es/panel_status_bar.xml
index 7eead3bc18..7eead3bc18 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_status_bar.xml
+++ b/indra/newview/skins/default/xui/es/panel_status_bar.xml
diff --git a/indra/newview/skins/default/xui/es/panel_teleport_history.xml b/indra/newview/skins/default/xui/es/panel_teleport_history.xml
index 364451b26b..364451b26b 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_teleport_history.xml
+++ b/indra/newview/skins/default/xui/es/panel_teleport_history.xml
diff --git a/indra/newview/skins/default/xui/es/panel_teleport_history_item.xml b/indra/newview/skins/default/xui/es/panel_teleport_history_item.xml
index 10b37b6880..10b37b6880 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_teleport_history_item.xml
+++ b/indra/newview/skins/default/xui/es/panel_teleport_history_item.xml
diff --git a/indra/newview/skins/default/xui/es/panel_tools_texture.xml b/indra/newview/skins/default/xui/es/panel_tools_texture.xml
new file mode 100644
index 0000000000..b820880e60
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/panel_tools_texture.xml
@@ -0,0 +1,116 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Textura" name="Texture">
+ <panel.string name="string repeats per meter">
+ Repeticiones por metro
+ </panel.string>
+ <panel.string name="string repeats per face">
+ Repeticiones por cara
+ </panel.string>
+ <text name="color label">
+ Color
+ </text>
+ <color_swatch label="" name="colorswatch" tool_tip="Pulsa para abrir el selector de color"/>
+ <text name="color trans">
+ Porcentaje de transparencia
+ </text>
+ <text name="glow label">
+ Resplandor
+ </text>
+ <check_box label="Brillo total" name="checkbox fullbright"/>
+ <combo_box name="combobox matmedia">
+ <combo_box.item label="Materiales" name="Materials"/>
+ <combo_box.item label="Media" name="Media"/>
+ </combo_box>
+ <combo_box name="combobox mattype">
+ <combo_box.item label="Textura (difuminar)" name="Texture (diffuse)"/>
+ <combo_box.item label="Rugosidad (normal)" name="Bumpiness (normal)"/>
+ <combo_box.item label="Brillo (efecto espejo)" name="Shininess (specular)"/>
+ </combo_box>
+ <texture_picker label="Textura" name="texture control" tool_tip="Pulsa para elegir una imagen"/>
+ <text name="label alphamode">
+ Modo alfa
+ </text>
+ <combo_box name="combobox alphamode">
+ <combo_box.item label="Ninguno" name="None"/>
+ <combo_box.item label="Mezclado alfa" name="Alpha blending"/>
+ <combo_box.item label="Máscara alfa" name="Alpha masking"/>
+ <combo_box.item label="Máscara de emisión lumínica" name="Emissive mask"/>
+ </combo_box>
+ <text name="label maskcutoff">
+ Límite de máscara
+ </text>
+ <texture_picker label="Textura" name="bumpytexture control" tool_tip="Pulsa para elegir una imagen"/>
+ <text name="label bumpiness">
+ Rugosidad
+ </text>
+ <combo_box name="combobox bumpiness">
+ <combo_box.item label="Ninguna" name="None"/>
+ <combo_box.item label="Claridad" name="Brightness"/>
+ <combo_box.item label="Oscuridad" name="Darkness"/>
+ <combo_box.item label="madera" name="woodgrain"/>
+ <combo_box.item label="corteza" name="bark"/>
+ <combo_box.item label="ladrillos" name="bricks"/>
+ <combo_box.item label="cuadrícula" name="checker"/>
+ <combo_box.item label="hormigón" name="concrete"/>
+ <combo_box.item label="azulejo" name="crustytile"/>
+ <combo_box.item label="piedralabrada" name="cutstone"/>
+ <combo_box.item label="discos" name="discs"/>
+ <combo_box.item label="gravilla" name="gravel"/>
+ <combo_box.item label="placadepetri" name="petridish"/>
+ <combo_box.item label="revestimiento" name="siding"/>
+ <combo_box.item label="baldosa" name="stonetile"/>
+ <combo_box.item label="estuco" name="stucco"/>
+ <combo_box.item label="succión" name="suction"/>
+ <combo_box.item label="tejido" name="weave"/>
+ </combo_box>
+ <texture_picker label="Textura" name="shinytexture control" tool_tip="Pulsa para elegir una imagen"/>
+ <text name="label shininess">
+ Brillo
+ </text>
+ <combo_box name="combobox shininess">
+ <combo_box.item label="Ninguno" name="None"/>
+ <combo_box.item label="Bajo" name="Low"/>
+ <combo_box.item label="Medio" name="Medium"/>
+ <combo_box.item label="Alto" name="High"/>
+ </combo_box>
+ <text name="label glossiness">
+ Efecto pulido
+ </text>
+ <text name="label environment">
+ Entorno
+ </text>
+ <text name="label shinycolor">
+ Color
+ </text>
+ <color_swatch label="" name="shinycolorswatch" tool_tip="Pulsa para abrir el selector de color"/>
+ <text name="media_info">
+ Espacio para la URL del media elegido, si procede
+ </text>
+ <button label="Elegir..." name="add_media" tool_tip="Añadir un media"/>
+ <button label="Eliminar" name="delete_media" tool_tip="Borrar esta textura para media"/>
+ <button label="Centrar" label_selected="Centrar los media" name="button align" tool_tip="Centrar esta textura para media (primero debe cargarse)"/>
+ <text name="tex gen">
+ Representación
+ </text>
+ <combo_box name="combobox texgen">
+ <combo_box.item label="Por defecto" name="Default"/>
+ <combo_box.item label="En el plano" name="Planar"/>
+ </combo_box>
+ <spinner label="Escala horizontal" name="TexScaleU"/>
+ <spinner label="Escala vertical" name="TexScaleV"/>
+ <spinner label="Repeticiones por metro" name="rptctrl"/>
+ <spinner label="Grados de rotación" name="TexRot"/>
+ <spinner label="Desplazamiento horizontal" name="TexOffsetU"/>
+ <spinner label="Desplazamiento vertical" name="TexOffsetV"/>
+ <spinner label="Escala horizontal" name="bumpyScaleU"/>
+ <spinner label="Escala vertical" name="bumpyScaleV"/>
+ <spinner label="Grados de rotación" name="bumpyRot"/>
+ <spinner label="Desplazamiento horizontal" name="bumpyOffsetU"/>
+ <spinner label="Desplazamiento vertical" name="bumpyOffsetV"/>
+ <spinner label="Escala horizontal" name="shinyScaleU"/>
+ <spinner label="Escala vertical" name="shinyScaleV"/>
+ <spinner label="Grados de rotación" name="shinyRot"/>
+ <spinner label="Desplazamiento horizontal" name="shinyOffsetU"/>
+ <spinner label="Desplazamiento vertical" name="shinyOffsetV"/>
+ <check_box initial_value="false" label="Alinear caras del plano" name="checkbox planar align" tool_tip="Alinear texturas en todas las caras seleccionadas con la última cara seleccionada. Requiere la representación de texturas en el plano."/>
+</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_voice_effect.xml b/indra/newview/skins/default/xui/es/panel_voice_effect.xml
index 94a0428941..94a0428941 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_voice_effect.xml
+++ b/indra/newview/skins/default/xui/es/panel_voice_effect.xml
diff --git a/indra/newview/skins/default/xui/es/panel_volume_pulldown.xml b/indra/newview/skins/default/xui/es/panel_volume_pulldown.xml
new file mode 100755
index 0000000000..426783aa8e
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/panel_volume_pulldown.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="volumepulldown_floater" width="215">
+ <slider label="General" label_width="55" name="System Volume" width="155"/>
+ <slider label="Botones" label_width="55" name="UI Volume" width="155"/>
+ <slider label="Ambiental" label_width="55" name="Wind Volume" width="155"/>
+ <slider label="Sonidos" label_width="55" name="SFX Volume" width="155"/>
+ <check_box name="gesture_audio_play_btn" tool_tip="Activar sonidos de los gestos"/>
+ <slider label="Música" label_width="55" name="Music Volume" width="155"/>
+ <check_box name="enable_music" tool_tip="Activar música en streaming"/>
+ <slider label="Media" label_width="55" name="Media Volume" width="155"/>
+ <check_box name="enable_media" tool_tip="Activar media en streaming"/>
+ <slider label="Voz" label_width="55" name="Voice Volume" width="155"/>
+ <check_box name="enable_voice_check" tool_tip="Activar el chat de voz"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_world_map.xml b/indra/newview/skins/default/xui/es/panel_world_map.xml
index b1dea02210..b1dea02210 100644..100755
--- a/indra/newview/skins/default/xui/es/panel_world_map.xml
+++ b/indra/newview/skins/default/xui/es/panel_world_map.xml
diff --git a/indra/newview/skins/default/xui/es/role_actions.xml b/indra/newview/skins/default/xui/es/role_actions.xml
index 660293b02c..902ed4df52 100644..100755
--- a/indra/newview/skins/default/xui/es/role_actions.xml
+++ b/indra/newview/skins/default/xui/es/role_actions.xml
@@ -25,7 +25,7 @@
</action_set>
<action_set description="Estas capacidades incluyen poder cambiar el nombre de la parcela y su configuración, así como si se muestra en Buscar y las opciones del punto de llegada y el de teleporte." name="Parcel Identity">
<action description="Cambiar &apos;Mostrar el sitio en Buscar&apos; y configurar la categoría" longdescription="Cambia &apos;Mostrar el sitio en Buscar&apos; y el configurar la categoría de una parcela en Acerca del terreno &gt; pestaña Opciones." name="land find places" value="17"/>
- <action description="Cambiar el nombre de la parcela, su descripción, y la configuración de &apos;Mostrar el sitio en Buscar&apos;" longdescription="Cambia el nombre de la parcela, su descripción, y la configuración de &apos;Mostrar el sitio en Buscar&apos;. Se hace en Acerca del terreno &gt; pestaña Opciones." name="land change identity" value="18"/>
+ <action description="Cambia el nombre de la parcela, su descripción y la configuración de &apos;Contenido moderado&apos;." longdescription="Cambia el nombre de la parcela, su descripción y la configuración de &apos;Contenido moderado&apos;. Se hace en Acerca del terreno &gt; pestaña Opciones." name="land change identity" value="18"/>
<action description="Definir los puntos de llegada y teleporte" longdescription="En una parcela perteneciente al grupo, los miembros con un rol que tenga esta capacidad pueden precisar el punto de llegada o el de teleporte. Se hace en Acerca del terreno &gt; pestaña Opciones." name="land set landing point" value="19"/>
</action_set>
<action_set description="Estas capacidades incluyen poderes que afectan a las opciones de la parcela, como &apos;Crear objetos&apos;, &apos;Editar el terreno&apos; y las configuraciones de la música y los media." name="Parcel Settings">
diff --git a/indra/newview/skins/default/xui/es/sidepanel_appearance.xml b/indra/newview/skins/default/xui/es/sidepanel_appearance.xml
index bdef89c392..bdef89c392 100644..100755
--- a/indra/newview/skins/default/xui/es/sidepanel_appearance.xml
+++ b/indra/newview/skins/default/xui/es/sidepanel_appearance.xml
diff --git a/indra/newview/skins/default/xui/es/sidepanel_inventory.xml b/indra/newview/skins/default/xui/es/sidepanel_inventory.xml
index f68dcc65e3..f68dcc65e3 100644..100755
--- a/indra/newview/skins/default/xui/es/sidepanel_inventory.xml
+++ b/indra/newview/skins/default/xui/es/sidepanel_inventory.xml
diff --git a/indra/newview/skins/default/xui/es/sidepanel_item_info.xml b/indra/newview/skins/default/xui/es/sidepanel_item_info.xml
index ef7c6781be..176247f90e 100644..100755
--- a/indra/newview/skins/default/xui/es/sidepanel_item_info.xml
+++ b/indra/newview/skins/default/xui/es/sidepanel_item_info.xml
@@ -3,6 +3,9 @@
<panel.string name="unknown">
(desconocidas)
</panel.string>
+ <panel.string name="unknown_multiple">
+ (desconocido/múltiple)
+ </panel.string>
<panel.string name="public">
(público)
</panel.string>
diff --git a/indra/newview/skins/default/xui/es/sidepanel_task_info.xml b/indra/newview/skins/default/xui/es/sidepanel_task_info.xml
index bd814ecc66..cb061796e7 100644..100755
--- a/indra/newview/skins/default/xui/es/sidepanel_task_info.xml
+++ b/indra/newview/skins/default/xui/es/sidepanel_task_info.xml
@@ -18,6 +18,12 @@
<panel.string name="text modify info 4">
No puedes modificar estos objetos
</panel.string>
+ <panel.string name="text modify info 5">
+ No se puede modificar este objeto a través del límite de una región
+ </panel.string>
+ <panel.string name="text modify info 6">
+ No se pueden modificar estos objetos a través del límite de una región
+ </panel.string>
<panel.string name="text modify warning">
Este objeto tiene partes enlazadas
</panel.string>
@@ -66,6 +72,7 @@
<combo_box.item label="Comprar el objeto" name="Buyobject"/>
<combo_box.item label="Pagar el objeto" name="Payobject"/>
<combo_box.item label="Abrir" name="Open"/>
+ <combo_box.item label="Zoom" name="Zoom"/>
</combo_box>
<panel name="perms_inv">
<text name="perm_modify">
@@ -95,6 +102,9 @@
</combo_box>
<spinner label="Precio: L$" name="Edit Cost"/>
<check_box label="Mostrar en la búsqueda" name="search_check" tool_tip="Permitir que la gente vea este objeto en los resultados de la búsqueda"/>
+ <text name="pathfinding_attributes_label">
+ Atributos de pathfinding:
+ </text>
<text name="B:">
B:
</text>
diff --git a/indra/newview/skins/default/xui/es/strings.xml b/indra/newview/skins/default/xui/es/strings.xml
index 67c65c6ce9..484511a08b 100644..100755
--- a/indra/newview/skins/default/xui/es/strings.xml
+++ b/indra/newview/skins/default/xui/es/strings.xml
@@ -128,7 +128,10 @@
Salir
</string>
<string name="create_account_url">
- http://join.secondlife.com/index.php?lang=es-ES
+ http://join.secondlife.com/?sourceid=[sourceid]
+ </string>
+ <string name="ViewerDownloadURL">
+ http://secondlife.com/download.
</string>
<string name="LoginFailedViewerNotPermitted">
Ya no puedes acceder a Second Life con el visor que estás utilizando. Visita la siguiente página para descargar un nuevo visor:
@@ -439,6 +442,9 @@ Intenta iniciar sesión de nuevo en unos instantes.
<string name="SLappAgentRequestFriend">
Petición de amistad
</string>
+ <string name="SLappAgentRemoveFriend">
+ Eliminación de amigos
+ </string>
<string name="BUTTON_CLOSE_DARWIN">
Cerrar (⌘W)
</string>
@@ -610,8 +616,8 @@ Intenta iniciar sesión de nuevo en unos instantes.
<string name="AvatarAway">
Ausente
</string>
- <string name="AvatarBusy">
- Ocupado
+ <string name="AvatarDoNotDisturb">
+ No molestar
</string>
<string name="AvatarMuted">
Ignorado
@@ -823,6 +829,9 @@ Intenta iniciar sesión de nuevo en unos instantes.
<string name="anim_yes_head">
Sí
</string>
+ <string name="use_texture">
+ Usar textura
+ </string>
<string name="texture_loading">
Cargando...
</string>
@@ -844,6 +853,12 @@ Intenta iniciar sesión de nuevo en unos instantes.
<string name="ST_NO_JOINT">
No se puede encontrar ROOT o JOINT.
</string>
+ <string name="NearbyChatTitle">
+ Chat
+ </string>
+ <string name="NearbyChatLabel">
+ (Chat)
+ </string>
<string name="whisper">
susurra:
</string>
@@ -871,6 +886,9 @@ Intenta iniciar sesión de nuevo en unos instantes.
<string name="ScriptQuestionCautionChatDenied">
A &apos;[OBJECTNAME]&apos;, un objeto propiedad de &apos;[OWNERNAME]&apos;, localizado en [REGIONNAME] con la posición [REGIONPOS], se le ha denegado el permiso para: [PERMISSIONS].
</string>
+ <string name="AdditionalPermissionsRequestHeader">
+ Si autorizas el acceso a tu cuenta, también permitirás al objeto:
+ </string>
<string name="ScriptTakeMoney">
Cogerle a usted dólares Linden (L$)
</string>
@@ -904,6 +922,27 @@ Intenta iniciar sesión de nuevo en unos instantes.
<string name="ControlYourCamera">
Controlar su cámara
</string>
+ <string name="AgentNameSubst">
+ (Tú)
+ </string>
+ <string name="TeleportYourAgent">
+ Teleportarte
+ </string>
+ <string name="JoinAnExperience">
+ Únete a una experiencia
+ </string>
+ <string name="SilentlyManageEstateAccess">
+ Suprimir alertas al gestionar las listas de acceso a un estado
+ </string>
+ <string name="OverrideYourAnimations">
+ Reemplazar tus animaciones predeterminadas
+ </string>
+ <string name="ScriptReturnObjects">
+ Devolver objetos en tu nombre
+ </string>
+ <string name="UnknownScriptPermission">
+ (desconocido)
+ </string>
<string name="SIM_ACCESS_PG">
General
</string>
@@ -982,17 +1021,8 @@ Intenta iniciar sesión de nuevo en unos instantes.
<string name="script_files">
Scripts
</string>
- <string name="AvatarSetNotAway">
- Salir del estado ausente
- </string>
- <string name="AvatarSetAway">
- Pasar al estado ausente
- </string>
- <string name="AvatarSetNotBusy">
- Salir del estado ocupado
- </string>
- <string name="AvatarSetBusy">
- Pasar al estado ocupado
+ <string name="dictionary_files">
+ Diccionarios
</string>
<string name="shape">
Forma
@@ -1226,7 +1256,7 @@ Intenta iniciar sesión de nuevo en unos instantes.
https://marketplace.[MARKETPLACE_DOMAIN_NAME]/
</string>
<string name="MarketplaceURL_CreateStore">
- http://community.secondlife.com/t5/English-Knowledge-Base/Selling-in-the-Marketplace/ta-p/700193#Section_.4
+ http://community.secondlife.com/t5/English-Knowledge-Base/Selling-in-the-Marketplace/ta-p/700193#Section_.3
</string>
<string name="MarketplaceURL_Dashboard">
https://marketplace.[MARKETPLACE_DOMAIN_NAME]/merchants/store/dashboard
@@ -1381,6 +1411,12 @@ Intenta iniciar sesión de nuevo en unos instantes.
<string name="InvFolder favorite">
Mis Favoritos
</string>
+ <string name="InvFolder Favorites">
+ Mis Favoritos
+ </string>
+ <string name="InvFolder favorites">
+ Mis Favoritos
+ </string>
<string name="InvFolder Current Outfit">
Vestuario actual
</string>
@@ -1396,6 +1432,12 @@ Intenta iniciar sesión de nuevo en unos instantes.
<string name="InvFolder Meshes">
Redes
</string>
+ <string name="InvFolder Received Items">
+ Objetos recibidos
+ </string>
+ <string name="InvFolder Merchant Outbox">
+ Buzón de salida de comerciante
+ </string>
<string name="InvFolder Friends">
Amigos
</string>
@@ -1926,6 +1968,12 @@ Intenta iniciar sesión de nuevo en unos instantes.
<string name="ATTACH_HUD_BOTTOM_RIGHT">
HUD: abajo der.
</string>
+ <string name="ATTACH_NECK">
+ Cuello
+ </string>
+ <string name="ATTACH_AVATAR_CENTER">
+ Centro del avatar
+ </string>
<string name="CursorPos">
Línea [LINE], Columna [COLUMN]
</string>
@@ -1938,8 +1986,8 @@ Intenta iniciar sesión de nuevo en unos instantes.
<string name="PanelContentsNewScript">
Script nuevo
</string>
- <string name="BusyModeResponseDefault">
- El Residente al que has enviado un mensaje ha solicitado que no se le moleste porque está en modo ocupado. Podrá ver tu mensaje más adelante, ya que éste aparecerá en su panel de MI.
+ <string name="DoNotDisturbModeResponseDefault">
+ Este residente tiene activado &apos;No molestar&apos; y verá tu mensaje más tarde.
</string>
<string name="MuteByName">
(Por el nombre)
@@ -2052,9 +2100,6 @@ Intenta iniciar sesión de nuevo en unos instantes.
<string name="GroupMoneyDate">
[weekday,datetime,utc] [mth,datetime,utc] [day,datetime,utc], [year,datetime,utc]
</string>
- <string name="ViewerObjectContents">
- Contenidos
- </string>
<string name="AcquiredItems">
Artículos adquiridos
</string>
@@ -2916,6 +2961,9 @@ Si sigues recibiendo este mensaje, contacta con [SUPPORT_SITE].
<string name="Hip Width">
Cadera: ancho
</string>
+ <string name="Hover">
+ Pasa el cursor
+ </string>
<string name="In">
Pegadas
</string>
@@ -3772,7 +3820,13 @@ Si sigues recibiendo este mensaje, contacta con [SUPPORT_SITE].
Región General
</string>
<string name="LocationCtrlSeeAVsTooltip">
- Los avatares están visibles y está permitido el chat fuera de esta parcela
+ Los avatares que están en esta parcela no pueden ser vistos ni escuchados por los que están fuera de ella
+ </string>
+ <string name="LocationCtrlPathfindingDirtyTooltip">
+ Los objetos que se mueven pueden presentar un comportamiento incorrecto en la región hasta que ésta se recargue.
+ </string>
+ <string name="LocationCtrlPathfindingDisabledTooltip">
+ Esta región no tiene activado el pathfinding dinámico.
</string>
<string name="UpdaterWindowTitle">
Actualizar [APP_NAME]
@@ -3840,6 +3894,12 @@ Si sigues recibiendo este mensaje, contacta con [SUPPORT_SITE].
<string name="Saved_message">
(Guardado [LONG_TIMESTAMP])
</string>
+ <string name="OnlineStatus">
+ Conectado/a
+ </string>
+ <string name="OfflineStatus">
+ Desconectado/a
+ </string>
<string name="answered_call">
Han respondido a tu llamada
</string>
@@ -3849,6 +3909,9 @@ Si sigues recibiendo este mensaje, contacta con [SUPPORT_SITE].
<string name="you_joined_call">
Has entrado en la llamada de voz
</string>
+ <string name="you_auto_rejected_call-im">
+ Rechazaste la llamada de voz automáticamente porque estaba activado &apos;No molestar&apos;.
+ </string>
<string name="name_started_call">
[NAME] inició una llamada de voz
</string>
@@ -3861,6 +3924,9 @@ Si sigues recibiendo este mensaje, contacta con [SUPPORT_SITE].
<string name="hang_up-im">
Se colgó la llamada de voz
</string>
+ <string name="conference-title">
+ Chat multi-persona
+ </string>
<string name="conference-title-incoming">
Conferencia con [AGENT_NAME]
</string>
@@ -4739,6 +4805,9 @@ Inténtalo incluyendo la ruta de acceso al editor entre comillas
<string name="Command_Chat_Label">
Chat
</string>
+ <string name="Command_Conversations_Label">
+ Conversaciones
+ </string>
<string name="Command_Compass_Label">
Brújula
</string>
@@ -4814,6 +4883,9 @@ Inténtalo incluyendo la ruta de acceso al editor entre comillas
<string name="Command_Chat_Tooltip">
Habla por chat de texto con las personas próximas
</string>
+ <string name="Command_Conversations_Tooltip">
+ Conversar con todos
+ </string>
<string name="Command_Compass_Tooltip">
Brújula
</string>
@@ -4907,6 +4979,21 @@ Inténtalo incluyendo la ruta de acceso al editor entre comillas
<string name="Normal">
Normal
</string>
+ <string name="Pathfinding_Wiki_URL">
+ http://wiki.secondlife.com/wiki/Pathfinding_Tools_in_the_Second_Life_Viewer
+ </string>
+ <string name="Pathfinding_Object_Attr_None">
+ Ninguno
+ </string>
+ <string name="Pathfinding_Object_Attr_Permanent">
+ Afecta al navmesh
+ </string>
+ <string name="Pathfinding_Object_Attr_Character">
+ Personaje
+ </string>
+ <string name="Pathfinding_Object_Attr_MultiSelect">
+ (Múltiple)
+ </string>
<string name="snapshot_quality_very_low">
Muy bajo
</string>
@@ -4922,4 +5009,22 @@ Inténtalo incluyendo la ruta de acceso al editor entre comillas
<string name="snapshot_quality_very_high">
Muy alto
</string>
+ <string name="TeleportMaturityExceeded">
+ El Residente no puede visitar esta región.
+ </string>
+ <string name="UserDictionary">
+ [Usuario]
+ </string>
+ <string name="logging_calls_disabled_log_empty">
+ No se están registrando las conversaciones. Para empezar a grabar un registro, elige &quot;Guardar: Solo registro&quot; o &quot;Guardar: Registro y transcripciones&quot; en Preferencias &gt; Chat.
+ </string>
+ <string name="logging_calls_disabled_log_not_empty">
+ No se registrarán más conversaciones. Para reanudar la grabación de un registro, elige &quot;Guardar: Solo registro&quot; o &quot;Guardar: Registro y transcripciones&quot; en Preferencias &gt; Chat.
+ </string>
+ <string name="logging_calls_enabled_log_empty">
+ No hay conversaciones grabadas. Después de contactar con una persona, o de que alguien contacte contigo, aquí se mostrará una entrada de registro.
+ </string>
+ <string name="loading_chat_logs">
+ Cargando...
+ </string>
</strings>
diff --git a/indra/newview/skins/default/xui/es/teleport_strings.xml b/indra/newview/skins/default/xui/es/teleport_strings.xml
index a23d9c43d0..94975a83f8 100644..100755
--- a/indra/newview/skins/default/xui/es/teleport_strings.xml
+++ b/indra/newview/skins/default/xui/es/teleport_strings.xml
@@ -44,6 +44,9 @@ Para repetir el tutorial, visita la isla de bienvenida pública.
<message name="no_inventory_host">
En estos momentos no está disponible el sistema del inventario.
</message>
+ <message name="MustGetAgeRegion">
+ Solo pueden acceder a esta región los mayores de 18 años.
+ </message>
</message_set>
<message_set name="progress">
<message name="sending_dest">
@@ -79,5 +82,8 @@ Para repetir el tutorial, visita la isla de bienvenida pública.
<message name="requesting">
Solicitando teleporte...
</message>
+ <message name="pending">
+ Teleporte pendiente...
+ </message>
</message_set>
</teleport_messages>
diff --git a/indra/newview/skins/default/xui/es/xui_version.xml b/indra/newview/skins/default/xui/es/xui_version.xml
index 0e777751d3..0e777751d3 100644..100755
--- a/indra/newview/skins/default/xui/es/xui_version.xml
+++ b/indra/newview/skins/default/xui/es/xui_version.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_about.xml b/indra/newview/skins/default/xui/fr/floater_about.xml
index 4409949584..384966354e 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_about.xml
+++ b/indra/newview/skins/default/xui/fr/floater_about.xml
@@ -8,7 +8,9 @@
Compilé avec [COMPILER] version [COMPILER_VERSION]
</floater.string>
<floater.string name="AboutPosition">
- Vous êtes à [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1] dans [REGION], se trouvant à &lt;nolink&gt;[HOSTNAME]&lt;/nolink&gt; ([HOSTIP])
+ Vous êtes à [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] dans [REGION], se trouvant à &lt;nolink&gt;[HOSTNAME]&lt;/nolink&gt; ([HOSTIP])
+SLURL : &lt;nolink&gt;[SLURL]&lt;/nolink&gt;
+(coordonnées globales [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1])
[SERVER_VERSION]
[SERVER_RELEASE_NOTES_URL]
</floater.string>
@@ -66,27 +68,26 @@ Version serveur vocal : [VOICE_VERSION]
</panel>
<panel label="Licences" name="licenses_panel">
<text_editor name="credits_editor">
- 3Dconnexion SDK Copyright (C) 1992-2007 3Dconnexion
- APR Copyright (C) 2000-2004 The Apache Software Foundation
- Collada DOM Copyright 2005 Sony Computer Entertainment Inc.
- cURL Copyright (C) 1996-2002, Daniel Stenberg, (daniel@haxx.se)
+ 3Dconnexion SDK Copyright (C) 1992-2009 3Dconnexion
+ APR Copyright (C) 2011 The Apache Software Foundation
+ Collada DOM Copyright 2006 Sony Computer Entertainment Inc.
+ cURL Copyright (C) 1996-2010, Daniel Stenberg, (daniel@haxx.se)
DBus/dbus-glib Copyright (C) 2002, 2003 CodeFactory AB / Copyright (C) 2003, 2004 Red Hat, Inc.
expat Copyright (C) 1998, 1999, 2000 Thai Open Source Software Center Ltd.
- FreeType Copyright (C) 1996-2002, The FreeType Project (www.freetype.org).
+ FreeType Copyright (C) 1996-2002, 2006 David Turner, Robert Wilhelm et Werner Lemberg.
GL Copyright (C) 1999-2004 Brian Paul.
- GLOD Copyright (C) 2003-04 Jonathan Cohen, Nat Duca, Chris Niski, Johns Hopkins University et David Luebke, Brenden Schubert, University of Virginia.
+ GLOD Copyright (C) 2003-04 Jonathan Cohen, Nat Duca, Chris Niski, Johns Hopkins University, et David Luebke, Brenden Schubert, University of Virginia.
google-perftools Copyright (c) 2005, Google Inc.
Havok.com(TM) Copyright (C) 1999-2001, Telekinesys Research Limited.
jpeg2000 Copyright (C) 2001, David Taubman, The University of New South Wales (UNSW)
jpeglib Copyright (C) 1991-1998, Thomas G. Lane.
- ogg/vorbis Copyright (C) 2001, Xiphophorus
- OpenSSL Copyright (C) 1998-2002 The OpenSSL Project.
- PCRE Copyright (c) 1997-2008 University of Cambridge
+ ogg/vorbis Copyright (C) 2002, Xiphophorus
+ OpenSSL Copyright (C) 1998-2008 The OpenSSL Project.
+ PCRE Copyright (c) 1997-2012 University of Cambridge
SDL Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga
SSLeay Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
xmlrpc-epi Copyright (C) 2000 Epinions, Inc.
- zlib Copyright (C) 1995-2002 Jean-loup Gailly et Mark Adler.
- google-perftools Copyright (c) 2005, Google Inc.
+ zlib Copyright (C) 1995-2012 Jean-Loup Gailly et Mark Adler.
Le client Second Life utilise Havok (TM) Physics. (c)Copyright 1999-2010 Havok.com Inc. (et ses concédants de licence). Tous droits réservés. Pour plus de détails, consultez le site Web www.havok.com.
diff --git a/indra/newview/skins/default/xui/fr/floater_about_land.xml b/indra/newview/skins/default/xui/fr/floater_about_land.xml
index 6f8885487a..25c49b97b5 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/fr/floater_about_land.xml
@@ -134,7 +134,7 @@
<text name="DwellText">
Chargement...
</text>
- <button label="Acheter du terrain" label_selected="Acheter le terrain..." left_delta="60" name="Buy Land..." width="125"/>
+ <button label="Acheter le terrain" label_selected="Acheter le terrain..." left_delta="60" name="Buy Land..." width="125"/>
<button label="Vente Linden" label_selected="Vente Linden..." name="Linden Sale..." tool_tip="Le terrain doit être la propriété d&apos;un résident, avoir un contenu défini et ne pas être aux enchères."/>
<button label="Infos sur les scripts" name="Scripts..." width="110"/>
<button label="Acheter pour le groupe" label_selected="Acheter pour le groupe..." name="Buy For Group..."/>
@@ -339,7 +339,7 @@ Seules les parcelles de grande taille peuvent apparaître dans la recherche.
<check_box label="Groupe" name="check group scripts"/>
<check_box label="Sécurisé (pas de dégâts)" name="check safe" tool_tip="Si cette option est cochée, le terrain est sécurisé et il n&apos;y pas de risques de dommages causés par des combats. Si elle est décochée, des dommages causés par les combats peuvent avoir lieu."/>
<check_box label="Pas de bousculades" name="PushRestrictCheck" tool_tip="Empêche l&apos;utilisation de scripts causant des bousculades. Cette option est utile pour empêcher les comportements abusifs sur votre terrain."/>
- <check_box label="Afficher le lieu dans la recherche (30 L$/semaine)" name="ShowDirectoryCheck" tool_tip="Afficher la parcelle dans les résultats de recherche"/>
+ <check_box label="Voir le lieu dans la recherche (30 L$/sem.)" name="ShowDirectoryCheck" tool_tip="Afficher la parcelle dans les résultats de recherche"/>
<combo_box name="land category with adult">
<combo_box.item label="Toutes catégories" name="item0"/>
<combo_box.item label="Appartenant aux Lindens" name="item1"/>
@@ -377,7 +377,7 @@ Seules les parcelles de grande taille peuvent apparaître dans la recherche.
</text>
<texture_picker label="" name="snapshot_ctrl" tool_tip="Cliquez pour sélectionner une image"/>
<text name="allow_label5">
- Les avatars présents sur d&apos;autres parcelles peuvent voir et chatter avec les avatars présents sur cette parcelle.
+ Les avatars sur d&apos;autres parcelles peuvent voir et chatter avec les avatars sur cette parcelle.
</text>
<check_box label="Voir les avatars" name="SeeAvatarsCheck" tool_tip="Permettre aux avatars présents sur d&apos;autres parcelles de voir et chatter avec les avatars présents sur cette parcelle et à vous de les voir et de chatter avec eux."/>
<text name="landing_point">
@@ -439,7 +439,7 @@ musique :
<text name="Sound:">
Son :
</text>
- <check_box label="Limiter les gestes et sons d&apos;objet à cette parcelle" name="check sound local"/>
+ <check_box label="Limiter les sons des gestes et des objets à cette parcelle" name="check sound local"/>
<text name="Avatar Sounds:">
Sons d&apos;avatar :
</text>
@@ -470,7 +470,7 @@ musique :
Conditions d&apos;accès des résidents :
</text>
<check_box label="Informations de paiement enregistrées [ESTATE_PAYMENT_LIMIT]" name="limit_payment" tool_tip="Pour pouvoir accéder à cette parcelle, les résidents doivent avoir enregistré des informations de paiement. Consultez le [SUPPORT_SITE] pour plus d&apos;informations."/>
- <check_box label="Âge vérifié [ESTATE_AGE_LIMIT]" name="limit_age_verified" tool_tip="Pour que les résidents puissent accéder à cette parcelle, leur âge doit avoir fait l&apos;objet d&apos;une vérification. Consultez le [SUPPORT_SITE] pour plus d&apos;informations."/>
+ <check_box label="Avoir plus de 18 ans [ESTATE_AGE_LIMIT]" name="limit_age_verified" tool_tip="Pour accéder à cette parcelle, les résidents doivent avoir au moins 18 ans. Consultez le [SUPPORT_SITE] pour plus d&apos;informations."/>
<check_box label="Autoriser l&apos;accès au groupe : [GROUP]" name="GroupCheck" tool_tip="Définir le groupe à l&apos;onglet Général."/>
<check_box label="Vendre des pass à :" name="PassCheck" tool_tip="Autoriser un accès temporaire à cette parcelle"/>
<combo_box name="pass_combo" width="110">
diff --git a/indra/newview/skins/default/xui/fr/floater_activeim.xml b/indra/newview/skins/default/xui/fr/floater_activeim.xml
index 18e3d66bb7..18e3d66bb7 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_activeim.xml
+++ b/indra/newview/skins/default/xui/fr/floater_activeim.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_animation_anim_preview.xml b/indra/newview/skins/default/xui/fr/floater_animation_anim_preview.xml
index e82518ce80..e82518ce80 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_animation_anim_preview.xml
+++ b/indra/newview/skins/default/xui/fr/floater_animation_anim_preview.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_animation_bvh_preview.xml b/indra/newview/skins/default/xui/fr/floater_animation_bvh_preview.xml
index 84c40b5987..84c40b5987 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_animation_bvh_preview.xml
+++ b/indra/newview/skins/default/xui/fr/floater_animation_bvh_preview.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_animation_preview.xml b/indra/newview/skins/default/xui/fr/floater_animation_preview.xml
deleted file mode 100644
index aa42fe6150..0000000000
--- a/indra/newview/skins/default/xui/fr/floater_animation_preview.xml
+++ /dev/null
@@ -1,189 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Animation Preview" title="">
- <floater.string name="failed_to_initialize">
- Echec de l&apos;initialisation du mouvement
- </floater.string>
- <floater.string name="anim_too_long">
- Le fichier d&apos;animation fait [LENGTH] secondes.
-
-La longueur maximale est de [MAX_LENGTH] secondes.
- </floater.string>
- <floater.string name="failed_file_read">
- Impossible de lire le fichier d&apos;animation.
-
-[STATUS]
- </floater.string>
- <floater.string name="E_ST_OK">
- Ok
- </floater.string>
- <floater.string name="E_ST_EOF">
- Fichier incomplet.
- </floater.string>
- <floater.string name="E_ST_NO_CONSTRAINT">
- Impossible de lire la définition des contraintes.
- </floater.string>
- <floater.string name="E_ST_NO_FILE">
- Impossible d&apos;ouvrir le fichier BVH.
- </floater.string>
- <floater.string name="E_ST_NO_HIER">
- En-tête HIERARCHY non valide.
- </floater.string>
- <floater.string name="E_ST_NO_JOINT">
- Impossible de trouver ROOT ou JOINT.
- </floater.string>
- <floater.string name="E_ST_NO_NAME">
- Impossible de trouver le nom JOINT.
- </floater.string>
- <floater.string name="E_ST_NO_OFFSET">
- Impossible de trouver OFFSET.
- </floater.string>
- <floater.string name="E_ST_NO_CHANNELS">
- Impossible de trouver les CHANNELS.
- </floater.string>
- <floater.string name="E_ST_NO_ROTATION">
- Impossible d&apos;obtenir l&apos;ordre de rotation.
- </floater.string>
- <floater.string name="E_ST_NO_AXIS">
- Impossible d&apos;obtenir l&apos;axe de rotation.
- </floater.string>
- <floater.string name="E_ST_NO_MOTION">
- Impossible de trouver MOTION.
- </floater.string>
- <floater.string name="E_ST_NO_FRAMES">
- Impossible d&apos;obtenir le nombre de cadres.
- </floater.string>
- <floater.string name="E_ST_NO_FRAME_TIME">
- Impossible d&apos;obtenir le temps du cadre.
- </floater.string>
- <floater.string name="E_ST_NO_POS">
- Impossible de trouver les valeurs de la position.
- </floater.string>
- <floater.string name="E_ST_NO_ROT">
- Impossible de trouver les valeurs de rotation.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_FILE">
- Impossible d&apos;ouvrir le fichier de traduction.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_HEADER">
- Impossible de lire l&apos;en-tête de traduction.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_NAME">
- Impossible de lire la traduction.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_IGNORE">
- Impossible de lire la traduction.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_RELATIVE">
- Impossible de lire la valeur de traduction relative.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_OUTNAME">
- Impossible de lire la traduction.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_MATRIX">
- Impossible de lire la matrice de traduction.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_MERGECHILD">
- Impossible de trouver le nom mergechild.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_MERGEPARENT">
- Impossible de trouver le nom mergeparent.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_PRIORITY">
- Impossible de définir la valeur de la priorité.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_LOOP">
- Impossible de définir la valeur de la boucle
- </floater.string>
- <floater.string name="E_ST_NO_XLT_EASEIN">
- Impossible de trouver les valeurs easeIn.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_EASEOUT">
- Impossible de trouver les valeurs easeOut.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_HAND">
- Impossible d&apos;obtenir la valeur hand morph.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_EMOTE">
- Impossible de lire le nom emote.
- </floater.string>
- <floater.string name="E_ST_BAD_ROOT">
- Nom de racine incorrect.
- </floater.string>
- <text name="name_label">
- Nom :
- </text>
- <text name="description_label">
- Description :
- </text>
- <spinner label="Priorité" name="priority" tool_tip="Contrôle quelles autres animations peuvent être remplacées par cette animation"/>
- <check_box label="Boucle" left="6" name="loop_check" tool_tip="Lit cette animation en boucle"/>
- <spinner label="Début (%)" label_width="65" name="loop_in_point" tool_tip="Définit un point de l&apos;animation auquel retourne la boucle" width="105"/>
- <spinner label="Fin (%)" name="loop_out_point" tool_tip="Définit un point de l&apos;animation qui met fin à la boucle"/>
- <text name="hand_label">
- Mouvement de
-main
- </text>
- <combo_box label="" name="hand_pose_combo" tool_tip="Contrôle ce que font les mains pendant l&apos;animation">
- <combo_box.item label="Espacement" name="Spread"/>
- <combo_box.item label="Détendues" name="Relaxed"/>
- <combo_box.item label="Pointer (les deux)" name="PointBoth"/>
- <combo_box.item label="Poing" name="Fist"/>
- <combo_box.item label="Détendue (gauche)" name="RelaxedLeft"/>
- <combo_box.item label="Pointer (gauche)" name="PointLeft"/>
- <combo_box.item label="Poing (gauche)" name="FistLeft"/>
- <combo_box.item label="Détendue (droite)" name="RelaxedRight"/>
- <combo_box.item label="Pointer (droite)" name="PointRight"/>
- <combo_box.item label="Poing (droite)" name="FistRight"/>
- <combo_box.item label="Saluer (droite)" name="SaluteRight"/>
- <combo_box.item label="Taper" name="Typing"/>
- <combo_box.item label="Paix (main droite)" name="PeaceRight"/>
- </combo_box>
- <text name="emote_label">
- Expression
- </text>
- <combo_box label="" name="emote_combo" tool_tip="Contrôle ce que fait le visage pendant l&apos;animation">
- <item label="(aucun)" name="[None]" value=""/>
- <item label="Aaaaah" name="Aaaaah" value="Aaaaah"/>
- <item label="Effrayé" name="Afraid" value="Effrayé"/>
- <item label="En colère" name="Angry" value="En colère"/>
- <item label="Grand sourire" name="BigSmile" value="Grand sourire"/>
- <item label="Ennui" name="Bored" value="Ennui"/>
- <item label="Pleurer" name="Cry" value="Pleurer"/>
- <item label="Mépris" name="Disdain" value="Mépris"/>
- <item label="Gêne" name="Embarrassed" value="Gêne"/>
- <item label="Froncer les sourcils" name="Frown" value="Froncer les sourcils"/>
- <item label="Embrasser" name="Kiss" value="Embrasser"/>
- <item label="Rire" name="Laugh" value="Rire"/>
- <item label="Plllppt" name="Plllppt" value="Tirer la langue"/>
- <item label="Dégoût" name="Repulsed" value="Dégoût"/>
- <item label="Triste" name="Sad" value="Triste"/>
- <item label="Hausser les épaules" name="Shrug" value="Hausser les épaules"/>
- <item label="Sourire" name="Smile" value="Sourire"/>
- <item label="Surprise" name="Surprise" value="Surprise"/>
- <item label="Clin d&apos;Å“il" name="Wink" value="Clin d&apos;Å“il"/>
- <item label="Soucis" name="Worry" value="Inquiétude"/>
- </combo_box>
- <text name="preview_label">
- Prévisualiser
-pendant
- </text>
- <combo_box label="" name="preview_base_anim" tool_tip="Utilisez cette option pour tester votre animation pendant que votre avatar fait des choses banales.">
- <item label="Debout" name="Standing" value="Debout"/>
- <item label="Marche" name="Walking" value="Marche"/>
- <item label="Assis" name="Sitting" value="Assis"/>
- <item label="Vol" name="Flying" value="Vol"/>
- </combo_box>
- <spinner label="Transition début (s)" name="ease_in_time" tool_tip="Durée (en secondes) de l&apos;entrée en fondu de l&apos;animation"/>
- <spinner label="Transition fin (s)" name="ease_out_time" tool_tip="Durée (en secondes) de la sortie en fondu de l&apos;animation"/>
- <button label="" name="play_btn" tool_tip="Lire votre animation"/>
- <button name="pause_btn" tool_tip="Pauser votre animation"/>
- <button label="" name="stop_btn" tool_tip="Arrêter le playback"/>
- <slider label="" name="playback_slider"/>
- <text name="bad_animation_text">
- Impossible de lire le fichier d&apos;animation.
-
-Nous recommandons les fichiers BVH extraits de Poser 4.
- </text>
- <button label="Charger ([AMOUNT] L$)" name="ok_btn"/>
- <button label="Annuler" name="cancel_btn"/>
-</floater>
diff --git a/indra/newview/skins/default/xui/fr/floater_auction.xml b/indra/newview/skins/default/xui/fr/floater_auction.xml
index 6cef2a3591..6cef2a3591 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_auction.xml
+++ b/indra/newview/skins/default/xui/fr/floater_auction.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_autoreplace.xml b/indra/newview/skins/default/xui/fr/floater_autoreplace.xml
new file mode 100755
index 0000000000..1d19181692
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/floater_autoreplace.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="autoreplace_floater" title="Paramètres Rechercher/Remplacer">
+ <check_box label="Activer la fonction Rechercher/Remplacer" name="autoreplace_enable" tool_tip="Lors de la saisie du texte d&apos;un chat, remplace chaque mot-clé spécifié par la valeur correspondante."/>
+ <button label="Importer une liste..." name="autoreplace_import_list" tool_tip="Charger une liste précédemment exportée à partir d&apos;un fichier."/>
+ <button label="Exporter la liste..." name="autoreplace_export_list" tool_tip="Enregistrer la liste sélectionnée dans un fichier afin de pouvoir la partager."/>
+ <button label="Nouvelle liste..." name="autoreplace_new_list" tool_tip="Créer une nouvelle liste."/>
+ <button label="Supprimer la liste" name="autoreplace_delete_list" tool_tip="Supprimer la liste sélectionnée."/>
+ <button name="autoreplace_list_up" tool_tip="Augmenter la priorité de cette liste."/>
+ <button name="autoreplace_list_down" tool_tip="Diminuer la priorité de cette liste."/>
+ <scroll_list name="autoreplace_list_replacements">
+ <scroll_list.columns label="Mot-clé" name="keyword"/>
+ <scroll_list.columns label="Remplacement" name="replacement"/>
+ </scroll_list>
+ <button label="Ajouter..." name="autoreplace_add_entry"/>
+ <button label="Supprimer" name="autoreplace_delete_entry"/>
+ <button label="Enregistrer" name="autoreplace_save_entry" tool_tip="Enregistrer cette entrée."/>
+ <button label="Enregistrer les modifications" name="autoreplace_save_changes" tool_tip="Enregistrer toutes les modifications."/>
+ <button label="Annuler" name="autoreplace_cancel" tool_tip="Ignorer toutes les modifications."/>
+</floater>
+<!--
+ <text
+ top_pad="10"
+ left="10"
+ height="16"
+ width="260"
+ follows="left|top"
+ halign="center"
+ mouse_opaque="true"
+ name="autoreplace_text2">
+ Entries
+ </text>
+-->
diff --git a/indra/newview/skins/default/xui/fr/floater_avatar.xml b/indra/newview/skins/default/xui/fr/floater_avatar.xml
index 7cbb50a3d6..7cbb50a3d6 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_avatar.xml
+++ b/indra/newview/skins/default/xui/fr/floater_avatar.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_avatar_picker.xml b/indra/newview/skins/default/xui/fr/floater_avatar_picker.xml
index 74de4ddb1c..74de4ddb1c 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_avatar_picker.xml
+++ b/indra/newview/skins/default/xui/fr/floater_avatar_picker.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_avatar_textures.xml b/indra/newview/skins/default/xui/fr/floater_avatar_textures.xml
index e1786eafc7..e1786eafc7 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_avatar_textures.xml
+++ b/indra/newview/skins/default/xui/fr/floater_avatar_textures.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_beacons.xml b/indra/newview/skins/default/xui/fr/floater_beacons.xml
index ebd4dab683..ebd4dab683 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_beacons.xml
+++ b/indra/newview/skins/default/xui/fr/floater_beacons.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_build_options.xml b/indra/newview/skins/default/xui/fr/floater_build_options.xml
index a200ed192f..a200ed192f 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_build_options.xml
+++ b/indra/newview/skins/default/xui/fr/floater_build_options.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_bulk_perms.xml b/indra/newview/skins/default/xui/fr/floater_bulk_perms.xml
index ab68ce166b..7ee4441758 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_bulk_perms.xml
+++ b/indra/newview/skins/default/xui/fr/floater_bulk_perms.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floaterbulkperms" title="MODIFIER LES DROITS">
+<floater name="floaterbulkperms" title="MODIFIER LES DROITS RELATIFS AU CONTENU">
<floater.string name="nothing_to_modify_text">
Certains contenus sont non modifiables.
</floater.string>
@@ -33,7 +33,7 @@
<button label="√ Tout" label_selected="Tout" name="check_all"/>
<button label="Effacer" label_selected="Aucun" name="check_none"/>
<text name="newperms">
- Nouveaux droits
+ Modifier les droits relatifs au contenu et remplacer par
</text>
<text name="GroupLabel">
Groupe :
@@ -49,6 +49,7 @@
<check_box label="Modifier" name="next_owner_modify"/>
<check_box label="Copier" name="next_owner_copy"/>
<check_box initial_value="true" label="Transférer" name="next_owner_transfer" tool_tip="Le prochain propriétaire peut donner ou revendre cet objet"/>
- <button label="OK" name="apply"/>
+ <button label="OK" name="ok"/>
+ <button label="Appliquer" name="apply"/>
<button label="Annuler" name="close"/>
</floater>
diff --git a/indra/newview/skins/default/xui/fr/floater_bumps.xml b/indra/newview/skins/default/xui/fr/floater_bumps.xml
index 32714ea09c..32714ea09c 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_bumps.xml
+++ b/indra/newview/skins/default/xui/fr/floater_bumps.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_buy_contents.xml b/indra/newview/skins/default/xui/fr/floater_buy_contents.xml
index 0436dc8a91..0436dc8a91 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_buy_contents.xml
+++ b/indra/newview/skins/default/xui/fr/floater_buy_contents.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_buy_currency.xml b/indra/newview/skins/default/xui/fr/floater_buy_currency.xml
index 148a5a35d2..148a5a35d2 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_buy_currency.xml
+++ b/indra/newview/skins/default/xui/fr/floater_buy_currency.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_buy_currency_html.xml b/indra/newview/skins/default/xui/fr/floater_buy_currency_html.xml
index 953fca3544..953fca3544 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_buy_currency_html.xml
+++ b/indra/newview/skins/default/xui/fr/floater_buy_currency_html.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_buy_land.xml b/indra/newview/skins/default/xui/fr/floater_buy_land.xml
index b7f8f36f81..b7f8f36f81 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_buy_land.xml
+++ b/indra/newview/skins/default/xui/fr/floater_buy_land.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_buy_object.xml b/indra/newview/skins/default/xui/fr/floater_buy_object.xml
index 519e741a25..519e741a25 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_buy_object.xml
+++ b/indra/newview/skins/default/xui/fr/floater_buy_object.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_camera.xml b/indra/newview/skins/default/xui/fr/floater_camera.xml
index f2b0ee8af3..893e389f69 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_camera.xml
+++ b/indra/newview/skins/default/xui/fr/floater_camera.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="camera_floater" title="PARAMÈTRES DE LA CAMÉRA">
+<floater name="camera_floater" title="CONTRÔLE DE LA CAMÉRA">
<floater.string name="rotate_tooltip">
Faire tourner la caméra autour du point central
</floater.string>
diff --git a/indra/newview/skins/default/xui/fr/floater_chat_bar.xml b/indra/newview/skins/default/xui/fr/floater_chat_bar.xml
index 890411d091..7dcb9a280d 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_chat_bar.xml
+++ b/indra/newview/skins/default/xui/fr/floater_chat_bar.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="chat_bar" title="CHAT PRÈS DE MOI">
+<floater name="nearby_chat" title="CHAT PRÈS DE MOI">
<panel name="bottom_panel">
<line_editor label="Cliquer ici pour chatter." name="chat_box" tool_tip="Appuyer sur Entrée pour dire, Ctrl+Entrée pour crier"/>
<button name="show_nearby_chat" tool_tip="Afficher/masquer le journal de chat près de vous."/>
diff --git a/indra/newview/skins/default/xui/fr/floater_choose_group.xml b/indra/newview/skins/default/xui/fr/floater_choose_group.xml
index b73bedd7b5..b73bedd7b5 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_choose_group.xml
+++ b/indra/newview/skins/default/xui/fr/floater_choose_group.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_color_picker.xml b/indra/newview/skins/default/xui/fr/floater_color_picker.xml
index c54e3e9ce0..c54e3e9ce0 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_color_picker.xml
+++ b/indra/newview/skins/default/xui/fr/floater_color_picker.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_conversation_log.xml b/indra/newview/skins/default/xui/fr/floater_conversation_log.xml
new file mode 100644
index 0000000000..e9017c79b1
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/floater_conversation_log.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="floater_conversation_log" title="JOURNAL DES CONVERSATIONS">
+ <panel name="buttons_panel">
+ <filter_editor label="Filtrer les personnes" name="people_filter_input"/>
+ <menu_button name="conversation_view_btn" tool_tip="Options d&apos;affichage/de tri"/>
+ <menu_button name="conversations_gear_btn" tool_tip="Actions sur la personne ou le groupe sélectionné"/>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/fr/floater_conversation_preview.xml b/indra/newview/skins/default/xui/fr/floater_conversation_preview.xml
new file mode 100644
index 0000000000..9a486a84c6
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/floater_conversation_preview.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="preview_conversation" title="CONVERSATION:">
+ <floater.string name="Title">
+ CONVERSATION: [NAME]
+ </floater.string>
+ <text name="page_label" value="Page"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/fr/floater_critical.xml b/indra/newview/skins/default/xui/fr/floater_critical.xml
index 6d30d97048..6d30d97048 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_critical.xml
+++ b/indra/newview/skins/default/xui/fr/floater_critical.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_delete_env_preset.xml b/indra/newview/skins/default/xui/fr/floater_delete_env_preset.xml
index 035bdbe5f3..035bdbe5f3 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_delete_env_preset.xml
+++ b/indra/newview/skins/default/xui/fr/floater_delete_env_preset.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_destinations.xml b/indra/newview/skins/default/xui/fr/floater_destinations.xml
index 25e6c90a8e..25e6c90a8e 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_destinations.xml
+++ b/indra/newview/skins/default/xui/fr/floater_destinations.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_display_name.xml b/indra/newview/skins/default/xui/fr/floater_display_name.xml
index eebe7abf2c..eebe7abf2c 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_display_name.xml
+++ b/indra/newview/skins/default/xui/fr/floater_display_name.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_edit_day_cycle.xml b/indra/newview/skins/default/xui/fr/floater_edit_day_cycle.xml
index 0100419bc5..5ec68458e1 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_edit_day_cycle.xml
+++ b/indra/newview/skins/default/xui/fr/floater_edit_day_cycle.xml
@@ -22,13 +22,13 @@
Remarque : si vous changez votre préréglage de nom, un nouveau préréglage sera créé et celui existant restera tel quel.
</text>
<text name="hint_item1">
- - Cliquez sur un repère pour modifier le réglage du ciel et l&apos;heure associés.
+ - Modifier un réglage de ciel/heure : clic sur le repère
</text>
<text name="hint_item2">
- - Cliquez sur les repères et faites-les glisser afin de définir les heures de transition.
+ - Heures de transition : clic-glissement des repères
</text>
<text name="hint_item3">
- - Déplacez le marqueur en forme de triangle pour afficher un aperçu du cycle du jour.
+ - Aperçu du cycle du jour : déplacement du triangle
</text>
<panel name="day_cycle_slider_panel">
<multi_slider initial_value="0" name="WLTimeSlider"/>
@@ -91,11 +91,11 @@
</text>
</panel>
<text name="WLCurKeyPresetText">
- Réglage du ciel :
+ Régl. ciel :
</text>
<combo_box label="Préréglage" name="WLSkyPresets"/>
<text name="WLCurKeyTimeText">
- Heure :
+ H. :
</text>
<time name="time" value="6h"/>
<check_box label="Appliquer ce nouveau cycle du jour" name="make_default_cb"/>
diff --git a/indra/newview/skins/default/xui/fr/floater_edit_sky_preset.xml b/indra/newview/skins/default/xui/fr/floater_edit_sky_preset.xml
index 4ec9bbb3dd..4ec9bbb3dd 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_edit_sky_preset.xml
+++ b/indra/newview/skins/default/xui/fr/floater_edit_sky_preset.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_edit_water_preset.xml b/indra/newview/skins/default/xui/fr/floater_edit_water_preset.xml
index 81d9d34cfb..81d9d34cfb 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_edit_water_preset.xml
+++ b/indra/newview/skins/default/xui/fr/floater_edit_water_preset.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_environment_settings.xml b/indra/newview/skins/default/xui/fr/floater_environment_settings.xml
index 9ea47a3dd7..ea12749d27 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_environment_settings.xml
+++ b/indra/newview/skins/default/xui/fr/floater_environment_settings.xml
@@ -18,7 +18,7 @@
<combo_box.item label="-Effectuer une sélection-" name="item0"/>
</combo_box>
<text name="sky_dayc_settings_title">
- Ciel / Cycle du jour
+ Ciel/Cycle du jour
</text>
<radio_group name="sky_dayc_settings_radio_group">
<radio_item label="Ciel fixe" name="my_sky_settings"/>
diff --git a/indra/newview/skins/default/xui/fr/floater_event.xml b/indra/newview/skins/default/xui/fr/floater_event.xml
index 67d70ac003..67d70ac003 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_event.xml
+++ b/indra/newview/skins/default/xui/fr/floater_event.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_fast_timers.xml b/indra/newview/skins/default/xui/fr/floater_fast_timers.xml
index 0100b10557..0100b10557 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_fast_timers.xml
+++ b/indra/newview/skins/default/xui/fr/floater_fast_timers.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_font_test.xml b/indra/newview/skins/default/xui/fr/floater_font_test.xml
index 974a5ca3a2..974a5ca3a2 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_font_test.xml
+++ b/indra/newview/skins/default/xui/fr/floater_font_test.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_gesture.xml b/indra/newview/skins/default/xui/fr/floater_gesture.xml
index 5ead1cae3a..5ead1cae3a 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_gesture.xml
+++ b/indra/newview/skins/default/xui/fr/floater_gesture.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_god_tools.xml b/indra/newview/skins/default/xui/fr/floater_god_tools.xml
index e4c53d866c..0d21a8af32 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_god_tools.xml
+++ b/indra/newview/skins/default/xui/fr/floater_god_tools.xml
@@ -71,8 +71,8 @@
<button label="Supprimer tous les objets scriptés de la cible sur les terrains des autres" label_selected="Supprimer tous les objets scriptés de la cible sur les terrains des autres" name="Delete Target&apos;s Scripted Objects On Others Land" tool_tip="Supprimer tous les objets scriptés appartenant à la cible sur les terrains ne lui appartenant pas. Les objets non copiables seront renvoyés."/>
<button label="Supprimer les objets scriptés de la cible sur *tous* les terrains" label_selected="Supprimer les objets scriptés de la cible sur *tous* les terrains" name="Delete Target&apos;s Scripted Objects On *Any* Land" tool_tip="Supprimer les objets scriptés appartenant à la cible dans cette région. Les objets non copiables seront renvoyés."/>
<button label="Supprimer *tous* les objets de la cible" label_selected="Supprimer *tous* les objets de la cible" name="Delete *ALL* Of Target&apos;s Objects" tool_tip="Supprimer tous les objets appartenant à la cible dans cette région. Les objets non copiables seront renvoyés."/>
- <button label="Afficher les collisions les plus consommatrices" label_selected="Afficher les collisions les plus consommatrices" name="Get Top Colliders" tool_tip="Dresse une liste des objets avec les callbacks les plus fréquents. " width="300"/>
- <button label="Afficher les objets scriptés les plus consommateurs" label_selected="Afficher les objets scriptés les plus consommateurs" name="Get Top Scripts" tool_tip="Dresse une liste des objets qui passent le plus de temps à exécuter des scripts." width="300"/>
+ <button label="Collisions les plus consommatrices" label_selected="Collisions les plus consommatrices" name="Get Top Colliders" tool_tip="Liste des objets avec les callbacks les plus fréquents. " width="300"/>
+ <button label="Scripts les plus consommateurs" label_selected="Scripts les plus consommateurs" name="Get Top Scripts" tool_tip="Liste des objets passant le plus de temps à exécuter des scripts." width="300"/>
<button label="Résumé des scripts" label_selected="Résumé des scripts" name="Scripts digest" tool_tip="Dresse une liste des scripts et de leurs occurrences." width="300"/>
</panel>
<panel label="Requête" name="request">
diff --git a/indra/newview/skins/default/xui/fr/floater_goto_line.xml b/indra/newview/skins/default/xui/fr/floater_goto_line.xml
new file mode 100644
index 0000000000..fdc800b40b
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/floater_goto_line.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="script goto" title="ALLER À LA LIGNE">
+ <button label="OK" label_selected="OK" name="goto_btn"/>
+ <text name="txt">
+ Aller à la ligne
+ </text>
+</floater>
diff --git a/indra/newview/skins/default/xui/fr/floater_hardware_settings.xml b/indra/newview/skins/default/xui/fr/floater_hardware_settings.xml
index 2bc76e0c63..bb146556ba 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_hardware_settings.xml
+++ b/indra/newview/skins/default/xui/fr/floater_hardware_settings.xml
@@ -25,6 +25,10 @@
Activer le VBO :
</text>
<check_box initial_value="true" label="Activer OpenGL Vertex Buffer Objects" name="vbo" tool_tip="Sur un matériel moderne, cette option permet une meilleure performance. Par contre, sur un matériel plus ancien, les VBO sont souvent mal implémentés et peuvent causer des crashs lorsqu&apos;ils sont activés."/>
+ <text name="tc label">
+ Activer S3TC :
+ </text>
+ <check_box initial_value="true" label="Activer la compression des textures (redémarrage requis)" name="texture compression" tool_tip="Comprime les textures en mémoire vidéo afin de permettre de charger des textures de résolution plus élevée au prix d&apos;une certaine qualité de couleur."/>
<slider label="Mémoire textures (Mo) :" name="GraphicsCardTextureMemory" tool_tip="Quantité de mémoire à affecter aux textures. Utilise la mémoire de la carte vidéo par défaut. Si vous réduisez ce paramètre, cela peut améliorer les performances, mais les textures risquent d&apos;être floues."/>
<spinner label="Indice du brouillard :" name="fog"/>
<button label="OK" label_selected="OK" name="OK"/>
diff --git a/indra/newview/skins/default/xui/fr/floater_help_browser.xml b/indra/newview/skins/default/xui/fr/floater_help_browser.xml
index 11caca640c..11caca640c 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_help_browser.xml
+++ b/indra/newview/skins/default/xui/fr/floater_help_browser.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_how_to.xml b/indra/newview/skins/default/xui/fr/floater_how_to.xml
index a414212ba0..a414212ba0 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_how_to.xml
+++ b/indra/newview/skins/default/xui/fr/floater_how_to.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_hud.xml b/indra/newview/skins/default/xui/fr/floater_hud.xml
index f212f113b3..f212f113b3 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_hud.xml
+++ b/indra/newview/skins/default/xui/fr/floater_hud.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_im_container.xml b/indra/newview/skins/default/xui/fr/floater_im_container.xml
index 5ea073365e..f0b17e8437 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_im_container.xml
+++ b/indra/newview/skins/default/xui/fr/floater_im_container.xml
@@ -1,2 +1,29 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<multi_floater name="floater_im_box" title="CONVERSATIONS"/>
+<multi_floater name="floater_im_box" title="CONVERSATIONS">
+ <string name="collapse_icon" value="Conv_toolbar_collapse"/>
+ <string name="expand_icon" value="Conv_toolbar_expand"/>
+ <layout_stack name="conversations_stack">
+ <layout_panel name="conversations_layout_panel">
+ <layout_stack name="conversations_pane_buttons_stack">
+ <layout_panel name="conversations_pane_buttons_expanded">
+ <menu_button name="sort_btn" tool_tip="Options d&apos;affichage/de tri"/>
+ <button name="add_btn" tool_tip="Commencer une nouvelle conversation"/>
+ <button name="speak_btn" tool_tip="Parler aux personnes en utilisant votre micro"/>
+ </layout_panel>
+ <layout_panel name="conversations_pane_buttons_collapsed">
+ <button name="expand_collapse_btn" tool_tip="Réduire/Développer cette liste"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ <layout_panel name="messages_layout_panel">
+ <panel_container name="im_box_tab_container">
+ <panel name="stub_panel">
+ <button name="stub_collapse_btn" tool_tip="Réduire ce panneau"/>
+ <text name="stub_textbox">
+ Cette conversation s&apos;affiche dans une fenêtre distincte. [secondlife:/// la rattacher.]
+ </text>
+ </panel>
+ </panel_container>
+ </layout_panel>
+ </layout_stack>
+</multi_floater>
diff --git a/indra/newview/skins/default/xui/fr/floater_im_session.xml b/indra/newview/skins/default/xui/fr/floater_im_session.xml
index 516eb41362..6d98f0a846 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/fr/floater_im_session.xml
@@ -1,8 +1,57 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="panel_im">
- <layout_stack name="im_panels">
- <layout_panel>
- <line_editor label="À" name="chat_editor"/>
- </layout_panel>
- </layout_stack>
+ <floater.string name="call_btn_start">
+ Conv_toolbar_open_call
+ </floater.string>
+ <floater.string name="call_btn_stop">
+ Conv_toolbar_hang_up
+ </floater.string>
+ <floater.string name="collapseline_icon" value="Conv_collapse_to_one_line"/>
+ <floater.string name="expandline_icon" value="Conv_expand_one_line"/>
+ <floater.string name="collapse_icon" value="Conv_toolbar_collapse"/>
+ <floater.string name="expand_icon" value="Conv_toolbar_expand"/>
+ <floater.string name="tear_off_icon" value="Conv_toolbar_arrow_ne"/>
+ <floater.string name="return_icon" value="Conv_toolbar_arrow_sw"/>
+ <floater.string name="participant_added" value="[NAME] a été invité à la conversation."/>
+ <floater.string name="multiple_participants_added" value="[NAME] ont été invités à la conversation."/>
+ <floater.string name="tooltip_to_separate_window" value="Déplacer cette conversation dans une fenêtre distincte"/>
+ <floater.string name="tooltip_to_main_window" value="Replacer cette conversation dans la fenêtre principale"/>
+ <floater.string name="start_call_button_tooltip" value="Ouvrir une connexion vocale"/>
+ <floater.string name="end_call_button_tooltip" value="Fermer la connexion vocale"/>
+ <floater.string name="expcol_button_not_tearoff_tooltip" value="Réduire ce panneau"/>
+ <floater.string name="expcol_button_tearoff_and_expanded_tooltip" value="Réduire la liste des participants"/>
+ <floater.string name="expcol_button_tearoff_and_collapsed_tooltip" value="Développer la liste des participants"/>
+ <view name="contents_view">
+ <layout_stack name="main_stack">
+ <layout_panel name="toolbar_panel">
+ <menu_button name="view_options_btn" tool_tip="Options d&apos;affichage/de tri"/>
+ <menu_button name="gear_btn" tool_tip="Actions sur la personne sélectionnée"/>
+ <button name="add_btn" tool_tip="Ajouter un participant à cette conversation"/>
+ <button name="voice_call_btn" tool_tip="Ouvrir une connexion vocale"/>
+ <button name="close_btn" tool_tip="Mettre fin à cette conversation"/>
+ <button name="expand_collapse_btn" tool_tip="Réduire/Développer ce panneau"/>
+ </layout_panel>
+ <layout_panel name="body_panel">
+ <layout_stack name="im_panels">
+ <layout_panel name="right_part_holder">
+ <layout_stack name="translate_and_chat_stack">
+ <layout_panel name="translate_chat_checkbox_lp">
+ <check_box label="Traduire le chat" name="translate_chat_checkbox"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ <layout_panel name="chat_layout_panel">
+ <layout_stack name="input_panels">
+ <layout_panel name="input_editor_layout_panel">
+ <chat_editor label="À" name="chat_editor"/>
+ </layout_panel>
+ <layout_panel name="input_button_layout_panel">
+ <button name="minz_btn" tool_tip="Affiche/Masque le panneau des messages"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
+ </view>
</floater>
diff --git a/indra/newview/skins/default/xui/fr/floater_image_preview.xml b/indra/newview/skins/default/xui/fr/floater_image_preview.xml
index 3d405f358d..3d405f358d 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_image_preview.xml
+++ b/indra/newview/skins/default/xui/fr/floater_image_preview.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_import_collada.xml b/indra/newview/skins/default/xui/fr/floater_import_collada.xml
index 03804c4bd5..03804c4bd5 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_import_collada.xml
+++ b/indra/newview/skins/default/xui/fr/floater_import_collada.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_incoming_call.xml b/indra/newview/skins/default/xui/fr/floater_incoming_call.xml
index 7594eec5f2..9e6946ba9e 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_incoming_call.xml
+++ b/indra/newview/skins/default/xui/fr/floater_incoming_call.xml
@@ -10,7 +10,7 @@
anonyme
</floater.string>
<floater.string name="VoiceInviteP2P">
- appelle.
+ vous appelle.
</floater.string>
<floater.string name="VoiceInviteAdHoc">
a rejoint un chat vocal avec conférence.
@@ -25,9 +25,9 @@
Voulez-vous quitter [CURRENT_CHAT] et rejoindre ce chat vocal ?
</floater.string>
<text name="question">
- Voulez-vous quitter [CURRENT_CHAT] et rejoindre ce chat vocal ?
+ Si vous répondez, vous serez déconnecté de votre conversation vocale actuelle.
</text>
- <button label="Accepter" label_selected="Accepter" name="Accept"/>
- <button label="Refuser" label_selected="Refuser" name="Reject"/>
- <button label="Lancer IM" name="Start IM"/>
+ <button label="Répondre" label_selected="Répondre" name="Accept"/>
+ <button label="Ignorer" label_selected="Ignorer" name="Reject"/>
+ <button label="Ouvrir IM à la place" name="Start IM"/>
</floater>
diff --git a/indra/newview/skins/default/xui/fr/floater_inspect.xml b/indra/newview/skins/default/xui/fr/floater_inspect.xml
index 9b1bdf106d..9b1bdf106d 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_inspect.xml
+++ b/indra/newview/skins/default/xui/fr/floater_inspect.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_inventory.xml b/indra/newview/skins/default/xui/fr/floater_inventory.xml
deleted file mode 100644
index 200c07e522..0000000000
--- a/indra/newview/skins/default/xui/fr/floater_inventory.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Inventory" title="MON INVENTAIRE">
- <floater.string name="Title">
- MON INVENTAIRE
- </floater.string>
- <floater.string name="TitleFetching">
- MON INVENTAIRE (récupération de [ITEM_COUNT] articles en cours) [FILTER]
- </floater.string>
- <floater.string name="TitleCompleted">
- MON INVENTAIRE ([ITEM_COUNT] articles) [FILTER]
- </floater.string>
- <floater.string name="Fetched">
- Récupéré
- </floater.string>
- <panel label="Panneau Inventaire" name="Inventory Panel"/>
-</floater>
diff --git a/indra/newview/skins/default/xui/fr/floater_inventory_item_properties.xml b/indra/newview/skins/default/xui/fr/floater_inventory_item_properties.xml
index f2eb3cb6bc..f2eb3cb6bc 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_inventory_item_properties.xml
+++ b/indra/newview/skins/default/xui/fr/floater_inventory_item_properties.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_inventory_view_finder.xml b/indra/newview/skins/default/xui/fr/floater_inventory_view_finder.xml
index 7567817f3a..7567817f3a 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_inventory_view_finder.xml
+++ b/indra/newview/skins/default/xui/fr/floater_inventory_view_finder.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_joystick.xml b/indra/newview/skins/default/xui/fr/floater_joystick.xml
index 02ac21bf82..02ac21bf82 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_joystick.xml
+++ b/indra/newview/skins/default/xui/fr/floater_joystick.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_lagmeter.xml b/indra/newview/skins/default/xui/fr/floater_lagmeter.xml
index 39a861d8bd..39a861d8bd 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_lagmeter.xml
+++ b/indra/newview/skins/default/xui/fr/floater_lagmeter.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_land_holdings.xml b/indra/newview/skins/default/xui/fr/floater_land_holdings.xml
index 10fe132623..ff728e3aaa 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_land_holdings.xml
+++ b/indra/newview/skins/default/xui/fr/floater_land_holdings.xml
@@ -7,7 +7,7 @@
<column label="Surface" name="area"/>
<column label="" name="hidden"/>
</scroll_list>
- <button label="Téléporter" label_selected="Téléporter" name="Teleport" tool_tip="Téléportez-vous au milieu de ce terrain."/>
+ <button label="Téléportation" label_selected="Téléportation" name="Teleport" tool_tip="Téléportez-vous au milieu de ce terrain."/>
<button label="Carte" label_selected="Carte" name="Show on Map" tool_tip="Afficher ce terrain sur la carte du monde"/>
<text name="contrib_label">
Vos contributions :
diff --git a/indra/newview/skins/default/xui/fr/floater_live_lsleditor.xml b/indra/newview/skins/default/xui/fr/floater_live_lsleditor.xml
index 7647452e91..7647452e91 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_live_lsleditor.xml
+++ b/indra/newview/skins/default/xui/fr/floater_live_lsleditor.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_lsl_guide.xml b/indra/newview/skins/default/xui/fr/floater_lsl_guide.xml
index 71d2c42578..71d2c42578 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_lsl_guide.xml
+++ b/indra/newview/skins/default/xui/fr/floater_lsl_guide.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_map.xml b/indra/newview/skins/default/xui/fr/floater_map.xml
index dbd3dd9406..dbd3dd9406 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_map.xml
+++ b/indra/newview/skins/default/xui/fr/floater_map.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_media_browser.xml b/indra/newview/skins/default/xui/fr/floater_media_browser.xml
index 58535eddf5..58535eddf5 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_media_browser.xml
+++ b/indra/newview/skins/default/xui/fr/floater_media_browser.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_media_settings.xml b/indra/newview/skins/default/xui/fr/floater_media_settings.xml
index 27db5ea995..27db5ea995 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_media_settings.xml
+++ b/indra/newview/skins/default/xui/fr/floater_media_settings.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_mem_leaking.xml b/indra/newview/skins/default/xui/fr/floater_mem_leaking.xml
index d03c4d7544..d03c4d7544 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_mem_leaking.xml
+++ b/indra/newview/skins/default/xui/fr/floater_mem_leaking.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_merchant_outbox.xml b/indra/newview/skins/default/xui/fr/floater_merchant_outbox.xml
index b491dd6aed..b491dd6aed 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_merchant_outbox.xml
+++ b/indra/newview/skins/default/xui/fr/floater_merchant_outbox.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_model_preview.xml b/indra/newview/skins/default/xui/fr/floater_model_preview.xml
index a3b50351ae..bd3dae6599 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_model_preview.xml
+++ b/indra/newview/skins/default/xui/fr/floater_model_preview.xml
@@ -92,19 +92,54 @@
<text initial_value="Triangles" name="triangles" value="Triangles"/>
<text initial_value="Sommets" name="vertices" value="Sommets"/>
<text initial_value="Élevé" name="high_label" value="Élevé"/>
+ <combo_box name="lod_source_high">
+ <item name="Load from file" value="Depuis un fichier"/>
+ <item name="Generate" value="Génération"/>
+ </combo_box>
<button label="Parcourir..." name="lod_browse_high"/>
+ <combo_box name="lod_mode_high">
+ <item name="Triangle Limit" value="Triangles max"/>
+ <item name="Error Threshold" value="Seuil d&apos;erreur"/>
+ </combo_box>
<text initial_value="0" name="high_triangles" value="0"/>
<text initial_value="0" name="high_vertices" value="0"/>
<text initial_value="Moyen" name="medium_label" value="Moyen"/>
+ <combo_box name="lod_source_medium">
+ <item name="Load from file" value="Depuis un fichier"/>
+ <item name="Generate" value="Génération"/>
+ <item name="Use LoD above" value="Niveau de détail du dessus"/>
+ </combo_box>
<button label="Parcourir..." name="lod_browse_medium"/>
+ <combo_box name="lod_mode_medium">
+ <item name="Triangle Limit" value="Triangles max"/>
+ <item name="Error Threshold" value="Seuil d&apos;erreur"/>
+ </combo_box>
<text initial_value="0" name="medium_triangles" value="0"/>
<text initial_value="0" name="medium_vertices" value="0"/>
<text initial_value="Faible" name="low_label" value="Faible"/>
+ <combo_box name="lod_source_low">
+ <item name="Load from file" value="Depuis un fichier"/>
+ <item name="Generate" value="Génération"/>
+ <item name="Use LoD above" value="Niveau de détail du dessus"/>
+ </combo_box>
<button label="Parcourir..." name="lod_browse_low"/>
+ <combo_box name="lod_mode_low">
+ <item name="Triangle Limit" value="Triangles max"/>
+ <item name="Error Threshold" value="Seuil d&apos;erreur"/>
+ </combo_box>
<text initial_value="0" name="low_triangles" value="0"/>
<text initial_value="0" name="low_vertices" value="0"/>
<text initial_value="Le plus faible" name="lowest_label" value="Le plus faible"/>
+ <combo_box name="lod_source_lowest">
+ <item name="Load from file" value="Depuis un fichier"/>
+ <item name="Generate" value="Génération"/>
+ <item name="Use LoD above" value="Niveau de détail du dessus"/>
+ </combo_box>
<button label="Parcourir..." name="lod_browse_lowest"/>
+ <combo_box name="lod_mode_lowest">
+ <item name="Triangle Limit" value="Triangles max"/>
+ <item name="Error Threshold" value="Seuil d&apos;erreur"/>
+ </combo_box>
<text initial_value="0" name="lowest_triangles" value="0"/>
<text initial_value="0" name="lowest_vertices" value="0"/>
<check_box label="Génération de normales" name="gen_normals"/>
@@ -166,7 +201,7 @@
Passes :
</text>
<text name="Detail Scale label">
- Échelle de détail :
+ Échelle détail :
</text>
<text name="Retain%_label">
Retenue :
@@ -192,7 +227,7 @@
</panel>
<panel label="Option de chargement" name="modifiers_panel">
<text name="scale_label">
- Echelle (1 = pas d&apos;échelle) :
+ Échelle (1 = aucune) :
</text>
<spinner name="import_scale" value="1.0"/>
<text name="dimensions_label">
@@ -203,21 +238,21 @@
</text>
<check_box label="Inclure les textures" name="upload_textures"/>
<text name="include_label">
- Pour les modèles d&apos;avatar uniquement :
+ Modèles d&apos;avatar uniquement :
</text>
- <check_box label="Inclure la pondération de la peau :" name="upload_skin"/>
- <check_box label="Inclure la position des articulations :" name="upload_joints"/>
+ <check_box label="Inclure pondération de la peau :" name="upload_skin"/>
+ <check_box label="Inclure position des articulations :" name="upload_joints"/>
<text name="pelvis_offset_label">
- Décalage Z (élever ou abaisser l&apos;avatar) :
+ Décalage Z (élever/abaisser l&apos;avatar) :
</text>
<spinner name="pelvis_offset" value="0.0"/>
</panel>
</tab_container>
<panel name="weights_and_warning_panel">
- <button label="Calculer les poids et les frais." name="calculate_btn" tool_tip="Calculer les poids et les frais."/>
+ <button label="Calculer les poids et les frais" name="calculate_btn" tool_tip="Calculer les poids et les frais."/>
<button label="Annuler" name="cancel_btn"/>
<button label="Charger le modèle" name="ok_btn" tool_tip="Charger dans le simulateur"/>
- <button label="Effacer les paramètres et réinitialiser le formulaire" name="reset_btn"/>
+ <button label="Effacer les paramètres / réinitialiser le formulaire" name="reset_btn"/>
<text name="upload_fee">
Frais de chargement : [FEE] L$
</text>
diff --git a/indra/newview/skins/default/xui/fr/floater_model_wizard.xml b/indra/newview/skins/default/xui/fr/floater_model_wizard.xml
deleted file mode 100644
index 128b9d6fa4..0000000000
--- a/indra/newview/skins/default/xui/fr/floater_model_wizard.xml
+++ /dev/null
@@ -1,208 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Model Wizard" title="ASSISTANT DE CHARGEMENT DE MODÈLE">
- <button label="5. Chargement" name="upload_btn"/>
- <button label="4. Vérification" name="review_btn"/>
- <button label="3. Propriétés physiques" name="physics_btn"/>
- <button label="2. Optimisation" name="optimize_btn"/>
- <button label="1. Sélection du fichier" name="choose_file_btn"/>
- <panel name="choose_file_panel">
- <panel name="choose_file_header_panel">
- <text name="choose_file_header_text">
- Choisir un fichier de modèle
- </text>
- </panel>
- <panel name="choose_file_content">
- <text name="advanced_users_text">
- Utilisateurs expérimentés : si vous êtes habitué à utiliser des outils de création de contenu en 3D, l&apos;outil de chargement avancé est mis à votre disposition.
- </text>
- <button label="Passer à Avancé" name="switch_to_advanced"/>
- <text name="Cache location">
- Choisir un fichier de modèle à charger
- </text>
- <button label="Parcourir..." label_selected="Parcourir..." name="browse"/>
- <text name="Model types">
- Second Life prend en charge les fichiers COLLADA (.dae).
- </text>
- <text name="dimensions">
- X Y Z
- </text>
- <text name="warning_label">
- AVERTISSEMENT :
- </text>
- <text name="warning_text">
- Vous ne pourrez pas effectuer l&apos;étape de chargement finale du modèle sur les serveurs Second Life. [secondlife:///app/floater/learn_more Découvrez comment] configurer votre compte pour le chargement de modèles de maillage.
- </text>
- </panel>
- </panel>
- <panel name="optimize_panel">
- <panel name="optimize_header_panel">
- <text name="optimize_header_text">
- Optimiser le modèle
- </text>
- </panel>
- <text name="optimize_description">
- Le modèle a été optimisé en termes de performances. Vous pouvez l&apos;ajuster si vous le souhaitez.
- </text>
- <panel name="optimize_content">
- <text name="high_detail_text">
- Générer le niveau de détail : Élevé
- </text>
- <text name="medium_detail_text">
- Générer le niveau de détail : Moyen
- </text>
- <text name="low_detail_text">
- Générer le niveau de détail : Faible
- </text>
- <text name="lowest_detail_text">
- Générer le niveau de détail : Le plus faible
- </text>
- </panel>
- <panel name="content2">
- <button label="Recalcul géométrique" name="recalculate_geometry_btn"/>
- <text name="lod_label">
- Aperçu de la géométrie
- </text>
- <combo_box name="preview_lod_combo" tool_tip="Niveau de détail à afficher en rendu d&apos;aperçu.">
- <combo_item name="high">
- Niveau de détail élevé
- </combo_item>
- <combo_item name="medium">
- Niveau de détail moyen
- </combo_item>
- <combo_item name="low">
- Niveau de détail faible
- </combo_item>
- <combo_item name="lowest">
- Niveau de détail le plus faible
- </combo_item>
- </combo_box>
- </panel>
- </panel>
- <panel name="physics_panel">
- <panel name="physics_header_panel">
- <text name="physics_header_text">
- Ajuster les propriétés physiques
- </text>
- </panel>
- <text name="physics_description">
- Une forme va être créée pour l&apos;enveloppe externe du modèle. Ajustez le niveau de détail de la forme en fonction de l&apos;objectif souhaité pour votre modèle.
- </text>
- <panel name="physics_content">
- <button label="Recalcul physique" name="recalculate_physics_btn"/>
- <button label="Recalcul en cours..." name="recalculating_physics_btn"/>
- <text name="lod_label">
- Aperçu des propriétés physiques
- </text>
- <combo_box name="preview_lod_combo2" tool_tip="Niveau de détail à afficher en rendu d&apos;aperçu.">
- <combo_item name="high">
- Niveau de détail élevé
- </combo_item>
- <combo_item name="medium">
- Niveau de détail moyen
- </combo_item>
- <combo_item name="low">
- Niveau de détail faible
- </combo_item>
- <combo_item name="lowest">
- Niveau de détail le plus faible
- </combo_item>
- </combo_box>
- </panel>
- </panel>
- <panel name="review_panel">
- <panel name="review_header_panel">
- <text name="review_header_text">
- Vérification
- </text>
- </panel>
- <panel name="review_content">
- <text name="review_prim_equiv">
- Impact sur la parcelle/région : équivalent à [EQUIV] prims
- </text>
- <text name="review_fee">
- Votre compte sera débité de [FEE] L$ de frais de chargement.
- </text>
- <text name="review_confirmation">
- En cliquant sur le bouton de chargement, vous confirmez que vous disposez des droits appropriés sur le contenu du modèle.
- </text>
- </panel>
- </panel>
- <panel name="upload_panel">
- <panel name="upload_header_panel">
- <text name="upload_header_text">
- Chargement terminé
- </text>
- </panel>
- <text name="model_uploaded_text">
- Votre modèle a été chargé.
- </text>
- <text name="inventory_text">
- Vous le trouverez dans le dossier Objets de votre inventaire.
- </text>
- <text name="charged_fee">
- Votre compte a été débité de [FEE] L$.
- </text>
- </panel>
- <button label="&lt;&lt; Préc." name="back"/>
- <button label="Suiv. &gt;&gt;" name="next"/>
- <button label="Calculer les poids et les frais &gt;&gt;" name="calculate"/>
- <button label="Calcul en cours..." name="calculating"/>
- <button label="Charger" name="upload" tool_tip="Charger dans le simulateur."/>
- <button label="Annuler" name="cancel"/>
- <button label="Fermer" name="close"/>
- <spinner name="import_scale" value="1.0"/>
- <string name="status_idle">
- Inactif
- </string>
- <string name="status_parse_error">
- Problème d&apos;analyse de fichier .dae ; reportez-vous au journal pour plus de détails.
- </string>
- <string name="status_reading_file">
- Chargement...
- </string>
- <string name="status_generating_meshes">
- Génération des maillages...
- </string>
- <string name="status_vertex_number_overflow">
- Erreur : valeur de sommet supérieure à 65534. Opération abandonnée.
- </string>
- <string name="bad_element">
- Erreur : élément non valide
- </string>
- <string name="high">
- Élevé
- </string>
- <string name="medium">
- Moyen
- </string>
- <string name="low">
- Faible
- </string>
- <string name="lowest">
- Le plus faible
- </string>
- <string name="mesh_status_good">
- Bon à publier !
- </string>
- <string name="mesh_status_na">
- N/A
- </string>
- <string name="mesh_status_none">
- Aucun
- </string>
- <string name="mesh_status_submesh_mismatch">
- Un nombre différent de faces d&apos;application de texture est associé aux niveaux de détail.
- </string>
- <string name="mesh_status_mesh_mismatch">
- Un nombre différent d&apos;instances de maillage est associé aux niveaux de détail.
- </string>
- <string name="mesh_status_too_many_vertices">
- Trop de sommets pour le niveau de détail.
- </string>
- <string name="mesh_status_missing_lod">
- Niveau de détail requis manquant.
- </string>
- <string name="layer_all">
- Tout
- </string>
-</floater>
diff --git a/indra/newview/skins/default/xui/fr/floater_moveview.xml b/indra/newview/skins/default/xui/fr/floater_moveview.xml
index 853af2afdf..853af2afdf 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_moveview.xml
+++ b/indra/newview/skins/default/xui/fr/floater_moveview.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_mute_object.xml b/indra/newview/skins/default/xui/fr/floater_mute_object.xml
index f4db3201a8..f4db3201a8 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_mute_object.xml
+++ b/indra/newview/skins/default/xui/fr/floater_mute_object.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_my_appearance.xml b/indra/newview/skins/default/xui/fr/floater_my_appearance.xml
index 53ff58e307..53ff58e307 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_my_appearance.xml
+++ b/indra/newview/skins/default/xui/fr/floater_my_appearance.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_my_inventory.xml b/indra/newview/skins/default/xui/fr/floater_my_inventory.xml
index d514d08081..d514d08081 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_my_inventory.xml
+++ b/indra/newview/skins/default/xui/fr/floater_my_inventory.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_nearby_chat.xml b/indra/newview/skins/default/xui/fr/floater_nearby_chat.xml
deleted file mode 100644
index 8bbd34baae..0000000000
--- a/indra/newview/skins/default/xui/fr/floater_nearby_chat.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="nearby_chat" title="CHAT PRÈS DE MOI">
- <check_box label="Traduction du chat" name="translate_chat_checkbox"/>
-</floater>
diff --git a/indra/newview/skins/default/xui/fr/floater_notification.xml b/indra/newview/skins/default/xui/fr/floater_notification.xml
index fe4b5f9bd6..fe4b5f9bd6 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_notification.xml
+++ b/indra/newview/skins/default/xui/fr/floater_notification.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_notifications_console.xml b/indra/newview/skins/default/xui/fr/floater_notifications_console.xml
index e040e948f5..e040e948f5 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_notifications_console.xml
+++ b/indra/newview/skins/default/xui/fr/floater_notifications_console.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_object_weights.xml b/indra/newview/skins/default/xui/fr/floater_object_weights.xml
index 2667188308..2667188308 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_object_weights.xml
+++ b/indra/newview/skins/default/xui/fr/floater_object_weights.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_openobject.xml b/indra/newview/skins/default/xui/fr/floater_openobject.xml
index 4e046ff3f3..4e046ff3f3 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_openobject.xml
+++ b/indra/newview/skins/default/xui/fr/floater_openobject.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_outfit_save_as.xml b/indra/newview/skins/default/xui/fr/floater_outfit_save_as.xml
index 72018f5de5..72018f5de5 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_outfit_save_as.xml
+++ b/indra/newview/skins/default/xui/fr/floater_outfit_save_as.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_outgoing_call.xml b/indra/newview/skins/default/xui/fr/floater_outgoing_call.xml
index 089d710f17..089d710f17 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_outgoing_call.xml
+++ b/indra/newview/skins/default/xui/fr/floater_outgoing_call.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_pathfinding_characters.xml b/indra/newview/skins/default/xui/fr/floater_pathfinding_characters.xml
new file mode 100755
index 0000000000..7c9109c011
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/floater_pathfinding_characters.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="floater_pathfinding_characters" title="Personnages de recherche de chemin">
+ <floater.string name="messaging_get_inprogress">
+ Requête relative aux personnages de recherche de chemin en cours...
+ </floater.string>
+ <floater.string name="messaging_get_error">
+ Erreur lors de la requête relative aux personnages de recherche de chemin.
+ </floater.string>
+ <floater.string name="messaging_complete_none_found">
+ Aucun personnage de recherche de chemin.
+ </floater.string>
+ <floater.string name="messaging_complete_available">
+ [NUM_SELECTED] personnages sélectionnés sur [NUM_TOTAL].
+ </floater.string>
+ <floater.string name="messaging_not_enabled">
+ La recherche de chemin n&apos;a pas été activée pour cette région.
+ </floater.string>
+ <floater.string name="character_cpu_time">
+ [CPU_TIME] µs
+ </floater.string>
+ <floater.string name="character_owner_loading">
+ [Chargement]
+ </floater.string>
+ <floater.string name="character_owner_unknown">
+ [Inconnu]
+ </floater.string>
+ <floater.string name="character_owner_group">
+ [Groupe]
+ </floater.string>
+ <panel>
+ <scroll_list name="objects_scroll_list">
+ <scroll_list.columns label="Nom" name="name"/>
+ <scroll_list.columns label="Description" name="description"/>
+ <scroll_list.columns label="Propriétaire" name="owner"/>
+ <scroll_list.columns label="CPU" name="cpu_time"/>
+ <scroll_list.columns label="Altitude" name="altitude"/>
+ </scroll_list>
+ <text name="messaging_status">
+ Personnages :
+ </text>
+ <button label="Actualiser" name="refresh_objects_list"/>
+ <button label="Tout sélectionner" name="select_all_objects"/>
+ <button label="Ne rien sélectionner" name="select_none_objects"/>
+ </panel>
+ <panel>
+ <text name="actions_label">
+ Actions sur les personnages sélectionnés :
+ </text>
+ <check_box label="Afficher la balise" name="show_beacon"/>
+ <check_box label="Afficher la capsule physique" name="show_physics_capsule"/>
+ <button label="Prendre" name="take_objects"/>
+ <button label="Prendre une copie" name="take_copy_objects"/>
+ <button label="M&apos;y téléporter" name="teleport_me_to_object" tool_tip="Activé uniquement lorsqu&apos;un personnage est sélectionné."/>
+ <button label="Renvoyer" name="return_objects"/>
+ <button label="Supprimer" name="delete_objects"/>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/fr/floater_pathfinding_console.xml b/indra/newview/skins/default/xui/fr/floater_pathfinding_console.xml
new file mode 100755
index 0000000000..02d969dc08
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/floater_pathfinding_console.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="floater_pathfinding_console" title="Vue/Test de recherche de chemin">
+ <floater.string name="navmesh_viewer_status_library_not_implemented">
+ Implémentation de la bibliothèque de recherche de chemin introuvable
+ </floater.string>
+ <floater.string name="navmesh_viewer_status_region_not_enabled">
+ La recherche de chemin n&apos;a pas été activée pour cette région.
+ </floater.string>
+ <floater.string name="navmesh_viewer_status_region_loading">
+ En attente de fin de chargement de la région.
+ </floater.string>
+ <floater.string name="navmesh_viewer_status_checking_version">
+ Vérification de l&apos;état du maillage de navigation.
+ </floater.string>
+ <floater.string name="navmesh_viewer_status_downloading">
+ Téléchargement du maillage de navigation.
+ </floater.string>
+ <floater.string name="navmesh_viewer_status_updating">
+ Maillage de navigation modifié sur le serveur. Téléchargement du plus récent.
+ </floater.string>
+ <floater.string name="navmesh_viewer_status_has_navmesh">
+ Le maillage de navigation le plus récent a été téléchargé.
+ </floater.string>
+ <floater.string name="navmesh_viewer_status_error">
+ Impossible de télécharger le maillage de navigation.
+ </floater.string>
+ <floater.string name="navmesh_simulator_status_pending">
+ Des modifications sont en attente concernant le maillage de navigation.
+ </floater.string>
+ <floater.string name="navmesh_simulator_status_building">
+ Maillage de navigation en cours de création.
+ </floater.string>
+ <floater.string name="navmesh_simulator_status_some_pending">
+ Des modifications sont en attente pour certaines régions de maillage de navigation.
+ </floater.string>
+ <floater.string name="navmesh_simulator_status_some_building">
+ Certaines régions de maillage de navigation sont en cours de création.
+ </floater.string>
+ <floater.string name="navmesh_simulator_status_pending_and_building">
+ Des modifications sont en attente pour certaines régions de maillage de navigation et d&apos;autres sont en cours de création.
+ </floater.string>
+ <floater.string name="navmesh_simulator_status_complete">
+ Maillage de navigation à jour.
+ </floater.string>
+ <floater.string name="pathing_library_not_implemented">
+ Implémentation de la bibliothèque de recherche de chemin introuvable
+ </floater.string>
+ <floater.string name="pathing_region_not_enabled">
+ La recherche de chemin n&apos;a pas été activée pour cette région.
+ </floater.string>
+ <floater.string name="pathing_choose_start_and_end_points">
+ Choisissez un point de départ et un point d&apos;arrivée.
+ </floater.string>
+ <floater.string name="pathing_choose_start_point">
+ Choisissez un point de départ.
+ </floater.string>
+ <floater.string name="pathing_choose_end_point">
+ Choisissez un point d&apos;arrivée.
+ </floater.string>
+ <floater.string name="pathing_path_valid">
+ Le chemin s&apos;affiche en orange.
+ </floater.string>
+ <floater.string name="pathing_path_invalid">
+ Impossible de trouver un chemin entre les points choisis.
+ </floater.string>
+ <floater.string name="pathing_error">
+ Erreur lors de la génération du chemin.
+ </floater.string>
+ <tab_container name="view_test_tab_container">
+ <panel label="Vue" name="view_panel">
+ <text name="show_label">
+ Afficher :
+ </text>
+ <check_box label="Monde" name="show_world"/>
+ <check_box label="Mobiles uniquement" name="show_world_movables_only"/>
+ <check_box label="Maillage de navigation" name="show_navmesh"/>
+ <text name="show_walkability_label">
+ Où marcher est possible :
+ </text>
+ <combo_box name="show_heatmap_mode">
+ <combo_box.item label="Ne pas afficher" name="show_heatmap_mode_none"/>
+ <combo_box.item label="Type de personnage A" name="show_heatmap_mode_a"/>
+ <combo_box.item label="Type de personnage B" name="show_heatmap_mode_b"/>
+ <combo_box.item label="Type de personnage C" name="show_heatmap_mode_c"/>
+ <combo_box.item label="Type de personnage D" name="show_heatmap_mode_d"/>
+ </combo_box>
+ <check_box label="Marche possible" name="show_walkables"/>
+ <check_box label="Volumes de matériau" name="show_material_volumes"/>
+ <check_box label="Obstacles statiques" name="show_static_obstacles"/>
+ <check_box label="Volumes d&apos;exclusion" name="show_exclusion_volumes"/>
+ <check_box label="Plan de l&apos;eau" name="show_water_plane"/>
+ <check_box label="Mode rayons X" name="show_xray"/>
+ </panel>
+ <panel label="Chemin test" name="test_panel">
+ <text name="ctrl_click_label">
+ Ctrl-clic : sélection point de départ
+ </text>
+ <text name="shift_click_label">
+ Maj-clic : sélection point d&apos;arrivée
+ </text>
+ <text name="character_width_label">
+ Largeur du personnage
+ </text>
+ <slider name="character_width" value="1"/>
+ <text name="character_width_unit_label">
+ m
+ </text>
+ <text name="character_type_label">
+ Type de personnage
+ </text>
+ <combo_box name="path_character_type">
+ <combo_box.item label="Aucun" name="path_character_type_none"/>
+ <combo_box.item label="A" name="path_character_type_a"/>
+ <combo_box.item label="B" name="path_character_type_b"/>
+ <combo_box.item label="C" name="path_character_type_c"/>
+ <combo_box.item label="D" name="path_character_type_d"/>
+ </combo_box>
+ <button label="Effacer chemin" name="clear_path"/>
+ </panel>
+ </tab_container>
+</floater>
diff --git a/indra/newview/skins/default/xui/fr/floater_pathfinding_linksets.xml b/indra/newview/skins/default/xui/fr/floater_pathfinding_linksets.xml
new file mode 100755
index 0000000000..894ec6dd9c
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/floater_pathfinding_linksets.xml
@@ -0,0 +1,167 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="floater_pathfinding_linksets" title="Groupes de liens de recherche de chemin">
+ <floater.string name="messaging_get_inprogress">
+ Requête relative aux groupes de liens de recherche de chemin en cours...
+ </floater.string>
+ <floater.string name="messaging_get_error">
+ Erreur lors de la requête relative aux groupes de liens de recherche de chemin.
+ </floater.string>
+ <floater.string name="messaging_set_inprogress">
+ Modification des groupes de liens de recherche de chemin sélectionnés...
+ </floater.string>
+ <floater.string name="messaging_set_error">
+ Erreur lors de la modification des groupes de liens de recherche de chemin sélectionnés.
+ </floater.string>
+ <floater.string name="messaging_complete_none_found">
+ Aucun groupe de liens de recherche de chemin.
+ </floater.string>
+ <floater.string name="messaging_complete_available">
+ [NUM_SELECTED] groupes de liens sélectionnés sur [NUM_TOTAL].
+ </floater.string>
+ <floater.string name="messaging_not_enabled">
+ La recherche de chemin n&apos;a pas été activée pour cette région.
+ </floater.string>
+ <floater.string name="linkset_terrain_name">
+ [Terrain]
+ </floater.string>
+ <floater.string name="linkset_terrain_description">
+ --
+ </floater.string>
+ <floater.string name="linkset_terrain_owner">
+ --
+ </floater.string>
+ <floater.string name="linkset_terrain_scripted">
+ --
+ </floater.string>
+ <floater.string name="linkset_terrain_land_impact">
+ --
+ </floater.string>
+ <floater.string name="linkset_terrain_dist_from_you">
+ --
+ </floater.string>
+ <floater.string name="linkset_owner_loading">
+ [Chargement]
+ </floater.string>
+ <floater.string name="linkset_owner_unknown">
+ [Inconnu]
+ </floater.string>
+ <floater.string name="linkset_owner_group">
+ [Groupe]
+ </floater.string>
+ <floater.string name="linkset_is_scripted">
+ Oui
+ </floater.string>
+ <floater.string name="linkset_is_not_scripted">
+ Non
+ </floater.string>
+ <floater.string name="linkset_is_unknown_scripted">
+ Inconnu
+ </floater.string>
+ <floater.string name="linkset_use_walkable">
+ Marche possible
+ </floater.string>
+ <floater.string name="linkset_use_static_obstacle">
+ Obstacle statique
+ </floater.string>
+ <floater.string name="linkset_use_dynamic_obstacle">
+ Obstacle mobile
+ </floater.string>
+ <floater.string name="linkset_use_material_volume">
+ Volume de matériau
+ </floater.string>
+ <floater.string name="linkset_use_exclusion_volume">
+ Volume d&apos;exclusion
+ </floater.string>
+ <floater.string name="linkset_use_dynamic_phantom">
+ Fantôme mobile
+ </floater.string>
+ <floater.string name="linkset_is_terrain">
+ [Non modifiable]
+ </floater.string>
+ <floater.string name="linkset_is_restricted_state">
+ [Restriction]
+ </floater.string>
+ <floater.string name="linkset_is_non_volume_state">
+ [Concave]
+ </floater.string>
+ <floater.string name="linkset_is_restricted_non_volume_state">
+ [Restriction,Concave]
+ </floater.string>
+ <floater.string name="linkset_choose_use">
+ Choisir un usage de groupe de liens...
+ </floater.string>
+ <panel>
+ <combo_box name="filter_by_linkset_use">
+ <combo_box.item label="Filtrer par usage..." name="filter_by_linkset_use_none"/>
+ <combo_box.item label="Marche possible" name="filter_by_linkset_use_walkable"/>
+ <combo_box.item label="Obstacle statique" name="filter_by_linkset_use_static_obstacle"/>
+ <combo_box.item label="Obstacle mobile" name="filter_by_linkset_use_dynamic_obstacle"/>
+ <combo_box.item label="Volume de matériau" name="filter_by_linkset_use_material_volume"/>
+ <combo_box.item label="Volume d&apos;exclusion" name="filter_by_linkset_use_exclusion_volume"/>
+ <combo_box.item label="Fantôme mobile" name="filter_by_linkset_use_dynamic_phantom"/>
+ </combo_box>
+ <button label="Appliquer" name="apply_filters"/>
+ <button label="Effacer" name="clear_filters"/>
+ <scroll_list name="objects_scroll_list">
+ <scroll_list.columns label="Nom (prim racine)" name="name"/>
+ <scroll_list.columns label="Description (prim racine)" name="description"/>
+ <scroll_list.columns label="Propriétaire" name="owner"/>
+ <scroll_list.columns label="Scripté" name="scripted"/>
+ <scroll_list.columns label="Impact" name="land_impact"/>
+ <scroll_list.columns label="Distance" name="dist_from_you"/>
+ <scroll_list.columns label="Usage du groupe de liens" name="linkset_use"/>
+ <scroll_list.columns label="% A" name="a_percent"/>
+ <scroll_list.columns label="% B" name="b_percent"/>
+ <scroll_list.columns label="% C" name="c_percent"/>
+ <scroll_list.columns label="% D" name="d_percent"/>
+ </scroll_list>
+ <text name="messaging_status">
+ Groupes de liens :
+ </text>
+ <button label="Actualiser" name="refresh_objects_list"/>
+ <button label="Tout sélectionner" name="select_all_objects"/>
+ <button label="Ne rien sélectionner" name="select_none_objects"/>
+ </panel>
+ <panel>
+ <check_box label="Afficher la balise" name="show_beacon"/>
+ <button label="Prendre" name="take_objects"/>
+ <button label="Prendre une copie" name="take_copy_objects"/>
+ <button label="M&apos;y téléporter" name="teleport_me_to_object"/>
+ <button label="Renvoyer" name="return_objects"/>
+ <button label="Supprimer" name="delete_objects"/>
+ </panel>
+ <panel>
+ <text name="walkability_coefficients_label">
+ Marche possible :
+ </text>
+ <text name="edit_a_label">
+ A
+ </text>
+ <line_editor name="edit_a_value" tool_tip="Marche possible pour les personnages de type A. Exemple de type de personnage : humanoïde."/>
+ <text name="edit_b_label">
+ B
+ </text>
+ <line_editor name="edit_b_value" tool_tip="Marche possible pour les personnages de type B. Exemple de type de personnage : créature."/>
+ <text name="edit_c_label">
+ C
+ </text>
+ <line_editor name="edit_c_value" tool_tip="Marche possible pour les personnages de type C. Exemple de type de personnage : mécanique."/>
+ <text name="edit_d_label">
+ D
+ </text>
+ <line_editor name="edit_d_value" tool_tip="Marche possible pour les personnages de type D. Exemple de type de personnage : autre."/>
+ <button label="Appliquer les changements" name="apply_edit_values"/>
+ <text name="suggested_use_a_label">
+ (Humanoïde)
+ </text>
+ <text name="suggested_use_b_label">
+ (Créature)
+ </text>
+ <text name="suggested_use_c_label">
+ (Mécanique)
+ </text>
+ <text name="suggested_use_d_label">
+ (Autre)
+ </text>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/fr/floater_pay.xml b/indra/newview/skins/default/xui/fr/floater_pay.xml
index 397436876d..397436876d 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_pay.xml
+++ b/indra/newview/skins/default/xui/fr/floater_pay.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_pay_object.xml b/indra/newview/skins/default/xui/fr/floater_pay_object.xml
index 966fa3b8a6..966fa3b8a6 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_pay_object.xml
+++ b/indra/newview/skins/default/xui/fr/floater_pay_object.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_people.xml b/indra/newview/skins/default/xui/fr/floater_people.xml
index 58701c06b2..58701c06b2 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_people.xml
+++ b/indra/newview/skins/default/xui/fr/floater_people.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_perm_prefs.xml b/indra/newview/skins/default/xui/fr/floater_perm_prefs.xml
index 36bec80561..36bec80561 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_perm_prefs.xml
+++ b/indra/newview/skins/default/xui/fr/floater_perm_prefs.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_picks.xml b/indra/newview/skins/default/xui/fr/floater_picks.xml
index f058ff668b..f058ff668b 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_picks.xml
+++ b/indra/newview/skins/default/xui/fr/floater_picks.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_places.xml b/indra/newview/skins/default/xui/fr/floater_places.xml
index 9e649aca47..9e649aca47 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_places.xml
+++ b/indra/newview/skins/default/xui/fr/floater_places.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_post_process.xml b/indra/newview/skins/default/xui/fr/floater_post_process.xml
index a22c7512e5..a22c7512e5 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_post_process.xml
+++ b/indra/newview/skins/default/xui/fr/floater_post_process.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_postcard.xml b/indra/newview/skins/default/xui/fr/floater_postcard.xml
deleted file mode 100644
index e65dfb09b4..0000000000
--- a/indra/newview/skins/default/xui/fr/floater_postcard.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Postcard" title="ENVOYER LA PHOTO PAR E-MAIL">
- <text name="to_label">
- E-mail du destinataire :
- </text>
- <text name="from_label">
- Votre e-mail :
- </text>
- <text name="name_label">
- Votre nom :
- </text>
- <text name="subject_label">
- Objet :
- </text>
- <line_editor label="Saisir ici votre objet" name="subject_form"/>
- <text name="msg_label">
- Message :
- </text>
- <text_editor name="msg_form">
- Saisir ici votre message
- </text_editor>
- <text name="fine_print">
- Si le destinataire s&apos;inscrit sur [SECOND_LIFE], vous recevrez un bonus.
- </text>
- <button label="Annuler" name="cancel_btn"/>
- <button label="Envoyer" name="send_btn"/>
- <string name="default_subject">
- Carte postale de [SECOND_LIFE].
- </string>
- <string name="default_message">
- Ouvrez-moi !
- </string>
- <string name="upload_message">
- Envoi en cours...
- </string>
-</floater>
diff --git a/indra/newview/skins/default/xui/fr/floater_preferences.xml b/indra/newview/skins/default/xui/fr/floater_preferences.xml
index 0f9fb1334b..0f9fb1334b 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_preferences.xml
+++ b/indra/newview/skins/default/xui/fr/floater_preferences.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_preferences_proxy.xml b/indra/newview/skins/default/xui/fr/floater_preferences_proxy.xml
index 020bdf928b..020bdf928b 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_preferences_proxy.xml
+++ b/indra/newview/skins/default/xui/fr/floater_preferences_proxy.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_preview_animation.xml b/indra/newview/skins/default/xui/fr/floater_preview_animation.xml
index f2cb1d5e70..6488089c06 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_preview_animation.xml
+++ b/indra/newview/skins/default/xui/fr/floater_preview_animation.xml
@@ -6,6 +6,6 @@
<text name="desc txt">
Description :
</text>
- <button label="Exécuter dans Second Life" label_selected="Arrêter" name="Inworld" tool_tip="Lire cette animation de façon à ce que les autres la voient."/>
+ <button label="Exécuter dans SL" label_selected="Arrêter" name="Inworld" tool_tip="Lire cette animation de façon à ce que les autres la voient dans Second Life."/>
<button label="Exécuter localement" label_selected="Arrêter" name="Locally" tool_tip="Lire cette animation de façon à ce que vous soyez la seule personne à la voir."/>
</floater>
diff --git a/indra/newview/skins/default/xui/fr/floater_preview_gesture.xml b/indra/newview/skins/default/xui/fr/floater_preview_gesture.xml
index 6287f10f3e..6287f10f3e 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_preview_gesture.xml
+++ b/indra/newview/skins/default/xui/fr/floater_preview_gesture.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_preview_notecard.xml b/indra/newview/skins/default/xui/fr/floater_preview_notecard.xml
index 5646ad45eb..5646ad45eb 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_preview_notecard.xml
+++ b/indra/newview/skins/default/xui/fr/floater_preview_notecard.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_preview_sound.xml b/indra/newview/skins/default/xui/fr/floater_preview_sound.xml
index a215f92df1..a215f92df1 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_preview_sound.xml
+++ b/indra/newview/skins/default/xui/fr/floater_preview_sound.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_preview_texture.xml b/indra/newview/skins/default/xui/fr/floater_preview_texture.xml
index 9fc9d14026..9fc9d14026 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_preview_texture.xml
+++ b/indra/newview/skins/default/xui/fr/floater_preview_texture.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_price_for_listing.xml b/indra/newview/skins/default/xui/fr/floater_price_for_listing.xml
index a6e598dd2b..a6e598dd2b 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_price_for_listing.xml
+++ b/indra/newview/skins/default/xui/fr/floater_price_for_listing.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_publish_classified.xml b/indra/newview/skins/default/xui/fr/floater_publish_classified.xml
index d4d8652434..d4d8652434 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_publish_classified.xml
+++ b/indra/newview/skins/default/xui/fr/floater_publish_classified.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_region_debug_console.xml b/indra/newview/skins/default/xui/fr/floater_region_debug_console.xml
index 1747155b60..1747155b60 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_region_debug_console.xml
+++ b/indra/newview/skins/default/xui/fr/floater_region_debug_console.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_region_info.xml b/indra/newview/skins/default/xui/fr/floater_region_info.xml
index c2663174d4..c2663174d4 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_region_info.xml
+++ b/indra/newview/skins/default/xui/fr/floater_region_info.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_report_abuse.xml b/indra/newview/skins/default/xui/fr/floater_report_abuse.xml
index 78c35dc303..78c35dc303 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_report_abuse.xml
+++ b/indra/newview/skins/default/xui/fr/floater_report_abuse.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_script_debug.xml b/indra/newview/skins/default/xui/fr/floater_script_debug.xml
index e257aac6c4..e257aac6c4 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_script_debug.xml
+++ b/indra/newview/skins/default/xui/fr/floater_script_debug.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_script_debug_panel.xml b/indra/newview/skins/default/xui/fr/floater_script_debug_panel.xml
index e70a30fa24..e70a30fa24 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_script_debug_panel.xml
+++ b/indra/newview/skins/default/xui/fr/floater_script_debug_panel.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_script_limits.xml b/indra/newview/skins/default/xui/fr/floater_script_limits.xml
index cc3aaa6653..cc3aaa6653 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_script_limits.xml
+++ b/indra/newview/skins/default/xui/fr/floater_script_limits.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_script_preview.xml b/indra/newview/skins/default/xui/fr/floater_script_preview.xml
index 7b6bc73677..7b6bc73677 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_script_preview.xml
+++ b/indra/newview/skins/default/xui/fr/floater_script_preview.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_script_queue.xml b/indra/newview/skins/default/xui/fr/floater_script_queue.xml
index b9a8165457..b9a8165457 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_script_queue.xml
+++ b/indra/newview/skins/default/xui/fr/floater_script_queue.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_script_search.xml b/indra/newview/skins/default/xui/fr/floater_script_search.xml
index 09b903f41c..09b903f41c 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_script_search.xml
+++ b/indra/newview/skins/default/xui/fr/floater_script_search.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_search.xml b/indra/newview/skins/default/xui/fr/floater_search.xml
index 32800182ea..32800182ea 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_search.xml
+++ b/indra/newview/skins/default/xui/fr/floater_search.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_select_key.xml b/indra/newview/skins/default/xui/fr/floater_select_key.xml
index 664bc0a723..664bc0a723 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_select_key.xml
+++ b/indra/newview/skins/default/xui/fr/floater_select_key.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_sell_land.xml b/indra/newview/skins/default/xui/fr/floater_sell_land.xml
index c5fb0ea0d4..c5fb0ea0d4 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_sell_land.xml
+++ b/indra/newview/skins/default/xui/fr/floater_sell_land.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_settings_debug.xml b/indra/newview/skins/default/xui/fr/floater_settings_debug.xml
index 995837e9ee..995837e9ee 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_settings_debug.xml
+++ b/indra/newview/skins/default/xui/fr/floater_settings_debug.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_snapshot.xml b/indra/newview/skins/default/xui/fr/floater_snapshot.xml
index 9244051edc..9244051edc 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_snapshot.xml
+++ b/indra/newview/skins/default/xui/fr/floater_snapshot.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_sound_devices.xml b/indra/newview/skins/default/xui/fr/floater_sound_devices.xml
index 080ade9dd4..080ade9dd4 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_sound_devices.xml
+++ b/indra/newview/skins/default/xui/fr/floater_sound_devices.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_sound_preview.xml b/indra/newview/skins/default/xui/fr/floater_sound_preview.xml
index 6f0fb3421f..6f0fb3421f 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_sound_preview.xml
+++ b/indra/newview/skins/default/xui/fr/floater_sound_preview.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_spellcheck.xml b/indra/newview/skins/default/xui/fr/floater_spellcheck.xml
new file mode 100755
index 0000000000..635db52ffa
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/floater_spellcheck.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="spellcheck_floater" title="Paramètres du vérificateur orthographique">
+ <check_box label="Activer le vérificateur orthographique" name="spellcheck_enable"/>
+ <text name="spellcheck_main">
+ Diction. principal :
+ </text>
+ <text label="Journaux :" name="spellcheck_additional">
+ Dictionnaires supplémentaires :
+ </text>
+ <text name="spellcheck_available">
+ Disponibles
+ </text>
+ <text name="spellcheck_active">
+ Actifs
+ </text>
+ <button label="Supprimer" name="spellcheck_remove_btn"/>
+ <button label="Importer..." name="spellcheck_import_btn"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/fr/floater_spellcheck_import.xml b/indra/newview/skins/default/xui/fr/floater_spellcheck_import.xml
new file mode 100755
index 0000000000..c8c76c672d
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/floater_spellcheck_import.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="spellcheck_import" title="Importation d&apos;un dictionnaire">
+ <button label="Parcourir" label_selected="Parcourir" name="dictionary_path_browse"/>
+ <button label="Importer" name="ok_btn"/>
+ <button label="Annuler" name="cancel_btn"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/fr/floater_stats.xml b/indra/newview/skins/default/xui/fr/floater_stats.xml
index 2ce2e6dcd5..d6bd187956 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_stats.xml
+++ b/indra/newview/skins/default/xui/fr/floater_stats.xml
@@ -14,8 +14,11 @@
<stat_bar label="KTris par s" name="ktrissec"/>
<stat_bar label="Objets totaux" name="objs"/>
<stat_bar label="Nouveaux objets" name="newobjs"/>
+ <stat_bar label="Taux de réussite du cache des objets" name="object_cache_hits"/>
</stat_view>
<stat_view label="Texture" name="texture">
+ <stat_bar label="Taux de réussite du cache" name="texture_cache_hits"/>
+ <stat_bar label="Latence de lecture du cache" name="texture_cache_read_latency"/>
<stat_bar label="Nombre" name="numimagesstat"/>
<stat_bar label="Nombre brut" name="numrawimagesstat"/>
<stat_bar label="Mém GL" name="gltexmemstat"/>
@@ -50,14 +53,20 @@
<stat_bar label="Objets" name="simobjects"/>
<stat_bar label="Objets actifs" name="simactiveobjects"/>
<stat_bar label="Scripts actifs" name="simactivescripts"/>
+ <stat_bar label="Scripts exécutés" name="simpctscriptsrun"/>
<stat_bar label="Événements de scripts" name="simscripteps"/>
+ <stat_view label="Recherche de chemin" name="simpathfinding">
+ <stat_bar label="Durée de l&apos;étape IA" name="simsimaistepmsec"/>
+ <stat_bar label="Étapes de silhouette ignorées" name="simsimskippedsilhouettesteps"/>
+ <stat_bar label="Personnages mis à jour" name="simsimpctsteppedcharacters"/>
+ </stat_view>
<stat_bar label="Paquets en entrée" name="siminpps"/>
<stat_bar label="Paquets en sortie" name="simoutpps"/>
<stat_bar label="Téléchargements en attente" name="simpendingdownloads"/>
<stat_bar label="Chargements en attente" name="simpendinguploads"/>
<stat_bar label="Total Unacked Bytes" name="simtotalunackedbytes"/>
<stat_view label="Temps (ms)" name="simperf">
- <stat_bar label="Durée totale de l'image" name="simframemsec"/>
+ <stat_bar label="Durée totale de l&apos;image" name="simframemsec"/>
<stat_bar label="Durée nette" name="simnetmsec"/>
<stat_bar label="Durée sim (physique)" name="simsimphysicsmsec"/>
<stat_bar label="Durée sim (autre)" name="simsimothermsec"/>
diff --git a/indra/newview/skins/default/xui/fr/floater_sys_well.xml b/indra/newview/skins/default/xui/fr/floater_sys_well.xml
index dbdd32974c..dbdd32974c 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_sys_well.xml
+++ b/indra/newview/skins/default/xui/fr/floater_sys_well.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_telehub.xml b/indra/newview/skins/default/xui/fr/floater_telehub.xml
index c529ca2736..c529ca2736 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_telehub.xml
+++ b/indra/newview/skins/default/xui/fr/floater_telehub.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_test_layout_stacks.xml b/indra/newview/skins/default/xui/fr/floater_test_layout_stacks.xml
index b479d5f6d6..b479d5f6d6 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_test_layout_stacks.xml
+++ b/indra/newview/skins/default/xui/fr/floater_test_layout_stacks.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_test_text_vertical_aligment.xml b/indra/newview/skins/default/xui/fr/floater_test_text_vertical_aligment.xml
index 702170ef52..702170ef52 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_test_text_vertical_aligment.xml
+++ b/indra/newview/skins/default/xui/fr/floater_test_text_vertical_aligment.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/fr/floater_texture_ctrl.xml
index 381bcceb00..eace67026c 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_texture_ctrl.xml
+++ b/indra/newview/skins/default/xui/fr/floater_texture_ctrl.xml
@@ -1,24 +1,36 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="texture picker" title="CHOISIR : TEXTURE">
- <string name="choose_picture">
+ <floater.string name="choose_picture">
Cliquez pour sélectionner une image
- </string>
+ </floater.string>
+ <floater.string name="pick title">
+ Choisir :
+ </floater.string>
<text name="Multiple">
Textures multiples
</text>
+ <radio_group name="mode_selection">
+ <radio_item label="Inventaire" name="inventory" value="0"/>
+ <radio_item label="Local" name="local" value="1"/>
+ </radio_group>
<text name="unknown">
Taille : [DIMENSIONS]
</text>
<button label="Défaut" label_selected="Défaut" name="Default" width="60"/>
- <button label="Aucune" label_selected="Aucune" left="68" name="None" width="60"/>
<button label="Vierge" label_selected="Vierge" name="Blank" width="60"/>
- <check_box label="Afficher les dossiers" name="show_folders_check"/>
- <search_editor label="Filtrer les textures" name="inventory search editor"/>
- <check_box label="Appliquer maintenant" name="apply_immediate_check"/>
+ <button label="Aucune" label_selected="Aucune" left="68" name="None" width="60"/>
<button bottom="-240" label="" label_selected="" name="Pipette"/>
- <button label="Annuler" label_selected="Annuler" name="Cancel"/>
+ <check_box initial_value="true" label="Appliquer maintenant" name="apply_immediate_check"/>
+ <text name="preview_disabled" value="Aperçu désactivé"/>
+ <filter_editor label="Filtrer les textures" name="inventory search editor"/>
+ <check_box initial_value="false" label="Afficher les dossiers" name="show_folders_check"/>
+ <button label="Ajouter" label_selected="Ajouter" name="l_add_btn"/>
+ <button label="Supprimer" label_selected="Supprimer" name="l_rem_btn"/>
+ <button label="Charger" label_selected="Charger" name="l_upl_btn"/>
+ <scroll_list name="l_name_list">
+ <column label="Nom" name="unit_name"/>
+ <column label="ID" name="unit_id_HIDDEN"/>
+ </scroll_list>
<button label="OK" label_selected="OK" name="Select"/>
- <string name="pick title">
- Choisir :
- </string>
+ <button label="Annuler" label_selected="Annuler" name="Cancel"/>
</floater>
diff --git a/indra/newview/skins/default/xui/fr/floater_texture_fetch_debugger.xml b/indra/newview/skins/default/xui/fr/floater_texture_fetch_debugger.xml
new file mode 100755
index 0000000000..caae15ea17
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/floater_texture_fetch_debugger.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="TexFetchDebugger" title="Outil de débogage de la récupération des textures">
+ <text name="total_num_fetched_label">
+ 1, nombre total de textures récupérées : [NUM]
+ </text>
+ <text name="total_num_fetching_requests_label">
+ 2, nombre total de demandes de récupération : [NUM]
+ </text>
+ <text name="total_num_cache_hits_label">
+ 3, nombre total de présences dans le cache : [NUM]
+ </text>
+ <text name="total_num_visible_tex_label">
+ 4, nombre total de textures visibles : [NUM]
+ </text>
+ <text name="total_num_visible_tex_fetch_req_label">
+ 5, nombre total de demandes de récupération de textures visibles : [NUM]
+ </text>
+ <text name="total_fetched_data_label">
+ 6, nombre total de données récupérées : [SIZE1] Ko, données décodées : [SIZE2] Ko, [PIXEL] Mpixels
+ </text>
+ <text name="total_fetched_vis_data_label">
+ 7, nombre total de données visibles : [SIZE1] Ko, données décodées : [SIZE2] Ko
+ </text>
+ <text name="total_fetched_rendered_data_label">
+ 8, nombre total de données rendues : [SIZE1] Ko, données décodées : [SIZE2] Ko, [PIXEL] Mpixels
+ </text>
+ <text name="total_time_cache_read_label">
+ 9, durée totale des lectures du cache : [TIME] secondes
+ </text>
+ <text name="total_time_cache_write_label">
+ 10, durée totale des écritures du cache : [TIME] secondes
+ </text>
+ <text name="total_time_decode_label">
+ 11, durée totale des décodages : [TIME] secondes
+ </text>
+ <text name="total_time_gl_label">
+ 12, durée totale de la création de textures GL : [TIME] secondes
+ </text>
+ <text name="total_time_http_label">
+ 13, durée totale de la récupération HTTP : [TIME] secondes
+ </text>
+ <text name="total_time_fetch_label">
+ 14, durée totale de la récupération intégrale : [TIME] secondes
+ </text>
+ <text name="total_time_refetch_vis_cache_label">
+ 15, nouvelle récupération des données visibles du cache, Durée : [TIME] secondes, Récupéré : [SIZE] Ko, [PIXEL] Mpixels
+ </text>
+ <text name="total_time_refetch_all_cache_label">
+ 16, nouvelle récupération de toutes les textures du cache, Durée : [TIME] secondes, Récupéré : [SIZE] Ko, [PIXEL] Mpixels
+ </text>
+ <text name="total_time_refetch_vis_http_label">
+ 17, nouvelle récupération des données visibles de la requête HTTP, Durée : [TIME] secondes, Récupéré : [SIZE] Ko, [PIXEL] Mpixels
+ </text>
+ <text name="total_time_refetch_all_http_label">
+ 18, nouvelle récupération de toutes les textures de la requête HTTP, Durée : [TIME] secondes, Récupéré : [SIZE] Ko, [PIXEL] Mpixels
+ </text>
+ <spinner label="19, taux de texels/pixels :" name="texel_pixel_ratio"/>
+ <text name="texture_source_label">
+ 20, source des textures :
+ </text>
+ <radio_group name="texture_source">
+ <radio_item label="Cache + HTTP" name="0"/>
+ <radio_item label="HTTP uniquement" name="1"/>
+ </radio_group>
+ <button label="Démarrer" name="start_btn"/>
+ <button label="Réinitialiser" name="clear_btn"/>
+ <button label="Fermer" name="close_btn"/>
+ <button label="Lecture du cache" name="cacheread_btn"/>
+ <button label="Écriture du cache" name="cachewrite_btn"/>
+ <button label="HTTP" name="http_btn"/>
+ <button label="Décoder" name="decode_btn"/>
+ <button label="Texture GL" name="gl_btn"/>
+ <button label="Récupérer à nouveau les données visibles du cache" name="refetchviscache_btn"/>
+ <button label="Récupérer cache" name="refetchallcache_btn"/>
+ <button label="Récupérer à nouveau les données visibles de la requête HTTP" name="refetchvishttp_btn"/>
+ <button label="Récupérer HTTP" name="refetchallhttp_btn"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/fr/floater_tools.xml b/indra/newview/skins/default/xui/fr/floater_tools.xml
index e21c6f4c08..421e14d51b 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_tools.xml
+++ b/indra/newview/skins/default/xui/fr/floater_tools.xml
@@ -99,7 +99,7 @@
<button label="" label_selected="" name="ToolRing" tool_tip="Anneau"/>
<button label="" label_selected="" name="ToolTree" tool_tip="Arbre"/>
<button label="" label_selected="" name="ToolGrass" tool_tip="Herbe"/>
- <check_box label="Maintenir l&apos;outil sélectionné" name="checkbox sticky"/>
+ <check_box label="Maintenir l&apos;outil sélect." name="checkbox sticky"/>
<check_box label="Copier la sélection" name="checkbox copy selection"/>
<check_box initial_value="true" label="Centrer" name="checkbox copy centers"/>
<check_box label="Pivoter" name="checkbox copy rotates"/>
@@ -148,6 +148,12 @@
<panel.string name="text modify info 4">
Vous ne pouvez pas modifier ces objets
</panel.string>
+ <panel.string name="text modify info 5">
+ Impossible de modifier cet objet au-delà de la frontière d&apos;une région
+ </panel.string>
+ <panel.string name="text modify info 6">
+ Impossible de modifier ces objets au-delà de la frontière d&apos;une région
+ </panel.string>
<panel.string name="text modify warning">
Sélectionnez l&apos;objet en entier
</panel.string>
@@ -197,12 +203,12 @@
<combo_box.item label="Zoomer" name="Zoom"/>
</combo_box>
<check_box label="À vendre :" name="checkbox for sale"/>
+ <spinner label="L$" name="Edit Cost"/>
<combo_box name="sale type">
<combo_box.item label="Copie" name="Copy"/>
<combo_box.item label="Contenus" name="Contents"/>
<combo_box.item label="Original" name="Original"/>
</combo_box>
- <spinner label="Prix : L$" name="Edit Cost"/>
<check_box label="Afficher dans la recherche" name="search_check" tool_tip="Afficher l&apos;objet dans les résultats de recherche"/>
<panel name="perms_build">
<text name="perm_modify">
@@ -238,6 +244,11 @@
F :
</text>
</panel>
+ <panel name="pathfinding_attrs_panel">
+ <text name="pathfinding_attributes_label">
+ Attributs de recherche de chemin :
+ </text>
+ </panel>
</panel>
<panel label="Objet" name="Object">
<check_box label="Verrouillé" name="checkbox locked" tool_tip="Empêche l&apos;objet d&apos;être déplacé ou supprimé. Utile pendant la construction pour éviter les modifications involontaires."/>
@@ -452,16 +463,11 @@
<combo_box.item label="Ventouses" name="suction"/>
<combo_box.item label="Tissage" name="weave"/>
</combo_box>
- <check_box initial_value="false" label="Aligner les faces Plan" name="checkbox planar align" tool_tip="Aligner les textures sur toutes les faces sélectionnées avec la dernière face sélectionnée. Application de la texture Plan requise."/>
- <text name="rpt">
- Répétitions / Face
- </text>
<spinner label="Horizontal (U)" name="TexScaleU"/>
<check_box label="Inverser" name="checkbox flip s"/>
<spinner label="Vertical (V)" name="TexScaleV"/>
<check_box label="Inverser" name="checkbox flip t"/>
<spinner label="RotationËš" name="TexRot"/>
- <spinner label="Répétitions / Mètre" name="rptctrl"/>
<button label="Appliquer" label_selected="Appliquer" name="button apply"/>
<text name="tex offset">
Décalage de la texture
diff --git a/indra/newview/skins/default/xui/fr/floater_top_objects.xml b/indra/newview/skins/default/xui/fr/floater_top_objects.xml
index 42352e7c1e..eb084d9184 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_top_objects.xml
+++ b/indra/newview/skins/default/xui/fr/floater_top_objects.xml
@@ -1,16 +1,13 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="top_objects" title="Objets les plus utilisés">
+<floater name="top_objects" title="Objets les plus consommateurs">
<floater.string name="top_scripts_title">
- Scripts principaux
+ Scripts les plus consommateurs
</floater.string>
<floater.string name="top_scripts_text">
[COUNT] scripts prenant un total de [TIME] ms
</floater.string>
<floater.string name="scripts_score_label">
- Heure
- </floater.string>
- <floater.string name="scripts_mono_time_label">
- Heure Mono
+ Temps
</floater.string>
<floater.string name="top_colliders_title">
Collisions les plus consommatrices
@@ -32,9 +29,10 @@
<scroll_list.columns label="Nom" name="name"/>
<scroll_list.columns label="Propriétaire" name="owner"/>
<scroll_list.columns label="Lieu" name="location"/>
- <scroll_list.columns label="Heure" name="time"/>
- <scroll_list.columns label="Heure Mono" name="mono_time"/>
+ <scroll_list.columns label="Parcelle" name="parcel"/>
+ <scroll_list.columns label="Temps" name="time"/>
<scroll_list.columns label="URL" name="URLs"/>
+ <scroll_list.columns label="Mémoire (Ko)" name="memory"/>
</scroll_list>
<text name="id_text">
ID de l&apos;objet :
@@ -43,11 +41,15 @@
<text name="obj_name_text">
Nom :
</text>
- <button label="Filtre" name="filter_object_btn"/>
+ <button label="Filtrer" name="filter_object_btn"/>
<text name="owner_name_text">
Propriétaire :
</text>
- <button label="Filtre" name="filter_owner_btn"/>
+ <button label="Filtrer" name="filter_owner_btn"/>
+ <text name="parcel_name_text">
+ Parcelle :
+ </text>
+ <button label="Filtrer" name="filter_parcel_btn"/>
<button label="Rafraîchir" name="refresh_btn"/>
<button label="Renvoyer" name="return_selected_btn"/>
<button label="Tout renvoyer" name="return_all_btn"/>
diff --git a/indra/newview/skins/default/xui/fr/floater_tos.xml b/indra/newview/skins/default/xui/fr/floater_tos.xml
index 6d58cf77ca..6d58cf77ca 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_tos.xml
+++ b/indra/newview/skins/default/xui/fr/floater_tos.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_toybox.xml b/indra/newview/skins/default/xui/fr/floater_toybox.xml
index f99d3d30b5..f99d3d30b5 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_toybox.xml
+++ b/indra/newview/skins/default/xui/fr/floater_toybox.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_translation_settings.xml b/indra/newview/skins/default/xui/fr/floater_translation_settings.xml
index c7582f110f..c7582f110f 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_translation_settings.xml
+++ b/indra/newview/skins/default/xui/fr/floater_translation_settings.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_url_entry.xml b/indra/newview/skins/default/xui/fr/floater_url_entry.xml
index 4b2be14569..4b2be14569 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_url_entry.xml
+++ b/indra/newview/skins/default/xui/fr/floater_url_entry.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_voice_chat_volume.xml b/indra/newview/skins/default/xui/fr/floater_voice_chat_volume.xml
new file mode 100644
index 0000000000..f4f452eea7
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/floater_voice_chat_volume.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="floater_voice_volume" title="VOLUME DU CHAT VOCAL">
+ <slider label="Chat vocal" name="chat_voice_volume"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/fr/floater_voice_controls.xml b/indra/newview/skins/default/xui/fr/floater_voice_controls.xml
index fc4de4a5a6..fc4de4a5a6 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_voice_controls.xml
+++ b/indra/newview/skins/default/xui/fr/floater_voice_controls.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_voice_effect.xml b/indra/newview/skins/default/xui/fr/floater_voice_effect.xml
index 671fb5c14d..f9a76d127e 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_voice_effect.xml
+++ b/indra/newview/skins/default/xui/fr/floater_voice_effect.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater label="Endroits" name="voice_effects" title="EFFET DE VOIX">
+<floater label="Endroits" name="voice_effects" title="APERÇU DES EFFETS DE VOIX">
<string name="no_voice_effect">
(Aucun effet de voix)
</string>
diff --git a/indra/newview/skins/default/xui/fr/floater_voice_volume.xml b/indra/newview/skins/default/xui/fr/floater_voice_volume.xml
new file mode 100644
index 0000000000..bf91a5bb79
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/floater_voice_volume.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<!--
+ Not can_close / no title to avoid window chrome
+ Single instance - only have one at a time, recycle it each spawn
+-->
+<floater name="floater_voice_volume" title="VOLUME DE LA VOIX">
+ <slider name="volume_slider" tool_tip="Volume de la voix" value="0.5"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/fr/floater_web_content.xml b/indra/newview/skins/default/xui/fr/floater_web_content.xml
index 65dfafe760..65dfafe760 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_web_content.xml
+++ b/indra/newview/skins/default/xui/fr/floater_web_content.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_whitelist_entry.xml b/indra/newview/skins/default/xui/fr/floater_whitelist_entry.xml
index 99e4954555..99e4954555 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_whitelist_entry.xml
+++ b/indra/newview/skins/default/xui/fr/floater_whitelist_entry.xml
diff --git a/indra/newview/skins/default/xui/fr/floater_window_size.xml b/indra/newview/skins/default/xui/fr/floater_window_size.xml
index cbda4390d8..11c2e439bd 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_window_size.xml
+++ b/indra/newview/skins/default/xui/fr/floater_window_size.xml
@@ -7,10 +7,17 @@
Définir la taille de la fenêtre :
</text>
<combo_box name="window_size_combo" tool_tip="largeur x hauteur">
- <combo_box.item label="1 000 x 700 (défaut)" name="item0"/>
- <combo_box.item label="1 024 x 768" name="item1"/>
- <combo_box.item label="1 280 x 720 (720 p)" name="item2"/>
- <combo_box.item label="1 920 x 1 080 (1 080p)" name="item3"/>
+ <combo_box.item label="1000 x 700 (par défaut)" name="item1"/>
+ <combo_box.item label="1024 x 768 (4:3 XGA)" name="item2"/>
+ <combo_box.item label="1280 x 720 (16:9 HDTV)" name="item3"/>
+ <combo_box.item label="1280 x 800 (5:8 WXGA)" name="item4"/>
+ <combo_box.item label="1280 x 1024 (5:4 SXGA)" name="item5"/>
+ <combo_box.item label="1440 x 900 (8:5 WSXGA)" name="item7"/>
+ <combo_box.item label="1600 x 900 (16:9 HD+)" name="item8"/>
+ <combo_box.item label="1600 x 1200 (4:3 UXGA)" name="item9"/>
+ <combo_box.item label="1680 x 1050 (8:5 WSXGA+)" name="item10"/>
+ <combo_box.item label="1920 x 1080 (16:9 HDTV)" name="item11"/>
+ <combo_box.item label="1920 x 1200 (8:5 WUXGA)" name="item12"/>
</combo_box>
<button label="Choisir" name="set_btn"/>
<button label="Annuler" name="cancel_btn"/>
diff --git a/indra/newview/skins/default/xui/fr/floater_world_map.xml b/indra/newview/skins/default/xui/fr/floater_world_map.xml
index f5dab91924..f5dab91924 100644..100755
--- a/indra/newview/skins/default/xui/fr/floater_world_map.xml
+++ b/indra/newview/skins/default/xui/fr/floater_world_map.xml
diff --git a/indra/newview/skins/default/xui/fr/fonts.xml b/indra/newview/skins/default/xui/fr/fonts.xml
index cccb45b973..cccb45b973 100644..100755
--- a/indra/newview/skins/default/xui/fr/fonts.xml
+++ b/indra/newview/skins/default/xui/fr/fonts.xml
diff --git a/indra/newview/skins/default/xui/fr/inspect_avatar.xml b/indra/newview/skins/default/xui/fr/inspect_avatar.xml
index 553646f8e9..553646f8e9 100644..100755
--- a/indra/newview/skins/default/xui/fr/inspect_avatar.xml
+++ b/indra/newview/skins/default/xui/fr/inspect_avatar.xml
diff --git a/indra/newview/skins/default/xui/fr/inspect_group.xml b/indra/newview/skins/default/xui/fr/inspect_group.xml
index e8c528c1ac..e8c528c1ac 100644..100755
--- a/indra/newview/skins/default/xui/fr/inspect_group.xml
+++ b/indra/newview/skins/default/xui/fr/inspect_group.xml
diff --git a/indra/newview/skins/default/xui/fr/inspect_object.xml b/indra/newview/skins/default/xui/fr/inspect_object.xml
index b66af7a2bf..b66af7a2bf 100644..100755
--- a/indra/newview/skins/default/xui/fr/inspect_object.xml
+++ b/indra/newview/skins/default/xui/fr/inspect_object.xml
diff --git a/indra/newview/skins/default/xui/fr/inspect_remote_object.xml b/indra/newview/skins/default/xui/fr/inspect_remote_object.xml
index 6d7cfadc04..6d7cfadc04 100644..100755
--- a/indra/newview/skins/default/xui/fr/inspect_remote_object.xml
+++ b/indra/newview/skins/default/xui/fr/inspect_remote_object.xml
diff --git a/indra/newview/skins/default/xui/fr/language_settings.xml b/indra/newview/skins/default/xui/fr/language_settings.xml
index fdac9d65a7..fdac9d65a7 100644..100755
--- a/indra/newview/skins/default/xui/fr/language_settings.xml
+++ b/indra/newview/skins/default/xui/fr/language_settings.xml
diff --git a/indra/newview/skins/default/xui/fr/menu_add_wearable_gear.xml b/indra/newview/skins/default/xui/fr/menu_add_wearable_gear.xml
index 7e7993175e..7e7993175e 100644..100755
--- a/indra/newview/skins/default/xui/fr/menu_add_wearable_gear.xml
+++ b/indra/newview/skins/default/xui/fr/menu_add_wearable_gear.xml
diff --git a/indra/newview/skins/default/xui/fr/menu_attachment_other.xml b/indra/newview/skins/default/xui/fr/menu_attachment_other.xml
index f48513eb2b..0450be28e0 100644..100755
--- a/indra/newview/skins/default/xui/fr/menu_attachment_other.xml
+++ b/indra/newview/skins/default/xui/fr/menu_attachment_other.xml
@@ -11,7 +11,9 @@
<menu_item_call label="Figer" name="Freeze..."/>
<menu_item_call label="Expulser" name="Eject..."/>
<menu_item_call label="Déboguer les textures" name="Debug..."/>
+ <menu_item_call label="Dump XML" name="Dump XML"/>
<menu_item_call label="Zoomer en avant" name="Zoom In"/>
<menu_item_call label="Payer" name="Pay..."/>
<menu_item_call label="Profil de l&apos;objet" name="Object Inspect"/>
+ <menu_item_call label="Ignorer le propriétaire des particules" name="Mute Particle"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/fr/menu_attachment_self.xml b/indra/newview/skins/default/xui/fr/menu_attachment_self.xml
index 6af2064e44..f2e7928c24 100644..100755
--- a/indra/newview/skins/default/xui/fr/menu_attachment_self.xml
+++ b/indra/newview/skins/default/xui/fr/menu_attachment_self.xml
@@ -12,5 +12,7 @@
<menu_item_call label="Mes groupes" name="Groups..."/>
<menu_item_call label="Mon profil" name="Profile..."/>
<menu_item_call label="Déboguer les textures" name="Debug..."/>
+ <menu_item_call label="Dump XML" name="Dump XML"/>
<menu_item_call label="Lâcher" name="Drop"/>
+ <menu_item_call label="Ignorer le propriétaire des particules" name="Mute Particle"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/fr/menu_avatar_icon.xml b/indra/newview/skins/default/xui/fr/menu_avatar_icon.xml
index 3bac25c79b..3bac25c79b 100644..100755
--- a/indra/newview/skins/default/xui/fr/menu_avatar_icon.xml
+++ b/indra/newview/skins/default/xui/fr/menu_avatar_icon.xml
diff --git a/indra/newview/skins/default/xui/fr/menu_avatar_other.xml b/indra/newview/skins/default/xui/fr/menu_avatar_other.xml
index 08d1a20361..1f5c1724f8 100644..100755
--- a/indra/newview/skins/default/xui/fr/menu_avatar_other.xml
+++ b/indra/newview/skins/default/xui/fr/menu_avatar_other.xml
@@ -11,6 +11,8 @@
<menu_item_call label="Figer" name="Freeze..."/>
<menu_item_call label="Expulser" name="Eject..."/>
<menu_item_call label="Déboguer les textures" name="Debug..."/>
+ <menu_item_call label="Dump XML" name="Dump XML"/>
<menu_item_call label="Zoomer en avant" name="Zoom In"/>
<menu_item_call label="Payer" name="Pay..."/>
+ <menu_item_call label="Ignorer le propriétaire des particules" name="Mute Particle"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/fr/menu_avatar_self.xml b/indra/newview/skins/default/xui/fr/menu_avatar_self.xml
index 6310a2177a..4815ad0676 100644..100755
--- a/indra/newview/skins/default/xui/fr/menu_avatar_self.xml
+++ b/indra/newview/skins/default/xui/fr/menu_avatar_self.xml
@@ -29,4 +29,6 @@
<menu_item_call label="Mes groupes" name="Groups..."/>
<menu_item_call label="Mon profil" name="Profile..."/>
<menu_item_call label="Déboguer les textures" name="Debug..."/>
+ <menu_item_call label="Dump XML" name="Dump XML"/>
+ <menu_item_call label="Ignorer le propriétaire des particules" name="Mute Particle"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/fr/menu_bottomtray.xml b/indra/newview/skins/default/xui/fr/menu_bottomtray.xml
deleted file mode 100644
index d0d245b286..0000000000
--- a/indra/newview/skins/default/xui/fr/menu_bottomtray.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<menu name="hide_camera_move_controls_menu">
- <menu_item_check label="Bouton Parler" name="EnableVoiceChat"/>
- <menu_item_check label="Bouton Geste" name="ShowGestureButton"/>
- <menu_item_check label="Bouton Bouger" name="ShowMoveButton"/>
- <menu_item_check label="Bouton Affichage" name="ShowCameraButton"/>
- <menu_item_check label="Bouton Photo" name="ShowSnapshotButton"/>
- <menu_item_check label="Bouton Construire" name="ShowBuildButton"/>
- <menu_item_check label="Bouton Rechercher" name="ShowSearchButton"/>
- <menu_item_check label="Bouton Carte" name="ShowWorldMapButton"/>
- <menu_item_check label="Bouton Mini-carte" name="ShowMiniMapButton"/>
- <menu_item_call label="Couper" name="NearbyChatBar_Cut"/>
- <menu_item_call label="Copier" name="NearbyChatBar_Copy"/>
- <menu_item_call label="Coller" name="NearbyChatBar_Paste"/>
- <menu_item_call label="Supprimer" name="NearbyChatBar_Delete"/>
- <menu_item_call label="Tout sélectionner" name="NearbyChatBar_Select_All"/>
-</menu>
diff --git a/indra/newview/skins/default/xui/fr/menu_cof_attachment.xml b/indra/newview/skins/default/xui/fr/menu_cof_attachment.xml
index a4ead48b6b..a4ead48b6b 100644..100755
--- a/indra/newview/skins/default/xui/fr/menu_cof_attachment.xml
+++ b/indra/newview/skins/default/xui/fr/menu_cof_attachment.xml
diff --git a/indra/newview/skins/default/xui/fr/menu_cof_body_part.xml b/indra/newview/skins/default/xui/fr/menu_cof_body_part.xml
index 4b6907fcc6..4b6907fcc6 100644..100755
--- a/indra/newview/skins/default/xui/fr/menu_cof_body_part.xml
+++ b/indra/newview/skins/default/xui/fr/menu_cof_body_part.xml
diff --git a/indra/newview/skins/default/xui/fr/menu_cof_clothing.xml b/indra/newview/skins/default/xui/fr/menu_cof_clothing.xml
index 03cc569704..03cc569704 100644..100755
--- a/indra/newview/skins/default/xui/fr/menu_cof_clothing.xml
+++ b/indra/newview/skins/default/xui/fr/menu_cof_clothing.xml
diff --git a/indra/newview/skins/default/xui/fr/menu_cof_gear.xml b/indra/newview/skins/default/xui/fr/menu_cof_gear.xml
index 8276d57025..fea0486d8a 100644..100755
--- a/indra/newview/skins/default/xui/fr/menu_cof_gear.xml
+++ b/indra/newview/skins/default/xui/fr/menu_cof_gear.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<menu name="Gear COF">
+<toggleable_menu name="Gear COF">
<menu label="Nouveaux habits" name="COF.Gear.New_Clothes"/>
- <menu label="Nouvelles parties du corps" name="COF.Geear.New_Body_Parts"/>
-</menu>
+ <menu label="Nouvelles parties du corps" name="COF.Gear.New_Body_Parts"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/fr/menu_conversation.xml b/indra/newview/skins/default/xui/fr/menu_conversation.xml
new file mode 100644
index 0000000000..09109f4555
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/menu_conversation.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_conversation_participant">
+ <menu_item_call label="Fermer la conversation" name="close_conversation"/>
+ <menu_item_call label="Ouvrir une conversation vocale" name="open_voice_conversation"/>
+ <menu_item_call label="Se déconnecter de la conversation et du canal vocal" name="disconnect_from_voice"/>
+ <menu_item_call label="Fermer la sélection" name="close_selected_conversations"/>
+ <menu_item_call label="Voir le profil" name="view_profile"/>
+ <menu_item_call label="IM" name="im"/>
+ <menu_item_call label="Proposer une téléportation." name="offer_teleport"/>
+ <menu_item_call label="Appel" name="voice_call"/>
+ <menu_item_call label="Historique du chat..." name="chat_history"/>
+ <menu_item_call label="Devenir amis" name="add_friend"/>
+ <menu_item_call label="Supprimer cet ami" name="remove_friend"/>
+ <menu_item_call label="Supprimer ces amis" name="remove_friends"/>
+ <menu_item_call label="Inviter dans le groupe..." name="invite_to_group"/>
+ <menu_item_call label="Zoomer en avant" name="zoom_in"/>
+ <menu_item_call label="Carte" name="map"/>
+ <menu_item_call label="Partager" name="share"/>
+ <menu_item_call label="Payer" name="pay"/>
+ <menu_item_check label="Bloquer le chat vocal" name="block_unblock"/>
+ <menu_item_check label="Ignorer le texte" name="MuteText"/>
+ <menu_item_call label="Profil du groupe" name="group_profile"/>
+ <menu_item_call label="Activer le groupe" name="activate_group"/>
+ <menu_item_call label="Quitter le groupe" name="leave_group"/>
+ <context_menu label="Options du modérateur" name="Moderator Options">
+ <menu_item_check label="Autoriser les chats écrits" name="AllowTextChat"/>
+ <menu_item_call label="Ignorer ce participant" name="ModerateVoiceMuteSelected"/>
+ <menu_item_call label="Ne plus ignorer ce participant" name="ModerateVoiceUnMuteSelected"/>
+ <menu_item_call label="Ignorer les autres" name="ModerateVoiceMute"/>
+ <menu_item_call label="Ne plus ignorer les autres" name="ModerateVoiceUnmute"/>
+ </context_menu>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/fr/menu_conversation_log_gear.xml b/indra/newview/skins/default/xui/fr/menu_conversation_log_gear.xml
new file mode 100644
index 0000000000..4e7e84199d
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/menu_conversation_log_gear.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="Conversation Context Menu">
+ <menu_item_call label="IM..." name="IM"/>
+ <menu_item_call label="Appel..." name="Call"/>
+ <menu_item_call label="Ouvrir l&apos;historique du chat..." name="Chat history"/>
+ <menu_item_call label="Voir le profil" name="View Profile"/>
+ <menu_item_call label="Téléporter" name="teleport"/>
+ <menu_item_call label="Devenir amis" name="add_friend"/>
+ <menu_item_call label="Supprimer cet ami" name="remove_friend"/>
+ <menu_item_call label="Inviter dans le groupe..." name="Invite"/>
+ <menu_item_call label="Carte" name="Map"/>
+ <menu_item_call label="Partager" name="Share"/>
+ <menu_item_call label="Payer" name="Pay"/>
+ <menu_item_check label="Ignorer/Ne plus ignorer" name="Block/Unblock"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/fr/menu_conversation_log_view.xml b/indra/newview/skins/default/xui/fr/menu_conversation_log_view.xml
new file mode 100644
index 0000000000..c515a8e8e5
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/menu_conversation_log_view.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_conversation_view">
+ <menu_item_check label="Trier par nom" name="sort_by_name"/>
+ <menu_item_check label="Trier par date" name="sort_by_date"/>
+ <menu_item_check label="Trier avec les amis en haut" name="sort_by_friends"/>
+ <menu_item_call label="Afficher l&apos;historique du Chat près de moi" name="view_nearby_chat_history"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/fr/menu_edit.xml b/indra/newview/skins/default/xui/fr/menu_edit.xml
index 56669f31e1..56669f31e1 100644..100755
--- a/indra/newview/skins/default/xui/fr/menu_edit.xml
+++ b/indra/newview/skins/default/xui/fr/menu_edit.xml
diff --git a/indra/newview/skins/default/xui/fr/menu_favorites.xml b/indra/newview/skins/default/xui/fr/menu_favorites.xml
index 5f1545fde7..5f1545fde7 100644..100755
--- a/indra/newview/skins/default/xui/fr/menu_favorites.xml
+++ b/indra/newview/skins/default/xui/fr/menu_favorites.xml
diff --git a/indra/newview/skins/default/xui/fr/menu_gesture_gear.xml b/indra/newview/skins/default/xui/fr/menu_gesture_gear.xml
index 062dd0f005..062dd0f005 100644..100755
--- a/indra/newview/skins/default/xui/fr/menu_gesture_gear.xml
+++ b/indra/newview/skins/default/xui/fr/menu_gesture_gear.xml
diff --git a/indra/newview/skins/default/xui/fr/menu_group_plus.xml b/indra/newview/skins/default/xui/fr/menu_group_plus.xml
index ad76f11d79..ad76f11d79 100644..100755
--- a/indra/newview/skins/default/xui/fr/menu_group_plus.xml
+++ b/indra/newview/skins/default/xui/fr/menu_group_plus.xml
diff --git a/indra/newview/skins/default/xui/fr/menu_hide_navbar.xml b/indra/newview/skins/default/xui/fr/menu_hide_navbar.xml
index 09c9f5084a..09c9f5084a 100644..100755
--- a/indra/newview/skins/default/xui/fr/menu_hide_navbar.xml
+++ b/indra/newview/skins/default/xui/fr/menu_hide_navbar.xml
diff --git a/indra/newview/skins/default/xui/fr/menu_im_conversation.xml b/indra/newview/skins/default/xui/fr/menu_im_conversation.xml
new file mode 100644
index 0000000000..1ec5910c8f
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/menu_im_conversation.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="Conversation Gear Menu">
+ <menu_item_call label="Voir le profil" name="View Profile"/>
+ <menu_item_call label="Devenir amis" name="Add Friend"/>
+ <menu_item_call label="Supprimer cet ami" name="remove_friend"/>
+ <menu_item_call label="Proposer une téléportation." name="offer_teleport"/>
+ <menu_item_call label="Inviter dans le groupe..." name="invite_to_group"/>
+ <menu_item_call label="Historique du chat..." name="chat_history"/>
+ <menu_item_call label="Zoomer en avant" name="zoom_in"/>
+ <menu_item_call label="Carte" name="map"/>
+ <menu_item_call label="Partager" name="Share"/>
+ <menu_item_call label="Payer" name="Pay"/>
+ <menu_item_check label="Bloquer le chat vocal" name="Block/Unblock"/>
+ <menu_item_check label="Ignorer le texte" name="MuteText"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/fr/menu_im_session_showmodes.xml b/indra/newview/skins/default/xui/fr/menu_im_session_showmodes.xml
new file mode 100644
index 0000000000..03a091d1cc
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/menu_im_session_showmodes.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_modes">
+ <menu_item_check label="Vue compacte" name="compact_view"/>
+ <menu_item_check label="Vue développée" name="expanded_view"/>
+ <menu_item_check label="Afficher l’heure" name="IMShowTime"/>
+ <menu_item_check label="Afficher les noms dans les conversations privées" name="IMShowNamesForP2PConv"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/fr/menu_im_well_button.xml b/indra/newview/skins/default/xui/fr/menu_im_well_button.xml
deleted file mode 100644
index 8ef1529e6b..0000000000
--- a/indra/newview/skins/default/xui/fr/menu_im_well_button.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<context_menu name="IM Well Button Context Menu">
- <menu_item_call label="Tout fermer" name="Close All"/>
-</context_menu>
diff --git a/indra/newview/skins/default/xui/fr/menu_imchiclet_adhoc.xml b/indra/newview/skins/default/xui/fr/menu_imchiclet_adhoc.xml
index 4d9a103058..4d9a103058 100644..100755
--- a/indra/newview/skins/default/xui/fr/menu_imchiclet_adhoc.xml
+++ b/indra/newview/skins/default/xui/fr/menu_imchiclet_adhoc.xml
diff --git a/indra/newview/skins/default/xui/fr/menu_imchiclet_group.xml b/indra/newview/skins/default/xui/fr/menu_imchiclet_group.xml
index 59f97d8b48..59f97d8b48 100644..100755
--- a/indra/newview/skins/default/xui/fr/menu_imchiclet_group.xml
+++ b/indra/newview/skins/default/xui/fr/menu_imchiclet_group.xml
diff --git a/indra/newview/skins/default/xui/fr/menu_imchiclet_p2p.xml b/indra/newview/skins/default/xui/fr/menu_imchiclet_p2p.xml
index ecc8cee413..ecc8cee413 100644..100755
--- a/indra/newview/skins/default/xui/fr/menu_imchiclet_p2p.xml
+++ b/indra/newview/skins/default/xui/fr/menu_imchiclet_p2p.xml
diff --git a/indra/newview/skins/default/xui/fr/menu_inspect_avatar_gear.xml b/indra/newview/skins/default/xui/fr/menu_inspect_avatar_gear.xml
index 53f22bb44a..53f22bb44a 100644..100755
--- a/indra/newview/skins/default/xui/fr/menu_inspect_avatar_gear.xml
+++ b/indra/newview/skins/default/xui/fr/menu_inspect_avatar_gear.xml
diff --git a/indra/newview/skins/default/xui/fr/menu_inspect_object_gear.xml b/indra/newview/skins/default/xui/fr/menu_inspect_object_gear.xml
index f3b974aba5..f3b974aba5 100644..100755
--- a/indra/newview/skins/default/xui/fr/menu_inspect_object_gear.xml
+++ b/indra/newview/skins/default/xui/fr/menu_inspect_object_gear.xml
diff --git a/indra/newview/skins/default/xui/fr/menu_inspect_self_gear.xml b/indra/newview/skins/default/xui/fr/menu_inspect_self_gear.xml
index ac70df472d..ac70df472d 100644..100755
--- a/indra/newview/skins/default/xui/fr/menu_inspect_self_gear.xml
+++ b/indra/newview/skins/default/xui/fr/menu_inspect_self_gear.xml
diff --git a/indra/newview/skins/default/xui/fr/menu_inv_offer_chiclet.xml b/indra/newview/skins/default/xui/fr/menu_inv_offer_chiclet.xml
index a9b2883cca..a9b2883cca 100644..100755
--- a/indra/newview/skins/default/xui/fr/menu_inv_offer_chiclet.xml
+++ b/indra/newview/skins/default/xui/fr/menu_inv_offer_chiclet.xml
diff --git a/indra/newview/skins/default/xui/fr/menu_inventory.xml b/indra/newview/skins/default/xui/fr/menu_inventory.xml
index 59dcff9075..627d3068c3 100644..100755
--- a/indra/newview/skins/default/xui/fr/menu_inventory.xml
+++ b/indra/newview/skins/default/xui/fr/menu_inventory.xml
@@ -68,6 +68,7 @@
<menu_item_call label="Supprimer le dossier système" name="Delete System Folder"/>
<menu_item_call label="Démarrer le chat conférence" name="Conference Chat Folder"/>
<menu_item_call label="Jouer" name="Sound Play"/>
+ <menu_item_call label="Copier la SLurl" name="url_copy"/>
<menu_item_call label="À propos du repère" name="About Landmark"/>
<menu_item_call label="Jouer dans Second Life" name="Animation Play"/>
<menu_item_call label="Jouer localement" name="Animation Audition"/>
diff --git a/indra/newview/skins/default/xui/fr/menu_inventory_add.xml b/indra/newview/skins/default/xui/fr/menu_inventory_add.xml
index 1076af44d9..1076af44d9 100644..100755
--- a/indra/newview/skins/default/xui/fr/menu_inventory_add.xml
+++ b/indra/newview/skins/default/xui/fr/menu_inventory_add.xml
diff --git a/indra/newview/skins/default/xui/fr/menu_inventory_gear_default.xml b/indra/newview/skins/default/xui/fr/menu_inventory_gear_default.xml
index 364872c875..364872c875 100644..100755
--- a/indra/newview/skins/default/xui/fr/menu_inventory_gear_default.xml
+++ b/indra/newview/skins/default/xui/fr/menu_inventory_gear_default.xml
diff --git a/indra/newview/skins/default/xui/fr/menu_land.xml b/indra/newview/skins/default/xui/fr/menu_land.xml
index b84daee3ae..7beaf00c58 100644..100755
--- a/indra/newview/skins/default/xui/fr/menu_land.xml
+++ b/indra/newview/skins/default/xui/fr/menu_land.xml
@@ -6,4 +6,5 @@
<menu_item_call label="Acheter un pass" name="Land Buy Pass"/>
<menu_item_call label="Construire" name="Create"/>
<menu_item_call label="Modifier le terrain" name="Edit Terrain"/>
+ <menu_item_call label="Ignorer le propriétaire des particules" name="Mute Particle"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/fr/menu_landmark.xml b/indra/newview/skins/default/xui/fr/menu_landmark.xml
index 73eaa4af7e..73eaa4af7e 100644..100755
--- a/indra/newview/skins/default/xui/fr/menu_landmark.xml
+++ b/indra/newview/skins/default/xui/fr/menu_landmark.xml
diff --git a/indra/newview/skins/default/xui/fr/menu_login.xml b/indra/newview/skins/default/xui/fr/menu_login.xml
index dc6b2793ca..7b1e106474 100644..100755
--- a/indra/newview/skins/default/xui/fr/menu_login.xml
+++ b/indra/newview/skins/default/xui/fr/menu_login.xml
@@ -18,7 +18,13 @@
<menu_item_call label="Afficher les conditions d&apos;utilisation" name="TOS"/>
<menu_item_call label="Afficher le message critique" name="Critical"/>
<menu_item_call label="Test de débogage de la fenêtre flottante du contenu Web" name="Web Content Floater Debug Test"/>
- <menu label="Définir le niveau de connexion" name="Set Logging Level"/>
+ <menu label="Définir le niveau de connexion" name="Set Logging Level">
+ <menu_item_check label="Débogage" name="Debug"/>
+ <menu_item_check label="Infos" name="Info"/>
+ <menu_item_check label="Avertissement" name="Warning"/>
+ <menu_item_check label="Erreur" name="Error"/>
+ <menu_item_check label="Aucun" name="None"/>
+ </menu>
<menu_item_check label="Afficher le sélecteur de grille" name="Show Grid Picker"/>
<menu_item_call label="Afficher la console des notifications" name="Show Notifications Console"/>
</menu>
diff --git a/indra/newview/skins/default/xui/fr/menu_media_ctrl.xml b/indra/newview/skins/default/xui/fr/menu_media_ctrl.xml
index 1941ad2cbf..1941ad2cbf 100644..100755
--- a/indra/newview/skins/default/xui/fr/menu_media_ctrl.xml
+++ b/indra/newview/skins/default/xui/fr/menu_media_ctrl.xml
diff --git a/indra/newview/skins/default/xui/fr/menu_mini_map.xml b/indra/newview/skins/default/xui/fr/menu_mini_map.xml
index b9d0a70383..b9d0a70383 100644..100755
--- a/indra/newview/skins/default/xui/fr/menu_mini_map.xml
+++ b/indra/newview/skins/default/xui/fr/menu_mini_map.xml
diff --git a/indra/newview/skins/default/xui/fr/menu_mode_change.xml b/indra/newview/skins/default/xui/fr/menu_mode_change.xml
deleted file mode 100644
index 982a331c5b..0000000000
--- a/indra/newview/skins/default/xui/fr/menu_mode_change.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<toggleable_menu name="Mode Change">
- <menu_item_check label="Basique" name="BasicMode"/>
- <menu_item_check label="Avancé" name="AdvancedMode"/>
-</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/fr/menu_model_import_gear_default.xml b/indra/newview/skins/default/xui/fr/menu_model_import_gear_default.xml
index af6bfcd028..af6bfcd028 100644..100755
--- a/indra/newview/skins/default/xui/fr/menu_model_import_gear_default.xml
+++ b/indra/newview/skins/default/xui/fr/menu_model_import_gear_default.xml
diff --git a/indra/newview/skins/default/xui/fr/menu_mute_particle.xml b/indra/newview/skins/default/xui/fr/menu_mute_particle.xml
new file mode 100644
index 0000000000..5f5e4c8b08
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/menu_mute_particle.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<!-- *NOTE: See also menu_attachment_other.xml -->
+<context_menu name="Mute Particle Pie">
+ <menu_item_call label="Ignorer le propriétaire des particules" name="Mute Particle"/>
+</context_menu>
diff --git a/indra/newview/skins/default/xui/fr/menu_navbar.xml b/indra/newview/skins/default/xui/fr/menu_navbar.xml
index 08d810b653..08d810b653 100644..100755
--- a/indra/newview/skins/default/xui/fr/menu_navbar.xml
+++ b/indra/newview/skins/default/xui/fr/menu_navbar.xml
diff --git a/indra/newview/skins/default/xui/fr/menu_nearby_chat.xml b/indra/newview/skins/default/xui/fr/menu_nearby_chat.xml
index 99e22aeff7..99e22aeff7 100644..100755
--- a/indra/newview/skins/default/xui/fr/menu_nearby_chat.xml
+++ b/indra/newview/skins/default/xui/fr/menu_nearby_chat.xml
diff --git a/indra/newview/skins/default/xui/fr/menu_notification_well_button.xml b/indra/newview/skins/default/xui/fr/menu_notification_well_button.xml
index 323bfdbf16..323bfdbf16 100644..100755
--- a/indra/newview/skins/default/xui/fr/menu_notification_well_button.xml
+++ b/indra/newview/skins/default/xui/fr/menu_notification_well_button.xml
diff --git a/indra/newview/skins/default/xui/fr/menu_object.xml b/indra/newview/skins/default/xui/fr/menu_object.xml
index c6db48a31c..d7b69e495a 100644..100755
--- a/indra/newview/skins/default/xui/fr/menu_object.xml
+++ b/indra/newview/skins/default/xui/fr/menu_object.xml
@@ -10,6 +10,8 @@
<menu_item_call label="Me lever" name="Object Stand Up"/>
<menu_item_call label="Profil de l&apos;objet" name="Object Inspect"/>
<menu_item_call label="Zoomer en avant" name="Zoom In"/>
+ <menu_item_call label="Voir parmi les groupes de liens" name="show_in_linksets"/>
+ <menu_item_call label="Voir parmi les personnages" name="show_in_characters"/>
<context_menu label="Porter" name="Put On">
<menu_item_call label="Porter" name="Wear"/>
<menu_item_call label="Ajouter" name="Add"/>
@@ -26,4 +28,5 @@
<menu_item_call label="Payer" name="Pay..."/>
<menu_item_call label="Acheter" name="Buy..."/>
<menu_item_call label="Supprimer" name="Delete"/>
+ <menu_item_call label="Ignorer le propriétaire des particules" name="Mute Particle"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/fr/menu_object_icon.xml b/indra/newview/skins/default/xui/fr/menu_object_icon.xml
index 69f8e88a0d..7c94930160 100644..100755
--- a/indra/newview/skins/default/xui/fr/menu_object_icon.xml
+++ b/indra/newview/skins/default/xui/fr/menu_object_icon.xml
@@ -2,4 +2,6 @@
<menu name="Object Icon Menu">
<menu_item_call label="Profil de l&apos;objet..." name="Object Profile"/>
<menu_item_call label="Ignorer..." name="Block"/>
+ <menu_item_call label="Voir sur la carte" name="show_on_map"/>
+ <menu_item_call label="Me téléporter à l’emplacement de l&apos;objet" name="teleport_to_object"/>
</menu>
diff --git a/indra/newview/skins/default/xui/fr/menu_outfit_gear.xml b/indra/newview/skins/default/xui/fr/menu_outfit_gear.xml
index b5181f4f82..21b19eded6 100644..100755
--- a/indra/newview/skins/default/xui/fr/menu_outfit_gear.xml
+++ b/indra/newview/skins/default/xui/fr/menu_outfit_gear.xml
@@ -23,6 +23,8 @@
<menu_item_call label="Nouveaux cheveux" name="New Hair"/>
<menu_item_call label="Nouveaux yeux" name="New Eyes"/>
</menu>
+ <menu_item_call label="Développer tous les dossiers" name="expand"/>
+ <menu_item_call label="Réduire tous les dossiers" name="collapse"/>
<menu_item_call label="Renommer la tenue" name="rename"/>
<menu_item_call label="Supprimer la tenue" name="delete_outfit"/>
</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/fr/menu_outfit_tab.xml b/indra/newview/skins/default/xui/fr/menu_outfit_tab.xml
index 2a7f618e07..2a7f618e07 100644..100755
--- a/indra/newview/skins/default/xui/fr/menu_outfit_tab.xml
+++ b/indra/newview/skins/default/xui/fr/menu_outfit_tab.xml
diff --git a/indra/newview/skins/default/xui/fr/menu_participant_list.xml b/indra/newview/skins/default/xui/fr/menu_participant_list.xml
index f91a30f6bb..f91a30f6bb 100644..100755
--- a/indra/newview/skins/default/xui/fr/menu_participant_list.xml
+++ b/indra/newview/skins/default/xui/fr/menu_participant_list.xml
diff --git a/indra/newview/skins/default/xui/fr/menu_participant_view.xml b/indra/newview/skins/default/xui/fr/menu_participant_view.xml
new file mode 100644
index 0000000000..1811082c84
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/menu_participant_view.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="participant_manu_view">
+ <menu_item_check label="Trier les conversations par type" name="sort_sessions_by_type"/>
+ <menu_item_check label="Trier les conversations par nom" name="sort_sessions_by_name"/>
+ <menu_item_check label="Trier les conversations par activité récente" name="sort_sessions_by_recent"/>
+ <menu_item_check label="Trier les participants par nom" name="sort_participants_by_name"/>
+ <menu_item_check label="Trier les participants par activité récente" name="sort_participants_by_recent"/>
+ <menu_item_call label="Préférences pour le chat..." name="chat_preferences"/>
+ <menu_item_call label="Préférences pour la confidentialité" name="privacy_preferences"/>
+ <menu_item_check label="Journal des conversations..." name="Conversation"/>
+ <menu_item_check label="Traduire le Chat près de moi" name="Translate_chat"/>
+ <menu_item_check label="Paramètres de traduction" name="Translation_settings"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/fr/menu_people_blocked_gear.xml b/indra/newview/skins/default/xui/fr/menu_people_blocked_gear.xml
new file mode 100644
index 0000000000..47589572c2
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/menu_people_blocked_gear.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_blocked_gear">
+ <menu_item_call label="Ne plus ignorer" name="unblock"/>
+ <menu_item_call label="Profil..." name="profile"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/fr/menu_people_blocked_plus.xml b/indra/newview/skins/default/xui/fr/menu_people_blocked_plus.xml
new file mode 100644
index 0000000000..79880dd16d
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/menu_people_blocked_plus.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_blocked_plus">
+ <menu_item_call label="Ignorer un résident par son nom…" name="block_resident_by_name"/>
+ <menu_item_call label="Ignorer un objet par son nom" name="block_object_by_name"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/fr/menu_people_blocked_view.xml b/indra/newview/skins/default/xui/fr/menu_people_blocked_view.xml
new file mode 100644
index 0000000000..13f1575090
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/menu_people_blocked_view.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_blocked_view">
+ <menu_item_check label="Trier par nom" name="sort_by_name"/>
+ <menu_item_check label="Trier par type" name="sort_by_type"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/fr/menu_people_friends_view.xml b/indra/newview/skins/default/xui/fr/menu_people_friends_view.xml
new file mode 100644
index 0000000000..cc81172462
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/menu_people_friends_view.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_group_plus">
+ <menu_item_check label="Trier par nom" name="sort_name"/>
+ <menu_item_check label="Trier par statut" name="sort_status"/>
+ <menu_item_check label="Afficher les icônes des résidents" name="view_icons"/>
+ <menu_item_check label="Afficher les droits octroyés" name="view_permissions"/>
+ <menu_item_check label="Afficher le journal des conversations..." name="view_conversation"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/fr/menu_people_friends_view_sort.xml b/indra/newview/skins/default/xui/fr/menu_people_friends_view_sort.xml
index a6170a6c16..a6170a6c16 100644..100755
--- a/indra/newview/skins/default/xui/fr/menu_people_friends_view_sort.xml
+++ b/indra/newview/skins/default/xui/fr/menu_people_friends_view_sort.xml
diff --git a/indra/newview/skins/default/xui/fr/menu_people_groups.xml b/indra/newview/skins/default/xui/fr/menu_people_groups.xml
index eb51b4cf7e..8e32f065fa 100644..100755
--- a/indra/newview/skins/default/xui/fr/menu_people_groups.xml
+++ b/indra/newview/skins/default/xui/fr/menu_people_groups.xml
@@ -2,7 +2,7 @@
<menu name="menu_group_plus">
<menu_item_call label="Afficher les infos" name="View Info"/>
<menu_item_call label="Chat" name="Chat"/>
- <menu_item_call label="Appeler" name="Call"/>
+ <menu_item_call label="Appel" name="Call"/>
<menu_item_call label="Activer" name="Activate"/>
<menu_item_call label="Quitter" name="Leave"/>
</menu>
diff --git a/indra/newview/skins/default/xui/fr/menu_people_groups_view.xml b/indra/newview/skins/default/xui/fr/menu_people_groups_view.xml
new file mode 100644
index 0000000000..79ede5e22d
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/menu_people_groups_view.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_group_plus">
+ <menu_item_check label="Afficher les icônes des groupes" name="Display Group Icons"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/fr/menu_people_groups_view_sort.xml b/indra/newview/skins/default/xui/fr/menu_people_groups_view_sort.xml
index 34f949cf2c..34f949cf2c 100644..100755
--- a/indra/newview/skins/default/xui/fr/menu_people_groups_view_sort.xml
+++ b/indra/newview/skins/default/xui/fr/menu_people_groups_view_sort.xml
diff --git a/indra/newview/skins/default/xui/fr/menu_people_nearby.xml b/indra/newview/skins/default/xui/fr/menu_people_nearby.xml
index 26bd3978a9..6f7d02ef74 100644..100755
--- a/indra/newview/skins/default/xui/fr/menu_people_nearby.xml
+++ b/indra/newview/skins/default/xui/fr/menu_people_nearby.xml
@@ -1,13 +1,16 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Avatar Context Menu">
- <menu_item_call label="Voir le profil" name="View Profile"/>
- <menu_item_call label="Devenir amis" name="Add Friend"/>
- <menu_item_call label="Supprimer cet ami" name="Remove Friend"/>
- <menu_item_call label="IM" name="IM"/>
- <menu_item_call label="Appeler" name="Call"/>
- <menu_item_call label="Carte" name="Map"/>
- <menu_item_call label="Partager" name="Share"/>
- <menu_item_call label="Payer" name="Pay"/>
- <menu_item_check label="Ignorer/Ne plus ignorer" name="Block/Unblock"/>
- <menu_item_call label="Proposer une téléportation" name="teleport"/>
+ <menu_item_call label="Voir le profil" name="view_profile"/>
+ <menu_item_call label="IM" name="im"/>
+ <menu_item_call label="Téléporter" name="offer_teleport"/>
+ <menu_item_call label="Appel" name="voice_call"/>
+ <menu_item_call label="Afficher l&apos;historique du chat..." name="chat_history"/>
+ <menu_item_call label="Devenir amis" name="add_friend"/>
+ <menu_item_call label="Supprimer cet ami" name="remove_friend"/>
+ <menu_item_call label="Inviter dans le groupe..." name="invite_to_group"/>
+ <menu_item_call label="Zoomer en avant" name="zoom_in"/>
+ <menu_item_call label="Carte" name="map"/>
+ <menu_item_call label="Partager" name="share"/>
+ <menu_item_call label="Payer" name="pay"/>
+ <menu_item_check label="Ignorer/Ne plus ignorer" name="block_unblock"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/fr/menu_people_nearby_multiselect.xml b/indra/newview/skins/default/xui/fr/menu_people_nearby_multiselect.xml
index 8400ec0a14..37abf831c2 100644..100755
--- a/indra/newview/skins/default/xui/fr/menu_people_nearby_multiselect.xml
+++ b/indra/newview/skins/default/xui/fr/menu_people_nearby_multiselect.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Multi-Selected People Context Menu">
- <menu_item_call label="Devenir amis" name="Add Friends"/>
- <menu_item_call label="Supprimer des amis" name="Remove Friend"/>
- <menu_item_call label="IM" name="IM"/>
- <menu_item_call label="Appeler" name="Call"/>
- <menu_item_call label="Partager" name="Share"/>
- <menu_item_call label="Payer" name="Pay"/>
- <menu_item_call label="Proposer une téléportation" name="teleport"/>
+ <menu_item_call label="Devenir amis" name="add_friends"/>
+ <menu_item_call label="Supprimer des amis" name="remove_friends"/>
+ <menu_item_call label="IM" name="im"/>
+ <menu_item_call label="Appeler" name="call"/>
+ <menu_item_call label="Partager" name="share"/>
+ <menu_item_call label="Payer" name="pay"/>
+ <menu_item_call label="Téléporter" name="offer_teleport"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/fr/menu_people_nearby_view.xml b/indra/newview/skins/default/xui/fr/menu_people_nearby_view.xml
new file mode 100644
index 0000000000..086002dce5
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/menu_people_nearby_view.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_group_plus">
+ <menu_item_check label="Trier par intervenants récents" name="sort_by_recent_speakers"/>
+ <menu_item_check label="Trier par nom" name="sort_name"/>
+ <menu_item_check label="Trier par distance" name="sort_distance"/>
+ <menu_item_check label="Afficher les icônes des résidents" name="view_icons"/>
+ <menu_item_check label="Afficher la carte" name="view_map"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/fr/menu_people_nearby_view_sort.xml b/indra/newview/skins/default/xui/fr/menu_people_nearby_view_sort.xml
index 8bb466b8d6..8bb466b8d6 100644..100755
--- a/indra/newview/skins/default/xui/fr/menu_people_nearby_view_sort.xml
+++ b/indra/newview/skins/default/xui/fr/menu_people_nearby_view_sort.xml
diff --git a/indra/newview/skins/default/xui/fr/menu_people_recent_view.xml b/indra/newview/skins/default/xui/fr/menu_people_recent_view.xml
new file mode 100644
index 0000000000..a7d698ab7c
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/menu_people_recent_view.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_group_plus">
+ <menu_item_check label="Trier en commençant par le plus récent" name="sort_most"/>
+ <menu_item_check label="Trier par nom" name="sort_name"/>
+ <menu_item_check label="Afficher les icônes des résidents" name="view_icons"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/fr/menu_people_recent_view_sort.xml b/indra/newview/skins/default/xui/fr/menu_people_recent_view_sort.xml
index 93b90ae61c..93b90ae61c 100644..100755
--- a/indra/newview/skins/default/xui/fr/menu_people_recent_view_sort.xml
+++ b/indra/newview/skins/default/xui/fr/menu_people_recent_view_sort.xml
diff --git a/indra/newview/skins/default/xui/fr/menu_picks.xml b/indra/newview/skins/default/xui/fr/menu_picks.xml
index 7d7174d43c..7d7174d43c 100644..100755
--- a/indra/newview/skins/default/xui/fr/menu_picks.xml
+++ b/indra/newview/skins/default/xui/fr/menu_picks.xml
diff --git a/indra/newview/skins/default/xui/fr/menu_picks_plus.xml b/indra/newview/skins/default/xui/fr/menu_picks_plus.xml
index b6cde6d6e2..b6cde6d6e2 100644..100755
--- a/indra/newview/skins/default/xui/fr/menu_picks_plus.xml
+++ b/indra/newview/skins/default/xui/fr/menu_picks_plus.xml
diff --git a/indra/newview/skins/default/xui/fr/menu_place.xml b/indra/newview/skins/default/xui/fr/menu_place.xml
index 6b0f4db752..6b0f4db752 100644..100755
--- a/indra/newview/skins/default/xui/fr/menu_place.xml
+++ b/indra/newview/skins/default/xui/fr/menu_place.xml
diff --git a/indra/newview/skins/default/xui/fr/menu_place_add_button.xml b/indra/newview/skins/default/xui/fr/menu_place_add_button.xml
index 92f9e7719d..92f9e7719d 100644..100755
--- a/indra/newview/skins/default/xui/fr/menu_place_add_button.xml
+++ b/indra/newview/skins/default/xui/fr/menu_place_add_button.xml
diff --git a/indra/newview/skins/default/xui/fr/menu_places_gear_folder.xml b/indra/newview/skins/default/xui/fr/menu_places_gear_folder.xml
index 3fdf3bf3c4..3fdf3bf3c4 100644..100755
--- a/indra/newview/skins/default/xui/fr/menu_places_gear_folder.xml
+++ b/indra/newview/skins/default/xui/fr/menu_places_gear_folder.xml
diff --git a/indra/newview/skins/default/xui/fr/menu_places_gear_landmark.xml b/indra/newview/skins/default/xui/fr/menu_places_gear_landmark.xml
index b48f6ea693..b48f6ea693 100644..100755
--- a/indra/newview/skins/default/xui/fr/menu_places_gear_landmark.xml
+++ b/indra/newview/skins/default/xui/fr/menu_places_gear_landmark.xml
diff --git a/indra/newview/skins/default/xui/fr/menu_profile_overflow.xml b/indra/newview/skins/default/xui/fr/menu_profile_overflow.xml
index ddf898b791..ddf898b791 100644..100755
--- a/indra/newview/skins/default/xui/fr/menu_profile_overflow.xml
+++ b/indra/newview/skins/default/xui/fr/menu_profile_overflow.xml
diff --git a/indra/newview/skins/default/xui/fr/menu_save_outfit.xml b/indra/newview/skins/default/xui/fr/menu_save_outfit.xml
index f78db411b3..f78db411b3 100644..100755
--- a/indra/newview/skins/default/xui/fr/menu_save_outfit.xml
+++ b/indra/newview/skins/default/xui/fr/menu_save_outfit.xml
diff --git a/indra/newview/skins/default/xui/fr/menu_script_chiclet.xml b/indra/newview/skins/default/xui/fr/menu_script_chiclet.xml
index 46efa30bd6..46efa30bd6 100644..100755
--- a/indra/newview/skins/default/xui/fr/menu_script_chiclet.xml
+++ b/indra/newview/skins/default/xui/fr/menu_script_chiclet.xml
diff --git a/indra/newview/skins/default/xui/fr/menu_slurl.xml b/indra/newview/skins/default/xui/fr/menu_slurl.xml
index ddfa5c0849..ddfa5c0849 100644..100755
--- a/indra/newview/skins/default/xui/fr/menu_slurl.xml
+++ b/indra/newview/skins/default/xui/fr/menu_slurl.xml
diff --git a/indra/newview/skins/default/xui/fr/menu_teleport_history_gear.xml b/indra/newview/skins/default/xui/fr/menu_teleport_history_gear.xml
index 3dea662cc2..3dea662cc2 100644..100755
--- a/indra/newview/skins/default/xui/fr/menu_teleport_history_gear.xml
+++ b/indra/newview/skins/default/xui/fr/menu_teleport_history_gear.xml
diff --git a/indra/newview/skins/default/xui/fr/menu_teleport_history_item.xml b/indra/newview/skins/default/xui/fr/menu_teleport_history_item.xml
index fb4582dbce..fb4582dbce 100644..100755
--- a/indra/newview/skins/default/xui/fr/menu_teleport_history_item.xml
+++ b/indra/newview/skins/default/xui/fr/menu_teleport_history_item.xml
diff --git a/indra/newview/skins/default/xui/fr/menu_teleport_history_tab.xml b/indra/newview/skins/default/xui/fr/menu_teleport_history_tab.xml
index 369680985d..369680985d 100644..100755
--- a/indra/newview/skins/default/xui/fr/menu_teleport_history_tab.xml
+++ b/indra/newview/skins/default/xui/fr/menu_teleport_history_tab.xml
diff --git a/indra/newview/skins/default/xui/fr/menu_text_editor.xml b/indra/newview/skins/default/xui/fr/menu_text_editor.xml
index b6f429aec9..c31b0c8556 100644..100755
--- a/indra/newview/skins/default/xui/fr/menu_text_editor.xml
+++ b/indra/newview/skins/default/xui/fr/menu_text_editor.xml
@@ -1,5 +1,12 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Text editor context menu">
+ <menu_item_call label="(inconnu)" name="Suggestion 1"/>
+ <menu_item_call label="(inconnu)" name="Suggestion 2"/>
+ <menu_item_call label="(inconnu)" name="Suggestion 3"/>
+ <menu_item_call label="(inconnu)" name="Suggestion 4"/>
+ <menu_item_call label="(inconnu)" name="Suggestion 5"/>
+ <menu_item_call label="Ajouter au dictionnaire" name="Add to Dictionary"/>
+ <menu_item_call label="Ajouter aux éléments à ignorer" name="Add to Ignore"/>
<menu_item_call label="Couper" name="Cut"/>
<menu_item_call label="Copier" name="Copy"/>
<menu_item_call label="Coller" name="Paste"/>
diff --git a/indra/newview/skins/default/xui/fr/menu_toolbars.xml b/indra/newview/skins/default/xui/fr/menu_toolbars.xml
index f74d206d56..f74d206d56 100644..100755
--- a/indra/newview/skins/default/xui/fr/menu_toolbars.xml
+++ b/indra/newview/skins/default/xui/fr/menu_toolbars.xml
diff --git a/indra/newview/skins/default/xui/fr/menu_topinfobar.xml b/indra/newview/skins/default/xui/fr/menu_topinfobar.xml
index dc68f40fe7..dc68f40fe7 100644..100755
--- a/indra/newview/skins/default/xui/fr/menu_topinfobar.xml
+++ b/indra/newview/skins/default/xui/fr/menu_topinfobar.xml
diff --git a/indra/newview/skins/default/xui/fr/menu_url_agent.xml b/indra/newview/skins/default/xui/fr/menu_url_agent.xml
index 5ed627fbc3..2c7443c6ca 100644..100755
--- a/indra/newview/skins/default/xui/fr/menu_url_agent.xml
+++ b/indra/newview/skins/default/xui/fr/menu_url_agent.xml
@@ -1,6 +1,9 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Url Popup">
- <menu_item_call label="Voir le profil du résident" name="show_agent"/>
+ <menu_item_call label="Voir le profil" name="show_agent"/>
+ <menu_item_call label="Envoyer IM..." name="send_im"/>
+ <menu_item_call label="Devenir amis..." name="add_friend"/>
+ <menu_item_call label="Supprimer cet ami..." name="remove_friend"/>
<menu_item_call label="Copier le nom dans le presse-papiers" name="url_copy_label"/>
<menu_item_call label="Copier la SLurl dans le presse-papiers" name="url_copy"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/fr/menu_url_group.xml b/indra/newview/skins/default/xui/fr/menu_url_group.xml
index de90c3ff7e..de90c3ff7e 100644..100755
--- a/indra/newview/skins/default/xui/fr/menu_url_group.xml
+++ b/indra/newview/skins/default/xui/fr/menu_url_group.xml
diff --git a/indra/newview/skins/default/xui/fr/menu_url_http.xml b/indra/newview/skins/default/xui/fr/menu_url_http.xml
index 5e96352999..5e96352999 100644..100755
--- a/indra/newview/skins/default/xui/fr/menu_url_http.xml
+++ b/indra/newview/skins/default/xui/fr/menu_url_http.xml
diff --git a/indra/newview/skins/default/xui/fr/menu_url_inventory.xml b/indra/newview/skins/default/xui/fr/menu_url_inventory.xml
index 8ab88b4be7..8ab88b4be7 100644..100755
--- a/indra/newview/skins/default/xui/fr/menu_url_inventory.xml
+++ b/indra/newview/skins/default/xui/fr/menu_url_inventory.xml
diff --git a/indra/newview/skins/default/xui/fr/menu_url_map.xml b/indra/newview/skins/default/xui/fr/menu_url_map.xml
index 67e6986f5d..67e6986f5d 100644..100755
--- a/indra/newview/skins/default/xui/fr/menu_url_map.xml
+++ b/indra/newview/skins/default/xui/fr/menu_url_map.xml
diff --git a/indra/newview/skins/default/xui/fr/menu_url_objectim.xml b/indra/newview/skins/default/xui/fr/menu_url_objectim.xml
index f581c3ef9d..5d745ef5f8 100644..100755
--- a/indra/newview/skins/default/xui/fr/menu_url_objectim.xml
+++ b/indra/newview/skins/default/xui/fr/menu_url_objectim.xml
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Url Popup">
- <menu_item_call label="Afficher les informations sur l&apos;objet" name="show_object"/>
+ <menu_item_call label="Profil de l&apos;objet…" name="show_object"/>
+ <menu_item_call label="Ignorer…" name="block_object"/>
<menu_item_call label="Voir sur la carte" name="show_on_map"/>
<menu_item_call label="Me téléporter à l&apos;emplacement de l&apos;objet" name="teleport_to_object"/>
<menu_item_call label="Copier le nom de l&apos;objet dans le presse-papiers" name="url_copy_label"/>
diff --git a/indra/newview/skins/default/xui/fr/menu_url_parcel.xml b/indra/newview/skins/default/xui/fr/menu_url_parcel.xml
index 07b0eeca49..07b0eeca49 100644..100755
--- a/indra/newview/skins/default/xui/fr/menu_url_parcel.xml
+++ b/indra/newview/skins/default/xui/fr/menu_url_parcel.xml
diff --git a/indra/newview/skins/default/xui/fr/menu_url_slapp.xml b/indra/newview/skins/default/xui/fr/menu_url_slapp.xml
index f4b7e212ca..f4b7e212ca 100644..100755
--- a/indra/newview/skins/default/xui/fr/menu_url_slapp.xml
+++ b/indra/newview/skins/default/xui/fr/menu_url_slapp.xml
diff --git a/indra/newview/skins/default/xui/fr/menu_url_slurl.xml b/indra/newview/skins/default/xui/fr/menu_url_slurl.xml
index e44943cf15..e44943cf15 100644..100755
--- a/indra/newview/skins/default/xui/fr/menu_url_slurl.xml
+++ b/indra/newview/skins/default/xui/fr/menu_url_slurl.xml
diff --git a/indra/newview/skins/default/xui/fr/menu_url_teleport.xml b/indra/newview/skins/default/xui/fr/menu_url_teleport.xml
index a5075a2740..a5075a2740 100644..100755
--- a/indra/newview/skins/default/xui/fr/menu_url_teleport.xml
+++ b/indra/newview/skins/default/xui/fr/menu_url_teleport.xml
diff --git a/indra/newview/skins/default/xui/fr/menu_viewer.xml b/indra/newview/skins/default/xui/fr/menu_viewer.xml
index 3c3d4f5f69..5d0026ace0 100644..100755
--- a/indra/newview/skins/default/xui/fr/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/fr/menu_viewer.xml
@@ -8,7 +8,7 @@
<menu_item_call label="Nouvelle fenêtre d&apos;inventaire" name="NewInventoryWindow"/>
<menu_item_call label="Endroits..." name="Places"/>
<menu_item_call label="Favoris..." name="Picks"/>
- <menu_item_call label="Paramètres de la caméra..." name="Camera Controls"/>
+ <menu_item_call label="Contrôles de la caméra..." name="Camera Controls"/>
<menu label="Déplacement" name="Movement">
<menu_item_call label="M&apos;asseoir" name="Sit Down Here"/>
<menu_item_check label="Voler" name="Fly"/>
@@ -17,8 +17,8 @@
<menu_item_call label="Marcher / Courir / Voler..." name="Walk / run / fly"/>
</menu>
<menu label="Statut" name="Status">
- <menu_item_call label="Absent" name="Set Away"/>
- <menu_item_call label="Occupé" name="Set Busy"/>
+ <menu_item_check label="Absent" name="Away"/>
+ <menu_item_check label="Ne pas déranger" name="Do Not Disturb"/>
</menu>
<menu_item_call label="Acheter des L$..." name="Buy and Sell L$"/>
<menu_item_call label="Boîte d&apos;envoi vendeur..." name="MerchantOutbox"/>
@@ -28,17 +28,25 @@
<menu_item_call label="Préférences..." name="Preferences"/>
<menu_item_call label="Boutons des barres d&apos;outils..." name="Toolbars"/>
<menu_item_call label="Masquer tous les contrôles" name="Hide UI"/>
+ <menu_item_check label="Afficher les éléments HUD" name="Show HUD Attachments"/>
<menu_item_call label="Quitter [APP_NAME]" name="Quit"/>
</menu>
<menu label="Communiquer" name="Communicate">
- <menu_item_check label="Chat..." name="Nearby Chat"/>
+ <menu_item_check label="Conversations..." name="Conversations"/>
+ <menu_item_check label="Chat près de moi..." name="Nearby Chat"/>
<menu_item_check label="Parler" name="Speak"/>
- <menu_item_check label="Paramètres vocaux..." name="Nearby Voice"/>
- <menu_item_check label="Effet de voix..." name="ShowVoice"/>
+ <menu_item_check label="Journal des conversations..." name="Conversation Log..."/>
+ <menu label="Effet de voix" name="VoiceMorphing">
+ <menu_item_check label="Aucun effet de voix" name="NoVoiceMorphing"/>
+ <menu_item_check label="Aperçu..." name="Preview"/>
+ <menu_item_call label="S&apos;abonner..." name="Subscribe"/>
+ </menu>
<menu_item_check label="Gestes..." name="Gestures"/>
- <menu_item_call label="Amis" name="My Friends"/>
- <menu_item_call label="Groupes" name="My Groups"/>
- <menu_item_call label="Personnes près de vous" name="Active Speakers"/>
+ <menu_item_check label="Amis" name="My Friends"/>
+ <menu_item_check label="Groupes" name="My Groups"/>
+ <menu_item_check label="Personnes près de vous" name="Active Speakers"/>
+ <menu_item_call label="Liste des ignorés" name="Block List"/>
+ <menu_item_check label="Ne pas déranger" name="Do Not Disturb"/>
</menu>
<menu label="Monde" name="World">
<menu_item_call label="Créer un repère pour ce lieu" name="Create Landmark Here"/>
@@ -107,13 +115,13 @@
<menu_item_call label="Inclure la partie suivante" name="Include Next Part"/>
<menu_item_call label="Inclure la partie précédente" name="Include Previous Part"/>
</menu>
+ <menu_item_call label="Groupes de liens..." name="pathfinding_linkset_menu_item"/>
<menu_item_call label="Point central sur la sélection" name="Focus on Selection"/>
<menu_item_call label="Zoomer sur la sélection" name="Zoom to Selection"/>
<menu label="Objet" name="Object">
<menu_item_call label="Acheter" name="Menu Object Buy"/>
<menu_item_call label="Prendre" name="Menu Object Take"/>
<menu_item_call label="Prendre une copie" name="Take Copy"/>
- <menu_item_call label="Enregistrer dans mon inventaire" name="Save Object Back to My Inventory"/>
<menu_item_call label="Enregistrer dans le contenu des objets" name="Save Object Back to Object Contents"/>
<menu_item_call label="Renvoi de l&apos;objet" name="Return Object back to Owner"/>
</menu>
@@ -124,6 +132,12 @@
<menu_item_call label="Définir les scripts sur Exécution" name="Set Scripts to Running"/>
<menu_item_call label="Définir les scripts sur Pas d&apos;exécution" name="Set Scripts to Not Running"/>
</menu>
+ <menu label="Recherche de chemin" name="Pathfinding">
+ <menu_item_call label="Groupes de liens..." name="pathfinding_linksets_menu_item"/>
+ <menu_item_call label="Personnages..." name="pathfinding_characters_menu_item"/>
+ <menu_item_call label="Vue / test..." name="pathfinding_console_menu_item"/>
+ <menu_item_call label="Refiger la région" name="pathfinding_rebake_navmesh_item"/>
+ </menu>
<menu label="Options" name="Options">
<menu_item_check label="Afficher les droits avancés" name="DebugPermissions"/>
<menu_item_check label="Sélectionner mes objets uniquement" name="Select Only My Objects"/>
@@ -152,6 +166,13 @@
<menu label="Aide" name="Help">
<menu_item_call label="Aide rapide..." name="How To"/>
<menu_item_call label="Aide de [SECOND_LIFE]" name="Second Life Help"/>
+ <menu_item_call label="Guide de l&apos;utilisateur" name="User’s guide"/>
+ <menu_item_call label="Base de connaissances" name="Knowledge Base"/>
+ <menu_item_call label="Wiki" name="Wiki"/>
+ <menu_item_call label="Forums de la communauté" name="Community Forums"/>
+ <menu_item_call label="Portail d&apos;assistance" name="Support portal"/>
+ <menu_item_call label="Actualités [SECOND_LIFE]" name="Second Life News"/>
+ <menu_item_call label="Blogs [SECOND_LIFE]" name="Second Life Blogs"/>
<menu_item_call label="Signaler une infraction" name="Report Abuse"/>
<menu_item_call label="Signaler un bug" name="Report Bug"/>
<menu_item_call label="À propos de [APP_NAME]" name="About Second Life"/>
@@ -171,10 +192,9 @@
</menu>
<menu label="Surbrillance et visibilité" name="Highlighting and Visibility">
<menu_item_check label="Balise animée" name="Cheesy Beacon"/>
- <menu_item_check label="Cacher les particules" name="Hide Particles"/>
+ <menu_item_check label="Masquer les particules" name="Hide Particles"/>
<menu_item_check label="Masquer la sélection" name="Hide Selected"/>
<menu_item_check label="Mettre la transparence en surbrillance" name="Highlight Transparent"/>
- <menu_item_check label="Afficher les éléments HUD" name="Show HUD Attachments"/>
<menu_item_check label="Afficher le réticule de la vue subjective" name="ShowCrosshairs"/>
</menu>
<menu label="Types de rendu" name="Rendering Types">
@@ -227,11 +247,10 @@
<menu_item_check label="Console de textures" name="Texture Console"/>
<menu_item_check label="Console de débogage" name="Debug Console"/>
<menu_item_call label="Console de notifications" name="Notifications"/>
- <menu_item_check label="Console de tailles de textures" name="Texture Size"/>
- <menu_item_check label="Console des catégories de textures" name="Texture Category"/>
<menu_item_check label="Chronos" name="Fast Timers"/>
<menu_item_check label="Mémoire" name="Memory"/>
<menu_item_check label="Statistiques de la scène" name="Scene Statistics"/>
+ <menu_item_call label="Console de débogage de la récupération des textures" name="Texture Fetch Debug Console"/>
<menu_item_call label="Infos de région vers la console de débogage" name="Region Info to Debug Console"/>
<menu_item_call label="Infos de groupe vers la console de débogage" name="Group Info to Debug Console"/>
<menu_item_call label="Infos de capacités vers la console de débogage" name="Capabilities Info to Debug Console"/>
@@ -266,6 +285,7 @@
<menu_item_check label="Taux de défilement aléatoire" name="Randomize Framerate"/>
<menu_item_check label="Cadre lent périodique" name="Periodic Slow Frame"/>
<menu_item_check label="Test cadre" name="Frame Test"/>
+ <menu_item_call label="Profil du cadre" name="Frame Profile"/>
</menu>
<menu label="Métadonnées de rendu" name="Render Metadata">
<menu_item_check label="Cadres" name="Bounding Boxes"/>
@@ -289,14 +309,21 @@
<menu_item_check label="Complexité du rendu" name="rendercomplexity"/>
<menu_item_check label="Octets d&apos;éléments attachés" name="attachment bytes"/>
<menu_item_check label="Sculpture" name="Sculpt"/>
+ <menu label="Densité des textures" name="Texture Density">
+ <menu_item_check label="Aucune" name="None"/>
+ <menu_item_check label="Actuelle" name="Current"/>
+ <menu_item_check label="Souhaitée" name="Desired"/>
+ <menu_item_check label="Complète" name="Full"/>
+ </menu>
</menu>
<menu label="Rendu" name="Rendering">
<menu_item_check label="Axes" name="Axes"/>
<menu_item_check label="Tangente" name="Tangent Basis"/>
<menu_item_call label="Base des infos de la texture sélectionnée" name="Selected Texture Info Basis"/>
+ <menu_item_call label="Infos sur les matériaux sélectionnés" name="Selected Material Info"/>
<menu_item_check label="Filaire" name="Wireframe"/>
<menu_item_check label="Occlusion objet-objet" name="Object-Object Occlusion"/>
- <menu_item_check label="Éclairage et ombres" name="Lighting and Shadows"/>
+ <menu_item_check label="Modèle d&apos;éclairage avancé" name="Advanced Lighting Model"/>
<menu_item_check label="Ombres du soleil/de la lune/des projecteurs" name="Shadows from Sun/Moon/Projectors"/>
<menu_item_check label="SSAO et lissage des ombres" name="SSAO and Shadow Smoothing"/>
<menu_item_check label="Débogage GL" name="Debug GL"/>
@@ -306,8 +333,6 @@
<menu_item_check label="Textures d&apos;animation" name="Animation Textures"/>
<menu_item_check label="Désactiver les textures" name="Disable Textures"/>
<menu_item_check label="Textures pleine résolution" name="Rull Res Textures"/>
- <menu_item_check label="Audit Textures" name="Audit Textures"/>
- <menu_item_check label="Atlas des textures (expérimental)" name="Texture Atlas"/>
<menu_item_check label="Rendu des lumières jointes" name="Render Attached Lights"/>
<menu_item_check label="Rendu des particules jointes" name="Render Attached Particles"/>
<menu_item_check label="Objets en surbrillance avec le pointeur" name="Hover Glow Objects"/>
@@ -343,7 +368,6 @@
<menu_item_call label="Dump Focus Holder" name="Dump Focus Holder"/>
<menu_item_call label="Imprimer les infos sur l&apos;objet sélectionné" name="Print Selected Object Info"/>
<menu_item_call label="Imprimer les infos sur l&apos;avatar" name="Print Agent Info"/>
- <menu_item_call label="Statistiques de mémoire" name="Memory Stats"/>
<menu_item_check label="Console de débogage de région" name="Region Debug Console"/>
<menu_item_check label="Débogage SelectMgr" name="Debug SelectMgr"/>
<menu_item_check label="Débogage clics" name="Debug Clicks"/>
@@ -373,12 +397,16 @@
<menu_item_call label="Basculer la géométrie des personnages" name="Toggle Character Geometry"/>
<menu_item_call label="Test homme" name="Test Male"/>
<menu_item_call label="Test femme" name="Test Female"/>
- <menu_item_call label="Activer/désactiver PG" name="Toggle PG"/>
<menu_item_check label="Autoriser la sélection de l&apos;avatar" name="Allow Select Avatar"/>
</menu>
+ <menu label="Vitesse d&apos;animation" name="Animation Speed">
+ <menu_item_call label="Toutes les animations 10 % plus rapides" name="All Animations 10 Faster"/>
+ <menu_item_call label="Toutes les animations 10 % plus lentes" name="All Animations 10 Slower"/>
+ <menu_item_call label="Réinitialiser la vitesse de toutes les animations" name="Reset All Animation Speed"/>
+ <menu_item_check label="Animations au ralenti" name="Slow Motion Animations"/>
+ </menu>
<menu_item_call label="Forcer les paramètres par défaut" name="Force Params to Default"/>
<menu_item_check label="Infos sur l&apos;animation" name="Animation Info"/>
- <menu_item_check label="Animations au ralenti" name="Slow Motion Animations"/>
<menu_item_check label="Afficher la direction du regard" name="Show Look At"/>
<menu_item_check label="Afficher la direction du pointeur" name="Show Point At"/>
<menu_item_check label="Débogages des mises à jour" name="Debug Joint Updates"/>
diff --git a/indra/newview/skins/default/xui/fr/menu_wearable_list_item.xml b/indra/newview/skins/default/xui/fr/menu_wearable_list_item.xml
index 187cb4bcd2..187cb4bcd2 100644..100755
--- a/indra/newview/skins/default/xui/fr/menu_wearable_list_item.xml
+++ b/indra/newview/skins/default/xui/fr/menu_wearable_list_item.xml
diff --git a/indra/newview/skins/default/xui/fr/menu_wearing_gear.xml b/indra/newview/skins/default/xui/fr/menu_wearing_gear.xml
index c3d9d908b0..c3d9d908b0 100644..100755
--- a/indra/newview/skins/default/xui/fr/menu_wearing_gear.xml
+++ b/indra/newview/skins/default/xui/fr/menu_wearing_gear.xml
diff --git a/indra/newview/skins/default/xui/fr/menu_wearing_tab.xml b/indra/newview/skins/default/xui/fr/menu_wearing_tab.xml
index 4d88445506..4d88445506 100644..100755
--- a/indra/newview/skins/default/xui/fr/menu_wearing_tab.xml
+++ b/indra/newview/skins/default/xui/fr/menu_wearing_tab.xml
diff --git a/indra/newview/skins/default/xui/fr/mime_types.xml b/indra/newview/skins/default/xui/fr/mime_types.xml
index 322887fb76..322887fb76 100644..100755
--- a/indra/newview/skins/default/xui/fr/mime_types.xml
+++ b/indra/newview/skins/default/xui/fr/mime_types.xml
diff --git a/indra/newview/skins/default/xui/fr/mime_types_linux.xml b/indra/newview/skins/default/xui/fr/mime_types_linux.xml
index 3a7ff979ee..3a7ff979ee 100644..100755
--- a/indra/newview/skins/default/xui/fr/mime_types_linux.xml
+++ b/indra/newview/skins/default/xui/fr/mime_types_linux.xml
diff --git a/indra/newview/skins/default/xui/fr/mime_types_mac.xml b/indra/newview/skins/default/xui/fr/mime_types_mac.xml
index 3a7ff979ee..3a7ff979ee 100644..100755
--- a/indra/newview/skins/default/xui/fr/mime_types_mac.xml
+++ b/indra/newview/skins/default/xui/fr/mime_types_mac.xml
diff --git a/indra/newview/skins/default/xui/fr/notifications.xml b/indra/newview/skins/default/xui/fr/notifications.xml
index 746a4b1d55..c295a6f5a7 100644..100755
--- a/indra/newview/skins/default/xui/fr/notifications.xml
+++ b/indra/newview/skins/default/xui/fr/notifications.xml
@@ -37,6 +37,12 @@
<button name="Help" text="$helptext"/>
</form>
</template>
+ <template name="okhelpignore">
+ <form>
+ <button name="OK_okhelpignore" text="$yestext"/>
+ <button name="Help_okhelpignore" text="$helptext"/>
+ </form>
+ </template>
<template name="yesnocancelbuttons">
<form>
<button name="Yes" text="$yestext"/>
@@ -203,6 +209,14 @@ Ajouter ce pouvoir à « [ROLE_NAME] » ?
Ajouter ce pouvoir à « [ROLE_NAME] » ?
<usetemplate name="okcancelbuttons" notext="Non" yestext="Oui"/>
</notification>
+ <notification name="EjectGroupMemberWarning">
+ Vous allez expulser [AVATAR_NAME] du groupe.
+ <usetemplate ignoretext="Confirmer l&apos;expulsion d&apos;un membre du groupe" name="okcancelignore" notext="Annuler" yestext="Expulser"/>
+ </notification>
+ <notification name="EjectGroupMembersWarning">
+ Vous allez expulser [COUNT] membres du groupe.
+ <usetemplate ignoretext="Confirmer l&apos;expulsion de plusieurs membres du groupe" name="okcancelignore" notext="Annuler" yestext="Expulser"/>
+ </notification>
<notification name="AttachmentDrop">
Vous êtes sur le point d&apos;abandonner l&apos;élément joint.
Voulez-vous vraiment continuer ?
@@ -359,13 +373,19 @@ Vous devez saisir le nom d&apos;utilisateur de votre avatar.
Pour entrer dans [SECOND_LIFE], vous devez disposer d&apos;un compte. Voulez-vous en créer un maintenant ?
<url name="url">
- https://join.secondlife.com/index.php?lang=fr-FR
+ [create_account_url]
</url>
<usetemplate name="okcancelbuttons" notext="Réessayer" yestext="Créer un compte"/>
</notification>
<notification name="InvalidCredentialFormat">
Saisissez soit le nom d&apos;utilisateur soit à la fois le prénom et le nom de votre avatar dans le champ Nom d&apos;utilisateur, puis connectez-vous.
</notification>
+ <notification name="InvalidGrid">
+ [GRID] n&apos;est pas un identifiant de grille valide.
+ </notification>
+ <notification name="InvalidLocationSLURL">
+ Grille non valide spécifiée au niveau du lieu de départ.
+ </notification>
<notification name="DeleteClassified">
Supprimer l&apos;annonce [NAME] ?
Une fois payés, les frais ne sont pas remboursables.
@@ -472,7 +492,7 @@ L&apos;objet est peut-être inaccessible ou a peut-être été supprimé.
</notification>
<notification name="StartRegionEmpty">
Vous n&apos;avez pas défini de région de départ.
-Veuillez saisir le nom de la région dans la case Lieu de départ, ou choisissez Dernier emplacement ou Domicile comme Lieu de départ.
+Saisissez le nom de la région voulue dans la case Lieu de départ ou choisissez Dernier emplacement ou Domicile comme lieu de départ.
<usetemplate name="okbutton" yestext="OK"/>
</notification>
<notification name="CouldNotStartStopScript">
@@ -494,6 +514,33 @@ Consulter [_URL] pour en savoir plus ?
</url>
<usetemplate ignoretext="Mon matériel n&apos;est pas pris en charge" name="okcancelignore" notext="Non" yestext="Oui"/>
</notification>
+ <notification name="IntelOldDriver">
+ Il existe probablement un pilote plus récent pour votre puce graphique. La mise à jour des pilotes graphiques est susceptible d&apos;améliorer considérablement les performances.
+
+ Visiter la page [_URL] pour rechercher d&apos;éventuelles mises à jour de pilotes ?
+ <url name="url">
+ http://www.intel.com/p/fr_FR/support/detect/graphics
+ </url>
+ <usetemplate ignoretext="Mon pilote graphique est obsolète." name="okcancelignore" notext="Non" yestext="Oui"/>
+ </notification>
+ <notification name="AMDOldDriver">
+ Il existe probablement un pilote plus récent pour votre puce graphique. La mise à jour des pilotes graphiques est susceptible d&apos;améliorer considérablement les performances.
+
+ Visiter la page [_URL] pour rechercher d&apos;éventuelles mises à jour de pilotes ?
+ <url name="url">
+ http://support.amd.com/us/Pages/AMDSupportHub.aspx
+ </url>
+ <usetemplate ignoretext="Mon pilote graphique est obsolète." name="okcancelignore" notext="Non" yestext="Oui"/>
+ </notification>
+ <notification name="NVIDIAOldDriver">
+ Il existe probablement un pilote plus récent pour votre puce graphique. La mise à jour des pilotes graphiques est susceptible d&apos;améliorer considérablement les performances.
+
+ Visiter la page [_URL] pour rechercher d&apos;éventuelles mises à jour de pilotes ?
+ <url name="url">
+ http://www.nvidia.com/Download/index.aspx?lang=fr
+ </url>
+ <usetemplate ignoretext="Mon pilote graphique est obsolète." name="okcancelignore" notext="Non" yestext="Oui"/>
+ </notification>
<notification name="UnknownGPU">
Votre système contient une carte graphique que [APP_NAME] ne reconnaît pas.
Cela est souvent le cas avec le nouveau matériel qui n&apos;a pas encore été testé avec [APP_NAME]. Cela ne posera probablement pas de problème, mais vous devrez peut-être ajuster vos paramètres graphiques.
@@ -590,6 +637,9 @@ Vous pouvez lier un maximum de [MAX] objets.
Assurez-vous que vous êtes le propriétaire de tous les objets et qu&apos;aucun d&apos;eux n&apos;est verrouillé.
</notification>
+ <notification name="CannotLinkPermanent">
+ Impossible de lier des objets d&apos;une région à une autre.
+ </notification>
<notification name="CannotLinkDifferentOwners">
Impossible de lier car les objets n&apos;ont pas tous le même propriétaire.
@@ -970,6 +1020,41 @@ Proposer à [NAME] de devenir votre ami(e) ?
<button name="Cancel" text="Annuler"/>
</form>
</notification>
+ <notification label="Ajouter une liste Rechercher/Remplacer" name="AddAutoReplaceList">
+ Nom de la nouvelle liste :
+ <form name="form">
+ <button name="SetName" text="OK"/>
+ </form>
+ </notification>
+ <notification label="Renommer la liste Rechercher/Remplacer" name="RenameAutoReplaceList">
+ Le nom [DUPNAME] est déjà utilisé.
+ Saisissez un nouveau nom unique :
+ <form name="form">
+ <button name="ReplaceList" text="Remplacer la liste actuelle"/>
+ <button name="SetName" text="Utiliser le nouveau nom"/>
+ </form>
+ </notification>
+ <notification name="InvalidAutoReplaceEntry">
+ Le mot-clé doit être constitué d&apos;un seul mot et sa valeur de remplacement doit être renseignée.
+ </notification>
+ <notification name="InvalidAutoReplaceList">
+ Liste de remplacement non valide.
+ </notification>
+ <notification name="SpellingDictImportRequired">
+ Spécifiez un fichier, un nom et une langue.
+ </notification>
+ <notification name="SpellingDictIsSecondary">
+ Le dictionnaire [DIC_NAME] ne semble pas contenir de fichier &quot;aff&quot; ; il s&apos;agit donc d&apos;un dictionnaire « secondaire ».
+Vous pouvez l&apos;utiliser comme dictionnaire supplémentaire mais pas comme dictionnaire principal.
+
+Voir https://wiki.secondlife.com/wiki/Adding_Spelling_Dictionaries
+ </notification>
+ <notification name="SpellingDictImportFailed">
+ Impossible de copier
+ [FROM_NAME]
+ vers
+ [TO_NAME]
+ </notification>
<notification label="Enregistrer la tenue" name="SaveOutfitAs">
Enregistrer ce que je porte comme nouvelle tenue :
<form name="form">
@@ -1029,7 +1114,7 @@ Proposer à [NAME] de devenir votre ami(e) ?
Veuillez saisir un montant plus élevé.
</notification>
<notification name="ConfirmItemDeleteHasLinks">
- Des articles liés pointent vers au moins un article sélectionné. Les liens arrêteront définitivement de fonctionner si vous supprimez cet article. Il est vivement conseillé de supprimer d&apos;abord ces liens.
+ Des liens pointent vers au moins un article sélectionné. Les liens arrêteront définitivement de fonctionner si vous supprimez cet article. Il est vivement conseillé de supprimer d&apos;abord ces liens.
Voulez-vous vraiment supprimer ces articles ?
<usetemplate name="okcancelbuttons" notext="Annuler" yestext="OK"/>
@@ -1049,7 +1134,7 @@ Voulez-vous vraiment supprimer ces articles ?
<notification name="ConfirmObjectDeleteNoOwn">
Au moins un des objets que vous avez sélectionnés ne vous appartient pas.
-Êtes-vous certain de vouloir supprimer ces objets ?
+Voulez-vous vraiment supprimer ces articles ?
<usetemplate name="okcancelbuttons" notext="Annuler" yestext="OK"/>
</notification>
<notification name="ConfirmObjectDeleteLockNoCopy">
@@ -1063,23 +1148,23 @@ Au moins un des objets n&apos;est pas copiable.
Au moins un des objets est verrouillé.
Au moins un des objets ne vous appartient pas.
-Êtes-vous certain de vouloir supprimer ces objets ?
+Voulez-vous vraiment supprimer ces articles ?
<usetemplate name="okcancelbuttons" notext="Annuler" yestext="OK"/>
</notification>
<notification name="ConfirmObjectDeleteNoCopyNoOwn">
- Au moins un des objets n&apos;est pas copiable.
+ Au moins un des objets n&apos;est pas reproductible.
Au moins un des objets ne vous appartient pas.
-Êtes-vous certain de vouloir supprimer ces objets ?
+Voulez-vous vraiment supprimer ces articles ?
<usetemplate name="okcancelbuttons" notext="Annuler" yestext="OK"/>
</notification>
<notification name="ConfirmObjectDeleteLockNoCopyNoOwn">
Au moins un des objets est verrouillé.
-Au moins un des objets n&apos;est pas copiable.
+Au moins un des objets n&apos;est pas reproductible.
Au moins un des objets ne vous appartient pas.
-Êtes-vous certain de vouloir supprimer ces objets ?
- <usetemplate name="okcancelbuttons" notext="annuler" yestext="OK"/>
+Voulez-vous vraiment supprimer ces articles ?
+ <usetemplate name="okcancelbuttons" notext="Annuler" yestext="OK"/>
</notification>
<notification name="ConfirmObjectTakeLock">
Au moins un des objets est verrouillé.
@@ -1143,7 +1228,7 @@ par une carte [THIS_GPU].
Vous avez été téléporté vers une région voisine.
</notification>
<notification name="AvatarMovedLast">
- Votre dernière destination n&apos;est pas disponible actuellement.
+ La destination demandée n&apos;est pas disponible actuellement.
Vous avez été téléporté vers une région voisine.
</notification>
<notification name="AvatarMovedHome">
@@ -1162,8 +1247,7 @@ Vous pouvez utiliser [SECOND_LIFE] normalement, les autres résidents vous voien
L&apos;installation de [APP_NAME] est terminée.
Si vous utilisez [SECOND_LIFE] pour la première fois, vous devez ouvrir un compte avant de pouvoir vous connecter.
-Retourner sur [http://join.secondlife.com secondlife.com] pour ouvrir un nouveau compte ?
- <usetemplate name="okcancelbuttons" notext="Continuer" yestext="Nouveau compte..."/>
+ <usetemplate name="okcancelbuttons" notext="Continuer" yestext="Créer un compte..."/>
</notification>
<notification name="LoginPacketNeverReceived">
Nous avons des difficultés à vous connecter. Il y a peut-être un problème avec votre connexion Internet ou la [SECOND_LIFE_GRID].
@@ -1305,7 +1389,7 @@ Dépasse la limite fixée à [MAX_AGENTS] [LIST_TYPE] de [NUM_EXCESS].
Veuillez choisir un objet à vendre et réessayer.
</notification>
<notification name="FinishedRawDownload">
- Chargement du fichier de terrain raw effectué vers :
+ Téléchargement du fichier de terrain raw effectué vers :
[DOWNLOAD_PATH].
</notification>
<notification name="DownloadWindowsMandatory">
@@ -1401,13 +1485,43 @@ Version [VERSION] [[RELEASE_NOTES_FULL_URL] Informations relatives à cette mise
</notification>
<notification name="RequiredUpdateDownloadedVerboseDialog">
Nous avons téléchargé une mise à jour logicielle requise.
-Version [VERSION]
+Version [VERSION] [Informations au sujet de cette mise à jour [INFO_URL]]
[APP_NAME] doit être redémarré pour que la mise à jour soit installée.
<usetemplate name="okbutton" yestext="OK"/>
</notification>
<notification name="RequiredUpdateDownloadedDialog">
[APP_NAME] doit être redémarré pour que la mise à jour soit installée.
+[Informations au sujet de cette mise à jour [INFO_URL]]
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
+ <notification name="OtherChannelDownloadBackgroundTip">
+ Nous avons téléchargé une mise à jour de votre installation [APP_NAME].
+Version [VERSION]
+Le client expérimental a été remplacé par un nouveau client [NEW_CHANNEL] ;
+consultez [[INFO_URL] pour en savoir plus sur cette mise à jour]
+ <usetemplate name="okcancelbuttons" notext="Ultérieurement..." yestext="Installer maintenant et redémarrer [APP_NAME]"/>
+ </notification>
+ <notification name="OtherChannelDownloadBackgroundDialog">
+ Nous avons téléchargé une mise à jour de votre installation [APP_NAME].
+Version [VERSION]
+Le client expérimental a été remplacé par un nouveau client [NEW_CHANNEL] ;
+consultez [Informations au sujet de cette mise à jour [INFO_URL]]
+ <usetemplate name="okcancelbuttons" notext="Ultérieurement..." yestext="Installer maintenant et redémarrer [APP_NAME]"/>
+ </notification>
+ <notification name="OtherChannelRequiredUpdateDownloadedVerboseDialog">
+ Nous avons téléchargé une mise à jour logicielle requise.
+Version [VERSION]
+Le client expérimental a été remplacé par un nouveau client [NEW_CHANNEL] ;
+consultez [Informations au sujet de cette mise à jour [INFO_URL]]
+
+[APP_NAME] doit être redémarré pour que la mise à jour soit installée.
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
+ <notification name="OtherChannelRequiredUpdateDownloadedDialog">
+ [APP_NAME] doit être redémarré pour que la mise à jour soit installée.
+Le client expérimental a été remplacé par un nouveau client [NEW_CHANNEL] ;
+consultez [Informations au sujet de cette mise à jour [INFO_URL]]
<usetemplate name="okbutton" yestext="OK"/>
</notification>
<notification name="DeedObjectToGroup">
@@ -1458,6 +1572,10 @@ Version [VERSION]
Quitter le groupe ?
<usetemplate name="okcancelbuttons" notext="Annuler" yestext="OK"/>
</notification>
+ <notification name="OwnerCannotLeaveGroup">
+ Impossible de quitter le groupe. Vous ne pouvez pas quitter le groupe car vous en êtes le dernier propriétaire. Vous devez d&apos;abord affecter le rôle de propriétaire à un autre membre.
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
<notification name="ConfirmKick">
Souhaitez-vous vraiment éjecter tous les résidents de la grille ?
<usetemplate name="okcancelbuttons" notext="Annuler" yestext="Éjecter tous les résidents"/>
@@ -1485,10 +1603,13 @@ Quitter le groupe ?
Impossible de proposer votre amitié actuellement. Veuillez réessayer dans un moment.
<usetemplate name="okbutton" yestext="OK"/>
</notification>
- <notification name="BusyModeSet">
- Le mode Occupé est sélectionné.
-Les chats et les messages instantanés ne s&apos;afficheront pas. Les messages instantanés génèreront la réponse en mode occupé que vous avez créée. Toutes les offres de téléportation seront refusées. Toutes les offres d&apos;inventaire iront dans la corbeille.
- <usetemplate ignoretext="Je change mon statut en mode Occupé" name="okignore" yestext="OK"/>
+ <notification name="DoNotDisturbModeSet">
+ Ne pas déranger est activé. Vous ne recevrez pas les notifications de communications entrantes.
+
+- Les autres résidents recevront votre réponse Ne pas déranger (définie dans Préférences &gt; Général).
+- Toutes les offres de téléportation seront refusées.
+- Les appels vocaux seront refusés.
+ <usetemplate ignoretext="J&apos;ai changé mon statut et suis désormais en mode Ne pas déranger." name="okignore" yestext="OK"/>
</notification>
<notification name="JoinedTooManyGroupsMember">
Vous avez atteint le nombre de groupes maximum. Avant de pouvoir rejoindre ce groupe, vous devez en quitter un ou refuser cette offre.
@@ -1684,83 +1805,128 @@ Cette action modifiera des milliers de régions et sera difficile à digérer po
<usetemplate name="okcancelbuttons" notext="Annuler" yestext="OK"/>
</notification>
<notification name="RegionEntryAccessBlocked">
- Votre catégorie d&apos;accès ne vous autorise pas à pénétrer dans cette région. Cela vient peut-être du fait qu&apos;il manquait des informations pour valider votre âge.
-
-Vérifiez que vous avez la toute dernière version du client et consultez les pages d&apos;aide pour savoir comment accéder aux zones ayant ce niveau d&apos;accès.
+ La région que vous essayez de visiter comporte du contenu dont le niveau dépasse celui de vos préférences actuelles. Vous pouvez modifier vos préférences en accédant à Moi &gt; Préférences &gt; Général.
<usetemplate name="okbutton" yestext="OK"/>
</notification>
- <notification name="RegionEntryAccessBlocked_KB">
- Votre catégorie d&apos;accès ne vous permet pas de pénétrer dans cette région.
-
-Souhaitez-vous en savoir plus sur les différentes catégories d&apos;accès ?
+ <notification name="RegionEntryAccessBlocked_AdultsOnlyContent">
+ La région que vous essayez de visiter comporte du contenu [REGIONMATURITY] uniquement accessible aux adultes.
<url name="url">
- http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview/fr
+ http://community.secondlife.com/t5/Base-de-connaissances/Cat%C3%A9gories-niveaux-de-contenu/ta-p/700311
</url>
- <usetemplate ignoretext="Je ne peux pas pénétrer dans cette région car je n&apos;ai pas accès à cette catégorie de contenu" name="okcancelignore" notext="Fermer" yestext="Consulter les pages d&apos;aide"/>
+ <usetemplate ignoretext="Passage à une autre région : la région que vous essayez de visiter comporte du contenu uniquement accessible aux adultes." name="okcancelignore" notext="Fermer" yestext="Accéder à la Base de connaissances"/>
</notification>
<notification name="RegionEntryAccessBlocked_Notify">
- Votre catégorie d&apos;accès ne vous permet pas de pénétrer dans cette région.
+ La région que vous essayez de visiter comporte du contenu [REGIONMATURITY] alors que les préférences que vous avez définies excluent tout contenu [REGIONMATURITY].
+ </notification>
+ <notification name="RegionEntryAccessBlocked_NotifyAdultsOnly">
+ La région que vous essayez de visiter comporte du contenu [REGIONMATURITY] uniquement accessible aux adultes.
</notification>
<notification name="RegionEntryAccessBlocked_Change">
- La catégorie de contenu définie dans vos préférences ne vous permet pas de pénétrer dans cette région.
-
-Pour cela, vous devez modifier votre paramètre de catégorie de contenu. Vous pourrez alors rechercher du contenu [REGIONMATURITY] et y accéder. Pour annuler vos modifications, accédez à Moi &gt; Préférences &gt; Général.
+ La région que vous essayez de visiter comporte du contenu [REGIONMATURITY] alors que les préférences que vous avez définies excluent tout contenu [REGIONMATURITY]. Il est possible de modifier vos préférences ou d&apos;annuler l&apos;action. Une fois vos préférences modifiées, vous pouvez réessayer d&apos;accéder à la région.
<form name="form">
<button name="OK" text="Modifier les préférences"/>
- <button default="true" name="Cancel" text="Fermer"/>
- <ignore name="ignore" text="La catégorie de contenu que j&apos;ai choisie m&apos;empêche de pénétrer dans une région"/>
+ <button default="true" name="Cancel" text="Annuler"/>
+ <ignore name="ignore" text="Passage à une autre région : la région que vous essayez de visiter comporte du contenu dont le niveau est exclu de vos préférences actuelles."/>
</form>
</notification>
+ <notification name="RegionEntryAccessBlocked_PreferencesOutOfSync">
+ Nous rencontrons des difficultés techniques au niveau de votre téléportation car vos préférences ne sont pas synchronisées avec le serveur.
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
+ <notification name="TeleportEntryAccessBlocked">
+ La région que vous essayez de visiter comporte du contenu dont le niveau dépasse celui de vos préférences actuelles. Vous pouvez modifier vos préférences en accédant à Moi &gt; Préférences &gt; Général.
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
+ <notification name="TeleportEntryAccessBlocked_AdultsOnlyContent">
+ La région que vous essayez de visiter comporte du contenu [REGIONMATURITY] uniquement accessible aux adultes.
+ <url name="url">
+ http://community.secondlife.com/t5/Base-de-connaissances/Cat%C3%A9gories-niveaux-de-contenu/ta-p/700311
+ </url>
+ <usetemplate ignoretext="Téléportation : la région que vous essayez de visiter comporte du contenu uniquement accessible aux adultes." name="okcancelignore" notext="Fermer" yestext="Accéder à la Base de connaissances"/>
+ </notification>
+ <notification name="TeleportEntryAccessBlocked_Notify">
+ La région que vous essayez de visiter comporte du contenu [REGIONMATURITY] alors que les préférences que vous avez définies excluent tout contenu [REGIONMATURITY].
+ </notification>
+ <notification name="TeleportEntryAccessBlocked_NotifyAdultsOnly">
+ La région que vous essayez de visiter comporte du contenu [REGIONMATURITY] uniquement accessible aux adultes.
+ </notification>
+ <notification name="TeleportEntryAccessBlocked_ChangeAndReTeleport">
+ La région que vous essayez de visiter comporte du contenu [REGIONMATURITY] alors que les préférences que vous avez définies excluent tout contenu [REGIONMATURITY]. Il est possible de modifier vos préférences afin de poursuivre la téléportation ou d&apos;annuler la téléportation.
+ <form name="form">
+ <button name="OK" text="Modifier et continuer"/>
+ <button name="Cancel" text="Annuler"/>
+ <ignore name="ignore" text="Téléportation (redémarrage possible) : la région que vous essayez de visiter comporte du contenu dont le niveau est exclu de vos préférences."/>
+ </form>
+ </notification>
+ <notification name="TeleportEntryAccessBlocked_Change">
+ La région que vous essayez de visiter comporte du contenu [REGIONMATURITY] alors que les préférences que vous avez définies excluent tout contenu [REGIONMATURITY]. Il est possible de modifier vos préférences ou d&apos;annuler la téléportation. Une fois vos préférences modifiées, vous devrez réessayer de vous téléporter.
+ <form name="form">
+ <button name="OK" text="Modifier les préférences"/>
+ <button name="Cancel" text="Annuler"/>
+ <ignore name="ignore" text="Téléportation (redémarrage impossible) : la région que vous essayez de visiter comporte du contenu dont le niveau est exclu de vos préférences."/>
+ </form>
+ </notification>
+ <notification name="TeleportEntryAccessBlocked_PreferencesOutOfSync">
+ Nous rencontrons des difficultés techniques au niveau de votre téléportation car vos préférences ne sont pas synchronisées avec le serveur.
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
<notification name="PreferredMaturityChanged">
- Votre préférence de catégorie de contenu est désormais [RATING].
+ Aucune autre notification vous informant que vous allez visiter une région au contenu [RATING] ne vous sera envoyée. Vous pouvez modifier vos préférences de contenu à l&apos;avenir en accédant à Moi &gt; Préférences &gt; Général, à partir de la barre de menus.
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
+ <notification name="MaturityChangeError">
+ Impossible de modifier vos préférences afin d&apos;afficher le contenu [PREFERRED_MATURITY] à l&apos;heure actuelle. Le paramètre [ACTUAL_MATURITY] a été rétabli. Vous pouvez réessayer de modifier vos préférences en accédant à Moi &gt; Préférences &gt; Général, à partir de la barre de menus.
+ <usetemplate name="okbutton" yestext="OK"/>
</notification>
<notification name="LandClaimAccessBlocked">
- Votre catégorie d&apos;accès ne vous permet pas de réclamer cette région. Cela vient peut-être du fait qu&apos;il manquait des informations pour valider votre âge.
-
-Vérifiez que vous avez la toute dernière version du client et consultez les pages d&apos;aide pour savoir comment accéder aux zones ayant ce niveau d&apos;accès.
+ Le niveau de contenu du terrain que vous essayez de revendiquer dépasse celui défini dans vos préférences actuelles. Vous pouvez modifier vos préférences en accédant à Moi &gt; Préférences &gt; Général.
<usetemplate name="okbutton" yestext="OK"/>
</notification>
- <notification name="LandClaimAccessBlocked_KB">
- Votre catégorie d&apos;accès ne vous permet pas de réclamer cette région.
-
-Souhaitez-vous en savoir plus sur les différentes catégories d&apos;accès ?
+ <notification name="LandClaimAccessBlocked_AdultsOnlyContent">
+ Seuls les adultes sont autorisés à revendiquer ce terrain.
<url name="url">
- http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview/fr
+ http://community.secondlife.com/t5/Base-de-connaissances/Cat%C3%A9gories-niveaux-de-contenu/ta-p/700311
</url>
- <usetemplate ignoretext="Je ne peux pas réclamer cette région car je n&apos;ai pas accès à cette catégorie de contenu" name="okcancelignore" notext="Fermer" yestext="Consulter les pages d&apos;aide"/>
+ <usetemplate ignoretext="Seuls les adultes sont autorisés à revendiquer ce terrain." name="okcancelignore" notext="Fermer" yestext="Accéder à la Base de connaissances"/>
</notification>
<notification name="LandClaimAccessBlocked_Notify">
- Votre catégorie d&apos;accès ne vous autorise pas à réclamer cette région.
+ Le terrain que vous essayez de revendiquer comporte du contenu [REGIONMATURITY] alors que les préférences que vous avez définies excluent tout contenu [REGIONMATURITY].
+ </notification>
+ <notification name="LandClaimAccessBlocked_NotifyAdultsOnly">
+ Le terrain que vous essayez de revendiquer comporte du contenu [REGIONMATURITY] uniquement accessible aux adultes.
</notification>
<notification name="LandClaimAccessBlocked_Change">
- Votre catégorie d&apos;accès ne vous permet pas de réclamer cette région.
-
-En cliquant sur Modifier les préférences, vous pourrez changer votre catégorie d&apos;accès et pénétrer dans la région. À partir de maintenant, vous pouvez rechercher et accéder au contenu [REGIONMATURITY]. Vous pouvez modifier ce paramètre à partir du menu Moi &gt; Préférences &gt; Général.
- <usetemplate ignoretext="La catégorie de contenu que j&apos;ai choisie m&apos;empêche de réclamer un terrain" name="okcancelignore" notext="Fermer" yestext="Modifier les Préférences"/>
+ Le terrain que vous essayez de revendiquer comporte du contenu [REGIONMATURITY] alors que les préférences que vous avez définies excluent tout contenu [REGIONMATURITY]. Il est possible de modifier vos préférences, puis d&apos;essayer de revendiquer ce terrain à nouveau.
+ <form name="form">
+ <button name="OK" text="Modifier les préférences"/>
+ <button name="Cancel" text="Annuler"/>
+ <ignore name="ignore" text="Le terrain que vous essayez de revendiquer comporte du contenu dont le niveau est exclu de vos préférences."/>
+ </form>
</notification>
<notification name="LandBuyAccessBlocked">
- Votre catégorie d&apos;accès ne vous permet pas d&apos;acheter cette région. Cela vient peut-être du fait qu&apos;il manquait des informations pour valider votre âge.
-
-Vérifiez que vous avez la toute dernière version du client et consultez les pages d&apos;aide pour savoir comment accéder aux zones ayant ce niveau d&apos;accès.
+ Le niveau de contenu du terrain que vous essayez d&apos;acheter dépasse celui défini dans vos préférences actuelles. Vous pouvez modifier vos préférences en accédant à Moi &gt; Préférences &gt; Général.
<usetemplate name="okbutton" yestext="OK"/>
</notification>
- <notification name="LandBuyAccessBlocked_KB">
- Votre catégorie d&apos;accès ne vous permet pas d&apos;acheter cette région.
-
-Souhaitez-vous en savoir plus sur les différentes catégories d&apos;accès ?
+ <notification name="LandBuyAccessBlocked_AdultsOnlyContent">
+ Seuls les adultes sont autorisés à acheter ce terrain.
<url name="url">
- http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview/fr
+ http://community.secondlife.com/t5/Base-de-connaissances/Cat%C3%A9gories-niveaux-de-contenu/ta-p/700311
</url>
- <usetemplate ignoretext="Je ne peux pas acheter ce terrain car je n&apos;ai pas accès à cette catégorie de contenu" name="okcancelignore" notext="Fermer" yestext="Consulter les pages d&apos;aide"/>
+ <usetemplate ignoretext="Seuls les adultes sont autorisés à acheter ce terrain." name="okcancelignore" notext="Fermer" yestext="Accéder à la Base de connaissances"/>
</notification>
<notification name="LandBuyAccessBlocked_Notify">
- Votre catégorie d&apos;accès ne vous permet pas d&apos;acheter cette région.
+ Le terrain que vous essayez d&apos;acheter comporte du contenu [REGIONMATURITY] alors que les préférences que vous avez définies excluent tout contenu [REGIONMATURITY].
+ </notification>
+ <notification name="LandBuyAccessBlocked_NotifyAdultsOnly">
+ Le terrain que vous essayez d&apos;acheter comporte du contenu [REGIONMATURITY] uniquement accessible aux adultes.
</notification>
<notification name="LandBuyAccessBlocked_Change">
- Votre catégorie d&apos;accès ne vous autorise pas à acheter cette région.
-
-En cliquant sur Modifier les préférences, vous pourrez changer votre catégorie d&apos;accès et pénétrer dans la région. À partir de maintenant, vous pouvez rechercher et accéder au contenu [REGIONMATURITY]. Vous pouvez modifier ce paramètre à partir du menu Moi &gt; Préférences &gt; Général.
- <usetemplate ignoretext="La catégorie de contenu que j&apos;ai choisie m&apos;empêche d&apos;acheter un terrain" name="okcancelignore" notext="Fermer" yestext="Modifier les Préférences"/>
+ Le terrain que vous essayez d&apos;acheter comporte du contenu [REGIONMATURITY] alors que les préférences que vous avez définies excluent tout contenu [REGIONMATURITY]. Il est possible de modifier vos préférences, puis d&apos;essayer d&apos;acheter ce terrain à nouveau.
+ <form name="form">
+ <button name="OK" text="Modifier les préférences"/>
+ <button name="Cancel" text="Annuler"/>
+ <ignore name="ignore" text="Le terrain que vous essayez d&apos;acheter comporte du contenu dont le niveau est exclu de vos préférences."/>
+ </form>
</notification>
<notification name="TooManyPrimsSelected">
Vous avez sélectionné trop de prims. Veuillez sélectionner au maximum [MAX_PRIM_COUNT] prims et réessayer.
@@ -1815,10 +1981,9 @@ Publier cette petite annonce maintenant pour [AMOUNT] L$ ?
</form>
</notification>
<notification label="Catégorie de la région modifiée" name="RegionMaturityChange">
- Le niveau de maturité de cette région a été mis à jour.
-Ce changement n&apos;apparaîtra pas immédiatement sur la carte.
-
-Pour entrer dans les régions Adultes, le résident doit avoir vérifié son compte, que ce soit par vérification de l&apos;âge ou du mode de paiement.
+ Le niveau de contenu de cette région a changé.
+Il se peut que l&apos;affichage de cette modification sur la carte prenne quelque temps.
+ <usetemplate name="okbutton" yestext="OK"/>
</notification>
<notification label="Versions de voix non compatibles" name="VoiceVersionMismatch">
Cette version de [APP_NAME] n&apos;est pas compatible avec la fonctionnalité de chat vocal dans cette région. Vous devez mettre à jour [APP_NAME] pour que le chat vocal fonctionne correctement.
@@ -1931,6 +2096,10 @@ Déplacer les objets de l&apos;inventaire ?
Accéder à votre [http://secondlife.com/account/ Page d&apos;accueil] pour consulter l&apos;historique de votre compte ?
<usetemplate ignoretext="Lancer mon navigateur pour consulter l&apos;historique de mon compte" name="okcancelignore" notext="Annuler" yestext="Aller sur cette page"/>
</notification>
+ <notification name="ConfirmAddingChatParticipants">
+ Quand vous ajoutez une personne à une conversation existante, une nouvelle conversation est créée. Tous les participants recevront les notifications de nouvelle conversation.
+ <usetemplate ignoretext="Confirmer l&apos;ajout de participants au chat" name="okcancelignore" notext="Annuler" yestext="OK"/>
+ </notification>
<notification name="ConfirmQuit">
Êtes-vous certain de vouloir quitter ?
<usetemplate ignoretext="Confirmer avant de quitter" name="okcancelignore" notext="Ne pas quitter" yestext="Quitter"/>
@@ -2005,14 +2174,14 @@ Voulez-vous le remplacer par l&apos;objet sélectionné ?
<button ignore="Ne jamais remplacer" name="No" text="Annuler"/>
</form>
</notification>
- <notification label="Réponse si occupé(e)" name="BusyModePay">
- Vous êtes en mode occupé et vous ne recevrez donc aucun objet en échange de ce paiement.
+ <notification label="Avertissement de mode Ne pas déranger" name="DoNotDisturbModePay">
+ Vous avez activé Ne pas déranger. Vous ne recevrez aucun article proposé en échange de ce paiement.
-Souhaitez-vous quitter le mode occupé avant de terminer cette transaction ?
+Voulez-vous désactiver Ne pas déranger avant de terminer cette transaction ?
<form name="form">
- <ignore name="ignore" save_option="true" text="Je suis sur le point de payer une personne ou un objet mais suis en mode Occupé"/>
- <button ignore="Toujours quitter le mode occupé" name="Yes" text="OK"/>
- <button ignore="Ne jamais quitter le mode occupé" name="No" text="Annuler"/>
+ <ignore name="ignore" text="Je suis sur le point de payer une personne ou un objet mais suis en mode Ne pas déranger"/>
+ <button ignore="Toujours quitter le mode Ne pas déranger" name="Yes" text="OK"/>
+ <button ignore="Ne jamais quitter le mode Ne pas déranger" name="No" text="Annuler"/>
</form>
</notification>
<notification name="ConfirmDeleteProtectedCategory">
@@ -2108,14 +2277,11 @@ Liez-la à partir d&apos;une page web pour permettre aux autres résidents d&apo
<usetemplate ignoretext="Porter automatiquement tout en modifiant mon apparence" name="okcancelignore" notext="Non" yestext="Oui"/>
</notification>
<notification name="NotAgeVerified">
- Vous devez avoir au moins 18 ans pour accéder au contenu et aux zones Adulte dans Second Life. Visitez la page de vérification de l&apos;âge afin de confirmer que vous avez plus de 18 ans.
-Cette opération lancera votre navigateur Web.
-
-[_URL]
- <url name="url" option="0">
- https://secondlife.com/my/account/verification.php
- </url>
- <usetemplate ignoretext="Je n&apos;ai pas procédé à la vérification de mon âge" name="okcancelignore" notext="Annuler" yestext="Accéder à la page de vérification de l&apos;âge"/>
+ L&apos;accès à l&apos;endroit que vous essayez de visiter est limité aux résidents de plus de 18 ans.
+ <usetemplate ignoretext="Je n&apos;ai pas l&apos;âge requis pour visiter les zones d&apos;accès limité en fonction de l&apos;âge." name="okignore" yestext="OK"/>
+ </notification>
+ <notification name="NotAgeVerified_Notify">
+ L&apos;accès à cet endroit est limité aux plus de 18 ans.
</notification>
<notification name="Cannot enter parcel: no payment info on file">
Pour pouvoir pénétrer dans cette zone, vous devez avoir enregistré vos informations de paiement. Souhaitez-vous aller sur [SECOND_LIFE] et enregistrer vos informations de paiement ?
@@ -2150,11 +2316,8 @@ Cette opération lancera votre navigateur Web.
<notification name="GroupNotice">
Sujet : [SUBJECT], Message : [MESSAGE]
</notification>
- <notification name="FriendOnline">
- &lt;nolink&gt;[NAME]&lt;/nolink&gt; est en ligne
- </notification>
- <notification name="FriendOffline">
- &lt;nolink&gt;[NAME]&lt;/nolink&gt; est hors ligne
+ <notification name="FriendOnlineOffline">
+ &lt;nolink&gt;[NAME]&lt;/nolink&gt; est [STATUS]
</notification>
<notification name="AddSelfFriend">
Même si vous êtes extrêmement sympathique, vous ne pouvez pas devenir ami avec vous-même.
@@ -2275,9 +2438,7 @@ Veuillez sélectionner un seul objet.
choisir Téléportation).
</notification>
<notification name="TeleportToPerson">
- Pour contacter un résident tel que [NAME], cliquez sur le bouton Personnes, sélectionnez le résident dans la fenêtre qui s&apos;ouvre, puis cliquez sur IM en
- bas de la fenêtre.
- (Vous pouvez aussi double-cliquer sur le nom du résident dans la liste ou cliquer-droit dessus et choisir IM.)
+ Pour ouvrir une conversation privée avec une autre personne, cliquez-droit sur son avatar et choisissez IM dans le menu.
</notification>
<notification name="CantSelectLandFromMultipleRegions">
Vous ne pouvez pas sélectionner de terrain en dehors des limites du serveur.
@@ -2377,6 +2538,16 @@ Vous ne pouvez pas voler ici.
<notification name="NoBuild">
La construction est interdite dans cette zone. Vous ne pouvez pas construite ou rezzer d&apos;objets ici.
</notification>
+ <notification name="PathfindingDirty">
+ Des modifications de recherche de chemin sont en attente concernant cette région. Si vous disposez de droits de construction, vous pouvez la figer de nouveau en cliquant sur le bouton Refiger la région.
+ </notification>
+ <notification name="DynamicPathfindingDisabled">
+ La recherche de chemin dynamique n&apos;est pas activée dans cette région. Il se peut que les objets scriptés utilisant des appels LSL de recherche de chemin ne fonctionnent pas comme prévu pour cette région.
+ </notification>
+ <notification name="PathfindingCannotRebakeNavmesh">
+ Une erreur est survenue. Un problème réseau ou serveur s&apos;est peut-être produit ou vous ne disposez pas de droits de construction. Se déconnecter puis se reconnecter permet parfois de résoudre le problème.
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
<notification name="SeeAvatars">
Cette parcelle masque les avatars et le chat écrit des autres parcelles. Vous ne pouvez pas voir les résidents qui se trouvent en dehors, et ceux qui se trouvent en dehors ne peuvent pas vous voir. Le chat écrit habituel sur le canal 0 est également bloqué.
</notification>
@@ -2395,9 +2566,7 @@ Aucun script ne marche ici à part ceux du propriétaire du terrain.
Vous ne pouvez réclamer qu&apos;un terrain public dans la région où vous vous trouvez actuellement.
</notification>
<notification name="RegionTPAccessBlocked">
- Votre catégorie d&apos;accès ne vous autorise pas à pénétrer dans cette région. Vous devez sans doute procéder à la vérification de votre âge ou installer une version plus récente du client.
-
-Pour savoir comment accéder aux zones ayant un tel niveau d&apos;accès, veuillez consulter les pages d&apos;aide.
+ La région que vous essayez de visiter comporte du contenu dont le niveau dépasse celui de vos préférences actuelles. Vous pouvez modifier vos préférences en accédant à Moi &gt; Préférences &gt; Général.
</notification>
<notification name="URBannedFromRegion">
Vous avez été banni de cette région.
@@ -2408,11 +2577,11 @@ Pour savoir comment accéder aux zones ayant un tel niveau d&apos;accès, veuill
<notification name="ImproperPaymentStatus">
Vous n&apos;avez pas le statut de paiement approprié pour pénétrer dans cette région.
</notification>
- <notification name="MustGetAgeRgion">
- Pour pouvoir pénétrer dans cette région, vous devez avoir procédé à la vérification de votre âge.
+ <notification name="MustGetAgeRegion">
+ Pour accéder à cette région, vous devez avoir au moins 18 ans.
</notification>
<notification name="MustGetAgeParcel">
- Pour pouvoir pénétrer sur cette parcelle, vous devez avoir procédé à la vérification de votre âge.
+ Pour accéder à cette parcelle, vous devez avoir au moins 18 ans.
</notification>
<notification name="NoDestRegion">
Région de destination introuvable.
@@ -2514,12 +2683,33 @@ Veuillez réessayer dans quelques minutes.
<notification name="TeleportOffered">
[NAME_SLURL] propose de vous téléporter à son emplacement :
-[MESSAGE] - [MATURITY_STR] &lt;icon&gt;[MATURITY_ICON]&lt;/icon&gt;
+« [MESSAGE] »
+&lt;icon&gt;[MATURITY_ICON]&lt;/icon&gt; - [MATURITY_STR]
<form name="form">
<button name="Teleport" text="Téléporter"/>
<button name="Cancel" text="Annuler"/>
</form>
</notification>
+ <notification name="TeleportOffered_MaturityExceeded">
+ [NAME_SLURL] propose de vous téléporter à son emplacement :
+
+« [MESSAGE] »
+&lt;icon&gt;[MATURITY_ICON]&lt;/icon&gt; - [MATURITY_STR]
+
+Cette région comporte du contenu [REGION_CONTENT_MATURITY] alors que vos préférences actuelles excluent tout contenu [REGION_CONTENT_MATURITY]. Il est possible de modifier vos préférences afin de poursuivre la téléportation ou d&apos;annuler la téléportation.
+ <form name="form">
+ <button name="Teleport" text="Modifier et continuer"/>
+ <button name="Cancel" text="Annuler"/>
+ </form>
+ </notification>
+ <notification name="TeleportOffered_MaturityBlocked">
+ [NAME_SLURL] propose de vous téléporter à son emplacement :
+
+« [MESSAGE] »
+&lt;icon&gt;[MATURITY_ICON]&lt;/icon&gt; - [MATURITY_STR]
+
+Toutefois, cette région comporte du contenu uniquement accessible aux adultes.
+ </notification>
<notification name="TeleportOfferSent">
Offre de téléportation envoyée à [TO_NAME]
</notification>
@@ -2614,16 +2804,21 @@ Acceptez-vous ?
</form>
</notification>
<notification name="ScriptQuestionCaution">
- Un objet nommé &lt;nolink&gt;[OBJECTNAME]&lt;/nolink&gt;, appartenant à [NAME], aimerait :
-
-[QUESTIONS]
-Si vous n&apos;avez pas confiance en cet objet ni en son créateur, refusez cette requête.
-
-Accepter cette requête ?
+ Avertissement : l&apos;objet &lt;nolink&gt;[OBJECTNAME]&lt;/nolink&gt; souhaite un accès total à votre compte en Linden dollars. Si vous autorisez cet accès, il pourra supprimer des fonds de votre compte à tout moment ou le vider entièrement de façon continue sans avis préalable.
+
+N&apos;autorisez pas cet accès si vous ne comprenez pas entièrement pourquoi l&apos;objet souhaite accéder à votre compte.
<form name="form">
- <button name="Grant" text="Accepter"/>
+ <button name="Grant" text="Permettre un accès total"/>
<button name="Deny" text="Refuser"/>
- <button name="Details" text="Détails..."/>
+ </form>
+ </notification>
+ <notification name="UnknownScriptQuestion">
+ Le client ne reconnaît pas le droit de script à l&apos;exécution demandé par &lt;nolink&gt;[OBJECTNAME]&lt;/nolink&gt;, objet appartenant à [NAME], et ne peut donc pas l&apos;accorder.
+
+Pour accorder ce droit, mettez votre client à jour pour passer à la version la plus récente, à partir de [DOWNLOADURL].
+ <form name="form">
+ <button name="Deny" text="OK"/>
+ <button name="Mute" text="Ignorer"/>
</form>
</notification>
<notification name="ScriptDialog">
@@ -2927,6 +3122,10 @@ Texture figée de [RESOLUTION] chargée pour [BODYREGION] au bout de [TIME] seco
([EXISTENCE] secondes d&apos;existence)
Texture figée de [RESOLUTION] mise à jour localement pour [BODYREGION] au bout de [TIME] secondes.
</notification>
+ <notification name="LivePreviewUnavailable">
+ Impossible d&apos;afficher un aperçu de cette texture car il s&apos;agit d&apos;une texture sans copie et/ou transfert.
+ <usetemplate ignoretext="M&apos;avertir que le mode Aperçu en direct n&apos;est pas disponible pour les textures sans copie et/ou transfert" name="okignore" yestext="OK"/>
+ </notification>
<notification name="ConfirmLeaveCall">
Voulez-vous vraiment quitter cet appel ?
<usetemplate ignoretext="Confirmer avant de quitter l&apos;appel" name="okcancelignore" notext="Non" yestext="Oui"/>
@@ -3098,6 +3297,62 @@ Cliquez sur un point dans le monde et faites glisser votre souris pour faire tou
Cette action masquera tous les boutons et articles de menu. Pour les récupérer, cliquez de nouveau sur [SHORTCUT].
<usetemplate ignoretext="Confirmer avant de masquer l&apos;interface" name="okcancelignore" notext="Annuler" yestext="OK"/>
</notification>
+ <notification name="PathfindingLinksets_WarnOnPhantom">
+ L&apos;indicateur Fantôme de certains groupes de liens sélectionnés basculera.
+
+Voulez-vous continuer ?
+ <usetemplate ignoretext="L&apos;indicateur Fantôme de certains groupes de liens basculera." name="okcancelignore" notext="Annuler" yestext="OK"/>
+ </notification>
+ <notification name="PathfindingLinksets_MismatchOnRestricted">
+ Certains groupes de liens sélectionnés ne peuvent pas être définis sur [REQUESTED_TYPE] en raison des restrictions d&apos;autorisation les concernant. Ces groupes de liens seront définis sur [RESTRICTED_TYPE].
+
+Voulez-vous continuer ?
+ <usetemplate ignoretext="Certains groupes de liens sélectionnés ne peuvent pas être définis en raison des restrictions d&apos;autorisation les concernant." name="okcancelignore" notext="Annuler" yestext="OK"/>
+ </notification>
+ <notification name="PathfindingLinksets_MismatchOnVolume">
+ Certains groupes de liens sélectionnés ne peuvent pas être définis sur [REQUESTED_TYPE] en raison d&apos;une forme non convexe.
+
+Voulez-vous continuer ?
+ <usetemplate ignoretext="Certains groupes de liens sélectionnés ne peuvent pas être définis en raison d&apos;une forme non convexe." name="okcancelignore" notext="Annuler" yestext="OK"/>
+ </notification>
+ <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnRestricted">
+ L&apos;indicateur Fantôme de certains groupes de liens sélectionnés basculera.
+
+Certains groupes de liens sélectionnés ne peuvent pas être définis sur [REQUESTED_TYPE] en raison des restrictions d&apos;autorisation les concernant. Ces groupes de liens seront définis sur [RESTRICTED_TYPE].
+
+Voulez-vous continuer ?
+ <usetemplate ignoretext="L&apos;indicateur Fantôme de certains groupes de liens sélectionnés basculera et d&apos;autres ne peuvent pas être définis en raison de restrictions d&apos;autorisation sur les groupes de liens." name="okcancelignore" notext="Annuler" yestext="OK"/>
+ </notification>
+ <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnVolume">
+ L&apos;indicateur Fantôme de certains groupes de liens sélectionnés basculera.
+
+Certains groupes de liens sélectionnés ne peuvent pas être définis sur [REQUESTED_TYPE] en raison d&apos;une forme non convexe.
+
+Voulez-vous continuer ?
+ <usetemplate ignoretext="L&apos;indicateur Fantôme de certains groupes de liens sélectionnés basculera et d&apos;autres ne peuvent pas être définis en raison d&apos;une forme non convexe." name="okcancelignore" notext="Annuler" yestext="OK"/>
+ </notification>
+ <notification name="PathfindingLinksets_MismatchOnRestricted_MismatchOnVolume">
+ Certains groupes de liens sélectionnés ne peuvent pas être définis sur [REQUESTED_TYPE] en raison des restrictions d&apos;autorisation les concernant. Ces groupes de liens seront définis sur [RESTRICTED_TYPE].
+
+Certains groupes de liens sélectionnés ne peuvent pas être définis sur [REQUESTED_TYPE] en raison d&apos;une forme non convexe. Les types d&apos;usage de ces groupes de liens ne seront pas modifiés.
+
+Voulez-vous continuer ?
+ <usetemplate ignoretext="Certains groupes de liens sélectionnés ne peuvent pas être définis en raison des restrictions d&apos;autorisation les concernant et d&apos;une forme non convexe." name="okcancelignore" notext="Annuler" yestext="OK"/>
+ </notification>
+ <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnRestricted_MismatchOnVolume">
+ L&apos;indicateur Fantôme de certains groupes de liens sélectionnés basculera.
+
+Certains groupes de liens sélectionnés ne peuvent pas être définis sur [REQUESTED_TYPE] en raison des restrictions d&apos;autorisation les concernant. Ces groupes de liens seront définis sur [RESTRICTED_TYPE].
+
+Certains groupes de liens sélectionnés ne peuvent pas être définis sur [REQUESTED_TYPE] en raison d&apos;une forme non convexe. Les types d&apos;usage de ces groupes de liens ne seront pas modifiés.
+
+Voulez-vous continuer ?
+ <usetemplate ignoretext="L&apos;indicateur Fantôme de certains groupes de liens sélectionnés basculera et d&apos;autres ne peuvent pas être définis en raison de restrictions d&apos;autorisation sur les groupes de liens et d&apos;une forme non convexe." name="okcancelignore" notext="Annuler" yestext="OK"/>
+ </notification>
+ <notification name="PathfindingLinksets_ChangeToFlexiblePath">
+ L&apos;objet sélectionné affecte le maillage de navigation. Si vous le modifiez en Flexibilité, il sera supprimé de ce maillage.
+ <usetemplate ignoretext="L&apos;objet sélectionné affecte le maillage de navigation. Si vous le modifiez en Flexibilité, il sera supprimé de ce maillage." name="okcancelignore" notext="Annuler" yestext="OK"/>
+ </notification>
<global name="UnsupportedGLRequirements">
Vous semblez ne pas avoir le matériel requis pour utiliser [APP_NAME]. [APP_NAME] requiert une carte graphique OpenGL avec une prise en charge du multitexturing. Si vous avez une telle carte, assurez-vous que vous avez aussi les pilotes les plus récents pour la carte, ainsi que les service packs et les patchs pour votre système d&apos;exploitation.
@@ -3122,4 +3377,652 @@ Sinon, consultez la carte et trouvez les &quot; infohubs &quot;.
<global name="You died and have been teleported to your home location">
Vous êtes mort et avez été téléporté à votre domicile.
</global>
+ <notification name="LocalBitmapsUpdateFileNotFound">
+ Impossible de mettre à jour [FNAME] car le fichier est introuvable.
+Désactivation des mises à jour futures de ce fichier...
+ </notification>
+ <notification name="LocalBitmapsUpdateFailedFinal">
+ [NRETRIES] tentatives d&apos;ouverture ou de décodage de [FNAME] ont échoué. Le fichier est désormais considéré comme endommagé.
+Désactivation des mises à jour futures de ce fichier...
+ </notification>
+ <notification name="LocalBitmapsVerifyFail">
+ Tentative d&apos;ajout d&apos;un fichier image [FNAME] non valide ou illisible n&apos;ayant pas pu être ouvert ou décodé. Tentative annulée.
+ </notification>
+ <notification name="PathfindingReturnMultipleItems">
+ Vous allez renvoyer [NUM_ITEMS] articles. Voulez-vous vraiment continuer ?
+ <usetemplate ignoretext="Voulez-vous vraiment renvoyer plusieurs articles ?" name="okcancelignore" notext="Non" yestext="Oui"/>
+ </notification>
+ <notification name="PathfindingDeleteMultipleItems">
+ Vous allez supprimer [NUM_ITEMS] articles. Voulez-vous vraiment continuer ?
+ <usetemplate ignoretext="Voulez-vous vraiment supprimer plusieurs articles ?" name="okcancelignore" notext="Non" yestext="Oui"/>
+ </notification>
+ <notification name="AvatarFrozen">
+ [AV_FREEZER] vous a figé. Vous ne pouvez pas bouger ni interagir avec le monde.
+ </notification>
+ <notification name="AvatarFrozenDuration">
+ [AV_FREEZER] vous a figé pour une durée de [AV_FREEZE_TIME] secondes. Vous ne pouvez pas bouger ni interagir avec le monde.
+ </notification>
+ <notification name="YouFrozeAvatar">
+ Avatar figé.
+ </notification>
+ <notification name="AvatarHasUnFrozenYou">
+ [AV_FREEZER] vous a libéré.
+ </notification>
+ <notification name="AvatarUnFrozen">
+ Avatar libéré.
+ </notification>
+ <notification name="AvatarFreezeFailure">
+ Vous n&apos;avez pas pu figer ce que vous vouliez car vous ne disposez pas des droits d&apos;admin pour cette parcelle.
+ </notification>
+ <notification name="AvatarFreezeThaw">
+ Vous n&apos;êtes plus figé, vous pouvez reprendre votre vie.
+ </notification>
+ <notification name="AvatarCantFreeze">
+ Impossible de figer cet utilisateur.
+ </notification>
+ <notification name="NowOwnObject">
+ Vous êtes désormais le propriétaire de l&apos;objet [OBJECT_NAME].
+ </notification>
+ <notification name="CantRezOnLand">
+ Impossible de rezzer l&apos;objet à [OBJECT_POS] car le propriétaire de ce terrain de l&apos;autorise pas. Utilisez l&apos;outil Terrain pour voir à qui appartiennent les terrains.
+ </notification>
+ <notification name="RezFailTooManyRequests">
+ Impossible de rezzer l&apos;objet car il y a trop de demandes.
+ </notification>
+ <notification name="SitFailCantMove">
+ Vous ne pouvez pas vous asseoir car vous ne pouvez actuellement pas bouger.
+ </notification>
+ <notification name="SitFailNotAllowedOnLand">
+ Vous ne pouvez pas vous asseoir car votre présence sur ce terrain n&apos;est pas autorisée.
+ </notification>
+ <notification name="SitFailNotSameRegion">
+ Essayez de vous rapprocher. Impossible de vous asseoir sur l&apos;objet car
+il ne se trouve pas dans la même région que vous.
+ </notification>
+ <notification name="NoNewObjectRegionFull">
+ Création d&apos;un nouvel objet impossible. La région est pleine.
+ </notification>
+ <notification name="FailedToPlaceObject">
+ Échec du placement de l&apos;objet à l&apos;emplacement spécifié. Veuillez réessayer.
+ </notification>
+ <notification name="NoOwnNoGardening">
+ Vous ne pouvez pas créer d&apos;arbres ni d&apos;herbe sur un terrain qui ne vous appartient pas.
+ </notification>
+ <notification name="NoCopyPermsNoObject">
+ Échec de la copie car vous ne disposez pas des droits requis pour copier l&apos;objet [OBJ_NAME].
+ </notification>
+ <notification name="NoTransPermsNoObject">
+ Échec de la copie car l&apos;objet [OBJ_NAME] ne peut pas vous être transféré.
+ </notification>
+ <notification name="AddToNavMeshNoCopy">
+ Échec de la copie car l&apos;objet [OBJ_NAME] contribue au maillage de navigation.
+ </notification>
+ <notification name="DupeWithNoRootsSelected">
+ Dupliquer sans objet racine sélectionné
+ </notification>
+ <notification name="CantDupeCuzRegionIsFull">
+ Impossible de dupliquer les objets car la région est pleine.
+ </notification>
+ <notification name="CantDupeCuzParcelNotFound">
+ Impossible de dupliquer les objets - la parcelle sur laquelle ils sont est introuvable.
+ </notification>
+ <notification name="CantCreateCuzParcelFull">
+ Création de l&apos;objet impossible car
+la parcelle est pleine.
+ </notification>
+ <notification name="RezAttemptFailed">
+ Échec d&apos;une tentative pour rezzer un objet.
+ </notification>
+ <notification name="ToxicInvRezAttemptFailed">
+ Impossible de créer l&apos;article qui a provoqué des problèmes pour cette région.
+ </notification>
+ <notification name="InvItemIsBlacklisted">
+ Cet article d&apos;inventaire a été placé sur liste noire.
+ </notification>
+ <notification name="NoCanRezObjects">
+ Vous n&apos;êtes actuellement pas autorisé à créer des objets.
+ </notification>
+ <notification name="LandSearchBlocked">
+ Recherche de terrain bloquée.
+Vous avez effectué trop de recherches de terrain trop rapidement.
+Veuillez réessayer dans une minute.
+ </notification>
+ <notification name="NotEnoughResourcesToAttach">
+ Ressources de script insuffisantes pour attacher cet objet.
+ </notification>
+ <notification name="YouDiedAndGotTPHome">
+ Vous êtes mort et avez été téléporté à votre domicile.
+ </notification>
+ <notification name="EjectComingSoon">
+ Votre présence ici n&apos;est plus autorisée et vous disposez de [EJECT_TIME] secondes pour partir.
+ </notification>
+ <notification name="NoEnterServerFull">
+ Vous ne pouvez pas pénétrer dans cette région car
+le serveur est plein.
+ </notification>
+ <notification name="SaveBackToInvDisabled">
+ Le réenregistrement dans l&apos;inventaire a été désactivé.
+ </notification>
+ <notification name="NoExistNoSaveToContents">
+ Impossible d&apos;enregistrer [OBJ_NAME] dans le contenu des objets car l&apos;objet à partir duquel il a été rezzé n&apos;existe plus.
+ </notification>
+ <notification name="NoModNoSaveToContents">
+ Impossible d&apos;enregistrer [OBJ_NAME] dans le contenu des objets car vous ne disposez pas des droits requis pour modifier l&apos;objet [DEST_NAME].
+ </notification>
+ <notification name="NoSaveBackToInvDisabled">
+ Impossible de réenregistrer [OBJ_NAME] dans l&apos;inventaire -- cette opération a été désactivée.
+ </notification>
+ <notification name="NoCopyNoSelCopy">
+ Vous ne pouvez pas copier votre sélection car vous n&apos;avez pas le droit de copier l&apos;objet [OBJ_NAME].
+ </notification>
+ <notification name="NoTransNoSelCopy">
+ Vous ne pouvez pas copier votre sélection car l&apos;objet [OBJ_NAME] n&apos;est pas transférable.
+ </notification>
+ <notification name="NoTransNoCopy">
+ Vous ne pouvez pas copier votre sélection car l&apos;objet [OBJ_NAME] n&apos;est pas transférable.
+ </notification>
+ <notification name="NoPermsNoRemoval">
+ La suppression de l&apos;objet [OBJ_NAME] du simulateur n&apos;est pas autorisée par le système de droits.
+ </notification>
+ <notification name="NoModNoSaveSelection">
+ Vous ne pouvez pas enregistrer votre sélection car vous n&apos;avez pas le droit de modifier l&apos;objet [OBJ_NAME].
+ </notification>
+ <notification name="NoCopyNoSaveSelection">
+ Vous ne pouvez pas enregistrer votre sélection car l&apos;objet [OBJ_NAME] ne peut pas être copié.
+ </notification>
+ <notification name="NoModNoTaking">
+ Vous ne pouvez pas prendre votre sélection car vous n&apos;avez pas le droit de modifier l&apos;objet [OBJ_NAME].
+ </notification>
+ <notification name="RezDestInternalError">
+ Erreur interne : type de destination inconnue.
+ </notification>
+ <notification name="DeleteFailObjNotFound">
+ Échec de la suppression car l&apos;objet est introuvable
+ </notification>
+ <notification name="SorryCantEjectUser">
+ Exclusion de cet utilisateur impossible.
+ </notification>
+ <notification name="RegionSezNotAHome">
+ Cette région ne vous permet pas d&apos;y définir votre domicile.
+ </notification>
+ <notification name="HomeLocationLimits">
+ Vous ne pouvez définir votre domicile que sur votre terrain ou un infohub du continent.
+ </notification>
+ <notification name="HomePositionSet">
+ Emplacement du domicile défini.
+ </notification>
+ <notification name="AvatarEjected">
+ Avatar expulsé.
+ </notification>
+ <notification name="AvatarEjectFailed">
+ Vous n&apos;avez pas pu réaliser l&apos;exclusion car vous ne disposez pas des droits d&apos;admin pour cette parcelle.
+ </notification>
+ <notification name="CantMoveObjectParcelFull">
+ Impossible de déplacer [OBJECT_NAME] jusqu&apos;à
+[OBJ_POSITION] dans la région [REGION_NAME] car la parcelle est pleine.
+ </notification>
+ <notification name="CantMoveObjectParcelPerms">
+ Impossible de déplacer [OBJECT_NAME] jusqu&apos;à
+[OBJ_POSITION] dans la région [REGION_NAME] car vos objets ne sont pas autorisés sur cette parcelle.
+ </notification>
+ <notification name="CantMoveObjectParcelResources">
+ Impossible de déplacer [OBJECT_NAME] jusqu&apos;à
+[OBJ_POSITION] dans la région [REGION_NAME] car il n&apos;y a pas suffisamment de ressources pour cet objet sur cette parcelle.
+ </notification>
+ <notification name="CantMoveObjectRegionVersion">
+ Impossible de déplacer [OBJECT_NAME] jusqu&apos;à
+[OBJ_POSITION] dans la région [REGION_NAME] car l&apos;autre région exécute une version plus ancienne qui ne prend pas en charge la réception de cet objet via le passage à une autre région.
+ </notification>
+ <notification name="CantMoveObjectNavMesh">
+ Impossible de déplacer [OBJECT_NAME] jusqu&apos;à
+[OBJ_POSITION] dans la région [REGION_NAME] car vous ne pouvez pas modifier le maillage de navigation d&apos;une région à une autre.
+ </notification>
+ <notification name="CantMoveObjectWTF">
+ Impossible de déplacer [OBJECT_NAME] jusqu&apos;à
+[OBJ_POSITION] dans la région [REGION_NAME] pour une raison inconnue. ([FAILURE_TYPE])
+ </notification>
+ <notification name="NoPermModifyObject">
+ Vous n&apos;êtes pas autorisé à modifier cet objet.
+ </notification>
+ <notification name="CantEnablePhysObjContributesToNav">
+ Impossible d&apos;activer les propriétés physiques pour un objet qui contribue au maillage de navigation.
+ </notification>
+ <notification name="CantEnablePhysKeyframedObj">
+ Impossible d&apos;activer les propriétés physiques pour les objets avec images-clés.
+ </notification>
+ <notification name="CantEnablePhysNotEnoughLandResources">
+ Impossible d&apos;activer les propriétés physiques pour l&apos;objet -- ressources de terrain insuffisantes.
+ </notification>
+ <notification name="CantEnablePhysCostTooGreat">
+ Impossible d&apos;activer les propriétés physiques pour les objets avec un coût de ressources physiques supérieur à [MAX_OBJECTS]
+ </notification>
+ <notification name="PhantomWithConcavePiece">
+ Cet objet ne peut pas contenir de morceau concave car c&apos;est un fantôme qui contribue au maillage de navigation.
+ </notification>
+ <notification name="UnableAddItem">
+ Ajout de l&apos;article impossible.
+ </notification>
+ <notification name="UnableEditItem">
+ Modification impossible
+ </notification>
+ <notification name="NoPermToEdit">
+ Modification interdite.
+ </notification>
+ <notification name="NoPermToCopyInventory">
+ Pas autorisé à copier cet inventaire.
+ </notification>
+ <notification name="CantSaveItemDoesntExist">
+ Impossible d&apos;enregistrer dans le contenu des objets : L&apos;article n&apos;existe plus.
+ </notification>
+ <notification name="CantSaveItemAlreadyExists">
+ Impossible d&apos;enregistrer dans le contenu des objets : Un article avec ce nom existe déjà dans l&apos;inventaire.
+ </notification>
+ <notification name="CantSaveModifyAttachment">
+ Impossible d&apos;enregistrer dans le contenu des objets : cela modifierait les droits d&apos;attache.
+ </notification>
+ <notification name="TooManyScripts">
+ Trop de scripts.
+ </notification>
+ <notification name="UnableAddScript">
+ Ajout du script impossible.
+ </notification>
+ <notification name="AssetServerTimeoutObjReturn">
+ Le serveur d&apos;actifs n&apos;a pas répondu assez vite. Objet renvoyé dans le sim.
+ </notification>
+ <notification name="RegionDisablePhysicsShapes">
+ Les formes physiques ne sont pas activées pour cette région.
+ </notification>
+ <notification name="NoModNavmeshAcrossRegions">
+ Vous ne pouvez pas modifier le maillage de navigation d&apos;une région à une autre.
+ </notification>
+ <notification name="NoSetPhysicsPropertiesOnObjectType">
+ Impossible de définir les propriétés physiques pour ce type d&apos;objet.
+ </notification>
+ <notification name="NoSetRootPrimWithNoShape">
+ Vous devenez définir une forme pour la prim racine.
+ </notification>
+ <notification name="NoRegionSupportPhysMats">
+ Les matériaux physiques ne sont pas activés pour cette région.
+ </notification>
+ <notification name="OnlyRootPrimPhysMats">
+ Les matériaux physiques ne peuvent être ajustés que pour les prims racines.
+ </notification>
+ <notification name="NoSupportCharacterPhysMats">
+ La configuration de matériaux physiques sur les personnages n&apos;est pas prise en charge actuellement.
+ </notification>
+ <notification name="InvalidPhysMatProperty">
+ Une ou plusieurs propriétés des ressources physiques spécifiées n&apos;étaient pas valides.
+ </notification>
+ <notification name="NoPermsAlterStitchingMeshObj">
+ Vous ne pouvez pas changer le type de raccord d&apos;un objet avec maillage.
+ </notification>
+ <notification name="NoPermsAlterShapeMeshObj">
+ Vous ne pouvez pas changer la forme d&apos;un objet avec maillage.
+ </notification>
+ <notification name="FullRegionCantEnter">
+ Vous ne pouvez pas pénétrer dans cette région car \ncar la région est pleine.
+ </notification>
+ <notification name="LinkFailedOwnersDiffer">
+ Échec du lien -- les propriétaires sont différents
+ </notification>
+ <notification name="LinkFailedNoModNavmeshAcrossRegions">
+ Échec du lien -- vous ne pouvez pas modifier le maillage de navigation d&apos;une région à une autre.
+ </notification>
+ <notification name="LinkFailedNoPermToEdit">
+ Échec du lien car vous ne disposez pas des droits de modification.
+ </notification>
+ <notification name="LinkFailedTooManyPrims">
+ Échec du lien -- trop de primitives
+ </notification>
+ <notification name="LinkFailedCantLinkNoCopyNoTrans">
+ Échec du lien -- impossible de lier pas de copie et pas de transfert
+ </notification>
+ <notification name="LinkFailedNothingLinkable">
+ Échec du lien - il n&apos;y a rien qui puisse être lié.
+ </notification>
+ <notification name="LinkFailedTooManyPathfindingChars">
+ Échec du lien -- trop de personnages de recherche de chemin
+ </notification>
+ <notification name="LinkFailedInsufficientLand">
+ Échec du lien -- ressources de terrain insuffisantes
+ </notification>
+ <notification name="LinkFailedTooMuchPhysics">
+ Cet objet utilise trop de ressources physiques - sa dynamique a été désactivée.
+ </notification>
+ <notification name="TeleportedHomeByObjectOnParcel">
+ Vous avez été téléporté chez vous par l&apos;objet [OBJECT_NAME] sur la parcelle [PARCEL_NAME].
+ </notification>
+ <notification name="TeleportedHomeByObject">
+ Vous avez été téléporté chez vous par l&apos;objet [OBJECT_NAME].
+ </notification>
+ <notification name="TeleportedByAttachment">
+ Vous avez été téléporté par un élément sur [ITEM_ID]
+ </notification>
+ <notification name="TeleportedByObjectOnParcel">
+ Vous avez été téléporté par l&apos;objet [OBJECT_NAME] sur la parcelle [PARCEL_NAME].
+ </notification>
+ <notification name="TeleportedByObjectOwnedBy">
+ Vous avez été téléporté par l&apos;objet [OBJECT_NAME] appartenant à [OWNER_ID].
+ </notification>
+ <notification name="TeleportedByObjectUnknownUser">
+ Vous avez été téléporté par l&apos;objet [OBJECT_NAME] appartenant à un utilisateur inconnu.
+ </notification>
+ <notification name="CantCreateObjectRegionFull">
+ Création de l&apos;objet demandé impossible. La région est pleine.
+ </notification>
+ <notification name="CantAttackMultipleObjOneSpot">
+ Vous ne pouvez pas attacher plusieurs objets au même endroit.
+ </notification>
+ <notification name="CantCreateMultipleObjAtLoc">
+ Vous ne pouvez pas créer plusieurs objets ici.
+ </notification>
+ <notification name="UnableToCreateObjTimeOut">
+ Création de l&apos;objet demandé impossible. Objet absent de la base de données.
+ </notification>
+ <notification name="UnableToCreateObjUnknown">
+ Création de l&apos;objet demandé impossible. Délai d&apos;attente dépassé. Veuillez réessayer.
+ </notification>
+ <notification name="UnableToCreateObjMissingFromDB">
+ Création de l&apos;objet demandé impossible. Veuillez réessayer.
+ </notification>
+ <notification name="RezFailureTookTooLong">
+ Échec de l&apos;action « rezzer », le chargement de l&apos;objet demandé a pris trop longtemps.
+ </notification>
+ <notification name="FailedToPlaceObjAtLoc">
+ Échec du placement de l&apos;objet à l&apos;emplacement spécifié. Veuillez réessayer.
+ </notification>
+ <notification name="CantCreatePlantsOnLand">
+ Vous ne pouvez pas créer de plantes sur ce terrain.
+ </notification>
+ <notification name="CantRestoreObjectNoWorldPos">
+ Impossible de restaurer l&apos;objet. Position dans le monde introuvable.
+ </notification>
+ <notification name="CantRezObjectInvalidMeshData">
+ Impossible de rezzer l&apos;objet car ses données de maillage ne sont pas valides.
+ </notification>
+ <notification name="CantRezObjectTooManyScripts">
+ Impossible de rezzer l&apos;objet car il y a déjà trop de scripts dans cette région.
+ </notification>
+ <notification name="CantCreateObjectNoAccess">
+ Vos privilèges d&apos;accès ne vous autorisent pas à créer des objets à cet endroit.
+ </notification>
+ <notification name="CantCreateObject">
+ Vous n&apos;êtes actuellement pas autorisé à créer des objets.
+ </notification>
+ <notification name="InvalidObjectParams">
+ Paramètres d&apos;objet non valides
+ </notification>
+ <notification name="CantDuplicateObjectNoAcess">
+ Vos privilèges d&apos;accès ne vous autorisent pas à dupliquer des objets ici.
+ </notification>
+ <notification name="CantChangeShape">
+ Vous n’êtes pas autorisé à modifier cette forme.
+ </notification>
+ <notification name="NoAccessToClaimObjects">
+ Vos privilèges d&apos;accès ne vous autorisent pas à revendiquer des objets ici.
+ </notification>
+ <notification name="DeedFailedNoPermToDeedForGroup">
+ Échec de la cession car vous de disposez pas des droits de cession des objets pour votre groupe.
+ </notification>
+ <notification name="NoPrivsToBuyObject">
+ Vos privilèges d&apos;accès ne vous autorisent pas à acheter des objets ici.
+ </notification>
+ <notification name="CantAttachObjectAvatarSittingOnIt">
+ Impossible d&apos;attacher l&apos;objet car un avatar est assis dessus.
+ </notification>
+ <notification name="WhyAreYouTryingToWearShrubbery">
+ Les arbres et les plantes ne peuvent pas être portés sous forme d&apos;éléments attachés.
+ </notification>
+ <notification name="CantAttachGroupOwnedObjs">
+ Impossible d&apos;attacher les objets appartenant au groupe.
+ </notification>
+ <notification name="CantAttachObjectsNotOwned">
+ Vous ne pouvez pas attacher des objets qui ne vous appartiennent pas.
+ </notification>
+ <notification name="CantAttachNavmeshObjects">
+ Impossible d&apos;attacher les objets contribuant au maillage de navigation.
+ </notification>
+ <notification name="CantAttachObjectNoMovePermissions">
+ Impossible d&apos;attacher l&apos;objet car vous n&apos;avez pas le droit de le déplacer.
+ </notification>
+ <notification name="CantAttachNotEnoughScriptResources">
+ Ressources de script insuffisantes pour attacher cet objet.
+ </notification>
+ <notification name="CantDropItemTrialUser">
+ Vous ne pouvez pas déposer d&apos;objets ici. Essayez la zone de période d&apos;essai gratuite.
+ </notification>
+ <notification name="CantDropMeshAttachment">
+ Vous ne pouvez pas déposer les éléments attachés avec maillage. Détachez-les dans l&apos;inventaire puis rezzez-les dans le monde.
+ </notification>
+ <notification name="CantDropAttachmentNoPermission">
+ L&apos;élément n&apos;a pas pu être déposé : vous n&apos;avez pas le droit de déposer des éléments à cet endroit.
+ </notification>
+ <notification name="CantDropAttachmentInsufficientLandResources">
+ L&apos;élément n&apos;a pas pu être déposé : ressources de terrain disponibles insuffisantes.
+ </notification>
+ <notification name="CantDropAttachmentInsufficientResources">
+ Les éléments n&apos;ont pas pu être déposés : ressources disponibles insuffisantes.
+ </notification>
+ <notification name="CantDropObjectFullParcel">
+ Impossible de déposer l&apos;objet ici. La parcelle est pleine.
+ </notification>
+ <notification name="CantTouchObjectBannedFromParcel">
+ Vous ne pouvez pas toucher/attraper cet objet car vous êtes banni de cette parcelle de terrain.
+ </notification>
+ <notification name="PlzNarrowDeleteParams">
+ Veuillez affiner vos paramètres de suppression.
+ </notification>
+ <notification name="UnableToUploadAsset">
+ Chargement de l&apos;actif impossible.
+ </notification>
+ <notification name="CantTeleportCouldNotFindUser">
+ Impossible de trouver l&apos;utilisateur à téléporter chez lui
+ </notification>
+ <notification name="GodlikeRequestFailed">
+ échec de la demande de type divine
+ </notification>
+ <notification name="GenericRequestFailed">
+ échec de la demande générique
+ </notification>
+ <notification name="CantUploadPostcard">
+ Chargement de la carte postale impossible. Réessayez ultérieurement.
+ </notification>
+ <notification name="CantFetchInventoryForGroupNotice">
+ Impossible récupérer les détails de l&apos;inventaire pour la notice au groupe.
+ </notification>
+ <notification name="CantSendGroupNoticeNotPermitted">
+ Impossible d&apos;envoyer une notice au groupe -- ce n&apos;est pas autorisé.
+ </notification>
+ <notification name="CantSendGroupNoticeCantConstructInventory">
+ Impossible d&apos;envoyer une notice au groupe - échec de la construction de l&apos;inventaire.
+ </notification>
+ <notification name="CantParceInventoryInNotice">
+ Impossible d&apos;analyser l&apos;inventaire dans la notice.
+ </notification>
+ <notification name="TerrainUploadFailed">
+ Échec du chargement du terrain.
+ </notification>
+ <notification name="TerrainFileWritten">
+ Fichier de terrain écrit
+ </notification>
+ <notification name="TerrainFileWrittenStartingDownload">
+ Fichier de terrain écrit, lancement du téléchargement...
+ </notification>
+ <notification name="TerrainBaked">
+ Terrain figé.
+ </notification>
+ <notification name="TenObjectsDisabledPlzRefresh">
+ Seuls les 10 premiers objets sélectionnés ont été désactivés. Actualisez et effectuez des sélections supplémentaires si nécessaire.
+ </notification>
+ <notification name="UpdateViewerBuyParcel">
+ Vous devez mettre votre client à jour pour acheter cette parcelle.
+ </notification>
+ <notification name="CantBuyParcelNotForSale">
+ Achat impossible, cette parcelle n&apos;est pas à vendre.
+ </notification>
+ <notification name="CantBuySalePriceOrLandAreaChanged">
+ Achat impossible, le prix de vente ou la zone de terrain a changé.
+ </notification>
+ <notification name="CantBuyParcelNotAuthorized">
+ Vous n&apos;êtes pas un acheteur autorisé pour cette parcelle.
+ </notification>
+ <notification name="CantBuyParcelAwaitingPurchaseAuth">
+ Vous ne pouvez pas acheter cette parcelle car elle est déjà en attente d&apos;une autorisation d&apos;achat.
+ </notification>
+ <notification name="CantBuildOverflowParcel">
+ Vous ne pouvez pas construire d&apos;objets ici car cela saturerait la parcelle.
+ </notification>
+ <notification name="SelectedMultipleOwnedLand">
+ Vous avez sélectionné des terrains avec des propriétaires différents. Sélectionnez une zone plus petite et réessayez.
+ </notification>
+ <notification name="CantJoinTooFewLeasedParcels">
+ Pas suffisamment de parcelles louées dans la sélection pour effectuer la fusion.
+ </notification>
+ <notification name="CantDivideLandMultipleParcelsSelected">
+ Division du terrain impossible.\nPlusieurs parcelles sont sélectionnées.\nVeuillez sélectionner un terrain plus petit.
+ </notification>
+ <notification name="CantDivideLandCantFindParcel">
+ Division du terrain impossible.\nParcelle introuvable.\nSignalez-le en allant à Aide -&gt; Signaler un bug...
+ </notification>
+ <notification name="CantDivideLandWholeParcelSelected">
+ Division du terrain impossible. Toute la parcelle est sélectionnée.\nVeuillez sélectionner un terrain plus petit.
+ </notification>
+ <notification name="LandHasBeenDivided">
+ Le terrain a été divisé.
+ </notification>
+ <notification name="PassPurchased">
+ Vous avez acheté un pass.
+ </notification>
+ <notification name="RegionDisallowsClassifieds">
+ Cette région n&apos;autorise pas les petites annonces.
+ </notification>
+ <notification name="LandPassExpireSoon">
+ Votre pass pour ce terrain arrive à expiration.
+ </notification>
+ <notification name="CantSitNoSuitableSurface">
+ Il n&apos;y a pas de surface appropriée sur laquelle s&apos;asseoir, essayez un autre endroit.
+ </notification>
+ <notification name="CantSitNoRoom">
+ Pas de place pour s&apos;asseoir ici, essayez un autre endroit.
+ </notification>
+ <notification name="ClaimObjectFailedNoPermission">
+ Échec de la revendication de l&apos;objet car vous ne disposez pas des droits requis.
+ </notification>
+ <notification name="ClaimObjectFailedNoMoney">
+ Échec de la revendication de l&apos;objet car vous ne disposez pas de suffisamment de L$.
+ </notification>
+ <notification name="CantDeedGroupLand">
+ Impossible de céder un terrain appartenant au groupe.
+ </notification>
+ <notification name="BuyObjectFailedNoMoney">
+ Échec de l&apos;achat de l&apos;objet car vous ne disposez pas de suffisamment de L$.
+ </notification>
+ <notification name="BuyInventoryFailedNoMoney">
+ Échec de l&apos;achat d&apos;inventaire car vous ne disposez pas de suffisamment de L$.
+ </notification>
+ <notification name="BuyPassFailedNoMoney">
+ Vous ne disposez pas de suffisamment de L$ pour acheter un pass pour ce terrain.
+ </notification>
+ <notification name="CantBuyPassTryAgain">
+ Impossible d&apos;acheter le pass actuellement. Réessayez ultérieurement.
+ </notification>
+ <notification name="CantCreateObjectParcelFull">
+ Création de l&apos;objet impossible car \nla parcelle est pleine.
+ </notification>
+ <notification name="FailedPlacingObject">
+ Échec du placement de l&apos;objet à l&apos;emplacement spécifié. Veuillez réessayer.
+ </notification>
+ <notification name="CantCreateLandmarkForEvent">
+ Impossible de créer le repère pour l&apos;événement.
+ </notification>
+ <notification name="GodBeatsFreeze">
+ Grâce à vos pouvoirs de type divin, vous n&apos;êtes plus figé.
+ </notification>
+ <notification name="SpecialPowersRequestFailedLogged">
+ Échec de la demande de pouvoirs spéciaux. Cette demande a été archivée.
+ </notification>
+ <notification name="ExpireExplanation">
+ Le système ne peut pas traiter votre demande actuellement. Délai d&apos;attente dépassé.
+ </notification>
+ <notification name="DieExplanation">
+ Le système ne peut pas traiter votre demande.
+ </notification>
+ <notification name="AddPrimitiveFailure">
+ Fonds insuffisants pour créer la primitive.
+ </notification>
+ <notification name="RezObjectFailure">
+ Fonds insuffisants pour créer l&apos;objet.
+ </notification>
+ <notification name="ResetHomePositionNotLegal">
+ Réinitialiser l&apos;emplacement du domicile car il n&apos;était pas légal.
+ </notification>
+ <notification name="CantInviteRegionFull">
+ Vous ne pouvez pas inviter quiconque là où vous vous trouvez actuellement car la région est pleine. Réessayez ultérieurement.
+ </notification>
+ <notification name="CantSetHomeAtRegion">
+ Cette région ne vous permet pas d&apos;y définir votre domicile.
+ </notification>
+ <notification name="ListValidHomeLocations">
+ Vous ne pouvez définir votre domicile que sur votre terrain ou un infohub du continent.
+ </notification>
+ <notification name="SetHomePosition">
+ Emplacement du domicile défini.
+ </notification>
+ <notification name="CantDerezInventoryError">
+ Impossible de dérezzer l&apos;objet à cause d&apos;un défaut d&apos;inventaire.
+ </notification>
+ <notification name="CantCreateRequestedInv">
+ Création de l&apos;inventaire demandé impossible.
+ </notification>
+ <notification name="CantCreateRequestedInvFolder">
+ Création du dossier d&apos;inventaire demandé impossible.
+ </notification>
+ <notification name="CantCreateInventory">
+ Création de cet inventaire impossible.
+ </notification>
+ <notification name="CantCreateLandmark">
+ Création du repère impossible.
+ </notification>
+ <notification name="CantCreateOutfit">
+ Création de la tenue impossible. Veuillez réessayer dans une minute.
+ </notification>
+ <notification name="InventoryNotForSale">
+ L&apos;inventaire n&apos;est pas à vendre.
+ </notification>
+ <notification name="CantFindInvItem">
+ Objet de l&apos;inventaire introuvable.
+ </notification>
+ <notification name="CantFindObject">
+ Objet introuvable.
+ </notification>
+ <notification name="CantTransfterMoneyRegionDisabled">
+ Les transferts d&apos;argent aux objets sont actuellement désactivés dans cette région.
+ </notification>
+ <notification name="CantPayNoAgent">
+ Impossible de savoir qui payer.
+ </notification>
+ <notification name="CantDonateToPublicObjects">
+ Vous ne pouvez pas donner de L$ à des objets publics.
+ </notification>
+ <notification name="InventoryCreationInWorldObjectFailed">
+ Échec de la création d&apos;inventaire sur l&apos;objet Second Life.
+ </notification>
+ <notification name="UserBalanceOrLandUsageError">
+ Une erreur interne nous a empêchés de mettre votre client à jour correctement. Le solde de L$ et le patrimoine affichés dans votre client peuvent ne pas correspondre à votre solde réel sur les serveurs.
+ </notification>
+ <notification name="LargePrimAgentIntersect">
+ Impossible de créer de grandes prims qui coupent d&apos;autres joueurs. Réessayez une fois que les autres joueurs se seront déplacés.
+ </notification>
+ <notification name="PreferenceChatClearLog">
+ Cela supprimera les journaux des conversations précédentes, ainsi que toute copie de sauvegarde de ce fichier.
+ <usetemplate ignoretext="Confirmer avant de supprimer le journal des conversations précédentes" name="okcancelignore" notext="Annuler" yestext="OK"/>
+ </notification>
+ <notification name="PreferenceChatDeleteTranscripts">
+ Cela supprimera les transcriptions de toutes les conversations précédentes. La liste des conversations passées ne sera pas affectée. Tous les fichiers avec les suffixes .txt et txt.backup dans le dossier [FOLDER] seront supprimés.
+ <usetemplate ignoretext="Confirmer avant la suppression des transcriptions" name="okcancelignore" notext="Annuler" yestext="OK"/>
+ </notification>
+ <notification name="PreferenceChatPathChanged">
+ Impossible de déplacer les fichiers. Chemin précédent rétabli.
+ <usetemplate ignoretext="Impossible de déplacer les fichiers. Chemin précédent rétabli." name="okignore" yestext="OK"/>
+ </notification>
</notifications>
diff --git a/indra/newview/skins/default/xui/fr/outfit_accordion_tab.xml b/indra/newview/skins/default/xui/fr/outfit_accordion_tab.xml
index bac885e5d8..bac885e5d8 100644..100755
--- a/indra/newview/skins/default/xui/fr/outfit_accordion_tab.xml
+++ b/indra/newview/skins/default/xui/fr/outfit_accordion_tab.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_active_object_row.xml b/indra/newview/skins/default/xui/fr/panel_active_object_row.xml
index 0baa8353d9..0baa8353d9 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_active_object_row.xml
+++ b/indra/newview/skins/default/xui/fr/panel_active_object_row.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_adhoc_control_panel.xml b/indra/newview/skins/default/xui/fr/panel_adhoc_control_panel.xml
index 4191ba42f9..4191ba42f9 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_adhoc_control_panel.xml
+++ b/indra/newview/skins/default/xui/fr/panel_adhoc_control_panel.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_avatar_list_item.xml b/indra/newview/skins/default/xui/fr/panel_avatar_list_item.xml
index 54b8f53e59..c8fa9f340f 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_avatar_list_item.xml
+++ b/indra/newview/skins/default/xui/fr/panel_avatar_list_item.xml
@@ -27,5 +27,6 @@
<icon name="permission_edit_mine_icon" tool_tip="Cet(te) ami(e) peut modifier, supprimer ou prendre vos objets."/>
<icon name="permission_map_icon" tool_tip="Cet(te) ami(e) peut vous localiser sur la carte."/>
<icon name="permission_online_icon" tool_tip="Cet(te) ami(e) peut voir lorsque vous êtes en ligne."/>
+ <button name="info_btn" tool_tip="En savoir plus"/>
<button name="profile_btn" tool_tip="Voir le profil"/>
</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_avatar_tag.xml b/indra/newview/skins/default/xui/fr/panel_avatar_tag.xml
index 20a355b11d..20a355b11d 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_avatar_tag.xml
+++ b/indra/newview/skins/default/xui/fr/panel_avatar_tag.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_block_list_sidetray.xml b/indra/newview/skins/default/xui/fr/panel_block_list_sidetray.xml
index f54bed4fae..0e2b5a9c93 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_block_list_sidetray.xml
+++ b/indra/newview/skins/default/xui/fr/panel_block_list_sidetray.xml
@@ -1,10 +1,11 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel name="block_list_panel">
- <text name="title_text">
- Liste des ignorés
- </text>
- <scroll_list name="blocked" tool_tip="Liste des résidents actuellement ignorés"/>
- <button label="Ignorer une personne" label_selected="Ignorer le résident..." name="Block resident..." tool_tip="Choisir un résident à ignorer"/>
- <button label="Ignorer l&apos;objet par nom" label_selected="Ignorer l&apos;objet par nom..." name="Block object by name..." tool_tip="Choisir un objet à ignorer par nom"/>
- <button label="Ne plus ignorer" label_selected="Ne plus ignorer" name="Unblock" tool_tip="Enlever le résident ou l&apos;objet de la liste des ignorés"/>
+ <panel label="bottom_panel" name="blocked_buttons_panel">
+ <filter_editor label="Filtrer" name="blocked_filter_input"/>
+ <menu_button name="blocked_gear_btn" tool_tip="Actions sur la personne ou l&apos;objet sélectionné"/>
+ <menu_button name="view_btn" tool_tip="Options de tri"/>
+ <menu_button name="plus_btn" tool_tip="Choisir un résident ou un objet à ignorer"/>
+ <button name="unblock_btn" tool_tip="Enlever le résident ou l’objet de la liste des ignorés"/>
+ </panel>
+ <block_list name="blocked" tool_tip="Liste des résidents actuellement ignorés"/>
</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_body_parts_list_item.xml b/indra/newview/skins/default/xui/fr/panel_body_parts_list_item.xml
index 377f85368f..377f85368f 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_body_parts_list_item.xml
+++ b/indra/newview/skins/default/xui/fr/panel_body_parts_list_item.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_bodyparts_list_button_bar.xml b/indra/newview/skins/default/xui/fr/panel_bodyparts_list_button_bar.xml
index 5e7442b877..5e7442b877 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_bodyparts_list_button_bar.xml
+++ b/indra/newview/skins/default/xui/fr/panel_bodyparts_list_button_bar.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_bottomtray.xml b/indra/newview/skins/default/xui/fr/panel_bottomtray.xml
deleted file mode 100644
index c4537861e3..0000000000
--- a/indra/newview/skins/default/xui/fr/panel_bottomtray.xml
+++ /dev/null
@@ -1,47 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel name="bottom_tray">
- <string name="DragIndicationImageName" value="Accordion_ArrowOpened_Off"/>
- <string name="SpeakBtnToolTip" value="Active/Désactive le micro"/>
- <string name="VoiceControlBtnToolTip" value="Affiche/Masque le panneau de contrôle de la voix"/>
- <layout_stack name="toolbar_stack">
- <layout_panel name="speak_panel">
- <talk_button name="talk">
- <speak_button label="Parler" label_selected="Parler" name="speak_btn"/>
- </talk_button>
- </layout_panel>
- <layout_panel name="gesture_panel">
- <gesture_combo_list label="Geste" name="Gesture" tool_tip="Affiche/Masque les gestes"/>
- </layout_panel>
- <layout_panel name="movement_panel">
- <bottomtray_button label="Bouger" name="movement_btn" tool_tip="Affiche/Masque le contrôle des déplacements"/>
- </layout_panel>
- <layout_panel name="cam_panel">
- <bottomtray_button label="Affichage" name="camera_btn" tool_tip="Affiche/Masque le contrôle de la caméra"/>
- </layout_panel>
- <layout_panel name="snapshot_panel">
- <bottomtray_button label="" name="snapshots" tool_tip="Prendre une photo"/>
- </layout_panel>
- <layout_panel name="build_btn_panel">
- <bottomtray_button label="Construire" name="build_btn" tool_tip="Affiche/Masque les outils pour la construction"/>
- </layout_panel>
- <layout_panel name="search_btn_panel">
- <bottomtray_button label="Rechercher" name="search_btn" tool_tip="Affiche/Masque la recherche"/>
- </layout_panel>
- <layout_panel name="world_map_btn_panel">
- <bottomtray_button label="Carte" name="world_map_btn" tool_tip="Affiche/Masque la carte du monde"/>
- </layout_panel>
- <layout_panel name="mini_map_btn_panel">
- <bottomtray_button label="Mini-carte" name="mini_map_btn" tool_tip="Affiche/Masque la mini-carte"/>
- </layout_panel>
- <layout_panel name="im_well_panel">
- <chiclet_im_well name="im_well">
- <button name="Unread IM messages" tool_tip="Conversations"/>
- </chiclet_im_well>
- </layout_panel>
- <layout_panel name="notification_well_panel">
- <chiclet_notification name="notification_well">
- <button name="Unread" tool_tip="Notifications"/>
- </chiclet_notification>
- </layout_panel>
- </layout_stack>
-</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_bottomtray_lite.xml b/indra/newview/skins/default/xui/fr/panel_bottomtray_lite.xml
index 5b6d37ce00..5b6d37ce00 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_bottomtray_lite.xml
+++ b/indra/newview/skins/default/xui/fr/panel_bottomtray_lite.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_chat_header.xml b/indra/newview/skins/default/xui/fr/panel_chat_header.xml
index 7916bf5155..7916bf5155 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_chat_header.xml
+++ b/indra/newview/skins/default/xui/fr/panel_chat_header.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_chiclet_bar.xml b/indra/newview/skins/default/xui/fr/panel_chiclet_bar.xml
index de21996404..de21996404 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_chiclet_bar.xml
+++ b/indra/newview/skins/default/xui/fr/panel_chiclet_bar.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_classified_info.xml b/indra/newview/skins/default/xui/fr/panel_classified_info.xml
index c4265be877..c4265be877 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_classified_info.xml
+++ b/indra/newview/skins/default/xui/fr/panel_classified_info.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_clothing_list_button_bar.xml b/indra/newview/skins/default/xui/fr/panel_clothing_list_button_bar.xml
index 0b58a4e40b..0b58a4e40b 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_clothing_list_button_bar.xml
+++ b/indra/newview/skins/default/xui/fr/panel_clothing_list_button_bar.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_clothing_list_item.xml b/indra/newview/skins/default/xui/fr/panel_clothing_list_item.xml
index b23cb91c6f..b23cb91c6f 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_clothing_list_item.xml
+++ b/indra/newview/skins/default/xui/fr/panel_clothing_list_item.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_cof_wearables.xml b/indra/newview/skins/default/xui/fr/panel_cof_wearables.xml
index c1085aa461..c1085aa461 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_cof_wearables.xml
+++ b/indra/newview/skins/default/xui/fr/panel_cof_wearables.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_conversation_list_item.xml b/indra/newview/skins/default/xui/fr/panel_conversation_list_item.xml
new file mode 100644
index 0000000000..ebf18f6483
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/panel_conversation_list_item.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="conversation_list_item">
+ <layout_stack name="conversation_item_stack">
+ <layout_panel name="conversation_title_panel">
+ <text name="conversation_title" value="(chargement)"/>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_conversation_log_list_item.xml b/indra/newview/skins/default/xui/fr/panel_conversation_log_list_item.xml
new file mode 100644
index 0000000000..9c277842b5
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/panel_conversation_log_list_item.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="conversation_log_list_item">
+ <icon name="voice_session_icon" tool_tip="Incluait une conversation vocale"/>
+ <icon name="unread_ims_icon" tool_tip="Des messages sont arrivés pendant que vous étiez déconnecté."/>
+ <button name="delete_btn" tool_tip="Supprimer cette entrée"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_deletable_wearable_list_item.xml b/indra/newview/skins/default/xui/fr/panel_deletable_wearable_list_item.xml
index e1fa769f2f..e1fa769f2f 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_deletable_wearable_list_item.xml
+++ b/indra/newview/skins/default/xui/fr/panel_deletable_wearable_list_item.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_dummy_clothing_list_item.xml b/indra/newview/skins/default/xui/fr/panel_dummy_clothing_list_item.xml
index bc0edda5b6..bc0edda5b6 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_dummy_clothing_list_item.xml
+++ b/indra/newview/skins/default/xui/fr/panel_dummy_clothing_list_item.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_edit_alpha.xml b/indra/newview/skins/default/xui/fr/panel_edit_alpha.xml
index a8b95c66fb..a8b95c66fb 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_edit_alpha.xml
+++ b/indra/newview/skins/default/xui/fr/panel_edit_alpha.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_edit_classified.xml b/indra/newview/skins/default/xui/fr/panel_edit_classified.xml
index 7b58f2e825..7b58f2e825 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_edit_classified.xml
+++ b/indra/newview/skins/default/xui/fr/panel_edit_classified.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_edit_eyes.xml b/indra/newview/skins/default/xui/fr/panel_edit_eyes.xml
index 549864e237..549864e237 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_edit_eyes.xml
+++ b/indra/newview/skins/default/xui/fr/panel_edit_eyes.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_edit_gloves.xml b/indra/newview/skins/default/xui/fr/panel_edit_gloves.xml
index 68a7ac54e2..68a7ac54e2 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_edit_gloves.xml
+++ b/indra/newview/skins/default/xui/fr/panel_edit_gloves.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_edit_hair.xml b/indra/newview/skins/default/xui/fr/panel_edit_hair.xml
index 575cbabc88..575cbabc88 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_edit_hair.xml
+++ b/indra/newview/skins/default/xui/fr/panel_edit_hair.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_edit_jacket.xml b/indra/newview/skins/default/xui/fr/panel_edit_jacket.xml
index 7e467b130c..7e467b130c 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_edit_jacket.xml
+++ b/indra/newview/skins/default/xui/fr/panel_edit_jacket.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_edit_pants.xml b/indra/newview/skins/default/xui/fr/panel_edit_pants.xml
index 60d8e947f8..60d8e947f8 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_edit_pants.xml
+++ b/indra/newview/skins/default/xui/fr/panel_edit_pants.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_edit_physics.xml b/indra/newview/skins/default/xui/fr/panel_edit_physics.xml
index d79f7df90a..d79f7df90a 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_edit_physics.xml
+++ b/indra/newview/skins/default/xui/fr/panel_edit_physics.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_edit_pick.xml b/indra/newview/skins/default/xui/fr/panel_edit_pick.xml
index 247e18da82..247e18da82 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_edit_pick.xml
+++ b/indra/newview/skins/default/xui/fr/panel_edit_pick.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_edit_profile.xml b/indra/newview/skins/default/xui/fr/panel_edit_profile.xml
index 9e63c88221..9e63c88221 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_edit_profile.xml
+++ b/indra/newview/skins/default/xui/fr/panel_edit_profile.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_edit_shape.xml b/indra/newview/skins/default/xui/fr/panel_edit_shape.xml
index 6a5f71a36b..6a5f71a36b 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_edit_shape.xml
+++ b/indra/newview/skins/default/xui/fr/panel_edit_shape.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_edit_shirt.xml b/indra/newview/skins/default/xui/fr/panel_edit_shirt.xml
index 9a263f6148..9a263f6148 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_edit_shirt.xml
+++ b/indra/newview/skins/default/xui/fr/panel_edit_shirt.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_edit_shoes.xml b/indra/newview/skins/default/xui/fr/panel_edit_shoes.xml
index 3eb70923ef..3eb70923ef 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_edit_shoes.xml
+++ b/indra/newview/skins/default/xui/fr/panel_edit_shoes.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_edit_skin.xml b/indra/newview/skins/default/xui/fr/panel_edit_skin.xml
index f5f2738319..f5f2738319 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_edit_skin.xml
+++ b/indra/newview/skins/default/xui/fr/panel_edit_skin.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_edit_skirt.xml b/indra/newview/skins/default/xui/fr/panel_edit_skirt.xml
index f562d67937..f562d67937 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_edit_skirt.xml
+++ b/indra/newview/skins/default/xui/fr/panel_edit_skirt.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_edit_socks.xml b/indra/newview/skins/default/xui/fr/panel_edit_socks.xml
index f97047ae28..f97047ae28 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_edit_socks.xml
+++ b/indra/newview/skins/default/xui/fr/panel_edit_socks.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_edit_tattoo.xml b/indra/newview/skins/default/xui/fr/panel_edit_tattoo.xml
index 086542dee2..086542dee2 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_edit_tattoo.xml
+++ b/indra/newview/skins/default/xui/fr/panel_edit_tattoo.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_edit_underpants.xml b/indra/newview/skins/default/xui/fr/panel_edit_underpants.xml
index c83ce04885..c83ce04885 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_edit_underpants.xml
+++ b/indra/newview/skins/default/xui/fr/panel_edit_underpants.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_edit_undershirt.xml b/indra/newview/skins/default/xui/fr/panel_edit_undershirt.xml
index 689b7b81f4..689b7b81f4 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_edit_undershirt.xml
+++ b/indra/newview/skins/default/xui/fr/panel_edit_undershirt.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_edit_wearable.xml b/indra/newview/skins/default/xui/fr/panel_edit_wearable.xml
index def158cf68..def158cf68 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_edit_wearable.xml
+++ b/indra/newview/skins/default/xui/fr/panel_edit_wearable.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_group_control_panel.xml b/indra/newview/skins/default/xui/fr/panel_group_control_panel.xml
index 3e66b3c72a..3e66b3c72a 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_group_control_panel.xml
+++ b/indra/newview/skins/default/xui/fr/panel_group_control_panel.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_group_general.xml b/indra/newview/skins/default/xui/fr/panel_group_general.xml
index a2655dcd45..a2655dcd45 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_group_general.xml
+++ b/indra/newview/skins/default/xui/fr/panel_group_general.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_group_info_sidetray.xml b/indra/newview/skins/default/xui/fr/panel_group_info_sidetray.xml
index 047cd692e8..047cd692e8 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_group_info_sidetray.xml
+++ b/indra/newview/skins/default/xui/fr/panel_group_info_sidetray.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_group_invite.xml b/indra/newview/skins/default/xui/fr/panel_group_invite.xml
index 53f7ac33c2..d792439220 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_group_invite.xml
+++ b/indra/newview/skins/default/xui/fr/panel_group_invite.xml
@@ -9,6 +9,9 @@
<panel.string name="already_in_group">
Certains résidents que vous avez choisis font déjà partie du groupe et l&apos;invitation ne leur a donc pas été envoyée.
</panel.string>
+ <panel.string name="invite_selection_too_large">
+ Invitations de groupe non envoyées : trop de résidents sélectionnés. Les invitations de groupe sont limitées à 100 par demande.
+ </panel.string>
<text name="help_text">
Vous pouvez inviter plusieurs résidents à la fois. Cliquez d&apos;abord sur Choisir un résident.
</text>
diff --git a/indra/newview/skins/default/xui/fr/panel_group_land_money.xml b/indra/newview/skins/default/xui/fr/panel_group_land_money.xml
index 4011d1b8c7..4011d1b8c7 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_group_land_money.xml
+++ b/indra/newview/skins/default/xui/fr/panel_group_land_money.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_group_list_item.xml b/indra/newview/skins/default/xui/fr/panel_group_list_item.xml
index 5fb69d1989..b1b32af7c6 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_group_list_item.xml
+++ b/indra/newview/skins/default/xui/fr/panel_group_list_item.xml
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel name="group_list_item">
<text name="group_name" value="Inconnu"/>
+ <button name="info_btn" tool_tip="En savoir plus"/>
<button name="profile_btn" tool_tip="Voir le profil"/>
</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_group_notices.xml b/indra/newview/skins/default/xui/fr/panel_group_notices.xml
index 3364dd9dbc..3364dd9dbc 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_group_notices.xml
+++ b/indra/newview/skins/default/xui/fr/panel_group_notices.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_group_notify.xml b/indra/newview/skins/default/xui/fr/panel_group_notify.xml
index 08a49f908c..08a49f908c 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_group_notify.xml
+++ b/indra/newview/skins/default/xui/fr/panel_group_notify.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_group_roles.xml b/indra/newview/skins/default/xui/fr/panel_group_roles.xml
index 0bd2e0bdab..0bd2e0bdab 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_group_roles.xml
+++ b/indra/newview/skins/default/xui/fr/panel_group_roles.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_im_control_panel.xml b/indra/newview/skins/default/xui/fr/panel_im_control_panel.xml
index 1f2169e22c..1f2169e22c 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_im_control_panel.xml
+++ b/indra/newview/skins/default/xui/fr/panel_im_control_panel.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_instant_message.xml b/indra/newview/skins/default/xui/fr/panel_instant_message.xml
index 305d2d853c..305d2d853c 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_instant_message.xml
+++ b/indra/newview/skins/default/xui/fr/panel_instant_message.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_inventory_item.xml b/indra/newview/skins/default/xui/fr/panel_inventory_item.xml
index d18047fbcf..d18047fbcf 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_inventory_item.xml
+++ b/indra/newview/skins/default/xui/fr/panel_inventory_item.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_landmark_info.xml b/indra/newview/skins/default/xui/fr/panel_landmark_info.xml
index 60507f191d..60507f191d 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_landmark_info.xml
+++ b/indra/newview/skins/default/xui/fr/panel_landmark_info.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_landmarks.xml b/indra/newview/skins/default/xui/fr/panel_landmarks.xml
index 7501e54f11..7501e54f11 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_landmarks.xml
+++ b/indra/newview/skins/default/xui/fr/panel_landmarks.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_login.xml b/indra/newview/skins/default/xui/fr/panel_login.xml
index e54b36644c..c8a1fe8751 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_login.xml
+++ b/indra/newview/skins/default/xui/fr/panel_login.xml
@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel name="panel_login">
- <panel.string name="create_account_url">
- http://fr.secondlife.com/registration/
- </panel.string>
<panel.string name="forgot_password_url">
http://secondlife.com/account/request.php?lang=fr
</panel.string>
<layout_stack name="login_widgets">
<layout_panel name="login">
+ <text name="log_in_text">
+ CONNEXION
+ </text>
<text name="username_text">
Nom d&apos;utilisateur :
</text>
@@ -15,34 +15,32 @@
<text name="password_text">
Mot de passe :
</text>
- <check_box label="Enregistrer" name="remember_check"/>
- <button label="Connexion" name="connect_btn"/>
- <text name="mode_selection_text">
- Mode :
- </text>
- <combo_box name="mode_combo" tool_tip="Sélectionnez un mode. Pour une exploration facile et rapide avec chat, choisissez Basique. Pour accéder à plus de fonctionnalités, choisissez Avancé.">
- <combo_box.item label="Basique" name="Basic"/>
- <combo_box.item label="Avancé" name="Advanced"/>
- </combo_box>
+ </layout_panel>
+ <layout_panel name="start_location_panel">
<text name="start_location_text">
Lieu de départ :
</text>
<combo_box name="start_location_combo">
<combo_box.item label="Dernier emplacement" name="MyLastLocation"/>
<combo_box.item label="Domicile" name="MyHome"/>
- <combo_box.item label="&lt;Saisir le nom de la région&gt;" name="Typeregionname"/>
+ <combo_box.item label="&lt;Nom de la région&gt;" name="Typeregionname"/>
</combo_box>
</layout_panel>
- <layout_panel name="links">
- <text name="create_new_account_text">
- S&apos;inscrire
+ <layout_panel name="links_login_panel">
+ <text name="login_help">
+ Besoin d&apos;aide ?
</text>
<text name="forgot_password_text">
Nom d&apos;utilisateur ou mot de passe oublié ?
</text>
- <text name="login_help">
- Besoin d&apos;aide ?
+ <button label="Connexion" name="connect_btn"/>
+ <check_box label="Enregistrer" name="remember_check"/>
+ </layout_panel>
+ <layout_panel name="links">
+ <text name="create_account_text">
+ CRÉER VOTRE COMPTE
</text>
+ <button label="Commencer" name="create_new_account_btn"/>
</layout_panel>
</layout_stack>
</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_main_inventory.xml b/indra/newview/skins/default/xui/fr/panel_main_inventory.xml
index db7d254b7a..db7d254b7a 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_main_inventory.xml
+++ b/indra/newview/skins/default/xui/fr/panel_main_inventory.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_me.xml b/indra/newview/skins/default/xui/fr/panel_me.xml
index 5676986228..5676986228 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_me.xml
+++ b/indra/newview/skins/default/xui/fr/panel_me.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_media_settings_general.xml b/indra/newview/skins/default/xui/fr/panel_media_settings_general.xml
index e048e66810..e048e66810 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_media_settings_general.xml
+++ b/indra/newview/skins/default/xui/fr/panel_media_settings_general.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_media_settings_permissions.xml b/indra/newview/skins/default/xui/fr/panel_media_settings_permissions.xml
index 8f1b436ba1..8f1b436ba1 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_media_settings_permissions.xml
+++ b/indra/newview/skins/default/xui/fr/panel_media_settings_permissions.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_media_settings_security.xml b/indra/newview/skins/default/xui/fr/panel_media_settings_security.xml
index 9d070b7aff..9d070b7aff 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_media_settings_security.xml
+++ b/indra/newview/skins/default/xui/fr/panel_media_settings_security.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_navigation_bar.xml b/indra/newview/skins/default/xui/fr/panel_navigation_bar.xml
index ecb1e9813a..ecb1e9813a 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_navigation_bar.xml
+++ b/indra/newview/skins/default/xui/fr/panel_navigation_bar.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_nearby_chat.xml b/indra/newview/skins/default/xui/fr/panel_nearby_chat.xml
index b02e53269b..b02e53269b 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_nearby_chat.xml
+++ b/indra/newview/skins/default/xui/fr/panel_nearby_chat.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_nearby_chat_bar.xml b/indra/newview/skins/default/xui/fr/panel_nearby_chat_bar.xml
index 82cdf292ab..762dee01bb 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_nearby_chat_bar.xml
+++ b/indra/newview/skins/default/xui/fr/panel_nearby_chat_bar.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel name="chat_bar">
+<panel name="nearby_chat">
<line_editor label="Cliquer ici pour chatter." name="chat_box" tool_tip="Appuyer sur Entrée pour dire, Ctrl-Entrée pour crier"/>
<button name="show_nearby_chat" tool_tip="Affiche/Masque le journal de chats près de vous"/>
</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_nearby_media.xml b/indra/newview/skins/default/xui/fr/panel_nearby_media.xml
index 7b7b67041a..7b7b67041a 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_nearby_media.xml
+++ b/indra/newview/skins/default/xui/fr/panel_nearby_media.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_notifications_channel.xml b/indra/newview/skins/default/xui/fr/panel_notifications_channel.xml
index 110e017050..110e017050 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_notifications_channel.xml
+++ b/indra/newview/skins/default/xui/fr/panel_notifications_channel.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_notify_textbox.xml b/indra/newview/skins/default/xui/fr/panel_notify_textbox.xml
index 6ce09cde4b..6ce09cde4b 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_notify_textbox.xml
+++ b/indra/newview/skins/default/xui/fr/panel_notify_textbox.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_online_status_toast.xml b/indra/newview/skins/default/xui/fr/panel_online_status_toast.xml
index fdc489f375..fdc489f375 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_online_status_toast.xml
+++ b/indra/newview/skins/default/xui/fr/panel_online_status_toast.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_outbox_inventory.xml b/indra/newview/skins/default/xui/fr/panel_outbox_inventory.xml
index d947dbceb8..d947dbceb8 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_outbox_inventory.xml
+++ b/indra/newview/skins/default/xui/fr/panel_outbox_inventory.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_outfit_edit.xml b/indra/newview/skins/default/xui/fr/panel_outfit_edit.xml
index 39bc7ef8af..39bc7ef8af 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_outfit_edit.xml
+++ b/indra/newview/skins/default/xui/fr/panel_outfit_edit.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_outfits_inventory.xml b/indra/newview/skins/default/xui/fr/panel_outfits_inventory.xml
index 1bc553c8c0..1bc553c8c0 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_outfits_inventory.xml
+++ b/indra/newview/skins/default/xui/fr/panel_outfits_inventory.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_outfits_inventory_gear_default.xml b/indra/newview/skins/default/xui/fr/panel_outfits_inventory_gear_default.xml
index 4703559111..4703559111 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_outfits_inventory_gear_default.xml
+++ b/indra/newview/skins/default/xui/fr/panel_outfits_inventory_gear_default.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_outfits_list.xml b/indra/newview/skins/default/xui/fr/panel_outfits_list.xml
index 416353e1d4..416353e1d4 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_outfits_list.xml
+++ b/indra/newview/skins/default/xui/fr/panel_outfits_list.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_outfits_wearing.xml b/indra/newview/skins/default/xui/fr/panel_outfits_wearing.xml
index 874bab2daa..874bab2daa 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_outfits_wearing.xml
+++ b/indra/newview/skins/default/xui/fr/panel_outfits_wearing.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_people.xml b/indra/newview/skins/default/xui/fr/panel_people.xml
index f035853efc..e306a00183 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_people.xml
+++ b/indra/newview/skins/default/xui/fr/panel_people.xml
@@ -14,81 +14,56 @@ Pour rechercher des résidents avec qui passer du temps, utilisez [secondlife://
<string name="no_filtered_friends_msg">
Vous n&apos;avez pas trouvé ce que vous cherchiez ? Essayez [secondlife:///app/search/people/[SEARCH_TERM] Rechercher].
</string>
- <string name="people_filter_label" value="Filtrer les personnes"/>
- <string name="groups_filter_label" value="Filtrer les groupes"/>
<string name="no_filtered_groups_msg" value="Vous n&apos;avez pas trouvé ce que vous cherchiez ? Essayez [secondlife:///app/search/groups/[SEARCH_TERM] Rechercher]."/>
<string name="no_groups_msg" value="Vous souhaitez trouver des groupes à rejoindre ? Utilisez [secondlife:///app/search/groups Rechercher]."/>
<string name="MiniMapToolTipMsg" value="[REGION](Carte : double-clic ; Panoramique : Maj + faire glisser)"/>
<string name="AltMiniMapToolTipMsg" value="[REGION](Téléportation : double-clic ; Panoramique : Maj + faire glisser)"/>
- <filter_editor label="Filtre" name="filter_input"/>
<tab_container name="tabs">
<panel label="PRÈS DE VOUS" name="nearby_panel">
- <panel label="bottom_panel" name="bottom_panel">
- <menu_button name="nearby_view_sort_btn" tool_tip="Options"/>
- <button name="add_friend_btn" tool_tip="Ajouter le résident sélectionné à votre liste d&apos;amis"/>
+ <panel label="bottom_panel" name="nearby_buttons_panel">
+ <filter_editor label="Filtrer les personnes" name="nearby_filter_input"/>
+ <button name="gear_btn" tool_tip="Actions sur la personne sélectionnée"/>
+ <menu_button name="nearby_view_btn" tool_tip="Options d&apos;affichage/de tri"/>
+ <button name="add_friend_btn" tool_tip="Proposer à ce résident de devenir votre ami"/>
+ <dnd_button name="nearby_del_btn" tool_tip="Supprimer la personne sélectionnée des amis"/>
</panel>
</panel>
- <panel label="MES AMIS" name="friends_panel">
+ <panel label="AMIS" name="friends_panel">
+ <panel label="bottom_panel" name="friends_buttons_panel">
+ <filter_editor label="Filtrer les personnes" name="friends_filter_input"/>
+ <button name="gear_btn" tool_tip="Actions sur la personne sélectionnée"/>
+ <menu_button name="friends_view_btn" tool_tip="Options d&apos;affichage/de tri"/>
+ <button name="friends_add_btn" tool_tip="Proposer à ce résident de devenir votre ami"/>
+ <dnd_button name="friends_del_btn" tool_tip="Supprimer la personne sélectionnée des amis"/>
+ </panel>
<accordion name="friends_accordion">
<accordion_tab name="tab_online" title="En ligne"/>
<accordion_tab name="tab_all" title="Tout"/>
</accordion>
- <panel label="bottom_panel" name="bottom_panel">
- <layout_stack name="bottom_panel">
- <layout_panel name="options_gear_btn_panel">
- <menu_button name="friends_viewsort_btn" tool_tip="Afficher d&apos;autres options"/>
- </layout_panel>
- <layout_panel name="add_btn_panel">
- <button name="add_btn" tool_tip="Proposer à un résident de devenir votre ami"/>
- </layout_panel>
- <layout_panel name="trash_btn_panel">
- <dnd_button name="del_btn" tool_tip="Supprimer le résident sélectionné de votre liste d&apos;amis."/>
- </layout_panel>
- </layout_stack>
- </panel>
</panel>
- <panel label="MES GROUPES" name="groups_panel">
- <panel label="bottom_panel" name="bottom_panel">
- <menu_button name="groups_viewsort_btn" tool_tip="Options"/>
- <button name="plus_btn" tool_tip="Rejoindre/créer un nouveau groupe"/>
- <button name="activate_btn" tool_tip="Activer le groupe sélectionné"/>
+ <panel label="GROUPES" name="groups_panel">
+ <panel label="bottom_panel" name="groups_buttons_panel">
+ <filter_editor label="Filtrer les groupes" name="groups_filter_input"/>
+ <menu_button name="groups_gear_btn" tool_tip="Actions sur le groupe sélectionné"/>
+ <menu_button name="groups_view_btn" tool_tip="Options d&apos;affichage/de tri"/>
+ <menu_button name="plus_btn" tool_tip="Rejoindre/créer un nouveau groupe"/>
+ <dnd_button name="minus_btn" tool_tip="Quitter le groupe sélectionné"/>
</panel>
+ <text name="groupcount">
+ Vous appartenez à [COUNT] groupes, et pouvez en rejoindre [REMAINING] autres.
+ </text>
</panel>
<panel label="RÉCENT" name="recent_panel">
- <panel label="bottom_panel" name="bottom_panel">
- <menu_button name="recent_viewsort_btn" tool_tip="Options"/>
- <button name="add_friend_btn" tool_tip="Ajouter le résident sélectionné à votre liste d&apos;amis"/>
+ <panel label="bottom_panel" name="recent_buttons_panel">
+ <filter_editor label="Filtrer les personnes" name="recent_filter_input"/>
+ <button name="gear_btn" tool_tip="Actions sur la personne sélectionnée"/>
+ <menu_button name="recent_view_btn" tool_tip="Options d&apos;affichage/de tri"/>
+ <button name="add_friend_btn" tool_tip="Proposer à ce résident de devenir votre ami"/>
+ <dnd_button name="recent_del_btn" tool_tip="Supprimer la personne sélectionnée des amis"/>
</panel>
</panel>
+ <panel label="BLOQUÉ" name="blocked_panel">
+ <panel label="Résidents et objets ignorés" name="panel_block_list_sidetray"/>
+ </panel>
</tab_container>
- <panel name="button_bar">
- <layout_stack name="bottom_bar_ls">
- <layout_panel name="view_profile_btn_lp">
- <button label="Profil" name="view_profile_btn" tool_tip="Afficher la photo, les groupes et autres infos des résidents"/>
- </layout_panel>
- <layout_panel name="im_btn_lp">
- <button label="IM" name="im_btn" tool_tip="Ouvrir une session IM."/>
- </layout_panel>
- <layout_panel name="call_btn_lp">
- <button label="Appel" name="call_btn" tool_tip="Appeler ce résident."/>
- </layout_panel>
- <layout_panel name="share_btn_lp">
- <button label="Partager" name="share_btn" tool_tip="Partager un article de l&apos;inventaire."/>
- </layout_panel>
- <layout_panel name="teleport_btn_lp">
- <button label="Téléporter" name="teleport_btn" tool_tip="Proposer une téléportation."/>
- </layout_panel>
- </layout_stack>
- <layout_stack name="bottom_bar_ls1">
- <layout_panel name="group_info_btn_lp">
- <button label="Profil du groupe" name="group_info_btn" tool_tip="Afficher les informations sur le groupe"/>
- </layout_panel>
- <layout_panel name="chat_btn_lp">
- <button label="Chat de groupe" name="chat_btn" tool_tip="Ouvrir une session de chat"/>
- </layout_panel>
- <layout_panel name="group_call_btn_lp">
- <button label="Appel de groupe" name="group_call_btn" tool_tip="Appeler ce groupe"/>
- </layout_panel>
- </layout_stack>
- </panel>
</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_pick_info.xml b/indra/newview/skins/default/xui/fr/panel_pick_info.xml
index 1de9b243f1..1de9b243f1 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_pick_info.xml
+++ b/indra/newview/skins/default/xui/fr/panel_pick_info.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_picks.xml b/indra/newview/skins/default/xui/fr/panel_picks.xml
index fb277f653f..fb277f653f 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_picks.xml
+++ b/indra/newview/skins/default/xui/fr/panel_picks.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_place_profile.xml b/indra/newview/skins/default/xui/fr/panel_place_profile.xml
index 30be838896..30be838896 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_place_profile.xml
+++ b/indra/newview/skins/default/xui/fr/panel_place_profile.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_places.xml b/indra/newview/skins/default/xui/fr/panel_places.xml
index 5ec48c44c7..5ec48c44c7 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_places.xml
+++ b/indra/newview/skins/default/xui/fr/panel_places.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_postcard_message.xml b/indra/newview/skins/default/xui/fr/panel_postcard_message.xml
index 0f8397cfb4..0f8397cfb4 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_postcard_message.xml
+++ b/indra/newview/skins/default/xui/fr/panel_postcard_message.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_postcard_settings.xml b/indra/newview/skins/default/xui/fr/panel_postcard_settings.xml
index 6f4e9c23f9..945a5e0272 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_postcard_settings.xml
+++ b/indra/newview/skins/default/xui/fr/panel_postcard_settings.xml
@@ -9,12 +9,12 @@
</combo_box>
<layout_stack name="postcard_image_params_ls">
<layout_panel name="postcard_image_size_lp">
- <spinner label="Largeur" name="postcard_snapshot_width"/>
- <spinner label="Hauteur" name="postcard_snapshot_height"/>
+ <spinner label="Larg." name="postcard_snapshot_width"/>
+ <spinner label="Haut." name="postcard_snapshot_height"/>
<check_box label="Conserver les proportions" name="postcard_keep_aspect_check"/>
</layout_panel>
<layout_panel name="postcard_image_format_quality_lp">
- <slider label="Qualité de l&apos;image" name="image_quality_slider"/>
+ <slider label="Qualité image" name="image_quality_slider"/>
<text name="image_quality_level">
([QLVL])
</text>
diff --git a/indra/newview/skins/default/xui/fr/panel_preferences_advanced.xml b/indra/newview/skins/default/xui/fr/panel_preferences_advanced.xml
index 3f3d0f51f4..3f3d0f51f4 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_preferences_advanced.xml
+++ b/indra/newview/skins/default/xui/fr/panel_preferences_advanced.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_preferences_alerts.xml b/indra/newview/skins/default/xui/fr/panel_preferences_alerts.xml
index 901a92ed1b..901a92ed1b 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_preferences_alerts.xml
+++ b/indra/newview/skins/default/xui/fr/panel_preferences_alerts.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_preferences_chat.xml b/indra/newview/skins/default/xui/fr/panel_preferences_chat.xml
index 76ed237451..52c6ed24b9 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/fr/panel_preferences_chat.xml
@@ -1,33 +1,99 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel label="Chat écrit" name="chat">
- <text name="font_size">
- Taille de la police :
- </text>
- <radio_group name="chat_font_size">
- <radio_item label="Petite" name="radio" value="0"/>
- <radio_item label="Moyenne" name="radio2" value="1"/>
- <radio_item label="Grande" name="radio3" value="2"/>
- </radio_group>
- <check_box initial_value="true" label="Exécuter l&apos;animation clavier quand vous écrivez" name="play_typing_animation"/>
- <check_box label="M&apos;envoyer les IM par e-mail une fois déconnecté" name="send_im_to_email"/>
- <check_box label="Activer l&apos;historique des chats et des IM en texte brut" name="plain_text_chat_history"/>
- <check_box label="Bulles de chat" name="bubble_text_chat"/>
- <text name="show_ims_in_label">
- Afficher les IM dans :
- </text>
- <text name="requires_restart_label">
- (redémarrage requis)
- </text>
- <radio_group name="chat_window" tool_tip="Afficher vos messages instantanés dans plusieurs fenêtres ou dans une seule fenêtre avec plusieurs onglets (redémarrage requis)">
- <radio_item label="Plusieurs fenêtres" name="radio" value="0"/>
- <radio_item label="Onglets" name="radio2" value="1"/>
- </radio_group>
- <text name="disable_toast_label">
- Activer les popups de chat entrant :
- </text>
- <check_box label="Chats de groupe" name="EnableGroupChatPopups" tool_tip="Cocher cette case pour qu&apos;un popup s&apos;affiche à réception d&apos;un message de chat de groupe."/>
- <check_box label="Chats IM" name="EnableIMChatPopups" tool_tip="Cocher cette case pour qu&apos;un popup s&apos;affiche à réception d&apos;un message instantané."/>
- <spinner label="Durée de vie du popup Chat près de moi :" name="nearby_toasts_lifetime"/>
- <spinner label="Disparition progressive du popup Chat près de moi :" name="nearby_toasts_fadingtime"/>
- <button label="Traduction automatique" name="ok_btn"/>
+ <panel name="general_chat_settings">
+ <check_box initial_value="true" label="Exécuter l&apos;animation clavier quand vous écrivez" name="play_typing_animation"/>
+ <check_box label="M&apos;envoyer les IM par e-mail une fois déconnecté" name="send_im_to_email"/>
+ <check_box label="Seuls mes amis et groupes peuvent m&apos;appeler ou m&apos;envoyer un IM" name="voice_call_friends_only_check"/>
+ <text name="font_size">
+ Taille de la police :
+ </text>
+ <combo_box name="chat_font_size">
+ <item label="Petite" name="Small" value="0"/>
+ <item label="Moyenne" name="Medium" value="1"/>
+ <item label="Grande" name="Large" value="2"/>
+ </combo_box>
+ <check_box label="Bulles de chat" name="bubble_text_chat"/>
+ </panel>
+ <panel name="im_notification_settings">
+ <text name="friend_ims">
+ IM amis :
+ </text>
+ <combo_box name="FriendIMOptions">
+ <item label="Ouvrir la fenêtre Conversation" name="OpenConversationsWindow" value="openconversations"/>
+ <item label="Afficher le message dans une fenêtre popup" name="PopUpMessage" value="toast"/>
+ <item label="Bouton de la barre d&apos;outils Flash" name="FlashToolbarButton" value="flash"/>
+ <item label="Aucune action" name="NoAction" value="noaction"/>
+ </combo_box>
+ <check_box label="Écouter le son" name="play_sound_friend_im"/>
+ <text name="non_friend_ims">
+ IM non amis :
+ </text>
+ <combo_box name="NonFriendIMOptions">
+ <item label="Ouvrir la fenêtre Conversation" name="OpenConversationsWindow" value="openconversations"/>
+ <item label="Afficher le message dans une fenêtre popup" name="PopUpMessage" value="toast"/>
+ <item label="Bouton de la barre d&apos;outils Flash" name="FlashToolbarButton" value="flash"/>
+ <item label="Aucune action" name="NoAction" value="noaction"/>
+ </combo_box>
+ <check_box label="Écouter le son" name="play_sound_non_friend_im"/>
+ <text name="conference_ims">
+ IM conférence :
+ </text>
+ <combo_box name="ConferenceIMOptions">
+ <item label="Ouvrir la fenêtre Conversation" name="OpenConversationsWindow" value="openconversations"/>
+ <item label="Afficher le message dans une fenêtre popup" name="PopUpMessage" value="toast"/>
+ <item label="Bouton de la barre d&apos;outils Flash" name="FlashToolbarButton" value="flash"/>
+ <item label="Aucune action" name="NoAction" value="noaction"/>
+ </combo_box>
+ <check_box label="Écouter le son" name="play_sound_conference_im"/>
+ <text name="group_chat">
+ Chat de groupe :
+ </text>
+ <combo_box name="GroupChatOptions">
+ <item label="Ouvrir la fenêtre Conversation" name="OpenConversationsWindow" value="openconversations"/>
+ <item label="Afficher le message dans une fenêtre popup" name="PopUpMessage" value="toast"/>
+ <item label="Bouton de la barre d&apos;outils Flash" name="FlashToolbarButton" value="flash"/>
+ <item label="Aucune action" name="NoAction" value="noaction"/>
+ </combo_box>
+ <check_box label="Écouter le son" name="play_sound_group_chat_im"/>
+ <text name="nearby_chat">
+ Chat près de moi :
+ </text>
+ <combo_box name="NearbyChatOptions">
+ <item label="Ouvrir la fenêtre Conversation" name="OpenConversationsWindow" value="openconversations"/>
+ <item label="Afficher le message dans une fenêtre popup" name="PopUpMessage" value="toast"/>
+ <item label="Bouton de la barre d&apos;outils Flash" name="FlashToolBarButton" value="flash"/>
+ <item label="Aucune action" name="NoAction" value="noaction"/>
+ </combo_box>
+ <check_box label="Écouter le son" name="play_sound_nearby_chat_im"/>
+ <text name="object_ims">
+ IM objet :
+ </text>
+ <combo_box name="ObjectIMOptions">
+ <item label="Ouvrir la fenêtre Conversation" name="OpenConversationsWindow" value="openconversations"/>
+ <item label="Afficher le message dans une fenêtre popup" name="PopUpMessage" value="toast"/>
+ <item label="Bouton de la barre d&apos;outils Flash" name="FlashToolBarButton" value="flash"/>
+ <item label="Aucune action" name="NoAction" value="noaction"/>
+ </combo_box>
+ <check_box label="Écouter le son" name="play_sound_object_im"/>
+ <text name="notifications_alert">
+ Pour suspendre temporairement toutes les notifications, utilisez Communication &gt; Ne pas déranger.
+ </text>
+ </panel>
+ <panel name="play_sound_settings">
+ <text name="play_sound">
+ Écouter le son :
+ </text>
+ <check_box label="Nouvelle conversation" name="new_conversation"/>
+ <check_box label="Appel entrant" name="incoming_voice_call"/>
+ <check_box label="Offre de téléportation" name="teleport_offer"/>
+ <check_box label="Offre d&apos;inventaire" name="inventory_offer"/>
+ </panel>
+ <panel name="log_settings">
+ <button label="Effacer le journal..." name="clear_log"/>
+ <button label="Supprimer les transcriptions..." name="delete_transcripts"/>
+ <button label="Parcourir..." label_selected="Parcourir" name="log_path_button"/>
+ </panel>
+ <button label="Traduction..." name="ok_btn"/>
+ <button label="Rechercher/Remplacer..." name="autoreplace_showgui"/>
+ <button label="Orthographe..." name="spellcheck_showgui"/>
</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_preferences_colors.xml b/indra/newview/skins/default/xui/fr/panel_preferences_colors.xml
index e50fd2b6f3..e50fd2b6f3 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_preferences_colors.xml
+++ b/indra/newview/skins/default/xui/fr/panel_preferences_colors.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_preferences_general.xml b/indra/newview/skins/default/xui/fr/panel_preferences_general.xml
index 66b84af3aa..533c392d6b 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_preferences_general.xml
+++ b/indra/newview/skins/default/xui/fr/panel_preferences_general.xml
@@ -69,9 +69,9 @@
<combo_box.item label="Jamais" name="item4"/>
</combo_box>
<text name="text_box3">
- Réponse si occupé(e) :
+ Réponse Ne pas déranger
</text>
- <text_editor name="busy_response">
+ <text_editor name="do_not_disturb_response">
log_in_to_change
</text_editor>
</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/fr/panel_preferences_graphics1.xml
index a738b2d43f..4946b09814 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_preferences_graphics1.xml
+++ b/indra/newview/skins/default/xui/fr/panel_preferences_graphics1.xml
@@ -30,7 +30,7 @@
<check_box initial_value="true" label="Lumières locales" name="LocalLights"/>
<check_box initial_value="true" label="Effets de base" name="BasicShaders" tool_tip="La désactivation de cette option peut éviter le plantage de certains pilotes de cartes graphiques"/>
<check_box initial_value="true" label="Effets atmosphériques" name="WindLightUseAtmosShaders"/>
- <check_box initial_value="true" label="Éclairage et ombres" name="UseLightShaders"/>
+ <check_box initial_value="true" label="Modèle d&apos;éclairage avancé" name="UseLightShaders"/>
<check_box initial_value="true" label="Occlusion ambiante" name="UseSSAO"/>
<check_box initial_value="true" label="Profondeur de champ" name="UseDoF"/>
<text name="shadows_label">
diff --git a/indra/newview/skins/default/xui/fr/panel_preferences_move.xml b/indra/newview/skins/default/xui/fr/panel_preferences_move.xml
index 94d7322b22..80aed90a2d 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_preferences_move.xml
+++ b/indra/newview/skins/default/xui/fr/panel_preferences_move.xml
@@ -28,7 +28,7 @@
<combo_box.item label="Déplacement vers le clic" name="1"/>
</combo_box>
<text name="double_click_action_lbl">
- Double-clic sur le terrain :
+ Double clic sur le terrain :
</text>
<combo_box name="double_click_action_combo">
<combo_box.item label="Aucune action" name="0"/>
diff --git a/indra/newview/skins/default/xui/fr/panel_preferences_privacy.xml b/indra/newview/skins/default/xui/fr/panel_preferences_privacy.xml
index cf1a374da6..cf1a374da6 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_preferences_privacy.xml
+++ b/indra/newview/skins/default/xui/fr/panel_preferences_privacy.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_preferences_setup.xml b/indra/newview/skins/default/xui/fr/panel_preferences_setup.xml
index 83303950dc..50f4a49bd0 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_preferences_setup.xml
+++ b/indra/newview/skins/default/xui/fr/panel_preferences_setup.xml
@@ -29,6 +29,7 @@
<combo_box.item label="Installation automatique" name="Install_automatically"/>
<combo_box.item label="Téléchargement et installation manuels" name="Install_manual"/>
</combo_box>
+ <check_box label="Accepte de passer aux versions avant sortie officielle" name="update_willing_to_test"/>
<text name="Proxy Settings:">
Paramètres de proxy :
</text>
diff --git a/indra/newview/skins/default/xui/fr/panel_preferences_sound.xml b/indra/newview/skins/default/xui/fr/panel_preferences_sound.xml
index 37eb6bbeb0..37eb6bbeb0 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_preferences_sound.xml
+++ b/indra/newview/skins/default/xui/fr/panel_preferences_sound.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_prim_media_controls.xml b/indra/newview/skins/default/xui/fr/panel_prim_media_controls.xml
index ad744b7760..ad744b7760 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_prim_media_controls.xml
+++ b/indra/newview/skins/default/xui/fr/panel_prim_media_controls.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_region_covenant.xml b/indra/newview/skins/default/xui/fr/panel_region_covenant.xml
index a30306d116..a30306d116 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_region_covenant.xml
+++ b/indra/newview/skins/default/xui/fr/panel_region_covenant.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_region_debug.xml b/indra/newview/skins/default/xui/fr/panel_region_debug.xml
index 733c3f9a22..98ae250215 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_region_debug.xml
+++ b/indra/newview/skins/default/xui/fr/panel_region_debug.xml
@@ -30,11 +30,11 @@
<check_box label="Sur le terrain d&apos;un autre résident" name="return_other_land" tool_tip="Ne renvoyer que les objets se trouvant sur le terrain de quelqu&apos;un d&apos;autre"/>
<check_box label="Dans toutes les régions de ce domaine" name="return_estate_wide" tool_tip="Renvoyer les objets dans toutes les régions qui constituent ce domaine"/>
<button label="Renvoyer" name="return_btn"/>
- <button label="Afficher les collisions les plus consommatrices..." name="top_colliders_btn" tool_tip="Liste des objets avec le plus de collisions potentielles" width="320"/>
+ <button label="Collisions les plus consommatrices" name="top_colliders_btn" tool_tip="Liste des objets avec le plus de collisions potentielles" width="320"/>
<button label="?" left="337" name="top_colliders_help"/>
- <button label="Afficher les objets scriptés les plus consommateurs..." name="top_scripts_btn" tool_tip="Liste des objets qui passent le plus de temps à exécuter des scripts" width="320"/>
+ <button label="Scripts les plus consommateurs" name="top_scripts_btn" tool_tip="Liste des objets passant le plus de temps à exécuter des scripts" width="320"/>
<button label="?" left="337" name="top_scripts_help"/>
<button label="Redémarrer la région" name="restart_btn" tool_tip="Redémarrer la région au bout de 2 minutes" width="160"/>
<button label="?" left="177" name="restart_help"/>
- <button label="Retarder le redémarrage" name="cancel_restart_btn" tool_tip="Retarder le redémarrage de la région d&apos;une heure" width="160"/>
+ <button label="Annuler le redémarrage" name="cancel_restart_btn" tool_tip="Annuler le redémarrage de la région." width="160"/>
</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_region_environment.xml b/indra/newview/skins/default/xui/fr/panel_region_environment.xml
index d18503db86..085a308786 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_region_environment.xml
+++ b/indra/newview/skins/default/xui/fr/panel_region_environment.xml
@@ -15,7 +15,7 @@
<combo_box.item label="-Effectuer une sélection-" name="item0"/>
</combo_box>
<text name="sky_dayc_settings_title">
- Ciel / Cycle du jour
+ Ciel/Cycle du jour
</text>
<radio_group name="sky_dayc_settings_radio_group">
<radio_item label="Ciel fixe" name="my_sky_settings"/>
diff --git a/indra/newview/skins/default/xui/fr/panel_region_estate.xml b/indra/newview/skins/default/xui/fr/panel_region_estate.xml
index 9d97d1bf29..be89020ac7 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_region_estate.xml
+++ b/indra/newview/skins/default/xui/fr/panel_region_estate.xml
@@ -21,7 +21,7 @@ domaine.
Conditions d&apos;accès des résidents :
</text>
<check_box label="Informations de paiement enregistrées" name="limit_payment" tool_tip="Pour pouvoir accéder à ce domaine, les résidents doivent avoir enregistré des informations de paiement. Consultez le [SUPPORT_SITE] pour plus d&apos;informations."/>
- <check_box label="Âge vérifié" name="limit_age_verified" tool_tip="Pour que les résidents puissent accéder à ce domaine, leur âge doit avoir fait l&apos;objet d&apos;une vérification. Consultez le [SUPPORT_SITE] pour plus d&apos;informations."/>
+ <check_box label="Avoir plus de 18 ans" name="limit_age_verified" tool_tip="Pour accéder à ce domaine, les résidents doivent avoir au moins 18 ans. Consultez le [SUPPORT_SITE] pour plus d&apos;informations."/>
<check_box label="Autoriser les chats vocaux" name="voice_chat_check"/>
<button label="?" name="voice_chat_help"/>
<text name="abuse_email_text">
diff --git a/indra/newview/skins/default/xui/fr/panel_region_general.xml b/indra/newview/skins/default/xui/fr/panel_region_general.xml
index b5795bebe2..234d316069 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_region_general.xml
+++ b/indra/newview/skins/default/xui/fr/panel_region_general.xml
@@ -22,7 +22,7 @@
<check_box label="Interdire le vol" name="block_fly_check"/>
<check_box label="Autoriser les dégâts" name="allow_damage_check"/>
<check_box label="Interdire les bousculades" name="restrict_pushobject"/>
- <check_box label="Autoriser la revente" name="allow_land_resell_check"/>
+ <check_box label="Autoriser la revente de terrain" name="allow_land_resell_check"/>
<check_box label="Autoriser la fusion/division" name="allow_parcel_changes_check"/>
<check_box label="Ne pas afficher dans la recherche" name="block_parcel_search_check" tool_tip="Afficher cette région et ses parcelles dans les résultats de recherche"/>
<check_box label="Autoriser les objets de maillage" name="mesh_rez_enabled_check" tool_tip="Laisser les gens rezzer des objets de maillage dans cette région."/>
diff --git a/indra/newview/skins/default/xui/fr/panel_region_terrain.xml b/indra/newview/skins/default/xui/fr/panel_region_terrain.xml
index d7e321d06d..97f486d3a3 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_region_terrain.xml
+++ b/indra/newview/skins/default/xui/fr/panel_region_terrain.xml
@@ -55,8 +55,8 @@ du terrain" name="terrain_lower_spin"/>
<spinner label="Bas" name="height_start_spin_2"/>
<spinner label="Haut" name="height_range_spin_0"/>
<spinner label="Haut" name="height_range_spin_2"/>
- <button label="Télécharger le terrain au format RAW..." name="download_raw_btn" tool_tip="Réservé aux propriétaires de domaine, pas aux gérants" width="230"/>
- <button label="Charger le terrain au format RAW..." name="upload_raw_btn" tool_tip="Réservé aux propriétaires de domaine, pas aux gérants" width="230"/>
+ <button label="Télécharger le terrain en RAW..." name="download_raw_btn" tool_tip="Réservé aux propriétaires de domaine, pas aux gérants" width="230"/>
+ <button label="Charger un terrain en RAW..." name="upload_raw_btn" tool_tip="Réservé aux propriétaires de domaine, pas aux gérants" width="230"/>
<button label="Figer le terrain" name="bake_terrain_btn" tool_tip="Définir le terrain actuel comme point central pour les limites d&apos;élévation/abaissement"/>
<button label="Appliquer" name="apply_btn"/>
</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_region_texture.xml b/indra/newview/skins/default/xui/fr/panel_region_texture.xml
deleted file mode 100644
index c0b667137a..0000000000
--- a/indra/newview/skins/default/xui/fr/panel_region_texture.xml
+++ /dev/null
@@ -1,72 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel label="Textures du sol" name="Textures">
- <text name="region_text_lbl">
- Région :
- </text>
- <text name="region_text">
- (inconnue)
- </text>
- <text name="base_texture_text">
- Textures de base (fichiers 128x128, 24 bit .tga)
- </text>
- <text name="height_text_lbl">
- 1 (faible)
- </text>
- <text name="height_text_lbl2">
- 2
- </text>
- <text name="height_text_lbl3">
- 3
- </text>
- <text name="height_text_lbl4">
- 4 (élevé)
- </text>
- <text name="detail_texture_text">
- Textures du terrain (fichiers.tga 512 x 512, 24 bit requis)
- </text>
- <text name="height_text_lbl5">
- Limites d&apos;élévation de texture
- </text>
- <text name="height_text_lbl6">
- Nord-ouest
- </text>
- <text name="height_text_lbl7">
- Nord-est
- </text>
- <text name="height_text_lbl8">
- Sud-ouest
- </text>
- <text name="height_text_lbl9">
- Sud-est
- </text>
- <text name="height_text_lbl10" width="460">
- Ces valeurs représentent les limites de mélange pour les textures ci-dessus.
- </text>
- <text name="height_text_lbl11">
- En mètres, la valeur Bas correspond à la hauteur max. de la texture n°1
- </text>
- <text name="height_text_lbl12">
- et la valeur Haut correspond à la hauteur min. de la texture n°4.
- </text>
- <text name="height_text_lbl13">
- Nord-est
- </text>
- <spinner label="Bas" name="height_start_spin_0"/>
- <spinner label="Bas" name="height_start_spin_1"/>
- <spinner label="Bas" name="height_start_spin_2"/>
- <spinner label="Bas" name="height_start_spin_3"/>
- <spinner label="Haut" name="height_range_spin_0"/>
- <spinner label="Haut" name="height_range_spin_1"/>
- <spinner label="Haut" name="height_range_spin_2"/>
- <spinner label="Haut" name="height_range_spin_3"/>
- <text name="height_text_lbl14">
- Ces valeurs représentent les limites de mélange pour les textures ci-dessus.
- </text>
- <text name="height_text_lbl15">
- La valeur Bas correspond à la hauteur max. de la Texture 1,
- </text>
- <text name="height_text_lbl16">
- et la valeur Haut correspond à la hauteur min. de la Texture 4.
- </text>
- <button label="Appliquer" name="apply_btn"/>
-</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_script_ed.xml b/indra/newview/skins/default/xui/fr/panel_script_ed.xml
index 29fbe3c7e7..38e5cbe1f1 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_script_ed.xml
+++ b/indra/newview/skins/default/xui/fr/panel_script_ed.xml
@@ -34,6 +34,7 @@
<menu_item_call label="Tout sélectionner" name="Select All"/>
<menu_item_call label="Désélectionner" name="Deselect"/>
<menu_item_call label="Rechercher / Remplacer..." name="Search / Replace..."/>
+ <menu_item_call label="Aller à la ligne..." name="Go to line..."/>
</menu>
<menu label="Aide" name="Help">
<menu_item_call label="Aide..." name="Help..."/>
diff --git a/indra/newview/skins/default/xui/fr/panel_script_limits_my_avatar.xml b/indra/newview/skins/default/xui/fr/panel_script_limits_my_avatar.xml
index e541fae31f..e541fae31f 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_script_limits_my_avatar.xml
+++ b/indra/newview/skins/default/xui/fr/panel_script_limits_my_avatar.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_script_limits_region_memory.xml b/indra/newview/skins/default/xui/fr/panel_script_limits_region_memory.xml
index 751abd6f1d..751abd6f1d 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_script_limits_region_memory.xml
+++ b/indra/newview/skins/default/xui/fr/panel_script_limits_region_memory.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_script_question_toast.xml b/indra/newview/skins/default/xui/fr/panel_script_question_toast.xml
new file mode 100755
index 0000000000..a2d0237da0
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/panel_script_question_toast.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<panel label="script_question_panel" name="panel_script_question_toast">
+ <panel label="buttons_panel" name="buttons_panel"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_scrolling_param.xml b/indra/newview/skins/default/xui/fr/panel_scrolling_param.xml
index 8febdccbed..8febdccbed 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_scrolling_param.xml
+++ b/indra/newview/skins/default/xui/fr/panel_scrolling_param.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_scrolling_param_base.xml b/indra/newview/skins/default/xui/fr/panel_scrolling_param_base.xml
index fa659040ea..fa659040ea 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_scrolling_param_base.xml
+++ b/indra/newview/skins/default/xui/fr/panel_scrolling_param_base.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_side_tray.xml b/indra/newview/skins/default/xui/fr/panel_side_tray.xml
deleted file mode 100644
index 178ae4324b..0000000000
--- a/indra/newview/skins/default/xui/fr/panel_side_tray.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<!-- Side tray cannot show background because it is always
- partially on screen to hold tab buttons. -->
-<side_tray name="sidebar">
- <sidetray_tab description="Activer/désactiver le panneau latéral." name="sidebar_openclose" tab_title="Activer/désactiver le panneau latéral"/>
- <sidetray_tab description="Domicile." name="sidebar_home" tab_title="Accueil">
- <panel label="domicile" name="panel_home"/>
- </sidetray_tab>
- <sidetray_tab description="Modifiez votre profil public et vos Favoris." name="sidebar_me" tab_title="Mon profil">
- <panel_container name="panel_container">
- <panel label="Moi" name="panel_me"/>
- </panel_container>
- </sidetray_tab>
- <sidetray_tab description="Trouvez vos amis, vos contacts et les personnes se trouvant près de vous." name="sidebar_people" tab_title="Personnes">
- <panel_container name="panel_container">
- <panel label="Profil du groupe" name="panel_group_info_sidetray"/>
- <panel label="Résidents et objets ignorés" name="panel_block_list_sidetray"/>
- </panel_container>
- </sidetray_tab>
- <sidetray_tab description="Trouvez de nouveaux lieux à découvrir et les lieux que vous connaissez déjà." label="Lieux" name="sidebar_places" tab_title="Endroits">
- <panel label="Lieux" name="panel_places"/>
- </sidetray_tab>
- <sidetray_tab description="Parcourez votre inventaire." name="sidebar_inventory" tab_title="Mon inventaire">
- <panel label="Modifier l&apos;inventaire" name="sidepanel_inventory"/>
- </sidetray_tab>
- <sidetray_tab description="Modifiez votre apparence actuelle." name="sidebar_appearance" tab_title="Mon apparence">
- <panel label="Changer d&apos;apparence" name="sidepanel_appearance"/>
- </sidetray_tab>
-</side_tray>
diff --git a/indra/newview/skins/default/xui/fr/panel_side_tray_tab_caption.xml b/indra/newview/skins/default/xui/fr/panel_side_tray_tab_caption.xml
index 45efbdc980..45efbdc980 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_side_tray_tab_caption.xml
+++ b/indra/newview/skins/default/xui/fr/panel_side_tray_tab_caption.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_sidetray_home_tab.xml b/indra/newview/skins/default/xui/fr/panel_sidetray_home_tab.xml
index 48bcff1c09..48bcff1c09 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_sidetray_home_tab.xml
+++ b/indra/newview/skins/default/xui/fr/panel_sidetray_home_tab.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_snapshot_inventory.xml b/indra/newview/skins/default/xui/fr/panel_snapshot_inventory.xml
index 4454d2475e..472c4a5e8f 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_snapshot_inventory.xml
+++ b/indra/newview/skins/default/xui/fr/panel_snapshot_inventory.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel name="panel_snapshot_inventory">
<text name="title">
- Enregistrer dans mon inventaire
+ Enregistrer dans l&apos;inventaire
</text>
<text name="hint_lbl">
- L&apos;enregistrement d&apos;une image dans votre inventaire coûte [UPLOAD_COST] L$. Pour enregistrer votre image sous forme de texture, sélectionnez l&apos;un des formats carrés.
+ L&apos;enregistrement d&apos;une image dans l&apos;inventaire coûte [UPLOAD_COST] L$. Pour enregistrer votre image sous forme de texture, sélectionnez un format carré.
</text>
<combo_box label="Résolution" name="texture_size_combo">
<combo_box.item label="Fenêtre actuelle" name="CurrentWindow"/>
diff --git a/indra/newview/skins/default/xui/fr/panel_snapshot_local.xml b/indra/newview/skins/default/xui/fr/panel_snapshot_local.xml
index 41264521fd..97dc3e7e2b 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_snapshot_local.xml
+++ b/indra/newview/skins/default/xui/fr/panel_snapshot_local.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel name="panel_snapshot_local">
<text name="title">
- Enregistrer sur mon ordinateur
+ Enregistrer sur l&apos;ordinateur
</text>
<combo_box label="Résolution" name="local_size_combo">
<combo_box.item label="Fenêtre actuelle" name="CurrentWindow"/>
@@ -25,7 +25,7 @@
<combo_box.item label="JPEG" name="JPEG"/>
<combo_box.item label="BMP (sans perte)" name="BMP"/>
</combo_box>
- <slider label="Qualité de l&apos;image" name="image_quality_slider"/>
+ <slider label="Qualité image" name="image_quality_slider"/>
<text name="image_quality_level">
([QLVL])
</text>
diff --git a/indra/newview/skins/default/xui/fr/panel_snapshot_options.xml b/indra/newview/skins/default/xui/fr/panel_snapshot_options.xml
index db3fcbeac9..befe1b3bc6 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_snapshot_options.xml
+++ b/indra/newview/skins/default/xui/fr/panel_snapshot_options.xml
@@ -2,6 +2,6 @@
<panel name="panel_snapshot_options">
<button label="Publier sur le flux de mon profil" name="save_to_profile_btn"/>
<button label="Envoyer par e-mail" name="save_to_email_btn"/>
- <button label="Enregistrer dans mon inventaire ([AMOUNT] L$)" name="save_to_inventory_btn"/>
- <button label="Enregistrer sur mon ordinateur" name="save_to_computer_btn"/>
+ <button label="Enreg. dans l&apos;inventaire ([AMOUNT] L$)" name="save_to_inventory_btn"/>
+ <button label="Enreg. sur l&apos;ordinateur" name="save_to_computer_btn"/>
</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_snapshot_postcard.xml b/indra/newview/skins/default/xui/fr/panel_snapshot_postcard.xml
index bb23b52850..82a4815144 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_snapshot_postcard.xml
+++ b/indra/newview/skins/default/xui/fr/panel_snapshot_postcard.xml
@@ -10,7 +10,7 @@
Envoi en cours...
</string>
<text name="title">
- Envoyer par e-mail
+ E-mail
</text>
<button label="Message" name="message_btn"/>
<button label="Paramètres" name="settings_btn"/>
diff --git a/indra/newview/skins/default/xui/fr/panel_snapshot_profile.xml b/indra/newview/skins/default/xui/fr/panel_snapshot_profile.xml
index 427ffe2113..427ffe2113 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_snapshot_profile.xml
+++ b/indra/newview/skins/default/xui/fr/panel_snapshot_profile.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_sound_devices.xml b/indra/newview/skins/default/xui/fr/panel_sound_devices.xml
index 460b269f7c..460b269f7c 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_sound_devices.xml
+++ b/indra/newview/skins/default/xui/fr/panel_sound_devices.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_stand_stop_flying.xml b/indra/newview/skins/default/xui/fr/panel_stand_stop_flying.xml
index ee4e8a6be6..ee4e8a6be6 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_stand_stop_flying.xml
+++ b/indra/newview/skins/default/xui/fr/panel_stand_stop_flying.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_status_bar.xml b/indra/newview/skins/default/xui/fr/panel_status_bar.xml
index ba36a7d299..ba36a7d299 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_status_bar.xml
+++ b/indra/newview/skins/default/xui/fr/panel_status_bar.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_sys_well_item.xml b/indra/newview/skins/default/xui/fr/panel_sys_well_item.xml
index 81db7c8989..81db7c8989 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_sys_well_item.xml
+++ b/indra/newview/skins/default/xui/fr/panel_sys_well_item.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_teleport_history.xml b/indra/newview/skins/default/xui/fr/panel_teleport_history.xml
index cf1266a460..cf1266a460 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_teleport_history.xml
+++ b/indra/newview/skins/default/xui/fr/panel_teleport_history.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_teleport_history_item.xml b/indra/newview/skins/default/xui/fr/panel_teleport_history_item.xml
index 21eb7ff62c..21eb7ff62c 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_teleport_history_item.xml
+++ b/indra/newview/skins/default/xui/fr/panel_teleport_history_item.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_tools_texture.xml b/indra/newview/skins/default/xui/fr/panel_tools_texture.xml
new file mode 100644
index 0000000000..c69cb61a92
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/panel_tools_texture.xml
@@ -0,0 +1,116 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Texture" name="Texture">
+ <panel.string name="string repeats per meter">
+ Répétitions au mètre
+ </panel.string>
+ <panel.string name="string repeats per face">
+ Répétitions par face
+ </panel.string>
+ <text name="color label">
+ Couleur
+ </text>
+ <color_swatch label="" name="colorswatch" tool_tip="Cliquez pour ouvrir le sélecteur de couleurs"/>
+ <text name="color trans">
+ % de transparence
+ </text>
+ <text name="glow label">
+ Rayonnement
+ </text>
+ <check_box label="Lumineux" name="checkbox fullbright"/>
+ <combo_box name="combobox matmedia">
+ <combo_box.item label="Matériaux" name="Materials"/>
+ <combo_box.item label="Médias" name="Media"/>
+ </combo_box>
+ <combo_box name="combobox mattype">
+ <combo_box.item label="Texture (diffuse)" name="Texture (diffuse)"/>
+ <combo_box.item label="Relief (normal)" name="Bumpiness (normal)"/>
+ <combo_box.item label="Brillance (spéculaire)" name="Shininess (specular)"/>
+ </combo_box>
+ <texture_picker label="Texture" name="texture control" tool_tip="Cliquer pour sélectionner une image."/>
+ <text name="label alphamode">
+ Mode alpha
+ </text>
+ <combo_box name="combobox alphamode">
+ <combo_box.item label="Aucun" name="None"/>
+ <combo_box.item label="Fusion alpha" name="Alpha blending"/>
+ <combo_box.item label="Masquage alpha" name="Alpha masking"/>
+ <combo_box.item label="Masque émissif" name="Emissive mask"/>
+ </combo_box>
+ <text name="label maskcutoff">
+ Coupe du masque
+ </text>
+ <texture_picker label="Texture" name="bumpytexture control" tool_tip="Cliquer pour sélectionner une image."/>
+ <text name="label bumpiness">
+ Relief
+ </text>
+ <combo_box name="combobox bumpiness">
+ <combo_box.item label="Aucun" name="None"/>
+ <combo_box.item label="Luminosité" name="Brightness"/>
+ <combo_box.item label="Obscurité" name="Darkness"/>
+ <combo_box.item label="aggloméré" name="woodgrain"/>
+ <combo_box.item label="écorce" name="bark"/>
+ <combo_box.item label="briques" name="bricks"/>
+ <combo_box.item label="damier" name="checker"/>
+ <combo_box.item label="béton" name="concrete"/>
+ <combo_box.item label="carrelage" name="crustytile"/>
+ <combo_box.item label="pierre de taille" name="cutstone"/>
+ <combo_box.item label="disques" name="discs"/>
+ <combo_box.item label="gravier" name="gravel"/>
+ <combo_box.item label="boîte de Petri" name="petridish"/>
+ <combo_box.item label="lattes" name="siding"/>
+ <combo_box.item label="carreaux" name="stonetile"/>
+ <combo_box.item label="stuc" name="stucco"/>
+ <combo_box.item label="ventouses" name="suction"/>
+ <combo_box.item label="tissage" name="weave"/>
+ </combo_box>
+ <texture_picker label="Texture" name="shinytexture control" tool_tip="Cliquer pour sélectionner une image."/>
+ <text name="label shininess">
+ Brillance
+ </text>
+ <combo_box name="combobox shininess">
+ <combo_box.item label="Aucune" name="None"/>
+ <combo_box.item label="Faible" name="Low"/>
+ <combo_box.item label="Moyenne" name="Medium"/>
+ <combo_box.item label="Élevée" name="High"/>
+ </combo_box>
+ <text name="label glossiness">
+ Lustrage
+ </text>
+ <text name="label environment">
+ Environnement
+ </text>
+ <text name="label shinycolor">
+ Couleur
+ </text>
+ <color_swatch label="" name="shinycolorswatch" tool_tip="Cliquez pour ouvrir le sélecteur de couleurs"/>
+ <text name="media_info">
+ L&apos;URL du média choisi, le cas échéant, se place ici.
+ </text>
+ <button label="Choisir..." name="add_media" tool_tip="Ajouter un média"/>
+ <button label="Supprimer" name="delete_media" tool_tip="Supprimer cette texture de média"/>
+ <button label="Aligner" label_selected="Aligner le média" name="button align" tool_tip="Ajuster la texture du média (le chargement doit d’abord se terminer)"/>
+ <text name="tex gen">
+ Application
+ </text>
+ <combo_box name="combobox texgen">
+ <combo_box.item label="Valeur par défaut" name="Default"/>
+ <combo_box.item label="Plan" name="Planar"/>
+ </combo_box>
+ <spinner label="Échelle horizontale" name="TexScaleU"/>
+ <spinner label="Échelle verticale" name="TexScaleV"/>
+ <spinner label="Répétitions au mètre" name="rptctrl"/>
+ <spinner label="Degrés de rotation" name="TexRot"/>
+ <spinner label="Décalage horizontal" name="TexOffsetU"/>
+ <spinner label="Décalage vertical" name="TexOffsetV"/>
+ <spinner label="Échelle horizontale" name="bumpyScaleU"/>
+ <spinner label="Échelle verticale" name="bumpyScaleV"/>
+ <spinner label="Degrés de rotation" name="bumpyRot"/>
+ <spinner label="Décalage horizontal" name="bumpyOffsetU"/>
+ <spinner label="Décalage vertical" name="bumpyOffsetV"/>
+ <spinner label="Échelle horizontale" name="shinyScaleU"/>
+ <spinner label="Échelle verticale" name="shinyScaleV"/>
+ <spinner label="Degrés de rotation" name="shinyRot"/>
+ <spinner label="Décalage horizontal" name="shinyOffsetU"/>
+ <spinner label="Décalage vertical" name="shinyOffsetV"/>
+ <check_box initial_value="false" label="Aligner les faces Plan" name="checkbox planar align" tool_tip="Aligner les textures sur toutes les faces sélectionnées avec la dernière face sélectionnée. Application de la texture Plan requise."/>
+</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_voice_effect.xml b/indra/newview/skins/default/xui/fr/panel_voice_effect.xml
index a134854706..a134854706 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_voice_effect.xml
+++ b/indra/newview/skins/default/xui/fr/panel_voice_effect.xml
diff --git a/indra/newview/skins/default/xui/fr/panel_volume_pulldown.xml b/indra/newview/skins/default/xui/fr/panel_volume_pulldown.xml
new file mode 100755
index 0000000000..e05c93a4ac
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/panel_volume_pulldown.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="volumepulldown_floater">
+ <slider label="Principal" name="System Volume"/>
+ <slider label="Boutons" name="UI Volume"/>
+ <slider label="Ambiant" name="Wind Volume"/>
+ <slider label="Sons" name="SFX Volume"/>
+ <check_box name="gesture_audio_play_btn" tool_tip="Activer les sons des gestes."/>
+ <slider label="Musique" name="Music Volume"/>
+ <check_box name="enable_music" tool_tip="Activer les flux de musique."/>
+ <slider label="Médias" name="Media Volume"/>
+ <check_box name="enable_media" tool_tip="Activer les flux de média."/>
+ <slider label="Voix" name="Voice Volume"/>
+ <check_box name="enable_voice_check" tool_tip="Activer le chat vocal."/>
+</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_world_map.xml b/indra/newview/skins/default/xui/fr/panel_world_map.xml
index 972aae1fab..972aae1fab 100644..100755
--- a/indra/newview/skins/default/xui/fr/panel_world_map.xml
+++ b/indra/newview/skins/default/xui/fr/panel_world_map.xml
diff --git a/indra/newview/skins/default/xui/fr/role_actions.xml b/indra/newview/skins/default/xui/fr/role_actions.xml
index 7187de8760..2a68ca0ddb 100644..100755
--- a/indra/newview/skins/default/xui/fr/role_actions.xml
+++ b/indra/newview/skins/default/xui/fr/role_actions.xml
@@ -25,7 +25,7 @@
</action_set>
<action_set description="Ces pouvoirs permettent de modifier le nom de la parcelle, son référencement dans la recherche et le lieu de téléportation." name="Parcel Identity">
<action description="Activer Afficher le lieu dans la recherche et définir la catégorie" longdescription="Activez Afficher le lieu dans la recherche et définissez la catégorie d&apos;une parcelle dans l&apos;onglet À propos du terrain &gt; Options." name="land find places" value="17"/>
- <action description="Modifier le nom et la description de la parcelle, ainsi que les paramètres d&apos;affichage du lieu dans la recherche" longdescription="Modifiez le nom et la description de la parcelle, ainsi que les paramètres d&apos;affichage du lieu dans la recherche. Pour ce faire, utilisez l&apos;onglet À propos du terrain &gt; Options." name="land change identity" value="18"/>
+ <action description="Changer le nom de la parcelle, la description et les paramètres de contenu modéré" longdescription="Changez le nom de la parcelle, la description et les paramètres de contenu modéré. Pour ce faire, utilisez l&apos;onglet À propos du terrain &gt; Options." name="land change identity" value="18"/>
<action description="Définir le lieu d&apos;arrivée et le routage des téléportations" longdescription="Définissez le lieu d&apos;arrivée des téléportations et le routage à partir du menu À propos du terrain &gt; Options." name="land set landing point" value="19"/>
</action_set>
<action_set description="Ces pouvoirs permettent de définir les options de la parcelle concernant la musique, les médias, la création d&apos;objets et le relief." name="Parcel Settings">
diff --git a/indra/newview/skins/default/xui/fr/sidepanel_appearance.xml b/indra/newview/skins/default/xui/fr/sidepanel_appearance.xml
index 5e1ac55a97..5e1ac55a97 100644..100755
--- a/indra/newview/skins/default/xui/fr/sidepanel_appearance.xml
+++ b/indra/newview/skins/default/xui/fr/sidepanel_appearance.xml
diff --git a/indra/newview/skins/default/xui/fr/sidepanel_inventory.xml b/indra/newview/skins/default/xui/fr/sidepanel_inventory.xml
index 1b9c832679..1b9c832679 100644..100755
--- a/indra/newview/skins/default/xui/fr/sidepanel_inventory.xml
+++ b/indra/newview/skins/default/xui/fr/sidepanel_inventory.xml
diff --git a/indra/newview/skins/default/xui/fr/sidepanel_item_info.xml b/indra/newview/skins/default/xui/fr/sidepanel_item_info.xml
index 95649d3934..e7fc7859c9 100644..100755
--- a/indra/newview/skins/default/xui/fr/sidepanel_item_info.xml
+++ b/indra/newview/skins/default/xui/fr/sidepanel_item_info.xml
@@ -3,6 +3,9 @@
<panel.string name="unknown">
(inconnu)
</panel.string>
+ <panel.string name="unknown_multiple">
+ (valeur inconnue ou valeurs multiples)
+ </panel.string>
<panel.string name="public">
(public)
</panel.string>
diff --git a/indra/newview/skins/default/xui/fr/sidepanel_task_info.xml b/indra/newview/skins/default/xui/fr/sidepanel_task_info.xml
index bd8a39fe16..896dd932e3 100644..100755
--- a/indra/newview/skins/default/xui/fr/sidepanel_task_info.xml
+++ b/indra/newview/skins/default/xui/fr/sidepanel_task_info.xml
@@ -18,6 +18,12 @@
<panel.string name="text modify info 4">
Vous ne pouvez pas modifier ces objets
</panel.string>
+ <panel.string name="text modify info 5">
+ Impossible de modifier cet objet au-delà de la frontière d&apos;une région
+ </panel.string>
+ <panel.string name="text modify info 6">
+ Impossible de modifier ces objets au-delà de la frontière d&apos;une région
+ </panel.string>
<panel.string name="text modify warning">
Cet objet comprend des parties liées
</panel.string>
@@ -66,6 +72,7 @@
<combo_box.item label="Acheter l&apos;objet" name="Buyobject"/>
<combo_box.item label="Payer l&apos;objet" name="Payobject"/>
<combo_box.item label="Ouvrir" name="Open"/>
+ <combo_box.item label="Zoom" name="Zoom"/>
</combo_box>
<panel name="perms_inv">
<text name="perm_modify">
@@ -95,6 +102,9 @@
</combo_box>
<spinner label="Prix : L$" name="Edit Cost"/>
<check_box label="Afficher avec la recherche" name="search_check" tool_tip="Permettre aux autres résidents de voir cet objet dans les résultats de recherche"/>
+ <text name="pathfinding_attributes_label">
+ Attributs de recherche de chemin :
+ </text>
<text name="B:">
B :
</text>
diff --git a/indra/newview/skins/default/xui/fr/strings.xml b/indra/newview/skins/default/xui/fr/strings.xml
index 3eebed450f..78d846ff4f 100644..100755
--- a/indra/newview/skins/default/xui/fr/strings.xml
+++ b/indra/newview/skins/default/xui/fr/strings.xml
@@ -137,7 +137,10 @@
Quitter
</string>
<string name="create_account_url">
- http://join.secondlife.com/index.php?lang=fr-FR
+ http://join.secondlife.com/?sourceid=[sourceid]
+ </string>
+ <string name="ViewerDownloadURL">
+ http://secondlife.com/download
</string>
<string name="LoginFailedViewerNotPermitted">
Le client que vous utilisez ne permet plus d&apos;accéder à Second Life. Téléchargez un nouveau client à la page suivante :
@@ -448,6 +451,9 @@ Veuillez réessayer de vous connecter dans une minute.
<string name="SLappAgentRequestFriend">
Demande d&apos;amitié
</string>
+ <string name="SLappAgentRemoveFriend">
+ Suppression d&apos;un ami
+ </string>
<string name="BUTTON_CLOSE_DARWIN">
Fermer (⌘W)
</string>
@@ -622,8 +628,8 @@ Veuillez réessayer de vous connecter dans une minute.
<string name="AvatarAway">
Absent
</string>
- <string name="AvatarBusy">
- Occupé
+ <string name="AvatarDoNotDisturb">
+ Ne pas déranger
</string>
<string name="AvatarMuted">
Bloqué(e)
@@ -838,6 +844,9 @@ Veuillez réessayer de vous connecter dans une minute.
<string name="multiple_textures">
Multiples
</string>
+ <string name="use_texture">
+ Utiliser la texture
+ </string>
<string name="texture_loading">
Chargement...
</string>
@@ -859,6 +868,12 @@ Veuillez réessayer de vous connecter dans une minute.
<string name="ST_NO_JOINT">
Impossible de trouver ROOT ou JOINT.
</string>
+ <string name="NearbyChatTitle">
+ Chat près de moi
+ </string>
+ <string name="NearbyChatLabel">
+ (Chat près de moi)
+ </string>
<string name="whisper">
chuchote :
</string>
@@ -886,6 +901,9 @@ Veuillez réessayer de vous connecter dans une minute.
<string name="ScriptQuestionCautionChatDenied">
&apos;[OBJECTNAME]&apos;, un objet appartenant à [OWNERNAME], situé dans [REGIONNAME] à [REGIONPOS], n&apos;a pas reçu le droit de : [PERMISSIONS].
</string>
+ <string name="AdditionalPermissionsRequestHeader">
+ Si vous autorisez un accès à votre compte, vous autorisez également l&apos;objet à :
+ </string>
<string name="ScriptTakeMoney">
Débiter vos Linden dollars (L$)
</string>
@@ -922,6 +940,27 @@ Veuillez réessayer de vous connecter dans une minute.
<string name="NotConnected">
Pas connecté(e)
</string>
+ <string name="AgentNameSubst">
+ (Vous)
+ </string>
+ <string name="TeleportYourAgent">
+ Vous téléporter
+ </string>
+ <string name="JoinAnExperience">
+ Rejoindre une expérience
+ </string>
+ <string name="SilentlyManageEstateAccess">
+ Supprimer les alertes lors de la gestion des listes d&apos;accès aux domaines
+ </string>
+ <string name="OverrideYourAnimations">
+ Remplacer vos animations par défaut
+ </string>
+ <string name="ScriptReturnObjects">
+ Renvoyer les objets de votre part
+ </string>
+ <string name="UnknownScriptPermission">
+ (inconnu)
+ </string>
<string name="SIM_ACCESS_PG">
Général
</string>
@@ -1000,17 +1039,8 @@ Veuillez réessayer de vous connecter dans une minute.
<string name="script_files">
Scripts
</string>
- <string name="AvatarSetNotAway">
- Présent
- </string>
- <string name="AvatarSetAway">
- Absent
- </string>
- <string name="AvatarSetNotBusy">
- Pas occupé
- </string>
- <string name="AvatarSetBusy">
- Occupé
+ <string name="dictionary_files">
+ Dictionnaires
</string>
<string name="shape">
Silhouette
@@ -1244,7 +1274,7 @@ Veuillez réessayer de vous connecter dans une minute.
https://marketplace.[MARKETPLACE_DOMAIN_NAME]/
</string>
<string name="MarketplaceURL_CreateStore">
- http://community.secondlife.com/t5/English-Knowledge-Base/Selling-in-the-Marketplace/ta-p/700193#Section_.4
+ http://community.secondlife.com/t5/English-Knowledge-Base/Selling-in-the-Marketplace/ta-p/700193#Section_.3
</string>
<string name="MarketplaceURL_Dashboard">
https://marketplace.[MARKETPLACE_DOMAIN_NAME]/merchants/store/dashboard
@@ -1405,6 +1435,12 @@ Veuillez réessayer de vous connecter dans une minute.
<string name="InvFolder favorite">
Mes Favoris
</string>
+ <string name="InvFolder Favorites">
+ Mes favoris
+ </string>
+ <string name="InvFolder favorites">
+ Mes favoris
+ </string>
<string name="InvFolder Current Outfit">
Tenue actuelle
</string>
@@ -1420,6 +1456,12 @@ Veuillez réessayer de vous connecter dans une minute.
<string name="InvFolder Meshes">
Maillages
</string>
+ <string name="InvFolder Received Items">
+ Articles reçus
+ </string>
+ <string name="InvFolder Merchant Outbox">
+ Boîte d&apos;envoi vendeur
+ </string>
<string name="InvFolder Friends">
Amis
</string>
@@ -1950,6 +1992,12 @@ Veuillez réessayer de vous connecter dans une minute.
<string name="ATTACH_HUD_BOTTOM_RIGHT">
HUD en bas à droite
</string>
+ <string name="ATTACH_NECK">
+ Cou
+ </string>
+ <string name="ATTACH_AVATAR_CENTER">
+ Centre de l&apos;avatar
+ </string>
<string name="CursorPos">
Ligne [LINE], colonne [COLUMN]
</string>
@@ -1968,8 +2016,8 @@ Veuillez réessayer de vous connecter dans une minute.
<string name="PanelContentsNewScript">
Nouveau script
</string>
- <string name="BusyModeResponseDefault">
- Le résident auquel vous avez envoyé un message est en mode Occupé, ce qui signifie qu&apos;il a demandé à ne pas être dérangé. Votre message restera affiché dans son panneau IM afin qu&apos;il puisse le lire ultérieurement.
+ <string name="DoNotDisturbModeResponseDefault">
+ Ce résident a activé Ne pas déranger et verra votre message plus tard.
</string>
<string name="MuteByName">
(par nom)
@@ -2082,9 +2130,6 @@ Veuillez réessayer de vous connecter dans une minute.
<string name="GroupMoneyDate">
[weekday,datetime,utc] [day,datetime,utc] [mth,datetime,utc] [year,datetime,utc]
</string>
- <string name="ViewerObjectContents">
- Contenus
- </string>
<string name="AcquiredItems">
Objets acquis
</string>
@@ -2982,6 +3027,9 @@ Si ce message persiste, veuillez aller sur la page [SUPPORT_SITE].
<string name="Hip Width">
Largeur hanche
</string>
+ <string name="Hover">
+ Survol
+ </string>
<string name="In">
Rentré
</string>
@@ -3856,7 +3904,13 @@ Si ce message persiste, veuillez aller sur la page [SUPPORT_SITE].
Région de type Général
</string>
<string name="LocationCtrlSeeAVsTooltip">
- Avatars visibles et chat autorisé en dehors de cette parcelle
+ Les avatars à l&apos;extérieur de cette parcelle ne peuvent pas voir ni entendre les avatars qui se trouvent à l&apos;intérieur.
+ </string>
+ <string name="LocationCtrlPathfindingDirtyTooltip">
+ Les objets mobiles risquent de ne pas se comporter correctement dans cette région tant qu&apos;elle n&apos;est pas refigée.
+ </string>
+ <string name="LocationCtrlPathfindingDisabledTooltip">
+ La recherche de chemin dynamique n&apos;est pas activée dans cette région.
</string>
<string name="UpdaterWindowTitle">
[APP_NAME] - Mise à jour
@@ -3927,6 +3981,12 @@ Si ce message persiste, veuillez aller sur la page [SUPPORT_SITE].
<string name="IM_unblock_only_groups_friends">
Pour afficher ce message, vous devez désactiver la case Seuls mes amis et groupes peuvent m&apos;appeler ou m&apos;envoyer un IM, sous Préférences/Confidentialité.
</string>
+ <string name="OnlineStatus">
+ En ligne
+ </string>
+ <string name="OfflineStatus">
+ Hors ligne
+ </string>
<string name="answered_call">
Votre appel a fait l&apos;objet d&apos;une réponse
</string>
@@ -3936,6 +3996,9 @@ Si ce message persiste, veuillez aller sur la page [SUPPORT_SITE].
<string name="you_joined_call">
Vous avez rejoint l&apos;appel
</string>
+ <string name="you_auto_rejected_call-im">
+ Vous avez automatiquement refusé l&apos;appel vocal quand le mode Ne pas déranger était activé.
+ </string>
<string name="name_started_call">
[NAME] appelle.
</string>
@@ -3952,7 +4015,7 @@ Si ce message persiste, veuillez aller sur la page [SUPPORT_SITE].
Connexion en cours...
</string>
<string name="conference-title">
- Conférence ad-hoc
+ Chat à plusieurs
</string>
<string name="conference-title-incoming">
Conférence avec [AGENT_NAME]
@@ -4509,7 +4572,7 @@ Essayez avec le chemin d&apos;accès à l&apos;éditeur entre guillemets doubles
Backsp
</string>
<string name="Shift">
- Shift
+ Maj
</string>
<string name="Ctrl">
Ctrl
@@ -4832,6 +4895,9 @@ Essayez avec le chemin d&apos;accès à l&apos;éditeur entre guillemets doubles
<string name="Command_Chat_Label">
Chat
</string>
+ <string name="Command_Conversations_Label">
+ Conversations
+ </string>
<string name="Command_Compass_Label">
Boussole
</string>
@@ -4887,7 +4953,7 @@ Essayez avec le chemin d&apos;accès à l&apos;éditeur entre guillemets doubles
Parler
</string>
<string name="Command_View_Label">
- Paramètres de la caméra
+ Caméra
</string>
<string name="Command_Voice_Label">
Paramètres vocaux
@@ -4907,6 +4973,9 @@ Essayez avec le chemin d&apos;accès à l&apos;éditeur entre guillemets doubles
<string name="Command_Chat_Tooltip">
Parler aux personnes près de vous par chat écrit
</string>
+ <string name="Command_Conversations_Tooltip">
+ Parler à quelqu&apos;un
+ </string>
<string name="Command_Compass_Tooltip">
Boussole
</string>
@@ -5000,6 +5069,21 @@ Essayez avec le chemin d&apos;accès à l&apos;éditeur entre guillemets doubles
<string name="Normal">
Normal
</string>
+ <string name="Pathfinding_Wiki_URL">
+ http://wiki.secondlife.com/wiki/Pathfinding_Tools_in_the_Second_Life_Viewer
+ </string>
+ <string name="Pathfinding_Object_Attr_None">
+ Aucun
+ </string>
+ <string name="Pathfinding_Object_Attr_Permanent">
+ Maillage de navigation affecté
+ </string>
+ <string name="Pathfinding_Object_Attr_Character">
+ Personnage
+ </string>
+ <string name="Pathfinding_Object_Attr_MultiSelect">
+ (Multiple)
+ </string>
<string name="snapshot_quality_very_low">
Très faible
</string>
@@ -5015,4 +5099,22 @@ Essayez avec le chemin d&apos;accès à l&apos;éditeur entre guillemets doubles
<string name="snapshot_quality_very_high">
Très élevée
</string>
+ <string name="TeleportMaturityExceeded">
+ Le résident ne peut pas visiter cette région.
+ </string>
+ <string name="UserDictionary">
+ [User]
+ </string>
+ <string name="logging_calls_disabled_log_empty">
+ Les conversations ne sont pas archivées. Pour commencer à tenir un journal, choisissez Enregistrer : Journal seul ou Enregistrer : Journal et transcriptions sous Préférences &gt; Chat.
+ </string>
+ <string name="logging_calls_disabled_log_not_empty">
+ Aucune conversation ne sera plus enregistrée. Pour recommencer à tenir un journal, choisissez Enregistrer : Journal seul ou Enregistrer : Journal et transcriptions sous Préférences &gt; Chat.
+ </string>
+ <string name="logging_calls_enabled_log_empty">
+ Il n&apos;y a aucune conversation enregistrée. Quand quelqu&apos;un vous contacte ou quand vous contactez quelqu&apos;un, une entrée de journal s&apos;affiche ici.
+ </string>
+ <string name="loading_chat_logs">
+ Chargement...
+ </string>
</strings>
diff --git a/indra/newview/skins/default/xui/fr/teleport_strings.xml b/indra/newview/skins/default/xui/fr/teleport_strings.xml
index d0c74ff353..6065fa2966 100644..100755
--- a/indra/newview/skins/default/xui/fr/teleport_strings.xml
+++ b/indra/newview/skins/default/xui/fr/teleport_strings.xml
@@ -45,6 +45,9 @@ Pour recommencer le didacticiel, accédez à Welcome Island Public.
<message name="no_inventory_host">
L&apos;inventaire est temporairement indisponible.
</message>
+ <message name="MustGetAgeRegion">
+ Pour accéder à cette région, vous devez avoir au moins 18 ans.
+ </message>
</message_set>
<message_set name="progress">
<message name="sending_dest">
@@ -80,5 +83,8 @@ Pour recommencer le didacticiel, accédez à Welcome Island Public.
<message name="requesting">
Demande de téléportation en cours...
</message>
+ <message name="pending">
+ En attente de téléportation...
+ </message>
</message_set>
</teleport_messages>
diff --git a/indra/newview/skins/default/xui/fr/xui_version.xml b/indra/newview/skins/default/xui/fr/xui_version.xml
index 0e777751d3..0e777751d3 100644..100755
--- a/indra/newview/skins/default/xui/fr/xui_version.xml
+++ b/indra/newview/skins/default/xui/fr/xui_version.xml
diff --git a/indra/newview/skins/default/xui/it/floater_about.xml b/indra/newview/skins/default/xui/it/floater_about.xml
index 39114b7bf7..6f09eca90c 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_about.xml
+++ b/indra/newview/skins/default/xui/it/floater_about.xml
@@ -8,7 +8,9 @@
Generato con [COMPILER] versione [COMPILER_VERSION]
</floater.string>
<floater.string name="AboutPosition">
- Tu sei [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1] in [REGION] che si trova a &lt;nolink&gt;[HOSTNAME]&lt;/nolink&gt; ([HOSTIP])
+ Tu sei a [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] in [REGION] che si trova a &lt;nolink&gt;[HOSTNAME]&lt;/nolink&gt; ([HOSTIP])
+SLURL: &lt;nolink&gt;[SLURL]&lt;/nolink&gt;
+(coordinate globali [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1])
[SERVER_VERSION]
[SERVER_RELEASE_NOTES_URL]
</floater.string>
@@ -66,27 +68,26 @@ Versione Server voice: [VOICE_VERSION]
</panel>
<panel label="Licenze" name="licenses_panel">
<text_editor name="credits_editor">
- 3Dconnexion SDK Copyright (C) 1992-2007 3Dconnexion
- APR Copyright (C) 2000-2004 The Apache Software Foundation
- Collada DOM Copyright 2005 Sony Computer Entertainment Inc.
- cURL Copyright (C) 1996-2002, Daniel Stenberg, (daniel@haxx.se)
+ 3Dconnexion SDK Copyright (C) 1992-2009 3Dconnexion
+ APR Copyright (C) 2011 The Apache Software Foundation
+ Collada DOM Copyright 2006 Sony Computer Entertainment Inc.
+ cURL Copyright (C) 1996-2010, Daniel Stenberg, (daniel@haxx.se)
DBus/dbus-glib Copyright (C) 2002, 2003 CodeFactory AB / Copyright (C) 2003, 2004 Red Hat, Inc.
expat Copyright (C) 1998, 1999, 2000 Thai Open Source Software Center Ltd.
- FreeType Copyright (C) 1996-2002, The FreeType Project (www.freetype.org).
+ FreeType Copyright (C) 1996-2002, 2006 David Turner, Robert Wilhelm, and Werner Lemberg.
GL Copyright (C) 1999-2004 Brian Paul.
GLOD Copyright (C) 2003-04 Jonathan Cohen, Nat Duca, Chris Niski, Johns Hopkins University and David Luebke, Brenden Schubert, University of Virginia.
google-perftools Copyright (c) 2005, Google Inc.
Havok.com(TM) Copyright (C) 1999-2001, Telekinesys Research Limited.
jpeg2000 Copyright (C) 2001, David Taubman, The University of New South Wales (UNSW)
jpeglib Copyright (C) 1991-1998, Thomas G. Lane.
- ogg/vorbis Copyright (C) 2001, Xiphophorus
- OpenSSL Copyright (C) 1998-2002 The OpenSSL Project.
- PCRE Copyright (c) 1997-2008 University of Cambridge
+ ogg/vorbis Copyright (C) 2002, Xiphophorus
+ OpenSSL Copyright (C) 1998-2008 The OpenSSL Project.
+ PCRE Copyright (c) 1997-2012 University of Cambridge
SDL Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga
SSLeay Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
xmlrpc-epi Copyright (C) 2000 Epinions, Inc.
- zlib Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler.
- google-perftools Copyright (c) 2005, Google Inc.
+ zlib Copyright (C) 1995-2012 Jean-loup Gailly and Mark Adler.
Il Viewer Second Life utilizza Havok (TM) Physics. (c)Copyright 1999-2010 Havok.com Inc. (e licenziatari). Tutti i diritti riservati. Per informazioni dettagliate, vedere www.havok.com.
diff --git a/indra/newview/skins/default/xui/it/floater_about_land.xml b/indra/newview/skins/default/xui/it/floater_about_land.xml
index cfc3ad8fdb..fe3e59b0bd 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/it/floater_about_land.xml
@@ -470,7 +470,7 @@ Media:
Consenti l&apos;accesso solo ai Residenti che:
</text>
<check_box label="Hanno informazioni di pagamento in archivio [ESTATE_PAYMENT_LIMIT]" name="limit_payment" tool_tip="Per poter visitare questo lotto i Residenti devono aver fornito informazioni di pagamento a Linden Lab. Vedi [SUPPORT_SITE] per maggiori informazioni."/>
- <check_box label="Hanno verificato l&apos;età [ESTATE_AGE_LIMIT]" name="limit_age_verified" tool_tip="Per poter visitare questo lotto i Residenti devono aver verificato la propria età. Vedi [SUPPORT_SITE] per maggiori informazioni."/>
+ <check_box label="Hanno almeno 18 anni [ESTATE_AGE_LIMIT]" name="limit_age_verified" tool_tip="Per poter visitare questo lotto i Residenti devono avere almeno 18 anni. Vedi [SUPPORT_SITE] per maggiori informazioni."/>
<check_box label="Permetti accesso al gruppo: [GROUP]" name="GroupCheck" tool_tip="Imposta il gruppo nel pannello generale."/>
<check_box label="Vendi pass a:" name="PassCheck" tool_tip="Permetti in questo terreno l&apos;accesso temporaneo"/>
<combo_box name="pass_combo">
diff --git a/indra/newview/skins/default/xui/it/floater_activeim.xml b/indra/newview/skins/default/xui/it/floater_activeim.xml
index 0c1f0448e1..0c1f0448e1 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_activeim.xml
+++ b/indra/newview/skins/default/xui/it/floater_activeim.xml
diff --git a/indra/newview/skins/default/xui/it/floater_animation_anim_preview.xml b/indra/newview/skins/default/xui/it/floater_animation_anim_preview.xml
index a2bce00141..a2bce00141 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_animation_anim_preview.xml
+++ b/indra/newview/skins/default/xui/it/floater_animation_anim_preview.xml
diff --git a/indra/newview/skins/default/xui/it/floater_animation_bvh_preview.xml b/indra/newview/skins/default/xui/it/floater_animation_bvh_preview.xml
index a4319f2e77..a4319f2e77 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_animation_bvh_preview.xml
+++ b/indra/newview/skins/default/xui/it/floater_animation_bvh_preview.xml
diff --git a/indra/newview/skins/default/xui/it/floater_animation_preview.xml b/indra/newview/skins/default/xui/it/floater_animation_preview.xml
deleted file mode 100644
index dc99d287b9..0000000000
--- a/indra/newview/skins/default/xui/it/floater_animation_preview.xml
+++ /dev/null
@@ -1,187 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Animation Preview" title="">
- <floater.string name="failed_to_initialize">
- Impossibile inizializzare la sequenza
- </floater.string>
- <floater.string name="anim_too_long">
- Il file dell&apos;animazione è lungo [LENGTH] secondi.
-
-La lunghezza massima è [MAX_LENGTH] secondi.
- </floater.string>
- <floater.string name="failed_file_read">
- Impossibile leggere il file dell&apos;animazione.
-
-[STATUS]
- </floater.string>
- <floater.string name="E_ST_OK">
- Ok
- </floater.string>
- <floater.string name="E_ST_EOF">
- Fine prematura del file.
- </floater.string>
- <floater.string name="E_ST_NO_CONSTRAINT">
- Impossibile leggere la definizione del vincolo.
- </floater.string>
- <floater.string name="E_ST_NO_FILE">
- Impossibile aprire il file BVH.
- </floater.string>
- <floater.string name="E_ST_NO_HIER">
- Intestazione HIERARCHY non valida.
- </floater.string>
- <floater.string name="E_ST_NO_JOINT">
- Impossibile trovare la ROOT o JOINT.
- </floater.string>
- <floater.string name="E_ST_NO_NAME">
- Impossibile trovare il nome JOINT.
- </floater.string>
- <floater.string name="E_ST_NO_OFFSET">
- Impossibile trovare OFFSET.
- </floater.string>
- <floater.string name="E_ST_NO_CHANNELS">
- Impossibile trovare CHANNELS.
- </floater.string>
- <floater.string name="E_ST_NO_ROTATION">
- Impossibile ottenere un ordine di rotazione.
- </floater.string>
- <floater.string name="E_ST_NO_AXIS">
- Rotazione dell&apos;asse non disponibile.
- </floater.string>
- <floater.string name="E_ST_NO_MOTION">
- Impossibile trovare MOTION.
- </floater.string>
- <floater.string name="E_ST_NO_FRAMES">
- Impossibile ottenere il numero dei frame.
- </floater.string>
- <floater.string name="E_ST_NO_FRAME_TIME">
- Impossibile ottenere il tempo del frame.
- </floater.string>
- <floater.string name="E_ST_NO_POS">
- Impossibile ottenere i valori della posizione.
- </floater.string>
- <floater.string name="E_ST_NO_ROT">
- Impossibile ottenere i valori di rotazione.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_FILE">
- Impossibile aprire il file di traduzione.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_HEADER">
- Impossibile leggere l&apos;intestazione della traduzione.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_NAME">
- Impossibile leggere i nomi della traduzione.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_IGNORE">
- Impossibile leggere la traduzione, ignora il valore.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_RELATIVE">
- Impossibile leggere la traduzione del valore relativo.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_OUTNAME">
- Valore non trovato.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_MATRIX">
- Impossibile leggere la matrice di traduzione.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_MERGECHILD">
- Impossibile trovare il nome mergechild.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_MERGEPARENT">
- Impossibile ottenere il nome mergeparent.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_PRIORITY">
- Impossibile ottenere il valore di priorità.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_LOOP">
- Impossibile ottenere il valore di ripetizione.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_EASEIN">
- Impossibile ottenere i valori easeIn.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_EASEOUT">
- Cannot get ease Out values.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_HAND">
- Impossibile ottenere il valore morph della mano.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_EMOTE">
- Impossibile leggere il nome emote.
- </floater.string>
- <floater.string name="E_ST_BAD_ROOT">
- Nome non corretto del root joint, usa &quot;hip&quot;.
- </floater.string>
- <text name="name_label">
- Nome:
- </text>
- <text name="description_label">
- Descrizione:
- </text>
- <spinner label="Priorità" name="priority" tool_tip="Definisce quali altre animazioni possono essere sostituite da questa animazione"/>
- <check_box label="Ciclica" name="loop_check" tool_tip="Riproduce questa animazione in ripetizione"/>
- <spinner label="In(%)" name="loop_in_point" tool_tip="Imposta il punto sul quale ritorna l&apos;animazione"/>
- <spinner label="Out(%)" name="loop_out_point" tool_tip="Imposta il punto sul quale termina l&apos;animazione"/>
- <text name="hand_label">
- Postura della mano
- </text>
- <combo_box name="hand_pose_combo" tool_tip="Definisce ciò che fanno le mani durante l&apos;animazione">
- <combo_box.item label="Stendi" name="Spread"/>
- <combo_box.item label="Rilassato" name="Relaxed"/>
- <combo_box.item label="Indica entrambi" name="PointBoth"/>
- <combo_box.item label="Pugno" name="Fist"/>
- <combo_box.item label="Sinistra rilassata" name="RelaxedLeft"/>
- <combo_box.item label="Indica sinistra" name="PointLeft"/>
- <combo_box.item label="Pugno con la sinistra" name="FistLeft"/>
- <combo_box.item label="Destra rilassata" name="RelaxedRight"/>
- <combo_box.item label="Indica destra" name="PointRight"/>
- <combo_box.item label="Pugno destro" name="FistRight"/>
- <combo_box.item label="Saluta a destra" name="SaluteRight"/>
- <combo_box.item label="Battitura" name="Typing"/>
- <combo_box.item label="Pace a destra" name="PeaceRight"/>
- </combo_box>
- <text name="emote_label">
- Espressione
- </text>
- <combo_box name="emote_combo" tool_tip="Definisce ciò che fa il viso durante l&apos;animazione">
- <item label="(Nessuno)" name="[None]" value=""/>
- <item label="Aaaaah" name="Aaaaah" value="Aaaaah"/>
- <item label="Spavento" name="Afraid" value="Spavento"/>
- <item label="Arrabbiato" name="Angry" value="Arrabbiato"/>
- <item label="Grande sorriso" name="BigSmile" value="Grande sorriso"/>
- <item label="Annoiato" name="Bored" value="Annoiato"/>
- <item label="Pianto" name="Cry" value="Pianto"/>
- <item label="Disdegno" name="Disdain" value="Disdegno"/>
- <item label="Imbarazzato" name="Embarrassed" value="Imbarazzato"/>
- <item label="Accigliato" name="Frown" value="Accigliato"/>
- <item label="Bacio" name="Kiss" value="Bacio"/>
- <item label="Risata" name="Laugh" value="Risata"/>
- <item label="Plllppt" name="Plllppt" value="Linguaccia"/>
- <item label="Repulsione" name="Repulsed" value="Repulsione"/>
- <item label="Triste" name="Sad" value="Triste"/>
- <item label="Scrollata di spalle" name="Shrug" value="Scrollata di spalle"/>
- <item label="Sorriso" name="Smile" value="Sorriso"/>
- <item label="Stupore" name="Surprise" value="Stupore"/>
- <item label="Occhiolino" name="Wink" value="Occhiolino"/>
- <item label="Preoccupato" name="Worry" value="Preoccupato"/>
- </combo_box>
- <text name="preview_label">
- Vedi anteprima mentre
- </text>
- <combo_box name="preview_base_anim" tool_tip="Da usarsi per controllare il comportamento dell&apos;animazione mentre l&apos;avatar svolge azioni abituali.">
- <item label="In piedi" name="Standing" value="In piedi"/>
- <item label="Camminando" name="Walking" value="Cammina"/>
- <item label="Seduto" name="Sitting" value="Seduto"/>
- <item label="Volo" name="Flying" value="Volo"/>
- </combo_box>
- <spinner label="Avvio lento (sec)" name="ease_in_time" tool_tip="Durata (in secondi) della fusione in entrata delle animazioni"/>
- <spinner label="Arresto lento (sec)" name="ease_out_time" tool_tip="Durata (in secondi) della fusione in uscita delle animazioni"/>
- <button name="play_btn" tool_tip="Riproduci la tua animazione"/>
- <button name="pause_btn" tool_tip="Metti in pausa la tua animazione"/>
- <button label="" name="stop_btn" tool_tip="Ferma la riproduzione dell&apos;animazione"/>
- <text name="bad_animation_text">
- Impossibile leggere il file dell&apos;animazione.
-
-Raccomandiamo file di tipo BVH esportati da
-Poser 4.
- </text>
- <button label="Importa ([AMOUNT]L$)" name="ok_btn"/>
- <button label="Annulla" name="cancel_btn"/>
-</floater>
diff --git a/indra/newview/skins/default/xui/it/floater_auction.xml b/indra/newview/skins/default/xui/it/floater_auction.xml
index 4cad8b744d..4cad8b744d 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_auction.xml
+++ b/indra/newview/skins/default/xui/it/floater_auction.xml
diff --git a/indra/newview/skins/default/xui/it/floater_autoreplace.xml b/indra/newview/skins/default/xui/it/floater_autoreplace.xml
new file mode 100755
index 0000000000..559a42cfae
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/floater_autoreplace.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="autoreplace_floater" title="Impostazioni sostituzione automatica">
+ <check_box label="Attiva sostituzione automatica" name="autoreplace_enable" tool_tip="Quando inserisci testo nella chat, sostituisci le parole chiave inserite con l&apos;elemento sostitutivo corrispondente."/>
+ <button label="Importa lista..." name="autoreplace_import_list" tool_tip="Carica da file una lista esportata in precedenza."/>
+ <button label="Esporta lista..." name="autoreplace_export_list" tool_tip="Salva la lista selezionata in un file per condividerla."/>
+ <button label="Nuova lista..." name="autoreplace_new_list" tool_tip="Crea una nuova lista"/>
+ <button label="Cancella lista" name="autoreplace_delete_list" tool_tip="Cancella la lista selezionata"/>
+ <button name="autoreplace_list_up" tool_tip="Aumenta la priorità di questa lista."/>
+ <button name="autoreplace_list_down" tool_tip="Diminuisci la priorità di questa lista."/>
+ <scroll_list name="autoreplace_list_replacements">
+ <scroll_list.columns label="Parola chiave" name="keyword"/>
+ <scroll_list.columns label="Sostituzione" name="replacement"/>
+ </scroll_list>
+ <button label="Aggiungi..." name="autoreplace_add_entry"/>
+ <button label="Rimuovi" name="autoreplace_delete_entry"/>
+ <button label="Salva elemento" name="autoreplace_save_entry" tool_tip="Salva questo elemento."/>
+ <button label="Salva modifiche" name="autoreplace_save_changes" tool_tip="Salva tutte le modifiche."/>
+ <button label="Annulla" name="autoreplace_cancel" tool_tip="Annulla tutte le modifiche."/>
+</floater>
+<!--
+ <text
+ top_pad="10"
+ left="10"
+ height="16"
+ width="260"
+ follows="left|top"
+ halign="center"
+ mouse_opaque="true"
+ name="autoreplace_text2">
+ Entries
+ </text>
+-->
diff --git a/indra/newview/skins/default/xui/it/floater_avatar.xml b/indra/newview/skins/default/xui/it/floater_avatar.xml
index d7445cfb2b..d7445cfb2b 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_avatar.xml
+++ b/indra/newview/skins/default/xui/it/floater_avatar.xml
diff --git a/indra/newview/skins/default/xui/it/floater_avatar_picker.xml b/indra/newview/skins/default/xui/it/floater_avatar_picker.xml
index 5a542d6a27..5a542d6a27 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_avatar_picker.xml
+++ b/indra/newview/skins/default/xui/it/floater_avatar_picker.xml
diff --git a/indra/newview/skins/default/xui/it/floater_avatar_textures.xml b/indra/newview/skins/default/xui/it/floater_avatar_textures.xml
index b6376973cd..b6376973cd 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_avatar_textures.xml
+++ b/indra/newview/skins/default/xui/it/floater_avatar_textures.xml
diff --git a/indra/newview/skins/default/xui/it/floater_beacons.xml b/indra/newview/skins/default/xui/it/floater_beacons.xml
index b7ab265cc2..b7ab265cc2 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_beacons.xml
+++ b/indra/newview/skins/default/xui/it/floater_beacons.xml
diff --git a/indra/newview/skins/default/xui/it/floater_build_options.xml b/indra/newview/skins/default/xui/it/floater_build_options.xml
index 080e396642..080e396642 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_build_options.xml
+++ b/indra/newview/skins/default/xui/it/floater_build_options.xml
diff --git a/indra/newview/skins/default/xui/it/floater_bulk_perms.xml b/indra/newview/skins/default/xui/it/floater_bulk_perms.xml
index 89f4a0cb71..399eb15802 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_bulk_perms.xml
+++ b/indra/newview/skins/default/xui/it/floater_bulk_perms.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floaterbulkperms" title="MODIFICA PERMESSI DEL CONTENUTO">
+<floater name="floaterbulkperms" title="CAMBIA I PERMESSI DEL CONTENUTO">
<floater.string name="nothing_to_modify_text">
La selezione non contiene nessun contenuto modificabile.
</floater.string>
@@ -33,7 +33,7 @@
<button label="√ Tutti" label_selected="Tutti" name="check_all"/>
<button label="Cancella" label_selected="Nessuno" name="check_none"/>
<text name="newperms">
- Nuovi permessi del contenuto
+ Cambia i permessi del contenuto a
</text>
<text name="GroupLabel">
Gruppo:
@@ -49,6 +49,7 @@
<check_box label="Modificare" name="next_owner_modify"/>
<check_box label="Copiare" name="next_owner_copy"/>
<check_box initial_value="true" label="Trasferisci" name="next_owner_transfer" tool_tip="Il prossimo proprietario può regalare o rivendere questo oggetto"/>
- <button label="OK" name="apply"/>
+ <button label="OK" name="ok"/>
+ <button label="Applica" name="apply"/>
<button label="Annulla" name="close"/>
</floater>
diff --git a/indra/newview/skins/default/xui/it/floater_bumps.xml b/indra/newview/skins/default/xui/it/floater_bumps.xml
index ae66148659..ae66148659 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_bumps.xml
+++ b/indra/newview/skins/default/xui/it/floater_bumps.xml
diff --git a/indra/newview/skins/default/xui/it/floater_buy_contents.xml b/indra/newview/skins/default/xui/it/floater_buy_contents.xml
index 84ed85e362..84ed85e362 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_buy_contents.xml
+++ b/indra/newview/skins/default/xui/it/floater_buy_contents.xml
diff --git a/indra/newview/skins/default/xui/it/floater_buy_currency.xml b/indra/newview/skins/default/xui/it/floater_buy_currency.xml
index 743969f557..743969f557 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_buy_currency.xml
+++ b/indra/newview/skins/default/xui/it/floater_buy_currency.xml
diff --git a/indra/newview/skins/default/xui/it/floater_buy_currency_html.xml b/indra/newview/skins/default/xui/it/floater_buy_currency_html.xml
index 4a1bf33403..4a1bf33403 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_buy_currency_html.xml
+++ b/indra/newview/skins/default/xui/it/floater_buy_currency_html.xml
diff --git a/indra/newview/skins/default/xui/it/floater_buy_land.xml b/indra/newview/skins/default/xui/it/floater_buy_land.xml
index 3940c43a3d..3940c43a3d 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_buy_land.xml
+++ b/indra/newview/skins/default/xui/it/floater_buy_land.xml
diff --git a/indra/newview/skins/default/xui/it/floater_buy_object.xml b/indra/newview/skins/default/xui/it/floater_buy_object.xml
index e7cbd68b38..e7cbd68b38 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_buy_object.xml
+++ b/indra/newview/skins/default/xui/it/floater_buy_object.xml
diff --git a/indra/newview/skins/default/xui/it/floater_camera.xml b/indra/newview/skins/default/xui/it/floater_camera.xml
index be03857bc9..be03857bc9 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_camera.xml
+++ b/indra/newview/skins/default/xui/it/floater_camera.xml
diff --git a/indra/newview/skins/default/xui/it/floater_chat_bar.xml b/indra/newview/skins/default/xui/it/floater_chat_bar.xml
index 94c85b50c8..b47e32ce90 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_chat_bar.xml
+++ b/indra/newview/skins/default/xui/it/floater_chat_bar.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="chat_bar" title="CHAT NEI DINTORNI">
+<floater name="nearby_chat" title="CHAT NEI DINTORNI">
<panel name="bottom_panel">
<line_editor label="Clicca qui per la chat." name="chat_box" tool_tip="Premi Invio per parlare, Ctrl+Invio per gridare"/>
<button name="show_nearby_chat" tool_tip="Mostra/Nasconde il registro della chat nei dintorni"/>
diff --git a/indra/newview/skins/default/xui/it/floater_choose_group.xml b/indra/newview/skins/default/xui/it/floater_choose_group.xml
index 00f2692295..00f2692295 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_choose_group.xml
+++ b/indra/newview/skins/default/xui/it/floater_choose_group.xml
diff --git a/indra/newview/skins/default/xui/it/floater_color_picker.xml b/indra/newview/skins/default/xui/it/floater_color_picker.xml
index 38d4a0a037..38d4a0a037 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_color_picker.xml
+++ b/indra/newview/skins/default/xui/it/floater_color_picker.xml
diff --git a/indra/newview/skins/default/xui/it/floater_conversation_log.xml b/indra/newview/skins/default/xui/it/floater_conversation_log.xml
new file mode 100644
index 0000000000..8354824ed1
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/floater_conversation_log.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="floater_conversation_log" title="REGISTRO CONVERSAZIONI">
+ <panel name="buttons_panel">
+ <filter_editor label="Filtro persone" name="people_filter_input"/>
+ <menu_button name="conversation_view_btn" tool_tip="Opzioni Mostra/Ordina"/>
+ <menu_button name="conversations_gear_btn" tool_tip="Azioni sulla persona o gruppo selezionato"/>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/it/floater_conversation_preview.xml b/indra/newview/skins/default/xui/it/floater_conversation_preview.xml
new file mode 100644
index 0000000000..d0e9c8ee0e
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/floater_conversation_preview.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="preview_conversation" title="CONVERSAZIONE:">
+ <floater.string name="Title">
+ CONVERSAZIONE: [NAME]
+ </floater.string>
+ <text name="page_label" value="Pagina"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/it/floater_critical.xml b/indra/newview/skins/default/xui/it/floater_critical.xml
index 82850b0ada..82850b0ada 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_critical.xml
+++ b/indra/newview/skins/default/xui/it/floater_critical.xml
diff --git a/indra/newview/skins/default/xui/it/floater_delete_env_preset.xml b/indra/newview/skins/default/xui/it/floater_delete_env_preset.xml
index 71071825af..71071825af 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_delete_env_preset.xml
+++ b/indra/newview/skins/default/xui/it/floater_delete_env_preset.xml
diff --git a/indra/newview/skins/default/xui/it/floater_destinations.xml b/indra/newview/skins/default/xui/it/floater_destinations.xml
index 242403e431..242403e431 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_destinations.xml
+++ b/indra/newview/skins/default/xui/it/floater_destinations.xml
diff --git a/indra/newview/skins/default/xui/it/floater_display_name.xml b/indra/newview/skins/default/xui/it/floater_display_name.xml
index 3e0c43e741..3e0c43e741 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_display_name.xml
+++ b/indra/newview/skins/default/xui/it/floater_display_name.xml
diff --git a/indra/newview/skins/default/xui/it/floater_edit_day_cycle.xml b/indra/newview/skins/default/xui/it/floater_edit_day_cycle.xml
index c922b2e4f7..c922b2e4f7 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_edit_day_cycle.xml
+++ b/indra/newview/skins/default/xui/it/floater_edit_day_cycle.xml
diff --git a/indra/newview/skins/default/xui/it/floater_edit_sky_preset.xml b/indra/newview/skins/default/xui/it/floater_edit_sky_preset.xml
index 571027fd29..571027fd29 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_edit_sky_preset.xml
+++ b/indra/newview/skins/default/xui/it/floater_edit_sky_preset.xml
diff --git a/indra/newview/skins/default/xui/it/floater_edit_water_preset.xml b/indra/newview/skins/default/xui/it/floater_edit_water_preset.xml
index 7bffc60ba2..7bffc60ba2 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_edit_water_preset.xml
+++ b/indra/newview/skins/default/xui/it/floater_edit_water_preset.xml
diff --git a/indra/newview/skins/default/xui/it/floater_environment_settings.xml b/indra/newview/skins/default/xui/it/floater_environment_settings.xml
index f191078fad..f191078fad 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_environment_settings.xml
+++ b/indra/newview/skins/default/xui/it/floater_environment_settings.xml
diff --git a/indra/newview/skins/default/xui/it/floater_event.xml b/indra/newview/skins/default/xui/it/floater_event.xml
index b64f429870..b64f429870 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_event.xml
+++ b/indra/newview/skins/default/xui/it/floater_event.xml
diff --git a/indra/newview/skins/default/xui/it/floater_fast_timers.xml b/indra/newview/skins/default/xui/it/floater_fast_timers.xml
index 52ab6b0c3d..52ab6b0c3d 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_fast_timers.xml
+++ b/indra/newview/skins/default/xui/it/floater_fast_timers.xml
diff --git a/indra/newview/skins/default/xui/it/floater_font_test.xml b/indra/newview/skins/default/xui/it/floater_font_test.xml
index 859c068b11..859c068b11 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_font_test.xml
+++ b/indra/newview/skins/default/xui/it/floater_font_test.xml
diff --git a/indra/newview/skins/default/xui/it/floater_gesture.xml b/indra/newview/skins/default/xui/it/floater_gesture.xml
index b9419ebc22..b9419ebc22 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_gesture.xml
+++ b/indra/newview/skins/default/xui/it/floater_gesture.xml
diff --git a/indra/newview/skins/default/xui/it/floater_god_tools.xml b/indra/newview/skins/default/xui/it/floater_god_tools.xml
index 32c79936cf..32c79936cf 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_god_tools.xml
+++ b/indra/newview/skins/default/xui/it/floater_god_tools.xml
diff --git a/indra/newview/skins/default/xui/it/floater_goto_line.xml b/indra/newview/skins/default/xui/it/floater_goto_line.xml
new file mode 100644
index 0000000000..29a4aabb99
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/floater_goto_line.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="script goto" title="PASSA ALLA RIGA">
+ <button label="OK" label_selected="OK" name="goto_btn"/>
+ <text name="txt">
+ Passa alla riga
+ </text>
+</floater>
diff --git a/indra/newview/skins/default/xui/it/floater_hardware_settings.xml b/indra/newview/skins/default/xui/it/floater_hardware_settings.xml
index 5d3ae04a4d..edbbc354cf 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_hardware_settings.xml
+++ b/indra/newview/skins/default/xui/it/floater_hardware_settings.xml
@@ -25,6 +25,10 @@
Attiva VBO:
</text>
<check_box initial_value="true" label="Attiva oggetti OpenGL Vertex Buffer" name="vbo" tool_tip="Attivandolo su un hardware moderno aumenta la performance. Ma, su un vecchio hardware, spesso l&apos;implementazione dei VBO è scarsa e potresti avere dei crash quando è attivato."/>
+ <text name="tc label">
+ Attiva S3TC:
+ </text>
+ <check_box initial_value="true" label="Attiva compressione texture (richiede riavvio)" name="texture compression" tool_tip="Comprime le texture nella memoria video, consentendo il caricamento di texture a risoluzione maggiore al prezzo di ua perdita di qualit&apos; del colore."/>
<slider label="Memoria texture (MB):" name="GraphicsCardTextureMemory" tool_tip="Spazio di memoria da ssegnare alle textures. Utilizza la memoria della scheda video come impostazione predefinita. La riduzione di questa impostazione potrebbe migliorare il rendimento ma potrebbe anche rendere le texture poco definite."/>
<spinner label="Indice della distanza della nebbia:" name="fog"/>
<button label="OK" label_selected="OK" name="OK"/>
diff --git a/indra/newview/skins/default/xui/it/floater_help_browser.xml b/indra/newview/skins/default/xui/it/floater_help_browser.xml
index 008643afac..008643afac 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_help_browser.xml
+++ b/indra/newview/skins/default/xui/it/floater_help_browser.xml
diff --git a/indra/newview/skins/default/xui/it/floater_how_to.xml b/indra/newview/skins/default/xui/it/floater_how_to.xml
index 8f0e210571..8f0e210571 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_how_to.xml
+++ b/indra/newview/skins/default/xui/it/floater_how_to.xml
diff --git a/indra/newview/skins/default/xui/it/floater_hud.xml b/indra/newview/skins/default/xui/it/floater_hud.xml
index 437d2d6496..437d2d6496 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_hud.xml
+++ b/indra/newview/skins/default/xui/it/floater_hud.xml
diff --git a/indra/newview/skins/default/xui/it/floater_im_container.xml b/indra/newview/skins/default/xui/it/floater_im_container.xml
index fb8e77b32f..10cf1b7f7e 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_im_container.xml
+++ b/indra/newview/skins/default/xui/it/floater_im_container.xml
@@ -1,2 +1,29 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<multi_floater name="floater_im_box" title="CONVERSAZIONI"/>
+<multi_floater name="floater_im_box" title="CONVERSAZIONI">
+ <string name="collapse_icon" value="Conv_toolbar_collapse"/>
+ <string name="expand_icon" value="Conv_toolbar_expand"/>
+ <layout_stack name="conversations_stack">
+ <layout_panel name="conversations_layout_panel">
+ <layout_stack name="conversations_pane_buttons_stack">
+ <layout_panel name="conversations_pane_buttons_expanded">
+ <menu_button name="sort_btn" tool_tip="Opzioni Mostra/Ordina"/>
+ <button name="add_btn" tool_tip="Avvia una nuova conversazione"/>
+ <button name="speak_btn" tool_tip="Parla con le persone usando il microfono"/>
+ </layout_panel>
+ <layout_panel name="conversations_pane_buttons_collapsed">
+ <button name="expand_collapse_btn" tool_tip="Minimizza/espandi questo elenco"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ <layout_panel name="messages_layout_panel">
+ <panel_container name="im_box_tab_container">
+ <panel name="stub_panel">
+ <button name="stub_collapse_btn" tool_tip="Minimizza questo pannello"/>
+ <text name="stub_textbox">
+ Questa conversazione in una finestra separata. [secondlife:/// Ripristina conversazione.]
+ </text>
+ </panel>
+ </panel_container>
+ </layout_panel>
+ </layout_stack>
+</multi_floater>
diff --git a/indra/newview/skins/default/xui/it/floater_im_session.xml b/indra/newview/skins/default/xui/it/floater_im_session.xml
index 3d9d17fc81..71f90accde 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/it/floater_im_session.xml
@@ -1,8 +1,57 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="panel_im">
- <layout_stack name="im_panels">
- <layout_panel>
- <line_editor label="A" name="chat_editor"/>
- </layout_panel>
- </layout_stack>
+ <floater.string name="call_btn_start">
+ Conv_toolbar_open_call
+ </floater.string>
+ <floater.string name="call_btn_stop">
+ Conv_toolbar_hang_up
+ </floater.string>
+ <floater.string name="collapseline_icon" value="Conv_collapse_to_one_line"/>
+ <floater.string name="expandline_icon" value="Conv_expand_one_line"/>
+ <floater.string name="collapse_icon" value="Conv_toolbar_collapse"/>
+ <floater.string name="expand_icon" value="Conv_toolbar_expand"/>
+ <floater.string name="tear_off_icon" value="Conv_toolbar_arrow_ne"/>
+ <floater.string name="return_icon" value="Conv_toolbar_arrow_sw"/>
+ <floater.string name="participant_added" value="[NAME] è stato invitato alla conversazione."/>
+ <floater.string name="multiple_participants_added" value="[NAME] sono stati invitati alla conversazione."/>
+ <floater.string name="tooltip_to_separate_window" value="Sposta questa conversazione in una finestra separata."/>
+ <floater.string name="tooltip_to_main_window" value="Sposta questa conversazione di nuovo nella finestra principale"/>
+ <floater.string name="start_call_button_tooltip" value="Apri collegamento voce"/>
+ <floater.string name="end_call_button_tooltip" value="Chiudi collegamento voce"/>
+ <floater.string name="expcol_button_not_tearoff_tooltip" value="Minimizza questo pannello"/>
+ <floater.string name="expcol_button_tearoff_and_expanded_tooltip" value="Minimizza elenco partecipanti"/>
+ <floater.string name="expcol_button_tearoff_and_collapsed_tooltip" value="Espandi l&apos;elenco dei partecipanti"/>
+ <view name="contents_view">
+ <layout_stack name="main_stack">
+ <layout_panel name="toolbar_panel">
+ <menu_button name="view_options_btn" tool_tip="Opzioni Mostra/Ordina"/>
+ <menu_button name="gear_btn" tool_tip="Azioni per la persona selezionata:"/>
+ <button name="add_btn" tool_tip="Aggiungi qualcuno a questa conversazione"/>
+ <button name="voice_call_btn" tool_tip="Apri collegamento voce"/>
+ <button name="close_btn" tool_tip="Termina questa conversazione"/>
+ <button name="expand_collapse_btn" tool_tip="Minimizza/espandi questo pannello"/>
+ </layout_panel>
+ <layout_panel name="body_panel">
+ <layout_stack name="im_panels">
+ <layout_panel name="right_part_holder">
+ <layout_stack name="translate_and_chat_stack">
+ <layout_panel name="translate_chat_checkbox_lp">
+ <check_box label="Traduci chat" name="translate_chat_checkbox"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ <layout_panel name="chat_layout_panel">
+ <layout_stack name="input_panels">
+ <layout_panel name="input_editor_layout_panel">
+ <chat_editor label="A" name="chat_editor"/>
+ </layout_panel>
+ <layout_panel name="input_button_layout_panel">
+ <button name="minz_btn" tool_tip="Mostra/nascondi pannello messaggi"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
+ </view>
</floater>
diff --git a/indra/newview/skins/default/xui/it/floater_image_preview.xml b/indra/newview/skins/default/xui/it/floater_image_preview.xml
index ee7be7b155..ee7be7b155 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_image_preview.xml
+++ b/indra/newview/skins/default/xui/it/floater_image_preview.xml
diff --git a/indra/newview/skins/default/xui/it/floater_import_collada.xml b/indra/newview/skins/default/xui/it/floater_import_collada.xml
index eb4d0c0fdb..eb4d0c0fdb 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_import_collada.xml
+++ b/indra/newview/skins/default/xui/it/floater_import_collada.xml
diff --git a/indra/newview/skins/default/xui/it/floater_incoming_call.xml b/indra/newview/skins/default/xui/it/floater_incoming_call.xml
index a95ed44662..566920209d 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_incoming_call.xml
+++ b/indra/newview/skins/default/xui/it/floater_incoming_call.xml
@@ -10,7 +10,7 @@
anonimo
</floater.string>
<floater.string name="VoiceInviteP2P">
- sta chiamando.
+ ti sta chiamando.
</floater.string>
<floater.string name="VoiceInviteAdHoc">
ha aderito ad una chiamata in chat vocale in conferenza.
@@ -25,9 +25,9 @@
Vuoi abbandonare [CURRENT_CHAT] e aderire a questa voice chat?
</floater.string>
<text name="question">
- Vuoi abbandonare [CURRENT_CHAT] e aderire a questa voice chat?
+ Se rispondi, verrà interrotto il collegamento dalla conversazione a voce corrente.
</text>
- <button label="Accetta" label_selected="Accetta" name="Accept"/>
- <button label="Rifiuta" label_selected="Rifiuta" name="Reject"/>
- <button label="Inizia IM" name="Start IM"/>
+ <button label="Risposta" label_selected="Risposta" name="Accept"/>
+ <button label="Ignora" label_selected="Ignora" name="Reject"/>
+ <button label="Apri invece IM" name="Start IM"/>
</floater>
diff --git a/indra/newview/skins/default/xui/it/floater_inspect.xml b/indra/newview/skins/default/xui/it/floater_inspect.xml
index bae993d2be..bae993d2be 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_inspect.xml
+++ b/indra/newview/skins/default/xui/it/floater_inspect.xml
diff --git a/indra/newview/skins/default/xui/it/floater_inventory.xml b/indra/newview/skins/default/xui/it/floater_inventory.xml
deleted file mode 100644
index 2aa6795988..0000000000
--- a/indra/newview/skins/default/xui/it/floater_inventory.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Inventory" title="IL MIO INVENTARIO">
- <floater.string name="Title">
- IL MIO INVENTARIO
- </floater.string>
- <floater.string name="TitleFetching">
- IL MIO INVENTARIO (recupero di [ITEM_COUNT] articoli...) [FILTER]
- </floater.string>
- <floater.string name="TitleCompleted">
- IL MIO INVENTARIO ([ITEM_COUNT] articoli) [FILTER]
- </floater.string>
- <floater.string name="Fetched">
- Completato
- </floater.string>
- <panel label="Pannello dell&apos;Inventario" name="Inventory Panel"/>
-</floater>
diff --git a/indra/newview/skins/default/xui/it/floater_inventory_item_properties.xml b/indra/newview/skins/default/xui/it/floater_inventory_item_properties.xml
index 7ed3486b9b..7ed3486b9b 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_inventory_item_properties.xml
+++ b/indra/newview/skins/default/xui/it/floater_inventory_item_properties.xml
diff --git a/indra/newview/skins/default/xui/it/floater_inventory_view_finder.xml b/indra/newview/skins/default/xui/it/floater_inventory_view_finder.xml
index cf790ee62e..cf790ee62e 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_inventory_view_finder.xml
+++ b/indra/newview/skins/default/xui/it/floater_inventory_view_finder.xml
diff --git a/indra/newview/skins/default/xui/it/floater_joystick.xml b/indra/newview/skins/default/xui/it/floater_joystick.xml
index 3d60ded7ab..3d60ded7ab 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_joystick.xml
+++ b/indra/newview/skins/default/xui/it/floater_joystick.xml
diff --git a/indra/newview/skins/default/xui/it/floater_lagmeter.xml b/indra/newview/skins/default/xui/it/floater_lagmeter.xml
index f7b2b1ab4a..f7b2b1ab4a 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_lagmeter.xml
+++ b/indra/newview/skins/default/xui/it/floater_lagmeter.xml
diff --git a/indra/newview/skins/default/xui/it/floater_land_holdings.xml b/indra/newview/skins/default/xui/it/floater_land_holdings.xml
index 1b2f2605f7..1b2f2605f7 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_land_holdings.xml
+++ b/indra/newview/skins/default/xui/it/floater_land_holdings.xml
diff --git a/indra/newview/skins/default/xui/it/floater_live_lsleditor.xml b/indra/newview/skins/default/xui/it/floater_live_lsleditor.xml
index 0bd2b02323..0bd2b02323 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_live_lsleditor.xml
+++ b/indra/newview/skins/default/xui/it/floater_live_lsleditor.xml
diff --git a/indra/newview/skins/default/xui/it/floater_lsl_guide.xml b/indra/newview/skins/default/xui/it/floater_lsl_guide.xml
index 47fe2de051..47fe2de051 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_lsl_guide.xml
+++ b/indra/newview/skins/default/xui/it/floater_lsl_guide.xml
diff --git a/indra/newview/skins/default/xui/it/floater_map.xml b/indra/newview/skins/default/xui/it/floater_map.xml
index 5e4e4abca4..5e4e4abca4 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_map.xml
+++ b/indra/newview/skins/default/xui/it/floater_map.xml
diff --git a/indra/newview/skins/default/xui/it/floater_media_browser.xml b/indra/newview/skins/default/xui/it/floater_media_browser.xml
index 0a8c0f1c41..0a8c0f1c41 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_media_browser.xml
+++ b/indra/newview/skins/default/xui/it/floater_media_browser.xml
diff --git a/indra/newview/skins/default/xui/it/floater_media_settings.xml b/indra/newview/skins/default/xui/it/floater_media_settings.xml
index d521502a4c..d521502a4c 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_media_settings.xml
+++ b/indra/newview/skins/default/xui/it/floater_media_settings.xml
diff --git a/indra/newview/skins/default/xui/it/floater_mem_leaking.xml b/indra/newview/skins/default/xui/it/floater_mem_leaking.xml
index 63074d5a4c..63074d5a4c 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_mem_leaking.xml
+++ b/indra/newview/skins/default/xui/it/floater_mem_leaking.xml
diff --git a/indra/newview/skins/default/xui/it/floater_merchant_outbox.xml b/indra/newview/skins/default/xui/it/floater_merchant_outbox.xml
index 02f257d466..02f257d466 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_merchant_outbox.xml
+++ b/indra/newview/skins/default/xui/it/floater_merchant_outbox.xml
diff --git a/indra/newview/skins/default/xui/it/floater_model_preview.xml b/indra/newview/skins/default/xui/it/floater_model_preview.xml
index ca36fd2def..e8df4d2d4b 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_model_preview.xml
+++ b/indra/newview/skins/default/xui/it/floater_model_preview.xml
@@ -92,19 +92,54 @@
<text initial_value="Triangoli" name="triangles" value="Triangoli"/>
<text initial_value="Vertici" name="vertices" value="Vertici"/>
<text initial_value="Alto" name="high_label" value="Alto"/>
+ <combo_box name="lod_source_high">
+ <item name="Load from file" value="Carica da file"/>
+ <item name="Generate" value="Genera"/>
+ </combo_box>
<button label="Sfoglia..." name="lod_browse_high"/>
+ <combo_box name="lod_mode_high">
+ <item name="Triangle Limit" value="Limite triangoli"/>
+ <item name="Error Threshold" value="Limite errori"/>
+ </combo_box>
<text initial_value="0" name="high_triangles" value="0"/>
<text initial_value="0" name="high_vertices" value="0"/>
<text initial_value="Medio" name="medium_label" value="Medio"/>
+ <combo_box name="lod_source_medium">
+ <item name="Load from file" value="Carica da file"/>
+ <item name="Generate" value="Genera"/>
+ <item name="Use LoD above" value="Usa livello di dettaglio indicato in precedenza"/>
+ </combo_box>
<button label="Sfoglia..." name="lod_browse_medium"/>
+ <combo_box name="lod_mode_medium">
+ <item name="Triangle Limit" value="Limite triangoli"/>
+ <item name="Error Threshold" value="Limite errori"/>
+ </combo_box>
<text initial_value="0" name="medium_triangles" value="0"/>
<text initial_value="0" name="medium_vertices" value="0"/>
<text initial_value="Basso" name="low_label" value="Basso"/>
+ <combo_box name="lod_source_low">
+ <item name="Load from file" value="Carica da file"/>
+ <item name="Generate" value="Genera"/>
+ <item name="Use LoD above" value="Usa livello di dettaglio indicato in precedenza"/>
+ </combo_box>
<button label="Sfoglia..." name="lod_browse_low"/>
+ <combo_box name="lod_mode_low">
+ <item name="Triangle Limit" value="Limite triangoli"/>
+ <item name="Error Threshold" value="Limite errori"/>
+ </combo_box>
<text initial_value="0" name="low_triangles" value="0"/>
<text initial_value="0" name="low_vertices" value="0"/>
<text initial_value="Bassissimo" name="lowest_label" value="Bassissimo"/>
+ <combo_box name="lod_source_lowest">
+ <item name="Load from file" value="Carica da file"/>
+ <item name="Generate" value="Genera"/>
+ <item name="Use LoD above" value="Usa livello di dettaglio indicato in precedenza"/>
+ </combo_box>
<button label="Sfoglia..." name="lod_browse_lowest"/>
+ <combo_box name="lod_mode_lowest">
+ <item name="Triangle Limit" value="Limite triangoli"/>
+ <item name="Error Threshold" value="Limite errori"/>
+ </combo_box>
<text initial_value="0" name="lowest_triangles" value="0"/>
<text initial_value="0" name="lowest_vertices" value="0"/>
<check_box label="Genera normali" name="gen_normals"/>
diff --git a/indra/newview/skins/default/xui/it/floater_model_wizard.xml b/indra/newview/skins/default/xui/it/floater_model_wizard.xml
deleted file mode 100644
index ab5fdb29e4..0000000000
--- a/indra/newview/skins/default/xui/it/floater_model_wizard.xml
+++ /dev/null
@@ -1,208 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Model Wizard" title="PROCEDURA GUIDATA CARICA MODELLO">
- <button label="5. Carica sul server" name="upload_btn"/>
- <button label="4. Rivedi" name="review_btn"/>
- <button label="3. Fisica" name="physics_btn"/>
- <button label="2. Ottimizza" name="optimize_btn"/>
- <button label="1. Seleziona file" name="choose_file_btn"/>
- <panel name="choose_file_panel">
- <panel name="choose_file_header_panel">
- <text name="choose_file_header_text">
- Seleziona file modello
- </text>
- </panel>
- <panel name="choose_file_content">
- <text name="advanced_users_text">
- Utenti avanzati: Gli utenti che hanno dimestichezza con gli strumenti di creazione 3D possono usare le opzioni di caricamento avanzate.
- </text>
- <button label="Passa a modalità avanzata" name="switch_to_advanced"/>
- <text name="Cache location">
- Scegli il file del modello da caricare
- </text>
- <button label="Sfoglia..." label_selected="Sfoglia..." name="browse"/>
- <text name="Model types">
- Second Life supporta file COLLADA (.dae)
- </text>
- <text name="dimensions">
- X Y Z
- </text>
- <text name="warning_label">
- ATTENZIONE:
- </text>
- <text name="warning_text">
- Non sarà possibile completare il passaggio finale per il caricamento finale di questo modello sui server di Second Life. [secondlife:///app/floater/learn_more Scopri come] impostare l&apos;account per il caricamento di modelli con reticolo.
- </text>
- </panel>
- </panel>
- <panel name="optimize_panel">
- <panel name="optimize_header_panel">
- <text name="optimize_header_text">
- Ottimizza modello
- </text>
- </panel>
- <text name="optimize_description">
- Abbiamo ottimizzato il modello per migliorare le prestazioni. Se necessario, può essere regolato ulteriormente.
- </text>
- <panel name="optimize_content">
- <text name="high_detail_text">
- Genera livello di dettaglio: Alto
- </text>
- <text name="medium_detail_text">
- Genera livello di dettaglio: Medio
- </text>
- <text name="low_detail_text">
- Genera livello di dettaglio: Basso
- </text>
- <text name="lowest_detail_text">
- Genera livello di dettaglio: Bassissimo
- </text>
- </panel>
- <panel name="content2">
- <button label="Ricalcola geometria" name="recalculate_geometry_btn"/>
- <text name="lod_label">
- Anteprima geometria
- </text>
- <combo_box name="preview_lod_combo" tool_tip="Livello di dettaglio per anteprima rendering">
- <combo_item name="high">
- Molti dettagli
- </combo_item>
- <combo_item name="medium">
- Dettagli medi
- </combo_item>
- <combo_item name="low">
- Meno dettagli
- </combo_item>
- <combo_item name="lowest">
- Dettaglio minimo
- </combo_item>
- </combo_box>
- </panel>
- </panel>
- <panel name="physics_panel">
- <panel name="physics_header_panel">
- <text name="physics_header_text">
- Modifica fisica
- </text>
- </panel>
- <text name="physics_description">
- Verrà creata una forma per lo scafo esterno del modello. Regola il livello di dettaglio della forma in base al fine desiderato del modello.
- </text>
- <panel name="physics_content">
- <button label="Ricalcola fisica" name="recalculate_physics_btn"/>
- <button label="Ricalcolo in corso..." name="recalculating_physics_btn"/>
- <text name="lod_label">
- Anteprima fisica
- </text>
- <combo_box name="preview_lod_combo2" tool_tip="Livello di dettaglio per anteprima rendering">
- <combo_item name="high">
- Molti dettagli
- </combo_item>
- <combo_item name="medium">
- Dettagli medi
- </combo_item>
- <combo_item name="low">
- Meno dettagli
- </combo_item>
- <combo_item name="lowest">
- Dettaglio minimo
- </combo_item>
- </combo_box>
- </panel>
- </panel>
- <panel name="review_panel">
- <panel name="review_header_panel">
- <text name="review_header_text">
- Rivedi
- </text>
- </panel>
- <panel name="review_content">
- <text name="review_prim_equiv">
- Impatto sul lotto o sulla regione: [EQUIV] prim equivalenti
- </text>
- <text name="review_fee">
- All&apos;account verrà accreditata una tariffa di caricamento pari a L$ [FEE].
- </text>
- <text name="review_confirmation">
- Facendo clic sul pulsante Carica, confermi di possedere i diritti relativi ai materiali contenuti nel modello.
- </text>
- </panel>
- </panel>
- <panel name="upload_panel">
- <panel name="upload_header_panel">
- <text name="upload_header_text">
- Caricamento completato
- </text>
- </panel>
- <text name="model_uploaded_text">
- Il modello è stato caricato.
- </text>
- <text name="inventory_text">
- Puoi trovarlo nella cartella Oggetti nel tuo inventario.
- </text>
- <text name="charged_fee">
- La somma di L$ [FEE] è stata addebitata sul tuo account.
- </text>
- </panel>
- <button label="&lt;&lt; Indietro" name="back"/>
- <button label="Avanti &gt;&gt;" name="next"/>
- <button label="Calcolare pesi e tariffa &gt;&gt;" name="calculate"/>
- <button label="Calcolo in corso..." name="calculating"/>
- <button label="Carica" name="upload" tool_tip="Carica al simulatore"/>
- <button label="Annulla" name="cancel"/>
- <button label="Chiudi" name="close"/>
- <spinner name="import_scale" value="1.0"/>
- <string name="status_idle">
- Pausa
- </string>
- <string name="status_parse_error">
- Problema nell&apos;elaborazione DAE - vedi il registro per informazioni al riguardo.
- </string>
- <string name="status_reading_file">
- Caricamento in corso...
- </string>
- <string name="status_generating_meshes">
- Generazione reticoli...
- </string>
- <string name="status_vertex_number_overflow">
- Errore: numero di vertici maggiore di 65534, annullato.
- </string>
- <string name="bad_element">
- Errore: elemento non valido
- </string>
- <string name="high">
- Alto
- </string>
- <string name="medium">
- Medio
- </string>
- <string name="low">
- Basso
- </string>
- <string name="lowest">
- Bassissimo
- </string>
- <string name="mesh_status_good">
- Invia!
- </string>
- <string name="mesh_status_na">
- N/D
- </string>
- <string name="mesh_status_none">
- Nessuno
- </string>
- <string name="mesh_status_submesh_mismatch">
- Ai vari livelli del dettaglio corrispondono numeri diversi di faccette con texture.
- </string>
- <string name="mesh_status_mesh_mismatch">
- Ai vari livelli del dettaglio corrispondono numeri diversi istanze di reticoli.
- </string>
- <string name="mesh_status_too_many_vertices">
- Troppi vertici per il livello di dettaglio.
- </string>
- <string name="mesh_status_missing_lod">
- Livello di dettaglio minimo mancante.
- </string>
- <string name="layer_all">
- Tutto
- </string>
-</floater>
diff --git a/indra/newview/skins/default/xui/it/floater_moveview.xml b/indra/newview/skins/default/xui/it/floater_moveview.xml
index 1237bd06a9..1237bd06a9 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_moveview.xml
+++ b/indra/newview/skins/default/xui/it/floater_moveview.xml
diff --git a/indra/newview/skins/default/xui/it/floater_mute_object.xml b/indra/newview/skins/default/xui/it/floater_mute_object.xml
index dd1a2b67d7..dd1a2b67d7 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_mute_object.xml
+++ b/indra/newview/skins/default/xui/it/floater_mute_object.xml
diff --git a/indra/newview/skins/default/xui/it/floater_my_appearance.xml b/indra/newview/skins/default/xui/it/floater_my_appearance.xml
index 39ddd6186a..39ddd6186a 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_my_appearance.xml
+++ b/indra/newview/skins/default/xui/it/floater_my_appearance.xml
diff --git a/indra/newview/skins/default/xui/it/floater_my_inventory.xml b/indra/newview/skins/default/xui/it/floater_my_inventory.xml
index 0efd9f1c6d..0efd9f1c6d 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_my_inventory.xml
+++ b/indra/newview/skins/default/xui/it/floater_my_inventory.xml
diff --git a/indra/newview/skins/default/xui/it/floater_nearby_chat.xml b/indra/newview/skins/default/xui/it/floater_nearby_chat.xml
deleted file mode 100644
index 9e81899880..0000000000
--- a/indra/newview/skins/default/xui/it/floater_nearby_chat.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="nearby_chat" title="CHAT NEI DINTORNI">
- <check_box label="Traduci chat" name="translate_chat_checkbox"/>
-</floater>
diff --git a/indra/newview/skins/default/xui/it/floater_object_weights.xml b/indra/newview/skins/default/xui/it/floater_object_weights.xml
index fdcb732dee..fdcb732dee 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_object_weights.xml
+++ b/indra/newview/skins/default/xui/it/floater_object_weights.xml
diff --git a/indra/newview/skins/default/xui/it/floater_openobject.xml b/indra/newview/skins/default/xui/it/floater_openobject.xml
index d8144c7cd5..d8144c7cd5 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_openobject.xml
+++ b/indra/newview/skins/default/xui/it/floater_openobject.xml
diff --git a/indra/newview/skins/default/xui/it/floater_outfit_save_as.xml b/indra/newview/skins/default/xui/it/floater_outfit_save_as.xml
index 55bb5adb1e..55bb5adb1e 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_outfit_save_as.xml
+++ b/indra/newview/skins/default/xui/it/floater_outfit_save_as.xml
diff --git a/indra/newview/skins/default/xui/it/floater_outgoing_call.xml b/indra/newview/skins/default/xui/it/floater_outgoing_call.xml
index cdb180bacd..cdb180bacd 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_outgoing_call.xml
+++ b/indra/newview/skins/default/xui/it/floater_outgoing_call.xml
diff --git a/indra/newview/skins/default/xui/it/floater_pathfinding_characters.xml b/indra/newview/skins/default/xui/it/floater_pathfinding_characters.xml
new file mode 100755
index 0000000000..5122954edb
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/floater_pathfinding_characters.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="floater_pathfinding_characters" title="Personaggi con pathfinding">
+ <floater.string name="messaging_get_inprogress">
+ Ricerca personaggi con pathfinding in corso...
+ </floater.string>
+ <floater.string name="messaging_get_error">
+ Errore rilevato durante la ricerca di personaggi con pathfinding.
+ </floater.string>
+ <floater.string name="messaging_complete_none_found">
+ Nessun personaggio con pathfinding.
+ </floater.string>
+ <floater.string name="messaging_complete_available">
+ [NUM_SELECTED] personaggi selezionati su [NUM_TOTAL].
+ </floater.string>
+ <floater.string name="messaging_not_enabled">
+ In questa regione non è attivata la funzione pathfinding
+ </floater.string>
+ <floater.string name="character_cpu_time">
+ [CPU_TIME] µs
+ </floater.string>
+ <floater.string name="character_owner_loading">
+ [Caricamento in corso]
+ </floater.string>
+ <floater.string name="character_owner_unknown">
+ [Sconosciuto]
+ </floater.string>
+ <floater.string name="character_owner_group">
+ [gruppo]
+ </floater.string>
+ <panel>
+ <scroll_list name="objects_scroll_list">
+ <scroll_list.columns label="Nome" name="name"/>
+ <scroll_list.columns label="Descrizione" name="description"/>
+ <scroll_list.columns label="Proprietario" name="owner"/>
+ <scroll_list.columns label="CPU" name="cpu_time"/>
+ <scroll_list.columns label="Altitudine" name="altitude"/>
+ </scroll_list>
+ <text name="messaging_status">
+ Personaggi:
+ </text>
+ <button label="Aggiorna lista" name="refresh_objects_list"/>
+ <button label="Seleziona tutto" name="select_all_objects"/>
+ <button label="Non selezionare nessuno" name="select_none_objects"/>
+ </panel>
+ <panel>
+ <text name="actions_label">
+ Azioni per i personaggi selezionati:
+ </text>
+ <check_box label="Mostra marcatore" name="show_beacon"/>
+ <check_box label="Mostra capsula fisica" name="show_physics_capsule"/>
+ <button label="Prendi" name="take_objects"/>
+ <button label="Prendi copia" name="take_copy_objects"/>
+ <button label="Teletrasportami alla posizione" name="teleport_me_to_object" tool_tip="Attivato solo se viene selezionato un personaggio."/>
+ <button label="Restituisci" name="return_objects"/>
+ <button label="Elimina" name="delete_objects"/>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/it/floater_pathfinding_console.xml b/indra/newview/skins/default/xui/it/floater_pathfinding_console.xml
new file mode 100755
index 0000000000..77be220a2a
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/floater_pathfinding_console.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="floater_pathfinding_console" title="Visualizzazione / test pathfinding">
+ <floater.string name="navmesh_viewer_status_library_not_implemented">
+ Implementazione libreria percorsi non trovata.
+ </floater.string>
+ <floater.string name="navmesh_viewer_status_region_not_enabled">
+ In questa regione non è attivata la funzione pathfinding
+ </floater.string>
+ <floater.string name="navmesh_viewer_status_region_loading">
+ Attendere il caricamento della regione.
+ </floater.string>
+ <floater.string name="navmesh_viewer_status_checking_version">
+ Controllo stato navmesh
+ </floater.string>
+ <floater.string name="navmesh_viewer_status_downloading">
+ Scaricamento navmesh in corso
+ </floater.string>
+ <floater.string name="navmesh_viewer_status_updating">
+ Il navmesh è stato cambiato sul server. Scaricamento del navmesh più recente in corso
+ </floater.string>
+ <floater.string name="navmesh_viewer_status_has_navmesh">
+ Il navmesh più recente è stato scaricato.
+ </floater.string>
+ <floater.string name="navmesh_viewer_status_error">
+ Navmesh non scaricato correttamente.
+ </floater.string>
+ <floater.string name="navmesh_simulator_status_pending">
+ Il navmesh ha modifiche in sospeso.
+ </floater.string>
+ <floater.string name="navmesh_simulator_status_building">
+ Costruzione navmesh in corso.
+ </floater.string>
+ <floater.string name="navmesh_simulator_status_some_pending">
+ Alcune regioni navmesh hanno modifiche in sospeso.
+ </floater.string>
+ <floater.string name="navmesh_simulator_status_some_building">
+ La costruzione di alcune regioni navmesh è in corso.
+ </floater.string>
+ <floater.string name="navmesh_simulator_status_pending_and_building">
+ Alcune regioni navmesh hanno modifiche in sospeso e in altre la costruzione è in corso.
+ </floater.string>
+ <floater.string name="navmesh_simulator_status_complete">
+ Navmesh è aggiornato.
+ </floater.string>
+ <floater.string name="pathing_library_not_implemented">
+ Implementazione libreria percorsi non trovata.
+ </floater.string>
+ <floater.string name="pathing_region_not_enabled">
+ In questa regione non è attivata la funzione pathfinding
+ </floater.string>
+ <floater.string name="pathing_choose_start_and_end_points">
+ Seleziona punti iniziale e finale.
+ </floater.string>
+ <floater.string name="pathing_choose_start_point">
+ Seleziona punto iniziale.
+ </floater.string>
+ <floater.string name="pathing_choose_end_point">
+ Seleziona punto finale.
+ </floater.string>
+ <floater.string name="pathing_path_valid">
+ Il percorso viene visualizzato con il colore arancione.
+ </floater.string>
+ <floater.string name="pathing_path_invalid">
+ Nessun percorso trovato tra i punti selezionati.
+ </floater.string>
+ <floater.string name="pathing_error">
+ Si è verificato un errore durante la generazione del percorso.
+ </floater.string>
+ <tab_container name="view_test_tab_container">
+ <panel label="Visuale" name="view_panel">
+ <text name="show_label">
+ Mostra:
+ </text>
+ <check_box label="Mondo" name="show_world"/>
+ <check_box label="Solo elementi spostabili" name="show_world_movables_only"/>
+ <check_box label="Navmesh" name="show_navmesh"/>
+ <text name="show_walkability_label">
+ Mostra mappa camminabilità:
+ </text>
+ <combo_box name="show_heatmap_mode">
+ <combo_box.item label="Non mostrare" name="show_heatmap_mode_none"/>
+ <combo_box.item label="Personaggio tipo A" name="show_heatmap_mode_a"/>
+ <combo_box.item label="Personaggio tipo B" name="show_heatmap_mode_b"/>
+ <combo_box.item label="Personaggio tipo C" name="show_heatmap_mode_c"/>
+ <combo_box.item label="Personaggio tipo D" name="show_heatmap_mode_d"/>
+ </combo_box>
+ <check_box label="Camminabili" name="show_walkables"/>
+ <check_box label="Volumi materiali" name="show_material_volumes"/>
+ <check_box label="Ostacoli statici" name="show_static_obstacles"/>
+ <check_box label="Volumi esclusioni" name="show_exclusion_volumes"/>
+ <check_box label="Piano acqua" name="show_water_plane"/>
+ <check_box label="Con vista a raggi X" name="show_xray"/>
+ </panel>
+ <panel label="Percorso test" name="test_panel">
+ <text name="ctrl_click_label">
+ Seleziona il punto iniziale premendo Ctrl e facendo clic.
+ </text>
+ <text name="shift_click_label">
+ Seleziona il punto finale premendo Maiusc e facendo clic.
+ </text>
+ <text name="character_width_label">
+ Larghezza personaggio
+ </text>
+ <slider name="character_width" value="1"/>
+ <text name="character_width_unit_label">
+ m
+ </text>
+ <text name="character_type_label">
+ Tipo personaggio
+ </text>
+ <combo_box name="path_character_type">
+ <combo_box.item label="Nessuno" name="path_character_type_none"/>
+ <combo_box.item label="A" name="path_character_type_a"/>
+ <combo_box.item label="B" name="path_character_type_b"/>
+ <combo_box.item label="C" name="path_character_type_c"/>
+ <combo_box.item label="D" name="path_character_type_d"/>
+ </combo_box>
+ <button label="Cancella percorso" name="clear_path"/>
+ </panel>
+ </tab_container>
+</floater>
diff --git a/indra/newview/skins/default/xui/it/floater_pathfinding_linksets.xml b/indra/newview/skins/default/xui/it/floater_pathfinding_linksets.xml
new file mode 100755
index 0000000000..7edac3ff46
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/floater_pathfinding_linksets.xml
@@ -0,0 +1,167 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="floater_pathfinding_linksets" title="Set collegati pathfinding">
+ <floater.string name="messaging_get_inprogress">
+ Ricerca set collegati pathfinding in corso...
+ </floater.string>
+ <floater.string name="messaging_get_error">
+ Errore rilevato durante la ricerca di set collegati pathfinding.
+ </floater.string>
+ <floater.string name="messaging_set_inprogress">
+ Modifica set collegati pathfinding selezionati in corso...
+ </floater.string>
+ <floater.string name="messaging_set_error">
+ Errore rilevato durante la modifica dei set collegati pathfinding selezionati.
+ </floater.string>
+ <floater.string name="messaging_complete_none_found">
+ Nessun set collegato con pathfinding.
+ </floater.string>
+ <floater.string name="messaging_complete_available">
+ [NUM_SELECTED] set collegati selezionati su [NUM_TOTAL].
+ </floater.string>
+ <floater.string name="messaging_not_enabled">
+ In questa regione non è attivata la funzione pathfinding
+ </floater.string>
+ <floater.string name="linkset_terrain_name">
+ [Terreno]
+ </floater.string>
+ <floater.string name="linkset_terrain_description">
+ --
+ </floater.string>
+ <floater.string name="linkset_terrain_owner">
+ --
+ </floater.string>
+ <floater.string name="linkset_terrain_scripted">
+ --
+ </floater.string>
+ <floater.string name="linkset_terrain_land_impact">
+ --
+ </floater.string>
+ <floater.string name="linkset_terrain_dist_from_you">
+ --
+ </floater.string>
+ <floater.string name="linkset_owner_loading">
+ [Caricamento in corso]
+ </floater.string>
+ <floater.string name="linkset_owner_unknown">
+ [Sconosciuto]
+ </floater.string>
+ <floater.string name="linkset_owner_group">
+ [gruppo]
+ </floater.string>
+ <floater.string name="linkset_is_scripted">
+ Sì
+ </floater.string>
+ <floater.string name="linkset_is_not_scripted">
+ No
+ </floater.string>
+ <floater.string name="linkset_is_unknown_scripted">
+ Sconosciuto
+ </floater.string>
+ <floater.string name="linkset_use_walkable">
+ Camminabile
+ </floater.string>
+ <floater.string name="linkset_use_static_obstacle">
+ Ostacolo statico
+ </floater.string>
+ <floater.string name="linkset_use_dynamic_obstacle">
+ Ostacolo mobile
+ </floater.string>
+ <floater.string name="linkset_use_material_volume">
+ Volume materiale
+ </floater.string>
+ <floater.string name="linkset_use_exclusion_volume">
+ Volume esclusione
+ </floater.string>
+ <floater.string name="linkset_use_dynamic_phantom">
+ Oggetto fantasma mobile
+ </floater.string>
+ <floater.string name="linkset_is_terrain">
+ [non modificabile]
+ </floater.string>
+ <floater.string name="linkset_is_restricted_state">
+ [limitato]
+ </floater.string>
+ <floater.string name="linkset_is_non_volume_state">
+ [concavo]
+ </floater.string>
+ <floater.string name="linkset_is_restricted_non_volume_state">
+ [limitato,concavo]
+ </floater.string>
+ <floater.string name="linkset_choose_use">
+ Seleziona uso set collegati...
+ </floater.string>
+ <panel>
+ <combo_box name="filter_by_linkset_use">
+ <combo_box.item label="Filtra in base all&apos;uso set collegati..." name="filter_by_linkset_use_none"/>
+ <combo_box.item label="Camminabile" name="filter_by_linkset_use_walkable"/>
+ <combo_box.item label="Ostacolo statico" name="filter_by_linkset_use_static_obstacle"/>
+ <combo_box.item label="Ostacolo mobile" name="filter_by_linkset_use_dynamic_obstacle"/>
+ <combo_box.item label="Volume materiale" name="filter_by_linkset_use_material_volume"/>
+ <combo_box.item label="Volume esclusione" name="filter_by_linkset_use_exclusion_volume"/>
+ <combo_box.item label="Oggetto fantasma mobile" name="filter_by_linkset_use_dynamic_phantom"/>
+ </combo_box>
+ <button label="Applica" name="apply_filters"/>
+ <button label="Cancella" name="clear_filters"/>
+ <scroll_list name="objects_scroll_list">
+ <scroll_list.columns label="Nome (prim principale)" name="name"/>
+ <scroll_list.columns label="Descrizione (prim principale)" name="description"/>
+ <scroll_list.columns label="Proprietario" name="owner"/>
+ <scroll_list.columns label="Scriptato" name="scripted"/>
+ <scroll_list.columns label="Impatto" name="land_impact"/>
+ <scroll_list.columns label="Distanza" name="dist_from_you"/>
+ <scroll_list.columns label="Uso set collegati" name="linkset_use"/>
+ <scroll_list.columns label="A %" name="a_percent"/>
+ <scroll_list.columns label="B %" name="b_percent"/>
+ <scroll_list.columns label="C %" name="c_percent"/>
+ <scroll_list.columns label="D %" name="d_percent"/>
+ </scroll_list>
+ <text name="messaging_status">
+ Set collegati:
+ </text>
+ <button label="Aggiorna lista" name="refresh_objects_list"/>
+ <button label="Seleziona tutto" name="select_all_objects"/>
+ <button label="Non selezionare nessuno" name="select_none_objects"/>
+ </panel>
+ <panel>
+ <check_box label="Mostra marcatore" name="show_beacon"/>
+ <button label="Prendi" name="take_objects"/>
+ <button label="Prendi copia" name="take_copy_objects"/>
+ <button label="Teletrasportami alla posizione" name="teleport_me_to_object"/>
+ <button label="Restituisci" name="return_objects"/>
+ <button label="Elimina" name="delete_objects"/>
+ </panel>
+ <panel>
+ <text name="walkability_coefficients_label">
+ Camminabilità:
+ </text>
+ <text name="edit_a_label">
+ A
+ </text>
+ <line_editor name="edit_a_value" tool_tip="Camminabilità per personaggi di tipo A. Umanoide è un esempio del tipo di personaggio."/>
+ <text name="edit_b_label">
+ B
+ </text>
+ <line_editor name="edit_b_value" tool_tip="Camminabilità per personaggi di tipo B. Creatura è un esempio del tipo di personaggio."/>
+ <text name="edit_c_label">
+ C
+ </text>
+ <line_editor name="edit_c_value" tool_tip="Camminabilità per personaggi di tipo C. Elemento meccanico è un esempio del tipo di personaggio."/>
+ <text name="edit_d_label">
+ D
+ </text>
+ <line_editor name="edit_d_value" tool_tip="Camminabilità per personaggi di tipo D. Altro è un esempio del tipo di personaggio."/>
+ <button label="Applica modifiche" name="apply_edit_values"/>
+ <text name="suggested_use_a_label">
+ (Umanoide)
+ </text>
+ <text name="suggested_use_b_label">
+ (Creatura)
+ </text>
+ <text name="suggested_use_c_label">
+ (Elemento meccanico)
+ </text>
+ <text name="suggested_use_d_label">
+ (Altro)
+ </text>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/it/floater_pay.xml b/indra/newview/skins/default/xui/it/floater_pay.xml
index 5753c8c765..5753c8c765 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_pay.xml
+++ b/indra/newview/skins/default/xui/it/floater_pay.xml
diff --git a/indra/newview/skins/default/xui/it/floater_pay_object.xml b/indra/newview/skins/default/xui/it/floater_pay_object.xml
index 8805f3208e..8805f3208e 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_pay_object.xml
+++ b/indra/newview/skins/default/xui/it/floater_pay_object.xml
diff --git a/indra/newview/skins/default/xui/it/floater_people.xml b/indra/newview/skins/default/xui/it/floater_people.xml
index 1acc3cbf19..1acc3cbf19 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_people.xml
+++ b/indra/newview/skins/default/xui/it/floater_people.xml
diff --git a/indra/newview/skins/default/xui/it/floater_perm_prefs.xml b/indra/newview/skins/default/xui/it/floater_perm_prefs.xml
index a02b3b5075..a02b3b5075 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_perm_prefs.xml
+++ b/indra/newview/skins/default/xui/it/floater_perm_prefs.xml
diff --git a/indra/newview/skins/default/xui/it/floater_picks.xml b/indra/newview/skins/default/xui/it/floater_picks.xml
index dfc539da66..dfc539da66 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_picks.xml
+++ b/indra/newview/skins/default/xui/it/floater_picks.xml
diff --git a/indra/newview/skins/default/xui/it/floater_places.xml b/indra/newview/skins/default/xui/it/floater_places.xml
index cd46cf8b59..cd46cf8b59 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_places.xml
+++ b/indra/newview/skins/default/xui/it/floater_places.xml
diff --git a/indra/newview/skins/default/xui/it/floater_post_process.xml b/indra/newview/skins/default/xui/it/floater_post_process.xml
index 3aa8b29101..3aa8b29101 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_post_process.xml
+++ b/indra/newview/skins/default/xui/it/floater_post_process.xml
diff --git a/indra/newview/skins/default/xui/it/floater_postcard.xml b/indra/newview/skins/default/xui/it/floater_postcard.xml
deleted file mode 100644
index cb2916268a..0000000000
--- a/indra/newview/skins/default/xui/it/floater_postcard.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Postcard" title="INVIA FOTO VIA E-MAIL">
- <text name="to_label" width="135">
- Email del destinatario:
- </text>
- <line_editor left="143" name="to_form" width="127"/>
- <text name="from_label">
- La tua email:
- </text>
- <line_editor left="143" name="from_form" width="127"/>
- <text name="name_label">
- Il tuo nome:
- </text>
- <line_editor left="143" name="name_form" width="127"/>
- <text name="subject_label">
- Soggetto:
- </text>
- <line_editor left="143" name="subject_form" width="127"/>
- <line_editor label="Scrivi il soggetto qui." name="subject_form"/>
- <text name="msg_label">
- Messaggio:
- </text>
- <text_editor name="msg_form">
- Scrivi il messaggio qui.
- </text_editor>
- <text name="fine_print">
- Se il tuo destinatario si registrerà in [SECOND_LIFE], riceverai il relativo bonus.
- </text>
- <button label="Annulla" name="cancel_btn"/>
- <button label="Invia" name="send_btn"/>
- <string name="default_subject">
- Cartolina da [SECOND_LIFE].
- </string>
- <string name="default_message">
- Vieni a vedere!
- </string>
- <string name="upload_message">
- Invio...
- </string>
-</floater>
diff --git a/indra/newview/skins/default/xui/it/floater_preferences.xml b/indra/newview/skins/default/xui/it/floater_preferences.xml
index 7a1d2966ed..7a1d2966ed 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_preferences.xml
+++ b/indra/newview/skins/default/xui/it/floater_preferences.xml
diff --git a/indra/newview/skins/default/xui/it/floater_preferences_proxy.xml b/indra/newview/skins/default/xui/it/floater_preferences_proxy.xml
index 86ea8064b1..86ea8064b1 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_preferences_proxy.xml
+++ b/indra/newview/skins/default/xui/it/floater_preferences_proxy.xml
diff --git a/indra/newview/skins/default/xui/it/floater_preview_animation.xml b/indra/newview/skins/default/xui/it/floater_preview_animation.xml
index ed609c70fa..ed609c70fa 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_preview_animation.xml
+++ b/indra/newview/skins/default/xui/it/floater_preview_animation.xml
diff --git a/indra/newview/skins/default/xui/it/floater_preview_gesture.xml b/indra/newview/skins/default/xui/it/floater_preview_gesture.xml
index 2172b9848b..2172b9848b 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_preview_gesture.xml
+++ b/indra/newview/skins/default/xui/it/floater_preview_gesture.xml
diff --git a/indra/newview/skins/default/xui/it/floater_preview_notecard.xml b/indra/newview/skins/default/xui/it/floater_preview_notecard.xml
index 7ec229f9d3..7ec229f9d3 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_preview_notecard.xml
+++ b/indra/newview/skins/default/xui/it/floater_preview_notecard.xml
diff --git a/indra/newview/skins/default/xui/it/floater_preview_sound.xml b/indra/newview/skins/default/xui/it/floater_preview_sound.xml
index 8eb9573e54..8eb9573e54 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_preview_sound.xml
+++ b/indra/newview/skins/default/xui/it/floater_preview_sound.xml
diff --git a/indra/newview/skins/default/xui/it/floater_preview_texture.xml b/indra/newview/skins/default/xui/it/floater_preview_texture.xml
index 5b4054514e..5b4054514e 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_preview_texture.xml
+++ b/indra/newview/skins/default/xui/it/floater_preview_texture.xml
diff --git a/indra/newview/skins/default/xui/it/floater_price_for_listing.xml b/indra/newview/skins/default/xui/it/floater_price_for_listing.xml
index 06c838a981..06c838a981 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_price_for_listing.xml
+++ b/indra/newview/skins/default/xui/it/floater_price_for_listing.xml
diff --git a/indra/newview/skins/default/xui/it/floater_publish_classified.xml b/indra/newview/skins/default/xui/it/floater_publish_classified.xml
index c371e28caa..c371e28caa 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_publish_classified.xml
+++ b/indra/newview/skins/default/xui/it/floater_publish_classified.xml
diff --git a/indra/newview/skins/default/xui/it/floater_region_debug_console.xml b/indra/newview/skins/default/xui/it/floater_region_debug_console.xml
index 6efa10290b..6efa10290b 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_region_debug_console.xml
+++ b/indra/newview/skins/default/xui/it/floater_region_debug_console.xml
diff --git a/indra/newview/skins/default/xui/it/floater_region_info.xml b/indra/newview/skins/default/xui/it/floater_region_info.xml
index dc2c24ca56..dc2c24ca56 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_region_info.xml
+++ b/indra/newview/skins/default/xui/it/floater_region_info.xml
diff --git a/indra/newview/skins/default/xui/it/floater_report_abuse.xml b/indra/newview/skins/default/xui/it/floater_report_abuse.xml
index eeba54b0ca..eeba54b0ca 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_report_abuse.xml
+++ b/indra/newview/skins/default/xui/it/floater_report_abuse.xml
diff --git a/indra/newview/skins/default/xui/it/floater_script_debug.xml b/indra/newview/skins/default/xui/it/floater_script_debug.xml
index 89bf80da5e..89bf80da5e 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_script_debug.xml
+++ b/indra/newview/skins/default/xui/it/floater_script_debug.xml
diff --git a/indra/newview/skins/default/xui/it/floater_script_debug_panel.xml b/indra/newview/skins/default/xui/it/floater_script_debug_panel.xml
index e70a30fa24..e70a30fa24 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_script_debug_panel.xml
+++ b/indra/newview/skins/default/xui/it/floater_script_debug_panel.xml
diff --git a/indra/newview/skins/default/xui/it/floater_script_limits.xml b/indra/newview/skins/default/xui/it/floater_script_limits.xml
index 2383b85bb7..2383b85bb7 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_script_limits.xml
+++ b/indra/newview/skins/default/xui/it/floater_script_limits.xml
diff --git a/indra/newview/skins/default/xui/it/floater_script_preview.xml b/indra/newview/skins/default/xui/it/floater_script_preview.xml
index d007774f43..d007774f43 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_script_preview.xml
+++ b/indra/newview/skins/default/xui/it/floater_script_preview.xml
diff --git a/indra/newview/skins/default/xui/it/floater_script_queue.xml b/indra/newview/skins/default/xui/it/floater_script_queue.xml
index f4117d30a2..f4117d30a2 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_script_queue.xml
+++ b/indra/newview/skins/default/xui/it/floater_script_queue.xml
diff --git a/indra/newview/skins/default/xui/it/floater_script_search.xml b/indra/newview/skins/default/xui/it/floater_script_search.xml
index 3d0b02877e..3d0b02877e 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_script_search.xml
+++ b/indra/newview/skins/default/xui/it/floater_script_search.xml
diff --git a/indra/newview/skins/default/xui/it/floater_search.xml b/indra/newview/skins/default/xui/it/floater_search.xml
index ac3dc17aa3..ac3dc17aa3 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_search.xml
+++ b/indra/newview/skins/default/xui/it/floater_search.xml
diff --git a/indra/newview/skins/default/xui/it/floater_select_key.xml b/indra/newview/skins/default/xui/it/floater_select_key.xml
index 014bc76ffb..014bc76ffb 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_select_key.xml
+++ b/indra/newview/skins/default/xui/it/floater_select_key.xml
diff --git a/indra/newview/skins/default/xui/it/floater_sell_land.xml b/indra/newview/skins/default/xui/it/floater_sell_land.xml
index 106ae0373c..106ae0373c 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_sell_land.xml
+++ b/indra/newview/skins/default/xui/it/floater_sell_land.xml
diff --git a/indra/newview/skins/default/xui/it/floater_settings_debug.xml b/indra/newview/skins/default/xui/it/floater_settings_debug.xml
index 489d52d3b8..489d52d3b8 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_settings_debug.xml
+++ b/indra/newview/skins/default/xui/it/floater_settings_debug.xml
diff --git a/indra/newview/skins/default/xui/it/floater_snapshot.xml b/indra/newview/skins/default/xui/it/floater_snapshot.xml
index bff6081bdf..bff6081bdf 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_snapshot.xml
+++ b/indra/newview/skins/default/xui/it/floater_snapshot.xml
diff --git a/indra/newview/skins/default/xui/it/floater_sound_devices.xml b/indra/newview/skins/default/xui/it/floater_sound_devices.xml
index 9799b48d89..9799b48d89 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_sound_devices.xml
+++ b/indra/newview/skins/default/xui/it/floater_sound_devices.xml
diff --git a/indra/newview/skins/default/xui/it/floater_sound_preview.xml b/indra/newview/skins/default/xui/it/floater_sound_preview.xml
index 221e5e5b53..221e5e5b53 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_sound_preview.xml
+++ b/indra/newview/skins/default/xui/it/floater_sound_preview.xml
diff --git a/indra/newview/skins/default/xui/it/floater_spellcheck.xml b/indra/newview/skins/default/xui/it/floater_spellcheck.xml
new file mode 100755
index 0000000000..2a8557b0fc
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/floater_spellcheck.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="spellcheck_floater" title="Impostazioni controllo ortografico">
+ <check_box label="Attiva controllo ortografico" name="spellcheck_enable"/>
+ <text name="spellcheck_main">
+ Dizionario principale:
+ </text>
+ <text label="Registri:" name="spellcheck_additional">
+ Dizionari aggiuntivi:
+ </text>
+ <text name="spellcheck_available">
+ Disponibile
+ </text>
+ <text name="spellcheck_active">
+ Attivato
+ </text>
+ <button label="Rimuovi" name="spellcheck_remove_btn"/>
+ <button label="Importa..." name="spellcheck_import_btn"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/it/floater_spellcheck_import.xml b/indra/newview/skins/default/xui/it/floater_spellcheck_import.xml
new file mode 100755
index 0000000000..c04fc249a7
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/floater_spellcheck_import.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="spellcheck_import" title="Imposta dizionario">
+ <button label="Sfoglia" label_selected="Sfoglia" name="dictionary_path_browse"/>
+ <button label="Importa" name="ok_btn"/>
+ <button label="Annulla" name="cancel_btn"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/it/floater_stats.xml b/indra/newview/skins/default/xui/it/floater_stats.xml
index ad6ef6b54b..825b2ce57a 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_stats.xml
+++ b/indra/newview/skins/default/xui/it/floater_stats.xml
@@ -14,8 +14,11 @@
<stat_bar label="KTris disegnato per secondo" name="ktrissec"/>
<stat_bar label="Totale oggetti" name="objs"/>
<stat_bar label="Nuovi oggetti" name="newobjs"/>
+ <stat_bar label="Hit rate della cache per l&apos;oggetto" name="object_cache_hits"/>
</stat_view>
<stat_view label="Texture" name="texture">
+ <stat_bar label="Hit rate della cache" name="texture_cache_hits"/>
+ <stat_bar label="Latenza di lettura della cache" name="texture_cache_read_latency"/>
<stat_bar label="Conteggio" name="numimagesstat"/>
<stat_bar label="Conteggio grezzo" name="numrawimagesstat"/>
<stat_bar label="Memoria GL" name="gltexmemstat"/>
@@ -44,6 +47,12 @@
<stat_bar label="Oggetti a basso LOD" name="physicslodtasks"/>
<stat_bar label="Memoria allocata" name="physicsmemoryallocated"/>
</stat_view>
+ <stat_bar label="Script eseguiti" name="simpctscriptsrun"/>
+ <stat_view label="Pathfinding" name="simpathfinding">
+ <stat_bar label="Tempo passaggio AI" name="simsimaistepmsec"/>
+ <stat_bar label="Passaggi silhouette saltati" name="simsimskippedsilhouettesteps"/>
+ <stat_bar label="Personaggi aggiornati" name="simsimpctsteppedcharacters"/>
+ </stat_view>
<stat_view label="Tempo (ms)" name="simperf">
<stat_bar label="Tempo totale Frame" name="simframemsec"/>
<stat_bar label="Tempo netto" name="simnetmsec"/>
diff --git a/indra/newview/skins/default/xui/it/floater_sys_well.xml b/indra/newview/skins/default/xui/it/floater_sys_well.xml
index e1c0b89902..e1c0b89902 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_sys_well.xml
+++ b/indra/newview/skins/default/xui/it/floater_sys_well.xml
diff --git a/indra/newview/skins/default/xui/it/floater_telehub.xml b/indra/newview/skins/default/xui/it/floater_telehub.xml
index 15312a8959..15312a8959 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_telehub.xml
+++ b/indra/newview/skins/default/xui/it/floater_telehub.xml
diff --git a/indra/newview/skins/default/xui/it/floater_test_layout_stacks.xml b/indra/newview/skins/default/xui/it/floater_test_layout_stacks.xml
index b479d5f6d6..b479d5f6d6 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_test_layout_stacks.xml
+++ b/indra/newview/skins/default/xui/it/floater_test_layout_stacks.xml
diff --git a/indra/newview/skins/default/xui/it/floater_test_text_vertical_aligment.xml b/indra/newview/skins/default/xui/it/floater_test_text_vertical_aligment.xml
index 23da6f7588..23da6f7588 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_test_text_vertical_aligment.xml
+++ b/indra/newview/skins/default/xui/it/floater_test_text_vertical_aligment.xml
diff --git a/indra/newview/skins/default/xui/it/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/it/floater_texture_ctrl.xml
index 7b77584ba0..27a17868a7 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_texture_ctrl.xml
+++ b/indra/newview/skins/default/xui/it/floater_texture_ctrl.xml
@@ -1,23 +1,35 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="texture picker" title="PREFERITO: TEXTURE">
- <string name="choose_picture">
+ <floater.string name="choose_picture">
Clicca per scegliere l&apos;immagine
- </string>
+ </floater.string>
+ <floater.string name="pick title">
+ Scegli:
+ </floater.string>
<text name="Multiple">
Texture multiple
</text>
+ <radio_group name="mode_selection">
+ <radio_item label="Inventario" name="inventory" value="0"/>
+ <radio_item label="Locale" name="local" value="1"/>
+ </radio_group>
<text name="unknown">
Dimensioni: [DIMENSIONS]
</text>
<button label="Default" label_selected="Default" name="Default"/>
- <button label="Niente" label_selected="Niente" name="None"/>
<button label="Vuoto" label_selected="Vuoto" name="Blank"/>
- <check_box label="Mostra cartelle" name="show_folders_check"/>
- <search_editor label="Filtro texture" name="inventory search editor"/>
- <check_box label="Applica adesso" name="apply_immediate_check"/>
- <button label="Annulla" label_selected="Annulla" name="Cancel"/>
+ <button label="Niente" label_selected="Niente" name="None"/>
+ <check_box initial_value="true" label="Applica adesso" name="apply_immediate_check"/>
+ <text name="preview_disabled" value="Anteprima disattivata"/>
+ <filter_editor label="Filtro texture" name="inventory search editor"/>
+ <check_box initial_value="false" label="Mostra cartelle" name="show_folders_check"/>
+ <button label="Aggiungi" label_selected="Aggiungi" name="l_add_btn"/>
+ <button label="Rimuovi" label_selected="Rimuovi" name="l_rem_btn"/>
+ <button label="Carica" label_selected="Carica" name="l_upl_btn"/>
+ <scroll_list name="l_name_list">
+ <column label="Nome" name="unit_name"/>
+ <column label="ID" name="unit_id_HIDDEN"/>
+ </scroll_list>
<button label="OK" label_selected="OK" name="Select"/>
- <string name="pick title">
- Scegli:
- </string>
+ <button label="Annulla" label_selected="Annulla" name="Cancel"/>
</floater>
diff --git a/indra/newview/skins/default/xui/it/floater_texture_fetch_debugger.xml b/indra/newview/skins/default/xui/it/floater_texture_fetch_debugger.xml
new file mode 100755
index 0000000000..49b6453319
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/floater_texture_fetch_debugger.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="TexFetchDebugger" title="Debugger recupero texture">
+ <text name="total_num_fetched_label">
+ 1, Numero totale di texture recuperate: [NUM]
+ </text>
+ <text name="total_num_fetching_requests_label">
+ 2, Numero totale di richieste di recupero: [NUM]
+ </text>
+ <text name="total_num_cache_hits_label">
+ 3, Numero totale di recuperi dalla cache: [NUM]
+ </text>
+ <text name="total_num_visible_tex_label">
+ 4, Numero totale di texture visibili: [NUM]
+ </text>
+ <text name="total_num_visible_tex_fetch_req_label">
+ 5, Numero totale di richieste di fetching texture visibili: [NUM]
+ </text>
+ <text name="total_fetched_data_label">
+ 6, Numero totale di fetching dati: [SIZE1] KB, Dati decodificati: [SIZE2] KB, [PIXEL] MPixel
+ </text>
+ <text name="total_fetched_vis_data_label">
+ 7, Numero totale di dati visibili: [SIZE1] KB, Dati decodificati: [SIZE2] KB
+ </text>
+ <text name="total_fetched_rendered_data_label">
+ 8, Numero totale di rendering dei dati: [SIZE1] KB, Dati decodificati: [SIZE2] KB, [PIXEL] MPixel
+ </text>
+ <text name="total_time_cache_read_label">
+ 9, Tempo totale letture cache: [TIME] secondi
+ </text>
+ <text name="total_time_cache_write_label">
+ 10, Tempo totale scrittura cache: [TIME] secondi
+ </text>
+ <text name="total_time_decode_label">
+ 11, Tempo totale decodifica: [TIME] secondi
+ </text>
+ <text name="total_time_gl_label">
+ 12, Tempo totale creazione texture gl: [TIME] secondi
+ </text>
+ <text name="total_time_http_label">
+ 13, Tempo totale fetching HTTP: [TIME] secondi
+ </text>
+ <text name="total_time_fetch_label">
+ 14, Tempo totale complessivo fetching: [TIME] secondi
+ </text>
+ <text name="total_time_refetch_vis_cache_label">
+ 15, Nuovo fetching elementi visibili dalla cache, Tempo: [TIME] secondi, fetching: [SIZE] KB, [PIXEL] MPixels
+ </text>
+ <text name="total_time_refetch_all_cache_label">
+ 16, Nuovo fetching di tutte le texture dalla cache, Tempo: [TIME] secondi, fetching: [SIZE] KB, [PIXEL] MPixels
+ </text>
+ <text name="total_time_refetch_vis_http_label">
+ 17, Nuovo fetching elementi visibili da HTTP, Tempo: [TIME] secondi, fetching: [SIZE] KB, [PIXEL] MPixels
+ </text>
+ <text name="total_time_refetch_all_http_label">
+ 18, Nuovo fetching di tutte le texture da HTTP, Tempo: [TIME] secondi, fetching: [SIZE] KB, [PIXEL] MPixels
+ </text>
+ <spinner label="19, Rapporto Texel/Pixel:" name="texel_pixel_ratio"/>
+ <text name="texture_source_label">
+ 20, Fonte texture:
+ </text>
+ <radio_group name="texture_source">
+ <radio_item label="Cache + HTTP" name="0"/>
+ <radio_item label="Solo HTTP" name="1"/>
+ </radio_group>
+ <button label="Attiva" name="start_btn"/>
+ <button label="Reimposta" name="clear_btn"/>
+ <button label="Chiudi" name="close_btn"/>
+ <button label="Lettura cache" name="cacheread_btn"/>
+ <button label="Scrittura cache" name="cachewrite_btn"/>
+ <button label="HTTP" name="http_btn"/>
+ <button label="Decodifica" name="decode_btn"/>
+ <button label="Texture GL" name="gl_btn"/>
+ <button label="Nuovo fetch visibili cache" name="refetchviscache_btn"/>
+ <button label="Nuovo fetching di tutta la cache" name="refetchallcache_btn"/>
+ <button label="Nuovo fetch visibili HTTP" name="refetchvishttp_btn"/>
+ <button label="Nuovo fetching di tutto il contenuto HTTP" name="refetchallhttp_btn"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/it/floater_tools.xml b/indra/newview/skins/default/xui/it/floater_tools.xml
index c963ac72e6..468f284ccb 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_tools.xml
+++ b/indra/newview/skins/default/xui/it/floater_tools.xml
@@ -149,6 +149,12 @@
<panel.string name="text modify info 4">
Non puoi modificare questi oggetti
</panel.string>
+ <panel.string name="text modify info 5">
+ Questo oggetto non può essere modificato attraverso il confine di una regione
+ </panel.string>
+ <panel.string name="text modify info 6">
+ Questi oggetti non possono essere modificati attraverso il confine di una regione
+ </panel.string>
<panel.string name="text modify warning">
Devi selezionare tutto l&apos;oggetto per impostare i permessi
</panel.string>
@@ -204,12 +210,12 @@
<combo_box.item label="Ingrandisci" name="Zoom"/>
</combo_box>
<check_box label="In vendita:" name="checkbox for sale"/>
+ <spinner label="L$" name="Edit Cost"/>
<combo_box name="sale type">
<combo_box.item label="Copia" name="Copy"/>
<combo_box.item label="Contenuto" name="Contents"/>
<combo_box.item label="Originale" name="Original"/>
</combo_box>
- <spinner label="Prezzo: L$" name="Edit Cost"/>
<check_box label="Mostra nella ricerca" name="search_check" tool_tip="Permetti che l&apos;oggetto sia visibile nella ricerca"/>
<panel name="perms_build">
<text name="perm_modify">
@@ -245,6 +251,11 @@
F:
</text>
</panel>
+ <panel name="pathfinding_attrs_panel">
+ <text name="pathfinding_attributes_label">
+ Attributi pathfinding:
+ </text>
+ </panel>
</panel>
<panel label="Oggetto" name="Object">
<check_box label="Bloccato" name="checkbox locked" tool_tip="Previene lo spostamento o la cancellazione dell&apos;oggetto. Spesso utile mentre si costruisce per evitare involontarie modifiche."/>
@@ -459,16 +470,11 @@
<combo_box.item label="Cerchi rialzati" name="suction"/>
<combo_box.item label="Trama" name="weave"/>
</combo_box>
- <check_box initial_value="falso" label="Allinea facce planari" name="checkbox planar align" tool_tip="Allinea le texture su tutte le facce selezionate con l’ultima faccia selezionata. È richiesta la mappatura planare delle texture."/>
- <text name="rpt">
- Ripetizioni / Faccia
- </text>
<spinner label="Orizzontale (U)" name="TexScaleU"/>
<check_box label="Inverti" name="checkbox flip s"/>
<spinner label="Verticale (V)" name="TexScaleV"/>
<check_box label="Inverti" name="checkbox flip t"/>
<spinner label="RotazioneËš" name="TexRot"/>
- <spinner label="Ripetizioni / Metro" name="rptctrl"/>
<button label="Applica" label_selected="Applica" name="button apply"/>
<text name="tex offset">
Bilanciamento della texture
diff --git a/indra/newview/skins/default/xui/it/floater_top_objects.xml b/indra/newview/skins/default/xui/it/floater_top_objects.xml
index 7d062db23b..d8ca7f4438 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_top_objects.xml
+++ b/indra/newview/skins/default/xui/it/floater_top_objects.xml
@@ -9,9 +9,6 @@
<floater.string name="scripts_score_label">
Ora
</floater.string>
- <floater.string name="scripts_mono_time_label">
- Ora &apos;Mono&apos;
- </floater.string>
<floater.string name="top_colliders_title">
Oggetti con maggiori collisioni
</floater.string>
@@ -32,9 +29,10 @@
<scroll_list.columns label="Nome" name="name" width="84"/>
<scroll_list.columns label="Proprietario" name="owner" width="84"/>
<scroll_list.columns label="Ubicazione" name="location" width="84"/>
+ <scroll_list.columns label="Lotto" name="parcel"/>
<scroll_list.columns label="Ora" name="time" width="84"/>
- <scroll_list.columns label="Ora (Mono)" name="mono_time" width="84"/>
<scroll_list.columns label="URL" name="URLs"/>
+ <scroll_list.columns label="Memoria (KB)" name="memory"/>
</scroll_list>
<text name="id_text">
ID oggetto:
@@ -51,6 +49,10 @@
</text>
<line_editor font="SansSerifSmall" left="90" name="owner_name_editor" width="280"/>
<button label="Filtro" name="filter_owner_btn" width="150"/>
+ <text name="parcel_name_text">
+ Lotto:
+ </text>
+ <button label="Filtra" name="filter_parcel_btn"/>
<button label="Aggiorna" name="refresh_btn" width="150"/>
<button label="Restituisci selezionato" name="return_selected_btn" width="150"/>
<button label="Restituisci tutti" left="170" name="return_all_btn"/>
diff --git a/indra/newview/skins/default/xui/it/floater_tos.xml b/indra/newview/skins/default/xui/it/floater_tos.xml
index 28a2dfdda2..28a2dfdda2 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_tos.xml
+++ b/indra/newview/skins/default/xui/it/floater_tos.xml
diff --git a/indra/newview/skins/default/xui/it/floater_toybox.xml b/indra/newview/skins/default/xui/it/floater_toybox.xml
index 269e2831d0..269e2831d0 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_toybox.xml
+++ b/indra/newview/skins/default/xui/it/floater_toybox.xml
diff --git a/indra/newview/skins/default/xui/it/floater_translation_settings.xml b/indra/newview/skins/default/xui/it/floater_translation_settings.xml
index a0a34da723..a0a34da723 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_translation_settings.xml
+++ b/indra/newview/skins/default/xui/it/floater_translation_settings.xml
diff --git a/indra/newview/skins/default/xui/it/floater_url_entry.xml b/indra/newview/skins/default/xui/it/floater_url_entry.xml
index 9ad1a0dce5..9ad1a0dce5 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_url_entry.xml
+++ b/indra/newview/skins/default/xui/it/floater_url_entry.xml
diff --git a/indra/newview/skins/default/xui/it/floater_voice_chat_volume.xml b/indra/newview/skins/default/xui/it/floater_voice_chat_volume.xml
new file mode 100644
index 0000000000..b168d067c2
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/floater_voice_chat_volume.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="floater_voice_volume" title="VOLUME CHAT VOCALE">
+ <slider label="Chat vocale" name="chat_voice_volume"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/it/floater_voice_controls.xml b/indra/newview/skins/default/xui/it/floater_voice_controls.xml
index 77973eef1e..77973eef1e 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_voice_controls.xml
+++ b/indra/newview/skins/default/xui/it/floater_voice_controls.xml
diff --git a/indra/newview/skins/default/xui/it/floater_voice_effect.xml b/indra/newview/skins/default/xui/it/floater_voice_effect.xml
index c83b11f698..f102622f5d 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_voice_effect.xml
+++ b/indra/newview/skins/default/xui/it/floater_voice_effect.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater label="Luoghi" name="voice_effects" title="MANIPOLAZIONE VOCE">
+<floater label="Luoghi" name="voice_effects" title="ANTEPRIMA MANIPOLAZIONE VOCE">
<string name="no_voice_effect">
(Nessuna manipolazione voce)
</string>
diff --git a/indra/newview/skins/default/xui/it/floater_voice_volume.xml b/indra/newview/skins/default/xui/it/floater_voice_volume.xml
new file mode 100644
index 0000000000..eaeda7597f
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/floater_voice_volume.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<!--
+ Not can_close / no title to avoid window chrome
+ Single instance - only have one at a time, recycle it each spawn
+-->
+<floater name="floater_voice_volume" title="VOLUME VOCE">
+ <slider name="volume_slider" tool_tip="Volume voce" value="0.5"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/it/floater_web_content.xml b/indra/newview/skins/default/xui/it/floater_web_content.xml
index 5603e85417..5603e85417 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_web_content.xml
+++ b/indra/newview/skins/default/xui/it/floater_web_content.xml
diff --git a/indra/newview/skins/default/xui/it/floater_whitelist_entry.xml b/indra/newview/skins/default/xui/it/floater_whitelist_entry.xml
index 9abc968b94..9abc968b94 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_whitelist_entry.xml
+++ b/indra/newview/skins/default/xui/it/floater_whitelist_entry.xml
diff --git a/indra/newview/skins/default/xui/it/floater_window_size.xml b/indra/newview/skins/default/xui/it/floater_window_size.xml
index 036b74b7d9..fef423aefe 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_window_size.xml
+++ b/indra/newview/skins/default/xui/it/floater_window_size.xml
@@ -7,10 +7,17 @@
Imposta dimensione finestra:
</text>
<combo_box name="window_size_combo" tool_tip="larghezza x altezza">
- <combo_box.item label="1000 x 700 (default)" name="item0"/>
- <combo_box.item label="1024 x 768" name="item1"/>
- <combo_box.item label="1280 x 720 (720p)" name="item2"/>
- <combo_box.item label="1920 x 1080 (1080p)" name="item3"/>
+ <combo_box.item label="1000 x 700 (predefinito)" name="item1"/>
+ <combo_box.item label="1024 x 768 (4:3 XGA)" name="item2"/>
+ <combo_box.item label="1280 x 720 (16:9 HDTV)" name="item3"/>
+ <combo_box.item label="1280 x 800 (5:8 WXGA)" name="item4"/>
+ <combo_box.item label="1280 x 1024 (5:4 SXGA)" name="item5"/>
+ <combo_box.item label="1440 x 900 (8:5 WSXGA)" name="item7"/>
+ <combo_box.item label="1600 x 900 (16:9 HD+)" name="item8"/>
+ <combo_box.item label="1600 x 1200 (4:3 UXGA)" name="item9"/>
+ <combo_box.item label="1680 x 1050 (8:5 WSXGA+)" name="item10"/>
+ <combo_box.item label="1920 x 1080 (16:9 HDTV)" name="item11"/>
+ <combo_box.item label="1920 x 1200 (8:5 WUXGA)" name="item12"/>
</combo_box>
<button label="Imposta" name="set_btn"/>
<button label="Annulla" name="cancel_btn"/>
diff --git a/indra/newview/skins/default/xui/it/floater_world_map.xml b/indra/newview/skins/default/xui/it/floater_world_map.xml
index 8da17a4034..8da17a4034 100644..100755
--- a/indra/newview/skins/default/xui/it/floater_world_map.xml
+++ b/indra/newview/skins/default/xui/it/floater_world_map.xml
diff --git a/indra/newview/skins/default/xui/it/inspect_avatar.xml b/indra/newview/skins/default/xui/it/inspect_avatar.xml
index 6f52aaef74..6f52aaef74 100644..100755
--- a/indra/newview/skins/default/xui/it/inspect_avatar.xml
+++ b/indra/newview/skins/default/xui/it/inspect_avatar.xml
diff --git a/indra/newview/skins/default/xui/it/inspect_group.xml b/indra/newview/skins/default/xui/it/inspect_group.xml
index 2416f4bb12..2416f4bb12 100644..100755
--- a/indra/newview/skins/default/xui/it/inspect_group.xml
+++ b/indra/newview/skins/default/xui/it/inspect_group.xml
diff --git a/indra/newview/skins/default/xui/it/inspect_object.xml b/indra/newview/skins/default/xui/it/inspect_object.xml
index d8ab10cfda..d8ab10cfda 100644..100755
--- a/indra/newview/skins/default/xui/it/inspect_object.xml
+++ b/indra/newview/skins/default/xui/it/inspect_object.xml
diff --git a/indra/newview/skins/default/xui/it/inspect_remote_object.xml b/indra/newview/skins/default/xui/it/inspect_remote_object.xml
index b2d96ad757..b2d96ad757 100644..100755
--- a/indra/newview/skins/default/xui/it/inspect_remote_object.xml
+++ b/indra/newview/skins/default/xui/it/inspect_remote_object.xml
diff --git a/indra/newview/skins/default/xui/it/language_settings.xml b/indra/newview/skins/default/xui/it/language_settings.xml
index 5f448fa828..5f448fa828 100644..100755
--- a/indra/newview/skins/default/xui/it/language_settings.xml
+++ b/indra/newview/skins/default/xui/it/language_settings.xml
diff --git a/indra/newview/skins/default/xui/it/menu_add_wearable_gear.xml b/indra/newview/skins/default/xui/it/menu_add_wearable_gear.xml
index 46abd7deed..46abd7deed 100644..100755
--- a/indra/newview/skins/default/xui/it/menu_add_wearable_gear.xml
+++ b/indra/newview/skins/default/xui/it/menu_add_wearable_gear.xml
diff --git a/indra/newview/skins/default/xui/it/menu_attachment_other.xml b/indra/newview/skins/default/xui/it/menu_attachment_other.xml
index d4d6fd68d0..d4ce25e6a5 100644..100755
--- a/indra/newview/skins/default/xui/it/menu_attachment_other.xml
+++ b/indra/newview/skins/default/xui/it/menu_attachment_other.xml
@@ -11,7 +11,9 @@
<menu_item_call label="Congela" name="Freeze..."/>
<menu_item_call label="Espelli" name="Eject..."/>
<menu_item_call label="Debug delle texture" name="Debug..."/>
+ <menu_item_call label="Dump XML" name="Dump XML"/>
<menu_item_call label="Zoom avanti" name="Zoom In"/>
<menu_item_call label="Paga" name="Pay..."/>
<menu_item_call label="Profilo dell&apos;oggetto" name="Object Inspect"/>
+ <menu_item_call label="Blocca proprietario particella" name="Mute Particle"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/it/menu_attachment_self.xml b/indra/newview/skins/default/xui/it/menu_attachment_self.xml
index 0b841d591f..b28137262f 100644..100755
--- a/indra/newview/skins/default/xui/it/menu_attachment_self.xml
+++ b/indra/newview/skins/default/xui/it/menu_attachment_self.xml
@@ -12,5 +12,7 @@
<menu_item_call label="I miei gruppi" name="Groups..."/>
<menu_item_call label="Il mio profilo" name="Profile..."/>
<menu_item_call label="Debug delle texture" name="Debug..."/>
+ <menu_item_call label="Dump XML" name="Dump XML"/>
<menu_item_call label="Lascia" name="Drop"/>
+ <menu_item_call label="Blocca proprietario particella" name="Mute Particle"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/it/menu_avatar_icon.xml b/indra/newview/skins/default/xui/it/menu_avatar_icon.xml
index b93b695300..b93b695300 100644..100755
--- a/indra/newview/skins/default/xui/it/menu_avatar_icon.xml
+++ b/indra/newview/skins/default/xui/it/menu_avatar_icon.xml
diff --git a/indra/newview/skins/default/xui/it/menu_avatar_other.xml b/indra/newview/skins/default/xui/it/menu_avatar_other.xml
index c2edc32a49..a2b864b3e1 100644..100755
--- a/indra/newview/skins/default/xui/it/menu_avatar_other.xml
+++ b/indra/newview/skins/default/xui/it/menu_avatar_other.xml
@@ -11,6 +11,8 @@
<menu_item_call label="Congela" name="Freeze..."/>
<menu_item_call label="Espelli" name="Eject..."/>
<menu_item_call label="Debug delle texture" name="Debug..."/>
+ <menu_item_call label="Dump XML" name="Dump XML"/>
<menu_item_call label="Zoom avanti" name="Zoom In"/>
<menu_item_call label="Paga" name="Pay..."/>
+ <menu_item_call label="Blocca proprietario particella" name="Mute Particle"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/it/menu_avatar_self.xml b/indra/newview/skins/default/xui/it/menu_avatar_self.xml
index a4dafd7b5f..3666571065 100644..100755
--- a/indra/newview/skins/default/xui/it/menu_avatar_self.xml
+++ b/indra/newview/skins/default/xui/it/menu_avatar_self.xml
@@ -29,4 +29,6 @@
<menu_item_call label="I miei gruppi" name="Groups..."/>
<menu_item_call label="Il mio profilo" name="Profile..."/>
<menu_item_call label="Debug delle texture" name="Debug..."/>
+ <menu_item_call label="Dump XML" name="Dump XML"/>
+ <menu_item_call label="Blocca proprietario particella" name="Mute Particle"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/it/menu_bottomtray.xml b/indra/newview/skins/default/xui/it/menu_bottomtray.xml
deleted file mode 100644
index ddd6909136..0000000000
--- a/indra/newview/skins/default/xui/it/menu_bottomtray.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<menu name="hide_camera_move_controls_menu">
- <menu_item_check label="Pulsante Parla" name="EnableVoiceChat"/>
- <menu_item_check label="Tasto Gesture" name="ShowGestureButton"/>
- <menu_item_check label="Tasto Movimento" name="ShowMoveButton"/>
- <menu_item_check label="Tasto Visuale" name="ShowCameraButton"/>
- <menu_item_check label="Tasto Foto" name="ShowSnapshotButton"/>
- <menu_item_check label="Pulsante Costruisci" name="ShowBuildButton"/>
- <menu_item_check label="Pulsante Cerca" name="ShowSearchButton"/>
- <menu_item_check label="Pulsante Mappa" name="ShowWorldMapButton"/>
- <menu_item_check label="Pulsante Mini mappa" name="ShowMiniMapButton"/>
- <menu_item_call label="Taglia" name="NearbyChatBar_Cut"/>
- <menu_item_call label="Copia" name="NearbyChatBar_Copy"/>
- <menu_item_call label="Incolla" name="NearbyChatBar_Paste"/>
- <menu_item_call label="Elimina" name="NearbyChatBar_Delete"/>
- <menu_item_call label="Seleziona tutto" name="NearbyChatBar_Select_All"/>
-</menu>
diff --git a/indra/newview/skins/default/xui/it/menu_cof_attachment.xml b/indra/newview/skins/default/xui/it/menu_cof_attachment.xml
index 699490c8f1..699490c8f1 100644..100755
--- a/indra/newview/skins/default/xui/it/menu_cof_attachment.xml
+++ b/indra/newview/skins/default/xui/it/menu_cof_attachment.xml
diff --git a/indra/newview/skins/default/xui/it/menu_cof_body_part.xml b/indra/newview/skins/default/xui/it/menu_cof_body_part.xml
index 1e3658ef45..1e3658ef45 100644..100755
--- a/indra/newview/skins/default/xui/it/menu_cof_body_part.xml
+++ b/indra/newview/skins/default/xui/it/menu_cof_body_part.xml
diff --git a/indra/newview/skins/default/xui/it/menu_cof_clothing.xml b/indra/newview/skins/default/xui/it/menu_cof_clothing.xml
index 1e16ce8ed1..1e16ce8ed1 100644..100755
--- a/indra/newview/skins/default/xui/it/menu_cof_clothing.xml
+++ b/indra/newview/skins/default/xui/it/menu_cof_clothing.xml
diff --git a/indra/newview/skins/default/xui/it/menu_cof_gear.xml b/indra/newview/skins/default/xui/it/menu_cof_gear.xml
index 10524ba92d..984e4a1611 100644..100755
--- a/indra/newview/skins/default/xui/it/menu_cof_gear.xml
+++ b/indra/newview/skins/default/xui/it/menu_cof_gear.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<menu name="Gear COF">
+<toggleable_menu name="Gear COF">
<menu label="Nuovi abiti" name="COF.Gear.New_Clothes"/>
- <menu label="Nuove parti del corpo" name="COF.Geear.New_Body_Parts"/>
-</menu>
+ <menu label="Nuove parti del corpo" name="COF.Gear.New_Body_Parts"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/it/menu_conversation.xml b/indra/newview/skins/default/xui/it/menu_conversation.xml
new file mode 100644
index 0000000000..24486f2af2
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/menu_conversation.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_conversation_participant">
+ <menu_item_call label="Chiudi la conversazione" name="close_conversation"/>
+ <menu_item_call label="Apri conversazione a voce" name="open_voice_conversation"/>
+ <menu_item_call label="Interrompi collegamento a voce" name="disconnect_from_voice"/>
+ <menu_item_call label="Chiudi selezionato" name="close_selected_conversations"/>
+ <menu_item_call label="Vedi profilo" name="view_profile"/>
+ <menu_item_call label="IM" name="im"/>
+ <menu_item_call label="Offri teleport" name="offer_teleport"/>
+ <menu_item_call label="Chiamata a voce" name="voice_call"/>
+ <menu_item_call label="Cronologia chat..." name="chat_history"/>
+ <menu_item_call label="Aggiungi amico" name="add_friend"/>
+ <menu_item_call label="Rimuovi amico" name="remove_friend"/>
+ <menu_item_call label="Rimuovi amici" name="remove_friends"/>
+ <menu_item_call label="Invita al gruppo..." name="invite_to_group"/>
+ <menu_item_call label="Zoom avanti" name="zoom_in"/>
+ <menu_item_call label="Mappa" name="map"/>
+ <menu_item_call label="Condividi" name="share"/>
+ <menu_item_call label="Paga" name="pay"/>
+ <menu_item_check label="Blocca voce" name="block_unblock"/>
+ <menu_item_check label="Blocca testo" name="MuteText"/>
+ <menu_item_call label="Profilo del gruppo" name="group_profile"/>
+ <menu_item_call label="Attiva gruppo" name="activate_group"/>
+ <menu_item_call label="Lascia il gruppo" name="leave_group"/>
+ <context_menu label="Opzioni moderatore" name="Moderator Options">
+ <menu_item_check label="Consenti chat di testo" name="AllowTextChat"/>
+ <menu_item_call label="Disattiva audio di questo partecipante" name="ModerateVoiceMuteSelected"/>
+ <menu_item_call label="Riattiva audio di questo partecipante" name="ModerateVoiceUnMuteSelected"/>
+ <menu_item_call label="Disattiva audio di tutti" name="ModerateVoiceMute"/>
+ <menu_item_call label="Riattiva audio di tutti" name="ModerateVoiceUnmute"/>
+ </context_menu>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/it/menu_conversation_log_gear.xml b/indra/newview/skins/default/xui/it/menu_conversation_log_gear.xml
new file mode 100644
index 0000000000..5686a902eb
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/menu_conversation_log_gear.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="Conversation Context Menu">
+ <menu_item_call label="IM..." name="IM"/>
+ <menu_item_call label="Chiamata a voce..." name="Call"/>
+ <menu_item_call label="Apro la cronologia delle chat..." name="Chat history"/>
+ <menu_item_call label="Vedi profilo" name="View Profile"/>
+ <menu_item_call label="Offri Teleport" name="teleport"/>
+ <menu_item_call label="Aggiungi come amico" name="add_friend"/>
+ <menu_item_call label="Rimuovi amico" name="remove_friend"/>
+ <menu_item_call label="Invita al gruppo..." name="Invite"/>
+ <menu_item_call label="Mappa" name="Map"/>
+ <menu_item_call label="Condividi" name="Share"/>
+ <menu_item_call label="Paga" name="Pay"/>
+ <menu_item_check label="Blocca/Sblocca" name="Block/Unblock"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/it/menu_conversation_log_view.xml b/indra/newview/skins/default/xui/it/menu_conversation_log_view.xml
new file mode 100644
index 0000000000..73b05831ef
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/menu_conversation_log_view.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_conversation_view">
+ <menu_item_check label="Ordina in base al nome" name="sort_by_name"/>
+ <menu_item_check label="Ordina in base alla data" name="sort_by_date"/>
+ <menu_item_check label="Ordina con gli amici in alto" name="sort_by_friends"/>
+ <menu_item_call label="Mostra la cronologia delle chat vicine..." name="view_nearby_chat_history"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/it/menu_edit.xml b/indra/newview/skins/default/xui/it/menu_edit.xml
index ffb20a02e9..ffb20a02e9 100644..100755
--- a/indra/newview/skins/default/xui/it/menu_edit.xml
+++ b/indra/newview/skins/default/xui/it/menu_edit.xml
diff --git a/indra/newview/skins/default/xui/it/menu_favorites.xml b/indra/newview/skins/default/xui/it/menu_favorites.xml
index 7813ef44b5..7813ef44b5 100644..100755
--- a/indra/newview/skins/default/xui/it/menu_favorites.xml
+++ b/indra/newview/skins/default/xui/it/menu_favorites.xml
diff --git a/indra/newview/skins/default/xui/it/menu_gesture_gear.xml b/indra/newview/skins/default/xui/it/menu_gesture_gear.xml
index 7cfcc6287e..7cfcc6287e 100644..100755
--- a/indra/newview/skins/default/xui/it/menu_gesture_gear.xml
+++ b/indra/newview/skins/default/xui/it/menu_gesture_gear.xml
diff --git a/indra/newview/skins/default/xui/it/menu_group_plus.xml b/indra/newview/skins/default/xui/it/menu_group_plus.xml
index 3b76fb94a9..3b76fb94a9 100644..100755
--- a/indra/newview/skins/default/xui/it/menu_group_plus.xml
+++ b/indra/newview/skins/default/xui/it/menu_group_plus.xml
diff --git a/indra/newview/skins/default/xui/it/menu_hide_navbar.xml b/indra/newview/skins/default/xui/it/menu_hide_navbar.xml
index 48f6691fd8..48f6691fd8 100644..100755
--- a/indra/newview/skins/default/xui/it/menu_hide_navbar.xml
+++ b/indra/newview/skins/default/xui/it/menu_hide_navbar.xml
diff --git a/indra/newview/skins/default/xui/it/menu_im_conversation.xml b/indra/newview/skins/default/xui/it/menu_im_conversation.xml
new file mode 100644
index 0000000000..1621d57e12
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/menu_im_conversation.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="Conversation Gear Menu">
+ <menu_item_call label="Vedi profilo" name="View Profile"/>
+ <menu_item_call label="Aggiungi come amico" name="Add Friend"/>
+ <menu_item_call label="Rimuovi amico" name="remove_friend"/>
+ <menu_item_call label="Offri teleport" name="offer_teleport"/>
+ <menu_item_call label="Invita al gruppo..." name="invite_to_group"/>
+ <menu_item_call label="Cronologia chat..." name="chat_history"/>
+ <menu_item_call label="Zoom avanti" name="zoom_in"/>
+ <menu_item_call label="Mappa" name="map"/>
+ <menu_item_call label="Condividi" name="Share"/>
+ <menu_item_call label="Paga" name="Pay"/>
+ <menu_item_check label="Blocca voce" name="Block/Unblock"/>
+ <menu_item_check label="Blocca testo" name="MuteText"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/it/menu_im_session_showmodes.xml b/indra/newview/skins/default/xui/it/menu_im_session_showmodes.xml
new file mode 100644
index 0000000000..350fbc5c6f
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/menu_im_session_showmodes.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_modes">
+ <menu_item_check label="Vista compatta" name="compact_view"/>
+ <menu_item_check label="Vista espansa" name="expanded_view"/>
+ <menu_item_check label="Mostra orario" name="IMShowTime"/>
+ <menu_item_check label="Mostra i nomi nelle conversazioni individuali" name="IMShowNamesForP2PConv"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/it/menu_im_well_button.xml b/indra/newview/skins/default/xui/it/menu_im_well_button.xml
deleted file mode 100644
index 9e471b771c..0000000000
--- a/indra/newview/skins/default/xui/it/menu_im_well_button.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<context_menu name="IM Well Button Context Menu">
- <menu_item_call label="Chiudi tutto" name="Close All"/>
-</context_menu>
diff --git a/indra/newview/skins/default/xui/it/menu_imchiclet_adhoc.xml b/indra/newview/skins/default/xui/it/menu_imchiclet_adhoc.xml
index f78ed8489f..f78ed8489f 100644..100755
--- a/indra/newview/skins/default/xui/it/menu_imchiclet_adhoc.xml
+++ b/indra/newview/skins/default/xui/it/menu_imchiclet_adhoc.xml
diff --git a/indra/newview/skins/default/xui/it/menu_imchiclet_group.xml b/indra/newview/skins/default/xui/it/menu_imchiclet_group.xml
index baa4e671b0..baa4e671b0 100644..100755
--- a/indra/newview/skins/default/xui/it/menu_imchiclet_group.xml
+++ b/indra/newview/skins/default/xui/it/menu_imchiclet_group.xml
diff --git a/indra/newview/skins/default/xui/it/menu_imchiclet_p2p.xml b/indra/newview/skins/default/xui/it/menu_imchiclet_p2p.xml
index 2eacbb09ad..2eacbb09ad 100644..100755
--- a/indra/newview/skins/default/xui/it/menu_imchiclet_p2p.xml
+++ b/indra/newview/skins/default/xui/it/menu_imchiclet_p2p.xml
diff --git a/indra/newview/skins/default/xui/it/menu_inspect_avatar_gear.xml b/indra/newview/skins/default/xui/it/menu_inspect_avatar_gear.xml
index 1f10734c4a..1f10734c4a 100644..100755
--- a/indra/newview/skins/default/xui/it/menu_inspect_avatar_gear.xml
+++ b/indra/newview/skins/default/xui/it/menu_inspect_avatar_gear.xml
diff --git a/indra/newview/skins/default/xui/it/menu_inspect_object_gear.xml b/indra/newview/skins/default/xui/it/menu_inspect_object_gear.xml
index 4740c9bf67..4740c9bf67 100644..100755
--- a/indra/newview/skins/default/xui/it/menu_inspect_object_gear.xml
+++ b/indra/newview/skins/default/xui/it/menu_inspect_object_gear.xml
diff --git a/indra/newview/skins/default/xui/it/menu_inspect_self_gear.xml b/indra/newview/skins/default/xui/it/menu_inspect_self_gear.xml
index 4f62ccaa9c..4f62ccaa9c 100644..100755
--- a/indra/newview/skins/default/xui/it/menu_inspect_self_gear.xml
+++ b/indra/newview/skins/default/xui/it/menu_inspect_self_gear.xml
diff --git a/indra/newview/skins/default/xui/it/menu_inv_offer_chiclet.xml b/indra/newview/skins/default/xui/it/menu_inv_offer_chiclet.xml
index 471640eff5..471640eff5 100644..100755
--- a/indra/newview/skins/default/xui/it/menu_inv_offer_chiclet.xml
+++ b/indra/newview/skins/default/xui/it/menu_inv_offer_chiclet.xml
diff --git a/indra/newview/skins/default/xui/it/menu_inventory.xml b/indra/newview/skins/default/xui/it/menu_inventory.xml
index 4bf6be82fd..b31e35771d 100644..100755
--- a/indra/newview/skins/default/xui/it/menu_inventory.xml
+++ b/indra/newview/skins/default/xui/it/menu_inventory.xml
@@ -68,6 +68,7 @@
<menu_item_call label="Elimina la cartella di sistema" name="Delete System Folder"/>
<menu_item_call label="Inizia la conferenza chat" name="Conference Chat Folder"/>
<menu_item_call label="Esegui" name="Sound Play"/>
+ <menu_item_call label="Copia SLurl" name="url_copy"/>
<menu_item_call label="Informazioni sul punto di riferimento" name="About Landmark"/>
<menu_item_call label="Riproduci in Second Life" name="Animation Play"/>
<menu_item_call label="Esegui localmente" name="Animation Audition"/>
diff --git a/indra/newview/skins/default/xui/it/menu_inventory_add.xml b/indra/newview/skins/default/xui/it/menu_inventory_add.xml
index 62da61cd6b..62da61cd6b 100644..100755
--- a/indra/newview/skins/default/xui/it/menu_inventory_add.xml
+++ b/indra/newview/skins/default/xui/it/menu_inventory_add.xml
diff --git a/indra/newview/skins/default/xui/it/menu_inventory_gear_default.xml b/indra/newview/skins/default/xui/it/menu_inventory_gear_default.xml
index 3d64e4da4e..3d64e4da4e 100644..100755
--- a/indra/newview/skins/default/xui/it/menu_inventory_gear_default.xml
+++ b/indra/newview/skins/default/xui/it/menu_inventory_gear_default.xml
diff --git a/indra/newview/skins/default/xui/it/menu_land.xml b/indra/newview/skins/default/xui/it/menu_land.xml
index f510078e14..816849a7b5 100644..100755
--- a/indra/newview/skins/default/xui/it/menu_land.xml
+++ b/indra/newview/skins/default/xui/it/menu_land.xml
@@ -6,4 +6,5 @@
<menu_item_call label="Acquista Permesso" name="Land Buy Pass"/>
<menu_item_call label="Costruisci" name="Create"/>
<menu_item_call label="Modifica terreno" name="Edit Terrain"/>
+ <menu_item_call label="Blocca proprietario particella" name="Mute Particle"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/it/menu_landmark.xml b/indra/newview/skins/default/xui/it/menu_landmark.xml
index b3cddab783..b3cddab783 100644..100755
--- a/indra/newview/skins/default/xui/it/menu_landmark.xml
+++ b/indra/newview/skins/default/xui/it/menu_landmark.xml
diff --git a/indra/newview/skins/default/xui/it/menu_login.xml b/indra/newview/skins/default/xui/it/menu_login.xml
index 7b060e6565..35053ec499 100644..100755
--- a/indra/newview/skins/default/xui/it/menu_login.xml
+++ b/indra/newview/skins/default/xui/it/menu_login.xml
@@ -17,7 +17,13 @@
<menu_item_call label="Mostra i Termini del servizio (TOS)" name="TOS"/>
<menu_item_call label="Mostra messaggio critico" name="Critical"/>
<menu_item_call label="Test debug finestra contenuti Web" name="Web Content Floater Debug Test"/>
- <menu label="Imposta livello di registrazione" name="Set Logging Level"/>
+ <menu label="Imposta livello di registrazione" name="Set Logging Level">
+ <menu_item_check label="Debug" name="Debug"/>
+ <menu_item_check label="Info" name="Info"/>
+ <menu_item_check label="Attenzione" name="Warning"/>
+ <menu_item_check label="Errore" name="Error"/>
+ <menu_item_check label="Nessuno" name="None"/>
+ </menu>
<menu_item_check label="Mostra selettore griglia" name="Show Grid Picker"/>
<menu_item_call label="Mostra Console notifiche" name="Show Notifications Console"/>
</menu>
diff --git a/indra/newview/skins/default/xui/it/menu_media_ctrl.xml b/indra/newview/skins/default/xui/it/menu_media_ctrl.xml
index aa9e583f8e..aa9e583f8e 100644..100755
--- a/indra/newview/skins/default/xui/it/menu_media_ctrl.xml
+++ b/indra/newview/skins/default/xui/it/menu_media_ctrl.xml
diff --git a/indra/newview/skins/default/xui/it/menu_mini_map.xml b/indra/newview/skins/default/xui/it/menu_mini_map.xml
index 561b80e046..561b80e046 100644..100755
--- a/indra/newview/skins/default/xui/it/menu_mini_map.xml
+++ b/indra/newview/skins/default/xui/it/menu_mini_map.xml
diff --git a/indra/newview/skins/default/xui/it/menu_mode_change.xml b/indra/newview/skins/default/xui/it/menu_mode_change.xml
deleted file mode 100644
index 499dcf1873..0000000000
--- a/indra/newview/skins/default/xui/it/menu_mode_change.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<toggleable_menu name="Mode Change">
- <menu_item_check label="Di base" name="BasicMode"/>
- <menu_item_check label="Avanzata" name="AdvancedMode"/>
-</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/it/menu_model_import_gear_default.xml b/indra/newview/skins/default/xui/it/menu_model_import_gear_default.xml
index 5012e6450f..5012e6450f 100644..100755
--- a/indra/newview/skins/default/xui/it/menu_model_import_gear_default.xml
+++ b/indra/newview/skins/default/xui/it/menu_model_import_gear_default.xml
diff --git a/indra/newview/skins/default/xui/it/menu_mute_particle.xml b/indra/newview/skins/default/xui/it/menu_mute_particle.xml
new file mode 100644
index 0000000000..7eb4b09495
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/menu_mute_particle.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<!-- *NOTE: See also menu_attachment_other.xml -->
+<context_menu name="Mute Particle Pie">
+ <menu_item_call label="Blocca proprietario particella" name="Mute Particle"/>
+</context_menu>
diff --git a/indra/newview/skins/default/xui/it/menu_navbar.xml b/indra/newview/skins/default/xui/it/menu_navbar.xml
index e42d913a6f..e42d913a6f 100644..100755
--- a/indra/newview/skins/default/xui/it/menu_navbar.xml
+++ b/indra/newview/skins/default/xui/it/menu_navbar.xml
diff --git a/indra/newview/skins/default/xui/it/menu_nearby_chat.xml b/indra/newview/skins/default/xui/it/menu_nearby_chat.xml
index 719a6d3261..719a6d3261 100644..100755
--- a/indra/newview/skins/default/xui/it/menu_nearby_chat.xml
+++ b/indra/newview/skins/default/xui/it/menu_nearby_chat.xml
diff --git a/indra/newview/skins/default/xui/it/menu_notification_well_button.xml b/indra/newview/skins/default/xui/it/menu_notification_well_button.xml
index 8c82e30f0e..8c82e30f0e 100644..100755
--- a/indra/newview/skins/default/xui/it/menu_notification_well_button.xml
+++ b/indra/newview/skins/default/xui/it/menu_notification_well_button.xml
diff --git a/indra/newview/skins/default/xui/it/menu_object.xml b/indra/newview/skins/default/xui/it/menu_object.xml
index a172cf3b26..9bcc0879d2 100644..100755
--- a/indra/newview/skins/default/xui/it/menu_object.xml
+++ b/indra/newview/skins/default/xui/it/menu_object.xml
@@ -10,6 +10,8 @@
<menu_item_call label="Alzati" name="Object Stand Up"/>
<menu_item_call label="Profilo dell&apos;oggetto" name="Object Inspect"/>
<menu_item_call label="Zoom avanti" name="Zoom In"/>
+ <menu_item_call label="Mostra nei set collegati" name="show_in_linksets"/>
+ <menu_item_call label="Mostra nei personaggi" name="show_in_characters"/>
<context_menu label="Metti" name="Put On">
<menu_item_call label="Indossa" name="Wear"/>
<menu_item_call label="Aggiungi" name="Add"/>
@@ -26,4 +28,5 @@
<menu_item_call label="Paga" name="Pay..."/>
<menu_item_call label="Acquista" name="Buy..."/>
<menu_item_call label="Elimina" name="Delete"/>
+ <menu_item_call label="Blocca proprietario particella" name="Mute Particle"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/it/menu_object_icon.xml b/indra/newview/skins/default/xui/it/menu_object_icon.xml
index 0f347b1a90..9623775af4 100644..100755
--- a/indra/newview/skins/default/xui/it/menu_object_icon.xml
+++ b/indra/newview/skins/default/xui/it/menu_object_icon.xml
@@ -2,4 +2,6 @@
<menu name="Object Icon Menu">
<menu_item_call label="Profilo oggetto..." name="Object Profile"/>
<menu_item_call label="Blocca..." name="Block"/>
+ <menu_item_call label="Mostra sulla mappa" name="show_on_map"/>
+ <menu_item_call label="Teleport sul luogo dell&apos;oggetto" name="teleport_to_object"/>
</menu>
diff --git a/indra/newview/skins/default/xui/it/menu_outfit_gear.xml b/indra/newview/skins/default/xui/it/menu_outfit_gear.xml
index 09fc867d7c..3ac0c5ce69 100644..100755
--- a/indra/newview/skins/default/xui/it/menu_outfit_gear.xml
+++ b/indra/newview/skins/default/xui/it/menu_outfit_gear.xml
@@ -23,6 +23,8 @@
<menu_item_call label="Nuovi capelli" name="New Hair"/>
<menu_item_call label="Nuovi occhi" name="New Eyes"/>
</menu>
+ <menu_item_call label="Apri tutte le cartelle" name="expand"/>
+ <menu_item_call label="Chiudi tutte le cartelle" name="collapse"/>
<menu_item_call label="Cambia nome del vestiario" name="rename"/>
<menu_item_call label="Elimina vestito" name="delete_outfit"/>
</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/it/menu_outfit_tab.xml b/indra/newview/skins/default/xui/it/menu_outfit_tab.xml
index 8166cf20ed..8166cf20ed 100644..100755
--- a/indra/newview/skins/default/xui/it/menu_outfit_tab.xml
+++ b/indra/newview/skins/default/xui/it/menu_outfit_tab.xml
diff --git a/indra/newview/skins/default/xui/it/menu_participant_list.xml b/indra/newview/skins/default/xui/it/menu_participant_list.xml
index 1b057c4077..1b057c4077 100644..100755
--- a/indra/newview/skins/default/xui/it/menu_participant_list.xml
+++ b/indra/newview/skins/default/xui/it/menu_participant_list.xml
diff --git a/indra/newview/skins/default/xui/it/menu_participant_view.xml b/indra/newview/skins/default/xui/it/menu_participant_view.xml
new file mode 100644
index 0000000000..c87cda57bf
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/menu_participant_view.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="participant_manu_view">
+ <menu_item_check label="Ordina le conversazioni in base al tipo" name="sort_sessions_by_type"/>
+ <menu_item_check label="Ordina le conversazioni in base al nome" name="sort_sessions_by_name"/>
+ <menu_item_check label="Ordina le conversazioni in base alle attività più recenti" name="sort_sessions_by_recent"/>
+ <menu_item_check label="Ordina i partecipanti in base al nome" name="sort_participants_by_name"/>
+ <menu_item_check label="Ordina i partecipanti in base alle attività più recenti" name="sort_participants_by_recent"/>
+ <menu_item_call label="Preferenze chat..." name="chat_preferences"/>
+ <menu_item_call label="Preferenze privacy..." name="privacy_preferences"/>
+ <menu_item_check label="Registro conversazioni..." name="Conversation"/>
+ <menu_item_check label="Traduci chat vicina" name="Translate_chat"/>
+ <menu_item_check label="Impostazioni traduzione..." name="Translation_settings"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/it/menu_people_blocked_gear.xml b/indra/newview/skins/default/xui/it/menu_people_blocked_gear.xml
new file mode 100644
index 0000000000..e9955923b2
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/menu_people_blocked_gear.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_blocked_gear">
+ <menu_item_call label="Sblocca" name="unblock"/>
+ <menu_item_call label="Profilo..." name="profile"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/it/menu_people_blocked_plus.xml b/indra/newview/skins/default/xui/it/menu_people_blocked_plus.xml
new file mode 100644
index 0000000000..cbcf084b86
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/menu_people_blocked_plus.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_blocked_plus">
+ <menu_item_call label="Blocca residente per nome..." name="block_resident_by_name"/>
+ <menu_item_call label="Blocca oggetto per nome" name="block_object_by_name"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/it/menu_people_blocked_view.xml b/indra/newview/skins/default/xui/it/menu_people_blocked_view.xml
new file mode 100644
index 0000000000..fc80c73ae3
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/menu_people_blocked_view.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_blocked_view">
+ <menu_item_check label="Ordina in base al nome" name="sort_by_name"/>
+ <menu_item_check label="Ordina in base al tipo" name="sort_by_type"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/it/menu_people_friends_view.xml b/indra/newview/skins/default/xui/it/menu_people_friends_view.xml
new file mode 100644
index 0000000000..972e359cfe
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/menu_people_friends_view.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_group_plus">
+ <menu_item_check label="Ordina in base al nome" name="sort_name"/>
+ <menu_item_check label="Ordina in base allo stato" name="sort_status"/>
+ <menu_item_check label="Mostra le icone delle persone" name="view_icons"/>
+ <menu_item_check label="Mostra le autorizzazioni concesse" name="view_permissions"/>
+ <menu_item_check label="Mostra il registro conversazioni..." name="view_conversation"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/it/menu_people_friends_view_sort.xml b/indra/newview/skins/default/xui/it/menu_people_friends_view_sort.xml
index 3a799f44eb..3a799f44eb 100644..100755
--- a/indra/newview/skins/default/xui/it/menu_people_friends_view_sort.xml
+++ b/indra/newview/skins/default/xui/it/menu_people_friends_view_sort.xml
diff --git a/indra/newview/skins/default/xui/it/menu_people_groups.xml b/indra/newview/skins/default/xui/it/menu_people_groups.xml
index 30a97a1c72..8ca7537ee0 100644..100755
--- a/indra/newview/skins/default/xui/it/menu_people_groups.xml
+++ b/indra/newview/skins/default/xui/it/menu_people_groups.xml
@@ -2,7 +2,7 @@
<menu name="menu_group_plus">
<menu_item_call label="Mostra informazioni" name="View Info"/>
<menu_item_call label="Chat" name="Chat"/>
- <menu_item_call label="Chiama" name="Call"/>
+ <menu_item_call label="Chiamata a voce" name="Call"/>
<menu_item_call label="Attiva" name="Activate"/>
<menu_item_call label="Chiudi" name="Leave"/>
</menu>
diff --git a/indra/newview/skins/default/xui/it/menu_people_groups_view.xml b/indra/newview/skins/default/xui/it/menu_people_groups_view.xml
new file mode 100644
index 0000000000..56b9abbd3a
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/menu_people_groups_view.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_group_plus">
+ <menu_item_check label="Mostra le icone di gruppo" name="Display Group Icons"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/it/menu_people_groups_view_sort.xml b/indra/newview/skins/default/xui/it/menu_people_groups_view_sort.xml
index d31ddaf1aa..d31ddaf1aa 100644..100755
--- a/indra/newview/skins/default/xui/it/menu_people_groups_view_sort.xml
+++ b/indra/newview/skins/default/xui/it/menu_people_groups_view_sort.xml
diff --git a/indra/newview/skins/default/xui/it/menu_people_nearby.xml b/indra/newview/skins/default/xui/it/menu_people_nearby.xml
index a974bd181d..1c09b1cfe2 100644..100755
--- a/indra/newview/skins/default/xui/it/menu_people_nearby.xml
+++ b/indra/newview/skins/default/xui/it/menu_people_nearby.xml
@@ -1,13 +1,16 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Avatar Context Menu">
- <menu_item_call label="Vedi profilo" name="View Profile"/>
- <menu_item_call label="Aggiungi amico" name="Add Friend"/>
- <menu_item_call label="Rimuovi amico" name="Remove Friend"/>
- <menu_item_call label="IM" name="IM"/>
- <menu_item_call label="Chiama" name="Call"/>
- <menu_item_call label="Mappa" name="Map"/>
- <menu_item_call label="Condividi" name="Share"/>
- <menu_item_call label="Paga" name="Pay"/>
- <menu_item_check label="Blocca/Sblocca" name="Block/Unblock"/>
- <menu_item_call label="Offri Teleport" name="teleport"/>
+ <menu_item_call label="Vedi profilo" name="view_profile"/>
+ <menu_item_call label="IM" name="im"/>
+ <menu_item_call label="Offri Teleport" name="offer_teleport"/>
+ <menu_item_call label="Chiamata a voce" name="voice_call"/>
+ <menu_item_call label="Mostra la cronologia delle chat..." name="chat_history"/>
+ <menu_item_call label="Aggiungi come amico" name="add_friend"/>
+ <menu_item_call label="Rimuovi amico" name="remove_friend"/>
+ <menu_item_call label="Invita al gruppo..." name="invite_to_group"/>
+ <menu_item_call label="Zoom avanti" name="zoom_in"/>
+ <menu_item_call label="Mappa" name="map"/>
+ <menu_item_call label="Condividi" name="share"/>
+ <menu_item_call label="Paga" name="pay"/>
+ <menu_item_check label="Blocca/Sblocca" name="block_unblock"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/it/menu_people_nearby_multiselect.xml b/indra/newview/skins/default/xui/it/menu_people_nearby_multiselect.xml
index e0b9ceb63d..b9ce70167f 100644..100755
--- a/indra/newview/skins/default/xui/it/menu_people_nearby_multiselect.xml
+++ b/indra/newview/skins/default/xui/it/menu_people_nearby_multiselect.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Multi-Selected People Context Menu">
- <menu_item_call label="Aggiungi amici" name="Add Friends"/>
- <menu_item_call label="Rimuovi amici" name="Remove Friend"/>
- <menu_item_call label="IM" name="IM"/>
- <menu_item_call label="Chiama" name="Call"/>
- <menu_item_call label="Condividi" name="Share"/>
- <menu_item_call label="Paga" name="Pay"/>
- <menu_item_call label="Offri Teleport" name="teleport"/>
+ <menu_item_call label="Aggiungi amici" name="add_friends"/>
+ <menu_item_call label="Rimuovi amici" name="remove_friends"/>
+ <menu_item_call label="IM" name="im"/>
+ <menu_item_call label="Chiama" name="call"/>
+ <menu_item_call label="Condividi" name="share"/>
+ <menu_item_call label="Paga" name="pay"/>
+ <menu_item_call label="Offri Teleport" name="offer_teleport"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/it/menu_people_nearby_view.xml b/indra/newview/skins/default/xui/it/menu_people_nearby_view.xml
new file mode 100644
index 0000000000..223d88fee1
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/menu_people_nearby_view.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_group_plus">
+ <menu_item_check label="Ordina in base a intervenuti recenti" name="sort_by_recent_speakers"/>
+ <menu_item_check label="Ordina in base al nome" name="sort_name"/>
+ <menu_item_check label="Ordina in base alla distanza" name="sort_distance"/>
+ <menu_item_check label="Mostra le icone delle persone" name="view_icons"/>
+ <menu_item_check label="Mostra mappa" name="view_map"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/it/menu_people_nearby_view_sort.xml b/indra/newview/skins/default/xui/it/menu_people_nearby_view_sort.xml
index 2b5c235706..2b5c235706 100644..100755
--- a/indra/newview/skins/default/xui/it/menu_people_nearby_view_sort.xml
+++ b/indra/newview/skins/default/xui/it/menu_people_nearby_view_sort.xml
diff --git a/indra/newview/skins/default/xui/it/menu_people_recent_view.xml b/indra/newview/skins/default/xui/it/menu_people_recent_view.xml
new file mode 100644
index 0000000000..fc6213bd08
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/menu_people_recent_view.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_group_plus">
+ <menu_item_check label="Mostra prima i più recenti" name="sort_most"/>
+ <menu_item_check label="Ordina in base al nome" name="sort_name"/>
+ <menu_item_check label="Mostra le icone delle persone" name="view_icons"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/it/menu_people_recent_view_sort.xml b/indra/newview/skins/default/xui/it/menu_people_recent_view_sort.xml
index 7fccd1621a..7fccd1621a 100644..100755
--- a/indra/newview/skins/default/xui/it/menu_people_recent_view_sort.xml
+++ b/indra/newview/skins/default/xui/it/menu_people_recent_view_sort.xml
diff --git a/indra/newview/skins/default/xui/it/menu_picks.xml b/indra/newview/skins/default/xui/it/menu_picks.xml
index 000d219ed0..000d219ed0 100644..100755
--- a/indra/newview/skins/default/xui/it/menu_picks.xml
+++ b/indra/newview/skins/default/xui/it/menu_picks.xml
diff --git a/indra/newview/skins/default/xui/it/menu_picks_plus.xml b/indra/newview/skins/default/xui/it/menu_picks_plus.xml
index 7fbd5abd57..7fbd5abd57 100644..100755
--- a/indra/newview/skins/default/xui/it/menu_picks_plus.xml
+++ b/indra/newview/skins/default/xui/it/menu_picks_plus.xml
diff --git a/indra/newview/skins/default/xui/it/menu_place.xml b/indra/newview/skins/default/xui/it/menu_place.xml
index 5381a4effa..5381a4effa 100644..100755
--- a/indra/newview/skins/default/xui/it/menu_place.xml
+++ b/indra/newview/skins/default/xui/it/menu_place.xml
diff --git a/indra/newview/skins/default/xui/it/menu_place_add_button.xml b/indra/newview/skins/default/xui/it/menu_place_add_button.xml
index 0e783c0000..0e783c0000 100644..100755
--- a/indra/newview/skins/default/xui/it/menu_place_add_button.xml
+++ b/indra/newview/skins/default/xui/it/menu_place_add_button.xml
diff --git a/indra/newview/skins/default/xui/it/menu_places_gear_folder.xml b/indra/newview/skins/default/xui/it/menu_places_gear_folder.xml
index 23757d47e0..23757d47e0 100644..100755
--- a/indra/newview/skins/default/xui/it/menu_places_gear_folder.xml
+++ b/indra/newview/skins/default/xui/it/menu_places_gear_folder.xml
diff --git a/indra/newview/skins/default/xui/it/menu_places_gear_landmark.xml b/indra/newview/skins/default/xui/it/menu_places_gear_landmark.xml
index a458b1a768..a458b1a768 100644..100755
--- a/indra/newview/skins/default/xui/it/menu_places_gear_landmark.xml
+++ b/indra/newview/skins/default/xui/it/menu_places_gear_landmark.xml
diff --git a/indra/newview/skins/default/xui/it/menu_profile_overflow.xml b/indra/newview/skins/default/xui/it/menu_profile_overflow.xml
index 56b695c597..56b695c597 100644..100755
--- a/indra/newview/skins/default/xui/it/menu_profile_overflow.xml
+++ b/indra/newview/skins/default/xui/it/menu_profile_overflow.xml
diff --git a/indra/newview/skins/default/xui/it/menu_save_outfit.xml b/indra/newview/skins/default/xui/it/menu_save_outfit.xml
index 4882a8ac64..4882a8ac64 100644..100755
--- a/indra/newview/skins/default/xui/it/menu_save_outfit.xml
+++ b/indra/newview/skins/default/xui/it/menu_save_outfit.xml
diff --git a/indra/newview/skins/default/xui/it/menu_script_chiclet.xml b/indra/newview/skins/default/xui/it/menu_script_chiclet.xml
index 604f754ba8..604f754ba8 100644..100755
--- a/indra/newview/skins/default/xui/it/menu_script_chiclet.xml
+++ b/indra/newview/skins/default/xui/it/menu_script_chiclet.xml
diff --git a/indra/newview/skins/default/xui/it/menu_slurl.xml b/indra/newview/skins/default/xui/it/menu_slurl.xml
index be83133efc..be83133efc 100644..100755
--- a/indra/newview/skins/default/xui/it/menu_slurl.xml
+++ b/indra/newview/skins/default/xui/it/menu_slurl.xml
diff --git a/indra/newview/skins/default/xui/it/menu_teleport_history_gear.xml b/indra/newview/skins/default/xui/it/menu_teleport_history_gear.xml
index 409a62c31b..409a62c31b 100644..100755
--- a/indra/newview/skins/default/xui/it/menu_teleport_history_gear.xml
+++ b/indra/newview/skins/default/xui/it/menu_teleport_history_gear.xml
diff --git a/indra/newview/skins/default/xui/it/menu_teleport_history_item.xml b/indra/newview/skins/default/xui/it/menu_teleport_history_item.xml
index 81053fbd65..81053fbd65 100644..100755
--- a/indra/newview/skins/default/xui/it/menu_teleport_history_item.xml
+++ b/indra/newview/skins/default/xui/it/menu_teleport_history_item.xml
diff --git a/indra/newview/skins/default/xui/it/menu_teleport_history_tab.xml b/indra/newview/skins/default/xui/it/menu_teleport_history_tab.xml
index c221f141a6..c221f141a6 100644..100755
--- a/indra/newview/skins/default/xui/it/menu_teleport_history_tab.xml
+++ b/indra/newview/skins/default/xui/it/menu_teleport_history_tab.xml
diff --git a/indra/newview/skins/default/xui/it/menu_text_editor.xml b/indra/newview/skins/default/xui/it/menu_text_editor.xml
index 4636ce9929..5b61da914e 100644..100755
--- a/indra/newview/skins/default/xui/it/menu_text_editor.xml
+++ b/indra/newview/skins/default/xui/it/menu_text_editor.xml
@@ -1,5 +1,12 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Text editor context menu">
+ <menu_item_call label="(sconosciuto)" name="Suggestion 1"/>
+ <menu_item_call label="(sconosciuto)" name="Suggestion 2"/>
+ <menu_item_call label="(sconosciuto)" name="Suggestion 3"/>
+ <menu_item_call label="(sconosciuto)" name="Suggestion 4"/>
+ <menu_item_call label="(sconosciuto)" name="Suggestion 5"/>
+ <menu_item_call label="Aggiungi al dizionario" name="Add to Dictionary"/>
+ <menu_item_call label="Aggiungi per ignorare" name="Add to Ignore"/>
<menu_item_call label="Taglia" name="Cut"/>
<menu_item_call label="Copia" name="Copy"/>
<menu_item_call label="Incolla" name="Paste"/>
diff --git a/indra/newview/skins/default/xui/it/menu_toolbars.xml b/indra/newview/skins/default/xui/it/menu_toolbars.xml
index 604ca763d1..604ca763d1 100644..100755
--- a/indra/newview/skins/default/xui/it/menu_toolbars.xml
+++ b/indra/newview/skins/default/xui/it/menu_toolbars.xml
diff --git a/indra/newview/skins/default/xui/it/menu_topinfobar.xml b/indra/newview/skins/default/xui/it/menu_topinfobar.xml
index 0beb9314de..0beb9314de 100644..100755
--- a/indra/newview/skins/default/xui/it/menu_topinfobar.xml
+++ b/indra/newview/skins/default/xui/it/menu_topinfobar.xml
diff --git a/indra/newview/skins/default/xui/it/menu_url_agent.xml b/indra/newview/skins/default/xui/it/menu_url_agent.xml
index 37755d5749..e5c20fb9e9 100644..100755
--- a/indra/newview/skins/default/xui/it/menu_url_agent.xml
+++ b/indra/newview/skins/default/xui/it/menu_url_agent.xml
@@ -1,6 +1,9 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Url Popup">
- <menu_item_call label="Mostra profilo residente" name="show_agent"/>
+ <menu_item_call label="Vedi profilo" name="show_agent"/>
+ <menu_item_call label="Manda IM..." name="send_im"/>
+ <menu_item_call label="Aggiungi come amico..." name="add_friend"/>
+ <menu_item_call label="Togli amicizia..." name="remove_friend"/>
<menu_item_call label="Copia nome negli Appunti" name="url_copy_label"/>
<menu_item_call label="Copia SLurl negli Appunti" name="url_copy"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/it/menu_url_group.xml b/indra/newview/skins/default/xui/it/menu_url_group.xml
index d9a792ebdf..d9a792ebdf 100644..100755
--- a/indra/newview/skins/default/xui/it/menu_url_group.xml
+++ b/indra/newview/skins/default/xui/it/menu_url_group.xml
diff --git a/indra/newview/skins/default/xui/it/menu_url_http.xml b/indra/newview/skins/default/xui/it/menu_url_http.xml
index e0153d9169..e0153d9169 100644..100755
--- a/indra/newview/skins/default/xui/it/menu_url_http.xml
+++ b/indra/newview/skins/default/xui/it/menu_url_http.xml
diff --git a/indra/newview/skins/default/xui/it/menu_url_inventory.xml b/indra/newview/skins/default/xui/it/menu_url_inventory.xml
index a45a6bbc10..a45a6bbc10 100644..100755
--- a/indra/newview/skins/default/xui/it/menu_url_inventory.xml
+++ b/indra/newview/skins/default/xui/it/menu_url_inventory.xml
diff --git a/indra/newview/skins/default/xui/it/menu_url_map.xml b/indra/newview/skins/default/xui/it/menu_url_map.xml
index cb7935b3ed..cb7935b3ed 100644..100755
--- a/indra/newview/skins/default/xui/it/menu_url_map.xml
+++ b/indra/newview/skins/default/xui/it/menu_url_map.xml
diff --git a/indra/newview/skins/default/xui/it/menu_url_objectim.xml b/indra/newview/skins/default/xui/it/menu_url_objectim.xml
index 763e65f17c..116b652172 100644..100755
--- a/indra/newview/skins/default/xui/it/menu_url_objectim.xml
+++ b/indra/newview/skins/default/xui/it/menu_url_objectim.xml
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Url Popup">
- <menu_item_call label="Mostra informazioni oggetto" name="show_object"/>
+ <menu_item_call label="Profilo oggetto..." name="show_object"/>
+ <menu_item_call label="Blocca..." name="block_object"/>
<menu_item_call label="Mostra sulla mappa" name="show_on_map"/>
<menu_item_call label="Teleport sul luogo dell&apos;oggetto" name="teleport_to_object"/>
<menu_item_call label="Copia nome oggetto negli Appunti" name="url_copy_label"/>
diff --git a/indra/newview/skins/default/xui/it/menu_url_parcel.xml b/indra/newview/skins/default/xui/it/menu_url_parcel.xml
index a032c33585..a032c33585 100644..100755
--- a/indra/newview/skins/default/xui/it/menu_url_parcel.xml
+++ b/indra/newview/skins/default/xui/it/menu_url_parcel.xml
diff --git a/indra/newview/skins/default/xui/it/menu_url_slapp.xml b/indra/newview/skins/default/xui/it/menu_url_slapp.xml
index b368aa9141..b368aa9141 100644..100755
--- a/indra/newview/skins/default/xui/it/menu_url_slapp.xml
+++ b/indra/newview/skins/default/xui/it/menu_url_slapp.xml
diff --git a/indra/newview/skins/default/xui/it/menu_url_slurl.xml b/indra/newview/skins/default/xui/it/menu_url_slurl.xml
index 355c7dbed9..355c7dbed9 100644..100755
--- a/indra/newview/skins/default/xui/it/menu_url_slurl.xml
+++ b/indra/newview/skins/default/xui/it/menu_url_slurl.xml
diff --git a/indra/newview/skins/default/xui/it/menu_url_teleport.xml b/indra/newview/skins/default/xui/it/menu_url_teleport.xml
index c129e61f25..c129e61f25 100644..100755
--- a/indra/newview/skins/default/xui/it/menu_url_teleport.xml
+++ b/indra/newview/skins/default/xui/it/menu_url_teleport.xml
diff --git a/indra/newview/skins/default/xui/it/menu_viewer.xml b/indra/newview/skins/default/xui/it/menu_viewer.xml
index 99b7e3c4e6..52247d6c9c 100644..100755
--- a/indra/newview/skins/default/xui/it/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/it/menu_viewer.xml
@@ -17,8 +17,8 @@
<menu_item_call label="Cammina / corri / vola..." name="Walk / run / fly"/>
</menu>
<menu label="Stato" name="Status">
- <menu_item_call label="Assente" name="Set Away"/>
- <menu_item_call label="Non disponibile" name="Set Busy"/>
+ <menu_item_check label="Assente" name="Away"/>
+ <menu_item_check label="Non disturbare" name="Do Not Disturb"/>
</menu>
<menu_item_call label="Acquista L$..." name="Buy and Sell L$"/>
<menu_item_call label="Casella venditore in uscita..." name="MerchantOutbox"/>
@@ -28,17 +28,25 @@
<menu_item_call label="Preferenze..." name="Preferences"/>
<menu_item_call label="Pulsanti barra strumenti..." name="Toolbars"/>
<menu_item_call label="Nascondi tutti i controlli" name="Hide UI"/>
+ <menu_item_check label="Mostra elementi HUD" name="Show HUD Attachments"/>
<menu_item_call label="Esci da [APP_NAME]" name="Quit"/>
</menu>
<menu label="Comunica" name="Communicate">
- <menu_item_check label="Chat..." name="Nearby Chat"/>
+ <menu_item_check label="Conversazioni..." name="Conversations"/>
+ <menu_item_check label="Chat nei dintorni..." name="Nearby Chat"/>
<menu_item_check label="Parla" name="Speak"/>
- <menu_item_check label="Impostazioni voce..." name="Nearby Voice"/>
- <menu_item_check label="Manipolazione voce..." name="ShowVoice"/>
+ <menu_item_check label="Registro conversazioni..." name="Conversation Log..."/>
+ <menu label="Manipolazione voce" name="VoiceMorphing">
+ <menu_item_check label="Nessuna manipolazione voce" name="NoVoiceMorphing"/>
+ <menu_item_check label="Anteprima..." name="Preview"/>
+ <menu_item_call label="Abbonati..." name="Subscribe"/>
+ </menu>
<menu_item_check label="Gesture..." name="Gestures"/>
- <menu_item_call label="Amici" name="My Friends"/>
- <menu_item_call label="Gruppi" name="My Groups"/>
- <menu_item_call label="Persone vicine" name="Active Speakers"/>
+ <menu_item_check label="Amici" name="My Friends"/>
+ <menu_item_check label="Gruppi" name="My Groups"/>
+ <menu_item_check label="Persone vicine" name="Active Speakers"/>
+ <menu_item_call label="Blocca lista" name="Block List"/>
+ <menu_item_check label="Non disturbare" name="Do Not Disturb"/>
</menu>
<menu label="Mondo" name="World">
<menu_item_call label="Crea punto di riferimento per questo luogo" name="Create Landmark Here"/>
@@ -107,13 +115,13 @@
<menu_item_call label="Includi parte successiva" name="Include Next Part"/>
<menu_item_call label="Includi parte precedente" name="Include Previous Part"/>
</menu>
+ <menu_item_call label="Set collegati..." name="pathfinding_linkset_menu_item"/>
<menu_item_call label="Ingrandisci selezione" name="Focus on Selection"/>
<menu_item_call label="Zoom sulla selezione" name="Zoom to Selection"/>
<menu label="Oggetto" name="Object">
<menu_item_call label="Acquista" name="Menu Object Buy"/>
<menu_item_call label="Prendi" name="Menu Object Take"/>
<menu_item_call label="Prendi copia" name="Take Copy"/>
- <menu_item_call label="Salva nell&apos;inventario" name="Save Object Back to My Inventory"/>
<menu_item_call label="Salva nei contenuti oggetto" name="Save Object Back to Object Contents"/>
<menu_item_call label="Restituisci oggetto" name="Return Object back to Owner"/>
</menu>
@@ -124,6 +132,12 @@
<menu_item_call label="Imposta gli script come in esecuzione" name="Set Scripts to Running"/>
<menu_item_call label="Imposta script come non in esecuzione" name="Set Scripts to Not Running"/>
</menu>
+ <menu label="Pathfinding" name="Pathfinding">
+ <menu_item_call label="Set collegati..." name="pathfinding_linksets_menu_item"/>
+ <menu_item_call label="Personaggi..." name="pathfinding_characters_menu_item"/>
+ <menu_item_call label="Visualizza / test..." name="pathfinding_console_menu_item"/>
+ <menu_item_call label="Rebake regione" name="pathfinding_rebake_navmesh_item"/>
+ </menu>
<menu label="Opzioni" name="Options">
<menu_item_check label="Mostra autorizzazioni avanzate" name="DebugPermissions"/>
<menu_item_check label="Seleziona solo i miei oggetti" name="Select Only My Objects"/>
@@ -152,6 +166,13 @@
<menu label="Aiuto" name="Help">
<menu_item_call label="Istruzioni..." name="How To"/>
<menu_item_call label="Aiuto di [SECOND_LIFE]" name="Second Life Help"/>
+ <menu_item_call label="Guida dell&apos;utente" name="User’s guide"/>
+ <menu_item_call label="Base di conoscenza" name="Knowledge Base"/>
+ <menu_item_call label="Wiki" name="Wiki"/>
+ <menu_item_call label="Forum della comunità" name="Community Forums"/>
+ <menu_item_call label="Portale assistenza" name="Support portal"/>
+ <menu_item_call label="[SECOND_LIFE] Notizie" name="Second Life News"/>
+ <menu_item_call label="[SECOND_LIFE] Blog" name="Second Life Blogs"/>
<menu_item_call label="Segnala abuso" name="Report Abuse"/>
<menu_item_call label="Segnala bug" name="Report Bug"/>
<menu_item_call label="Informazioni su [APP_NAME]" name="About Second Life"/>
@@ -174,7 +195,6 @@
<menu_item_check label="Nascondi particelle" name="Hide Particles"/>
<menu_item_check label="Nascondi selezionati" name="Hide Selected"/>
<menu_item_check label="Evidenzia trasparenza" name="Highlight Transparent"/>
- <menu_item_check label="Mostra elementi HUD" name="Show HUD Attachments"/>
<menu_item_check label="Mostra mirino visuale soggettiva" name="ShowCrosshairs"/>
</menu>
<menu label="Modalità di rendering" name="Rendering Types">
@@ -226,11 +246,10 @@
<menu_item_check label="Console texture" name="Texture Console"/>
<menu_item_check label="Console di Debug" name="Debug Console"/>
<menu_item_call label="Console notifiche" name="Notifications"/>
- <menu_item_check label="Console dimensioni texture" name="Texture Size"/>
- <menu_item_check label="Console categoria texture" name="Texture Category"/>
<menu_item_check label="Timer veloci" name="Fast Timers"/>
<menu_item_check label="Memoria" name="Memory"/>
<menu_item_check label="Statistiche scena" name="Scene Statistics"/>
+ <menu_item_call label="Console di debug recupero texture" name="Texture Fetch Debug Console"/>
<menu_item_call label="Informazioni regione sulla console di debug" name="Region Info to Debug Console"/>
<menu_item_check label="Fotocamera" name="Camera"/>
<menu_item_check label="Vento" name="Wind"/>
@@ -260,6 +279,7 @@
<menu_item_check label="Spostamento fotocamera" name="Camera Offset"/>
<menu_item_check label="Veloc. di visualizzazione casuale" name="Randomize Framerate"/>
<menu_item_check label="Test frame" name="Frame Test"/>
+ <menu_item_call label="Profilo frame" name="Frame Profile"/>
</menu>
<menu label="Render Metadata" name="Render Metadata">
<menu_item_check label="Normali" name="Normals"/>
@@ -271,18 +291,24 @@
<menu_item_check label="Complessità rendering" name="rendercomplexity"/>
<menu_item_check label="Byte collegamento" name="attachment bytes"/>
<menu_item_check label="Scolpisci" name="Sculpt"/>
+ <menu label="Densità texture" name="Texture Density">
+ <menu_item_check label="Nessuna" name="None"/>
+ <menu_item_check label="Attuale" name="Current"/>
+ <menu_item_check label="Desiderata" name="Desired"/>
+ <menu_item_check label="Completa" name="Full"/>
+ </menu>
</menu>
<menu label="Rendering" name="Rendering">
<menu_item_check label="Assi" name="Axes"/>
+ <menu_item_call label="Info materiale selezionato" name="Selected Material Info"/>
<menu_item_check label="Wireframe" name="Wireframe"/>
- <menu_item_check label="Luci e ombre" name="Lighting and Shadows"/>
+ <menu_item_check label="Modello illuminazione avanzato" name="Advanced Lighting Model"/>
<menu_item_check label="Ombra dal sole, dalla luna e dai proiettori" name="Shadows from Sun/Moon/Projectors"/>
<menu_item_check label="SSAO e ombre fluide" name="SSAO and Shadow Smoothing"/>
<menu_item_check label="Maschera alfa automatica (differita)" name="Automatic Alpha Masks (deferred)"/>
<menu_item_check label="Maschera alfa automatica (non differita)" name="Automatic Alpha Masks (non-deferred)"/>
<menu_item_check label="Texture delle animazioni" name="Animation Textures"/>
<menu_item_check label="Disabilita texture" name="Disable Textures"/>
- <menu_item_check label="Atlante tessitura (sperimentale)" name="Texture Atlas"/>
<menu_item_check label="Rendering delle luci unite" name="Render Attached Lights"/>
<menu_item_check label="Rendering particelle unite" name="Render Attached Particles"/>
<menu_item_check label="Gli oggetti brillano quando sono sotto il cursore" name="Hover Glow Objects"/>
@@ -301,7 +327,6 @@
<menu_item_call label="Test browser multimedia" name="Web Browser Test"/>
<menu_item_call label="Browser contenuto Web" name="Web Content Browser"/>
<menu_item_call label="Stampa informazioni oggetto selezionato" name="Print Selected Object Info"/>
- <menu_item_call label="Statistiche memoria" name="Memory Stats"/>
<menu_item_check label="Console di debug regione" name="Region Debug Console"/>
<menu_item_check label="Debug clic" name="Debug Clicks"/>
<menu_item_check label="Debug eventi mouse" name="Debug Mouse Events"/>
@@ -325,9 +350,14 @@
<menu_item_call label="Alterna la geometria dei personaggi" name="Toggle Character Geometry"/>
<menu_item_check label="Consenti selezione avatar" name="Allow Select Avatar"/>
</menu>
+ <menu label="Velocità animazione" name="Animation Speed">
+ <menu_item_call label="Accelera tutte le animazioni del 10%" name="All Animations 10 Faster"/>
+ <menu_item_call label="Rallenta tutte le animazioni del 10%" name="All Animations 10 Slower"/>
+ <menu_item_call label="Ripristina la velocità di tutte le animazioni" name="Reset All Animation Speed"/>
+ <menu_item_check label="Animazioni lente" name="Slow Motion Animations"/>
+ </menu>
<menu_item_call label="Forza i parametri sui valori predefiniti" name="Force Params to Default"/>
<menu_item_check label="Informazioni sull&apos;animazione" name="Animation Info"/>
- <menu_item_check label="Animazioni lente" name="Slow Motion Animations"/>
<menu_item_check label="Disabilita livello di dettaglio" name="Disable LOD"/>
<menu_item_check label="Mostra schemi collisione" name="Show Collision Skeleton"/>
<menu_item_check label="Mostra bersaglio" name="Display Agent Target"/>
diff --git a/indra/newview/skins/default/xui/it/menu_wearable_list_item.xml b/indra/newview/skins/default/xui/it/menu_wearable_list_item.xml
index c9a02d8a86..c9a02d8a86 100644..100755
--- a/indra/newview/skins/default/xui/it/menu_wearable_list_item.xml
+++ b/indra/newview/skins/default/xui/it/menu_wearable_list_item.xml
diff --git a/indra/newview/skins/default/xui/it/menu_wearing_gear.xml b/indra/newview/skins/default/xui/it/menu_wearing_gear.xml
index de25f88aca..de25f88aca 100644..100755
--- a/indra/newview/skins/default/xui/it/menu_wearing_gear.xml
+++ b/indra/newview/skins/default/xui/it/menu_wearing_gear.xml
diff --git a/indra/newview/skins/default/xui/it/menu_wearing_tab.xml b/indra/newview/skins/default/xui/it/menu_wearing_tab.xml
index 4a5366091f..4a5366091f 100644..100755
--- a/indra/newview/skins/default/xui/it/menu_wearing_tab.xml
+++ b/indra/newview/skins/default/xui/it/menu_wearing_tab.xml
diff --git a/indra/newview/skins/default/xui/it/mime_types.xml b/indra/newview/skins/default/xui/it/mime_types.xml
index 5eda7a5752..5eda7a5752 100644..100755
--- a/indra/newview/skins/default/xui/it/mime_types.xml
+++ b/indra/newview/skins/default/xui/it/mime_types.xml
diff --git a/indra/newview/skins/default/xui/it/mime_types_linux.xml b/indra/newview/skins/default/xui/it/mime_types_linux.xml
index 3bc30b507a..3bc30b507a 100644..100755
--- a/indra/newview/skins/default/xui/it/mime_types_linux.xml
+++ b/indra/newview/skins/default/xui/it/mime_types_linux.xml
diff --git a/indra/newview/skins/default/xui/it/mime_types_mac.xml b/indra/newview/skins/default/xui/it/mime_types_mac.xml
index 3bc30b507a..3bc30b507a 100644..100755
--- a/indra/newview/skins/default/xui/it/mime_types_mac.xml
+++ b/indra/newview/skins/default/xui/it/mime_types_mac.xml
diff --git a/indra/newview/skins/default/xui/it/notifications.xml b/indra/newview/skins/default/xui/it/notifications.xml
index 0e6fee60d1..96b8c96595 100644..100755
--- a/indra/newview/skins/default/xui/it/notifications.xml
+++ b/indra/newview/skins/default/xui/it/notifications.xml
@@ -37,6 +37,12 @@
<button name="Help" text="$helptext"/>
</form>
</template>
+ <template name="okhelpignore">
+ <form>
+ <button name="OK_okhelpignore" text="$yestext"/>
+ <button name="Help_okhelpignore" text="$helptext"/>
+ </form>
+ </template>
<template name="yesnocancelbuttons">
<form>
<button name="Yes" text="$yestext"/>
@@ -204,6 +210,14 @@ Aggiungi questo potere a &apos;[ROLE_NAME]&apos;?
Aggiungi questo potere a &apos;[ROLE_NAME]&apos;?
<usetemplate name="okcancelbuttons" notext="No" yestext="Si"/>
</notification>
+ <notification name="EjectGroupMemberWarning">
+ Stai per espellere [AVATAR_NAME] dal gruppo.
+ <usetemplate ignoretext="Conferma l&apos;espulsione di un partecipante dal gruppo" name="okcancelignore" notext="Annulla" yestext="Espelli"/>
+ </notification>
+ <notification name="EjectGroupMembersWarning">
+ Stai per espellere [COUNT] membri dal gruppo.
+ <usetemplate ignoretext="Conferma l&apos;espulsione di vari partecipanti dal gruppo" name="okcancelignore" notext="Annulla" yestext="Espelli"/>
+ </notification>
<notification name="AttachmentDrop">
Stai per abbandonare il tuo accessorio.
Vuoi continuare?
@@ -360,13 +374,19 @@ Inserisci il Nome utente del tuo avatar.
Devi avere un account per entrare in [SECOND_LIFE]. Vuoi crearne uno adesso?
<url name="url">
- https://join.secondlife.com/index.php?lang=it-IT
+ [create_account_url]
</url>
<usetemplate name="okcancelbuttons" notext="Riprova" yestext="Crea un nuovo account"/>
</notification>
<notification name="InvalidCredentialFormat">
Immetti il nome utente oppure sia il nome che il cognome del tuo avatar nel campo del nome utente, quindi effettua nuovamente l&apos;accesso.
</notification>
+ <notification name="InvalidGrid">
+ &apos;[GRID]&apos; non è un identificatore di griglia valido.
+ </notification>
+ <notification name="InvalidLocationSLURL">
+ La tua posizione iniziale non ha specificato una griglia valida.
+ </notification>
<notification name="DeleteClassified">
Cancella annuncio &apos;[NAME]&apos;?
Non ci sono rimborsi per la tariffa pagata.
@@ -492,6 +512,33 @@ Visitare [_URL] per ulteriori informazioni?
</url>
<usetemplate ignoretext="L&apos;hardware di questo computer non è compatibile" name="okcancelignore" notext="No" yestext="Si"/>
</notification>
+ <notification name="IntelOldDriver">
+ È probabile che ci sia un driver aggiornato per il processore grafico. L&apos;aggiornamento dei driver della grafica può migliorare le prestazioni in maniera significativa.
+
+ Visitare [_URL] per cercare un aggiornamento del driver?
+ <url name="url">
+ http://www.intel.com/p/it_IT/support/detect/graphics
+ </url>
+ <usetemplate ignoretext="Driver grafica obsoleto" name="okcancelignore" notext="No" yestext="Sì"/>
+ </notification>
+ <notification name="AMDOldDriver">
+ È probabile che ci sia un driver aggiornato per il processore grafico. L&apos;aggiornamento dei driver della grafica può migliorare le prestazioni in maniera significativa.
+
+ Visitare [_URL] per cercare un aggiornamento del driver?
+ <url name="url">
+ http://support.amd.com/it/Pages/AMDSupportHub.aspx
+ </url>
+ <usetemplate ignoretext="Driver grafica obsoleto" name="okcancelignore" notext="No" yestext="Sì"/>
+ </notification>
+ <notification name="NVIDIAOldDriver">
+ È probabile che ci sia un driver aggiornato per il processore grafico. L&apos;aggiornamento dei driver della grafica può migliorare le prestazioni in maniera significativa.
+
+ Visitare [_URL] per cercare un aggiornamento del driver?
+ <url name="url">
+ http://www.nvidia.it/Download/index.aspx?lang=it
+ </url>
+ <usetemplate ignoretext="Driver grafica obsoleto" name="okcancelignore" notext="No" yestext="Sì"/>
+ </notification>
<notification name="UnknownGPU">
Il tuo sistema utilizza una scheda grafica che [APP_NAME] non riconosce.
Questo succede spesso con un nuovo hardware che non è stato ancora testato con [APP_NAME]. Probabilmente tutto andrà bene, ma devi riconfigurare le tue impostazioni grafiche.
@@ -589,6 +636,9 @@ Puoi unire al massimo [MAX] oggetti.
Accertati che nessuno sia bloccato e che li possiedi tutti.
</notification>
+ <notification name="CannotLinkPermanent">
+ Gli oggetti non possono essere collegati attraverso i confini.
+ </notification>
<notification name="CannotLinkDifferentOwners">
Impossibile unire perche non tutti gli oggetti hanno lo stesso proprietario.
@@ -968,6 +1018,41 @@ Offri l&apos;amicizia a [NAME]?
<button name="Cancel" text="Annulla"/>
</form>
</notification>
+ <notification label="Aggiungi lista di sostituzione automatica" name="AddAutoReplaceList">
+ Nome per la nuova lista:
+ <form name="form">
+ <button name="SetName" text="OK"/>
+ </form>
+ </notification>
+ <notification label="Rinomina lista di sostituzione automatica" name="RenameAutoReplaceList">
+ Il nome &apos;[DUPNAME]&apos; è già in uso
+ Inserisci un nuovo nome univoco:
+ <form name="form">
+ <button name="ReplaceList" text="Sostituisci lista corrente"/>
+ <button name="SetName" text="Usa nuovo nome"/>
+ </form>
+ </notification>
+ <notification name="InvalidAutoReplaceEntry">
+ La parola chiave deve essere una sola parola e la sostituzione non può essere vuota.
+ </notification>
+ <notification name="InvalidAutoReplaceList">
+ L&apos;elenco di sostituzione non è valido.
+ </notification>
+ <notification name="SpellingDictImportRequired">
+ Devi specificare un file, un nome e una lingua.
+ </notification>
+ <notification name="SpellingDictIsSecondary">
+ Sembra che il dizionario [DIC_NAME] non includa un file &quot;aff&quot;; ciò indica che di tratta di un dizionario &quot;secondario&quot;.
+Può essere usato come dizionario aggiuntivo, ma non come dizionario principale.
+
+Vedi https://wiki.secondlife.com/wiki/Adding_Spelling_Dictionaries
+ </notification>
+ <notification name="SpellingDictImportFailed">
+ Copia non eseguita da
+ [FROM_NAME]
+ a
+ [TO_NAME]
+ </notification>
<notification label="Salva vestiario" name="SaveOutfitAs">
Salva gli abiti che indosso come nuovo vestiario:
<form name="form">
@@ -1033,7 +1118,7 @@ su TUTTI I TERRENI di questa sim?
Introduci un prezzo più alto.
</notification>
<notification name="ConfirmItemDeleteHasLinks">
- Almeno uno degli oggetti selezionati è collegato tramite link ad altri oggetti. Se elimini l&apos;oggetto, i relativi link non funzioneranno più. Pertanto si consiglia vivamente di eliminare prima i link.
+ Almeno uno degli oggetti è collegato tramite link ad altri oggetti. Se elimini l&apos;oggetto, i relativi link non funzioneranno più. Si consiglia vivamente di eliminare prima i link.
Sei sicuro di volere eliminare gli oggetti?
<usetemplate name="okcancelbuttons" notext="Annulla" yestext="OK"/>
@@ -1051,9 +1136,9 @@ Confermi di voler cancellare questi elementi?
<usetemplate name="okcancelbuttons" notext="Annulla" yestext="OK"/>
</notification>
<notification name="ConfirmObjectDeleteNoOwn">
- Non possiedi neanche uno degli oggetti selezionati.
+ Non possiedi almeno uno degli oggetti selezionati.
-Confermi di voler cancellare questi elementi?
+Sei sicuro di volere eliminare gli oggetti?
<usetemplate name="okcancelbuttons" notext="Annulla" yestext="OK"/>
</notification>
<notification name="ConfirmObjectDeleteLockNoCopy">
@@ -1065,24 +1150,24 @@ Confermi di voler cancellare questi elementi?
</notification>
<notification name="ConfirmObjectDeleteLockNoOwn">
Almeno un oggetto è bloccato.
-Non possiedi neanche un oggetto.
+Non possiedi almeno uno degli oggetti.
-Confermi di voler cancellare questi elementi?
+Sei sicuro di volere eliminare gli oggetti?
<usetemplate name="okcancelbuttons" notext="Cancella" yestext="OK"/>
</notification>
<notification name="ConfirmObjectDeleteNoCopyNoOwn">
- Almeno un oggetto non è copiabile.
-Non possiedi neanche un oggetto.
+ Almeno un oggetto non può essere copiato.
+Non possiedi almeno uno degli oggetti.
-Confermi di voler cancellare questi elementi?
+Sei sicuro di volere eliminare gli oggetti?
<usetemplate name="okcancelbuttons" notext="Annulla" yestext="OK"/>
</notification>
<notification name="ConfirmObjectDeleteLockNoCopyNoOwn">
Almeno un oggetto è bloccato.
-Almeno un oggetto è non copiabile.
-Non possiedi neanche un oggetto.
+Almeno un oggetto non può essere copiato.
+Non possiedi almeno uno degli oggetti.
-Confermi di voler cancellare questi elementi?
+Sei sicuro di volere eliminare gli oggetti?
<usetemplate name="okcancelbuttons" notext="Annulla" yestext="OK"/>
</notification>
<notification name="ConfirmObjectTakeLock">
@@ -1148,7 +1233,7 @@ a &apos;[THIS_GPU]&apos;
Sei stato trasferito in una regione vicina.
</notification>
<notification name="AvatarMovedLast">
- La tua ultima posizione non è al momento disponibile.
+ La posizione richiesta non è al momento disponibile.
Sei stato trasferito in una regione vicina.
</notification>
<notification name="AvatarMovedHome">
@@ -1167,8 +1252,7 @@ Puoi comunque usare [SECOND_LIFE] normalmente e gli altri residenti ti vedranno
L&apos;installazione di [APP_NAME] è terminata.
Se questa è la prima volta che usi [SECOND_LIFE], devi creare un account prima che tu possa effettuare l&apos;accesso.
-Vuoi tornare a [http://join.secondlife.com secondlife.com] per creare un nuovo account?
- <usetemplate name="okcancelbuttons" notext="Continua" yestext="Nuovo Account..."/>
+ <usetemplate name="okcancelbuttons" notext="Continua" yestext="Crea account..."/>
</notification>
<notification name="LoginPacketNeverReceived">
Ci sono problemi di connessione. È possibile che ci siano problemi con la tua connessione Internet oppure sulla [SECOND_LIFE_GRID].
@@ -1405,13 +1489,43 @@ Versione [VERSION] [[RELEASE_NOTES_FULL_URL] Informazioni su questo aggiornament
</notification>
<notification name="RequiredUpdateDownloadedVerboseDialog">
È stato scaricato un aggiornamento obbligatorio del software.
-Versione [VERSION]
+Versione [VERSION] [[INFO_URL] Informazioni su questo aggiornamento]
Per installare l&apos;aggiornamento è necessario riavviare [APP_NAME].
<usetemplate name="okbutton" yestext="OK"/>
</notification>
<notification name="RequiredUpdateDownloadedDialog">
Per installare l&apos;aggiornamento è necessario riavviare [APP_NAME].
+[[INFO_URL] Informazioni su questo aggiornamento]
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
+ <notification name="OtherChannelDownloadBackgroundTip">
+ È stato scaricato un aggiornamento dell&apos;installazione di [APP_NAME].
+Versione [VERSION]
+Questo viewer sperimentale è stato sostituito con un viewer [NEW_CHANNEL];
+vedi [[INFO_URL] per informazioni su queesto aggiornamento]
+ <usetemplate name="okcancelbuttons" notext="Più tardi..." yestext="Installa ora e riavvia [APP_NAME]"/>
+ </notification>
+ <notification name="OtherChannelDownloadBackgroundDialog">
+ È stato scaricato un aggiornamento dell&apos;installazione di [APP_NAME].
+Versione [VERSION]
+Questo viewer sperimentale è stato sostituito con un viewer [NEW_CHANNEL];
+vedi [[INFO_URL] Informazioni su questo aggiornamento]
+ <usetemplate name="okcancelbuttons" notext="Più tardi..." yestext="Installa ora e riavvia [APP_NAME]"/>
+ </notification>
+ <notification name="OtherChannelRequiredUpdateDownloadedVerboseDialog">
+ È stato scaricato un aggiornamento obbligatorio del software.
+Versione [VERSION]
+Questo viewer sperimentale è stato sostituito con un viewer [NEW_CHANNEL];
+vedi [[INFO_URL] Informazioni su questo aggiornamento]
+
+Per installare l&apos;aggiornamento è necessario riavviare [APP_NAME].
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
+ <notification name="OtherChannelRequiredUpdateDownloadedDialog">
+ Per installare l&apos;aggiornamento è necessario riavviare [APP_NAME].
+Questo viewer sperimentale è stato sostituito con un viewer [NEW_CHANNEL];
+vedi [[INFO_URL] Informazioni su questo aggiornamento]
<usetemplate name="okbutton" yestext="OK"/>
</notification>
<notification name="DeedObjectToGroup">
@@ -1462,6 +1576,10 @@ Per installare l&apos;aggiornamento è necessario riavviare [APP_NAME].
Lasciare il gruppo?
<usetemplate name="okcancelbuttons" notext="Annulla" yestext="OK"/>
</notification>
+ <notification name="OwnerCannotLeaveGroup">
+ Impossibile abbandonare il gruppo. Non puoi abbandonare il gruppo perché sei l&apos;ultimo proprietario del gruppo. Devi prima assegnare a un altro membro il ruolo di proprietario.
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
<notification name="ConfirmKick">
Vuoi veramente espellere tutti i residenti dalla griglia?
<usetemplate name="okcancelbuttons" notext="Annulla" yestext="Espelli tutti i residenti"/>
@@ -1490,10 +1608,13 @@ Vuoi cancellare quell&apos;elemento?
Impossibile offrire l&apos;amicizia in questo momento. Riprova fra poco.
<usetemplate name="okbutton" yestext="OK"/>
</notification>
- <notification name="BusyModeSet">
- È stata impostata la modalità Non disponibile.
-La chat e gli IM verranno nascosti. Gli IM riceveranno la tua risposta di Non disponibile. Tutte le offerte di teleport verranno rifiutate. Tutte le offerte di Inventario andranno nel Cestino.
- <usetemplate ignoretext="Cambio il mio stato sulla modalità Non disponibile" name="okignore" yestext="OK"/>
+ <notification name="DoNotDisturbModeSet">
+ Non disturbare è attivo. Non riceverai la notifica delle comunicazioni in arrivo.
+
+- Gli altri residenti riceveranno la tua risposta Non disturbare (impostata in Preferenze &gt; Generali).
+- Le offerte di teleport verranno rifiutate.
+- Le chiamate voce verranno rifiutate.
+ <usetemplate ignoretext="Io cambio il mio stato alla modalità Non disturbare." name="okignore" yestext="OK"/>
</notification>
<notification name="JoinedTooManyGroupsMember">
Hai raggiunto il numero massimo di gruppi. Per favore abbandona almeno un gruppo prima di aderire a questo, oppure declina l&apos;offerta.
@@ -1689,83 +1810,128 @@ Cambierà migliaia di regioni e produrrà seri problemi ai vari server.
<usetemplate name="okcancelbuttons" notext="Annulla" yestext="OK"/>
</notification>
<notification name="RegionEntryAccessBlocked">
- Non sei ammesso in questa regione a causa della tua categoria di accesso. Questo può risultare da una mancanza di informazioni necessarie per convalidare la tua età.
-
-Verifica di avere installato l&apos;ultima versione del programma e vai alla Knowledge Base per ulteriori informazioni su come accedere nelle zone con tale categoria di accesso.
+ La regione che cerchi di visitare include contenuti che non corripondono al livello selezionato nelle preferenze. Per cambiare le preferenze seleziona Io &gt; Preferenze &gt; Generale.
<usetemplate name="okbutton" yestext="OK"/>
</notification>
- <notification name="RegionEntryAccessBlocked_KB">
- Non sei ammesso in questa regione a causa della tua categoria d&apos;accesso.
-
-Vuoi andare alla Knowledge Base per ulteriori informazioni sulle categorie di accesso?
+ <notification name="RegionEntryAccessBlocked_AdultsOnlyContent">
+ La regione che cerchi di visitare include contenuti [REGIONMATURITY] accessibili solo ad adulti.
<url name="url">
- http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview/it
+ http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview
</url>
- <usetemplate ignoretext="Non posso entrare in questa regione a causa delle restrizioni della categoria di accesso" name="okcancelignore" notext="Chiudi" yestext="Vai alla Knowledge Base"/>
+ <usetemplate ignoretext="Attraversamento regione: la regione che cerchi di visitare include contenuti accessibili solo ad adulti." name="okcancelignore" notext="Chiudi" yestext="Passa alla Base conoscenze"/>
</notification>
<notification name="RegionEntryAccessBlocked_Notify">
- Non sei ammesso in questa regione a causa della tua categoria d&apos;accesso.
+ La regione che cerchi di visitare include contenuti [REGIONMATURITY], ma le tue preferenze attuali escludono i contenuti [REGIONMATURITY].
+ </notification>
+ <notification name="RegionEntryAccessBlocked_NotifyAdultsOnly">
+ La regione che cerchi di visitare include contenuti [REGIONMATURITY] accessibili solo ad adulti.
</notification>
<notification name="RegionEntryAccessBlocked_Change">
- Non ti è consentito entrare in quella regione a causa della categoria di accesso impostata nelle preferenze.
-
-Per entrare nella regione, dovrai modificare la tua categoria di accesso. Ciò ti consentirà inoltre di effettuare ricerche di contenuti di categoria [REGIONMATURITY]. Per annullare le modifiche in un secondo momento, vai a Io &gt; Preferenze &gt; Generali.
+ La regione che cerchi di visitare include contenuti [REGIONMATURITY], ma le tue preferenze attuali escludono i contenuti [REGIONMATURITY]. Puoi modificare le tue preferenze o annullare. Dopo aver modificato le preferenze, prova nuovamente ad entrare nella regione.
<form name="form">
- <button name="OK" text="Cambia preferenza"/>
- <button default="true" name="Cancel" text="Chiudi"/>
- <ignore name="ignore" text="La categoria di accesso impostata mi impedisce di entrare in una regione"/>
+ <button name="OK" text="Modifica preferenze"/>
+ <button default="true" name="Cancel" text="Annulla"/>
+ <ignore name="ignore" text="Attraversamento regione: La regione che cerchi di visitare include contenuti esclusi nelle preferenze."/>
</form>
</notification>
+ <notification name="RegionEntryAccessBlocked_PreferencesOutOfSync">
+ Si è verificato un problema con il teleport a causa di un errore di sincronizzazione delle preferenze con il server.
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
+ <notification name="TeleportEntryAccessBlocked">
+ La regione che cerchi di visitare include contenuti che non corripondono al livello selezionato nelle preferenze. Per cambiare le preferenze seleziona Io &gt; Preferenze &gt; Generale.
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
+ <notification name="TeleportEntryAccessBlocked_AdultsOnlyContent">
+ La regione che cerchi di visitare include contenuti [REGIONMATURITY] accessibili solo ad adulti.
+ <url name="url">
+ http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview
+ </url>
+ <usetemplate ignoretext="Teleport: la regione che cerchi di visitare include contenuti accessibili solo ad adulti." name="okcancelignore" notext="Chiudi" yestext="Passa alla Base conoscenze"/>
+ </notification>
+ <notification name="TeleportEntryAccessBlocked_Notify">
+ La regione che cerchi di visitare include contenuti [REGIONMATURITY], ma le tue preferenze attuali escludono i contenuti [REGIONMATURITY].
+ </notification>
+ <notification name="TeleportEntryAccessBlocked_NotifyAdultsOnly">
+ La regione che cerchi di visitare include contenuti [REGIONMATURITY] accessibili solo ad adulti.
+ </notification>
+ <notification name="TeleportEntryAccessBlocked_ChangeAndReTeleport">
+ La regione che cerchi di visitare include contenuti [REGIONMATURITY], ma le tue preferenze attuali escludono i contenuti [REGIONMATURITY]. Puoi modificare le preferenze e continuare con il teleport oppure annullarlo.
+ <form name="form">
+ <button name="OK" text="Modifica e continua"/>
+ <button name="Cancel" text="Annulla"/>
+ <ignore name="ignore" text="Teleport (riavviabile): La regione che cerchi di visitare include contenuti esclusi nelle preferenze."/>
+ </form>
+ </notification>
+ <notification name="TeleportEntryAccessBlocked_Change">
+ La regione che cerchi di visitare include contenuti [REGIONMATURITY], ma le tue preferenze attuali escludono i contenuti [REGIONMATURITY]. Puoi modificare le tue preferenze o annullare il teleport. Dopo aver modificato le preferenze, prova nuovamente a teletrasportarti nella regione.
+ <form name="form">
+ <button name="OK" text="Modifica preferenze"/>
+ <button name="Cancel" text="Annulla"/>
+ <ignore name="ignore" text="Teleport (non riavviabile): La regione che cerchi di visitare include contenuti esclusi nelle preferenze."/>
+ </form>
+ </notification>
+ <notification name="TeleportEntryAccessBlocked_PreferencesOutOfSync">
+ Si è verificato un problema con il teleport a causa di un errore di sincronizzazione delle preferenze con il server.
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
<notification name="PreferredMaturityChanged">
- La tua categoria di accesso attuale è [RATING].
+ Non riceverai più notifiche se stai per visitare una regione con contenuti [RATING]. In futuro potrai modificare le preferenze relative ai contenuti selezionando Io &gt; Preferenze &gt; Generale nella barra del menu.
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
+ <notification name="MaturityChangeError">
+ Non è stato possibile modificare le preferenze per visualizzare contenuti [PREFERRED_MATURITY]. le preferenze sono state ripristinate per consentire la visualizzazione di contenuti [ACTUAL_MATURITY]. Puoi cercare di modificare nuovamente le preferenze selezionando Io &gt; Preferenze &gt; Generale nella barra del menu.
+ <usetemplate name="okbutton" yestext="OK"/>
</notification>
<notification name="LandClaimAccessBlocked">
- Non puoi prendere possesso di questo terreno a causa della tua categoria di accesso. Questo può essere dovuto ad una mancanza di informazioni valide che confermino la tua età.
-
-Verifica di avere installato l&apos;ultima versione del programma e vai alla Knowledge Base per informazioni sull&apos;accesso ad aree con queste categorie di accesso.
+ Il terreno che desideri richiedere ha una categoria di accesso maggiore di quella indicata nelle preferenze. Per cambiare le preferenze seleziona Io &gt; Preferenze &gt; Generale.
<usetemplate name="okbutton" yestext="OK"/>
</notification>
- <notification name="LandClaimAccessBlocked_KB">
- Non puoi prendere possesso di questa terra a causa delle preferenze sulle categorie di accesso.
-
-Vuoi andare alla Knowledge Base per maggiori informazioni sulle categorie di accesso?
+ <notification name="LandClaimAccessBlocked_AdultsOnlyContent">
+ Solo gli adulti possono richiedere questo terreno.
<url name="url">
- http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview/it
+ http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview
</url>
- <usetemplate ignoretext="Non posso richiedere questo terreno a causa delle restrizioni della categoria di accesso" name="okcancelignore" notext="Chiudi" yestext="Vai alla Knowledge Base"/>
+ <usetemplate ignoretext="Solo gli adulti possono richiedere questo terreno." name="okcancelignore" notext="Chiudi" yestext="Passa alla Base conoscenze"/>
</notification>
<notification name="LandClaimAccessBlocked_Notify">
- Non puoi prendere possesso di questa terra a causa della tua categoria di accesso.
+ Il terreno che desideri richiedere include contenuti [REGIONMATURITY], ma le tue preferenze attuali escludono i contenuti [REGIONMATURITY].
+ </notification>
+ <notification name="LandClaimAccessBlocked_NotifyAdultsOnly">
+ Il terreno che cerchi di richiedere include contenuti [REGIONMATURITY], accessibili solo ad adulti.
</notification>
<notification name="LandClaimAccessBlocked_Change">
- Non puoi richiedere questo terreno a causa della tua categoria di accesso.
-
-Puoi cliccare su Cambia preferenze per modificare la categoria di accesso e quindi riuscire ad entrare. Da adesso potrai accedere ai contenuti [REGIONMATURITY] ed effettuare ricerche in questa categoria. Se in seguito tu volessi cambiare di nuovo le tue impostazioni, apri la finestra di dialogo da Io &gt; Preferenze &gt; Generale.
- <usetemplate ignoretext="Le mie preferenze di categoria di accesso mi impediscono di richiedere terreno" name="okcancelignore" notext="Chiudi" yestext="Cambia le preferenze"/>
+ Il terreno che desideri richiedere include contenuti [REGIONMATURITY], ma le tue preferenze attuali escludono i contenuti [REGIONMATURITY]. Puoi modificare le preferenze e quindi cercare di richiedere nuovamente il terreno.
+ <form name="form">
+ <button name="OK" text="Modifica preferenze"/>
+ <button name="Cancel" text="Annulla"/>
+ <ignore name="ignore" text="Il terreno che cerchi di richiedere include contenuti esclusi nelle preferenze."/>
+ </form>
</notification>
<notification name="LandBuyAccessBlocked">
- Non puoi acquistare questo terreno a causa della tua categoria di accesso. Questo può essere dovuto ad una mancanza di informazioni valide che confermino la tua età.
-
-Verifica di avere installato l&apos;ultima versione del programma e vai alla Knowledge Base per informazioni sull&apos;accesso ad aree con queste categorie di accesso.
+ Il terreno che desideri acquistare ha una categoria di accesso maggiore di quella indicata nelle preferenze. Per cambiare le preferenze seleziona Io &gt; Preferenze &gt; Generale.
<usetemplate name="okbutton" yestext="OK"/>
</notification>
- <notification name="LandBuyAccessBlocked_KB">
- Non puoi acquistare questo terreno a causa della tua categoria di accesso.
-
-Vuoi andare alla Knowledge Base per maggiori informazioni sulle categorie di accesso?
+ <notification name="LandBuyAccessBlocked_AdultsOnlyContent">
+ Solo gli adulti possono acquistare questo terreno.
<url name="url">
- http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview/it
+ http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview
</url>
- <usetemplate ignoretext="Non posso acquistare questo terreno a causa delle restrizioni della categoria di accesso" name="okcancelignore" notext="Chiudi" yestext="Vai alla Knowledge Base"/>
+ <usetemplate ignoretext="Solo gli adulti possono acquistare questo terreno." name="okcancelignore" notext="Chiudi" yestext="Passa alla Base conoscenze"/>
</notification>
<notification name="LandBuyAccessBlocked_Notify">
- Non puoi acquistare questa land a causa della tua categoria di accesso.
+ Il terreno che cerchi di acquistare include contenuti [REGIONMATURITY], ma le tue preferenze attuali escludono i contenuti [REGIONMATURITY].
+ </notification>
+ <notification name="LandBuyAccessBlocked_NotifyAdultsOnly">
+ Il terreno che cerchi di acquistare include contenuti [REGIONMATURITY], accessibili solo ad adulti.
</notification>
<notification name="LandBuyAccessBlocked_Change">
- Non puoi acquistare questo terreno a causa della tua categoria di accesso.
-
-Puoi cliccare su Cambia preferenze per modificare la categoria di accesso e quindi riuscire ad entrare. Da adesso potrai accedere ai contenuti [REGIONMATURITY] ed effettuare ricerche in questa categoria. Se in seguito tu volessi cambiare di nuovo le tue impostazioni, apri la finestra di dialogo da Io &gt; Preferenze &gt; Generale.
- <usetemplate ignoretext="Le mie Preferenze di accesso mi impediscono di acquistare terreno" name="okcancelignore" notext="Chiudi" yestext="Cambia le preferenze"/>
+ Il terreno che cerchi di acquistare include contenuti [REGIONMATURITY], ma le tue preferenze attuali escludono i contenuti [REGIONMATURITY]. Puoi modificare le preferenze e quindi cercare di acquistare nuovamente il terreno.
+ <form name="form">
+ <button name="OK" text="Modifica preferenze"/>
+ <button name="Cancel" text="Annulla"/>
+ <ignore name="ignore" text="Il terreno che cerchi di acquistare include contenuti esclusi nelle preferenze."/>
+ </form>
</notification>
<notification name="TooManyPrimsSelected">
Hai selezionato troppi prim. Seleziona non più di [MAX_PRIM_COUNT] prim e riprova
@@ -1820,10 +1986,9 @@ Pubblica questo annuncio adesso per [AMOUNT]L$?
</form>
</notification>
<notification label="Cambiato il contenuto Moderato" name="RegionMaturityChange">
- La classificazione di questa regione è stata aggiornata.
-Un periodo di tempo è necessario prima che la modifica venga integrata nella mappa.
-
-Per accedere a regioni per adulti, i residenti devono avere un Account verificato, mediante verifica dell&apos;età oppure mediante verifica della modalità di pagamento.
+ La classificazione di questa regione è stata modificata.
+Prima che questa modifica venga integrata nella mappa potrebbe essere necessario un po&apos; di tempo.
+ <usetemplate name="okbutton" yestext="OK"/>
</notification>
<notification label="Versione voice non compatibile" name="VoiceVersionMismatch">
Questa versione di [APP_NAME] non è compatibile con la funzionalità di chat vocale in questa regione. Affinché la chat vocale funzioni correttamente, dovrai aggiornare [APP_NAME].
@@ -1937,6 +2102,10 @@ Trasferisci gli elementi nell&apos;inventario?
Vai al [http://secondlife.com/account/ Dashboard] per vedere la cronologia del tuo account?
<usetemplate ignoretext="Lancia il browser per vedere la cronologia del mio account" name="okcancelignore" notext="Annulla" yestext="Vai alla pagina"/>
</notification>
+ <notification name="ConfirmAddingChatParticipants">
+ Quando aggiungi una persona a una conversazione esistente, viene creata una nuova conversazione. Tutti i partecipanti riceveranno notifiche per la nuova conversazione.
+ <usetemplate ignoretext="Conferma l&apos;aggiunta dei partecipanti alla chat" name="okcancelignore" notext="Annulla" yestext="Ok"/>
+ </notification>
<notification name="ConfirmQuit">
Confermi di voler uscire?
<usetemplate ignoretext="Conferma prima di uscire" name="okcancelignore" notext="Non uscire" yestext="Esci"/>
@@ -2011,14 +2180,14 @@ Vuoi sostituirlo con l&apos;oggetto selezionato?
<button ignore="Never Replace" name="No" text="Annulla"/>
</form>
</notification>
- <notification label="Avviso di &apos;Occupato&apos;" name="BusyModePay">
- Sei in modalità &apos;Occupato&apos;, ciò significa che non riceverai ciò che attendi per questo pagamento.
+ <notification label="Avviso modalità Non disturbare" name="DoNotDisturbModePay">
+ Hai attivato la modalità Non disturbare. Non riceverai alcun oggetto offerto in cambio di questo pagamento.
-Desideri abbandonare la modalità &apos;Occupato&apos; prima di completare questa transazione?
+Vuoi disattivare la modalità Non disturbare prima di completare questa transazione?
<form name="form">
- <ignore name="ignore" save_option="true" text="Sto per pagare una persona o un oggetto mentro sono in modalià Non disponibile"/>
- <button ignore="Always leave Busy Mode" name="Yes" text="OK"/>
- <button ignore="Never leave Busy Mode" name="No" text="Abbandona"/>
+ <ignore name="ignore" text="Sto per pagare una persona o un oggetto mentre sono in modalità Non disturbare"/>
+ <button ignore="Lascia sempre la modalità Non disturbare" name="Yes" text="OK"/>
+ <button ignore="Non lasciare mai la modalità Non disturbare" name="No" text="Annulla"/>
</form>
</notification>
<notification name="ConfirmDeleteProtectedCategory">
@@ -2114,14 +2283,11 @@ Inseriscilo in una pagina web per dare ad altri un accesso facile a questa ubica
<usetemplate ignoretext="Indossare gli abiti che creo mentre modifico il mio aspetto" name="okcancelignore" notext="No" yestext="Si"/>
</notification>
<notification name="NotAgeVerified">
- Per accedere ai contenuti e alle aree per adulti in Second Life devi avere almeno 18 anni. Visita la pagina di verifica dell&apos;età per confermare di avere almeno 18 anni.
-Verrà avviato il browser Web.
-
-[_URL]
- <url name="url" option="0">
- https://secondlife.com/my/account/verification.php
- </url>
- <usetemplate ignoretext="Non ho verificato la mia età" name="okcancelignore" notext="Annulla" yestext="Passa alla verifica dell&apos;età"/>
+ Il luogo che desideri visitare è limitato a persone di almeno 18 anni di età.
+ <usetemplate ignoretext="Non ho l&apos;età necessaria per visitare aree limitate." name="okignore" yestext="OK"/>
+ </notification>
+ <notification name="NotAgeVerified_Notify">
+ Posizione limitata a persone maggiori di 18 anni di età.
</notification>
<notification name="Cannot enter parcel: no payment info on file">
Per poter visitare questa zona devi avere devi aver fornito informazioni di pagamento a Linden Lab. Vuoi andare sul sito di [SECOND_LIFE] ed impostarle?
@@ -2156,11 +2322,8 @@ Verrà avviato il browser Web.
<notification name="GroupNotice">
Oggetto: [SUBJECT], Messaggio: [MESSAGE]
</notification>
- <notification name="FriendOnline">
- &lt;nolink&gt;[NAME]&lt;/nolink&gt; è online
- </notification>
- <notification name="FriendOffline">
- &lt;nolink&gt;[NAME]&lt;/nolink&gt; è offline
+ <notification name="FriendOnlineOffline">
+ &lt;nolink&gt;[NAME]&lt;/nolink&gt; è [STATUS]
</notification>
<notification name="AddSelfFriend">
Anche se sei molto simpatico, non puoi aggiungere te stesso all&apos;elenco degli amici.
@@ -2280,9 +2443,7 @@ Seleziona solo un oggetto.
scegliere Teleport.)
</notification>
<notification name="TeleportToPerson">
- Per contattare Residenti come &apos;[NAME]&apos;, clicca sul pulsante &quot;Persone&quot;, seleziona un Residente nel pannello che viene aperto, quindi clicca su &apos;IM&apos; in
- basso nel pannello.
- (Puoi anche fare doppio clic sul nome nell&apos;elenco oppure fare clic con il pulsante destro del mouse e selezionare &apos;IM&apos;).
+ Per avviare una conversazione privata con un&apos;altra persona, fai clic con il tasto destro sull&apos;avatar e seleziona &apos;IM&apos; dal menu.
</notification>
<notification name="CantSelectLandFromMultipleRegions">
Non è possibile selezionare il terreno attraverso i confini del server.
@@ -2382,6 +2543,16 @@ Qui non puoi volare.
<notification name="NoBuild">
In questa zona è proibita la costruzione. Qui non puoi costruire né rezzare oggetti.
</notification>
+ <notification name="PathfindingDirty">
+ La regione ha modifiche di pathfinding in sospeso. Se hai le autorizzazioni necessarie per la costruzione puoi eseguire il rebake facendo clic sul pulsante “Rebake regioneâ€.
+ </notification>
+ <notification name="DynamicPathfindingDisabled">
+ Il pathfinding dinamico non è attivato in questa regione. Gli oggetti scriptati che usano chiamate LSL di pathfinding potrebbero non funzionare come previsto in questa regione.
+ </notification>
+ <notification name="PathfindingCannotRebakeNavmesh">
+ Si è verificato un errore. Potrebbe trattarsi di un problema di rete o del server, oppure potresti non avere le autorizzazioni necessarie per la costruzione. A volte il problema viene risolto uscendo ed eseguendo nuovamente l&apos;accesso.
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
<notification name="SeeAvatars">
In questo lotto non si possono vedere avatar e chat di testo presenti in altri lotti. Non puoi vedere altri residenti fuori dal lotto e loro non possono vederti. Viene bloccata anche la normale chat di testo sul canale 0.
</notification>
@@ -2400,9 +2571,7 @@ Qui funzionano soltanto gli script del proprietario del terreno.
Puoi solo richiedere terreni pubblici nella regione in cui sei posizionato.
</notification>
<notification name="RegionTPAccessBlocked">
- Non puoi entrare in quella regione a causa della tua categoria di accesso. Può essere necessario validare l&apos;età e/o installare l&apos;ultima versione del programma.
-
-Visita la Knowledge Base per informazioni sull&apos;accesso alle aree con queste categorie di accesso.
+ La regione che cerchi di visitare include contenuti che non corripondono al livello selezionato nelle preferenze. Per cambiare le preferenze seleziona Io &gt; Preferenze &gt; Generale.
</notification>
<notification name="URBannedFromRegion">
Tu hai l&apos;accesso bloccato a questa regione.
@@ -2413,8 +2582,11 @@ Visita la Knowledge Base per informazioni sull&apos;accesso alle aree con queste
<notification name="ImproperPaymentStatus">
Non hai una impostazioni di pagamento corrette per entrare in questa regione.
</notification>
+ <notification name="MustGetAgeRegion">
+ Per poter entrare in questa regione devi avere almeno 18 anni.
+ </notification>
<notification name="MustGetAgeParcel">
- Devi essere di età verificata per entrare in questa terra.
+ Per poter entrare in questo lotto devi avere almeno 18 anni.
</notification>
<notification name="NoDestRegion">
Non è stata trovata nessuna regione di destinazione.
@@ -2516,12 +2688,33 @@ Riprova tra qualche istante.
<notification name="TeleportOffered">
[NAME_SLURL] ti ha offerto il teleport alla sua ubicazione:
-[MESSAGE] - [MATURITY_STR] &lt;icon&gt;[MATURITY_ICON]&lt;/icon&gt;
+“[MESSAGE]â€
+&lt;icon&gt;[MATURITY_ICON]&lt;/icon&gt; - [MATURITY_STR]
<form name="form">
<button name="Teleport" text="Teleport"/>
<button name="Cancel" text="Cancella"/>
</form>
</notification>
+ <notification name="TeleportOffered_MaturityExceeded">
+ [NAME_SLURL] ti ha offerto il teleport alla sua ubicazione:
+
+“[MESSAGE]â€
+&lt;icon&gt;[MATURITY_ICON]&lt;/icon&gt; - [MATURITY_STR]
+
+Questa regione include contenuti [REGION_CONTENT_MATURITY], ma le tue preferenze attuali escludono i contenuti [REGION_CONTENT_MATURITY]. Puoi modificare le preferenze e continuare con il teleport oppure annullarlo.
+ <form name="form">
+ <button name="Teleport" text="Modifica e continua"/>
+ <button name="Cancel" text="Annulla"/>
+ </form>
+ </notification>
+ <notification name="TeleportOffered_MaturityBlocked">
+ [NAME_SLURL] ti ha offerto il teleport alla sua ubicazione:
+
+“[MESSAGE]â€
+&lt;icon&gt;[MATURITY_ICON]&lt;/icon&gt; - [MATURITY_STR]
+
+Questa regione include però contenuti accessibili solo agli adulti.
+ </notification>
<notification name="TeleportOfferSent">
Offerta di Teleport inviata a [TO_NAME]
</notification>
@@ -2616,16 +2809,21 @@ OK?
</form>
</notification>
<notification name="ScriptQuestionCaution">
- Un oggetto di nome &apos;&lt;nolink&gt;[OBJECTNAME]&lt;/nolink&gt;&apos;, posseduto da &apos;[NAME]&apos; vorrebbe:
-
-[QUESTIONS]
-Se non ti fidi di questo oggetto e del suo ideatore, dovresti rifiutare la richiesta.
-
-Concedi questa richiesta?
+ Avviso: L&apos;oggetto &apos;&lt;nolink&gt;[OBJECTNAME]&lt;/nolink&gt;&apos; ha richiesto accesso completo al tuo account in Dollari Linden. Se consenti l&apos;accesso, potrà rimuovere fondi dal tuo account in qualunque momento e anche svuotare completamente l&apos;account, per un periodo illimitato e senza ulteriori avvisi.
+
+Non consentire l&apos;accesso se non comprendi perfettamente il motivo per cui desidera accedere al tuo account.
<form name="form">
- <button name="Grant" text="Accetta"/>
+ <button name="Grant" text="Consenti accesso totale"/>
<button name="Deny" text="Nega"/>
- <button name="Details" text="Dettagli..."/>
+ </form>
+ </notification>
+ <notification name="UnknownScriptQuestion">
+ L&apos;autorizzazione per script runtime richiesta da &apos;&lt;nolink&gt;[OBJECTNAME]&lt;/nolink&gt;&apos;, un oggetto di proprietà di &apos;[NAME]&apos;, non è stata riconosciuta nel viewer e non può essere concessa.
+
+Per concedere questa autorizzazione è necessario che il viewer venga aggiornato alla versione più recente da [DOWNLOADURL].
+ <form name="form">
+ <button name="Deny" text="Ok"/>
+ <button name="Mute" text="Blocca"/>
</form>
</notification>
<notification name="ScriptDialog">
@@ -2929,6 +3127,10 @@ Hai caricato una texture [RESOLUTION] completata per &apos;[BODYREGION]&apos; do
( In esistenza da [EXISTENCE] secondi)
Hai aggiornato localmente una texture [RESOLUTION] completata per &apos;[BODYREGION]&apos; dopo [TIME] secondi.
</notification>
+ <notification name="LivePreviewUnavailable">
+ Non possiamo mostrare un&apos;anteprima di questa texture perché non ne è consentita la copia e/o il trasferimento.
+ <usetemplate ignoretext="Avvisami se la modalità Anteprima dal vivo non è disponibile per texture per cui non è consentita la copia e/o il trasferimento." name="okignore" yestext="OK"/>
+ </notification>
<notification name="ConfirmLeaveCall">
Sei sicuro di volere uscire dalla chiamata?
<usetemplate ignoretext="Conferma prima di uscire dalla chiamata" name="okcancelignore" notext="No" yestext="Sì"/>
@@ -3100,6 +3302,62 @@ Clicca e trascina dovunque nel mondo per ruotare la visuale
Questa azione cancellerà tutte le voci di menu e i pulsanti. Per visualizzarli nuovamente cliccare ancora [SHORTCUT].
<usetemplate ignoretext="Conferma prima di nascondere l&apos;interfaccia" name="okcancelignore" notext="Annulla" yestext="OK"/>
</notification>
+ <notification name="PathfindingLinksets_WarnOnPhantom">
+ L&apos;indicatore oggetto fantasma di alcuni set collegati verrà commutato.
+
+Vuoi continuare?
+ <usetemplate ignoretext="L&apos;indicatore oggetto fantasma di alcuni set collegati verrà commutato." name="okcancelignore" notext="Annulla" yestext="OK"/>
+ </notification>
+ <notification name="PathfindingLinksets_MismatchOnRestricted">
+ Alcuni set collegati selezionati non possono essere impostati su &apos;[REQUESTED_TYPE]&apos; a causa di limitazioni nelle autorizzazioni per i set collegati. Questi set collegati verranno invece impostati su &apos;[RESTRICTED_TYPE]&apos;.
+
+Vuoi continuare?
+ <usetemplate ignoretext="Alcuni set collegati selezionati non possono essere impostati a causa di limitazioni nelle autorizzazioni per i set collegati." name="okcancelignore" notext="Annulla" yestext="OK"/>
+ </notification>
+ <notification name="PathfindingLinksets_MismatchOnVolume">
+ Alcuni set collegati selezionati non possono essere impostati a &apos;[REQUESTED_TYPE]&apos; perché la forma è non-convessa.
+
+Vuoi continuare?
+ <usetemplate ignoretext="Alcuni set collegati selezionati non possono essere impostati perché la forma è non-convessa." name="okcancelignore" notext="Annulla" yestext="OK"/>
+ </notification>
+ <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnRestricted">
+ L&apos;indicatore oggetto fantasma di alcuni set collegati verrà commutato.
+
+Alcuni set collegati selezionati non possono essere impostati su &apos;[REQUESTED_TYPE]&apos; a causa di limitazioni nelle autorizzazioni per i set collegati. Questi set collegati verranno invece impostati su &apos;[RESTRICTED_TYPE]&apos;.
+
+Vuoi continuare?
+ <usetemplate ignoretext="L&apos;indicatore oggetto fantasma per alcuni set collegati selezionati verrà commutato, mentre quello degli altri non può essere impostato a causa di limitazioni nelle autorizzazioni per i set collegati." name="okcancelignore" notext="Annulla" yestext="OK"/>
+ </notification>
+ <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnVolume">
+ L&apos;indicatore oggetto fantasma di alcuni set collegati verrà commutato.
+
+Alcuni set collegati selezionati non possono essere impostati a &apos;[REQUESTED_TYPE]&apos; perché la forma è non-convessa.
+
+Vuoi continuare?
+ <usetemplate ignoretext="L&apos;indicatore oggetto fantasma per alcuni set collegati selezionati verrà commutato, mentre quello degli altri non può essere impostato perché la forma è non-convessa." name="okcancelignore" notext="Annulla" yestext="OK"/>
+ </notification>
+ <notification name="PathfindingLinksets_MismatchOnRestricted_MismatchOnVolume">
+ Alcuni set collegati selezionati non possono essere impostati su &apos;[REQUESTED_TYPE]&apos; a causa di limitazioni nelle autorizzazioni per i set collegati. Questi set collegati verranno invece impostati su &apos;[RESTRICTED_TYPE]&apos;.
+
+Alcuni set collegati selezionati non possono essere impostati a &apos;[REQUESTED_TYPE]&apos; perché la forma è non-convessa. Il tipo di utilizzo di questi set collegati non cambierà.
+
+Vuoi continuare?
+ <usetemplate ignoretext="Alcuni set collegati selezionati non possono essere impostati a causa delle limitazioni nelle autorizzazioni per il set collegato e perché la forma è non-convessa." name="okcancelignore" notext="Annulla" yestext="OK"/>
+ </notification>
+ <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnRestricted_MismatchOnVolume">
+ L&apos;indicatore oggetto fantasma di alcuni set collegati verrà commutato.
+
+Alcuni set collegati selezionati non possono essere impostati su &apos;[REQUESTED_TYPE]&apos; a causa di limitazioni nelle autorizzazioni per i set collegati. Questi set collegati verranno invece impostati su &apos;[RESTRICTED_TYPE]&apos;.
+
+Alcuni set collegati selezionati non possono essere impostati a &apos;[REQUESTED_TYPE]&apos; perché la forma è non-convessa. Il tipo di utilizzo di questi set collegati non cambierà.
+
+Vuoi continuare?
+ <usetemplate ignoretext="L&apos;indicatore oggetto fantasma per alcuni set collegati selezionati verrà commutato, mentre quello degli altri non può essere impostato a causa delle limitazioni nelle autorizzazioni per il set collegato e perché la forma è non-convessa." name="okcancelignore" notext="Annulla" yestext="OK"/>
+ </notification>
+ <notification name="PathfindingLinksets_ChangeToFlexiblePath">
+ L&apos;oggetto selezionato influenza il navmesh. Se lo si trasforma in un percorso flessibile verrà rimosso dal navmesh.
+ <usetemplate ignoretext="L&apos;oggetto selezionato influenza il navmesh. Se lo si trasforma in un percorso flessibile verrà rimosso dal navmesh." name="okcancelignore" notext="Annulla" yestext="OK"/>
+ </notification>
<global name="UnsupportedGLRequirements">
Non sembra che tu abbia i requisiti hardware adeguati per [APP_NAME]. [APP_NAME] richiede una scheda grafica OpenGL con supporto multitexture. Se ne hai una in dotazione, accertati di avere i driver, i service pack e i patch più recenti per la scheda grafica e per il sistema operativo.
@@ -3124,4 +3382,653 @@ In alternativa, puoi guardare sulla mappa e trovare luoghi segnalati come &quot;
<global name="You died and have been teleported to your home location">
Sei deceduto e sei stato teleportato a casa tua.
</global>
+ <notification name="LocalBitmapsUpdateFileNotFound">
+ [FNAME] non è stato aggiornato perché il file non è stato più trovato.
+Gli aggiornamenti futuri per questo file sono disattivati.
+ </notification>
+ <notification name="LocalBitmapsUpdateFailedFinal">
+ [FNAME] non è stato aperto o decodificato dopo [NRETRIES] tentativi, viene considerato danneggiato.
+Gli aggiornamenti futuri per questo file sono disattivati.
+ </notification>
+ <notification name="LocalBitmapsVerifyFail">
+ Tentativo di aggiungere un file immagine [FNAME] non valido o non leggibile che non è stato possibile aprire o decodificare.
+Tentativo annullato.
+ </notification>
+ <notification name="PathfindingReturnMultipleItems">
+ Stai per restituire [NUM_ITEMS] elementi. Vuoi continuare?
+ <usetemplate ignoretext="Sei sicuro di volere restituire più oggetti?" name="okcancelignore" notext="No" yestext="Sì"/>
+ </notification>
+ <notification name="PathfindingDeleteMultipleItems">
+ Stai per cancellare [NUM_ITEMS] elementi. Vuoi continuare?
+ <usetemplate ignoretext="Sei sicuro di volere eliminare più oggetti?" name="okcancelignore" notext="No" yestext="Sì"/>
+ </notification>
+ <notification name="AvatarFrozen">
+ [AV_FREEZER] ti ha congelato. Non ti puoi muovere o interagire con il mondo.
+ </notification>
+ <notification name="AvatarFrozenDuration">
+ [AV_FREEZER] ti ha congelato per [AV_FREEZE_TIME] secondi. Non ti puoi muovere o interagire con il mondo.
+ </notification>
+ <notification name="YouFrozeAvatar">
+ Avatar congelato.
+ </notification>
+ <notification name="AvatarHasUnFrozenYou">
+ [AV_FREEZER] ti ha scongelato.
+ </notification>
+ <notification name="AvatarUnFrozen">
+ Avatar scongelato.
+ </notification>
+ <notification name="AvatarFreezeFailure">
+ La congelazione non ha avuto successo perché non hai le autorizzazioni dell&apos;amministratore per quel lotto.
+ </notification>
+ <notification name="AvatarFreezeThaw">
+ Non sei più congelato, puoi continuare.
+ </notification>
+ <notification name="AvatarCantFreeze">
+ Non puoi congelare quell&apos;utente.
+ </notification>
+ <notification name="NowOwnObject">
+ Sei ora il proprietario dell&apos;oggetto [OBJECT_NAME]
+ </notification>
+ <notification name="CantRezOnLand">
+ Non puoi rezzare l&apos;oggetto a [OBJECT_POS] perché non è consentito dal proprietario del terreno. Usa lo strumento terreno per visualizzare a chi appartiene il terreno.
+ </notification>
+ <notification name="RezFailTooManyRequests">
+ Oggetto non razzato perché ci sono troppe richieste.
+ </notification>
+ <notification name="SitFailCantMove">
+ Non puoi sederti perché al momento non puoi muoverti.
+ </notification>
+ <notification name="SitFailNotAllowedOnLand">
+ Non puoi sederti perché non ti è consentito entrare in quel terreno.
+ </notification>
+ <notification name="SitFailNotSameRegion">
+ Proba ad avvicinarti. Non puoi sederti su un oggetto perché
+non è nella stessa regione in cui ti trovi.
+ </notification>
+ <notification name="NoNewObjectRegionFull">
+ Impossibile creare il nuovo oggetto. La regione è piena.
+ </notification>
+ <notification name="FailedToPlaceObject">
+ Il posizionamento dell&apos;oggetto nella posizione specificata non è riuscito. Riprova.
+ </notification>
+ <notification name="NoOwnNoGardening">
+ Non puoi creare alberi ed erba su terreni che non sono di tua proprietà.
+ </notification>
+ <notification name="NoCopyPermsNoObject">
+ Copia non riuscita perché non hai l&apos;autorizzazione necessaria per copiare l&apos;oggetto &apos;[OBJ_NAME]&apos;.
+ </notification>
+ <notification name="NoTransPermsNoObject">
+ La copia non è riuscita perché &apos;[OBJ_NAME]&apos; non può essere trasferito a te.
+ </notification>
+ <notification name="AddToNavMeshNoCopy">
+ La copia non è riuscita perché &apos;[OBJ_NAME]&apos; contribuisce al navmesh.
+ </notification>
+ <notification name="DupeWithNoRootsSelected">
+ Duplicato senza oggetto principale selezionato.
+ </notification>
+ <notification name="CantDupeCuzRegionIsFull">
+ Impossibile duplicare gli oggetti perché la regione è piena.
+ </notification>
+ <notification name="CantDupeCuzParcelNotFound">
+ Impossibile duplicare gli oggetti - Impossibile trovare i lotti in cui si trovano.
+ </notification>
+ <notification name="CantCreateCuzParcelFull">
+ Impossibile creare l&apos;oggetto perché
+il lotto è pieno.
+ </notification>
+ <notification name="RezAttemptFailed">
+ Tentativo di rezzare un oggetto non riuscito.
+ </notification>
+ <notification name="ToxicInvRezAttemptFailed">
+ Impossibile creare un oggetto che ha causato problemi in questa regione.
+ </notification>
+ <notification name="InvItemIsBlacklisted">
+ L&apos;oggetto dell&apos;inventario è stato aggiunto alla blacklist.
+ </notification>
+ <notification name="NoCanRezObjects">
+ Al momento non ti è consentito creare oggetti.
+ </notification>
+ <notification name="LandSearchBlocked">
+ Ricerca terreno bloccata.
+Hai eseguito troppe ricerche terreno in un breve tempo.
+Riprova tra un minuto.
+ </notification>
+ <notification name="NotEnoughResourcesToAttach">
+ Risorse di script non sufficienti per collegare l&apos;oggetto.
+ </notification>
+ <notification name="YouDiedAndGotTPHome">
+ Sei deceduto e sei stato teleportato alla tua posizione iniziale
+ </notification>
+ <notification name="EjectComingSoon">
+ Non sei più benvenuto qui e hai [EJECT_TIME] secondi per andartene.
+ </notification>
+ <notification name="NoEnterServerFull">
+ Non puoi entrare in questa regione perché
+il server è pieno.
+ </notification>
+ <notification name="SaveBackToInvDisabled">
+ Opzione Salva nell&apos;inventario disattivata
+ </notification>
+ <notification name="NoExistNoSaveToContents">
+ Impossibile salvare &apos;[OBJ_NAME]&apos; nei contenuti dell&apos;oggetto perché l&apos;oggetto da cui è stato razzato non esiste più.
+ </notification>
+ <notification name="NoModNoSaveToContents">
+ Impossibile salvare &apos;[OBJ_NAME]&apos; nei contenuti dell&apos;oggetto perché non hai l&apos;autorizzazione necessaria per modificare l&apos;oggetto &apos;[DEST_NAME]&apos;.
+ </notification>
+ <notification name="NoSaveBackToInvDisabled">
+ Impossibile riportare &apos;[OBJ_NAME]&apos; nell&apos;inventario -- questa operazione è stata disattivata.
+ </notification>
+ <notification name="NoCopyNoSelCopy">
+ Non puoi copiare l&apos;elemento selezionato perché non hai l&apos;autorizzazione necessaria per copiare l&apos;oggetto &apos;[OBJ_NAME]&apos;.
+ </notification>
+ <notification name="NoTransNoSelCopy">
+ Non puoi copiare la selezione perché l&apos;oggetto &apos;[OBJ_NAME]&apos; non può essere trasferito.
+ </notification>
+ <notification name="NoTransNoCopy">
+ Non puoi copiare la selezione perché l&apos;oggetto &apos;[OBJ_NAME]&apos; non può essere trasferito.
+ </notification>
+ <notification name="NoPermsNoRemoval">
+ La rimozione dell&apos;oggetto &apos;[OBJ_NAME]&apos; dal simulatore non è consentita dal sistema delle autorizzazioni.
+ </notification>
+ <notification name="NoModNoSaveSelection">
+ Non puoi salvare l&apos;elemento selezionato perché non hai l&apos;autorizzazione necessaria per modificare l&apos;oggetto &apos;[OBJ_NAME]&apos;.
+ </notification>
+ <notification name="NoCopyNoSaveSelection">
+ Non puoi salvare la selezione perché l&apos;oggetto &apos;[OBJ_NAME]&apos; non può essere copiato.
+ </notification>
+ <notification name="NoModNoTaking">
+ Non puoi prendere l&apos;elemento selezionato perché non hai l&apos;autorizzazione necessaria per modificare l&apos;oggetto &apos;[OBJ_NAME]&apos;.
+ </notification>
+ <notification name="RezDestInternalError">
+ Errore interno: Tipo di destinazione sconosciuto.
+ </notification>
+ <notification name="DeleteFailObjNotFound">
+ Cancellazione non riuscita perché l&apos;oggetto non è stato trovato.
+ </notification>
+ <notification name="SorryCantEjectUser">
+ Non puoi espellere quell&apos;utente.
+ </notification>
+ <notification name="RegionSezNotAHome">
+ Questa regione non ti consente di impostare qui la tua posizione iniziale.
+ </notification>
+ <notification name="HomeLocationLimits">
+ Puoi impostare la tua posizione iniziale nel tuo terreno o in un Infohub sulla terraferma.
+ </notification>
+ <notification name="HomePositionSet">
+ Posizione di base impostata.
+ </notification>
+ <notification name="AvatarEjected">
+ Avatar espulso.
+ </notification>
+ <notification name="AvatarEjectFailed">
+ L&apos;espulsione non ha avuto successo perché non hai l&apos;autorizzazione dell&apos;amministratore del lotto.
+ </notification>
+ <notification name="CantMoveObjectParcelFull">
+ Impossibile muovere l&apos;oggetto &apos;[OBJECT_NAME]&apos; a
+[OBJ_POSITION] nella regione [REGION_NAME] perché il lotto è pieno.
+ </notification>
+ <notification name="CantMoveObjectParcelPerms">
+ Impossibile muovere l&apos;oggetto &apos;[OBJECT_NAME]&apos; a
+[OBJ_POSITION] nella regione [REGION_NAME] perché i tuoi oggetti non sono ammessi su questo lotto.
+ </notification>
+ <notification name="CantMoveObjectParcelResources">
+ Impossibile muovere l&apos;oggetto &apos;[OBJECT_NAME]&apos; a
+[OBJ_POSITION] nella regione [REGION_NAME] perché non ci sono risorse sufficienti per l&apos;oggetto su questo lotto.
+ </notification>
+ <notification name="CantMoveObjectRegionVersion">
+ Impossibile muovere l&apos;oggetto &apos;[OBJECT_NAME]&apos; a
+[OBJ_POSITION] nella regione [REGION_NAME] perché nell&apos;altra regione è in esecuzione una versione precedente che non consente la ricezione di questo oggetto attraverso i confini tra regioni.
+ </notification>
+ <notification name="CantMoveObjectNavMesh">
+ Impossibile muovere l&apos;oggetto &apos;[OBJECT_NAME]&apos; a
+[OBJ_POSITION] nella regione [REGION_NAME] perché non puoi modificare il navmesh attraverso il confine tra regioni.
+ </notification>
+ <notification name="CantMoveObjectWTF">
+ Impossibile muovere l&apos;oggetto &apos;[OBJECT_NAME]&apos; a
+[OBJ_POSITION] nella regione [REGION_NAME] per un motivo sconosciuto. ([FAILURE_TYPE])
+ </notification>
+ <notification name="NoPermModifyObject">
+ Non hai l&apos;autorizzazione necessaria per modificare questa immagine
+ </notification>
+ <notification name="CantEnablePhysObjContributesToNav">
+ Non è possibile attivare la fisica per un oggetto che contribuisce al navmesh.
+ </notification>
+ <notification name="CantEnablePhysKeyframedObj">
+ Impossibile attivare la fisica per oggetti keyframe.
+ </notification>
+ <notification name="CantEnablePhysNotEnoughLandResources">
+ Impossibile attivare la fisica per l&apos;oggetto -- risorse di terreno insufficienti.
+ </notification>
+ <notification name="CantEnablePhysCostTooGreat">
+ Impossibile attivare la fisica per un oggetto con un costo delle risorse della fisica maggiore di [MAX_OBJECTS]
+ </notification>
+ <notification name="PhantomWithConcavePiece">
+ Questo oggetto non può avere un pezzo concavo perché è un oggetto fantasma e contribuisce al navmesh.
+ </notification>
+ <notification name="UnableAddItem">
+ Aggiunta elemento non riuscita
+ </notification>
+ <notification name="UnableEditItem">
+ Impossibile modificare questo elemento.
+ </notification>
+ <notification name="NoPermToEdit">
+ Non sei autorizzato a modificare questo elemento.
+ </notification>
+ <notification name="NoPermToCopyInventory">
+ Non ti è permesso copiare quell&apos;inventario.
+ </notification>
+ <notification name="CantSaveItemDoesntExist">
+ Impossibile salvare i contenuti dell&apos;oggetto: L&apos;elemento non esiste più.
+ </notification>
+ <notification name="CantSaveItemAlreadyExists">
+ Impossibile salvare i contenuti dell&apos;oggetto: Nell&apos;inventario esiste già un elemento con quel nome.
+ </notification>
+ <notification name="CantSaveModifyAttachment">
+ Impossibile salvare i contenuti dell&apos;oggetto: Verrebbero modificate le autorizzazioni per il collegamento.
+ </notification>
+ <notification name="TooManyScripts">
+ Troppi script.
+ </notification>
+ <notification name="UnableAddScript">
+ Aggiunta script non riuscita.
+ </notification>
+ <notification name="AssetServerTimeoutObjReturn">
+ Il server degli asset non ha inviato una risposta entro il tempo massimo. Oggetto restituito al sim.
+ </notification>
+ <notification name="RegionDisablePhysicsShapes">
+ In questa regione non sono attivate le forme per la fisica.
+ </notification>
+ <notification name="NoModNavmeshAcrossRegions">
+ Non puoi modificare il navmesh attraverso il confine tra le regioni.
+ </notification>
+ <notification name="NoSetPhysicsPropertiesOnObjectType">
+ Impossibile impostare le proprietà della fisica per quel tipo di oggetto.
+ </notification>
+ <notification name="NoSetRootPrimWithNoShape">
+ impossibile impostare un prim principale senza forma.
+ </notification>
+ <notification name="NoRegionSupportPhysMats">
+ In questa regione non sono attivati i materiali per la fisica.
+ </notification>
+ <notification name="OnlyRootPrimPhysMats">
+ I materiali per la fisica possono essere modificati solo i prim principali.
+ </notification>
+ <notification name="NoSupportCharacterPhysMats">
+ L&apos;impostazione dei materiali per la fisica nei caratteri non è ancora supportata.
+ </notification>
+ <notification name="InvalidPhysMatProperty">
+ Almeno una delle proprietà dei materiali per la fisica non è valida.
+ </notification>
+ <notification name="NoPermsAlterStitchingMeshObj">
+ Non puoi alterare il tipo di punto di un oggetto con reticolo
+ </notification>
+ <notification name="NoPermsAlterShapeMeshObj">
+ Non puoi alterare la forma di un oggetto con reticolo
+ </notification>
+ <notification name="FullRegionCantEnter">
+ Non puoi entrare in questa regione perché è piena.
+ </notification>
+ <notification name="LinkFailedOwnersDiffer">
+ Collegamento non riuscito -- i proprietari non corrispondono
+ </notification>
+ <notification name="LinkFailedNoModNavmeshAcrossRegions">
+ Collegamento non riuscito -- non puoi modificare il navmesh attraverso il confine tra le regioni.
+ </notification>
+ <notification name="LinkFailedNoPermToEdit">
+ Collegamento non riuscito perché non hai le autorizzazioni necessarie per la modifica.
+ </notification>
+ <notification name="LinkFailedTooManyPrims">
+ Collegamento non riuscito -- troppe primitive.
+ </notification>
+ <notification name="LinkFailedCantLinkNoCopyNoTrans">
+ Collegamento non riuscito -- impossibile collegare elementi senza copia ed elementi senza trasferimento
+ </notification>
+ <notification name="LinkFailedNothingLinkable">
+ Collegamento non riuscito -- niente di collegabile.
+ </notification>
+ <notification name="LinkFailedTooManyPathfindingChars">
+ Collegamento non riuscito -- troppi personaggi con pathfinding
+ </notification>
+ <notification name="LinkFailedInsufficientLand">
+ Collegamento non riuscito -- risorse terreno non sufficienti
+ </notification>
+ <notification name="LinkFailedTooMuchPhysics">
+ L&apos;oggetto usa troppe risorse per la fisica -- le sue dinamiche sono state disattivate.
+ </notification>
+ <notification name="TeleportedHomeByObjectOnParcel">
+ Sei stato teleportato nella posizione iniziale dall&apos;oggetto &apos;[OBJECT_NAME]&apos; del lotto &apos;[PARCEL_NAME]&apos;
+ </notification>
+ <notification name="TeleportedHomeByObject">
+ Sei stato teleportato nella tua posizione iniziale dall&apos;oggetto &apos;[OBJECT_NAME]&apos;
+ </notification>
+ <notification name="TeleportedByAttachment">
+ Sei stato teletrasportato da un elemento collegato a [ITEM_ID]
+ </notification>
+ <notification name="TeleportedByObjectOnParcel">
+ Sei stato teleportato dall&apos;oggetto &apos;[OBJECT_NAME]&apos; sul lotto &apos;[PARCEL_NAME]&apos;
+ </notification>
+ <notification name="TeleportedByObjectOwnedBy">
+ Sei stato teleportato dall&apos;oggetto &apos;[OBJECT_NAME]&apos; di proprietà di [OWNER_ID]
+ </notification>
+ <notification name="TeleportedByObjectUnknownUser">
+ Sei stato teleportato dall&apos;oggetto &apos;[OBJECT_NAME]&apos; di proprietà di un utente sconosciuto.
+ </notification>
+ <notification name="CantCreateObjectRegionFull">
+ Impossibile creare l&apos;oggetto richiesto. La regione è piena.
+ </notification>
+ <notification name="CantAttackMultipleObjOneSpot">
+ Non puoi collegare più oggetti a un singolo luogo.
+ </notification>
+ <notification name="CantCreateMultipleObjAtLoc">
+ Non puoi creare oggetti multipli in questa posizione.
+ </notification>
+ <notification name="UnableToCreateObjTimeOut">
+ Impossibile creare l&apos;oggetto richiesto. L&apos;oggetto non è presente nel database.
+ </notification>
+ <notification name="UnableToCreateObjUnknown">
+ Impossibile creare l&apos;oggetto richiesto. Tempo scaduto per la richiesta. Riprova.
+ </notification>
+ <notification name="UnableToCreateObjMissingFromDB">
+ Impossibile creare l&apos;oggetto richiesto. Riprova.
+ </notification>
+ <notification name="RezFailureTookTooLong">
+ Rezzing non riuscito. Il caricamento dell&apos;oggetto richiesto è durato troppo a lungo.
+ </notification>
+ <notification name="FailedToPlaceObjAtLoc">
+ Il posizionamento dell&apos;oggetto nella posizione specificata non è riuscito. Riprova.
+ </notification>
+ <notification name="CantCreatePlantsOnLand">
+ Non puoi creare piante su questo terreno.
+ </notification>
+ <notification name="CantRestoreObjectNoWorldPos">
+ Impossibile ripristinare l&apos;oggetto. Nessuna posizione trovata nel mondo virtuale.
+ </notification>
+ <notification name="CantRezObjectInvalidMeshData">
+ Impossibile rezzare l&apos;oggetto perché i dati del reticolo non sono validi.
+ </notification>
+ <notification name="CantRezObjectTooManyScripts">
+ Impossibile rezzare l&apos;oggetto perché ci sono già troppi script in questa regione.
+ </notification>
+ <notification name="CantCreateObjectNoAccess">
+ Le tue autorizzazioni di accesso non ti permettono di creare oggetti in quella posizione.
+ </notification>
+ <notification name="CantCreateObject">
+ Al momento non ti è consentito creare oggetti.
+ </notification>
+ <notification name="InvalidObjectParams">
+ Parametri oggetto non validi
+ </notification>
+ <notification name="CantDuplicateObjectNoAcess">
+ Le tue autorizzazioni di accesso non ti permettono di duplicare oggetti in questa posizione.
+ </notification>
+ <notification name="CantChangeShape">
+ Non ti è consentito modificare questa forma.
+ </notification>
+ <notification name="NoAccessToClaimObjects">
+ Le tue autorizzazioni di accesso non ti permettono di richiedere oggetti in questa posizione.
+ </notification>
+ <notification name="DeedFailedNoPermToDeedForGroup">
+ Assegnazione non riuscita perché non hai l&apos;autorizzazione necessaria per assegnare oggetti per il tuo gruppo.
+ </notification>
+ <notification name="NoPrivsToBuyObject">
+ Le tue autorizzazioni di accesso non ti permettono di acquistare oggetti in questa posizione.
+ </notification>
+ <notification name="CantAttachObjectAvatarSittingOnIt">
+ Impossibile collegare l&apos;oggetto perché un avatar è seduto sopra.
+ </notification>
+ <notification name="WhyAreYouTryingToWearShrubbery">
+ Alberi ed erba non possono essere indossati come collegati.
+ </notification>
+ <notification name="CantAttachGroupOwnedObjs">
+ Impossibile collegare oggetti di proprietà di un gruppo.
+ </notification>
+ <notification name="CantAttachObjectsNotOwned">
+ Non puoi collegare oggetti che non sono di tua proprietà.
+ </notification>
+ <notification name="CantAttachNavmeshObjects">
+ Impossibile collegare oggetti che contribuiscono a navmesh.
+ </notification>
+ <notification name="CantAttachObjectNoMovePermissions">
+ L&apos;oggetto non può essere collegato perché non sei autorizzato a muoverlo.
+ </notification>
+ <notification name="CantAttachNotEnoughScriptResources">
+ Risorse di script non sufficienti per collegare l&apos;oggetto.
+ </notification>
+ <notification name="CantDropItemTrialUser">
+ Non puoi lasciare oggetti qui, prova la zona Prova gratuita.
+ </notification>
+ <notification name="CantDropMeshAttachment">
+ Non puoi lasciare elementi collegati con reticolo. Separa nell&apos;inventario e quindi rezza nel mondo virtuale.
+ </notification>
+ <notification name="CantDropAttachmentNoPermission">
+ Impossibile rimuovere l&apos;elemento collegato: non hai l&apos;autorizzazione necessaria per rimuoverlo qui.
+ </notification>
+ <notification name="CantDropAttachmentInsufficientLandResources">
+ Impossibile rimuovere l&apos;elemento collegato: risorse terreno disponibili non sufficienti.
+ </notification>
+ <notification name="CantDropAttachmentInsufficientResources">
+ Impossibile rimuovere gli elementi collegati: risorse disponibili non sufficienti.
+ </notification>
+ <notification name="CantDropObjectFullParcel">
+ Non puoi lasciare l&apos;oggetto qui. Il lotto è pieno.
+ </notification>
+ <notification name="CantTouchObjectBannedFromParcel">
+ Non puoi toccare/afferrare questo oggetto perché sei stato bandito dal lotto di terreno.
+ </notification>
+ <notification name="PlzNarrowDeleteParams">
+ Limita i parametri per la cancellazione.
+ </notification>
+ <notification name="UnableToUploadAsset">
+ Impossibile caricare l&apos;asset.
+ </notification>
+ <notification name="CantTeleportCouldNotFindUser">
+ Utente da teleportare alla posizione iniziale non trovato
+ </notification>
+ <notification name="GodlikeRequestFailed">
+ richiesta superpoteri non riuscita
+ </notification>
+ <notification name="GenericRequestFailed">
+ richiesta generica non riuscita
+ </notification>
+ <notification name="CantUploadPostcard">
+ Impossibile caricare la cartolina. Riprova più tardi.
+ </notification>
+ <notification name="CantFetchInventoryForGroupNotice">
+ I dettagli dell&apos;inventario per la notifica di gruppo non sono stati trovati.
+ </notification>
+ <notification name="CantSendGroupNoticeNotPermitted">
+ Impossibile inviare la notifica di gruppo -- non consentita.
+ </notification>
+ <notification name="CantSendGroupNoticeCantConstructInventory">
+ Impossibile inviare la notifica di gruppo -- impossibile costruire l&apos;inventario.
+ </notification>
+ <notification name="CantParceInventoryInNotice">
+ Impossibile analizzare l&apos;inventario nella notifica.
+ </notification>
+ <notification name="TerrainUploadFailed">
+ Caricamento terreno non riuscito.
+ </notification>
+ <notification name="TerrainFileWritten">
+ File terreno scritto.
+ </notification>
+ <notification name="TerrainFileWrittenStartingDownload">
+ File terreno generato, avvio del download...
+ </notification>
+ <notification name="TerrainBaked">
+ Baking terreno completata.
+ </notification>
+ <notification name="TenObjectsDisabledPlzRefresh">
+ Sono stati disattivati solo i primi 10 oggetti. Se necessario, aggiorna e seleziona nuovamente.
+ </notification>
+ <notification name="UpdateViewerBuyParcel">
+ Devi aggiornare il Viewer per poter acquistare questo lotto.
+ </notification>
+ <notification name="CantBuyParcelNotForSale">
+ Impossibile acquistare, questo lotto non è in vendita.
+ </notification>
+ <notification name="CantBuySalePriceOrLandAreaChanged">
+ Impossibile acquistare. Il prezzo o l&apos;area del terreno sono stati cambiati.
+ </notification>
+ <notification name="CantBuyParcelNotAuthorized">
+ Non sei l&apos;acquirente autorizzato di questo lotto.
+ </notification>
+ <notification name="CantBuyParcelAwaitingPurchaseAuth">
+ Non puoi acquistare questo lotto perché è in attesa di autorizzazione all&apos;acquisto
+ </notification>
+ <notification name="CantBuildOverflowParcel">
+ Non puoi costruire oggetti qui perché si supererebbe il limite per il lotto.
+ </notification>
+ <notification name="SelectedMultipleOwnedLand">
+ hai selezionato terreni con proprietari diversi. Seleziona un&apos;area più piccola e riprova.
+ </notification>
+ <notification name="CantJoinTooFewLeasedParcels">
+ Non sono stati selezionati abbastanza lotti affittati da collegare.
+ </notification>
+ <notification name="CantDivideLandMultipleParcelsSelected">
+ Terreno non divisibile.\nHai selezionato più di un lotto.\nProva a selezionare una quantità di terreno più piccola.
+ </notification>
+ <notification name="CantDivideLandCantFindParcel">
+ impossibile suddividere il terreno.\nimpossibile trovare il lotto.\nInvia una segnalazione con Aiuto -&gt; Segnala bug...
+ </notification>
+ <notification name="CantDivideLandWholeParcelSelected">
+ Impossibile suddividere il terreno. È stato selezionato l&apos;intero lotto.\nProva a selezionare un pezzo di terreno più piccolo.
+ </notification>
+ <notification name="LandHasBeenDivided">
+ Il terreno è stato diviso.
+ </notification>
+ <notification name="PassPurchased">
+ Hai acquistato un pass.
+ </notification>
+ <notification name="RegionDisallowsClassifieds">
+ Nella regione non sono permessi gli annunci pubblicitari.
+ </notification>
+ <notification name="LandPassExpireSoon">
+ Il tuo pass per questo terreno è quasi scaduto.
+ </notification>
+ <notification name="CantSitNoSuitableSurface">
+ Nessuna superficie adatta a sedersi, prova un altro luogo.
+ </notification>
+ <notification name="CantSitNoRoom">
+ Non c&apos;è posto per sedersi, prova un altro luogo.
+ </notification>
+ <notification name="ClaimObjectFailedNoPermission">
+ La richiesta dell&apos;oggetto non ha avuto successo perché non hai l&apos;autorizzazione necessaria.
+ </notification>
+ <notification name="ClaimObjectFailedNoMoney">
+ La richiesta dell&apos;oggetto non ha avuto successo perché non hai L$ sufficienti.
+ </notification>
+ <notification name="CantDeedGroupLand">
+ Non puoi assegnare terreno di proprietà di un gruppo.
+ </notification>
+ <notification name="BuyObjectFailedNoMoney">
+ L&apos;acquisto dell&apos;oggetto non ha avuto successo perché non hai L$ sufficienti.
+ </notification>
+ <notification name="BuyInventoryFailedNoMoney">
+ L&apos;acquisto dell&apos;inventario non ha avuto successo perché non hai L$ sufficienti.
+ </notification>
+ <notification name="BuyPassFailedNoMoney">
+ Non hai abbastanza L$ per acquistare un pass per questo terreno.
+ </notification>
+ <notification name="CantBuyPassTryAgain">
+ Al momento non puoi acquistare un pass. Riprova più tardi.
+ </notification>
+ <notification name="CantCreateObjectParcelFull">
+ Impossibile creare l&apos;oggetto perché il lotto è pieno.
+ </notification>
+ <notification name="FailedPlacingObject">
+ Il posizionamento dell&apos;oggetto nella posizione specificata non è riuscito. Riprova.
+ </notification>
+ <notification name="CantCreateLandmarkForEvent">
+ Impossibile creare il punto di riferimento per l&apos;evento.
+ </notification>
+ <notification name="GodBeatsFreeze">
+ I tuoi superpoteri hanno interrotto la congelazione.
+ </notification>
+ <notification name="SpecialPowersRequestFailedLogged">
+ Richiesta di poteri speciali non riuscita. La richiesta è stata registrata.
+ </notification>
+ <notification name="ExpireExplanation">
+ Al momento il sistema non è in grado di elaborare la tua richiesta. Tempo scaduto per la richiesta.
+ </notification>
+ <notification name="DieExplanation">
+ Il sistema non è in grado di elaborare la tua richiesta.
+ </notification>
+ <notification name="AddPrimitiveFailure">
+ Denaro insufficiente per creare una primitiva.
+ </notification>
+ <notification name="RezObjectFailure">
+ Denaro insufficiente per creare un oggetto.
+ </notification>
+ <notification name="ResetHomePositionNotLegal">
+ Posizione iniziale ripristinata perché non era valida.
+ </notification>
+ <notification name="CantInviteRegionFull">
+ Al momento non puoi invitare nessuno alla tua posizione perché la regione è piena. Riprova più tardi.
+ </notification>
+ <notification name="CantSetHomeAtRegion">
+ Questa regione non ti consente di impostare qui la tua posizione iniziale.
+ </notification>
+ <notification name="ListValidHomeLocations">
+ Puoi impostare la tua posizione iniziale nel tuo terreno o in un Infohub sulla terraferma.
+ </notification>
+ <notification name="SetHomePosition">
+ Posizione di base impostata.
+ </notification>
+ <notification name="CantDerezInventoryError">
+ Impossibile derazzare l&apos;oggetto a causa di un errore nell&apos;inventario.
+ </notification>
+ <notification name="CantCreateRequestedInv">
+ Impossibile creare l&apos;inventario richiesto.
+ </notification>
+ <notification name="CantCreateRequestedInvFolder">
+ Impossibile creare la cartella dell&apos;inventario richiesta.
+ </notification>
+ <notification name="CantCreateInventory">
+ Impossibile creare quell&apos;inventario.
+ </notification>
+ <notification name="CantCreateLandmark">
+ Impossibile creare il punto di riferimento.
+ </notification>
+ <notification name="CantCreateOutfit">
+ Il vestiario non può essere creato in questo momento. Riprova tra un minuto.
+ </notification>
+ <notification name="InventoryNotForSale">
+ L&apos;inventario non è in vendita.
+ </notification>
+ <notification name="CantFindInvItem">
+ Impossibile trovare l&apos;elemento nell&apos;inventario.
+ </notification>
+ <notification name="CantFindObject">
+ Impossibile trovare l&apos;oggetto.
+ </notification>
+ <notification name="CantTransfterMoneyRegionDisabled">
+ Il trasferimento di denaro agli oggetti è attualmente disattivato in questa regione.
+ </notification>
+ <notification name="CantPayNoAgent">
+ Non si capisce chi deve essere pagato.
+ </notification>
+ <notification name="CantDonateToPublicObjects">
+ Non puoi dare L$ a oggetti pubblici.
+ </notification>
+ <notification name="InventoryCreationInWorldObjectFailed">
+ Creazione inventario non riuscito per un oggetto nel mondo virtuale.
+ </notification>
+ <notification name="UserBalanceOrLandUsageError">
+ Un errore interno ha impedito l&apos;aggiornamento del Viewer. Il saldo in L$ o i lotti posseduti mostrati nel Viewer potrebbero non corrispondere ai valori correnti sui server.
+ </notification>
+ <notification name="LargePrimAgentIntersect">
+ Non puoi creare prim grandi che intersecano altri giocatori. Riprova quando gli altri giocatori si sono spostati.
+ </notification>
+ <notification name="PreferenceChatClearLog">
+ Verranno cancellati i registri delle conversazioni precedenti e tutti gli eventuali backup di quel file.
+ <usetemplate ignoretext="Conferma prima di cancellare il registro delle conversazioni precedenti." name="okcancelignore" notext="Annulla" yestext="OK"/>
+ </notification>
+ <notification name="PreferenceChatDeleteTranscripts">
+ Verranno cancellate le trascrizioni di tutte le conversazioni precedenti. L&apos;elenco delle conversazioni passate non cambierà. Tutti i file con i suffissi .txt e txt.backup nella cartella [FOLDER] verranno cancellati.
+ <usetemplate ignoretext="Conferma prima di cancellare le trascrizioni." name="okcancelignore" notext="Annulla" yestext="OK"/>
+ </notification>
+ <notification name="PreferenceChatPathChanged">
+ Impossibile spostare i file. Il percorso precedente è stato ripristinato.
+ <usetemplate ignoretext="Impossibile spostare i file. Il percorso precedente è stato ripristinato." name="okignore" yestext="OK"/>
+ </notification>
</notifications>
diff --git a/indra/newview/skins/default/xui/it/outfit_accordion_tab.xml b/indra/newview/skins/default/xui/it/outfit_accordion_tab.xml
index bac885e5d8..bac885e5d8 100644..100755
--- a/indra/newview/skins/default/xui/it/outfit_accordion_tab.xml
+++ b/indra/newview/skins/default/xui/it/outfit_accordion_tab.xml
diff --git a/indra/newview/skins/default/xui/it/panel_active_object_row.xml b/indra/newview/skins/default/xui/it/panel_active_object_row.xml
index b8cca6f01a..b8cca6f01a 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_active_object_row.xml
+++ b/indra/newview/skins/default/xui/it/panel_active_object_row.xml
diff --git a/indra/newview/skins/default/xui/it/panel_adhoc_control_panel.xml b/indra/newview/skins/default/xui/it/panel_adhoc_control_panel.xml
index be001d09f8..be001d09f8 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_adhoc_control_panel.xml
+++ b/indra/newview/skins/default/xui/it/panel_adhoc_control_panel.xml
diff --git a/indra/newview/skins/default/xui/it/panel_avatar_list_item.xml b/indra/newview/skins/default/xui/it/panel_avatar_list_item.xml
index ede19b9e5a..cfceb5b982 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_avatar_list_item.xml
+++ b/indra/newview/skins/default/xui/it/panel_avatar_list_item.xml
@@ -26,5 +26,6 @@
<icon name="permission_edit_mine_icon" tool_tip="Questo amico può modificare, cancellare o prendere i tuoi oggetti"/>
<icon name="permission_map_icon" tool_tip="Questo amico può identificarti sulla mappa"/>
<icon name="permission_online_icon" tool_tip="Questo amico può vedere se sei online"/>
+ <button name="info_btn" tool_tip="Maggiori informazioni"/>
<button name="profile_btn" tool_tip="Vedi profilo"/>
</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_block_list_sidetray.xml b/indra/newview/skins/default/xui/it/panel_block_list_sidetray.xml
index 610f561a65..7ca2d3b57b 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_block_list_sidetray.xml
+++ b/indra/newview/skins/default/xui/it/panel_block_list_sidetray.xml
@@ -1,10 +1,11 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel name="block_list_panel">
- <text name="title_text">
- Blocca lista
- </text>
- <scroll_list name="blocked" tool_tip="Lista degli attuali residenti bloccati"/>
- <button label="Blocca il residente..." label_selected="Blocca il residente..." name="Block resident..." tool_tip="Scegli un residente da bloccare"/>
- <button label="Blocca l&apos;oggetto per nome..." label_selected="Blocca l&apos;oggetto per nome..." name="Block object by name..."/>
- <button label="Sblocca" label_selected="Sblocca" name="Unblock" tool_tip="Rimuovi un residente o un oggetto dalla lista bloccati"/>
+ <panel label="bottom_panel" name="blocked_buttons_panel">
+ <filter_editor label="Filtro" name="blocked_filter_input"/>
+ <menu_button name="blocked_gear_btn" tool_tip="Azioni sulla persona o oggetto selezionato"/>
+ <menu_button name="view_btn" tool_tip="Opzioni Ordina"/>
+ <menu_button name="plus_btn" tool_tip="Seleziona un residente o un oggetto da bloccare"/>
+ <button name="unblock_btn" tool_tip="Rimuovi un residente o un oggetto dalla lista bloccati"/>
+ </panel>
+ <block_list name="blocked" tool_tip="Lista degli attuali residenti bloccati"/>
</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_body_parts_list_item.xml b/indra/newview/skins/default/xui/it/panel_body_parts_list_item.xml
index b44c4c29e6..b44c4c29e6 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_body_parts_list_item.xml
+++ b/indra/newview/skins/default/xui/it/panel_body_parts_list_item.xml
diff --git a/indra/newview/skins/default/xui/it/panel_bodyparts_list_button_bar.xml b/indra/newview/skins/default/xui/it/panel_bodyparts_list_button_bar.xml
index 8fc23d34f1..8fc23d34f1 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_bodyparts_list_button_bar.xml
+++ b/indra/newview/skins/default/xui/it/panel_bodyparts_list_button_bar.xml
diff --git a/indra/newview/skins/default/xui/it/panel_bottomtray.xml b/indra/newview/skins/default/xui/it/panel_bottomtray.xml
deleted file mode 100644
index 3d12473c87..0000000000
--- a/indra/newview/skins/default/xui/it/panel_bottomtray.xml
+++ /dev/null
@@ -1,47 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel name="bottom_tray">
- <string name="DragIndicationImageName" value="Accordion_ArrowOpened_Off"/>
- <string name="SpeakBtnToolTip" value="Accende o spegne il microfono"/>
- <string name="VoiceControlBtnToolTip" value="Mostra o nasconde il pannello di regolazione voce"/>
- <layout_stack name="toolbar_stack">
- <layout_panel name="speak_panel">
- <talk_button name="talk">
- <speak_button label="Parla" label_selected="Parla" name="speak_btn"/>
- </talk_button>
- </layout_panel>
- <layout_panel name="gesture_panel">
- <gesture_combo_list label="Gesture" name="Gesture" tool_tip="Mostra o nasconde le gesture"/>
- </layout_panel>
- <layout_panel name="movement_panel">
- <bottomtray_button label="Sposta" name="movement_btn" tool_tip="Mostra o nasconde i comandi del movimento"/>
- </layout_panel>
- <layout_panel name="cam_panel">
- <bottomtray_button label="Visuale" name="camera_btn" tool_tip="Mostra o nasconde le regolazioni della visuale"/>
- </layout_panel>
- <layout_panel name="snapshot_panel">
- <bottomtray_button label="" name="snapshots" tool_tip="Scatta una foto"/>
- </layout_panel>
- <layout_panel name="build_btn_panel">
- <bottomtray_button label="Costruisci" name="build_btn" tool_tip="Mostra o nasconde gli strumenti di costruzione"/>
- </layout_panel>
- <layout_panel name="search_btn_panel">
- <bottomtray_button label="Cerca" name="search_btn" tool_tip="Mostra o nasconde la ricerca"/>
- </layout_panel>
- <layout_panel name="world_map_btn_panel">
- <bottomtray_button label="Mappa" name="world_map_btn" tool_tip="Mostra o nasconde la mappa del mondo"/>
- </layout_panel>
- <layout_panel name="mini_map_btn_panel">
- <bottomtray_button label="Mini mappa" name="mini_map_btn" tool_tip="Mostra o nasconde la mini mappa"/>
- </layout_panel>
- <layout_panel name="im_well_panel">
- <chiclet_im_well name="im_well">
- <button name="Unread IM messages" tool_tip="Conversazioni"/>
- </chiclet_im_well>
- </layout_panel>
- <layout_panel name="notification_well_panel">
- <chiclet_notification name="notification_well">
- <button name="Unread" tool_tip="Notifiche"/>
- </chiclet_notification>
- </layout_panel>
- </layout_stack>
-</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_bottomtray_lite.xml b/indra/newview/skins/default/xui/it/panel_bottomtray_lite.xml
index ff576c7dd2..ff576c7dd2 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_bottomtray_lite.xml
+++ b/indra/newview/skins/default/xui/it/panel_bottomtray_lite.xml
diff --git a/indra/newview/skins/default/xui/it/panel_chiclet_bar.xml b/indra/newview/skins/default/xui/it/panel_chiclet_bar.xml
index 66bf3f140f..66bf3f140f 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_chiclet_bar.xml
+++ b/indra/newview/skins/default/xui/it/panel_chiclet_bar.xml
diff --git a/indra/newview/skins/default/xui/it/panel_classified_info.xml b/indra/newview/skins/default/xui/it/panel_classified_info.xml
index a7cf51c4b9..a7cf51c4b9 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_classified_info.xml
+++ b/indra/newview/skins/default/xui/it/panel_classified_info.xml
diff --git a/indra/newview/skins/default/xui/it/panel_clothing_list_button_bar.xml b/indra/newview/skins/default/xui/it/panel_clothing_list_button_bar.xml
index e9d9795b3a..e9d9795b3a 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_clothing_list_button_bar.xml
+++ b/indra/newview/skins/default/xui/it/panel_clothing_list_button_bar.xml
diff --git a/indra/newview/skins/default/xui/it/panel_clothing_list_item.xml b/indra/newview/skins/default/xui/it/panel_clothing_list_item.xml
index 7667e95663..7667e95663 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_clothing_list_item.xml
+++ b/indra/newview/skins/default/xui/it/panel_clothing_list_item.xml
diff --git a/indra/newview/skins/default/xui/it/panel_cof_wearables.xml b/indra/newview/skins/default/xui/it/panel_cof_wearables.xml
index d914a5740f..d914a5740f 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_cof_wearables.xml
+++ b/indra/newview/skins/default/xui/it/panel_cof_wearables.xml
diff --git a/indra/newview/skins/default/xui/it/panel_conversation_list_item.xml b/indra/newview/skins/default/xui/it/panel_conversation_list_item.xml
new file mode 100644
index 0000000000..ca6b65300a
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/panel_conversation_list_item.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="conversation_list_item">
+ <layout_stack name="conversation_item_stack">
+ <layout_panel name="conversation_title_panel">
+ <text name="conversation_title" value="(caricamento in corso)"/>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_conversation_log_list_item.xml b/indra/newview/skins/default/xui/it/panel_conversation_log_list_item.xml
new file mode 100644
index 0000000000..624eaa639c
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/panel_conversation_log_list_item.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="conversation_log_list_item">
+ <icon name="voice_session_icon" tool_tip="La conversazione includeva la voce"/>
+ <icon name="unread_ims_icon" tool_tip="Sono arrivati dei messaggi mentre eri via"/>
+ <button name="delete_btn" tool_tip="Elimina questo elemento"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_deletable_wearable_list_item.xml b/indra/newview/skins/default/xui/it/panel_deletable_wearable_list_item.xml
index cbcaa0689a..cbcaa0689a 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_deletable_wearable_list_item.xml
+++ b/indra/newview/skins/default/xui/it/panel_deletable_wearable_list_item.xml
diff --git a/indra/newview/skins/default/xui/it/panel_dummy_clothing_list_item.xml b/indra/newview/skins/default/xui/it/panel_dummy_clothing_list_item.xml
index eb3af5f2a5..eb3af5f2a5 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_dummy_clothing_list_item.xml
+++ b/indra/newview/skins/default/xui/it/panel_dummy_clothing_list_item.xml
diff --git a/indra/newview/skins/default/xui/it/panel_edit_alpha.xml b/indra/newview/skins/default/xui/it/panel_edit_alpha.xml
index 6daa0cf8fd..6daa0cf8fd 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_edit_alpha.xml
+++ b/indra/newview/skins/default/xui/it/panel_edit_alpha.xml
diff --git a/indra/newview/skins/default/xui/it/panel_edit_classified.xml b/indra/newview/skins/default/xui/it/panel_edit_classified.xml
index ad827696ff..ad827696ff 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_edit_classified.xml
+++ b/indra/newview/skins/default/xui/it/panel_edit_classified.xml
diff --git a/indra/newview/skins/default/xui/it/panel_edit_eyes.xml b/indra/newview/skins/default/xui/it/panel_edit_eyes.xml
index 9f31bb7dc7..9f31bb7dc7 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_edit_eyes.xml
+++ b/indra/newview/skins/default/xui/it/panel_edit_eyes.xml
diff --git a/indra/newview/skins/default/xui/it/panel_edit_gloves.xml b/indra/newview/skins/default/xui/it/panel_edit_gloves.xml
index 366a82f7aa..366a82f7aa 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_edit_gloves.xml
+++ b/indra/newview/skins/default/xui/it/panel_edit_gloves.xml
diff --git a/indra/newview/skins/default/xui/it/panel_edit_hair.xml b/indra/newview/skins/default/xui/it/panel_edit_hair.xml
index 50e2e7e4b3..50e2e7e4b3 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_edit_hair.xml
+++ b/indra/newview/skins/default/xui/it/panel_edit_hair.xml
diff --git a/indra/newview/skins/default/xui/it/panel_edit_jacket.xml b/indra/newview/skins/default/xui/it/panel_edit_jacket.xml
index 337720d068..337720d068 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_edit_jacket.xml
+++ b/indra/newview/skins/default/xui/it/panel_edit_jacket.xml
diff --git a/indra/newview/skins/default/xui/it/panel_edit_pants.xml b/indra/newview/skins/default/xui/it/panel_edit_pants.xml
index 21b5b7c026..21b5b7c026 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_edit_pants.xml
+++ b/indra/newview/skins/default/xui/it/panel_edit_pants.xml
diff --git a/indra/newview/skins/default/xui/it/panel_edit_physics.xml b/indra/newview/skins/default/xui/it/panel_edit_physics.xml
index 669a2c0eab..669a2c0eab 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_edit_physics.xml
+++ b/indra/newview/skins/default/xui/it/panel_edit_physics.xml
diff --git a/indra/newview/skins/default/xui/it/panel_edit_pick.xml b/indra/newview/skins/default/xui/it/panel_edit_pick.xml
index 145b8cf4e3..145b8cf4e3 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_edit_pick.xml
+++ b/indra/newview/skins/default/xui/it/panel_edit_pick.xml
diff --git a/indra/newview/skins/default/xui/it/panel_edit_profile.xml b/indra/newview/skins/default/xui/it/panel_edit_profile.xml
index 545e96a8f1..545e96a8f1 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_edit_profile.xml
+++ b/indra/newview/skins/default/xui/it/panel_edit_profile.xml
diff --git a/indra/newview/skins/default/xui/it/panel_edit_shape.xml b/indra/newview/skins/default/xui/it/panel_edit_shape.xml
index fd6a7af69c..fd6a7af69c 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_edit_shape.xml
+++ b/indra/newview/skins/default/xui/it/panel_edit_shape.xml
diff --git a/indra/newview/skins/default/xui/it/panel_edit_shirt.xml b/indra/newview/skins/default/xui/it/panel_edit_shirt.xml
index 1777c0147f..1777c0147f 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_edit_shirt.xml
+++ b/indra/newview/skins/default/xui/it/panel_edit_shirt.xml
diff --git a/indra/newview/skins/default/xui/it/panel_edit_shoes.xml b/indra/newview/skins/default/xui/it/panel_edit_shoes.xml
index c79408b94a..c79408b94a 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_edit_shoes.xml
+++ b/indra/newview/skins/default/xui/it/panel_edit_shoes.xml
diff --git a/indra/newview/skins/default/xui/it/panel_edit_skin.xml b/indra/newview/skins/default/xui/it/panel_edit_skin.xml
index 466eff2708..466eff2708 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_edit_skin.xml
+++ b/indra/newview/skins/default/xui/it/panel_edit_skin.xml
diff --git a/indra/newview/skins/default/xui/it/panel_edit_skirt.xml b/indra/newview/skins/default/xui/it/panel_edit_skirt.xml
index 87cdd16676..87cdd16676 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_edit_skirt.xml
+++ b/indra/newview/skins/default/xui/it/panel_edit_skirt.xml
diff --git a/indra/newview/skins/default/xui/it/panel_edit_socks.xml b/indra/newview/skins/default/xui/it/panel_edit_socks.xml
index f61a72ed76..f61a72ed76 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_edit_socks.xml
+++ b/indra/newview/skins/default/xui/it/panel_edit_socks.xml
diff --git a/indra/newview/skins/default/xui/it/panel_edit_tattoo.xml b/indra/newview/skins/default/xui/it/panel_edit_tattoo.xml
index d76fb62c53..d76fb62c53 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_edit_tattoo.xml
+++ b/indra/newview/skins/default/xui/it/panel_edit_tattoo.xml
diff --git a/indra/newview/skins/default/xui/it/panel_edit_underpants.xml b/indra/newview/skins/default/xui/it/panel_edit_underpants.xml
index 924344e3c0..924344e3c0 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_edit_underpants.xml
+++ b/indra/newview/skins/default/xui/it/panel_edit_underpants.xml
diff --git a/indra/newview/skins/default/xui/it/panel_edit_undershirt.xml b/indra/newview/skins/default/xui/it/panel_edit_undershirt.xml
index 2f22c03294..2f22c03294 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_edit_undershirt.xml
+++ b/indra/newview/skins/default/xui/it/panel_edit_undershirt.xml
diff --git a/indra/newview/skins/default/xui/it/panel_edit_wearable.xml b/indra/newview/skins/default/xui/it/panel_edit_wearable.xml
index e54dc26d05..e54dc26d05 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_edit_wearable.xml
+++ b/indra/newview/skins/default/xui/it/panel_edit_wearable.xml
diff --git a/indra/newview/skins/default/xui/it/panel_group_control_panel.xml b/indra/newview/skins/default/xui/it/panel_group_control_panel.xml
index 2d17e4a0cd..2d17e4a0cd 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_group_control_panel.xml
+++ b/indra/newview/skins/default/xui/it/panel_group_control_panel.xml
diff --git a/indra/newview/skins/default/xui/it/panel_group_general.xml b/indra/newview/skins/default/xui/it/panel_group_general.xml
index 49baa73811..49baa73811 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_group_general.xml
+++ b/indra/newview/skins/default/xui/it/panel_group_general.xml
diff --git a/indra/newview/skins/default/xui/it/panel_group_info_sidetray.xml b/indra/newview/skins/default/xui/it/panel_group_info_sidetray.xml
index 34ee3c2dca..34ee3c2dca 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_group_info_sidetray.xml
+++ b/indra/newview/skins/default/xui/it/panel_group_info_sidetray.xml
diff --git a/indra/newview/skins/default/xui/it/panel_group_invite.xml b/indra/newview/skins/default/xui/it/panel_group_invite.xml
index e3cb3c1092..1b57eba3f0 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_group_invite.xml
+++ b/indra/newview/skins/default/xui/it/panel_group_invite.xml
@@ -9,6 +9,9 @@
<panel.string name="already_in_group">
Alcuni dei residenti selezionati sono già nel gruppo, pertanto l&apos;invito non verrà loro spedito.
</panel.string>
+ <panel.string name="invite_selection_too_large">
+ Invito di gruppo non inviato: troppi residenti selezionati Gli inviti di gruppo possono essere inviati a un massimo di 100 persone per ciascuna richiesta.
+ </panel.string>
<text name="help_text">
Puoi selezionare più residenti da invitare nel tuo gruppo. Per iniziare, clicca su Apri il selettore di residenti.
</text>
diff --git a/indra/newview/skins/default/xui/it/panel_group_land_money.xml b/indra/newview/skins/default/xui/it/panel_group_land_money.xml
index 27675a18f5..27675a18f5 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_group_land_money.xml
+++ b/indra/newview/skins/default/xui/it/panel_group_land_money.xml
diff --git a/indra/newview/skins/default/xui/it/panel_group_list_item.xml b/indra/newview/skins/default/xui/it/panel_group_list_item.xml
index 7cdc4c7ff6..72e644008c 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_group_list_item.xml
+++ b/indra/newview/skins/default/xui/it/panel_group_list_item.xml
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel name="group_list_item">
<text name="group_name" value="Sconosciuto"/>
+ <button name="info_btn" tool_tip="Maggiori informazioni"/>
<button name="profile_btn" tool_tip="Vedi profilo"/>
</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_group_notices.xml b/indra/newview/skins/default/xui/it/panel_group_notices.xml
index 524f7d2822..524f7d2822 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_group_notices.xml
+++ b/indra/newview/skins/default/xui/it/panel_group_notices.xml
diff --git a/indra/newview/skins/default/xui/it/panel_group_notify.xml b/indra/newview/skins/default/xui/it/panel_group_notify.xml
index 91a41353a5..91a41353a5 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_group_notify.xml
+++ b/indra/newview/skins/default/xui/it/panel_group_notify.xml
diff --git a/indra/newview/skins/default/xui/it/panel_group_roles.xml b/indra/newview/skins/default/xui/it/panel_group_roles.xml
index 478b35e628..478b35e628 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_group_roles.xml
+++ b/indra/newview/skins/default/xui/it/panel_group_roles.xml
diff --git a/indra/newview/skins/default/xui/it/panel_im_control_panel.xml b/indra/newview/skins/default/xui/it/panel_im_control_panel.xml
index 76b28eab24..76b28eab24 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_im_control_panel.xml
+++ b/indra/newview/skins/default/xui/it/panel_im_control_panel.xml
diff --git a/indra/newview/skins/default/xui/it/panel_inventory_item.xml b/indra/newview/skins/default/xui/it/panel_inventory_item.xml
index d18047fbcf..d18047fbcf 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_inventory_item.xml
+++ b/indra/newview/skins/default/xui/it/panel_inventory_item.xml
diff --git a/indra/newview/skins/default/xui/it/panel_landmark_info.xml b/indra/newview/skins/default/xui/it/panel_landmark_info.xml
index b4c5ab01bc..b4c5ab01bc 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_landmark_info.xml
+++ b/indra/newview/skins/default/xui/it/panel_landmark_info.xml
diff --git a/indra/newview/skins/default/xui/it/panel_landmarks.xml b/indra/newview/skins/default/xui/it/panel_landmarks.xml
index 5617105c31..5617105c31 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_landmarks.xml
+++ b/indra/newview/skins/default/xui/it/panel_landmarks.xml
diff --git a/indra/newview/skins/default/xui/it/panel_login.xml b/indra/newview/skins/default/xui/it/panel_login.xml
index f88230ed11..2afde40940 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_login.xml
+++ b/indra/newview/skins/default/xui/it/panel_login.xml
@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel name="panel_login">
- <panel.string name="create_account_url">
- http://join.secondlife.com/
- </panel.string>
<panel.string name="forgot_password_url">
http://secondlife.com/account/request.php?lang=it
</panel.string>
<layout_stack name="login_widgets">
<layout_panel name="login">
+ <text name="log_in_text">
+ ACCEDI
+ </text>
<text name="username_text">
Nome utente:
</text>
@@ -15,15 +15,8 @@
<text name="password_text">
Password:
</text>
- <check_box label="Ricorda password" name="remember_check"/>
- <button label="Accedi" name="connect_btn"/>
- <text name="mode_selection_text">
- Modalità:
- </text>
- <combo_box name="mode_combo" tool_tip="Seleziona la modalità. Seleziona Di base per esplorare facilmente e rapidamente e per la chat. Seleziona Avanzata per accedere ad altre funzionalità.">
- <combo_box.item label="Di base" name="Basic"/>
- <combo_box.item label="Avanzate" name="Advanced"/>
- </combo_box>
+ </layout_panel>
+ <layout_panel name="start_location_panel">
<text name="start_location_text">
Inizia da:
</text>
@@ -33,16 +26,21 @@
<combo_box.item label="&lt;Scrivi nome regione&gt;" name="Typeregionname"/>
</combo_box>
</layout_panel>
- <layout_panel name="links">
- <text name="create_new_account_text">
- Iscriviti
+ <layout_panel name="links_login_panel">
+ <text name="login_help">
+ Ti serve aiuto con la fase di accesso?
</text>
<text name="forgot_password_text">
Hai dimenticato il nome utente o la password?
</text>
- <text name="login_help">
- Ti serve aiuto con la fase di accesso?
+ <button label="Accedi" name="connect_btn"/>
+ <check_box label="Ricorda password" name="remember_check"/>
+ </layout_panel>
+ <layout_panel name="links">
+ <text name="create_account_text">
+ CREA IL TUO ACCOUNT
</text>
+ <button label="Inizia adesso" name="create_new_account_btn"/>
</layout_panel>
</layout_stack>
</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_main_inventory.xml b/indra/newview/skins/default/xui/it/panel_main_inventory.xml
index 446b51ffa3..446b51ffa3 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_main_inventory.xml
+++ b/indra/newview/skins/default/xui/it/panel_main_inventory.xml
diff --git a/indra/newview/skins/default/xui/it/panel_me.xml b/indra/newview/skins/default/xui/it/panel_me.xml
index a134f6f1de..a134f6f1de 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_me.xml
+++ b/indra/newview/skins/default/xui/it/panel_me.xml
diff --git a/indra/newview/skins/default/xui/it/panel_media_settings_general.xml b/indra/newview/skins/default/xui/it/panel_media_settings_general.xml
index f11b2415ee..f11b2415ee 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_media_settings_general.xml
+++ b/indra/newview/skins/default/xui/it/panel_media_settings_general.xml
diff --git a/indra/newview/skins/default/xui/it/panel_media_settings_permissions.xml b/indra/newview/skins/default/xui/it/panel_media_settings_permissions.xml
index 0f0f1c9fe4..0f0f1c9fe4 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_media_settings_permissions.xml
+++ b/indra/newview/skins/default/xui/it/panel_media_settings_permissions.xml
diff --git a/indra/newview/skins/default/xui/it/panel_media_settings_security.xml b/indra/newview/skins/default/xui/it/panel_media_settings_security.xml
index 785cd048a1..785cd048a1 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_media_settings_security.xml
+++ b/indra/newview/skins/default/xui/it/panel_media_settings_security.xml
diff --git a/indra/newview/skins/default/xui/it/panel_navigation_bar.xml b/indra/newview/skins/default/xui/it/panel_navigation_bar.xml
index 0299e2a532..0299e2a532 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_navigation_bar.xml
+++ b/indra/newview/skins/default/xui/it/panel_navigation_bar.xml
diff --git a/indra/newview/skins/default/xui/it/panel_nearby_chat.xml b/indra/newview/skins/default/xui/it/panel_nearby_chat.xml
index d46a15c735..d46a15c735 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_nearby_chat.xml
+++ b/indra/newview/skins/default/xui/it/panel_nearby_chat.xml
diff --git a/indra/newview/skins/default/xui/it/panel_nearby_chat_bar.xml b/indra/newview/skins/default/xui/it/panel_nearby_chat_bar.xml
index 6317d3192e..1fef88870a 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_nearby_chat_bar.xml
+++ b/indra/newview/skins/default/xui/it/panel_nearby_chat_bar.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel name="chat_bar">
+<panel name="nearby_chat">
<string name="min_width">
192
</string>
diff --git a/indra/newview/skins/default/xui/it/panel_nearby_media.xml b/indra/newview/skins/default/xui/it/panel_nearby_media.xml
index 03421456f9..03421456f9 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_nearby_media.xml
+++ b/indra/newview/skins/default/xui/it/panel_nearby_media.xml
diff --git a/indra/newview/skins/default/xui/it/panel_notify_textbox.xml b/indra/newview/skins/default/xui/it/panel_notify_textbox.xml
index ef27262010..ef27262010 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_notify_textbox.xml
+++ b/indra/newview/skins/default/xui/it/panel_notify_textbox.xml
diff --git a/indra/newview/skins/default/xui/it/panel_online_status_toast.xml b/indra/newview/skins/default/xui/it/panel_online_status_toast.xml
index fdc489f375..fdc489f375 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_online_status_toast.xml
+++ b/indra/newview/skins/default/xui/it/panel_online_status_toast.xml
diff --git a/indra/newview/skins/default/xui/it/panel_outbox_inventory.xml b/indra/newview/skins/default/xui/it/panel_outbox_inventory.xml
index af5e05336e..af5e05336e 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_outbox_inventory.xml
+++ b/indra/newview/skins/default/xui/it/panel_outbox_inventory.xml
diff --git a/indra/newview/skins/default/xui/it/panel_outfit_edit.xml b/indra/newview/skins/default/xui/it/panel_outfit_edit.xml
index 446c211b1c..446c211b1c 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_outfit_edit.xml
+++ b/indra/newview/skins/default/xui/it/panel_outfit_edit.xml
diff --git a/indra/newview/skins/default/xui/it/panel_outfits_inventory.xml b/indra/newview/skins/default/xui/it/panel_outfits_inventory.xml
index c7821bc363..c7821bc363 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_outfits_inventory.xml
+++ b/indra/newview/skins/default/xui/it/panel_outfits_inventory.xml
diff --git a/indra/newview/skins/default/xui/it/panel_outfits_inventory_gear_default.xml b/indra/newview/skins/default/xui/it/panel_outfits_inventory_gear_default.xml
index 9e1a45b129..9e1a45b129 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_outfits_inventory_gear_default.xml
+++ b/indra/newview/skins/default/xui/it/panel_outfits_inventory_gear_default.xml
diff --git a/indra/newview/skins/default/xui/it/panel_outfits_list.xml b/indra/newview/skins/default/xui/it/panel_outfits_list.xml
index d0c275e29f..d0c275e29f 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_outfits_list.xml
+++ b/indra/newview/skins/default/xui/it/panel_outfits_list.xml
diff --git a/indra/newview/skins/default/xui/it/panel_outfits_wearing.xml b/indra/newview/skins/default/xui/it/panel_outfits_wearing.xml
index 3bbf2446f5..3bbf2446f5 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_outfits_wearing.xml
+++ b/indra/newview/skins/default/xui/it/panel_outfits_wearing.xml
diff --git a/indra/newview/skins/default/xui/it/panel_people.xml b/indra/newview/skins/default/xui/it/panel_people.xml
index f903ae6e2c..2f40d4bdc4 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_people.xml
+++ b/indra/newview/skins/default/xui/it/panel_people.xml
@@ -14,81 +14,56 @@ Stai cercando persone da frequentare? Prova la [secondlife:///app/worldmap Mappa
<string name="no_filtered_friends_msg">
Non riesci a trovare quello che cerchi? Prova [secondlife:///app/search/people/[SEARCH_TERM] Cerca].
</string>
- <string name="people_filter_label" value="Filtro persone"/>
- <string name="groups_filter_label" value="Filtro gruppi"/>
<string name="no_filtered_groups_msg" value="Non riesci a trovare quello che cerchi? Prova [secondlife:///app/search/groups/[SEARCH_TERM] Cerca]."/>
<string name="no_groups_msg" value="Stai cercando gruppi di cui far parte? Prova [secondlife:///app/search/groups Cerca]."/>
<string name="MiniMapToolTipMsg" value="[REGION](Fai doppio clic per aprire la Mappa, premi il tasto Maiusc e trascina per la panoramica)"/>
<string name="AltMiniMapToolTipMsg" value="[REGION](Fai doppio clic per teleportarti, premi il tasto Maiusc e trascina per la panoramica)"/>
- <filter_editor label="Filtro" name="filter_input"/>
<tab_container name="tabs">
<panel label="NELLE VICINANZE" name="nearby_panel">
- <panel label="bottom_panel" name="bottom_panel">
- <menu_button name="nearby_view_sort_btn" tool_tip="Opzioni"/>
- <button name="add_friend_btn" tool_tip="Aggiungi il residente selezionato alla tua lista degli amici"/>
+ <panel label="bottom_panel" name="nearby_buttons_panel">
+ <filter_editor label="Filtro persone" name="nearby_filter_input"/>
+ <button name="gear_btn" tool_tip="Azioni per la persona selezionata:"/>
+ <menu_button name="nearby_view_btn" tool_tip="Opzioni Mostra/Ordina"/>
+ <button name="add_friend_btn" tool_tip="Offri amicizia a un residente"/>
+ <dnd_button name="nearby_del_btn" tool_tip="Rimuovi la persona selezionata dagli amici"/>
</panel>
</panel>
- <panel label="I MIEI AMICI" name="friends_panel">
+ <panel label="AMICI" name="friends_panel">
+ <panel label="bottom_panel" name="friends_buttons_panel">
+ <filter_editor label="Filtro persone" name="friends_filter_input"/>
+ <button name="gear_btn" tool_tip="Azioni per la persona selezionata:"/>
+ <menu_button name="friends_view_btn" tool_tip="Opzioni Mostra/Ordina"/>
+ <button name="friends_add_btn" tool_tip="Offri amicizia a un residente"/>
+ <dnd_button name="friends_del_btn" tool_tip="Rimuovi la persona selezionata dagli amici"/>
+ </panel>
<accordion name="friends_accordion">
<accordion_tab name="tab_online" title="Online"/>
<accordion_tab name="tab_all" title="Tutto"/>
</accordion>
- <panel label="bottom_panel" name="bottom_panel">
- <layout_stack name="bottom_panel">
- <layout_panel name="options_gear_btn_panel">
- <menu_button name="friends_viewsort_btn" tool_tip="Mostra ulteriori opzioni"/>
- </layout_panel>
- <layout_panel name="add_btn_panel">
- <button name="add_btn" tool_tip="Offri amicizia a un residente"/>
- </layout_panel>
- <layout_panel name="trash_btn_panel">
- <dnd_button name="del_btn" tool_tip="Rimuovi la persona selezionata dalla lista degli amici"/>
- </layout_panel>
- </layout_stack>
- </panel>
</panel>
- <panel label="I MIEI GRUPPI" name="groups_panel">
- <panel label="bottom_panel" name="bottom_panel">
- <menu_button name="groups_viewsort_btn" tool_tip="Opzioni"/>
- <button name="plus_btn" tool_tip="Aderisci al gruppo/Crea nuovo gruppo"/>
- <button name="activate_btn" tool_tip="Attiva il gruppo selezionato"/>
+ <panel label="GRUPPI" name="groups_panel">
+ <panel label="bottom_panel" name="groups_buttons_panel">
+ <filter_editor label="Filtro gruppi" name="groups_filter_input"/>
+ <menu_button name="groups_gear_btn" tool_tip="Azioni per il gruppo selezionato:"/>
+ <menu_button name="groups_view_btn" tool_tip="Opzioni Mostra/Ordina"/>
+ <menu_button name="plus_btn" tool_tip="Aderisci al gruppo/Crea nuovo gruppo"/>
+ <dnd_button name="minus_btn" tool_tip="Lascia il gruppo selezionato"/>
</panel>
+ <text name="groupcount">
+ Fai parte di [COUNT] gruppi e puoi iscriverti a [REMAINING] altri.
+ </text>
</panel>
<panel label="RECENTE" name="recent_panel">
- <panel label="bottom_panel" name="bottom_panel">
- <menu_button name="recent_viewsort_btn" tool_tip="Opzioni"/>
- <button name="add_friend_btn" tool_tip="Aggiungi il residente selezionato alla tua lista degli amici"/>
+ <panel label="bottom_panel" name="recent_buttons_panel">
+ <filter_editor label="Filtro persone" name="recent_filter_input"/>
+ <button name="gear_btn" tool_tip="Azioni per la persona selezionata:"/>
+ <menu_button name="recent_view_btn" tool_tip="Opzioni Mostra/Ordina"/>
+ <button name="add_friend_btn" tool_tip="Offri amicizia a un residente"/>
+ <dnd_button name="recent_del_btn" tool_tip="Rimuovi la persona selezionata dagli amici"/>
</panel>
</panel>
+ <panel label="BLOCCATO" name="blocked_panel">
+ <panel label="Residenti e oggetti bloccati" name="panel_block_list_sidetray"/>
+ </panel>
</tab_container>
- <panel name="button_bar">
- <layout_stack name="bottom_bar_ls">
- <layout_panel name="view_profile_btn_lp">
- <button label="Profilo" name="view_profile_btn" tool_tip="Mostra immagine, gruppi e altre informazioni del residente"/>
- </layout_panel>
- <layout_panel name="im_btn_lp">
- <button label="IM" name="im_btn" tool_tip="Apri una sessione messaggio istantaneo"/>
- </layout_panel>
- <layout_panel name="call_btn_lp">
- <button label="Chiama" name="call_btn" tool_tip="Chiama questo residente"/>
- </layout_panel>
- <layout_panel name="share_btn_lp">
- <button label="Condividi" name="share_btn" tool_tip="Condividi un oggetto dell&apos;inventario"/>
- </layout_panel>
- <layout_panel name="teleport_btn_lp">
- <button label="Teleport" name="teleport_btn" tool_tip="Offri teleport"/>
- </layout_panel>
- </layout_stack>
- <layout_stack name="bottom_bar_ls1">
- <layout_panel name="group_info_btn_lp">
- <button label="Profilo del gruppo" name="group_info_btn" tool_tip="Mostra informazioni gruppo"/>
- </layout_panel>
- <layout_panel name="chat_btn_lp">
- <button label="Chat di gruppo" name="chat_btn" tool_tip="Apri sessione chat"/>
- </layout_panel>
- <layout_panel name="group_call_btn_lp">
- <button label="Chiamata al gruppo" name="group_call_btn" tool_tip="Chiama questo gruppo"/>
- </layout_panel>
- </layout_stack>
- </panel>
</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_pick_info.xml b/indra/newview/skins/default/xui/it/panel_pick_info.xml
index ca9959a581..ca9959a581 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_pick_info.xml
+++ b/indra/newview/skins/default/xui/it/panel_pick_info.xml
diff --git a/indra/newview/skins/default/xui/it/panel_picks.xml b/indra/newview/skins/default/xui/it/panel_picks.xml
index 3faf28a948..3faf28a948 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_picks.xml
+++ b/indra/newview/skins/default/xui/it/panel_picks.xml
diff --git a/indra/newview/skins/default/xui/it/panel_place_profile.xml b/indra/newview/skins/default/xui/it/panel_place_profile.xml
index 890dfc2458..890dfc2458 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_place_profile.xml
+++ b/indra/newview/skins/default/xui/it/panel_place_profile.xml
diff --git a/indra/newview/skins/default/xui/it/panel_places.xml b/indra/newview/skins/default/xui/it/panel_places.xml
index 69995fb5de..69995fb5de 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_places.xml
+++ b/indra/newview/skins/default/xui/it/panel_places.xml
diff --git a/indra/newview/skins/default/xui/it/panel_postcard_message.xml b/indra/newview/skins/default/xui/it/panel_postcard_message.xml
index c720f4822d..c720f4822d 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_postcard_message.xml
+++ b/indra/newview/skins/default/xui/it/panel_postcard_message.xml
diff --git a/indra/newview/skins/default/xui/it/panel_postcard_settings.xml b/indra/newview/skins/default/xui/it/panel_postcard_settings.xml
index 6a586c4415..6a586c4415 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_postcard_settings.xml
+++ b/indra/newview/skins/default/xui/it/panel_postcard_settings.xml
diff --git a/indra/newview/skins/default/xui/it/panel_preferences_advanced.xml b/indra/newview/skins/default/xui/it/panel_preferences_advanced.xml
index 224780f234..224780f234 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_preferences_advanced.xml
+++ b/indra/newview/skins/default/xui/it/panel_preferences_advanced.xml
diff --git a/indra/newview/skins/default/xui/it/panel_preferences_alerts.xml b/indra/newview/skins/default/xui/it/panel_preferences_alerts.xml
index fd1fd57761..fd1fd57761 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_preferences_alerts.xml
+++ b/indra/newview/skins/default/xui/it/panel_preferences_alerts.xml
diff --git a/indra/newview/skins/default/xui/it/panel_preferences_chat.xml b/indra/newview/skins/default/xui/it/panel_preferences_chat.xml
index 7f5992b584..09d7c96370 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/it/panel_preferences_chat.xml
@@ -1,33 +1,99 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel label="Text Chat" name="chat">
- <text name="font_size">
- Dimensioni caratteri:
- </text>
- <radio_group name="chat_font_size">
- <radio_item label="Piccola" name="radio" value="0"/>
- <radio_item label="Media" name="radio2" value="1"/>
- <radio_item label="Grande" name="radio3" value="2"/>
- </radio_group>
- <check_box initial_value="true" label="Simula la battitura tasti quando scrivi" name="play_typing_animation"/>
- <check_box label="Quando sono OFF-LINE, spediscimi gli IM in una e-mail" name="send_im_to_email"/>
- <check_box label="Attiva IM in testo semplice e cronologia chat" name="plain_text_chat_history"/>
- <check_box label="Chat a vignetta" name="bubble_text_chat"/>
- <text name="show_ims_in_label">
- Mostra gli IM in:
- </text>
- <text name="requires_restart_label">
- (richiede il riavvio)
- </text>
- <radio_group name="chat_window" tool_tip="Mostra i tuoi messaggi istantanei in diverse finestre, o in una finestra con più schede (richiede il riavvio)">
- <radio_item label="Finestre separate" name="radio" value="0"/>
- <radio_item label="Schede" name="radio2" value="1"/>
- </radio_group>
- <text name="disable_toast_label">
- Attiva popup per chat in arrivo:
- </text>
- <check_box label="Chat di gruppo" name="EnableGroupChatPopups" tool_tip="Seleziona per vedere una finestra popup quando arriva una chat di gruppo"/>
- <check_box label="Chat IM" name="EnableIMChatPopups" tool_tip="Seleziona per vedere una finestra popup quando arriva un messaggio IM"/>
- <spinner label="Durata chat vicine:" name="nearby_toasts_lifetime"/>
- <spinner label="Durata dissolvenza chat vicine:" name="nearby_toasts_fadingtime"/>
- <button label="Impostazioni traduzione chat" name="ok_btn"/>
+ <panel name="general_chat_settings">
+ <check_box initial_value="true" label="Simula la battitura tasti quando sei in chat" name="play_typing_animation"/>
+ <check_box label="Quando sono OFF-LINE, spediscimi gli IM in una e-mail" name="send_im_to_email"/>
+ <check_box label="Solo amici e gruppi possono chiamarmi o mandarmi IM" name="voice_call_friends_only_check"/>
+ <text name="font_size">
+ Dimensioni carattere:
+ </text>
+ <combo_box name="chat_font_size">
+ <item label="Piccolo" name="Small" value="0"/>
+ <item label="Medio" name="Medium" value="1"/>
+ <item label="Grande" name="Large" value="2"/>
+ </combo_box>
+ <check_box label="Chat a vignetta" name="bubble_text_chat"/>
+ </panel>
+ <panel name="im_notification_settings">
+ <text name="friend_ims">
+ IM degli amici:
+ </text>
+ <combo_box name="FriendIMOptions">
+ <item label="Apri finestra Conversazioni" name="OpenConversationsWindow" value="openconversations"/>
+ <item label="Mostra il messaggio in una finestra pop-up" name="PopUpMessage" value="toast"/>
+ <item label="Pulsante barra strumenti Flash" name="FlashToolbarButton" value="flash"/>
+ <item label="Nessuna azione" name="NoAction" value="noaction"/>
+ </combo_box>
+ <check_box label="Riproduci suono" name="play_sound_friend_im"/>
+ <text name="non_friend_ims">
+ IM non di amici:
+ </text>
+ <combo_box name="NonFriendIMOptions">
+ <item label="Apri finestra Conversazioni" name="OpenConversationsWindow" value="openconversations"/>
+ <item label="Mostra il messaggio in una finestra pop-up" name="PopUpMessage" value="toast"/>
+ <item label="Pulsante barra strumenti Flash" name="FlashToolbarButton" value="flash"/>
+ <item label="Nessuna azione" name="NoAction" value="noaction"/>
+ </combo_box>
+ <check_box label="Riproduci suono" name="play_sound_non_friend_im"/>
+ <text name="conference_ims">
+ IM conferenza:
+ </text>
+ <combo_box name="ConferenceIMOptions">
+ <item label="Apri finestra Conversazioni" name="OpenConversationsWindow" value="openconversations"/>
+ <item label="Mostra il messaggio in una finestra pop-up" name="PopUpMessage" value="toast"/>
+ <item label="Pulsante barra strumenti Flash" name="FlashToolbarButton" value="flash"/>
+ <item label="Nessuna azione" name="NoAction" value="noaction"/>
+ </combo_box>
+ <check_box label="Riproduci suono" name="play_sound_conference_im"/>
+ <text name="group_chat">
+ Chat di gruppo:
+ </text>
+ <combo_box name="GroupChatOptions">
+ <item label="Apri finestra Conversazioni" name="OpenConversationsWindow" value="openconversations"/>
+ <item label="Mostra il messaggio in una finestra pop-up" name="PopUpMessage" value="toast"/>
+ <item label="Pulsante barra strumenti Flash" name="FlashToolbarButton" value="flash"/>
+ <item label="Nessuna azione" name="NoAction" value="noaction"/>
+ </combo_box>
+ <check_box label="Riproduci suono" name="play_sound_group_chat_im"/>
+ <text name="nearby_chat">
+ Chat nei dintorni:
+ </text>
+ <combo_box name="NearbyChatOptions">
+ <item label="Apri finestra Conversazioni" name="OpenConversationsWindow" value="openconversations"/>
+ <item label="Mostra il messaggio in una finestra pop-up" name="PopUpMessage" value="toast"/>
+ <item label="Pulsante barra strumenti Flash" name="FlashToolBarButton" value="flash"/>
+ <item label="Nessuna azione" name="NoAction" value="noaction"/>
+ </combo_box>
+ <check_box label="Riproduci suono" name="play_sound_nearby_chat_im"/>
+ <text name="object_ims">
+ IM di oggetti:
+ </text>
+ <combo_box name="ObjectIMOptions">
+ <item label="Apri finestra Conversazioni" name="OpenConversationsWindow" value="openconversations"/>
+ <item label="Mostra il messaggio in una finestra pop-up" name="PopUpMessage" value="toast"/>
+ <item label="Pulsante barra strumenti Flash" name="FlashToolBarButton" value="flash"/>
+ <item label="Nessuna azione" name="NoAction" value="noaction"/>
+ </combo_box>
+ <check_box label="Riproduci suono" name="play_sound_object_im"/>
+ <text name="notifications_alert">
+ Per interrompere temporaneamente le notifiche, usa Comunica &gt; Non disturbare.
+ </text>
+ </panel>
+ <panel name="play_sound_settings">
+ <text name="play_sound">
+ Riproduci suono:
+ </text>
+ <check_box label="Nuova conversazione" name="new_conversation"/>
+ <check_box label="Chiamata voce in arrivo" name="incoming_voice_call"/>
+ <check_box label="Offerta di Teleport" name="teleport_offer"/>
+ <check_box label="Offerta inventario" name="inventory_offer"/>
+ </panel>
+ <panel name="log_settings">
+ <button label="Cancella registro..." name="clear_log"/>
+ <button label="Cancella trascrizioni..." name="delete_transcripts"/>
+ <button label="Sfoglia..." label_selected="Sfoglia" name="log_path_button"/>
+ </panel>
+ <button label="Traduzione..." name="ok_btn"/>
+ <button label="Sostituzione automatica..." name="autoreplace_showgui"/>
+ <button label="Correzione ortografica..." name="spellcheck_showgui"/>
</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_preferences_colors.xml b/indra/newview/skins/default/xui/it/panel_preferences_colors.xml
index 016970d9a3..016970d9a3 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_preferences_colors.xml
+++ b/indra/newview/skins/default/xui/it/panel_preferences_colors.xml
diff --git a/indra/newview/skins/default/xui/it/panel_preferences_general.xml b/indra/newview/skins/default/xui/it/panel_preferences_general.xml
index 90a833471c..45cc06c2ea 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_preferences_general.xml
+++ b/indra/newview/skins/default/xui/it/panel_preferences_general.xml
@@ -69,6 +69,9 @@
<combo_box.item label="mai" name="item4"/>
</combo_box>
<text name="text_box3">
- Risposta in modalità occupato:
+ Risposta Non disturbare:
</text>
+ <text_editor name="do_not_disturb_response">
+ log_in_to_change
+ </text_editor>
</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/it/panel_preferences_graphics1.xml
index 1f2b97af45..2978c48db6 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_preferences_graphics1.xml
+++ b/indra/newview/skins/default/xui/it/panel_preferences_graphics1.xml
@@ -25,12 +25,12 @@
<text name="ShadersText">
Effetti grafici:
</text>
- <check_box initial_value="vero" label="Acqua trasparente" name="TransparentWater"/>
+ <check_box initial_value="true" label="Acqua trasparente" name="TransparentWater"/>
<check_box initial_value="true" label="Piccoli rilievi e scintillii" name="BumpShiny"/>
<check_box initial_value="true" label="Luci locali" name="LocalLights"/>
<check_box initial_value="true" label="Effetti grafici base" name="BasicShaders" tool_tip="Disabilitare questa opzione può evitare che qualche scheda grafica vada in crash."/>
<check_box initial_value="true" label="Effetti grafici atmosferici" name="WindLightUseAtmosShaders"/>
- <check_box initial_value="true" label="Luci e ombre" name="UseLightShaders"/>
+ <check_box initial_value="true" label="Modello illuminazione avanzato" name="UseLightShaders"/>
<check_box initial_value="true" label="Occlusione ambientale" name="UseSSAO"/>
<check_box initial_value="true" label="Profondità di campo" name="UseDoF"/>
<text name="shadows_label">
diff --git a/indra/newview/skins/default/xui/it/panel_preferences_move.xml b/indra/newview/skins/default/xui/it/panel_preferences_move.xml
index 8d172bb8bb..8d172bb8bb 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_preferences_move.xml
+++ b/indra/newview/skins/default/xui/it/panel_preferences_move.xml
diff --git a/indra/newview/skins/default/xui/it/panel_preferences_privacy.xml b/indra/newview/skins/default/xui/it/panel_preferences_privacy.xml
index 41e7a59139..41e7a59139 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_preferences_privacy.xml
+++ b/indra/newview/skins/default/xui/it/panel_preferences_privacy.xml
diff --git a/indra/newview/skins/default/xui/it/panel_preferences_setup.xml b/indra/newview/skins/default/xui/it/panel_preferences_setup.xml
index 0189d47f45..fcc9661d03 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_preferences_setup.xml
+++ b/indra/newview/skins/default/xui/it/panel_preferences_setup.xml
@@ -21,7 +21,7 @@
<check_box initial_value="true" label="Abilita plugin" name="browser_plugins_enabled"/>
<check_box initial_value="true" label="Accetta cookie" name="cookies_enabled"/>
<check_box initial_value="true" label="Abilita Javascript" name="browser_javascript_enabled"/>
- <check_box initial_value="falso" label="Consenti pop-up nel browser media" name="media_popup_enabled"/>
+ <check_box initial_value="false" label="Consenti pop-up nel browser media" name="media_popup_enabled"/>
<text name="Software updates:">
Aggiornamenti software:
</text>
@@ -29,6 +29,7 @@
<combo_box.item label="Installa automaticamente" name="Install_automatically"/>
<combo_box.item label="Scarica e installa manualmente gli aggiornamenti" name="Install_manual"/>
</combo_box>
+ <check_box label="Disponibile agli aggiornamenti con versioni non rilasciate" name="update_willing_to_test"/>
<text name="Proxy Settings:">
Impostazioni proxy:
</text>
diff --git a/indra/newview/skins/default/xui/it/panel_preferences_sound.xml b/indra/newview/skins/default/xui/it/panel_preferences_sound.xml
index d00512aaf7..d00512aaf7 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_preferences_sound.xml
+++ b/indra/newview/skins/default/xui/it/panel_preferences_sound.xml
diff --git a/indra/newview/skins/default/xui/it/panel_prim_media_controls.xml b/indra/newview/skins/default/xui/it/panel_prim_media_controls.xml
index 4620d72977..4620d72977 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_prim_media_controls.xml
+++ b/indra/newview/skins/default/xui/it/panel_prim_media_controls.xml
diff --git a/indra/newview/skins/default/xui/it/panel_region_covenant.xml b/indra/newview/skins/default/xui/it/panel_region_covenant.xml
index 0d3117ca7a..0d3117ca7a 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_region_covenant.xml
+++ b/indra/newview/skins/default/xui/it/panel_region_covenant.xml
diff --git a/indra/newview/skins/default/xui/it/panel_region_debug.xml b/indra/newview/skins/default/xui/it/panel_region_debug.xml
index 45b3a016f4..aba60d03aa 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_region_debug.xml
+++ b/indra/newview/skins/default/xui/it/panel_region_debug.xml
@@ -36,5 +36,5 @@
<button label="?" left="297" name="top_scripts_help"/>
<button label="Riavvia la regione" name="restart_btn" tool_tip="Dai 2 minuti di tempo massimo e fai riavviare la regione"/>
<button label="?" name="restart_help"/>
- <button label="Ritarda il riavvio" name="cancel_restart_btn" tool_tip="Ritarda il riavvio della regione di un&apos;ora"/>
+ <button label="Annulla riavvio" name="cancel_restart_btn" tool_tip="Annulla riavvio regione"/>
</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_region_environment.xml b/indra/newview/skins/default/xui/it/panel_region_environment.xml
index 81bc8253f4..81bc8253f4 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_region_environment.xml
+++ b/indra/newview/skins/default/xui/it/panel_region_environment.xml
diff --git a/indra/newview/skins/default/xui/it/panel_region_estate.xml b/indra/newview/skins/default/xui/it/panel_region_estate.xml
index da6b6b277f..98d9b86cfc 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_region_estate.xml
+++ b/indra/newview/skins/default/xui/it/panel_region_estate.xml
@@ -26,7 +26,7 @@
Consenti l&apos;accesso solo ai Residenti che:
</text>
<check_box label="Hanno memorizzato le informazioni per l&apos;addebito" name="limit_payment" tool_tip="Per poter visitare questa proprietà immobiliare i Residenti devono aver fornito informazioni di pagamento a Linden Lab. Vedi [SUPPORT_SITE] per maggiori informazioni."/>
- <check_box label="Hanno verificato l&apos;età" name="limit_age_verified" tool_tip="Per poter visitare questa proprietà immobiliare i Residenti devono aver verificato la propria età. Vedi [SUPPORT_SITE] per maggiori informazioni."/>
+ <check_box label="Hanno almeno 18 anni" name="limit_age_verified" tool_tip="Per poter visitare questa proprietà immobiliare i Residenti devono avere almeno 18 anni. Vedi [SUPPORT_SITE] per maggiori informazioni."/>
<check_box label="Permetti la chat voice" name="voice_chat_check"/>
<button label="?" name="voice_chat_help"/>
<check_box label="Permetti teleport diretto" name="allow_direct_teleport"/>
diff --git a/indra/newview/skins/default/xui/it/panel_region_general.xml b/indra/newview/skins/default/xui/it/panel_region_general.xml
index c550e005ae..c550e005ae 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_region_general.xml
+++ b/indra/newview/skins/default/xui/it/panel_region_general.xml
diff --git a/indra/newview/skins/default/xui/it/panel_region_terrain.xml b/indra/newview/skins/default/xui/it/panel_region_terrain.xml
index c61ac3ecce..c61ac3ecce 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_region_terrain.xml
+++ b/indra/newview/skins/default/xui/it/panel_region_terrain.xml
diff --git a/indra/newview/skins/default/xui/it/panel_region_texture.xml b/indra/newview/skins/default/xui/it/panel_region_texture.xml
deleted file mode 100644
index 1337ed18ca..0000000000
--- a/indra/newview/skins/default/xui/it/panel_region_texture.xml
+++ /dev/null
@@ -1,57 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel label="Texture del terreno" name="Textures">
- <text name="region_text_lbl">
- Regione:
- </text>
- <text name="region_text">
- sconosciuto
- </text>
- <text name="detail_texture_text" width="380">
- Texture del terreno (è necessario siano 512x512, 24 bit .tga files)
- </text>
- <text name="height_text_lbl">
- 1 (Bassa)
- </text>
- <text name="height_text_lbl2">
- 2
- </text>
- <text name="height_text_lbl3">
- 3
- </text>
- <text name="height_text_lbl4">
- 4 (Alta)
- </text>
- <text name="height_text_lbl5">
- Range di elevazione della texture
- </text>
- <text name="height_text_lbl6">
- Nordovest
- </text>
- <text name="height_text_lbl7">
- Nordest
- </text>
- <text name="height_text_lbl8">
- Sudovest
- </text>
- <text name="height_text_lbl9">
- Sudest
- </text>
- <spinner label="Bassa" name="height_start_spin_0"/>
- <spinner label="Bassa" name="height_start_spin_1"/>
- <spinner label="Bassa" name="height_start_spin_2"/>
- <spinner label="Bassa" name="height_start_spin_3"/>
- <spinner label="Alta" name="height_range_spin_0"/>
- <spinner label="Alta" name="height_range_spin_1"/>
- <spinner label="Alta" name="height_range_spin_2"/>
- <spinner label="Alta" name="height_range_spin_3"/>
- <text name="height_text_lbl10">
- Questi valori indicano la gamma di miscele per le texture di cui sopra.
- </text>
- <text name="height_text_lbl11">
- Misurato in metri, il valore BASSO è la MASSIMA altezza della texture n. 1, e il valore ALTO è l&apos;altezza MINIMA della texture n. 4.
- </text>
- <text name="height_text_lbl12">
- Texture #1, e il valore più ALTO all&apos;altezza MINIMA della Texture #4.
- </text>
- <button label="Applica" name="apply_btn"/>
-</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_script_ed.xml b/indra/newview/skins/default/xui/it/panel_script_ed.xml
index d7ee8230b3..feee8b1927 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_script_ed.xml
+++ b/indra/newview/skins/default/xui/it/panel_script_ed.xml
@@ -34,6 +34,7 @@
<menu_item_call label="Seleziona tutto" name="Select All"/>
<menu_item_call label="Deseleziona" name="Deselect"/>
<menu_item_call label="Cerca / Sostituisci..." name="Search / Replace..."/>
+ <menu_item_call label="Passa alla riga..." name="Go to line..."/>
</menu>
<menu label="Guida" name="Help">
<menu_item_call label="Aiuto..." name="Help..."/>
diff --git a/indra/newview/skins/default/xui/it/panel_script_limits_my_avatar.xml b/indra/newview/skins/default/xui/it/panel_script_limits_my_avatar.xml
index 98096a391a..98096a391a 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_script_limits_my_avatar.xml
+++ b/indra/newview/skins/default/xui/it/panel_script_limits_my_avatar.xml
diff --git a/indra/newview/skins/default/xui/it/panel_script_limits_region_memory.xml b/indra/newview/skins/default/xui/it/panel_script_limits_region_memory.xml
index df7b0eae1c..df7b0eae1c 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_script_limits_region_memory.xml
+++ b/indra/newview/skins/default/xui/it/panel_script_limits_region_memory.xml
diff --git a/indra/newview/skins/default/xui/it/panel_script_question_toast.xml b/indra/newview/skins/default/xui/it/panel_script_question_toast.xml
new file mode 100755
index 0000000000..a2d0237da0
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/panel_script_question_toast.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<panel label="script_question_panel" name="panel_script_question_toast">
+ <panel label="buttons_panel" name="buttons_panel"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_scrolling_param.xml b/indra/newview/skins/default/xui/it/panel_scrolling_param.xml
index b5f8c8d6f0..b5f8c8d6f0 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_scrolling_param.xml
+++ b/indra/newview/skins/default/xui/it/panel_scrolling_param.xml
diff --git a/indra/newview/skins/default/xui/it/panel_scrolling_param_base.xml b/indra/newview/skins/default/xui/it/panel_scrolling_param_base.xml
index fa659040ea..fa659040ea 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_scrolling_param_base.xml
+++ b/indra/newview/skins/default/xui/it/panel_scrolling_param_base.xml
diff --git a/indra/newview/skins/default/xui/it/panel_side_tray.xml b/indra/newview/skins/default/xui/it/panel_side_tray.xml
deleted file mode 100644
index e0143088a5..0000000000
--- a/indra/newview/skins/default/xui/it/panel_side_tray.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<!-- Side tray cannot show background because it is always
- partially on screen to hold tab buttons. -->
-<side_tray name="sidebar">
- <sidetray_tab description="Apri/chiudi la barra laterale." name="sidebar_openclose" tab_title="Apri/chiudi la barra laterale"/>
- <sidetray_tab description="Casa." name="sidebar_home" tab_title="Home">
- <panel label="casa" name="panel_home"/>
- </sidetray_tab>
- <sidetray_tab description="Modifica il tuo profilo pubblico e i preferiti." name="sidebar_me" tab_title="Il mio profilo">
- <panel_container name="panel_container">
- <panel label="Io" name="panel_me"/>
- </panel_container>
- </sidetray_tab>
- <sidetray_tab description="Trova amici, contatti e persone nelle vicinanze." name="sidebar_people" tab_title="Persone">
- <panel_container name="panel_container">
- <panel label="Profilo del gruppo" name="panel_group_info_sidetray"/>
- <panel label="Residenti e oggetti bloccati" name="panel_block_list_sidetray"/>
- </panel_container>
- </sidetray_tab>
- <sidetray_tab description="Trova luoghi dove andare e luoghi già visitati." label="Luoghi" name="sidebar_places" tab_title="Luoghi">
- <panel label="Luoghi" name="panel_places"/>
- </sidetray_tab>
- <sidetray_tab description="Sfoglia il tuo inventario." name="sidebar_inventory" tab_title="Il mio inventario">
- <panel label="Modifica inventario" name="sidepanel_inventory"/>
- </sidetray_tab>
- <sidetray_tab description="Cambia il tuo aspetto ed il tuo look attuale." name="sidebar_appearance" tab_title="Il mio aspetto">
- <panel label="Modifica aspetto fisico" name="sidepanel_appearance"/>
- </sidetray_tab>
-</side_tray>
diff --git a/indra/newview/skins/default/xui/it/panel_side_tray_tab_caption.xml b/indra/newview/skins/default/xui/it/panel_side_tray_tab_caption.xml
index 3c7874e093..3c7874e093 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_side_tray_tab_caption.xml
+++ b/indra/newview/skins/default/xui/it/panel_side_tray_tab_caption.xml
diff --git a/indra/newview/skins/default/xui/it/panel_snapshot_inventory.xml b/indra/newview/skins/default/xui/it/panel_snapshot_inventory.xml
index c9245029b7..c9245029b7 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_snapshot_inventory.xml
+++ b/indra/newview/skins/default/xui/it/panel_snapshot_inventory.xml
diff --git a/indra/newview/skins/default/xui/it/panel_snapshot_local.xml b/indra/newview/skins/default/xui/it/panel_snapshot_local.xml
index 4b725b68f9..4b725b68f9 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_snapshot_local.xml
+++ b/indra/newview/skins/default/xui/it/panel_snapshot_local.xml
diff --git a/indra/newview/skins/default/xui/it/panel_snapshot_options.xml b/indra/newview/skins/default/xui/it/panel_snapshot_options.xml
index f2d42c5197..f2d42c5197 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_snapshot_options.xml
+++ b/indra/newview/skins/default/xui/it/panel_snapshot_options.xml
diff --git a/indra/newview/skins/default/xui/it/panel_snapshot_postcard.xml b/indra/newview/skins/default/xui/it/panel_snapshot_postcard.xml
index 3703b97e6c..3703b97e6c 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_snapshot_postcard.xml
+++ b/indra/newview/skins/default/xui/it/panel_snapshot_postcard.xml
diff --git a/indra/newview/skins/default/xui/it/panel_snapshot_profile.xml b/indra/newview/skins/default/xui/it/panel_snapshot_profile.xml
index 2cdbf97049..2cdbf97049 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_snapshot_profile.xml
+++ b/indra/newview/skins/default/xui/it/panel_snapshot_profile.xml
diff --git a/indra/newview/skins/default/xui/it/panel_sound_devices.xml b/indra/newview/skins/default/xui/it/panel_sound_devices.xml
index b1934fd515..b1934fd515 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_sound_devices.xml
+++ b/indra/newview/skins/default/xui/it/panel_sound_devices.xml
diff --git a/indra/newview/skins/default/xui/it/panel_stand_stop_flying.xml b/indra/newview/skins/default/xui/it/panel_stand_stop_flying.xml
index e4ff7019ec..e4ff7019ec 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_stand_stop_flying.xml
+++ b/indra/newview/skins/default/xui/it/panel_stand_stop_flying.xml
diff --git a/indra/newview/skins/default/xui/it/panel_status_bar.xml b/indra/newview/skins/default/xui/it/panel_status_bar.xml
index 0aaf89d8c8..0aaf89d8c8 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_status_bar.xml
+++ b/indra/newview/skins/default/xui/it/panel_status_bar.xml
diff --git a/indra/newview/skins/default/xui/it/panel_teleport_history.xml b/indra/newview/skins/default/xui/it/panel_teleport_history.xml
index f4fa59babe..f4fa59babe 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_teleport_history.xml
+++ b/indra/newview/skins/default/xui/it/panel_teleport_history.xml
diff --git a/indra/newview/skins/default/xui/it/panel_teleport_history_item.xml b/indra/newview/skins/default/xui/it/panel_teleport_history_item.xml
index 2ba4baacaf..2ba4baacaf 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_teleport_history_item.xml
+++ b/indra/newview/skins/default/xui/it/panel_teleport_history_item.xml
diff --git a/indra/newview/skins/default/xui/it/panel_tools_texture.xml b/indra/newview/skins/default/xui/it/panel_tools_texture.xml
new file mode 100644
index 0000000000..36ad2980cb
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/panel_tools_texture.xml
@@ -0,0 +1,116 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Texture" name="Texture">
+ <panel.string name="string repeats per meter">
+ Ripetizioni al metro
+ </panel.string>
+ <panel.string name="string repeats per face">
+ Ripetizioni per faccia
+ </panel.string>
+ <text name="color label">
+ Colore
+ </text>
+ <color_swatch label="" name="colorswatch" tool_tip="Clicca per aprire il selettore dei colori"/>
+ <text name="color trans">
+ Trasparenza %
+ </text>
+ <text name="glow label">
+ Bagliore
+ </text>
+ <check_box label="Luminosità massima" name="checkbox fullbright"/>
+ <combo_box name="combobox matmedia">
+ <combo_box.item label="Materiali" name="Materials"/>
+ <combo_box.item label="Multimedia" name="Media"/>
+ </combo_box>
+ <combo_box name="combobox mattype">
+ <combo_box.item label="Texture (diffusa)" name="Texture (diffuse)"/>
+ <combo_box.item label="Irregolarità (normale)" name="Bumpiness (normal)"/>
+ <combo_box.item label="Lucentezza (speculare)" name="Shininess (specular)"/>
+ </combo_box>
+ <texture_picker label="Texture" name="texture control" tool_tip="Clicca per scegliere una fotografia"/>
+ <text name="label alphamode">
+ Modalità Alfa
+ </text>
+ <combo_box name="combobox alphamode">
+ <combo_box.item label="Nessuno" name="None"/>
+ <combo_box.item label="Miscelazione Alfa" name="Alpha blending"/>
+ <combo_box.item label="Mascheratura Alfa" name="Alpha masking"/>
+ <combo_box.item label="Mascheratura emissiva" name="Emissive mask"/>
+ </combo_box>
+ <text name="label maskcutoff">
+ Limite mascheratura
+ </text>
+ <texture_picker label="Texture" name="bumpytexture control" tool_tip="Clicca per scegliere una fotografia"/>
+ <text name="label bumpiness">
+ Irregolarità
+ </text>
+ <combo_box name="combobox bumpiness">
+ <combo_box.item label="Nessuno" name="None"/>
+ <combo_box.item label="Luminosità" name="Brightness"/>
+ <combo_box.item label="Oscurità" name="Darkness"/>
+ <combo_box.item label="venatura" name="woodgrain"/>
+ <combo_box.item label="corteccia" name="bark"/>
+ <combo_box.item label="mattoni" name="bricks"/>
+ <combo_box.item label="scacchiera" name="checker"/>
+ <combo_box.item label="cemento" name="concrete"/>
+ <combo_box.item label="incrostatura" name="crustytile"/>
+ <combo_box.item label="gemma" name="cutstone"/>
+ <combo_box.item label="dischi" name="discs"/>
+ <combo_box.item label="ciottoli" name="gravel"/>
+ <combo_box.item label="batteri" name="petridish"/>
+ <combo_box.item label="rivestimento" name="siding"/>
+ <combo_box.item label="lastricato" name="stonetile"/>
+ <combo_box.item label="stucco" name="stucco"/>
+ <combo_box.item label="suzione" name="suction"/>
+ <combo_box.item label="trama" name="weave"/>
+ </combo_box>
+ <texture_picker label="Texture" name="shinytexture control" tool_tip="Clicca per scegliere una fotografia"/>
+ <text name="label shininess">
+ Lucentezza
+ </text>
+ <combo_box name="combobox shininess">
+ <combo_box.item label="Nessuna" name="None"/>
+ <combo_box.item label="Bassa" name="Low"/>
+ <combo_box.item label="Media" name="Medium"/>
+ <combo_box.item label="Alta" name="High"/>
+ </combo_box>
+ <text name="label glossiness">
+ Patinatura
+ </text>
+ <text name="label environment">
+ Ambiente
+ </text>
+ <text name="label shinycolor">
+ Colore
+ </text>
+ <color_swatch label="" name="shinycolorswatch" tool_tip="Clicca per aprire il selettore dei colori"/>
+ <text name="media_info">
+ L&apos;URL dell&apos;eventuale elemento multimediale selezionato va qui
+ </text>
+ <button label="Scegli..." name="add_media" tool_tip="Aggiungi elemento multimediale"/>
+ <button label="Rimuovi" name="delete_media" tool_tip="Cancella questa texture dell&apos;elemento multimediale"/>
+ <button label="Alllinea" label_selected="Allinea elmento multimediale" name="button align" tool_tip="Allinea texture dell&apos;elemento multimediale (il caricamento deve prima essere completato)"/>
+ <text name="tex gen">
+ Mappatura
+ </text>
+ <combo_box name="combobox texgen">
+ <combo_box.item label="Predefinita" name="Default"/>
+ <combo_box.item label="Planare" name="Planar"/>
+ </combo_box>
+ <spinner label="Scala orizzontale" name="TexScaleU"/>
+ <spinner label="Scala veritcale" name="TexScaleV"/>
+ <spinner label="Ripetizioni al metro" name="rptctrl"/>
+ <spinner label="Gradi di rotazione" name="TexRot"/>
+ <spinner label="Spostamento orizzontale" name="TexOffsetU"/>
+ <spinner label="Spostamento verticale" name="TexOffsetV"/>
+ <spinner label="Scala orizzontale" name="bumpyScaleU"/>
+ <spinner label="Scala veritcale" name="bumpyScaleV"/>
+ <spinner label="Gradi di rotazione" name="bumpyRot"/>
+ <spinner label="Spostamento orizzontale" name="bumpyOffsetU"/>
+ <spinner label="Spostamento verticale" name="bumpyOffsetV"/>
+ <spinner label="Scala orizzontale" name="shinyScaleU"/>
+ <spinner label="Scala veritcale" name="shinyScaleV"/>
+ <spinner label="Gradi di rotazione" name="shinyRot"/>
+ <spinner label="Spostamento orizzontale" name="shinyOffsetU"/>
+ <spinner label="Spostamento verticale" name="shinyOffsetV"/>
+ <check_box initial_value="false" label="Allinea facce planari" name="checkbox planar align" tool_tip="Allinea le texture su tutte le facce selezionate con l’ultima faccia selezionata. È richiesta la mappatura planare delle texture."/>
+</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_voice_effect.xml b/indra/newview/skins/default/xui/it/panel_voice_effect.xml
index b43f766e5e..b43f766e5e 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_voice_effect.xml
+++ b/indra/newview/skins/default/xui/it/panel_voice_effect.xml
diff --git a/indra/newview/skins/default/xui/it/panel_volume_pulldown.xml b/indra/newview/skins/default/xui/it/panel_volume_pulldown.xml
new file mode 100755
index 0000000000..bc17fc0c89
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/panel_volume_pulldown.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="volumepulldown_floater" width="220">
+ <button left="197" name="prefs_btn"/>
+ <slider label="Principale" label_width="60" name="System Volume" width="160"/>
+ <slider label="Pulsanti" label_width="60" name="UI Volume" width="160"/>
+ <slider label="Ambiente" label_width="60" name="Wind Volume" width="160"/>
+ <slider label="Suoni" label_width="60" name="SFX Volume" width="160"/>
+ <check_box name="gesture_audio_play_btn" tool_tip="Attiva suoni dai gesti"/>
+ <slider label="Musica" label_width="60" name="Music Volume" width="160"/>
+ <check_box name="enable_music" tool_tip="Attiva streaming musica"/>
+ <slider label="Multimedia" label_width="60" name="Media Volume" width="160"/>
+ <check_box name="enable_media" tool_tip="Attiva streaming multimediale"/>
+ <slider label="Voce" label_width="60" name="Voice Volume" width="160"/>
+ <check_box name="enable_voice_check" tool_tip="Attiva chat vocale"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_world_map.xml b/indra/newview/skins/default/xui/it/panel_world_map.xml
index 642af75028..642af75028 100644..100755
--- a/indra/newview/skins/default/xui/it/panel_world_map.xml
+++ b/indra/newview/skins/default/xui/it/panel_world_map.xml
diff --git a/indra/newview/skins/default/xui/it/role_actions.xml b/indra/newview/skins/default/xui/it/role_actions.xml
index 300e6cf721..3ccb674ed0 100644..100755
--- a/indra/newview/skins/default/xui/it/role_actions.xml
+++ b/indra/newview/skins/default/xui/it/role_actions.xml
@@ -25,7 +25,7 @@
</action_set>
<action_set description="Queste abilità permettono di cambiare il nome del lotto, le impostazioni di pubblicazione, la visibilità negli elenchi e il punto di arrivo, nonché opzioni di indirizzamento del Teleport." name="Parcel Identity">
<action description="Premi Mostra luogo nella ricerca e seleziona una categoria" longdescription="Premi Mostra luogo nella ricerca e seleziona una categoria di lotto in Informazioni sul terreno &gt; scheda Opzioni." name="land find places" value="17"/>
- <action description="Cambia il nome del lotto, la descrizione e le impostazioni di Mostra luogo nella ricerca" longdescription="Cambia il nome del lotto, la descrizione e le impostazioni di Mostra luogo nella ricerca. Ciò viene fatto in Informazioni sul terreno &gt; scheda Opzioni." name="land change identity" value="18"/>
+ <action description="Cambia il nome, la descrizione e le impostazioni &apos;Contenuto Moderato&apos; per il lotto" longdescription="Cambia il nome, la descrizione e le impostazioni &apos;Contenuto Moderato&apos; per il lotto. Ciò viene fatto in Informazioni sul terreno &gt; scheda Opzioni." name="land change identity" value="18"/>
<action description="Impostare il punto di arrivo e l&apos;indirizzamento del Teleport" longdescription="In un lotto di proprietà di un gruppo, i membri con questo ruolo e abilità possono impostare un punto di arrivo per i teleport entranti e impostare anche l&apos;indirizzamento del teleport per ulteriore precisione. Viene fatto in Informazioni sul terreno &gt; Opzioni." name="land set landing point" value="19"/>
</action_set>
<action_set description="Queste abilità hanno poteri relativi alle opzioni dei lotti, come la creazione di oggetti, la modifica del terreno e le impostazioni per la musica e gli elementi multimediali." name="Parcel Settings">
diff --git a/indra/newview/skins/default/xui/it/sidepanel_appearance.xml b/indra/newview/skins/default/xui/it/sidepanel_appearance.xml
index 220a6f84af..220a6f84af 100644..100755
--- a/indra/newview/skins/default/xui/it/sidepanel_appearance.xml
+++ b/indra/newview/skins/default/xui/it/sidepanel_appearance.xml
diff --git a/indra/newview/skins/default/xui/it/sidepanel_inventory.xml b/indra/newview/skins/default/xui/it/sidepanel_inventory.xml
index 5ac0961bd7..5ac0961bd7 100644..100755
--- a/indra/newview/skins/default/xui/it/sidepanel_inventory.xml
+++ b/indra/newview/skins/default/xui/it/sidepanel_inventory.xml
diff --git a/indra/newview/skins/default/xui/it/sidepanel_item_info.xml b/indra/newview/skins/default/xui/it/sidepanel_item_info.xml
index 900a65956b..2b3ea0fb83 100644..100755
--- a/indra/newview/skins/default/xui/it/sidepanel_item_info.xml
+++ b/indra/newview/skins/default/xui/it/sidepanel_item_info.xml
@@ -3,6 +3,9 @@
<panel.string name="unknown">
(sconosciuto)
</panel.string>
+ <panel.string name="unknown_multiple">
+ (sconosciuto / multiplo)
+ </panel.string>
<panel.string name="public">
(pubblico)
</panel.string>
diff --git a/indra/newview/skins/default/xui/it/sidepanel_task_info.xml b/indra/newview/skins/default/xui/it/sidepanel_task_info.xml
index cfabdc81b0..5f912dd126 100644..100755
--- a/indra/newview/skins/default/xui/it/sidepanel_task_info.xml
+++ b/indra/newview/skins/default/xui/it/sidepanel_task_info.xml
@@ -18,6 +18,12 @@
<panel.string name="text modify info 4">
Non puoi modificare questi oggetti
</panel.string>
+ <panel.string name="text modify info 5">
+ Questo oggetto non può essere modificato attraverso il confine di una regione
+ </panel.string>
+ <panel.string name="text modify info 6">
+ Questi oggetti non possono essere modificati attraverso il confine di una regione
+ </panel.string>
<panel.string name="text modify warning">
Questo oggetto ha parti collegate
</panel.string>
@@ -66,6 +72,7 @@
<combo_box.item label="Acquista oggetto" name="Buyobject"/>
<combo_box.item label="Paga oggetto" name="Payobject"/>
<combo_box.item label="Apri" name="Open"/>
+ <combo_box.item label="Ingrandisci" name="Zoom"/>
</combo_box>
<panel name="perms_inv">
<text name="perm_modify">
@@ -95,6 +102,9 @@
</combo_box>
<spinner label="Prezzo: L$" name="Edit Cost"/>
<check_box label="Mostra nella ricerca" name="search_check" tool_tip="Permetti alle persone di vedere questo oggetto nei risultati della ricerca"/>
+ <text name="pathfinding_attributes_label">
+ Attributi pathfinding:
+ </text>
<text name="B:">
B:
</text>
diff --git a/indra/newview/skins/default/xui/it/strings.xml b/indra/newview/skins/default/xui/it/strings.xml
index 8529fadd7d..60ed2b0929 100644..100755
--- a/indra/newview/skins/default/xui/it/strings.xml
+++ b/indra/newview/skins/default/xui/it/strings.xml
@@ -134,7 +134,10 @@
Esci
</string>
<string name="create_account_url">
- http://join.secondlife.com/index.php?lang=it-IT
+ http://join.secondlife.com/?sourceid=[sourceid]
+ </string>
+ <string name="ViewerDownloadURL">
+ http://secondlife.com/download.
</string>
<string name="LoginFailedViewerNotPermitted">
Il viewer utilizzato non è più in grado di accedere a Second Life. Visita la parina seguente per scaricare un nuovo viewer:
@@ -445,6 +448,9 @@ Prova ad accedere nuovamente tra un minuto.
<string name="SLappAgentRequestFriend">
Richiesta di amicizia
</string>
+ <string name="SLappAgentRemoveFriend">
+ Rimozione amico
+ </string>
<string name="BUTTON_CLOSE_DARWIN">
Chiudi (⌘W)
</string>
@@ -616,8 +622,8 @@ Prova ad accedere nuovamente tra un minuto.
<string name="AvatarAway">
Assente
</string>
- <string name="AvatarBusy">
- Occupato
+ <string name="AvatarDoNotDisturb">
+ Non disturbare
</string>
<string name="AvatarMuted">
Mutato
@@ -832,6 +838,9 @@ Prova ad accedere nuovamente tra un minuto.
<string name="multiple_textures">
Multiple
</string>
+ <string name="use_texture">
+ Usa texture
+ </string>
<string name="texture_loading">
Caricamento in corso...
</string>
@@ -853,6 +862,12 @@ Prova ad accedere nuovamente tra un minuto.
<string name="ST_NO_JOINT">
Impossibile trovare ROOT o JOINT.
</string>
+ <string name="NearbyChatTitle">
+ Chat nei dintorni
+ </string>
+ <string name="NearbyChatLabel">
+ (Chat nei dintorni)
+ </string>
<string name="whisper">
sussurra:
</string>
@@ -880,6 +895,9 @@ Prova ad accedere nuovamente tra un minuto.
<string name="ScriptQuestionCautionChatDenied">
A &apos;[OBJECTNAME]&apos;, un oggetto di proprietà di &apos;[OWNERNAME]&apos;, situato in [REGIONNAME] [REGIONPOS], è stato negato il permesso di: [PERMISSIONS].
</string>
+ <string name="AdditionalPermissionsRequestHeader">
+ Se consenti l&apos;accesso al tuo account, consentirai anche all&apos;oggetto di:
+ </string>
<string name="ScriptTakeMoney">
Prendere dollari Linden (L$) da te
</string>
@@ -913,6 +931,27 @@ Prova ad accedere nuovamente tra un minuto.
<string name="ControlYourCamera">
Controllare la tua fotocamera
</string>
+ <string name="AgentNameSubst">
+ (Tu)
+ </string>
+ <string name="TeleportYourAgent">
+ Teleportarti
+ </string>
+ <string name="JoinAnExperience">
+ Partecipa a un&apos;esperienza
+ </string>
+ <string name="SilentlyManageEstateAccess">
+ Omette gli avvisi durante la gestione degli elenchi di accesso alle proprietà immobiliari
+ </string>
+ <string name="OverrideYourAnimations">
+ Sostituisce le animazioni predefinite
+ </string>
+ <string name="ScriptReturnObjects">
+ Restituisce oggetti per conto tuo
+ </string>
+ <string name="UnknownScriptPermission">
+ (sconosciuto)!
+ </string>
<string name="SIM_ACCESS_PG">
Generale
</string>
@@ -991,17 +1030,8 @@ Prova ad accedere nuovamente tra un minuto.
<string name="script_files">
Script
</string>
- <string name="AvatarSetNotAway">
- Imposta come non assente
- </string>
- <string name="AvatarSetAway">
- Imposta come assente
- </string>
- <string name="AvatarSetNotBusy">
- Imposta come non occupato
- </string>
- <string name="AvatarSetBusy">
- Imposta come occupato
+ <string name="dictionary_files">
+ Dizionari
</string>
<string name="shape">
Figura corporea
@@ -1235,7 +1265,7 @@ Prova ad accedere nuovamente tra un minuto.
https://marketplace.[MARKETPLACE_DOMAIN_NAME]/
</string>
<string name="MarketplaceURL_CreateStore">
- http://community.secondlife.com/t5/English-Knowledge-Base/Selling-in-the-Marketplace/ta-p/700193#Section_.4
+ http://community.secondlife.com/t5/English-Knowledge-Base/Selling-in-the-Marketplace/ta-p/700193#Section_.3
</string>
<string name="MarketplaceURL_Dashboard">
https://marketplace.[MARKETPLACE_DOMAIN_NAME]/merchants/store/dashboard
@@ -1390,6 +1420,12 @@ Prova ad accedere nuovamente tra un minuto.
<string name="InvFolder favorite">
I miei preferiti
</string>
+ <string name="InvFolder Favorites">
+ I miei preferiti
+ </string>
+ <string name="InvFolder favorites">
+ I miei preferiti
+ </string>
<string name="InvFolder Current Outfit">
Abbigliamento attuale
</string>
@@ -1405,6 +1441,12 @@ Prova ad accedere nuovamente tra un minuto.
<string name="InvFolder Meshes">
Reticoli
</string>
+ <string name="InvFolder Received Items">
+ Oggetti ricevuti
+ </string>
+ <string name="InvFolder Merchant Outbox">
+ Casella venditore in uscita
+ </string>
<string name="InvFolder Friends">
Amici
</string>
@@ -1935,6 +1977,12 @@ Prova ad accedere nuovamente tra un minuto.
<string name="ATTACH_HUD_BOTTOM_RIGHT">
HUD basso a destra
</string>
+ <string name="ATTACH_NECK">
+ Collo
+ </string>
+ <string name="ATTACH_AVATAR_CENTER">
+ Centro avatar
+ </string>
<string name="CursorPos">
Riga [LINE], Colonna [COLUMN]
</string>
@@ -1947,8 +1995,8 @@ Prova ad accedere nuovamente tra un minuto.
<string name="PanelContentsNewScript">
Nuovo script
</string>
- <string name="BusyModeResponseDefault">
- Il residente al quale hai inviato un messaggio è in modalità &apos;occupato&apos;, ovvero ha chiesto di non essere disturbato. Il tuo messaggio comparirà nel suo pannello IM, dove potrà essere letto in un secondo momento.
+ <string name="DoNotDisturbModeResponseDefault">
+ Questo residente ha attivato la modalità &apos;Non disturbare&apos; e vedrà il tuo messaggio più tardi.
</string>
<string name="MuteByName">
(In base al nome)
@@ -2061,9 +2109,6 @@ Prova ad accedere nuovamente tra un minuto.
<string name="GroupMoneyDate">
[weekday,datetime,utc] [mth,datetime,utc] [day,datetime,utc], [year,datetime,utc]
</string>
- <string name="ViewerObjectContents">
- Contenuto
- </string>
<string name="AcquiredItems">
Oggetti acquisiti
</string>
@@ -2925,6 +2970,9 @@ Se il messaggio persiste, contatta [SUPPORT_SITE].
<string name="Hip Width">
Larghezza bacino
</string>
+ <string name="Hover">
+ Muovi sopra
+ </string>
<string name="In">
Dentro
</string>
@@ -3778,7 +3826,13 @@ Se il messaggio persiste, contatta [SUPPORT_SITE].
Regione generale
</string>
<string name="LocationCtrlSeeAVsTooltip">
- Avatar visibili e chat consentita fuori di questo lotto
+ Gli avatar in questo lotto non possono essere visti o sentiti da avatar all&apos;esterno del lotto
+ </string>
+ <string name="LocationCtrlPathfindingDirtyTooltip">
+ Gli oggetti che si muovono potrebbero non comportarsi correttamente in questa regione fino a quando non viene eseguito il rebake della regione.
+ </string>
+ <string name="LocationCtrlPathfindingDisabledTooltip">
+ Il pathfinding dinamico non è attivato in questa regione.
</string>
<string name="UpdaterWindowTitle">
Aggiornamento [APP_NAME]
@@ -3849,6 +3903,12 @@ Se il messaggio persiste, contatta [SUPPORT_SITE].
<string name="IM_unblock_only_groups_friends">
Per vedere questo messaggio, devi deselezionare &apos;Solo amici e gruppi possono chiamarmi o mandarmi IM&apos; in Preferenze/Privacy.
</string>
+ <string name="OnlineStatus">
+ Online
+ </string>
+ <string name="OfflineStatus">
+ Offline
+ </string>
<string name="answered_call">
Risposto alla chiamata
</string>
@@ -3858,6 +3918,9 @@ Se il messaggio persiste, contatta [SUPPORT_SITE].
<string name="you_joined_call">
Ti sei collegato alla chiamata in voce
</string>
+ <string name="you_auto_rejected_call-im">
+ Hai rifiutato automaticamente la chiamata voce mentre era attivata la modalità &apos;Non disturbare&apos;.
+ </string>
<string name="name_started_call">
[NAME] ha iniziato una chiamata vocale
</string>
@@ -3870,6 +3933,9 @@ Se il messaggio persiste, contatta [SUPPORT_SITE].
<string name="hang_up-im">
Chiusa la chiamata
</string>
+ <string name="conference-title">
+ Chat con più persone
+ </string>
<string name="conference-title-incoming">
Chiamata in conferenza con [AGENT_NAME]
</string>
@@ -4742,6 +4808,9 @@ Prova a racchiudere il percorso dell&apos;editor in doppie virgolette.
<string name="Command_Chat_Label">
Chat
</string>
+ <string name="Command_Conversations_Label">
+ Conversazioni
+ </string>
<string name="Command_Compass_Label">
Bussola
</string>
@@ -4817,6 +4886,9 @@ Prova a racchiudere il percorso dell&apos;editor in doppie virgolette.
<string name="Command_Chat_Tooltip">
Chatta con persone vicine usando il testo
</string>
+ <string name="Command_Conversations_Tooltip">
+ Conversa con chiunque
+ </string>
<string name="Command_Compass_Tooltip">
Bussola
</string>
@@ -4910,6 +4982,21 @@ Prova a racchiudere il percorso dell&apos;editor in doppie virgolette.
<string name="Normal">
Normale
</string>
+ <string name="Pathfinding_Wiki_URL">
+ http://wiki.secondlife.com/wiki/Pathfinding_Tools_in_the_Second_Life_Viewer
+ </string>
+ <string name="Pathfinding_Object_Attr_None">
+ Nessuno
+ </string>
+ <string name="Pathfinding_Object_Attr_Permanent">
+ Influenza il navmesh
+ </string>
+ <string name="Pathfinding_Object_Attr_Character">
+ Personaggio
+ </string>
+ <string name="Pathfinding_Object_Attr_MultiSelect">
+ (Multiple)
+ </string>
<string name="snapshot_quality_very_low">
Molto basso
</string>
@@ -4925,4 +5012,22 @@ Prova a racchiudere il percorso dell&apos;editor in doppie virgolette.
<string name="snapshot_quality_very_high">
Molto alto
</string>
+ <string name="TeleportMaturityExceeded">
+ Il Residente non può visitare questa regione.
+ </string>
+ <string name="UserDictionary">
+ [User]
+ </string>
+ <string name="logging_calls_disabled_log_empty">
+ Le conversazioni non vengono registrate. Per iniziare a registrare, seleziona &quot;Salva: Solo registro&quot; oppure &quot;Salva: Registri e trascrizioni&quot; in Preferenze &gt; Chat.
+ </string>
+ <string name="logging_calls_disabled_log_not_empty">
+ Non verranno registrate più le conversazioni. Per riprendere a registrare, seleziona &quot;Salva: Solo registro&quot; oppure &quot;Salva: Registri e trascrizioni&quot; in Preferenze &gt; Chat.
+ </string>
+ <string name="logging_calls_enabled_log_empty">
+ Nessuna conversazione in registro. Dopo che hai contattato qualcuno o se qualcuno ti contatta, una voce del registro verrà mostrata qui.
+ </string>
+ <string name="loading_chat_logs">
+ Caricamento in corso...
+ </string>
</strings>
diff --git a/indra/newview/skins/default/xui/it/teleport_strings.xml b/indra/newview/skins/default/xui/it/teleport_strings.xml
index f485212290..bd967ebcc4 100644..100755
--- a/indra/newview/skins/default/xui/it/teleport_strings.xml
+++ b/indra/newview/skins/default/xui/it/teleport_strings.xml
@@ -43,6 +43,9 @@ Per ripetere l&apos;esercitazione, visita &apos;Welcome Island Public&apos;.
<message name="no_inventory_host">
L&apos;inventario è temporaneamente inaccessibile.
</message>
+ <message name="MustGetAgeRegion">
+ Per poter entrare in questa regione devi avere almeno 18 anni.
+ </message>
</message_set>
<message_set name="progress">
<message name="sending_dest">
@@ -78,5 +81,8 @@ Per ripetere l&apos;esercitazione, visita &apos;Welcome Island Public&apos;.
<message name="requesting">
Avvio teletrasporto....
</message>
+ <message name="pending">
+ Teleport in sospeso...
+ </message>
</message_set>
</teleport_messages>
diff --git a/indra/newview/skins/default/xui/ja/floater_about.xml b/indra/newview/skins/default/xui/ja/floater_about.xml
index 3c7a210a22..63a4e69c10 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_about.xml
+++ b/indra/newview/skins/default/xui/ja/floater_about.xml
@@ -8,7 +8,9 @@
コンパイラー [COMPILER] [COMPILER_VERSION] ãƒãƒ¼ã‚¸ãƒ§ãƒ³
</floater.string>
<floater.string name="AboutPosition">
- ã‚ãªãŸã®ç¾åœ¨åœ°ã¯ã€[POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1] ã® [REGION] ã§ã™ã€‚ä½ç½®ã¯ &lt;nolink&gt;[HOSTNAME]&lt;/nolink&gt; ã§ã™ã€‚([HOSTIP])
+ ã‚ãªãŸã®ç¾åœ¨åœ°ã¯ã€[POSITION_LOCAL_0,number,1]ã€[POSITION_LOCAL_1,number,1]ã€[POSITION_LOCAL_2,number,1] ã® [REGION] ã§ã™ã€‚ä½ç½®ã¯ &lt;nolink&gt;[HOSTNAME]&lt;/nolink&gt; ã§ã™ã€‚([HOSTIP])
+SLURL:&lt;nolink&gt;[SLURL]&lt;/nolink&gt;
+(グローãƒãƒ«åº§æ¨™ [POSITION_0,number,1]ã€[POSITION_1,number,1]ã€[POSITION_2,number,1])
[SERVER_VERSION]
[SERVER_RELEASE_NOTES_URL]
</floater.string>
@@ -66,27 +68,26 @@ Qt Webkit ãƒãƒ¼ã‚¸ãƒ§ãƒ³ï¼š [QT_WEBKIT_VERSION]
</panel>
<panel label="ライセンス" name="licenses_panel">
<text_editor name="credits_editor">
- 3Dconnexion SDK Copyright (C) 1992-2007 3Dconnexion
-APR Copyright (C) 2000-2004 The Apache Software Foundation
-Collada DOM Copyright 2005 Sony Computer Entertainment Inc.
-cURL Copyright (C) 1996-2002, Daniel Stenberg, (daniel@haxx.se)
+ 3Dconnexion SDK Copyright (C) 1992-2009 3Dconnexion
+APR Copyright (C) 2011 The Apache Software Foundation
+Collada DOM Copyright 2006 Sony Computer Entertainment Inc.
+cURL Copyright (C) 1996-2010, Daniel Stenberg, (daniel@haxx.se)
DBus/dbus-glib Copyright (C) 2002, 2003 CodeFactory AB / Copyright (C) 2003, 2004 Red Hat, Inc.
expat Copyright (C) 1998, 1999, 2000 Thai Open Source Software Center Ltd.
-FreeType Copyright (C) 1996-2002, The FreeType Project (www.freetype.org).
+FreeType Copyright (C) 1996-2002, 2006 David Turner, Robert Wilhelm, and Werner Lemberg.
GL Copyright (C) 1999-2004 Brian Paul.
GLOD Copyright (C) 2003-04 Jonathan Cohen, Nat Duca, Chris Niski, Johns Hopkins University and David Luebke, Brenden Schubert, University of Virginia.
google-perftools Copyright (c) 2005, Google Inc.
Havok.com(TM) Copyright (C) 1999-2001, Telekinesys Research Limited.
jpeg2000 Copyright (C) 2001, David Taubman, The University of New South Wales (UNSW)
jpeglib Copyright (C) 1991-1998, Thomas G. Lane.
-ogg/vorbis Copyright (C) 2001, Xiphophorus
-OpenSSL Copyright (C) 1998-2002 The OpenSSL Project.
-PCRE Copyright (c) 1997-2008 University of Cambridge
+ogg/vorbis Copyright (C) 2002, Xiphophorus
+OpenSSL Copyright (C) 1998-2008 The OpenSSL Project.
+PCRE Copyright (c) 1997-2012 University of Cambridge
SDL Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga
SSLeay Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
xmlrpc-epi Copyright (C) 2000 Epinions, Inc.
-zlib Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler.
-google-perftools Copyright (c) 2005, Google Inc.
+zlib Copyright (C) 1995-2012 Jean-loup Gailly and Mark Adler.
Second Life ビューワã§ã¯ Havok (TM) Physics ãŒä½¿ç”¨ã•ã‚Œã¦ã„ã¾ã™ã€‚(c)Copyright 1999-2010 Havok.com Inc. (and its Licensors).無断複写・複製・転載をç¦ã˜ã¾ã™ã€‚詳細ã«ã¤ã„ã¦ã¯ www.havok.com ã‚’ã”å‚ç…§ãã ã•ã„。
diff --git a/indra/newview/skins/default/xui/ja/floater_about_land.xml b/indra/newview/skins/default/xui/ja/floater_about_land.xml
index 7c87bad5a3..3b4b5ed070 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/ja/floater_about_land.xml
@@ -464,7 +464,7 @@
次ã®ä½äººã«ã®ã¿ã‚¢ã‚¯ã‚»ã‚¹ã‚’許å¯ï¼š
</text>
<check_box label="支払情情報ãŒç™»éŒ²ã•ã‚Œã¦ã„ã‚‹ [ESTATE_PAYMENT_LIMIT]" name="limit_payment" tool_tip="支払情報ãŒç™»éŒ²ã•ã‚Œã¦ã„ãªã„ã¨ã€ã“ã®åŒºç”»ã«ã‚¢ã‚¯ã‚»ã‚¹ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。詳細ã«ã¤ã„ã¦ã¯ã€[SUPPORT_SITE] ã‚’ã”覧ãã ã•ã„。"/>
- <check_box label="年齢確èªãŒæ¸ˆã‚“ã§ã„ã‚‹ [ESTATE_AGE_LIMIT]" name="limit_age_verified" tool_tip="ã“ã®åŒºç”»ã«ã‚¢ã‚¯ã‚»ã‚¹ã™ã‚‹ã«ã¯ã€å¹´é½¢ç¢ºèªã‚’済ã¾ã›ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚詳細ã«ã¤ã„ã¦ã¯ã€[SUPPORT_SITE] ã‚’ã”覧ãã ã•ã„。"/>
+ <check_box label="18 æ‰ä»¥ä¸Šã§ã™ [ESTATE_AGE_LIMIT]" name="limit_age_verified" tool_tip="ã“ã®åŒºç”»ã«ã‚¢ã‚¯ã‚»ã‚¹ã™ã‚‹ã«ã¯ã€18 æ‰ä»¥ä¸Šã§ãªã‘ã‚Œã°ãªã‚Šã¾ã›ã‚“。詳細ã«ã¤ã„ã¦ã¯ã€[SUPPORT_SITE] ã‚’ã”覧ãã ã•ã„。"/>
<check_box label="グループã®ã‚¢ã‚¯ã‚»ã‚¹ã‚’許å¯ï¼š[GROUP]" name="GroupCheck" tool_tip="「一般ã€ã‚¿ãƒ–ã§ã€ã‚°ãƒ«ãƒ¼ãƒ—ã‚’é¸æŠžã—ã¦ãã ã•ã„。"/>
<check_box label="入場許å¯ã‚’販売:" name="PassCheck" tool_tip="ã“ã®åŒºç”»ã¸ã®ä¸€æ™‚çš„ãªã‚¢ã‚¯ã‚»ã‚¹ã‚’許å¯ã—ã¾ã™ã€‚"/>
<combo_box name="pass_combo">
diff --git a/indra/newview/skins/default/xui/ja/floater_activeim.xml b/indra/newview/skins/default/xui/ja/floater_activeim.xml
index 1c743e1fd2..1c743e1fd2 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_activeim.xml
+++ b/indra/newview/skins/default/xui/ja/floater_activeim.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_animation_anim_preview.xml b/indra/newview/skins/default/xui/ja/floater_animation_anim_preview.xml
index 2bada303ae..2bada303ae 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_animation_anim_preview.xml
+++ b/indra/newview/skins/default/xui/ja/floater_animation_anim_preview.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_animation_bvh_preview.xml b/indra/newview/skins/default/xui/ja/floater_animation_bvh_preview.xml
index f74bab3598..f74bab3598 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_animation_bvh_preview.xml
+++ b/indra/newview/skins/default/xui/ja/floater_animation_bvh_preview.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_animation_preview.xml b/indra/newview/skins/default/xui/ja/floater_animation_preview.xml
deleted file mode 100644
index 548d24097f..0000000000
--- a/indra/newview/skins/default/xui/ja/floater_animation_preview.xml
+++ /dev/null
@@ -1,187 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Animation Preview" title="">
- <floater.string name="failed_to_initialize">
- モーションをåˆæœŸåŒ–ã§ãã¾ã›ã‚“ã§ã—ãŸ
- </floater.string>
- <floater.string name="anim_too_long">
- アニメーションファイルã®é•·ã•ã¯[LENGTH]秒ã§ã™ã€‚
-
-アニメーションã®æœ€å¤§ã®é•·ã•ã¯[MAX_LENGTH]秒ã§ã™ã€‚
- </floater.string>
- <floater.string name="failed_file_read">
- アニメーションファイルを読ã¿å–ã‚Œã¾ã›ã‚“。
-
-[STATUS]
- </floater.string>
- <floater.string name="E_ST_OK">
- Ok
- </floater.string>
- <floater.string name="E_ST_EOF">
- ä¸å®Œå…¨ãªãƒ•ã‚¡ã‚¤ãƒ«ã€‚
- </floater.string>
- <floater.string name="E_ST_NO_CONSTRAINT">
- 制約定義を読ã¿ã¨ã‚Œã¾ã›ã‚“。
- </floater.string>
- <floater.string name="E_ST_NO_FILE">
- BVH ファイルを開ã‘ã¾ã›ã‚“。
- </floater.string>
- <floater.string name="E_ST_NO_HIER">
- 無効㪠HIERARCHY ヘッダーã§ã™ã€‚.
- </floater.string>
- <floater.string name="E_ST_NO_JOINT">
- ROOT ã¾ãŸã¯ JOINT ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“。
- </floater.string>
- <floater.string name="E_ST_NO_NAME">
- JOINT ãƒãƒ¼ãƒ ã‚’å–å¾—ã§ãã¾ã›ã‚“。
- </floater.string>
- <floater.string name="E_ST_NO_OFFSET">
- OFFSET ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“。
- </floater.string>
- <floater.string name="E_ST_NO_CHANNELS">
- CHANNELS ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“。
- </floater.string>
- <floater.string name="E_ST_NO_ROTATION">
- 回転順åºã‚’å–å¾—ã§ãã¾ã›ã‚“。
- </floater.string>
- <floater.string name="E_ST_NO_AXIS">
- 回転軸をå–å¾—ã§ãã¾ã›ã‚“。
- </floater.string>
- <floater.string name="E_ST_NO_MOTION">
- MOTION ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“。
- </floater.string>
- <floater.string name="E_ST_NO_FRAMES">
- フレーム数をå–å¾—ã§ãã¾ã›ã‚“。
- </floater.string>
- <floater.string name="E_ST_NO_FRAME_TIME">
- フレームタイムをå–å¾—ã§ãã¾ã›ã‚“。
- </floater.string>
- <floater.string name="E_ST_NO_POS">
- ãƒã‚¸ã‚·ãƒ§ãƒ³å€¤ã‚’å–å¾—ã§ãã¾ã›ã‚“。
- </floater.string>
- <floater.string name="E_ST_NO_ROT">
- 回転値をå–å¾—ã§ãã¾ã›ã‚“。
- </floater.string>
- <floater.string name="E_ST_NO_XLT_FILE">
- ファイルを開ã‘ã¾ã›ã‚“。
- </floater.string>
- <floater.string name="E_ST_NO_XLT_HEADER">
- 読ã¿ã¨ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“。
- </floater.string>
- <floater.string name="E_ST_NO_XLT_NAME">
- 読ã¿ã¨ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“。
- </floater.string>
- <floater.string name="E_ST_NO_XLT_IGNORE">
- 読ã¿ã¨ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“。
- </floater.string>
- <floater.string name="E_ST_NO_XLT_RELATIVE">
- 読ã¿ã¨ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“。
- </floater.string>
- <floater.string name="E_ST_NO_XLT_OUTNAME">
- 読ã¿ã¨ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“。
- </floater.string>
- <floater.string name="E_ST_NO_XLT_MATRIX">
- 読ã¿ã¨ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“。
- </floater.string>
- <floater.string name="E_ST_NO_XLT_MERGECHILD">
- Mergechild åã‚’å–å¾—ã§ãã¾ã›ã‚“。
- </floater.string>
- <floater.string name="E_ST_NO_XLT_MERGEPARENT">
- Mergeparent åã‚’å–å¾—ã§ãã¾ã›ã‚“。
- </floater.string>
- <floater.string name="E_ST_NO_XLT_PRIORITY">
- プロパティ値をå–å¾—ã§ãã¾ã›ã‚“。
- </floater.string>
- <floater.string name="E_ST_NO_XLT_LOOP">
- ループ値をå–å¾—ã§ãã¾ã›ã‚“。
- </floater.string>
- <floater.string name="E_ST_NO_XLT_EASEIN">
- easeln 値をå–å¾—ã§ãã¾ã›ã‚“。
- </floater.string>
- <floater.string name="E_ST_NO_XLT_EASEOUT">
- easeOut 値をå–å¾—ã§ãã¾ã›ã‚“。
- </floater.string>
- <floater.string name="E_ST_NO_XLT_HAND">
- Hand morph 値をå–å¾—ã§ãã¾ã›ã‚“。
- </floater.string>
- <floater.string name="E_ST_NO_XLT_EMOTE">
- エモートåを読ã¿ã¨ã‚Œã¾ã›ã‚“。
- </floater.string>
- <floater.string name="E_ST_BAD_ROOT">
- ルートジョイントåãŒç„¡åŠ¹ã§ã™ã€‚「hipã€ã‚’使用ã—ã¦ãã ã•ã„。
- </floater.string>
- <text name="name_label">
- åå‰ï¼š
- </text>
- <text name="description_label">
- 説明:
- </text>
- <spinner label="優先順ä½" name="priority" tool_tip="ã“ã®ã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³ãŒã©ã®ã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³ã‚’上書ãã™ã‚‹ã‹ã‚’決ã‚ã¾ã™"/>
- <check_box label="ループ" name="loop_check" tool_tip="ã“ã®ã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³ã‚’ループå†ç”Ÿã—ã¾ã™"/>
- <spinner label="イン(ï¼…)" label_width="45" left="60" name="loop_in_point" tool_tip="アニメーションã®ãƒ«ãƒ¼ãƒ—復帰点を設定ã—ã¾ã™" width="100"/>
- <spinner label="アウト(ï¼…)" label_width="50" left="170" name="loop_out_point" tool_tip="アニメーションã®ãƒ«ãƒ¼ãƒ—終了点を設定ã—ã¾ã™" width="100"/>
- <text name="hand_label">
- 手ã®å‹•ã
- </text>
- <combo_box label="" name="hand_pose_combo" tool_tip="アニメーションå†ç”Ÿä¸­ã®æ‰‹ã®å‹•ãを決ã‚ã¾ã™">
- <combo_box.item label="広ã’ã‚‹" name="Spread"/>
- <combo_box.item label="リラックス" name="Relaxed"/>
- <combo_box.item label="指を指ã™ãƒ»ä¸¡æ‰‹" name="PointBoth"/>
- <combo_box.item label="拳" name="Fist"/>
- <combo_box.item label="リラックス・左" name="RelaxedLeft"/>
- <combo_box.item label="指を指ã™ãƒ»å·¦" name="PointLeft"/>
- <combo_box.item label="拳を上ã’る・左" name="FistLeft"/>
- <combo_box.item label="リラックス・å³" name="RelaxedRight"/>
- <combo_box.item label="指を指ã™ãƒ»å³" name="PointRight"/>
- <combo_box.item label="拳を上ã’る・å³" name="FistRight"/>
- <combo_box.item label="敬礼・å³" name="SaluteRight"/>
- <combo_box.item label="タイピング" name="Typing"/>
- <combo_box.item label="ピース・å³" name="PeaceRight"/>
- </combo_box>
- <text name="emote_label">
- 表ç¾
- </text>
- <combo_box label="" name="emote_combo" tool_tip="アニメーションå†ç”Ÿä¸­ã®é¡”ã®è¡¨æƒ…を決ã‚ã¾ã™">
- <item label="(ãªã—)" name="[None]" value=""/>
- <item label="アーーーーー" name="Aaaaah" value="アーーーーー"/>
- <item label="æれる" name="Afraid" value="æれる"/>
- <item label="怒る" name="Angry" value="怒る"/>
- <item label="満é¢ã®ç¬‘ã¿" name="BigSmile" value="満é¢ã®ç¬‘ã¿"/>
- <item label="退屈" name="Bored" value="退屈"/>
- <item label="æ³£ã" name="Cry" value="æ³£ã"/>
- <item label="侮辱" name="Disdain" value="侮辱"/>
- <item label="æ¥ãšã‹ã—ãŒã‚‹" name="Embarrassed" value="æ¥ãšã‹ã—ãŒã‚‹"/>
- <item label="ã—ã‹ã‚ã£é¢" name="Frown" value="ã—ã‹ã‚ã£é¢"/>
- <item label="キス" name="Kiss" value="キス"/>
- <item label="笑ã†" name="Laugh" value="笑ã†"/>
- <item label="Plllppt" name="Plllppt" value="Plllppt"/>
- <item label="嫌悪感" name="Repulsed" value="嫌悪感"/>
- <item label="悲ã—ã„" name="Sad" value="悲ã—ã„"/>
- <item label="è‚©ã‚’ã™ãã‚ã‚‹" name="Shrug" value="è‚©ã‚’ã™ãã‚ã‚‹"/>
- <item label="微笑む" name="Smile" value="微笑む"/>
- <item label="é©šã" name="Surprise" value="é©šã"/>
- <item label="ウィンク" name="Wink" value="ウィンク"/>
- <item label="心é…ã™ã‚‹" name="Worry" value="心é…ã™ã‚‹"/>
- </combo_box>
- <text name="preview_label">
- åŒæ™‚進行行動
- </text>
- <combo_box label="" name="preview_base_anim" tool_tip="ã‚¢ãƒã‚¿ãƒ¼ãŒæ™®é€šã®è¡Œå‹•ã‚’ã™ã‚‹ã¨ãã®ã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³ã®å‹•ãをテストã™ã‚‹ãŸã‚ã«ã“れを使ã„ã¾ã™ã€‚">
- <item label="ç«‹ã¤" name="Standing" value="ç«‹ã¤"/>
- <item label="æ­©ã" name="Walking" value="æ­©ã"/>
- <item label="座る" name="Sitting" value="座る"/>
- <item label="飛ã¶" name="Flying" value="飛ã¶"/>
- </combo_box>
- <spinner label="イーズイン(秒)" name="ease_in_time" tool_tip="アニメーションã®ãƒ–レンドイン時間(秒)"/>
- <spinner label="イーズアウト(秒)" name="ease_out_time" tool_tip="アニメーションã®ãƒ–レンドアウト時間(秒)"/>
- <button label="" name="play_btn" tool_tip="アニメーションをå†ç”Ÿã™ã‚‹"/>
- <button name="pause_btn" tool_tip="アニメーションを一時åœæ­¢ã™ã‚‹"/>
- <button label="" name="stop_btn" tool_tip="アニメーションã®å†ç”Ÿã‚’åœæ­¢"/>
- <slider label="" name="playback_slider"/>
- <text name="bad_animation_text">
- アニメーションファイルを読ã¿è¾¼ã‚ã¾ã›ã‚“。
-
- Poser 4ã‹ã‚‰ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆã•ã‚ŒãŸBVHファイルを推奨ã—ã¾ã™ã€‚
- </text>
- <button label="アップロードL$[AMOUNT]" name="ok_btn"/>
- <button label="å–り消ã—" name="cancel_btn"/>
-</floater>
diff --git a/indra/newview/skins/default/xui/ja/floater_auction.xml b/indra/newview/skins/default/xui/ja/floater_auction.xml
index e9aa287f2c..e9aa287f2c 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_auction.xml
+++ b/indra/newview/skins/default/xui/ja/floater_auction.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_autoreplace.xml b/indra/newview/skins/default/xui/ja/floater_autoreplace.xml
new file mode 100755
index 0000000000..21abf59160
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/floater_autoreplace.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="autoreplace_floater" title="自動置æ›è¨­å®š">
+ <check_box label="自動置æ›ã‚’有効ã«ã™ã‚‹" name="autoreplace_enable" tool_tip="ãƒãƒ£ãƒƒãƒˆãƒ†ã‚­ã‚¹ãƒˆã‚’入力ã™ã‚‹ã«ã¤ã‚Œã¦ã€å…¥åŠ›ã—ãŸã‚­ãƒ¼ãƒ¯ãƒ¼ãƒ‰ã‚’対応ã™ã‚‹ç½®æ›ã‚­ãƒ¼ãƒ¯ãƒ¼ãƒ‰ã«ç½®ãæ›ãˆã¾ã™"/>
+ <button label="リストをインãƒãƒ¼ãƒˆ..." name="autoreplace_import_list" tool_tip="以å‰ã«ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆã—ãŸãƒªã‚¹ãƒˆã‚’ファイルã‹ã‚‰ãƒ­ãƒ¼ãƒ‰ã—ã¾ã™ã€‚"/>
+ <button label="リストをエクスãƒãƒ¼ãƒˆ..." name="autoreplace_export_list" tool_tip="é¸æŠžã—ãŸãƒªã‚¹ãƒˆã‚’ファイルã«ä¿å­˜ã—ã¦ã€å…±æœ‰ã§ãるよã†ã«ã—ã¾ã™ã€‚"/>
+ <button label="æ–°è¦ãƒªã‚¹ãƒˆ..." name="autoreplace_new_list" tool_tip="æ–°è¦ãƒªã‚¹ãƒˆã‚’作æˆã—ã¾ã™ã€‚"/>
+ <button label="リストを削除" name="autoreplace_delete_list" tool_tip="é¸æŠžã—ãŸãƒªã‚¹ãƒˆã‚’削除ã—ã¾ã™ã€‚"/>
+ <button name="autoreplace_list_up" tool_tip="ã“ã®ãƒªã‚¹ãƒˆã®å„ªå…ˆåº¦ã‚’上ã’ã¾ã™ã€‚"/>
+ <button name="autoreplace_list_down" tool_tip="ã“ã®ãƒªã‚¹ãƒˆã®å„ªå…ˆåº¦ã‚’下ã’ã¾ã™ã€‚"/>
+ <scroll_list name="autoreplace_list_replacements">
+ <scroll_list.columns label="キーワード" name="keyword"/>
+ <scroll_list.columns label="ç½®æ›" name="replacement"/>
+ </scroll_list>
+ <button label="追加..." name="autoreplace_add_entry"/>
+ <button label="削除" name="autoreplace_delete_entry"/>
+ <button label="エントリをä¿å­˜" name="autoreplace_save_entry" tool_tip="ã“ã®ã‚¨ãƒ³ãƒˆãƒªã‚’ä¿å­˜ã—ã¾ã™ã€‚"/>
+ <button label="変更をä¿å­˜" name="autoreplace_save_changes" tool_tip="変更をã™ã¹ã¦ä¿å­˜ã—ã¾ã™ã€‚"/>
+ <button label="å–り消ã—" name="autoreplace_cancel" tool_tip="変更をã™ã¹ã¦ç ´æ£„ã—ã¾ã™ã€‚"/>
+</floater>
+<!--
+ <text
+ top_pad="10"
+ left="10"
+ height="16"
+ width="260"
+ follows="left|top"
+ halign="center"
+ mouse_opaque="true"
+ name="autoreplace_text2">
+ Entries
+ </text>
+-->
diff --git a/indra/newview/skins/default/xui/ja/floater_avatar.xml b/indra/newview/skins/default/xui/ja/floater_avatar.xml
index d289580506..d289580506 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_avatar.xml
+++ b/indra/newview/skins/default/xui/ja/floater_avatar.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_avatar_picker.xml b/indra/newview/skins/default/xui/ja/floater_avatar_picker.xml
index 4bd6b4e053..4bd6b4e053 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_avatar_picker.xml
+++ b/indra/newview/skins/default/xui/ja/floater_avatar_picker.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_avatar_textures.xml b/indra/newview/skins/default/xui/ja/floater_avatar_textures.xml
index 5c23b77498..5c23b77498 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_avatar_textures.xml
+++ b/indra/newview/skins/default/xui/ja/floater_avatar_textures.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_beacons.xml b/indra/newview/skins/default/xui/ja/floater_beacons.xml
index a55698e3d0..a55698e3d0 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_beacons.xml
+++ b/indra/newview/skins/default/xui/ja/floater_beacons.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_build_options.xml b/indra/newview/skins/default/xui/ja/floater_build_options.xml
index 6865409e7a..6865409e7a 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_build_options.xml
+++ b/indra/newview/skins/default/xui/ja/floater_build_options.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_bulk_perms.xml b/indra/newview/skins/default/xui/ja/floater_bulk_perms.xml
index d8d0164618..1b5a745cc4 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_bulk_perms.xml
+++ b/indra/newview/skins/default/xui/ja/floater_bulk_perms.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floaterbulkperms" title="中身ã®æ¨©é™ã®ç·¨é›†">
+<floater name="floaterbulkperms" title="コンテンツ権é™ã‚’調整">
<floater.string name="nothing_to_modify_text">
é¸æŠžã—ãŸä¸­ã«ç·¨é›†ã§ããªã„ã‚‚ã®ãŒå«ã¾ã‚Œã¦ã„ã¾ã™
</floater.string>
@@ -33,7 +33,7 @@
<button label="ã™ã¹ã¦ã« √" label_selected="å…¨ã¦" name="check_all"/>
<button label="クリア" label_selected="ãªã—" name="check_none"/>
<text name="newperms">
- æ–°ã—ã„中身ã®æ¨©é™
+ コンテンツ権é™ã‚’以下ã«èª¿æ•´
</text>
<text name="GroupLabel">
グループ:
@@ -49,6 +49,7 @@
<check_box label="修正" name="next_owner_modify"/>
<check_box label="コピー" name="next_owner_copy"/>
<check_box initial_value="true" label="å†è²©ãƒ»ãƒ—レゼント" name="next_owner_transfer" tool_tip="次ã®æ‰€æœ‰è€…ã¯ã“ã®ã‚ªãƒ–ジェクトを他人ã«ã‚ã’ãŸã‚Šå†è²©ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™"/>
- <button label="OK" name="apply"/>
+ <button label="OK" name="ok"/>
+ <button label="é©ç”¨" name="apply"/>
<button label="キャンセル" name="close"/>
</floater>
diff --git a/indra/newview/skins/default/xui/ja/floater_bumps.xml b/indra/newview/skins/default/xui/ja/floater_bumps.xml
index fd12a9e69a..fd12a9e69a 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_bumps.xml
+++ b/indra/newview/skins/default/xui/ja/floater_bumps.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_buy_contents.xml b/indra/newview/skins/default/xui/ja/floater_buy_contents.xml
index 7e4932c78f..7e4932c78f 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_buy_contents.xml
+++ b/indra/newview/skins/default/xui/ja/floater_buy_contents.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_buy_currency.xml b/indra/newview/skins/default/xui/ja/floater_buy_currency.xml
index a472f163e3..a472f163e3 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_buy_currency.xml
+++ b/indra/newview/skins/default/xui/ja/floater_buy_currency.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_buy_currency_html.xml b/indra/newview/skins/default/xui/ja/floater_buy_currency_html.xml
index 37fd6826e5..37fd6826e5 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_buy_currency_html.xml
+++ b/indra/newview/skins/default/xui/ja/floater_buy_currency_html.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_buy_land.xml b/indra/newview/skins/default/xui/ja/floater_buy_land.xml
index 34f9d38de1..34f9d38de1 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_buy_land.xml
+++ b/indra/newview/skins/default/xui/ja/floater_buy_land.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_buy_object.xml b/indra/newview/skins/default/xui/ja/floater_buy_object.xml
index ce269df6da..ce269df6da 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_buy_object.xml
+++ b/indra/newview/skins/default/xui/ja/floater_buy_object.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_camera.xml b/indra/newview/skins/default/xui/ja/floater_camera.xml
index 982e5ce42b..982e5ce42b 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_camera.xml
+++ b/indra/newview/skins/default/xui/ja/floater_camera.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_chat_bar.xml b/indra/newview/skins/default/xui/ja/floater_chat_bar.xml
index 11f223ade6..9f5df6fb85 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_chat_bar.xml
+++ b/indra/newview/skins/default/xui/ja/floater_chat_bar.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="chat_bar" title="è¿‘ãã®ãƒãƒ£ãƒƒãƒˆ">
+<floater name="nearby_chat" title="è¿‘ãã®ãƒãƒ£ãƒƒãƒˆ">
<panel name="bottom_panel">
<line_editor label="ã“ã“をクリックã—ã¦ãƒãƒ£ãƒƒãƒˆã‚’開始ã—ã¾ã™ã€‚" name="chat_box" tool_tip="Enter キーを押ã—ã¦è©±ã—ã€Ctrl + Enter キーã§å«ã³ã¾ã™ã€‚"/>
<button name="show_nearby_chat" tool_tip="è¿‘ãã®ãƒãƒ£ãƒƒãƒˆãƒ­ã‚°ã‚’表示ï¼éžè¡¨ç¤º"/>
diff --git a/indra/newview/skins/default/xui/ja/floater_choose_group.xml b/indra/newview/skins/default/xui/ja/floater_choose_group.xml
index 7d91cb69ed..7d91cb69ed 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_choose_group.xml
+++ b/indra/newview/skins/default/xui/ja/floater_choose_group.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_color_picker.xml b/indra/newview/skins/default/xui/ja/floater_color_picker.xml
index dc87d27a15..dc87d27a15 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_color_picker.xml
+++ b/indra/newview/skins/default/xui/ja/floater_color_picker.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_conversation_log.xml b/indra/newview/skins/default/xui/ja/floater_conversation_log.xml
new file mode 100644
index 0000000000..98b1a59a0d
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/floater_conversation_log.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="floater_conversation_log" title="会話ログ">
+ <panel name="buttons_panel">
+ <filter_editor label="人をフィルター" name="people_filter_input"/>
+ <menu_button name="conversation_view_btn" tool_tip="表示 / 並ã¹æ›¿ãˆã®ã‚ªãƒ—ション"/>
+ <menu_button name="conversations_gear_btn" tool_tip="é¸æŠžã—ãŸä½äººãƒ»ã‚°ãƒ«ãƒ¼ãƒ—ã«å¯¾ã™ã‚‹ã‚¢ã‚¯ã‚·ãƒ§ãƒ³"/>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/ja/floater_conversation_preview.xml b/indra/newview/skins/default/xui/ja/floater_conversation_preview.xml
new file mode 100644
index 0000000000..ea0b23de48
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/floater_conversation_preview.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="preview_conversation" title="会話:">
+ <floater.string name="Title">
+ 会話:[NAME]
+ </floater.string>
+ <text name="page_label" value="ページ"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/ja/floater_critical.xml b/indra/newview/skins/default/xui/ja/floater_critical.xml
index f69c24622a..f69c24622a 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_critical.xml
+++ b/indra/newview/skins/default/xui/ja/floater_critical.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_delete_env_preset.xml b/indra/newview/skins/default/xui/ja/floater_delete_env_preset.xml
index eb39d1b336..eb39d1b336 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_delete_env_preset.xml
+++ b/indra/newview/skins/default/xui/ja/floater_delete_env_preset.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_destinations.xml b/indra/newview/skins/default/xui/ja/floater_destinations.xml
index b7f6ad4d4e..b7f6ad4d4e 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_destinations.xml
+++ b/indra/newview/skins/default/xui/ja/floater_destinations.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_display_name.xml b/indra/newview/skins/default/xui/ja/floater_display_name.xml
index cc71b1cd9f..cc71b1cd9f 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_display_name.xml
+++ b/indra/newview/skins/default/xui/ja/floater_display_name.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_edit_day_cycle.xml b/indra/newview/skins/default/xui/ja/floater_edit_day_cycle.xml
index fd601672b6..fd601672b6 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_edit_day_cycle.xml
+++ b/indra/newview/skins/default/xui/ja/floater_edit_day_cycle.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_edit_sky_preset.xml b/indra/newview/skins/default/xui/ja/floater_edit_sky_preset.xml
index 68d0c70baa..68d0c70baa 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_edit_sky_preset.xml
+++ b/indra/newview/skins/default/xui/ja/floater_edit_sky_preset.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_edit_water_preset.xml b/indra/newview/skins/default/xui/ja/floater_edit_water_preset.xml
index eddfbd4298..eddfbd4298 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_edit_water_preset.xml
+++ b/indra/newview/skins/default/xui/ja/floater_edit_water_preset.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_environment_settings.xml b/indra/newview/skins/default/xui/ja/floater_environment_settings.xml
index 0e3803119f..0e3803119f 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_environment_settings.xml
+++ b/indra/newview/skins/default/xui/ja/floater_environment_settings.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_event.xml b/indra/newview/skins/default/xui/ja/floater_event.xml
index ca50ba8ef8..ca50ba8ef8 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_event.xml
+++ b/indra/newview/skins/default/xui/ja/floater_event.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_fast_timers.xml b/indra/newview/skins/default/xui/ja/floater_fast_timers.xml
index 5f538ecdb0..5f538ecdb0 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_fast_timers.xml
+++ b/indra/newview/skins/default/xui/ja/floater_fast_timers.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_font_test.xml b/indra/newview/skins/default/xui/ja/floater_font_test.xml
index b853f395dd..b853f395dd 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_font_test.xml
+++ b/indra/newview/skins/default/xui/ja/floater_font_test.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_gesture.xml b/indra/newview/skins/default/xui/ja/floater_gesture.xml
index 1ed5ad31db..1ed5ad31db 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_gesture.xml
+++ b/indra/newview/skins/default/xui/ja/floater_gesture.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_god_tools.xml b/indra/newview/skins/default/xui/ja/floater_god_tools.xml
index 9e5d473db7..9e5d473db7 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_god_tools.xml
+++ b/indra/newview/skins/default/xui/ja/floater_god_tools.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_goto_line.xml b/indra/newview/skins/default/xui/ja/floater_goto_line.xml
new file mode 100644
index 0000000000..5f2717ace5
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/floater_goto_line.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="script goto" title="è¡Œã«ç§»å‹•">
+ <button label="OK" label_selected="OK" name="goto_btn"/>
+ <text name="txt">
+ è¡Œã«ç§»å‹•
+ </text>
+</floater>
diff --git a/indra/newview/skins/default/xui/ja/floater_hardware_settings.xml b/indra/newview/skins/default/xui/ja/floater_hardware_settings.xml
index 1b6558a9eb..c8b8e918e0 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_hardware_settings.xml
+++ b/indra/newview/skins/default/xui/ja/floater_hardware_settings.xml
@@ -25,6 +25,10 @@
VBO を有効化:
</text>
<check_box initial_value="true" label="OpenGL Vertex Buffer Objectsを有効化" name="vbo" tool_tip="最新ã®ãƒãƒ¼ãƒ‰ã‚¦ã‚§ã‚¢ã§ã“ã®è¨­å®šã‚’有効ã«ã™ã‚‹ã¨ã€ãƒ‘フォーマンスãŒå‘上ã—ã¾ã™ã€‚ ã—ã‹ã—ã€æ—§åž‹ã®ãƒãƒ¼ãƒ‰ã‚¦ã‚§ã‚¢ã§ã¯ VBO ã®å®Ÿè£…ãŒè²§å¼±ãªå ´åˆãŒå¤šãã€ã“ã®è¨­å®šã‚’有効ã«ã™ã‚‹ã“ã¨ã§ã‚¯ãƒ©ãƒƒã‚·ãƒ¥ã«ã¤ãªãŒã‚‹ãŠãã‚ŒãŒã‚ã‚Šã¾ã™ã€‚"/>
+ <text name="tc label">
+ S3TC を有効ã«ã™ã‚‹ï¼š
+ </text>
+ <check_box initial_value="true" label="テクスãƒãƒ£åœ§ç¸®ã‚’有効ã«ã™ã‚‹ï¼ˆå†èµ·å‹•ãŒå¿…è¦ï¼‰" name="texture compression" tool_tip="ビデオメモリ内ã§ãƒ†ã‚¯ã‚¹ãƒãƒ£ã‚’圧縮ã™ã‚‹ã“ã¨ã«ã‚ˆã‚Šã€è‰²ã®è³ªã‚’多少犠牲ã«ã—ãªãŒã‚‰ã€ã‚ˆã‚Šé«˜è§£åƒåº¦ã®ãƒ†ã‚¯ã‚¹ãƒãƒ£ã‚’読ã¿è¾¼ã‚るよã†ã«ã—ã¾ã™ã€‚"/>
<slider label="テクスãƒãƒ£ãƒ¡ãƒ¢ãƒªï¼ˆMB):" name="GraphicsCardTextureMemory" tool_tip="テクスãƒãƒ£ã«å‰²ã‚Šå½“ã¦ã‚‰ã‚ŒãŸãƒ¡ãƒ¢ãƒªã®é‡ã€‚ ビデオカードã®ãƒ¡ãƒ¢ãƒªã«æ—¢å®šã€‚ 数値を下ã’ã‚‹ã¨ãƒ‘フォーマンスãŒå‘上ã—ã¾ã™ãŒã€ãƒ†ã‚¯ã‚¹ãƒãƒ£ã®ç²¾åº¦ãŒè½ã¡ã‚‹ã“ã¨ãŒã‚ã‚Šã¾ã™ã€‚"/>
<spinner label="フォグã®è·é›¢æ¯”率:" name="fog"/>
<button label="OK" label_selected="OK" name="OK"/>
diff --git a/indra/newview/skins/default/xui/ja/floater_help_browser.xml b/indra/newview/skins/default/xui/ja/floater_help_browser.xml
index 15200d7ef7..15200d7ef7 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_help_browser.xml
+++ b/indra/newview/skins/default/xui/ja/floater_help_browser.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_how_to.xml b/indra/newview/skins/default/xui/ja/floater_how_to.xml
index 4cebe27226..4cebe27226 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_how_to.xml
+++ b/indra/newview/skins/default/xui/ja/floater_how_to.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_hud.xml b/indra/newview/skins/default/xui/ja/floater_hud.xml
index e3841c2cd9..e3841c2cd9 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_hud.xml
+++ b/indra/newview/skins/default/xui/ja/floater_hud.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_im_container.xml b/indra/newview/skins/default/xui/ja/floater_im_container.xml
index 06b65e27f0..a155efdc1e 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_im_container.xml
+++ b/indra/newview/skins/default/xui/ja/floater_im_container.xml
@@ -1,2 +1,29 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<multi_floater name="floater_im_box" title="会話"/>
+<multi_floater name="floater_im_box" title="会話">
+ <string name="collapse_icon" value="Conv_toolbar_collapse"/>
+ <string name="expand_icon" value="Conv_toolbar_expand"/>
+ <layout_stack name="conversations_stack">
+ <layout_panel name="conversations_layout_panel">
+ <layout_stack name="conversations_pane_buttons_stack">
+ <layout_panel name="conversations_pane_buttons_expanded">
+ <menu_button name="sort_btn" tool_tip="オプションã®è¡¨ç¤º / 並ã¹æ›¿ãˆ"/>
+ <button name="add_btn" tool_tip="æ–°ã—ã„会話を開始"/>
+ <button name="speak_btn" tool_tip="マイクを使ã£ã¦äººã¨è©±ã™"/>
+ </layout_panel>
+ <layout_panel name="conversations_pane_buttons_collapsed">
+ <button name="expand_collapse_btn" tool_tip="ã“ã®ãƒªã‚¹ãƒˆã‚’é–‰ã˜ã‚‹ / é–‹ã"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ <layout_panel name="messages_layout_panel">
+ <panel_container name="im_box_tab_container">
+ <panel name="stub_panel">
+ <button name="stub_collapse_btn" tool_tip="ã“ã®ãƒšã‚¤ãƒ³ã‚’é–‰ã˜ã‚‹"/>
+ <text name="stub_textbox">
+ ã“ã®ä¼šè©±ã¯ã€åˆ¥ã®ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã«è¡¨ç¤ºã•ã‚Œã¾ã™ã€‚[secondlife:/// 戻る.]
+ </text>
+ </panel>
+ </panel_container>
+ </layout_panel>
+ </layout_stack>
+</multi_floater>
diff --git a/indra/newview/skins/default/xui/ja/floater_im_session.xml b/indra/newview/skins/default/xui/ja/floater_im_session.xml
index dfa1c85ca2..7ed46f7f01 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/ja/floater_im_session.xml
@@ -1,8 +1,57 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="panel_im">
- <layout_stack name="im_panels">
- <layout_panel>
- <line_editor label="宛先" name="chat_editor"/>
- </layout_panel>
- </layout_stack>
+ <floater.string name="call_btn_start">
+ Conv_toolbar_open_call
+ </floater.string>
+ <floater.string name="call_btn_stop">
+ Conv_toolbar_hang_up
+ </floater.string>
+ <floater.string name="collapseline_icon" value="Conv_collapse_to_one_line"/>
+ <floater.string name="expandline_icon" value="Conv_expand_one_line"/>
+ <floater.string name="collapse_icon" value="Conv_toolbar_collapse"/>
+ <floater.string name="expand_icon" value="Conv_toolbar_expand"/>
+ <floater.string name="tear_off_icon" value="Conv_toolbar_arrow_ne"/>
+ <floater.string name="return_icon" value="Conv_toolbar_arrow_sw"/>
+ <floater.string name="participant_added" value="[NAME] ã¯ä¼šè©±ã«æ‹›å¾…ã•ã‚Œã¾ã—ãŸã€‚"/>
+ <floater.string name="multiple_participants_added" value="[NAME] ã¯ä¼šè©±ã«æ‹›å¾…ã•ã‚Œã¾ã—ãŸã€‚"/>
+ <floater.string name="tooltip_to_separate_window" value="ã“ã®ä¼šè©±ã‚’別ã®ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã¸ç§»å‹•ã™ã‚‹"/>
+ <floater.string name="tooltip_to_main_window" value="ã“ã®ä¼šè©±ã‚’メインウィンドウã¸æˆ»ã™"/>
+ <floater.string name="start_call_button_tooltip" value="会話ã®æŽ¥ç¶šã‚’é–‹ã"/>
+ <floater.string name="end_call_button_tooltip" value="会話ã®æŽ¥ç¶šã‚’é–‰ã˜ã‚‹"/>
+ <floater.string name="expcol_button_not_tearoff_tooltip" value="ã“ã®ãƒšã‚¤ãƒ³ã‚’é–‰ã˜ã‚‹"/>
+ <floater.string name="expcol_button_tearoff_and_expanded_tooltip" value="å‚加者リストを閉ã˜ã‚‹"/>
+ <floater.string name="expcol_button_tearoff_and_collapsed_tooltip" value="å‚加者リストを開ã"/>
+ <view name="contents_view">
+ <layout_stack name="main_stack">
+ <layout_panel name="toolbar_panel">
+ <menu_button name="view_options_btn" tool_tip="表示 / 並ã¹æ›¿ãˆã®ã‚ªãƒ—ション"/>
+ <menu_button name="gear_btn" tool_tip="é¸æŠžã—ãŸäººã«å¯¾ã™ã‚‹ã‚¢ã‚¯ã‚·ãƒ§ãƒ³"/>
+ <button name="add_btn" tool_tip="ã“ã®ä¼šè©±ã«ä»–ã®äººã‚’追加ã™ã‚‹"/>
+ <button name="voice_call_btn" tool_tip="会話ã®æŽ¥ç¶šã‚’é–‹ã"/>
+ <button name="close_btn" tool_tip="ã“ã®ä¼šè©±ã‚’終了ã™ã‚‹"/>
+ <button name="expand_collapse_btn" tool_tip="ã“ã®ãƒšã‚¤ãƒ³ã‚’é–‰ã˜ã‚‹ / é–‹ã"/>
+ </layout_panel>
+ <layout_panel name="body_panel">
+ <layout_stack name="im_panels">
+ <layout_panel name="right_part_holder">
+ <layout_stack name="translate_and_chat_stack">
+ <layout_panel name="translate_chat_checkbox_lp">
+ <check_box label="ãƒãƒ£ãƒƒãƒˆã‚’翻訳" name="translate_chat_checkbox"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ <layout_panel name="chat_layout_panel">
+ <layout_stack name="input_panels">
+ <layout_panel name="input_editor_layout_panel">
+ <chat_editor label="宛先" name="chat_editor"/>
+ </layout_panel>
+ <layout_panel name="input_button_layout_panel">
+ <button name="minz_btn" tool_tip="メッセージパãƒãƒ«ã®è¡¨ç¤º / éžè¡¨ç¤º"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
+ </view>
</floater>
diff --git a/indra/newview/skins/default/xui/ja/floater_image_preview.xml b/indra/newview/skins/default/xui/ja/floater_image_preview.xml
index 1ffc27fd70..1ffc27fd70 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_image_preview.xml
+++ b/indra/newview/skins/default/xui/ja/floater_image_preview.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_import_collada.xml b/indra/newview/skins/default/xui/ja/floater_import_collada.xml
index 65edafb169..65edafb169 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_import_collada.xml
+++ b/indra/newview/skins/default/xui/ja/floater_import_collada.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_incoming_call.xml b/indra/newview/skins/default/xui/ja/floater_incoming_call.xml
index f152fcd738..308f6f9a3d 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_incoming_call.xml
+++ b/indra/newview/skins/default/xui/ja/floater_incoming_call.xml
@@ -10,7 +10,7 @@
匿åユーザー
</floater.string>
<floater.string name="VoiceInviteP2P">
- ãŒã‚³ãƒ¼ãƒ«ã—ã¦ã„ã¾ã™ã€‚
+ ã‹ã‚‰ã‚³ãƒ¼ãƒ«ã‚’å—ã‘ã¦ã„ã¾ã™ã€‚
</floater.string>
<floater.string name="VoiceInviteAdHoc">
ãŒã‚³ãƒ³ãƒ•ã‚¡ãƒ¬ãƒ³ã‚¹ãƒãƒ£ãƒƒãƒˆã§ã€ãƒœã‚¤ã‚¹ãƒãƒ£ãƒƒãƒˆã«å‚加ã—ã¾ã—ãŸã€‚
@@ -25,9 +25,9 @@
[CURRENT_CHAT]を退席ã—ã¦ã€ã“ã®ãƒœã‚¤ã‚¹ãƒãƒ£ãƒƒãƒˆã«å‚加ã—ã¾ã™ã‹ï¼Ÿ
</floater.string>
<text name="question">
- [CURRENT_CHAT] を退席ã—ã¦ã€ã“ã®ãƒœã‚¤ã‚¹ãƒãƒ£ãƒƒãƒˆã«å‚加ã—ã¾ã™ã‹ï¼Ÿ
+ コールã«å¿œç­”ã™ã‚‹ã¨ã€ç¾åœ¨ã®ãƒœã‚¤ã‚¹ãƒãƒ£ãƒƒãƒˆã‹ã‚‰åˆ‡æ–­ã•ã‚Œã¾ã™ã€‚
</text>
- <button label="ã¯ã„" label_selected="ã¯ã„" name="Accept"/>
- <button label="ã„ã„ãˆ" label_selected="ã„ã„ãˆ" name="Reject"/>
- <button label="IM" name="Start IM"/>
+ <button label="å–ã‚‹" label_selected="å–ã‚‹" name="Accept"/>
+ <button label="無視" label_selected="無視" name="Reject"/>
+ <button label="代ã‚ã‚Šã« IM ã‚’é–‹ã" name="Start IM"/>
</floater>
diff --git a/indra/newview/skins/default/xui/ja/floater_inspect.xml b/indra/newview/skins/default/xui/ja/floater_inspect.xml
index b3825c0b7f..b3825c0b7f 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_inspect.xml
+++ b/indra/newview/skins/default/xui/ja/floater_inspect.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_inventory.xml b/indra/newview/skins/default/xui/ja/floater_inventory.xml
deleted file mode 100644
index b113fde94a..0000000000
--- a/indra/newview/skins/default/xui/ja/floater_inventory.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Inventory" title="æŒã¡ç‰©">
- <floater.string name="Title">
- æŒã¡ç‰©
- </floater.string>
- <floater.string name="TitleFetching">
- æŒã¡ç‰© ( [ITEM_COUNT] アイテムをå–得中...) [FILTER]
- </floater.string>
- <floater.string name="TitleCompleted">
- æŒã¡ç‰© ( [ITEM_COUNT] アイテム) [FILTER]
- </floater.string>
- <floater.string name="Fetched">
- å–得済
- </floater.string>
- <panel label="æŒã¡ç‰©ãƒ‘ãƒãƒ«" name="Inventory Panel"/>
-</floater>
diff --git a/indra/newview/skins/default/xui/ja/floater_inventory_item_properties.xml b/indra/newview/skins/default/xui/ja/floater_inventory_item_properties.xml
index c01c46211e..c01c46211e 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_inventory_item_properties.xml
+++ b/indra/newview/skins/default/xui/ja/floater_inventory_item_properties.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_inventory_view_finder.xml b/indra/newview/skins/default/xui/ja/floater_inventory_view_finder.xml
index af96edda79..af96edda79 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_inventory_view_finder.xml
+++ b/indra/newview/skins/default/xui/ja/floater_inventory_view_finder.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_joystick.xml b/indra/newview/skins/default/xui/ja/floater_joystick.xml
index daa480ef5a..daa480ef5a 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_joystick.xml
+++ b/indra/newview/skins/default/xui/ja/floater_joystick.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_lagmeter.xml b/indra/newview/skins/default/xui/ja/floater_lagmeter.xml
index e3546cd837..e3546cd837 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_lagmeter.xml
+++ b/indra/newview/skins/default/xui/ja/floater_lagmeter.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_land_holdings.xml b/indra/newview/skins/default/xui/ja/floater_land_holdings.xml
index aca916f22f..aca916f22f 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_land_holdings.xml
+++ b/indra/newview/skins/default/xui/ja/floater_land_holdings.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_live_lsleditor.xml b/indra/newview/skins/default/xui/ja/floater_live_lsleditor.xml
index 5a155c9f12..5a155c9f12 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_live_lsleditor.xml
+++ b/indra/newview/skins/default/xui/ja/floater_live_lsleditor.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_lsl_guide.xml b/indra/newview/skins/default/xui/ja/floater_lsl_guide.xml
index 5773752788..5773752788 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_lsl_guide.xml
+++ b/indra/newview/skins/default/xui/ja/floater_lsl_guide.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_map.xml b/indra/newview/skins/default/xui/ja/floater_map.xml
index 1122203446..1122203446 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_map.xml
+++ b/indra/newview/skins/default/xui/ja/floater_map.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_media_browser.xml b/indra/newview/skins/default/xui/ja/floater_media_browser.xml
index c4731b73a3..c4731b73a3 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_media_browser.xml
+++ b/indra/newview/skins/default/xui/ja/floater_media_browser.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_media_settings.xml b/indra/newview/skins/default/xui/ja/floater_media_settings.xml
index 46ac1a8dfd..46ac1a8dfd 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_media_settings.xml
+++ b/indra/newview/skins/default/xui/ja/floater_media_settings.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_mem_leaking.xml b/indra/newview/skins/default/xui/ja/floater_mem_leaking.xml
index f48bb94e32..f48bb94e32 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_mem_leaking.xml
+++ b/indra/newview/skins/default/xui/ja/floater_mem_leaking.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_merchant_outbox.xml b/indra/newview/skins/default/xui/ja/floater_merchant_outbox.xml
index c59a3dc0ab..c59a3dc0ab 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_merchant_outbox.xml
+++ b/indra/newview/skins/default/xui/ja/floater_merchant_outbox.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_model_preview.xml b/indra/newview/skins/default/xui/ja/floater_model_preview.xml
index c9ff0e29cb..942cc91317 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_model_preview.xml
+++ b/indra/newview/skins/default/xui/ja/floater_model_preview.xml
@@ -92,19 +92,54 @@
<text initial_value="三角形" name="triangles" value="三角形"/>
<text initial_value="頂点" name="vertices" value="頂点"/>
<text initial_value="高" name="high_label" value="高"/>
+ <combo_box name="lod_source_high">
+ <item name="Load from file" value="ファイルã‹ã‚‰ãƒ­ãƒ¼ãƒ‰"/>
+ <item name="Generate" value="生æˆ"/>
+ </combo_box>
<button label="å‚ç…§" name="lod_browse_high"/>
+ <combo_box name="lod_mode_high">
+ <item name="Triangle Limit" value="三角形ã®é™åº¦æ•°"/>
+ <item name="Error Threshold" value="エラーã—ãã„値"/>
+ </combo_box>
<text initial_value="0" name="high_triangles" value="0"/>
<text initial_value="0" name="high_vertices" value="0"/>
<text initial_value="中" name="medium_label" value="中"/>
+ <combo_box name="lod_source_medium">
+ <item name="Load from file" value="ファイルã‹ã‚‰ãƒ­ãƒ¼ãƒ‰"/>
+ <item name="Generate" value="生æˆ"/>
+ <item name="Use LoD above" value="上記㮠LoD を使用"/>
+ </combo_box>
<button label="å‚ç…§" name="lod_browse_medium"/>
+ <combo_box name="lod_mode_medium">
+ <item name="Triangle Limit" value="三角形ã®é™åº¦æ•°"/>
+ <item name="Error Threshold" value="エラーã—ãã„値"/>
+ </combo_box>
<text initial_value="0" name="medium_triangles" value="0"/>
<text initial_value="0" name="medium_vertices" value="0"/>
<text initial_value="低" name="low_label" value="低"/>
+ <combo_box name="lod_source_low">
+ <item name="Load from file" value="ファイルã‹ã‚‰ãƒ­ãƒ¼ãƒ‰"/>
+ <item name="Generate" value="生æˆ"/>
+ <item name="Use LoD above" value="上記㮠LoD を使用"/>
+ </combo_box>
<button label="å‚ç…§" name="lod_browse_low"/>
+ <combo_box name="lod_mode_low">
+ <item name="Triangle Limit" value="三角形ã®é™åº¦æ•°"/>
+ <item name="Error Threshold" value="エラーã—ãã„値"/>
+ </combo_box>
<text initial_value="0" name="low_triangles" value="0"/>
<text initial_value="0" name="low_vertices" value="0"/>
<text initial_value="最低" name="lowest_label" value="最低"/>
+ <combo_box name="lod_source_lowest">
+ <item name="Load from file" value="ファイルã‹ã‚‰ãƒ­ãƒ¼ãƒ‰"/>
+ <item name="Generate" value="生æˆ"/>
+ <item name="Use LoD above" value="上記㮠LoD を使用"/>
+ </combo_box>
<button label="å‚ç…§" name="lod_browse_lowest"/>
+ <combo_box name="lod_mode_lowest">
+ <item name="Triangle Limit" value="三角形ã®é™åº¦æ•°"/>
+ <item name="Error Threshold" value="エラーã—ãã„値"/>
+ </combo_box>
<text initial_value="0" name="lowest_triangles" value="0"/>
<text initial_value="0" name="lowest_vertices" value="0"/>
<check_box label="ノーマルã®ä½œæˆ" name="gen_normals"/>
diff --git a/indra/newview/skins/default/xui/ja/floater_model_wizard.xml b/indra/newview/skins/default/xui/ja/floater_model_wizard.xml
deleted file mode 100644
index 746bd8553c..0000000000
--- a/indra/newview/skins/default/xui/ja/floater_model_wizard.xml
+++ /dev/null
@@ -1,208 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Model Wizard" title="モデルウィザードをアップロード">
- <button label="5. アップロード" name="upload_btn"/>
- <button label="4. 確èª" name="review_btn"/>
- <button label="3. 物ç†åŠ¹æžœ" name="physics_btn"/>
- <button label="2. 最é©åŒ–" name="optimize_btn"/>
- <button label="1. ファイルをé¸æŠž" name="choose_file_btn"/>
- <panel name="choose_file_panel">
- <panel name="choose_file_header_panel">
- <text name="choose_file_header_text">
- モデルファイルをé¸æŠž
- </text>
- </panel>
- <panel name="choose_file_content">
- <text name="advanced_users_text">
- 上級ユーザーã®å ´åˆï¼š3D コンテンツ制作ツールã®ä½¿ç”¨ã«æ…£ã‚Œã¦ã„ã‚‹æ–¹ã¯ã€é«˜åº¦ãªã‚¢ãƒƒãƒ—ローダーもãŠè©¦ã—ãã ã•ã„。
- </text>
- <button label="アドãƒãƒ³ã‚¹ãƒ¢ãƒ¼ãƒ‰ã«åˆ‡ã‚Šæ›¿ãˆã‚‹" name="switch_to_advanced"/>
- <text name="Cache location">
- アップロードã™ã‚‹ãƒ¢ãƒ‡ãƒ«ãƒ•ã‚¡ã‚¤ãƒ«ã‚’é¸æŠž
- </text>
- <button label="å‚ç…§..." label_selected="å‚ç…§..." name="browse"/>
- <text name="Model types">
- Second Life 㯠COLLADA (.dae) ファイルをサãƒãƒ¼ãƒˆã—ã¾ã™ã€‚
- </text>
- <text name="dimensions">
- X Y Z
- </text>
- <text name="warning_label">
- 警告:
- </text>
- <text name="warning_text">
- ã“ã®ãƒ¢ãƒ‡ãƒ«ã‚’ Second Life サーãƒãƒ¼ã«ã‚¢ãƒƒãƒ—ロードã™ã‚‹ãŸã‚ã®æœ€çµ‚手順を実行ã§ãã¾ã›ã‚“。[secondlife:///app/floater/learn_more ã“ã¡ã‚‰ã‚’å‚ç…§ã—ã¦]ã€ãƒ¡ãƒƒã‚·ãƒ¥ãƒ¢ãƒ‡ãƒ«ã‚’アップロードã§ãるよã†ã«ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã‚’設定ã—ã¦ãã ã•ã„。
- </text>
- </panel>
- </panel>
- <panel name="optimize_panel">
- <panel name="optimize_header_panel">
- <text name="optimize_header_text">
- モデルを最é©åŒ–
- </text>
- </panel>
- <text name="optimize_description">
- モデルã¯ãƒ‘フォーマンスをé‡è¦–ã—ã¦æœ€é©åŒ–ã•ã‚Œã¦ã„ã¾ã™ã€‚å¿…è¦ã«å¿œã˜ã¦èª¿æ•´ã—ã¦ãã ã•ã„。
- </text>
- <panel name="optimize_content">
- <text name="high_detail_text">
- 次ã®æ画詳細度を作æˆï¼šé«˜
- </text>
- <text name="medium_detail_text">
- 次ã®æ画詳細度を作æˆï¼šä¸­
- </text>
- <text name="low_detail_text">
- 次ã®æ画詳細度を作æˆï¼šä½Ž
- </text>
- <text name="lowest_detail_text">
- 次ã®æ画詳細度を作æˆï¼šæœ€ä½Ž
- </text>
- </panel>
- <panel name="content2">
- <button label="ジオメトリをå†è¨ˆç®—" name="recalculate_geometry_btn"/>
- <text name="lod_label">
- ジオメトリã®ãƒ—レビュー
- </text>
- <combo_box name="preview_lod_combo" tool_tip="プレビュー表示㮠LOD 設定">
- <combo_item name="high">
- 高ã„詳細度
- </combo_item>
- <combo_item name="medium">
- 中ã®è©³ç´°åº¦
- </combo_item>
- <combo_item name="low">
- 低ã„詳細度
- </combo_item>
- <combo_item name="lowest">
- 最低ã®è©³ç´°åº¦
- </combo_item>
- </combo_box>
- </panel>
- </panel>
- <panel name="physics_panel">
- <panel name="physics_header_panel">
- <text name="physics_header_text">
- 物ç†ä½œç”¨ã®èª¿æ•´
- </text>
- </panel>
- <text name="physics_description">
- モデルã®å¤–殻構造ã®ã‚·ã‚§ã‚¤ãƒ—ã¯å¼Šç¤¾ãŒä½œæˆã—ã¾ã™ã€‚モデルã®ç›®çš„ã«å¿œã˜ã¦ã‚·ã‚§ã‚¤ãƒ—ã®è©³ç´°åº¦ã‚’調整ã—ã¦ãã ã•ã„。
- </text>
- <panel name="physics_content">
- <button label="物ç†ä½œç”¨ã‚’å†è¨ˆç®—" name="recalculate_physics_btn"/>
- <button label="å†è¨ˆç®—中..." name="recalculating_physics_btn"/>
- <text name="lod_label">
- 物ç†ä½œç”¨ã®ãƒ—レビュー
- </text>
- <combo_box name="preview_lod_combo2" tool_tip="プレビュー表示㮠LOD 設定">
- <combo_item name="high">
- 高ã„詳細度
- </combo_item>
- <combo_item name="medium">
- 中ã®è©³ç´°åº¦
- </combo_item>
- <combo_item name="low">
- 低ã„詳細度
- </combo_item>
- <combo_item name="lowest">
- 最低ã®è©³ç´°åº¦
- </combo_item>
- </combo_box>
- </panel>
- </panel>
- <panel name="review_panel">
- <panel name="review_header_panel">
- <text name="review_header_text">
- 確èª
- </text>
- </panel>
- <panel name="review_content">
- <text name="review_prim_equiv">
- 区画/リージョンã¸ã®è² è·ï¼š[EQUIV] プリムæ›ç®—値
- </text>
- <text name="review_fee">
- L$ [FEE] ã®ã‚¢ãƒƒãƒ—ロード料金ãŒã‚ãªãŸã®ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã«è«‹æ±‚ã•ã‚Œã¾ã™ã€‚
- </text>
- <text name="review_confirmation">
- アップロードボタンをクリックã™ã‚‹ã“ã¨ã«ã‚ˆã‚Šã€ãƒ¢ãƒ‡ãƒ«ã«å«ã¾ã‚Œã‚‹ãƒžãƒ†ãƒªã‚¢ãƒ«ã®æ‰€æœ‰æ¨©ã‚„使用許å¯ã®æ‰€æŒã‚’èªã‚ãŸã“ã¨ã«ãªã‚Šã¾ã™ã€‚
- </text>
- </panel>
- </panel>
- <panel name="upload_panel">
- <panel name="upload_header_panel">
- <text name="upload_header_text">
- アップロード完了
- </text>
- </panel>
- <text name="model_uploaded_text">
- モデルãŒã‚¢ãƒƒãƒ—ロードã•ã‚Œã¾ã—ãŸã€‚
- </text>
- <text name="inventory_text">
- ãã‚Œã¯ã‚¤ãƒ³ãƒ™ãƒ³ãƒˆãƒªã®ã€Œã‚ªãƒ–ジェクトã€ãƒ•ã‚©ãƒ«ãƒ€ã«ã‚ã‚Šã¾ã™ã€‚
- </text>
- <text name="charged_fee">
- ã‚ãªãŸã®ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã« L$ [FEE] ãŒè«‹æ±‚ã•ã‚Œã¾ã—ãŸã€‚
- </text>
- </panel>
- <button label="&lt;&lt; 戻る" name="back"/>
- <button label="次ã¸&gt;&gt;" name="next"/>
- <button label="ウェイトã¨æ–™é‡‘ã®è¨ˆç®— &gt;&gt;" name="calculate"/>
- <button label="計算中..." name="calculating"/>
- <button label="アップロード" name="upload" tool_tip="シミュレーターã«ã‚¢ãƒƒãƒ—ロード"/>
- <button label="å–り消ã—" name="cancel"/>
- <button label="é–‰ã˜ã‚‹" name="close"/>
- <spinner name="import_scale" value="1.0"/>
- <string name="status_idle">
- 待機状態
- </string>
- <string name="status_parse_error">
- Dae ã«å•é¡ŒãŒè¦‹ã¤ã‹ã‚Šã¾ã—㟠- 詳細ã«ã¤ã„ã¦ã¯ãƒ­ã‚°ã‚’ã”å‚ç…§ãã ã•ã„。
- </string>
- <string name="status_reading_file">
- ローディング...
- </string>
- <string name="status_generating_meshes">
- メッシュを作æˆä¸­
- </string>
- <string name="status_vertex_number_overflow">
- エラー:頂点ã®æ•°ãŒ65534を超éŽã—ãŸã®ã§ä¸­æ­¢ã•ã‚Œã¾ã—ãŸã€‚
- </string>
- <string name="bad_element">
- エラー:è¦ç´ ãŒç„¡åŠ¹ã§ã™
- </string>
- <string name="high">
- 高
- </string>
- <string name="medium">
- 中
- </string>
- <string name="low">
- 低
- </string>
- <string name="lowest">
- 最低
- </string>
- <string name="mesh_status_good">
- 発é€
- </string>
- <string name="mesh_status_na">
- 該当ãªã—
- </string>
- <string name="mesh_status_none">
- ãªã—
- </string>
- <string name="mesh_status_submesh_mismatch">
- テクスãƒãƒ£ç·¨é›†å¯èƒ½ãªé¢ã®æ•°ã¯æ画詳細度ã«å¿œã˜ã¦ç•°ãªã‚Šã¾ã™ã€‚
- </string>
- <string name="mesh_status_mesh_mismatch">
- メッシュインスタンスã®æ•°ã¯æ画詳細度ã«å¿œã˜ã¦ç•°ãªã‚Šã¾ã™ã€‚
- </string>
- <string name="mesh_status_too_many_vertices">
- æ画詳細度ã«å¯¾ã—ã¦é ‚点ã®æ•°ãŒå¤šã™ãŽã¾ã™ã€‚
- </string>
- <string name="mesh_status_missing_lod">
- å¿…è¦ãªæ画詳細度ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“。
- </string>
- <string name="layer_all">
- å…¨ã¦
- </string>
-</floater>
diff --git a/indra/newview/skins/default/xui/ja/floater_moveview.xml b/indra/newview/skins/default/xui/ja/floater_moveview.xml
index aed3b78a14..aed3b78a14 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_moveview.xml
+++ b/indra/newview/skins/default/xui/ja/floater_moveview.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_mute_object.xml b/indra/newview/skins/default/xui/ja/floater_mute_object.xml
index 04ffd5254d..04ffd5254d 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_mute_object.xml
+++ b/indra/newview/skins/default/xui/ja/floater_mute_object.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_my_appearance.xml b/indra/newview/skins/default/xui/ja/floater_my_appearance.xml
index c9a0ecefd7..c9a0ecefd7 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_my_appearance.xml
+++ b/indra/newview/skins/default/xui/ja/floater_my_appearance.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_my_inventory.xml b/indra/newview/skins/default/xui/ja/floater_my_inventory.xml
index d708fc3dec..d708fc3dec 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_my_inventory.xml
+++ b/indra/newview/skins/default/xui/ja/floater_my_inventory.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_nearby_chat.xml b/indra/newview/skins/default/xui/ja/floater_nearby_chat.xml
deleted file mode 100644
index bcddcc6907..0000000000
--- a/indra/newview/skins/default/xui/ja/floater_nearby_chat.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="nearby_chat" title="è¿‘ãã®ãƒãƒ£ãƒƒãƒˆ">
- <check_box label="ãƒãƒ£ãƒƒãƒˆã‚’翻訳" name="translate_chat_checkbox"/>
-</floater>
diff --git a/indra/newview/skins/default/xui/ja/floater_notification.xml b/indra/newview/skins/default/xui/ja/floater_notification.xml
index 0f37b30f52..0f37b30f52 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_notification.xml
+++ b/indra/newview/skins/default/xui/ja/floater_notification.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_notifications_console.xml b/indra/newview/skins/default/xui/ja/floater_notifications_console.xml
index c9d9ea7acb..c9d9ea7acb 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_notifications_console.xml
+++ b/indra/newview/skins/default/xui/ja/floater_notifications_console.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_object_weights.xml b/indra/newview/skins/default/xui/ja/floater_object_weights.xml
index d727a268fb..d727a268fb 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_object_weights.xml
+++ b/indra/newview/skins/default/xui/ja/floater_object_weights.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_openobject.xml b/indra/newview/skins/default/xui/ja/floater_openobject.xml
index af02ffedda..af02ffedda 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_openobject.xml
+++ b/indra/newview/skins/default/xui/ja/floater_openobject.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_outfit_save_as.xml b/indra/newview/skins/default/xui/ja/floater_outfit_save_as.xml
index 70555e6ded..70555e6ded 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_outfit_save_as.xml
+++ b/indra/newview/skins/default/xui/ja/floater_outfit_save_as.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_outgoing_call.xml b/indra/newview/skins/default/xui/ja/floater_outgoing_call.xml
index f1a05e0eec..f1a05e0eec 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_outgoing_call.xml
+++ b/indra/newview/skins/default/xui/ja/floater_outgoing_call.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_pathfinding_characters.xml b/indra/newview/skins/default/xui/ja/floater_pathfinding_characters.xml
new file mode 100755
index 0000000000..ada96b5b62
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/floater_pathfinding_characters.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="floater_pathfinding_characters" title="パスファインディングキャラクター">
+ <floater.string name="messaging_get_inprogress">
+ パスファインディングキャラクターを照会中...
+ </floater.string>
+ <floater.string name="messaging_get_error">
+ パスファインディングキャラクターã®ç…§ä¼šä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚
+ </floater.string>
+ <floater.string name="messaging_complete_none_found">
+ パスファインディングキャラクターãŒã‚ã‚Šã¾ã›ã‚“。
+ </floater.string>
+ <floater.string name="messaging_complete_available">
+ [NUM_TOTAL] キャラクター中 [NUM_SELECTED] キャラクターãŒé¸æŠžã•ã‚Œã¾ã—ãŸã€‚
+ </floater.string>
+ <floater.string name="messaging_not_enabled">
+ ã“ã®åœ°åŸŸï¼ˆãƒªãƒ¼ã‚¸ãƒ§ãƒ³ï¼‰ã¯ãƒ‘スファインディングã«å¯¾å¿œã—ã¦ã„ã¾ã›ã‚“。
+ </floater.string>
+ <floater.string name="character_cpu_time">
+ [CPU_TIME] µs
+ </floater.string>
+ <floater.string name="character_owner_loading">
+ [Loading]
+ </floater.string>
+ <floater.string name="character_owner_unknown">
+ [Unknown]
+ </floater.string>
+ <floater.string name="character_owner_group">
+ [group]
+ </floater.string>
+ <panel>
+ <scroll_list name="objects_scroll_list">
+ <scroll_list.columns label="åå‰" name="name"/>
+ <scroll_list.columns label="説明" name="description"/>
+ <scroll_list.columns label="所有者" name="owner"/>
+ <scroll_list.columns label="CPU" name="cpu_time"/>
+ <scroll_list.columns label="高度" name="altitude"/>
+ </scroll_list>
+ <text name="messaging_status">
+ キャラクター:
+ </text>
+ <button label="リストを更新" name="refresh_objects_list"/>
+ <button label="ã™ã¹ã¦é¸æŠž" name="select_all_objects"/>
+ <button label="何もé¸æŠžã—ãªã„" name="select_none_objects"/>
+ </panel>
+ <panel>
+ <text name="actions_label">
+ é¸æŠžã—ãŸã‚­ãƒ£ãƒ©ã‚¯ã‚¿ãƒ¼ã«å¯¾ã™ã‚‹ã‚¢ã‚¯ã‚·ãƒ§ãƒ³:
+ </text>
+ <check_box label="ビーコンを表示" name="show_beacon"/>
+ <check_box label="物ç†åŠ¹æžœã‚«ãƒ—セルを表示" name="show_physics_capsule"/>
+ <button label="å–ã‚‹" name="take_objects"/>
+ <button label="コピーをå–ã‚‹" name="take_copy_objects"/>
+ <button label="ç§ã‚’ãã“ã«ãƒ†ãƒ¬ãƒãƒ¼ãƒˆã™ã‚‹" name="teleport_me_to_object" tool_tip="1 ã¤ã®ã‚­ãƒ£ãƒ©ã‚¯ã‚¿ãƒ¼ãŒé¸æŠžã•ã‚ŒãŸå ´åˆã«ã®ã¿æœ‰åŠ¹ã§ã™ã€‚"/>
+ <button label="è¿”å´" name="return_objects"/>
+ <button label="削除" name="delete_objects"/>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/ja/floater_pathfinding_console.xml b/indra/newview/skins/default/xui/ja/floater_pathfinding_console.xml
new file mode 100755
index 0000000000..ec107f3e6b
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/floater_pathfinding_console.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="floater_pathfinding_console" title="パスファインディングã®è¡¨ç¤º/テスト">
+ <floater.string name="navmesh_viewer_status_library_not_implemented">
+ パスファインディングライブラリã®å®Ÿè£…ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“。
+ </floater.string>
+ <floater.string name="navmesh_viewer_status_region_not_enabled">
+ ã“ã®åœ°åŸŸï¼ˆãƒªãƒ¼ã‚¸ãƒ§ãƒ³ï¼‰ã¯ãƒ‘スファインディングã«å¯¾å¿œã—ã¦ã„ã¾ã›ã‚“。
+ </floater.string>
+ <floater.string name="navmesh_viewer_status_region_loading">
+ 地域(リージョン)ã®èª­ã¿è¾¼ã¿ã‚’å¾…æ©Ÿã—ã¦ã„ã¾ã™ã€‚
+ </floater.string>
+ <floater.string name="navmesh_viewer_status_checking_version">
+ ナビメッシュã®ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ã‚’確èªã—ã¦ã„ã¾ã™ã€‚
+ </floater.string>
+ <floater.string name="navmesh_viewer_status_downloading">
+ ナビメッシュをダウンロードã—ã¦ã„ã¾ã™ã€‚
+ </floater.string>
+ <floater.string name="navmesh_viewer_status_updating">
+ サーãƒãƒ¼ä¸Šã§ãƒŠãƒ“メッシュãŒå¤‰ã‚ã‚Šã¾ã—ãŸã€‚最新ã®ãƒŠãƒ“メッシュをダウンロードã—ã¦ã„ã¾ã™ã€‚
+ </floater.string>
+ <floater.string name="navmesh_viewer_status_has_navmesh">
+ 最新ã®ãƒŠãƒ“メッシュãŒãƒ€ã‚¦ãƒ³ãƒ­ãƒ¼ãƒ‰ã•ã‚Œã¾ã—ãŸã€‚
+ </floater.string>
+ <floater.string name="navmesh_viewer_status_error">
+ ナビメッシュを正ã—ãダウンロードã§ãã¾ã›ã‚“。
+ </floater.string>
+ <floater.string name="navmesh_simulator_status_pending">
+ ナビメッシュã«ä¿ç•™ä¸­ã®å¤‰æ›´ãŒã‚ã‚Šã¾ã™ã€‚
+ </floater.string>
+ <floater.string name="navmesh_simulator_status_building">
+ ナビメッシュを作æˆã—ã¦ã„ã¾ã™ã€‚
+ </floater.string>
+ <floater.string name="navmesh_simulator_status_some_pending">
+ ナビメッシュã®ä¸€éƒ¨ã®åœ°åŸŸï¼ˆãƒªãƒ¼ã‚¸ãƒ§ãƒ³ï¼‰ã«ä¿ç•™ä¸­ã®å¤‰æ›´ãŒã‚ã‚Šã¾ã™ã€‚
+ </floater.string>
+ <floater.string name="navmesh_simulator_status_some_building">
+ 一部ã®ãƒŠãƒ“メッシュ地域(リージョン)を構築ã—ã¦ã„ã¾ã™ã€‚
+ </floater.string>
+ <floater.string name="navmesh_simulator_status_pending_and_building">
+ ナビメッシュã®ä¸€éƒ¨ã®åœ°åŸŸï¼ˆãƒªãƒ¼ã‚¸ãƒ§ãƒ³ï¼‰ã«ä¿ç•™ä¸­ã®å¤‰æ›´ãŒã‚ã‚Šã€ãã®ä»–ã®åœ°åŸŸï¼ˆãƒªãƒ¼ã‚¸ãƒ§ãƒ³ï¼‰ã¯æ§‹ç¯‰ä¸­ã§ã™ã€‚
+ </floater.string>
+ <floater.string name="navmesh_simulator_status_complete">
+ ナビメッシュã¯æœ€æ–°ã§ã™ã€‚
+ </floater.string>
+ <floater.string name="pathing_library_not_implemented">
+ パスファインディングライブラリã®å®Ÿè£…ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“。
+ </floater.string>
+ <floater.string name="pathing_region_not_enabled">
+ ã“ã®åœ°åŸŸï¼ˆãƒªãƒ¼ã‚¸ãƒ§ãƒ³ï¼‰ã¯ãƒ‘スファインディングã«å¯¾å¿œã—ã¦ã„ã¾ã›ã‚“。
+ </floater.string>
+ <floater.string name="pathing_choose_start_and_end_points">
+ 開始点ã¨çµ‚了点をé¸æŠžã—ã¦ãã ã•ã„。
+ </floater.string>
+ <floater.string name="pathing_choose_start_point">
+ 開始点をé¸æŠžã—ã¦ãã ã•ã„。
+ </floater.string>
+ <floater.string name="pathing_choose_end_point">
+ 終了点をé¸æŠžã—ã¦ãã ã•ã„。
+ </floater.string>
+ <floater.string name="pathing_path_valid">
+ パスã¯ã‚ªãƒ¬ãƒ³ã‚¸è‰²ã§è¡¨ç¤ºã•ã‚Œã¦ã„ã¾ã™ã€‚
+ </floater.string>
+ <floater.string name="pathing_path_invalid">
+ é¸æŠžã—㟠2 点間ã®ãƒ‘スãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“。
+ </floater.string>
+ <floater.string name="pathing_error">
+ パスã®ç”Ÿæˆä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚
+ </floater.string>
+ <tab_container name="view_test_tab_container">
+ <panel label="表示" name="view_panel">
+ <text name="show_label">
+ 表示:
+ </text>
+ <check_box label="世界" name="show_world"/>
+ <check_box label="å¯å‹•ç‰©ã®ã¿" name="show_world_movables_only"/>
+ <check_box label="ナビメッシュ" name="show_navmesh"/>
+ <text name="show_walkability_label">
+ æ­©è¡Œå¯èƒ½ãƒžãƒƒãƒ—を表示:
+ </text>
+ <combo_box name="show_heatmap_mode">
+ <combo_box.item label="表示ã—ãªã„" name="show_heatmap_mode_none"/>
+ <combo_box.item label="キャラクター タイプ A" name="show_heatmap_mode_a"/>
+ <combo_box.item label="キャラクター タイプ B" name="show_heatmap_mode_b"/>
+ <combo_box.item label="キャラクター タイプ C" name="show_heatmap_mode_c"/>
+ <combo_box.item label="キャラクター タイプ D" name="show_heatmap_mode_d"/>
+ </combo_box>
+ <check_box label="æ­©è¡Œå¯èƒ½" name="show_walkables"/>
+ <check_box label="ç´ æボリューム" name="show_material_volumes"/>
+ <check_box label="é™çš„障害物" name="show_static_obstacles"/>
+ <check_box label="除外ボリューム" name="show_exclusion_volumes"/>
+ <check_box label="水上飛行機" name="show_water_plane"/>
+ <check_box label="X 線表示ã«ã‚ˆã‚‹" name="show_xray"/>
+ </panel>
+ <panel label="パスをテスト" name="test_panel">
+ <text name="ctrl_click_label">
+ Ctrl キーを押ã—ãªãŒã‚‰ã‚¯ãƒªãƒƒã‚¯ã—ã¦ã€é–‹å§‹ç‚¹ã‚’é¸æŠžã—ã¾ã™ã€‚
+ </text>
+ <text name="shift_click_label">
+ Shift キーを押ã—ãªãŒã‚‰ã‚¯ãƒªãƒƒã‚¯ã—ã¦ã€çµ‚了点をé¸æŠžã—ã¾ã™ã€‚
+ </text>
+ <text name="character_width_label">
+ キャラクターã®å¹…
+ </text>
+ <slider name="character_width" value="1"/>
+ <text name="character_width_unit_label">
+ m
+ </text>
+ <text name="character_type_label">
+ キャラクタータイプ
+ </text>
+ <combo_box name="path_character_type">
+ <combo_box.item label="ãªã—" name="path_character_type_none"/>
+ <combo_box.item label="A" name="path_character_type_a"/>
+ <combo_box.item label="B" name="path_character_type_b"/>
+ <combo_box.item label="C" name="path_character_type_c"/>
+ <combo_box.item label="D" name="path_character_type_d"/>
+ </combo_box>
+ <button label="パスをクリア" name="clear_path"/>
+ </panel>
+ </tab_container>
+</floater>
diff --git a/indra/newview/skins/default/xui/ja/floater_pathfinding_linksets.xml b/indra/newview/skins/default/xui/ja/floater_pathfinding_linksets.xml
new file mode 100755
index 0000000000..4441d5e738
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/floater_pathfinding_linksets.xml
@@ -0,0 +1,167 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="floater_pathfinding_linksets" title="パスファインディングリンクセット">
+ <floater.string name="messaging_get_inprogress">
+ パスファインディングリンクセットを照会中...
+ </floater.string>
+ <floater.string name="messaging_get_error">
+ パスファインディングリンクセットã®ç…§ä¼šä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚
+ </floater.string>
+ <floater.string name="messaging_set_inprogress">
+ é¸æŠžã—ãŸãƒ‘スファインディングリンクセットを修正中...
+ </floater.string>
+ <floater.string name="messaging_set_error">
+ é¸æŠžã—ãŸãƒ‘スファインディングリンクセットã®ä¿®æ­£ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚
+ </floater.string>
+ <floater.string name="messaging_complete_none_found">
+ パスファインディングリンクセットãŒã‚ã‚Šã¾ã›ã‚“。
+ </floater.string>
+ <floater.string name="messaging_complete_available">
+ [NUM_TOTAL] リンクセット中 [NUM_SELECTED] リンクセットãŒé¸æŠžã•ã‚Œã¾ã—ãŸã€‚
+ </floater.string>
+ <floater.string name="messaging_not_enabled">
+ ã“ã®åœ°åŸŸï¼ˆãƒªãƒ¼ã‚¸ãƒ§ãƒ³ï¼‰ã¯ãƒ‘スファインディングã«å¯¾å¿œã—ã¦ã„ã¾ã›ã‚“。
+ </floater.string>
+ <floater.string name="linkset_terrain_name">
+ [Terrain]
+ </floater.string>
+ <floater.string name="linkset_terrain_description">
+ --
+ </floater.string>
+ <floater.string name="linkset_terrain_owner">
+ --
+ </floater.string>
+ <floater.string name="linkset_terrain_scripted">
+ --
+ </floater.string>
+ <floater.string name="linkset_terrain_land_impact">
+ --
+ </floater.string>
+ <floater.string name="linkset_terrain_dist_from_you">
+ --
+ </floater.string>
+ <floater.string name="linkset_owner_loading">
+ [Loading]
+ </floater.string>
+ <floater.string name="linkset_owner_unknown">
+ [Unknown]
+ </floater.string>
+ <floater.string name="linkset_owner_group">
+ [group]
+ </floater.string>
+ <floater.string name="linkset_is_scripted">
+ ã¯ã„
+ </floater.string>
+ <floater.string name="linkset_is_not_scripted">
+ ã„ã„ãˆ
+ </floater.string>
+ <floater.string name="linkset_is_unknown_scripted">
+ ä¸æ˜Ž
+ </floater.string>
+ <floater.string name="linkset_use_walkable">
+ æ­©è¡Œå¯èƒ½
+ </floater.string>
+ <floater.string name="linkset_use_static_obstacle">
+ é™çš„障害物
+ </floater.string>
+ <floater.string name="linkset_use_dynamic_obstacle">
+ å¯å‹•éšœå®³ç‰©
+ </floater.string>
+ <floater.string name="linkset_use_material_volume">
+ ç´ æボリューム
+ </floater.string>
+ <floater.string name="linkset_use_exclusion_volume">
+ 除外ボリューム
+ </floater.string>
+ <floater.string name="linkset_use_dynamic_phantom">
+ å¯å‹•ãƒœãƒªãƒ¥ãƒ¼ãƒ 
+ </floater.string>
+ <floater.string name="linkset_is_terrain">
+ [unmodifiable]
+ </floater.string>
+ <floater.string name="linkset_is_restricted_state">
+ [restricted]
+ </floater.string>
+ <floater.string name="linkset_is_non_volume_state">
+ [concave]
+ </floater.string>
+ <floater.string name="linkset_is_restricted_non_volume_state">
+ [restricted,concave]
+ </floater.string>
+ <floater.string name="linkset_choose_use">
+ リンクセットã®ç”¨é€”ã‚’é¸æŠž...
+ </floater.string>
+ <panel>
+ <combo_box name="filter_by_linkset_use">
+ <combo_box.item label="リンクセットã®ç”¨é€”ã§ãƒ•ã‚£ãƒ«ã‚¿ãƒ¼..." name="filter_by_linkset_use_none"/>
+ <combo_box.item label="æ­©è¡Œå¯èƒ½" name="filter_by_linkset_use_walkable"/>
+ <combo_box.item label="é™çš„障害物" name="filter_by_linkset_use_static_obstacle"/>
+ <combo_box.item label="å¯å‹•éšœå®³ç‰©" name="filter_by_linkset_use_dynamic_obstacle"/>
+ <combo_box.item label="ç´ æボリューム" name="filter_by_linkset_use_material_volume"/>
+ <combo_box.item label="除外ボリューム" name="filter_by_linkset_use_exclusion_volume"/>
+ <combo_box.item label="å¯å‹•ãƒœãƒªãƒ¥ãƒ¼ãƒ " name="filter_by_linkset_use_dynamic_phantom"/>
+ </combo_box>
+ <button label="é©ç”¨" name="apply_filters"/>
+ <button label="クリア" name="clear_filters"/>
+ <scroll_list name="objects_scroll_list">
+ <scroll_list.columns label="åå‰ï¼ˆãƒ«ãƒ¼ãƒˆãƒ—リム)" name="name"/>
+ <scroll_list.columns label="説明(ルートプリム)" name="description"/>
+ <scroll_list.columns label="所有者" name="owner"/>
+ <scroll_list.columns label="スクリプト" name="scripted"/>
+ <scroll_list.columns label="è² è·" name="land_impact"/>
+ <scroll_list.columns label="è·é›¢" name="dist_from_you"/>
+ <scroll_list.columns label="リンクセットã®ç”¨é€”" name="linkset_use"/>
+ <scroll_list.columns label="A %" name="a_percent"/>
+ <scroll_list.columns label="B %" name="b_percent"/>
+ <scroll_list.columns label="C %" name="c_percent"/>
+ <scroll_list.columns label="D %" name="d_percent"/>
+ </scroll_list>
+ <text name="messaging_status">
+ リンクセット:
+ </text>
+ <button label="リスト更新" name="refresh_objects_list"/>
+ <button label="ã™ã¹ã¦é¸æŠž" name="select_all_objects"/>
+ <button label="何もé¸æŠžã—ãªã„" name="select_none_objects"/>
+ </panel>
+ <panel>
+ <check_box label="ビーコンを表示" name="show_beacon"/>
+ <button label="å–ã‚‹" name="take_objects"/>
+ <button label="コピーをå–ã‚‹" name="take_copy_objects"/>
+ <button label="ç§ã‚’ãã“ã«ãƒ†ãƒ¬ãƒãƒ¼ãƒˆã™ã‚‹" name="teleport_me_to_object"/>
+ <button label="è¿”å´" name="return_objects"/>
+ <button label="削除" name="delete_objects"/>
+ </panel>
+ <panel>
+ <text name="walkability_coefficients_label">
+ æ­©è¡Œå¯èƒ½æ€§:
+ </text>
+ <text name="edit_a_label">
+ A
+ </text>
+ <line_editor name="edit_a_value" tool_tip="タイプ A ã®ã‚­ãƒ£ãƒ©ã‚¯ã‚¿ãƒ¼ã®æ­©è¡Œå¯èƒ½æ€§ã€‚キャラクタータイプã®ä¾‹ã¯ãƒ’ューマノイドã§ã™ã€‚"/>
+ <text name="edit_b_label">
+ B
+ </text>
+ <line_editor name="edit_b_value" tool_tip="タイプ B ã®ã‚­ãƒ£ãƒ©ã‚¯ã‚¿ãƒ¼ã®æ­©è¡Œå¯èƒ½æ€§ã€‚キャラクタータイプã®ä¾‹ã¯ã‚¯ãƒªãƒ¼ãƒãƒ£ãƒ¼ã§ã™ã€‚"/>
+ <text name="edit_c_label">
+ C
+ </text>
+ <line_editor name="edit_c_value" tool_tip="タイプ C ã®ã‚­ãƒ£ãƒ©ã‚¯ã‚¿ãƒ¼ã®æ­©è¡Œå¯èƒ½æ€§ã€‚キャラクタータイプã®ä¾‹ã¯ãƒ¡ã‚«ãƒ‹ã‚«ãƒ«ã§ã™ã€‚"/>
+ <text name="edit_d_label">
+ D
+ </text>
+ <line_editor name="edit_d_value" tool_tip="タイプ D ã®ã‚­ãƒ£ãƒ©ã‚¯ã‚¿ãƒ¼ã®æ­©è¡Œå¯èƒ½æ€§ã€‚キャラクタータイプã®ä¾‹ã¯ãã®ä»–ã§ã™ã€‚"/>
+ <button label="変更をé©ç”¨" name="apply_edit_values"/>
+ <text name="suggested_use_a_label">
+ (ヒューマノイド)
+ </text>
+ <text name="suggested_use_b_label">
+ (クリーãƒãƒ£ãƒ¼)
+ </text>
+ <text name="suggested_use_c_label">
+ (メカニカル)
+ </text>
+ <text name="suggested_use_d_label">
+ (ãã®ä»–)
+ </text>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/ja/floater_pay.xml b/indra/newview/skins/default/xui/ja/floater_pay.xml
index 17965fb60a..17965fb60a 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_pay.xml
+++ b/indra/newview/skins/default/xui/ja/floater_pay.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_pay_object.xml b/indra/newview/skins/default/xui/ja/floater_pay_object.xml
index 637ad496ef..637ad496ef 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_pay_object.xml
+++ b/indra/newview/skins/default/xui/ja/floater_pay_object.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_people.xml b/indra/newview/skins/default/xui/ja/floater_people.xml
index b180658ab7..b180658ab7 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_people.xml
+++ b/indra/newview/skins/default/xui/ja/floater_people.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_perm_prefs.xml b/indra/newview/skins/default/xui/ja/floater_perm_prefs.xml
index 98cda25a81..98cda25a81 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_perm_prefs.xml
+++ b/indra/newview/skins/default/xui/ja/floater_perm_prefs.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_picks.xml b/indra/newview/skins/default/xui/ja/floater_picks.xml
index 359585eb86..359585eb86 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_picks.xml
+++ b/indra/newview/skins/default/xui/ja/floater_picks.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_places.xml b/indra/newview/skins/default/xui/ja/floater_places.xml
index 0d167444db..0d167444db 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_places.xml
+++ b/indra/newview/skins/default/xui/ja/floater_places.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_post_process.xml b/indra/newview/skins/default/xui/ja/floater_post_process.xml
index 7c4d9c78ee..7c4d9c78ee 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_post_process.xml
+++ b/indra/newview/skins/default/xui/ja/floater_post_process.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_postcard.xml b/indra/newview/skins/default/xui/ja/floater_postcard.xml
deleted file mode 100644
index 9d9b59fa51..0000000000
--- a/indra/newview/skins/default/xui/ja/floater_postcard.xml
+++ /dev/null
@@ -1,42 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Postcard" title="スナップショットをEメールã§é€ä¿¡">
- <text name="to_label">
- å—ä¿¡å…ˆã®Eメール:
- </text>
- <line_editor left="145" name="to_form" width="125"/>
- <text name="from_label">
- ã‚ãªãŸã®Eメール:
- </text>
- <line_editor left="145" name="from_form" width="125"/>
- <text name="name_label">
- ã‚ãªãŸã®åå‰ï¼š
- </text>
- <line_editor left="145" name="name_form" width="125"/>
- <text name="subject_label">
- 件å:
- </text>
- <line_editor label="件åを入力ã—ã¦ãã ã•ã„" left="145" name="subject_form" width="125"/>
- <text name="msg_label">
- メッセージ:
- </text>
- <text_editor bottom_delta="-120" height="110" name="msg_form">
- メッセージをã“ã“ã«å…¥åŠ›ã—ã¦ãã ã•ã„。
- </text_editor>
- <check_box label="Web上ã§å…¬é–‹" name="allow_publish_check" tool_tip="ã“ã®ãƒã‚¹ãƒˆã‚«ãƒ¼ãƒ‰ã‚’Web上ã§å…¬é–‹ã—ã¾ã™ã€‚"/>
- <check_box label="æˆäººå‘ã‘コンテンツ" name="mature_check" tool_tip="ã“ã®ãƒã‚¹ãƒˆã‚«ãƒ¼ãƒ‰ã«ã¯æˆäººå‘ã‘内容ãŒå«ã¾ã‚Œã¾ã™ã€‚"/>
- <button label="?" left="300" name="publish_help_btn"/>
- <text name="fine_print">
- ã“ã®å—信者ãŒSLã«å‚加ã™ã‚‹ã¨ã€ã‚ãªãŸã«ç´¹ä»‹ãƒœãƒ¼ãƒŠã‚¹ãŒå…¥ã‚Šã¾ã™
- </text>
- <button bottom_delta="-52" label="å–り消ã—" name="cancel_btn"/>
- <button label="é€ä¿¡" name="send_btn"/>
- <text name="default_subject">
- [SECOND_LIFE] ã‹ã‚‰ã®ãƒã‚¹ãƒˆã‚«ãƒ¼ãƒ‰ã§ã™ã€‚
- </text>
- <text name="default_message">
- ã“ã‚Œã¯çµ¶å¯¾ãƒã‚§ãƒƒã‚¯ï¼
- </text>
- <string name="upload_message">
- é€ä¿¡ä¸­...
- </string>
-</floater>
diff --git a/indra/newview/skins/default/xui/ja/floater_preferences.xml b/indra/newview/skins/default/xui/ja/floater_preferences.xml
index d48a8241ec..d48a8241ec 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_preferences.xml
+++ b/indra/newview/skins/default/xui/ja/floater_preferences.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_preferences_proxy.xml b/indra/newview/skins/default/xui/ja/floater_preferences_proxy.xml
index 4638fd002e..4638fd002e 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_preferences_proxy.xml
+++ b/indra/newview/skins/default/xui/ja/floater_preferences_proxy.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_preview_animation.xml b/indra/newview/skins/default/xui/ja/floater_preview_animation.xml
index a3042f66ea..a3042f66ea 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_preview_animation.xml
+++ b/indra/newview/skins/default/xui/ja/floater_preview_animation.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_preview_gesture.xml b/indra/newview/skins/default/xui/ja/floater_preview_gesture.xml
index 59ce36b022..59ce36b022 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_preview_gesture.xml
+++ b/indra/newview/skins/default/xui/ja/floater_preview_gesture.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_preview_notecard.xml b/indra/newview/skins/default/xui/ja/floater_preview_notecard.xml
index ae8ae9f7b5..ae8ae9f7b5 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_preview_notecard.xml
+++ b/indra/newview/skins/default/xui/ja/floater_preview_notecard.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_preview_sound.xml b/indra/newview/skins/default/xui/ja/floater_preview_sound.xml
index 5c0f05cec6..5c0f05cec6 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_preview_sound.xml
+++ b/indra/newview/skins/default/xui/ja/floater_preview_sound.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_preview_texture.xml b/indra/newview/skins/default/xui/ja/floater_preview_texture.xml
index 4617fd1d92..4617fd1d92 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_preview_texture.xml
+++ b/indra/newview/skins/default/xui/ja/floater_preview_texture.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_price_for_listing.xml b/indra/newview/skins/default/xui/ja/floater_price_for_listing.xml
index 10a46247a7..10a46247a7 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_price_for_listing.xml
+++ b/indra/newview/skins/default/xui/ja/floater_price_for_listing.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_publish_classified.xml b/indra/newview/skins/default/xui/ja/floater_publish_classified.xml
index f33406da51..f33406da51 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_publish_classified.xml
+++ b/indra/newview/skins/default/xui/ja/floater_publish_classified.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_region_debug_console.xml b/indra/newview/skins/default/xui/ja/floater_region_debug_console.xml
index 4edb4972e4..4edb4972e4 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_region_debug_console.xml
+++ b/indra/newview/skins/default/xui/ja/floater_region_debug_console.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_region_info.xml b/indra/newview/skins/default/xui/ja/floater_region_info.xml
index d08c51c61e..d08c51c61e 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_region_info.xml
+++ b/indra/newview/skins/default/xui/ja/floater_region_info.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_report_abuse.xml b/indra/newview/skins/default/xui/ja/floater_report_abuse.xml
index dc34441535..dc34441535 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_report_abuse.xml
+++ b/indra/newview/skins/default/xui/ja/floater_report_abuse.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_script_debug.xml b/indra/newview/skins/default/xui/ja/floater_script_debug.xml
index 0ac7a988e0..0ac7a988e0 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_script_debug.xml
+++ b/indra/newview/skins/default/xui/ja/floater_script_debug.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_script_debug_panel.xml b/indra/newview/skins/default/xui/ja/floater_script_debug_panel.xml
index e70a30fa24..e70a30fa24 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_script_debug_panel.xml
+++ b/indra/newview/skins/default/xui/ja/floater_script_debug_panel.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_script_limits.xml b/indra/newview/skins/default/xui/ja/floater_script_limits.xml
index 7ccd858af7..7ccd858af7 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_script_limits.xml
+++ b/indra/newview/skins/default/xui/ja/floater_script_limits.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_script_preview.xml b/indra/newview/skins/default/xui/ja/floater_script_preview.xml
index 656357aa17..656357aa17 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_script_preview.xml
+++ b/indra/newview/skins/default/xui/ja/floater_script_preview.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_script_queue.xml b/indra/newview/skins/default/xui/ja/floater_script_queue.xml
index 97e79fb483..97e79fb483 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_script_queue.xml
+++ b/indra/newview/skins/default/xui/ja/floater_script_queue.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_script_search.xml b/indra/newview/skins/default/xui/ja/floater_script_search.xml
index bc4f48c995..bc4f48c995 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_script_search.xml
+++ b/indra/newview/skins/default/xui/ja/floater_script_search.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_search.xml b/indra/newview/skins/default/xui/ja/floater_search.xml
index 0723be0068..0723be0068 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_search.xml
+++ b/indra/newview/skins/default/xui/ja/floater_search.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_select_key.xml b/indra/newview/skins/default/xui/ja/floater_select_key.xml
index d41be86873..d41be86873 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_select_key.xml
+++ b/indra/newview/skins/default/xui/ja/floater_select_key.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_sell_land.xml b/indra/newview/skins/default/xui/ja/floater_sell_land.xml
index aa368eef11..aa368eef11 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_sell_land.xml
+++ b/indra/newview/skins/default/xui/ja/floater_sell_land.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_settings_debug.xml b/indra/newview/skins/default/xui/ja/floater_settings_debug.xml
index cb7950bf53..cb7950bf53 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_settings_debug.xml
+++ b/indra/newview/skins/default/xui/ja/floater_settings_debug.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_snapshot.xml b/indra/newview/skins/default/xui/ja/floater_snapshot.xml
index f145a2e8b8..f145a2e8b8 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_snapshot.xml
+++ b/indra/newview/skins/default/xui/ja/floater_snapshot.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_sound_devices.xml b/indra/newview/skins/default/xui/ja/floater_sound_devices.xml
index 28d2388bed..28d2388bed 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_sound_devices.xml
+++ b/indra/newview/skins/default/xui/ja/floater_sound_devices.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_sound_preview.xml b/indra/newview/skins/default/xui/ja/floater_sound_preview.xml
index 7d83309c46..7d83309c46 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_sound_preview.xml
+++ b/indra/newview/skins/default/xui/ja/floater_sound_preview.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_spellcheck.xml b/indra/newview/skins/default/xui/ja/floater_spellcheck.xml
new file mode 100755
index 0000000000..31fbef9bcf
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/floater_spellcheck.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="spellcheck_floater" title="スペルãƒã‚§ãƒƒã‚«ãƒ¼ã®è¨­å®š">
+ <check_box label="スペルãƒã‚§ãƒƒã‚«ãƒ¼ã‚’有効ã«ã™ã‚‹" name="spellcheck_enable"/>
+ <text name="spellcheck_main">
+ メイン辞書:
+ </text>
+ <text label="ログ:" name="spellcheck_additional">
+ ãã®ä»–ã®è¾žæ›¸ï¼š
+ </text>
+ <text name="spellcheck_available">
+ 入手å¯
+ </text>
+ <text name="spellcheck_active">
+ 有効
+ </text>
+ <button label="削除" name="spellcheck_remove_btn"/>
+ <button label="インãƒãƒ¼ãƒˆ..." name="spellcheck_import_btn"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/ja/floater_spellcheck_import.xml b/indra/newview/skins/default/xui/ja/floater_spellcheck_import.xml
new file mode 100755
index 0000000000..febe153d25
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/floater_spellcheck_import.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="spellcheck_import" title="辞書をインãƒãƒ¼ãƒˆ">
+ <button label="å‚ç…§" label_selected="å‚ç…§" name="dictionary_path_browse"/>
+ <button label="インãƒãƒ¼ãƒˆ" name="ok_btn"/>
+ <button label="å–り消ã—" name="cancel_btn"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/ja/floater_stats.xml b/indra/newview/skins/default/xui/ja/floater_stats.xml
index 6a1f34cfd8..1922e4841a 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_stats.xml
+++ b/indra/newview/skins/default/xui/ja/floater_stats.xml
@@ -14,8 +14,11 @@
<stat_bar label="秒ã”ã¨ã® KTris æç”»" name="ktrissec"/>
<stat_bar label="オブジェクトåˆè¨ˆ" name="objs"/>
<stat_bar label="æ–°è¦ã‚ªãƒ–ジェクト" name="newobjs"/>
+ <stat_bar label="オブジェクトキャッシュヒット率" name="object_cache_hits"/>
</stat_view>
<stat_view label="テクスãƒãƒ£" name="texture">
+ <stat_bar label="キャッシュヒット率" name="texture_cache_hits"/>
+ <stat_bar label="キャッシュ読ã¿å–ã‚Šé…延" name="texture_cache_read_latency"/>
<stat_bar label="カウント" name="numimagesstat"/>
<stat_bar label="Raw カウント" name="numrawimagesstat"/>
<stat_bar label="GL メモリ" name="gltexmemstat"/>
@@ -50,7 +53,13 @@
<stat_bar label="オブジェクト" name="simobjects"/>
<stat_bar label="アクティブãªã‚ªãƒ–ジェクト" name="simactiveobjects"/>
<stat_bar label="アクティブãªã‚¹ã‚¯ãƒªãƒ—ト" name="simactivescripts"/>
+ <stat_bar label="スクリプト実行" name="simpctscriptsrun"/>
<stat_bar label="スクリプトイベント" name="simscripteps"/>
+ <stat_view label="パスファインディング" name="simpathfinding">
+ <stat_bar label="AIステップ時間" name="simsimaistepmsec"/>
+ <stat_bar label="スキップã•ã‚ŒãŸã‚·ãƒ«ã‚¨ãƒƒãƒˆã‚¹ãƒ†ãƒƒãƒ—" name="simsimskippedsilhouettesteps"/>
+ <stat_bar label="æ›´æ–°ã•ã‚ŒãŸã‚­ãƒ£ãƒ©ã‚¯ã‚¿ãƒ¼" name="simsimpctsteppedcharacters"/>
+ </stat_view>
<stat_bar label="パケットイン" name="siminpps"/>
<stat_bar label="パケットアウト" name="simoutpps"/>
<stat_bar label="ä¿ç•™ä¸­ã®ãƒ€ã‚¦ãƒ³ãƒ­ãƒ¼ãƒ‰" name="simpendingdownloads"/>
diff --git a/indra/newview/skins/default/xui/ja/floater_sys_well.xml b/indra/newview/skins/default/xui/ja/floater_sys_well.xml
index 45e97bdf5d..45e97bdf5d 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_sys_well.xml
+++ b/indra/newview/skins/default/xui/ja/floater_sys_well.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_telehub.xml b/indra/newview/skins/default/xui/ja/floater_telehub.xml
index 7318083771..7318083771 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_telehub.xml
+++ b/indra/newview/skins/default/xui/ja/floater_telehub.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_test_layout_stacks.xml b/indra/newview/skins/default/xui/ja/floater_test_layout_stacks.xml
index 31b5bbd3bf..31b5bbd3bf 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_test_layout_stacks.xml
+++ b/indra/newview/skins/default/xui/ja/floater_test_layout_stacks.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_test_text_vertical_aligment.xml b/indra/newview/skins/default/xui/ja/floater_test_text_vertical_aligment.xml
index 40fd8e9f93..40fd8e9f93 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_test_text_vertical_aligment.xml
+++ b/indra/newview/skins/default/xui/ja/floater_test_text_vertical_aligment.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/ja/floater_texture_ctrl.xml
index 399cffcce5..37233d3e68 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_texture_ctrl.xml
+++ b/indra/newview/skins/default/xui/ja/floater_texture_ctrl.xml
@@ -1,24 +1,36 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="texture picker" title="テクスãƒãƒ£ã®é¸æŠž">
- <string name="choose_picture">
+ <floater.string name="choose_picture">
クリックã—ã¦å†™çœŸã‚’é¸æŠž
- </string>
+ </floater.string>
+ <floater.string name="pick title">
+ ピック:
+ </floater.string>
<text name="Multiple">
複数ã®ãƒ†ã‚¯ã‚¹ãƒãƒ£
</text>
+ <radio_group name="mode_selection">
+ <radio_item label="インベントリ" name="inventory" value="0"/>
+ <radio_item label="ローカル" name="local" value="1"/>
+ </radio_group>
<text name="unknown">
サイズ: [DIMENSIONS]
</text>
<button label="デフォルト" label_selected="デフォルト" name="Default"/>
- <button label="ãªã—" label_selected="ãªã—" name="None"/>
<button label="ブランク" label_selected="ブランク" name="Blank"/>
- <check_box label="フォルダを表示" name="show_folders_check"/>
- <search_editor label="テクスãƒãƒ£ã‚’フィルター" name="inventory search editor"/>
- <check_box label="ã™ãé©ç”¨" name="apply_immediate_check"/>
+ <button label="ãªã—" label_selected="ãªã—" name="None"/>
<button label="" label_selected="" name="Pipette"/>
- <button label="å–り消ã—" label_selected="å–り消ã—" name="Cancel"/>
+ <check_box initial_value="true" label="今ã™ãé©ç”¨" name="apply_immediate_check"/>
+ <text name="preview_disabled" value="プレビュー無効"/>
+ <filter_editor label="テクスãƒãƒ£ã‚’フィルター" name="inventory search editor"/>
+ <check_box initial_value="false" label="フォルダを表示" name="show_folders_check"/>
+ <button label="追加" label_selected="追加" name="l_add_btn"/>
+ <button label="削除" label_selected="削除" name="l_rem_btn"/>
+ <button label="アップロード" label_selected="アップロード" name="l_upl_btn"/>
+ <scroll_list name="l_name_list">
+ <column label="åå‰" name="unit_name"/>
+ <column label="ID" name="unit_id_HIDDEN"/>
+ </scroll_list>
<button label="OK" label_selected="OK" name="Select"/>
- <text name="pick title">
- ピック:
- </text>
+ <button label="å–り消ã—" label_selected="å–り消ã—" name="Cancel"/>
</floater>
diff --git a/indra/newview/skins/default/xui/ja/floater_texture_fetch_debugger.xml b/indra/newview/skins/default/xui/ja/floater_texture_fetch_debugger.xml
new file mode 100755
index 0000000000..adc35137b5
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/floater_texture_fetch_debugger.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="TexFetchDebugger" title="テクスãƒãƒ£å–得デãƒãƒƒã‚¬">
+ <text name="total_num_fetched_label">
+ 1, å–å¾—ã—ãŸãƒ†ã‚¯ã‚¹ãƒãƒ£ã®åˆè¨ˆæ•°ï¼š[NUM]
+ </text>
+ <text name="total_num_fetching_requests_label">
+ 2, å–得リクエストã®åˆè¨ˆæ•°ï¼š[NUM]
+ </text>
+ <text name="total_num_cache_hits_label">
+ 3, キャッシュヒットã®åˆè¨ˆæ•°ï¼š[NUM]
+ </text>
+ <text name="total_num_visible_tex_label">
+ 4, 表示テクスãƒãƒ£ã®åˆè¨ˆæ•°ï¼š[NUM]
+ </text>
+ <text name="total_num_visible_tex_fetch_req_label">
+ 5, 表示テクスãƒãƒ£å–得リクエストã®åˆè¨ˆæ•°ï¼š[NUM]
+ </text>
+ <text name="total_fetched_data_label">
+ 6, å–å¾—ã—ãŸãƒ‡ãƒ¼ã‚¿ã®åˆè¨ˆæ•°ï¼š[SIZE1]KBã€ãƒ‡ã‚³ãƒ¼ãƒ‰ã•ã‚ŒãŸãƒ‡ãƒ¼ã‚¿ï¼š[SIZE2]KBã€[PIXEL]メガピクセル
+ </text>
+ <text name="total_fetched_vis_data_label">
+ 7, 表示データã®åˆè¨ˆæ•°ï¼š[SIZE1]KBã€ãƒ‡ã‚³ãƒ¼ãƒ‰ã•ã‚ŒãŸãƒ‡ãƒ¼ã‚¿ï¼š[SIZE2]KB
+ </text>
+ <text name="total_fetched_rendered_data_label">
+ 8, レンダリングã•ã‚ŒãŸãƒ‡ãƒ¼ã‚¿ã®åˆè¨ˆæ•°ï¼š[SIZE1]KBã€ãƒ‡ã‚³ãƒ¼ãƒ‰ã•ã‚ŒãŸãƒ‡ãƒ¼ã‚¿ï¼š[SIZE2]KBã€[PIXEL]メガピクセル
+ </text>
+ <text name="total_time_cache_read_label">
+ 9, キャッシュ読ã¿å–ã‚Šã®åˆè¨ˆæ™‚間:[TIME] 秒
+ </text>
+ <text name="total_time_cache_write_label">
+ 10, キャッシュ書ãè¾¼ã¿ã®åˆè¨ˆæ™‚間:[TIME] 秒
+ </text>
+ <text name="total_time_decode_label">
+ 11, デコードã®åˆè¨ˆæ™‚間:[TIME] 秒
+ </text>
+ <text name="total_time_gl_label">
+ 12, glテクスãƒãƒ£ä½œæˆã®åˆè¨ˆæ™‚間:[TIME] 秒
+ </text>
+ <text name="total_time_http_label">
+ 13, HTTP å–å¾—ã®åˆè¨ˆæ™‚間:[TIME] 秒
+ </text>
+ <text name="total_time_fetch_label">
+ 14, å–得全体ã®åˆè¨ˆæ™‚間:[TIME] 秒
+ </text>
+ <text name="total_time_refetch_vis_cache_label">
+ 15, キャッシュã‹ã‚‰è¡¨ç¤ºãƒ†ã‚¯ã‚¹ãƒãƒ£ã‚’å†å–å¾—ã€æ™‚間:[TIME] 秒ã€å–得:[SIZE]KBã€[PIXEL]メガピクセル
+ </text>
+ <text name="total_time_refetch_all_cache_label">
+ 16ã€ã‚­ãƒ£ãƒƒã‚·ãƒ¥ã‹ã‚‰ã™ã¹ã¦ã®ãƒ†ã‚¯ã‚¹ãƒãƒ£ã‚’å†ãƒ•ã‚§ãƒƒãƒä¸­ã€æ™‚é–“: [TIME] 秒ã€ãƒ•ã‚§ãƒƒãƒæ¸ˆã¿: [SIZE]KBã€[PIXEL]メガピクセル
+ </text>
+ <text name="total_time_refetch_vis_http_label">
+ 17ã€HTTP ã‹ã‚‰å¯è¦–ファイルをå†ãƒ•ã‚§ãƒƒãƒä¸­ã€æ™‚é–“: [TIME] 秒ã€ãƒ•ã‚§ãƒƒãƒæ¸ˆã¿: [SIZE]KBã€[PIXEL]メガピクセル
+ </text>
+ <text name="total_time_refetch_all_http_label">
+ 18ã€HTTP ã‹ã‚‰ã™ã¹ã¦ã®ãƒ†ã‚¯ã‚¹ãƒãƒ£ã‚’å†ãƒ•ã‚§ãƒƒãƒä¸­ã€æ™‚é–“: [TIME] 秒ã€ãƒ•ã‚§ãƒƒãƒæ¸ˆã¿: [SIZE]KBã€[PIXEL]メガピクセル
+ </text>
+ <spinner label="19ã€ãƒ†ã‚»ãƒ«/ピクセル比:" name="texel_pixel_ratio"/>
+ <text name="texture_source_label">
+ 20ã€ãƒ†ã‚¯ã‚¹ãƒãƒ£ ソース:
+ </text>
+ <radio_group name="texture_source">
+ <radio_item label="キャッシュ + HTTP" name="0"/>
+ <radio_item label="HTTP ã®ã¿" name="1"/>
+ </radio_group>
+ <button label="開始" name="start_btn"/>
+ <button label="リセット" name="clear_btn"/>
+ <button label="é–‰ã˜ã‚‹" name="close_btn"/>
+ <button label="キャッシュ読ã¿å–ã‚Š" name="cacheread_btn"/>
+ <button label="キャッシュ書ãè¾¼ã¿" name="cachewrite_btn"/>
+ <button label="HTTP" name="http_btn"/>
+ <button label="デコード" name="decode_btn"/>
+ <button label="GL テクスãƒãƒ£" name="gl_btn"/>
+ <button label="キャッシュ表示テクスãƒãƒ£å†å–å¾—" name="refetchviscache_btn"/>
+ <button label="ã™ã¹ã¦ã®ã‚­ãƒ£ãƒƒã‚·ãƒ¥ã‚’å†ãƒ•ã‚§ãƒƒãƒ" name="refetchallcache_btn"/>
+ <button label="HTTP表示テクスãƒãƒ£å†å–å¾—" name="refetchvishttp_btn"/>
+ <button label="ã™ã¹ã¦ã® HTTP ã‚’å†ãƒ•ã‚§ãƒƒãƒ" name="refetchallhttp_btn"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/ja/floater_tools.xml b/indra/newview/skins/default/xui/ja/floater_tools.xml
index 2d12a5e56a..5511433ae3 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_tools.xml
+++ b/indra/newview/skins/default/xui/ja/floater_tools.xml
@@ -148,6 +148,12 @@
<panel.string name="text modify info 4">
ã“れらã®ã‚ªãƒ–ジェクトを修正ã§ãã¾ã›ã‚“
</panel.string>
+ <panel.string name="text modify info 5">
+ 地域(リージョン)ã®å¢ƒç•Œã‚’越ãˆã¦ã“ã®ã‚ªãƒ–ジェクトを修正ã§ãã¾ã›ã‚“
+ </panel.string>
+ <panel.string name="text modify info 6">
+ 地域(リージョン)ã®å¢ƒç•Œã‚’越ãˆã¦ã“れらã®ã‚ªãƒ–ジェクトを修正ã§ãã¾ã›ã‚“
+ </panel.string>
<panel.string name="text modify warning">
オブジェクト全体をé¸æŠžã—ã¦æ¨©é™ã®è¨­å®šã‚’è¡Œã£ã¦ãã ã•ã„。
</panel.string>
@@ -203,12 +209,12 @@
<combo_box.item label="ズームã™ã‚‹" name="Zoom"/>
</combo_box>
<check_box label="販売対象:" name="checkbox for sale"/>
+ <spinner label="L$" name="Edit Cost"/>
<combo_box name="sale type">
<combo_box.item label="コピー" name="Copy"/>
<combo_box.item label="中身" name="Contents"/>
<combo_box.item label="オリジナル" name="Original"/>
</combo_box>
- <spinner label="価格: L$" name="Edit Cost"/>
<check_box label="検索ã«è¡¨ç¤º" name="search_check" tool_tip="検索çµæžœã«ã“ã®ã‚ªãƒ–ジェクトを表示ã—ã¾ã™"/>
<panel name="perms_build">
<text name="perm_modify">
@@ -244,6 +250,11 @@
F:
</text>
</panel>
+ <panel name="pathfinding_attrs_panel">
+ <text name="pathfinding_attributes_label">
+ パスファインディング属性:
+ </text>
+ </panel>
</panel>
<panel label="形状" name="Object">
<check_box label="ロック" name="checkbox locked" tool_tip="オブジェクトã®ç§»å‹•ã¨å‰Šé™¤ã‚’ç¦æ­¢ã—ã¾ã™ã€‚ ã“ã®æ©Ÿèƒ½ã‚’使ã†ã¨ã€åˆ¶ä½œä¸­ã®æ„図ã›ã¬ç·¨é›†ã‚’防ãã“ã¨ãŒã§ãã¾ã™"/>
@@ -458,16 +469,11 @@
<combo_box.item label="å¸ã„è¾¼ã¿" name="suction"/>
<combo_box.item label="織目" name="weave"/>
</combo_box>
- <check_box initial_value="false" label="å¹³é¢ã‚’æƒãˆã‚‹" name="checkbox planar align" tool_tip="é¸æŠžé¢å…¨ã¦ã®ãƒ†ã‚¯ã‚¹ãƒãƒ£ã‚’ã€æœ€å¾Œã«é¸æŠžã•ã‚ŒãŸé¢ã«æƒãˆã¾ã™ã€‚ å¹³é¢ãƒ†ã‚¯ã‚¹ãƒãƒ£ã®ãƒžãƒƒãƒ”ングãŒå¿…è¦ã§ã™ã€‚"/>
- <text name="rpt">
- å復 / é¢
- </text>
<spinner label="水平(U)" name="TexScaleU"/>
<check_box label="å転" name="checkbox flip s"/>
<spinner label="垂直(V)" name="TexScaleV"/>
<check_box label="å転" name="checkbox flip t"/>
<spinner label="回転˚" name="TexRot"/>
- <spinner label="å復 / メーター" name="rptctrl"/>
<button label="é©ç”¨" label_selected="é©ç”¨" name="button apply"/>
<text name="tex offset">
テクスãƒãƒ£ã®ã‚ºãƒ¬
diff --git a/indra/newview/skins/default/xui/ja/floater_top_objects.xml b/indra/newview/skins/default/xui/ja/floater_top_objects.xml
index bfc93e5624..c44f409d4e 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_top_objects.xml
+++ b/indra/newview/skins/default/xui/ja/floater_top_objects.xml
@@ -9,9 +9,6 @@
<floater.string name="scripts_score_label">
時間
</floater.string>
- <floater.string name="scripts_mono_time_label">
- Monoタイム
- </floater.string>
<floater.string name="top_colliders_title">
上部コライダー
</floater.string>
@@ -32,9 +29,10 @@
<scroll_list.columns label="åå‰" name="name"/>
<scroll_list.columns label="所有者" name="owner"/>
<scroll_list.columns label="ロケーション" name="location"/>
+ <scroll_list.columns label="区画" name="parcel"/>
<scroll_list.columns label="時間" name="time"/>
- <scroll_list.columns label="Monoタイム" name="mono_time"/>
<scroll_list.columns label="URL" name="URLs"/>
+ <scroll_list.columns label="メモリ(KB)" name="memory"/>
</scroll_list>
<text name="id_text">
物体ID:
@@ -48,6 +46,10 @@
所有者:
</text>
<button label="フィルタ" name="filter_owner_btn"/>
+ <text name="parcel_name_text">
+ 区画:
+ </text>
+ <button label="フィルター" name="filter_parcel_btn"/>
<button label="æ›´æ–°" name="refresh_btn"/>
<button label="é¸æŠžå†…容を返å´" name="return_selected_btn"/>
<button label="ã™ã¹ã¦è¿”å´" name="return_all_btn"/>
diff --git a/indra/newview/skins/default/xui/ja/floater_tos.xml b/indra/newview/skins/default/xui/ja/floater_tos.xml
index ae064724c0..ae064724c0 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_tos.xml
+++ b/indra/newview/skins/default/xui/ja/floater_tos.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_toybox.xml b/indra/newview/skins/default/xui/ja/floater_toybox.xml
index 682352ec82..682352ec82 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_toybox.xml
+++ b/indra/newview/skins/default/xui/ja/floater_toybox.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_translation_settings.xml b/indra/newview/skins/default/xui/ja/floater_translation_settings.xml
index 27143086ac..27143086ac 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_translation_settings.xml
+++ b/indra/newview/skins/default/xui/ja/floater_translation_settings.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_url_entry.xml b/indra/newview/skins/default/xui/ja/floater_url_entry.xml
index 8e09e4748a..8e09e4748a 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_url_entry.xml
+++ b/indra/newview/skins/default/xui/ja/floater_url_entry.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_voice_chat_volume.xml b/indra/newview/skins/default/xui/ja/floater_voice_chat_volume.xml
new file mode 100644
index 0000000000..44e96c35ad
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/floater_voice_chat_volume.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="floater_voice_volume" title="ボイスãƒãƒ£ãƒƒãƒˆã®éŸ³é‡">
+ <slider label="ボイスãƒãƒ£ãƒƒãƒˆ" name="chat_voice_volume"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/ja/floater_voice_controls.xml b/indra/newview/skins/default/xui/ja/floater_voice_controls.xml
index f7d3fd11e0..f7d3fd11e0 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_voice_controls.xml
+++ b/indra/newview/skins/default/xui/ja/floater_voice_controls.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_voice_effect.xml b/indra/newview/skins/default/xui/ja/floater_voice_effect.xml
index ee675e143b..b38ea9331a 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_voice_effect.xml
+++ b/indra/newview/skins/default/xui/ja/floater_voice_effect.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater label="場所" name="voice_effects" title="ボイスモーフィング">
+<floater label="場所" name="voice_effects" title="ボイスモーフィングã®ãƒ—レビュー">
<string name="no_voice_effect">
(ボイスモーフィングãªã—)
</string>
diff --git a/indra/newview/skins/default/xui/ja/floater_voice_volume.xml b/indra/newview/skins/default/xui/ja/floater_voice_volume.xml
new file mode 100644
index 0000000000..a380615d5a
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/floater_voice_volume.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<!--
+ Not can_close / no title to avoid window chrome
+ Single instance - only have one at a time, recycle it each spawn
+-->
+<floater name="floater_voice_volume" title="ボイス音é‡">
+ <slider name="volume_slider" tool_tip="ボイス音é‡" value="0.5"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/ja/floater_web_content.xml b/indra/newview/skins/default/xui/ja/floater_web_content.xml
index 48fe8aee78..48fe8aee78 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_web_content.xml
+++ b/indra/newview/skins/default/xui/ja/floater_web_content.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_whitelist_entry.xml b/indra/newview/skins/default/xui/ja/floater_whitelist_entry.xml
index 34aba9d485..34aba9d485 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_whitelist_entry.xml
+++ b/indra/newview/skins/default/xui/ja/floater_whitelist_entry.xml
diff --git a/indra/newview/skins/default/xui/ja/floater_window_size.xml b/indra/newview/skins/default/xui/ja/floater_window_size.xml
index 152a5f4806..416813d6cc 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_window_size.xml
+++ b/indra/newview/skins/default/xui/ja/floater_window_size.xml
@@ -7,10 +7,17 @@
ウィンドウã®ã‚µã‚¤ã‚ºã‚’設定:
</text>
<combo_box name="window_size_combo" tool_tip="横幅 x 高ã•">
- <combo_box.item label="1000 x 700 (標準)" name="item0"/>
- <combo_box.item label="1024 x 768" name="item1"/>
- <combo_box.item label="1280 x 720 (720p)" name="item2"/>
- <combo_box.item label="1920 x 1080 (1080p)" name="item3"/>
+ <combo_box.item label="1000 x 700 (デフォルト)" name="item1"/>
+ <combo_box.item label="1024 x 768 (4:3 XGA)" name="item2"/>
+ <combo_box.item label="1280 x 720 (16:9 HDTV)" name="item3"/>
+ <combo_box.item label="1280 x 800 (5:8 WXGA)" name="item4"/>
+ <combo_box.item label="1280 x 1024 (5:4 SXGA)" name="item5"/>
+ <combo_box.item label="1440 x 900 (8:5 WSXGA)" name="item7"/>
+ <combo_box.item label="1600 x 900 (16:9 HD+)" name="item8"/>
+ <combo_box.item label="1600 x 1200 (4:3 UXGA)" name="item9"/>
+ <combo_box.item label="1680 x 1050 (8:5 WSXGA+)" name="item10"/>
+ <combo_box.item label="1920 x 1080 (16:9 HDTV)" name="item11"/>
+ <combo_box.item label="1920 x 1200 (8:5 WUXGA)" name="item12"/>
</combo_box>
<button label="設定" name="set_btn"/>
<button label="キャンセル" name="cancel_btn"/>
diff --git a/indra/newview/skins/default/xui/ja/floater_world_map.xml b/indra/newview/skins/default/xui/ja/floater_world_map.xml
index cc07596adc..cc07596adc 100644..100755
--- a/indra/newview/skins/default/xui/ja/floater_world_map.xml
+++ b/indra/newview/skins/default/xui/ja/floater_world_map.xml
diff --git a/indra/newview/skins/default/xui/ja/inspect_avatar.xml b/indra/newview/skins/default/xui/ja/inspect_avatar.xml
index 42b67cd333..42b67cd333 100644..100755
--- a/indra/newview/skins/default/xui/ja/inspect_avatar.xml
+++ b/indra/newview/skins/default/xui/ja/inspect_avatar.xml
diff --git a/indra/newview/skins/default/xui/ja/inspect_group.xml b/indra/newview/skins/default/xui/ja/inspect_group.xml
index be628befdf..be628befdf 100644..100755
--- a/indra/newview/skins/default/xui/ja/inspect_group.xml
+++ b/indra/newview/skins/default/xui/ja/inspect_group.xml
diff --git a/indra/newview/skins/default/xui/ja/inspect_object.xml b/indra/newview/skins/default/xui/ja/inspect_object.xml
index e6999ac9b1..e6999ac9b1 100644..100755
--- a/indra/newview/skins/default/xui/ja/inspect_object.xml
+++ b/indra/newview/skins/default/xui/ja/inspect_object.xml
diff --git a/indra/newview/skins/default/xui/ja/inspect_remote_object.xml b/indra/newview/skins/default/xui/ja/inspect_remote_object.xml
index 483d3fec52..483d3fec52 100644..100755
--- a/indra/newview/skins/default/xui/ja/inspect_remote_object.xml
+++ b/indra/newview/skins/default/xui/ja/inspect_remote_object.xml
diff --git a/indra/newview/skins/default/xui/ja/language_settings.xml b/indra/newview/skins/default/xui/ja/language_settings.xml
index 91e8f4be7c..91e8f4be7c 100644..100755
--- a/indra/newview/skins/default/xui/ja/language_settings.xml
+++ b/indra/newview/skins/default/xui/ja/language_settings.xml
diff --git a/indra/newview/skins/default/xui/ja/menu_add_wearable_gear.xml b/indra/newview/skins/default/xui/ja/menu_add_wearable_gear.xml
index 982a03c6a8..982a03c6a8 100644..100755
--- a/indra/newview/skins/default/xui/ja/menu_add_wearable_gear.xml
+++ b/indra/newview/skins/default/xui/ja/menu_add_wearable_gear.xml
diff --git a/indra/newview/skins/default/xui/ja/menu_attachment_other.xml b/indra/newview/skins/default/xui/ja/menu_attachment_other.xml
index 5adf0b3745..930af10692 100644..100755
--- a/indra/newview/skins/default/xui/ja/menu_attachment_other.xml
+++ b/indra/newview/skins/default/xui/ja/menu_attachment_other.xml
@@ -11,7 +11,9 @@
<menu_item_call label="フリーズ" name="Freeze..."/>
<menu_item_call label="追放" name="Eject..."/>
<menu_item_call label="テクスãƒãƒ£ã®ãƒ‡ãƒãƒƒã‚°" name="Debug..."/>
+ <menu_item_call label="ダンプ XML" name="Dump XML"/>
<menu_item_call label="ズームイン" name="Zoom In"/>
<menu_item_call label="支払ã†" name="Pay..."/>
<menu_item_call label="オブジェクトã®ãƒ—ロフィール" name="Object Inspect"/>
+ <menu_item_call label="パーティクル所有者をブロック" name="Mute Particle"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/ja/menu_attachment_self.xml b/indra/newview/skins/default/xui/ja/menu_attachment_self.xml
index 6036e1075e..d87ef8e2a0 100644..100755
--- a/indra/newview/skins/default/xui/ja/menu_attachment_self.xml
+++ b/indra/newview/skins/default/xui/ja/menu_attachment_self.xml
@@ -12,5 +12,7 @@
<menu_item_call label="グループ" name="Groups..."/>
<menu_item_call label="プロフィール" name="Profile..."/>
<menu_item_call label="テクスãƒãƒ£ã®ãƒ‡ãƒãƒƒã‚°" name="Debug..."/>
+ <menu_item_call label="ダンプ XML" name="Dump XML"/>
<menu_item_call label="下ã«è½ã¨ã™" name="Drop"/>
+ <menu_item_call label="パーティクル所有者をブロック" name="Mute Particle"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/ja/menu_avatar_icon.xml b/indra/newview/skins/default/xui/ja/menu_avatar_icon.xml
index b04f602134..b04f602134 100644..100755
--- a/indra/newview/skins/default/xui/ja/menu_avatar_icon.xml
+++ b/indra/newview/skins/default/xui/ja/menu_avatar_icon.xml
diff --git a/indra/newview/skins/default/xui/ja/menu_avatar_other.xml b/indra/newview/skins/default/xui/ja/menu_avatar_other.xml
index 54dd96f5ef..f9cadc36ac 100644..100755
--- a/indra/newview/skins/default/xui/ja/menu_avatar_other.xml
+++ b/indra/newview/skins/default/xui/ja/menu_avatar_other.xml
@@ -11,6 +11,8 @@
<menu_item_call label="フリーズ" name="Freeze..."/>
<menu_item_call label="追放" name="Eject..."/>
<menu_item_call label="テクスãƒãƒ£ã®ãƒ‡ãƒãƒƒã‚°" name="Debug..."/>
+ <menu_item_call label="ダンプ XML" name="Dump XML"/>
<menu_item_call label="ズームイン" name="Zoom In"/>
<menu_item_call label="支払ã†" name="Pay..."/>
+ <menu_item_call label="パーティクル所有者をブロック" name="Mute Particle"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/ja/menu_avatar_self.xml b/indra/newview/skins/default/xui/ja/menu_avatar_self.xml
index 4709522665..eb8e98059a 100644..100755
--- a/indra/newview/skins/default/xui/ja/menu_avatar_self.xml
+++ b/indra/newview/skins/default/xui/ja/menu_avatar_self.xml
@@ -29,4 +29,6 @@
<menu_item_call label="グループ" name="Groups..."/>
<menu_item_call label="プロフィール" name="Profile..."/>
<menu_item_call label="テクスãƒãƒ£ã®ãƒ‡ãƒãƒƒã‚°" name="Debug..."/>
+ <menu_item_call label="ダンプ XML" name="Dump XML"/>
+ <menu_item_call label="パーティクル所有者をブロック" name="Mute Particle"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/ja/menu_bottomtray.xml b/indra/newview/skins/default/xui/ja/menu_bottomtray.xml
deleted file mode 100644
index 7f106c1ab5..0000000000
--- a/indra/newview/skins/default/xui/ja/menu_bottomtray.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<menu name="hide_camera_move_controls_menu">
- <menu_item_check label="スピーカーボタン" name="EnableVoiceChat"/>
- <menu_item_check label="ジェスãƒãƒ£ãƒ¼ãƒœã‚¿ãƒ³" name="ShowGestureButton"/>
- <menu_item_check label="移動ボタン" name="ShowMoveButton"/>
- <menu_item_check label="視界ボタン" name="ShowCameraButton"/>
- <menu_item_check label="スナップショットボタン" name="ShowSnapshotButton"/>
- <menu_item_check label="制作ボタン" name="ShowBuildButton"/>
- <menu_item_check label="検索ボタン" name="ShowSearchButton"/>
- <menu_item_check label="地図ボタン" name="ShowWorldMapButton"/>
- <menu_item_check label="ミニマップボタン" name="ShowMiniMapButton"/>
- <menu_item_call label="切りå–ã‚Š" name="NearbyChatBar_Cut"/>
- <menu_item_call label="コピー" name="NearbyChatBar_Copy"/>
- <menu_item_call label="貼り付ã‘" name="NearbyChatBar_Paste"/>
- <menu_item_call label="削除" name="NearbyChatBar_Delete"/>
- <menu_item_call label="ã™ã¹ã¦é¸æŠž" name="NearbyChatBar_Select_All"/>
-</menu>
diff --git a/indra/newview/skins/default/xui/ja/menu_cof_attachment.xml b/indra/newview/skins/default/xui/ja/menu_cof_attachment.xml
index e786d02e40..e786d02e40 100644..100755
--- a/indra/newview/skins/default/xui/ja/menu_cof_attachment.xml
+++ b/indra/newview/skins/default/xui/ja/menu_cof_attachment.xml
diff --git a/indra/newview/skins/default/xui/ja/menu_cof_body_part.xml b/indra/newview/skins/default/xui/ja/menu_cof_body_part.xml
index eb5faa2545..eb5faa2545 100644..100755
--- a/indra/newview/skins/default/xui/ja/menu_cof_body_part.xml
+++ b/indra/newview/skins/default/xui/ja/menu_cof_body_part.xml
diff --git a/indra/newview/skins/default/xui/ja/menu_cof_clothing.xml b/indra/newview/skins/default/xui/ja/menu_cof_clothing.xml
index d984342896..d984342896 100644..100755
--- a/indra/newview/skins/default/xui/ja/menu_cof_clothing.xml
+++ b/indra/newview/skins/default/xui/ja/menu_cof_clothing.xml
diff --git a/indra/newview/skins/default/xui/ja/menu_cof_gear.xml b/indra/newview/skins/default/xui/ja/menu_cof_gear.xml
index a071abbd2e..07bcefd9b3 100644..100755
--- a/indra/newview/skins/default/xui/ja/menu_cof_gear.xml
+++ b/indra/newview/skins/default/xui/ja/menu_cof_gear.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<menu name="Gear COF">
+<toggleable_menu name="Gear COF">
<menu label="衣類" name="COF.Gear.New_Clothes"/>
- <menu label="æ–°ã—ã„身体部ä½" name="COF.Geear.New_Body_Parts"/>
-</menu>
+ <menu label="æ–°ã—ã„身体部ä½" name="COF.Gear.New_Body_Parts"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/ja/menu_conversation.xml b/indra/newview/skins/default/xui/ja/menu_conversation.xml
new file mode 100644
index 0000000000..66940471da
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/menu_conversation.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_conversation_participant">
+ <menu_item_call label="会話を終ãˆã‚‹" name="close_conversation"/>
+ <menu_item_call label="ボイスãƒãƒ£ãƒƒãƒˆã‚’始ã‚ã‚‹" name="open_voice_conversation"/>
+ <menu_item_call label="ボイスãƒãƒ£ãƒƒãƒˆã‚’切断ã™ã‚‹" name="disconnect_from_voice"/>
+ <menu_item_call label="é¸æŠžã—ãŸé …目を閉ã˜ã‚‹" name="close_selected_conversations"/>
+ <menu_item_call label="プロフィールを表示" name="view_profile"/>
+ <menu_item_call label="IM" name="im"/>
+ <menu_item_call label="テレãƒãƒ¼ãƒˆã‚’é€ã‚‹" name="offer_teleport"/>
+ <menu_item_call label="ボイスコール" name="voice_call"/>
+ <menu_item_call label="ãƒãƒ£ãƒƒãƒˆã®å±¥æ­´..." name="chat_history"/>
+ <menu_item_call label="フレンドを追加" name="add_friend"/>
+ <menu_item_call label="フレンドを削除" name="remove_friend"/>
+ <menu_item_call label="フレンドを削除" name="remove_friends"/>
+ <menu_item_call label="グループã«æ‹›å¾…..." name="invite_to_group"/>
+ <menu_item_call label="ズームイン" name="zoom_in"/>
+ <menu_item_call label="地図" name="map"/>
+ <menu_item_call label="共有" name="share"/>
+ <menu_item_call label="支払ã„" name="pay"/>
+ <menu_item_check label="ボイスをブロック" name="block_unblock"/>
+ <menu_item_check label="文字をブロックã™ã‚‹" name="MuteText"/>
+ <menu_item_call label="グループ情報" name="group_profile"/>
+ <menu_item_call label="グループをアクティブã«ã™ã‚‹" name="activate_group"/>
+ <menu_item_call label="グループã‹ã‚‰è„±é€€ã™ã‚‹" name="leave_group"/>
+ <context_menu label="モデレーターã®ã‚ªãƒ—ション" name="Moderator Options">
+ <menu_item_check label="文字ãƒãƒ£ãƒƒãƒˆã‚’許å¯" name="AllowTextChat"/>
+ <menu_item_call label="ã“ã®å‚加者をミュートã™ã‚‹" name="ModerateVoiceMuteSelected"/>
+ <menu_item_call label="ã“ã®å‚加者ã®ãƒŸãƒ¥ãƒ¼ãƒˆã‚’解除ã™ã‚‹" name="ModerateVoiceUnMuteSelected"/>
+ <menu_item_call label="全員ã®éŸ³å£°ã‚’ミュートã™ã‚‹" name="ModerateVoiceMute"/>
+ <menu_item_call label="全員ã®ãƒŸãƒ¥ãƒ¼ãƒˆã‚’解除ã™ã‚‹" name="ModerateVoiceUnmute"/>
+ </context_menu>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/ja/menu_conversation_log_gear.xml b/indra/newview/skins/default/xui/ja/menu_conversation_log_gear.xml
new file mode 100644
index 0000000000..c9d4f947a4
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/menu_conversation_log_gear.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="Conversation Context Menu">
+ <menu_item_call label="IM..." name="IM"/>
+ <menu_item_call label="ボイスコール..." name="Call"/>
+ <menu_item_call label="ãƒãƒ£ãƒƒãƒˆã®å±¥æ­´ã‚’é–‹ã..." name="Chat history"/>
+ <menu_item_call label="プロフィールを表示" name="View Profile"/>
+ <menu_item_call label="テレãƒãƒ¼ãƒˆã‚’é€ã‚‹" name="teleport"/>
+ <menu_item_call label="フレンド登録" name="add_friend"/>
+ <menu_item_call label="フレンドを削除" name="remove_friend"/>
+ <menu_item_call label="グループã«æ‹›å¾…..." name="Invite"/>
+ <menu_item_call label="地図" name="Map"/>
+ <menu_item_call label="共有" name="Share"/>
+ <menu_item_call label="支払ã„" name="Pay"/>
+ <menu_item_check label="ブロック・ブロック解除" name="Block/Unblock"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/ja/menu_conversation_log_view.xml b/indra/newview/skins/default/xui/ja/menu_conversation_log_view.xml
new file mode 100644
index 0000000000..bd4812603f
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/menu_conversation_log_view.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_conversation_view">
+ <menu_item_check label="åå‰ã§ä¸¦ã¹æ›¿ãˆ" name="sort_by_name"/>
+ <menu_item_check label="日付ã§ä¸¦ã¹æ›¿ãˆ" name="sort_by_date"/>
+ <menu_item_check label="上ä½ã®ãƒ•ãƒ¬ãƒ³ãƒ‰ã‚’並ã¹æ›¿ãˆ" name="sort_by_friends"/>
+ <menu_item_call label="è¿‘ãã®ãƒãƒ£ãƒƒãƒˆã®å±¥æ­´ã‚’表示..." name="view_nearby_chat_history"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/ja/menu_edit.xml b/indra/newview/skins/default/xui/ja/menu_edit.xml
index c2ef0179b2..c2ef0179b2 100644..100755
--- a/indra/newview/skins/default/xui/ja/menu_edit.xml
+++ b/indra/newview/skins/default/xui/ja/menu_edit.xml
diff --git a/indra/newview/skins/default/xui/ja/menu_favorites.xml b/indra/newview/skins/default/xui/ja/menu_favorites.xml
index 4708b1446c..4708b1446c 100644..100755
--- a/indra/newview/skins/default/xui/ja/menu_favorites.xml
+++ b/indra/newview/skins/default/xui/ja/menu_favorites.xml
diff --git a/indra/newview/skins/default/xui/ja/menu_gesture_gear.xml b/indra/newview/skins/default/xui/ja/menu_gesture_gear.xml
index abf490a247..abf490a247 100644..100755
--- a/indra/newview/skins/default/xui/ja/menu_gesture_gear.xml
+++ b/indra/newview/skins/default/xui/ja/menu_gesture_gear.xml
diff --git a/indra/newview/skins/default/xui/ja/menu_group_plus.xml b/indra/newview/skins/default/xui/ja/menu_group_plus.xml
index 3787f7d645..3787f7d645 100644..100755
--- a/indra/newview/skins/default/xui/ja/menu_group_plus.xml
+++ b/indra/newview/skins/default/xui/ja/menu_group_plus.xml
diff --git a/indra/newview/skins/default/xui/ja/menu_hide_navbar.xml b/indra/newview/skins/default/xui/ja/menu_hide_navbar.xml
index 2e633ae1b2..2e633ae1b2 100644..100755
--- a/indra/newview/skins/default/xui/ja/menu_hide_navbar.xml
+++ b/indra/newview/skins/default/xui/ja/menu_hide_navbar.xml
diff --git a/indra/newview/skins/default/xui/ja/menu_im_conversation.xml b/indra/newview/skins/default/xui/ja/menu_im_conversation.xml
new file mode 100644
index 0000000000..55cd6610f7
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/menu_im_conversation.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="Conversation Gear Menu">
+ <menu_item_call label="プロフィールを表示" name="View Profile"/>
+ <menu_item_call label="フレンド登録" name="Add Friend"/>
+ <menu_item_call label="フレンドを削除" name="remove_friend"/>
+ <menu_item_call label="テレãƒãƒ¼ãƒˆã‚’é€ã‚‹" name="offer_teleport"/>
+ <menu_item_call label="グループã«æ‹›å¾…..." name="invite_to_group"/>
+ <menu_item_call label="ãƒãƒ£ãƒƒãƒˆã®å±¥æ­´..." name="chat_history"/>
+ <menu_item_call label="ズームイン" name="zoom_in"/>
+ <menu_item_call label="地図" name="map"/>
+ <menu_item_call label="共有" name="Share"/>
+ <menu_item_call label="支払ã„" name="Pay"/>
+ <menu_item_check label="ボイスをブロック" name="Block/Unblock"/>
+ <menu_item_check label="文字をブロックã™ã‚‹" name="MuteText"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/ja/menu_im_session_showmodes.xml b/indra/newview/skins/default/xui/ja/menu_im_session_showmodes.xml
new file mode 100644
index 0000000000..222a741718
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/menu_im_session_showmodes.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_modes">
+ <menu_item_check label="簡略表示" name="compact_view"/>
+ <menu_item_check label="詳細表示" name="expanded_view"/>
+ <menu_item_check label="時間を表示" name="IMShowTime"/>
+ <menu_item_check label="1対1ã®ä¼šè©±ã§åå‰ã‚’表示" name="IMShowNamesForP2PConv"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/ja/menu_im_well_button.xml b/indra/newview/skins/default/xui/ja/menu_im_well_button.xml
deleted file mode 100644
index 3397004bd7..0000000000
--- a/indra/newview/skins/default/xui/ja/menu_im_well_button.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<context_menu name="IM Well Button Context Menu">
- <menu_item_call label="ã™ã¹ã¦é–‰ã˜ã‚‹" name="Close All"/>
-</context_menu>
diff --git a/indra/newview/skins/default/xui/ja/menu_imchiclet_adhoc.xml b/indra/newview/skins/default/xui/ja/menu_imchiclet_adhoc.xml
index 8cd6fa4a27..8cd6fa4a27 100644..100755
--- a/indra/newview/skins/default/xui/ja/menu_imchiclet_adhoc.xml
+++ b/indra/newview/skins/default/xui/ja/menu_imchiclet_adhoc.xml
diff --git a/indra/newview/skins/default/xui/ja/menu_imchiclet_group.xml b/indra/newview/skins/default/xui/ja/menu_imchiclet_group.xml
index 5bcb96f083..5bcb96f083 100644..100755
--- a/indra/newview/skins/default/xui/ja/menu_imchiclet_group.xml
+++ b/indra/newview/skins/default/xui/ja/menu_imchiclet_group.xml
diff --git a/indra/newview/skins/default/xui/ja/menu_imchiclet_p2p.xml b/indra/newview/skins/default/xui/ja/menu_imchiclet_p2p.xml
index 5453f998fa..5453f998fa 100644..100755
--- a/indra/newview/skins/default/xui/ja/menu_imchiclet_p2p.xml
+++ b/indra/newview/skins/default/xui/ja/menu_imchiclet_p2p.xml
diff --git a/indra/newview/skins/default/xui/ja/menu_inspect_avatar_gear.xml b/indra/newview/skins/default/xui/ja/menu_inspect_avatar_gear.xml
index 9d0d0f10a6..9d0d0f10a6 100644..100755
--- a/indra/newview/skins/default/xui/ja/menu_inspect_avatar_gear.xml
+++ b/indra/newview/skins/default/xui/ja/menu_inspect_avatar_gear.xml
diff --git a/indra/newview/skins/default/xui/ja/menu_inspect_object_gear.xml b/indra/newview/skins/default/xui/ja/menu_inspect_object_gear.xml
index 5a0519ba19..5a0519ba19 100644..100755
--- a/indra/newview/skins/default/xui/ja/menu_inspect_object_gear.xml
+++ b/indra/newview/skins/default/xui/ja/menu_inspect_object_gear.xml
diff --git a/indra/newview/skins/default/xui/ja/menu_inspect_self_gear.xml b/indra/newview/skins/default/xui/ja/menu_inspect_self_gear.xml
index e3e206f3aa..e3e206f3aa 100644..100755
--- a/indra/newview/skins/default/xui/ja/menu_inspect_self_gear.xml
+++ b/indra/newview/skins/default/xui/ja/menu_inspect_self_gear.xml
diff --git a/indra/newview/skins/default/xui/ja/menu_inv_offer_chiclet.xml b/indra/newview/skins/default/xui/ja/menu_inv_offer_chiclet.xml
index 9a4a8138f5..9a4a8138f5 100644..100755
--- a/indra/newview/skins/default/xui/ja/menu_inv_offer_chiclet.xml
+++ b/indra/newview/skins/default/xui/ja/menu_inv_offer_chiclet.xml
diff --git a/indra/newview/skins/default/xui/ja/menu_inventory.xml b/indra/newview/skins/default/xui/ja/menu_inventory.xml
index d1893a0fc8..106b09453a 100644..100755
--- a/indra/newview/skins/default/xui/ja/menu_inventory.xml
+++ b/indra/newview/skins/default/xui/ja/menu_inventory.xml
@@ -68,6 +68,7 @@
<menu_item_call label="システムフォルダを削除ã™ã‚‹" name="Delete System Folder"/>
<menu_item_call label="コンファレンスãƒãƒ£ãƒƒãƒˆã‚’開始ã™ã‚‹" name="Conference Chat Folder"/>
<menu_item_call label="å†ç”Ÿã™ã‚‹" name="Sound Play"/>
+ <menu_item_call label="SLurl をコピー" name="url_copy"/>
<menu_item_call label="ランドマークã®æƒ…å ±" name="About Landmark"/>
<menu_item_call label="インワールドã§å†ç”Ÿã™ã‚‹" name="Animation Play"/>
<menu_item_call label="ローカルã§å†ç”Ÿã™ã‚‹" name="Animation Audition"/>
diff --git a/indra/newview/skins/default/xui/ja/menu_inventory_add.xml b/indra/newview/skins/default/xui/ja/menu_inventory_add.xml
index ae5ddbb78f..ae5ddbb78f 100644..100755
--- a/indra/newview/skins/default/xui/ja/menu_inventory_add.xml
+++ b/indra/newview/skins/default/xui/ja/menu_inventory_add.xml
diff --git a/indra/newview/skins/default/xui/ja/menu_inventory_gear_default.xml b/indra/newview/skins/default/xui/ja/menu_inventory_gear_default.xml
index f38dbc71a8..f38dbc71a8 100644..100755
--- a/indra/newview/skins/default/xui/ja/menu_inventory_gear_default.xml
+++ b/indra/newview/skins/default/xui/ja/menu_inventory_gear_default.xml
diff --git a/indra/newview/skins/default/xui/ja/menu_land.xml b/indra/newview/skins/default/xui/ja/menu_land.xml
index 89c122f14f..3754bd7fa4 100644..100755
--- a/indra/newview/skins/default/xui/ja/menu_land.xml
+++ b/indra/newview/skins/default/xui/ja/menu_land.xml
@@ -6,4 +6,5 @@
<menu_item_call label="入場許å¯ã‚’購入" name="Land Buy Pass"/>
<menu_item_call label="制作" name="Create"/>
<menu_item_call label="地形を編集" name="Edit Terrain"/>
+ <menu_item_call label="パーティクル所有者をブロック" name="Mute Particle"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/ja/menu_landmark.xml b/indra/newview/skins/default/xui/ja/menu_landmark.xml
index c134422955..c134422955 100644..100755
--- a/indra/newview/skins/default/xui/ja/menu_landmark.xml
+++ b/indra/newview/skins/default/xui/ja/menu_landmark.xml
diff --git a/indra/newview/skins/default/xui/ja/menu_login.xml b/indra/newview/skins/default/xui/ja/menu_login.xml
index ab6d9e3546..3918732fa8 100644..100755
--- a/indra/newview/skins/default/xui/ja/menu_login.xml
+++ b/indra/newview/skins/default/xui/ja/menu_login.xml
@@ -18,7 +18,13 @@
<menu_item_call label="利用è¦ç´„を表示" name="TOS"/>
<menu_item_call label="クリティカルメッセージを表示" name="Critical"/>
<menu_item_call label="Web コンテンツフローターã®ãƒ‡ãƒãƒƒã‚°ãƒ†ã‚¹ãƒˆ" name="Web Content Floater Debug Test"/>
- <menu label="ログレベルを設定" name="Set Logging Level"/>
+ <menu label="ログレベルを設定" name="Set Logging Level">
+ <menu_item_check label="デãƒãƒƒã‚°" name="Debug"/>
+ <menu_item_check label="情報" name="Info"/>
+ <menu_item_check label="警告" name="Warning"/>
+ <menu_item_check label="エラー" name="Error"/>
+ <menu_item_check label="ãªã—" name="None"/>
+ </menu>
<menu_item_check label="グリッドピッカーを表示ã™ã‚‹" name="Show Grid Picker"/>
<menu_item_call label="通知コンソールを表示ã™ã‚‹" name="Show Notifications Console"/>
</menu>
diff --git a/indra/newview/skins/default/xui/ja/menu_media_ctrl.xml b/indra/newview/skins/default/xui/ja/menu_media_ctrl.xml
index faae4ef717..faae4ef717 100644..100755
--- a/indra/newview/skins/default/xui/ja/menu_media_ctrl.xml
+++ b/indra/newview/skins/default/xui/ja/menu_media_ctrl.xml
diff --git a/indra/newview/skins/default/xui/ja/menu_mini_map.xml b/indra/newview/skins/default/xui/ja/menu_mini_map.xml
index 2e733ee24b..2e733ee24b 100644..100755
--- a/indra/newview/skins/default/xui/ja/menu_mini_map.xml
+++ b/indra/newview/skins/default/xui/ja/menu_mini_map.xml
diff --git a/indra/newview/skins/default/xui/ja/menu_mode_change.xml b/indra/newview/skins/default/xui/ja/menu_mode_change.xml
deleted file mode 100644
index dff3392bd5..0000000000
--- a/indra/newview/skins/default/xui/ja/menu_mode_change.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<toggleable_menu name="Mode Change">
- <menu_item_check label="ベーシック" name="BasicMode"/>
- <menu_item_check label="アドãƒãƒ³ã‚¹" name="AdvancedMode"/>
-</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/ja/menu_model_import_gear_default.xml b/indra/newview/skins/default/xui/ja/menu_model_import_gear_default.xml
index 43f86e84bf..43f86e84bf 100644..100755
--- a/indra/newview/skins/default/xui/ja/menu_model_import_gear_default.xml
+++ b/indra/newview/skins/default/xui/ja/menu_model_import_gear_default.xml
diff --git a/indra/newview/skins/default/xui/ja/menu_mute_particle.xml b/indra/newview/skins/default/xui/ja/menu_mute_particle.xml
new file mode 100644
index 0000000000..8dab025309
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/menu_mute_particle.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<!-- *NOTE: See also menu_attachment_other.xml -->
+<context_menu name="Mute Particle Pie">
+ <menu_item_call label="パーティクル所有者をブロック" name="Mute Particle"/>
+</context_menu>
diff --git a/indra/newview/skins/default/xui/ja/menu_navbar.xml b/indra/newview/skins/default/xui/ja/menu_navbar.xml
index 9ae2e58198..9ae2e58198 100644..100755
--- a/indra/newview/skins/default/xui/ja/menu_navbar.xml
+++ b/indra/newview/skins/default/xui/ja/menu_navbar.xml
diff --git a/indra/newview/skins/default/xui/ja/menu_nearby_chat.xml b/indra/newview/skins/default/xui/ja/menu_nearby_chat.xml
index c2e4a27686..c2e4a27686 100644..100755
--- a/indra/newview/skins/default/xui/ja/menu_nearby_chat.xml
+++ b/indra/newview/skins/default/xui/ja/menu_nearby_chat.xml
diff --git a/indra/newview/skins/default/xui/ja/menu_notification_well_button.xml b/indra/newview/skins/default/xui/ja/menu_notification_well_button.xml
index 913bae8958..913bae8958 100644..100755
--- a/indra/newview/skins/default/xui/ja/menu_notification_well_button.xml
+++ b/indra/newview/skins/default/xui/ja/menu_notification_well_button.xml
diff --git a/indra/newview/skins/default/xui/ja/menu_object.xml b/indra/newview/skins/default/xui/ja/menu_object.xml
index 4cee8089ee..39c32bc41e 100644..100755
--- a/indra/newview/skins/default/xui/ja/menu_object.xml
+++ b/indra/newview/skins/default/xui/ja/menu_object.xml
@@ -10,6 +10,8 @@
<menu_item_call label="ç«‹ã¡ä¸ŠãŒã‚‹" name="Object Stand Up"/>
<menu_item_call label="オブジェクトã®ãƒ—ロフィール" name="Object Inspect"/>
<menu_item_call label="ズームイン" name="Zoom In"/>
+ <menu_item_call label="リンクセットã§è¡¨ç¤º" name="show_in_linksets"/>
+ <menu_item_call label="キャラクターã§è¡¨ç¤º" name="show_in_characters"/>
<context_menu label="装ç€" name="Put On">
<menu_item_call label="装ç€" name="Wear"/>
<menu_item_call label="追加" name="Add"/>
@@ -26,4 +28,5 @@
<menu_item_call label="支払ã†" name="Pay..."/>
<menu_item_call label="è²·ã†" name="Buy..."/>
<menu_item_call label="削除" name="Delete"/>
+ <menu_item_call label="パーティクル所有者をブロック" name="Mute Particle"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/ja/menu_object_icon.xml b/indra/newview/skins/default/xui/ja/menu_object_icon.xml
index 8c4f328661..6448e9244e 100644..100755
--- a/indra/newview/skins/default/xui/ja/menu_object_icon.xml
+++ b/indra/newview/skins/default/xui/ja/menu_object_icon.xml
@@ -2,4 +2,6 @@
<menu name="Object Icon Menu">
<menu_item_call label="オブジェクトã®ãƒ—ロフィール..." name="Object Profile"/>
<menu_item_call label="ブロック..." name="Block"/>
+ <menu_item_call label="地図ã«è¡¨ç¤º" name="show_on_map"/>
+ <menu_item_call label="オブジェクトã®å ´æ‰€ã«ãƒ†ãƒ¬ãƒãƒ¼ãƒˆ" name="teleport_to_object"/>
</menu>
diff --git a/indra/newview/skins/default/xui/ja/menu_outfit_gear.xml b/indra/newview/skins/default/xui/ja/menu_outfit_gear.xml
index 2bcbe1915b..1969ae2a10 100644..100755
--- a/indra/newview/skins/default/xui/ja/menu_outfit_gear.xml
+++ b/indra/newview/skins/default/xui/ja/menu_outfit_gear.xml
@@ -23,6 +23,8 @@
<menu_item_call label="髪" name="New Hair"/>
<menu_item_call label="ç›®" name="New Eyes"/>
</menu>
+ <menu_item_call label="フォルダをã™ã¹ã¦é–‹ã" name="expand"/>
+ <menu_item_call label="フォルダをã™ã¹ã¦é–‰ã˜ã‚‹" name="collapse"/>
<menu_item_call label="アウトフィットã®åå‰ã‚’変更ã™ã‚‹" name="rename"/>
<menu_item_call label="アウトフィットを削除ã™ã‚‹" name="delete_outfit"/>
</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/ja/menu_outfit_tab.xml b/indra/newview/skins/default/xui/ja/menu_outfit_tab.xml
index 9491c22f31..9491c22f31 100644..100755
--- a/indra/newview/skins/default/xui/ja/menu_outfit_tab.xml
+++ b/indra/newview/skins/default/xui/ja/menu_outfit_tab.xml
diff --git a/indra/newview/skins/default/xui/ja/menu_participant_list.xml b/indra/newview/skins/default/xui/ja/menu_participant_list.xml
index 64d8ded722..64d8ded722 100644..100755
--- a/indra/newview/skins/default/xui/ja/menu_participant_list.xml
+++ b/indra/newview/skins/default/xui/ja/menu_participant_list.xml
diff --git a/indra/newview/skins/default/xui/ja/menu_participant_view.xml b/indra/newview/skins/default/xui/ja/menu_participant_view.xml
new file mode 100644
index 0000000000..5816351d9d
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/menu_participant_view.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="participant_manu_view">
+ <menu_item_check label="会話をタイプã§ä¸¦ã¹æ›¿ãˆ" name="sort_sessions_by_type"/>
+ <menu_item_check label="会話をåå‰ã§ä¸¦ã¹æ›¿ãˆ" name="sort_sessions_by_name"/>
+ <menu_item_check label="会話を最新アクティビティã§ä¸¦ã¹æ›¿ãˆ" name="sort_sessions_by_recent"/>
+ <menu_item_check label="å‚加者をåå‰ã§ä¸¦ã¹æ›¿ãˆ" name="sort_participants_by_name"/>
+ <menu_item_check label="å‚加者を最新アクティビティã§ä¸¦ã¹æ›¿ãˆ" name="sort_participants_by_recent"/>
+ <menu_item_call label="ãƒãƒ£ãƒƒãƒˆã®ç’°å¢ƒè¨­å®š..." name="chat_preferences"/>
+ <menu_item_call label="プライãƒã‚·ãƒ¼ã®ç’°å¢ƒè¨­å®š..." name="privacy_preferences"/>
+ <menu_item_check label="会話ログ..." name="Conversation"/>
+ <menu_item_check label="è¿‘ãã®ãƒãƒ£ãƒƒãƒˆã‚’翻訳" name="Translate_chat"/>
+ <menu_item_check label="翻訳ã®è¨­å®š..." name="Translation_settings"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/ja/menu_people_blocked_gear.xml b/indra/newview/skins/default/xui/ja/menu_people_blocked_gear.xml
new file mode 100644
index 0000000000..b5c9d11e02
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/menu_people_blocked_gear.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_blocked_gear">
+ <menu_item_call label="ブロック解除" name="unblock"/>
+ <menu_item_call label="プロフィール..." name="profile"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/ja/menu_people_blocked_plus.xml b/indra/newview/skins/default/xui/ja/menu_people_blocked_plus.xml
new file mode 100644
index 0000000000..3e74b2ddff
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/menu_people_blocked_plus.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_blocked_plus">
+ <menu_item_call label="åå‰ã§ä½äººã‚’ブロック..." name="block_resident_by_name"/>
+ <menu_item_call label="åå‰ã§ã‚ªãƒ–ジェクトをブロック..." name="block_object_by_name"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/ja/menu_people_blocked_view.xml b/indra/newview/skins/default/xui/ja/menu_people_blocked_view.xml
new file mode 100644
index 0000000000..4b86a353f4
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/menu_people_blocked_view.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_blocked_view">
+ <menu_item_check label="åå‰ã§ä¸¦ã¹æ›¿ãˆ" name="sort_by_name"/>
+ <menu_item_check label="タイプã«ã‚ˆã‚‹ä¸¦ã¹æ›¿ãˆ" name="sort_by_type"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/ja/menu_people_friends_view.xml b/indra/newview/skins/default/xui/ja/menu_people_friends_view.xml
new file mode 100644
index 0000000000..b95d11fdbd
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/menu_people_friends_view.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_group_plus">
+ <menu_item_check label="åå‰ã§ä¸¦ã¹æ›¿ãˆ" name="sort_name"/>
+ <menu_item_check label="オンライン状æ³ã§ä¸¦ã¹æ›¿ãˆ" name="sort_status"/>
+ <menu_item_check label="人ã®ã‚¢ã‚¤ã‚³ãƒ³è¡¨ç¤º" name="view_icons"/>
+ <menu_item_check label="与ãˆã‚‰ã‚ŒãŸæ¨©é™ã‚’表示" name="view_permissions"/>
+ <menu_item_check label="会話ログを表示..." name="view_conversation"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/ja/menu_people_friends_view_sort.xml b/indra/newview/skins/default/xui/ja/menu_people_friends_view_sort.xml
index 76340e4d76..76340e4d76 100644..100755
--- a/indra/newview/skins/default/xui/ja/menu_people_friends_view_sort.xml
+++ b/indra/newview/skins/default/xui/ja/menu_people_friends_view_sort.xml
diff --git a/indra/newview/skins/default/xui/ja/menu_people_groups.xml b/indra/newview/skins/default/xui/ja/menu_people_groups.xml
index 842d79dc4b..2c0c85ba28 100644..100755
--- a/indra/newview/skins/default/xui/ja/menu_people_groups.xml
+++ b/indra/newview/skins/default/xui/ja/menu_people_groups.xml
@@ -2,7 +2,7 @@
<menu name="menu_group_plus">
<menu_item_call label="情報を表示" name="View Info"/>
<menu_item_call label="ãƒãƒ£ãƒƒãƒˆ" name="Chat"/>
- <menu_item_call label="コール" name="Call"/>
+ <menu_item_call label="ボイスコール" name="Call"/>
<menu_item_call label="アクティブ" name="Activate"/>
<menu_item_call label="脱退" name="Leave"/>
</menu>
diff --git a/indra/newview/skins/default/xui/ja/menu_people_groups_view.xml b/indra/newview/skins/default/xui/ja/menu_people_groups_view.xml
new file mode 100644
index 0000000000..4a9e402fa4
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/menu_people_groups_view.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_group_plus">
+ <menu_item_check label="グループアイコンを表示" name="Display Group Icons"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/ja/menu_people_groups_view_sort.xml b/indra/newview/skins/default/xui/ja/menu_people_groups_view_sort.xml
index bfc7d15017..bfc7d15017 100644..100755
--- a/indra/newview/skins/default/xui/ja/menu_people_groups_view_sort.xml
+++ b/indra/newview/skins/default/xui/ja/menu_people_groups_view_sort.xml
diff --git a/indra/newview/skins/default/xui/ja/menu_people_nearby.xml b/indra/newview/skins/default/xui/ja/menu_people_nearby.xml
index 8d84b0e521..972ab767bf 100644..100755
--- a/indra/newview/skins/default/xui/ja/menu_people_nearby.xml
+++ b/indra/newview/skins/default/xui/ja/menu_people_nearby.xml
@@ -1,13 +1,16 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Avatar Context Menu">
- <menu_item_call label="プロフィールã®è¡¨ç¤º" name="View Profile"/>
- <menu_item_call label="フレンド登録" name="Add Friend"/>
- <menu_item_call label="フレンドを削除" name="Remove Friend"/>
- <menu_item_call label="IM" name="IM"/>
- <menu_item_call label="コール" name="Call"/>
- <menu_item_call label="地図" name="Map"/>
- <menu_item_call label="共有" name="Share"/>
- <menu_item_call label="支払ã†" name="Pay"/>
- <menu_item_check label="ブロック・ブロック解除" name="Block/Unblock"/>
- <menu_item_call label="テレãƒãƒ¼ãƒˆã‚’é€ã‚‹" name="teleport"/>
+ <menu_item_call label="プロフィールを表示" name="view_profile"/>
+ <menu_item_call label="IM" name="im"/>
+ <menu_item_call label="テレãƒãƒ¼ãƒˆã‚’é€ã‚‹" name="offer_teleport"/>
+ <menu_item_call label="ボイスコール" name="voice_call"/>
+ <menu_item_call label="ãƒãƒ£ãƒƒãƒˆã®å±¥æ­´ã‚’表示..." name="chat_history"/>
+ <menu_item_call label="フレンド登録" name="add_friend"/>
+ <menu_item_call label="フレンドを削除" name="remove_friend"/>
+ <menu_item_call label="グループã«æ‹›å¾…..." name="invite_to_group"/>
+ <menu_item_call label="ズームイン" name="zoom_in"/>
+ <menu_item_call label="地図" name="map"/>
+ <menu_item_call label="共有" name="share"/>
+ <menu_item_call label="支払ã„" name="pay"/>
+ <menu_item_check label="ブロック・ブロック解除" name="block_unblock"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/ja/menu_people_nearby_multiselect.xml b/indra/newview/skins/default/xui/ja/menu_people_nearby_multiselect.xml
index 3f20e5d3ab..fe85e278cf 100644..100755
--- a/indra/newview/skins/default/xui/ja/menu_people_nearby_multiselect.xml
+++ b/indra/newview/skins/default/xui/ja/menu_people_nearby_multiselect.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Multi-Selected People Context Menu">
- <menu_item_call label="フレンド登録" name="Add Friends"/>
- <menu_item_call label="フレンドを削除" name="Remove Friend"/>
- <menu_item_call label="IM" name="IM"/>
- <menu_item_call label="コール" name="Call"/>
- <menu_item_call label="共有" name="Share"/>
- <menu_item_call label="支払ã†" name="Pay"/>
- <menu_item_call label="テレãƒãƒ¼ãƒˆã‚’é€ã‚‹" name="teleport"/>
+ <menu_item_call label="フレンド登録" name="add_friends"/>
+ <menu_item_call label="フレンドを削除" name="remove_friends"/>
+ <menu_item_call label="IM" name="im"/>
+ <menu_item_call label="コール" name="call"/>
+ <menu_item_call label="共有" name="share"/>
+ <menu_item_call label="支払ã„" name="pay"/>
+ <menu_item_call label="テレãƒãƒ¼ãƒˆã‚’é€ã‚‹" name="offer_teleport"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/ja/menu_people_nearby_view.xml b/indra/newview/skins/default/xui/ja/menu_people_nearby_view.xml
new file mode 100644
index 0000000000..b7cccc4396
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/menu_people_nearby_view.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_group_plus">
+ <menu_item_check label="最近ã®ç™ºè¨€è€…ã§ä¸¦ã¹æ›¿ãˆ" name="sort_by_recent_speakers"/>
+ <menu_item_check label="åå‰ã§ä¸¦ã¹æ›¿ãˆ" name="sort_name"/>
+ <menu_item_check label="è·é›¢ã§ä¸¦ã¹æ›¿ãˆ" name="sort_distance"/>
+ <menu_item_check label="人ã®ã‚¢ã‚¤ã‚³ãƒ³è¡¨ç¤º" name="view_icons"/>
+ <menu_item_check label="地図を表示" name="view_map"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/ja/menu_people_nearby_view_sort.xml b/indra/newview/skins/default/xui/ja/menu_people_nearby_view_sort.xml
index 44c5438509..44c5438509 100644..100755
--- a/indra/newview/skins/default/xui/ja/menu_people_nearby_view_sort.xml
+++ b/indra/newview/skins/default/xui/ja/menu_people_nearby_view_sort.xml
diff --git a/indra/newview/skins/default/xui/ja/menu_people_recent_view.xml b/indra/newview/skins/default/xui/ja/menu_people_recent_view.xml
new file mode 100644
index 0000000000..feaeba4398
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/menu_people_recent_view.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_group_plus">
+ <menu_item_check label="æ–°ã—ã„é †ã«ä¸¦ã¹æ›¿ãˆ" name="sort_most"/>
+ <menu_item_check label="åå‰ã§ä¸¦ã¹æ›¿ãˆ" name="sort_name"/>
+ <menu_item_check label="人ã®ã‚¢ã‚¤ã‚³ãƒ³è¡¨ç¤º" name="view_icons"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/ja/menu_people_recent_view_sort.xml b/indra/newview/skins/default/xui/ja/menu_people_recent_view_sort.xml
index b4f177a068..b4f177a068 100644..100755
--- a/indra/newview/skins/default/xui/ja/menu_people_recent_view_sort.xml
+++ b/indra/newview/skins/default/xui/ja/menu_people_recent_view_sort.xml
diff --git a/indra/newview/skins/default/xui/ja/menu_picks.xml b/indra/newview/skins/default/xui/ja/menu_picks.xml
index 011d3d2526..011d3d2526 100644..100755
--- a/indra/newview/skins/default/xui/ja/menu_picks.xml
+++ b/indra/newview/skins/default/xui/ja/menu_picks.xml
diff --git a/indra/newview/skins/default/xui/ja/menu_picks_plus.xml b/indra/newview/skins/default/xui/ja/menu_picks_plus.xml
index 84bf90fea0..84bf90fea0 100644..100755
--- a/indra/newview/skins/default/xui/ja/menu_picks_plus.xml
+++ b/indra/newview/skins/default/xui/ja/menu_picks_plus.xml
diff --git a/indra/newview/skins/default/xui/ja/menu_place.xml b/indra/newview/skins/default/xui/ja/menu_place.xml
index a9f05e126d..a9f05e126d 100644..100755
--- a/indra/newview/skins/default/xui/ja/menu_place.xml
+++ b/indra/newview/skins/default/xui/ja/menu_place.xml
diff --git a/indra/newview/skins/default/xui/ja/menu_place_add_button.xml b/indra/newview/skins/default/xui/ja/menu_place_add_button.xml
index d5ce88b055..d5ce88b055 100644..100755
--- a/indra/newview/skins/default/xui/ja/menu_place_add_button.xml
+++ b/indra/newview/skins/default/xui/ja/menu_place_add_button.xml
diff --git a/indra/newview/skins/default/xui/ja/menu_places_gear_folder.xml b/indra/newview/skins/default/xui/ja/menu_places_gear_folder.xml
index c455204722..c455204722 100644..100755
--- a/indra/newview/skins/default/xui/ja/menu_places_gear_folder.xml
+++ b/indra/newview/skins/default/xui/ja/menu_places_gear_folder.xml
diff --git a/indra/newview/skins/default/xui/ja/menu_places_gear_landmark.xml b/indra/newview/skins/default/xui/ja/menu_places_gear_landmark.xml
index 579f2c2cbd..579f2c2cbd 100644..100755
--- a/indra/newview/skins/default/xui/ja/menu_places_gear_landmark.xml
+++ b/indra/newview/skins/default/xui/ja/menu_places_gear_landmark.xml
diff --git a/indra/newview/skins/default/xui/ja/menu_profile_overflow.xml b/indra/newview/skins/default/xui/ja/menu_profile_overflow.xml
index 9d3a5dda1c..9d3a5dda1c 100644..100755
--- a/indra/newview/skins/default/xui/ja/menu_profile_overflow.xml
+++ b/indra/newview/skins/default/xui/ja/menu_profile_overflow.xml
diff --git a/indra/newview/skins/default/xui/ja/menu_save_outfit.xml b/indra/newview/skins/default/xui/ja/menu_save_outfit.xml
index 6513d9264a..6513d9264a 100644..100755
--- a/indra/newview/skins/default/xui/ja/menu_save_outfit.xml
+++ b/indra/newview/skins/default/xui/ja/menu_save_outfit.xml
diff --git a/indra/newview/skins/default/xui/ja/menu_script_chiclet.xml b/indra/newview/skins/default/xui/ja/menu_script_chiclet.xml
index a89dd0bcbe..a89dd0bcbe 100644..100755
--- a/indra/newview/skins/default/xui/ja/menu_script_chiclet.xml
+++ b/indra/newview/skins/default/xui/ja/menu_script_chiclet.xml
diff --git a/indra/newview/skins/default/xui/ja/menu_slurl.xml b/indra/newview/skins/default/xui/ja/menu_slurl.xml
index 61ba3085d9..61ba3085d9 100644..100755
--- a/indra/newview/skins/default/xui/ja/menu_slurl.xml
+++ b/indra/newview/skins/default/xui/ja/menu_slurl.xml
diff --git a/indra/newview/skins/default/xui/ja/menu_teleport_history_gear.xml b/indra/newview/skins/default/xui/ja/menu_teleport_history_gear.xml
index 901eab9166..901eab9166 100644..100755
--- a/indra/newview/skins/default/xui/ja/menu_teleport_history_gear.xml
+++ b/indra/newview/skins/default/xui/ja/menu_teleport_history_gear.xml
diff --git a/indra/newview/skins/default/xui/ja/menu_teleport_history_item.xml b/indra/newview/skins/default/xui/ja/menu_teleport_history_item.xml
index 66bc32214f..66bc32214f 100644..100755
--- a/indra/newview/skins/default/xui/ja/menu_teleport_history_item.xml
+++ b/indra/newview/skins/default/xui/ja/menu_teleport_history_item.xml
diff --git a/indra/newview/skins/default/xui/ja/menu_teleport_history_tab.xml b/indra/newview/skins/default/xui/ja/menu_teleport_history_tab.xml
index 4dd44d2ec8..4dd44d2ec8 100644..100755
--- a/indra/newview/skins/default/xui/ja/menu_teleport_history_tab.xml
+++ b/indra/newview/skins/default/xui/ja/menu_teleport_history_tab.xml
diff --git a/indra/newview/skins/default/xui/ja/menu_text_editor.xml b/indra/newview/skins/default/xui/ja/menu_text_editor.xml
index fcb1038a6a..eda973c888 100644..100755
--- a/indra/newview/skins/default/xui/ja/menu_text_editor.xml
+++ b/indra/newview/skins/default/xui/ja/menu_text_editor.xml
@@ -1,5 +1,12 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Text editor context menu">
+ <menu_item_call label="(ä¸æ˜Žï¼‰" name="Suggestion 1"/>
+ <menu_item_call label="(ä¸æ˜Žï¼‰" name="Suggestion 2"/>
+ <menu_item_call label="(ä¸æ˜Žï¼‰" name="Suggestion 3"/>
+ <menu_item_call label="(ä¸æ˜Žï¼‰" name="Suggestion 4"/>
+ <menu_item_call label="(ä¸æ˜Žï¼‰" name="Suggestion 5"/>
+ <menu_item_call label="辞書ã«è¿½åŠ " name="Add to Dictionary"/>
+ <menu_item_call label="無視ã«è¿½åŠ " name="Add to Ignore"/>
<menu_item_call label="切りå–ã‚Š" name="Cut"/>
<menu_item_call label="コピー" name="Copy"/>
<menu_item_call label="貼り付ã‘" name="Paste"/>
diff --git a/indra/newview/skins/default/xui/ja/menu_toolbars.xml b/indra/newview/skins/default/xui/ja/menu_toolbars.xml
index d5363a5131..d5363a5131 100644..100755
--- a/indra/newview/skins/default/xui/ja/menu_toolbars.xml
+++ b/indra/newview/skins/default/xui/ja/menu_toolbars.xml
diff --git a/indra/newview/skins/default/xui/ja/menu_topinfobar.xml b/indra/newview/skins/default/xui/ja/menu_topinfobar.xml
index 1a67a2a8f7..1a67a2a8f7 100644..100755
--- a/indra/newview/skins/default/xui/ja/menu_topinfobar.xml
+++ b/indra/newview/skins/default/xui/ja/menu_topinfobar.xml
diff --git a/indra/newview/skins/default/xui/ja/menu_url_agent.xml b/indra/newview/skins/default/xui/ja/menu_url_agent.xml
index 92d118a5ae..639602ce3c 100644..100755
--- a/indra/newview/skins/default/xui/ja/menu_url_agent.xml
+++ b/indra/newview/skins/default/xui/ja/menu_url_agent.xml
@@ -1,6 +1,9 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Url Popup">
- <menu_item_call label="ä½äººã®ãƒ—ロフィールを表示" name="show_agent"/>
+ <menu_item_call label="プロフィールを表示" name="show_agent"/>
+ <menu_item_call label="IM ã‚’é€ä¿¡..." name="send_im"/>
+ <menu_item_call label="フレンドを追加..." name="add_friend"/>
+ <menu_item_call label="フレンドを削除..." name="remove_friend"/>
<menu_item_call label="åå‰ã‚’クリップボードã«ã‚³ãƒ”ー" name="url_copy_label"/>
<menu_item_call label="SLurl をクリップボードã«ã‚³ãƒ”ー" name="url_copy"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/ja/menu_url_group.xml b/indra/newview/skins/default/xui/ja/menu_url_group.xml
index 1dd3d79438..1dd3d79438 100644..100755
--- a/indra/newview/skins/default/xui/ja/menu_url_group.xml
+++ b/indra/newview/skins/default/xui/ja/menu_url_group.xml
diff --git a/indra/newview/skins/default/xui/ja/menu_url_http.xml b/indra/newview/skins/default/xui/ja/menu_url_http.xml
index c3da8a8686..c3da8a8686 100644..100755
--- a/indra/newview/skins/default/xui/ja/menu_url_http.xml
+++ b/indra/newview/skins/default/xui/ja/menu_url_http.xml
diff --git a/indra/newview/skins/default/xui/ja/menu_url_inventory.xml b/indra/newview/skins/default/xui/ja/menu_url_inventory.xml
index 147ab44a1b..147ab44a1b 100644..100755
--- a/indra/newview/skins/default/xui/ja/menu_url_inventory.xml
+++ b/indra/newview/skins/default/xui/ja/menu_url_inventory.xml
diff --git a/indra/newview/skins/default/xui/ja/menu_url_map.xml b/indra/newview/skins/default/xui/ja/menu_url_map.xml
index 8d41e1a571..8d41e1a571 100644..100755
--- a/indra/newview/skins/default/xui/ja/menu_url_map.xml
+++ b/indra/newview/skins/default/xui/ja/menu_url_map.xml
diff --git a/indra/newview/skins/default/xui/ja/menu_url_objectim.xml b/indra/newview/skins/default/xui/ja/menu_url_objectim.xml
index d6a048dcfc..a02ca8415d 100644..100755
--- a/indra/newview/skins/default/xui/ja/menu_url_objectim.xml
+++ b/indra/newview/skins/default/xui/ja/menu_url_objectim.xml
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Url Popup">
- <menu_item_call label="オブジェクトã®æƒ…報を表示" name="show_object"/>
+ <menu_item_call label="オブジェクトã®ãƒ—ロフィール..." name="show_object"/>
+ <menu_item_call label="ブロック..." name="block_object"/>
<menu_item_call label="地図ã«è¡¨ç¤º" name="show_on_map"/>
<menu_item_call label="オブジェクトã®å ´æ‰€ã«ãƒ†ãƒ¬ãƒãƒ¼ãƒˆ" name="teleport_to_object"/>
<menu_item_call label="オブジェクトåをクリップボードã«ã‚³ãƒ”ー" name="url_copy_label"/>
diff --git a/indra/newview/skins/default/xui/ja/menu_url_parcel.xml b/indra/newview/skins/default/xui/ja/menu_url_parcel.xml
index 8d264059d3..8d264059d3 100644..100755
--- a/indra/newview/skins/default/xui/ja/menu_url_parcel.xml
+++ b/indra/newview/skins/default/xui/ja/menu_url_parcel.xml
diff --git a/indra/newview/skins/default/xui/ja/menu_url_slapp.xml b/indra/newview/skins/default/xui/ja/menu_url_slapp.xml
index a516c5a075..a516c5a075 100644..100755
--- a/indra/newview/skins/default/xui/ja/menu_url_slapp.xml
+++ b/indra/newview/skins/default/xui/ja/menu_url_slapp.xml
diff --git a/indra/newview/skins/default/xui/ja/menu_url_slurl.xml b/indra/newview/skins/default/xui/ja/menu_url_slurl.xml
index 2c857ec915..2c857ec915 100644..100755
--- a/indra/newview/skins/default/xui/ja/menu_url_slurl.xml
+++ b/indra/newview/skins/default/xui/ja/menu_url_slurl.xml
diff --git a/indra/newview/skins/default/xui/ja/menu_url_teleport.xml b/indra/newview/skins/default/xui/ja/menu_url_teleport.xml
index c3507a9a33..c3507a9a33 100644..100755
--- a/indra/newview/skins/default/xui/ja/menu_url_teleport.xml
+++ b/indra/newview/skins/default/xui/ja/menu_url_teleport.xml
diff --git a/indra/newview/skins/default/xui/ja/menu_viewer.xml b/indra/newview/skins/default/xui/ja/menu_viewer.xml
index 8496dfb1db..b1ec62115c 100644..100755
--- a/indra/newview/skins/default/xui/ja/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/ja/menu_viewer.xml
@@ -17,8 +17,8 @@
<menu_item_call label="æ­©è¡Œï¼èµ°è¡Œï¼é£›è¡Œ..." name="Walk / run / fly"/>
</menu>
<menu label="ログイン" name="Status">
- <menu_item_call label="一時退席中" name="Set Away"/>
- <menu_item_call label="å–ã‚Šè¾¼ã¿ä¸­" name="Set Busy"/>
+ <menu_item_check label="一時退席中" name="Away"/>
+ <menu_item_check label="ç€ä¿¡æ‹’å¦" name="Do Not Disturb"/>
</menu>
<menu_item_call label="L$ ã®è³¼å…¥..." name="Buy and Sell L$"/>
<menu_item_call label="マーãƒãƒ£ãƒ³ãƒˆã‚¢ã‚¦ãƒˆãƒœãƒƒã‚¯ã‚¹..." name="MerchantOutbox"/>
@@ -28,17 +28,25 @@
<menu_item_call label="環境設定..." name="Preferences"/>
<menu_item_call label="ツールãƒãƒ¼ã®ãƒœã‚¿ãƒ³..." name="Toolbars"/>
<menu_item_call label="å…¨ã¦ã®ã‚³ãƒ³ãƒˆãƒ­ãƒ¼ãƒ«ã‚’éžè¡¨ç¤ºã«ã™ã‚‹" name="Hide UI"/>
+ <menu_item_check label="HUD を表示" name="Show HUD Attachments"/>
<menu_item_call label="[APP_NAME] を終了" name="Quit"/>
</menu>
<menu label="コミュニケーション" name="Communicate">
- <menu_item_check label="ãƒãƒ£ãƒƒãƒˆ..." name="Nearby Chat"/>
+ <menu_item_check label="会話..." name="Conversations"/>
+ <menu_item_check label="è¿‘ãã®ãƒãƒ£ãƒƒãƒˆ..." name="Nearby Chat"/>
<menu_item_check label="話ã™" name="Speak"/>
- <menu_item_check label="ボイス設定..." name="Nearby Voice"/>
- <menu_item_check label="ボイスモーフィング..." name="ShowVoice"/>
+ <menu_item_check label="会話ログ..." name="Conversation Log..."/>
+ <menu label="ボイスモーフィング" name="VoiceMorphing">
+ <menu_item_check label="ボイスモーフィングãªã—" name="NoVoiceMorphing"/>
+ <menu_item_check label="プレビュー..." name="Preview"/>
+ <menu_item_call label="申ã—込む..." name="Subscribe"/>
+ </menu>
<menu_item_check label="ジェスãƒãƒ£ãƒ¼..." name="Gestures"/>
- <menu_item_call label="フレンド" name="My Friends"/>
- <menu_item_call label="グループ" name="My Groups"/>
- <menu_item_call label="è¿‘ãã«ã„る人" name="Active Speakers"/>
+ <menu_item_check label="フレンド" name="My Friends"/>
+ <menu_item_check label="グループ" name="My Groups"/>
+ <menu_item_check label="è¿‘ãã«ã„る人" name="Active Speakers"/>
+ <menu_item_call label="リストをブロック" name="Block List"/>
+ <menu_item_check label="ç€ä¿¡æ‹’å¦" name="Do Not Disturb"/>
</menu>
<menu label="世界" name="World">
<menu_item_call label="ç¾åœ¨åœ°ã‚’ランドマーク" name="Create Landmark Here"/>
@@ -107,13 +115,13 @@
<menu_item_call label="次ã®éƒ¨åˆ†ã‚’å«ã‚ã‚‹" name="Include Next Part"/>
<menu_item_call label="å‰å›žã®éƒ¨åˆ†ã‚’å«ã‚ã‚‹" name="Include Previous Part"/>
</menu>
+ <menu_item_call label="リンクセット..." name="pathfinding_linkset_menu_item"/>
<menu_item_call label="é¸æŠžã—ãŸã‚‚ã®ã«ç„¦ç‚¹ã‚’åˆã‚ã›ã‚‹" name="Focus on Selection"/>
<menu_item_call label="é¸æŠžã—ãŸã‚‚ã®ã‚’ズームã™ã‚‹" name="Zoom to Selection"/>
<menu label="オブジェクト" name="Object">
<menu_item_call label="è²·ã†" name="Menu Object Buy"/>
<menu_item_call label="å–ã‚‹" name="Menu Object Take"/>
<menu_item_call label="コピーをå–ã‚‹" name="Take Copy"/>
- <menu_item_call label="マイインベントリã«ä¿å­˜" name="Save Object Back to My Inventory"/>
<menu_item_call label="オブジェクトã®ä¸­èº«ã«ä¿å­˜" name="Save Object Back to Object Contents"/>
<menu_item_call label="オブジェクトを返å´ã™ã‚‹" name="Return Object back to Owner"/>
</menu>
@@ -124,6 +132,12 @@
<menu_item_call label="スクリプトを実行中ã«ã™ã‚‹" name="Set Scripts to Running"/>
<menu_item_call label="スクリプトを実行åœæ­¢ã«ã™ã‚‹" name="Set Scripts to Not Running"/>
</menu>
+ <menu label="パスファインディング" name="Pathfinding">
+ <menu_item_call label="リンクセット..." name="pathfinding_linksets_menu_item"/>
+ <menu_item_call label="キャラクター..." name="pathfinding_characters_menu_item"/>
+ <menu_item_call label="表示/テスト..." name="pathfinding_console_menu_item"/>
+ <menu_item_call label="地域ã®å†æ§‹ç¯‰" name="pathfinding_rebake_navmesh_item"/>
+ </menu>
<menu label="オプション" name="Options">
<menu_item_check label="権é™ã®è©³ç´°ã‚’表示ã™ã‚‹" name="DebugPermissions"/>
<menu_item_check label="ç§ã®ã‚ªãƒ–ジェクトã ã‘ã‚’é¸æŠžã™ã‚‹" name="Select Only My Objects"/>
@@ -152,6 +166,13 @@
<menu label="ヘルプ" name="Help">
<menu_item_call label="ãƒã‚¦ãƒ„ー..." name="How To"/>
<menu_item_call label="[SECOND_LIFE] ヘルプ" name="Second Life Help"/>
+ <menu_item_call label="ユーザーガイド" name="User’s guide"/>
+ <menu_item_call label="ナレッジベース" name="Knowledge Base"/>
+ <menu_item_call label="Wiki" name="Wiki"/>
+ <menu_item_call label="コミュニティフォーラム" name="Community Forums"/>
+ <menu_item_call label="日本語サãƒãƒ¼ãƒˆãƒšãƒ¼ã‚¸" name="Support portal"/>
+ <menu_item_call label="[SECOND_LIFE] ニュース" name="Second Life News"/>
+ <menu_item_call label="[SECOND_LIFE] ブログ" name="Second Life Blogs"/>
<menu_item_call label="å«ŒãŒã‚‰ã›ã‚’報告ã™ã‚‹" name="Report Abuse"/>
<menu_item_call label="ãƒã‚°ã‚’報告ã™ã‚‹" name="Report Bug"/>
<menu_item_call label="[APP_NAME] ã«ã¤ã„ã¦" name="About Second Life"/>
@@ -174,7 +195,6 @@
<menu_item_check label="パーティクルをéžè¡¨ç¤ºã«ã™ã‚‹" name="Hide Particles"/>
<menu_item_check label="é¸æŠžã—ãŸã‚‚ã®ã‚’éžè¡¨ç¤ºã«ã™ã‚‹" name="Hide Selected"/>
<menu_item_check label="é€æ˜Žéƒ¨åˆ†ã‚’ãƒã‚¤ãƒ©ã‚¤ãƒˆã™ã‚‹" name="Highlight Transparent"/>
- <menu_item_check label="HUD を表示ã™ã‚‹" name="Show HUD Attachments"/>
<menu_item_check label="一人称視点ã®ã¨ãã«å字線を表示ã™ã‚‹" name="ShowCrosshairs"/>
</menu>
<menu label="レンダリング(種類)" name="Rendering Types">
@@ -227,11 +247,10 @@
<menu_item_check label="テクスãƒãƒ£ã®ã‚³ãƒ³ã‚½ãƒ¼ãƒ«" name="Texture Console"/>
<menu_item_check label="デãƒãƒƒã‚°ã‚³ãƒ³ã‚½ãƒ¼ãƒ«" name="Debug Console"/>
<menu_item_call label="通知コンソール" name="Notifications"/>
- <menu_item_check label="テクスãƒãƒ£ã‚µã‚¤ã‚ºã®ã‚³ãƒ³ã‚½ãƒ¼ãƒ«" name="Texture Size"/>
- <menu_item_check label="テクスãƒãƒ£ã‚«ãƒ†ã‚´ãƒªã®ã‚³ãƒ³ã‚½ãƒ¼ãƒ«" name="Texture Category"/>
<menu_item_check label="ファーストタイマー" name="Fast Timers"/>
<menu_item_check label="メモリ" name="Memory"/>
<menu_item_check label="風景ã®çµ±è¨ˆ" name="Scene Statistics"/>
+ <menu_item_call label="テクスãƒãƒ£å–得デãƒãƒƒã‚°ã‚³ãƒ³ã‚½ãƒ¼ãƒ«" name="Texture Fetch Debug Console"/>
<menu_item_call label="リージョン情報をデãƒãƒƒã‚°ã‚³ãƒ³ã‚½ãƒ¼ãƒ«ã¸" name="Region Info to Debug Console"/>
<menu_item_call label="グループ情報をデãƒãƒƒã‚°ã‚³ãƒ³ã‚½ãƒ¼ãƒ«ã¸" name="Group Info to Debug Console"/>
<menu_item_call label="性能情報をデãƒãƒƒã‚°ã‚³ãƒ³ã‚½ãƒ¼ãƒ«ã¸" name="Capabilities Info to Debug Console"/>
@@ -266,6 +285,7 @@
<menu_item_check label="フレームレートをランダム化" name="Randomize Framerate"/>
<menu_item_check label="定期的ã«é…ã„フレームを挿入ã™ã‚‹" name="Periodic Slow Frame"/>
<menu_item_check label="フレームテスト" name="Frame Test"/>
+ <menu_item_call label="フレームプロフィール" name="Frame Profile"/>
</menu>
<menu label="メタデータã®ãƒ¬ãƒ³ãƒ€ãƒ¼" name="Render Metadata">
<menu_item_check label="ãƒã‚¦ãƒ³ãƒ‡ã‚£ãƒ³ã‚°ãƒœãƒƒã‚¯ã‚¹" name="Bounding Boxes"/>
@@ -289,14 +309,21 @@
<menu_item_check label="æç”»ã®è©³ç´°åº¦" name="rendercomplexity"/>
<menu_item_check label="添付アイテムã®ãƒã‚¤ãƒˆæ•°" name="attachment bytes"/>
<menu_item_check label="スカルプト" name="Sculpt"/>
+ <menu label="テクスãƒãƒ£ã®å¯†åº¦" name="Texture Density">
+ <menu_item_check label="ãªã—" name="None"/>
+ <menu_item_check label="ç¾åœ¨" name="Current"/>
+ <menu_item_check label="望ã¾ã—ã„" name="Desired"/>
+ <menu_item_check label="フル" name="Full"/>
+ </menu>
</menu>
<menu label="レンダリング" name="Rendering">
<menu_item_check label="軸" name="Axes"/>
<menu_item_check label="接線基底" name="Tangent Basis"/>
<menu_item_call label="é¸æŠžã—ãŸãƒ†ã‚¯ã‚¹ãƒãƒ£æƒ…報基底" name="Selected Texture Info Basis"/>
+ <menu_item_call label="é¸æŠžã—ãŸãƒžãƒ†ãƒªã‚¢ãƒ«æƒ…å ±" name="Selected Material Info"/>
<menu_item_check label="ワイヤーフレーム" name="Wireframe"/>
<menu_item_check label="オブジェクト間オクルージョン" name="Object-Object Occlusion"/>
- <menu_item_check label="å…‰ã¨å½±" name="Lighting and Shadows"/>
+ <menu_item_check label="高度ãªãƒ©ã‚¤ãƒ†ã‚£ãƒ³ã‚°ãƒ¢ãƒ‡ãƒ«" name="Advanced Lighting Model"/>
<menu_item_check label="太陽・月・プロジェクタã‹ã‚‰ã®å½±" name="Shadows from Sun/Moon/Projectors"/>
<menu_item_check label="SSAO ã¨å½±ã®å¹³æ»‘化" name="SSAO and Shadow Smoothing"/>
<menu_item_check label="GL デãƒãƒƒã‚°" name="Debug GL"/>
@@ -306,8 +333,6 @@
<menu_item_check label="アニメーションテクスãƒãƒ£" name="Animation Textures"/>
<menu_item_check label="テクスãƒãƒ£ã‚’無効ã«ã™ã‚‹" name="Disable Textures"/>
<menu_item_check label="フル解åƒåº¦ãƒ†ã‚¯ã‚¹ãƒãƒ£" name="Rull Res Textures"/>
- <menu_item_check label="テクスãƒãƒ£ã®æ¤œæŸ»" name="Audit Textures"/>
- <menu_item_check label="テクスãƒãƒ£ã‚¢ãƒˆãƒ©ã‚¹ï¼ˆè©¦é¨“段階)" name="Texture Atlas"/>
<menu_item_check label="装ç€ã•ã‚ŒãŸå…‰æºã‚’æç”»ã™ã‚‹" name="Render Attached Lights"/>
<menu_item_check label="å–り付ã‘られãŸãƒ‘ーティクルをæç”»ã™ã‚‹" name="Render Attached Particles"/>
<menu_item_check label="マウスオーãƒãƒ¼ã§å¼·èª¿è¡¨ç¤ºã™ã‚‹" name="Hover Glow Objects"/>
@@ -343,7 +368,6 @@
<menu_item_call label="フォーカスホールダーをダンプ" name="Dump Focus Holder"/>
<menu_item_call label="é¸æŠžã—ãŸã‚ªãƒ–ジェクト情報をプリント" name="Print Selected Object Info"/>
<menu_item_call label="エージェント情報をプリント" name="Print Agent Info"/>
- <menu_item_call label="メモリ使用状æ³" name="Memory Stats"/>
<menu_item_check label="地域デãƒãƒƒã‚°ã‚³ãƒ³ã‚½ãƒ¼ãƒ«" name="Region Debug Console"/>
<menu_item_check label="SelectMgr ã®ãƒ‡ãƒãƒƒã‚°" name="Debug SelectMgr"/>
<menu_item_check label="ダブルクリック" name="Debug Clicks"/>
@@ -373,12 +397,16 @@
<menu_item_call label="キャラクタジオメトリã®åˆ‡ã‚Šæ›¿ãˆ" name="Toggle Character Geometry"/>
<menu_item_call label="男性アãƒã‚¿ãƒ¼ã®ãƒ†ã‚¹ãƒˆ" name="Test Male"/>
<menu_item_call label="女性アãƒã‚¿ãƒ¼ã®ãƒ†ã‚¹ãƒˆ" name="Test Female"/>
- <menu_item_call label="PG ã®ãƒˆã‚°ãƒ«" name="Toggle PG"/>
<menu_item_check label="é¸æŠžã‚¢ãƒã‚¿ãƒ¼è¨±å¯" name="Allow Select Avatar"/>
</menu>
+ <menu label="アニメーションã®ã‚¹ãƒ”ード" name="Animation Speed">
+ <menu_item_call label="ã™ã¹ã¦ã®ã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³ã®ã‚¹ãƒ”ードを 10% アップ" name="All Animations 10 Faster"/>
+ <menu_item_call label="ã™ã¹ã¦ã®ã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³ã®ã‚¹ãƒ”ードを 10% ダウン" name="All Animations 10 Slower"/>
+ <menu_item_call label="ã™ã¹ã¦ã®ã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³ã®ã‚¹ãƒ”ードをリセット" name="Reset All Animation Speed"/>
+ <menu_item_check label="アニメーションをスローモーション" name="Slow Motion Animations"/>
+ </menu>
<menu_item_call label="パラメータを強制的ã«ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã«ã™ã‚‹" name="Force Params to Default"/>
<menu_item_check label="アニメーション情報" name="Animation Info"/>
- <menu_item_check label="スローモーションã®ã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³" name="Slow Motion Animations"/>
<menu_item_check label="見ã¦ã„ã‚‹ã‚‚ã®ã‚’表示ã™ã‚‹" name="Show Look At"/>
<menu_item_check label="クリックã—ãŸå ´æ‰€ã‚’表示ã™ã‚‹" name="Show Point At"/>
<menu_item_check label="çµåˆéƒ¨ã®ã‚¢ãƒƒãƒ—デートã®ãƒ‡ãƒãƒƒã‚°" name="Debug Joint Updates"/>
diff --git a/indra/newview/skins/default/xui/ja/menu_wearable_list_item.xml b/indra/newview/skins/default/xui/ja/menu_wearable_list_item.xml
index c402fa0b6d..c402fa0b6d 100644..100755
--- a/indra/newview/skins/default/xui/ja/menu_wearable_list_item.xml
+++ b/indra/newview/skins/default/xui/ja/menu_wearable_list_item.xml
diff --git a/indra/newview/skins/default/xui/ja/menu_wearing_gear.xml b/indra/newview/skins/default/xui/ja/menu_wearing_gear.xml
index 5334042dc9..5334042dc9 100644..100755
--- a/indra/newview/skins/default/xui/ja/menu_wearing_gear.xml
+++ b/indra/newview/skins/default/xui/ja/menu_wearing_gear.xml
diff --git a/indra/newview/skins/default/xui/ja/menu_wearing_tab.xml b/indra/newview/skins/default/xui/ja/menu_wearing_tab.xml
index 9effed1f42..9effed1f42 100644..100755
--- a/indra/newview/skins/default/xui/ja/menu_wearing_tab.xml
+++ b/indra/newview/skins/default/xui/ja/menu_wearing_tab.xml
diff --git a/indra/newview/skins/default/xui/ja/mime_types.xml b/indra/newview/skins/default/xui/ja/mime_types.xml
index 54663a0367..54663a0367 100644..100755
--- a/indra/newview/skins/default/xui/ja/mime_types.xml
+++ b/indra/newview/skins/default/xui/ja/mime_types.xml
diff --git a/indra/newview/skins/default/xui/ja/mime_types_linux.xml b/indra/newview/skins/default/xui/ja/mime_types_linux.xml
index 0ec1030113..0ec1030113 100644..100755
--- a/indra/newview/skins/default/xui/ja/mime_types_linux.xml
+++ b/indra/newview/skins/default/xui/ja/mime_types_linux.xml
diff --git a/indra/newview/skins/default/xui/ja/mime_types_mac.xml b/indra/newview/skins/default/xui/ja/mime_types_mac.xml
index 0ec1030113..0ec1030113 100644..100755
--- a/indra/newview/skins/default/xui/ja/mime_types_mac.xml
+++ b/indra/newview/skins/default/xui/ja/mime_types_mac.xml
diff --git a/indra/newview/skins/default/xui/ja/notifications.xml b/indra/newview/skins/default/xui/ja/notifications.xml
index 54031ccf12..f1c916bf53 100644..100755
--- a/indra/newview/skins/default/xui/ja/notifications.xml
+++ b/indra/newview/skins/default/xui/ja/notifications.xml
@@ -37,6 +37,12 @@
<button name="Help" text="$helptext"/>
</form>
</template>
+ <template name="okhelpignore">
+ <form>
+ <button name="OK_okhelpignore" text="$yestext"/>
+ <button name="Help_okhelpignore" text="$helptext"/>
+ </form>
+ </template>
<template name="yesnocancelbuttons">
<form>
<button name="Yes" text="$yestext"/>
@@ -144,7 +150,7 @@
<usetemplate canceltext="å–り消ã—" name="yesnocancelbuttons" notext="ä¿å­˜ã—ãªã„" yestext="ã™ã¹ã¦ä¿å­˜"/>
</notification>
<notification name="FriendsAndGroupsOnly">
- フレンド以外ã‹ã‚‰ã®ã‚³ãƒ¼ãƒ«ã‚„インスタントメッセージを無視ã™ã‚‹è¨­å®šã«ã—ãŸã“ã¨ã‚’ã€ç›¸æ‰‹ã«çŸ¥ã‚‰ã‚Œã‚‹ã“ã¨ã¯ã‚ã‚Šã¾ã›ã‚“。
+ フレンド以外ã®äººã‹ã‚‰ã®ã‚³ãƒ¼ãƒ«ã‚„ã€ã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ãƒˆãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’無視ã™ã‚‹è¨­å®šã«ã—ãŸã“ã¨ã‚’ã€ç›¸æ‰‹ã«çŸ¥ã‚‰ã‚Œã‚‹ã“ã¨ã¯ã‚ã‚Šã¾ã›ã‚“。
<usetemplate name="okbutton" yestext="OK"/>
</notification>
<notification name="FavoritesOnLogin">
@@ -215,6 +221,14 @@
ã“ã®èƒ½åŠ›ã‚’ [ROLE_NAME] ã«å‰²ã‚Šå½“ã¦ã¾ã™ã‹ï¼Ÿ
<usetemplate name="okcancelbuttons" notext="ã„ã„ãˆ" yestext="ã¯ã„"/>
</notification>
+ <notification name="EjectGroupMemberWarning">
+ [AVATAR_NAME] をグループã‹ã‚‰è¿½æ”¾ã—よã†ã¨ã—ã¦ã„ã¾ã™ã€‚
+ <usetemplate ignoretext="グループã‹ã‚‰ã®å‚加者ã®è¿½æ”¾ã‚’確èªã—ã¾ã™" name="okcancelignore" notext="å–り消ã—" yestext="追放"/>
+ </notification>
+ <notification name="EjectGroupMembersWarning">
+ [COUNT] åã®ãƒ¡ãƒ³ãƒãƒ¼ã‚’グループã‹ã‚‰è¿½æ”¾ã—よã†ã¨ã—ã¦ã„ã¾ã™ã€‚
+ <usetemplate ignoretext="グループã‹ã‚‰ã®è¤‡æ•°ã®ãƒ¡ãƒ³ãƒãƒ¼ã®è¿½æ”¾ã‚’確èªã—ã¾ã™" name="okcancelignore" notext="å–り消ã—" yestext="追放"/>
+ </notification>
<notification name="AttachmentDrop">
アタッãƒãƒ¡ãƒ³ãƒˆã‚’下ã«ç½®ã“ã†ã¨ã—ã¦ã„ã¾ã™ã€‚
続ã‘ã¾ã™ã‹ï¼Ÿ
@@ -382,13 +396,19 @@ L$ ãŒä¸è¶³ã—ã¦ã„ã‚‹ã®ã§ã“ã®ã‚°ãƒ«ãƒ¼ãƒ—ã«å‚加ã™ã‚‹ã“ã¨ãŒã§ãã
[SECOND_LIFE] ã«å…¥ã‚‹ã«ã¯ã‚¢ã‚«ã‚¦ãƒ³ãƒˆãŒå¿…è¦ã§ã™ã€‚今ã™ãアカウントを作æˆã—ã¾ã™ã‹ï¼Ÿ
<url name="url">
- https://join.secondlife.com/index.php?lang=ja-JP
+ [create_account_url]
</url>
<usetemplate name="okcancelbuttons" notext="ã‚‚ã†ä¸€åº¦è©¦ã™" yestext="æ–°ã—ã„アカウントを作æˆ"/>
</notification>
<notification name="InvalidCredentialFormat">
ユーザーåã®ãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰ã«ã‚¢ãƒã‚¿ãƒ¼ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼åã‚‚ã—ãã¯æ°åを入力ã—ã¦ã‹ã‚‰ã€å†åº¦ãƒ­ã‚°ã‚¤ãƒ³ã™ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚
</notification>
+ <notification name="InvalidGrid">
+ &apos;[GRID]&apos; ã¯æœ‰åŠ¹ãªã‚°ãƒªãƒƒãƒ‰ ID ã§ã¯ã‚ã‚Šã¾ã›ã‚“。
+ </notification>
+ <notification name="InvalidLocationSLURL">
+ ログインä½ç½®ã§æœ‰åŠ¹ãªã‚°ãƒªãƒƒãƒ‰ãŒæŒ‡å®šã•ã‚Œã¾ã›ã‚“ã§ã—ãŸã€‚
+ </notification>
<notification name="DeleteClassified">
クラシファイド広告 [NAME] を削除ã—ã¾ã™ã‹ï¼Ÿ
支払ã„済ã¿ã®æ–™é‡‘ã¯è¿”金ã•ã‚Œã¾ã›ã‚“。
@@ -495,7 +515,7 @@ L$ ãŒä¸è¶³ã—ã¦ã„ã‚‹ã®ã§ã“ã®ã‚°ãƒ«ãƒ¼ãƒ—ã«å‚加ã™ã‚‹ã“ã¨ãŒã§ãã
</notification>
<notification name="StartRegionEmpty">
ログインä½ç½®ãŒæŒ‡å®šã•ã‚Œã¦ã„ã¾ã›ã‚“。
-ログインä½ç½®ã®æ¬„ã«ãƒªãƒ¼ã‚¸ãƒ§ãƒ³åを入力ã™ã‚‹ã‹ã€ã€Œæœ€å¾Œã«ãƒ­ã‚°ã‚¢ã‚¦ãƒˆã—ãŸå ´æ‰€ã€ã‹ã€Œãƒ›ãƒ¼ãƒ ã€ã‚’é¸æŠžã—ã¦ãã ã•ã„。
+ログインä½ç½®ã®æ¬„ã«ãƒªãƒ¼ã‚¸ãƒ§ãƒ³åを入力ã™ã‚‹ã‹ã€ã€Œæœ€å¾Œã«ãƒ­ã‚°ã‚¢ã‚¦ãƒˆã—ãŸå ´æ‰€ã€ã‹ã€Œè‡ªå®…(ホーム)ã€ã‚’é¸æŠžã—ã¦ãã ã•ã„。
<usetemplate name="okbutton" yestext="OK"/>
</notification>
<notification name="CouldNotStartStopScript">
@@ -517,6 +537,33 @@ L$ ãŒä¸è¶³ã—ã¦ã„ã‚‹ã®ã§ã“ã®ã‚°ãƒ«ãƒ¼ãƒ—ã«å‚加ã™ã‚‹ã“ã¨ãŒã§ãã
</url>
<usetemplate ignoretext="使用中ã®ã‚³ãƒ³ãƒ”ューターã®ãƒãƒ¼ãƒ‰ã‚¦ã‚§ã‚¢ãŒã‚µãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ãªã„ã¨ã" name="okcancelignore" notext="ã„ã„ãˆ" yestext="ã¯ã„"/>
</notification>
+ <notification name="IntelOldDriver">
+ ãŠãらããŠä½¿ã„ã®ã‚°ãƒ©ãƒ•ã‚£ãƒƒã‚¯ãƒãƒƒãƒ—用ã®æ–°ã—ã„ドライãƒãŒå…¥æ‰‹å¯èƒ½ã§ã™ã€‚グラフィックドライãƒã‚’æ›´æ–°ã™ã‚‹ã“ã¨ã«ã‚ˆã‚Šã€ãƒ‘フォーマンスãŒå¤§å¹…ã«å‘上ã™ã‚‹å ´åˆãŒã‚ã‚Šã¾ã™ã€‚
+
+[_URL] ã«ã‚¢ã‚¯ã‚»ã‚¹ã—ã¦æ›´æ–°ç‰ˆã®ãƒ‰ãƒ©ã‚¤ãƒãŒã‚ã‚‹ã‹ã©ã†ã‹ã‚’確èªã—ã¾ã™ã‹ï¼Ÿ
+ <url name="url">
+ http://www.intel.com/p/ja_JP/support/detect/graphics
+ </url>
+ <usetemplate ignoretext="使用ã—ã¦ã„るグラフィックドライãƒãŒå¤ã„å ´åˆ" name="okcancelignore" notext="ã„ã„ãˆ" yestext="ã¯ã„"/>
+ </notification>
+ <notification name="AMDOldDriver">
+ ãŠä½¿ã„ã®ã‚°ãƒ©ãƒ•ã‚£ãƒƒã‚¯ãƒãƒƒãƒ—ã«ã¯æœ€æ–°ã®ãƒ‰ãƒ©ã‚¤ãƒãŒå­˜åœ¨ã™ã‚‹ã‚ˆã†ã§ã™ã€‚グラフィックドライãƒã‚’æ›´æ–°ã™ã‚‹ã¨ã€ãƒ‘フォーマンスãŒå¤§å¹…ã«æ”¹å–„ã•ã‚Œã¾ã™ã€‚
+
+[_URL] ã¸ã‚¢ã‚¯ã‚»ã‚¹ã—ã¦ã€ãƒ‰ãƒ©ã‚¤ãƒãƒ¼ã‚’æ›´æ–°ã—ã¾ã™ã‹ã€‚
+ <url name="url">
+ http://support.amd.com/us/Pages/AMDSupportHub.aspx
+ </url>
+ <usetemplate ignoretext="自分ã®ã‚°ãƒ©ãƒ•ã‚£ãƒƒã‚¯ãƒ‰ãƒ©ã‚¤ãƒãŒæ—§ããªã‚Šã¾ã—ãŸã€‚" name="okcancelignore" notext="ã„ã„ãˆ" yestext="ã¯ã„"/>
+ </notification>
+ <notification name="NVIDIAOldDriver">
+ ãŠä½¿ã„ã®ã‚°ãƒ©ãƒ•ã‚£ãƒƒã‚¯ãƒãƒƒãƒ—ã«ã¯æœ€æ–°ã®ãƒ‰ãƒ©ã‚¤ãƒãŒå­˜åœ¨ã™ã‚‹ã‚ˆã†ã§ã™ã€‚グラフィックドライãƒã‚’æ›´æ–°ã™ã‚‹ã¨ã€ãƒ‘フォーマンスãŒå¤§å¹…ã«æ”¹å–„ã•ã‚Œã¾ã™ã€‚
+
+[_URL] ã¸ã‚¢ã‚¯ã‚»ã‚¹ã—ã¦ã€ãƒ‰ãƒ©ã‚¤ãƒãƒ¼ã‚’æ›´æ–°ã—ã¾ã™ã‹ã€‚
+ <url name="url">
+ http://www.nvidia.com/Download/index.aspx?lang=en-us
+ </url>
+ <usetemplate ignoretext="自分ã®ã‚°ãƒ©ãƒ•ã‚£ãƒƒã‚¯ãƒ‰ãƒ©ã‚¤ãƒãŒæ—§ããªã‚Šã¾ã—ãŸã€‚" name="okcancelignore" notext="ã„ã„ãˆ" yestext="ã¯ã„"/>
+ </notification>
<notification name="UnknownGPU">
ãŠä½¿ã„ã®ã‚·ã‚¹ãƒ†ãƒ ã«ã¯ã€[APP_NAME] ãŒèªè­˜ã§ããªã„グラフィックカードãŒæ­è¼‰ã•ã‚Œã¦ã„ã¾ã™ã€‚
[APP_NAME] ã§ã¾ã ãƒ†ã‚¹ãƒˆã•ã‚Œã¦ã„ãªã„最新ãƒãƒ¼ãƒ‰ã‚¦ã‚§ã‚¢ã®ãŸã‚ã ã¨è€ƒãˆã‚‰ã‚Œã¾ã™ã€‚ å•é¡Œãªã„ã¨ã¯æ€ã„ã¾ã™ãŒã€ã‚°ãƒ©ãƒ•ã‚£ãƒƒã‚¯ã®è¨­å®šã‚’調整ã™ã‚‹å¿…è¦ãŒã‚ã‚‹ã‹ã‚‚ã—ã‚Œã¾ã›ã‚“。
@@ -614,6 +661,9 @@ L$ ãŒä¸è¶³ã—ã¦ã„ã‚‹ã®ã§ã“ã®ã‚°ãƒ«ãƒ¼ãƒ—ã«å‚加ã™ã‚‹ã“ã¨ãŒã§ãã
ã©ã®ã‚ªãƒ–ジェクトもロックã•ã‚Œã¦ãŠã‚‰ãšã€ã‚ãªãŸã®ã‚‚ã®ã§ã‚ã‚‹ã“ã¨ã‚’確èªã—ã¦ãã ã•ã„。
</notification>
+ <notification name="CannotLinkPermanent">
+ 地域(リージョン)ã®å¢ƒç•Œã‚’越ãˆã¦ã‚ªãƒ–ジェクトをリンクã§ãã¾ã›ã‚“。
+ </notification>
<notification name="CannotLinkDifferentOwners">
所有者ãŒç•°ãªã‚‹ãŸã‚ã€ã‚ªãƒ–ジェクトをリンクã§ãã¾ã›ã‚“。
@@ -1000,6 +1050,40 @@ L$ ã¯è¿”金ã•ã‚Œã¾ã›ã‚“。
<button name="Cancel" text="キャンセル"/>
</form>
</notification>
+ <notification label="自動置æ›ãƒªã‚¹ãƒˆã‚’追加" name="AddAutoReplaceList">
+ æ–°ã—ã„リストã®åå‰:
+ <form name="form">
+ <button name="SetName" text="OK"/>
+ </form>
+ </notification>
+ <notification label="自動置æ›ãƒªã‚¹ãƒˆã®åå‰ã‚’変更" name="RenameAutoReplaceList">
+ åå‰ &apos;[DUPNAME]&apos; ã¯æ—¢ã«ä½¿ã‚ã‚Œã¦ã„ã¾ã™
+一æ„ã®åå‰ã‚’入力ã—ã¦ãã ã•ã„:
+ <form name="form">
+ <button name="ReplaceList" text="ç€ç”¨ä¸­ã®ãƒªã‚¹ãƒˆã‚’入れ替ãˆã‚‹"/>
+ <button name="SetName" text="æ–°ã—ã„åå‰ã‚’使用"/>
+ </form>
+ </notification>
+ <notification name="InvalidAutoReplaceEntry">
+ キーワードã¯ä¸€èªžã§ãªã‘ã‚Œã°ãªã‚‰ãšã€ç½®æ›ã¯ç©ºã«ã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="InvalidAutoReplaceList">
+ ãã®ç½®æ›ãƒªã‚¹ãƒˆã¯ç„¡åŠ¹ã§ã™ã€‚
+ </notification>
+ <notification name="SpellingDictImportRequired">
+ ファイルã€åå‰ãŠã‚ˆã³è¨€èªžã‚’指定ã™ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚
+ </notification>
+ <notification name="SpellingDictIsSecondary">
+ 辞書 [DIC_NAME] ã«ã€Œaffã€ãƒ•ã‚¡ã‚¤ãƒ«ãŒãªã„よã†ã§ã™ã€‚ã“ã‚Œã¯ã“ã®è¾žæ›¸ãŒã€Œã‚»ã‚«ãƒ³ãƒ€ãƒªã€è¾žæ›¸ã§ã‚ã‚‹ã“ã¨ã‚’æ„味ã—ã¾ã™ã€‚
+ã“ã®è¾žæ›¸ã¯è¿½åŠ è¾žæ›¸ã¨ã—ã¦ä½¿ç”¨ã§ãã¾ã™ãŒã€ãƒ¡ã‚¤ãƒ³è¾žæ›¸ã¨ã—ã¦ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“。
+
+https://wiki.secondlife.com/wiki/Adding_Spelling_Dictionaries ã‚’å‚ç…§ã—ã¦ãã ã•ã„。
+ </notification>
+ <notification name="SpellingDictImportFailed">
+ [FROM_NAME] ã‹ã‚‰
+
+[TO_NAME] ã¸ã‚³ãƒ”ーã§ãã¾ã›ã‚“
+ </notification>
<notification label="アウトフィットをä¿å­˜ã™ã‚‹" name="SaveOutfitAs">
ç€ç”¨ä¸­ã®ã‚¢ã‚¦ãƒˆãƒ•ã‚£ãƒƒãƒˆã‚’æ–°ã—ã„アウトフットã¨ã—ã¦ä¿å­˜ï¼š
<form name="form">
@@ -1063,7 +1147,7 @@ L$ ã¯è¿”金ã•ã‚Œã¾ã›ã‚“。
金é¡ã‚’増やã—ã¦ãã ã•ã„。
</notification>
<notification name="ConfirmItemDeleteHasLinks">
- ã“ã“ã«ãƒªãƒ³ã‚¯ã•ã‚ŒãŸã‚¢ã‚¤ãƒ†ãƒ ãŒå°‘ãªãã¨ã‚‚1ã¤ã‚ã‚Šã¾ã™ã€‚ ã“ã®ã‚¢ã‚¤ãƒ†ãƒ ã‚’削除ã™ã‚‹ã¨ã“ã“ã«ãƒªãƒ³ã‚¯ã•ã‚ŒãŸã‚‚ã®ãŒæ©Ÿèƒ½ã—ãªããªã‚Šã¾ã™ã€‚ リンクを先ã«å‰Šé™¤ã™ã‚‹ã“ã¨ã‚’å¼·ããŠå‹§ã‚ã—ã¾ã™ã€‚
+ 1 ã¤ä»¥ä¸Šã®ã‚¢ã‚¤ãƒ†ãƒ ã«ãƒã‚¤ãƒ³ãƒˆã™ã‚‹ãƒªãƒ³ã‚¯ãŒã‚ã‚Šã¾ã™ã€‚ã“ã®ã‚¢ã‚¤ãƒ†ãƒ ã‚’削除ã™ã‚‹å ´åˆã€ãã®ãƒªãƒ³ã‚¯ã¯æ°¸ä¹…ã«æ©Ÿèƒ½ã—ãªããªã‚Šã¾ã™ã€‚ã¾ãšæœ€åˆã«ãƒªãƒ³ã‚¯ã‚’削除ã™ã‚‹ã“ã¨ã‚’å¼·ããŠå‹§ã‚ã—ã¾ã™ã€‚
ã“れらã®ã‚¢ã‚¤ãƒ†ãƒ ã‚’削除ã—ã¾ã™ã‹ï¼Ÿ
<usetemplate name="okcancelbuttons" notext="キャンセル" yestext="OK"/>
@@ -1081,9 +1165,9 @@ L$ ã¯è¿”金ã•ã‚Œã¾ã›ã‚“。
<usetemplate name="okcancelbuttons" notext="キャンセル" yestext="OK"/>
</notification>
<notification name="ConfirmObjectDeleteNoOwn">
- é¸æŠžã—ãŸã‚¢ã‚¤ãƒ†ãƒ ã®ã†ã¡ã€å°‘ãªãã¨ã‚‚ 1 ã¤ãŒã‚ãªãŸã®æ‰€æœ‰ç‰©ã§ã¯ã‚ã‚Šã¾ã›ã‚“。
+ é¸æŠžã—ãŸã‚¢ã‚¤ãƒ†ãƒ ã® 1 ã¤ä»¥ä¸Šã‚’所有ã—ã¦ã„ã¾ã›ã‚“。
-本当ã«å‰Šé™¤ã—ã¾ã™ã‹ï¼Ÿ
+ã“れらã®ã‚¢ã‚¤ãƒ†ãƒ ã‚’削除ã—ã¾ã™ã‹ï¼Ÿ
<usetemplate name="okcancelbuttons" notext="キャンセル" yestext="OK"/>
</notification>
<notification name="ConfirmObjectDeleteLockNoCopy">
@@ -1094,26 +1178,26 @@ L$ ã¯è¿”金ã•ã‚Œã¾ã›ã‚“。
<usetemplate name="okcancelbuttons" notext="キャンセル" yestext="OK"/>
</notification>
<notification name="ConfirmObjectDeleteLockNoOwn">
- å°‘ãªãã¨ã‚‚ 1 ã¤ã®ã‚ªãƒ–ジェクトãŒãƒ­ãƒƒã‚¯ã•ã‚Œã¦ã„ã¾ã™ã€‚
-å°‘ãªãã¨ã‚‚ 1 ã¤ã®ã‚ªãƒ–ジェクトãŒã€ã‚ãªãŸã®æ‰€æœ‰ç‰©ã§ã¯ã‚ã‚Šã¾ã›ã‚“。
+ 1 ã¤ä»¥ä¸Šã®ã‚ªãƒ–ジェクトãŒãƒ­ãƒƒã‚¯ã•ã‚Œã¾ã—ãŸã€‚
+1 ã¤ä»¥ä¸Šã®ã‚ªãƒ–ジェクトを所有ã—ã¦ã„ã¾ã›ã‚“。
-本当ã«å‰Šé™¤ã—ã¾ã™ã‹ï¼Ÿ
+ã“れらã®ã‚¢ã‚¤ãƒ†ãƒ ã‚’削除ã—ã¾ã™ã‹ï¼Ÿ
<usetemplate name="okcancelbuttons" notext="キャンセル" yestext="OK"/>
</notification>
<notification name="ConfirmObjectDeleteNoCopyNoOwn">
- å°‘ãªãã¨ã‚‚ 1 ã¤ã®ã‚ªãƒ–ジェクトãŒã‚³ãƒ”ーã§ãã¾ã›ã‚“。
-å°‘ãªãã¨ã‚‚ 1 ã¤ã®ã‚ªãƒ–ジェクトãŒã€ã‚ãªãŸã®æ‰€æœ‰ç‰©ã§ã¯ã‚ã‚Šã¾ã›ã‚“。
+ 1 ã¤ä»¥ä¸Šã®ã‚ªãƒ–ジェクトãŒã‚³ãƒ”ーã§ãã¾ã›ã‚“。
+1 ã¤ä»¥ä¸Šã®ã‚ªãƒ–ジェクトを所有ã—ã¦ã„ã¾ã›ã‚“。
-本当ã«å‰Šé™¤ã—ã¾ã™ã‹ï¼Ÿ
+ã“れらã®ã‚¢ã‚¤ãƒ†ãƒ ã‚’削除ã—ã¾ã™ã‹ï¼Ÿ
<usetemplate name="okcancelbuttons" notext="キャンセル" yestext="OK"/>
</notification>
<notification name="ConfirmObjectDeleteLockNoCopyNoOwn">
- å°‘ãªãã¨ã‚‚ 1 ã¤ã®ã‚ªãƒ–ジェクトãŒãƒ­ãƒƒã‚¯ã•ã‚Œã¦ã„ã¾ã™ã€‚
-å°‘ãªãã¨ã‚‚ 1 ã¤ã®ã‚ªãƒ–ジェクトãŒã‚³ãƒ”ーã§ãã¾ã›ã‚“。
-å°‘ãªãã¨ã‚‚ 1 ã¤ã®ã‚ªãƒ–ジェクトãŒã€ã‚ãªãŸã®æ‰€æœ‰ç‰©ã§ã¯ã‚ã‚Šã¾ã›ã‚“。
+ 1 ã¤ä»¥ä¸Šã®ã‚ªãƒ–ジェクトãŒãƒ­ãƒƒã‚¯ã•ã‚Œã¦ã„ã¾ã™ã€‚
+1 ã¤ä»¥ä¸Šã®ã‚ªãƒ–ジェクトãŒã‚³ãƒ”ーã§ãã¾ã›ã‚“。
+1 ã¤ä»¥ä¸Šã®ã‚ªãƒ–ジェクトを所有ã—ã¦ã„ã¾ã›ã‚“。
-本当ã«å‰Šé™¤ã—ã¾ã™ã‹ï¼Ÿ
- <usetemplate name="okcancelbuttons" notext="キャンセル" yestext="OK"/>
+ã“れらã®ã‚¢ã‚¤ãƒ†ãƒ ã‚’削除ã—ã¾ã™ã‹ï¼Ÿ
+ <usetemplate name="okcancelbuttons" notext="å–り消ã—" yestext="OK"/>
</notification>
<notification name="ConfirmObjectTakeLock">
å°‘ãªãã¨ã‚‚ 1 ã¤ã®ã‚ªãƒ–ジェクトãŒãƒ­ãƒƒã‚¯ã•ã‚Œã¦ã„ã¾ã™ã€‚
@@ -1182,7 +1266,7 @@ L$ ã¯è¿”金ã•ã‚Œã¾ã›ã‚“。
è¿‘ãã®ãƒªãƒ¼ã‚¸ãƒ§ãƒ³ã«ç§»å‹•ã—ã¾ã—ãŸã€‚
</notification>
<notification name="AvatarMovedLast">
- å‰å›žã„ãŸå ´æ‰€ã¯ç¾åœ¨ã”利用ã„ãŸã ã‘ã¾ã›ã‚“。
+ リクエストã•ã‚ŒãŸå ´æ‰€ã¯ç¾åœ¨ã”利用ã„ãŸã ã‘ã¾ã›ã‚“。
è¿‘ãã®ãƒªãƒ¼ã‚¸ãƒ§ãƒ³ã«ç§»å‹•ã—ã¾ã—ãŸã€‚
</notification>
<notification name="AvatarMovedHome">
@@ -1201,8 +1285,7 @@ L$ ã¯è¿”金ã•ã‚Œã¾ã›ã‚“。
[APP_NAME] ã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ãŒå®Œäº†ã—ã¾ã—ãŸã€‚
[SECOND_LIFE] を使ã£ãŸã“ã¨ãŒãªã„å ´åˆã¯ã€ãƒ­ã‚°ã‚¤ãƒ³ã™ã‚‹å‰ã«ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã®ä½œæˆã‚’è¡Œã£ã¦ãã ã•ã„。
-[http://join.secondlife.com/?lang=ja-JP] ã§æ–°ã—ã„アカウントを作æˆã—ã¾ã™ã‹ï¼Ÿ
- <usetemplate name="okcancelbuttons" notext="続行" yestext="æ–°è¦ã‚¢ã‚«ã‚¦ãƒ³ãƒˆ..."/>
+ <usetemplate name="okcancelbuttons" notext="続行" yestext="アカウントを作æˆ..."/>
</notification>
<notification name="LoginPacketNeverReceived">
接続ãŒãªã‹ãªã‹ã§ãã¾ã›ã‚“。 ãŠä½¿ã„ã®ã‚¤ãƒ³ã‚¿ãƒ¼ãƒãƒƒãƒˆæŽ¥ç¶šã‹ã€[SECOND_LIFE_GRID] ã®å•é¡Œã¨è€ƒãˆã‚‰ã‚Œã¾ã™ã€‚
@@ -1438,13 +1521,43 @@ http://secondlife.com/download ã‹ã‚‰æœ€æ–°ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’ダウンロードã
</notification>
<notification name="RequiredUpdateDownloadedVerboseDialog">
å¿…è¦ãªã‚½ãƒ•ãƒˆã‚¦ã‚§ã‚¢ã®ã‚¢ãƒƒãƒ—デートをダウンロードã—ã¾ã—ãŸã€‚
-ãƒãƒ¼ã‚¸ãƒ§ãƒ³ [VERSION]
+ãƒãƒ¼ã‚¸ãƒ§ãƒ³ [VERSION] [[INFO_URL] ã“ã®ã‚¢ãƒƒãƒ—デートã«é–¢ã™ã‚‹æƒ…å ±]
アップデートをインストールã™ã‚‹ã«ã¯ [APP_NAME] ã‚’å†èµ·å‹•ã™ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚
<usetemplate name="okbutton" yestext="OK"/>
</notification>
<notification name="RequiredUpdateDownloadedDialog">
アップデートをインストールã™ã‚‹ã«ã¯ [APP_NAME] ã‚’å†èµ·å‹•ã™ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚
+[[INFO_URL] ã“ã®ã‚¢ãƒƒãƒ—デートã«é–¢ã™ã‚‹æƒ…å ±]
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
+ <notification name="OtherChannelDownloadBackgroundTip">
+ ãŠä½¿ã„ã® [APP_NAME] ã«å¿…è¦ãªã‚¢ãƒƒãƒ—デートをダウンロードã—ã¾ã—ãŸã€‚
+ãƒãƒ¼ã‚¸ãƒ§ãƒ³ [VERSION]
+ã“ã®è©¦é¨“çš„ãªãƒ“ューア㌠[NEW_CHANNEL] ビューアã«ç½®ãæ›ãˆã‚‰ã‚Œã¦ã„ã¾ã™;
+ã“ã®ã‚¢ãƒƒãƒ—デートã®è©³ç´°ã«ã¤ã„ã¦ã¯ã€[[INFO_URL] ã‚’å‚ç…§ã—ã¦ãã ã•ã„]
+ <usetemplate name="okcancelbuttons" notext="後ã§å®Ÿè¡Œ" yestext="今ã™ãインストールã—㦠[APP_NAME] ã‚’å†èµ·å‹•"/>
+ </notification>
+ <notification name="OtherChannelDownloadBackgroundDialog">
+ ãŠä½¿ã„ã® [APP_NAME] ã«å¿…è¦ãªã‚¢ãƒƒãƒ—デートをダウンロードã—ã¾ã—ãŸã€‚
+ãƒãƒ¼ã‚¸ãƒ§ãƒ³ [VERSION]
+ã“ã®è©¦é¨“çš„ãªãƒ“ューア㌠[NEW_CHANNEL] ビューアã«ç½®ãæ›ãˆã‚‰ã‚Œã¦ã„ã¾ã™;
+[[INFO_URL] ã“ã®ã‚¢ãƒƒãƒ—デートã«é–¢ã™ã‚‹æƒ…å ±] ã‚’å‚ç…§
+ <usetemplate name="okcancelbuttons" notext="後ã§å®Ÿè¡Œ" yestext="今ã™ãインストールã—㦠[APP_NAME] ã‚’å†èµ·å‹•"/>
+ </notification>
+ <notification name="OtherChannelRequiredUpdateDownloadedVerboseDialog">
+ å¿…è¦ãªã‚½ãƒ•ãƒˆã‚¦ã‚§ã‚¢ã®ã‚¢ãƒƒãƒ—デートをダウンロードã—ã¾ã—ãŸã€‚
+ãƒãƒ¼ã‚¸ãƒ§ãƒ³ [VERSION]
+ã“ã®è©¦é¨“çš„ãªãƒ“ューア㌠[NEW_CHANNEL] ビューアã«ç½®ãæ›ãˆã‚‰ã‚Œã¦ã„ã¾ã™;
+[[INFO_URL] ã“ã®ã‚¢ãƒƒãƒ—デートã«é–¢ã™ã‚‹æƒ…å ±] ã‚’å‚ç…§
+
+アップデートをインストールã™ã‚‹ã«ã¯ [APP_NAME] ã‚’å†èµ·å‹•ã™ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
+ <notification name="OtherChannelRequiredUpdateDownloadedDialog">
+ アップデートをインストールã™ã‚‹ã«ã¯ [APP_NAME] ã‚’å†èµ·å‹•ã™ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚
+ã“ã®è©¦é¨“çš„ãªãƒ“ューア㌠[NEW_CHANNEL] ビューアã«ç½®ãæ›ãˆã‚‰ã‚Œã¦ã„ã¾ã™;
+[[INFO_URL] ã“ã®ã‚¢ãƒƒãƒ—デートã«é–¢ã™ã‚‹æƒ…å ±] ã‚’å‚ç…§
<usetemplate name="okbutton" yestext="OK"/>
</notification>
<notification name="DeedObjectToGroup">
@@ -1497,6 +1610,10 @@ http://secondlife.com/download ã‹ã‚‰æœ€æ–°ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’ダウンロードã
グループã‹ã‚‰è„±é€€ã—ã¾ã™ã‹ï¼Ÿ
<usetemplate name="okcancelbuttons" notext="å–り消ã—" yestext="OK"/>
</notification>
+ <notification name="OwnerCannotLeaveGroup">
+ グループを抜ã‘ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“。グループã®æœ€å¾Œã®ã‚ªãƒ¼ãƒŠãƒ¼ã§ã‚ã‚‹ãŸã‚ã€ã‚°ãƒ«ãƒ¼ãƒ—を抜ã‘ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“。最åˆã«ã€åˆ¥ã®ãƒ¡ãƒ³ãƒãƒ¼ã‚’オーナーã®å½¹å‰²ã«å‰²ã‚Šå½“ã¦ã¦ãã ã•ã„。
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
<notification name="ConfirmKick">
本当ã«ä½äººå…¨å“¡ã‚’グリッドã‹ã‚‰è¿½ã„出ã—ã¾ã™ã‹ï¼Ÿ
<usetemplate name="okcancelbuttons" notext="キャンセル" yestext="ä½äººå…¨å“¡ã‚’追ã„出ã™"/>
@@ -1525,10 +1642,13 @@ http://secondlife.com/download ã‹ã‚‰æœ€æ–°ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’ダウンロードã
ç¾åœ¨ãƒ•ãƒ¬ãƒ³ãƒ‰ã‚·ãƒƒãƒ—ã‚’é€ã‚Œã¾ã›ã‚“。数分後ã«ã‚‚ã†ä¸€åº¦ãŠè©¦ã—ãã ã•ã„。
<usetemplate name="okbutton" yestext="OK"/>
</notification>
- <notification name="BusyModeSet">
- å–ã‚Šè¾¼ã¿ä¸­ãƒ¢ãƒ¼ãƒ‰ã«ãªã‚Šã¾ã—ãŸã€‚
-ãƒãƒ£ãƒƒãƒˆã¨ã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ãƒˆãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã¯è¡¨ç¤ºã•ã‚Œã¾ã›ã‚“。 å—ä¿¡ã™ã‚‹ã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ãƒˆãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã«ã¯å–ã‚Šè¾¼ã¿ä¸­è¿”答メッセージãŒè¡¨ç¤ºã•ã‚Œã¾ã™ã€‚ テレãƒãƒ¼ãƒˆã®ã‚ªãƒ•ã‚¡ãƒ¼ã¯å—ã‘å–ã‚Šæ‹’å¦ã¨ãªã‚Šã¾ã™ã€‚ アイテムã®ã‚ªãƒ•ã‚¡ãƒ¼ã¯ã™ã¹ã¦ã”ã¿ç®±ã«å…¥ã‚Šã¾ã™ã€‚
- <usetemplate ignoretext="ログイン状態をå–ã‚Šè¾¼ã¿ä¸­ãƒ¢ãƒ¼ãƒ‰ã«å¤‰æ›´ã™ã‚‹ã¨ã" name="okignore" yestext="OK"/>
+ <notification name="DoNotDisturbModeSet">
+ 「通知をå—ã‘ãªã„ã€ãŒã‚ªãƒ³ã«ãªã‚Šã¾ã™ã€‚ç€ä¿¡é€šä¿¡ã¯ã‚ãªãŸã«ã¯é€šçŸ¥ã•ã‚Œã¾ã›ã‚“。
+
+- ä»–ã®ä½æ°‘ã¯ã€Œé€šçŸ¥ã‚’å—ã‘ãªã„ã€ã®å¿œç­”(「設定ã€&gt;「一般ã€ã§è¨­å®šï¼‰ã‚’å—ã‘å–ã‚‹ã“ã¨ã«ãªã‚Šã¾ã™ã€‚
+- テレãƒãƒ¼ãƒˆã®ã‚ªãƒ•ã‚¡ãƒ¼ã¯ã™ã¹ã¦å—ã‘å–ã‚Šæ‹’å¦ã¨ãªã‚Šã¾ã™ã€‚
+- ボイスコールã¯æ‹’å¦ã•ã‚Œã¾ã™ã€‚
+ <usetemplate ignoretext="マイ ログイン状態を「通知をå—ã‘ãªã„ã€ãƒ¢ãƒ¼ãƒ‰ã«å¤‰æ›´ã—ã¾ã—ãŸã€‚" name="okignore" yestext="OK"/>
</notification>
<notification name="JoinedTooManyGroupsMember">
加入ã§ãるグループã®æœ€å¤§é™ã«é”ã—ã¾ã—ãŸã€‚ ã“ã®ã‚°ãƒ«ãƒ¼ãƒ—ã«åŠ å…¥ã™ã‚‹ãŸã‚ã«ä»–ã®ã‚°ãƒ«ãƒ¼ãƒ—を脱退ã™ã‚‹ã‹ã€ã“ã®ç”³ã—入れを断ã£ã¦ãã ã•ã„。
@@ -1724,83 +1844,128 @@ http://wiki.secondlife.com/wiki/Setting_your_display_name ã‚’å‚ç…§ã—ã¦ãã ã
<usetemplate name="okcancelbuttons" notext="å–り消ã—" yestext="OK"/>
</notification>
<notification name="RegionEntryAccessBlocked">
- ã‚ãªãŸã®ãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°åŒºåˆ†ã«ã‚ˆã‚Šã€ãã®ãƒªãƒ¼ã‚¸ãƒ§ãƒ³ï¼ˆåœ°åŸŸï¼‰ã¸ã¯å…¥ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“。 年齢を確èªã™ã‚‹éš›ã®æƒ…å ±ã«ä¸è¶³ãŒã‚ã£ãŸãŸã‚ã¨è€ƒãˆã‚‰ã‚Œã¾ã™ã€‚
-
-最新ビューワãŒã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã•ã‚Œã¦ã„ã‚‹ã‹ã‚’ã”確èªãã ã•ã„。ã“ã®ãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°åŒºåˆ†ã§ã®ã‚¢ã‚¯ã‚»ã‚¹ã«é–¢ã™ã‚‹è©³ç´°ã¯ãƒŠãƒ¬ãƒƒã‚¸ãƒ™ãƒ¼ã‚¹ã‚’ã”覧ãã ã•ã„。
+ 訪å•ã—よã†ã¨ã—ã¦ã„る地域(リージョン)ã«ã¯ç¾åœ¨ã®ç’°å¢ƒè¨­å®šã‚’超ãˆã‚‹ã‚³ãƒ³ãƒ†ãƒ³ãƒ„ãŒå«ã¾ã‚Œã¦ã„ã¾ã™ã€‚「ミー〠&gt; 「環境設定〠&gt; 「一般ã€ã‚’é¸æŠžã—ã¦ã€ç’°å¢ƒè¨­å®šã‚’変更ã§ãã¾ã™ã€‚
<usetemplate name="okbutton" yestext="OK"/>
</notification>
- <notification name="RegionEntryAccessBlocked_KB">
- ã‚ãªãŸã®ãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°åŒºåˆ†ã«ã‚ˆã‚Šã€ãã®ãƒªãƒ¼ã‚¸ãƒ§ãƒ³ï¼ˆåœ°åŸŸï¼‰ã¸ã¯å…¥ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“。
-
-ナレッジベースを開ãレーティング区分ã«ã¤ã„ã¦å­¦ã³ã¾ã™ã‹ï¼Ÿ
+ <notification name="RegionEntryAccessBlocked_AdultsOnlyContent">
+ 訪å•ã—よã†ã¨ã—ã¦ã„る地域(リージョン)ã«ã¯ã€æˆäººã®ã¿ã‚¢ã‚¯ã‚»ã‚¹ã§ãã‚‹ [REGIONMATURITY] コンテンツãŒå«ã¾ã‚Œã¦ã„ã¾ã™ã€‚
<url name="url">
- http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview/ja
+ http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview
</url>
- <usetemplate ignoretext="レーティング区分ã®åˆ¶é™ã®ãŸã‚ã€ãƒªãƒ¼ã‚¸ãƒ§ãƒ³ã«å…¥ã‚‹ã“ã¨ãŒã§ããªã„ã¨ã" name="okcancelignore" notext="é–‰ã˜ã‚‹" yestext="ナレッジベースを開ã"/>
+ <usetemplate ignoretext="リージョン(地域)ã®æ¨ªæ–­ï¼šè¨ªå•ã—よã†ã¨ã—ã¦ã„る地域(リージョン)ã«ã¯ã€æˆäººã®ã¿ã‚¢ã‚¯ã‚»ã‚¹ã§ãるコンテンツãŒå«ã¾ã‚Œã¦ã„ã¾ã™ã€‚" name="okcancelignore" notext="é–‰ã˜ã‚‹" yestext="ナレッジベースを開ã"/>
</notification>
<notification name="RegionEntryAccessBlocked_Notify">
- ã‚ãªãŸã®ãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°åŒºåˆ†ã«ã‚ˆã‚Šã€ãã®ãƒªãƒ¼ã‚¸ãƒ§ãƒ³ï¼ˆåœ°åŸŸï¼‰ã¸ã¯å…¥ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“。
+ 訪å•ã—よã†ã¨ã—ã¦ã„る地域(リージョン)ã«ã¯ [REGIONMATURITY] コンテンツãŒå«ã¾ã‚Œã¦ã„ã¾ã™ãŒã€ç¾åœ¨ã®ç’°å¢ƒè¨­å®šã¯ [REGIONMATURITY] コンテンツ除外ã™ã‚‹ã‚ˆã†ã«è¨­å®šã•ã‚Œã¦ã„ã¾ã™ã€‚
+ </notification>
+ <notification name="RegionEntryAccessBlocked_NotifyAdultsOnly">
+ 訪å•ã—よã†ã¨ã—ã¦ã„る地域(リージョン)ã«ã¯ã€æˆäººã®ã¿ã‚¢ã‚¯ã‚»ã‚¹ã§ãã‚‹ [REGIONMATURITY] コンテンツãŒå«ã¾ã‚Œã¦ã„ã¾ã™ã€‚
</notification>
<notification name="RegionEntryAccessBlocked_Change">
- レーティング区分ã«é–¢ã™ã‚‹è¨­å®šã«ã‚ˆã‚Šã€ãã®åœ°åŸŸï¼ˆãƒªãƒ¼ã‚¸ãƒ§ãƒ³ï¼‰ã«ã¯ç«‹ã¡å…¥ã‚Œã¾ã›ã‚“。
-
-ãã®åœ°åŸŸã«å…¥ã‚‹ã«ã¯ã€ã‚ãªãŸã®ãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°åŒºåˆ†ã®è¨­å®šã‚’変更ã—ã¦ãã ã•ã„。変更ã™ã‚‹ã¨ã€[REGIONMATURITY]ã®ã‚³ãƒ³ãƒ†ãƒ³ãƒ„ã®æ¤œç´¢ã‚„アクセスãŒå¯èƒ½ã«ãªã‚Šã¾ã™ã€‚変更内容を元ã«æˆ»ã™ã«ã¯ã€ãƒŸãƒ¼ &gt; 環境設定 &gt; 一般をé¸æŠžã—ã¦ãã ã•ã„。
+ 訪å•ã—よã†ã¨ã—ã¦ã„る地域(リージョン)ã«ã¯ [REGIONMATURITY] コンテンツãŒå«ã¾ã‚Œã¦ã„ã¾ã™ãŒã€ç¾åœ¨ã®ç’°å¢ƒè¨­å®šã¯ [REGIONMATURITY] コンテンツを除外ã™ã‚‹ã‚ˆã†ã«è¨­å®šã•ã‚Œã¦ã„ã¾ã™ã€‚環境設定を変更ã™ã‚‹ã‹ã€å–り消ã™ã“ã¨ãŒã§ãã¾ã™ã€‚環境設定を変更ã—ãŸå¾Œã€ã‚‚ã†ä¸€åº¦ã€åœ°åŸŸï¼ˆãƒªãƒ¼ã‚¸ãƒ§ãƒ³ï¼‰ã«å…¥ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚
+ <form name="form">
+ <button name="OK" text="環境設定ã®å¤‰æ›´"/>
+ <button default="true" name="Cancel" text="å–り消ã—"/>
+ <ignore name="ignore" text="リージョン(地域)ã®æ¨ªæ–­ï¼šè¨ªå•ã—よã†ã¨ã—ã¦ã„る地域(リージョン)ã«ã¯ç¾åœ¨ã®ç’°å¢ƒè¨­å®šã«ã‚ˆã‚Šé™¤å¤–ã•ã‚ŒãŸã‚³ãƒ³ãƒ†ãƒ³ãƒ„ãŒå«ã¾ã‚Œã¦ã„ã¾ã™ã€‚"/>
+ </form>
+ </notification>
+ <notification name="RegionEntryAccessBlocked_PreferencesOutOfSync">
+ ã‚ãªãŸã®ç’°å¢ƒè¨­å®šãŒã‚µãƒ¼ãƒãƒ¼ã¨åŒæœŸã—ã¦ã„ãªã„ãŸã‚ã€ãƒ†ãƒ¬ãƒãƒ¼ãƒˆã«æŠ€è¡“çš„ãªå•é¡ŒãŒç™ºç”Ÿã—ã¦ã„ã¾ã™ã€‚
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
+ <notification name="TeleportEntryAccessBlocked">
+ 訪å•ã—よã†ã¨ã—ã¦ã„る地域(リージョン)ã«ã¯ç¾åœ¨ã®ç’°å¢ƒè¨­å®šã‚’超ãˆã‚‹ã‚³ãƒ³ãƒ†ãƒ³ãƒ„ãŒå«ã¾ã‚Œã¦ã„ã¾ã™ã€‚「ミー〠&gt; 「環境設定〠&gt; 「一般ã€ã‚’é¸æŠžã—ã¦ã€ç’°å¢ƒè¨­å®šã‚’変更ã§ãã¾ã™ã€‚
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
+ <notification name="TeleportEntryAccessBlocked_AdultsOnlyContent">
+ 訪å•ã—よã†ã¨ã—ã¦ã„る地域(リージョン)ã«ã¯ã€æˆäººã®ã¿ã‚¢ã‚¯ã‚»ã‚¹ã§ãã‚‹ [REGIONMATURITY] コンテンツãŒå«ã¾ã‚Œã¦ã„ã¾ã™ã€‚
+ <url name="url">
+ http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview
+ </url>
+ <usetemplate ignoretext="テレãƒãƒ¼ãƒˆï¼šè¨ªå•ã—よã†ã¨ã—ã¦ã„る地域(リージョン)ã«ã¯ã€æˆäººã®ã¿ã‚¢ã‚¯ã‚»ã‚¹ã§ãるコンテンツãŒå«ã¾ã‚Œã¦ã„ã¾ã™ã€‚" name="okcancelignore" notext="é–‰ã˜ã‚‹" yestext="ナレッジベースを開ã"/>
+ </notification>
+ <notification name="TeleportEntryAccessBlocked_Notify">
+ 訪å•ã—よã†ã¨ã—ã¦ã„る地域(リージョン)ã«ã¯ [REGIONMATURITY] コンテンツãŒå«ã¾ã‚Œã¦ã„ã¾ã™ãŒã€ç¾åœ¨ã®ç’°å¢ƒè¨­å®šã¯ [REGIONMATURITY] コンテンツを除外ã™ã‚‹ã‚ˆã†ã«è¨­å®šã•ã‚Œã¦ã„ã¾ã™ã€‚
+ </notification>
+ <notification name="TeleportEntryAccessBlocked_NotifyAdultsOnly">
+ 訪å•ã—よã†ã¨ã—ã¦ã„る地域(リージョン)ã«ã¯ã€æˆäººã®ã¿ã‚¢ã‚¯ã‚»ã‚¹ã§ãã‚‹ [REGIONMATURITY] コンテンツãŒå«ã¾ã‚Œã¦ã„ã¾ã™ã€‚
+ </notification>
+ <notification name="TeleportEntryAccessBlocked_ChangeAndReTeleport">
+ 訪å•ã—よã†ã¨ã—ã¦ã„る地域(リージョン)ã«ã¯ [REGIONMATURITY] コンテンツãŒå«ã¾ã‚Œã¦ã„ã¾ã™ãŒã€ç¾åœ¨ã®ç’°å¢ƒè¨­å®šã¯ [REGIONMATURITY] コンテンツを除外ã™ã‚‹ã‚ˆã†ã«è¨­å®šã•ã‚Œã¦ã„ã¾ã™ã€‚環境設定を変更ã—ã¦ãƒ†ãƒ¬ãƒãƒ¼ãƒˆã‚’続ã‘ã‚‹ã‹ã€ã“ã®ãƒ†ãƒ¬ãƒãƒ¼ãƒˆã‚’å–り消ã™ã“ã¨ãŒã§ãã¾ã™ã€‚
+ <form name="form">
+ <button name="OK" text="変更ã—ã¦ç¶šã‘ã‚‹"/>
+ <button name="Cancel" text="å–り消ã—"/>
+ <ignore name="ignore" text="テレãƒãƒ¼ãƒˆï¼ˆå†èµ·å‹•å¯èƒ½ï¼‰ï¼šè¨ªå•ã—よã†ã¨ã—ã¦ã„る地域(リージョン)ã«ã¯ç¾åœ¨ã®ç’°å¢ƒè¨­å®šã«ã‚ˆã‚Šé™¤å¤–ã•ã‚ŒãŸã‚³ãƒ³ãƒ†ãƒ³ãƒ„ãŒå«ã¾ã‚Œã¦ã„ã¾ã™ã€‚"/>
+ </form>
+ </notification>
+ <notification name="TeleportEntryAccessBlocked_Change">
+ 訪å•ã—よã†ã¨ã—ã¦ã„る地域(リージョン)ã«ã¯ [REGIONMATURITY] コンテンツãŒå«ã¾ã‚Œã¦ã„ã¾ã™ãŒã€ç¾åœ¨ã®ç’°å¢ƒè¨­å®šã¯ [REGIONMATURITY] コンテンツを除外ã™ã‚‹ã‚ˆã†ã«è¨­å®šã•ã‚Œã¦ã„ã¾ã™ã€‚環境設定を変更ã™ã‚‹ã‹ã€ãƒ†ãƒ¬ãƒãƒ¼ãƒˆã‚’å–り消ã™ã“ã¨ãŒã§ãã¾ã™ã€‚環境設定を変更ã—ãŸå¾Œã€ã‚‚ã†ä¸€åº¦ãƒ†ãƒ¬ãƒãƒ¼ãƒˆã‚’実行ã™ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚
<form name="form">
<button name="OK" text="環境設定ã®å¤‰æ›´"/>
- <button default="true" name="Cancel" text="é–‰ã˜ã‚‹"/>
- <ignore name="ignore" text="é¸æŠžã—ãŸãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°åŒºåˆ†ãŒåŽŸå› ã§ã€ãƒªãƒ¼ã‚¸ãƒ§ãƒ³ã«å…¥ã‚Œãªã„ã¨ã"/>
+ <button name="Cancel" text="å–り消ã—"/>
+ <ignore name="ignore" text="テレãƒãƒ¼ãƒˆï¼ˆå†èµ·å‹•ä¸å¯ï¼‰ï¼šè¨ªå•ã—よã†ã¨ã—ã¦ã„る地域(リージョン)ã«ã¯ç¾åœ¨ã®ç’°å¢ƒè¨­å®šã«ã‚ˆã‚Šé™¤å¤–ã•ã‚ŒãŸã‚³ãƒ³ãƒ†ãƒ³ãƒ„ãŒå«ã¾ã‚Œã¦ã„ã¾ã™ã€‚"/>
</form>
</notification>
+ <notification name="TeleportEntryAccessBlocked_PreferencesOutOfSync">
+ ã‚ãªãŸã®ç’°å¢ƒè¨­å®šãŒã‚µãƒ¼ãƒãƒ¼ã¨åŒæœŸã—ã¦ã„ãªã„ãŸã‚ã€ãƒ†ãƒ¬ãƒãƒ¼ãƒˆã«æŠ€è¡“çš„ãªå•é¡ŒãŒç™ºç”Ÿã—ã¦ã„ã¾ã™ã€‚
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
<notification name="PreferredMaturityChanged">
- ã‚ãªãŸã®ãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°åŒºåˆ†è¨­å®šã¯ç¾åœ¨ [RATING] ã§ã™ã€‚
+ 今後ã€[RATING] コンテンツ付ãã®åœ°åŸŸï¼ˆãƒªãƒ¼ã‚¸ãƒ§ãƒ³ï¼‰ã‚’訪å•ã—よã†ã¨ã—ã¦ã„ã‚‹ã¨ã„ã†é€šçŸ¥ã‚’å—ã‘å–ã‚Šã¾ã›ã‚“。後ã§ãƒ¡ãƒ‹ãƒ¥ãƒ¼ãƒãƒ¼ã®ã€ŒãƒŸãƒ¼ã€ &gt; 「環境設定〠&gt; 「一般ã€ã‚’使用ã—ã¦ã€ã‚³ãƒ³ãƒ†ãƒ³ãƒ„ã®ç’°å¢ƒè¨­å®šã‚’変更ã§ãã¾ã™ã€‚
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
+ <notification name="MaturityChangeError">
+ ç¾åœ¨ã€[PREFERRED_MATURITY] コンテンツを表示ã™ã‚‹ã‚ˆã†ã«ç’°å¢ƒè¨­å®šã‚’変更ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ã‚ãªãŸã®ç’°å¢ƒè¨­å®šã¯ã€[ACTUAL_MATURITY] コンテンツを表示ã™ã‚‹ã‚ˆã†ã«ãƒªã‚»ãƒƒãƒˆã•ã‚Œã¾ã—ãŸã€‚メニューãƒãƒ¼ã®ã€ŒãƒŸãƒ¼ã€ &gt; 「環境設定〠&gt; 「一般ã€ã‚’使用ã—ã¦ã€ã‚‚ã†ä¸€åº¦ç’°å¢ƒè¨­å®šã‚’変更ã§ãã¾ã™ã€‚
+ <usetemplate name="okbutton" yestext="OK"/>
</notification>
<notification name="LandClaimAccessBlocked">
- ã‚ãªãŸã®ãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°åŒºåˆ†ã«ã‚ˆã‚Šã€ã“ã®åœŸåœ°ã‚’å–å¾—ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。 年齢を確èªã™ã‚‹éš›ã®æƒ…å ±ã«ä¸è¶³ãŒã‚ã£ãŸãŸã‚ã¨è€ƒãˆã‚‰ã‚Œã¾ã™ã€‚
-
-最新ビューワãŒã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã•ã‚Œã¦ã„ã‚‹ã‹ã‚’ã”確èªãã ã•ã„。ã“ã®ãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°åŒºåˆ†ã§ã®ã‚¢ã‚¯ã‚»ã‚¹ã«é–¢ã™ã‚‹è©³ç´°ã¯ãƒŠãƒ¬ãƒƒã‚¸ãƒ™ãƒ¼ã‚¹ã‚’ã”覧ãã ã•ã„。
+ å–å¾—ã—よã†ã¨ã—ã¦ã„る土地ã«ã¯ç¾åœ¨ã®ç’°å¢ƒè¨­å®šã‚’超ãˆã‚‹ãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°åŒºåˆ†ãŒå«ã¾ã‚Œã¦ã„ã¾ã™ã€‚「ミー〠&gt; 「環境設定〠&gt; 「一般ã€ã‚’é¸æŠžã—ã¦ã€ç’°å¢ƒè¨­å®šã‚’変更ã§ãã¾ã™ã€‚
<usetemplate name="okbutton" yestext="OK"/>
</notification>
- <notification name="LandClaimAccessBlocked_KB">
- ã‚ãªãŸã®ãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°åŒºåˆ†ã«ã‚ˆã‚Šã€ã“ã®åœŸåœ°ã‚’å–å¾—ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。
-
-ナレッジベースを開ãレーティング区分ã«ã¤ã„ã¦å­¦ã³ã¾ã™ã‹ï¼Ÿ
+ <notification name="LandClaimAccessBlocked_AdultsOnlyContent">
+ ã“ã®åœŸåœ°ã‚’購入ã§ãã‚‹ã®ã¯ã€æˆäººã ã‘ã§ã™ã€‚
<url name="url">
- http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview/ja
+ http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview
</url>
- <usetemplate ignoretext="レーティング区分ã®åˆ¶é™ã®ãŸã‚ã€ã“ã®åœŸåœ°ã‚’å–å¾—ã§ãã¾ã›ã‚“" name="okcancelignore" notext="é–‰ã˜ã‚‹" yestext="ナレッジベースを開ã"/>
+ <usetemplate ignoretext="ã“ã®åœŸåœ°ã‚’購入ã§ãã‚‹ã®ã¯ã€æˆäººã ã‘ã§ã™ã€‚" name="okcancelignore" notext="é–‰ã˜ã‚‹" yestext="ナレッジベースを開ã"/>
</notification>
<notification name="LandClaimAccessBlocked_Notify">
- ã‚ãªãŸã®ãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°åŒºåˆ†ã«ã‚ˆã‚Šã€ã“ã®åœŸåœ°ã‚’å–å¾—ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。
+ å–å¾—ã—よã†ã¨ã—ã¦ã„る土地ã«ã¯ [REGIONMATURITY] コンテンツãŒå«ã¾ã‚Œã¦ã„ã¾ã™ãŒã€ç¾åœ¨ã®ç’°å¢ƒè¨­å®šã¯ [REGIONMATURITY] コンテンツを除外ã™ã‚‹ã‚ˆã†ã«è¨­å®šã•ã‚Œã¦ã„ã¾ã™ã€‚
+ </notification>
+ <notification name="LandClaimAccessBlocked_NotifyAdultsOnly">
+ å–å¾—ã—よã†ã¨ã—ã¦ã„る土地ã«ã¯ã€æˆäººã®ã¿ã‚¢ã‚¯ã‚»ã‚¹ã§ãã‚‹ [REGIONMATURITY] コンテンツãŒå«ã¾ã‚Œã¦ã„ã¾ã™ã€‚
</notification>
<notification name="LandClaimAccessBlocked_Change">
- ã‚ãªãŸã®ãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°åŒºåˆ†è¨­å®šã«ã‚ˆã‚Šã€ã“ã®åœŸåœ°ã‚’å–å¾—ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。
-
-「設定を変更ã€ã‚’クリックã—ã¦ã‚ãªãŸã®ãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°åŒºåˆ†ã‚’上ã’ã‚‹ã¨ã€å…¥ã‚Œã‚‹ã‚ˆã†ã«ãªã‚Šã¾ã™ã€‚ ã‚ãªãŸã¯ä»Šå¾Œ [REGIONMATURITY] コンテンツã®æ¤œç´¢åŠã³ã‚¢ã‚¯ã‚»ã‚¹ãŒå¯èƒ½ã¨ãªã‚Šã¾ã™ã€‚ ã‚ã¨ã§è¨­å®šã‚’å…ƒã«æˆ»ã—ãŸã„å ´åˆã¯ã€ã€Œç·¨é›†ã€ï¼žã€Œç’°å¢ƒè¨­å®šã€ã‚’ã”覧ãã ã•ã„。
- <usetemplate ignoretext="é¸æŠžã—ãŸãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°åŒºåˆ†ãŒåŽŸå› ã§ã€åœŸåœ°ã‚’å–å¾—ã§ããªã„ã¨ã" name="okcancelignore" notext="é–‰ã˜ã‚‹" yestext="設定ã®å¤‰æ›´"/>
+ å–å¾—ã—よã†ã¨ã—ã¦ã„る土地ã«ã¯ [REGIONMATURITY] コンテンツãŒå«ã¾ã‚Œã¦ã„ã¾ã™ãŒã€ç¾åœ¨ã®ç’°å¢ƒè¨­å®šã¯ [REGIONMATURITY] コンテンツを除外ã™ã‚‹ã‚ˆã†ã«è¨­å®šã•ã‚Œã¦ã„ã¾ã™ã€‚環境設定を変更ã—ã¦ã€ã‚‚ã†ä¸€åº¦åœŸåœ°ã®å–得を試ã¿ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚
+ <form name="form">
+ <button name="OK" text="環境設定ã®å¤‰æ›´"/>
+ <button name="Cancel" text="å–り消ã—"/>
+ <ignore name="ignore" text="å–å¾—ã—よã†ã¨ã—ã¦ã„る土地ã«ã¯ç¾åœ¨ã®ç’°å¢ƒè¨­å®šã«ã‚ˆã‚Šé™¤å¤–ã•ã‚ŒãŸã‚³ãƒ³ãƒ†ãƒ³ãƒ„ãŒå«ã¾ã‚Œã¦ã„ã¾ã™ã€‚"/>
+ </form>
</notification>
<notification name="LandBuyAccessBlocked">
- ã‚ãªãŸã®ãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°åŒºåˆ†ã«ã‚ˆã‚Šã€ã“ã®åœŸåœ°ã‚’購入ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。 年齢を確èªã™ã‚‹éš›ã®æƒ…å ±ã«ä¸è¶³ãŒã‚ã£ãŸãŸã‚ã¨è€ƒãˆã‚‰ã‚Œã¾ã™ã€‚
-
-最新ビューワãŒã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã•ã‚Œã¦ã„ã‚‹ã‹ã‚’ã”確èªãã ã•ã„。ã“ã®ãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°åŒºåˆ†ã§ã®ã‚¢ã‚¯ã‚»ã‚¹ã«é–¢ã™ã‚‹è©³ç´°ã¯ãƒŠãƒ¬ãƒƒã‚¸ãƒ™ãƒ¼ã‚¹ã‚’ã”覧ãã ã•ã„。
+ 購入ã—よã†ã¨ã—ã¦ã„る土地ã«ã¯ç¾åœ¨ã®ç’°å¢ƒè¨­å®šã‚’超ãˆã‚‹ãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°åŒºåˆ†ãŒå«ã¾ã‚Œã¦ã„ã¾ã™ã€‚「ミー〠&gt; 「環境設定〠&gt; 「一般ã€ã‚’é¸æŠžã—ã¦ã€ç’°å¢ƒè¨­å®šã‚’変更ã§ãã¾ã™ã€‚
<usetemplate name="okbutton" yestext="OK"/>
</notification>
- <notification name="LandBuyAccessBlocked_KB">
- ã‚ãªãŸã®ãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°åŒºåˆ†ã«ã‚ˆã‚Šã€ã“ã®åœŸåœ°ã‚’購入ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。
-
-ナレッジベースを開ãレーティング区分ã«ã¤ã„ã¦å­¦ã³ã¾ã™ã‹ï¼Ÿ
+ <notification name="LandBuyAccessBlocked_AdultsOnlyContent">
+ ã“ã®åœŸåœ°ã‚’å–å¾—ã§ãã‚‹ã®ã¯ã€æˆäººã ã‘ã§ã™ã€‚
<url name="url">
- http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview/ja
+ http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview
</url>
- <usetemplate ignoretext="レーティング区分ã®åˆ¶é™ã®ãŸã‚ã€ã“ã®åœŸåœ°ã‚’購入ã§ãã¾ã›ã‚“" name="okcancelignore" notext="é–‰ã˜ã‚‹" yestext="ナレッジベースを開ã"/>
+ <usetemplate ignoretext="ã“ã®åœŸåœ°ã‚’å–å¾—ã§ãã‚‹ã®ã¯ã€æˆäººã ã‘ã§ã™ã€‚" name="okcancelignore" notext="é–‰ã˜ã‚‹" yestext="ナレッジベースを開ã"/>
</notification>
<notification name="LandBuyAccessBlocked_Notify">
- ã‚ãªãŸã®ãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°åŒºåˆ†ã«ã‚ˆã‚Šã€ã“ã®åœŸåœ°ã‚’購入ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。
+ 購入ã—よã†ã¨ã—ã¦ã„る土地ã«ã¯ [REGIONMATURITY] コンテンツãŒå«ã¾ã‚Œã¦ã„ã¾ã™ãŒã€ç¾åœ¨ã®ç’°å¢ƒè¨­å®šã¯ [REGIONMATURITY] コンテンツを除外ã™ã‚‹ã‚ˆã†ã«è¨­å®šã•ã‚Œã¦ã„ã¾ã™ã€‚
+ </notification>
+ <notification name="LandBuyAccessBlocked_NotifyAdultsOnly">
+ 購入ã—よã†ã¨ã—ã¦ã„る土地ã«ã¯ã€æˆäººã®ã¿ã‚¢ã‚¯ã‚»ã‚¹ã§ãã‚‹ [REGIONMATURITY] コンテンツãŒå«ã¾ã‚Œã¦ã„ã¾ã™ã€‚
</notification>
<notification name="LandBuyAccessBlocked_Change">
- ã‚ãªãŸã®ãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°åŒºåˆ†è¨­å®šã«ã‚ˆã‚Šã€ã“ã®åœŸåœ°ã‚’購入ã™ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“。
-
-「設定を変更ã€ã‚’クリックã—ã¦ã‚ãªãŸã®ãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°åŒºåˆ†ã‚’上ã’ã‚‹ã¨ã€å…¥ã‚Œã‚‹ã‚ˆã†ã«ãªã‚Šã¾ã™ã€‚ ã‚ãªãŸã¯ä»Šå¾Œ [REGIONMATURITY] コンテンツã®æ¤œç´¢åŠã³ã‚¢ã‚¯ã‚»ã‚¹ãŒå¯èƒ½ã¨ãªã‚Šã¾ã™ã€‚ ã‚ã¨ã§è¨­å®šã‚’å…ƒã«æˆ»ã—ãŸã„å ´åˆã¯ã€ã€Œç·¨é›†ã€ï¼žã€Œç’°å¢ƒè¨­å®šã€ã‚’ã”覧ãã ã•ã„。
- <usetemplate ignoretext="é¸æŠžã—ãŸãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°åŒºåˆ†ãŒåŽŸå› ã§ã€åœŸåœ°ã‚’購入ã§ããªã„ã¨ã" name="okcancelignore" notext="é–‰ã˜ã‚‹" yestext="設定ã®å¤‰æ›´"/>
+ 購入ã—よã†ã¨ã—ã¦ã„る土地ã«ã¯ [REGIONMATURITY] コンテンツãŒå«ã¾ã‚Œã¦ã„ã¾ã™ãŒã€ç¾åœ¨ã®ç’°å¢ƒè¨­å®šã¯ [REGIONMATURITY] コンテンツを除外ã™ã‚‹ã‚ˆã†ã«è¨­å®šã•ã‚Œã¦ã„ã¾ã™ã€‚環境設定を変更ã—ã¦ã€ã‚‚ã†ä¸€åº¦åœŸåœ°ã®è³¼å…¥ã‚’試ã¿ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚
+ <form name="form">
+ <button name="OK" text="環境設定ã®å¤‰æ›´"/>
+ <button name="Cancel" text="å–り消ã—"/>
+ <ignore name="ignore" text="購入ã—よã†ã¨ã—ã¦ã„る土地ã«ã¯ç¾åœ¨ã®ç’°å¢ƒè¨­å®šã«ã‚ˆã‚Šé™¤å¤–ã•ã‚ŒãŸã‚³ãƒ³ãƒ†ãƒ³ãƒ„ãŒå«ã¾ã‚Œã¦ã„ã¾ã™ã€‚"/>
+ </form>
</notification>
<notification name="TooManyPrimsSelected">
é¸æŠžã—ãŸãƒ—リムãŒå¤šã™ãŽã¾ã™ã€‚ [MAX_PRIM_COUNT] 個é¸æŠžã™ã‚‹ã‹ã€ãƒ—リム数を減らã—ã¦ã‚‚ã†ä¸€åº¦ãŠè©¦ã—ãã ã•ã„。
@@ -1858,10 +2023,9 @@ L$ [AMOUNT] ã§ã€ã“ã®ã‚¯ãƒ©ã‚·ãƒ•ã‚¡ã‚¤ãƒ‰åºƒå‘Šã‚’今ã™ã公開ã—ã¾ã™ã
</form>
</notification>
<notification label="地域ã®ãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°åŒºåˆ†æŒ‡å®šå¤‰æ›´æ¸ˆã¿" name="RegionMaturityChange">
- ã“ã®ãƒªãƒ¼ã‚¸ãƒ§ãƒ³ï¼ˆåœ°åŸŸï¼‰ã®ãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°åŒºåˆ†ãŒã‚¢ãƒƒãƒ—デートã•ã‚Œã¾ã—ãŸã€‚
-地図ã«å¤‰æ›´ãŒå映ã•ã‚Œã‚‹ã¾ã§æ•°åˆ†ã‹ã‹ã‚‹ã“ã¨ãŒã‚ã‚Šã¾ã™ã€‚
-
-Adult 専用リージョンã«å…¥ã‚‹ã«ã¯ã€ä½äººã®ã‚¢ã‚«ã‚¦ãƒ³ãƒˆãŒå¹´é½¢ç¢ºèªã‹æ”¯æ‰•æ–¹æ³•ã®ã„ãšã‚Œã‹ã§ã€Œç¢ºèªæ¸ˆã¿ã€ã§ãªã‘ã‚Œã°ãªã‚Šã¾ã›ã‚“。
+ ã“ã®ãƒªãƒ¼ã‚¸ãƒ§ãƒ³ã®ãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°åŒºåˆ†ãŒå¤‰æ›´ã•ã‚Œã¾ã—ãŸã€‚
+地図ã«ã“ã®å¤‰æ›´ãŒå映ã™ã‚‹ã«ã¯æ•°åˆ†ã‹ã‹ã‚‹ã“ã¨ãŒã‚ã‚Šã¾ã™ã€‚
+ <usetemplate name="okbutton" yestext="OK"/>
</notification>
<notification label="ボイスãƒãƒ¼ã‚¸ãƒ§ãƒ³ã®ä¸ä¸€è‡´" name="VoiceVersionMismatch">
[APP_NAME] ã®ã“ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã¯ã€ã“ã®ãƒªãƒ¼ã‚¸ãƒ§ãƒ³ã«ãŠã‘るボイスãƒãƒ£ãƒƒãƒˆã®äº’æ›æ€§ãŒã‚ã‚Šã¾ã›ã‚“。 ボイスãƒãƒ£ãƒƒãƒˆã‚’正常ã«è¡Œã†ãŸã‚ã«ã¯ã€[APP_NAME] ã®ã‚¢ãƒƒãƒ—デートãŒå¿…è¦ã§ã™ã€‚
@@ -1975,6 +2139,10 @@ Adult 専用リージョンã«å…¥ã‚‹ã«ã¯ã€ä½äººã®ã‚¢ã‚«ã‚¦ãƒ³ãƒˆãŒå¹´é½¢ç¢
[http://jp.secondlife.com/account/ マイアカウント] ページã«ç§»å‹•ã—ã¦ã‚¢ã‚«ã‚¦ãƒ³ãƒˆå±¥æ­´ã‚’確èªã—ã¾ã™ã‹ï¼Ÿ
<usetemplate ignoretext="ブラウザを起動ã—ã¦ã‚¢ã‚«ã‚¦ãƒ³ãƒˆå±¥æ­´ã‚’見るã¨ã" name="okcancelignore" notext="å–り消ã—" yestext="ページã«ç§»å‹•"/>
</notification>
+ <notification name="ConfirmAddingChatParticipants">
+ 既存ã®ä¼šè©±ã«äººã‚’加ãˆã‚‹ã¨ã€æ–°ã—ã„会話ãŒä½œæˆã•ã‚Œã¾ã™ã€‚å‚加者全員ã«æ–°ã—ã„会話ã«ã¤ã„ã¦ã®é€šçŸ¥ãŒé…ä¿¡ã•ã‚Œã¾ã™ã€‚
+ <usetemplate ignoretext="ãƒãƒ£ãƒƒãƒˆã®å‚加者ã®è¿½åŠ ã‚’確èªã—ã¦ãã ã•ã„" name="okcancelignore" notext="å–り消ã—" yestext="OK"/>
+ </notification>
<notification name="ConfirmQuit">
終了ã—よã†ã¨ã—ã¦ã„ã¾ã™ã€‚続ã‘ã¾ã™ã‹ï¼Ÿ
<usetemplate ignoretext="終了時ã®ç¢ºèª" name="okcancelignore" notext="終了ã—ãªã„" yestext="終了"/>
@@ -2052,14 +2220,14 @@ Linden Lab
<button ignore="交æ›ã—ãªã„" name="No" text="キャンセル"/>
</form>
</notification>
- <notification label="å–ã‚Šè¾¼ã¿ä¸­ã®è­¦å‘Š" name="BusyModePay">
- ç¾åœ¨ã€ã€Œå–ã‚Šè¾¼ã¿ä¸­ã€ãƒ¢ãƒ¼ãƒ‰ã®ãŸã‚ã€æ”¯æ‰•ã„ã¨å¼•ãæ›ãˆã«ã‚¢ã‚¤ãƒ†ãƒ ã‚’å—ã‘å–ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“。
+ <notification label="「通知をå—ã‘ãªã„ã€ãƒ¢ãƒ¼ãƒ‰ã®è­¦å‘Š" name="DoNotDisturbModePay">
+ 「通知をå—ã‘ãªã„ã€ã‚’オンã«ã—ã¾ã™ã€‚ã“ã®æ”¯æ‰•ã¨ã®äº¤æ›ã§æä¾›ã•ã‚Œã‚‹ã‚¢ã‚¤ãƒ†ãƒ ãŒå—ä¿¡ã•ã‚Œãªããªã‚Šã¾ã™ã€‚
-ã“ã®å–引を行ã†ãŸã‚ã«ã€Œå–ã‚Šè¾¼ã¿ä¸­ã€ã®è¨­å®šã‚’解除ã—ã¾ã™ã‹ï¼Ÿ
+ã“ã®ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã‚’完了ã™ã‚‹ãŸã‚ã«ã€ã€Œé€šçŸ¥ã‚’å—ã‘ãªã„ã€ã‚’オフã«ã—ã¦ã‚‚よã‚ã—ã„ã§ã™ã‹ã€‚
<form name="form">
- <ignore name="ignore" save_option="true" text="å–ã‚Šè¾¼ã¿ä¸­ãƒ¢ãƒ¼ãƒ‰æ™‚ã«æ”¯æ‰•ã‚’ã™ã‚‹ã¨ã"/>
- <button ignore="常ã«ã€Œå–ã‚Šè¾¼ã¿ä¸­ã€ã®è¨­å®šã‚’解除" name="Yes" text="OK"/>
- <button ignore="常ã«ã€Œå–ã‚Šè¾¼ã¿ä¸­ã€ã®è¨­å®šã‚’継続" name="No" text="キャンセル"/>
+ <ignore name="ignore" text="「通知をå—ã‘ãªã„ã€ãƒ¢ãƒ¼ãƒ‰æ™‚ã«ã€äººã‚„物を支払ã†äºˆå®šã§ã™ã€‚"/>
+ <button ignore="「通知をå—ã‘ãªã„ã€ãƒ¢ãƒ¼ãƒ‰ã‚’維æŒã—ãªã„" name="Yes" text="OK"/>
+ <button ignore="「通知をå—ã‘ãªã„ã€ãƒ¢ãƒ¼ãƒ‰ã‚’維æŒã™ã‚‹" name="No" text="å–り消ã—"/>
</form>
</notification>
<notification name="ConfirmDeleteProtectedCategory">
@@ -2156,14 +2324,11 @@ Web ページã«ãƒªãƒ³ã‚¯ã™ã‚‹ã¨ã€ä»–人ãŒã“ã®å ´æ‰€ã«ç°¡å˜ã«ã‚¢ã‚¯ã‚»ã
<usetemplate ignoretext="「容姿ã€ã‚’編集中ã«ã€ä½œæˆã™ã‚‹è¡£é¡žã‚’装ç€ã™ã‚‹ã¨ã" name="okcancelignore" notext="ã„ã„ãˆ" yestext="ã¯ã„"/>
</notification>
<notification name="NotAgeVerified">
- Second Life 㧠Adult 指定ã®ã‚³ãƒ³ãƒ†ãƒ³ãƒ„や領域ã«ã‚¢ã‚¯ã‚»ã‚¹ã§ãã‚‹ã®ã¯ 18 歳以上ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ã®ã¿ã§ã™ã€‚年齢確èªãƒšãƒ¼ã‚¸ã§ 18 歳以上ã§ã‚ã‚‹ã“ã¨ã‚’証明ã—ã¦ãã ã•ã„。
-ã“れをクリックã™ã‚‹ã¨ã‚¦ã‚§ãƒ–ブラウザãŒé–‹ãã¾ã™ã€‚
-
-[_URL]
- <url name="url" option="0">
- https://secondlife.com/my/account/verification.php
- </url>
- <usetemplate ignoretext="å¹´é½¢ã®ç¢ºèªã‚’済ã¾ã›ã¦ã„ãªã„ã¨ã" name="okcancelignore" notext="å–り消ã—" yestext="年齢確èªãƒšãƒ¼ã‚¸ã‚’é–‹ã"/>
+ 訪å•ã—よã†ã¨ã—ã¦ã„るロケーションã¯ã€18 æ‰ä»¥ä¸Šã®ä½äººã«åˆ¶é™ã•ã‚Œã¦ã„ã¾ã™ã€‚
+ <usetemplate ignoretext="年齢制é™ä»˜ãã®ã‚¨ãƒªã‚¢ã‚’訪å•ã™ã‚‹å¹´é½¢ã«é”ã—ã¦ã„ã¾ã›ã‚“。" name="okignore" yestext="OK"/>
+ </notification>
+ <notification name="NotAgeVerified_Notify">
+ ロケーション㯠18 æ‰ä»¥ä¸Šã«åˆ¶é™ã•ã‚Œã¦ã„ã¾ã™ã€‚
</notification>
<notification name="Cannot enter parcel: no payment info on file">
支払情報ãŒç™»éŒ²ã•ã‚Œã¦ã„ãªã„ã¨ã“ã®ã‚¨ãƒªã‚¢ã‚’訪れるã“ã¨ãŒã§ãã¾ã›ã‚“。 [SECOND_LIFE] サイトã§ç™»éŒ²ã‚’è¡Œã„ã¾ã™ã‹ï¼Ÿ
@@ -2198,11 +2363,8 @@ Web ページã«ãƒªãƒ³ã‚¯ã™ã‚‹ã¨ã€ä»–人ãŒã“ã®å ´æ‰€ã«ç°¡å˜ã«ã‚¢ã‚¯ã‚»ã
<notification name="GroupNotice">
件å: [SUBJECT]ã€ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ï¼š [MESSAGE]
</notification>
- <notification name="FriendOnline">
- &lt;nolink&gt;[NAME]&lt;/nolink&gt; ã¯ã‚ªãƒ³ãƒ©ã‚¤ãƒ³ã§ã™
- </notification>
- <notification name="FriendOffline">
- &lt;nolink&gt;[NAME]&lt;/nolink&gt; ã¯ã‚ªãƒ•ãƒ©ã‚¤ãƒ³ã§ã™
+ <notification name="FriendOnlineOffline">
+ &lt;nolink&gt;[NAME]&lt;/nolink&gt; 㯠[STATUS] ã§ã™
</notification>
<notification name="AddSelfFriend">
残念ãªãŒã‚‰è‡ªåˆ†è‡ªèº«ã‚’フレンド登録ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。
@@ -2323,9 +2485,7 @@ Web ページã«ãƒªãƒ³ã‚¯ã™ã‚‹ã¨ã€ä»–人ãŒã“ã®å ´æ‰€ã«ç°¡å˜ã«ã‚¢ã‚¯ã‚»ã
「テレãƒãƒ¼ãƒˆã€ã‚’é¸æŠžã—ã¦å®Ÿè¡Œã™ã‚‹ã“ã¨ã‚‚ã§ãã¾ã™ã€‚)
</notification>
<notification name="TeleportToPerson">
- [NAME] ã®ã‚ˆã†ãªä½äººã«é€£çµ¡ã‚’ã¨ã‚‹ã«ã¯ã€ã€Œäººã€ãƒœã‚¿ãƒ³ã‚’クリックã—ã€è¡¨ç¤ºã•ã‚Œã‚‹ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã§ã€Œä½äººã€ã‚’é¸æŠžã—ã¦ã‹ã‚‰ã€
-ウィンドウ下部ã«ã‚る「IMã€ã‚’クリックã—ã¾ã™ã€‚
-(リストã®åå‰ã‚’ダブルクリックã€ã¾ãŸã¯å³ã‚¯ãƒªãƒƒã‚¯ã—ã¦ã€ŒIMã€ã‚’é¸ã‚“ã§ã‚‚åŒã˜ã§ã™ã€‚)
+ 誰ã‹ã¨ã®ãƒ—ライベートãªä¼šè©±ã‚’é–‹ãã«ã¯ã€ç›¸æ‰‹ã®ã‚¢ãƒã‚¿ãƒ¼ã‚’クリックã—ã¦ã€ãƒ¡ãƒ‹ãƒ¥ãƒ¼ã‹ã‚‰ã€ŒIMã€ã‚’é¸æŠžã—ã¾ã™ã€‚
</notification>
<notification name="CantSelectLandFromMultipleRegions">
サーãƒãƒ¼ã®å¢ƒç•Œã‚’越ãˆã¦åœŸåœ°ã‚’é¸æŠžã™ã‚‹ã“ã¨ã§ãã¾ã›ã‚“。
@@ -2426,6 +2586,16 @@ Web ページã«ãƒªãƒ³ã‚¯ã™ã‚‹ã¨ã€ä»–人ãŒã“ã®å ´æ‰€ã«ç°¡å˜ã«ã‚¢ã‚¯ã‚»ã
<notification name="NoBuild">
ã“ã®ã‚¨ãƒªã‚¢ã§ã¯åˆ¶ä½œãŒç¦æ­¢ã•ã‚Œã¦ã„ã¾ã™ã€‚ オブジェクトを制作ã—ãŸã‚Š Rez ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。
</notification>
+ <notification name="PathfindingDirty">
+ ã“ã®å€¤åŸŸï¼ˆãƒªãƒ¼ã‚¸ãƒ§ãƒ³ï¼‰ã«ã¯ã€ä¿ç•™ä¸­ã®ãƒ‘スファインディングã®å¤‰æ›´ãŒã‚ã‚Šã¾ã™ã€‚制作権ãŒã‚ã‚‹å ´åˆã¯ã€ã€Œåœ°åŸŸã®å†æ§‹ç¯‰ã€ãƒœã‚¿ãƒ³ã‚’クリックã—ã¦ã€åœ°åŸŸï¼ˆãƒªãƒ¼ã‚¸ãƒ§ãƒ³ï¼‰ã‚’å†æ§‹ç¯‰ã§ãã¾ã™ã€‚
+ </notification>
+ <notification name="DynamicPathfindingDisabled">
+ ã“ã®åœ°åŸŸï¼ˆãƒªãƒ¼ã‚¸ãƒ§ãƒ³ï¼‰ã§ãƒ€ã‚¤ãƒŠãƒŸãƒƒã‚¯ãƒ‘スファインディングãŒæœ‰åŠ¹ã«ãªã£ã¦ã„ã¾ã›ã‚“。パスファインディング LSL 呼ã³å‡ºã—を使用ã™ã‚‹ã‚¹ã‚¯ãƒªãƒ—ト化ã•ã‚ŒãŸã‚ªãƒ–ジェクトãŒã“ã®åœ°åŸŸï¼ˆãƒªãƒ¼ã‚¸ãƒ§ãƒ³ï¼‰ã§ã¯å‹•ä½œã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="PathfindingCannotRebakeNavmesh">
+ エラーãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ã¾ãŸã¯ã‚µãƒ¼ãƒãƒ¼ã«å•é¡ŒãŒã‚ã‚‹ã‹ã€åˆ¶ä½œæ¨©ãŒãªã„å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚ã“ã®å•é¡Œã¯ã€ä¸€åº¦ãƒ­ã‚°ã‚¢ã‚¦ãƒˆã—ã¦ã‹ã‚‰ã€ãƒ­ã‚°ã‚¤ãƒ³ã—ç›´ã™ã¨è§£æ±ºã•ã‚Œã‚‹å ´åˆãŒã‚ã‚Šã¾ã™ã€‚
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
<notification name="SeeAvatars">
ã“ã®åŒºç”»ã«ã„ã‚‹ã‚¢ãƒã‚¿ãƒ¼ã‚„ã“ã®åŒºç”»å†…ã§è¡Œã‚れる文字ãƒãƒ£ãƒƒãƒˆã¯ã€ä»–ã®åŒºç”»ã‹ã‚‰è¦‹ãˆã¾ã›ã‚“。ã‚ãªãŸã«ã¯ã€ã“ã®åŒºç”»å¤–ã«ã„ã‚‹ä½äººãŒè¦‹ãˆãšã€å¤–ã®ä½äººã«ã¯ã‚ãªãŸã®å§¿ãŒè¦‹ãˆã¾ã›ã‚“。ãƒãƒ£ãƒ³ãƒãƒ« 0 ã§ã®é€šå¸¸ã®æ–‡å­—ãƒãƒ£ãƒƒãƒˆã‚‚ブロックã•ã‚Œã¾ã™ã€‚
</notification>
@@ -2444,9 +2614,7 @@ Web ページã«ãƒªãƒ³ã‚¯ã™ã‚‹ã¨ã€ä»–人ãŒã“ã®å ´æ‰€ã«ç°¡å˜ã«ã‚¢ã‚¯ã‚»ã
ãã®ãƒªãƒ¼ã‚¸ãƒ§ãƒ³ã«ã„ãªã„ã¨å…¬å…±ã®åœŸåœ°ã‚’å–å¾—ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。
</notification>
<notification name="RegionTPAccessBlocked">
- ã‚ãªãŸã®ãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°åŒºåˆ†ã«ã‚ˆã‚Šãã®ãƒªãƒ¼ã‚¸ãƒ§ãƒ³ã¸ã¯å…¥ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“。 年齢確èªã‚’è¡Œã†ã‹ã€æœ€æ–°ãƒ“ューワをインストールã—ã¦ãã ã•ã„。
-
-ç¾åœ¨ã®ãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°åŒºåˆ†ã§ã‚¢ã‚¯ã‚»ã‚¹å¯èƒ½ãªã‚¨ãƒªã‚¢ã«é–¢ã™ã‚‹è©³ç´°ã¯ãƒŠãƒ¬ãƒƒã‚¸ãƒ™ãƒ¼ã‚¹ã‚’å‚ç…§ã—ã¦ãã ã•ã„。
+ 訪å•ã—よã†ã¨ã—ã¦ã„る地域(リージョン)ã«ã¯ç¾åœ¨ã®ç’°å¢ƒè¨­å®šã‚’超ãˆã‚‹ã‚³ãƒ³ãƒ†ãƒ³ãƒ„ãŒå«ã¾ã‚Œã¦ã„ã¾ã™ã€‚「ミー〠&gt; 「環境設定〠&gt; 「一般ã€ã‚’é¸æŠžã—ã¦ã€ç’°å¢ƒè¨­å®šã‚’変更ã§ãã¾ã™ã€‚
</notification>
<notification name="URBannedFromRegion">
ã‚ãªãŸã¯ãƒªãƒ¼ã‚¸ãƒ§ãƒ³ã¸ã®ç«‹å…¥ãŒç¦æ­¢ã•ã‚Œã¦ã„ã¾ã™ã€‚
@@ -2457,11 +2625,11 @@ Web ページã«ãƒªãƒ³ã‚¯ã™ã‚‹ã¨ã€ä»–人ãŒã“ã®å ´æ‰€ã«ç°¡å˜ã«ã‚¢ã‚¯ã‚»ã
<notification name="ImproperPaymentStatus">
ã“ã®ãƒªãƒ¼ã‚¸ãƒ§ãƒ³ã«å…¥ã‚‹ãŸã‚ã«é©ã—ãŸæ”¯æ‰•ã„ステータスãŒã‚ã‚Šã¾ã›ã‚“。
</notification>
- <notification name="MustGetAgeRgion">
- ã“ã®ãƒªãƒ¼ã‚¸ãƒ§ãƒ³ã«å…¥ã‚‹ãŸã‚ã«ã¯ã€å¹´é½¢ç¢ºèªã‚’済ã¾ã›ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚
+ <notification name="MustGetAgeRegion">
+ ã“ã®åœ°åŸŸï¼ˆãƒªãƒ¼ã‚¸ãƒ§ãƒ³ï¼‰ã«å…¥ã‚‹ã«ã¯ 18 æ‰ä»¥ä¸Šã§ã‚ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚
</notification>
<notification name="MustGetAgeParcel">
- ã“ã®åŒºç”»ã«å…¥ã‚‹ãŸã‚ã«ã¯ã€å¹´é½¢ç¢ºèªã‚’済ã¾ã›ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚
+ ã“ã®åŒºç”»ã«å…¥ã‚‹ã«ã¯ 18 æ‰ä»¥ä¸Šã§ã‚ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚
</notification>
<notification name="NoDestRegion">
目的地ã®ãƒªãƒ¼ã‚¸ãƒ§ãƒ³ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸã€‚
@@ -2563,12 +2731,33 @@ Web ページã«ãƒªãƒ³ã‚¯ã™ã‚‹ã¨ã€ä»–人ãŒã“ã®å ´æ‰€ã«ç°¡å˜ã«ã‚¢ã‚¯ã‚»ã
<notification name="TeleportOffered">
[NAME_SLURL] ã¯ãƒ†ãƒ¬ãƒãƒ¼ãƒˆã§ã‚ãªãŸã‚’呼んã§ã„ã¾ã™ã€‚
-[MESSAGE] - [MATURITY_STR] &lt;icon&gt;[MATURITY_ICON]&lt;/icon&gt;
+“[MESSAGE]â€
+&lt;icon&gt;[MATURITY_ICON]&lt;/icon&gt; - [MATURITY_STR]
<form name="form">
<button name="Teleport" text="テレãƒãƒ¼ãƒˆ"/>
<button name="Cancel" text="å–り消ã—"/>
</form>
</notification>
+ <notification name="TeleportOffered_MaturityExceeded">
+ [NAME_SLURL] ã¯ãƒ†ãƒ¬ãƒãƒ¼ãƒˆã§ã‚ãªãŸã‚’呼んã§ã„ã¾ã™ã€‚
+
+“[MESSAGE]â€
+&lt;icon&gt;[MATURITY_ICON]&lt;/icon&gt; - [MATURITY_STR]
+
+ã“ã®åœ°åŸŸï¼ˆãƒªãƒ¼ã‚¸ãƒ§ãƒ³ï¼‰ã«ã¯ [REGION_CONTENT_MATURITY] コンテンツãŒå«ã¾ã‚Œã¦ã„ã¾ã™ãŒã€ç¾åœ¨ã®ç’°å¢ƒè¨­å®šã¯ [REGION_CONTENT_MATURITY] コンテンツを除外ã™ã‚‹ã‚ˆã†ã«è¨­å®šã•ã‚Œã¦ã„ã¾ã™ã€‚環境設定を変更ã—ã¦ãƒ†ãƒ¬ãƒãƒ¼ãƒˆã‚’続ã‘ã‚‹ã‹ã€ã“ã®ãƒ†ãƒ¬ãƒãƒ¼ãƒˆã‚’å–り消ã™ã“ã¨ãŒã§ãã¾ã™ã€‚
+ <form name="form">
+ <button name="Teleport" text="変更ã—ã¦ç¶šã‘ã‚‹"/>
+ <button name="Cancel" text="å–り消ã—"/>
+ </form>
+ </notification>
+ <notification name="TeleportOffered_MaturityBlocked">
+ [NAME_SLURL] ã¯ãƒ†ãƒ¬ãƒãƒ¼ãƒˆã§ã‚ãªãŸã‚’呼んã§ã„ã¾ã™ã€‚
+
+“[MESSAGE]â€
+&lt;icon&gt;[MATURITY_ICON]&lt;/icon&gt; - [MATURITY_STR]
+
+ãŸã ã—ã€ã“ã®åœ°åŸŸï¼ˆãƒªãƒ¼ã‚¸ãƒ§ãƒ³ï¼‰ã«ã¯æˆäººã®ã¿ã‚¢ã‚¯ã‚»ã‚¹ã§ãるコンテンツãŒå«ã¾ã‚Œã¦ã„ã¾ã™ã€‚
+ </notification>
<notification name="TeleportOfferSent">
[TO_NAME] ã«ãƒ†ãƒ¬ãƒãƒ¼ãƒˆã‚’é€ã‚Šã¾ã—ãŸã€‚
</notification>
@@ -2663,16 +2852,21 @@ Web ページã«ãƒªãƒ³ã‚¯ã™ã‚‹ã¨ã€ä»–人ãŒã“ã®å ´æ‰€ã«ç°¡å˜ã«ã‚¢ã‚¯ã‚»ã
</form>
</notification>
<notification name="ScriptQuestionCaution">
- [NAME] ãŒæ‰€æœ‰ã™ã‚‹ã€Œ&lt;nolink&gt;[OBJECTNAME]&lt;/nolink&gt;〠ã¨ã„ã†ã‚ªãƒ–ジェクトãŒã€æ¬¡ã®ã“ã¨ã‚’ã—よã†ã¨ã—ã¦ã„ã¾ã™ï¼š
-
-[QUESTIONS]
-ã“ã®ã‚ªãƒ–ジェクトや制作者を信用ã§ããªã„å ´åˆã¯ã€ã“ã®ãƒªã‚¯ã‚¨ã‚¹ãƒˆã‚’æ‹’å¦ã—ã¦ãã ã•ã„。
-
-リクエストをå—ã‘ã¾ã™ã‹ï¼Ÿ
+ 警告:オブジェクト &apos;&lt;nolink&gt;[OBJECTNAME]&lt;/nolink&gt;&apos; ã¯ã€ã‚ãªãŸã®ãƒªãƒ³ãƒ‡ãƒ³ãƒ‰ãƒ«ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã¸ã®ãƒ•ãƒ«ã‚¢ã‚¯ã‚»ã‚¹ã‚’è¦æ±‚ã—ã¦ã„ã¾ã™ã€‚アクセスを許å¯ã™ã‚‹ã¨ã€ã“ã®ã‚ªãƒ–ジェクトã¯ã€ç‰¹ã«è­¦å‘Šã‚’発ã›ãšã«å˜ç™ºã§ã€éšæ™‚アカウントã‹ã‚‰è³‡é‡‘を削除ã™ã‚‹ã‹ã€ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã‚’完全ã«ç©ºã«ã—ã¾ã™ã€‚
+
+ãã®ã‚ªãƒ–ジェクトãŒã‚¢ã‚«ã‚¦ãƒ³ãƒˆã¸ã®ã‚¢ã‚¯ã‚»ã‚¹ã‚’è¦æ±‚ã™ã‚‹ç†ç”±ãŒã‚ˆãã‚ã‹ã‚‰ãªã„å ´åˆã¯ã€ã‚¢ã‚¯ã‚»ã‚¹ã‚’許å¯ã—ãªã„ã§ãã ã•ã„。
<form name="form">
- <button name="Grant" text="許å¯"/>
+ <button name="Grant" text="トータルアクセスを許å¯"/>
<button name="Deny" text="æ‹’å¦"/>
- <button name="Details" text="詳細..."/>
+ </form>
+ </notification>
+ <notification name="UnknownScriptQuestion">
+ &apos;[NAME]&apos; ãŒæ‰€æœ‰ã™ã‚‹ &apos;&lt;nolink&gt;[OBJECTNAME]&lt;/nolink&gt;&apos; ã«ã‚ˆã£ã¦ãƒªã‚¯ã‚¨ã‚¹ãƒˆã•ã‚ŒãŸãƒ©ãƒ³ã‚¿ã‚¤ãƒ ã‚¹ã‚¯ãƒªãƒ—ト権é™ãŒãƒ“ューアã«ã‚ˆã£ã¦èªè­˜ã•ã‚Œãªã„ãŸã‚ã€è¨±å¯ã§ãã¾ã›ã‚“。
+
+ã“ã®æ¨©é™ã‚’許å¯ã™ã‚‹ã«ã¯ã€ãƒ“ューアを [DOWNLOADURL] ã‹ã‚‰ã®æœ€æ–°ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã«ã‚¢ãƒƒãƒ—デートã—ã¦ãã ã•ã„。
+ <form name="form">
+ <button name="Deny" text="Ok"/>
+ <button name="Mute" text="ブロック"/>
</form>
</notification>
<notification name="ScriptDialog">
@@ -2973,6 +3167,10 @@ M キーを押ã—ã¦å¤‰æ›´ã—ã¾ã™ã€‚
( 作æˆå¾Œ[EXISTENCE]秒経éŽï¼‰
&apos;[BODYREGION]&apos;ã®[RESOLUTION]ã®ãƒ™ãƒ¼ã‚¯ãƒ‰ãƒ†ã‚¯ã‚¹ãƒãƒ£ã¯[TIME]秒後ã«ãƒ­ãƒ¼ã‚«ãƒ«ã«æ›´æ–°ã•ã‚Œã¾ã—ãŸã€‚
</notification>
+ <notification name="LivePreviewUnavailable">
+ コピーä¸å¯ãŠã‚ˆã³/ã¾ãŸã¯è»¢é€ä¸å¯ã®ãŸã‚ã€ã“ã®ãƒ†ã‚¯ã‚¹ãƒãƒ£ã‚’表示ã§ãã¾ã›ã‚“。
+ <usetemplate ignoretext="コピーä¸å¯ãŠã‚ˆã³/ã¾ãŸã¯è»¢é€ä¸å¯ãƒ†ã‚¯ã‚¹ãƒãƒ£ã§ãƒ©ã‚¤ãƒ–プレビューモードを使用ã§ããªã„ã“ã¨ã‚’警告ã™ã‚‹" name="okignore" yestext="OK"/>
+ </notification>
<notification name="ConfirmLeaveCall">
ã“ã®ã‚³ãƒ¼ãƒ«ã‹ã‚‰æŠœã‘ã¾ã™ã‹ï¼Ÿ
<usetemplate ignoretext="コールã‹ã‚‰æŠœã‘ã‚‹å‰ã®ç¢ºèª" name="okcancelignore" notext="ã„ã„ãˆ" yestext="ã¯ã„"/>
@@ -3144,6 +3342,62 @@ M キーを押ã—ã¦å¤‰æ›´ã—ã¾ã™ã€‚
ã“ã®æ“作ã«ã‚ˆã‚Šã€å…¨ã¦ã®ãƒ¡ãƒ‹ãƒ¥ãƒ¼é …ç›®ã¨ãƒœã‚¿ãƒ³ãŒéžè¡¨ç¤ºã«ãªã‚Šã¾ã™ã€‚å†ã³è¡¨ç¤ºã™ã‚‹ã«ã¯ [SHORTCUT] ã‚’ã‚‚ã†ä¸€åº¦ã‚¯ãƒªãƒƒã‚¯ã—ã¦ãã ã•ã„。
<usetemplate ignoretext="UI ã‚’éžè¡¨ç¤ºã«ã™ã‚‹å‰ã«ç¢ºèª" name="okcancelignore" notext="å–り消ã—" yestext="OK"/>
</notification>
+ <notification name="PathfindingLinksets_WarnOnPhantom">
+ é¸æŠžã•ã‚ŒãŸä¸€éƒ¨ã®ãƒªãƒ³ã‚¯ã‚»ãƒƒãƒˆã¯ãƒ•ã‚¡ãƒ³ãƒˆãƒ ãƒ•ãƒ©ã‚°ãŒåˆ‡ã‚Šæ›¿ãˆã‚‰ã‚Œã¾ã™ã€‚
+
+続ã‘ã¾ã™ã‹ï¼Ÿ
+ <usetemplate ignoretext="é¸æŠžã•ã‚ŒãŸä¸€éƒ¨ã®ãƒªãƒ³ã‚¯ã‚»ãƒƒãƒˆã®ãƒ•ã‚¡ãƒ³ãƒˆãƒ ãƒ•ãƒ©ã‚°ãŒåˆ‡ã‚Šæ›¿ãˆã‚‰ã‚Œã¾ã™ã€‚" name="okcancelignore" notext="å–り消ã—" yestext="OK"/>
+ </notification>
+ <notification name="PathfindingLinksets_MismatchOnRestricted">
+ 一部ã®é¸æŠžã•ã‚ŒãŸãƒªãƒ³ã‚¯ã‚»ãƒƒãƒˆã¯ã€ãƒªãƒ³ã‚¯ã‚»ãƒƒãƒˆã¸ã®æ¨©é™ãŒåˆ¶é™ã•ã‚Œã¦ã„ã‚‹ãŸã‚ã€&apos;[REQUESTED_TYPE]&apos; ã«è¨­å®šã§ãã¾ã›ã‚“。ã“れらã®ãƒªãƒ³ã‚¯ã‚»ãƒƒãƒˆã¯ä»£ã‚ã‚Šã« &apos;[RESTRICTED_TYPE]&apos; ã«è¨­å®šã•ã‚Œã¾ã™ã€‚
+
+続ã‘ã¾ã™ã‹ï¼Ÿ
+ <usetemplate ignoretext="一部ã®é¸æŠžã•ã‚ŒãŸãƒªãƒ³ã‚¯ã‚»ãƒƒãƒˆã¯ã€ãƒªãƒ³ã‚¯ã‚»ãƒƒãƒˆã¸ã®æ¨©é™ãŒåˆ¶é™ã•ã‚Œã¦ã„ã‚‹ãŸã‚設定ã§ãã¾ã›ã‚“。" name="okcancelignore" notext="å–り消ã—" yestext="OK"/>
+ </notification>
+ <notification name="PathfindingLinksets_MismatchOnVolume">
+ é¸æŠžã•ã‚ŒãŸä¸€éƒ¨ã®ãƒªãƒ³ã‚¯ã‚»ãƒƒãƒˆã¯ã€å½¢çŠ¶ãŒå‡¸çŠ¶ã§ãªã„ãŸã‚ã€&apos;[REQUESTED_TYPE]&apos; ã«è¨­å®šã§ãã¾ã›ã‚“。
+
+続ã‘ã¾ã™ã‹ï¼Ÿ
+ <usetemplate ignoretext="é¸æŠžã•ã‚ŒãŸä¸€éƒ¨ã®ãƒªãƒ³ã‚¯ã‚»ãƒƒãƒˆã¯ã€å½¢çŠ¶ãŒå‡¸çŠ¶ã§ãªã„ãŸã‚設定ã§ãã¾ã›ã‚“。" name="okcancelignore" notext="å–り消ã—" yestext="OK"/>
+ </notification>
+ <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnRestricted">
+ é¸æŠžã•ã‚ŒãŸä¸€éƒ¨ã®ãƒªãƒ³ã‚¯ã‚»ãƒƒãƒˆã¯ãƒ•ã‚¡ãƒ³ãƒˆãƒ ãƒ•ãƒ©ã‚°ãŒåˆ‡ã‚Šæ›¿ãˆã‚‰ã‚Œã¾ã™ã€‚
+
+一部ã®é¸æŠžã•ã‚ŒãŸãƒªãƒ³ã‚¯ã‚»ãƒƒãƒˆã¯ã€ãƒªãƒ³ã‚¯ã‚»ãƒƒãƒˆã¸ã®æ¨©é™ãŒåˆ¶é™ã•ã‚Œã¦ã„ã‚‹ãŸã‚ã€&apos;[REQUESTED_TYPE]&apos; ã«è¨­å®šã§ãã¾ã›ã‚“。ã“れらã®ãƒªãƒ³ã‚¯ã‚»ãƒƒãƒˆã¯ä»£ã‚ã‚Šã« &apos;[RESTRICTED_TYPE]&apos; ã«è¨­å®šã•ã‚Œã¾ã™ã€‚
+
+続ã‘ã¾ã™ã‹ï¼Ÿ
+ <usetemplate ignoretext="é¸æŠžã•ã‚ŒãŸä¸€éƒ¨ã®ãƒªãƒ³ã‚¯ã‚»ãƒƒãƒˆã®ãƒ•ã‚¡ãƒ³ãƒˆãƒ ãƒ•ãƒ©ã‚°ãŒåˆ‡ã‚Šæ›¿ãˆã‚‰ã‚Œã€ä»–ã®ãƒªãƒ³ã‚¯ã‚»ãƒƒãƒˆã¯ãƒªãƒ³ã‚¯ã‚»ãƒƒãƒˆã¸ã®æ¨©é™ãŒåˆ¶é™ã•ã‚Œã¦ã„ã‚‹ãŸã‚設定ã§ãã¾ã›ã‚“。" name="okcancelignore" notext="å–り消ã—" yestext="OK"/>
+ </notification>
+ <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnVolume">
+ é¸æŠžã•ã‚ŒãŸä¸€éƒ¨ã®ãƒªãƒ³ã‚¯ã‚»ãƒƒãƒˆã¯ãƒ•ã‚¡ãƒ³ãƒˆãƒ ãƒ•ãƒ©ã‚°ãŒåˆ‡ã‚Šæ›¿ãˆã‚‰ã‚Œã¾ã™ã€‚
+
+é¸æŠžã•ã‚ŒãŸä¸€éƒ¨ã®ãƒªãƒ³ã‚¯ã‚»ãƒƒãƒˆã¯ã€å½¢çŠ¶ãŒå‡¸çŠ¶ã§ãªã„ãŸã‚ã€&apos;[REQUESTED_TYPE]&apos; ã«è¨­å®šã§ãã¾ã›ã‚“。
+
+続ã‘ã¾ã™ã‹ï¼Ÿ
+ <usetemplate ignoretext="é¸æŠžã•ã‚ŒãŸä¸€éƒ¨ã®ãƒªãƒ³ã‚¯ã‚»ãƒƒãƒˆã®ãƒ•ã‚¡ãƒ³ãƒˆãƒ ãƒ•ãƒ©ã‚°ãŒåˆ‡ã‚Šæ›¿ãˆã‚‰ã‚Œã€ä»–ã®ãƒªãƒ³ã‚¯ã‚»ãƒƒãƒˆã¯å½¢çŠ¶ãŒå‡¸çŠ¶ã§ãªã„ãŸã‚設定ã§ãã¾ã›ã‚“。" name="okcancelignore" notext="å–り消ã—" yestext="OK"/>
+ </notification>
+ <notification name="PathfindingLinksets_MismatchOnRestricted_MismatchOnVolume">
+ 一部ã®é¸æŠžã•ã‚ŒãŸãƒªãƒ³ã‚¯ã‚»ãƒƒãƒˆã¯ã€ãƒªãƒ³ã‚¯ã‚»ãƒƒãƒˆã¸ã®æ¨©é™ãŒåˆ¶é™ã•ã‚Œã¦ã„ã‚‹ãŸã‚ã€&apos;[REQUESTED_TYPE]&apos; ã«è¨­å®šã§ãã¾ã›ã‚“。ã“れらã®ãƒªãƒ³ã‚¯ã‚»ãƒƒãƒˆã¯ä»£ã‚ã‚Šã« &apos;[RESTRICTED_TYPE]&apos; ã«è¨­å®šã•ã‚Œã¾ã™ã€‚
+
+é¸æŠžã•ã‚ŒãŸä¸€éƒ¨ã®ãƒªãƒ³ã‚¯ã‚»ãƒƒãƒˆã¯ã€å½¢çŠ¶ãŒå‡¸çŠ¶ã§ãªã„ãŸã‚ã€&apos;[REQUESTED_TYPE]&apos; ã«è¨­å®šã§ãã¾ã›ã‚“。ã“れらã®ãƒªãƒ³ã‚¯ã‚»ãƒƒãƒˆã®ç”¨é€”タイプã¯å¤‰ã‚ã‚Šã¾ã›ã‚“。
+
+続ã‘ã¾ã™ã‹ï¼Ÿ
+ <usetemplate ignoretext="一部ã®é¸æŠžã•ã‚ŒãŸãƒªãƒ³ã‚¯ã‚»ãƒƒãƒˆã¯ã€ãƒªãƒ³ã‚¯ã‚»ãƒƒãƒˆã¸ã®æ¨©é™ãŒåˆ¶é™ã•ã‚Œã¦ãŠã‚Šã€ã¾ãŸå½¢çŠ¶ãŒå‡¸çŠ¶ã§ãªã„ãŸã‚設定ã§ãã¾ã›ã‚“。" name="okcancelignore" notext="å–り消ã—" yestext="OK"/>
+ </notification>
+ <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnRestricted_MismatchOnVolume">
+ é¸æŠžã•ã‚ŒãŸä¸€éƒ¨ã®ãƒªãƒ³ã‚¯ã‚»ãƒƒãƒˆã¯ãƒ•ã‚¡ãƒ³ãƒˆãƒ ãƒ•ãƒ©ã‚°ãŒåˆ‡ã‚Šæ›¿ãˆã‚‰ã‚Œã¾ã™ã€‚
+
+一部ã®é¸æŠžã•ã‚ŒãŸãƒªãƒ³ã‚¯ã‚»ãƒƒãƒˆã¯ã€ãƒªãƒ³ã‚¯ã‚»ãƒƒãƒˆã¸ã®æ¨©é™ãŒåˆ¶é™ã•ã‚Œã¦ã„ã‚‹ãŸã‚ã€&apos;[REQUESTED_TYPE]&apos; ã«è¨­å®šã§ãã¾ã›ã‚“。ã“れらã®ãƒªãƒ³ã‚¯ã‚»ãƒƒãƒˆã¯ä»£ã‚ã‚Šã« &apos;[RESTRICTED_TYPE]&apos; ã«è¨­å®šã•ã‚Œã¾ã™ã€‚
+
+é¸æŠžã•ã‚ŒãŸä¸€éƒ¨ã®ãƒªãƒ³ã‚¯ã‚»ãƒƒãƒˆã¯ã€å½¢çŠ¶ãŒå‡¸çŠ¶ã§ãªã„ãŸã‚ã€&apos;[REQUESTED_TYPE]&apos; ã«è¨­å®šã§ãã¾ã›ã‚“。ã“れらã®ãƒªãƒ³ã‚¯ã‚»ãƒƒãƒˆã®ç”¨é€”タイプã¯å¤‰ã‚ã‚Šã¾ã›ã‚“。
+
+続ã‘ã¾ã™ã‹ï¼Ÿ
+ <usetemplate ignoretext="é¸æŠžã•ã‚ŒãŸä¸€éƒ¨ã®ãƒªãƒ³ã‚¯ã‚»ãƒƒãƒˆã®ãƒ•ã‚¡ãƒ³ãƒˆãƒ ãƒ•ãƒ©ã‚°ãŒåˆ‡ã‚Šæ›¿ãˆã‚‰ã‚Œã€ä»–ã®ãƒªãƒ³ã‚¯ã‚»ãƒƒãƒˆã¯ãƒªãƒ³ã‚¯ã‚»ãƒƒãƒˆã¸ã®æ¨©é™ãŒåˆ¶é™ã•ã‚Œã€ã¾ãŸå½¢çŠ¶ãŒå‡¸çŠ¶ã§ãªã„ãŸã‚設定ã§ãã¾ã›ã‚“。" name="okcancelignore" notext="å–り消ã—" yestext="OK"/>
+ </notification>
+ <notification name="PathfindingLinksets_ChangeToFlexiblePath">
+ é¸æŠžã•ã‚ŒãŸã‚ªãƒ–ジェクトã¯ãƒŠãƒ“メッシュã«å½±éŸ¿ã‚’与ãˆã¾ã™ã€‚オブジェクトをフレキシブルパスã«å¤‰æ›´ã™ã‚‹ã¨ã€ãƒŠãƒ“メッシュã‹ã‚‰å‰Šé™¤ã•ã‚Œã¾ã™ã€‚
+ <usetemplate ignoretext="é¸æŠžã•ã‚ŒãŸã‚ªãƒ–ジェクトã¯ãƒŠãƒ“メッシュã«å½±éŸ¿ã‚’与ãˆã¾ã™ã€‚オブジェクトをフレキシブルパスã«å¤‰æ›´ã™ã‚‹ã¨ã€ãƒŠãƒ“メッシュã‹ã‚‰å‰Šé™¤ã•ã‚Œã¾ã™ã€‚" name="okcancelignore" notext="å–り消ã—" yestext="OK"/>
+ </notification>
<global name="UnsupportedGLRequirements">
[APP_NAME] ã«å¿…è¦ãªãƒãƒ¼ãƒ‰ã‚¦ã‚§ã‚¢ãŒãªã„よã†ã§ã™ã€‚ [APP_NAME] ã«ã¯ãƒžãƒ«ãƒãƒ†ã‚¯ã‚¹ãƒãƒ£ã‚’サãƒãƒ¼ãƒˆã™ã‚‹ OpenGL グラフィックカードãŒå¿…è¦ã§ã™ã€‚ ãŠä½¿ã„ã®ã‚°ãƒ©ãƒ•ã‚£ãƒƒã‚¯ã‚«ãƒ¼ãƒ‰ã®æœ€æ–°ãƒ‰ãƒ©ã‚¤ãƒãŒã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã•ã‚Œã¦ã„ã‚‹ã‹ã©ã†ã‹ã€ã‚ªãƒšãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°ã‚·ã‚¹ãƒ†ãƒ ã®ã‚µãƒ¼ãƒ“スパックã¨ãƒ‘ッãƒãŒå…¥ã£ã¦ã„ã‚‹ã‹ã‚’ã”確èªãã ã•ã„。
@@ -3168,4 +3422,647 @@ M キーを押ã—ã¦å¤‰æ›´ã—ã¾ã™ã€‚
<global name="You died and have been teleported to your home location">
死んã§ã—ã¾ã£ãŸã®ã§ã€ãƒ›ãƒ¼ãƒ ã«ãƒ†ãƒ¬ãƒãƒ¼ãƒˆã•ã‚Œã¾ã—ãŸã€‚
</global>
+ <notification name="LocalBitmapsUpdateFileNotFound">
+ [FNAME] ã¯ã€è¦‹ã¤ã‹ã‚‰ãªã‹ã£ãŸãŸã‚ã€æ›´æ–°ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚
+ã“ã®ãƒ•ã‚¡ã‚¤ãƒ«ã«å¯¾ã™ã‚‹ä»Šå¾Œã®æ›´æ–°ã‚’無効ã«ã—ã¾ã™ã€‚
+ </notification>
+ <notification name="LocalBitmapsUpdateFailedFinal">
+ [FNAME] ã‚’é–‹ãã¾ãŸã¯ãƒ‡ã‚³ãƒ¼ãƒ‰ã™ã‚‹è©¦è¡Œã«å¤±æ•—ã—ã¾ã—ãŸï¼ˆè©¦è¡Œå›žæ•° [NRETRIES] 回)。ãã®ãŸã‚ã€ã“ã®ãƒ•ã‚¡ã‚¤ãƒ«ã¯å£Šã‚Œã¦ã„ã‚‹ã‚‚ã®ã¨ã—ã¦å‡¦ç†ã•ã‚Œã¾ã—ãŸã€‚
+ã“ã®ãƒ•ã‚¡ã‚¤ãƒ«ã«å¯¾ã™ã‚‹ä»Šå¾Œã®æ›´æ–°ã‚’無効ã«ã—ã¾ã™ã€‚
+ </notification>
+ <notification name="LocalBitmapsVerifyFail">
+ é–‹ãã“ã¨ãŒã§ããªã„ã€ã¾ãŸã¯ãƒ‡ã‚³ãƒ¼ãƒ‰ã§ããªã„無効ã¾ãŸã¯èª­ã¿å–ã‚Šä¸èƒ½ãªç”»åƒãƒ•ã‚¡ã‚¤ãƒ« [FNAME] を追加ã—よã†ã¨ã—ã¾ã—ãŸã€‚
+ã“ã®è©¦è¡Œã¯ã‚­ãƒ£ãƒ³ã‚»ãƒ«ã•ã‚Œã¾ã—ãŸã€‚
+ </notification>
+ <notification name="PathfindingReturnMultipleItems">
+ [NUM_ITEMS] 個ã®ã‚¢ã‚¤ãƒ†ãƒ ã‚’è¿”å´ä¸­ã§ã™ã€‚続ã‘ã¾ã™ã‹ï¼Ÿ
+ <usetemplate ignoretext="複数ã®ã‚¢ã‚¤ãƒ†ãƒ ã‚’è¿”ã—ã¾ã™ã‹ï¼Ÿ" name="okcancelignore" notext="ã„ã„ãˆ" yestext="ã¯ã„"/>
+ </notification>
+ <notification name="PathfindingDeleteMultipleItems">
+ [NUM_ITEMS] 個ã®ã‚¢ã‚¤ãƒ†ãƒ ã‚’削除中ã§ã™ã€‚続ã‘ã¾ã™ã‹ï¼Ÿ
+ <usetemplate ignoretext="複数ã®ã‚¢ã‚¤ãƒ†ãƒ ã‚’削除ã—ã¾ã™ã‹ï¼Ÿ" name="okcancelignore" notext="ã„ã„ãˆ" yestext="ã¯ã„"/>
+ </notification>
+ <notification name="AvatarFrozen">
+ [AV_FREEZER] ã«ã‚ˆã£ã¦ã‚ãªãŸã¯ãƒ•ãƒªãƒ¼ã‚ºã•ã‚Œã¦ã„ã¾ã™ã€‚世界を動ã‹ã™ã“ã¨ã‚‚ã€ä¸–ç•Œã¨ã‚¤ãƒ³ã‚¿ãƒ©ã‚¯ã‚·ãƒ§ãƒ³ã™ã‚‹ã“ã¨ã‚‚ã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="AvatarFrozenDuration">
+ [AV_FREEZER] ã«ã‚ˆã£ã¦ã€ã‚ãªãŸã¯ [AV_FREEZE_TIME] 秒間フリーズã•ã‚Œã¾ã—ãŸã€‚世界を動ã‹ã™ã“ã¨ã‚‚ã€ä¸–ç•Œã¨ã‚¤ãƒ³ã‚¿ãƒ©ã‚¯ã‚·ãƒ§ãƒ³ã™ã‚‹ã“ã¨ã‚‚ã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="YouFrozeAvatar">
+ ã‚¢ãƒã‚¿ãƒ¼ãŒãƒ•ãƒªãƒ¼ã‚ºã•ã‚Œã¦ã„ã¾ã™ã€‚
+ </notification>
+ <notification name="AvatarHasUnFrozenYou">
+ [AV_FREEZER] ã«ã‚ˆã£ã¦ãƒ•ãƒªãƒ¼ã‚ºãŒè§£é™¤ã•ã‚Œã¦ã„ã¾ã™ã€‚
+ </notification>
+ <notification name="AvatarUnFrozen">
+ ã‚¢ãƒã‚¿ãƒ¼ã®ãƒ•ãƒªãƒ¼ã‚ºãŒè§£é™¤ã•ã‚Œã¾ã—ãŸã€‚
+ </notification>
+ <notification name="AvatarFreezeFailure">
+ ãã®åŒºç”»ã®ç®¡ç†æ¨©é™ã‚’æŒã£ã¦ã„ãªã„ãŸã‚ã€ãƒ•ãƒªãƒ¼ã‚ºã«å¤±æ•—ã—ã¾ã—ãŸã€‚
+ </notification>
+ <notification name="AvatarFreezeThaw">
+ フリーズ期間ãŒåˆ‡ã‚Œã¾ã—ãŸã€‚仕事ã«æˆ»ã£ã¦ãã ã•ã„。
+ </notification>
+ <notification name="AvatarCantFreeze">
+ 残念ãªãŒã‚‰ã€ãã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ã‚’フリーズã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="NowOwnObject">
+ ã“ã‚Œã§ã€ã‚ªãƒ–ジェクト [OBJECT_NAME] ã®æ‰€æœ‰è€…ã«ãªã‚Šã¾ã—ãŸ
+ </notification>
+ <notification name="CantRezOnLand">
+ ã“ã®åœŸåœ°ã®æ‰€æœ‰è€…ãŒè¨±å¯ã—ã¦ã„ãªã„ãŸã‚ã€[OBJECT_POS] ã§ã‚ªãƒ–ジェクトを Rez ã™ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“。土地ツールを使用ã—ã¦ã€åœŸåœ°ã®æ‰€æœ‰ã‚’確èªã—ã¦ãã ã•ã„。
+ </notification>
+ <notification name="RezFailTooManyRequests">
+ リクエストãŒå¤šã™ãŽã¦ã€ã‚ªãƒ–ジェクトを Rez ã™ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="SitFailCantMove">
+ 今回移動ã§ããªã‹ã£ãŸãŸã‚ã€åº§ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="SitFailNotAllowedOnLand">
+ ãã®åœŸåœ°ã«å¯¾ã—ã¦è¨±å¯ã‚’å—ã‘ã¦ã„ãªã„ãŸã‚ã€åº§ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="SitFailNotSameRegion">
+ 移動ã—ã¦è¿‘ã¥ã‘ã¦ã¿ã¦ãã ã•ã„。オブジェクトãŒåŒã˜ãƒªãƒ¼ã‚¸ãƒ§ãƒ³ã«ãªã„ãŸã‚ã€ã‚ªãƒ–ジェクトをé…ç½®ã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="NoNewObjectRegionFull">
+ æ–°ã—ã„オブジェクトを作æˆã§ãã¾ã›ã‚“。リージョンãŒåŸ‹ã¾ã£ã¦ã„ã¾ã™ã€‚
+ </notification>
+ <notification name="FailedToPlaceObject">
+ 指定ã—ãŸå ´æ‰€ã«ã‚ªãƒ–ジェクトをé…ç½®ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ã‚‚ã†ä¸€åº¦ãŠè©¦ã—ãã ã•ã„。
+ </notification>
+ <notification name="NoOwnNoGardening">
+ 所有ã—ã¦ã„ãªã„土地ã«æœ¨ã‚„è‰ã‚’æ¤ãˆã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="NoCopyPermsNoObject">
+ オブジェクト &apos;[OBJ_NAME]&apos; をコピーã™ã‚‹æ¨©é™ãŒãªã„ãŸã‚ã€ã‚³ãƒ”ーã«å¤±æ•—ã—ã¾ã—ãŸã€‚
+ </notification>
+ <notification name="NoTransPermsNoObject">
+ オブジェクト &apos;[OBJ_NAME]&apos; ã‚’ã‚ãªãŸã«è»¢é€ã§ããªã„ãŸã‚ã€ã‚³ãƒ”ーã«å¤±æ•—ã—ã¾ã—ãŸã€‚
+ </notification>
+ <notification name="AddToNavMeshNoCopy">
+ オブジェクト &apos;[OBJ_NAME]&apos; ãŒãƒŠãƒ“メッシュã«è²¢çŒ®ã—ã¦ã„ã‚‹ãŸã‚ã€ã‚³ãƒ”ーã«å¤±æ•—ã—ã¾ã—ãŸã€‚
+ </notification>
+ <notification name="DupeWithNoRootsSelected">
+ ルートオブジェクトをé¸æŠžã›ãšã«è¤‡è£½ã—ã¾ã™ã€‚
+ </notification>
+ <notification name="CantDupeCuzRegionIsFull">
+ リージョンãŒåŸ‹ã¾ã£ã¦ã„ã‚‹ãŸã‚ã€ã‚ªãƒ–ジェクトã®ã‚³ãƒ”ーを作æˆã™ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="CantDupeCuzParcelNotFound">
+ オブジェクトã®ã‚³ãƒ”ーを作æˆã§ãã¾ã›ã‚“。オブジェクトã®ã‚る区画ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“。
+ </notification>
+ <notification name="CantCreateCuzParcelFull">
+ 区画ãŒã„ã£ã±ã„ã®ãŸã‚ã€
+オブジェクトを作æˆã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="RezAttemptFailed">
+ オブジェクトã¸ã® Rez ã®è©¦ã¿ã«å¤±æ•—ã—ã¾ã—ãŸã€‚
+ </notification>
+ <notification name="ToxicInvRezAttemptFailed">
+ ã“ã®ãƒªãƒ¼ã‚¸ãƒ§ãƒ³ã§å•é¡Œã‚’引ãèµ·ã“ã™ã‚¢ã‚¤ãƒ†ãƒ ã¯ä½œæˆã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="InvItemIsBlacklisted">
+ ãã®æŒã¡ç‰©ã‚¢ã‚¤ãƒ†ãƒ ã¯ãƒ–ラックリストã«ç™»éŒ²ã•ã‚Œã¦ã„ã¾ã™ã€‚
+ </notification>
+ <notification name="NoCanRezObjects">
+ ç¾åœ¨ã‚ãªãŸã«ã¯ã‚ªãƒ–ジェクトを作æˆã™ã‚‹ãŸã‚ã®è¨±å¯ãŒã‚ã‚Šã¾ã›ã‚“。
+ </notification>
+ <notification name="LandSearchBlocked">
+ 土地ã®æ¤œç´¢ãŒãƒ–ロックã•ã‚Œã¾ã—ãŸã€‚
+短期間ã«å¤šãã®åœŸåœ°ã‚’検索ã—ãŸãŸã‚ã§ã™ã€‚
+ã—ã°ã‚‰ãã—ã¦ã‹ã‚‰å†åº¦ãŠè©¦ã—ãã ã•ã„。
+ </notification>
+ <notification name="NotEnoughResourcesToAttach">
+ オブジェクトã®ç€ç”¨ã«ä½¿ç”¨ã§ãるスクリプトリソースãŒè¶³ã‚Šã¾ã›ã‚“。
+ </notification>
+ <notification name="YouDiedAndGotTPHome">
+ 死んã§ã—ã¾ã£ãŸã®ã§ã€ãƒ›ãƒ¼ãƒ ã«ãƒ†ãƒ¬ãƒãƒ¼ãƒˆã•ã‚Œã¾ã—ãŸã€‚
+ </notification>
+ <notification name="EjectComingSoon">
+ ã“ã“ã¸ã®å…¥å ´ãŒè¨±å¯ã•ã‚Œã¦ã„ãªã„ãŸã‚ã€[EJECT_TIME] 秒後ã«è¿½æ”¾ã•ã‚Œã¾ã™ã€‚
+ </notification>
+ <notification name="NoEnterServerFull">
+ サーãƒãƒ¼ãŒåŸ‹ã¾ã£ã¦ã„ã‚‹ãŸã‚ã€
+ã“ã®ãƒªãƒ¼ã‚¸ãƒ§ãƒ³ã«å…¥å ´ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="SaveBackToInvDisabled">
+ 「「æŒã¡ç‰©ã€ã«ä¿å­˜ã€ãŒç„¡åŠ¹ã«ãªã£ã¦ã„ã¾ã™ã€‚
+ </notification>
+ <notification name="NoExistNoSaveToContents">
+ &apos;[OBJ_NAME]&apos; ã® Rez å…ƒã§ã‚るオブジェクトãŒå­˜åœ¨ã—ãªã„ãŸã‚ã€ã“ã®ã‚ªãƒ–ジェクトをオブジェクトコンテンツã«ä¿å­˜ã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="NoModNoSaveToContents">
+ オブジェクト &apos;[DEST_NAME]&apos; を修正ã™ã‚‹æ¨©é™ãŒãªã„ãŸã‚ã€ã‚ªãƒ–ジェクトã®ã‚³ãƒ³ãƒ†ãƒ³ãƒ„ã« &apos;[OBJ_NAME]&apos; ã‚’ä¿å­˜ã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="NoSaveBackToInvDisabled">
+ インベントリ㫠&apos;[OBJ_NAME]&apos; ã‚’ä¿å­˜ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“ - ã“ã®æ“作ãŒç„¡åŠ¹ã«ãªã£ã¦ã„ã¾ã™ã€‚
+ </notification>
+ <notification name="NoCopyNoSelCopy">
+ オブジェクト &apos;[OBJ_NAME]&apos; を変更ã™ã‚‹æ¨©é™ã‚’æŒã£ã¦ã„ãªã„ãŸã‚ã€é¸æŠžã—ãŸã‚‚ã®ã‚’コピーã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="NoTransNoSelCopy">
+ オブジェクト &apos;[OBJ_NAME]&apos; を転é€ã§ããªã„ãŸã‚ã€é¸æŠžã—ãŸã‚‚ã®ã‚’コピーã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="NoTransNoCopy">
+ オブジェクト &apos;[OBJ_NAME]&apos; を転é€ã§ããªã„ãŸã‚ã€é¸æŠžã—ãŸã‚‚ã®ã‚’コピーã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="NoPermsNoRemoval">
+ シミュレータã‹ã‚‰ã®ã‚ªãƒ–ジェクト &apos;[OBJ_NAME]&apos; ã®å‰Šé™¤ã¯ã€æ¨©é™ã‚·ã‚¹ãƒ†ãƒ ã«ã‚ˆã£ã¦ç„¡åŠ¹ã«ã•ã‚Œã¦ã„ã¾ã™ã€‚
+ </notification>
+ <notification name="NoModNoSaveSelection">
+ オブジェクト &apos;[OBJ_NAME]&apos; を変更ã™ã‚‹æ¨©é™ã‚’æŒã£ã¦ã„ãªã„ãŸã‚ã€é¸æŠžã—ãŸã‚‚ã®ã‚’ä¿å­˜ã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="NoCopyNoSaveSelection">
+ オブジェクト &apos;[OBJ_NAME]&apos; をコピーã§ããªã„ãŸã‚ã€é¸æŠžã—ãŸã‚‚ã®ã‚’ä¿å­˜ã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="NoModNoTaking">
+ オブジェクト &apos;[OBJ_NAME]&apos; を変更ã™ã‚‹æ¨©é™ã‚’æŒã£ã¦ã„ãªã„ãŸã‚ã€é¸æŠžã—ãŸã‚‚ã®ã‚’å–å¾—ã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="RezDestInternalError">
+ 内部エラー: ä¸æ˜Žãªå®›å…ˆã‚¿ã‚¤ãƒ—。
+ </notification>
+ <notification name="DeleteFailObjNotFound">
+ オブジェクトãŒè¦‹ã¤ã‹ã‚‰ãªã„ãŸã‚削除ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚
+ </notification>
+ <notification name="SorryCantEjectUser">
+ 残念ãªãŒã‚‰ã€ãã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ã‚’追放ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="RegionSezNotAHome">
+ ã“ã®ãƒªãƒ¼ã‚¸ãƒ§ãƒ³ã§ã¯ã€ã“ã“ã«ãƒ›ãƒ¼ãƒ ã®ä½ç½®ã‚’設定ã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="HomeLocationLimits">
+ ホームã®å ´æ‰€ã‚’設定ã§ãã‚‹ã®ã¯ã€è‡ªåˆ†ã®åœŸåœ°ã‹ã€ã¾ãŸã¯ãƒ¡ã‚¤ãƒ³ãƒ©ãƒ³ãƒ‰ã®ã‚¤ãƒ³ãƒ•ã‚©ãƒãƒ–ã§ã®ã¿ã§ã™ã€‚
+ </notification>
+ <notification name="HomePositionSet">
+ 家ã®é…ç½®ã®è¨­å®šã€‚
+ </notification>
+ <notification name="AvatarEjected">
+ ã‚¢ãƒã‚¿ãƒ¼ãŒè¿½æ”¾ã•ã‚Œã¾ã—ãŸã€‚
+ </notification>
+ <notification name="AvatarEjectFailed">
+ ãã®åŒºç”»ã®ç®¡ç†æ¨©é™ãŒãªã„ãŸã‚ã€è¿½æ”¾ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚
+ </notification>
+ <notification name="CantMoveObjectParcelFull">
+ 区画ãŒåŸ‹ã¾ã£ã¦ã„ã‚‹ãŸã‚ã€ã‚ªãƒ–ジェクト &apos;[OBJECT_NAME]&apos; ã‚’ã€ãƒªãƒ¼ã‚¸ãƒ§ãƒ³ [REGION_NAME] 内㮠[OBJ_POSITION] ã«ç§»å‹•ã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="CantMoveObjectParcelPerms">
+ オブジェクト &apos;[OBJECT_NAME]&apos; ã¯ã€ã“ã®åŒºç”»ã§è¨±å¯ã•ã‚Œã¦ã„ãªã„ãŸã‚ã€ãƒªãƒ¼ã‚¸ãƒ§ãƒ³ [REGION_NAME] 内㮠[OBJ_POSITION] ã«ç§»å‹•ã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="CantMoveObjectParcelResources">
+ ã“ã®åŒºç”»ã§ã“ã®ã‚ªãƒ–ジェクトã®ãƒªã‚½ãƒ¼ã‚¹ãŒä¸è¶³ã—ã¦ã„ã‚‹ãŸã‚ã€ã‚ªãƒ–ジェクト &apos;[OBJECT_NAME]&apos; をリージョン [REGION_NAME] 内㮠[OBJ_POSITION] ã«ç§»å‹•ã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="CantMoveObjectRegionVersion">
+ オブジェクト &apos;[OBJECT_NAME]&apos; をリージョン [REGION_NAME] 内㮠[OBJ_POSITION] ã«ç§»å‹•ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。他ã®ãƒªãƒ¼ã‚¸ãƒ§ãƒ³ã§ã¯ã€ãƒªãƒ¼ã‚¸ãƒ§ãƒ³ã®å¢ƒç•Œã‚’ã¾ãŸã„ã ã“ã®ã‚ªãƒ–ジェクトをå—ä¿¡ã™ã‚‹ã“ã¨ãŒã§ããªã„å¤ã„ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’実行ã—ã¦ã„ã‚‹ãŸã‚ã§ã™ã€‚
+ </notification>
+ <notification name="CantMoveObjectNavMesh">
+ リージョン境界をã¾ãŸãナビメッシュを変更ã§ããªã„ãŸã‚ã€ã‚ªãƒ–ジェクト &apos;[OBJECT_NAME]&apos; をリージョン [REGION_NAME] 内㮠[OBJ_POSITION] ã«ç§»å‹•ã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="CantMoveObjectWTF">
+ ä¸æ˜Žãªç†ç”±ã«ã‚ˆã‚Šã€ã‚ªãƒ–ジェクト &apos;[OBJECT_NAME]&apos; ã‚’ã€ãƒªãƒ¼ã‚¸ãƒ§ãƒ³ [REGION_NAME] 内㮠[OBJ_POSITION] ã«ç§»å‹•ã§ãã¾ã›ã‚“。
+([FAILURE_TYPE])
+ </notification>
+ <notification name="NoPermModifyObject">
+ ãã®ã‚ªãƒ–ジェクトを変更ã™ã‚‹æ¨©é™ãŒã‚ã‚Šã¾ã›ã‚“
+ </notification>
+ <notification name="CantEnablePhysObjContributesToNav">
+ ナビメッシュã«è²¢çŒ®ã™ã‚‹ã‚ªãƒ–ジェクトã«å¯¾ã—ã¦ç‰©ç†ã‚’有効ã«ã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="CantEnablePhysKeyframedObj">
+ キーフレームオブジェクトã®ãŸã‚ã«ç‰©ç†ã‚’有効ã«ã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="CantEnablePhysNotEnoughLandResources">
+ 土地ã®ãƒªã‚½ãƒ¼ã‚¹ãŒè¶³ã‚Šãªã„ãŸã‚ã€ã‚ªãƒ–ジェクトã®ç‰©ç†ã‚’有効ã«ã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="CantEnablePhysCostTooGreat">
+ [MAX_OBJECTS] より大ãã„物ç†ãƒªã‚½ãƒ¼ã‚¹ã‚³ã‚¹ãƒˆã‚’æŒã¤ã‚ªãƒ–ジェクトã§ã¯ã€ç‰©ç†ã‚’有効ã«ã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="PhantomWithConcavePiece">
+ ã“ã®ã‚ªãƒ–ジェクトã¯ãƒ•ã‚¡ãƒ³ãƒˆãƒ ã§ã€ãƒŠãƒ“メッシュã«è²¢çŒ®ã—ã¦ã„ã‚‹ãŸã‚ã€ãã¼ã¿ã‚’æŒãŸã›ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="UnableAddItem">
+ アイテムを追加ã§ãã¾ã›ã‚“!
+ </notification>
+ <notification name="UnableEditItem">
+ ã“ã‚Œã¯ç·¨é›†ã§ãã¾ã›ã‚“!
+ </notification>
+ <notification name="NoPermToEdit">
+ ã“れを編集ã™ã‚‹è¨±å¯ãŒã‚ã‚Šã¾ã›ã‚“。
+ </notification>
+ <notification name="NoPermToCopyInventory">
+ ãã®ã‚¤ãƒ³ãƒ™ãƒ³ãƒˆãƒªã‚’コピーã™ã‚‹ã“ã¨ã¯è¨±å¯ã•ã‚Œã¾ã›ã‚“。
+ </notification>
+ <notification name="CantSaveItemDoesntExist">
+ オブジェクトã®ã‚³ãƒ³ãƒ†ãƒ³ãƒ„ã«ä¿å­˜ã§ãã¾ã›ã‚“。アイテムãŒå­˜åœ¨ã—ã¦ã„ã¾ã›ã‚“。
+ </notification>
+ <notification name="CantSaveItemAlreadyExists">
+ オブジェクトã®ã‚³ãƒ³ãƒ†ãƒ³ãƒ„ã«ä¿å­˜ã§ãã¾ã›ã‚“。åŒã˜åå‰ã‚’æŒã¤ã‚¢ã‚¤ãƒ†ãƒ ãŒã™ã§ã«ã‚¤ãƒ³ãƒ™ãƒ³ãƒˆãƒªã«å­˜åœ¨ã—ã¾ã™ã€‚
+ </notification>
+ <notification name="CantSaveModifyAttachment">
+ オブジェクトã®ã‚³ãƒ³ãƒ†ãƒ³ãƒ„ã«ä¿å­˜ã§ãã¾ã›ã‚“。ã“ã®ãŸã‚ã€ã‚¢ã‚¿ãƒƒãƒãƒ¡ãƒ³ãƒˆã®æ¨©é™ãŒå¤‰æ›´ã•ã‚Œã¾ã™ã€‚
+ </notification>
+ <notification name="TooManyScripts">
+ スクリプトãŒå¤šã™ãŽã¾ã™ã€‚
+ </notification>
+ <notification name="UnableAddScript">
+ テキストを追加ã§ãã¾ã›ã‚“!
+ </notification>
+ <notification name="AssetServerTimeoutObjReturn">
+ 資産サーãƒãƒ¼ãŒã‚¿ã‚¤ãƒ ãƒªãƒ¼ã«å¿œç­”ã—ã¾ã›ã‚“ã§ã—ãŸã€‚オブジェクト㌠sim ã«è¿”ã•ã‚Œã¾ã—ãŸã€‚
+ </notification>
+ <notification name="RegionDisablePhysicsShapes">
+ ã“ã®ãƒªãƒ¼ã‚¸ãƒ§ãƒ³ã§ã¯ã€ç‰©ç†çš„シェイプãŒæœ‰åŠ¹ã«ã•ã‚Œã¦ã„ã¾ã›ã‚“。
+ </notification>
+ <notification name="NoModNavmeshAcrossRegions">
+ リージョンã®å¢ƒç•Œã‚’ã¾ãŸãナビメッシュã¯å¤‰æ›´ã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="NoSetPhysicsPropertiesOnObjectType">
+ ãã®ã‚ªãƒ–ジェクトタイプã®ç‰©ç†çš„プロパティを設定ã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="NoSetRootPrimWithNoShape">
+ ルートプリムを設定ã§ããªã„ãŸã‚ã€ã‚·ã‚§ã‚¤ãƒ—ãŒã‚ã‚Šã¾ã›ã‚“。
+ </notification>
+ <notification name="NoRegionSupportPhysMats">
+ ã“ã®ãƒªãƒ¼ã‚¸ãƒ§ãƒ³ã§ã¯ã€ç‰©ç†çš„ç´ æãŒæœ‰åŠ¹ã«ã•ã‚Œã¦ã„ã¾ã›ã‚“。
+ </notification>
+ <notification name="OnlyRootPrimPhysMats">
+ 物ç†çš„ç´ æを調整ã§ãã‚‹ã®ã¯ã€ãƒ«ãƒ¼ãƒˆãƒ—リムã ã‘ã§ã™ã€‚
+ </notification>
+ <notification name="NoSupportCharacterPhysMats">
+ キャラクターã¸ã®ç‰©ç†çš„ç´ æã®è¨­å®šã¯ã¾ã ã‚µãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ã¾ã›ã‚“。
+ </notification>
+ <notification name="InvalidPhysMatProperty">
+ 指定ã—ãŸç‰©ç†çš„ç´ æã®ãƒ—ロパティ㌠1 ã¤ä»¥ä¸Šç„¡åŠ¹ã§ã™ã€‚
+ </notification>
+ <notification name="NoPermsAlterStitchingMeshObj">
+ メッシュオブジェクトã®ç¸«ã„ç›®ã®ã‚¿ã‚¤ãƒ—を変更ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="NoPermsAlterShapeMeshObj">
+ メッシュオブジェクトã®å½¢çŠ¶ã‚’変更ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“
+ </notification>
+ <notification name="FullRegionCantEnter">
+ リージョンãŒåŸ‹ã¾ã£ã¦ã„ã‚‹ãŸã‚ã€\nã“ã®ãƒªãƒ¼ã‚¸ãƒ§ãƒ³ã«å…¥å ´ã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="LinkFailedOwnersDiffer">
+ リンクエラー -- 所有者ãŒé•ã„ã¾ã™
+ </notification>
+ <notification name="LinkFailedNoModNavmeshAcrossRegions">
+ リンクエラー -- リージョンã®å¢ƒç•Œã‚’ã¾ãŸãナビメッシュã¯å¤‰æ›´ã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="LinkFailedNoPermToEdit">
+ リンクエラー -- 編集権é™ãŒã‚ã‚Šã¾ã›ã‚“。
+ </notification>
+ <notification name="LinkFailedTooManyPrims">
+ リンクエラー -- プリミティブãŒå¤šã™ãŽã¾ã™ã€‚
+ </notification>
+ <notification name="LinkFailedCantLinkNoCopyNoTrans">
+ リンクエラー -- コピーãªã—ã¨è»¢é€ãªã—をリンクã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="LinkFailedNothingLinkable">
+ リンクエラー -- リンクã§ãã‚‹ã‚‚ã®ãŒã‚ã‚Šã¾ã›ã‚“。
+ </notification>
+ <notification name="LinkFailedTooManyPathfindingChars">
+ リンクエラー -- パスファインディングã®æ–‡å­—æ•°ãŒå¤šã™ãŽã¾ã™
+ </notification>
+ <notification name="LinkFailedInsufficientLand">
+ リンクエラー -- 土地ã®ãƒªã‚½ãƒ¼ã‚¹ãŒè¶³ã‚Šã¾ã›ã‚“
+ </notification>
+ <notification name="LinkFailedTooMuchPhysics">
+ オブジェクトãŒä½¿ç”¨ã—ã¦ã„る物ç†ãƒªã‚½ãƒ¼ã‚¹ãŒå¤šã™ãŽãŸãŸã‚ã€ãƒ€ã‚¤ãƒŠãƒŸãƒƒã‚¯ã‚¹ãŒç„¡åŠ¹ã«ã•ã‚Œã¾ã—ãŸã€‚
+ </notification>
+ <notification name="TeleportedHomeByObjectOnParcel">
+ 区画 &apos;[PARCEL_NAME]&apos; ã®ã‚ªãƒ–ジェクト &apos;[OBJECT_NAME]&apos; ã«ã‚ˆã£ã¦ã€ã‚ãªãŸã¯ãƒ›ãƒ¼ãƒ ã«ãƒ†ãƒ¬ãƒãƒ¼ãƒˆã•ã‚Œã¾ã—ãŸã€‚
+ </notification>
+ <notification name="TeleportedHomeByObject">
+ ​オブジェクト ​&apos;[OBJECT_NAME]&apos; ã«ã‚ˆã£ã¦ã€ã‚ãªãŸã¯ãƒ›ãƒ¼ãƒ ã¸ãƒ†ãƒ¬ãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ã¾ã™ã€‚
+ </notification>
+ <notification name="TeleportedByAttachment">
+ [ITEM_ID] ã¸ã®ã‚¢ã‚¿ãƒƒãƒãƒ¡ãƒ³ãƒˆã«ã‚ˆã£ã¦ã€ã‚ãªãŸã¯ãƒ†ãƒ¬ãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ã¾ã™ã€‚
+ </notification>
+ <notification name="TeleportedByObjectOnParcel">
+ 区画 &apos;[PARCEL_NAME]&apos; ã®ã‚ªãƒ–ジェクト &apos;[OBJECT_NAME]&apos; ã«ã‚ˆã£ã¦ã€ã‚ãªãŸã¯ãƒ†ãƒ¬ãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ã¾ã™ã€‚
+ </notification>
+ <notification name="TeleportedByObjectOwnedBy">
+ [OWNER_ID] ãŒæ‰€æœ‰ã—ã¦ã„るオブジェクト &apos;[OBJECT_NAME]&apos; ã«ã‚ˆã£ã¦ã€ã‚ãªãŸã¯ãƒ†ãƒ¬ãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ã¾ã™ã€‚
+ </notification>
+ <notification name="TeleportedByObjectUnknownUser">
+ ä¸æ˜Žãªãƒ¦ãƒ¼ã‚¶ãƒ¼ãŒæ‰€æœ‰ã—ã¦ã„るオブジェクト &apos;[OBJECT_NAME]&apos; ã«ã‚ˆã£ã¦ã€ã‚ãªãŸã¯ãƒ†ãƒ¬ãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ã¾ã™ã€‚
+ </notification>
+ <notification name="CantCreateObjectRegionFull">
+ リクエストã•ã‚ŒãŸã‚ªãƒ–ジェクトを作æˆã§ãã¾ã›ã‚“。リージョンãŒåŸ‹ã¾ã£ã¦ã„ã¾ã™ã€‚
+ </notification>
+ <notification name="CantAttackMultipleObjOneSpot">
+ 1 ã¤ã®å ´æ‰€ã«è¤‡æ•°ã®ã‚ªãƒ–ジェクトをç€ç”¨ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="CantCreateMultipleObjAtLoc">
+ ã“ã“ã§ã¯ã€è¤‡æ•°ã®ã‚ªãƒ–ジェクトを作æˆã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="UnableToCreateObjTimeOut">
+ リクエストã•ã‚ŒãŸã‚ªãƒ–ジェクトを作æˆã§ãã¾ã›ã‚“。オブジェクトãŒãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã«è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“。
+ </notification>
+ <notification name="UnableToCreateObjUnknown">
+ リクエストã•ã‚ŒãŸã‚ªãƒ–ジェクトを作æˆã§ãã¾ã›ã‚“。リクエストãŒã‚¿ã‚¤ãƒ ã‚¢ã‚¦ãƒˆã«ãªã‚Šã¾ã—ãŸã€‚ã‚‚ã†ä¸€åº¦ãŠè©¦ã—ãã ã•ã„。
+ </notification>
+ <notification name="UnableToCreateObjMissingFromDB">
+ è¦æ±‚ã•ã‚ŒãŸã‚ªãƒ–ジェクトを作æˆã§ãã¾ã›ã‚“。もã†ä¸€åº¦ãŠè©¦ã—ãã ã•ã„。
+ </notification>
+ <notification name="RezFailureTookTooLong">
+ リクエストã•ã‚ŒãŸã‚ªãƒ–ジェクトã®ãƒ­ãƒ¼ãƒ‰ã«æ™‚é–“ãŒã‹ã‹ã‚Šã™ãŽãŸãŸã‚ã€Rez ã«å¤±æ•—ã—ã¾ã—ãŸã€‚
+ </notification>
+ <notification name="FailedToPlaceObjAtLoc">
+ 指定ã—ãŸå ´æ‰€ã«ã‚ªãƒ–ジェクトをé…ç½®ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ã‚‚ã†ä¸€åº¦ãŠè©¦ã—ãã ã•ã„。
+ </notification>
+ <notification name="CantCreatePlantsOnLand">
+ ã“ã®åœŸåœ°ã«æœ¨ã‚’æ¤ãˆã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="CantRestoreObjectNoWorldPos">
+ オブジェクトをリストアã§ãã¾ã›ã‚“。ワールドã®ä½ç½®ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“。
+ </notification>
+ <notification name="CantRezObjectInvalidMeshData">
+ メッシュデータãŒç„¡åŠ¹ãªãŸã‚ã€ã‚ªãƒ–ジェクトを Rez ã™ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="CantRezObjectTooManyScripts">
+ ã“ã®ãƒªãƒ¼ã‚¸ãƒ§ãƒ³ã«æ—¢ã«å¤šãã®ã‚¹ã‚¯ãƒªãƒ—トãŒå­˜åœ¨ã™ã‚‹ãŸã‚ã€ã‚ªãƒ–ジェクトを Rez ã™ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="CantCreateObjectNoAccess">
+ ç¾åœ¨ã®ã‚¢ã‚¯ã‚»ã‚¹æ¨©é™ã§ã¯ã€ãã“ã«ã‚ªãƒ–ジェクトを作æˆã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="CantCreateObject">
+ ç¾åœ¨ã‚ãªãŸã«ã¯ã‚ªãƒ–ジェクト作æˆã™ã‚‹è¨±å¯ãŒã‚ã‚Šã¾ã›ã‚“。
+ </notification>
+ <notification name="InvalidObjectParams">
+ 無効ãªã‚ªãƒ–ジェクトパラメーター
+ </notification>
+ <notification name="CantDuplicateObjectNoAcess">
+ ç¾åœ¨ã®ã‚¢ã‚¯ã‚»ã‚¹æ¨©é™ã§ã¯ã€ã“ã“ã«ã‚ªãƒ–ジェクトã®ã‚³ãƒ”ーを作æˆã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="CantChangeShape">
+ ã‚ãªãŸã«ã¯ã“ã®ã‚·ã‚§ã‚¤ãƒ—を変更ã™ã‚‹è¨±å¯ãŒã‚ã‚Šã¾ã›ã‚“。
+ </notification>
+ <notification name="NoAccessToClaimObjects">
+ ç¾åœ¨ã®ã‚¢ã‚¯ã‚»ã‚¹æ¨©é™ã§ã¯ã€ã“ã“ã«ã‚ªãƒ–ジェクトをå–å¾—ã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="DeedFailedNoPermToDeedForGroup">
+ ã‚ãªãŸã®ã‚°ãƒ«ãƒ¼ãƒ—ã«ã‚ªãƒ–ジェクトを譲渡ã™ã‚‹æ¨©é™ãŒãªã„ãŸã‚ã€è­²æ¸¡ã«å¤±æ•—ã—ã¾ã—ãŸã€‚
+ </notification>
+ <notification name="NoPrivsToBuyObject">
+ ç¾åœ¨ã®ã‚¢ã‚¯ã‚»ã‚¹æ¨©é™ã§ã¯ã€ã“ã“ã§ã‚ªãƒ–ジェクトを購入ã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="CantAttachObjectAvatarSittingOnIt">
+ ã‚¢ãƒã‚¿ãƒ¼ãŒã‚ªãƒ–ジェクトã«å­˜åœ¨ã™ã‚‹ãŸã‚ã€ã‚ªãƒ–ジェクトをç€ç”¨ã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="WhyAreYouTryingToWearShrubbery">
+ 木やè‰ã‚’アタッãƒãƒ¡ãƒ³ãƒˆã¨ã—ã¦ç€ç”¨ã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="CantAttachGroupOwnedObjs">
+ グループãŒæ‰€æœ‰ã—ã¦ã„るオブジェクトã¯ç€ç”¨ã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="CantAttachObjectsNotOwned">
+ 所有ã—ã¦ã„ãªã„オブジェクトã¯ç€ç”¨ã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="CantAttachNavmeshObjects">
+ ナビメッシュã«è²¢çŒ®ã—ã¦ã„るオブジェクトã¯ç€ç”¨ã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="CantAttachObjectNoMovePermissions">
+ ã‚ãªãŸã«ã¯ã‚ªãƒ–ジェクトを移動ã™ã‚‹æ¨©é™ãŒãªã„ãŸã‚ã€ãã®ã‚ªãƒ–ジェクト添付ã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="CantAttachNotEnoughScriptResources">
+ オブジェクトã®ç€ç”¨ã«ä½¿ç”¨ã§ãるスクリプトリソースãŒè¶³ã‚Šã¾ã›ã‚“。
+ </notification>
+ <notification name="CantDropItemTrialUser">
+ オブジェクトをã“ã“ã«ãƒ‰ãƒ­ãƒƒãƒ—ã§ãã¾ã›ã‚“。フリートライアル領域をãŠè©¦ã—ãã ã•ã„。
+ </notification>
+ <notification name="CantDropMeshAttachment">
+ メッシュアタッãƒãƒ¡ãƒ³ãƒˆã‚’ドロップã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。インベントリã‹ã‚‰åˆ‡ã‚Šé›¢ã—ã¦ã€ãƒ¯ãƒ¼ãƒ«ãƒ‰ã§ Rez ã—ã¦ãã ã•ã„。
+ </notification>
+ <notification name="CantDropAttachmentNoPermission">
+ アタッãƒãƒ¡ãƒ³ãƒˆã®ãƒ‰ãƒ­ãƒƒãƒ—ã«å¤±æ•—ã—ã¾ã—ãŸã€‚ãã“ã¸ãƒ‰ãƒ­ãƒƒãƒ—ã™ã‚‹æ¨©é™ãŒã‚ã‚Šã¾ã›ã‚“。
+ </notification>
+ <notification name="CantDropAttachmentInsufficientLandResources">
+ アタッãƒãƒ¡ãƒ³ãƒˆã®ãƒ‰ãƒ­ãƒƒãƒ—ã«å¤±æ•—ã—ã¾ã—ãŸã€‚利用ã§ãる土地リソースã®æ•°ãŒè¶³ã‚Šã¾ã›ã‚“。
+ </notification>
+ <notification name="CantDropAttachmentInsufficientResources">
+ 利用ã§ãるリソースãŒè¶³ã‚Šãªã„ãŸã‚ã€ã‚¢ã‚¿ãƒƒãƒãƒ¡ãƒ³ãƒˆã®ãƒ‰ãƒ­ãƒƒãƒ—ã«å¤±æ•—ã—ã¾ã—ãŸã€‚
+ </notification>
+ <notification name="CantDropObjectFullParcel">
+ ã“ã“ã«ã‚ªãƒ–ジェクトをドロップã§ãã¾ã›ã‚“。区画ãŒåŸ‹ã¾ã£ã¦ã„ã¾ã™ã€‚
+ </notification>
+ <notification name="CantTouchObjectBannedFromParcel">
+ 土地区画ã«å…¥å ´ã™ã‚‹ã“ã¨ã‚’ç¦æ­¢ã•ã‚Œã¦ã„ã‚‹ãŸã‚ã€ã“ã®ã‚ªãƒ–ジェクトを触ã£ãŸã‚Šã€ã¤ã‹ã‚€ã“ã¨ãŒã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="PlzNarrowDeleteParams">
+ 削除パラメーターを絞ã£ã¦ãã ã•ã„。
+ </notification>
+ <notification name="UnableToUploadAsset">
+ 資産をアップロードã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="CantTeleportCouldNotFindUser">
+ ホームをテレãƒãƒ¼ãƒˆã™ã‚‹ãƒ¦ãƒ¼ã‚¶ãƒ¼ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸã€‚
+ </notification>
+ <notification name="GodlikeRequestFailed">
+ éŽå‰°ãªãƒªã‚¯ã‚¨ã‚¹ãƒˆãŒå¤±æ•—ã—ã¾ã—ãŸ
+ </notification>
+ <notification name="GenericRequestFailed">
+ 一般的ãªãƒªã‚¯ã‚¨ã‚¹ãƒˆã«å¤±æ•—ã—ã¾ã—ãŸ
+ </notification>
+ <notification name="CantUploadPostcard">
+ ãƒã‚¹ãƒˆã‚«ãƒ¼ãƒ‰ã‚’アップロードã§ãã¾ã›ã‚“。後ã§ã‚‚ã†ä¸€åº¦ãŠè©¦ã—ãã ã•ã„。
+ </notification>
+ <notification name="CantFetchInventoryForGroupNotice">
+ グループ通知ã®ã‚¤ãƒ³ãƒ™ãƒ³ãƒˆãƒªã®è©³ç´°ã‚’å–å¾—ã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="CantSendGroupNoticeNotPermitted">
+ グループ通知ã®é€ä¿¡ãŒè¨±å¯ã•ã‚Œãªã„ãŸã‚ã€é€ä¿¡ã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="CantSendGroupNoticeCantConstructInventory">
+ グループ通知をé€ä¿¡ã§ãã¾ã›ã‚“。æŒã¡ç‰©ã‚’作æˆã™ã‚‹ã“ã¨ã‚‚ã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="CantParceInventoryInNotice">
+ 通知内ã®æŒã¡ç‰©ã‚’検出ã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="TerrainUploadFailed">
+ 地形ã®ã‚¢ãƒƒãƒ—ロードã«å¤±æ•—ã—ã¾ã—ãŸã€‚
+ </notification>
+ <notification name="TerrainFileWritten">
+ 地形ファイルãŒæ›¸ãè¾¼ã¾ã‚Œã¾ã—ãŸã€‚
+ </notification>
+ <notification name="TerrainFileWrittenStartingDownload">
+ 地形ファイルを書ã出ã—ã€ãƒ€ã‚¦ãƒ³ãƒ­ãƒ¼ãƒ‰ã‚’開始ã—ã¦ã„ã¾ã™...
+ </notification>
+ <notification name="TerrainBaked">
+ 地形ãŒãƒ™ãƒ¼ã‚¯ã•ã‚Œã¾ã—ãŸã€‚
+ </notification>
+ <notification name="TenObjectsDisabledPlzRefresh">
+ é¸æŠžã•ã‚ŒãŸæœ€åˆã® 10 個ã®ã‚ªãƒ–ジェクトã®ã¿ãŒç„¡åŠ¹ã«ã•ã‚Œã¾ã—ãŸã€‚å¿…è¦ã«å¿œã˜ã¦ã€ãƒªãƒ•ãƒ¬ãƒƒã‚·ãƒ¥ã—ã¦é¸æŠžå†…容を追加ã—ã¦ãã ã•ã„。
+ </notification>
+ <notification name="UpdateViewerBuyParcel">
+ ã“ã®åŒºç”»ã‚’購入ã™ã‚‹ã«ã¯ã€ãƒ“ューワをアップデートã™ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚
+ </notification>
+ <notification name="CantBuyParcelNotForSale">
+ 購入ã™ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“。ã“ã®åŒºç”»ã¯è²©å£²å¯¾è±¡ã§ã¯ã‚ã‚Šã¾ã›ã‚“。
+ </notification>
+ <notification name="CantBuySalePriceOrLandAreaChanged">
+ 販売価格ã¾ãŸã¯åœŸåœ°ã®é¢ç©ãŒå¤‰ã‚ã£ãŸãŸã‚ã€è³¼å…¥ã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="CantBuyParcelNotAuthorized">
+ ã‚ãªãŸã¯ã“ã®åŒºç”»ã®å§”ä»»ã•ã‚ŒãŸè²·ã„手ã§ã¯ã‚ã‚Šã¾ã›ã‚“。
+ </notification>
+ <notification name="CantBuyParcelAwaitingPurchaseAuth">
+ ã™ã§ã«è³¼å…¥ã®èªè¨¼ã‚’å¾…æ©Ÿã—ã¦ã„ã‚‹ãŸã‚ã€ã“ã®åŒºç”»ã‚’購入ã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="CantBuildOverflowParcel">
+ 区画をオーãƒãƒ¼ãƒ•ãƒ­ãƒ¼ã™ã‚‹ãŸã‚ã€ã“ã“ã§ã‚ªãƒ–ジェクトを構築ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="SelectedMultipleOwnedLand">
+ 所有者ã®é•ã†åœŸåœ°ã‚’é¸ã³ã¾ã—ãŸã€‚é¸æŠžã™ã‚‹é¢ç©ã‚’å°ã•ãã—ã¦ã€ã‚‚ã†ä¸€åº¦è©¦ã—ã¦ãã ã•ã„。
+ </notification>
+ <notification name="CantJoinTooFewLeasedParcels">
+ é¸æŠžç¯„囲ã®ãƒªãƒ¼ã‚¹åŒºç”»ã®æ•°ãŒå°‘ãªã„ãŸã‚ã€å‚加ã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="CantDivideLandMultipleParcelsSelected">
+ 土地を分割ã§ãã¾ã›ã‚“。\n区画ãŒè¤‡æ•°é¸æŠžã•ã‚Œã¦ã„ã¾ã™ã€‚\nã‚‚ã£ã¨å°ã•ã„土地をé¸æŠžã—ã¦ã¿ã¦ãã ã•ã„。
+ </notification>
+ <notification name="CantDivideLandCantFindParcel">
+ 土地を分解ã§ãã¾ã›ã‚“。\n区画ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“。\n「Helpã€&gt;「Reprt Bug...ã€ã§ãƒ¬ãƒãƒ¼ãƒˆã‚’è¡Œã£ã¦ãã ã•ã„。
+ </notification>
+ <notification name="CantDivideLandWholeParcelSelected">
+ 土地を分割ã§ãã¾ã›ã‚“。区画全体をé¸æŠžã—ã¾ã™ã€‚\nå°ã•ã„土地をé¸æŠžã—ã¦ã¿ã¦ãã ã•ã„。
+ </notification>
+ <notification name="LandHasBeenDivided">
+ 土地ãŒåˆ†å‰²ã•ã‚Œã¦ã„ã¾ã™ã€‚
+ </notification>
+ <notification name="PassPurchased">
+ 入場許å¯ã‚’購入ã—ã¾ã—ãŸã€‚
+ </notification>
+ <notification name="RegionDisallowsClassifieds">
+ リージョンã§ã¯ã€ã‚¯ãƒ©ã‚·ãƒ•ã‚¡ã‚¤ãƒ‰åºƒå‘Šã‚’許å¯ã—ã¾ã›ã‚“。
+ </notification>
+ <notification name="LandPassExpireSoon">
+ ã“ã®åœŸåœ°ã¸ã®å…¥å ´è¨±å¯ã¯ã¾ã‚‚ãªã期é™ãŒåˆ‡ã‚Œã¾ã™ã€‚
+ </notification>
+ <notification name="CantSitNoSuitableSurface">
+ é…ç½®ã«é©ã—ãŸè¡¨é¢ãŒã‚ã‚Šã¾ã›ã‚“。別ã®å ´æ‰€ã‚’試ã—ã¦ã¿ãŸãã ã•ã„。
+ </notification>
+ <notification name="CantSitNoRoom">
+ ã“ã“ã«ã¯åº§ã‚‹ä½™åœ°ãŒã‚ã‚Šã¾ã›ã‚“。他ã®å ´æ‰€ã‚’試ã—ã¦ãã ã•ã„。
+ </notification>
+ <notification name="ClaimObjectFailedNoPermission">
+ 権é™ãŒãªã„ãŸã‚ã€ã‚ªãƒ–ジェクトをå–å¾—ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚
+ </notification>
+ <notification name="ClaimObjectFailedNoMoney">
+ リンデンドルãŒè¶³ã‚Šãªã„ãŸã‚ã€ã‚ªãƒ–ジェクトã®å–å¾—ã«å¤±æ•—ã—ã¾ã—ãŸã€‚
+ </notification>
+ <notification name="CantDeedGroupLand">
+ グループ所有ã®åœŸåœ°ã¯ã€è­²æ¸¡ã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="BuyObjectFailedNoMoney">
+ リンデンドルãŒè¶³ã‚Šãªã„ãŸã‚ã€ã‚ªãƒ–ジェクトã®è³¼å…¥ã«å¤±æ•—ã—ã¾ã—ãŸã€‚
+ </notification>
+ <notification name="BuyInventoryFailedNoMoney">
+ リンデンドルãŒä¸è¶³ã—ã¦ã„ã‚‹ãŸã‚ã€ã‚¤ãƒ³ãƒ™ãƒ³ãƒˆãƒªã‚’購入ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚
+ </notification>
+ <notification name="BuyPassFailedNoMoney">
+ リンデンドルãŒè¶³ã‚Šãªã„ãŸã‚ã€ã“ã®åœŸåœ°ã¸ã®å…¥å ´è¨±å¯ã‚’購入ã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="CantBuyPassTryAgain">
+ 今ã™ãã«ã¯å…¥å ´è¨±å¯ã‚’購入ã§ãã¾ã›ã‚“。後ã§ã‚‚ã†ä¸€åº¦ãŠè©¦ã—ãã ã•ã„。
+ </notification>
+ <notification name="CantCreateObjectParcelFull">
+ 区画ãŒåŸ‹ã¾ã£ã¦ã„ã‚‹ãŸã‚ã€ã‚ªãƒ–ジェクトを\n作æˆã™ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="FailedPlacingObject">
+ 指定ã—ãŸå ´æ‰€ã«ã‚ªãƒ–ジェクトをé…ç½®ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ã‚‚ã†ä¸€åº¦ãŠè©¦ã—ãã ã•ã„。
+ </notification>
+ <notification name="CantCreateLandmarkForEvent">
+ イベントã®ãŸã‚ã®ãƒ©ãƒ³ãƒ‰ãƒžãƒ¼ã‚¯ã‚’作æˆã™ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="GodBeatsFreeze">
+ 強力ãªåŠ›ã§ãƒ•ãƒªãƒ¼ã‚ºã‚’解除ã—ã¾ã™ã€‚
+ </notification>
+ <notification name="SpecialPowersRequestFailedLogged">
+ 特殊ãªæ¨©é™ã®ãƒªã‚¯ã‚¨ã‚¹ãƒˆã«å¤±æ•—ã—ã¾ã—ãŸã€‚ã“ã®ãƒªã‚¯ã‚¨ã‚¹ãƒˆã¯ãƒ­ã‚°ã«è¨˜éŒ²ã•ã‚Œã¦ã„ã¾ã™ã€‚
+ </notification>
+ <notification name="ExpireExplanation">
+ システムã¯ã€ç¾åœ¨ã‚ãªãŸã®ãƒªã‚¯ã‚¨ã‚¹ãƒˆã‚’処ç†ã§ãã¾ã›ã‚“。リクエストãŒã‚¿ã‚¤ãƒ ã‚¢ã‚¦ãƒˆã«ãªã‚Šã¾ã—ãŸã€‚
+ </notification>
+ <notification name="DieExplanation">
+ システムã¯ã€ã‚ãªãŸã®ãƒªã‚¯ã‚¨ã‚¹ãƒˆã‚’処ç†ã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="AddPrimitiveFailure">
+ プリミティブ広告を出ã™ã«ã¯ã€è³‡é‡‘ãŒè¶³ã‚Šã¾ã›ã‚“。
+ </notification>
+ <notification name="RezObjectFailure">
+ 資金ãŒè¶³ã‚Šãªã„ãŸã‚ã€ã‚ªãƒ–ジェクトを作æˆã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="ResetHomePositionNotLegal">
+ ホームãŒä¸æ­£ãªãŸã‚ã€ãƒ›ãƒ¼ãƒ ã®ä½ç½®ã‚’リセットã—ã¾ã™ã€‚
+ </notification>
+ <notification name="CantInviteRegionFull">
+ リージョンãŒåŸ‹ã¾ã£ã¦ã„ã‚‹ãŸã‚ã€ç¾åœ¨ã®å ´æ‰€ã«èª°ã‹ã‚’招待ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。後ã§ã‚‚ã†ä¸€åº¦ãŠè©¦ã—ãã ã•ã„。
+ </notification>
+ <notification name="CantSetHomeAtRegion">
+ ã“ã®ãƒªãƒ¼ã‚¸ãƒ§ãƒ³ã§ã¯ã€ã“ã“ã«ãƒ›ãƒ¼ãƒ ã®ä½ç½®ã‚’設定ã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="ListValidHomeLocations">
+ ホームã®å ´æ‰€ã‚’設定ã§ãã‚‹ã®ã¯ã€è‡ªåˆ†ã®åœŸåœ°ã‹ã€ã¾ãŸã¯ãƒ¡ã‚¤ãƒ³ãƒ©ãƒ³ãƒ‰ã®ã‚¤ãƒ³ãƒ•ã‚©ãƒãƒ–ã§ã®ã¿ã§ã™ã€‚
+ </notification>
+ <notification name="SetHomePosition">
+ 家ã®é…ç½®ã®è¨­å®šã€‚
+ </notification>
+ <notification name="CantDerezInventoryError">
+ インベントリエラーã®ãŸã‚ã€ã‚ªãƒ–ジェクト㮠Rez 解除ãŒã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="CantCreateRequestedInv">
+ リクエストã•ã‚ŒãŸã‚¤ãƒ³ãƒ™ãƒ³ãƒˆãƒªã‚’作æˆã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="CantCreateRequestedInvFolder">
+ リクエストã•ã‚ŒãŸæŒã¡ç‰©ãƒ•ã‚©ãƒ«ãƒ€ãƒ¼ã‚’作æˆã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="CantCreateInventory">
+ ãã®ã‚¤ãƒ³ãƒ™ãƒ³ãƒˆãƒªã‚’作æˆã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="CantCreateLandmark">
+ ランドマークを作æˆã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="CantCreateOutfit">
+ アウトフィットをã™ãã«ã¯ä½œæˆã§ãã¾ã›ã‚“。ã—ã°ã‚‰ãã—ã¦ã‹ã‚‰å†åº¦ãŠè©¦ã—ãã ã•ã„。
+ </notification>
+ <notification name="InventoryNotForSale">
+ インベントリã¯è²©å£²å¯¾è±¡ã§ã¯ã‚ã‚Šã¾ã›ã‚“。
+ </notification>
+ <notification name="CantFindInvItem">
+ æŒã¡ç‰©ã‚¢ã‚¤ãƒ†ãƒ ã‚’見ã¤ã‘ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="CantFindObject">
+ オブジェクトãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“。
+ </notification>
+ <notification name="CantTransfterMoneyRegionDisabled">
+ オブジェクトã¸ã®é€é‡‘ã¯ã€ã“ã®ãƒªãƒ¼ã‚¸ãƒ§ãƒ³ã§ã¯ç¾åœ¨ç„¡åŠ¹ã«ã•ã‚Œã¦ã„ã¾ã™ã€‚
+ </notification>
+ <notification name="CantPayNoAgent">
+ 支払ã„ã®ç›¸æ‰‹ã‚’把æ¡ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚
+ </notification>
+ <notification name="CantDonateToPublicObjects">
+ パブリックオブジェクトã«ãƒªãƒ³ãƒ‡ãƒ³ãƒ‰ãƒ«ã‚’与ãˆã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="InventoryCreationInWorldObjectFailed">
+ インワールドオブジェクトã§ã®ã‚¤ãƒ³ãƒ™ãƒ³ãƒˆãƒªä½œæˆã«å¤±æ•—ã—ã¾ã—ãŸã€‚
+ </notification>
+ <notification name="UserBalanceOrLandUsageError">
+ 内部エラーãŒç™ºç”Ÿã—ãŸãŸã‚ã€ãƒ“ューワを正ã—ãæ›´æ–°ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ビューワã«è¡¨ç¤ºã•ã‚Œã‚‹ãƒªãƒ³ãƒ‡ãƒ³ãƒ‰ãƒ«ã®æ®‹é«˜ã¾ãŸã¯åŒºç”»ã®æ‰€æœ‰ã¯ã€ã‚µãƒ¼ãƒãƒ¼ä¸Šã®å®Ÿéš›ã®æ®‹é«˜ã‚’å映ã—ã¦ã„ãªã„å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚
+ </notification>
+ <notification name="LargePrimAgentIntersect">
+ ä»–ã®ãƒ—レイヤーã®é–¢å¿ƒã‚’引ã大ããªãƒ—リムを作æˆã§ãã¾ã›ã‚“。他ã®ãƒ—レイヤーãŒç§»å‹•ã—ãŸã¨ãã«å†è©¦è¡Œã—ã¦ãã ã•ã„。
+ </notification>
+ <notification name="PreferenceChatClearLog">
+ ã“ã‚Œã«ã‚ˆã‚Šã€éŽåŽ»ã®ä¼šè©±ã®ãƒ­ã‚°ã€ãŠã‚ˆã³ãã®ãƒ•ã‚¡ã‚¤ãƒ«ã®ã™ã¹ã¦ã®ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ãŒå‰Šé™¤ã•ã‚Œã¾ã™ã€‚
+ <usetemplate ignoretext="以å‰ã®ä¼šè©±ã®ãƒ­ã‚°ã‚’削除ã™ã‚‹å‰ã«ç¢ºèªã—ã¦ãã ã•ã„。" name="okcancelignore" notext="å–り消ã—" yestext="OK"/>
+ </notification>
+ <notification name="PreferenceChatDeleteTranscripts">
+ ã“ã‚Œã«ã‚ˆã‚Šã€ä»¥å‰ã®ã™ã¹ã¦ã®ä¼šè©±ã®ãƒ†ã‚­ã‚¹ãƒˆãŒå‰Šé™¤ã•ã‚Œã¾ã™ã€‚éŽåŽ»ã®ä¼šè©±ã®ãƒªã‚¹ãƒˆã«ã¯å½±éŸ¿ã—ã¾ã›ã‚“。.txt ãŠã‚ˆã³ txt.backup ã®æ‹¡å¼µå­ãŒä»˜ã„ãŸã™ã¹ã¦ã®ãƒ•ã‚¡ã‚¤ãƒ«ãŒ [FOLDER] フォルダーã‹ã‚‰å‰Šé™¤ã•ã‚Œã¾ã™ã€‚
+ <usetemplate ignoretext="テキストを削除ã™ã‚‹ã¾ãˆã«ç¢ºèªã—ã¦ãã ã•ã„。" name="okcancelignore" notext="å–り消ã—" yestext="OK"/>
+ </notification>
+ <notification name="PreferenceChatPathChanged">
+ ファイルを移動ã§ãã¾ã›ã‚“。以å‰ã®ãƒ‘スãŒãƒªã‚¹ãƒˆã‚¢ã•ã‚Œã¾ã—ãŸã€‚
+ <usetemplate ignoretext="ファイルを移動ã§ãã¾ã›ã‚“。以å‰ã®ãƒ‘スãŒãƒªã‚¹ãƒˆã‚¢ã•ã‚Œã¾ã—ãŸã€‚" name="okignore" yestext="OK"/>
+ </notification>
</notifications>
diff --git a/indra/newview/skins/default/xui/ja/outfit_accordion_tab.xml b/indra/newview/skins/default/xui/ja/outfit_accordion_tab.xml
index bac885e5d8..bac885e5d8 100644..100755
--- a/indra/newview/skins/default/xui/ja/outfit_accordion_tab.xml
+++ b/indra/newview/skins/default/xui/ja/outfit_accordion_tab.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_active_object_row.xml b/indra/newview/skins/default/xui/ja/panel_active_object_row.xml
index 90491e84c5..90491e84c5 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_active_object_row.xml
+++ b/indra/newview/skins/default/xui/ja/panel_active_object_row.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_adhoc_control_panel.xml b/indra/newview/skins/default/xui/ja/panel_adhoc_control_panel.xml
index 17e1283d24..17e1283d24 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_adhoc_control_panel.xml
+++ b/indra/newview/skins/default/xui/ja/panel_adhoc_control_panel.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_avatar_list_item.xml b/indra/newview/skins/default/xui/ja/panel_avatar_list_item.xml
index 70d37c3bad..3ef8eba19f 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_avatar_list_item.xml
+++ b/indra/newview/skins/default/xui/ja/panel_avatar_list_item.xml
@@ -27,5 +27,6 @@
<icon name="permission_edit_mine_icon" tool_tip="ã“ã®ãƒ•ãƒ¬ãƒ³ãƒ‰ã¯ã€ã‚ãªãŸã®ã‚ªãƒ–ジェクトを編集・削除・å–å¾—ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™"/>
<icon name="permission_map_icon" tool_tip="ã“ã®ãƒ•ãƒ¬ãƒ³ãƒ‰ã¯åœ°å›³ä¸Šã§ã‚ãªãŸã®ä½ç½®ã‚’表示ã§ãã¾ã™"/>
<icon name="permission_online_icon" tool_tip="ã“ã®ãƒ•ãƒ¬ãƒ³ãƒ‰ã¯ã‚ãªãŸãŒã‚ªãƒ³ãƒ©ã‚¤ãƒ³ã«ã„ã‚‹ã“ã¨ã‚’確èªã§ãã¾ã™"/>
+ <button name="info_btn" tool_tip="詳細"/>
<button name="profile_btn" tool_tip="プロフィールã®è¡¨ç¤º"/>
</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_avatar_tag.xml b/indra/newview/skins/default/xui/ja/panel_avatar_tag.xml
index fd91ea97d1..fd91ea97d1 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_avatar_tag.xml
+++ b/indra/newview/skins/default/xui/ja/panel_avatar_tag.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_block_list_sidetray.xml b/indra/newview/skins/default/xui/ja/panel_block_list_sidetray.xml
index 5d6a6065ae..9263e5f347 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_block_list_sidetray.xml
+++ b/indra/newview/skins/default/xui/ja/panel_block_list_sidetray.xml
@@ -1,10 +1,11 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel name="block_list_panel">
- <text name="title_text">
- ブロックリスト
- </text>
- <scroll_list name="blocked" tool_tip="ç¾åœ¨ãƒ–ロックã•ã‚Œã¦ã„ã‚‹ä½äººä¸€è¦§"/>
- <button label="ã‚¢ãƒã‚¿ãƒ¼ã‚’ブロック" label_selected="ä½äººã‚’ブロック..." name="Block resident..." tool_tip="ブロックã—ãŸã„ä½äººã‚’é¸ã‚“ã§ãã ã•ã„"/>
- <button label="åå‰ã§ã‚ªãƒ–ジェクトをブロック..." label_selected="åå‰ã§ã‚ªãƒ–ジェクトをブロック..." name="Block object by name..." tool_tip="åå‰ã§ãƒ–ロックã—ãŸã„オブジェクトをé¸ã‚“ã§ãã ã•ã„"/>
- <button label="ブロック解除" label_selected="ブロック解除" name="Unblock" tool_tip="ブロックリストã‹ã‚‰ä½äººãƒ»ã‚ªãƒ–ジェクトを削除"/>
+ <panel label="bottom_panel" name="blocked_buttons_panel">
+ <filter_editor label="フィルター" name="blocked_filter_input"/>
+ <menu_button name="blocked_gear_btn" tool_tip="é¸æŠžã—ãŸä½äººãƒ»ã‚ªãƒ–ジェクトã«å¯¾ã™ã‚‹ã‚¢ã‚¯ã‚·ãƒ§ãƒ³"/>
+ <menu_button name="view_btn" tool_tip="オプションを並ã¹æ›¿ãˆã‚‹"/>
+ <menu_button name="plus_btn" tool_tip="ブロックã™ã‚‹ä½äººãƒ»ã‚ªãƒ–ジェクトをé¸æŠž"/>
+ <button name="unblock_btn" tool_tip="ブロックリストã‹ã‚‰ä½äººãƒ»ã‚ªãƒ–ジェクトを削除"/>
+ </panel>
+ <block_list name="blocked" tool_tip="ç¾åœ¨ãƒ–ロックã•ã‚Œã¦ã„ã‚‹ä½äººä¸€è¦§"/>
</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_body_parts_list_item.xml b/indra/newview/skins/default/xui/ja/panel_body_parts_list_item.xml
index 95a5a26d4e..95a5a26d4e 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_body_parts_list_item.xml
+++ b/indra/newview/skins/default/xui/ja/panel_body_parts_list_item.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_bodyparts_list_button_bar.xml b/indra/newview/skins/default/xui/ja/panel_bodyparts_list_button_bar.xml
index 42d8a21660..42d8a21660 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_bodyparts_list_button_bar.xml
+++ b/indra/newview/skins/default/xui/ja/panel_bodyparts_list_button_bar.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_bottomtray.xml b/indra/newview/skins/default/xui/ja/panel_bottomtray.xml
deleted file mode 100644
index 3529abbf36..0000000000
--- a/indra/newview/skins/default/xui/ja/panel_bottomtray.xml
+++ /dev/null
@@ -1,47 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel name="bottom_tray">
- <string name="DragIndicationImageName" value="Accordion_ArrowOpened_Off"/>
- <string name="SpeakBtnToolTip" value="マイクã®ã‚ªãƒ³ãƒ»ã‚ªãƒ•"/>
- <string name="VoiceControlBtnToolTip" value="ボイスコントロールパãƒãƒ«ã®è¡¨ç¤ºãƒ»éžè¡¨ç¤º"/>
- <layout_stack name="toolbar_stack">
- <layout_panel name="speak_panel">
- <talk_button name="talk">
- <speak_button label="話ã™" label_selected="話ã™" name="speak_btn"/>
- </talk_button>
- </layout_panel>
- <layout_panel name="gesture_panel">
- <gesture_combo_list label="ジェスãƒãƒ£ãƒ¼" name="Gesture" tool_tip="ジェスãƒãƒ£ãƒ¼ã®è¡¨ç¤ºãƒ»éžè¡¨ç¤º"/>
- </layout_panel>
- <layout_panel name="movement_panel">
- <bottomtray_button label="移動" name="movement_btn" tool_tip="移動コントロールã®è¡¨ç¤ºãƒ»éžè¡¨ç¤º"/>
- </layout_panel>
- <layout_panel name="cam_panel">
- <bottomtray_button label="視界" name="camera_btn" tool_tip="カメラコントロールã®è¡¨ç¤ºãƒ»éžè¡¨ç¤º"/>
- </layout_panel>
- <layout_panel name="snapshot_panel">
- <bottomtray_button label="" name="snapshots" tool_tip="スナップショットを撮りã¾ã™"/>
- </layout_panel>
- <layout_panel name="build_btn_panel">
- <bottomtray_button label="制作" name="build_btn" tool_tip="制作ツールã®è¡¨ç¤ºãƒ»éžè¡¨ç¤º"/>
- </layout_panel>
- <layout_panel name="search_btn_panel">
- <bottomtray_button label="検索" name="search_btn" tool_tip="検索ã®è¡¨ç¤ºãƒ»éžè¡¨ç¤º"/>
- </layout_panel>
- <layout_panel name="world_map_btn_panel">
- <bottomtray_button label="地図" name="world_map_btn" tool_tip="世界地図ã®è¡¨ç¤ºãƒ»éžè¡¨ç¤º"/>
- </layout_panel>
- <layout_panel name="mini_map_btn_panel">
- <bottomtray_button label="ミニマップ" name="mini_map_btn" tool_tip="ミニマップã®è¡¨ç¤ºãƒ»éžè¡¨ç¤º"/>
- </layout_panel>
- <layout_panel name="im_well_panel">
- <chiclet_im_well name="im_well">
- <button name="Unread IM messages" tool_tip="会話"/>
- </chiclet_im_well>
- </layout_panel>
- <layout_panel name="notification_well_panel">
- <chiclet_notification name="notification_well">
- <button name="Unread" tool_tip="通知"/>
- </chiclet_notification>
- </layout_panel>
- </layout_stack>
-</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_bottomtray_lite.xml b/indra/newview/skins/default/xui/ja/panel_bottomtray_lite.xml
index 6eca8adfe5..6eca8adfe5 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_bottomtray_lite.xml
+++ b/indra/newview/skins/default/xui/ja/panel_bottomtray_lite.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_chat_header.xml b/indra/newview/skins/default/xui/ja/panel_chat_header.xml
index 7916bf5155..7916bf5155 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_chat_header.xml
+++ b/indra/newview/skins/default/xui/ja/panel_chat_header.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_chiclet_bar.xml b/indra/newview/skins/default/xui/ja/panel_chiclet_bar.xml
index 6717ba9ba3..6717ba9ba3 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_chiclet_bar.xml
+++ b/indra/newview/skins/default/xui/ja/panel_chiclet_bar.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_classified_info.xml b/indra/newview/skins/default/xui/ja/panel_classified_info.xml
index 57a255afde..57a255afde 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_classified_info.xml
+++ b/indra/newview/skins/default/xui/ja/panel_classified_info.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_clothing_list_button_bar.xml b/indra/newview/skins/default/xui/ja/panel_clothing_list_button_bar.xml
index 2159f17fec..2159f17fec 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_clothing_list_button_bar.xml
+++ b/indra/newview/skins/default/xui/ja/panel_clothing_list_button_bar.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_clothing_list_item.xml b/indra/newview/skins/default/xui/ja/panel_clothing_list_item.xml
index 158b2fa6ac..158b2fa6ac 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_clothing_list_item.xml
+++ b/indra/newview/skins/default/xui/ja/panel_clothing_list_item.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_cof_wearables.xml b/indra/newview/skins/default/xui/ja/panel_cof_wearables.xml
index b9bc10c220..b9bc10c220 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_cof_wearables.xml
+++ b/indra/newview/skins/default/xui/ja/panel_cof_wearables.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_conversation_list_item.xml b/indra/newview/skins/default/xui/ja/panel_conversation_list_item.xml
new file mode 100644
index 0000000000..09ffb92d36
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/panel_conversation_list_item.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="conversation_list_item">
+ <layout_stack name="conversation_item_stack">
+ <layout_panel name="conversation_title_panel">
+ <text name="conversation_title" value="(ローディング)"/>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_conversation_log_list_item.xml b/indra/newview/skins/default/xui/ja/panel_conversation_log_list_item.xml
new file mode 100644
index 0000000000..e05a67e31d
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/panel_conversation_log_list_item.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="conversation_log_list_item">
+ <icon name="voice_session_icon" tool_tip="ボイスãƒãƒ£ãƒƒãƒˆ"/>
+ <icon name="unread_ims_icon" tool_tip="ログアウト時ã«è¡¨ç¤ºã•ã‚Œã‚‹ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸"/>
+ <button name="delete_btn" tool_tip="ã“ã®ã‚¨ãƒ³ãƒˆãƒªãƒ¼ã‚’削除"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_deletable_wearable_list_item.xml b/indra/newview/skins/default/xui/ja/panel_deletable_wearable_list_item.xml
index a1e30283ee..a1e30283ee 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_deletable_wearable_list_item.xml
+++ b/indra/newview/skins/default/xui/ja/panel_deletable_wearable_list_item.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_dummy_clothing_list_item.xml b/indra/newview/skins/default/xui/ja/panel_dummy_clothing_list_item.xml
index 0395d4edd8..0395d4edd8 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_dummy_clothing_list_item.xml
+++ b/indra/newview/skins/default/xui/ja/panel_dummy_clothing_list_item.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_edit_alpha.xml b/indra/newview/skins/default/xui/ja/panel_edit_alpha.xml
index 7250da69a4..7250da69a4 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_edit_alpha.xml
+++ b/indra/newview/skins/default/xui/ja/panel_edit_alpha.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_edit_classified.xml b/indra/newview/skins/default/xui/ja/panel_edit_classified.xml
index b556b68e02..b556b68e02 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_edit_classified.xml
+++ b/indra/newview/skins/default/xui/ja/panel_edit_classified.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_edit_eyes.xml b/indra/newview/skins/default/xui/ja/panel_edit_eyes.xml
index 94967999a1..94967999a1 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_edit_eyes.xml
+++ b/indra/newview/skins/default/xui/ja/panel_edit_eyes.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_edit_gloves.xml b/indra/newview/skins/default/xui/ja/panel_edit_gloves.xml
index 72eb120c3d..72eb120c3d 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_edit_gloves.xml
+++ b/indra/newview/skins/default/xui/ja/panel_edit_gloves.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_edit_hair.xml b/indra/newview/skins/default/xui/ja/panel_edit_hair.xml
index f73f760192..f73f760192 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_edit_hair.xml
+++ b/indra/newview/skins/default/xui/ja/panel_edit_hair.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_edit_jacket.xml b/indra/newview/skins/default/xui/ja/panel_edit_jacket.xml
index ee39e9435c..ee39e9435c 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_edit_jacket.xml
+++ b/indra/newview/skins/default/xui/ja/panel_edit_jacket.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_edit_pants.xml b/indra/newview/skins/default/xui/ja/panel_edit_pants.xml
index 6a1789c9f4..6a1789c9f4 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_edit_pants.xml
+++ b/indra/newview/skins/default/xui/ja/panel_edit_pants.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_edit_physics.xml b/indra/newview/skins/default/xui/ja/panel_edit_physics.xml
index 6ebf0062dc..6ebf0062dc 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_edit_physics.xml
+++ b/indra/newview/skins/default/xui/ja/panel_edit_physics.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_edit_pick.xml b/indra/newview/skins/default/xui/ja/panel_edit_pick.xml
index 39ea1df1e3..39ea1df1e3 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_edit_pick.xml
+++ b/indra/newview/skins/default/xui/ja/panel_edit_pick.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_edit_profile.xml b/indra/newview/skins/default/xui/ja/panel_edit_profile.xml
index 4cbd7f793b..4cbd7f793b 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_edit_profile.xml
+++ b/indra/newview/skins/default/xui/ja/panel_edit_profile.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_edit_shape.xml b/indra/newview/skins/default/xui/ja/panel_edit_shape.xml
index 5a3a949150..5a3a949150 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_edit_shape.xml
+++ b/indra/newview/skins/default/xui/ja/panel_edit_shape.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_edit_shirt.xml b/indra/newview/skins/default/xui/ja/panel_edit_shirt.xml
index f33daa4eba..f33daa4eba 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_edit_shirt.xml
+++ b/indra/newview/skins/default/xui/ja/panel_edit_shirt.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_edit_shoes.xml b/indra/newview/skins/default/xui/ja/panel_edit_shoes.xml
index c7626189af..c7626189af 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_edit_shoes.xml
+++ b/indra/newview/skins/default/xui/ja/panel_edit_shoes.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_edit_skin.xml b/indra/newview/skins/default/xui/ja/panel_edit_skin.xml
index 7573132576..7573132576 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_edit_skin.xml
+++ b/indra/newview/skins/default/xui/ja/panel_edit_skin.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_edit_skirt.xml b/indra/newview/skins/default/xui/ja/panel_edit_skirt.xml
index 6efc4ce99a..6efc4ce99a 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_edit_skirt.xml
+++ b/indra/newview/skins/default/xui/ja/panel_edit_skirt.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_edit_socks.xml b/indra/newview/skins/default/xui/ja/panel_edit_socks.xml
index 71fc7c5682..71fc7c5682 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_edit_socks.xml
+++ b/indra/newview/skins/default/xui/ja/panel_edit_socks.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_edit_tattoo.xml b/indra/newview/skins/default/xui/ja/panel_edit_tattoo.xml
index f4cfe6d83f..f4cfe6d83f 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_edit_tattoo.xml
+++ b/indra/newview/skins/default/xui/ja/panel_edit_tattoo.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_edit_underpants.xml b/indra/newview/skins/default/xui/ja/panel_edit_underpants.xml
index f345a81922..f345a81922 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_edit_underpants.xml
+++ b/indra/newview/skins/default/xui/ja/panel_edit_underpants.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_edit_undershirt.xml b/indra/newview/skins/default/xui/ja/panel_edit_undershirt.xml
index 66b2ffa8ba..66b2ffa8ba 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_edit_undershirt.xml
+++ b/indra/newview/skins/default/xui/ja/panel_edit_undershirt.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_edit_wearable.xml b/indra/newview/skins/default/xui/ja/panel_edit_wearable.xml
index 000dac7b5b..000dac7b5b 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_edit_wearable.xml
+++ b/indra/newview/skins/default/xui/ja/panel_edit_wearable.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_group_control_panel.xml b/indra/newview/skins/default/xui/ja/panel_group_control_panel.xml
index 49749732c9..49749732c9 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_group_control_panel.xml
+++ b/indra/newview/skins/default/xui/ja/panel_group_control_panel.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_group_general.xml b/indra/newview/skins/default/xui/ja/panel_group_general.xml
index a1bfb67823..a1bfb67823 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_group_general.xml
+++ b/indra/newview/skins/default/xui/ja/panel_group_general.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_group_info_sidetray.xml b/indra/newview/skins/default/xui/ja/panel_group_info_sidetray.xml
index 7aa1aec6d0..7aa1aec6d0 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_group_info_sidetray.xml
+++ b/indra/newview/skins/default/xui/ja/panel_group_info_sidetray.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_group_invite.xml b/indra/newview/skins/default/xui/ja/panel_group_invite.xml
index a21b340fdd..cc9ebc405b 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_group_invite.xml
+++ b/indra/newview/skins/default/xui/ja/panel_group_invite.xml
@@ -9,6 +9,9 @@
<panel.string name="already_in_group">
é¸æŠžã—ãŸä½äººã®ãªã‹ã«ã€æ—¢ã«ã‚°ãƒ«ãƒ¼ãƒ—ã«æ‰€å±žã—ã¦ã„る人ãŒã„ã‚‹ãŸã‚ã€æ‹›å¾…ã‚’é€ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“ã§ã—ãŸã€‚
</panel.string>
+ <panel.string name="invite_selection_too_large">
+ グループã¸ã®æ‹›å¾…ãŒé€ä¿¡ã•ã‚Œã¦ã„ã¾ã›ã‚“: é¸æŠžã•ã‚ŒãŸä½äººãŒå¤šã™ãŽã¾ã™ã€‚グループã¸ã®æ‹›å¾…ã¯1回ã®ãƒªã‚¯ã‚¨ã‚¹ãƒˆã‚ãŸã‚Š100人ã«åˆ¶é™ã•ã‚Œã¦ã„ã¾ã™ã€‚
+ </panel.string>
<text bottom_delta="-96" font="SansSerifSmall" height="72" name="help_text">
グループã«ã¯ä¸€åº¦ã«è¤‡æ•°ã®ä½äººã‚’招待ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚ 「リストã‹ã‚‰ä½äººã‚’é¸æŠžã€ã‚’クリックã—ã¦ãã ã•ã„。
</text>
diff --git a/indra/newview/skins/default/xui/ja/panel_group_land_money.xml b/indra/newview/skins/default/xui/ja/panel_group_land_money.xml
index 82be58a0fb..82be58a0fb 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_group_land_money.xml
+++ b/indra/newview/skins/default/xui/ja/panel_group_land_money.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_group_list_item.xml b/indra/newview/skins/default/xui/ja/panel_group_list_item.xml
index 4b548049c8..77d3d8f391 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_group_list_item.xml
+++ b/indra/newview/skins/default/xui/ja/panel_group_list_item.xml
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel name="group_list_item">
<text name="group_name" value="ä¸æ˜Ž"/>
+ <button name="info_btn" tool_tip="詳細"/>
<button name="profile_btn" tool_tip="プロフィールã®è¡¨ç¤º"/>
</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_group_notices.xml b/indra/newview/skins/default/xui/ja/panel_group_notices.xml
index ddad6c1f9b..ddad6c1f9b 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_group_notices.xml
+++ b/indra/newview/skins/default/xui/ja/panel_group_notices.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_group_notify.xml b/indra/newview/skins/default/xui/ja/panel_group_notify.xml
index 7135ae780d..7135ae780d 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_group_notify.xml
+++ b/indra/newview/skins/default/xui/ja/panel_group_notify.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_group_roles.xml b/indra/newview/skins/default/xui/ja/panel_group_roles.xml
index d40dedf566..d40dedf566 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_group_roles.xml
+++ b/indra/newview/skins/default/xui/ja/panel_group_roles.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_im_control_panel.xml b/indra/newview/skins/default/xui/ja/panel_im_control_panel.xml
index f2429ac12a..f2429ac12a 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_im_control_panel.xml
+++ b/indra/newview/skins/default/xui/ja/panel_im_control_panel.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_instant_message.xml b/indra/newview/skins/default/xui/ja/panel_instant_message.xml
index bf4cbcdc46..bf4cbcdc46 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_instant_message.xml
+++ b/indra/newview/skins/default/xui/ja/panel_instant_message.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_inventory_item.xml b/indra/newview/skins/default/xui/ja/panel_inventory_item.xml
index d18047fbcf..d18047fbcf 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_inventory_item.xml
+++ b/indra/newview/skins/default/xui/ja/panel_inventory_item.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_landmark_info.xml b/indra/newview/skins/default/xui/ja/panel_landmark_info.xml
index 7fca66f90f..7fca66f90f 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_landmark_info.xml
+++ b/indra/newview/skins/default/xui/ja/panel_landmark_info.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_landmarks.xml b/indra/newview/skins/default/xui/ja/panel_landmarks.xml
index 24d6ff23ae..24d6ff23ae 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_landmarks.xml
+++ b/indra/newview/skins/default/xui/ja/panel_landmarks.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_login.xml b/indra/newview/skins/default/xui/ja/panel_login.xml
index ac1fe455c7..396d9e65b1 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_login.xml
+++ b/indra/newview/skins/default/xui/ja/panel_login.xml
@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel name="panel_login">
- <panel.string name="create_account_url">
- http://jp.secondlife.com/registration/
- </panel.string>
<panel.string name="forgot_password_url">
http://secondlife.com/account/request.php?lang=ja
</panel.string>
<layout_stack name="login_widgets">
<layout_panel name="login">
+ <text name="log_in_text">
+ ログイン
+ </text>
<text name="username_text">
ユーザーãƒãƒ¼ãƒ ï¼š
</text>
@@ -15,15 +15,8 @@
<text name="password_text">
パスワード:
</text>
- <check_box label="パスワードを記憶" name="remember_check"/>
- <button label="ログイン" left_pad="30" name="connect_btn" width="60"/>
- <text name="mode_selection_text">
- モード:
- </text>
- <combo_box name="mode_combo" tool_tip="モードをé¸æŠžã—ã¾ã™ã€‚ベーシックモードã§ã¯æŽ¢ç´¢ã‚„ãƒãƒ£ãƒƒãƒˆã‚’ã™ã°ã‚„ãç°¡å˜ã«å®Ÿè¡Œã§ãã€ã‚¢ãƒ‰ãƒãƒ³ã‚¹ãƒ¢ãƒ¼ãƒ‰ã§ã¯ã€ã‚ˆã‚Šå¤šãã®æ©Ÿèƒ½ãŒåˆ©ç”¨ã§ãã¾ã™ã€‚">
- <combo_box.item label="ベーシック" name="Basic"/>
- <combo_box.item label="アドãƒãƒ³ã‚¹" name="Advanced"/>
- </combo_box>
+ </layout_panel>
+ <layout_panel name="start_location_panel">
<text name="start_location_text">
開始地点:
</text>
@@ -33,16 +26,21 @@
<combo_box.item label="<地域åを入力>" name="Typeregionname"/>
</combo_box>
</layout_panel>
- <layout_panel name="links">
- <text name="create_new_account_text">
- ãŠç”³ã—è¾¼ã¿
+ <layout_panel name="links_login_panel">
+ <text name="login_help">
+ ログインã®æ–¹æ³•
</text>
<text name="forgot_password_text">
ユーザーåã¾ãŸã¯ãƒ‘スワードをãŠå¿˜ã‚Œã§ã™ã‹ï¼Ÿ
</text>
- <text name="login_help">
- ログインã®æ–¹æ³•
+ <button label="ログイン" left_pad="30" name="connect_btn" width="60"/>
+ <check_box label="パスワードを記憶" name="remember_check"/>
+ </layout_panel>
+ <layout_panel name="links">
+ <text name="create_account_text">
+ アカウントを作æˆã—ã¦ãã ã•ã„
</text>
+ <button label="今ã™ã開始" name="create_new_account_btn"/>
</layout_panel>
</layout_stack>
</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_main_inventory.xml b/indra/newview/skins/default/xui/ja/panel_main_inventory.xml
index f908262f4f..f908262f4f 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_main_inventory.xml
+++ b/indra/newview/skins/default/xui/ja/panel_main_inventory.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_me.xml b/indra/newview/skins/default/xui/ja/panel_me.xml
index 3df1ae8048..3df1ae8048 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_me.xml
+++ b/indra/newview/skins/default/xui/ja/panel_me.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_media_settings_general.xml b/indra/newview/skins/default/xui/ja/panel_media_settings_general.xml
index 6321dbb048..6321dbb048 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_media_settings_general.xml
+++ b/indra/newview/skins/default/xui/ja/panel_media_settings_general.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_media_settings_permissions.xml b/indra/newview/skins/default/xui/ja/panel_media_settings_permissions.xml
index 11d9ed4c16..11d9ed4c16 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_media_settings_permissions.xml
+++ b/indra/newview/skins/default/xui/ja/panel_media_settings_permissions.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_media_settings_security.xml b/indra/newview/skins/default/xui/ja/panel_media_settings_security.xml
index ea4fdb9ce5..ea4fdb9ce5 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_media_settings_security.xml
+++ b/indra/newview/skins/default/xui/ja/panel_media_settings_security.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_navigation_bar.xml b/indra/newview/skins/default/xui/ja/panel_navigation_bar.xml
index 51402b2e00..51402b2e00 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_navigation_bar.xml
+++ b/indra/newview/skins/default/xui/ja/panel_navigation_bar.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_nearby_chat.xml b/indra/newview/skins/default/xui/ja/panel_nearby_chat.xml
index 4048b48d3a..4048b48d3a 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_nearby_chat.xml
+++ b/indra/newview/skins/default/xui/ja/panel_nearby_chat.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_nearby_chat_bar.xml b/indra/newview/skins/default/xui/ja/panel_nearby_chat_bar.xml
index 5998206f27..201fb0a376 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_nearby_chat_bar.xml
+++ b/indra/newview/skins/default/xui/ja/panel_nearby_chat_bar.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel name="chat_bar">
+<panel name="nearby_chat">
<line_editor label="ã“ã“をクリックã—ã¦ãƒãƒ£ãƒƒãƒˆã‚’開始ã—ã¾ã™ã€‚" name="chat_box" tool_tip="Enter キーを押ã—ã¦ç™ºè¨€ã—ã€Ctrl + Enter キーã§å«ã³ã¾ã™ã€‚"/>
<button name="show_nearby_chat" tool_tip="è¿‘ãã®ãƒãƒ£ãƒƒãƒˆãƒ­ã‚°ã‚’表示・éžè¡¨ç¤º"/>
</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_nearby_media.xml b/indra/newview/skins/default/xui/ja/panel_nearby_media.xml
index c29ec64304..c29ec64304 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_nearby_media.xml
+++ b/indra/newview/skins/default/xui/ja/panel_nearby_media.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_notifications_channel.xml b/indra/newview/skins/default/xui/ja/panel_notifications_channel.xml
index aff427ed49..aff427ed49 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_notifications_channel.xml
+++ b/indra/newview/skins/default/xui/ja/panel_notifications_channel.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_notify_textbox.xml b/indra/newview/skins/default/xui/ja/panel_notify_textbox.xml
index 8e0cf4bc9d..8e0cf4bc9d 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_notify_textbox.xml
+++ b/indra/newview/skins/default/xui/ja/panel_notify_textbox.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_online_status_toast.xml b/indra/newview/skins/default/xui/ja/panel_online_status_toast.xml
index fdc489f375..fdc489f375 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_online_status_toast.xml
+++ b/indra/newview/skins/default/xui/ja/panel_online_status_toast.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_outbox_inventory.xml b/indra/newview/skins/default/xui/ja/panel_outbox_inventory.xml
index 1a14283113..1a14283113 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_outbox_inventory.xml
+++ b/indra/newview/skins/default/xui/ja/panel_outbox_inventory.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_outfit_edit.xml b/indra/newview/skins/default/xui/ja/panel_outfit_edit.xml
index e89ce0c479..e89ce0c479 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_outfit_edit.xml
+++ b/indra/newview/skins/default/xui/ja/panel_outfit_edit.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_outfits_inventory.xml b/indra/newview/skins/default/xui/ja/panel_outfits_inventory.xml
index 93df0ba2bd..93df0ba2bd 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_outfits_inventory.xml
+++ b/indra/newview/skins/default/xui/ja/panel_outfits_inventory.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_outfits_inventory_gear_default.xml b/indra/newview/skins/default/xui/ja/panel_outfits_inventory_gear_default.xml
index e8caab0696..e8caab0696 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_outfits_inventory_gear_default.xml
+++ b/indra/newview/skins/default/xui/ja/panel_outfits_inventory_gear_default.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_outfits_list.xml b/indra/newview/skins/default/xui/ja/panel_outfits_list.xml
index df9ef40113..df9ef40113 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_outfits_list.xml
+++ b/indra/newview/skins/default/xui/ja/panel_outfits_list.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_outfits_wearing.xml b/indra/newview/skins/default/xui/ja/panel_outfits_wearing.xml
index fd03e6b89e..fd03e6b89e 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_outfits_wearing.xml
+++ b/indra/newview/skins/default/xui/ja/panel_outfits_wearing.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_people.xml b/indra/newview/skins/default/xui/ja/panel_people.xml
index 88c31451b5..dd8fd41681 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_people.xml
+++ b/indra/newview/skins/default/xui/ja/panel_people.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<!-- Side tray panel -->
<panel label="人" name="people_panel">
<string name="no_recent_people" value="最近交æµã—ãŸäººã¯ã„ã¾ã›ã‚“。 一緒ã«ä½•ã‹ã™ã‚‹ä»²é–“ã‚’ãŠæŽ¢ã—ã§ã™ã‹ï¼Ÿ [secondlife:///app/search/people 検索] ã‹ [secondlife:///app/worldmap 世界地図] ã‚’ãŠè©¦ã—ãã ã•ã„。"/>
@@ -14,81 +14,56 @@
<string name="no_filtered_friends_msg">
ãŠæŽ¢ã—ã®ã‚‚ã®ã¯è¦‹ã¤ã‹ã‚Šã¾ã—ãŸã‹ï¼Ÿ [secondlife:///app/search/people/[SEARCH_TERM] 検索] ã‚’ãŠè©¦ã—ãã ã•ã„。
</string>
- <string name="people_filter_label" value="人をフィルター"/>
- <string name="groups_filter_label" value="グループをフィルター"/>
<string name="no_filtered_groups_msg" value="ãŠæŽ¢ã—ã®ã‚‚ã®ã¯è¦‹ã¤ã‹ã‚Šã¾ã—ãŸã‹ï¼Ÿ [secondlife:///app/search/groups/[SEARCH_TERM] 検索] ã‚’ãŠè©¦ã—ãã ã•ã„。"/>
<string name="no_groups_msg" value="グループをãŠæŽ¢ã—ã§ã™ã‹ï¼Ÿ [secondlife:///app/search/groups 検索] ã‚’ãŠè©¦ã—ãã ã•ã„。"/>
<string name="MiniMapToolTipMsg" value="[地域](ダブルクリックã§åœ°å›³ã‚’é–‹ã。Shiftâ€ãƒ‰ãƒ©ãƒƒã‚°ã§æ°´å¹³ãƒ»åž‚直移動)"/>
<string name="AltMiniMapToolTipMsg" value="[地域](ダブルクリックã§ãƒ†ãƒ¬ãƒãƒ¼ãƒˆã€‚Shiftâ€ãƒ‰ãƒ©ãƒƒã‚°ã§æ°´å¹³ãƒ»åž‚直移動)"/>
- <filter_editor label="フィルター" name="filter_input"/>
<tab_container name="tabs">
<panel label="è¿‘ã" name="nearby_panel">
- <panel label="bottom_panel" name="bottom_panel">
- <menu_button name="nearby_view_sort_btn" tool_tip="オプション"/>
- <button name="add_friend_btn" tool_tip="é¸æŠžã—ãŸä½äººã‚’フレンドリストã«ç™»éŒ²"/>
+ <panel label="bottom_panel" name="nearby_buttons_panel">
+ <filter_editor label="人をフィルター" name="nearby_filter_input"/>
+ <button name="gear_btn" tool_tip="é¸æŠžã—ãŸäººã«å¯¾ã™ã‚‹ã‚¢ã‚¯ã‚·ãƒ§ãƒ³"/>
+ <menu_button name="nearby_view_btn" tool_tip="表示 / 並ã¹æ›¿ãˆã®ã‚ªãƒ—ション"/>
+ <button name="add_friend_btn" tool_tip="フレンド登録を申ã—出ã¾ã™"/>
+ <dnd_button name="nearby_del_btn" tool_tip="フレンドã¨ã—ã¦é¸æŠžã•ã‚Œã¦ã„る人を削除"/>
</panel>
</panel>
- <panel label="マイ フレンド" name="friends_panel">
+ <panel label="フレンド" name="friends_panel">
+ <panel label="bottom_panel" name="friends_buttons_panel">
+ <filter_editor label="人をフィルター" name="friends_filter_input"/>
+ <button name="gear_btn" tool_tip="é¸æŠžã—ãŸäººã«å¯¾ã™ã‚‹ã‚¢ã‚¯ã‚·ãƒ§ãƒ³"/>
+ <menu_button name="friends_view_btn" tool_tip="表示 / 並ã¹æ›¿ãˆã®ã‚ªãƒ—ション"/>
+ <button name="friends_add_btn" tool_tip="フレンド登録を申ã—出ã¾ã™"/>
+ <dnd_button name="friends_del_btn" tool_tip="フレンドã¨ã—ã¦é¸æŠžã•ã‚Œã¦ã„る人を削除"/>
+ </panel>
<accordion name="friends_accordion">
<accordion_tab name="tab_online" title="オンライン"/>
<accordion_tab name="tab_all" title="全員"/>
</accordion>
- <panel label="bottom_panel" name="bottom_panel">
- <layout_stack name="bottom_panel">
- <layout_panel name="options_gear_btn_panel">
- <menu_button name="friends_viewsort_btn" tool_tip="オプションを表示ã—ã¾ã™"/>
- </layout_panel>
- <layout_panel name="add_btn_panel">
- <button name="add_btn" tool_tip="フレンド登録を申ã—出る"/>
- </layout_panel>
- <layout_panel name="trash_btn_panel">
- <dnd_button name="del_btn" tool_tip="é¸æŠžã—ãŸäººã‚’フレンドリストã‹ã‚‰å‰Šé™¤"/>
- </layout_panel>
- </layout_stack>
- </panel>
</panel>
- <panel label="マイ グループ" name="groups_panel">
- <panel label="bottom_panel" name="bottom_panel">
- <menu_button name="groups_viewsort_btn" tool_tip="オプション"/>
- <button name="plus_btn" tool_tip="グループã«å‚加 / æ–°è¦ã‚°ãƒ«ãƒ¼ãƒ—を作æˆã—ã¾ã™"/>
- <button name="activate_btn" tool_tip="é¸æŠžã—ãŸã‚°ãƒ«ãƒ¼ãƒ—をアクティブã«ã—ã¾ã™"/>
+ <panel label="グループ" name="groups_panel">
+ <panel label="bottom_panel" name="groups_buttons_panel">
+ <filter_editor label="フィルターグループ" name="groups_filter_input"/>
+ <menu_button name="groups_gear_btn" tool_tip="é¸æŠžã—ãŸã‚°ãƒ«ãƒ¼ãƒ—ã«å¯¾ã™ã‚‹ã‚¢ã‚¯ã‚·ãƒ§ãƒ³"/>
+ <menu_button name="groups_view_btn" tool_tip="表示 / 並ã¹æ›¿ãˆã®ã‚ªãƒ—ション"/>
+ <menu_button name="plus_btn" tool_tip="グループã«å‚加 / æ–°è¦ã‚°ãƒ«ãƒ¼ãƒ—を作æˆã—ã¾ã™"/>
+ <dnd_button name="minus_btn" tool_tip="é¸æŠžã—ãŸã‚°ãƒ«ãƒ¼ãƒ—ã‹ã‚‰è„±é€€"/>
</panel>
+ <text name="groupcount">
+ ã‚ãªãŸã¯[COUNT]グループã«å±žã—ã¦ã„ã‚‹ã®ã§ã€ã¾ã [REMAINING]å‚加ã§ãã¾ã™ã€‚
+ </text>
</panel>
<panel label="最新" name="recent_panel">
- <panel label="bottom_panel" name="bottom_panel">
- <menu_button name="recent_viewsort_btn" tool_tip="オプション"/>
- <button name="add_friend_btn" tool_tip="é¸æŠžã—ãŸä½äººã‚’フレンドリストã«ç™»éŒ²"/>
+ <panel label="bottom_panel" name="recent_buttons_panel">
+ <filter_editor label="人をフィルター" name="recent_filter_input"/>
+ <button name="gear_btn" tool_tip="é¸æŠžã—ãŸäººã«å¯¾ã™ã‚‹ã‚¢ã‚¯ã‚·ãƒ§ãƒ³"/>
+ <menu_button name="recent_view_btn" tool_tip="表示 / 並ã¹æ›¿ãˆã®ã‚ªãƒ—ション"/>
+ <button name="add_friend_btn" tool_tip="フレンド登録を申ã—出ã¾ã™"/>
+ <dnd_button name="recent_del_btn" tool_tip="フレンドã¨ã—ã¦é¸æŠžã•ã‚Œã¦ã„る人を削除"/>
</panel>
</panel>
+ <panel label="åœæ­¢" name="blocked_panel">
+ <panel label="ブロックã•ã‚ŒãŸä½äººã¨ã‚ªãƒ–ジェクト" name="panel_block_list_sidetray"/>
+ </panel>
</tab_container>
- <panel name="button_bar">
- <layout_stack name="bottom_bar_ls">
- <layout_panel name="view_profile_btn_lp">
- <button label="プロフィール" name="view_profile_btn" tool_tip="写真ã€ã‚°ãƒ«ãƒ¼ãƒ—ã€ãã®ä»–ä½äººæƒ…報を表示"/>
- </layout_panel>
- <layout_panel name="im_btn_lp">
- <button label="IM" name="im_btn" tool_tip="インスタントメッセージを開ãã¾ã™"/>
- </layout_panel>
- <layout_panel name="call_btn_lp">
- <button label="コール" name="call_btn" tool_tip="ã“ã®ä½äººã«ã‚³ãƒ¼ãƒ«ã™ã‚‹"/>
- </layout_panel>
- <layout_panel name="share_btn_lp">
- <button label="共有" name="share_btn" tool_tip="インベントリã®ã‚¢ã‚¤ãƒ†ãƒ ã‚’共有ã™ã‚‹"/>
- </layout_panel>
- <layout_panel name="teleport_btn_lp">
- <button label="テレãƒãƒ¼ãƒˆ" name="teleport_btn" tool_tip="テレãƒãƒ¼ãƒˆã‚’é€ã‚Šã¾ã™"/>
- </layout_panel>
- </layout_stack>
- <layout_stack name="bottom_bar_ls1">
- <layout_panel name="group_info_btn_lp">
- <button label="グループプロフィール" name="group_info_btn" tool_tip="グループプロフィールを表示ã—ã¾ã™"/>
- </layout_panel>
- <layout_panel name="chat_btn_lp">
- <button label="グループãƒãƒ£ãƒƒãƒˆ" name="chat_btn" tool_tip="ãƒãƒ£ãƒƒãƒˆã‚’開始ã—ã¾ã™"/>
- </layout_panel>
- <layout_panel name="group_call_btn_lp">
- <button label="グループコール" name="group_call_btn" tool_tip="ã“ã®ã‚°ãƒ«ãƒ¼ãƒ—ã«ã‚³ãƒ¼ãƒ«ã™ã‚‹"/>
- </layout_panel>
- </layout_stack>
- </panel>
</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_pick_info.xml b/indra/newview/skins/default/xui/ja/panel_pick_info.xml
index e7b5d1929d..e7b5d1929d 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_pick_info.xml
+++ b/indra/newview/skins/default/xui/ja/panel_pick_info.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_picks.xml b/indra/newview/skins/default/xui/ja/panel_picks.xml
index c6eaaeef41..c6eaaeef41 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_picks.xml
+++ b/indra/newview/skins/default/xui/ja/panel_picks.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_place_profile.xml b/indra/newview/skins/default/xui/ja/panel_place_profile.xml
index 7235bc0f18..7235bc0f18 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_place_profile.xml
+++ b/indra/newview/skins/default/xui/ja/panel_place_profile.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_places.xml b/indra/newview/skins/default/xui/ja/panel_places.xml
index 9d3925afdc..9d3925afdc 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_places.xml
+++ b/indra/newview/skins/default/xui/ja/panel_places.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_postcard_message.xml b/indra/newview/skins/default/xui/ja/panel_postcard_message.xml
index b7c3f48557..b7c3f48557 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_postcard_message.xml
+++ b/indra/newview/skins/default/xui/ja/panel_postcard_message.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_postcard_settings.xml b/indra/newview/skins/default/xui/ja/panel_postcard_settings.xml
index 314aaef7fd..314aaef7fd 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_postcard_settings.xml
+++ b/indra/newview/skins/default/xui/ja/panel_postcard_settings.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_preferences_advanced.xml b/indra/newview/skins/default/xui/ja/panel_preferences_advanced.xml
index dcaa23fee5..dcaa23fee5 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_preferences_advanced.xml
+++ b/indra/newview/skins/default/xui/ja/panel_preferences_advanced.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_preferences_alerts.xml b/indra/newview/skins/default/xui/ja/panel_preferences_alerts.xml
index 7fd2e31698..7fd2e31698 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_preferences_alerts.xml
+++ b/indra/newview/skins/default/xui/ja/panel_preferences_alerts.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_preferences_chat.xml b/indra/newview/skins/default/xui/ja/panel_preferences_chat.xml
index 75bf28a3c8..1c3204ea04 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/ja/panel_preferences_chat.xml
@@ -1,33 +1,99 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel label="ãƒãƒ£ãƒƒãƒˆ" name="chat">
- <text name="font_size">
- 文字ã®å¤§ãã•ï¼š
- </text>
- <radio_group name="chat_font_size">
- <radio_item label="å°" name="radio" value="0"/>
- <radio_item label="中" name="radio2" value="1"/>
- <radio_item label="大" name="radio3" value="2"/>
- </radio_group>
- <check_box initial_value="true" label="ãƒãƒ£ãƒƒãƒˆä¸­ã«ã‚¿ã‚¤ãƒ”ング動作ã®ã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³ã‚’å†ç”Ÿ" name="play_typing_animation"/>
- <check_box label="オフライン時ã«å—ã‘å–ã£ãŸ IM をメールã§å—ä¿¡" name="send_im_to_email"/>
- <check_box label="IM ã¨ãƒãƒ£ãƒƒãƒˆå±¥æ­´ã«æ–‡å­—ã ã‘表示ã™ã‚‹" name="plain_text_chat_history"/>
- <check_box label="å¹ã出ã—ãƒãƒ£ãƒƒãƒˆ" name="bubble_text_chat"/>
- <text name="show_ims_in_label">
- IM ã®è¡¨ç¤ºæ–¹æ³•ï¼š
- </text>
- <text name="requires_restart_label">
- (å†èµ·å‹•å¾Œã«å映)
- </text>
- <radio_group name="chat_window" tool_tip="インスタントメッセージを別フローターã€ã¾ãŸã¯1ã¤ã®ãƒ•ãƒ­ãƒ¼ã‚¿ãƒ¼ã«è¤‡æ•°ã‚¿ãƒ–ã§è¡¨ç¤ºã—ã¾ã™ï¼ˆè¦å†èµ·å‹•ï¼‰">
- <radio_item label="別々ã®ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦" name="radio" value="0"/>
- <radio_item label="タブ" name="radio2" value="1"/>
- </radio_group>
- <text name="disable_toast_label">
- å—ä¿¡ãƒãƒ£ãƒƒãƒˆã®ãƒãƒƒãƒ—アップを有効ã«ã™ã‚‹
- </text>
- <check_box label="グループãƒãƒ£ãƒƒãƒˆ" name="EnableGroupChatPopups" tool_tip="ã“れをé¸æŠžã™ã‚‹ã¨ã€ã‚°ãƒ«ãƒ¼ãƒ—ãƒãƒ£ãƒƒãƒˆãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’å—ä¿¡ã—ãŸéš›ã«ãƒãƒƒãƒ—アップãŒè¡¨ç¤ºã•ã‚Œã¾ã™"/>
- <check_box label="IM ãƒãƒ£ãƒƒãƒˆ" name="EnableIMChatPopups" tool_tip="ã“れをé¸æŠžã™ã‚‹ã¨ã€ã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ãƒˆãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’å—ä¿¡ã—ãŸéš›ã«ãƒãƒƒãƒ—アップãŒè¡¨ç¤ºã•ã‚Œã¾ã™"/>
- <spinner label="è¿‘ãã®ãƒãƒ£ãƒƒãƒˆãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ãŒè¡¨ç¤ºã•ã‚Œã‚‹é•·ã•ï¼š" name="nearby_toasts_lifetime"/>
- <spinner label="è¿‘ãã®ãƒãƒ£ãƒƒãƒˆãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ãŒæ¶ˆãˆã‚‹ã¾ã§ã®é•·ã•ï¼š" name="nearby_toasts_fadingtime"/>
- <button label="ãƒãƒ£ãƒƒãƒˆã®ç¿»è¨³è¨­å®š" name="ok_btn"/>
+ <panel name="general_chat_settings">
+ <check_box initial_value="true" label="ãƒãƒ£ãƒƒãƒˆä¸­ã«ã‚¿ã‚¤ãƒ”ング動作ã®ã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³ã‚’å†ç”Ÿ" name="play_typing_animation"/>
+ <check_box label="オフライン時ã«å—ã‘å–ã£ãŸ IM をメールã§å—ä¿¡" name="send_im_to_email"/>
+ <check_box label="フレンドã¨ã‚°ãƒ«ãƒ¼ãƒ—以外ã‹ã‚‰ã¯ã‚³ãƒ¼ãƒ«ã¨ IM ã‚’å—ä¿¡ã—ãªã„" name="voice_call_friends_only_check"/>
+ <text name="font_size">
+ 文字ã®å¤§ãã•ï¼š
+ </text>
+ <combo_box name="chat_font_size">
+ <item label="å°è¦æ¨¡" name="Small" value="0"/>
+ <item label="中" name="Medium" value="1"/>
+ <item label="大è¦æ¨¡" name="Large" value="2"/>
+ </combo_box>
+ <check_box label="å¹ã出ã—ãƒãƒ£ãƒƒãƒˆ" name="bubble_text_chat"/>
+ </panel>
+ <panel name="im_notification_settings">
+ <text name="friend_ims">
+ フレンド IM:
+ </text>
+ <combo_box name="FriendIMOptions">
+ <item label="é–‹ã„ã¦ã„る会話ウィンドウ" name="OpenConversationsWindow" value="openconversations"/>
+ <item label="メッセージをãƒãƒƒãƒ—アップ表示" name="PopUpMessage" value="トースト"/>
+ <item label="フラッシュ ツールãƒãƒ¼ ボタン" name="FlashToolbarButton" value="フラッシュ"/>
+ <item label="動作ãªã—" name="NoAction" value="noaction"/>
+ </combo_box>
+ <check_box label="サウンドをå†ç”Ÿ" name="play_sound_friend_im"/>
+ <text name="non_friend_ims">
+ フレンドã®ã„ãªã„ IM:
+ </text>
+ <combo_box name="NonFriendIMOptions">
+ <item label="é–‹ã„ã¦ã„る会話ウィンドウ" name="OpenConversationsWindow" value="openconversations"/>
+ <item label="メッセージをãƒãƒƒãƒ—アップ表示" name="PopUpMessage" value="トースト"/>
+ <item label="フラッシュ ツールãƒãƒ¼ ボタン" name="FlashToolbarButton" value="フラッシュ"/>
+ <item label="動作ãªã—" name="NoAction" value="noaction"/>
+ </combo_box>
+ <check_box label="サウンドをå†ç”Ÿ" name="play_sound_non_friend_im"/>
+ <text name="conference_ims">
+ 会議 IM:
+ </text>
+ <combo_box name="ConferenceIMOptions">
+ <item label="é–‹ã„ã¦ã„る会話ウィンドウ" name="OpenConversationsWindow" value="openconversations"/>
+ <item label="メッセージをãƒãƒƒãƒ—アップ表示" name="PopUpMessage" value="トースト"/>
+ <item label="フラッシュ ツールãƒãƒ¼ ボタン" name="FlashToolbarButton" value="フラッシュ"/>
+ <item label="動作ãªã—" name="NoAction" value="noaction"/>
+ </combo_box>
+ <check_box label="サウンドをå†ç”Ÿ" name="play_sound_conference_im"/>
+ <text name="group_chat">
+ グループãƒãƒ£ãƒƒãƒˆ:
+ </text>
+ <combo_box name="GroupChatOptions">
+ <item label="é–‹ã„ã¦ã„る会話ウィンドウ" name="OpenConversationsWindow" value="openconversations"/>
+ <item label="メッセージをãƒãƒƒãƒ—アップ表示" name="PopUpMessage" value="トースト"/>
+ <item label="フラッシュ ツールãƒãƒ¼ ボタン" name="FlashToolbarButton" value="フラッシュ"/>
+ <item label="動作ãªã—" name="NoAction" value="noaction"/>
+ </combo_box>
+ <check_box label="サウンドをå†ç”Ÿ" name="play_sound_group_chat_im"/>
+ <text name="nearby_chat">
+ è¿‘ãã®ãƒãƒ£ãƒƒãƒˆ:
+ </text>
+ <combo_box name="NearbyChatOptions">
+ <item label="é–‹ã„ã¦ã„る会話ウィンドウ" name="OpenConversationsWindow" value="openconversations"/>
+ <item label="メッセージをãƒãƒƒãƒ—アップ表示" name="PopUpMessage" value="トースト"/>
+ <item label="フラッシュ ツールãƒãƒ¼ ボタン" name="FlashToolBarButton" value="フラッシュ"/>
+ <item label="動作ãªã—" name="NoAction" value="noaction"/>
+ </combo_box>
+ <check_box label="サウンドをå†ç”Ÿ" name="play_sound_nearby_chat_im"/>
+ <text name="object_ims">
+ オブジェクト IM:
+ </text>
+ <combo_box name="ObjectIMOptions">
+ <item label="é–‹ã„ã¦ã„る会話ウィンドウ" name="OpenConversationsWindow" value="openconversations"/>
+ <item label="メッセージをãƒãƒƒãƒ—アップ表示" name="PopUpMessage" value="トースト"/>
+ <item label="フラッシュ ツールãƒãƒ¼ ボタン" name="FlashToolBarButton" value="フラッシュ"/>
+ <item label="動作ãªã—" name="NoAction" value="noaction"/>
+ </combo_box>
+ <check_box label="サウンドをå†ç”Ÿ" name="play_sound_object_im"/>
+ <text name="notifications_alert">
+ 一時的ã«ã™ã¹ã¦ã®é€šçŸ¥ã‚’åœæ­¢ã™ã‚‹ã«ã¯ã€ã€Œã‚³ãƒŸãƒ¥ãƒ‹ã‚±ãƒ¼ã‚·ãƒ§ãƒ³ã€ &gt; 「ç€ä¿¡æ‹’å¦]を使用ã—ã¾ã™ã€‚
+ </text>
+ </panel>
+ <panel name="play_sound_settings">
+ <text name="play_sound">
+ サウンドをå†ç”Ÿ:
+ </text>
+ <check_box label="æ–°ã—ã„会話" name="new_conversation"/>
+ <check_box label="å—信音声コール" name="incoming_voice_call"/>
+ <check_box label="テレãƒãƒ¼ãƒˆã‚’é€ã‚‹" name="teleport_offer"/>
+ <check_box label="インベントリをé€ã‚‹" name="inventory_offer"/>
+ </panel>
+ <panel name="log_settings">
+ <button label="ログを消去..." name="clear_log"/>
+ <button label="テキストãƒãƒ£ãƒƒãƒˆã‚’削除..." name="delete_transcripts"/>
+ <button label="å‚ç…§..." label_selected="å‚ç…§" name="log_path_button"/>
+ </panel>
+ <button label="ä»–ã®è¨€èªž..." name="ok_btn"/>
+ <button label="自動置æ›..." name="autoreplace_showgui"/>
+ <button label="スペルãƒã‚§ãƒƒã‚¯ä¸­..." name="spellcheck_showgui"/>
</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_preferences_colors.xml b/indra/newview/skins/default/xui/ja/panel_preferences_colors.xml
index 9f6abf8fcb..9f6abf8fcb 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_preferences_colors.xml
+++ b/indra/newview/skins/default/xui/ja/panel_preferences_colors.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_preferences_general.xml b/indra/newview/skins/default/xui/ja/panel_preferences_general.xml
index 91e1514e49..d70af7e099 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_preferences_general.xml
+++ b/indra/newview/skins/default/xui/ja/panel_preferences_general.xml
@@ -69,9 +69,9 @@
<combo_box.item label="一時退席設定ãªã—" name="item4"/>
</combo_box>
<text name="text_box3">
- å–ã‚Šè¾¼ã¿ä¸­ãƒ¢ãƒ¼ãƒ‰æ™‚ã®è¿”事:
+ 「通知をå—ã‘ãªã„ã€å¿œç­”:
</text>
- <text_editor name="busy_response">
+ <text_editor name="do_not_disturb_response">
log_in_to_change
</text_editor>
</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/ja/panel_preferences_graphics1.xml
index 1786b4befc..15017e330e 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_preferences_graphics1.xml
+++ b/indra/newview/skins/default/xui/ja/panel_preferences_graphics1.xml
@@ -30,7 +30,7 @@
<check_box initial_value="true" label="è¿‘ãã®å…‰" name="LocalLights"/>
<check_box initial_value="true" label="基本シェーダー" name="BasicShaders" tool_tip="ã“ã®ã‚ªãƒ—ションを無効ã«ã™ã‚‹ã¨ã€ã‚°ãƒ©ãƒ•ã‚£ãƒƒã‚¯ã‚«ãƒ¼ãƒ‰ã®ãƒ‰ãƒ©ã‚¤ãƒã®ç¨®é¡žã«ã‚ˆã£ã¦ã¯ã€ã‚¯ãƒ©ãƒƒã‚·ãƒ¥ã™ã‚‹ã®ã‚’防ãŽã¾ã™ã€‚"/>
<check_box initial_value="true" label="周囲(大気)シェーダー" name="WindLightUseAtmosShaders"/>
- <check_box initial_value="true" label="å…‰ã¨å½±" name="UseLightShaders"/>
+ <check_box initial_value="true" label="高度ãªãƒ©ã‚¤ãƒ†ã‚£ãƒ³ã‚°ãƒ¢ãƒ‡ãƒ«" name="UseLightShaders"/>
<check_box initial_value="true" label="アンビエントオクルージョン" name="UseSSAO"/>
<check_box initial_value="true" label="フィールドã®é è¿‘æ„Ÿ" name="UseDoF"/>
<text name="shadows_label">
diff --git a/indra/newview/skins/default/xui/ja/panel_preferences_move.xml b/indra/newview/skins/default/xui/ja/panel_preferences_move.xml
index 121bebfd52..121bebfd52 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_preferences_move.xml
+++ b/indra/newview/skins/default/xui/ja/panel_preferences_move.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_preferences_privacy.xml b/indra/newview/skins/default/xui/ja/panel_preferences_privacy.xml
index 420bbed572..420bbed572 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_preferences_privacy.xml
+++ b/indra/newview/skins/default/xui/ja/panel_preferences_privacy.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_preferences_setup.xml b/indra/newview/skins/default/xui/ja/panel_preferences_setup.xml
index d90a1632ab..2c0359cb15 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_preferences_setup.xml
+++ b/indra/newview/skins/default/xui/ja/panel_preferences_setup.xml
@@ -29,6 +29,7 @@
<combo_box.item label="自動的ã«ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«" name="Install_automatically"/>
<combo_box.item label="手動ã§ã‚¢ãƒƒãƒ—デートをダウンロード&amp;インストール" name="Install_manual"/>
</combo_box>
+ <check_box label="release candidate ã«ã‚¢ãƒƒãƒ—グレードã—ã¾ã™" name="update_willing_to_test"/>
<text name="Proxy Settings:">
プロキシ設定:
</text>
diff --git a/indra/newview/skins/default/xui/ja/panel_preferences_sound.xml b/indra/newview/skins/default/xui/ja/panel_preferences_sound.xml
index 3a4c360ccc..3a4c360ccc 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_preferences_sound.xml
+++ b/indra/newview/skins/default/xui/ja/panel_preferences_sound.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_prim_media_controls.xml b/indra/newview/skins/default/xui/ja/panel_prim_media_controls.xml
index 5506373eb0..5506373eb0 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_prim_media_controls.xml
+++ b/indra/newview/skins/default/xui/ja/panel_prim_media_controls.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_region_covenant.xml b/indra/newview/skins/default/xui/ja/panel_region_covenant.xml
index 5214f79141..5214f79141 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_region_covenant.xml
+++ b/indra/newview/skins/default/xui/ja/panel_region_covenant.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_region_debug.xml b/indra/newview/skins/default/xui/ja/panel_region_debug.xml
index f6865c12b1..169da27ce5 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_region_debug.xml
+++ b/indra/newview/skins/default/xui/ja/panel_region_debug.xml
@@ -36,5 +36,5 @@
<button label="?" name="top_scripts_help"/>
<button label="地域å†èµ·å‹•" name="restart_btn" tool_tip="2分間ã®ã‚«ã‚¦ãƒ³ãƒˆãƒ€ã‚¦ãƒ³å¾Œã€åœ°åŸŸã‚’å†èµ·å‹•ã—ã¾ã™"/>
<button label="?" name="restart_help"/>
- <button label="å†èµ·å‹•ã‚’é…延" name="cancel_restart_btn" tool_tip="地域ã®å†èµ·å‹•ã‚’1時間é…延ã—ã¾ã™"/>
+ <button label="å†èµ·å‹•ã‚’キャンセル" name="cancel_restart_btn" tool_tip="リージョンã®å†èµ·å‹•ã‚’キャンセル"/>
</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_region_environment.xml b/indra/newview/skins/default/xui/ja/panel_region_environment.xml
index f6ef3f0934..f6ef3f0934 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_region_environment.xml
+++ b/indra/newview/skins/default/xui/ja/panel_region_environment.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_region_estate.xml b/indra/newview/skins/default/xui/ja/panel_region_estate.xml
index 2e58c5a8f1..b5cc6b9765 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_region_estate.xml
+++ b/indra/newview/skins/default/xui/ja/panel_region_estate.xml
@@ -19,7 +19,7 @@
次ã®ä½äººã«ã®ã¿ã‚¢ã‚¯ã‚»ã‚¹ã‚’許å¯ï¼š
</text>
<check_box label="支払情情報ãŒç™»éŒ²ã•ã‚Œã¦ã„ã‚‹" name="limit_payment" tool_tip="支払情報ãŒç™»éŒ²ã•ã‚Œã¦ã„ãªã„ã¨ã€ã“ã®ä¸å‹•ç”£ã«ã‚¢ã‚¯ã‚»ã‚¹ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。詳細ã«ã¤ã„ã¦ã¯ã€[SUPPORT_SITE] ã‚’ã”覧ãã ã•ã„。"/>
- <check_box label="年齢確èªãŒæ¸ˆã‚“ã§ã„ã‚‹" name="limit_age_verified" tool_tip="ã“ã®ä¸å‹•ç”£ã«ã‚¢ã‚¯ã‚»ã‚¹ã™ã‚‹ã«ã¯ã€å¹´é½¢ç¢ºèªã‚’済ã¾ã›ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚詳細ã«ã¤ã„ã¦ã¯ã€[SUPPORT_SITE] ã‚’ã”覧ãã ã•ã„。"/>
+ <check_box label="18 æ‰ä»¥ä¸Šã§ã™" name="limit_age_verified" tool_tip="ã“ã®ä¸å‹•ç”£ï¼ˆã‚¨ã‚¹ãƒ†ãƒ¼ãƒˆï¼‰ã«ã‚¢ã‚¯ã‚»ã‚¹ã™ã‚‹ã«ã¯ã€18 æ‰ä»¥ä¸Šã§ãªã‘ã‚Œã°ãªã‚Šã¾ã›ã‚“。詳細ã«ã¤ã„ã¦ã¯ã€[SUPPORT_SITE] ã‚’ã”覧ãã ã•ã„。"/>
<check_box label="ボイスãƒãƒ£ãƒƒãƒˆã‚’許å¯" name="voice_chat_check"/>
<button label="?" name="voice_chat_help"/>
<text name="abuse_email_text">
diff --git a/indra/newview/skins/default/xui/ja/panel_region_general.xml b/indra/newview/skins/default/xui/ja/panel_region_general.xml
index 65148cf1ee..65148cf1ee 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_region_general.xml
+++ b/indra/newview/skins/default/xui/ja/panel_region_general.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_region_terrain.xml b/indra/newview/skins/default/xui/ja/panel_region_terrain.xml
index fb853c1925..fb853c1925 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_region_terrain.xml
+++ b/indra/newview/skins/default/xui/ja/panel_region_terrain.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_region_texture.xml b/indra/newview/skins/default/xui/ja/panel_region_texture.xml
deleted file mode 100644
index 9e442ce091..0000000000
--- a/indra/newview/skins/default/xui/ja/panel_region_texture.xml
+++ /dev/null
@@ -1,58 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel label="地é¢ãƒ†ã‚¯ã‚¹ãƒãƒ£" name="Textures">
- <text name="region_text_lbl">
- 地域:
- </text>
- <text name="region_text">
- 未知
- </text>
- <text name="detail_texture_text">
- 地形ã®ãƒ†ã‚¯ã‚¹ãƒãƒ£ (512x512ã€24ビット .tgaファイルãŒå¿…è¦ã§ã™ï¼‰
- </text>
- <text name="height_text_lbl">
- 1(低)
- </text>
- <text name="height_text_lbl2">
- 2
- </text>
- <text name="height_text_lbl3">
- 3
- </text>
- <text name="height_text_lbl4">
- 4(高)
- </text>
- <text name="height_text_lbl5">
- 地形テクスãƒãƒ£ã®éš†èµ·ç¯„囲
- </text>
- <text name="height_text_lbl6">
- 北西
- </text>
- <text name="height_text_lbl7">
- 北æ±
- </text>
- <text name="height_text_lbl8">
- å—西
- </text>
- <text name="height_text_lbl9">
- å—æ±
- </text>
- <spinner label="低" name="height_start_spin_0"/>
- <spinner label="低" name="height_start_spin_1"/>
- <spinner label="低" name="height_start_spin_2"/>
- <spinner label="低" name="height_start_spin_3"/>
- <spinner label="高" name="height_range_spin_0"/>
- <spinner label="高" name="height_range_spin_1"/>
- <spinner label="高" name="height_range_spin_2"/>
- <spinner label="高" name="height_range_spin_3"/>
- <text name="height_text_lbl10">
- 数値ã¯ä¸Šã®ãƒ†ã‚¯ã‚¹ãƒãƒ£ãŒèª¿å’Œã™ã‚‹ç¯„囲を示ã—ã¾ã™ã€‚
- </text>
- <text name="height_text_lbl11">
- 計測å˜ä½ã¯ãƒ¡ãƒ¼ãƒˆãƒ«ã§ã€ã€Œä½Žã€ã®å€¤ã¯ã€1番ã®ãƒ†ã‚¯ã‚¹ãƒãƒ£ã®é«˜ã•ã®
-「最大値ã€ã§ã™ã€‚「高ã€ã®å€¤ã¯ã€4番ã®ãƒ†ã‚¯ã‚¹ãƒãƒ£ã®é«˜ã•ã®ã€Œæœ€ä½Žå€¤ã€ã§ã™ã€‚
- </text>
- <text name="height_text_lbl12">
- ãã—ã¦ã€Œé«˜ã€ã®å€¤ã¯ãƒ†ã‚¯ã‚¹ãƒãƒ£#4ã®é«˜ã•ã®ä¸‹é™ã¨ãªã‚Šã¾ã™ã€‚
- </text>
- <button label="é©ç”¨" name="apply_btn"/>
-</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_script_ed.xml b/indra/newview/skins/default/xui/ja/panel_script_ed.xml
index 14d55002a3..b6d51085eb 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_script_ed.xml
+++ b/indra/newview/skins/default/xui/ja/panel_script_ed.xml
@@ -34,6 +34,7 @@
<menu_item_call label="ã™ã¹ã¦é¸æŠž" name="Select All"/>
<menu_item_call label="é¸æŠžè§£é™¤" name="Deselect"/>
<menu_item_call label="検索 / å†é…ç½®..." name="Search / Replace..."/>
+ <menu_item_call label="è¡Œã«ç§»å‹•..." name="Go to line..."/>
</menu>
<menu label="ヘルプ" name="Help">
<menu_item_call label="ヘルプ..." name="Help..."/>
diff --git a/indra/newview/skins/default/xui/ja/panel_script_limits_my_avatar.xml b/indra/newview/skins/default/xui/ja/panel_script_limits_my_avatar.xml
index 494884c187..494884c187 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_script_limits_my_avatar.xml
+++ b/indra/newview/skins/default/xui/ja/panel_script_limits_my_avatar.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_script_limits_region_memory.xml b/indra/newview/skins/default/xui/ja/panel_script_limits_region_memory.xml
index d91eba9699..d91eba9699 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_script_limits_region_memory.xml
+++ b/indra/newview/skins/default/xui/ja/panel_script_limits_region_memory.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_script_question_toast.xml b/indra/newview/skins/default/xui/ja/panel_script_question_toast.xml
new file mode 100755
index 0000000000..a2d0237da0
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/panel_script_question_toast.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<panel label="script_question_panel" name="panel_script_question_toast">
+ <panel label="buttons_panel" name="buttons_panel"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_scrolling_param.xml b/indra/newview/skins/default/xui/ja/panel_scrolling_param.xml
index b698fa762d..b698fa762d 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_scrolling_param.xml
+++ b/indra/newview/skins/default/xui/ja/panel_scrolling_param.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_scrolling_param_base.xml b/indra/newview/skins/default/xui/ja/panel_scrolling_param_base.xml
index fa659040ea..fa659040ea 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_scrolling_param_base.xml
+++ b/indra/newview/skins/default/xui/ja/panel_scrolling_param_base.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_side_tray.xml b/indra/newview/skins/default/xui/ja/panel_side_tray.xml
deleted file mode 100644
index 3fd14ece06..0000000000
--- a/indra/newview/skins/default/xui/ja/panel_side_tray.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<!-- Side tray cannot show background because it is always
- partially on screen to hold tab buttons. -->
-<side_tray name="sidebar">
- <sidetray_tab description="サイドãƒãƒ¼ã‚’表示・éžè¡¨ç¤º" name="sidebar_openclose" tab_title="サイドãƒãƒ¼ã‚’é–‹ã・閉ã˜ã‚‹"/>
- <sidetray_tab description="ホーム。" name="sidebar_home" tab_title="ホーム">
- <panel label="ホーム" name="panel_home"/>
- </sidetray_tab>
- <sidetray_tab description="ã‚ãªãŸã®å…¬é–‹ãƒ—ロフィールã¨ãƒ”ックを編集ã—ã¦ãã ã•ã„。" name="sidebar_me" tab_title="マイ プロフィール">
- <panel_container name="panel_container">
- <panel label="ミー" name="panel_me"/>
- </panel_container>
- </sidetray_tab>
- <sidetray_tab description="フレンドã€é€£çµ¡å…ˆã€è¿‘ãã®äººã‚’探ã—ã¦ãã ã•ã„。" name="sidebar_people" tab_title="人">
- <panel_container name="panel_container">
- <panel label="グループ情報" name="panel_group_info_sidetray"/>
- <panel label="ブロックã•ã‚ŒãŸä½äººã¨ã‚ªãƒ–ジェクト" name="panel_block_list_sidetray"/>
- </panel_container>
- </sidetray_tab>
- <sidetray_tab description="è¡ŒããŸã„場所ã€è¡Œã£ãŸã“ã¨ã®ã‚る場所を探ã—ã¦ãã ã•ã„。" label="場所" name="sidebar_places" tab_title="場所">
- <panel label="場所" name="panel_places"/>
- </sidetray_tab>
- <sidetray_tab description="ã‚ãªãŸã®æŒã¡ç‰©ã‚’眺ã‚ã¦ãã ã•ã„。" name="sidebar_inventory" tab_title="æŒã¡ç‰©">
- <panel label="æŒã¡ç‰©ã‚’編集" name="sidepanel_inventory"/>
- </sidetray_tab>
- <sidetray_tab description="ã‚ãªãŸã®å®¹å§¿ã‚„ç¾åœ¨ã®è¦‹ãŸç›®ã‚’変更ã—ã¦ãã ã•ã„。" name="sidebar_appearance" tab_title="容姿">
- <panel label="容姿ã®ç·¨é›†" name="sidepanel_appearance"/>
- </sidetray_tab>
-</side_tray>
diff --git a/indra/newview/skins/default/xui/ja/panel_side_tray_tab_caption.xml b/indra/newview/skins/default/xui/ja/panel_side_tray_tab_caption.xml
index d06db8ccb1..d06db8ccb1 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_side_tray_tab_caption.xml
+++ b/indra/newview/skins/default/xui/ja/panel_side_tray_tab_caption.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_sidetray_home_tab.xml b/indra/newview/skins/default/xui/ja/panel_sidetray_home_tab.xml
index ea17cd6526..ea17cd6526 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_sidetray_home_tab.xml
+++ b/indra/newview/skins/default/xui/ja/panel_sidetray_home_tab.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_snapshot_inventory.xml b/indra/newview/skins/default/xui/ja/panel_snapshot_inventory.xml
index e496e6602b..e496e6602b 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_snapshot_inventory.xml
+++ b/indra/newview/skins/default/xui/ja/panel_snapshot_inventory.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_snapshot_local.xml b/indra/newview/skins/default/xui/ja/panel_snapshot_local.xml
index cb658fb6c9..cb658fb6c9 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_snapshot_local.xml
+++ b/indra/newview/skins/default/xui/ja/panel_snapshot_local.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_snapshot_options.xml b/indra/newview/skins/default/xui/ja/panel_snapshot_options.xml
index c3b1cd91e7..c3b1cd91e7 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_snapshot_options.xml
+++ b/indra/newview/skins/default/xui/ja/panel_snapshot_options.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_snapshot_postcard.xml b/indra/newview/skins/default/xui/ja/panel_snapshot_postcard.xml
index 1ddd723840..1ddd723840 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_snapshot_postcard.xml
+++ b/indra/newview/skins/default/xui/ja/panel_snapshot_postcard.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_snapshot_profile.xml b/indra/newview/skins/default/xui/ja/panel_snapshot_profile.xml
index b860a6afe9..b860a6afe9 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_snapshot_profile.xml
+++ b/indra/newview/skins/default/xui/ja/panel_snapshot_profile.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_sound_devices.xml b/indra/newview/skins/default/xui/ja/panel_sound_devices.xml
index 0824504235..0824504235 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_sound_devices.xml
+++ b/indra/newview/skins/default/xui/ja/panel_sound_devices.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_stand_stop_flying.xml b/indra/newview/skins/default/xui/ja/panel_stand_stop_flying.xml
index 2308aff19b..2308aff19b 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_stand_stop_flying.xml
+++ b/indra/newview/skins/default/xui/ja/panel_stand_stop_flying.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_status_bar.xml b/indra/newview/skins/default/xui/ja/panel_status_bar.xml
index f09643d562..f09643d562 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_status_bar.xml
+++ b/indra/newview/skins/default/xui/ja/panel_status_bar.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_sys_well_item.xml b/indra/newview/skins/default/xui/ja/panel_sys_well_item.xml
index 81db7c8989..81db7c8989 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_sys_well_item.xml
+++ b/indra/newview/skins/default/xui/ja/panel_sys_well_item.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_teleport_history.xml b/indra/newview/skins/default/xui/ja/panel_teleport_history.xml
index 58e396877c..58e396877c 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_teleport_history.xml
+++ b/indra/newview/skins/default/xui/ja/panel_teleport_history.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_teleport_history_item.xml b/indra/newview/skins/default/xui/ja/panel_teleport_history_item.xml
index c570cd5696..c570cd5696 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_teleport_history_item.xml
+++ b/indra/newview/skins/default/xui/ja/panel_teleport_history_item.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_tools_texture.xml b/indra/newview/skins/default/xui/ja/panel_tools_texture.xml
new file mode 100644
index 0000000000..34763f78c1
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/panel_tools_texture.xml
@@ -0,0 +1,116 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="テクスãƒãƒ£" name="Texture">
+ <panel.string name="string repeats per meter">
+ メーターã”ã¨ã«ç¹°ã‚Šè¿”ã™
+ </panel.string>
+ <panel.string name="string repeats per face">
+ é¢ã”ã¨ã«ç¹°ã‚Šè¿”ã™
+ </panel.string>
+ <text name="color label">
+ 色
+ </text>
+ <color_swatch label="" name="colorswatch" tool_tip="クリックã—ã¦ã‚«ãƒ©ãƒ¼ãƒ”ッカーを開ãã¾ã™"/>
+ <text name="color trans">
+ é€éŽåº¦ %
+ </text>
+ <text name="glow label">
+ グロー
+ </text>
+ <check_box label="明るã•å…¨é–‹" name="checkbox fullbright"/>
+ <combo_box name="combobox matmedia">
+ <combo_box.item label="æ質" name="Materials"/>
+ <combo_box.item label="メディア" name="Media"/>
+ </combo_box>
+ <combo_box name="combobox mattype">
+ <combo_box.item label="テクスãƒãƒ£ (æ‹¡æ•£)" name="Texture (diffuse)"/>
+ <combo_box.item label="凹凸 (標準)" name="Bumpiness (normal)"/>
+ <combo_box.item label="è¼ã (åå°„)" name="Shininess (specular)"/>
+ </combo_box>
+ <texture_picker label="テクスãƒãƒ£" name="texture control" tool_tip="クリックã—ã¦å†™çœŸã‚’é¸æŠžã—ã¾ã™"/>
+ <text name="label alphamode">
+ アルファモード
+ </text>
+ <combo_box name="combobox alphamode">
+ <combo_box.item label="ãªã—" name="None"/>
+ <combo_box.item label="アルファブレンディング" name="Alpha blending"/>
+ <combo_box.item label="アルファマスキング" name="Alpha masking"/>
+ <combo_box.item label="放射状マスク" name="Emissive mask"/>
+ </combo_box>
+ <text name="label maskcutoff">
+ マスクカットオフ
+ </text>
+ <texture_picker label="テクスãƒãƒ£" name="bumpytexture control" tool_tip="クリックã—ã¦å†™çœŸã‚’é¸æŠžã—ã¾ã™"/>
+ <text name="label bumpiness">
+ 凹凸
+ </text>
+ <combo_box name="combobox bumpiness">
+ <combo_box.item label="ãªã—" name="None"/>
+ <combo_box.item label="明るã•" name="Brightness"/>
+ <combo_box.item label="æš—ã•" name="Darkness"/>
+ <combo_box.item label="木目調" name="woodgrain"/>
+ <combo_box.item label="ãƒãƒ¼ã‚¯" name="bark"/>
+ <combo_box.item label="レンガ" name="bricks"/>
+ <combo_box.item label="市æ¾æ¨¡æ§˜" name="checker"/>
+ <combo_box.item label="コンクリート" name="concrete"/>
+ <combo_box.item label="å …ã„タイル" name="crustytile"/>
+ <combo_box.item label="カットストーン" name="cutstone"/>
+ <combo_box.item label="円æ¿" name="discs"/>
+ <combo_box.item label="å°çŸ³" name="gravel"/>
+ <combo_box.item label="ペトリ皿" name="petridish"/>
+ <combo_box.item label="サイディング" name="siding"/>
+ <combo_box.item label="ストーンタイル" name="stonetile"/>
+ <combo_box.item label="化粧ã—ã£ãã„" name="stucco"/>
+ <combo_box.item label="サクション" name="suction"/>
+ <combo_box.item label="ウィーブ" name="weave"/>
+ </combo_box>
+ <texture_picker label="テクスãƒãƒ£" name="shinytexture control" tool_tip="クリックã—ã¦å†™çœŸã‚’é¸æŠžã—ã¾ã™"/>
+ <text name="label shininess">
+ è¼ã
+ </text>
+ <combo_box name="combobox shininess">
+ <combo_box.item label="ãªã—" name="None"/>
+ <combo_box.item label="低" name="Low"/>
+ <combo_box.item label="中" name="Medium"/>
+ <combo_box.item label="高" name="High"/>
+ </combo_box>
+ <text name="label glossiness">
+ 光沢度
+ </text>
+ <text name="label environment">
+ 環境
+ </text>
+ <text name="label shinycolor">
+ 色
+ </text>
+ <color_swatch label="" name="shinycolorswatch" tool_tip="クリックã—ã¦ã‚«ãƒ©ãƒ¼ãƒ”ッカーを開ãã¾ã™"/>
+ <text name="media_info">
+ é¸æŠžã—ãŸãƒ¡ãƒ‡ã‚£ã‚¢ã® URL ãŒã‚‚ã—ã‚ã‚Œã°ã€ã“ã“ã«å…¥ã‚Šã¾ã™
+ </text>
+ <button label="é¸æŠž..." name="add_media" tool_tip="メディアを追加ã—ã¾ã™"/>
+ <button label="削除" name="delete_media" tool_tip="ã“ã®ãƒ¡ãƒ‡ã‚£ã‚¢ãƒ†ã‚¯ã‚¹ãƒãƒ£ã‚’削除ã—ã¾ã™"/>
+ <button label="æƒãˆã‚‹" label_selected="メディアを一列ã«æƒãˆã¾ã™" name="button align" tool_tip="メディアテクスãƒãƒ£ã‚’一列ã«æƒãˆã‚‹ï¼ˆæœ€åˆã«èª­ã¿è¾¼ã‚€å¿…è¦ãŒã‚ã‚Šã¾ã™ï¼‰"/>
+ <text name="tex gen">
+ マッピング
+ </text>
+ <combo_box name="combobox texgen">
+ <combo_box.item label="デフォルト" name="Default"/>
+ <combo_box.item label="å¹³é¢" name="Planar"/>
+ </combo_box>
+ <spinner label="水平スケール" name="TexScaleU"/>
+ <spinner label="垂直スケール" name="TexScaleV"/>
+ <spinner label="メーターã”ã¨ã«ç¹°ã‚Šè¿”ã™" name="rptctrl"/>
+ <spinner label="回転度" name="TexRot"/>
+ <spinner label="水平オフセット" name="TexOffsetU"/>
+ <spinner label="垂直オフセット" name="TexOffsetV"/>
+ <spinner label="水平スケール" name="bumpyScaleU"/>
+ <spinner label="垂直スケール" name="bumpyScaleV"/>
+ <spinner label="回転度" name="bumpyRot"/>
+ <spinner label="水平オフセット" name="bumpyOffsetU"/>
+ <spinner label="垂直オフセット" name="bumpyOffsetV"/>
+ <spinner label="水平スケール" name="shinyScaleU"/>
+ <spinner label="垂直スケール" name="shinyScaleV"/>
+ <spinner label="回転度" name="shinyRot"/>
+ <spinner label="水平オフセット" name="shinyOffsetU"/>
+ <spinner label="垂直オフセット" name="shinyOffsetV"/>
+ <check_box initial_value="false" label="å¹³é¢ã‚’æƒãˆã‚‹" name="checkbox planar align" tool_tip="é¸æŠžé¢å…¨ã¦ã®ãƒ†ã‚¯ã‚¹ãƒãƒ£ã‚’ã€æœ€å¾Œã«é¸æŠžã•ã‚ŒãŸé¢ã«æƒãˆã¾ã™ã€‚å¹³é¢ãƒ†ã‚¯ã‚¹ãƒãƒ£ã®ãƒžãƒƒãƒ”ングãŒå¿…è¦ã§ã™ã€‚"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_voice_effect.xml b/indra/newview/skins/default/xui/ja/panel_voice_effect.xml
index 530f0fb59d..530f0fb59d 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_voice_effect.xml
+++ b/indra/newview/skins/default/xui/ja/panel_voice_effect.xml
diff --git a/indra/newview/skins/default/xui/ja/panel_volume_pulldown.xml b/indra/newview/skins/default/xui/ja/panel_volume_pulldown.xml
new file mode 100755
index 0000000000..967dedf061
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/panel_volume_pulldown.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="volumepulldown_floater">
+ <slider label="マスター" name="System Volume"/>
+ <slider label="ボタン" name="UI Volume"/>
+ <slider label="環境音" name="Wind Volume"/>
+ <slider label="サウンド" name="SFX Volume"/>
+ <check_box name="gesture_audio_play_btn" tool_tip="ジェスãƒãƒ£ãƒ¼ã®éŸ³ã‚’有効ã«ã™ã‚‹"/>
+ <slider label="音楽" name="Music Volume"/>
+ <check_box name="enable_music" tool_tip="ストリーミング音楽を有効ã«ã™ã‚‹"/>
+ <slider label="メディア" name="Media Volume"/>
+ <check_box name="enable_media" tool_tip="ストリーミングメディアを有効ã«ã™ã‚‹"/>
+ <slider label="ボイス" name="Voice Volume"/>
+ <check_box name="enable_voice_check" tool_tip="ボイスãƒãƒ£ãƒƒãƒˆã‚’有効ã«ã™ã‚‹"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_world_map.xml b/indra/newview/skins/default/xui/ja/panel_world_map.xml
index 8ff853193a..8ff853193a 100644..100755
--- a/indra/newview/skins/default/xui/ja/panel_world_map.xml
+++ b/indra/newview/skins/default/xui/ja/panel_world_map.xml
diff --git a/indra/newview/skins/default/xui/ja/role_actions.xml b/indra/newview/skins/default/xui/ja/role_actions.xml
index 896ed556ae..5c2e18df03 100644..100755
--- a/indra/newview/skins/default/xui/ja/role_actions.xml
+++ b/indra/newview/skins/default/xui/ja/role_actions.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<role_actions>
<action_set description="ã“れらã®èƒ½åŠ›ã«ã¯ã€ã‚°ãƒ«ãƒ¼ãƒ—メンãƒãƒ¼ã‚’追加ã€æŽ’除ã—ã€æ‹›å¾…状ãªã—ã«æ–°ãƒ¡ãƒ³ãƒãƒ¼ã®å‚加をèªã‚る権é™ãŒå«ã¾ã‚Œã¾ã™ã€‚" name="Membership">
<action description="ã“ã®ã‚°ãƒ«ãƒ¼ãƒ—ã«äººã‚’招待" longdescription="「役割ã€ã‚»ã‚¯ã‚·ãƒ§ãƒ³ã®ã€Œãƒ¡ãƒ³ãƒãƒ¼ã€ã‚¿ãƒ–内ã«ã‚る「招待ã€ãƒœã‚¿ãƒ³ã‚’押ã—ã¦ã€ã“ã®ã‚°ãƒ«ãƒ¼ãƒ—ã«ãƒ¡ãƒ³ãƒãƒ¼ã‚’招待ã—ã¾ã™ã€‚" name="member invite" value="1"/>
@@ -25,7 +25,7 @@
</action_set>
<action_set description="ã“れらã®èƒ½åŠ›ã«ã¯ã€åŒºç”»åã€å…¬é–‹è¨­å®šã€æ¤œç´¢ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã¸ã®ç™»éŒ²ã€ç€åœ°ç‚¹ãªã‚‰ã³ã« TP ルートã®ã‚ªãƒ—ションを変更ã™ã‚‹æ¨©é™ãŒå«ã¾ã‚Œã¾ã™ã€‚" name="Parcel Identity">
<action description="「場所検索ã«è¡¨ç¤ºã€ã‚’切り替ãˆã‚«ãƒ†ã‚´ãƒªã‚’設定" longdescription="「場所検索ã«è¡¨ç¤ºã€ã«åˆ‡ã‚Šæ›¿ãˆã€ã€ŒåœŸåœ°æƒ…報〠&gt; 「オプションã€ã‚¿ãƒ–ã§åŒºç”»ã®ã‚«ãƒ†ã‚´ãƒªã‚’設定ã—ã¾ã™ã€‚" name="land find places" value="17"/>
- <action description="区画åã€èª¬æ˜Žã€ã€Œå ´æ‰€æ¤œç´¢ã«è¡¨ç¤ºã€ã®è¨­å®šã‚’変更" longdescription="区画åã€èª¬æ˜Žã€ã€Œå ´æ‰€æ¤œç´¢ã«è¡¨ç¤ºã€ã®è¨­å®šã‚’変更ã—ã¾ã™ã€‚ 「土地情報〠&gt; 「オプションã€ã‚¿ãƒ–ã§è¡Œã„ã¾ã™ã€‚" name="land change identity" value="18"/>
+ <action description="区画åã€èª¬æ˜Žã€ãŠã‚ˆã³ã€ŒModerate コンテンツã€è¨­å®šã‚’変更" longdescription="区画åã€èª¬æ˜Žã€ãŠã‚ˆã³ã€ŒModerate コンテンツã€è¨­å®šã‚’変更ã—ã¾ã™ã€‚「土地情報〠&gt; 「オプションã€ã‚¿ãƒ–ã§è¡Œã„ã¾ã™ã€‚" name="land change identity" value="18"/>
<action description="ç€åœ°ç‚¹ãŠã‚ˆã³ãƒ†ãƒ¬ãƒãƒ¼ãƒˆãƒ«ãƒ¼ãƒˆã‚’設定" longdescription="ã“ã®èƒ½åŠ›ã‚’æŒã¤å½¹å‰²ã®ãƒ¡ãƒ³ãƒãƒ¼ã¯ã€ã‚°ãƒ«ãƒ¼ãƒ—所有ã®åŒºç”»ä¸Šã§ç€åœ°ç‚¹ã‚’設定ã™ã‚‹ã“ã¨ã«ã‚ˆã‚Šå¤–部ã‹ã‚‰ã®ãƒ†ãƒ¬ãƒãƒ¼ãƒˆã®åˆ°ç€ä½ç½®ã‚’指定ã§ãã‚‹ã¨å…±ã«ã€ãƒ†ãƒ¬ãƒãƒ¼ãƒˆãƒ«ãƒ¼ãƒˆã‚’設定ã—ã¦ç´°ã‹ã制御ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚ ã“ã®æ“作ã¯ã€ã€ŒåœŸåœ°æƒ…å ±ã€ï¼žã€Œã‚ªãƒ—ションã€ã‚¿ãƒ–ã§è¡Œã„ã¾ã™ã€‚" name="land set landing point" value="19"/>
</action_set>
<action_set description="ã“れらã®èƒ½åŠ›ã«ã¯ã€ã€Œã‚ªãƒ–ジェクトを作æˆã€ã€ã€Œåœ°å½¢ã‚’編集ã€ã€éŸ³æ¥½ã¨ãƒ¡ãƒ‡ã‚£ã‚¢ã®è¨­å®šãªã©ã€åŒºç”»ã®ã‚ªãƒ—ションã«é–¢é€£ã™ã‚‹æ¨©é™ãŒå«ã¾ã‚Œã¾ã™ã€‚" name="Parcel Settings">
diff --git a/indra/newview/skins/default/xui/ja/sidepanel_appearance.xml b/indra/newview/skins/default/xui/ja/sidepanel_appearance.xml
index 30cef9ccc0..30cef9ccc0 100644..100755
--- a/indra/newview/skins/default/xui/ja/sidepanel_appearance.xml
+++ b/indra/newview/skins/default/xui/ja/sidepanel_appearance.xml
diff --git a/indra/newview/skins/default/xui/ja/sidepanel_inventory.xml b/indra/newview/skins/default/xui/ja/sidepanel_inventory.xml
index 51d6d48f90..51d6d48f90 100644..100755
--- a/indra/newview/skins/default/xui/ja/sidepanel_inventory.xml
+++ b/indra/newview/skins/default/xui/ja/sidepanel_inventory.xml
diff --git a/indra/newview/skins/default/xui/ja/sidepanel_item_info.xml b/indra/newview/skins/default/xui/ja/sidepanel_item_info.xml
index 6931e448b3..e70d91d258 100644..100755
--- a/indra/newview/skins/default/xui/ja/sidepanel_item_info.xml
+++ b/indra/newview/skins/default/xui/ja/sidepanel_item_info.xml
@@ -1,8 +1,11 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel name="item properties" title="アイテムã®ãƒ—ロフィール">
<panel.string name="unknown">
(ä¸æ˜Žï¼‰
</panel.string>
+ <panel.string name="unknown_multiple">
+ (ä¸æ˜Ž/複数)
+ </panel.string>
<panel.string name="public">
(公開)
</panel.string>
diff --git a/indra/newview/skins/default/xui/ja/sidepanel_task_info.xml b/indra/newview/skins/default/xui/ja/sidepanel_task_info.xml
index eb2bfa993b..4f65c8477b 100644..100755
--- a/indra/newview/skins/default/xui/ja/sidepanel_task_info.xml
+++ b/indra/newview/skins/default/xui/ja/sidepanel_task_info.xml
@@ -18,6 +18,12 @@
<panel.string name="text modify info 4">
ã“れらã®ã‚ªãƒ–ジェクトを修正ã§ãã¾ã›ã‚“
</panel.string>
+ <panel.string name="text modify info 5">
+ 地域(リージョン)ã®å¢ƒç•Œã‚’越ãˆã¦ã“ã®ã‚ªãƒ–ジェクトを修正ã§ãã¾ã›ã‚“
+ </panel.string>
+ <panel.string name="text modify info 6">
+ 地域(リージョン)ã®å¢ƒç•Œã‚’越ãˆã¦ã“れらã®ã‚ªãƒ–ジェクトを修正ã§ãã¾ã›ã‚“
+ </panel.string>
<panel.string name="text modify warning">
ã“ã®ã‚ªãƒ–ジェクトã«ã¯ã€ãƒ‘ーツãŒãƒªãƒ³ã‚¯ã•ã‚Œã¦ã„ã¾ã™
</panel.string>
@@ -66,6 +72,7 @@
<combo_box.item label="オブジェクトを買ã†" name="Buyobject"/>
<combo_box.item label="オブジェクトã«æ”¯æ‰•ã†" name="Payobject"/>
<combo_box.item label="é–‹ã" name="Open"/>
+ <combo_box.item label="ズーム" name="Zoom"/>
</combo_box>
<panel name="perms_inv">
<text name="perm_modify">
@@ -95,6 +102,9 @@
</combo_box>
<spinner label="価格: L$" name="Edit Cost"/>
<check_box label="検索ã«è¡¨ç¤º" name="search_check" tool_tip="ã“ã®ã‚ªãƒ–ジェクトを検索çµæžœã«è¡¨ç¤ºã—ã¾ã™"/>
+ <text name="pathfinding_attributes_label">
+ パスファインディング属性:
+ </text>
<text name="B:">
B.
</text>
diff --git a/indra/newview/skins/default/xui/ja/strings.xml b/indra/newview/skins/default/xui/ja/strings.xml
index 680ef60890..a0f45e5a55 100644..100755
--- a/indra/newview/skins/default/xui/ja/strings.xml
+++ b/indra/newview/skins/default/xui/ja/strings.xml
@@ -137,7 +137,10 @@
終了
</string>
<string name="create_account_url">
- http://join.secondlife.com/index.php?lang=ja-JP
+ http://join.secondlife.com/?sourceid=[sourceid]
+ </string>
+ <string name="ViewerDownloadURL">
+ http://secondlife.com/download
</string>
<string name="LoginFailedViewerNotPermitted">
ãŠä½¿ã„ã®å¤ã„ビューワã§ã¯ Second Life ã«ã‚¢ã‚¯ã‚»ã‚¹ã§ãã¾ã›ã‚“。以下ã®ãƒšãƒ¼ã‚¸ã‹ã‚‰æ–°ã—ã„ビューワをダウンロードã—ã¦ãã ã•ã„:
@@ -448,6 +451,9 @@ support@secondlife.com ã«ãŠå•ã„åˆã‚ã›ãã ã•ã„。
<string name="SLappAgentRequestFriend">
フレンド登録リクエスト
</string>
+ <string name="SLappAgentRemoveFriend">
+ フレンドã®å‰Šé™¤
+ </string>
<string name="BUTTON_CLOSE_DARWIN">
é–‰ã˜ã‚‹ (⌘W)
</string>
@@ -622,8 +628,8 @@ support@secondlife.com ã«ãŠå•ã„åˆã‚ã›ãã ã•ã„。
<string name="AvatarAway">
一時退席中
</string>
- <string name="AvatarBusy">
- å–ã‚Šè¾¼ã¿ä¸­
+ <string name="AvatarDoNotDisturb">
+ 通知をå—ã‘ãªã„
</string>
<string name="AvatarMuted">
ブロック中
@@ -838,6 +844,9 @@ support@secondlife.com ã«ãŠå•ã„åˆã‚ã›ãã ã•ã„。
<string name="multiple_textures">
複数
</string>
+ <string name="use_texture">
+ テクスãƒãƒ£ã‚’使用
+ </string>
<string name="texture_loading">
ローディング...
</string>
@@ -859,6 +868,12 @@ support@secondlife.com ã«ãŠå•ã„åˆã‚ã›ãã ã•ã„。
<string name="ST_NO_JOINT">
ROOT ã¾ãŸã¯ JOINT ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“
</string>
+ <string name="NearbyChatTitle">
+ è¿‘ãã®ãƒãƒ£ãƒƒãƒˆ
+ </string>
+ <string name="NearbyChatLabel">
+ (è¿‘ãã®ãƒãƒ£ãƒƒãƒˆ)
+ </string>
<string name="whisper">
ã®ã•ã•ã‚„ã:
</string>
@@ -886,6 +901,9 @@ support@secondlife.com ã«ãŠå•ã„åˆã‚ã›ãã ã•ã„。
<string name="ScriptQuestionCautionChatDenied">
[REGIONNAME] ã® [REGIONPOS] ã¨ã„ã†å ´æ‰€ã«ã‚ã‚‹ã€ã€Œ [OWNERNAME] ã€ãŒæ‰€æœ‰ã™ã‚‹ã€Œ [OBJECTNAME] ã€ã¨ã„ã†ã‚ªãƒ–ジェクトã¯ã€æ¬¡ã®æ¨©é™ã‚’æ‹’å¦ã—ã¾ã—ãŸï¼š [PERMISSIONS]
</string>
+ <string name="AdditionalPermissionsRequestHeader">
+ ã‚ãªãŸã®ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã¸ã®ã‚¢ã‚¯ã‚»ã‚¹ã‚’許å¯ã™ã‚‹ã¨ã€ã“ã®ã‚ªãƒ–ジェクトã«ã¯æ¬¡ã®æ“作も許å¯ã•ã‚Œã¾ã™ï¼š
+ </string>
<string name="ScriptTakeMoney">
リンデンドル(L$)を支払ã†
</string>
@@ -922,6 +940,27 @@ support@secondlife.com ã«ãŠå•ã„åˆã‚ã›ãã ã•ã„。
<string name="NotConnected">
接続ã•ã‚Œã¦ã„ã¾ã›ã‚“
</string>
+ <string name="AgentNameSubst">
+ (ã‚ãªãŸ)
+ </string>
+ <string name="TeleportYourAgent">
+ ã‚ãªãŸã‚’テレãƒãƒ¼ãƒˆ
+ </string>
+ <string name="JoinAnExperience">
+ 体験ã«å‚加ã™ã‚‹
+ </string>
+ <string name="SilentlyManageEstateAccess">
+ 土地ã®ã‚¢ã‚¯ã‚»ã‚¹ãƒªã‚¹ãƒˆã‚’管ç†ã™ã‚‹ã¨ãã«ã‚¢ãƒ©ãƒ¼ãƒˆã‚’表示ã—ãªã„
+ </string>
+ <string name="OverrideYourAnimations">
+ デフォルトã®ã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³ã‚’ç½®ãæ›ãˆ
+ </string>
+ <string name="ScriptReturnObjects">
+ ã‚ãªãŸã®ä»£ã‚ã‚Šã«ã‚ªãƒ–ジェクトを返å´
+ </string>
+ <string name="UnknownScriptPermission">
+ (ä¸æ˜Ž)!
+ </string>
<string name="SIM_ACCESS_PG">
General
</string>
@@ -1000,17 +1039,8 @@ support@secondlife.com ã«ãŠå•ã„åˆã‚ã›ãã ã•ã„。
<string name="script_files">
スクリプト
</string>
- <string name="AvatarSetNotAway">
- 一時退席中解除
- </string>
- <string name="AvatarSetAway">
- 一時退席中
- </string>
- <string name="AvatarSetNotBusy">
- å–ã‚Šè¾¼ã¿ä¸­è§£é™¤
- </string>
- <string name="AvatarSetBusy">
- å–ã‚Šè¾¼ã¿ä¸­
+ <string name="dictionary_files">
+ 辞書
</string>
<string name="shape">
シェイプ
@@ -1244,7 +1274,7 @@ support@secondlife.com ã«ãŠå•ã„åˆã‚ã›ãã ã•ã„。
https://marketplace.[MARKETPLACE_DOMAIN_NAME]/
</string>
<string name="MarketplaceURL_CreateStore">
- http://community.secondlife.com/t5/English-Knowledge-Base/Selling-in-the-Marketplace/ta-p/700193#Section_.4
+ http://community.secondlife.com/t5/English-Knowledge-Base/Selling-in-the-Marketplace/ta-p/700193#Section_.3
</string>
<string name="MarketplaceURL_Dashboard">
https://marketplace.[MARKETPLACE_DOMAIN_NAME]/merchants/store/dashboard
@@ -1405,6 +1435,12 @@ support@secondlife.com ã«ãŠå•ã„åˆã‚ã›ãã ã•ã„。
<string name="InvFolder favorite">
ãŠæ°—ã«å…¥ã‚Š
</string>
+ <string name="InvFolder Favorites">
+ ãŠæ°—ã«å…¥ã‚Š
+ </string>
+ <string name="InvFolder favorites">
+ ãŠæ°—ã«å…¥ã‚Š
+ </string>
<string name="InvFolder Current Outfit">
ç€ç”¨ä¸­ã®ã‚¢ã‚¦ãƒˆãƒ•ã‚£ãƒƒãƒˆ
</string>
@@ -1420,6 +1456,12 @@ support@secondlife.com ã«ãŠå•ã„åˆã‚ã›ãã ã•ã„。
<string name="InvFolder Meshes">
メッシュ
</string>
+ <string name="InvFolder Received Items">
+ å—ã‘å–ã£ãŸå•†å“
+ </string>
+ <string name="InvFolder Merchant Outbox">
+ マーãƒãƒ£ãƒ³ãƒˆã®ã‚¢ã‚¦ãƒˆãƒœãƒƒã‚¯ã‚¹
+ </string>
<string name="InvFolder Friends">
フレンド
</string>
@@ -1950,6 +1992,12 @@ support@secondlife.com ã«ãŠå•ã„åˆã‚ã›ãã ã•ã„。
<string name="ATTACH_HUD_BOTTOM_RIGHT">
HUD(å³ä¸‹ï¼‰
</string>
+ <string name="ATTACH_NECK">
+ 首
+ </string>
+ <string name="ATTACH_AVATAR_CENTER">
+ ã‚¢ãƒã‚¿ãƒ¼ã®ä¸­å¤®
+ </string>
<string name="CursorPos">
[LINE] 行目ã€[COLUMN] 列目
</string>
@@ -1968,8 +2016,8 @@ support@secondlife.com ã«ãŠå•ã„åˆã‚ã›ãã ã•ã„。
<string name="PanelContentsNewScript">
æ–°è¦ã‚¹ã‚¯ãƒªãƒ—ト
</string>
- <string name="BusyModeResponseDefault">
- メッセージをé€ã£ãŸä½äººã¯ã€èª°ã«ã‚‚邪魔をã•ã‚ŒãŸããªã„ãŸã‚ç¾åœ¨ã€Œå–ã‚Šè¾¼ã¿ä¸­ã€ãƒ¢ãƒ¼ãƒ‰ã§ã™ã€‚ ã‚ãªãŸã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã¯ã€ã‚ã¨ã§ç¢ºèªã§ãるよã†ã« IM パãƒãƒ«ã«è¡¨ç¤ºã•ã‚Œã¾ã™ã€‚
+ <string name="DoNotDisturbModeResponseDefault">
+ ã“ã®ä½æ°‘ãŒã€Œé€šçŸ¥ã‚’å—ã‘ãªã„ã€ã‚’オンã«ã™ã‚‹ã¨ã€ã‚ãªãŸã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ãŒå¾Œã§è¡¨ç¤ºã•ã‚Œã‚‹ã‚ˆã†ã«ãªã‚Šã¾ã™ã€‚
</string>
<string name="MuteByName">
(å称別)
@@ -2082,9 +2130,6 @@ support@secondlife.com ã«ãŠå•ã„åˆã‚ã›ãã ã•ã„。
<string name="GroupMoneyDate">
[year,datetime,utc]年[mth,datetime,utc]月[day,datetime,utc]日[weekday,datetime,utc]
</string>
- <string name="ViewerObjectContents">
- 内容
- </string>
<string name="AcquiredItems">
å–得アイテム
</string>
@@ -2982,6 +3027,9 @@ www.secondlife.com ã‹ã‚‰æœ€æ–°ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’ダウンロードã—ã¦ãã ã
<string name="Hip Width">
è…°ã®å¹…
</string>
+ <string name="Hover">
+ ホãƒãƒ¼
+ </string>
<string name="In">
内å‘ã
</string>
@@ -3856,7 +3904,13 @@ www.secondlife.com ã‹ã‚‰æœ€æ–°ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’ダウンロードã—ã¦ãã ã
General リージョン
</string>
<string name="LocationCtrlSeeAVsTooltip">
- ã“ã®åŒºç”»å¤–ã«ã‚¢ãƒã‚¿ãƒ¼ã‚’見ãˆã‚‹ã‚ˆã†ã«ã—ã¦ã€ãƒãƒ£ãƒƒãƒˆã‚‚許å¯
+ ã“ã®åŒºç”»å†…ã®ã‚¢ãƒã‚¿ãƒ¼ã¯ã€ã“ã®åŒºç”»ã®å¤–ã«ã„ã‚‹ã‚¢ãƒã‚¿ãƒ¼ã‹ã‚‰ã¯è¦‹ã‚‹ã“ã¨ã‚‚èžãã“ã¨ã‚‚ã§ãã¾ã›ã‚“。
+ </string>
+ <string name="LocationCtrlPathfindingDirtyTooltip">
+ 地域(リージョン)ãŒå†æ§‹ç¯‰ã•ã‚Œã‚‹ã¾ã§ã€ç§»å‹•ã™ã‚‹ã‚ªãƒ–ジェクトã¯æ­£ã—ã動作ã—ãªã„å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚
+ </string>
+ <string name="LocationCtrlPathfindingDisabledTooltip">
+ ã“ã®åœ°åŸŸï¼ˆãƒªãƒ¼ã‚¸ãƒ§ãƒ³ï¼‰ã§ãƒ€ã‚¤ãƒŠãƒŸãƒƒã‚¯ãƒ‘スファインディングãŒæœ‰åŠ¹ã«ãªã£ã¦ã„ã¾ã›ã‚“。
</string>
<string name="UpdaterWindowTitle">
[APP_NAME] アップデート
@@ -3927,6 +3981,12 @@ www.secondlife.com ã‹ã‚‰æœ€æ–°ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’ダウンロードã—ã¦ãã ã
<string name="IM_unblock_only_groups_friends">
ã“ã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’表示ã™ã‚‹ã«ã¯ã€ã€Œç’°å¢ƒè¨­å®šã€ã®ã€Œãƒ—ライãƒã‚·ãƒ¼ã€ã§ã€Œãƒ•ãƒ¬ãƒ³ãƒ‰ã¨ã‚°ãƒ«ãƒ¼ãƒ—以外ã‹ã‚‰ã¯ã‚³ãƒ¼ãƒ«ã¨ IM ã‚’å—ä¿¡ã—ãªã„ã€ãƒã‚§ãƒƒã‚¯ãƒœãƒƒã‚¯ã‚¹ã‚’オフã«ã—ã¾ã™ã€‚
</string>
+ <string name="OnlineStatus">
+ オンライン
+ </string>
+ <string name="OfflineStatus">
+ オフライン
+ </string>
<string name="answered_call">
相手ãŒã‚³ãƒ¼ãƒ«ã‚’å—ã‘ã¾ã—ãŸ
</string>
@@ -3936,6 +3996,9 @@ www.secondlife.com ã‹ã‚‰æœ€æ–°ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’ダウンロードã—ã¦ãã ã
<string name="you_joined_call">
ボイスコールã«å‚加ã—ã¾ã—ãŸ
</string>
+ <string name="you_auto_rejected_call-im">
+ 「通知をå—ã‘ãªã„ã€ãŒã‚ªãƒ³ã®ã¨ãã«ã€è‡ªå‹•çš„ã«ãƒœã‚¤ã‚¹ã‚³ãƒ¼ãƒ«ã‚’æ‹’å¦ã—ã¾ã—ãŸã€‚
+ </string>
<string name="name_started_call">
[NAME] ã¯ãƒœã‚¤ã‚¹ã‚³ãƒ¼ãƒ«ã‚’開始ã—ã¾ã™
</string>
@@ -3952,7 +4015,7 @@ www.secondlife.com ã‹ã‚‰æœ€æ–°ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’ダウンロードã—ã¦ãã ã
接続中...
</string>
<string name="conference-title">
- アドホックコンファレンス
+ 複数人ãƒãƒ£ãƒƒãƒˆ
</string>
<string name="conference-title-incoming">
[AGENT_NAME] ã¨ã‚³ãƒ³ãƒ•ã‚¡ãƒ¬ãƒ³ã‚¹ã™ã‚‹
@@ -4832,6 +4895,9 @@ www.secondlife.com ã‹ã‚‰æœ€æ–°ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’ダウンロードã—ã¦ãã ã
<string name="Command_Chat_Label">
ãƒãƒ£ãƒƒãƒˆ
</string>
+ <string name="Command_Conversations_Label">
+ 会話
+ </string>
<string name="Command_Compass_Label">
コンパス
</string>
@@ -4907,6 +4973,9 @@ www.secondlife.com ã‹ã‚‰æœ€æ–°ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’ダウンロードã—ã¦ãã ã
<string name="Command_Chat_Tooltip">
è¿‘ãã®äººã¨æ–‡å­—ãƒãƒ£ãƒƒãƒˆã™ã‚‹
</string>
+ <string name="Command_Conversations_Tooltip">
+ 全員ã¨ã®ä¼šè©±
+ </string>
<string name="Command_Compass_Tooltip">
コンパス
</string>
@@ -5000,6 +5069,21 @@ www.secondlife.com ã‹ã‚‰æœ€æ–°ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’ダウンロードã—ã¦ãã ã
<string name="Normal">
普通
</string>
+ <string name="Pathfinding_Wiki_URL">
+ http://wiki.secondlife.com/wiki/Pathfinding_Tools_in_the_Second_Life_Viewer
+ </string>
+ <string name="Pathfinding_Object_Attr_None">
+ ãªã—
+ </string>
+ <string name="Pathfinding_Object_Attr_Permanent">
+ ナビメッシュã«å½±éŸ¿ã‚’与ãˆã‚‹
+ </string>
+ <string name="Pathfinding_Object_Attr_Character">
+ キャラクター
+ </string>
+ <string name="Pathfinding_Object_Attr_MultiSelect">
+ (複数)
+ </string>
<string name="snapshot_quality_very_low">
éžå¸¸ã«ä½Žã„
</string>
@@ -5015,4 +5099,22 @@ www.secondlife.com ã‹ã‚‰æœ€æ–°ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’ダウンロードã—ã¦ãã ã
<string name="snapshot_quality_very_high">
éžå¸¸ã«é«˜ã„
</string>
+ <string name="TeleportMaturityExceeded">
+ ä½äººã¯ã“ã®åœ°åŸŸï¼ˆãƒªãƒ¼ã‚¸ãƒ§ãƒ³ï¼‰ã‚’訪å•ã§ãã¾ã›ã‚“。
+ </string>
+ <string name="UserDictionary">
+ [User]
+ </string>
+ <string name="logging_calls_disabled_log_empty">
+ 会話ã¯ãƒ­ã‚°ã«è¨˜éŒ²ã•ã‚Œã¦ã„ã¾ã›ã‚“。ログã®è¨˜éŒ²ã‚’開始ã™ã‚‹ã«ã¯ã€ã€Œç’°å¢ƒè¨­å®šã€&gt;「ãƒãƒ£ãƒƒãƒˆã€ã§ã€Œä¿å­˜: ログã®ã¿ã€ã¾ãŸã¯ã€Œä¿å­˜: ログã¨ä¼šè©±ã®ãƒ†ã‚­ã‚¹ãƒˆã€ã‚’é¸æŠžã—ã¾ã™ã€‚
+ </string>
+ <string name="logging_calls_disabled_log_not_empty">
+ ã“れ以上ã®ä¼šè©±ã¯è¨˜éŒ²ã•ã‚Œã¾ã›ã‚“。ログã®è¨˜éŒ²ã‚’å†é–‹ã™ã‚‹ã«ã¯ã€ã€Œç’°å¢ƒè¨­å®šã€&gt;「ãƒãƒ£ãƒƒãƒˆã€ã§ã€Œä¿å­˜: ログã®ã¿ã€ã¾ãŸã¯ã€Œä¿å­˜: ログã¨ä¼šè©±ã®ãƒ†ã‚­ã‚¹ãƒˆã€ã‚’é¸æŠžã—ã¾ã™ã€‚
+ </string>
+ <string name="logging_calls_enabled_log_empty">
+ ログイン時ã®ä¼šè©±ã¯ã‚ã‚Šã¾ã›ã‚“。誰ã‹ã«ã”連絡ã—ãŸå¾Œã€ã¾ãŸã¯èª°ã‹ãŒã‚ãªãŸã«é€£çµ¡ã—ãŸå¾Œã€ãƒ­ã‚°ã‚¨ãƒ³ãƒˆãƒªãŒã“ã“ã«è¡¨ç¤ºã•ã‚Œã¾ã™ã€‚
+ </string>
+ <string name="loading_chat_logs">
+ ロード中...
+ </string>
</strings>
diff --git a/indra/newview/skins/default/xui/ja/teleport_strings.xml b/indra/newview/skins/default/xui/ja/teleport_strings.xml
index 64f01f4030..7868c25807 100644..100755
--- a/indra/newview/skins/default/xui/ja/teleport_strings.xml
+++ b/indra/newview/skins/default/xui/ja/teleport_strings.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<teleport_messages>
<message_set name="errors">
<message name="invalid_tport">
@@ -47,6 +47,9 @@
<message name="no_inventory_host">
インベントリシステムã¯ç¾åœ¨åˆ©ç”¨ã§ãã¾ã›ã‚“。
</message>
+ <message name="MustGetAgeRegion">
+ ã“ã®åœ°åŸŸï¼ˆãƒªãƒ¼ã‚¸ãƒ§ãƒ³ï¼‰ã«å…¥ã‚‹ã«ã¯ 18 æ‰ä»¥ä¸Šã§ã‚ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚
+ </message>
</message_set>
<message_set name="progress">
<message name="sending_dest">
@@ -82,5 +85,8 @@
<message name="requesting">
テレãƒãƒ¼ãƒˆã‚’リクエスト...
</message>
+ <message name="pending">
+ テレãƒãƒ¼ãƒˆã‚’ä¿ç•™ä¸­...
+ </message>
</message_set>
</teleport_messages>
diff --git a/indra/newview/skins/default/xui/ja/xui_version.xml b/indra/newview/skins/default/xui/ja/xui_version.xml
index 0e777751d3..0e777751d3 100644..100755
--- a/indra/newview/skins/default/xui/ja/xui_version.xml
+++ b/indra/newview/skins/default/xui/ja/xui_version.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_about.xml b/indra/newview/skins/default/xui/pl/floater_about.xml
index 409429ffaa..61a72ff27d 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_about.xml
+++ b/indra/newview/skins/default/xui/pl/floater_about.xml
@@ -8,7 +8,7 @@
Buduj z [COMPILER] wersjÄ… [COMPILER_VERSION]
</floater.string>
<floater.string name="AboutPosition">
- Położenie [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1] w [REGION] zlokalizowanym w &lt;nolink&gt;[HOSTNAME]&lt;/nolink&gt; ([HOSTIP])
+ Położenie [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] w [REGION] zlokalizowanym w &lt;nolink&gt;[HOSTNAME]&lt;/nolink&gt; ([HOSTIP])
[SERVER_VERSION]
[SERVER_RELEASE_NOTES_URL]
</floater.string>
diff --git a/indra/newview/skins/default/xui/pl/floater_about_land.xml b/indra/newview/skins/default/xui/pl/floater_about_land.xml
index badff11a59..badff11a59 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/pl/floater_about_land.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_activeim.xml b/indra/newview/skins/default/xui/pl/floater_activeim.xml
index 2a34409f8b..2a34409f8b 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_activeim.xml
+++ b/indra/newview/skins/default/xui/pl/floater_activeim.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_animation_preview.xml b/indra/newview/skins/default/xui/pl/floater_animation_preview.xml
index 3402d8d31f..3402d8d31f 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_animation_preview.xml
+++ b/indra/newview/skins/default/xui/pl/floater_animation_preview.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_auction.xml b/indra/newview/skins/default/xui/pl/floater_auction.xml
index 9399fa1115..9399fa1115 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_auction.xml
+++ b/indra/newview/skins/default/xui/pl/floater_auction.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_avatar_picker.xml b/indra/newview/skins/default/xui/pl/floater_avatar_picker.xml
index da0e947683..da0e947683 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_avatar_picker.xml
+++ b/indra/newview/skins/default/xui/pl/floater_avatar_picker.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_avatar_textures.xml b/indra/newview/skins/default/xui/pl/floater_avatar_textures.xml
index 45b9e066e9..45b9e066e9 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_avatar_textures.xml
+++ b/indra/newview/skins/default/xui/pl/floater_avatar_textures.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_beacons.xml b/indra/newview/skins/default/xui/pl/floater_beacons.xml
index e6286a6ac1..e6286a6ac1 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_beacons.xml
+++ b/indra/newview/skins/default/xui/pl/floater_beacons.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_build_options.xml b/indra/newview/skins/default/xui/pl/floater_build_options.xml
index 5d296aa725..5d296aa725 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_build_options.xml
+++ b/indra/newview/skins/default/xui/pl/floater_build_options.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_bulk_perms.xml b/indra/newview/skins/default/xui/pl/floater_bulk_perms.xml
index 1c24e0b35e..1c24e0b35e 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_bulk_perms.xml
+++ b/indra/newview/skins/default/xui/pl/floater_bulk_perms.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_bumps.xml b/indra/newview/skins/default/xui/pl/floater_bumps.xml
index c1045ece9a..c1045ece9a 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_bumps.xml
+++ b/indra/newview/skins/default/xui/pl/floater_bumps.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_buy_contents.xml b/indra/newview/skins/default/xui/pl/floater_buy_contents.xml
index 94f2b50450..94f2b50450 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_buy_contents.xml
+++ b/indra/newview/skins/default/xui/pl/floater_buy_contents.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_buy_currency.xml b/indra/newview/skins/default/xui/pl/floater_buy_currency.xml
index 3e51761b37..3e51761b37 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_buy_currency.xml
+++ b/indra/newview/skins/default/xui/pl/floater_buy_currency.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_buy_currency_html.xml b/indra/newview/skins/default/xui/pl/floater_buy_currency_html.xml
index 36ac88f7f6..36ac88f7f6 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_buy_currency_html.xml
+++ b/indra/newview/skins/default/xui/pl/floater_buy_currency_html.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_buy_land.xml b/indra/newview/skins/default/xui/pl/floater_buy_land.xml
index 7b4f459b4e..7b4f459b4e 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_buy_land.xml
+++ b/indra/newview/skins/default/xui/pl/floater_buy_land.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_buy_object.xml b/indra/newview/skins/default/xui/pl/floater_buy_object.xml
index 85861d9e76..85861d9e76 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_buy_object.xml
+++ b/indra/newview/skins/default/xui/pl/floater_buy_object.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_camera.xml b/indra/newview/skins/default/xui/pl/floater_camera.xml
index 60f3cd0fff..60f3cd0fff 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_camera.xml
+++ b/indra/newview/skins/default/xui/pl/floater_camera.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_choose_group.xml b/indra/newview/skins/default/xui/pl/floater_choose_group.xml
index 877cedc0bc..877cedc0bc 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_choose_group.xml
+++ b/indra/newview/skins/default/xui/pl/floater_choose_group.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_color_picker.xml b/indra/newview/skins/default/xui/pl/floater_color_picker.xml
index a607ca982f..a607ca982f 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_color_picker.xml
+++ b/indra/newview/skins/default/xui/pl/floater_color_picker.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_critical.xml b/indra/newview/skins/default/xui/pl/floater_critical.xml
index 8221a4e1bd..8221a4e1bd 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_critical.xml
+++ b/indra/newview/skins/default/xui/pl/floater_critical.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_display_name.xml b/indra/newview/skins/default/xui/pl/floater_display_name.xml
index ea28e65728..ea28e65728 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_display_name.xml
+++ b/indra/newview/skins/default/xui/pl/floater_display_name.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_event.xml b/indra/newview/skins/default/xui/pl/floater_event.xml
index d278114969..d278114969 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_event.xml
+++ b/indra/newview/skins/default/xui/pl/floater_event.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_font_test.xml b/indra/newview/skins/default/xui/pl/floater_font_test.xml
index 019cee3e1e..019cee3e1e 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_font_test.xml
+++ b/indra/newview/skins/default/xui/pl/floater_font_test.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_gesture.xml b/indra/newview/skins/default/xui/pl/floater_gesture.xml
index 0c27e4d0bb..0c27e4d0bb 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_gesture.xml
+++ b/indra/newview/skins/default/xui/pl/floater_gesture.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_god_tools.xml b/indra/newview/skins/default/xui/pl/floater_god_tools.xml
index 828898de54..828898de54 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_god_tools.xml
+++ b/indra/newview/skins/default/xui/pl/floater_god_tools.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_hardware_settings.xml b/indra/newview/skins/default/xui/pl/floater_hardware_settings.xml
index 471d2c39ba..471d2c39ba 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_hardware_settings.xml
+++ b/indra/newview/skins/default/xui/pl/floater_hardware_settings.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_help_browser.xml b/indra/newview/skins/default/xui/pl/floater_help_browser.xml
index dfd5f907e5..dfd5f907e5 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_help_browser.xml
+++ b/indra/newview/skins/default/xui/pl/floater_help_browser.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_hud.xml b/indra/newview/skins/default/xui/pl/floater_hud.xml
index a5d85aca4e..a5d85aca4e 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_hud.xml
+++ b/indra/newview/skins/default/xui/pl/floater_hud.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_im_container.xml b/indra/newview/skins/default/xui/pl/floater_im_container.xml
index ddf0790fa8..ddf0790fa8 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_im_container.xml
+++ b/indra/newview/skins/default/xui/pl/floater_im_container.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_im_session.xml b/indra/newview/skins/default/xui/pl/floater_im_session.xml
index 9041ff7416..9041ff7416 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/pl/floater_im_session.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_image_preview.xml b/indra/newview/skins/default/xui/pl/floater_image_preview.xml
index ba9724ff9a..ba9724ff9a 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_image_preview.xml
+++ b/indra/newview/skins/default/xui/pl/floater_image_preview.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_incoming_call.xml b/indra/newview/skins/default/xui/pl/floater_incoming_call.xml
index b06b6d713d..b06b6d713d 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_incoming_call.xml
+++ b/indra/newview/skins/default/xui/pl/floater_incoming_call.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_inspect.xml b/indra/newview/skins/default/xui/pl/floater_inspect.xml
index 2c66f2851d..2c66f2851d 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_inspect.xml
+++ b/indra/newview/skins/default/xui/pl/floater_inspect.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_inventory.xml b/indra/newview/skins/default/xui/pl/floater_inventory.xml
index c42f57fb55..c42f57fb55 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_inventory.xml
+++ b/indra/newview/skins/default/xui/pl/floater_inventory.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_inventory_item_properties.xml b/indra/newview/skins/default/xui/pl/floater_inventory_item_properties.xml
index 054d74b234..054d74b234 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_inventory_item_properties.xml
+++ b/indra/newview/skins/default/xui/pl/floater_inventory_item_properties.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_inventory_view_finder.xml b/indra/newview/skins/default/xui/pl/floater_inventory_view_finder.xml
index bd7b221c5d..bd7b221c5d 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_inventory_view_finder.xml
+++ b/indra/newview/skins/default/xui/pl/floater_inventory_view_finder.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_joystick.xml b/indra/newview/skins/default/xui/pl/floater_joystick.xml
index 2b1e362b98..2b1e362b98 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_joystick.xml
+++ b/indra/newview/skins/default/xui/pl/floater_joystick.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_lagmeter.xml b/indra/newview/skins/default/xui/pl/floater_lagmeter.xml
index 8038550bcb..8038550bcb 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_lagmeter.xml
+++ b/indra/newview/skins/default/xui/pl/floater_lagmeter.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_land_holdings.xml b/indra/newview/skins/default/xui/pl/floater_land_holdings.xml
index 72a078949a..72a078949a 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_land_holdings.xml
+++ b/indra/newview/skins/default/xui/pl/floater_land_holdings.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_live_lsleditor.xml b/indra/newview/skins/default/xui/pl/floater_live_lsleditor.xml
index e03c5faaeb..e03c5faaeb 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_live_lsleditor.xml
+++ b/indra/newview/skins/default/xui/pl/floater_live_lsleditor.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_lsl_guide.xml b/indra/newview/skins/default/xui/pl/floater_lsl_guide.xml
index 7b1b395f87..7b1b395f87 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_lsl_guide.xml
+++ b/indra/newview/skins/default/xui/pl/floater_lsl_guide.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_map.xml b/indra/newview/skins/default/xui/pl/floater_map.xml
index e01c4c8a82..e01c4c8a82 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_map.xml
+++ b/indra/newview/skins/default/xui/pl/floater_map.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_media_browser.xml b/indra/newview/skins/default/xui/pl/floater_media_browser.xml
index 9787736ad8..9787736ad8 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_media_browser.xml
+++ b/indra/newview/skins/default/xui/pl/floater_media_browser.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_media_settings.xml b/indra/newview/skins/default/xui/pl/floater_media_settings.xml
index 5a36331c9a..5a36331c9a 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_media_settings.xml
+++ b/indra/newview/skins/default/xui/pl/floater_media_settings.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_mem_leaking.xml b/indra/newview/skins/default/xui/pl/floater_mem_leaking.xml
index 9ce99692d0..9ce99692d0 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_mem_leaking.xml
+++ b/indra/newview/skins/default/xui/pl/floater_mem_leaking.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_moveview.xml b/indra/newview/skins/default/xui/pl/floater_moveview.xml
index 592814dbc0..592814dbc0 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_moveview.xml
+++ b/indra/newview/skins/default/xui/pl/floater_moveview.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_mute_object.xml b/indra/newview/skins/default/xui/pl/floater_mute_object.xml
index 4af5872ef5..4af5872ef5 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_mute_object.xml
+++ b/indra/newview/skins/default/xui/pl/floater_mute_object.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_nearby_chat.xml b/indra/newview/skins/default/xui/pl/floater_nearby_chat.xml
index 214d465f1c..214d465f1c 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_nearby_chat.xml
+++ b/indra/newview/skins/default/xui/pl/floater_nearby_chat.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_openobject.xml b/indra/newview/skins/default/xui/pl/floater_openobject.xml
index 8e94ae821c..8e94ae821c 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_openobject.xml
+++ b/indra/newview/skins/default/xui/pl/floater_openobject.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_outgoing_call.xml b/indra/newview/skins/default/xui/pl/floater_outgoing_call.xml
index de0b4d08c0..de0b4d08c0 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_outgoing_call.xml
+++ b/indra/newview/skins/default/xui/pl/floater_outgoing_call.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_pay.xml b/indra/newview/skins/default/xui/pl/floater_pay.xml
index 38fe5286a4..38fe5286a4 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_pay.xml
+++ b/indra/newview/skins/default/xui/pl/floater_pay.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_pay_object.xml b/indra/newview/skins/default/xui/pl/floater_pay_object.xml
index bf88348c87..bf88348c87 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_pay_object.xml
+++ b/indra/newview/skins/default/xui/pl/floater_pay_object.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_perm_prefs.xml b/indra/newview/skins/default/xui/pl/floater_perm_prefs.xml
index 2128cfa3c8..2128cfa3c8 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_perm_prefs.xml
+++ b/indra/newview/skins/default/xui/pl/floater_perm_prefs.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_post_process.xml b/indra/newview/skins/default/xui/pl/floater_post_process.xml
index e3dce84933..e3dce84933 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_post_process.xml
+++ b/indra/newview/skins/default/xui/pl/floater_post_process.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_postcard.xml b/indra/newview/skins/default/xui/pl/floater_postcard.xml
index fe796c6fa0..fe796c6fa0 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_postcard.xml
+++ b/indra/newview/skins/default/xui/pl/floater_postcard.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_preferences.xml b/indra/newview/skins/default/xui/pl/floater_preferences.xml
index 930a5c76b0..930a5c76b0 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_preferences.xml
+++ b/indra/newview/skins/default/xui/pl/floater_preferences.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_preview_animation.xml b/indra/newview/skins/default/xui/pl/floater_preview_animation.xml
index d276b1f63a..d276b1f63a 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_preview_animation.xml
+++ b/indra/newview/skins/default/xui/pl/floater_preview_animation.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_preview_gesture.xml b/indra/newview/skins/default/xui/pl/floater_preview_gesture.xml
index 8171225666..8171225666 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_preview_gesture.xml
+++ b/indra/newview/skins/default/xui/pl/floater_preview_gesture.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_preview_notecard.xml b/indra/newview/skins/default/xui/pl/floater_preview_notecard.xml
index b3275cb7b5..b3275cb7b5 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_preview_notecard.xml
+++ b/indra/newview/skins/default/xui/pl/floater_preview_notecard.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_preview_sound.xml b/indra/newview/skins/default/xui/pl/floater_preview_sound.xml
index 3825fe742e..3825fe742e 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_preview_sound.xml
+++ b/indra/newview/skins/default/xui/pl/floater_preview_sound.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_preview_texture.xml b/indra/newview/skins/default/xui/pl/floater_preview_texture.xml
index e58acee139..e58acee139 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_preview_texture.xml
+++ b/indra/newview/skins/default/xui/pl/floater_preview_texture.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_publish_classified.xml b/indra/newview/skins/default/xui/pl/floater_publish_classified.xml
index cfdac165cd..cfdac165cd 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_publish_classified.xml
+++ b/indra/newview/skins/default/xui/pl/floater_publish_classified.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_region_debug_console.xml b/indra/newview/skins/default/xui/pl/floater_region_debug_console.xml
index ce1f3c0ac7..ce1f3c0ac7 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_region_debug_console.xml
+++ b/indra/newview/skins/default/xui/pl/floater_region_debug_console.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_region_info.xml b/indra/newview/skins/default/xui/pl/floater_region_info.xml
index a1f7785f48..a1f7785f48 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_region_info.xml
+++ b/indra/newview/skins/default/xui/pl/floater_region_info.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_report_abuse.xml b/indra/newview/skins/default/xui/pl/floater_report_abuse.xml
index a5b96601b8..a5b96601b8 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_report_abuse.xml
+++ b/indra/newview/skins/default/xui/pl/floater_report_abuse.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_script_debug.xml b/indra/newview/skins/default/xui/pl/floater_script_debug.xml
index 714a600262..714a600262 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_script_debug.xml
+++ b/indra/newview/skins/default/xui/pl/floater_script_debug.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_script_debug_panel.xml b/indra/newview/skins/default/xui/pl/floater_script_debug_panel.xml
index e70a30fa24..e70a30fa24 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_script_debug_panel.xml
+++ b/indra/newview/skins/default/xui/pl/floater_script_debug_panel.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_script_limits.xml b/indra/newview/skins/default/xui/pl/floater_script_limits.xml
index dd13d641a0..dd13d641a0 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_script_limits.xml
+++ b/indra/newview/skins/default/xui/pl/floater_script_limits.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_script_preview.xml b/indra/newview/skins/default/xui/pl/floater_script_preview.xml
index eb6a1df77b..eb6a1df77b 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_script_preview.xml
+++ b/indra/newview/skins/default/xui/pl/floater_script_preview.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_script_queue.xml b/indra/newview/skins/default/xui/pl/floater_script_queue.xml
index bdfdba569e..bdfdba569e 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_script_queue.xml
+++ b/indra/newview/skins/default/xui/pl/floater_script_queue.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_script_search.xml b/indra/newview/skins/default/xui/pl/floater_script_search.xml
index 901d61a137..901d61a137 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_script_search.xml
+++ b/indra/newview/skins/default/xui/pl/floater_script_search.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_search.xml b/indra/newview/skins/default/xui/pl/floater_search.xml
index a0198670e4..a0198670e4 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_search.xml
+++ b/indra/newview/skins/default/xui/pl/floater_search.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_select_key.xml b/indra/newview/skins/default/xui/pl/floater_select_key.xml
index 190ad61352..190ad61352 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_select_key.xml
+++ b/indra/newview/skins/default/xui/pl/floater_select_key.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_sell_land.xml b/indra/newview/skins/default/xui/pl/floater_sell_land.xml
index 2201c4b0ad..2201c4b0ad 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_sell_land.xml
+++ b/indra/newview/skins/default/xui/pl/floater_sell_land.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_settings_debug.xml b/indra/newview/skins/default/xui/pl/floater_settings_debug.xml
index 131f92d56f..131f92d56f 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_settings_debug.xml
+++ b/indra/newview/skins/default/xui/pl/floater_settings_debug.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_snapshot.xml b/indra/newview/skins/default/xui/pl/floater_snapshot.xml
index be92ef917d..be92ef917d 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_snapshot.xml
+++ b/indra/newview/skins/default/xui/pl/floater_snapshot.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_sound_preview.xml b/indra/newview/skins/default/xui/pl/floater_sound_preview.xml
index ac041dff6a..ac041dff6a 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_sound_preview.xml
+++ b/indra/newview/skins/default/xui/pl/floater_sound_preview.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_stats.xml b/indra/newview/skins/default/xui/pl/floater_stats.xml
index 886a30e5d9..886a30e5d9 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_stats.xml
+++ b/indra/newview/skins/default/xui/pl/floater_stats.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_sys_well.xml b/indra/newview/skins/default/xui/pl/floater_sys_well.xml
index e6c73af4f3..e6c73af4f3 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_sys_well.xml
+++ b/indra/newview/skins/default/xui/pl/floater_sys_well.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_telehub.xml b/indra/newview/skins/default/xui/pl/floater_telehub.xml
index 32cc08810d..32cc08810d 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_telehub.xml
+++ b/indra/newview/skins/default/xui/pl/floater_telehub.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/pl/floater_texture_ctrl.xml
index 52c0cb8a93..52c0cb8a93 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_texture_ctrl.xml
+++ b/indra/newview/skins/default/xui/pl/floater_texture_ctrl.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_tools.xml b/indra/newview/skins/default/xui/pl/floater_tools.xml
index 9e6fed8387..69d5c23f9c 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_tools.xml
+++ b/indra/newview/skins/default/xui/pl/floater_tools.xml
@@ -442,16 +442,11 @@
<combo_box.item label="Suction" name="suction"/>
<combo_box.item label="Fali" name="weave"/>
</combo_box>
- <check_box initial_value="nieprawda" label="Połącz powierzchnie planarne" name="checkbox planar align" tool_tip="Połącz tekstury na wszystkich wybranych powierzchniach z powierzchnią wybraną jako ostatnia. Wymaga planarnego mapowania tekstury."/>
- <text name="rpt">
- Powtórzenia / Powierzchnia
- </text>
<spinner label="Poziomo (U)" name="TexScaleU"/>
<check_box label="Odwróć" name="checkbox flip s"/>
<spinner label="Pionowo (V)" name="TexScaleV"/>
<check_box label="Odwróć" name="checkbox flip t"/>
<spinner label="Powtórzenia˚" name="TexRot"/>
- <spinner label="Powtórzenia / metr" name="rptctrl"/>
<button label="Zastosuj" label_selected="Zastosuj" name="button apply"/>
<text name="tex offset">
Wyrównanie tekstury
diff --git a/indra/newview/skins/default/xui/pl/floater_top_objects.xml b/indra/newview/skins/default/xui/pl/floater_top_objects.xml
index 2b06ae9f78..2b06ae9f78 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_top_objects.xml
+++ b/indra/newview/skins/default/xui/pl/floater_top_objects.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_tos.xml b/indra/newview/skins/default/xui/pl/floater_tos.xml
index 8cdf267f4b..8cdf267f4b 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_tos.xml
+++ b/indra/newview/skins/default/xui/pl/floater_tos.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_url_entry.xml b/indra/newview/skins/default/xui/pl/floater_url_entry.xml
index fc170d8d1b..fc170d8d1b 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_url_entry.xml
+++ b/indra/newview/skins/default/xui/pl/floater_url_entry.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_voice_controls.xml b/indra/newview/skins/default/xui/pl/floater_voice_controls.xml
index 2155d56f27..2155d56f27 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_voice_controls.xml
+++ b/indra/newview/skins/default/xui/pl/floater_voice_controls.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_voice_effect.xml b/indra/newview/skins/default/xui/pl/floater_voice_effect.xml
index e2d1fb77e9..e2d1fb77e9 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_voice_effect.xml
+++ b/indra/newview/skins/default/xui/pl/floater_voice_effect.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_web_content.xml b/indra/newview/skins/default/xui/pl/floater_web_content.xml
index 4cc8d0b27b..4cc8d0b27b 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_web_content.xml
+++ b/indra/newview/skins/default/xui/pl/floater_web_content.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_whitelist_entry.xml b/indra/newview/skins/default/xui/pl/floater_whitelist_entry.xml
index 4081b8a37e..4081b8a37e 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_whitelist_entry.xml
+++ b/indra/newview/skins/default/xui/pl/floater_whitelist_entry.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_window_size.xml b/indra/newview/skins/default/xui/pl/floater_window_size.xml
index 2a6c257e54..2a6c257e54 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_window_size.xml
+++ b/indra/newview/skins/default/xui/pl/floater_window_size.xml
diff --git a/indra/newview/skins/default/xui/pl/floater_world_map.xml b/indra/newview/skins/default/xui/pl/floater_world_map.xml
index 4f53337365..4f53337365 100644..100755
--- a/indra/newview/skins/default/xui/pl/floater_world_map.xml
+++ b/indra/newview/skins/default/xui/pl/floater_world_map.xml
diff --git a/indra/newview/skins/default/xui/pl/inspect_avatar.xml b/indra/newview/skins/default/xui/pl/inspect_avatar.xml
index 5e982c0185..5e982c0185 100644..100755
--- a/indra/newview/skins/default/xui/pl/inspect_avatar.xml
+++ b/indra/newview/skins/default/xui/pl/inspect_avatar.xml
diff --git a/indra/newview/skins/default/xui/pl/inspect_group.xml b/indra/newview/skins/default/xui/pl/inspect_group.xml
index 63c79acc8c..63c79acc8c 100644..100755
--- a/indra/newview/skins/default/xui/pl/inspect_group.xml
+++ b/indra/newview/skins/default/xui/pl/inspect_group.xml
diff --git a/indra/newview/skins/default/xui/pl/inspect_object.xml b/indra/newview/skins/default/xui/pl/inspect_object.xml
index 23d8ce7700..23d8ce7700 100644..100755
--- a/indra/newview/skins/default/xui/pl/inspect_object.xml
+++ b/indra/newview/skins/default/xui/pl/inspect_object.xml
diff --git a/indra/newview/skins/default/xui/pl/inspect_remote_object.xml b/indra/newview/skins/default/xui/pl/inspect_remote_object.xml
index 0d570940c1..0d570940c1 100644..100755
--- a/indra/newview/skins/default/xui/pl/inspect_remote_object.xml
+++ b/indra/newview/skins/default/xui/pl/inspect_remote_object.xml
diff --git a/indra/newview/skins/default/xui/pl/language_settings.xml b/indra/newview/skins/default/xui/pl/language_settings.xml
index 93051d1317..93051d1317 100644..100755
--- a/indra/newview/skins/default/xui/pl/language_settings.xml
+++ b/indra/newview/skins/default/xui/pl/language_settings.xml
diff --git a/indra/newview/skins/default/xui/pl/menu_add_wearable_gear.xml b/indra/newview/skins/default/xui/pl/menu_add_wearable_gear.xml
index 7c572b4fc9..7c572b4fc9 100644..100755
--- a/indra/newview/skins/default/xui/pl/menu_add_wearable_gear.xml
+++ b/indra/newview/skins/default/xui/pl/menu_add_wearable_gear.xml
diff --git a/indra/newview/skins/default/xui/pl/menu_attachment_other.xml b/indra/newview/skins/default/xui/pl/menu_attachment_other.xml
index aacdad97e3..aacdad97e3 100644..100755
--- a/indra/newview/skins/default/xui/pl/menu_attachment_other.xml
+++ b/indra/newview/skins/default/xui/pl/menu_attachment_other.xml
diff --git a/indra/newview/skins/default/xui/pl/menu_attachment_self.xml b/indra/newview/skins/default/xui/pl/menu_attachment_self.xml
index 163b3a231e..163b3a231e 100644..100755
--- a/indra/newview/skins/default/xui/pl/menu_attachment_self.xml
+++ b/indra/newview/skins/default/xui/pl/menu_attachment_self.xml
diff --git a/indra/newview/skins/default/xui/pl/menu_avatar_icon.xml b/indra/newview/skins/default/xui/pl/menu_avatar_icon.xml
index e8d2b14231..e8d2b14231 100644..100755
--- a/indra/newview/skins/default/xui/pl/menu_avatar_icon.xml
+++ b/indra/newview/skins/default/xui/pl/menu_avatar_icon.xml
diff --git a/indra/newview/skins/default/xui/pl/menu_avatar_other.xml b/indra/newview/skins/default/xui/pl/menu_avatar_other.xml
index dcf7921bad..dcf7921bad 100644..100755
--- a/indra/newview/skins/default/xui/pl/menu_avatar_other.xml
+++ b/indra/newview/skins/default/xui/pl/menu_avatar_other.xml
diff --git a/indra/newview/skins/default/xui/pl/menu_avatar_self.xml b/indra/newview/skins/default/xui/pl/menu_avatar_self.xml
index 8eb501c5b8..8eb501c5b8 100644..100755
--- a/indra/newview/skins/default/xui/pl/menu_avatar_self.xml
+++ b/indra/newview/skins/default/xui/pl/menu_avatar_self.xml
diff --git a/indra/newview/skins/default/xui/pl/menu_bottomtray.xml b/indra/newview/skins/default/xui/pl/menu_bottomtray.xml
index 1ec5883cfe..1ec5883cfe 100644..100755
--- a/indra/newview/skins/default/xui/pl/menu_bottomtray.xml
+++ b/indra/newview/skins/default/xui/pl/menu_bottomtray.xml
diff --git a/indra/newview/skins/default/xui/pl/menu_cof_attachment.xml b/indra/newview/skins/default/xui/pl/menu_cof_attachment.xml
index 4e5407601b..4e5407601b 100644..100755
--- a/indra/newview/skins/default/xui/pl/menu_cof_attachment.xml
+++ b/indra/newview/skins/default/xui/pl/menu_cof_attachment.xml
diff --git a/indra/newview/skins/default/xui/pl/menu_cof_body_part.xml b/indra/newview/skins/default/xui/pl/menu_cof_body_part.xml
index ee60d3feb6..ee60d3feb6 100644..100755
--- a/indra/newview/skins/default/xui/pl/menu_cof_body_part.xml
+++ b/indra/newview/skins/default/xui/pl/menu_cof_body_part.xml
diff --git a/indra/newview/skins/default/xui/pl/menu_cof_clothing.xml b/indra/newview/skins/default/xui/pl/menu_cof_clothing.xml
index ad43900137..ad43900137 100644..100755
--- a/indra/newview/skins/default/xui/pl/menu_cof_clothing.xml
+++ b/indra/newview/skins/default/xui/pl/menu_cof_clothing.xml
diff --git a/indra/newview/skins/default/xui/pl/menu_cof_gear.xml b/indra/newview/skins/default/xui/pl/menu_cof_gear.xml
index 9fba39be1a..9fba39be1a 100644..100755
--- a/indra/newview/skins/default/xui/pl/menu_cof_gear.xml
+++ b/indra/newview/skins/default/xui/pl/menu_cof_gear.xml
diff --git a/indra/newview/skins/default/xui/pl/menu_edit.xml b/indra/newview/skins/default/xui/pl/menu_edit.xml
index 578e270fed..578e270fed 100644..100755
--- a/indra/newview/skins/default/xui/pl/menu_edit.xml
+++ b/indra/newview/skins/default/xui/pl/menu_edit.xml
diff --git a/indra/newview/skins/default/xui/pl/menu_favorites.xml b/indra/newview/skins/default/xui/pl/menu_favorites.xml
index 7310ff5c27..7310ff5c27 100644..100755
--- a/indra/newview/skins/default/xui/pl/menu_favorites.xml
+++ b/indra/newview/skins/default/xui/pl/menu_favorites.xml
diff --git a/indra/newview/skins/default/xui/pl/menu_gesture_gear.xml b/indra/newview/skins/default/xui/pl/menu_gesture_gear.xml
index a72dec22fc..a72dec22fc 100644..100755
--- a/indra/newview/skins/default/xui/pl/menu_gesture_gear.xml
+++ b/indra/newview/skins/default/xui/pl/menu_gesture_gear.xml
diff --git a/indra/newview/skins/default/xui/pl/menu_group_plus.xml b/indra/newview/skins/default/xui/pl/menu_group_plus.xml
index 83be4d38c5..83be4d38c5 100644..100755
--- a/indra/newview/skins/default/xui/pl/menu_group_plus.xml
+++ b/indra/newview/skins/default/xui/pl/menu_group_plus.xml
diff --git a/indra/newview/skins/default/xui/pl/menu_hide_navbar.xml b/indra/newview/skins/default/xui/pl/menu_hide_navbar.xml
index 19d9510cd3..19d9510cd3 100644..100755
--- a/indra/newview/skins/default/xui/pl/menu_hide_navbar.xml
+++ b/indra/newview/skins/default/xui/pl/menu_hide_navbar.xml
diff --git a/indra/newview/skins/default/xui/pl/menu_im_well_button.xml b/indra/newview/skins/default/xui/pl/menu_im_well_button.xml
deleted file mode 100644
index 207bc2211b..0000000000
--- a/indra/newview/skins/default/xui/pl/menu_im_well_button.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<context_menu name="IM Well Button Context Menu">
- <menu_item_call label="Zamknij wszystkie" name="Close All"/>
-</context_menu>
diff --git a/indra/newview/skins/default/xui/pl/menu_imchiclet_adhoc.xml b/indra/newview/skins/default/xui/pl/menu_imchiclet_adhoc.xml
index 4ead44878a..4ead44878a 100644..100755
--- a/indra/newview/skins/default/xui/pl/menu_imchiclet_adhoc.xml
+++ b/indra/newview/skins/default/xui/pl/menu_imchiclet_adhoc.xml
diff --git a/indra/newview/skins/default/xui/pl/menu_imchiclet_group.xml b/indra/newview/skins/default/xui/pl/menu_imchiclet_group.xml
index 2b9a362123..2b9a362123 100644..100755
--- a/indra/newview/skins/default/xui/pl/menu_imchiclet_group.xml
+++ b/indra/newview/skins/default/xui/pl/menu_imchiclet_group.xml
diff --git a/indra/newview/skins/default/xui/pl/menu_imchiclet_p2p.xml b/indra/newview/skins/default/xui/pl/menu_imchiclet_p2p.xml
index 8924d6db3e..8924d6db3e 100644..100755
--- a/indra/newview/skins/default/xui/pl/menu_imchiclet_p2p.xml
+++ b/indra/newview/skins/default/xui/pl/menu_imchiclet_p2p.xml
diff --git a/indra/newview/skins/default/xui/pl/menu_inspect_avatar_gear.xml b/indra/newview/skins/default/xui/pl/menu_inspect_avatar_gear.xml
index 59560f236c..59560f236c 100644..100755
--- a/indra/newview/skins/default/xui/pl/menu_inspect_avatar_gear.xml
+++ b/indra/newview/skins/default/xui/pl/menu_inspect_avatar_gear.xml
diff --git a/indra/newview/skins/default/xui/pl/menu_inspect_object_gear.xml b/indra/newview/skins/default/xui/pl/menu_inspect_object_gear.xml
index c12bd490ff..c12bd490ff 100644..100755
--- a/indra/newview/skins/default/xui/pl/menu_inspect_object_gear.xml
+++ b/indra/newview/skins/default/xui/pl/menu_inspect_object_gear.xml
diff --git a/indra/newview/skins/default/xui/pl/menu_inspect_self_gear.xml b/indra/newview/skins/default/xui/pl/menu_inspect_self_gear.xml
index c4ef9761d9..c4ef9761d9 100644..100755
--- a/indra/newview/skins/default/xui/pl/menu_inspect_self_gear.xml
+++ b/indra/newview/skins/default/xui/pl/menu_inspect_self_gear.xml
diff --git a/indra/newview/skins/default/xui/pl/menu_inv_offer_chiclet.xml b/indra/newview/skins/default/xui/pl/menu_inv_offer_chiclet.xml
index 5ef0f2f7a4..5ef0f2f7a4 100644..100755
--- a/indra/newview/skins/default/xui/pl/menu_inv_offer_chiclet.xml
+++ b/indra/newview/skins/default/xui/pl/menu_inv_offer_chiclet.xml
diff --git a/indra/newview/skins/default/xui/pl/menu_inventory.xml b/indra/newview/skins/default/xui/pl/menu_inventory.xml
index 5492f78b26..5492f78b26 100644..100755
--- a/indra/newview/skins/default/xui/pl/menu_inventory.xml
+++ b/indra/newview/skins/default/xui/pl/menu_inventory.xml
diff --git a/indra/newview/skins/default/xui/pl/menu_inventory_add.xml b/indra/newview/skins/default/xui/pl/menu_inventory_add.xml
index 04f9b94f7c..04f9b94f7c 100644..100755
--- a/indra/newview/skins/default/xui/pl/menu_inventory_add.xml
+++ b/indra/newview/skins/default/xui/pl/menu_inventory_add.xml
diff --git a/indra/newview/skins/default/xui/pl/menu_inventory_gear_default.xml b/indra/newview/skins/default/xui/pl/menu_inventory_gear_default.xml
index 591c3a81d5..591c3a81d5 100644..100755
--- a/indra/newview/skins/default/xui/pl/menu_inventory_gear_default.xml
+++ b/indra/newview/skins/default/xui/pl/menu_inventory_gear_default.xml
diff --git a/indra/newview/skins/default/xui/pl/menu_land.xml b/indra/newview/skins/default/xui/pl/menu_land.xml
index cbfecaee56..cbfecaee56 100644..100755
--- a/indra/newview/skins/default/xui/pl/menu_land.xml
+++ b/indra/newview/skins/default/xui/pl/menu_land.xml
diff --git a/indra/newview/skins/default/xui/pl/menu_landmark.xml b/indra/newview/skins/default/xui/pl/menu_landmark.xml
index aa5808390c..aa5808390c 100644..100755
--- a/indra/newview/skins/default/xui/pl/menu_landmark.xml
+++ b/indra/newview/skins/default/xui/pl/menu_landmark.xml
diff --git a/indra/newview/skins/default/xui/pl/menu_login.xml b/indra/newview/skins/default/xui/pl/menu_login.xml
index e50b694641..e50b694641 100644..100755
--- a/indra/newview/skins/default/xui/pl/menu_login.xml
+++ b/indra/newview/skins/default/xui/pl/menu_login.xml
diff --git a/indra/newview/skins/default/xui/pl/menu_media_ctrl.xml b/indra/newview/skins/default/xui/pl/menu_media_ctrl.xml
index 60dc3673a9..60dc3673a9 100644..100755
--- a/indra/newview/skins/default/xui/pl/menu_media_ctrl.xml
+++ b/indra/newview/skins/default/xui/pl/menu_media_ctrl.xml
diff --git a/indra/newview/skins/default/xui/pl/menu_mini_map.xml b/indra/newview/skins/default/xui/pl/menu_mini_map.xml
index 8f86965416..8f86965416 100644..100755
--- a/indra/newview/skins/default/xui/pl/menu_mini_map.xml
+++ b/indra/newview/skins/default/xui/pl/menu_mini_map.xml
diff --git a/indra/newview/skins/default/xui/pl/menu_navbar.xml b/indra/newview/skins/default/xui/pl/menu_navbar.xml
index 1d434670ee..1d434670ee 100644..100755
--- a/indra/newview/skins/default/xui/pl/menu_navbar.xml
+++ b/indra/newview/skins/default/xui/pl/menu_navbar.xml
diff --git a/indra/newview/skins/default/xui/pl/menu_nearby_chat.xml b/indra/newview/skins/default/xui/pl/menu_nearby_chat.xml
index fe5bc6ba6f..fe5bc6ba6f 100644..100755
--- a/indra/newview/skins/default/xui/pl/menu_nearby_chat.xml
+++ b/indra/newview/skins/default/xui/pl/menu_nearby_chat.xml
diff --git a/indra/newview/skins/default/xui/pl/menu_notification_well_button.xml b/indra/newview/skins/default/xui/pl/menu_notification_well_button.xml
index bd3d42f9b1..bd3d42f9b1 100644..100755
--- a/indra/newview/skins/default/xui/pl/menu_notification_well_button.xml
+++ b/indra/newview/skins/default/xui/pl/menu_notification_well_button.xml
diff --git a/indra/newview/skins/default/xui/pl/menu_object.xml b/indra/newview/skins/default/xui/pl/menu_object.xml
index 3da6c5c890..3da6c5c890 100644..100755
--- a/indra/newview/skins/default/xui/pl/menu_object.xml
+++ b/indra/newview/skins/default/xui/pl/menu_object.xml
diff --git a/indra/newview/skins/default/xui/pl/menu_object_icon.xml b/indra/newview/skins/default/xui/pl/menu_object_icon.xml
index b499bca2db..b499bca2db 100644..100755
--- a/indra/newview/skins/default/xui/pl/menu_object_icon.xml
+++ b/indra/newview/skins/default/xui/pl/menu_object_icon.xml
diff --git a/indra/newview/skins/default/xui/pl/menu_outfit_gear.xml b/indra/newview/skins/default/xui/pl/menu_outfit_gear.xml
index c093557e86..c093557e86 100644..100755
--- a/indra/newview/skins/default/xui/pl/menu_outfit_gear.xml
+++ b/indra/newview/skins/default/xui/pl/menu_outfit_gear.xml
diff --git a/indra/newview/skins/default/xui/pl/menu_outfit_tab.xml b/indra/newview/skins/default/xui/pl/menu_outfit_tab.xml
index 998e25f38e..998e25f38e 100644..100755
--- a/indra/newview/skins/default/xui/pl/menu_outfit_tab.xml
+++ b/indra/newview/skins/default/xui/pl/menu_outfit_tab.xml
diff --git a/indra/newview/skins/default/xui/pl/menu_participant_list.xml b/indra/newview/skins/default/xui/pl/menu_participant_list.xml
index 9e59102788..9e59102788 100644..100755
--- a/indra/newview/skins/default/xui/pl/menu_participant_list.xml
+++ b/indra/newview/skins/default/xui/pl/menu_participant_list.xml
diff --git a/indra/newview/skins/default/xui/pl/menu_people_friends_view_sort.xml b/indra/newview/skins/default/xui/pl/menu_people_friends_view_sort.xml
index b62b85d30a..b62b85d30a 100644..100755
--- a/indra/newview/skins/default/xui/pl/menu_people_friends_view_sort.xml
+++ b/indra/newview/skins/default/xui/pl/menu_people_friends_view_sort.xml
diff --git a/indra/newview/skins/default/xui/pl/menu_people_groups.xml b/indra/newview/skins/default/xui/pl/menu_people_groups.xml
index ace5ebf888..ace5ebf888 100644..100755
--- a/indra/newview/skins/default/xui/pl/menu_people_groups.xml
+++ b/indra/newview/skins/default/xui/pl/menu_people_groups.xml
diff --git a/indra/newview/skins/default/xui/pl/menu_people_groups_view_sort.xml b/indra/newview/skins/default/xui/pl/menu_people_groups_view_sort.xml
index c70ea2315f..c70ea2315f 100644..100755
--- a/indra/newview/skins/default/xui/pl/menu_people_groups_view_sort.xml
+++ b/indra/newview/skins/default/xui/pl/menu_people_groups_view_sort.xml
diff --git a/indra/newview/skins/default/xui/pl/menu_people_nearby.xml b/indra/newview/skins/default/xui/pl/menu_people_nearby.xml
index a8cc6b4a60..a8cc6b4a60 100644..100755
--- a/indra/newview/skins/default/xui/pl/menu_people_nearby.xml
+++ b/indra/newview/skins/default/xui/pl/menu_people_nearby.xml
diff --git a/indra/newview/skins/default/xui/pl/menu_people_nearby_multiselect.xml b/indra/newview/skins/default/xui/pl/menu_people_nearby_multiselect.xml
index dcfc48fb60..dcfc48fb60 100644..100755
--- a/indra/newview/skins/default/xui/pl/menu_people_nearby_multiselect.xml
+++ b/indra/newview/skins/default/xui/pl/menu_people_nearby_multiselect.xml
diff --git a/indra/newview/skins/default/xui/pl/menu_people_nearby_view_sort.xml b/indra/newview/skins/default/xui/pl/menu_people_nearby_view_sort.xml
index 8ec3820f84..8ec3820f84 100644..100755
--- a/indra/newview/skins/default/xui/pl/menu_people_nearby_view_sort.xml
+++ b/indra/newview/skins/default/xui/pl/menu_people_nearby_view_sort.xml
diff --git a/indra/newview/skins/default/xui/pl/menu_people_recent_view_sort.xml b/indra/newview/skins/default/xui/pl/menu_people_recent_view_sort.xml
index b474a556bd..b474a556bd 100644..100755
--- a/indra/newview/skins/default/xui/pl/menu_people_recent_view_sort.xml
+++ b/indra/newview/skins/default/xui/pl/menu_people_recent_view_sort.xml
diff --git a/indra/newview/skins/default/xui/pl/menu_picks.xml b/indra/newview/skins/default/xui/pl/menu_picks.xml
index 6f6e4b7fa8..6f6e4b7fa8 100644..100755
--- a/indra/newview/skins/default/xui/pl/menu_picks.xml
+++ b/indra/newview/skins/default/xui/pl/menu_picks.xml
diff --git a/indra/newview/skins/default/xui/pl/menu_picks_plus.xml b/indra/newview/skins/default/xui/pl/menu_picks_plus.xml
index e9c00f51a9..e9c00f51a9 100644..100755
--- a/indra/newview/skins/default/xui/pl/menu_picks_plus.xml
+++ b/indra/newview/skins/default/xui/pl/menu_picks_plus.xml
diff --git a/indra/newview/skins/default/xui/pl/menu_place.xml b/indra/newview/skins/default/xui/pl/menu_place.xml
index c3b72d6abb..c3b72d6abb 100644..100755
--- a/indra/newview/skins/default/xui/pl/menu_place.xml
+++ b/indra/newview/skins/default/xui/pl/menu_place.xml
diff --git a/indra/newview/skins/default/xui/pl/menu_place_add_button.xml b/indra/newview/skins/default/xui/pl/menu_place_add_button.xml
index 3d0c1c87fb..3d0c1c87fb 100644..100755
--- a/indra/newview/skins/default/xui/pl/menu_place_add_button.xml
+++ b/indra/newview/skins/default/xui/pl/menu_place_add_button.xml
diff --git a/indra/newview/skins/default/xui/pl/menu_places_gear_folder.xml b/indra/newview/skins/default/xui/pl/menu_places_gear_folder.xml
index d1f283b7aa..d1f283b7aa 100644..100755
--- a/indra/newview/skins/default/xui/pl/menu_places_gear_folder.xml
+++ b/indra/newview/skins/default/xui/pl/menu_places_gear_folder.xml
diff --git a/indra/newview/skins/default/xui/pl/menu_places_gear_landmark.xml b/indra/newview/skins/default/xui/pl/menu_places_gear_landmark.xml
index 0139d3a987..0139d3a987 100644..100755
--- a/indra/newview/skins/default/xui/pl/menu_places_gear_landmark.xml
+++ b/indra/newview/skins/default/xui/pl/menu_places_gear_landmark.xml
diff --git a/indra/newview/skins/default/xui/pl/menu_profile_overflow.xml b/indra/newview/skins/default/xui/pl/menu_profile_overflow.xml
index ef836c8ecf..ef836c8ecf 100644..100755
--- a/indra/newview/skins/default/xui/pl/menu_profile_overflow.xml
+++ b/indra/newview/skins/default/xui/pl/menu_profile_overflow.xml
diff --git a/indra/newview/skins/default/xui/pl/menu_save_outfit.xml b/indra/newview/skins/default/xui/pl/menu_save_outfit.xml
index 4bc65eca38..4bc65eca38 100644..100755
--- a/indra/newview/skins/default/xui/pl/menu_save_outfit.xml
+++ b/indra/newview/skins/default/xui/pl/menu_save_outfit.xml
diff --git a/indra/newview/skins/default/xui/pl/menu_script_chiclet.xml b/indra/newview/skins/default/xui/pl/menu_script_chiclet.xml
index 256500a402..256500a402 100644..100755
--- a/indra/newview/skins/default/xui/pl/menu_script_chiclet.xml
+++ b/indra/newview/skins/default/xui/pl/menu_script_chiclet.xml
diff --git a/indra/newview/skins/default/xui/pl/menu_slurl.xml b/indra/newview/skins/default/xui/pl/menu_slurl.xml
index 862f538aa7..862f538aa7 100644..100755
--- a/indra/newview/skins/default/xui/pl/menu_slurl.xml
+++ b/indra/newview/skins/default/xui/pl/menu_slurl.xml
diff --git a/indra/newview/skins/default/xui/pl/menu_teleport_history_gear.xml b/indra/newview/skins/default/xui/pl/menu_teleport_history_gear.xml
index 0e58592d46..0e58592d46 100644..100755
--- a/indra/newview/skins/default/xui/pl/menu_teleport_history_gear.xml
+++ b/indra/newview/skins/default/xui/pl/menu_teleport_history_gear.xml
diff --git a/indra/newview/skins/default/xui/pl/menu_teleport_history_item.xml b/indra/newview/skins/default/xui/pl/menu_teleport_history_item.xml
index cd36c116b0..cd36c116b0 100644..100755
--- a/indra/newview/skins/default/xui/pl/menu_teleport_history_item.xml
+++ b/indra/newview/skins/default/xui/pl/menu_teleport_history_item.xml
diff --git a/indra/newview/skins/default/xui/pl/menu_teleport_history_tab.xml b/indra/newview/skins/default/xui/pl/menu_teleport_history_tab.xml
index b12df08d6a..b12df08d6a 100644..100755
--- a/indra/newview/skins/default/xui/pl/menu_teleport_history_tab.xml
+++ b/indra/newview/skins/default/xui/pl/menu_teleport_history_tab.xml
diff --git a/indra/newview/skins/default/xui/pl/menu_text_editor.xml b/indra/newview/skins/default/xui/pl/menu_text_editor.xml
index 812f87bc1a..812f87bc1a 100644..100755
--- a/indra/newview/skins/default/xui/pl/menu_text_editor.xml
+++ b/indra/newview/skins/default/xui/pl/menu_text_editor.xml
diff --git a/indra/newview/skins/default/xui/pl/menu_topinfobar.xml b/indra/newview/skins/default/xui/pl/menu_topinfobar.xml
index 53536c8f1c..53536c8f1c 100644..100755
--- a/indra/newview/skins/default/xui/pl/menu_topinfobar.xml
+++ b/indra/newview/skins/default/xui/pl/menu_topinfobar.xml
diff --git a/indra/newview/skins/default/xui/pl/menu_url_agent.xml b/indra/newview/skins/default/xui/pl/menu_url_agent.xml
index db729be725..db729be725 100644..100755
--- a/indra/newview/skins/default/xui/pl/menu_url_agent.xml
+++ b/indra/newview/skins/default/xui/pl/menu_url_agent.xml
diff --git a/indra/newview/skins/default/xui/pl/menu_url_group.xml b/indra/newview/skins/default/xui/pl/menu_url_group.xml
index f340b3296a..f340b3296a 100644..100755
--- a/indra/newview/skins/default/xui/pl/menu_url_group.xml
+++ b/indra/newview/skins/default/xui/pl/menu_url_group.xml
diff --git a/indra/newview/skins/default/xui/pl/menu_url_http.xml b/indra/newview/skins/default/xui/pl/menu_url_http.xml
index e73f7b6745..e73f7b6745 100644..100755
--- a/indra/newview/skins/default/xui/pl/menu_url_http.xml
+++ b/indra/newview/skins/default/xui/pl/menu_url_http.xml
diff --git a/indra/newview/skins/default/xui/pl/menu_url_inventory.xml b/indra/newview/skins/default/xui/pl/menu_url_inventory.xml
index e36fa0dd2b..e36fa0dd2b 100644..100755
--- a/indra/newview/skins/default/xui/pl/menu_url_inventory.xml
+++ b/indra/newview/skins/default/xui/pl/menu_url_inventory.xml
diff --git a/indra/newview/skins/default/xui/pl/menu_url_map.xml b/indra/newview/skins/default/xui/pl/menu_url_map.xml
index 179ab1f676..179ab1f676 100644..100755
--- a/indra/newview/skins/default/xui/pl/menu_url_map.xml
+++ b/indra/newview/skins/default/xui/pl/menu_url_map.xml
diff --git a/indra/newview/skins/default/xui/pl/menu_url_objectim.xml b/indra/newview/skins/default/xui/pl/menu_url_objectim.xml
index 7576208a9e..7576208a9e 100644..100755
--- a/indra/newview/skins/default/xui/pl/menu_url_objectim.xml
+++ b/indra/newview/skins/default/xui/pl/menu_url_objectim.xml
diff --git a/indra/newview/skins/default/xui/pl/menu_url_parcel.xml b/indra/newview/skins/default/xui/pl/menu_url_parcel.xml
index 1b8dd62137..1b8dd62137 100644..100755
--- a/indra/newview/skins/default/xui/pl/menu_url_parcel.xml
+++ b/indra/newview/skins/default/xui/pl/menu_url_parcel.xml
diff --git a/indra/newview/skins/default/xui/pl/menu_url_slapp.xml b/indra/newview/skins/default/xui/pl/menu_url_slapp.xml
index eb83245c48..eb83245c48 100644..100755
--- a/indra/newview/skins/default/xui/pl/menu_url_slapp.xml
+++ b/indra/newview/skins/default/xui/pl/menu_url_slapp.xml
diff --git a/indra/newview/skins/default/xui/pl/menu_url_slurl.xml b/indra/newview/skins/default/xui/pl/menu_url_slurl.xml
index 4d4a5b4c4d..4d4a5b4c4d 100644..100755
--- a/indra/newview/skins/default/xui/pl/menu_url_slurl.xml
+++ b/indra/newview/skins/default/xui/pl/menu_url_slurl.xml
diff --git a/indra/newview/skins/default/xui/pl/menu_url_teleport.xml b/indra/newview/skins/default/xui/pl/menu_url_teleport.xml
index e225546930..e225546930 100644..100755
--- a/indra/newview/skins/default/xui/pl/menu_url_teleport.xml
+++ b/indra/newview/skins/default/xui/pl/menu_url_teleport.xml
diff --git a/indra/newview/skins/default/xui/pl/menu_viewer.xml b/indra/newview/skins/default/xui/pl/menu_viewer.xml
index 24c961fa26..e1725fc308 100644..100755
--- a/indra/newview/skins/default/xui/pl/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/pl/menu_viewer.xml
@@ -236,7 +236,7 @@
<menu label="Renderowanie" name="Rendering">
<menu_item_check label="Osie" name="Axes"/>
<menu_item_check label="Tryb obrazu szkieletowego" name="Wireframe"/>
- <menu_item_check label="Oświetlenie i cienie" name="Lighting and Shadows"/>
+ <menu_item_check label="Oświetlenie i cienie" name="Advanced Lighting Model"/>
<menu_item_check label="Cienie Słońca/Księżyca/Projektory" name="Shadows from Sun/Moon/Projectors"/>
<menu_item_check label="SSAO and wygładzanie cienia" name="SSAO and Shadow Smoothing"/>
<menu_item_check label="Globalne oświetlenie (eksperymentalne)" name="Global Illumination"/>
diff --git a/indra/newview/skins/default/xui/pl/menu_wearable_list_item.xml b/indra/newview/skins/default/xui/pl/menu_wearable_list_item.xml
index bf85246be8..bf85246be8 100644..100755
--- a/indra/newview/skins/default/xui/pl/menu_wearable_list_item.xml
+++ b/indra/newview/skins/default/xui/pl/menu_wearable_list_item.xml
diff --git a/indra/newview/skins/default/xui/pl/menu_wearing_gear.xml b/indra/newview/skins/default/xui/pl/menu_wearing_gear.xml
index 47cafdbd99..47cafdbd99 100644..100755
--- a/indra/newview/skins/default/xui/pl/menu_wearing_gear.xml
+++ b/indra/newview/skins/default/xui/pl/menu_wearing_gear.xml
diff --git a/indra/newview/skins/default/xui/pl/menu_wearing_tab.xml b/indra/newview/skins/default/xui/pl/menu_wearing_tab.xml
index 7531437043..7531437043 100644..100755
--- a/indra/newview/skins/default/xui/pl/menu_wearing_tab.xml
+++ b/indra/newview/skins/default/xui/pl/menu_wearing_tab.xml
diff --git a/indra/newview/skins/default/xui/pl/mime_types.xml b/indra/newview/skins/default/xui/pl/mime_types.xml
index cbf2afa91d..cbf2afa91d 100644..100755
--- a/indra/newview/skins/default/xui/pl/mime_types.xml
+++ b/indra/newview/skins/default/xui/pl/mime_types.xml
diff --git a/indra/newview/skins/default/xui/pl/mime_types_linux.xml b/indra/newview/skins/default/xui/pl/mime_types_linux.xml
index a2b8168b51..a2b8168b51 100644..100755
--- a/indra/newview/skins/default/xui/pl/mime_types_linux.xml
+++ b/indra/newview/skins/default/xui/pl/mime_types_linux.xml
diff --git a/indra/newview/skins/default/xui/pl/mime_types_mac.xml b/indra/newview/skins/default/xui/pl/mime_types_mac.xml
index 7213b26165..7213b26165 100644..100755
--- a/indra/newview/skins/default/xui/pl/mime_types_mac.xml
+++ b/indra/newview/skins/default/xui/pl/mime_types_mac.xml
diff --git a/indra/newview/skins/default/xui/pl/notifications.xml b/indra/newview/skins/default/xui/pl/notifications.xml
index 0194293642..f255b1b8ea 100644..100755
--- a/indra/newview/skins/default/xui/pl/notifications.xml
+++ b/indra/newview/skins/default/xui/pl/notifications.xml
@@ -1106,7 +1106,6 @@ Możesz normalnie używać [SECOND_LIFE], inni użytkownicy będą Cię widzieli
Instalacja [APP_NAME] zakończona.
Jeżeli używasz [SECOND_LIFE] po raz pierwszy to musisz stworzyć konto żeby móc się zalogować.
-Czy chcesz przejść na stronę [http://join.secondlife.com secondlife.com] żeby stworzyć nowe konto?
<usetemplate name="okcancelbuttons" notext="Kontynuuj" yestext="Nowe konto..."/>
</notification>
<notification name="LoginPacketNeverReceived">
diff --git a/indra/newview/skins/default/xui/pl/outfit_accordion_tab.xml b/indra/newview/skins/default/xui/pl/outfit_accordion_tab.xml
index bac885e5d8..bac885e5d8 100644..100755
--- a/indra/newview/skins/default/xui/pl/outfit_accordion_tab.xml
+++ b/indra/newview/skins/default/xui/pl/outfit_accordion_tab.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_active_object_row.xml b/indra/newview/skins/default/xui/pl/panel_active_object_row.xml
index ab1d8d7007..ab1d8d7007 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_active_object_row.xml
+++ b/indra/newview/skins/default/xui/pl/panel_active_object_row.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_adhoc_control_panel.xml b/indra/newview/skins/default/xui/pl/panel_adhoc_control_panel.xml
index ba0c85e4ef..ba0c85e4ef 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_adhoc_control_panel.xml
+++ b/indra/newview/skins/default/xui/pl/panel_adhoc_control_panel.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_avatar_list_item.xml b/indra/newview/skins/default/xui/pl/panel_avatar_list_item.xml
index c43a9bed81..c43a9bed81 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_avatar_list_item.xml
+++ b/indra/newview/skins/default/xui/pl/panel_avatar_list_item.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_block_list_sidetray.xml b/indra/newview/skins/default/xui/pl/panel_block_list_sidetray.xml
index 62cb392ba7..62cb392ba7 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_block_list_sidetray.xml
+++ b/indra/newview/skins/default/xui/pl/panel_block_list_sidetray.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_body_parts_list_item.xml b/indra/newview/skins/default/xui/pl/panel_body_parts_list_item.xml
index cebb6e3cfe..cebb6e3cfe 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_body_parts_list_item.xml
+++ b/indra/newview/skins/default/xui/pl/panel_body_parts_list_item.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_bodyparts_list_button_bar.xml b/indra/newview/skins/default/xui/pl/panel_bodyparts_list_button_bar.xml
index 560bfe78f4..560bfe78f4 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_bodyparts_list_button_bar.xml
+++ b/indra/newview/skins/default/xui/pl/panel_bodyparts_list_button_bar.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_bottomtray.xml b/indra/newview/skins/default/xui/pl/panel_bottomtray.xml
index 8a033fc32f..8a033fc32f 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_bottomtray.xml
+++ b/indra/newview/skins/default/xui/pl/panel_bottomtray.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_bottomtray_lite.xml b/indra/newview/skins/default/xui/pl/panel_bottomtray_lite.xml
index e32c12a8ee..e32c12a8ee 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_bottomtray_lite.xml
+++ b/indra/newview/skins/default/xui/pl/panel_bottomtray_lite.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_classified_info.xml b/indra/newview/skins/default/xui/pl/panel_classified_info.xml
index 52f54fc7cf..52f54fc7cf 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_classified_info.xml
+++ b/indra/newview/skins/default/xui/pl/panel_classified_info.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_clothing_list_button_bar.xml b/indra/newview/skins/default/xui/pl/panel_clothing_list_button_bar.xml
index 17a6d1eb8b..17a6d1eb8b 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_clothing_list_button_bar.xml
+++ b/indra/newview/skins/default/xui/pl/panel_clothing_list_button_bar.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_clothing_list_item.xml b/indra/newview/skins/default/xui/pl/panel_clothing_list_item.xml
index 42d1ead400..42d1ead400 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_clothing_list_item.xml
+++ b/indra/newview/skins/default/xui/pl/panel_clothing_list_item.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_cof_wearables.xml b/indra/newview/skins/default/xui/pl/panel_cof_wearables.xml
index 970b994c20..970b994c20 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_cof_wearables.xml
+++ b/indra/newview/skins/default/xui/pl/panel_cof_wearables.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_deletable_wearable_list_item.xml b/indra/newview/skins/default/xui/pl/panel_deletable_wearable_list_item.xml
index f9fba4d79f..f9fba4d79f 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_deletable_wearable_list_item.xml
+++ b/indra/newview/skins/default/xui/pl/panel_deletable_wearable_list_item.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_dummy_clothing_list_item.xml b/indra/newview/skins/default/xui/pl/panel_dummy_clothing_list_item.xml
index 83210808f1..83210808f1 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_dummy_clothing_list_item.xml
+++ b/indra/newview/skins/default/xui/pl/panel_dummy_clothing_list_item.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_edit_alpha.xml b/indra/newview/skins/default/xui/pl/panel_edit_alpha.xml
index 51ee3af00d..51ee3af00d 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_edit_alpha.xml
+++ b/indra/newview/skins/default/xui/pl/panel_edit_alpha.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_edit_classified.xml b/indra/newview/skins/default/xui/pl/panel_edit_classified.xml
index 7cfd9c221c..7cfd9c221c 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_edit_classified.xml
+++ b/indra/newview/skins/default/xui/pl/panel_edit_classified.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_edit_eyes.xml b/indra/newview/skins/default/xui/pl/panel_edit_eyes.xml
index 390a5313b5..390a5313b5 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_edit_eyes.xml
+++ b/indra/newview/skins/default/xui/pl/panel_edit_eyes.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_edit_gloves.xml b/indra/newview/skins/default/xui/pl/panel_edit_gloves.xml
index d32646d1a3..d32646d1a3 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_edit_gloves.xml
+++ b/indra/newview/skins/default/xui/pl/panel_edit_gloves.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_edit_hair.xml b/indra/newview/skins/default/xui/pl/panel_edit_hair.xml
index cbcba97eb6..cbcba97eb6 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_edit_hair.xml
+++ b/indra/newview/skins/default/xui/pl/panel_edit_hair.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_edit_jacket.xml b/indra/newview/skins/default/xui/pl/panel_edit_jacket.xml
index 7653e84cc0..7653e84cc0 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_edit_jacket.xml
+++ b/indra/newview/skins/default/xui/pl/panel_edit_jacket.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_edit_pants.xml b/indra/newview/skins/default/xui/pl/panel_edit_pants.xml
index 7975e55746..7975e55746 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_edit_pants.xml
+++ b/indra/newview/skins/default/xui/pl/panel_edit_pants.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_edit_physics.xml b/indra/newview/skins/default/xui/pl/panel_edit_physics.xml
index a773a52a59..a773a52a59 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_edit_physics.xml
+++ b/indra/newview/skins/default/xui/pl/panel_edit_physics.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_edit_pick.xml b/indra/newview/skins/default/xui/pl/panel_edit_pick.xml
index 72c162f63d..72c162f63d 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_edit_pick.xml
+++ b/indra/newview/skins/default/xui/pl/panel_edit_pick.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_edit_profile.xml b/indra/newview/skins/default/xui/pl/panel_edit_profile.xml
index e6fd8b18f8..e6fd8b18f8 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_edit_profile.xml
+++ b/indra/newview/skins/default/xui/pl/panel_edit_profile.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_edit_shape.xml b/indra/newview/skins/default/xui/pl/panel_edit_shape.xml
index 54f9fdc21c..54f9fdc21c 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_edit_shape.xml
+++ b/indra/newview/skins/default/xui/pl/panel_edit_shape.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_edit_shirt.xml b/indra/newview/skins/default/xui/pl/panel_edit_shirt.xml
index 9530c781ab..9530c781ab 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_edit_shirt.xml
+++ b/indra/newview/skins/default/xui/pl/panel_edit_shirt.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_edit_shoes.xml b/indra/newview/skins/default/xui/pl/panel_edit_shoes.xml
index d90a6d8726..d90a6d8726 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_edit_shoes.xml
+++ b/indra/newview/skins/default/xui/pl/panel_edit_shoes.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_edit_skin.xml b/indra/newview/skins/default/xui/pl/panel_edit_skin.xml
index 9e0acd3cec..9e0acd3cec 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_edit_skin.xml
+++ b/indra/newview/skins/default/xui/pl/panel_edit_skin.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_edit_skirt.xml b/indra/newview/skins/default/xui/pl/panel_edit_skirt.xml
index f74ad916cd..f74ad916cd 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_edit_skirt.xml
+++ b/indra/newview/skins/default/xui/pl/panel_edit_skirt.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_edit_socks.xml b/indra/newview/skins/default/xui/pl/panel_edit_socks.xml
index b41069e8d7..b41069e8d7 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_edit_socks.xml
+++ b/indra/newview/skins/default/xui/pl/panel_edit_socks.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_edit_tattoo.xml b/indra/newview/skins/default/xui/pl/panel_edit_tattoo.xml
index 6fd1e2277a..6fd1e2277a 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_edit_tattoo.xml
+++ b/indra/newview/skins/default/xui/pl/panel_edit_tattoo.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_edit_underpants.xml b/indra/newview/skins/default/xui/pl/panel_edit_underpants.xml
index f2a9b10f17..f2a9b10f17 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_edit_underpants.xml
+++ b/indra/newview/skins/default/xui/pl/panel_edit_underpants.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_edit_undershirt.xml b/indra/newview/skins/default/xui/pl/panel_edit_undershirt.xml
index 7da1341e96..7da1341e96 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_edit_undershirt.xml
+++ b/indra/newview/skins/default/xui/pl/panel_edit_undershirt.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_edit_wearable.xml b/indra/newview/skins/default/xui/pl/panel_edit_wearable.xml
index 2027b8715b..2027b8715b 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_edit_wearable.xml
+++ b/indra/newview/skins/default/xui/pl/panel_edit_wearable.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_group_control_panel.xml b/indra/newview/skins/default/xui/pl/panel_group_control_panel.xml
index 4e373cdf8f..4e373cdf8f 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_group_control_panel.xml
+++ b/indra/newview/skins/default/xui/pl/panel_group_control_panel.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_group_general.xml b/indra/newview/skins/default/xui/pl/panel_group_general.xml
index a4d76badf0..a4d76badf0 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_group_general.xml
+++ b/indra/newview/skins/default/xui/pl/panel_group_general.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_group_info_sidetray.xml b/indra/newview/skins/default/xui/pl/panel_group_info_sidetray.xml
index 37fb529f2b..37fb529f2b 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_group_info_sidetray.xml
+++ b/indra/newview/skins/default/xui/pl/panel_group_info_sidetray.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_group_invite.xml b/indra/newview/skins/default/xui/pl/panel_group_invite.xml
index 1822551e86..1822551e86 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_group_invite.xml
+++ b/indra/newview/skins/default/xui/pl/panel_group_invite.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_group_land_money.xml b/indra/newview/skins/default/xui/pl/panel_group_land_money.xml
index aea4e50fd5..aea4e50fd5 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_group_land_money.xml
+++ b/indra/newview/skins/default/xui/pl/panel_group_land_money.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_group_list_item.xml b/indra/newview/skins/default/xui/pl/panel_group_list_item.xml
index a8b4056976..a8b4056976 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_group_list_item.xml
+++ b/indra/newview/skins/default/xui/pl/panel_group_list_item.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_group_notices.xml b/indra/newview/skins/default/xui/pl/panel_group_notices.xml
index a3b0998de3..a3b0998de3 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_group_notices.xml
+++ b/indra/newview/skins/default/xui/pl/panel_group_notices.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_group_notify.xml b/indra/newview/skins/default/xui/pl/panel_group_notify.xml
index d27a81217a..d27a81217a 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_group_notify.xml
+++ b/indra/newview/skins/default/xui/pl/panel_group_notify.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_group_roles.xml b/indra/newview/skins/default/xui/pl/panel_group_roles.xml
index 9e9c79d26a..9e9c79d26a 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_group_roles.xml
+++ b/indra/newview/skins/default/xui/pl/panel_group_roles.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_im_control_panel.xml b/indra/newview/skins/default/xui/pl/panel_im_control_panel.xml
index 4aadd3b93b..4aadd3b93b 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_im_control_panel.xml
+++ b/indra/newview/skins/default/xui/pl/panel_im_control_panel.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_inventory_item.xml b/indra/newview/skins/default/xui/pl/panel_inventory_item.xml
index d18047fbcf..d18047fbcf 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_inventory_item.xml
+++ b/indra/newview/skins/default/xui/pl/panel_inventory_item.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_landmark_info.xml b/indra/newview/skins/default/xui/pl/panel_landmark_info.xml
index 3370f6f58e..3370f6f58e 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_landmark_info.xml
+++ b/indra/newview/skins/default/xui/pl/panel_landmark_info.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_landmarks.xml b/indra/newview/skins/default/xui/pl/panel_landmarks.xml
index 039be3b504..039be3b504 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_landmarks.xml
+++ b/indra/newview/skins/default/xui/pl/panel_landmarks.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_login.xml b/indra/newview/skins/default/xui/pl/panel_login.xml
index dc8e7399af..c87a3d3bd4 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_login.xml
+++ b/indra/newview/skins/default/xui/pl/panel_login.xml
@@ -5,6 +5,9 @@
</panel.string>
<layout_stack name="login_widgets">
<layout_panel name="login">
+ <text name="log_in_text">
+ POÅÄ„CZ
+ </text>
<text name="username_text">
Użytkownik:
</text>
@@ -12,15 +15,8 @@
<text name="password_text">
Hasło:
</text>
- <check_box label="Zapamiętaj hasło" name="remember_check"/>
- <button label="Połącz" name="connect_btn"/>
- <text name="mode_selection_text">
- Tryb życia:
- </text>
- <combo_box name="mode_combo" tool_tip="Wybierz tryb życia. Wybierz tryb turystyczny dla łatwego zwiedzania i czatowania. Wybierz tryb zaawansowany aby mieć dostęp do większej ilości opcji.">
- <combo_box.item label="Turystyczny" name="Basic"/>
- <combo_box.item label="Zaawansowany" name="Advanced"/>
- </combo_box>
+ </layout_panel>
+ <layout_panel name="start_location_panel">
<text name="start_location_text">
Rozpocznij w:
</text>
@@ -30,16 +26,23 @@
<combo_box.item label="&lt;Wpisz Region&gt;" name="Typeregionname"/>
</combo_box>
</layout_panel>
- <layout_panel name="links">
- <text name="create_new_account_text">
- Utwórz nowe konto
+ <layout_panel name="links_login_panel">
+ <text name="login_help">
+ Potrzebujesz pomocy z logowaniem siÄ™?
</text>
<text name="forgot_password_text">
Zapomniałeś swojej nazwy użytkownika lub hasła?
</text>
- <text name="login_help">
- Potrzebujesz pomocy z logowaniem siÄ™?
+ <button label="Połącz" name="connect_btn"/>
+ <check_box label="Zapamiętaj hasło" name="remember_check"/>
+ </layout_panel>
+ <layout_panel name="links">
+ <text name="create_account_text">
+ CREATE YǾUR ACCǾUNT
</text>
+ <button name="create_new_account_btn"
+ label="Utwórz nowe konto"
+ width="120"/>
</layout_panel>
</layout_stack>
</panel>
diff --git a/indra/newview/skins/default/xui/pl/panel_main_inventory.xml b/indra/newview/skins/default/xui/pl/panel_main_inventory.xml
index 8d6fa1173c..8d6fa1173c 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_main_inventory.xml
+++ b/indra/newview/skins/default/xui/pl/panel_main_inventory.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_me.xml b/indra/newview/skins/default/xui/pl/panel_me.xml
index 72a5f51520..72a5f51520 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_me.xml
+++ b/indra/newview/skins/default/xui/pl/panel_me.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_media_settings_general.xml b/indra/newview/skins/default/xui/pl/panel_media_settings_general.xml
index 914a2aee73..914a2aee73 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_media_settings_general.xml
+++ b/indra/newview/skins/default/xui/pl/panel_media_settings_general.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_media_settings_permissions.xml b/indra/newview/skins/default/xui/pl/panel_media_settings_permissions.xml
index a87c29d7b3..a87c29d7b3 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_media_settings_permissions.xml
+++ b/indra/newview/skins/default/xui/pl/panel_media_settings_permissions.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_media_settings_security.xml b/indra/newview/skins/default/xui/pl/panel_media_settings_security.xml
index 7e95c4942f..7e95c4942f 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_media_settings_security.xml
+++ b/indra/newview/skins/default/xui/pl/panel_media_settings_security.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_navigation_bar.xml b/indra/newview/skins/default/xui/pl/panel_navigation_bar.xml
index b01e686c41..b01e686c41 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_navigation_bar.xml
+++ b/indra/newview/skins/default/xui/pl/panel_navigation_bar.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_nearby_chat_bar.xml b/indra/newview/skins/default/xui/pl/panel_nearby_chat_bar.xml
index 63cf96b571..4ed3ff669b 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_nearby_chat_bar.xml
+++ b/indra/newview/skins/default/xui/pl/panel_nearby_chat_bar.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel name="chat_bar">
+<panel name="nearby_chat">
<string name="min_width">
192
</string>
diff --git a/indra/newview/skins/default/xui/pl/panel_nearby_media.xml b/indra/newview/skins/default/xui/pl/panel_nearby_media.xml
index d77c6d7852..d77c6d7852 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_nearby_media.xml
+++ b/indra/newview/skins/default/xui/pl/panel_nearby_media.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_notify_textbox.xml b/indra/newview/skins/default/xui/pl/panel_notify_textbox.xml
index e1668e1ef1..e1668e1ef1 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_notify_textbox.xml
+++ b/indra/newview/skins/default/xui/pl/panel_notify_textbox.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_online_status_toast.xml b/indra/newview/skins/default/xui/pl/panel_online_status_toast.xml
index fdc489f375..fdc489f375 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_online_status_toast.xml
+++ b/indra/newview/skins/default/xui/pl/panel_online_status_toast.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_outfit_edit.xml b/indra/newview/skins/default/xui/pl/panel_outfit_edit.xml
index 50353d4fba..50353d4fba 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_outfit_edit.xml
+++ b/indra/newview/skins/default/xui/pl/panel_outfit_edit.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_outfits_inventory.xml b/indra/newview/skins/default/xui/pl/panel_outfits_inventory.xml
index bf23ace58f..bf23ace58f 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_outfits_inventory.xml
+++ b/indra/newview/skins/default/xui/pl/panel_outfits_inventory.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_outfits_inventory_gear_default.xml b/indra/newview/skins/default/xui/pl/panel_outfits_inventory_gear_default.xml
index 2f8c008f98..2f8c008f98 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_outfits_inventory_gear_default.xml
+++ b/indra/newview/skins/default/xui/pl/panel_outfits_inventory_gear_default.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_outfits_list.xml b/indra/newview/skins/default/xui/pl/panel_outfits_list.xml
index ed3057399d..ed3057399d 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_outfits_list.xml
+++ b/indra/newview/skins/default/xui/pl/panel_outfits_list.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_outfits_wearing.xml b/indra/newview/skins/default/xui/pl/panel_outfits_wearing.xml
index 5559c151e7..5559c151e7 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_outfits_wearing.xml
+++ b/indra/newview/skins/default/xui/pl/panel_outfits_wearing.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_people.xml b/indra/newview/skins/default/xui/pl/panel_people.xml
index ef52e2148b..ef52e2148b 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_people.xml
+++ b/indra/newview/skins/default/xui/pl/panel_people.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_pick_info.xml b/indra/newview/skins/default/xui/pl/panel_pick_info.xml
index 26afded795..26afded795 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_pick_info.xml
+++ b/indra/newview/skins/default/xui/pl/panel_pick_info.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_picks.xml b/indra/newview/skins/default/xui/pl/panel_picks.xml
index 1ba4e76196..1ba4e76196 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_picks.xml
+++ b/indra/newview/skins/default/xui/pl/panel_picks.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_place_profile.xml b/indra/newview/skins/default/xui/pl/panel_place_profile.xml
index 2a4ffab36c..2a4ffab36c 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_place_profile.xml
+++ b/indra/newview/skins/default/xui/pl/panel_place_profile.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_places.xml b/indra/newview/skins/default/xui/pl/panel_places.xml
index d69d137d23..d69d137d23 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_places.xml
+++ b/indra/newview/skins/default/xui/pl/panel_places.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_preferences_advanced.xml b/indra/newview/skins/default/xui/pl/panel_preferences_advanced.xml
index 5e61f62691..5e61f62691 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_preferences_advanced.xml
+++ b/indra/newview/skins/default/xui/pl/panel_preferences_advanced.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_preferences_alerts.xml b/indra/newview/skins/default/xui/pl/panel_preferences_alerts.xml
index d53a99e8c1..d53a99e8c1 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_preferences_alerts.xml
+++ b/indra/newview/skins/default/xui/pl/panel_preferences_alerts.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_preferences_chat.xml b/indra/newview/skins/default/xui/pl/panel_preferences_chat.xml
index 7fd1029e6a..7fd1029e6a 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/pl/panel_preferences_chat.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_preferences_colors.xml b/indra/newview/skins/default/xui/pl/panel_preferences_colors.xml
index 3affda57bf..3affda57bf 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_preferences_colors.xml
+++ b/indra/newview/skins/default/xui/pl/panel_preferences_colors.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_preferences_general.xml b/indra/newview/skins/default/xui/pl/panel_preferences_general.xml
index fff56eab6e..fff56eab6e 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_preferences_general.xml
+++ b/indra/newview/skins/default/xui/pl/panel_preferences_general.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/pl/panel_preferences_graphics1.xml
index f2beef091a..4cd271a141 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_preferences_graphics1.xml
+++ b/indra/newview/skins/default/xui/pl/panel_preferences_graphics1.xml
@@ -26,7 +26,7 @@
<text name="ShadersText">
Cieniowanie pixeli (shadery):
</text>
- <check_box initial_value="prawda" label="Przeźroczystość wody" name="TransparentWater"/>
+ <check_box initial_value="true" label="Przeźroczystość wody" name="TransparentWater"/>
<check_box initial_value="true" label="Mapowanie wypukłości i połysk" name="BumpShiny"/>
<check_box initial_value="true" label="Podstawowe shadery" name="BasicShaders" tool_tip="Wyłączenie tej opcji może naprawić błędy niektórych sterowników graficznych."/>
<check_box initial_value="true" label="Shadery atmosfery" name="WindLightUseAtmosShaders"/>
diff --git a/indra/newview/skins/default/xui/pl/panel_preferences_move.xml b/indra/newview/skins/default/xui/pl/panel_preferences_move.xml
index 4c2df2c1f3..4c2df2c1f3 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_preferences_move.xml
+++ b/indra/newview/skins/default/xui/pl/panel_preferences_move.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_preferences_privacy.xml b/indra/newview/skins/default/xui/pl/panel_preferences_privacy.xml
index 5af2fed142..5af2fed142 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_preferences_privacy.xml
+++ b/indra/newview/skins/default/xui/pl/panel_preferences_privacy.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_preferences_setup.xml b/indra/newview/skins/default/xui/pl/panel_preferences_setup.xml
index fa0a5981a8..b663e18227 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_preferences_setup.xml
+++ b/indra/newview/skins/default/xui/pl/panel_preferences_setup.xml
@@ -26,14 +26,13 @@
Internet:
</text>
<radio_group name="use_external_browser">
- <radio_item label="Użyj zewnętrznej przeglądarki (IE, Firefox, Safari)" name="external" tool_tip="Używaj zewnętrznej przeglądarki. Nie jest to rekomendowane w trybie pełnoekranowym." value="1"/>
+ <radio_item label="Użyj zewnętrznej przeglądarki (IE, Firefox, Safari)" name="external" tool_tip="Używaj zewnętrznej przeglądarki. Nie jest to rekomendowane w trybie pełnoekranowym." value="true"/>
<radio_item label="Używaj wbudowanej przeglądarki." name="internal" tool_tip="Używaj wbudowanej przeglądarki. Ta przeglądarka otworzy nowe okno w [APP_NAME]." value=""/>
</radio_group>
<check_box initial_value="true" label="Zezwalaj na wtyczki" name="browser_plugins_enabled"/>
<check_box initial_value="true" label="Akceptuj ciasteczka z Internetu" name="cookies_enabled"/>
<check_box initial_value="true" label="Zezwalaj na Javascript" name="browser_javascript_enabled"/>
- <check_box initial_value="nieprawda" label="Zezwól na wyskakujące okienka przeglądarki mediów" name="media_popup_enabled"/>
- <check_box initial_value="false" label="Używaj serwera proxy" name="web_proxy_enabled"/>
+ <check_box initial_value="false" label="Zezwól na wyskakujące okienka przeglądarki mediów" name="media_popup_enabled"/>
<text name="Proxy location">
Lokalizacja proxy:
</text>
diff --git a/indra/newview/skins/default/xui/pl/panel_preferences_sound.xml b/indra/newview/skins/default/xui/pl/panel_preferences_sound.xml
index 46f5ebb8e2..46f5ebb8e2 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_preferences_sound.xml
+++ b/indra/newview/skins/default/xui/pl/panel_preferences_sound.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_prim_media_controls.xml b/indra/newview/skins/default/xui/pl/panel_prim_media_controls.xml
index b5763e1291..b5763e1291 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_prim_media_controls.xml
+++ b/indra/newview/skins/default/xui/pl/panel_prim_media_controls.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_region_covenant.xml b/indra/newview/skins/default/xui/pl/panel_region_covenant.xml
index 932e3631ab..932e3631ab 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_region_covenant.xml
+++ b/indra/newview/skins/default/xui/pl/panel_region_covenant.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_region_debug.xml b/indra/newview/skins/default/xui/pl/panel_region_debug.xml
index c5b08383dc..c5b08383dc 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_region_debug.xml
+++ b/indra/newview/skins/default/xui/pl/panel_region_debug.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_region_estate.xml b/indra/newview/skins/default/xui/pl/panel_region_estate.xml
index 1b64827725..1b64827725 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_region_estate.xml
+++ b/indra/newview/skins/default/xui/pl/panel_region_estate.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_region_general.xml b/indra/newview/skins/default/xui/pl/panel_region_general.xml
index 601571f62e..601571f62e 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_region_general.xml
+++ b/indra/newview/skins/default/xui/pl/panel_region_general.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_region_terrain.xml b/indra/newview/skins/default/xui/pl/panel_region_terrain.xml
index f22b4a5989..f22b4a5989 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_region_terrain.xml
+++ b/indra/newview/skins/default/xui/pl/panel_region_terrain.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_region_texture.xml b/indra/newview/skins/default/xui/pl/panel_region_texture.xml
index c6ed2457f1..c6ed2457f1 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_region_texture.xml
+++ b/indra/newview/skins/default/xui/pl/panel_region_texture.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_script_ed.xml b/indra/newview/skins/default/xui/pl/panel_script_ed.xml
index b05223aa0f..b05223aa0f 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_script_ed.xml
+++ b/indra/newview/skins/default/xui/pl/panel_script_ed.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_script_limits_my_avatar.xml b/indra/newview/skins/default/xui/pl/panel_script_limits_my_avatar.xml
index a52d8aed3d..a52d8aed3d 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_script_limits_my_avatar.xml
+++ b/indra/newview/skins/default/xui/pl/panel_script_limits_my_avatar.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_script_limits_region_memory.xml b/indra/newview/skins/default/xui/pl/panel_script_limits_region_memory.xml
index 070f025087..070f025087 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_script_limits_region_memory.xml
+++ b/indra/newview/skins/default/xui/pl/panel_script_limits_region_memory.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_scrolling_param.xml b/indra/newview/skins/default/xui/pl/panel_scrolling_param.xml
index 70a6e39412..70a6e39412 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_scrolling_param.xml
+++ b/indra/newview/skins/default/xui/pl/panel_scrolling_param.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_scrolling_param_base.xml b/indra/newview/skins/default/xui/pl/panel_scrolling_param_base.xml
index fa659040ea..fa659040ea 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_scrolling_param_base.xml
+++ b/indra/newview/skins/default/xui/pl/panel_scrolling_param_base.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_side_tray.xml b/indra/newview/skins/default/xui/pl/panel_side_tray.xml
index ff4ca23a4d..ff4ca23a4d 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_side_tray.xml
+++ b/indra/newview/skins/default/xui/pl/panel_side_tray.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_side_tray_tab_caption.xml b/indra/newview/skins/default/xui/pl/panel_side_tray_tab_caption.xml
index 95cd7c53dc..95cd7c53dc 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_side_tray_tab_caption.xml
+++ b/indra/newview/skins/default/xui/pl/panel_side_tray_tab_caption.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_stand_stop_flying.xml b/indra/newview/skins/default/xui/pl/panel_stand_stop_flying.xml
index 9f7f7f1238..9f7f7f1238 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_stand_stop_flying.xml
+++ b/indra/newview/skins/default/xui/pl/panel_stand_stop_flying.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_status_bar.xml b/indra/newview/skins/default/xui/pl/panel_status_bar.xml
index 6aa0d27bb8..6aa0d27bb8 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_status_bar.xml
+++ b/indra/newview/skins/default/xui/pl/panel_status_bar.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_teleport_history.xml b/indra/newview/skins/default/xui/pl/panel_teleport_history.xml
index b43bd96536..b43bd96536 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_teleport_history.xml
+++ b/indra/newview/skins/default/xui/pl/panel_teleport_history.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_teleport_history_item.xml b/indra/newview/skins/default/xui/pl/panel_teleport_history_item.xml
index f0fe28c4ce..f0fe28c4ce 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_teleport_history_item.xml
+++ b/indra/newview/skins/default/xui/pl/panel_teleport_history_item.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_voice_effect.xml b/indra/newview/skins/default/xui/pl/panel_voice_effect.xml
index f8a076424f..f8a076424f 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_voice_effect.xml
+++ b/indra/newview/skins/default/xui/pl/panel_voice_effect.xml
diff --git a/indra/newview/skins/default/xui/pl/panel_volume_pulldown.xml b/indra/newview/skins/default/xui/pl/panel_volume_pulldown.xml
new file mode 100755
index 0000000000..1611900700
--- /dev/null
+++ b/indra/newview/skins/default/xui/pl/panel_volume_pulldown.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel name="volumepulldown_floater">
+ <slider label="Główny" name="System Volume"/>
+ <slider label="Przyciski" name="UI Volume"/>
+ <slider label="Okolica" name="Wind Volume"/>
+ <slider label="Efekty" name="SFX Volume"/>
+ <check_box name="gesture_audio_play_btn" tool_tip="Włącz dźwięki gestów"/>
+ <slider label="Muzyka" name="Music Volume"/>
+ <check_box tool_tip="WÅ‚Ä…cz muzykÄ™ strumieniowÄ…" name="enable_music"/>
+ <slider label="Media" name="Media Volume"/>
+ <check_box tool_tip="WÅ‚Ä…cz media strumieniowe" name="enable_media"/>
+ <slider label="GÅ‚os" name="Voice Volume"/>
+ <check_box tool_tip="Włącz rozmowy głosowe" name="enable_voice_check"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/pl/panel_world_map.xml b/indra/newview/skins/default/xui/pl/panel_world_map.xml
index 69f18be767..69f18be767 100644..100755
--- a/indra/newview/skins/default/xui/pl/panel_world_map.xml
+++ b/indra/newview/skins/default/xui/pl/panel_world_map.xml
diff --git a/indra/newview/skins/default/xui/pl/role_actions.xml b/indra/newview/skins/default/xui/pl/role_actions.xml
index 57df2bc70f..57df2bc70f 100644..100755
--- a/indra/newview/skins/default/xui/pl/role_actions.xml
+++ b/indra/newview/skins/default/xui/pl/role_actions.xml
diff --git a/indra/newview/skins/default/xui/pl/sidepanel_appearance.xml b/indra/newview/skins/default/xui/pl/sidepanel_appearance.xml
index cea903769c..cea903769c 100644..100755
--- a/indra/newview/skins/default/xui/pl/sidepanel_appearance.xml
+++ b/indra/newview/skins/default/xui/pl/sidepanel_appearance.xml
diff --git a/indra/newview/skins/default/xui/pl/sidepanel_inventory.xml b/indra/newview/skins/default/xui/pl/sidepanel_inventory.xml
index c2e50473a5..c2e50473a5 100644..100755
--- a/indra/newview/skins/default/xui/pl/sidepanel_inventory.xml
+++ b/indra/newview/skins/default/xui/pl/sidepanel_inventory.xml
diff --git a/indra/newview/skins/default/xui/pl/sidepanel_item_info.xml b/indra/newview/skins/default/xui/pl/sidepanel_item_info.xml
index 9ec3c480b7..9ec3c480b7 100644..100755
--- a/indra/newview/skins/default/xui/pl/sidepanel_item_info.xml
+++ b/indra/newview/skins/default/xui/pl/sidepanel_item_info.xml
diff --git a/indra/newview/skins/default/xui/pl/sidepanel_task_info.xml b/indra/newview/skins/default/xui/pl/sidepanel_task_info.xml
index eb8c9cdbbb..eb8c9cdbbb 100644..100755
--- a/indra/newview/skins/default/xui/pl/sidepanel_task_info.xml
+++ b/indra/newview/skins/default/xui/pl/sidepanel_task_info.xml
diff --git a/indra/newview/skins/default/xui/pl/strings.xml b/indra/newview/skins/default/xui/pl/strings.xml
index f6dec8536b..f6dec8536b 100644..100755
--- a/indra/newview/skins/default/xui/pl/strings.xml
+++ b/indra/newview/skins/default/xui/pl/strings.xml
diff --git a/indra/newview/skins/default/xui/pl/teleport_strings.xml b/indra/newview/skins/default/xui/pl/teleport_strings.xml
index 0366c3fdbc..0366c3fdbc 100644..100755
--- a/indra/newview/skins/default/xui/pl/teleport_strings.xml
+++ b/indra/newview/skins/default/xui/pl/teleport_strings.xml
diff --git a/indra/newview/skins/default/xui/pl/xui_version.xml b/indra/newview/skins/default/xui/pl/xui_version.xml
index 0e777751d3..0e777751d3 100644..100755
--- a/indra/newview/skins/default/xui/pl/xui_version.xml
+++ b/indra/newview/skins/default/xui/pl/xui_version.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_about.xml b/indra/newview/skins/default/xui/pt/floater_about.xml
index e843e56090..47975a6386 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_about.xml
+++ b/indra/newview/skins/default/xui/pt/floater_about.xml
@@ -7,7 +7,9 @@
Construído com [COMPILER] versão [COMPILER_VERSION]
</floater.string>
<floater.string name="AboutPosition">
- Você está em [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1] em [REGION] localizado em [HOSTNAME]&lt;/nolink&gt;([HOSTIP])
+ Você está em [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] em [REGION] localizado em &lt;nolink&gt;[HOSTNAME]&lt;/nolink&gt; ([HOSTIP])
+SLURL: &lt;nolink&gt;[SLURL]&lt;/nolink&gt;
+(coordenadas globais [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1])
[SERVER_VERSION]
[SERVER_RELEASE_NOTES_URL]
</floater.string>
@@ -65,27 +67,26 @@ Versão do servidor de voz: [VOICE_VERSION]
</panel>
<panel label="Licenças" name="licenses_panel">
<text_editor name="credits_editor">
- 3Dconnexion SDK Copyright (C) 1992-2007 3Dconnexion
- APR Copyright (C) 2000-2004 The Apache Software Foundation
- Collada DOM Copyright 2005 Sony Computer Entertainment Inc.
- cURL Copyright (C) 1996-2002, Daniel Stenberg, (daniel@haxx.se)
+ 3Dconnexion SDK Copyright (C) 1992-2009 3Dconnexion
+ APR Copyright (C) 2011 The Apache Software Foundation
+ Collada DOM Copyright 2006 Sony Computer Entertainment Inc.
+ cURL Copyright (C) 1996-2010, Daniel Stenberg, (daniel@haxx.se)
DBus/dbus-glib Copyright (C) 2002, 2003 CodeFactory AB / Copyright (C) 2003, 2004 Red Hat, Inc.
expat Copyright (C) 1998, 1999, 2000 Thai Open Source Software Center Ltd.
- FreeType Copyright (C) 1996-2002, The FreeType Project (www.freetype.org).
+ FreeType Copyright (C) 1996-2002, 2006 David Turner, Robert Wilhelm, and Werner Lemberg.
GL Copyright (C) 1999-2004 Brian Paul.
GLOD Copyright (C) 2003-04 Jonathan Cohen, Nat Duca, Chris Niski, Johns Hopkins University e David Luebke, Brenden Schubert, University of Virginia.
google-perftools Copyright (c) 2005, Google Inc.
Havok.com(TM) Copyright (C) 1999-2001, Telekinesys Research Limited.
jpeg2000 Copyright (C) 2001, David Taubman, The University of New South Wales (UNSW)
jpeglib Copyright (C) 1991-1998, Thomas G. Lane.
- ogg/vorbis Copyright (C) 2001, Xiphophorus
- OpenSSL Copyright (C) 1998-2002 The OpenSSL Project.
- PCRE Copyright (c) 1997-2008 University of Cambridge
+ ogg/vorbis Copyright (C) 2002, Xiphophorus
+ OpenSSL Copyright (C) 1998-2008 The OpenSSL Project.
+ PCRE Copyright (c) 1997-2012 University of Cambridge
SDL Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga
SSLeay Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
xmlrpc-epi Copyright (C) 2000 Epinions, Inc.
- zlib Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler.
- google-perftools Copyright (c) 2005, Google Inc.
+ zlib Copyright (C) 1995-2012 Jean-loup Gailly and Mark Adler.
O Visualizador do Second Life usa Havok (TM) Physics. (c)Copyright 1999-2010 Havok.com Inc. (e seus Licenciantes). Todos os direitos reservados. Consulte www.havok.com para obter detalhes.
diff --git a/indra/newview/skins/default/xui/pt/floater_about_land.xml b/indra/newview/skins/default/xui/pt/floater_about_land.xml
index cd0fb4c41b..f48280840c 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/pt/floater_about_land.xml
@@ -465,7 +465,7 @@ Mídia:
Permitir acesso apenas para residentes que:
</text>
<check_box label="Possuam Dados de pagamento fornecidos [ESTATE_PAYMENT_LIMIT]" name="limit_payment" tool_tip="Os residentes devem ter seus dados de pagamento cadastrados para acessar este lote. Consulte o [SUPPORT_SITE] para saber mais."/>
- <check_box label="Tiveram sua idade verificada [ESTATE_AGE_LIMIT]" name="limit_age_verified" tool_tip="Os residentes devem ter a idade verificada para acessar este lote. Consulte o [SUPPORT_SITE] para saber mais."/>
+ <check_box label="Tem 18 anos ou mais [ESTATE_AGE_LIMIT]" name="limit_age_verified" tool_tip="Os residentes devem ter 18 anos ou mais para acessar este lote. Consulte o [SUPPORT_SITE] para obter mais informações."/>
<check_box label="Permitir acesso do grupo: [GROUP]" name="GroupCheck" tool_tip="Definir grupo na aba Geral."/>
<check_box label="Vender passes para:" name="PassCheck" tool_tip="Permite acesso temporário a este terreno"/>
<combo_box name="pass_combo">
diff --git a/indra/newview/skins/default/xui/pt/floater_activeim.xml b/indra/newview/skins/default/xui/pt/floater_activeim.xml
index 892ccdf974..892ccdf974 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_activeim.xml
+++ b/indra/newview/skins/default/xui/pt/floater_activeim.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_animation_anim_preview.xml b/indra/newview/skins/default/xui/pt/floater_animation_anim_preview.xml
index 05326d8594..05326d8594 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_animation_anim_preview.xml
+++ b/indra/newview/skins/default/xui/pt/floater_animation_anim_preview.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_animation_bvh_preview.xml b/indra/newview/skins/default/xui/pt/floater_animation_bvh_preview.xml
index 5cae581045..5cae581045 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_animation_bvh_preview.xml
+++ b/indra/newview/skins/default/xui/pt/floater_animation_bvh_preview.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_animation_preview.xml b/indra/newview/skins/default/xui/pt/floater_animation_preview.xml
deleted file mode 100644
index 3ec81612a1..0000000000
--- a/indra/newview/skins/default/xui/pt/floater_animation_preview.xml
+++ /dev/null
@@ -1,187 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Animation Preview" title="">
- <floater.string name="failed_to_initialize">
- Não foi possível iniciar o movimento
- </floater.string>
- <floater.string name="anim_too_long">
- O arquivo de animação tem [LENGTH] segundos de duração.
-
-A duração máxima de animação permitida é de [MAX_LENGTH] segundos.
- </floater.string>
- <floater.string name="failed_file_read">
- Não foi possível ler o arquivo de animação.
-
-[STATUS]
- </floater.string>
- <floater.string name="E_ST_OK">
- OK
- </floater.string>
- <floater.string name="E_ST_EOF">
- Fim de arquivo prematuro
- </floater.string>
- <floater.string name="E_ST_NO_CONSTRAINT">
- Impossível ler definição constraint.
- </floater.string>
- <floater.string name="E_ST_NO_FILE">
- Impossível abrir arquivo BVH.
- </floater.string>
- <floater.string name="E_ST_NO_HIER">
- Invalid HIERARCHY header.
- </floater.string>
- <floater.string name="E_ST_NO_JOINT">
- RAIZ ou JUNTA não encontrados.
- </floater.string>
- <floater.string name="E_ST_NO_NAME">
- Impossível obter nome JOINT.
- </floater.string>
- <floater.string name="E_ST_NO_OFFSET">
- Impossível localizar OFFSET.
- </floater.string>
- <floater.string name="E_ST_NO_CHANNELS">
- Impossível localizar CHANNELS.
- </floater.string>
- <floater.string name="E_ST_NO_ROTATION">
- Impossível obter ordem de rotação.
- </floater.string>
- <floater.string name="E_ST_NO_AXIS">
- Impossível obter eixo de rotação.
- </floater.string>
- <floater.string name="E_ST_NO_MOTION">
- Impossível localizar MOTION.
- </floater.string>
- <floater.string name="E_ST_NO_FRAMES">
- Impossível determinar número de quadros.
- </floater.string>
- <floater.string name="E_ST_NO_FRAME_TIME">
- Impossível determinar tempo dos quadros.
- </floater.string>
- <floater.string name="E_ST_NO_POS">
- Impossível definir posicionamento.
- </floater.string>
- <floater.string name="E_ST_NO_ROT">
- Impossível definir valores da rotação.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_FILE">
- Impossível abrir arquivo de tradução.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_HEADER">
- Impossível ler cabeçalho de tradução.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_NAME">
- Impossível ler nomes traduzidos.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_IGNORE">
- Impossível obter valor traduzido a ignorar.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_RELATIVE">
- Impossível obter valor traduzido relativo.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_OUTNAME">
- Impossível obter valor traduzido.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_MATRIX">
- Impossível ler matriz de tradução.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_MERGECHILD">
- Impossível obter nome mergechild.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_MERGEPARENT">
- Impossível obter nome mergeparent.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_PRIORITY">
- Impossível obter valor prioritário.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_LOOP">
- Impossível obter valor do loop.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_EASEIN">
- Impossível obter valor easeIn.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_EASEOUT">
- Impossível obter valor easeOut.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_HAND">
- Impossível obter valor de morph da mão.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_EMOTE">
- Impossível ler nome do emote.
- </floater.string>
- <floater.string name="E_ST_BAD_ROOT">
- Nome da junta incorreto, use &quot;quadril&quot;.
- </floater.string>
- <text name="name_label">
- Nome:
- </text>
- <text name="description_label">
- Descrição:
- </text>
- <spinner label="Prioridade" label_width="72" name="priority" tool_tip="Controla quais animações podem ser interrompidas por esta animação" width="110"/>
- <check_box label="Loop" name="loop_check" tool_tip="Executa esta animação sem parar"/>
- <spinner label="Dentro(%)" label_width="56" left="65" name="loop_in_point" tool_tip="Define o ponto em que a animação em loop reinicia" width="116"/>
- <spinner label="Fora(%)" label_width="40" left="185" name="loop_out_point" tool_tip="Define o ponto em que a animação em loop acaba"/>
- <text name="hand_label">
- Pose de Mão
- </text>
- <combo_box left_delta="100" name="hand_pose_combo" tool_tip="Controla os gestos das mãos durante a animação" width="184">
- <combo_box.item label="Abrir" name="Spread"/>
- <combo_box.item label="Relaxado" name="Relaxed"/>
- <combo_box.item label="Apontar ambas" name="PointBoth"/>
- <combo_box.item label="Punho" name="Fist"/>
- <combo_box.item label="E relaxada" name="RelaxedLeft"/>
- <combo_box.item label="Apontar E" name="PointLeft"/>
- <combo_box.item label="Punho E" name="FistLeft"/>
- <combo_box.item label="D relaxada" name="RelaxedRight"/>
- <combo_box.item label="Apontar D" name="PointRight"/>
- <combo_box.item label="Punho D" name="FistRight"/>
- <combo_box.item label="Saudação D" name="SaluteRight"/>
- <combo_box.item label="Escrevendo" name="Typing"/>
- <combo_box.item label="Paz D" name="PeaceRight"/>
- </combo_box>
- <text name="emote_label">
- Expressão
- </text>
- <combo_box left_delta="100" name="emote_combo" tool_tip="Controla as expressões faciais durante a animação" width="184">
- <item label="(nenhum)" name="[None]" value=""/>
- <item label="Aaaaah" name="Aaaaah" value="Aaaaah"/>
- <item label="Com medo" name="Afraid" value="Com medo"/>
- <item label="Bravo" name="Angry" value="Bravo"/>
- <item label="Sorriso contagiante" name="BigSmile" value="Sorriso contagiante"/>
- <item label="À toa" name="Bored" value="À toa"/>
- <item label="Chorar" name="Cry" value="Chorar"/>
- <item label="Desdenho" name="Disdain" value="Desdenho"/>
- <item label="Com vergonha" name="Embarrassed" value="Com vergonha"/>
- <item label="Franzir testa" name="Frown" value="Franzir testa"/>
- <item label="Beijo" name="Kiss" value="Beijo"/>
- <item label="Rir" name="Laugh" value="Rir"/>
- <item label="Mostrar a língua" name="Plllppt" value="Mostrar a língua"/>
- <item label="Asco" name="Repulsed" value="Asco"/>
- <item label="Triste" name="Sad" value="Triste"/>
- <item label="Encolher os ombros" name="Shrug" value="Encolher os ombros"/>
- <item label="Sorriso" name="Smile" value="Sorriso"/>
- <item label="Surpresa" name="Surprise" value="Surpresa"/>
- <item label="Piscar" name="Wink" value="Piscar"/>
- <item label="Preocupado" name="Worry" value="Preocupado"/>
- </combo_box>
- <text name="preview_label" width="250">
- Prever enquanto
- </text>
- <combo_box left_delta="100" name="preview_base_anim" tool_tip="Use isto para testar o comportamento de sua animação enquanto seu avatar executa ações comuns." width="130">
- <item label="Em pé" name="Standing" value="Em pé"/>
- <item label="Andando" name="Walking" value="Andando"/>
- <item label="Sentado" name="Sitting" value="Sentado"/>
- <item label="Voando" name="Flying" value="Voando"/>
- </combo_box>
- <spinner label="Facilitar a entrada (sec)" label_width="125" name="ease_in_time" tool_tip="Tempo (em segundos) da transição inicial da animação" width="192"/>
- <spinner bottom_delta="-20" label="Facilitar a saída (sec)" label_width="125" left="10" name="ease_out_time" tool_tip="Tempo (em segundos) da transição de saída da animação" width="192"/>
- <button bottom_delta="-32" name="play_btn" tool_tip="Executar animação"/>
- <button name="pause_btn" tool_tip="Pausar a animação"/>
- <button label="" name="stop_btn" tool_tip="Interrompe a execução da animação."/>
- <text name="bad_animation_text">
- Incapaz de ler o arquivo de animação.
-
-Nós recomendamos exportar arquivos BVH do
-Poser 4.
- </text>
- <button label="Carregar (L$[AMOUNT])" name="ok_btn"/>
- <button label="Cancelar" name="cancel_btn"/>
-</floater>
diff --git a/indra/newview/skins/default/xui/pt/floater_auction.xml b/indra/newview/skins/default/xui/pt/floater_auction.xml
index 074f7bf001..074f7bf001 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_auction.xml
+++ b/indra/newview/skins/default/xui/pt/floater_auction.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_autoreplace.xml b/indra/newview/skins/default/xui/pt/floater_autoreplace.xml
new file mode 100755
index 0000000000..ca813a8540
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/floater_autoreplace.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="autoreplace_floater" title="Configurações da substituição automática">
+ <check_box label="Habilitar substituição automática" name="autoreplace_enable" tool_tip="Ao inserir texto de bate-papo, substitua quaisquer palavras-chave inseridas pela substituição correspondente"/>
+ <button label="Importar lista..." name="autoreplace_import_list" tool_tip="Carrega uma lista exportada anteriormente de um arquivo."/>
+ <button label="Exportar lista..." name="autoreplace_export_list" tool_tip="Salva um arquivo da lista selecionada para compartilhá-la."/>
+ <button label="Nova lista..." name="autoreplace_new_list" tool_tip="Cria uma nova lista."/>
+ <button label="Excluir lista" name="autoreplace_delete_list" tool_tip="Exclui a lista selecionada."/>
+ <button name="autoreplace_list_up" tool_tip="Aumenta a prioridade desta lista."/>
+ <button name="autoreplace_list_down" tool_tip="Diminui a prioridade desta lista."/>
+ <scroll_list name="autoreplace_list_replacements">
+ <scroll_list.columns label="Palavra-chave" name="keyword"/>
+ <scroll_list.columns label="Substituição" name="replacement"/>
+ </scroll_list>
+ <button label="Adicionar..." name="autoreplace_add_entry"/>
+ <button label="Remover" name="autoreplace_delete_entry"/>
+ <button label="Salvar entrada" name="autoreplace_save_entry" tool_tip="Salva esta entrada."/>
+ <button label="Salvar alterações" name="autoreplace_save_changes" tool_tip="Salvar todas as alterações."/>
+ <button label="Cancelar" name="autoreplace_cancel" tool_tip="Descarta todas as alterações."/>
+</floater>
+<!--
+ <text
+ top_pad="10"
+ left="10"
+ height="16"
+ width="260"
+ follows="left|top"
+ halign="center"
+ mouse_opaque="true"
+ name="autoreplace_text2">
+ Entries
+ </text>
+-->
diff --git a/indra/newview/skins/default/xui/pt/floater_avatar.xml b/indra/newview/skins/default/xui/pt/floater_avatar.xml
index 168cdacae1..168cdacae1 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_avatar.xml
+++ b/indra/newview/skins/default/xui/pt/floater_avatar.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_avatar_picker.xml b/indra/newview/skins/default/xui/pt/floater_avatar_picker.xml
index 2b65952676..2b65952676 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_avatar_picker.xml
+++ b/indra/newview/skins/default/xui/pt/floater_avatar_picker.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_avatar_textures.xml b/indra/newview/skins/default/xui/pt/floater_avatar_textures.xml
index 9473ee7ce9..9473ee7ce9 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_avatar_textures.xml
+++ b/indra/newview/skins/default/xui/pt/floater_avatar_textures.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_beacons.xml b/indra/newview/skins/default/xui/pt/floater_beacons.xml
index f8ae3cd2d8..f8ae3cd2d8 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_beacons.xml
+++ b/indra/newview/skins/default/xui/pt/floater_beacons.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_build_options.xml b/indra/newview/skins/default/xui/pt/floater_build_options.xml
index acc462ea94..acc462ea94 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_build_options.xml
+++ b/indra/newview/skins/default/xui/pt/floater_build_options.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_bulk_perms.xml b/indra/newview/skins/default/xui/pt/floater_bulk_perms.xml
index 8823d04b62..998fa8b2d6 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_bulk_perms.xml
+++ b/indra/newview/skins/default/xui/pt/floater_bulk_perms.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floaterbulkperms" title="EDITAR AUTORIZAÇÕES DE CONTEÚDO">
+<floater name="floaterbulkperms" title="AJUSTAR PERMISSÕES DE CONTEÚDO">
<floater.string name="nothing_to_modify_text">
A seleção não contém nenhum conteúdo editável.
</floater.string>
@@ -33,7 +33,7 @@
<button label="Tudo" label_selected="Todas" name="check_all"/>
<button label="Limpar" label_selected="Nenhuma" name="check_none"/>
<text name="newperms">
- Novas autorizações de conteúdo
+ Ajustar permissões de conteúdo para
</text>
<text name="GroupLabel">
Grupo:
@@ -49,6 +49,7 @@
<check_box label="Modificar" name="next_owner_modify"/>
<check_box label="Copiar" name="next_owner_copy"/>
<check_box initial_value="true" label="Transferir" name="next_owner_transfer" tool_tip="O próximo dono poderá revender ou dar este objeto"/>
- <button label="OK" name="apply"/>
+ <button label="OK" name="ok"/>
+ <button label="Aplicar" name="apply"/>
<button label="Cancelar" name="close"/>
</floater>
diff --git a/indra/newview/skins/default/xui/pt/floater_bumps.xml b/indra/newview/skins/default/xui/pt/floater_bumps.xml
index 475d36c119..475d36c119 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_bumps.xml
+++ b/indra/newview/skins/default/xui/pt/floater_bumps.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_buy_contents.xml b/indra/newview/skins/default/xui/pt/floater_buy_contents.xml
index b9e7a04412..b9e7a04412 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_buy_contents.xml
+++ b/indra/newview/skins/default/xui/pt/floater_buy_contents.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_buy_currency.xml b/indra/newview/skins/default/xui/pt/floater_buy_currency.xml
index 2845a29e1d..2845a29e1d 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_buy_currency.xml
+++ b/indra/newview/skins/default/xui/pt/floater_buy_currency.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_buy_currency_html.xml b/indra/newview/skins/default/xui/pt/floater_buy_currency_html.xml
index 24e41ac8c8..24e41ac8c8 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_buy_currency_html.xml
+++ b/indra/newview/skins/default/xui/pt/floater_buy_currency_html.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_buy_land.xml b/indra/newview/skins/default/xui/pt/floater_buy_land.xml
index 258c95cc7d..258c95cc7d 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_buy_land.xml
+++ b/indra/newview/skins/default/xui/pt/floater_buy_land.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_buy_object.xml b/indra/newview/skins/default/xui/pt/floater_buy_object.xml
index c465197c9a..c465197c9a 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_buy_object.xml
+++ b/indra/newview/skins/default/xui/pt/floater_buy_object.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_camera.xml b/indra/newview/skins/default/xui/pt/floater_camera.xml
index 9cda01c187..9cda01c187 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_camera.xml
+++ b/indra/newview/skins/default/xui/pt/floater_camera.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_chat_bar.xml b/indra/newview/skins/default/xui/pt/floater_chat_bar.xml
index 72016c6b40..2eb2c94940 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_chat_bar.xml
+++ b/indra/newview/skins/default/xui/pt/floater_chat_bar.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="chat_bar" title="BATE-PAPO LOCAL">
+<floater name="nearby_chat" title="BATE-PAPO LOCAL">
<panel name="bottom_panel">
<line_editor label="Clique aqui para bater papo." name="chat_box" tool_tip="Tecle Enter para falar, Ctrl+Enter para gritar"/>
<button name="show_nearby_chat" tool_tip="Mostra/oculta o histórico do bate-papo local"/>
diff --git a/indra/newview/skins/default/xui/pt/floater_choose_group.xml b/indra/newview/skins/default/xui/pt/floater_choose_group.xml
index 60f01a3733..60f01a3733 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_choose_group.xml
+++ b/indra/newview/skins/default/xui/pt/floater_choose_group.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_color_picker.xml b/indra/newview/skins/default/xui/pt/floater_color_picker.xml
index 4ea014335f..4ea014335f 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_color_picker.xml
+++ b/indra/newview/skins/default/xui/pt/floater_color_picker.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_conversation_log.xml b/indra/newview/skins/default/xui/pt/floater_conversation_log.xml
new file mode 100644
index 0000000000..ae7dd3c441
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/floater_conversation_log.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="floater_conversation_log" title="REGISTRO DE CONVERSA">
+ <panel name="buttons_panel">
+ <filter_editor label="Filtrar pessoas" name="people_filter_input"/>
+ <menu_button name="conversation_view_btn" tool_tip="Opções de exibição/ordenação"/>
+ <menu_button name="conversations_gear_btn" tool_tip="Ações em uma pessoa ou um grupo selecionado"/>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/pt/floater_conversation_preview.xml b/indra/newview/skins/default/xui/pt/floater_conversation_preview.xml
new file mode 100644
index 0000000000..97a2e8327c
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/floater_conversation_preview.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="preview_conversation" title="CONVERSA:">
+ <floater.string name="Title">
+ CONVERSA: [NAME]
+ </floater.string>
+ <text name="page_label" value="Página"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/pt/floater_critical.xml b/indra/newview/skins/default/xui/pt/floater_critical.xml
index 5d7fe0142b..5d7fe0142b 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_critical.xml
+++ b/indra/newview/skins/default/xui/pt/floater_critical.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_delete_env_preset.xml b/indra/newview/skins/default/xui/pt/floater_delete_env_preset.xml
index a8b5d8f67d..a8b5d8f67d 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_delete_env_preset.xml
+++ b/indra/newview/skins/default/xui/pt/floater_delete_env_preset.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_destinations.xml b/indra/newview/skins/default/xui/pt/floater_destinations.xml
index df18698d2f..df18698d2f 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_destinations.xml
+++ b/indra/newview/skins/default/xui/pt/floater_destinations.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_display_name.xml b/indra/newview/skins/default/xui/pt/floater_display_name.xml
index 8daa40cc23..8daa40cc23 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_display_name.xml
+++ b/indra/newview/skins/default/xui/pt/floater_display_name.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_edit_day_cycle.xml b/indra/newview/skins/default/xui/pt/floater_edit_day_cycle.xml
index 9e25938986..9e25938986 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_edit_day_cycle.xml
+++ b/indra/newview/skins/default/xui/pt/floater_edit_day_cycle.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_edit_sky_preset.xml b/indra/newview/skins/default/xui/pt/floater_edit_sky_preset.xml
index 1f1fbcce7e..1f1fbcce7e 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_edit_sky_preset.xml
+++ b/indra/newview/skins/default/xui/pt/floater_edit_sky_preset.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_edit_water_preset.xml b/indra/newview/skins/default/xui/pt/floater_edit_water_preset.xml
index 7bde22851e..7bde22851e 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_edit_water_preset.xml
+++ b/indra/newview/skins/default/xui/pt/floater_edit_water_preset.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_environment_settings.xml b/indra/newview/skins/default/xui/pt/floater_environment_settings.xml
index 4055ba97ef..4055ba97ef 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_environment_settings.xml
+++ b/indra/newview/skins/default/xui/pt/floater_environment_settings.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_event.xml b/indra/newview/skins/default/xui/pt/floater_event.xml
index a8dc3f96d7..a8dc3f96d7 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_event.xml
+++ b/indra/newview/skins/default/xui/pt/floater_event.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_fast_timers.xml b/indra/newview/skins/default/xui/pt/floater_fast_timers.xml
index eeb39583ef..eeb39583ef 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_fast_timers.xml
+++ b/indra/newview/skins/default/xui/pt/floater_fast_timers.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_font_test.xml b/indra/newview/skins/default/xui/pt/floater_font_test.xml
index c506cdb12d..c506cdb12d 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_font_test.xml
+++ b/indra/newview/skins/default/xui/pt/floater_font_test.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_gesture.xml b/indra/newview/skins/default/xui/pt/floater_gesture.xml
index 2e5b92aaf7..2e5b92aaf7 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_gesture.xml
+++ b/indra/newview/skins/default/xui/pt/floater_gesture.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_god_tools.xml b/indra/newview/skins/default/xui/pt/floater_god_tools.xml
index 8003a35d16..8003a35d16 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_god_tools.xml
+++ b/indra/newview/skins/default/xui/pt/floater_god_tools.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_goto_line.xml b/indra/newview/skins/default/xui/pt/floater_goto_line.xml
new file mode 100644
index 0000000000..f2ef825ba0
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/floater_goto_line.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="script goto" title="IR PARA A LINHA">
+ <button label="OK" label_selected="OK" name="goto_btn"/>
+ <text name="txt">
+ Ir para a linha
+ </text>
+</floater>
diff --git a/indra/newview/skins/default/xui/pt/floater_hardware_settings.xml b/indra/newview/skins/default/xui/pt/floater_hardware_settings.xml
index 1bc2bce768..1204fb93e2 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_hardware_settings.xml
+++ b/indra/newview/skins/default/xui/pt/floater_hardware_settings.xml
@@ -25,6 +25,10 @@
Habilitar VBO:
</text>
<check_box initial_value="true" label="Habilitar Objetos com Armazenamento de Vértices" name="vbo" tool_tip="Habilitando-o em máquinas novas, ele oferece um ganho de performance. Contudo, as máquinas antigas tem freqüentemente implementações pobres de VBOs e você pode ter travamentos quando esta opção é habilitada."/>
+ <text name="tc label">
+ Habilitar S3TC:
+ </text>
+ <check_box initial_value="true" label="Habilitar compressão de texturas (requer reinício)" name="texture compression" tool_tip="Comprime as texturas na memória de vídeo, permitindo o carregamento de texturas de maior resolução em detrimento da qualidade da cor."/>
<slider label="Memória de texturas (MB):" name="GraphicsCardTextureMemory" tool_tip="Quanto da memória deve ser alocado para texturas. O padrão é definido pela memória da placa de vídeo. Reduzir este valor pode melhorar o desempenho, mas as texturas podem fica fora de foco."/>
<spinner label="Relação de Distância de Nevoeiro:" name="fog"/>
<button label="OK" label_selected="OK" name="OK"/>
diff --git a/indra/newview/skins/default/xui/pt/floater_help_browser.xml b/indra/newview/skins/default/xui/pt/floater_help_browser.xml
index 9cc8a0a6b2..9cc8a0a6b2 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_help_browser.xml
+++ b/indra/newview/skins/default/xui/pt/floater_help_browser.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_how_to.xml b/indra/newview/skins/default/xui/pt/floater_how_to.xml
index 15c4946cb0..15c4946cb0 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_how_to.xml
+++ b/indra/newview/skins/default/xui/pt/floater_how_to.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_hud.xml b/indra/newview/skins/default/xui/pt/floater_hud.xml
index e458913452..e458913452 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_hud.xml
+++ b/indra/newview/skins/default/xui/pt/floater_hud.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_im_container.xml b/indra/newview/skins/default/xui/pt/floater_im_container.xml
index 0fbb826a96..a1cea72b1e 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_im_container.xml
+++ b/indra/newview/skins/default/xui/pt/floater_im_container.xml
@@ -1,2 +1,29 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<multi_floater name="floater_im_box" title="CONVERSAS"/>
+<multi_floater name="floater_im_box" title="CONVERSAS">
+ <string name="collapse_icon" value="Conv_toolbar_collapse"/>
+ <string name="expand_icon" value="Conv_toolbar_expand"/>
+ <layout_stack name="conversations_stack">
+ <layout_panel name="conversations_layout_panel">
+ <layout_stack name="conversations_pane_buttons_stack">
+ <layout_panel name="conversations_pane_buttons_expanded">
+ <menu_button name="sort_btn" tool_tip="Opções de exibição/ordenação"/>
+ <button name="add_btn" tool_tip="Iniciar uma nova conversa"/>
+ <button name="speak_btn" tool_tip="Fale com pessoas usando seu microfone"/>
+ </layout_panel>
+ <layout_panel name="conversations_pane_buttons_collapsed">
+ <button name="expand_collapse_btn" tool_tip="Recolher/expandir esta lista"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ <layout_panel name="messages_layout_panel">
+ <panel_container name="im_box_tab_container">
+ <panel name="stub_panel">
+ <button name="stub_collapse_btn" tool_tip="Recolher este painel"/>
+ <text name="stub_textbox">
+ Esta conversa está em uma janela separada. [secondlife:/// Trazer de volta.]
+ </text>
+ </panel>
+ </panel_container>
+ </layout_panel>
+ </layout_stack>
+</multi_floater>
diff --git a/indra/newview/skins/default/xui/pt/floater_im_session.xml b/indra/newview/skins/default/xui/pt/floater_im_session.xml
index 5543ffa41d..e592b14fa7 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/pt/floater_im_session.xml
@@ -1,8 +1,57 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="panel_im">
- <layout_stack name="im_panels">
- <layout_panel>
- <line_editor label="Para" name="chat_editor"/>
- </layout_panel>
- </layout_stack>
+ <floater.string name="call_btn_start">
+ Conv_toolbar_open_call
+ </floater.string>
+ <floater.string name="call_btn_stop">
+ Conv_toolbar_hang_up
+ </floater.string>
+ <floater.string name="collapseline_icon" value="Conv_collapse_to_one_line"/>
+ <floater.string name="expandline_icon" value="Conv_expand_one_line"/>
+ <floater.string name="collapse_icon" value="Conv_toolbar_collapse"/>
+ <floater.string name="expand_icon" value="Conv_toolbar_expand"/>
+ <floater.string name="tear_off_icon" value="Conv_toolbar_arrow_ne"/>
+ <floater.string name="return_icon" value="Conv_toolbar_arrow_sw"/>
+ <floater.string name="participant_added" value="[NAME] foi convidado para a conversa."/>
+ <floater.string name="multiple_participants_added" value="[NAME] foram convidados para a conversa."/>
+ <floater.string name="tooltip_to_separate_window" value="Mover esta conversa para uma janela separada"/>
+ <floater.string name="tooltip_to_main_window" value="Mover esta conversa para a janela principal"/>
+ <floater.string name="start_call_button_tooltip" value="Abrir conexão por voz"/>
+ <floater.string name="end_call_button_tooltip" value="Encerrar conexão por voz"/>
+ <floater.string name="expcol_button_not_tearoff_tooltip" value="Recolher este painel"/>
+ <floater.string name="expcol_button_tearoff_and_expanded_tooltip" value="Recolher lista de participantes"/>
+ <floater.string name="expcol_button_tearoff_and_collapsed_tooltip" value="Expandir a lista de participantes"/>
+ <view name="contents_view">
+ <layout_stack name="main_stack">
+ <layout_panel name="toolbar_panel">
+ <menu_button name="view_options_btn" tool_tip="Opções de exibição/ordenação"/>
+ <menu_button name="gear_btn" tool_tip="Ações nas pessoas selecionadas"/>
+ <button name="add_btn" tool_tip="Adicionar alguém a esta conversa"/>
+ <button name="voice_call_btn" tool_tip="Abrir conexão por voz"/>
+ <button name="close_btn" tool_tip="Encerrar esta conversa"/>
+ <button name="expand_collapse_btn" tool_tip="Recolher/expandir este painel"/>
+ </layout_panel>
+ <layout_panel name="body_panel">
+ <layout_stack name="im_panels">
+ <layout_panel name="right_part_holder">
+ <layout_stack name="translate_and_chat_stack">
+ <layout_panel name="translate_chat_checkbox_lp">
+ <check_box label="Traduzir conversa" name="translate_chat_checkbox"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ <layout_panel name="chat_layout_panel">
+ <layout_stack name="input_panels">
+ <layout_panel name="input_editor_layout_panel">
+ <chat_editor label="Para" name="chat_editor"/>
+ </layout_panel>
+ <layout_panel name="input_button_layout_panel">
+ <button name="minz_btn" tool_tip="Mostrar/ocultar painel de mensagens"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
+ </view>
</floater>
diff --git a/indra/newview/skins/default/xui/pt/floater_image_preview.xml b/indra/newview/skins/default/xui/pt/floater_image_preview.xml
index 362a553d64..362a553d64 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_image_preview.xml
+++ b/indra/newview/skins/default/xui/pt/floater_image_preview.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_import_collada.xml b/indra/newview/skins/default/xui/pt/floater_import_collada.xml
index ad55d416c3..ad55d416c3 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_import_collada.xml
+++ b/indra/newview/skins/default/xui/pt/floater_import_collada.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_incoming_call.xml b/indra/newview/skins/default/xui/pt/floater_incoming_call.xml
index 6344258fa0..1e86f847ad 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_incoming_call.xml
+++ b/indra/newview/skins/default/xui/pt/floater_incoming_call.xml
@@ -25,9 +25,9 @@
Sair do [CURRENT_CHAT] e entrar neste bate-papo de voz?
</floater.string>
<text name="question">
- Sair do [CURRENT_CHAT] e entrar neste bate-papo?
+ Se você atender, será desconectado de suas conversas de voz atuais.
</text>
- <button label="Aceitar" label_selected="Aceitar" name="Accept"/>
- <button label="Rejeitar" label_selected="Rejeitar" name="Reject"/>
- <button label="Enviar MI" name="Start IM"/>
+ <button label="Atender" label_selected="Atender" name="Accept"/>
+ <button label="Ignorar" label_selected="Ignorar" name="Reject"/>
+ <button label="Iniciar MI em vez disso" name="Start IM"/>
</floater>
diff --git a/indra/newview/skins/default/xui/pt/floater_inspect.xml b/indra/newview/skins/default/xui/pt/floater_inspect.xml
index 6a00b1a628..6a00b1a628 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_inspect.xml
+++ b/indra/newview/skins/default/xui/pt/floater_inspect.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_inventory.xml b/indra/newview/skins/default/xui/pt/floater_inventory.xml
deleted file mode 100644
index ae3312eab0..0000000000
--- a/indra/newview/skins/default/xui/pt/floater_inventory.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Inventory" title="MEU INVENTÃRIO">
- <floater.string name="Title">
- MEU INVENTÃRIO
- </floater.string>
- <floater.string name="TitleFetching">
- MEU INVENTÃRIO (Pegando [ITEM_COUNT] items...) [FILTER]
- </floater.string>
- <floater.string name="TitleCompleted">
- MEU INVENTÃRIO ([ITEM_COUNT] items) [FILTER]
- </floater.string>
- <floater.string name="Fetched">
- Obtido
- </floater.string>
- <panel label="Painel do inventário" name="Inventory Panel"/>
-</floater>
diff --git a/indra/newview/skins/default/xui/pt/floater_inventory_item_properties.xml b/indra/newview/skins/default/xui/pt/floater_inventory_item_properties.xml
index 8a8f1f5b34..8a8f1f5b34 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_inventory_item_properties.xml
+++ b/indra/newview/skins/default/xui/pt/floater_inventory_item_properties.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_inventory_view_finder.xml b/indra/newview/skins/default/xui/pt/floater_inventory_view_finder.xml
index 71759abdc2..71759abdc2 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_inventory_view_finder.xml
+++ b/indra/newview/skins/default/xui/pt/floater_inventory_view_finder.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_joystick.xml b/indra/newview/skins/default/xui/pt/floater_joystick.xml
index 98d8c0e319..98d8c0e319 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_joystick.xml
+++ b/indra/newview/skins/default/xui/pt/floater_joystick.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_lagmeter.xml b/indra/newview/skins/default/xui/pt/floater_lagmeter.xml
index 9932318293..9932318293 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_lagmeter.xml
+++ b/indra/newview/skins/default/xui/pt/floater_lagmeter.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_land_holdings.xml b/indra/newview/skins/default/xui/pt/floater_land_holdings.xml
index 7475bdd5b8..7475bdd5b8 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_land_holdings.xml
+++ b/indra/newview/skins/default/xui/pt/floater_land_holdings.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_live_lsleditor.xml b/indra/newview/skins/default/xui/pt/floater_live_lsleditor.xml
index 5ad116ac8a..5ad116ac8a 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_live_lsleditor.xml
+++ b/indra/newview/skins/default/xui/pt/floater_live_lsleditor.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_lsl_guide.xml b/indra/newview/skins/default/xui/pt/floater_lsl_guide.xml
index 73f187f0e4..73f187f0e4 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_lsl_guide.xml
+++ b/indra/newview/skins/default/xui/pt/floater_lsl_guide.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_map.xml b/indra/newview/skins/default/xui/pt/floater_map.xml
index 8233f2a43f..8233f2a43f 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_map.xml
+++ b/indra/newview/skins/default/xui/pt/floater_map.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_media_browser.xml b/indra/newview/skins/default/xui/pt/floater_media_browser.xml
index 7491218067..7491218067 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_media_browser.xml
+++ b/indra/newview/skins/default/xui/pt/floater_media_browser.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_media_settings.xml b/indra/newview/skins/default/xui/pt/floater_media_settings.xml
index 5af002c502..5af002c502 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_media_settings.xml
+++ b/indra/newview/skins/default/xui/pt/floater_media_settings.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_mem_leaking.xml b/indra/newview/skins/default/xui/pt/floater_mem_leaking.xml
index efb5da4ace..efb5da4ace 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_mem_leaking.xml
+++ b/indra/newview/skins/default/xui/pt/floater_mem_leaking.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_merchant_outbox.xml b/indra/newview/skins/default/xui/pt/floater_merchant_outbox.xml
index bb6113671b..bb6113671b 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_merchant_outbox.xml
+++ b/indra/newview/skins/default/xui/pt/floater_merchant_outbox.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_model_preview.xml b/indra/newview/skins/default/xui/pt/floater_model_preview.xml
index 8960500831..8194278b16 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_model_preview.xml
+++ b/indra/newview/skins/default/xui/pt/floater_model_preview.xml
@@ -92,19 +92,54 @@
<text initial_value="Triângulos" name="triangles" value="Triângulos"/>
<text initial_value="Vértices" name="vertices" value="Vértices"/>
<text initial_value="Alto" name="high_label" value="Alto"/>
+ <combo_box name="lod_source_high">
+ <item name="Load from file" value="Carregar do arquivo"/>
+ <item name="Generate" value="Gerar"/>
+ </combo_box>
<button label="Procurar..." name="lod_browse_high"/>
+ <combo_box name="lod_mode_high">
+ <item name="Triangle Limit" value="Limite de triângulos"/>
+ <item name="Error Threshold" value="Limite de erro"/>
+ </combo_box>
<text initial_value="0" name="high_triangles" value="0"/>
<text initial_value="0" name="high_vertices" value="0"/>
<text initial_value="Médio" name="medium_label" value="Médio"/>
+ <combo_box name="lod_source_medium">
+ <item name="Load from file" value="Carregar do arquivo"/>
+ <item name="Generate" value="Gerar"/>
+ <item name="Use LoD above" value="Usar LoD acima"/>
+ </combo_box>
<button label="Procurar..." name="lod_browse_medium"/>
+ <combo_box name="lod_mode_medium">
+ <item name="Triangle Limit" value="Limite de triângulos"/>
+ <item name="Error Threshold" value="Limite de erro"/>
+ </combo_box>
<text initial_value="0" name="medium_triangles" value="0"/>
<text initial_value="0" name="medium_vertices" value="0"/>
<text initial_value="Baixo" name="low_label" value="Baixo"/>
+ <combo_box name="lod_source_low">
+ <item name="Load from file" value="Carregar do arquivo"/>
+ <item name="Generate" value="Gerar"/>
+ <item name="Use LoD above" value="Usar LoD acima"/>
+ </combo_box>
<button label="Procurar..." name="lod_browse_low"/>
+ <combo_box name="lod_mode_low">
+ <item name="Triangle Limit" value="Limite de triângulos"/>
+ <item name="Error Threshold" value="Limite de erro"/>
+ </combo_box>
<text initial_value="0" name="low_triangles" value="0"/>
<text initial_value="0" name="low_vertices" value="0"/>
<text initial_value="Mais baixo" name="lowest_label" value="Mais baixo"/>
+ <combo_box name="lod_source_lowest">
+ <item name="Load from file" value="Carregar do arquivo"/>
+ <item name="Generate" value="Gerar"/>
+ <item name="Use LoD above" value="Usar LoD acima"/>
+ </combo_box>
<button label="Procurar..." name="lod_browse_lowest"/>
+ <combo_box name="lod_mode_lowest">
+ <item name="Triangle Limit" value="Limite de triângulos"/>
+ <item name="Error Threshold" value="Limite de erro"/>
+ </combo_box>
<text initial_value="0" name="lowest_triangles" value="0"/>
<text initial_value="0" name="lowest_vertices" value="0"/>
<check_box label="Gerar normais" name="gen_normals"/>
diff --git a/indra/newview/skins/default/xui/pt/floater_model_wizard.xml b/indra/newview/skins/default/xui/pt/floater_model_wizard.xml
deleted file mode 100644
index 0d07303c91..0000000000
--- a/indra/newview/skins/default/xui/pt/floater_model_wizard.xml
+++ /dev/null
@@ -1,208 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Model Wizard" title="CARREGAR ASSISTENTE DE MODELAGEM">
- <button label="5. Carregar" name="upload_btn"/>
- <button label="4. Revisar" name="review_btn"/>
- <button label="3. Física" name="physics_btn"/>
- <button label="2. Otimizar" name="optimize_btn"/>
- <button label="1. Selecionra arquivo" name="choose_file_btn"/>
- <panel name="choose_file_panel">
- <panel name="choose_file_header_panel">
- <text name="choose_file_header_text">
- Escolher arquivo de modelo
- </text>
- </panel>
- <panel name="choose_file_content">
- <text name="advanced_users_text">
- Usuários avançados: se você estiver familiarizado com ferramentas de criação de conteúdo 3D, use o Advanced Uploader.
- </text>
- <button label="Trocar para avançado" name="switch_to_advanced"/>
- <text name="Cache location">
- Escolha o arquivo de modelo para upload
- </text>
- <button label="Procurar..." label_selected="Procurar..." name="browse"/>
- <text name="Model types">
- O Second Life oferece suporte a arquivos COLLADA (.dae)
- </text>
- <text name="dimensions">
- X Y Z
- </text>
- <text name="warning_label">
- AVISO:
- </text>
- <text name="warning_text">
- Não será possível concluir a etapa final do upload desse modelo para os servidores do Second Life. [secondlife:///app/floater/learn_more Saiba como] configurar sua conta para uploads de modelos mesh.
- </text>
- </panel>
- </panel>
- <panel name="optimize_panel">
- <panel name="optimize_header_panel">
- <text name="optimize_header_text">
- Otimizar modelo
- </text>
- </panel>
- <text name="optimize_description">
- O modelo foi ajustado para desempenho. Faça novos ajustes, se desejar.
- </text>
- <panel name="optimize_content">
- <text name="high_detail_text">
- Gerar nível de detalhes: Alto
- </text>
- <text name="medium_detail_text">
- Gerar nível de detalhes: Médio
- </text>
- <text name="low_detail_text">
- Gerar nível de detalhes: Baixo
- </text>
- <text name="lowest_detail_text">
- Gerar nível de detalhes: Mais baixo
- </text>
- </panel>
- <panel name="content2">
- <button label="Recalcular geometria" name="recalculate_geometry_btn"/>
- <text name="lod_label">
- Visualização da geometria
- </text>
- <combo_box name="preview_lod_combo" tool_tip="LOD para exibir na renderização de visualização">
- <combo_item name="high">
- Máximo de detalhes
- </combo_item>
- <combo_item name="medium">
- Detalhes médios
- </combo_item>
- <combo_item name="low">
- Poucos detalhes
- </combo_item>
- <combo_item name="lowest">
- Mínimo de detalhes
- </combo_item>
- </combo_box>
- </panel>
- </panel>
- <panel name="physics_panel">
- <panel name="physics_header_panel">
- <text name="physics_header_text">
- Ajustar físico
- </text>
- </panel>
- <text name="physics_description">
- Criaremos uma forma para o corpo externo do modelo. Ajuste o nível de detalhes como necessário para a finalidade desejada de seu modelo.
- </text>
- <panel name="physics_content">
- <button label="Recalcular físico" name="recalculate_physics_btn"/>
- <button label="Recalculando..." name="recalculating_physics_btn"/>
- <text name="lod_label">
- Visualização do físico
- </text>
- <combo_box name="preview_lod_combo2" tool_tip="LOD para exibir na renderização de visualização">
- <combo_item name="high">
- Máximo de detalhes
- </combo_item>
- <combo_item name="medium">
- Detalhes médios
- </combo_item>
- <combo_item name="low">
- Poucos detalhes
- </combo_item>
- <combo_item name="lowest">
- Mínimo de detalhes
- </combo_item>
- </combo_box>
- </panel>
- </panel>
- <panel name="review_panel">
- <panel name="review_header_panel">
- <text name="review_header_text">
- Revisar
- </text>
- </panel>
- <panel name="review_content">
- <text name="review_prim_equiv">
- Impacto no lote/região: [EQUIV] equivalentes de prim
- </text>
- <text name="review_fee">
- Uma tarifa de upload de L$ [FEE] será debitada da sua conta.
- </text>
- <text name="review_confirmation">
- Ao clicar no botão de upload, você confirma que detém os direitos apropriados sobre o material contido no modelo.
- </text>
- </panel>
- </panel>
- <panel name="upload_panel">
- <panel name="upload_header_panel">
- <text name="upload_header_text">
- Upload concluído
- </text>
- </panel>
- <text name="model_uploaded_text">
- Seu modelo foi carregado.
- </text>
- <text name="inventory_text">
- Disponível na pasta Objetos do seu inventário.
- </text>
- <text name="charged_fee">
- L$ [FEE] foram debitados da sua conta.
- </text>
- </panel>
- <button label="&lt;&lt; Voltar" name="back"/>
- <button label="Próximo &gt;&gt;" name="next"/>
- <button label="Calcular pesos e tarifa &gt;&gt;" name="calculate"/>
- <button label="Calculando..." name="calculating"/>
- <button label="Carregar" name="upload" tool_tip="Carregar no simulador"/>
- <button label="Cancelar" name="cancel"/>
- <button label="Fechar" name="close"/>
- <spinner name="import_scale" value="1.0"/>
- <string name="status_idle">
- Inativo
- </string>
- <string name="status_parse_error">
- Dae parsing - erro, detalhes no log.
- </string>
- <string name="status_reading_file">
- Carregando...
- </string>
- <string name="status_generating_meshes">
- Gerando meshes...
- </string>
- <string name="status_vertex_number_overflow">
- Erro: Número de Vertex acima de 65534. Abortado.
- </string>
- <string name="bad_element">
- Erro: elemento inválido
- </string>
- <string name="high">
- Alto
- </string>
- <string name="medium">
- Médio
- </string>
- <string name="low">
- Baixo
- </string>
- <string name="lowest">
- Mais baixo
- </string>
- <string name="mesh_status_good">
- Entregar!
- </string>
- <string name="mesh_status_na">
- N/D
- </string>
- <string name="mesh_status_none">
- Nenhum
- </string>
- <string name="mesh_status_submesh_mismatch">
- Cada nível de detalhamento têm um número de faces para textura.
- </string>
- <string name="mesh_status_mesh_mismatch">
- Cada nível de detalhamento têm um número de faces para textura.
- </string>
- <string name="mesh_status_too_many_vertices">
- O nível de detalhamento possui vértices demais.
- </string>
- <string name="mesh_status_missing_lod">
- Falta o nível de detalhamento necessário.
- </string>
- <string name="layer_all">
- Tudo
- </string>
-</floater>
diff --git a/indra/newview/skins/default/xui/pt/floater_moveview.xml b/indra/newview/skins/default/xui/pt/floater_moveview.xml
index 728357a400..728357a400 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_moveview.xml
+++ b/indra/newview/skins/default/xui/pt/floater_moveview.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_mute_object.xml b/indra/newview/skins/default/xui/pt/floater_mute_object.xml
index 97fbd35fcc..97fbd35fcc 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_mute_object.xml
+++ b/indra/newview/skins/default/xui/pt/floater_mute_object.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_my_appearance.xml b/indra/newview/skins/default/xui/pt/floater_my_appearance.xml
index 38e06d2aed..38e06d2aed 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_my_appearance.xml
+++ b/indra/newview/skins/default/xui/pt/floater_my_appearance.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_my_inventory.xml b/indra/newview/skins/default/xui/pt/floater_my_inventory.xml
index 71d8682758..71d8682758 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_my_inventory.xml
+++ b/indra/newview/skins/default/xui/pt/floater_my_inventory.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_nearby_chat.xml b/indra/newview/skins/default/xui/pt/floater_nearby_chat.xml
deleted file mode 100644
index 653861f7d8..0000000000
--- a/indra/newview/skins/default/xui/pt/floater_nearby_chat.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="nearby_chat" title="Bate-papo local">
- <check_box label="Traduzir bate-papo" name="translate_chat_checkbox"/>
-</floater>
diff --git a/indra/newview/skins/default/xui/pt/floater_object_weights.xml b/indra/newview/skins/default/xui/pt/floater_object_weights.xml
index 45bd1c7127..45bd1c7127 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_object_weights.xml
+++ b/indra/newview/skins/default/xui/pt/floater_object_weights.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_openobject.xml b/indra/newview/skins/default/xui/pt/floater_openobject.xml
index 0dc2852bac..0dc2852bac 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_openobject.xml
+++ b/indra/newview/skins/default/xui/pt/floater_openobject.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_outfit_save_as.xml b/indra/newview/skins/default/xui/pt/floater_outfit_save_as.xml
index 60d4d3dc5c..60d4d3dc5c 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_outfit_save_as.xml
+++ b/indra/newview/skins/default/xui/pt/floater_outfit_save_as.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_outgoing_call.xml b/indra/newview/skins/default/xui/pt/floater_outgoing_call.xml
index 35afde7612..35afde7612 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_outgoing_call.xml
+++ b/indra/newview/skins/default/xui/pt/floater_outgoing_call.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_pathfinding_characters.xml b/indra/newview/skins/default/xui/pt/floater_pathfinding_characters.xml
new file mode 100755
index 0000000000..05784115e7
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/floater_pathfinding_characters.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="floater_pathfinding_characters" title="Personagens do pathfinding">
+ <floater.string name="messaging_get_inprogress">
+ Procurando por personagens do pathfinding...
+ </floater.string>
+ <floater.string name="messaging_get_error">
+ Erro detectado ao procurar por personagens do pathfinding.
+ </floater.string>
+ <floater.string name="messaging_complete_none_found">
+ Nenhum personagem do pathfinding.
+ </floater.string>
+ <floater.string name="messaging_complete_available">
+ [NUM_SELECTED] personagens selecionados de [NUM_TOTAL].
+ </floater.string>
+ <floater.string name="messaging_not_enabled">
+ Esta região não está habilitada para pathfinding.
+ </floater.string>
+ <floater.string name="character_cpu_time">
+ [CPU_TIME] µs
+ </floater.string>
+ <floater.string name="character_owner_loading">
+ [Carregando]
+ </floater.string>
+ <floater.string name="character_owner_unknown">
+ [Desconhecido]
+ </floater.string>
+ <floater.string name="character_owner_group">
+ [grupo]
+ </floater.string>
+ <panel>
+ <scroll_list name="objects_scroll_list">
+ <scroll_list.columns label="Nome" name="name"/>
+ <scroll_list.columns label="Descrição" name="description"/>
+ <scroll_list.columns label="Proprietário" name="owner"/>
+ <scroll_list.columns label="CPU" name="cpu_time"/>
+ <scroll_list.columns label="Altitude" name="altitude"/>
+ </scroll_list>
+ <text name="messaging_status">
+ Personagens:
+ </text>
+ <button label="Atualizar lista" name="refresh_objects_list"/>
+ <button label="Selecionar tudo" name="select_all_objects"/>
+ <button label="Selecionar nenhum" name="select_none_objects"/>
+ </panel>
+ <panel>
+ <text name="actions_label">
+ Ações nos personagens selecionados:
+ </text>
+ <check_box label="Exibir baliza" name="show_beacon"/>
+ <check_box label="Exibir cápsula da física" name="show_physics_capsule"/>
+ <button label="Pegar" name="take_objects"/>
+ <button label="Pegar uma cópia" name="take_copy_objects"/>
+ <button label="Teletransportar-me até ele" name="teleport_me_to_object" tool_tip="Habilitado apenas quando um personagem é selecionado."/>
+ <button label="Devolver" name="return_objects"/>
+ <button label="Excluir" name="delete_objects"/>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/pt/floater_pathfinding_console.xml b/indra/newview/skins/default/xui/pt/floater_pathfinding_console.xml
new file mode 100755
index 0000000000..182f2513e0
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/floater_pathfinding_console.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="floater_pathfinding_console" title="Visualização/teste do pathfinding">
+ <floater.string name="navmesh_viewer_status_library_not_implemented">
+ Impossível encontrar a implementação de biblioteca de pathing.
+ </floater.string>
+ <floater.string name="navmesh_viewer_status_region_not_enabled">
+ Esta região não está habilitada para pathfinding.
+ </floater.string>
+ <floater.string name="navmesh_viewer_status_region_loading">
+ Aguardando a conclusão do carregamento da região.
+ </floater.string>
+ <floater.string name="navmesh_viewer_status_checking_version">
+ Verificando o status do navmesh.
+ </floater.string>
+ <floater.string name="navmesh_viewer_status_downloading">
+ Baixando o navmesh.
+ </floater.string>
+ <floater.string name="navmesh_viewer_status_updating">
+ O navmesh foi alterado no servidor. Baixando o navmesh mais recente.
+ </floater.string>
+ <floater.string name="navmesh_viewer_status_has_navmesh">
+ O navmesh mais recente foi baixado.
+ </floater.string>
+ <floater.string name="navmesh_viewer_status_error">
+ Impossível baixar o navmesh com êxito.
+ </floater.string>
+ <floater.string name="navmesh_simulator_status_pending">
+ O navmesh tem alterações pendentes.
+ </floater.string>
+ <floater.string name="navmesh_simulator_status_building">
+ O navmesh está compilando.
+ </floater.string>
+ <floater.string name="navmesh_simulator_status_some_pending">
+ Algumas regiões navmesh têm alterações pendentes.
+ </floater.string>
+ <floater.string name="navmesh_simulator_status_some_building">
+ Algumas regiões navmesh estão compilando.
+ </floater.string>
+ <floater.string name="navmesh_simulator_status_pending_and_building">
+ Algumas regiões navmesh têm alterações pendentes e outras estão compilando.
+ </floater.string>
+ <floater.string name="navmesh_simulator_status_complete">
+ O navmesh está atualizado.
+ </floater.string>
+ <floater.string name="pathing_library_not_implemented">
+ Impossível encontrar a implementação de biblioteca de pathing.
+ </floater.string>
+ <floater.string name="pathing_region_not_enabled">
+ Esta região não está habilitada para pathfinding.
+ </floater.string>
+ <floater.string name="pathing_choose_start_and_end_points">
+ Escolha os pontos inicial e final.
+ </floater.string>
+ <floater.string name="pathing_choose_start_point">
+ Escolha o ponto inicial.
+ </floater.string>
+ <floater.string name="pathing_choose_end_point">
+ Escolha o ponto final.
+ </floater.string>
+ <floater.string name="pathing_path_valid">
+ O caminho é exibido em laranja.
+ </floater.string>
+ <floater.string name="pathing_path_invalid">
+ Impossível encontrar um caminho entre os pontos escolhidos.
+ </floater.string>
+ <floater.string name="pathing_error">
+ Ocorreu um erro durante a geração do caminho.
+ </floater.string>
+ <tab_container name="view_test_tab_container">
+ <panel label="Visualizar" name="view_panel">
+ <text name="show_label">
+ Exibir:
+ </text>
+ <check_box label="Mundo" name="show_world"/>
+ <check_box label="Apenas móveis" name="show_world_movables_only"/>
+ <check_box label="Navmesh" name="show_navmesh"/>
+ <text name="show_walkability_label">
+ Exibir mapa de possibilidade de caminhar:
+ </text>
+ <combo_box name="show_heatmap_mode">
+ <combo_box.item label="Não exibir" name="show_heatmap_mode_none"/>
+ <combo_box.item label="Tipo de personagem A" name="show_heatmap_mode_a"/>
+ <combo_box.item label="Tipo de personagem B" name="show_heatmap_mode_b"/>
+ <combo_box.item label="Tipo de personagem C" name="show_heatmap_mode_c"/>
+ <combo_box.item label="Tipo de personagem D" name="show_heatmap_mode_d"/>
+ </combo_box>
+ <check_box label="Caminháveis" name="show_walkables"/>
+ <check_box label="Volumes materiais" name="show_material_volumes"/>
+ <check_box label="Obstáculos estáticos" name="show_static_obstacles"/>
+ <check_box label="Volumes de exclusão" name="show_exclusion_volumes"/>
+ <check_box label="Plano aquático" name="show_water_plane"/>
+ <check_box label="Com visão de raio X" name="show_xray"/>
+ </panel>
+ <panel label="Testar caminho" name="test_panel">
+ <text name="ctrl_click_label">
+ Aperte a tecla Ctrl e clique com o mouse para selecionar o ponto inicial.
+ </text>
+ <text name="shift_click_label">
+ Aperte a tecla Shift e clique com o mouse para selecionar o ponto final.
+ </text>
+ <text name="character_width_label">
+ Largura do personagem
+ </text>
+ <slider name="character_width" value="1"/>
+ <text name="character_width_unit_label">
+ m
+ </text>
+ <text name="character_type_label">
+ Tipo de personagem
+ </text>
+ <combo_box name="path_character_type">
+ <combo_box.item label="Nenhum" name="path_character_type_none"/>
+ <combo_box.item label="A" name="path_character_type_a"/>
+ <combo_box.item label="B" name="path_character_type_b"/>
+ <combo_box.item label="C" name="path_character_type_c"/>
+ <combo_box.item label="D" name="path_character_type_d"/>
+ </combo_box>
+ <button label="Limpar caminho" name="clear_path"/>
+ </panel>
+ </tab_container>
+</floater>
diff --git a/indra/newview/skins/default/xui/pt/floater_pathfinding_linksets.xml b/indra/newview/skins/default/xui/pt/floater_pathfinding_linksets.xml
new file mode 100755
index 0000000000..e0c60679dd
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/floater_pathfinding_linksets.xml
@@ -0,0 +1,167 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="floater_pathfinding_linksets" title="Linksets do pathfinding">
+ <floater.string name="messaging_get_inprogress">
+ Procurando por linksets do pathfinding...
+ </floater.string>
+ <floater.string name="messaging_get_error">
+ Erro detectado ao procurar por linksets do pathfinding.
+ </floater.string>
+ <floater.string name="messaging_set_inprogress">
+ Modificando os linksets do pathfinding selecionados...
+ </floater.string>
+ <floater.string name="messaging_set_error">
+ Erro detectado ao modificar os linksets do pathfinding selecionados.
+ </floater.string>
+ <floater.string name="messaging_complete_none_found">
+ Nenhum linkset do pathfinding.
+ </floater.string>
+ <floater.string name="messaging_complete_available">
+ [NUM_SELECTED] linksets selecionados de [NUM_TOTAL].
+ </floater.string>
+ <floater.string name="messaging_not_enabled">
+ Esta região não está habilitada para pathfinding.
+ </floater.string>
+ <floater.string name="linkset_terrain_name">
+ [Terreno]
+ </floater.string>
+ <floater.string name="linkset_terrain_description">
+ --
+ </floater.string>
+ <floater.string name="linkset_terrain_owner">
+ --
+ </floater.string>
+ <floater.string name="linkset_terrain_scripted">
+ --
+ </floater.string>
+ <floater.string name="linkset_terrain_land_impact">
+ --
+ </floater.string>
+ <floater.string name="linkset_terrain_dist_from_you">
+ --
+ </floater.string>
+ <floater.string name="linkset_owner_loading">
+ [Carregando]
+ </floater.string>
+ <floater.string name="linkset_owner_unknown">
+ [Desconhecido]
+ </floater.string>
+ <floater.string name="linkset_owner_group">
+ [grupo]
+ </floater.string>
+ <floater.string name="linkset_is_scripted">
+ Sim
+ </floater.string>
+ <floater.string name="linkset_is_not_scripted">
+ Não
+ </floater.string>
+ <floater.string name="linkset_is_unknown_scripted">
+ Desconhecido
+ </floater.string>
+ <floater.string name="linkset_use_walkable">
+ Caminhável
+ </floater.string>
+ <floater.string name="linkset_use_static_obstacle">
+ Obstáculo estático
+ </floater.string>
+ <floater.string name="linkset_use_dynamic_obstacle">
+ Obstáculo móvel
+ </floater.string>
+ <floater.string name="linkset_use_material_volume">
+ Volume material
+ </floater.string>
+ <floater.string name="linkset_use_exclusion_volume">
+ Volume de exclusão
+ </floater.string>
+ <floater.string name="linkset_use_dynamic_phantom">
+ Fantasma móvel
+ </floater.string>
+ <floater.string name="linkset_is_terrain">
+ [inalterável]
+ </floater.string>
+ <floater.string name="linkset_is_restricted_state">
+ [restrito]
+ </floater.string>
+ <floater.string name="linkset_is_non_volume_state">
+ [côncavo]
+ </floater.string>
+ <floater.string name="linkset_is_restricted_non_volume_state">
+ [restrito,côncavo]
+ </floater.string>
+ <floater.string name="linkset_choose_use">
+ Escolher uso do linkset...
+ </floater.string>
+ <panel>
+ <combo_box name="filter_by_linkset_use">
+ <combo_box.item label="Filtrar por uso do linkset..." name="filter_by_linkset_use_none"/>
+ <combo_box.item label="Caminhável" name="filter_by_linkset_use_walkable"/>
+ <combo_box.item label="Obstáculo estático" name="filter_by_linkset_use_static_obstacle"/>
+ <combo_box.item label="Obstáculo móvel" name="filter_by_linkset_use_dynamic_obstacle"/>
+ <combo_box.item label="Volume material" name="filter_by_linkset_use_material_volume"/>
+ <combo_box.item label="Volume de exclusão" name="filter_by_linkset_use_exclusion_volume"/>
+ <combo_box.item label="Fantasma móvel" name="filter_by_linkset_use_dynamic_phantom"/>
+ </combo_box>
+ <button label="Aplicar" name="apply_filters"/>
+ <button label="Limpar" name="clear_filters"/>
+ <scroll_list name="objects_scroll_list">
+ <scroll_list.columns label="Nome (prim raiz)" name="name"/>
+ <scroll_list.columns label="Descrição (prim raiz)" name="description"/>
+ <scroll_list.columns label="Proprietário" name="owner"/>
+ <scroll_list.columns label="Com script" name="scripted"/>
+ <scroll_list.columns label="Impacto" name="land_impact"/>
+ <scroll_list.columns label="Distância" name="dist_from_you"/>
+ <scroll_list.columns label="Uso do linkset" name="linkset_use"/>
+ <scroll_list.columns label="A %" name="a_percent"/>
+ <scroll_list.columns label="B %" name="b_percent"/>
+ <scroll_list.columns label="C %" name="c_percent"/>
+ <scroll_list.columns label="D %" name="d_percent"/>
+ </scroll_list>
+ <text name="messaging_status">
+ Linksets:
+ </text>
+ <button label="Atualizar lista" name="refresh_objects_list"/>
+ <button label="Selecionar tudo" name="select_all_objects"/>
+ <button label="Selecionar nenhum" name="select_none_objects"/>
+ </panel>
+ <panel>
+ <check_box label="Exibir baliza" name="show_beacon"/>
+ <button label="Pegar" name="take_objects"/>
+ <button label="Pegar uma cópia" name="take_copy_objects"/>
+ <button label="Teletransportar-me até ele" name="teleport_me_to_object"/>
+ <button label="Devolver" name="return_objects"/>
+ <button label="Excluir" name="delete_objects"/>
+ </panel>
+ <panel>
+ <text name="walkability_coefficients_label">
+ Possibilidade de caminhar:
+ </text>
+ <text name="edit_a_label">
+ A
+ </text>
+ <line_editor name="edit_a_value" tool_tip="Possibilidade de caminhar para os personagens do tipo A. Por exemplo: o tipo do personagem é humano."/>
+ <text name="edit_b_label">
+ B
+ </text>
+ <line_editor name="edit_b_value" tool_tip="Possibilidade de caminhar para os personagens do tipo B. Por exemplo: o tipo do personagem é criatura."/>
+ <text name="edit_c_label">
+ C
+ </text>
+ <line_editor name="edit_c_value" tool_tip="Possibilidade de caminhar para os personagens do tipo C. Por exemplo: o tipo do personagem é robô."/>
+ <text name="edit_d_label">
+ D
+ </text>
+ <line_editor name="edit_d_value" tool_tip="Possibilidade de caminhar para os personagens do tipo D. Por exemplo: o tipo do personagem é outro."/>
+ <button label="Aplicar alterações" name="apply_edit_values"/>
+ <text name="suggested_use_a_label">
+ (Humano)
+ </text>
+ <text name="suggested_use_b_label">
+ (Criatura)
+ </text>
+ <text name="suggested_use_c_label">
+ (Robô)
+ </text>
+ <text name="suggested_use_d_label">
+ (Outro)
+ </text>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/pt/floater_pay.xml b/indra/newview/skins/default/xui/pt/floater_pay.xml
index 8094ad376c..8094ad376c 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_pay.xml
+++ b/indra/newview/skins/default/xui/pt/floater_pay.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_pay_object.xml b/indra/newview/skins/default/xui/pt/floater_pay_object.xml
index a5579f03bf..a5579f03bf 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_pay_object.xml
+++ b/indra/newview/skins/default/xui/pt/floater_pay_object.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_people.xml b/indra/newview/skins/default/xui/pt/floater_people.xml
index 10a516ee36..10a516ee36 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_people.xml
+++ b/indra/newview/skins/default/xui/pt/floater_people.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_perm_prefs.xml b/indra/newview/skins/default/xui/pt/floater_perm_prefs.xml
index 33a0d6a456..33a0d6a456 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_perm_prefs.xml
+++ b/indra/newview/skins/default/xui/pt/floater_perm_prefs.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_picks.xml b/indra/newview/skins/default/xui/pt/floater_picks.xml
index 9766196319..9766196319 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_picks.xml
+++ b/indra/newview/skins/default/xui/pt/floater_picks.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_places.xml b/indra/newview/skins/default/xui/pt/floater_places.xml
index 12c6548205..12c6548205 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_places.xml
+++ b/indra/newview/skins/default/xui/pt/floater_places.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_post_process.xml b/indra/newview/skins/default/xui/pt/floater_post_process.xml
index d4f2e96539..d4f2e96539 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_post_process.xml
+++ b/indra/newview/skins/default/xui/pt/floater_post_process.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_postcard.xml b/indra/newview/skins/default/xui/pt/floater_postcard.xml
deleted file mode 100644
index 9740fbcb4d..0000000000
--- a/indra/newview/skins/default/xui/pt/floater_postcard.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Postcard" title="ENVIAR FOTO VIA EMAIL">
- <text name="to_label" width="135">
- Para (email):
- </text>
- <line_editor left="143" name="to_form" width="127"/>
- <text name="from_label">
- De (email):
- </text>
- <line_editor left="143" name="from_form" width="127"/>
- <text name="name_label">
- Seu nome:
- </text>
- <line_editor left="143" name="name_form" width="127"/>
- <text name="subject_label">
- Assunto:
- </text>
- <line_editor left="143" name="subject_form" width="127"/>
- <line_editor label="Digite o assunto aqui" name="subject_form"/>
- <text name="msg_label">
- Mensagem:
- </text>
- <text_editor name="msg_form">
- Digite sua mensagem aqui.
- </text_editor>
- <text name="fine_print">
- Se seu indicado entrar no [SECOND_LIFE], você receberá um bônus pela indicação.
- </text>
- <button label="Cancelar" name="cancel_btn"/>
- <button label="Enviar" name="send_btn"/>
- <string name="default_subject">
- Postal do [SECOND_LIFE].
- </string>
- <string name="default_message">
- Dá uma olhada nisto!
- </string>
- <string name="upload_message">
- Enviando...
- </string>
-</floater>
diff --git a/indra/newview/skins/default/xui/pt/floater_preferences.xml b/indra/newview/skins/default/xui/pt/floater_preferences.xml
index c89a61d9b1..c89a61d9b1 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_preferences.xml
+++ b/indra/newview/skins/default/xui/pt/floater_preferences.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_preferences_proxy.xml b/indra/newview/skins/default/xui/pt/floater_preferences_proxy.xml
index 3aaee2d4a7..3aaee2d4a7 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_preferences_proxy.xml
+++ b/indra/newview/skins/default/xui/pt/floater_preferences_proxy.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_preview_animation.xml b/indra/newview/skins/default/xui/pt/floater_preview_animation.xml
index 19474d8099..19474d8099 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_preview_animation.xml
+++ b/indra/newview/skins/default/xui/pt/floater_preview_animation.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_preview_gesture.xml b/indra/newview/skins/default/xui/pt/floater_preview_gesture.xml
index 089694608b..089694608b 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_preview_gesture.xml
+++ b/indra/newview/skins/default/xui/pt/floater_preview_gesture.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_preview_notecard.xml b/indra/newview/skins/default/xui/pt/floater_preview_notecard.xml
index d094c1b63a..d094c1b63a 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_preview_notecard.xml
+++ b/indra/newview/skins/default/xui/pt/floater_preview_notecard.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_preview_sound.xml b/indra/newview/skins/default/xui/pt/floater_preview_sound.xml
index 7c5a1538f2..7c5a1538f2 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_preview_sound.xml
+++ b/indra/newview/skins/default/xui/pt/floater_preview_sound.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_preview_texture.xml b/indra/newview/skins/default/xui/pt/floater_preview_texture.xml
index 6f39635240..6f39635240 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_preview_texture.xml
+++ b/indra/newview/skins/default/xui/pt/floater_preview_texture.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_price_for_listing.xml b/indra/newview/skins/default/xui/pt/floater_price_for_listing.xml
index b078962feb..b078962feb 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_price_for_listing.xml
+++ b/indra/newview/skins/default/xui/pt/floater_price_for_listing.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_publish_classified.xml b/indra/newview/skins/default/xui/pt/floater_publish_classified.xml
index de3417ea14..de3417ea14 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_publish_classified.xml
+++ b/indra/newview/skins/default/xui/pt/floater_publish_classified.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_region_debug_console.xml b/indra/newview/skins/default/xui/pt/floater_region_debug_console.xml
index d3b5df2d74..d3b5df2d74 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_region_debug_console.xml
+++ b/indra/newview/skins/default/xui/pt/floater_region_debug_console.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_region_info.xml b/indra/newview/skins/default/xui/pt/floater_region_info.xml
index cc5e0d59d4..cc5e0d59d4 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_region_info.xml
+++ b/indra/newview/skins/default/xui/pt/floater_region_info.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_report_abuse.xml b/indra/newview/skins/default/xui/pt/floater_report_abuse.xml
index 08413a9231..08413a9231 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_report_abuse.xml
+++ b/indra/newview/skins/default/xui/pt/floater_report_abuse.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_script_debug.xml b/indra/newview/skins/default/xui/pt/floater_script_debug.xml
index 6d1d981ca7..6d1d981ca7 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_script_debug.xml
+++ b/indra/newview/skins/default/xui/pt/floater_script_debug.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_script_debug_panel.xml b/indra/newview/skins/default/xui/pt/floater_script_debug_panel.xml
index e70a30fa24..e70a30fa24 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_script_debug_panel.xml
+++ b/indra/newview/skins/default/xui/pt/floater_script_debug_panel.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_script_limits.xml b/indra/newview/skins/default/xui/pt/floater_script_limits.xml
index 64a8a49c85..64a8a49c85 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_script_limits.xml
+++ b/indra/newview/skins/default/xui/pt/floater_script_limits.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_script_preview.xml b/indra/newview/skins/default/xui/pt/floater_script_preview.xml
index 5be866d052..5be866d052 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_script_preview.xml
+++ b/indra/newview/skins/default/xui/pt/floater_script_preview.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_script_queue.xml b/indra/newview/skins/default/xui/pt/floater_script_queue.xml
index 5fb6dd1c35..5fb6dd1c35 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_script_queue.xml
+++ b/indra/newview/skins/default/xui/pt/floater_script_queue.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_script_search.xml b/indra/newview/skins/default/xui/pt/floater_script_search.xml
index 8878590a4e..8878590a4e 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_script_search.xml
+++ b/indra/newview/skins/default/xui/pt/floater_script_search.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_search.xml b/indra/newview/skins/default/xui/pt/floater_search.xml
index 3509cb786d..3509cb786d 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_search.xml
+++ b/indra/newview/skins/default/xui/pt/floater_search.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_select_key.xml b/indra/newview/skins/default/xui/pt/floater_select_key.xml
index 7264a5a713..7264a5a713 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_select_key.xml
+++ b/indra/newview/skins/default/xui/pt/floater_select_key.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_sell_land.xml b/indra/newview/skins/default/xui/pt/floater_sell_land.xml
index 014ae0845e..014ae0845e 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_sell_land.xml
+++ b/indra/newview/skins/default/xui/pt/floater_sell_land.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_settings_debug.xml b/indra/newview/skins/default/xui/pt/floater_settings_debug.xml
index 83f7b24572..83f7b24572 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_settings_debug.xml
+++ b/indra/newview/skins/default/xui/pt/floater_settings_debug.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_snapshot.xml b/indra/newview/skins/default/xui/pt/floater_snapshot.xml
index 4110e69068..4110e69068 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_snapshot.xml
+++ b/indra/newview/skins/default/xui/pt/floater_snapshot.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_sound_devices.xml b/indra/newview/skins/default/xui/pt/floater_sound_devices.xml
index 948d727540..948d727540 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_sound_devices.xml
+++ b/indra/newview/skins/default/xui/pt/floater_sound_devices.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_sound_preview.xml b/indra/newview/skins/default/xui/pt/floater_sound_preview.xml
index e62260c2e3..e62260c2e3 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_sound_preview.xml
+++ b/indra/newview/skins/default/xui/pt/floater_sound_preview.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_spellcheck.xml b/indra/newview/skins/default/xui/pt/floater_spellcheck.xml
new file mode 100755
index 0000000000..02bb154d26
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/floater_spellcheck.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="spellcheck_floater" title="Configurações do verificador ortográfico">
+ <check_box label="Habilitar verificador ortográfico" name="spellcheck_enable"/>
+ <text name="spellcheck_main">
+ Dicionário principal:
+ </text>
+ <text label="Logs:" name="spellcheck_additional">
+ Dicionários adicionais:
+ </text>
+ <text name="spellcheck_available">
+ Disponível
+ </text>
+ <text name="spellcheck_active">
+ Ativo
+ </text>
+ <button label="Remover" name="spellcheck_remove_btn"/>
+ <button label="Importar..." name="spellcheck_import_btn"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/pt/floater_spellcheck_import.xml b/indra/newview/skins/default/xui/pt/floater_spellcheck_import.xml
new file mode 100755
index 0000000000..f4e95bddec
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/floater_spellcheck_import.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="spellcheck_import" title="Importar dicionário">
+ <button label="Procurar" label_selected="Procurar" name="dictionary_path_browse"/>
+ <button label="Importar" name="ok_btn"/>
+ <button label="Cancelar" name="cancel_btn"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/pt/floater_stats.xml b/indra/newview/skins/default/xui/pt/floater_stats.xml
index f0a053ebe3..be53624145 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_stats.xml
+++ b/indra/newview/skins/default/xui/pt/floater_stats.xml
@@ -14,8 +14,11 @@
<stat_bar label="KTris desenhados por segundo" name="ktrissec"/>
<stat_bar label="Total Objects" name="objs"/>
<stat_bar label="New Objects" name="newobjs"/>
+ <stat_bar label="Taxa de acertos do cache do objeto" name="object_cache_hits"/>
</stat_view>
<stat_view label="Texture" name="texture">
+ <stat_bar label="Taxa de acertos do cache" name="texture_cache_hits"/>
+ <stat_bar label="Latência de leitura do cache" name="texture_cache_read_latency"/>
<stat_bar label="Count" name="numimagesstat"/>
<stat_bar label="Raw Count" name="numrawimagesstat"/>
<stat_bar label="GL Mem" name="gltexmemstat"/>
@@ -44,6 +47,12 @@
<stat_bar label="Low LOD Objects" name="physicslodtasks"/>
<stat_bar label="Memory Allocated" name="physicsmemoryallocated"/>
</stat_view>
+ <stat_bar label="Scripts executados" name="simpctscriptsrun"/>
+ <stat_view label="Pathfinding" name="simpathfinding">
+ <stat_bar label="Tempo de etapa de AI" name="simsimaistepmsec"/>
+ <stat_bar label="Etapas de silhueta ignoradas" name="simsimskippedsilhouettesteps"/>
+ <stat_bar label="Personagens atualizados" name="simsimpctsteppedcharacters"/>
+ </stat_view>
<stat_view label="Time (ms)" name="simperf">
<stat_bar label="Total Frame Time" name="simframemsec"/>
<stat_bar label="Net Time" name="simnetmsec"/>
diff --git a/indra/newview/skins/default/xui/pt/floater_sys_well.xml b/indra/newview/skins/default/xui/pt/floater_sys_well.xml
index 38beec022c..38beec022c 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_sys_well.xml
+++ b/indra/newview/skins/default/xui/pt/floater_sys_well.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_telehub.xml b/indra/newview/skins/default/xui/pt/floater_telehub.xml
index 6b35d3f919..6b35d3f919 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_telehub.xml
+++ b/indra/newview/skins/default/xui/pt/floater_telehub.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_test_layout_stacks.xml b/indra/newview/skins/default/xui/pt/floater_test_layout_stacks.xml
index b479d5f6d6..b479d5f6d6 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_test_layout_stacks.xml
+++ b/indra/newview/skins/default/xui/pt/floater_test_layout_stacks.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_test_text_vertical_aligment.xml b/indra/newview/skins/default/xui/pt/floater_test_text_vertical_aligment.xml
index dd282bf1fc..dd282bf1fc 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_test_text_vertical_aligment.xml
+++ b/indra/newview/skins/default/xui/pt/floater_test_text_vertical_aligment.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/pt/floater_texture_ctrl.xml
index 144bc0340e..ba4ef0afde 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_texture_ctrl.xml
+++ b/indra/newview/skins/default/xui/pt/floater_texture_ctrl.xml
@@ -1,23 +1,35 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="texture picker" title="DESTAQUE: TEXTURA">
- <string name="choose_picture">
+ <floater.string name="choose_picture">
Clique para escolher uma imagem
- </string>
+ </floater.string>
+ <floater.string name="pick title">
+ Pegar:
+ </floater.string>
<text name="Multiple">
Multiplas texturas
</text>
+ <radio_group name="mode_selection">
+ <radio_item label="Inventário" name="inventory" value="0"/>
+ <radio_item label="Local" name="local" value="1"/>
+ </radio_group>
<text name="unknown">
Tamanho: [DIMENSÕES]
</text>
<button label="Padrão" label_selected="Padrão" name="Default"/>
- <button label="Nenhum" label_selected="Nenhum" name="None"/>
<button label="Branco" label_selected="Branco" name="Blank"/>
- <check_box label="Exibir pastas" name="show_folders_check"/>
- <search_editor label="Filtrar texturas" name="inventory search editor"/>
- <check_box label="Applicar agora" name="apply_immediate_check"/>
- <button label="Cancelar" label_selected="Cancelar" name="Cancel"/>
+ <button label="Nenhum" label_selected="Nenhum" name="None"/>
+ <check_box initial_value="true" label="Inscrever-se agora" name="apply_immediate_check"/>
+ <text name="preview_disabled" value="Visualização desativada"/>
+ <filter_editor label="Filtrar texturas" name="inventory search editor"/>
+ <check_box initial_value="false" label="Exibir pastas" name="show_folders_check"/>
+ <button label="Adicionar" label_selected="Adicionar" name="l_add_btn"/>
+ <button label="Remover" label_selected="Remover" name="l_rem_btn"/>
+ <button label="Enviar" label_selected="Enviar" name="l_upl_btn"/>
+ <scroll_list name="l_name_list">
+ <column label="Nome" name="unit_name"/>
+ <column label="ID" name="unit_id_HIDDEN"/>
+ </scroll_list>
<button label="OK" label_selected="OK" name="Select"/>
- <string name="pick title">
- Pegar:
- </string>
+ <button label="Cancelar" label_selected="Cancelar" name="Cancel"/>
</floater>
diff --git a/indra/newview/skins/default/xui/pt/floater_texture_fetch_debugger.xml b/indra/newview/skins/default/xui/pt/floater_texture_fetch_debugger.xml
new file mode 100755
index 0000000000..0e897aea09
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/floater_texture_fetch_debugger.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="TexFetchDebugger" title="Depurador de obtenção de textura">
+ <text name="total_num_fetched_label">
+ 1, Número total de texturas obtidas: [NUM]
+ </text>
+ <text name="total_num_fetching_requests_label">
+ 2, Número total de solicitações de obtenção: [NUM]
+ </text>
+ <text name="total_num_cache_hits_label">
+ 3, Número total de acertos de cache: [NUM]
+ </text>
+ <text name="total_num_visible_tex_label">
+ 4, Número total de texturas visíveis: [NUM]
+ </text>
+ <text name="total_num_visible_tex_fetch_req_label">
+ 5, Número total de solicitações de obtenção de texturas visíveis: [NUM]
+ </text>
+ <text name="total_fetched_data_label">
+ 6, Número total de dados obtidos: [SIZE1]KB, Dados decodificados: [SIZE2]KB, [PIXEL]MPixels
+ </text>
+ <text name="total_fetched_vis_data_label">
+ 7, Número total de dados visíveis: [SIZE1]KB, Dados decodificados: [SIZE2]KB
+ </text>
+ <text name="total_fetched_rendered_data_label">
+ 8, Número total de dados renderizados: [SIZE1]KB, Dados decodificados: [SIZE2]KB, [PIXEL]MPixels
+ </text>
+ <text name="total_time_cache_read_label">
+ 9, Tempo total de leituras de cache: [TIME] segundos
+ </text>
+ <text name="total_time_cache_write_label">
+ 10, Tempo total de gravações em cache: [TIME] segundos
+ </text>
+ <text name="total_time_decode_label">
+ 11, Tempo total das decodificações: [TIME] segundos
+ </text>
+ <text name="total_time_gl_label">
+ 12, Tempo total de criação de texturas gl: [TIME] segundos
+ </text>
+ <text name="total_time_http_label">
+ 13, Tempo total de obtenção de HTTP: [TIME] segundos
+ </text>
+ <text name="total_time_fetch_label">
+ 14, Tempo total de obtenção completa: [TIME] segundos
+ </text>
+ <text name="total_time_refetch_vis_cache_label">
+ 15, Obtendo novamente visíveis do cache, Tempo: [TIME] segundos, Obtidos: [SIZE]KB, [PIXEL]MPixels
+ </text>
+ <text name="total_time_refetch_all_cache_label">
+ 16, Obtendo novamente todas as texturas do cache, Tempo: [TIME] segundos, Obtidos: [SIZE]KB, [PIXEL]MPixels
+ </text>
+ <text name="total_time_refetch_vis_http_label">
+ 17, Obtendo novamente visíveis do HTTP, Tempo: [TIME] segundos, Obtidos: [SIZE]KB, [PIXEL]MPixels
+ </text>
+ <text name="total_time_refetch_all_http_label">
+ 18, Obtendo novamente todas as texturas do HTTP, Tempo: [TIME] segundos, Obtidos: [SIZE]KB, [PIXEL]MPixels
+ </text>
+ <spinner label="19, Proporção de texel/pixel:" name="texel_pixel_ratio"/>
+ <text name="texture_source_label">
+ 20, Origem da textura:
+ </text>
+ <radio_group name="texture_source">
+ <radio_item label="Cache + HTTP" name="0"/>
+ <radio_item label="Apenas HTTP" name="1"/>
+ </radio_group>
+ <button label="Iniciar" name="start_btn"/>
+ <button label="Redefinir" name="clear_btn"/>
+ <button label="Fechar" name="close_btn"/>
+ <button label="Leitura do cache" name="cacheread_btn"/>
+ <button label="Gravação em cache" name="cachewrite_btn"/>
+ <button label="HTTP" name="http_btn"/>
+ <button label="Decodificar" name="decode_btn"/>
+ <button label="Textura GL" name="gl_btn"/>
+ <button label="Obter novamente cache visível" name="refetchviscache_btn"/>
+ <button label="Obter todo o cache novamente" name="refetchallcache_btn"/>
+ <button label="Obter novamente HTTP visível" name="refetchvishttp_btn"/>
+ <button label="Obter todo o HTTP novamente" name="refetchallhttp_btn"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/pt/floater_tools.xml b/indra/newview/skins/default/xui/pt/floater_tools.xml
index 4b31833602..66c14cdecf 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_tools.xml
+++ b/indra/newview/skins/default/xui/pt/floater_tools.xml
@@ -148,6 +148,12 @@
<panel.string name="text modify info 4">
Você não pode modificar estes objetos
</panel.string>
+ <panel.string name="text modify info 5">
+ Não é possível modificar este objeto através de uma demarcação da região
+ </panel.string>
+ <panel.string name="text modify info 6">
+ Não é possível modificar estes objetos através de uma demarcação da região
+ </panel.string>
<panel.string name="text modify warning">
Selecione o objeto inteiro para configurar as autorizações
</panel.string>
@@ -197,12 +203,12 @@
<combo_box.item label="Zoom" name="Zoom"/>
</combo_box>
<check_box label="À venda" name="checkbox for sale"/>
+ <spinner label="L$" name="Edit Cost"/>
<combo_box name="sale type">
<combo_box.item label="Cópia" name="Copy"/>
<combo_box.item label="Conteúdo" name="Contents"/>
<combo_box.item label="Original" name="Original"/>
</combo_box>
- <spinner label="Preço: L$" name="Edit Cost"/>
<check_box label="Mostrar na busca" name="search_check" tool_tip="Permitir que as pessoas vejam este objeto nos resultados de busca"/>
<panel name="perms_build">
<text name="perm_modify">
@@ -238,6 +244,11 @@
F:
</text>
</panel>
+ <panel name="pathfinding_attrs_panel">
+ <text name="pathfinding_attributes_label">
+ Atributos do pathfinding:
+ </text>
+ </panel>
</panel>
<panel label="Objeto" name="Object">
<check_box label="Travado" name="checkbox locked" tool_tip="Previne que o objeto seja movido ou apagado. Muito útil para evitar edições não intencionais durante a construção."/>
@@ -452,16 +463,11 @@
<combo_box.item label="Sulcos" name="suction"/>
<combo_box.item label="Weave" name="weave"/>
</combo_box>
- <check_box initial_value="falso" label="Alinhar planares" name="checkbox planar align" tool_tip="Alinhar texturas dos planos selecionados com o plano selecionado por último. Requer mapeamento planar da textura."/>
- <text name="rpt">
- Repetições / Plano
- </text>
<spinner label="Horizontal (U)" name="TexScaleU"/>
<check_box label="Inverter" name="checkbox flip s"/>
<spinner label="Vertical (V)" name="TexScaleV"/>
<check_box label="Inverter" name="checkbox flip t"/>
<spinner label="Rotação˚" name="TexRot"/>
- <spinner label="Repetições/Metro" name="rptctrl"/>
<button label="Aplicar" label_selected="Aplicar" name="button apply"/>
<text name="tex offset">
Offset de textura
diff --git a/indra/newview/skins/default/xui/pt/floater_top_objects.xml b/indra/newview/skins/default/xui/pt/floater_top_objects.xml
index c3d5820616..ef682714c6 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_top_objects.xml
+++ b/indra/newview/skins/default/xui/pt/floater_top_objects.xml
@@ -9,9 +9,6 @@
<floater.string name="scripts_score_label">
Tempo
</floater.string>
- <floater.string name="scripts_mono_time_label">
- Hora Mono
- </floater.string>
<floater.string name="top_colliders_title">
Principais Colidentes
</floater.string>
@@ -32,9 +29,10 @@
<scroll_list.columns label="Nome" name="name"/>
<scroll_list.columns label="Proprietário" name="owner"/>
<scroll_list.columns label="Local" name="location"/>
+ <scroll_list.columns label="Lote" name="parcel"/>
<scroll_list.columns label="Tempo" name="time"/>
- <scroll_list.columns label="Hora Mono" name="mono_time"/>
<scroll_list.columns label="URLs" name="URLs"/>
+ <scroll_list.columns label="Memória (KB)" name="memory"/>
</scroll_list>
<text name="id_text">
ID do Objeto:
@@ -51,6 +49,10 @@
</text>
<line_editor font="SansSerifSmall" left="140" name="owner_name_editor" width="280"/>
<button label="Filtro" name="filter_owner_btn"/>
+ <text name="parcel_name_text">
+ Lote:
+ </text>
+ <button label="Filtrar" name="filter_parcel_btn"/>
<button label="Atualizar" name="refresh_btn"/>
<button label="Retornar Selecionado" name="return_selected_btn" width="170"/>
<button label="Retornar Tudo" left="190" name="return_all_btn"/>
diff --git a/indra/newview/skins/default/xui/pt/floater_tos.xml b/indra/newview/skins/default/xui/pt/floater_tos.xml
index c4954cb61f..c4954cb61f 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_tos.xml
+++ b/indra/newview/skins/default/xui/pt/floater_tos.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_toybox.xml b/indra/newview/skins/default/xui/pt/floater_toybox.xml
index 3677c3b1f5..3677c3b1f5 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_toybox.xml
+++ b/indra/newview/skins/default/xui/pt/floater_toybox.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_translation_settings.xml b/indra/newview/skins/default/xui/pt/floater_translation_settings.xml
index 1955599a81..1955599a81 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_translation_settings.xml
+++ b/indra/newview/skins/default/xui/pt/floater_translation_settings.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_url_entry.xml b/indra/newview/skins/default/xui/pt/floater_url_entry.xml
index 48af8de363..48af8de363 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_url_entry.xml
+++ b/indra/newview/skins/default/xui/pt/floater_url_entry.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_voice_chat_volume.xml b/indra/newview/skins/default/xui/pt/floater_voice_chat_volume.xml
new file mode 100644
index 0000000000..de7aa2df12
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/floater_voice_chat_volume.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="floater_voice_volume" title="VOLUME DO BATE-PAPO DE VOZ">
+ <slider label="Bate-papo de voz" name="chat_voice_volume"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/pt/floater_voice_controls.xml b/indra/newview/skins/default/xui/pt/floater_voice_controls.xml
index 745a7d0e00..745a7d0e00 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_voice_controls.xml
+++ b/indra/newview/skins/default/xui/pt/floater_voice_controls.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_voice_effect.xml b/indra/newview/skins/default/xui/pt/floater_voice_effect.xml
index b29ca3d699..71d3c33ae5 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_voice_effect.xml
+++ b/indra/newview/skins/default/xui/pt/floater_voice_effect.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater label="Lugares" name="voice_effects" title="EFEITOS DE VOZ">
+<floater label="Lugares" name="voice_effects" title="AMOSTRA DE DISTORÇÃO DE VOZ">
<string name="no_voice_effect">
(Não distorcer voz)
</string>
diff --git a/indra/newview/skins/default/xui/pt/floater_voice_volume.xml b/indra/newview/skins/default/xui/pt/floater_voice_volume.xml
new file mode 100644
index 0000000000..dae47a99ae
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/floater_voice_volume.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<!--
+ Not can_close / no title to avoid window chrome
+ Single instance - only have one at a time, recycle it each spawn
+-->
+<floater name="floater_voice_volume" title="VOLUME DE VOZ">
+ <slider name="volume_slider" tool_tip="Volume de voz" value="0.5"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/pt/floater_web_content.xml b/indra/newview/skins/default/xui/pt/floater_web_content.xml
index 5101579c6f..5101579c6f 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_web_content.xml
+++ b/indra/newview/skins/default/xui/pt/floater_web_content.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_whitelist_entry.xml b/indra/newview/skins/default/xui/pt/floater_whitelist_entry.xml
index 865d939d24..865d939d24 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_whitelist_entry.xml
+++ b/indra/newview/skins/default/xui/pt/floater_whitelist_entry.xml
diff --git a/indra/newview/skins/default/xui/pt/floater_window_size.xml b/indra/newview/skins/default/xui/pt/floater_window_size.xml
index 6a8ccbd002..7deb799bd7 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_window_size.xml
+++ b/indra/newview/skins/default/xui/pt/floater_window_size.xml
@@ -7,10 +7,17 @@
Definir tamanho da janela:
</text>
<combo_box name="window_size_combo" tool_tip="largura x altura">
- <combo_box.item label="1000 x 700 (padrão)" name="item0"/>
- <combo_box.item label="1024 x 768" name="item1"/>
- <combo_box.item label="1280 x 720 (720p)" name="item2"/>
- <combo_box.item label="1920 x 1080 (1080p)" name="item3"/>
+ <combo_box.item label="1000 x 700 (padrão)" name="item1"/>
+ <combo_box.item label="1024 x 768 (4:3 XGA)" name="item2"/>
+ <combo_box.item label="1280 x 720 (16:9 HDTV)" name="item3"/>
+ <combo_box.item label="1280 x 800 (5:8 WXGA)" name="item4"/>
+ <combo_box.item label="1280 x 1024 (5:4 SXGA)" name="item5"/>
+ <combo_box.item label="1440 x 900 (8:5 WSXGA)" name="item7"/>
+ <combo_box.item label="1600 x 900 (16:9 HD+)" name="item8"/>
+ <combo_box.item label="1600 x 1200 (4:3 UXGA)" name="item9"/>
+ <combo_box.item label="1680 x 1050 (8:5 WSXGA+)" name="item10"/>
+ <combo_box.item label="1920 x 1080 (16:9 HDTV)" name="item11"/>
+ <combo_box.item label="1920 x 1200 (8:5 WUXGA)" name="item12"/>
</combo_box>
<button label="Definir" name="set_btn"/>
<button label="Cancelar" name="cancel_btn"/>
diff --git a/indra/newview/skins/default/xui/pt/floater_world_map.xml b/indra/newview/skins/default/xui/pt/floater_world_map.xml
index 490a975e80..490a975e80 100644..100755
--- a/indra/newview/skins/default/xui/pt/floater_world_map.xml
+++ b/indra/newview/skins/default/xui/pt/floater_world_map.xml
diff --git a/indra/newview/skins/default/xui/pt/inspect_avatar.xml b/indra/newview/skins/default/xui/pt/inspect_avatar.xml
index 19244d9b27..19244d9b27 100644..100755
--- a/indra/newview/skins/default/xui/pt/inspect_avatar.xml
+++ b/indra/newview/skins/default/xui/pt/inspect_avatar.xml
diff --git a/indra/newview/skins/default/xui/pt/inspect_group.xml b/indra/newview/skins/default/xui/pt/inspect_group.xml
index 889d35f269..889d35f269 100644..100755
--- a/indra/newview/skins/default/xui/pt/inspect_group.xml
+++ b/indra/newview/skins/default/xui/pt/inspect_group.xml
diff --git a/indra/newview/skins/default/xui/pt/inspect_object.xml b/indra/newview/skins/default/xui/pt/inspect_object.xml
index b72de7038d..b72de7038d 100644..100755
--- a/indra/newview/skins/default/xui/pt/inspect_object.xml
+++ b/indra/newview/skins/default/xui/pt/inspect_object.xml
diff --git a/indra/newview/skins/default/xui/pt/inspect_remote_object.xml b/indra/newview/skins/default/xui/pt/inspect_remote_object.xml
index 789194bf2e..789194bf2e 100644..100755
--- a/indra/newview/skins/default/xui/pt/inspect_remote_object.xml
+++ b/indra/newview/skins/default/xui/pt/inspect_remote_object.xml
diff --git a/indra/newview/skins/default/xui/pt/language_settings.xml b/indra/newview/skins/default/xui/pt/language_settings.xml
index 8799475ace..8799475ace 100644..100755
--- a/indra/newview/skins/default/xui/pt/language_settings.xml
+++ b/indra/newview/skins/default/xui/pt/language_settings.xml
diff --git a/indra/newview/skins/default/xui/pt/menu_add_wearable_gear.xml b/indra/newview/skins/default/xui/pt/menu_add_wearable_gear.xml
index 4b81276ab3..4b81276ab3 100644..100755
--- a/indra/newview/skins/default/xui/pt/menu_add_wearable_gear.xml
+++ b/indra/newview/skins/default/xui/pt/menu_add_wearable_gear.xml
diff --git a/indra/newview/skins/default/xui/pt/menu_attachment_other.xml b/indra/newview/skins/default/xui/pt/menu_attachment_other.xml
index cfd69158bc..61953f9f78 100644..100755
--- a/indra/newview/skins/default/xui/pt/menu_attachment_other.xml
+++ b/indra/newview/skins/default/xui/pt/menu_attachment_other.xml
@@ -11,7 +11,9 @@
<menu_item_call label="Congelar" name="Freeze..."/>
<menu_item_call label="Ejetar" name="Eject..."/>
<menu_item_call label="Depurar texturas" name="Debug..."/>
+ <menu_item_call label="Descartar XML" name="Dump XML"/>
<menu_item_call label="Mais zoom" name="Zoom In"/>
<menu_item_call label="Pagar" name="Pay..."/>
<menu_item_call label="Perfil do objeto" name="Object Inspect"/>
+ <menu_item_call label="Bloquear proprietário da partícula" name="Mute Particle"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/pt/menu_attachment_self.xml b/indra/newview/skins/default/xui/pt/menu_attachment_self.xml
index 5b32784c32..2d4cd670e6 100644..100755
--- a/indra/newview/skins/default/xui/pt/menu_attachment_self.xml
+++ b/indra/newview/skins/default/xui/pt/menu_attachment_self.xml
@@ -12,5 +12,7 @@
<menu_item_call label="Meus grupos" name="Groups..."/>
<menu_item_call label="Meu perfil" name="Profile..."/>
<menu_item_call label="Depurar texturas" name="Debug..."/>
+ <menu_item_call label="Descartar XML" name="Dump XML"/>
<menu_item_call label="Largar" name="Drop"/>
+ <menu_item_call label="Bloquear proprietário da partícula" name="Mute Particle"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/pt/menu_avatar_icon.xml b/indra/newview/skins/default/xui/pt/menu_avatar_icon.xml
index beba969b7e..beba969b7e 100644..100755
--- a/indra/newview/skins/default/xui/pt/menu_avatar_icon.xml
+++ b/indra/newview/skins/default/xui/pt/menu_avatar_icon.xml
diff --git a/indra/newview/skins/default/xui/pt/menu_avatar_other.xml b/indra/newview/skins/default/xui/pt/menu_avatar_other.xml
index a4a26144c7..1af8d64438 100644..100755
--- a/indra/newview/skins/default/xui/pt/menu_avatar_other.xml
+++ b/indra/newview/skins/default/xui/pt/menu_avatar_other.xml
@@ -11,6 +11,8 @@
<menu_item_call label="Congelar" name="Freeze..."/>
<menu_item_call label="Ejetar" name="Eject..."/>
<menu_item_call label="Depurar texturas" name="Debug..."/>
+ <menu_item_call label="Descartar XML" name="Dump XML"/>
<menu_item_call label="Mais zoom" name="Zoom In"/>
<menu_item_call label="Pagar" name="Pay..."/>
+ <menu_item_call label="Bloquear proprietário da partícula" name="Mute Particle"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/pt/menu_avatar_self.xml b/indra/newview/skins/default/xui/pt/menu_avatar_self.xml
index e84dcb093d..447b77657b 100644..100755
--- a/indra/newview/skins/default/xui/pt/menu_avatar_self.xml
+++ b/indra/newview/skins/default/xui/pt/menu_avatar_self.xml
@@ -29,4 +29,6 @@
<menu_item_call label="Meus grupos" name="Groups..."/>
<menu_item_call label="Meu perfil" name="Profile..."/>
<menu_item_call label="Depurar texturas" name="Debug..."/>
+ <menu_item_call label="Descartar XML" name="Dump XML"/>
+ <menu_item_call label="Bloquear proprietário da partícula" name="Mute Particle"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/pt/menu_bottomtray.xml b/indra/newview/skins/default/xui/pt/menu_bottomtray.xml
deleted file mode 100644
index 4598b8ab25..0000000000
--- a/indra/newview/skins/default/xui/pt/menu_bottomtray.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<menu name="hide_camera_move_controls_menu">
- <menu_item_check label="Botão Falar" name="EnableVoiceChat"/>
- <menu_item_check label="Botão de gestos" name="ShowGestureButton"/>
- <menu_item_check label="Botão de movimento" name="ShowMoveButton"/>
- <menu_item_check label="Botão de ver" name="ShowCameraButton"/>
- <menu_item_check label="Botão de fotos" name="ShowSnapshotButton"/>
- <menu_item_check label="Botão Construir" name="ShowBuildButton"/>
- <menu_item_check label="Botão Buscar" name="ShowSearchButton"/>
- <menu_item_check label="Botão Mapa" name="ShowWorldMapButton"/>
- <menu_item_check label="Botão do Mini mapa" name="ShowMiniMapButton"/>
- <menu_item_call label="Cortar" name="NearbyChatBar_Cut"/>
- <menu_item_call label="Copiar" name="NearbyChatBar_Copy"/>
- <menu_item_call label="Colar" name="NearbyChatBar_Paste"/>
- <menu_item_call label="Excluir" name="NearbyChatBar_Delete"/>
- <menu_item_call label="Selecionar tudo" name="NearbyChatBar_Select_All"/>
-</menu>
diff --git a/indra/newview/skins/default/xui/pt/menu_cof_attachment.xml b/indra/newview/skins/default/xui/pt/menu_cof_attachment.xml
index 527e3af3c9..527e3af3c9 100644..100755
--- a/indra/newview/skins/default/xui/pt/menu_cof_attachment.xml
+++ b/indra/newview/skins/default/xui/pt/menu_cof_attachment.xml
diff --git a/indra/newview/skins/default/xui/pt/menu_cof_body_part.xml b/indra/newview/skins/default/xui/pt/menu_cof_body_part.xml
index 704fd226eb..704fd226eb 100644..100755
--- a/indra/newview/skins/default/xui/pt/menu_cof_body_part.xml
+++ b/indra/newview/skins/default/xui/pt/menu_cof_body_part.xml
diff --git a/indra/newview/skins/default/xui/pt/menu_cof_clothing.xml b/indra/newview/skins/default/xui/pt/menu_cof_clothing.xml
index 051323ae6a..051323ae6a 100644..100755
--- a/indra/newview/skins/default/xui/pt/menu_cof_clothing.xml
+++ b/indra/newview/skins/default/xui/pt/menu_cof_clothing.xml
diff --git a/indra/newview/skins/default/xui/pt/menu_cof_gear.xml b/indra/newview/skins/default/xui/pt/menu_cof_gear.xml
index 8716992a5e..b59895573e 100644..100755
--- a/indra/newview/skins/default/xui/pt/menu_cof_gear.xml
+++ b/indra/newview/skins/default/xui/pt/menu_cof_gear.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<menu name="Gear COF">
+<toggleable_menu name="Gear COF">
<menu label="Roupas novas" name="COF.Gear.New_Clothes"/>
- <menu label="Nova parte do corpo" name="COF.Geear.New_Body_Parts"/>
-</menu>
+ <menu label="Novas partes do corpo" name="COF.Gear.New_Body_Parts"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/pt/menu_conversation.xml b/indra/newview/skins/default/xui/pt/menu_conversation.xml
new file mode 100644
index 0000000000..2dd150a61e
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/menu_conversation.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_conversation_participant">
+ <menu_item_call label="Encerrar conversa" name="close_conversation"/>
+ <menu_item_call label="Abrir conversa de voz" name="open_voice_conversation"/>
+ <menu_item_call label="Desconectar de voz" name="disconnect_from_voice"/>
+ <menu_item_call label="Fechar selecionados" name="close_selected_conversations"/>
+ <menu_item_call label="Exibir perfil" name="view_profile"/>
+ <menu_item_call label="MI" name="im"/>
+ <menu_item_call label="Oferecer teletransporte" name="offer_teleport"/>
+ <menu_item_call label="Chamada de voz" name="voice_call"/>
+ <menu_item_call label="Histórico de bate-papo..." name="chat_history"/>
+ <menu_item_call label="Adicionar amigo" name="add_friend"/>
+ <menu_item_call label="Remover amigo" name="remove_friend"/>
+ <menu_item_call label="Remover amigos" name="remove_friends"/>
+ <menu_item_call label="Convidar para entrar no grupo..." name="invite_to_group"/>
+ <menu_item_call label="Mais zoom" name="zoom_in"/>
+ <menu_item_call label="Mapa" name="map"/>
+ <menu_item_call label="Compartilhar" name="share"/>
+ <menu_item_call label="Pagar" name="pay"/>
+ <menu_item_check label="Bloquear voz" name="block_unblock"/>
+ <menu_item_check label="Bloquear texto" name="MuteText"/>
+ <menu_item_call label="Perfil do grupo" name="group_profile"/>
+ <menu_item_call label="Ativar grupo" name="activate_group"/>
+ <menu_item_call label="Sair do grupo" name="leave_group"/>
+ <context_menu label="Opções do moderador &gt;" name="Moderator Options">
+ <menu_item_check label="Pode bater papo por escrito" name="AllowTextChat"/>
+ <menu_item_call label="Silenciar este participante" name="ModerateVoiceMuteSelected"/>
+ <menu_item_call label="Desfazer silenciar deste participante" name="ModerateVoiceUnMuteSelected"/>
+ <menu_item_call label="Silenciar todos" name="ModerateVoiceMute"/>
+ <menu_item_call label="Desfazer silenciar para todos" name="ModerateVoiceUnmute"/>
+ </context_menu>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/pt/menu_conversation_log_gear.xml b/indra/newview/skins/default/xui/pt/menu_conversation_log_gear.xml
new file mode 100644
index 0000000000..616e6db46e
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/menu_conversation_log_gear.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="Conversation Context Menu">
+ <menu_item_call label="MI..." name="IM"/>
+ <menu_item_call label="Chamada de voz..." name="Call"/>
+ <menu_item_call label="Abrir histórico de bate-papo..." name="Chat history"/>
+ <menu_item_call label="Exibir perfil" name="View Profile"/>
+ <menu_item_call label="Oferecer teletransporte" name="teleport"/>
+ <menu_item_call label="Adicionar amigo" name="add_friend"/>
+ <menu_item_call label="Remover amigo" name="remove_friend"/>
+ <menu_item_call label="Convidar para entrar no grupo..." name="Invite"/>
+ <menu_item_call label="Mapa" name="Map"/>
+ <menu_item_call label="Compartilhar" name="Share"/>
+ <menu_item_call label="Pagar" name="Pay"/>
+ <menu_item_check label="Bloquear/desbloquear" name="Block/Unblock"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/pt/menu_conversation_log_view.xml b/indra/newview/skins/default/xui/pt/menu_conversation_log_view.xml
new file mode 100644
index 0000000000..cab81175a0
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/menu_conversation_log_view.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_conversation_view">
+ <menu_item_check label="Ordenar por nome" name="sort_by_name"/>
+ <menu_item_check label="Ordenar por data" name="sort_by_date"/>
+ <menu_item_check label="Ordenar com amigos acima" name="sort_by_friends"/>
+ <menu_item_call label="Exibir histórico de Bate-papo local..." name="view_nearby_chat_history"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/pt/menu_edit.xml b/indra/newview/skins/default/xui/pt/menu_edit.xml
index ff431c9a21..ff431c9a21 100644..100755
--- a/indra/newview/skins/default/xui/pt/menu_edit.xml
+++ b/indra/newview/skins/default/xui/pt/menu_edit.xml
diff --git a/indra/newview/skins/default/xui/pt/menu_favorites.xml b/indra/newview/skins/default/xui/pt/menu_favorites.xml
index 062820fbca..062820fbca 100644..100755
--- a/indra/newview/skins/default/xui/pt/menu_favorites.xml
+++ b/indra/newview/skins/default/xui/pt/menu_favorites.xml
diff --git a/indra/newview/skins/default/xui/pt/menu_gesture_gear.xml b/indra/newview/skins/default/xui/pt/menu_gesture_gear.xml
index 70d8ae7a8e..70d8ae7a8e 100644..100755
--- a/indra/newview/skins/default/xui/pt/menu_gesture_gear.xml
+++ b/indra/newview/skins/default/xui/pt/menu_gesture_gear.xml
diff --git a/indra/newview/skins/default/xui/pt/menu_group_plus.xml b/indra/newview/skins/default/xui/pt/menu_group_plus.xml
index 1083845d68..1083845d68 100644..100755
--- a/indra/newview/skins/default/xui/pt/menu_group_plus.xml
+++ b/indra/newview/skins/default/xui/pt/menu_group_plus.xml
diff --git a/indra/newview/skins/default/xui/pt/menu_hide_navbar.xml b/indra/newview/skins/default/xui/pt/menu_hide_navbar.xml
index 5f6bd096a8..5f6bd096a8 100644..100755
--- a/indra/newview/skins/default/xui/pt/menu_hide_navbar.xml
+++ b/indra/newview/skins/default/xui/pt/menu_hide_navbar.xml
diff --git a/indra/newview/skins/default/xui/pt/menu_im_conversation.xml b/indra/newview/skins/default/xui/pt/menu_im_conversation.xml
new file mode 100644
index 0000000000..a8434dc336
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/menu_im_conversation.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="Conversation Gear Menu">
+ <menu_item_call label="Exibir perfil" name="View Profile"/>
+ <menu_item_call label="Adicionar amigo" name="Add Friend"/>
+ <menu_item_call label="Remover amigo" name="remove_friend"/>
+ <menu_item_call label="Oferecer teletransporte" name="offer_teleport"/>
+ <menu_item_call label="Convidar para entrar no grupo..." name="invite_to_group"/>
+ <menu_item_call label="Histórico de bate-papo..." name="chat_history"/>
+ <menu_item_call label="Mais zoom" name="zoom_in"/>
+ <menu_item_call label="Mapa" name="map"/>
+ <menu_item_call label="Compartilhar" name="Share"/>
+ <menu_item_call label="Pagar" name="Pay"/>
+ <menu_item_check label="Bloquear voz" name="Block/Unblock"/>
+ <menu_item_check label="Bloquear texto" name="MuteText"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/pt/menu_im_session_showmodes.xml b/indra/newview/skins/default/xui/pt/menu_im_session_showmodes.xml
new file mode 100644
index 0000000000..398b890f66
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/menu_im_session_showmodes.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_modes">
+ <menu_item_check label="Exibição compacta" name="compact_view"/>
+ <menu_item_check label="Exibição expandida" name="expanded_view"/>
+ <menu_item_check label="Mostrar hora" name="IMShowTime"/>
+ <menu_item_check label="Mostrar nomes em conversas individuais" name="IMShowNamesForP2PConv"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/pt/menu_im_well_button.xml b/indra/newview/skins/default/xui/pt/menu_im_well_button.xml
deleted file mode 100644
index 2d37cefd6f..0000000000
--- a/indra/newview/skins/default/xui/pt/menu_im_well_button.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<context_menu name="IM Well Button Context Menu">
- <menu_item_call label="Fechar tudo" name="Close All"/>
-</context_menu>
diff --git a/indra/newview/skins/default/xui/pt/menu_imchiclet_adhoc.xml b/indra/newview/skins/default/xui/pt/menu_imchiclet_adhoc.xml
index ead949ba13..ead949ba13 100644..100755
--- a/indra/newview/skins/default/xui/pt/menu_imchiclet_adhoc.xml
+++ b/indra/newview/skins/default/xui/pt/menu_imchiclet_adhoc.xml
diff --git a/indra/newview/skins/default/xui/pt/menu_imchiclet_group.xml b/indra/newview/skins/default/xui/pt/menu_imchiclet_group.xml
index dd177d1b8d..dd177d1b8d 100644..100755
--- a/indra/newview/skins/default/xui/pt/menu_imchiclet_group.xml
+++ b/indra/newview/skins/default/xui/pt/menu_imchiclet_group.xml
diff --git a/indra/newview/skins/default/xui/pt/menu_imchiclet_p2p.xml b/indra/newview/skins/default/xui/pt/menu_imchiclet_p2p.xml
index d821b3ded0..d821b3ded0 100644..100755
--- a/indra/newview/skins/default/xui/pt/menu_imchiclet_p2p.xml
+++ b/indra/newview/skins/default/xui/pt/menu_imchiclet_p2p.xml
diff --git a/indra/newview/skins/default/xui/pt/menu_inspect_avatar_gear.xml b/indra/newview/skins/default/xui/pt/menu_inspect_avatar_gear.xml
index 2b5aa7508b..2b5aa7508b 100644..100755
--- a/indra/newview/skins/default/xui/pt/menu_inspect_avatar_gear.xml
+++ b/indra/newview/skins/default/xui/pt/menu_inspect_avatar_gear.xml
diff --git a/indra/newview/skins/default/xui/pt/menu_inspect_object_gear.xml b/indra/newview/skins/default/xui/pt/menu_inspect_object_gear.xml
index 7e271904e9..7e271904e9 100644..100755
--- a/indra/newview/skins/default/xui/pt/menu_inspect_object_gear.xml
+++ b/indra/newview/skins/default/xui/pt/menu_inspect_object_gear.xml
diff --git a/indra/newview/skins/default/xui/pt/menu_inspect_self_gear.xml b/indra/newview/skins/default/xui/pt/menu_inspect_self_gear.xml
index e8fafa58a9..e8fafa58a9 100644..100755
--- a/indra/newview/skins/default/xui/pt/menu_inspect_self_gear.xml
+++ b/indra/newview/skins/default/xui/pt/menu_inspect_self_gear.xml
diff --git a/indra/newview/skins/default/xui/pt/menu_inv_offer_chiclet.xml b/indra/newview/skins/default/xui/pt/menu_inv_offer_chiclet.xml
index c404719c95..c404719c95 100644..100755
--- a/indra/newview/skins/default/xui/pt/menu_inv_offer_chiclet.xml
+++ b/indra/newview/skins/default/xui/pt/menu_inv_offer_chiclet.xml
diff --git a/indra/newview/skins/default/xui/pt/menu_inventory.xml b/indra/newview/skins/default/xui/pt/menu_inventory.xml
index 09e1fbf72e..a3a648eb34 100644..100755
--- a/indra/newview/skins/default/xui/pt/menu_inventory.xml
+++ b/indra/newview/skins/default/xui/pt/menu_inventory.xml
@@ -68,6 +68,7 @@
<menu_item_call label="Excluir pasta do sistema" name="Delete System Folder"/>
<menu_item_call label="Pasta conversa em conferência" name="Conference Chat Folder"/>
<menu_item_call label="Executar som" name="Sound Play"/>
+ <menu_item_call label="Copiar SLurl" name="url_copy"/>
<menu_item_call label="Sobre o marco" name="About Landmark"/>
<menu_item_call label="Executar animação" name="Animation Play"/>
<menu_item_call label="Executar áudio" name="Animation Audition"/>
diff --git a/indra/newview/skins/default/xui/pt/menu_inventory_add.xml b/indra/newview/skins/default/xui/pt/menu_inventory_add.xml
index 7a7ebc50af..7a7ebc50af 100644..100755
--- a/indra/newview/skins/default/xui/pt/menu_inventory_add.xml
+++ b/indra/newview/skins/default/xui/pt/menu_inventory_add.xml
diff --git a/indra/newview/skins/default/xui/pt/menu_inventory_gear_default.xml b/indra/newview/skins/default/xui/pt/menu_inventory_gear_default.xml
index 6faea517fe..6faea517fe 100644..100755
--- a/indra/newview/skins/default/xui/pt/menu_inventory_gear_default.xml
+++ b/indra/newview/skins/default/xui/pt/menu_inventory_gear_default.xml
diff --git a/indra/newview/skins/default/xui/pt/menu_land.xml b/indra/newview/skins/default/xui/pt/menu_land.xml
index 9182ce321a..2ebe85df6e 100644..100755
--- a/indra/newview/skins/default/xui/pt/menu_land.xml
+++ b/indra/newview/skins/default/xui/pt/menu_land.xml
@@ -6,4 +6,5 @@
<menu_item_call label="Comprar passe" name="Land Buy Pass"/>
<menu_item_call label="Construir" name="Create"/>
<menu_item_call label="Editar a topografia" name="Edit Terrain"/>
+ <menu_item_call label="Bloquear proprietário da partícula" name="Mute Particle"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/pt/menu_landmark.xml b/indra/newview/skins/default/xui/pt/menu_landmark.xml
index 6accfebee7..6accfebee7 100644..100755
--- a/indra/newview/skins/default/xui/pt/menu_landmark.xml
+++ b/indra/newview/skins/default/xui/pt/menu_landmark.xml
diff --git a/indra/newview/skins/default/xui/pt/menu_login.xml b/indra/newview/skins/default/xui/pt/menu_login.xml
index be94ad49db..cd840f3137 100644..100755
--- a/indra/newview/skins/default/xui/pt/menu_login.xml
+++ b/indra/newview/skins/default/xui/pt/menu_login.xml
@@ -17,7 +17,13 @@
<menu_item_call label="Mostrar TOS" name="TOS"/>
<menu_item_call label="Mostrar mensagem crítica" name="Critical"/>
<menu_item_call label="Test de Bugs de Conteúdo Web" name="Web Content Floater Debug Test"/>
- <menu label="Configurar nível de registro em log" name="Set Logging Level"/>
+ <menu label="Configurar nível de registro em log" name="Set Logging Level">
+ <menu_item_check label="Depurar" name="Debug"/>
+ <menu_item_check label="Info" name="Info"/>
+ <menu_item_check label="Aviso" name="Warning"/>
+ <menu_item_check label="Erro" name="Error"/>
+ <menu_item_check label="Nenhum" name="None"/>
+ </menu>
<menu_item_check label="Exibir seletor da grade" name="Show Grid Picker"/>
<menu_item_call label="Exibir painel de notificações" name="Show Notifications Console"/>
</menu>
diff --git a/indra/newview/skins/default/xui/pt/menu_media_ctrl.xml b/indra/newview/skins/default/xui/pt/menu_media_ctrl.xml
index ac84b02870..ac84b02870 100644..100755
--- a/indra/newview/skins/default/xui/pt/menu_media_ctrl.xml
+++ b/indra/newview/skins/default/xui/pt/menu_media_ctrl.xml
diff --git a/indra/newview/skins/default/xui/pt/menu_mini_map.xml b/indra/newview/skins/default/xui/pt/menu_mini_map.xml
index 6a3fe55de5..6a3fe55de5 100644..100755
--- a/indra/newview/skins/default/xui/pt/menu_mini_map.xml
+++ b/indra/newview/skins/default/xui/pt/menu_mini_map.xml
diff --git a/indra/newview/skins/default/xui/pt/menu_mode_change.xml b/indra/newview/skins/default/xui/pt/menu_mode_change.xml
deleted file mode 100644
index 314d3e409b..0000000000
--- a/indra/newview/skins/default/xui/pt/menu_mode_change.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<toggleable_menu name="Mode Change">
- <menu_item_check label="Básico" name="BasicMode"/>
- <menu_item_check label="Avançado" name="AdvancedMode"/>
-</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/pt/menu_model_import_gear_default.xml b/indra/newview/skins/default/xui/pt/menu_model_import_gear_default.xml
index 079f876add..079f876add 100644..100755
--- a/indra/newview/skins/default/xui/pt/menu_model_import_gear_default.xml
+++ b/indra/newview/skins/default/xui/pt/menu_model_import_gear_default.xml
diff --git a/indra/newview/skins/default/xui/pt/menu_mute_particle.xml b/indra/newview/skins/default/xui/pt/menu_mute_particle.xml
new file mode 100644
index 0000000000..be13c66d7a
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/menu_mute_particle.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<!-- *NOTE: See also menu_attachment_other.xml -->
+<context_menu name="Mute Particle Pie">
+ <menu_item_call label="Bloquear proprietário da partícula" name="Mute Particle"/>
+</context_menu>
diff --git a/indra/newview/skins/default/xui/pt/menu_navbar.xml b/indra/newview/skins/default/xui/pt/menu_navbar.xml
index 57c1471de3..57c1471de3 100644..100755
--- a/indra/newview/skins/default/xui/pt/menu_navbar.xml
+++ b/indra/newview/skins/default/xui/pt/menu_navbar.xml
diff --git a/indra/newview/skins/default/xui/pt/menu_nearby_chat.xml b/indra/newview/skins/default/xui/pt/menu_nearby_chat.xml
index f1ea83c837..f1ea83c837 100644..100755
--- a/indra/newview/skins/default/xui/pt/menu_nearby_chat.xml
+++ b/indra/newview/skins/default/xui/pt/menu_nearby_chat.xml
diff --git a/indra/newview/skins/default/xui/pt/menu_notification_well_button.xml b/indra/newview/skins/default/xui/pt/menu_notification_well_button.xml
index 43ad4134ec..43ad4134ec 100644..100755
--- a/indra/newview/skins/default/xui/pt/menu_notification_well_button.xml
+++ b/indra/newview/skins/default/xui/pt/menu_notification_well_button.xml
diff --git a/indra/newview/skins/default/xui/pt/menu_object.xml b/indra/newview/skins/default/xui/pt/menu_object.xml
index f4919e0c1f..a552a5de5a 100644..100755
--- a/indra/newview/skins/default/xui/pt/menu_object.xml
+++ b/indra/newview/skins/default/xui/pt/menu_object.xml
@@ -10,6 +10,8 @@
<menu_item_call label="Ficar de pé" name="Object Stand Up"/>
<menu_item_call label="Perfil do objeto" name="Object Inspect"/>
<menu_item_call label="Mais zoom" name="Zoom In"/>
+ <menu_item_call label="Exibir em linksets" name="show_in_linksets"/>
+ <menu_item_call label="Exibir em personagens" name="show_in_characters"/>
<context_menu label="Colocar no(a)" name="Put On">
<menu_item_call label="Vestir" name="Wear"/>
<menu_item_call label="Adicionar" name="Add"/>
@@ -26,4 +28,5 @@
<menu_item_call label="Pagar" name="Pay..."/>
<menu_item_call label="Comprar" name="Buy..."/>
<menu_item_call label="Excluir" name="Delete"/>
+ <menu_item_call label="Bloquear proprietário da partícula" name="Mute Particle"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/pt/menu_object_icon.xml b/indra/newview/skins/default/xui/pt/menu_object_icon.xml
index 7af760a6ee..df224a88fa 100644..100755
--- a/indra/newview/skins/default/xui/pt/menu_object_icon.xml
+++ b/indra/newview/skins/default/xui/pt/menu_object_icon.xml
@@ -2,4 +2,6 @@
<menu name="Object Icon Menu">
<menu_item_call label="Perfil do objeto..." name="Object Profile"/>
<menu_item_call label="Bloquear..." name="Block"/>
+ <menu_item_call label="Mostrar no mapa" name="show_on_map"/>
+ <menu_item_call label="Teletransportar para lugar do objeto" name="teleport_to_object"/>
</menu>
diff --git a/indra/newview/skins/default/xui/pt/menu_outfit_gear.xml b/indra/newview/skins/default/xui/pt/menu_outfit_gear.xml
index 894f1d741c..3602bdaac4 100644..100755
--- a/indra/newview/skins/default/xui/pt/menu_outfit_gear.xml
+++ b/indra/newview/skins/default/xui/pt/menu_outfit_gear.xml
@@ -23,6 +23,8 @@
<menu_item_call label="Novo cabelo" name="New Hair"/>
<menu_item_call label="Novos olhos" name="New Eyes"/>
</menu>
+ <menu_item_call label="Expandir todas as pastas" name="expand"/>
+ <menu_item_call label="Recolher todas as pastas" name="collapse"/>
<menu_item_call label="Renomear look" name="rename"/>
<menu_item_call label="Excluir visual" name="delete_outfit"/>
</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/pt/menu_outfit_tab.xml b/indra/newview/skins/default/xui/pt/menu_outfit_tab.xml
index 8db5e405b3..8db5e405b3 100644..100755
--- a/indra/newview/skins/default/xui/pt/menu_outfit_tab.xml
+++ b/indra/newview/skins/default/xui/pt/menu_outfit_tab.xml
diff --git a/indra/newview/skins/default/xui/pt/menu_participant_list.xml b/indra/newview/skins/default/xui/pt/menu_participant_list.xml
index 01f1d4ef80..01f1d4ef80 100644..100755
--- a/indra/newview/skins/default/xui/pt/menu_participant_list.xml
+++ b/indra/newview/skins/default/xui/pt/menu_participant_list.xml
diff --git a/indra/newview/skins/default/xui/pt/menu_participant_view.xml b/indra/newview/skins/default/xui/pt/menu_participant_view.xml
new file mode 100644
index 0000000000..b61108cf54
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/menu_participant_view.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="participant_manu_view">
+ <menu_item_check label="Ordenar conversas por tipo" name="sort_sessions_by_type"/>
+ <menu_item_check label="Ordenar conversas por nome" name="sort_sessions_by_name"/>
+ <menu_item_check label="Ordenar conversas por atividade recente" name="sort_sessions_by_recent"/>
+ <menu_item_check label="Ordenar participantes por nome" name="sort_participants_by_name"/>
+ <menu_item_check label="Ordenar participantes por atividade recente" name="sort_participants_by_recent"/>
+ <menu_item_call label="Preferências de bate-papo..." name="chat_preferences"/>
+ <menu_item_call label="Preferências de privacidade..." name="privacy_preferences"/>
+ <menu_item_check label="Registro de conversas..." name="Conversation"/>
+ <menu_item_check label="Traduzir Bate-papo local" name="Translate_chat"/>
+ <menu_item_check label="Configurações de tradução..." name="Translation_settings"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/pt/menu_people_blocked_gear.xml b/indra/newview/skins/default/xui/pt/menu_people_blocked_gear.xml
new file mode 100644
index 0000000000..8bbde9b38c
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/menu_people_blocked_gear.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_blocked_gear">
+ <menu_item_call label="Desbloquear" name="unblock"/>
+ <menu_item_call label="Perfil..." name="profile"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/pt/menu_people_blocked_plus.xml b/indra/newview/skins/default/xui/pt/menu_people_blocked_plus.xml
new file mode 100644
index 0000000000..e69935995c
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/menu_people_blocked_plus.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_blocked_plus">
+ <menu_item_call label="Bloquear residente por nome..." name="block_resident_by_name"/>
+ <menu_item_call label="Bloquear objeto por nome" name="block_object_by_name"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/pt/menu_people_blocked_view.xml b/indra/newview/skins/default/xui/pt/menu_people_blocked_view.xml
new file mode 100644
index 0000000000..b80d683c7b
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/menu_people_blocked_view.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_blocked_view">
+ <menu_item_check label="Ordenar por nome" name="sort_by_name"/>
+ <menu_item_check label="Ordenar por tipo" name="sort_by_type"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/pt/menu_people_friends_view.xml b/indra/newview/skins/default/xui/pt/menu_people_friends_view.xml
new file mode 100644
index 0000000000..46caeae310
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/menu_people_friends_view.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_group_plus">
+ <menu_item_check label="Ordenar por nome" name="sort_name"/>
+ <menu_item_check label="Ordenar por status" name="sort_status"/>
+ <menu_item_check label="Exibir ícones de pessoas" name="view_icons"/>
+ <menu_item_check label="Exibir permissões concedidas" name="view_permissions"/>
+ <menu_item_check label="Exibir registro de conversas..." name="view_conversation"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/pt/menu_people_friends_view_sort.xml b/indra/newview/skins/default/xui/pt/menu_people_friends_view_sort.xml
index e7c325010f..e7c325010f 100644..100755
--- a/indra/newview/skins/default/xui/pt/menu_people_friends_view_sort.xml
+++ b/indra/newview/skins/default/xui/pt/menu_people_friends_view_sort.xml
diff --git a/indra/newview/skins/default/xui/pt/menu_people_groups.xml b/indra/newview/skins/default/xui/pt/menu_people_groups.xml
index 9a924ad7b9..2ba7af17cd 100644..100755
--- a/indra/newview/skins/default/xui/pt/menu_people_groups.xml
+++ b/indra/newview/skins/default/xui/pt/menu_people_groups.xml
@@ -2,7 +2,7 @@
<menu name="menu_group_plus">
<menu_item_call label="Ver dados" name="View Info"/>
<menu_item_call label="Bate-papo" name="Chat"/>
- <menu_item_call label="Ligar" name="Call"/>
+ <menu_item_call label="Chamada de voz" name="Call"/>
<menu_item_call label="Ativar" name="Activate"/>
<menu_item_call label="Sair" name="Leave"/>
</menu>
diff --git a/indra/newview/skins/default/xui/pt/menu_people_groups_view.xml b/indra/newview/skins/default/xui/pt/menu_people_groups_view.xml
new file mode 100644
index 0000000000..637e591ae1
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/menu_people_groups_view.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_group_plus">
+ <menu_item_check label="Mostrar ícones de grupos" name="Display Group Icons"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/pt/menu_people_groups_view_sort.xml b/indra/newview/skins/default/xui/pt/menu_people_groups_view_sort.xml
index 86a9d2263f..86a9d2263f 100644..100755
--- a/indra/newview/skins/default/xui/pt/menu_people_groups_view_sort.xml
+++ b/indra/newview/skins/default/xui/pt/menu_people_groups_view_sort.xml
diff --git a/indra/newview/skins/default/xui/pt/menu_people_nearby.xml b/indra/newview/skins/default/xui/pt/menu_people_nearby.xml
index 7c720f262b..51464fed68 100644..100755
--- a/indra/newview/skins/default/xui/pt/menu_people_nearby.xml
+++ b/indra/newview/skins/default/xui/pt/menu_people_nearby.xml
@@ -1,13 +1,16 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Avatar Context Menu">
- <menu_item_call label="Ver perfil" name="View Profile"/>
- <menu_item_call label="Adicionar amigo..." name="Add Friend"/>
- <menu_item_call label="Remover amigo..." name="Remove Friend"/>
- <menu_item_call label="MI" name="IM"/>
- <menu_item_call label="Ligar" name="Call"/>
- <menu_item_call label="Mapa" name="Map"/>
- <menu_item_call label="Compartilhar" name="Share"/>
- <menu_item_call label="Pagar" name="Pay"/>
- <menu_item_check label="Bloquear/desbloquear" name="Block/Unblock"/>
- <menu_item_call label="Teletransportar?" name="teleport"/>
+ <menu_item_call label="Exibir perfil" name="view_profile"/>
+ <menu_item_call label="MI" name="im"/>
+ <menu_item_call label="Oferecer teletransporte" name="offer_teleport"/>
+ <menu_item_call label="Chamada de voz" name="voice_call"/>
+ <menu_item_call label="Exibir histórico de bate-papo..." name="chat_history"/>
+ <menu_item_call label="Adicionar amigo" name="add_friend"/>
+ <menu_item_call label="Remover amigo" name="remove_friend"/>
+ <menu_item_call label="Convidar para entrar no grupo..." name="invite_to_group"/>
+ <menu_item_call label="Mais zoom" name="zoom_in"/>
+ <menu_item_call label="Mapa" name="map"/>
+ <menu_item_call label="Compartilhar" name="share"/>
+ <menu_item_call label="Pagar" name="pay"/>
+ <menu_item_check label="Bloquear/desbloquear" name="block_unblock"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/pt/menu_people_nearby_multiselect.xml b/indra/newview/skins/default/xui/pt/menu_people_nearby_multiselect.xml
index 79edb96b1c..7f3c6ace27 100644..100755
--- a/indra/newview/skins/default/xui/pt/menu_people_nearby_multiselect.xml
+++ b/indra/newview/skins/default/xui/pt/menu_people_nearby_multiselect.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Multi-Selected People Context Menu">
- <menu_item_call label="Adicionar amigo..." name="Add Friends"/>
- <menu_item_call label="Remover amigo..." name="Remove Friend"/>
- <menu_item_call label="MI" name="IM"/>
- <menu_item_call label="Ligar" name="Call"/>
- <menu_item_call label="Compartilhar" name="Share"/>
- <menu_item_call label="Pagar" name="Pay"/>
- <menu_item_call label="Teletransportar?" name="teleport"/>
+ <menu_item_call label="Adicionar amigo..." name="add_friends"/>
+ <menu_item_call label="Remover amigo..." name="remove_friends"/>
+ <menu_item_call label="MI" name="im"/>
+ <menu_item_call label="Ligar" name="call"/>
+ <menu_item_call label="Compartilhar" name="share"/>
+ <menu_item_call label="Pagar" name="pay"/>
+ <menu_item_call label="Oferecer teletransporte" name="offer_teleport"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/pt/menu_people_nearby_view.xml b/indra/newview/skins/default/xui/pt/menu_people_nearby_view.xml
new file mode 100644
index 0000000000..bce015e732
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/menu_people_nearby_view.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_group_plus">
+ <menu_item_check label="Ordenar por conversas mais recentes" name="sort_by_recent_speakers"/>
+ <menu_item_check label="Ordenar por nome" name="sort_name"/>
+ <menu_item_check label="Ordenar por distância" name="sort_distance"/>
+ <menu_item_check label="Exibir ícones de pessoas" name="view_icons"/>
+ <menu_item_check label="Exibir mapa" name="view_map"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/pt/menu_people_nearby_view_sort.xml b/indra/newview/skins/default/xui/pt/menu_people_nearby_view_sort.xml
index 0d32d58de4..0d32d58de4 100644..100755
--- a/indra/newview/skins/default/xui/pt/menu_people_nearby_view_sort.xml
+++ b/indra/newview/skins/default/xui/pt/menu_people_nearby_view_sort.xml
diff --git a/indra/newview/skins/default/xui/pt/menu_people_recent_view.xml b/indra/newview/skins/default/xui/pt/menu_people_recent_view.xml
new file mode 100644
index 0000000000..e4b368fe14
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/menu_people_recent_view.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_group_plus">
+ <menu_item_check label="Ordenar por mais recente" name="sort_most"/>
+ <menu_item_check label="Ordenar por nome" name="sort_name"/>
+ <menu_item_check label="Exibir ícones de pessoas" name="view_icons"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/pt/menu_people_recent_view_sort.xml b/indra/newview/skins/default/xui/pt/menu_people_recent_view_sort.xml
index f3b89e01cd..f3b89e01cd 100644..100755
--- a/indra/newview/skins/default/xui/pt/menu_people_recent_view_sort.xml
+++ b/indra/newview/skins/default/xui/pt/menu_people_recent_view_sort.xml
diff --git a/indra/newview/skins/default/xui/pt/menu_picks.xml b/indra/newview/skins/default/xui/pt/menu_picks.xml
index 8b9e10fc02..8b9e10fc02 100644..100755
--- a/indra/newview/skins/default/xui/pt/menu_picks.xml
+++ b/indra/newview/skins/default/xui/pt/menu_picks.xml
diff --git a/indra/newview/skins/default/xui/pt/menu_picks_plus.xml b/indra/newview/skins/default/xui/pt/menu_picks_plus.xml
index 95a7c05262..95a7c05262 100644..100755
--- a/indra/newview/skins/default/xui/pt/menu_picks_plus.xml
+++ b/indra/newview/skins/default/xui/pt/menu_picks_plus.xml
diff --git a/indra/newview/skins/default/xui/pt/menu_place.xml b/indra/newview/skins/default/xui/pt/menu_place.xml
index 282ea20a7a..282ea20a7a 100644..100755
--- a/indra/newview/skins/default/xui/pt/menu_place.xml
+++ b/indra/newview/skins/default/xui/pt/menu_place.xml
diff --git a/indra/newview/skins/default/xui/pt/menu_place_add_button.xml b/indra/newview/skins/default/xui/pt/menu_place_add_button.xml
index d099d04f8d..d099d04f8d 100644..100755
--- a/indra/newview/skins/default/xui/pt/menu_place_add_button.xml
+++ b/indra/newview/skins/default/xui/pt/menu_place_add_button.xml
diff --git a/indra/newview/skins/default/xui/pt/menu_places_gear_folder.xml b/indra/newview/skins/default/xui/pt/menu_places_gear_folder.xml
index 7cba70a110..7cba70a110 100644..100755
--- a/indra/newview/skins/default/xui/pt/menu_places_gear_folder.xml
+++ b/indra/newview/skins/default/xui/pt/menu_places_gear_folder.xml
diff --git a/indra/newview/skins/default/xui/pt/menu_places_gear_landmark.xml b/indra/newview/skins/default/xui/pt/menu_places_gear_landmark.xml
index fec0911fcf..fec0911fcf 100644..100755
--- a/indra/newview/skins/default/xui/pt/menu_places_gear_landmark.xml
+++ b/indra/newview/skins/default/xui/pt/menu_places_gear_landmark.xml
diff --git a/indra/newview/skins/default/xui/pt/menu_profile_overflow.xml b/indra/newview/skins/default/xui/pt/menu_profile_overflow.xml
index d41ecbd755..d41ecbd755 100644..100755
--- a/indra/newview/skins/default/xui/pt/menu_profile_overflow.xml
+++ b/indra/newview/skins/default/xui/pt/menu_profile_overflow.xml
diff --git a/indra/newview/skins/default/xui/pt/menu_save_outfit.xml b/indra/newview/skins/default/xui/pt/menu_save_outfit.xml
index 61c6b9202f..61c6b9202f 100644..100755
--- a/indra/newview/skins/default/xui/pt/menu_save_outfit.xml
+++ b/indra/newview/skins/default/xui/pt/menu_save_outfit.xml
diff --git a/indra/newview/skins/default/xui/pt/menu_script_chiclet.xml b/indra/newview/skins/default/xui/pt/menu_script_chiclet.xml
index ccf3878e14..ccf3878e14 100644..100755
--- a/indra/newview/skins/default/xui/pt/menu_script_chiclet.xml
+++ b/indra/newview/skins/default/xui/pt/menu_script_chiclet.xml
diff --git a/indra/newview/skins/default/xui/pt/menu_slurl.xml b/indra/newview/skins/default/xui/pt/menu_slurl.xml
index 6d4c84fc3c..6d4c84fc3c 100644..100755
--- a/indra/newview/skins/default/xui/pt/menu_slurl.xml
+++ b/indra/newview/skins/default/xui/pt/menu_slurl.xml
diff --git a/indra/newview/skins/default/xui/pt/menu_teleport_history_gear.xml b/indra/newview/skins/default/xui/pt/menu_teleport_history_gear.xml
index f034509be8..f034509be8 100644..100755
--- a/indra/newview/skins/default/xui/pt/menu_teleport_history_gear.xml
+++ b/indra/newview/skins/default/xui/pt/menu_teleport_history_gear.xml
diff --git a/indra/newview/skins/default/xui/pt/menu_teleport_history_item.xml b/indra/newview/skins/default/xui/pt/menu_teleport_history_item.xml
index ec1e7a0950..ec1e7a0950 100644..100755
--- a/indra/newview/skins/default/xui/pt/menu_teleport_history_item.xml
+++ b/indra/newview/skins/default/xui/pt/menu_teleport_history_item.xml
diff --git a/indra/newview/skins/default/xui/pt/menu_teleport_history_tab.xml b/indra/newview/skins/default/xui/pt/menu_teleport_history_tab.xml
index 6a633cf74c..6a633cf74c 100644..100755
--- a/indra/newview/skins/default/xui/pt/menu_teleport_history_tab.xml
+++ b/indra/newview/skins/default/xui/pt/menu_teleport_history_tab.xml
diff --git a/indra/newview/skins/default/xui/pt/menu_text_editor.xml b/indra/newview/skins/default/xui/pt/menu_text_editor.xml
index 31c284c6ed..a26b50e1c2 100644..100755
--- a/indra/newview/skins/default/xui/pt/menu_text_editor.xml
+++ b/indra/newview/skins/default/xui/pt/menu_text_editor.xml
@@ -1,5 +1,12 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Text editor context menu">
+ <menu_item_call label="(desconhecido)" name="Suggestion 1"/>
+ <menu_item_call label="(desconhecido)" name="Suggestion 2"/>
+ <menu_item_call label="(desconhecido)" name="Suggestion 3"/>
+ <menu_item_call label="(desconhecido)" name="Suggestion 4"/>
+ <menu_item_call label="(desconhecido)" name="Suggestion 5"/>
+ <menu_item_call label="Adicionar ao dicionário" name="Add to Dictionary"/>
+ <menu_item_call label="Adicionar para ignorar" name="Add to Ignore"/>
<menu_item_call label="Cortar" name="Cut"/>
<menu_item_call label="Copiar" name="Copy"/>
<menu_item_call label="Colar" name="Paste"/>
diff --git a/indra/newview/skins/default/xui/pt/menu_toolbars.xml b/indra/newview/skins/default/xui/pt/menu_toolbars.xml
index b58a1a6e4f..b58a1a6e4f 100644..100755
--- a/indra/newview/skins/default/xui/pt/menu_toolbars.xml
+++ b/indra/newview/skins/default/xui/pt/menu_toolbars.xml
diff --git a/indra/newview/skins/default/xui/pt/menu_topinfobar.xml b/indra/newview/skins/default/xui/pt/menu_topinfobar.xml
index d9347950b1..d9347950b1 100644..100755
--- a/indra/newview/skins/default/xui/pt/menu_topinfobar.xml
+++ b/indra/newview/skins/default/xui/pt/menu_topinfobar.xml
diff --git a/indra/newview/skins/default/xui/pt/menu_url_agent.xml b/indra/newview/skins/default/xui/pt/menu_url_agent.xml
index ba5e055124..102df18b28 100644..100755
--- a/indra/newview/skins/default/xui/pt/menu_url_agent.xml
+++ b/indra/newview/skins/default/xui/pt/menu_url_agent.xml
@@ -1,6 +1,9 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Url Popup">
- <menu_item_call label="Mostrar perfil de residente" name="show_agent"/>
+ <menu_item_call label="Exibir perfil" name="show_agent"/>
+ <menu_item_call label="Enviar MI..." name="send_im"/>
+ <menu_item_call label="Adicionar amigo..." name="add_friend"/>
+ <menu_item_call label="Remover amigo..." name="remove_friend"/>
<menu_item_call label="Copiar nome para área de transferência" name="url_copy_label"/>
<menu_item_call label="Copiar SLurl para área de transferência" name="url_copy"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/pt/menu_url_group.xml b/indra/newview/skins/default/xui/pt/menu_url_group.xml
index 5b67a69c9a..5b67a69c9a 100644..100755
--- a/indra/newview/skins/default/xui/pt/menu_url_group.xml
+++ b/indra/newview/skins/default/xui/pt/menu_url_group.xml
diff --git a/indra/newview/skins/default/xui/pt/menu_url_http.xml b/indra/newview/skins/default/xui/pt/menu_url_http.xml
index e53a2572b8..e53a2572b8 100644..100755
--- a/indra/newview/skins/default/xui/pt/menu_url_http.xml
+++ b/indra/newview/skins/default/xui/pt/menu_url_http.xml
diff --git a/indra/newview/skins/default/xui/pt/menu_url_inventory.xml b/indra/newview/skins/default/xui/pt/menu_url_inventory.xml
index 45c14355d0..45c14355d0 100644..100755
--- a/indra/newview/skins/default/xui/pt/menu_url_inventory.xml
+++ b/indra/newview/skins/default/xui/pt/menu_url_inventory.xml
diff --git a/indra/newview/skins/default/xui/pt/menu_url_map.xml b/indra/newview/skins/default/xui/pt/menu_url_map.xml
index ba114cccaa..ba114cccaa 100644..100755
--- a/indra/newview/skins/default/xui/pt/menu_url_map.xml
+++ b/indra/newview/skins/default/xui/pt/menu_url_map.xml
diff --git a/indra/newview/skins/default/xui/pt/menu_url_objectim.xml b/indra/newview/skins/default/xui/pt/menu_url_objectim.xml
index c197444181..2cd0f52ef3 100644..100755
--- a/indra/newview/skins/default/xui/pt/menu_url_objectim.xml
+++ b/indra/newview/skins/default/xui/pt/menu_url_objectim.xml
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Url Popup">
- <menu_item_call label="Mostrar informações sobre o objeto" name="show_object"/>
+ <menu_item_call label="Perfil do objeto..." name="show_object"/>
+ <menu_item_call label="Bloquear..." name="block_object"/>
<menu_item_call label="Mostrar no mapa" name="show_on_map"/>
<menu_item_call label="Teletransportar para lugar do objeto" name="teleport_to_object"/>
<menu_item_call label="Copiar nome do objeto para área de transferência" name="url_copy_label"/>
diff --git a/indra/newview/skins/default/xui/pt/menu_url_parcel.xml b/indra/newview/skins/default/xui/pt/menu_url_parcel.xml
index 6cc668bfd3..6cc668bfd3 100644..100755
--- a/indra/newview/skins/default/xui/pt/menu_url_parcel.xml
+++ b/indra/newview/skins/default/xui/pt/menu_url_parcel.xml
diff --git a/indra/newview/skins/default/xui/pt/menu_url_slapp.xml b/indra/newview/skins/default/xui/pt/menu_url_slapp.xml
index d0784149ac..d0784149ac 100644..100755
--- a/indra/newview/skins/default/xui/pt/menu_url_slapp.xml
+++ b/indra/newview/skins/default/xui/pt/menu_url_slapp.xml
diff --git a/indra/newview/skins/default/xui/pt/menu_url_slurl.xml b/indra/newview/skins/default/xui/pt/menu_url_slurl.xml
index 7216ccf0b3..7216ccf0b3 100644..100755
--- a/indra/newview/skins/default/xui/pt/menu_url_slurl.xml
+++ b/indra/newview/skins/default/xui/pt/menu_url_slurl.xml
diff --git a/indra/newview/skins/default/xui/pt/menu_url_teleport.xml b/indra/newview/skins/default/xui/pt/menu_url_teleport.xml
index f007425646..f007425646 100644..100755
--- a/indra/newview/skins/default/xui/pt/menu_url_teleport.xml
+++ b/indra/newview/skins/default/xui/pt/menu_url_teleport.xml
diff --git a/indra/newview/skins/default/xui/pt/menu_viewer.xml b/indra/newview/skins/default/xui/pt/menu_viewer.xml
index d7d5d59a33..e6eceb5f2f 100644..100755
--- a/indra/newview/skins/default/xui/pt/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/pt/menu_viewer.xml
@@ -17,8 +17,8 @@
<menu_item_call label="Andar/correr/voar..." name="Walk / run / fly"/>
</menu>
<menu label="Status" name="Status">
- <menu_item_call label="Ausente" name="Set Away"/>
- <menu_item_call label="Ocupado" name="Set Busy"/>
+ <menu_item_check label="Ausente" name="Away"/>
+ <menu_item_check label="Não perturbe" name="Do Not Disturb"/>
</menu>
<menu_item_call label="Comprar L$..." name="Buy and Sell L$"/>
<menu_item_call label="Caixa de saída do lojista..." name="MerchantOutbox"/>
@@ -28,17 +28,25 @@
<menu_item_call label="Preferências..." name="Preferences"/>
<menu_item_call label="Botões da barra de ferramentas..." name="Toolbars"/>
<menu_item_call label="Ocultar todos os controles" name="Hide UI"/>
+ <menu_item_check label="Exibir anexos de HUD" name="Show HUD Attachments"/>
<menu_item_call label="Sair do [APP_NAME]" name="Quit"/>
</menu>
<menu label="Comunicar" name="Communicate">
- <menu_item_check label="Bate-papo..." name="Nearby Chat"/>
+ <menu_item_check label="Conversas..." name="Conversations"/>
+ <menu_item_check label="Bate-papo local..." name="Nearby Chat"/>
<menu_item_check label="Falar" name="Speak"/>
- <menu_item_check label="Configurações de voz..." name="Nearby Voice"/>
- <menu_item_check label="Distorção de voz..." name="ShowVoice"/>
+ <menu_item_check label="Registro de conversas..." name="Conversation Log..."/>
+ <menu label="Distorção de voz" name="VoiceMorphing">
+ <menu_item_check label="Não distorcer voz" name="NoVoiceMorphing"/>
+ <menu_item_check label="Visualizar..." name="Preview"/>
+ <menu_item_call label="Assinar..." name="Subscribe"/>
+ </menu>
<menu_item_check label="Gestos..." name="Gestures"/>
- <menu_item_call label="Amigos" name="My Friends"/>
- <menu_item_call label="Grupos" name="My Groups"/>
- <menu_item_call label="Pessoas próximas" name="Active Speakers"/>
+ <menu_item_check label="Amigos" name="My Friends"/>
+ <menu_item_check label="Grupos" name="My Groups"/>
+ <menu_item_check label="Pessoas próximas" name="Active Speakers"/>
+ <menu_item_call label="Lista de bloqueados" name="Block List"/>
+ <menu_item_check label="Não perturbe" name="Do Not Disturb"/>
</menu>
<menu label="Mundo" name="World">
<menu_item_call label="Criar marco deste lugar" name="Create Landmark Here"/>
@@ -107,23 +115,29 @@
<menu_item_call label="Incluir próxima parte" name="Include Next Part"/>
<menu_item_call label="Incluir parte anterior" name="Include Previous Part"/>
</menu>
+ <menu_item_call label="Linksets..." name="pathfinding_linkset_menu_item"/>
<menu_item_call label="Enfocar seleção" name="Focus on Selection"/>
<menu_item_call label="Ampliar seleção" name="Zoom to Selection"/>
<menu label="Objeto:" name="Object">
<menu_item_call label="Comprar" name="Menu Object Buy"/>
<menu_item_call label="Pegar" name="Menu Object Take"/>
<menu_item_call label="Pegar uma cópia" name="Take Copy"/>
- <menu_item_call label="Salvar no meu inventário" name="Save Object Back to My Inventory"/>
<menu_item_call label="Salvar objeto de volta aos conteúdos do objeto" name="Save Object Back to Object Contents"/>
<menu_item_call label="Devolver objeto" name="Return Object back to Owner"/>
</menu>
<menu label="Scripts" name="Scripts">
- <menu_item_call label="Recompilar scripts (LSL)" name="Mono"/>
+ <menu_item_call label="Recompilar scripts (Mono)" name="Mono"/>
<menu_item_call label="Recompilar scripts (LSL)" name="LSL"/>
<menu_item_call label="Resetar scripts" name="Reset Scripts"/>
<menu_item_call label="Scripts em modo execução" name="Set Scripts to Running"/>
<menu_item_call label="Scripts em modo não execução" name="Set Scripts to Not Running"/>
</menu>
+ <menu label="Pathfinding" name="Pathfinding">
+ <menu_item_call label="Linksets..." name="pathfinding_linksets_menu_item"/>
+ <menu_item_call label="Personagens..." name="pathfinding_characters_menu_item"/>
+ <menu_item_call label="Visualização/teste..." name="pathfinding_console_menu_item"/>
+ <menu_item_call label="Recarregar região" name="pathfinding_rebake_navmesh_item"/>
+ </menu>
<menu label="Opções" name="Options">
<menu_item_check label="Mostrar permissões avançadas" name="DebugPermissions"/>
<menu_item_check label="Só selecionar meus objetos" name="Select Only My Objects"/>
@@ -152,6 +166,13 @@
<menu label="Ajuda" name="Help">
<menu_item_call label="Como..." name="How To"/>
<menu_item_call label="[SECOND_LIFE] Ajuda" name="Second Life Help"/>
+ <menu_item_call label="Guia do usuário" name="User’s guide"/>
+ <menu_item_call label="Base de conhecimento" name="Knowledge Base"/>
+ <menu_item_call label="Wiki" name="Wiki"/>
+ <menu_item_call label="Fóruns da comunidade" name="Community Forums"/>
+ <menu_item_call label="Portal de suporte" name="Support portal"/>
+ <menu_item_call label="Notícias do [SECOND_LIFE]" name="Second Life News"/>
+ <menu_item_call label="Blogs do [SECOND_LIFE]" name="Second Life Blogs"/>
<menu_item_call label="Denunciar abuso" name="Report Abuse"/>
<menu_item_call label="Relatar bug" name="Report Bug"/>
<menu_item_call label="Sobre [APP_NAME]" name="About Second Life"/>
@@ -163,7 +184,7 @@
<menu_item_check label="Limitar distância da seleção" name="Limit Select Distance"/>
<menu_item_check label="Disable Camera Constraints" name="Disable Camera Distance"/>
<menu_item_check label="Foto de alta resolução" name="HighResSnapshot"/>
- <menu_item_check label="Compactar fotos para HD" name="QuietSnapshotsToDisk"/>
+ <menu_item_check label="Fotos sem barulho para HD" name="QuietSnapshotsToDisk"/>
<menu label="Ferramentas de desempenho" name="Performance Tools">
<menu_item_call label="Medidor de lag" name="Lag Meter"/>
<menu_item_check label="Barra de estatísticas" name="Statistics Bar"/>
@@ -174,7 +195,6 @@
<menu_item_check label="Esconder partículas" name="Hide Particles"/>
<menu_item_check label="Ocultar seleções" name="Hide Selected"/>
<menu_item_check label="Realçar transparentes" name="Highlight Transparent"/>
- <menu_item_check label="Mostrar anexos HUD" name="Show HUD Attachments"/>
<menu_item_check label="Mostrar retículo na vista subjetiva" name="ShowCrosshairs"/>
</menu>
<menu label="Tipos de renderização" name="Rendering Types">
@@ -226,11 +246,10 @@
<menu_item_check label="Painel de textura" name="Texture Console"/>
<menu_item_check label="Console de depuração" name="Debug Console"/>
<menu_item_call label="Painel de avisos" name="Notifications"/>
- <menu_item_check label="Painel de tamanho de textura" name="Texture Size"/>
- <menu_item_check label="Painel de texturas" name="Texture Category"/>
<menu_item_check label="Tempos" name="Fast Timers"/>
<menu_item_check label="Memória" name="Memory"/>
<menu_item_check label="Estatísticas da cena" name="Scene Statistics"/>
+ <menu_item_call label="Painel de depuração de obtenção de textura" name="Texture Fetch Debug Console"/>
<menu_item_call label="Region Info to Debug Console" name="Region Info to Debug Console"/>
<menu_item_check label="Câmera:" name="Camera"/>
<menu_item_check label="Vento" name="Wind"/>
@@ -260,6 +279,7 @@
<menu_item_check label="Camera Offset" name="Camera Offset"/>
<menu_item_check label="Taxa de quadros aleatória" name="Randomize Framerate"/>
<menu_item_check label="Frame Test" name="Frame Test"/>
+ <menu_item_call label="Perfil do quadro" name="Frame Profile"/>
</menu>
<menu label="Render Metadata" name="Render Metadata">
<menu_item_check label="Normais" name="Normals"/>
@@ -271,18 +291,24 @@
<menu_item_check label="Renderizar complexidade" name="rendercomplexity"/>
<menu_item_check label="Bytes do anexo" name="attachment bytes"/>
<menu_item_check label="Esculpir" name="Sculpt"/>
+ <menu label="Densidade da textura" name="Texture Density">
+ <menu_item_check label="Nenhuma" name="None"/>
+ <menu_item_check label="Atual" name="Current"/>
+ <menu_item_check label="Desejada" name="Desired"/>
+ <menu_item_check label="Completa" name="Full"/>
+ </menu>
</menu>
<menu label="Rendering" name="Rendering">
<menu_item_check label="Axes" name="Axes"/>
+ <menu_item_call label="Informações sobre o material selecionado" name="Selected Material Info"/>
<menu_item_check label="Wireframe" name="Wireframe"/>
- <menu_item_check label="Iluminação e sombras" name="Lighting and Shadows"/>
+ <menu_item_check label="Modelo avançado de luzes" name="Advanced Lighting Model"/>
<menu_item_check label="Sombras da projeção do sol/lua" name="Shadows from Sun/Moon/Projectors"/>
<menu_item_check label="SSAO e sombra suave" name="SSAO and Shadow Smoothing"/>
<menu_item_check label="Máscaras alpha automáticas (adiadas)" name="Automatic Alpha Masks (deferred)"/>
<menu_item_check label="Máscaras alpha automáticas (sem adiar)" name="Automatic Alpha Masks (non-deferred)"/>
<menu_item_check label="Texturas de animação" name="Animation Textures"/>
<menu_item_check label="Desativar texturas" name="Disable Textures"/>
- <menu_item_check label="Atlas texturizado (fase experimental)" name="Texture Atlas"/>
<menu_item_check label="Render Attached Lights" name="Render Attached Lights"/>
<menu_item_check label="Render Attached Particles" name="Render Attached Particles"/>
<menu_item_check label="Objetos iridescentes" name="Hover Glow Objects"/>
@@ -301,7 +327,6 @@
<menu_item_call label="Teste de mídia do navegador" name="Web Browser Test"/>
<menu_item_call label="Navegador de conteúdo web" name="Web Content Browser"/>
<menu_item_call label="Print Selected Object Info" name="Print Selected Object Info"/>
- <menu_item_call label="Dados de memória" name="Memory Stats"/>
<menu_item_check label="Console de depuração de região" name="Region Debug Console"/>
<menu_item_check label="Debug Clicks" name="Debug Clicks"/>
<menu_item_check label="Debug Mouse Events" name="Debug Mouse Events"/>
@@ -325,9 +350,14 @@
<menu_item_call label="Toggle Character Geometry" name="Toggle Character Geometry"/>
<menu_item_check label="Allow Select Avatar" name="Allow Select Avatar"/>
</menu>
+ <menu label="Velocidade de animação" name="Animation Speed">
+ <menu_item_call label="Todas as animações 10% mais rápidas" name="All Animations 10 Faster"/>
+ <menu_item_call label="Todas as animações 10% mais lentas" name="All Animations 10 Slower"/>
+ <menu_item_call label="Redefinir todas as velocidades de animação" name="Reset All Animation Speed"/>
+ <menu_item_check label="Animações em câmera lenta" name="Slow Motion Animations"/>
+ </menu>
<menu_item_call label="Force Params to Default" name="Force Params to Default"/>
<menu_item_check label="Dados da animação" name="Animation Info"/>
- <menu_item_check label="Mostrar animação de movimento" name="Slow Motion Animations"/>
<menu_item_check label="Disable Level Of Detail" name="Disable LOD"/>
<menu_item_check label="Show Collision Skeleton" name="Show Collision Skeleton"/>
<menu_item_check label="Display Agent Target" name="Display Agent Target"/>
diff --git a/indra/newview/skins/default/xui/pt/menu_wearable_list_item.xml b/indra/newview/skins/default/xui/pt/menu_wearable_list_item.xml
index 2487f6779f..2487f6779f 100644..100755
--- a/indra/newview/skins/default/xui/pt/menu_wearable_list_item.xml
+++ b/indra/newview/skins/default/xui/pt/menu_wearable_list_item.xml
diff --git a/indra/newview/skins/default/xui/pt/menu_wearing_gear.xml b/indra/newview/skins/default/xui/pt/menu_wearing_gear.xml
index 75dca703cb..75dca703cb 100644..100755
--- a/indra/newview/skins/default/xui/pt/menu_wearing_gear.xml
+++ b/indra/newview/skins/default/xui/pt/menu_wearing_gear.xml
diff --git a/indra/newview/skins/default/xui/pt/menu_wearing_tab.xml b/indra/newview/skins/default/xui/pt/menu_wearing_tab.xml
index 4e6e52ebc7..4e6e52ebc7 100644..100755
--- a/indra/newview/skins/default/xui/pt/menu_wearing_tab.xml
+++ b/indra/newview/skins/default/xui/pt/menu_wearing_tab.xml
diff --git a/indra/newview/skins/default/xui/pt/mime_types.xml b/indra/newview/skins/default/xui/pt/mime_types.xml
index f9c0496eea..f9c0496eea 100644..100755
--- a/indra/newview/skins/default/xui/pt/mime_types.xml
+++ b/indra/newview/skins/default/xui/pt/mime_types.xml
diff --git a/indra/newview/skins/default/xui/pt/mime_types_linux.xml b/indra/newview/skins/default/xui/pt/mime_types_linux.xml
index 789843cbba..789843cbba 100644..100755
--- a/indra/newview/skins/default/xui/pt/mime_types_linux.xml
+++ b/indra/newview/skins/default/xui/pt/mime_types_linux.xml
diff --git a/indra/newview/skins/default/xui/pt/mime_types_mac.xml b/indra/newview/skins/default/xui/pt/mime_types_mac.xml
index 34b40e94ab..34b40e94ab 100644..100755
--- a/indra/newview/skins/default/xui/pt/mime_types_mac.xml
+++ b/indra/newview/skins/default/xui/pt/mime_types_mac.xml
diff --git a/indra/newview/skins/default/xui/pt/notifications.xml b/indra/newview/skins/default/xui/pt/notifications.xml
index 3b39c0f92c..d5096ec858 100644..100755
--- a/indra/newview/skins/default/xui/pt/notifications.xml
+++ b/indra/newview/skins/default/xui/pt/notifications.xml
@@ -37,6 +37,12 @@
<button name="Help" text="$helptext"/>
</form>
</template>
+ <template name="okhelpignore">
+ <form>
+ <button name="OK_okhelpignore" text="$yestext"/>
+ <button name="Help_okhelpignore" text="$helptext"/>
+ </form>
+ </template>
<template name="yesnocancelbuttons">
<form>
<button name="Yes" text="$yestext"/>
@@ -203,6 +209,14 @@ Qualquer membro numa função com esta habilidade, pode atribuir a sí mesmo --
Adicionar esta habilidade a &apos;[ROLE_NAME]&apos;?
<usetemplate name="okcancelbuttons" notext="Não" yestext="Sim"/>
</notification>
+ <notification name="EjectGroupMemberWarning">
+ Você está prestes a expulsar [AVATAR_NAME] do grupo.
+ <usetemplate ignoretext="Confirmar expulsão de um participante do grupo" name="okcancelignore" notext="Cancelar" yestext="Expulsar"/>
+ </notification>
+ <notification name="EjectGroupMembersWarning">
+ Você está prestes a expulsar [COUNT] membros do grupo.
+ <usetemplate ignoretext="Confirmar expulsão de diversos membros do grupo" name="okcancelignore" notext="Cancelar" yestext="Expulsar"/>
+ </notification>
<notification name="AttachmentDrop">
Você está prestes a largar seu anexo.
Tem certeza de que quer prosseguir?
@@ -357,13 +371,19 @@ Digite o nome de usuário de seu avatar.
É preciso ter uma conta para entrar no [SECOND_LIFE]. Deseja criar uma conta agora?
<url name="url">
- https://join.secondlife.com/index.php?lang=pt-BR
+ [create_account_url]
</url>
<usetemplate name="okcancelbuttons" notext="Tentar novamente" yestext="Abrir conta"/>
</notification>
<notification name="InvalidCredentialFormat">
Digite o nome de usuário ou o nome e sobrenome do seu avatar no campo Nome de usuário, depois entre em sua conta novamente.
</notification>
+ <notification name="InvalidGrid">
+ &apos;[GRID]&apos; não é um identificador de grade válido.
+ </notification>
+ <notification name="InvalidLocationSLURL">
+ Seu ponto de partida não especificou uma grade válida.
+ </notification>
<notification name="DeleteClassified">
Apagar classificado&apos;[NAME]&apos;?
Não há reembolso por taxas já pagas.
@@ -466,8 +486,8 @@ O objeto pode estar fora de alcance ou ter sido deletado.
Houve um problema em salvar uma compilação de script devido a seguinte razão: [REASON]. Por favor, tente salvar novamente o script mais tarde.
</notification>
<notification name="StartRegionEmpty">
- Oops, você ainda não definiu sua região de partida.
-Digite o nome da região na caixa &apos;Ponto de partida&apos; ou selecione &apos;Última localização&apos; ou &apos;Meu início&apos; como ponto de partida.
+ Sua região de partida não está definida.
+Digite o nome da região na caixa &apos;Ponto de partida&apos; ou selecione &apos;Meu último local&apos; ou &apos;Minha casa&apos; como ponto de partida.
<usetemplate name="okbutton" yestext="OK"/>
</notification>
<notification name="CouldNotStartStopScript">
@@ -489,6 +509,33 @@ Consultar [_URL] para mais informações?
</url>
<usetemplate ignoretext="O hardware do meu computador não é suportado" name="okcancelignore" notext="Não" yestext="Sim"/>
</notification>
+ <notification name="IntelOldDriver">
+ Provavelmente, há um driver mais recente para o seu chip gráfico. A atualização dos drivers gráficos pode melhorar significativamente o desempenho.
+
+ Visitar [_URL] para verificar se há atualizações do driver?
+ <url name="url">
+ http://www.intel.com/p/pt_BR/support/detect/graphics
+ </url>
+ <usetemplate ignoretext="Meu driver gráfico está desatualizado" name="okcancelignore" notext="Não" yestext="Sim"/>
+ </notification>
+ <notification name="AMDOldDriver">
+ Provavelmente, há um driver mais recente para o seu chip gráfico. A atualização dos drivers gráficos pode melhorar significativamente o desempenho.
+
+ Visitar [_URL] para verificar se há atualizações do driver?
+ <url name="url">
+ http://support.amd.com/us/Pages/AMDSupportHub.aspx
+ </url>
+ <usetemplate ignoretext="Meu driver gráfico está desatualizado" name="okcancelignore" notext="Não" yestext="Sim"/>
+ </notification>
+ <notification name="NVIDIAOldDriver">
+ Provavelmente, há um driver mais recente para o seu chip gráfico. A atualização dos drivers gráficos pode melhorar significativamente o desempenho.
+
+ Visitar [_URL] para verificar se há atualizações do driver?
+ <url name="url">
+ http://www.nvidia.com.br/Download/index.aspx?lang=br
+ </url>
+ <usetemplate ignoretext="Meu driver gráfico está desatualizado" name="okcancelignore" notext="Não" yestext="Sim"/>
+ </notification>
<notification name="UnknownGPU">
A placa de vídeo do seu sistema não é reconhecida pelo [APP_NAME].
Isto acontece quando novos hardwares que ainda não foram testados no [APP_NAME]. Talvez isso não cause problemas, mas pode ser preciso checar as configurações de vídeo.
@@ -585,6 +632,9 @@ Você pode unir um máximo de [MAX] objetos.
Por favor, certifique-se de que nenhum deles está travado e que você é dono de todos eles.
</notification>
+ <notification name="CannotLinkPermanent">
+ Os objetos não podem ser vinculados através de demarcações de região.
+ </notification>
<notification name="CannotLinkDifferentOwners">
Impossibilitado de unir porque nem todos os objetos são do mesmo dono.
@@ -963,6 +1013,41 @@ Oferecer amizade para [NAME]?
<button name="Cancel" text="Cancelar"/>
</form>
</notification>
+ <notification label="Adicionar lista de substituição automática" name="AddAutoReplaceList">
+ Nome para a nova lista:
+ <form name="form">
+ <button name="SetName" text="OK"/>
+ </form>
+ </notification>
+ <notification label="Renomear lista de substituição automática" name="RenameAutoReplaceList">
+ O nome &apos;[DUPNAME]&apos; já está em uso
+ Insira um novo nome exclusivo:
+ <form name="form">
+ <button name="ReplaceList" text="Substituir lista atual"/>
+ <button name="SetName" text="Usar novo nome"/>
+ </form>
+ </notification>
+ <notification name="InvalidAutoReplaceEntry">
+ A palavra-chave deve ser uma palavra única e a substituição não pode estar vazia.
+ </notification>
+ <notification name="InvalidAutoReplaceList">
+ A lista de substituição é inválida.
+ </notification>
+ <notification name="SpellingDictImportRequired">
+ Você deve especificar um arquivo, um nome e um idioma.
+ </notification>
+ <notification name="SpellingDictIsSecondary">
+ O dicionário [DIC_NAME] não aparenta ter um arquivo &quot;aff&quot;; isso significa que ele é um dicionário &quot;secundário&quot;.
+Ele pode ser usado como dicionário adicional mas não como dicionário Principal.
+
+Consulte https://wiki.secondlife.com/wiki/Adding_Spelling_Dictionaries
+ </notification>
+ <notification name="SpellingDictImportFailed">
+ Impossível copiar
+ [FROM_NAME]
+ para
+ [TO_NAME]
+ </notification>
<notification label="Salvar este look" name="SaveOutfitAs">
Veja o meu novo visual:
<form name="form">
@@ -1028,9 +1113,9 @@ em TODOS OS TERRENOS deste sim?
Por favor, insira um valor maior.
</notification>
<notification name="ConfirmItemDeleteHasLinks">
- Pelo menos um dos itens possui links que levam a ele. Ao excluir o item, os links não funcionarão mais. Por isso, recomendamos excluir os links primeiro.
+ Pelo menos um dos itens possui links que levam a ele. Ao excluir o item, os links não funcionarão mais. Por isso, recomendamos excluir os links primeiro.
-Tem certeza de que quer excluir estes items?
+Tem certeza de que quer excluir estes itens?
<usetemplate name="okcancelbuttons" notext="Cancelar" yestext="OK"/>
</notification>
<notification name="ConfirmObjectDeleteLock">
@@ -1046,9 +1131,9 @@ Tem certeza de que deseja apagar estes itens?
<usetemplate name="okcancelbuttons" notext="Não" yestext="Sim"/>
</notification>
<notification name="ConfirmObjectDeleteNoOwn">
- Você não é proprietário de pelo menos um dos itens selecionados.
+ Ao menos um dos itens selecionados não é seu.
-Tem certeza de que deseja apagar estes itens?
+Tem certeza de que quer excluir estes itens?
<usetemplate name="okcancelbuttons" notext="Não" yestext="Sim"/>
</notification>
<notification name="ConfirmObjectDeleteLockNoCopy">
@@ -1058,22 +1143,26 @@ Tem certeza de que deseja apagar estes itens?
<usetemplate name="okcancelbuttons" notext="Não" yestext="Sim"/>
</notification>
<notification name="ConfirmObjectDeleteLockNoOwn">
- Pelo menos um dos objetos está trancado ou não é de sua posse.
+ Ao menos um objeto está bloqueado.
+Ao menos um objeto não é seu.
-Tem certeza de que deseja apagar estes itens?
+Tem certeza de que quer excluir estes itens?
<usetemplate name="okcancelbuttons" notext="Não" yestext="Sim"/>
</notification>
<notification name="ConfirmObjectDeleteNoCopyNoOwn">
- Pelo menos um dos objetos não é copiável ou não é de sua posse.
+ Ao menos um objeto não é copiável.
+Ao menos um objeto não é seu.
-Tem certeza de que deseja apagar estes itens?
+Tem certeza de que quer excluir estes itens?
<usetemplate name="okcancelbuttons" notext="Não" yestext="Sim"/>
</notification>
<notification name="ConfirmObjectDeleteLockNoCopyNoOwn">
- Pelo menos um dos objetos está trancado, não é copiável ou você não o possui.
+ Ao menos um objeto está bloqueado.
+Ao menos um objeto não é copiável.
+Ao menos um objeto não é seu.
-Tem certeza de que deseja apagar estes itens?
- <usetemplate name="okcancelbuttons" notext="Não" yestext="Sim"/>
+Tem certeza de que quer excluir estes itens?
+ <usetemplate name="okcancelbuttons" notext="Cancelar" yestext="Sim"/>
</notification>
<notification name="ConfirmObjectTakeLock">
Pelo menos um dos objetos está trancado.
@@ -1137,7 +1226,7 @@ para &apos;[THIS_GPU]&apos;
Você chegou a uma região próxima.
</notification>
<notification name="AvatarMovedLast">
- Esse destino não está disponível no momento.
+ O destino solicitado não está disponível no momento.
Você chegou a uma região próxima.
</notification>
<notification name="AvatarMovedHome">
@@ -1153,11 +1242,10 @@ Enquando isso, use o [SECOND_LIFE] normalmente. Seu visual será exibido correta
</form>
</notification>
<notification name="FirstRun">
- A instalação do [APP_NAME] está pronta.
+ A instalação do [APP_NAME] está pronta.
-Se você ainda não conhece o [SECOND_LIFE], basta criar uma conta para começar.
-Voltar para [http://join.secondlife.com secondlife.com] para criar sua conta?
- <usetemplate name="okcancelbuttons" notext="Continuar" yestext="Nova conta.."/>
+Se você ainda não conhece o [SECOND_LIFE], basta criar uma conta para começar.
+ <usetemplate name="okcancelbuttons" notext="Continuar" yestext="Criar conta"/>
</notification>
<notification name="LoginPacketNeverReceived">
Estamos detectando um problema de conexão. Pode haver um problema com a sua conexão à internet ou com o [SECOND_LIFE_GRID].
@@ -1392,13 +1480,43 @@ Versão [VERSION] [[RELEASE_NOTES_FULL_URL] sobre esta atualização]
</notification>
<notification name="RequiredUpdateDownloadedVerboseDialog">
O software requer uma atualização que já foi baixada.
-Versão [VERSION]
+Versão [VERSION] Informação [[INFO_URL] sobre essa atualização]
Para instalar a atualização, será preciso reiniciar o [APP_NAME].
<usetemplate name="okbutton" yestext="OK"/>
</notification>
<notification name="RequiredUpdateDownloadedDialog">
Para instalar a atualização, será preciso reiniciar o [APP_NAME].
+Informação [[INFO_URL] sobre essa atualização]
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
+ <notification name="OtherChannelDownloadBackgroundTip">
+ Baixamos uma atualização para a instalação do [APP_NAME].
+Versão [VERSION]
+O visualizador experimental foi substituído por um visualizador [NEW_CHANNEL];
+consulte [[INFO_URL] para obter mais detalhes sobre essa atualização]
+ <usetemplate name="okcancelbuttons" notext="Depois..." yestext="Instalar agora e reiniciar o [APP_NAME]"/>
+ </notification>
+ <notification name="OtherChannelDownloadBackgroundDialog">
+ Baixamos uma atualização para a instalação do [APP_NAME].
+Versão [VERSION]
+O visualizador experimental foi substituído por um visualizador [NEW_CHANNEL];
+consulte a informação [[INFO_URL] sobre essa atualização]
+ <usetemplate name="okcancelbuttons" notext="Depois..." yestext="Instalar agora e reiniciar o [APP_NAME]"/>
+ </notification>
+ <notification name="OtherChannelRequiredUpdateDownloadedVerboseDialog">
+ O software requer uma atualização que já foi baixada.
+Versão [VERSION]
+O visualizador experimental foi substituído por um visualizador [NEW_CHANNEL];
+consulte a informação [[INFO_URL] sobre essa atualização]
+
+Para instalar a atualização, será preciso reiniciar o [APP_NAME].
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
+ <notification name="OtherChannelRequiredUpdateDownloadedDialog">
+ Para instalar a atualização, será preciso reiniciar o [APP_NAME].
+O visualizador experimental foi substituído por um visualizador [NEW_CHANNEL];
+consulte a informação [[INFO_URL] sobre essa atualização]
<usetemplate name="okbutton" yestext="OK"/>
</notification>
<notification name="DeedObjectToGroup">
@@ -1448,6 +1566,10 @@ Para instalar a atualização, será preciso reiniciar o [APP_NAME].
Você é atualmente um membro do grupo
<usetemplate name="okcancelbuttons" notext="Cancelar" yestext="Sair"/>
</notification>
+ <notification name="OwnerCannotLeaveGroup">
+ Não foi possível deixar o grupo. Você não pode deixar o grupo pois é o último proprietário dele. Primeiramente, atribua outro membro à função de proprietário.
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
<notification name="ConfirmKick">
Tem CERTEZA de que deseja expulsar todos os residentes do grid?
<usetemplate name="okcancelbuttons" notext="Cancelar" yestext="Chutar todos"/>
@@ -1475,10 +1597,13 @@ Para instalar a atualização, será preciso reiniciar o [APP_NAME].
Não é possível oferecer amizade neste momento. Por favor, tente novamente em breve.
<usetemplate name="okbutton" yestext="OK"/>
</notification>
- <notification name="BusyModeSet">
- Modo ocupado ativado.
-O bate-papo e MIs não serão exibidos. MIs enviadas para você receberão sua resposta de modo ocupado. Todas as ofertas de teletransporte serão recusadas. Todas as ofertas de inventário serão colocadas na Lixeira.
- <usetemplate ignoretext="Passar meu status para o modo ocupado" name="okignore" yestext="OK"/>
+ <notification name="DoNotDisturbModeSet">
+ Não perturbe está ativado. Você não será notificado de comunicações recebidas.
+
+- Outros residentes receberão a sua resposta de Não perturbe (definida em Preferências &gt; Geral).
+- As ofertas de teletransporte serão recusadas.
+- Chamadas de voz serão recusadas.
+ <usetemplate ignoretext="Altero meu status para o modo Não perturbe" name="okignore" yestext="OK"/>
</notification>
<notification name="JoinedTooManyGroupsMember">
Você atingiu o limite máximo de grupos. Saia de outro grupo para poder entrar nesse ou recuse o convite.
@@ -1673,83 +1798,128 @@ Isto mudará milhares de regiões e fará o spaceserver soluçar.
<usetemplate name="okcancelbuttons" notext="Cancelar" yestext="Mudar"/>
</notification>
<notification name="RegionEntryAccessBlocked">
- Você não é permitido na Região devido à sua Classificação de maturidade. Isto pode ser o resultado da falta de informação de validação de sua idade.
-
-Por favor, verifique se você está com o último Visualizador instalado e vá ao Banco de Conhecimento para detalhes em como acessar áreas com esta classificação de maturidade.
+ A região que você está tentando visitar tem conteúdo que excede suas preferências atuais. Você pode alterar suas preferências acessando Eu &gt; Preferências &gt; Geral.
<usetemplate name="okbutton" yestext="OK"/>
</notification>
- <notification name="RegionEntryAccessBlocked_KB">
- Você não é permitido nesta região devido à sua Classificação de maturidade.
-
-Ir para o Banco de Conhecimento para maiores informações sobre Classificações de maturidade?
+ <notification name="RegionEntryAccessBlocked_AdultsOnlyContent">
+ A região que você está tentando visitar tem conteúdo [REGIONMATURITY], acessível apenas para adultos.
<url name="url">
- http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview/pt
+ http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview
</url>
- <usetemplate ignoretext="Não posso entrar nessa região devido à classificação do conteúdo" name="okcancelignore" notext="Fechar" yestext="Ir para o Banco de Conhecimento"/>
+ <usetemplate ignoretext="Passagem de região: A região que você está tentando visitar tem conteúdo acessível apenas para adultos." name="okcancelignore" notext="Fechar" yestext="Ir para a Base de Conhecimento"/>
</notification>
<notification name="RegionEntryAccessBlocked_Notify">
- Você não é permitido nesta região devido à sua Classificação de maturidade.
+ A região que você está tentando visitar tem conteúdo [REGIONMATURITY], mas suas preferências atuais estão definidas para excluir conteúdo [REGIONMATURITY].
+ </notification>
+ <notification name="RegionEntryAccessBlocked_NotifyAdultsOnly">
+ A região que você está tentando visitar tem conteúdo [REGIONMATURITY], acessível apenas para adultos.
</notification>
<notification name="RegionEntryAccessBlocked_Change">
- Você não pode entrar nessa região devido à sua seleção de maturidade.
-
-Para entrar na região desejada, mude o nível de maturidade. Você então poderá fazer buscas e acessar conteúdo [REGIONMATURITY]. Para desfazer qualquer mudança, vá para Eu &gt; Preferências &gt; Geral.
+ A região que você está tentando visitar tem conteúdo [REGIONMATURITY], mas suas preferências atuais estão definidas para excluir conteúdo [REGIONMATURITY]. Podemos alterar suas preferências ou você pode cancelar. Após a alteração de suas preferências, você pode tentar acessar a região novamente.
+ <form name="form">
+ <button name="OK" text="Mudar preferências"/>
+ <button default="true" name="Cancel" text="Cancelar"/>
+ <ignore name="ignore" text="Passagem de região: A região que você está tentando visitar tem conteúdo excluído por suas preferências."/>
+ </form>
+ </notification>
+ <notification name="RegionEntryAccessBlocked_PreferencesOutOfSync">
+ Estamos tendo dificuldades técnicas com seu teletransporte, pois suas preferências estão dessincronizadas com o servidor.
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
+ <notification name="TeleportEntryAccessBlocked">
+ A região que você está tentando visitar tem conteúdo que excede suas preferências atuais. Você pode alterar suas preferências acessando Eu &gt; Preferências &gt; Geral.
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
+ <notification name="TeleportEntryAccessBlocked_AdultsOnlyContent">
+ A região que você está tentando visitar tem conteúdo [REGIONMATURITY], acessível apenas para adultos.
+ <url name="url">
+ http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview
+ </url>
+ <usetemplate ignoretext="Teletransportar: A região que você está tentando visitar tem conteúdo acessível apenas para adultos." name="okcancelignore" notext="Fechar" yestext="Ir para a Base de Conhecimento"/>
+ </notification>
+ <notification name="TeleportEntryAccessBlocked_Notify">
+ A região que você está tentando visitar tem conteúdo [REGIONMATURITY], mas suas preferências atuais estão definidas para excluir conteúdo [REGIONMATURITY].
+ </notification>
+ <notification name="TeleportEntryAccessBlocked_NotifyAdultsOnly">
+ A região que você está tentando visitar tem conteúdo [REGIONMATURITY], acessível apenas para adultos.
+ </notification>
+ <notification name="TeleportEntryAccessBlocked_ChangeAndReTeleport">
+ A região que você está tentando visitar tem conteúdo [REGIONMATURITY], mas suas preferências atuais estão definidas para excluir conteúdo [REGIONMATURITY]. Podemos alterar suas preferências e continuar o teletransporte, ou você pode cancelar este teletransporte.
+ <form name="form">
+ <button name="OK" text="Alterar e continuar"/>
+ <button name="Cancel" text="Cancelar"/>
+ <ignore name="ignore" text="Teletransportar (reinicializável): A região que você está tentando visitar tem conteúdo excluído por suas preferências."/>
+ </form>
+ </notification>
+ <notification name="TeleportEntryAccessBlocked_Change">
+ A região que você está tentando visitar tem conteúdo [REGIONMATURITY], mas suas preferências atuais estão definidas para excluir conteúdo [REGIONMATURITY]. Podemos alterar suas preferências ou você pode cancelar o teletransporte. Após a alteração de suas preferências, você pode tentar se teletransportar novamente.
<form name="form">
- <button name="OK" text="Mudar preferência"/>
- <button default="true" name="Cancel" text="Fechar"/>
- <ignore name="ignore" text="Minha preferência de maturidade impede que eu vá a uma região"/>
+ <button name="OK" text="Mudar preferências"/>
+ <button name="Cancel" text="Cancelar"/>
+ <ignore name="ignore" text="Teletransportar (não reinicializável): A região que você está tentando visitar tem conteúdo excluído por suas preferências."/>
</form>
</notification>
+ <notification name="TeleportEntryAccessBlocked_PreferencesOutOfSync">
+ Estamos tendo dificuldades técnicas com seu teletransporte, pois suas preferências estão dessincronizadas com o servidor.
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
<notification name="PreferredMaturityChanged">
- Sua opção de nível de maturidade é [RATING].
+ Você não receberá mais notificações de que está prestes a visitar uma região com conteúdo [RATING]. Posteriormente você poderá alterar suas preferências de conteúdo acessando Eu &gt; Preferências &gt; Geral da barra do menu.
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
+ <notification name="MaturityChangeError">
+ Impossível alterar suas preferências para visualizar conteúdo [PREFERRED_MATURITY] no momento. Suas preferências foram redefinidas para visualizar conteúdo [ACTUAL_MATURITY]. Você pode tentar alterar suas preferências novamente acessando Eu &gt; Preferências &gt; Geral na barra do menu.
+ <usetemplate name="okbutton" yestext="OK"/>
</notification>
<notification name="LandClaimAccessBlocked">
- Você não pode reclamar esta terra devido à sua Classificação de maturidade. Isto pode ser o resultado de falta de informação na validação de sua idade.
-
-Por favor, verifique se você tem o último Visualizador instalado e vá para o Banco de Conhecimento para detalhes sobre o acesso de áreas com esta Classificação de maturidade.
+ O terreno que você está tentando reivindicar possui uma classificação de maturidade que excede suas preferências atuais. Você pode alterar suas preferências acessando Eu &gt; Preferências &gt; Geral.
<usetemplate name="okbutton" yestext="OK"/>
</notification>
- <notification name="LandClaimAccessBlocked_KB">
- Você não pode reclamar esta terra devido à sua Classificação de maturidade.
-
-Ir para a o Banco de Conhecimento para maiores informações sobre Classificações de maturidade?
+ <notification name="LandClaimAccessBlocked_AdultsOnlyContent">
+ Apenas adultos podem reivindicar este terreno.
<url name="url">
- http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview/pt
+ http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview
</url>
- <usetemplate ignoretext="Não reivindicar essa região devido à classificação do conteúdo" name="okcancelignore" notext="Fechar" yestext="Ir para o Banco de Conhecimento"/>
+ <usetemplate ignoretext="Apenas adultos podem reivindicar este terreno." name="okcancelignore" notext="Fechar" yestext="Ir para a Base de Conhecimento"/>
</notification>
<notification name="LandClaimAccessBlocked_Notify">
- Você não pode reclamar esta terra devido à sua Classificação de maturidade.
+ O terreno que você está tentando reivindicar tem conteúdo [REGIONMATURITY], mas suas preferências atuais estão definidas para excluir conteúdo [REGIONMATURITY].
+ </notification>
+ <notification name="LandClaimAccessBlocked_NotifyAdultsOnly">
+ O terreno que você está tentando reivindicar tem conteúdo [REGIONMATURITY], que é acessível apenas para adultos.
</notification>
<notification name="LandClaimAccessBlocked_Change">
- Você não pode reivindicar essa região devido à sua preferência de maturidade
-
-Clique em &apos;Mudar preferência&apos; para aumentar o nível de maturidade e entrar nessa região. De agora em diante você pode buscar e acessar conteúdo [REGIONMATURITY] . Para modificar esta configuração, vá à Eu &gt; Preferências &gt; Geral.
- <usetemplate ignoretext="Minha preferência de conteúdo impede que eu reivindique terrenos" name="okcancelignore" notext="Fechar" yestext="Mudar Preferência"/>
+ O terreno que você está tentando reivindicar tem conteúdo [REGIONMATURITY], mas suas preferências atuais estão definidas para excluir conteúdo [REGIONMATURITY]. Podemos alterar suas preferências e, então, você poderá tentar reivindicar a região novamente.
+ <form name="form">
+ <button name="OK" text="Mudar preferências"/>
+ <button name="Cancel" text="Cancelar"/>
+ <ignore name="ignore" text="O terreno que você está tentando reivindicar tem conteúdo excluído por suas preferências."/>
+ </form>
</notification>
<notification name="LandBuyAccessBlocked">
- Você não pode comprar esta terra devido à sua Classificação de maturidade. Isto pode ser o resultado de falta de informação na validação de sua idade.
-
-Por favor, verifique se você tem o último Visualizador instalado e vá para o Banco de Conhecimento para detalhes sobre o acesso de áreas com esta Classificação de maturidade.
+ O terreno que você está tentando comprar possui uma classificação de maturidade que excede suas preferências atuais. Você pode alterar suas preferências acessando Eu &gt; Preferências &gt; Geral.
<usetemplate name="okbutton" yestext="OK"/>
</notification>
- <notification name="LandBuyAccessBlocked_KB">
- Você não pode comprar esta terra devido à sua Classificação de maturidade.
-
-Ir para o Banco de Conhecimento para maiores informações sobre Classificações de Maturidade?
+ <notification name="LandBuyAccessBlocked_AdultsOnlyContent">
+ Apenas adultos podem comprar este terreno.
<url name="url">
- http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview/pt
+ http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview
</url>
- <usetemplate ignoretext="Não posso comprar essa região devido à classificação do conteúdo" name="okcancelignore" notext="Fechar" yestext="Ir para o Banco de Conhecimento"/>
+ <usetemplate ignoretext="Apenas adultos podem comprar este terreno." name="okcancelignore" notext="Fechar" yestext="Ir para a Base de Conhecimento"/>
</notification>
<notification name="LandBuyAccessBlocked_Notify">
- Você não pode comprar esta terra devido à sua Classificação de maturidade.
+ O terreno que você está tentando comprar tem conteúdo [REGIONMATURITY], mas suas preferências atuais estão definidas para excluir conteúdo [REGIONMATURITY].
+ </notification>
+ <notification name="LandBuyAccessBlocked_NotifyAdultsOnly">
+ A região que você está tentando visitar tem conteúdo [REGIONMATURITY], que é acessível apenas para adultos.
</notification>
<notification name="LandBuyAccessBlocked_Change">
- Você não pode comprar esse terreno devido à sua preferência de maturidade
-
-Clique em &apos;Mudar preferência&apos; para aumentar o nível de maturidade e entrar nessa região. De agora em diante você pode buscar e acessar conteúdo [REGIONMATURITY] . Para modificar esta configuração, vá à Eu &gt; Preferências &gt; Geral.
- <usetemplate ignoretext="Minha preferência de conteúdo não me deixa comprar terrenos" name="okcancelignore" notext="Fechar" yestext="Mudar Preferência"/>
+ O terreno que você está tentando comprar tem conteúdo [REGIONMATURITY], mas suas preferências atuais estão definidas para excluir conteúdo [REGIONMATURITY]. Podemos alterar suas preferências e, então, você poderá tentar comprar a região novamente.
+ <form name="form">
+ <button name="OK" text="Mudar preferências"/>
+ <button name="Cancel" text="Cancelar"/>
+ <ignore name="ignore" text="O terreno que você está tentando comprar tem conteúdo excluído por suas preferências."/>
+ </form>
</notification>
<notification name="TooManyPrimsSelected">
Muitos prims foram selecionados. Selecione [MAX_PRIM_COUNT] ou menos prims, e tente de novo
@@ -1804,10 +1974,9 @@ Publicar este classificado agora por L$ [AMOUNT]?
</form>
</notification>
<notification label="Modificar a maturidade da Região" name="RegionMaturityChange">
- O conteúdo desta região foi reclassificado.
-Talvez leve algum tempo para a mudança ser refletida no mapa.
-
-Para ir a regiões de conteúdo Adulto, é preciso ter uma conta verificada, seja comprovando a idade ou com dados de pagamento.
+ A classificação de maturidade desta região foi alterada.
+Talvez leve algum tempo para que esta mudança seja refletida no mapa.
+ <usetemplate name="okbutton" yestext="OK"/>
</notification>
<notification label="Discordância de Versão de Voz" name="VoiceVersionMismatch">
Esta versão do [APP_NAME] não é compatível com o recurso &apos;Bate-papo de voz&apos; desta região. Para o bate-papo de voz funcionar, atualize o [APP_NAME].
@@ -1920,6 +2089,10 @@ Mover para o inventário o(s) item(s)?
Deseja abrir o [http://secondlife.com/account/ Painel] para ver o histórico da sua conta?
<usetemplate ignoretext="Abrir o navegador para acessar minha conta" name="okcancelignore" notext="Cancelar" yestext="Ir para a página"/>
</notification>
+ <notification name="ConfirmAddingChatParticipants">
+ Quando você adiciona uma pessoa a uma conversa existente, uma nova conversa é criada. Todos os participantes recebem notificações sobre a nova conversa.
+ <usetemplate ignoretext="Confirme a inclusão de participantes no bate-papo" name="okcancelignore" notext="Cancelar" yestext="Ok"/>
+ </notification>
<notification name="ConfirmQuit">
Tem certeza que deseja sair?
<usetemplate ignoretext="Confirmar antes de sair" name="okcancelignore" notext="Não sair" yestext="Sair"/>
@@ -1994,14 +2167,14 @@ Você deseja substituí-lo pelo objeto selecionado?
<button ignore="Never Replace" name="No" text="Não"/>
</form>
</notification>
- <notification label="Aviso de Modo Ocupado" name="BusyModePay">
- Você está no modo Ocupado, o que significa que você não receberá quaisquer itens oferecidos em troca deste pagamento.
+ <notification label="Aviso de modo Não perturbe" name="DoNotDisturbModePay">
+ Você ativou o Não perturbe. Você não receberá qualquer item oferecido em troca deste pagamento.
-Você gostaria de deixar o modo Ocupado antes de completar esta transação?
+Deseja desativar o Não perturbe antes de concluir esta transação?
<form name="form">
- <ignore name="ignore" save_option="true" text="Estou prestes a pagar alguém ou um objeto no modo ocupado"/>
- <button ignore="Always leave Busy Mode" name="Yes" text="Sim"/>
- <button ignore="Never leave Busy Mode" name="No" text="Não"/>
+ <ignore name="ignore" text="Estou prestes a pagar alguém ou um objeto no modo Não perturbe"/>
+ <button ignore="Sempre manter no modo Não perturbe" name="Yes" text="OK"/>
+ <button ignore="Nunca sair do modo Não perturbe" name="No" text="Cancelar"/>
</form>
</notification>
<notification name="ConfirmDeleteProtectedCategory">
@@ -2097,14 +2270,11 @@ Inclua um link para facilitar o acesso para visitantes. Teste o link na barra de
<usetemplate ignoretext="Vestir as roupas que eu criar enquanto edito minha aparência" name="okcancelignore" notext="Não" yestext="Sim"/>
</notification>
<notification name="NotAgeVerified">
- Você deve ter no mínimo 18 anos para acessar conteúdo e áreas adultas no Second Life. Visite nossa página de verificação de idade para confirmar que você tem mais de 18 anos.
-Isso abrirá o seu navegador.
-
-[_URL]
- <url name="url" option="0">
- https://secondlife.com/my/account/verification.php
- </url>
- <usetemplate ignoretext="Ainda não comprovei minha idade" name="okcancelignore" notext="Cancelar" yestext="Ir para verificação de idade"/>
+ O local que você está tentando visitar é restrito a residentes com 18 anos ou mais.
+ <usetemplate ignoretext="Não tenho idade suficiente para visitar áreas com restrição de idade." name="okignore" yestext="OK"/>
+ </notification>
+ <notification name="NotAgeVerified_Notify">
+ Localização restrita para 18 anos de idade ou mais.
</notification>
<notification name="Cannot enter parcel: no payment info on file">
Ãrea restrita a residentes que já cadastraram seus dados de pagamento Deseja ir ao site do [SECOND_LIFE] para cuidar disso?
@@ -2139,11 +2309,8 @@ Isso abrirá o seu navegador.
<notification name="GroupNotice">
Assunto: [SUBJECT], Mensagem: [MESSAGE]
</notification>
- <notification name="FriendOnline">
- &lt;nolink&gt;[NAME]&lt;/nolink&gt; está online
- </notification>
- <notification name="FriendOffline">
- &lt;nolink&gt;[NAME]&lt;/nolink&gt; está offline
+ <notification name="FriendOnlineOffline">
+ &lt;nolink&gt;[NAME]&lt;/nolink&gt; está [STATUS]
</notification>
<notification name="AddSelfFriend">
Você é o máximo! Mesmo assim, não dá para adicionar a si mesmo(a) como amigo(a).
@@ -2263,9 +2430,7 @@ Selecione só um objeto.
e selecionar &apos;Teletransportar&apos;.)
</notification>
<notification name="TeleportToPerson">
- Para entrar em contato com residentes como &apos;[NAME]&apos;, clique no botão &quot;Pessoas&quot;, selecione um residente na janela que é exibida e clique em &apos;MI&apos; na
- parte inferior da janela.
- (Também é possível clicar duas vezes no nome, ou clicar no nome com o botão direito e selecionar &apos;MI&apos;.)
+ Para iniciar uma conversa particular com alguém, clique com o botão direito no avatar e selecione &quot;MI&quot; no menu.
</notification>
<notification name="CantSelectLandFromMultipleRegions">
Impossível selecionar terra nas fronteiras do servidor. Tente selecionar um pedaço menor de terra.
@@ -2362,6 +2527,16 @@ Logo, não é possível voar aqui.
<notification name="NoBuild">
Esta área desativou a opção de construir. Não é possível construir ou fazer rez de objetos nesta área.
</notification>
+ <notification name="PathfindingDirty">
+ A região possui alterações de pathfinding pendentes. Se você possui direitos de construção, poderá recarregar a região clicando no botão “Recarregar regiãoâ€.
+ </notification>
+ <notification name="DynamicPathfindingDisabled">
+ O pathfinding dinâmico não está habilitado nesta região. Os objetos com script usando chamadas LSL de pathfinding podem não operar como o esperado na região.
+ </notification>
+ <notification name="PathfindingCannotRebakeNavmesh">
+ Erro. Pode haver um erro de rede ou do servidor, ou você pode não ter direitos de construção. Às vezes, fazer login e logout novamente resolve este problema.
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
<notification name="SeeAvatars">
Este terreno oculta os avatares e bate-papo de outro terreno. Não é possível ver residentes fora do terreno e vice-versa. O bate-papo por texto no canal 0 também está bloqueado.
</notification>
@@ -2380,9 +2555,7 @@ Os únicos scripts que funcionam são os do proprietário do terreno.
Você só pode reivindicar terrenos públicos na região onde você está.
</notification>
<notification name="RegionTPAccessBlocked">
- Você não é permitido na Região devido à sua Classificação de maturidade. Você precisa validar sua idade e/ou instalar o último Visualizador.
-
-Por favor, vá ao Banco de Conhecimento para detalhes sobre o acesso de áreas com esta Classificação de maturidade.
+ A região que você está tentando visitar tem conteúdo que excede suas preferências atuais. Você pode alterar suas preferências acessando Eu &gt; Preferências &gt; Geral.
</notification>
<notification name="URBannedFromRegion">
Você está banido da região.
@@ -2393,8 +2566,11 @@ Por favor, vá ao Banco de Conhecimento para detalhes sobre o acesso de áreas c
<notification name="ImproperPaymentStatus">
Você não tem o status de pagamento adequado para entrar nesta região.
</notification>
+ <notification name="MustGetAgeRegion">
+ Você deve ter 18 anos ou mais para acessar esta região.
+ </notification>
<notification name="MustGetAgeParcel">
- Você precisa ter a idade verificada para entrar neste lote.
+ Você deve ter 18 anos ou mais para acessar este lote.
</notification>
<notification name="NoDestRegion">
Nenhuma região de destino encontrada.
@@ -2496,12 +2672,33 @@ Por favor, tente novamente em alguns instantes.
<notification name="TeleportOffered">
[NAME_SLURL] quer teletransportar você para a região deles:
-[MESSAGE] - [MATURITY_STR] &lt;icon&gt;[MATURITY_ICON]&lt;/icon&gt;
+“[MESSAGE]â€
+&lt;icon&gt;[MATURITY_ICON]&lt;/icon&gt; - [MATURITY_STR]
<form name="form">
<button name="Teleport" text="Teletransporte"/>
<button name="Cancel" text="Cancelar"/>
</form>
</notification>
+ <notification name="TeleportOffered_MaturityExceeded">
+ [NAME_SLURL] quer teletransportar você para a região deles:
+
+“[MESSAGE]â€
+&lt;icon&gt;[MATURITY_ICON]&lt;/icon&gt; - [MATURITY_STR]
+
+A região tem conteúdo [REGION_CONTENT_MATURITY], mas suas preferências atuais estão definidas para excluir conteúdo [REGION_CONTENT_MATURITY]. Podemos alterar suas preferências e continuar o teletransporte, ou você pode cancelar este teletransporte.
+ <form name="form">
+ <button name="Teleport" text="Alterar e continuar"/>
+ <button name="Cancel" text="Cancelar"/>
+ </form>
+ </notification>
+ <notification name="TeleportOffered_MaturityBlocked">
+ [NAME_SLURL] quer teletransportar você para a região deles:
+
+“[MESSAGE]â€
+&lt;icon&gt;[MATURITY_ICON]&lt;/icon&gt; - [MATURITY_STR]
+
+No entanto, esta região tem conteúdo acessível apenas para adultos.
+ </notification>
<notification name="TeleportOfferSent">
Oferta de teletransporte enviada para [TO_NAME]
</notification>
@@ -2596,16 +2793,21 @@ OK?
</form>
</notification>
<notification name="ScriptQuestionCaution">
- Um objeto chamado &apos;&lt;nolink&gt;[OBJECTNAME]&lt;/nolink&gt;&apos;&apos;, de &apos;[NAME]&apos;, gostaria de:
-
-[QUESTIONS]
-Se você não confia nos objetos deste autor, recuse-o.
-
-Deseja aceitar?
+ Aviso: O objeto &apos;&lt;nolink&gt;[OBJECTNAME]&lt;/nolink&gt;&apos; deseja obter acesso total à sua conta de dólares Linden. Se você conceder acesso, ele poderá remover fundos de sua conta a qualquer momento ou esvaziar sua conta completamente, continuamente e sem avisos adicionais.
+
+Não conceda acesso se você não entender completamente por que ele deseja acessar sua conta.
<form name="form">
- <button name="Grant" text="Autorizar"/>
+ <button name="Grant" text="Permitir acesso total"/>
<button name="Deny" text="Negar"/>
- <button name="Details" text="Detalhes..."/>
+ </form>
+ </notification>
+ <notification name="UnknownScriptQuestion">
+ A permissão de script de tempo de execução solicitada por &apos;&lt;nolink&gt;[OBJECTNAME]&lt;/nolink&gt;&apos;, um objeto de &apos;[NAME]&apos;, não é reconhecida pelo visualizador e não pode ser concedida.
+
+Para conceder essa permissão, atualize seu visualizador para a versão mais recente em [DOWNLOADURL].
+ <form name="form">
+ <button name="Deny" text="Ok"/>
+ <button name="Mute" text="Bloquear"/>
</form>
</notification>
<notification name="ScriptDialog">
@@ -2903,6 +3105,10 @@ Você carregou uma textura com [RESOLUTION] para o(a) &apos;[BODYREGION]&apos; e
( [EXISTENCE] segundos de vida )
Você carregou uma textura com [RESOLUTION] para o(a) &apos;[BODYREGION]&apos; em [TIME] segundos.
</notification>
+ <notification name="LivePreviewUnavailable">
+ Não podemos exibir uma visualização desta textura, pois ela é cópia proibida e/ou transferência proibida.
+ <usetemplate ignoretext="Avise-me quando o modo Visualização em Tempo Real estiver indisponível para texturas de cópia proibida e/ou transferência proibida" name="okignore" yestext="OK"/>
+ </notification>
<notification name="ConfirmLeaveCall">
Tem certeza de que quer sair desta ligação?
<usetemplate ignoretext="Confirmar antes de deixar ligação" name="okcancelignore" notext="Não" yestext="Sim"/>
@@ -3072,6 +3278,62 @@ Se o botão Falar for ocultado, o recurso de voz será desabilitado.
Essa ação irá ocultar todos os itens de menu e botões. Para trazê-los de volta, clique em [SHORTCUT] novamente.
<usetemplate ignoretext="Confirmar antes de ocultar interface" name="okcancelignore" notext="Cancelar" yestext="OK"/>
</notification>
+ <notification name="PathfindingLinksets_WarnOnPhantom">
+ Alguns linksets selecionados terão suas sinalizações fantasmas alternadas.
+
+Deseja continuar?
+ <usetemplate ignoretext="Algumas sinalizações fantasmas dos linksets selecionados serão alternadas." name="okcancelignore" notext="Cancelar" yestext="OK"/>
+ </notification>
+ <notification name="PathfindingLinksets_MismatchOnRestricted">
+ Algumas sinalizações fantasmas dos linksets selecionados não podem ser definidas como &apos;[REQUESTED_TYPE]&apos; devido às restrições de permissão no linkset. Ao invés disso, estes linksets serão definidos como &apos;[RESTRICTED_TYPE]&apos;.
+
+Deseja continuar?
+ <usetemplate ignoretext="Alguns linksets selecionados não podem ser definidos devido às restrições de permissão no linkset." name="okcancelignore" notext="Cancelar" yestext="OK"/>
+ </notification>
+ <notification name="PathfindingLinksets_MismatchOnVolume">
+ Alguns linksets selecionados não podem ser definidos como &apos;[REQUESTED_TYPE]&apos;, pois a forma não é convexa.
+
+Deseja continuar?
+ <usetemplate ignoretext="Alguns linksets selecionados não podem ser definidos, pois a forma não é convexa." name="okcancelignore" notext="Cancelar" yestext="OK"/>
+ </notification>
+ <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnRestricted">
+ Alguns linksets selecionados terão suas sinalizações fantasmas alternadas.
+
+Algumas sinalizações fantasmas dos linksets selecionados não podem ser definidas como &apos;[REQUESTED_TYPE]&apos; devido às restrições de permissão no linkset. Ao invés disso, estes linksets serão definidos como &apos;[RESTRICTED_TYPE]&apos;.
+
+Deseja continuar?
+ <usetemplate ignoretext="Algumas sinalizações fantasmas dos linksets selecionados serão alternadas e outras não poderão ser definidas devido às restrições de permissão no linkset." name="okcancelignore" notext="Cancelar" yestext="OK"/>
+ </notification>
+ <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnVolume">
+ Alguns linksets selecionados terão suas sinalizações fantasmas alternadas.
+
+Alguns linksets selecionados não podem ser definidos como &apos;[REQUESTED_TYPE]&apos;, pois a forma não é convexa.
+
+Deseja continuar?
+ <usetemplate ignoretext="Algumas sinalizações fantasmas dos linksets selecionados serão alternadas e outros não podem ser definidas, pois a forma não é convexa." name="okcancelignore" notext="Cancelar" yestext="OK"/>
+ </notification>
+ <notification name="PathfindingLinksets_MismatchOnRestricted_MismatchOnVolume">
+ Algumas sinalizações fantasmas dos linksets selecionados não podem ser definidas como &apos;[REQUESTED_TYPE]&apos; devido às restrições de permissão no linkset. Ao invés disso, estes linksets serão definidos como &apos;[RESTRICTED_TYPE]&apos;.
+
+Alguns linksets selecionados não podem ser definidos como &apos;[REQUESTED_TYPE]&apos;, pois a forma não é convexa. Estes tipos de uso de linksets não mudarão.
+
+Deseja continuar?
+ <usetemplate ignoretext="Alguns linksets selecionados não podem ser definidos devido às restrições de permissão no linkset e porque a forma não é convexa." name="okcancelignore" notext="Cancelar" yestext="OK"/>
+ </notification>
+ <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnRestricted_MismatchOnVolume">
+ Alguns linksets selecionados terão suas sinalizações fantasmas alternadas.
+
+Algumas sinalizações fantasmas dos linksets selecionados não podem ser definidas como &apos;[REQUESTED_TYPE]&apos; devido às restrições de permissão no linkset. Ao invés disso, estes linksets serão definidos como &apos;[RESTRICTED_TYPE]&apos;.
+
+Alguns linksets selecionados não podem ser definidos como &apos;[REQUESTED_TYPE]&apos;, pois a forma não é convexa. Estes tipos de uso de linksets não mudarão.
+
+Deseja continuar?
+ <usetemplate ignoretext="Algumas sinalizações fantasmas dos linksets selecionados serão alternadas e outras não poderão ser definidas, pois a forma não é convexa." name="okcancelignore" notext="Cancelar" yestext="OK"/>
+ </notification>
+ <notification name="PathfindingLinksets_ChangeToFlexiblePath">
+ O objeto selecionado afeta o navmesh. Alterá-lo para um Caminho Flexível irá removê-lo do navmesh.
+ <usetemplate ignoretext="O objeto selecionado afeta o navmesh. Alterá-lo para um Caminho Flexível irá removê-lo do navmesh." name="okcancelignore" notext="Cancelar" yestext="OK"/>
+ </notification>
<global name="UnsupportedGLRequirements">
Aparentemente a sua máquina não atende os requisitos de hardware do [APP_NAME]. [APP_NAME] requer placas de vídeo OpenGL com suporte a multitexturas. Se sua place de vídeo tiver este perfil, atualize o driver da placa de vídeo, assim como patches e service packs do sistema operacional.
@@ -3096,4 +3358,653 @@ Outra opção é procurar por lugares com a tag &apos;Infohub&apos; no mapa.
<global name="You died and have been teleported to your home location">
Você morreu e foi reenviado ao seu início.
</global>
+ <notification name="LocalBitmapsUpdateFileNotFound">
+ Não foi possível atualizar [FNAME], pois o arquivo não pôde ser encontrado.
+Desabilitando atualizações futuras deste arquivo.
+ </notification>
+ <notification name="LocalBitmapsUpdateFailedFinal">
+ [FNAME] não pode ser aberto ou decodificado em [NRETRIES] tentativas, e agora é considerado corrompido.
+Desabilitando atualizações futuras deste arquivo.
+ </notification>
+ <notification name="LocalBitmapsVerifyFail">
+ Tentativa de adição de um formato de imagem inválido ou ilegível [FNAME] que não pode ser aberto ou decodificado.
+Tentativa cancelada.
+ </notification>
+ <notification name="PathfindingReturnMultipleItems">
+ Você está devolvendo [NUM_ITEMS] itens. Tem certeza de que deseja continuar?
+ <usetemplate ignoretext="Tem certeza de que deseja devolver múltiplos itens?" name="okcancelignore" notext="Não" yestext="Sim"/>
+ </notification>
+ <notification name="PathfindingDeleteMultipleItems">
+ Você está excluindo [NUM_ITEMS] itens. Tem certeza de que deseja continuar?
+ <usetemplate ignoretext="Tem certeza de que deseja excluir múltiplos itens?" name="okcancelignore" notext="Não" yestext="Sim"/>
+ </notification>
+ <notification name="AvatarFrozen">
+ [AV_FREEZER] congelou você. Você não pode se mover ou interagir com o mundo.
+ </notification>
+ <notification name="AvatarFrozenDuration">
+ [AV_FREEZER] congelou você por [AV_FREEZE_TIME] segundos. Você não pode se mover ou interagir com o mundo.
+ </notification>
+ <notification name="YouFrozeAvatar">
+ Avatar congelado.
+ </notification>
+ <notification name="AvatarHasUnFrozenYou">
+ [AV_FREEZER] descongelou você.
+ </notification>
+ <notification name="AvatarUnFrozen">
+ Avatar descongelado.
+ </notification>
+ <notification name="AvatarFreezeFailure">
+ O congelamento falhou porque você não tem permissão de administrador para esse lote.
+ </notification>
+ <notification name="AvatarFreezeThaw">
+ Seu congelamento expirou, vá cuidar da sua vida.
+ </notification>
+ <notification name="AvatarCantFreeze">
+ Não é possível congelar esse usuário.
+ </notification>
+ <notification name="NowOwnObject">
+ Agora você é o proprietário do objeto [OBJECT_NAME]
+ </notification>
+ <notification name="CantRezOnLand">
+ Não é possível renderizar objeto em [OBJECT_POS] porque o proprietário do terreno não permite. Use a ferramenta de terrenos para ver a propriedade do terreno.
+ </notification>
+ <notification name="RezFailTooManyRequests">
+ O objeto não pode ser renderizado porque há muitas solicitações.
+ </notification>
+ <notification name="SitFailCantMove">
+ Você não pode sentar porque não pode se mover no momento.
+ </notification>
+ <notification name="SitFailNotAllowedOnLand">
+ Você não pode sentar porque não está autorizado a sentar nesse terreno.
+ </notification>
+ <notification name="SitFailNotSameRegion">
+ Tente chegar mais perto. Não é possível sentar no objeto porque
+ele não está na mesma região que você.
+ </notification>
+ <notification name="NoNewObjectRegionFull">
+ Não foi possível criar um novo objeto. A região está cheia.
+ </notification>
+ <notification name="FailedToPlaceObject">
+ Falha ao posicionar objeto em local específico. Tente novamente.
+ </notification>
+ <notification name="NoOwnNoGardening">
+ Você não pode criar árvores e grama em terrenos que não são sua propriedade.
+ </notification>
+ <notification name="NoCopyPermsNoObject">
+ A cópia falhou porque você não está autorizado a copiar o objeto &apos;[OBJ_NAME]&apos;.
+ </notification>
+ <notification name="NoTransPermsNoObject">
+ A cópia falhou porque o objeto &apos;[OBJ_NAME]&apos; não pode ser transferido para você.
+ </notification>
+ <notification name="AddToNavMeshNoCopy">
+ A cópia falhou porque o objeto &apos;[OBJ_NAME]&apos; contribui para o navmesh.
+ </notification>
+ <notification name="DupeWithNoRootsSelected">
+ Duplicar sem objetos raiz selecionados.
+ </notification>
+ <notification name="CantDupeCuzRegionIsFull">
+ Não é possível duplicar objetos porque a região está cheia.
+ </notification>
+ <notification name="CantDupeCuzParcelNotFound">
+ Não é possível duplicar os objetos - não é possível encontrar o lote em que eles estão.
+ </notification>
+ <notification name="CantCreateCuzParcelFull">
+ Não é possível criar objeto porque
+o lote está cheio.
+ </notification>
+ <notification name="RezAttemptFailed">
+ Falha na tentativa de renderizar um objeto.
+ </notification>
+ <notification name="ToxicInvRezAttemptFailed">
+ Não é possível criar um item que causou problemas a essa região.
+ </notification>
+ <notification name="InvItemIsBlacklisted">
+ Esse item do inventário foi incluído na lista.
+ </notification>
+ <notification name="NoCanRezObjects">
+ No momento, você não está autorizado a criar objetos.
+ </notification>
+ <notification name="LandSearchBlocked">
+ Pesquisa de terreno bloqueada.
+Você realizou muitas pesquisas de terreno muito rápido.
+Tente novamente em instantes.
+ </notification>
+ <notification name="NotEnoughResourcesToAttach">
+ Não há recursos de script disponíveis suficientes para anexar objeto!
+ </notification>
+ <notification name="YouDiedAndGotTPHome">
+ Você morreu e foi teletransportado para seu início
+ </notification>
+ <notification name="EjectComingSoon">
+ Você não tem mais permissão para ficar aqui e tem [EJECT_TIME] segundos para sair.
+ </notification>
+ <notification name="NoEnterServerFull">
+ Você não pode entrar nesta região porque
+o servidor está cheio.
+ </notification>
+ <notification name="SaveBackToInvDisabled">
+ Salvar no inventário foi desativado.
+ </notification>
+ <notification name="NoExistNoSaveToContents">
+ Não é possível salvar &apos;[OBJ_NAME]&apos; no conteúdo do objeto porque o objeto do qual ele foi renderizado não existe mais.
+ </notification>
+ <notification name="NoModNoSaveToContents">
+ Não é possível salvar &apos;[OBJ_NAME]&apos; no conteúdo do objeto porque você não tem permissão para modificar o objeto &apos;[DEST_NAME]&apos;.
+ </notification>
+ <notification name="NoSaveBackToInvDisabled">
+ Não é possível salvar &apos;[OBJ_NAME]&apos; no inventário -- essa operação foi desativada.
+ </notification>
+ <notification name="NoCopyNoSelCopy">
+ Você não pode copiar sua seleção porque não está autorizado a copiar o objeto &apos;[OBJ_NAME]&apos;.
+ </notification>
+ <notification name="NoTransNoSelCopy">
+ Você não pode copiar a seleção porque o objeto &apos;[OBJ_NAME]&apos; não é transferível.
+ </notification>
+ <notification name="NoTransNoCopy">
+ Você não pode copiar a seleção porque o objeto &apos;[OBJ_NAME]&apos; não é transferível.
+ </notification>
+ <notification name="NoPermsNoRemoval">
+ A remoção do objeto &apos;[OBJ_NAME]&apos; do simulador é proibida pelo sistema de permissões.
+ </notification>
+ <notification name="NoModNoSaveSelection">
+ Você não pode salvar sua seleção porque não está autorizado a modificar o objeto &apos;[OBJ_NAME]&apos;.
+ </notification>
+ <notification name="NoCopyNoSaveSelection">
+ Não é possível salvar sua seleção porque o objeto &apos;[OBJ_NAME]&apos; não é copiável.
+ </notification>
+ <notification name="NoModNoTaking">
+ Você não pode levar sua seleção porque não está autorizado a modificar o objeto &apos;[OBJ_NAME]&apos;.
+ </notification>
+ <notification name="RezDestInternalError">
+ Erro interno: tipo de destino desconhecido.
+ </notification>
+ <notification name="DeleteFailObjNotFound">
+ A exclusão falhou porque o objeto não foi encontrado
+ </notification>
+ <notification name="SorryCantEjectUser">
+ Não é possível expulsar esse usuário.
+ </notification>
+ <notification name="RegionSezNotAHome">
+ Esta região não permite que você a defina como seu início.
+ </notification>
+ <notification name="HomeLocationLimits">
+ Você só pode definir seu &quot;Início&quot; em seu terreno ou em um Infohub do continente.
+ </notification>
+ <notification name="HomePositionSet">
+ Posição de início definida.
+ </notification>
+ <notification name="AvatarEjected">
+ Avatar expulso.
+ </notification>
+ <notification name="AvatarEjectFailed">
+ A expulsão falhou porque você não tem permissão de administrador para esse lote.
+ </notification>
+ <notification name="CantMoveObjectParcelFull">
+ Não é possível mover &apos;[OBJECT_NAME]&apos; para
+[OBJ_POSITION] na região [REGION_NAME] porque o lote está cheio.
+ </notification>
+ <notification name="CantMoveObjectParcelPerms">
+ Não é possível mover &apos;[OBJECT_NAME]&apos; para
+[OBJ_POSITION] na região [REGION_NAME] porque seus objetos não são permitidos neste lote.
+ </notification>
+ <notification name="CantMoveObjectParcelResources">
+ Não é possível mover &apos;[OBJECT_NAME]&apos; para
+[OBJ_POSITION] na região [REGION_NAME] porque não há recursos suficientes para este objeto neste lote.
+ </notification>
+ <notification name="CantMoveObjectRegionVersion">
+ Não é possível mover &apos;[OBJECT_NAME]&apos; para
+[OBJ_POSITION] na região [REGION_NAME] porque outra região está executando uma versão mais antiga, que não dá suporte o recebimento deste objeto por meio de passagem de regiões.
+ </notification>
+ <notification name="CantMoveObjectNavMesh">
+ Não é possível mover &apos;[OBJECT_NAME]&apos; para
+[OBJ_POSITION] na região [REGION_NAME] porque você não está autorizado a modificar o navmesh além dos limites da região.
+ </notification>
+ <notification name="CantMoveObjectWTF">
+ Não é possível mover &apos;[OBJECT_NAME]&apos; para
+[OBJ_POSITION] na região [REGION_NAME] por uma razão desconhecida. ([FAILURE_TYPE])
+ </notification>
+ <notification name="NoPermModifyObject">
+ Você não está autorizado a modificar este objeto
+ </notification>
+ <notification name="CantEnablePhysObjContributesToNav">
+ Não é possível ativar propriedades físicas para um objeto que contribui para o navmesh.
+ </notification>
+ <notification name="CantEnablePhysKeyframedObj">
+ Não é possível ativar propriedades físicas para objetos keyframe.
+ </notification>
+ <notification name="CantEnablePhysNotEnoughLandResources">
+ Não é possível ativar propriedades físicas para o objeto -- recursos de terreno insuficientes.
+ </notification>
+ <notification name="CantEnablePhysCostTooGreat">
+ Não é possível ativar propriedades físicas para objeto com custo de recursos físicos acima de [MAX_OBJECTS]
+ </notification>
+ <notification name="PhantomWithConcavePiece">
+ Este objeto não pode ter uma peça côncava porque é phantom e contribui para o navmesh.
+ </notification>
+ <notification name="UnableAddItem">
+ Não é possível adicionar item!
+ </notification>
+ <notification name="UnableEditItem">
+ Não é possível editar isso!
+ </notification>
+ <notification name="NoPermToEdit">
+ Não é permitido editar isso.
+ </notification>
+ <notification name="NoPermToCopyInventory">
+ Não é permitido copiar esse inventário.
+ </notification>
+ <notification name="CantSaveItemDoesntExist">
+ Não é possível salvar no conteúdo do objeto: O item não existe mais.
+ </notification>
+ <notification name="CantSaveItemAlreadyExists">
+ Não é possível salvar no conteúdo do objeto: já existe um item com esse nome no inventário
+ </notification>
+ <notification name="CantSaveModifyAttachment">
+ Não é possível salvar no conteúdo do objeto: isso modificaria as permissões de anexo.
+ </notification>
+ <notification name="TooManyScripts">
+ Muitos scripts.
+ </notification>
+ <notification name="UnableAddScript">
+ Não é possível adicionar script!
+ </notification>
+ <notification name="AssetServerTimeoutObjReturn">
+ Servidor de objetos não respondeu a tempo. Objeto retornado a sim.
+ </notification>
+ <notification name="RegionDisablePhysicsShapes">
+ Esta região não tem formas físicas ativadas.
+ </notification>
+ <notification name="NoModNavmeshAcrossRegions">
+ Você não pode modificar o navmesh além dos limites da região.
+ </notification>
+ <notification name="NoSetPhysicsPropertiesOnObjectType">
+ Não é possível definir as propriedades físicas neste tipo de objeto.
+ </notification>
+ <notification name="NoSetRootPrimWithNoShape">
+ Não é possível definir que um prim raiz não tenha forma.
+ </notification>
+ <notification name="NoRegionSupportPhysMats">
+ Esta região não tem materiais físicos ativados.
+ </notification>
+ <notification name="OnlyRootPrimPhysMats">
+ Apenas prims raiz podem ter seus materiais físicos ajustados.
+ </notification>
+ <notification name="NoSupportCharacterPhysMats">
+ Ainda não há suporte para a configuração dos materiais físicos em personagens.
+ </notification>
+ <notification name="InvalidPhysMatProperty">
+ Uma ou mais das propriedades do material físico são inválidas.
+ </notification>
+ <notification name="NoPermsAlterStitchingMeshObj">
+ Você não pode alterar o tipo de acabamento de um objeto mesh.
+ </notification>
+ <notification name="NoPermsAlterShapeMeshObj">
+ Você não pode alterar a forma de um objeto mesh
+ </notification>
+ <notification name="FullRegionCantEnter">
+ Você não pode entrar nesta região porque \nela está cheia.
+ </notification>
+ <notification name="LinkFailedOwnersDiffer">
+ Falha na vinculação -- proprietários diferentes
+ </notification>
+ <notification name="LinkFailedNoModNavmeshAcrossRegions">
+ Falha na vinculação -- não é possível modificar o navmesh além dos limites da região.
+ </notification>
+ <notification name="LinkFailedNoPermToEdit">
+ Ocorreu uma falha na vinculação porque você não tem permissão de edição.
+ </notification>
+ <notification name="LinkFailedTooManyPrims">
+ Falha na vinculação -- muitos prims
+ </notification>
+ <notification name="LinkFailedCantLinkNoCopyNoTrans">
+ Falha na vinculação -- não é possível vincular itens com cópia proibida a itens com transferência proibida
+ </notification>
+ <notification name="LinkFailedNothingLinkable">
+ Falha na vinculação -- nada é vinculável.
+ </notification>
+ <notification name="LinkFailedTooManyPathfindingChars">
+ Falha na vinculação -- muitos personagens com pathfinding
+ </notification>
+ <notification name="LinkFailedInsufficientLand">
+ Falha na vinculação -- recursos de terreno insuficientes
+ </notification>
+ <notification name="LinkFailedTooMuchPhysics">
+ O objeto usa muitos recursos físicos – sua dinâmica foi desativada.
+ </notification>
+ <notification name="TeleportedHomeByObjectOnParcel">
+ Você foi teletransportado para seu início pelo objeto &apos;[OBJECT_NAME]&apos; no lote &apos;[PARCEL_NAME]&apos;
+ </notification>
+ <notification name="TeleportedHomeByObject">
+ Você foi teletransportado para seu início pelo objeto &apos;[OBJECT_NAME]&apos;
+ </notification>
+ <notification name="TeleportedByAttachment">
+ Você foi teletransportado por um anexo em [ITEM_ID]
+ </notification>
+ <notification name="TeleportedByObjectOnParcel">
+ Você foi teletransportado pelo objeto &apos;[OBJECT_NAME]&apos; no lote &apos;[PARCEL_NAME]&apos;
+ </notification>
+ <notification name="TeleportedByObjectOwnedBy">
+ Você foi teletransportado pelo objeto &apos;[OBJECT_NAME]&apos; de propriedade de [OWNER_ID]
+ </notification>
+ <notification name="TeleportedByObjectUnknownUser">
+ Você foi teletransportado pelo objeto &apos;[OBJECT_NAME]&apos; de propriedade de um usuário desconhecido.
+ </notification>
+ <notification name="CantCreateObjectRegionFull">
+ Não foi possível criar o objeto solicitado. A região está cheia.
+ </notification>
+ <notification name="CantAttackMultipleObjOneSpot">
+ Não é possível anexar vários objetos a um local.
+ </notification>
+ <notification name="CantCreateMultipleObjAtLoc">
+ Você não pode criar vários objetos aqui.
+ </notification>
+ <notification name="UnableToCreateObjTimeOut">
+ Não foi possível criar o objeto solicitado. Objeto ausente do banco de dados.
+ </notification>
+ <notification name="UnableToCreateObjUnknown">
+ Não foi possível criar o objeto solicitado. A solicitação expirou. Tente novamente.
+ </notification>
+ <notification name="UnableToCreateObjMissingFromDB">
+ Não foi possível criar o objeto solicitado. Tente novamente.
+ </notification>
+ <notification name="RezFailureTookTooLong">
+ Falha na renderização, objeto solicitado demorou muito a carregar.
+ </notification>
+ <notification name="FailedToPlaceObjAtLoc">
+ Falha ao posicionar objeto em local específico. Tente novamente.
+ </notification>
+ <notification name="CantCreatePlantsOnLand">
+ Você não pode criar plantas neste terreno.
+ </notification>
+ <notification name="CantRestoreObjectNoWorldPos">
+ Não é possível restaurar o objeto. Nenhuma posição encontrada no mundo.
+ </notification>
+ <notification name="CantRezObjectInvalidMeshData">
+ Não é possível renderizar o objeto porque os dados de mesh são inválidos.
+ </notification>
+ <notification name="CantRezObjectTooManyScripts">
+ Não foi possível renderizar objeto porque já há muitos scripts nesta região.
+ </notification>
+ <notification name="CantCreateObjectNoAccess">
+ Seus privilégios de acesso não permitem que você crie objetos aqui.
+ </notification>
+ <notification name="CantCreateObject">
+ No momento, você não está autorizado a criar objetos.
+ </notification>
+ <notification name="InvalidObjectParams">
+ Parâmetros de objeto inválidos
+ </notification>
+ <notification name="CantDuplicateObjectNoAcess">
+ Seus privilégios de acesso não permitem que você duplique objetos aqui.
+ </notification>
+ <notification name="CantChangeShape">
+ Você não está autorizado a alterar essa forma.
+ </notification>
+ <notification name="NoAccessToClaimObjects">
+ Seus privilégios de acesso não permitem que você reivindique objetos aqui.
+ </notification>
+ <notification name="DeedFailedNoPermToDeedForGroup">
+ A doação falhou porque você não está autorizado a doar objetos ao seu grupo.
+ </notification>
+ <notification name="NoPrivsToBuyObject">
+ Seus privilégios de acesso não permitem que você compre objetos aqui.
+ </notification>
+ <notification name="CantAttachObjectAvatarSittingOnIt">
+ Não é possível anexar objeto porque um avatar está sentado nele.
+ </notification>
+ <notification name="WhyAreYouTryingToWearShrubbery">
+ Ãrvores e grama não podem ser usadas como anexos.
+ </notification>
+ <notification name="CantAttachGroupOwnedObjs">
+ Não é possível anexar objetos de propriedade de um grupo.
+ </notification>
+ <notification name="CantAttachObjectsNotOwned">
+ Não é possível anexar objetos que não sua propriedade.
+ </notification>
+ <notification name="CantAttachNavmeshObjects">
+ Não é possível anexar objetos que contribuem com o navmesh.
+ </notification>
+ <notification name="CantAttachObjectNoMovePermissions">
+ Não é possível vincular objeto porque você não tem permissão para movê-lo.
+ </notification>
+ <notification name="CantAttachNotEnoughScriptResources">
+ Não há recursos de script disponíveis suficientes para anexar objeto!
+ </notification>
+ <notification name="CantDropItemTrialUser">
+ Não é possível largar objetos aqui. Tente a área de Avaliação grátis.
+ </notification>
+ <notification name="CantDropMeshAttachment">
+ Você não pode largar anexos mesh. Separe para o inventário e depois renderize no mundo.
+ </notification>
+ <notification name="CantDropAttachmentNoPermission">
+ Falha ao largar anexo: você não está autorizado a largá-lo aqui.
+ </notification>
+ <notification name="CantDropAttachmentInsufficientLandResources">
+ Falha ao largar anexo: recursos de terreno disponíveis insuficientes.
+ </notification>
+ <notification name="CantDropAttachmentInsufficientResources">
+ Falha ao largar anexos: recursos disponíveis insuficientes.
+ </notification>
+ <notification name="CantDropObjectFullParcel">
+ Não é possível largar objeto aqui. O lote está cheio.
+ </notification>
+ <notification name="CantTouchObjectBannedFromParcel">
+ Não é possível tocar/pegar este objeto porque você foi banido do lote de terreno.
+ </notification>
+ <notification name="PlzNarrowDeleteParams">
+ Detalhe seus parâmetros de exclusão.
+ </notification>
+ <notification name="UnableToUploadAsset">
+ Não é possível carregar objeto.
+ </notification>
+ <notification name="CantTeleportCouldNotFindUser">
+ Não foi possível encontrar usuário para teletransportar para início
+ </notification>
+ <notification name="GodlikeRequestFailed">
+ solicitação de poderes de deus falhou
+ </notification>
+ <notification name="GenericRequestFailed">
+ falha em solicitação genérica
+ </notification>
+ <notification name="CantUploadPostcard">
+ Não foi possível carregar cartão postal. Tente novamente mais tarde.
+ </notification>
+ <notification name="CantFetchInventoryForGroupNotice">
+ Não foi possível obter detalhes de inventário para o anúncio de grupo.
+ </notification>
+ <notification name="CantSendGroupNoticeNotPermitted">
+ Não é possível enviar anúncio de grupo -- não permitido.
+ </notification>
+ <notification name="CantSendGroupNoticeCantConstructInventory">
+ Não é possível enviar anúncio de grupo -- não foi possível construir inventário.
+ </notification>
+ <notification name="CantParceInventoryInNotice">
+ Não é possível processar o inventário do anúncio.
+ </notification>
+ <notification name="TerrainUploadFailed">
+ Falha no envio de terreno.
+ </notification>
+ <notification name="TerrainFileWritten">
+ Arquivo de terreno gravado.
+ </notification>
+ <notification name="TerrainFileWrittenStartingDownload">
+ Arquivo de terreno criado, iniciando o download...
+ </notification>
+ <notification name="TerrainBaked">
+ Terreno confeccionado.
+ </notification>
+ <notification name="TenObjectsDisabledPlzRefresh">
+ Apenas os 10 primeiros objetos selecionados foram desativados. Atualize e faça novas seleções, se necessário.
+ </notification>
+ <notification name="UpdateViewerBuyParcel">
+ Você precisa atualizar seu visualizador para comprar este lote.
+ </notification>
+ <notification name="CantBuyParcelNotForSale">
+ Não é possível comprar, este lote não está à venda.
+ </notification>
+ <notification name="CantBuySalePriceOrLandAreaChanged">
+ Não é possível comprar, o preço de venda ou a área do terreno foram alterados.
+ </notification>
+ <notification name="CantBuyParcelNotAuthorized">
+ Você não é o comprador autorizado deste lote.
+ </notification>
+ <notification name="CantBuyParcelAwaitingPurchaseAuth">
+ Você não pode comprar este lote porque já está aguardando aut. de compra
+ </notification>
+ <notification name="CantBuildOverflowParcel">
+ Não é possível criar objeto aqui porque isso sobrecarregaria o lote.
+ </notification>
+ <notification name="SelectedMultipleOwnedLand">
+ Você selecionou terreno com proprietários diferentes. Selecione uma área menor e tente novamente.
+ </notification>
+ <notification name="CantJoinTooFewLeasedParcels">
+ Não há lotes alugados suficientes na seleção para reunir.
+ </notification>
+ <notification name="CantDivideLandMultipleParcelsSelected">
+ Não é possível dividir o terreno.\nHá mais de um lote selecionado.\nTente selecionar um pedaço menor de terreno.
+ </notification>
+ <notification name="CantDivideLandCantFindParcel">
+ Não é possível dividir o terreno.\nNão é possível encontrar o lote.\nComunique isso em Ajuda -&gt; Relatar bug...
+ </notification>
+ <notification name="CantDivideLandWholeParcelSelected">
+ Não é possível dividir o terreno. O lote inteiro está selecionado.\nTente selecionar um pedaço menor do terreno.
+ </notification>
+ <notification name="LandHasBeenDivided">
+ O terreno foi dividido.
+ </notification>
+ <notification name="PassPurchased">
+ Você comprou um passe.
+ </notification>
+ <notification name="RegionDisallowsClassifieds">
+ A região não permite classificados.
+ </notification>
+ <notification name="LandPassExpireSoon">
+ Seu passe para este terreno está prestes a expirar.
+ </notification>
+ <notification name="CantSitNoSuitableSurface">
+ Não há uma superfície adequada para sentar, tente outro local.
+ </notification>
+ <notification name="CantSitNoRoom">
+ Não há espaço para sentar aqui, tente outro local.
+ </notification>
+ <notification name="ClaimObjectFailedNoPermission">
+ A reivindicação do objeto falhou porque você não tem permissão
+ </notification>
+ <notification name="ClaimObjectFailedNoMoney">
+ A reivindicação do objeto falhou porque você não tem L$ suficiente.
+ </notification>
+ <notification name="CantDeedGroupLand">
+ Não é possível doar terrenos de propriedade de um grupo.
+ </notification>
+ <notification name="BuyObjectFailedNoMoney">
+ A compra do objeto falhou porque você não tem L$ suficientes.
+ </notification>
+ <notification name="BuyInventoryFailedNoMoney">
+ A compra do inventário falhou porque você não tem L$ suficiente
+ </notification>
+ <notification name="BuyPassFailedNoMoney">
+ Você não tem L $ suficientes para comprar um passe para este terreno.
+ </notification>
+ <notification name="CantBuyPassTryAgain">
+ Não é possível comprar passe no momento. Tente novamente mais tarde.
+ </notification>
+ <notification name="CantCreateObjectParcelFull">
+ Não é possível criar objeto porque \no lote está cheio.
+ </notification>
+ <notification name="FailedPlacingObject">
+ Falha ao posicionar objeto em local específico. Tente novamente.
+ </notification>
+ <notification name="CantCreateLandmarkForEvent">
+ Não é possível criar marco para o evento.
+ </notification>
+ <notification name="GodBeatsFreeze">
+ Seus poderes de deus rompem o congelamento!
+ </notification>
+ <notification name="SpecialPowersRequestFailedLogged">
+ Falha na solicitação de poderes especiais. Essa solicitação foi registrada.
+ </notification>
+ <notification name="ExpireExplanation">
+ O sistema não pode processar sua solicitação no momento. A solicitação expirou.
+ </notification>
+ <notification name="DieExplanation">
+ O sistema não pode processar sua solicitação.
+ </notification>
+ <notification name="AddPrimitiveFailure">
+ Fundos insuficientes para criar prim.
+ </notification>
+ <notification name="RezObjectFailure">
+ Fundos insuficientes para criar objeto.
+ </notification>
+ <notification name="ResetHomePositionNotLegal">
+ Redefinir Início pois o Início não era legal.
+ </notification>
+ <notification name="CantInviteRegionFull">
+ No momento, você não pode convidar ninguém para seu local pois a região está cheia. Tente novamente mais tarde.
+ </notification>
+ <notification name="CantSetHomeAtRegion">
+ Esta região não permite que você a defina como seu início.
+ </notification>
+ <notification name="ListValidHomeLocations">
+ Você só pode definir seu &quot;Início&quot; em seu terreno ou em um Infohub do continente.
+ </notification>
+ <notification name="SetHomePosition">
+ Posição de início definida.
+ </notification>
+ <notification name="CantDerezInventoryError">
+ Não é possível desrenderizar objeto devido a uma falha de inventário.
+ </notification>
+ <notification name="CantCreateRequestedInv">
+ Não é possível criar o inventário solicitado.
+ </notification>
+ <notification name="CantCreateRequestedInvFolder">
+ Não é possível criar a pasta de inventário solicitada.
+ </notification>
+ <notification name="CantCreateInventory">
+ Não é possível criar esse inventário.
+ </notification>
+ <notification name="CantCreateLandmark">
+ Não é possível criar marco.
+ </notification>
+ <notification name="CantCreateOutfit">
+ Não é possível criar roupa agora. Tente novamente em instantes.
+ </notification>
+ <notification name="InventoryNotForSale">
+ O inventário não está à venda.
+ </notification>
+ <notification name="CantFindInvItem">
+ Não é possível encontrar item do inventário.
+ </notification>
+ <notification name="CantFindObject">
+ Não foi possível encontrar objeto.
+ </notification>
+ <notification name="CantTransfterMoneyRegionDisabled">
+ Transferências de dinheiro para objetos estão desativadas para esta região no momento.
+ </notification>
+ <notification name="CantPayNoAgent">
+ Não foi possível descobrir a quem pagar.
+ </notification>
+ <notification name="CantDonateToPublicObjects">
+ Não é possível dar L$ a objetos públicos.
+ </notification>
+ <notification name="InventoryCreationInWorldObjectFailed">
+ Falha na criação de inventário de objetos do mundo virtual.
+ </notification>
+ <notification name="UserBalanceOrLandUsageError">
+ Um erro interno impediu que seu visualizador fosse atualizado corretamente. O saldo em L$ ou a propriedade de lotes exibidos em seu visualizador pode não refletir o saldo real nos servidores.
+ </notification>
+ <notification name="LargePrimAgentIntersect">
+ Não é possível criar grandes prims que interceptam outros jogadores. Tente novamente quando os outros jogadores tiverem se movido.
+ </notification>
+ <notification name="PreferenceChatClearLog">
+ Isso excluirá os registros das conversas anteriores e qualquer backup desse arquivo.
+ <usetemplate ignoretext="Confirmar antes de excluir o registro com conversas anteriores." name="okcancelignore" notext="Cancelar" yestext="OK"/>
+ </notification>
+ <notification name="PreferenceChatDeleteTranscripts">
+ Isso excluirá todas as transcrições de todas as conversas anteriores. A lista de conversas antigas não será afetada. Todos os arquivos com as extensões .txt e txt.backup na pasta [FOLDER] serão excluídos.
+ <usetemplate ignoretext="Confirmar antes de excluir transcrições." name="okcancelignore" notext="Cancelar" yestext="OK"/>
+ </notification>
+ <notification name="PreferenceChatPathChanged">
+ Não foi possível mover arquivos. Caminho anterior restaurado.
+ <usetemplate ignoretext="Não foi possível mover arquivos. Caminho anterior restaurado." name="okignore" yestext="OK"/>
+ </notification>
</notifications>
diff --git a/indra/newview/skins/default/xui/pt/outfit_accordion_tab.xml b/indra/newview/skins/default/xui/pt/outfit_accordion_tab.xml
index b1ffa0d2e5..b1ffa0d2e5 100644..100755
--- a/indra/newview/skins/default/xui/pt/outfit_accordion_tab.xml
+++ b/indra/newview/skins/default/xui/pt/outfit_accordion_tab.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_active_object_row.xml b/indra/newview/skins/default/xui/pt/panel_active_object_row.xml
index 73f6b2225f..73f6b2225f 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_active_object_row.xml
+++ b/indra/newview/skins/default/xui/pt/panel_active_object_row.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_adhoc_control_panel.xml b/indra/newview/skins/default/xui/pt/panel_adhoc_control_panel.xml
index bd50d4953d..bd50d4953d 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_adhoc_control_panel.xml
+++ b/indra/newview/skins/default/xui/pt/panel_adhoc_control_panel.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_avatar_list_item.xml b/indra/newview/skins/default/xui/pt/panel_avatar_list_item.xml
index b444593af8..22eb23ebc5 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_avatar_list_item.xml
+++ b/indra/newview/skins/default/xui/pt/panel_avatar_list_item.xml
@@ -26,5 +26,6 @@
<icon name="permission_edit_mine_icon" tool_tip="Este amigo pode editar, excluir ou pegar seus pertences"/>
<icon name="permission_map_icon" tool_tip="Este amigo pode localizar você no mapa"/>
<icon name="permission_online_icon" tool_tip="Este amigo pode saber quando você estiver online"/>
+ <button name="info_btn" tool_tip="Mais informações"/>
<button name="profile_btn" tool_tip="Ver perfil"/>
</panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_block_list_sidetray.xml b/indra/newview/skins/default/xui/pt/panel_block_list_sidetray.xml
index c5f93d719a..2fcf6b9932 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_block_list_sidetray.xml
+++ b/indra/newview/skins/default/xui/pt/panel_block_list_sidetray.xml
@@ -1,10 +1,11 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel name="block_list_panel">
- <text name="title_text">
- Lista de bloqueados
- </text>
- <scroll_list name="blocked" tool_tip="Lista atual dos residentes bloqueados"/>
- <button label="Bloquear residente..." label_selected="Bloquear residente..." name="Block resident..." tool_tip="Selecione o residente a bloquear"/>
- <button label="Bloquear objeto por nome..." label_selected="Bloquear objeto por nome..." name="Block object by name..."/>
- <button label="Desbloquear" label_selected="Desbloquear" name="Unblock" tool_tip="Remover residente ou objeto da lista dos bloqueados"/>
+ <panel label="bottom_panel" name="blocked_buttons_panel">
+ <filter_editor label="Filtrar" name="blocked_filter_input"/>
+ <menu_button name="blocked_gear_btn" tool_tip="Ações em uma pessoa ou um objeto selecionado"/>
+ <menu_button name="view_btn" tool_tip="Opções de ordenação"/>
+ <menu_button name="plus_btn" tool_tip="Escolher um residente ou um objeto a ser bloqueado"/>
+ <button name="unblock_btn" tool_tip="Remover residente ou objeto da lista dos bloqueados"/>
+ </panel>
+ <block_list name="blocked" tool_tip="Lista atual dos residentes bloqueados"/>
</panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_body_parts_list_item.xml b/indra/newview/skins/default/xui/pt/panel_body_parts_list_item.xml
index 87a2e1674d..87a2e1674d 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_body_parts_list_item.xml
+++ b/indra/newview/skins/default/xui/pt/panel_body_parts_list_item.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_bodyparts_list_button_bar.xml b/indra/newview/skins/default/xui/pt/panel_bodyparts_list_button_bar.xml
index 094a03553b..094a03553b 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_bodyparts_list_button_bar.xml
+++ b/indra/newview/skins/default/xui/pt/panel_bodyparts_list_button_bar.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_bottomtray.xml b/indra/newview/skins/default/xui/pt/panel_bottomtray.xml
deleted file mode 100644
index cb517f643c..0000000000
--- a/indra/newview/skins/default/xui/pt/panel_bottomtray.xml
+++ /dev/null
@@ -1,47 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel name="bottom_tray">
- <string name="DragIndicationImageName" value="Accordion_ArrowOpened_Off"/>
- <string name="SpeakBtnToolTip" value="Liga e desliga o microfone"/>
- <string name="VoiceControlBtnToolTip" value="Mostra/oculta os controles de voz"/>
- <layout_stack name="toolbar_stack">
- <layout_panel name="speak_panel">
- <talk_button name="talk">
- <speak_button label="Falar" label_selected="Falar" name="speak_btn"/>
- </talk_button>
- </layout_panel>
- <layout_panel name="gesture_panel">
- <gesture_combo_list label="Gesto" name="Gesture" tool_tip="Mostra/oculta os gestos"/>
- </layout_panel>
- <layout_panel name="movement_panel">
- <bottomtray_button label="Movimentar" name="movement_btn" tool_tip="Mostra/oculta os controles de movimento"/>
- </layout_panel>
- <layout_panel name="cam_panel">
- <bottomtray_button label="Exibir" name="camera_btn" tool_tip="Mostra/oculta os controles da câmera"/>
- </layout_panel>
- <layout_panel name="snapshot_panel">
- <bottomtray_button label="" name="snapshots" tool_tip="Tirar foto"/>
- </layout_panel>
- <layout_panel name="build_btn_panel">
- <bottomtray_button label="Construir" name="build_btn" tool_tip="Mostra/oculta ferramentas de Construção"/>
- </layout_panel>
- <layout_panel name="search_btn_panel">
- <bottomtray_button label="Busca" name="search_btn" tool_tip="Mostra/oculta os gestos"/>
- </layout_panel>
- <layout_panel name="world_map_btn_panel">
- <bottomtray_button label="Mapa" name="world_map_btn" tool_tip="Mostra/oculta o Mapa Múndi"/>
- </layout_panel>
- <layout_panel name="mini_map_btn_panel">
- <bottomtray_button label="Mini Mapa" name="mini_map_btn" tool_tip="Mostra/oculta o Mini Mapa"/>
- </layout_panel>
- <layout_panel name="im_well_panel">
- <chiclet_im_well name="im_well">
- <button name="Unread IM messages" tool_tip="Conversas"/>
- </chiclet_im_well>
- </layout_panel>
- <layout_panel name="notification_well_panel">
- <chiclet_notification name="notification_well">
- <button name="Unread" tool_tip="Notificações"/>
- </chiclet_notification>
- </layout_panel>
- </layout_stack>
-</panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_bottomtray_lite.xml b/indra/newview/skins/default/xui/pt/panel_bottomtray_lite.xml
index 78d9826099..78d9826099 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_bottomtray_lite.xml
+++ b/indra/newview/skins/default/xui/pt/panel_bottomtray_lite.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_chiclet_bar.xml b/indra/newview/skins/default/xui/pt/panel_chiclet_bar.xml
index 0551d9cba6..0551d9cba6 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_chiclet_bar.xml
+++ b/indra/newview/skins/default/xui/pt/panel_chiclet_bar.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_classified_info.xml b/indra/newview/skins/default/xui/pt/panel_classified_info.xml
index 73bfe7444e..73bfe7444e 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_classified_info.xml
+++ b/indra/newview/skins/default/xui/pt/panel_classified_info.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_clothing_list_button_bar.xml b/indra/newview/skins/default/xui/pt/panel_clothing_list_button_bar.xml
index bfdc7290d2..bfdc7290d2 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_clothing_list_button_bar.xml
+++ b/indra/newview/skins/default/xui/pt/panel_clothing_list_button_bar.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_clothing_list_item.xml b/indra/newview/skins/default/xui/pt/panel_clothing_list_item.xml
index 4b45a49f74..4b45a49f74 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_clothing_list_item.xml
+++ b/indra/newview/skins/default/xui/pt/panel_clothing_list_item.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_cof_wearables.xml b/indra/newview/skins/default/xui/pt/panel_cof_wearables.xml
index 3e4b12b001..3e4b12b001 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_cof_wearables.xml
+++ b/indra/newview/skins/default/xui/pt/panel_cof_wearables.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_conversation_list_item.xml b/indra/newview/skins/default/xui/pt/panel_conversation_list_item.xml
new file mode 100644
index 0000000000..f56168c962
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/panel_conversation_list_item.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="conversation_list_item">
+ <layout_stack name="conversation_item_stack">
+ <layout_panel name="conversation_title_panel">
+ <text name="conversation_title" value="(carregando)"/>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_conversation_log_list_item.xml b/indra/newview/skins/default/xui/pt/panel_conversation_log_list_item.xml
new file mode 100644
index 0000000000..74daded58f
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/panel_conversation_log_list_item.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="conversation_log_list_item">
+ <icon name="voice_session_icon" tool_tip="Uma conversa de voz foi incluída"/>
+ <icon name="unread_ims_icon" tool_tip="Chegaram mensagens enquanto você estava desconectado"/>
+ <button name="delete_btn" tool_tip="Remover esta entrada"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_deletable_wearable_list_item.xml b/indra/newview/skins/default/xui/pt/panel_deletable_wearable_list_item.xml
index 7ca5e23981..7ca5e23981 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_deletable_wearable_list_item.xml
+++ b/indra/newview/skins/default/xui/pt/panel_deletable_wearable_list_item.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_dummy_clothing_list_item.xml b/indra/newview/skins/default/xui/pt/panel_dummy_clothing_list_item.xml
index 3dfb5a0a16..3dfb5a0a16 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_dummy_clothing_list_item.xml
+++ b/indra/newview/skins/default/xui/pt/panel_dummy_clothing_list_item.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_edit_alpha.xml b/indra/newview/skins/default/xui/pt/panel_edit_alpha.xml
index b274945dbd..b274945dbd 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_edit_alpha.xml
+++ b/indra/newview/skins/default/xui/pt/panel_edit_alpha.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_edit_classified.xml b/indra/newview/skins/default/xui/pt/panel_edit_classified.xml
index 23e00bfc3a..23e00bfc3a 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_edit_classified.xml
+++ b/indra/newview/skins/default/xui/pt/panel_edit_classified.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_edit_eyes.xml b/indra/newview/skins/default/xui/pt/panel_edit_eyes.xml
index f21656d526..f21656d526 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_edit_eyes.xml
+++ b/indra/newview/skins/default/xui/pt/panel_edit_eyes.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_edit_gloves.xml b/indra/newview/skins/default/xui/pt/panel_edit_gloves.xml
index 281823d641..281823d641 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_edit_gloves.xml
+++ b/indra/newview/skins/default/xui/pt/panel_edit_gloves.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_edit_hair.xml b/indra/newview/skins/default/xui/pt/panel_edit_hair.xml
index 13f1f892f9..13f1f892f9 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_edit_hair.xml
+++ b/indra/newview/skins/default/xui/pt/panel_edit_hair.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_edit_jacket.xml b/indra/newview/skins/default/xui/pt/panel_edit_jacket.xml
index 5798325bd7..5798325bd7 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_edit_jacket.xml
+++ b/indra/newview/skins/default/xui/pt/panel_edit_jacket.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_edit_pants.xml b/indra/newview/skins/default/xui/pt/panel_edit_pants.xml
index 18568a81a8..18568a81a8 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_edit_pants.xml
+++ b/indra/newview/skins/default/xui/pt/panel_edit_pants.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_edit_physics.xml b/indra/newview/skins/default/xui/pt/panel_edit_physics.xml
index 967aab8bc3..967aab8bc3 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_edit_physics.xml
+++ b/indra/newview/skins/default/xui/pt/panel_edit_physics.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_edit_pick.xml b/indra/newview/skins/default/xui/pt/panel_edit_pick.xml
index 5eb9987e71..5eb9987e71 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_edit_pick.xml
+++ b/indra/newview/skins/default/xui/pt/panel_edit_pick.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_edit_profile.xml b/indra/newview/skins/default/xui/pt/panel_edit_profile.xml
index 0ba7382845..0ba7382845 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_edit_profile.xml
+++ b/indra/newview/skins/default/xui/pt/panel_edit_profile.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_edit_shape.xml b/indra/newview/skins/default/xui/pt/panel_edit_shape.xml
index de41ba3ad2..de41ba3ad2 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_edit_shape.xml
+++ b/indra/newview/skins/default/xui/pt/panel_edit_shape.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_edit_shirt.xml b/indra/newview/skins/default/xui/pt/panel_edit_shirt.xml
index c7e2b1e64c..c7e2b1e64c 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_edit_shirt.xml
+++ b/indra/newview/skins/default/xui/pt/panel_edit_shirt.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_edit_shoes.xml b/indra/newview/skins/default/xui/pt/panel_edit_shoes.xml
index 08465d09e7..08465d09e7 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_edit_shoes.xml
+++ b/indra/newview/skins/default/xui/pt/panel_edit_shoes.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_edit_skin.xml b/indra/newview/skins/default/xui/pt/panel_edit_skin.xml
index d00aa2dc66..d00aa2dc66 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_edit_skin.xml
+++ b/indra/newview/skins/default/xui/pt/panel_edit_skin.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_edit_skirt.xml b/indra/newview/skins/default/xui/pt/panel_edit_skirt.xml
index 275efba6e6..275efba6e6 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_edit_skirt.xml
+++ b/indra/newview/skins/default/xui/pt/panel_edit_skirt.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_edit_socks.xml b/indra/newview/skins/default/xui/pt/panel_edit_socks.xml
index 6f4779d855..6f4779d855 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_edit_socks.xml
+++ b/indra/newview/skins/default/xui/pt/panel_edit_socks.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_edit_tattoo.xml b/indra/newview/skins/default/xui/pt/panel_edit_tattoo.xml
index f85bb3c499..f85bb3c499 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_edit_tattoo.xml
+++ b/indra/newview/skins/default/xui/pt/panel_edit_tattoo.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_edit_underpants.xml b/indra/newview/skins/default/xui/pt/panel_edit_underpants.xml
index c383471851..c383471851 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_edit_underpants.xml
+++ b/indra/newview/skins/default/xui/pt/panel_edit_underpants.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_edit_undershirt.xml b/indra/newview/skins/default/xui/pt/panel_edit_undershirt.xml
index 0bf510c67f..0bf510c67f 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_edit_undershirt.xml
+++ b/indra/newview/skins/default/xui/pt/panel_edit_undershirt.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_edit_wearable.xml b/indra/newview/skins/default/xui/pt/panel_edit_wearable.xml
index 2e3e3d6305..2e3e3d6305 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_edit_wearable.xml
+++ b/indra/newview/skins/default/xui/pt/panel_edit_wearable.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_group_control_panel.xml b/indra/newview/skins/default/xui/pt/panel_group_control_panel.xml
index 502dae8d67..502dae8d67 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_group_control_panel.xml
+++ b/indra/newview/skins/default/xui/pt/panel_group_control_panel.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_group_general.xml b/indra/newview/skins/default/xui/pt/panel_group_general.xml
index b634ec3f64..b634ec3f64 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_group_general.xml
+++ b/indra/newview/skins/default/xui/pt/panel_group_general.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_group_info_sidetray.xml b/indra/newview/skins/default/xui/pt/panel_group_info_sidetray.xml
index 30c825723b..30c825723b 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_group_info_sidetray.xml
+++ b/indra/newview/skins/default/xui/pt/panel_group_info_sidetray.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_group_invite.xml b/indra/newview/skins/default/xui/pt/panel_group_invite.xml
index c7def0ed96..de057481de 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_group_invite.xml
+++ b/indra/newview/skins/default/xui/pt/panel_group_invite.xml
@@ -9,6 +9,9 @@
<panel.string name="already_in_group">
Alguns dos residentes selecionados já estão no grupo, portanto não receberam convite.
</panel.string>
+ <panel.string name="invite_selection_too_large">
+ Os convites para o grupo não foram enviados: muitos residentes selecionados. Os convites para o grupo são limitados a 100 por solicitação.
+ </panel.string>
<text name="help_text" width="214">
Selecione um ou mais residentes para convidar. Clique em &apos;Abrir seletor de residentes&apos; para começar.
</text>
diff --git a/indra/newview/skins/default/xui/pt/panel_group_land_money.xml b/indra/newview/skins/default/xui/pt/panel_group_land_money.xml
index 2346fe7f4f..2346fe7f4f 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_group_land_money.xml
+++ b/indra/newview/skins/default/xui/pt/panel_group_land_money.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_group_list_item.xml b/indra/newview/skins/default/xui/pt/panel_group_list_item.xml
index 19c34d2f10..0490878507 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_group_list_item.xml
+++ b/indra/newview/skins/default/xui/pt/panel_group_list_item.xml
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel name="group_list_item">
<text name="group_name" value="Desconhecido"/>
+ <button name="info_btn" tool_tip="Mais informações"/>
<button name="profile_btn" tool_tip="Ver perfil"/>
</panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_group_notices.xml b/indra/newview/skins/default/xui/pt/panel_group_notices.xml
index 3bff1f8fb3..3bff1f8fb3 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_group_notices.xml
+++ b/indra/newview/skins/default/xui/pt/panel_group_notices.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_group_notify.xml b/indra/newview/skins/default/xui/pt/panel_group_notify.xml
index 5a8ea81074..5a8ea81074 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_group_notify.xml
+++ b/indra/newview/skins/default/xui/pt/panel_group_notify.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_group_roles.xml b/indra/newview/skins/default/xui/pt/panel_group_roles.xml
index 11a31570d1..11a31570d1 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_group_roles.xml
+++ b/indra/newview/skins/default/xui/pt/panel_group_roles.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_im_control_panel.xml b/indra/newview/skins/default/xui/pt/panel_im_control_panel.xml
index 91b7d1b7cd..91b7d1b7cd 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_im_control_panel.xml
+++ b/indra/newview/skins/default/xui/pt/panel_im_control_panel.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_inventory_item.xml b/indra/newview/skins/default/xui/pt/panel_inventory_item.xml
index d18047fbcf..d18047fbcf 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_inventory_item.xml
+++ b/indra/newview/skins/default/xui/pt/panel_inventory_item.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_landmark_info.xml b/indra/newview/skins/default/xui/pt/panel_landmark_info.xml
index 39c19a22d4..39c19a22d4 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_landmark_info.xml
+++ b/indra/newview/skins/default/xui/pt/panel_landmark_info.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_landmarks.xml b/indra/newview/skins/default/xui/pt/panel_landmarks.xml
index 49e1203601..49e1203601 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_landmarks.xml
+++ b/indra/newview/skins/default/xui/pt/panel_landmarks.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_login.xml b/indra/newview/skins/default/xui/pt/panel_login.xml
index f4af6a7108..d7e9fa76ea 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_login.xml
+++ b/indra/newview/skins/default/xui/pt/panel_login.xml
@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel name="panel_login">
- <panel.string name="create_account_url">
- http://join.secondlife.com/
- </panel.string>
<panel.string name="forgot_password_url">
http://secondlife.com/account/request.php?lang=pt
</panel.string>
<layout_stack name="login_widgets">
<layout_panel name="login">
+ <text name="log_in_text">
+ LOGIN
+ </text>
<text name="username_text">
Nome de usuário:
</text>
@@ -15,33 +15,32 @@
<text name="password_text">
Senha:
</text>
- <check_box label="Lembrar senha" name="remember_check"/>
- <button label="conectar" name="connect_btn"/>
- <text name="mode_selection_text">
- Modo:
- </text>
- <combo_box name="mode_combo" tool_tip="Selecione o modo. O modo Básico é mais rápido e ideal para explorar e conversar. Use o modo Avançado para acessar mais recursos.">
- <combo_box.item label="Básico" name="Basic"/>
- <combo_box.item label="Avançado" name="Advanced"/>
- </combo_box>
+ </layout_panel>
+ <layout_panel name="start_location_panel">
<text name="start_location_text">
Começar em:
</text>
<combo_box name="start_location_combo">
<combo_box.item label="Última posição" name="MyLastLocation"/>
- <combo_box.item label="Meu início" name="MyHome"/>
+ <combo_box.item label="Minha casa" name="MyHome"/>
+ <combo_box.item label="&lt;Digite o nome da região&gt;" name="Typeregionname"/>
</combo_box>
</layout_panel>
- <layout_panel name="links">
- <text name="create_new_account_text">
- Cadastre-se
+ <layout_panel name="links_login_panel">
+ <text name="login_help">
+ Precisa de ajuda com o login?
</text>
<text name="forgot_password_text">
Esqueceu seu nome ou senha?
</text>
- <text name="login_help">
- Precisa de ajuda ao conectar?
+ <button label="Login" name="connect_btn"/>
+ <check_box label="Lembrar senha" name="remember_check"/>
+ </layout_panel>
+ <layout_panel name="links">
+ <text name="create_account_text">
+ CRIE SUA CONTA
</text>
+ <button label="Comece agora" name="create_new_account_btn"/>
</layout_panel>
</layout_stack>
</panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_main_inventory.xml b/indra/newview/skins/default/xui/pt/panel_main_inventory.xml
index dbf8e4fa52..dbf8e4fa52 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_main_inventory.xml
+++ b/indra/newview/skins/default/xui/pt/panel_main_inventory.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_me.xml b/indra/newview/skins/default/xui/pt/panel_me.xml
index 281c886bd4..281c886bd4 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_me.xml
+++ b/indra/newview/skins/default/xui/pt/panel_me.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_media_settings_general.xml b/indra/newview/skins/default/xui/pt/panel_media_settings_general.xml
index 43c0820036..43c0820036 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_media_settings_general.xml
+++ b/indra/newview/skins/default/xui/pt/panel_media_settings_general.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_media_settings_permissions.xml b/indra/newview/skins/default/xui/pt/panel_media_settings_permissions.xml
index 55226db274..55226db274 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_media_settings_permissions.xml
+++ b/indra/newview/skins/default/xui/pt/panel_media_settings_permissions.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_media_settings_security.xml b/indra/newview/skins/default/xui/pt/panel_media_settings_security.xml
index e38c44d8fe..e38c44d8fe 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_media_settings_security.xml
+++ b/indra/newview/skins/default/xui/pt/panel_media_settings_security.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_navigation_bar.xml b/indra/newview/skins/default/xui/pt/panel_navigation_bar.xml
index 4fa5436805..4fa5436805 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_navigation_bar.xml
+++ b/indra/newview/skins/default/xui/pt/panel_navigation_bar.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_nearby_chat.xml b/indra/newview/skins/default/xui/pt/panel_nearby_chat.xml
index 6828d41dee..6828d41dee 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_nearby_chat.xml
+++ b/indra/newview/skins/default/xui/pt/panel_nearby_chat.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_nearby_chat_bar.xml b/indra/newview/skins/default/xui/pt/panel_nearby_chat_bar.xml
index 9b993488be..5628a87109 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_nearby_chat_bar.xml
+++ b/indra/newview/skins/default/xui/pt/panel_nearby_chat_bar.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel name="chat_bar">
+<panel name="nearby_chat">
<line_editor label="Clique aqui para bater papo." name="chat_box" tool_tip="Tecle Enter para falar, Ctrl+Enter para gritar"/>
<button name="show_nearby_chat" tool_tip="Mostra/oculta o histórico do bate-papo local"/>
</panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_nearby_media.xml b/indra/newview/skins/default/xui/pt/panel_nearby_media.xml
index 43bf8f9661..43bf8f9661 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_nearby_media.xml
+++ b/indra/newview/skins/default/xui/pt/panel_nearby_media.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_notify_textbox.xml b/indra/newview/skins/default/xui/pt/panel_notify_textbox.xml
index dcd9ba1815..dcd9ba1815 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_notify_textbox.xml
+++ b/indra/newview/skins/default/xui/pt/panel_notify_textbox.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_online_status_toast.xml b/indra/newview/skins/default/xui/pt/panel_online_status_toast.xml
index fdc489f375..fdc489f375 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_online_status_toast.xml
+++ b/indra/newview/skins/default/xui/pt/panel_online_status_toast.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_outbox_inventory.xml b/indra/newview/skins/default/xui/pt/panel_outbox_inventory.xml
index 442622035a..442622035a 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_outbox_inventory.xml
+++ b/indra/newview/skins/default/xui/pt/panel_outbox_inventory.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_outfit_edit.xml b/indra/newview/skins/default/xui/pt/panel_outfit_edit.xml
index eb23f5c079..eb23f5c079 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_outfit_edit.xml
+++ b/indra/newview/skins/default/xui/pt/panel_outfit_edit.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_outfits_inventory.xml b/indra/newview/skins/default/xui/pt/panel_outfits_inventory.xml
index 816a9bc46e..816a9bc46e 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_outfits_inventory.xml
+++ b/indra/newview/skins/default/xui/pt/panel_outfits_inventory.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_outfits_inventory_gear_default.xml b/indra/newview/skins/default/xui/pt/panel_outfits_inventory_gear_default.xml
index 736b8f1fdd..736b8f1fdd 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_outfits_inventory_gear_default.xml
+++ b/indra/newview/skins/default/xui/pt/panel_outfits_inventory_gear_default.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_outfits_list.xml b/indra/newview/skins/default/xui/pt/panel_outfits_list.xml
index 2d74e092a4..2d74e092a4 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_outfits_list.xml
+++ b/indra/newview/skins/default/xui/pt/panel_outfits_list.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_outfits_wearing.xml b/indra/newview/skins/default/xui/pt/panel_outfits_wearing.xml
index 9224ec4742..9224ec4742 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_outfits_wearing.xml
+++ b/indra/newview/skins/default/xui/pt/panel_outfits_wearing.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_people.xml b/indra/newview/skins/default/xui/pt/panel_people.xml
index f3af15b991..205fd6b97d 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_people.xml
+++ b/indra/newview/skins/default/xui/pt/panel_people.xml
@@ -14,81 +14,56 @@ Em busca de alguém para conversar? Procure no [secondlife:///app/worldmap Mapa-
<string name="no_filtered_friends_msg">
Não encontrou o que procura? Tente buscar no [secondlife:///app/search/people/[SEARCH_TERM] Search].
</string>
- <string name="people_filter_label" value="Filtro de pessoas"/>
- <string name="groups_filter_label" value="Filtro de grupos"/>
<string name="no_filtered_groups_msg" value="Não encontrou o que procura? Tente buscar no [secondlife:///app/search/groups/[SEARCH_TERM] Search]."/>
<string name="no_groups_msg" value="À procura de grupos interessantes? Tente fazer uma [secondlife:///app/search/groups Busca]."/>
<string name="MiniMapToolTipMsg" value="[REGION](Clique duas vezes para abrir o mapa, shift+arraste para a visão pan)"/>
<string name="AltMiniMapToolTipMsg" value="[REGION](Clique duas vezes para teletransportar, shift+arraste para a visão pan)"/>
- <filter_editor label="Filtro" name="filter_input"/>
<tab_container name="tabs">
<panel label="PROXIMIDADE" name="nearby_panel">
- <panel label="bottom_panel" name="bottom_panel">
- <menu_button name="nearby_view_sort_btn" tool_tip="Opções"/>
- <button name="add_friend_btn" tool_tip="Adicionar o residente selecionado para sua lista de amigos"/>
+ <panel label="bottom_panel" name="nearby_buttons_panel">
+ <filter_editor label="Filtrar pessoas" name="nearby_filter_input"/>
+ <button name="gear_btn" tool_tip="Ações nas pessoas selecionadas"/>
+ <menu_button name="nearby_view_btn" tool_tip="Opções de exibição/ordenação"/>
+ <button name="add_friend_btn" tool_tip="Oferecer amizade ao residente"/>
+ <dnd_button name="nearby_del_btn" tool_tip="Remover a pessoa selecionada dos amigos"/>
</panel>
</panel>
- <panel label="MEUS AMIGOS" name="friends_panel">
+ <panel label="AMIGOS" name="friends_panel">
+ <panel label="bottom_panel" name="friends_buttons_panel">
+ <filter_editor label="Filtrar pessoas" name="friends_filter_input"/>
+ <button name="gear_btn" tool_tip="Ações nas pessoas selecionadas"/>
+ <menu_button name="friends_view_btn" tool_tip="Opções de exibição/ordenação"/>
+ <button name="friends_add_btn" tool_tip="Oferecer amizade ao residente"/>
+ <dnd_button name="friends_del_btn" tool_tip="Remover a pessoa selecionada dos amigos"/>
+ </panel>
<accordion name="friends_accordion">
<accordion_tab name="tab_online" title="Online"/>
<accordion_tab name="tab_all" title="Todos"/>
</accordion>
- <panel label="bottom_panel" name="bottom_panel">
- <layout_stack name="bottom_panel">
- <layout_panel name="options_gear_btn_panel">
- <menu_button name="friends_viewsort_btn" tool_tip="Mostrar opções adicionais"/>
- </layout_panel>
- <layout_panel name="add_btn_panel">
- <button name="add_btn" tool_tip="Oferecer amizade para um residente"/>
- </layout_panel>
- <layout_panel name="trash_btn_panel">
- <dnd_button name="del_btn" tool_tip="Remover a pessoa selecionada da sua lista de amigos"/>
- </layout_panel>
- </layout_stack>
- </panel>
</panel>
- <panel label="MEUS GRUPOS" name="groups_panel">
- <panel label="bottom_panel" name="bottom_panel">
- <menu_button name="groups_viewsort_btn" tool_tip="Opções"/>
- <button name="plus_btn" tool_tip="Ingressar em um grupo/Criar novo grupo"/>
- <button name="activate_btn" tool_tip="Ativar o grupo selecionado"/>
+ <panel label="GRUPOS" name="groups_panel">
+ <panel label="bottom_panel" name="groups_buttons_panel">
+ <filter_editor label="Filtrar grupos" name="groups_filter_input"/>
+ <menu_button name="groups_gear_btn" tool_tip="Ações no grupo selecionado"/>
+ <menu_button name="groups_view_btn" tool_tip="Opções de exibição/ordenação"/>
+ <menu_button name="plus_btn" tool_tip="Entrar em um grupo/Criar novo grupo"/>
+ <dnd_button name="minus_btn" tool_tip="Sair do grupo selecionado"/>
</panel>
+ <text name="groupcount">
+ Você pertence a [COUNT] grupos e pode entrar em mais [REMAINING].
+ </text>
</panel>
<panel label="RECENTE" name="recent_panel">
- <panel label="bottom_panel" name="bottom_panel">
- <menu_button name="recent_viewsort_btn" tool_tip="Opções"/>
- <button name="add_friend_btn" tool_tip="Adicionar o residente selecionado para sua lista de amigos"/>
+ <panel label="bottom_panel" name="recent_buttons_panel">
+ <filter_editor label="Filtrar pessoas" name="recent_filter_input"/>
+ <button name="gear_btn" tool_tip="Ações nas pessoas selecionadas"/>
+ <menu_button name="recent_view_btn" tool_tip="Opções de exibição/ordenação"/>
+ <button name="add_friend_btn" tool_tip="Oferecer amizade ao residente"/>
+ <dnd_button name="recent_del_btn" tool_tip="Remover a pessoa selecionada dos amigos"/>
</panel>
</panel>
+ <panel label="BLOQUEADA" name="blocked_panel">
+ <panel label="Residentes e objetos bloqueados" name="panel_block_list_sidetray"/>
+ </panel>
</tab_container>
- <panel name="button_bar">
- <layout_stack name="bottom_bar_ls">
- <layout_panel name="view_profile_btn_lp">
- <button label="Perfil" name="view_profile_btn" tool_tip="Exibir fotografia, grupos e outras informações dos residentes"/>
- </layout_panel>
- <layout_panel name="im_btn_lp">
- <button label="MI" name="im_btn" tool_tip="Abrir sessão de mensagem instantânea"/>
- </layout_panel>
- <layout_panel name="call_btn_lp">
- <button label="Ligar" name="call_btn" tool_tip="Ligar para este residente"/>
- </layout_panel>
- <layout_panel name="share_btn_lp">
- <button label="Compartilhar" name="share_btn" tool_tip="Compartilhar item de inventário"/>
- </layout_panel>
- <layout_panel name="teleport_btn_lp">
- <button label="Teletransportar" name="teleport_btn" tool_tip="Oferecer teletransporte"/>
- </layout_panel>
- </layout_stack>
- <layout_stack name="bottom_bar_ls1">
- <layout_panel name="group_info_btn_lp">
- <button label="Perfil do grupo" name="group_info_btn" tool_tip="Exibir dados do grupo"/>
- </layout_panel>
- <layout_panel name="chat_btn_lp">
- <button label="Bate-papo de grupo" name="chat_btn" tool_tip="Nova sessão de bate-papo"/>
- </layout_panel>
- <layout_panel name="group_call_btn_lp">
- <button label="Ligar para o grupo" name="group_call_btn" tool_tip="Ligar para este grupo"/>
- </layout_panel>
- </layout_stack>
- </panel>
</panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_pick_info.xml b/indra/newview/skins/default/xui/pt/panel_pick_info.xml
index caa140a245..caa140a245 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_pick_info.xml
+++ b/indra/newview/skins/default/xui/pt/panel_pick_info.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_picks.xml b/indra/newview/skins/default/xui/pt/panel_picks.xml
index 2ff1eed624..2ff1eed624 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_picks.xml
+++ b/indra/newview/skins/default/xui/pt/panel_picks.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_place_profile.xml b/indra/newview/skins/default/xui/pt/panel_place_profile.xml
index 8abe579702..8abe579702 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_place_profile.xml
+++ b/indra/newview/skins/default/xui/pt/panel_place_profile.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_places.xml b/indra/newview/skins/default/xui/pt/panel_places.xml
index 69f0baf65f..69f0baf65f 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_places.xml
+++ b/indra/newview/skins/default/xui/pt/panel_places.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_postcard_message.xml b/indra/newview/skins/default/xui/pt/panel_postcard_message.xml
index 9cde810430..9cde810430 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_postcard_message.xml
+++ b/indra/newview/skins/default/xui/pt/panel_postcard_message.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_postcard_settings.xml b/indra/newview/skins/default/xui/pt/panel_postcard_settings.xml
index 3088b9a996..3088b9a996 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_postcard_settings.xml
+++ b/indra/newview/skins/default/xui/pt/panel_postcard_settings.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_preferences_advanced.xml b/indra/newview/skins/default/xui/pt/panel_preferences_advanced.xml
index c72928fc35..c72928fc35 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_preferences_advanced.xml
+++ b/indra/newview/skins/default/xui/pt/panel_preferences_advanced.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_preferences_alerts.xml b/indra/newview/skins/default/xui/pt/panel_preferences_alerts.xml
index 2ffe720ccf..2ffe720ccf 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_preferences_alerts.xml
+++ b/indra/newview/skins/default/xui/pt/panel_preferences_alerts.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_preferences_chat.xml b/indra/newview/skins/default/xui/pt/panel_preferences_chat.xml
index c5a4febb0e..89f1e07647 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/pt/panel_preferences_chat.xml
@@ -1,33 +1,99 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel label="Chat" name="chat">
- <text name="font_size">
- Tamanho da fonte:
- </text>
- <radio_group name="chat_font_size">
- <radio_item label="Pequeno" name="radio" value="0"/>
- <radio_item label="Médio" name="radio2" value="1"/>
- <radio_item label="Grande" name="radio3" value="2"/>
- </radio_group>
- <check_box initial_value="true" label="Executar animação digitada quando estiver conversando" name="play_typing_animation"/>
- <check_box label="Enviar MIs por email se estiver desconectado" name="send_im_to_email"/>
- <check_box label="Ativar MIs e bate-papos de texto simples" name="plain_text_chat_history"/>
- <check_box label="Balão de bate-papo" name="bubble_text_chat"/>
- <text name="show_ims_in_label">
- Mostrar MIs em:
- </text>
- <text name="requires_restart_label">
- (Reinicie para ativar)
- </text>
- <radio_group name="chat_window" tool_tip="Exibir cada bate-papo em uma janela separada ou exibir todos em uma única janela com uma aba para cada pessoa (requer reinício)">
- <radio_item label="Janelas separadas" name="radio" value="0"/>
- <radio_item label="Guias" name="radio2" value="1"/>
- </radio_group>
- <text name="disable_toast_label">
- Ativar pop-ups de novos bate-papos:
- </text>
- <check_box label="Bate-papo de grupo" name="EnableGroupChatPopups" tool_tip="Exibir pop-up de bate-papos novos de grupos"/>
- <check_box label="Bate-papos de MI" name="EnableIMChatPopups" tool_tip="Exibir pop-up de mensagens instantâneas novas"/>
- <spinner label="Transição de avisos de bate-papos por perto:" name="nearby_toasts_lifetime"/>
- <spinner label="Transição de avisos de bate-papos por perto:" name="nearby_toasts_fadingtime"/>
- <button label="Configurações de tradução de bate-papo" name="ok_btn"/>
+ <panel name="general_chat_settings">
+ <check_box initial_value="true" label="Executar animação de digitação durante o bate-papo" name="play_typing_animation"/>
+ <check_box label="Envie MIs por email quando eu estiver desconectado" name="send_im_to_email"/>
+ <check_box label="Apenas amigos e grupos podem me ligar ou enviar MIs" name="voice_call_friends_only_check"/>
+ <text name="font_size">
+ Tamanho da fonte:
+ </text>
+ <combo_box name="chat_font_size">
+ <item label="Pequeno" name="Small" value="0"/>
+ <item label="Médio" name="Medium" value="1"/>
+ <item label="Grande" name="Large" value="2"/>
+ </combo_box>
+ <check_box label="Balão de conversa" name="bubble_text_chat"/>
+ </panel>
+ <panel name="im_notification_settings">
+ <text name="friend_ims">
+ MIs de amigos:
+ </text>
+ <combo_box name="FriendIMOptions">
+ <item label="Abrir janela Conversas" name="OpenConversationsWindow" value="openconversations"/>
+ <item label="Abrir pop up com mensagem" name="PopUpMessage" value="avisos"/>
+ <item label="Piscar botão da barra de ferramentas" name="FlashToolbarButton" value="piscar"/>
+ <item label="Nenhuma ação" name="NoAction" value="noaction"/>
+ </combo_box>
+ <check_box label="Executar som" name="play_sound_friend_im"/>
+ <text name="non_friend_ims">
+ MIs de não amigos:
+ </text>
+ <combo_box name="NonFriendIMOptions">
+ <item label="Abrir janela Conversas" name="OpenConversationsWindow" value="openconversations"/>
+ <item label="Abrir pop up com mensagem" name="PopUpMessage" value="avisos"/>
+ <item label="Piscar botão da barra de ferramentas" name="FlashToolbarButton" value="piscar"/>
+ <item label="Nenhuma ação" name="NoAction" value="noaction"/>
+ </combo_box>
+ <check_box label="Executar som" name="play_sound_non_friend_im"/>
+ <text name="conference_ims">
+ MIs de conferências:
+ </text>
+ <combo_box name="ConferenceIMOptions">
+ <item label="Abrir janela Conversas" name="OpenConversationsWindow" value="openconversations"/>
+ <item label="Abrir pop up com mensagem" name="PopUpMessage" value="avisos"/>
+ <item label="Piscar botão da barra de ferramentas" name="FlashToolbarButton" value="piscar"/>
+ <item label="Nenhuma ação" name="NoAction" value="noaction"/>
+ </combo_box>
+ <check_box label="Executar som" name="play_sound_conference_im"/>
+ <text name="group_chat">
+ Conversa em grupo:
+ </text>
+ <combo_box name="GroupChatOptions">
+ <item label="Abrir janela Conversas" name="OpenConversationsWindow" value="openconversations"/>
+ <item label="Abrir pop up com mensagem" name="PopUpMessage" value="avisos"/>
+ <item label="Piscar botão da barra de ferramentas" name="FlashToolbarButton" value="piscar"/>
+ <item label="Nenhuma ação" name="NoAction" value="noaction"/>
+ </combo_box>
+ <check_box label="Executar som" name="play_sound_group_chat_im"/>
+ <text name="nearby_chat">
+ Conversa local:
+ </text>
+ <combo_box name="NearbyChatOptions">
+ <item label="Abrir janela Conversas" name="OpenConversationsWindow" value="openconversations"/>
+ <item label="Abrir pop up com mensagem" name="PopUpMessage" value="avisos"/>
+ <item label="Piscar botão da barra de ferramentas" name="FlashToolBarButton" value="piscar"/>
+ <item label="Nenhuma ação" name="NoAction" value="noaction"/>
+ </combo_box>
+ <check_box label="Executar som" name="play_sound_nearby_chat_im"/>
+ <text name="object_ims">
+ MIs de objetos:
+ </text>
+ <combo_box name="ObjectIMOptions">
+ <item label="Abrir janela Conversas" name="OpenConversationsWindow" value="openconversations"/>
+ <item label="Abrir pop up com mensagem" name="PopUpMessage" value="avisos"/>
+ <item label="Piscar botão da barra de ferramentas" name="FlashToolBarButton" value="piscar"/>
+ <item label="Nenhuma ação" name="NoAction" value="noaction"/>
+ </combo_box>
+ <check_box label="Executar som" name="play_sound_object_im"/>
+ <text name="notifications_alert">
+ Para interromper temporariamente todas as notificações, use Comunicar &gt; Não perturbe.
+ </text>
+ </panel>
+ <panel name="play_sound_settings">
+ <text name="play_sound">
+ Executar som:
+ </text>
+ <check_box label="Nova conversa" name="new_conversation"/>
+ <check_box label="Chamada de voz recebida" name="incoming_voice_call"/>
+ <check_box label="Oferta de teletransporte" name="teleport_offer"/>
+ <check_box label="Oferta de inventário" name="inventory_offer"/>
+ </panel>
+ <panel name="log_settings">
+ <button label="Limpar registro..." name="clear_log"/>
+ <button label="Excluir transcrições..." name="delete_transcripts"/>
+ <button label="Procurar..." label_selected="Procurar" name="log_path_button"/>
+ </panel>
+ <button label="Tradução..." name="ok_btn"/>
+ <button label="Substituição automática..." name="autoreplace_showgui"/>
+ <button label="Verificando a ortografia..." name="spellcheck_showgui"/>
</panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_preferences_colors.xml b/indra/newview/skins/default/xui/pt/panel_preferences_colors.xml
index d6c6f66e37..d6c6f66e37 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_preferences_colors.xml
+++ b/indra/newview/skins/default/xui/pt/panel_preferences_colors.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_preferences_general.xml b/indra/newview/skins/default/xui/pt/panel_preferences_general.xml
index c53aa7d5f7..8a0495f9bb 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_preferences_general.xml
+++ b/indra/newview/skins/default/xui/pt/panel_preferences_general.xml
@@ -69,6 +69,9 @@
<combo_box.item label="(nunca)" name="item4"/>
</combo_box>
<text name="text_box3">
- Mensagem do modo ocupado:
+ Resposta de Não perturbe:
</text>
+ <text_editor name="do_not_disturb_response">
+ log_in_to_change
+ </text_editor>
</panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/pt/panel_preferences_graphics1.xml
index 28e7184326..756e345cb8 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_preferences_graphics1.xml
+++ b/indra/newview/skins/default/xui/pt/panel_preferences_graphics1.xml
@@ -26,14 +26,14 @@ rápido
<text name="ShadersText">
Sombreadores:
</text>
- <check_box initial_value="verdadeiro" label="Ãgua transparente" name="TransparentWater"/>
+ <check_box initial_value="true" label="Ãgua transparente" name="TransparentWater"/>
<check_box initial_value="true" label="Bump de Mapeamento e Brilho" name="BumpShiny"/>
- <check_box initial_value="verdadeiro" label="Luzes locais" name="LocalLights"/>
+ <check_box initial_value="true" label="Luzes locais" name="LocalLights"/>
<check_box initial_value="true" label="Sombreadores básicos" name="BasicShaders" tool_tip="Desabilitar esta opção poderá impedir que alguns drivers de placa de vídeo a travem."/>
<check_box initial_value="true" label="Sombreadores Atmosféricos" name="WindLightUseAtmosShaders"/>
- <check_box initial_value="verdadeiro" label="Iluminação e sombras" name="UseLightShaders"/>
- <check_box initial_value="verdadeiro" label="Oclusão ambiental" name="UseSSAO"/>
- <check_box initial_value="verdadeiro" label="Profundidade" name="UseDoF"/>
+ <check_box initial_value="true" label="Modelo avançado de luzes" name="UseLightShaders"/>
+ <check_box initial_value="true" label="Oclusão ambiental" name="UseSSAO"/>
+ <check_box initial_value="true" label="Profundidade" name="UseDoF"/>
<text name="shadows_label">
Sombras:
</text>
diff --git a/indra/newview/skins/default/xui/pt/panel_preferences_move.xml b/indra/newview/skins/default/xui/pt/panel_preferences_move.xml
index fa6f5f5851..fa6f5f5851 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_preferences_move.xml
+++ b/indra/newview/skins/default/xui/pt/panel_preferences_move.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_preferences_privacy.xml b/indra/newview/skins/default/xui/pt/panel_preferences_privacy.xml
index d7fb585e35..d7fb585e35 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_preferences_privacy.xml
+++ b/indra/newview/skins/default/xui/pt/panel_preferences_privacy.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_preferences_setup.xml b/indra/newview/skins/default/xui/pt/panel_preferences_setup.xml
index ebbd63138a..1279e74e21 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_preferences_setup.xml
+++ b/indra/newview/skins/default/xui/pt/panel_preferences_setup.xml
@@ -21,7 +21,7 @@
<check_box initial_value="true" label="Habilitar plugins" name="browser_plugins_enabled"/>
<check_box initial_value="true" label="Aceitar cookies" name="cookies_enabled"/>
<check_box initial_value="true" label="Habilitar Javascript" name="browser_javascript_enabled"/>
- <check_box initial_value="falso" label="Ativar pop-ups no navegador de mídia" name="media_popup_enabled"/>
+ <check_box initial_value="false" label="Ativar pop-ups no navegador de mídia" name="media_popup_enabled"/>
<text name="Software updates:">
Atualizações de software:
</text>
@@ -29,6 +29,7 @@
<combo_box.item label="Instalar automaticamente" name="Install_automatically"/>
<combo_box.item label="Baixar e instalar atualizações manualmente" name="Install_manual"/>
</combo_box>
+ <check_box label="Disposto a atualizar para candidatos da versão" name="update_willing_to_test"/>
<text name="Proxy Settings:">
Configurações de proxy:
</text>
diff --git a/indra/newview/skins/default/xui/pt/panel_preferences_sound.xml b/indra/newview/skins/default/xui/pt/panel_preferences_sound.xml
index d910a7b812..fff5fd7005 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_preferences_sound.xml
+++ b/indra/newview/skins/default/xui/pt/panel_preferences_sound.xml
@@ -19,7 +19,7 @@
<check_box label="Ativado" name="enable_voice_check"/>
<check_box label="Autorizar auto-play de mídias" name="media_auto_play_btn" tool_tip="Marque esta opção para auto-executar mídias, se elas quiserem" value="true"/>
<check_box label="Tocar mídia anexada em outros avatares" name="media_show_on_others_btn" tool_tip="Desmarque esta opção para ocultar mídias anexadas em avatares por perto" value="true"/>
- <check_box label="Tocar áudio de gestos" name="gesture_audio_play_btn" tool_tip="Selecione para ouvir o áudio de gestos" value="verdadeiro"/>
+ <check_box label="Tocar áudio de gestos" name="gesture_audio_play_btn" tool_tip="Selecione para ouvir o áudio de gestos" value="true"/>
<text name="voice_chat_settings">
Configuração de bate-papo de voz
</text>
diff --git a/indra/newview/skins/default/xui/pt/panel_prim_media_controls.xml b/indra/newview/skins/default/xui/pt/panel_prim_media_controls.xml
index 9e07b6772f..9e07b6772f 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_prim_media_controls.xml
+++ b/indra/newview/skins/default/xui/pt/panel_prim_media_controls.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_region_covenant.xml b/indra/newview/skins/default/xui/pt/panel_region_covenant.xml
index 65ac89baf8..65ac89baf8 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_region_covenant.xml
+++ b/indra/newview/skins/default/xui/pt/panel_region_covenant.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_region_debug.xml b/indra/newview/skins/default/xui/pt/panel_region_debug.xml
index f2cc9f644d..be15d40d74 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_region_debug.xml
+++ b/indra/newview/skins/default/xui/pt/panel_region_debug.xml
@@ -36,5 +36,5 @@
<button label="?" left="297" name="top_scripts_help"/>
<button label="Reiniciar a região" name="restart_btn" tool_tip="Após 2 minutos de contagem regressiva, reiniciar a região"/>
<button label="?" name="restart_help"/>
- <button label="Adiar reinício" name="cancel_restart_btn" tool_tip="Adiar o reinício da região por uma hora"/>
+ <button label="Cancelar reinício" name="cancel_restart_btn" tool_tip="Cancelar reinício da região"/>
</panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_region_environment.xml b/indra/newview/skins/default/xui/pt/panel_region_environment.xml
index 79eedebe5f..79eedebe5f 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_region_environment.xml
+++ b/indra/newview/skins/default/xui/pt/panel_region_environment.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_region_estate.xml b/indra/newview/skins/default/xui/pt/panel_region_estate.xml
index 6c5945aa15..b1453c9c32 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_region_estate.xml
+++ b/indra/newview/skins/default/xui/pt/panel_region_estate.xml
@@ -26,7 +26,7 @@
Permitir acesso apenas para residentes que:
</text>
<check_box label="Dados de pagamento constam no registro." name="limit_payment" tool_tip="Propriedade de acesso restrito a residentes que já cadastraram seus dados de pagamento Consulte o [SUPPORT_SITE] para saber mais."/>
- <check_box label="A idade foi verificada" name="limit_age_verified" tool_tip="Residentes devem ter a idade verificada para acessar esta propriedade. Consulte o [SUPPORT_SITE] para saber mais."/>
+ <check_box label="Tem 18 anos ou mais" name="limit_age_verified" tool_tip="Os residentes devem ter 18 anos ou mais para acessar esta propriedade. Consulte o [SUPPORT_SITE] para obter mais informações."/>
<check_box label="Permitir conversa de voz" name="voice_chat_check"/>
<button label="?" name="voice_chat_help"/>
<check_box label="Permitir Tele-transporte direto" name="allow_direct_teleport"/>
diff --git a/indra/newview/skins/default/xui/pt/panel_region_general.xml b/indra/newview/skins/default/xui/pt/panel_region_general.xml
index 4be1cd11c0..4be1cd11c0 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_region_general.xml
+++ b/indra/newview/skins/default/xui/pt/panel_region_general.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_region_terrain.xml b/indra/newview/skins/default/xui/pt/panel_region_terrain.xml
index 74330a8946..74330a8946 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_region_terrain.xml
+++ b/indra/newview/skins/default/xui/pt/panel_region_terrain.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_region_texture.xml b/indra/newview/skins/default/xui/pt/panel_region_texture.xml
deleted file mode 100644
index 35928ccc67..0000000000
--- a/indra/newview/skins/default/xui/pt/panel_region_texture.xml
+++ /dev/null
@@ -1,57 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel label="Texturas de Chão" name="Textures">
- <text name="region_text_lbl">
- Região:
- </text>
- <text name="region_text">
- desconhecido
- </text>
- <text name="detail_texture_text" width="380">
- Texturas de Terreno (requer 512x512, arquivos 24 bit .tga )
- </text>
- <text name="height_text_lbl">
- 1 (baixo)
- </text>
- <text name="height_text_lbl2">
- 2
- </text>
- <text name="height_text_lbl3">
- 3
- </text>
- <text name="height_text_lbl4">
- 4 (alto)
- </text>
- <text name="height_text_lbl5">
- Escalas de Elevação de Terreno
- </text>
- <text name="height_text_lbl6">
- Noroeste
- </text>
- <text name="height_text_lbl7">
- Nordeste
- </text>
- <text name="height_text_lbl8">
- Sudoeste
- </text>
- <text name="height_text_lbl9">
- Sudeste
- </text>
- <spinner label="Baixo" name="height_start_spin_0"/>
- <spinner label="Baixo" name="height_start_spin_1"/>
- <spinner label="Baixo" name="height_start_spin_2"/>
- <spinner label="Baixo" name="height_start_spin_3"/>
- <spinner label="Alto" name="height_range_spin_0"/>
- <spinner label="Alto" name="height_range_spin_1"/>
- <spinner label="Alto" name="height_range_spin_2"/>
- <spinner label="Alto" name="height_range_spin_3"/>
- <text name="height_text_lbl10">
- Os valores representam o intervalo de mistura das texturas acima.
- </text>
- <text name="height_text_lbl11">
- Em metros, o valor BAIXO é a altura MÃXIMA da Textura 1, e HIGH é a altura MÃNIMA da Textura 4.
- </text>
- <text name="height_text_lbl12">
- e o valor Alto é a altura Mínima da Textura #4.
- </text>
- <button label="Aplicar" name="apply_btn"/>
-</panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_script_ed.xml b/indra/newview/skins/default/xui/pt/panel_script_ed.xml
index de02aafe2f..39bb5edc75 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_script_ed.xml
+++ b/indra/newview/skins/default/xui/pt/panel_script_ed.xml
@@ -34,6 +34,7 @@
<menu_item_call label="Selecionar tudo" name="Select All"/>
<menu_item_call label="Desmarcar" name="Deselect"/>
<menu_item_call label="Buscar / Substituir..." name="Search / Replace..."/>
+ <menu_item_call label="Ir para a linha..." name="Go to line..."/>
</menu>
<menu label="Ajuda" name="Help">
<menu_item_call label="ajuda..." name="Help..."/>
diff --git a/indra/newview/skins/default/xui/pt/panel_script_limits_my_avatar.xml b/indra/newview/skins/default/xui/pt/panel_script_limits_my_avatar.xml
index daf87c4dc6..daf87c4dc6 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_script_limits_my_avatar.xml
+++ b/indra/newview/skins/default/xui/pt/panel_script_limits_my_avatar.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_script_limits_region_memory.xml b/indra/newview/skins/default/xui/pt/panel_script_limits_region_memory.xml
index 94274b2cfe..94274b2cfe 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_script_limits_region_memory.xml
+++ b/indra/newview/skins/default/xui/pt/panel_script_limits_region_memory.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_script_question_toast.xml b/indra/newview/skins/default/xui/pt/panel_script_question_toast.xml
new file mode 100755
index 0000000000..a2d0237da0
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/panel_script_question_toast.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<panel label="script_question_panel" name="panel_script_question_toast">
+ <panel label="buttons_panel" name="buttons_panel"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_scrolling_param.xml b/indra/newview/skins/default/xui/pt/panel_scrolling_param.xml
index 87e6d16056..87e6d16056 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_scrolling_param.xml
+++ b/indra/newview/skins/default/xui/pt/panel_scrolling_param.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_scrolling_param_base.xml b/indra/newview/skins/default/xui/pt/panel_scrolling_param_base.xml
index 0a5a2e2572..0a5a2e2572 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_scrolling_param_base.xml
+++ b/indra/newview/skins/default/xui/pt/panel_scrolling_param_base.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_side_tray.xml b/indra/newview/skins/default/xui/pt/panel_side_tray.xml
deleted file mode 100644
index 1a424fb7f1..0000000000
--- a/indra/newview/skins/default/xui/pt/panel_side_tray.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<!-- Side tray cannot show background because it is always
- partially on screen to hold tab buttons. -->
-<side_tray name="sidebar">
- <sidetray_tab description="Exibir ou não barra lateral" name="sidebar_openclose" tab_title="Exibir ou não barra lateral"/>
- <sidetray_tab description="Início" name="sidebar_home" tab_title="Início">
- <panel label="Início" name="panel_home"/>
- </sidetray_tab>
- <sidetray_tab description="Edite seu perfil público e destaques." name="sidebar_me" tab_title="Meu perfil">
- <panel_container name="panel_container">
- <panel label="Eu" name="panel_me"/>
- </panel_container>
- </sidetray_tab>
- <sidetray_tab description="Encontre seus amigos, contatos e pessoas nas proximidades." name="sidebar_people" tab_title="Pessoas">
- <panel_container name="panel_container">
- <panel label="Perfil do grupo" name="panel_group_info_sidetray"/>
- <panel label="Residentes&amp; Objetos bloqueados" name="panel_block_list_sidetray"/>
- </panel_container>
- </sidetray_tab>
- <sidetray_tab description="Encontre lugares para ir e lugares que você ja visitou." label="Lugares" name="sidebar_places" tab_title="Lugares">
- <panel label="Lugares" name="panel_places"/>
- </sidetray_tab>
- <sidetray_tab description="Abra seu inventário." name="sidebar_inventory" tab_title="Meu inventário">
- <panel label="Editar inventário" name="sidepanel_inventory"/>
- </sidetray_tab>
- <sidetray_tab description="Muda sua aparência e seu visual atual." name="sidebar_appearance" tab_title="Minha aparência">
- <panel label="Editar aparência" name="sidepanel_appearance"/>
- </sidetray_tab>
-</side_tray>
diff --git a/indra/newview/skins/default/xui/pt/panel_side_tray_tab_caption.xml b/indra/newview/skins/default/xui/pt/panel_side_tray_tab_caption.xml
index 09444a5535..09444a5535 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_side_tray_tab_caption.xml
+++ b/indra/newview/skins/default/xui/pt/panel_side_tray_tab_caption.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_snapshot_inventory.xml b/indra/newview/skins/default/xui/pt/panel_snapshot_inventory.xml
index 3c4bb18687..3c4bb18687 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_snapshot_inventory.xml
+++ b/indra/newview/skins/default/xui/pt/panel_snapshot_inventory.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_snapshot_local.xml b/indra/newview/skins/default/xui/pt/panel_snapshot_local.xml
index 36b5b0cbe6..36b5b0cbe6 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_snapshot_local.xml
+++ b/indra/newview/skins/default/xui/pt/panel_snapshot_local.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_snapshot_options.xml b/indra/newview/skins/default/xui/pt/panel_snapshot_options.xml
index 7f1452e992..7f1452e992 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_snapshot_options.xml
+++ b/indra/newview/skins/default/xui/pt/panel_snapshot_options.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_snapshot_postcard.xml b/indra/newview/skins/default/xui/pt/panel_snapshot_postcard.xml
index 12a648f600..12a648f600 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_snapshot_postcard.xml
+++ b/indra/newview/skins/default/xui/pt/panel_snapshot_postcard.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_snapshot_profile.xml b/indra/newview/skins/default/xui/pt/panel_snapshot_profile.xml
index 095b8fc75d..095b8fc75d 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_snapshot_profile.xml
+++ b/indra/newview/skins/default/xui/pt/panel_snapshot_profile.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_sound_devices.xml b/indra/newview/skins/default/xui/pt/panel_sound_devices.xml
index 66db89f48f..66db89f48f 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_sound_devices.xml
+++ b/indra/newview/skins/default/xui/pt/panel_sound_devices.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_stand_stop_flying.xml b/indra/newview/skins/default/xui/pt/panel_stand_stop_flying.xml
index 05869cf67a..05869cf67a 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_stand_stop_flying.xml
+++ b/indra/newview/skins/default/xui/pt/panel_stand_stop_flying.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_status_bar.xml b/indra/newview/skins/default/xui/pt/panel_status_bar.xml
index cb9a6eb757..cb9a6eb757 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_status_bar.xml
+++ b/indra/newview/skins/default/xui/pt/panel_status_bar.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_teleport_history.xml b/indra/newview/skins/default/xui/pt/panel_teleport_history.xml
index b77064a1ff..b77064a1ff 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_teleport_history.xml
+++ b/indra/newview/skins/default/xui/pt/panel_teleport_history.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_teleport_history_item.xml b/indra/newview/skins/default/xui/pt/panel_teleport_history_item.xml
index 65f80fddd2..65f80fddd2 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_teleport_history_item.xml
+++ b/indra/newview/skins/default/xui/pt/panel_teleport_history_item.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_tools_texture.xml b/indra/newview/skins/default/xui/pt/panel_tools_texture.xml
new file mode 100644
index 0000000000..03da89dd3b
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/panel_tools_texture.xml
@@ -0,0 +1,116 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Textura" name="Texture">
+ <panel.string name="string repeats per meter">
+ Repetições por metro
+ </panel.string>
+ <panel.string name="string repeats per face">
+ Repetições por face
+ </panel.string>
+ <text name="color label">
+ Cor
+ </text>
+ <color_swatch label="" name="colorswatch" tool_tip="Selecionar a cor"/>
+ <text name="color trans">
+ % de transparência
+ </text>
+ <text name="glow label">
+ Brilho
+ </text>
+ <check_box label="Completamente luminoso" name="checkbox fullbright"/>
+ <combo_box name="combobox matmedia">
+ <combo_box.item label="Materiais" name="Materials"/>
+ <combo_box.item label="Mídia" name="Media"/>
+ </combo_box>
+ <combo_box name="combobox mattype">
+ <combo_box.item label="Textura (difusa)" name="Texture (diffuse)"/>
+ <combo_box.item label="Relevo (normal)" name="Bumpiness (normal)"/>
+ <combo_box.item label="Brilho (especular)" name="Shininess (specular)"/>
+ </combo_box>
+ <texture_picker label="Textura" name="texture control" tool_tip="Selecionar imagem"/>
+ <text name="label alphamode">
+ Modo alpha
+ </text>
+ <combo_box name="combobox alphamode">
+ <combo_box.item label="Nenhum" name="None"/>
+ <combo_box.item label="Mistura alpha" name="Alpha blending"/>
+ <combo_box.item label="Máscara alpha" name="Alpha masking"/>
+ <combo_box.item label="Máscara emissiva" name="Emissive mask"/>
+ </combo_box>
+ <text name="label maskcutoff">
+ Corte da máscara
+ </text>
+ <texture_picker label="Textura" name="bumpytexture control" tool_tip="Selecionar imagem"/>
+ <text name="label bumpiness">
+ Relevo
+ </text>
+ <combo_box name="combobox bumpiness">
+ <combo_box.item label="Nenhum" name="None"/>
+ <combo_box.item label="Luminosidade" name="Brightness"/>
+ <combo_box.item label="Escuridão" name="Darkness"/>
+ <combo_box.item label="grão de madeira" name="woodgrain"/>
+ <combo_box.item label="casca de árvore" name="bark"/>
+ <combo_box.item label="tijolos" name="bricks"/>
+ <combo_box.item label="quadriculado" name="checker"/>
+ <combo_box.item label="concreto" name="concrete"/>
+ <combo_box.item label="ladrilho ríspido" name="crustytile"/>
+ <combo_box.item label="pedra talhada" name="cutstone"/>
+ <combo_box.item label="discos" name="discs"/>
+ <combo_box.item label="cascalho" name="gravel"/>
+ <combo_box.item label="placa de petri" name="petridish"/>
+ <combo_box.item label="desvio" name="siding"/>
+ <combo_box.item label="ladrilho de pedra" name="stonetile"/>
+ <combo_box.item label="estuque" name="stucco"/>
+ <combo_box.item label="sucção" name="suction"/>
+ <combo_box.item label="tecelagem" name="weave"/>
+ </combo_box>
+ <texture_picker label="Textura" name="shinytexture control" tool_tip="Selecionar imagem"/>
+ <text name="label shininess">
+ Brilho
+ </text>
+ <combo_box name="combobox shininess">
+ <combo_box.item label="Nenhum" name="None"/>
+ <combo_box.item label="Baixo" name="Low"/>
+ <combo_box.item label="Médio" name="Medium"/>
+ <combo_box.item label="Alto" name="High"/>
+ </combo_box>
+ <text name="label glossiness">
+ Acetinação
+ </text>
+ <text name="label environment">
+ Ambiente
+ </text>
+ <text name="label shinycolor">
+ Cor
+ </text>
+ <color_swatch label="" name="shinycolorswatch" tool_tip="Selecionar a cor"/>
+ <text name="media_info">
+ A URL da mídia escolhida, caso haja, é inserida aqui
+ </text>
+ <button label="Selecionar..." name="add_media" tool_tip="Adicionar mídia"/>
+ <button label="Remover" name="delete_media" tool_tip="Excluir esta textura de mídia"/>
+ <button label="Alinhar" label_selected="Alinhar mídia" name="button align" tool_tip="Alinhar texturas de mídia (após carregar mídia)"/>
+ <text name="tex gen">
+ Mapeamento
+ </text>
+ <combo_box name="combobox texgen">
+ <combo_box.item label="Padrão" name="Default"/>
+ <combo_box.item label="Planar" name="Planar"/>
+ </combo_box>
+ <spinner label="Escala horizontal" name="TexScaleU"/>
+ <spinner label="Escala vertical" name="TexScaleV"/>
+ <spinner label="Repetições por metro" name="rptctrl"/>
+ <spinner label="Graus de rotação" name="TexRot"/>
+ <spinner label="Offset horizontal" name="TexOffsetU"/>
+ <spinner label="Offset vertical" name="TexOffsetV"/>
+ <spinner label="Escala horizontal" name="bumpyScaleU"/>
+ <spinner label="Escala vertical" name="bumpyScaleV"/>
+ <spinner label="Graus de rotação" name="bumpyRot"/>
+ <spinner label="Offset horizontal" name="bumpyOffsetU"/>
+ <spinner label="Offset vertical" name="bumpyOffsetV"/>
+ <spinner label="Escala horizontal" name="shinyScaleU"/>
+ <spinner label="Escala vertical" name="shinyScaleV"/>
+ <spinner label="Graus de rotação" name="shinyRot"/>
+ <spinner label="Offset horizontal" name="shinyOffsetU"/>
+ <spinner label="Offset vertical" name="shinyOffsetV"/>
+ <check_box initial_value="false" label="Alinhar planos planares" name="checkbox planar align" tool_tip="Alinhar texturas de todos os planos selecionados com o plano selecionado por último. Requer mapeamento de textura planar."/>
+</panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_voice_effect.xml b/indra/newview/skins/default/xui/pt/panel_voice_effect.xml
index 1d7878408a..1d7878408a 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_voice_effect.xml
+++ b/indra/newview/skins/default/xui/pt/panel_voice_effect.xml
diff --git a/indra/newview/skins/default/xui/pt/panel_volume_pulldown.xml b/indra/newview/skins/default/xui/pt/panel_volume_pulldown.xml
new file mode 100755
index 0000000000..1dfd2a69ca
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/panel_volume_pulldown.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="volumepulldown_floater">
+ <slider label="Master" name="System Volume"/>
+ <slider label="Botões" name="UI Volume"/>
+ <slider label="Ambiente" name="Wind Volume"/>
+ <slider label="Sons" name="SFX Volume"/>
+ <check_box name="gesture_audio_play_btn" tool_tip="Ativar sons dos gestos"/>
+ <slider label="Música" name="Music Volume"/>
+ <check_box name="enable_music" tool_tip="Ativar streaming de música"/>
+ <slider label="Mídia" name="Media Volume"/>
+ <check_box name="enable_media" tool_tip="Ativar mídia em stream"/>
+ <slider label="Voz" name="Voice Volume"/>
+ <check_box name="enable_voice_check" tool_tip="Ativar bate-papo de voz"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_world_map.xml b/indra/newview/skins/default/xui/pt/panel_world_map.xml
index accab068fd..accab068fd 100644..100755
--- a/indra/newview/skins/default/xui/pt/panel_world_map.xml
+++ b/indra/newview/skins/default/xui/pt/panel_world_map.xml
diff --git a/indra/newview/skins/default/xui/pt/role_actions.xml b/indra/newview/skins/default/xui/pt/role_actions.xml
index 21b085431e..e45a3bd21f 100644..100755
--- a/indra/newview/skins/default/xui/pt/role_actions.xml
+++ b/indra/newview/skins/default/xui/pt/role_actions.xml
@@ -25,7 +25,7 @@
</action_set>
<action_set description="Estas habilidades incluem poderes para mudar o nome da parcelas e configurações de publicação, visibilidade da busca de diretório e ponto de aterrissagem &amp; opções de rota de TP." name="Parcel Identity">
<action description="Alternar &apos;Exibir nos resultados de busca&apos; e selecionar a categoria" longdescription="Alterne entre &apos;Exibir nos resultados de busca&apos; ou não, e selecione a categoria do terreno em &apos;Sobre o terreno&apos;." name="land find places" value="17"/>
- <action description="Mude o nome, a descrição e a exibição do terreno nos resultados de busca." longdescription="Mude o nome, a descrição e a exibição do terreno nos resultados de busca. Veja essas opções em Sobre o terreno &gt; guia Opções." name="land change identity" value="18"/>
+ <action description="Alterar nome da parcela, descrição e configurações de &quot;Conteúdo moderado&quot;" longdescription="Altere o nome da parcela, descrição e configurações de &quot;Conteúdo moderado&quot;. Isso é feito em Sobre o terreno &gt; guia Opções." name="land change identity" value="18"/>
<action description="Definir ponto de aterrissagem e rota de teletransporte" longdescription="Em uma parcela pertencente ao grupo, membros em uma função com esta habilidade podem definir um ponto de aterrissagem para especificar onde os teletransportes chegam e também definir a rota do teletransporte para um maior controle. É feito em Sobre o terreno &gt; aba Opções." name="land set landing point" value="19"/>
</action_set>
<action_set description="Estas habilidade incluem poderes que afetam opções de parcela, como &apos;Criar objetos&apos;, &apos;Editar terreno&apos; e música &amp; configurações de mídia." name="Parcel Settings">
diff --git a/indra/newview/skins/default/xui/pt/sidepanel_appearance.xml b/indra/newview/skins/default/xui/pt/sidepanel_appearance.xml
index a5048e63b2..a5048e63b2 100644..100755
--- a/indra/newview/skins/default/xui/pt/sidepanel_appearance.xml
+++ b/indra/newview/skins/default/xui/pt/sidepanel_appearance.xml
diff --git a/indra/newview/skins/default/xui/pt/sidepanel_inventory.xml b/indra/newview/skins/default/xui/pt/sidepanel_inventory.xml
index 7908ea5f3a..7908ea5f3a 100644..100755
--- a/indra/newview/skins/default/xui/pt/sidepanel_inventory.xml
+++ b/indra/newview/skins/default/xui/pt/sidepanel_inventory.xml
diff --git a/indra/newview/skins/default/xui/pt/sidepanel_item_info.xml b/indra/newview/skins/default/xui/pt/sidepanel_item_info.xml
index e6370ea830..d3cb087108 100644..100755
--- a/indra/newview/skins/default/xui/pt/sidepanel_item_info.xml
+++ b/indra/newview/skins/default/xui/pt/sidepanel_item_info.xml
@@ -3,6 +3,9 @@
<panel.string name="unknown">
(desconhecido)
</panel.string>
+ <panel.string name="unknown_multiple">
+ (desconhecido / múltiplo)
+ </panel.string>
<panel.string name="public">
(público)
</panel.string>
diff --git a/indra/newview/skins/default/xui/pt/sidepanel_task_info.xml b/indra/newview/skins/default/xui/pt/sidepanel_task_info.xml
index 8092e6c145..f0fd438cef 100644..100755
--- a/indra/newview/skins/default/xui/pt/sidepanel_task_info.xml
+++ b/indra/newview/skins/default/xui/pt/sidepanel_task_info.xml
@@ -18,6 +18,12 @@
<panel.string name="text modify info 4">
Você não pode modificar estes objetos
</panel.string>
+ <panel.string name="text modify info 5">
+ Não é possível modificar este objeto através de uma demarcação da região
+ </panel.string>
+ <panel.string name="text modify info 6">
+ Não é possível modificar estes objetos através de uma demarcação da região
+ </panel.string>
<panel.string name="text modify warning">
O objeto contém links ligando suas partes
</panel.string>
@@ -66,6 +72,7 @@
<combo_box.item label="Comprar objeto" name="Buyobject"/>
<combo_box.item label="Pagar por objeto" name="Payobject"/>
<combo_box.item label="Abrir" name="Open"/>
+ <combo_box.item label="Zoom" name="Zoom"/>
</combo_box>
<panel name="perms_inv">
<text name="perm_modify">
@@ -95,6 +102,9 @@
</combo_box>
<spinner label="Preço: L$" name="Edit Cost"/>
<check_box label="Mostrar nos resultados de busca" name="search_check" tool_tip="Incluir o objeto nos resultados de busca"/>
+ <text name="pathfinding_attributes_label">
+ Atributos do pathfinding:
+ </text>
<text name="B:">
B:
</text>
diff --git a/indra/newview/skins/default/xui/pt/strings.xml b/indra/newview/skins/default/xui/pt/strings.xml
index 342a52356b..2eb4c0a02e 100644..100755
--- a/indra/newview/skins/default/xui/pt/strings.xml
+++ b/indra/newview/skins/default/xui/pt/strings.xml
@@ -128,7 +128,10 @@
Sair
</string>
<string name="create_account_url">
- http://join.secondlife.com/index.php?lang=pt-BR
+ http://join.secondlife.com/?sourceid=[sourceid]
+ </string>
+ <string name="ViewerDownloadURL">
+ http://secondlife.com/download
</string>
<string name="LoginFailedViewerNotPermitted">
O visualizador utilizado já não é compatível com o Second Life. Visite a página abaixo para baixar uma versão atual: http://secondlife.com/download
@@ -400,6 +403,9 @@ Pessoas com contas gratuitas não poderão acessar o Second Life no momento para
<string name="SLappAgentRequestFriend">
Pedido de amizade
</string>
+ <string name="SLappAgentRemoveFriend">
+ Remoção de amigo
+ </string>
<string name="BUTTON_CLOSE_DARWIN">
Fechar (⌘W)
</string>
@@ -571,8 +577,8 @@ Pessoas com contas gratuitas não poderão acessar o Second Life no momento para
<string name="AvatarAway">
Distante
</string>
- <string name="AvatarBusy">
- Ocupado
+ <string name="AvatarDoNotDisturb">
+ Não perturbe
</string>
<string name="AvatarMuted">
Mudo
@@ -787,6 +793,9 @@ Pessoas com contas gratuitas não poderão acessar o Second Life no momento para
<string name="multiple_textures">
Múltiplo
</string>
+ <string name="use_texture">
+ Usar textura
+ </string>
<string name="texture_loading">
Carregando...
</string>
@@ -808,6 +817,12 @@ Pessoas com contas gratuitas não poderão acessar o Second Life no momento para
<string name="ST_NO_JOINT">
Não é possível encontrar a raiz (ROOT) ou junção (JOINT).
</string>
+ <string name="NearbyChatTitle">
+ Bate-papo local
+ </string>
+ <string name="NearbyChatLabel">
+ (Bate-papo local)
+ </string>
<string name="whisper">
sussurra:
</string>
@@ -835,6 +850,9 @@ Pessoas com contas gratuitas não poderão acessar o Second Life no momento para
<string name="ScriptQuestionCautionChatDenied">
&apos;[OBJECTNAME]&apos;, um objeto de &apos;[OWNERNAME]&apos;, localizado em [REGIONNAME] a [REGIONPOS], teve permissão negada para: [PERMISSIONS].
</string>
+ <string name="AdditionalPermissionsRequestHeader">
+ Se você permitir acesso à sua conta, o objeto também poderá:
+ </string>
<string name="ScriptTakeMoney">
Tomar linden dólares (L$) de você
</string>
@@ -868,6 +886,27 @@ Pessoas com contas gratuitas não poderão acessar o Second Life no momento para
<string name="ControlYourCamera">
Controle sua camera
</string>
+ <string name="AgentNameSubst">
+ (Você)
+ </string>
+ <string name="TeleportYourAgent">
+ Teletransportá-lo
+ </string>
+ <string name="JoinAnExperience">
+ Participar de uma experiência
+ </string>
+ <string name="SilentlyManageEstateAccess">
+ Suprimir alertas ao gerenciar listas de acesso ao terreno
+ </string>
+ <string name="OverrideYourAnimations">
+ Substituir suas animações padrão
+ </string>
+ <string name="ScriptReturnObjects">
+ Retornar objetos em seu nome
+ </string>
+ <string name="UnknownScriptPermission">
+ (desconhecido)!
+ </string>
<string name="SIM_ACCESS_PG">
Público geral
</string>
@@ -946,17 +985,8 @@ Pessoas com contas gratuitas não poderão acessar o Second Life no momento para
<string name="script_files">
Scripts
</string>
- <string name="AvatarSetNotAway">
- deixar como ausente
- </string>
- <string name="AvatarSetAway">
- deixar como ausente
- </string>
- <string name="AvatarSetNotBusy">
- deixar como não ocupado
- </string>
- <string name="AvatarSetBusy">
- Deixar como ocupado
+ <string name="dictionary_files">
+ Dicionários
</string>
<string name="shape">
Silhueta
@@ -1190,7 +1220,7 @@ Pessoas com contas gratuitas não poderão acessar o Second Life no momento para
https://marketplace.[MARKETPLACE_DOMAIN_NAME]/
</string>
<string name="MarketplaceURL_CreateStore">
- http://community.secondlife.com/t5/English-Knowledge-Base/Selling-in-the-Marketplace/ta-p/700193#Section_.4
+ http://community.secondlife.com/t5/English-Knowledge-Base/Selling-in-the-Marketplace/ta-p/700193#Section_.3
</string>
<string name="MarketplaceURL_Dashboard">
https://marketplace.[MARKETPLACE_DOMAIN_NAME]/merchants/store/dashboard
@@ -1345,6 +1375,12 @@ Pessoas com contas gratuitas não poderão acessar o Second Life no momento para
<string name="InvFolder favorite">
Meus favoritos
</string>
+ <string name="InvFolder Favorites">
+ Meus favoritos
+ </string>
+ <string name="InvFolder favorites">
+ Meus favoritos
+ </string>
<string name="InvFolder Current Outfit">
Look atual
</string>
@@ -1360,6 +1396,12 @@ Pessoas com contas gratuitas não poderão acessar o Second Life no momento para
<string name="InvFolder Meshes">
Meshes:
</string>
+ <string name="InvFolder Received Items">
+ Itens recebidos
+ </string>
+ <string name="InvFolder Merchant Outbox">
+ Caixa de saída do lojista
+ </string>
<string name="InvFolder Friends">
Amigos
</string>
@@ -1890,6 +1932,12 @@ Pessoas com contas gratuitas não poderão acessar o Second Life no momento para
<string name="ATTACH_HUD_BOTTOM_RIGHT">
HUD direito inferior
</string>
+ <string name="ATTACH_NECK">
+ Pescoço
+ </string>
+ <string name="ATTACH_AVATAR_CENTER">
+ Centro do avatar
+ </string>
<string name="CursorPos">
Linha [LINE], Coluna [COLUMN]
</string>
@@ -1902,8 +1950,8 @@ Pessoas com contas gratuitas não poderão acessar o Second Life no momento para
<string name="PanelContentsNewScript">
Novo Script
</string>
- <string name="BusyModeResponseDefault">
- O residente para o qual escreveu está no modo &apos;ocupado&apos;, ou seja, ele prefere não receber nada no momento. Sua mensagem será exibida como uma MI mais tarde.
+ <string name="DoNotDisturbModeResponseDefault">
+ Este residente ativou o &quot;Não perturbe&quot; e verá sua mensagem mais tarde.
</string>
<string name="MuteByName">
(por nome)
@@ -2016,9 +2064,6 @@ Pessoas com contas gratuitas não poderão acessar o Second Life no momento para
<string name="GroupMoneyDate">
[weekday,datetime,utc] [mth,datetime,utc] [day,datetime,utc], [year,datetime,utc]
</string>
- <string name="ViewerObjectContents">
- Conteúdo
- </string>
<string name="AcquiredItems">
Itens adquiridos
</string>
@@ -2879,6 +2924,9 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
<string name="Hip Width">
Largura do quadril
</string>
+ <string name="Hover">
+ Pairar
+ </string>
<string name="In">
Dentro
</string>
@@ -3732,7 +3780,13 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
Região em geral
</string>
<string name="LocationCtrlSeeAVsTooltip">
- Avatar visíveis e bate-papo permitido fora deste terreno
+ Os avatares neste lote não podem ser vistos ou ouvidos por avatares fora dele
+ </string>
+ <string name="LocationCtrlPathfindingDirtyTooltip">
+ Os objetos que se movem podem não se comportar corretamente nesta região até que ela seja recarregada.
+ </string>
+ <string name="LocationCtrlPathfindingDisabledTooltip">
+ O pathfinding dinâmico não está habilitado nesta região.
</string>
<string name="UpdaterWindowTitle">
[APP_NAME] Atualização
@@ -3803,6 +3857,12 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
<string name="IM_unblock_only_groups_friends">
Para visualizar esta mensagem, você deve desmarcar &quot;Apenas amigos e grupos podem me ligar ou enviar MIs&quot; em Preferências/Privacidade.
</string>
+ <string name="OnlineStatus">
+ Conectado
+ </string>
+ <string name="OfflineStatus">
+ Desconectado
+ </string>
<string name="answered_call">
Ligação atendida
</string>
@@ -3812,6 +3872,9 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
<string name="you_joined_call">
Você entrou na ligação
</string>
+ <string name="you_auto_rejected_call-im">
+ Você recusou automaticamente a chamada de voz enquanto &quot;Não perturbe&quot; estava ativado.
+ </string>
<string name="name_started_call">
[NAME] iniciou uma ligação de voz
</string>
@@ -3824,6 +3887,9 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
<string name="hang_up-im">
Saiu da ligação de voz
</string>
+ <string name="conference-title">
+ Bate-papo com várias pessoas
+ </string>
<string name="conference-title-incoming">
Conversa com [AGENT_NAME]
</string>
@@ -4699,6 +4765,9 @@ Tente colocar o caminho do editor entre aspas.
<string name="Command_Chat_Label">
Bate-papo
</string>
+ <string name="Command_Conversations_Label">
+ Conversas
+ </string>
<string name="Command_Compass_Label">
Bússola
</string>
@@ -4774,6 +4843,9 @@ Tente colocar o caminho do editor entre aspas.
<string name="Command_Chat_Tooltip">
Bater papo com pessoas próximas usando texto
</string>
+ <string name="Command_Conversations_Tooltip">
+ Conversar com todos
+ </string>
<string name="Command_Compass_Tooltip">
Bússola
</string>
@@ -4867,6 +4939,21 @@ Tente colocar o caminho do editor entre aspas.
<string name="Normal">
Normal
</string>
+ <string name="Pathfinding_Wiki_URL">
+ http://wiki.secondlife.com/wiki/Pathfinding_Tools_in_the_Second_Life_Viewer
+ </string>
+ <string name="Pathfinding_Object_Attr_None">
+ Nenhum
+ </string>
+ <string name="Pathfinding_Object_Attr_Permanent">
+ Afeta o navmesh
+ </string>
+ <string name="Pathfinding_Object_Attr_Character">
+ Personagem
+ </string>
+ <string name="Pathfinding_Object_Attr_MultiSelect">
+ (Múltiplo)
+ </string>
<string name="snapshot_quality_very_low">
Muito baixo
</string>
@@ -4882,4 +4969,22 @@ Tente colocar o caminho do editor entre aspas.
<string name="snapshot_quality_very_high">
Muito alto
</string>
+ <string name="TeleportMaturityExceeded">
+ O residente não pode visitar a região.
+ </string>
+ <string name="UserDictionary">
+ [Usuário]
+ </string>
+ <string name="logging_calls_disabled_log_empty">
+ As conversas não estão sendo registradas. Para começar a manter um registro, selecione &quot;Salvar: apenas registro&quot; ou &quot;Salvar: registro e transcrições&quot; em Preferências&gt; Bate-papo.
+ </string>
+ <string name="logging_calls_disabled_log_not_empty">
+ Nenhuma conversa será registrada. Para recomeçar a gravação de registros, selecione &quot;Salvar: apenas registro&quot; ou &quot;Salvar: registro e transcrições&quot; em Preferências&gt; Bate-papo.
+ </string>
+ <string name="logging_calls_enabled_log_empty">
+ Não há conversas registradas. Depois que você entrar em contato com alguém, ou alguém entrar em contato com você, um registro será exibido aqui.
+ </string>
+ <string name="loading_chat_logs">
+ Carregando...
+ </string>
</strings>
diff --git a/indra/newview/skins/default/xui/pt/teleport_strings.xml b/indra/newview/skins/default/xui/pt/teleport_strings.xml
index 3fb77a02d2..40fb4caebf 100644..100755
--- a/indra/newview/skins/default/xui/pt/teleport_strings.xml
+++ b/indra/newview/skins/default/xui/pt/teleport_strings.xml
@@ -43,6 +43,9 @@ Vá para a &apos;Ilha Welcome Pública&apos; para repetir o tutorial.
<message name="no_inventory_host">
O sistema de inventário está indisponível no momento.
</message>
+ <message name="MustGetAgeRegion">
+ Você deve ter 18 anos ou mais para acessar esta região.
+ </message>
</message_set>
<message_set name="progress">
<message name="sending_dest">
@@ -78,5 +81,8 @@ Vá para a &apos;Ilha Welcome Pública&apos; para repetir o tutorial.
<message name="requesting">
Solicitando teletransporte...
</message>
+ <message name="pending">
+ Teletransporte pendente...
+ </message>
</message_set>
</teleport_messages>
diff --git a/indra/newview/skins/default/xui/pt/xui_version.xml b/indra/newview/skins/default/xui/pt/xui_version.xml
index 0e777751d3..0e777751d3 100644..100755
--- a/indra/newview/skins/default/xui/pt/xui_version.xml
+++ b/indra/newview/skins/default/xui/pt/xui_version.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_aaa.xml b/indra/newview/skins/default/xui/ru/floater_aaa.xml
index aa18a4a4a3..aa18a4a4a3 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_aaa.xml
+++ b/indra/newview/skins/default/xui/ru/floater_aaa.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_about.xml b/indra/newview/skins/default/xui/ru/floater_about.xml
index 119f104906..9494106e96 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_about.xml
+++ b/indra/newview/skins/default/xui/ru/floater_about.xml
@@ -8,7 +8,9 @@
ИÑпользован компилÑтор [COMPILER], верÑÐ¸Ñ [COMPILER_VERSION]
</floater.string>
<floater.string name="AboutPosition">
- Ð’Ñ‹ в точке [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1] в регионе «[REGION]», раÑположенном на &lt;nolink&gt;[HOSTNAME]&lt;/nolink&gt; ([HOSTIP])
+ Ð’Ñ‹ в точке [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] в регионе «[REGION]», раÑположенном на &lt;nolink&gt;[HOSTNAME]&lt;/nolink&gt; ([HOSTIP])
+SLURL: &lt;nolink&gt;[SLURL]&lt;/nolink&gt;
+(глобальные координаты [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1])
[SERVER_VERSION]
[SERVER_RELEASE_NOTES_URL]
</floater.string>
@@ -62,27 +64,26 @@
</panel>
<panel label="Лицензии" name="licenses_panel">
<text_editor name="credits_editor">
- 3Dconnexion SDK (C) 1992-2007 3Dconnexion
- APR (C) 2000-2004 The Apache Software Foundation
- Collada DOM (C) 2005 Sony Computer Entertainment Inc.
- cURL (C) 1996-2002, Daniel Stenberg, (daniel@haxx.se)
+ 3Dconnexion SDK (C) 1992-2009 3Dconnexion
+ APR (C) 2011 The Apache Software Foundation
+ Collada DOM (C) 2006 Sony Computer Entertainment Inc.
+ cURL (C) 1996-2010, Daniel Stenberg, (daniel@haxx.se)
DBus/dbus-glib (C) 2002, 2003 CodeFactory AB / (C) 2003, 2004 Red Hat, Inc.
expat (C) 1998, 1999, 2000 Thai Open Source Software Center Ltd.
- FreeType (C) 1996-2002, The FreeType Project (www.freetype.org).
+ FreeType (C) 1996-2002, 2006 David Turner, Robert Wilhelm и Werner Lemberg.
GL (C) 1999-2004 Brian Paul.
GLOD (C) 2003-04 Jonathan Cohen, Nat Duca, Chris Niski, УниверÑитет Джона ГопкинÑа и David Luebke, Brenden Schubert, УниверÑитет Вирджинии.
google-perftools (c) 2005, Google Inc.
Havok.com(TM) (C) 1999-2001, Telekinesys Research Limited.
jpeg2000 (C) 2001, David Taubman, УниверÑитет Ðового Южного УÑльÑа (UNSW)
jpeglib (C) 1991-1998, Thomas G. Lane.
- ogg/vorbis (C) 2001, Xiphophorus
- OpenSSL (C) 1998-2002 The OpenSSL Project.
- PCRE (c) 1997-2008, КембриджÑкий универÑитет
+ ogg/vorbis (C) 2002, Xiphophorus
+ OpenSSL (C) 1998-2008 The OpenSSL Project.
+ PCRE (c) 1997-2012, КембриджÑкий универÑитет
SDL (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga
SSLeay (C) 1995-1998 Eric Young (eay@cryptsoft.com)
xmlrpc-epi (C) 2000 Epinions, Inc.
- zlib (C) 1995-2002 Jean-loup Gailly и Mark Adler.
- google-perftools (c) 2005, Google Inc.
+ zlib (C) 1995-2012 Jean-loup Gailly и Mark Adler.
Ð’ клиенте Second Life иÑпользуетÑÑ Ñ‚ÐµÑ…Ð½Ð¾Ð»Ð¾Ð³Ð¸Ñ Havok (TM) Physics. (C) 1999-2010 Havok.com Inc. (и лицензиары компании). Ð’Ñе права защищены. Подробнее Ñм. веб-Ñайт www.havok.com.
diff --git a/indra/newview/skins/default/xui/ru/floater_about_land.xml b/indra/newview/skins/default/xui/ru/floater_about_land.xml
index ee74aad5cc..12691df684 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/ru/floater_about_land.xml
@@ -451,7 +451,7 @@
Разрешить доÑтуп только таким жителÑм:
</text>
<check_box label="ЗарегиÑтрирована Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾Ð± оплате [ESTATE_PAYMENT_LIMIT]" name="limit_payment" tool_tip="Ð”Ð»Ñ Ð´Ð¾Ñтупа к Ñтому учаÑтку у Ð¶Ð¸Ñ‚ÐµÐ»Ñ Ð´Ð¾Ð»Ð¶Ð½Ð° быть зарегиÑтрирована Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾Ð± оплате. Более Ð¿Ð¾Ð´Ñ€Ð¾Ð±Ð½Ð°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð½Ð°Ñ…Ð¾Ð´Ð¸Ñ‚ÑÑ Ð·Ð´ÐµÑÑŒ: [SUPPORT_SITE]."/>
- <check_box label="Подтвержден возраÑÑ‚ [ESTATE_AGE_LIMIT]" name="limit_age_verified" tool_tip="Ð”Ð»Ñ Ð´Ð¾Ñтупа к Ñтому учаÑтку житель должен подтвердить Ñвой возраÑÑ‚. Более Ð¿Ð¾Ð´Ñ€Ð¾Ð±Ð½Ð°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð½Ð°Ñ…Ð¾Ð´Ð¸Ñ‚ÑÑ Ð·Ð´ÐµÑÑŒ: [SUPPORT_SITE]."/>
+ <check_box label="18 лет и Ñтарше [ESTATE_AGE_LIMIT]" name="limit_age_verified" tool_tip="ДоÑтуп к Ñтому учаÑтку имеют только жители 18 лет и Ñтарше. Более Ð¿Ð¾Ð´Ñ€Ð¾Ð±Ð½Ð°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð½Ð°Ñ…Ð¾Ð´Ð¸Ñ‚ÑÑ Ð·Ð´ÐµÑÑŒ: [SUPPORT_SITE]."/>
<check_box label="Разрешить доÑтуп группе: [GROUP]" name="GroupCheck" tool_tip="Группа уÑтанавливаетÑÑ Ð½Ð° оÑновной вкладке."/>
<check_box label="Продать доÑтуп:" name="PassCheck" tool_tip="Разрешить временный доÑтуп к учаÑтку."/>
<combo_box name="pass_combo">
diff --git a/indra/newview/skins/default/xui/ru/floater_activeim.xml b/indra/newview/skins/default/xui/ru/floater_activeim.xml
index adfa277822..adfa277822 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_activeim.xml
+++ b/indra/newview/skins/default/xui/ru/floater_activeim.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_animation_anim_preview.xml b/indra/newview/skins/default/xui/ru/floater_animation_anim_preview.xml
index 711afc2717..711afc2717 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_animation_anim_preview.xml
+++ b/indra/newview/skins/default/xui/ru/floater_animation_anim_preview.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_animation_bvh_preview.xml b/indra/newview/skins/default/xui/ru/floater_animation_bvh_preview.xml
index 8ad9d8657a..8ad9d8657a 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_animation_bvh_preview.xml
+++ b/indra/newview/skins/default/xui/ru/floater_animation_bvh_preview.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_animation_preview.xml b/indra/newview/skins/default/xui/ru/floater_animation_preview.xml
deleted file mode 100644
index b7075fbf97..0000000000
--- a/indra/newview/skins/default/xui/ru/floater_animation_preview.xml
+++ /dev/null
@@ -1,183 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Animation Preview">
- <floater.string name="failed_to_initialize">
- Ðевозможно инициализировать движение
- </floater.string>
- <floater.string name="anim_too_long">
- Длина файла анимации: [LENGTH] Ñ.
-МакÑÐ¸Ð¼Ð°Ð»ÑŒÐ½Ð°Ñ Ð´Ð»Ð¸Ð½Ð° анимации: [MAX_LENGTH] Ñ.
- </floater.string>
- <floater.string name="failed_file_read">
- Ðевозможно прочитать файл анимации.
-[STATUS]
- </floater.string>
- <floater.string name="E_ST_OK">
- ОК
- </floater.string>
- <floater.string name="E_ST_EOF">
- Преждевременный конец файла.
- </floater.string>
- <floater.string name="E_ST_NO_CONSTRAINT">
- Ðе могу прочитать определение ограничений.
- </floater.string>
- <floater.string name="E_ST_NO_FILE">
- Ðе удалоÑÑŒ открыть BVH-файл.
- </floater.string>
- <floater.string name="E_ST_NO_HIER">
- Ðеправильный заголовок HIERARCHY.
- </floater.string>
- <floater.string name="E_ST_NO_JOINT">
- Ðе удалоÑÑŒ найти ROOT или JOINT.
- </floater.string>
- <floater.string name="E_ST_NO_NAME">
- Ðе удалоÑÑŒ получить Ð¸Ð¼Ñ JOINT.
- </floater.string>
- <floater.string name="E_ST_NO_OFFSET">
- Ðе удалоÑÑŒ найти OFFSET.
- </floater.string>
- <floater.string name="E_ST_NO_CHANNELS">
- Ðе удалоÑÑŒ найти CHANNELS.
- </floater.string>
- <floater.string name="E_ST_NO_ROTATION">
- Ðе удалоÑÑŒ получить порÑдок вращениÑ.
- </floater.string>
- <floater.string name="E_ST_NO_AXIS">
- Ðе удалоÑÑŒ получить оÑи вращениÑ.
- </floater.string>
- <floater.string name="E_ST_NO_MOTION">
- Ðе удалоÑÑŒ найти MOTION.
- </floater.string>
- <floater.string name="E_ST_NO_FRAMES">
- Ðе удалоÑÑŒ получить количеÑтво кадров.
- </floater.string>
- <floater.string name="E_ST_NO_FRAME_TIME">
- Ðе удалоÑÑŒ получить Ð²Ñ€ÐµÐ¼Ñ ÐºÐ°Ð´Ñ€Ð°.
- </floater.string>
- <floater.string name="E_ST_NO_POS">
- Ðе удалоÑÑŒ получить Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ position.
- </floater.string>
- <floater.string name="E_ST_NO_ROT">
- Ðе удалоÑÑŒ получить Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ rotation.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_FILE">
- Ðе удалоÑÑŒ открыть файл перевода.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_HEADER">
- Ðе удалоÑÑŒ прочитать заголовок перевода.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_NAME">
- Ðе удалоÑÑŒ прочитать имена перевода.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_IGNORE">
- Ðе удалоÑÑŒ прочитать значение перевода ignore.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_RELATIVE">
- Ðе удалоÑÑŒ прочитать значение перевода relative.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_OUTNAME">
- Ðе удалоÑÑŒ прочитать значение перевода outname.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_MATRIX">
- Ðе удалоÑÑŒ прочитать матрицу перевода.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_MERGECHILD">
- Ðе удалоÑÑŒ получить Ð¸Ð¼Ñ mergechild.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_MERGEPARENT">
- Ðе удалоÑÑŒ получить Ð¸Ð¼Ñ mergeparent.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_PRIORITY">
- Ðе удалоÑÑŒ получить значение priority.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_LOOP">
- Ðе удалоÑÑŒ получить значение loop.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_EASEIN">
- Ðе удалоÑÑŒ получить Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ easeIn.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_EASEOUT">
- Ðе удалоÑÑŒ получить Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ easeOut.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_HAND">
- Ðе удалоÑÑŒ получить значение hand morph.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_EMOTE">
- Ðе удалоÑÑŒ прочитать Ð¸Ð¼Ñ emote.
- </floater.string>
- <floater.string name="E_ST_BAD_ROOT">
- Ðеверное Ð¸Ð¼Ñ ÐºÐ¾Ñ€Ð½ÐµÐ²Ð¾Ð³Ð¾ ÑоединениÑ, должно быть «hip».
- </floater.string>
- <text name="name_label">
- Ðазвание:
- </text>
- <text name="description_label">
- ОпиÑание:
- </text>
- <spinner label="Приоритет" name="priority" tool_tip="УправлÑет тем, как другие анимации могут перекрыватьÑÑ Ñтой"/>
- <check_box label="Цикл" name="loop_check" tool_tip="Делает анимацию зацикленной"/>
- <spinner label="Ðачало(%)" name="loop_in_point" tool_tip="УÑтанавливает точку возврата цикла"/>
- <spinner label="Конец(%)" name="loop_out_point" tool_tip="УÑтанавливает точку конца цикла"/>
- <text name="hand_label">
- Положение пальцев
- </text>
- <combo_box name="hand_pose_combo" tool_tip="Контролирует положение пальцев во Ð²Ñ€ÐµÐ¼Ñ Ð°Ð½Ð¸Ð¼Ð°Ñ†Ð¸Ð¸">
- <combo_box.item label="Разведены" name="Spread"/>
- <combo_box.item label="РаÑÑлаблены" name="Relaxed"/>
- <combo_box.item label="Указывают" name="PointBoth"/>
- <combo_box.item label="Сжаты в кулаки" name="Fist"/>
- <combo_box.item label="Левые раÑÑлаблены" name="RelaxedLeft"/>
- <combo_box.item label="Левые указывают" name="PointLeft"/>
- <combo_box.item label="Левые в кулак" name="FistLeft"/>
- <combo_box.item label="Правые раÑÑлаблены" name="RelaxedRight"/>
- <combo_box.item label="Правые указывают" name="PointRight"/>
- <combo_box.item label="Правые в кулак" name="FistRight"/>
- <combo_box.item label="Правые в приветÑтвии" name="SaluteRight"/>
- <combo_box.item label="Печатают" name="Typing"/>
- <combo_box.item label="Правые «V»" name="PeaceRight"/>
- </combo_box>
- <text name="emote_label">
- Выражение лица
- </text>
- <combo_box name="emote_combo" tool_tip="Контролирует выражение лица во Ð²Ñ€ÐµÐ¼Ñ Ð°Ð½Ð¸Ð¼Ð°Ñ†Ð¸Ð¸">
- <item label="(нет)" name="[None]" value=""/>
- <item label="Ðаааах" name="Aaaaah" value="Ðаааах"/>
- <item label="БоитÑÑ" name="Afraid" value="БоитÑÑ"/>
- <item label="ЗлитÑÑ" name="Angry" value="ЗлитÑÑ"/>
- <item label="Широко улыбаетÑÑ" name="BigSmile" value="Широко улыбаетÑÑ"/>
- <item label="Скучает" name="Bored" value="Скучает"/>
- <item label="Плачет" name="Cry" value="Плачет"/>
- <item label="Презирает" name="Disdain" value="Презирает"/>
- <item label="СмущаетÑÑ" name="Embarrassed" value="СмущаетÑÑ"/>
- <item label="ХмуритÑÑ" name="Frown" value="ХмуритÑÑ"/>
- <item label="Целует" name="Kiss" value="Целует"/>
- <item label="СмеетÑÑ" name="Laugh" value="СмеетÑÑ"/>
- <item label="ДразнитÑÑ" name="Plllppt" value="ДразнитÑÑ"/>
- <item label="Ðе ÑоглашаетÑÑ" name="Repulsed" value="Ðе ÑоглашаетÑÑ"/>
- <item label="ГруÑтит" name="Sad" value="ГруÑтит"/>
- <item label="Ðе понимает" name="Shrug" value="Ðе понимает"/>
- <item label="УлыбаетÑÑ" name="Smile" value="УлыбаетÑÑ"/>
- <item label="УдивлÑетÑÑ" name="Surprise" value="УдивлÑетÑÑ"/>
- <item label="Подмигивает" name="Wink" value="Подмигивает"/>
- <item label="БеÑпокоитÑÑ" name="Worry" value="БеÑпокоитÑÑ"/>
- </combo_box>
- <text name="preview_label">
- ПроÑмотр во времÑ
- </text>
- <combo_box name="preview_base_anim" tool_tip="ПроÑмотр вашей анимации во Ð²Ñ€ÐµÐ¼Ñ Ð²Ñ‹Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð°Ð²Ð°Ñ‚Ð°Ñ€Ð¾Ð¼ дейÑтвий.">
- <item label="СтоÑние" name="Standing" value="СтоÑние"/>
- <item label="Ходьба" name="Walking" value="Ходьба"/>
- <item label="Сидение" name="Sitting" value="Сидение"/>
- <item label="Полет" name="Flying" value="Полет"/>
- </combo_box>
- <spinner label="Вход (Ñек.)" name="ease_in_time" tool_tip="КоличеÑтво времени (в Ñекундах) Ð´Ð»Ñ Ð²Ñ…Ð¾Ð´Ð° в Ñтартовое положение"/>
- <spinner label="Выход (Ñек.)" name="ease_out_time" tool_tip="КоличеÑтво времени (в Ñекундах) Ð´Ð»Ñ Ð²Ñ‹Ñ…Ð¾Ð´Ð° из анимации"/>
- <button name="play_btn" tool_tip="Проиграть анимацию"/>
- <button name="pause_btn" tool_tip="ПриоÑтановить анимацию"/>
- <button name="stop_btn" tool_tip="ОÑтановить проигрывание анимации"/>
- <text name="bad_animation_text">
- Ðевозможно прочитать файл анимации.
-РекомендуетÑÑ Ð¸Ñпользовать BVH-файлы, ÑкÑпортированные из Poser 4.
- </text>
- <button label="Передать (L$[AMOUNT])" name="ok_btn"/>
- <button label="Отмена" name="cancel_btn"/>
-</floater>
diff --git a/indra/newview/skins/default/xui/ru/floater_auction.xml b/indra/newview/skins/default/xui/ru/floater_auction.xml
index d84dc2e941..105c75c919 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_auction.xml
+++ b/indra/newview/skins/default/xui/ru/floater_auction.xml
@@ -3,7 +3,7 @@
<floater.string name="already for sale">
ÐÐµÐ»ÑŒÐ·Ñ Ð²Ñ‹Ñтавить на аукцион учаÑтки, которые уже продаютÑÑ.
</floater.string>
- <check_box initial_value="иÑтина" label="Ð’ÐºÐ»ÑŽÑ‡Ð°Ñ Ð¶ÐµÐ»Ñ‚ÑƒÑŽ ограду вокруг выбранного учаÑтка" name="fence_check"/>
+ <check_box initial_value="true" label="Ð’ÐºÐ»ÑŽÑ‡Ð°Ñ Ð¶ÐµÐ»Ñ‚ÑƒÑŽ ограду вокруг выбранного учаÑтка" name="fence_check"/>
<button label="Снимок" label_selected="Снимок" name="snapshot_btn"/>
<button label="Купить может каждый" label_selected="Купить может каждый" name="sell_to_anyone_btn"/>
<button label="ОчиÑтить наÑтройки" label_selected="ОчиÑтить наÑтройки" name="reset_parcel_btn"/>
diff --git a/indra/newview/skins/default/xui/ru/floater_autoreplace.xml b/indra/newview/skins/default/xui/ru/floater_autoreplace.xml
new file mode 100755
index 0000000000..6827931e5d
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/floater_autoreplace.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="autoreplace_floater" title="ÐаÑтройки автозамены">
+ <check_box label="Включить автозамену" name="autoreplace_enable" tool_tip="Ð’ чате по мере ввода текÑта ключевые Ñлова будут заменÑÑ‚ÑŒÑÑ ÑоответÑтвующими заменителÑми"/>
+ <button label="Импорт ÑпиÑка..." name="autoreplace_import_list" tool_tip="Загрузить ранее ÑкÑпортированный ÑпиÑок из файла."/>
+ <button label="ЭкÑпорт ÑпиÑка..." name="autoreplace_export_list" tool_tip="Сохранить выбранный ÑпиÑок в файл Ð´Ð»Ñ Ð¿Ð¾Ñледующего раÑпроÑтранениÑ."/>
+ <button label="Ðовый ÑпиÑок..." name="autoreplace_new_list" tool_tip="Создать новый ÑпиÑок."/>
+ <button label="Удалить ÑпиÑок" name="autoreplace_delete_list" tool_tip="Удалить выбранный ÑпиÑок."/>
+ <button name="autoreplace_list_up" tool_tip="ПовыÑить приоритет ÑпиÑка."/>
+ <button name="autoreplace_list_down" tool_tip="Понизить приоритет ÑпиÑка."/>
+ <scroll_list name="autoreplace_list_replacements">
+ <scroll_list.columns label="Ключевое Ñлово" name="keyword"/>
+ <scroll_list.columns label="Замена" name="replacement"/>
+ </scroll_list>
+ <button label="Добавить..." name="autoreplace_add_entry"/>
+ <button label="Удалить" name="autoreplace_delete_entry"/>
+ <button label="Сохранить запиÑÑŒ" name="autoreplace_save_entry" tool_tip="Сохранить Ñту запиÑÑŒ."/>
+ <button label="Сохранить изменениÑ" name="autoreplace_save_changes" tool_tip="Сохранить вÑе изменениÑ."/>
+ <button label="Отмена" name="autoreplace_cancel" tool_tip="Отменить вÑе изменениÑ."/>
+</floater>
+<!--
+ <text
+ top_pad="10"
+ left="10"
+ height="16"
+ width="260"
+ follows="left|top"
+ halign="center"
+ mouse_opaque="true"
+ name="autoreplace_text2">
+ Entries
+ </text>
+-->
diff --git a/indra/newview/skins/default/xui/ru/floater_avatar.xml b/indra/newview/skins/default/xui/ru/floater_avatar.xml
index b480af9345..b480af9345 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_avatar.xml
+++ b/indra/newview/skins/default/xui/ru/floater_avatar.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_avatar_picker.xml b/indra/newview/skins/default/xui/ru/floater_avatar_picker.xml
index edcc35d2b9..edcc35d2b9 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_avatar_picker.xml
+++ b/indra/newview/skins/default/xui/ru/floater_avatar_picker.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_avatar_textures.xml b/indra/newview/skins/default/xui/ru/floater_avatar_textures.xml
index cb39f66247..cb39f66247 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_avatar_textures.xml
+++ b/indra/newview/skins/default/xui/ru/floater_avatar_textures.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_beacons.xml b/indra/newview/skins/default/xui/ru/floater_beacons.xml
index 38d257ff81..38d257ff81 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_beacons.xml
+++ b/indra/newview/skins/default/xui/ru/floater_beacons.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_build_options.xml b/indra/newview/skins/default/xui/ru/floater_build_options.xml
index 9dd01dc823..9dd01dc823 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_build_options.xml
+++ b/indra/newview/skins/default/xui/ru/floater_build_options.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_bulk_perms.xml b/indra/newview/skins/default/xui/ru/floater_bulk_perms.xml
index ccf13cf02a..304bf97dc1 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_bulk_perms.xml
+++ b/indra/newview/skins/default/xui/ru/floater_bulk_perms.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floaterbulkperms" title="ИЗМЕÐИТЬ РÐЗРЕШЕÐИЯ ÐРИСПОЛЬЗОВÐÐИЕ КОÐТЕÐТÐ">
+<floater name="floaterbulkperms" title="ÐÐСТРОИТЬ РÐЗРЕШЕÐИЯ ÐРИСПОЛЬЗОВÐÐИЕ КОÐТЕÐТÐ">
<floater.string name="nothing_to_modify_text">
Ð’ выбранной облаÑти нет контента, который можно изменÑÑ‚ÑŒ.
</floater.string>
@@ -24,7 +24,7 @@
<button label="√ Ð’Ñе" name="check_all"/>
<button label="ОчиÑтить" label_selected="Ðет" name="check_none"/>
<text name="newperms">
- Ðовые Ñ€Ð°Ð·Ñ€ÐµÑˆÐµÐ½Ð¸Ñ Ð½Ð° контент
+ ÐаÑтроить Ñ€Ð°Ð·Ñ€ÐµÑˆÐµÐ½Ð¸Ñ Ð½Ð° иÑпользование контента:
</text>
<text name="GroupLabel">
Группа:
@@ -39,7 +39,8 @@
</text>
<check_box label="ИзменÑÑ‚ÑŒ" name="next_owner_modify"/>
<check_box label="Копировать" name="next_owner_copy"/>
- <check_box initial_value="иÑтина" label="Передать" name="next_owner_transfer" tool_tip="Следующий владелец может отдать или перепродать объект"/>
- <button label="ОК" name="apply"/>
+ <check_box initial_value="true" label="Передать" name="next_owner_transfer" tool_tip="Следующий владелец может отдать или перепродать объект"/>
+ <button label="OK" name="ok"/>
+ <button label="Применить" name="apply"/>
<button label="Отмена" name="close"/>
</floater>
diff --git a/indra/newview/skins/default/xui/ru/floater_bumps.xml b/indra/newview/skins/default/xui/ru/floater_bumps.xml
index f81f728290..f81f728290 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_bumps.xml
+++ b/indra/newview/skins/default/xui/ru/floater_bumps.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_buy_contents.xml b/indra/newview/skins/default/xui/ru/floater_buy_contents.xml
index b1d66ae14d..b1d66ae14d 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_buy_contents.xml
+++ b/indra/newview/skins/default/xui/ru/floater_buy_contents.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_buy_currency.xml b/indra/newview/skins/default/xui/ru/floater_buy_currency.xml
index 87e8bd524e..87e8bd524e 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_buy_currency.xml
+++ b/indra/newview/skins/default/xui/ru/floater_buy_currency.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_buy_currency_html.xml b/indra/newview/skins/default/xui/ru/floater_buy_currency_html.xml
index ac8ad469fb..ac8ad469fb 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_buy_currency_html.xml
+++ b/indra/newview/skins/default/xui/ru/floater_buy_currency_html.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_buy_land.xml b/indra/newview/skins/default/xui/ru/floater_buy_land.xml
index 907a795393..907a795393 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_buy_land.xml
+++ b/indra/newview/skins/default/xui/ru/floater_buy_land.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_buy_object.xml b/indra/newview/skins/default/xui/ru/floater_buy_object.xml
index d25f9eccc2..d25f9eccc2 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_buy_object.xml
+++ b/indra/newview/skins/default/xui/ru/floater_buy_object.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_camera.xml b/indra/newview/skins/default/xui/ru/floater_camera.xml
index 52e7c62e06..52e7c62e06 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_camera.xml
+++ b/indra/newview/skins/default/xui/ru/floater_camera.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_chat_bar.xml b/indra/newview/skins/default/xui/ru/floater_chat_bar.xml
index 79b7b033fb..f6b2fc81e1 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_chat_bar.xml
+++ b/indra/newview/skins/default/xui/ru/floater_chat_bar.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="chat_bar" title="ЛОКÐЛЬÐЫЙ ЧÐТ">
+<floater name="nearby_chat" title="ЛОКÐЛЬÐЫЙ ЧÐТ">
<panel name="bottom_panel">
<line_editor label="Щелкните здеÑÑŒ Ð´Ð»Ñ Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ." name="chat_box" tool_tip="Ðажмите Enter, чтобы Ñказать, Ctrl+Enter, чтобы прокричать"/>
<button name="show_nearby_chat" tool_tip="Показать/Ñкрыть лог локального чата"/>
diff --git a/indra/newview/skins/default/xui/ru/floater_choose_group.xml b/indra/newview/skins/default/xui/ru/floater_choose_group.xml
index ab8350f539..ab8350f539 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_choose_group.xml
+++ b/indra/newview/skins/default/xui/ru/floater_choose_group.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_color_picker.xml b/indra/newview/skins/default/xui/ru/floater_color_picker.xml
index b7034bef0b..b7034bef0b 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_color_picker.xml
+++ b/indra/newview/skins/default/xui/ru/floater_color_picker.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_conversation_log.xml b/indra/newview/skins/default/xui/ru/floater_conversation_log.xml
new file mode 100644
index 0000000000..090ac7193a
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/floater_conversation_log.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="floater_conversation_log" title="ЖУРÐÐЛ РÐЗГОВОРÐ">
+ <panel name="buttons_panel">
+ <filter_editor label="Фильтр Ð´Ð»Ñ Ð»ÑŽÐ´ÐµÐ¹" name="people_filter_input"/>
+ <menu_button name="conversation_view_btn" tool_tip="Параметры проÑмотра/Ñортировки"/>
+ <menu_button name="conversations_gear_btn" tool_tip="ДейÑÑ‚Ð²Ð¸Ñ Ñ Ð²Ñ‹Ð±Ñ€Ð°Ð½Ð½Ñ‹Ð¼ жителем или группой"/>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/ru/floater_conversation_preview.xml b/indra/newview/skins/default/xui/ru/floater_conversation_preview.xml
new file mode 100644
index 0000000000..23225fcf56
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/floater_conversation_preview.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="preview_conversation" title="РÐЗГОВОР:">
+ <floater.string name="Title">
+ РÐЗГОВОР: [NAME]
+ </floater.string>
+ <text name="page_label" value="Страница"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/ru/floater_critical.xml b/indra/newview/skins/default/xui/ru/floater_critical.xml
index bc64f3a83e..bc64f3a83e 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_critical.xml
+++ b/indra/newview/skins/default/xui/ru/floater_critical.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_delete_env_preset.xml b/indra/newview/skins/default/xui/ru/floater_delete_env_preset.xml
index 3303a4f4c1..3303a4f4c1 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_delete_env_preset.xml
+++ b/indra/newview/skins/default/xui/ru/floater_delete_env_preset.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_destinations.xml b/indra/newview/skins/default/xui/ru/floater_destinations.xml
index 5ba0841564..5ba0841564 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_destinations.xml
+++ b/indra/newview/skins/default/xui/ru/floater_destinations.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_display_name.xml b/indra/newview/skins/default/xui/ru/floater_display_name.xml
index feb8a2721f..feb8a2721f 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_display_name.xml
+++ b/indra/newview/skins/default/xui/ru/floater_display_name.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_edit_day_cycle.xml b/indra/newview/skins/default/xui/ru/floater_edit_day_cycle.xml
index 61d708c567..61d708c567 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_edit_day_cycle.xml
+++ b/indra/newview/skins/default/xui/ru/floater_edit_day_cycle.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_edit_sky_preset.xml b/indra/newview/skins/default/xui/ru/floater_edit_sky_preset.xml
index 354120ea72..354120ea72 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_edit_sky_preset.xml
+++ b/indra/newview/skins/default/xui/ru/floater_edit_sky_preset.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_edit_water_preset.xml b/indra/newview/skins/default/xui/ru/floater_edit_water_preset.xml
index f6def86380..f6def86380 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_edit_water_preset.xml
+++ b/indra/newview/skins/default/xui/ru/floater_edit_water_preset.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_env_settings.xml b/indra/newview/skins/default/xui/ru/floater_env_settings.xml
deleted file mode 100644
index a3e77d61de..0000000000
--- a/indra/newview/skins/default/xui/ru/floater_env_settings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Environment Editor Floater" title="РЕДÐКТОР СРЕДЫ">
- <floater.string name="timeStr">
- [hour,datetime,utc]:[min,datetime,utc]
- </floater.string>
- <text name="EnvTimeText">
- Ð’Ñ€ÐµÐ¼Ñ Ñуток
- </text>
- <text name="EnvTimeText2">
- 12:00
- </text>
- <text name="EnvCloudText">
- ОблачноÑÑ‚ÑŒ
- </text>
- <text name="EnvWaterColorText">
- Цвет воды
- </text>
- <color_swatch name="EnvWaterColor" tool_tip="Щелкните Ð´Ð»Ñ Ð²Ñ‹Ð±Ð¾Ñ€Ð° цвета"/>
- <text name="EnvWaterFogText">
- Водный туман
- </text>
- <button label="ИÑпользовать Ð²Ñ€ÐµÐ¼Ñ Ð² землевладении" name="EnvUseEstateTimeButton"/>
- <button label="Улучшенное небо" name="EnvAdvancedSkyButton"/>
- <button label="Ð£Ð»ÑƒÑ‡ÑˆÐµÐ½Ð½Ð°Ñ Ð²Ð¾Ð´Ð°" name="EnvAdvancedWaterButton"/>
-</floater>
diff --git a/indra/newview/skins/default/xui/ru/floater_environment_settings.xml b/indra/newview/skins/default/xui/ru/floater_environment_settings.xml
index d752c08cbb..d752c08cbb 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_environment_settings.xml
+++ b/indra/newview/skins/default/xui/ru/floater_environment_settings.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_event.xml b/indra/newview/skins/default/xui/ru/floater_event.xml
index 5c5bcc6d09..5c5bcc6d09 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_event.xml
+++ b/indra/newview/skins/default/xui/ru/floater_event.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_fast_timers.xml b/indra/newview/skins/default/xui/ru/floater_fast_timers.xml
index 20936b8494..20936b8494 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_fast_timers.xml
+++ b/indra/newview/skins/default/xui/ru/floater_fast_timers.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_font_test.xml b/indra/newview/skins/default/xui/ru/floater_font_test.xml
index b51732d3f1..b51732d3f1 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_font_test.xml
+++ b/indra/newview/skins/default/xui/ru/floater_font_test.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_gesture.xml b/indra/newview/skins/default/xui/ru/floater_gesture.xml
index 759d81b2c6..759d81b2c6 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_gesture.xml
+++ b/indra/newview/skins/default/xui/ru/floater_gesture.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_god_tools.xml b/indra/newview/skins/default/xui/ru/floater_god_tools.xml
index 81329475aa..81329475aa 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_god_tools.xml
+++ b/indra/newview/skins/default/xui/ru/floater_god_tools.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_goto_line.xml b/indra/newview/skins/default/xui/ru/floater_goto_line.xml
new file mode 100644
index 0000000000..51caaa471d
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/floater_goto_line.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="script goto" title="ПЕРЕЙТИ ÐРСТРОКУ">
+ <button label="OK" label_selected="OK" name="goto_btn"/>
+ <text name="txt">
+ Перейти на Ñтроку
+ </text>
+</floater>
diff --git a/indra/newview/skins/default/xui/ru/floater_hardware_settings.xml b/indra/newview/skins/default/xui/ru/floater_hardware_settings.xml
index 7400f1df3b..d7da112a27 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_hardware_settings.xml
+++ b/indra/newview/skins/default/xui/ru/floater_hardware_settings.xml
@@ -24,7 +24,11 @@
<text name="Enable VBO:">
Включить VBO:
</text>
- <check_box initial_value="иÑтина" label="Включить объекты вершинных буферов OpenGL" name="vbo" tool_tip="Включение Ñтого параметра на Ñовременном оборудовании даÑÑ‚ увеличение производительноÑти. Однако на Ñтаром оборудовании Ñто может привеÑти к Ñбою приложениÑ."/>
+ <check_box initial_value="true" label="Включить объекты вершинных буферов OpenGL" name="vbo" tool_tip="Включение Ñтого параметра на Ñовременном оборудовании даÑÑ‚ увеличение производительноÑти. Однако на Ñтаром оборудовании Ñто может привеÑти к Ñбою приложениÑ."/>
+ <text name="tc label">
+ Включить S3TC:
+ </text>
+ <check_box initial_value="true" label="Разрешить Ñжатие текÑтур (требует перезагрузки)" name="texture compression" tool_tip="Сжатие текÑтур в видеопамÑти, что позволÑет загружать текÑтуры большего размера за Ñчет некоторого Ð¿Ð°Ð´ÐµÐ½Ð¸Ñ ÐºÐ°Ñ‡ÐµÑтва цвета."/>
<slider label="ПамÑÑ‚ÑŒ Ð´Ð»Ñ Ñ‚ÐµÐºÑтур (Мб):" name="GraphicsCardTextureMemory" tool_tip="КоличеÑтво памÑти, отводимое Ð´Ð»Ñ Ñ‚ÐµÐºÑтур. По умолчанию равно памÑти видеокарты. Уменьшение поможет увеличить производительноÑÑ‚ÑŒ, но текÑтуры могут Ñтать размытыми."/>
<spinner label="ДиÑÑ‚Ð°Ð½Ñ†Ð¸Ñ Ñ‚ÑƒÐ¼Ð°Ð½Ð°:" name="fog"/>
<button label="OK" label_selected="OK" name="OK"/>
diff --git a/indra/newview/skins/default/xui/ru/floater_help_browser.xml b/indra/newview/skins/default/xui/ru/floater_help_browser.xml
index 2f560340ed..2f560340ed 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_help_browser.xml
+++ b/indra/newview/skins/default/xui/ru/floater_help_browser.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_how_to.xml b/indra/newview/skins/default/xui/ru/floater_how_to.xml
index 52525e5d33..52525e5d33 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_how_to.xml
+++ b/indra/newview/skins/default/xui/ru/floater_how_to.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_hud.xml b/indra/newview/skins/default/xui/ru/floater_hud.xml
index b05113bfe0..b05113bfe0 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_hud.xml
+++ b/indra/newview/skins/default/xui/ru/floater_hud.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_im_container.xml b/indra/newview/skins/default/xui/ru/floater_im_container.xml
index b147cfa2b3..eba7a19cd4 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_im_container.xml
+++ b/indra/newview/skins/default/xui/ru/floater_im_container.xml
@@ -1,2 +1,29 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<multi_floater name="floater_im_box" title="ОБЩЕÐИЕ"/>
+<multi_floater name="floater_im_box" title="ОБЩЕÐИЕ">
+ <string name="collapse_icon" value="Conv_toolbar_collapse"/>
+ <string name="expand_icon" value="Conv_toolbar_expand"/>
+ <layout_stack name="conversations_stack">
+ <layout_panel name="conversations_layout_panel">
+ <layout_stack name="conversations_pane_buttons_stack">
+ <layout_panel name="conversations_pane_buttons_expanded">
+ <menu_button name="sort_btn" tool_tip="Параметры проÑмотра/Ñортировки"/>
+ <button name="add_btn" tool_tip="Ðачать разговор"/>
+ <button name="speak_btn" tool_tip="Разговаривать через микрофон"/>
+ </layout_panel>
+ <layout_panel name="conversations_pane_buttons_collapsed">
+ <button name="expand_collapse_btn" tool_tip="Свернуть/развернуть Ñтот ÑпиÑок"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ <layout_panel name="messages_layout_panel">
+ <panel_container name="im_box_tab_container">
+ <panel name="stub_panel">
+ <button name="stub_collapse_btn" tool_tip="Свернуть Ñту панель"/>
+ <text name="stub_textbox">
+ Разговор отображаетÑÑ Ð² отдельном окне. [secondlife:/// Вернуть.]
+ </text>
+ </panel>
+ </panel_container>
+ </layout_panel>
+ </layout_stack>
+</multi_floater>
diff --git a/indra/newview/skins/default/xui/ru/floater_im_session.xml b/indra/newview/skins/default/xui/ru/floater_im_session.xml
index 604d9dc6d3..d4ca04b88b 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/ru/floater_im_session.xml
@@ -1,8 +1,57 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="panel_im">
- <layout_stack name="im_panels">
- <layout_panel>
- <line_editor label="Кому" name="chat_editor"/>
- </layout_panel>
- </layout_stack>
+ <floater.string name="call_btn_start">
+ Conv_toolbar_open_call
+ </floater.string>
+ <floater.string name="call_btn_stop">
+ Conv_toolbar_hang_up
+ </floater.string>
+ <floater.string name="collapseline_icon" value="Conv_collapse_to_one_line"/>
+ <floater.string name="expandline_icon" value="Conv_expand_one_line"/>
+ <floater.string name="collapse_icon" value="Conv_toolbar_collapse"/>
+ <floater.string name="expand_icon" value="Conv_toolbar_expand"/>
+ <floater.string name="tear_off_icon" value="Conv_toolbar_arrow_ne"/>
+ <floater.string name="return_icon" value="Conv_toolbar_arrow_sw"/>
+ <floater.string name="participant_added" value="[NAME] приглашен(а) на разговор."/>
+ <floater.string name="multiple_participants_added" value="[NAME] приглашены на разговор."/>
+ <floater.string name="tooltip_to_separate_window" value="ПеренеÑти Ñтот разговор в отдельное окно"/>
+ <floater.string name="tooltip_to_main_window" value="Вернуть Ñтот разговор в главное окно"/>
+ <floater.string name="start_call_button_tooltip" value="Открыть голоÑовое подключение"/>
+ <floater.string name="end_call_button_tooltip" value="Закрыть голоÑовое подключение"/>
+ <floater.string name="expcol_button_not_tearoff_tooltip" value="Свернуть Ñту панель"/>
+ <floater.string name="expcol_button_tearoff_and_expanded_tooltip" value="Свернуть ÑпиÑок учаÑтников"/>
+ <floater.string name="expcol_button_tearoff_and_collapsed_tooltip" value="Развернуть ÑпиÑок учаÑтников"/>
+ <view name="contents_view">
+ <layout_stack name="main_stack">
+ <layout_panel name="toolbar_panel">
+ <menu_button name="view_options_btn" tool_tip="Параметры проÑмотра/Ñортировки"/>
+ <menu_button name="gear_btn" tool_tip="ДейÑÑ‚Ð²Ð¸Ñ Ñ Ð²Ñ‹Ð±Ñ€Ð°Ð½Ð½Ñ‹Ð¼ жителем"/>
+ <button name="add_btn" tool_tip="Добавить учаÑтника в Ñтот разговор"/>
+ <button name="voice_call_btn" tool_tip="Открыть голоÑовое подключение"/>
+ <button name="close_btn" tool_tip="Завершить Ñтот разговор"/>
+ <button name="expand_collapse_btn" tool_tip="Развернуть/Ñвернуть Ñту панель"/>
+ </layout_panel>
+ <layout_panel name="body_panel">
+ <layout_stack name="im_panels">
+ <layout_panel name="right_part_holder">
+ <layout_stack name="translate_and_chat_stack">
+ <layout_panel name="translate_chat_checkbox_lp">
+ <check_box label="Переводить чат" name="translate_chat_checkbox"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ <layout_panel name="chat_layout_panel">
+ <layout_stack name="input_panels">
+ <layout_panel name="input_editor_layout_panel">
+ <chat_editor label="Кому" name="chat_editor"/>
+ </layout_panel>
+ <layout_panel name="input_button_layout_panel">
+ <button name="minz_btn" tool_tip="Показать/Ñкрыть панель Ñообщений"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
+ </view>
</floater>
diff --git a/indra/newview/skins/default/xui/ru/floater_image_preview.xml b/indra/newview/skins/default/xui/ru/floater_image_preview.xml
index dbc4c32b98..dbc4c32b98 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_image_preview.xml
+++ b/indra/newview/skins/default/xui/ru/floater_image_preview.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_import_collada.xml b/indra/newview/skins/default/xui/ru/floater_import_collada.xml
index 122315cb26..122315cb26 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_import_collada.xml
+++ b/indra/newview/skins/default/xui/ru/floater_import_collada.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_incoming_call.xml b/indra/newview/skins/default/xui/ru/floater_incoming_call.xml
index 072c20147d..3f61421d0c 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_incoming_call.xml
+++ b/indra/newview/skins/default/xui/ru/floater_incoming_call.xml
@@ -10,7 +10,7 @@
анонимно
</floater.string>
<floater.string name="VoiceInviteP2P">
- вызывает.
+ вызывает ваÑ.
</floater.string>
<floater.string name="VoiceInviteAdHoc">
теперь учаÑтвует в групповом голоÑовом чате.
@@ -25,9 +25,9 @@
Хотите выйти из чата «[CURRENT_CHAT]» и приÑоединитьÑÑ Ðº Ñтому голоÑовому чату?
</floater.string>
<text name="question">
- Хотите выйти из чата «[CURRENT_CHAT]» и приÑоединитьÑÑ Ðº Ñтому голоÑовому чату?
+ ЕÑли вы ответите, вы покинете текущий голоÑовой чат.
</text>
- <button label="ПринÑÑ‚ÑŒ" label_selected="ПринÑÑ‚ÑŒ" name="Accept"/>
- <button label="Отклонить" label_selected="Отклонить" name="Reject"/>
- <button label="Ðачать IM" name="Start IM"/>
+ <button label="Ответить" label_selected="Ответить" name="Accept"/>
+ <button label="Игнорировать" label_selected="Игнорировать" name="Reject"/>
+ <button label="Открыть IM" name="Start IM"/>
</floater>
diff --git a/indra/newview/skins/default/xui/ru/floater_inspect.xml b/indra/newview/skins/default/xui/ru/floater_inspect.xml
index f7bb981575..f7bb981575 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_inspect.xml
+++ b/indra/newview/skins/default/xui/ru/floater_inspect.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_inventory.xml b/indra/newview/skins/default/xui/ru/floater_inventory.xml
deleted file mode 100644
index 35cbcf177d..0000000000
--- a/indra/newview/skins/default/xui/ru/floater_inventory.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Inventory" title="МОЙ ИÐВЕÐТÐРЬ">
- <panel label="Панель инвентарÑ" name="Inventory Panel"/>
-</floater>
diff --git a/indra/newview/skins/default/xui/ru/floater_inventory_item_properties.xml b/indra/newview/skins/default/xui/ru/floater_inventory_item_properties.xml
index 9021b71fe2..9021b71fe2 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_inventory_item_properties.xml
+++ b/indra/newview/skins/default/xui/ru/floater_inventory_item_properties.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_inventory_view_finder.xml b/indra/newview/skins/default/xui/ru/floater_inventory_view_finder.xml
index 02068c57b8..02068c57b8 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_inventory_view_finder.xml
+++ b/indra/newview/skins/default/xui/ru/floater_inventory_view_finder.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_joystick.xml b/indra/newview/skins/default/xui/ru/floater_joystick.xml
index 66568563da..66568563da 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_joystick.xml
+++ b/indra/newview/skins/default/xui/ru/floater_joystick.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_lagmeter.xml b/indra/newview/skins/default/xui/ru/floater_lagmeter.xml
index c420006a03..c420006a03 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_lagmeter.xml
+++ b/indra/newview/skins/default/xui/ru/floater_lagmeter.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_land_holdings.xml b/indra/newview/skins/default/xui/ru/floater_land_holdings.xml
index 17d347867d..17d347867d 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_land_holdings.xml
+++ b/indra/newview/skins/default/xui/ru/floater_land_holdings.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_live_lsleditor.xml b/indra/newview/skins/default/xui/ru/floater_live_lsleditor.xml
index d8047fc045..fb6e747592 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_live_lsleditor.xml
+++ b/indra/newview/skins/default/xui/ru/floater_live_lsleditor.xml
@@ -10,6 +10,6 @@
СКРИПТ: [NAME]
</floater.string>
<button label="СброÑ" label_selected="СброÑ" name="Reset"/>
- <check_box initial_value="иÑтина" label="ВыполнÑетÑÑ" name="running"/>
- <check_box initial_value="иÑтина" label="Моно" name="mono"/>
+ <check_box initial_value="true" label="ВыполнÑетÑÑ" name="running"/>
+ <check_box initial_value="true" label="Моно" name="mono"/>
</floater>
diff --git a/indra/newview/skins/default/xui/ru/floater_lsl_guide.xml b/indra/newview/skins/default/xui/ru/floater_lsl_guide.xml
index 95a3b8b2a0..95a3b8b2a0 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_lsl_guide.xml
+++ b/indra/newview/skins/default/xui/ru/floater_lsl_guide.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_map.xml b/indra/newview/skins/default/xui/ru/floater_map.xml
index 59ceb0a773..59ceb0a773 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_map.xml
+++ b/indra/newview/skins/default/xui/ru/floater_map.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_media_browser.xml b/indra/newview/skins/default/xui/ru/floater_media_browser.xml
index d1fc105046..d1fc105046 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_media_browser.xml
+++ b/indra/newview/skins/default/xui/ru/floater_media_browser.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_media_settings.xml b/indra/newview/skins/default/xui/ru/floater_media_settings.xml
index 1515cbb3b8..1515cbb3b8 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_media_settings.xml
+++ b/indra/newview/skins/default/xui/ru/floater_media_settings.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_mem_leaking.xml b/indra/newview/skins/default/xui/ru/floater_mem_leaking.xml
index 7aa5c27cde..7aa5c27cde 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_mem_leaking.xml
+++ b/indra/newview/skins/default/xui/ru/floater_mem_leaking.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_merchant_outbox.xml b/indra/newview/skins/default/xui/ru/floater_merchant_outbox.xml
index 332fa3b82f..332fa3b82f 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_merchant_outbox.xml
+++ b/indra/newview/skins/default/xui/ru/floater_merchant_outbox.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_model_preview.xml b/indra/newview/skins/default/xui/ru/floater_model_preview.xml
index 5bb96b8de4..0c6d41b4ef 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_model_preview.xml
+++ b/indra/newview/skins/default/xui/ru/floater_model_preview.xml
@@ -92,19 +92,54 @@
<text initial_value="Треугольники" name="triangles" value="Треугольники"/>
<text initial_value="Вершины" name="vertices" value="Вершины"/>
<text initial_value="Ð’Ñ‹Ñокий" name="high_label" value="Ð’Ñ‹Ñокий"/>
+ <combo_box name="lod_source_high">
+ <item name="Load from file" value="Загрузка из файла"/>
+ <item name="Generate" value="Создать"/>
+ </combo_box>
<button label="Обзор..." name="lod_browse_high"/>
+ <combo_box name="lod_mode_high">
+ <item name="Triangle Limit" value="Предельное чиÑло треугольников"/>
+ <item name="Error Threshold" value="Порог ошибки"/>
+ </combo_box>
<text initial_value="0" name="high_triangles" value="0"/>
<text initial_value="0" name="high_vertices" value="0"/>
<text initial_value="Средний" name="medium_label" value="Средний"/>
+ <combo_box name="lod_source_medium">
+ <item name="Load from file" value="Загрузка из файла"/>
+ <item name="Generate" value="Создать"/>
+ <item name="Use LoD above" value="ИÑпользовать УД выше"/>
+ </combo_box>
<button label="Обзор..." name="lod_browse_medium"/>
+ <combo_box name="lod_mode_medium">
+ <item name="Triangle Limit" value="Предельное чиÑло треугольников"/>
+ <item name="Error Threshold" value="Порог ошибки"/>
+ </combo_box>
<text initial_value="0" name="medium_triangles" value="0"/>
<text initial_value="0" name="medium_vertices" value="0"/>
<text initial_value="Ðизкий" name="low_label" value="Ðизкий"/>
+ <combo_box name="lod_source_low">
+ <item name="Load from file" value="Загрузка из файла"/>
+ <item name="Generate" value="Создать"/>
+ <item name="Use LoD above" value="ИÑпользовать УД выше"/>
+ </combo_box>
<button label="Обзор..." name="lod_browse_low"/>
+ <combo_box name="lod_mode_low">
+ <item name="Triangle Limit" value="Предельное чиÑло треугольников"/>
+ <item name="Error Threshold" value="Порог ошибки"/>
+ </combo_box>
<text initial_value="0" name="low_triangles" value="0"/>
<text initial_value="0" name="low_vertices" value="0"/>
<text initial_value="Самый низкий" name="lowest_label" value="Самый низкий"/>
+ <combo_box name="lod_source_lowest">
+ <item name="Load from file" value="Загрузка из файла"/>
+ <item name="Generate" value="Создать"/>
+ <item name="Use LoD above" value="ИÑпользовать УД выше"/>
+ </combo_box>
<button label="Обзор..." name="lod_browse_lowest"/>
+ <combo_box name="lod_mode_lowest">
+ <item name="Triangle Limit" value="Предельное чиÑло треугольников"/>
+ <item name="Error Threshold" value="Порог ошибки"/>
+ </combo_box>
<text initial_value="0" name="lowest_triangles" value="0"/>
<text initial_value="0" name="lowest_vertices" value="0"/>
<check_box label="Генерировать нормали" name="gen_normals"/>
diff --git a/indra/newview/skins/default/xui/ru/floater_model_wizard.xml b/indra/newview/skins/default/xui/ru/floater_model_wizard.xml
deleted file mode 100644
index c1a63bf7da..0000000000
--- a/indra/newview/skins/default/xui/ru/floater_model_wizard.xml
+++ /dev/null
@@ -1,208 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Model Wizard" title="ПЕРЕДÐТЬ ÐœÐСТЕР МОДЕЛИРОВÐÐИЯ">
- <button label="5. Передать" name="upload_btn"/>
- <button label="4. ПроÑмотр" name="review_btn"/>
- <button label="3. Физика" name="physics_btn"/>
- <button label="2. Оптимизировать" name="optimize_btn"/>
- <button label="1. Выбрать файл" name="choose_file_btn"/>
- <panel name="choose_file_panel">
- <panel name="choose_file_header_panel">
- <text name="choose_file_header_text">
- Выберите файл модели
- </text>
- </panel>
- <panel name="choose_file_content">
- <text name="advanced_users_text">
- ПользователÑм, работающим в раÑширенном режиме: еÑли вы умеете Ñоздавать трехмерные графичеÑкие объекты, то, возможно, захотите воÑпользоватьÑÑ ÑредÑтвом Advanced Uploader, которое предоÑтавлÑет раÑширенные возможноÑти передачи объектов.
- </text>
- <button label="Перейти в раÑширенный режим" name="switch_to_advanced"/>
- <text name="Cache location">
- Выберите файл модели Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ´Ð°Ñ‡Ð¸
- </text>
- <button label="Обзор..." label_selected="Обзор..." name="browse"/>
- <text name="Model types">
- Ð’ Second Life поддерживаютÑÑ Ñ„Ð°Ð¹Ð»Ñ‹ COLLADA (.dae)
- </text>
- <text name="dimensions">
- X Y Z
- </text>
- <text name="warning_label">
- Ð’ÐИМÐÐИЕ!
- </text>
- <text name="warning_text">
- Ð’Ñ‹ не Ñможете завершить передачу Ñтой модели на Ñерверы Second Life. [secondlife:///app/floater/learn_more Узнайте, как] наÑтроить в вашем аккаунте передачу Ñеточных моделей.
- </text>
- </panel>
- </panel>
- <panel name="optimize_panel">
- <panel name="optimize_header_panel">
- <text name="optimize_header_text">
- Оптимизировать модель
- </text>
- </panel>
- <text name="optimize_description">
- Мы оптимизировали модель Ð´Ð»Ñ Ð¿Ð¾Ð²Ñ‹ÑˆÐµÐ½Ð¸Ñ Ð±Ñ‹ÑтродейÑтвиÑ. По желанию можно выполнить дополнительную наÑтройку.
- </text>
- <panel name="optimize_content">
- <text name="high_detail_text">
- Создать уровень детализации: Ð’Ñ‹Ñокий
- </text>
- <text name="medium_detail_text">
- Создать уровень детализации: Средний
- </text>
- <text name="low_detail_text">
- Создать уровень детализации: Ðизкий
- </text>
- <text name="lowest_detail_text">
- Создать уровень детализации: Самый низкий
- </text>
- </panel>
- <panel name="content2">
- <button label="ПереÑчитать геометрию" name="recalculate_geometry_btn"/>
- <text name="lod_label">
- ПроÑмотр геометрии
- </text>
- <combo_box name="preview_lod_combo" tool_tip="Ð”ÐµÑ‚Ð°Ð»Ð¸Ð·Ð°Ñ†Ð¸Ñ Ð¿Ñ€Ð¸ предварительном проÑмотре">
- <combo_item name="high">
- Детально
- </combo_item>
- <combo_item name="medium">
- СреднÑÑ Ð´ÐµÑ‚Ð°Ð»Ð¸Ð·Ð°Ñ†Ð¸Ñ
- </combo_item>
- <combo_item name="low">
- Мало деталей
- </combo_item>
- <combo_item name="lowest">
- Минимум деталей
- </combo_item>
- </combo_box>
- </panel>
- </panel>
- <panel name="physics_panel">
- <panel name="physics_header_panel">
- <text name="physics_header_text">
- ÐаÑтроить физичеÑкие параметры
- </text>
- </panel>
- <text name="physics_description">
- Мы Ñоздадим форму Ð´Ð»Ñ Ð²Ð½ÐµÑˆÐ½ÐµÐ³Ð¾ каркаÑа модели. ÐаÑтройте уровень детализации формы в ÑоответÑтвии Ñ Ñ†ÐµÐ»Ñми, Ð´Ð»Ñ ÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ñ… предназначена модель.
- </text>
- <panel name="physics_content">
- <button label="ПереÑчитать физичеÑкие данные" name="recalculate_physics_btn"/>
- <button label="ПереÑчет..." name="recalculating_physics_btn"/>
- <text name="lod_label">
- ПроÑмотр физичеÑких данных
- </text>
- <combo_box name="preview_lod_combo2" tool_tip="Уровень детализации при предварительном проÑмотре">
- <combo_item name="high">
- Детально
- </combo_item>
- <combo_item name="medium">
- СреднÑÑ Ð´ÐµÑ‚Ð°Ð»Ð¸Ð·Ð°Ñ†Ð¸Ñ
- </combo_item>
- <combo_item name="low">
- Мало деталей
- </combo_item>
- <combo_item name="lowest">
- Минимум деталей
- </combo_item>
- </combo_box>
- </panel>
- </panel>
- <panel name="review_panel">
- <panel name="review_header_panel">
- <text name="review_header_text">
- ПроÑмотр
- </text>
- </panel>
- <panel name="review_content">
- <text name="review_prim_equiv">
- ВоздейÑтвие на учаÑток/регион: Ñквивалент в примитивах: [EQUIV]
- </text>
- <text name="review_fee">
- За передачу Ñ Ð²Ð°ÑˆÐµÐ³Ð¾ Ñчета будет ÑнÑта плата в размере L$[FEE].
- </text>
- <text name="review_confirmation">
- Ðажав кнопку «Передать», вы подтверждаете, что у Ð²Ð°Ñ ÐµÑÑ‚ÑŒ надлежащие права на вÑе ÑоÑтавлÑющие модели.
- </text>
- </panel>
- </panel>
- <panel name="upload_panel">
- <panel name="upload_header_panel">
- <text name="upload_header_text">
- Передача завершена
- </text>
- </panel>
- <text name="model_uploaded_text">
- Ваша модель передана.
- </text>
- <text name="inventory_text">
- ÐаходитÑÑ Ð² папке «Объекты» вашего инвентарÑ.
- </text>
- <text name="charged_fee">
- С вашего Ñчета ÑнÑто: L$[FEE].
- </text>
- </panel>
- <button label="&lt;&lt; Ðазад" name="back"/>
- <button label="Далее &gt;&gt;" name="next"/>
- <button label="РаÑÑчитать Ð²ÐµÑ Ð¸ плату &gt;&gt;" name="calculate"/>
- <button label="РаÑчет..." name="calculating"/>
- <button label="Передать" name="upload" tool_tip="Передать в ÑимулÑтор"/>
- <button label="Отмена" name="cancel"/>
- <button label="Закрыть" name="close"/>
- <spinner name="import_scale" value="1.0"/>
- <string name="status_idle">
- Ðеактивно
- </string>
- <string name="status_parse_error">
- Проблема при анализе файла DAE – Ñм. подробноÑти в журнале.
- </string>
- <string name="status_reading_file">
- Загрузка...
- </string>
- <string name="status_generating_meshes">
- СоздаютÑÑ Ð¼ÐµÑˆÐ¸...
- </string>
- <string name="status_vertex_number_overflow">
- Ошибка. ЧиÑло вершин превышает 65534. Прервано.
- </string>
- <string name="bad_element">
- Ошибка: недопуÑтимый Ñлемент
- </string>
- <string name="high">
- выÑокий
- </string>
- <string name="medium">
- Ñредний
- </string>
- <string name="low">
- низкий
- </string>
- <string name="lowest">
- Ñамый низкий
- </string>
- <string name="mesh_status_good">
- ДоÑтавлено!
- </string>
- <string name="mesh_status_na">
- Ð/Д
- </string>
- <string name="mesh_status_none">
- Ðет
- </string>
- <string name="mesh_status_submesh_mismatch">
- ОтличаетÑÑ Ñ‡Ð¸Ñло текÑтурируемых граней на уровнÑÑ… детализации.
- </string>
- <string name="mesh_status_mesh_mismatch">
- ОтличаетÑÑ Ñ‡Ð¸Ñло ÑкземплÑров меша на уровнÑÑ… детализации.
- </string>
- <string name="mesh_status_too_many_vertices">
- Слишком много вершин на уровне детализации.
- </string>
- <string name="mesh_status_missing_lod">
- ОтÑутÑтвует необходимый уровень детализации.
- </string>
- <string name="layer_all">
- Ð’Ñе
- </string>
-</floater>
diff --git a/indra/newview/skins/default/xui/ru/floater_moveview.xml b/indra/newview/skins/default/xui/ru/floater_moveview.xml
index cb1fda1a1f..cb1fda1a1f 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_moveview.xml
+++ b/indra/newview/skins/default/xui/ru/floater_moveview.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_mute_object.xml b/indra/newview/skins/default/xui/ru/floater_mute_object.xml
index 44177acb53..44177acb53 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_mute_object.xml
+++ b/indra/newview/skins/default/xui/ru/floater_mute_object.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_my_appearance.xml b/indra/newview/skins/default/xui/ru/floater_my_appearance.xml
index b90d80f3fd..b90d80f3fd 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_my_appearance.xml
+++ b/indra/newview/skins/default/xui/ru/floater_my_appearance.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_my_inventory.xml b/indra/newview/skins/default/xui/ru/floater_my_inventory.xml
index 534d2a5774..534d2a5774 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_my_inventory.xml
+++ b/indra/newview/skins/default/xui/ru/floater_my_inventory.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_nearby_chat.xml b/indra/newview/skins/default/xui/ru/floater_nearby_chat.xml
deleted file mode 100644
index 184c753e40..0000000000
--- a/indra/newview/skins/default/xui/ru/floater_nearby_chat.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="nearby_chat" title="ЛОКÐЛЬÐЫЙ ЧÐТ">
- <check_box label="Перевод чата" name="translate_chat_checkbox"/>
-</floater>
diff --git a/indra/newview/skins/default/xui/ru/floater_notification.xml b/indra/newview/skins/default/xui/ru/floater_notification.xml
index c3e299202c..c3e299202c 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_notification.xml
+++ b/indra/newview/skins/default/xui/ru/floater_notification.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_notifications_console.xml b/indra/newview/skins/default/xui/ru/floater_notifications_console.xml
index bd836590e1..bd836590e1 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_notifications_console.xml
+++ b/indra/newview/skins/default/xui/ru/floater_notifications_console.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_object_weights.xml b/indra/newview/skins/default/xui/ru/floater_object_weights.xml
index 41e0118732..41e0118732 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_object_weights.xml
+++ b/indra/newview/skins/default/xui/ru/floater_object_weights.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_openobject.xml b/indra/newview/skins/default/xui/ru/floater_openobject.xml
index 5da308eecb..5da308eecb 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_openobject.xml
+++ b/indra/newview/skins/default/xui/ru/floater_openobject.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_outfit_save_as.xml b/indra/newview/skins/default/xui/ru/floater_outfit_save_as.xml
index 301206e473..301206e473 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_outfit_save_as.xml
+++ b/indra/newview/skins/default/xui/ru/floater_outfit_save_as.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_outgoing_call.xml b/indra/newview/skins/default/xui/ru/floater_outgoing_call.xml
index 5e50a75b85..5e50a75b85 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_outgoing_call.xml
+++ b/indra/newview/skins/default/xui/ru/floater_outgoing_call.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_pathfinding_characters.xml b/indra/newview/skins/default/xui/ru/floater_pathfinding_characters.xml
new file mode 100755
index 0000000000..ce7ffc3d20
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/floater_pathfinding_characters.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="floater_pathfinding_characters" title="ПерÑонажи Ñ Ð¿Ð¾Ð¸Ñком пути">
+ <floater.string name="messaging_get_inprogress">
+ ÐžÐ¿Ñ€Ð¾Ñ Ð¿ÐµÑ€Ñонажей Ñ Ð¿Ð¾Ð¸Ñком пути...
+ </floater.string>
+ <floater.string name="messaging_get_error">
+ Ошибка при опроÑе перÑонажей Ñ Ð¿Ð¾Ð¸Ñком пути.
+ </floater.string>
+ <floater.string name="messaging_complete_none_found">
+ Ðет перÑонажей Ñ Ð¿Ð¾Ð¸Ñком пути.
+ </floater.string>
+ <floater.string name="messaging_complete_available">
+ Выбрано перÑонажей: [NUM_SELECTED] из [NUM_TOTAL].
+ </floater.string>
+ <floater.string name="messaging_not_enabled">
+ Ð’ Ñтом регионе не разрешен поиÑк пути.
+ </floater.string>
+ <floater.string name="character_cpu_time">
+ [CPU_TIME] мкÑ
+ </floater.string>
+ <floater.string name="character_owner_loading">
+ [Загрузка]
+ </floater.string>
+ <floater.string name="character_owner_unknown">
+ [ÐеизвеÑтно]
+ </floater.string>
+ <floater.string name="character_owner_group">
+ [группа]
+ </floater.string>
+ <panel>
+ <scroll_list name="objects_scroll_list">
+ <scroll_list.columns label="ИмÑ" name="name"/>
+ <scroll_list.columns label="ОпиÑание" name="description"/>
+ <scroll_list.columns label="Владелец" name="owner"/>
+ <scroll_list.columns label="ЦП" name="cpu_time"/>
+ <scroll_list.columns label="Ð’Ñ‹Ñота" name="altitude"/>
+ </scroll_list>
+ <text name="messaging_status">
+ ПерÑонажи:
+ </text>
+ <button label="Обновить ÑпиÑок" name="refresh_objects_list"/>
+ <button label="Выбрать вÑе" name="select_all_objects"/>
+ <button label="Отменить выбор" name="select_none_objects"/>
+ </panel>
+ <panel>
+ <text name="actions_label">
+ ДейÑÑ‚Ð²Ð¸Ñ Ñ Ð²Ñ‹Ð±Ñ€Ð°Ð½Ð½Ñ‹Ð¼Ð¸ перÑонажами:
+ </text>
+ <check_box label="Показать метку" name="show_beacon"/>
+ <check_box label="Показать физичеÑкую капÑулу" name="show_physics_capsule"/>
+ <button label="ВзÑÑ‚ÑŒ" name="take_objects"/>
+ <button label="Сделать копию" name="take_copy_objects"/>
+ <button label="Телепортировать Ð¼ÐµÐ½Ñ Ñ‚ÑƒÐ´Ð°" name="teleport_me_to_object" tool_tip="Разрешено, только еÑли выбран один перÑонаж."/>
+ <button label="Возврат" name="return_objects"/>
+ <button label="Удалить" name="delete_objects"/>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/ru/floater_pathfinding_console.xml b/indra/newview/skins/default/xui/ru/floater_pathfinding_console.xml
new file mode 100755
index 0000000000..fa72df04fd
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/floater_pathfinding_console.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="floater_pathfinding_console" title="ПроÑмотр/теÑтирование поиÑка пути">
+ <floater.string name="navmesh_viewer_status_library_not_implemented">
+ Ðе удалоÑÑŒ найти реализацию библиотеки поиÑка пути
+ </floater.string>
+ <floater.string name="navmesh_viewer_status_region_not_enabled">
+ Ð’ Ñтом регионе не разрешен поиÑк пути.
+ </floater.string>
+ <floater.string name="navmesh_viewer_status_region_loading">
+ Ожидание Ð¾ÐºÐ¾Ð½Ñ‡Ð°Ð½Ð¸Ñ Ð·Ð°Ð³Ñ€ÑƒÐ·ÐºÐ¸ региона.
+ </floater.string>
+ <floater.string name="navmesh_viewer_status_checking_version">
+ Проверка ÑоÑтоÑÐ½Ð¸Ñ Ð½Ð°Ð²Ð¸Ð³Ð°Ñ†Ð¸Ð¾Ð½Ð½Ð¾Ð¹ Ñетки.
+ </floater.string>
+ <floater.string name="navmesh_viewer_status_downloading">
+ Загрузка навигационной Ñетки.
+ </floater.string>
+ <floater.string name="navmesh_viewer_status_updating">
+ Ðа Ñервере изменилаÑÑŒ Ð½Ð°Ð²Ð¸Ð³Ð°Ñ†Ð¸Ð¾Ð½Ð½Ð°Ñ Ñетка. Загрузка новой навигационной Ñетки.
+ </floater.string>
+ <floater.string name="navmesh_viewer_status_has_navmesh">
+ Загружена поÑледнÑÑ Ð½Ð°Ð²Ð¸Ð³Ð°Ñ†Ð¸Ð¾Ð½Ð½Ð°Ñ Ñетка.
+ </floater.string>
+ <floater.string name="navmesh_viewer_status_error">
+ Ðе удалоÑÑŒ загрузить навигационную Ñетку.
+ </floater.string>
+ <floater.string name="navmesh_simulator_status_pending">
+ Ð’ навигационной Ñетке еÑÑ‚ÑŒ незавершенные изменениÑ.
+ </floater.string>
+ <floater.string name="navmesh_simulator_status_building">
+ Идет поÑтроение навигационной Ñетки.
+ </floater.string>
+ <floater.string name="navmesh_simulator_status_some_pending">
+ Ð’ некоторых регионах навигационной Ñетки еÑÑ‚ÑŒ незавершенные изменениÑ.
+ </floater.string>
+ <floater.string name="navmesh_simulator_status_some_building">
+ Идет поÑтроение регионов навигационной Ñетки.
+ </floater.string>
+ <floater.string name="navmesh_simulator_status_pending_and_building">
+ Ð’ некоторых регионах навигационной Ñетки еÑÑ‚ÑŒ незавершенные изменениÑ, идет поÑтроение других регионов.
+ </floater.string>
+ <floater.string name="navmesh_simulator_status_complete">
+ ÐÐ°Ð²Ð¸Ð³Ð°Ñ†Ð¸Ð¾Ð½Ð½Ð°Ñ Ñетка уже обновлена.
+ </floater.string>
+ <floater.string name="pathing_library_not_implemented">
+ Ðе удалоÑÑŒ найти реализацию библиотеки поиÑка пути
+ </floater.string>
+ <floater.string name="pathing_region_not_enabled">
+ Ð’ Ñтом регионе не разрешен поиÑк пути.
+ </floater.string>
+ <floater.string name="pathing_choose_start_and_end_points">
+ Выберите начальную и конечную точки.
+ </floater.string>
+ <floater.string name="pathing_choose_start_point">
+ Выберите начальную точку.
+ </floater.string>
+ <floater.string name="pathing_choose_end_point">
+ Выберите конечную точку.
+ </floater.string>
+ <floater.string name="pathing_path_valid">
+ Путь показан оранжевым цветом.
+ </floater.string>
+ <floater.string name="pathing_path_invalid">
+ Ðе удалоÑÑŒ найти путь между выбранными точками.
+ </floater.string>
+ <floater.string name="pathing_error">
+ Ошибка при Ñоздании пути.
+ </floater.string>
+ <tab_container name="view_test_tab_container">
+ <panel label="Вид" name="view_panel">
+ <text name="show_label">
+ Показать:
+ </text>
+ <check_box label="Мир" name="show_world"/>
+ <check_box label="Только перемещаемые предметы" name="show_world_movables_only"/>
+ <check_box label="ÐÐ°Ð²Ð¸Ð³Ð°Ñ†Ð¸Ð¾Ð½Ð½Ð°Ñ Ñетка" name="show_navmesh"/>
+ <text name="show_walkability_label">
+ Показать карту проходимоÑти:
+ </text>
+ <combo_box name="show_heatmap_mode">
+ <combo_box.item label="Ðе показывать" name="show_heatmap_mode_none"/>
+ <combo_box.item label="Тип перÑонажа A" name="show_heatmap_mode_a"/>
+ <combo_box.item label="Тип перÑонажа B" name="show_heatmap_mode_b"/>
+ <combo_box.item label="Тип перÑонажа C" name="show_heatmap_mode_c"/>
+ <combo_box.item label="Тип перÑонажа D" name="show_heatmap_mode_d"/>
+ </combo_box>
+ <check_box label="Проходимые меÑта" name="show_walkables"/>
+ <check_box label="Материальные объемы" name="show_material_volumes"/>
+ <check_box label="Статичные препÑÑ‚ÑтвиÑ" name="show_static_obstacles"/>
+ <check_box label="ИÑключающие объемы" name="show_exclusion_volumes"/>
+ <check_box label="Водное зеркало" name="show_water_plane"/>
+ <check_box label="РентгеновÑкое зрение" name="show_xray"/>
+ </panel>
+ <panel label="Проверить путь" name="test_panel">
+ <text name="ctrl_click_label">
+ Ctrl-щелчок Ð´Ð»Ñ Ð²Ñ‹Ð±Ð¾Ñ€Ð° начальной точки.
+ </text>
+ <text name="shift_click_label">
+ Shift-щелчок Ð´Ð»Ñ Ð²Ñ‹Ð±Ð¾Ñ€Ð° конечной точки.
+ </text>
+ <text name="character_width_label">
+ Ширина перÑонажа
+ </text>
+ <slider name="character_width" value="1"/>
+ <text name="character_width_unit_label">
+ м
+ </text>
+ <text name="character_type_label">
+ Тип перÑонажа
+ </text>
+ <combo_box name="path_character_type">
+ <combo_box.item label="Ðет" name="path_character_type_none"/>
+ <combo_box.item label="A" name="path_character_type_a"/>
+ <combo_box.item label="B" name="path_character_type_b"/>
+ <combo_box.item label="C" name="path_character_type_c"/>
+ <combo_box.item label="D" name="path_character_type_d"/>
+ </combo_box>
+ <button label="Удалить путь" name="clear_path"/>
+ </panel>
+ </tab_container>
+</floater>
diff --git a/indra/newview/skins/default/xui/ru/floater_pathfinding_linksets.xml b/indra/newview/skins/default/xui/ru/floater_pathfinding_linksets.xml
new file mode 100755
index 0000000000..db100fa415
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/floater_pathfinding_linksets.xml
@@ -0,0 +1,167 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="floater_pathfinding_linksets" title="Ðаборы ÑвÑзей Ð´Ð»Ñ Ð¿Ð¾Ð¸Ñка пути">
+ <floater.string name="messaging_get_inprogress">
+ Ð—Ð°Ð¿Ñ€Ð¾Ñ Ð½Ð°Ð±Ð¾Ñ€Ð¾Ð² ÑвÑзей Ð´Ð»Ñ Ð¿Ð¾Ð¸Ñка пути...
+ </floater.string>
+ <floater.string name="messaging_get_error">
+ Ошибка при запроÑе наборов ÑвÑзей Ð´Ð»Ñ Ð¿Ð¾Ð¸Ñка пути.
+ </floater.string>
+ <floater.string name="messaging_set_inprogress">
+ Изменение выбранных наборов ÑвÑзей Ð´Ð»Ñ Ð¿Ð¾Ð¸Ñка пути...
+ </floater.string>
+ <floater.string name="messaging_set_error">
+ Ошибка при изменении выбранных наборов ÑвÑзей Ð´Ð»Ñ Ð¿Ð¾Ð¸Ñка пути.
+ </floater.string>
+ <floater.string name="messaging_complete_none_found">
+ Ðет наборов ÑвÑзей Ð´Ð»Ñ Ð¿Ð¾Ð¸Ñка пути.
+ </floater.string>
+ <floater.string name="messaging_complete_available">
+ Выбрано наборов ÑвÑзей: [NUM_SELECTED] из [NUM_TOTAL].
+ </floater.string>
+ <floater.string name="messaging_not_enabled">
+ Ð’ Ñтом регионе не разрешен поиÑк пути.
+ </floater.string>
+ <floater.string name="linkset_terrain_name">
+ [Ландшафт]
+ </floater.string>
+ <floater.string name="linkset_terrain_description">
+ --
+ </floater.string>
+ <floater.string name="linkset_terrain_owner">
+ --
+ </floater.string>
+ <floater.string name="linkset_terrain_scripted">
+ --
+ </floater.string>
+ <floater.string name="linkset_terrain_land_impact">
+ --
+ </floater.string>
+ <floater.string name="linkset_terrain_dist_from_you">
+ --
+ </floater.string>
+ <floater.string name="linkset_owner_loading">
+ [Загрузка]
+ </floater.string>
+ <floater.string name="linkset_owner_unknown">
+ [ÐеизвеÑтно]
+ </floater.string>
+ <floater.string name="linkset_owner_group">
+ [группа]
+ </floater.string>
+ <floater.string name="linkset_is_scripted">
+ Да
+ </floater.string>
+ <floater.string name="linkset_is_not_scripted">
+ Ðет
+ </floater.string>
+ <floater.string name="linkset_is_unknown_scripted">
+ ÐеизвеÑтно
+ </floater.string>
+ <floater.string name="linkset_use_walkable">
+ Проходимое меÑто
+ </floater.string>
+ <floater.string name="linkset_use_static_obstacle">
+ Статичное препÑÑ‚Ñтвие
+ </floater.string>
+ <floater.string name="linkset_use_dynamic_obstacle">
+ Перемещаемое препÑÑ‚Ñтвие
+ </floater.string>
+ <floater.string name="linkset_use_material_volume">
+ Материальный объем
+ </floater.string>
+ <floater.string name="linkset_use_exclusion_volume">
+ ИÑключающий объем
+ </floater.string>
+ <floater.string name="linkset_use_dynamic_phantom">
+ Перемещаемый фантом
+ </floater.string>
+ <floater.string name="linkset_is_terrain">
+ [неизменÑемый]
+ </floater.string>
+ <floater.string name="linkset_is_restricted_state">
+ [ограниченный]
+ </floater.string>
+ <floater.string name="linkset_is_non_volume_state">
+ [вогнутый]
+ </floater.string>
+ <floater.string name="linkset_is_restricted_non_volume_state">
+ [ограниченный,вогнутый]
+ </floater.string>
+ <floater.string name="linkset_choose_use">
+ Выберите Ñтепень иÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð½Ð°Ð±Ð¾Ñ€Ð¾Ð² ÑвÑзей...
+ </floater.string>
+ <panel>
+ <combo_box name="filter_by_linkset_use">
+ <combo_box.item label="Фильтр по Ñтепени иÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð½Ð°Ð±Ð¾Ñ€Ð¾Ð² ÑвÑзей..." name="filter_by_linkset_use_none"/>
+ <combo_box.item label="Проходимое меÑто" name="filter_by_linkset_use_walkable"/>
+ <combo_box.item label="Статичное препÑÑ‚Ñтвие" name="filter_by_linkset_use_static_obstacle"/>
+ <combo_box.item label="Перемещаемое препÑÑ‚Ñтвие" name="filter_by_linkset_use_dynamic_obstacle"/>
+ <combo_box.item label="Материальный объем" name="filter_by_linkset_use_material_volume"/>
+ <combo_box.item label="ИÑключающий объем" name="filter_by_linkset_use_exclusion_volume"/>
+ <combo_box.item label="Перемещаемый фантом" name="filter_by_linkset_use_dynamic_phantom"/>
+ </combo_box>
+ <button label="Применить" name="apply_filters"/>
+ <button label="ЧиÑто" name="clear_filters"/>
+ <scroll_list name="objects_scroll_list">
+ <scroll_list.columns label="Ð˜Ð¼Ñ (корневой примитив)" name="name"/>
+ <scroll_list.columns label="ОпиÑание (корневой примитив)" name="description"/>
+ <scroll_list.columns label="Владелец" name="owner"/>
+ <scroll_list.columns label="Скриптовые" name="scripted"/>
+ <scroll_list.columns label="ВоздейÑтвие" name="land_impact"/>
+ <scroll_list.columns label="РаÑÑтоÑние" name="dist_from_you"/>
+ <scroll_list.columns label="ИÑпользование набора ÑвÑзей" name="linkset_use"/>
+ <scroll_list.columns label="A %" name="a_percent"/>
+ <scroll_list.columns label="B %" name="b_percent"/>
+ <scroll_list.columns label="C %" name="c_percent"/>
+ <scroll_list.columns label="D %" name="d_percent"/>
+ </scroll_list>
+ <text name="messaging_status">
+ Ðаборы ÑвÑзей:
+ </text>
+ <button label="Обновить ÑпиÑок" name="refresh_objects_list"/>
+ <button label="Выбрать вÑе" name="select_all_objects"/>
+ <button label="Отменить выбор" name="select_none_objects"/>
+ </panel>
+ <panel>
+ <check_box label="Показать метку" name="show_beacon"/>
+ <button label="ВзÑÑ‚ÑŒ" name="take_objects"/>
+ <button label="Сделать копию" name="take_copy_objects"/>
+ <button label="Телепортировать Ð¼ÐµÐ½Ñ Ñ‚ÑƒÐ´Ð°" name="teleport_me_to_object"/>
+ <button label="Возврат" name="return_objects"/>
+ <button label="Удалить" name="delete_objects"/>
+ </panel>
+ <panel>
+ <text name="walkability_coefficients_label">
+ ПроходимоÑÑ‚ÑŒ:
+ </text>
+ <text name="edit_a_label">
+ A
+ </text>
+ <line_editor name="edit_a_value" tool_tip="ПроходимоÑÑ‚ÑŒ Ð´Ð»Ñ Ð¿ÐµÑ€Ñонажей типа A. Пример перÑонажа – гуманоид."/>
+ <text name="edit_b_label">
+ B
+ </text>
+ <line_editor name="edit_b_value" tool_tip="ПроходимоÑÑ‚ÑŒ Ð´Ð»Ñ Ð¿ÐµÑ€Ñонажей типа B. Пример перÑонажа – ÑущеÑтво."/>
+ <text name="edit_c_label">
+ C
+ </text>
+ <line_editor name="edit_c_value" tool_tip="ПроходимоÑÑ‚ÑŒ Ð´Ð»Ñ Ð¿ÐµÑ€Ñонажей типа C. Пример перÑонажа – механизм."/>
+ <text name="edit_d_label">
+ D
+ </text>
+ <line_editor name="edit_d_value" tool_tip="ПроходимоÑÑ‚ÑŒ Ð´Ð»Ñ Ð¿ÐµÑ€Ñонажей типа D. Пример перÑонажа – иное."/>
+ <button label="Применить изменениÑ" name="apply_edit_values"/>
+ <text name="suggested_use_a_label">
+ (Гуманоид)
+ </text>
+ <text name="suggested_use_b_label">
+ (СущеÑтво)
+ </text>
+ <text name="suggested_use_c_label">
+ (Механизм)
+ </text>
+ <text name="suggested_use_d_label">
+ (Иное)
+ </text>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/ru/floater_pay.xml b/indra/newview/skins/default/xui/ru/floater_pay.xml
index 1471a7e133..1471a7e133 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_pay.xml
+++ b/indra/newview/skins/default/xui/ru/floater_pay.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_pay_object.xml b/indra/newview/skins/default/xui/ru/floater_pay_object.xml
index 7d2da44ac1..7d2da44ac1 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_pay_object.xml
+++ b/indra/newview/skins/default/xui/ru/floater_pay_object.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_people.xml b/indra/newview/skins/default/xui/ru/floater_people.xml
index 7abc34986a..7abc34986a 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_people.xml
+++ b/indra/newview/skins/default/xui/ru/floater_people.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_perm_prefs.xml b/indra/newview/skins/default/xui/ru/floater_perm_prefs.xml
index a704b87bd1..626f3c9321 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_perm_prefs.xml
+++ b/indra/newview/skins/default/xui/ru/floater_perm_prefs.xml
@@ -8,7 +8,7 @@
</text>
<check_box label="изменÑÑ‚ÑŒ" name="next_owner_modify"/>
<check_box label="копировать" name="next_owner_copy"/>
- <check_box initial_value="иÑтина" label="перепродавать/отдавать" name="next_owner_transfer"/>
+ <check_box initial_value="true" label="перепродавать/отдавать" name="next_owner_transfer"/>
</panel>
<button label="ОК" label_selected="ОК" name="ok"/>
<button label="Отмена" label_selected="Отмена" name="cancel"/>
diff --git a/indra/newview/skins/default/xui/ru/floater_picks.xml b/indra/newview/skins/default/xui/ru/floater_picks.xml
index e0ae8d6f03..e0ae8d6f03 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_picks.xml
+++ b/indra/newview/skins/default/xui/ru/floater_picks.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_places.xml b/indra/newview/skins/default/xui/ru/floater_places.xml
index 2a22a855ef..2a22a855ef 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_places.xml
+++ b/indra/newview/skins/default/xui/ru/floater_places.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_post_process.xml b/indra/newview/skins/default/xui/ru/floater_post_process.xml
index ae97670548..ae97670548 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_post_process.xml
+++ b/indra/newview/skins/default/xui/ru/floater_post_process.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_postcard.xml b/indra/newview/skins/default/xui/ru/floater_postcard.xml
deleted file mode 100644
index 889d219511..0000000000
--- a/indra/newview/skins/default/xui/ru/floater_postcard.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Postcard" title="ПОСЛÐТЬ СÐИМОК ПО EMAIL">
- <floater.string name="default_subject">
- Открытка из [SECOND_LIFE].
- </floater.string>
- <floater.string name="default_message">
- Побывай здеÑÑŒ!
- </floater.string>
- <floater.string name="upload_message">
- Отправка...
- </floater.string>
- <text name="to_label">
- Email получателÑ:
- </text>
- <text name="from_label">
- Ваш Email:
- </text>
- <text name="name_label">
- Ваше имÑ:
- </text>
- <text name="subject_label">
- Тема:
- </text>
- <line_editor label="Введите тему пиÑьма." name="subject_form"/>
- <text name="msg_label">
- Сообщение:
- </text>
- <text_editor name="msg_form">
- Введите текÑÑ‚ пиÑьма.
- </text_editor>
- <button label="Отмена" name="cancel_btn"/>
- <button label="Отправить" name="send_btn"/>
-</floater>
diff --git a/indra/newview/skins/default/xui/ru/floater_preferences.xml b/indra/newview/skins/default/xui/ru/floater_preferences.xml
index fc244b9d8b..fc244b9d8b 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_preferences.xml
+++ b/indra/newview/skins/default/xui/ru/floater_preferences.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_preferences_proxy.xml b/indra/newview/skins/default/xui/ru/floater_preferences_proxy.xml
index 4eecfedf17..13cff2bcbe 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_preferences_proxy.xml
+++ b/indra/newview/skins/default/xui/ru/floater_preferences_proxy.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="Proxy Settings Floater" title="ÐаÑтройки прокÑи-Ñервера">
- <check_box initial_value="ложь" label="ИÑпользовать HTTP-прокÑи Ð´Ð»Ñ Ð²ÐµÐ±-Ñтраниц" name="web_proxy_enabled"/>
+ <check_box initial_value="false" label="ИÑпользовать HTTP-прокÑи Ð´Ð»Ñ Ð²ÐµÐ±-Ñтраниц" name="web_proxy_enabled"/>
<text name="http_proxy_label">
HTTP-прокÑи:
</text>
diff --git a/indra/newview/skins/default/xui/ru/floater_preview_animation.xml b/indra/newview/skins/default/xui/ru/floater_preview_animation.xml
index 22c6bc5901..22c6bc5901 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_preview_animation.xml
+++ b/indra/newview/skins/default/xui/ru/floater_preview_animation.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_preview_gesture.xml b/indra/newview/skins/default/xui/ru/floater_preview_gesture.xml
index fde2cea00e..fde2cea00e 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_preview_gesture.xml
+++ b/indra/newview/skins/default/xui/ru/floater_preview_gesture.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_preview_notecard.xml b/indra/newview/skins/default/xui/ru/floater_preview_notecard.xml
index 2f39d4a4a4..2f39d4a4a4 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_preview_notecard.xml
+++ b/indra/newview/skins/default/xui/ru/floater_preview_notecard.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_preview_sound.xml b/indra/newview/skins/default/xui/ru/floater_preview_sound.xml
index 691b2f3e82..691b2f3e82 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_preview_sound.xml
+++ b/indra/newview/skins/default/xui/ru/floater_preview_sound.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_preview_texture.xml b/indra/newview/skins/default/xui/ru/floater_preview_texture.xml
index c9cb87282a..c9cb87282a 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_preview_texture.xml
+++ b/indra/newview/skins/default/xui/ru/floater_preview_texture.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_price_for_listing.xml b/indra/newview/skins/default/xui/ru/floater_price_for_listing.xml
index fd513c8cdb..fd513c8cdb 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_price_for_listing.xml
+++ b/indra/newview/skins/default/xui/ru/floater_price_for_listing.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_publish_classified.xml b/indra/newview/skins/default/xui/ru/floater_publish_classified.xml
index b9e33d6e22..b9e33d6e22 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_publish_classified.xml
+++ b/indra/newview/skins/default/xui/ru/floater_publish_classified.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_region_debug_console.xml b/indra/newview/skins/default/xui/ru/floater_region_debug_console.xml
index d413a0bdcc..d413a0bdcc 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_region_debug_console.xml
+++ b/indra/newview/skins/default/xui/ru/floater_region_debug_console.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_region_info.xml b/indra/newview/skins/default/xui/ru/floater_region_info.xml
index 011b58e385..011b58e385 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_region_info.xml
+++ b/indra/newview/skins/default/xui/ru/floater_region_info.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_report_abuse.xml b/indra/newview/skins/default/xui/ru/floater_report_abuse.xml
index 6fdbdacadc..6fdbdacadc 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_report_abuse.xml
+++ b/indra/newview/skins/default/xui/ru/floater_report_abuse.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_script_debug.xml b/indra/newview/skins/default/xui/ru/floater_script_debug.xml
index b91fc4e4ff..b91fc4e4ff 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_script_debug.xml
+++ b/indra/newview/skins/default/xui/ru/floater_script_debug.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_script_debug_panel.xml b/indra/newview/skins/default/xui/ru/floater_script_debug_panel.xml
index e70a30fa24..e70a30fa24 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_script_debug_panel.xml
+++ b/indra/newview/skins/default/xui/ru/floater_script_debug_panel.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_script_limits.xml b/indra/newview/skins/default/xui/ru/floater_script_limits.xml
index 7805eac03b..7805eac03b 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_script_limits.xml
+++ b/indra/newview/skins/default/xui/ru/floater_script_limits.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_script_preview.xml b/indra/newview/skins/default/xui/ru/floater_script_preview.xml
index 78cefb7aa7..78cefb7aa7 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_script_preview.xml
+++ b/indra/newview/skins/default/xui/ru/floater_script_preview.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_script_queue.xml b/indra/newview/skins/default/xui/ru/floater_script_queue.xml
index 4f2e389b19..4f2e389b19 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_script_queue.xml
+++ b/indra/newview/skins/default/xui/ru/floater_script_queue.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_script_search.xml b/indra/newview/skins/default/xui/ru/floater_script_search.xml
index fc040f6593..fc040f6593 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_script_search.xml
+++ b/indra/newview/skins/default/xui/ru/floater_script_search.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_search.xml b/indra/newview/skins/default/xui/ru/floater_search.xml
index 405a6598ac..405a6598ac 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_search.xml
+++ b/indra/newview/skins/default/xui/ru/floater_search.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_select_key.xml b/indra/newview/skins/default/xui/ru/floater_select_key.xml
index 99c2b9a2c4..99c2b9a2c4 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_select_key.xml
+++ b/indra/newview/skins/default/xui/ru/floater_select_key.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_sell_land.xml b/indra/newview/skins/default/xui/ru/floater_sell_land.xml
index e15f761101..e15f761101 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_sell_land.xml
+++ b/indra/newview/skins/default/xui/ru/floater_sell_land.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_settings_debug.xml b/indra/newview/skins/default/xui/ru/floater_settings_debug.xml
index 7db014ef53..db78d11e90 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_settings_debug.xml
+++ b/indra/newview/skins/default/xui/ru/floater_settings_debug.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="settings_debug" title="ÐÐСТРОЙКИ ОТЛÐДКИ">
<radio_group name="boolean_combo">
- <radio_item label="ИСТИÐÐ" name="TRUE" value="иÑтина"/>
+ <radio_item label="ИСТИÐÐ" name="TRUE" value="true"/>
<radio_item label="ЛОЖЬ" name="FALSE" value=""/>
</radio_group>
<color_swatch label="Цвет" name="val_color_swatch"/>
diff --git a/indra/newview/skins/default/xui/ru/floater_snapshot.xml b/indra/newview/skins/default/xui/ru/floater_snapshot.xml
index 7e88630b32..7e88630b32 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_snapshot.xml
+++ b/indra/newview/skins/default/xui/ru/floater_snapshot.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_sound_devices.xml b/indra/newview/skins/default/xui/ru/floater_sound_devices.xml
index fc8de858cd..fc8de858cd 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_sound_devices.xml
+++ b/indra/newview/skins/default/xui/ru/floater_sound_devices.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_sound_preview.xml b/indra/newview/skins/default/xui/ru/floater_sound_preview.xml
index 6fdb12b76b..6fdb12b76b 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_sound_preview.xml
+++ b/indra/newview/skins/default/xui/ru/floater_sound_preview.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_spellcheck.xml b/indra/newview/skins/default/xui/ru/floater_spellcheck.xml
new file mode 100755
index 0000000000..691b4a89c3
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/floater_spellcheck.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="spellcheck_floater" title="ÐаÑтройки проверки правопиÑаниÑ">
+ <check_box label="Включить проверку правопиÑаниÑ" name="spellcheck_enable"/>
+ <text name="spellcheck_main">
+ ОÑновной Ñловарь:
+ </text>
+ <text label="Журналы:" name="spellcheck_additional">
+ Дополнительные Ñловари:
+ </text>
+ <text name="spellcheck_available">
+ ДоÑтупно
+ </text>
+ <text name="spellcheck_active">
+ Ðктивно
+ </text>
+ <button label="Удалить" name="spellcheck_remove_btn"/>
+ <button label="Импорт..." name="spellcheck_import_btn"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/ru/floater_spellcheck_import.xml b/indra/newview/skins/default/xui/ru/floater_spellcheck_import.xml
new file mode 100755
index 0000000000..a01866db73
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/floater_spellcheck_import.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="spellcheck_import" title="Импорт ÑловарÑ">
+ <button label="Обзор" label_selected="Обзор" name="dictionary_path_browse"/>
+ <button label="Импорт" name="ok_btn"/>
+ <button label="Отмена" name="cancel_btn"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/ru/floater_stats.xml b/indra/newview/skins/default/xui/ru/floater_stats.xml
index b1f60c8029..46426495dc 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_stats.xml
+++ b/indra/newview/skins/default/xui/ru/floater_stats.xml
@@ -14,8 +14,11 @@
<stat_bar label="Треугольников в Ñекунду" name="ktrissec"/>
<stat_bar label="Ð’Ñего объектов" name="objs"/>
<stat_bar label="Ðовых объектов" name="newobjs"/>
+ <stat_bar label="ЧаÑтота попаданий в кÑш объектов" name="object_cache_hits"/>
</stat_view>
<stat_view label="ТекÑтура" name="texture">
+ <stat_bar label="ЧаÑтота попаданий в кÑш" name="texture_cache_hits"/>
+ <stat_bar label="Задержка Ñ‡Ñ‚ÐµÐ½Ð¸Ñ ÐºÑша" name="texture_cache_read_latency"/>
<stat_bar label="КоличеÑтво" name="numimagesstat"/>
<stat_bar label="Ðеобраб. изображений" name="numrawimagesstat"/>
<stat_bar label="ПамÑÑ‚ÑŒ GL" name="gltexmemstat"/>
@@ -50,7 +53,13 @@
<stat_bar label="Объекты" name="simobjects"/>
<stat_bar label="Ðктивные объекты" name="simactiveobjects"/>
<stat_bar label="Ðктивные Ñкрипты" name="simactivescripts"/>
+ <stat_bar label="Запущенные Ñкрипты" name="simpctscriptsrun"/>
<stat_bar label="Ð¡Ð¾Ð±Ñ‹Ñ‚Ð¸Ñ Ñкрипта" name="simscripteps"/>
+ <stat_view label="ПоиÑк пути" name="simpathfinding">
+ <stat_bar label="Ð’Ñ€ÐµÐ¼Ñ ÑˆÐ°Ð³Ð° ИИ" name="simsimaistepmsec"/>
+ <stat_bar label="Пропущенные ÑилуÑтные шаги" name="simsimskippedsilhouettesteps"/>
+ <stat_bar label="Обновленные перÑонажи" name="simsimpctsteppedcharacters"/>
+ </stat_view>
<stat_bar label="ВходÑщие пакеты" name="siminpps"/>
<stat_bar label="ИÑходÑщие пакеты" name="simoutpps"/>
<stat_bar label="Отложенные загрузки" name="simpendingdownloads"/>
diff --git a/indra/newview/skins/default/xui/ru/floater_sys_well.xml b/indra/newview/skins/default/xui/ru/floater_sys_well.xml
index b6975ac9ab..b6975ac9ab 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_sys_well.xml
+++ b/indra/newview/skins/default/xui/ru/floater_sys_well.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_telehub.xml b/indra/newview/skins/default/xui/ru/floater_telehub.xml
index 799fd57b5b..799fd57b5b 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_telehub.xml
+++ b/indra/newview/skins/default/xui/ru/floater_telehub.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_test_layout_stacks.xml b/indra/newview/skins/default/xui/ru/floater_test_layout_stacks.xml
index b479d5f6d6..b479d5f6d6 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_test_layout_stacks.xml
+++ b/indra/newview/skins/default/xui/ru/floater_test_layout_stacks.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_test_text_vertical_aligment.xml b/indra/newview/skins/default/xui/ru/floater_test_text_vertical_aligment.xml
index d0bd86160e..d0bd86160e 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_test_text_vertical_aligment.xml
+++ b/indra/newview/skins/default/xui/ru/floater_test_text_vertical_aligment.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/ru/floater_texture_ctrl.xml
index d55daea836..c9e117362f 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_texture_ctrl.xml
+++ b/indra/newview/skins/default/xui/ru/floater_texture_ctrl.xml
@@ -9,15 +9,27 @@
<text name="Multiple">
ÐеÑколько текÑтур
</text>
+ <radio_group name="mode_selection">
+ <radio_item label="Инвентарь" name="inventory" value="0"/>
+ <radio_item label="Локально" name="local" value="1"/>
+ </radio_group>
<text name="unknown">
Размер: [DIMENSIONS]
</text>
<button label="По умолчанию" label_selected="По умолчанию" name="Default"/>
- <button label="Ðет" label_selected="Ðет" name="None"/>
<button label="ОчиÑтить" label_selected="ОчиÑтить" name="Blank"/>
- <check_box initial_value="иÑтина" label="Применить ÑейчаÑ" name="apply_immediate_check"/>
+ <button label="Ðет" label_selected="Ðет" name="None"/>
+ <check_box initial_value="true" label="Применить ÑейчаÑ" name="apply_immediate_check"/>
+ <text name="preview_disabled" value="ПроÑмотр отключен"/>
<filter_editor label="Фильтровать текÑтуры" name="inventory search editor"/>
- <check_box initial_value="ложь" label="Показывать папки" name="show_folders_check"/>
+ <check_box initial_value="false" label="Показывать папки" name="show_folders_check"/>
+ <button label="Добавить" label_selected="Добавить" name="l_add_btn"/>
+ <button label="Удалить" label_selected="Удалить" name="l_rem_btn"/>
+ <button label="Передать" label_selected="Передать" name="l_upl_btn"/>
+ <scroll_list name="l_name_list">
+ <column label="ИмÑ" name="unit_name"/>
+ <column label="ID" name="unit_id_HIDDEN"/>
+ </scroll_list>
<button label="ОК" label_selected="ОК" name="Select"/>
<button label="Отмена" label_selected="Отмена" name="Cancel"/>
</floater>
diff --git a/indra/newview/skins/default/xui/ru/floater_texture_fetch_debugger.xml b/indra/newview/skins/default/xui/ru/floater_texture_fetch_debugger.xml
new file mode 100755
index 0000000000..628e6c5c87
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/floater_texture_fetch_debugger.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="TexFetchDebugger" title="Отладчик Ð¸Ð·Ð²Ð»ÐµÑ‡ÐµÐ½Ð¸Ñ Ñ‚ÐµÐºÑтур">
+ <text name="total_num_fetched_label">
+ 1, Общее количеÑтво извлеченных текÑтур: [NUM]
+ </text>
+ <text name="total_num_fetching_requests_label">
+ 2, Общее количеÑтво запроÑов на извлечение: [NUM]
+ </text>
+ <text name="total_num_cache_hits_label">
+ 3, Общее количеÑтво попаданий в кÑш: [NUM]
+ </text>
+ <text name="total_num_visible_tex_label">
+ 4, Общее количеÑтво видимых текÑтур: [NUM]
+ </text>
+ <text name="total_num_visible_tex_fetch_req_label">
+ 5, Общее количеÑтво запроÑов на извлечение видимых текÑтур: [NUM]
+ </text>
+ <text name="total_fetched_data_label">
+ 6, Общий объем извлеченных данных: [SIZE1] КБ, декодированные данные: [SIZE2] КБ, [PIXEL] МпикÑелов
+ </text>
+ <text name="total_fetched_vis_data_label">
+ 7, Общий объем видимых данных: [SIZE1] КБ, декодированные данные: [SIZE2] КБ
+ </text>
+ <text name="total_fetched_rendered_data_label">
+ 8, Общий объем визуализированных данных: [SIZE1] КБ, декодированные данные: [SIZE2] КБ, [PIXEL] МпикÑелов
+ </text>
+ <text name="total_time_cache_read_label">
+ 9, Общее Ð²Ñ€ÐµÐ¼Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ Ð¸Ð· кÑша: [TIME] Ñ
+ </text>
+ <text name="total_time_cache_write_label">
+ 10, Общее Ð²Ñ€ÐµÐ¼Ñ Ð·Ð°Ð¿Ð¸Ñи в кÑш: [TIME] Ñ
+ </text>
+ <text name="total_time_decode_label">
+ 11, Общее Ð²Ñ€ÐµÐ¼Ñ Ð´ÐµÐºÐ¾Ð´Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ: [TIME] Ñ
+ </text>
+ <text name="total_time_gl_label">
+ 12, Общее Ð²Ñ€ÐµÐ¼Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ñ‚ÐµÐºÑтур: [TIME] Ñ
+ </text>
+ <text name="total_time_http_label">
+ 13, Общее Ð²Ñ€ÐµÐ¼Ñ HTTP-извлечениÑ: [TIME] Ñ
+ </text>
+ <text name="total_time_fetch_label">
+ 14, Общее Ð²Ñ€ÐµÐ¼Ñ Ð¿Ð¾Ð»Ð½Ð¾Ð³Ð¾ извлечениÑ: [TIME] Ñ
+ </text>
+ <text name="total_time_refetch_vis_cache_label">
+ 15, Повторное извлечение из кÑша, времÑ: [TIME] Ñ, извлечено: [SIZE] КБ, [PIXEL] МпикÑелов
+ </text>
+ <text name="total_time_refetch_all_cache_label">
+ 16, Повторное извлечение вÑех текÑтур из кÑша, времÑ: [TIME] Ñ, извлечено: [SIZE] КБ, [PIXEL] МпикÑелов
+ </text>
+ <text name="total_time_refetch_vis_http_label">
+ 17, Повторное извлечение из HTTP, времÑ: [TIME] Ñ, извлечено: [SIZE] КБ, [PIXEL] МпикÑелов
+ </text>
+ <text name="total_time_refetch_all_http_label">
+ 18, Повторное извлечение вÑех текÑтур из HTTP, времÑ: [TIME] Ñ, извлечено: [SIZE] КБ, [PIXEL] МпикÑелов
+ </text>
+ <spinner label="19, Отношение текÑелы/пикÑелы:" name="texel_pixel_ratio"/>
+ <text name="texture_source_label">
+ 20, ИÑтоÑник текÑтур:
+ </text>
+ <radio_group name="texture_source">
+ <radio_item label="КÑш + HTTP" name="0"/>
+ <radio_item label="Только HTTP" name="1"/>
+ </radio_group>
+ <button label="ПуÑк" name="start_btn"/>
+ <button label="СброÑ" name="clear_btn"/>
+ <button label="Закрыть" name="close_btn"/>
+ <button label="Чтение кÑша" name="cacheread_btn"/>
+ <button label="ЗапиÑÑŒ в кÑш" name="cachewrite_btn"/>
+ <button label="HTTP" name="http_btn"/>
+ <button label="Декодировать" name="decode_btn"/>
+ <button label="ТекÑтура GL" name="gl_btn"/>
+ <button label="Повторно извлечь из кÑша" name="refetchviscache_btn"/>
+ <button label="Повторно извлечь вÑе из кÑша" name="refetchallcache_btn"/>
+ <button label="Повторно извлечь из HTTP" name="refetchvishttp_btn"/>
+ <button label="Повторно извлечь вÑе из HTTP" name="refetchallhttp_btn"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/ru/floater_tools.xml b/indra/newview/skins/default/xui/ru/floater_tools.xml
index 3d7d1198f0..35921d147f 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_tools.xml
+++ b/indra/newview/skins/default/xui/ru/floater_tools.xml
@@ -76,8 +76,8 @@
<text label="РаÑÑ‚Ñжка обеих Ñторон" name="checkbox uniform label">
РаÑÑ‚Ñжка обеих Ñторон
</text>
- <check_box initial_value="иÑтина" label="РаÑÑ‚Ñгивать текÑтуры" name="checkbox stretch textures"/>
- <check_box initial_value="иÑтина" label="ПривÑзка" name="checkbox snap to grid"/>
+ <check_box initial_value="true" label="РаÑÑ‚Ñгивать текÑтуры" name="checkbox stretch textures"/>
+ <check_box initial_value="true" label="ПривÑзка" name="checkbox snap to grid"/>
<combo_box name="combobox grid mode" tool_tip="Выберите тип линейки Ñетки Ð´Ð»Ñ Ñ€Ð°Ð·Ð¼ÐµÑ‰ÐµÐ½Ð¸Ñ Ð¾Ð±ÑŠÐµÐºÑ‚Ð°">
<combo_box.item label="МироваÑ" name="World"/>
<combo_box.item label="ЛокальнаÑ" name="Local"/>
@@ -101,7 +101,7 @@
<button name="ToolGrass" tool_tip="Трава"/>
<check_box label="Держать инÑтрумент" name="checkbox sticky"/>
<check_box label="Копировать выдел." name="checkbox copy selection"/>
- <check_box initial_value="иÑтина" label="Центрир. копию" name="checkbox copy centers"/>
+ <check_box initial_value="true" label="Центрир. копию" name="checkbox copy centers"/>
<check_box label="Повернуть копию" name="checkbox copy rotates"/>
<radio_group name="land_radio_group">
<radio_item label="Выбрать землю" name="radio select land"/>
@@ -150,6 +150,12 @@
<panel.string name="text modify info 4">
Эти объекты Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ð·Ð¼ÐµÐ½ÑÑ‚ÑŒ
</panel.string>
+ <panel.string name="text modify info 5">
+ Этот объект Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ð·Ð¼ÐµÐ½ÑÑ‚ÑŒ через границу региона
+ </panel.string>
+ <panel.string name="text modify info 6">
+ Эти объекты Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ð·Ð¼ÐµÐ½ÑÑ‚ÑŒ через границу региона
+ </panel.string>
<panel.string name="text modify warning">
Чтобы задать права доÑтупа, нужно выделить объект целиком
</panel.string>
@@ -199,12 +205,12 @@
<combo_box.item label="Увеличение" name="Zoom"/>
</combo_box>
<check_box label="Ð”Ð»Ñ Ð¿Ñ€Ð¾Ð´Ð°Ð¶Ð¸:" name="checkbox for sale"/>
+ <spinner label="L$" name="Edit Cost"/>
<combo_box name="sale type">
<combo_box.item label="Копировать" name="Copy"/>
<combo_box.item label="Контент" name="Contents"/>
<combo_box.item label="Оригинал" name="Original"/>
</combo_box>
- <spinner label="Цена: L$" name="Edit Cost"/>
<check_box label="Показать в поиÑке" name="search_check" tool_tip="Показывать объект в результатах поиÑка"/>
<panel name="perms_build">
<text name="perm_modify">
@@ -240,6 +246,11 @@
F:
</text>
</panel>
+ <panel name="pathfinding_attrs_panel">
+ <text name="pathfinding_attributes_label">
+ Ðтрибуты поиÑка пути:
+ </text>
+ </panel>
</panel>
<panel label="Объект" name="Object">
<check_box label="ФикÑированный" name="checkbox locked" tool_tip="Предотвращение Ð¿ÐµÑ€ÐµÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ Ð¸Ð»Ð¸ ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ñ Ð¾Ð±ÑŠÐµÐºÑ‚Ð°. Обычно Ñта Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð¿Ð¾Ð»ÐµÐ·Ð½Ð° во Ð²Ñ€ÐµÐ¼Ñ Ñтройки Ð´Ð»Ñ Ð¸Ð·Ð±ÐµÐ¶Ð°Ð½Ð¸Ñ Ð½ÐµÐ¶ÐµÐ»Ð°Ñ‚ÐµÐ»ÑŒÐ½Ñ‹Ñ… изменений."/>
@@ -454,16 +465,11 @@
<combo_box.item label="приÑоÑка" name="suction"/>
<combo_box.item label="переплетение" name="weave"/>
</combo_box>
- <check_box initial_value="ложь" label="СоглаÑование" name="checkbox planar align" tool_tip="СоглаÑование текÑтур на вÑех выбранных граних по поÑледней выбранной грани. Должно быть выбрано наложение по плоÑкоÑÑ‚Ñм."/>
- <text name="rpt">
- Повторов на грань
- </text>
<spinner label="По горизонтали (U)" name="TexScaleU"/>
<check_box label="Разворот" name="checkbox flip s"/>
<spinner label="По вертикали (V)" name="TexScaleV"/>
<check_box label="Разворот" name="checkbox flip t"/>
<spinner label="Вращение˚" name="TexRot"/>
- <spinner label="Повторов на метр" name="rptctrl"/>
<button label="Применить" label_selected="Применить" name="button apply"/>
<text name="tex offset">
Сдвиг текÑтуры
diff --git a/indra/newview/skins/default/xui/ru/floater_top_objects.xml b/indra/newview/skins/default/xui/ru/floater_top_objects.xml
index a6ffe5c030..c7ece5c9c9 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_top_objects.xml
+++ b/indra/newview/skins/default/xui/ru/floater_top_objects.xml
@@ -9,9 +9,6 @@
<floater.string name="scripts_score_label">
ВремÑ
</floater.string>
- <floater.string name="scripts_mono_time_label">
- Ð’Ñ€ÐµÐ¼Ñ Ð¼Ð¾Ð½Ð¾
- </floater.string>
<floater.string name="top_colliders_title">
Лучшие ÑтолкновениÑ
</floater.string>
@@ -32,9 +29,10 @@
<scroll_list.columns label="Ðазвание" name="name"/>
<scroll_list.columns label="Владелец" name="owner"/>
<scroll_list.columns label="МеÑто" name="location"/>
+ <scroll_list.columns label="УчаÑток" name="parcel"/>
<scroll_list.columns label="ВремÑ" name="time"/>
- <scroll_list.columns label="Ð’Ñ€ÐµÐ¼Ñ Ð¼Ð¾Ð½Ð¾" name="mono_time"/>
<scroll_list.columns label="URL-адреÑа" name="URLs"/>
+ <scroll_list.columns label="ПамÑÑ‚ÑŒ (КБ)" name="memory"/>
</scroll_list>
<text name="id_text">
ID объекта:
@@ -48,6 +46,10 @@
Владелец:
</text>
<button label="Фильтр" name="filter_owner_btn"/>
+ <text name="parcel_name_text">
+ УчаÑток:
+ </text>
+ <button label="Фильтр" name="filter_parcel_btn"/>
<button label="Вернуть выбранное" name="return_selected_btn"/>
<button label="Вернуть вÑе" name="return_all_btn"/>
<button label="Отключить выбранное" name="disable_selected_btn"/>
diff --git a/indra/newview/skins/default/xui/ru/floater_tos.xml b/indra/newview/skins/default/xui/ru/floater_tos.xml
index bd72f6b308..bd72f6b308 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_tos.xml
+++ b/indra/newview/skins/default/xui/ru/floater_tos.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_toybox.xml b/indra/newview/skins/default/xui/ru/floater_toybox.xml
index a4754ad7ab..a4754ad7ab 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_toybox.xml
+++ b/indra/newview/skins/default/xui/ru/floater_toybox.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_translation_settings.xml b/indra/newview/skins/default/xui/ru/floater_translation_settings.xml
index ad280a50dd..ad280a50dd 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_translation_settings.xml
+++ b/indra/newview/skins/default/xui/ru/floater_translation_settings.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_url_entry.xml b/indra/newview/skins/default/xui/ru/floater_url_entry.xml
index 59f8dd0c31..59f8dd0c31 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_url_entry.xml
+++ b/indra/newview/skins/default/xui/ru/floater_url_entry.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_voice_chat_volume.xml b/indra/newview/skins/default/xui/ru/floater_voice_chat_volume.xml
new file mode 100644
index 0000000000..5a7e7a7061
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/floater_voice_chat_volume.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="floater_voice_volume" title="ГРОМКОСТЬ ГОЛОСОВОГО ЧÐТÐ">
+ <slider label="ГолоÑовой чат" name="chat_voice_volume"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/ru/floater_voice_controls.xml b/indra/newview/skins/default/xui/ru/floater_voice_controls.xml
index 2b23086062..2b23086062 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_voice_controls.xml
+++ b/indra/newview/skins/default/xui/ru/floater_voice_controls.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_voice_effect.xml b/indra/newview/skins/default/xui/ru/floater_voice_effect.xml
index 1eb8a94d7a..d3cef042a3 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_voice_effect.xml
+++ b/indra/newview/skins/default/xui/ru/floater_voice_effect.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater label="МеÑта" name="voice_effects" title="ИЗМЕÐЕÐИЕ ГОЛОСÐ">
+<floater label="МеÑта" name="voice_effects" title="ПРОСМОТР ИЗМЕÐЕÐИЯ ГОЛОСÐ">
<string name="no_voice_effect">
(Ðет Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð³Ð¾Ð»Ð¾Ñа)
</string>
diff --git a/indra/newview/skins/default/xui/ru/floater_voice_volume.xml b/indra/newview/skins/default/xui/ru/floater_voice_volume.xml
new file mode 100644
index 0000000000..aca6bd518a
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/floater_voice_volume.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<!--
+ Not can_close / no title to avoid window chrome
+ Single instance - only have one at a time, recycle it each spawn
+-->
+<floater name="floater_voice_volume" title="ГРОМКОСТЬ ГОЛОСÐ">
+ <slider name="volume_slider" tool_tip="ГромкоÑÑ‚ÑŒ голоÑа" value="0.5"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/ru/floater_water.xml b/indra/newview/skins/default/xui/ru/floater_water.xml
deleted file mode 100644
index 5030351f5b..0000000000
--- a/indra/newview/skins/default/xui/ru/floater_water.xml
+++ /dev/null
@@ -1,70 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Water Floater" title="РÐСШИРЕÐÐЫЙ РЕДÐКТОР ВОДЫ">
- <floater.string name="WLDefaultWaterNames">
- По умолчанию:глÑнец:пруд:туман:Second Plague:SNAKE!!!:Valdez
- </floater.string>
- <text name="KeyFramePresetsText">
- ÐаÑтройки воды:
- </text>
- <button label="Создать" label_selected="Создать" name="WaterNewPreset"/>
- <button label="Сохранить" label_selected="Сохранить" name="WaterSavePreset"/>
- <button label="Удалить" label_selected="Удалить" name="WaterDeletePreset"/>
- <tab_container name="Water Tabs">
- <panel label="ÐÐСТРОЙКИ" name="Settings">
- <text name="BHText">
- Цвет водного тумана
- </text>
- <color_swatch name="WaterFogColor" tool_tip="Щелкните Ð´Ð»Ñ Ð²Ñ‹Ð±Ð¾Ñ€Ð° цвета"/>
- <text name="WaterFogDensText">
- ПлотноÑÑ‚ÑŒ тумана
- </text>
- <text name="WaterUnderWaterFogModText">
- Подводный туман
- </text>
- <text name="BDensText">
- Уровень Ð¾Ñ‚Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ð²Ð¾Ð»Ð½
- </text>
- <slider label="1" name="WaterNormalScaleX"/>
- <slider label="2" name="WaterNormalScaleY"/>
- <slider label="3" name="WaterNormalScaleZ"/>
- <text name="HDText">
- МаÑштаб ФренелÑ
- </text>
- <text name="FresnelOffsetText">
- Сдвиг ФренелÑ
- </text>
- <text name="DensMultText">
- Преломление над водой
- </text>
- <text name="WaterScaleBelowText">
- Преломление под водой
- </text>
- <text name="MaxAltText">
- КоÑффициент размытиÑ
- </text>
- </panel>
- <panel label="ИЗОБРÐЖЕÐИЕ" name="Waves">
- <text name="BHText">
- Ðаправление больших волн
- </text>
- <text name="WaterWave1DirXText">
- X
- </text>
- <text name="WaterWave1DirYText">
- Y
- </text>
- <text name="BHText2">
- Ðаправление маленьких волн
- </text>
- <text name="WaterWave2DirXText">
- X
- </text>
- <text name="WaterWave2DirYText">
- Y
- </text>
- <text name="BHText3">
- Карта поверхноÑти
- </text>
- </panel>
- </tab_container>
-</floater>
diff --git a/indra/newview/skins/default/xui/ru/floater_web_content.xml b/indra/newview/skins/default/xui/ru/floater_web_content.xml
index 403ab0ef5d..403ab0ef5d 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_web_content.xml
+++ b/indra/newview/skins/default/xui/ru/floater_web_content.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_whitelist_entry.xml b/indra/newview/skins/default/xui/ru/floater_whitelist_entry.xml
index 811a2756fa..811a2756fa 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_whitelist_entry.xml
+++ b/indra/newview/skins/default/xui/ru/floater_whitelist_entry.xml
diff --git a/indra/newview/skins/default/xui/ru/floater_windlight_options.xml b/indra/newview/skins/default/xui/ru/floater_windlight_options.xml
deleted file mode 100644
index bbb37aaaa0..0000000000
--- a/indra/newview/skins/default/xui/ru/floater_windlight_options.xml
+++ /dev/null
@@ -1,167 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="WindLight floater" title="РÐСШИРЕÐÐЫЙ РЕДÐКТОР ÐЕБÐ">
- <floater.string name="WLDefaultSkyNames">
- A-12AM:A-12PM:A-3AM:A-3PM:A-4.30PM:A-6AM:A-6PM:A-9AM:A-9PM:Barcelona:Blizzard:Blue Midday:Coastal Afternoon:Coastal Sunset:Default:Desert Sunset:Fine Day:Fluffy Big Clouds:Foggy:Funky Funky:Funky Funky Funky:Gelatto:Ghost:Incongruent Truths:Midday 1:Midday 2:Midday 3:Midday 4:Night:Pirate:Purple:Sailor&apos;s Delight:Sheer Sensuality
- </floater.string>
- <text name="KeyFramePresetsText">
- ÐаÑтройки неба:
- </text>
- <button label="ÐоваÑ" label_selected="ÐоваÑ" name="WLNewPreset"/>
- <button label="Сохранить" label_selected="Сохранить" name="WLSavePreset"/>
- <button label="Удалить" label_selected="Удалить" name="WLDeletePreset"/>
- <button label="Редактор Ñуточных циклов" label_selected="Редактор Ñуточных циклов" name="WLDayCycleMenuButton"/>
- <tab_container name="WindLight Tabs">
- <panel label="ÐТМОСФЕРÐ" name="Atmosphere">
- <text name="BHText">
- Голубой горизонт
- </text>
- <text name="BHText2">
- R
- </text>
- <text name="BHText3">
- G
- </text>
- <text name="BHText4">
- B
- </text>
- <text name="BHText5">
- I
- </text>
- <text name="BDensText">
- Дымка на горизонте
- </text>
- <text name="BDensText2">
- ÐаÑыщенноÑÑ‚ÑŒ голубого
- </text>
- <text name="BHText6">
- R
- </text>
- <text name="BHText7">
- G
- </text>
- <text name="BHText8">
- B
- </text>
- <text name="BHText9">
- I
- </text>
- <text name="HDText">
- ПлотноÑÑ‚ÑŒ дымки
- </text>
- <text name="DensMultText">
- КоÑффициент плотноÑти
- </text>
- <text name="WLDistanceMultText">
- КоÑффициент раÑÑтоÑниÑ
- </text>
- <text name="MaxAltText">
- МакÑÐ¸Ð¼Ð°Ð»ÑŒÐ½Ð°Ñ Ð²Ñ‹Ñота
- </text>
- </panel>
- <panel label="ОСВЕЩЕÐИЕ" name="Lighting">
- <text name="SLCText">
- Цвет Ñолнца/луны
- </text>
- <text name="BHText">
- R
- </text>
- <text name="BHText2">
- G
- </text>
- <text name="BHText3">
- B
- </text>
- <text name="BHText4">
- I
- </text>
- <text name="TODText">
- Положение Ñолнца/луны
- </text>
- <text name="WLAmbientText">
- РаÑÑеÑнное
- </text>
- <text name="BHText5">
- R
- </text>
- <text name="BHText6">
- G
- </text>
- <text name="BHText7">
- B
- </text>
- <text name="BHText8">
- I
- </text>
- <text name="WLEastAngleText">
- Смещение отноÑительно воÑтока
- </text>
- <text name="SunGlowText">
- СиÑние Ñолнца
- </text>
- <slider label="ФокуÑ" name="WLGlowB"/>
- <slider label="Размер" name="WLGlowR"/>
- <text name="SceneGammaText">
- Гамма-ÐºÐ¾Ñ€Ñ€ÐµÐºÑ†Ð¸Ñ Ñцены
- </text>
- <text name="WLStarText">
- ЯркоÑÑ‚ÑŒ звезд
- </text>
- </panel>
- <panel label="ОБЛÐКÐ" name="Clouds">
- <text name="WLCloudColorText">
- Цвет
- </text>
- <text name="BHText">
- R
- </text>
- <text name="BHText2">
- G
- </text>
- <text name="BHText3">
- B
- </text>
- <text name="BHText4">
- I
- </text>
- <text name="WLCloudColorText2">
- Положение и плотноÑÑ‚ÑŒ
- </text>
- <text name="BHText5">
- X
- </text>
- <text name="BHText6">
- Y
- </text>
- <text name="BHText7">
- П
- </text>
- <text name="WLCloudCoverageText">
- ОблачноÑÑ‚ÑŒ
- </text>
- <text name="WLCloudScaleText">
- Размеры
- </text>
- <text name="WLCloudDetailText">
- Ð”ÐµÑ‚Ð°Ð»Ð¸Ð·Ð°Ñ†Ð¸Ñ (положение/плотноÑÑ‚ÑŒ)
- </text>
- <text name="BHText8">
- X
- </text>
- <text name="BHText9">
- Y
- </text>
- <text name="BHText10">
- П
- </text>
- <text name="WLCloudScrollXText">
- СкороÑÑ‚ÑŒ по X
- </text>
- <check_box label="Ðа меÑте" name="WLCloudLockX"/>
- <text name="WLCloudScrollYText">
- СкороÑÑ‚ÑŒ по Y
- </text>
- <check_box label="Ðа меÑте" name="WLCloudLockY"/>
- <check_box label="Создать клаÑÑичеÑкие облака" name="DrawClassicClouds"/>
- </panel>
- </tab_container>
-</floater>
diff --git a/indra/newview/skins/default/xui/ru/floater_window_size.xml b/indra/newview/skins/default/xui/ru/floater_window_size.xml
index 24865a6ba5..fbff6a72b2 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_window_size.xml
+++ b/indra/newview/skins/default/xui/ru/floater_window_size.xml
@@ -7,10 +7,17 @@
Задать размер окна:
</text>
<combo_box name="window_size_combo" tool_tip="ширина x выÑота">
- <combo_box.item label="1000 x 700 (по умолчанию)" name="item0"/>
- <combo_box.item label="1024 x 768" name="item1"/>
- <combo_box.item label="1280 x 720 (720p)" name="item2"/>
- <combo_box.item label="1920 x 1080 (1080p)" name="item3"/>
+ <combo_box.item label="1000 x 700 (по умолчанию)" name="item1"/>
+ <combo_box.item label="1024 x 768 (4:3 XGA)" name="item2"/>
+ <combo_box.item label="1280 x 720 (16:9 HDTV)" name="item3"/>
+ <combo_box.item label="1280 x 800 (5:8 WXGA)" name="item4"/>
+ <combo_box.item label="1280 x 1024 (5:4 WXGA)" name="item5"/>
+ <combo_box.item label="1440 x 900 (8:5 WSXGA)" name="item7"/>
+ <combo_box.item label="1600 x 900 (16:9 HD+)" name="item8"/>
+ <combo_box.item label="1600 x 1200 (4:3 UXGA)" name="item9"/>
+ <combo_box.item label="1680 x 1050 (8:5 WSXGA)" name="item10"/>
+ <combo_box.item label="1920 x 1080 (16:9 HDTV)" name="item11"/>
+ <combo_box.item label="1920 x 1200 (8:5 UXGA)" name="item12"/>
</combo_box>
<button label="Задать" name="set_btn"/>
<button label="Отмена" name="cancel_btn"/>
diff --git a/indra/newview/skins/default/xui/ru/floater_world_map.xml b/indra/newview/skins/default/xui/ru/floater_world_map.xml
index ef8dfe22ae..7d2acfd9a0 100644..100755
--- a/indra/newview/skins/default/xui/ru/floater_world_map.xml
+++ b/indra/newview/skins/default/xui/ru/floater_world_map.xml
@@ -35,7 +35,7 @@
<text name="pg_label">
Общие
</text>
- <check_box initial_value="иÑтина" name="events_mature_chk"/>
+ <check_box initial_value="true" name="events_mature_chk"/>
<text name="events_mature_label">
Умеренные
</text>
diff --git a/indra/newview/skins/default/xui/ru/inspect_avatar.xml b/indra/newview/skins/default/xui/ru/inspect_avatar.xml
index e38ae967cc..e38ae967cc 100644..100755
--- a/indra/newview/skins/default/xui/ru/inspect_avatar.xml
+++ b/indra/newview/skins/default/xui/ru/inspect_avatar.xml
diff --git a/indra/newview/skins/default/xui/ru/inspect_group.xml b/indra/newview/skins/default/xui/ru/inspect_group.xml
index ca600b0a1f..ca600b0a1f 100644..100755
--- a/indra/newview/skins/default/xui/ru/inspect_group.xml
+++ b/indra/newview/skins/default/xui/ru/inspect_group.xml
diff --git a/indra/newview/skins/default/xui/ru/inspect_object.xml b/indra/newview/skins/default/xui/ru/inspect_object.xml
index 1a43357cd3..1a43357cd3 100644..100755
--- a/indra/newview/skins/default/xui/ru/inspect_object.xml
+++ b/indra/newview/skins/default/xui/ru/inspect_object.xml
diff --git a/indra/newview/skins/default/xui/ru/inspect_remote_object.xml b/indra/newview/skins/default/xui/ru/inspect_remote_object.xml
index eec4817f02..eec4817f02 100644..100755
--- a/indra/newview/skins/default/xui/ru/inspect_remote_object.xml
+++ b/indra/newview/skins/default/xui/ru/inspect_remote_object.xml
diff --git a/indra/newview/skins/default/xui/ru/menu_add_wearable_gear.xml b/indra/newview/skins/default/xui/ru/menu_add_wearable_gear.xml
index 786e571527..786e571527 100644..100755
--- a/indra/newview/skins/default/xui/ru/menu_add_wearable_gear.xml
+++ b/indra/newview/skins/default/xui/ru/menu_add_wearable_gear.xml
diff --git a/indra/newview/skins/default/xui/ru/menu_attachment_other.xml b/indra/newview/skins/default/xui/ru/menu_attachment_other.xml
index fb1c24448b..76acb32a64 100644..100755
--- a/indra/newview/skins/default/xui/ru/menu_attachment_other.xml
+++ b/indra/newview/skins/default/xui/ru/menu_attachment_other.xml
@@ -11,7 +11,9 @@
<menu_item_call label="Заморозить" name="Freeze..."/>
<menu_item_call label="Выкинуть" name="Eject..."/>
<menu_item_call label="Отладка текÑтур" name="Debug..."/>
+ <menu_item_call label="Вывод XML" name="Dump XML"/>
<menu_item_call label="Приблизить" name="Zoom In"/>
<menu_item_call label="Заплатить" name="Pay..."/>
<menu_item_call label="Профиль объекта" name="Object Inspect"/>
+ <menu_item_call label="Блокировать владельца учаÑтка" name="Mute Particle"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/ru/menu_attachment_self.xml b/indra/newview/skins/default/xui/ru/menu_attachment_self.xml
index f241b48871..2b1291a8d5 100644..100755
--- a/indra/newview/skins/default/xui/ru/menu_attachment_self.xml
+++ b/indra/newview/skins/default/xui/ru/menu_attachment_self.xml
@@ -12,5 +12,7 @@
<menu_item_call label="Мои группы" name="Groups..."/>
<menu_item_call label="Мой профиль" name="Profile..."/>
<menu_item_call label="Отладка текÑтур" name="Debug..."/>
+ <menu_item_call label="Вывод XML" name="Dump XML"/>
<menu_item_call label="БроÑить" name="Drop"/>
+ <menu_item_call label="Блокировать владельца учаÑтка" name="Mute Particle"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/ru/menu_avatar_icon.xml b/indra/newview/skins/default/xui/ru/menu_avatar_icon.xml
index ac2b4be003..ac2b4be003 100644..100755
--- a/indra/newview/skins/default/xui/ru/menu_avatar_icon.xml
+++ b/indra/newview/skins/default/xui/ru/menu_avatar_icon.xml
diff --git a/indra/newview/skins/default/xui/ru/menu_avatar_other.xml b/indra/newview/skins/default/xui/ru/menu_avatar_other.xml
index fb283c9d80..dfe3c2e701 100644..100755
--- a/indra/newview/skins/default/xui/ru/menu_avatar_other.xml
+++ b/indra/newview/skins/default/xui/ru/menu_avatar_other.xml
@@ -11,6 +11,8 @@
<menu_item_call label="Заморозить" name="Freeze..."/>
<menu_item_call label="Выкинуть" name="Eject..."/>
<menu_item_call label="Отладка текÑтур" name="Debug..."/>
+ <menu_item_call label="Вывод XML" name="Dump XML"/>
<menu_item_call label="Приблизить" name="Zoom In"/>
<menu_item_call label="Заплатить" name="Pay..."/>
+ <menu_item_call label="Блокировать владельца учаÑтка" name="Mute Particle"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/ru/menu_avatar_self.xml b/indra/newview/skins/default/xui/ru/menu_avatar_self.xml
index b72f3dcc42..e09117226c 100644..100755
--- a/indra/newview/skins/default/xui/ru/menu_avatar_self.xml
+++ b/indra/newview/skins/default/xui/ru/menu_avatar_self.xml
@@ -29,4 +29,6 @@
<menu_item_call label="Мои группы" name="Groups..."/>
<menu_item_call label="Мой профиль" name="Profile..."/>
<menu_item_call label="Отладка текÑтур" name="Debug..."/>
+ <menu_item_call label="Вывод XML" name="Dump XML"/>
+ <menu_item_call label="Блокировать владельца учаÑтка" name="Mute Particle"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/ru/menu_bottomtray.xml b/indra/newview/skins/default/xui/ru/menu_bottomtray.xml
deleted file mode 100644
index fa3558945b..0000000000
--- a/indra/newview/skins/default/xui/ru/menu_bottomtray.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<menu name="hide_camera_move_controls_menu">
- <menu_item_check label="Кнопка разговора" name="EnableVoiceChat"/>
- <menu_item_check label="Кнопка жеÑтов" name="ShowGestureButton"/>
- <menu_item_check label="Кнопка движениÑ" name="ShowMoveButton"/>
- <menu_item_check label="Кнопка камеры" name="ShowCameraButton"/>
- <menu_item_check label="Кнопка Ñнимка" name="ShowSnapshotButton"/>
- <menu_item_check label="Кнопка ÑтроительÑтва" name="ShowBuildButton"/>
- <menu_item_check label="Кнопка поиÑка" name="ShowSearchButton"/>
- <menu_item_check label="Кнопка карты" name="ShowWorldMapButton"/>
- <menu_item_check label="Кнопка миникарты" name="ShowMiniMapButton"/>
- <menu_item_call label="Вырезать" name="NearbyChatBar_Cut"/>
- <menu_item_call label="Копировать" name="NearbyChatBar_Copy"/>
- <menu_item_call label="Ð’Ñтавить" name="NearbyChatBar_Paste"/>
- <menu_item_call label="Удалить" name="NearbyChatBar_Delete"/>
- <menu_item_call label="Выделить вÑе" name="NearbyChatBar_Select_All"/>
-</menu>
diff --git a/indra/newview/skins/default/xui/ru/menu_cof_attachment.xml b/indra/newview/skins/default/xui/ru/menu_cof_attachment.xml
index 72d1bc52b5..72d1bc52b5 100644..100755
--- a/indra/newview/skins/default/xui/ru/menu_cof_attachment.xml
+++ b/indra/newview/skins/default/xui/ru/menu_cof_attachment.xml
diff --git a/indra/newview/skins/default/xui/ru/menu_cof_body_part.xml b/indra/newview/skins/default/xui/ru/menu_cof_body_part.xml
index ee0a0c70ed..ee0a0c70ed 100644..100755
--- a/indra/newview/skins/default/xui/ru/menu_cof_body_part.xml
+++ b/indra/newview/skins/default/xui/ru/menu_cof_body_part.xml
diff --git a/indra/newview/skins/default/xui/ru/menu_cof_clothing.xml b/indra/newview/skins/default/xui/ru/menu_cof_clothing.xml
index bbdf4fd0d4..bbdf4fd0d4 100644..100755
--- a/indra/newview/skins/default/xui/ru/menu_cof_clothing.xml
+++ b/indra/newview/skins/default/xui/ru/menu_cof_clothing.xml
diff --git a/indra/newview/skins/default/xui/ru/menu_cof_gear.xml b/indra/newview/skins/default/xui/ru/menu_cof_gear.xml
index 0332c03a04..b7a32dfd75 100644..100755
--- a/indra/newview/skins/default/xui/ru/menu_cof_gear.xml
+++ b/indra/newview/skins/default/xui/ru/menu_cof_gear.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<toggleable_menu name="Gear COF">
<menu label="ÐÐ¾Ð²Ð°Ñ Ð¾Ð´ÐµÐ¶Ð´Ð°" name="COF.Gear.New_Clothes"/>
- <menu label="Ðовые чаÑти тела" name="COF.Geear.New_Body_Parts"/>
+ <menu label="Ðовые чаÑти тела" name="COF.Gear.New_Body_Parts"/>
</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/ru/menu_conversation.xml b/indra/newview/skins/default/xui/ru/menu_conversation.xml
new file mode 100644
index 0000000000..4d1240db98
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/menu_conversation.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_conversation_participant">
+ <menu_item_call label="Закрыть разговор" name="close_conversation"/>
+ <menu_item_call label="Открыть голоÑовой чат" name="open_voice_conversation"/>
+ <menu_item_call label="Прекратить голоÑовой чат" name="disconnect_from_voice"/>
+ <menu_item_call label="Закрыть выбранные" name="close_selected_conversations"/>
+ <menu_item_call label="Смотреть профиль" name="view_profile"/>
+ <menu_item_call label="IM" name="im"/>
+ <menu_item_call label="Предложить телепортацию" name="offer_teleport"/>
+ <menu_item_call label="ГолоÑовой вызов" name="voice_call"/>
+ <menu_item_call label="Журнал чата..." name="chat_history"/>
+ <menu_item_call label="Добавить друга" name="add_friend"/>
+ <menu_item_call label="Удалить друга" name="remove_friend"/>
+ <menu_item_call label="Удалить друзей" name="remove_friends"/>
+ <menu_item_call label="ПриглаÑить в группу..." name="invite_to_group"/>
+ <menu_item_call label="Приблизить" name="zoom_in"/>
+ <menu_item_call label="Карта" name="map"/>
+ <menu_item_call label="ПоделитьÑÑ" name="share"/>
+ <menu_item_call label="Заплатить" name="pay"/>
+ <menu_item_check label="Блокировать голоÑ" name="block_unblock"/>
+ <menu_item_check label="Блокировать текÑÑ‚" name="MuteText"/>
+ <menu_item_call label="Профиль группы" name="group_profile"/>
+ <menu_item_call label="Ðктивировать группу" name="activate_group"/>
+ <menu_item_call label="Покинуть группу" name="leave_group"/>
+ <context_menu label="Параметры модератора" name="Moderator Options">
+ <menu_item_check label="Разрешить текÑтовый чат" name="AllowTextChat"/>
+ <menu_item_call label="Заглушить Ñтого учаÑтника" name="ModerateVoiceMuteSelected"/>
+ <menu_item_call label="Позволить говорить Ñтому учаÑтнику" name="ModerateVoiceUnMuteSelected"/>
+ <menu_item_call label="Заглушить вÑех" name="ModerateVoiceMute"/>
+ <menu_item_call label="Позволить говорить вÑем" name="ModerateVoiceUnmute"/>
+ </context_menu>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/ru/menu_conversation_log_gear.xml b/indra/newview/skins/default/xui/ru/menu_conversation_log_gear.xml
new file mode 100644
index 0000000000..3fbffbe038
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/menu_conversation_log_gear.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="Conversation Context Menu">
+ <menu_item_call label="IM..." name="IM"/>
+ <menu_item_call label="ГолоÑовой вызов..." name="Call"/>
+ <menu_item_call label="Открыть журнал чата..." name="Chat history"/>
+ <menu_item_call label="Смотреть профиль" name="View Profile"/>
+ <menu_item_call label="Предложить телепорт" name="teleport"/>
+ <menu_item_call label="Добавить друга" name="add_friend"/>
+ <menu_item_call label="Удалить из друзей" name="remove_friend"/>
+ <menu_item_call label="ПриглаÑить в группу..." name="Invite"/>
+ <menu_item_call label="Карта" name="Map"/>
+ <menu_item_call label="ПоделитьÑÑ" name="Share"/>
+ <menu_item_call label="Заплатить" name="Pay"/>
+ <menu_item_check label="Черный ÑпиÑок" name="Block/Unblock"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/ru/menu_conversation_log_view.xml b/indra/newview/skins/default/xui/ru/menu_conversation_log_view.xml
new file mode 100644
index 0000000000..928146e273
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/menu_conversation_log_view.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_conversation_view">
+ <menu_item_check label="Сортировать по имени" name="sort_by_name"/>
+ <menu_item_check label="Сортировать по дате" name="sort_by_date"/>
+ <menu_item_check label="Сначала друзьÑ" name="sort_by_friends"/>
+ <menu_item_call label="ПоÑмотреть журнал локального чата..." name="view_nearby_chat_history"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/ru/menu_edit.xml b/indra/newview/skins/default/xui/ru/menu_edit.xml
index 0dddea9c04..0dddea9c04 100644..100755
--- a/indra/newview/skins/default/xui/ru/menu_edit.xml
+++ b/indra/newview/skins/default/xui/ru/menu_edit.xml
diff --git a/indra/newview/skins/default/xui/ru/menu_favorites.xml b/indra/newview/skins/default/xui/ru/menu_favorites.xml
index 074be06ba9..074be06ba9 100644..100755
--- a/indra/newview/skins/default/xui/ru/menu_favorites.xml
+++ b/indra/newview/skins/default/xui/ru/menu_favorites.xml
diff --git a/indra/newview/skins/default/xui/ru/menu_gesture_gear.xml b/indra/newview/skins/default/xui/ru/menu_gesture_gear.xml
index d0b68cefbd..d0b68cefbd 100644..100755
--- a/indra/newview/skins/default/xui/ru/menu_gesture_gear.xml
+++ b/indra/newview/skins/default/xui/ru/menu_gesture_gear.xml
diff --git a/indra/newview/skins/default/xui/ru/menu_group_plus.xml b/indra/newview/skins/default/xui/ru/menu_group_plus.xml
index edd012b964..edd012b964 100644..100755
--- a/indra/newview/skins/default/xui/ru/menu_group_plus.xml
+++ b/indra/newview/skins/default/xui/ru/menu_group_plus.xml
diff --git a/indra/newview/skins/default/xui/ru/menu_hide_navbar.xml b/indra/newview/skins/default/xui/ru/menu_hide_navbar.xml
index 34e5f4c0e4..34e5f4c0e4 100644..100755
--- a/indra/newview/skins/default/xui/ru/menu_hide_navbar.xml
+++ b/indra/newview/skins/default/xui/ru/menu_hide_navbar.xml
diff --git a/indra/newview/skins/default/xui/ru/menu_im_conversation.xml b/indra/newview/skins/default/xui/ru/menu_im_conversation.xml
new file mode 100644
index 0000000000..1db0b8bae3
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/menu_im_conversation.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="Conversation Gear Menu">
+ <menu_item_call label="Смотреть профиль" name="View Profile"/>
+ <menu_item_call label="Добавить друга" name="Add Friend"/>
+ <menu_item_call label="Удалить друга" name="remove_friend"/>
+ <menu_item_call label="Предложить телепортацию" name="offer_teleport"/>
+ <menu_item_call label="ПриглаÑить в группу..." name="invite_to_group"/>
+ <menu_item_call label="Журнал чата..." name="chat_history"/>
+ <menu_item_call label="Приблизить" name="zoom_in"/>
+ <menu_item_call label="Карта" name="map"/>
+ <menu_item_call label="ПоделитьÑÑ" name="Share"/>
+ <menu_item_call label="Заплатить" name="Pay"/>
+ <menu_item_check label="Блокировать голоÑ" name="Block/Unblock"/>
+ <menu_item_check label="Блокировать текÑÑ‚" name="MuteText"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/ru/menu_im_session_showmodes.xml b/indra/newview/skins/default/xui/ru/menu_im_session_showmodes.xml
new file mode 100644
index 0000000000..35cff8e4bf
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/menu_im_session_showmodes.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_modes">
+ <menu_item_check label="Компактный вид" name="compact_view"/>
+ <menu_item_check label="Развернутый вид" name="expanded_view"/>
+ <menu_item_check label="Показать времÑ" name="IMShowTime"/>
+ <menu_item_check label="Показывать имена при разговорах" name="IMShowNamesForP2PConv"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/ru/menu_im_well_button.xml b/indra/newview/skins/default/xui/ru/menu_im_well_button.xml
deleted file mode 100644
index 5a5bde61b9..0000000000
--- a/indra/newview/skins/default/xui/ru/menu_im_well_button.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<context_menu name="IM Well Button Context Menu">
- <menu_item_call label="Закрыть вÑе" name="Close All"/>
-</context_menu>
diff --git a/indra/newview/skins/default/xui/ru/menu_imchiclet_adhoc.xml b/indra/newview/skins/default/xui/ru/menu_imchiclet_adhoc.xml
index 8b60a585ab..8b60a585ab 100644..100755
--- a/indra/newview/skins/default/xui/ru/menu_imchiclet_adhoc.xml
+++ b/indra/newview/skins/default/xui/ru/menu_imchiclet_adhoc.xml
diff --git a/indra/newview/skins/default/xui/ru/menu_imchiclet_group.xml b/indra/newview/skins/default/xui/ru/menu_imchiclet_group.xml
index 766b3847a7..766b3847a7 100644..100755
--- a/indra/newview/skins/default/xui/ru/menu_imchiclet_group.xml
+++ b/indra/newview/skins/default/xui/ru/menu_imchiclet_group.xml
diff --git a/indra/newview/skins/default/xui/ru/menu_imchiclet_p2p.xml b/indra/newview/skins/default/xui/ru/menu_imchiclet_p2p.xml
index a33f6d5be8..a33f6d5be8 100644..100755
--- a/indra/newview/skins/default/xui/ru/menu_imchiclet_p2p.xml
+++ b/indra/newview/skins/default/xui/ru/menu_imchiclet_p2p.xml
diff --git a/indra/newview/skins/default/xui/ru/menu_inspect_avatar_gear.xml b/indra/newview/skins/default/xui/ru/menu_inspect_avatar_gear.xml
index 957609a7a3..957609a7a3 100644..100755
--- a/indra/newview/skins/default/xui/ru/menu_inspect_avatar_gear.xml
+++ b/indra/newview/skins/default/xui/ru/menu_inspect_avatar_gear.xml
diff --git a/indra/newview/skins/default/xui/ru/menu_inspect_object_gear.xml b/indra/newview/skins/default/xui/ru/menu_inspect_object_gear.xml
index 30953e830b..30953e830b 100644..100755
--- a/indra/newview/skins/default/xui/ru/menu_inspect_object_gear.xml
+++ b/indra/newview/skins/default/xui/ru/menu_inspect_object_gear.xml
diff --git a/indra/newview/skins/default/xui/ru/menu_inspect_self_gear.xml b/indra/newview/skins/default/xui/ru/menu_inspect_self_gear.xml
index 901bb615e0..901bb615e0 100644..100755
--- a/indra/newview/skins/default/xui/ru/menu_inspect_self_gear.xml
+++ b/indra/newview/skins/default/xui/ru/menu_inspect_self_gear.xml
diff --git a/indra/newview/skins/default/xui/ru/menu_inv_offer_chiclet.xml b/indra/newview/skins/default/xui/ru/menu_inv_offer_chiclet.xml
index 95d162d7fe..95d162d7fe 100644..100755
--- a/indra/newview/skins/default/xui/ru/menu_inv_offer_chiclet.xml
+++ b/indra/newview/skins/default/xui/ru/menu_inv_offer_chiclet.xml
diff --git a/indra/newview/skins/default/xui/ru/menu_inventory.xml b/indra/newview/skins/default/xui/ru/menu_inventory.xml
index 49f7281b4e..37ee19fc1d 100644..100755
--- a/indra/newview/skins/default/xui/ru/menu_inventory.xml
+++ b/indra/newview/skins/default/xui/ru/menu_inventory.xml
@@ -68,6 +68,7 @@
<menu_item_call label="Удалить ÑиÑтемную папку" name="Delete System Folder"/>
<menu_item_call label="Ðачать конференцию" name="Conference Chat Folder"/>
<menu_item_call label="ВоÑпроизвеÑти" name="Sound Play"/>
+ <menu_item_call label="Копировать URL SL" name="url_copy"/>
<menu_item_call label="О закладке" name="About Landmark"/>
<menu_item_call label="Проиграть Ð´Ð»Ñ Ð²Ñех" name="Animation Play"/>
<menu_item_call label="Проиграть Ð´Ð»Ñ ÑебÑ" name="Animation Audition"/>
diff --git a/indra/newview/skins/default/xui/ru/menu_inventory_add.xml b/indra/newview/skins/default/xui/ru/menu_inventory_add.xml
index 9a240c653e..9a240c653e 100644..100755
--- a/indra/newview/skins/default/xui/ru/menu_inventory_add.xml
+++ b/indra/newview/skins/default/xui/ru/menu_inventory_add.xml
diff --git a/indra/newview/skins/default/xui/ru/menu_inventory_gear_default.xml b/indra/newview/skins/default/xui/ru/menu_inventory_gear_default.xml
index 9fc0b6d44e..9fc0b6d44e 100644..100755
--- a/indra/newview/skins/default/xui/ru/menu_inventory_gear_default.xml
+++ b/indra/newview/skins/default/xui/ru/menu_inventory_gear_default.xml
diff --git a/indra/newview/skins/default/xui/ru/menu_land.xml b/indra/newview/skins/default/xui/ru/menu_land.xml
index 89889d7bf6..5aa4e6ccd2 100644..100755
--- a/indra/newview/skins/default/xui/ru/menu_land.xml
+++ b/indra/newview/skins/default/xui/ru/menu_land.xml
@@ -6,4 +6,5 @@
<menu_item_call label="Купить пропуÑк" name="Land Buy Pass"/>
<menu_item_call label="СтроительÑтво" name="Create"/>
<menu_item_call label="Изменить ландшафт" name="Edit Terrain"/>
+ <menu_item_call label="Блокировать владельца учаÑтка" name="Mute Particle"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/ru/menu_landmark.xml b/indra/newview/skins/default/xui/ru/menu_landmark.xml
index 24b60f9d86..24b60f9d86 100644..100755
--- a/indra/newview/skins/default/xui/ru/menu_landmark.xml
+++ b/indra/newview/skins/default/xui/ru/menu_landmark.xml
diff --git a/indra/newview/skins/default/xui/ru/menu_login.xml b/indra/newview/skins/default/xui/ru/menu_login.xml
index 93a5ffbb25..835c4e186e 100644..100755
--- a/indra/newview/skins/default/xui/ru/menu_login.xml
+++ b/indra/newview/skins/default/xui/ru/menu_login.xml
@@ -18,7 +18,13 @@
<menu_item_call label="Показать лицензионное Ñоглашение" name="TOS"/>
<menu_item_call label="Показать Ñообщение об ошибке" name="Critical"/>
<menu_item_call label="ТеÑÑ‚ отладки плавающего окна Ñ Ð²ÐµÐ±-контентом" name="Web Content Floater Debug Test"/>
- <menu label="Уровень журнала" name="Set Logging Level"/>
+ <menu label="Уровень журнала" name="Set Logging Level">
+ <menu_item_check label="Отладка" name="Debug"/>
+ <menu_item_check label="ИнформациÑ" name="Info"/>
+ <menu_item_check label="Внимание!" name="Warning"/>
+ <menu_item_check label="Ошибка" name="Error"/>
+ <menu_item_check label="Ðет" name="None"/>
+ </menu>
<menu_item_check label="Выбор Ñетки" name="Show Grid Picker"/>
<menu_item_call label="КонÑоль уведомлений" name="Show Notifications Console"/>
</menu>
diff --git a/indra/newview/skins/default/xui/ru/menu_media_ctrl.xml b/indra/newview/skins/default/xui/ru/menu_media_ctrl.xml
index d7485b02af..d7485b02af 100644..100755
--- a/indra/newview/skins/default/xui/ru/menu_media_ctrl.xml
+++ b/indra/newview/skins/default/xui/ru/menu_media_ctrl.xml
diff --git a/indra/newview/skins/default/xui/ru/menu_mini_map.xml b/indra/newview/skins/default/xui/ru/menu_mini_map.xml
index 6b3db11609..6b3db11609 100644..100755
--- a/indra/newview/skins/default/xui/ru/menu_mini_map.xml
+++ b/indra/newview/skins/default/xui/ru/menu_mini_map.xml
diff --git a/indra/newview/skins/default/xui/ru/menu_mode_change.xml b/indra/newview/skins/default/xui/ru/menu_mode_change.xml
deleted file mode 100644
index 25d6e9af27..0000000000
--- a/indra/newview/skins/default/xui/ru/menu_mode_change.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<toggleable_menu name="Mode Change">
- <menu_item_check label="ОÑновной" name="BasicMode"/>
- <menu_item_check label="РаÑширенный" name="AdvancedMode"/>
-</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/ru/menu_model_import_gear_default.xml b/indra/newview/skins/default/xui/ru/menu_model_import_gear_default.xml
index 5ae5e7dfbc..5ae5e7dfbc 100644..100755
--- a/indra/newview/skins/default/xui/ru/menu_model_import_gear_default.xml
+++ b/indra/newview/skins/default/xui/ru/menu_model_import_gear_default.xml
diff --git a/indra/newview/skins/default/xui/ru/menu_mute_particle.xml b/indra/newview/skins/default/xui/ru/menu_mute_particle.xml
new file mode 100644
index 0000000000..0c5a147419
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/menu_mute_particle.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<!-- *NOTE: See also menu_attachment_other.xml -->
+<context_menu name="Mute Particle Pie">
+ <menu_item_call label="Блокировать владельца учаÑтка" name="Mute Particle"/>
+</context_menu>
diff --git a/indra/newview/skins/default/xui/ru/menu_navbar.xml b/indra/newview/skins/default/xui/ru/menu_navbar.xml
index 2dd0c0df36..2dd0c0df36 100644..100755
--- a/indra/newview/skins/default/xui/ru/menu_navbar.xml
+++ b/indra/newview/skins/default/xui/ru/menu_navbar.xml
diff --git a/indra/newview/skins/default/xui/ru/menu_nearby_chat.xml b/indra/newview/skins/default/xui/ru/menu_nearby_chat.xml
index 4b5346d083..4b5346d083 100644..100755
--- a/indra/newview/skins/default/xui/ru/menu_nearby_chat.xml
+++ b/indra/newview/skins/default/xui/ru/menu_nearby_chat.xml
diff --git a/indra/newview/skins/default/xui/ru/menu_notification_well_button.xml b/indra/newview/skins/default/xui/ru/menu_notification_well_button.xml
index 4d067e232a..4d067e232a 100644..100755
--- a/indra/newview/skins/default/xui/ru/menu_notification_well_button.xml
+++ b/indra/newview/skins/default/xui/ru/menu_notification_well_button.xml
diff --git a/indra/newview/skins/default/xui/ru/menu_object.xml b/indra/newview/skins/default/xui/ru/menu_object.xml
index d6abfd12a2..056dab74c1 100644..100755
--- a/indra/newview/skins/default/xui/ru/menu_object.xml
+++ b/indra/newview/skins/default/xui/ru/menu_object.xml
@@ -8,6 +8,8 @@
<menu_item_call label="Ð’Ñтать" name="Object Stand Up"/>
<menu_item_call label="Профиль объекта" name="Object Inspect"/>
<menu_item_call label="Приблизить" name="Zoom In"/>
+ <menu_item_call label="Показывать в наборах ÑвÑзей" name="show_in_linksets"/>
+ <menu_item_call label="Показывать в перÑонажах" name="show_in_characters"/>
<context_menu label="Ðадеть" name="Put On">
<menu_item_call label="Ðадеть" name="Wear"/>
<menu_item_call label="Добавить" name="Add"/>
@@ -24,4 +26,5 @@
<menu_item_call label="Заплатить" name="Pay..."/>
<menu_item_call label="Купить" name="Buy..."/>
<menu_item_call label="Удалить" name="Delete"/>
+ <menu_item_call label="Блокировать владельца учаÑтка" name="Mute Particle"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/ru/menu_object_icon.xml b/indra/newview/skins/default/xui/ru/menu_object_icon.xml
index 6229b2e72f..0c50abcfbd 100644..100755
--- a/indra/newview/skins/default/xui/ru/menu_object_icon.xml
+++ b/indra/newview/skins/default/xui/ru/menu_object_icon.xml
@@ -2,4 +2,6 @@
<menu name="Object Icon Menu">
<menu_item_call label="Профиль объекта..." name="Object Profile"/>
<menu_item_call label="Блокировать..." name="Block"/>
+ <menu_item_call label="Показать на карте" name="show_on_map"/>
+ <menu_item_call label="Телепорт в меÑтоположение объекта" name="teleport_to_object"/>
</menu>
diff --git a/indra/newview/skins/default/xui/ru/menu_outfit_gear.xml b/indra/newview/skins/default/xui/ru/menu_outfit_gear.xml
index 93dbd7d6a7..d379a17216 100644..100755
--- a/indra/newview/skins/default/xui/ru/menu_outfit_gear.xml
+++ b/indra/newview/skins/default/xui/ru/menu_outfit_gear.xml
@@ -23,6 +23,8 @@
<menu_item_call label="Ðовые волоÑÑ‹" name="New Hair"/>
<menu_item_call label="Ðовые глаза" name="New Eyes"/>
</menu>
+ <menu_item_call label="Открыть вÑе папки" name="expand"/>
+ <menu_item_call label="Закрыть вÑе папки" name="collapse"/>
<menu_item_call label="Переименовать коÑтюм" name="rename"/>
<menu_item_call label="Удалить коÑтюм" name="delete_outfit"/>
</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/ru/menu_outfit_tab.xml b/indra/newview/skins/default/xui/ru/menu_outfit_tab.xml
index 46404195b9..46404195b9 100644..100755
--- a/indra/newview/skins/default/xui/ru/menu_outfit_tab.xml
+++ b/indra/newview/skins/default/xui/ru/menu_outfit_tab.xml
diff --git a/indra/newview/skins/default/xui/ru/menu_participant_list.xml b/indra/newview/skins/default/xui/ru/menu_participant_list.xml
index 932ad5bacf..932ad5bacf 100644..100755
--- a/indra/newview/skins/default/xui/ru/menu_participant_list.xml
+++ b/indra/newview/skins/default/xui/ru/menu_participant_list.xml
diff --git a/indra/newview/skins/default/xui/ru/menu_participant_view.xml b/indra/newview/skins/default/xui/ru/menu_participant_view.xml
new file mode 100644
index 0000000000..851a42d428
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/menu_participant_view.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="participant_manu_view">
+ <menu_item_check label="Сортировать разговоры по типу" name="sort_sessions_by_type"/>
+ <menu_item_check label="Сортировать разговоры по имени" name="sort_sessions_by_name"/>
+ <menu_item_check label="Сортировать разговоры по поÑледнему дейÑтвию" name="sort_sessions_by_recent"/>
+ <menu_item_check label="Сортировать учаÑтников по имени" name="sort_participants_by_name"/>
+ <menu_item_check label="Сортировать учаÑтников по поÑледнему дейÑтвию" name="sort_participants_by_recent"/>
+ <menu_item_call label="Изменить наÑтройки..." name="chat_preferences"/>
+ <menu_item_call label="ÐаÑтройки приватноÑти..." name="privacy_preferences"/>
+ <menu_item_check label="Журнал разговора..." name="Conversation"/>
+ <menu_item_check label="ПеревеÑти локальный чат" name="Translate_chat"/>
+ <menu_item_check label="ÐаÑтройки перевода..." name="Translation_settings"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/ru/menu_people_blocked_gear.xml b/indra/newview/skins/default/xui/ru/menu_people_blocked_gear.xml
new file mode 100644
index 0000000000..157f2ad5e2
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/menu_people_blocked_gear.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_blocked_gear">
+ <menu_item_call label="Разблокировать" name="unblock"/>
+ <menu_item_call label="Профиль…" name="profile"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/ru/menu_people_blocked_plus.xml b/indra/newview/skins/default/xui/ru/menu_people_blocked_plus.xml
new file mode 100644
index 0000000000..f42e8f8609
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/menu_people_blocked_plus.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_blocked_plus">
+ <menu_item_call label="Блокировать Ð¶Ð¸Ñ‚ÐµÐ»Ñ Ð¿Ð¾ имени..." name="block_resident_by_name"/>
+ <menu_item_call label="Блокировать объект по имени" name="block_object_by_name"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/ru/menu_people_blocked_view.xml b/indra/newview/skins/default/xui/ru/menu_people_blocked_view.xml
new file mode 100644
index 0000000000..8c0150e8ae
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/menu_people_blocked_view.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_blocked_view">
+ <menu_item_check label="Сортировать по имени" name="sort_by_name"/>
+ <menu_item_check label="Сортировать по типу" name="sort_by_type"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/ru/menu_people_friends_view.xml b/indra/newview/skins/default/xui/ru/menu_people_friends_view.xml
new file mode 100644
index 0000000000..7b2dba0539
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/menu_people_friends_view.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_group_plus">
+ <menu_item_check label="Сортировать по имени" name="sort_name"/>
+ <menu_item_check label="Сортировать по ÑтатуÑу" name="sort_status"/>
+ <menu_item_check label="Показывать значки людей" name="view_icons"/>
+ <menu_item_check label="Показывать разрешенные дейÑтвиÑ" name="view_permissions"/>
+ <menu_item_check label="ПоÑмотреть журнал разговора..." name="view_conversation"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/ru/menu_people_friends_view_sort.xml b/indra/newview/skins/default/xui/ru/menu_people_friends_view_sort.xml
index 0fa252aa99..0fa252aa99 100644..100755
--- a/indra/newview/skins/default/xui/ru/menu_people_friends_view_sort.xml
+++ b/indra/newview/skins/default/xui/ru/menu_people_friends_view_sort.xml
diff --git a/indra/newview/skins/default/xui/ru/menu_people_groups.xml b/indra/newview/skins/default/xui/ru/menu_people_groups.xml
index e734a83ef0..78d73c9d1e 100644..100755
--- a/indra/newview/skins/default/xui/ru/menu_people_groups.xml
+++ b/indra/newview/skins/default/xui/ru/menu_people_groups.xml
@@ -2,7 +2,7 @@
<menu name="menu_group_plus">
<menu_item_call label="ИнформациÑ" name="View Info"/>
<menu_item_call label="Чат" name="Chat"/>
- <menu_item_call label="Звонок" name="Call"/>
+ <menu_item_call label="ГолоÑовой вызов" name="Call"/>
<menu_item_call label="ÐктивациÑ" name="Activate"/>
<menu_item_call label="Покинуть" name="Leave"/>
</menu>
diff --git a/indra/newview/skins/default/xui/ru/menu_people_groups_view.xml b/indra/newview/skins/default/xui/ru/menu_people_groups_view.xml
new file mode 100644
index 0000000000..cbf1c64774
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/menu_people_groups_view.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_group_plus">
+ <menu_item_check label="Показывать значки группы" name="Display Group Icons"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/ru/menu_people_groups_view_sort.xml b/indra/newview/skins/default/xui/ru/menu_people_groups_view_sort.xml
index 0358068db9..0358068db9 100644..100755
--- a/indra/newview/skins/default/xui/ru/menu_people_groups_view_sort.xml
+++ b/indra/newview/skins/default/xui/ru/menu_people_groups_view_sort.xml
diff --git a/indra/newview/skins/default/xui/ru/menu_people_nearby.xml b/indra/newview/skins/default/xui/ru/menu_people_nearby.xml
index ebce959044..d05b7e7d01 100644..100755
--- a/indra/newview/skins/default/xui/ru/menu_people_nearby.xml
+++ b/indra/newview/skins/default/xui/ru/menu_people_nearby.xml
@@ -1,13 +1,16 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Avatar Context Menu">
- <menu_item_call label="Смотреть профиль" name="View Profile"/>
- <menu_item_call label="Ð’ друзьÑ" name="Add Friend"/>
- <menu_item_call label="Удалить из друзей" name="Remove Friend"/>
- <menu_item_call label="IM" name="IM"/>
- <menu_item_call label="Звонок" name="Call"/>
- <menu_item_call label="Карта" name="Map"/>
- <menu_item_call label="ПоделитьÑÑ" name="Share"/>
- <menu_item_call label="Заплатить" name="Pay"/>
- <menu_item_check label="Черный ÑпиÑок" name="Block/Unblock"/>
- <menu_item_call label="Предложить телепорт" name="teleport"/>
+ <menu_item_call label="Смотреть профиль" name="view_profile"/>
+ <menu_item_call label="IM" name="im"/>
+ <menu_item_call label="Предложить телепорт" name="offer_teleport"/>
+ <menu_item_call label="ГолоÑовой вызов" name="voice_call"/>
+ <menu_item_call label="ПоÑмотреть журнал чата..." name="chat_history"/>
+ <menu_item_call label="Добавить друга" name="add_friend"/>
+ <menu_item_call label="Удалить из друзей" name="remove_friend"/>
+ <menu_item_call label="ПриглаÑить в группу..." name="invite_to_group"/>
+ <menu_item_call label="Приблизить" name="zoom_in"/>
+ <menu_item_call label="Карта" name="map"/>
+ <menu_item_call label="ПоделитьÑÑ" name="share"/>
+ <menu_item_call label="Заплатить" name="pay"/>
+ <menu_item_check label="Черный ÑпиÑок" name="block_unblock"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/ru/menu_people_nearby_multiselect.xml b/indra/newview/skins/default/xui/ru/menu_people_nearby_multiselect.xml
index 0e8e0d4053..88eb56c9f5 100644..100755
--- a/indra/newview/skins/default/xui/ru/menu_people_nearby_multiselect.xml
+++ b/indra/newview/skins/default/xui/ru/menu_people_nearby_multiselect.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Multi-Selected People Context Menu">
- <menu_item_call label="Добавить в друзьÑ" name="Add Friends"/>
- <menu_item_call label="Удалить из друзей" name="Remove Friend"/>
- <menu_item_call label="IM" name="IM"/>
- <menu_item_call label="Звонок" name="Call"/>
- <menu_item_call label="ПоделитьÑÑ" name="Share"/>
- <menu_item_call label="Заплатить" name="Pay"/>
- <menu_item_call label="Предложить телепорт" name="teleport"/>
+ <menu_item_call label="Добавить в друзьÑ" name="add_friends"/>
+ <menu_item_call label="Удалить из друзей" name="remove_friends"/>
+ <menu_item_call label="IM" name="im"/>
+ <menu_item_call label="Звонок" name="call"/>
+ <menu_item_call label="ПоделитьÑÑ" name="share"/>
+ <menu_item_call label="Заплатить" name="pay"/>
+ <menu_item_call label="Предложить телепорт" name="offer_teleport"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/ru/menu_people_nearby_view.xml b/indra/newview/skins/default/xui/ru/menu_people_nearby_view.xml
new file mode 100644
index 0000000000..2bc353ad58
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/menu_people_nearby_view.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_group_plus">
+ <menu_item_check label="Сортировать по недавно говорившим" name="sort_by_recent_speakers"/>
+ <menu_item_check label="Сортировать по имени" name="sort_name"/>
+ <menu_item_check label="Сортировать по раÑÑтоÑнию" name="sort_distance"/>
+ <menu_item_check label="Показывать значки людей" name="view_icons"/>
+ <menu_item_check label="Смотреть карту" name="view_map"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/ru/menu_people_nearby_view_sort.xml b/indra/newview/skins/default/xui/ru/menu_people_nearby_view_sort.xml
index 4589815f6b..4589815f6b 100644..100755
--- a/indra/newview/skins/default/xui/ru/menu_people_nearby_view_sort.xml
+++ b/indra/newview/skins/default/xui/ru/menu_people_nearby_view_sort.xml
diff --git a/indra/newview/skins/default/xui/ru/menu_people_recent_view.xml b/indra/newview/skins/default/xui/ru/menu_people_recent_view.xml
new file mode 100644
index 0000000000..a009cf081f
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/menu_people_recent_view.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_group_plus">
+ <menu_item_check label="Сортировать по времени" name="sort_most"/>
+ <menu_item_check label="Сортировать по имени" name="sort_name"/>
+ <menu_item_check label="Показывать значки людей" name="view_icons"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/ru/menu_people_recent_view_sort.xml b/indra/newview/skins/default/xui/ru/menu_people_recent_view_sort.xml
index 2ac83ffe52..2ac83ffe52 100644..100755
--- a/indra/newview/skins/default/xui/ru/menu_people_recent_view_sort.xml
+++ b/indra/newview/skins/default/xui/ru/menu_people_recent_view_sort.xml
diff --git a/indra/newview/skins/default/xui/ru/menu_picks.xml b/indra/newview/skins/default/xui/ru/menu_picks.xml
index 839c7411a6..839c7411a6 100644..100755
--- a/indra/newview/skins/default/xui/ru/menu_picks.xml
+++ b/indra/newview/skins/default/xui/ru/menu_picks.xml
diff --git a/indra/newview/skins/default/xui/ru/menu_picks_plus.xml b/indra/newview/skins/default/xui/ru/menu_picks_plus.xml
index 1bc4078179..1bc4078179 100644..100755
--- a/indra/newview/skins/default/xui/ru/menu_picks_plus.xml
+++ b/indra/newview/skins/default/xui/ru/menu_picks_plus.xml
diff --git a/indra/newview/skins/default/xui/ru/menu_place.xml b/indra/newview/skins/default/xui/ru/menu_place.xml
index ee8878c131..ee8878c131 100644..100755
--- a/indra/newview/skins/default/xui/ru/menu_place.xml
+++ b/indra/newview/skins/default/xui/ru/menu_place.xml
diff --git a/indra/newview/skins/default/xui/ru/menu_place_add_button.xml b/indra/newview/skins/default/xui/ru/menu_place_add_button.xml
index b1a38fb9eb..b1a38fb9eb 100644..100755
--- a/indra/newview/skins/default/xui/ru/menu_place_add_button.xml
+++ b/indra/newview/skins/default/xui/ru/menu_place_add_button.xml
diff --git a/indra/newview/skins/default/xui/ru/menu_places_gear_folder.xml b/indra/newview/skins/default/xui/ru/menu_places_gear_folder.xml
index 25df8c5d19..25df8c5d19 100644..100755
--- a/indra/newview/skins/default/xui/ru/menu_places_gear_folder.xml
+++ b/indra/newview/skins/default/xui/ru/menu_places_gear_folder.xml
diff --git a/indra/newview/skins/default/xui/ru/menu_places_gear_landmark.xml b/indra/newview/skins/default/xui/ru/menu_places_gear_landmark.xml
index b1ebd4af83..b1ebd4af83 100644..100755
--- a/indra/newview/skins/default/xui/ru/menu_places_gear_landmark.xml
+++ b/indra/newview/skins/default/xui/ru/menu_places_gear_landmark.xml
diff --git a/indra/newview/skins/default/xui/ru/menu_profile_overflow.xml b/indra/newview/skins/default/xui/ru/menu_profile_overflow.xml
index 1865fead7b..1865fead7b 100644..100755
--- a/indra/newview/skins/default/xui/ru/menu_profile_overflow.xml
+++ b/indra/newview/skins/default/xui/ru/menu_profile_overflow.xml
diff --git a/indra/newview/skins/default/xui/ru/menu_save_outfit.xml b/indra/newview/skins/default/xui/ru/menu_save_outfit.xml
index 88947e1433..88947e1433 100644..100755
--- a/indra/newview/skins/default/xui/ru/menu_save_outfit.xml
+++ b/indra/newview/skins/default/xui/ru/menu_save_outfit.xml
diff --git a/indra/newview/skins/default/xui/ru/menu_script_chiclet.xml b/indra/newview/skins/default/xui/ru/menu_script_chiclet.xml
index 6cacff3870..6cacff3870 100644..100755
--- a/indra/newview/skins/default/xui/ru/menu_script_chiclet.xml
+++ b/indra/newview/skins/default/xui/ru/menu_script_chiclet.xml
diff --git a/indra/newview/skins/default/xui/ru/menu_slurl.xml b/indra/newview/skins/default/xui/ru/menu_slurl.xml
index f02549055c..f02549055c 100644..100755
--- a/indra/newview/skins/default/xui/ru/menu_slurl.xml
+++ b/indra/newview/skins/default/xui/ru/menu_slurl.xml
diff --git a/indra/newview/skins/default/xui/ru/menu_teleport_history_gear.xml b/indra/newview/skins/default/xui/ru/menu_teleport_history_gear.xml
index 332f2784b9..332f2784b9 100644..100755
--- a/indra/newview/skins/default/xui/ru/menu_teleport_history_gear.xml
+++ b/indra/newview/skins/default/xui/ru/menu_teleport_history_gear.xml
diff --git a/indra/newview/skins/default/xui/ru/menu_teleport_history_item.xml b/indra/newview/skins/default/xui/ru/menu_teleport_history_item.xml
index 6a22fd00dc..6a22fd00dc 100644..100755
--- a/indra/newview/skins/default/xui/ru/menu_teleport_history_item.xml
+++ b/indra/newview/skins/default/xui/ru/menu_teleport_history_item.xml
diff --git a/indra/newview/skins/default/xui/ru/menu_teleport_history_tab.xml b/indra/newview/skins/default/xui/ru/menu_teleport_history_tab.xml
index 9b2434a310..9b2434a310 100644..100755
--- a/indra/newview/skins/default/xui/ru/menu_teleport_history_tab.xml
+++ b/indra/newview/skins/default/xui/ru/menu_teleport_history_tab.xml
diff --git a/indra/newview/skins/default/xui/ru/menu_text_editor.xml b/indra/newview/skins/default/xui/ru/menu_text_editor.xml
index 113dd85318..0c928308a1 100644..100755
--- a/indra/newview/skins/default/xui/ru/menu_text_editor.xml
+++ b/indra/newview/skins/default/xui/ru/menu_text_editor.xml
@@ -1,5 +1,12 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Text editor context menu">
+ <menu_item_call label="(неизвеÑтно)" name="Suggestion 1"/>
+ <menu_item_call label="(неизвеÑтно)" name="Suggestion 2"/>
+ <menu_item_call label="(неизвеÑтно)" name="Suggestion 3"/>
+ <menu_item_call label="(неизвеÑтно)" name="Suggestion 4"/>
+ <menu_item_call label="(неизвеÑтно)" name="Suggestion 5"/>
+ <menu_item_call label="Добавить в Ñловарь" name="Add to Dictionary"/>
+ <menu_item_call label="Добавить в ÑпиÑок игнорируемых" name="Add to Ignore"/>
<menu_item_call label="Вырезать" name="Cut"/>
<menu_item_call label="Копировать" name="Copy"/>
<menu_item_call label="Ð’Ñтавить" name="Paste"/>
diff --git a/indra/newview/skins/default/xui/ru/menu_toolbars.xml b/indra/newview/skins/default/xui/ru/menu_toolbars.xml
index aa05dbc390..aa05dbc390 100644..100755
--- a/indra/newview/skins/default/xui/ru/menu_toolbars.xml
+++ b/indra/newview/skins/default/xui/ru/menu_toolbars.xml
diff --git a/indra/newview/skins/default/xui/ru/menu_topinfobar.xml b/indra/newview/skins/default/xui/ru/menu_topinfobar.xml
index 76cadbe5a4..76cadbe5a4 100644..100755
--- a/indra/newview/skins/default/xui/ru/menu_topinfobar.xml
+++ b/indra/newview/skins/default/xui/ru/menu_topinfobar.xml
diff --git a/indra/newview/skins/default/xui/ru/menu_url_agent.xml b/indra/newview/skins/default/xui/ru/menu_url_agent.xml
index 0ba3ee152a..fcd1fe310d 100644..100755
--- a/indra/newview/skins/default/xui/ru/menu_url_agent.xml
+++ b/indra/newview/skins/default/xui/ru/menu_url_agent.xml
@@ -1,6 +1,9 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Url Popup">
- <menu_item_call label="Показать профиль жителÑ" name="show_agent"/>
+ <menu_item_call label="Смотреть профиль" name="show_agent"/>
+ <menu_item_call label="Отправить Ñообщение..." name="send_im"/>
+ <menu_item_call label="Добавить в друзьÑ..." name="add_friend"/>
+ <menu_item_call label="Удалить из друзей..." name="remove_friend"/>
<menu_item_call label="Копировать название в буфер обмена" name="url_copy_label"/>
<menu_item_call label="Копировать URL-Ð°Ð´Ñ€ÐµÑ SL в буфер обмена" name="url_copy"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/ru/menu_url_group.xml b/indra/newview/skins/default/xui/ru/menu_url_group.xml
index f25e2a7eb8..f25e2a7eb8 100644..100755
--- a/indra/newview/skins/default/xui/ru/menu_url_group.xml
+++ b/indra/newview/skins/default/xui/ru/menu_url_group.xml
diff --git a/indra/newview/skins/default/xui/ru/menu_url_http.xml b/indra/newview/skins/default/xui/ru/menu_url_http.xml
index 781211b16f..781211b16f 100644..100755
--- a/indra/newview/skins/default/xui/ru/menu_url_http.xml
+++ b/indra/newview/skins/default/xui/ru/menu_url_http.xml
diff --git a/indra/newview/skins/default/xui/ru/menu_url_inventory.xml b/indra/newview/skins/default/xui/ru/menu_url_inventory.xml
index 6127bf9868..6127bf9868 100644..100755
--- a/indra/newview/skins/default/xui/ru/menu_url_inventory.xml
+++ b/indra/newview/skins/default/xui/ru/menu_url_inventory.xml
diff --git a/indra/newview/skins/default/xui/ru/menu_url_map.xml b/indra/newview/skins/default/xui/ru/menu_url_map.xml
index bbf64f20e9..bbf64f20e9 100644..100755
--- a/indra/newview/skins/default/xui/ru/menu_url_map.xml
+++ b/indra/newview/skins/default/xui/ru/menu_url_map.xml
diff --git a/indra/newview/skins/default/xui/ru/menu_url_objectim.xml b/indra/newview/skins/default/xui/ru/menu_url_objectim.xml
index 6e7800d3f5..4f5361b2e3 100644..100755
--- a/indra/newview/skins/default/xui/ru/menu_url_objectim.xml
+++ b/indra/newview/skins/default/xui/ru/menu_url_objectim.xml
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Url Popup">
- <menu_item_call label="Показать информацию об объекте" name="show_object"/>
+ <menu_item_call label="Профиль объекта..." name="show_object"/>
+ <menu_item_call label="Блокировать..." name="block_object"/>
<menu_item_call label="Показать на карте" name="show_on_map"/>
<menu_item_call label="Телепорт в меÑтоположение объекта" name="teleport_to_object"/>
<menu_item_call label="Копировать название объекта в буфер обмена" name="url_copy_label"/>
diff --git a/indra/newview/skins/default/xui/ru/menu_url_parcel.xml b/indra/newview/skins/default/xui/ru/menu_url_parcel.xml
index 84a679703a..84a679703a 100644..100755
--- a/indra/newview/skins/default/xui/ru/menu_url_parcel.xml
+++ b/indra/newview/skins/default/xui/ru/menu_url_parcel.xml
diff --git a/indra/newview/skins/default/xui/ru/menu_url_slapp.xml b/indra/newview/skins/default/xui/ru/menu_url_slapp.xml
index 3d582ea2c5..3d582ea2c5 100644..100755
--- a/indra/newview/skins/default/xui/ru/menu_url_slapp.xml
+++ b/indra/newview/skins/default/xui/ru/menu_url_slapp.xml
diff --git a/indra/newview/skins/default/xui/ru/menu_url_slurl.xml b/indra/newview/skins/default/xui/ru/menu_url_slurl.xml
index cbceafea21..cbceafea21 100644..100755
--- a/indra/newview/skins/default/xui/ru/menu_url_slurl.xml
+++ b/indra/newview/skins/default/xui/ru/menu_url_slurl.xml
diff --git a/indra/newview/skins/default/xui/ru/menu_url_teleport.xml b/indra/newview/skins/default/xui/ru/menu_url_teleport.xml
index 2ecde09383..2ecde09383 100644..100755
--- a/indra/newview/skins/default/xui/ru/menu_url_teleport.xml
+++ b/indra/newview/skins/default/xui/ru/menu_url_teleport.xml
diff --git a/indra/newview/skins/default/xui/ru/menu_viewer.xml b/indra/newview/skins/default/xui/ru/menu_viewer.xml
index 0699314d97..fcb7c4e531 100644..100755
--- a/indra/newview/skins/default/xui/ru/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/ru/menu_viewer.xml
@@ -17,8 +17,8 @@
<menu_item_call label="Ходьба / бег / полет..." name="Walk / run / fly"/>
</menu>
<menu label="СтатуÑ" name="Status">
- <menu_item_call label="Ðет на меÑте" name="Set Away"/>
- <menu_item_call label="Ðе беÑпокоить" name="Set Busy"/>
+ <menu_item_check label="Ðет на меÑте" name="Away"/>
+ <menu_item_check label="Ðе беÑпокоить" name="Do Not Disturb"/>
</menu>
<menu_item_call label="Купить L$..." name="Buy and Sell L$"/>
<menu_item_call label="Торговые иÑходÑщие..." name="MerchantOutbox"/>
@@ -26,17 +26,25 @@
<menu_item_call label="ÐаÑтройки..." name="Preferences"/>
<menu_item_call label="Кнопки панели инÑтрументов..." name="Toolbars"/>
<menu_item_call label="Скрыть вÑе Ñлементы управлениÑ" name="Hide UI"/>
+ <menu_item_check label="Показывать приÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ HUD" name="Show HUD Attachments"/>
<menu_item_call label="Выход из [APP_NAME]" name="Quit"/>
</menu>
<menu label="Общение" name="Communicate">
- <menu_item_check label="Чат..." name="Nearby Chat"/>
+ <menu_item_check label="Разговоры..." name="Conversations"/>
+ <menu_item_check label="Локальный чат..." name="Nearby Chat"/>
<menu_item_check label="Говорить" name="Speak"/>
- <menu_item_check label="ÐаÑтройки голоÑа..." name="Nearby Voice"/>
- <menu_item_check label="Изменение голоÑа..." name="ShowVoice"/>
+ <menu_item_check label="Журнал разговора..." name="Conversation Log..."/>
+ <menu label="Изменение голоÑа" name="VoiceMorphing">
+ <menu_item_check label="Без Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð³Ð¾Ð»Ð¾Ñа" name="NoVoiceMorphing"/>
+ <menu_item_check label="ПроÑмотр..." name="Preview"/>
+ <menu_item_call label="ПодпиÑатьÑÑ..." name="Subscribe"/>
+ </menu>
<menu_item_check label="ЖеÑÑ‚Ñ‹..." name="Gestures"/>
- <menu_item_call label="ДрузьÑ" name="My Friends"/>
- <menu_item_call label="Группы" name="My Groups"/>
- <menu_item_call label="Люди неподалеку" name="Active Speakers"/>
+ <menu_item_check label="ДрузьÑ" name="My Friends"/>
+ <menu_item_check label="Группы" name="My Groups"/>
+ <menu_item_check label="Люди неподалеку" name="Active Speakers"/>
+ <menu_item_call label="Черный ÑпиÑок" name="Block List"/>
+ <menu_item_check label="Ðе беÑпокоить" name="Do Not Disturb"/>
</menu>
<menu label="Мир" name="World">
<menu_item_call label="Добавить закладку на Ñто меÑто" name="Create Landmark Here"/>
@@ -105,13 +113,13 @@
<menu_item_call label="Включить Ñледующую" name="Include Next Part"/>
<menu_item_call label="Включить предыдущую" name="Include Previous Part"/>
</menu>
+ <menu_item_call label="Ðаборы ÑвÑзей..." name="pathfinding_linkset_menu_item"/>
<menu_item_call label="Ð¤Ð¾ÐºÑƒÑ Ð½Ð° выбранном" name="Focus on Selection"/>
<menu_item_call label="Приблизить к выбранному" name="Zoom to Selection"/>
<menu label="Объект" name="Object">
<menu_item_call label="Купить" name="Menu Object Buy"/>
<menu_item_call label="ВзÑÑ‚ÑŒ" name="Menu Object Take"/>
<menu_item_call label="ВзÑÑ‚ÑŒ копию" name="Take Copy"/>
- <menu_item_call label="Сохранить в моем инвентаре" name="Save Object Back to My Inventory"/>
<menu_item_call label="Сохранить в контенте объектов" name="Save Object Back to Object Contents"/>
<menu_item_call label="Вернуть объект" name="Return Object back to Owner"/>
</menu>
@@ -122,6 +130,11 @@
<menu_item_call label="ЗапуÑтить Ñкрипты" name="Set Scripts to Running"/>
<menu_item_call label="ОÑтановить Ñкрипты" name="Set Scripts to Not Running"/>
</menu>
+ <menu label="ПоиÑк пути" name="Pathfinding">
+ <menu_item_call label="Ðаборы ÑвÑзей..." name="pathfinding_linksets_menu_item"/>
+ <menu_item_call label="ПерÑонажи..." name="pathfinding_characters_menu_item"/>
+ <menu_item_call label="ПроÑмотр/теÑтирование..." name="pathfinding_console_menu_item"/>
+ </menu>
<menu label="Параметры" name="Options">
<menu_item_check label="Показать раÑширенные разрешениÑ" name="DebugPermissions"/>
<menu_item_check label="Выбирать только мои объекты" name="Select Only My Objects"/>
@@ -172,7 +185,6 @@
<menu_item_check label="Скрыть чаÑтицы" name="Hide Particles"/>
<menu_item_check label="Скрыть выбранное" name="Hide Selected"/>
<menu_item_check label="ПодÑветка прозрачного" name="Highlight Transparent"/>
- <menu_item_check label="Показывать приÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ HUD" name="Show HUD Attachments"/>
<menu_item_check label="Показывать прицел при обзоре мышью" name="ShowCrosshairs"/>
</menu>
<menu label="Типы визуализации" name="Rendering Types">
@@ -225,11 +237,10 @@
<menu_item_check label="КонÑоль текÑтур" name="Texture Console"/>
<menu_item_check label="КонÑоль отладки" name="Debug Console"/>
<menu_item_call label="КонÑоль уведомлений" name="Notifications"/>
- <menu_item_check label="КонÑоль размера текÑтуры" name="Texture Size"/>
- <menu_item_check label="КонÑоль категории текÑтуры" name="Texture Category"/>
<menu_item_check label="Оперативные таймеры" name="Fast Timers"/>
<menu_item_check label="ПамÑÑ‚ÑŒ" name="Memory"/>
<menu_item_check label="СтатиÑтика по Ñцене" name="Scene Statistics"/>
+ <menu_item_call label="КонÑоль отладки Ð¸Ð·Ð²Ð»ÐµÑ‡ÐµÐ½Ð¸Ñ Ñ‚ÐµÐºÑтур" name="Texture Fetch Debug Console"/>
<menu_item_call label="Данные о регионе на конÑоль отладки" name="Region Info to Debug Console"/>
<menu_item_call label="Данны о группе на конÑоль отладки" name="Group Info to Debug Console"/>
<menu_item_call label="Данные о ÑпоÑобноÑÑ‚ÑÑ… на конÑоль отладки" name="Capabilities Info to Debug Console"/>
@@ -264,6 +275,7 @@
<menu_item_check label="Ð¡Ð»ÑƒÑ‡Ð°Ð¹Ð½Ð°Ñ Ñ‡Ð°Ñтота кадров" name="Randomize Framerate"/>
<menu_item_check label="ПериодичеÑкое замедление кадров" name="Periodic Slow Frame"/>
<menu_item_check label="ТеÑÑ‚ кадров" name="Frame Test"/>
+ <menu_item_call label="Профиль кадра" name="Frame Profile"/>
</menu>
<menu label="Визуализировать метаданные" name="Render Metadata">
<menu_item_check label="Рамки" name="Bounding Boxes"/>
@@ -287,14 +299,21 @@
<menu_item_check label="СложноÑÑ‚ÑŒ визуализации" name="rendercomplexity"/>
<menu_item_check label="Байты приÑоединениÑ" name="attachment bytes"/>
<menu_item_check label="Лепка" name="Sculpt"/>
+ <menu label="ПлотноÑÑ‚ÑŒ текÑтуры" name="Texture Density">
+ <menu_item_check label="Ðет" name="None"/>
+ <menu_item_check label="ТекущаÑ" name="Current"/>
+ <menu_item_check label="ЖелаемаÑ" name="Desired"/>
+ <menu_item_check label="ПолнаÑ" name="Full"/>
+ </menu>
</menu>
<menu label="ВизуализациÑ" name="Rendering">
<menu_item_check label="ОÑи" name="Axes"/>
<menu_item_check label="КаÑательный базиÑ" name="Tangent Basis"/>
<menu_item_call label="Ð’Ñ‹Ð±Ñ€Ð°Ð½Ð½Ð°Ñ Ñ‚ÐµÐºÑтура в оÑнове" name="Selected Texture Info Basis"/>
+ <menu_item_call label="Ð¡Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¾ выбранном материале" name="Selected Material Info"/>
<menu_item_check label="КаркаÑ" name="Wireframe"/>
<menu_item_check label="Смыкание объектов" name="Object-Object Occlusion"/>
- <menu_item_check label="ОÑвещение и тени" name="Lighting and Shadows"/>
+ <menu_item_check label="РаÑÑˆÐ¸Ñ€ÐµÐ½Ð½Ð°Ñ Ð¼Ð¾Ð´ÐµÐ»ÑŒ оÑвещениÑ" name="Advanced Lighting Model"/>
<menu_item_check label="Тени от Ñолнца, луны и прожекторов" name="Shadows from Sun/Moon/Projectors"/>
<menu_item_check label="SSAO и Ñглаживание теней" name="SSAO and Shadow Smoothing"/>
<menu_item_check label="Отладка GL" name="Debug GL"/>
@@ -304,8 +323,6 @@
<menu_item_check label="ТекÑтуры анимаций" name="Animation Textures"/>
<menu_item_check label="Отключить текÑтуры" name="Disable Textures"/>
<menu_item_check label="ТекÑтуры в полном разрешении" name="Rull Res Textures"/>
- <menu_item_check label="Проверить текÑтуры" name="Audit Textures"/>
- <menu_item_check label="ÐÑ‚Ð»Ð°Ñ Ñ‚ÐµÐºÑтур (ÑкÑÐ¿ÐµÑ€Ð¸Ð¼ÐµÐ½Ñ‚Ð°Ð»ÑŒÐ½Ð°Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ)" name="Texture Atlas"/>
<menu_item_check label="Ð’Ð¸Ð·ÑƒÐ°Ð»Ð¸Ð·Ð°Ñ†Ð¸Ñ Ð¿Ñ€Ð¸Ñоединенных иÑточников Ñвета" name="Render Attached Lights"/>
<menu_item_check label="Ð’Ð¸Ð·ÑƒÐ°Ð»Ð¸Ð·Ð°Ñ†Ð¸Ñ Ð¿Ñ€Ð¸Ñоединенных чаÑтиц" name="Render Attached Particles"/>
<menu_item_check label="ПарÑщие ÑветÑщиеÑÑ Ð¾Ð±ÑŠÐµÐºÑ‚Ñ‹" name="Hover Glow Objects"/>
@@ -341,7 +358,6 @@
<menu_item_call label="Вывод ÑредÑтва фокуÑировки" name="Dump Focus Holder"/>
<menu_item_call label="Печать информации о выбранных объектах" name="Print Selected Object Info"/>
<menu_item_call label="Печать информации об агенте" name="Print Agent Info"/>
- <menu_item_call label="СтатиÑтичеÑÐºÐ°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾ памÑти" name="Memory Stats"/>
<menu_item_check label="КонÑоль отладки региона" name="Region Debug Console"/>
<menu_item_check label="Отладка SelectMgr" name="Debug SelectMgr"/>
<menu_item_check label="Отладка щелчков мышью" name="Debug Clicks"/>
@@ -371,12 +387,10 @@
<menu_item_call label="Ðктивировать геометрию перÑонажа" name="Toggle Character Geometry"/>
<menu_item_call label="Проверка мужчины" name="Test Male"/>
<menu_item_call label="Проверка женщины" name="Test Female"/>
- <menu_item_call label="Ðктивировать PG-контент" name="Toggle PG"/>
<menu_item_check label="Разрешить выбор аватара" name="Allow Select Avatar"/>
</menu>
<menu_item_call label="Скинуть параметры" name="Force Params to Default"/>
<menu_item_check label="Данные об анимации" name="Animation Info"/>
- <menu_item_check label="ÐÐ½Ð¸Ð¼Ð°Ñ†Ð¸Ñ Ð¼ÐµÐ´Ð»ÐµÐ½Ð½Ñ‹Ñ… движений" name="Slow Motion Animations"/>
<menu_item_check label="Показать взглÑд" name="Show Look At"/>
<menu_item_check label="Показать указание" name="Show Point At"/>
<menu_item_check label="Отладка обновленных движений ÑуÑтавов" name="Debug Joint Updates"/>
diff --git a/indra/newview/skins/default/xui/ru/menu_wearable_list_item.xml b/indra/newview/skins/default/xui/ru/menu_wearable_list_item.xml
index 2832e17b7d..2832e17b7d 100644..100755
--- a/indra/newview/skins/default/xui/ru/menu_wearable_list_item.xml
+++ b/indra/newview/skins/default/xui/ru/menu_wearable_list_item.xml
diff --git a/indra/newview/skins/default/xui/ru/menu_wearing_gear.xml b/indra/newview/skins/default/xui/ru/menu_wearing_gear.xml
index c2351fbfff..c2351fbfff 100644..100755
--- a/indra/newview/skins/default/xui/ru/menu_wearing_gear.xml
+++ b/indra/newview/skins/default/xui/ru/menu_wearing_gear.xml
diff --git a/indra/newview/skins/default/xui/ru/menu_wearing_tab.xml b/indra/newview/skins/default/xui/ru/menu_wearing_tab.xml
index f178b39c77..f178b39c77 100644..100755
--- a/indra/newview/skins/default/xui/ru/menu_wearing_tab.xml
+++ b/indra/newview/skins/default/xui/ru/menu_wearing_tab.xml
diff --git a/indra/newview/skins/default/xui/ru/mime_types.xml b/indra/newview/skins/default/xui/ru/mime_types.xml
index 7ed23b5d53..7ed23b5d53 100644..100755
--- a/indra/newview/skins/default/xui/ru/mime_types.xml
+++ b/indra/newview/skins/default/xui/ru/mime_types.xml
diff --git a/indra/newview/skins/default/xui/ru/mime_types_linux.xml b/indra/newview/skins/default/xui/ru/mime_types_linux.xml
index a42b0bb9cc..a42b0bb9cc 100644..100755
--- a/indra/newview/skins/default/xui/ru/mime_types_linux.xml
+++ b/indra/newview/skins/default/xui/ru/mime_types_linux.xml
diff --git a/indra/newview/skins/default/xui/ru/mime_types_mac.xml b/indra/newview/skins/default/xui/ru/mime_types_mac.xml
index 7ed23b5d53..7ed23b5d53 100644..100755
--- a/indra/newview/skins/default/xui/ru/mime_types_mac.xml
+++ b/indra/newview/skins/default/xui/ru/mime_types_mac.xml
diff --git a/indra/newview/skins/default/xui/ru/notifications.xml b/indra/newview/skins/default/xui/ru/notifications.xml
index b4692385d1..1dc8202b00 100644..100755
--- a/indra/newview/skins/default/xui/ru/notifications.xml
+++ b/indra/newview/skins/default/xui/ru/notifications.xml
@@ -37,6 +37,12 @@
<button name="Help" text="$helptext"/>
</form>
</template>
+ <template name="okhelpignore">
+ <form>
+ <button name="OK_okhelpignore" text="$yestext"/>
+ <button name="Help_okhelpignore" text="$helptext"/>
+ </form>
+ </template>
<template name="yesnocancelbuttons">
<form>
<button name="Yes" text="$yestext"/>
@@ -204,6 +210,14 @@
Добавить Ñту ÑпоÑобноÑÑ‚ÑŒ к роли «[ROLE_NAME]»?
<usetemplate name="okcancelbuttons" notext="Ðет" yestext="Да"/>
</notification>
+ <notification name="EjectGroupMemberWarning">
+ Ð’Ñ‹ ÑобираетеÑÑŒ иÑключить [AVATAR_NAME] из группы.
+ <usetemplate ignoretext="Подтвердите иÑключение учаÑтника из группы" name="okcancelignore" notext="Отмена" yestext="Выкинуть"/>
+ </notification>
+ <notification name="EjectGroupMembersWarning">
+ Ð’Ñ‹ ÑобираетеÑÑŒ иÑключить [COUNT] учаÑтников из группы.
+ <usetemplate ignoretext="Подтвердите иÑключение учаÑтников из группы" name="okcancelignore" notext="Отмена" yestext="Выкинуть"/>
+ </notification>
<notification name="AttachmentDrop">
Ð’Ñ‹ ÑобираетеÑÑŒ ÑброÑить Ñвое приÑоединение.
Продолжить?
@@ -360,13 +374,19 @@
Ð”Ð»Ñ Ð²Ñ…Ð¾Ð´Ð° в [SECOND_LIFE] нужен аккаунт. Создать его?
<url name="url">
- http://join.secondlife.com/
+ [create_account_url]
</url>
<usetemplate name="okcancelbuttons" notext="Повторить попытку" yestext="Создать новый аккаунт"/>
</notification>
<notification name="InvalidCredentialFormat">
Введите Ð¸Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð¸Ð»Ð¸ Ð¸Ð¼Ñ Ð¸ фамилию вашего аватара в поле Â«Ð˜Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ», затем Ñнова войдите в программу.
</notification>
+ <notification name="InvalidGrid">
+ «[GRID]» – недопуÑтимый идентификатор Ñетки.
+ </notification>
+ <notification name="InvalidLocationSLURL">
+ Ð’ меÑте Ñтарта не указана Ð¿Ñ€Ð°Ð²Ð¸Ð»ÑŒÐ½Ð°Ñ Ñетка.
+ </notification>
<notification name="DeleteClassified">
Удалить рекламу «[NAME]»?
Плата за нее не будет возвращена.
@@ -472,8 +492,8 @@
Ошибка при Ñохранении Ñкомпилированного Ñкрипта по Ñледующей причине: [REASON]. Попробуйте Ñохранить Ñкрипт через некоторое времÑ.
</notification>
<notification name="StartRegionEmpty">
- Ðй-Ñй-Ñй, ваш Ñтартовый регион не определен.
-Введите название региона в поле «МеÑто Ñтарта» или выберите в качеÑтве меÑта Ñтарта «Мое поÑледнее меÑтоположение» или «Мой дом».
+ Ваш Ñтартовый регион не определен.
+Введите название региона в поле «МеÑто Ñтарта» или выберите в качеÑтве меÑта Ñтарта «Мое поÑледнее меÑто» или «Мой дом».
<usetemplate name="okbutton" yestext="OK"/>
</notification>
<notification name="CouldNotStartStopScript">
@@ -495,6 +515,33 @@
</url>
<usetemplate ignoretext="Оборудование моего компьютера не поддерживаетÑÑ" name="okcancelignore" notext="Ðет" yestext="Да"/>
</notification>
+ <notification name="IntelOldDriver">
+ Возможно, Ð´Ð»Ñ Ð²Ð°ÑˆÐµÐ¹ видеокарты имеетÑÑ Ð±Ð¾Ð»ÐµÐµ новый драйвер. Обновление драйвера может ÑущеÑтвенно повыÑить быÑтродейÑтвие.
+
+ Проверить наличие Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ð´Ñ€Ð°Ð¹Ð²ÐµÑ€Ð° по адреÑу [_URL]?
+ <url name="url">
+ http://www.intel.com/p/ru_RU/support/detect/graphics
+ </url>
+ <usetemplate ignoretext="Мой графичеÑкий драйвер уÑтарел" name="okcancelignore" notext="Ðет" yestext="Да"/>
+ </notification>
+ <notification name="AMDOldDriver">
+ Возможно, Ð´Ð»Ñ Ð²Ð°ÑˆÐµÐ¹ видеокарты имеетÑÑ Ð±Ð¾Ð»ÐµÐµ новый драйвер. Обновление драйвера может ÑущеÑтвенно повыÑить быÑтродейÑтвие.
+
+ Проверить наличие Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ð´Ñ€Ð°Ð¹Ð²ÐµÑ€Ð° по адреÑу [_URL]?
+ <url name="url">
+ http://support.amd.com/us/Pages/AMDSupportHub.aspx
+ </url>
+ <usetemplate ignoretext="Мой графичеÑкий драйвер уÑтарел" name="okcancelignore" notext="Ðет" yestext="Да"/>
+ </notification>
+ <notification name="NVIDIAOldDriver">
+ Возможно, Ð´Ð»Ñ Ð²Ð°ÑˆÐµÐ¹ видеокарты имеетÑÑ Ð±Ð¾Ð»ÐµÐµ новый драйвер. Обновление драйвера может ÑущеÑтвенно повыÑить быÑтродейÑтвие.
+
+ Проверить наличие Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ð´Ñ€Ð°Ð¹Ð²ÐµÑ€Ð° по адреÑу [_URL]?
+ <url name="url">
+ http://www.nvidia.com/Download/index.aspx?lang=ru-ru
+ </url>
+ <usetemplate ignoretext="Мой графичеÑкий драйвер уÑтарел" name="okcancelignore" notext="Ðет" yestext="Да"/>
+ </notification>
<notification name="UnknownGPU">
Ð’ вашей ÑиÑтеме уÑтановлена графичеÑÐºÐ°Ñ ÐºÐ°Ñ€Ñ‚Ð°, которую [APP_NAME] не может раÑпознать.
Так чаÑто бывает, еÑли новое оборудование еще не было проверено на работу Ñ [APP_NAME]. Скорее вÑего, оно будет работать нормально, но, возможно, придетÑÑ Ð¾Ñ‚Ñ€ÐµÐ³ÑƒÐ»Ð¸Ñ€Ð¾Ð²Ð°Ñ‚ÑŒ параметры графики.
@@ -591,6 +638,9 @@
УбедитеÑÑŒ, что вÑе объекты разблокированы и что вы владеете вÑеми ими.
</notification>
+ <notification name="CannotLinkPermanent">
+ Объекты Ð½ÐµÐ»ÑŒÐ·Ñ ÑвÑзывать через границу региона.
+ </notification>
<notification name="CannotLinkDifferentOwners">
Ðевозможно объединить объекты: не у вÑех объектов один владелец.
@@ -969,6 +1019,41 @@
<button name="Cancel" text="Отмена"/>
</form>
</notification>
+ <notification label="Добавить ÑпиÑок автозамены" name="AddAutoReplaceList">
+ Ð˜Ð¼Ñ Ð½Ð¾Ð²Ð¾Ð³Ð¾ ÑпиÑка:
+ <form name="form">
+ <button name="SetName" text="OK"/>
+ </form>
+ </notification>
+ <notification label="Переименовать ÑпиÑок автозамены" name="RenameAutoReplaceList">
+ Ð˜Ð¼Ñ Â«[DUPNAME]» уже занÑто.
+ Введите новое уникальное имÑ:
+ <form name="form">
+ <button name="ReplaceList" text="Заменить текущий ÑпиÑок"/>
+ <button name="SetName" text="ИÑпользовать новое имÑ"/>
+ </form>
+ </notification>
+ <notification name="InvalidAutoReplaceEntry">
+ Ключевое Ñлово должно быть одним Ñловом, а поле замены не может быть пуÑтым.
+ </notification>
+ <notification name="InvalidAutoReplaceList">
+ ÐедопуÑтимый ÑпиÑок замены.
+ </notification>
+ <notification name="SpellingDictImportRequired">
+ Следует указать файл, Ð¸Ð¼Ñ Ð¸ Ñзык.
+ </notification>
+ <notification name="SpellingDictIsSecondary">
+ Словарь [DIC_NAME] не ÑвлÑетÑÑ aff-файлом, Ñ‚. е. Ñто «вÑпомогательный» Ñловарь.
+Он может иÑпользоватьÑÑ ÐºÐ°Ðº дополнительный, но не как оÑновной Ñловарь.
+
+См. https://wiki.secondlife.com/wiki/Adding_Spelling_Dictionaries
+ </notification>
+ <notification name="SpellingDictImportFailed">
+ Ðевозможно Ñкопировать
+ [FROM_NAME]
+ в
+ [TO_NAME]
+ </notification>
<notification label="Сохранить коÑтюм" name="SaveOutfitAs">
Сохранить текущую одежду как новый коÑтюм:
<form name="form">
@@ -1034,7 +1119,7 @@
Введите более выÑокую цену.
</notification>
<notification name="ConfirmItemDeleteHasLinks">
- ИмеетÑÑ ÑÑылка, ÑƒÐºÐ°Ð·Ñ‹Ð²Ð°ÑŽÑ‰Ð°Ñ ÐºÐ°Ðº минимум на один из выбранных вами предметов. ЕÑли удалить Ñтот предмет, его ÑÑылки переÑтанут работать. ÐаÑтоÑтельно рекомендуетÑÑ Ñначала удалить ÑÑылки.
+ По крайней мере у одного предмета еÑÑ‚ÑŒ ÑÑылки, указывающие на него. ЕÑли удалить Ñтот предмет, его ÑÑылки переÑтанут работать. ÐаÑтоÑтельно рекомендуетÑÑ Ñначала удалить ÑÑылки.
ДейÑтвительно удалить Ñти предметы?
<usetemplate name="okcancelbuttons" notext="Отмена" yestext="OK"/>
@@ -1084,7 +1169,7 @@
Вы не владеете по крайней мере одним объектом.
ДейÑтвительно удалить Ñти предметы?
- <usetemplate name="okcancelbuttons" notext="отмена" yestext="OK"/>
+ <usetemplate name="okcancelbuttons" notext="Отмена" yestext="OK"/>
</notification>
<notification name="ConfirmObjectTakeLock">
Как минимум один объект фикÑирован.
@@ -1148,7 +1233,7 @@
Ð’Ñ‹ перемещены в ÑоÑедний регион.
</notification>
<notification name="AvatarMovedLast">
- Ваше поÑледнее меÑтоположение ÑÐµÐ¹Ñ‡Ð°Ñ Ð½ÐµÐ´Ð¾Ñтупно.
+ Требуемое вами меÑтоположение ÑÐµÐ¹Ñ‡Ð°Ñ Ð½ÐµÐ´Ð¾Ñтупно.
Ð’Ñ‹ перемещены в ÑоÑедний регион.
</notification>
<notification name="AvatarMovedHome">
@@ -1167,7 +1252,6 @@
УÑтановка [APP_NAME] завершена.
ЕÑли вы иÑпользуете [SECOND_LIFE] впервые, Ð´Ð»Ñ Ð²Ñ…Ð¾Ð´Ð° в программу вам потребуетÑÑ Ñоздать аккаунт.
-ВернутьÑÑ Ð½Ð° [http://join.secondlife.com secondlife.com] Ð´Ð»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð°ÐºÐºÐ°ÑƒÐ½Ñ‚Ð°?
<usetemplate name="okcancelbuttons" notext="Продолжить" yestext="Создать аккаунт..."/>
</notification>
<notification name="LoginPacketNeverReceived">
@@ -1404,13 +1488,43 @@ http://secondlife.com/download.
</notification>
<notification name="RequiredUpdateDownloadedVerboseDialog">
Загружено обÑзательное обновление.
-ВерÑÐ¸Ñ [VERSION]
+ВерÑÐ¸Ñ [VERSION]. [[INFO_URL] Ð¡Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¾Ð± Ñтом обновлении]
Ðеобходимо перезапуÑтить [APP_NAME] Ð´Ð»Ñ ÑƒÑтановки обновлениÑ.
<usetemplate name="okbutton" yestext="OK"/>
</notification>
<notification name="RequiredUpdateDownloadedDialog">
Ðеобходимо перезапуÑтить [APP_NAME] Ð´Ð»Ñ ÑƒÑтановки обновлениÑ.
+[[INFO_URL] Ð¡Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¾Ð± Ñтом обновлении]
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
+ <notification name="OtherChannelDownloadBackgroundTip">
+ Загружено обновление Ð´Ð»Ñ Ð²Ð°ÑˆÐµÐ¹ верÑии [APP_NAME].
+ВерÑÐ¸Ñ [VERSION]
+Ðа замену Ñтой ÑкÑпериментальной верÑии клиента предлагаетÑÑ ÐºÐ»Ð¸ÐµÐ½Ñ‚ [NEW_CHANNEL];
+Ñм. [[INFO_URL] об Ñтом обновлении]
+ <usetemplate name="okcancelbuttons" notext="Позже..." yestext="УÑтановите обновление и перезапуÑтите [APP_NAME]"/>
+ </notification>
+ <notification name="OtherChannelDownloadBackgroundDialog">
+ Загружено обновление Ð´Ð»Ñ Ð²Ð°ÑˆÐµÐ¹ верÑии [APP_NAME].
+ВерÑÐ¸Ñ [VERSION]
+Ðа замену Ñтой ÑкÑпериментальной верÑии клиента предлагаетÑÑ ÐºÐ»Ð¸ÐµÐ½Ñ‚ [NEW_CHANNEL];
+Ñм. [[INFO_URL] Ð¡Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¾Ð± Ñтом обновлении]
+ <usetemplate name="okcancelbuttons" notext="Позже..." yestext="УÑтановите обновление и перезапуÑтите [APP_NAME]"/>
+ </notification>
+ <notification name="OtherChannelRequiredUpdateDownloadedVerboseDialog">
+ Загружено обÑзательное обновление.
+ВерÑÐ¸Ñ [VERSION]
+Ðа замену Ñтой ÑкÑпериментальной верÑии клиента предлагаетÑÑ ÐºÐ»Ð¸ÐµÐ½Ñ‚ [NEW_CHANNEL];
+Ñм. [[INFO_URL] Ð¡Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¾Ð± Ñтом обновлении]
+
+Ðеобходимо перезапуÑтить [APP_NAME] Ð´Ð»Ñ ÑƒÑтановки обновлениÑ.
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
+ <notification name="OtherChannelRequiredUpdateDownloadedDialog">
+ Ðеобходимо перезапуÑтить [APP_NAME] Ð´Ð»Ñ ÑƒÑтановки обновлениÑ.
+Ðа замену Ñтой ÑкÑпериментальной верÑии клиента предлагаетÑÑ ÐºÐ»Ð¸ÐµÐ½Ñ‚ [NEW_CHANNEL];
+Ñм. [[INFO_URL] Ð¡Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¾Ð± Ñтом обновлении]
<usetemplate name="okbutton" yestext="OK"/>
</notification>
<notification name="DeedObjectToGroup">
@@ -1461,6 +1575,10 @@ http://secondlife.com/download.
Хотите покинуть группу?
<usetemplate name="okcancelbuttons" notext="Отмена" yestext="OK"/>
</notification>
+ <notification name="OwnerCannotLeaveGroup">
+ Ðевозможно покинуть группу. Ð’Ñ‹ не можете покинуть группу, так как вы ее поÑледний владелец. Сначала назначьте владельцем другого учаÑтника.
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
<notification name="ConfirmKick">
Ð’Ñ‹ ДЕЙСТВИТЕЛЬÐО хотите выброÑить вÑех жителей Ñ Ñетки?
<usetemplate name="okcancelbuttons" notext="Отмена" yestext="ВыброÑить вÑех жителей"/>
@@ -1488,10 +1606,13 @@ http://secondlife.com/download.
Ð¡ÐµÐ¹Ñ‡Ð°Ñ Ð½ÐµÐ²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾ предложить дружбу. Повторите попытку через минуту.
<usetemplate name="okbutton" yestext="OK"/>
</notification>
- <notification name="BusyModeSet">
- УÑтановлен режим «ЗанÑт».
-Ð¡Ð¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ñ‡Ð°Ñ‚Ð° и IM будут Ñкрыты. Ðа IM-ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð±ÑƒÐ´ÐµÑ‚ возвращатьÑÑ Ð·Ð°Ð´Ð°Ð½Ð½Ñ‹Ð¹ ответ в режиме «ЗанÑт». Ð’Ñе Ð¿Ñ€ÐµÐ´Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ñ‚ÐµÐ»ÐµÐ¿Ð¾Ñ€Ñ‚Ð°Ñ†Ð¸Ð¸ будут отклонÑÑ‚ÑŒÑÑ. Ð’Ñе Ð¿Ñ€ÐµÐ´Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð¸Ð½Ð²ÐµÐ½Ñ‚Ð°Ñ€Ñ Ð±ÑƒÐ´ÑƒÑ‚ направлены в корзину.
- <usetemplate ignoretext="Смена моего ÑтатуÑа на режим «ЗанÑт»" name="okignore" yestext="OK"/>
+ <notification name="DoNotDisturbModeSet">
+ Режим «Ðе беÑпокоить» включен. Ð’Ñ‹ не будете получать уведомлений о входÑщих вызовах.
+
+- Другие жители будут получать ваш ответ, уÑтановленный Ð´Ð»Ñ Ñ€ÐµÐ¶Ð¸Ð¼Ð° «Ðе беÑпокоить» (ÐаÑтройки &gt; Общие).
+- ÐŸÑ€ÐµÐ´Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ñ‚ÐµÐ»ÐµÐ¿Ð¾Ñ€Ñ‚Ð°Ñ†Ð¸Ð¸ будут отклонÑÑ‚ÑŒÑÑ.
+- ГолоÑовые вызовы будут отклонÑÑ‚ÑŒÑÑ.
+ <usetemplate ignoretext="Смена моего ÑтатуÑа на режим «Ðе беÑпокоить»" name="okignore" yestext="OK"/>
</notification>
<notification name="JoinedTooManyGroupsMember">
ДоÑтигнуто макÑимальное количеÑтво групп. Выйдите из другой группы, прежде чем вÑтупать в Ñту, или отклоните предложение.
@@ -1685,83 +1806,128 @@ http://secondlife.com/download.
<usetemplate name="okcancelbuttons" notext="Отмена" yestext="OK"/>
</notification>
<notification name="RegionEntryAccessBlocked">
- Вам Ð½ÐµÐ»ÑŒÐ·Ñ Ð±Ñ‹Ñ‚ÑŒ в Ñтом регионе из-за вашего рейтинга зрелоÑти. Возможно, Ñто результат недоÑтатка информации, подтверждающей ваш возраÑÑ‚.
-
-УбедитеÑÑŒ, что у Ð²Ð°Ñ ÑƒÑтановлена поÑледнÑÑ Ð²ÐµÑ€ÑÐ¸Ñ ÐºÐ»Ð¸ÐµÐ½Ñ‚Ð°, и прочитайте в Базе знаний о доÑтупе к облаÑÑ‚Ñм Ñ Ñтим рейтингом зрелоÑти.
+ Ð’Ñ‹ пытаетеÑÑŒ поÑетить регион, контент в котором не ÑоответÑтвует вашим наÑтройкам. Попробуйте изменить наÑтройки в меню «Я &gt; ÐаÑтройки &gt; Общие».
<usetemplate name="okbutton" yestext="OK"/>
</notification>
- <notification name="RegionEntryAccessBlocked_KB">
- Вам Ð½ÐµÐ»ÑŒÐ·Ñ Ð±Ñ‹Ñ‚ÑŒ в Ñтом регионе из-за вашего рейтинга зрелоÑти.
-
-Перейти в Базу знаний и ознакомитьÑÑ Ñ Ñ€ÐµÐ¹Ñ‚Ð¸Ð½Ð³Ð°Ð¼Ð¸ зрелоÑти?
+ <notification name="RegionEntryAccessBlocked_AdultsOnlyContent">
+ Ð’Ñ‹ пытаетеÑÑŒ поÑетить регион, контент в котором имеет рейтинг [REGIONMATURITY] и предназначен только Ð´Ð»Ñ Ð²Ð·Ñ€Ð¾Ñлых.
<url name="url">
http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview
</url>
- <usetemplate ignoretext="Я не могу войти в Ñтот регион из-за ограничений по рейтингу зрелоÑти" name="okcancelignore" notext="Закрыть" yestext="Перейти в Базу знаний"/>
+ <usetemplate ignoretext="ПереÑечение региона: вы пытаетеÑÑŒ поÑетить регион, контент в котором предназначен только Ð´Ð»Ñ Ð²Ð·Ñ€Ð¾Ñлых." name="okcancelignore" notext="Закрыть" yestext="Перейти в Базу знаний"/>
</notification>
<notification name="RegionEntryAccessBlocked_Notify">
- Вам Ð½ÐµÐ»ÑŒÐ·Ñ Ð±Ñ‹Ñ‚ÑŒ в Ñтом регионе из-за вашего рейтинга зрелоÑти.
+ Ð’Ñ‹ пытаетеÑÑŒ поÑетить регион, контент в котором имеет рейтинг [REGIONMATURITY], но ваши наÑтройки не допуÑкают контента [REGIONMATURITY].
+ </notification>
+ <notification name="RegionEntryAccessBlocked_NotifyAdultsOnly">
+ Ð’Ñ‹ пытаетеÑÑŒ поÑетить регион, контент в котором имеет рейтинг [REGIONMATURITY] и предназначен только Ð´Ð»Ñ Ð²Ð·Ñ€Ð¾Ñлых.
</notification>
<notification name="RegionEntryAccessBlocked_Change">
- Вам Ð½ÐµÐ»ÑŒÐ·Ñ Ð±Ñ‹Ñ‚ÑŒ в Ñтом регионе из-за вашей наÑтройки рейтинга зрелоÑти.
-
-Ð”Ð»Ñ Ð²Ñ…Ð¾Ð´Ð° в желаемый регион измените наÑтройку рейтинга зрелоÑти. ПоÑле Ñтого вам будет разрешено иÑкать и проÑматривать контент [REGIONMATURITY]. Ð”Ð»Ñ Ð¾Ñ‚Ð¼ÐµÐ½Ñ‹ изменений выберите команды «Я &gt; ÐаÑтройки &gt; Общие».
+ Ð’Ñ‹ пытаетеÑÑŒ поÑетить регион, контент в котором имеет рейтинг [REGIONMATURITY], но ваши наÑтройки не допуÑкают контента [REGIONMATURITY]. Ð’Ñ‹ можете отказатьÑÑ Ð¾Ñ‚ поÑещениÑ, или ваши наÑтройки будут изменены. ПоÑле Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð½Ð°Ñтроек вы можете попробовать войти в регион Ñнова.
+ <form name="form">
+ <button name="OK" text="Изменить наÑтройки"/>
+ <button name="Cancel" text="Отмена"/>
+ <ignore name="ignore" text="ПереÑечение региона: вы пытаетеÑÑŒ поÑетить регион, контент в котором запрещен вашими наÑтройками."/>
+ </form>
+ </notification>
+ <notification name="RegionEntryAccessBlocked_PreferencesOutOfSync">
+ При телепортации возникли техничеÑкие проблемы, так как ваши наÑтройки не Ñинхронизированы Ñ Ñервером.
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
+ <notification name="TeleportEntryAccessBlocked">
+ Ð’Ñ‹ пытаетеÑÑŒ поÑетить регион, контент в котором не ÑоответÑтвует вашим наÑтройкам. Попробуйте изменить наÑтройки в меню «Я &gt; ÐаÑтройки &gt; Общие».
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
+ <notification name="TeleportEntryAccessBlocked_AdultsOnlyContent">
+ Ð’Ñ‹ пытаетеÑÑŒ поÑетить регион, контент в котором имеет рейтинг [REGIONMATURITY] и предназначен только Ð´Ð»Ñ Ð²Ð·Ñ€Ð¾Ñлых.
+ <url name="url">
+ http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview
+ </url>
+ <usetemplate ignoretext="ТелепортациÑ: вы пытаетеÑÑŒ поÑетить регион, контент в котором предназначен только Ð´Ð»Ñ Ð²Ð·Ñ€Ð¾Ñлых." name="okcancelignore" notext="Закрыть" yestext="Перейти в Базу знаний"/>
+ </notification>
+ <notification name="TeleportEntryAccessBlocked_Notify">
+ Ð’Ñ‹ пытаетеÑÑŒ поÑетить регион, контент в котором имеет рейтинг [REGIONMATURITY], но ваши наÑтройки не допуÑкают контента [REGIONMATURITY].
+ </notification>
+ <notification name="TeleportEntryAccessBlocked_NotifyAdultsOnly">
+ Ð’Ñ‹ пытаетеÑÑŒ поÑетить регион, контент в котором имеет рейтинг [REGIONMATURITY] и предназначен только Ð´Ð»Ñ Ð²Ð·Ñ€Ð¾Ñлых.
+ </notification>
+ <notification name="TeleportEntryAccessBlocked_ChangeAndReTeleport">
+ Ð’Ñ‹ пытаетеÑÑŒ поÑетить регион, контент в котором имеет рейтинг [REGIONMATURITY], но ваши наÑтройки не допуÑкают контента [REGIONMATURITY]. Ð’Ñ‹ можете отказатьÑÑ Ð¾Ñ‚ телепортации, или ваши наÑтройки будут изменены.
+ <form name="form">
+ <button name="OK" text="Изменить и продолжить"/>
+ <button name="Cancel" text="Отмена"/>
+ <ignore name="ignore" text="Ð¢ÐµÐ»ÐµÐ¿Ð¾Ñ€Ñ‚Ð°Ñ†Ð¸Ñ (возобновлÑемаÑ): вы пытаетеÑÑŒ поÑетить регион, контент в котором запрещен вашими наÑтройками."/>
+ </form>
+ </notification>
+ <notification name="TeleportEntryAccessBlocked_Change">
+ Ð’Ñ‹ пытаетеÑÑŒ поÑетить регион, контент в котором имеет рейтинг [REGIONMATURITY], но ваши наÑтройки не допуÑкают контента [REGIONMATURITY]. Ð’Ñ‹ можете отказатьÑÑ Ð¾Ñ‚ телепортации, или ваши наÑтройки будут изменены. ПоÑле Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð½Ð°Ñтроек вы можете попробовать телепортироватьÑÑ Ñнова.
<form name="form">
- <button name="OK" text="Изменить наÑтройку"/>
- <button name="Cancel" text="Закрыть"/>
- <ignore name="ignore" text="Ð’Ñ‹Ð±Ñ€Ð°Ð½Ð½Ð°Ñ Ð¼Ð½Ð¾Ð¹ наÑтройка рейтинга запрещает мне вход в регион"/>
+ <button name="OK" text="Изменить наÑтройки"/>
+ <button name="Cancel" text="Отмена"/>
+ <ignore name="ignore" text="Ð¢ÐµÐ»ÐµÐ¿Ð¾Ñ€Ñ‚Ð°Ñ†Ð¸Ñ (невозобновлÑемаÑ): вы пытаетеÑÑŒ поÑетить регион, контент в котором запрещен вашими наÑтройками."/>
</form>
</notification>
+ <notification name="TeleportEntryAccessBlocked_PreferencesOutOfSync">
+ При телепортации возникли техничеÑкие проблемы, так как ваши наÑтройки не Ñинхронизированы Ñ Ñервером.
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
<notification name="PreferredMaturityChanged">
- Теперь ваша наÑтройка рейтинга зрелоÑти: [RATING].
+ Ð’Ñ‹ больше не будете получать уведомлений о поÑещении региона Ñ ÐºÐ¾Ð½Ñ‚ÐµÐ½Ñ‚Ð¾Ð¼ рейтинга [RATING]. ÐаÑтройки Ð´Ð»Ñ ÐºÐ¾Ð½Ñ‚ÐµÐ½Ñ‚Ð° можно изменить на будущее Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ команд меню «Я &gt; ÐаÑтройки &gt; Общие».
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
+ <notification name="MaturityChangeError">
+ Ðе удалоÑÑŒ изменить ваши наÑтройки так, чтобы вы могли видеть контент Ñ Ñ€ÐµÐ¹Ñ‚Ð¸Ð½Ð³Ð¾Ð¼ [PREFERRED_MATURITY]. Ваши теперешние наÑтройки разрешают проÑматривать контент [ACTUAL_MATURITY]. Попробуйте изменить наÑтройки Ñнова Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ команд меню «Я &gt; ÐаÑтройки &gt; Общие».
+ <usetemplate name="okbutton" yestext="OK"/>
</notification>
<notification name="LandClaimAccessBlocked">
- Ð’Ñ‹ не можете претендовать на Ñту землю из-за вашего рейтинга зрелоÑти. Возможно, Ñто результат недоÑтатка информации, подтверждающей ваш возраÑÑ‚.
-
-УбедитеÑÑŒ, что у Ð²Ð°Ñ ÑƒÑтановлена поÑледнÑÑ Ð²ÐµÑ€ÑÐ¸Ñ ÐºÐ»Ð¸ÐµÐ½Ñ‚Ð°, и прочитайте в Базе знаний о доÑтупе к облаÑÑ‚Ñм Ñ Ñтим рейтингом зрелоÑти.
+ Ð’Ñ‹ претендуете на землю, рейтинг зрелоÑти контента на которой не ÑоответÑтвует вашим наÑтройкам. Попробуйте изменить наÑтройки в меню «Я &gt; ÐаÑтройки &gt; Общие».
<usetemplate name="okbutton" yestext="OK"/>
</notification>
- <notification name="LandClaimAccessBlocked_KB">
- Ð’Ñ‹ не можете претендовать на Ñту землю из-за вашего рейтинга зрелоÑти.
-
-Перейти в Базу знаний и ознакомитьÑÑ Ñ Ñ€ÐµÐ¹Ñ‚Ð¸Ð½Ð³Ð°Ð¼Ð¸ зрелоÑти?
+ <notification name="LandClaimAccessBlocked_AdultsOnlyContent">
+ Ðа Ñту землю могут претендовать только взроÑлые.
<url name="url">
http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview
</url>
- <usetemplate ignoretext="Я не могу претендовать на Ñту землю из-за ограничений по рейтингу зрелоÑти" name="okcancelignore" notext="Закрыть" yestext="Перейти в Базу знаний"/>
+ <usetemplate ignoretext="Ðа Ñту землю могут претендовать только взроÑлые." name="okcancelignore" notext="Закрыть" yestext="Перейти в Базу знаний"/>
</notification>
<notification name="LandClaimAccessBlocked_Notify">
- Ð’Ñ‹ не можете претендовать на Ñту землю из-за вашего рейтинга зрелоÑти.
+ Ð’Ñ‹ претендуете на землю, контент на которой имеет рейтинг [REGIONMATURITY], но ваши наÑтройки не допуÑкают контента [REGIONMATURITY].
+ </notification>
+ <notification name="LandClaimAccessBlocked_NotifyAdultsOnly">
+ Ð’Ñ‹ претендуете на землю Ñ ÐºÐ¾Ð½Ñ‚ÐµÐ½Ñ‚Ð¾Ð¼ [REGIONMATURITY], который предназначен только Ð´Ð»Ñ Ð²Ð·Ñ€Ð¾Ñлых.
</notification>
<notification name="LandClaimAccessBlocked_Change">
- Ð’Ñ‹ не можете претендовать на Ñту землю из-за вашей наÑтройки рейтинга зрелоÑти.
-
-Ðажмите кнопку «Изменить наÑтройку», чтобы повыÑить Ñвой рейтинг зрелоÑти. ПоÑле Ñтого вам будет разрешено иÑкать и проÑматривать контент [REGIONMATURITY]. ЕÑли в будущем понадобитÑÑ Ð¾Ñ‚Ð¼ÐµÐ½Ð¸Ñ‚ÑŒ Ñто изменение, выберите команды «Я &gt; ÐаÑтройки &gt; Общие».
- <usetemplate ignoretext="Ð’Ñ‹Ð±Ñ€Ð°Ð½Ð½Ð°Ñ Ð¼Ð½Ð¾Ð¹ наÑтройка рейтинга запрещает мне претендовать на землю" name="okcancelignore" notext="Закрыть" yestext="Изменить наÑтройку"/>
+ Ð’Ñ‹ претендуете на землю, контент на которой имеет рейтинг [REGIONMATURITY], но ваши наÑтройки не допуÑкают контента [REGIONMATURITY]. Мы можем изменить ваши наÑтройки, поÑле чего вы Ñможете претендовать на землю Ñнова.
+ <form name="form">
+ <button name="OK" text="Изменить наÑтройки"/>
+ <button name="Cancel" text="Отмена"/>
+ <ignore name="ignore" text="Ð’Ñ‹ претендуете на землю, контент на которой запрещен вашими наÑтройками."/>
+ </form>
</notification>
<notification name="LandBuyAccessBlocked">
- Ð’Ñ‹ не можете купить Ñту землю из-за вашего рейтинга зрелоÑти. Возможно, Ñто результат недоÑтатка информации, подтверждающей ваш возраÑÑ‚.
-
-УбедитеÑÑŒ, что у Ð²Ð°Ñ ÑƒÑтановлена поÑледнÑÑ Ð²ÐµÑ€ÑÐ¸Ñ ÐºÐ»Ð¸ÐµÐ½Ñ‚Ð°, и прочитайте в Базе знаний о доÑтупе к облаÑÑ‚Ñм Ñ Ñтим рейтингом зрелоÑти.
+ Ð’Ñ‹ пытаетеÑÑŒ купить землю, рейтинг зрелоÑти контента на которой не ÑоответÑтвует вашим наÑтройкам. Попробуйте изменить наÑтройки в меню «Я &gt; ÐаÑтройки &gt; Общие».
<usetemplate name="okbutton" yestext="OK"/>
</notification>
- <notification name="LandBuyAccessBlocked_KB">
- Ð’Ñ‹ не можете купить Ñту землю из-за вашего рейтинга зрелоÑти.
-
-Перейти в Базу знаний и ознакомитьÑÑ Ñ Ñ€ÐµÐ¹Ñ‚Ð¸Ð½Ð³Ð°Ð¼Ð¸ зрелоÑти?
+ <notification name="LandBuyAccessBlocked_AdultsOnlyContent">
+ Эту землю могут купить только взроÑлые.
<url name="url">
http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview
</url>
- <usetemplate ignoretext="Я не могу купить Ñту землю из-за ограничений по рейтингу зрелоÑти" name="okcancelignore" notext="Закрыть" yestext="Перейти в Базу знаний"/>
+ <usetemplate ignoretext="Эту землю могут купить только взроÑлые." name="okcancelignore" notext="Закрыть" yestext="Перейти в Базу знаний"/>
</notification>
<notification name="LandBuyAccessBlocked_Notify">
- Ð’Ñ‹ не можете купить Ñту землю из-за вашего рейтинга зрелоÑти.
+ Ð’Ñ‹ пытаетеÑÑŒ купить землю, контент на которой имеет рейтинг [REGIONMATURITY], но ваши наÑтройки не допуÑкают контента [REGIONMATURITY].
+ </notification>
+ <notification name="LandBuyAccessBlocked_NotifyAdultsOnly">
+ Ð’Ñ‹ пытаетеÑÑŒ купить землю Ñ ÐºÐ¾Ð½Ñ‚ÐµÐ½Ñ‚Ð¾Ð¼ [REGIONMATURITY], который предназначен только Ð´Ð»Ñ Ð²Ð·Ñ€Ð¾Ñлых.
</notification>
<notification name="LandBuyAccessBlocked_Change">
- Ð’Ñ‹ не можете купить Ñту землю из-за выбранного вами рейтинга зрелоÑти.
-
-Ðажмите кнопку «Изменить наÑтройку», чтобы повыÑить Ñвой рейтинг зрелоÑти. ПоÑле Ñтого вам будет разрешено иÑкать и проÑматривать контент [REGIONMATURITY]. ЕÑли в будущем понадобитÑÑ Ð¾Ñ‚Ð¼ÐµÐ½Ð¸Ñ‚ÑŒ Ñто изменение, выберите команды «Я &gt; ÐаÑтройки &gt; Общие».
- <usetemplate ignoretext="Ð’Ñ‹Ð±Ñ€Ð°Ð½Ð½Ð°Ñ Ð¼Ð½Ð¾Ð¹ наÑтройка рейтинга запрещает мне покупать землю" name="okcancelignore" notext="Закрыть" yestext="Изменить наÑтройку"/>
+ Ð’Ñ‹ пытаетеÑÑŒ купить землю, контент на которой имеет рейтинг [REGIONMATURITY], но ваши наÑтройки не допуÑкают контента [REGIONMATURITY]. Мы можем изменить ваши наÑтройки, поÑле чего вы Ñможете попробовать купить землю Ñнова.
+ <form name="form">
+ <button name="OK" text="Изменить наÑтройки"/>
+ <button name="Cancel" text="Отмена"/>
+ <ignore name="ignore" text="Ð’Ñ‹ пытаетеÑÑŒ купить землю, контент на которой запрещен вашими наÑтройками."/>
+ </form>
</notification>
<notification name="TooManyPrimsSelected">
Выбрано Ñлишком много примитивов. Выберите [MAX_PRIM_COUNT] или меньше примитивов и повторите попытку.
@@ -1815,10 +1981,9 @@ http://secondlife.com/download.
</form>
</notification>
<notification label="Изменен рейтинг зрелоÑти региона" name="RegionMaturityChange">
- Рейтинг зрелоÑти Ð´Ð»Ñ Ñтого региона будет обновлен.
+ Рейтинг зрелоÑти Ð´Ð»Ñ Ñтого региона был изменен.
Отображение Ñтого Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð½Ð° карте может занÑÑ‚ÑŒ некоторое времÑ.
-
-Ð”Ð»Ñ Ð²Ñ…Ð¾Ð´Ð° в регионы Ð´Ð»Ñ Ð²Ð·Ñ€Ð¾Ñлых у Ð¶Ð¸Ñ‚ÐµÐ»Ñ Ð´Ð¾Ð»Ð¶ÐµÐ½ быть подтвержденный аккаунт: либо Ñ Ð¿Ð¾Ð´Ñ‚Ð²ÐµÑ€Ð¶Ð´ÐµÐ½Ð¸ÐµÐ¼ возраÑта, либо Ñ Ð¿Ð¾Ð´Ñ‚Ð²ÐµÑ€Ð¶Ð´ÐµÐ½Ð¸ÐµÐ¼ оплаты.
+ <usetemplate name="okbutton" yestext="OK"/>
</notification>
<notification label="ÐеÑоответÑтвие верÑии голоÑа" name="VoiceVersionMismatch">
Ð”Ð°Ð½Ð½Ð°Ñ Ð²ÐµÑ€ÑÐ¸Ñ [APP_NAME] неÑовмеÑтима Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸ÐµÐ¹ голоÑового чата в Ñтом регионе. Ð”Ð»Ñ Ð¿Ñ€Ð°Ð²Ð¸Ð»ÑŒÐ½Ð¾Ð¹ работы голоÑового чата необходимо обновить [APP_NAME].
@@ -1931,6 +2096,10 @@ http://secondlife.com/download.
Перейти на [http://secondlife.com/account/ информационную панель], чтобы увидеть иÑторию аккаунта?
<usetemplate ignoretext="ЗапуÑтить браузер Ð´Ð»Ñ Ð¿Ñ€Ð¾Ñмотра иÑтории аккаунта" name="okcancelignore" notext="Отмена" yestext="Перейти на Ñтраницу"/>
</notification>
+ <notification name="ConfirmAddingChatParticipants">
+ При добавлении учаÑтника в ÑущеÑтвующий разговор будет Ñоздан новый разговор. Ð’Ñе учаÑтники получат ÑƒÐ²ÐµÐ´Ð¾Ð¼Ð»ÐµÐ½Ð¸Ñ Ð¾ новом разговоре.
+ <usetemplate ignoretext="Подтвердите добавление учаÑтников чата" name="okcancelignore" notext="Отмена" yestext="ОК"/>
+ </notification>
<notification name="ConfirmQuit">
Выйти из программы?
<usetemplate ignoretext="Подтверждать перед выходом" name="okcancelignore" notext="Ðе выходить" yestext="Выйти"/>
@@ -2005,14 +2174,14 @@ http://secondlife.com/download.
<button ignore="Ðе заменÑÑ‚ÑŒ" name="No" text="Отмена"/>
</form>
</notification>
- <notification label="Предупреждение о режиме «ЗанÑт»" name="BusyModePay">
- У Ð²Ð°Ñ Ð²ÐºÐ»ÑŽÑ‡ÐµÐ½ режим «ЗанÑт», поÑтому вы не получите никаких предметов, предлагаемых в обмен на Ñтот платеж.
+ <notification label="Предупреждение режима «Ðе беÑпокоить»" name="DoNotDisturbModePay">
+ Включен режим «Ðе беÑпокоить». Ð’Ñ‹ не будете получать никаких предметов, предлагаемых в обмен за Ñтот платеж.
-Хотите отключить режим «ЗанÑт» до Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð¸Ñ Ñтой транзакции?
+Отключить режим «Ðе беÑпокоить» перед завершением Ñтой операции?
<form name="form">
- <ignore name="ignore" text="Я ÑобираюÑÑŒ заплатить за Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð¸Ð»Ð¸ объект, когда включен режим «ЗанÑт»"/>
- <button ignore="Ð’Ñегда отключать режим «ЗанÑт»" name="Yes" text="OK"/>
- <button ignore="Ðе отключать режим «ЗанÑт»" name="No" text="Отмена"/>
+ <ignore name="ignore" text="Я ÑобираюÑÑŒ заплатить за Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð¸Ð»Ð¸ объект, когда включен режим «Ðе беÑпокоить»"/>
+ <button ignore="Ð’Ñегда выходить из режима «Ðе беÑпокоить»" name="Yes" text="OK"/>
+ <button ignore="Ðе выходить из режима «Ðе беÑпокоить»" name="No" text="Отмена"/>
</form>
</notification>
<notification name="ConfirmDeleteProtectedCategory">
@@ -2108,14 +2277,11 @@ http://secondlife.com/download.
<usetemplate ignoretext="Ðадевать одежду, Ñоздаваемую при редактировании моей внешноÑти" name="okcancelignore" notext="Ðет" yestext="Да"/>
</notification>
<notification name="NotAgeVerified">
- ДоÑтуп к контенту и облаÑÑ‚Ñм Ð´Ð»Ñ Ð²Ð·Ñ€Ð¾Ñлых в Second Life разрешен только Ñ 18 лет. ПоÑетите нашу Ñтраницу проверки возраÑта и подтвердите, что вам уже иÑполнилоÑÑŒ 18.
-Страница будет открыта в браузере.
-
-[_URL]
- <url name="url">
- https://secondlife.com/my/account/verification.php
- </url>
- <usetemplate ignoretext="Мой возраÑÑ‚ не подтвержден" name="okcancelignore" notext="Отмена" yestext="Перейти к проверке возраÑта"/>
+ Ð’Ñ‹ пытаетеÑÑŒ поÑетить меÑто, доÑтуп в которое разрешен только жителÑм 18 лет и Ñтарше.
+ <usetemplate ignoretext="Мне еще рано поÑещать меÑта Ñ Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñми по возраÑту." name="okignore" yestext="OK"/>
+ </notification>
+ <notification name="NotAgeVerified_Notify">
+ Это меÑто разрешено Ð´Ð»Ñ Ð¶Ð¸Ñ‚ÐµÐ»ÐµÐ¹ 18 лет и Ñтарше.
</notification>
<notification name="Cannot enter parcel: no payment info on file">
Ð”Ð»Ñ Ð¿Ð¾ÑÐµÑ‰ÐµÐ½Ð¸Ñ Ñтой облаÑти необходимо зарегиÑтрировать платеж. Перейти на веб-Ñайт [SECOND_LIFE] и ввеÑти Ñту информацию?
@@ -2150,11 +2316,8 @@ http://secondlife.com/download.
<notification name="GroupNotice">
Раздел: [SUBJECT], Ñообщение: [MESSAGE]
</notification>
- <notification name="FriendOnline">
- &lt;nolink&gt;[NAME]&lt;/nolink&gt; в Ñети
- </notification>
- <notification name="FriendOffline">
- &lt;nolink&gt;[NAME]&lt;/nolink&gt; не в Ñети
+ <notification name="FriendOnlineOffline">
+ &lt;nolink&gt;[NAME]&lt;/nolink&gt; [STATUS]
</notification>
<notification name="AddSelfFriend">
Ð’Ñ‹ лучше вÑех, но Ð½ÐµÐ»ÑŒÐ·Ñ Ð´Ð¾Ð±Ð°Ð²Ð¸Ñ‚ÑŒ в Ð´Ñ€ÑƒÐ·ÑŒÑ ÑÐµÐ±Ñ Ñамого.
@@ -2275,9 +2438,7 @@ http://secondlife.com/download.
выбрать команду «ТелепортациÑ».)
</notification>
<notification name="TeleportToPerson">
- Чтобы обратитьÑÑ Ðº жителю, например «[NAME]», нажмите кнопку «Люди», выберите Ð¶Ð¸Ñ‚ÐµÐ»Ñ Ð² поÑвившемÑÑ Ð¾ÐºÐ½Ðµ и нажмите кнопку
- «IM» внизу окна.
- (Также можно дважды щелкнуть Ð¸Ð¼Ñ Ð¶Ð¸Ñ‚ÐµÐ»Ñ Ð² ÑпиÑке или щелкнуть его правой кнопкой мыши и выбрать команду «IM».)
+ Чтобы начать личный разговор, щелкните аватар ÑобеÑедника правой кнопкой мыши и выберите в меню «IM».
</notification>
<notification name="CantSelectLandFromMultipleRegions">
ÐÐµÐ»ÑŒÐ·Ñ Ð²Ñ‹Ð±Ñ€Ð°Ñ‚ÑŒ землю Ñ Ð¾Ð±ÐµÐ¸Ñ… Ñторон границы между Ñерверами.
@@ -2377,6 +2538,16 @@ http://secondlife.com/download.
<notification name="NoBuild">
Ð’ Ñтой облаÑти запрещено ÑтроительÑтво. ЗдеÑÑŒ вы не Ñможете Ñтроить или выкладывать объекты.
</notification>
+ <notification name="PathfindingDirty">
+ Ð’ регионе еÑÑ‚ÑŒ незавершенные Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð¿Ð¾Ð¸Ñка пути. ЕÑли у Ð²Ð°Ñ ÐµÑÑ‚ÑŒ права на ÑтроительÑтво, воÑÑтановите регион, нажав кнопку «ВоÑÑтановить регион».
+ </notification>
+ <notification name="DynamicPathfindingDisabled">
+ Ð’ Ñтом регионе не разрешен динамичеÑкий поиÑк пути. Возможны Ð½Ð°Ñ€ÑƒÑˆÐµÐ½Ð¸Ñ Ñ€Ð°Ð±Ð¾Ñ‚Ñ‹ Ñкриптовых объектов Ñ Ð¸Ñпользованием вызовов LSL поиÑка пути.
+ </notification>
+ <notification name="PathfindingCannotRebakeNavmesh">
+ Произошла ошибка. Возможно, неполадка в Ñети или на Ñервере, или у Ð²Ð°Ñ Ð½ÐµÑ‚ прав на ÑтроительÑтво. Иногда Ð´Ð»Ñ ÑƒÑÑ‚Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ñтой проблемы доÑтаточно выйти и Ñнова войти.
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
<notification name="SeeAvatars">
Ðа Ñтом учаÑтке аватары и текÑтовый чат Ñкрыты от другого учаÑтка. Жителей за пределами Ñтого учаÑтка не будет видно, а они не будут видеть ваÑ. Обычный текÑтовый чат на канале 0 также блокируетÑÑ.
</notification>
@@ -2395,9 +2566,7 @@ http://secondlife.com/download.
Ð’Ñ‹ можете претендовать на публичную землю только в регионе, в котором вы находитеÑÑŒ.
</notification>
<notification name="RegionTPAccessBlocked">
- Вам Ð½ÐµÐ»ÑŒÐ·Ñ Ð±Ñ‹Ñ‚ÑŒ в Ñтом регионе из-за вашего рейтинга зрелоÑти. Подтвердите Ñвой возраÑÑ‚ и/или уÑтановите поÑледнюю верÑию клиента.
-
-Прочитайте в Базе знаний о доÑтупе к облаÑÑ‚Ñм Ñ Ñтим рейтингом зрелоÑти.
+ Ð’Ñ‹ пытаетеÑÑŒ поÑетить регион, контент в котором не ÑоответÑтвует вашим наÑтройкам. Попробуйте изменить наÑтройки в меню «Я &gt; ÐаÑтройки &gt; Общие».
</notification>
<notification name="URBannedFromRegion">
Вы забанены в регионе.
@@ -2408,11 +2577,11 @@ http://secondlife.com/download.
<notification name="ImproperPaymentStatus">
У Ð²Ð°Ñ Ð½ÐµÑ‚ необходимого ÑтатуÑа оплаты Ð´Ð»Ñ Ð²Ñ…Ð¾Ð´Ð° в Ñтот регион.
</notification>
- <notification name="MustGetAgeRgion">
- Ð”Ð»Ñ Ð²Ñ…Ð¾Ð´Ð° в Ñтот регион необходимо подтверждение возраÑта.
+ <notification name="MustGetAgeRegion">
+ Входить в Ñтот регион могут только жители 18 лет и Ñтарше.
</notification>
<notification name="MustGetAgeParcel">
- Ð”Ð»Ñ Ð²Ñ…Ð¾Ð´Ð° на Ñтот учаÑток необходимо подтверждение возраÑта.
+ Входить на Ñтот учаÑток могут только жители 18 лет и Ñтарше.
</notification>
<notification name="NoDestRegion">
Ðе найден регион назначениÑ.
@@ -2514,12 +2683,33 @@ http://secondlife.com/download.
<notification name="TeleportOffered">
[NAME_SLURL] предложил(а) телепортировать Ð²Ð°Ñ Ðº Ñебе:
-[MESSAGE] - [MATURITY_STR] &lt;icon&gt;[MATURITY_ICON]&lt;/icon&gt;
+«[MESSAGE]»
+&lt;icon&gt;[MATURITY_ICON]&lt;/icon&gt; - [MATURITY_STR]
<form name="form">
<button name="Teleport" text="ТелепортациÑ"/>
<button name="Cancel" text="Отмена"/>
</form>
</notification>
+ <notification name="TeleportOffered_MaturityExceeded">
+ [NAME_SLURL] предложил(а) телепортировать Ð²Ð°Ñ Ðº Ñебе:
+
+«[MESSAGE]»
+&lt;icon&gt;[MATURITY_ICON]&lt;/icon&gt; - [MATURITY_STR]
+
+Этот регион Ñодержит контент Ñ Ñ€ÐµÐ¹Ñ‚Ð¸Ð½Ð³Ð¾Ð¼ [REGION_CONTENT_MATURITY], но ваши наÑтройки не допуÑкают контента [REGION_CONTENT_MATURITY]. Ð’Ñ‹ можете отказатьÑÑ Ð¾Ñ‚ телепортации, или ваши наÑтройки будут изменены.
+ <form name="form">
+ <button name="Teleport" text="Изменить и продолжить"/>
+ <button name="Cancel" text="Отмена"/>
+ </form>
+ </notification>
+ <notification name="TeleportOffered_MaturityBlocked">
+ [NAME_SLURL] предложил(а) телепортировать Ð²Ð°Ñ Ðº Ñебе:
+
+«[MESSAGE]»
+&lt;icon&gt;[MATURITY_ICON]&lt;/icon&gt; - [MATURITY_STR]
+
+Однако Ñтот регион Ñодержит контент, доÑтупный только Ð´Ð»Ñ Ð²Ð·Ñ€Ð¾Ñлых.
+ </notification>
<notification name="TeleportOfferSent">
Предложение телепортации отправлено [TO_NAME]
</notification>
@@ -2614,16 +2804,21 @@ http://secondlife.com/download.
</form>
</notification>
<notification name="ScriptQuestionCaution">
- Объект «&lt;nolink&gt;[OBJECTNAME]&lt;/nolink&gt;», владелец которого – «[NAME]», желает:
-
-[QUESTIONS]
-ЕÑли вы не доверÑете Ñтому объекту или его Ñоздателю, отклоните запроÑ.
-
-ПринÑÑ‚ÑŒ Ñтот запроÑ?
+ Предупреждение. Объект «&lt;nolink&gt;[OBJECTNAME]&lt;/nolink&gt;» требует полного доÑтупа к вашему аккаунту Ð´Ð»Ñ Linden-долларов. ЕÑли разрешить такой доÑтуп, объект Ñможет в любое Ð²Ñ€ÐµÐ¼Ñ Ñнимать ÑредÑтва Ñ Ð²Ð°ÑˆÐµÐ³Ð¾ аккаунта или полноÑтью опуÑтошать его неоднократно и без предупреждениÑ.
+
+Ðе разрешайте доÑтуп к Ñвоему аккаунту, еÑли только не полноÑтью оÑознаете, зачем он нужен Ñтому объекту.
<form name="form">
- <button name="Grant" text="ПринÑÑ‚ÑŒ"/>
+ <button name="Grant" text="Разрешить полный доÑтуп"/>
<button name="Deny" text="Отклонить"/>
- <button name="Details" text="ПодробноÑти..."/>
+ </form>
+ </notification>
+ <notification name="UnknownScriptQuestion">
+ Объект &lt;nolink&gt;[OBJECTNAME]&lt;/nolink&gt;» владельца «[NAME]» требует Ñ€Ð°Ð·Ñ€ÐµÑˆÐµÐ½Ð¸Ñ Ð½Ð° выполнение Ñкрипта; разрешение не раÑпознаетÑÑ ÐºÐ»Ð¸ÐµÐ½Ñ‚Ð¾Ð¼ и не будет предоÑтавлено
+
+Ð”Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ñтого Ñ€Ð°Ð·Ñ€ÐµÑˆÐµÐ½Ð¸Ñ ÑƒÑтановите поÑледнюю верÑию клиента из [DOWNLOADURL].
+ <form name="form">
+ <button name="Deny" text="OK"/>
+ <button name="Mute" text="Заблокировать"/>
</form>
</notification>
<notification name="ScriptDialog">
@@ -2927,6 +3122,10 @@ http://secondlife.com/download.
( [EXISTENCE] Ñек. жизни )
Ð’Ñ‹ локально обновили готовую текÑтуру [RESOLUTION] Ð´Ð»Ñ Â«[BODYREGION]» через [TIME] Ñек.
</notification>
+ <notification name="LivePreviewUnavailable">
+ ПроÑмотр Ñтой текÑтуры невозможен, так как запрещено ее копирование и/или переноÑ.
+ <usetemplate ignoretext="Предупреждать, еÑли режим проÑмотра вживую недоÑтупен Ð´Ð»Ñ Ñ‚ÐµÐºÑтур Ñ Ð·Ð°Ð¿Ñ€ÐµÑ‰ÐµÐ½Ð½Ñ‹Ð¼ копированием и/или переноÑом" name="okignore" yestext="OK"/>
+ </notification>
<notification name="ConfirmLeaveCall">
ДейÑтвительно покинуть Ñтот разговор?
<usetemplate ignoretext="Подтверждать перед выходом из разговора" name="okcancelignore" notext="Ðет" yestext="Да"/>
@@ -3098,6 +3297,62 @@ http://secondlife.com/download.
Это дейÑтвие приведет к Ñкрытию вÑех меню и кнопок. Чтобы вернуть их, щелкните [SHORTCUT] Ñнова.
<usetemplate ignoretext="Подтверждать перед Ñкрытием интерфейÑа" name="okcancelignore" notext="Отмена" yestext="OK"/>
</notification>
+ <notification name="PathfindingLinksets_WarnOnPhantom">
+ Признак фантомноÑти некоторых выбранных наборов ÑвÑзей будет изменен.
+
+Продолжить?
+ <usetemplate ignoretext="Признак фантомноÑти некоторых выбранных наборов ÑвÑзей будет изменен." name="okcancelignore" notext="Отмена" yestext="OK"/>
+ </notification>
+ <notification name="PathfindingLinksets_MismatchOnRestricted">
+ Ð”Ð»Ñ Ð½ÐµÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ñ… выбранных наборов ÑвÑзей Ð½ÐµÐ»ÑŒÐ·Ñ Ð·Ð°Ð´Ð°Ñ‚ÑŒ тип «[REQUESTED_TYPE]» из-за ограничений Ñтих наборов. Эти наборы ÑвÑзей будут иметь тип «[RESTRICTED_TYPE]».
+
+Продолжить?
+ <usetemplate ignoretext="ÐÐµÐ»ÑŒÐ·Ñ Ð·Ð°Ð´Ð°Ñ‚ÑŒ некоторые выбранные наборы ÑвÑзей из-за ограничений Ñтих наборов." name="okcancelignore" notext="Отмена" yestext="OK"/>
+ </notification>
+ <notification name="PathfindingLinksets_MismatchOnVolume">
+ Ð”Ð»Ñ Ð½ÐµÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ñ… выбранных наборов ÑвÑзей невозможно задать тип «[REQUESTED_TYPE]», так как фигура не выпуклаÑ.
+
+Продолжить?
+ <usetemplate ignoretext="ÐÐµÐ»ÑŒÐ·Ñ Ð·Ð°Ð´Ð°Ñ‚ÑŒ некоторые выбранные наборы ÑвÑзей, так как фигура не выпуклаÑ." name="okcancelignore" notext="Отмена" yestext="OK"/>
+ </notification>
+ <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnRestricted">
+ Признак фантомноÑти некоторых выбранных наборов ÑвÑзей будет изменен.
+
+Ð”Ð»Ñ Ð½ÐµÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ñ… выбранных наборов ÑвÑзей Ð½ÐµÐ»ÑŒÐ·Ñ Ð·Ð°Ð´Ð°Ñ‚ÑŒ тип «[REQUESTED_TYPE]» из-за ограничений Ñтих наборов. Эти наборы ÑвÑзей будут иметь тип «[RESTRICTED_TYPE]».
+
+Продолжить?
+ <usetemplate ignoretext="Ð”Ð»Ñ Ð½ÐµÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ñ… выбранных наборов ÑвÑзей будет изменен признак фантомноÑти, а другие наборы Ð½ÐµÐ»ÑŒÐ·Ñ Ð·Ð°Ð´Ð°Ñ‚ÑŒ из-за ограничений Ñтих наборов." name="okcancelignore" notext="Отмена" yestext="OK"/>
+ </notification>
+ <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnVolume">
+ Признак фантомноÑти некоторых выбранных наборов ÑвÑзей будет изменен.
+
+Ð”Ð»Ñ Ð½ÐµÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ñ… выбранных наборов ÑвÑзей невозможно задать тип «[REQUESTED_TYPE]», так как фигура не выпуклаÑ.
+
+Продолжить?
+ <usetemplate ignoretext="Ð”Ð»Ñ Ð½ÐµÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ñ… выбранных наборов ÑвÑзей будет изменен признак фантомноÑти, а другие наборы Ð½ÐµÐ»ÑŒÐ·Ñ Ð·Ð°Ð´Ð°Ñ‚ÑŒ, так как фигура не выпуклаÑ." name="okcancelignore" notext="Отмена" yestext="OK"/>
+ </notification>
+ <notification name="PathfindingLinksets_MismatchOnRestricted_MismatchOnVolume">
+ Ð”Ð»Ñ Ð½ÐµÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ñ… выбранных наборов ÑвÑзей Ð½ÐµÐ»ÑŒÐ·Ñ Ð·Ð°Ð´Ð°Ñ‚ÑŒ тип «[REQUESTED_TYPE]» из-за ограничений Ñтих наборов. Эти наборы ÑвÑзей будут иметь тип «[RESTRICTED_TYPE]».
+
+Ð”Ð»Ñ Ð½ÐµÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ñ… выбранных наборов ÑвÑзей невозможно задать тип «[REQUESTED_TYPE]», так как фигура не выпуклаÑ. Тип иÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ñтих наборов ÑвÑзей не изменитÑÑ.
+
+Продолжить?
+ <usetemplate ignoretext="ÐÐµÐ»ÑŒÐ·Ñ Ð·Ð°Ð´Ð°Ñ‚ÑŒ некоторые выбранные наборы ÑвÑзей из-за ограничений Ñтих наборов и потому, что фигура не выпуклаÑ." name="okcancelignore" notext="Отмена" yestext="OK"/>
+ </notification>
+ <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnRestricted_MismatchOnVolume">
+ Признак фантомноÑти некоторых выбранных наборов ÑвÑзей будет изменен.
+
+Ð”Ð»Ñ Ð½ÐµÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ñ… выбранных наборов ÑвÑзей Ð½ÐµÐ»ÑŒÐ·Ñ Ð·Ð°Ð´Ð°Ñ‚ÑŒ тип «[REQUESTED_TYPE]» из-за ограничений Ñтих наборов. Эти наборы ÑвÑзей будут иметь тип «[RESTRICTED_TYPE]».
+
+Ð”Ð»Ñ Ð½ÐµÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ñ… выбранных наборов ÑвÑзей невозможно задать тип «[REQUESTED_TYPE]», так как фигура не выпуклаÑ. Тип иÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ñтих наборов ÑвÑзей не изменитÑÑ.
+
+Продолжить?
+ <usetemplate ignoretext="Ð”Ð»Ñ Ð½ÐµÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ñ… выбранных наборов ÑвÑзей будет изменен признак фантомноÑти, а другие наборы Ð½ÐµÐ»ÑŒÐ·Ñ Ð·Ð°Ð´Ð°Ñ‚ÑŒ из-за ограничений Ñтих наборов и потому, что фигура не выпуклаÑ." name="okcancelignore" notext="Отмена" yestext="OK"/>
+ </notification>
+ <notification name="PathfindingLinksets_ChangeToFlexiblePath">
+ Выбранный объект влиÑет на навигационную Ñетку. ЕÑли заменить его на гибкий путь, он будет удален из навигационной Ñетки.
+ <usetemplate ignoretext="Выбранный объект влиÑет на навигационную Ñетку. ЕÑли заменить его на гибкий путь, он будет удален из навигационной Ñетки." name="okcancelignore" notext="Отмена" yestext="OK"/>
+ </notification>
<global name="UnsupportedGLRequirements">
По-видимому, ваше оборудование не удовлетворÑет требованиÑм [APP_NAME]. Ð”Ð»Ñ Ñ€Ð°Ð±Ð¾Ñ‚Ñ‹ [APP_NAME] необходима графичеÑÐºÐ°Ñ ÐºÐ°Ñ€Ñ‚Ð° OpenGL Ñ Ð¿Ð¾Ð´Ð´ÐµÑ€Ð¶ÐºÐ¾Ð¹ мультитекÑтур. ЕÑли у Ð²Ð°Ñ ÐµÑÑ‚ÑŒ Ñ‚Ð°ÐºÐ°Ñ ÐºÐ°Ñ€Ñ‚Ð°, убедитеÑÑŒ, что уÑтановлены новейшие верÑии драйверов Ð´Ð»Ñ Ð½ÐµÐµ и пакеты обновлений и иÑÐ¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ð¾Ð¿ÐµÑ€Ð°Ñ†Ð¸Ð¾Ð½Ð½Ð¾Ð¹ ÑиÑтемы.
@@ -3122,4 +3377,652 @@ http://secondlife.com/download.
<global name="You died and have been teleported to your home location">
Ð’Ñ‹ умерли и были телепортированы в ваше домашнее меÑтоположение.
</global>
+ <notification name="LocalBitmapsUpdateFileNotFound">
+ Ðе удалоÑÑŒ обновить [FNAME]: файл не найден.
+ПоÑледующее обновление Ñтого файла запрещаетÑÑ.
+ </notification>
+ <notification name="LocalBitmapsUpdateFailedFinal">
+ Ðе удалоÑÑŒ открыть или декодировать [FNAME] Ñ [NRETRIES] попыток. Этот файл ÑчитаетÑÑ Ð¿Ð¾Ð²Ñ€ÐµÐ¶Ð´ÐµÐ½Ð½Ñ‹Ð¼.
+ПоÑледующее обновление Ñтого файла запрещаетÑÑ.
+ </notification>
+ <notification name="LocalBitmapsVerifyFail">
+ Попытка добавить недопуÑтимый или нечитаемый файл Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ [FNAME], который не удалоÑÑŒ открыть или декодировать.
+Попытка отменена.
+ </notification>
+ <notification name="PathfindingReturnMultipleItems">
+ Возвращено [NUM_ITEMS] Ñлементов. Продолжить?
+ <usetemplate ignoretext="Возвратить неÑколько предметов?" name="okcancelignore" notext="Ðет" yestext="Да"/>
+ </notification>
+ <notification name="PathfindingDeleteMultipleItems">
+ Ð’Ñ‹ удалÑете неÑколько предметов ([NUM_ITEMS]). Продолжить?
+ <usetemplate ignoretext="Удалить неÑколько предметов?" name="okcancelignore" notext="Ðет" yestext="Да"/>
+ </notification>
+ <notification name="AvatarFrozen">
+ [AV_FREEZER] заморозил ваÑ. Ð’ Ñто Ð²Ñ€ÐµÐ¼Ñ Ð²Ñ‹ не можете перемещатьÑÑ Ð¸ выполнÑÑ‚ÑŒ другие дейÑÑ‚Ð²Ð¸Ñ Ñ Ð¼Ð¸Ñ€Ð¾Ð¼.
+ </notification>
+ <notification name="AvatarFrozenDuration">
+ [AV_FREEZER] заморозил Ð²Ð°Ñ Ð½Ð° [AV_FREEZE_TIME] Ñек. Ð’ Ñто Ð²Ñ€ÐµÐ¼Ñ Ð²Ñ‹ не можете перемещатьÑÑ Ð¸ выполнÑÑ‚ÑŒ другие дейÑÑ‚Ð²Ð¸Ñ Ñ Ð¼Ð¸Ñ€Ð¾Ð¼.
+ </notification>
+ <notification name="YouFrozeAvatar">
+ Ðватар заморожен.
+ </notification>
+ <notification name="AvatarHasUnFrozenYou">
+ [AV_FREEZER] разморозил ваÑ.
+ </notification>
+ <notification name="AvatarUnFrozen">
+ Ðватар разморожен.
+ </notification>
+ <notification name="AvatarFreezeFailure">
+ Ðе удалоÑÑŒ заморозить: у Ð²Ð°Ñ Ð½ÐµÑ‚ прав админиÑтратора на Ñтом учаÑтке.
+ </notification>
+ <notification name="AvatarFreezeThaw">
+ Заморозка кончилаÑÑŒ, занимайтеÑÑŒ Ñвоим делом.
+ </notification>
+ <notification name="AvatarCantFreeze">
+ Ðевозможно заморозить Ñтого пользователÑ.
+ </notification>
+ <notification name="NowOwnObject">
+ Ð’Ñ‹ Ñтали владельцем объекта [OBJECT_NAME]
+ </notification>
+ <notification name="CantRezOnLand">
+ ÐÐµÐ»ÑŒÐ·Ñ Ð²Ñ‹Ð»Ð¾Ð¶Ð¸Ñ‚ÑŒ объект на [OBJECT_POS]: Ñто не разрешено владельцем земли. Узнать, кто владелец, можно Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ инÑтрумента «ЗемлÑ».
+ </notification>
+ <notification name="RezFailTooManyRequests">
+ Ðевозможно выложить объект: Ñлишком много запроÑов.
+ </notification>
+ <notification name="SitFailCantMove">
+ ÐÐµÐ»ÑŒÐ·Ñ ÑеÑÑ‚ÑŒ: ÑÐµÐ¹Ñ‡Ð°Ñ Ð²Ñ‹ не можете двигатьÑÑ.
+ </notification>
+ <notification name="SitFailNotAllowedOnLand">
+ Вам не разрешено ÑадитьÑÑ Ð½Ð° Ñтой земле.
+ </notification>
+ <notification name="SitFailNotSameRegion">
+ Попробуйте перемеÑтитьÑÑ Ð±Ð»Ð¸Ð¶Ðµ. ÐÐµÐ»ÑŒÐ·Ñ ÑеÑÑ‚ÑŒ на объект:
+он находитÑÑ Ð² другом регионе.
+ </notification>
+ <notification name="NoNewObjectRegionFull">
+ Ðевозможно Ñоздать новый объект. Регион уже заполнен.
+ </notification>
+ <notification name="FailedToPlaceObject">
+ Ðе удалоÑÑŒ помеÑтить объект в указанное меÑто. Повторите попытку.
+ </notification>
+ <notification name="NoOwnNoGardening">
+ Ð’Ñ‹ не можете Ñоздавать Ð´ÐµÑ€ÐµÐ²ÑŒÑ Ð¸ траву на чужой земле.
+ </notification>
+ <notification name="NoCopyPermsNoObject">
+ Ðе удалоÑÑŒ Ñкопировать: вам не разрешено копировать объект «[OBJ_NAME]».
+ </notification>
+ <notification name="NoTransPermsNoObject">
+ Ðе удалоÑÑŒ Ñкопировать: объект «[OBJ_NAME]» Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿ÐµÑ€ÐµÐ½ÐµÑти к вам.
+ </notification>
+ <notification name="AddToNavMeshNoCopy">
+ Ðе удалоÑÑŒ Ñкопировать: объект «[OBJ_NAME]» отноÑитÑÑ Ðº навигационной Ñетке.
+ </notification>
+ <notification name="DupeWithNoRootsSelected">
+ Выбран дубликат без корневых объектов.
+ </notification>
+ <notification name="CantDupeCuzRegionIsFull">
+ Ðевозможно дублировать объекты: регион заполнен.
+ </notification>
+ <notification name="CantDupeCuzParcelNotFound">
+ Ðевозможно дублировать объекты: не удалоÑÑŒ найти их учаÑток.
+ </notification>
+ <notification name="CantCreateCuzParcelFull">
+ ÐÐµÐ»ÑŒÐ·Ñ Ñоздать объект:
+учаÑток уже заполнен.
+ </notification>
+ <notification name="RezAttemptFailed">
+ Ðе удалоÑÑŒ выложить объект.
+ </notification>
+ <notification name="ToxicInvRezAttemptFailed">
+ Ðевозможно Ñоздать Ñлемент, который вызвал проблемы в Ñтом регионе.
+ </notification>
+ <notification name="InvItemIsBlacklisted">
+ Этот предмет Ð¸Ð½Ð²ÐµÐ½Ñ‚Ð°Ñ€Ñ Ð½Ð°Ñ…Ð¾Ð´Ð¸Ñ‚ÑÑ Ð² черном ÑпиÑке.
+ </notification>
+ <notification name="NoCanRezObjects">
+ Ð¡ÐµÐ¹Ñ‡Ð°Ñ Ð²Ð°Ð¼ не разрешено Ñоздавать объекты.
+ </notification>
+ <notification name="LandSearchBlocked">
+ ПоиÑк по земле заблокирован.
+Ð’Ñ‹ провели Ñлишком много операций поиÑка за короткое времÑ.
+Повторите попытку через минуту.
+ </notification>
+ <notification name="NotEnoughResourcesToAttach">
+ ÐедоÑтаточно Ñвободных реÑурÑов Ñкриптинга Ð´Ð»Ñ Ð¿Ñ€Ð¸ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ð¾Ð±ÑŠÐµÐºÑ‚Ð°!
+ </notification>
+ <notification name="YouDiedAndGotTPHome">
+ Ð’Ñ‹ умерли и были телепортированы в ваше домашнее меÑтоположение
+ </notification>
+ <notification name="EjectComingSoon">
+ Вам запрещено здеÑÑŒ приÑутÑтвовать; у Ð²Ð°Ñ ÐµÑÑ‚ÑŒ [EJECT_TIME] Ñек, чтобы покинуть Ñто меÑто.
+ </notification>
+ <notification name="NoEnterServerFull">
+ Вам нет доÑтупа в Ñтот регион:
+Ñерпер переполнен.
+ </notification>
+ <notification name="SaveBackToInvDisabled">
+ Сохранение в инвентаре отключено.
+ </notification>
+ <notification name="NoExistNoSaveToContents">
+ ÐÐµÐ»ÑŒÐ·Ñ Ñохранить «[OBJ_NAME]» в Ñодержимом объекта: объект, из которого оно было выложено, уже не ÑущеÑтвует.
+ </notification>
+ <notification name="NoModNoSaveToContents">
+ ÐÐµÐ»ÑŒÐ·Ñ Ñохранить «[OBJ_NAME]» в Ñодержимом объекта: вам не разрешено изменÑÑ‚ÑŒ объект «[DEST_NAME]».
+ </notification>
+ <notification name="NoSaveBackToInvDisabled">
+ Ðевозможно Ñохранить «[OBJ_NAME]» в инвентаре: Ñта Ð¾Ð¿ÐµÑ€Ð°Ñ†Ð¸Ñ Ð·Ð°Ð¿Ñ€ÐµÑ‰ÐµÐ½Ð°.
+ </notification>
+ <notification name="NoCopyNoSelCopy">
+ ÐÐµÐ»ÑŒÐ·Ñ Ñкопировать выбранное: вам не разрешено копировать объект «[OBJ_NAME]».
+ </notification>
+ <notification name="NoTransNoSelCopy">
+ Ðевозможно Ñкопировать выбранный предмет: объект «[OBJ_NAME]» не переноÑитÑÑ.
+ </notification>
+ <notification name="NoTransNoCopy">
+ Ðевозможно Ñкопировать выбранный предмет: объект «[OBJ_NAME]» не переноÑитÑÑ.
+ </notification>
+ <notification name="NoPermsNoRemoval">
+ Удаление объекта «[OBJ_NAME]» из ÑимулÑтора запрещено ÑиÑтемой разрешений.
+ </notification>
+ <notification name="NoModNoSaveSelection">
+ ÐÐµÐ»ÑŒÐ·Ñ Ñохранить выбранное: вам не разрешено изменÑÑ‚ÑŒ объект «[OBJ_NAME]».
+ </notification>
+ <notification name="NoCopyNoSaveSelection">
+ Ðевозможно Ñохранить выбранный предмет: объект «[OBJ_NAME]» не копируетÑÑ.
+ </notification>
+ <notification name="NoModNoTaking">
+ ÐÐµÐ»ÑŒÐ·Ñ Ð·Ð°Ð±Ñ€Ð°Ñ‚ÑŒ выбранное: вам не разрешено изменÑÑ‚ÑŒ объект «[OBJ_NAME]».
+ </notification>
+ <notification name="RezDestInternalError">
+ ВнутреннÑÑ Ð¾ÑˆÐ¸Ð±ÐºÐ°: неизвеÑтный тип меÑта назначениÑ.
+ </notification>
+ <notification name="DeleteFailObjNotFound">
+ Ðевозможно удалить: объект не найден
+ </notification>
+ <notification name="SorryCantEjectUser">
+ Ðевозможно выброÑить Ñтого пользователÑ.
+ </notification>
+ <notification name="RegionSezNotAHome">
+ Вам не разрешено уÑтанавливать Ñвое домашнее меÑтоположение в Ñтом регионе.
+ </notification>
+ <notification name="HomeLocationLimits">
+ Задать домашнее меÑтоположение можно только на вашей земле или в Инфохабе материка.
+ </notification>
+ <notification name="HomePositionSet">
+ Задано положение дома.
+ </notification>
+ <notification name="AvatarEjected">
+ Ðватар выброшен.
+ </notification>
+ <notification name="AvatarEjectFailed">
+ Ðе удалоÑÑŒ выброÑить: у Ð²Ð°Ñ Ð½ÐµÑ‚ прав админиÑтратора на Ñтом учаÑтке.
+ </notification>
+ <notification name="CantMoveObjectParcelFull">
+ ÐÐµÐ»ÑŒÐ·Ñ Ð¿ÐµÑ€ÐµÐ¼ÐµÑтить объект «[OBJECT_NAME]» в позицию «[OBJ_POSITION]» региона [REGION_NAME]: учаÑток уже заполнен.
+ </notification>
+ <notification name="CantMoveObjectParcelPerms">
+ ÐÐµÐ»ÑŒÐ·Ñ Ð¿ÐµÑ€ÐµÐ¼ÐµÑтить объект «[OBJECT_NAME]» в позицию
+«[OBJ_POSITION]» региона [REGION_NAME]: вашим объектам не разрешено приÑутÑтвовать на Ñтом учаÑтке.
+ </notification>
+ <notification name="CantMoveObjectParcelResources">
+ ÐÐµÐ»ÑŒÐ·Ñ Ð¿ÐµÑ€ÐµÐ¼ÐµÑтить объект «[OBJECT_NAME]» в позицию
+«[OBJ_POSITION]» региона [REGION_NAME]: на Ñтом учаÑтке недоÑтаточно реÑурÑов Ð´Ð»Ñ Ð´Ð°Ð½Ð½Ð¾Ð³Ð¾ объекта.
+ </notification>
+ <notification name="CantMoveObjectRegionVersion">
+ ÐÐµÐ»ÑŒÐ·Ñ Ð¿ÐµÑ€ÐµÐ¼ÐµÑтить объект «[OBJECT_NAME]» в позицию
+[OBJ_POSITION] региона [REGION_NAME]: в другом регионе работает ÑÑ‚Ð°Ñ€Ð°Ñ Ð²ÐµÑ€ÑÐ¸Ñ ÑимулÑтора, ÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð½Ðµ поддерживает прием Ñтого объекта через границу регионов.
+ </notification>
+ <notification name="CantMoveObjectNavMesh">
+ ÐÐµÐ»ÑŒÐ·Ñ Ð¿ÐµÑ€ÐµÐ¼ÐµÑтить объект «[OBJECT_NAME]» в позицию
+«[OBJ_POSITION]» региона [REGION_NAME]: вам не разрешено изменÑÑ‚ÑŒ навигационную Ñетку за пределами региона.
+ </notification>
+ <notification name="CantMoveObjectWTF">
+ ÐÐµÐ»ÑŒÐ·Ñ Ð¿ÐµÑ€ÐµÐ¼ÐµÑтить объект «[OBJECT_NAME]» в позицию
+[OBJ_POSITION] региона [REGION_NAME] по неизвеÑтной причине. ([FAILURE_TYPE])
+ </notification>
+ <notification name="NoPermModifyObject">
+ У Ð²Ð°Ñ Ð½ÐµÑ‚ прав на изменение Ñтого объекта
+ </notification>
+ <notification name="CantEnablePhysObjContributesToNav">
+ ÐÐµÐ»ÑŒÐ·Ñ Ð²ÐºÐ»ÑŽÑ‡Ð¸Ñ‚ÑŒ физику Ð´Ð»Ñ Ð¾Ð±ÑŠÐµÐºÑ‚Ð°, который отноÑитÑÑ Ðº навигационной Ñетке.
+ </notification>
+ <notification name="CantEnablePhysKeyframedObj">
+ ÐÐµÐ»ÑŒÐ·Ñ Ð²ÐºÐ»ÑŽÑ‡Ð¸Ñ‚ÑŒ физику Ð´Ð»Ñ Ð¾Ð±ÑŠÐµÐºÑ‚Ð¾Ð² Ñ ÐºÐ»ÑŽÑ‡ÐµÐ²Ñ‹Ð¼Ð¸ кадрами.
+ </notification>
+ <notification name="CantEnablePhysNotEnoughLandResources">
+ ÐÐµÐ»ÑŒÐ·Ñ Ð²ÐºÐ»ÑŽÑ‡Ð¸Ñ‚ÑŒ физику Ð´Ð»Ñ Ð¾Ð±ÑŠÐµÐºÑ‚Ð° -- недоÑтаточно земельных реÑурÑов.
+ </notification>
+ <notification name="CantEnablePhysCostTooGreat">
+ ÐÐµÐ»ÑŒÐ·Ñ Ð²ÐºÐ»ÑŽÑ‡Ð¸Ñ‚ÑŒ физику Ð´Ð»Ñ Ð¾Ð±ÑŠÐµÐºÑ‚Ð° Ñ Ñ€Ð°Ñходом реÑурÑов физики больше [MAX_OBJECTS]
+ </notification>
+ <notification name="PhantomWithConcavePiece">
+ Этот объект не может Ñодержать вогнутых Ñлементов: Ñто фантом, который отноÑитÑÑ Ðº навигационной Ñетке.
+ </notification>
+ <notification name="UnableAddItem">
+ Ðевозможно добавить предмет!
+ </notification>
+ <notification name="UnableEditItem">
+ Редактирование невозможно!
+ </notification>
+ <notification name="NoPermToEdit">
+ Редактирование не разрешено.
+ </notification>
+ <notification name="NoPermToCopyInventory">
+ Ðе разрешено копировать Ñтот инвентарь.
+ </notification>
+ <notification name="CantSaveItemDoesntExist">
+ ÐÐµÐ»ÑŒÐ·Ñ Ñохранить в Ñодержимом объекта: предмет уже не ÑущеÑтвует.
+ </notification>
+ <notification name="CantSaveItemAlreadyExists">
+ ÐÐµÐ»ÑŒÐ·Ñ Ñохранить в Ñодержимом объекта: предмет Ñ Ñ‚Ð°ÐºÐ¸Ð¼ названием уже еÑÑ‚ÑŒ в инвентаре
+ </notification>
+ <notification name="CantSaveModifyAttachment">
+ ÐÐµÐ»ÑŒÐ·Ñ Ñохранить в Ñодержимом объекта: Ñто приведет к изменению разрешений прикрепленного объекта.
+ </notification>
+ <notification name="TooManyScripts">
+ Слишком много Ñкриптов.
+ </notification>
+ <notification name="UnableAddScript">
+ Ðевозможно добавить Ñкрипт!
+ </notification>
+ <notification name="AssetServerTimeoutObjReturn">
+ Сервер активов не ответил в заданное времÑ. Объект возвращен в ÑимулÑтор.
+ </notification>
+ <notification name="RegionDisablePhysicsShapes">
+ Ð’ Ñтом регионе не разрешены фигуры Ñ Ñ„Ð¸Ð·Ð¸Ñ‡ÐµÑкими данными.
+ </notification>
+ <notification name="NoModNavmeshAcrossRegions">
+ ÐÐµÐ»ÑŒÐ·Ñ Ð¸Ð·Ð¼ÐµÐ½ÑÑ‚ÑŒ навигационную Ñетку за пределами региона.
+ </notification>
+ <notification name="NoSetPhysicsPropertiesOnObjectType">
+ ÐÐµÐ»ÑŒÐ·Ñ Ð·Ð°Ð´Ð°Ñ‚ÑŒ ÑвойÑтва физики Ð´Ð»Ñ Ð¾Ð±ÑŠÐµÐºÑ‚Ð° Ñтого типа.
+ </notification>
+ <notification name="NoSetRootPrimWithNoShape">
+ ÐÐµÐ»ÑŒÐ·Ñ Ð·Ð°Ð´Ð°Ñ‚ÑŒ корневой примитив без фигуры.
+ </notification>
+ <notification name="NoRegionSupportPhysMats">
+ Ð’ Ñтом регионе не разрешены материалы Ñ Ñ„Ð¸Ð·Ð¸Ñ‡ÐµÑкими данными.
+ </notification>
+ <notification name="OnlyRootPrimPhysMats">
+ ÐаÑтройка материалов Ñ Ñ„Ð¸Ð·Ð¸Ñ‡ÐµÑкими данными разрешена только Ð´Ð»Ñ ÐºÐ¾Ñ€Ð½ÐµÐ²Ñ‹Ñ… примитивов.
+ </notification>
+ <notification name="NoSupportCharacterPhysMats">
+ ПриÑвоение перÑонажам материалов Ñ Ñ„Ð¸Ð·Ð¸Ñ‡ÐµÑкими данными еще не поддерживаетÑÑ.
+ </notification>
+ <notification name="InvalidPhysMatProperty">
+ Одно или неÑколько ÑвойÑтв указанного материала Ñ Ñ„Ð¸Ð·Ð¸Ñ‡ÐµÑкими данными недопуÑтимы.
+ </notification>
+ <notification name="NoPermsAlterStitchingMeshObj">
+ Ðе разрешаетÑÑ Ð¸Ð·Ð¼ÐµÐ½ÑÑ‚ÑŒ тип Ñтыковки меш-объекта.
+ </notification>
+ <notification name="NoPermsAlterShapeMeshObj">
+ Ðе разрешаетÑÑ Ð¸Ð·Ð¼ÐµÐ½ÑÑ‚ÑŒ форму меш-объекта
+ </notification>
+ <notification name="FullRegionCantEnter">
+ Вам нет доÑтупа в Ñтот регион: \nрегион заполнен.
+ </notification>
+ <notification name="LinkFailedOwnersDiffer">
+ СвÑзь невозможна -- разные владельцы
+ </notification>
+ <notification name="LinkFailedNoModNavmeshAcrossRegions">
+ СвÑзь невозможна – Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ð·Ð¼ÐµÐ½ÑÑ‚ÑŒ навигационную Ñетку за пределами региона.
+ </notification>
+ <notification name="LinkFailedNoPermToEdit">
+ СвÑзь невозможна: у Ð²Ð°Ñ Ð½ÐµÑ‚ Ñ€Ð°Ð·Ñ€ÐµÑˆÐµÐ½Ð¸Ñ Ð½Ð° редактирование.
+ </notification>
+ <notification name="LinkFailedTooManyPrims">
+ СвÑзь невозможна -- Ñлишком много примитивов
+ </notification>
+ <notification name="LinkFailedCantLinkNoCopyNoTrans">
+ СвÑзь невозможна -- Ð½ÐµÐ»ÑŒÐ·Ñ ÑвÑзать некопируемый и непереноÑимый объекты
+ </notification>
+ <notification name="LinkFailedNothingLinkable">
+ СвÑзь невозможна -- нет ÑвÑзываемых объектов.
+ </notification>
+ <notification name="LinkFailedTooManyPathfindingChars">
+ СвÑзь невозможна -- Ñлишком много перÑонажей Ñ Ð¿Ð¾Ð¸Ñком пути
+ </notification>
+ <notification name="LinkFailedInsufficientLand">
+ СвÑзь невозможна -- недоÑтаточно земельных реÑурÑов
+ </notification>
+ <notification name="LinkFailedTooMuchPhysics">
+ Объект иÑпользует Ñлишком много реÑурÑов физики -- динамичеÑкое поведение отключено.
+ </notification>
+ <notification name="TeleportedHomeByObjectOnParcel">
+ Ð’Ñ‹ были телепортированы домой объектом «[OBJECT_NAME]» на учаÑтке «[PARCEL_NAME]»
+ </notification>
+ <notification name="TeleportedHomeByObject">
+ Вы были телепортированы домой объектом «[OBJECT_NAME]»
+ </notification>
+ <notification name="TeleportedByAttachment">
+ Вы были телепортированы прикрепленным объектом [ITEM_ID]
+ </notification>
+ <notification name="TeleportedByObjectOnParcel">
+ Ð’Ñ‹ были телепортированы объектом «[OBJECT_NAME]» на учаÑтке «[PARCEL_NAME]»
+ </notification>
+ <notification name="TeleportedByObjectOwnedBy">
+ Вы были телепортированы объектом «[OBJECT_NAME]», владелец – [OWNER_ID]
+ </notification>
+ <notification name="TeleportedByObjectUnknownUser">
+ Ð’Ñ‹ были телепортированы объектом «[OBJECT_NAME]», владелец неизвеÑтен.
+ </notification>
+ <notification name="CantCreateObjectRegionFull">
+ Ðевозможно Ñоздать запрошенный объект. Регион уже заполнен.
+ </notification>
+ <notification name="CantAttackMultipleObjOneSpot">
+ ÐÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€Ð¸Ñоединить неÑколько объектов к одной точке.
+ </notification>
+ <notification name="CantCreateMultipleObjAtLoc">
+ ЗдеÑÑŒ Ð½ÐµÐ»ÑŒÐ·Ñ Ñоздать неÑколько объектов.
+ </notification>
+ <notification name="UnableToCreateObjTimeOut">
+ Ðевозможно Ñоздать запрошенный объект. Объекта нет в базе данных.
+ </notification>
+ <notification name="UnableToCreateObjUnknown">
+ Ðевозможно Ñоздать запрошенный объект. ИÑтекло Ð²Ñ€ÐµÐ¼Ñ Ð·Ð°Ð¿Ñ€Ð¾Ñа. Повторите попытку.
+ </notification>
+ <notification name="UnableToCreateObjMissingFromDB">
+ Ðевозможно Ñоздать запрошенный объект. Повторите попытку.
+ </notification>
+ <notification name="RezFailureTookTooLong">
+ Ðе удалоÑÑŒ выложить, загрузка нужного объекта длитÑÑ Ñлишком долго.
+ </notification>
+ <notification name="FailedToPlaceObjAtLoc">
+ Ðе удалоÑÑŒ помеÑтить объект в указанное меÑто. Повторите попытку.
+ </notification>
+ <notification name="CantCreatePlantsOnLand">
+ Вам Ð½ÐµÐ»ÑŒÐ·Ñ Ñоздавать раÑÑ‚ÐµÐ½Ð¸Ñ Ð½Ð° Ñтой земле.
+ </notification>
+ <notification name="CantRestoreObjectNoWorldPos">
+ Ðевозможно воÑÑтановить объект. Ðе найдена Ð¿Ð¾Ð·Ð¸Ñ†Ð¸Ñ Ð² игровом мире.
+ </notification>
+ <notification name="CantRezObjectInvalidMeshData">
+ Ðевозможно выложить объект: его данные Ñетки неверны.
+ </notification>
+ <notification name="CantRezObjectTooManyScripts">
+ Ðевозможно выложить объект: в Ñтом регионе уже Ñликом много Ñкриптов.
+ </notification>
+ <notification name="CantCreateObjectNoAccess">
+ Ваши привилегии доÑтупа не разрешают Ñоздание объектов на Ñтом меÑте.
+ </notification>
+ <notification name="CantCreateObject">
+ Ð¡ÐµÐ¹Ñ‡Ð°Ñ Ð²Ð°Ð¼ не разрешено Ñоздавать объекты.
+ </notification>
+ <notification name="InvalidObjectParams">
+ Ðеверные параметры объекта
+ </notification>
+ <notification name="CantDuplicateObjectNoAcess">
+ Ваши привилегии доÑтупа не разрешают дублирование объектов на Ñтом меÑте.
+ </notification>
+ <notification name="CantChangeShape">
+ Вам не разрешено изменÑÑ‚ÑŒ Ñту фигуру.
+ </notification>
+ <notification name="NoAccessToClaimObjects">
+ Ваши привилегии доÑтупа не разрешают претендовать на объекты на Ñтом меÑте.
+ </notification>
+ <notification name="DeedFailedNoPermToDeedForGroup">
+ Ðе удалоÑÑŒ передать: вам не разрешено передавать объекты Ð´Ð»Ñ Ñтой группы.
+ </notification>
+ <notification name="NoPrivsToBuyObject">
+ Ваши привилегии доÑтупа не разрешают покупать объекты на Ñтом меÑте.
+ </notification>
+ <notification name="CantAttachObjectAvatarSittingOnIt">
+ Ðевозможно приÑоединить объект: на нем Ñидит аватар.
+ </notification>
+ <notification name="WhyAreYouTryingToWearShrubbery">
+ Ð”ÐµÑ€ÐµÐ²ÑŒÑ Ð¸ траву Ð½ÐµÐ»ÑŒÐ·Ñ Ð½Ð¾Ñить как прикрепленные объекты.
+ </notification>
+ <notification name="CantAttachGroupOwnedObjs">
+ ÐÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€Ð¸ÑоединÑÑ‚ÑŒ объекты, принадлежащие группе.
+ </notification>
+ <notification name="CantAttachObjectsNotOwned">
+ ÐÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€Ð¸ÐºÑ€ÐµÐ¿Ð»ÑÑ‚ÑŒ объекты, которыми вы не владеете.
+ </notification>
+ <notification name="CantAttachNavmeshObjects">
+ Ðевозможно приÑоединить объекты, которые отноÑÑÑ‚ÑÑ Ðº навигационной Ñетке.
+ </notification>
+ <notification name="CantAttachObjectNoMovePermissions">
+ ÐÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€Ð¸Ñоединить объект: вам не разрешено его перемещать.
+ </notification>
+ <notification name="CantAttachNotEnoughScriptResources">
+ ÐедоÑтаточно Ñвободных реÑурÑов Ñкриптинга Ð´Ð»Ñ Ð¿Ñ€Ð¸ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ð¾Ð±ÑŠÐµÐºÑ‚Ð°!
+ </notification>
+ <notification name="CantDropItemTrialUser">
+ ЗдеÑÑŒ Ð½ÐµÐ»ÑŒÐ·Ñ ÑбраÑывать объекты; перейдите в беÑплатную облаÑÑ‚ÑŒ Ð´Ð»Ñ Ð³Ð¾Ñтей.
+ </notification>
+ <notification name="CantDropMeshAttachment">
+ ÐÐµÐ»ÑŒÐ·Ñ ÑбраÑывать прикрепленные меш-объекты. ОтÑоедините их в инвентарь, а затем выложите в игровой мир.
+ </notification>
+ <notification name="CantDropAttachmentNoPermission">
+ Ðе удалоÑÑŒ ÑброÑить прикрепленный объект: вам не разрешено оÑтавлÑÑ‚ÑŒ его здеÑÑŒ.
+ </notification>
+ <notification name="CantDropAttachmentInsufficientLandResources">
+ Ðе удалоÑÑŒ ÑброÑить прикрепленный объект: не хватает Ñвободных земельных реÑурÑов.
+ </notification>
+ <notification name="CantDropAttachmentInsufficientResources">
+ Ðе удалоÑÑŒ ÑброÑить прикрепленные объекты: не хватает Ñвободных реÑурÑов.
+ </notification>
+ <notification name="CantDropObjectFullParcel">
+ ÐÐµÐ»ÑŒÐ·Ñ ÑброÑить объект здеÑÑŒ. УчаÑток уже заполнен.
+ </notification>
+ <notification name="CantTouchObjectBannedFromParcel">
+ ÐÐµÐ»ÑŒÐ·Ñ ÐºÐ¾ÑнутьÑÑ/взÑÑ‚ÑŒ Ñтот объект: вы забанены на Ñтом учаÑтке.
+ </notification>
+ <notification name="PlzNarrowDeleteParams">
+ Уточните параметры удалениÑ.
+ </notification>
+ <notification name="UnableToUploadAsset">
+ Ðевозможно отправить актив.
+ </notification>
+ <notification name="CantTeleportCouldNotFindUser">
+ Ðе удалоÑÑŒ найти Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð´Ð»Ñ Ñ‚ÐµÐ»ÐµÐ¿Ð¾Ñ€Ñ‚Ð°Ñ†Ð¸Ð¸ домой
+ </notification>
+ <notification name="GodlikeRequestFailed">
+ режим творца недоÑтупен
+ </notification>
+ <notification name="GenericRequestFailed">
+ не удалоÑÑŒ выполнить общий запроÑ
+ </notification>
+ <notification name="CantUploadPostcard">
+ Ðевозможно отправить открытку. Повторите попытку позже.
+ </notification>
+ <notification name="CantFetchInventoryForGroupNotice">
+ Ðевозможно получить данные Ð¸Ð½Ð²ÐµÐ½Ñ‚Ð°Ñ€Ñ Ð´Ð»Ñ Ð³Ñ€ÑƒÐ¿Ð¿Ð¾Ð²Ð¾Ð³Ð¾ уведомлениÑ.
+ </notification>
+ <notification name="CantSendGroupNoticeNotPermitted">
+ Ðевозможно отправить групповое уведомление -- не разрешено.
+ </notification>
+ <notification name="CantSendGroupNoticeCantConstructInventory">
+ Ðевозможно отправить групповое уведомление -- не удалоÑÑŒ Ñобрать инвентарь.
+ </notification>
+ <notification name="CantParceInventoryInNotice">
+ Ðевозможно проанализировать инвентарь, указанный в уведомлении.
+ </notification>
+ <notification name="TerrainUploadFailed">
+ Ðе удалоÑÑŒ загрузить ландшафт.
+ </notification>
+ <notification name="TerrainFileWritten">
+ Файл ландшафта запиÑан.
+ </notification>
+ <notification name="TerrainFileWrittenStartingDownload">
+ Файл ландшафта запиÑан, начинаетÑÑ Ð·Ð°Ð³Ñ€ÑƒÐ·ÐºÐ°...
+ </notification>
+ <notification name="TerrainBaked">
+ Ландшафт готов.
+ </notification>
+ <notification name="TenObjectsDisabledPlzRefresh">
+ Отключены только первые 10 выбранных объектов. Обновите Ñкран и выберите объекты Ñнова, еÑли требуетÑÑ.
+ </notification>
+ <notification name="UpdateViewerBuyParcel">
+ Ð”Ð»Ñ Ð¿Ð¾ÐºÑƒÐ¿ÐºÐ¸ Ñтого учаÑтка необходимо обновить клиент.
+ </notification>
+ <notification name="CantBuyParcelNotForSale">
+ Ðевозможно купить, Ñтот учаÑток не предназначен Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð´Ð°Ð¶Ð¸.
+ </notification>
+ <notification name="CantBuySalePriceOrLandAreaChanged">
+ Ðевозможно купить: цена или площадь земли изменилиÑÑŒ.
+ </notification>
+ <notification name="CantBuyParcelNotAuthorized">
+ Вам не разрешено покупать Ñтот учаÑток.
+ </notification>
+ <notification name="CantBuyParcelAwaitingPurchaseAuth">
+ Ð’Ñ‹ не можете приобреÑти Ñтот учаÑток: он уже ожидает Ð¿Ð¾Ð´Ñ‚Ð²ÐµÑ€Ð¶Ð´ÐµÐ½Ð¸Ñ Ð¿Ð¾ÐºÑƒÐ¿ÐºÐ¸
+ </notification>
+ <notification name="CantBuildOverflowParcel">
+ ЗдеÑÑŒ Ð½ÐµÐ»ÑŒÐ·Ñ Ñоздавать объекты – учаÑток будет переполнен.
+ </notification>
+ <notification name="SelectedMultipleOwnedLand">
+ Ð’Ñ‹ выбрали землю Ñ Ñ€Ð°Ð·Ð½Ñ‹Ð¼Ð¸ владельцами. Выберите меньшую облаÑÑ‚ÑŒ и повторите попытку.
+ </notification>
+ <notification name="CantJoinTooFewLeasedParcels">
+ Выбрано недоÑтаточно арендуемых учаÑтков Ð´Ð»Ñ Ð²ÑтуплениÑ.
+ </notification>
+ <notification name="CantDivideLandMultipleParcelsSelected">
+ ÐÐµÐ»ÑŒÐ·Ñ Ñ€Ð°Ð·Ð´ÐµÐ»Ð¸Ñ‚ÑŒ землю.\nВыбрано больше одного учаÑтка.\nВыберите меньшую территорию.
+ </notification>
+ <notification name="CantDivideLandCantFindParcel">
+ ÐÐµÐ»ÑŒÐ·Ñ Ñ€Ð°Ð·Ð´ÐµÐ»Ð¸Ñ‚ÑŒ землю.\nÐе удалоÑÑŒ найти учаÑток.\nСообщите об Ñтой неполадке: Справка -&gt; Сообщить об ошибке...
+ </notification>
+ <notification name="CantDivideLandWholeParcelSelected">
+ Ðевозможно разделить землю. Выбран веÑÑŒ учаÑток.\nПопробуйте выбрать территорию поменьше.
+ </notification>
+ <notification name="LandHasBeenDivided">
+ Ð—ÐµÐ¼Ð»Ñ Ñ€Ð°Ð·Ð´ÐµÐ»ÐµÐ½Ð°.
+ </notification>
+ <notification name="PassPurchased">
+ Ð’Ñ‹ приобрели пропуÑк.
+ </notification>
+ <notification name="RegionDisallowsClassifieds">
+ Ð’ регионе не разрешены рекламные объÑвлениÑ.
+ </notification>
+ <notification name="LandPassExpireSoon">
+ Ваш пропуÑк на Ñту землю Ñкоро закончитÑÑ.
+ </notification>
+ <notification name="CantSitNoSuitableSurface">
+ Ðет подходÑщей поверхноÑти, чтобы ÑеÑÑ‚ÑŒ. Попробуйте в другом меÑте.
+ </notification>
+ <notification name="CantSitNoRoom">
+ ЗдеÑÑŒ нет меÑта, чтобы ÑеÑÑ‚ÑŒ. Попробуйте в другом меÑте.
+ </notification>
+ <notification name="ClaimObjectFailedNoPermission">
+ Ðевозможно претендовать на объект: у Ð²Ð°Ñ Ð½ÐµÑ‚ разрешениÑ
+ </notification>
+ <notification name="ClaimObjectFailedNoMoney">
+ Ðевозможно претендовать на объект: у Ð²Ð°Ñ Ð½Ðµ хватает L$.
+ </notification>
+ <notification name="CantDeedGroupLand">
+ ÐÐµÐ»ÑŒÐ·Ñ Ð¿ÐµÑ€ÐµÐ´Ð°Ñ‚ÑŒ землю, принадлежащую группе.
+ </notification>
+ <notification name="BuyObjectFailedNoMoney">
+ Ðе удалоÑÑŒ купить объект: у Ð²Ð°Ñ Ð½Ðµ хватает L$.
+ </notification>
+ <notification name="BuyInventoryFailedNoMoney">
+ Ðе удалоÑÑŒ купить инвентарь: у Ð²Ð°Ñ Ð½Ðµ хватает L$.
+ </notification>
+ <notification name="BuyPassFailedNoMoney">
+ У Ð²Ð°Ñ Ð½ÐµÐ´Ð¾Ñтаточно L$, чтобы заплатить за проход на Ñту землю.
+ </notification>
+ <notification name="CantBuyPassTryAgain">
+ Ð¡ÐµÐ¹Ñ‡Ð°Ñ Ð½ÐµÐ»ÑŒÐ·Ñ ÐºÑƒÐ¿Ð¸Ñ‚ÑŒ пропуÑк. Повторите попытку позже.
+ </notification>
+ <notification name="CantCreateObjectParcelFull">
+ Ðевозможно Ñоздать объект:\nучаÑток заполнен.
+ </notification>
+ <notification name="FailedPlacingObject">
+ Ðе удалоÑÑŒ помеÑтить объект в указанное меÑто. Повторите попытку.
+ </notification>
+ <notification name="CantCreateLandmarkForEvent">
+ Ðевозможно Ñоздать закладку Ð´Ð»Ñ ÑобытиÑ.
+ </notification>
+ <notification name="GodBeatsFreeze">
+ Сила творца одолевает заморозку!
+ </notification>
+ <notification name="SpecialPowersRequestFailedLogged">
+ Ðе удалоÑÑŒ выполнить Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð½Ð° оÑобые ÑпоÑобноÑти. Ð—Ð°Ð¿Ñ€Ð¾Ñ Ð·Ð°Ñ€ÐµÐ³Ð¸Ñтрирован.
+ </notification>
+ <notification name="ExpireExplanation">
+ СиÑтема ÑÐµÐ¹Ñ‡Ð°Ñ Ð½Ðµ может обработать ваш запроÑ. ИÑтекло Ð²Ñ€ÐµÐ¼Ñ Ð·Ð°Ð¿Ñ€Ð¾Ñа.
+ </notification>
+ <notification name="DieExplanation">
+ СиÑтема не может обработать ваш запроÑ.
+ </notification>
+ <notification name="AddPrimitiveFailure">
+ ÐедоÑтаточно денег Ð´Ð»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð¿Ñ€Ð¸Ð¼Ð¸Ñ‚Ð¸Ð²Ð°.
+ </notification>
+ <notification name="RezObjectFailure">
+ ÐедоÑтаточно денег Ð´Ð»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð¾Ð±ÑŠÐµÐºÑ‚Ð°.
+ </notification>
+ <notification name="ResetHomePositionNotLegal">
+ ÐедопуÑтимое домашнее меÑтоположение; воÑÑтановлено Ñтандартное меÑтоположение.
+ </notification>
+ <notification name="CantInviteRegionFull">
+ Ð¡ÐµÐ¹Ñ‡Ð°Ñ Ð²Ñ‹ не можете никого приглаÑить к Ñебе: регион уже заполнен. Повторите попытку позже.
+ </notification>
+ <notification name="CantSetHomeAtRegion">
+ Вам не разрешено уÑтанавливать Ñвое домашнее меÑтоположение в Ñтом регионе.
+ </notification>
+ <notification name="ListValidHomeLocations">
+ Задать домашнее меÑтоположение можно только на вашей земле или в Инфохабе материка.
+ </notification>
+ <notification name="SetHomePosition">
+ Домашнее меÑтоположение задано.
+ </notification>
+ <notification name="CantDerezInventoryError">
+ Ðевозможно забрать объект: Ñбой инвентарÑ.
+ </notification>
+ <notification name="CantCreateRequestedInv">
+ Ðевозможно Ñоздать требуемый инвентарь.
+ </notification>
+ <notification name="CantCreateRequestedInvFolder">
+ Ðевозможно Ñоздать требуемую папку инвентарÑ.
+ </notification>
+ <notification name="CantCreateInventory">
+ Ðевозможно Ñоздать Ñтот инвентарь.
+ </notification>
+ <notification name="CantCreateLandmark">
+ Ðевозможно Ñоздать закладку.
+ </notification>
+ <notification name="CantCreateOutfit">
+ Ð¡ÐµÐ¹Ñ‡Ð°Ñ Ð½ÐµÐ»ÑŒÐ·Ñ Ñоздать коÑтюм. Попробуйте через минуту.
+ </notification>
+ <notification name="InventoryNotForSale">
+ Инвентарь не Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð´Ð°Ð¶Ð¸.
+ </notification>
+ <notification name="CantFindInvItem">
+ Ðе удалоÑÑŒ найти предмет из инвентарÑ.
+ </notification>
+ <notification name="CantFindObject">
+ Ðе удалоÑÑŒ найти объект.
+ </notification>
+ <notification name="CantTransfterMoneyRegionDisabled">
+ Ð¡ÐµÐ¹Ñ‡Ð°Ñ Ð² Ñтом регионе запрещен перевод денег на объекты.
+ </notification>
+ <notification name="CantPayNoAgent">
+ ÐепонÑтно, кому платить.
+ </notification>
+ <notification name="CantDonateToPublicObjects">
+ ÐÐµÐ»ÑŒÐ·Ñ Ð¾Ñ‚Ð´Ð°Ð²Ð°Ñ‚ÑŒ L$ за общедоÑтупные объекты.
+ </notification>
+ <notification name="InventoryCreationInWorldObjectFailed">
+ Ðе удалоÑÑŒ Ñоздать инвентарь в объекте игрового мира.
+ </notification>
+ <notification name="UserBalanceOrLandUsageError">
+ Ðе удалоÑÑŒ обновить клиент из-за внутренней ошибки. Отображаемый в клиенте Ð±Ð°Ð»Ð°Ð½Ñ L$ или владение учаÑтками могут не ÑоответÑтвовать дейÑтвительному баланÑу на Ñерверах.
+ </notification>
+ <notification name="LargePrimAgentIntersect">
+ ÐÐµÐ»ÑŒÐ·Ñ Ñоздавать большие примитивы, которые переÑекаютÑÑ Ñ Ð´Ñ€ÑƒÐ³Ð¸Ð¼Ð¸ игроками. Повторите попытку, когда другие игроки уйдут.
+ </notification>
+ <notification name="PreferenceChatClearLog">
+ Будут удалены журналы предыдущих разговоров и вÑе резервные копии Ñтих файлов.
+ <usetemplate ignoretext="Подтверждать удаление журнала предыдущих разговоров." name="okcancelignore" notext="Отмена" yestext="OK"/>
+ </notification>
+ <notification name="PreferenceChatDeleteTranscripts">
+ Будут удалены запиÑи вÑех предыдущих разговоров. СпиÑок прошедших разговоров не изменитÑÑ. Ð’Ñе файлы Ñ Ñ€Ð°ÑширениÑми .txt и txt.backup в папке [FOLDER] будут удалены.
+ <usetemplate ignoretext="Подтверждать удаление запиÑей." name="okcancelignore" notext="Отмена" yestext="OK"/>
+ </notification>
+ <notification name="PreferenceChatPathChanged">
+ Ðевозможно перемеÑтить файлы. ВоÑÑтановлен прежний путь.
+ <usetemplate ignoretext="Ðевозможно перемеÑтить файлы. ВоÑÑтановлен прежний путь." name="okignore" yestext="OK"/>
+ </notification>
</notifications>
diff --git a/indra/newview/skins/default/xui/ru/panel_active_object_row.xml b/indra/newview/skins/default/xui/ru/panel_active_object_row.xml
index 825f9a6229..825f9a6229 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_active_object_row.xml
+++ b/indra/newview/skins/default/xui/ru/panel_active_object_row.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_adhoc_control_panel.xml b/indra/newview/skins/default/xui/ru/panel_adhoc_control_panel.xml
index ae2240593d..ae2240593d 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_adhoc_control_panel.xml
+++ b/indra/newview/skins/default/xui/ru/panel_adhoc_control_panel.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_avatar_list_item.xml b/indra/newview/skins/default/xui/ru/panel_avatar_list_item.xml
index 75e396222f..4866bb7ed6 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_avatar_list_item.xml
+++ b/indra/newview/skins/default/xui/ru/panel_avatar_list_item.xml
@@ -27,5 +27,6 @@
<icon name="permission_edit_mine_icon" tool_tip="Этот друг может изменÑÑ‚ÑŒ, удалÑÑ‚ÑŒ или брать ваши объекты"/>
<icon name="permission_map_icon" tool_tip="Этот друг может видеть Ð²Ð°Ñ Ð½Ð° карте"/>
<icon name="permission_online_icon" tool_tip="Этот друг может видеть ваш ÑÑ‚Ð°Ñ‚ÑƒÑ Ð² Ñети"/>
+ <button name="info_btn" tool_tip="Дополнительно"/>
<button name="profile_btn" tool_tip="Смотреть профиль"/>
</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_avatar_tag.xml b/indra/newview/skins/default/xui/ru/panel_avatar_tag.xml
index 03c164affd..03c164affd 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_avatar_tag.xml
+++ b/indra/newview/skins/default/xui/ru/panel_avatar_tag.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_block_list_sidetray.xml b/indra/newview/skins/default/xui/ru/panel_block_list_sidetray.xml
index 214ca8bf3a..70a1b25996 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_block_list_sidetray.xml
+++ b/indra/newview/skins/default/xui/ru/panel_block_list_sidetray.xml
@@ -1,10 +1,11 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel name="block_list_panel">
- <text name="title_text">
- Черный ÑпиÑок
- </text>
- <scroll_list name="blocked" tool_tip="СпиÑок заблокированных жителей"/>
- <button label="Заблокировать жителÑ" name="Block resident..." tool_tip="Выберите Ð¶Ð¸Ñ‚ÐµÐ»Ñ Ð´Ð»Ñ Ð±Ð»Ð¾ÐºÐ¸Ñ€Ð¾Ð²ÐºÐ¸"/>
- <button label="Блокировать объект по имени" name="Block object by name..." tool_tip="Выберите объект Ð´Ð»Ñ Ð±Ð»Ð¾ÐºÐ¸Ñ€Ð¾Ð²ÐºÐ¸ по имени"/>
- <button label="Разблокировать" name="Unblock" tool_tip="Удалить объект или Ð¶Ð¸Ñ‚ÐµÐ»Ñ Ð¸Ð· ÑпиÑка заблокированных"/>
+ <panel label="bottom_panel" name="blocked_buttons_panel">
+ <filter_editor label="Фильтр" name="blocked_filter_input"/>
+ <menu_button name="blocked_gear_btn" tool_tip="ДейÑÑ‚Ð²Ð¸Ñ Ñ Ð²Ñ‹Ð±Ñ€Ð°Ð½Ð½Ñ‹Ð¼ жителем или объектом"/>
+ <menu_button name="view_btn" tool_tip="Параметры Ñортировки"/>
+ <menu_button name="plus_btn" tool_tip="Выберите Ð¶Ð¸Ñ‚ÐµÐ»Ñ Ð¸Ð»Ð¸ объект Ð´Ð»Ñ Ð±Ð»Ð¾ÐºÐ¸Ñ€Ð¾Ð²ÐºÐ¸"/>
+ <button name="unblock_btn" tool_tip="Удалить объект или Ð¶Ð¸Ñ‚ÐµÐ»Ñ Ð¸Ð· ÑпиÑка заблокированных"/>
+ </panel>
+ <block_list name="blocked" tool_tip="СпиÑок заблокированных жителей"/>
</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_body_parts_list_item.xml b/indra/newview/skins/default/xui/ru/panel_body_parts_list_item.xml
index 20a99500b6..20a99500b6 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_body_parts_list_item.xml
+++ b/indra/newview/skins/default/xui/ru/panel_body_parts_list_item.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_bodyparts_list_button_bar.xml b/indra/newview/skins/default/xui/ru/panel_bodyparts_list_button_bar.xml
index f7d31813f9..f7d31813f9 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_bodyparts_list_button_bar.xml
+++ b/indra/newview/skins/default/xui/ru/panel_bodyparts_list_button_bar.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_bottomtray.xml b/indra/newview/skins/default/xui/ru/panel_bottomtray.xml
deleted file mode 100644
index ebf6c4264b..0000000000
--- a/indra/newview/skins/default/xui/ru/panel_bottomtray.xml
+++ /dev/null
@@ -1,47 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel name="bottom_tray">
- <string name="DragIndicationImageName" value="Accordion_ArrowOpened_Off"/>
- <string name="SpeakBtnToolTip" value="Включить/выключить микрофон"/>
- <string name="VoiceControlBtnToolTip" value="Показать/Ñкрыть панель ÑƒÐ¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð³Ð¾Ð»Ð¾Ñом"/>
- <layout_stack name="toolbar_stack">
- <layout_panel name="speak_panel">
- <talk_button name="talk">
- <speak_button label="Говорить" label_selected="Говорить" name="speak_btn"/>
- </talk_button>
- </layout_panel>
- <layout_panel name="gesture_panel">
- <gesture_combo_list label="ЖеÑÑ‚Ñ‹" name="Gesture" tool_tip="Показать/Ñкрыть жеÑÑ‚Ñ‹"/>
- </layout_panel>
- <layout_panel name="movement_panel">
- <bottomtray_button label="Перемещение" name="movement_btn" tool_tip="Показать/Ñкрыть панель ÑƒÐ¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð´Ð²Ð¸Ð¶ÐµÐ½Ð¸ÐµÐ¼"/>
- </layout_panel>
- <layout_panel name="cam_panel">
- <bottomtray_button label="Камера" name="camera_btn" tool_tip="Показать/Ñкрыть управление камерой"/>
- </layout_panel>
- <layout_panel name="snapshot_panel">
- <bottomtray_button name="snapshots" tool_tip="Сделать Ñнимок"/>
- </layout_panel>
- <layout_panel name="build_btn_panel">
- <bottomtray_button label="СтроительÑтво" name="build_btn" tool_tip="Показать/Ñкрыть инÑтрументы"/>
- </layout_panel>
- <layout_panel name="search_btn_panel">
- <bottomtray_button label="ПоиÑк" name="search_btn" tool_tip="Показать/Ñкрыть поиÑк"/>
- </layout_panel>
- <layout_panel name="world_map_btn_panel">
- <bottomtray_button label="Карта" name="world_map_btn" tool_tip="Показать/Ñкрыть карту мира"/>
- </layout_panel>
- <layout_panel name="mini_map_btn_panel">
- <bottomtray_button label="Миникарта" name="mini_map_btn" tool_tip="Показать/Ñкрыть миникарту"/>
- </layout_panel>
- <layout_panel name="im_well_panel">
- <chiclet_im_well name="im_well">
- <button name="Unread IM messages" tool_tip="Общение"/>
- </chiclet_im_well>
- </layout_panel>
- <layout_panel name="notification_well_panel">
- <chiclet_notification name="notification_well">
- <button name="Unread" tool_tip="УведомлениÑ"/>
- </chiclet_notification>
- </layout_panel>
- </layout_stack>
-</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_bottomtray_lite.xml b/indra/newview/skins/default/xui/ru/panel_bottomtray_lite.xml
index bcdff112c5..bcdff112c5 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_bottomtray_lite.xml
+++ b/indra/newview/skins/default/xui/ru/panel_bottomtray_lite.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_chat_header.xml b/indra/newview/skins/default/xui/ru/panel_chat_header.xml
index 7916bf5155..7916bf5155 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_chat_header.xml
+++ b/indra/newview/skins/default/xui/ru/panel_chat_header.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_chiclet_bar.xml b/indra/newview/skins/default/xui/ru/panel_chiclet_bar.xml
index f203ecde4b..f203ecde4b 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_chiclet_bar.xml
+++ b/indra/newview/skins/default/xui/ru/panel_chiclet_bar.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_classified_info.xml b/indra/newview/skins/default/xui/ru/panel_classified_info.xml
index c7fd0ad42f..c7fd0ad42f 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_classified_info.xml
+++ b/indra/newview/skins/default/xui/ru/panel_classified_info.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_clothing_list_button_bar.xml b/indra/newview/skins/default/xui/ru/panel_clothing_list_button_bar.xml
index cc3f7feb83..cc3f7feb83 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_clothing_list_button_bar.xml
+++ b/indra/newview/skins/default/xui/ru/panel_clothing_list_button_bar.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_clothing_list_item.xml b/indra/newview/skins/default/xui/ru/panel_clothing_list_item.xml
index 98d4fd8b47..98d4fd8b47 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_clothing_list_item.xml
+++ b/indra/newview/skins/default/xui/ru/panel_clothing_list_item.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_cof_wearables.xml b/indra/newview/skins/default/xui/ru/panel_cof_wearables.xml
index 9e1bc4b5c4..9e1bc4b5c4 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_cof_wearables.xml
+++ b/indra/newview/skins/default/xui/ru/panel_cof_wearables.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_conversation_list_item.xml b/indra/newview/skins/default/xui/ru/panel_conversation_list_item.xml
new file mode 100644
index 0000000000..4fdb4f9122
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/panel_conversation_list_item.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="conversation_list_item">
+ <layout_stack name="conversation_item_stack">
+ <layout_panel name="conversation_title_panel">
+ <text name="conversation_title" value="(загрузка)"/>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_conversation_log_list_item.xml b/indra/newview/skins/default/xui/ru/panel_conversation_log_list_item.xml
new file mode 100644
index 0000000000..98fe7b99be
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/panel_conversation_log_list_item.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="conversation_log_list_item">
+ <icon name="voice_session_icon" tool_tip="Ð’ÐºÐ»ÑŽÑ‡Ð°Ñ Ð³Ð¾Ð»Ð¾Ñовой чат"/>
+ <icon name="unread_ims_icon" tool_tip="За Ð²Ñ€ÐµÐ¼Ñ Ð²Ð°ÑˆÐµÐ³Ð¾ отÑутÑÑ‚Ð²Ð¸Ñ Ð¿Ñ€Ð¸ÑˆÐ»Ð¸ ÑообщениÑ"/>
+ <button name="delete_btn" tool_tip="Удалить Ñту запиÑÑŒ"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_deletable_wearable_list_item.xml b/indra/newview/skins/default/xui/ru/panel_deletable_wearable_list_item.xml
index 762baa2052..762baa2052 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_deletable_wearable_list_item.xml
+++ b/indra/newview/skins/default/xui/ru/panel_deletable_wearable_list_item.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_dummy_clothing_list_item.xml b/indra/newview/skins/default/xui/ru/panel_dummy_clothing_list_item.xml
index dc9d678edd..dc9d678edd 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_dummy_clothing_list_item.xml
+++ b/indra/newview/skins/default/xui/ru/panel_dummy_clothing_list_item.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_edit_alpha.xml b/indra/newview/skins/default/xui/ru/panel_edit_alpha.xml
index 7cde4099ef..7cde4099ef 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_edit_alpha.xml
+++ b/indra/newview/skins/default/xui/ru/panel_edit_alpha.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_edit_classified.xml b/indra/newview/skins/default/xui/ru/panel_edit_classified.xml
index a2f06dbadf..a2f06dbadf 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_edit_classified.xml
+++ b/indra/newview/skins/default/xui/ru/panel_edit_classified.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_edit_eyes.xml b/indra/newview/skins/default/xui/ru/panel_edit_eyes.xml
index 84e1204b5d..84e1204b5d 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_edit_eyes.xml
+++ b/indra/newview/skins/default/xui/ru/panel_edit_eyes.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_edit_gloves.xml b/indra/newview/skins/default/xui/ru/panel_edit_gloves.xml
index 561777745e..561777745e 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_edit_gloves.xml
+++ b/indra/newview/skins/default/xui/ru/panel_edit_gloves.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_edit_hair.xml b/indra/newview/skins/default/xui/ru/panel_edit_hair.xml
index d5e67ddf87..d5e67ddf87 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_edit_hair.xml
+++ b/indra/newview/skins/default/xui/ru/panel_edit_hair.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_edit_jacket.xml b/indra/newview/skins/default/xui/ru/panel_edit_jacket.xml
index 2f5a437e69..2f5a437e69 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_edit_jacket.xml
+++ b/indra/newview/skins/default/xui/ru/panel_edit_jacket.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_edit_pants.xml b/indra/newview/skins/default/xui/ru/panel_edit_pants.xml
index 4970c93801..4970c93801 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_edit_pants.xml
+++ b/indra/newview/skins/default/xui/ru/panel_edit_pants.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_edit_physics.xml b/indra/newview/skins/default/xui/ru/panel_edit_physics.xml
index da4ebb154d..da4ebb154d 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_edit_physics.xml
+++ b/indra/newview/skins/default/xui/ru/panel_edit_physics.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_edit_pick.xml b/indra/newview/skins/default/xui/ru/panel_edit_pick.xml
index 6be1448ac5..6be1448ac5 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_edit_pick.xml
+++ b/indra/newview/skins/default/xui/ru/panel_edit_pick.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_edit_profile.xml b/indra/newview/skins/default/xui/ru/panel_edit_profile.xml
index e9a6a781db..e9a6a781db 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_edit_profile.xml
+++ b/indra/newview/skins/default/xui/ru/panel_edit_profile.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_edit_shape.xml b/indra/newview/skins/default/xui/ru/panel_edit_shape.xml
index 312ad593a1..312ad593a1 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_edit_shape.xml
+++ b/indra/newview/skins/default/xui/ru/panel_edit_shape.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_edit_shirt.xml b/indra/newview/skins/default/xui/ru/panel_edit_shirt.xml
index d576a2cd2f..d576a2cd2f 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_edit_shirt.xml
+++ b/indra/newview/skins/default/xui/ru/panel_edit_shirt.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_edit_shoes.xml b/indra/newview/skins/default/xui/ru/panel_edit_shoes.xml
index f6d7029108..f6d7029108 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_edit_shoes.xml
+++ b/indra/newview/skins/default/xui/ru/panel_edit_shoes.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_edit_skin.xml b/indra/newview/skins/default/xui/ru/panel_edit_skin.xml
index f5a5339afe..f5a5339afe 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_edit_skin.xml
+++ b/indra/newview/skins/default/xui/ru/panel_edit_skin.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_edit_skirt.xml b/indra/newview/skins/default/xui/ru/panel_edit_skirt.xml
index 909946e577..909946e577 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_edit_skirt.xml
+++ b/indra/newview/skins/default/xui/ru/panel_edit_skirt.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_edit_socks.xml b/indra/newview/skins/default/xui/ru/panel_edit_socks.xml
index 2827fbc028..2827fbc028 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_edit_socks.xml
+++ b/indra/newview/skins/default/xui/ru/panel_edit_socks.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_edit_tattoo.xml b/indra/newview/skins/default/xui/ru/panel_edit_tattoo.xml
index 874d5f8bc4..874d5f8bc4 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_edit_tattoo.xml
+++ b/indra/newview/skins/default/xui/ru/panel_edit_tattoo.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_edit_underpants.xml b/indra/newview/skins/default/xui/ru/panel_edit_underpants.xml
index f2f6e5e516..f2f6e5e516 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_edit_underpants.xml
+++ b/indra/newview/skins/default/xui/ru/panel_edit_underpants.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_edit_undershirt.xml b/indra/newview/skins/default/xui/ru/panel_edit_undershirt.xml
index 6f84c6cec2..6f84c6cec2 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_edit_undershirt.xml
+++ b/indra/newview/skins/default/xui/ru/panel_edit_undershirt.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_edit_wearable.xml b/indra/newview/skins/default/xui/ru/panel_edit_wearable.xml
index 79130a9c80..79130a9c80 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_edit_wearable.xml
+++ b/indra/newview/skins/default/xui/ru/panel_edit_wearable.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_group_control_panel.xml b/indra/newview/skins/default/xui/ru/panel_group_control_panel.xml
index 2e6f3502b6..2e6f3502b6 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_group_control_panel.xml
+++ b/indra/newview/skins/default/xui/ru/panel_group_control_panel.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_group_general.xml b/indra/newview/skins/default/xui/ru/panel_group_general.xml
index 4d7e1c9fff..ba38dbf89e 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_group_general.xml
+++ b/indra/newview/skins/default/xui/ru/panel_group_general.xml
@@ -51,6 +51,6 @@
<combo_box.item label="Умеренный контент" name="mature"/>
<combo_box.item label="Общий контент" name="pg"/>
</combo_box>
- <check_box initial_value="иÑтина" label="Показать в поиÑке" name="show_in_group_list" tool_tip="Позволить людÑм видеть Ñту группу в результатах поиÑка"/>
+ <check_box initial_value="true" label="Показать в поиÑке" name="show_in_group_list" tool_tip="Позволить людÑм видеть Ñту группу в результатах поиÑка"/>
</panel>
</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_group_info_sidetray.xml b/indra/newview/skins/default/xui/ru/panel_group_info_sidetray.xml
index d8cf1b4756..d8cf1b4756 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_group_info_sidetray.xml
+++ b/indra/newview/skins/default/xui/ru/panel_group_info_sidetray.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_group_invite.xml b/indra/newview/skins/default/xui/ru/panel_group_invite.xml
index 3041046041..68dac5cd7e 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_group_invite.xml
+++ b/indra/newview/skins/default/xui/ru/panel_group_invite.xml
@@ -9,6 +9,9 @@
<panel.string name="already_in_group">
ÐеÑколько выбранных жителей уже ÑоÑтоÑÑ‚ в группе. Им Ð¿Ñ€Ð¸Ð³Ð»Ð°ÑˆÐµÐ½Ð¸Ñ Ð½Ðµ были отправлены.
</panel.string>
+ <panel.string name="invite_selection_too_large">
+ Групповые Ð¿Ñ€Ð¸Ð³Ð»Ð°ÑˆÐµÐ½Ð¸Ñ Ð½Ðµ отправлены: выбрано Ñлишком много жителей. Групповые Ð¿Ñ€Ð¸Ð³Ð»Ð°ÑˆÐµÐ½Ð¸Ñ Ð¼Ð¾Ð³ÑƒÑ‚ охватывать не более 100 пользователей за один запроÑ.
+ </panel.string>
<text name="help_text">
Можно выбрать неÑколько жителей Ð´Ð»Ñ Ð¿Ñ€Ð¸Ð³Ð»Ð°ÑˆÐµÐ½Ð¸Ñ Ð² группу. Чтобы начать, щелкните «Выбрать жителей».
</text>
diff --git a/indra/newview/skins/default/xui/ru/panel_group_land_money.xml b/indra/newview/skins/default/xui/ru/panel_group_land_money.xml
index 9235aa2f69..9235aa2f69 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_group_land_money.xml
+++ b/indra/newview/skins/default/xui/ru/panel_group_land_money.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_group_list_item.xml b/indra/newview/skins/default/xui/ru/panel_group_list_item.xml
index 7f000fb5a0..b043ffbbe2 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_group_list_item.xml
+++ b/indra/newview/skins/default/xui/ru/panel_group_list_item.xml
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel name="group_list_item">
<text name="group_name" value="ÐеизвеÑтно"/>
+ <button name="info_btn" tool_tip="Дополнительно"/>
<button name="profile_btn" tool_tip="Смотреть профиль"/>
</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_group_notices.xml b/indra/newview/skins/default/xui/ru/panel_group_notices.xml
index 8d20c4a96b..8d20c4a96b 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_group_notices.xml
+++ b/indra/newview/skins/default/xui/ru/panel_group_notices.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_group_notify.xml b/indra/newview/skins/default/xui/ru/panel_group_notify.xml
index 1aee7a7f61..1aee7a7f61 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_group_notify.xml
+++ b/indra/newview/skins/default/xui/ru/panel_group_notify.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_group_roles.xml b/indra/newview/skins/default/xui/ru/panel_group_roles.xml
index c57f21679f..c57f21679f 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_group_roles.xml
+++ b/indra/newview/skins/default/xui/ru/panel_group_roles.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_im_control_panel.xml b/indra/newview/skins/default/xui/ru/panel_im_control_panel.xml
index 2a23cdb800..2a23cdb800 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_im_control_panel.xml
+++ b/indra/newview/skins/default/xui/ru/panel_im_control_panel.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_instant_message.xml b/indra/newview/skins/default/xui/ru/panel_instant_message.xml
index cf9bc7fccb..cf9bc7fccb 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_instant_message.xml
+++ b/indra/newview/skins/default/xui/ru/panel_instant_message.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_inventory_item.xml b/indra/newview/skins/default/xui/ru/panel_inventory_item.xml
index d18047fbcf..d18047fbcf 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_inventory_item.xml
+++ b/indra/newview/skins/default/xui/ru/panel_inventory_item.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_landmark_info.xml b/indra/newview/skins/default/xui/ru/panel_landmark_info.xml
index f4febd49cd..f4febd49cd 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_landmark_info.xml
+++ b/indra/newview/skins/default/xui/ru/panel_landmark_info.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_landmarks.xml b/indra/newview/skins/default/xui/ru/panel_landmarks.xml
index 7d684cd479..7d684cd479 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_landmarks.xml
+++ b/indra/newview/skins/default/xui/ru/panel_landmarks.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_login.xml b/indra/newview/skins/default/xui/ru/panel_login.xml
index 7928191fa6..f0877731c6 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_login.xml
+++ b/indra/newview/skins/default/xui/ru/panel_login.xml
@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel name="panel_login">
- <panel.string name="create_account_url">
- http://join.secondlife.com/
- </panel.string>
<panel.string name="forgot_password_url">
http://secondlife.com/account/request.php
</panel.string>
<layout_stack name="login_widgets">
<layout_panel name="login">
+ <text name="log_in_text">
+ ВОЙТИ
+ </text>
<text name="username_text">
Ð˜Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ:
</text>
@@ -15,15 +15,8 @@
<text name="password_text">
Пароль:
</text>
- <check_box label="Запомнить пароль" name="remember_check"/>
- <button label="Войти" name="connect_btn"/>
- <text name="mode_selection_text">
- Режим:
- </text>
- <combo_box name="mode_combo" tool_tip="Выберите режим. ОÑновной – Ð´Ð»Ñ Ð±Ñ‹Ñтрого и проÑтого Ð¾Ð·Ð½Ð°ÐºÐ¾Ð¼Ð»ÐµÐ½Ð¸Ñ Ñ Ð¸Ð³Ñ€Ð¾Ð¹, а также общениÑ. РаÑширенный – Ð´Ð»Ñ Ð´Ð¾Ñтупа к более широким возможноÑÑ‚Ñм.">
- <combo_box.item label="ОÑновной" name="Basic"/>
- <combo_box.item label="РаÑширенный" name="Advanced"/>
- </combo_box>
+ </layout_panel>
+ <layout_panel name="start_location_panel">
<text name="start_location_text">
МеÑто Ñтарта:
</text>
@@ -33,16 +26,21 @@
<combo_box.item label="&lt;Введите название региона&gt;" name="Typeregionname"/>
</combo_box>
</layout_panel>
- <layout_panel name="links">
- <text name="create_new_account_text">
- РегиÑтрациÑ
+ <layout_panel name="links_login_panel">
+ <text name="login_help">
+ Ðужна помощь при входе?
</text>
<text name="forgot_password_text">
Забыли Ð¸Ð¼Ñ Ð¸Ð»Ð¸ пароль?
</text>
- <text name="login_help">
- Ðужна помощь при входе?
+ <button label="Войти" name="connect_btn"/>
+ <check_box label="Запомнить пароль" name="remember_check"/>
+ </layout_panel>
+ <layout_panel name="links">
+ <text name="create_account_text">
+ СОЗДÐЙТЕ СВОЙ ÐККÐУÐТ
</text>
+ <button label="Ðачать" name="create_new_account_btn"/>
</layout_panel>
</layout_stack>
</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_main_inventory.xml b/indra/newview/skins/default/xui/ru/panel_main_inventory.xml
index 80a67371af..80a67371af 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_main_inventory.xml
+++ b/indra/newview/skins/default/xui/ru/panel_main_inventory.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_me.xml b/indra/newview/skins/default/xui/ru/panel_me.xml
index 21a125af87..21a125af87 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_me.xml
+++ b/indra/newview/skins/default/xui/ru/panel_me.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_media_settings_general.xml b/indra/newview/skins/default/xui/ru/panel_media_settings_general.xml
index 6dc435db20..d52397832c 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_media_settings_general.xml
+++ b/indra/newview/skins/default/xui/ru/panel_media_settings_general.xml
@@ -15,14 +15,14 @@
</text>
<text name="current_url" tool_tip="Ð¢ÐµÐºÑƒÑ‰Ð°Ñ Ñтраница Ð´Ð»Ñ Ñтого медиа-иÑточника" value=""/>
<button label="СброÑ" name="current_url_reset_btn"/>
- <check_box initial_value="ложь" label="ÐвтоматичеÑкое зацикливание" name="auto_loop"/>
- <check_box initial_value="ложь" label="Ð ÐµÐ°ÐºÑ†Ð¸Ñ Ð½Ð° первый щелчок" name="first_click_interact"/>
- <check_box initial_value="ложь" label="Ðвтоувеличение" name="auto_zoom"/>
- <check_box initial_value="ложь" label="ÐвтоматичеÑкое проигрывание" name="auto_play"/>
+ <check_box initial_value="false" label="ÐвтоматичеÑкое зацикливание" name="auto_loop"/>
+ <check_box initial_value="false" label="Ð ÐµÐ°ÐºÑ†Ð¸Ñ Ð½Ð° первый щелчок" name="first_click_interact"/>
+ <check_box initial_value="false" label="Ðвтоувеличение" name="auto_zoom"/>
+ <check_box initial_value="false" label="ÐвтоматичеÑкое проигрывание" name="auto_play"/>
<text name="media_setting_note">
Примечание. Жители могут переопределÑÑ‚ÑŒ Ñту наÑтройку.
</text>
- <check_box initial_value="ложь" label="ÐвтомаÑштабирование на объекте" name="auto_scale"/>
+ <check_box initial_value="false" label="ÐвтомаÑштабирование на объекте" name="auto_scale"/>
<text name="size_label">
Размер:
</text>
diff --git a/indra/newview/skins/default/xui/ru/panel_media_settings_permissions.xml b/indra/newview/skins/default/xui/ru/panel_media_settings_permissions.xml
index 680cba9c14..cfb006f346 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_media_settings_permissions.xml
+++ b/indra/newview/skins/default/xui/ru/panel_media_settings_permissions.xml
@@ -14,16 +14,16 @@
<text name="owner_label">
Владелец
</text>
- <check_box initial_value="ложь" label="Разрешить навигацию и взаимодейÑтвие" name="perms_owner_interact"/>
- <check_box initial_value="ложь" label="Панель ÑƒÐ¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð²Ð¸Ð´Ð½Ð°" name="perms_owner_control"/>
+ <check_box initial_value="false" label="Разрешить навигацию и взаимодейÑтвие" name="perms_owner_interact"/>
+ <check_box initial_value="false" label="Панель ÑƒÐ¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð²Ð¸Ð´Ð½Ð°" name="perms_owner_control"/>
<text name="group_label">
Группа:
</text>
- <check_box initial_value="ложь" label="Разрешить навигацию и взаимодейÑтвие" name="perms_group_interact"/>
- <check_box initial_value="ложь" label="Панель ÑƒÐ¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð²Ð¸Ð´Ð½Ð°" name="perms_group_control"/>
+ <check_box initial_value="false" label="Разрешить навигацию и взаимодейÑтвие" name="perms_group_interact"/>
+ <check_box initial_value="false" label="Панель ÑƒÐ¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð²Ð¸Ð´Ð½Ð°" name="perms_group_control"/>
<text name="anyone_label">
вÑем
</text>
- <check_box initial_value="ложь" label="Разрешить навигацию и взаимодейÑтвие" name="perms_anyone_interact"/>
- <check_box initial_value="ложь" label="Панель ÑƒÐ¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð²Ð¸Ð´Ð½Ð°" name="perms_anyone_control"/>
+ <check_box initial_value="false" label="Разрешить навигацию и взаимодейÑтвие" name="perms_anyone_interact"/>
+ <check_box initial_value="false" label="Панель ÑƒÐ¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð²Ð¸Ð´Ð½Ð°" name="perms_anyone_control"/>
</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_media_settings_security.xml b/indra/newview/skins/default/xui/ru/panel_media_settings_security.xml
index 6b30dc799c..bae491472a 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_media_settings_security.xml
+++ b/indra/newview/skins/default/xui/ru/panel_media_settings_security.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel label="БезопаÑноÑÑ‚ÑŒ" name="Media Settings Security">
- <check_box initial_value="ложь" label="Разрешить доÑтуп к ÑÑылкам только по шаблону" name="whitelist_enable"/>
+ <check_box initial_value="false" label="Разрешить доÑтуп к ÑÑылкам только по шаблону" name="whitelist_enable"/>
<text name="home_url_fails_some_items_in_whitelist">
Пункты, не подходÑщие Ð´Ð»Ñ Ð´Ð¾Ð¼Ð°ÑˆÐ½ÐµÐ¹ Ñтраницы, отмечены знаком:
</text>
diff --git a/indra/newview/skins/default/xui/ru/panel_navigation_bar.xml b/indra/newview/skins/default/xui/ru/panel_navigation_bar.xml
index 5e3de180f9..5e3de180f9 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_navigation_bar.xml
+++ b/indra/newview/skins/default/xui/ru/panel_navigation_bar.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_nearby_chat.xml b/indra/newview/skins/default/xui/ru/panel_nearby_chat.xml
index a8fdfde1c4..a8fdfde1c4 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_nearby_chat.xml
+++ b/indra/newview/skins/default/xui/ru/panel_nearby_chat.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_nearby_chat_bar.xml b/indra/newview/skins/default/xui/ru/panel_nearby_chat_bar.xml
index 804ba7def7..395c643b0b 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_nearby_chat_bar.xml
+++ b/indra/newview/skins/default/xui/ru/panel_nearby_chat_bar.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel name="chat_bar">
+<panel name="nearby_chat">
<line_editor label="Щелкните здеÑÑŒ Ð´Ð»Ñ Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ" name="chat_box" tool_tip="Ðажмите Enter, чтобы Ñказать, Ctrl+Enter, чтобы прокричать"/>
<button name="show_nearby_chat" tool_tip="Показать/Ñкрыть лог локального чата"/>
</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_nearby_media.xml b/indra/newview/skins/default/xui/ru/panel_nearby_media.xml
index 3b23fc78f5..3b23fc78f5 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_nearby_media.xml
+++ b/indra/newview/skins/default/xui/ru/panel_nearby_media.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_notify_textbox.xml b/indra/newview/skins/default/xui/ru/panel_notify_textbox.xml
index 1ac88a01b3..1ac88a01b3 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_notify_textbox.xml
+++ b/indra/newview/skins/default/xui/ru/panel_notify_textbox.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_online_status_toast.xml b/indra/newview/skins/default/xui/ru/panel_online_status_toast.xml
index fdc489f375..fdc489f375 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_online_status_toast.xml
+++ b/indra/newview/skins/default/xui/ru/panel_online_status_toast.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_outbox_inventory.xml b/indra/newview/skins/default/xui/ru/panel_outbox_inventory.xml
index 0095d48af9..0095d48af9 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_outbox_inventory.xml
+++ b/indra/newview/skins/default/xui/ru/panel_outbox_inventory.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_outfit_edit.xml b/indra/newview/skins/default/xui/ru/panel_outfit_edit.xml
index 91c03342a7..91c03342a7 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_outfit_edit.xml
+++ b/indra/newview/skins/default/xui/ru/panel_outfit_edit.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_outfits_inventory.xml b/indra/newview/skins/default/xui/ru/panel_outfits_inventory.xml
index 4d0e13fca2..4d0e13fca2 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_outfits_inventory.xml
+++ b/indra/newview/skins/default/xui/ru/panel_outfits_inventory.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_outfits_inventory_gear_default.xml b/indra/newview/skins/default/xui/ru/panel_outfits_inventory_gear_default.xml
index 96f4b4a893..96f4b4a893 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_outfits_inventory_gear_default.xml
+++ b/indra/newview/skins/default/xui/ru/panel_outfits_inventory_gear_default.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_outfits_list.xml b/indra/newview/skins/default/xui/ru/panel_outfits_list.xml
index 74551e4274..74551e4274 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_outfits_list.xml
+++ b/indra/newview/skins/default/xui/ru/panel_outfits_list.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_outfits_wearing.xml b/indra/newview/skins/default/xui/ru/panel_outfits_wearing.xml
index 7ed6bf35c0..7ed6bf35c0 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_outfits_wearing.xml
+++ b/indra/newview/skins/default/xui/ru/panel_outfits_wearing.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_people.xml b/indra/newview/skins/default/xui/ru/panel_people.xml
index 607921f2d6..9606f0aec1 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_people.xml
+++ b/indra/newview/skins/default/xui/ru/panel_people.xml
@@ -14,81 +14,56 @@
<string name="no_filtered_friends_msg">
Ðе нашли того, что вам нужно? ВоÑпользуйтеÑÑŒ [secondlife:///app/search/people/[SEARCH_TERM] поиÑком].
</string>
- <string name="people_filter_label" value="Фильтр Ð´Ð»Ñ Ð»ÑŽÐ´ÐµÐ¹"/>
- <string name="groups_filter_label" value="Фильтр Ð´Ð»Ñ Ð³Ñ€ÑƒÐ¿Ð¿"/>
<string name="no_filtered_groups_msg" value="Ðе нашли того, что вам нужно? ВоÑпользуйтеÑÑŒ [secondlife:///app/search/groups/[SEARCH_TERM] поиÑком]."/>
<string name="no_groups_msg" value="Ищете группу, чтобы приÑоединитьÑÑ Ðº ней? ВоÑпользуйтеÑÑŒ [secondlife:///app/search/groups поиÑком]."/>
<string name="MiniMapToolTipMsg" value="[REGION](Двойной щелчок открывает карту, shift+перетÑгивание – обзор)"/>
<string name="AltMiniMapToolTipMsg" value="[REGION](Двойной щелчок – телепортациÑ, shift+перетÑгивание – обзор)"/>
- <filter_editor label="Фильтр" name="filter_input"/>
<tab_container name="tabs">
<panel label="РЯДОМ" name="nearby_panel">
- <panel label="bottom_panel" name="bottom_panel">
- <menu_button name="nearby_view_sort_btn" tool_tip="Опции"/>
- <button name="add_friend_btn" tool_tip="Добавить выбранного Ð¶Ð¸Ñ‚ÐµÐ»Ñ Ð² ÑпиÑок друзей"/>
+ <panel label="bottom_panel" name="nearby_buttons_panel">
+ <filter_editor label="Фильтр Ð´Ð»Ñ Ð»ÑŽÐ´ÐµÐ¹" name="nearby_filter_input"/>
+ <button name="gear_btn" tool_tip="ДейÑÑ‚Ð²Ð¸Ñ Ñ Ð²Ñ‹Ð±Ñ€Ð°Ð½Ð½Ñ‹Ð¼ жителем"/>
+ <menu_button name="nearby_view_btn" tool_tip="Параметры проÑмотра/Ñортировки"/>
+ <button name="add_friend_btn" tool_tip="Предложить жителю дружбу"/>
+ <dnd_button name="nearby_del_btn" tool_tip="Удалить выбранного Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð¸Ð· друзей"/>
</panel>
</panel>
- <panel label="МОИ ДРУЗЬЯ" name="friends_panel">
+ <panel label="ДРУЗЬЯ" name="friends_panel">
+ <panel label="bottom_panel" name="friends_buttons_panel">
+ <filter_editor label="Фильтр Ð´Ð»Ñ Ð»ÑŽÐ´ÐµÐ¹" name="friends_filter_input"/>
+ <button name="gear_btn" tool_tip="ДейÑÑ‚Ð²Ð¸Ñ Ñ Ð²Ñ‹Ð±Ñ€Ð°Ð½Ð½Ñ‹Ð¼ жителем"/>
+ <menu_button name="friends_view_btn" tool_tip="Параметры проÑмотра/Ñортировки"/>
+ <button name="friends_add_btn" tool_tip="Предложить жителю дружбу"/>
+ <dnd_button name="friends_del_btn" tool_tip="Удалить выбранного Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð¸Ð· друзей"/>
+ </panel>
<accordion name="friends_accordion">
<accordion_tab name="tab_online" title="Онлайн"/>
<accordion_tab name="tab_all" title="Ð’Ñе"/>
</accordion>
- <panel label="bottom_panel" name="bottom_panel">
- <layout_stack name="bottom_panel">
- <layout_panel name="options_gear_btn_panel">
- <menu_button name="friends_viewsort_btn" tool_tip="Показать дополнительные параметры"/>
- </layout_panel>
- <layout_panel name="add_btn_panel">
- <button name="add_btn" tool_tip="Предложить жителю дружбу"/>
- </layout_panel>
- <layout_panel name="trash_btn_panel">
- <dnd_button name="del_btn" tool_tip="Удалить выбранного Ð¶Ð¸Ñ‚ÐµÐ»Ñ Ð¸Ð· ÑпиÑка друзей"/>
- </layout_panel>
- </layout_stack>
- </panel>
</panel>
- <panel label="МОИ ГРУППЫ" name="groups_panel">
- <panel label="bottom_panel" name="bottom_panel">
- <menu_button name="groups_viewsort_btn" tool_tip="Опции"/>
- <button name="plus_btn" tool_tip="ПриÑоединитьÑÑ Ðº группе/Ñоздать новую группу"/>
- <button name="activate_btn" tool_tip="Ðктивировать выбранную группу"/>
+ <panel label="ГРУППЫ" name="groups_panel">
+ <panel label="bottom_panel" name="groups_buttons_panel">
+ <filter_editor label="Фильтр Ð´Ð»Ñ Ð³Ñ€ÑƒÐ¿Ð¿" name="groups_filter_input"/>
+ <menu_button name="groups_gear_btn" tool_tip="ДейÑÑ‚Ð²Ð¸Ñ Ñ Ð²Ñ‹Ð±Ñ€Ð°Ð½Ð½Ð¾Ð¹ группой"/>
+ <menu_button name="groups_view_btn" tool_tip="Параметры проÑмотра/Ñортировки"/>
+ <menu_button name="plus_btn" tool_tip="ПриÑоединитьÑÑ Ðº группе/Ñоздать новую группу"/>
+ <dnd_button name="minus_btn" tool_tip="Покинуть выбранную группу"/>
</panel>
+ <text name="groupcount">
+ Ð’Ñ‹ входите в [COUNT] групп и можете приÑоединитьÑÑ ÐµÑ‰Ðµ к [REMAINING].
+ </text>
</panel>
<panel label="ÐЕДÐÐ’ÐИЕ" name="recent_panel">
- <panel label="bottom_panel" name="bottom_panel">
- <menu_button name="recent_viewsort_btn" tool_tip="Опции"/>
- <button name="add_friend_btn" tool_tip="Добавить выбранного Ð¶Ð¸Ñ‚ÐµÐ»Ñ Ð² ÑпиÑок друзей"/>
+ <panel label="bottom_panel" name="recent_buttons_panel">
+ <filter_editor label="Фильтр Ð´Ð»Ñ Ð»ÑŽÐ´ÐµÐ¹" name="recent_filter_input"/>
+ <button name="gear_btn" tool_tip="ДейÑÑ‚Ð²Ð¸Ñ Ñ Ð²Ñ‹Ð±Ñ€Ð°Ð½Ð½Ñ‹Ð¼ жителем"/>
+ <menu_button name="recent_view_btn" tool_tip="Параметры проÑмотра/Ñортировки"/>
+ <button name="add_friend_btn" tool_tip="Предложить жителю дружбу"/>
+ <dnd_button name="recent_del_btn" tool_tip="Удалить выбранного Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð¸Ð· друзей"/>
</panel>
</panel>
+ <panel label="БЛОКИРОВÐÐ" name="blocked_panel">
+ <panel label="Черный ÑпиÑок жителей и объектов" name="panel_block_list_sidetray"/>
+ </panel>
</tab_container>
- <panel name="button_bar">
- <layout_stack name="bottom_bar_ls">
- <layout_panel name="view_profile_btn_lp">
- <button label="Профиль" name="view_profile_btn" tool_tip="Показать изображение, группы и прочую информацию о жителе"/>
- </layout_panel>
- <layout_panel name="im_btn_lp">
- <button label="IM" name="im_btn" tool_tip="Ðачать ÑÐµÐ°Ð½Ñ IM"/>
- </layout_panel>
- <layout_panel name="call_btn_lp">
- <button label="Звонок" name="call_btn" tool_tip="Позвонить Ñтому жителю"/>
- </layout_panel>
- <layout_panel name="share_btn_lp">
- <button label="ПоделитьÑÑ" name="share_btn" tool_tip="ПоделитьÑÑ Ð¾Ð±ÑŠÐµÐºÑ‚Ð¾Ð¼ из инвентарÑ"/>
- </layout_panel>
- <layout_panel name="teleport_btn_lp">
- <button label="ТелепортациÑ" name="teleport_btn" tool_tip="Предложить телепортацию"/>
- </layout_panel>
- </layout_stack>
- <layout_stack name="bottom_bar_ls1">
- <layout_panel name="group_info_btn_lp">
- <button label="Профиль группы" name="group_info_btn" tool_tip="Показать информацию о группе"/>
- </layout_panel>
- <layout_panel name="chat_btn_lp">
- <button label="Групповой чат" name="chat_btn" tool_tip="Открыть ÑÐµÐ°Ð½Ñ Ñ‡Ð°Ñ‚Ð°"/>
- </layout_panel>
- <layout_panel name="group_call_btn_lp">
- <button label="Звонок группе" name="group_call_btn" tool_tip="Позвонить Ñтой группе"/>
- </layout_panel>
- </layout_stack>
- </panel>
</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_pick_info.xml b/indra/newview/skins/default/xui/ru/panel_pick_info.xml
index 373cf211fb..373cf211fb 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_pick_info.xml
+++ b/indra/newview/skins/default/xui/ru/panel_pick_info.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_picks.xml b/indra/newview/skins/default/xui/ru/panel_picks.xml
index d6770e0eeb..d6770e0eeb 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_picks.xml
+++ b/indra/newview/skins/default/xui/ru/panel_picks.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_place_profile.xml b/indra/newview/skins/default/xui/ru/panel_place_profile.xml
index b486b918ed..b486b918ed 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_place_profile.xml
+++ b/indra/newview/skins/default/xui/ru/panel_place_profile.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_places.xml b/indra/newview/skins/default/xui/ru/panel_places.xml
index 54837d3c0b..54837d3c0b 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_places.xml
+++ b/indra/newview/skins/default/xui/ru/panel_places.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_postcard_message.xml b/indra/newview/skins/default/xui/ru/panel_postcard_message.xml
index 70587d8090..70587d8090 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_postcard_message.xml
+++ b/indra/newview/skins/default/xui/ru/panel_postcard_message.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_postcard_settings.xml b/indra/newview/skins/default/xui/ru/panel_postcard_settings.xml
index dc9d59008f..dc9d59008f 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_postcard_settings.xml
+++ b/indra/newview/skins/default/xui/ru/panel_postcard_settings.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_preferences_advanced.xml b/indra/newview/skins/default/xui/ru/panel_preferences_advanced.xml
index 7d8ee96924..7d8ee96924 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_preferences_advanced.xml
+++ b/indra/newview/skins/default/xui/ru/panel_preferences_advanced.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_preferences_alerts.xml b/indra/newview/skins/default/xui/ru/panel_preferences_alerts.xml
index 9d7ae546fd..9d7ae546fd 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_preferences_alerts.xml
+++ b/indra/newview/skins/default/xui/ru/panel_preferences_alerts.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_preferences_chat.xml b/indra/newview/skins/default/xui/ru/panel_preferences_chat.xml
index a9d5569c7f..914426c91e 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/ru/panel_preferences_chat.xml
@@ -1,33 +1,99 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel label="ТекÑтовый чат" name="chat">
- <text name="font_size">
- Размер шрифта:
- </text>
- <radio_group name="chat_font_size">
- <radio_item label="Мелкий" name="radio" value="0"/>
- <radio_item label="Средний" name="radio2" value="1"/>
- <radio_item label="Крупный" name="radio3" value="2"/>
- </radio_group>
- <check_box initial_value="иÑтина" label="ВоÑпроизводить анимацию ввода текÑта при общении" name="play_typing_animation"/>
- <check_box label="ОтправлÑÑ‚ÑŒ мне ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð¿Ð¾ почте, когда Ð¼ÐµÐ½Ñ Ð½ÐµÑ‚ в Ñети" name="send_im_to_email"/>
- <check_box label="ВеÑти журнал текÑтового IM и чата" name="plain_text_chat_history"/>
- <check_box label="Чат в пузырьках" name="bubble_text_chat"/>
- <text name="show_ims_in_label">
- Показывать ÑообщениÑ:
- </text>
- <text name="requires_restart_label">
- (требуетÑÑ Ð¿ÐµÑ€ÐµÐ·Ð°Ð¿ÑƒÑк)
- </text>
- <radio_group name="chat_window" tool_tip="Показывать IM-ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð² отдельных окнах или же в одном окне Ñ Ð½ÐµÑколькими вкладками (требуетÑÑ Ð¿ÐµÑ€ÐµÐ·Ð°Ð¿ÑƒÑк)">
- <radio_item label="В отдельных окнах" name="radio" value="0"/>
- <radio_item label="Ðа вкладках" name="radio2" value="1"/>
- </radio_group>
- <text name="disable_toast_label">
- Включить вÑплывающие ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ñ Ð½Ð¾Ð²Ñ‹Ð¼Ð¸ репликами в чате:
- </text>
- <check_box label="Групповой чат" name="EnableGroupChatPopups" tool_tip="Отображать вÑплывающие ÑƒÐ²ÐµÐ´Ð¾Ð¼Ð»ÐµÐ½Ð¸Ñ Ð¿Ñ€Ð¸ поÑвлении Ñообщений в групповом чате"/>
- <check_box label="ТекÑтовые чаты" name="EnableIMChatPopups" tool_tip="Отображать вÑплывающие ÑƒÐ²ÐµÐ´Ð¾Ð¼Ð»ÐµÐ½Ð¸Ñ Ð¿Ñ€Ð¸ получении IM-Ñообщений"/>
- <spinner label="Ð’Ñ€ÐµÐ¼Ñ Ð¾Ñ‚Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ð²Ñплывающих реплик:" name="nearby_toasts_lifetime"/>
- <spinner label="Ð’Ñ€ÐµÐ¼Ñ Ð·Ð°Ñ‚ÑƒÑ…Ð°Ð½Ð¸Ñ Ð²Ñплывающих реплик:" name="nearby_toasts_fadingtime"/>
- <button label="ÐаÑтройки перевода чата" name="ok_btn"/>
+ <panel name="general_chat_settings">
+ <check_box initial_value="true" label="ВоÑпроизводить анимацию ввода текÑта при общении" name="play_typing_animation"/>
+ <check_box label="ОтправлÑÑ‚ÑŒ мне ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð¿Ð¾ почте, когда Ð¼ÐµÐ½Ñ Ð½ÐµÑ‚ в Ñети" name="send_im_to_email"/>
+ <check_box label="Только Ð´Ñ€ÑƒÐ·ÑŒÑ Ð¸ группы могут звонить мне и отправлÑÑ‚ÑŒ IM" name="voice_call_friends_only_check"/>
+ <text name="font_size">
+ Размер шрифта:
+ </text>
+ <combo_box name="chat_font_size">
+ <item label="Мелкий" name="Small" value="0"/>
+ <item label="Средний" name="Medium" value="1"/>
+ <item label="Крупный" name="Large" value="2"/>
+ </combo_box>
+ <check_box label="Чат в пузырьках" name="bubble_text_chat"/>
+ </panel>
+ <panel name="im_notification_settings">
+ <text name="friend_ims">
+ IM друзей:
+ </text>
+ <combo_box name="FriendIMOptions">
+ <item label="Открыть окно разговоров" name="OpenConversationsWindow" value="openconversations"/>
+ <item label="Сообщение во вÑплывающем окне" name="PopUpMessage" value="вÑплывание"/>
+ <item label="Мигание кнопки на панели инÑтрументов" name="FlashToolbarButton" value="мигание"/>
+ <item label="Без дейÑтвиÑ" name="NoAction" value="noaction"/>
+ </combo_box>
+ <check_box label="Звук" name="play_sound_friend_im"/>
+ <text name="non_friend_ims">
+ IM чужих:
+ </text>
+ <combo_box name="NonFriendIMOptions">
+ <item label="Открыть окно разговоров" name="OpenConversationsWindow" value="openconversations"/>
+ <item label="Сообщение во вÑплывающем окне" name="PopUpMessage" value="вÑплывание"/>
+ <item label="Мигание кнопки на панели инÑтрументов" name="FlashToolbarButton" value="мигание"/>
+ <item label="Без дейÑтвиÑ" name="NoAction" value="noaction"/>
+ </combo_box>
+ <check_box label="Звук" name="play_sound_non_friend_im"/>
+ <text name="conference_ims">
+ IM конференции:
+ </text>
+ <combo_box name="ConferenceIMOptions">
+ <item label="Открыть окно разговоров" name="OpenConversationsWindow" value="openconversations"/>
+ <item label="Сообщение во вÑплывающем окне" name="PopUpMessage" value="вÑплывание"/>
+ <item label="Мигание кнопки на панели инÑтрументов" name="FlashToolbarButton" value="мигание"/>
+ <item label="Без дейÑтвиÑ" name="NoAction" value="noaction"/>
+ </combo_box>
+ <check_box label="Звук" name="play_sound_conference_im"/>
+ <text name="group_chat">
+ Групповой чат:
+ </text>
+ <combo_box name="GroupChatOptions">
+ <item label="Открыть окно разговоров" name="OpenConversationsWindow" value="openconversations"/>
+ <item label="Сообщение во вÑплывающем окне" name="PopUpMessage" value="вÑплывание"/>
+ <item label="Мигание кнопки на панели инÑтрументов" name="FlashToolbarButton" value="мигание"/>
+ <item label="Без дейÑтвиÑ" name="NoAction" value="noaction"/>
+ </combo_box>
+ <check_box label="Звук" name="play_sound_group_chat_im"/>
+ <text name="nearby_chat">
+ Локальный чат:
+ </text>
+ <combo_box name="NearbyChatOptions">
+ <item label="Открыть окно разговоров" name="OpenConversationsWindow" value="openconversations"/>
+ <item label="Сообщение во вÑплывающем окне" name="PopUpMessage" value="вÑплывание"/>
+ <item label="Мигание кнопки на панели инÑтрументов" name="FlashToolBarButton" value="мигание"/>
+ <item label="Без дейÑтвиÑ" name="NoAction" value="noaction"/>
+ </combo_box>
+ <check_box label="Звук" name="play_sound_nearby_chat_im"/>
+ <text name="object_ims">
+ IM объектов:
+ </text>
+ <combo_box name="ObjectIMOptions">
+ <item label="Открыть окно разговоров" name="OpenConversationsWindow" value="openconversations"/>
+ <item label="Сообщение во вÑплывающем окне" name="PopUpMessage" value="вÑплывание"/>
+ <item label="Мигание кнопки на панели инÑтрументов" name="FlashToolBarButton" value="мигание"/>
+ <item label="Без дейÑтвиÑ" name="NoAction" value="noaction"/>
+ </combo_box>
+ <check_box label="Звук" name="play_sound_object_im"/>
+ <text name="notifications_alert">
+ Ð”Ð»Ñ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð½Ð¾Ð³Ð¾ Ð¾Ñ‚ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ð²Ñех уведомлений вызовите меню «Общение &gt; Ðе беÑпокоить».
+ </text>
+ </panel>
+ <panel name="play_sound_settings">
+ <text name="play_sound">
+ Звук:
+ </text>
+ <check_box label="Ðовый разговор" name="new_conversation"/>
+ <check_box label="ВходÑщий голоÑовой вызов" name="incoming_voice_call"/>
+ <check_box label="Предложение телепортации" name="teleport_offer"/>
+ <check_box label="Предложение инвентарÑ" name="inventory_offer"/>
+ </panel>
+ <panel name="log_settings">
+ <button label="ОчиÑтить журнал..." name="clear_log"/>
+ <button label="Удалить запиÑи..." name="delete_transcripts"/>
+ <button label="Обзор..." label_selected="Обзор" name="log_path_button"/>
+ </panel>
+ <button label="Перевод..." name="ok_btn"/>
+ <button label="Ðвтозамена..." name="autoreplace_showgui"/>
+ <button label="Проверка правопиÑаниÑ..." name="spellcheck_showgui"/>
</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_preferences_colors.xml b/indra/newview/skins/default/xui/ru/panel_preferences_colors.xml
index 48c34fcbb2..48c34fcbb2 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_preferences_colors.xml
+++ b/indra/newview/skins/default/xui/ru/panel_preferences_colors.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_preferences_general.xml b/indra/newview/skins/default/xui/ru/panel_preferences_general.xml
index d1bfedf2d8..62617caed3 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_preferences_general.xml
+++ b/indra/newview/skins/default/xui/ru/panel_preferences_general.xml
@@ -36,7 +36,7 @@
<combo_box.item label="Мое поÑледнее меÑто" name="MyLastLocation"/>
<combo_box.item label="Мой дом" name="MyHome"/>
</combo_box>
- <check_box initial_value="иÑтина" label="Показывать на Ñкране входа" name="show_location_checkbox"/>
+ <check_box initial_value="true" label="Показывать на Ñкране входа" name="show_location_checkbox"/>
<text name="name_tags_textbox">
Теги имен:
</text>
@@ -68,9 +68,9 @@
<combo_box.item label="никогда" name="item4"/>
</combo_box>
<text name="text_box3">
- Ответ в режиме «ЗанÑт»:
+ Ответ в режиме «Ðе беÑпокоить»:
</text>
- <text_editor name="busy_response">
+ <text_editor name="do_not_disturb_response">
log_in_to_change
</text_editor>
</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/ru/panel_preferences_graphics1.xml
index a7e826f5fc..c93955fcdc 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_preferences_graphics1.xml
+++ b/indra/newview/skins/default/xui/ru/panel_preferences_graphics1.xml
@@ -25,14 +25,14 @@
<text name="ShadersText">
Шейдеры:
</text>
- <check_box initial_value="иÑтина" label="ПрозрачноÑÑ‚ÑŒ воды" name="TransparentWater"/>
- <check_box initial_value="иÑтина" label="РельефноÑÑ‚ÑŒ и ÑиÑние" name="BumpShiny"/>
- <check_box initial_value="иÑтина" label="Локальный Ñвет" name="LocalLights"/>
- <check_box initial_value="иÑтина" label="Базовые шейдеры" name="BasicShaders" tool_tip="Отключение Ñтого параметра может предотвратить завиÑание некоторых видеокарт"/>
- <check_box initial_value="иÑтина" label="ÐтмоÑферные шейдеры" name="WindLightUseAtmosShaders"/>
- <check_box initial_value="иÑтина" label="ОÑвещение и тени" name="UseLightShaders"/>
- <check_box initial_value="иÑтина" label="Объемный Ñвет" name="UseSSAO"/>
- <check_box initial_value="иÑтина" label="Глубина полÑ" name="UseDoF"/>
+ <check_box initial_value="true" label="ПрозрачноÑÑ‚ÑŒ воды" name="TransparentWater"/>
+ <check_box initial_value="true" label="РельефноÑÑ‚ÑŒ и ÑиÑние" name="BumpShiny"/>
+ <check_box initial_value="true" label="Локальный Ñвет" name="LocalLights"/>
+ <check_box initial_value="true" label="Базовые шейдеры" name="BasicShaders" tool_tip="Отключение Ñтого параметра может предотвратить завиÑание некоторых видеокарт"/>
+ <check_box initial_value="true" label="ÐтмоÑферные шейдеры" name="WindLightUseAtmosShaders"/>
+ <check_box initial_value="true" label="РаÑÑˆÐ¸Ñ€ÐµÐ½Ð½Ð°Ñ Ð¼Ð¾Ð´ÐµÐ»ÑŒ оÑвещениÑ" name="UseLightShaders"/>
+ <check_box initial_value="true" label="Объемный Ñвет" name="UseSSAO"/>
+ <check_box initial_value="true" label="Глубина полÑ" name="UseDoF"/>
<text name="shadows_label">
Тени:
</text>
@@ -95,9 +95,9 @@
<text name="AvatarRenderingText">
ОтриÑовка аватара:
</text>
- <check_box initial_value="иÑтина" label="ПлоÑкие аватары" name="AvatarImpostors"/>
- <check_box initial_value="иÑтина" label="ÐÐ¿Ð¿Ð°Ñ€Ð°Ñ‚Ð½Ð°Ñ Ð¾Ñ‚Ñ€Ð¸Ñовка" name="AvatarVertexProgram"/>
- <check_box initial_value="иÑтина" label="Одежда аватара" name="AvatarCloth"/>
+ <check_box initial_value="true" label="ПлоÑкие аватары" name="AvatarImpostors"/>
+ <check_box initial_value="true" label="ÐÐ¿Ð¿Ð°Ñ€Ð°Ñ‚Ð½Ð°Ñ Ð¾Ñ‚Ñ€Ð¸Ñовка" name="AvatarVertexProgram"/>
+ <check_box initial_value="true" label="Одежда аватара" name="AvatarCloth"/>
<text name="TerrainDetailText">
Ландшафт:
</text>
diff --git a/indra/newview/skins/default/xui/ru/panel_preferences_move.xml b/indra/newview/skins/default/xui/ru/panel_preferences_move.xml
index a6e9b00f2a..a6e9b00f2a 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_preferences_move.xml
+++ b/indra/newview/skins/default/xui/ru/panel_preferences_move.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_preferences_privacy.xml b/indra/newview/skins/default/xui/ru/panel_preferences_privacy.xml
index 20bb839eed..20bb839eed 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_preferences_privacy.xml
+++ b/indra/newview/skins/default/xui/ru/panel_preferences_privacy.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_preferences_setup.xml b/indra/newview/skins/default/xui/ru/panel_preferences_setup.xml
index 8e7fc71f0d..1741397a84 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_preferences_setup.xml
+++ b/indra/newview/skins/default/xui/ru/panel_preferences_setup.xml
@@ -18,10 +18,10 @@
<radio_item label="ИÑпользовать мой браузер (IE, Firefox, Safari)" name="external" tool_tip="Будет иÑпользоватьÑÑ Ð±Ñ€Ð°ÑƒÐ·ÐµÑ€, заданный в ÑиÑтеме по умолчанию. Ðе рекомендуетÑÑ, еÑли [APP_NAME] работает в полноÑкранном режиме." value="true"/>
<radio_item label="ИÑпользовать вÑтроенный браузер" name="internal" tool_tip="Ð”Ð»Ñ Ð¿Ñ€Ð¾Ñмотра Ñправки, ÑÑылок на веб-Ñтраницы и Ñ‚. д. будет иÑпользоватьÑÑ Ð²Ñтроенный браузер. Этот браузер открываетÑÑ ÐºÐ°Ðº новое окно в [APP_NAME]." value=""/>
</radio_group>
- <check_box initial_value="иÑтина" label="Разрешить плагины" name="browser_plugins_enabled"/>
- <check_box initial_value="иÑтина" label="Принимать файлы cookie" name="cookies_enabled"/>
- <check_box initial_value="иÑтина" label="Разрешить Javascript" name="browser_javascript_enabled"/>
- <check_box initial_value="ложь" label="Разрешить вÑплывающие окна" name="media_popup_enabled"/>
+ <check_box initial_value="true" label="Разрешить плагины" name="browser_plugins_enabled"/>
+ <check_box initial_value="true" label="Принимать файлы cookie" name="cookies_enabled"/>
+ <check_box initial_value="true" label="Разрешить Javascript" name="browser_javascript_enabled"/>
+ <check_box initial_value="false" label="Разрешить вÑплывающие окна" name="media_popup_enabled"/>
<text name="Software updates:">
ÐžÐ±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ ÐŸÐž:
</text>
@@ -29,6 +29,7 @@
<combo_box.item label="УÑтанавливать автоматичеÑки" name="Install_automatically"/>
<combo_box.item label="Загружать и уÑтанавливать Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð²Ñ€ÑƒÑ‡Ð½ÑƒÑŽ" name="Install_manual"/>
</combo_box>
+ <check_box label="УÑтанавливать бета-верÑии" name="update_willing_to_test"/>
<text name="Proxy Settings:">
ÐаÑтройки прокÑи-Ñервера:
</text>
diff --git a/indra/newview/skins/default/xui/ru/panel_preferences_sound.xml b/indra/newview/skins/default/xui/ru/panel_preferences_sound.xml
index bf673750d2..44f270527c 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_preferences_sound.xml
+++ b/indra/newview/skins/default/xui/ru/panel_preferences_sound.xml
@@ -4,7 +4,7 @@
Ñреднюю кнопку мыши
</panel.string>
<slider label="ÐžÐ±Ñ‰Ð°Ñ Ð³Ñ€Ð¾Ð¼ÐºÐ¾ÑÑ‚ÑŒ" name="System Volume"/>
- <check_box initial_value="иÑтина" name="mute_when_minimized"/>
+ <check_box initial_value="true" name="mute_when_minimized"/>
<text name="mute_chb_label">
Заглушать, когда Ñвернуто
</text>
@@ -17,9 +17,9 @@
<check_box label="Включено" name="enable_media"/>
<slider label="ГолоÑовой чат" name="Voice Volume"/>
<check_box label="Включено" name="enable_voice_check"/>
- <check_box label="Разрешить автовоÑпроизведение медиа" name="media_auto_play_btn" tool_tip="УÑтановка флажка позволит вам автоматичеÑки воÑпроизводить медиа" value="иÑтина"/>
- <check_box label="ВоÑпроизводить медиа, приÑоединенные к другому аватару" name="media_show_on_others_btn" tool_tip="СнÑтие флажка Ñкроет медиа, приÑоединенные к другому аватару" value="иÑтина"/>
- <check_box label="Сопровождать жеÑÑ‚Ñ‹ звуками" name="gesture_audio_play_btn" tool_tip="УÑтановите флажок, чтобы Ñлышать звуки при жеÑтах" value="иÑтина"/>
+ <check_box label="Разрешить автовоÑпроизведение медиа" name="media_auto_play_btn" tool_tip="УÑтановка флажка позволит вам автоматичеÑки воÑпроизводить медиа" value="true"/>
+ <check_box label="ВоÑпроизводить медиа, приÑоединенные к другому аватару" name="media_show_on_others_btn" tool_tip="СнÑтие флажка Ñкроет медиа, приÑоединенные к другому аватару" value="true"/>
+ <check_box label="Сопровождать жеÑÑ‚Ñ‹ звуками" name="gesture_audio_play_btn" tool_tip="УÑтановите флажок, чтобы Ñлышать звуки при жеÑтах" value="true"/>
<text name="voice_chat_settings">
ÐаÑтройки голоÑового чата
</text>
diff --git a/indra/newview/skins/default/xui/ru/panel_prim_media_controls.xml b/indra/newview/skins/default/xui/ru/panel_prim_media_controls.xml
index 76bb6518e9..76bb6518e9 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_prim_media_controls.xml
+++ b/indra/newview/skins/default/xui/ru/panel_prim_media_controls.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_region_covenant.xml b/indra/newview/skins/default/xui/ru/panel_region_covenant.xml
index 706a38f110..706a38f110 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_region_covenant.xml
+++ b/indra/newview/skins/default/xui/ru/panel_region_covenant.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_region_debug.xml b/indra/newview/skins/default/xui/ru/panel_region_debug.xml
index c21d2d7051..4be1e781fa 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_region_debug.xml
+++ b/indra/newview/skins/default/xui/ru/panel_region_debug.xml
@@ -30,5 +30,5 @@
<button label="Самые активные учаÑтники Ñтолкновений..." name="top_colliders_btn" tool_tip="СпиÑок объектов, Ð´Ð»Ñ ÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ñ… ÑÑ‚Ð¾Ð»ÐºÐ½Ð¾Ð²ÐµÐ½Ð¸Ñ Ð½Ð°Ð¸Ð±Ð¾Ð»ÐµÐµ вероÑтны"/>
<button label="СпиÑок лучших Ñкриптов..." name="top_scripts_btn" tool_tip="Объекты, в которых Ñкрипты выполнÑÑŽÑ‚ÑÑ Ð´Ð¾Ð»ÑŒÑˆÐµ вÑего"/>
<button label="Перезагрузить регион" name="restart_btn" tool_tip="ОтÑчитать 2 минуты и перезагрузить регион"/>
- <button label="Отложить перезагрузку" name="cancel_restart_btn" tool_tip="Отложить перезагрузку региона на чаÑ"/>
+ <button label="Отменить перезапуÑк" name="cancel_restart_btn" tool_tip="Отменить перезапуÑк региона"/>
</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_region_environment.xml b/indra/newview/skins/default/xui/ru/panel_region_environment.xml
index 85be8f63bd..85be8f63bd 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_region_environment.xml
+++ b/indra/newview/skins/default/xui/ru/panel_region_environment.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_region_estate.xml b/indra/newview/skins/default/xui/ru/panel_region_estate.xml
index 93b21704bc..bcfb974fcb 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_region_estate.xml
+++ b/indra/newview/skins/default/xui/ru/panel_region_estate.xml
@@ -23,7 +23,7 @@
Разрешить доÑтуп только таким жителÑм:
</text>
<check_box label="ЗарегиÑтрирована Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾Ð± оплате" name="limit_payment" tool_tip="Ð”Ð»Ñ Ð´Ð¾Ñтупа к Ñтому землевладению у Ð¶Ð¸Ñ‚ÐµÐ»Ñ Ð´Ð¾Ð»Ð¶Ð½Ð° быть зарегиÑтрирована Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾Ð± оплате. Более Ð¿Ð¾Ð´Ñ€Ð¾Ð±Ð½Ð°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð½Ð°Ñ…Ð¾Ð´Ð¸Ñ‚ÑÑ Ð·Ð´ÐµÑÑŒ: [SUPPORT_SITE]."/>
- <check_box label="Подтвержден возраÑÑ‚" name="limit_age_verified" tool_tip="Ð”Ð»Ñ Ð´Ð¾Ñтупа к Ñтому землевладению житель должен подтвердить Ñвой возраÑÑ‚. Более Ð¿Ð¾Ð´Ñ€Ð¾Ð±Ð½Ð°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð½Ð°Ñ…Ð¾Ð´Ð¸Ñ‚ÑÑ Ð·Ð´ÐµÑÑŒ: [SUPPORT_SITE]."/>
+ <check_box label="18 лет и Ñтарше" name="limit_age_verified" tool_tip="ДоÑтуп к Ñтому землевладению имеют только жители 18 лет и Ñтарше. Более Ð¿Ð¾Ð´Ñ€Ð¾Ð±Ð½Ð°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð½Ð°Ñ…Ð¾Ð´Ð¸Ñ‚ÑÑ Ð·Ð´ÐµÑÑŒ: [SUPPORT_SITE]."/>
<check_box label="Разрешить голоÑовое общение" name="voice_chat_check"/>
<check_box label="Разрешить прÑмой телепорт" name="allow_direct_teleport"/>
<button label="Применить" name="apply_btn"/>
diff --git a/indra/newview/skins/default/xui/ru/panel_region_general.xml b/indra/newview/skins/default/xui/ru/panel_region_general.xml
index 8559be6c9e..8559be6c9e 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_region_general.xml
+++ b/indra/newview/skins/default/xui/ru/panel_region_general.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_region_terrain.xml b/indra/newview/skins/default/xui/ru/panel_region_terrain.xml
index af25565226..af25565226 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_region_terrain.xml
+++ b/indra/newview/skins/default/xui/ru/panel_region_terrain.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_region_texture.xml b/indra/newview/skins/default/xui/ru/panel_region_texture.xml
deleted file mode 100644
index c4b35a536d..0000000000
--- a/indra/newview/skins/default/xui/ru/panel_region_texture.xml
+++ /dev/null
@@ -1,54 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel label="ТекÑтуры земли" name="Textures">
- <text name="region_text_lbl">
- Регион:
- </text>
- <text name="region_text">
- неизвеÑтен
- </text>
- <text name="detail_texture_text">
- ТекÑтуры ландшафта (требованиÑ: 512x512, 24-битные TGA-файлы)
- </text>
- <text name="height_text_lbl">
- 1 (низ)
- </text>
- <text name="height_text_lbl2">
- 2
- </text>
- <text name="height_text_lbl3">
- 3
- </text>
- <text name="height_text_lbl4">
- 4 (верх)
- </text>
- <text name="height_text_lbl5">
- Диапазон выÑот текÑтур
- </text>
- <text name="height_text_lbl6">
- Северо-запад
- </text>
- <text name="height_text_lbl7">
- Северо-воÑток
- </text>
- <spinner label="Ðиз" name="height_start_spin_1"/>
- <spinner label="Ðиз" name="height_start_spin_3"/>
- <spinner label="Верх" name="height_range_spin_1"/>
- <spinner label="Верх" name="height_range_spin_3"/>
- <text name="height_text_lbl8">
- Юго-запад
- </text>
- <text name="height_text_lbl9">
- Юго-воÑток
- </text>
- <spinner label="Ðиз" name="height_start_spin_0"/>
- <spinner label="Ðиз" name="height_start_spin_2"/>
- <spinner label="Верх" name="height_range_spin_0"/>
- <spinner label="Верх" name="height_range_spin_2"/>
- <text name="height_text_lbl10">
- Эти Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð¾Ñ‚Ð¾Ð±Ñ€Ð°Ð¶Ð°ÑŽÑ‚ диапазон Ð¿ÐµÑ€ÐµÐºÑ€Ñ‹Ñ‚Ð¸Ñ Ð²Ñ‹ÑˆÐµÑƒÐºÐ°Ð·Ð°Ð½Ð½Ñ‹Ñ… текÑтур.
- </text>
- <text name="height_text_lbl11">
- ИзмерÑетÑÑ Ð² метрах, значение «Ðиз» – Ñто ÐœÐКСИМÐЛЬÐÐЯ выÑота текÑтуры â„–1, значение «Верх» – Ñто МИÐИМÐЛЬÐÐЯ выÑота текÑтуры â„–4.
- </text>
- <button label="Применить" name="apply_btn"/>
-</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_script_ed.xml b/indra/newview/skins/default/xui/ru/panel_script_ed.xml
index 05ccaeb54b..a9e5d9ef10 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_script_ed.xml
+++ b/indra/newview/skins/default/xui/ru/panel_script_ed.xml
@@ -34,6 +34,7 @@
<menu_item_call label="Выделить вÑе" name="Select All"/>
<menu_item_call label="СнÑÑ‚ÑŒ выделение" name="Deselect"/>
<menu_item_call label="ПоиÑк и замена..." name="Search / Replace..."/>
+ <menu_item_call label="Перейти на Ñтроку..." name="Go to line..."/>
</menu>
<menu label="Справка" name="Help">
<menu_item_call label="Справка..." name="Help..."/>
diff --git a/indra/newview/skins/default/xui/ru/panel_script_limits_my_avatar.xml b/indra/newview/skins/default/xui/ru/panel_script_limits_my_avatar.xml
index a06c465a2b..a06c465a2b 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_script_limits_my_avatar.xml
+++ b/indra/newview/skins/default/xui/ru/panel_script_limits_my_avatar.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_script_limits_region_memory.xml b/indra/newview/skins/default/xui/ru/panel_script_limits_region_memory.xml
index 189e21fd2f..189e21fd2f 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_script_limits_region_memory.xml
+++ b/indra/newview/skins/default/xui/ru/panel_script_limits_region_memory.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_script_question_toast.xml b/indra/newview/skins/default/xui/ru/panel_script_question_toast.xml
new file mode 100755
index 0000000000..a2d0237da0
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/panel_script_question_toast.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<panel label="script_question_panel" name="panel_script_question_toast">
+ <panel label="buttons_panel" name="buttons_panel"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_scrolling_param.xml b/indra/newview/skins/default/xui/ru/panel_scrolling_param.xml
index c25f92cb8d..c25f92cb8d 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_scrolling_param.xml
+++ b/indra/newview/skins/default/xui/ru/panel_scrolling_param.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_scrolling_param_base.xml b/indra/newview/skins/default/xui/ru/panel_scrolling_param_base.xml
index fa659040ea..fa659040ea 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_scrolling_param_base.xml
+++ b/indra/newview/skins/default/xui/ru/panel_scrolling_param_base.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_side_tray.xml b/indra/newview/skins/default/xui/ru/panel_side_tray.xml
deleted file mode 100644
index 10c5775291..0000000000
--- a/indra/newview/skins/default/xui/ru/panel_side_tray.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<!-- Side tray cannot show background because it is always
- partially on screen to hold tab buttons. -->
-<side_tray name="sidebar">
- <sidetray_tab description="Открыть/закрыть боковую панель" name="sidebar_openclose" tab_title="Открыть/закрыть боковую панель"/>
- <sidetray_tab description="Дом." name="sidebar_home" tab_title="Дом">
- <panel label="дом" name="panel_home"/>
- </sidetray_tab>
- <sidetray_tab description="Изменение Ñвоего Ð¿Ñ€Ð¾Ñ„Ð¸Ð»Ñ Ð¸ подборки." name="sidebar_me" tab_title="Мой профиль">
- <panel_container name="panel_container">
- <panel label="Я" name="panel_me"/>
- </panel_container>
- </sidetray_tab>
- <sidetray_tab description="ПоиÑк друзей, контактов и находÑщихÑÑ Ð¿Ð¾Ð±Ð»Ð¸Ð·Ð¾Ñти людей." name="sidebar_people" tab_title="Люди">
- <panel_container name="panel_container">
- <panel label="Профиль группы" name="panel_group_info_sidetray"/>
- <panel label="Черный ÑпиÑок жителей и объектов" name="panel_block_list_sidetray"/>
- </panel_container>
- </sidetray_tab>
- <sidetray_tab description="ПоиÑк меÑÑ‚, которые можно было бы поÑетить или которые вы уже поÑещали ранее." label="МеÑта" name="sidebar_places" tab_title="МеÑта">
- <panel label="МеÑта" name="panel_places"/>
- </sidetray_tab>
- <sidetray_tab description="ПроÑмотрите Ñвой инвентарь." name="sidebar_inventory" tab_title="Мой инвентарь">
- <panel label="Изменить инвентарь" name="sidepanel_inventory"/>
- </sidetray_tab>
- <sidetray_tab description="Изменение внешнего вида и текущего образа." name="sidebar_appearance" tab_title="Мой внешний вид">
- <panel label="Изменить внешний вид" name="sidepanel_appearance"/>
- </sidetray_tab>
-</side_tray>
diff --git a/indra/newview/skins/default/xui/ru/panel_side_tray_tab_caption.xml b/indra/newview/skins/default/xui/ru/panel_side_tray_tab_caption.xml
index 1a260dc31f..1a260dc31f 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_side_tray_tab_caption.xml
+++ b/indra/newview/skins/default/xui/ru/panel_side_tray_tab_caption.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_snapshot_inventory.xml b/indra/newview/skins/default/xui/ru/panel_snapshot_inventory.xml
index 53a150c9f9..53a150c9f9 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_snapshot_inventory.xml
+++ b/indra/newview/skins/default/xui/ru/panel_snapshot_inventory.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_snapshot_local.xml b/indra/newview/skins/default/xui/ru/panel_snapshot_local.xml
index 446b9bb2fd..446b9bb2fd 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_snapshot_local.xml
+++ b/indra/newview/skins/default/xui/ru/panel_snapshot_local.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_snapshot_options.xml b/indra/newview/skins/default/xui/ru/panel_snapshot_options.xml
index 250a76cd21..250a76cd21 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_snapshot_options.xml
+++ b/indra/newview/skins/default/xui/ru/panel_snapshot_options.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_snapshot_postcard.xml b/indra/newview/skins/default/xui/ru/panel_snapshot_postcard.xml
index 47f4caf8e3..47f4caf8e3 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_snapshot_postcard.xml
+++ b/indra/newview/skins/default/xui/ru/panel_snapshot_postcard.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_snapshot_profile.xml b/indra/newview/skins/default/xui/ru/panel_snapshot_profile.xml
index 79a9ef58d0..79a9ef58d0 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_snapshot_profile.xml
+++ b/indra/newview/skins/default/xui/ru/panel_snapshot_profile.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_sound_devices.xml b/indra/newview/skins/default/xui/ru/panel_sound_devices.xml
index 98dab288a3..98dab288a3 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_sound_devices.xml
+++ b/indra/newview/skins/default/xui/ru/panel_sound_devices.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_stand_stop_flying.xml b/indra/newview/skins/default/xui/ru/panel_stand_stop_flying.xml
index 81a2175fc3..81a2175fc3 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_stand_stop_flying.xml
+++ b/indra/newview/skins/default/xui/ru/panel_stand_stop_flying.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_status_bar.xml b/indra/newview/skins/default/xui/ru/panel_status_bar.xml
index 9c84ff1fd8..9c84ff1fd8 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_status_bar.xml
+++ b/indra/newview/skins/default/xui/ru/panel_status_bar.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_teleport_history.xml b/indra/newview/skins/default/xui/ru/panel_teleport_history.xml
index c457bc2269..c457bc2269 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_teleport_history.xml
+++ b/indra/newview/skins/default/xui/ru/panel_teleport_history.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_teleport_history_item.xml b/indra/newview/skins/default/xui/ru/panel_teleport_history_item.xml
index 90fb720068..90fb720068 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_teleport_history_item.xml
+++ b/indra/newview/skins/default/xui/ru/panel_teleport_history_item.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_tools_texture.xml b/indra/newview/skins/default/xui/ru/panel_tools_texture.xml
new file mode 100644
index 0000000000..1abf729487
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/panel_tools_texture.xml
@@ -0,0 +1,116 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="ТекÑтура" name="Texture">
+ <panel.string name="string repeats per meter">
+ Повторений на метр
+ </panel.string>
+ <panel.string name="string repeats per face">
+ Повторений на грань
+ </panel.string>
+ <text name="color label">
+ Цвет
+ </text>
+ <color_swatch label="" name="colorswatch" tool_tip="Щелкните Ð´Ð»Ñ Ð²Ñ‹Ð±Ð¾Ñ€Ð° цвета"/>
+ <text name="color trans">
+ ПрозрачноÑÑ‚ÑŒ %
+ </text>
+ <text name="glow label">
+ Свечение
+ </text>
+ <check_box label="СобÑÑ‚Ð²ÐµÐ½Ð½Ð°Ñ ÑркоÑÑ‚ÑŒ" name="checkbox fullbright"/>
+ <combo_box name="combobox matmedia">
+ <combo_box.item label="Материалы" name="Materials"/>
+ <combo_box.item label="Медиа" name="Media"/>
+ </combo_box>
+ <combo_box name="combobox mattype">
+ <combo_box.item label="ТекÑтура (раÑÑеÑннаÑ)" name="Texture (diffuse)"/>
+ <combo_box.item label="ШероховатоÑÑ‚ÑŒ (обычнаÑ)" name="Bumpiness (normal)"/>
+ <combo_box.item label="БлеÑк (зеркальный)" name="Shininess (specular)"/>
+ </combo_box>
+ <texture_picker label="ТекÑтура" name="texture control" tool_tip="Щелкните Ð´Ð»Ñ Ð²Ñ‹Ð±Ð¾Ñ€Ð° изображениÑ"/>
+ <text name="label alphamode">
+ Ðльфа-режим
+ </text>
+ <combo_box name="combobox alphamode">
+ <combo_box.item label="Ðет" name="None"/>
+ <combo_box.item label="Ðльфа-Ñмешивание" name="Alpha blending"/>
+ <combo_box.item label="Ðльфа-маÑкирование" name="Alpha masking"/>
+ <combo_box.item label="Ð˜Ð·Ð»ÑƒÑ‡Ð°ÑŽÑ‰Ð°Ñ Ð¼Ð°Ñка" name="Emissive mask"/>
+ </combo_box>
+ <text name="label maskcutoff">
+ ОтÑечка маÑки
+ </text>
+ <texture_picker label="ТекÑтура" name="bumpytexture control" tool_tip="Щелкните Ð´Ð»Ñ Ð²Ñ‹Ð±Ð¾Ñ€Ð° изображениÑ"/>
+ <text name="label bumpiness">
+ РельефноÑÑ‚ÑŒ
+ </text>
+ <combo_box name="combobox bumpiness">
+ <combo_box.item label="Ðет" name="None"/>
+ <combo_box.item label="ЯркоÑÑ‚ÑŒ" name="Brightness"/>
+ <combo_box.item label="По темному" name="Darkness"/>
+ <combo_box.item label="дерево" name="woodgrain"/>
+ <combo_box.item label="кора" name="bark"/>
+ <combo_box.item label="кирпич" name="bricks"/>
+ <combo_box.item label="ÑˆÐ°Ñ…Ð¼Ð°Ñ‚Ð½Ð°Ñ Ð´Ð¾Ñка" name="checker"/>
+ <combo_box.item label="бетон" name="concrete"/>
+ <combo_box.item label="ÑÑ‚Ð°Ñ€Ð°Ñ Ð¿Ð»Ð¸Ñ‚ÐºÐ°" name="crustytile"/>
+ <combo_box.item label="теÑаный камень" name="cutstone"/>
+ <combo_box.item label="диÑки" name="discs"/>
+ <combo_box.item label="гравий" name="gravel"/>
+ <combo_box.item label="чашка Петри" name="petridish"/>
+ <combo_box.item label="Ñайдинг" name="siding"/>
+ <combo_box.item label="ÐºÐ°Ð¼ÐµÐ½Ð½Ð°Ñ Ð¿Ð»Ð¸Ñ‚ÐºÐ°" name="stonetile"/>
+ <combo_box.item label="штукатурка" name="stucco"/>
+ <combo_box.item label="приÑоÑка" name="suction"/>
+ <combo_box.item label="переплетение" name="weave"/>
+ </combo_box>
+ <texture_picker label="ТекÑтура" name="shinytexture control" tool_tip="Щелкните Ð´Ð»Ñ Ð²Ñ‹Ð±Ð¾Ñ€Ð° изображениÑ"/>
+ <text name="label shininess">
+ БлеÑк
+ </text>
+ <combo_box name="combobox shininess">
+ <combo_box.item label="Ðет" name="None"/>
+ <combo_box.item label="Ðизкий" name="Low"/>
+ <combo_box.item label="Средний" name="Medium"/>
+ <combo_box.item label="Ð’Ñ‹Ñокий" name="High"/>
+ </combo_box>
+ <text name="label glossiness">
+ ГлÑнец
+ </text>
+ <text name="label environment">
+ Среда
+ </text>
+ <text name="label shinycolor">
+ Цвет
+ </text>
+ <color_swatch label="" name="shinycolorswatch" tool_tip="Щелкните Ð´Ð»Ñ Ð²Ñ‹Ð±Ð¾Ñ€Ð° цвета"/>
+ <text name="media_info">
+ URL выбранного медиа (еÑли еÑÑ‚ÑŒ)
+ </text>
+ <button label="Выбрать..." name="add_media" tool_tip="Добавить медиа"/>
+ <button label="Удалить" name="delete_media" tool_tip="Удалить медиа-текÑтуру"/>
+ <button label="ВыровнÑÑ‚ÑŒ" label_selected="ВыровнÑÑ‚ÑŒ медиа" name="button align" tool_tip="МаÑштабирование медиа-текÑтуры (Ñначала нужно загрузить)"/>
+ <text name="tex gen">
+ Ðаложение
+ </text>
+ <combo_box name="combobox texgen">
+ <combo_box.item label="По умолчанию" name="Default"/>
+ <combo_box.item label="Ðа плоÑкоÑÑ‚ÑŒ" name="Planar"/>
+ </combo_box>
+ <spinner label="МаÑштаб по горизонтали" name="TexScaleU"/>
+ <spinner label="МаÑштаб по вертикали" name="TexScaleV"/>
+ <spinner label="Повторений на метр" name="rptctrl"/>
+ <spinner label="Поворот, градуÑÑ‹" name="TexRot"/>
+ <spinner label="Смещение по горизонтали" name="TexOffsetU"/>
+ <spinner label="Смещение по вертикали" name="TexOffsetV"/>
+ <spinner label="МаÑштаб по горизонтали" name="bumpyScaleU"/>
+ <spinner label="МаÑштаб по вертикали" name="bumpyScaleV"/>
+ <spinner label="Поворот, градуÑÑ‹" name="bumpyRot"/>
+ <spinner label="Смещение по горизонтали" name="bumpyOffsetU"/>
+ <spinner label="Смещение по вертикали" name="bumpyOffsetV"/>
+ <spinner label="МаÑштаб по горизонтали" name="shinyScaleU"/>
+ <spinner label="МаÑштаб по вертикали" name="shinyScaleV"/>
+ <spinner label="Поворот, градуÑÑ‹" name="shinyRot"/>
+ <spinner label="Смещение по горизонтали" name="shinyOffsetU"/>
+ <spinner label="Смещение по вертикали" name="shinyOffsetV"/>
+ <check_box initial_value="false" label="СоглаÑование" name="checkbox planar align" tool_tip="СоглаÑование текÑтур на вÑех выбранных гранÑÑ… по поÑледней выбранной грани. Должно быть выбрано наложение по плоÑкоÑÑ‚Ñм."/>
+</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_voice_effect.xml b/indra/newview/skins/default/xui/ru/panel_voice_effect.xml
index de0b38198f..de0b38198f 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_voice_effect.xml
+++ b/indra/newview/skins/default/xui/ru/panel_voice_effect.xml
diff --git a/indra/newview/skins/default/xui/ru/panel_volume_pulldown.xml b/indra/newview/skins/default/xui/ru/panel_volume_pulldown.xml
new file mode 100755
index 0000000000..fe044cd083
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/panel_volume_pulldown.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="volumepulldown_floater">
+ <slider label="ОбщаÑ" name="System Volume"/>
+ <slider label="Кнопки" name="UI Volume"/>
+ <slider label="ОкружающаÑ" name="Wind Volume"/>
+ <slider label="Звуки" name="SFX Volume"/>
+ <check_box name="gesture_audio_play_btn" tool_tip="Включить звуки от жеÑтов"/>
+ <slider label="Музыка" name="Music Volume"/>
+ <check_box name="enable_music" tool_tip="Включить потоковую музыку"/>
+ <slider label="Медиа" name="Media Volume"/>
+ <check_box name="enable_media" tool_tip="Включить потоковое медиа"/>
+ <slider label="ГолоÑ" name="Voice Volume"/>
+ <check_box name="enable_voice_check" tool_tip="Включить голоÑовой чат"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_world_map.xml b/indra/newview/skins/default/xui/ru/panel_world_map.xml
index 0ab8720185..0ab8720185 100644..100755
--- a/indra/newview/skins/default/xui/ru/panel_world_map.xml
+++ b/indra/newview/skins/default/xui/ru/panel_world_map.xml
diff --git a/indra/newview/skins/default/xui/ru/role_actions.xml b/indra/newview/skins/default/xui/ru/role_actions.xml
index b6ba818abd..3f31ecfa10 100644..100755
--- a/indra/newview/skins/default/xui/ru/role_actions.xml
+++ b/indra/newview/skins/default/xui/ru/role_actions.xml
@@ -25,7 +25,7 @@
</action_set>
<action_set description="К Ñтим ÑпоÑобноÑÑ‚Ñм отноÑитÑÑ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ðµ Ð½Ð°Ð·Ð²Ð°Ð½Ð¸Ñ ÑƒÑ‡Ð°Ñтка и Ð¿ÑƒÐ±Ð»Ð¸ÐºÐ°Ñ†Ð¸Ñ Ð½Ð°Ñтроек, поиÑк видимых каталогов, а также наÑтройки точек и вариантов телепортации." name="Parcel Identity">
<action description="Включение-отключение показа меÑта в результатах поиÑка и наÑтройка категории" longdescription="Включить-отключить показ меÑта в результатах поиÑка и наÑтроить категорию учаÑтка можно в окне «О земле» на вкладке «Параметры»." name="land find places" value="17"/>
- <action description="Изменение Ð½Ð°Ð·Ð²Ð°Ð½Ð¸Ñ Ð¸Ð»Ð¸ опиÑÐ°Ð½Ð¸Ñ ÑƒÑ‡Ð°Ñтка, наÑтройки «Показать меÑто в поиÑке»" longdescription="Изменение Ð½Ð°Ð·Ð²Ð°Ð½Ð¸Ñ Ð¸Ð»Ð¸ опиÑÐ°Ð½Ð¸Ñ ÑƒÑ‡Ð°Ñтка, наÑтройки «Показать меÑто в поиÑке». Это можно выполнить в окне «О земле» на вкладке «Параметры»." name="land change identity" value="18"/>
+ <action description="Изменение Ð½Ð°Ð·Ð²Ð°Ð½Ð¸Ñ Ð¸Ð»Ð¸ опиÑÐ°Ð½Ð¸Ñ ÑƒÑ‡Ð°Ñтка, наÑтройки «Умеренный контент»" longdescription="Изменение Ð½Ð°Ð·Ð²Ð°Ð½Ð¸Ñ Ð¸Ð»Ð¸ опиÑÐ°Ð½Ð¸Ñ ÑƒÑ‡Ð°Ñтка, наÑтройки «Умеренный контент». Это можно выполнить в окне «О земле» на вкладке «Параметры»." name="land change identity" value="18"/>
<action description="УÑтановка конечной точки и варианта телепортации" longdescription="УчаÑтники роли Ñ Ñтой ÑпоÑобноÑтью могут уÑтановить конечную точку телепортации на учаÑтке группы, а также задать вариант телепортации Ð´Ð»Ñ ÑƒÑÐ¸Ð»ÐµÐ½Ð¸Ñ ÐºÐ¾Ð½Ñ‚Ñ€Ð¾Ð»Ñ. Это можно выполнить в окне «О земле» на вкладке «Параметры»." name="land set landing point" value="19"/>
</action_set>
<action_set description="К Ñтим ÑпоÑобноÑÑ‚Ñм отноÑитÑÑ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ðµ наÑтроек учаÑтка, в Ñ‚. ч. «Создать объекты», «Изменить ландшафт», а также наÑтройки музыки и медиа." name="Parcel Settings">
diff --git a/indra/newview/skins/default/xui/ru/sidepanel_appearance.xml b/indra/newview/skins/default/xui/ru/sidepanel_appearance.xml
index a23f6134f2..a23f6134f2 100644..100755
--- a/indra/newview/skins/default/xui/ru/sidepanel_appearance.xml
+++ b/indra/newview/skins/default/xui/ru/sidepanel_appearance.xml
diff --git a/indra/newview/skins/default/xui/ru/sidepanel_inventory.xml b/indra/newview/skins/default/xui/ru/sidepanel_inventory.xml
index c106c2de79..c106c2de79 100644..100755
--- a/indra/newview/skins/default/xui/ru/sidepanel_inventory.xml
+++ b/indra/newview/skins/default/xui/ru/sidepanel_inventory.xml
diff --git a/indra/newview/skins/default/xui/ru/sidepanel_item_info.xml b/indra/newview/skins/default/xui/ru/sidepanel_item_info.xml
index 62095acbaf..0106ed50ac 100644..100755
--- a/indra/newview/skins/default/xui/ru/sidepanel_item_info.xml
+++ b/indra/newview/skins/default/xui/ru/sidepanel_item_info.xml
@@ -3,6 +3,9 @@
<panel.string name="unknown">
(неизвеÑтно)
</panel.string>
+ <panel.string name="unknown_multiple">
+ (неизвеÑтно/неÑколько)
+ </panel.string>
<panel.string name="public">
(публичное)
</panel.string>
diff --git a/indra/newview/skins/default/xui/ru/sidepanel_task_info.xml b/indra/newview/skins/default/xui/ru/sidepanel_task_info.xml
index 8e56dd80c0..5502530ca4 100644..100755
--- a/indra/newview/skins/default/xui/ru/sidepanel_task_info.xml
+++ b/indra/newview/skins/default/xui/ru/sidepanel_task_info.xml
@@ -18,6 +18,12 @@
<panel.string name="text modify info 4">
Эти объекты Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ð·Ð¼ÐµÐ½ÑÑ‚ÑŒ
</panel.string>
+ <panel.string name="text modify info 5">
+ Этот объект Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ð·Ð¼ÐµÐ½ÑÑ‚ÑŒ через границу региона
+ </panel.string>
+ <panel.string name="text modify info 6">
+ Эти объекты Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ð·Ð¼ÐµÐ½ÑÑ‚ÑŒ через границу региона
+ </panel.string>
<panel.string name="text modify warning">
Этот объект Ñодержит объединенные чаÑти
</panel.string>
@@ -66,6 +72,7 @@
<combo_box.item label="Купить объект" name="Buyobject"/>
<combo_box.item label="Заплатить за объект" name="Payobject"/>
<combo_box.item label="Открыть" name="Open"/>
+ <combo_box.item label="Приблизить" name="Zoom"/>
</combo_box>
<panel name="perms_inv">
<text name="perm_modify">
@@ -95,6 +102,9 @@
</combo_box>
<spinner label="Цена: L$" name="Edit Cost"/>
<check_box label="Показать в результатах поиÑка" name="search_check" tool_tip="Показывать объект в результатах поиÑка"/>
+ <text name="pathfinding_attributes_label">
+ Ðтрибуты поиÑка пути:
+ </text>
<text name="B:">
Ð:
</text>
diff --git a/indra/newview/skins/default/xui/ru/strings.xml b/indra/newview/skins/default/xui/ru/strings.xml
index 8dbc4f092d..0f71edcee0 100644..100755
--- a/indra/newview/skins/default/xui/ru/strings.xml
+++ b/indra/newview/skins/default/xui/ru/strings.xml
@@ -137,7 +137,10 @@
Выйти
</string>
<string name="create_account_url">
- http://join.secondlife.com/
+ http://join.secondlife.com/?sourceid=[sourceid]
+ </string>
+ <string name="ViewerDownloadURL">
+ http://secondlife.com/download
</string>
<string name="LoginFailedViewerNotPermitted">
У клиента, которым вы пользуетеÑÑŒ, больше нет доÑтупа к игре Second Life. Загрузить новую верÑию клиента можно по адреÑу
@@ -448,6 +451,9 @@ support@secondlife.com.
<string name="SLappAgentRequestFriend">
Предложить дружбу
</string>
+ <string name="SLappAgentRemoveFriend">
+ Удаление друга
+ </string>
<string name="BUTTON_CLOSE_DARWIN">
Закрыть (⌘W)
</string>
@@ -619,7 +625,7 @@ support@secondlife.com.
<string name="AvatarAway">
Ðет на меÑте
</string>
- <string name="AvatarBusy">
+ <string name="AvatarDoNotDisturb">
Ðе беÑпокоить
</string>
<string name="AvatarMuted">
@@ -835,6 +841,9 @@ support@secondlife.com.
<string name="multiple_textures">
ÐеÑколько
</string>
+ <string name="use_texture">
+ ИÑпользовать текÑтуру
+ </string>
<string name="texture_loading">
Загрузка...
</string>
@@ -856,6 +865,12 @@ support@secondlife.com.
<string name="ST_NO_JOINT">
Ðе удаетÑÑ Ð½Ð°Ð¹Ñ‚Ð¸ объект ROOT или JOINT.
</string>
+ <string name="NearbyChatTitle">
+ Локальный чат
+ </string>
+ <string name="NearbyChatLabel">
+ (Локальный чат)
+ </string>
<string name="whisper">
шепчет:
</string>
@@ -883,6 +898,9 @@ support@secondlife.com.
<string name="ScriptQuestionCautionChatDenied">
Объекту «[OBJECTNAME]», который принадлежит пользователю «[OWNERNAME]» и находитÑÑ Ð² [REGIONPOS] в регионе «[REGIONNAME]», отказано в разрешении: [PERMISSIONS].
</string>
+ <string name="AdditionalPermissionsRequestHeader">
+ Разрешив доÑтуп к Ñвоему аккаунту, вы также разрешите объекту:
+ </string>
<string name="ScriptTakeMoney">
У Ð²Ð°Ñ Ð±ÐµÑ€ÑƒÑ‚ Linden-деньги
</string>
@@ -919,6 +937,27 @@ support@secondlife.com.
<string name="NotConnected">
Ðет подключениÑ
</string>
+ <string name="AgentNameSubst">
+ (Ð’Ñ‹)
+ </string>
+ <string name="TeleportYourAgent">
+ Телепортировать ваÑ
+ </string>
+ <string name="JoinAnExperience">
+ ПриÑоединитеÑÑŒ
+ </string>
+ <string name="SilentlyManageEstateAccess">
+ Отключить Ð¸Ð·Ð²ÐµÑ‰ÐµÐ½Ð¸Ñ Ð¿Ñ€Ð¸ управлении ÑпиÑками доÑтупа к землевладениÑм
+ </string>
+ <string name="OverrideYourAnimations">
+ Заменить ваши Ñтандартные анимации
+ </string>
+ <string name="ScriptReturnObjects">
+ Вернуть объекты от вашего имени
+ </string>
+ <string name="UnknownScriptPermission">
+ (неизвеÑтно)!
+ </string>
<string name="SIM_ACCESS_PG">
Общий
</string>
@@ -997,17 +1036,8 @@ support@secondlife.com.
<string name="script_files">
Скрипты
</string>
- <string name="AvatarSetNotAway">
- Ðа меÑте
- </string>
- <string name="AvatarSetAway">
- Ðет на меÑте
- </string>
- <string name="AvatarSetNotBusy">
- Ðе занÑÑ‚(а)
- </string>
- <string name="AvatarSetBusy">
- Ðе беÑпокоить
+ <string name="dictionary_files">
+ Словари
</string>
<string name="shape">
Фигура
@@ -1241,7 +1271,7 @@ support@secondlife.com.
https://marketplace.[MARKETPLACE_DOMAIN_NAME]/
</string>
<string name="MarketplaceURL_CreateStore">
- http://community.secondlife.com/t5/English-Knowledge-Base/Selling-in-the-Marketplace/ta-p/700193#Section_.4
+ http://community.secondlife.com/t5/English-Knowledge-Base/Selling-in-the-Marketplace/ta-p/700193#Section_.3
</string>
<string name="MarketplaceURL_Dashboard">
https://marketplace.[MARKETPLACE_DOMAIN_NAME]/merchants/store/dashboard
@@ -1402,6 +1432,12 @@ support@secondlife.com.
<string name="InvFolder favorite">
Мое избранное
</string>
+ <string name="InvFolder Favorites">
+ Мое избранное
+ </string>
+ <string name="InvFolder favorites">
+ Мое избранное
+ </string>
<string name="InvFolder Current Outfit">
Текущий коÑтюм
</string>
@@ -1417,6 +1453,12 @@ support@secondlife.com.
<string name="InvFolder Meshes">
Меши
</string>
+ <string name="InvFolder Received Items">
+ Полученные вещи
+ </string>
+ <string name="InvFolder Merchant Outbox">
+ Торговые иÑходÑщие
+ </string>
<string name="InvFolder Friends">
ДрузьÑ
</string>
@@ -1947,6 +1989,12 @@ support@secondlife.com.
<string name="ATTACH_HUD_BOTTOM_RIGHT">
Данные в игре внизу Ñправа
</string>
+ <string name="ATTACH_NECK">
+ ШеÑ
+ </string>
+ <string name="ATTACH_AVATAR_CENTER">
+ Центр аватара
+ </string>
<string name="CursorPos">
Строка [LINE], Ñтолбец [COLUMN]
</string>
@@ -1965,8 +2013,8 @@ support@secondlife.com.
<string name="PanelContentsNewScript">
Ðовый Ñкрипт
</string>
- <string name="BusyModeResponseDefault">
- У адреÑата вашего ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð·Ð°Ð´Ð°Ð½ ÑÑ‚Ð°Ñ‚ÑƒÑ Â«Ðе беÑпокоить». Ваше Ñообщение вÑе равно будет отображено на панели IM Ð´Ð»Ñ Ð¿Ñ€Ð¾Ñмотра позже.
+ <string name="DoNotDisturbModeResponseDefault">
+ Этот житель включил режим «Ðе беÑпокоить» и увидит ваше Ñообщение позже.
</string>
<string name="MuteByName">
(по имени)
@@ -2079,9 +2127,6 @@ support@secondlife.com.
<string name="GroupMoneyDate">
[weekday,datetime,utc], [day,datetime,utc] [mth,datetime,utc] [year,datetime,utc]
</string>
- <string name="ViewerObjectContents">
- Контент
- </string>
<string name="AcquiredItems">
Купленные вещи
</string>
@@ -2976,6 +3021,9 @@ support@secondlife.com.
<string name="Hip Width">
Ширина бедер
</string>
+ <string name="Hover">
+ Ðаведите
+ </string>
<string name="In">
Внутрь
</string>
@@ -3850,7 +3898,13 @@ support@secondlife.com.
ОблаÑÑ‚ÑŒ общей дозволенноÑти
</string>
<string name="LocationCtrlSeeAVsTooltip">
- Ð’Ñе жители Ñ Ð´Ñ€ÑƒÐ³Ð¸Ñ… учаÑтков могут видеть аватары и общатьÑÑ Ð² чате
+ Ðватары на Ñтом учаÑтке невидимы и неÑлышимы Ð´Ð»Ñ Ð°Ð²Ð°Ñ‚Ð°Ñ€Ð¾Ð² Ñ Ð´Ñ€ÑƒÐ³Ð¸Ñ… учаÑтков
+ </string>
+ <string name="LocationCtrlPathfindingDirtyTooltip">
+ Возможны неполадки подвижных объектов в Ñтом регионе, пока регион не будет воÑÑтановлен.
+ </string>
+ <string name="LocationCtrlPathfindingDisabledTooltip">
+ Ð’ Ñтом регионе не разрешен динамичеÑкий поиÑк пути.
</string>
<string name="UpdaterWindowTitle">
Обновление [APP_NAME]
@@ -3921,6 +3975,12 @@ support@secondlife.com.
<string name="IM_unblock_only_groups_friends">
Ð”Ð»Ñ Ð¿Ñ€Ð¾Ñмотра Ñтого ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ñнимите флажок «Только Ð´Ñ€ÑƒÐ·ÑŒÑ Ð¸ группы могут звонить мне и отправлÑÑ‚ÑŒ IM» в окне «ÐаÑтройки/ПриватноÑть».
</string>
+ <string name="OnlineStatus">
+ Онлайн
+ </string>
+ <string name="OfflineStatus">
+ Оффлайн
+ </string>
<string name="answered_call">
Ðа ваш звонок ответили
</string>
@@ -3930,6 +3990,9 @@ support@secondlife.com.
<string name="you_joined_call">
Ð’Ñ‹ приÑоединилиÑÑŒ к голоÑовой беÑеде
</string>
+ <string name="you_auto_rejected_call-im">
+ ГолоÑовой вызов автоматичеÑки отклонен, так как включен режим «Ðе беÑпокоить».
+ </string>
<string name="name_started_call">
Житель [NAME] начал голоÑовую беÑеду
</string>
@@ -3946,7 +4009,7 @@ support@secondlife.com.
СоединÑетÑÑ...
</string>
<string name="conference-title">
- Ð¡Ð¿Ð¾Ð½Ñ‚Ð°Ð½Ð½Ð°Ñ ÐºÐ¾Ð½Ñ„ÐµÑ€ÐµÐ½Ñ†Ð¸Ñ
+ Чат Ñ Ð½ÐµÑколькими учаÑтниками
</string>
<string name="conference-title-incoming">
ÐšÐ¾Ð½Ñ„ÐµÑ€ÐµÐ½Ñ†Ð¸Ñ Ñ Ð¶Ð¸Ñ‚ÐµÐ»ÐµÐ¼ [AGENT_NAME]
@@ -4838,6 +4901,9 @@ support@secondlife.com.
<string name="Command_Chat_Label">
Чат
</string>
+ <string name="Command_Conversations_Label">
+ Разговоры
+ </string>
<string name="Command_Compass_Label">
КомпаÑ
</string>
@@ -4913,6 +4979,9 @@ support@secondlife.com.
<string name="Command_Chat_Tooltip">
ОбменивайтеÑÑŒ текÑтовыми репликами Ñ Ð»ÑŽÐ´ÑŒÐ¼Ð¸ вокруг ваÑ
</string>
+ <string name="Command_Conversations_Tooltip">
+ Поговорить Ñо вÑеми
+ </string>
<string name="Command_Compass_Tooltip">
КомпаÑ
</string>
@@ -5006,6 +5075,21 @@ support@secondlife.com.
<string name="Normal">
Ðормальный
</string>
+ <string name="Pathfinding_Wiki_URL">
+ http://wiki.secondlife.com/wiki/Pathfinding_Tools_in_the_Second_Life_Viewer
+ </string>
+ <string name="Pathfinding_Object_Attr_None">
+ Ðет
+ </string>
+ <string name="Pathfinding_Object_Attr_Permanent">
+ ВлиÑет на навигационную Ñетку
+ </string>
+ <string name="Pathfinding_Object_Attr_Character">
+ ПерÑонаж
+ </string>
+ <string name="Pathfinding_Object_Attr_MultiSelect">
+ (неÑколько)
+ </string>
<string name="snapshot_quality_very_low">
Очень низкий
</string>
@@ -5021,4 +5105,22 @@ support@secondlife.com.
<string name="snapshot_quality_very_high">
Очень выÑокий
</string>
+ <string name="TeleportMaturityExceeded">
+ Житель не может поÑетить Ñтот регион.
+ </string>
+ <string name="UserDictionary">
+ [Пользователь]
+ </string>
+ <string name="logging_calls_disabled_log_empty">
+ Разговоры не запиÑываютÑÑ. Чтобы начать запиÑÑŒ разговора, в меню «ÐаÑтройки &gt; Чат» выберите «СохранÑÑ‚ÑŒ: только журнал» или «СохранÑÑ‚ÑŒ: журнал и запиÑи».
+ </string>
+ <string name="logging_calls_disabled_log_not_empty">
+ Разговоры больше не будут запиÑыватьÑÑ. Чтобы воÑÑтановить запиÑÑŒ разговора, в меню «ÐаÑтройки &gt; Чат» выберите «СохранÑÑ‚ÑŒ: только журнал» или «СохранÑÑ‚ÑŒ: журнал и запиÑи».
+ </string>
+ <string name="logging_calls_enabled_log_empty">
+ Ðет зарегиÑтрированных разговоров. ЕÑли вы обратитеÑÑŒ к кому-то или наоборот, в журнале поÑвитÑÑ Ð½Ð¾Ð²Ð°Ñ Ð·Ð°Ð¿Ð¸ÑÑŒ.
+ </string>
+ <string name="loading_chat_logs">
+ Загрузка...
+ </string>
</strings>
diff --git a/indra/newview/skins/default/xui/ru/teleport_strings.xml b/indra/newview/skins/default/xui/ru/teleport_strings.xml
index feff286111..40c9267408 100644..100755
--- a/indra/newview/skins/default/xui/ru/teleport_strings.xml
+++ b/indra/newview/skins/default/xui/ru/teleport_strings.xml
@@ -45,6 +45,9 @@
<message name="no_inventory_host">
СиÑтема Ð¸Ð½Ð²ÐµÐ½Ñ‚Ð°Ñ€Ñ ÑÐµÐ¹Ñ‡Ð°Ñ Ð½ÐµÐ´Ð¾Ñтупна.
</message>
+ <message name="MustGetAgeRegion">
+ Входить в Ñтот регион могут только жители 18 лет и Ñтарше.
+ </message>
</message_set>
<message_set name="progress">
<message name="sending_dest">
@@ -80,5 +83,8 @@
<message name="requesting">
Ð—Ð°Ð¿Ñ€Ð¾Ñ Ñ‚ÐµÐ»ÐµÐ¿Ð¾Ñ€Ñ‚Ð°Ñ†Ð¸Ð¸â€¦
</message>
+ <message name="pending">
+ Ð¢ÐµÐ»ÐµÐ¿Ð¾Ñ€Ñ‚Ð°Ñ†Ð¸Ñ Ð½Ðµ закончена...
+ </message>
</message_set>
</teleport_messages>
diff --git a/indra/newview/skins/default/xui/tr/floater_aaa.xml b/indra/newview/skins/default/xui/tr/floater_aaa.xml
index d663ec1a5b..d663ec1a5b 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_aaa.xml
+++ b/indra/newview/skins/default/xui/tr/floater_aaa.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_about.xml b/indra/newview/skins/default/xui/tr/floater_about.xml
index 8fa12ea759..7b925e8830 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_about.xml
+++ b/indra/newview/skins/default/xui/tr/floater_about.xml
@@ -8,7 +8,9 @@
[COMPILER] [COMPILER_VERSION] sürümü ile oluşturuldu
</floater.string>
<floater.string name="AboutPosition">
- &lt;nolink&gt;[HOSTNAME]&lt;/nolink&gt; ([HOSTIP]) üzerinde bulunan [REGION] içerisinde [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1] konumundasınız
+ &lt;nolink&gt;[HOSTNAME]&lt;/nolink&gt; ([HOSTIP]) üzerinde bulunan [REGION] içerisinde [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] konumundasınız
+SLURL: &lt;nolink&gt;[SLURL]&lt;/nolink&gt;
+(küresel koordinatlar [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1])
[SERVER_VERSION]
[SERVER_RELEASE_NOTES_URL]
</floater.string>
@@ -63,27 +65,26 @@ Ses Sunucusu Sürümü: [VOICE_VERSION]
</panel>
<panel label="Lisanslar" name="licenses_panel">
<text_editor name="credits_editor">
- 3Dconnexion SDK Telif Hakkı (C) 1992-2007 3Dconnexion
- APR Telif Hakkı (C) 2000-2004 The Apache Software Foundation
- Collada DOM Telif Hakkı 2005 Sony Computer Entertainment Inc.
- cURL Telif Hakkı (C) 1996-2002, Daniel Stenberg, (daniel@haxx.se)
+ 3Dconnexion SDK Telif Hakkı (C) 1992-2009 3Dconnexion
+ APR Telif Hakkı (C) 2011 The Apache Software Foundation
+ Collada DOM Telif Hakkı 2006 Sony Computer Entertainment Inc.
+ cURL Telif Hakkı (C) 1996-2010, Daniel Stenberg, (daniel@haxx.se)
DBus/dbus-glib Telif Hakkı (C) 2002, 2003 CodeFactory AB / Telif Hakkı (C) 2003, 2004 Red Hat, Inc.
expat Telif Hakkı (C) 1998, 1999, 2000 Thai Open Source Software Center Ltd.
- FreeType Telif Hakkı (C) 1996-2002, The FreeType Project (www.freetype.org).
+ FreeType Telif Hakkı (C) 1996-2002, 2006 David Turner, Robert Wilhelm ve Werner Lemberg.
GL Telif Hakkı (C) 1999-2004 Brian Paul.
GLOD Telif Hakkı (C) 2003-04 Jonathan Cohen, Nat Duca, Chris Niski, Johns Hopkins University ve David Luebke, Brenden Schubert, University of Virginia.
google-perftools Telif Hakkı (c) 2005, Google Inc.
Havok.com(TM) Telif Hakkı (C) 1999-2001, Telekinesys Research Limited.
jpeg2000 Telif Hakkı (C) 2001, David Taubman, The University of New South Wales (UNSW)
jpeglib Telif Hakkı (C) 1991-1998, Thomas G. Lane.
- ogg/vorbis Telif Hakkı (C) 2001, Xiphophorus
- OpenSSL Telif Hakkı (C) 1998-2002 The OpenSSL Project.
- PCRE Telif Hakkı (c) 1997-2008 University of Cambridge
+ ogg/vorbis Telif Hakkı (C) 2002, Xiphophorus
+ OpenSSL Telif Hakkı (C) 1998-2008 The OpenSSL Project.
+ PCRE Telif Hakkı (c) 1997-2012 University of Cambridge
SDL Telif Hakkı (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga
SSLeay Telif Hakkı (C) 1995-1998 Eric Young (eay@cryptsoft.com)
xmlrpc-epi Telif Hakkı (C) 2000 Epinions, Inc.
- zlib Telif Hakkı (C) 1995-2002 Jean-loup Gailly ve Mark Adler.
- google-perftools Telif Hakkı (c) 2005, Google Inc.
+ zlib Telif Hakkı (C) 1995-2012 Jean-loup Gailly ve Mark Adler.
Second Life Görüntüleyicisi Havok (TM) Fizik motorunu kullanmaktadır. (c)Telif Hakkı 1999-2010 Havok.com Inc. (ve Lisans Verenleri). Tüm Hakları Saklıdır. Ayrıntılı bilgi için bkz. www.havok.com
diff --git a/indra/newview/skins/default/xui/tr/floater_about_land.xml b/indra/newview/skins/default/xui/tr/floater_about_land.xml
index a478d347a8..481fc540d0 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/tr/floater_about_land.xml
@@ -451,7 +451,7 @@ Sadece büyük parseller aramada görünür.
Sadece ÅŸu Sakinlere eriÅŸim izni verin:
</text>
<check_box label="Ödeme bilgileri kayıtlı [ESTATE_PAYMENT_LIMIT]" name="limit_payment" tool_tip="Sakinlerin bu parsele erişebilmesi için ödeme bilgilerinin kayıtlı olması gerekir. Daha fazla bilgi için [SUPPORT_SITE] adresini ziyaret edin."/>
- <check_box label="Yaş doğrulaması yapılmış [ESTATE_AGE_LIMIT]" name="limit_age_verified" tool_tip="Sakinlerin bu parsele erişebilmesi için yaş doğrulamalarının yapılmış olması gerekir. Daha fazla bilgi için [SUPPORT_SITE] adresini ziyaret edin."/>
+ <check_box label="18 veya üzeri bir yaşta [ESTATE_AGE_LIMIT]" name="limit_age_verified" tool_tip="Sakinlerin bu parsele erişebilmesi için 18 veya üzeri bir yaşta olmaları gerekir. Daha fazla bilgi için [SUPPORT_SITE] adresini ziyaret edin."/>
<check_box label="Grup EriÅŸimine Ä°zin Ver: [GROUP]" name="GroupCheck" tool_tip="Genel sekmesinde grup ayarla."/>
<check_box label="Geçiş haklr. şuna sat:" name="PassCheck" tool_tip="Bu parsele geçici erişim verir"/>
<combo_box name="pass_combo">
diff --git a/indra/newview/skins/default/xui/tr/floater_activeim.xml b/indra/newview/skins/default/xui/tr/floater_activeim.xml
index f3f66b942f..f3f66b942f 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_activeim.xml
+++ b/indra/newview/skins/default/xui/tr/floater_activeim.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_animation_anim_preview.xml b/indra/newview/skins/default/xui/tr/floater_animation_anim_preview.xml
index a63e1e107e..a63e1e107e 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_animation_anim_preview.xml
+++ b/indra/newview/skins/default/xui/tr/floater_animation_anim_preview.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_animation_bvh_preview.xml b/indra/newview/skins/default/xui/tr/floater_animation_bvh_preview.xml
index f8800c674d..f8800c674d 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_animation_bvh_preview.xml
+++ b/indra/newview/skins/default/xui/tr/floater_animation_bvh_preview.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_animation_preview.xml b/indra/newview/skins/default/xui/tr/floater_animation_preview.xml
deleted file mode 100644
index f8800c674d..0000000000
--- a/indra/newview/skins/default/xui/tr/floater_animation_preview.xml
+++ /dev/null
@@ -1,186 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Animation Preview">
- <floater.string name="failed_to_initialize">
- Hareket başlatılamadı
- </floater.string>
- <floater.string name="anim_too_long">
- Animasyon dosyası [LENGTH] saniye uzunluğunda.
-
-Maksimum animasyon uzunluÄŸu [LENGTH] saniye.
- </floater.string>
- <floater.string name="failed_file_read">
- Animasyon dosyası okunamadı.
-
-[STATUS]
- </floater.string>
- <floater.string name="E_ST_OK">
- Tamam
- </floater.string>
- <floater.string name="E_ST_EOF">
- Dosyanın zamanından önce sonu.
- </floater.string>
- <floater.string name="E_ST_NO_CONSTRAINT">
- Kısıtlama tanımı okunamadı.
- </floater.string>
- <floater.string name="E_ST_NO_FILE">
- BVH dosyası açılamadı.
- </floater.string>
- <floater.string name="E_ST_NO_HIER">
- Geçersiz HİYERARŞİ üst bilgisi.
- </floater.string>
- <floater.string name="E_ST_NO_JOINT">
- KÖK veya EKLEM bulunamadı.
- </floater.string>
- <floater.string name="E_ST_NO_NAME">
- EKLEM adı alınamadı.
- </floater.string>
- <floater.string name="E_ST_NO_OFFSET">
- OFSET bulunamadı.
- </floater.string>
- <floater.string name="E_ST_NO_CHANNELS">
- KANALLAR bulunamadı.
- </floater.string>
- <floater.string name="E_ST_NO_ROTATION">
- Döndürme sırası alınamadı.
- </floater.string>
- <floater.string name="E_ST_NO_AXIS">
- Döndürme ekseni alınamadı.
- </floater.string>
- <floater.string name="E_ST_NO_MOTION">
- HAREKET bulunamadı.
- </floater.string>
- <floater.string name="E_ST_NO_FRAMES">
- kARE SAYISI alınamadı.
- </floater.string>
- <floater.string name="E_ST_NO_FRAME_TIME">
- Kare zamanı alınamadı.
- </floater.string>
- <floater.string name="E_ST_NO_POS">
- Konum değerleri alınamadı.
- </floater.string>
- <floater.string name="E_ST_NO_ROT">
- Döndürme değerleri alınamadı.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_FILE">
- Çeviri dosyası açılamadı.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_HEADER">
- Çeviri üst bilgisi okunamadı.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_NAME">
- Çeviri adları okunamadı.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_IGNORE">
- Çeviri yoksay değeri okunamadı.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_RELATIVE">
- Çeviri nisbi değeri okunamadı.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_OUTNAME">
- Çeviri çıkış adı değeri okunamadı.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_MATRIX">
- Çeviri matrisi okunamadı.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_MERGECHILD">
- Birleştirme alt birim adı alınamadı.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_MERGEPARENT">
- Birleştirme üst birim adı alınamadı.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_PRIORITY">
- Öncelik değerleri alınamadı.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_LOOP">
- Döngü (tekrar) değerleri alınamadı.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_EASEIN">
- Easln (Yavaş Başlangıç) değerleri alınamadı.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_EASEOUT">
- EaseOut (Yavaş Bitiş) değerleri alınamadı.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_HAND">
- El şekillendirme değeri alınamadı.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_EMOTE">
- Duygu ifadesi adı okunamadı.
- </floater.string>
- <floater.string name="E_ST_BAD_ROOT">
- Yanlış kök eklem adı, &quot;kalça&quot; kullanın
- </floater.string>
- <text name="name_label">
- Ad:
- </text>
- <text name="description_label">
- Açıklama:
- </text>
- <spinner label="Öncelik" name="priority" tool_tip="Bu animasyonun diğer animasyonları geçersiz kılabileceği kontrolleri"/>
- <check_box label="Döngü" name="loop_check" tool_tip="Bu animasyonun döngülenmesini (tekrarlanmasını) sağlar"/>
- <spinner label="İç (%)" name="loop_in_point" tool_tip="Döngünün döndüğü animasyon noktasını belirler"/>
- <spinner label="Dış (%)" name="loop_out_point" tool_tip="Animasyonda döngünün bittiği noktayı belirler"/>
- <text name="hand_label">
- El DuruÅŸu
- </text>
- <combo_box name="hand_pose_combo" tool_tip="Ellerin animasyon sırasında neler yaptığını kontrol eder">
- <combo_box.item label="Yayılım" name="Spread"/>
- <combo_box.item label="Rahat" name="Relaxed"/>
- <combo_box.item label="Her Ä°kisi de Ä°ÅŸaret Ediyor" name="PointBoth"/>
- <combo_box.item label="Yumruk" name="Fist"/>
- <combo_box.item label="Sol Rahat" name="RelaxedLeft"/>
- <combo_box.item label="Sol Ä°ÅŸaret Ediyor" name="PointLeft"/>
- <combo_box.item label="Sol Yumruk" name="FistLeft"/>
- <combo_box.item label="SaÄŸ Rahat" name="RelaxedRight"/>
- <combo_box.item label="SaÄŸ Ä°ÅŸaret Ediyor" name="PointRight"/>
- <combo_box.item label="SaÄŸ Yumruk" name="FistRight"/>
- <combo_box.item label="Sağı Selamlıyor" name="SaluteRight"/>
- <combo_box.item label="Yazı Yazıyor" name="Typing"/>
- <combo_box.item label="Sağ Barış" name="PeaceRight"/>
- </combo_box>
- <text name="emote_label">
- Ä°fade
- </text>
- <combo_box name="emote_combo" tool_tip="Yüzün animasyon sırasındaki ifadesini kontrol eder">
- <item label="(Hiçbiri)" name="[None]" value=""/>
- <item label="Aaaaah" name="Aaaaah" value="Aaaaah"/>
- <item label="KorkmuÅŸ" name="Afraid" value="KorkmuÅŸ"/>
- <item label="Kızgın" name="Angry" value="Kızgın"/>
- <item label="Yaygın Gülümseyiş" name="BigSmile" value="Yaygın Gülümseyiş"/>
- <item label="Canı Sıkılmış" name="Bored" value="Canı Sıkılmış"/>
- <item label="AÄŸlama" name="Cry" value="AÄŸlama"/>
- <item label="Dudak Bükme" name="Disdain" value="Dudak Bükme"/>
- <item label="Utanmış" name="Embarrassed" value="Utanmış"/>
- <item label="Kaş Çatma" name="Frown" value="Kaş Çatma"/>
- <item label="Öpücük" name="Kiss" value="Öpücük"/>
- <item label="Gülme" name="Laugh" value="Gülme"/>
- <item label="Kahkaha" name="Plllppt" value="Kahkaha"/>
- <item label="TiksinmiÅŸ" name="Repulsed" value="TiksinmiÅŸ"/>
- <item label="Üzgün" name="Sad" value="Üzgün"/>
- <item label="Omuz Silkme" name="Shrug" value="Omuz Silkme"/>
- <item label="Gülümseme" name="Smile" value="Gülümseme"/>
- <item label="Sürpriz" name="Surprise" value="Sürpriz"/>
- <item label="Göz Kırpma" name="Wink" value="Göz Kırpma"/>
- <item label="EndiÅŸelenme" name="Worry" value="EndiÅŸelenme"/>
- </combo_box>
- <text name="preview_label">
- Şu sırada önizle
- </text>
- <combo_box name="preview_base_anim" tool_tip="Animasyon davranışınızı avatarınız genel hareketleri yaparken test etmek için bunu kullanın.">
- <item label="Ayakta Duruyor" name="Standing" value="Ayakta Duruyor"/>
- <item label="Yürüyor" name="Walking" value="Yürüyor"/>
- <item label="Oturuyor" name="Sitting" value="Oturuyor"/>
- <item label="Uçuyor" name="Flying" value="Uçuyor"/>
- </combo_box>
- <spinner label="Yavaş Başlangıç (saniye)" name="ease_in_time" tool_tip="Animasyonun kaynaştığı süre (saniye olarak)"/>
- <spinner label="Yavaş Bitiş (saniye)" name="ease_out_time" tool_tip="Animasyonun ayrıştığı süre (saniye olarak)"/>
- <button name="play_btn" tool_tip="Animasyonunu oynat"/>
- <button name="pause_btn" tool_tip="Animasyonunu duraklat"/>
- <button name="stop_btn" tool_tip="Animasyo oynatmayı durdur"/>
- <text name="bad_animation_text">
- Animasyon dosyası okunamadı.
-
-Poser 4&apos;ten aktarılan BHV dosyalarını tavsiye ederiz.
- </text>
- <button label="Karşıya Yükle (L$[AMOUNT])" name="ok_btn"/>
- <button label="Ä°ptal" name="cancel_btn"/>
-</floater>
diff --git a/indra/newview/skins/default/xui/tr/floater_auction.xml b/indra/newview/skins/default/xui/tr/floater_auction.xml
index 3c945a9c96..3c945a9c96 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_auction.xml
+++ b/indra/newview/skins/default/xui/tr/floater_auction.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_autoreplace.xml b/indra/newview/skins/default/xui/tr/floater_autoreplace.xml
new file mode 100755
index 0000000000..e52e05dc61
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/floater_autoreplace.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="autoreplace_floater" title="Otomatik Yerine Koyma Ayarları">
+ <check_box label="Otomatik Yerine Koymayı Etkinleştir" name="autoreplace_enable" tool_tip="Siz sohbet metni girdikçe, girilen herhangi bir anahtar kelimenin yerine karşılık gelen değiştirmeyi koyabilirsiniz"/>
+ <button label="Listeyi İçeri Aktar..." name="autoreplace_import_list" tool_tip="Daha önce aktarılan bir listeyi yükler."/>
+ <button label="Listeyi Aktarın..." name="autoreplace_export_list" tool_tip="Seçilen listeyi bir dosyaya kaydederek paylaşın."/>
+ <button label="Yeni Liste..." name="autoreplace_new_list" tool_tip="Yeni bir liste oluÅŸturun."/>
+ <button label="Listeyi Sil" name="autoreplace_delete_list" tool_tip="Seçilen listeyi silin."/>
+ <button name="autoreplace_list_up" tool_tip="Bu listenin önceliğini yükseltin."/>
+ <button name="autoreplace_list_down" tool_tip="Bu listenin önceliğini azaltın."/>
+ <scroll_list name="autoreplace_list_replacements">
+ <scroll_list.columns label="Anahtar kelime" name="keyword"/>
+ <scroll_list.columns label="DeÄŸiÅŸtirme" name="replacement"/>
+ </scroll_list>
+ <button label="Ekle..." name="autoreplace_add_entry"/>
+ <button label="Kaldır" name="autoreplace_delete_entry"/>
+ <button label="GiriÅŸi Kaydet" name="autoreplace_save_entry" tool_tip="Bu giriÅŸi kaydet."/>
+ <button label="Değişiklikleri Kaydet" name="autoreplace_save_changes" tool_tip="Tüm değişiklikleri kaydet."/>
+ <button label="İptal" name="autoreplace_cancel" tool_tip="Tüm değişiklikleri iptal et."/>
+</floater>
+<!--
+ <text
+ top_pad="10"
+ left="10"
+ height="16"
+ width="260"
+ follows="left|top"
+ halign="center"
+ mouse_opaque="true"
+ name="autoreplace_text2">
+ Entries
+ </text>
+-->
diff --git a/indra/newview/skins/default/xui/tr/floater_avatar.xml b/indra/newview/skins/default/xui/tr/floater_avatar.xml
index c6b14ba710..c6b14ba710 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_avatar.xml
+++ b/indra/newview/skins/default/xui/tr/floater_avatar.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_avatar_picker.xml b/indra/newview/skins/default/xui/tr/floater_avatar_picker.xml
index 99c2aae5a3..99c2aae5a3 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_avatar_picker.xml
+++ b/indra/newview/skins/default/xui/tr/floater_avatar_picker.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_avatar_textures.xml b/indra/newview/skins/default/xui/tr/floater_avatar_textures.xml
index b519cfa1a9..b519cfa1a9 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_avatar_textures.xml
+++ b/indra/newview/skins/default/xui/tr/floater_avatar_textures.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_beacons.xml b/indra/newview/skins/default/xui/tr/floater_beacons.xml
index 08ebf36be5..08ebf36be5 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_beacons.xml
+++ b/indra/newview/skins/default/xui/tr/floater_beacons.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_build_options.xml b/indra/newview/skins/default/xui/tr/floater_build_options.xml
index 5e77f6b168..5e77f6b168 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_build_options.xml
+++ b/indra/newview/skins/default/xui/tr/floater_build_options.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_bulk_perms.xml b/indra/newview/skins/default/xui/tr/floater_bulk_perms.xml
index 1d929a2dd3..bf4473ce1f 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_bulk_perms.xml
+++ b/indra/newview/skins/default/xui/tr/floater_bulk_perms.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floaterbulkperms" title="İÇERİK İZİNLERİNİ DÜZENLE">
+<floater name="floaterbulkperms" title="İÇERİK İZİNLERİNİ AYARLA">
<floater.string name="nothing_to_modify_text">
Seçim içerisinde düzenlenebilir içerik yok.
</floater.string>
@@ -24,7 +24,7 @@
<button label="√ Tümü" name="check_all"/>
<button label="Temizle" label_selected="Hiçbiri" name="check_none"/>
<text name="newperms">
- Yeni İçerik İzinleri
+ Şunun İçin İçerik İzinlerini Ayarla:
</text>
<text name="GroupLabel">
Grup:
@@ -40,6 +40,7 @@
<check_box label="DeÄŸiÅŸtir" name="next_owner_modify"/>
<check_box label="Kopyala" name="next_owner_copy"/>
<check_box initial_value="true" label="Aktar" name="next_owner_transfer" tool_tip="Sonraki sahibi bu nesneyi verebilir veya tekrar satabilir"/>
- <button label="Tamam" name="apply"/>
+ <button label="Tamam" name="ok"/>
+ <button label="Uygula" name="apply"/>
<button label="Ä°ptal" name="close"/>
</floater>
diff --git a/indra/newview/skins/default/xui/tr/floater_bumps.xml b/indra/newview/skins/default/xui/tr/floater_bumps.xml
index 06ae3a2ec3..06ae3a2ec3 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_bumps.xml
+++ b/indra/newview/skins/default/xui/tr/floater_bumps.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_buy_contents.xml b/indra/newview/skins/default/xui/tr/floater_buy_contents.xml
index 9012189ce5..9012189ce5 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_buy_contents.xml
+++ b/indra/newview/skins/default/xui/tr/floater_buy_contents.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_buy_currency.xml b/indra/newview/skins/default/xui/tr/floater_buy_currency.xml
index d90985dcff..d90985dcff 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_buy_currency.xml
+++ b/indra/newview/skins/default/xui/tr/floater_buy_currency.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_buy_currency_html.xml b/indra/newview/skins/default/xui/tr/floater_buy_currency_html.xml
index 98aaf50db0..98aaf50db0 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_buy_currency_html.xml
+++ b/indra/newview/skins/default/xui/tr/floater_buy_currency_html.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_buy_land.xml b/indra/newview/skins/default/xui/tr/floater_buy_land.xml
index 7b43af2ea4..7b43af2ea4 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_buy_land.xml
+++ b/indra/newview/skins/default/xui/tr/floater_buy_land.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_buy_object.xml b/indra/newview/skins/default/xui/tr/floater_buy_object.xml
index 91ef05fb29..91ef05fb29 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_buy_object.xml
+++ b/indra/newview/skins/default/xui/tr/floater_buy_object.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_camera.xml b/indra/newview/skins/default/xui/tr/floater_camera.xml
index 22e2aa52c6..22e2aa52c6 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_camera.xml
+++ b/indra/newview/skins/default/xui/tr/floater_camera.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_chat_bar.xml b/indra/newview/skins/default/xui/tr/floater_chat_bar.xml
index 988c845982..cd999b4b7a 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_chat_bar.xml
+++ b/indra/newview/skins/default/xui/tr/floater_chat_bar.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="chat_bar" title="YAKINDAKÄ° SOHBET">
+<floater name="nearby_chat" title="YAKINDAKÄ° SOHBET">
<panel name="bottom_panel">
<line_editor label="Sohbet etmek için buraya tıklayın." name="chat_box" tool_tip="Söylemek için Enter, bağırmak için Ctrl+Enter yapın"/>
<button name="show_nearby_chat" tool_tip="Yakın sohbet günlüğünü gösterir/gizler"/>
diff --git a/indra/newview/skins/default/xui/tr/floater_choose_group.xml b/indra/newview/skins/default/xui/tr/floater_choose_group.xml
index 1bfc772f4a..1bfc772f4a 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_choose_group.xml
+++ b/indra/newview/skins/default/xui/tr/floater_choose_group.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_color_picker.xml b/indra/newview/skins/default/xui/tr/floater_color_picker.xml
index c9465fff83..c9465fff83 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_color_picker.xml
+++ b/indra/newview/skins/default/xui/tr/floater_color_picker.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_conversation_log.xml b/indra/newview/skins/default/xui/tr/floater_conversation_log.xml
new file mode 100644
index 0000000000..5f8dac506f
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/floater_conversation_log.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="floater_conversation_log" title="SOHBET GÜNLÜĞÜ">
+ <panel name="buttons_panel">
+ <filter_editor label="KiÅŸileri Filtrele" name="people_filter_input"/>
+ <menu_button name="conversation_view_btn" tool_tip="Gösterme/sıralama seçenekleri"/>
+ <menu_button name="conversations_gear_btn" tool_tip="Seçilen kişi veya grup üzerindeki eylemler"/>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/tr/floater_conversation_preview.xml b/indra/newview/skins/default/xui/tr/floater_conversation_preview.xml
new file mode 100644
index 0000000000..84403dfd68
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/floater_conversation_preview.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="preview_conversation" title="KONUÅžMA:">
+ <floater.string name="Title">
+ KONUÅžMA: [NAME]
+ </floater.string>
+ <text name="page_label" value="Sayfa"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/tr/floater_critical.xml b/indra/newview/skins/default/xui/tr/floater_critical.xml
index 041a303bae..041a303bae 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_critical.xml
+++ b/indra/newview/skins/default/xui/tr/floater_critical.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_delete_env_preset.xml b/indra/newview/skins/default/xui/tr/floater_delete_env_preset.xml
index 915770f727..915770f727 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_delete_env_preset.xml
+++ b/indra/newview/skins/default/xui/tr/floater_delete_env_preset.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_destinations.xml b/indra/newview/skins/default/xui/tr/floater_destinations.xml
index 4504366d63..4504366d63 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_destinations.xml
+++ b/indra/newview/skins/default/xui/tr/floater_destinations.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_display_name.xml b/indra/newview/skins/default/xui/tr/floater_display_name.xml
index e39be5a24b..e39be5a24b 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_display_name.xml
+++ b/indra/newview/skins/default/xui/tr/floater_display_name.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_edit_day_cycle.xml b/indra/newview/skins/default/xui/tr/floater_edit_day_cycle.xml
index 4be1068dcc..4be1068dcc 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_edit_day_cycle.xml
+++ b/indra/newview/skins/default/xui/tr/floater_edit_day_cycle.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_edit_sky_preset.xml b/indra/newview/skins/default/xui/tr/floater_edit_sky_preset.xml
index 0e9f86148d..0e9f86148d 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_edit_sky_preset.xml
+++ b/indra/newview/skins/default/xui/tr/floater_edit_sky_preset.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_edit_water_preset.xml b/indra/newview/skins/default/xui/tr/floater_edit_water_preset.xml
index 2ddee32bad..2ddee32bad 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_edit_water_preset.xml
+++ b/indra/newview/skins/default/xui/tr/floater_edit_water_preset.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_env_settings.xml b/indra/newview/skins/default/xui/tr/floater_env_settings.xml
deleted file mode 100644
index d53629f6fe..0000000000
--- a/indra/newview/skins/default/xui/tr/floater_env_settings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Environment Editor Floater" title="ÇEVRE DÜZENLEYİCİ">
- <floater.string name="timeStr">
- [hour12,datetime,utc]:[min,datetime,utc] [ampm,datetime,utc]
- </floater.string>
- <text name="EnvTimeText">
- Günün Saati
- </text>
- <text name="EnvTimeText2">
- 12:00 PM
- </text>
- <text name="EnvCloudText">
- Bulut Örtüsü
- </text>
- <text name="EnvWaterColorText">
- Su Rengi
- </text>
- <color_swatch name="EnvWaterColor" tool_tip="Renk seçiciyi açmak için tıklayın"/>
- <text name="EnvWaterFogText">
- Su Sisi
- </text>
- <button label="Gayrimenkul Saati Kullan" name="EnvUseEstateTimeButton"/>
- <button label="Gelişmiş Gökyüzü" name="EnvAdvancedSkyButton"/>
- <button label="GeliÅŸmiÅŸ Su" name="EnvAdvancedWaterButton"/>
-</floater>
diff --git a/indra/newview/skins/default/xui/tr/floater_environment_settings.xml b/indra/newview/skins/default/xui/tr/floater_environment_settings.xml
index e702da7e1b..e702da7e1b 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_environment_settings.xml
+++ b/indra/newview/skins/default/xui/tr/floater_environment_settings.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_event.xml b/indra/newview/skins/default/xui/tr/floater_event.xml
index 60dece124b..60dece124b 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_event.xml
+++ b/indra/newview/skins/default/xui/tr/floater_event.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_fast_timers.xml b/indra/newview/skins/default/xui/tr/floater_fast_timers.xml
index 5736bda45e..5736bda45e 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_fast_timers.xml
+++ b/indra/newview/skins/default/xui/tr/floater_fast_timers.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_font_test.xml b/indra/newview/skins/default/xui/tr/floater_font_test.xml
index 5371d5d2a4..5371d5d2a4 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_font_test.xml
+++ b/indra/newview/skins/default/xui/tr/floater_font_test.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_gesture.xml b/indra/newview/skins/default/xui/tr/floater_gesture.xml
index 5f5d28ad6c..5f5d28ad6c 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_gesture.xml
+++ b/indra/newview/skins/default/xui/tr/floater_gesture.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_god_tools.xml b/indra/newview/skins/default/xui/tr/floater_god_tools.xml
index 26e5ebd18b..26e5ebd18b 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_god_tools.xml
+++ b/indra/newview/skins/default/xui/tr/floater_god_tools.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_goto_line.xml b/indra/newview/skins/default/xui/tr/floater_goto_line.xml
new file mode 100644
index 0000000000..673fe553cc
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/floater_goto_line.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="script goto" title="ÅžU SATIRA GÄ°T:">
+ <button label="Tamam" label_selected="Tamam" name="goto_btn"/>
+ <text name="txt">
+ Şu satıra git:
+ </text>
+</floater>
diff --git a/indra/newview/skins/default/xui/tr/floater_hardware_settings.xml b/indra/newview/skins/default/xui/tr/floater_hardware_settings.xml
index 8e056b9b0d..b204389083 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_hardware_settings.xml
+++ b/indra/newview/skins/default/xui/tr/floater_hardware_settings.xml
@@ -25,6 +25,10 @@
VBO EtkinleÅŸtir:
</text>
<check_box initial_value="true" label="OpenGL Vertex Tampon Nesnelerini Etkinleştir" name="vbo" tool_tip="Modern donanımlarda bunun etkinleştirilmesi performans artışı sağlar. Ancak, eski donanımlardaki VBO uygulamaları yetersizdir ve etkinleştirildiğinde bilgisayarınız çökebilir."/>
+ <text name="tc label">
+ S3TC&apos;ü Etkinleştir:
+ </text>
+ <check_box initial_value="true" label="Doku Sıkıştırmasını Etkinleştir (yeniden başlatma gerektirir)" name="texture compression" tool_tip="Video bellekteki dokuları sıkıştırır, renk kalitesinde bazı kayıplar olmasına karşın daha yüksek çözünürlükte dokuların yüklenmesine imkan tanır."/>
<slider label="Doku Belleği (MB):" name="GraphicsCardTextureMemory" tool_tip="Dokular için tahsis edilecek bellek miktarı. Varsayılan değer video kartı belleğidir. Bu değerin küçültülmesi performansı artırabilir, ama ayrıca dokuları bulanıklaştırabilir."/>
<spinner label="Sis Mesafe Oranı:" name="fog"/>
<button label="Tamam" label_selected="Tamam" name="OK"/>
diff --git a/indra/newview/skins/default/xui/tr/floater_help_browser.xml b/indra/newview/skins/default/xui/tr/floater_help_browser.xml
index 695f838936..695f838936 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_help_browser.xml
+++ b/indra/newview/skins/default/xui/tr/floater_help_browser.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_how_to.xml b/indra/newview/skins/default/xui/tr/floater_how_to.xml
index a42fe0b122..a42fe0b122 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_how_to.xml
+++ b/indra/newview/skins/default/xui/tr/floater_how_to.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_hud.xml b/indra/newview/skins/default/xui/tr/floater_hud.xml
index 09f119bbc1..09f119bbc1 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_hud.xml
+++ b/indra/newview/skins/default/xui/tr/floater_hud.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_im_container.xml b/indra/newview/skins/default/xui/tr/floater_im_container.xml
index 4451d1d309..6504430b3c 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_im_container.xml
+++ b/indra/newview/skins/default/xui/tr/floater_im_container.xml
@@ -1,2 +1,29 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<multi_floater name="floater_im_box" title="SOHBETLER"/>
+<multi_floater name="floater_im_box" title="SOHBETLER">
+ <string name="collapse_icon" value="Conv_toolbar_collapse"/>
+ <string name="expand_icon" value="Conv_toolbar_expand"/>
+ <layout_stack name="conversations_stack">
+ <layout_panel name="conversations_layout_panel">
+ <layout_stack name="conversations_pane_buttons_stack">
+ <layout_panel name="conversations_pane_buttons_expanded">
+ <menu_button name="sort_btn" tool_tip="Gösterme/sıralama seçenekleri"/>
+ <button name="add_btn" tool_tip="Yeni bir sohbet baÅŸlat"/>
+ <button name="speak_btn" tool_tip="Mikrofonunuzu kullanarak kiÅŸilerle konuÅŸun"/>
+ </layout_panel>
+ <layout_panel name="conversations_pane_buttons_collapsed">
+ <button name="expand_collapse_btn" tool_tip="Bu listeyi Daralt/GeniÅŸlet"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ <layout_panel name="messages_layout_panel">
+ <panel_container name="im_box_tab_container">
+ <panel name="stub_panel">
+ <button name="stub_collapse_btn" tool_tip="Bu panoyu daralt"/>
+ <text name="stub_textbox">
+ Sohbet ayrı bir pencerede. [secondlife:/// Bunu geri getir.]
+ </text>
+ </panel>
+ </panel_container>
+ </layout_panel>
+ </layout_stack>
+</multi_floater>
diff --git a/indra/newview/skins/default/xui/tr/floater_im_session.xml b/indra/newview/skins/default/xui/tr/floater_im_session.xml
index bed08b36c6..52a10feeef 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/tr/floater_im_session.xml
@@ -1,8 +1,57 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="panel_im">
- <layout_stack name="im_panels">
- <layout_panel>
- <line_editor label="Kime" name="chat_editor"/>
- </layout_panel>
- </layout_stack>
+ <floater.string name="call_btn_start">
+ Conv_toolbar_open_call
+ </floater.string>
+ <floater.string name="call_btn_stop">
+ Conv_toolbar_hang_up
+ </floater.string>
+ <floater.string name="collapseline_icon" value="Conv_collapse_to_one_line"/>
+ <floater.string name="expandline_icon" value="Conv_expand_one_line"/>
+ <floater.string name="collapse_icon" value="Conv_toolbar_collapse"/>
+ <floater.string name="expand_icon" value="Conv_toolbar_expand"/>
+ <floater.string name="tear_off_icon" value="Conv_toolbar_arrow_ne"/>
+ <floater.string name="return_icon" value="Conv_toolbar_arrow_sw"/>
+ <floater.string name="participant_added" value="[NAME] sohbete davet edildi."/>
+ <floater.string name="multiple_participants_added" value="[NAME] sohbete davet edildi."/>
+ <floater.string name="tooltip_to_separate_window" value="Bu sohbeti ayrı bir pencereye taşı"/>
+ <floater.string name="tooltip_to_main_window" value="Bu sohbeti ana pencereye geri taşı"/>
+ <floater.string name="start_call_button_tooltip" value="Ses bağlantısını aç"/>
+ <floater.string name="end_call_button_tooltip" value="Ses bağlantısını kapat"/>
+ <floater.string name="expcol_button_not_tearoff_tooltip" value="Bu panoyu daralt"/>
+ <floater.string name="expcol_button_tearoff_and_expanded_tooltip" value="Katılımcı listesini daralt"/>
+ <floater.string name="expcol_button_tearoff_and_collapsed_tooltip" value="Katılımcı listesini genişlet"/>
+ <view name="contents_view">
+ <layout_stack name="main_stack">
+ <layout_panel name="toolbar_panel">
+ <menu_button name="view_options_btn" tool_tip="Gösterme/sıralama seçenekleri"/>
+ <menu_button name="gear_btn" tool_tip="Seçilen kişi üzerindeki eylemler"/>
+ <button name="add_btn" tool_tip="Bu sohbete birini ekle"/>
+ <button name="voice_call_btn" tool_tip="Ses bağlantısını aç"/>
+ <button name="close_btn" tool_tip="Bu sohbeti bitir"/>
+ <button name="expand_collapse_btn" tool_tip="Bu panoyu Daralt/GeniÅŸlet"/>
+ </layout_panel>
+ <layout_panel name="body_panel">
+ <layout_stack name="im_panels">
+ <layout_panel name="right_part_holder">
+ <layout_stack name="translate_and_chat_stack">
+ <layout_panel name="translate_chat_checkbox_lp">
+ <check_box label="Sohbeti çevir" name="translate_chat_checkbox"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ <layout_panel name="chat_layout_panel">
+ <layout_stack name="input_panels">
+ <layout_panel name="input_editor_layout_panel">
+ <chat_editor label="Kime" name="chat_editor"/>
+ </layout_panel>
+ <layout_panel name="input_button_layout_panel">
+ <button name="minz_btn" tool_tip="Mesaj panelini gösterir/gizler"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
+ </view>
</floater>
diff --git a/indra/newview/skins/default/xui/tr/floater_image_preview.xml b/indra/newview/skins/default/xui/tr/floater_image_preview.xml
index a5963bdf63..a5963bdf63 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_image_preview.xml
+++ b/indra/newview/skins/default/xui/tr/floater_image_preview.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_import_collada.xml b/indra/newview/skins/default/xui/tr/floater_import_collada.xml
index 1e77d1b376..1e77d1b376 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_import_collada.xml
+++ b/indra/newview/skins/default/xui/tr/floater_import_collada.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_incoming_call.xml b/indra/newview/skins/default/xui/tr/floater_incoming_call.xml
index adb03c2dff..0f2b27241e 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_incoming_call.xml
+++ b/indra/newview/skins/default/xui/tr/floater_incoming_call.xml
@@ -10,7 +10,7 @@
anonim
</floater.string>
<floater.string name="VoiceInviteP2P">
- arıyor.
+ sizi arıyor.
</floater.string>
<floater.string name="VoiceInviteAdHoc">
bir Sesli Sohbet aramasına bir konferans araması ile katıldı.
@@ -25,9 +25,9 @@
[CURRENT_CHAT] sohbetinden ayrılıp, bu sesli sohbete katılmak istiyor musunuz?
</floater.string>
<text name="question">
- [CURRENT_CHAT] sohbetinden ayrılıp, bu sesli sohbete katılmak istiyor musunuz?
+ Yanıtlarsanız, mevcut sesli sohbetinizle bağlantınız kesilecek.
</text>
- <button label="Kabul Et" label_selected="Kabul Et" name="Accept"/>
- <button label="Reddet" label_selected="Reddet" name="Reject"/>
- <button label="AÄ° BaÅŸlat" name="Start IM"/>
+ <button label="Yanıtla" label_selected="Yanıtla" name="Accept"/>
+ <button label="Yok say" label_selected="Yok say" name="Reject"/>
+ <button label="Bunun yerine Aİ aç" name="Start IM"/>
</floater>
diff --git a/indra/newview/skins/default/xui/tr/floater_inspect.xml b/indra/newview/skins/default/xui/tr/floater_inspect.xml
index 09130a31f3..09130a31f3 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_inspect.xml
+++ b/indra/newview/skins/default/xui/tr/floater_inspect.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_inventory.xml b/indra/newview/skins/default/xui/tr/floater_inventory.xml
deleted file mode 100644
index cfb12d4b68..0000000000
--- a/indra/newview/skins/default/xui/tr/floater_inventory.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Inventory" title="ENVANTERÄ°M">
- <panel label="Envanter Paneli" name="Inventory Panel"/>
-</floater>
diff --git a/indra/newview/skins/default/xui/tr/floater_inventory_item_properties.xml b/indra/newview/skins/default/xui/tr/floater_inventory_item_properties.xml
index e49fef1f46..e49fef1f46 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_inventory_item_properties.xml
+++ b/indra/newview/skins/default/xui/tr/floater_inventory_item_properties.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_inventory_view_finder.xml b/indra/newview/skins/default/xui/tr/floater_inventory_view_finder.xml
index 9d1a556751..9d1a556751 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_inventory_view_finder.xml
+++ b/indra/newview/skins/default/xui/tr/floater_inventory_view_finder.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_joystick.xml b/indra/newview/skins/default/xui/tr/floater_joystick.xml
index 4a27aac3c1..4a27aac3c1 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_joystick.xml
+++ b/indra/newview/skins/default/xui/tr/floater_joystick.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_lagmeter.xml b/indra/newview/skins/default/xui/tr/floater_lagmeter.xml
index 736c50be90..736c50be90 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_lagmeter.xml
+++ b/indra/newview/skins/default/xui/tr/floater_lagmeter.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_land_holdings.xml b/indra/newview/skins/default/xui/tr/floater_land_holdings.xml
index a075a93c1e..a075a93c1e 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_land_holdings.xml
+++ b/indra/newview/skins/default/xui/tr/floater_land_holdings.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_live_lsleditor.xml b/indra/newview/skins/default/xui/tr/floater_live_lsleditor.xml
index 34c3e28a0b..34c3e28a0b 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_live_lsleditor.xml
+++ b/indra/newview/skins/default/xui/tr/floater_live_lsleditor.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_lsl_guide.xml b/indra/newview/skins/default/xui/tr/floater_lsl_guide.xml
index 0b898d6032..0b898d6032 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_lsl_guide.xml
+++ b/indra/newview/skins/default/xui/tr/floater_lsl_guide.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_map.xml b/indra/newview/skins/default/xui/tr/floater_map.xml
index 7d6c314f04..7d6c314f04 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_map.xml
+++ b/indra/newview/skins/default/xui/tr/floater_map.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_media_browser.xml b/indra/newview/skins/default/xui/tr/floater_media_browser.xml
index 6cce4d59b8..6cce4d59b8 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_media_browser.xml
+++ b/indra/newview/skins/default/xui/tr/floater_media_browser.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_media_settings.xml b/indra/newview/skins/default/xui/tr/floater_media_settings.xml
index 4205a0dbef..4205a0dbef 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_media_settings.xml
+++ b/indra/newview/skins/default/xui/tr/floater_media_settings.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_mem_leaking.xml b/indra/newview/skins/default/xui/tr/floater_mem_leaking.xml
index ba87ee99a4..ba87ee99a4 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_mem_leaking.xml
+++ b/indra/newview/skins/default/xui/tr/floater_mem_leaking.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_merchant_outbox.xml b/indra/newview/skins/default/xui/tr/floater_merchant_outbox.xml
index 325d1d9ed9..325d1d9ed9 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_merchant_outbox.xml
+++ b/indra/newview/skins/default/xui/tr/floater_merchant_outbox.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_model_preview.xml b/indra/newview/skins/default/xui/tr/floater_model_preview.xml
index 0c7cabc6ea..c00cadd3bd 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_model_preview.xml
+++ b/indra/newview/skins/default/xui/tr/floater_model_preview.xml
@@ -92,19 +92,54 @@
<text initial_value="Üçgenler" name="triangles" value="Üçgenler"/>
<text initial_value="Köşeler" name="vertices" value="Köşeler"/>
<text initial_value="Yüksek" name="high_label" value="Yüksek"/>
+ <combo_box name="lod_source_high">
+ <item name="Load from file" value="Dosyadan yükle"/>
+ <item name="Generate" value="OluÅŸtur"/>
+ </combo_box>
<button label="Gözat..." name="lod_browse_high"/>
+ <combo_box name="lod_mode_high">
+ <item name="Triangle Limit" value="Üçgen Limiti"/>
+ <item name="Error Threshold" value="Hata EÅŸiÄŸi"/>
+ </combo_box>
<text initial_value="0" name="high_triangles" value="0"/>
<text initial_value="0" name="high_vertices" value="0"/>
<text initial_value="Orta" name="medium_label" value="Orta"/>
+ <combo_box name="lod_source_medium">
+ <item name="Load from file" value="Dosyadan yükle"/>
+ <item name="Generate" value="OluÅŸtur"/>
+ <item name="Use LoD above" value="Yukarıdaki ayrıntı seviyesini kullan"/>
+ </combo_box>
<button label="Gözat..." name="lod_browse_medium"/>
+ <combo_box name="lod_mode_medium">
+ <item name="Triangle Limit" value="Üçgen Limiti"/>
+ <item name="Error Threshold" value="Hata EÅŸiÄŸi"/>
+ </combo_box>
<text initial_value="0" name="medium_triangles" value="0"/>
<text initial_value="0" name="medium_vertices" value="0"/>
<text initial_value="Düşük" name="low_label" value="Düşük"/>
+ <combo_box name="lod_source_low">
+ <item name="Load from file" value="Dosyadan yükle"/>
+ <item name="Generate" value="OluÅŸtur"/>
+ <item name="Use LoD above" value="Yukarıdaki ayrıntı seviyesini kullan"/>
+ </combo_box>
<button label="Gözat..." name="lod_browse_low"/>
+ <combo_box name="lod_mode_low">
+ <item name="Triangle Limit" value="Üçgen Limiti"/>
+ <item name="Error Threshold" value="Hata EÅŸiÄŸi"/>
+ </combo_box>
<text initial_value="0" name="low_triangles" value="0"/>
<text initial_value="0" name="low_vertices" value="0"/>
<text initial_value="En Düşük" name="lowest_label" value="En Düşük"/>
+ <combo_box name="lod_source_lowest">
+ <item name="Load from file" value="Dosyadan yükle"/>
+ <item name="Generate" value="OluÅŸtur"/>
+ <item name="Use LoD above" value="Yukarıdaki ayrıntı seviyesini kullan"/>
+ </combo_box>
<button label="Gözat..." name="lod_browse_lowest"/>
+ <combo_box name="lod_mode_lowest">
+ <item name="Triangle Limit" value="Üçgen Limiti"/>
+ <item name="Error Threshold" value="Hata EÅŸiÄŸi"/>
+ </combo_box>
<text initial_value="0" name="lowest_triangles" value="0"/>
<text initial_value="0" name="lowest_vertices" value="0"/>
<check_box label="Normalleri OluÅŸtur" name="gen_normals"/>
diff --git a/indra/newview/skins/default/xui/tr/floater_model_wizard.xml b/indra/newview/skins/default/xui/tr/floater_model_wizard.xml
deleted file mode 100644
index 9d8b982c24..0000000000
--- a/indra/newview/skins/default/xui/tr/floater_model_wizard.xml
+++ /dev/null
@@ -1,208 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Model Wizard" title="KARÅžIYA MODEL YÃœKLEME SÄ°HÄ°RBAZI">
- <button label="5. Karşıya Yükle" name="upload_btn"/>
- <button label="4. Ä°ncele" name="review_btn"/>
- <button label="3. Fizik" name="physics_btn"/>
- <button label="2. Optimize et" name="optimize_btn"/>
- <button label="1. Dosya Seç" name="choose_file_btn"/>
- <panel name="choose_file_panel">
- <panel name="choose_file_header_panel">
- <text name="choose_file_header_text">
- Model dosyasını seçin
- </text>
- </panel>
- <panel name="choose_file_content">
- <text name="advanced_users_text">
- Gelişmiş kullanıcılar: Eğer 3B içerik oluşturma araçlarını kullanmayı biliyorsanız, Gelişmiş Karşıya Yükleyiciyi kullanmak isteyebilirsiniz.
- </text>
- <button label="Gelişmişe geç" name="switch_to_advanced"/>
- <text name="Cache location">
- Karşıya yüklenecek model dosyasını seçin
- </text>
- <button label="Gözat..." label_selected="Gözat..." name="browse"/>
- <text name="Model types">
- Second Life, COLLADA (.dae) dosyalarını destekler
- </text>
- <text name="dimensions">
- X Y Z
- </text>
- <text name="warning_label">
- UYARI:
- </text>
- <text name="warning_text">
- Bu modelin Second Life sunucularına nihai karşıya yükleme adımını tamamlayamayacaksınız. Hesabınızı örgü modellerinin karşıya yüklenmesi için ayarlamanın [secondlife:///app/floater/learn_more nasıl yapılacağını öğrenin].
- </text>
- </panel>
- </panel>
- <panel name="optimize_panel">
- <panel name="optimize_header_panel">
- <text name="optimize_header_text">
- Modeli optimize et
- </text>
- </panel>
- <text name="optimize_description">
- Modeli performans için optimize ettik. İstiyorsanız daha da ayarlayabilirsiniz.
- </text>
- <panel name="optimize_content">
- <text name="high_detail_text">
- Ayrıntı Seviyesi Oluştur: Yüksek
- </text>
- <text name="medium_detail_text">
- Ayrıntı Seviyesi Oluştur: Orta
- </text>
- <text name="low_detail_text">
- Ayrıntı Seviyesi Oluştur: Düşük
- </text>
- <text name="lowest_detail_text">
- Ayrıntı Seviyesi Oluştur: En Düşük
- </text>
- </panel>
- <panel name="content2">
- <button label="Geometri hesaplarını tekrar yap" name="recalculate_geometry_btn"/>
- <text name="lod_label">
- Geometri önizleme
- </text>
- <combo_box name="preview_lod_combo" tool_tip="Önizleme işlemesinde görülecek ayrıntı seviyesi">
- <combo_item name="high">
- Çok ayrıntı
- </combo_item>
- <combo_item name="medium">
- Orta düzey ayrıntı
- </combo_item>
- <combo_item name="low">
- Az ayrıntı
- </combo_item>
- <combo_item name="lowest">
- En az ayrıntı
- </combo_item>
- </combo_box>
- </panel>
- </panel>
- <panel name="physics_panel">
- <panel name="physics_header_panel">
- <text name="physics_header_text">
- Fizik ayarlarını yap
- </text>
- </panel>
- <text name="physics_description">
- Modelin dış gövdesi için bir şekil oluşturacağız. Modelinizin amacına uygun olarak şeklin ayrıntı seviyesini belirleyin.
- </text>
- <panel name="physics_content">
- <button label="Fizik hesaplarını tekrar yap" name="recalculate_physics_btn"/>
- <button label="Tekrar hesaplanıyor..." name="recalculating_physics_btn"/>
- <text name="lod_label">
- Fizik önizleme
- </text>
- <combo_box name="preview_lod_combo2" tool_tip="Önizleme işlemesinde görülecek ayrıntı seviyesi">
- <combo_item name="high">
- Çok ayrıntı
- </combo_item>
- <combo_item name="medium">
- Orta düzey ayrıntı
- </combo_item>
- <combo_item name="low">
- Az ayrıntı
- </combo_item>
- <combo_item name="lowest">
- En az ayrıntı
- </combo_item>
- </combo_box>
- </panel>
- </panel>
- <panel name="review_panel">
- <panel name="review_header_panel">
- <text name="review_header_text">
- Ä°ncele
- </text>
- </panel>
- <panel name="review_content">
- <text name="review_prim_equiv">
- Parsele/bölgeye etkisi: [EQUIV] prim eşdeğerleri
- </text>
- <text name="review_fee">
- Hesabınızdan L$ [FEE] karşıya yükleme ücreti düşülecektir.
- </text>
- <text name="review_confirmation">
- Karşıya yükleme düğmesine tıkladığınızda, modelde yer alan malzeme için ilgili haklara sahip olduğunuzu teyid edersiniz.
- </text>
- </panel>
- </panel>
- <panel name="upload_panel">
- <panel name="upload_header_panel">
- <text name="upload_header_text">
- Karşıya yükleme bitti
- </text>
- </panel>
- <text name="model_uploaded_text">
- Modeliniz karşıya yüklendi.
- </text>
- <text name="inventory_text">
- Bunu, envanterinizdeki Nesneler klasöründe bulacaksınız.
- </text>
- <text name="charged_fee">
- Hesabınızdan L$ [FEE] düşüldü.
- </text>
- </panel>
- <button label="&lt;&lt; Geri" name="back"/>
- <button label="Sonraki &gt;&gt;" name="next"/>
- <button label="Ağırlıkları ve ücreti hesapla &gt;&gt;" name="calculate"/>
- <button label="Hesaplanıyor..." name="calculating"/>
- <button label="Karşıya Yükle" name="upload" tool_tip="Simülatöre karşıya yükle"/>
- <button label="Ä°ptal" name="cancel"/>
- <button label="Kapat" name="close"/>
- <spinner name="import_scale" value="1.0"/>
- <string name="status_idle">
- BoÅŸta
- </string>
- <string name="status_parse_error">
- Dae ayrıştırma sorunu - ayrıntılar için günlüğe bakın.
- </string>
- <string name="status_reading_file">
- Yükleniyor...
- </string>
- <string name="status_generating_meshes">
- Örgüler Oluşturuluyor...
- </string>
- <string name="status_vertex_number_overflow">
- Hata: Köşe numarası 65534&apos;ten fazla, işlem durduruldu!
- </string>
- <string name="bad_element">
- Hata: Öğe geçersiz
- </string>
- <string name="high">
- Yüksek
- </string>
- <string name="medium">
- Orta
- </string>
- <string name="low">
- Düşük
- </string>
- <string name="lowest">
- En Düşük
- </string>
- <string name="mesh_status_good">
- Uygula!
- </string>
- <string name="mesh_status_na">
- G/D
- </string>
- <string name="mesh_status_none">
- Hiçbiri
- </string>
- <string name="mesh_status_submesh_mismatch">
- Ayrıntı seviyelerinde farklı sayıda dokulanabilir yüz var.
- </string>
- <string name="mesh_status_mesh_mismatch">
- Ayrıntı seviyelerinde farklı sayıda örgü örneği var.
- </string>
- <string name="mesh_status_too_many_vertices">
- Ayrıntı seviyesinde fazla sayıda köşe var.
- </string>
- <string name="mesh_status_missing_lod">
- Gereken ayrıntı seviyesi eksik.
- </string>
- <string name="layer_all">
- Tümü
- </string>
-</floater>
diff --git a/indra/newview/skins/default/xui/tr/floater_moveview.xml b/indra/newview/skins/default/xui/tr/floater_moveview.xml
index 9226218a24..9226218a24 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_moveview.xml
+++ b/indra/newview/skins/default/xui/tr/floater_moveview.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_mute_object.xml b/indra/newview/skins/default/xui/tr/floater_mute_object.xml
index becad38a8e..becad38a8e 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_mute_object.xml
+++ b/indra/newview/skins/default/xui/tr/floater_mute_object.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_my_appearance.xml b/indra/newview/skins/default/xui/tr/floater_my_appearance.xml
index 4d71187a1f..4d71187a1f 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_my_appearance.xml
+++ b/indra/newview/skins/default/xui/tr/floater_my_appearance.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_my_inventory.xml b/indra/newview/skins/default/xui/tr/floater_my_inventory.xml
index 8c62692a88..8c62692a88 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_my_inventory.xml
+++ b/indra/newview/skins/default/xui/tr/floater_my_inventory.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_nearby_chat.xml b/indra/newview/skins/default/xui/tr/floater_nearby_chat.xml
deleted file mode 100644
index 6b12ad0ef5..0000000000
--- a/indra/newview/skins/default/xui/tr/floater_nearby_chat.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="nearby_chat" title="YAKINDAKÄ° SOHBET">
- <check_box label="Sohbeti çevir" name="translate_chat_checkbox"/>
-</floater>
diff --git a/indra/newview/skins/default/xui/tr/floater_notification.xml b/indra/newview/skins/default/xui/tr/floater_notification.xml
index 89a56348f6..89a56348f6 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_notification.xml
+++ b/indra/newview/skins/default/xui/tr/floater_notification.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_notifications_console.xml b/indra/newview/skins/default/xui/tr/floater_notifications_console.xml
index e4eaf2cf9e..e4eaf2cf9e 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_notifications_console.xml
+++ b/indra/newview/skins/default/xui/tr/floater_notifications_console.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_object_weights.xml b/indra/newview/skins/default/xui/tr/floater_object_weights.xml
index b57943f666..b57943f666 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_object_weights.xml
+++ b/indra/newview/skins/default/xui/tr/floater_object_weights.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_openobject.xml b/indra/newview/skins/default/xui/tr/floater_openobject.xml
index 9980aee97f..9980aee97f 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_openobject.xml
+++ b/indra/newview/skins/default/xui/tr/floater_openobject.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_outfit_save_as.xml b/indra/newview/skins/default/xui/tr/floater_outfit_save_as.xml
index 7a9f507c93..7a9f507c93 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_outfit_save_as.xml
+++ b/indra/newview/skins/default/xui/tr/floater_outfit_save_as.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_outgoing_call.xml b/indra/newview/skins/default/xui/tr/floater_outgoing_call.xml
index 7ba4580f4f..7ba4580f4f 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_outgoing_call.xml
+++ b/indra/newview/skins/default/xui/tr/floater_outgoing_call.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_pathfinding_characters.xml b/indra/newview/skins/default/xui/tr/floater_pathfinding_characters.xml
new file mode 100755
index 0000000000..f38d8c84c6
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/floater_pathfinding_characters.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="floater_pathfinding_characters" title="Yol bulma karakterleri">
+ <floater.string name="messaging_get_inprogress">
+ Yol bulma karakterleri için sorgulama yapılıyor ...
+ </floater.string>
+ <floater.string name="messaging_get_error">
+ Yol bulma karakterleri için sorgulama yapılırken hata saptandı.
+ </floater.string>
+ <floater.string name="messaging_complete_none_found">
+ Yol bulma karakterleri yok.
+ </floater.string>
+ <floater.string name="messaging_complete_available">
+ Toplam [NUM_TOTAL] karakter içerisinden [NUM_SELECTED] adet seçildi.
+ </floater.string>
+ <floater.string name="messaging_not_enabled">
+ Bu bölgede yol bulma etkin değil.
+ </floater.string>
+ <floater.string name="character_cpu_time">
+ [CPU_TIME] µs
+ </floater.string>
+ <floater.string name="character_owner_loading">
+ [Yükleniyor]
+ </floater.string>
+ <floater.string name="character_owner_unknown">
+ [Bilinmiyor]
+ </floater.string>
+ <floater.string name="character_owner_group">
+ [grup]
+ </floater.string>
+ <panel>
+ <scroll_list name="objects_scroll_list">
+ <scroll_list.columns label="Ad" name="name"/>
+ <scroll_list.columns label="Açıklama" name="description"/>
+ <scroll_list.columns label="Sahip" name="owner"/>
+ <scroll_list.columns label="CPU" name="cpu_time"/>
+ <scroll_list.columns label="Ä°rtifa" name="altitude"/>
+ </scroll_list>
+ <text name="messaging_status">
+ Karakterler:
+ </text>
+ <button label="Listeyi yenile" name="refresh_objects_list"/>
+ <button label="Tümünü seç" name="select_all_objects"/>
+ <button label="Hiçbirini seçme" name="select_none_objects"/>
+ </panel>
+ <panel>
+ <text name="actions_label">
+ Seçilen karakterler üzerinde eylemler:
+ </text>
+ <check_box label="İşareti göster" name="show_beacon"/>
+ <check_box label="Fizik kapsülünü göster" name="show_physics_capsule"/>
+ <button label="Al" name="take_objects"/>
+ <button label="Kopya al" name="take_copy_objects"/>
+ <button label="Beni ona ışınla" name="teleport_me_to_object" tool_tip="Sadece bir karakter seçildiğinde etkindir."/>
+ <button label="Ä°ade Et" name="return_objects"/>
+ <button label="Sil" name="delete_objects"/>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/tr/floater_pathfinding_console.xml b/indra/newview/skins/default/xui/tr/floater_pathfinding_console.xml
new file mode 100755
index 0000000000..6eecc7fb77
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/floater_pathfinding_console.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="floater_pathfinding_console" title="Yol bulma görüntüleme / test">
+ <floater.string name="navmesh_viewer_status_library_not_implemented">
+ Yol bulma kütüphanesi uygulaması bulunamıyor.
+ </floater.string>
+ <floater.string name="navmesh_viewer_status_region_not_enabled">
+ Bu bölgede yol bulma etkin değil.
+ </floater.string>
+ <floater.string name="navmesh_viewer_status_region_loading">
+ Bölgenin yüklenmesinin bitmesi bekleniyor.
+ </floater.string>
+ <floater.string name="navmesh_viewer_status_checking_version">
+ Navigasyon örgüsünün durumu kontrol ediliyor.
+ </floater.string>
+ <floater.string name="navmesh_viewer_status_downloading">
+ Navigasyon örgüsü indiriliyor.
+ </floater.string>
+ <floater.string name="navmesh_viewer_status_updating">
+ Sunucudaki navigasyon örgüsü değişti. En son navigasyon örgüsü indiriliyor.
+ </floater.string>
+ <floater.string name="navmesh_viewer_status_has_navmesh">
+ En son navigasyon örgüsü indirildi.
+ </floater.string>
+ <floater.string name="navmesh_viewer_status_error">
+ Navigasyon örgüsü başarıyla indirilemedi.
+ </floater.string>
+ <floater.string name="navmesh_simulator_status_pending">
+ Navigasyon örgüsünde bekleyen değişiklikler var.
+ </floater.string>
+ <floater.string name="navmesh_simulator_status_building">
+ Navigasyon örgüsü oluşturuluyor.
+ </floater.string>
+ <floater.string name="navmesh_simulator_status_some_pending">
+ Bazı navigasyon örgüsü bölgelerinde bekleyen değişiklikler var.
+ </floater.string>
+ <floater.string name="navmesh_simulator_status_some_building">
+ Bazı navigasyon örgüsü bölgeleri oluşturuluyor.
+ </floater.string>
+ <floater.string name="navmesh_simulator_status_pending_and_building">
+ Bazı navigasyon örgüsü bölgelerinde bekleyen değişiklikler var, bazıları ise oluşturuluyor.
+ </floater.string>
+ <floater.string name="navmesh_simulator_status_complete">
+ Navigasyon örgüsü güncel.
+ </floater.string>
+ <floater.string name="pathing_library_not_implemented">
+ Yol bulma kütüphanesi uygulaması bulunamıyor.
+ </floater.string>
+ <floater.string name="pathing_region_not_enabled">
+ Bu bölgede yol bulma etkin değil.
+ </floater.string>
+ <floater.string name="pathing_choose_start_and_end_points">
+ Lütfen başlangıç ve bitim noktalarını seçin.
+ </floater.string>
+ <floater.string name="pathing_choose_start_point">
+ Lütfen başlangıç noktasını seçin.
+ </floater.string>
+ <floater.string name="pathing_choose_end_point">
+ Lütfen bitim noktasını seçin.
+ </floater.string>
+ <floater.string name="pathing_path_valid">
+ Yol turuncu olarak gösterilmiştir.
+ </floater.string>
+ <floater.string name="pathing_path_invalid">
+ Seçilen noktalar arasında bir yol bulunamıyor.
+ </floater.string>
+ <floater.string name="pathing_error">
+ Yol oluşturma sırasında bir hata meydana geldi.
+ </floater.string>
+ <tab_container name="view_test_tab_container">
+ <panel label="Görünüm" name="view_panel">
+ <text name="show_label">
+ Göster:
+ </text>
+ <check_box label="Dünya" name="show_world"/>
+ <check_box label="Sadece hareket ettirilebilir nesneler" name="show_world_movables_only"/>
+ <check_box label="Navigasyon örgüsü" name="show_navmesh"/>
+ <text name="show_walkability_label">
+ Yürüyebilirlik haritasını göster:
+ </text>
+ <combo_box name="show_heatmap_mode">
+ <combo_box.item label="Gösterme" name="show_heatmap_mode_none"/>
+ <combo_box.item label="A karakter tipi" name="show_heatmap_mode_a"/>
+ <combo_box.item label="B karakter tipi" name="show_heatmap_mode_b"/>
+ <combo_box.item label="C karakter tipi" name="show_heatmap_mode_c"/>
+ <combo_box.item label="D karakter tipi" name="show_heatmap_mode_d"/>
+ </combo_box>
+ <check_box label="Yürüyebilirler" name="show_walkables"/>
+ <check_box label="Maddi hacimler" name="show_material_volumes"/>
+ <check_box label="Statik engeller" name="show_static_obstacles"/>
+ <check_box label="Hariç tutma hacimleri" name="show_exclusion_volumes"/>
+ <check_box label="Su düzlemi" name="show_water_plane"/>
+ <check_box label="X-ışını görünümü ile" name="show_xray"/>
+ </panel>
+ <panel label="Yolu test et" name="test_panel">
+ <text name="ctrl_click_label">
+ Başlangıç noktasını seçmek için Ctrl tuşuna basarak tıklayın.
+ </text>
+ <text name="shift_click_label">
+ Bitim noktasını seçmek için Shift tuşuna basarak tıklayın.
+ </text>
+ <text name="character_width_label">
+ Karakter geniÅŸliÄŸi
+ </text>
+ <slider name="character_width" value="1"/>
+ <text name="character_width_unit_label">
+ m
+ </text>
+ <text name="character_type_label">
+ Karakter tipi
+ </text>
+ <combo_box name="path_character_type">
+ <combo_box.item label="Hiçbiri" name="path_character_type_none"/>
+ <combo_box.item label="A" name="path_character_type_a"/>
+ <combo_box.item label="B" name="path_character_type_b"/>
+ <combo_box.item label="C" name="path_character_type_c"/>
+ <combo_box.item label="D" name="path_character_type_d"/>
+ </combo_box>
+ <button label="Yolu temizle" name="clear_path"/>
+ </panel>
+ </tab_container>
+</floater>
diff --git a/indra/newview/skins/default/xui/tr/floater_pathfinding_linksets.xml b/indra/newview/skins/default/xui/tr/floater_pathfinding_linksets.xml
new file mode 100755
index 0000000000..2e416c9311
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/floater_pathfinding_linksets.xml
@@ -0,0 +1,167 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="floater_pathfinding_linksets" title="Yol bulma bağlantı kümeleri">
+ <floater.string name="messaging_get_inprogress">
+ Yol bulma bağlantı kümeleri için sorgulama yapılıyor ...
+ </floater.string>
+ <floater.string name="messaging_get_error">
+ Yol bulma bağlantı kümeleri için sorgulama yapılırken hata saptandı.
+ </floater.string>
+ <floater.string name="messaging_set_inprogress">
+ Seçilen yol bulma bağlantı kümeleri değiştiriliyor ...
+ </floater.string>
+ <floater.string name="messaging_set_error">
+ Seçilen yol bulma bağlantı kümeleri değiştirilirken hata saptandı.
+ </floater.string>
+ <floater.string name="messaging_complete_none_found">
+ Yol bulma bağlantı kümeleri yok.
+ </floater.string>
+ <floater.string name="messaging_complete_available">
+ Toplam [NUM_TOTAL] bağlantı kümesi içerisinden [NUM_SELECTED] adet seçildi.
+ </floater.string>
+ <floater.string name="messaging_not_enabled">
+ Bu bölgede yol bulma etkin değil.
+ </floater.string>
+ <floater.string name="linkset_terrain_name">
+ [Yüzey]
+ </floater.string>
+ <floater.string name="linkset_terrain_description">
+ --
+ </floater.string>
+ <floater.string name="linkset_terrain_owner">
+ --
+ </floater.string>
+ <floater.string name="linkset_terrain_scripted">
+ --
+ </floater.string>
+ <floater.string name="linkset_terrain_land_impact">
+ --
+ </floater.string>
+ <floater.string name="linkset_terrain_dist_from_you">
+ --
+ </floater.string>
+ <floater.string name="linkset_owner_loading">
+ [Yükleniyor]
+ </floater.string>
+ <floater.string name="linkset_owner_unknown">
+ [Bilinmiyor]
+ </floater.string>
+ <floater.string name="linkset_owner_group">
+ [grup]
+ </floater.string>
+ <floater.string name="linkset_is_scripted">
+ Evet
+ </floater.string>
+ <floater.string name="linkset_is_not_scripted">
+ Hayır
+ </floater.string>
+ <floater.string name="linkset_is_unknown_scripted">
+ Bilinmiyor
+ </floater.string>
+ <floater.string name="linkset_use_walkable">
+ Yürüyebilir
+ </floater.string>
+ <floater.string name="linkset_use_static_obstacle">
+ Statik engel
+ </floater.string>
+ <floater.string name="linkset_use_dynamic_obstacle">
+ Hareket ettirilebilir engel
+ </floater.string>
+ <floater.string name="linkset_use_material_volume">
+ Maddi hacim
+ </floater.string>
+ <floater.string name="linkset_use_exclusion_volume">
+ Hariç tutma hacmi
+ </floater.string>
+ <floater.string name="linkset_use_dynamic_phantom">
+ Hareket ettirilebilir fantom
+ </floater.string>
+ <floater.string name="linkset_is_terrain">
+ [deÄŸiÅŸtirilemez]
+ </floater.string>
+ <floater.string name="linkset_is_restricted_state">
+ [kısıtlı]
+ </floater.string>
+ <floater.string name="linkset_is_non_volume_state">
+ [konkav]
+ </floater.string>
+ <floater.string name="linkset_is_restricted_non_volume_state">
+ [kısıtlı, konkav]
+ </floater.string>
+ <floater.string name="linkset_choose_use">
+ Bağlantı kümesi kullanımını seç...
+ </floater.string>
+ <panel>
+ <combo_box name="filter_by_linkset_use">
+ <combo_box.item label="Bağlantı kümesi kullanımına göre filtrele..." name="filter_by_linkset_use_none"/>
+ <combo_box.item label="Yürüyebilir" name="filter_by_linkset_use_walkable"/>
+ <combo_box.item label="Statik engel" name="filter_by_linkset_use_static_obstacle"/>
+ <combo_box.item label="Hareket ettirilebilir engel" name="filter_by_linkset_use_dynamic_obstacle"/>
+ <combo_box.item label="Maddi hacim" name="filter_by_linkset_use_material_volume"/>
+ <combo_box.item label="Hariç tutma hacmi" name="filter_by_linkset_use_exclusion_volume"/>
+ <combo_box.item label="Hareket ettirilebilir fantom" name="filter_by_linkset_use_dynamic_phantom"/>
+ </combo_box>
+ <button label="Uygula" name="apply_filters"/>
+ <button label="Temizle" name="clear_filters"/>
+ <scroll_list name="objects_scroll_list">
+ <scroll_list.columns label="Ad (kök prim)" name="name"/>
+ <scroll_list.columns label="Açıklama (kök prim)" name="description"/>
+ <scroll_list.columns label="Sahip" name="owner"/>
+ <scroll_list.columns label="Komut Dosyalı" name="scripted"/>
+ <scroll_list.columns label="Etki" name="land_impact"/>
+ <scroll_list.columns label="Mesafe" name="dist_from_you"/>
+ <scroll_list.columns label="Bağlantı kümesi kullanımı" name="linkset_use"/>
+ <scroll_list.columns label="% A" name="a_percent"/>
+ <scroll_list.columns label="% B" name="b_percent"/>
+ <scroll_list.columns label="% C" name="c_percent"/>
+ <scroll_list.columns label="% D" name="d_percent"/>
+ </scroll_list>
+ <text name="messaging_status">
+ Bağlantı kümeleri:
+ </text>
+ <button label="Listeyi yenile" name="refresh_objects_list"/>
+ <button label="Tümünü seç" name="select_all_objects"/>
+ <button label="Hiçbirini seçme" name="select_none_objects"/>
+ </panel>
+ <panel>
+ <check_box label="İşareti göster" name="show_beacon"/>
+ <button label="Al" name="take_objects"/>
+ <button label="Kopya al" name="take_copy_objects"/>
+ <button label="Beni ona ışınla" name="teleport_me_to_object"/>
+ <button label="Ä°ade Et" name="return_objects"/>
+ <button label="Sil" name="delete_objects"/>
+ </panel>
+ <panel>
+ <text name="walkability_coefficients_label">
+ Yürüyebilirlik:
+ </text>
+ <text name="edit_a_label">
+ A
+ </text>
+ <line_editor name="edit_a_value" tool_tip="A tipi karakterleri için yürüyebilirlik. Örnek karakter tipi humanoiddir."/>
+ <text name="edit_b_label">
+ B
+ </text>
+ <line_editor name="edit_b_value" tool_tip="B tipi karakterleri için yürüyebilirlik. Örnek karakter tipi yaratıktır."/>
+ <text name="edit_c_label">
+ C
+ </text>
+ <line_editor name="edit_c_value" tool_tip="C tipi karakterleri için yürüyebilirlik. Örnek karakter tipi mekaniktir."/>
+ <text name="edit_d_label">
+ D
+ </text>
+ <line_editor name="edit_d_value" tool_tip="D tipi karakterleri için yürüyebilirlik. Örnek karakter tipi diğerdir."/>
+ <button label="DeÄŸiÅŸiklikleri uygula" name="apply_edit_values"/>
+ <text name="suggested_use_a_label">
+ (Humanoid)
+ </text>
+ <text name="suggested_use_b_label">
+ (Yaratık)
+ </text>
+ <text name="suggested_use_c_label">
+ (Mekanik)
+ </text>
+ <text name="suggested_use_d_label">
+ (DiÄŸer)
+ </text>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/tr/floater_pay.xml b/indra/newview/skins/default/xui/tr/floater_pay.xml
index 6604e5c37a..6604e5c37a 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_pay.xml
+++ b/indra/newview/skins/default/xui/tr/floater_pay.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_pay_object.xml b/indra/newview/skins/default/xui/tr/floater_pay_object.xml
index 7772d3b101..7772d3b101 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_pay_object.xml
+++ b/indra/newview/skins/default/xui/tr/floater_pay_object.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_people.xml b/indra/newview/skins/default/xui/tr/floater_people.xml
index 94a27bff57..94a27bff57 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_people.xml
+++ b/indra/newview/skins/default/xui/tr/floater_people.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_perm_prefs.xml b/indra/newview/skins/default/xui/tr/floater_perm_prefs.xml
index 669b833c26..669b833c26 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_perm_prefs.xml
+++ b/indra/newview/skins/default/xui/tr/floater_perm_prefs.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_picks.xml b/indra/newview/skins/default/xui/tr/floater_picks.xml
index 513a2e319a..513a2e319a 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_picks.xml
+++ b/indra/newview/skins/default/xui/tr/floater_picks.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_places.xml b/indra/newview/skins/default/xui/tr/floater_places.xml
index 4e09a699f6..4e09a699f6 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_places.xml
+++ b/indra/newview/skins/default/xui/tr/floater_places.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_post_process.xml b/indra/newview/skins/default/xui/tr/floater_post_process.xml
index 5e419f8ffa..5e419f8ffa 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_post_process.xml
+++ b/indra/newview/skins/default/xui/tr/floater_post_process.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_postcard.xml b/indra/newview/skins/default/xui/tr/floater_postcard.xml
deleted file mode 100644
index ef11c68afe..0000000000
--- a/indra/newview/skins/default/xui/tr/floater_postcard.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Postcard" title="ANLIK GÖRÜNTÜYÜ E-POSTAYLA GÖNDER">
- <floater.string name="default_subject">
- SECOND_LIFE]&apos;dan posta kartı.
- </floater.string>
- <floater.string name="default_message">
- Buna bakın!
- </floater.string>
- <floater.string name="upload_message">
- Gönderiyor...
- </floater.string>
- <text name="to_label">
- Alıcının E-postası:
- </text>
- <text name="from_label">
- E-postanız:
- </text>
- <text name="name_label">
- Adınız:
- </text>
- <text name="subject_label">
- Konu:
- </text>
- <line_editor label="Konunuzu buraya yazın." name="subject_form"/>
- <text name="msg_label">
- Ä°leti:
- </text>
- <text_editor name="msg_form">
- İletinizi buraya yazın.
- </text_editor>
- <button label="Ä°ptal" name="cancel_btn"/>
- <button label="Gönder" name="send_btn"/>
-</floater>
diff --git a/indra/newview/skins/default/xui/tr/floater_preferences.xml b/indra/newview/skins/default/xui/tr/floater_preferences.xml
index edb3c19b81..edb3c19b81 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_preferences.xml
+++ b/indra/newview/skins/default/xui/tr/floater_preferences.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_preferences_proxy.xml b/indra/newview/skins/default/xui/tr/floater_preferences_proxy.xml
index 1c462e6ebf..1c462e6ebf 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_preferences_proxy.xml
+++ b/indra/newview/skins/default/xui/tr/floater_preferences_proxy.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_preview_animation.xml b/indra/newview/skins/default/xui/tr/floater_preview_animation.xml
index 23b4848333..23b4848333 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_preview_animation.xml
+++ b/indra/newview/skins/default/xui/tr/floater_preview_animation.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_preview_gesture.xml b/indra/newview/skins/default/xui/tr/floater_preview_gesture.xml
index dc6f66f657..dc6f66f657 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_preview_gesture.xml
+++ b/indra/newview/skins/default/xui/tr/floater_preview_gesture.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_preview_notecard.xml b/indra/newview/skins/default/xui/tr/floater_preview_notecard.xml
index 23391249d1..23391249d1 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_preview_notecard.xml
+++ b/indra/newview/skins/default/xui/tr/floater_preview_notecard.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_preview_sound.xml b/indra/newview/skins/default/xui/tr/floater_preview_sound.xml
index 50874f024a..50874f024a 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_preview_sound.xml
+++ b/indra/newview/skins/default/xui/tr/floater_preview_sound.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_preview_texture.xml b/indra/newview/skins/default/xui/tr/floater_preview_texture.xml
index 79e184130a..79e184130a 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_preview_texture.xml
+++ b/indra/newview/skins/default/xui/tr/floater_preview_texture.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_price_for_listing.xml b/indra/newview/skins/default/xui/tr/floater_price_for_listing.xml
index 5cdd25b64c..5cdd25b64c 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_price_for_listing.xml
+++ b/indra/newview/skins/default/xui/tr/floater_price_for_listing.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_publish_classified.xml b/indra/newview/skins/default/xui/tr/floater_publish_classified.xml
index 572892667b..572892667b 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_publish_classified.xml
+++ b/indra/newview/skins/default/xui/tr/floater_publish_classified.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_region_debug_console.xml b/indra/newview/skins/default/xui/tr/floater_region_debug_console.xml
index e2a5e8e86a..e2a5e8e86a 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_region_debug_console.xml
+++ b/indra/newview/skins/default/xui/tr/floater_region_debug_console.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_region_info.xml b/indra/newview/skins/default/xui/tr/floater_region_info.xml
index 2b2e00161b..2b2e00161b 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_region_info.xml
+++ b/indra/newview/skins/default/xui/tr/floater_region_info.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_report_abuse.xml b/indra/newview/skins/default/xui/tr/floater_report_abuse.xml
index c5765883c4..c5765883c4 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_report_abuse.xml
+++ b/indra/newview/skins/default/xui/tr/floater_report_abuse.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_script_debug.xml b/indra/newview/skins/default/xui/tr/floater_script_debug.xml
index baf0aabd85..baf0aabd85 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_script_debug.xml
+++ b/indra/newview/skins/default/xui/tr/floater_script_debug.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_script_debug_panel.xml b/indra/newview/skins/default/xui/tr/floater_script_debug_panel.xml
index e70a30fa24..e70a30fa24 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_script_debug_panel.xml
+++ b/indra/newview/skins/default/xui/tr/floater_script_debug_panel.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_script_limits.xml b/indra/newview/skins/default/xui/tr/floater_script_limits.xml
index 875599bde3..875599bde3 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_script_limits.xml
+++ b/indra/newview/skins/default/xui/tr/floater_script_limits.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_script_preview.xml b/indra/newview/skins/default/xui/tr/floater_script_preview.xml
index e193f7c1af..e193f7c1af 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_script_preview.xml
+++ b/indra/newview/skins/default/xui/tr/floater_script_preview.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_script_queue.xml b/indra/newview/skins/default/xui/tr/floater_script_queue.xml
index c1d98b717a..c1d98b717a 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_script_queue.xml
+++ b/indra/newview/skins/default/xui/tr/floater_script_queue.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_script_search.xml b/indra/newview/skins/default/xui/tr/floater_script_search.xml
index 54b1d20c8c..54b1d20c8c 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_script_search.xml
+++ b/indra/newview/skins/default/xui/tr/floater_script_search.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_search.xml b/indra/newview/skins/default/xui/tr/floater_search.xml
index 08c1e5162c..08c1e5162c 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_search.xml
+++ b/indra/newview/skins/default/xui/tr/floater_search.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_select_key.xml b/indra/newview/skins/default/xui/tr/floater_select_key.xml
index b828672ec2..b828672ec2 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_select_key.xml
+++ b/indra/newview/skins/default/xui/tr/floater_select_key.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_sell_land.xml b/indra/newview/skins/default/xui/tr/floater_sell_land.xml
index 9bea1e120e..9bea1e120e 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_sell_land.xml
+++ b/indra/newview/skins/default/xui/tr/floater_sell_land.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_settings_debug.xml b/indra/newview/skins/default/xui/tr/floater_settings_debug.xml
index 65264c57d7..65264c57d7 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_settings_debug.xml
+++ b/indra/newview/skins/default/xui/tr/floater_settings_debug.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_snapshot.xml b/indra/newview/skins/default/xui/tr/floater_snapshot.xml
index fa51f15d16..fa51f15d16 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_snapshot.xml
+++ b/indra/newview/skins/default/xui/tr/floater_snapshot.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_sound_devices.xml b/indra/newview/skins/default/xui/tr/floater_sound_devices.xml
index 470a222d7e..470a222d7e 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_sound_devices.xml
+++ b/indra/newview/skins/default/xui/tr/floater_sound_devices.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_sound_preview.xml b/indra/newview/skins/default/xui/tr/floater_sound_preview.xml
index 1938f184b3..1938f184b3 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_sound_preview.xml
+++ b/indra/newview/skins/default/xui/tr/floater_sound_preview.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_spellcheck.xml b/indra/newview/skins/default/xui/tr/floater_spellcheck.xml
new file mode 100755
index 0000000000..f5f0ba8fd9
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/floater_spellcheck.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="spellcheck_floater" title="Yazım Denetimcisi Ayarları">
+ <check_box label="Yazım denetimcisini etkinleştir" name="spellcheck_enable"/>
+ <text name="spellcheck_main">
+ Ana sözlük :
+ </text>
+ <text label="Günlükler:" name="spellcheck_additional">
+ İlave sözlükler :
+ </text>
+ <text name="spellcheck_available">
+ Mevcut
+ </text>
+ <text name="spellcheck_active">
+ Etkin
+ </text>
+ <button label="Kaldır" name="spellcheck_remove_btn"/>
+ <button label="İçeri Aktar..." name="spellcheck_import_btn"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/tr/floater_spellcheck_import.xml b/indra/newview/skins/default/xui/tr/floater_spellcheck_import.xml
new file mode 100755
index 0000000000..ded71cad40
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/floater_spellcheck_import.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="spellcheck_import" title="Sözlüğü İçeri Aktar">
+ <button label="Gözat" label_selected="Gözat" name="dictionary_path_browse"/>
+ <button label="İçeri Aktar" name="ok_btn"/>
+ <button label="Ä°ptal" name="cancel_btn"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/tr/floater_stats.xml b/indra/newview/skins/default/xui/tr/floater_stats.xml
index 17f1166c46..afce87bdaa 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_stats.xml
+++ b/indra/newview/skins/default/xui/tr/floater_stats.xml
@@ -14,8 +14,11 @@
<stat_bar label="Saniyede Bir Çizilen Üçgenler" name="ktrissec"/>
<stat_bar label="Toplam Nesne" name="objs"/>
<stat_bar label="Yeni Nesne" name="newobjs"/>
+ <stat_bar label="Nesne Önbellek İsabet Oranı" name="object_cache_hits"/>
</stat_view>
<stat_view label="Doku" name="texture">
+ <stat_bar label="Önbellek İsabet Oranı" name="texture_cache_hits"/>
+ <stat_bar label="Önbellek Okuma Gecikme Süresi" name="texture_cache_read_latency"/>
<stat_bar label="Sayım" name="numimagesstat"/>
<stat_bar label="Ham Sayım" name="numrawimagesstat"/>
<stat_bar label="GL BelleÄŸi" name="gltexmemstat"/>
@@ -50,7 +53,13 @@
<stat_bar label="Nesneler" name="simobjects"/>
<stat_bar label="Etkin Nesneler" name="simactiveobjects"/>
<stat_bar label="Etkin Komut Dosyaları" name="simactivescripts"/>
+ <stat_bar label="Çalıştırılan Komut Dosyaları" name="simpctscriptsrun"/>
<stat_bar label="Komut Dosyası Etkinlikleri" name="simscripteps"/>
+ <stat_view label="Yol bulma" name="simpathfinding">
+ <stat_bar label="Yapay Zeka Adım Süresi" name="simsimaistepmsec"/>
+ <stat_bar label="Atlanan Siluet Adımları" name="simsimskippedsilhouettesteps"/>
+ <stat_bar label="Güncellenen Karakterler" name="simsimpctsteppedcharacters"/>
+ </stat_view>
<stat_bar label="Gelen Paketler" name="siminpps"/>
<stat_bar label="Giden Paketler" name="simoutpps"/>
<stat_bar label="Bekleyen Karşıdan Yüklemeler" name="simpendingdownloads"/>
diff --git a/indra/newview/skins/default/xui/tr/floater_sys_well.xml b/indra/newview/skins/default/xui/tr/floater_sys_well.xml
index 301d9af063..301d9af063 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_sys_well.xml
+++ b/indra/newview/skins/default/xui/tr/floater_sys_well.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_telehub.xml b/indra/newview/skins/default/xui/tr/floater_telehub.xml
index 2cdb464ed0..2cdb464ed0 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_telehub.xml
+++ b/indra/newview/skins/default/xui/tr/floater_telehub.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_test_layout_stacks.xml b/indra/newview/skins/default/xui/tr/floater_test_layout_stacks.xml
index b479d5f6d6..b479d5f6d6 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_test_layout_stacks.xml
+++ b/indra/newview/skins/default/xui/tr/floater_test_layout_stacks.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_test_text_vertical_aligment.xml b/indra/newview/skins/default/xui/tr/floater_test_text_vertical_aligment.xml
index fcb7d87287..fcb7d87287 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_test_text_vertical_aligment.xml
+++ b/indra/newview/skins/default/xui/tr/floater_test_text_vertical_aligment.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/tr/floater_texture_ctrl.xml
index 4ef789f585..42483c09e1 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_texture_ctrl.xml
+++ b/indra/newview/skins/default/xui/tr/floater_texture_ctrl.xml
@@ -9,15 +9,27 @@
<text name="Multiple">
Birden çok doku
</text>
+ <radio_group name="mode_selection">
+ <radio_item label="Envanter" name="inventory" value="0"/>
+ <radio_item label="Yerel" name="local" value="1"/>
+ </radio_group>
<text name="unknown">
Büyüklük: [DIMENSIONS]
</text>
<button label="Varsayılan" label_selected="Varsayılan" name="Default"/>
- <button label="Hiçbiri" label_selected="Hiçbiri" name="None"/>
<button label="BoÅŸ" label_selected="BoÅŸ" name="Blank"/>
+ <button label="Hiçbiri" label_selected="Hiçbiri" name="None"/>
<check_box initial_value="true" label="Åžimdi uygula" name="apply_immediate_check"/>
+ <text name="preview_disabled" value="Önizleme Devre Dışı"/>
<filter_editor label="Dokuları Filtrele" name="inventory search editor"/>
<check_box initial_value="false" label="Klasörleri göster" name="show_folders_check"/>
+ <button label="Ekle" label_selected="Ekle" name="l_add_btn"/>
+ <button label="Kaldır" label_selected="Kaldır" name="l_rem_btn"/>
+ <button label="Karşıya Yükle" label_selected="Karşıya Yükle" name="l_upl_btn"/>
+ <scroll_list name="l_name_list">
+ <column label="Ad" name="unit_name"/>
+ <column label="Kimlik" name="unit_id_HIDDEN"/>
+ </scroll_list>
<button label="Tamam" label_selected="Tamam" name="Select"/>
<button label="Ä°ptal" label_selected="Ä°ptal" name="Cancel"/>
</floater>
diff --git a/indra/newview/skins/default/xui/tr/floater_texture_fetch_debugger.xml b/indra/newview/skins/default/xui/tr/floater_texture_fetch_debugger.xml
new file mode 100755
index 0000000000..42426225c7
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/floater_texture_fetch_debugger.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="TexFetchDebugger" title="Doku Alımı Hata Ayıklayıcı">
+ <text name="total_num_fetched_label">
+ 1, Alınan dokuların toplam sayısı: [NUM]
+ </text>
+ <text name="total_num_fetching_requests_label">
+ 2, Toplam alım talebi sayısı: [NUM]
+ </text>
+ <text name="total_num_cache_hits_label">
+ 3, Toplam önbellek isabet sayısı: [NUM]
+ </text>
+ <text name="total_num_visible_tex_label">
+ 4, Görünür dokuların toplam sayısı: [NUM]
+ </text>
+ <text name="total_num_visible_tex_fetch_req_label">
+ 5, Görünür dokuların alınması için toplam talep sayısı: [NUM]
+ </text>
+ <text name="total_fetched_data_label">
+ 6, Alınan verilerin toplam sayısı: [SIZE1]KB, Şifresi Çözülen Veri: [SIZE2]KB, [PIXEL]MPiksel
+ </text>
+ <text name="total_fetched_vis_data_label">
+ 7, Görünür verilerin toplam sayısı: [SIZE1]KB, Şifresi Çözülen Veri: [SIZE2]KB
+ </text>
+ <text name="total_fetched_rendered_data_label">
+ 8, İşlenen verilerin toplam sayısı: [SIZE1]KB, Şifresi Çözülen Veri: [SIZE2]KB, [PIXEL]MPiksel
+ </text>
+ <text name="total_time_cache_read_label">
+ 9, Önbellek okunması için toplam süre: [TIME] saniye
+ </text>
+ <text name="total_time_cache_write_label">
+ 10, Önbellek yazılması için toplam süre: [TIME] saniye
+ </text>
+ <text name="total_time_decode_label">
+ 11, Şifre çözülmesi için toplam süre: [TIME] saniye
+ </text>
+ <text name="total_time_gl_label">
+ 12, GL doku oluşturma için toplam süre: [TIME] saniye
+ </text>
+ <text name="total_time_http_label">
+ 13, HTTP alımı için toplam süre: [TIME] saniye
+ </text>
+ <text name="total_time_fetch_label">
+ 14, Tüm alımlar için toplam süre: [TIME] saniye
+ </text>
+ <text name="total_time_refetch_vis_cache_label">
+ 15, Görünür dokuların önbellekten tekrar alınması, Süre: [TIME] saniye, Alınan: [SIZE]KB, [PIXEL]MPiksel
+ </text>
+ <text name="total_time_refetch_all_cache_label">
+ 16, Tüm dokuların önbellekten tekrar alınması, Süre: [TIME] saniye, Alınan: [SIZE]KB, [PIXEL]MPiksel
+ </text>
+ <text name="total_time_refetch_vis_http_label">
+ 17, Görünür dokuların HTTP&apos;den tekrar alınması, Süre: [TIME] saniye, Alınan: [SIZE]KB, [PIXEL]MPiksel
+ </text>
+ <text name="total_time_refetch_all_http_label">
+ 18, Tüm dokuların HTTP&apos;den tekrar alınması, Süre: [TIME] saniye, Alınan: [SIZE]KB, [PIXEL]MPiksel
+ </text>
+ <spinner label="19, Teksel/Piksel Oranı:" name="texel_pixel_ratio"/>
+ <text name="texture_source_label">
+ 20, Doku Kaynağı:
+ </text>
+ <radio_group name="texture_source">
+ <radio_item label="Önbellek + HTTP" name="0"/>
+ <radio_item label="Sadece HTTP" name="1"/>
+ </radio_group>
+ <button label="BaÅŸla" name="start_btn"/>
+ <button label="Sıfırla" name="clear_btn"/>
+ <button label="Kapat" name="close_btn"/>
+ <button label="Önbellek Okunması" name="cacheread_btn"/>
+ <button label="Önbellek Yazılması" name="cachewrite_btn"/>
+ <button label="HTTP" name="http_btn"/>
+ <button label="Şifre Çöz" name="decode_btn"/>
+ <button label="GL Dokusu" name="gl_btn"/>
+ <button label="Görünür Dokuları Önbellekten Tekrar Al" name="refetchviscache_btn"/>
+ <button label="Tüm Önbelleği Tekrar Al" name="refetchallcache_btn"/>
+ <button label="Görünür Dokuları HTTP&apos;den Tekrar Al" name="refetchvishttp_btn"/>
+ <button label="Tüm HTTP&apos;yi Tekrar Al" name="refetchallhttp_btn"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/tr/floater_tools.xml b/indra/newview/skins/default/xui/tr/floater_tools.xml
index b0c59ced42..39a3569efa 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_tools.xml
+++ b/indra/newview/skins/default/xui/tr/floater_tools.xml
@@ -150,6 +150,12 @@
<panel.string name="text modify info 4">
Bu nesneleri deÄŸiÅŸtiremezsiniz
</panel.string>
+ <panel.string name="text modify info 5">
+ Bir bölge sınırı üzerinden bu nesneyi değiştiremezsiniz
+ </panel.string>
+ <panel.string name="text modify info 6">
+ Bir bölge sınırı üzerinden bu nesneleri değiştiremezsiniz
+ </panel.string>
<panel.string name="text modify warning">
İzinleri ayarlamak için tüm nesneyi seçmelisiniz
</panel.string>
@@ -199,12 +205,12 @@
<combo_box.item label="Yakınlaştır" name="Zoom"/>
</combo_box>
<check_box label="Satılık:" name="checkbox for sale"/>
+ <spinner label="L$" name="Edit Cost"/>
<combo_box name="sale type">
<combo_box.item label="Kopyala" name="Copy"/>
<combo_box.item label="İçerik" name="Contents"/>
<combo_box.item label="Orijinal" name="Original"/>
</combo_box>
- <spinner label="Fiyat: L$" name="Edit Cost"/>
<check_box label="Aramada göster" name="search_check" tool_tip="Kişiler arama sonuçlarında bu nesneyi görebilsin"/>
<panel name="perms_build">
<text name="perm_modify">
@@ -240,6 +246,11 @@
F:
</text>
</panel>
+ <panel name="pathfinding_attrs_panel">
+ <text name="pathfinding_attributes_label">
+ Yol bulma özellikleri:
+ </text>
+ </panel>
</panel>
<panel label="Nesne" name="Object">
<check_box label="Kilitli" name="checkbox locked" tool_tip="Nesnenin hareket ettirilmesini veya silinmesini engeller. Arzulanmayan düzenlemelerden kaçınmak için inşa işlemleri sırasında oldukça faydalıdır."/>
@@ -454,16 +465,11 @@
<combo_box.item label="vakum" name="suction"/>
<combo_box.item label="örgü" name="weave"/>
</combo_box>
- <check_box initial_value="false" label="Planar yüzleri hizala" name="checkbox planar align" tool_tip="Tüm seçili yüzeylerdeki dokuları son seçili yüzdekiyle hizalar. Planar doku eşleştirmesi gerektirir."/>
- <text name="rpt">
- Tekrarlar / Yüz
- </text>
<spinner label="Yatay (U)" name="TexScaleU"/>
<check_box label="Çevir" name="checkbox flip s"/>
<spinner label="Dikey (V)" name="TexScaleV"/>
<check_box label="Çevir" name="checkbox flip t"/>
<spinner label="Döndürme*" name="TexRot"/>
- <spinner label="Tekrarlar / Metre" name="rptctrl"/>
<button label="Uygula" label_selected="Uygula" name="button apply"/>
<text name="tex offset">
Doku Dengeleyicisi
diff --git a/indra/newview/skins/default/xui/tr/floater_top_objects.xml b/indra/newview/skins/default/xui/tr/floater_top_objects.xml
index e726f583cc..19420c68e3 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_top_objects.xml
+++ b/indra/newview/skins/default/xui/tr/floater_top_objects.xml
@@ -9,9 +9,6 @@
<floater.string name="scripts_score_label">
Süre
</floater.string>
- <floater.string name="scripts_mono_time_label">
- Mono Süre
- </floater.string>
<floater.string name="top_colliders_title">
En Çok Çarpışanlar
</floater.string>
@@ -32,9 +29,10 @@
<scroll_list.columns label="Ad" name="name"/>
<scroll_list.columns label="Sahip" name="owner"/>
<scroll_list.columns label="Konum" name="location"/>
+ <scroll_list.columns label="Parsel" name="parcel"/>
<scroll_list.columns label="Süre" name="time"/>
- <scroll_list.columns label="Mono Süre" name="mono_time"/>
<scroll_list.columns label="URL&apos;ler" name="URLs"/>
+ <scroll_list.columns label="Bellek (KB)" name="memory"/>
</scroll_list>
<text name="id_text">
Nesne KimliÄŸi:
@@ -48,6 +46,10 @@
Sahip:
</text>
<button label="Filtrele" name="filter_owner_btn"/>
+ <text name="parcel_name_text">
+ Parsel:
+ </text>
+ <button label="Filtrele" name="filter_parcel_btn"/>
<button label="Seçileni İade Et" name="return_selected_btn"/>
<button label="Tümünü İade Et" name="return_all_btn"/>
<button label="Seçileni Devre Dışı Bırak" name="disable_selected_btn"/>
diff --git a/indra/newview/skins/default/xui/tr/floater_tos.xml b/indra/newview/skins/default/xui/tr/floater_tos.xml
index 7ff0001ddd..7ff0001ddd 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_tos.xml
+++ b/indra/newview/skins/default/xui/tr/floater_tos.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_toybox.xml b/indra/newview/skins/default/xui/tr/floater_toybox.xml
index e60e176643..e60e176643 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_toybox.xml
+++ b/indra/newview/skins/default/xui/tr/floater_toybox.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_translation_settings.xml b/indra/newview/skins/default/xui/tr/floater_translation_settings.xml
index 33ce76bd9a..33ce76bd9a 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_translation_settings.xml
+++ b/indra/newview/skins/default/xui/tr/floater_translation_settings.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_url_entry.xml b/indra/newview/skins/default/xui/tr/floater_url_entry.xml
index 54c5b047a8..54c5b047a8 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_url_entry.xml
+++ b/indra/newview/skins/default/xui/tr/floater_url_entry.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_voice_chat_volume.xml b/indra/newview/skins/default/xui/tr/floater_voice_chat_volume.xml
new file mode 100644
index 0000000000..ec350bee60
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/floater_voice_chat_volume.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="floater_voice_volume" title="SOHBET SES DÃœZEYÄ°">
+ <slider label="Sesli Sohbet" name="chat_voice_volume"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/tr/floater_voice_controls.xml b/indra/newview/skins/default/xui/tr/floater_voice_controls.xml
index 5ff0804f17..5ff0804f17 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_voice_controls.xml
+++ b/indra/newview/skins/default/xui/tr/floater_voice_controls.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_voice_effect.xml b/indra/newview/skins/default/xui/tr/floater_voice_effect.xml
index 3534a3fe90..7a157244cd 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_voice_effect.xml
+++ b/indra/newview/skins/default/xui/tr/floater_voice_effect.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater label="Yerler" name="voice_effects" title="SES ÅžEKÄ°LLENDÄ°RME">
+<floater label="Yerler" name="voice_effects" title="SES ŞEKİLLENDİRME ÖNİZLEMESİ">
<string name="no_voice_effect">
(Ses Åžekillendirme Yok)
</string>
diff --git a/indra/newview/skins/default/xui/tr/floater_voice_volume.xml b/indra/newview/skins/default/xui/tr/floater_voice_volume.xml
new file mode 100644
index 0000000000..acf99d6199
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/floater_voice_volume.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<!--
+ Not can_close / no title to avoid window chrome
+ Single instance - only have one at a time, recycle it each spawn
+-->
+<floater name="floater_voice_volume" title="SES DÃœZEYÄ°">
+ <slider name="volume_slider" tool_tip="Ses düzeyi" value="0.5"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/tr/floater_water.xml b/indra/newview/skins/default/xui/tr/floater_water.xml
deleted file mode 100644
index 66d6c1e30d..0000000000
--- a/indra/newview/skins/default/xui/tr/floater_water.xml
+++ /dev/null
@@ -1,70 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Water Floater" title="GELÄ°ÅžMÄ°Åž SU DÃœZENLEYÄ°CÄ°">
- <floater.string name="WLDefaultWaterNames">
- Varsayılan:Camsı:Havuz:çamurlu:İkinci Veba:YILAN!!!:Valdez
- </floater.string>
- <text name="KeyFramePresetsText">
- Su Ön Ayarları:
- </text>
- <button label="Yeni" label_selected="Yeni" name="WaterNewPreset"/>
- <button label="Kaydet" label_selected="Kaydet" name="WaterSavePreset"/>
- <button label="Sil" label_selected="Sil" name="WaterDeletePreset"/>
- <tab_container name="Water Tabs">
- <panel label="AYARLAR" name="Settings">
- <text name="BHText">
- Su Sisi Rengi
- </text>
- <color_swatch name="WaterFogColor" tool_tip="Renk seçiciyi açmak için tıklayın"/>
- <text name="WaterFogDensText">
- Su Yoğunluk Üssü
- </text>
- <text name="WaterUnderWaterFogModText">
- Sualtı Sis Değiştiricisi
- </text>
- <text name="BDensText">
- Yansıma Dalgacığı Ölçeği
- </text>
- <slider label="1" name="WaterNormalScaleX"/>
- <slider label="2" name="WaterNormalScaleY"/>
- <slider label="3" name="WaterNormalScaleZ"/>
- <text name="HDText">
- Fresnel Ölçeği
- </text>
- <text name="FresnelOffsetText">
- Fresnel Dengeleyicisi
- </text>
- <text name="DensMultText">
- Yukarıdan Kırılma Ölçeği
- </text>
- <text name="WaterScaleBelowText">
- Aşağıdan Kırılma Ölçeği
- </text>
- <text name="MaxAltText">
- Bulanıklaştırma Çarpanı
- </text>
- </panel>
- <panel label="GÖRÜNTÜ" name="Waves">
- <text name="BHText">
- Büyük Dalga Yönü
- </text>
- <text name="WaterWave1DirXText">
- X
- </text>
- <text name="WaterWave1DirYText">
- Y
- </text>
- <text name="BHText2">
- Küçük Dalga Yönü
- </text>
- <text name="WaterWave2DirXText">
- X
- </text>
- <text name="WaterWave2DirYText">
- Y
- </text>
- <text name="BHText3">
- Normal Harita
- </text>
- </panel>
- </tab_container>
-</floater>
diff --git a/indra/newview/skins/default/xui/tr/floater_web_content.xml b/indra/newview/skins/default/xui/tr/floater_web_content.xml
index 93491b80fb..93491b80fb 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_web_content.xml
+++ b/indra/newview/skins/default/xui/tr/floater_web_content.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_whitelist_entry.xml b/indra/newview/skins/default/xui/tr/floater_whitelist_entry.xml
index 1a9f731af0..1a9f731af0 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_whitelist_entry.xml
+++ b/indra/newview/skins/default/xui/tr/floater_whitelist_entry.xml
diff --git a/indra/newview/skins/default/xui/tr/floater_windlight_options.xml b/indra/newview/skins/default/xui/tr/floater_windlight_options.xml
deleted file mode 100644
index 6c5fba374c..0000000000
--- a/indra/newview/skins/default/xui/tr/floater_windlight_options.xml
+++ /dev/null
@@ -1,167 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="WindLight floater" title="GELİŞMİŞ GÖKYÜZÜ DÜZENLEYİCİ">
- <floater.string name="WLDefaultSkyNames">
- A-12:A-24:A-3:A-15:A-16.30:A-6:A-18:A-9:A-21:Barselona:Tipi:Mavi Gün Ortası:Sahilde Öğleden Sonra:Sahilde Gün Batımı:Varsayılan:Çölde Gün Batımı:Güzel Bir Gün:Kabarık Büyük Bulutlar:Sisli:Şık Şık:Şık Şık Şık:Dondurma:Hayalet:Uygunsuz Gerçekler:Gün Ortası1:Gün Ortası 2:Gün Ortası 3:Gün Ortası 4:Gece:Korsan:Mor:Denizcinin Keyfi:Saf Tensel
- </floater.string>
- <text name="KeyFramePresetsText">
- Gökyüzü Ön Ayarları:
- </text>
- <button label="Yeni" label_selected="Yeni" name="WLNewPreset"/>
- <button label="Kaydet" label_selected="Kaydet" name="WLSavePreset"/>
- <button label="Sil" label_selected="Sil" name="WLDeletePreset"/>
- <button label="Gün Döngüsü Düzenleyici" label_selected="Gün Döngüsü Düzenleyici" name="WLDayCycleMenuButton"/>
- <tab_container name="WindLight Tabs">
- <panel label="ATMOSFER" name="Atmosphere">
- <text name="BHText">
- Mavi Ufuk
- </text>
- <text name="BHText2">
- R
- </text>
- <text name="BHText3">
- G
- </text>
- <text name="BHText4">
- B
- </text>
- <text name="BHText5">
- I
- </text>
- <text name="BDensText">
- Puslu Ufuk
- </text>
- <text name="BDensText2">
- Mavi YoÄŸunluÄŸu
- </text>
- <text name="BHText6">
- R
- </text>
- <text name="BHText7">
- G
- </text>
- <text name="BHText8">
- B
- </text>
- <text name="BHText9">
- I
- </text>
- <text name="HDText">
- Pus YoÄŸunluÄŸu
- </text>
- <text name="DensMultText">
- Yoğunluk Çarpanı
- </text>
- <text name="WLDistanceMultText">
- Mesafe Çarpanı
- </text>
- <text name="MaxAltText">
- Maks Ä°rtifa
- </text>
- </panel>
- <panel label="AYDINLATMA" name="Lighting">
- <text name="SLCText">
- Güneş/Ay Rengi
- </text>
- <text name="BHText">
- R
- </text>
- <text name="BHText2">
- G
- </text>
- <text name="BHText3">
- B
- </text>
- <text name="BHText4">
- I
- </text>
- <text name="TODText">
- Güneş/Ay Konumu
- </text>
- <text name="WLAmbientText">
- Ortam
- </text>
- <text name="BHText5">
- R
- </text>
- <text name="BHText6">
- G
- </text>
- <text name="BHText7">
- B
- </text>
- <text name="BHText8">
- I
- </text>
- <text name="WLEastAngleText">
- Doğu Açısı
- </text>
- <text name="SunGlowText">
- Güneş Parıltısı
- </text>
- <slider label="Odak" name="WLGlowB"/>
- <slider label="Büyüklük" name="WLGlowR"/>
- <text name="SceneGammaText">
- Sahne Gaması
- </text>
- <text name="WLStarText">
- Yıldız Parlaklığı
- </text>
- </panel>
- <panel label="BULUTLAR" name="Clouds">
- <text name="WLCloudColorText">
- Bulut Rengi
- </text>
- <text name="BHText">
- R
- </text>
- <text name="BHText2">
- G
- </text>
- <text name="BHText3">
- B
- </text>
- <text name="BHText4">
- I
- </text>
- <text name="WLCloudColorText2">
- Bulut XY/YoÄŸunluÄŸu
- </text>
- <text name="BHText5">
- X
- </text>
- <text name="BHText6">
- Y
- </text>
- <text name="BHText7">
- D
- </text>
- <text name="WLCloudCoverageText">
- Bulut Örtüsü
- </text>
- <text name="WLCloudScaleText">
- Bulut Yüksekliği
- </text>
- <text name="WLCloudDetailText">
- Bulut Ayrıntısı (XY/Yoğunluğu)
- </text>
- <text name="BHText8">
- X
- </text>
- <text name="BHText9">
- Y
- </text>
- <text name="BHText10">
- D
- </text>
- <text name="WLCloudScrollXText">
- Bulut Kaydırma X
- </text>
- <check_box label="Kilitle" name="WLCloudLockX"/>
- <text name="WLCloudScrollYText">
- Bulut Kaydırma Y
- </text>
- <check_box label="Kilitle" name="WLCloudLockY"/>
- <check_box label="Klasik Bulutlar Çiz" name="DrawClassicClouds"/>
- </panel>
- </tab_container>
-</floater>
diff --git a/indra/newview/skins/default/xui/tr/floater_window_size.xml b/indra/newview/skins/default/xui/tr/floater_window_size.xml
index acc2cc3376..aff20e7960 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_window_size.xml
+++ b/indra/newview/skins/default/xui/tr/floater_window_size.xml
@@ -7,10 +7,17 @@
Pencere büyüklüğünü ayarla:
</text>
<combo_box name="window_size_combo" tool_tip="genişlik x yükseklik">
- <combo_box.item label="1000 x 700 (varsayılan)" name="item0"/>
- <combo_box.item label="1024 x 768" name="item1"/>
- <combo_box.item label="1280 x 720 (720p)" name="item2"/>
- <combo_box.item label="1920 x 1080 (1080p)" name="item3"/>
+ <combo_box.item label="1000 x 700 (varsayılan)" name="item1"/>
+ <combo_box.item label="1024 x 768 (4:3 XGA)" name="item2"/>
+ <combo_box.item label="1280 x 720 (16:9 HDTV)" name="item3"/>
+ <combo_box.item label="1280 x 800 (5:8 WXGA)" name="item4"/>
+ <combo_box.item label="1280 x 1024 (5:4 SXGA)" name="item5"/>
+ <combo_box.item label="1440 x 900 (8:5 WSXGA)" name="item7"/>
+ <combo_box.item label="1600 x 900 (16:9 HD+)" name="item8"/>
+ <combo_box.item label="1600 x 1200 (4:3 UXGA)" name="item9"/>
+ <combo_box.item label="1680 x 1050 (8:5 WSXGA+)" name="item10"/>
+ <combo_box.item label="1920 x 1080 (16:9 HDTV)" name="item11"/>
+ <combo_box.item label="1920 x 1200 (8:5 WUXGA)" name="item12"/>
</combo_box>
<button label="Ayarla" name="set_btn"/>
<button label="Ä°ptal" name="cancel_btn"/>
diff --git a/indra/newview/skins/default/xui/tr/floater_world_map.xml b/indra/newview/skins/default/xui/tr/floater_world_map.xml
index e4729c2aed..e4729c2aed 100644..100755
--- a/indra/newview/skins/default/xui/tr/floater_world_map.xml
+++ b/indra/newview/skins/default/xui/tr/floater_world_map.xml
diff --git a/indra/newview/skins/default/xui/tr/inspect_avatar.xml b/indra/newview/skins/default/xui/tr/inspect_avatar.xml
index cb3c7e9282..cb3c7e9282 100644..100755
--- a/indra/newview/skins/default/xui/tr/inspect_avatar.xml
+++ b/indra/newview/skins/default/xui/tr/inspect_avatar.xml
diff --git a/indra/newview/skins/default/xui/tr/inspect_group.xml b/indra/newview/skins/default/xui/tr/inspect_group.xml
index 9b130c9ef6..9b130c9ef6 100644..100755
--- a/indra/newview/skins/default/xui/tr/inspect_group.xml
+++ b/indra/newview/skins/default/xui/tr/inspect_group.xml
diff --git a/indra/newview/skins/default/xui/tr/inspect_object.xml b/indra/newview/skins/default/xui/tr/inspect_object.xml
index bd09267319..bd09267319 100644..100755
--- a/indra/newview/skins/default/xui/tr/inspect_object.xml
+++ b/indra/newview/skins/default/xui/tr/inspect_object.xml
diff --git a/indra/newview/skins/default/xui/tr/inspect_remote_object.xml b/indra/newview/skins/default/xui/tr/inspect_remote_object.xml
index 4b696b2ae5..4b696b2ae5 100644..100755
--- a/indra/newview/skins/default/xui/tr/inspect_remote_object.xml
+++ b/indra/newview/skins/default/xui/tr/inspect_remote_object.xml
diff --git a/indra/newview/skins/default/xui/tr/menu_add_wearable_gear.xml b/indra/newview/skins/default/xui/tr/menu_add_wearable_gear.xml
index dcb4629259..dcb4629259 100644..100755
--- a/indra/newview/skins/default/xui/tr/menu_add_wearable_gear.xml
+++ b/indra/newview/skins/default/xui/tr/menu_add_wearable_gear.xml
diff --git a/indra/newview/skins/default/xui/tr/menu_attachment_other.xml b/indra/newview/skins/default/xui/tr/menu_attachment_other.xml
index 9ba214ff31..0cb233a657 100644..100755
--- a/indra/newview/skins/default/xui/tr/menu_attachment_other.xml
+++ b/indra/newview/skins/default/xui/tr/menu_attachment_other.xml
@@ -11,7 +11,9 @@
<menu_item_call label="Dondur" name="Freeze..."/>
<menu_item_call label="Çıkar" name="Eject..."/>
<menu_item_call label="Dokularda Hata Ayıkla" name="Debug..."/>
+ <menu_item_call label="XML Dökümünü Al" name="Dump XML"/>
<menu_item_call label="Yakınlaştır" name="Zoom In"/>
<menu_item_call label="Öde" name="Pay..."/>
<menu_item_call label="Nesne Profili" name="Object Inspect"/>
+ <menu_item_call label="Parçacık Sahibini Engelle" name="Mute Particle"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/tr/menu_attachment_self.xml b/indra/newview/skins/default/xui/tr/menu_attachment_self.xml
index 16d1e3f356..ff7c718979 100644..100755
--- a/indra/newview/skins/default/xui/tr/menu_attachment_self.xml
+++ b/indra/newview/skins/default/xui/tr/menu_attachment_self.xml
@@ -12,5 +12,7 @@
<menu_item_call label="Gruplarım" name="Groups..."/>
<menu_item_call label="Profilim" name="Profile..."/>
<menu_item_call label="Dokularda Hata Ayıkla" name="Debug..."/>
+ <menu_item_call label="XML Dökümünü Al" name="Dump XML"/>
<menu_item_call label="Bırak" name="Drop"/>
+ <menu_item_call label="Parçacık Sahibini Engelle" name="Mute Particle"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/tr/menu_avatar_icon.xml b/indra/newview/skins/default/xui/tr/menu_avatar_icon.xml
index d3ef490735..d3ef490735 100644..100755
--- a/indra/newview/skins/default/xui/tr/menu_avatar_icon.xml
+++ b/indra/newview/skins/default/xui/tr/menu_avatar_icon.xml
diff --git a/indra/newview/skins/default/xui/tr/menu_avatar_other.xml b/indra/newview/skins/default/xui/tr/menu_avatar_other.xml
index 7d691d2ac5..0da328a894 100644..100755
--- a/indra/newview/skins/default/xui/tr/menu_avatar_other.xml
+++ b/indra/newview/skins/default/xui/tr/menu_avatar_other.xml
@@ -11,6 +11,8 @@
<menu_item_call label="Dondur" name="Freeze..."/>
<menu_item_call label="Çıkar" name="Eject..."/>
<menu_item_call label="Dokularda Hata Ayıkla" name="Debug..."/>
+ <menu_item_call label="XML Dökümünü Al" name="Dump XML"/>
<menu_item_call label="Yakınlaştır" name="Zoom In"/>
<menu_item_call label="Öde" name="Pay..."/>
+ <menu_item_call label="Parçacık Sahibini Engelle" name="Mute Particle"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/tr/menu_avatar_self.xml b/indra/newview/skins/default/xui/tr/menu_avatar_self.xml
index c520aff521..6996dc612f 100644..100755
--- a/indra/newview/skins/default/xui/tr/menu_avatar_self.xml
+++ b/indra/newview/skins/default/xui/tr/menu_avatar_self.xml
@@ -29,4 +29,6 @@
<menu_item_call label="Gruplarım" name="Groups..."/>
<menu_item_call label="Profilim" name="Profile..."/>
<menu_item_call label="Dokularda Hata Ayıkla" name="Debug..."/>
+ <menu_item_call label="XML Dökümünü Al" name="Dump XML"/>
+ <menu_item_call label="Parçacık Sahibini Engelle" name="Mute Particle"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/tr/menu_bottomtray.xml b/indra/newview/skins/default/xui/tr/menu_bottomtray.xml
deleted file mode 100644
index f17c0f9971..0000000000
--- a/indra/newview/skins/default/xui/tr/menu_bottomtray.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<menu name="hide_camera_move_controls_menu">
- <menu_item_check label="Konuşma Düğmesi" name="EnableVoiceChat"/>
- <menu_item_check label="Mimik düğmesi" name="ShowGestureButton"/>
- <menu_item_check label="Taşıma düğmesi" name="ShowMoveButton"/>
- <menu_item_check label="Görüntüleme düğmesi" name="ShowCameraButton"/>
- <menu_item_check label="Anlık görüntü düğmesi" name="ShowSnapshotButton"/>
- <menu_item_check label="İnşa Et düğmesi" name="ShowBuildButton"/>
- <menu_item_check label="Arama düğmesi" name="ShowSearchButton"/>
- <menu_item_check label="Harita düğmesi" name="ShowWorldMapButton"/>
- <menu_item_check label="Mini-harita düğmesi" name="ShowMiniMapButton"/>
- <menu_item_call label="Kes" name="NearbyChatBar_Cut"/>
- <menu_item_call label="Kopyala" name="NearbyChatBar_Copy"/>
- <menu_item_call label="Yapıştır" name="NearbyChatBar_Paste"/>
- <menu_item_call label="Sil" name="NearbyChatBar_Delete"/>
- <menu_item_call label="Tümünü Seç" name="NearbyChatBar_Select_All"/>
-</menu>
diff --git a/indra/newview/skins/default/xui/tr/menu_cof_attachment.xml b/indra/newview/skins/default/xui/tr/menu_cof_attachment.xml
index d57c43f6c1..d57c43f6c1 100644..100755
--- a/indra/newview/skins/default/xui/tr/menu_cof_attachment.xml
+++ b/indra/newview/skins/default/xui/tr/menu_cof_attachment.xml
diff --git a/indra/newview/skins/default/xui/tr/menu_cof_body_part.xml b/indra/newview/skins/default/xui/tr/menu_cof_body_part.xml
index 31f77d834a..31f77d834a 100644..100755
--- a/indra/newview/skins/default/xui/tr/menu_cof_body_part.xml
+++ b/indra/newview/skins/default/xui/tr/menu_cof_body_part.xml
diff --git a/indra/newview/skins/default/xui/tr/menu_cof_clothing.xml b/indra/newview/skins/default/xui/tr/menu_cof_clothing.xml
index 784d809d70..784d809d70 100644..100755
--- a/indra/newview/skins/default/xui/tr/menu_cof_clothing.xml
+++ b/indra/newview/skins/default/xui/tr/menu_cof_clothing.xml
diff --git a/indra/newview/skins/default/xui/tr/menu_cof_gear.xml b/indra/newview/skins/default/xui/tr/menu_cof_gear.xml
index f910e1fe91..9480d30029 100644..100755
--- a/indra/newview/skins/default/xui/tr/menu_cof_gear.xml
+++ b/indra/newview/skins/default/xui/tr/menu_cof_gear.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<toggleable_menu name="Gear COF">
<menu label="Yeni Giysiler" name="COF.Gear.New_Clothes"/>
- <menu label="Yeni Vücut Bölümleri" name="COF.Geear.New_Body_Parts"/>
+ <menu label="Yeni Vücut Bölümleri" name="COF.Gear.New_Body_Parts"/>
</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/tr/menu_conversation.xml b/indra/newview/skins/default/xui/tr/menu_conversation.xml
new file mode 100644
index 0000000000..c2773cdc26
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/menu_conversation.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_conversation_participant">
+ <menu_item_call label="Sohbeti kapat" name="close_conversation"/>
+ <menu_item_call label="Ses sohbetini aç" name="open_voice_conversation"/>
+ <menu_item_call label="Ses bağlantısını kes" name="disconnect_from_voice"/>
+ <menu_item_call label="Seçileni Kapat" name="close_selected_conversations"/>
+ <menu_item_call label="Profili Göster" name="view_profile"/>
+ <menu_item_call label="AÄ°" name="im"/>
+ <menu_item_call label="Işınlama teklif et" name="offer_teleport"/>
+ <menu_item_call label="Sesli arama" name="voice_call"/>
+ <menu_item_call label="Sohbet geçmişi..." name="chat_history"/>
+ <menu_item_call label="ArkadaÅŸ ekle" name="add_friend"/>
+ <menu_item_call label="Arkadaşı çıkar" name="remove_friend"/>
+ <menu_item_call label="Arkadaşları çıkar" name="remove_friends"/>
+ <menu_item_call label="Gruba davet et..." name="invite_to_group"/>
+ <menu_item_call label="Yakınlaştır" name="zoom_in"/>
+ <menu_item_call label="Harita" name="map"/>
+ <menu_item_call label="PaylaÅŸ" name="share"/>
+ <menu_item_call label="Öde" name="pay"/>
+ <menu_item_check label="Sesi Engelle" name="block_unblock"/>
+ <menu_item_check label="Metni Engelle" name="MuteText"/>
+ <menu_item_call label="Grup Profili" name="group_profile"/>
+ <menu_item_call label="Grubu EtkinleÅŸtir" name="activate_group"/>
+ <menu_item_call label="Gruptan Ayrıl" name="leave_group"/>
+ <context_menu label="Moderatör Seçenekleri" name="Moderator Options">
+ <menu_item_check label="Metin sohbetine izin ver" name="AllowTextChat"/>
+ <menu_item_call label="Bu katılımcıyı engelle" name="ModerateVoiceMuteSelected"/>
+ <menu_item_call label="Bu katılımcının engellemesini kaldır" name="ModerateVoiceUnMuteSelected"/>
+ <menu_item_call label="Herkesi engelle" name="ModerateVoiceMute"/>
+ <menu_item_call label="Herkesin engellemesini kaldır" name="ModerateVoiceUnmute"/>
+ </context_menu>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/tr/menu_conversation_log_gear.xml b/indra/newview/skins/default/xui/tr/menu_conversation_log_gear.xml
new file mode 100644
index 0000000000..9e91780eb8
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/menu_conversation_log_gear.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="Conversation Context Menu">
+ <menu_item_call label="AÄ°..." name="IM"/>
+ <menu_item_call label="Sesli arama..." name="Call"/>
+ <menu_item_call label="Sohbet geçmişini aç..." name="Chat history"/>
+ <menu_item_call label="Profili Göster" name="View Profile"/>
+ <menu_item_call label="Işınlama Teklif Et" name="teleport"/>
+ <menu_item_call label="ArkadaÅŸ Ekle" name="add_friend"/>
+ <menu_item_call label="Arkadaşı Çıkar" name="remove_friend"/>
+ <menu_item_call label="Gruba davet et..." name="Invite"/>
+ <menu_item_call label="Harita" name="Map"/>
+ <menu_item_call label="PaylaÅŸ" name="Share"/>
+ <menu_item_call label="Öde" name="Pay"/>
+ <menu_item_check label="Engelle/Engeli Kaldır" name="Block/Unblock"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/tr/menu_conversation_log_view.xml b/indra/newview/skins/default/xui/tr/menu_conversation_log_view.xml
new file mode 100644
index 0000000000..9a77eaadd9
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/menu_conversation_log_view.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_conversation_view">
+ <menu_item_check label="Ada göre sırala" name="sort_by_name"/>
+ <menu_item_check label="Tarihe göre sırala" name="sort_by_date"/>
+ <menu_item_check label="Arkadaşlar üstte olacak şekilde sırala" name="sort_by_friends"/>
+ <menu_item_call label="Yakındaki sohbet geçmişini göster..." name="view_nearby_chat_history"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/tr/menu_edit.xml b/indra/newview/skins/default/xui/tr/menu_edit.xml
index 81cd270af0..81cd270af0 100644..100755
--- a/indra/newview/skins/default/xui/tr/menu_edit.xml
+++ b/indra/newview/skins/default/xui/tr/menu_edit.xml
diff --git a/indra/newview/skins/default/xui/tr/menu_favorites.xml b/indra/newview/skins/default/xui/tr/menu_favorites.xml
index 7bb2ed1ddc..7bb2ed1ddc 100644..100755
--- a/indra/newview/skins/default/xui/tr/menu_favorites.xml
+++ b/indra/newview/skins/default/xui/tr/menu_favorites.xml
diff --git a/indra/newview/skins/default/xui/tr/menu_gesture_gear.xml b/indra/newview/skins/default/xui/tr/menu_gesture_gear.xml
index cb9b678fdd..cb9b678fdd 100644..100755
--- a/indra/newview/skins/default/xui/tr/menu_gesture_gear.xml
+++ b/indra/newview/skins/default/xui/tr/menu_gesture_gear.xml
diff --git a/indra/newview/skins/default/xui/tr/menu_group_plus.xml b/indra/newview/skins/default/xui/tr/menu_group_plus.xml
index 82cf7dcf74..82cf7dcf74 100644..100755
--- a/indra/newview/skins/default/xui/tr/menu_group_plus.xml
+++ b/indra/newview/skins/default/xui/tr/menu_group_plus.xml
diff --git a/indra/newview/skins/default/xui/tr/menu_hide_navbar.xml b/indra/newview/skins/default/xui/tr/menu_hide_navbar.xml
index d1f213516b..d1f213516b 100644..100755
--- a/indra/newview/skins/default/xui/tr/menu_hide_navbar.xml
+++ b/indra/newview/skins/default/xui/tr/menu_hide_navbar.xml
diff --git a/indra/newview/skins/default/xui/tr/menu_im_conversation.xml b/indra/newview/skins/default/xui/tr/menu_im_conversation.xml
new file mode 100644
index 0000000000..3b9738edce
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/menu_im_conversation.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="Conversation Gear Menu">
+ <menu_item_call label="Profili Göster" name="View Profile"/>
+ <menu_item_call label="ArkadaÅŸ Ekle" name="Add Friend"/>
+ <menu_item_call label="Arkadaşı çıkar" name="remove_friend"/>
+ <menu_item_call label="Işınlama teklif et" name="offer_teleport"/>
+ <menu_item_call label="Gruba davet et..." name="invite_to_group"/>
+ <menu_item_call label="Sohbet geçmişi..." name="chat_history"/>
+ <menu_item_call label="Yakınlaştır" name="zoom_in"/>
+ <menu_item_call label="Harita" name="map"/>
+ <menu_item_call label="PaylaÅŸ" name="Share"/>
+ <menu_item_call label="Öde" name="Pay"/>
+ <menu_item_check label="Sesi Engelle" name="Block/Unblock"/>
+ <menu_item_check label="Metni Engelle" name="MuteText"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/tr/menu_im_session_showmodes.xml b/indra/newview/skins/default/xui/tr/menu_im_session_showmodes.xml
new file mode 100644
index 0000000000..c4d4357ac9
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/menu_im_session_showmodes.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_modes">
+ <menu_item_check label="Daraltılmış görünüm" name="compact_view"/>
+ <menu_item_check label="Genişletilmiş görünüm" name="expanded_view"/>
+ <menu_item_check label="Zamanı göster" name="IMShowTime"/>
+ <menu_item_check label="Bire bir sohbetlerde adları göster" name="IMShowNamesForP2PConv"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/tr/menu_im_well_button.xml b/indra/newview/skins/default/xui/tr/menu_im_well_button.xml
deleted file mode 100644
index c3e559a723..0000000000
--- a/indra/newview/skins/default/xui/tr/menu_im_well_button.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<context_menu name="IM Well Button Context Menu">
- <menu_item_call label="Tümünü Kapat" name="Close All"/>
-</context_menu>
diff --git a/indra/newview/skins/default/xui/tr/menu_imchiclet_adhoc.xml b/indra/newview/skins/default/xui/tr/menu_imchiclet_adhoc.xml
index 0396ad8fb5..0396ad8fb5 100644..100755
--- a/indra/newview/skins/default/xui/tr/menu_imchiclet_adhoc.xml
+++ b/indra/newview/skins/default/xui/tr/menu_imchiclet_adhoc.xml
diff --git a/indra/newview/skins/default/xui/tr/menu_imchiclet_group.xml b/indra/newview/skins/default/xui/tr/menu_imchiclet_group.xml
index 60a50b114e..60a50b114e 100644..100755
--- a/indra/newview/skins/default/xui/tr/menu_imchiclet_group.xml
+++ b/indra/newview/skins/default/xui/tr/menu_imchiclet_group.xml
diff --git a/indra/newview/skins/default/xui/tr/menu_imchiclet_p2p.xml b/indra/newview/skins/default/xui/tr/menu_imchiclet_p2p.xml
index 0ef4471088..0ef4471088 100644..100755
--- a/indra/newview/skins/default/xui/tr/menu_imchiclet_p2p.xml
+++ b/indra/newview/skins/default/xui/tr/menu_imchiclet_p2p.xml
diff --git a/indra/newview/skins/default/xui/tr/menu_inspect_avatar_gear.xml b/indra/newview/skins/default/xui/tr/menu_inspect_avatar_gear.xml
index 69432e967b..69432e967b 100644..100755
--- a/indra/newview/skins/default/xui/tr/menu_inspect_avatar_gear.xml
+++ b/indra/newview/skins/default/xui/tr/menu_inspect_avatar_gear.xml
diff --git a/indra/newview/skins/default/xui/tr/menu_inspect_object_gear.xml b/indra/newview/skins/default/xui/tr/menu_inspect_object_gear.xml
index d1d3f9ac8d..d1d3f9ac8d 100644..100755
--- a/indra/newview/skins/default/xui/tr/menu_inspect_object_gear.xml
+++ b/indra/newview/skins/default/xui/tr/menu_inspect_object_gear.xml
diff --git a/indra/newview/skins/default/xui/tr/menu_inspect_self_gear.xml b/indra/newview/skins/default/xui/tr/menu_inspect_self_gear.xml
index 0655db8196..0655db8196 100644..100755
--- a/indra/newview/skins/default/xui/tr/menu_inspect_self_gear.xml
+++ b/indra/newview/skins/default/xui/tr/menu_inspect_self_gear.xml
diff --git a/indra/newview/skins/default/xui/tr/menu_inv_offer_chiclet.xml b/indra/newview/skins/default/xui/tr/menu_inv_offer_chiclet.xml
index 2e2b17491a..2e2b17491a 100644..100755
--- a/indra/newview/skins/default/xui/tr/menu_inv_offer_chiclet.xml
+++ b/indra/newview/skins/default/xui/tr/menu_inv_offer_chiclet.xml
diff --git a/indra/newview/skins/default/xui/tr/menu_inventory.xml b/indra/newview/skins/default/xui/tr/menu_inventory.xml
index 170cdebd24..51049427af 100644..100755
--- a/indra/newview/skins/default/xui/tr/menu_inventory.xml
+++ b/indra/newview/skins/default/xui/tr/menu_inventory.xml
@@ -68,6 +68,7 @@
<menu_item_call label="Sistem Klasörünü Sil" name="Delete System Folder"/>
<menu_item_call label="Konferans Sohbeti BaÅŸlat" name="Conference Chat Folder"/>
<menu_item_call label="Oyna" name="Sound Play"/>
+ <menu_item_call label="SLurl&apos;i Kopyala" name="url_copy"/>
<menu_item_call label="Yer İmi Hakkında" name="About Landmark"/>
<menu_item_call label="SL Dünyasında Oynat" name="Animation Play"/>
<menu_item_call label="Yerel Olarak Oynat" name="Animation Audition"/>
diff --git a/indra/newview/skins/default/xui/tr/menu_inventory_add.xml b/indra/newview/skins/default/xui/tr/menu_inventory_add.xml
index db2a9a2c8c..db2a9a2c8c 100644..100755
--- a/indra/newview/skins/default/xui/tr/menu_inventory_add.xml
+++ b/indra/newview/skins/default/xui/tr/menu_inventory_add.xml
diff --git a/indra/newview/skins/default/xui/tr/menu_inventory_gear_default.xml b/indra/newview/skins/default/xui/tr/menu_inventory_gear_default.xml
index 5f3e4e8789..5f3e4e8789 100644..100755
--- a/indra/newview/skins/default/xui/tr/menu_inventory_gear_default.xml
+++ b/indra/newview/skins/default/xui/tr/menu_inventory_gear_default.xml
diff --git a/indra/newview/skins/default/xui/tr/menu_land.xml b/indra/newview/skins/default/xui/tr/menu_land.xml
index db65f1af1e..d6d8dbf730 100644..100755
--- a/indra/newview/skins/default/xui/tr/menu_land.xml
+++ b/indra/newview/skins/default/xui/tr/menu_land.xml
@@ -6,4 +6,5 @@
<menu_item_call label="Geçiş Hakkı Satın Al" name="Land Buy Pass"/>
<menu_item_call label="Ä°nÅŸa Et" name="Create"/>
<menu_item_call label="Yüzeyi Düzenle" name="Edit Terrain"/>
+ <menu_item_call label="Parçacık Sahibini Engelle" name="Mute Particle"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/tr/menu_landmark.xml b/indra/newview/skins/default/xui/tr/menu_landmark.xml
index c68a2f6a90..c68a2f6a90 100644..100755
--- a/indra/newview/skins/default/xui/tr/menu_landmark.xml
+++ b/indra/newview/skins/default/xui/tr/menu_landmark.xml
diff --git a/indra/newview/skins/default/xui/tr/menu_login.xml b/indra/newview/skins/default/xui/tr/menu_login.xml
index f27908bf7a..79c95407e8 100644..100755
--- a/indra/newview/skins/default/xui/tr/menu_login.xml
+++ b/indra/newview/skins/default/xui/tr/menu_login.xml
@@ -18,7 +18,13 @@
<menu_item_call label="Hizmet Şartlarını Göster" name="TOS"/>
<menu_item_call label="Kritik İletiyi Göster" name="Critical"/>
<menu_item_call label="Web İçeriği Gezdiricisi Hata Ayıklama Testi" name="Web Content Floater Debug Test"/>
- <menu label="Günlük Tutma Seviyesini Seç" name="Set Logging Level"/>
+ <menu label="Günlük Tutma Seviyesini Seç" name="Set Logging Level">
+ <menu_item_check label="Hata ayıkla" name="Debug"/>
+ <menu_item_check label="Bilgi" name="Info"/>
+ <menu_item_check label="Uyarı" name="Warning"/>
+ <menu_item_check label="Hata" name="Error"/>
+ <menu_item_check label="Hiçbiri" name="None"/>
+ </menu>
<menu_item_check label="Izgara Seçiciyi Göster" name="Show Grid Picker"/>
<menu_item_call label="Bildirimler Konsolunu Göster" name="Show Notifications Console"/>
</menu>
diff --git a/indra/newview/skins/default/xui/tr/menu_media_ctrl.xml b/indra/newview/skins/default/xui/tr/menu_media_ctrl.xml
index 8d04e645fd..8d04e645fd 100644..100755
--- a/indra/newview/skins/default/xui/tr/menu_media_ctrl.xml
+++ b/indra/newview/skins/default/xui/tr/menu_media_ctrl.xml
diff --git a/indra/newview/skins/default/xui/tr/menu_mini_map.xml b/indra/newview/skins/default/xui/tr/menu_mini_map.xml
index 9abe78931e..9abe78931e 100644..100755
--- a/indra/newview/skins/default/xui/tr/menu_mini_map.xml
+++ b/indra/newview/skins/default/xui/tr/menu_mini_map.xml
diff --git a/indra/newview/skins/default/xui/tr/menu_mode_change.xml b/indra/newview/skins/default/xui/tr/menu_mode_change.xml
deleted file mode 100644
index 678950b633..0000000000
--- a/indra/newview/skins/default/xui/tr/menu_mode_change.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<toggleable_menu name="Mode Change">
- <menu_item_check label="Temel" name="BasicMode"/>
- <menu_item_check label="GeliÅŸmiÅŸ" name="AdvancedMode"/>
-</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/tr/menu_model_import_gear_default.xml b/indra/newview/skins/default/xui/tr/menu_model_import_gear_default.xml
index 51cf29a4de..51cf29a4de 100644..100755
--- a/indra/newview/skins/default/xui/tr/menu_model_import_gear_default.xml
+++ b/indra/newview/skins/default/xui/tr/menu_model_import_gear_default.xml
diff --git a/indra/newview/skins/default/xui/tr/menu_mute_particle.xml b/indra/newview/skins/default/xui/tr/menu_mute_particle.xml
new file mode 100644
index 0000000000..a05a745ed0
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/menu_mute_particle.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<!-- *NOTE: See also menu_attachment_other.xml -->
+<context_menu name="Mute Particle Pie">
+ <menu_item_call label="Parçacık Sahibini Engelle" name="Mute Particle"/>
+</context_menu>
diff --git a/indra/newview/skins/default/xui/tr/menu_navbar.xml b/indra/newview/skins/default/xui/tr/menu_navbar.xml
index b05b816e64..b05b816e64 100644..100755
--- a/indra/newview/skins/default/xui/tr/menu_navbar.xml
+++ b/indra/newview/skins/default/xui/tr/menu_navbar.xml
diff --git a/indra/newview/skins/default/xui/tr/menu_nearby_chat.xml b/indra/newview/skins/default/xui/tr/menu_nearby_chat.xml
index b76a736979..b76a736979 100644..100755
--- a/indra/newview/skins/default/xui/tr/menu_nearby_chat.xml
+++ b/indra/newview/skins/default/xui/tr/menu_nearby_chat.xml
diff --git a/indra/newview/skins/default/xui/tr/menu_notification_well_button.xml b/indra/newview/skins/default/xui/tr/menu_notification_well_button.xml
index 39c66268f5..39c66268f5 100644..100755
--- a/indra/newview/skins/default/xui/tr/menu_notification_well_button.xml
+++ b/indra/newview/skins/default/xui/tr/menu_notification_well_button.xml
diff --git a/indra/newview/skins/default/xui/tr/menu_object.xml b/indra/newview/skins/default/xui/tr/menu_object.xml
index d60c68e5e9..2f8b5c0362 100644..100755
--- a/indra/newview/skins/default/xui/tr/menu_object.xml
+++ b/indra/newview/skins/default/xui/tr/menu_object.xml
@@ -8,6 +8,8 @@
<menu_item_call label="Kalk" name="Object Stand Up"/>
<menu_item_call label="Nesne Profili" name="Object Inspect"/>
<menu_item_call label="Yakınlaştır" name="Zoom In"/>
+ <menu_item_call label="Bağlantı kümelerinde göster" name="show_in_linksets"/>
+ <menu_item_call label="Karakterlerde göster" name="show_in_characters"/>
<context_menu label="Ãœzerine Koy" name="Put On">
<menu_item_call label="Giy" name="Wear"/>
<menu_item_call label="Ekle" name="Add"/>
@@ -24,4 +26,5 @@
<menu_item_call label="Öde" name="Pay..."/>
<menu_item_call label="Satın Al" name="Buy..."/>
<menu_item_call label="Sil" name="Delete"/>
+ <menu_item_call label="Parçacık Sahibini Engelle" name="Mute Particle"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/tr/menu_object_icon.xml b/indra/newview/skins/default/xui/tr/menu_object_icon.xml
index 34a2661d8a..3d5c68d9d3 100644..100755
--- a/indra/newview/skins/default/xui/tr/menu_object_icon.xml
+++ b/indra/newview/skins/default/xui/tr/menu_object_icon.xml
@@ -2,4 +2,6 @@
<menu name="Object Icon Menu">
<menu_item_call label="Nesne Profili..." name="Object Profile"/>
<menu_item_call label="Engelle..." name="Block"/>
+ <menu_item_call label="Haritada Göster" name="show_on_map"/>
+ <menu_item_call label="Nesne Konumuna Işınla" name="teleport_to_object"/>
</menu>
diff --git a/indra/newview/skins/default/xui/tr/menu_outfit_gear.xml b/indra/newview/skins/default/xui/tr/menu_outfit_gear.xml
index d2e7e7107a..674041e9c9 100644..100755
--- a/indra/newview/skins/default/xui/tr/menu_outfit_gear.xml
+++ b/indra/newview/skins/default/xui/tr/menu_outfit_gear.xml
@@ -23,6 +23,8 @@
<menu_item_call label="Yeni Saç" name="New Hair"/>
<menu_item_call label="Yeni Gözler" name="New Eyes"/>
</menu>
+ <menu_item_call label="Tüm klasörleri genişlet" name="expand"/>
+ <menu_item_call label="Tüm klasörleri daralt" name="collapse"/>
<menu_item_call label="Dış Görünümü Yeniden Adlandır" name="rename"/>
<menu_item_call label="Dış Görünümü Sil" name="delete_outfit"/>
</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/tr/menu_outfit_tab.xml b/indra/newview/skins/default/xui/tr/menu_outfit_tab.xml
index a48529e462..a48529e462 100644..100755
--- a/indra/newview/skins/default/xui/tr/menu_outfit_tab.xml
+++ b/indra/newview/skins/default/xui/tr/menu_outfit_tab.xml
diff --git a/indra/newview/skins/default/xui/tr/menu_participant_list.xml b/indra/newview/skins/default/xui/tr/menu_participant_list.xml
index 1d56105e1e..1d56105e1e 100644..100755
--- a/indra/newview/skins/default/xui/tr/menu_participant_list.xml
+++ b/indra/newview/skins/default/xui/tr/menu_participant_list.xml
diff --git a/indra/newview/skins/default/xui/tr/menu_participant_view.xml b/indra/newview/skins/default/xui/tr/menu_participant_view.xml
new file mode 100644
index 0000000000..e9411ff350
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/menu_participant_view.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="participant_manu_view">
+ <menu_item_check label="Sohbetleri türe göre sırala" name="sort_sessions_by_type"/>
+ <menu_item_check label="Sohbetleri ada göre sırala" name="sort_sessions_by_name"/>
+ <menu_item_check label="Sohbetleri son faaliyetlere göre sırala" name="sort_sessions_by_recent"/>
+ <menu_item_check label="Katılımcıları ada göre sırala" name="sort_participants_by_name"/>
+ <menu_item_check label="Katılımcıları son faaliyetlere göre sırala" name="sort_participants_by_recent"/>
+ <menu_item_call label="Sohbet tercihleri..." name="chat_preferences"/>
+ <menu_item_call label="Gizlilik tercihleri..." name="privacy_preferences"/>
+ <menu_item_check label="Sohbet günlüğü..." name="Conversation"/>
+ <menu_item_check label="Yakındaki sohbeti çevir" name="Translate_chat"/>
+ <menu_item_check label="Çeviri ayarları..." name="Translation_settings"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/tr/menu_people_blocked_gear.xml b/indra/newview/skins/default/xui/tr/menu_people_blocked_gear.xml
new file mode 100644
index 0000000000..2bf1101b48
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/menu_people_blocked_gear.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_blocked_gear">
+ <menu_item_call label="Engellemeyi Kaldır" name="unblock"/>
+ <menu_item_call label="Profil..." name="profile"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/tr/menu_people_blocked_plus.xml b/indra/newview/skins/default/xui/tr/menu_people_blocked_plus.xml
new file mode 100644
index 0000000000..a869e2ae7d
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/menu_people_blocked_plus.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_blocked_plus">
+ <menu_item_call label="Sakini ada göre engelle..." name="block_resident_by_name"/>
+ <menu_item_call label="Nesneyi ada göre engelle" name="block_object_by_name"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/tr/menu_people_blocked_view.xml b/indra/newview/skins/default/xui/tr/menu_people_blocked_view.xml
new file mode 100644
index 0000000000..14b3de3a9f
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/menu_people_blocked_view.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_blocked_view">
+ <menu_item_check label="Ada göre sırala" name="sort_by_name"/>
+ <menu_item_check label="Türe göre sırala" name="sort_by_type"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/tr/menu_people_friends_view.xml b/indra/newview/skins/default/xui/tr/menu_people_friends_view.xml
new file mode 100644
index 0000000000..609584d6a6
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/menu_people_friends_view.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_group_plus">
+ <menu_item_check label="Ada Göre Sırala" name="sort_name"/>
+ <menu_item_check label="Duruma Göre Sırala" name="sort_status"/>
+ <menu_item_check label="Kişi Simgelerini Göster" name="view_icons"/>
+ <menu_item_check label="Verilen İzinleri Göster" name="view_permissions"/>
+ <menu_item_check label="Sohbet Günlüğünü Göster..." name="view_conversation"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/tr/menu_people_friends_view_sort.xml b/indra/newview/skins/default/xui/tr/menu_people_friends_view_sort.xml
index 404fab17e6..404fab17e6 100644..100755
--- a/indra/newview/skins/default/xui/tr/menu_people_friends_view_sort.xml
+++ b/indra/newview/skins/default/xui/tr/menu_people_friends_view_sort.xml
diff --git a/indra/newview/skins/default/xui/tr/menu_people_groups.xml b/indra/newview/skins/default/xui/tr/menu_people_groups.xml
index 9f2946e310..743b01844d 100644..100755
--- a/indra/newview/skins/default/xui/tr/menu_people_groups.xml
+++ b/indra/newview/skins/default/xui/tr/menu_people_groups.xml
@@ -2,7 +2,7 @@
<menu name="menu_group_plus">
<menu_item_call label="Bilgileri Görüntüle" name="View Info"/>
<menu_item_call label="Sohbet" name="Chat"/>
- <menu_item_call label="Ara" name="Call"/>
+ <menu_item_call label="Sesli arama" name="Call"/>
<menu_item_call label="EtkinleÅŸtir" name="Activate"/>
<menu_item_call label="Ayrıl" name="Leave"/>
</menu>
diff --git a/indra/newview/skins/default/xui/tr/menu_people_groups_view.xml b/indra/newview/skins/default/xui/tr/menu_people_groups_view.xml
new file mode 100644
index 0000000000..e550b20add
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/menu_people_groups_view.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_group_plus">
+ <menu_item_check label="Grup Simgelerini Göster" name="Display Group Icons"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/tr/menu_people_groups_view_sort.xml b/indra/newview/skins/default/xui/tr/menu_people_groups_view_sort.xml
index a1e5ad9a50..a1e5ad9a50 100644..100755
--- a/indra/newview/skins/default/xui/tr/menu_people_groups_view_sort.xml
+++ b/indra/newview/skins/default/xui/tr/menu_people_groups_view_sort.xml
diff --git a/indra/newview/skins/default/xui/tr/menu_people_nearby.xml b/indra/newview/skins/default/xui/tr/menu_people_nearby.xml
index ee859a9450..2d61461c91 100644..100755
--- a/indra/newview/skins/default/xui/tr/menu_people_nearby.xml
+++ b/indra/newview/skins/default/xui/tr/menu_people_nearby.xml
@@ -1,13 +1,16 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Avatar Context Menu">
- <menu_item_call label="Profili Göster" name="View Profile"/>
- <menu_item_call label="ArkadaÅŸ Ekle" name="Add Friend"/>
- <menu_item_call label="Arkadaşı Çıkar" name="Remove Friend"/>
- <menu_item_call label="AÄ°" name="IM"/>
- <menu_item_call label="Ara" name="Call"/>
- <menu_item_call label="Harita" name="Map"/>
- <menu_item_call label="PaylaÅŸ" name="Share"/>
- <menu_item_call label="Öde" name="Pay"/>
- <menu_item_check label="Engelle/Engeli Kaldır" name="Block/Unblock"/>
- <menu_item_call label="Işınlama Teklif Et" name="teleport"/>
+ <menu_item_call label="Profili Göster" name="view_profile"/>
+ <menu_item_call label="AÄ°" name="im"/>
+ <menu_item_call label="Işınlama Teklif Et" name="offer_teleport"/>
+ <menu_item_call label="Sesli arama" name="voice_call"/>
+ <menu_item_call label="Sohbet geçmişini göster..." name="chat_history"/>
+ <menu_item_call label="ArkadaÅŸ Ekle" name="add_friend"/>
+ <menu_item_call label="Arkadaşı Çıkar" name="remove_friend"/>
+ <menu_item_call label="Gruba davet et..." name="invite_to_group"/>
+ <menu_item_call label="Yakınlaştır" name="zoom_in"/>
+ <menu_item_call label="Harita" name="map"/>
+ <menu_item_call label="PaylaÅŸ" name="share"/>
+ <menu_item_call label="Öde" name="pay"/>
+ <menu_item_check label="Engelle/Engeli Kaldır" name="block_unblock"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/tr/menu_people_nearby_multiselect.xml b/indra/newview/skins/default/xui/tr/menu_people_nearby_multiselect.xml
index 5c89f87906..20695d98e8 100644..100755
--- a/indra/newview/skins/default/xui/tr/menu_people_nearby_multiselect.xml
+++ b/indra/newview/skins/default/xui/tr/menu_people_nearby_multiselect.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Multi-Selected People Context Menu">
- <menu_item_call label="ArkadaÅŸ Ekle" name="Add Friends"/>
- <menu_item_call label="Arkadaşı Çıkar" name="Remove Friend"/>
- <menu_item_call label="AÄ°" name="IM"/>
- <menu_item_call label="Ara" name="Call"/>
- <menu_item_call label="PaylaÅŸ" name="Share"/>
- <menu_item_call label="Öde" name="Pay"/>
- <menu_item_call label="Işınlama Teklif Et" name="teleport"/>
+ <menu_item_call label="ArkadaÅŸ Ekle" name="add_friends"/>
+ <menu_item_call label="Arkadaşı Çıkar" name="remove_friends"/>
+ <menu_item_call label="AÄ°" name="im"/>
+ <menu_item_call label="Ara" name="call"/>
+ <menu_item_call label="PaylaÅŸ" name="share"/>
+ <menu_item_call label="Öde" name="pay"/>
+ <menu_item_call label="Işınlama Teklif Et" name="offer_teleport"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/tr/menu_people_nearby_view.xml b/indra/newview/skins/default/xui/tr/menu_people_nearby_view.xml
new file mode 100644
index 0000000000..59ea7c145f
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/menu_people_nearby_view.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_group_plus">
+ <menu_item_check label="Son Konuşanlara Göre Sırala" name="sort_by_recent_speakers"/>
+ <menu_item_check label="Ada Göre Sırala" name="sort_name"/>
+ <menu_item_check label="Mesafeye Göre Sırala" name="sort_distance"/>
+ <menu_item_check label="Kişi Simgelerini Göster" name="view_icons"/>
+ <menu_item_check label="Haritayı Göster" name="view_map"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/tr/menu_people_nearby_view_sort.xml b/indra/newview/skins/default/xui/tr/menu_people_nearby_view_sort.xml
index 0ff2111e9e..0ff2111e9e 100644..100755
--- a/indra/newview/skins/default/xui/tr/menu_people_nearby_view_sort.xml
+++ b/indra/newview/skins/default/xui/tr/menu_people_nearby_view_sort.xml
diff --git a/indra/newview/skins/default/xui/tr/menu_people_recent_view.xml b/indra/newview/skins/default/xui/tr/menu_people_recent_view.xml
new file mode 100644
index 0000000000..02be715ed2
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/menu_people_recent_view.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_group_plus">
+ <menu_item_check label="En Sonunculara Göre Sırala" name="sort_most"/>
+ <menu_item_check label="Ada Göre Sırala" name="sort_name"/>
+ <menu_item_check label="Kişi Simgelerini Göster" name="view_icons"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/tr/menu_people_recent_view_sort.xml b/indra/newview/skins/default/xui/tr/menu_people_recent_view_sort.xml
index adfba50138..adfba50138 100644..100755
--- a/indra/newview/skins/default/xui/tr/menu_people_recent_view_sort.xml
+++ b/indra/newview/skins/default/xui/tr/menu_people_recent_view_sort.xml
diff --git a/indra/newview/skins/default/xui/tr/menu_picks.xml b/indra/newview/skins/default/xui/tr/menu_picks.xml
index 3e5375ecc0..3e5375ecc0 100644..100755
--- a/indra/newview/skins/default/xui/tr/menu_picks.xml
+++ b/indra/newview/skins/default/xui/tr/menu_picks.xml
diff --git a/indra/newview/skins/default/xui/tr/menu_picks_plus.xml b/indra/newview/skins/default/xui/tr/menu_picks_plus.xml
index d9c4fefc97..d9c4fefc97 100644..100755
--- a/indra/newview/skins/default/xui/tr/menu_picks_plus.xml
+++ b/indra/newview/skins/default/xui/tr/menu_picks_plus.xml
diff --git a/indra/newview/skins/default/xui/tr/menu_place.xml b/indra/newview/skins/default/xui/tr/menu_place.xml
index ad167a328a..ad167a328a 100644..100755
--- a/indra/newview/skins/default/xui/tr/menu_place.xml
+++ b/indra/newview/skins/default/xui/tr/menu_place.xml
diff --git a/indra/newview/skins/default/xui/tr/menu_place_add_button.xml b/indra/newview/skins/default/xui/tr/menu_place_add_button.xml
index 8e52b3f7f2..8e52b3f7f2 100644..100755
--- a/indra/newview/skins/default/xui/tr/menu_place_add_button.xml
+++ b/indra/newview/skins/default/xui/tr/menu_place_add_button.xml
diff --git a/indra/newview/skins/default/xui/tr/menu_places_gear_folder.xml b/indra/newview/skins/default/xui/tr/menu_places_gear_folder.xml
index b3a2986160..b3a2986160 100644..100755
--- a/indra/newview/skins/default/xui/tr/menu_places_gear_folder.xml
+++ b/indra/newview/skins/default/xui/tr/menu_places_gear_folder.xml
diff --git a/indra/newview/skins/default/xui/tr/menu_places_gear_landmark.xml b/indra/newview/skins/default/xui/tr/menu_places_gear_landmark.xml
index 939ee2c7cb..939ee2c7cb 100644..100755
--- a/indra/newview/skins/default/xui/tr/menu_places_gear_landmark.xml
+++ b/indra/newview/skins/default/xui/tr/menu_places_gear_landmark.xml
diff --git a/indra/newview/skins/default/xui/tr/menu_profile_overflow.xml b/indra/newview/skins/default/xui/tr/menu_profile_overflow.xml
index ed60dec63a..ed60dec63a 100644..100755
--- a/indra/newview/skins/default/xui/tr/menu_profile_overflow.xml
+++ b/indra/newview/skins/default/xui/tr/menu_profile_overflow.xml
diff --git a/indra/newview/skins/default/xui/tr/menu_save_outfit.xml b/indra/newview/skins/default/xui/tr/menu_save_outfit.xml
index b28488fe30..b28488fe30 100644..100755
--- a/indra/newview/skins/default/xui/tr/menu_save_outfit.xml
+++ b/indra/newview/skins/default/xui/tr/menu_save_outfit.xml
diff --git a/indra/newview/skins/default/xui/tr/menu_script_chiclet.xml b/indra/newview/skins/default/xui/tr/menu_script_chiclet.xml
index 7c1cefc2d1..7c1cefc2d1 100644..100755
--- a/indra/newview/skins/default/xui/tr/menu_script_chiclet.xml
+++ b/indra/newview/skins/default/xui/tr/menu_script_chiclet.xml
diff --git a/indra/newview/skins/default/xui/tr/menu_slurl.xml b/indra/newview/skins/default/xui/tr/menu_slurl.xml
index 73ac068b26..73ac068b26 100644..100755
--- a/indra/newview/skins/default/xui/tr/menu_slurl.xml
+++ b/indra/newview/skins/default/xui/tr/menu_slurl.xml
diff --git a/indra/newview/skins/default/xui/tr/menu_teleport_history_gear.xml b/indra/newview/skins/default/xui/tr/menu_teleport_history_gear.xml
index b08423be18..b08423be18 100644..100755
--- a/indra/newview/skins/default/xui/tr/menu_teleport_history_gear.xml
+++ b/indra/newview/skins/default/xui/tr/menu_teleport_history_gear.xml
diff --git a/indra/newview/skins/default/xui/tr/menu_teleport_history_item.xml b/indra/newview/skins/default/xui/tr/menu_teleport_history_item.xml
index 93984162e7..93984162e7 100644..100755
--- a/indra/newview/skins/default/xui/tr/menu_teleport_history_item.xml
+++ b/indra/newview/skins/default/xui/tr/menu_teleport_history_item.xml
diff --git a/indra/newview/skins/default/xui/tr/menu_teleport_history_tab.xml b/indra/newview/skins/default/xui/tr/menu_teleport_history_tab.xml
index b1e801c123..b1e801c123 100644..100755
--- a/indra/newview/skins/default/xui/tr/menu_teleport_history_tab.xml
+++ b/indra/newview/skins/default/xui/tr/menu_teleport_history_tab.xml
diff --git a/indra/newview/skins/default/xui/tr/menu_text_editor.xml b/indra/newview/skins/default/xui/tr/menu_text_editor.xml
index ffbf309e84..76c7b43e1e 100644..100755
--- a/indra/newview/skins/default/xui/tr/menu_text_editor.xml
+++ b/indra/newview/skins/default/xui/tr/menu_text_editor.xml
@@ -1,5 +1,12 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Text editor context menu">
+ <menu_item_call label="(bilinmiyor)" name="Suggestion 1"/>
+ <menu_item_call label="(bilinmiyor)" name="Suggestion 2"/>
+ <menu_item_call label="(bilinmiyor)" name="Suggestion 3"/>
+ <menu_item_call label="(bilinmiyor)" name="Suggestion 4"/>
+ <menu_item_call label="(bilinmiyor)" name="Suggestion 5"/>
+ <menu_item_call label="Sözlüğe Ekle" name="Add to Dictionary"/>
+ <menu_item_call label="Yok saya ekle" name="Add to Ignore"/>
<menu_item_call label="Kes" name="Cut"/>
<menu_item_call label="Kopyala" name="Copy"/>
<menu_item_call label="Yapıştır" name="Paste"/>
diff --git a/indra/newview/skins/default/xui/tr/menu_toolbars.xml b/indra/newview/skins/default/xui/tr/menu_toolbars.xml
index c8523a6ec9..c8523a6ec9 100644..100755
--- a/indra/newview/skins/default/xui/tr/menu_toolbars.xml
+++ b/indra/newview/skins/default/xui/tr/menu_toolbars.xml
diff --git a/indra/newview/skins/default/xui/tr/menu_topinfobar.xml b/indra/newview/skins/default/xui/tr/menu_topinfobar.xml
index d9b8d50f18..d9b8d50f18 100644..100755
--- a/indra/newview/skins/default/xui/tr/menu_topinfobar.xml
+++ b/indra/newview/skins/default/xui/tr/menu_topinfobar.xml
diff --git a/indra/newview/skins/default/xui/tr/menu_url_agent.xml b/indra/newview/skins/default/xui/tr/menu_url_agent.xml
index d82b52aea8..109cd62495 100644..100755
--- a/indra/newview/skins/default/xui/tr/menu_url_agent.xml
+++ b/indra/newview/skins/default/xui/tr/menu_url_agent.xml
@@ -1,6 +1,9 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Url Popup">
- <menu_item_call label="Sakin Profilini Göster" name="show_agent"/>
+ <menu_item_call label="Profili Göster" name="show_agent"/>
+ <menu_item_call label="Aİ Gönder..." name="send_im"/>
+ <menu_item_call label="ArkadaÅŸ Ekle..." name="add_friend"/>
+ <menu_item_call label="Arkadaşı Çıkar..." name="remove_friend"/>
<menu_item_call label="Adı panoya kopyala" name="url_copy_label"/>
<menu_item_call label="SLurl&apos;yi Panoya Kopyala" name="url_copy"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/tr/menu_url_group.xml b/indra/newview/skins/default/xui/tr/menu_url_group.xml
index 40fa13b4cf..40fa13b4cf 100644..100755
--- a/indra/newview/skins/default/xui/tr/menu_url_group.xml
+++ b/indra/newview/skins/default/xui/tr/menu_url_group.xml
diff --git a/indra/newview/skins/default/xui/tr/menu_url_http.xml b/indra/newview/skins/default/xui/tr/menu_url_http.xml
index fee8eba150..fee8eba150 100644..100755
--- a/indra/newview/skins/default/xui/tr/menu_url_http.xml
+++ b/indra/newview/skins/default/xui/tr/menu_url_http.xml
diff --git a/indra/newview/skins/default/xui/tr/menu_url_inventory.xml b/indra/newview/skins/default/xui/tr/menu_url_inventory.xml
index 3b22c5afec..3b22c5afec 100644..100755
--- a/indra/newview/skins/default/xui/tr/menu_url_inventory.xml
+++ b/indra/newview/skins/default/xui/tr/menu_url_inventory.xml
diff --git a/indra/newview/skins/default/xui/tr/menu_url_map.xml b/indra/newview/skins/default/xui/tr/menu_url_map.xml
index 770e330516..770e330516 100644..100755
--- a/indra/newview/skins/default/xui/tr/menu_url_map.xml
+++ b/indra/newview/skins/default/xui/tr/menu_url_map.xml
diff --git a/indra/newview/skins/default/xui/tr/menu_url_objectim.xml b/indra/newview/skins/default/xui/tr/menu_url_objectim.xml
index d55e34c11c..ae68669605 100644..100755
--- a/indra/newview/skins/default/xui/tr/menu_url_objectim.xml
+++ b/indra/newview/skins/default/xui/tr/menu_url_objectim.xml
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Url Popup">
- <menu_item_call label="Nesne Bilgilerini Göster" name="show_object"/>
+ <menu_item_call label="Nesne Profili..." name="show_object"/>
+ <menu_item_call label="Engelle..." name="block_object"/>
<menu_item_call label="Haritada Göster" name="show_on_map"/>
<menu_item_call label="Nesne Konumuna Işınla" name="teleport_to_object"/>
<menu_item_call label="Nesne Adını panoya kopyala" name="url_copy_label"/>
diff --git a/indra/newview/skins/default/xui/tr/menu_url_parcel.xml b/indra/newview/skins/default/xui/tr/menu_url_parcel.xml
index eac1d743c3..eac1d743c3 100644..100755
--- a/indra/newview/skins/default/xui/tr/menu_url_parcel.xml
+++ b/indra/newview/skins/default/xui/tr/menu_url_parcel.xml
diff --git a/indra/newview/skins/default/xui/tr/menu_url_slapp.xml b/indra/newview/skins/default/xui/tr/menu_url_slapp.xml
index a2ecfc6a48..a2ecfc6a48 100644..100755
--- a/indra/newview/skins/default/xui/tr/menu_url_slapp.xml
+++ b/indra/newview/skins/default/xui/tr/menu_url_slapp.xml
diff --git a/indra/newview/skins/default/xui/tr/menu_url_slurl.xml b/indra/newview/skins/default/xui/tr/menu_url_slurl.xml
index 3f4e51b36c..3f4e51b36c 100644..100755
--- a/indra/newview/skins/default/xui/tr/menu_url_slurl.xml
+++ b/indra/newview/skins/default/xui/tr/menu_url_slurl.xml
diff --git a/indra/newview/skins/default/xui/tr/menu_url_teleport.xml b/indra/newview/skins/default/xui/tr/menu_url_teleport.xml
index b7035a4d8f..b7035a4d8f 100644..100755
--- a/indra/newview/skins/default/xui/tr/menu_url_teleport.xml
+++ b/indra/newview/skins/default/xui/tr/menu_url_teleport.xml
diff --git a/indra/newview/skins/default/xui/tr/menu_viewer.xml b/indra/newview/skins/default/xui/tr/menu_viewer.xml
index d7b20bac4b..4236f91636 100644..100755
--- a/indra/newview/skins/default/xui/tr/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/tr/menu_viewer.xml
@@ -17,8 +17,8 @@
<menu_item_call label="Yürü / koş / uç..." name="Walk / run / fly"/>
</menu>
<menu label="Durum" name="Status">
- <menu_item_call label="Uzakta" name="Set Away"/>
- <menu_item_call label="MeÅŸgul" name="Set Busy"/>
+ <menu_item_check label="Uzakta" name="Away"/>
+ <menu_item_check label="Rahatsız Etme" name="Do Not Disturb"/>
</menu>
<menu_item_call label="L$ Satın Al..." name="Buy and Sell L$"/>
<menu_item_call label="Satıcı Giden Kutusu..." name="MerchantOutbox"/>
@@ -26,17 +26,25 @@
<menu_item_call label="Tercihler..." name="Preferences"/>
<menu_item_call label="Araç çubuğu düğmeleri..." name="Toolbars"/>
<menu_item_call label="Tüm denetimleri sakla" name="Hide UI"/>
+ <menu_item_check label="BÜG Aksesuarlarını Göster" name="Show HUD Attachments"/>
<menu_item_call label="[APP_NAME]&apos;den Çık" name="Quit"/>
</menu>
<menu label="Ä°letiÅŸim Kur" name="Communicate">
- <menu_item_check label="Sohbet..." name="Nearby Chat"/>
+ <menu_item_check label="Sohbetler..." name="Conversations"/>
+ <menu_item_check label="Yakındaki Sohbet..." name="Nearby Chat"/>
<menu_item_check label="KonuÅŸ" name="Speak"/>
- <menu_item_check label="Ses ayarları..." name="Nearby Voice"/>
- <menu_item_check label="Ses ÅŸekillendirme..." name="ShowVoice"/>
+ <menu_item_check label="Sohbet Günlüğü..." name="Conversation Log..."/>
+ <menu label="Ses ÅŸekillendirme" name="VoiceMorphing">
+ <menu_item_check label="Ses ÅŸekillendirme yok" name="NoVoiceMorphing"/>
+ <menu_item_check label="Önizleme..." name="Preview"/>
+ <menu_item_call label="Abone ol..." name="Subscribe"/>
+ </menu>
<menu_item_check label="Mimikler..." name="Gestures"/>
- <menu_item_call label="ArkadaÅŸlar" name="My Friends"/>
- <menu_item_call label="Gruplar" name="My Groups"/>
- <menu_item_call label="Yakındaki kişiler" name="Active Speakers"/>
+ <menu_item_check label="ArkadaÅŸlar" name="My Friends"/>
+ <menu_item_check label="Gruplar" name="My Groups"/>
+ <menu_item_check label="Yakındaki kişiler" name="Active Speakers"/>
+ <menu_item_call label="Engelleme Listesi" name="Block List"/>
+ <menu_item_check label="Rahatsız Etme" name="Do Not Disturb"/>
</menu>
<menu label="Dünya" name="World">
<menu_item_call label="Bu Yeri Yer Ä°mlerine Ekle" name="Create Landmark Here"/>
@@ -105,13 +113,13 @@
<menu_item_call label="Sonraki Parçayı Dahil Et" name="Include Next Part"/>
<menu_item_call label="Önceki Parçayı Dahil Et" name="Include Previous Part"/>
</menu>
+ <menu_item_call label="Bağlantı kümeleri..." name="pathfinding_linkset_menu_item"/>
<menu_item_call label="Seçime Odaklan" name="Focus on Selection"/>
<menu_item_call label="Seçimi Yakınlaştır" name="Zoom to Selection"/>
<menu label="Nesne" name="Object">
<menu_item_call label="Satın Al" name="Menu Object Buy"/>
<menu_item_call label="Al" name="Menu Object Take"/>
<menu_item_call label="Kopya Al" name="Take Copy"/>
- <menu_item_call label="Envanterime Geri Kaydet" name="Save Object Back to My Inventory"/>
<menu_item_call label="Nesne İçeriklerine Geri Kaydet" name="Save Object Back to Object Contents"/>
<menu_item_call label="Nesneyi Ä°ade Et" name="Return Object back to Owner"/>
</menu>
@@ -122,6 +130,12 @@
<menu_item_call label="Komut Dosyalarını Çalışıyor Olarak Ayarla" name="Set Scripts to Running"/>
<menu_item_call label="Komut Dosyalarını Çalışmıyor Olarak Ayarla" name="Set Scripts to Not Running"/>
</menu>
+ <menu label="Yol bulma" name="Pathfinding">
+ <menu_item_call label="Bağlantı kümeleri..." name="pathfinding_linksets_menu_item"/>
+ <menu_item_call label="Karakterler..." name="pathfinding_characters_menu_item"/>
+ <menu_item_call label="Görüntüleme / test..." name="pathfinding_console_menu_item"/>
+ <menu_item_call label="Bölgeyi tekrar kaydet" name="pathfinding_rebake_navmesh_item"/>
+ </menu>
<menu label="Seçenklr." name="Options">
<menu_item_check label="Gelişmiş İzinleri Göster" name="DebugPermissions"/>
<menu_item_check label="Sadece Nesnelerimi Seç" name="Select Only My Objects"/>
@@ -150,6 +164,13 @@
<menu label="Yardım" name="Help">
<menu_item_call label="Nasıl yapılır..." name="How To"/>
<menu_item_call label="[SECOND_LIFE] Yardımı" name="Second Life Help"/>
+ <menu_item_call label="Kullanıcı kılavuzu" name="User’s guide"/>
+ <menu_item_call label="Bilgi Bankası" name="Knowledge Base"/>
+ <menu_item_call label="Wiki" name="Wiki"/>
+ <menu_item_call label="Topluluk Forumları" name="Community Forums"/>
+ <menu_item_call label="Destek portalı" name="Support portal"/>
+ <menu_item_call label="[SECOND_LIFE] Haberleri" name="Second Life News"/>
+ <menu_item_call label="[SECOND_LIFE] Blogları" name="Second Life Blogs"/>
<menu_item_call label="Kötüye Kullanımı Bildir" name="Report Abuse"/>
<menu_item_call label="Hata Bildir" name="Report Bug"/>
<menu_item_call label="[APP_NAME] Hakkında" name="About Second Life"/>
@@ -172,7 +193,6 @@
<menu_item_check label="Parçacıkları Gizle" name="Hide Particles"/>
<menu_item_check label="Seçilenleri Gizle" name="Hide Selected"/>
<menu_item_check label="Saydamı Vurgula" name="Highlight Transparent"/>
- <menu_item_check label="BÜG Aksesuarlarını Göster" name="Show HUD Attachments"/>
<menu_item_check label="Fare Üzerinden Görünüm Artı İşaretini Göster" name="ShowCrosshairs"/>
</menu>
<menu label="İşleme Türleri" name="Rendering Types">
@@ -225,11 +245,10 @@
<menu_item_check label="Doku Konsolu" name="Texture Console"/>
<menu_item_check label="Hata Ayıklama Konsolu" name="Debug Console"/>
<menu_item_call label="Bildirimler Konsolu" name="Notifications"/>
- <menu_item_check label="Doku Büyüklüğü Konsolu" name="Texture Size"/>
- <menu_item_check label="Doku Kategorisi Konsolu" name="Texture Category"/>
<menu_item_check label="Hızlı Zamanlayıcılar" name="Fast Timers"/>
<menu_item_check label="Bellek" name="Memory"/>
<menu_item_check label="Sahne Ä°statistikleri" name="Scene Statistics"/>
+ <menu_item_call label="Doku Alınması Hata Ayıklama Konsolu" name="Texture Fetch Debug Console"/>
<menu_item_call label="Hata Ayıklama Konsoluna giden Bölge Bilgisi" name="Region Info to Debug Console"/>
<menu_item_call label="Hata Ayıklama Konsoluna giden Grup Bilgisi" name="Group Info to Debug Console"/>
<menu_item_call label="Hata Ayıklama Konsoluna giden Özellikler Bilgisi" name="Capabilities Info to Debug Console"/>
@@ -264,6 +283,7 @@
<menu_item_check label="Çerçeve Hızını Rastgele Seç" name="Randomize Framerate"/>
<menu_item_check label="Düzenli Yavaş Çerçeve" name="Periodic Slow Frame"/>
<menu_item_check label="Çerçeve Testi" name="Frame Test"/>
+ <menu_item_call label="Çerçeve Profili..." name="Frame Profile"/>
</menu>
<menu label="Meta Verileri Ä°ÅŸle" name="Render Metadata">
<menu_item_check label="Sınırlama Kutuları" name="Bounding Boxes"/>
@@ -287,14 +307,21 @@
<menu_item_check label="İşleme Karmaşıklığı" name="rendercomplexity"/>
<menu_item_check label="Aksesuar Bayt Büyüklüğü" name="attachment bytes"/>
<menu_item_check label="Åžekillendir" name="Sculpt"/>
+ <menu label="Doku YoÄŸunluÄŸu" name="Texture Density">
+ <menu_item_check label="Yok" name="None"/>
+ <menu_item_check label="Mevcut" name="Current"/>
+ <menu_item_check label="Arzulanan" name="Desired"/>
+ <menu_item_check label="Tam" name="Full"/>
+ </menu>
</menu>
<menu label="Ä°ÅŸleme" name="Rendering">
<menu_item_check label="Eksenler" name="Axes"/>
<menu_item_check label="Tanjant Temeli" name="Tangent Basis"/>
<menu_item_call label="Seçilen Doku Bilgi Temeli" name="Selected Texture Info Basis"/>
+ <menu_item_call label="Seçilen Malzeme Bilgisi" name="Selected Material Info"/>
<menu_item_check label="Telkafes" name="Wireframe"/>
<menu_item_check label="Görünen Nesneler İçin Gölgeleme" name="Object-Object Occlusion"/>
- <menu_item_check label="Işıklandırma ve Gölgeler" name="Lighting and Shadows"/>
+ <menu_item_check label="Gelişmiş Aydınlatma Modeli" name="Advanced Lighting Model"/>
<menu_item_check label="Güneş/Ay/Projektörlerden Gelen Gölgeler" name="Shadows from Sun/Moon/Projectors"/>
<menu_item_check label="SSAO ve Gölge Yumuşatma" name="SSAO and Shadow Smoothing"/>
<menu_item_check label="GL Hata Ayıklama" name="Debug GL"/>
@@ -304,8 +331,6 @@
<menu_item_check label="Animasyon Dokuları" name="Animation Textures"/>
<menu_item_check label="Dokuları Devre Dışı Bırak" name="Disable Textures"/>
<menu_item_check label="Tam Çöz. Dokular" name="Rull Res Textures"/>
- <menu_item_check label="Dokuları Denetle" name="Audit Textures"/>
- <menu_item_check label="Doku Atlas (deneysel)" name="Texture Atlas"/>
<menu_item_check label="Eklenmiş Işıkları İşle" name="Render Attached Lights"/>
<menu_item_check label="Eklenmiş Parçacıkları İşle" name="Render Attached Particles"/>
<menu_item_check label="Parıldayan Nesneler Üzerine Gel" name="Hover Glow Objects"/>
@@ -341,7 +366,6 @@
<menu_item_call label="Odaklayıcı Tutucunun Dökümünü Al" name="Dump Focus Holder"/>
<menu_item_call label="Seçilen Nesne Bilgisini Yazdır" name="Print Selected Object Info"/>
<menu_item_call label="Aracı Bilgisini Yazdır" name="Print Agent Info"/>
- <menu_item_call label="Bellek Ä°statistikleri" name="Memory Stats"/>
<menu_item_check label="Bölge Hata Ayıklama Konsolu" name="Region Debug Console"/>
<menu_item_check label="SelectMgr İçin Hata Ayıklama" name="Debug SelectMgr"/>
<menu_item_check label="Tıklamalar İçin Hata Ayıklama" name="Debug Clicks"/>
@@ -371,12 +395,16 @@
<menu_item_call label="Karakter Geometrisini Aç/Kapa" name="Toggle Character Geometry"/>
<menu_item_call label="Test ErkeÄŸi" name="Test Male"/>
<menu_item_call label="Test DiÅŸisi" name="Test Female"/>
- <menu_item_call label="PG&apos;yi Aç/Kapa" name="Toggle PG"/>
<menu_item_check label="Avatar Seçimine İzin Ver" name="Allow Select Avatar"/>
</menu>
+ <menu label="Animasyon Hızı" name="Animation Speed">
+ <menu_item_call label="Tüm Animasyonlar %10 Daha Hızlı" name="All Animations 10 Faster"/>
+ <menu_item_call label="Tüm Animasyonlar %10 Daha Yavaş" name="All Animations 10 Slower"/>
+ <menu_item_call label="Tüm Animasyon Hızlarını Sıfırla" name="Reset All Animation Speed"/>
+ <menu_item_check label="Yavaş Hareket Animasyonları" name="Slow Motion Animations"/>
+ </menu>
<menu_item_call label="Parametreleri Varsayılana Zorla" name="Force Params to Default"/>
<menu_item_check label="Animasyon Bilgisi" name="Animation Info"/>
- <menu_item_check label="Yavaş Hareket Animasyonları" name="Slow Motion Animations"/>
<menu_item_check label="Şuraya Bak&apos;ı Göster" name="Show Look At"/>
<menu_item_check label="Şuraya İşaret Et&apos;i Göster" name="Show Point At"/>
<menu_item_check label="Eklem Güncelleştirmeleri İçin Hata Ayıklama" name="Debug Joint Updates"/>
diff --git a/indra/newview/skins/default/xui/tr/menu_wearable_list_item.xml b/indra/newview/skins/default/xui/tr/menu_wearable_list_item.xml
index 448202df87..448202df87 100644..100755
--- a/indra/newview/skins/default/xui/tr/menu_wearable_list_item.xml
+++ b/indra/newview/skins/default/xui/tr/menu_wearable_list_item.xml
diff --git a/indra/newview/skins/default/xui/tr/menu_wearing_gear.xml b/indra/newview/skins/default/xui/tr/menu_wearing_gear.xml
index 438e580cd3..438e580cd3 100644..100755
--- a/indra/newview/skins/default/xui/tr/menu_wearing_gear.xml
+++ b/indra/newview/skins/default/xui/tr/menu_wearing_gear.xml
diff --git a/indra/newview/skins/default/xui/tr/menu_wearing_tab.xml b/indra/newview/skins/default/xui/tr/menu_wearing_tab.xml
index 9796546559..9796546559 100644..100755
--- a/indra/newview/skins/default/xui/tr/menu_wearing_tab.xml
+++ b/indra/newview/skins/default/xui/tr/menu_wearing_tab.xml
diff --git a/indra/newview/skins/default/xui/tr/mime_types.xml b/indra/newview/skins/default/xui/tr/mime_types.xml
index c37f872a65..c37f872a65 100644..100755
--- a/indra/newview/skins/default/xui/tr/mime_types.xml
+++ b/indra/newview/skins/default/xui/tr/mime_types.xml
diff --git a/indra/newview/skins/default/xui/tr/mime_types_linux.xml b/indra/newview/skins/default/xui/tr/mime_types_linux.xml
index c37f872a65..c37f872a65 100644..100755
--- a/indra/newview/skins/default/xui/tr/mime_types_linux.xml
+++ b/indra/newview/skins/default/xui/tr/mime_types_linux.xml
diff --git a/indra/newview/skins/default/xui/tr/mime_types_mac.xml b/indra/newview/skins/default/xui/tr/mime_types_mac.xml
index c37f872a65..c37f872a65 100644..100755
--- a/indra/newview/skins/default/xui/tr/mime_types_mac.xml
+++ b/indra/newview/skins/default/xui/tr/mime_types_mac.xml
diff --git a/indra/newview/skins/default/xui/tr/notifications.xml b/indra/newview/skins/default/xui/tr/notifications.xml
index 6681cdac7a..492178ab82 100644..100755
--- a/indra/newview/skins/default/xui/tr/notifications.xml
+++ b/indra/newview/skins/default/xui/tr/notifications.xml
@@ -37,6 +37,12 @@
<button name="Help" text="$helptext"/>
</form>
</template>
+ <template name="okhelpignore">
+ <form>
+ <button name="OK_okhelpignore" text="$yestext"/>
+ <button name="Help_okhelpignore" text="$helptext"/>
+ </form>
+ </template>
<template name="yesnocancelbuttons">
<form>
<button name="Yes" text="$yestext"/>
@@ -204,6 +210,14 @@ Bu Yetenek &apos;[ROLE_NAME]&apos; rolüne eklensin mi?
Bu Yetenek &apos;[ROLE_NAME]&apos; rolüne eklensin mi?
<usetemplate name="okcancelbuttons" notext="Hayır" yestext="Evet"/>
</notification>
+ <notification name="EjectGroupMemberWarning">
+ Gruptan [AVATAR_NAME] adlı üyeyi çıkarmak üzeresiniz.
+ <usetemplate ignoretext="Gruptan bir katılımcının çıkarılmasını doğrulayın" name="okcancelignore" notext="İptal" yestext="Çıkar"/>
+ </notification>
+ <notification name="EjectGroupMembersWarning">
+ Gruptan [COUNT] üyeyi çıkarmak üzeresiniz.
+ <usetemplate ignoretext="Gruptan birden çok üyenin çıkarılmasını doğrulayın" name="okcancelignore" notext="İptal" yestext="Çıkar"/>
+ </notification>
<notification name="AttachmentDrop">
Aksesuarınızı çıkarmak üzeresiniz.
Devam etmek istediÄŸinize emin misiniz?
@@ -360,13 +374,19 @@ Avatarınızın Kullanıcı adını girmeniz gerekmektedir.
[SECOND_LIFE]&apos;a giriş yapmak için bir hesabınız olması gerekir. Şimdi bir hesap oluşturmak ister misiniz?
<url name="url">
- http://join.secondlife.com/
+ [create_account_url]
</url>
<usetemplate name="okcancelbuttons" notext="Tekrar dene" yestext="Yeni bir hesap oluÅŸtur"/>
</notification>
<notification name="InvalidCredentialFormat">
Kullanıcı adı alanına Avatarınızın Kullanıcı adını ya da Ad ve Soyadını girmeniz ve yeniden oturum açmanız gerekmektedir.
</notification>
+ <notification name="InvalidGrid">
+ &apos;[GRID]&apos; geçerli bir ağ tanımlayıcısı değil.
+ </notification>
+ <notification name="InvalidLocationSLURL">
+ Başlangıç konumunuz için geçerli bir ağ belirtilmedi.
+ </notification>
<notification name="DeleteClassified">
&apos;[NAME]&apos; ilanı silinsin mi?
Ödenen ücretler iade edilmeyecektir.
@@ -472,8 +492,8 @@ Nesne aralık dışında ya da silinmiş olabilir.
Aşağıdaki nedenden dolayı, derlenen komut dosyası kaydedilirken bir sorun oluştu: [REASON]. Lütfen komut dosyasını kaydetmeyi daha sonra tekrar deneyin.
</notification>
<notification name="StartRegionEmpty">
- Hata. Başlangıç Bölgeniz tanımlanmamış.
-Lütfen Başlangıç Konumu kutusuna Bölge adını yazın ya da Son Konumum veya Ana Konumumu Başlangıç Konumu olarak seçin.
+ Başlangıç Bölgeniz tanımlanmamış.
+Lütfen Başlangıç Konumu kutusuna Bölge adını yazın ya da Son Bulunduğum Konum veya Ana Konumumu Başlangıç Konumu olarak seçin.
<usetemplate name="okbutton" yestext="Tamam"/>
</notification>
<notification name="CouldNotStartStopScript">
@@ -495,6 +515,33 @@ Daha fazla bilgi için [_URL] adresini ziyaret etmek ister misiniz?
</url>
<usetemplate ignoretext="Bilgisayar donanımım desteklenmiyor" name="okcancelignore" notext="Hayır" yestext="Evet"/>
</notification>
+ <notification name="IntelOldDriver">
+ Grafik yonganız için muhtemelen daha yeni bir sürücü mevcut. Grafik sürücüleri güncellemek performansınızı kayda değer şekilde artırabilir.
+
+ Sürücü güncellemeleri için [_URL] adresini ziyaret etmek ister misiniz?
+ <url name="url">
+ http://www.intel.com/p/en_US/support/detect/graphics
+ </url>
+ <usetemplate ignoretext="Grafik sürücüm güncel değil" name="okcancelignore" notext="Hayır" yestext="Evet"/>
+ </notification>
+ <notification name="AMDOldDriver">
+ Grafik yonganız için muhtemelen daha yeni bir sürücü mevcut. Grafik sürücüleri güncellemek performansınızı kayda değer şekilde artırabilir.
+
+ Sürücü güncellemeleri için [_URL] adresini ziyaret etmek ister misiniz?
+ <url name="url">
+ http://support.amd.com/us/Pages/AMDSupportHub.aspx
+ </url>
+ <usetemplate ignoretext="Grafik sürücüm güncel değil" name="okcancelignore" notext="Hayır" yestext="Evet"/>
+ </notification>
+ <notification name="NVIDIAOldDriver">
+ Grafik yonganız için muhtemelen daha yeni bir sürücü mevcut. Grafik sürücüleri güncellemek performansınızı kayda değer şekilde artırabilir.
+
+ Sürücü güncellemeleri için [_URL] adresini ziyaret etmek ister misiniz?
+ <url name="url">
+ http://www.nvidia.com/Download/index.aspx?lang=en-us
+ </url>
+ <usetemplate ignoretext="Grafik sürücüm güncel değil" name="okcancelignore" notext="Hayır" yestext="Evet"/>
+ </notification>
<notification name="UnknownGPU">
Sisteminiz [APP_NAME] uygulamasının tanımadığı bir grafik kartı içeriyor.
Bu durum genellikle [APP_NAME] uygulaması ile henüz denenmemiş yeni donanımlar kullanıldığında ortaya çıkar. Büyük olasılıkla bir sorun çıkmayacaktır, fakat grafik ayarlarınızı değiştirmeniz gerekebilir.
@@ -591,6 +638,9 @@ En fazla [MAX] nesneyi birbirine baÄŸlayabilirsiniz.
Lütfen hiçbirinin kilitli olmadığından ve hepsine sahip olduğunuzdan emin olun.
</notification>
+ <notification name="CannotLinkPermanent">
+ Nesneler bölge sınırları üzerinden bağlantılandırılamaz.
+ </notification>
<notification name="CannotLinkDifferentOwners">
Nesnelerin hepsinin sahibi aynı olmadığı için nesneler birbirine bağlanamıyor.
@@ -969,6 +1019,41 @@ Etkin grubunuz adına arazi satın almak için gerekli izne sahip değilsiniz.
<button name="Cancel" text="Ä°ptal"/>
</form>
</notification>
+ <notification label="Otomatik Yerine Koyma Listesine Ekle" name="AddAutoReplaceList">
+ Yeni liste için isim:
+ <form name="form">
+ <button name="SetName" text="Tamam"/>
+ </form>
+ </notification>
+ <notification label="Otomatik Yerine Koyma Listesinin Adını Değiştir" name="RenameAutoReplaceList">
+ &apos;[DUPNAME]&apos; adı kullanılıyor
+ Benzersiz yeni bir ad girin:
+ <form name="form">
+ <button name="ReplaceList" text="Mevcut Listenin Yerine Koy"/>
+ <button name="SetName" text="Yeni Adı Kullan"/>
+ </form>
+ </notification>
+ <notification name="InvalidAutoReplaceEntry">
+ Anahtar kelime tek bir kelime olmalıdır; değiştirme boş olamaz.
+ </notification>
+ <notification name="InvalidAutoReplaceList">
+ Bu değiştirme listesi geçerli değil.
+ </notification>
+ <notification name="SpellingDictImportRequired">
+ Bir dosya, ad ve dil belirtmelisiniz.
+ </notification>
+ <notification name="SpellingDictIsSecondary">
+ [DIC_NAME] sözlüğünde bir &quot;aff&quot; dosyası yok gibi görünüyor; bu da &quot;ikincil&quot; bir sözlük olduğu anlamına gelir.
+İlave bir sözlük olarak kullanılabilir; ancak Ana sözlüğünüz olarak kullanılamaz.
+
+Bkz. https://wiki.secondlife.com/wiki/Adding_Spelling_Dictionaries
+ </notification>
+ <notification name="SpellingDictImportFailed">
+ Şu kopyalama yapılamıyor:
+ [FROM_NAME]
+ kaynağından şuraya:
+ [TO_NAME]
+ </notification>
<notification label="Dış Görünümü Kaydet" name="SaveOutfitAs">
Üzerimdekileri yeni bir Dış Görünüm olarak kaydet:
<form name="form">
@@ -1034,7 +1119,7 @@ bu simdeki TÃœM ARAZÄ°LERDEN SÄ°LMEK istediÄŸinize emin misiniz?
Lütfen daha yüksek bir tutar girin.
</notification>
<notification name="ConfirmItemDeleteHasLinks">
- Seçtiğiniz öğelerden en az birinin kendisine işaret eden bağlantılı öğeler var. Bu öğeyi silerseniz, bağlantıları kalıcı olarak çalışmaz hale gelecek. Önce bağlantıları silmeniz önemle tavsiye edilir.
+ Öğelerden en az birinde kendisine işaret eden bağlantılar var. Bu öğeyi silerseniz, bağlantıları kalıcı olarak çalışmaz hale gelecek. Önce bağlantıları silmeniz önemle tavsiye edilir.
Bu öğeleri silmek istediğinize emin misiniz?
<usetemplate name="okcancelbuttons" notext="Ä°ptal" yestext="Tamam"/>
@@ -1148,7 +1233,7 @@ sonraki: &apos;[THIS_GPU]&apos;
Yakınındaki başka bir bölgeye taşındınız.
</notification>
<notification name="AvatarMovedLast">
- Son konumunuz şu anda kullanılamıyor.
+ Talep ettiğiniz konum şu anda kullanılamıyor.
Yakınındaki başka bir bölgeye taşındınız.
</notification>
<notification name="AvatarMovedHome">
@@ -1164,11 +1249,10 @@ Yeni bir ana konum ayarlamak isteyebilirsiniz.
</form>
</notification>
<notification name="FirstRun">
- [APP_NAME] kurulumu tamamlandı.
+ [APP_NAME] yüklemesi tamamlandı.
[SECOND_LIFE]&apos;ı ilk kez kullanıyorsanız, oturum açmadan önce bir hesap oluşturmalısınız.
-Yeni bir hesap oluşturmak için [http://join.secondlife.com secondlife.com] adresine dönülsün mü?
- <usetemplate name="okcancelbuttons" notext="Devam" yestext="Yeni Hesap..."/>
+ <usetemplate name="okcancelbuttons" notext="Devam" yestext="Hesap OluÅŸtur..."/>
</notification>
<notification name="LoginPacketNeverReceived">
Bağlantıda sorun yaşıyoruz. İnternet bağlantınızda ya da [SECOND_LIFE_GRID] uygulamasında bir problem olabilir.
@@ -1403,14 +1487,44 @@ Sürüm [VERSION] [[RELEASE_NOTES_FULL_URL] Bu güncelleme hakkında ayrıntılÄ
<usetemplate name="okcancelbuttons" notext="Sonra..." yestext="Şimdi kur ve [APP_NAME] uygulamasını yeniden başlat"/>
</notification>
<notification name="RequiredUpdateDownloadedVerboseDialog">
- Gerekli bir yazılım güncellemesini karşıdan yükledik.
-Sürüm [VERSION]
+ Gerekli bir yazılım güncellemesi indirdik.
+Sürüm [VERSION] [[INFO_URL] Bu güncelleme hakkında ayrıntılı bilgi]
-Güncellemeyi kurmak için [APP_NAME] uygulamasını yeniden başlatmalısınız.
+Güncellemeyi yüklemek için [APP_NAME] uygulamasını yeniden başlatmalısınız.
<usetemplate name="okbutton" yestext="Tamam"/>
</notification>
<notification name="RequiredUpdateDownloadedDialog">
- Güncellemeyi kurmak için [APP_NAME] uygulamasını yeniden başlatmalısınız.
+ Güncellemeyi yüklemek için [APP_NAME] uygulamasını yeniden başlatmalısınız.
+[[INFO_URL] Bu güncelleme hakkında bilgi]
+ <usetemplate name="okbutton" yestext="Tamam"/>
+ </notification>
+ <notification name="OtherChannelDownloadBackgroundTip">
+ [APP_NAME] kurulumunuz için bir güncelleme indirdik.
+Sürüm [VERSION]
+Bu deneysel görüntüleyicinin yerini bir [NEW_CHANNEL] görüntüleyici aldı;
+bkz. [bu güncelleme hakkında bilgi için [INFO_URL]]
+ <usetemplate name="okcancelbuttons" notext="Sonra..." yestext="Şimdi yükle ve [APP_NAME] uygulamasını yeniden başlat"/>
+ </notification>
+ <notification name="OtherChannelDownloadBackgroundDialog">
+ [APP_NAME] kurulumunuz için bir güncelleme indirdik.
+Sürüm [VERSION]
+Bu deneysel görüntüleyicinin yerini bir [NEW_CHANNEL] görüntüleyici aldı;
+bkz. [[INFO_URL] Bu güncelleme hakkında bilgi]
+ <usetemplate name="okcancelbuttons" notext="Sonra..." yestext="Şimdi yükle ve [APP_NAME] uygulamasını yeniden başlat"/>
+ </notification>
+ <notification name="OtherChannelRequiredUpdateDownloadedVerboseDialog">
+ Gerekli bir yazılım güncellemesi indirdik.
+Sürüm [VERSION]
+Bu deneysel görüntüleyicinin yerini bir [NEW_CHANNEL] görüntüleyici aldı;
+bkz. [[INFO_URL] Bu güncelleme hakkında bilgi]
+
+Güncellemeyi yüklemek için [APP_NAME] uygulamasını yeniden başlatmalısınız.
+ <usetemplate name="okbutton" yestext="Tamam"/>
+ </notification>
+ <notification name="OtherChannelRequiredUpdateDownloadedDialog">
+ Güncellemeyi yüklemek için [APP_NAME] uygulamasını yeniden başlatmalısınız.
+Bu deneysel görüntüleyicinin yerini bir [NEW_CHANNEL] görüntüleyici aldı;
+bkz. [[INFO_URL] Bu güncelleme hakkında bilgi]
<usetemplate name="okbutton" yestext="Tamam"/>
</notification>
<notification name="DeedObjectToGroup">
@@ -1461,6 +1575,10 @@ Güncellemeyi kurmak için [APP_NAME] uygulamasını yeniden başlatmalısınız
Gruptan ayrılmak istiyor musunuz?
<usetemplate name="okcancelbuttons" notext="Ä°ptal" yestext="Tamam"/>
</notification>
+ <notification name="OwnerCannotLeaveGroup">
+ Gruptan ayrılınamıyor. Gruptan ayrılamazsınız çünkü grubun son sahibisiniz. Lütfen önce sahip rolüne başka bir üye atayın.
+ <usetemplate name="okbutton" yestext="Tamam"/>
+ </notification>
<notification name="ConfirmKick">
Tüm Sakinleri GERÇEKTEN ağ dışına çıkarmak istiyor musunuz?
<usetemplate name="okcancelbuttons" notext="İptal Et" yestext="Tüm Sakinleri Çıkar"/>
@@ -1488,10 +1606,13 @@ Gruptan ayrılmak istiyor musunuz?
Şu anda arkadaşlık teklif edilemiyor. Lütfen biraz sonra tekrar deneyin.
<usetemplate name="okbutton" yestext="Tamam"/>
</notification>
- <notification name="BusyModeSet">
- Durumunuz Meşgul olarak ayarlandı.
-Sohbet ve anlık iletiler gizlenecek. Anlık iletilere Meşgul durumu için belirlediğiniz yanıt gönderilecek. Tüm ışınlanma teklifleri reddedilecek. Tüm envanter teklifleri Çöp Kutunuza gidecek.
- <usetemplate ignoretext="Durumumu MeÅŸgul olarak deÄŸiÅŸtiriyorum" name="okignore" yestext="Tamam"/>
+ <notification name="DoNotDisturbModeSet">
+ Rahatsız Etme açık. Gelen iletişimlerle ilgili size bilgi verilmeyecek.
+
+- Diğer sakinlere sizin Rahatsız Etmeyin yanıtı iletilecektir (Tercihler &gt; Genel içerisinde ayarlanır).
+- Işınlanma teklifleri reddedilecektir.
+- Sesli aramalar reddedilecektir.
+ <usetemplate ignoretext="Durumumu Rahatsız Etme moduna değiştiriyorum" name="okignore" yestext="Tamam"/>
</notification>
<notification name="JoinedTooManyGroupsMember">
Maksimum grup sayısına eriştiniz. Lütfen bu gruba katılmadan önce başka bir gruptan ayrılın ya da bu teklifi reddedin.
@@ -1685,83 +1806,128 @@ Binlerce bölgeyi değiştirecek ve alan sunucusunu kesintiye uğratacaktır.
<usetemplate name="okcancelbuttons" notext="Ä°ptal" yestext="Tamam"/>
</notification>
<notification name="RegionEntryAccessBlocked">
- Erişkinlik Seviyesi ayarlarınızdan dolayı bu Bölgeye giremezsiniz. Bu sorun yaşınızı doğrulamak için gerekli bilgilerin eksik olmasından kaynaklanabilir.
-
-Lütfen en son Görüntüleyicinin yüklü olduğunu doğrulayın ve bu erişkinlik seviyesi ile erişilecek alanlar hakkında ayrıntılı bilgi edinmek için Bilgi Bankası&apos;nı ziyaret edin.
+ Ziyaret etmeye çalıştığınız bölge, mevcut tercihlerinizi aşan içeriğe sahip. Ben &gt; Tercihler &gt; Genel sekmesini kullanarak tercihlerinizi değiştirebilirsiniz.
<usetemplate name="okbutton" yestext="Tamam"/>
</notification>
- <notification name="RegionEntryAccessBlocked_KB">
- Erişkinlik Seviyesi ayarlarınızdan dolayı bu bölgeye giremezsiniz.
-
-Erişkinlik Seviyeleri hakkında daha fazla bilgi edinmek için Bilgi Bankası&apos;nı ziyaret etmek ister misiniz?
+ <notification name="RegionEntryAccessBlocked_AdultsOnlyContent">
+ Ziyaret etmeye çalıştığınız bölge [REGIONMATURITY] içeriğe sahip, buna sadece yetişkinler erişebilir.
<url name="url">
http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview
</url>
- <usetemplate ignoretext="Erişkinlik Seviyesi ile ilgili kısıtlamalardan dolayı bu Bölgeye giremiyorum" name="okcancelignore" notext="Kapat" yestext="Bilgi Bankası&apos;na Git"/>
+ <usetemplate ignoretext="Bölge geçişi: Ziyaret etmeye çalıştığınız bölge, sadece yetişkinlerin erişebileceği içeriğe sahip." name="okcancelignore" notext="Kapat" yestext="Bilgi Bankası&apos;na Git"/>
</notification>
<notification name="RegionEntryAccessBlocked_Notify">
- Erişkinlik Seviyesi ayarlarınızdan dolayı bu bölgeye giremezsiniz.
+ Ziyaret etmeye çalıştığınız bölgede [REGIONMATURITY] içeriği mevcut, ama mevcut tercihleriniz [REGIONMATURITY] içeriğini dışlayacak şekilde ayarlanmış.
+ </notification>
+ <notification name="RegionEntryAccessBlocked_NotifyAdultsOnly">
+ Ziyaret etmeye çalıştığınız bölge [REGIONMATURITY] içeriğe sahip, buna sadece yetişkinler erişebilir.
</notification>
<notification name="RegionEntryAccessBlocked_Change">
- Erişkinlik Seviyesi tercihlerinizden dolayı bu Bölgeye giremezsiniz.
-
-İstenilen bölgeye girmek için, lütfen erişkinlik Seviyesi tercihinizi değiştirin. Bu tercih [REGIONMATURITY] içerikli alanlar içinde arama yapabilmenizi ve bu alanlara erişebilmenizi sağlayacak. Değişiklikleri geri almak için, Ben &gt; Tercihler &gt; Genel sekmesine gidin.
+ Ziyaret etmeye çalıştığınız bölgede [REGIONMATURITY] içeriği mevcut, ama mevcut tercihleriniz [REGIONMATURITY] içeriğini dışlayacak şekilde ayarlanmış. Tercihlerinizi değiştirebilirsiniz veya iptal edebilirsiniz. Tercihleriniz değiştikten sonra bölgeye tekrar girmeye çalışabilirsiniz.
<form name="form">
- <button name="OK" text="Tercihi DeÄŸiÅŸtir"/>
- <button name="Cancel" text="Kapat"/>
- <ignore name="ignore" text="Seçtiğim Seviye tercihleri bir bölgeye girmemi engelliyor"/>
+ <button name="OK" text="Tercihleri deÄŸiÅŸtirin"/>
+ <button name="Cancel" text="Ä°ptal"/>
+ <ignore name="ignore" text="Bölge geçişi: Ziyaret etmeye çalıştığınız bölge, mevcut tercihleriniz tarafından dışlanan içeriğe sahip."/>
+ </form>
+ </notification>
+ <notification name="RegionEntryAccessBlocked_PreferencesOutOfSync">
+ Tercihleriniz ile sunucu arasında senkronizasyon eksikliği olduğu için ışınlama işleminizde teknik sorunlar yaşanıyoruz.
+ <usetemplate name="okbutton" yestext="Tamam"/>
+ </notification>
+ <notification name="TeleportEntryAccessBlocked">
+ Ziyaret etmeye çalıştığınız bölge, mevcut tercihlerinizi aşan içeriğe sahip. Ben &gt; Tercihler &gt; Genel sekmesini kullanarak tercihlerinizi değiştirebilirsiniz.
+ <usetemplate name="okbutton" yestext="Tamam"/>
+ </notification>
+ <notification name="TeleportEntryAccessBlocked_AdultsOnlyContent">
+ Ziyaret etmeye çalıştığınız bölge [REGIONMATURITY] içeriğe sahip, buna sadece yetişkinler erişebilir.
+ <url name="url">
+ http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview
+ </url>
+ <usetemplate ignoretext="Işınla: Ziyaret etmeye çalıştığınız bölge, sadece yetişkinlerin erişebileceği içeriğe sahip." name="okcancelignore" notext="Kapat" yestext="Bilgi Bankası&apos;na Git"/>
+ </notification>
+ <notification name="TeleportEntryAccessBlocked_Notify">
+ Ziyaret etmeye çalıştığınız bölgede [REGIONMATURITY] içeriği mevcut, ama mevcut tercihleriniz [REGIONMATURITY] içeriğini dışlayacak şekilde ayarlanmış.
+ </notification>
+ <notification name="TeleportEntryAccessBlocked_NotifyAdultsOnly">
+ Ziyaret etmeye çalıştığınız bölge [REGIONMATURITY] içeriğe sahip, buna sadece yetişkinler erişebilir.
+ </notification>
+ <notification name="TeleportEntryAccessBlocked_ChangeAndReTeleport">
+ Ziyaret etmeye çalıştığınız bölgede [REGIONMATURITY] içeriği mevcut, ama mevcut tercihleriniz [REGIONMATURITY] içeriğini dışlayacak şekilde ayarlanmış. Tercihlerinizi değiştirebilirsiniz ve ışınlamaya devam edebilirsiniz veya bu ışınlama işlemini iptal edebilirsiniz.
+ <form name="form">
+ <button name="OK" text="DeÄŸiÅŸtir ve devam et"/>
+ <button name="Cancel" text="Ä°ptal"/>
+ <ignore name="ignore" text="Işınlama (yeniden başlatılabilir): Ziyaret etmeye çalıştığınız bölge, mevcut tercihleriniz tarafından dışlanan içeriğe sahip."/>
+ </form>
+ </notification>
+ <notification name="TeleportEntryAccessBlocked_Change">
+ Ziyaret etmeye çalıştığınız bölgede [REGIONMATURITY] içeriği mevcut, ama mevcut tercihleriniz [REGIONMATURITY] içeriğini dışlayacak şekilde ayarlanmış. Tercihlerinizi değiştirebilirsiniz veya ışınlamayı iptal edebilirsiniz. Tercihleriniz değiştikten sonra ışınlamayı tekrar yapmaya kalkışmanız gerekecek.
+ <form name="form">
+ <button name="OK" text="Tercihleri deÄŸiÅŸtirin"/>
+ <button name="Cancel" text="Ä°ptal"/>
+ <ignore name="ignore" text="Işınlama (yeniden başlatılamaz): Ziyaret etmeye çalıştığınız bölge, mevcut tercihleriniz tarafından dışlanan içeriğe sahip."/>
</form>
</notification>
+ <notification name="TeleportEntryAccessBlocked_PreferencesOutOfSync">
+ Tercihleriniz ile sunucu arasında senkronizasyon eksikliği olduğu için ışınlama işleminizde teknik sorunlar yaşanıyoruz.
+ <usetemplate name="okbutton" yestext="Tamam"/>
+ </notification>
<notification name="PreferredMaturityChanged">
- Erişkinlik Seviyesi tercihiniz artık [RATING].
+ [RATING] içeriğine sahip bir bölgeyi ziyaret edeceğiniz hakkında başka bildirim almayacaksınız. Daha sonra menü çubuğunda Ben &gt; Tercihler &gt; Genel sekmesini kullanarak tercihlerinizi değiştirebilirsiniz.
+ <usetemplate name="okbutton" yestext="Tamam"/>
+ </notification>
+ <notification name="MaturityChangeError">
+ Şu anda [PREFERRED_MATURITY] içeriğini görüntüleyecek şekilde tercihlerinizi değiştiremedik. Tercihleriniz, [ACTUAL_MATURITY] içeriğini görüntüleyecek şekilde sıfırlandı. Menü çubuğunda Ben &gt; Tercihler &gt; Genel sekmesini kullanarak tercihlerinizi tekrar değiştirmeyi deneyebilirsiniz.
+ <usetemplate name="okbutton" yestext="Tamam"/>
</notification>
<notification name="LandClaimAccessBlocked">
- Erişkinlik Seviyesi ayarlarınızdan dolayı bu arazi üzerinde hak talebinde bulunamazsınız. Bu sorun yaşınızı doğrulamak için gerekli bilgilerin eksik olmasından kaynaklanabilir.
-
-Lütfen en son Görüntüleyicinin yüklü olduğunu doğrulayın ve bu erişkinlik seviyesi ile erişilecek alanlar hakkında ayrıntılı bilgi edinmek için Bilgi Bankası&apos;nı ziyaret edin.
+ Hak talebinde bulunduğunuz arazinin erişkinlik seviyesi mevcut tercihlerinizi aşıyor. Ben &gt; Tercihler &gt; Genel sekmesini kullanarak tercihlerinizi değiştirebilirsiniz.
<usetemplate name="okbutton" yestext="Tamam"/>
</notification>
- <notification name="LandClaimAccessBlocked_KB">
- Erişkinlik Seviyesi ayarlarınızdan dolayı bu arazi üzerinde hak talebinde bulunamazsınız.
-
-Erişkinlik Seviyeleri hakkında daha fazla bilgi edinmek için Bilgi Bankası&apos;nı ziyaret etmek ister misiniz?
+ <notification name="LandClaimAccessBlocked_AdultsOnlyContent">
+ Bu arazi üzerinde sadece yetişkinler hak talebinde bulunabilir.
<url name="url">
http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview
</url>
- <usetemplate ignoretext="Erişkinlik Seviyesi ile ilgili kısıtlandırmalardan dolayı bu Arazi üzerinde hak talebinde bulunamıyorum." name="okcancelignore" notext="Kapat" yestext="Bilgi Bankası&apos;na Git"/>
+ <usetemplate ignoretext="Bu arazi üzerinde sadece yetişkinler hak talebinde bulunabilir." name="okcancelignore" notext="Kapat" yestext="Bilgi Bankası&apos;na Git"/>
</notification>
<notification name="LandClaimAccessBlocked_Notify">
- Erişkinlik Seviyesi ayarlarınızdan dolayı bu arazi üzerinde hak talebinde bulunamazsınız.
+ Hak talebinde bulunduğunuz arazide [REGIONMATURITY] içeriği mevcut, ama mevcut tercihleriniz [REGIONMATURITY] içeriğini dışlayacak şekilde ayarlanmış.
+ </notification>
+ <notification name="LandClaimAccessBlocked_NotifyAdultsOnly">
+ Hak talebinde bulunduğunuz arazi [REGIONMATURITY] içeriğe sahip, buna sadece yetişkinler erişebilir.
</notification>
<notification name="LandClaimAccessBlocked_Change">
- Erişkinlik Seviyesi tercihinizden dolayı bu arazi üzerinde hak talebinde bulunamazsınız.
-
-Erişkinlik Seviyesi tercihinizi şimdi yükseltmek ve araziye girebilmek için &apos;Tercihi Değiştir&apos; seçeneğini tıklatabilirsiniz. Böylece [REGIONMATURITY] içerikli alanlar içinde arama yapabilecek ve bu alanlara erişebileceksiniz. İleride bu ayarı eski haline döndürmek isterseniz, Ben &gt; Tercihler &gt; Genel sekmesine gidin.
- <usetemplate ignoretext="Seçtiğim Seviye tercihi Arazi üzerinde hak talebinde bulunmamı engelliyor" name="okcancelignore" notext="Kapat" yestext="Tercihi Değiştir"/>
+ Hak talebinde bulunduğunuz arazide [REGIONMATURITY] içeriği mevcut, ama mevcut tercihleriniz [REGIONMATURITY] içeriğini dışlayacak şekilde ayarlanmış. Tercihlerinizi değiştirebilirsiniz, sonra arazi üzerinde tekar hak talebinde bulunabilirsiniz.
+ <form name="form">
+ <button name="OK" text="Tercihleri deÄŸiÅŸtirin"/>
+ <button name="Cancel" text="Ä°ptal"/>
+ <ignore name="ignore" text="Hak talebinde bulunduğunuz arazi, mevcut tercihleriniz tarafından dışlanan içeriğe sahip."/>
+ </form>
</notification>
<notification name="LandBuyAccessBlocked">
- Erişkinlik Seviyesi ayarlarınızdan dolayı bu araziyi satın alamazsınız. Bu sorun yaşınızı doğrulamak için gerekli bilgilerin eksik olmasından kaynaklanabilir.
-
-Lütfen en son Görüntüleyicinin yüklü olduğunu doğrulayın ve bu erişkinlik seviyesi ile erişilecek alanlar hakkında ayrıntılı bilgi edinmek için Bilgi Bankası&apos;nı ziyaret edin.
+ Satın almaya çalıştığınız arazinin erişkinlik seviyesi mevcut tercihlerinizi aşıyor. Ben &gt; Tercihler &gt; Genel sekmesini kullanarak tercihlerinizi değiştirebilirsiniz.
<usetemplate name="okbutton" yestext="Tamam"/>
</notification>
- <notification name="LandBuyAccessBlocked_KB">
- Erişkinlik Seviyesi ayarlarınızdan dolayı bu araziyi satın alamazsınız.
-
-Erişkinlik Seviyeleri hakkında daha fazla bilgi edinmek için Bilgi Bankası&apos;nı ziyaret etmek ister misiniz?
+ <notification name="LandBuyAccessBlocked_AdultsOnlyContent">
+ Bu araziyi sadece yetişkinler satın alabilir.
<url name="url">
http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview
</url>
- <usetemplate ignoretext="Erişkinlik Seviyesi ile ilgili kısıtlandırmalardan dolayı bu Araziyi satın alamıyorum" name="okcancelignore" notext="Kapat" yestext="Bilgi Bankası&apos;na Git"/>
+ <usetemplate ignoretext="Bu araziyi sadece yetişkinler satın alabilir." name="okcancelignore" notext="Kapat" yestext="Bilgi Bankası&apos;na Git"/>
</notification>
<notification name="LandBuyAccessBlocked_Notify">
- Erişkinlik Seviyesi ayarlarınızdan dolayı bu araziyi satın alamazsınız.
+ Satın almaya çalıştığınız arazide [REGIONMATURITY] içeriği mevcut, ama mevcut tercihleriniz [REGIONMATURITY] içeriğini dışlayacak şekilde ayarlanmış.
+ </notification>
+ <notification name="LandBuyAccessBlocked_NotifyAdultsOnly">
+ Ziyaret etmeye çalıştığınız arazi [REGIONMATURITY] içeriğe sahip, buna sadece yetişkinler erişebilir.
</notification>
<notification name="LandBuyAccessBlocked_Change">
- Erişkinlik Seviyesi tercihinizden dolayı bu araziyi satın alamazsınız.
-
-Erişkinlik Seviyesi tercihinizi şimdi yükseltmek ve araziye girebilmek için &apos;Tercihi Değiştir&apos; seçeneğini tıklatabilirsiniz. Böylece [REGIONMATURITY] içerikli alanlar içinde arama yapabilecek ve bu alanlara erişebileceksiniz. İleride bu ayarı eski haline döndürmek isterseniz, Ben &gt; Tercihler &gt; Genel sekmesine gidin.
- <usetemplate ignoretext="Seçtiğim Seviye tercihi Araziyi satın almamı engelliyor" name="okcancelignore" notext="Kapat" yestext="Tercihi Değiştir"/>
+ Satın almaya çalıştığınız arazide [REGIONMATURITY] içeriği mevcut, ama mevcut tercihleriniz [REGIONMATURITY] içeriğini dışlayacak şekilde ayarlanmış. Tercihlerinizi değiştirebilirsiniz, sonra araziyi tekrar satın almaya çalışabilirsiniz.
+ <form name="form">
+ <button name="OK" text="Tercihleri deÄŸiÅŸtirin"/>
+ <button name="Cancel" text="Ä°ptal"/>
+ <ignore name="ignore" text="Satın almaya çalıştığınız arazi, mevcut tercihleriniz tarafından dışlanan içeriğe sahip."/>
+ </form>
</notification>
<notification name="TooManyPrimsSelected">
Çok fazla prim seçilmiş. Lütfen [MAX_PRIM_COUNT] ya da daha az prim seçin ve tekrar deneyin
@@ -1815,10 +1981,9 @@ Erişkinlik Seviyesi tercihinizi şimdi yükseltmek ve araziye girebilmek için
</form>
</notification>
<notification label="Bölgenin Erişkinlik Seviyesi Değişti" name="RegionMaturityChange">
- Bu bölgenin erişkinlik seviyesi güncellendi.
-Değişikliğin harita üzerine yansıtılması biraz zaman alabilir.
-
-Yetişkin bölgelerine girebilmek için, Sakinlerin yaş doğrulama ya da ödeme doğrulama yoluyla Doğrulanmış bir Hesaba sahip olmaları gerekmektedir.
+ Bu bölgenin yetişkin içerik seviyesi değişti.
+Bu değişikliğin harita üzerine yansıtılması biraz zaman alabilir.
+ <usetemplate name="okbutton" yestext="Tamam"/>
</notification>
<notification label="Sesli Sohbet Sürüm Uyumsuzluğu" name="VoiceVersionMismatch">
[APP_NAME] uygulamasının bu sürümü bu bölgedeki Sesli Sohbet özelliği ile uyumlu değil. Sesli Sohbet özelliğinin düzgün bir şekilde çalışabilmesi için [APP_NAME] uygulamasını güncellemeniz gerekiyor.
@@ -1931,6 +2096,10 @@ Envanter öğesi/öğeleri taşınsın mı?
Hesap geçmişinizi görüntülemek için [http://secondlife.com/account/ Kontrol Paneli] adresine gitmek istiyor musunuz?
<usetemplate ignoretext="Hesap geçmişimi görüntülemek için tarayıcımı başlat" name="okcancelignore" notext="İptal" yestext="Sayfaya git"/>
</notification>
+ <notification name="ConfirmAddingChatParticipants">
+ Mevcut bir sohbete bir kişi eklediğinizde yeni bir sohbet oluşturulur. Tüm katılımcılara yeni sohbet bildirimi gönderilir.
+ <usetemplate ignoretext="Sohbet katılımcılarının eklenmesini doğrula" name="okcancelignore" notext="İptal" yestext="Tamam"/>
+ </notification>
<notification name="ConfirmQuit">
Çıkmak istediğinize emin misiniz?
<usetemplate ignoretext="Çıkmadan önce doğrulama iste" name="okcancelignore" notext="Çıkma" yestext="Çık"/>
@@ -2005,14 +2174,14 @@ Bu nesneyi seçilen nesne ile değiştirmek istiyor musunuz?
<button ignore="Hiçbir Zaman Değiştirme" name="No" text="İptal"/>
</form>
</notification>
- <notification label="Meşgul Durumu Uyarısı" name="BusyModePay">
- Durumunuz Meşgul olarak ayarlanmış; bu da, bu ödemenin karşılığında teklif edilen hiçbir öğeyi almayacağınız anlamına gelir.
+ <notification label="Rahatsız Etme Modu Uyarısı" name="DoNotDisturbModePay">
+ Rahatsız Etme seçeneğini devreye aldınız. Bu ödemenin karşılığında sunulan hiçbir öğeyi almayacaksınız.
-Bu işlemi tamamlamadan önce Meşgul durumundan çıkmak ister misiniz?
+Bu işlemi tamamlamadan önce Rahatsız Etme&apos;yi kapatmak ister misiniz?
<form name="form">
- <ignore name="ignore" text="Meşgul durumundayken bir kişiye veya bir nesneye ödeme yapmak üzereyim."/>
- <button ignore="Her zaman Meşgul durumundan çık" name="Yes" text="Tamam"/>
- <button ignore="Hiçbir zaman Meşgul durumundan çıkma" name="No" text="İptal"/>
+ <ignore name="ignore" text="Rahatsız Etmeyin modundayken bir kişiye veya bir nesneye ödeme yapmak üzereyim"/>
+ <button ignore="Rahatsız Etme Modundan daima çıkılsın" name="Yes" text="Tamam"/>
+ <button ignore="Rahatsız Etme Modundan asla çıkılmasın" name="No" text="İptal"/>
</form>
</notification>
<notification name="ConfirmDeleteProtectedCategory">
@@ -2108,14 +2277,11 @@ Diğer kişilerin bu konuma kolayca erişmesini sağlamak için bu adrese bir we
<usetemplate ignoretext="Görünümümü düzenlerken oluşturduğum giysiyi giy" name="okcancelignore" notext="Hayır" yestext="Evet"/>
</notification>
<notification name="NotAgeVerified">
- Second Life içinde yetişkinlere yönelik içeriğe ve bölgelere erişmek için en az 18 yaşında olmalısınız. 18 yaşından büyük olduğunuzu onaylamak için lütfen yaş doğrulama sayfamızı ziyaret edin.
-Bu adımda web tarayıcınızın başlatılacağına dikkat edin.
-
-[_URL]
- <url name="url">
- https://secondlife.com/my/account/verification.php
- </url>
- <usetemplate ignoretext="Yaşımı doğrulatmadım" name="okcancelignore" notext="İptal" yestext="Yaş Doğrulamasına Git"/>
+ Ziyaret etmeye çalıştığınız konum, yaşı 18 ve üzeri olan sakinlere kısıtlanmıştır.
+ <usetemplate ignoretext="Yaş kısıtı olan alanları ziyaret etmek için yaşım yeterli değil." name="okignore" yestext="Tamam"/>
+ </notification>
+ <notification name="NotAgeVerified_Notify">
+ Konum, 18 veya üzeri bir yaşta olanlara kısıtlanmıştır.
</notification>
<notification name="Cannot enter parcel: no payment info on file">
Bu alanı ziyaret edebilmek için ödeme bilgilerinizin kayıtlı olması gerekir. [SECOND_LIFE] web sitesine gitmek ve bunu ayarlamak istiyor musunuz?
@@ -2150,11 +2316,8 @@ Bu adımda web tarayıcınızın başlatılacağına dikkat edin.
<notification name="GroupNotice">
Konu: [SUBJECT], Ä°leti: [MESSAGE]
</notification>
- <notification name="FriendOnline">
- &lt;nolink&gt;[NAME]&lt;/nolink&gt; çevrimiçi
- </notification>
- <notification name="FriendOffline">
- &lt;nolink&gt;[NAME]&lt;/nolink&gt; çevrimdışı
+ <notification name="FriendOnlineOffline">
+ &lt;nolink&gt;[NAME]&lt;/nolink&gt; durumu: [STATUS]
</notification>
<notification name="AddSelfFriend">
Çok iyi biri olduğunuza eminiz fakat kendinizi arkadaş olarak ekleyemezsiniz.
@@ -2176,7 +2339,7 @@ Bu adımda web tarayıcınızın başlatılacağına dikkat edin.
Terrain.raw karşıdan yüklendi
</notification>
<notification name="GestureMissing">
- Hmm. [NAME] mimiği veri tabanında yok.
+ [NAME] mimiği veri tabanında yok.
</notification>
<notification name="UnableToLoadGesture">
[NAME] mimiği karşıya yüklenemiyor.
@@ -2275,9 +2438,7 @@ Lütfen tek bir nesne seçin.
&apos;Işınla&apos; seçimini yapabilirsiniz.)
</notification>
<notification name="TeleportToPerson">
- &apos;[NAME]&apos; gibi sakinlerle bağlantıya geçmek için &quot;Kişiler&quot; düğmesine tıklayın, açılan pencereden bir Sakin seçin ve sonra
- pencerenin altında &apos;Anlık İleti&quot; üzerine tıklayın.
- (Listede adlarına çift tıklayarak veya sağ tıklayıp &quot;Anlık İleti&quot;yi seçerek de bunu yapabilirsiniz.)
+ Biriyle özel bir sohbet başlatmak için, avatarlarına sağ tıklayın ve menüden &quot;Aİ&quot; seçimini yapın.
</notification>
<notification name="CantSelectLandFromMultipleRegions">
Sunucunun sınırları dışındaki arazi seçilemez.
@@ -2377,6 +2538,16 @@ Burada uçamazsınız.
<notification name="NoBuild">
Bu alanda inşa etme özelliği devre dışı. Burada nesne inşa edemez ve oluşturamazsınız.
</notification>
+ <notification name="PathfindingDirty">
+ Bu bölgede bekleyen yol bulma değişiklikleri var. Eğer oluşturma haklarına sahipseniz, “Bölgeyi yeniden kaydet†düğmesine tıklayarak bölgeyi yeniden kaydedebilirsiniz.
+ </notification>
+ <notification name="DynamicPathfindingDisabled">
+ Bu bölgede dinamik yol bulma etkin değil. Yol bulma LSL çağrılarını kullanan komut dosyalı nesneler, bu bölgede beklendiiği gibi çalışmayabilir.
+ </notification>
+ <notification name="PathfindingCannotRebakeNavmesh">
+ Bir hata meydana geldi. Bir ağ veya sunucu sorunu olabilir ya da oluşturma haklarına sahip olmayabilirsiniz. Bazen oturumu kapatıp, tekrar açmak bu sorunu çözer.
+ <usetemplate name="okbutton" yestext="Tamam"/>
+ </notification>
<notification name="SeeAvatars">
Bu parsel, avatarları ve metin sohbetini başka bir parselden saklar. Parselin dışındaki diğer sakinleri göremezsiniz, dışardakiler de sizi göremez. 0. kanaldaki normal metin sohbeti de engellenmiştir.
</notification>
@@ -2395,9 +2566,7 @@ Arazi sahibine ait olanlar dışında hiçbir komut dosyası çalışmayacak.
İçinde bulunduğunuz Bölgede sadece kamuya ait araziler üzerinde hak talebinde bulunabilirsiniz.
</notification>
<notification name="RegionTPAccessBlocked">
- Erişkinlik Seviyesi ayarlarınızdan dolayı bu Bölgeye giremezsiniz. Yaşınızı doğrulatmanız ve/veya en son Görüntüleyici&apos;yi yüklemeniz gerekebilir.
-
-Lütfen bu erişkinlik Seviyesi ile erişilecek alanlar hakkında ayrıntılı bilgi edinmek için Bilgi Bankası&apos;na gidin.
+ Ziyaret etmeye çalıştığınız bölge, mevcut tercihlerinizi aşan içeriğe sahip. Ben &gt; Tercihler &gt; Genel sekmesini kullanarak tercihlerinizi değiştirebilirsiniz.
</notification>
<notification name="URBannedFromRegion">
Bu bölgeye erişiminiz yasaklandı.
@@ -2408,11 +2577,11 @@ Lütfen bu erişkinlik Seviyesi ile erişilecek alanlar hakkında ayrıntılı b
<notification name="ImproperPaymentStatus">
Bu bölgeye girmek için gerekli ödeme durumuna sahip değilsiniz.
</notification>
- <notification name="MustGetAgeRgion">
- Bu bölgeye girebilmek için yaş doğrulamanızın yapılmış olması gerekir.
+ <notification name="MustGetAgeRegion">
+ Bu bölgeye girebilmek için 18 veya üzeri bir yaşta olmanız gerekir.
</notification>
<notification name="MustGetAgeParcel">
- Bu parsele girebilmek için yaş doğrulamanızın yapılmış olması gerekir.
+ Bu parsele girebilmek için 18 veya üzeri bir yaşta olmanız gerekir.
</notification>
<notification name="NoDestRegion">
Seçili hedef bölge yok.
@@ -2514,12 +2683,33 @@ Lütfen biraz sonra tekrar deneyin.
<notification name="TeleportOffered">
[NAME_SLURL] size kendi konumuna ışınlanmayı teklif etti:
-[MESSAGE] - [MATURITY_STR] &lt;icon&gt;[MATURITY_ICON]&lt;/icon&gt;
+“[MESSAGE]â€
+&lt;icon&gt;[MATURITY_ICON]&lt;/icon&gt; - [MATURITY_STR]
<form name="form">
<button name="Teleport" text="Işınla"/>
<button name="Cancel" text="Ä°ptal"/>
</form>
</notification>
+ <notification name="TeleportOffered_MaturityExceeded">
+ [NAME_SLURL] size kendi konumuna ışınlanmayı teklif etti:
+
+“[MESSAGE]â€
+&lt;icon&gt;[MATURITY_ICON]&lt;/icon&gt; - [MATURITY_STR]
+
+Bu bölgede [REGION_CONTENT_MATURITY] içeriği mevcut, ama mevcut tercihleriniz [REGION_CONTENT_MATURITY] içeriğini dışlayacak şekilde ayarlanmış durumda. Tercihlerinizi değiştirebilirsiniz ve ışınlamaya devam edebilirsiniz veya bu ışınlama işlemini iptal edebilirsiniz.
+ <form name="form">
+ <button name="Teleport" text="DeÄŸiÅŸtir ve Devam Et"/>
+ <button name="Cancel" text="Ä°ptal"/>
+ </form>
+ </notification>
+ <notification name="TeleportOffered_MaturityBlocked">
+ [NAME_SLURL] size kendi konumuna ışınlanmayı teklif etti:
+
+“[MESSAGE]â€
+&lt;icon&gt;[MATURITY_ICON]&lt;/icon&gt; - [MATURITY_STR]
+
+Ancak bu bölge sadece yetişkinlerin erişebileceği içeriğe sahip.
+ </notification>
<notification name="TeleportOfferSent">
Işınlanma teklifi [TO_NAME] adlı kişiye gönderildi
</notification>
@@ -2614,16 +2804,21 @@ Kabul ediyor musunuz?
</form>
</notification>
<notification name="ScriptQuestionCaution">
- &apos;[NAME]&apos; adlı kişiye ait &apos;&lt;nolink&gt;[OBJECTNAME]&lt;/nolink&gt;&apos; adındaki bir nesne şunu yapmak istiyor:
-
-[QUESTIONS]
-Bu nesneye ya da onu oluşturan kişiye güvenmiyorsanız, bu talebi reddetmelisiniz.
-
-Talep kabul edilsin mi?
+ Uyarı: &apos;&lt;nolink&gt;[OBJECTNAME]&lt;/nolink&gt;&apos; nesnesi, Linden Dolar hesabınıza tam erişim istiyor. Eğer erişime izin verirseniz, süregelen bir şekilde, ilave uyarı olmaksızın, hesabınızdan herhangi bir zamanda fon çekebilir veya hesabınızı tamamen boşaltabilir.
+
+Eğer hesabınıza neden erişmek istediğini tam olarak anlamıyorsanız, erişime izin vermeyin.
<form name="form">
- <button name="Grant" text="Kabul Et"/>
+ <button name="Grant" text="Tam eriÅŸime izin ver"/>
<button name="Deny" text="Reddet"/>
- <button name="Details" text="Ayrıntılar..."/>
+ </form>
+ </notification>
+ <notification name="UnknownScriptQuestion">
+ &apos;[NAME]&apos; tarafından sahip olunan bir nesne olan &apos;&lt;nolink&gt;[OBJECTNAME]&lt;/nolink&gt;&apos; tarafından istenen çalışma zamanı komut dosyası izni görüntüleyici tarafından tanınmadı ve verilemez.
+
+Bu izni vermek için lütfen [DOWNLOADURL] adresinden görüntüleyicinizi en son sürüme güncelleyin.
+ <form name="form">
+ <button name="Deny" text="Tamam"/>
+ <button name="Mute" text="Engelle"/>
</form>
</notification>
<notification name="ScriptDialog">
@@ -2927,6 +3122,10 @@ Lütfen ağ ve güvenlik duvarı ayarlarınızı kontrol edin.
( [EXISTENCE] saniyedir hayatta )
&apos;[BODYREGION]&apos; için [RESOLUTION] çözünürlükte kaydedilmiş bir dokuyu [TIME] saniye sonra yerel olarak güncellediniz.
</notification>
+ <notification name="LivePreviewUnavailable">
+ Kopyalanamaz ve/veya aktarılamaz olduğu için bu dokunun bir önizlemesini görüntüleyemiyoruz.
+ <usetemplate ignoretext="Kopyalanamayan ve/veya aktarılamayan dokular için Canlı Önizleme modu mevcut olmayınca beni uyar" name="okignore" yestext="Tamam"/>
+ </notification>
<notification name="ConfirmLeaveCall">
Bu aramadan çıkmak istediğinize emin misiniz?
<usetemplate ignoretext="Aramadan çıkmadan önce doğrulama iste" name="okcancelignore" notext="Hayır" yestext="Evet"/>
@@ -3098,6 +3297,62 @@ Görünümünüzü döndürmek için dünya üzerindeki herhangi bir yeri tıkla
Bu eylem tüm menü öğelerini ve düğmelerini gizler. Bunları geri almak için [SHORTCUT] üzerine tekrar tıklayın.
<usetemplate ignoretext="KA&apos;ni gizlemeden önce onayla" name="okcancelignore" notext="İptal" yestext="Tamam"/>
</notification>
+ <notification name="PathfindingLinksets_WarnOnPhantom">
+ Bazı seçili bağlantı kümelerinin Fantom bayrağı dönüştürülecek.
+
+Devam etmek istiyor musunuz?
+ <usetemplate ignoretext="Bazı seçili bağlantı kümelerinin fantom bayrağı dönüştürülecek." name="okcancelignore" notext="İptal" yestext="Tamam"/>
+ </notification>
+ <notification name="PathfindingLinksets_MismatchOnRestricted">
+ Seçilen bazı bağlantı kümeleri, bağlantı kümesi için izin kısıtlamaları nedeniyle &apos;[REQUESTED_TYPE]&apos; olarak ayarlanamıyor. Bunun yerine bu bağlantı kümeleri &apos;[RESTRICTED_TYPE]&apos; olarak ayarlanacak.
+
+Devam etmek istiyor musunuz?
+ <usetemplate ignoretext="Seçilen bazı bağlantı kümeleri, bağlantı kümesi için izin kısıtlamaları nedeniyle ayarlanamıyor." name="okcancelignore" notext="İptal" yestext="Tamam"/>
+ </notification>
+ <notification name="PathfindingLinksets_MismatchOnVolume">
+ Seçilen bazı bağlantı kümeleri &apos;[REQUESTED_TYPE]&apos; olarak ayarlanamaz, çünkü şekil konveks değil.
+
+Devam etmek istiyor musunuz?
+ <usetemplate ignoretext="Seçilen bazı bağlantı kümeleri ayarlanamaz, çünkü şekil konveks değil." name="okcancelignore" notext="İptal" yestext="Tamam"/>
+ </notification>
+ <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnRestricted">
+ Bazı seçili bağlantı kümelerinin Fantom bayrağı dönüştürülecek.
+
+Seçilen bazı bağlantı kümeleri, bağlantı kümesi için izin kısıtlamaları nedeniyle &apos;[REQUESTED_TYPE]&apos; olarak ayarlanamıyor. Bunun yerine bu bağlantı kümeleri &apos;[RESTRICTED_TYPE]&apos; olarak ayarlanacak.
+
+Devam etmek istiyor musunuz?
+ <usetemplate ignoretext="Bazı seçili bağlantı kümelerinin fantom bayrağı dönüştürülecek, diğerleri ise bağlantı kümesi için izin kısıtlamaları nedeniyle ayarlanamıyor." name="okcancelignore" notext="İptal" yestext="Tamam"/>
+ </notification>
+ <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnVolume">
+ Bazı seçili bağlantı kümelerinin Fantom bayrağı dönüştürülecek.
+
+Seçilen bazı bağlantı kümeleri &apos;[REQUESTED_TYPE]&apos; olarak ayarlanamaz, çünkü şekil konveks değil.
+
+Devam etmek istiyor musunuz?
+ <usetemplate ignoretext="Bazı seçili bağlantı kümelerinin fantom bayrağı dönüştürülecek, diğerleri ise şekil konveks olmadığı için ayarlanamıyor" name="okcancelignore" notext="İptal" yestext="Tamam"/>
+ </notification>
+ <notification name="PathfindingLinksets_MismatchOnRestricted_MismatchOnVolume">
+ Seçilen bazı bağlantı kümeleri, bağlantı kümesi için izin kısıtlamaları nedeniyle &apos;[REQUESTED_TYPE]&apos; olarak ayarlanamıyor. Bunun yerine bu bağlantı kümeleri &apos;[RESTRICTED_TYPE]&apos; olarak ayarlanacak.
+
+Seçilen bazı bağlantı kümeleri &apos;[REQUESTED_TYPE]&apos; olarak ayarlanamaz, çünkü şekil konveks değil. Bu bağlantı kümelerinin kullanım tipleri değişmez.
+
+Devam etmek istiyor musunuz?
+ <usetemplate ignoretext="Seçilen bazı bağlantı kümeleri, bağlantı kümesi için izin kısıtlamaları nedeniyle ve şekil konveks olmadığı için ayarlanamıyor." name="okcancelignore" notext="İptal" yestext="Tamam"/>
+ </notification>
+ <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnRestricted_MismatchOnVolume">
+ Bazı seçili bağlantı kümelerinin Fantom bayrağı dönüştürülecek.
+
+Seçilen bazı bağlantı kümeleri, bağlantı kümesi için izin kısıtlamaları nedeniyle &apos;[REQUESTED_TYPE]&apos; olarak ayarlanamıyor. Bunun yerine bu bağlantı kümeleri &apos;[RESTRICTED_TYPE]&apos; olarak ayarlanacak.
+
+Seçilen bazı bağlantı kümeleri &apos;[REQUESTED_TYPE]&apos; olarak ayarlanamaz, çünkü şekil konveks değil. Bu bağlantı kümelerinin kullanım tipleri değişmez.
+
+Devam etmek istiyor musunuz?
+ <usetemplate ignoretext="Bazı seçili bağlantı kümelerinin fantom bayrağı dönüştürülecek, diğerleri ise bağlantı kümesi için izin kısıtlamaları nedeniyle ve şekil konveks olmadığı için ayarlanamıyor." name="okcancelignore" notext="İptal" yestext="Tamam"/>
+ </notification>
+ <notification name="PathfindingLinksets_ChangeToFlexiblePath">
+ Seçilen nesne navigasyon örgüsünü etkiliyor. Bunu bir Esnek Yol olarak değiştirirseniz, navigasyon örgüsünden çıkartmış olursunuz.
+ <usetemplate ignoretext="Seçilen nesne navigasyon örgüsünü etkiliyor. Bunu bir Esnek Yol olarak değiştirirseniz, navigasyon örgüsünden çıkartmış olursunuz." name="okcancelignore" notext="İptal" yestext="Tamam"/>
+ </notification>
<global name="UnsupportedGLRequirements">
[APP_NAME] uygulaması için gerekli donanım gereksinimlerine sahip olmadığınız görünüyor. [APP_NAME] çoklu doku desteği sunan bir OpenGL grafik kartı gerektiriyor. Eğer grafik kartınız bu özellikteyse, grafik kartınızın en son sürücülerine ve işletim sisteminiz için gerekli Service Pack ve yamalara sahip olup olmadığınızı kontrol etmeyi deneyebilirsiniz.
@@ -3122,4 +3377,646 @@ Bir araziye sahip değilseniz, Harita&apos;ya bakıp &quot;Bilgi İstasyonu&quot
<global name="You died and have been teleported to your home location">
Hayatınızı kaybettiniz ve ana konumunuza ışınlandınız.
</global>
+ <notification name="LocalBitmapsUpdateFileNotFound">
+ [FNAME] güncellenemedi çünkü bu dosya artık bulunamıyor.
+Bundan sonra bu dosya için güncellemeler devre dışı bırakılacak.
+ </notification>
+ <notification name="LocalBitmapsUpdateFailedFinal">
+ [NRETRIES] girişimde [FNAME] açılamadı veya şifresi çözülemedi, bu dosya artık bozuk olarak değerlendiriliyor.
+Bundan sonra bu dosya için güncellemeler devre dışı bırakılacak.
+ </notification>
+ <notification name="LocalBitmapsVerifyFail">
+ Geçersiz veya okunamayan bir görüntü dosyası [FNAME] eklenmeye kalkışıldı, ancak dosya açılamadı veya şifresi çözülemedi.
+GiriÅŸim iptal edildi.
+ </notification>
+ <notification name="PathfindingReturnMultipleItems">
+ [NUM_ITEMS] öğeyi iade ediyorsunuz. Devam etmek istediğinize emin misiniz?
+ <usetemplate ignoretext="Birden çok öğeyi iade etmek istediğinize emin misiniz?" name="okcancelignore" notext="Hayır" yestext="Evet"/>
+ </notification>
+ <notification name="PathfindingDeleteMultipleItems">
+ [NUM_ITEMS] öğeyi siliyorsunuz. Devam etmek istediğinize emin misiniz?
+ <usetemplate ignoretext="Birden çok öğeyi silmek istediğinize emin misiniz?" name="okcancelignore" notext="Hayır" yestext="Evet"/>
+ </notification>
+ <notification name="AvatarFrozen">
+ [AV_FREEZER] sizi dondurdu. Hareket edemez veya dünyayla etkileşim kuramazsınız.
+ </notification>
+ <notification name="AvatarFrozenDuration">
+ [AV_FREEZER] sizi [AV_FREEZE_TIME] saniye boyunca dondurdu. Hareket edemez veya dünyayla etkileşim kuramazsınız.
+ </notification>
+ <notification name="YouFrozeAvatar">
+ Avatar donduruldu.
+ </notification>
+ <notification name="AvatarHasUnFrozenYou">
+ [AV_FREEZER] sizin dondurulmanızı kaldırdı.
+ </notification>
+ <notification name="AvatarUnFrozen">
+ Avatar artık dondurulmuş değil.
+ </notification>
+ <notification name="AvatarFreezeFailure">
+ Dondurma başarılamadı çünkü bu parsel için yönetici iznine sahip değilsiniz.
+ </notification>
+ <notification name="AvatarFreezeThaw">
+ Dondurmanızın süresi sona erdi, istediğinizi yapabilirsiniz.
+ </notification>
+ <notification name="AvatarCantFreeze">
+ Üzgünüz, bu kullanıcı dondurulamaz.
+ </notification>
+ <notification name="NowOwnObject">
+ Artık [OBJECT_NAME] nesnesinin sahibisiniz
+ </notification>
+ <notification name="CantRezOnLand">
+ [OBJECT_POS] konumunda nesneyi oluşturamazsınız çünkü bu arazinin sahibi buna izin vermiyor. Arazinin sahibini görmek için arazi aracını kullanın.
+ </notification>
+ <notification name="RezFailTooManyRequests">
+ Çok fazla talep olduğu için nesne oluşturulamadı.
+ </notification>
+ <notification name="SitFailCantMove">
+ Oturamazsınız çünkü şu anda hareket edemezsiniz.
+ </notification>
+ <notification name="SitFailNotAllowedOnLand">
+ Oturamazsınız çünkü bu araziye girme izniniz yok.
+ </notification>
+ <notification name="SitFailNotSameRegion">
+ Daha yakına gelmeyi deneyin. Nesne sizinle aynı bölgede olmadığı için nesnenin üzerine oturulamaz.
+ </notification>
+ <notification name="NoNewObjectRegionFull">
+ Yeni nesne oluşturulamıyor. Bölge dolu.
+ </notification>
+ <notification name="FailedToPlaceObject">
+ Belirtilen konuma nesne yerleştirilemedi. Lütfen tekrar deneyin.
+ </notification>
+ <notification name="NoOwnNoGardening">
+ Sahibi olmadığınız arazide ağaçlar ve çimen oluşturamazsınız.
+ </notification>
+ <notification name="NoCopyPermsNoObject">
+ &apos;[OBJ_NAME]&apos; nesnesini kopyalama izniniz olmadığı için kopyalama başarılamadı.
+ </notification>
+ <notification name="NoTransPermsNoObject">
+ &apos;[OBJ_NAME]&apos; nesnesi size aktarılamadığı için kopyalama başarılamadı.
+ </notification>
+ <notification name="AddToNavMeshNoCopy">
+ &apos;[OBJ_NAME]&apos; nesnesi navmesh&apos;e katkıda bulunduğu için kopyalama başarılamadı.
+ </notification>
+ <notification name="DupeWithNoRootsSelected">
+ Kök nesne seçili olmayan kopya.
+ </notification>
+ <notification name="CantDupeCuzRegionIsFull">
+ Nesneler çoğaltılamıyor çünkü bölge dolu.
+ </notification>
+ <notification name="CantDupeCuzParcelNotFound">
+ Nesneler çoğaltılamadı - Üzerinde oldukları parsel bulunamadı.
+ </notification>
+ <notification name="CantCreateCuzParcelFull">
+ Nesne oluşturulamıyor çünkü
+parsel dolu.
+ </notification>
+ <notification name="RezAttemptFailed">
+ Bir nesneyi oluşturma girişimi başarısız oldu.
+ </notification>
+ <notification name="ToxicInvRezAttemptFailed">
+ Bu bölgede hatalara yol açmış olan öğe oluşturulamıyor.
+ </notification>
+ <notification name="InvItemIsBlacklisted">
+ Bu envanter öğesi kara listeye alınmış.
+ </notification>
+ <notification name="NoCanRezObjects">
+ Şu anda nesne oluşturmanıza izin verilmiyor.
+ </notification>
+ <notification name="LandSearchBlocked">
+ Arazi Arama Engellendi.
+Çok fazla sayıda arazi aramasını çok hızlı gerçekleştirdiniz.
+Lütfen bir dakika sonra tekrar deneyin.
+ </notification>
+ <notification name="NotEnoughResourcesToAttach">
+ Nesneyi iliştirmek için yeterli komut dosyası kaynağı mevcut değil!
+ </notification>
+ <notification name="YouDiedAndGotTPHome">
+ Hayatınızı kaybettiniz ve ana konumunuza ışınlandınız
+ </notification>
+ <notification name="EjectComingSoon">
+ Daha fazla burada olma izniniz yok ve ayrılmak için [EJECT_TIME] saniyeniz var.
+ </notification>
+ <notification name="NoEnterServerFull">
+ Bu bölgeye giremezsiniz çünkü
+sunucu dolu.
+ </notification>
+ <notification name="SaveBackToInvDisabled">
+ Envantere Geri Kaydet devre dışı bırakıldı.
+ </notification>
+ <notification name="NoExistNoSaveToContents">
+ &apos;[OBJ_NAME]&apos; nesne içeriğine kaydedilemedi, çünkü oluşturulurken temel alınan nesne artık mevcut değil.
+ </notification>
+ <notification name="NoModNoSaveToContents">
+ &apos;[DEST_NAME]&apos; nesnesini değiştirme izniniz olmadığı için &apos;[OBJ_NAME]&apos; nesne içeriğine kaydedilemedi.
+ </notification>
+ <notification name="NoSaveBackToInvDisabled">
+ &apos;[OBJ_NAME]&apos; envantere geri kaydedilemez -- bu işlem devre dışı bırakıldı.
+ </notification>
+ <notification name="NoCopyNoSelCopy">
+ &apos;[OBJ_NAME]&apos; nesnesini kopyalama izniniz olmadığı için seçiminizi kopyalamayazsınız.
+ </notification>
+ <notification name="NoTransNoSelCopy">
+ &apos;[OBJ_NAME]&apos; nesnesi aktarılamaz olduğu için seçiminizi kopyalayamazsınız.
+ </notification>
+ <notification name="NoTransNoCopy">
+ &apos;[OBJ_NAME]&apos; nesnesi aktarılamaz olduğu için seçiminizi kopyalayamazsınız.
+ </notification>
+ <notification name="NoPermsNoRemoval">
+ Benzeticiden &apos;[OBJ_NAME]&apos; nesnesinin kaldırılmasına izinler sistemi izin vermiyor.
+ </notification>
+ <notification name="NoModNoSaveSelection">
+ &apos;[OBJ_NAME]&apos; nesnesini değiştirme izniniz olmadığı için seçiminizi kaydedemezsiniz.
+ </notification>
+ <notification name="NoCopyNoSaveSelection">
+ &apos;[OBJ_NAME]&apos; nesnesi kopyalanamaz olduğu için seçiminizi kaydedemezsiniz.
+ </notification>
+ <notification name="NoModNoTaking">
+ &apos;[OBJ_NAME]&apos; nesnesini değiştirme izniniz olmadığı için seçiminizi alamazsınız.
+ </notification>
+ <notification name="RezDestInternalError">
+ Dahili Hata: Bilinmeyen hedef türü.
+ </notification>
+ <notification name="DeleteFailObjNotFound">
+ Nesne bulunamadığı için silme başarılamadı
+ </notification>
+ <notification name="SorryCantEjectUser">
+ Üzgünüz, bu kullanıcı çıkartılamaz.
+ </notification>
+ <notification name="RegionSezNotAHome">
+ Bu bölge, ana konumunuzu buraya kurmanıza izin vermiyor.
+ </notification>
+ <notification name="HomeLocationLimits">
+ &apos;Ana Konum&apos;unuzu sadece arazinizde veya anakarada bir Bilgi Ä°stasyonu&apos;nda ayarlayabilirsiniz.
+ </notification>
+ <notification name="HomePositionSet">
+ Ana konum ayarlandı.
+ </notification>
+ <notification name="AvatarEjected">
+ Avatar çıkartıldı.
+ </notification>
+ <notification name="AvatarEjectFailed">
+ Çıkarma başarılamadı çünkü bu parsel için yönetici iznine sahip değilsiniz.
+ </notification>
+ <notification name="CantMoveObjectParcelFull">
+ [REGION_NAME] bölgesinde &apos;[OBJECT_NAME]&apos; nesnesi [OBJ_POSITION] konumuna hareket ettirilemiyor çünkü parsel dolu.
+ </notification>
+ <notification name="CantMoveObjectParcelPerms">
+ [REGION_NAME] bölgesinde &apos;[OBJECT_NAME]&apos; nesnesi [OBJ_POSITION] konumuna hareket ettirilemiyor çünkü bu parselde nesnelerinize izin verilmiyor.
+ </notification>
+ <notification name="CantMoveObjectParcelResources">
+ [REGION_NAME] bölgesinde &apos;[OBJECT_NAME]&apos; nesnesi [OBJ_POSITION] konumuna hareket ettirilemiyor, çünkü bu parselde bu nesne için yeterli kaynak yok.
+ </notification>
+ <notification name="CantMoveObjectRegionVersion">
+ [REGION_NAME] bölgesinde &apos;[OBJECT_NAME]&apos; nesnesi [OBJ_POSITION] konumuna hareket ettirilemiyor çünkü bölgede çalıştırılan eski versiyon, bölge değiştirme üzerinden bu nesnenin alınmasını desteklemiyor.
+ </notification>
+ <notification name="CantMoveObjectNavMesh">
+ [REGION_NAME] bölgesinde &apos;[OBJECT_NAME]&apos; nesnesi [OBJ_POSITION] konumuna hareket ettirilemiyor çünkü navmesh&apos;i bölge sınırları ötesinde değiştiremezsiniz.
+ </notification>
+ <notification name="CantMoveObjectWTF">
+ Bilinmeyen bir nedenden ötürü [REGION_NAME] bölgesinde &apos;[OBJECT_NAME]&apos; nesnesi [OBJ_POSITION] konumuna hareket ettirilemiyor. ([FAILURE_TYPE])
+ </notification>
+ <notification name="NoPermModifyObject">
+ Bu nesneyi deÄŸiÅŸtirme izniniz yok
+ </notification>
+ <notification name="CantEnablePhysObjContributesToNav">
+ Navmesh&apos;e katkıda bulunan bir nesne için fizik etkinleştirilemez.
+ </notification>
+ <notification name="CantEnablePhysKeyframedObj">
+ Anahtar karelenmiş nesneler için fizik etkinleştirilemez.
+ </notification>
+ <notification name="CantEnablePhysNotEnoughLandResources">
+ Nesne için fizik etkinleştirilemedi -- arazi kaynakları yetersiz.
+ </notification>
+ <notification name="CantEnablePhysCostTooGreat">
+ Fizik kaynağı maliyeti [MAX_OBJECTS]&apos;dan büyük nesne için fizik etkinleştirilemedi
+ </notification>
+ <notification name="PhantomWithConcavePiece">
+ Bu nesne fantom olduğu ve navmesh&apos;e katkıda bulunduğu için konkav bir parçaya sahip olamaz.
+ </notification>
+ <notification name="UnableAddItem">
+ Öğe eklenemedi!
+ </notification>
+ <notification name="UnableEditItem">
+ Bu düzenlenemiyor!
+ </notification>
+ <notification name="NoPermToEdit">
+ Bunu düzenleme izni yok.
+ </notification>
+ <notification name="NoPermToCopyInventory">
+ Bu envanteri kopyalama izni yok.
+ </notification>
+ <notification name="CantSaveItemDoesntExist">
+ Nesne içeriklerine kaydedilemedi: Öğe artık mevcut değil.
+ </notification>
+ <notification name="CantSaveItemAlreadyExists">
+ Nesne içeriklerine kaydedilemedi: Bu ada sahip öğe envanterde zaten mevcut
+ </notification>
+ <notification name="CantSaveModifyAttachment">
+ Nesne içeriklerine kaydedilemedi: Bu, aksesuar izinlerini değiştirmeyi gerektirirdi.
+ </notification>
+ <notification name="TooManyScripts">
+ Çok fazla komut dosyası.
+ </notification>
+ <notification name="UnableAddScript">
+ Komut dosyası eklenemedi!
+ </notification>
+ <notification name="AssetServerTimeoutObjReturn">
+ Varlık sunucusu zamanında yanıt vermedi. Nesne sime iade edildi.
+ </notification>
+ <notification name="RegionDisablePhysicsShapes">
+ Bu bölgede fiziksel şekiller etkin değil.
+ </notification>
+ <notification name="NoModNavmeshAcrossRegions">
+ Navmesh&apos;i bölge sınırlarının ötesinde değiştiremezsiniz.
+ </notification>
+ <notification name="NoSetPhysicsPropertiesOnObjectType">
+ Bu nesne türü üzerinde fizik özellikleri ayarlanamaz.
+ </notification>
+ <notification name="NoSetRootPrimWithNoShape">
+ Kök prim şekilsiz olacak şekilde ayarlanamaz.
+ </notification>
+ <notification name="NoRegionSupportPhysMats">
+ Bu bölgede fiziksel malzemeler etkin değil.
+ </notification>
+ <notification name="OnlyRootPrimPhysMats">
+ Sadece kök primlerin fizik malzemeleri ayarlanabilir.
+ </notification>
+ <notification name="NoSupportCharacterPhysMats">
+ Karakterler üzerinde fizik malzemelerin ayarlanması henüz desteklenmiyor.
+ </notification>
+ <notification name="InvalidPhysMatProperty">
+ Belirtilen fizik malzemesi özelliklerinden biri veya daha fazlası geçersiz.
+ </notification>
+ <notification name="NoPermsAlterStitchingMeshObj">
+ Bir örgü nesnesinin dikiş türünü değiştiremezsiniz.
+ </notification>
+ <notification name="NoPermsAlterShapeMeshObj">
+ Bir örgü nesnesinin şeklini değiştiremezsiniz
+ </notification>
+ <notification name="FullRegionCantEnter">
+ Bu bölgeye giremezsiniz çünkü \nbölge dolu.
+ </notification>
+ <notification name="LinkFailedOwnersDiffer">
+ Bağlantı başarısız oldu -- sahipler farklı
+ </notification>
+ <notification name="LinkFailedNoModNavmeshAcrossRegions">
+ Bağlntı başarılamadı -- navmesh&apos;i bölge sınırlarının ötesinde değiştiremezsiniz.
+ </notification>
+ <notification name="LinkFailedNoPermToEdit">
+ Düzenleme iznine sahip olmadığınız için bağlantı başarılamadı.
+ </notification>
+ <notification name="LinkFailedTooManyPrims">
+ Bağlantı başarısız oldu -- çok fazla ilkel öğe var
+ </notification>
+ <notification name="LinkFailedCantLinkNoCopyNoTrans">
+ Bağlantı başarısız oldu -- aktarılamayanla kopyalanamayan arasında bağlantı kurulamaz
+ </notification>
+ <notification name="LinkFailedNothingLinkable">
+ Bağlantı başarısız oldu -- bağlantı verilebilecek bir şey yok.
+ </notification>
+ <notification name="LinkFailedTooManyPathfindingChars">
+ Bağlantı başarısız oldu -- çok fazla yol bulma karakteri var
+ </notification>
+ <notification name="LinkFailedInsufficientLand">
+ Bağlantı başarısız oldu -- arazi kaynakları yetersiz
+ </notification>
+ <notification name="LinkFailedTooMuchPhysics">
+ Nesne çok fazla fizik kaynağı kullanıyor -- dinamikleri devre dışı bırakıldı.
+ </notification>
+ <notification name="TeleportedHomeByObjectOnParcel">
+ &apos;[PARCEL_NAME]&apos; parseli üzerindeki &apos;[OBJECT_NAME]&apos; nesnesi tarafından ana konuma ışınlandınız
+ </notification>
+ <notification name="TeleportedHomeByObject">
+ &apos;[OBJECT_NAME]&apos; nesnesi tarafından ana konuma ışınlandınız
+ </notification>
+ <notification name="TeleportedByAttachment">
+ You have been teleported by an attachment on [ITEM_ID]
+ </notification>
+ <notification name="TeleportedByObjectOnParcel">
+ &apos;[PARCEL_NAME]&apos; parseli üzerindeki &apos;[OBJECT_NAME]&apos; nesnesi tarafından ışınlandınız
+ </notification>
+ <notification name="TeleportedByObjectOwnedBy">
+ Sahibi [OWNER_ID] olan &apos;[OBJECT_NAME]&apos; nesnesi tarafından ışınlandınız
+ </notification>
+ <notification name="TeleportedByObjectUnknownUser">
+ Bilinmeyen bir sahibi olan &apos;[OBJECT_NAME]&apos; nesnesi tarafından ışınlandınız.
+ </notification>
+ <notification name="CantCreateObjectRegionFull">
+ Talep edilen nesne oluşturulamıyor. Bölge dolu.
+ </notification>
+ <notification name="CantAttackMultipleObjOneSpot">
+ Tek bir noktaya birden fazla nesne iliÅŸtiremezsiniz.
+ </notification>
+ <notification name="CantCreateMultipleObjAtLoc">
+ Burada birden fazla nesne oluşturamazsınız.
+ </notification>
+ <notification name="UnableToCreateObjTimeOut">
+ Talep edilen nesne oluşturulamıyor. Nesne veri tabanında yok.
+ </notification>
+ <notification name="UnableToCreateObjUnknown">
+ Talep edilen nesne oluşturulamıyor. Talep zaman aşımına uğradı. Lütfen tekrar deneyin.
+ </notification>
+ <notification name="UnableToCreateObjMissingFromDB">
+ Talep edilen nesne oluşturulamıyor. Lütfen tekrar deneyin.
+ </notification>
+ <notification name="RezFailureTookTooLong">
+ Oluşturma başarısız oldu, talep edilen nesnenin yüklenmesi çok zaman aldı.
+ </notification>
+ <notification name="FailedToPlaceObjAtLoc">
+ Belirtilen konuma nesne yerleştirilemedi. Lütfen tekrar deneyin.
+ </notification>
+ <notification name="CantCreatePlantsOnLand">
+ Bu arazide bitkiler oluşturamazsınız.
+ </notification>
+ <notification name="CantRestoreObjectNoWorldPos">
+ Nesne geri yüklenemiyor. Dünya konumu bulunamadı.
+ </notification>
+ <notification name="CantRezObjectInvalidMeshData">
+ Örgü verileri geçersiz olduğu için nesne oluşturulamadı.
+ </notification>
+ <notification name="CantRezObjectTooManyScripts">
+ Bölgede zaten fazlasıyla komut dosyası olduğu için nesne oluşturulamadı.
+ </notification>
+ <notification name="CantCreateObjectNoAccess">
+ Erişim ayrıcalıklarınız orada nesne oluşturmanıza izin vermiyor.
+ </notification>
+ <notification name="CantCreateObject">
+ Şu anda nesne oluşturmanıza izin verilmiyor.
+ </notification>
+ <notification name="InvalidObjectParams">
+ Geçersiz nesne parametreleri
+ </notification>
+ <notification name="CantDuplicateObjectNoAcess">
+ Erişim ayrıcalıklarınız burada nesne çoğaltmanıza izin vermiyor.
+ </notification>
+ <notification name="CantChangeShape">
+ Bu ÅŸekli deÄŸiÅŸtirmenize izin verilmiyor.
+ </notification>
+ <notification name="NoAccessToClaimObjects">
+ Erişim ayrıcalıklarınız burada nesneler üzerinde hak talebinde bulunmanıza izin vermiyor.
+ </notification>
+ <notification name="DeedFailedNoPermToDeedForGroup">
+ Grubunuz adına nesne devretmek için gerekli izne sahip olmadığınız için devretme başarılamadı.
+ </notification>
+ <notification name="NoPrivsToBuyObject">
+ Erişim ayrıcalıklarınız burada nesneler satın almanıza izin vermiyor.
+ </notification>
+ <notification name="CantAttachObjectAvatarSittingOnIt">
+ Üzerinde bir avatar oturduğu için nesne iliştirilemiyor.
+ </notification>
+ <notification name="WhyAreYouTryingToWearShrubbery">
+ Ağaçlar ve çimen aksesuar olarak giyilemez.
+ </notification>
+ <notification name="CantAttachGroupOwnedObjs">
+ Sahibi grup olan nesneler iliÅŸtirilemiyor.
+ </notification>
+ <notification name="CantAttachObjectsNotOwned">
+ Sahip olmadığınız nesneleri iliştiremezsiniz.
+ </notification>
+ <notification name="CantAttachNavmeshObjects">
+ Navmesh&apos;e katkıda bulunan nesneler iliştirilemez.
+ </notification>
+ <notification name="CantAttachObjectNoMovePermissions">
+ Nesneyi hareket ettirme izniniz olmadığı için nesneyi iliştiremiyorsanız.
+ </notification>
+ <notification name="CantAttachNotEnoughScriptResources">
+ Nesneyi iliştirmek için yeterli komut dosyası kaynağı mevcut değil!
+ </notification>
+ <notification name="CantDropItemTrialUser">
+ Buraya nesne düşüremezsiniz; Ücretsiz Deneme alanını deneyin.
+ </notification>
+ <notification name="CantDropMeshAttachment">
+ Örgü aksesuarlarını düşüremezsiniz. Envantere ayırın, sonra dünyada oluşturun.
+ </notification>
+ <notification name="CantDropAttachmentNoPermission">
+ Aksesuar düşürülemedi: Burada düşürme izniniz yok.
+ </notification>
+ <notification name="CantDropAttachmentInsufficientLandResources">
+ Aksesuar düşürülemedi: Mevcut arazi kaynakları yetersiz.
+ </notification>
+ <notification name="CantDropAttachmentInsufficientResources">
+ Aksesuarlar düşürülemedi: Mevcut kaynaklar yetersiz.
+ </notification>
+ <notification name="CantDropObjectFullParcel">
+ Nesne buraya düşürülemez. Parsel dolu.
+ </notification>
+ <notification name="CantTouchObjectBannedFromParcel">
+ Bu arazi parselinde yasaklandığınız için bu nesneye dokunamıyor/tutamıyorsunuz.
+ </notification>
+ <notification name="PlzNarrowDeleteParams">
+ Lütfen silme parametrelerinizi daraltın.
+ </notification>
+ <notification name="UnableToUploadAsset">
+ Varlık karşıya yüklenemiyor.
+ </notification>
+ <notification name="CantTeleportCouldNotFindUser">
+ Ana konuma ışınlanacak kullanıcı bulunamadı
+ </notification>
+ <notification name="GodlikeRequestFailed">
+ tanrısal talep başarısız oldu
+ </notification>
+ <notification name="GenericRequestFailed">
+ genel talep başarısız oldu
+ </notification>
+ <notification name="CantUploadPostcard">
+ Posta kartı karşıya yüklenemiyor. Daha sonra tekrar deneyin.
+ </notification>
+ <notification name="CantFetchInventoryForGroupNotice">
+ Grup bildirimi için envanter ayrıntıları alınamadı.
+ </notification>
+ <notification name="CantSendGroupNoticeNotPermitted">
+ Grup bildirimi gönderilemedi -- izin verilmiyor.
+ </notification>
+ <notification name="CantSendGroupNoticeCantConstructInventory">
+ Grup bildirimi gönderilemedi -- envanter oluşturulamadı.
+ </notification>
+ <notification name="CantParceInventoryInNotice">
+ Bildirimde envanter ayrıştırılamadı.
+ </notification>
+ <notification name="TerrainUploadFailed">
+ Yüzeyin karşıya yüklemesi başarılamadı.
+ </notification>
+ <notification name="TerrainFileWritten">
+ Yüzey dosyası yazıldı.
+ </notification>
+ <notification name="TerrainFileWrittenStartingDownload">
+ Yüzey dosyası yazıldı, karşıdan yükleme başlatılıyor...
+ </notification>
+ <notification name="TerrainBaked">
+ Yüzey kaydedildi.
+ </notification>
+ <notification name="TenObjectsDisabledPlzRefresh">
+ Sadece seçilen ilk 10 nesne devre dışı bırakıldı. Gerekiyorsa yenileyin ve ilave seçimler yapın.
+ </notification>
+ <notification name="UpdateViewerBuyParcel">
+ Bu parseli satın almak için görüntüleyicinizi güncelleştirmelisiniz.
+ </notification>
+ <notification name="CantBuyParcelNotForSale">
+ Satın alınamıyor, bu parsel satılık değil.
+ </notification>
+ <notification name="CantBuySalePriceOrLandAreaChanged">
+ Satın alınamıyor, satış fiyatı veya arazi bölgesi değişmiş.
+ </notification>
+ <notification name="CantBuyParcelNotAuthorized">
+ Bu parsel için yetkili alıcı değilsiniz.
+ </notification>
+ <notification name="CantBuyParcelAwaitingPurchaseAuth">
+ Bu parseli satın alamazsınız çünkü zaten satın alım yetkilendirmesi bekliyor
+ </notification>
+ <notification name="CantBuildOverflowParcel">
+ Burada nesneler inşa edemezsiniz, aksi halde parselin kaynak sınırları aşılır.
+ </notification>
+ <notification name="SelectedMultipleOwnedLand">
+ Farklı sahiplere ait araziler seçtiniz. Lütfen daha küçük bir alan seçin ve tekrar deneyin.
+ </notification>
+ <notification name="CantJoinTooFewLeasedParcels">
+ Seçimde birleştirilecek yeterli sayıda lease edilmiş parsel yok.
+ </notification>
+ <notification name="CantDivideLandMultipleParcelsSelected">
+ Arazi bölünemedi.\nBirden fazla parsel seçili durumda.\nDaha küçük bir arazi parçası seçmeyi deneyin.
+ </notification>
+ <notification name="CantDivideLandCantFindParcel">
+ Arazi bölünemiyor.\nParsel bulunamıyor.\nLütfen Yardım -&gt; Hata Bildir ile bildirin...
+ </notification>
+ <notification name="CantDivideLandWholeParcelSelected">
+ Arazi bölünemiyor. Tüm parsel seçilidir.\nDaha küçük bir arazi parçası seçmeyi deneyin.
+ </notification>
+ <notification name="LandHasBeenDivided">
+ Arazi bölündü.
+ </notification>
+ <notification name="PassPurchased">
+ Bir geçiş hakkı satın aldınız.
+ </notification>
+ <notification name="RegionDisallowsClassifieds">
+ Bölgede seri ilanlara izin verilmiyor.
+ </notification>
+ <notification name="LandPassExpireSoon">
+ Bu arazi için geçiş hakkınız sona ermek üzere.
+ </notification>
+ <notification name="CantSitNoSuitableSurface">
+ Üzerinde oturulabilecek uygun bir yüzey yok, başka bir noktayı deneyin.
+ </notification>
+ <notification name="CantSitNoRoom">
+ Burada oturacak yer yok, baÅŸka bir yer deneyin.
+ </notification>
+ <notification name="ClaimObjectFailedNoPermission">
+ İzniniz olmadığı için nesne üzerinde hak talep etme başarılamadı
+ </notification>
+ <notification name="ClaimObjectFailedNoMoney">
+ Sahip olduğunuz L$ yeterli olmadığı için nesne üzerinde hak talep etme başarılamadı.
+ </notification>
+ <notification name="CantDeedGroupLand">
+ Grubun sahip olduÄŸu araziyi devredemezsiniz.
+ </notification>
+ <notification name="BuyObjectFailedNoMoney">
+ Sahip olduğunuz L$ yeterli olmadığı için nesne satın alma başarılamadı.
+ </notification>
+ <notification name="BuyInventoryFailedNoMoney">
+ Sahip olduğunuz L$ yeterli olmadığı için envanter satın alma başarılamadı.
+ </notification>
+ <notification name="BuyPassFailedNoMoney">
+ Sahibi olduğunuz L$ bu araziye geçiş hakkı almanıza yeterli değil.
+ </notification>
+ <notification name="CantBuyPassTryAgain">
+ Şu anda geçiş hakkı satın alınamıyor. Daha sonra tekrar deneyin.
+ </notification>
+ <notification name="CantCreateObjectParcelFull">
+ Nesne oluşturulamıyor çünkü \nparsel dolu.
+ </notification>
+ <notification name="FailedPlacingObject">
+ Belirtilen konuma nesne yerleştirilemedi. Lütfen tekrar deneyin.
+ </notification>
+ <notification name="CantCreateLandmarkForEvent">
+ Etkinlik için yer imi oluşturulamıyor.
+ </notification>
+ <notification name="GodBeatsFreeze">
+ Tanrısal güçleriniz dondurmayı devre dışı bıraktı!
+ </notification>
+ <notification name="SpecialPowersRequestFailedLogged">
+ Özel yetkiler talebi başarısız oldu. Bu talep günlüğe kaydedildi.
+ </notification>
+ <notification name="ExpireExplanation">
+ Sistem şu anda talebinizi işleyemiyor. Talep zaman aşımına uğradı.
+ </notification>
+ <notification name="DieExplanation">
+ Sistem talebinizi iÅŸleyemiyor.
+ </notification>
+ <notification name="AddPrimitiveFailure">
+ İlkel öğeyi oluşturmak için yeterli fon yok.
+ </notification>
+ <notification name="RezObjectFailure">
+ Nesneyi oluşturmak için yeterli fon yok.
+ </notification>
+ <notification name="ResetHomePositionNotLegal">
+ Ana konum sıfırlandı çünkü Ana konum yasal değildi.
+ </notification>
+ <notification name="CantInviteRegionFull">
+ Şu anda konumunuza kimseyi davet edemezsiniz çünkü bölge dolu. Daha sonra tekrar deneyin.
+ </notification>
+ <notification name="CantSetHomeAtRegion">
+ Bu bölge, ana konumunuzu buraya kurmanıza izin vermiyor.
+ </notification>
+ <notification name="ListValidHomeLocations">
+ &apos;Ana Konum&apos;unuzu sadece arazinizde veya anakarada bir Bilgi Ä°stasyonu&apos;nda ayarlayabilirsiniz.
+ </notification>
+ <notification name="SetHomePosition">
+ Ana konum ayarlandı.
+ </notification>
+ <notification name="CantDerezInventoryError">
+ Envanter hatasından ötürü nesne oluşturulması geri alınamıyor.
+ </notification>
+ <notification name="CantCreateRequestedInv">
+ Talep edilen envanter oluşturulamadı.
+ </notification>
+ <notification name="CantCreateRequestedInvFolder">
+ Talep edilen envanter klasörü oluşturulamadı.
+ </notification>
+ <notification name="CantCreateInventory">
+ Bu envanter oluşturulamadı.
+ </notification>
+ <notification name="CantCreateLandmark">
+ Yer imi oluşturulamıyor.
+ </notification>
+ <notification name="CantCreateOutfit">
+ Dış görünüm şu anda oluşturulamıyor. Bir dakika sonra tekrar deneyin.
+ </notification>
+ <notification name="InventoryNotForSale">
+ Envanter satılık değil.
+ </notification>
+ <notification name="CantFindInvItem">
+ Envanter öğesi bulunamıyor.
+ </notification>
+ <notification name="CantFindObject">
+ Nesne bulunamıyor.
+ </notification>
+ <notification name="CantTransfterMoneyRegionDisabled">
+ Nesnelere para transferleri bölgede şu anda devre dışı bırakılmış durumda.
+ </notification>
+ <notification name="CantPayNoAgent">
+ Kime ödeme yapılacağı belirlenemedi.
+ </notification>
+ <notification name="CantDonateToPublicObjects">
+ Kamusal nesnelere L$ veremezsiniz.
+ </notification>
+ <notification name="InventoryCreationInWorldObjectFailed">
+ Dünya içerisindeki nesnede envater oluşturma başarısız oldu.
+ </notification>
+ <notification name="UserBalanceOrLandUsageError">
+ Dahili bir hata nedeniyle görüntüleyicinizi gerektiği gibi güncelleyemedik. Görüntüleyicinizde gösterilen L$ bakiyesi veya parsel tutarı sunucular üzerinde gerçekteki bakiyenizi yansıtmayabilir.
+ </notification>
+ <notification name="LargePrimAgentIntersect">
+ Başka oyuncularla kesişen büyük primler oluşturulamaz. Öbür oyuncular hareket ettiğinde lütfen tekrar deneyin.
+ </notification>
+ <notification name="PreferenceChatClearLog">
+ Bu, geçmiş sohbetlerin günlüklerini ve bu dosyanın tüm yedeklerini silecektir.
+ <usetemplate ignoretext="Ben geçmiş sohbetlerin günlüğünü silmeden önce doğrula." name="okcancelignore" notext="İptal" yestext="Tamam"/>
+ </notification>
+ <notification name="PreferenceChatDeleteTranscripts">
+ Bu, tüm geçmiş sohbetlerin dökümlerini silecektir. Geçmiş sohbetlerin listesi bundan etkilenmez. [FOLDER] klasöründe .txt ve txt.backup uzantısına sahip tüm dosyalar silinecektir.
+ <usetemplate ignoretext="Ben dökümleri silmeden önce doğrulama iste." name="okcancelignore" notext="İptal" yestext="Tamam"/>
+ </notification>
+ <notification name="PreferenceChatPathChanged">
+ Dosyalar taşınamıyor. Önceki yol geri yüklendi.
+ <usetemplate ignoretext="Dosyalar taşınamıyor. Önceki yol geri yüklendi." name="okignore" yestext="Tamam"/>
+ </notification>
</notifications>
diff --git a/indra/newview/skins/default/xui/tr/panel_active_object_row.xml b/indra/newview/skins/default/xui/tr/panel_active_object_row.xml
index b03ce3ebe5..b03ce3ebe5 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_active_object_row.xml
+++ b/indra/newview/skins/default/xui/tr/panel_active_object_row.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_adhoc_control_panel.xml b/indra/newview/skins/default/xui/tr/panel_adhoc_control_panel.xml
index 602818de94..602818de94 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_adhoc_control_panel.xml
+++ b/indra/newview/skins/default/xui/tr/panel_adhoc_control_panel.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_avatar_list_item.xml b/indra/newview/skins/default/xui/tr/panel_avatar_list_item.xml
index 7542778aca..f330bd85e8 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_avatar_list_item.xml
+++ b/indra/newview/skins/default/xui/tr/panel_avatar_list_item.xml
@@ -27,5 +27,6 @@
<icon name="permission_edit_mine_icon" tool_tip="Bu arkadaşınız nesnelerinizi düzenleyebilir, silebilir veya alabilir"/>
<icon name="permission_map_icon" tool_tip="Bu arkadaşınız haritada sizi bulabilir"/>
<icon name="permission_online_icon" tool_tip="Bu arkadaşınız çevrimiçi olduğunuzda sizi görebilir"/>
+ <button name="info_btn" tool_tip="Ek bilgi"/>
<button name="profile_btn" tool_tip="Profili göster"/>
</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_avatar_tag.xml b/indra/newview/skins/default/xui/tr/panel_avatar_tag.xml
index 81e04379a1..81e04379a1 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_avatar_tag.xml
+++ b/indra/newview/skins/default/xui/tr/panel_avatar_tag.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_block_list_sidetray.xml b/indra/newview/skins/default/xui/tr/panel_block_list_sidetray.xml
index 0464b7ec07..87b67e249e 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_block_list_sidetray.xml
+++ b/indra/newview/skins/default/xui/tr/panel_block_list_sidetray.xml
@@ -1,10 +1,11 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel name="block_list_panel">
- <text name="title_text">
- Listeyi Engelle
- </text>
- <scroll_list name="blocked" tool_tip="Åžu anda engellenmiÅŸ olan Sakinler listesi"/>
- <button label="Kişiyi engelle" name="Block resident..." tool_tip="Engellenecek bir Sakin seç"/>
- <button label="Nesneyi ada göre engelle" name="Block object by name..." tool_tip="Ada göre engellenecek bir nesne seç"/>
- <button label="Engellemeyi Kaldır" name="Unblock" tool_tip="Engelleme listesinden Sakini veya nesneyi kaldır"/>
+ <panel label="bottom_panel" name="blocked_buttons_panel">
+ <filter_editor label="Filtrele" name="blocked_filter_input"/>
+ <menu_button name="blocked_gear_btn" tool_tip="Seçilen kişi veya nesne üzerindeki eylemler"/>
+ <menu_button name="view_btn" tool_tip="Sıralama seçenekleri"/>
+ <menu_button name="plus_btn" tool_tip="Engellenecek bir Sakin veya nesne seç"/>
+ <button name="unblock_btn" tool_tip="Engelleme listesinden Sakini veya nesneyi kaldır"/>
+ </panel>
+ <block_list name="blocked" tool_tip="Åžu anda engellenmiÅŸ olan Sakinler listesi"/>
</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_body_parts_list_item.xml b/indra/newview/skins/default/xui/tr/panel_body_parts_list_item.xml
index f991c3b688..f991c3b688 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_body_parts_list_item.xml
+++ b/indra/newview/skins/default/xui/tr/panel_body_parts_list_item.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_bodyparts_list_button_bar.xml b/indra/newview/skins/default/xui/tr/panel_bodyparts_list_button_bar.xml
index 6c2478cdb7..6c2478cdb7 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_bodyparts_list_button_bar.xml
+++ b/indra/newview/skins/default/xui/tr/panel_bodyparts_list_button_bar.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_bottomtray.xml b/indra/newview/skins/default/xui/tr/panel_bottomtray.xml
deleted file mode 100644
index 26118d8b39..0000000000
--- a/indra/newview/skins/default/xui/tr/panel_bottomtray.xml
+++ /dev/null
@@ -1,47 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel name="bottom_tray">
- <string name="DragIndicationImageName" value="Accordion_ArrowOpened_Off"/>
- <string name="SpeakBtnToolTip" value="Mikrofonu açar/kapatır"/>
- <string name="VoiceControlBtnToolTip" value="Ses kontrol panelini gösterir/gizler"/>
- <layout_stack name="toolbar_stack">
- <layout_panel name="speak_panel">
- <talk_button name="talk">
- <speak_button label="KonuÅŸ" label_selected="KonuÅŸ" name="speak_btn"/>
- </talk_button>
- </layout_panel>
- <layout_panel name="gesture_panel">
- <gesture_combo_list label="Mimik" name="Gesture" tool_tip="Mimikleri gösterir/gizler"/>
- </layout_panel>
- <layout_panel name="movement_panel">
- <bottomtray_button label="Hareket Et" name="movement_btn" tool_tip="Hareket kontrollerini gösterir/gizler"/>
- </layout_panel>
- <layout_panel name="cam_panel">
- <bottomtray_button label="Görünüm" name="camera_btn" tool_tip="Kamera kontrollerini gösterir/gizler"/>
- </layout_panel>
- <layout_panel name="snapshot_panel">
- <bottomtray_button name="snapshots" tool_tip="Anlık görüntü al"/>
- </layout_panel>
- <layout_panel name="build_btn_panel">
- <bottomtray_button label="İnşa Et" name="build_btn" tool_tip="İnşa Et Aracını gösterir/gizler"/>
- </layout_panel>
- <layout_panel name="search_btn_panel">
- <bottomtray_button label="Ara" name="search_btn" tool_tip="Aramayı gösterir/gizler"/>
- </layout_panel>
- <layout_panel name="world_map_btn_panel">
- <bottomtray_button label="Harita" name="world_map_btn" tool_tip="Dünya Haritasını gösterir/gizler"/>
- </layout_panel>
- <layout_panel name="mini_map_btn_panel">
- <bottomtray_button label="Mini-Harita" name="mini_map_btn" tool_tip="Mini Haritayı gösterir/gizler"/>
- </layout_panel>
- <layout_panel name="im_well_panel">
- <chiclet_im_well name="im_well">
- <button name="Unread IM messages" tool_tip="Sohbetler"/>
- </chiclet_im_well>
- </layout_panel>
- <layout_panel name="notification_well_panel">
- <chiclet_notification name="notification_well">
- <button name="Unread" tool_tip="Bildirimler"/>
- </chiclet_notification>
- </layout_panel>
- </layout_stack>
-</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_bottomtray_lite.xml b/indra/newview/skins/default/xui/tr/panel_bottomtray_lite.xml
index 5d7006af2f..5d7006af2f 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_bottomtray_lite.xml
+++ b/indra/newview/skins/default/xui/tr/panel_bottomtray_lite.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_chat_header.xml b/indra/newview/skins/default/xui/tr/panel_chat_header.xml
index 7916bf5155..7916bf5155 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_chat_header.xml
+++ b/indra/newview/skins/default/xui/tr/panel_chat_header.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_chiclet_bar.xml b/indra/newview/skins/default/xui/tr/panel_chiclet_bar.xml
index a1e8190bbc..a1e8190bbc 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_chiclet_bar.xml
+++ b/indra/newview/skins/default/xui/tr/panel_chiclet_bar.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_classified_info.xml b/indra/newview/skins/default/xui/tr/panel_classified_info.xml
index d412a03e32..d412a03e32 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_classified_info.xml
+++ b/indra/newview/skins/default/xui/tr/panel_classified_info.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_clothing_list_button_bar.xml b/indra/newview/skins/default/xui/tr/panel_clothing_list_button_bar.xml
index bb5930ee79..bb5930ee79 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_clothing_list_button_bar.xml
+++ b/indra/newview/skins/default/xui/tr/panel_clothing_list_button_bar.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_clothing_list_item.xml b/indra/newview/skins/default/xui/tr/panel_clothing_list_item.xml
index e60e291ee8..e60e291ee8 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_clothing_list_item.xml
+++ b/indra/newview/skins/default/xui/tr/panel_clothing_list_item.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_cof_wearables.xml b/indra/newview/skins/default/xui/tr/panel_cof_wearables.xml
index 7d70177553..7d70177553 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_cof_wearables.xml
+++ b/indra/newview/skins/default/xui/tr/panel_cof_wearables.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_conversation_list_item.xml b/indra/newview/skins/default/xui/tr/panel_conversation_list_item.xml
new file mode 100644
index 0000000000..c7227f02b6
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/panel_conversation_list_item.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="conversation_list_item">
+ <layout_stack name="conversation_item_stack">
+ <layout_panel name="conversation_title_panel">
+ <text name="conversation_title" value="(yükleniyor)"/>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_conversation_log_list_item.xml b/indra/newview/skins/default/xui/tr/panel_conversation_log_list_item.xml
new file mode 100644
index 0000000000..79895f9c21
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/panel_conversation_log_list_item.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="conversation_log_list_item">
+ <icon name="voice_session_icon" tool_tip="Sohbet ses dahil edildi"/>
+ <icon name="unread_ims_icon" tool_tip="Oturumunuz kapalıyken mesajlar geldi"/>
+ <button name="delete_btn" tool_tip="Bu girişi kaldır"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_deletable_wearable_list_item.xml b/indra/newview/skins/default/xui/tr/panel_deletable_wearable_list_item.xml
index 47703136b0..47703136b0 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_deletable_wearable_list_item.xml
+++ b/indra/newview/skins/default/xui/tr/panel_deletable_wearable_list_item.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_dummy_clothing_list_item.xml b/indra/newview/skins/default/xui/tr/panel_dummy_clothing_list_item.xml
index 28e034a357..28e034a357 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_dummy_clothing_list_item.xml
+++ b/indra/newview/skins/default/xui/tr/panel_dummy_clothing_list_item.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_edit_alpha.xml b/indra/newview/skins/default/xui/tr/panel_edit_alpha.xml
index e3ba806b0d..e3ba806b0d 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_edit_alpha.xml
+++ b/indra/newview/skins/default/xui/tr/panel_edit_alpha.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_edit_classified.xml b/indra/newview/skins/default/xui/tr/panel_edit_classified.xml
index 7584b754f1..7584b754f1 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_edit_classified.xml
+++ b/indra/newview/skins/default/xui/tr/panel_edit_classified.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_edit_eyes.xml b/indra/newview/skins/default/xui/tr/panel_edit_eyes.xml
index 42f62b6bbe..42f62b6bbe 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_edit_eyes.xml
+++ b/indra/newview/skins/default/xui/tr/panel_edit_eyes.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_edit_gloves.xml b/indra/newview/skins/default/xui/tr/panel_edit_gloves.xml
index be89e94bbf..be89e94bbf 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_edit_gloves.xml
+++ b/indra/newview/skins/default/xui/tr/panel_edit_gloves.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_edit_hair.xml b/indra/newview/skins/default/xui/tr/panel_edit_hair.xml
index f33a6d6402..f33a6d6402 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_edit_hair.xml
+++ b/indra/newview/skins/default/xui/tr/panel_edit_hair.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_edit_jacket.xml b/indra/newview/skins/default/xui/tr/panel_edit_jacket.xml
index 10bc4278db..10bc4278db 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_edit_jacket.xml
+++ b/indra/newview/skins/default/xui/tr/panel_edit_jacket.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_edit_pants.xml b/indra/newview/skins/default/xui/tr/panel_edit_pants.xml
index 06e1b7b4ab..06e1b7b4ab 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_edit_pants.xml
+++ b/indra/newview/skins/default/xui/tr/panel_edit_pants.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_edit_physics.xml b/indra/newview/skins/default/xui/tr/panel_edit_physics.xml
index 98dbfd8e42..98dbfd8e42 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_edit_physics.xml
+++ b/indra/newview/skins/default/xui/tr/panel_edit_physics.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_edit_pick.xml b/indra/newview/skins/default/xui/tr/panel_edit_pick.xml
index 98b02d27df..98b02d27df 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_edit_pick.xml
+++ b/indra/newview/skins/default/xui/tr/panel_edit_pick.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_edit_profile.xml b/indra/newview/skins/default/xui/tr/panel_edit_profile.xml
index 21f4e419bc..21f4e419bc 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_edit_profile.xml
+++ b/indra/newview/skins/default/xui/tr/panel_edit_profile.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_edit_shape.xml b/indra/newview/skins/default/xui/tr/panel_edit_shape.xml
index 57cd9aca75..57cd9aca75 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_edit_shape.xml
+++ b/indra/newview/skins/default/xui/tr/panel_edit_shape.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_edit_shirt.xml b/indra/newview/skins/default/xui/tr/panel_edit_shirt.xml
index 2dd417afc6..2dd417afc6 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_edit_shirt.xml
+++ b/indra/newview/skins/default/xui/tr/panel_edit_shirt.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_edit_shoes.xml b/indra/newview/skins/default/xui/tr/panel_edit_shoes.xml
index 34acb414b0..34acb414b0 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_edit_shoes.xml
+++ b/indra/newview/skins/default/xui/tr/panel_edit_shoes.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_edit_skin.xml b/indra/newview/skins/default/xui/tr/panel_edit_skin.xml
index fdf75100ed..fdf75100ed 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_edit_skin.xml
+++ b/indra/newview/skins/default/xui/tr/panel_edit_skin.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_edit_skirt.xml b/indra/newview/skins/default/xui/tr/panel_edit_skirt.xml
index 2099013fe1..2099013fe1 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_edit_skirt.xml
+++ b/indra/newview/skins/default/xui/tr/panel_edit_skirt.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_edit_socks.xml b/indra/newview/skins/default/xui/tr/panel_edit_socks.xml
index d386814d31..d386814d31 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_edit_socks.xml
+++ b/indra/newview/skins/default/xui/tr/panel_edit_socks.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_edit_tattoo.xml b/indra/newview/skins/default/xui/tr/panel_edit_tattoo.xml
index 7f5590a485..7f5590a485 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_edit_tattoo.xml
+++ b/indra/newview/skins/default/xui/tr/panel_edit_tattoo.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_edit_underpants.xml b/indra/newview/skins/default/xui/tr/panel_edit_underpants.xml
index ed003e1adf..ed003e1adf 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_edit_underpants.xml
+++ b/indra/newview/skins/default/xui/tr/panel_edit_underpants.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_edit_undershirt.xml b/indra/newview/skins/default/xui/tr/panel_edit_undershirt.xml
index e0a0be8abb..e0a0be8abb 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_edit_undershirt.xml
+++ b/indra/newview/skins/default/xui/tr/panel_edit_undershirt.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_edit_wearable.xml b/indra/newview/skins/default/xui/tr/panel_edit_wearable.xml
index 7a4a09aaed..7a4a09aaed 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_edit_wearable.xml
+++ b/indra/newview/skins/default/xui/tr/panel_edit_wearable.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_group_control_panel.xml b/indra/newview/skins/default/xui/tr/panel_group_control_panel.xml
index 58bb68a5c3..58bb68a5c3 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_group_control_panel.xml
+++ b/indra/newview/skins/default/xui/tr/panel_group_control_panel.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_group_general.xml b/indra/newview/skins/default/xui/tr/panel_group_general.xml
index 0462026249..0462026249 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_group_general.xml
+++ b/indra/newview/skins/default/xui/tr/panel_group_general.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_group_info_sidetray.xml b/indra/newview/skins/default/xui/tr/panel_group_info_sidetray.xml
index 32f39da490..32f39da490 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_group_info_sidetray.xml
+++ b/indra/newview/skins/default/xui/tr/panel_group_info_sidetray.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_group_invite.xml b/indra/newview/skins/default/xui/tr/panel_group_invite.xml
index 9b0c7f799a..4ba5761edb 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_group_invite.xml
+++ b/indra/newview/skins/default/xui/tr/panel_group_invite.xml
@@ -9,6 +9,9 @@
<panel.string name="already_in_group">
Seçtiğiniz bazı Sakinler zaten grupta yer alıyor, bu yüzden bunlara davetiye gönderilmedi.
</panel.string>
+ <panel.string name="invite_selection_too_large">
+ Gönderilmeyen Grup Davetiyeleri: Çok fazla Sakin seçilmiş. Grup Davetiyelerinde talep başına 100 sınırı vardır.
+ </panel.string>
<text name="help_text">
Grubunuza davet etmek için birden fazla Sakin seçebilirsiniz. Başlamak için &quot;Sakin Seçiciyi Aç&quot; üzerine tıklayın.
</text>
diff --git a/indra/newview/skins/default/xui/tr/panel_group_land_money.xml b/indra/newview/skins/default/xui/tr/panel_group_land_money.xml
index e9112a862b..e9112a862b 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_group_land_money.xml
+++ b/indra/newview/skins/default/xui/tr/panel_group_land_money.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_group_list_item.xml b/indra/newview/skins/default/xui/tr/panel_group_list_item.xml
index 2bc597f2fa..f44d2b5e76 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_group_list_item.xml
+++ b/indra/newview/skins/default/xui/tr/panel_group_list_item.xml
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel name="group_list_item">
<text name="group_name" value="Bilinmiyor"/>
+ <button name="info_btn" tool_tip="Ek bilgi"/>
<button name="profile_btn" tool_tip="Profili göster"/>
</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_group_notices.xml b/indra/newview/skins/default/xui/tr/panel_group_notices.xml
index 179b5fff69..179b5fff69 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_group_notices.xml
+++ b/indra/newview/skins/default/xui/tr/panel_group_notices.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_group_notify.xml b/indra/newview/skins/default/xui/tr/panel_group_notify.xml
index bcc5482daa..bcc5482daa 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_group_notify.xml
+++ b/indra/newview/skins/default/xui/tr/panel_group_notify.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_group_roles.xml b/indra/newview/skins/default/xui/tr/panel_group_roles.xml
index fb03107da8..fb03107da8 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_group_roles.xml
+++ b/indra/newview/skins/default/xui/tr/panel_group_roles.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_im_control_panel.xml b/indra/newview/skins/default/xui/tr/panel_im_control_panel.xml
index aebdc6b48d..aebdc6b48d 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_im_control_panel.xml
+++ b/indra/newview/skins/default/xui/tr/panel_im_control_panel.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_instant_message.xml b/indra/newview/skins/default/xui/tr/panel_instant_message.xml
index cf9bc7fccb..cf9bc7fccb 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_instant_message.xml
+++ b/indra/newview/skins/default/xui/tr/panel_instant_message.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_inventory_item.xml b/indra/newview/skins/default/xui/tr/panel_inventory_item.xml
index d18047fbcf..d18047fbcf 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_inventory_item.xml
+++ b/indra/newview/skins/default/xui/tr/panel_inventory_item.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_landmark_info.xml b/indra/newview/skins/default/xui/tr/panel_landmark_info.xml
index 2cad753f25..2cad753f25 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_landmark_info.xml
+++ b/indra/newview/skins/default/xui/tr/panel_landmark_info.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_landmarks.xml b/indra/newview/skins/default/xui/tr/panel_landmarks.xml
index d40d0c1543..d40d0c1543 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_landmarks.xml
+++ b/indra/newview/skins/default/xui/tr/panel_landmarks.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_login.xml b/indra/newview/skins/default/xui/tr/panel_login.xml
index acd6aa1921..28d316e46b 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_login.xml
+++ b/indra/newview/skins/default/xui/tr/panel_login.xml
@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel name="panel_login">
- <panel.string name="create_account_url">
- http://join.secondlife.com/
- </panel.string>
<panel.string name="forgot_password_url">
http://secondlife.com/account/request.php
</panel.string>
<layout_stack name="login_widgets">
<layout_panel name="login">
+ <text name="log_in_text">
+ OTURUM AÇ
+ </text>
<text name="username_text">
Kullanıcı Adı:
</text>
@@ -15,15 +15,8 @@
<text name="password_text">
Parola:
</text>
- <check_box label="Parolayı hatırla" name="remember_check"/>
- <button label="Oturum Aç" name="connect_btn"/>
- <text name="mode_selection_text">
- Mod:
- </text>
- <combo_box name="mode_combo" tool_tip="Modunuzu seçin. Hızlı, kolay keşif yapmak ve sohbet için Temel seçimini yapın. Daha fazla özelliğe erişmek için Gelişmiş seçimini yapın.">
- <combo_box.item label="Temel" name="Basic"/>
- <combo_box.item label="GeliÅŸmiÅŸ" name="Advanced"/>
- </combo_box>
+ </layout_panel>
+ <layout_panel name="start_location_panel">
<text name="start_location_text">
Buradan baÅŸla:
</text>
@@ -33,16 +26,21 @@
<combo_box.item label="&lt;Bölge adını girin&gt;" name="Typeregionname"/>
</combo_box>
</layout_panel>
- <layout_panel name="links">
- <text name="create_new_account_text">
- Kaydolun
+ <layout_panel name="links_login_panel">
+ <text name="login_help">
+ Oturum açarken yardım mı gerekiyor?
</text>
<text name="forgot_password_text">
Kullanıcı adınızı veya parolanızı mı unuttunuz?
</text>
- <text name="login_help">
- Oturum açarken yardım mı gerekiyor?
+ <button label="Oturum Aç" name="connect_btn"/>
+ <check_box label="Parolayı hatırla" name="remember_check"/>
+ </layout_panel>
+ <layout_panel name="links">
+ <text name="create_account_text">
+ HESABINIZI OLUÅžTURUN
</text>
+ <button label="Åžimdi baÅŸla" name="create_new_account_btn"/>
</layout_panel>
</layout_stack>
</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_main_inventory.xml b/indra/newview/skins/default/xui/tr/panel_main_inventory.xml
index c69fb39130..c69fb39130 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_main_inventory.xml
+++ b/indra/newview/skins/default/xui/tr/panel_main_inventory.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_me.xml b/indra/newview/skins/default/xui/tr/panel_me.xml
index 4b911c9ce6..4b911c9ce6 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_me.xml
+++ b/indra/newview/skins/default/xui/tr/panel_me.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_media_settings_general.xml b/indra/newview/skins/default/xui/tr/panel_media_settings_general.xml
index 89e78b75de..89e78b75de 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_media_settings_general.xml
+++ b/indra/newview/skins/default/xui/tr/panel_media_settings_general.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_media_settings_permissions.xml b/indra/newview/skins/default/xui/tr/panel_media_settings_permissions.xml
index 6c0b14a889..6c0b14a889 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_media_settings_permissions.xml
+++ b/indra/newview/skins/default/xui/tr/panel_media_settings_permissions.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_media_settings_security.xml b/indra/newview/skins/default/xui/tr/panel_media_settings_security.xml
index da3ca1bd29..da3ca1bd29 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_media_settings_security.xml
+++ b/indra/newview/skins/default/xui/tr/panel_media_settings_security.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_navigation_bar.xml b/indra/newview/skins/default/xui/tr/panel_navigation_bar.xml
index 8d43e3fb5a..8d43e3fb5a 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_navigation_bar.xml
+++ b/indra/newview/skins/default/xui/tr/panel_navigation_bar.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_nearby_chat.xml b/indra/newview/skins/default/xui/tr/panel_nearby_chat.xml
index d238388b0e..d238388b0e 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_nearby_chat.xml
+++ b/indra/newview/skins/default/xui/tr/panel_nearby_chat.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_nearby_chat_bar.xml b/indra/newview/skins/default/xui/tr/panel_nearby_chat_bar.xml
index fd954475ac..7d191191c4 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_nearby_chat_bar.xml
+++ b/indra/newview/skins/default/xui/tr/panel_nearby_chat_bar.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel name="chat_bar">
+<panel name="nearby_chat">
<line_editor label="Sohbet etmek için buraya tıklayın." name="chat_box" tool_tip="Söylemek için Enter, bağırmak için Ctrl+Enter yapın"/>
<button name="show_nearby_chat" tool_tip="yakın sohbet günlüğünü gösterir/gizler"/>
</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_nearby_media.xml b/indra/newview/skins/default/xui/tr/panel_nearby_media.xml
index a654b2ac14..a654b2ac14 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_nearby_media.xml
+++ b/indra/newview/skins/default/xui/tr/panel_nearby_media.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_notify_textbox.xml b/indra/newview/skins/default/xui/tr/panel_notify_textbox.xml
index b893da2a71..b893da2a71 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_notify_textbox.xml
+++ b/indra/newview/skins/default/xui/tr/panel_notify_textbox.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_online_status_toast.xml b/indra/newview/skins/default/xui/tr/panel_online_status_toast.xml
index fdc489f375..fdc489f375 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_online_status_toast.xml
+++ b/indra/newview/skins/default/xui/tr/panel_online_status_toast.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_outbox_inventory.xml b/indra/newview/skins/default/xui/tr/panel_outbox_inventory.xml
index a947eee150..a947eee150 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_outbox_inventory.xml
+++ b/indra/newview/skins/default/xui/tr/panel_outbox_inventory.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_outfit_edit.xml b/indra/newview/skins/default/xui/tr/panel_outfit_edit.xml
index 00cd49abcd..00cd49abcd 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_outfit_edit.xml
+++ b/indra/newview/skins/default/xui/tr/panel_outfit_edit.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_outfits_inventory.xml b/indra/newview/skins/default/xui/tr/panel_outfits_inventory.xml
index 550f7ebf10..550f7ebf10 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_outfits_inventory.xml
+++ b/indra/newview/skins/default/xui/tr/panel_outfits_inventory.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_outfits_inventory_gear_default.xml b/indra/newview/skins/default/xui/tr/panel_outfits_inventory_gear_default.xml
index d222f1a6e3..d222f1a6e3 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_outfits_inventory_gear_default.xml
+++ b/indra/newview/skins/default/xui/tr/panel_outfits_inventory_gear_default.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_outfits_list.xml b/indra/newview/skins/default/xui/tr/panel_outfits_list.xml
index 60a3576d84..60a3576d84 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_outfits_list.xml
+++ b/indra/newview/skins/default/xui/tr/panel_outfits_list.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_outfits_wearing.xml b/indra/newview/skins/default/xui/tr/panel_outfits_wearing.xml
index 462926738f..462926738f 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_outfits_wearing.xml
+++ b/indra/newview/skins/default/xui/tr/panel_outfits_wearing.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_people.xml b/indra/newview/skins/default/xui/tr/panel_people.xml
index 1a1e53bac2..b499ec8307 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_people.xml
+++ b/indra/newview/skins/default/xui/tr/panel_people.xml
@@ -14,81 +14,56 @@ Birlikte takılacak kişiler mi arıyorsunuz? [secondlife:///app/worldmap Dünya
<string name="no_filtered_friends_msg">
Aradığınızı bulamadınız mı? [secondlife:///app/search/people/[SEARCH_TERM] Ara] deneyin.
</string>
- <string name="people_filter_label" value="KiÅŸileri Filtrele"/>
- <string name="groups_filter_label" value="Grupları Filtrele"/>
<string name="no_filtered_groups_msg" value="Aradığınızı bulamadınız mı? [secondlife:///app/search/groups/[SEARCH_TERM] Ara] deneyin."/>
<string name="no_groups_msg" value="Katılacak Gruplar mı arıyorsunuz? [secondlife:///app/search/groups Ara] deneyin."/>
<string name="MiniMapToolTipMsg" value="[REGION](Haritayı açmak için çift tıkla, yatay hareket için shift çek)"/>
<string name="AltMiniMapToolTipMsg" value="[REGION](Işınlamak için çift tıkla, yatay hareket için shift çek)"/>
- <filter_editor label="Filtrele" name="filter_input"/>
<tab_container name="tabs">
<panel label="YAKIN" name="nearby_panel">
- <panel label="bottom_panel" name="bottom_panel">
- <menu_button name="nearby_view_sort_btn" tool_tip="Seçenklr."/>
- <button name="add_friend_btn" tool_tip="Seçilen Sakini arkadaş listene ekle"/>
+ <panel label="bottom_panel" name="nearby_buttons_panel">
+ <filter_editor label="KiÅŸileri Filtrele" name="nearby_filter_input"/>
+ <button name="gear_btn" tool_tip="Seçilen kişi üzerindeki eylemler"/>
+ <menu_button name="nearby_view_btn" tool_tip="Gösterme/sıralama seçenekleri"/>
+ <button name="add_friend_btn" tool_tip="Bir sakine arkadaşlık öner"/>
+ <dnd_button name="nearby_del_btn" tool_tip="Seçilen kişiyi arkadaş olarak kaldır"/>
</panel>
</panel>
- <panel label="ARKADAÅžLARIM" name="friends_panel">
+ <panel label="ARKADAÅžLAR" name="friends_panel">
+ <panel label="bottom_panel" name="friends_buttons_panel">
+ <filter_editor label="KiÅŸileri Filtrele" name="friends_filter_input"/>
+ <button name="gear_btn" tool_tip="Seçilen kişi üzerindeki eylemler"/>
+ <menu_button name="friends_view_btn" tool_tip="Seçenekleri göster/sırala"/>
+ <button name="friends_add_btn" tool_tip="Bir sakine arkadaşlık öner"/>
+ <dnd_button name="friends_del_btn" tool_tip="Seçilen kişiyi arkadaş olarak kaldır"/>
+ </panel>
<accordion name="friends_accordion">
<accordion_tab name="tab_online" title="Çevrimiçi"/>
<accordion_tab name="tab_all" title="Tümü"/>
</accordion>
- <panel label="bottom_panel" name="bottom_panel">
- <layout_stack name="bottom_panel">
- <layout_panel name="options_gear_btn_panel">
- <menu_button name="friends_viewsort_btn" tool_tip="İlave seçenekleri göster"/>
- </layout_panel>
- <layout_panel name="add_btn_panel">
- <button name="add_btn" tool_tip="Bir Sakine arkadaşlık öner"/>
- </layout_panel>
- <layout_panel name="trash_btn_panel">
- <dnd_button name="del_btn" tool_tip="Seçilen kişiyi arkadaş Listenden çıkar"/>
- </layout_panel>
- </layout_stack>
- </panel>
</panel>
- <panel label="GRUPLARIM" name="groups_panel">
- <panel label="bottom_panel" name="bottom_panel">
- <menu_button name="groups_viewsort_btn" tool_tip="Seçenklr."/>
- <button name="plus_btn" tool_tip="Gruba katıl/yeni grup oluştur"/>
- <button name="activate_btn" tool_tip="Seçilen grubu etkinleştir"/>
+ <panel label="GRUPLAR" name="groups_panel">
+ <panel label="bottom_panel" name="groups_buttons_panel">
+ <filter_editor label="Grupları Filtrele" name="groups_filter_input"/>
+ <menu_button name="groups_gear_btn" tool_tip="Seçilen grup üzerindeki eylemler"/>
+ <menu_button name="groups_view_btn" tool_tip="Seçenekleri göster/sırala"/>
+ <menu_button name="plus_btn" tool_tip="Gruba katıl/yeni grup oluştur"/>
+ <dnd_button name="minus_btn" tool_tip="Seçilen gruptan ayrıl"/>
</panel>
+ <text name="groupcount">
+ [COUNT] gruba üyesiniz, daha [REMAINING] gruba üye olabilirsiniz.
+ </text>
</panel>
<panel label="SON" name="recent_panel">
- <panel label="bottom_panel" name="bottom_panel">
- <menu_button name="recent_viewsort_btn" tool_tip="Seçenklr."/>
- <button name="add_friend_btn" tool_tip="Seçilen Sakini arkadaş listene ekle"/>
+ <panel label="bottom_panel" name="recent_buttons_panel">
+ <filter_editor label="KiÅŸileri Filtrele" name="recent_filter_input"/>
+ <button name="gear_btn" tool_tip="Seçilen kişi üzerindeki eylemler"/>
+ <menu_button name="recent_view_btn" tool_tip="Seçenekleri göster/sırala"/>
+ <button name="add_friend_btn" tool_tip="Bir sakine arkadaşlık öner"/>
+ <dnd_button name="recent_del_btn" tool_tip="Seçilen kişiyi arkadaş olarak kaldır"/>
</panel>
</panel>
+ <panel label="ENGELLENMÄ°Åž" name="blocked_panel">
+ <panel label="EngellenmiÅŸ Sakinler ve Nesneler" name="panel_block_list_sidetray"/>
+ </panel>
</tab_container>
- <panel name="button_bar">
- <layout_stack name="bottom_bar_ls">
- <layout_panel name="view_profile_btn_lp">
- <button label="Profil" name="view_profile_btn" tool_tip="Resim, grup ve diğer Sakin bilgilerini göster"/>
- </layout_panel>
- <layout_panel name="im_btn_lp">
- <button label="Aİ" name="im_btn" tool_tip="Anlık ileti oturumu aç"/>
- </layout_panel>
- <layout_panel name="call_btn_lp">
- <button label="Ara" name="call_btn" tool_tip="Bu Sakini ara"/>
- </layout_panel>
- <layout_panel name="share_btn_lp">
- <button label="Paylaş" name="share_btn" tool_tip="Bir envanter öğesini paylaş"/>
- </layout_panel>
- <layout_panel name="teleport_btn_lp">
- <button label="Işınla" name="teleport_btn" tool_tip="Işınlama teklif et"/>
- </layout_panel>
- </layout_stack>
- <layout_stack name="bottom_bar_ls1">
- <layout_panel name="group_info_btn_lp">
- <button label="Grup Profili" name="group_info_btn" tool_tip="Grup bilgilerini göster"/>
- </layout_panel>
- <layout_panel name="chat_btn_lp">
- <button label="Grup Sohbeti" name="chat_btn" tool_tip="Sohbet oturumu aç"/>
- </layout_panel>
- <layout_panel name="group_call_btn_lp">
- <button label="Grup Araması" name="group_call_btn" tool_tip="Bu grubu ara"/>
- </layout_panel>
- </layout_stack>
- </panel>
</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_pick_info.xml b/indra/newview/skins/default/xui/tr/panel_pick_info.xml
index f2bbfac232..f2bbfac232 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_pick_info.xml
+++ b/indra/newview/skins/default/xui/tr/panel_pick_info.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_picks.xml b/indra/newview/skins/default/xui/tr/panel_picks.xml
index 26beac7854..26beac7854 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_picks.xml
+++ b/indra/newview/skins/default/xui/tr/panel_picks.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_place_profile.xml b/indra/newview/skins/default/xui/tr/panel_place_profile.xml
index f42cde0ace..f42cde0ace 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_place_profile.xml
+++ b/indra/newview/skins/default/xui/tr/panel_place_profile.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_places.xml b/indra/newview/skins/default/xui/tr/panel_places.xml
index c2a3acf9c5..c2a3acf9c5 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_places.xml
+++ b/indra/newview/skins/default/xui/tr/panel_places.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_postcard_message.xml b/indra/newview/skins/default/xui/tr/panel_postcard_message.xml
index 2361f4c1c3..2361f4c1c3 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_postcard_message.xml
+++ b/indra/newview/skins/default/xui/tr/panel_postcard_message.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_postcard_settings.xml b/indra/newview/skins/default/xui/tr/panel_postcard_settings.xml
index bce0b21b9a..bce0b21b9a 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_postcard_settings.xml
+++ b/indra/newview/skins/default/xui/tr/panel_postcard_settings.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_preferences_advanced.xml b/indra/newview/skins/default/xui/tr/panel_preferences_advanced.xml
index 770cdc6efd..770cdc6efd 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_preferences_advanced.xml
+++ b/indra/newview/skins/default/xui/tr/panel_preferences_advanced.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_preferences_alerts.xml b/indra/newview/skins/default/xui/tr/panel_preferences_alerts.xml
index 46a4793c53..46a4793c53 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_preferences_alerts.xml
+++ b/indra/newview/skins/default/xui/tr/panel_preferences_alerts.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_preferences_chat.xml b/indra/newview/skins/default/xui/tr/panel_preferences_chat.xml
index 9caf95a122..d46f3e08cc 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/tr/panel_preferences_chat.xml
@@ -1,33 +1,99 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel label="Metin Sohbeti" name="chat">
- <text name="font_size">
- Font büyüklüğü:
- </text>
- <radio_group name="chat_font_size">
- <radio_item label="Küçük" name="radio" value="0"/>
- <radio_item label="Orta" name="radio2" value="1"/>
- <radio_item label="Büyük" name="radio3" value="2"/>
- </radio_group>
- <check_box initial_value="true" label="Sohbet sırasında yazma animasyonunu oynat" name="play_typing_animation"/>
- <check_box label="Çevrimdışı olduğunda Aİ&apos;ler e-posta ile bana gönderilsin" name="send_im_to_email"/>
- <check_box label="Düz metin Aİ&apos;ler ve sohbet geçmişini etkinleştir" name="plain_text_chat_history"/>
- <check_box label="Balon Sohbeti" name="bubble_text_chat"/>
- <text name="show_ims_in_label">
- Aİ&apos;leri şurada göster:
- </text>
- <text name="requires_restart_label">
- (tekrar baÅŸlatma gerekir)
- </text>
- <radio_group name="chat_window" tool_tip="Anlık İletileri ayrı gezdiricilerde veya çoklu sekmelere sahip tek bir gezdiricide gösterin (tekrar başlatma gerekir)">
- <radio_item label="Ayrı Pencereler" name="radio" value="0"/>
- <radio_item label="Sekmeler" name="radio2" value="1"/>
- </radio_group>
- <text name="disable_toast_label">
- Gelen sohbet için açılır pencereleri etkinleştir:
- </text>
- <check_box label="Grup Sohbetleri" name="EnableGroupChatPopups" tool_tip="Bir Grup Sohbet iletisi gönderildiğinde açılır pencereleri görmek için işaretle"/>
- <check_box label="Aİ Sohbetleri" name="EnableIMChatPopups" tool_tip="Bir anlık ileti geldiğinde açılır pencereleri görmek için işaretle"/>
- <spinner label="Yakındaki sohbet iletilerinin vurgulanma süresi:" name="nearby_toasts_lifetime"/>
- <spinner label="Yakındaki sohbet iletilerinin sönme süresi:" name="nearby_toasts_fadingtime"/>
- <button label="Sohbet Çevirisi Ayarları" name="ok_btn"/>
+ <panel name="general_chat_settings">
+ <check_box initial_value="true" label="Sohbet sırasında yazma animasyonunu oynat" name="play_typing_animation"/>
+ <check_box label="Çevrimdışı olduğunda Aİ&apos;ler e-posta ile bana gönderilsin" name="send_im_to_email"/>
+ <check_box label="Sadece arkadaşlar ve gruplar beni arasın veya Aİ göndersin" name="voice_call_friends_only_check"/>
+ <text name="font_size">
+ Font büyüklüğü:
+ </text>
+ <combo_box name="chat_font_size">
+ <item label="Küçük" name="Small" value="0"/>
+ <item label="Orta" name="Medium" value="1"/>
+ <item label="Büyük" name="Large" value="2"/>
+ </combo_box>
+ <check_box label="Balon Sohbeti" name="bubble_text_chat"/>
+ </panel>
+ <panel name="im_notification_settings">
+ <text name="friend_ims">
+ ArkadaÅŸ AÄ°&apos;leri:
+ </text>
+ <combo_box name="FriendIMOptions">
+ <item label="Sohbetler penceresini aç" name="OpenConversationsWindow" value="openconversations"/>
+ <item label="Mesajı açılır pencerede göster" name="PopUpMessage" value="toast"/>
+ <item label="Araç çubuğu düğmesi yanıp sönsün" name="FlashToolbarButton" value="flash"/>
+ <item label="Eylem yok" name="NoAction" value="noaction"/>
+ </combo_box>
+ <check_box label="Sesi çal" name="play_sound_friend_im"/>
+ <text name="non_friend_ims">
+ ArkadaÅŸ harici AÄ°&apos;ler:
+ </text>
+ <combo_box name="NonFriendIMOptions">
+ <item label="Sohbetler penceresini aç" name="OpenConversationsWindow" value="openconversations"/>
+ <item label="Mesajı açılır pencerede göster" name="PopUpMessage" value="toast"/>
+ <item label="Araç çubuğu düğmesi yanıp sönsün" name="FlashToolbarButton" value="flash"/>
+ <item label="Eylem yok" name="NoAction" value="noaction"/>
+ </combo_box>
+ <check_box label="Sesi çal" name="play_sound_non_friend_im"/>
+ <text name="conference_ims">
+ Konferans AÄ°&apos;leri:
+ </text>
+ <combo_box name="ConferenceIMOptions">
+ <item label="Sohbetler penceresini aç" name="OpenConversationsWindow" value="openconversations"/>
+ <item label="Mesajı açılır pencerede göster" name="PopUpMessage" value="toast"/>
+ <item label="Araç çubuğu düğmesi yanıp sönsün" name="FlashToolbarButton" value="flash"/>
+ <item label="Eylem yok" name="NoAction" value="noaction"/>
+ </combo_box>
+ <check_box label="Sesi çal" name="play_sound_conference_im"/>
+ <text name="group_chat">
+ Grup sohbeti:
+ </text>
+ <combo_box name="GroupChatOptions">
+ <item label="Sohbetler penceresini aç" name="OpenConversationsWindow" value="openconversations"/>
+ <item label="Mesajı açılır pencerede göster" name="PopUpMessage" value="toast"/>
+ <item label="Araç çubuğu düğmesi yanıp sönsün" name="FlashToolbarButton" value="flash"/>
+ <item label="Eylem yok" name="NoAction" value="noaction"/>
+ </combo_box>
+ <check_box label="Sesi çal" name="play_sound_group_chat_im"/>
+ <text name="nearby_chat">
+ Yakındaki sohbet:
+ </text>
+ <combo_box name="NearbyChatOptions">
+ <item label="Sohbetler penceresini aç" name="OpenConversationsWindow" value="openconversations"/>
+ <item label="Mesajı açılır pencerede göster" name="PopUpMessage" value="toast"/>
+ <item label="Araç çubuğu düğmesi yanıp sönsün" name="FlashToolBarButton" value="flash"/>
+ <item label="Eylem yok" name="NoAction" value="noaction"/>
+ </combo_box>
+ <check_box label="Sesi çal" name="play_sound_nearby_chat_im"/>
+ <text name="object_ims">
+ Nesne AÄ°&apos;leri:
+ </text>
+ <combo_box name="ObjectIMOptions">
+ <item label="Sohbetler penceresini aç" name="OpenConversationsWindow" value="openconversations"/>
+ <item label="Mesajı açılır pencerede göster" name="PopUpMessage" value="toast"/>
+ <item label="Araç çubuğu düğmesi yanıp sönsün" name="FlashToolBarButton" value="flash"/>
+ <item label="Eylem yok" name="NoAction" value="noaction"/>
+ </combo_box>
+ <check_box label="Sesi çal" name="play_sound_object_im"/>
+ <text name="notifications_alert">
+ Tüm bildirimleri geçici olarak durdurmak için İletişim Kur &gt; Rahatsız Etme seçeneğini kullanın.
+ </text>
+ </panel>
+ <panel name="play_sound_settings">
+ <text name="play_sound">
+ Sesi çal:
+ </text>
+ <check_box label="Yeni sohbet" name="new_conversation"/>
+ <check_box label="Gelen sesli arama" name="incoming_voice_call"/>
+ <check_box label="Işınlama teklifi" name="teleport_offer"/>
+ <check_box label="Envanter teklifi" name="inventory_offer"/>
+ </panel>
+ <panel name="log_settings">
+ <button label="Günlüğü temizle..." name="clear_log"/>
+ <button label="Dökümleri sil..." name="delete_transcripts"/>
+ <button label="Gözat..." label_selected="Gözat" name="log_path_button"/>
+ </panel>
+ <button label="Çeviri..." name="ok_btn"/>
+ <button label="Otomatik Yerine Koy..." name="autoreplace_showgui"/>
+ <button label="Yazım Denetimi Yapılıyor..." name="spellcheck_showgui"/>
</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_preferences_colors.xml b/indra/newview/skins/default/xui/tr/panel_preferences_colors.xml
index f6e9d0948c..f6e9d0948c 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_preferences_colors.xml
+++ b/indra/newview/skins/default/xui/tr/panel_preferences_colors.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_preferences_general.xml b/indra/newview/skins/default/xui/tr/panel_preferences_general.xml
index 4a48b1588c..1a13cf8f71 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_preferences_general.xml
+++ b/indra/newview/skins/default/xui/tr/panel_preferences_general.xml
@@ -68,9 +68,9 @@
<combo_box.item label="asla" name="item4"/>
</combo_box>
<text name="text_box3">
- Meşgul durumu cevabı:
+ Rahatsız Etme yanıtı:
</text>
- <text_editor name="busy_response">
+ <text_editor name="do_not_disturb_response">
log_in_to_change
</text_editor>
</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/tr/panel_preferences_graphics1.xml
index ddb83ffc69..25c9e966c7 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_preferences_graphics1.xml
+++ b/indra/newview/skins/default/xui/tr/panel_preferences_graphics1.xml
@@ -30,7 +30,7 @@
<check_box initial_value="true" label="Yerel Işıklar" name="LocalLights"/>
<check_box initial_value="true" label="Temel gölgeleyiciler" name="BasicShaders" tool_tip="Bu seçeneğin devre dışı bırakılması bazı grafik kartlarının sürücülerinin kilitlenmesini önleyebilir"/>
<check_box initial_value="true" label="Atmosferik gölgeleyiciler" name="WindLightUseAtmosShaders"/>
- <check_box initial_value="true" label="Işıklandırma ve Gölgeler" name="UseLightShaders"/>
+ <check_box initial_value="true" label="Gelişmiş Aydınlatma Modeli" name="UseLightShaders"/>
<check_box initial_value="true" label="Ortam Gölgeleme" name="UseSSAO"/>
<check_box initial_value="true" label="Alan DerinliÄŸi" name="UseDoF"/>
<text name="shadows_label">
diff --git a/indra/newview/skins/default/xui/tr/panel_preferences_move.xml b/indra/newview/skins/default/xui/tr/panel_preferences_move.xml
index c35eaec9c3..c35eaec9c3 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_preferences_move.xml
+++ b/indra/newview/skins/default/xui/tr/panel_preferences_move.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_preferences_privacy.xml b/indra/newview/skins/default/xui/tr/panel_preferences_privacy.xml
index 9111594979..9111594979 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_preferences_privacy.xml
+++ b/indra/newview/skins/default/xui/tr/panel_preferences_privacy.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_preferences_setup.xml b/indra/newview/skins/default/xui/tr/panel_preferences_setup.xml
index 9d03d9b01d..2039761748 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_preferences_setup.xml
+++ b/indra/newview/skins/default/xui/tr/panel_preferences_setup.xml
@@ -29,6 +29,7 @@
<combo_box.item label="Otomatik olarak kurulsun" name="Install_automatically"/>
<combo_box.item label="Güncelleştirmeler manuel olarak karşıdan yüklensin ve kurulsun" name="Install_manual"/>
</combo_box>
+ <check_box label="Sürüm adaylarına güncelleme yapmaya gönüllü" name="update_willing_to_test"/>
<text name="Proxy Settings:">
Proxy Ayarları:
</text>
diff --git a/indra/newview/skins/default/xui/tr/panel_preferences_sound.xml b/indra/newview/skins/default/xui/tr/panel_preferences_sound.xml
index 9256f1d324..9256f1d324 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_preferences_sound.xml
+++ b/indra/newview/skins/default/xui/tr/panel_preferences_sound.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_prim_media_controls.xml b/indra/newview/skins/default/xui/tr/panel_prim_media_controls.xml
index 0433d03450..0433d03450 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_prim_media_controls.xml
+++ b/indra/newview/skins/default/xui/tr/panel_prim_media_controls.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_region_covenant.xml b/indra/newview/skins/default/xui/tr/panel_region_covenant.xml
index 5c46365aea..5c46365aea 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_region_covenant.xml
+++ b/indra/newview/skins/default/xui/tr/panel_region_covenant.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_region_debug.xml b/indra/newview/skins/default/xui/tr/panel_region_debug.xml
index 6e15e0f6f6..834ece563f 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_region_debug.xml
+++ b/indra/newview/skins/default/xui/tr/panel_region_debug.xml
@@ -30,5 +30,5 @@
<button label="En Çok Çarpışanlar..." name="top_colliders_btn" tool_tip="En çok potansiyel çarpışma yaşayan nesnelerin listesi"/>
<button label="En Çok Komut Dsy. Çalştr...." name="top_scripts_btn" tool_tip="Komut dosyalarını çalıştırırken en çok zaman harcayan nesnelerin listesi"/>
<button label="Bölgeyi Yeniden Başlat" name="restart_btn" tool_tip="2 dakikalık bir geri sayımdan sonra bölgeyi yeniden başlat"/>
- <button label="Yeniden Başlatmayı Ertele" name="cancel_restart_btn" tool_tip="Bölgenin yeniden başlatılmasını 1 saat ertele"/>
+ <button label="Yeniden Başlatmayı İptal Et" name="cancel_restart_btn" tool_tip="Bölge yeniden başlatmasını iptal et"/>
</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_region_environment.xml b/indra/newview/skins/default/xui/tr/panel_region_environment.xml
index 058ea91b70..058ea91b70 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_region_environment.xml
+++ b/indra/newview/skins/default/xui/tr/panel_region_environment.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_region_estate.xml b/indra/newview/skins/default/xui/tr/panel_region_estate.xml
index f1df13df61..4a9028643f 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_region_estate.xml
+++ b/indra/newview/skins/default/xui/tr/panel_region_estate.xml
@@ -23,7 +23,7 @@
Sadece ÅŸu Sakinlere eriÅŸim izni verin:
</text>
<check_box label="Ödeme bilgileri kayıtlı" name="limit_payment" tool_tip="Sakinlerin bu gayrimenkule erişebilmesi için ödeme bilgilerinin kayıtlı olması gerekir. Daha fazla bilgi için [SUPPORT_SITE] adresini ziyaret edin."/>
- <check_box label="Yaş doğrulaması yapılmış" name="limit_age_verified" tool_tip="Sakinlerin bu gayrimenkule erişebilmesi için yaş doğrulamalarının yapılmış olması gerekir. Daha fazla bilgi için [SUPPORT_SITE] adresini ziyaret edin."/>
+ <check_box label="18 veya üzeri bir yaşta" name="limit_age_verified" tool_tip="Sakinlerin bu gayrimenkule erişebilmesi için 18 veya üzeri bir yaşta olmaları gerekir. Daha fazla bilgi için [SUPPORT_SITE] adresini ziyaret edin."/>
<check_box label="Sesli Sohbete Ä°zin Ver" name="voice_chat_check"/>
<check_box label="Doğrudan Işınlamaya İzin Ver" name="allow_direct_teleport"/>
<button label="Uygula" name="apply_btn"/>
diff --git a/indra/newview/skins/default/xui/tr/panel_region_general.xml b/indra/newview/skins/default/xui/tr/panel_region_general.xml
index 37da0f2cca..37da0f2cca 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_region_general.xml
+++ b/indra/newview/skins/default/xui/tr/panel_region_general.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_region_terrain.xml b/indra/newview/skins/default/xui/tr/panel_region_terrain.xml
index 3226ee008e..3226ee008e 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_region_terrain.xml
+++ b/indra/newview/skins/default/xui/tr/panel_region_terrain.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_region_texture.xml b/indra/newview/skins/default/xui/tr/panel_region_texture.xml
deleted file mode 100644
index fd7ca2a893..0000000000
--- a/indra/newview/skins/default/xui/tr/panel_region_texture.xml
+++ /dev/null
@@ -1,54 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel label="Zemin Dokuları" name="Textures">
- <text name="region_text_lbl">
- Bölge:
- </text>
- <text name="region_text">
- bilinmiyor
- </text>
- <text name="detail_texture_text">
- Yüzey Dokuları (512x512, 24 bit .tga dosyalar gerektirir)
- </text>
- <text name="height_text_lbl">
- 1 (Düşük)
- </text>
- <text name="height_text_lbl2">
- 2
- </text>
- <text name="height_text_lbl3">
- 3
- </text>
- <text name="height_text_lbl4">
- 4 (Yüksek)
- </text>
- <text name="height_text_lbl5">
- Doku Yükselti Aralıkları
- </text>
- <text name="height_text_lbl6">
- Kuzeybatı
- </text>
- <text name="height_text_lbl7">
- KuzeydoÄŸu
- </text>
- <spinner label="Düşük" name="height_start_spin_1"/>
- <spinner label="Düşük" name="height_start_spin_3"/>
- <spinner label="Yüksek" name="height_range_spin_1"/>
- <spinner label="Yüksek" name="height_range_spin_3"/>
- <text name="height_text_lbl8">
- Güneybatı
- </text>
- <text name="height_text_lbl9">
- Güneydoğu
- </text>
- <spinner label="Düşük" name="height_start_spin_0"/>
- <spinner label="Düşük" name="height_start_spin_2"/>
- <spinner label="Yüksek" name="height_range_spin_0"/>
- <spinner label="Yüksek" name="height_range_spin_2"/>
- <text name="height_text_lbl10">
- Bu değerler yukarıdaki dokular için karışım aralığını temsil eder.
- </text>
- <text name="height_text_lbl11">
- Metre cinsinden olan bu değerler için, DÜŞÜK değer 1. Dokunun MAKSİMUM yüksekliği, YÜKSEK değer ise 4. Dokunun MİNİMUM yüksekliğidir.
- </text>
- <button label="Uygula" name="apply_btn"/>
-</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_script_ed.xml b/indra/newview/skins/default/xui/tr/panel_script_ed.xml
index 7aa1da6fb2..79cd86c3f0 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_script_ed.xml
+++ b/indra/newview/skins/default/xui/tr/panel_script_ed.xml
@@ -34,6 +34,7 @@
<menu_item_call label="Tümünü Seç" name="Select All"/>
<menu_item_call label="Seçimi Kaldır" name="Deselect"/>
<menu_item_call label="Ara / DeÄŸiÅŸtir..." name="Search / Replace..."/>
+ <menu_item_call label="Şu satıra git:" name="Go to line..."/>
</menu>
<menu label="Yardım" name="Help">
<menu_item_call label="Yardım..." name="Help..."/>
diff --git a/indra/newview/skins/default/xui/tr/panel_script_limits_my_avatar.xml b/indra/newview/skins/default/xui/tr/panel_script_limits_my_avatar.xml
index c821dc45c1..c821dc45c1 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_script_limits_my_avatar.xml
+++ b/indra/newview/skins/default/xui/tr/panel_script_limits_my_avatar.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_script_limits_region_memory.xml b/indra/newview/skins/default/xui/tr/panel_script_limits_region_memory.xml
index 2994aba39b..2994aba39b 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_script_limits_region_memory.xml
+++ b/indra/newview/skins/default/xui/tr/panel_script_limits_region_memory.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_script_question_toast.xml b/indra/newview/skins/default/xui/tr/panel_script_question_toast.xml
new file mode 100755
index 0000000000..a2d0237da0
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/panel_script_question_toast.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<panel label="script_question_panel" name="panel_script_question_toast">
+ <panel label="buttons_panel" name="buttons_panel"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_scrolling_param.xml b/indra/newview/skins/default/xui/tr/panel_scrolling_param.xml
index aabdc7358b..aabdc7358b 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_scrolling_param.xml
+++ b/indra/newview/skins/default/xui/tr/panel_scrolling_param.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_scrolling_param_base.xml b/indra/newview/skins/default/xui/tr/panel_scrolling_param_base.xml
index fa659040ea..fa659040ea 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_scrolling_param_base.xml
+++ b/indra/newview/skins/default/xui/tr/panel_scrolling_param_base.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_side_tray.xml b/indra/newview/skins/default/xui/tr/panel_side_tray.xml
deleted file mode 100644
index 97bca38a50..0000000000
--- a/indra/newview/skins/default/xui/tr/panel_side_tray.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<!-- Side tray cannot show background because it is always
- partially on screen to hold tab buttons. -->
-<side_tray name="sidebar">
- <sidetray_tab description="Yan Çubuğu Aç/Kapa." name="sidebar_openclose" tab_title="Yan Çubuğu Aç/Kapa"/>
- <sidetray_tab description="Ana konum." name="sidebar_home" tab_title="Ana konum">
- <panel label="ana konum" name="panel_home"/>
- </sidetray_tab>
- <sidetray_tab description="Kamuya açık profilinizi ve Favorilerinizi düzenleyin." name="sidebar_me" tab_title="Profilim">
- <panel_container name="panel_container">
- <panel label="Ben" name="panel_me"/>
- </panel_container>
- </sidetray_tab>
- <sidetray_tab description="Yakındaki arkadaşlarınızı, irtibatları ve kişileri bulun." name="sidebar_people" tab_title="Kişiler">
- <panel_container name="panel_container">
- <panel label="Grup Profili" name="panel_group_info_sidetray"/>
- <panel label="EngellenmiÅŸ Sakinler ve Nesneler" name="panel_block_list_sidetray"/>
- </panel_container>
- </sidetray_tab>
- <sidetray_tab description="Gitmek istediğiniz yerleri ve daha önce uğradığınız yerleri bulun." label="Yerler" name="sidebar_places" tab_title="Yerler">
- <panel label="Yerler" name="panel_places"/>
- </sidetray_tab>
- <sidetray_tab description="Envanterinize göz atın." name="sidebar_inventory" tab_title="Envanterim">
- <panel label="Envanteri Düzenle" name="sidepanel_inventory"/>
- </sidetray_tab>
- <sidetray_tab description="Görünümünüzü değiştirin." name="sidebar_appearance" tab_title="Görünümüm">
- <panel label="Görünümü Düzenle" name="sidepanel_appearance"/>
- </sidetray_tab>
-</side_tray>
diff --git a/indra/newview/skins/default/xui/tr/panel_side_tray_tab_caption.xml b/indra/newview/skins/default/xui/tr/panel_side_tray_tab_caption.xml
index b9c39ef8cb..b9c39ef8cb 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_side_tray_tab_caption.xml
+++ b/indra/newview/skins/default/xui/tr/panel_side_tray_tab_caption.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_snapshot_inventory.xml b/indra/newview/skins/default/xui/tr/panel_snapshot_inventory.xml
index e3b22c639a..e3b22c639a 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_snapshot_inventory.xml
+++ b/indra/newview/skins/default/xui/tr/panel_snapshot_inventory.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_snapshot_local.xml b/indra/newview/skins/default/xui/tr/panel_snapshot_local.xml
index 87d7677d73..87d7677d73 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_snapshot_local.xml
+++ b/indra/newview/skins/default/xui/tr/panel_snapshot_local.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_snapshot_options.xml b/indra/newview/skins/default/xui/tr/panel_snapshot_options.xml
index fd2e85fce5..fd2e85fce5 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_snapshot_options.xml
+++ b/indra/newview/skins/default/xui/tr/panel_snapshot_options.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_snapshot_postcard.xml b/indra/newview/skins/default/xui/tr/panel_snapshot_postcard.xml
index e999678a0d..e999678a0d 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_snapshot_postcard.xml
+++ b/indra/newview/skins/default/xui/tr/panel_snapshot_postcard.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_snapshot_profile.xml b/indra/newview/skins/default/xui/tr/panel_snapshot_profile.xml
index 334fd52a48..334fd52a48 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_snapshot_profile.xml
+++ b/indra/newview/skins/default/xui/tr/panel_snapshot_profile.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_sound_devices.xml b/indra/newview/skins/default/xui/tr/panel_sound_devices.xml
index 982ef2ea3b..982ef2ea3b 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_sound_devices.xml
+++ b/indra/newview/skins/default/xui/tr/panel_sound_devices.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_stand_stop_flying.xml b/indra/newview/skins/default/xui/tr/panel_stand_stop_flying.xml
index 91d07a3b0c..91d07a3b0c 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_stand_stop_flying.xml
+++ b/indra/newview/skins/default/xui/tr/panel_stand_stop_flying.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_status_bar.xml b/indra/newview/skins/default/xui/tr/panel_status_bar.xml
index 178cbda4a2..178cbda4a2 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_status_bar.xml
+++ b/indra/newview/skins/default/xui/tr/panel_status_bar.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_teleport_history.xml b/indra/newview/skins/default/xui/tr/panel_teleport_history.xml
index f5b1175029..f5b1175029 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_teleport_history.xml
+++ b/indra/newview/skins/default/xui/tr/panel_teleport_history.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_teleport_history_item.xml b/indra/newview/skins/default/xui/tr/panel_teleport_history_item.xml
index a3a5c70c7e..a3a5c70c7e 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_teleport_history_item.xml
+++ b/indra/newview/skins/default/xui/tr/panel_teleport_history_item.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_tools_texture.xml b/indra/newview/skins/default/xui/tr/panel_tools_texture.xml
new file mode 100644
index 0000000000..2ce7c9c11f
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/panel_tools_texture.xml
@@ -0,0 +1,116 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Doku" name="Texture">
+ <panel.string name="string repeats per meter">
+ Metrede Kaç Kez Tekrarlandığı
+ </panel.string>
+ <panel.string name="string repeats per face">
+ Bir Yüzde Kaç Kez Tekrarlandığı
+ </panel.string>
+ <text name="color label">
+ Renk
+ </text>
+ <color_swatch label="" name="colorswatch" tool_tip="Renk seçiciyi açmak için tıklayın"/>
+ <text name="color trans">
+ Saydamlık %
+ </text>
+ <text name="glow label">
+ Parıltı
+ </text>
+ <check_box label="Tam Parlak" name="checkbox fullbright"/>
+ <combo_box name="combobox matmedia">
+ <combo_box.item label="Malzemeler" name="Materials"/>
+ <combo_box.item label="Ortam" name="Media"/>
+ </combo_box>
+ <combo_box name="combobox mattype">
+ <combo_box.item label="Doku (yayılmış)" name="Texture (diffuse)"/>
+ <combo_box.item label="Yumruluk (normal)" name="Bumpiness (normal)"/>
+ <combo_box.item label="Parıldama (yansıtan)" name="Shininess (specular)"/>
+ </combo_box>
+ <texture_picker label="Doku" name="texture control" tool_tip="Bir resim seçmek için tıklayın"/>
+ <text name="label alphamode">
+ Alfa modu
+ </text>
+ <combo_box name="combobox alphamode">
+ <combo_box.item label="Hiçbiri" name="None"/>
+ <combo_box.item label="Alfa karıştırma" name="Alpha blending"/>
+ <combo_box.item label="Alfa maskeleme" name="Alpha masking"/>
+ <combo_box.item label="Yayımlatıcı maske" name="Emissive mask"/>
+ </combo_box>
+ <text name="label maskcutoff">
+ Maske kesimi
+ </text>
+ <texture_picker label="Doku" name="bumpytexture control" tool_tip="Bir resim seçmek için tıklayın"/>
+ <text name="label bumpiness">
+ Yumruluk
+ </text>
+ <combo_box name="combobox bumpiness">
+ <combo_box.item label="Yok" name="None"/>
+ <combo_box.item label="Parlaklık" name="Brightness"/>
+ <combo_box.item label="Koyuluk" name="Darkness"/>
+ <combo_box.item label="damarlı ahşap" name="woodgrain"/>
+ <combo_box.item label="ağaç kabuğu" name="bark"/>
+ <combo_box.item label="tuÄŸlalar" name="bricks"/>
+ <combo_box.item label="dama tahtası" name="checker"/>
+ <combo_box.item label="beton" name="concrete"/>
+ <combo_box.item label="sert çini" name="crustytile"/>
+ <combo_box.item label="kesilmiÅŸ taÅŸ" name="cutstone"/>
+ <combo_box.item label="diskler" name="discs"/>
+ <combo_box.item label="çakıl" name="gravel"/>
+ <combo_box.item label="petri kabı" name="petridish"/>
+ <combo_box.item label="dış kaplama" name="siding"/>
+ <combo_box.item label="taş çini" name="stonetile"/>
+ <combo_box.item label="stükko" name="stucco"/>
+ <combo_box.item label="vakum" name="suction"/>
+ <combo_box.item label="örgü" name="weave"/>
+ </combo_box>
+ <texture_picker label="Doku" name="shinytexture control" tool_tip="Bir resim seçmek için tıklayın"/>
+ <text name="label shininess">
+ Parıldama
+ </text>
+ <combo_box name="combobox shininess">
+ <combo_box.item label="Yok" name="None"/>
+ <combo_box.item label="Düşük" name="Low"/>
+ <combo_box.item label="Orta" name="Medium"/>
+ <combo_box.item label="Yüksek" name="High"/>
+ </combo_box>
+ <text name="label glossiness">
+ Pürüzsüzlük
+ </text>
+ <text name="label environment">
+ Ortam
+ </text>
+ <text name="label shinycolor">
+ Renk
+ </text>
+ <color_swatch label="" name="shinycolorswatch" tool_tip="Renk seçiciyi açmak için tıklayın"/>
+ <text name="media_info">
+ Varsa, seçilen ortamın URL&apos;si burada yer alır
+ </text>
+ <button label="Seç..." name="add_media" tool_tip="Ortam Ekle"/>
+ <button label="Kaldır" name="delete_media" tool_tip="Bu ortam dokusunu sil"/>
+ <button label="Hizala" label_selected="Ortamı Hizala" name="button align" tool_tip="Ortam dokusunu hizala (önce yüklenmelidir)"/>
+ <text name="tex gen">
+ EÅŸleÅŸtirme
+ </text>
+ <combo_box name="combobox texgen">
+ <combo_box.item label="Varsayılan" name="Default"/>
+ <combo_box.item label="Planar" name="Planar"/>
+ </combo_box>
+ <spinner label="Yatay ölçek" name="TexScaleU"/>
+ <spinner label="Dikey ölçek" name="TexScaleV"/>
+ <spinner label="Metrede kaç kez tekrarlandığı" name="rptctrl"/>
+ <spinner label="Dönüş derecesi" name="TexRot"/>
+ <spinner label="Yatay ofset" name="TexOffsetU"/>
+ <spinner label="Dikey ofset" name="TexOffsetV"/>
+ <spinner label="Yatay ölçek" name="bumpyScaleU"/>
+ <spinner label="Dikey ölçek" name="bumpyScaleV"/>
+ <spinner label="Dönüş derecesi" name="bumpyRot"/>
+ <spinner label="Yatay ofset" name="bumpyOffsetU"/>
+ <spinner label="Dikey ofset" name="bumpyOffsetV"/>
+ <spinner label="Yatay ölçek" name="shinyScaleU"/>
+ <spinner label="Dikey ölçek" name="shinyScaleV"/>
+ <spinner label="Dönüş derecesi" name="shinyRot"/>
+ <spinner label="Yatay ofset" name="shinyOffsetU"/>
+ <spinner label="Dikey ofset" name="shinyOffsetV"/>
+ <check_box initial_value="false" label="Planar yüzleri hizala" name="checkbox planar align" tool_tip="Tüm seçili yüzeylerdeki dokuları son seçili yüzdekiyle hizalar. Planar doku eşleştirmesi gerektirir."/>
+</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_voice_effect.xml b/indra/newview/skins/default/xui/tr/panel_voice_effect.xml
index b46833d7e6..b46833d7e6 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_voice_effect.xml
+++ b/indra/newview/skins/default/xui/tr/panel_voice_effect.xml
diff --git a/indra/newview/skins/default/xui/tr/panel_volume_pulldown.xml b/indra/newview/skins/default/xui/tr/panel_volume_pulldown.xml
new file mode 100755
index 0000000000..0c8c7b68b5
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/panel_volume_pulldown.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="volumepulldown_floater">
+ <slider label="Ana" name="System Volume"/>
+ <slider label="Düğmeler" name="UI Volume"/>
+ <slider label="Ortam" name="Wind Volume"/>
+ <slider label="Sesler" name="SFX Volume"/>
+ <check_box name="gesture_audio_play_btn" tool_tip="Mimiklerdeki sesleri etkinleÅŸtir"/>
+ <slider label="Müzik" name="Music Volume"/>
+ <check_box name="enable_music" tool_tip="Müzik Akışını Etkinleştir"/>
+ <slider label="Ortam" name="Media Volume"/>
+ <check_box name="enable_media" tool_tip="Akış Ortamını Etkinleştir"/>
+ <slider label="Ses" name="Voice Volume"/>
+ <check_box name="enable_voice_check" tool_tip="Sesli Sohbeti EtkinleÅŸtir"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_world_map.xml b/indra/newview/skins/default/xui/tr/panel_world_map.xml
index 5595c13a7c..5595c13a7c 100644..100755
--- a/indra/newview/skins/default/xui/tr/panel_world_map.xml
+++ b/indra/newview/skins/default/xui/tr/panel_world_map.xml
diff --git a/indra/newview/skins/default/xui/tr/role_actions.xml b/indra/newview/skins/default/xui/tr/role_actions.xml
index 655ac64172..76ca58c319 100644..100755
--- a/indra/newview/skins/default/xui/tr/role_actions.xml
+++ b/indra/newview/skins/default/xui/tr/role_actions.xml
@@ -25,7 +25,7 @@
</action_set>
<action_set description="Bu yetenekler arasında parsel adını ve yayınlama ayarlarını, Bul dizinindeki görünürlük ile iniş noktası ve TP yönlendirme seçeneklerini değiştirme imkanları yer alır." name="Parcel Identity">
<action description="&apos;Konumu Arama Sonuçlarında Göster&apos; seçeneğini Aç/Kapa ve kategoriyi ayarla" longdescription="Arazi Hakkında &gt; Seçenekler sekmesinden &apos;Konumu Arama Sonuçlarında Göster&apos; seçeneğini Açın/Kapayın ve parsel kategorisini ayarlayın." name="land find places" value="17"/>
- <action description="Parsel adını, açıklamasını ve &quot;Konumu Arama Sonuçlarında Göster&quot; ayarlarını değiştir" longdescription="Parsel adını, açıklamasını ve &quot;Konumu Arama Sonuçlarında Göster&quot; ayarlarını değiştirin. Bu işlem Arazi Hakkında &gt; Seçenekler sekmesinde yapılır." name="land change identity" value="18"/>
+ <action description="Parsel adını, açıklamasını ve &quot;Orta Seviyede İçerik&quot; ayarlarını değiştir" longdescription="Parsel adını, açıklamasını ve &quot;Orta Seviyede İçerik&quot; ayarlarını değiştir. Bu işlem Arazi Hakkında &gt; Seçenekler sekmesinde yapılır." name="land change identity" value="18"/>
<action description="İniş noktasını ve ışınlama yönlendirmesini ayarlayın" longdescription="Bir grubun sahip olduğu parsel üzerinde, bu Yeteneğe sahip olan bir Roldeki Üyeler gelen ışınlanmaların varacağı iniş noktasını ve daha fazla kontrol için ışınlama yönlendirmesini ayarlayabilirler. Bu işlem Arazi Hakkında &gt; Seçenekler sekmesinde yapılır." name="land set landing point" value="19"/>
</action_set>
<action_set description="Bu Yeteneklere &apos;Nesneleri Oluştur&apos;, &apos;Yüzeyi Düzenle&apos;, müzik ve ortam ayarları gibi parsel seçeneklerini etkileyen güçler de dahildir." name="Parcel Settings">
diff --git a/indra/newview/skins/default/xui/tr/sidepanel_appearance.xml b/indra/newview/skins/default/xui/tr/sidepanel_appearance.xml
index b632f21cf5..b632f21cf5 100644..100755
--- a/indra/newview/skins/default/xui/tr/sidepanel_appearance.xml
+++ b/indra/newview/skins/default/xui/tr/sidepanel_appearance.xml
diff --git a/indra/newview/skins/default/xui/tr/sidepanel_inventory.xml b/indra/newview/skins/default/xui/tr/sidepanel_inventory.xml
index 938b5a76d8..938b5a76d8 100644..100755
--- a/indra/newview/skins/default/xui/tr/sidepanel_inventory.xml
+++ b/indra/newview/skins/default/xui/tr/sidepanel_inventory.xml
diff --git a/indra/newview/skins/default/xui/tr/sidepanel_item_info.xml b/indra/newview/skins/default/xui/tr/sidepanel_item_info.xml
index 81291a431c..86b684c497 100644..100755
--- a/indra/newview/skins/default/xui/tr/sidepanel_item_info.xml
+++ b/indra/newview/skins/default/xui/tr/sidepanel_item_info.xml
@@ -3,6 +3,9 @@
<panel.string name="unknown">
(bilinmiyor)
</panel.string>
+ <panel.string name="unknown_multiple">
+ (bilinmiyor veya birden çok değer)
+ </panel.string>
<panel.string name="public">
(kamuya açık)
</panel.string>
diff --git a/indra/newview/skins/default/xui/tr/sidepanel_task_info.xml b/indra/newview/skins/default/xui/tr/sidepanel_task_info.xml
index 2fa6281f05..9a4cf54fa7 100644..100755
--- a/indra/newview/skins/default/xui/tr/sidepanel_task_info.xml
+++ b/indra/newview/skins/default/xui/tr/sidepanel_task_info.xml
@@ -18,6 +18,12 @@
<panel.string name="text modify info 4">
Bu nesneleri deÄŸiÅŸtiremezsiniz
</panel.string>
+ <panel.string name="text modify info 5">
+ Bir bölge sınırı üzerinden bu nesneyi değiştiremezsiniz
+ </panel.string>
+ <panel.string name="text modify info 6">
+ Bir bölge sınırı üzerinden bu nesneleri değiştiremezsiniz
+ </panel.string>
<panel.string name="text modify warning">
Bu nesne bağlantılı parçalara sahip
</panel.string>
@@ -66,6 +72,7 @@
<combo_box.item label="Nesneyi satın al" name="Buyobject"/>
<combo_box.item label="Nesneye ödeme yap" name="Payobject"/>
<combo_box.item label="Aç" name="Open"/>
+ <combo_box.item label="Yakınlaştır" name="Zoom"/>
</combo_box>
<panel name="perms_inv">
<text name="perm_modify">
@@ -95,6 +102,9 @@
</combo_box>
<spinner label="Fiyat: L$" name="Edit Cost"/>
<check_box label="Aramada göster" name="search_check" tool_tip="Kişiler arama sonuçlarında bu nesneyi görebilsin"/>
+ <text name="pathfinding_attributes_label">
+ Yol bulma özellikleri:
+ </text>
<text name="B:">
B:
</text>
diff --git a/indra/newview/skins/default/xui/tr/strings.xml b/indra/newview/skins/default/xui/tr/strings.xml
index 2a4e2c20a7..c4b1530b2b 100644..100755
--- a/indra/newview/skins/default/xui/tr/strings.xml
+++ b/indra/newview/skins/default/xui/tr/strings.xml
@@ -137,7 +137,10 @@
Çık
</string>
<string name="create_account_url">
- http://join.secondlife.com/
+ http://join.secondlife.com/?sourceid=[sourceid]
+ </string>
+ <string name="ViewerDownloadURL">
+ http://secondlife.com/download
</string>
<string name="LoginFailedViewerNotPermitted">
Kullandığınız görüntüleyici ile artık Second Life&apos;a erişemezsiniz. Yeni bir görüntüleyiciyi karşıdan yüklemek için lütfen şu sayfayı ziyaret edin:
@@ -448,6 +451,9 @@ Lütfen bir dakika içerisinde tekrar oturum açmayı deneyin.
<string name="SLappAgentRequestFriend">
Arkadaşlık Talebi
</string>
+ <string name="SLappAgentRemoveFriend">
+ Arkadaşların Çıkarılması
+ </string>
<string name="BUTTON_CLOSE_DARWIN">
Kapat (⌘W)
</string>
@@ -619,8 +625,8 @@ Lütfen bir dakika içerisinde tekrar oturum açmayı deneyin.
<string name="AvatarAway">
Uzakta
</string>
- <string name="AvatarBusy">
- MeÅŸgul
+ <string name="AvatarDoNotDisturb">
+ Rahatsız Etme
</string>
<string name="AvatarMuted">
EngellenmiÅŸ
@@ -835,6 +841,9 @@ Lütfen bir dakika içerisinde tekrar oturum açmayı deneyin.
<string name="multiple_textures">
Birden Çok
</string>
+ <string name="use_texture">
+ Dokuyu kullan
+ </string>
<string name="texture_loading">
Yükleniyor...
</string>
@@ -856,6 +865,12 @@ Lütfen bir dakika içerisinde tekrar oturum açmayı deneyin.
<string name="ST_NO_JOINT">
KÖK veya EKLEM bulunamıyor.
</string>
+ <string name="NearbyChatTitle">
+ Yakındaki sohbet
+ </string>
+ <string name="NearbyChatLabel">
+ (Yakındaki sohbet)
+ </string>
<string name="whisper">
fısıldar:
</string>
@@ -883,6 +898,9 @@ Lütfen bir dakika içerisinde tekrar oturum açmayı deneyin.
<string name="ScriptQuestionCautionChatDenied">
&apos;[OWNERNAME]&apos; adlı kişiye ait, [REGIONPOS] üzerinde [REGIONNAME] içerisinde bulunan &apos;[OBJECTNAME]&apos; nesnesine şunu yapma izni verilmedi: [PERMISSIONS].
</string>
+ <string name="AdditionalPermissionsRequestHeader">
+ Eğer hesabınıza erişime izin verirseniz, bu nesneye aynı zamanda şunun için izin vermiş olacaksınız:
+ </string>
<string name="ScriptTakeMoney">
Sizden Linden dolar (L$) almak
</string>
@@ -919,6 +937,27 @@ Lütfen bir dakika içerisinde tekrar oturum açmayı deneyin.
<string name="NotConnected">
Bağlı Değil
</string>
+ <string name="AgentNameSubst">
+ (Siz)
+ </string>
+ <string name="TeleportYourAgent">
+ Sizi ışınlama
+ </string>
+ <string name="JoinAnExperience">
+ Bir tecrübeye katıl
+ </string>
+ <string name="SilentlyManageEstateAccess">
+ Gayri menkul erişim listelerini yönetirken uyarıları bastır
+ </string>
+ <string name="OverrideYourAnimations">
+ Varsayılan animasyonlarınızı değiştirin
+ </string>
+ <string name="ScriptReturnObjects">
+ Kendi adınıza nesneler iade edin
+ </string>
+ <string name="UnknownScriptPermission">
+ (bilinmiyor)!
+ </string>
<string name="SIM_ACCESS_PG">
Genel
</string>
@@ -997,17 +1036,8 @@ Lütfen bir dakika içerisinde tekrar oturum açmayı deneyin.
<string name="script_files">
Komut Dosyaları
</string>
- <string name="AvatarSetNotAway">
- Uzakta DeÄŸil
- </string>
- <string name="AvatarSetAway">
- Uzakta
- </string>
- <string name="AvatarSetNotBusy">
- MeÅŸgul DeÄŸil
- </string>
- <string name="AvatarSetBusy">
- MeÅŸgul
+ <string name="dictionary_files">
+ Sözlükler
</string>
<string name="shape">
Åžekil
@@ -1241,7 +1271,7 @@ Lütfen bir dakika içerisinde tekrar oturum açmayı deneyin.
https://marketplace.[MARKETPLACE_DOMAIN_NAME]/
</string>
<string name="MarketplaceURL_CreateStore">
- http://community.secondlife.com/t5/English-Knowledge-Base/Selling-in-the-Marketplace/ta-p/700193#Section_.4
+ http://community.secondlife.com/t5/English-Knowledge-Base/Selling-in-the-Marketplace/ta-p/700193#Section_.3
</string>
<string name="MarketplaceURL_Dashboard">
https://marketplace.[MARKETPLACE_DOMAIN_NAME]/merchants/store/dashboard
@@ -1402,6 +1432,12 @@ Lütfen bir dakika içerisinde tekrar oturum açmayı deneyin.
<string name="InvFolder favorite">
Favorilerim
</string>
+ <string name="InvFolder Favorites">
+ Sık Kullanılanlarım
+ </string>
+ <string name="InvFolder favorites">
+ Sık Kullanılanlarım
+ </string>
<string name="InvFolder Current Outfit">
Mevcut Dış Görünüm
</string>
@@ -1417,6 +1453,12 @@ Lütfen bir dakika içerisinde tekrar oturum açmayı deneyin.
<string name="InvFolder Meshes">
Örgüler
</string>
+ <string name="InvFolder Received Items">
+ Alınan Öğeler
+ </string>
+ <string name="InvFolder Merchant Outbox">
+ Satıcı Giden Kutusu
+ </string>
<string name="InvFolder Friends">
ArkadaÅŸlar
</string>
@@ -1947,6 +1989,12 @@ Lütfen bir dakika içerisinde tekrar oturum açmayı deneyin.
<string name="ATTACH_HUD_BOTTOM_RIGHT">
BÃœG SaÄŸ Alt
</string>
+ <string name="ATTACH_NECK">
+ Boyun
+ </string>
+ <string name="ATTACH_AVATAR_CENTER">
+ Avatar Merkezi
+ </string>
<string name="CursorPos">
Satır [LINE], Sütun [COLUMN]
</string>
@@ -1965,8 +2013,8 @@ Lütfen bir dakika içerisinde tekrar oturum açmayı deneyin.
<string name="PanelContentsNewScript">
Yeni Komut Dosyası
</string>
- <string name="BusyModeResponseDefault">
- İleti gönderdiğiniz Sakin &apos;meşgul modu&apos;nda, bu da rahatsız edilmek istemediği anlamına geliyor. İletiniz daha sonra incelenmesi için kendisine ait Aİ panelinde gösterilecektir.
+ <string name="DoNotDisturbModeResponseDefault">
+ Bu sakin &quot;Rahatsız Etme&quot; seçeneğini devreye almış, mesajınızı sonra görecek.
</string>
<string name="MuteByName">
(Adına göre)
@@ -2079,9 +2127,6 @@ Lütfen bir dakika içerisinde tekrar oturum açmayı deneyin.
<string name="GroupMoneyDate">
[weekday,datetime,utc] [mth,datetime,utc] [day,datetime,utc], [year,datetime,utc]
</string>
- <string name="ViewerObjectContents">
- İçerik
- </string>
<string name="AcquiredItems">
Alınan Öğeler
</string>
@@ -2979,6 +3024,9 @@ Bu iletiyi almaya devam ederseniz, lütfen [SUPPORT_SITE] bölümüne başvurun.
<string name="Hip Width">
Kalça Genişliği
</string>
+ <string name="Hover">
+ Ãœzerine getir
+ </string>
<string name="In">
İçeri
</string>
@@ -3853,7 +3901,13 @@ Bu iletiyi almaya devam ederseniz, lütfen [SUPPORT_SITE] bölümüne başvurun.
Genel Bölge
</string>
<string name="LocationCtrlSeeAVsTooltip">
- Bu parselin dışında avatarlar görünür durumda ve sohbete izin veriliyor
+ Bu parselin içindeki avatarlar, bu parselin dışındaki avatarlar tarafından görülemez veya işitilemez
+ </string>
+ <string name="LocationCtrlPathfindingDirtyTooltip">
+ Bölge yeniden kaydedilinceye kadar hareket eden nesneler bu bölgede doğru davranmayabilir.
+ </string>
+ <string name="LocationCtrlPathfindingDisabledTooltip">
+ Bu bölgede dinamik yol bulma etkin değil.
</string>
<string name="UpdaterWindowTitle">
[APP_NAME] Güncelleştirme
@@ -3924,6 +3978,12 @@ Bu iletiyi almaya devam ederseniz, lütfen [SUPPORT_SITE] bölümüne başvurun.
<string name="IM_unblock_only_groups_friends">
Bu mesajı görmek için Tercihler/Gizlilik&apos;de &apos;Sadece arkadaşlar ve gruplar beni arasın veya Aİ göndersin&apos; seçeneğinin işaretini kaldırmalısınız.
</string>
+ <string name="OnlineStatus">
+ Çevrimiçi
+ </string>
+ <string name="OfflineStatus">
+ Çevrimdışı
+ </string>
<string name="answered_call">
Aramanız yanıtlandı
</string>
@@ -3933,6 +3993,9 @@ Bu iletiyi almaya devam ederseniz, lütfen [SUPPORT_SITE] bölümüne başvurun.
<string name="you_joined_call">
Sesli aramaya katıldınız
</string>
+ <string name="you_auto_rejected_call-im">
+ &quot;Rahatsız Etme&quot; seçeneğini devredeyken sesli aramayı otomatik olarak reddettiniz.
+ </string>
<string name="name_started_call">
[NAME] bir sesli arama başlattı
</string>
@@ -3949,7 +4012,7 @@ Bu iletiyi almaya devam ederseniz, lütfen [SUPPORT_SITE] bölümüne başvurun.
Bağlanıyor...
</string>
<string name="conference-title">
- Özel Konferans
+ Çok kişili sohbet
</string>
<string name="conference-title-incoming">
[AGENT_NAME] ile konferans
@@ -4839,6 +4902,9 @@ Düzenleyici yolunu çift tırnakla çevrelemeyi deneyin.
<string name="Command_Chat_Label">
Sohbet
</string>
+ <string name="Command_Conversations_Label">
+ Sohbetler
+ </string>
<string name="Command_Compass_Label">
Pusula
</string>
@@ -4914,6 +4980,9 @@ Düzenleyici yolunu çift tırnakla çevrelemeyi deneyin.
<string name="Command_Chat_Tooltip">
Metin kullanarak yakındaki kişilerle sohbet etmek
</string>
+ <string name="Command_Conversations_Tooltip">
+ Herkesle sohbet et
+ </string>
<string name="Command_Compass_Tooltip">
Pusula
</string>
@@ -5007,6 +5076,21 @@ Düzenleyici yolunu çift tırnakla çevrelemeyi deneyin.
<string name="Normal">
Normal
</string>
+ <string name="Pathfinding_Wiki_URL">
+ http://wiki.secondlife.com/wiki/Pathfinding_Tools_in_the_Second_Life_Viewer
+ </string>
+ <string name="Pathfinding_Object_Attr_None">
+ Hiçbiri
+ </string>
+ <string name="Pathfinding_Object_Attr_Permanent">
+ Navigasyon örgüsünü etkiler
+ </string>
+ <string name="Pathfinding_Object_Attr_Character">
+ Karakter
+ </string>
+ <string name="Pathfinding_Object_Attr_MultiSelect">
+ (Birden çok)
+ </string>
<string name="snapshot_quality_very_low">
Çok Düşük
</string>
@@ -5022,4 +5106,22 @@ Düzenleyici yolunu çift tırnakla çevrelemeyi deneyin.
<string name="snapshot_quality_very_high">
Çok Yüksek
</string>
+ <string name="TeleportMaturityExceeded">
+ Sakin bu bölgeyi ziyaret edemez.
+ </string>
+ <string name="UserDictionary">
+ [User]
+ </string>
+ <string name="logging_calls_disabled_log_empty">
+ Sohbetlerin günlüğü tutulmuyor. Bir günlük tutmaya başlamak için, Tercihler &gt; Sohbet altında &quot;Kaydet: Sadece günlük&quot; veya &quot;Kaydet: Günlük ve dökümler&quot; seçimini yapın.
+ </string>
+ <string name="logging_calls_disabled_log_not_empty">
+ Bundan böyle sohbetlerin günlükleri tutulmayacak. Bir günlük tutmaya devam etmek için, Tercihler &gt; Sohbet altında &quot;Kaydet: Sadece günlük&quot; veya &quot;Kaydet: Günlük ve dökümler&quot; seçimini yapın.
+ </string>
+ <string name="logging_calls_enabled_log_empty">
+ Günlüğü tutulmuş sohbet yok. Siz biriyle iletişime geçtikten sonra veya biri sizinle iletişime geçtikten sonra, burada bir günlük girişi gösterilir.
+ </string>
+ <string name="loading_chat_logs">
+ Yükleniyor...
+ </string>
</strings>
diff --git a/indra/newview/skins/default/xui/tr/teleport_strings.xml b/indra/newview/skins/default/xui/tr/teleport_strings.xml
index 62aaaf671f..20d09b1ee2 100644..100755
--- a/indra/newview/skins/default/xui/tr/teleport_strings.xml
+++ b/indra/newview/skins/default/xui/tr/teleport_strings.xml
@@ -45,6 +45,9 @@ Bir dakika sonra tekrar deneyin.
<message name="no_inventory_host">
Envanter sistemi şu anda kullanılamıyor.
</message>
+ <message name="MustGetAgeRegion">
+ Bu bölgeye girebilmek için 18 veya üzeri bir yaşta olmanız gerekir.
+ </message>
</message_set>
<message_set name="progress">
<message name="sending_dest">
@@ -80,5 +83,8 @@ Bir dakika sonra tekrar deneyin.
<message name="requesting">
Işınlanma talep ediliyor...
</message>
+ <message name="pending">
+ Işınlama Bekliyor...
+ </message>
</message_set>
</teleport_messages>
diff --git a/indra/newview/skins/default/xui/zh/floater_aaa.xml b/indra/newview/skins/default/xui/zh/floater_aaa.xml
index 0d110c0456..e2d6a2b004 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_aaa.xml
+++ b/indra/newview/skins/default/xui/zh/floater_aaa.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="Test Floater" title="測試浮動視窗">
<string name="test_the_vlt">
- This string CHANGE2 is extracted.
+ 字串 CHANGE2 已抽å–。
</string>
<string name="testing_eli">
這åªæ˜¯æ¸¬è©¦ - 變更。
diff --git a/indra/newview/skins/default/xui/zh/floater_about.xml b/indra/newview/skins/default/xui/zh/floater_about.xml
index 7e19c124a1..2dfb35fa54 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_about.xml
+++ b/indra/newview/skins/default/xui/zh/floater_about.xml
@@ -5,10 +5,12 @@
[[VIEWER_RELEASE_NOTES_URL] [ReleaseNotes]]
</floater.string>
<floater.string name="AboutCompiler">
- Built with [COMPILER] version [COMPILER_VERSION]
+ 以 [COMPILER_VERSION] 版本 [COMPILER] 建置
</floater.string>
<floater.string name="AboutPosition">
- You are at [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1] in [REGION] located at &lt;nolink&gt;[HOSTNAME]&lt;/nolink&gt; ([HOSTIP])
+ ä½ çš„æ–¹ä½æ˜¯ [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1],地å€å:[REGION],主機:&lt;nolink&gt;[HOSTNAME]&lt;/nolink&gt; ([HOSTIP])
+第二人生 URL:&lt;nolink&gt;[SLURL]&lt;/nolink&gt;
+(全域å標:[POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1])
[SERVER_VERSION]
[SERVER_RELEASE_NOTES_URL]
</floater.string>
@@ -20,10 +22,10 @@
顯示å¡ï¼š[GRAPHICS_CARD]
</floater.string>
<floater.string name="AboutDriver">
- Windows Graphics Driver Version: [GRAPHICS_DRIVER_VERSION]
+ Windows 顯示驅動程å¼ç‰ˆæœ¬ï¼š[GRAPHICS_DRIVER_VERSION]
</floater.string>
<floater.string name="AboutLibs">
- OpenGL Version: [OPENGL_VERSION]
+ OpenGL 版本:[OPENGL_VERSION]
libcurl 版本: [LIBCURL_VERSION]
J2C 解碼器版本: [J2C_VERSION]
@@ -37,47 +39,60 @@ Qt Webkit 版本: [QT_WEBKIT_VERSION]
<floater.string name="AboutTraffic">
å°åŒ…æ失:[PACKETS_LOST,number,0]/[PACKETS_IN,number,0] ([PACKETS_PCT,number,1]%)
</floater.string>
+ <floater.string name="ErrorFetchingServerReleaseNotesURL">
+ æ“·å–伺æœå™¨ç‰ˆæœ¬èªªæ˜Ž URL 時出錯。
+ </floater.string>
<tab_container name="about_tab">
<panel label="資訊" name="support_panel">
<button label="覆製到剪貼簿" name="copy_btn"/>
</panel>
- <panel label="Credits" name="credits_panel">
- <text_editor name="credits_editor">
- Second Life is brought to you by ..., and many others.
-
-Thank you to the following Residents for helping to ensure that this is the best version yet: ..., and many others.
-
-
-
-
-&quot;The work goes on, the cause endures, the hope still lives, and the dreams shall never die&quot; - Edward Kennedy
+ <panel label="貸記" name="credits_panel">
+ <text name="linden_intro">
+ 「第二人生ã€ç”±ä»¥ä¸‹çš„ Linden 家æ—帶給你:
+ </text>
+ <text name="contrib_intro">
+ 這些人士åšäº†é–‹æ”¾æºç¢¼çš„è²¢ç»ï¼š
+ </text>
+ <text_editor name="contrib_names">
+ 執行時期被å–代的å‡å稱
+ </text_editor>
+ <text name="trans_intro">
+ 以下人士æ供翻譯:
+ </text>
+ <text_editor name="trans_names">
+ 執行時期被å–代的å‡å稱
</text_editor>
</panel>
- <panel label="Licenses" name="licenses_panel">
+ <panel label="許å¯" name="licenses_panel">
<text_editor name="credits_editor">
- 3Dconnexion SDK Copyright (C) 1992-2007 3Dconnexion
-APR Copyright (C) 2000-2004 The Apache Software Foundation
-cURL Copyright (C) 1996-2002, Daniel Stenberg, (daniel@haxx.se)
-DBus/dbus-glib Copyright (C) 2002, 2003 CodeFactory AB / Copyright (C) 2003, 2004 Red Hat, Inc.
-expat Copyright (C) 1998, 1999, 2000 Thai Open Source Software Center Ltd.
-FreeType Copyright (C) 1996-2002, The FreeType Project (www.freetype.org).
-GL Copyright (C) 1999-2004 Brian Paul.
-google-perftools Copyright (c) 2005, Google Inc.
-Havok.com(TM) Copyright (C) 1999-2001, Telekinesys Research Limited.
-jpeg2000 Copyright (C) 2001, David Taubman, The University of New South Wales (UNSW)
-jpeglib Copyright (C) 1991-1998, Thomas G. Lane.
-ogg/vorbis Copyright (C) 2001, Xiphophorus
-OpenSSL Copyright (C) 1998-2002 The OpenSSL Project.
-Pth Copyright (C) 1999-2006 Ralf S. Engelschall &lt;rse@gnu.org&gt;
-SDL Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga
-SSLeay Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
-xmlrpc-epi Copyright (C) 2000 Epinions, Inc.
-zlib Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler.
-google-perftools Copyright (c) 2005, Google Inc.
+ 3Dconnexion SDK Copyright (C) 1992-2009 3Dconnexion
+ APR Copyright (C) 2011 The Apache Software Foundation
+ Collada DOM Copyright 2006 Sony Computer Entertainment Inc.
+ cURL Copyright (C) 1996-2010, Daniel Stenberg, (daniel@haxx.se)
+ DBus/dbus-glib Copyright (C) 2002, 2003 CodeFactory AB / Copyright (C) 2003, 2004 Red Hat, Inc.
+ expat Copyright (C) 1998, 1999, 2000 Thai Open Source Software Center Ltd.
+ FreeType Copyright (C) 1996-2002, 2006 David Turner, Robert Wilhelm, and Werner Lemberg.
+ GL Copyright (C) 1999-2004 Brian Paul.
+ GLOD Copyright (C) 2003-04 Jonathan Cohen, Nat Duca, Chris Niski, Johns Hopkins University and David Luebke, Brenden Schubert, University of Virginia.
+ google-perftools Copyright (c) 2005, Google Inc.
+ Havok.com(TM) Copyright (C) 1999-2001, Telekinesys Research Limited.
+ jpeg2000 Copyright (C) 2001, David Taubman, The University of New South Wales (UNSW)
+ jpeglib Copyright (C) 1991-1998, Thomas G. Lane.
+ ogg/vorbis Copyright (C) 2002, Xiphophorus
+ OpenSSL Copyright (C) 1998-2008 The OpenSSL Project.
+ PCRE Copyright (c) 1997-2012 University of Cambridge
+ SDL Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga
+ SSLeay Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ xmlrpc-epi Copyright (C) 2000 Epinions, Inc.
+ zlib Copyright (C) 1995-2012 Jean-loup Gailly and Mark Adler.
+
+ 第二人生 Viewer 採用 Havok (TM) 物ç†å¼•æ“Žã€‚ (c)Copyright 1999-2010 Havok.com Inc.(åŠå…¶æ”¾ç…§äººï¼‰ã€‚ ä¿ç•™ä¸€åˆ‡æ¬Šåˆ©ã€‚ 詳情見 www.havok.com。
+
+ 本軟體å«æœ‰ NVIDIA Corporation æ供的æºç¨‹å¼ç¢¼ã€‚
-All rights reserved. See licenses.txt for details.
+ ä¿ç•™ä¸€åˆ‡æ¬Šåˆ©ã€‚ 詳情見 licenses.txt。
-語音èŠå¤©éŸ³é »ç·¨ç¢¼ï¼šPolycom(R) Siren14(TM) (ITU-T Rec. G.722.1 Annex C)
+ 語音èŠå¤©éŸ³é »æŠ€è¡“:Polycom(R) Siren14(TM) (ITU-T Rec. G.722.1 Annex C)
</text_editor>
</panel>
</tab_container>
diff --git a/indra/newview/skins/default/xui/zh/floater_about_land.xml b/indra/newview/skins/default/xui/zh/floater_about_land.xml
index 2568d492f0..76db621951 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/zh/floater_about_land.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floaterland" title="關於土地">
+<floater name="floaterland" title="土地資料">
<floater.string name="maturity_icon_general">
&quot;Parcel_PG_Dark&quot;
</floater.string>
@@ -10,39 +10,39 @@
&quot;Parcel_R_Dark&quot;
</floater.string>
<floater.string name="Minutes">
- [MINUTES] minutes
+ [MINUTES] 分é˜
</floater.string>
<floater.string name="Minute">
- minute
+ 分é˜
</floater.string>
<floater.string name="Seconds">
- [SECONDS] seconds
+ [SECONDS] 秒
</floater.string>
<floater.string name="Remaining">
- remaining
+ 剩餘時間
</floater.string>
<tab_container name="landtab">
<panel label="一般" name="land_general_panel">
<panel.string name="new users only">
- New Residents only
+ 僅é™æ–°å±…æ°‘
</panel.string>
<panel.string name="anyone">
- Anyone
+ 任何人
</panel.string>
<panel.string name="area_text">
å€åŸŸ
</panel.string>
<panel.string name="area_size_text">
- [AREA] m²
+ [AREA] 平方公尺
</panel.string>
<panel.string name="auction_id_text">
- Auction ID: [ID]
+ æ‹è³£ ID:[ID]
</panel.string>
<panel.string name="need_tier_to_modify">
- You must approve your purchase to modify this land.
+ 你必須批准購買æ‰èƒ½ä¿®æ”¹é€™å¡ŠåœŸåœ°ã€‚
</panel.string>
<panel.string name="group_owned_text">
- (群組所æ“有)
+ (由群組所æ“有)
</panel.string>
<panel.string name="profile_text">
檔案
@@ -57,10 +57,10 @@
(無)
</panel.string>
<panel.string name="sale_pending_text">
- (Sale Pending)
+ (擱置銷售)
</panel.string>
<panel.string name="no_selection_text">
- No parcel selected.
+ 未é¸æ“‡åœ°æ®µã€‚
</panel.string>
<panel.string name="time_stamp_template">
[wkday,datetime,local] [mth,datetime,local] [day,datetime,local] [hour,datetime,local]:[min,datetime,local]:[second,datetime,local] [year,datetime,local]
@@ -75,7 +75,7 @@
類型:
</text>
<text name="LandTypeText">
- Mainland / Homestead
+ 大陸 / 家園
</text>
<text name="ContentRating">
分級:
@@ -84,37 +84,37 @@
完全æˆäºº
</text>
<text name="Owner:">
- æ“有者:
+ 所有人:
</text>
<text name="Group:">
群組:
</text>
<button label="設定" name="Set..."/>
- <check_box label="å…許讓渡給群組" name="check deed" tool_tip="A group officer can deed this land to the group, so it will be supported by the group&apos;s land allocation."/>
- <button label="讓渡" name="Deed..." tool_tip="You may only deed land if you are an officer in the selected group."/>
- <check_box label="Owner Makes Contribution With Deed" name="check contrib" tool_tip="When the land is deeded to the group, the former owner contributes enough land allocation to support it."/>
+ <check_box label="å…許讓渡給群組" name="check deed" tool_tip="群組工作人員å¯å°‡é€™åœŸåœ°è®“渡給群組,使其得到群組土地é…置的支æ´ã€‚"/>
+ <button label="讓渡" name="Deed..." tool_tip="你必須是所é¸ç¾¤çµ„的工作人員æ‰èƒ½è®“渡土地。"/>
+ <check_box label="所有人é€éŽè®“渡動作進行æç»" name="check contrib" tool_tip="將土地讓渡給群組,表示上一個所有人會æç»è¶³å¤ åœŸåœ°ä¾†æ”¯æŒè®“渡。"/>
<text name="For Sale:">
- 出售:
+ 出售中:
</text>
<text name="Not for sale.">
ä¸å‡ºå”®
</text>
<text name="For Sale: Price L$[PRICE].">
- Price: L$[PRICE] (L$[PRICE_PER_SQM]/m²)
+ 價格:L$[PRICE] (L$[PRICE_PER_SQM]/平方公尺)
</text>
<button label="出售土地" name="Sell Land..."/>
<text name="For sale to">
出售給:[BUYER]
</text>
<text name="Sell with landowners objects in parcel.">
- Objects included in sale
+ 物件連帶一起出售
</text>
<text name="Selling with no objects in parcel.">
- Objects not included in sale
+ 此次出售ä¸å«ç‰©ä»¶
</text>
- <button label="Cancel Land Sale" label_selected="Cancel Land Sale" name="Cancel Land Sale"/>
+ <button label="å–消土地出售" label_selected="å–消土地出售" name="Cancel Land Sale"/>
<text name="Claimed:">
- Claimed:
+ 已收å–:
</text>
<text name="DateClaimText">
Tue Aug 15 13:47:25 2006
@@ -123,52 +123,52 @@
é¢ç©ï¼š
</text>
<text name="PriceText">
- 4048 m²
+ 4048 平方公尺
</text>
<text name="Traffic:">
æµé‡ï¼š
</text>
<text name="DwellText">
- 0
+ 載入中...
</text>
<button label="購買土地" name="Buy Land..."/>
+ <button label="Linden 出售" name="Linden Sale..." tool_tip="土地必須有人æ“有ã€å·²è¨­æœ‰å…§å®¹ï¼Œä¸¦ä¸”ä¸åœ¨æ‹è³£ä¸­ã€‚"/>
<button label="腳本資訊" name="Scripts..."/>
<button label="為群組購買" name="Buy For Group..."/>
<button label="購買通行權" name="Buy Pass..." tool_tip="通行權å…許你暫時å¯å‡ºå…¥é€™å¡ŠåœŸåœ°ã€‚"/>
<button label="放棄土地" name="Abandon Land..."/>
- <button label="Reclaim Land" name="Reclaim Land..."/>
- <button label="Linden Sale" name="Linden Sale..." tool_tip="Land must be owned, set content, and not already for auction."/>
+ <button label="收回土地" name="Reclaim Land..."/>
</panel>
<panel label="契約" name="land_covenant_panel">
<panel.string name="can_resell">
- Purchased land in this region may be resold.
+ 購買這地å€çš„土地å…許轉售。
</panel.string>
<panel.string name="can_not_resell">
- Purchased land in this region may not be resold.
+ 購買這地å€çš„土地ä¸å…許轉售。
</panel.string>
<panel.string name="can_change">
- Purchased land in this region may be joined or subdivided.
+ 購買這地å€çš„土地å…許進行åˆä½µæˆ–分割。
</panel.string>
<panel.string name="can_not_change">
- Purchased land in this region may not be joined or subdivided.
+ 購買這地å€çš„土地ä¸å…許進行åˆä½µæˆ–分割。
</panel.string>
<text name="estate_section_lbl">
領地:
</text>
<text name="estate_name_text">
- mainland
+ 大陸
</text>
<text name="estate_owner_lbl">
- æ“有者:
+ 所有人:
</text>
<text name="estate_owner_text">
(無)
</text>
<text_editor name="covenant_editor">
- There is no Covenant provided for this Estate.
+ 此領地沒有任何契約è¦æ±‚。
</text_editor>
<text name="covenant_timestamp_text">
- Last Modified Wed Dec 31 16:00:00 1969
+ 上次修改於 Wed Dec 31 16:00:00 1969
</text>
<text name="region_section_lbl">
地å€ï¼š
@@ -180,7 +180,7 @@
類型:
</text>
<text name="region_landtype_text">
- Mainland / Homestead
+ 大陸 / 家園
</text>
<text name="region_maturity_lbl">
分級:
@@ -189,54 +189,54 @@
完全æˆäºº
</text>
<text name="resellable_lbl">
- Resale:
+ 轉售:
</text>
<text name="resellable_clause">
- Land in this region may not be resold.
+ 這地å€çš„土地ä¸èƒ½è½‰å”®ã€‚
</text>
<text name="changeable_lbl">
- Subdivide:
+ 分割:
</text>
<text name="changeable_clause">
- Land in this region may not be joined/subdivided.
+ 這地å€çš„土地ä¸èƒ½åˆä½µæˆ–分割。
</text>
</panel>
<panel label="物件" name="land_objects_panel">
<panel.string name="objects_available_text">
- [COUNT] out of [MAX] ([AVAILABLE] available)
+ 使用 [MAX] 中的 [COUNT] (剩餘 [AVAILABLE] å¯ç”¨ï¼‰
</panel.string>
<panel.string name="objects_deleted_text">
- [COUNT] out of [MAX] ([DELETED] will be deleted)
+ ç›®å‰ [COUNT],最多å…許 [MAX] ([DELETED] 將被刪除)
</panel.string>
<text name="parcel_object_bonus">
- Region Object Bonus Factor: [BONUS]
+ 地å€ç‰©ä»¶è² è·å€æ•¸ï¼š[BONUS]
</text>
<text name="Simulator primitive usage:">
- 幾何元件使用:
+ 地å€å®¹ç´é‡ï¼š
</text>
<text name="objects_available">
使用 [MAX] 中的 [COUNT] (剩餘 [AVAILABLE] å¯ç”¨ï¼‰
</text>
<text name="Primitives parcel supports:">
- 地段所æ供的幾何元件數:
+ 地段土地容ç´é‡ï¼š
</text>
<text name="object_contrib_text">
[COUNT]
</text>
<text name="Primitives on parcel:">
- 地段上的幾何元件數:
+ 地段土地è¡æ“Šé‡ï¼š
</text>
<text name="total_objects_text">
[COUNT]
</text>
<text name="Owned by parcel owner:">
- 地段æ“有者所æ“有:
+ 地段所有人所æ“有:
</text>
<text name="owner_objects_text">
[COUNT]
</text>
<button label="顯示" label_selected="顯示" name="ShowOwner"/>
- <button label="退回" name="ReturnOwner..." tool_tip="退回物件給它們的æ“有者。"/>
+ <button label="退回" name="ReturnOwner..." tool_tip="退回物件給它們的所有人。"/>
<text name="Set to group:">
設定群組:
</text>
@@ -244,7 +244,7 @@
[COUNT]
</text>
<button label="顯示" label_selected="顯示" name="ShowGroup"/>
- <button label="退回" name="ReturnGroup..." tool_tip="退回物件給它們的æ“有者。"/>
+ <button label="退回" name="ReturnGroup..." tool_tip="退回物件給它們的所有人。"/>
<text name="Owned by others:">
其他人所æ“有:
</text>
@@ -252,26 +252,26 @@
[COUNT]
</text>
<button label="顯示" label_selected="顯示" name="ShowOther"/>
- <button label="退回" name="ReturnOther..." tool_tip="退回物件給它們的æ“有者。"/>
+ <button label="退回" name="ReturnOther..." tool_tip="退回物件給它們的所有人。"/>
<text name="Selected / sat upon:">
- Selected / sat upon:
+ å·²é¸ / å在上é¢ï¼š
</text>
<text name="selected_objects_text">
[COUNT]
</text>
<text name="Autoreturn">
- Auto return other Residents&apos; objects (minutes, 0 for off):
+ 自動é€è¿”其他居民的物件(分é˜ï¼Œè¨­ç‚º 0 å¯å–消自動):
</text>
<text name="Object Owners:">
- 物件æ“有者:
+ 物件所有人:
</text>
<button name="Refresh List" tool_tip="刷新物件清單"/>
<button label="退回物件" name="Return objects..."/>
<name_list name="owner list">
- <name_list.columns label="Type" name="type"/>
+ <name_list.columns label="é¡žåž‹" name="type"/>
<name_list.columns label="å稱" name="name"/>
- <name_list.columns label="Count" name="count"/>
- <name_list.columns label="Most Recent" name="mostrecent"/>
+ <name_list.columns label="計數" name="count"/>
+ <name_list.columns label="最近" name="mostrecent"/>
</name_list>
</panel>
<panel label="é¸é …" name="land_options_panel">
@@ -279,8 +279,8 @@
讓其他人å¯ä»¥åœ¨æœå°‹çµæžœä¸­çœ‹åˆ°é€™å¡Šåœ°æ®µ
</panel.string>
<panel.string name="search_disabled_small_tooltip">
- This option is disabled because this parcel&apos;s area is 128 m² or smaller.
-Only large parcels can be listed in search.
+ 這個é¸é …å·²åœç”¨ï¼Œå› ç‚ºé€™å€‹åœ°æ®µé¢ç©å°æ–¼ 128 平方公尺。
+大é¢ç©åœ°æ®µæ‰å¯åˆ—å…¥æœå°‹çµæžœã€‚
</panel.string>
<panel.string name="search_disabled_permissions_tooltip">
這個é¸é …已關閉因為你ä¸èƒ½ä¿®æ”¹é€™å€‹åœ°æ®µçš„é¸é …。
@@ -292,10 +292,10 @@ Only large parcels can be listed in search.
完全æˆäººå…§å®¹
</panel.string>
<panel.string name="mature_check_mature_tooltip">
- Your parcel information or content is considered moderate.
+ 你的地段資訊或內容被視為é©åº¦æˆäººåˆ†ç´šã€‚
</panel.string>
<panel.string name="mature_check_adult_tooltip">
- Your parcel information or content is considered adult.
+ 你的地段資訊或內容被視為完全æˆäººåˆ†ç´šã€‚
</panel.string>
<panel.string name="landing_point_none">
(無)
@@ -309,8 +309,10 @@ Only large parcels can be listed in search.
<text name="allow_label">
å…許其他居民去:
</text>
- <check_box label="編輯地形" name="edit land check" tool_tip="若勾é¸å‰‡ä»»ä½•äººå°‡å¯ä»¥è®Šå½¢ä½ çš„土地,最好是ä¿æŒæœªå‹¾é¸ï¼Œå› ç‚ºä½ éš¨æ™‚å¯ä»¥ç·¨è¼¯è®Šæ›´ä½ çš„土地。"/>
- <check_box label="飛行" name="check fly" tool_tip="逤勾é¸å‰‡å±…æ°‘å¯ä»¥åœ¨ä½ é£›è¡Œï¼Œä¸ç„¶å°±åªèƒ½ç”±å¤–é¢é£›å…¥æˆ–飛越你的土地。"/>
+ <text name="allow_label0">
+ 飛行:
+ </text>
+ <check_box label="任何人" name="check fly" tool_tip="如果勾é¸ï¼Œå±…æ°‘å¯åœ¨ä½ åœŸåœ°ä¸Šé£›è¡Œã€‚ 如果ä¸å‹¾é¸ï¼Œå±…民僅å¯é£›è¶Šä½ åœŸåœ°ã€‚"/>
<text name="allow_label2">
建造:
</text>
@@ -326,67 +328,68 @@ Only large parcels can be listed in search.
</text>
<check_box label="任何人" name="check other scripts"/>
<check_box label="群組" name="check group scripts"/>
- <text name="land_options_label">
- 土地é¸é …:
- </text>
- <check_box label="安全(無傷害)" name="check safe" tool_tip="若勾é¸å‰‡è¨­æ‡‰åœŸåœ°ç‚ºå®‰å…¨çš„,傷害性的戰鬥將被關閉。清除勾é¸å¾Œæ‰èƒ½é€²è¡Œå‚·å®³æ€§çš„戰鬥。"/>
- <check_box label="ç¦æ­¢æŽ¨æ’ž" name="PushRestrictCheck" tool_tip="防止使用腳本推撞。勾é¸é€™å€‹é¸é …å°‡å¯ä»¥æœ‰æ•ˆé˜²æ­¢ä½ åœŸåœ°ä¸Šçš„破壞行為。"/>
+ <check_box label="安全(無傷害)" name="check safe" tool_tip="若勾é¸ï¼Œå°‡æŠŠåœŸåœ°è¨­ç‚ºå®‰å…¨ï¼Œç¦çµ•å‚·å®³æ€§çš„戰鬥。 若未勾é¸ï¼Œå‰‡å…許傷害性的戰鬥。"/>
+ <check_box label="ç¦æ­¢æŽ¨æ’ž" name="PushRestrictCheck" tool_tip="ç¦æ­¢ä½¿ç”¨è…³æœ¬æŽ¨æ’žã€‚ 勾é¸é€™é¸é …å¯æœ‰æ•ˆé˜²æ­¢ä½ åœŸåœ°ä¸Šå‡ºç¾æ»‹äº‹è¡Œç‚ºã€‚"/>
<check_box label="將地點刊登顯示在æœå°‹ä¸­ï¼ˆL$30 / æ¯é€±ï¼‰" name="ShowDirectoryCheck" tool_tip="讓其他人å¯ä»¥åœ¨æœå°‹çµæžœä¸­çœ‹åˆ°é€™å¡Šåœ°æ®µ"/>
<combo_box name="land category with adult">
<combo_box.item label="任何類別" name="item0"/>
- <combo_box.item label="Linden Location" name="item1"/>
+ <combo_box.item label="æž—ç™»ä½ç½®" name="item1"/>
<combo_box.item label="完全æˆäºº" name="item2"/>
<combo_box.item label="è—術與文化" name="item3"/>
<combo_box.item label="商業" name="item4"/>
<combo_box.item label="教育" name="item5"/>
<combo_box.item label="éŠæˆ²" name="item6"/>
<combo_box.item label="èšæœƒæ‰€" name="item7"/>
- <combo_box.item label="新手å‹å–„" name="item8"/>
- <combo_box.item label="公園與自然" name="item9"/>
+ <combo_box.item label="歡迎新手光臨" name="item8"/>
+ <combo_box.item label="公園與自然景觀" name="item9"/>
<combo_box.item label="ä½å®…" name="item10"/>
- <combo_box.item label="採購" name="item11"/>
- <combo_box.item label="Rental" name="item13"/>
- <combo_box.item label="Other" name="item12"/>
+ <combo_box.item label="購物" name="item11"/>
+ <combo_box.item label="出租" name="item13"/>
+ <combo_box.item label="其他" name="item12"/>
</combo_box>
<combo_box name="land category">
<combo_box.item label="任何類別" name="item0"/>
- <combo_box.item label="Linden Location" name="item1"/>
+ <combo_box.item label="æž—ç™»ä½ç½®" name="item1"/>
<combo_box.item label="è—術與文化" name="item3"/>
<combo_box.item label="商業" name="item4"/>
<combo_box.item label="教育" name="item5"/>
<combo_box.item label="éŠæˆ²" name="item6"/>
<combo_box.item label="èšæœƒæ‰€" name="item7"/>
- <combo_box.item label="新手å‹å–„" name="item8"/>
- <combo_box.item label="公園與自然" name="item9"/>
+ <combo_box.item label="歡迎新手光臨" name="item8"/>
+ <combo_box.item label="公園與自然景觀" name="item9"/>
<combo_box.item label="ä½å®…" name="item10"/>
- <combo_box.item label="採購" name="item11"/>
- <combo_box.item label="Rental" name="item13"/>
- <combo_box.item label="Other" name="item12"/>
+ <combo_box.item label="購物" name="item11"/>
+ <combo_box.item label="出租" name="item13"/>
+ <combo_box.item label="其他" name="item12"/>
</combo_box>
<check_box label="é©åº¦æˆäººå…§å®¹" name="MatureCheck" tool_tip=" "/>
<text name="Snapshot:">
快照:
</text>
- <texture_picker name="snapshot_ctrl" tool_tip="點擊以挑é¸åœ–åƒ"/>
+ <texture_picker name="snapshot_ctrl" tool_tip="點按以挑é¸åœ–片"/>
+ <text name="allow_label5">
+ 其他地段的化身å¯ä»¥çœ‹è¦‹æœ¬åœ°æ®µè£¡çš„化身,並與之交談
+ </text>
+ <check_box label="察看化身" name="SeeAvatarsCheck" tool_tip="å…許其他地段的化身看到本地段包括你在內的化身,並å¯äº’相交談。"/>
<text name="landing_point">
登陸點:[LANDING]
</text>
- <button label="設定" label_selected="設定" name="Set" tool_tip="Sets the landing point where visitors arrive. Sets to your avatar&apos;s location inside this parcel."/>
+ <button label="設定" label_selected="設定" name="Set" tool_tip="設定訪客登陸地點。 設定你的化身在此地段內的ä½ç½®ã€‚"/>
<button label="清除" label_selected="清除" name="Clear" tool_tip="清除登陸點"/>
<text name="Teleport Routing: ">
瞬間傳é€è·¯å¾‘:
</text>
- <combo_box name="landing type" tool_tip="Teleport Routing -- select how to handle teleports onto your land">
- <combo_box.item label="Blocked" name="Blocked"/>
- <combo_box.item label="Landing Point" name="LandingPoint"/>
- <combo_box.item label="Anywhere" name="Anywhere"/>
+ <combo_box name="landing type" tool_tip="瞬間傳é€ç¹žè·¯ -- 設定如何處ç†å‰å¾€ä½ åœŸåœ°çš„瞬間傳é€">
+ <combo_box.item label="å°éŽ–çš„" name="Blocked"/>
+ <combo_box.item label="登陸點" name="LandingPoint"/>
+ <combo_box.item label="任何地點" name="Anywhere"/>
</combo_box>
</panel>
- <panel label="MEDIA" name="land_media_panel">
+ <panel label="媒體" name="land_media_panel">
<text name="with media:">
類型:
</text>
- <combo_box name="media type" tool_tip="Specify if the URL is a movie, web page, or other media"/>
+ <combo_box name="media type" tool_tip="指明這 URL 是影片ã€ç¶²é é‚„是其他媒體類型"/>
<text name="at URL:">
首é ï¼š
</text>
@@ -394,27 +397,27 @@ Only large parcels can be listed in search.
<text name="Description:">
æ述:
</text>
- <line_editor name="url_description" tool_tip="Text displayed next to play/load button"/>
+ <line_editor name="url_description" tool_tip="播放 / 載入按鈕æ—顯示的文字"/>
<text name="Media texture:">
å–代æ質:
</text>
- <texture_picker name="media texture" tool_tip="點擊以挑é¸åœ–åƒ"/>
+ <texture_picker name="media texture" tool_tip="點按以挑é¸åœ–片"/>
<text name="replace_texture_help">
- Objects using this texture will show the movie or web page after you click the play arrow. Select the thumbnail to choose a different texture.
+ 使用此æ質的物件,將在你點按「播放ã€ç®­é ­å¾Œæ’­æ”¾å½±ç‰‡æˆ–顯示網é ã€‚ é¸å–縮圖å³å¯é¸æ“‡ä¸åŒçš„æ質。
</text>
- <check_box label="自動縮放" name="media_auto_scale" tool_tip="Checking this option will scale the content for this parcel automatically. It may be slightly slower and lower quality visually but no other texture scaling or alignment will be required."/>
- <text name="media_size" tool_tip="Size to render Web media, leave 0 for default.">
+ <check_box label="自動縮放" name="media_auto_scale" tool_tip="勾é¸æ­¤é¸é …將會在此地段自動變更內容的比例。 速度å¯èƒ½ç¨æ…¢ï¼Œè¦–覺效果å¯èƒ½ç•¥éœï¼Œä½†ä¸éœ€è¦èª¿æ•´å…¶ä»–æ質的比例或加以å°é½Šã€‚"/>
+ <text name="media_size" tool_tip="網上媒體的顯示尺寸,設 0 將採用é è¨­å€¼ã€‚">
尺寸:
</text>
- <spinner name="media_size_width" tool_tip="Size to render Web media, leave 0 for default."/>
- <spinner name="media_size_height" tool_tip="Size to render Web media, leave 0 for default."/>
+ <spinner name="media_size_width" tool_tip="網上媒體的顯示尺寸,設 0 將採用é è¨­å€¼ã€‚"/>
+ <spinner name="media_size_height" tool_tip="網上媒體的顯示尺寸,設 0 將採用é è¨­å€¼ã€‚"/>
<text name="pixels">
åƒç´ 
</text>
<text name="Options:">
é¸é …:
</text>
- <check_box label="Loop" name="media_loop" tool_tip="Play media in a loop. When the media has finished playing, it will restart from the beginning."/>
+ <check_box label="連續" name="media_loop" tool_tip="連續播放媒體。 媒體播放çµæŸå¾Œï¼Œæœƒå¾žé ­ç¹¼çºŒæ’­æ”¾ã€‚"/>
</panel>
<panel label="è²éŸ³" name="land_audio_panel">
<text name="MusicURL:">
@@ -423,45 +426,45 @@ Only large parcels can be listed in search.
<text name="Sound:">
è²éŸ³ï¼š
</text>
- <check_box label="Restrict gesture and object sounds to this parcel" name="check sound local"/>
+ <check_box label="將姿勢和物件的è²éŸ³é™åˆ¶æ–¼æ­¤åœ°æ®µ" name="check sound local"/>
+ <text name="Avatar Sounds:">
+ 化身è²éŸ³ï¼š
+ </text>
+ <check_box label="任何人" name="all av sound check"/>
+ <check_box label="群組" name="group av sound check"/>
<text name="Voice settings:">
- Voice:
+ 語音:
</text>
- <check_box label="Enable Voice" name="parcel_enable_voice_channel"/>
- <check_box label="Enable Voice (established by the Estate)" name="parcel_enable_voice_channel_is_estate_disabled"/>
- <check_box label="Restrict Voice to this parcel" name="parcel_enable_voice_channel_local"/>
+ <check_box label="啟用語音" name="parcel_enable_voice_channel"/>
+ <check_box label="啟用è²éŸ³ï¼ˆç”±é ˜åœ°æ‰€ç¢ºç«‹ï¼‰" name="parcel_enable_voice_channel_is_estate_disabled"/>
+ <check_box label="å°‡è²éŸ³é™åˆ¶æ–¼æ­¤åœ°æ®µ" name="parcel_enable_voice_channel_local"/>
</panel>
- <panel label="ACCESS" name="land_access_panel">
+ <panel label="出入許å¯" name="land_access_panel">
<panel.string name="access_estate_defined">
- (Defined by the Estate)
- </panel.string>
- <panel.string name="allow_public_access">
- Allow Public Access ([MATURITY]) (Note: Unchecking this will create ban lines)
+ (由領地定義)
</panel.string>
<panel.string name="estate_override">
- One or more of these options is set at the estate level
+ 至少一個é¸é …在領地的層級設定
</panel.string>
- <text name="Limit access to this parcel to:">
- 出入此地段
- </text>
+ <check_box label="å…許公開出入(若未勾é¸ï¼Œå°‡è¨­ç«‹ç¦è¶Šç·šï¼‰" name="public_access"/>
<text name="Only Allow">
- Restrict Access to Residents verified by:
+ 僅å…許符åˆä»¥ä¸‹æ¢ä»¶çš„居民進入:
</text>
- <check_box label="Payment Information on File [ESTATE_PAYMENT_LIMIT]" name="limit_payment" tool_tip="Ban unidentified Residents."/>
- <check_box label="年齡驗證 [ESTATE_AGE_LIMIT]" name="limit_age_verified" tool_tip="Ban Residents who have not verified their age. See the [SUPPORT_SITE] for more information."/>
+ <check_box label="å·²é ç•™ä»˜æ¬¾è³‡æ–™ [ESTATE_PAYMENT_LIMIT]" name="limit_payment" tool_tip="å±…æ°‘å¿…é ˆæ供付款資料æ‰èƒ½é€²å…¥é€™åœ°æ®µã€‚ åƒé–± [SUPPORT_SITE] ç²å–進一步資訊。"/>
+ <check_box label="年滿 18 æ­² [ESTATE_AGE_LIMIT]" name="limit_age_verified" tool_tip="居民必須年滿 18 æ­²æ‰èƒ½é€²å…¥é€™åœ°æ®µã€‚ åƒé–± [SUPPORT_SITE] ç²å–進一步資訊。"/>
<check_box label="å…許出入的群組:[GROUP]" name="GroupCheck" tool_tip="設定群組於一般é ç±¤ã€‚"/>
<check_box label="出售通行權給:" name="PassCheck" tool_tip="å…許暫時出入這個地段"/>
<combo_box name="pass_combo">
- <combo_box.item label="Anyone" name="Anyone"/>
+ <combo_box.item label="任何人" name="Anyone"/>
<combo_box.item label="群組" name="Group"/>
</combo_box>
- <spinner label="Price in L$:" name="PriceSpin"/>
- <spinner label="Hours of access:" name="HoursSpin"/>
+ <spinner label="價格(L$):" name="PriceSpin"/>
+ <spinner label="出入時間:" name="HoursSpin"/>
<panel name="Allowed_layout_panel">
- <text label="Always Allow" name="AllowedText">
- Allowed Residents
+ <text label="æ°¸é å…許" name="AllowedText">
+ å…許的居民
</text>
- <name_list name="AccessList" tool_tip="([LISTED] listed, [MAX] max)"/>
+ <name_list name="AccessList" tool_tip="(已列入 [LISTED],最多å¯åˆ— [MAX])"/>
<button label="添加" name="add_allowed"/>
<button label="移除" label_selected="移除" name="remove_allowed"/>
</panel>
@@ -469,7 +472,7 @@ Only large parcels can be listed in search.
<text label="ç¦æ­¢" name="BanCheck">
被å°éŽ–çš„å±…æ°‘
</text>
- <name_list name="BannedList" tool_tip="([LISTED] listed, [MAX] max)"/>
+ <name_list name="BannedList" tool_tip="(已列入 [LISTED],最多å¯åˆ— [MAX])"/>
<button label="添加" name="add_banned"/>
<button label="移除" label_selected="移除" name="remove_banned"/>
</panel>
diff --git a/indra/newview/skins/default/xui/zh/floater_activeim.xml b/indra/newview/skins/default/xui/zh/floater_activeim.xml
index 93017bf5b2..b148ca8eb4 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_activeim.xml
+++ b/indra/newview/skins/default/xui/zh/floater_activeim.xml
@@ -1,2 +1,2 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_activeim" title="ACTIVE IM"/>
+<floater name="floater_activeim" title="進行中的 IM"/>
diff --git a/indra/newview/skins/default/xui/zh/floater_animation_anim_preview.xml b/indra/newview/skins/default/xui/zh/floater_animation_anim_preview.xml
new file mode 100755
index 0000000000..76cb9079c4
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/floater_animation_anim_preview.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="Anim Preview" title="ANIMATION.ANIM">
+ <text name="name_label">
+ å稱:
+ </text>
+ <text name="description_label">
+ æ述:
+ </text>
+ <button label="上傳(L$[AMOUNT])" name="ok_btn"/>
+ <button label="å–消" label_selected="å–消" name="cancel_btn"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_animation_bvh_preview.xml b/indra/newview/skins/default/xui/zh/floater_animation_bvh_preview.xml
new file mode 100755
index 0000000000..ffb0de8a68
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/floater_animation_bvh_preview.xml
@@ -0,0 +1,186 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="Animation Preview">
+ <floater.string name="failed_to_initialize">
+ 動作åˆå§‹åŒ–失敗
+ </floater.string>
+ <floater.string name="anim_too_long">
+ 動作檔長度為 [LENGTH] 秒。
+
+動作檔長度最多å¯ç‚º [MAX_LENGTH] 秒。
+ </floater.string>
+ <floater.string name="failed_file_read">
+ 無法讀å–動作檔。
+
+[STATUS]
+ </floater.string>
+ <floater.string name="E_ST_OK">
+ 確定
+ </floater.string>
+ <floater.string name="E_ST_EOF">
+ 檔案çµå°¾ä¸æ­£å¸¸ã€‚
+ </floater.string>
+ <floater.string name="E_ST_NO_CONSTRAINT">
+ 無法讀å–ç´„æŸå®šç¾©ã€‚
+ </floater.string>
+ <floater.string name="E_ST_NO_FILE">
+ 無法開啟 BVH 檔案。
+ </floater.string>
+ <floater.string name="E_ST_NO_HIER">
+ HIERARCHY 檔頭無效。
+ </floater.string>
+ <floater.string name="E_ST_NO_JOINT">
+ 找ä¸åˆ° ROOT 或 JOINT。
+ </floater.string>
+ <floater.string name="E_ST_NO_NAME">
+ 無法å–å¾— JOINT å稱。
+ </floater.string>
+ <floater.string name="E_ST_NO_OFFSET">
+ 無法尋找ä½ç§»ã€‚
+ </floater.string>
+ <floater.string name="E_ST_NO_CHANNELS">
+ 找ä¸åˆ°é »é“。
+ </floater.string>
+ <floater.string name="E_ST_NO_ROTATION">
+ 無法å–得旋轉åºã€‚
+ </floater.string>
+ <floater.string name="E_ST_NO_AXIS">
+ 無法å–得旋轉軸。
+ </floater.string>
+ <floater.string name="E_ST_NO_MOTION">
+ 找ä¸åˆ°å‹•ä½œã€‚
+ </floater.string>
+ <floater.string name="E_ST_NO_FRAMES">
+ 無法å–得幀數。
+ </floater.string>
+ <floater.string name="E_ST_NO_FRAME_TIME">
+ 無法å–得幀時間。
+ </floater.string>
+ <floater.string name="E_ST_NO_POS">
+ 無法å–å¾—ä½ç½®å€¼ã€‚
+ </floater.string>
+ <floater.string name="E_ST_NO_ROT">
+ 無法å–得旋轉值。
+ </floater.string>
+ <floater.string name="E_ST_NO_XLT_FILE">
+ 無法開啟平移檔案。
+ </floater.string>
+ <floater.string name="E_ST_NO_XLT_HEADER">
+ 無法讀å–平移檔頭。
+ </floater.string>
+ <floater.string name="E_ST_NO_XLT_NAME">
+ 無法讀å–平移å稱。
+ </floater.string>
+ <floater.string name="E_ST_NO_XLT_IGNORE">
+ 無法讀å–平移忽略值。
+ </floater.string>
+ <floater.string name="E_ST_NO_XLT_RELATIVE">
+ 無法讀å–平移相å°å€¼ã€‚
+ </floater.string>
+ <floater.string name="E_ST_NO_XLT_OUTNAME">
+ 無法讀å–平移輸出å稱。
+ </floater.string>
+ <floater.string name="E_ST_NO_XLT_MATRIX">
+ 無法讀å–平移矩陣。
+ </floater.string>
+ <floater.string name="E_ST_NO_XLT_MERGECHILD">
+ 無法å–å¾— mergechild å稱。
+ </floater.string>
+ <floater.string name="E_ST_NO_XLT_MERGEPARENT">
+ 無法å–å¾— mergeparent å稱。
+ </floater.string>
+ <floater.string name="E_ST_NO_XLT_PRIORITY">
+ 無法å–得優先值。
+ </floater.string>
+ <floater.string name="E_ST_NO_XLT_LOOP">
+ 無法å–得迴圈值。
+ </floater.string>
+ <floater.string name="E_ST_NO_XLT_EASEIN">
+ 無法å–å¾— easeIn 值。
+ </floater.string>
+ <floater.string name="E_ST_NO_XLT_EASEOUT">
+ 無法å–å¾— easeOut 值。
+ </floater.string>
+ <floater.string name="E_ST_NO_XLT_HAND">
+ 無法å–å¾— hand morph 值。
+ </floater.string>
+ <floater.string name="E_ST_NO_XLT_EMOTE">
+ 無法讀å–表情符號å稱。
+ </floater.string>
+ <floater.string name="E_ST_BAD_ROOT">
+ root joint å稱ä¸æ­£ç¢ºï¼Œä½¿ç”¨ &quot;hip&quot;。
+ </floater.string>
+ <text name="name_label">
+ å稱:
+ </text>
+ <text name="description_label">
+ æ述:
+ </text>
+ <spinner label="優先度" name="priority" tool_tip="其他動作的控制å¯è¢«æ­¤å‹•ä½œå¼·è¡Œå–代"/>
+ <check_box label="連續" name="loop_check" tool_tip="讓此動作ä¸æ–·é‡è¦†æ¼”ç¹¹"/>
+ <spinner label="å…¥(%)" name="loop_in_point" tool_tip="設定動作中é‡è¦†æ¼”繹的起始點"/>
+ <spinner label="出(%)" name="loop_out_point" tool_tip="設定動作中é‡è¦†æ¼”繹的çµæŸé»ž"/>
+ <text name="hand_label">
+ 手部姿勢
+ </text>
+ <combo_box name="hand_pose_combo" tool_tip="控制動作演繹時雙手的姿勢">
+ <combo_box.item label="張開" name="Spread"/>
+ <combo_box.item label="放鬆" name="Relaxed"/>
+ <combo_box.item label="雙手伸出指頭" name="PointBoth"/>
+ <combo_box.item label="拳頭" name="Fist"/>
+ <combo_box.item label="左邊放鬆" name="RelaxedLeft"/>
+ <combo_box.item label="左邊伸指" name="PointLeft"/>
+ <combo_box.item label="左邊æ¡æ‹³" name="FistLeft"/>
+ <combo_box.item label="å³é‚Šæ”¾é¬†" name="RelaxedRight"/>
+ <combo_box.item label="å³é‚Šä¼¸æŒ‡" name="PointRight"/>
+ <combo_box.item label="å³é‚Šæ¡æ‹³" name="FistRight"/>
+ <combo_box.item label="å³æ‰‹æ•¬ç¦®" name="SaluteRight"/>
+ <combo_box.item label="打字" name="Typing"/>
+ <combo_box.item label="å³æ‰‹æ¯”出和平手勢" name="PeaceRight"/>
+ </combo_box>
+ <text name="emote_label">
+ 表情
+ </text>
+ <combo_box name="emote_combo" tool_tip="控制動作演繹時臉部的姿態">
+ <item label="(無)" name="[None]" value=""/>
+ <item label="å¼µå£å¶å–Šè²Œ" name="Aaaaah" value="å¼µå£å¶å–Šè²Œ"/>
+ <item label="害怕" name="Afraid" value="害怕"/>
+ <item label="生氣" name="Angry" value="生氣"/>
+ <item label="燦爛笑容" name="BigSmile" value="燦爛笑容"/>
+ <item label="ç„¡èŠ" name="Bored" value="ç„¡èŠ"/>
+ <item label="å“­æ³£" name="Cry" value="å“­æ³£"/>
+ <item label="鄙視" name="Disdain" value="鄙視"/>
+ <item label="å°·å°¬" name="Embarrassed" value="å°·å°¬"/>
+ <item label="皺眉" name="Frown" value="皺眉"/>
+ <item label="親å»" name="Kiss" value="親å»"/>
+ <item label="笑" name="Laugh" value="笑"/>
+ <item label="嫌惡貌" name="Plllppt" value="嫌惡貌"/>
+ <item label="作å™" name="Repulsed" value="作å™"/>
+ <item label="傷心" name="Sad" value="傷心"/>
+ <item label="è³è³è‚©" name="Shrug" value="è³è³è‚©"/>
+ <item label="微笑" name="Smile" value="微笑"/>
+ <item label="驚喜" name="Surprise" value="驚喜"/>
+ <item label="眨眼" name="Wink" value="眨眼"/>
+ <item label="擔心" name="Worry" value="擔心"/>
+ </combo_box>
+ <text name="preview_label">
+ é è¦½â€¦
+ </text>
+ <combo_box name="preview_base_anim" tool_tip="用這個來測試你的化身從一般動作轉入動作演繹時的情æ³ã€‚">
+ <item label="站立" name="Standing" value="站立"/>
+ <item label="步行中" name="Walking" value="步行中"/>
+ <item label="åè‘—" name="Sitting" value="åè‘—"/>
+ <item label="飛行" name="Flying" value="飛行"/>
+ </combo_box>
+ <spinner label="淡入(秒)" name="ease_in_time" tool_tip="動作攙混æ¤å…¥çš„時間長度(秒)"/>
+ <spinner label="淡出(秒)" name="ease_out_time" tool_tip="動作攙混淡出的時間長度(秒)"/>
+ <button name="play_btn" tool_tip="播放你的動作"/>
+ <button name="pause_btn" tool_tip="æš«åœä½ çš„å‹•åš"/>
+ <button name="stop_btn" tool_tip="åœæ­¢æ’­æ”¾å‹•ä½œ"/>
+ <text name="bad_animation_text">
+ 無法讀å–動作檔。
+
+我們建議採用由 Poser 4 匯出的 BVH 檔案格å¼ã€‚
+ </text>
+ <button label="上傳(L$[AMOUNT])" name="ok_btn"/>
+ <button label="å–消" name="cancel_btn"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_animation_preview.xml b/indra/newview/skins/default/xui/zh/floater_animation_preview.xml
deleted file mode 100644
index c5e2eac446..0000000000
--- a/indra/newview/skins/default/xui/zh/floater_animation_preview.xml
+++ /dev/null
@@ -1,186 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Animation Preview">
- <floater.string name="failed_to_initialize">
- Failed to initialize motion
- </floater.string>
- <floater.string name="anim_too_long">
- Animation file is [LENGTH] seconds in length.
-
-Maximum animation length is [MAX_LENGTH] seconds.
- </floater.string>
- <floater.string name="failed_file_read">
- 無法讀å–動作檔。
-
-[STATUS]
- </floater.string>
- <floater.string name="E_ST_OK">
- 確定
- </floater.string>
- <floater.string name="E_ST_EOF">
- Premature end of file.
- </floater.string>
- <floater.string name="E_ST_NO_CONSTRAINT">
- Cannot read constraint definition.
- </floater.string>
- <floater.string name="E_ST_NO_FILE">
- 無法開啟 BVH 檔案。
- </floater.string>
- <floater.string name="E_ST_NO_HIER">
- Invalid HIERARCHY header.
- </floater.string>
- <floater.string name="E_ST_NO_JOINT">
- Cannot find ROOT or JOINT.
- </floater.string>
- <floater.string name="E_ST_NO_NAME">
- Cannot get JOINT name.
- </floater.string>
- <floater.string name="E_ST_NO_OFFSET">
- 無法尋找ä½ç§»ã€‚
- </floater.string>
- <floater.string name="E_ST_NO_CHANNELS">
- Cannot find CHANNELS.
- </floater.string>
- <floater.string name="E_ST_NO_ROTATION">
- Cannot get rotation order.
- </floater.string>
- <floater.string name="E_ST_NO_AXIS">
- Cannot get rotation axis.
- </floater.string>
- <floater.string name="E_ST_NO_MOTION">
- Cannot find MOTION.
- </floater.string>
- <floater.string name="E_ST_NO_FRAMES">
- Cannot get number of frames.
- </floater.string>
- <floater.string name="E_ST_NO_FRAME_TIME">
- Cannot get frame time.
- </floater.string>
- <floater.string name="E_ST_NO_POS">
- Cannot get position values.
- </floater.string>
- <floater.string name="E_ST_NO_ROT">
- Cannot get rotation values.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_FILE">
- Cannot open translation file.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_HEADER">
- Cannot read translation header.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_NAME">
- Cannot read translation names.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_IGNORE">
- Cannot read translation ignore value.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_RELATIVE">
- Cannot read translation relative value.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_OUTNAME">
- Cannot read translation outname value.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_MATRIX">
- Cannot read translation matrix.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_MERGECHILD">
- Cannot get mergechild name.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_MERGEPARENT">
- Cannot get mergeparent name.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_PRIORITY">
- Cannot get priority value.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_LOOP">
- Cannot get loop value.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_EASEIN">
- Cannot get easeIn values.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_EASEOUT">
- Cannot get easeOut values.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_HAND">
- Cannot get hand morph value.
- </floater.string>
- <floater.string name="E_ST_NO_XLT_EMOTE">
- Cannot read emote name.
- </floater.string>
- <floater.string name="E_ST_BAD_ROOT">
- Incorrect root joint name, use &quot;hip&quot;.
- </floater.string>
- <text name="name_label">
- å稱:
- </text>
- <text name="description_label">
- æ述:
- </text>
- <spinner label="優先度" name="priority" tool_tip="Controls which other animations can be overridden by this animation"/>
- <check_box label="Loop" name="loop_check" tool_tip="Makes this animation loop"/>
- <spinner label="In(%)" name="loop_in_point" tool_tip="Sets point in animation that looping returns to"/>
- <spinner label="Out(%)" name="loop_out_point" tool_tip="Sets point in animation that ends a loop"/>
- <text name="hand_label">
- Hand Pose
- </text>
- <combo_box name="hand_pose_combo" tool_tip="Controls what hands do during animation">
- <combo_box.item label="Spread" name="Spread"/>
- <combo_box.item label="Relaxed" name="Relaxed"/>
- <combo_box.item label="Point Both" name="PointBoth"/>
- <combo_box.item label="Fist" name="Fist"/>
- <combo_box.item label="Relaxed Left" name="RelaxedLeft"/>
- <combo_box.item label="Point Left" name="PointLeft"/>
- <combo_box.item label="Fist Left" name="FistLeft"/>
- <combo_box.item label="Relaxed Right" name="RelaxedRight"/>
- <combo_box.item label="Point Right" name="PointRight"/>
- <combo_box.item label="Fist Right" name="FistRight"/>
- <combo_box.item label="Salute Right" name="SaluteRight"/>
- <combo_box.item label="Typing" name="Typing"/>
- <combo_box.item label="Peace Right" name="PeaceRight"/>
- </combo_box>
- <text name="emote_label">
- Expression
- </text>
- <combo_box name="emote_combo" tool_tip="Controls what face does during animation">
- <item label="(無)" name="[None]" value=""/>
- <item label="Aaaaah" name="Aaaaah" value="Aaaaah"/>
- <item label="Afraid" name="Afraid" value="Afraid"/>
- <item label="Angry" name="Angry" value="Angry"/>
- <item label="Big Smile" name="BigSmile" value="Big Smile"/>
- <item label="Bored" name="Bored" value="Bored"/>
- <item label="Cry" name="Cry" value="Cry"/>
- <item label="Disdain" name="Disdain" value="Disdain"/>
- <item label="Embarrassed" name="Embarrassed" value="Embarrassed"/>
- <item label="Frown" name="Frown" value="Frown"/>
- <item label="Kiss" name="Kiss" value="Kiss"/>
- <item label="Laugh" name="Laugh" value="Laugh"/>
- <item label="Plllppt" name="Plllppt" value="Plllppt"/>
- <item label="Repulsed" name="Repulsed" value="Repulsed"/>
- <item label="Sad" name="Sad" value="Sad"/>
- <item label="Shrug" name="Shrug" value="Shrug"/>
- <item label="Smile" name="Smile" value="Smile"/>
- <item label="Surprise" name="Surprise" value="Surprise"/>
- <item label="Wink" name="Wink" value="Wink"/>
- <item label="Worry" name="Worry" value="Worry"/>
- </combo_box>
- <text name="preview_label">
- Preview while
- </text>
- <combo_box name="preview_base_anim" tool_tip="Use this to test your animation behavior while your avatar performs common actions.">
- <item label="Standing" name="Standing" value="Standing"/>
- <item label="Walking" name="Walking" value="Walking"/>
- <item label="Sitting" name="Sitting" value="Sitting"/>
- <item label="飛行" name="Flying" value="飛行"/>
- </combo_box>
- <spinner label="淡入(秒)" name="ease_in_time" tool_tip="Amount of time (in seconds) over which animations blends in"/>
- <spinner label="淡出(秒)" name="ease_out_time" tool_tip="Amount of time (in seconds) over which animations blends out"/>
- <button name="play_btn" tool_tip="播放你的動作"/>
- <button name="pause_btn" tool_tip="æš«åœä½ çš„å‹•åš"/>
- <button name="stop_btn" tool_tip="Stop animation playback"/>
- <text name="bad_animation_text">
- Unable to read animation file.
-
-We recommend BVH files exported from Poser 4.
- </text>
- <button label="上傳(L$[AMOUNT])" name="ok_btn"/>
- <button label="å–消" name="cancel_btn"/>
-</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_auction.xml b/indra/newview/skins/default/xui/zh/floater_auction.xml
index b1862bc582..1b589a92cc 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_auction.xml
+++ b/indra/newview/skins/default/xui/zh/floater_auction.xml
@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_auction" title="START LINDEN LAND SALE">
+<floater name="floater_auction" title="開始 Linden 土地出售">
<floater.string name="already for sale">
- You cannot auction parcels which are already for sale.
+ 出售中的地段無法進行æ‹è³£ã€‚
</floater.string>
- <check_box initial_value="true" label="Include yellow selection fence" name="fence_check"/>
- <button label="Snapshot" label_selected="Snapshot" name="snapshot_btn"/>
- <button label="Sell to Anyone" label_selected="Sell to Anyone" name="sell_to_anyone_btn"/>
+ <check_box initial_value="true" label="包括黃色åœç·š" name="fence_check"/>
+ <button label="å¿«ç…§" label_selected="å¿«ç…§" name="snapshot_btn"/>
+ <button label="出售給任何人" label_selected="出售給任何人" name="sell_to_anyone_btn"/>
<button label="清除設定" label_selected="清除設定" name="reset_parcel_btn"/>
- <button label="Start Auction" label_selected="Start Auction" name="start_auction_btn"/>
+ <button label="開始æ‹è³£" label_selected="開始æ‹è³£" name="start_auction_btn"/>
</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_autoreplace.xml b/indra/newview/skins/default/xui/zh/floater_autoreplace.xml
new file mode 100755
index 0000000000..4ee07e6295
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/floater_autoreplace.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="autoreplace_floater" title="自動å–代設定">
+ <check_box label="啟用自動å–代" name="autoreplace_enable" tool_tip="在輸入èŠå¤©å…§å®¹çš„åŒæ™‚,將輸入的關éµå­—代æ›ç‚ºç›¸æ‡‰çš„å–代文字。"/>
+ <button label="匯入清單…" name="autoreplace_import_list" tool_tip="從檔案載入先å‰åŒ¯å‡ºéŽçš„清單。"/>
+ <button label="匯出清單…" name="autoreplace_export_list" tool_tip="將所é¸æ¸…單儲存到檔案以便和他人分享。"/>
+ <button label="新的清單…" name="autoreplace_new_list" tool_tip="新建一個清單。"/>
+ <button label="刪除清單" name="autoreplace_delete_list" tool_tip="刪除所é¸æ¸…單。"/>
+ <button name="autoreplace_list_up" tool_tip="æ高此清單的優先次åºã€‚"/>
+ <button name="autoreplace_list_down" tool_tip="é™ä½Žæ­¤æ¸…單的優先次åºã€‚"/>
+ <scroll_list name="autoreplace_list_replacements">
+ <scroll_list.columns label="é—œéµå­—" name="keyword"/>
+ <scroll_list.columns label="å–代文字" name="replacement"/>
+ </scroll_list>
+ <button label="添加..." name="autoreplace_add_entry"/>
+ <button label="移除" name="autoreplace_delete_entry"/>
+ <button label="儲存項目" name="autoreplace_save_entry" tool_tip="儲存此項目。"/>
+ <button label="儲存變更" name="autoreplace_save_changes" tool_tip="儲存所有變更。"/>
+ <button label="å–消" name="autoreplace_cancel" tool_tip="放棄所有變更。"/>
+</floater>
+<!--
+ <text
+ top_pad="10"
+ left="10"
+ height="16"
+ width="260"
+ follows="left|top"
+ halign="center"
+ mouse_opaque="true"
+ name="autoreplace_text2">
+ Entries
+ </text>
+-->
diff --git a/indra/newview/skins/default/xui/zh/floater_avatar.xml b/indra/newview/skins/default/xui/zh/floater_avatar.xml
new file mode 100755
index 0000000000..55b1a95a41
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/floater_avatar.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="Avatar" title="é¸æ“‡ä¸€å€‹åŒ–身"/>
diff --git a/indra/newview/skins/default/xui/zh/floater_avatar_picker.xml b/indra/newview/skins/default/xui/zh/floater_avatar_picker.xml
index 7e2d74c728..c19369c859 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_avatar_picker.xml
+++ b/indra/newview/skins/default/xui/zh/floater_avatar_picker.xml
@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="avatarpicker" title="挑é¸å±…æ°‘">
<floater.string name="not_found">
- &apos;[TEXT]&apos; not found
+ 查無「[TEXT]ã€
</floater.string>
<floater.string name="no_one_near">
- No one near
+ 附近無人
</floater.string>
<floater.string name="no_results">
- No results
+ 沒有çµæžœ
</floater.string>
<floater.string name="searching">
æœå°‹ä¸­...
@@ -21,9 +21,9 @@
<tab_container name="ResidentChooserTabs">
<panel label="æœå°‹" name="SearchPanel">
<text name="InstructSearchResidentName">
- Type part of a person&apos;s name:
+ éµå…¥äººå的一部分:
</text>
- <button label="Go" label_selected="Go" name="Find"/>
+ <button label="å‰å¾€" label_selected="å‰å¾€" name="Find"/>
<scroll_list name="SearchResults">
<columns label="å稱" name="name"/>
<columns label="使用者å稱" name="username"/>
diff --git a/indra/newview/skins/default/xui/zh/floater_avatar_textures.xml b/indra/newview/skins/default/xui/zh/floater_avatar_textures.xml
index 36dae7c798..69309c96de 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_avatar_textures.xml
+++ b/indra/newview/skins/default/xui/zh/floater_avatar_textures.xml
@@ -1,19 +1,19 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="avatar_texture_debug" title="化身æ質">
<floater.string name="InvalidAvatar">
- INVALID AVATAR
+ 無效的化身
</floater.string>
<scroll_container name="profile_scroll">
<panel name="scroll_content_panel">
<text name="label">
- Baked
-Textures
+ 確定產出的
+æ質
</text>
<text name="composite_label">
- Composite
-Textures
+ åˆæˆ
+æ質
</text>
- <button label="Dump IDs to Console" label_selected="Dump" name="Dump"/>
+ <button label="å‚¾å° ID 到控制臺" label_selected="傾å°" name="Dump"/>
<panel name="scroll_content_panel">
<texture_picker label="é ­é«®" name="hair-baked"/>
<texture_picker label="é ­é«®" name="hair_grain"/>
@@ -25,7 +25,7 @@ Textures
<texture_picker label="眼ç›" name="eyes-baked"/>
<texture_picker label="眼ç›" name="eyes_iris"/>
<texture_picker label="眼ç›åŠé€æ˜Ž" name="eyes_alpha"/>
- <texture_picker label="上åŠèº«åŠé€æ˜Ž" name="upper-baked"/>
+ <texture_picker label="上åŠèº«" name="upper-baked"/>
<texture_picker label="上åŠèº«èº«é«”部ä½" name="upper_bodypaint"/>
<texture_picker label="內衣" name="upper_undershirt"/>
<texture_picker label="手套" name="upper_gloves"/>
diff --git a/indra/newview/skins/default/xui/zh/floater_beacons.xml b/indra/newview/skins/default/xui/zh/floater_beacons.xml
index 1613b23e75..83e10804d6 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_beacons.xml
+++ b/indra/newview/skins/default/xui/zh/floater_beacons.xml
@@ -1,22 +1,22 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="beacons" title="BEACONS">
+<floater name="beacons" title="指標">
<panel name="beacons_panel">
<text name="label_show">
- Show :
+ 顯示:
</text>
- <check_box label="Beacons" name="beacons"/>
- <check_box label="Highlights" name="highlights"/>
- <text name="beacon_width_label" tool_tip="Beacon width">
- Width:
+ <check_box label="指標" name="beacons"/>
+ <check_box label="高亮顯示" name="highlights"/>
+ <text name="beacon_width_label" tool_tip="指標寬度">
+ 寬:
</text>
<text name="label_objects">
- For these objects:
+ å°è±¡ç‰©ä»¶ï¼š
</text>
- <check_box label="Physical" name="physical"/>
- <check_box label="Scripted" name="scripted"/>
- <check_box label="Touch only" name="touch_only"/>
- <check_box label="Sound sources" name="sounds"/>
- <check_box label="Particle sources" name="particles"/>
- <check_box label="Media sources" name="moapbeacon"/>
+ <check_box label="物ç†æ€§" name="physical"/>
+ <check_box label="有腳本" name="scripted"/>
+ <check_box label="僅å¯è§¸ç¢°" name="touch_only"/>
+ <check_box label="è²éŸ³ä¾†æº" name="sounds"/>
+ <check_box label="例å­ä¾†æº" name="particles"/>
+ <check_box label="媒體來æº" name="moapbeacon"/>
</panel>
</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_build_options.xml b/indra/newview/skins/default/xui/zh/floater_build_options.xml
index b9d3b6b849..29f36b461c 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_build_options.xml
+++ b/indra/newview/skins/default/xui/zh/floater_build_options.xml
@@ -1,9 +1,32 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="build options floater" title="格線é¸é …">
- <spinner label="格線單ä½ï¼ˆå…¬å°ºï¼‰" name="GridResolution"/>
- <spinner label="Grid Extents (meters)" name="GridDrawSize"/>
+ <floater.string name="grid_screen_text">
+ 螢幕
+ </floater.string>
+ <floater.string name="grid_local_text">
+ 本地
+ </floater.string>
+ <floater.string name="grid_world_text">
+ 世界
+ </floater.string>
+ <floater.string name="grid_reference_text">
+ åƒè€ƒ
+ </floater.string>
+ <floater.string name="grid_attachment_text">
+ 附件
+ </floater.string>
+ <text name="grid_mode_label" tool_tip="格線ä¸é€æ˜Žåº¦">
+ 模å¼
+ </text>
+ <combo_box name="combobox grid mode" tool_tip="é¸æ“‡ç‰©ä»¶å®šä½åƒè€ƒçš„格線尺度類型">
+ <combo_box.item label="世界格線" name="World"/>
+ <combo_box.item label="地方格線" name="Local"/>
+ <combo_box.item label="åƒè€ƒæ ¼ç·š" name="Reference"/>
+ </combo_box>
+ <spinner label="å–®ä½ï¼ˆå…¬å°ºï¼‰" name="GridResolution"/>
+ <spinner label="範åœï¼ˆå…¬å°ºï¼‰" name="GridDrawSize"/>
<check_box label="貼齊至å­å–®ä½" name="GridSubUnit"/>
- <check_box label="View cross-sections" name="GridCrossSection"/>
+ <check_box label="檢視橫剖é¢" name="GridCrossSection"/>
<text name="grid_opacity_label" tool_tip="格線ä¸é€æ˜Žåº¦">
ä¸é€æ˜Žåº¦ï¼š
</text>
diff --git a/indra/newview/skins/default/xui/zh/floater_bulk_perms.xml b/indra/newview/skins/default/xui/zh/floater_bulk_perms.xml
index 660710fb7b..c103ea938f 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_bulk_perms.xml
+++ b/indra/newview/skins/default/xui/zh/floater_bulk_perms.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floaterbulkperms" title="編輯內容物權é™">
+<floater name="floaterbulkperms" title="調整內容物權é™">
<floater.string name="nothing_to_modify_text">
é¸æ“‡æœªåŒ…å«å¯ç·¨è¼¯çš„內容物。
</floater.string>
@@ -24,7 +24,7 @@
<button label="√ 全部" name="check_all"/>
<button label="清除" label_selected="無" name="check_none"/>
<text name="newperms">
- 新內容物權é™
+ 調整內容物權é™ï¼š
</text>
<text name="GroupLabel">
群組:
@@ -33,13 +33,14 @@
<text name="AnyoneLabel">
任何人:
</text>
- <check_box label="覆製" name="everyone_copy"/>
+ <check_box label="æšåº¨" name="everyone_copy"/>
<text name="NextOwnerLabel">
- 下一個æ“有者:
+ 下一個所有人:
</text>
<check_box label="修改" name="next_owner_modify"/>
- <check_box label="覆製" name="next_owner_copy"/>
- <check_box initial_value="true" label="轉移" name="next_owner_transfer" tool_tip="下一個æ“有者能é€å‡ºæˆ–轉售這個物件"/>
- <button label="確定" name="apply"/>
+ <check_box label="æšåº¨" name="next_owner_copy"/>
+ <check_box initial_value="true" label="轉移" name="next_owner_transfer" tool_tip="下一個所有人å¯è´ˆé€æˆ–轉售這個物件"/>
+ <button label="確定" name="ok"/>
+ <button label="套用" name="apply"/>
<button label="å–消" name="close"/>
</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_bumps.xml b/indra/newview/skins/default/xui/zh/floater_bumps.xml
index 2d76a9f831..2d76a9f831 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_bumps.xml
+++ b/indra/newview/skins/default/xui/zh/floater_bumps.xml
diff --git a/indra/newview/skins/default/xui/zh/floater_buy_contents.xml b/indra/newview/skins/default/xui/zh/floater_buy_contents.xml
index 44d3394a52..5e4153de66 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_buy_contents.xml
+++ b/indra/newview/skins/default/xui/zh/floater_buy_contents.xml
@@ -1,19 +1,19 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_buy_contents" title="BUY CONTENTS">
+<floater name="floater_buy_contents" title="購買內容">
<floater.string name="no_copy_text">
- (no copy)
+ (ç¦æ­¢è¤‡è£½ï¼‰
</floater.string>
<floater.string name="no_modify_text">
- (no modify)
+ (ç¦æ­¢ä¿®æ”¹ï¼‰
</floater.string>
<floater.string name="no_transfer_text">
- (no transfer)
+ (ç¦æ­¢è½‰è®“)
</floater.string>
<text name="contains_text">
- [NAME] contains:
+ &lt;nolink&gt;[NAME]&lt;/nolink&gt; å…§å«ï¼š
</text>
<text name="buy_text">
- Buy for L$[AMOUNT] from [NAME]?
+ 是å¦èŠ± L$[AMOUNT] å‘ [NAME] 購買?
</text>
<check_box label="ç«‹å³ç©¿ä¸Šæœè£" name="wear_check"/>
<button label="購買" label_selected="購買" name="buy_btn"/>
diff --git a/indra/newview/skins/default/xui/zh/floater_buy_currency.xml b/indra/newview/skins/default/xui/zh/floater_buy_currency.xml
index 9f6591faf9..fcf2800728 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_buy_currency.xml
+++ b/indra/newview/skins/default/xui/zh/floater_buy_currency.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="buy currency" title="購買 L$">
<floater.string name="buy_currency">
- Buy L$ [LINDENS] for approx. [LOCALAMOUNT]
+ 購買 L$ [LINDENS],所需花費約為 [LOCALAMOUNT]
</floater.string>
<text name="info_need_more">
- 你需è¦æ›´å¤š L$
+ ä½ çš„ L$ ä¸è¶³
</text>
<text name="contacting">
è¯æŽ¥åˆ° LindeX 中...
@@ -31,10 +31,10 @@
以此價格
</text>
<text name="currency_est">
- approx. [LOCALAMOUNT]
+ ç´„åˆ [LOCALAMOUNT]
</text>
<text name="getting_data">
- Estimating...
+ 估算中…
</text>
<text name="buy_action">
[ACTION]
@@ -46,16 +46,16 @@
L$ [AMT]
</text>
<text name="currency_links">
- [http://www.secondlife.com/my/account/payment_method_management.php payment method] | [http://www.secondlife.com/my/account/currency.php currency]
+ [http://www.secondlife.com/my/account/payment_method_management.php 付費方å¼] | [http://www.secondlife.com/my/account/currency.php 幣種]
</text>
<text name="exchange_rate_note">
- Re-enter amount to see the latest exchange rate.
+ é‡æ–°è¼¸å…¥é‡‘é¡å³å¯å¯Ÿçœ‹æœ€æ–°çš„匯率。
</text>
<text name="purchase_warning_repurchase">
- Confirming this purchase only buys L$, not the object.
+ 確èªé€™æ¬¡è³¼è²·åªæ˜¯æ·»è³¼ L$,並éžè³¼è²·ç‰©ä»¶ã€‚
</text>
<text name="purchase_warning_notenough">
- 你並未購買足夠的林登幣,請先添加一些數é‡ã€‚
+ 你購買的林登幣ä¸è¶³ï¼Œ 請增加數é¡ã€‚
</text>
<button label="ç«‹å³è³¼è²·" name="buy_btn"/>
<button label="å–消" name="cancel_btn"/>
diff --git a/indra/newview/skins/default/xui/zh/floater_buy_currency_html.xml b/indra/newview/skins/default/xui/zh/floater_buy_currency_html.xml
index ec700ad7af..ec700ad7af 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_buy_currency_html.xml
+++ b/indra/newview/skins/default/xui/zh/floater_buy_currency_html.xml
diff --git a/indra/newview/skins/default/xui/zh/floater_buy_land.xml b/indra/newview/skins/default/xui/zh/floater_buy_land.xml
index 336d14747d..51bbd6a561 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_buy_land.xml
+++ b/indra/newview/skins/default/xui/zh/floater_buy_land.xml
@@ -1,29 +1,29 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="buy land" title="購買土地">
<floater.string name="can_resell">
- May be resold.
+ 得以å†å‡ºå”®ã€‚
</floater.string>
<floater.string name="can_not_resell">
- May not be resold.
+ ä¸å¾—å†å‡ºå”®ã€‚
</floater.string>
<floater.string name="can_change">
- May be joined or subdivided.
+ 得以åˆä½µæˆ–分割。
</floater.string>
<floater.string name="can_not_change">
- May not be joined or subdivided.
+ ä¸å¾—åˆä½µæˆ–分割。
</floater.string>
<floater.string name="cant_buy_for_group">
- You do not have permission to buy land for your active group.
+ 你沒有權é™ç‚ºä½ ç•¶å‰çš„群組購買土地。
</floater.string>
<floater.string name="no_land_selected">
無土地被é¸æ“‡ã€‚
</floater.string>
<floater.string name="multiple_parcels_selected">
- Multiple different parcels selected.
-Try selecting a smaller area.
+ é¸å–了多個ä¸åŒåœ°æ®µã€‚
+請嘗試é¸å–較å°å€åŸŸã€‚
</floater.string>
<floater.string name="no_permission">
- You do not have permission to buy land for your active group.
+ 你沒有權é™ç‚ºä½ ç•¶å‰çš„群組購買土地。
</floater.string>
<floater.string name="parcel_not_for_sale">
所é¸æ“‡çš„地段ä¸å‡ºå”®ã€‚.
@@ -35,37 +35,37 @@ Try selecting a smaller area.
你已經æ“有這個地段。
</floater.string>
<floater.string name="set_to_sell_to_other">
- The selected parcel is set to sell to another party.
+ 所é¸åœ°æ®µå·²è¨­ç‚ºå¾…售給他人。
</floater.string>
<floater.string name="no_public_land">
- The selected area has no public land.
+ 所é¸å€åŸŸå…§ç„¡å…¬å…±åœŸåœ°ã€‚
</floater.string>
<floater.string name="not_owned_by_you">
- Land owned by another Resident is selected.
-Try selecting a smaller area.
+ é¸å–了å¦ä¸€ä½å±…民所æ“有土地。
+請嘗試é¸å–較å°å€åŸŸã€‚
</floater.string>
<floater.string name="processing">
- Processing your purchase...
+ 正在處ç†ä½ çš„購買…
-(éŽç¨‹é€™å°‡æœƒèŠ±è²»ä¸€åˆ°å…©åˆ†é˜ï¼‰
+(這éŽç¨‹å°‡æœƒèŠ±è²»ä¸€åˆ°å…©åˆ†é˜ã€‚)
</floater.string>
<floater.string name="fetching_error">
- There has been an error while fetching land buying information.
+ æ“·å–購地訊æ¯æ™‚發生錯誤。
</floater.string>
<floater.string name="buying_will">
- Buying this land will:
+ 購買這塊土地後:
</floater.string>
<floater.string name="buying_for_group">
- Buying land for group will:
+ 為群組購買土地後:
</floater.string>
<floater.string name="cannot_buy_now">
- Cannot buy now:
+ ç¾åœ¨ç„¡æ³•è³¼è²·ï¼š
</floater.string>
<floater.string name="not_for_sale">
ä¸å‡ºå”®ï¼š
</floater.string>
<floater.string name="none_needed">
- none needed
+ ä¸éœ€è¦
</floater.string>
<floater.string name="must_upgrade">
你的帳戶必須è¦å‡ç´šæ‰èƒ½æ“有土地。
@@ -77,52 +77,52 @@ Try selecting a smaller area.
ä½ æŒæœ‰ [BUYER] m² 土地。
</floater.string>
<floater.string name="pay_to_for_land">
- Pay L$ [AMOUNT] to [SELLER] for this land
+ 支付 L$ [AMOUNT] 給 [SELLER] 購買這土地
</floater.string>
<floater.string name="buy_for_US">
- Buy L$ [AMOUNT] for approx. [LOCAL_AMOUNT],
+ 購買 L$ [AMOUNT],所需花費約為 [LOCAL_AMOUNT],
</floater.string>
<floater.string name="parcel_meters">
- 這個地段為 [AMOUNT] m²
+ 這個地段有 [AMOUNT] 平方公尺
</floater.string>
<floater.string name="premium_land">
- This land is premium, and will charge as [AMOUNT] m².
+ 這土地屬於高價地段,將計為 [AMOUNT] 平方公尺。
</floater.string>
<floater.string name="discounted_land">
- This land is discounted, and will charge as [AMOUNT] m².
+ 這土地有折扣,將計為 [AMOUNT] 平方公尺。
</floater.string>
<floater.string name="meters_supports_object">
- [AMOUNT] m²
-supports [AMOUNT2] objects
+ [AMOUNT] 平方公尺
+æ”¯æ´ [AMOUNT2] 項物件
</floater.string>
<floater.string name="sold_with_objects">
- sold with objects
+ å«ç‰©ä»¶å‡ºå”®
</floater.string>
<floater.string name="sold_without_objects">
- objects not included
+ ä¸å«ç‰©ä»¶
</floater.string>
<floater.string name="info_price_string">
- L$ [PRICE]
-(L$ [PRICE_PER_SQM]/m²)
+ L$[PRICE]
+(L$ [PRICE_PER_SQM]/平方公尺)
[SOLD_WITH_OBJECTS]
</floater.string>
<floater.string name="insufficient_land_credits">
- The group [GROUP] will need sufficient contributed land use credits to cover this parcel before the purchase will complete.
+ 群組 [GROUP] 需先有足夠的æ地使用é¡åº¦ä¾†æ”¯æ‡‰é€™å€‹åœ°æ®µï¼Œæ‰å¯å®Œæˆè³¼è²·ã€‚
</floater.string>
<floater.string name="have_enough_lindens">
- You have L$ [AMOUNT], which is enough to buy this land.
+ 你有 L$ [AMOUNT],足以購買這土地。
</floater.string>
<floater.string name="not_enough_lindens">
- You have only L$ [AMOUNT], and need L$ [AMOUNT2] more.
+ ä½ åªæœ‰ L$ [AMOUNT],尚缺 L$ [AMOUNT2]。
</floater.string>
<floater.string name="balance_left">
- After the purchase, you will have L$ [AMOUNT] left.
+ 購買後,你將剩餘 L$ [AMOUNT]。
</floater.string>
<floater.string name="balance_needed">
- You need to buy at least L$ [AMOUNT] to afford this land.
+ 你至少必須購買 L$ [AMOUNT] æ‰èƒ½æ·»è³¼é€™åœŸåœ°ã€‚
</floater.string>
<floater.string name="no_parcel_selected">
- (無地段被é¸æ“‡ï¼‰
+ (未é¸æ“‡åœ°æ®µï¼‰
</floater.string>
<text name="region_name_label">
地å€ï¼š
@@ -143,27 +143,27 @@ supports [AMOUNT2] objects
(未知)
</text>
<text name="estate_owner_label">
- 領地æ“有者:
+ 領地所有人:
</text>
<text name="estate_owner_text">
(未知)
</text>
<text name="resellable_changeable_label">
- Purchased land in this region:
+ 在本地å€å·²è³¼åœŸåœ°ï¼š
</text>
<text name="resellable_clause">
- May or may not be resold.
+ 是å¦å¯å†å”®å‡ºã€‚
</text>
<text name="changeable_clause">
- May or may not be joined or subdivided.
+ 是å¦å¯åˆä½µæˆ–分割。
</text>
<text name="covenant_text">
- You must agree to the Estate Covenant:
+ ä½ å¿…é ˆåŒæ„領地契約:
</text>
<text_editor name="covenant_editor">
載入中...
</text_editor>
- <check_box label="I Agree to the Covenant Defined Above." name="agree_covenant"/>
+ <check_box label="我åŒæ„以上所訂契約。" name="agree_covenant"/>
<text name="info_parcel_label">
地段:
</text>
@@ -174,60 +174,60 @@ supports [AMOUNT2] objects
尺寸:
</text>
<text name="info_size">
- 1024 m²
+ 1024 平方公尺
</text>
<text name="info_price_label">
價格:
</text>
<text name="info_price">
L$ 1500
-(L$ 1.1/m²)
-sold with objects
+(L$ 1.1/平方公尺)
+å«ç‰©ä»¶å‡ºå”®
</text>
<text name="info_action">
- Buying this land will:
+ 購買這塊土地後:
</text>
<text name="error_message">
- Something ain&apos;t right.
+ æ怕出å•é¡Œäº†ã€‚
</text>
<button label="å‰å¾€ç¶²ç«™" name="error_web"/>
<text name="account_action">
- Upgrade you to premium membership.
+ 將你å‡ç´šç‚ºä»˜è²»ç”¨æˆ¶
</text>
<text name="account_reason">
- Only premimum members may own land.
+ åªæœ‰ä»˜è²»ç”¨æˆ¶æ‰èƒ½æ“有土地。
</text>
<combo_box name="account_level">
- <combo_box.item label="US$9.95/month, billed monthly" name="US$9.95/month,billedmonthly"/>
- <combo_box.item label="US$7.50/month, billed quarterly" name="US$7.50/month,billedquarterly"/>
- <combo_box.item label="US$6.00/month, billed annually" name="US$6.00/month,billedannually"/>
+ <combo_box.item label="æ¯æœˆ US$9.95,按月支付" name="US$9.95/month,billedmonthly"/>
+ <combo_box.item label="æ¯æœˆ US$7.50,按季支付" name="US$7.50/month,billedquarterly"/>
+ <combo_box.item label="æ¯æœˆ US$6.00,一年支付一次" name="US$6.00/month,billedannually"/>
</combo_box>
<text name="land_use_action">
- Increase your monthly land use fees to US$ 40/month.
+ 將你的æ¯æœˆåœŸåœ°ä½¿ç”¨è²»å¢žåŠ ç‚ºæ¯æœˆ US$ 40。
</text>
<text name="land_use_reason">
- You hold 1309 m² of land.
-This parcel is 512 m² of land.
+ ä½ æŒæœ‰ 1309 平方公尺土地。
+這地段有 512 平方公尺的土地。
</text>
<text name="purchase_action">
- Pay Joe Resident L$ 4000 for the land
+ 支付給居民 Joe L$ 4000 購買土地
</text>
<text name="currency_reason">
- You have L$ 2,100.
+ 你有 L$ 2,100。
</text>
<text name="currency_action">
- Buy additional L$
+ 購買更多 L$
</text>
<line_editor name="currency_amt">
1000
</line_editor>
<text name="currency_est">
- for approx. [LOCAL_AMOUNT]
+ 花費大約 [LOCAL_AMOUNT]
</text>
<text name="currency_balance">
- You have L$ 2,100.
+ 你有 L$ 2,100。
</text>
- <check_box label="Remove [AMOUNT] m² of contribution from group." name="remove_contribution"/>
- <button label="Purchase" name="buy_btn"/>
+ <check_box label="從群組移除 [AMOUNT] 平方公尺的æ出地。" name="remove_contribution"/>
+ <button label="購買" name="buy_btn"/>
<button label="å–消" name="cancel_btn"/>
</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_buy_object.xml b/indra/newview/skins/default/xui/zh/floater_buy_object.xml
index 507e482766..ff4a1feedb 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_buy_object.xml
+++ b/indra/newview/skins/default/xui/zh/floater_buy_object.xml
@@ -4,25 +4,25 @@
購買
</floater.string>
<floater.string name="title_buy_copy_text">
- Buy a copy of
+ 購買一個
</floater.string>
<floater.string name="no_copy_text">
- (no copy)
+ (ç¦æ­¢è¤‡è£½ï¼‰
</floater.string>
<floater.string name="no_modify_text">
- (no modify)
+ (ç¦æ­¢ä¿®æ”¹ï¼‰
</floater.string>
<floater.string name="no_transfer_text">
- (no transfer)
+ (ç¦æ­¢è½‰è®“)
</floater.string>
<text name="contents_text">
- Contains:
+ å…§å«ï¼š
</text>
<text name="buy_text">
- Buy for L$[AMOUNT] from:
+ 購買,支付 L$[AMOUNT] 給:
</text>
<text name="buy_name_text">
- [NAME]?
+ [NAME]?
</text>
<button label="購買" label_selected="購買" name="buy_btn"/>
<button label="å–消" label_selected="å–消" name="cancel_btn"/>
diff --git a/indra/newview/skins/default/xui/zh/floater_camera.xml b/indra/newview/skins/default/xui/zh/floater_camera.xml
index b75474340c..becb7b9546 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_camera.xml
+++ b/indra/newview/skins/default/xui/zh/floater_camera.xml
@@ -1,13 +1,22 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="camera_floater">
+<floater name="camera_floater" title="æ”影機控制">
<floater.string name="rotate_tooltip">
- Rotate Camera Around Focus
+ 繞著焦點轉動æ”影機
</floater.string>
<floater.string name="zoom_tooltip">
- Zoom Camera Towards Focus
+ æ”影機移近焦點
</floater.string>
<floater.string name="move_tooltip">
- Move Camera Up and Down, Left and Right
+ æ”影機上下左å³ç§»å‹•
+ </floater.string>
+ <floater.string name="camera_modes_title">
+ æ”影機模å¼
+ </floater.string>
+ <floater.string name="pan_mode_title">
+ 環繞縮放平移
+ </floater.string>
+ <floater.string name="presets_mode_title">
+ é è¨­è¦–角
</floater.string>
<floater.string name="free_mode_title">
視角物件
@@ -43,14 +52,14 @@
</panel_camera_item>
</panel>
<panel name="zoom">
- <joystick_rotate name="cam_rotate_stick" tool_tip="Orbit camera around focus"/>
- <slider_bar name="zoom_slider" tool_tip="Zoom camera toward focus"/>
+ <joystick_rotate name="cam_rotate_stick" tool_tip="æ”影機繞焦點旋轉"/>
+ <slider_bar name="zoom_slider" tool_tip="æ”影機移近焦點"/>
<joystick_track name="cam_track_stick" tool_tip="移動æ”影機上下左å³"/>
</panel>
</panel>
<panel name="buttons">
<button label="" name="presets_btn" tool_tip="é è¨­è¦–角"/>
- <button label="" name="pan_btn" tool_tip="Orbit Zoom Pan"/>
+ <button label="" name="pan_btn" tool_tip="環繞縮放平移"/>
<button label="" name="avatarview_btn" tool_tip="æ”影機模å¼"/>
</panel>
</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_chat_bar.xml b/indra/newview/skins/default/xui/zh/floater_chat_bar.xml
new file mode 100755
index 0000000000..f1a69a7688
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/floater_chat_bar.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="chat_bar" title="附近的èŠå¤©">
+ <panel name="bottom_panel">
+ <line_editor label="點按此處開始èŠå¤©ã€‚" name="chat_box" tool_tip="按下 Enter éµä¾†èªªæˆ–按下 Ctrl+Enter 來喊å«"/>
+ <button name="show_nearby_chat" tool_tip="顯示 / éš±è— é™„è¿‘çš„èŠå¤©ç´€éŒ„"/>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_choose_group.xml b/indra/newview/skins/default/xui/zh/floater_choose_group.xml
index 9977bfc828..9977bfc828 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_choose_group.xml
+++ b/indra/newview/skins/default/xui/zh/floater_choose_group.xml
diff --git a/indra/newview/skins/default/xui/zh/floater_color_picker.xml b/indra/newview/skins/default/xui/zh/floater_color_picker.xml
index a7ac78e419..fa7b795d4f 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_color_picker.xml
+++ b/indra/newview/skins/default/xui/zh/floater_color_picker.xml
@@ -10,13 +10,13 @@
è—色:
</text>
<text name="h_val_text">
- Hue:
+ 色調:
</text>
<text name="s_val_text">
- Sat:
+ 飽和度:
</text>
<text name="l_val_text">
- Lum:
+ 亮度:
</text>
<check_box label="ç«‹å³å¥—用" name="apply_immediate"/>
<button label="確定" label_selected="確定" name="select_btn"/>
@@ -25,6 +25,6 @@
ç›®å‰é¡è‰²ï¼š
</text>
<text name="(Drag below to save.)">
- (Drag below to save)
+ (拖曳到下方å³å¯å„²å­˜ï¼‰
</text>
</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_conversation_log.xml b/indra/newview/skins/default/xui/zh/floater_conversation_log.xml
new file mode 100644
index 0000000000..37115a0310
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/floater_conversation_log.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="floater_conversation_log" title="交談記錄">
+ <panel name="buttons_panel">
+ <filter_editor label="人員éŽæ¿¾å™¨" name="people_filter_input"/>
+ <menu_button name="conversation_view_btn" tool_tip="檢視/排åºçš„é¸é …"/>
+ <menu_button name="conversations_gear_btn" tool_tip="å°æ‰€é¸çš„人或群組採å–動作"/>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_conversation_preview.xml b/indra/newview/skins/default/xui/zh/floater_conversation_preview.xml
new file mode 100644
index 0000000000..ece263f440
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/floater_conversation_preview.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="preview_conversation" title="交談:">
+ <floater.string name="Title">
+ 交談:[NAME]
+ </floater.string>
+ <text name="page_label" value="é "/>
+</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_critical.xml b/indra/newview/skins/default/xui/zh/floater_critical.xml
index 7d08fe8af2..7d08fe8af2 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_critical.xml
+++ b/indra/newview/skins/default/xui/zh/floater_critical.xml
diff --git a/indra/newview/skins/default/xui/zh/floater_delete_env_preset.xml b/indra/newview/skins/default/xui/zh/floater_delete_env_preset.xml
new file mode 100755
index 0000000000..4aafb31952
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/floater_delete_env_preset.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<floater name="Delete Env Preset" title="刪除環境自訂é…ç½®">
+ <string name="title_water">
+ 刪除水的自訂é…ç½®
+ </string>
+ <string name="title_sky">
+ 刪除天空自訂é…ç½®
+ </string>
+ <string name="title_day_cycle">
+ 刪除日循環
+ </string>
+ <string name="label_water">
+ 自訂é…置:
+ </string>
+ <string name="label_sky">
+ 自訂é…置:
+ </string>
+ <string name="label_day_cycle">
+ 日循環:
+ </string>
+ <string name="msg_confirm_deletion">
+ 確定è¦åˆªé™¤æ‰€é¸è‡ªè¨‚é…置?
+ </string>
+ <string name="msg_sky_is_referenced">
+ 無法刪除日循環有所指涉的自訂é…置。
+ </string>
+ <string name="combo_label">
+ -é¸æ“‡ä¸€å€‹è‡ªè¨‚é…ç½®-
+ </string>
+ <text name="label">
+ 自訂é…置:
+ </text>
+ <button label="刪除" name="delete"/>
+ <button label="å–消" name="cancel"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_destinations.xml b/indra/newview/skins/default/xui/zh/floater_destinations.xml
new file mode 100755
index 0000000000..f50a6a631a
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/floater_destinations.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="Destinations" title="目的地"/>
diff --git a/indra/newview/skins/default/xui/zh/floater_display_name.xml b/indra/newview/skins/default/xui/zh/floater_display_name.xml
index 01b5088794..aa71bba769 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_display_name.xml
+++ b/indra/newview/skins/default/xui/zh/floater_display_name.xml
@@ -1,18 +1,18 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="Display Name" title="變更顯示å稱">
<text name="info_text">
- The name you give your avatar is called your Display Name. You can change it once a week.
+ 你為你的化身å–çš„åå­—å«åšã€Œé¡¯ç¤ºå稱ã€ã€‚ 一星期å¯ä»¥ä¿®æ”¹ä¸€æ¬¡ã€‚
</text>
<text name="lockout_text">
- You cannot change your Display Name until: [TIME].
+ 你下次能å†æ›´æ”¹é¡¯ç¤ºå稱的時間為 [TIME]。
</text>
<text name="set_name_label">
新顯示å稱:
</text>
<text name="name_confirm_label">
- Type your new name again to confirm:
+ å†æ¬¡è¼¸å…¥ä½ çš„æ–°å稱以便確èªï¼š
</text>
- <button label="儲存" name="save_btn" tool_tip="儲存你的新顯示å稱"/>
- <button label="é‡è¨­" name="reset_btn" tool_tip="Make Display Name the same as Username"/>
+ <button label="儲存" name="save_btn" tool_tip="儲存你的新的顯示å稱"/>
+ <button label="é‡è¨­" name="reset_btn" tool_tip="將顯示å稱設æˆå’Œä½¿ç”¨è€…å稱相åŒ"/>
<button label="å–消" name="cancel_btn"/>
</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_edit_day_cycle.xml b/indra/newview/skins/default/xui/zh/floater_edit_day_cycle.xml
new file mode 100755
index 0000000000..b84a4027ea
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/floater_edit_day_cycle.xml
@@ -0,0 +1,104 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="Edit Day cycle" title="編輯日循環">
+ <string name="title_new">
+ 新建一個日循環
+ </string>
+ <string name="title_edit">
+ 編輯日循環
+ </string>
+ <string name="hint_new">
+ 為日循環定å,調整å„項控制確定細節,å†é»žæŒ‰ã€Œå„²å­˜ã€ã€‚
+ </string>
+ <string name="hint_edit">
+ è‹¥è¦ç·¨è¼¯ä½ çš„日循環,請調整下方å„項控制,å†é»žæŒ‰ã€Œå„²å­˜ã€ã€‚
+ </string>
+ <string name="combo_label">
+ -é¸æ“‡ä¸€å€‹è‡ªè¨‚é…ç½®-
+ </string>
+ <text name="label">
+ 自訂é…ç½®å稱:
+ </text>
+ <text name="note">
+ 注æ„:更改自訂é…置的å稱將會新建一個自訂é…置,ä¸æœƒæ”¹è®ŠåŽŸæœ‰çš„自訂é…置。
+ </text>
+ <text name="hint_item1">
+ - 點按一個é ç±¤ï¼Œç·¨è¼¯ç‰¹å®šçš„天空設定和時間。
+ </text>
+ <text name="hint_item2">
+ - 點按並拖曳å„個é ç±¤ï¼Œå³å¯è¨­å®šéŽæ¸¡æ™‚間。
+ </text>
+ <text name="hint_item3">
+ - 使用 scrubber é è¦½ä½ çš„日循環。
+ </text>
+ <panel name="day_cycle_slider_panel">
+ <multi_slider initial_value="0" name="WLTimeSlider"/>
+ <multi_slider initial_value="0" name="WLDayCycleKeys"/>
+ <button label="新增éµ" label_selected="新增éµ" name="WLAddKey"/>
+ <button label="刪除éµ" label_selected="刪除éµ" name="WLDeleteKey"/>
+ <text name="WL12am">
+ åˆå¤œ 12 點
+ </text>
+ <text name="WL3am">
+ 凌晨 3 點
+ </text>
+ <text name="WL6am">
+ ä¸Šåˆ 6 點
+ </text>
+ <text name="WL9amHash">
+ ä¸Šåˆ 9 點
+ </text>
+ <text name="WL12pmHash">
+ ä¸­åˆ 12 點
+ </text>
+ <text name="WL3pm">
+ ä¸‹åˆ 3 點
+ </text>
+ <text name="WL6pm">
+ ä¸‹åˆ 6 點
+ </text>
+ <text name="WL9pm">
+ ä¸‹åˆ 9 點
+ </text>
+ <text name="WL12am2">
+ åˆå¤œ 12 點
+ </text>
+ <text name="WL12amHash">
+ |
+ </text>
+ <text name="WL3amHash">
+ I
+ </text>
+ <text name="WL6amHash">
+ |
+ </text>
+ <text name="WL9amHash2">
+ I
+ </text>
+ <text name="WL12pmHash2">
+ |
+ </text>
+ <text name="WL3pmHash">
+ I
+ </text>
+ <text name="WL6pmHash">
+ |
+ </text>
+ <text name="WL9pmHash">
+ I
+ </text>
+ <text name="WL12amHash2">
+ |
+ </text>
+ </panel>
+ <text name="WLCurKeyPresetText">
+ 天空設定:
+ </text>
+ <combo_box label="é è¨­å€¼" name="WLSkyPresets"/>
+ <text name="WLCurKeyTimeText">
+ 時間:
+ </text>
+ <time name="time" value="ä¸Šåˆ 6 點"/>
+ <check_box label="根據這設定變更我的日循環" name="make_default_cb"/>
+ <button label="儲存" name="save"/>
+ <button label="å–消" name="cancel"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_edit_sky_preset.xml b/indra/newview/skins/default/xui/zh/floater_edit_sky_preset.xml
new file mode 100755
index 0000000000..1ff832cdc4
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/floater_edit_sky_preset.xml
@@ -0,0 +1,143 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="Edit Sky Preset" title="編輯天空自訂é…ç½®">
+ <string name="title_new">
+ 建立新的天空自訂é…ç½®
+ </string>
+ <string name="title_edit">
+ 編輯天空自訂é…ç½®
+ </string>
+ <string name="hint_new">
+ 為自訂é…置定å,調整å„項控制確定é…置細節,完æˆå¾Œé»žæŒ‰ã€Œå„²å­˜ã€ã€‚
+ </string>
+ <string name="hint_edit">
+ è‹¥è¦ç·¨è¼¯ä½ çš„天空自訂é…置,請調整å„項控制,å†é»žæŒ‰ã€Œå„²å­˜ã€ã€‚
+ </string>
+ <string name="combo_label">
+ -é¸æ“‡ä¸€å€‹è‡ªè¨‚é…ç½®-
+ </string>
+ <text name="hint">
+ è‹¥è¦ç·¨è¼¯ä½ çš„自訂é…置,請調整å„項控制,å†é»žæŒ‰ã€Œå„²å­˜ã€ã€‚
+ </text>
+ <text name="label">
+ 自訂é…ç½®å稱:
+ </text>
+ <text name="note">
+ 注æ„:更改自訂é…置的å稱將會新建一個自訂é…置,ä¸æœƒæ”¹è®ŠåŽŸæœ‰çš„自訂é…置。
+ </text>
+ <tab_container name="WindLight Tabs">
+ <panel label="大氣" name="Atmosphere">
+ <text name="BHText">
+ è—天水平線
+ </text>
+ <text name="BDensText">
+ 陰霾水平線
+ </text>
+ <text name="BDensText2">
+ è—天密度
+ </text>
+ <text name="HDText">
+ 陰霾密度
+ </text>
+ <text name="DensMultText">
+ 密度å€å¢ž
+ </text>
+ <text name="WLDistanceMultText">
+ è·é›¢å€å¢ž
+ </text>
+ <text name="MaxAltText">
+ 最大高度
+ </text>
+ </panel>
+ <panel label="照明" name="Lighting">
+ <text name="SLCText">
+ æ—¥ï¼æœˆ é¡è‰²
+ </text>
+ <text name="WLAmbientText">
+ 環境
+ </text>
+ <text name="SunGlowText">
+ 太陽光è¼
+ </text>
+ <slider label="èšç„¦" name="WLGlowB"/>
+ <slider label="尺寸" name="WLGlowR"/>
+ <text name="WLStarText">
+ 星空亮度
+ </text>
+ <text name="SceneGammaText">
+ 場景 Gamma 值
+ </text>
+ <text name="TODText">
+ æ—¥ï¼æœˆ ä½ç½®
+ </text>
+ <multi_slider initial_value="0" name="WLSunPos"/>
+ <text name="WL12amHash">
+ |
+ </text>
+ <text name="WL6amHash">
+ |
+ </text>
+ <text name="WL12pmHash2">
+ |
+ </text>
+ <text name="WL6pmHash">
+ |
+ </text>
+ <text name="WL12amHash2">
+ |
+ </text>
+ <text name="WL12am">
+ åˆå¤œ 12 點
+ </text>
+ <text name="WL6am">
+ ä¸Šåˆ 6 點
+ </text>
+ <text name="WL12pmHash">
+ ä¸­åˆ 12 點
+ </text>
+ <text name="WL6pm">
+ ä¸‹åˆ 6 點
+ </text>
+ <text name="WL12am2">
+ åˆå¤œ 12 點
+ </text>
+ <time name="WLDayTime" value="ä¸Šåˆ 6 點"/>
+ <text name="WLEastAngleText">
+ æ±å‡è§’度
+ </text>
+ </panel>
+ <panel label="雲彩" name="Clouds">
+ <text name="WLCloudColorText">
+ 雲彩é¡è‰²
+ </text>
+ <text name="WLCloudColorText2">
+ 雲彩 XY 軸 / 密度
+ </text>
+ <slider label="X" name="WLCloudX"/>
+ <slider label="Y" name="WLCloudY"/>
+ <slider label="D" name="WLCloudDensity"/>
+ <text name="WLCloudCoverageText">
+ 雲彩覆蓋
+ </text>
+ <text name="WLCloudScaleText">
+ 雲彩è¦æ¨¡
+ </text>
+ <text name="WLCloudDetailText">
+ 雲彩細節(XY 軸 / 密度)
+ </text>
+ <slider label="X" name="WLCloudDetailX"/>
+ <slider label="Y" name="WLCloudDetailY"/>
+ <slider label="D" name="WLCloudDetailDensity"/>
+ <text name="WLCloudScrollXText">
+ 雲彩 X 滾軸
+ </text>
+ <check_box label="鎖定" name="WLCloudLockX"/>
+ <text name="WLCloudScrollYText">
+ 雲彩 Y 滾軸
+ </text>
+ <check_box label="鎖定" name="WLCloudLockY"/>
+ </panel>
+ </tab_container>
+ <check_box label="根據這自訂é…置變更我的天空設定" name="make_default_cb"/>
+ <button label="儲存" name="save"/>
+ <button label="å–消" name="cancel"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_edit_water_preset.xml b/indra/newview/skins/default/xui/zh/floater_edit_water_preset.xml
new file mode 100755
index 0000000000..7943866e72
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/floater_edit_water_preset.xml
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="Edit Water Preset" title="編輯水的自訂é…ç½®">
+ <string name="title_new">
+ 新建水的自訂é…ç½®
+ </string>
+ <string name="title_edit">
+ 編輯水的自訂é…ç½®
+ </string>
+ <string name="hint_new">
+ 為自訂é…置定å,調整å„項控制確定é…置細節,完æˆå¾Œé»žæŒ‰ã€Œå„²å­˜ã€ã€‚
+ </string>
+ <string name="hint_edit">
+ è‹¥è¦ç·¨è¼¯æ°´çš„自訂é…置,請調整å„項控制,å†é»žæŒ‰ã€Œå„²å­˜ã€ã€‚
+ </string>
+ <string name="combo_label">
+ -é¸æ“‡ä¸€å€‹è‡ªè¨‚é…ç½®-
+ </string>
+ <text name="hint">
+ è‹¥è¦ç·¨è¼¯ä½ çš„自訂é…置,請調整å„項控制,å†é»žæŒ‰ã€Œå„²å­˜ã€ã€‚
+ </text>
+ <text name="label">
+ 自訂é…ç½®å稱:
+ </text>
+ <text name="note">
+ 注æ„:更改自訂é…置的å稱將會新建一個自訂é…置,ä¸æœƒæ”¹è®ŠåŽŸæœ‰çš„自訂é…置。
+ </text>
+ <panel name="panel_water_preset">
+ <text name="water_color_label">
+ 水霧é¡è‰²
+ </text>
+ <text name="water_fog_density_label">
+ 霧密度指數
+ </text>
+ <text name="underwater_fog_modifier_label">
+ 水底霧修飾元
+ </text>
+ <text name="BHText">
+ 大波浪方å‘
+ </text>
+ <slider label="X" name="WaterWave1DirX"/>
+ <slider label="Y" name="WaterWave1DirY"/>
+ <text name="BDensText">
+ åå°„å­æ³¢æ¯”例
+ </text>
+ <text name="HDText">
+ è²æ¶…耳比例
+ </text>
+ <text name="FresnelOffsetText">
+ è²æ¶…耳åè·
+ </text>
+ <text name="BHText2">
+ å°æ³¢æµªæ–¹å‘
+ </text>
+ <slider label="X" name="WaterWave2DirX"/>
+ <slider label="Y" name="WaterWave2DirY"/>
+ <text name="DensMultText">
+ 上折射比例
+ </text>
+ <text name="WaterScaleBelowText">
+ 下折射比例
+ </text>
+ <text name="MaxAltText">
+ 模糊å€æ•¸
+ </text>
+ <text name="BHText3">
+ 正常地圖
+ </text>
+ </panel>
+ <check_box label="根據這自訂é…置變更我水的設定" name="make_default_cb"/>
+ <button label="儲存" name="save"/>
+ <button label="å–消" name="cancel"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_env_settings.xml b/indra/newview/skins/default/xui/zh/floater_env_settings.xml
deleted file mode 100644
index 534ee7f0d0..0000000000
--- a/indra/newview/skins/default/xui/zh/floater_env_settings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Environment Editor Floater" title="ENVIRONMENT EDITOR">
- <floater.string name="timeStr">
- [hour12,datetime,utc]:[min,datetime,utc] [ampm,datetime,utc]
- </floater.string>
- <text name="EnvTimeText">
- Time of Day
- </text>
- <text name="EnvTimeText2">
- 12:00 PM
- </text>
- <text name="EnvCloudText">
- Cloud Cover
- </text>
- <text name="EnvWaterColorText">
- 水色
- </text>
- <color_swatch name="EnvWaterColor" tool_tip="Click to open color picker"/>
- <text name="EnvWaterFogText">
- 水霧
- </text>
- <button label="Use Estate Time" name="EnvUseEstateTimeButton"/>
- <button label="進階天空" name="EnvAdvancedSkyButton"/>
- <button label="進階水文" name="EnvAdvancedWaterButton"/>
-</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_environment_settings.xml b/indra/newview/skins/default/xui/zh/floater_environment_settings.xml
new file mode 100755
index 0000000000..1c6f2f936d
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/floater_environment_settings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="Environment Editor Floater" title="環境設定">
+ <text name="note">
+ 使用以下的é¸é …自訂你 Viewer 的環境設定。
+ </text>
+ <radio_group name="region_settings_radio_group">
+ <radio_item label="使用地å€è¨­å®š" name="use_region_settings"/>
+ <radio_item label="自訂我的環境" name="use_my_settings"/>
+ </radio_group>
+ <panel name="user_environment_settings">
+ <text name="note">
+ 注æ„:你的自訂設定ä¸æœƒè¢«å…¶ä»–使用者看見。
+ </text>
+ <text name="water_settings_title">
+ 水的設定
+ </text>
+ <combo_box name="water_settings_preset_combo">
+ <combo_box.item label="-é¸æ“‡ä¸€å€‹è‡ªè¨‚é…ç½®-" name="item0"/>
+ </combo_box>
+ <text name="sky_dayc_settings_title">
+ 天空 / 日循環
+ </text>
+ <radio_group name="sky_dayc_settings_radio_group">
+ <radio_item label="固定天空" name="my_sky_settings"/>
+ <radio_item label="日循環" name="my_dayc_settings"/>
+ </radio_group>
+ <combo_box name="sky_settings_preset_combo">
+ <combo_box.item label="-é¸æ“‡ä¸€å€‹è‡ªè¨‚é…ç½®-" name="item0"/>
+ </combo_box>
+ <combo_box name="dayc_settings_preset_combo">
+ <combo_box.item label="-é¸æ“‡ä¸€å€‹è‡ªè¨‚é…ç½®-" name="item0"/>
+ </combo_box>
+ </panel>
+ <button label="確定" name="ok_btn"/>
+ <button label="å–消" name="cancel_btn"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_event.xml b/indra/newview/skins/default/xui/zh/floater_event.xml
index 349b5717f2..7175731fef 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_event.xml
+++ b/indra/newview/skins/default/xui/zh/floater_event.xml
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater label="Event" name="Event" title="EVENT DETAILS">
+<floater label="活動" name="Event" title="活動細節">
<floater.string name="loading_text">
載入中...
</floater.string>
<floater.string name="done_text">
- Done
+ 完æˆ
</floater.string>
</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_fast_timers.xml b/indra/newview/skins/default/xui/zh/floater_fast_timers.xml
new file mode 100755
index 0000000000..871849305c
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/floater_fast_timers.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="fast_timers">
+ <string name="pause">
+ æš«åœ
+ </string>
+ <string name="run">
+ è·‘æ­¥
+ </string>
+ <button label="æš«åœ" name="pause_btn"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_font_test.xml b/indra/newview/skins/default/xui/zh/floater_font_test.xml
index ec83c51eb3..ec83c51eb3 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_font_test.xml
+++ b/indra/newview/skins/default/xui/zh/floater_font_test.xml
diff --git a/indra/newview/skins/default/xui/zh/floater_gesture.xml b/indra/newview/skins/default/xui/zh/floater_gesture.xml
index a809cf085c..e7b1ed1de3 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_gesture.xml
+++ b/indra/newview/skins/default/xui/zh/floater_gesture.xml
@@ -7,17 +7,17 @@
(播放中)
</floater.string>
<floater.string name="copy_name">
- Copy of [COPY_NAME]
+ [COPY_NAME] 複本
</floater.string>
<scroll_list name="gesture_list">
<scroll_list.columns label="å稱" name="name"/>
<scroll_list.columns label="èŠå¤©" name="trigger"/>
- <scroll_list.columns label="Key" name="shortcut"/>
+ <scroll_list.columns label="éµ" name="shortcut"/>
</scroll_list>
<panel label="bottom_panel" name="bottom_panel">
<menu_button name="gear_btn" tool_tip="更多é¸é …"/>
<button name="new_gesture_btn" tool_tip="製作新姿勢e"/>
- <button name="activate_btn" tool_tip="Activate/Deactivate selected gesture"/>
+ <button name="activate_btn" tool_tip="å•Ÿå‹•/åœæ­¢æ‰€é¸å§¿å‹¢"/>
<button name="del_btn" tool_tip="刪除這個姿勢"/>
</panel>
<button label="編輯" name="edit_btn"/>
diff --git a/indra/newview/skins/default/xui/zh/floater_god_tools.xml b/indra/newview/skins/default/xui/zh/floater_god_tools.xml
index 448113bf74..69a6eadc8c 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_god_tools.xml
+++ b/indra/newview/skins/default/xui/zh/floater_god_tools.xml
@@ -8,42 +8,42 @@
<text name="Region Name:">
地å€å稱:
</text>
- <check_box label="Prelude" name="check prelude" tool_tip="Set this to make the region a prelude"/>
- <check_box label="固定太陽" name="check fixed sun" tool_tip="Fix the sun position (like in Region/Estate &gt; Terrain"/>
- <check_box label="Reset Home On Teleport" name="check reset home" tool_tip="When Resident teleports out, reset their home to the destination position."/>
- <check_box label="Visible" name="check visible" tool_tip="Set this to make the region visible to non-gods"/>
- <check_box label="傷害" name="check damage" tool_tip="Set this to enable damage in this region"/>
- <check_box label="阻止æµé‡è¿½è¹¤" name="block dwell" tool_tip="Set this to make the region not compute traffic"/>
- <check_box label="阻止變形" name="block terraform" tool_tip="Set this to disallow people terraforming their land"/>
- <check_box label="沙盒" name="is sandbox" tool_tip="Toggle whether this is a sandbox region"/>
- <button label="Bake Terrain" label_selected="Bake Terrain" name="Bake Terrain" tool_tip="儲存目å‰çš„地形為é è¨­"/>
- <button label="Revert Terrain" label_selected="Revert Terrain" name="Revert Terrain" tool_tip="Replace the current terrain with default"/>
- <button label="Swap Terrain" label_selected="Swap Terrain" name="Swap Terrain" tool_tip="Swap current terrain with default"/>
+ <check_box label="導引å€" name="check prelude" tool_tip="在此設定,將å€åŸŸè¨­ç‚ºå°Žå¼•å€"/>
+ <check_box label="固定太陽" name="check fixed sun" tool_tip="固定太陽ä½ç½®ï¼ˆå¦‚åŒåœ°å€/領地 &gt; 地形)"/>
+ <check_box label="瞬間傳é€æ™‚é‡è¨­å®¶çš„ä½ç½®" name="check reset home" tool_tip="居民瞬間傳é€é›¢é–‹æ™‚,將他們的家é‡è¨­ç‚ºçž¬é–“傳é€çš„目的地。"/>
+ <check_box label="å¯çœ‹åˆ°" name="check visible" tool_tip="在此設定,將å€åŸŸè¨­ç‚ºå¯è®“éžç¥žè€…看到。"/>
+ <check_box label="傷害" name="check damage" tool_tip="在此設定,使本地å€å…許傷害。"/>
+ <check_box label="阻止æµé‡è¿½è¹¤" name="block dwell" tool_tip="在此設定,使本å€åŸŸä¸è¨ˆç®—æµé‡ã€‚"/>
+ <check_box label="阻止土地變形" name="block terraform" tool_tip="設定ç¦æ­¢äººå€‘將其土地變形。"/>
+ <check_box label="沙盤" name="is sandbox" tool_tip="切æ›æ˜¯å¦è¨­ç‚ºæ²™ç›¤å€åŸŸã€‚"/>
+ <button label="確定地形" label_selected="確定地形" name="Bake Terrain" tool_tip="將目å‰çš„地形儲存為é è¨­å€¼"/>
+ <button label="回復原地形" label_selected="回復原地形" name="Revert Terrain" tool_tip="以é è¨­å€¼å–代目å‰çš„地形"/>
+ <button label="交æ›åœ°å½¢" label_selected="交æ›åœ°å½¢" name="Swap Terrain" tool_tip="將目å‰çš„地形和é è¨­å€¼äº¤æ›"/>
<text name="estate id">
領地 ID:
</text>
<text name="parent id">
- Parent ID:
+ æ¯é ˜åœ° ID:
</text>
- <line_editor name="parentestate" tool_tip="This is the parent estate for this region"/>
+ <line_editor name="parentestate" tool_tip="這是本å€åŸŸçš„æ¯é ˜åœ°"/>
<text name="Grid Pos: ">
網格ä½ç½®ï¼š
</text>
- <line_editor name="gridposx" tool_tip="This is the grid x position for this region"/>
- <line_editor name="gridposy" tool_tip="This is the grid y position for this region"/>
+ <line_editor name="gridposx" tool_tip="這是本å€åŸŸçš„網格 X ä½ç½®"/>
+ <line_editor name="gridposy" tool_tip="這是本å€åŸŸçš„網格 Y ä½ç½®"/>
<text name="Redirect to Grid: ">
- Redirect to Grid:
+ é‡æ–°å°Žå‘至網格:
</text>
<text name="billable factor text">
- Billable Factor:
+ 收費率:
</text>
<text name="land cost text">
- L$ per m²:
+ æ¯å¹³æ–¹å…¬å°º L$:
</text>
- <button label="é‡æ–°æ•´ç†" label_selected="é‡æ–°æ•´ç†" name="Refresh" tool_tip="Click here to refresh the above information"/>
- <button label="套用" label_selected="套用" name="Apply" tool_tip="點擊此處以接å—套用上述變更"/>
- <button label="é¸æ“‡åœ°å€" label_selected="é¸æ“‡åœ°å€" name="Select Region" tool_tip="Select the whole region with the land tool"/>
- <button label="ç«‹å³è‡ªå‹•å„²å­˜" label_selected="ç«‹å³è‡ªå‹•å„²å­˜" name="Autosave now" tool_tip="Save gzipped state to autosave directory"/>
+ <button label="é‡æ–°æ•´ç†" label_selected="é‡æ–°æ•´ç†" name="Refresh" tool_tip="點按這裡刷新上列資料"/>
+ <button label="套用" label_selected="套用" name="Apply" tool_tip="點按此處以接å—套用上述變更"/>
+ <button label="é¸æ“‡åœ°å€" label_selected="é¸æ“‡åœ°å€" name="Select Region" tool_tip="以土地工具é¸å–整個å€åŸŸ"/>
+ <button label="ç«‹å³è‡ªå‹•å„²å­˜" label_selected="ç«‹å³è‡ªå‹•å„²å­˜" name="Autosave now" tool_tip="儲存 gzip 壓縮狀態至自動儲存目錄"/>
</panel>
<panel label="物件" name="objects">
<panel.string name="no_target">
@@ -53,44 +53,44 @@
地å€å稱:
</text>
<text name="region name">
- Welsh
+ å¨çˆ¾æ–¯
</text>
<check_box label="關閉腳本" name="disable scripts" tool_tip="關閉這個地å€ç¾åœ¨çš„全部腳本"/>
- <check_box label="Disable Collisions" name="disable collisions" tool_tip="Set this to disable non-agent collisions in this region"/>
- <check_box label="Disable Physics" name="disable physics" tool_tip="Set this to disable all physics in this region"/>
- <button label="套用" label_selected="套用" name="Apply" tool_tip="Click here to apply any changes from above"/>
- <button label="Set Target" label_selected="Set Target" name="Set Target" tool_tip="Set the target avatar for object deletion"/>
+ <check_box label="ç¦æ­¢ç¢°æ’ž" name="disable collisions" tool_tip="設置關閉地å€å…§é™¤äº†äººä»¥å¤–的碰撞"/>
+ <check_box label="關閉物ç†" name="disable physics" tool_tip="設置關閉本å€åŸŸå…§æ‰€æœ‰ç‰©ç†"/>
+ <button label="套用" label_selected="套用" name="Apply" tool_tip="點按此處以接å—套用上述變更"/>
+ <button label="設定目標" label_selected="設定目標" name="Set Target" tool_tip="將目標化身設為待刪除的物件"/>
<text name="target_avatar_name">
(無目標)
</text>
- <button label="Delete Target&apos;s Scripted Objects On Others Land" label_selected="Delete Target&apos;s Scripted Objects On Others Land" name="Delete Target&apos;s Scripted Objects On Others Land" tool_tip="Delete all scripted objects owned by the target on land not owned by the target. (no copy) objects will be returned."/>
- <button label="Delete Target&apos;s Scripted Objects On *Any* Land" label_selected="Delete Target&apos;s Scripted Objects On *Any* Land" name="Delete Target&apos;s Scripted Objects On *Any* Land" tool_tip="Delete all scripted objects owned by the target in this region. (no copy) objects will be returned."/>
- <button label="Delete *ALL* Of Target&apos;s Objects" label_selected="Delete *ALL* Of Target&apos;s Objects" name="Delete *ALL* Of Target&apos;s Objects" tool_tip="Delete all objects owned by the target in this region. (no copy) objects will be returned."/>
- <button label="Get Top Colliders" label_selected="Get Top Colliders" name="Get Top Colliders" tool_tip="Gets list of objects experiencing the most narrowphase callbacks"/>
- <button label="Get Top Scripts" label_selected="Get Top Scripts" name="Get Top Scripts" tool_tip="Gets list of objects spending the most time running scripts"/>
- <button label="Scripts digest" label_selected="Scripts digest" name="Scripts digest" tool_tip="Gets a list of all scripts and number of occurences of each"/>
+ <button label="刪除目標物在其他土地的帶腳本的物件" label_selected="刪除目標物在其他土地的帶腳本的物件" name="Delete Target&apos;s Scripted Objects On Others Land" tool_tip="在ä¸æ˜¯ç›®æ¨™ç‰©æ‰€æ“有的土地上,刪除屬於該目標物的所有帶腳本的物件。 「ç¦æ­¢è¤‡è£½ã€çš„物件將被é€å›žã€‚"/>
+ <button label="刪除目標物在任何土地的帶腳本的物件" label_selected="刪除目標物在任何土地的帶腳本的物件" name="Delete Target&apos;s Scripted Objects On *Any* Land" tool_tip="刪除本å€åŸŸå…§å±¬æ–¼ç›®æ¨™ç‰©çš„所有帶腳本的物件。 「ç¦æ­¢è¤‡è£½ã€çš„物件將被é€å›žã€‚"/>
+ <button label="刪除目標物所有的物件" label_selected="刪除目標物所有的物件" name="Delete *ALL* Of Target&apos;s Objects" tool_tip="刪除本å€åŸŸå…§å±¬æ–¼ç›®æ¨™ç‰©çš„所有物件。 「ç¦æ­¢è¤‡è£½ã€çš„物件將被é€å›žã€‚"/>
+ <button label="å–得最常碰撞的物件" label_selected="å–得最常碰撞的物件" name="Get Top Colliders" tool_tip="å–得經歷最多次「窄相ã€å›žèª¿çš„物件清單"/>
+ <button label="å–得排å最高的腳本" label_selected="å–得排å最高的腳本" name="Get Top Scripts" tool_tip="å–得花最多時間執行腳本的物件清單"/>
+ <button label="腳本集" label_selected="腳本集" name="Scripts digest" tool_tip="å–得所有腳本清單,並列出發生次數,é‡å°æ¯ä¸€"/>
</panel>
- <panel label="Request" name="request">
+ <panel label="請求" name="request">
<text name="Destination:">
- Destination:
+ 目的地:
</text>
<combo_box name="destination">
- <combo_box.item label="Selection" name="item1"/>
- <combo_box.item label="Agent Region" name="item2"/>
+ <combo_box.item label="é¸æ“‡" name="item1"/>
+ <combo_box.item label="用戶地å€" name="item2"/>
</combo_box>
<text name="Request:">
- Request:
+ 請求:
</text>
<combo_box name="request">
- <combo_box.item label="colliders &lt;steps&gt;" name="item1"/>
- <combo_box.item label="scripts &lt;count&gt;,&lt;optional pattern&gt;" name="item2"/>
- <combo_box.item label="objects &lt;pattern&gt;" name="item3"/>
+ <combo_box.item label="碰撞物 &lt;步驟&gt;" name="item1"/>
+ <combo_box.item label="腳本 &lt;計數&gt;,&lt;éžå¿…è¦å½¢æ…‹&gt;" name="item2"/>
+ <combo_box.item label="物件 &lt;形態&gt;" name="item3"/>
<combo_box.item label="rez &lt;asset_id&gt;" name="item4"/>
</combo_box>
<text name="Parameter:">
- Parameter:
+ åƒæ•¸ï¼š
</text>
- <button label="Make Request" label_selected="Make Request" name="Make Request"/>
+ <button label="æ出請求" label_selected="æ出請求" name="Make Request"/>
</panel>
</tab_container>
</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_goto_line.xml b/indra/newview/skins/default/xui/zh/floater_goto_line.xml
new file mode 100644
index 0000000000..e0215aef8a
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/floater_goto_line.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="script goto" title="å‰å¾€æŸè¡Œæ•¸">
+ <button label="確定" label_selected="確定" name="goto_btn"/>
+ <text name="txt">
+ å‰å¾€æŸè¡Œæ•¸
+ </text>
+</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_hardware_settings.xml b/indra/newview/skins/default/xui/zh/floater_hardware_settings.xml
index 1465dcb256..9e3bb88ac0 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_hardware_settings.xml
+++ b/indra/newview/skins/default/xui/zh/floater_hardware_settings.xml
@@ -1,14 +1,14 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="Hardware Settings Floater" title="硬體設定">
<text name="Filtering:">
- Filtering:
+ éŽæ¿¾ï¼š
</text>
- <check_box label="Anisotropic Filtering (slower when enabled)" name="ani"/>
- <text name="Antialiasing:">
- Antialiasing:
+ <check_box label="å„å‘異性éŽæ¿¾ï¼ˆè‹¥å•Ÿç”¨æœƒè®Šæ…¢ï¼‰" name="ani"/>
+ <text name="antialiasing label">
+ 消除鋸齒:
</text>
- <combo_box label="Antialiasing" name="fsaa">
- <combo_box.item label="Disabled" name="FSAADisabled"/>
+ <combo_box label="消除鋸齒" name="fsaa">
+ <combo_box.item label="å·²åœç”¨" name="FSAADisabled"/>
<combo_box.item label="2x" name="2x"/>
<combo_box.item label="4x" name="4x"/>
<combo_box.item label="8x" name="8x"/>
@@ -17,15 +17,19 @@
<text name="antialiasing restart">
(須é‡æ–°å•Ÿå‹•ç€è¦½å™¨ï¼‰
</text>
- <spinner label="Gamma:" name="gamma"/>
+ <spinner label="伽瑪值:" name="gamma"/>
<text name="(brightness, lower is brighter)">
- (0 = default brightness, lower = brighter)
+ (0 = é è¨­äº®åº¦ï¼›å€¼è¶Šå° = 亮度越高)
</text>
<text name="Enable VBO:">
- Enable VBO:
+ 啟用頂點緩è¡ç‰©ä»¶(VBO):
</text>
- <check_box initial_value="true" label="Enable OpenGL Vertex Buffer Objects" name="vbo" tool_tip="Enabling this on modern hardware gives a performance gain. However, older hardware often has poor implementations of VBOs and you may get crashes when this is enabled."/>
- <slider label="æ質記憶體(MB):" name="GraphicsCardTextureMemory" tool_tip="Amount of memory to allocate for textures. Defaults to video card memory. Reducing this may improve performance but may also make textures blurry."/>
- <spinner label="Fog Distance Ratio:" name="fog"/>
+ <check_box initial_value="true" label="啟用 OpenGL 頂點緩è¡ç‰©ä»¶(VBO)" name="vbo" tool_tip="在較新硬體上啟用,å¯æå‡æ•ˆèƒ½ã€‚ 但是,較舊硬體的 VBO 實作ä¸ä½³ï¼Œè‹¥å•Ÿç”¨å¯èƒ½å°Žè‡´ç•¶æ©Ÿã€‚"/>
+ <text name="tc label">
+ 啟用 S3TC:
+ </text>
+ <check_box initial_value="true" label="啟用æ質壓縮(須é‡æ–°å•Ÿå‹•ï¼‰" name="texture compression" tool_tip="在影片記憶體中壓縮æ質,讓高解æžåº¦æ質å¯ä»¥è¼‰å…¥ï¼Œä½†è‰²å½©å“質ç¨å·®ã€‚"/>
+ <slider label="æ質記憶體(MB):" name="GraphicsCardTextureMemory" tool_tip="é…置給æ質使用的記憶體é‡ã€‚ é è¨­ç‚ºé¡¯åƒå¡è¨˜æ†¶é«”。 é™ä½Žæ­¤å€¼å¯ä»¥æå‡æ•ˆèƒ½ï¼Œä½†æ質也會變模糊。"/>
+ <spinner label="霧è·é›¢æ¯”率:" name="fog"/>
<button label="確定" label_selected="確定" name="OK"/>
</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_help_browser.xml b/indra/newview/skins/default/xui/zh/floater_help_browser.xml
index e605d5f19c..e605d5f19c 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_help_browser.xml
+++ b/indra/newview/skins/default/xui/zh/floater_help_browser.xml
diff --git a/indra/newview/skins/default/xui/zh/floater_how_to.xml b/indra/newview/skins/default/xui/zh/floater_how_to.xml
new file mode 100755
index 0000000000..e033327165
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/floater_how_to.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="floater_how_to" title="簡易教學"/>
diff --git a/indra/newview/skins/default/xui/zh/floater_hud.xml b/indra/newview/skins/default/xui/zh/floater_hud.xml
index a788961e95..a788961e95 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_hud.xml
+++ b/indra/newview/skins/default/xui/zh/floater_hud.xml
diff --git a/indra/newview/skins/default/xui/zh/floater_im_container.xml b/indra/newview/skins/default/xui/zh/floater_im_container.xml
index 2d66c659fe..84ad869100 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_im_container.xml
+++ b/indra/newview/skins/default/xui/zh/floater_im_container.xml
@@ -1,2 +1,29 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<multi_floater name="floater_im_box" title="交談"/>
+<multi_floater name="floater_im_box" title="交談">
+ <string name="collapse_icon" value="Conv_toolbar_collapse"/>
+ <string name="expand_icon" value="Conv_toolbar_expand"/>
+ <layout_stack name="conversations_stack">
+ <layout_panel name="conversations_layout_panel">
+ <layout_stack name="conversations_pane_buttons_stack">
+ <layout_panel name="conversations_pane_buttons_expanded">
+ <menu_button name="sort_btn" tool_tip="檢視/排åºçš„é¸é …"/>
+ <button name="add_btn" tool_tip="開始新的交談"/>
+ <button name="speak_btn" tool_tip="用麥克風和大家交談"/>
+ </layout_panel>
+ <layout_panel name="conversations_pane_buttons_collapsed">
+ <button name="expand_collapse_btn" tool_tip="縮疊/展開這個清單"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ <layout_panel name="messages_layout_panel">
+ <panel_container name="im_box_tab_container">
+ <panel name="stub_panel">
+ <button name="stub_collapse_btn" tool_tip="縮疊這一å€å¡Š"/>
+ <text name="stub_textbox">
+ 這個交談å¦é–‹äº†æ–°è¦–窗。 [secondlife:/// 把它收回來]
+ </text>
+ </panel>
+ </panel_container>
+ </layout_panel>
+ </layout_stack>
+</multi_floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_im_session.xml b/indra/newview/skins/default/xui/zh/floater_im_session.xml
index e8db97560e..864af2e592 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/zh/floater_im_session.xml
@@ -1,8 +1,57 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="panel_im">
- <layout_stack name="im_panels">
- <layout_panel>
- <line_editor label="To" name="chat_editor"/>
- </layout_panel>
- </layout_stack>
+ <floater.string name="call_btn_start">
+ Conv_toolbar_open_call
+ </floater.string>
+ <floater.string name="call_btn_stop">
+ Conv_toolbar_hang_up
+ </floater.string>
+ <floater.string name="collapseline_icon" value="Conv_collapse_to_one_line"/>
+ <floater.string name="expandline_icon" value="Conv_expand_one_line"/>
+ <floater.string name="collapse_icon" value="Conv_toolbar_collapse"/>
+ <floater.string name="expand_icon" value="Conv_toolbar_expand"/>
+ <floater.string name="tear_off_icon" value="Conv_toolbar_arrow_ne"/>
+ <floater.string name="return_icon" value="Conv_toolbar_arrow_sw"/>
+ <floater.string name="participant_added" value="[NAME] å·²å—邀加入交談。"/>
+ <floater.string name="multiple_participants_added" value="[NAME] å·²å—邀加入交談。"/>
+ <floater.string name="tooltip_to_separate_window" value="為這個交談å¦é–‹æ–°è¦–窗"/>
+ <floater.string name="tooltip_to_main_window" value="將這個交談移回到主視窗"/>
+ <floater.string name="start_call_button_tooltip" value="建立語音通è¯"/>
+ <floater.string name="end_call_button_tooltip" value="切斷語音通è¯"/>
+ <floater.string name="expcol_button_not_tearoff_tooltip" value="縮疊這一å€å¡Š"/>
+ <floater.string name="expcol_button_tearoff_and_expanded_tooltip" value="縮疊åƒèˆ‡è€…清單"/>
+ <floater.string name="expcol_button_tearoff_and_collapsed_tooltip" value="展開åƒèˆ‡è€…清單"/>
+ <view name="contents_view">
+ <layout_stack name="main_stack">
+ <layout_panel name="toolbar_panel">
+ <menu_button name="view_options_btn" tool_tip="檢視/排åºçš„é¸é …"/>
+ <menu_button name="gear_btn" tool_tip="å°é¸å–的人採å–動作"/>
+ <button name="add_btn" tool_tip="新增æŸäººåˆ°é€™å€‹äº¤è«‡"/>
+ <button name="voice_call_btn" tool_tip="建立語音通è¯"/>
+ <button name="close_btn" tool_tip="çµæŸé€™å€‹äº¤è«‡"/>
+ <button name="expand_collapse_btn" tool_tip="縮疊/展開這個框"/>
+ </layout_panel>
+ <layout_panel name="body_panel">
+ <layout_stack name="im_panels">
+ <layout_panel name="right_part_holder">
+ <layout_stack name="translate_and_chat_stack">
+ <layout_panel name="translate_chat_checkbox_lp">
+ <check_box label="翻譯èŠå¤©å…§å®¹" name="translate_chat_checkbox"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ <layout_panel name="chat_layout_panel">
+ <layout_stack name="input_panels">
+ <layout_panel name="input_editor_layout_panel">
+ <chat_editor label="至" name="chat_editor"/>
+ </layout_panel>
+ <layout_panel name="input_button_layout_panel">
+ <button name="minz_btn" tool_tip="顯示/éš±è—訊æ¯æ¡†"/>
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
+ </view>
</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_image_preview.xml b/indra/newview/skins/default/xui/zh/floater_image_preview.xml
index 1260601f90..d2de37fa6a 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_image_preview.xml
+++ b/indra/newview/skins/default/xui/zh/floater_image_preview.xml
@@ -26,7 +26,7 @@
請嘗試儲存圖åƒç‚º 24 ä½å…ƒ Targa(.tga)格å¼ã€‚
</text>
- <check_box label="Use lossless compression" name="lossless_check"/>
+ <check_box label="使用零失真壓縮" name="lossless_check"/>
<button label="å–消" name="cancel_btn"/>
<button label="上傳(L$[AMOUNT])" name="ok_btn"/>
</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_import_collada.xml b/indra/newview/skins/default/xui/zh/floater_import_collada.xml
new file mode 100755
index 0000000000..8f6b476ccf
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/floater_import_collada.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="Import Collada" title="匯入場景">
+ <text name="mesh count">
+ 網é¢ï¼š[COUNT]
+ </text>
+ <text name="texture count">
+ æ質: [COUNT]
+ </text>
+ <text name="status">
+ 狀態:[STATUS]
+ </text>
+ <button label="å–消" name="cancel"/>
+ <button label="確定" name="ok"/>
+ <string name="status_idle">
+ 閒置中
+ </string>
+ <string name="status_uploading">
+ 正在上傳 [NAME]
+ </string>
+ <string name="status_creating">
+ 正在建立 [NAME] 物件
+ </string>
+</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_incoming_call.xml b/indra/newview/skins/default/xui/zh/floater_incoming_call.xml
index a0f31fa11f..4526eff21d 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_incoming_call.xml
+++ b/indra/newview/skins/default/xui/zh/floater_incoming_call.xml
@@ -4,30 +4,30 @@
5
</floater.string>
<floater.string name="localchat">
- 附近的音èŠå¤©
+ 附近的語音èŠå¤©
</floater.string>
<floater.string name="anonymous">
匿å
</floater.string>
<floater.string name="VoiceInviteP2P">
- 通話中。
+ 來電中。
</floater.string>
<floater.string name="VoiceInviteAdHoc">
- 已加訴入會議交談中的語音èŠå¤©ã€‚
+ 已加入多方語音通話。
</floater.string>
<floater.string name="VoiceInviteGroup">
剛加入 &apos;[GROUP]&apos; 語音頻é“。
</floater.string>
<floater.string name="VoiceInviteQuestionGroup">
- Would you like to leave [CURRENT_CHAT] and join the call with &apos;[GROUP]&apos;?
+ 是å¦é›¢é–‹ [CURRENT_CHAT] 並加入和「[GROUP]ã€é€šè©±ï¼Ÿ
</floater.string>
<floater.string name="VoiceInviteQuestionDefault">
- Do you want to leave [CURRENT_CHAT] and join this voice chat?
+ 是å¦é›¢é–‹ [CURRENT_CHAT] 並加入這個語音èŠå¤©ï¼Ÿ
</floater.string>
<text name="question">
- Do you want to leave [CURRENT_CHAT] and join this voice chat?
+ 如果接è½ï¼Œä½ å°‡åˆ‡æ–·ç›®å‰çš„語音交談。
</text>
- <button label="接å—" label_selected="接å—" name="Accept"/>
- <button label="拒絕" label_selected="拒絕" name="Reject"/>
- <button label="開始 IM" name="Start IM"/>
+ <button label="接è½" label_selected="接è½" name="Accept"/>
+ <button label="忽視" label_selected="忽視" name="Reject"/>
+ <button label="ä¸æŽ¥è½ä½†é–‹å•Ÿ IM" name="Start IM"/>
</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_inspect.xml b/indra/newview/skins/default/xui/zh/floater_inspect.xml
index ea3d9d0c3e..4e1f4b24fd 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_inspect.xml
+++ b/indra/newview/skins/default/xui/zh/floater_inspect.xml
@@ -1,14 +1,14 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="inspect" title="INSPECT OBJECTS">
+<floater name="inspect" title="檢視物件">
<floater.string name="timeStamp">
[wkday,datetime,local] [mth,datetime,local] [day,datetime,local] [hour,datetime,local]:[min,datetime,local]:[second,datetime,local] [year,datetime,local]
</floater.string>
- <scroll_list name="object_list" tool_tip="Select an object from this list to highlight it in-world">
+ <scroll_list name="object_list" tool_tip="從清單中é¸å–一物件,在虛擬世界中加以高亮顯示。">
<scroll_list.columns label="物件å稱" name="object_name"/>
- <scroll_list.columns label="æ“有者å稱" name="owner_name"/>
+ <scroll_list.columns label="所有人å稱" name="owner_name"/>
<scroll_list.columns label="創造者å稱" name="creator_name"/>
<scroll_list.columns label="創造日期" name="creation_date"/>
</scroll_list>
- <button label="察看æ“有者檔案..." name="button owner" tool_tip="See profile of the highlighted object&apos;s owner"/>
- <button label="察看創造者檔案..." name="button creator" tool_tip="See profile of the highlighted object&apos;s original creator"/>
+ <button label="察看所有人檔案..." name="button owner" tool_tip="察看高亮顯示的物件的物主個人檔案"/>
+ <button label="察看創造人檔案..." name="button creator" tool_tip="察看高亮顯示的物件的原創人個人檔案"/>
</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_inventory.xml b/indra/newview/skins/default/xui/zh/floater_inventory.xml
deleted file mode 100644
index da4619c964..0000000000
--- a/indra/newview/skins/default/xui/zh/floater_inventory.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Inventory" title="我的收ç´å€">
- <panel label="收ç´å€é¢æ¿" name="Inventory Panel"/>
-</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_inventory_item_properties.xml b/indra/newview/skins/default/xui/zh/floater_inventory_item_properties.xml
index a41be7ef9a..6998df75f3 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_inventory_item_properties.xml
+++ b/indra/newview/skins/default/xui/zh/floater_inventory_item_properties.xml
@@ -10,7 +10,7 @@
ä½ å¯ä»¥ï¼š
</floater.string>
<floater.string name="owner_can">
- æ“有者å¯ä»¥ï¼š
+ 所有人å¯ä»¥ï¼š
</floater.string>
<floater.string name="acquiredDate">
[wkday,datetime,local] [mth,datetime,local] [day,datetime,local] [hour,datetime,local]:[min,datetime,local]:[second,datetime,local] [year,datetime,local]
@@ -26,11 +26,11 @@
</text>
<button label="檔案..." name="BtnCreator"/>
<text name="LabelOwnerTitle">
- æ“有者:
+ 所有人:
</text>
<button label="檔案..." name="BtnOwner"/>
<text name="LabelAcquiredTitle">
- Acquired:
+ å–得於:
</text>
<text name="LabelAcquiredDate">
Wed May 24 12:50:46 2006
@@ -39,25 +39,25 @@
你:
</text>
<check_box label="編輯" name="CheckOwnerModify"/>
- <check_box label="覆製" name="CheckOwnerCopy"/>
+ <check_box label="æšåº¨" name="CheckOwnerCopy"/>
<check_box label="轉售" name="CheckOwnerTransfer"/>
<text name="AnyoneLabel">
任何人:
</text>
- <check_box label="覆製" name="CheckEveryoneCopy"/>
+ <check_box label="æšåº¨" name="CheckEveryoneCopy"/>
<text name="GroupLabel">
群組:
</text>
<check_box label="分享" name="CheckShareWithGroup"/>
<text name="NextOwnerLabel">
- 下一個æ“有者:
+ 下一個所有人:
</text>
<check_box label="編輯" name="CheckNextOwnerModify"/>
- <check_box label="覆製" name="CheckNextOwnerCopy"/>
+ <check_box label="æšåº¨" name="CheckNextOwnerCopy"/>
<check_box label="轉售" name="CheckNextOwnerTransfer"/>
<check_box label="出售" name="CheckPurchase"/>
<combo_box name="combobox sale copy">
- <combo_box.item label="副本" name="Copy"/>
+ <combo_box.item label="æšåº¨" name="Copy"/>
<combo_box.item label="原件" name="Original"/>
</combo_box>
<spinner label="價格:" name="Edit Cost"/>
diff --git a/indra/newview/skins/default/xui/zh/floater_inventory_view_finder.xml b/indra/newview/skins/default/xui/zh/floater_inventory_view_finder.xml
index d698edf5e5..6d1d18b67c 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_inventory_view_finder.xml
+++ b/indra/newview/skins/default/xui/zh/floater_inventory_view_finder.xml
@@ -5,16 +5,17 @@
<check_box label="æœè£" name="check_clothing"/>
<check_box label="姿勢" name="check_gesture"/>
<check_box label="地標" name="check_landmark"/>
+ <check_box label="網é¢" name="check_mesh"/>
<check_box label="記事å¡" name="check_notecard"/>
- <check_box label="Objects" name="check_object"/>
+ <check_box label="物件" name="check_object"/>
<check_box label="腳本" name="check_script"/>
- <check_box label="Sounds" name="check_sound"/>
+ <check_box label="è²éŸ³" name="check_sound"/>
<check_box label="æ質" name="check_texture"/>
- <check_box label="Snapshots" name="check_snapshot"/>
+ <check_box label="å¿«ç…§" name="check_snapshot"/>
<button label="全部" label_selected="全部" name="All"/>
<button label="ç„¡" label_selected="ç„¡" name="None"/>
- <check_box label="Always show folders" name="check_show_empty"/>
- <check_box label="Since Logoff" name="check_since_logoff"/>
+ <check_box label="固定顯示資料夾" name="check_show_empty"/>
+ <check_box label="自上次登出" name="check_since_logoff"/>
<text name="- OR -">
- 或 -
</text>
diff --git a/indra/newview/skins/default/xui/zh/floater_joystick.xml b/indra/newview/skins/default/xui/zh/floater_joystick.xml
index 1721f7cd1e..e0b2cf5a1c 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_joystick.xml
+++ b/indra/newview/skins/default/xui/zh/floater_joystick.xml
@@ -1,79 +1,79 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Joystick" title="JOYSTICK CONFIGURATION">
+<floater name="Joystick" title="æ–桿設置">
<floater.string name="NoDevice">
未åµæ¸¬åˆ°è¨­å‚™
</floater.string>
- <check_box label="Enable Joystick:" name="enable_joystick"/>
- <spinner label="X Axis Mapping" name="JoystickAxis1"/>
- <spinner label="Y Axis Mapping" name="JoystickAxis2"/>
- <spinner label="Z Axis Mapping" name="JoystickAxis0"/>
- <spinner label="Pitch Mapping" name="JoystickAxis4"/>
- <spinner label="Yaw Mapping" name="JoystickAxis5"/>
- <spinner label="Roll Mapping" name="JoystickAxis3"/>
- <spinner label="Zoom Mapping" name="JoystickAxis6"/>
- <check_box label="Direct Zoom" name="ZoomDirect"/>
- <check_box label="3D Cursor" name="Cursor3D"/>
- <check_box label="Auto Level" name="AutoLeveling"/>
+ <check_box label="啟用æ–桿:" name="enable_joystick"/>
+ <spinner label="X 軸映射" name="JoystickAxis1"/>
+ <spinner label="Y 軸映射" name="JoystickAxis2"/>
+ <spinner label="Z 軸映射" name="JoystickAxis0"/>
+ <spinner label="俯仰映射" name="JoystickAxis4"/>
+ <spinner label="å擺映射" name="JoystickAxis5"/>
+ <spinner label="翻滾映射" name="JoystickAxis3"/>
+ <spinner label="縮放映射" name="JoystickAxis6"/>
+ <check_box label="直接縮放" name="ZoomDirect"/>
+ <check_box label="三維游標" name="Cursor3D"/>
+ <check_box label="自動水平" name="AutoLeveling"/>
<text name="Control Modes:">
- Control Modes:
+ 控制模å¼ï¼š
</text>
<check_box label="化身" name="JoystickAvatarEnabled"/>
<check_box label="建造" name="JoystickBuildEnabled"/>
- <check_box label="Flycam" name="JoystickFlycamEnabled"/>
- <stat_view label="Joystick Monitor" name="axis_view">
- <stat_bar label="Axis 0" name="axis0"/>
- <stat_bar label="Axis 1" name="axis1"/>
- <stat_bar label="Axis 2" name="axis2"/>
- <stat_bar label="Axis 3" name="axis3"/>
- <stat_bar label="Axis 4" name="axis4"/>
- <stat_bar label="Axis 5" name="axis5"/>
+ <check_box label="移動æ”影機" name="JoystickFlycamEnabled"/>
+ <stat_view label="æ–桿監控器" name="axis_view">
+ <stat_bar label="軸 0" name="axis0"/>
+ <stat_bar label="軸 1" name="axis1"/>
+ <stat_bar label="軸 2" name="axis2"/>
+ <stat_bar label="軸 3" name="axis3"/>
+ <stat_bar label="軸 4" name="axis4"/>
+ <stat_bar label="軸 5" name="axis5"/>
</stat_view>
<text name="XScale">
- X Scale
+ X 比例
</text>
<text name="YScale">
- Y Scale
+ Y 比例
</text>
<text name="ZScale">
- Z Scale
+ Z 比例
</text>
<text name="PitchScale">
- Pitch Scale
+ 俯仰比例
</text>
<text name="YawScale">
- Yaw Scale
+ å擺比例
</text>
<text name="RollScale">
- Roll Scale
+ 翻滾比例
</text>
<text name="XDeadZone">
- X Dead Zone
+ X æ­»å€
</text>
<text name="YDeadZone">
- Y Dead Zone
+ Y æ­»å€
</text>
<text name="ZDeadZone">
- Z Dead Zone
+ Z æ­»å€
</text>
<text name="PitchDeadZone">
- Pitch Dead Zone
+ 俯仰死å€
</text>
<text name="YawDeadZone">
- Yaw Dead Zone
+ å擺死å€
</text>
<text name="RollDeadZone">
- Roll Dead Zone
+ 翻滾死å€
</text>
<text name="Feathering">
- Feathering
+ é‡é‡å應
</text>
<text name="ZoomScale2">
- Zoom Scale
+ 縮放比例
</text>
<text name="ZoomDeadZone">
- Zoom Dead Zone
+ 縮放死å€
</text>
- <button label="SpaceNavigator Defaults" name="SpaceNavigatorDefaults"/>
+ <button label="SpaceNavigator é è¨­å€¼" name="SpaceNavigatorDefaults"/>
<button label="確定" label_selected="確定" name="ok_btn"/>
<button label="å–消" label_selected="å–消" name="cancel_btn"/>
</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_lagmeter.xml b/indra/newview/skins/default/xui/zh/floater_lagmeter.xml
index 6e58e7332f..e9a082288a 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_lagmeter.xml
+++ b/indra/newview/skins/default/xui/zh/floater_lagmeter.xml
@@ -7,7 +7,7 @@
360
</floater.string>
<floater.string name="min_title_msg">
- Lag
+ 延é²
</floater.string>
<floater.string name="min_width_px">
90
@@ -22,28 +22,28 @@
15
</floater.string>
<floater.string name="client_frame_time_window_bg_msg">
- Normal, window in background
+ 正常,視窗ä½æ–¼èƒŒæ™¯
</floater.string>
<floater.string name="client_frame_time_critical_msg">
- Client frame rate below [CLIENT_FRAME_RATE_CRITICAL]
+ 客戶端幀率低於 [CLIENT_FRAME_RATE_CRITICAL]
</floater.string>
<floater.string name="client_frame_time_warning_msg">
- Client frame rate between [CLIENT_FRAME_RATE_CRITICAL] and [CLIENT_FRAME_RATE_WARNING]
+ 客戶端幀率介於 [CLIENT_FRAME_RATE_CRITICAL] 和 [CLIENT_FRAME_RATE_WARNING] 之間
</floater.string>
<floater.string name="client_frame_time_normal_msg">
正常
</floater.string>
<floater.string name="client_draw_distance_cause_msg">
- Possible cause: Draw distance set too high
+ å¯èƒ½åŽŸå› ï¼šå¯è¦–è·é›¢è¨­å¾—太é 
</floater.string>
<floater.string name="client_texture_loading_cause_msg">
- Possible cause: Images loading
+ å¯èƒ½åŽŸå› ï¼šæ­£åœ¨è¼‰å…¥åœ–åƒ
</floater.string>
<floater.string name="client_texture_memory_cause_msg">
- Possible cause: Too many images in memory
+ å¯èƒ½åŽŸå› ï¼šè¨˜æ†¶é«”裡圖åƒå¤ªå¤š
</floater.string>
<floater.string name="client_complex_objects_cause_msg">
- Possible cause: Too many complex objects in scene
+ å¯èƒ½åŽŸå› ï¼šå ´æ™¯å…§è¤‡é›œç‰©ä»¶å¤ªå¤š
</floater.string>
<floater.string name="network_text_msg">
網路
@@ -55,10 +55,10 @@
5
</floater.string>
<floater.string name="network_packet_loss_critical_msg">
- Connection is dropping over [NETWORK_PACKET_LOSS_CRITICAL]% of packets
+ 這次連通丟失了至少 [NETWORK_PACKET_LOSS_CRITICAL]% çš„å°åŒ…
</floater.string>
<floater.string name="network_packet_loss_warning_msg">
- Connection is dropping [NETWORK_PACKET_LOSS_WARNING]%-[NETWORK_PACKET_LOSS_CRITICAL]% of packets
+ 這次連通丟失了 [NETWORK_PACKET_LOSS_WARNING]%-[NETWORK_PACKET_LOSS_CRITICAL]% çš„å°åŒ…
</floater.string>
<floater.string name="network_performance_normal_msg">
正常
@@ -70,16 +70,16 @@
300
</floater.string>
<floater.string name="network_ping_critical_msg">
- Connection ping time is over [NETWORK_PING_CRITICAL] ms
+ æŽ¢æ¸¬é€£é€šå›žæ‡‰æ™‚é–“è¶…éŽ [NETWORK_PING_CRITICAL] 毫秒
</floater.string>
<floater.string name="network_ping_warning_msg">
- Connection ping time is [NETWORK_PING_WARNING]-[NETWORK_PING_CRITICAL] ms
+ 探測連通回應時間為 [NETWORK_PING_WARNING]-[NETWORK_PING_CRITICAL] 毫秒
</floater.string>
<floater.string name="network_packet_loss_cause_msg">
- Possible bad connection or &apos;Bandwidth&apos; pref too high.
+ å¯èƒ½é€£é€šä¸è‰¯ï¼Œæˆ–所設的å好連通頻寬éŽé«˜ã€‚
</floater.string>
<floater.string name="network_ping_cause_msg">
- Possible bad connection or file-sharing app.
+ å¯èƒ½é€£é€šä¸è‰¯ï¼Œæˆ–使用檔案分享應用程å¼ã€‚
</floater.string>
<floater.string name="server_text_msg">
伺æœå™¨
diff --git a/indra/newview/skins/default/xui/zh/floater_land_holdings.xml b/indra/newview/skins/default/xui/zh/floater_land_holdings.xml
index 1d172f63e1..aae2cfb466 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_land_holdings.xml
+++ b/indra/newview/skins/default/xui/zh/floater_land_holdings.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="land holdings floater" title="我的土地">
<floater.string name="area_string">
- [AREA] m²
+ [AREA] 平方公尺
</floater.string>
<scroll_list name="parcel list">
<scroll_list.columns label="地段" name="name"/>
@@ -12,28 +12,28 @@
<button label="瞬間傳é€" label_selected="瞬間傳é€" name="Teleport" tool_tip="瞬間傳é€åˆ°é€™åœŸåœ°çš„中央。"/>
<button label="地圖" label_selected="地圖" name="Show on Map" tool_tip="將這塊土地顯示在世界地圖上。"/>
<text name="contrib_label">
- Contributions to your groups:
+ å°ä½ çš„群組的貢ç»ï¼š
</text>
<scroll_list name="grant list">
<scroll_list.columns label="群組" name="group"/>
<scroll_list.columns label="å€åŸŸ" name="area"/>
</scroll_list>
<text name="allowed_label">
- Allowed land holdings at current payment plan:
+ ç›®å‰ä»˜è²»è¨ˆåŠƒæ‰€å…許æ“有的土地:
</text>
<text name="allowed_text">
- [AREA] m²
+ [AREA] 平方公尺
</text>
<text name="current_label">
- Current land holdings:
+ ç›®å‰æ“有的土地:
</text>
<text name="current_text">
- [AREA] m²
+ [AREA] 平方公尺
</text>
<text name="available_label">
- Available for land purchases:
+ å¯è³¼åœŸåœ°ï¼š
</text>
<text name="available_text">
- [AREA] m²
+ [AREA] 平方公尺
</text>
</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_live_lsleditor.xml b/indra/newview/skins/default/xui/zh/floater_live_lsleditor.xml
index fe61c312ed..f4a7ba5cca 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_live_lsleditor.xml
+++ b/indra/newview/skins/default/xui/zh/floater_live_lsleditor.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="script ed float" title="腳本: 新腳本">
<floater.string name="not_allowed">
- You can not view or edit this script, since it has been set as &quot;no copy&quot;. You need full permissions to view or edit a script inside an object.
+ 你無法察看或編輯這腳本,它被設為「ç¦æ­¢è¤‡è£½ã€ã€‚ 你需è¦å®Œæ•´æ¬Šé™åŽ»å¯Ÿçœ‹æˆ–編輯物件內的腳本。
</floater.string>
<floater.string name="script_running">
執行中
diff --git a/indra/newview/skins/default/xui/zh/floater_lsl_guide.xml b/indra/newview/skins/default/xui/zh/floater_lsl_guide.xml
index e5c3c47827..b10a480b06 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_lsl_guide.xml
+++ b/indra/newview/skins/default/xui/zh/floater_lsl_guide.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="script ed float" title="LSL REFERENCE">
- <check_box label="Follow cursor" name="lock_check"/>
- <combo_box label="Lock" name="history_combo"/>
- <button label="Back" name="back_btn"/>
- <button label="Forward" name="fwd_btn"/>
+<floater name="script ed float" title="LSL åƒè€ƒ">
+ <check_box label="跟隨游標" name="lock_check"/>
+ <combo_box label="鎖定" name="history_combo"/>
+ <button label="返回" name="back_btn"/>
+ <button label="å‘å‰" name="fwd_btn"/>
</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_map.xml b/indra/newview/skins/default/xui/zh/floater_map.xml
index b535ef0074..8a030b3b3f 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_map.xml
+++ b/indra/newview/skins/default/xui/zh/floater_map.xml
@@ -1,36 +1,36 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Map" title="">
+<floater name="Map" title="迷你地圖">
<floater.string name="ToolTipMsg">
- [REGION](Double-click to open Map, shift-drag to pan)
+ [REGION](雙擊以開啟地圖,按下 shift éµæ‹–曳來平移)
</floater.string>
<floater.string name="AltToolTipMsg">
- [REGION](Double-click to teleport, shift-drag to pan)
+ [REGION](雙擊以瞬間傳é€ï¼ŒæŒ‰ä¸‹ shift éµæ‹–曳來平移)
</floater.string>
<floater.string name="mini_map_caption">
- MINIMAP
+ 迷你地圖
</floater.string>
- <text label="N" name="floater_map_north">
- N
+ <text label="北" name="floater_map_north">
+ 北
</text>
<text label="E" name="floater_map_east">
E
</text>
- <text label="W" name="floater_map_west">
- W
+ <text label="西" name="floater_map_west">
+ 西
</text>
- <text label="S" name="floater_map_south">
- S
+ <text label="å—" name="floater_map_south">
+ å—
</text>
- <text label="SE" name="floater_map_southeast">
- SE
+ <text label="æ±å—" name="floater_map_southeast">
+ æ±å—
</text>
- <text label="NE" name="floater_map_northeast">
- NE
+ <text label="æ±åŒ—" name="floater_map_northeast">
+ æ±åŒ—
</text>
- <text label="SW" name="floater_map_southwest">
- SW
+ <text label="西å—" name="floater_map_southwest">
+ 西å—
</text>
- <text label="NW" name="floater_map_northwest">
- NW
+ <text label="西北" name="floater_map_northwest">
+ 西北
</text>
</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_media_browser.xml b/indra/newview/skins/default/xui/zh/floater_media_browser.xml
index 6e75016fad..7f030924e1 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_media_browser.xml
+++ b/indra/newview/skins/default/xui/zh/floater_media_browser.xml
@@ -8,13 +8,13 @@
</floater.string>
<layout_stack name="stack1">
<layout_panel name="nav_controls">
- <button label="å‘後" name="back"/>
+ <button label="返回" name="back"/>
<button label="å‘å‰" name="forward"/>
- <button label="é‡è¼‰" name="reload"/>
- <button label="Go" name="go"/>
+ <button label="é‡æ–°è¼‰å…¥" name="reload"/>
+ <button label="å‰å¾€" name="go"/>
</layout_panel>
<layout_panel name="time_controls">
- <button label="rewind" name="rewind"/>
+ <button label="倒轉" name="rewind"/>
<button label="åœæ­¢" name="stop"/>
<button label="å‘å‰" name="seek"/>
</layout_panel>
@@ -22,8 +22,8 @@
<button label="é€å‡ºç›®å‰é é¢åˆ°åœ°æ®µ" name="assign"/>
</layout_panel>
<layout_panel name="external_controls">
- <button label="在我的網é ç€è¦½å™¨ä¸­é–‹å•Ÿ" name="open_browser"/>
- <check_box label="總是在我的網é ç€è¦½å™¨ä¸­é–‹å•Ÿ" name="open_always"/>
+ <button label="用我的ç€è¦½å™¨é–‹å•Ÿ" name="open_browser"/>
+ <check_box label="固定用我的ç€è¦½å™¨é–‹å•Ÿ" name="open_always"/>
<button label="關閉" name="close"/>
</layout_panel>
</layout_stack>
diff --git a/indra/newview/skins/default/xui/zh/floater_media_settings.xml b/indra/newview/skins/default/xui/zh/floater_media_settings.xml
index f42c0af3d9..3984095a65 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_media_settings.xml
+++ b/indra/newview/skins/default/xui/zh/floater_media_settings.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="media_settings" title="MEDIA SETTINGS">
+<floater name="media_settings" title="媒體設定">
<button label="確定" label_selected="確定" name="OK"/>
<button label="å–消" label_selected="å–消" name="Cancel"/>
<button label="套用" label_selected="套用" name="Apply"/>
diff --git a/indra/newview/skins/default/xui/zh/floater_mem_leaking.xml b/indra/newview/skins/default/xui/zh/floater_mem_leaking.xml
index 93c1b58df6..350254e385 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_mem_leaking.xml
+++ b/indra/newview/skins/default/xui/zh/floater_mem_leaking.xml
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="MemLeak" title="SIMULATE A MEMORY LEAK">
- <spinner label="Leaking Speed (bytes per frame):" name="leak_speed"/>
- <spinner label="Max Leaked Memory (MB):" name="max_leak"/>
+<floater name="MemLeak" title="模擬記憶體æ¼è€—">
+ <spinner label="æ¼è€—速度(ä½å…ƒçµ„/幀):" name="leak_speed"/>
+ <spinner label="最大記憶體æ¼è€—(MB):" name="max_leak"/>
<text name="total_leaked_label">
- Current leaked memory: [SIZE] KB
+ ç›®å‰å·²æ¼è€—記憶體:[SIZE] KB
</text>
<text name="note_label_1">
[NOTE1]
@@ -11,8 +11,8 @@
<text name="note_label_2">
[NOTE2]
</text>
- <button label="Start" name="start_btn"/>
+ <button label="開始" name="start_btn"/>
<button label="åœæ­¢" name="stop_btn"/>
- <button label="Release" name="release_btn"/>
+ <button label="釋放" name="release_btn"/>
<button label="關閉" name="close_btn"/>
</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_merchant_outbox.xml b/indra/newview/skins/default/xui/zh/floater_merchant_outbox.xml
new file mode 100755
index 0000000000..6b6126c8e0
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/floater_merchant_outbox.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="floater_merchant_outbox" title="商家發件匣">
+ <string name="OutboxFolderCount1">
+ 1 個資料夾
+ </string>
+ <string name="OutboxFolderCountN">
+ [NUM] 個資料夾
+ </string>
+ <string name="OutboxImporting">
+ 正在傳é€è³‡æ–™å¤¾â€¦
+ </string>
+ <string name="OutboxInitializing">
+ 正在åˆå§‹åŒ–…
+ </string>
+ <panel label="">
+ <panel>
+ <panel name="outbox_inventory_placeholder_panel">
+ <text name="outbox_inventory_placeholder_title">
+ 載入中...
+ </text>
+ </panel>
+ </panel>
+ <panel>
+ <button label="é€å¾€ç¬¬äºŒäººç”Ÿè³¼ç‰©å¸‚集" name="outbox_import_btn" tool_tip="推到我第二人生購物市集的店é¢"/>
+ </panel>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_model_preview.xml b/indra/newview/skins/default/xui/zh/floater_model_preview.xml
new file mode 100755
index 0000000000..22b3d3b065
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/floater_model_preview.xml
@@ -0,0 +1,312 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="Model Preview" title="上傳模型">
+ <string name="status_idle"/>
+ <string name="status_parse_error">
+ éŒ¯èª¤ï¼šå‰–æž dae 時出錯,詳見記錄檔。
+ </string>
+ <string name="status_material_mismatch">
+ 錯誤:模型æ料並éžåƒè€ƒæ¨¡åž‹çš„å­é›†åˆã€‚
+ </string>
+ <string name="status_reading_file">
+ 載入中...
+ </string>
+ <string name="status_generating_meshes">
+ 正在生æˆç¶²é¢â€¦
+ </string>
+ <string name="status_vertex_number_overflow">
+ éŒ¯èª¤ï¼šé ‚é»žæ•¸ç›®è¶…éŽ 65534,程åºå·²ä¸­æ­¢ï¼
+ </string>
+ <string name="bad_element">
+ 錯誤:無效的元件
+ </string>
+ <string name="high">
+ 高
+ </string>
+ <string name="medium">
+ 中
+ </string>
+ <string name="low">
+ 低
+ </string>
+ <string name="lowest">
+ 最低
+ </string>
+ <string name="mesh_status_good">
+ 確定產生ï¼
+ </string>
+ <string name="mesh_status_na">
+ ä¸é©ç”¨
+ </string>
+ <string name="mesh_status_none">
+ ç„¡
+ </string>
+ <string name="mesh_status_submesh_mismatch">
+ 細節層次裡,å¯ä½¿ç”¨æ質的臉部數目ä¸åŒã€‚
+ </string>
+ <string name="mesh_status_mesh_mismatch">
+ 細節層次裡,網é¢å¯¦ä¾‹çš„數目ä¸åŒã€‚
+ </string>
+ <string name="mesh_status_too_many_vertices">
+ 細節層次裡,頂點數目太多。
+ </string>
+ <string name="mesh_status_missing_lod">
+ 缺ä¹éœ€è¦çš„細節層次。
+ </string>
+ <string name="mesh_status_invalid_material_list">
+ 細節層次æ料並éžåƒè€ƒæ¨¡åž‹çš„å­é›†åˆã€‚
+ </string>
+ <string name="layer_all">
+ 全部
+ </string>
+ <string name="decomposing">
+ 分æžä¸­â€¦
+ </string>
+ <string name="simplifying">
+ 簡化中…
+ </string>
+ <string name="tbd">
+ (未定)
+ </string>
+ <panel name="left_panel">
+ <panel name="model_name_representation_panel">
+ <text name="name_label">
+ 模型å稱:
+ </text>
+ <text name="model_category_label">
+ 這模型代表…
+ </text>
+ <combo_box name="model_category_combo">
+ <combo_item label="é¸æ“‡ä¸€é ……" name="Choose one"/>
+ <combo_item label="化身形狀" name="Avatar shape"/>
+ <combo_item label="化身附件" name="Avatar attachment"/>
+ <combo_item label="會移動的物件(車輛ã€å‹•ç‰©ï¼‰" name="Moving object (vehicle, animal)"/>
+ <combo_item label="建製元件" name="Building Component"/>
+ <combo_item label="大型ã€ä¸æœƒç§»å‹•ç­‰é¡žåž‹" name="Large, non moving etc"/>
+ <combo_item label="較å°åž‹ã€ä¸æœƒç§»å‹•ç­‰é¡žåž‹" name="Smaller, non-moving etc"/>
+ <combo_item label="並éžå…¶ä¸­ä»»ä½•ä¸€å€‹" name="Not really any of these"/>
+ </combo_box>
+ </panel>
+ <tab_container name="import_tab">
+ <panel label="細節層次" name="lod_panel" title="細節層次">
+ <text initial_value="來æº" name="source" value="來æº"/>
+ <text initial_value="三角形" name="triangles" value="三角形"/>
+ <text initial_value="頂點" name="vertices" value="頂點"/>
+ <text initial_value="高" name="high_label" value="高"/>
+ <combo_box name="lod_source_high">
+ <item name="Load from file" value="從檔案載入"/>
+ <item name="Generate" value="產生"/>
+ </combo_box>
+ <button label="ç€è¦½â€¦" name="lod_browse_high"/>
+ <combo_box name="lod_mode_high">
+ <item name="Triangle Limit" value="三角形上é™"/>
+ <item name="Error Threshold" value="錯誤門檻"/>
+ </combo_box>
+ <text initial_value="0" name="high_triangles" value="0"/>
+ <text initial_value="0" name="high_vertices" value="0"/>
+ <text initial_value="中" name="medium_label" value="中"/>
+ <combo_box name="lod_source_medium">
+ <item name="Load from file" value="從檔案載入"/>
+ <item name="Generate" value="產生"/>
+ <item name="Use LoD above" value="以上使用低階細節"/>
+ </combo_box>
+ <button label="ç€è¦½â€¦" name="lod_browse_medium"/>
+ <combo_box name="lod_mode_medium">
+ <item name="Triangle Limit" value="三角形上é™"/>
+ <item name="Error Threshold" value="錯誤門檻"/>
+ </combo_box>
+ <text initial_value="0" name="medium_triangles" value="0"/>
+ <text initial_value="0" name="medium_vertices" value="0"/>
+ <text initial_value="低" name="low_label" value="低"/>
+ <combo_box name="lod_source_low">
+ <item name="Load from file" value="從檔案載入"/>
+ <item name="Generate" value="產生"/>
+ <item name="Use LoD above" value="以上使用低階細節"/>
+ </combo_box>
+ <button label="ç€è¦½â€¦" name="lod_browse_low"/>
+ <combo_box name="lod_mode_low">
+ <item name="Triangle Limit" value="三角形上é™"/>
+ <item name="Error Threshold" value="錯誤門檻"/>
+ </combo_box>
+ <text initial_value="0" name="low_triangles" value="0"/>
+ <text initial_value="0" name="low_vertices" value="0"/>
+ <text initial_value="最低" name="lowest_label" value="最低"/>
+ <combo_box name="lod_source_lowest">
+ <item name="Load from file" value="從檔案載入"/>
+ <item name="Generate" value="產生"/>
+ <item name="Use LoD above" value="以上使用低階細節"/>
+ </combo_box>
+ <button label="ç€è¦½â€¦" name="lod_browse_lowest"/>
+ <combo_box name="lod_mode_lowest">
+ <item name="Triangle Limit" value="三角形上é™"/>
+ <item name="Error Threshold" value="錯誤門檻"/>
+ </combo_box>
+ <text initial_value="0" name="lowest_triangles" value="0"/>
+ <text initial_value="0" name="lowest_vertices" value="0"/>
+ <check_box label="產生法線" name="gen_normals"/>
+ <text initial_value="皺褶角度:" name="crease_label" value="皺褶角度:"/>
+ <spinner name="crease_angle" value="75"/>
+ </panel>
+ <panel label="物ç†" name="physics_panel">
+ <panel name="physics geometry">
+ <text name="first_step_name">
+ 步驟 1:細節層次
+ </text>
+ <combo_box name="physics_lod_combo" tool_tip="物ç†å½¢ç‹€æ‰€æŽ¡ç”¨çš„細節層次">
+ <combo_item name="choose_one">
+ é¸æ“‡ä¸€é ……
+ </combo_item>
+ <combo_item name="physics_high">
+ 高
+ </combo_item>
+ <combo_item name="physics_medium">
+ 中
+ </combo_item>
+ <combo_item name="physics_low">
+ 低
+ </combo_item>
+ <combo_item name="physics_lowest">
+ 最低
+ </combo_item>
+ <combo_item name="load_from_file">
+ 來自檔案
+ </combo_item>
+ </combo_box>
+ <button label="ç€è¦½â€¦" name="physics_browse"/>
+ </panel>
+ <panel name="physics analysis">
+ <text name="method_label">
+ 步驟 2:分æž
+ </text>
+ <text name="analysis_method_label">
+ 方法:
+ </text>
+ <text name="quality_label">
+ å“質:
+ </text>
+ <text name="smooth_method_label">
+ 平滑:
+ </text>
+ <check_box label="關閉洞å£" name="Close Holes (Slow)"/>
+ <button label="分æž" name="Decompose"/>
+ <button label="å–消" name="decompose_cancel"/>
+ </panel>
+ <panel name="physics simplification">
+ <text name="second_step_label">
+ 步驟 3:簡化
+ </text>
+ <text name="simp_method_header">
+ 方法:
+ </text>
+ <text name="pass_method_header">
+ 階段數:
+ </text>
+ <text name="Detail Scale label">
+ 細節比例:
+ </text>
+ <text name="Retain%_label">
+ ä¿ç•™ï¼š
+ </text>
+ <combo_box name="Combine Quality" value="1"/>
+ <button label="簡化" name="Simplify"/>
+ <button label="å–消" name="simplify_cancel"/>
+ </panel>
+ <panel name="physics info">
+ <text name="results_text">
+ çµæžœï¼š
+ </text>
+ <text name="physics_triangles">
+ 三角形:[TRIANGLES],
+ </text>
+ <text name="physics_points">
+ 頂點:[POINTS],
+ </text>
+ <text name="physics_hulls">
+ 殼é¢ï¼š[HULLS]
+ </text>
+ </panel>
+ </panel>
+ <panel label="上傳é¸é …" name="modifiers_panel">
+ <text name="scale_label">
+ 比例(1 = 原比例):
+ </text>
+ <spinner name="import_scale" value="1.0"/>
+ <text name="dimensions_label">
+ è¦æ ¼ï¼š
+ </text>
+ <text name="import_dimensions">
+ [X] X [Y] X [Z]
+ </text>
+ <check_box label="包å«æ質" name="upload_textures"/>
+ <text name="include_label">
+ 僅é™åŒ–身模型:
+ </text>
+ <check_box label="包å«è¡¨çš®é‡é‡" name="upload_skin"/>
+ <check_box label="包å«æŽ¥é»žä½ç½®" name="upload_joints"/>
+ <text name="pelvis_offset_label">
+ Z åè·ï¼ˆå‡é«˜æˆ–é™ä½ŽåŒ–身):
+ </text>
+ <spinner name="pelvis_offset" value="0.0"/>
+ </panel>
+ </tab_container>
+ <panel name="weights_and_warning_panel">
+ <button label="計算é‡é‡å’Œè²»ç”¨" name="calculate_btn" tool_tip="計算é‡é‡å’Œè²»ç”¨"/>
+ <button label="å–消" name="cancel_btn"/>
+ <button label="上傳" name="ok_btn" tool_tip="上傳至模擬器"/>
+ <button label="清除設定並é‡è¨­å½¢å¼" name="reset_btn"/>
+ <text name="upload_fee">
+ 上傳費用:L$ [FEE]
+ </text>
+ <text name="prim_weight">
+ 土地è¡æ“Šé‡ï¼š[EQ]
+ </text>
+ <text name="download_weight">
+ 下載:[ST]
+ </text>
+ <text name="physics_weight">
+ 物ç†ï¼š[PH]
+ </text>
+ <text name="server_weight">
+ 伺æœå™¨ï¼š[SIM]
+ </text>
+ <text name="warning_title">
+ 附註:
+ </text>
+ <text name="warning_message">
+ 你無權上傳網é¢æ¨¡åž‹ã€‚ [[VURL] 瞭解如何]通éŽèªè­‰ã€‚
+ </text>
+ <text name="status">
+ [STATUS]
+ </text>
+ </panel>
+ </panel>
+ <text name="lod_label">
+ é è¦½ï¼š
+ </text>
+ <panel name="right_panel">
+ <combo_box name="preview_lod_combo" tool_tip="è¦åœ¨å‘ˆåƒé è¦½ä¸­å¯Ÿçœ‹çš„細節層次">
+ <combo_item name="high">
+ 高
+ </combo_item>
+ <combo_item name="medium">
+ 中
+ </combo_item>
+ <combo_item name="low">
+ 低
+ </combo_item>
+ <combo_item name="lowest">
+ 最低
+ </combo_item>
+ </combo_box>
+ <text name="label_display">
+ 顯示…
+ </text>
+ <check_box label="é‚Š" name="show_edges"/>
+ <check_box label="物ç†" name="show_physics"/>
+ <check_box label="æ質" name="show_textures"/>
+ <check_box label="表皮é‡é‡" name="show_skin_weight"/>
+ <check_box label="接點" name="show_joint_positions"/>
+ <text name="physics_explode_label">
+ é è¦½ä¼¸å±•ï¼š
+ </text>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_moveview.xml b/indra/newview/skins/default/xui/zh/floater_moveview.xml
index e1155bdf34..0b267e8fae 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_moveview.xml
+++ b/indra/newview/skins/default/xui/zh/floater_moveview.xml
@@ -1,28 +1,28 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="move_floater">
+<floater name="move_floater" title="行走 / 跑步 / 飛行">
<string name="walk_forward_tooltip">
- Walk Forward (press Up Arrow or W)
+ å‘å‰èµ°ï¼ˆæŒ‰ä¸‹å‘上箭頭或 W éµï¼‰
</string>
<string name="walk_back_tooltip">
- Walk Backwards (press Down Arrow or S)
+ 倒退行走(按下å‘下箭頭或 S éµï¼‰
</string>
<string name="walk_left_tooltip">
- Walk left (press Shift + Left Arrow or A)
+ å‘左走(按下 Shift 加左方å‘éµæˆ–按 A éµï¼‰
</string>
<string name="walk_right_tooltip">
- Walk right (press Shift + Right Arrow or D)
+ å‘å³èµ°ï¼ˆæŒ‰ä¸‹ Shift 加å³æ–¹å‘éµæˆ–按 D éµï¼‰
</string>
<string name="run_forward_tooltip">
- Run Forward (press Up Arrow or W)
+ å‘å‰è·‘(按下å‘上箭頭或 W éµï¼‰
</string>
<string name="run_back_tooltip">
- Run Backwards (press Down Arrow or S)
+ 倒退跑步(按下å‘下箭頭或 S éµï¼‰
</string>
<string name="run_left_tooltip">
- Run left (press Shift + Left Arrow or A)
+ å‘左跑(按下 Shift + 左方å‘éµæˆ–按 A éµï¼‰
</string>
<string name="run_right_tooltip">
- Run right (press Shift + Right Arrow or D)
+ å‘å³è·‘(按下 Shift + å³æ–¹å‘éµæˆ–按 D éµï¼‰
</string>
<string name="fly_forward_tooltip">
å‘å‰é£›ï¼ˆæŒ‰ä¸‹å‘上箭頭或 W éµï¼‰
@@ -65,7 +65,7 @@
<joystick_turn name="forward btn" tool_tip="å‘å‰èµ°ï¼ˆæŒ‰å‘上方å‘éµæˆ–按 W éµï¼‰"/>
<joystick_turn name="backward btn" tool_tip="å‘後退(按å‘下方å‘éµæˆ–按 S éµï¼‰"/>
<button name="move up btn" tool_tip="å‘上飛(按下 E éµï¼‰"/>
- <button name="move down btn" tool_tip="å‘下飛(按下 C 建)"/>
+ <button name="move down btn" tool_tip="å‘下飛(按下 C éµï¼‰"/>
</panel>
<panel name="panel_modes">
<button label="" name="mode_walk_btn" tool_tip="行走模å¼"/>
diff --git a/indra/newview/skins/default/xui/zh/floater_mute_object.xml b/indra/newview/skins/default/xui/zh/floater_mute_object.xml
index 606e061395..64998d3e28 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_mute_object.xml
+++ b/indra/newview/skins/default/xui/zh/floater_mute_object.xml
@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="block by name" title="ä¾å稱å°éŽ–物件">
<text name="message">
- Block an object:
+ å°éŽ–一個物件:
</text>
<line_editor name="object_name">
物件å稱
</line_editor>
<text name="note">
- * Only blocks object text, not sounds
+ * åªå°éŽ–物件文字,ä¸å°éŽ–è²éŸ³
</text>
<button label="確定" name="OK"/>
<button label="å–消" name="Cancel"/>
diff --git a/indra/newview/skins/default/xui/zh/floater_my_appearance.xml b/indra/newview/skins/default/xui/zh/floater_my_appearance.xml
new file mode 100755
index 0000000000..217ea5d1f9
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/floater_my_appearance.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="floater_my_appearance" title="外觀">
+ <panel label="編輯外觀" name="main_panel"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_my_inventory.xml b/indra/newview/skins/default/xui/zh/floater_my_inventory.xml
new file mode 100755
index 0000000000..187597f4eb
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/floater_my_inventory.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="floater_my_inventory" title="收ç´å€"/>
diff --git a/indra/newview/skins/default/xui/zh/floater_nearby_chat.xml b/indra/newview/skins/default/xui/zh/floater_nearby_chat.xml
deleted file mode 100644
index 38a5dab523..0000000000
--- a/indra/newview/skins/default/xui/zh/floater_nearby_chat.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="nearby_chat" title="附近的èŠå¤©">
- <check_box label="Translate chat" name="translate_chat_checkbox"/>
-</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_notification.xml b/indra/newview/skins/default/xui/zh/floater_notification.xml
index 1e0e207fb0..1e0e207fb0 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_notification.xml
+++ b/indra/newview/skins/default/xui/zh/floater_notification.xml
diff --git a/indra/newview/skins/default/xui/zh/floater_notifications_console.xml b/indra/newview/skins/default/xui/zh/floater_notifications_console.xml
index 3478761b0b..3478761b0b 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_notifications_console.xml
+++ b/indra/newview/skins/default/xui/zh/floater_notifications_console.xml
diff --git a/indra/newview/skins/default/xui/zh/floater_object_weights.xml b/indra/newview/skins/default/xui/zh/floater_object_weights.xml
new file mode 100755
index 0000000000..d2875b24b4
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/floater_object_weights.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="object_weights" title="進階">
+ <floater.string name="nothing_selected" value="--"/>
+ <text name="selected_text" value="å·²é¸"/>
+ <text name="objects" value="--"/>
+ <text name="objects_label" value="物件"/>
+ <text name="prims" value="--"/>
+ <text name="prims_label" value="幾何元件"/>
+ <text name="weights_of_selected_text" value="所é¸ç‰©é‡é‡"/>
+ <text name="download" value="--"/>
+ <text name="download_label" value="下載"/>
+ <text name="physics" value="--"/>
+ <text name="physics_label" value="物ç†"/>
+ <text name="server" value="--"/>
+ <text name="server_label" value="伺æœå™¨"/>
+ <text name="display" value="--"/>
+ <text name="display_label" value="顯示"/>
+ <text name="land_impacts_text" value="土地è¡æ“Šé‡"/>
+ <text name="selected" value="--"/>
+ <text name="selected_label" value="é¸æ“‡"/>
+ <text name="rezzed_on_land" value="--"/>
+ <text name="rezzed_on_land_label" value="已產生到土地上"/>
+ <text name="remaining_capacity" value="--"/>
+ <text name="remaining_capacity_label" value="剩餘容ç´é‡"/>
+ <text name="total_capacity" value="--"/>
+ <text name="total_capacity_label" value="總容ç´é‡"/>
+ <text name="help_SLURL" value="[secondlife:///app/help/object_weights 這是什麼?]"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_openobject.xml b/indra/newview/skins/default/xui/zh/floater_openobject.xml
index 61ac3cb1fc..ce6869487a 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_openobject.xml
+++ b/indra/newview/skins/default/xui/zh/floater_openobject.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="objectcontents" title="物件內容">
<text name="object_name">
- [DESC]:
+ [DESC]:
</text>
<button label="覆製到收ç´å€" label_selected="覆製到收ç´å€" name="copy_to_inventory_button"/>
<button label="覆製且穿上" label_selected="覆製且穿上" name="copy_and_wear_button"/>
diff --git a/indra/newview/skins/default/xui/zh/floater_outfit_save_as.xml b/indra/newview/skins/default/xui/zh/floater_outfit_save_as.xml
index a557e1c2e3..9e786edcdd 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_outfit_save_as.xml
+++ b/indra/newview/skins/default/xui/zh/floater_outfit_save_as.xml
@@ -3,9 +3,9 @@
<button label="儲存" label_selected="儲存" name="Save"/>
<button label="å–消" label_selected="å–消" name="Cancel"/>
<text name="Save item as:">
- 儲存我正在穿的為新è£æ‰®ï¼š
+ 儲存我ç¾åœ¨çš„穿著為新è£æ‰®ï¼š
</text>
<line_editor name="name ed">
- [DESC] (新)
+ [DESC](新)
</line_editor>
</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_outgoing_call.xml b/indra/newview/skins/default/xui/zh/floater_outgoing_call.xml
index 63da47f4de..e57374f4d7 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_outgoing_call.xml
+++ b/indra/newview/skins/default/xui/zh/floater_outgoing_call.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="outgoing call" title="CALLING">
+<floater name="outgoing call" title="打電話">
<floater.string name="lifetime">
5
</floater.string>
@@ -10,31 +10,31 @@
匿å
</floater.string>
<floater.string name="VoiceInviteP2P">
- 通話中。
+ 來電中。
</floater.string>
<floater.string name="VoiceInviteAdHoc">
- has joined a Voice Chat call with a conference chat.
+ 已加入多方語音通話。
</floater.string>
<text name="connecting">
- Connecting to [CALLEE_NAME]
+ 正在連通 [CALLEE_NAME]
</text>
<text name="calling">
- Calling [CALLEE_NAME]
+ 正在打給 [CALLEE_NAME]
</text>
<text name="noanswer">
- 無應答,請ç¨å€™å†è©¦ã€‚
+ 無人接è½ã€‚ è«‹ç¨å€™å†è©¦ä¸€æ¬¡ã€‚
</text>
<text name="nearby">
- You have been disconnected from [VOICE_CHANNEL_NAME]. [RECONNECT_NEARBY]
+ 你的 [VOICE_CHANNEL_NAME] 通話已經中斷。 [RECONNECT_NEARBY]
</text>
<text name="nearby_P2P_by_other">
- Your call has ended. [RECONNECT_NEARBY]
+ 你的通話已經çµæŸã€‚ [RECONNECT_NEARBY]
</text>
<text name="nearby_P2P_by_agent">
- You have ended the call. [RECONNECT_NEARBY]
+ 你已經çµæŸé€šè©±ã€‚ [RECONNECT_NEARBY]
</text>
<text name="leaving">
- Leaving [CURRENT_CHAT].
+ 離開 [CURRENT_CHAT]。
</text>
<button label="å–消" label_selected="å–消" name="Cancel"/>
</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_pathfinding_characters.xml b/indra/newview/skins/default/xui/zh/floater_pathfinding_characters.xml
new file mode 100755
index 0000000000..e6971d111f
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/floater_pathfinding_characters.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="floater_pathfinding_characters" title="尋徑角色">
+ <floater.string name="messaging_get_inprogress">
+ 尋徑角色查詢中…
+ </floater.string>
+ <floater.string name="messaging_get_error">
+ 查詢尋徑角色時出錯。
+ </floater.string>
+ <floater.string name="messaging_complete_none_found">
+ 沒有尋徑角色。
+ </floater.string>
+ <floater.string name="messaging_complete_available">
+ 從 [NUM_TOTAL] 個角色中é¸å–了 [NUM_SELECTED] 個。
+ </floater.string>
+ <floater.string name="messaging_not_enabled">
+ 這地å€ä¸¦æœªå•Ÿç”¨å°‹å¾‘。
+ </floater.string>
+ <floater.string name="character_cpu_time">
+ [CPU_TIME] 微秒
+ </floater.string>
+ <floater.string name="character_owner_loading">
+ [Loading]
+ </floater.string>
+ <floater.string name="character_owner_unknown">
+ [Unknown]
+ </floater.string>
+ <floater.string name="character_owner_group">
+ [group]
+ </floater.string>
+ <panel>
+ <scroll_list name="objects_scroll_list">
+ <scroll_list.columns label="å稱" name="name"/>
+ <scroll_list.columns label="æè¿°" name="description"/>
+ <scroll_list.columns label="所有人" name="owner"/>
+ <scroll_list.columns label="中央處ç†å™¨" name="cpu_time"/>
+ <scroll_list.columns label="高度" name="altitude"/>
+ </scroll_list>
+ <text name="messaging_status">
+ 角色:
+ </text>
+ <button label="刷新清單" name="refresh_objects_list"/>
+ <button label="å…¨é¸" name="select_all_objects"/>
+ <button label="全都ä¸é¸" name="select_none_objects"/>
+ </panel>
+ <panel>
+ <text name="actions_label">
+ 所é¸è§’色所採動作:
+ </text>
+ <check_box label="顯示指標" name="show_beacon"/>
+ <check_box label="顯示物ç†å›Š" name="show_physics_capsule"/>
+ <button label="å–å¾—" name="take_objects"/>
+ <button label="æ‹¿å–副本" name="take_copy_objects"/>
+ <button label="瞬間傳é€æˆ‘到那裡" name="teleport_me_to_object" tool_tip="åªåœ¨é¸å–了一個角色時啟用。"/>
+ <button label="退回" name="return_objects"/>
+ <button label="刪除" name="delete_objects"/>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_pathfinding_console.xml b/indra/newview/skins/default/xui/zh/floater_pathfinding_console.xml
new file mode 100755
index 0000000000..be009b54d8
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/floater_pathfinding_console.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="floater_pathfinding_console" title="尋徑察看 / 測試">
+ <floater.string name="navmesh_viewer_status_library_not_implemented">
+ 找ä¸åˆ°å°‹å¾‘函å¼åº«å¯¦ä½œã€‚
+ </floater.string>
+ <floater.string name="navmesh_viewer_status_region_not_enabled">
+ 這地å€ä¸¦æœªå•Ÿç”¨å°‹å¾‘。
+ </floater.string>
+ <floater.string name="navmesh_viewer_status_region_loading">
+ 等待地å€å®Œæˆè¼‰å…¥ã€‚
+ </floater.string>
+ <floater.string name="navmesh_viewer_status_checking_version">
+ 正在檢查導航網é¢ç‹€æ…‹ã€‚
+ </floater.string>
+ <floater.string name="navmesh_viewer_status_downloading">
+ 正在下載導航網é¢ã€‚
+ </floater.string>
+ <floater.string name="navmesh_viewer_status_updating">
+ 伺æœå™¨ä¸Šçš„導航網é¢å·²è®Šæ›´ã€‚ 正在下載最新的導航網é¢ã€‚
+ </floater.string>
+ <floater.string name="navmesh_viewer_status_has_navmesh">
+ 最新的導航網é¢ä¸‹è¼‰å®Œæˆã€‚
+ </floater.string>
+ <floater.string name="navmesh_viewer_status_error">
+ 無法完æˆå°Žèˆªç¶²é¢ä¸‹è¼‰ã€‚
+ </floater.string>
+ <floater.string name="navmesh_simulator_status_pending">
+ 導航網é¢æœ‰è®Šæ›´å¾…存。
+ </floater.string>
+ <floater.string name="navmesh_simulator_status_building">
+ 正在建構導航網é¢ã€‚
+ </floater.string>
+ <floater.string name="navmesh_simulator_status_some_pending">
+ æŸäº›å°Žèˆªç¶²é¢åœ°å€æœ‰è®Šæ›´å¾…存。
+ </floater.string>
+ <floater.string name="navmesh_simulator_status_some_building">
+ 正在建構æŸäº›å°Žèˆªç¶²é¢åœ°å€ã€‚
+ </floater.string>
+ <floater.string name="navmesh_simulator_status_pending_and_building">
+ æŸäº›å°Žèˆªç¶²é¢åœ°å€æœ‰è®Šæ›´å¾…存,其他的正在建構中。
+ </floater.string>
+ <floater.string name="navmesh_simulator_status_complete">
+ 導航網é¢å·²å…¨é¢æ›´æ–°ã€‚
+ </floater.string>
+ <floater.string name="pathing_library_not_implemented">
+ 找ä¸åˆ°å°‹å¾‘函å¼åº«å¯¦ä½œã€‚
+ </floater.string>
+ <floater.string name="pathing_region_not_enabled">
+ 這地å€ä¸¦æœªå•Ÿç”¨å°‹å¾‘。
+ </floater.string>
+ <floater.string name="pathing_choose_start_and_end_points">
+ è«‹é¸æ“‡èµ·é»žå’Œçµ‚點。
+ </floater.string>
+ <floater.string name="pathing_choose_start_point">
+ è«‹é¸æ“‡èµ·é»žã€‚
+ </floater.string>
+ <floater.string name="pathing_choose_end_point">
+ è«‹é¸æ“‡çµ‚點。
+ </floater.string>
+ <floater.string name="pathing_path_valid">
+ 路徑以橘色顯示。
+ </floater.string>
+ <floater.string name="pathing_path_invalid">
+ 在所é¸çš„點之間找ä¸åˆ°è·¯å¾‘。
+ </floater.string>
+ <floater.string name="pathing_error">
+ 產生路徑時出錯。
+ </floater.string>
+ <tab_container name="view_test_tab_container">
+ <panel label="視角" name="view_panel">
+ <text name="show_label">
+ 顯示:
+ </text>
+ <check_box label="世界" name="show_world"/>
+ <check_box label="僅é™å¯ç§»å‹•çš„" name="show_world_movables_only"/>
+ <check_box label="導航網é¢" name="show_navmesh"/>
+ <text name="show_walkability_label">
+ 顯示å¯è¡Œèµ°åœ°åœ–:
+ </text>
+ <combo_box name="show_heatmap_mode">
+ <combo_box.item label="ä¸é¡¯ç¤º" name="show_heatmap_mode_none"/>
+ <combo_box.item label="類型 A 角色" name="show_heatmap_mode_a"/>
+ <combo_box.item label="類型 B 角色" name="show_heatmap_mode_b"/>
+ <combo_box.item label="類型 C 角色" name="show_heatmap_mode_c"/>
+ <combo_box.item label="類型 D 角色" name="show_heatmap_mode_d"/>
+ </combo_box>
+ <check_box label="å¯è¡Œèµ°çš„" name="show_walkables"/>
+ <check_box label="實質體ç©" name="show_material_volumes"/>
+ <check_box label="éœæ…‹éšœç¤™" name="show_static_obstacles"/>
+ <check_box label="排除體ç©" name="show_exclusion_volumes"/>
+ <check_box label="æ°´å¹³é¢" name="show_water_plane"/>
+ <check_box label="å…· X å…‰é€è¦–力" name="show_xray"/>
+ </panel>
+ <panel label="測試路徑" name="test_panel">
+ <text name="ctrl_click_label">
+ æŒ‰ä½ Ctrl 並點按å³å¯é¸æ“‡èµ·é»žã€‚
+ </text>
+ <text name="shift_click_label">
+ æŒ‰ä½ Shift 並點按å³å¯é¸æ“‡çµ‚點。
+ </text>
+ <text name="character_width_label">
+ 角色寬度
+ </text>
+ <slider name="character_width" value="1"/>
+ <text name="character_width_unit_label">
+ 公尺
+ </text>
+ <text name="character_type_label">
+ 角色類型
+ </text>
+ <combo_box name="path_character_type">
+ <combo_box.item label="ç„¡" name="path_character_type_none"/>
+ <combo_box.item label="A" name="path_character_type_a"/>
+ <combo_box.item label="B" name="path_character_type_b"/>
+ <combo_box.item label="C" name="path_character_type_c"/>
+ <combo_box.item label="D" name="path_character_type_d"/>
+ </combo_box>
+ <button label="清除路徑" name="clear_path"/>
+ </panel>
+ </tab_container>
+</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_pathfinding_linksets.xml b/indra/newview/skins/default/xui/zh/floater_pathfinding_linksets.xml
new file mode 100755
index 0000000000..22e5d2e846
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/floater_pathfinding_linksets.xml
@@ -0,0 +1,167 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="floater_pathfinding_linksets" title="尋徑è¯çµé›†">
+ <floater.string name="messaging_get_inprogress">
+ 尋徑è¯çµé›†æŸ¥è©¢ä¸­â€¦
+ </floater.string>
+ <floater.string name="messaging_get_error">
+ 查詢尋徑è¯çµé›†æ™‚出錯。
+ </floater.string>
+ <floater.string name="messaging_set_inprogress">
+ 正在修改所é¸å°‹å¾‘è¯çµé›†â€¦
+ </floater.string>
+ <floater.string name="messaging_set_error">
+ 修改所é¸å°‹å¾‘è¯çµé›†æ™‚出錯。
+ </floater.string>
+ <floater.string name="messaging_complete_none_found">
+ 沒有尋徑è¯çµé›†ã€‚
+ </floater.string>
+ <floater.string name="messaging_complete_available">
+ 從 [NUM_TOTAL] 個è¯çµé›†ä¸­é¸å–了 [NUM_SELECTED] 個。
+ </floater.string>
+ <floater.string name="messaging_not_enabled">
+ 這地å€ä¸¦æœªå•Ÿç”¨å°‹å¾‘。
+ </floater.string>
+ <floater.string name="linkset_terrain_name">
+ [Terrain]
+ </floater.string>
+ <floater.string name="linkset_terrain_description">
+ --
+ </floater.string>
+ <floater.string name="linkset_terrain_owner">
+ --
+ </floater.string>
+ <floater.string name="linkset_terrain_scripted">
+ --
+ </floater.string>
+ <floater.string name="linkset_terrain_land_impact">
+ --
+ </floater.string>
+ <floater.string name="linkset_terrain_dist_from_you">
+ --
+ </floater.string>
+ <floater.string name="linkset_owner_loading">
+ [Loading]
+ </floater.string>
+ <floater.string name="linkset_owner_unknown">
+ [Unknown]
+ </floater.string>
+ <floater.string name="linkset_owner_group">
+ [group]
+ </floater.string>
+ <floater.string name="linkset_is_scripted">
+ 是
+ </floater.string>
+ <floater.string name="linkset_is_not_scripted">
+ å¦
+ </floater.string>
+ <floater.string name="linkset_is_unknown_scripted">
+ 未知
+ </floater.string>
+ <floater.string name="linkset_use_walkable">
+ å¯è¡Œèµ°çš„
+ </floater.string>
+ <floater.string name="linkset_use_static_obstacle">
+ éœæ…‹éšœç¤™
+ </floater.string>
+ <floater.string name="linkset_use_dynamic_obstacle">
+ å¯ç§»å‹•éšœç¤™
+ </floater.string>
+ <floater.string name="linkset_use_material_volume">
+ 實質體ç©
+ </floater.string>
+ <floater.string name="linkset_use_exclusion_volume">
+ 排除體ç©
+ </floater.string>
+ <floater.string name="linkset_use_dynamic_phantom">
+ å¯ç§»å‹•å¹»å½±
+ </floater.string>
+ <floater.string name="linkset_is_terrain">
+ [unmodifiable]
+ </floater.string>
+ <floater.string name="linkset_is_restricted_state">
+ [restricted]
+ </floater.string>
+ <floater.string name="linkset_is_non_volume_state">
+ [concave]
+ </floater.string>
+ <floater.string name="linkset_is_restricted_non_volume_state">
+ [restricted,concave]
+ </floater.string>
+ <floater.string name="linkset_choose_use">
+ é¸æ“‡è¯çµé›†çš„使用…
+ </floater.string>
+ <panel>
+ <combo_box name="filter_by_linkset_use">
+ <combo_box.item label="按è¯çµé›†çš„使用來éŽæ¿¾â€¦" name="filter_by_linkset_use_none"/>
+ <combo_box.item label="å¯è¡Œèµ°çš„" name="filter_by_linkset_use_walkable"/>
+ <combo_box.item label="éœæ…‹éšœç¤™" name="filter_by_linkset_use_static_obstacle"/>
+ <combo_box.item label="å¯ç§»å‹•éšœç¤™" name="filter_by_linkset_use_dynamic_obstacle"/>
+ <combo_box.item label="實質體ç©" name="filter_by_linkset_use_material_volume"/>
+ <combo_box.item label="排除體ç©" name="filter_by_linkset_use_exclusion_volume"/>
+ <combo_box.item label="å¯ç§»å‹•å¹»å½±" name="filter_by_linkset_use_dynamic_phantom"/>
+ </combo_box>
+ <button label="套用" name="apply_filters"/>
+ <button label="清除" name="clear_filters"/>
+ <scroll_list name="objects_scroll_list">
+ <scroll_list.columns label="å稱(根幾何元件)" name="name"/>
+ <scroll_list.columns label="æ述(根幾何元件)" name="description"/>
+ <scroll_list.columns label="所有人" name="owner"/>
+ <scroll_list.columns label="有腳本" name="scripted"/>
+ <scroll_list.columns label="è¡æ“Š" name="land_impact"/>
+ <scroll_list.columns label="è·é›¢" name="dist_from_you"/>
+ <scroll_list.columns label="è¯çµé›†çš„使用" name="linkset_use"/>
+ <scroll_list.columns label="A %" name="a_percent"/>
+ <scroll_list.columns label="B %" name="b_percent"/>
+ <scroll_list.columns label="C %" name="c_percent"/>
+ <scroll_list.columns label="D %" name="d_percent"/>
+ </scroll_list>
+ <text name="messaging_status">
+ è¯çµé›†ï¼š
+ </text>
+ <button label="刷新清單" name="refresh_objects_list"/>
+ <button label="å…¨é¸" name="select_all_objects"/>
+ <button label="全都ä¸é¸" name="select_none_objects"/>
+ </panel>
+ <panel>
+ <check_box label="顯示指標" name="show_beacon"/>
+ <button label="å–å¾—" name="take_objects"/>
+ <button label="æ‹¿å–副本" name="take_copy_objects"/>
+ <button label="瞬間傳é€æˆ‘到那裡" name="teleport_me_to_object"/>
+ <button label="退回" name="return_objects"/>
+ <button label="刪除" name="delete_objects"/>
+ </panel>
+ <panel>
+ <text name="walkability_coefficients_label">
+ å¯è¡Œèµ°æ€§ï¼š
+ </text>
+ <text name="edit_a_label">
+ A
+ </text>
+ <line_editor name="edit_a_value" tool_tip="A 類型角色的å¯è¡Œèµ°æ€§ã€‚以類人類為範例角色類型。"/>
+ <text name="edit_b_label">
+ B
+ </text>
+ <line_editor name="edit_b_value" tool_tip="B 類型角色的å¯è¡Œèµ°æ€§ã€‚以ç¸é¡žç‚ºç¯„例角色類型。"/>
+ <text name="edit_c_label">
+ C
+ </text>
+ <line_editor name="edit_c_value" tool_tip="C 類型角色的å¯è¡Œèµ°æ€§ã€‚以機械類為範例角色類型。"/>
+ <text name="edit_d_label">
+ D
+ </text>
+ <line_editor name="edit_d_value" tool_tip="D 類型角色的å¯è¡Œèµ°æ€§ã€‚以其他種類為範例角色類型。"/>
+ <button label="套用變更" name="apply_edit_values"/>
+ <text name="suggested_use_a_label">
+ (類人類)
+ </text>
+ <text name="suggested_use_b_label">
+ (ç¸é¡žï¼‰
+ </text>
+ <text name="suggested_use_c_label">
+ (機械類)
+ </text>
+ <text name="suggested_use_d_label">
+ (其他)
+ </text>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_pay.xml b/indra/newview/skins/default/xui/zh/floater_pay.xml
index 0a823cd82e..69427605a4 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_pay.xml
+++ b/indra/newview/skins/default/xui/zh/floater_pay.xml
@@ -7,14 +7,14 @@
支付居民
</string>
<text name="payee_name">
- Test Name That Is Extremely Long To Check Clipping
+ 測試一個長度éžå¸¸éžå¸¸éžå¸¸é•·çš„å稱,檢查是å¦è¢«åˆ‡æ–·
</text>
<button label="L$1" label_selected="L$1" name="fastpay 1"/>
<button label="L$5" label_selected="L$5" name="fastpay 5"/>
<button label="L$10" label_selected="L$10" name="fastpay 10"/>
<button label="L$20" label_selected="L$20" name="fastpay 20"/>
<text name="amount text">
- 或,é¸æ“‡ä¸€å€‹é‡‘é¡ï¼š
+ 或é¸æ“‡ä¸€å€‹é‡‘é¡ï¼š
</text>
<button label="支付" label_selected="支付" name="pay btn"/>
<button label="å–消" label_selected="å–消" name="cancel btn"/>
diff --git a/indra/newview/skins/default/xui/zh/floater_pay_object.xml b/indra/newview/skins/default/xui/zh/floater_pay_object.xml
index 39259524d7..7d20b44bc6 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_pay_object.xml
+++ b/indra/newview/skins/default/xui/zh/floater_pay_object.xml
@@ -14,14 +14,14 @@
</text>
<icon name="icon_object" tool_tip="物件"/>
<text name="object_name_text">
- My awesome object with a really damn long name
+ 這是我å稱很長很長很長很長的一個很棒的物件
</text>
<button label="L$1" label_selected="L$1" name="fastpay 1"/>
<button label="L$5" label_selected="L$5" name="fastpay 5"/>
<button label="L$10" label_selected="L$10" name="fastpay 10"/>
<button label="L$20" label_selected="L$20" name="fastpay 20"/>
<text name="amount text">
- 或者,é¸æ“‡ä¸€å€‹é‡‘é¡ï¼š
+ 或é¸æ“‡ä¸€å€‹é‡‘é¡ï¼š
</text>
<button label="支付" label_selected="支付" name="pay btn"/>
<button label="å–消" label_selected="å–消" name="cancel btn"/>
diff --git a/indra/newview/skins/default/xui/zh/floater_people.xml b/indra/newview/skins/default/xui/zh/floater_people.xml
new file mode 100755
index 0000000000..f629f2f184
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/floater_people.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="floater_people" title="人群">
+ <panel_container name="main_panel">
+ <panel label="群組檔案" name="panel_group_info_sidetray"/>
+ <panel label="被å°éŽ–的居民與物件" name="panel_block_list_sidetray"/>
+ </panel_container>
+</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_perm_prefs.xml b/indra/newview/skins/default/xui/zh/floater_perm_prefs.xml
index 498848ee56..b38db59ff3 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_perm_prefs.xml
+++ b/indra/newview/skins/default/xui/zh/floater_perm_prefs.xml
@@ -4,10 +4,10 @@
<check_box label="與群組分享" name="share_with_group"/>
<check_box label="å…許任何人覆製" name="everyone_copy"/>
<text name="NextOwnerLabel">
- 下一個æ“有者å¯ä»¥ï¼š
+ 下一個所有人å¯ä»¥ï¼š
</text>
<check_box label="修改" name="next_owner_modify"/>
- <check_box label="覆製" name="next_owner_copy"/>
+ <check_box label="æšåº¨" name="next_owner_copy"/>
<check_box initial_value="true" label="轉售 / é€äºº" name="next_owner_transfer"/>
</panel>
<button label="確定" label_selected="確定" name="ok"/>
diff --git a/indra/newview/skins/default/xui/zh/floater_picks.xml b/indra/newview/skins/default/xui/zh/floater_picks.xml
new file mode 100755
index 0000000000..a8bfcd99e3
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/floater_picks.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="floater_picks" title="ç²¾é¸åœ°é»ž"/>
diff --git a/indra/newview/skins/default/xui/zh/floater_places.xml b/indra/newview/skins/default/xui/zh/floater_places.xml
new file mode 100755
index 0000000000..f6ef1e2141
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/floater_places.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="floater_places" title="地點">
+ <panel label="地點" name="main_panel"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_post_process.xml b/indra/newview/skins/default/xui/zh/floater_post_process.xml
index 0972c6dfa6..2908f7c1d0 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_post_process.xml
+++ b/indra/newview/skins/default/xui/zh/floater_post_process.xml
@@ -1,50 +1,50 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Post-Process Floater" title="POST-PROCESS SETTINGS">
+<floater name="Post-Process Floater" title="後處ç†è¨­å®šï¼š">
<tab_container name="Post-Process Tabs">
- <panel label="Color Filter" name="wmiColorFilterPanel">
- <check_box label="Enable" name="wmiColorFilterToggle"/>
+ <panel label="é¡è‰²éŽæ¿¾" name="wmiColorFilterPanel">
+ <check_box label="啟用" name="wmiColorFilterToggle"/>
<text name="wmiColorFilterBrightnessText">
- Brightness
+ 亮度
</text>
<text name="wmiColorFilterSaturationText">
- Saturation
+ 飽和度
</text>
<text name="wmiColorFilterContrastText">
- Contrast
+ å°æ¯”
</text>
<text name="wmiColorFilterBaseText">
- Contrast Base Color
+ å°æ¯”基本色
</text>
<slider label="R" name="wmiColorFilterBaseR"/>
<slider label="G" name="wmiColorFilterBaseG"/>
<slider label="B" name="wmiColorFilterBaseB"/>
<slider label="I" name="wmiColorFilterBaseI"/>
</panel>
- <panel label="Night Vision" name="wmiNightVisionPanel">
- <check_box label="Enable" name="wmiNightVisionToggle"/>
+ <panel label="夜視" name="wmiNightVisionPanel">
+ <check_box label="啟用" name="wmiNightVisionToggle"/>
<text name="wmiNightVisionBrightMultText">
- Light Amplification Multiple
+ 光放大å€æ•¸
</text>
<text name="wmiNightVisionNoiseSizeText">
- Noise Size
+ 噪音è¦æ¨¡
</text>
<text name="wmiNightVisionNoiseStrengthText">
- Noise Strength
+ 噪音強度
</text>
</panel>
- <panel label="Bloom" name="wmiBloomPanel">
- <check_box label="Enable" name="wmiBloomToggle"/>
+ <panel label="開花" name="wmiBloomPanel">
+ <check_box label="啟用" name="wmiBloomToggle"/>
<text name="wmiBloomExtractText">
- Luminosity Extraction
+ 光度èƒå–
</text>
<text name="wmiBloomSizeText">
- Bloom Size
+ 開花大å°
</text>
<text name="wmiBloomStrengthText">
- Bloom Strength
+ 開花強度
</text>
</panel>
- <panel label="Extras" name="Extras">
+ <panel label="其他" name="Extras">
<button label="LoadEffect" label_selected="LoadEffect" name="PPLoadEffect"/>
<button label="SaveEffect" label_selected="SaveEffect" name="PPSaveEffect"/>
<line_editor label="效果å稱" name="PPEffectNameEditor"/>
diff --git a/indra/newview/skins/default/xui/zh/floater_postcard.xml b/indra/newview/skins/default/xui/zh/floater_postcard.xml
deleted file mode 100644
index 6f6b75f468..0000000000
--- a/indra/newview/skins/default/xui/zh/floater_postcard.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Postcard" title="EMAIL SNAPSHOT">
- <floater.string name="default_subject">
- Postcard from [SECOND_LIFE].
- </floater.string>
- <floater.string name="default_message">
- Check this out!
- </floater.string>
- <floater.string name="upload_message">
- 傳é€ä¸­...
- </floater.string>
- <text name="to_label">
- 收件人電å­éƒµä»¶åœ°å€ï¼š
- </text>
- <text name="from_label">
- ä½ çš„é›»å­éƒµä»¶åœ°å€ï¼š
- </text>
- <text name="name_label">
- ä½ çš„å稱:
- </text>
- <text name="subject_label">
- 主旨:
- </text>
- <line_editor label="在此輸入你的主旨。" name="subject_form"/>
- <text name="msg_label">
- 訓æ¯ï¼š
- </text>
- <text_editor name="msg_form">
- 在此輸入你的訊æ¯ã€‚
- </text_editor>
- <button label="å–消" name="cancel_btn"/>
- <button label="é€å‡º" name="send_btn"/>
-</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_preferences.xml b/indra/newview/skins/default/xui/zh/floater_preferences.xml
index 396a4893e0..b0a27e8c1f 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_preferences.xml
+++ b/indra/newview/skins/default/xui/zh/floater_preferences.xml
@@ -3,11 +3,11 @@
<button label="確定" label_selected="確定" name="OK"/>
<button label="å–消" label_selected="å–消" name="Cancel"/>
<tab_container name="pref core">
- <panel label="一般" name="general"/>
- <panel label="圖形" name="display"/>
+ <panel label="基本設定" name="general"/>
+ <panel label="顯åƒ" name="display"/>
<panel label="è²éŸ³èˆ‡åª’é«”" name="audio"/>
<panel label="èŠå¤©" name="chat"/>
- <panel label="移動與視角" name="move"/>
+ <panel label="移動/視野" name="move"/>
<panel label="通知" name="msgs"/>
<panel label="é¡è‰²" name="colors"/>
<panel label="éš±ç§" name="im"/>
diff --git a/indra/newview/skins/default/xui/zh/floater_preferences_proxy.xml b/indra/newview/skins/default/xui/zh/floater_preferences_proxy.xml
new file mode 100755
index 0000000000..f91d5c5cdb
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/floater_preferences_proxy.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="Proxy Settings Floater" title="代ç†ä¼ºæœå™¨è¨­å®š">
+ <check_box initial_value="false" label="使用 HTTP 代ç†ä¼ºæœå™¨ç€è¦½ç¶²é " name="web_proxy_enabled"/>
+ <text name="http_proxy_label">
+ HTTP 代ç†ä¼ºæœå™¨ï¼š
+ </text>
+ <line_editor name="web_proxy_editor" tool_tip="你希望使用的 HTTP 代ç†ä¼ºæœå™¨çš„ DNS å稱或 IP ä½å€ã€‚"/>
+ <spinner label="埠號:" name="web_proxy_port" tool_tip="你希望使用的 HTTP 代ç†ä¼ºæœå™¨çš„埠號。"/>
+ <check_box label="使用 SOCKS 5 代ç†ä¼ºæœå™¨è™•ç† UDP 資料æµ" name="socks_proxy_enabled"/>
+ <text name="socks5_proxy_label">
+ SOCKS 5 代ç†ä¼ºæœå™¨ï¼š
+ </text>
+ <line_editor name="socks_proxy_editor" tool_tip="你希望使用的 SOCKS 5 代ç†ä¼ºæœå™¨çš„ DNS å稱或 IP ä½å€ã€‚"/>
+ <spinner label="埠號:" name="socks_proxy_port" tool_tip="你希望使用的 SOCKS 5 代ç†ä¼ºæœå™¨çš„埠號。"/>
+ <text name="socks_auth_label">
+ SOCKS é‘’èªï¼š
+ </text>
+ <radio_group name="socks5_auth_type">
+ <radio_item label="ç„¡é‘’èª" name="Socks5NoAuth" tool_tip="Socks5 代ç†ä¼ºæœå™¨ç„¡éœ€é‘’èªã€‚" value="ç„¡"/>
+ <radio_item label="使用者å稱 / 密碼" name="Socks5UserPass" tool_tip="Socks5 代ç†ä¼ºæœå™¨éœ€è¦é€éŽä½¿ç”¨è€…å稱 / 密碼鑒èªã€‚" value="UserPass"/>
+ </radio_group>
+ <text name="socks5_username_label">
+ 使用者å稱:
+ </text>
+ <text name="socks5_password_label">
+ 密碼:
+ </text>
+ <line_editor name="socks5_username" tool_tip="ä½ çš„ SOCKS 5 伺æœå™¨é‘’èªæ‰€ç”¨çš„使用者å稱"/>
+ <line_editor name="socks5_password" tool_tip="ä½ çš„ SOCKS 5 伺æœå™¨é‘’èªæ‰€ç”¨çš„密碼"/>
+ <text name="other_proxy_label">
+ 其他 HTTP 資料æµä»£ç†ä¼ºæœå™¨ï¼š
+ </text>
+ <radio_group name="other_http_proxy_type">
+ <radio_item label="ä¸ä½¿ç”¨ä»£ç†ä¼ºæœå™¨" name="OtherNoProxy" tool_tip="éžç¶²é çš„ HTTP 資料æµä¸æœƒè¢«å°Žå‘任何代ç†ä¼ºæœå™¨ã€‚" value="ç„¡"/>
+ <radio_item label="使用 HTTP 代ç†ä¼ºæœå™¨" name="OtherHTTPProxy" tool_tip="éžç¶²é çš„ HTTP 資料æµå°‡å°Žå‘所設的網é ä»£ç†ä¼ºæœå™¨ã€‚" value="網é "/>
+ <radio_item label="使用 SOCKS 5 代ç†ä¼ºæœå™¨" name="OtherSocksProxy" tool_tip="éžç¶²é çš„ HTTP 資料æµå°‡å°Žå‘所設的 Socks 5 代ç†ä¼ºæœå™¨ã€‚" value="網路套接"/>
+ </radio_group>
+ <button label="確定" label_selected="確定" name="OK"/>
+ <button label="å–消" label_selected="å–消" name="Cancel"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_preview_animation.xml b/indra/newview/skins/default/xui/zh/floater_preview_animation.xml
index c435ddc0bd..b94d67b7ef 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_preview_animation.xml
+++ b/indra/newview/skins/default/xui/zh/floater_preview_animation.xml
@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="preview_anim">
<floater.string name="Title">
- 動作: [NAME]
+ 動作:[NAME]
</floater.string>
<text name="desc txt">
æ述:
</text>
- <button label="播放於虛擬世界" label_selected="åœæ­¢" name="Anim play btn" tool_tip="Play this animation so that others can see it"/>
- <button label="播放於本地" label_selected="åœæ­¢" name="Anim audition btn" tool_tip="Play this animation so that only you can see it"/>
+ <button label="在虛擬世界播放" label_selected="åœæ­¢" name="Inworld" tool_tip="播放此動作讓他人看見"/>
+ <button label="在本地播放" label_selected="åœæ­¢" name="Locally" tool_tip="播放此動作,åªçµ¦è‡ªå·±çœ‹"/>
</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_preview_gesture.xml b/indra/newview/skins/default/xui/zh/floater_preview_gesture.xml
index ad49370423..be75038a09 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_preview_gesture.xml
+++ b/indra/newview/skins/default/xui/zh/floater_preview_gesture.xml
@@ -1,16 +1,16 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="gesture_preview">
<floater.string name="step_anim">
- Animation to play:
+ è¦æ’­æ”¾çš„動作:
</floater.string>
<floater.string name="step_sound">
- Sound to play:
+ è¦æ’­æ”¾çš„è²éŸ³ï¼š
</floater.string>
<floater.string name="step_chat">
- Chat to say:
+ è¦èªªå‡ºçš„èŠå¤©æ–‡å­—:
</floater.string>
<floater.string name="step_wait">
- Wait:
+ 等待:
</floater.string>
<floater.string name="stop_txt">
åœæ­¢
@@ -22,20 +22,20 @@
-- ç„¡ --
</floater.string>
<floater.string name="Title">
- Gesture: [NAME]
+ 姿勢:[NAME]
</floater.string>
<text name="desc_label">
æ述:
</text>
<text name="trigger_label">
- Trigger:
+ 觸發:
</text>
- <text name="replace_text" tool_tip="Replace the trigger word(s) with these words. For example, trigger &apos;hello&apos; replace with &apos;howdy&apos; will turn the chat &apos;I wanted to say hello&apos; into &apos;I wanted to say howdy&apos; as well as playing the gesture!">
- Replace with:
+ <text name="replace_text" tool_tip="用這些字眼å–代觸發字眼。 例如,觸發 &apos;hello&apos; å–代為 &apos;howdy&apos; 後,將使得èŠå¤©æ–‡å­—「我想說 helloã€è®Šæˆã€Œæˆ‘想說 howdyã€ï¼ŒåŒæ™‚還會播放該姿勢ï¼">
+ å–代æˆï¼š
</text>
- <line_editor name="replace_editor" tool_tip="Replace the trigger word(s) with these words. For example, trigger &apos;hello&apos; replace with &apos;howdy&apos; will turn the chat &apos;I wanted to say hello&apos; into &apos;I wanted to say howdy&apos; as well as playing the gesture"/>
+ <line_editor name="replace_editor" tool_tip="用這些字眼å–代觸發字眼。 例如,觸發 &apos;hello&apos; å–代為 &apos;howdy&apos; 後,將使得èŠå¤©æ–‡å­—「我想說 helloã€è®Šæˆã€Œæˆ‘想說 howdyã€ï¼ŒåŒæ™‚還會播放該姿勢。"/>
<text name="key_label">
- Shortcut Key:
+ å¿«æ·éµï¼š
</text>
<combo_box label="ç„¡" name="modifier_combo"/>
<combo_box label="ç„¡" name="key_combo"/>
@@ -50,10 +50,10 @@
</scroll_list>
<button label="添加 &gt;&gt;" name="add_btn"/>
<text name="steps_label">
- Steps:
+ 步驟:
</text>
- <button label="Up" name="up_btn"/>
- <button label="Down" name="down_btn"/>
+ <button label="上移éµ" name="up_btn"/>
+ <button label="下移éµ" name="down_btn"/>
<button label="移除" name="delete_btn"/>
<text name="options_text">
(é¸é …)
@@ -63,11 +63,11 @@
<radio_item label="åœæ­¢" name="stop"/>
</radio_group>
<check_box label="直到動作çµæŸã€‚" name="wait_anim_check"/>
- <check_box label="time in seconds:" name="wait_time_check"/>
+ <check_box label="時間(秒):" name="wait_time_check"/>
<text name="help_label">
- All steps happen simultaneously, unless you add wait steps.
+ 所有步驟都會åŒæ™‚進行,除éžä½ åŠ å…¥ã€Œç­‰å¾…ã€æ­¥é©Ÿã€‚
</text>
- <check_box label="Active" name="active_check" tool_tip="Active gestures can be triggered by chatting their trigger phrases or pressing their hot keys. Gestures usually become inactive when there is a key binding conflict."/>
+ <check_box label="å¯ç”¨" name="active_check" tool_tip="ä½ å¯ä»¥åœ¨èŠå¤©ä¸­éµå…¥ã€Œè§¸ç™¼å­—眼ã€ï¼Œæˆ–按æŸå§¿å‹¢çš„熱éµä¾†å•Ÿå‹•å¯ç”¨çš„姿勢。 熱éµçš„ç¶å®šè‹¥æœ‰è¡çªï¼Œé€šå¸¸æœƒä½¿å§¿å‹¢è®Šæˆä¸å¯ç”¨ã€‚"/>
<button label="é è¦½" name="preview_btn"/>
<button label="儲存" name="save_btn"/>
</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_preview_notecard.xml b/indra/newview/skins/default/xui/zh/floater_preview_notecard.xml
index 9447939801..9447939801 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_preview_notecard.xml
+++ b/indra/newview/skins/default/xui/zh/floater_preview_notecard.xml
diff --git a/indra/newview/skins/default/xui/zh/floater_preview_sound.xml b/indra/newview/skins/default/xui/zh/floater_preview_sound.xml
index 46844349de..d04428a36d 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_preview_sound.xml
+++ b/indra/newview/skins/default/xui/zh/floater_preview_sound.xml
@@ -6,6 +6,6 @@
<text name="desc txt">
æ述:
</text>
- <button label="播放於虛擬世界" label_selected="播放於虛擬世界" name="Sound play btn" tool_tip="Play this sound so that others can hear it"/>
- <button label="播放於本地" label_selected="播放於本地" name="Sound audition btn" tool_tip="Play this sound so that only you can hear it"/>
+ <button label="在虛擬世界播放" label_selected="在虛擬世界播放" name="Sound play btn" tool_tip="播放此è²éŸ³è®“他人è½è¦‹"/>
+ <button label="在本地播放" label_selected="在本地播放" name="Sound audition btn" tool_tip="播放此è²éŸ³ï¼Œåªè®“自己è½è¦‹"/>
</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_preview_texture.xml b/indra/newview/skins/default/xui/zh/floater_preview_texture.xml
index 02e26cea24..c56b1c2987 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_preview_texture.xml
+++ b/indra/newview/skins/default/xui/zh/floater_preview_texture.xml
@@ -10,31 +10,31 @@
æ述:
</text>
<text name="dimensions">
- [WIDTH]px x [HEIGHT]px
+ [WIDTH] åƒç´  X [HEIGHT] åƒç´ 
</text>
<text name="aspect_ratio">
- Preview aspect ratio
+ é è¦½é•·å¯¬æ¯”
</text>
- <combo_box name="combo_aspect_ratio" tool_tip="Preview at a fixed aspect ratio">
+ <combo_box name="combo_aspect_ratio" tool_tip="以固定長寬比é è¦½">
<combo_item name="Unconstrained">
- Unconstrained
+ ä¸å—é™
</combo_item>
- <combo_item name="1:1" tool_tip="Group insignia or Real World profile">
+ <combo_item name="1:1" tool_tip="群組徽章或ç¾å¯¦ä¸–ç•Œå°æª”案">
1:1
</combo_item>
<combo_item name="4:3" tool_tip="[SECOND_LIFE] 檔案">
4:3
</combo_item>
- <combo_item name="10:7" tool_tip="Classifieds and search listings, landmarks">
+ <combo_item name="10:7" tool_tip="個人廣告和æœç´¢åˆŠç™»å»£å‘Šã€åœ°æ¨™">
10:7
</combo_item>
- <combo_item name="3:2" tool_tip="關於土地">
+ <combo_item name="3:2" tool_tip="土地資料">
3:2
</combo_item>
<combo_item name="16:10">
16:10
</combo_item>
- <combo_item name="16:9" tool_tip="Profile picks">
+ <combo_item name="16:9" tool_tip="個人檔案精é¸">
16:9
</combo_item>
<combo_item name="2:1">
@@ -42,6 +42,6 @@
</combo_item>
</combo_box>
<button label="確定" name="Keep"/>
- <button label="Discard" name="Discard"/>
- <button label="å¦å­˜" name="save_tex_btn"/>
+ <button label="丟棄" name="Discard"/>
+ <button label="å¦å­˜ç‚º" name="save_tex_btn"/>
</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_price_for_listing.xml b/indra/newview/skins/default/xui/zh/floater_price_for_listing.xml
new file mode 100755
index 0000000000..078b490655
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/floater_price_for_listing.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="price_for_listing" title="刊登個人廣告">
+ <text name="explanation_text">
+ 你的個人廣告將從刊登日起連續刊載一星期。
+
+你的廣告在個人廣告欄出ç¾çš„ä½ç½®ï¼Œå–決於你決定付費的多寡。
+
+付費越多的個人廣告會出ç¾åœ¨æŽ¥è¿‘最上方ä½ç½®ï¼Œä¸¦é¡¯ç¤ºæ–¼æœå°‹çµæžœçš„å‰é¢ã€‚
+ </text>
+ <text name="price_text">
+ 刊登費:
+ </text>
+ <text name="price_symbol">
+ L$
+ </text>
+ <button label="確定" name="set_price_btn"/>
+ <button label="å–消" name="cancel_btn"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_publish_classified.xml b/indra/newview/skins/default/xui/zh/floater_publish_classified.xml
index 5f0ffea182..b810af0145 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_publish_classified.xml
+++ b/indra/newview/skins/default/xui/zh/floater_publish_classified.xml
@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="publish_classified" title="Publishing Classified">
+<floater name="publish_classified" title="刊登個人廣告">
<text name="explanation_text">
- Your classified ad will run for one week from the date it is published.
+ 你的個人廣告將從刊登日起連續刊載一星期。
-Remember, Classified fees are non-refundable.
+請注æ„,個人廣告刊登費æ•ä¸é€€é‚„。
</text>
- <spinner label="價格: L$" name="price_for_listing" tool_tip="刊登費用。" value="50"/>
+ <spinner label="價格: L$" name="price_for_listing" tool_tip="刊登費。" value="50"/>
<button label="發布" name="publish_btn"/>
<button label="å–消" name="cancel_btn"/>
</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_region_debug_console.xml b/indra/newview/skins/default/xui/zh/floater_region_debug_console.xml
index 4ff2a3fc79..4ff2a3fc79 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_region_debug_console.xml
+++ b/indra/newview/skins/default/xui/zh/floater_region_debug_console.xml
diff --git a/indra/newview/skins/default/xui/zh/floater_region_info.xml b/indra/newview/skins/default/xui/zh/floater_region_info.xml
index 0e4879f555..0e4879f555 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_region_info.xml
+++ b/indra/newview/skins/default/xui/zh/floater_region_info.xml
diff --git a/indra/newview/skins/default/xui/zh/floater_report_abuse.xml b/indra/newview/skins/default/xui/zh/floater_report_abuse.xml
index 436f5cdcc5..8dbc216ab5 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_report_abuse.xml
+++ b/indra/newview/skins/default/xui/zh/floater_report_abuse.xml
@@ -14,66 +14,66 @@
地å€å稱
</text>
<text name="pos_title">
- Position:
+ ä½ç½®ï¼š
</text>
<text name="pos_field">
{128.1, 128.1, 15.4}
</text>
<text name="select_object_label">
- Click the button, then the abusive object:
+ 點按按鈕,å†é»žæŒ‰é•ç´€çš„物件:
</text>
- <button name="pick_btn" tool_tip="Object Picker - Identify an object as the subject of this report"/>
+ <button name="pick_btn" tool_tip="物件é¸å–器 - 指明本舉報的å°è±¡ç‰©ä»¶"/>
<text name="object_name_label">
物件:
</text>
<text name="owner_name_label">
- æ“有者:
+ 所有人:
</text>
- <combo_box name="category_combo" tool_tip="Category -- select the category that best describes this report">
+ <combo_box name="category_combo" tool_tip="類別 -- é¸æ“‡æœ€ç¬¦åˆæ­¤æ¬¡èˆ‰å ±å…§å®¹çš„類別">
<combo_box.item label="é¸æ“‡é¡žåˆ¥" name="Select_category"/>
- <combo_box.item label="Age &gt; Age play" name="Age__Age_play"/>
- <combo_box.item label="Age &gt; Adult Resident on Teen Second Life" name="Age__Adult_resident_on_Teen_Second_Life"/>
- <combo_box.item label="Age &gt; Underage Resident outside of Teen Second Life" name="Age__Underage_resident_outside_of_Teen_Second_Life"/>
- <combo_box.item label="Assault &gt; Combat sandbox / unsafe area" name="Assault__Combat_sandbox___unsafe_area"/>
- <combo_box.item label="Assault &gt; Safe area" name="Assault__Safe_area"/>
- <combo_box.item label="Assault &gt; Weapons testing sandbox" name="Assault__Weapons_testing_sandbox"/>
- <combo_box.item label="Commerce &gt; Failure to deliver product or service" name="Commerce__Failure_to_deliver_product_or_service"/>
- <combo_box.item label="Disclosure &gt; Real world information" name="Disclosure__Real_world_information"/>
- <combo_box.item label="Disclosure &gt; Remotely monitoring chat" name="Disclosure__Remotely_monitoring chat"/>
- <combo_box.item label="Disclosure &gt; Second Life information/chat/IMs" name="Disclosure__Second_Life_information_chat_IMs"/>
- <combo_box.item label="Disturbing the peace &gt; Unfair use of region resources" name="Disturbing_the_peace__Unfair_use_of_region_resources"/>
- <combo_box.item label="Disturbing the peace &gt; Excessive scripted objects" name="Disturbing_the_peace__Excessive_scripted_objects"/>
- <combo_box.item label="Disturbing the peace &gt; Object littering" name="Disturbing_the_peace__Object_littering"/>
- <combo_box.item label="Disturbing the peace &gt; Repetitive spam" name="Disturbing_the_peace__Repetitive_spam"/>
- <combo_box.item label="Disturbing the peace &gt; Unwanted advert spam" name="Disturbing_the_peace__Unwanted_advert_spam"/>
- <combo_box.item label="Fraud &gt; L$" name="Fraud__L$"/>
- <combo_box.item label="Fraud &gt; Land" name="Fraud__Land"/>
- <combo_box.item label="Fraud &gt; Pyramid scheme or chain letter" name="Fraud__Pyramid_scheme_or_chain_letter"/>
- <combo_box.item label="Fraud &gt; US$" name="Fraud__US$"/>
- <combo_box.item label="Harassment &gt; Advert farms / visual spam" name="Harassment__Advert_farms___visual_spam"/>
- <combo_box.item label="Harassment &gt; Defaming individuals or groups" name="Harassment__Defaming_individuals_or_groups"/>
- <combo_box.item label="Harassment &gt; Impeding movement" name="Harassment__Impeding_movement"/>
- <combo_box.item label="Harassment &gt; Sexual harassment" name="Harassment__Sexual_harassment"/>
- <combo_box.item label="Harassment &gt; Solicting/inciting others to violate ToS" name="Harassment__Solicting_inciting_others_to_violate_ToS"/>
- <combo_box.item label="Harassment &gt; Verbal abuse" name="Harassment__Verbal_abuse"/>
- <combo_box.item label="Indecency &gt; Broadly offensive content or conduct" name="Indecency__Broadly_offensive_content_or_conduct"/>
- <combo_box.item label="Indecency &gt; Inappropriate avatar name" name="Indecency__Inappropriate_avatar_name"/>
- <combo_box.item label="Indecency &gt; Inappropriate content or conduct in a PG region" name="Indecency__Mature_content_in_PG_region"/>
- <combo_box.item label="Indecency &gt; Inappropriate content or conduct in a Moderate region" name="Indecency__Inappropriate_content_in_Mature_region"/>
- <combo_box.item label="Intellectual property infringement &gt; Content Removal" name="Intellectual_property_infringement_Content_Removal"/>
- <combo_box.item label="Intellectual property infringement &gt; CopyBot or Permissions Exploit" name="Intellectual_property_infringement_CopyBot_or_Permissions_Exploit"/>
- <combo_box.item label="Intolerance" name="Intolerance"/>
- <combo_box.item label="Land &gt; Abuse of sandbox resources" name="Land__Abuse_of_sandbox_resources"/>
- <combo_box.item label="Land &gt; Encroachment &gt; Objects/textures" name="Land__Encroachment__Objects_textures"/>
- <combo_box.item label="Land &gt; Encroachment &gt; Particles" name="Land__Encroachment__Particles"/>
- <combo_box.item label="Land &gt; Encroachment &gt; Trees/plants" name="Land__Encroachment__Trees_plants"/>
- <combo_box.item label="Wagering/gambling" name="Wagering_gambling"/>
+ <combo_box.item label="年齡 &gt; 年齡 play" name="Age__Age_play"/>
+ <combo_box.item label="年齡 &gt; æˆäººå±…民出ç¾åœ¨é’少年專用第二人生" name="Age__Adult_resident_on_Teen_Second_Life"/>
+ <combo_box.item label="年齡 &gt; 未æˆå¹´å±…民出ç¾åœ¨é’少年專用第二人生以外場所" name="Age__Underage_resident_outside_of_Teen_Second_Life"/>
+ <combo_box.item label="攻擊 &gt; 戰鬥沙盤 / ä¸å®‰å…¨å€åŸŸ" name="Assault__Combat_sandbox___unsafe_area"/>
+ <combo_box.item label="攻擊 &gt; 安全å€åŸŸ" name="Assault__Safe_area"/>
+ <combo_box.item label="攻擊 &gt; 測試武器的沙盤" name="Assault__Weapons_testing_sandbox"/>
+ <combo_box.item label="商業 &gt; 未é€äº¤ç”¢å“或履行æœå‹™" name="Commerce__Failure_to_deliver_product_or_service"/>
+ <combo_box.item label="æ­éœ² &gt; 真實世界資訊" name="Disclosure__Real_world_information"/>
+ <combo_box.item label="æ­éœ² &gt; é ç«¯ç›£æŽ§èŠå¤©å…§å®¹" name="Disclosure__Remotely_monitoring chat"/>
+ <combo_box.item label="æ­éœ² &gt; 第二人生資訊 / èŠå¤©å…§å®¹ / å³æ™‚訊æ¯" name="Disclosure__Second_Life_information_chat_IMs"/>
+ <combo_box.item label="擾亂 &gt; ä¸å…¬å¹³ä½¿ç”¨åœ°å€è³‡æº" name="Disturbing_the_peace__Unfair_use_of_region_resources"/>
+ <combo_box.item label="擾亂 &gt; éŽåº¦ä½¿ç”¨å¸¶è…³æœ¬çš„物件" name="Disturbing_the_peace__Excessive_scripted_objects"/>
+ <combo_box.item label="擾亂 &gt; ä»»æ„棄置物件" name="Disturbing_the_peace__Object_littering"/>
+ <combo_box.item label="擾亂 &gt; 一å†ç™¼å‡ºåžƒåœ¾è¨Šæ¯" name="Disturbing_the_peace__Repetitive_spam"/>
+ <combo_box.item label="擾亂 &gt; ä¸å—歡迎的垃圾廣告" name="Disturbing_the_peace__Unwanted_advert_spam"/>
+ <combo_box.item label="è©æ¬º &gt; L$" name="Fraud__L$"/>
+ <combo_box.item label="è©æ¬º &gt; 土地" name="Fraud__Land"/>
+ <combo_box.item label="è©æ¬º &gt; 層壓å¼æŽ¨éŠ·æˆ–連環信" name="Fraud__Pyramid_scheme_or_chain_letter"/>
+ <combo_box.item label="è©æ¬º &gt; 美金" name="Fraud__US$"/>
+ <combo_box.item label="騷擾 &gt; 廣告農場 / 視覺轟炸" name="Harassment__Advert_farms___visual_spam"/>
+ <combo_box.item label="騷擾 &gt; 詆譭個人或群組" name="Harassment__Defaming_individuals_or_groups"/>
+ <combo_box.item label="騷擾 &gt; 阻撓移動" name="Harassment__Impeding_movement"/>
+ <combo_box.item label="騷擾 &gt; 性騷擾" name="Harassment__Sexual_harassment"/>
+ <combo_box.item label="騷擾 &gt; é¼“å¹ / 教唆他人é•åæœå‹™æ¢æ¬¾" name="Harassment__Solicting_inciting_others_to_violate_ToS"/>
+ <combo_box.item label="騷擾 &gt; 言語暴力" name="Harassment__Verbal_abuse"/>
+ <combo_box.item label="ä¸é›… &gt; 令大多人ä¸å¿«çš„內容或行為" name="Indecency__Broadly_offensive_content_or_conduct"/>
+ <combo_box.item label="ä¸é›… &gt; 冒犯人的化身å稱" name="Indecency__Inappropriate_avatar_name"/>
+ <combo_box.item label="ä¸é›… &gt; 在一般普級地å€å‡ºç¾å†’犯人的內容或行為" name="Indecency__Mature_content_in_PG_region"/>
+ <combo_box.item label="ä¸é›… &gt; 在é©åº¦æˆäººåœ°å€å‡ºç¾å†’犯人的內容或行為" name="Indecency__Inappropriate_content_in_Mature_region"/>
+ <combo_box.item label="侵犯智產權 &gt; 移除內容" name="Intellectual_property_infringement_Content_Removal"/>
+ <combo_box.item label="侵犯智產權 &gt; 複製機器程å¼ç¢¼ CopyBot 或濫用權é™" name="Intellectual_property_infringement_CopyBot_or_Permissions_Exploit"/>
+ <combo_box.item label="ä¸å®¹ç•°å·±" name="Intolerance"/>
+ <combo_box.item label="土地 &gt; ä¸ç•¶ä½¿ç”¨æ²™ç›¤è³‡æº" name="Land__Abuse_of_sandbox_resources"/>
+ <combo_box.item label="土地 &gt; 侵佔 &gt; 物件 / æ質" name="Land__Encroachment__Objects_textures"/>
+ <combo_box.item label="土地 &gt; 侵佔 &gt; ç²’å­" name="Land__Encroachment__Particles"/>
+ <combo_box.item label="土地 &gt; 侵佔 &gt; 樹種 / æ¤ç‰©" name="Land__Encroachment__Trees_plants"/>
+ <combo_box.item label="下注 / è³­åš" name="Wagering_gambling"/>
<combo_box.item label="其他" name="Other"/>
</combo_box>
<text name="abuser_name_title">
濫用者å稱:
</text>
- <button label="é¸æ“‡" name="select_abuser" tool_tip="Select the name of the abuser from a list"/>
+ <button label="é¸æ“‡" name="select_abuser" tool_tip="從清單中é¸æ“‡é•ç´€è€…姓å"/>
<text name="abuser_name_title2">
濫用ä½ç½®ï¼š
</text>
@@ -84,11 +84,11 @@
細節:
</text>
<text name="bug_aviso">
- Please be as specific as possible
+ 請盡å¯èƒ½æ供具體細節
</text>
<text name="incomplete_title">
- * Incomplete reports won&apos;t be investigated
+ * ä¸å®Œæ•´çš„舉報內容概ä¸å—ç†èª¿æŸ¥
</text>
- <button label="舉報濫用" label_selected="舉報濫用" name="send_btn"/>
+ <button label="é•è¦èˆ‰å ±" label_selected="é•è¦èˆ‰å ±" name="send_btn"/>
<button label="å–消" label_selected="å–消" name="cancel_btn"/>
</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_script_debug.xml b/indra/newview/skins/default/xui/zh/floater_script_debug.xml
index 5b3500c018..5b3500c018 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_script_debug.xml
+++ b/indra/newview/skins/default/xui/zh/floater_script_debug.xml
diff --git a/indra/newview/skins/default/xui/zh/floater_script_debug_panel.xml b/indra/newview/skins/default/xui/zh/floater_script_debug_panel.xml
index e70a30fa24..e70a30fa24 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_script_debug_panel.xml
+++ b/indra/newview/skins/default/xui/zh/floater_script_debug_panel.xml
diff --git a/indra/newview/skins/default/xui/zh/floater_script_limits.xml b/indra/newview/skins/default/xui/zh/floater_script_limits.xml
index 7cd2c8e6c6..7cd2c8e6c6 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_script_limits.xml
+++ b/indra/newview/skins/default/xui/zh/floater_script_limits.xml
diff --git a/indra/newview/skins/default/xui/zh/floater_script_preview.xml b/indra/newview/skins/default/xui/zh/floater_script_preview.xml
index c3d05402c0..a6c6c76181 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_script_preview.xml
+++ b/indra/newview/skins/default/xui/zh/floater_script_preview.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="preview lsl text" title="SCRIPT: ROTATION SCRIPT">
+<floater name="preview lsl text" title="腳本:旋轉腳本">
<floater.string name="Title">
腳本:[NAME]
</floater.string>
diff --git a/indra/newview/skins/default/xui/zh/floater_script_queue.xml b/indra/newview/skins/default/xui/zh/floater_script_queue.xml
index ff02946d86..7c253aa74c 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_script_queue.xml
+++ b/indra/newview/skins/default/xui/zh/floater_script_queue.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="queue" title="RESET PROGRESS">
+<floater name="queue" title="é‡è¨­é€²åº¦">
<floater.string name="Starting">
- Starting [START] of [COUNT] items.
+ 正在啟動 [START] 項,共 [COUNT] 項。
</floater.string>
<floater.string name="Done">
- Done.
+ 完æˆã€‚
</floater.string>
<floater.string name="Resetting">
é‡è¨­ä¸­
diff --git a/indra/newview/skins/default/xui/zh/floater_script_search.xml b/indra/newview/skins/default/xui/zh/floater_script_search.xml
index 400ef4be81..11c23d933f 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_script_search.xml
+++ b/indra/newview/skins/default/xui/zh/floater_script_search.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="script search" title="腳本æœå°‹">
- <check_box label="Case Insensitive" name="case_text"/>
+ <check_box label="大å°å¯«è¦–為相åŒ" name="case_text"/>
<button label="æœå°‹" label_selected="æœå°‹" name="search_btn"/>
<button label="å–代" label_selected="å–代" name="replace_btn"/>
<button label="全部å–代" label_selected="全部å–代" name="replace_all_btn"/>
diff --git a/indra/newview/skins/default/xui/zh/floater_search.xml b/indra/newview/skins/default/xui/zh/floater_search.xml
index bb693b7a70..3e85a529ae 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_search.xml
+++ b/indra/newview/skins/default/xui/zh/floater_search.xml
@@ -1,15 +1,15 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_search" title="尋找">
+<floater name="floater_search" title="">
<floater.string name="loading_text">
載入中...
</floater.string>
<floater.string name="done_text">
- Done
+ 完æˆ
</floater.string>
<layout_stack name="stack1">
<layout_panel name="browser_layout">
<text name="refresh_search">
- Redo search to reflect current God level
+ 以目å‰å…·å‚™çš„神階級å†æœå°‹ä¸€æ¬¡
</text>
</layout_panel>
</layout_stack>
diff --git a/indra/newview/skins/default/xui/zh/floater_select_key.xml b/indra/newview/skins/default/xui/zh/floater_select_key.xml
index c1661635f1..231eb48b04 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_select_key.xml
+++ b/indra/newview/skins/default/xui/zh/floater_select_key.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="modal container">
<text name="Save item as:">
- Press a key to set your Speak button trigger.
+ 按任一éµè¨­å®šã€Œèªªè©±ã€æŒ‰éˆ•çš„觸發。
</text>
<button label="å–消" label_selected="å–消" name="Cancel"/>
</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_sell_land.xml b/indra/newview/skins/default/xui/zh/floater_sell_land.xml
index 19580c99a1..9030f7eb63 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_sell_land.xml
+++ b/indra/newview/skins/default/xui/zh/floater_sell_land.xml
@@ -12,16 +12,16 @@
尺寸:
</text>
<text name="info_size">
- [AREA] m²
+ [AREA] 平方公尺
</text>
<text name="info_action">
- To sell this parcel:
+ 出售地段:
</text>
<text name="price_label">
- 1. Set a price:
+ 1. 訂定價格:
</text>
<text name="price_text">
- Choose an appropriate price.
+ é¸æ“‡é©åˆçš„價格。
</text>
<text name="price_ld">
L$
@@ -30,13 +30,13 @@
0
</line_editor>
<text name="price_per_m">
- (L$[PER_METER] per m²)
+ (æ¯å¹³æ–¹å…¬å°º L$[PER_METER])
</text>
<text name="sell_to_label">
- 2. Sell the land to:
+ 2. 出售土地給:
</text>
<text name="sell_to_text">
- Choose whether to sell to anyone or a particular buyer.
+ é¸æ“‡è¦è³£çµ¦ä»»ä½•äººæˆ–賣給特定買主。
</text>
<combo_box name="sell_to">
<combo_box.item label="- é¸æ“‡ä¸€å€‹ -" name="--selectone--"/>
@@ -45,20 +45,20 @@
</combo_box>
<button label="é¸æ“‡" name="sell_to_select_agent"/>
<text name="sell_objects_label">
- 3. Sell the objects with the land?
+ 3. 物件連åŒåœŸåœ°ä¸€èµ·å”®å‡ºï¼Ÿ
</text>
<text name="sell_objects_text">
- Land owner&apos;s transferable objects on parcel will change ownership.
+ 地段上地主的å¯è½‰è®“物件將éŽç¹¼æ‰€æœ‰æ¬Šã€‚
</text>
<radio_group name="sell_objects">
- <radio_item label="No, keep ownership of objects" name="no"/>
- <radio_item label="Yes, sell objects with land" name="yes"/>
+ <radio_item label="ä¸ï¼Œæˆ‘è¦ä¿ç•™ç‰©ä»¶æ‰€æœ‰æ¬Š" name="no"/>
+ <radio_item label="好,物件連åŒåœŸåœ°ä¸€èµ·å”®å‡º" name="yes"/>
</radio_group>
<button label="顯示物件" name="show_objects"/>
<text name="nag_message_label">
- REMEMBER: All sales are final.
+ 請記ä½ï¼šå”®å¾Œä¸€æ¦‚ä¸é€€ã€‚
</text>
- <button label="Set Land For Sale" name="sell_btn"/>
+ <button label="設定土地待售" name="sell_btn"/>
<button label="å–消" name="cancel_btn"/>
</panel>
</scroll_container>
diff --git a/indra/newview/skins/default/xui/zh/floater_settings_debug.xml b/indra/newview/skins/default/xui/zh/floater_settings_debug.xml
index 56a31bc292..56a31bc292 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_settings_debug.xml
+++ b/indra/newview/skins/default/xui/zh/floater_settings_debug.xml
diff --git a/indra/newview/skins/default/xui/zh/floater_snapshot.xml b/indra/newview/skins/default/xui/zh/floater_snapshot.xml
index 9edc19969f..e86e20829f 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_snapshot.xml
+++ b/indra/newview/skins/default/xui/zh/floater_snapshot.xml
@@ -1,74 +1,65 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Snapshot" title="SNAPSHOT PREVIEW">
+<floater name="Snapshot" title="å¿«ç…§é è¦½">
<floater.string name="unknown">
未知
</floater.string>
- <radio_group label="Snapshot type" name="snapshot_type_radio">
- <radio_item label="Email" name="postcard"/>
- <radio_item label="我的收ç´å€ï¼ˆL$[AMOUNT])" name="texture"/>
- <radio_item label="Save to my computer" name="local"/>
- </radio_group>
+ <string name="postcard_progress_str">
+ 正在發é€é›»éƒµ
+ </string>
+ <string name="profile_progress_str">
+ 發佈
+ </string>
+ <string name="inventory_progress_str">
+ 儲存到收ç´å€
+ </string>
+ <string name="local_progress_str">
+ 正在存到電腦
+ </string>
+ <string name="profile_succeeded_str">
+ 圖åƒå·²ä¸Šå‚³
+ </string>
+ <string name="postcard_succeeded_str">
+ 電郵發é€æˆåŠŸï¼
+ </string>
+ <string name="inventory_succeeded_str">
+ æˆåŠŸå­˜å…¥æ”¶ç´å€ï¼
+ </string>
+ <string name="local_succeeded_str">
+ æˆåŠŸå­˜å…¥é›»è…¦ï¼
+ </string>
+ <string name="profile_failed_str">
+ 上傳圖åƒåˆ°ä½ çš„檔案訊æ¯ç™¼ä½ˆæ™‚出錯。
+ </string>
+ <string name="postcard_failed_str">
+ 電郵傳é€å¤±æ•—。
+ </string>
+ <string name="inventory_failed_str">
+ 無法存入收ç´å€ã€‚
+ </string>
+ <string name="local_failed_str">
+ 無法儲入電腦。
+ </string>
+ <button name="advanced_options_btn" tool_tip="進階é¸é …"/>
+ <text name="image_res_text">
+ [WIDTH] x [HEIGHT] åƒç´ 
+ </text>
<text name="file_size_label">
[SIZE] KB
</text>
- <button label="é€å‡º" name="send_btn"/>
- <button label="儲存(L$[AMOUNT])" name="upload_btn"/>
- <flyout_button label="儲存" name="save_btn" tool_tip="儲存圖åƒåˆ°æª”案">
- <flyout_button.item label="儲存" name="save_item"/>
- <flyout_button.item label="å¦å­˜..." name="saveas_item"/>
- </flyout_button>
- <button label="更多" name="more_btn" tool_tip="進階é¸é …"/>
- <button label="æ›´å°‘" name="less_btn" tool_tip="進階é¸é …"/>
- <button label="å–消" name="discard_btn"/>
- <text name="type_label2">
- 尺寸
- </text>
- <text name="format_label">
- Format
- </text>
- <combo_box label="Resolution" name="postcard_size_combo">
- <combo_box.item label="ç›®å‰è¦–窗" name="CurrentWindow"/>
- <combo_box.item label="640x480" name="640x480"/>
- <combo_box.item label="800x600" name="800x600"/>
- <combo_box.item label="1024x768" name="1024x768"/>
- <combo_box.item label="自訂" name="Custom"/>
- </combo_box>
- <combo_box label="Resolution" name="texture_size_combo">
- <combo_box.item label="ç›®å‰è¦–窗" name="CurrentWindow"/>
- <combo_box.item label="Small (128x128)" name="Small(128x128)"/>
- <combo_box.item label="Medium (256x256)" name="Medium(256x256)"/>
- <combo_box.item label="Large (512x512)" name="Large(512x512)"/>
- <combo_box.item label="自訂" name="Custom"/>
- </combo_box>
- <combo_box label="Resolution" name="local_size_combo">
- <combo_box.item label="ç›®å‰è¦–窗" name="CurrentWindow"/>
- <combo_box.item label="320x240" name="320x240"/>
- <combo_box.item label="640x480" name="640x480"/>
- <combo_box.item label="800x600" name="800x600"/>
- <combo_box.item label="1024x768" name="1024x768"/>
- <combo_box.item label="1280x1024" name="1280x1024"/>
- <combo_box.item label="1600x1200" name="1600x1200"/>
- <combo_box.item label="Custom" name="Custom"/>
- </combo_box>
- <combo_box label="Format" name="local_format_combo">
- <combo_box.item label="PNG" name="PNG"/>
- <combo_box.item label="JPEG" name="JPEG"/>
- <combo_box.item label="BMP" name="BMP"/>
- </combo_box>
- <spinner label="Width" name="snapshot_width"/>
- <spinner label="Height" name="snapshot_height"/>
- <check_box label="Constrain proportions" name="keep_aspect_check"/>
- <slider label="圖åƒå“質" name="image_quality_slider"/>
- <text name="layer_type_label">
- Capture:
- </text>
- <combo_box label="圖層" name="layer_types">
- <combo_box.item label="Colors" name="Colors"/>
- <combo_box.item label="Depth" name="Depth"/>
- </combo_box>
- <check_box label="Interface" name="ui_check"/>
- <check_box label="HUDs" name="hud_check"/>
- <check_box label="Keep open after saving" name="keep_open_check"/>
- <check_box label="å‡çµæ¡†æž¶ï¼ˆå…¨èž¢å¹•ï¼‰" name="freeze_frame_check"/>
- <check_box label="Auto-refresh" name="auto_snapshot_check"/>
+ <panel name="advanced_options_panel">
+ <text name="advanced_options_label">
+ 進階é¸é …
+ </text>
+ <text name="layer_type_label">
+ æ“·å–快照:
+ </text>
+ <combo_box label="圖層" name="layer_types">
+ <combo_box.item label="é¡è‰²" name="Colors"/>
+ <combo_box.item label="深度" name="Depth"/>
+ </combo_box>
+ <check_box label="介é¢" name="ui_check"/>
+ <check_box label="擡頭顯示" name="hud_check"/>
+ <check_box label="將幀å‡çµï¼ˆå…¨èž¢å¹•ï¼‰" name="freeze_frame_check"/>
+ <check_box label="自動刷新" name="auto_snapshot_check"/>
+ </panel>
</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_sound_devices.xml b/indra/newview/skins/default/xui/zh/floater_sound_devices.xml
new file mode 100755
index 0000000000..0374c74f8f
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/floater_sound_devices.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="floater_sound_devices" title="è²éŸ³è£ç½®">
+ <text name="voice_label">
+ 語音èŠå¤©
+ </text>
+ <check_box label="已啟用" name="enable_voice"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_sound_preview.xml b/indra/newview/skins/default/xui/zh/floater_sound_preview.xml
index c942ba1cfb..c942ba1cfb 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_sound_preview.xml
+++ b/indra/newview/skins/default/xui/zh/floater_sound_preview.xml
diff --git a/indra/newview/skins/default/xui/zh/floater_spellcheck.xml b/indra/newview/skins/default/xui/zh/floater_spellcheck.xml
new file mode 100755
index 0000000000..f5a6665844
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/floater_spellcheck.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="spellcheck_floater" title="拼字檢查設定">
+ <check_box label="啟用拼字檢查" name="spellcheck_enable"/>
+ <text name="spellcheck_main">
+ 主è¦å­—典:
+ </text>
+ <text label="記錄:" name="spellcheck_additional">
+ 附加字典:
+ </text>
+ <text name="spellcheck_available">
+ å¯ç”¨çš„
+ </text>
+ <text name="spellcheck_active">
+ å¯ç”¨
+ </text>
+ <button label="移除" name="spellcheck_remove_btn"/>
+ <button label="匯入…" name="spellcheck_import_btn"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_spellcheck_import.xml b/indra/newview/skins/default/xui/zh/floater_spellcheck_import.xml
new file mode 100755
index 0000000000..6094a3bbce
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/floater_spellcheck_import.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="spellcheck_import" title="匯入字典">
+ <button label="ç€è¦½" label_selected="ç€è¦½" name="dictionary_path_browse"/>
+ <button label="匯入" name="ok_btn"/>
+ <button label="å–消" name="cancel_btn"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_stats.xml b/indra/newview/skins/default/xui/zh/floater_stats.xml
index 582572d0e2..4af5684ec1 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_stats.xml
+++ b/indra/newview/skins/default/xui/zh/floater_stats.xml
@@ -3,67 +3,84 @@
<scroll_container name="statistics_scroll">
<container_view name="statistics_view">
<stat_view label="基本" name="basic">
- <stat_bar label="FPS" name="fps"/>
+ <stat_bar label="æ¯ç§’幀數" name="fps"/>
<stat_bar label="頻寬" name="bandwidth"/>
<stat_bar label="å°åŒ…æ失" name="packet_loss"/>
- <stat_bar label="Ping Sim" name="ping"/>
+ <stat_bar label="探詢模擬器有無å應" name="ping"/>
</stat_view>
<stat_view label="進階" name="advanced">
- <stat_view label="Render" name="render">
- <stat_bar label="KTris Drawn" name="ktrisframe"/>
- <stat_bar label="KTris Drawn" name="ktrissec"/>
+ <stat_view label="呈åƒ" name="render">
+ <stat_bar label="繪出的 KTris(æ¯å¹€ï¼‰" name="ktrisframe"/>
+ <stat_bar label="繪出的 KTris(æ¯ç§’)" name="ktrissec"/>
<stat_bar label="物件總計" name="objs"/>
<stat_bar label="新物件" name="newobjs"/>
+ <stat_bar label="物件快å–讀å–率" name="object_cache_hits"/>
</stat_view>
<stat_view label="æ質" name="texture">
+ <stat_bar label="å¿«å–讀å–率" name="texture_cache_hits"/>
+ <stat_bar label="å¿«å–讀å–延é²" name="texture_cache_read_latency"/>
<stat_bar label="計數" name="numimagesstat"/>
- <stat_bar label="Raw Count" name="numrawimagesstat"/>
- <stat_bar label="GL Mem" name="gltexmemstat"/>
- <stat_bar label="Formatted Mem" name="formattedmemstat"/>
- <stat_bar label="Raw Mem" name="rawmemstat"/>
- <stat_bar label="Bound Mem" name="glboundmemstat"/>
+ <stat_bar label="原始計數" name="numrawimagesstat"/>
+ <stat_bar label="GL 記憶" name="gltexmemstat"/>
+ <stat_bar label="æ ¼å¼åŒ–記憶" name="formattedmemstat"/>
+ <stat_bar label="原始記憶" name="rawmemstat"/>
+ <stat_bar label="ç•Œé™è¨˜æ†¶" name="glboundmemstat"/>
</stat_view>
<stat_view label="網路" name="network">
- <stat_bar label="Packets In" name="packetsinstat"/>
- <stat_bar label="Packets Out" name="packetsoutstat"/>
+ <stat_bar label="進入å°åŒ…" name="packetsinstat"/>
+ <stat_bar label="出去å°åŒ…" name="packetsoutstat"/>
<stat_bar label="物件" name="objectkbitstat"/>
<stat_bar label="æ質" name="texturekbitstat"/>
<stat_bar label="資產" name="assetkbitstat"/>
- <stat_bar label="Layers" name="layerskbitstat"/>
- <stat_bar label="Actual In" name="actualinkbitstat"/>
- <stat_bar label="Actual Out" name="actualoutkbitstat"/>
- <stat_bar label="VFS Pending Ops" name="vfspendingoperations"/>
+ <stat_bar label="層次" name="layerskbitstat"/>
+ <stat_bar label="實入" name="actualinkbitstat"/>
+ <stat_bar label="實出" name="actualoutkbitstat"/>
+ <stat_bar label="VFS 待行作業" name="vfspendingoperations"/>
</stat_view>
</stat_view>
<stat_view label="模擬器" name="sim">
- <stat_bar label="Time Dilation" name="simtimedilation"/>
- <stat_bar label="Sim FPS" name="simfps"/>
- <stat_bar label="Physics FPS" name="simphysicsfps"/>
- <stat_view label="Physics Details" name="physicsdetail">
- <stat_bar label="Pinned Objects" name="physicspinnedtasks"/>
- <stat_bar label="Low LOD Objects" name="physicslodtasks"/>
+ <stat_bar label="時間膨脹" name="simtimedilation"/>
+ <stat_bar label="模擬器æ¯ç§’幀數" name="simfps"/>
+ <stat_bar label="物ç†å¼•æ“Žæ¯ç§’幀數" name="simphysicsfps"/>
+ <stat_view label="物ç†ç´°ç¯€" name="physicsdetail">
+ <stat_bar label="固ä½ç‰©ä»¶" name="physicspinnedtasks"/>
+ <stat_bar label="低細節層次物件" name="physicslodtasks"/>
<stat_bar label="記憶體é…ç½®" name="physicsmemoryallocated"/>
</stat_view>
- <stat_bar label="Agent Updates/Sec" name="simagentups"/>
- <stat_bar label="Main Agents" name="simmainagents"/>
- <stat_bar label="Child Agents" name="simchildagents"/>
+ <stat_bar label="用戶更新 / 秒" name="simagentups"/>
+ <stat_bar label="主è¦ç”¨æˆ¶" name="simmainagents"/>
+ <stat_bar label="兒童用戶" name="simchildagents"/>
<stat_bar label="物件" name="simobjects"/>
- <stat_bar label="Active Objects" name="simactiveobjects"/>
- <stat_bar label="Active Scripts" name="simactivescripts"/>
+ <stat_bar label="使用中物件" name="simactiveobjects"/>
+ <stat_bar label="使用中腳本" name="simactivescripts"/>
+ <stat_bar label="腳本執行" name="simpctscriptsrun"/>
<stat_bar label="腳本事件" name="simscripteps"/>
+ <stat_view label="尋徑" name="simpathfinding">
+ <stat_bar label="人工智慧步驟時間" name="simsimaistepmsec"/>
+ <stat_bar label="已略éŽè¼ªå»“步驟" name="simsimskippedsilhouettesteps"/>
+ <stat_bar label="角色已更新" name="simsimpctsteppedcharacters"/>
+ </stat_view>
<stat_bar label="進入å°åŒ…" name="siminpps"/>
<stat_bar label="出去å°åŒ…" name="simoutpps"/>
<stat_bar label="擱置下載" name="simpendingdownloads"/>
<stat_bar label="擱置上傳" name="simpendinguploads"/>
- <stat_bar label="Total Unacked Bytes" name="simtotalunackedbytes"/>
- <stat_view label="Time (ms)" name="simperf">
- <stat_bar label="Total Frame Time" name="simframemsec"/>
- <stat_bar label="Net Time" name="simnetmsec"/>
- <stat_bar label="Physics Time" name="simsimphysicsmsec"/>
- <stat_bar label="Simulation Time" name="simsimothermsec"/>
- <stat_bar label="Agent Time" name="simagentmsec"/>
- <stat_bar label="Images Time" name="simimagesmsec"/>
+ <stat_bar label="未承èªçš„總ä½å…ƒçµ„數" name="simtotalunackedbytes"/>
+ <stat_view label="時間(毫秒)" name="simperf">
+ <stat_bar label="總禎時間" name="simframemsec"/>
+ <stat_bar label="淨時間" name="simnetmsec"/>
+ <stat_bar label="物ç†æ™‚é–“" name="simsimphysicsmsec"/>
+ <stat_bar label="模擬時間" name="simsimothermsec"/>
+ <stat_bar label="用戶時間" name="simagentmsec"/>
+ <stat_bar label="圖åƒæ™‚é–“" name="simimagesmsec"/>
<stat_bar label="腳本時間" name="simscriptmsec"/>
+ <stat_bar label="閒置時間" name="simsparemsec"/>
+ <stat_view label="時間細節(毫秒)" name="timedetails">
+ <stat_bar label="物ç†æ­¥é©Ÿ" name="simsimphysicsstepmsec"/>
+ <stat_bar label="更新物ç†å½¢ç‹€" name="simsimphysicsshapeupdatemsec"/>
+ <stat_bar label="物ç†ï¼ˆå…¶ä»–)" name="simsimphysicsothermsec"/>
+ <stat_bar label="ç¡çœ æ™‚é–“" name="simsleepmsec"/>
+ <stat_bar label="Pump IO" name="simpumpiomsec"/>
+ </stat_view>
</stat_view>
</stat_view>
</container_view>
diff --git a/indra/newview/skins/default/xui/zh/floater_sys_well.xml b/indra/newview/skins/default/xui/zh/floater_sys_well.xml
index fd27e944ac..ca0b7f146d 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_sys_well.xml
+++ b/indra/newview/skins/default/xui/zh/floater_sys_well.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="sys_well_window" title="通知">
<string name="title_im_well_window">
- CONVERSATIONS
+ 交談
</string>
<string name="title_notification_well_window">
通知
diff --git a/indra/newview/skins/default/xui/zh/floater_telehub.xml b/indra/newview/skins/default/xui/zh/floater_telehub.xml
index b4c9f3ab29..ee21a78e90 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_telehub.xml
+++ b/indra/newview/skins/default/xui/zh/floater_telehub.xml
@@ -1,29 +1,29 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<!-- Explicit left edge to avoid overlapping build tools -->
-<floater name="telehub" title="TELEHUB">
+<floater name="telehub" title="瞬間傳é€ä¸­å¿ƒ">
<text name="status_text_connected">
- Telehub connected to object [OBJECT]
+ 瞬間傳é€ä¸­å¿ƒå·²é€£é€šç‰©ä»¶ [OBJECT]
</text>
<text name="status_text_not_connected">
- No telehub connected.
+ 無連通的瞬間傳é€ä¸­å¿ƒã€‚
</text>
<text name="help_text_connected">
- To remove, click Disconnect.
+ 點按「中斷ã€å³å¯ç§»é™¤ã€‚
</text>
<text name="help_text_not_connected">
- Select object and click Connect Telehub.
+ é¸æ“‡ç‰©ä»¶ï¼Œä¸¦é»žæŒ‰ã€Œé€£é€šçž¬é–“傳é€ä¸­å¿ƒã€ã€‚
</text>
- <button label="Connect Telehub" name="connect_btn"/>
- <button label="Disconnect" name="disconnect_btn"/>
+ <button label="連通瞬間傳é€ä¸­å¿ƒ" name="connect_btn"/>
+ <button label="中斷" name="disconnect_btn"/>
<text name="spawn_points_text">
- Spawn Points (positions, not objects):
+ 產生點(ä½ç½®è€Œéžç‰©ä»¶ï¼‰ï¼š
</text>
- <button label="Add Spawn" name="add_spawn_point_btn"/>
- <button label="Remove Spawn" name="remove_spawn_point_btn"/>
+ <button label="新增產生" name="add_spawn_point_btn"/>
+ <button label="移除產生" name="remove_spawn_point_btn"/>
<text name="spawn_point_help">
- Select object and click &quot;Add Spawn&quot; to specify position.
-You can then move or delete the object.
-Positions are relative to the telehub center.
-Select an item in list to highlight it inworld.
+ é¸æ“‡ç‰©ä»¶ï¼Œä¸¦é»žæŒ‰ã€Œæ–°å¢žç”¢ç”Ÿã€ä¾†æŒ‡å®šä½ç½®ã€‚
+ä½ å¯ä»¥æŽ¥è‘—移動或刪除該物件。
+ä½ç½®æ˜¯èˆ‡çž¬é–“傳é€ä¸­å¿ƒç›¸å°ã€‚
+從清單中é¸å–一項,在虛擬世界中以高亮顯示。
</text>
</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_test_layout_stacks.xml b/indra/newview/skins/default/xui/zh/floater_test_layout_stacks.xml
new file mode 100755
index 0000000000..68fcf3f7f7
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/floater_test_layout_stacks.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="Test Floater" title="LAYOUTSTACK 測試"/>
diff --git a/indra/newview/skins/default/xui/zh/floater_test_text_vertical_aligment.xml b/indra/newview/skins/default/xui/zh/floater_test_text_vertical_aligment.xml
new file mode 100755
index 0000000000..83b6df6fe5
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/floater_test_text_vertical_aligment.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="Test Floater" title="測試浮動視窗"/>
diff --git a/indra/newview/skins/default/xui/zh/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/zh/floater_texture_ctrl.xml
index 01586ac153..02d06323d4 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_texture_ctrl.xml
+++ b/indra/newview/skins/default/xui/zh/floater_texture_ctrl.xml
@@ -1,23 +1,35 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="texture picker" title="PICK: TEXTURE">
+<floater name="texture picker" title="ç²¾é¸ï¼šæ質">
<floater.string name="choose_picture">
- 點擊以挑é¸åœ–åƒ
+ 點按以挑é¸åœ–片
</floater.string>
<floater.string name="pick title">
- Pick:
+ ç²¾é¸åœ°é»žï¼š
</floater.string>
<text name="Multiple">
- Multiple textures
+ 多é‡æ質
</text>
+ <radio_group name="mode_selection">
+ <radio_item label="收ç´å€" name="inventory" value="0"/>
+ <radio_item label="本地" name="local" value="1"/>
+ </radio_group>
<text name="unknown">
尺寸:[DIMENSIONS]
</text>
<button label="é è¨­" label_selected="é è¨­" name="Default"/>
+ <button label="空白" label_selected="空白" name="Blank"/>
<button label="ç„¡" label_selected="ç„¡" name="None"/>
- <button label="Blank" label_selected="Blank" name="Blank"/>
<check_box initial_value="true" label="ç«‹å³å¥—用" name="apply_immediate_check"/>
+ <text name="preview_disabled" value="å·²åœç”¨é è¦½"/>
<filter_editor label="æ質éŽæ¿¾å™¨" name="inventory search editor"/>
<check_box initial_value="false" label="顯示資料夾" name="show_folders_check"/>
+ <button label="添加" label_selected="添加" name="l_add_btn"/>
+ <button label="移除" label_selected="移除" name="l_rem_btn"/>
+ <button label="上傳" label_selected="上傳" name="l_upl_btn"/>
+ <scroll_list name="l_name_list">
+ <column label="å稱" name="unit_name"/>
+ <column label="ID" name="unit_id_HIDDEN"/>
+ </scroll_list>
<button label="確定" label_selected="確定" name="Select"/>
<button label="å–消" label_selected="å–消" name="Cancel"/>
</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_texture_fetch_debugger.xml b/indra/newview/skins/default/xui/zh/floater_texture_fetch_debugger.xml
new file mode 100755
index 0000000000..0dcac17a75
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/floater_texture_fetch_debugger.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="TexFetchDebugger" title="æ質擷å–除錯器">
+ <text name="total_num_fetched_label">
+ 1. 已擷å–æ質總數:[NUM]
+ </text>
+ <text name="total_num_fetching_requests_label">
+ 2. 總擷å–請求數:[NUM]
+ </text>
+ <text name="total_num_cache_hits_label">
+ 3. å¿«å–總讀å–數:[NUM]
+ </text>
+ <text name="total_num_visible_tex_label">
+ 4. å¯è¦‹æ質總數:[NUM]
+ </text>
+ <text name="total_num_visible_tex_fetch_req_label">
+ 5. å¯è¦‹æ質擷å–總請求數:[NUM]
+ </text>
+ <text name="total_fetched_data_label">
+ 6. 總擷å–資料é‡ï¼š[SIZE1] KB,解碼資料é‡ï¼š[SIZE2] KB,[PIXEL] 百è¬åƒç´ 
+ </text>
+ <text name="total_fetched_vis_data_label">
+ 7. å¯è¦‹è³‡æ–™ç¸½é‡ï¼š[SIZE1] KB,解碼資料é‡ï¼š[SIZE2] KB
+ </text>
+ <text name="total_fetched_rendered_data_label">
+ 8. 總呈åƒè³‡æ–™é‡ï¼š[SIZE1] KB,解碼資料é‡ï¼š[SIZE2] KB,[PIXEL] 百è¬åƒç´ 
+ </text>
+ <text name="total_time_cache_read_label">
+ 9. å¿«å–讀å–總時間:[TIME] 秒
+ </text>
+ <text name="total_time_cache_write_label">
+ 10. å¿«å–寫入總時間:[TIME] 秒
+ </text>
+ <text name="total_time_decode_label">
+ 11. 解碼總時間:[TIME] 秒
+ </text>
+ <text name="total_time_gl_label">
+ 12. 建立 gl æ質總時間:[TIME] 秒
+ </text>
+ <text name="total_time_http_label">
+ 13. HTTP æ“·å–總時間:[TIME] 秒
+ </text>
+ <text name="total_time_fetch_label">
+ 14. 所有擷å–動作總時間:[TIME] 秒
+ </text>
+ <text name="total_time_refetch_vis_cache_label">
+ 15. 自快å–é‡æ–°æ“·å–å¯è¦‹æ質,時間:[TIME] 秒,擷å–é‡ï¼š[SIZE] KB,[PIXEL] 百è¬åƒç´ 
+ </text>
+ <text name="total_time_refetch_all_cache_label">
+ 16. 從快å–é‡æ–°æ“·å–所有æ質,時間:[TIME] 秒,擷å–é‡ï¼š[SIZE] KB,[PIXEL] 百è¬åƒç´ 
+ </text>
+ <text name="total_time_refetch_vis_http_label">
+ 17. 自 HTTP é‡æ–°æ“·å–å¯è¦‹æ質,時間:[TIME] 秒,擷å–é‡ï¼š[SIZE] KB,[PIXEL] 百è¬åƒç´ 
+ </text>
+ <text name="total_time_refetch_all_http_label">
+ 18. 自 HTTP é‡æ–°æ“·å–所有æ質,時間:[TIME] 秒,擷å–é‡ï¼š[SIZE] KB,[PIXEL] 百è¬åƒç´ 
+ </text>
+ <spinner label="19. æ質/åƒç´ æ¯”率:" name="texel_pixel_ratio"/>
+ <text name="texture_source_label">
+ 20. æ質來æºï¼š
+ </text>
+ <radio_group name="texture_source">
+ <radio_item label="å¿«å– + HTTP" name="0"/>
+ <radio_item label="åƒ…é™ HTTP" name="1"/>
+ </radio_group>
+ <button label="開始" name="start_btn"/>
+ <button label="é‡è¨­" name="clear_btn"/>
+ <button label="關閉" name="close_btn"/>
+ <button label="å¿«å–讀å–" name="cacheread_btn"/>
+ <button label="å¿«å–寫入" name="cachewrite_btn"/>
+ <button label="HTTP" name="http_btn"/>
+ <button label="解碼" name="decode_btn"/>
+ <button label="GL æ質" name="gl_btn"/>
+ <button label="å¿«å–é‡å–å¯è¦‹æ質" name="refetchviscache_btn"/>
+ <button label="é‡æ–°æ“·å–所有快å–" name="refetchallcache_btn"/>
+ <button label="HTTP é‡å–å¯è¦‹æ質" name="refetchvishttp_btn"/>
+ <button label="é‡æ–°æ“·å–所有 HTTP" name="refetchallhttp_btn"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_tools.xml b/indra/newview/skins/default/xui/zh/floater_tools.xml
index 2db98eb3d7..7e6c972f40 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_tools.xml
+++ b/indra/newview/skins/default/xui/zh/floater_tools.xml
@@ -1,43 +1,49 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="toolbox floater" short_title="建造工具">
+ <floater.string name="grid_screen_text">
+ 螢幕
+ </floater.string>
+ <floater.string name="grid_local_text">
+ 本地
+ </floater.string>
+ <floater.string name="grid_world_text">
+ 世界
+ </floater.string>
+ <floater.string name="grid_reference_text">
+ åƒè€ƒ
+ </floater.string>
+ <floater.string name="grid_attachment_text">
+ 附件
+ </floater.string>
<floater.string name="status_rotate">
- Drag colored bands to rotate object
+ 拖曳色æ¢å¯ä»¥æ—‹è½‰ç‰©ä»¶
</floater.string>
<floater.string name="status_scale">
- Click and drag to stretch selected side
+ 按ä½ä¸¦æ‹–曳,å¯ä»¥æ‹‰ä¼¸æ‰€é¸çš„一é¢
</floater.string>
<floater.string name="status_move">
- Drag to move, shift-drag to copy
+ 拖曳就會移動,按下 Shift å†æ‹–曳則å¯è¤‡è£½
</floater.string>
<floater.string name="status_modifyland">
- Click and hold to modify land
+ 按ä½ä¸æ”¾é–‹ï¼Œå¯ä»¥ä¿®æ”¹åœŸåœ°
</floater.string>
<floater.string name="status_camera">
- Click and drag to move camera
+ 按ä½ä¸¦æ‹–曳,å¯ä»¥ç§»å‹•æ”影機
</floater.string>
<floater.string name="status_grab">
- Drag to move, Ctrl to lift, Ctrl+Shift to rotate
+ 拖曳就å¯ç§»å‹•ï¼ŒæŒ‰ä¸‹ Ctrl å¯ä»¥æ‹¿èµ·ï¼ŒæŒ‰ä¸‹ Ctrl+Shift å¯ä»¥æ—‹è½‰
</floater.string>
<floater.string name="status_place">
- Click inworld to build
+ 在虛擬世界裡點按一下,å¯ä»¥å»ºè£½ç‰©ä»¶
</floater.string>
<floater.string name="status_selectland">
- Click and drag to select land
+ 按ä½ä¸¦æ‹–曳,å¯ä»¥é¸å–土地
</floater.string>
- <floater.string name="grid_screen_text">
- Screen
+ <floater.string name="status_selectcount">
+ é¸å–了 [OBJ_COUNT] 個物件,土地è¡æ“Šé‡ [LAND_IMPACT]
</floater.string>
- <floater.string name="grid_local_text">
- Local
- </floater.string>
- <floater.string name="grid_world_text">
- World
- </floater.string>
- <floater.string name="grid_reference_text">
- Reference
- </floater.string>
- <floater.string name="grid_attachment_text">
- Attachment
+ <floater.string name="status_remaining_capacity">
+ 剩餘容ç´é‡ [LAND_CAPACITY]。
</floater.string>
<button name="button focus" tool_tip="èšç„¦"/>
<button name="button move" tool_tip="移動"/>
@@ -45,7 +51,7 @@
<button name="button create" tool_tip="創造"/>
<button name="button land" tool_tip="土地"/>
<text name="text status">
- Drag to move, shift-drag to copy
+ 拖曳就會移動,按下 Shift å†æ‹–曳則å¯è¤‡è£½
</text>
<radio_group name="focus_radio_group">
<radio_item label="縮放" name="radio zoom"/>
@@ -56,7 +62,7 @@
<radio_group name="move_radio_group">
<radio_item label="移動" name="radio move"/>
<radio_item label="舉起(Ctrl)" name="radio lift"/>
- <radio_item label="Spin (Ctrl+Shift)" name="radio spin"/>
+ <radio_item label="旋轉(Ctrl+Shift)" name="radio spin"/>
</radio_group>
<radio_group name="edit_radio_group">
<radio_item label="移動" name="radio position"/>
@@ -67,39 +73,36 @@
<check_box label="編輯è¯çµéƒ¨åˆ†" name="checkbox edit linked parts"/>
<button label="è¯çµ" name="link_btn"/>
<button label="å–消è¯çµ" name="unlink_btn"/>
- <text name="RenderingCost" tool_tip="Shows the rendering cost calculated for this object">
- þ: [COUNT]
- </text>
<text label="åŒæ™‚伸展兩å´" name="checkbox uniform label">
åŒæ™‚伸展兩å´
</text>
<check_box initial_value="true" label="伸展æ質" name="checkbox stretch textures"/>
- <check_box initial_value="true" label="貼齊格線" name="checkbox snap to grid"/>
+ <check_box initial_value="true" label="Snap" name="checkbox snap to grid"/>
<combo_box name="combobox grid mode" tool_tip="é¸æ“‡ç‰©ä»¶å®šä½åƒè€ƒçš„格線尺度類型">
- <combo_box.item label="世界格線" name="World"/>
- <combo_box.item label="地方格線" name="Local"/>
- <combo_box.item label="åƒè€ƒæ ¼ç·š" name="Reference"/>
+ <combo_box.item label="世界" name="World"/>
+ <combo_box.item label="本地" name="Local"/>
+ <combo_box.item label="åƒè€ƒ" name="Reference"/>
</combo_box>
- <button name="Options..." tool_tip="察看更多格線é¸é …"/>
- <button name="ToolCube" tool_tip="Cube"/>
- <button name="ToolPrism" tool_tip="Prism"/>
- <button name="ToolPyramid" tool_tip="Pyramid"/>
- <button name="ToolTetrahedron" tool_tip="Tetrahedron"/>
- <button name="ToolCylinder" tool_tip="Cylinder"/>
- <button name="ToolHemiCylinder" tool_tip="Hemicylinder"/>
- <button name="ToolCone" tool_tip="Cone"/>
- <button name="ToolHemiCone" tool_tip="Hemicone"/>
- <button name="ToolSphere" tool_tip="Sphere"/>
- <button name="ToolHemiSphere" tool_tip="Hemisphere"/>
- <button name="ToolTorus" tool_tip="Torus"/>
- <button name="ToolTube" tool_tip="Tube"/>
- <button name="ToolRing" tool_tip="Ring"/>
- <button name="ToolTree" tool_tip="Tree"/>
- <button name="ToolGrass" tool_tip="Grass"/>
+ <button label="" name="Options..." tool_tip="察看更多格線é¸é …"/>
+ <button name="ToolCube" tool_tip="立方體"/>
+ <button name="ToolPrism" tool_tip="稜é¡é«”"/>
+ <button name="ToolPyramid" tool_tip="金字塔"/>
+ <button name="ToolTetrahedron" tool_tip="正四é¢é«”"/>
+ <button name="ToolCylinder" tool_tip="圓柱體"/>
+ <button name="ToolHemiCylinder" tool_tip="åŠåœ“柱體"/>
+ <button name="ToolCone" tool_tip="圓éŒ"/>
+ <button name="ToolHemiCone" tool_tip="åŠåœ“éŒ"/>
+ <button name="ToolSphere" tool_tip="çƒé«”"/>
+ <button name="ToolHemiSphere" tool_tip="åŠçƒé«”"/>
+ <button name="ToolTorus" tool_tip="ç’°é¢"/>
+ <button name="ToolTube" tool_tip="圓管"/>
+ <button name="ToolRing" tool_tip="圓環"/>
+ <button name="ToolTree" tool_tip="樹木"/>
+ <button name="ToolGrass" tool_tip="è‰åœ°"/>
<check_box label="ä¿æŒå·²é¸æ“‡çš„工具" name="checkbox sticky"/>
- <check_box label="覆製é¸æ“‡" name="checkbox copy selection"/>
- <check_box initial_value="true" label="Center Copy" name="checkbox copy centers"/>
- <check_box label="Rotate Copy" name="checkbox copy rotates"/>
+ <check_box label="複製é¸æ“‡" name="checkbox copy selection"/>
+ <check_box initial_value="true" label="複製物置中" name="checkbox copy centers"/>
+ <check_box label="旋轉複製物" name="checkbox copy rotates"/>
<radio_group name="land_radio_group">
<radio_item label="é¸æ“‡åœŸåœ°" name="radio select land"/>
<radio_item label="攤平" name="radio flatten"/>
@@ -121,11 +124,11 @@
</text>
<slider_bar initial_value="0.00" name="slider force"/>
<button label="套用" label_selected="套用" name="button apply to selection" tool_tip="修改所é¸æ“‡çš„土地"/>
- <text name="obj_count">
- 物件: [COUNT]
+ <text name="selection_empty">
+ 未åšä»»ä½•é¸æ“‡ã€‚
</text>
- <text name="prim_count">
- 幾何元件: [COUNT]
+ <text name="remaining_capacity">
+ [CAPACITY_STRING] [secondlife:///app/openfloater/object_weights 詳情]
</text>
<tab_container name="Object Info Tabs">
<panel label="一般" name="General">
@@ -147,6 +150,12 @@
<panel.string name="text modify info 4">
ä½ ä¸èƒ½ä¿®æ”¹é€™äº›ç‰©ä»¶
</panel.string>
+ <panel.string name="text modify info 5">
+ 無法跨地å€ä¿®æ”¹é€™å€‹ç‰©ä»¶
+ </panel.string>
+ <panel.string name="text modify info 6">
+ 無法跨地å€ä¿®æ”¹é€™äº›ç‰©ä»¶
+ </panel.string>
<panel.string name="text modify warning">
ä½ å¿…é ˆé¸å–整個物件以設定權é™
</panel.string>
@@ -154,16 +163,16 @@
價格: L$
</panel.string>
<panel.string name="Cost Total">
- 總價: L$
+ 總價:L$
</panel.string>
<panel.string name="Cost Per Unit">
- 單價æ¯å€‹ï¼š L$
+ 單價:L$
</panel.string>
<panel.string name="Cost Mixed">
- Mixed Price
+ æ··åˆåƒ¹æ ¼
</panel.string>
<panel.string name="Sale Mixed">
- Mixed Sale
+ æ··åˆéŠ·å”®
</panel.string>
<text name="Name:">
å稱:
@@ -175,49 +184,49 @@
創造者:
</text>
<text name="Owner:">
- æ“有者:
+ 所有人:
</text>
<text name="Group:">
群組:
</text>
<name_box initial_value="載入中..." name="Group Name Proxy"/>
- <button name="button set group" tool_tip="é¸æ“‡ä¸€å€‹ç¾¤çµ„以分享這物件權é™"/>
- <check_box label="分享" name="checkbox share with group" tool_tip="Allow all members of the set group to share your modify permissions for this object. You must Deed to enable role restrictions."/>
- <button label="讓渡" label_selected="讓渡" name="button deed" tool_tip="Deeding gives this item away with next owner permissions. Group shared objects can be deeded by a group officer."/>
+ <button name="button set group" tool_tip="é¸æ“‡ä¸€å€‹ç¾¤çµ„以分享這物件的權é™"/>
+ <check_box label="分享" name="checkbox share with group" tool_tip="å…許此群組所有æˆå“¡å…±äº«ä½ ä¿®æ”¹æ­¤ç‰©ä»¶çš„權é™ã€‚ 你必須讓渡æ‰èƒ½å•Ÿå‹•è§’色é™åˆ¶ã€‚"/>
+ <button label="讓渡" label_selected="讓渡" name="button deed" tool_tip="「讓渡ã€æœƒæŠŠé€™ç‰©ä»¶è´ˆé€å‡ºåŽ»ä¸¦è³¦äºˆã€Œä¸‹ä¸€å€‹æ‰€æœ‰äººã€æ¬Šé™ã€‚ 群組所分享的物件å¯ç”±ç¾¤çµ„è·å“¡åŠ ä»¥è®“渡。"/>
<text name="label click action">
- 點擊以:
+ 點按以:
</text>
<combo_box name="clickaction">
<combo_box.item label="觸碰(é è¨­ï¼‰" name="Touch/grab(default)"/>
<combo_box.item label="å在物件上" name="Sitonobject"/>
<combo_box.item label="購買物件" name="Buyobject"/>
<combo_box.item label="支付物件" name="Payobject"/>
- <combo_box.item label="é–‹å•Ÿ" name="Open"/>
+ <combo_box.item label="打開" name="Open"/>
<combo_box.item label="縮放" name="Zoom"/>
</combo_box>
- <check_box label="出售:" name="checkbox for sale"/>
+ <check_box label="出售中:" name="checkbox for sale"/>
+ <spinner label="L$" name="Edit Cost"/>
<combo_box name="sale type">
- <combo_box.item label="副本" name="Copy"/>
+ <combo_box.item label="æšåº¨" name="Copy"/>
<combo_box.item label="內容" name="Contents"/>
<combo_box.item label="原件" name="Original"/>
</combo_box>
- <spinner label="價格: L$" name="Edit Cost"/>
- <check_box label="顯示在æœå°‹ä¸­" name="search_check" tool_tip="讓其他人å¯ä»¥åœ¨æœå°‹çµæžœä¸­çœ‹åˆ°é€™ç‰©ä»¶"/>
+ <check_box label="顯示在æœå°‹ä¸­" name="search_check" tool_tip="讓其他人å¯ä»¥åœ¨æœå°‹çµæžœä¸­å¯Ÿçœ‹åˆ°æ­¤ç‰©ä»¶"/>
<panel name="perms_build">
<text name="perm_modify">
- ä½ å¯ä»¥ä¿®æ”¹é€™å€‹ç‰©ä»¶
+ 你能修改這個物件
</text>
<text name="Anyone can:">
任何人:
</text>
<check_box label="移動" name="checkbox allow everyone move"/>
- <check_box label="覆製" name="checkbox allow everyone copy"/>
+ <check_box label="æšåº¨" name="checkbox allow everyone copy"/>
<text name="Next owner can:">
- 下一個æ“有者:
+ 下一個所有人:
</text>
<check_box label="修改" name="checkbox next owner can modify"/>
- <check_box label="覆製" name="checkbox next owner can copy"/>
- <check_box label="轉移" name="checkbox next owner can transfer" tool_tip="下一個æ“有者å¯ä»¥é€äººæˆ–轉售這個物件"/>
+ <check_box label="æšåº¨" name="checkbox next owner can copy"/>
+ <check_box label="轉移" name="checkbox next owner can transfer" tool_tip="下一個所有人å¯è´ˆé€æˆ–轉售這個物件"/>
<text name="B:">
B:
</text>
@@ -237,9 +246,14 @@
F:
</text>
</panel>
+ <panel name="pathfinding_attrs_panel">
+ <text name="pathfinding_attributes_label">
+ 尋徑屬性:
+ </text>
+ </panel>
</panel>
<panel label="物件" name="Object">
- <check_box label="鎖定" name="checkbox locked" tool_tip="é é˜²ç‰©ä»¶è¢«ç§»å‹•æˆ–刪除,最常使用的狀æ³æ˜¯åœ¨å»ºé€ éŽç¨‹ä¸­é¿å…被æ„外的編輯。"/>
+ <check_box label="已鎖ä½" name="checkbox locked" tool_tip="é¿å…物件被移動或刪除。 這在建製éŽç¨‹ä¸­éžå¸¸æœ‰ç”¨ï¼Œå¯é¿å…æ„外的編輯更動。"/>
<check_box label="物ç†æ€§" name="Physical Checkbox Ctrl" tool_tip="å…許物件被推撞與å—é‡åŠ›å½±éŸ¿"/>
<check_box label="暫時性" name="Temporary Checkbox Ctrl" tool_tip="使物件在建造後的一分é˜è‡ªå‹•åˆªé™¤"/>
<check_box label="幻影性" name="Phantom Checkbox Ctrl" tool_tip="使物件ä¸æœƒèˆ‡å…¶ä»–物件或化身產生碰撞"/>
@@ -262,26 +276,17 @@
<spinner label="Y" name="Rot Y"/>
<spinner label="Z" name="Rot Z"/>
<combo_box name="comboBaseType">
- <combo_box.item label="Box" name="Box"/>
- <combo_box.item label="Cylinder" name="Cylinder"/>
- <combo_box.item label="Prism" name="Prism"/>
- <combo_box.item label="Sphere" name="Sphere"/>
- <combo_box.item label="Torus" name="Torus"/>
- <combo_box.item label="Tube" name="Tube"/>
- <combo_box.item label="Ring" name="Ring"/>
- <combo_box.item label="Sculpted" name="Sculpted"/>
- </combo_box>
- <combo_box name="material">
- <combo_box.item label="石頭" name="Stone"/>
- <combo_box.item label="金屬" name="Metal"/>
- <combo_box.item label="玻璃" name="Glass"/>
- <combo_box.item label="木頭" name="Wood"/>
- <combo_box.item label="肌肉" name="Flesh"/>
- <combo_box.item label="塑膠" name="Plastic"/>
- <combo_box.item label="橡膠" name="Rubber"/>
+ <combo_box.item label="ç®±å­" name="Box"/>
+ <combo_box.item label="圓柱體" name="Cylinder"/>
+ <combo_box.item label="稜é¡é«”" name="Prism"/>
+ <combo_box.item label="çƒé«”" name="Sphere"/>
+ <combo_box.item label="ç’°é¢" name="Torus"/>
+ <combo_box.item label="圓管" name="Tube"/>
+ <combo_box.item label="圓環" name="Ring"/>
+ <combo_box.item label="雕刻的" name="Sculpted"/>
</combo_box>
<text name="text cut">
- Path Cut (begin/end)
+ 路徑切斷(開始 / çµæŸï¼‰
</text>
<spinner label="B" name="cut begin"/>
<spinner label="E" name="cut end"/>
@@ -289,24 +294,24 @@
中空
</text>
<text name="text skew">
- Skew
+ åæ–œ
</text>
<text name="Hollow Shape">
中空形狀
</text>
<combo_box name="hole">
<combo_box.item label="é è¨­" name="Default"/>
- <combo_box.item label="Circle" name="Circle"/>
- <combo_box.item label="Square" name="Square"/>
- <combo_box.item label="Triangle" name="Triangle"/>
+ <combo_box.item label="圓圈" name="Circle"/>
+ <combo_box.item label="方形" name="Square"/>
+ <combo_box.item label="三角形" name="Triangle"/>
</combo_box>
<text name="text twist">
- Twist (begin/end)
+ 扭曲(開始 / çµæŸï¼‰
</text>
<spinner label="B" name="Twist Begin"/>
<spinner label="E" name="Twist End"/>
<text name="scale_taper">
- Taper
+ éŒåŒ–
</text>
<text name="scale_hole">
洞尺寸
@@ -314,54 +319,62 @@
<spinner label="X" name="Taper Scale X"/>
<spinner label="Y" name="Taper Scale Y"/>
<text name="text topshear">
- Top Shear
+ 頂部斜變
</text>
<spinner label="X" name="Shear X"/>
<spinner label="Y" name="Shear Y"/>
<text name="advanced_cut">
- Profile Cut (begin/end)
+ å´é¢åˆ‡æ–·ï¼ˆé–‹å§‹ / çµæŸï¼‰
</text>
<text name="advanced_dimple">
- Dimple (begin/end)
+ 凹陷(開始 / çµæŸï¼‰
</text>
<text name="advanced_slice">
- Slice (begin/end)
+ Slice(開始 / çµæŸï¼‰
</text>
<spinner label="B" name="Path Limit Begin"/>
<spinner label="E" name="Path Limit End"/>
<text name="text taper2">
- Taper
+ éŒåŒ–
</text>
<spinner label="X" name="Taper X"/>
<spinner label="Y" name="Taper Y"/>
<text name="text radius delta">
- Radius
+ åŠå¾‘
</text>
<text name="text revolutions">
- Revolutions
+ 旋轉
</text>
- <texture_picker label="Sculpt Texture" name="sculpt texture control" tool_tip="點擊以挑é¸åœ–åƒ"/>
- <check_box label="Mirror" name="sculpt mirror control" tool_tip="Flips sculpted prim along the X axis"/>
- <check_box label="Inside-out" name="sculpt invert control" tool_tip="Inverts the sculpted prims normals, making it appear inside-out"/>
+ <texture_picker label="雕刻æ質" name="sculpt texture control" tool_tip="點按以挑é¸åœ–片"/>
+ <check_box label="é¡åƒ" name="sculpt mirror control" tool_tip="沿X軸翻轉雕刻幾何元件"/>
+ <check_box label="內外倒翻" name="sculpt invert control" tool_tip="將雕刻幾何元件的正常值顛倒,使其看來有如內外倒翻"/>
<text name="label sculpt type">
- Stitching type
+ 縫åˆé¡žåž‹
</text>
<combo_box name="sculpt type control">
- <combo_box.item label="(無)" name="None"/>
- <combo_box.item label="Sphere" name="Sphere"/>
- <combo_box.item label="Torus" name="Torus"/>
- <combo_box.item label="Plane" name="Plane"/>
- <combo_box.item label="Cylinder" name="Cylinder"/>
+ <combo_box.item label="çƒé«”" name="Sphere"/>
+ <combo_box.item label="ç’°é¢" name="Torus"/>
+ <combo_box.item label="å¹³é¢" name="Plane"/>
+ <combo_box.item label="圓柱體" name="Cylinder"/>
</combo_box>
</panel>
<panel label="特性" name="Features">
+ <panel.string name="None">
+ ç„¡
+ </panel.string>
+ <panel.string name="Prim">
+ 幾何元件
+ </panel.string>
+ <panel.string name="Convex Hull">
+ 凸包
+ </panel.string>
<text name="select_single">
åªèƒ½é¸æ“‡ä¸€å€‹å¹¾ä½•å…ƒä»¶åŽ»ç·¨è¼¯ç´°ç¯€ã€‚
</text>
<text name="edit_object">
編輯物件特性:
</text>
- <check_box label="彈性路徑" name="Flexible1D Checkbox Ctrl" tool_tip="Allows object to flex about the Z axis (Client-side only)"/>
+ <check_box label="彈性路徑" name="Flexible1D Checkbox Ctrl" tool_tip="å…許物件繞 Z 軸伸展(僅é™å®¢æˆ¶ç«¯ï¼‰"/>
<spinner label="柔軟" name="FlexNumSections"/>
<spinner label="é‡åŠ›" name="FlexGravity"/>
<spinner label="拖曳" name="FlexFriction"/>
@@ -371,14 +384,31 @@
<spinner label="強制 Y 軸" name="FlexForceY"/>
<spinner label="強制 Z 軸" name="FlexForceZ"/>
<check_box label="å…‰æº" name="Light Checkbox Ctrl" tool_tip="導致物件發光"/>
- <color_swatch name="colorswatch" tool_tip="點擊以開啟é¡è‰²æŒ‘é¸å™¨"/>
- <texture_picker label="" name="light texture control" tool_tip="Click to choose a projection image (only has effect with deferred rendering enabled)"/>
+ <color_swatch name="colorswatch" tool_tip="點按以開啟é¡è‰²æŒ‘é¸å™¨"/>
+ <texture_picker label="" name="light texture control" tool_tip="點é¸æŠ•å½±åœ–åƒï¼ˆåªåœ¨å•Ÿç”¨å»¶é²å‘ˆåƒæ™‚生效)"/>
<spinner label="強度" name="Light Intensity"/>
- <spinner label="FOV" name="Light FOV"/>
+ <spinner label="視角" name="Light FOV"/>
<spinner label="åŠå¾‘" name="Light Radius"/>
- <spinner label="Focus" name="Light Focus"/>
+ <spinner label="焦點" name="Light Focus"/>
<spinner label="衰減" name="Light Falloff"/>
- <spinner label="Ambiance" name="Light Ambiance"/>
+ <spinner label="環境" name="Light Ambiance"/>
+ <text name="label physicsshapetype">
+ 物ç†å½¢ç‹€é¡žåž‹ï¼š
+ </text>
+ <combo_box name="Physics Shape Type Combo Ctrl" tool_tip="é¸æ“‡ç‰©ç†å½¢ç‹€é¡žåž‹"/>
+ <combo_box name="material">
+ <combo_box.item label="石頭" name="Stone"/>
+ <combo_box.item label="金屬" name="Metal"/>
+ <combo_box.item label="玻璃" name="Glass"/>
+ <combo_box.item label="木頭" name="Wood"/>
+ <combo_box.item label="肌肉" name="Flesh"/>
+ <combo_box.item label="塑膠" name="Plastic"/>
+ <combo_box.item label="橡膠" name="Rubber"/>
+ </combo_box>
+ <spinner label="é‡åŠ›" name="Physics Gravity"/>
+ <spinner label="摩擦" name="Physics Friction"/>
+ <spinner label="密度(100 公斤 / 立方公尺)" name="Physics Density"/>
+ <spinner label="æ¢å¾©" name="Physics Restitution"/>
</panel>
<panel label="æ質" name="Texture">
<panel.string name="string repeats per meter">
@@ -387,8 +417,8 @@
<panel.string name="string repeats per face">
æ¯ä¸€é¢é‡è¦†æ¬¡æ•¸
</panel.string>
- <texture_picker label="æ質" name="texture control" tool_tip="點擊以挑é¸åœ–åƒ"/>
- <color_swatch label="é¡è‰²" name="colorswatch" tool_tip="點擊以開啟é¡è‰²æŒ‘é¸å™¨"/>
+ <texture_picker label="æ質" name="texture control" tool_tip="點按以挑é¸åœ–片"/>
+ <color_swatch label="é¡è‰²" name="colorswatch" tool_tip="點按以開啟é¡è‰²æŒ‘é¸å™¨"/>
<text name="color trans">
é€æ˜Žåº¦ %
</text>
@@ -417,34 +447,29 @@
</text>
<combo_box name="combobox bumpiness">
<combo_box.item label="ç„¡" name="None"/>
- <combo_box.item label="Brightness" name="Brightness"/>
- <combo_box.item label="Darkness" name="Darkness"/>
- <combo_box.item label="woodgrain" name="woodgrain"/>
- <combo_box.item label="bark" name="bark"/>
- <combo_box.item label="bricks" name="bricks"/>
- <combo_box.item label="checker" name="checker"/>
- <combo_box.item label="concrete" name="concrete"/>
- <combo_box.item label="crustytile" name="crustytile"/>
- <combo_box.item label="cutstone" name="cutstone"/>
- <combo_box.item label="discs" name="discs"/>
- <combo_box.item label="gravel" name="gravel"/>
- <combo_box.item label="petridish" name="petridish"/>
- <combo_box.item label="siding" name="siding"/>
- <combo_box.item label="stonetile" name="stonetile"/>
- <combo_box.item label="stucco" name="stucco"/>
- <combo_box.item label="suction" name="suction"/>
- <combo_box.item label="weave" name="weave"/>
+ <combo_box.item label="亮度" name="Brightness"/>
+ <combo_box.item label="暗度" name="Darkness"/>
+ <combo_box.item label="木紋" name="woodgrain"/>
+ <combo_box.item label="樹皮" name="bark"/>
+ <combo_box.item label="磚" name="bricks"/>
+ <combo_box.item label="æ ¼å­" name="checker"/>
+ <combo_box.item label="æ··å‡åœŸ" name="concrete"/>
+ <combo_box.item label="粗花磚" name="crustytile"/>
+ <combo_box.item label="石磚" name="cutstone"/>
+ <combo_box.item label="圓盤" name="discs"/>
+ <combo_box.item label="碎石" name="gravel"/>
+ <combo_box.item label="培養皿" name="petridish"/>
+ <combo_box.item label="å´é‚Šç‰‡" name="siding"/>
+ <combo_box.item label="石磚格" name="stonetile"/>
+ <combo_box.item label="彩色沙岩" name="stucco"/>
+ <combo_box.item label="å¸é™„" name="suction"/>
+ <combo_box.item label="編織" name="weave"/>
</combo_box>
- <check_box initial_value="false" label="å°é½Šå¹³é¢" name="checkbox planar align" tool_tip="以最後所é¸æ“‡çš„é¢ç‚ºåŸºæº–,å°é½Šå…¨éƒ¨æ‰€é¸æ“‡çš„é¢ä¸Šçš„æ質。這必須使用平é¢æ質映射方å¼ã€‚"/>
- <text name="rpt">
- é‡è¦†æ¬¡æ•¸ / é¢
- </text>
<spinner label="水平(U)" name="TexScaleU"/>
<check_box label="翻轉" name="checkbox flip s"/>
<spinner label="垂直(V)" name="TexScaleV"/>
<check_box label="翻轉" name="checkbox flip t"/>
<spinner label="旋轉˚" name="TexRot"/>
- <spinner label="é‡è¦†æ¬¡æ•¸ / 公尺" name="rptctrl"/>
<button label="套用" label_selected="套用" name="button apply"/>
<text name="tex offset">
æ質ä½ç§»
@@ -476,15 +501,8 @@
<text name="label_area">
é¢ç©ï¼š [AREA] m²
</text>
- <button label="關於土地" label_selected="關於土地" name="button about land"/>
- <check_box label="顯示æ“有者" name="checkbox show owners" tool_tip="Colorize the parcels according to the type of owner:
-
-綠色 = 你的土地
-æ°´è— = 你群組的土地
-紅色 = 其他人所有
-黃色 = 出售
-紫色 = æ‹è³£
-ç°è‰² = 公有地"/>
+ <button label="土地資料" label_selected="土地資料" name="button about land"/>
+ <check_box label="顯示所有人" name="checkbox show owners" tool_tip="根據所有人將地段分類上色: 綠色 = 你的土地 æ°´è— = 你群組的土地 紅色 = 其他人所有 黃色 = 出售 紫色 = æ‹è³£ ç°è‰² = 公有地"/>
<text name="label_parcel_modify">
修改地段
</text>
diff --git a/indra/newview/skins/default/xui/zh/floater_top_objects.xml b/indra/newview/skins/default/xui/zh/floater_top_objects.xml
index 0e7e0c5b1a..6f50be0855 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_top_objects.xml
+++ b/indra/newview/skins/default/xui/zh/floater_top_objects.xml
@@ -1,28 +1,25 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="top_objects" title="Top Objects">
+<floater name="top_objects" title="排行最高的物件">
<floater.string name="top_scripts_title">
- Top Scripts
+ 排行最高的腳本
</floater.string>
<floater.string name="top_scripts_text">
- [COUNT] scripts taking a total of [TIME] ms
+ [COUNT] 個腳本共需時 [TIME] 毫秒
</floater.string>
<floater.string name="scripts_score_label">
- Time
- </floater.string>
- <floater.string name="scripts_mono_time_label">
- Mono Time
+ 時間
</floater.string>
<floater.string name="top_colliders_title">
- Top Colliders
+ 最常碰撞物項
</floater.string>
<floater.string name="top_colliders_text">
- Top [COUNT] objects experiencing many potential collisions
+ 排行最高的 [COUNT] 個物件å¯èƒ½ç™¼ç”Ÿå¤šæ¬¡ç¢°æ’ž
</floater.string>
<floater.string name="colliders_score_label">
ç©åˆ†
</floater.string>
<floater.string name="none_descriptor">
- 未發ç¾ã€‚
+ 查無çµæžœã€‚
</floater.string>
<text name="title_text">
載入中...
@@ -30,11 +27,12 @@
<scroll_list name="objects_list">
<scroll_list.columns label="ç©åˆ†" name="score"/>
<scroll_list.columns label="å稱" name="name"/>
- <scroll_list.columns label="æ“有者" name="owner"/>
+ <scroll_list.columns label="所有人" name="owner"/>
<scroll_list.columns label="ä½ç½®" name="location"/>
- <scroll_list.columns label="Time" name="time"/>
- <scroll_list.columns label="Mono Time" name="mono_time"/>
- <scroll_list.columns label="URLs" name="URLs"/>
+ <scroll_list.columns label="地段" name="parcel"/>
+ <scroll_list.columns label="時間" name="time"/>
+ <scroll_list.columns label="URL" name="URLs"/>
+ <scroll_list.columns label="記憶體 (KB)" name="memory"/>
</scroll_list>
<text name="id_text">
物件 ID:
@@ -45,11 +43,15 @@
</text>
<button label="éŽæ¿¾å™¨" name="filter_object_btn"/>
<text name="owner_name_text">
- æ“有者:
+ 所有人:
</text>
<button label="éŽæ¿¾å™¨" name="filter_owner_btn"/>
+ <text name="parcel_name_text">
+ 地段:
+ </text>
+ <button label="éŽæ¿¾å™¨" name="filter_parcel_btn"/>
<button label="退回所é¸æ“‡çš„" name="return_selected_btn"/>
<button label="全部退回" name="return_all_btn"/>
- <button label="關閉所é¸æ“‡çš„" name="disable_selected_btn"/>
- <button label="全部關閉" name="disable_all_btn"/>
+ <button label="åœç”¨æ‰€é¸çš„" name="disable_selected_btn"/>
+ <button label="全部åœç”¨" name="disable_all_btn"/>
</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_tos.xml b/indra/newview/skins/default/xui/zh/floater_tos.xml
index 5f9e16afe1..3da9445a55 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_tos.xml
+++ b/indra/newview/skins/default/xui/zh/floater_tos.xml
@@ -4,12 +4,12 @@
http://secondlife.com/app/tos/
</floater.string>
<floater.string name="loading_url">
- data:text/html,%3Chtml%3E%3Chead%3E%3C/head%3E%3Cbody text=%22000000%22%3E%3Ch2%3E Loading %3Ca%20target%3D%22_external%22%20href%3D%22http%3A//secondlife.com/app/tos/%22%3ETerms%20of%20Service%3C/a%3E...%3C/h2%3E %3C/body%3E %3C/html%3E
+ data:text/html,%3Chtml%3E%3Chead%3E%3C/head%3E%3Cbody text=%22000000%22%3E%3Ch2%3E 正在載入 %3Ca%20target%3D%22_external%22%20href%3D%22http%3A//secondlife.com/app/tos/%22%3ETerms%20of%20Service%3C/a%3E...%3C/h2%3E %3C/body%3E %3C/html%3E
</floater.string>
<button label="繼續" label_selected="繼續" name="Continue"/>
<button label="å–消" label_selected="å–消" name="Cancel"/>
<check_box label="我åŒæ„接å—æœå‹™æ¢æ¬¾åŠéš±ç§æ”¿ç­–" name="agree_chk"/>
<text name="tos_heading">
- 請謹慎閱讀以下的æœå‹™æ¢æ¬¾åŠéš±ç§æ”¿ç­–。è¦ç¹¼çºŒç™»å…¥åˆ° [SECOND_LIFE],你必須接å—這些å”議。
+ 請仔細閱讀以下æœå‹™æ¢æ¬¾åŠéš±ç§æ”¿ç­–。 繼續登入 [SECOND_LIFE] å‰ï¼Œä½ å¿…é ˆåŒæ„æ¢æ¬¾ã€‚
</text>
</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_toybox.xml b/indra/newview/skins/default/xui/zh/floater_toybox.xml
new file mode 100755
index 0000000000..fc6b6ea611
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/floater_toybox.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="Toybox" title="工具列按鈕">
+ <text name="toybox label 1">
+ 將按鈕拖入或拖離工具列,å³å¯æ–°å¢žæˆ–移除該按鈕。
+ </text>
+ <text name="toybox label 2">
+ 按鈕將根據æ¯ä¸€å€‹å·¥å…·åˆ—的設定,僅顯示圖示或一併顯示文字標籤。
+ </text>
+ <button label="清除所有工具列" label_selected="清除所有工具列" name="btn_clear_all"/>
+ <button label="還原é è¨­å€¼" label_selected="還原é è¨­å€¼" name="btn_restore_defaults"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_translation_settings.xml b/indra/newview/skins/default/xui/zh/floater_translation_settings.xml
new file mode 100755
index 0000000000..fe84872557
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/floater_translation_settings.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="floater_translation_settings" title="èŠå¤©å…§å®¹ç¿»è­¯è¨­å®š">
+ <string name="bing_api_key_not_verified">
+ Bing AppID 未通éŽé©—證。 è«‹å†è©¦ä¸€æ¬¡ã€‚
+ </string>
+ <string name="google_api_key_not_verified">
+ Google API éµå€¼æœªé€šéŽé©—證。 è«‹å†è©¦ä¸€æ¬¡ã€‚
+ </string>
+ <string name="bing_api_key_verified">
+ Bing AppID é©—è­‰æˆåŠŸã€‚
+ </string>
+ <string name="google_api_key_verified">
+ Google API éµå€¼é©—è­‰æˆåŠŸã€‚
+ </string>
+ <check_box label="èŠå¤©æ™‚啟用機器翻譯" name="translate_chat_checkbox"/>
+ <text name="translate_language_label">
+ å°‡èŠå¤©å…§å®¹ç¿»è­¯æˆï¼š
+ </text>
+ <combo_box name="translate_language_combo">
+ <combo_box.item label="系統é è¨­" name="System Default Language"/>
+ <combo_box.item label="英語" name="English"/>
+ <combo_box.item label="Dansk(丹麥語)" name="Danish"/>
+ <combo_box.item label="Deutsch(德語)" name="German"/>
+ <combo_box.item label="Español(西ç­ç‰™èªžï¼‰" name="Spanish"/>
+ <combo_box.item label="Français(法語)" name="French"/>
+ <combo_box.item label="Italiano(義大利語)" name="Italian"/>
+ <combo_box.item label="Magyar(匈牙利語)" name="Hungarian"/>
+ <combo_box.item label="Nederlands(è·è˜­èªžï¼‰" name="Dutch"/>
+ <combo_box.item label="Polski(波蘭語)" name="Polish"/>
+ <combo_box.item label="Português(葡è„牙語)" name="Portugese"/>
+ <combo_box.item label="РуÑÑкий(俄羅斯語)" name="Russian"/>
+ <combo_box.item label="Türkçe(土耳其語)" name="Turkish"/>
+ <combo_box.item label="УкраїнÑька(çƒå…‹è˜­èªžï¼‰" name="Ukrainian"/>
+ <combo_box.item label="中文(正體)" name="Chinese"/>
+ <combo_box.item label="日本語(日語)" name="Japanese"/>
+ <combo_box.item label="한국어(漢語)" name="Korean"/>
+ </combo_box>
+ <text name="tip">
+ é¸æ“‡ç¿»è­¯æœå‹™ï¼š
+ </text>
+ <radio_group name="translation_service_rg">
+ <radio_item initial_value="bing" label="Bing 翻譯器" name="bing"/>
+ <radio_item initial_value="google" label="Google 翻譯" name="google"/>
+ </radio_group>
+ <text name="bing_api_key_label">
+ Bing [http://www.bing.com/developers/createapp.aspx AppID]:
+ </text>
+ <button label="é©—è­‰" name="verify_bing_api_key_btn"/>
+ <text name="google_api_key_label">
+ Google [http://code.google.com/apis/language/translate/v2/getting_started.html#auth API éµå€¼]:
+ </text>
+ <button label="é©—è­‰" name="verify_google_api_key_btn"/>
+ <text name="google_links_text">
+ [http://code.google.com/apis/language/translate/v2/pricing.html 價格表] | [https://code.google.com/apis/console 統計]
+ </text>
+ <button label="確定" name="ok_btn"/>
+ <button label="å–消" name="cancel_btn"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_url_entry.xml b/indra/newview/skins/default/xui/zh/floater_url_entry.xml
index 9e3f3cd47d..9e3f3cd47d 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_url_entry.xml
+++ b/indra/newview/skins/default/xui/zh/floater_url_entry.xml
diff --git a/indra/newview/skins/default/xui/zh/floater_voice_chat_volume.xml b/indra/newview/skins/default/xui/zh/floater_voice_chat_volume.xml
new file mode 100644
index 0000000000..96caa7d333
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/floater_voice_chat_volume.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="floater_voice_volume" title="語音èŠå¤©éŸ³é‡">
+ <slider label="語音èŠå¤©" name="chat_voice_volume"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_voice_controls.xml b/indra/newview/skins/default/xui/zh/floater_voice_controls.xml
index 24b7efea4f..a3a7679957 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_voice_controls.xml
+++ b/indra/newview/skins/default/xui/zh/floater_voice_controls.xml
@@ -1,16 +1,16 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="floater_voice_controls" title="語音控制">
<string name="title_nearby">
- 附近的語音
+ 語音設定
</string>
<string name="title_group">
與 [GROUP] 進行群組通話
</string>
<string name="title_adhoc">
- 會議通話
+ 多方通話
</string>
<string name="title_peer_2_peer">
- 與 [NAME] 進行通話
+ 和 [NAME] 通話
</string>
<string name="no_one_near">
附近沒有一人開啟語音
@@ -22,7 +22,7 @@
<layout_panel name="leave_call_panel">
<layout_stack name="voice_effect_and_leave_call_stack">
<layout_panel name="leave_call_btn_panel">
- <button label="çµæŸé€šè©±" name="leave_call_btn"/>
+ <button label="離開通話" name="leave_call_btn"/>
</layout_panel>
</layout_stack>
</layout_panel>
diff --git a/indra/newview/skins/default/xui/zh/floater_voice_effect.xml b/indra/newview/skins/default/xui/zh/floater_voice_effect.xml
index 36efe20b65..aab5fa6028 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_voice_effect.xml
+++ b/indra/newview/skins/default/xui/zh/floater_voice_effect.xml
@@ -1,29 +1,158 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater label="地點" name="voice_effects" title="語音變è²">
+<floater label="地點" name="voice_effects" title="語音變è²è©¦è½">
<string name="no_voice_effect">
- (No Voice Morph)
+ (無變è²æ•ˆæžœï¼‰
</string>
<string name="active_voice_effect">
- (Active)
+ (使用中)
</string>
<string name="unsubscribed_voice_effect">
- (Unsubscribed)
+ (已åœæ­¢è¨‚用)
</string>
<string name="new_voice_effect">
- (New!)
+ (新的ï¼ï¼‰
+ </string>
+ <string name="effect_Arena">
+ 競技場
+ </string>
+ <string name="effect_Beast">
+ 野ç¸
+ </string>
+ <string name="effect_Buff">
+ Buff
+ </string>
+ <string name="effect_Buzz">
+ Buzz
+ </string>
+ <string name="effect_Camille">
+ å¡èœœå…’
+ </string>
+ <string name="effect_Creepy">
+ 怪異
+ </string>
+ <string name="effect_CreepyBot">
+ 怪異機器人
+ </string>
+ <string name="effect_Cyber">
+ 科幻
+ </string>
+ <string name="effect_DeepBot">
+ 深沉機器人
+ </string>
+ <string name="effect_Demon">
+ 魔鬼
+ </string>
+ <string name="effect_Female Elf">
+ 女性 - å°ç²¾éˆ
+ </string>
+ <string name="effect_Flirty">
+ 調情
+ </string>
+ <string name="effect_Foxy">
+ 香豔
+ </string>
+ <string name="effect_Halloween 2010 Bonus">
+ 2010è¬è–節加贈
+ </string>
+ <string name="effect_Helium">
+ 氦氣
+ </string>
+ <string name="effect_Husky">
+ 沙啞
+ </string>
+ <string name="effect_Husky Whisper">
+ 沙啞耳語
+ </string>
+ <string name="effect_Intercom">
+ å°è¬›æ©Ÿ
+ </string>
+ <string name="effect_Julia">
+ 茱莉亞
+ </string>
+ <string name="effect_Lo Lilt">
+ 輕微抑æšé “挫
+ </string>
+ <string name="effect_Macho">
+ 陽剛
+ </string>
+ <string name="effect_Micro">
+ Micro
+ </string>
+ <string name="effect_Mini">
+ è¿·ä½ 
+ </string>
+ <string name="effect_Model">
+ 模型
+ </string>
+ <string name="effect_Nano">
+ Nano
+ </string>
+ <string name="effect_Nightmare">
+ 惡夢
+ </string>
+ <string name="effect_PopBot">
+ PopBot
+ </string>
+ <string name="effect_Rachel">
+ 瑞秋
+ </string>
+ <string name="effect_Radio">
+ 收音機
+ </string>
+ <string name="effect_Robot">
+ 機器人
+ </string>
+ <string name="effect_Roxanne">
+ 蘿å§
+ </string>
+ <string name="effect_Rumble">
+ 低沉隆隆è²
+ </string>
+ <string name="effect_Sabrina">
+ 薩賓娜
+ </string>
+ <string name="effect_Samantha">
+ å§æ›¼èŽŽ
+ </string>
+ <string name="effect_Sexy">
+ 性感
+ </string>
+ <string name="effect_Shorty">
+ 矮個兒
+ </string>
+ <string name="effect_Smaller">
+ 較å°
+ </string>
+ <string name="effect_Sneaky">
+ 鬼祟
+ </string>
+ <string name="effect_Stallion">
+ 種馬
+ </string>
+ <string name="effect_Sultry">
+ 勾魂
+ </string>
+ <string name="effect_Thunder">
+ é›·è²
+ </string>
+ <string name="effect_Vixen">
+ 潑婦
+ </string>
+ <string name="effect_WhinyBot">
+ 哭鬧機器人
</string>
<text name="preview_text">
- To Preview
+ é è¦½
</text>
<text name="status_text">
- Record a sample, then click on a voice to hear how it will sound.
+ 錄下一段樣本,å†é»žæŒ‰è²éŸ³æª¢æŸ¥çµæžœã€‚
</text>
- <button label="Record" name="record_btn" tool_tip="Record a sample of your voice."/>
+ <button label="錄音" name="record_btn" tool_tip="錄下一段你的è²éŸ³ã€‚"/>
<button label="åœæ­¢" name="record_stop_btn"/>
<text name="voice_morphing_link">
- [[URL] Subscribe Now]
+ [[URL] ç¾åœ¨è¨‚用]
</text>
- <scroll_list name="voice_effect_list" tool_tip="Record a sample of your voice, then click an effect to preview.">
+ <scroll_list name="voice_effect_list" tool_tip="錄下一段你的è²éŸ³ï¼Œå†é»žé¸ä¸€å€‹æ•ˆæžœè©¦è½ã€‚">
<scroll_list.columns label="語音å稱" name="name"/>
<scroll_list.columns label="éŽæœŸ" name="expires"/>
</scroll_list>
diff --git a/indra/newview/skins/default/xui/zh/floater_voice_volume.xml b/indra/newview/skins/default/xui/zh/floater_voice_volume.xml
new file mode 100644
index 0000000000..4260a8d331
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/floater_voice_volume.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<!--
+ Not can_close / no title to avoid window chrome
+ Single instance - only have one at a time, recycle it each spawn
+-->
+<floater name="floater_voice_volume" title="音é‡">
+ <slider name="volume_slider" tool_tip="音é‡" value="0.5"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_water.xml b/indra/newview/skins/default/xui/zh/floater_water.xml
deleted file mode 100644
index 5fb57272af..0000000000
--- a/indra/newview/skins/default/xui/zh/floater_water.xml
+++ /dev/null
@@ -1,70 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="Water Floater" title="進階水文編輯器">
- <floater.string name="WLDefaultWaterNames">
- Default:Glassy:Pond:Murky:Second Plague:SNAKE!!!:Valdez
- </floater.string>
- <text name="KeyFramePresetsText">
- Water Presets:
- </text>
- <button label="新增" label_selected="新增" name="WaterNewPreset"/>
- <button label="儲存" label_selected="儲存" name="WaterSavePreset"/>
- <button label="刪除" label_selected="刪除" name="WaterDeletePreset"/>
- <tab_container name="Water Tabs">
- <panel label="設定" name="Settings">
- <text name="BHText">
- Water Fog Color
- </text>
- <color_swatch name="WaterFogColor" tool_tip="點擊以開啟é¡è‰²æŒ‘é¸å™¨"/>
- <text name="WaterFogDensText">
- Fog Density Exponent
- </text>
- <text name="WaterUnderWaterFogModText">
- Underwater Fog Modifier
- </text>
- <text name="BDensText">
- Reflection Wavelet Scale
- </text>
- <slider label="1" name="WaterNormalScaleX"/>
- <slider label="2" name="WaterNormalScaleY"/>
- <slider label="3" name="WaterNormalScaleZ"/>
- <text name="HDText">
- Fresnel Scale
- </text>
- <text name="FresnelOffsetText">
- Fresnel Offset
- </text>
- <text name="DensMultText">
- Refract Scale Above
- </text>
- <text name="WaterScaleBelowText">
- Refract Scale Below
- </text>
- <text name="MaxAltText">
- Blur Multiplier
- </text>
- </panel>
- <panel label="圖åƒ" name="Waves">
- <text name="BHText">
- Big Wave Direction
- </text>
- <text name="WaterWave1DirXText">
- X
- </text>
- <text name="WaterWave1DirYText">
- Y
- </text>
- <text name="BHText2">
- Little Wave Direction
- </text>
- <text name="WaterWave2DirXText">
- X
- </text>
- <text name="WaterWave2DirYText">
- Y
- </text>
- <text name="BHText3">
- 正常地圖
- </text>
- </panel>
- </tab_container>
-</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_web_content.xml b/indra/newview/skins/default/xui/zh/floater_web_content.xml
index be6bf8bb27..be6bf8bb27 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_web_content.xml
+++ b/indra/newview/skins/default/xui/zh/floater_web_content.xml
diff --git a/indra/newview/skins/default/xui/zh/floater_whitelist_entry.xml b/indra/newview/skins/default/xui/zh/floater_whitelist_entry.xml
index 967e36ead7..967e36ead7 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_whitelist_entry.xml
+++ b/indra/newview/skins/default/xui/zh/floater_whitelist_entry.xml
diff --git a/indra/newview/skins/default/xui/zh/floater_windlight_options.xml b/indra/newview/skins/default/xui/zh/floater_windlight_options.xml
deleted file mode 100644
index 383e35d50d..0000000000
--- a/indra/newview/skins/default/xui/zh/floater_windlight_options.xml
+++ /dev/null
@@ -1,167 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="WindLight floater" title="進階天空編輯器">
- <floater.string name="WLDefaultSkyNames">
- A-12AM:A-12PM:A-3AM:A-3PM:A-4.30PM:A-6AM:A-6PM:A-9AM:A-9PM:Barcelona:Blizzard:Blue Midday:Coastal Afternoon:Coastal Sunset:Default:Desert Sunset:Fine Day:Fluffy Big Clouds:Foggy:Funky Funky:Funky Funky Funky:Gelatto:Ghost:Incongruent Truths:Midday 1:Midday 2:Midday 3:Midday 4:Night:Pirate:Purple:Sailor&apos;s Delight:Sheer Sensuality
- </floater.string>
- <text name="KeyFramePresetsText">
- 天空é è¨­å€¼ï¼š
- </text>
- <button label="新增" label_selected="新增" name="WLNewPreset"/>
- <button label="儲存" label_selected="儲存" name="WLSavePreset"/>
- <button label="刪除" label_selected="刪除" name="WLDeletePreset"/>
- <button label="日循環編輯器" label_selected="日循環編輯器" name="WLDayCycleMenuButton"/>
- <tab_container name="WindLight Tabs">
- <panel label="大氣" name="Atmosphere">
- <text name="BHText">
- è—天水平線
- </text>
- <text name="BHText2">
- R
- </text>
- <text name="BHText3">
- G
- </text>
- <text name="BHText4">
- B
- </text>
- <text name="BHText5">
- I
- </text>
- <text name="BDensText">
- 陰霾水平線
- </text>
- <text name="BDensText2">
- è—天密度
- </text>
- <text name="BHText6">
- R
- </text>
- <text name="BHText7">
- G
- </text>
- <text name="BHText8">
- B
- </text>
- <text name="BHText9">
- I
- </text>
- <text name="HDText">
- 陰霾密度
- </text>
- <text name="DensMultText">
- 密度å€å¢ž
- </text>
- <text name="WLDistanceMultText">
- è·é›¢å€å¢ž
- </text>
- <text name="MaxAltText">
- 最大高度
- </text>
- </panel>
- <panel label="照明" name="Lighting">
- <text name="SLCText">
- æ—¥ï¼æœˆ é¡è‰²
- </text>
- <text name="BHText">
- R
- </text>
- <text name="BHText2">
- G
- </text>
- <text name="BHText3">
- B
- </text>
- <text name="BHText4">
- I
- </text>
- <text name="TODText">
- æ—¥ï¼æœˆ ä½ç½®
- </text>
- <text name="WLAmbientText">
- 環境
- </text>
- <text name="BHText5">
- R
- </text>
- <text name="BHText6">
- G
- </text>
- <text name="BHText7">
- B
- </text>
- <text name="BHText8">
- I
- </text>
- <text name="WLEastAngleText">
- æ±å‡è§’度
- </text>
- <text name="SunGlowText">
- 太陽光è¼
- </text>
- <slider label="焦點" name="WLGlowB"/>
- <slider label="尺寸" name="WLGlowR"/>
- <text name="SceneGammaText">
- 場景 Gamma 值
- </text>
- <text name="WLStarText">
- 星空é‡åº¦
- </text>
- </panel>
- <panel label="雲彩" name="Clouds">
- <text name="WLCloudColorText">
- 雲彩é¡è‰²
- </text>
- <text name="BHText">
- R
- </text>
- <text name="BHText2">
- G
- </text>
- <text name="BHText3">
- B
- </text>
- <text name="BHText4">
- I
- </text>
- <text name="WLCloudColorText2">
- 雲彩 XY 軸 / 密度
- </text>
- <text name="BHText5">
- X
- </text>
- <text name="BHText6">
- Y
- </text>
- <text name="BHText7">
- D
- </text>
- <text name="WLCloudCoverageText">
- 雲彩覆蓋
- </text>
- <text name="WLCloudScaleText">
- 雲彩è¦æ¨¡
- </text>
- <text name="WLCloudDetailText">
- 雲彩細節(XY 軸 / 密度)
- </text>
- <text name="BHText8">
- X
- </text>
- <text name="BHText9">
- Y
- </text>
- <text name="BHText10">
- D
- </text>
- <text name="WLCloudScrollXText">
- 雲彩 X 滾軸
- </text>
- <check_box label="鎖定" name="WLCloudLockX"/>
- <text name="WLCloudScrollYText">
- 雲彩 Y 滾軸
- </text>
- <check_box label="鎖定" name="WLCloudLockY"/>
- <check_box label="æ繪傳統雲彩" name="DrawClassicClouds"/>
- </panel>
- </tab_container>
-</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_window_size.xml b/indra/newview/skins/default/xui/zh/floater_window_size.xml
index 54b72afccc..3942f72d76 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_window_size.xml
+++ b/indra/newview/skins/default/xui/zh/floater_window_size.xml
@@ -7,10 +7,17 @@
設定視窗尺寸大å°ï¼š
</text>
<combo_box name="window_size_combo" tool_tip="寬度 x 高度">
- <combo_box.item label="1000 x 700 (é è¨­ï¼‰" name="item0"/>
- <combo_box.item label="1024 x 768" name="item1"/>
- <combo_box.item label="1280 x 720 (720p)" name="item2"/>
- <combo_box.item label="1920 x 1080 (1080p)" name="item3"/>
+ <combo_box.item label="1000 x 700 (é è¨­ï¼‰" name="item1"/>
+ <combo_box.item label="1024 x 768 (4:3 XGA)" name="item2"/>
+ <combo_box.item label="1280 x 720 (16:9 HDTV)" name="item3"/>
+ <combo_box.item label="1280 x 800 (5:8 WXGA)" name="item4"/>
+ <combo_box.item label="1280 x 1024 (5:4 SXGA)" name="item5"/>
+ <combo_box.item label="1440 x 900 (8:5 WSXGA)" name="item7"/>
+ <combo_box.item label="1600 x 900 (16:9 HD+)" name="item8"/>
+ <combo_box.item label="1600 x 1200 (4:3 UXGA)" name="item9"/>
+ <combo_box.item label="1680 x 1050 (8:5 WSXGA+)" name="item10"/>
+ <combo_box.item label="1920 x 1080 (16:9 HDTV)" name="item11"/>
+ <combo_box.item label="1920 x 1200 (8:5 WUXGA)" name="item12"/>
</combo_box>
<button label="設定" name="set_btn"/>
<button label="å–消" name="cancel_btn"/>
diff --git a/indra/newview/skins/default/xui/zh/floater_world_map.xml b/indra/newview/skins/default/xui/zh/floater_world_map.xml
index 6ac6fb76b7..4cd05ebaa0 100644..100755
--- a/indra/newview/skins/default/xui/zh/floater_world_map.xml
+++ b/indra/newview/skins/default/xui/zh/floater_world_map.xml
@@ -8,7 +8,7 @@
<panel name="layout_panel_2">
<button name="Show My Location" tool_tip="以我的化身所在ä½ç½®å±…中地圖"/>
<text name="me_label">
- 自己
+ 我自己
</text>
<text name="person_label">
人
@@ -23,14 +23,14 @@
土地æ‹è³£
</text>
<text name="by_owner_label">
- ä¾æ“有者
+ ä¾æ‰€æœ‰äºº
</text>
- <button name="Go Home" tool_tip="瞬間傳é€åˆ°æˆ‘的家ä½ç½®"/>
+ <button name="Go Home" tool_tip="瞬間返回我的家"/>
<text name="Home_label">
- 家
+ 我的家
</text>
<text name="events_label">
- 事件:
+ 活動:
</text>
<text name="pg_label">
一般普級
@@ -57,17 +57,17 @@
</combo_box>
<search_editor label="地å€ä¾å稱" name="location" tool_tip="輸入一個地å€çš„å稱"/>
<button label="尋找" name="DoSearch" tool_tip="æœå°‹åœ°å€"/>
- <button name="Clear" tool_tip="Clear tracking lines and reset map"/>
+ <button name="Clear" tool_tip="清楚追蹤線並é‡è¨­åœ°åœ–"/>
<text name="events_label">
ä½ç½®ï¼š
</text>
<button label="瞬間傳é€" name="Teleport" tool_tip="瞬間傳é€åˆ°æ‰€é¸çš„ä½ç½®"/>
- <button label="覆製 SLurl" name="copy_slurl" tool_tip="Copies current location as SLurl to be used on the web."/>
- <button label="Show Selection" name="Show Destination" tool_tip="Center map on selected location"/>
+ <button label="覆製 SLurl" name="copy_slurl" tool_tip="將目å‰ä½ç½®è¤‡è£½ç‚ºå¯åœ¨ç¶²è·¯ä¸Šä½¿ç”¨çš„ SLurl。"/>
+ <button label="顯示é¸æ“‡" name="Show Destination" tool_tip="將所é¸ä½ç½®ç§»åˆ°åœ°åœ–中央"/>
</panel>
<panel name="layout_panel_5">
<text name="zoom_label">
- Zoom
+ 縮放
</text>
</panel>
</floater>
diff --git a/indra/newview/skins/default/xui/zh/inspect_avatar.xml b/indra/newview/skins/default/xui/zh/inspect_avatar.xml
index 02e81983a6..ef10e5d2d0 100644..100755
--- a/indra/newview/skins/default/xui/zh/inspect_avatar.xml
+++ b/indra/newview/skins/default/xui/zh/inspect_avatar.xml
@@ -10,16 +10,16 @@
<string name="Details">
[SL_PROFILE]
</string>
- <text name="user_subtitle" value="11 Months, 3 days old"/>
+ <text name="user_subtitle" value="年齡 11 å€‹æœˆåˆ 3 天"/>
<text name="user_details">
- This is my second life description and I really think it is great. But for some reason my description is super extra long because I like to talk a whole lot
+ 這是我的「第二人生ã€è³‡è¨Šã€‚é€™åœ°æ–¹å¤ªæ£’äº†ï¼ åªä¸éŽï¼Œå¯æ˜¯å˜›â€¦â€¦æˆ‘的訊æ¯ç›¸ç•¶ç›¸ç•¶çš„冗長,因為……我滿愛七嘴八舌的啦。
</text>
- <slider name="volume_slider" tool_tip="Voice volume" value="0.5"/>
+ <slider name="volume_slider" tool_tip="音é‡" value="0.5"/>
<button label="加為朋å‹" name="add_friend_btn"/>
<button label="IM" name="im_btn"/>
<button label="檔案" name="view_profile_btn"/>
<panel name="moderator_panel">
- <button label="Disable Voice" name="disable_voice"/>
- <button label="Enable Voice" name="enable_voice"/>
+ <button label="åœç”¨èªžéŸ³" name="disable_voice"/>
+ <button label="啟用語音" name="enable_voice"/>
</panel>
</floater>
diff --git a/indra/newview/skins/default/xui/zh/inspect_group.xml b/indra/newview/skins/default/xui/zh/inspect_group.xml
index ac331be203..ca5ccc3349 100644..100755
--- a/indra/newview/skins/default/xui/zh/inspect_group.xml
+++ b/indra/newview/skins/default/xui/zh/inspect_group.xml
@@ -17,14 +17,14 @@
你是æˆå“¡
</string>
<text name="group_subtitle">
- 123 members
+ 123 ä½æˆå“¡
</text>
<text name="group_details">
- A group of folks charged with creating a room with a moose.
-Fear the moose! Fear it! And the mongoose too!
+ 這一群人責在建立有麋鹿的房間。
+麋鹿è¬æ­²ï¼è²“鼬è¬æ­²ï¼
</text>
<text name="group_cost">
- L$123 to join
+ 加入費用 L$123
</text>
<button label="加入" name="join_btn"/>
<button label="退出" name="leave_btn"/>
diff --git a/indra/newview/skins/default/xui/zh/inspect_object.xml b/indra/newview/skins/default/xui/zh/inspect_object.xml
index 58091b3aef..377b8b7c78 100644..100755
--- a/indra/newview/skins/default/xui/zh/inspect_object.xml
+++ b/indra/newview/skins/default/xui/zh/inspect_object.xml
@@ -5,40 +5,40 @@
-->
<floater name="inspect_object">
<string name="Creator">
- By [CREATOR]
+ 創作人 [CREATOR]
</string>
<string name="CreatorAndOwner">
- By [CREATOR]
-Owner [OWNER]
+ 創作人 [CREATOR]
+所有人 [OWNER]
</string>
<string name="Price">
L$[AMOUNT]
</string>
<string name="PriceFree">
- Free!
+ å…è²»ï¼
</string>
<string name="Touch">
- Touch
+ 觸碰
</string>
<string name="Sit">
- Sit
+ å下
</string>
<text name="object_creator">
- by secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about
-owner secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about
+ 創作人 secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about
+所有人 secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about
</text>
<text name="price_text">
L$30,000
</text>
- <icon name="secure_browsing" tool_tip="Secure Browsing"/>
+ <icon name="secure_browsing" tool_tip="安全ç€è¦½"/>
<text name="object_media_url">
http://www.superdupertest.com
</text>
<button label="購買" name="buy_btn"/>
<button label="支付" name="pay_btn"/>
<button label="å–得副本" name="take_free_copy_btn"/>
- <button label="Touch" name="touch_btn"/>
- <button label="Sit" name="sit_btn"/>
- <button label="Open" name="open_btn"/>
- <button label="More" name="more_info_btn"/>
+ <button label="觸碰" name="touch_btn"/>
+ <button label="å下" name="sit_btn"/>
+ <button label="打開" name="open_btn"/>
+ <button label="更多" name="more_info_btn"/>
</floater>
diff --git a/indra/newview/skins/default/xui/zh/inspect_remote_object.xml b/indra/newview/skins/default/xui/zh/inspect_remote_object.xml
index bed19d6d78..b8418fc8a1 100644..100755
--- a/indra/newview/skins/default/xui/zh/inspect_remote_object.xml
+++ b/indra/newview/skins/default/xui/zh/inspect_remote_object.xml
@@ -5,10 +5,10 @@
-->
<floater name="inspect_remote_object">
<text name="object_name">
- Test Object Name That Is Really Long OMG so long I can&apos;t believe how long the name of this object is, I mean really.
+ 測試很長很長ã€é•·åˆ°ä¸å¯æ€è­°çš„ã€è½è½é•·çš„ã€é•·å¾—ä¸å¾—了的ã€å¾ˆé•·å¾ˆé•·å¾ˆé•·ã€é•·åˆ°æˆ‘快發瘋ã€é•·ä¹‹åˆé•·çš„物件å稱。
</text>
<text name="object_owner_label">
- æ“有者:
+ 所有人:
</text>
<text name="object_owner">
Longavatarname Johnsonlongstonnammer
diff --git a/indra/newview/skins/default/xui/zh/menu_add_wearable_gear.xml b/indra/newview/skins/default/xui/zh/menu_add_wearable_gear.xml
index 3c8c3e4a31..3c8c3e4a31 100644..100755
--- a/indra/newview/skins/default/xui/zh/menu_add_wearable_gear.xml
+++ b/indra/newview/skins/default/xui/zh/menu_add_wearable_gear.xml
diff --git a/indra/newview/skins/default/xui/zh/menu_attachment_other.xml b/indra/newview/skins/default/xui/zh/menu_attachment_other.xml
index 885c4b9add..41b3409627 100644..100755
--- a/indra/newview/skins/default/xui/zh/menu_attachment_other.xml
+++ b/indra/newview/skins/default/xui/zh/menu_attachment_other.xml
@@ -11,7 +11,9 @@
<menu_item_call label="å‡çµ" name="Freeze..."/>
<menu_item_call label="踢出" name="Eject..."/>
<menu_item_call label="æ質除錯" name="Debug..."/>
+ <menu_item_call label="å‚¾å° XML" name="Dump XML"/>
<menu_item_call label="放大" name="Zoom In"/>
<menu_item_call label="支付" name="Pay..."/>
<menu_item_call label="物件檔案" name="Object Inspect"/>
+ <menu_item_call label="å°éŽ–ç²’å­æ‰€æœ‰äºº" name="Mute Particle"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/zh/menu_attachment_self.xml b/indra/newview/skins/default/xui/zh/menu_attachment_self.xml
index 1911a1aeff..eb1bad0ca2 100644..100755
--- a/indra/newview/skins/default/xui/zh/menu_attachment_self.xml
+++ b/indra/newview/skins/default/xui/zh/menu_attachment_self.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Attachment Pie">
- <menu_item_call label="Touch" name="Attachment Object Touch"/>
+ <menu_item_call label="觸碰" name="Attachment Object Touch"/>
<menu_item_call label="編輯" name="Edit..."/>
<menu_item_call label="å¸ä¸‹" name="Detach"/>
<menu_item_call label="å下" name="Sit Down Here"/>
@@ -10,7 +10,9 @@
<menu_item_call label="編輯我的體形" name="Edit My Shape"/>
<menu_item_call label="我的朋å‹" name="Friends..."/>
<menu_item_call label="我的群組" name="Groups..."/>
- <menu_item_call label="我的檔案" name="Profile..."/>
+ <menu_item_call label="我的個人檔案" name="Profile..."/>
<menu_item_call label="æ質除錯" name="Debug..."/>
+ <menu_item_call label="å‚¾å° XML" name="Dump XML"/>
<menu_item_call label="丟棄" name="Drop"/>
+ <menu_item_call label="å°éŽ–ç²’å­æ‰€æœ‰äºº" name="Mute Particle"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/zh/menu_avatar_icon.xml b/indra/newview/skins/default/xui/zh/menu_avatar_icon.xml
index ef0986a13b..ef0986a13b 100644..100755
--- a/indra/newview/skins/default/xui/zh/menu_avatar_icon.xml
+++ b/indra/newview/skins/default/xui/zh/menu_avatar_icon.xml
diff --git a/indra/newview/skins/default/xui/zh/menu_avatar_other.xml b/indra/newview/skins/default/xui/zh/menu_avatar_other.xml
index 260571eb54..dc035bafa0 100644..100755
--- a/indra/newview/skins/default/xui/zh/menu_avatar_other.xml
+++ b/indra/newview/skins/default/xui/zh/menu_avatar_other.xml
@@ -6,11 +6,13 @@
<menu_item_call label="IM" name="Send IM..."/>
<menu_item_call label="通話" name="Call"/>
<menu_item_call label="邀請加入群組" name="Invite..."/>
- <menu_item_call label="Block" name="Avatar Mute"/>
+ <menu_item_call label="å°éŽ–" name="Avatar Mute"/>
<menu_item_call label="回報" name="abuse"/>
<menu_item_call label="å‡çµ" name="Freeze..."/>
<menu_item_call label="踢出" name="Eject..."/>
<menu_item_call label="æ質除錯" name="Debug..."/>
- <menu_item_call label="Zoom In" name="Zoom In"/>
+ <menu_item_call label="å‚¾å° XML" name="Dump XML"/>
+ <menu_item_call label="放大" name="Zoom In"/>
<menu_item_call label="支付" name="Pay..."/>
+ <menu_item_call label="å°éŽ–ç²’å­æ‰€æœ‰äºº" name="Mute Particle"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/zh/menu_avatar_self.xml b/indra/newview/skins/default/xui/zh/menu_avatar_self.xml
index d516e3ab58..68d0600141 100644..100755
--- a/indra/newview/skins/default/xui/zh/menu_avatar_self.xml
+++ b/indra/newview/skins/default/xui/zh/menu_avatar_self.xml
@@ -14,19 +14,21 @@
<menu_item_call label="內衣" name="Self Undershirt"/>
<menu_item_call label="內褲" name="Self Underpants"/>
<menu_item_call label="刺é’" name="Self Tattoo"/>
- <menu_item_call label="Physics" name="Self Physics"/>
+ <menu_item_call label="身體物ç†" name="Self Physics"/>
<menu_item_call label="åŠé€æ˜Ž" name="Self Alpha"/>
<menu_item_call label="全部衣æœ" name="All Clothes"/>
</context_menu>
- <context_menu label="HUD" name="Object Detach HUD"/>
+ <context_menu label="擡頭顯示" name="Object Detach HUD"/>
<context_menu label="å¸ä¸‹" name="Object Detach"/>
<menu_item_call label="全部å¸ä¸‹" name="Detach All"/>
</context_menu>
<menu_item_call label="我的外觀" name="Chenge Outfit"/>
- <menu_item_call label="編輯我è£æ‰®" name="Edit Outfit"/>
+ <menu_item_call label="編輯我的è£æ‰®" name="Edit Outfit"/>
<menu_item_call label="編輯我的體形" name="Edit My Shape"/>
<menu_item_call label="我的朋å‹" name="Friends..."/>
<menu_item_call label="我的群組" name="Groups..."/>
- <menu_item_call label="我的檔案" name="Profile..."/>
+ <menu_item_call label="我的個人檔案" name="Profile..."/>
<menu_item_call label="æ質除錯" name="Debug..."/>
+ <menu_item_call label="å‚¾å° XML" name="Dump XML"/>
+ <menu_item_call label="å°éŽ–ç²’å­æ‰€æœ‰äºº" name="Mute Particle"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/zh/menu_bottomtray.xml b/indra/newview/skins/default/xui/zh/menu_bottomtray.xml
deleted file mode 100644
index a00aa7cd35..0000000000
--- a/indra/newview/skins/default/xui/zh/menu_bottomtray.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<menu name="hide_camera_move_controls_menu">
- <menu_item_check label="講話按鈕" name="EnableVoiceChat"/>
- <menu_item_check label="姿勢按鈕" name="ShowGestureButton"/>
- <menu_item_check label="移動按鈕" name="ShowMoveButton"/>
- <menu_item_check label="視角按鈕" name="ShowCameraButton"/>
- <menu_item_check label="快照按鈕" name="ShowSnapshotButton"/>
- <menu_item_check label="建造按鈕" name="ShowBuildButton"/>
- <menu_item_check label="æœå°‹æŒ‰éˆ•" name="ShowSearchButton"/>
- <menu_item_check label="地圖按鈕" name="ShowWorldMapButton"/>
- <menu_item_check label="迷你地圖按鈕" name="ShowMiniMapButton"/>
- <menu_item_call label="剪下" name="NearbyChatBar_Cut"/>
- <menu_item_call label="覆製" name="NearbyChatBar_Copy"/>
- <menu_item_call label="貼上" name="NearbyChatBar_Paste"/>
- <menu_item_call label="刪除" name="NearbyChatBar_Delete"/>
- <menu_item_call label="å…¨é¸" name="NearbyChatBar_Select_All"/>
-</menu>
diff --git a/indra/newview/skins/default/xui/zh/menu_cof_attachment.xml b/indra/newview/skins/default/xui/zh/menu_cof_attachment.xml
index 876fef16df..876fef16df 100644..100755
--- a/indra/newview/skins/default/xui/zh/menu_cof_attachment.xml
+++ b/indra/newview/skins/default/xui/zh/menu_cof_attachment.xml
diff --git a/indra/newview/skins/default/xui/zh/menu_cof_body_part.xml b/indra/newview/skins/default/xui/zh/menu_cof_body_part.xml
index d06207b19d..d06207b19d 100644..100755
--- a/indra/newview/skins/default/xui/zh/menu_cof_body_part.xml
+++ b/indra/newview/skins/default/xui/zh/menu_cof_body_part.xml
diff --git a/indra/newview/skins/default/xui/zh/menu_cof_clothing.xml b/indra/newview/skins/default/xui/zh/menu_cof_clothing.xml
index 300ff47b12..300ff47b12 100644..100755
--- a/indra/newview/skins/default/xui/zh/menu_cof_clothing.xml
+++ b/indra/newview/skins/default/xui/zh/menu_cof_clothing.xml
diff --git a/indra/newview/skins/default/xui/zh/menu_cof_gear.xml b/indra/newview/skins/default/xui/zh/menu_cof_gear.xml
index cd069f9601..eb7093a23c 100644..100755
--- a/indra/newview/skins/default/xui/zh/menu_cof_gear.xml
+++ b/indra/newview/skins/default/xui/zh/menu_cof_gear.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<toggleable_menu name="Gear COF">
<menu label="æ–°è¡£æœ" name="COF.Gear.New_Clothes"/>
- <menu label="新身體部ä½" name="COF.Geear.New_Body_Parts"/>
+ <menu label="新身體部ä½" name="COF.Gear.New_Body_Parts"/>
</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/zh/menu_conversation.xml b/indra/newview/skins/default/xui/zh/menu_conversation.xml
new file mode 100644
index 0000000000..adfeefc337
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/menu_conversation.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_conversation_participant">
+ <menu_item_call label="關閉交談" name="close_conversation"/>
+ <menu_item_call label="開啟語音交談" name="open_voice_conversation"/>
+ <menu_item_call label="切斷語音交談" name="disconnect_from_voice"/>
+ <menu_item_call label="關閉所é¸" name="close_selected_conversations"/>
+ <menu_item_call label="察看檔案" name="view_profile"/>
+ <menu_item_call label="IM" name="im"/>
+ <menu_item_call label="發出瞬間傳é€é‚€è«‹" name="offer_teleport"/>
+ <menu_item_call label="語音通話" name="voice_call"/>
+ <menu_item_call label="èŠå¤©æ­·å²â€¦â€¦" name="chat_history"/>
+ <menu_item_call label="新增朋å‹" name="add_friend"/>
+ <menu_item_call label="移除朋å‹" name="remove_friend"/>
+ <menu_item_call label="移除朋å‹" name="remove_friends"/>
+ <menu_item_call label="邀請加入群組……" name="invite_to_group"/>
+ <menu_item_call label="放大" name="zoom_in"/>
+ <menu_item_call label="地圖" name="map"/>
+ <menu_item_call label="分享" name="share"/>
+ <menu_item_call label="支付" name="pay"/>
+ <menu_item_check label="ç¦æ­¢èªžéŸ³" name="block_unblock"/>
+ <menu_item_check label="ç¦æ­¢æ–‡å­—" name="MuteText"/>
+ <menu_item_call label="群組檔案" name="group_profile"/>
+ <menu_item_call label="啟用群組" name="activate_group"/>
+ <menu_item_call label="離開群組" name="leave_group"/>
+ <context_menu label="主æŒäººé¸é …" name="Moderator Options">
+ <menu_item_check label="å…許文字èŠå¤©" name="AllowTextChat"/>
+ <menu_item_call label="將此人消音" name="ModerateVoiceMuteSelected"/>
+ <menu_item_call label="å–消å°æ­¤äººçš„消音" name="ModerateVoiceUnMuteSelected"/>
+ <menu_item_call label="所有人消音" name="ModerateVoiceMute"/>
+ <menu_item_call label="å–消所有人的消音" name="ModerateVoiceUnmute"/>
+ </context_menu>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/zh/menu_conversation_log_gear.xml b/indra/newview/skins/default/xui/zh/menu_conversation_log_gear.xml
new file mode 100644
index 0000000000..49e91417e8
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/menu_conversation_log_gear.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="Conversation Context Menu">
+ <menu_item_call label="IM…" name="IM"/>
+ <menu_item_call label="語音通話…" name="Call"/>
+ <menu_item_call label="é–‹å•ŸèŠå¤©æ­·å²â€¦" name="Chat history"/>
+ <menu_item_call label="察看檔案" name="View Profile"/>
+ <menu_item_call label="發給瞬間傳é€è«‹æ±‚" name="teleport"/>
+ <menu_item_call label="加為朋å‹" name="add_friend"/>
+ <menu_item_call label="移除朋å‹" name="remove_friend"/>
+ <menu_item_call label="邀請加入群組……" name="Invite"/>
+ <menu_item_call label="地圖" name="Map"/>
+ <menu_item_call label="分享" name="Share"/>
+ <menu_item_call label="支付" name="Pay"/>
+ <menu_item_check label="å°éŽ–/ä¸å†å°éŽ–" name="Block/Unblock"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/zh/menu_conversation_log_view.xml b/indra/newview/skins/default/xui/zh/menu_conversation_log_view.xml
new file mode 100644
index 0000000000..3fa99a5cd7
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/menu_conversation_log_view.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_conversation_view">
+ <menu_item_check label="ä¾å稱排åº" name="sort_by_name"/>
+ <menu_item_check label="ä¾æ—¥æœŸæŽ’åº" name="sort_by_date"/>
+ <menu_item_check label="將朋å‹åˆ—在頂端" name="sort_by_friends"/>
+ <menu_item_call label="檢視附近èŠå¤©æ­·å²â€¦â€¦" name="view_nearby_chat_history"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/zh/menu_edit.xml b/indra/newview/skins/default/xui/zh/menu_edit.xml
index d6eb87a6b0..bda640e5f3 100644..100755
--- a/indra/newview/skins/default/xui/zh/menu_edit.xml
+++ b/indra/newview/skins/default/xui/zh/menu_edit.xml
@@ -3,7 +3,7 @@
<menu_item_call label="復原" name="Undo"/>
<menu_item_call label="é‡åš" name="Redo"/>
<menu_item_call label="剪下" name="Cut"/>
- <menu_item_call label="覆製" name="Copy"/>
+ <menu_item_call label="æšåº¨" name="Copy"/>
<menu_item_call label="貼上" name="Paste"/>
<menu_item_call label="刪除" name="Delete"/>
<menu_item_call label="覆製貼上" name="Duplicate"/>
diff --git a/indra/newview/skins/default/xui/zh/menu_favorites.xml b/indra/newview/skins/default/xui/zh/menu_favorites.xml
index c60bebd3dc..a01412ce1c 100644..100755
--- a/indra/newview/skins/default/xui/zh/menu_favorites.xml
+++ b/indra/newview/skins/default/xui/zh/menu_favorites.xml
@@ -4,7 +4,7 @@
<menu_item_call label="察看 / 編輯 地標" name="Landmark Open"/>
<menu_item_call label="覆製 SLurl" name="Copy slurl"/>
<menu_item_call label="顯示在地圖上" name="Show On Map"/>
- <menu_item_call label="覆製" name="Landmark Copy"/>
+ <menu_item_call label="æšåº¨" name="Landmark Copy"/>
<menu_item_call label="貼上" name="Landmark Paste"/>
<menu_item_call label="刪除" name="Delete"/>
</menu>
diff --git a/indra/newview/skins/default/xui/zh/menu_gesture_gear.xml b/indra/newview/skins/default/xui/zh/menu_gesture_gear.xml
index a331c47a6e..5a38197e4c 100644..100755
--- a/indra/newview/skins/default/xui/zh/menu_gesture_gear.xml
+++ b/indra/newview/skins/default/xui/zh/menu_gesture_gear.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<toggleable_menu name="menu_gesture_gear">
<menu_item_call label="由我的最愛中 添加/移除" name="activate"/>
- <menu_item_call label="覆製" name="copy_gesture"/>
+ <menu_item_call label="æšåº¨" name="copy_gesture"/>
<menu_item_call label="貼上" name="paste"/>
<menu_item_call label="覆製 UUID" name="copy_uuid"/>
<menu_item_call label="儲存到目å‰è£æ‰®" name="save_to_outfit"/>
diff --git a/indra/newview/skins/default/xui/zh/menu_group_plus.xml b/indra/newview/skins/default/xui/zh/menu_group_plus.xml
index d4a5a69104..d4a5a69104 100644..100755
--- a/indra/newview/skins/default/xui/zh/menu_group_plus.xml
+++ b/indra/newview/skins/default/xui/zh/menu_group_plus.xml
diff --git a/indra/newview/skins/default/xui/zh/menu_hide_navbar.xml b/indra/newview/skins/default/xui/zh/menu_hide_navbar.xml
index dbb8ececaa..3f6820cb32 100644..100755
--- a/indra/newview/skins/default/xui/zh/menu_hide_navbar.xml
+++ b/indra/newview/skins/default/xui/zh/menu_hide_navbar.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<menu name="hide_navbar_menu">
- <menu_item_check label="顯示導覽列" name="ShowNavbarNavigationPanel"/>
+ <menu_item_check label="顯示導覽列和我的最愛" name="ShowNavbarNavigationPanel"/>
<menu_item_check label="顯示最愛列" name="ShowNavbarFavoritesPanel"/>
<menu_item_check label="顯示迷你ä½ç½®åˆ—" name="ShowMiniLocationPanel"/>
</menu>
diff --git a/indra/newview/skins/default/xui/zh/menu_im_conversation.xml b/indra/newview/skins/default/xui/zh/menu_im_conversation.xml
new file mode 100644
index 0000000000..815b0b594c
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/menu_im_conversation.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="Conversation Gear Menu">
+ <menu_item_call label="察看檔案" name="View Profile"/>
+ <menu_item_call label="加為朋å‹" name="Add Friend"/>
+ <menu_item_call label="移除朋å‹" name="remove_friend"/>
+ <menu_item_call label="發出瞬間傳é€é‚€è«‹" name="offer_teleport"/>
+ <menu_item_call label="邀請加入群組……" name="invite_to_group"/>
+ <menu_item_call label="èŠå¤©æ­·å²â€¦â€¦" name="chat_history"/>
+ <menu_item_call label="放大" name="zoom_in"/>
+ <menu_item_call label="地圖" name="map"/>
+ <menu_item_call label="分享" name="Share"/>
+ <menu_item_call label="支付" name="Pay"/>
+ <menu_item_check label="ç¦æ­¢èªžéŸ³" name="Block/Unblock"/>
+ <menu_item_check label="ç¦æ­¢æ–‡å­—" name="MuteText"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/zh/menu_im_session_showmodes.xml b/indra/newview/skins/default/xui/zh/menu_im_session_showmodes.xml
new file mode 100644
index 0000000000..a7006e524a
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/menu_im_session_showmodes.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_modes">
+ <menu_item_check label="精簡視野" name="compact_view"/>
+ <menu_item_check label="全展視野" name="expanded_view"/>
+ <menu_item_check label="顯示時間" name="IMShowTime"/>
+ <menu_item_check label="一å°ä¸€äº¤è«‡æ™‚顯示åå­—" name="IMShowNamesForP2PConv"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/zh/menu_im_well_button.xml b/indra/newview/skins/default/xui/zh/menu_im_well_button.xml
deleted file mode 100644
index 4b9b4b2758..0000000000
--- a/indra/newview/skins/default/xui/zh/menu_im_well_button.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<context_menu name="IM Well Button Context Menu">
- <menu_item_call label="全部關閉" name="Close All"/>
-</context_menu>
diff --git a/indra/newview/skins/default/xui/zh/menu_imchiclet_adhoc.xml b/indra/newview/skins/default/xui/zh/menu_imchiclet_adhoc.xml
index 85417d554e..85417d554e 100644..100755
--- a/indra/newview/skins/default/xui/zh/menu_imchiclet_adhoc.xml
+++ b/indra/newview/skins/default/xui/zh/menu_imchiclet_adhoc.xml
diff --git a/indra/newview/skins/default/xui/zh/menu_imchiclet_group.xml b/indra/newview/skins/default/xui/zh/menu_imchiclet_group.xml
index 4664fcb027..4664fcb027 100644..100755
--- a/indra/newview/skins/default/xui/zh/menu_imchiclet_group.xml
+++ b/indra/newview/skins/default/xui/zh/menu_imchiclet_group.xml
diff --git a/indra/newview/skins/default/xui/zh/menu_imchiclet_p2p.xml b/indra/newview/skins/default/xui/zh/menu_imchiclet_p2p.xml
index 636bdaae09..636bdaae09 100644..100755
--- a/indra/newview/skins/default/xui/zh/menu_imchiclet_p2p.xml
+++ b/indra/newview/skins/default/xui/zh/menu_imchiclet_p2p.xml
diff --git a/indra/newview/skins/default/xui/zh/menu_inspect_avatar_gear.xml b/indra/newview/skins/default/xui/zh/menu_inspect_avatar_gear.xml
index 7385764e4c..f4e886ff67 100644..100755
--- a/indra/newview/skins/default/xui/zh/menu_inspect_avatar_gear.xml
+++ b/indra/newview/skins/default/xui/zh/menu_inspect_avatar_gear.xml
@@ -6,16 +6,16 @@
<menu_item_call label="通話" name="call"/>
<menu_item_call label="瞬間傳é€" name="teleport"/>
<menu_item_call label="邀請加入群組" name="invite_to_group"/>
- <menu_item_call label="Block" name="block"/>
- <menu_item_call label="Unblock" name="unblock"/>
+ <menu_item_call label="å°éŽ–" name="block"/>
+ <menu_item_call label="解除å°éŽ–" name="unblock"/>
<menu_item_call label="回報" name="report"/>
<menu_item_call label="å‡çµ" name="freeze"/>
<menu_item_call label="踢出" name="eject"/>
<menu_item_call label="踢出" name="kick"/>
- <menu_item_call label="CSR" name="csr"/>
+ <menu_item_call label="客æœ" name="csr"/>
<menu_item_call label="æ質除錯" name="debug"/>
<menu_item_call label="在地圖上尋找" name="find_on_map"/>
- <menu_item_call label="Zoom In" name="zoom_in"/>
+ <menu_item_call label="放大" name="zoom_in"/>
<menu_item_call label="支付" name="pay"/>
<menu_item_call label="分享" name="share"/>
</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/zh/menu_inspect_object_gear.xml b/indra/newview/skins/default/xui/zh/menu_inspect_object_gear.xml
index 94ab82b8a9..abff0f64ac 100644..100755
--- a/indra/newview/skins/default/xui/zh/menu_inspect_object_gear.xml
+++ b/indra/newview/skins/default/xui/zh/menu_inspect_object_gear.xml
@@ -2,17 +2,18 @@
<toggleable_menu name="Gear Menu">
<menu_item_call label="觸碰" name="touch"/>
<menu_item_call label="å下" name="sit"/>
- <menu_item_call label="Pay" name="pay"/>
+ <menu_item_call label="支付" name="pay"/>
<menu_item_call label="購買" name="buy"/>
<menu_item_call label="å–å¾—" name="take"/>
<menu_item_call label="å–得副本" name="take_copy"/>
- <menu_item_call label="é–‹å•Ÿ" name="open"/>
+ <menu_item_call label="打開" name="open"/>
<menu_item_call label="編輯" name="edit"/>
<menu_item_call label="穿上" name="wear"/>
<menu_item_call label="添加" name="add"/>
<menu_item_call label="回報" name="report"/>
- <menu_item_call label="Block" name="block"/>
- <menu_item_call label="Zoom In" name="zoom_in"/>
+ <menu_item_call label="å°éŽ–" name="block"/>
+ <menu_item_call label="解除å°éŽ–" name="unblock"/>
+ <menu_item_call label="放大" name="zoom_in"/>
<menu_item_call label="移除" name="remove"/>
<menu_item_call label="更多資訊" name="more_info"/>
</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/zh/menu_inspect_self_gear.xml b/indra/newview/skins/default/xui/zh/menu_inspect_self_gear.xml
index 1c75705743..c48ee0c9be 100644..100755
--- a/indra/newview/skins/default/xui/zh/menu_inspect_self_gear.xml
+++ b/indra/newview/skins/default/xui/zh/menu_inspect_self_gear.xml
@@ -17,7 +17,7 @@
<menu_item_call label="åŠé€æ˜Ž" name="Self Alpha"/>
<menu_item_call label="全部衣æœ" name="All Clothes"/>
</context_menu>
- <context_menu label="HUD" name="Object Detach HUD"/>
+ <context_menu label="擡頭顯示" name="Object Detach HUD"/>
<context_menu label="å¸ä¸‹" name="Object Detach"/>
<menu_item_call label="全部å¸ä¸‹" name="Detach All"/>
</context_menu>
@@ -26,6 +26,6 @@
<menu_item_call label="編輯我的體形" name="Edit My Shape"/>
<menu_item_call label="我的朋å‹" name="Friends..."/>
<menu_item_call label="我的群組" name="Groups..."/>
- <menu_item_call label="我的檔案" name="Profile..."/>
+ <menu_item_call label="我的個人檔案" name="Profile..."/>
<menu_item_call label="æ質除錯" name="Debug..."/>
</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/zh/menu_inv_offer_chiclet.xml b/indra/newview/skins/default/xui/zh/menu_inv_offer_chiclet.xml
index 577e5988f8..577e5988f8 100644..100755
--- a/indra/newview/skins/default/xui/zh/menu_inv_offer_chiclet.xml
+++ b/indra/newview/skins/default/xui/zh/menu_inv_offer_chiclet.xml
diff --git a/indra/newview/skins/default/xui/zh/menu_inventory.xml b/indra/newview/skins/default/xui/zh/menu_inventory.xml
index 87d769af0d..7f745ffaa7 100644..100755
--- a/indra/newview/skins/default/xui/zh/menu_inventory.xml
+++ b/indra/newview/skins/default/xui/zh/menu_inventory.xml
@@ -2,13 +2,13 @@
<menu name="Popup">
<menu_item_call label="分享" name="Share"/>
<menu_item_call label="購買" name="Task Buy"/>
- <menu_item_call label="é–‹å•Ÿ" name="Task Open"/>
+ <menu_item_call label="打開" name="Task Open"/>
<menu_item_call label="播放" name="Task Play"/>
<menu_item_call label="屬性" name="Task Properties"/>
<menu_item_call label="æ›´å" name="Task Rename"/>
<menu_item_call label="刪除" name="Task Remove"/>
<menu_item_call label="清空垃圾筒" name="Empty Trash"/>
- <menu_item_call label="清空 Lost And Found" name="Empty Lost And Found"/>
+ <menu_item_call label="清空所有失物" name="Empty Lost And Found"/>
<menu_item_call label="新資料夾" name="New Folder"/>
<menu_item_call label="新腳本" name="New Script"/>
<menu_item_call label="新記事å¡" name="New Note"/>
@@ -18,7 +18,7 @@
<menu_item_call label="新褲å­" name="New Pants"/>
<menu_item_call label="æ–°éž‹å­" name="New Shoes"/>
<menu_item_call label="新襪å­" name="New Socks"/>
- <menu_item_call label="新夾克" name="New Jacket"/>
+ <menu_item_call label="新外套" name="New Jacket"/>
<menu_item_call label="新裙å­" name="New Skirt"/>
<menu_item_call label="新手套" name="New Gloves"/>
<menu_item_call label="新內衣" name="New Undershirt"/>
@@ -46,42 +46,46 @@
<menu_item_call label="內衣" name="Undershirt"/>
</menu>
<menu_item_call label="瞬間傳é€" name="Landmark Open"/>
- <menu_item_call label="é–‹å•Ÿ" name="Animation Open"/>
- <menu_item_call label="é–‹å•Ÿ" name="Sound Open"/>
+ <menu_item_call label="打開" name="Animation Open"/>
+ <menu_item_call label="打開" name="Sound Open"/>
<menu_item_call label="å–代目å‰çš„è£æ‰®" name="Replace Outfit"/>
<menu_item_call label="添加到目å‰è£æ‰®" name="Add To Outfit"/>
<menu_item_call label="由目å‰çš„è£æ‰®ç§»é™¤" name="Remove From Outfit"/>
<menu_item_call label="尋找原件" name="Find Original"/>
<menu_item_call label="清空物å“" name="Purge Item"/>
- <menu_item_call label="æ¢å¾©ç‰©å“" name="Restore Item"/>
- <menu_item_call label="é–‹å•Ÿ" name="Open"/>
+ <menu_item_call label="還原物å“" name="Restore Item"/>
+ <menu_item_call label="打開" name="Open"/>
<menu_item_call label="開啟原件" name="Open Original"/>
<menu_item_call label="屬性" name="Properties"/>
<menu_item_call label="æ›´å" name="Rename"/>
<menu_item_call label="覆製資產 UUID" name="Copy Asset UUID"/>
- <menu_item_call label="覆製" name="Copy"/>
+ <menu_item_call label="剪下" name="Cut"/>
+ <menu_item_call label="æšåº¨" name="Copy"/>
<menu_item_call label="貼上" name="Paste"/>
- <menu_item_call label="Paste As Link" name="Paste As Link"/>
+ <menu_item_call label="以連çµæ ¼å¼è²¼ä¸Š" name="Paste As Link"/>
<menu_item_call label="刪除" name="Remove Link"/>
<menu_item_call label="刪除" name="Delete"/>
<menu_item_call label="刪除系統資料夾" name="Delete System Folder"/>
- <menu_item_call label="Start Conference Chat" name="Conference Chat Folder"/>
+ <menu_item_call label="發起多方通話" name="Conference Chat Folder"/>
<menu_item_call label="播放" name="Sound Play"/>
+ <menu_item_call label="覆製 SLurl" name="url_copy"/>
<menu_item_call label="添加地標" name="About Landmark"/>
- <menu_item_call label="播放於虛擬世界" name="Animation Play"/>
- <menu_item_call label="播放於本地" name="Animation Audition"/>
+ <menu_item_call label="在虛擬世界播放" name="Animation Play"/>
+ <menu_item_call label="在本地播放" name="Animation Audition"/>
<menu_item_call label="é€å‡ºå³æ™‚訊æ¯" name="Send Instant Message"/>
- <menu_item_call label="發給瞬間傳é€è«‹æ±‚..." name="Offer Teleport..."/>
- <menu_item_call label="開始會議交談" name="Conference Chat"/>
- <menu_item_call label="Activate" name="Activate"/>
- <menu_item_call label="Deactivate" name="Deactivate"/>
- <menu_item_call label="å¦å­˜" name="Save As"/>
- <menu_item_call label="Detach From Yourself" name="Detach From Yourself"/>
- <menu_item_call label="Wear" name="Wearable And Object Wear"/>
- <menu label="Attach To" name="Attach To"/>
- <menu label="Attach To HUD" name="Attach To HUD"/>
+ <menu_item_call label="發出瞬間傳é€é‚€è«‹..." name="Offer Teleport..."/>
+ <menu_item_call label="發起多方通話" name="Conference Chat"/>
+ <menu_item_call label="å•Ÿå‹•" name="Activate"/>
+ <menu_item_call label="åœç”¨" name="Deactivate"/>
+ <menu_item_call label="å¦å­˜ç‚º" name="Save As"/>
+ <menu_item_call label="從你身上移除" name="Detach From Yourself"/>
+ <menu_item_call label="穿上" name="Wearable And Object Wear"/>
+ <menu label="附著到..." name="Attach To"/>
+ <menu label="附著到擡頭顯示" name="Attach To HUD"/>
<menu_item_call label="編輯" name="Wearable Edit"/>
<menu_item_call label="添加" name="Wearable Add"/>
<menu_item_call label="脫下" name="Take Off"/>
+ <menu_item_call label="複製到商家發件匣" name="Merchant Copy"/>
+ <menu_item_call label="é€å¾€ç¬¬äºŒäººç”Ÿè³¼ç‰©å¸‚集" name="Marketplace Send"/>
<menu_item_call label="-- ç„¡é¸é … --" name="--no options--"/>
</menu>
diff --git a/indra/newview/skins/default/xui/zh/menu_inventory_add.xml b/indra/newview/skins/default/xui/zh/menu_inventory_add.xml
index a0fc060e27..30bf5a7e75 100644..100755
--- a/indra/newview/skins/default/xui/zh/menu_inventory_add.xml
+++ b/indra/newview/skins/default/xui/zh/menu_inventory_add.xml
@@ -4,7 +4,9 @@
<menu_item_call label="圖åƒï¼ˆL$[COST])..." name="Upload Image"/>
<menu_item_call label="è²éŸ³ï¼ˆL$[COST])..." name="Upload Sound"/>
<menu_item_call label="動作(L$[COST])..." name="Upload Animation"/>
- <menu_item_call label="大批(L$[COST] æ¯æª”案)..." name="Bulk Upload"/>
+ <menu_item_call label="模型…" name="Upload Model"/>
+ <menu_item_call label="模型精éˆâ€¦" name="Upload Model Wizard"/>
+ <menu_item_call label="批é‡ï¼ˆæ¯æª”案 L$[COST] )..." name="Bulk Upload"/>
<menu_item_call label="設定é è¨­ä¸Šå‚³æ¬Šé™" name="perm prefs"/>
</menu>
<menu_item_call label="新資料夾" name="New Folder"/>
@@ -16,7 +18,7 @@
<menu_item_call label="新褲å­" name="New Pants"/>
<menu_item_call label="æ–°éž‹å­" name="New Shoes"/>
<menu_item_call label="新襪å­" name="New Socks"/>
- <menu_item_call label="新夾克" name="New Jacket"/>
+ <menu_item_call label="新外套" name="New Jacket"/>
<menu_item_call label="新裙å­" name="New Skirt"/>
<menu_item_call label="新手套" name="New Gloves"/>
<menu_item_call label="新內衣" name="New Undershirt"/>
diff --git a/indra/newview/skins/default/xui/zh/menu_inventory_gear_default.xml b/indra/newview/skins/default/xui/zh/menu_inventory_gear_default.xml
index 8ad0e7324f..8ad0e7324f 100644..100755
--- a/indra/newview/skins/default/xui/zh/menu_inventory_gear_default.xml
+++ b/indra/newview/skins/default/xui/zh/menu_inventory_gear_default.xml
diff --git a/indra/newview/skins/default/xui/zh/menu_land.xml b/indra/newview/skins/default/xui/zh/menu_land.xml
index 84941d138c..3ad9c0ab31 100644..100755
--- a/indra/newview/skins/default/xui/zh/menu_land.xml
+++ b/indra/newview/skins/default/xui/zh/menu_land.xml
@@ -1,9 +1,10 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Land Pie">
- <menu_item_call label="關於土地" name="Place Information..."/>
- <menu_item_call label="å在此處" name="Sit Here"/>
+ <menu_item_call label="土地資料" name="Place Information..."/>
+ <menu_item_call label="å在這裡" name="Sit Here"/>
<menu_item_call label="購買這塊土地" name="Land Buy"/>
<menu_item_call label="購買通行權" name="Land Buy Pass"/>
<menu_item_call label="建造" name="Create"/>
<menu_item_call label="編輯地形" name="Edit Terrain"/>
+ <menu_item_call label="å°éŽ–ç²’å­æ‰€æœ‰äºº" name="Mute Particle"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/zh/menu_landmark.xml b/indra/newview/skins/default/xui/zh/menu_landmark.xml
index 7372b223cf..7372b223cf 100644..100755
--- a/indra/newview/skins/default/xui/zh/menu_landmark.xml
+++ b/indra/newview/skins/default/xui/zh/menu_landmark.xml
diff --git a/indra/newview/skins/default/xui/zh/menu_login.xml b/indra/newview/skins/default/xui/zh/menu_login.xml
index d6bf34c66e..1d3d771efb 100644..100755
--- a/indra/newview/skins/default/xui/zh/menu_login.xml
+++ b/indra/newview/skins/default/xui/zh/menu_login.xml
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<menu_bar name="Login Menu">
- <menu label="自己" name="File">
- <menu_item_call label="å好設定" name="Preferences..."/>
- <menu_item_call label="çµæŸé€€å‡º [APP_NAME]" name="Quit"/>
+ <menu label="我自己" name="File">
+ <menu_item_call label="å好設定…" name="Preferences..."/>
+ <menu_item_call label="退出 [APP_NAME]" name="Quit"/>
</menu>
<menu label="幫助" name="Help">
<menu_item_call label="[SECOND_LIFE] 幫助" name="Second Life Help"/>
@@ -14,11 +14,17 @@
<menu_item_call label="UI / é¡è‰² 設定" name="UI/Color Settings"/>
<menu_item_call label="XUI é è¦½å·¥å…·" name="UI Preview Tool"/>
<menu label="UI 測試" name="UI Tests"/>
- <menu_item_call label="設定視窗尺寸大å°..." name="Set Window Size..."/>
+ <menu_item_call label="設定視窗大å°..." name="Set Window Size..."/>
<menu_item_call label="顯示 TOS" name="TOS"/>
<menu_item_call label="顯示嚴é‡è¨Šæ¯" name="Critical"/>
- <menu_item_call label="媒體ç€è¦½å™¨æ¸¬è©¦" name="Web Browser Test"/>
- <menu_item_call label="網é å…§å®¹æµ®å‹•è¦–窗測試" name="Web Content Floater Test"/>
+ <menu_item_call label="網é å…§å®¹æµ®å‹•è¦–窗除錯測試" name="Web Content Floater Debug Test"/>
+ <menu label="設定記錄細節" name="Set Logging Level">
+ <menu_item_check label="除錯" name="Debug"/>
+ <menu_item_check label="資訊" name="Info"/>
+ <menu_item_check label="警告" name="Warning"/>
+ <menu_item_check label="錯誤" name="Error"/>
+ <menu_item_check label="ç„¡" name="None"/>
+ </menu>
<menu_item_check label="顯示網格挑é¸å™¨" name="Show Grid Picker"/>
<menu_item_call label="顯示通知控制å°" name="Show Notifications Console"/>
</menu>
diff --git a/indra/newview/skins/default/xui/zh/menu_media_ctrl.xml b/indra/newview/skins/default/xui/zh/menu_media_ctrl.xml
index 2ec95aa4f9..d222d7f658 100644..100755
--- a/indra/newview/skins/default/xui/zh/menu_media_ctrl.xml
+++ b/indra/newview/skins/default/xui/zh/menu_media_ctrl.xml
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="media ctrl context menu">
<menu_item_call label="剪下" name="Cut"/>
- <menu_item_call label="覆製" name="Copy"/>
+ <menu_item_call label="æšåº¨" name="Copy"/>
<menu_item_call label="貼上" name="Paste"/>
+ <menu_item_call label="開啟網é åµæŸ¥å™¨" name="open_webinspector"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/zh/menu_mini_map.xml b/indra/newview/skins/default/xui/zh/menu_mini_map.xml
index 24bc6355c7..7fd629471a 100644..100755
--- a/indra/newview/skins/default/xui/zh/menu_mini_map.xml
+++ b/indra/newview/skins/default/xui/zh/menu_mini_map.xml
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<menu name="Popup">
- <menu_item_call label="Zoom Close" name="Zoom Close"/>
- <menu_item_call label="Zoom Medium" name="Zoom Medium"/>
- <menu_item_call label="Zoom Far" name="Zoom Far"/>
- <menu_item_call label="Zoom Default" name="Zoom Default"/>
+ <menu_item_call label="放大é è¿‘" name="Zoom Close"/>
+ <menu_item_call label="é è¿‘é©è·" name="Zoom Medium"/>
+ <menu_item_call label="縮å°é é›¢" name="Zoom Far"/>
+ <menu_item_call label="縮放æ¢å¾©é è¨­" name="Zoom Default"/>
<menu_item_check label="旋轉地圖" name="Rotate Map"/>
<menu_item_check label="自動居中" name="Auto Center"/>
<menu_item_call label="åœæ­¢è¿½è¹¤" name="Stop Tracking"/>
diff --git a/indra/newview/skins/default/xui/zh/menu_model_import_gear_default.xml b/indra/newview/skins/default/xui/zh/menu_model_import_gear_default.xml
new file mode 100755
index 0000000000..5f82685632
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/menu_model_import_gear_default.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="model_menu_gear_default">
+ <menu_item_check label="顯示å´é‚Š" name="show_edges"/>
+ <menu_item_check label="顯示物ç†" name="show_physics"/>
+ <menu_item_check label="顯示æ質" name="show_textures"/>
+ <menu_item_check label="顯示表皮é‡é‡" name="show_skin_weight"/>
+ <menu_item_check label="顯示接點ä½ç½®" name="show_joint_positions"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/zh/menu_mute_particle.xml b/indra/newview/skins/default/xui/zh/menu_mute_particle.xml
new file mode 100644
index 0000000000..fbde9b435d
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/menu_mute_particle.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<!-- *NOTE: See also menu_attachment_other.xml -->
+<context_menu name="Mute Particle Pie">
+ <menu_item_call label="å°éŽ–ç²’å­æ‰€æœ‰äºº" name="Mute Particle"/>
+</context_menu>
diff --git a/indra/newview/skins/default/xui/zh/menu_navbar.xml b/indra/newview/skins/default/xui/zh/menu_navbar.xml
index 69df4929f2..d8356e6277 100644..100755
--- a/indra/newview/skins/default/xui/zh/menu_navbar.xml
+++ b/indra/newview/skins/default/xui/zh/menu_navbar.xml
@@ -4,7 +4,7 @@
<menu_item_check label="顯示地段屬性" name="Show Parcel Properties"/>
<menu_item_call label="地標" name="Landmark"/>
<menu_item_call label="剪下" name="Cut"/>
- <menu_item_call label="覆製" name="Copy"/>
+ <menu_item_call label="æšåº¨" name="Copy"/>
<menu_item_call label="貼上" name="Paste"/>
<menu_item_call label="刪除" name="Delete"/>
<menu_item_call label="å…¨é¸" name="Select All"/>
diff --git a/indra/newview/skins/default/xui/zh/menu_nearby_chat.xml b/indra/newview/skins/default/xui/zh/menu_nearby_chat.xml
index cad462eebb..ce5f5b6e17 100644..100755
--- a/indra/newview/skins/default/xui/zh/menu_nearby_chat.xml
+++ b/indra/newview/skins/default/xui/zh/menu_nearby_chat.xml
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<menu name="NearBy Chat Menu">
<menu_item_call label="顯示附近的人..." name="nearby_people"/>
- <menu_item_check label="Show Blocked Text" name="muted_text"/>
- <menu_item_check label="Show Buddy Icons" name="show_buddy_icons"/>
- <menu_item_check label="Show Names" name="show_names"/>
- <menu_item_check label="Show Icons and Names" name="show_icons_and_names"/>
+ <menu_item_check label="顯示被å°éŽ–文字" name="muted_text"/>
+ <menu_item_check label="顯示密å‹åœ–示" name="show_buddy_icons"/>
+ <menu_item_check label="顯示åå­—" name="show_names"/>
+ <menu_item_check label="顯示圖示和åå­—" name="show_icons_and_names"/>
<menu_item_call label="字型尺寸" name="font_size"/>
</menu>
diff --git a/indra/newview/skins/default/xui/zh/menu_notification_well_button.xml b/indra/newview/skins/default/xui/zh/menu_notification_well_button.xml
index b629f73584..b629f73584 100644..100755
--- a/indra/newview/skins/default/xui/zh/menu_notification_well_button.xml
+++ b/indra/newview/skins/default/xui/zh/menu_notification_well_button.xml
diff --git a/indra/newview/skins/default/xui/zh/menu_object.xml b/indra/newview/skins/default/xui/zh/menu_object.xml
index ed41a4f0bf..f6657d876e 100644..100755
--- a/indra/newview/skins/default/xui/zh/menu_object.xml
+++ b/indra/newview/skins/default/xui/zh/menu_object.xml
@@ -3,19 +3,21 @@
<menu_item_call label="觸碰" name="Object Touch"/>
<menu_item_call label="編輯" name="Edit..."/>
<menu_item_call label="建造" name="Build"/>
- <menu_item_call label="é–‹å•Ÿ" name="Open"/>
- <menu_item_call label="å下" name="Object Sit"/>
+ <menu_item_call label="打開" name="Open"/>
+ <menu_item_call label="å在這裡" name="Object Sit"/>
<menu_item_call label="èµ·ç«‹" name="Object Stand Up"/>
<menu_item_call label="物件檔案" name="Object Inspect"/>
- <menu_item_call label="Zoom In" name="Zoom In"/>
+ <menu_item_call label="放大" name="Zoom In"/>
+ <menu_item_call label="在è¯çµé›†è£¡é¡¯ç¤º" name="show_in_linksets"/>
+ <menu_item_call label="在角色中顯示" name="show_in_characters"/>
<context_menu label="穿上" name="Put On">
<menu_item_call label="穿上" name="Wear"/>
<menu_item_call label="添加" name="Add"/>
- <context_menu label="Attach" name="Object Attach"/>
- <context_menu label="Attach HUD" name="Object Attach HUD"/>
+ <context_menu label="附著" name="Object Attach"/>
+ <context_menu label="附加擡頭顯示" name="Object Attach HUD"/>
</context_menu>
<context_menu label="管ç†" name="Remove">
- <menu_item_call label="舉報濫用" name="Report Abuse..."/>
+ <menu_item_call label="é•è¦èˆ‰å ±" name="Report Abuse..."/>
<menu_item_call label="å°éŽ–" name="Object Mute"/>
<menu_item_call label="退回" name="Return..."/>
</context_menu>
@@ -24,4 +26,5 @@
<menu_item_call label="支付" name="Pay..."/>
<menu_item_call label="購買" name="Buy..."/>
<menu_item_call label="刪除" name="Delete"/>
+ <menu_item_call label="å°éŽ–ç²’å­æ‰€æœ‰äºº" name="Mute Particle"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/zh/menu_object_icon.xml b/indra/newview/skins/default/xui/zh/menu_object_icon.xml
index d27e75b830..9655732f2e 100644..100755
--- a/indra/newview/skins/default/xui/zh/menu_object_icon.xml
+++ b/indra/newview/skins/default/xui/zh/menu_object_icon.xml
@@ -1,5 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<menu name="Object Icon Menu">
<menu_item_call label="物件檔案..." name="Object Profile"/>
- <menu_item_call label="Block..." name="Block"/>
+ <menu_item_call label="å°éŽ–…" name="Block"/>
+ <menu_item_call label="顯示在地圖上" name="show_on_map"/>
+ <menu_item_call label="瞬間傳é€åˆ°ç‰©ä»¶ä½ç½®" name="teleport_to_object"/>
</menu>
diff --git a/indra/newview/skins/default/xui/zh/menu_outfit_gear.xml b/indra/newview/skins/default/xui/zh/menu_outfit_gear.xml
index 90704fee65..258d0d6b20 100644..100755
--- a/indra/newview/skins/default/xui/zh/menu_outfit_gear.xml
+++ b/indra/newview/skins/default/xui/zh/menu_outfit_gear.xml
@@ -8,7 +8,7 @@
<menu_item_call label="新褲å­" name="New Pants"/>
<menu_item_call label="æ–°éž‹å­" name="New Shoes"/>
<menu_item_call label="新襪å­" name="New Socks"/>
- <menu_item_call label="新夾克" name="New Jacket"/>
+ <menu_item_call label="新外套" name="New Jacket"/>
<menu_item_call label="新裙å­" name="New Skirt"/>
<menu_item_call label="新手套" name="New Gloves"/>
<menu_item_call label="新內衣" name="New Undershirt"/>
@@ -23,6 +23,8 @@
<menu_item_call label="æ–°é ­é«®" name="New Hair"/>
<menu_item_call label="新眼ç›" name="New Eyes"/>
</menu>
+ <menu_item_call label="展開全部資料夾" name="expand"/>
+ <menu_item_call label="摺疊全部資料夾" name="collapse"/>
<menu_item_call label="è£æ‰®æ›´å" name="rename"/>
<menu_item_call label="刪除è£æ‰®" name="delete_outfit"/>
</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/zh/menu_outfit_tab.xml b/indra/newview/skins/default/xui/zh/menu_outfit_tab.xml
index a4614710f4..a4614710f4 100644..100755
--- a/indra/newview/skins/default/xui/zh/menu_outfit_tab.xml
+++ b/indra/newview/skins/default/xui/zh/menu_outfit_tab.xml
diff --git a/indra/newview/skins/default/xui/zh/menu_participant_list.xml b/indra/newview/skins/default/xui/zh/menu_participant_list.xml
index 81ae6e4e85..2456e9fee9 100644..100755
--- a/indra/newview/skins/default/xui/zh/menu_participant_list.xml
+++ b/indra/newview/skins/default/xui/zh/menu_participant_list.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Participant List Context Menu">
<menu_item_check label="ä¾å稱排åº" name="SortByName"/>
- <menu_item_check label="Sort by Recent Speakers" name="SortByRecentSpeakers"/>
+ <menu_item_check label="ä¾æœ€è¿‘說話者排åº" name="SortByRecentSpeakers"/>
<menu_item_call label="察看檔案" name="View Profile"/>
<menu_item_call label="加為朋å‹" name="Add Friend"/>
<menu_item_call label="IM" name="IM"/>
@@ -9,13 +9,13 @@
<menu_item_call label="分享" name="Share"/>
<menu_item_call label="支付" name="Pay"/>
<menu_item_check label="察看人群圖示" name="View Icons"/>
- <menu_item_check label="Block Voice" name="Block/Unblock"/>
- <menu_item_check label="Block Text" name="MuteText"/>
- <context_menu label="Moderator Options" name="Moderator Options">
- <menu_item_check label="Allow text chat" name="AllowTextChat"/>
- <menu_item_call label="Mute this participant" name="ModerateVoiceMuteSelected"/>
- <menu_item_call label="Unmute this participant" name="ModerateVoiceUnMuteSelected"/>
- <menu_item_call label="Mute everyone" name="ModerateVoiceMute"/>
- <menu_item_call label="Unmute everyone" name="ModerateVoiceUnmute"/>
+ <menu_item_check label="ç¦æ­¢èªžéŸ³" name="Block/Unblock"/>
+ <menu_item_check label="ç¦æ­¢æ–‡å­—" name="MuteText"/>
+ <context_menu label="主æŒäººé¸é …" name="Moderator Options">
+ <menu_item_check label="å…許文字èŠå¤©" name="AllowTextChat"/>
+ <menu_item_call label="將此人消音" name="ModerateVoiceMuteSelected"/>
+ <menu_item_call label="å–消å°æ­¤äººçš„消音" name="ModerateVoiceUnMuteSelected"/>
+ <menu_item_call label="所有人消音" name="ModerateVoiceMute"/>
+ <menu_item_call label="å–消所有人的消音" name="ModerateVoiceUnmute"/>
</context_menu>
</context_menu>
diff --git a/indra/newview/skins/default/xui/zh/menu_participant_view.xml b/indra/newview/skins/default/xui/zh/menu_participant_view.xml
new file mode 100644
index 0000000000..8b35860eb6
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/menu_participant_view.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="participant_manu_view">
+ <menu_item_check label="將交談ä¾é¡žåž‹æŽ’åº" name="sort_sessions_by_type"/>
+ <menu_item_check label="將交談ä¾å字排åº" name="sort_sessions_by_name"/>
+ <menu_item_check label="將交談ä¾æœ€è¿‘活動排åº" name="sort_sessions_by_recent"/>
+ <menu_item_check label="å°‡åƒèˆ‡è€…ä¾å字排åº" name="sort_participants_by_name"/>
+ <menu_item_check label="å°‡åƒèˆ‡è€…ä¾æœ€è¿‘活動排åº" name="sort_participants_by_recent"/>
+ <menu_item_call label="èŠå¤©å好設定……" name="chat_preferences"/>
+ <menu_item_call label="éš±ç§å好設定……" name="privacy_preferences"/>
+ <menu_item_check label="交談記錄……" name="Conversation"/>
+ <menu_item_check label="翻譯附近的èŠå¤©" name="Translate_chat"/>
+ <menu_item_check label="翻譯設定……" name="Translation_settings"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/zh/menu_people_blocked_gear.xml b/indra/newview/skins/default/xui/zh/menu_people_blocked_gear.xml
new file mode 100644
index 0000000000..9a2a3c403d
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/menu_people_blocked_gear.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_blocked_gear">
+ <menu_item_call label="解除å°éŽ–" name="unblock"/>
+ <menu_item_call label="檔案..." name="profile"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/zh/menu_people_blocked_plus.xml b/indra/newview/skins/default/xui/zh/menu_people_blocked_plus.xml
new file mode 100644
index 0000000000..a8cecb4e14
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/menu_people_blocked_plus.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_blocked_plus">
+ <menu_item_call label="按åå­—å°éŽ–居民……" name="block_resident_by_name"/>
+ <menu_item_call label="ä¾å稱å°éŽ–物件" name="block_object_by_name"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/zh/menu_people_blocked_view.xml b/indra/newview/skins/default/xui/zh/menu_people_blocked_view.xml
new file mode 100644
index 0000000000..5b70cd35bf
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/menu_people_blocked_view.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_blocked_view">
+ <menu_item_check label="ä¾å稱排åº" name="sort_by_name"/>
+ <menu_item_check label="ä¾é¡žåž‹æŽ’åº" name="sort_by_type"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/zh/menu_people_friends_view.xml b/indra/newview/skins/default/xui/zh/menu_people_friends_view.xml
new file mode 100644
index 0000000000..4251238fd9
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/menu_people_friends_view.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_group_plus">
+ <menu_item_check label="ä¾å稱排åº" name="sort_name"/>
+ <menu_item_check label="ä¾ç‹€æ…‹æŽ’åº" name="sort_status"/>
+ <menu_item_check label="察看人群圖示" name="view_icons"/>
+ <menu_item_check label="察看許å¯æ¬Šé™" name="view_permissions"/>
+ <menu_item_check label="檢視交談記錄……" name="view_conversation"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/zh/menu_people_friends_view_sort.xml b/indra/newview/skins/default/xui/zh/menu_people_friends_view_sort.xml
index 59854faeec..59854faeec 100644..100755
--- a/indra/newview/skins/default/xui/zh/menu_people_friends_view_sort.xml
+++ b/indra/newview/skins/default/xui/zh/menu_people_friends_view_sort.xml
diff --git a/indra/newview/skins/default/xui/zh/menu_people_groups.xml b/indra/newview/skins/default/xui/zh/menu_people_groups.xml
index 1d78c1de0a..b4b566f5ca 100644..100755
--- a/indra/newview/skins/default/xui/zh/menu_people_groups.xml
+++ b/indra/newview/skins/default/xui/zh/menu_people_groups.xml
@@ -2,7 +2,7 @@
<menu name="menu_group_plus">
<menu_item_call label="察看資訊" name="View Info"/>
<menu_item_call label="èŠå¤©" name="Chat"/>
- <menu_item_call label="通話" name="Call"/>
- <menu_item_call label="Activate" name="Activate"/>
- <menu_item_call label="Leave" name="Leave"/>
+ <menu_item_call label="語音通話" name="Call"/>
+ <menu_item_call label="å•Ÿå‹•" name="Activate"/>
+ <menu_item_call label="退出" name="Leave"/>
</menu>
diff --git a/indra/newview/skins/default/xui/zh/menu_people_groups_view.xml b/indra/newview/skins/default/xui/zh/menu_people_groups_view.xml
new file mode 100644
index 0000000000..05a30d938f
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/menu_people_groups_view.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_group_plus">
+ <menu_item_check label="顯示群組圖示" name="Display Group Icons"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/zh/menu_people_groups_view_sort.xml b/indra/newview/skins/default/xui/zh/menu_people_groups_view_sort.xml
index 1be5c69b94..1be5c69b94 100644..100755
--- a/indra/newview/skins/default/xui/zh/menu_people_groups_view_sort.xml
+++ b/indra/newview/skins/default/xui/zh/menu_people_groups_view_sort.xml
diff --git a/indra/newview/skins/default/xui/zh/menu_people_nearby.xml b/indra/newview/skins/default/xui/zh/menu_people_nearby.xml
index 9faa35001c..d25adaf8fb 100644..100755
--- a/indra/newview/skins/default/xui/zh/menu_people_nearby.xml
+++ b/indra/newview/skins/default/xui/zh/menu_people_nearby.xml
@@ -1,13 +1,16 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Avatar Context Menu">
- <menu_item_call label="察看檔案" name="View Profile"/>
- <menu_item_call label="加為朋å‹" name="Add Friend"/>
- <menu_item_call label="Remove Friend" name="Remove Friend"/>
- <menu_item_call label="IM" name="IM"/>
- <menu_item_call label="通話" name="Call"/>
- <menu_item_call label="地圖" name="Map"/>
- <menu_item_call label="分享" name="Share"/>
- <menu_item_call label="支付" name="Pay"/>
- <menu_item_check label="Block/Unblock" name="Block/Unblock"/>
- <menu_item_call label="發給瞬間傳é€è«‹æ±‚" name="teleport"/>
+ <menu_item_call label="察看檔案" name="view_profile"/>
+ <menu_item_call label="IM" name="im"/>
+ <menu_item_call label="發給瞬間傳é€è«‹æ±‚" name="offer_teleport"/>
+ <menu_item_call label="語音通話" name="voice_call"/>
+ <menu_item_call label="檢視èŠå¤©æ­·å²â€¦â€¦" name="chat_history"/>
+ <menu_item_call label="加為朋å‹" name="add_friend"/>
+ <menu_item_call label="移除朋å‹" name="remove_friend"/>
+ <menu_item_call label="邀請加入群組……" name="invite_to_group"/>
+ <menu_item_call label="放大" name="zoom_in"/>
+ <menu_item_call label="地圖" name="map"/>
+ <menu_item_call label="分享" name="share"/>
+ <menu_item_call label="支付" name="pay"/>
+ <menu_item_check label="å°éŽ–/ä¸å†å°éŽ–" name="block_unblock"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/zh/menu_people_nearby_multiselect.xml b/indra/newview/skins/default/xui/zh/menu_people_nearby_multiselect.xml
index 1380e0b307..69f0eab7dc 100644..100755
--- a/indra/newview/skins/default/xui/zh/menu_people_nearby_multiselect.xml
+++ b/indra/newview/skins/default/xui/zh/menu_people_nearby_multiselect.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Multi-Selected People Context Menu">
- <menu_item_call label="加為朋å‹" name="Add Friends"/>
- <menu_item_call label="移除朋å‹" name="Remove Friend"/>
- <menu_item_call label="IM" name="IM"/>
- <menu_item_call label="通話" name="Call"/>
- <menu_item_call label="分享" name="Share"/>
- <menu_item_call label="支付" name="Pay"/>
- <menu_item_call label="發給瞬間傳é€è«‹æ±‚" name="teleport"/>
+ <menu_item_call label="加為朋å‹" name="add_friends"/>
+ <menu_item_call label="移除朋å‹" name="remove_friends"/>
+ <menu_item_call label="IM" name="im"/>
+ <menu_item_call label="通話" name="call"/>
+ <menu_item_call label="分享" name="share"/>
+ <menu_item_call label="支付" name="pay"/>
+ <menu_item_call label="發給瞬間傳é€è«‹æ±‚" name="offer_teleport"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/zh/menu_people_nearby_view.xml b/indra/newview/skins/default/xui/zh/menu_people_nearby_view.xml
new file mode 100644
index 0000000000..9bc5638472
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/menu_people_nearby_view.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_group_plus">
+ <menu_item_check label="ä¾æœ€è¿‘說話者排åº" name="sort_by_recent_speakers"/>
+ <menu_item_check label="ä¾å稱排åº" name="sort_name"/>
+ <menu_item_check label="ä¾è·é›¢æŽ’åº" name="sort_distance"/>
+ <menu_item_check label="察看人群圖示" name="view_icons"/>
+ <menu_item_check label="察看地圖" name="view_map"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/zh/menu_people_nearby_view_sort.xml b/indra/newview/skins/default/xui/zh/menu_people_nearby_view_sort.xml
index a7f5c74b82..6cb0ac3c89 100644..100755
--- a/indra/newview/skins/default/xui/zh/menu_people_nearby_view_sort.xml
+++ b/indra/newview/skins/default/xui/zh/menu_people_nearby_view_sort.xml
@@ -4,5 +4,6 @@
<menu_item_check label="ä¾å稱排åº" name="sort_name"/>
<menu_item_check label="ä¾è·é›¢æŽ’åº" name="sort_distance"/>
<menu_item_check label="察看人群圖示" name="view_icons"/>
- <menu_item_call label="顯示笨å°éŽ–的居民與物件" name="show_blocked_list"/>
+ <menu_item_check label="察看地圖" name="view_map"/>
+ <menu_item_call label="顯示被å°éŽ–的居民與物件" name="show_blocked_list"/>
</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/zh/menu_people_recent_view.xml b/indra/newview/skins/default/xui/zh/menu_people_recent_view.xml
new file mode 100644
index 0000000000..382234c3ec
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/menu_people_recent_view.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="menu_group_plus">
+ <menu_item_check label="ä¾æœ€è¿‘排åº" name="sort_most"/>
+ <menu_item_check label="ä¾å稱排åº" name="sort_name"/>
+ <menu_item_check label="察看人群圖示" name="view_icons"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/zh/menu_people_recent_view_sort.xml b/indra/newview/skins/default/xui/zh/menu_people_recent_view_sort.xml
index 5b6e7335d6..5b6e7335d6 100644..100755
--- a/indra/newview/skins/default/xui/zh/menu_people_recent_view_sort.xml
+++ b/indra/newview/skins/default/xui/zh/menu_people_recent_view_sort.xml
diff --git a/indra/newview/skins/default/xui/zh/menu_picks.xml b/indra/newview/skins/default/xui/zh/menu_picks.xml
index 2e88ac2d39..2e88ac2d39 100644..100755
--- a/indra/newview/skins/default/xui/zh/menu_picks.xml
+++ b/indra/newview/skins/default/xui/zh/menu_picks.xml
diff --git a/indra/newview/skins/default/xui/zh/menu_picks_plus.xml b/indra/newview/skins/default/xui/zh/menu_picks_plus.xml
index e962bd90d5..80922a757d 100644..100755
--- a/indra/newview/skins/default/xui/zh/menu_picks_plus.xml
+++ b/indra/newview/skins/default/xui/zh/menu_picks_plus.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<toggleable_menu name="picks_plus_menu">
<menu_item_call label="æ–°ç²¾é¸åœ°é»ž" name="create_pick"/>
- <menu_item_call label="New Classified" name="create_classified"/>
+ <menu_item_call label="新個人廣告" name="create_classified"/>
</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/zh/menu_place.xml b/indra/newview/skins/default/xui/zh/menu_place.xml
index 3733baf119..3733baf119 100644..100755
--- a/indra/newview/skins/default/xui/zh/menu_place.xml
+++ b/indra/newview/skins/default/xui/zh/menu_place.xml
diff --git a/indra/newview/skins/default/xui/zh/menu_place_add_button.xml b/indra/newview/skins/default/xui/zh/menu_place_add_button.xml
index 95f8917234..95f8917234 100644..100755
--- a/indra/newview/skins/default/xui/zh/menu_place_add_button.xml
+++ b/indra/newview/skins/default/xui/zh/menu_place_add_button.xml
diff --git a/indra/newview/skins/default/xui/zh/menu_places_gear_folder.xml b/indra/newview/skins/default/xui/zh/menu_places_gear_folder.xml
index 7f4144d14d..27f0c7ebdb 100644..100755
--- a/indra/newview/skins/default/xui/zh/menu_places_gear_folder.xml
+++ b/indra/newview/skins/default/xui/zh/menu_places_gear_folder.xml
@@ -4,7 +4,7 @@
<menu_item_call label="添加資料夾" name="add_folder"/>
<menu_item_call label="還原物å“" name="restore_item"/>
<menu_item_call label="剪下" name="cut"/>
- <menu_item_call label="覆製" name="copy_folder"/>
+ <menu_item_call label="æšåº¨" name="copy_folder"/>
<menu_item_call label="貼上" name="paste"/>
<menu_item_call label="æ›´å" name="rename"/>
<menu_item_call label="刪除" name="delete"/>
diff --git a/indra/newview/skins/default/xui/zh/menu_places_gear_landmark.xml b/indra/newview/skins/default/xui/zh/menu_places_gear_landmark.xml
index f23d970b78..f23d970b78 100644..100755
--- a/indra/newview/skins/default/xui/zh/menu_places_gear_landmark.xml
+++ b/indra/newview/skins/default/xui/zh/menu_places_gear_landmark.xml
diff --git a/indra/newview/skins/default/xui/zh/menu_profile_overflow.xml b/indra/newview/skins/default/xui/zh/menu_profile_overflow.xml
index ca637ae54d..f77e7090c4 100644..100755
--- a/indra/newview/skins/default/xui/zh/menu_profile_overflow.xml
+++ b/indra/newview/skins/default/xui/zh/menu_profile_overflow.xml
@@ -3,10 +3,10 @@
<menu_item_call label="地圖" name="show_on_map"/>
<menu_item_call label="支付" name="pay"/>
<menu_item_call label="分享" name="share"/>
- <menu_item_call label="Block" name="block"/>
- <menu_item_call label="Unblock" name="unblock"/>
+ <menu_item_call label="å°éŽ–" name="block"/>
+ <menu_item_call label="解除å°éŽ–" name="unblock"/>
<menu_item_call label="踢出" name="kick"/>
<menu_item_call label="å‡çµ" name="freeze"/>
<menu_item_call label="解å‡" name="unfreeze"/>
- <menu_item_call label="CSR" name="csr"/>
+ <menu_item_call label="客æœ" name="csr"/>
</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/zh/menu_save_outfit.xml b/indra/newview/skins/default/xui/zh/menu_save_outfit.xml
index 7884df5b01..53ee6ee977 100644..100755
--- a/indra/newview/skins/default/xui/zh/menu_save_outfit.xml
+++ b/indra/newview/skins/default/xui/zh/menu_save_outfit.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<toggleable_menu name="save_outfit_menu">
<menu_item_call label="儲存" name="save_outfit"/>
- <menu_item_call label="å¦å­˜" name="save_as_new_outfit"/>
+ <menu_item_call label="å¦å­˜ç‚º" name="save_as_new_outfit"/>
</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/zh/menu_script_chiclet.xml b/indra/newview/skins/default/xui/zh/menu_script_chiclet.xml
index e9817dd2bc..e9817dd2bc 100644..100755
--- a/indra/newview/skins/default/xui/zh/menu_script_chiclet.xml
+++ b/indra/newview/skins/default/xui/zh/menu_script_chiclet.xml
diff --git a/indra/newview/skins/default/xui/zh/menu_slurl.xml b/indra/newview/skins/default/xui/zh/menu_slurl.xml
index 2cea18105a..2cea18105a 100644..100755
--- a/indra/newview/skins/default/xui/zh/menu_slurl.xml
+++ b/indra/newview/skins/default/xui/zh/menu_slurl.xml
diff --git a/indra/newview/skins/default/xui/zh/menu_teleport_history_gear.xml b/indra/newview/skins/default/xui/zh/menu_teleport_history_gear.xml
index d188840588..d188840588 100644..100755
--- a/indra/newview/skins/default/xui/zh/menu_teleport_history_gear.xml
+++ b/indra/newview/skins/default/xui/zh/menu_teleport_history_gear.xml
diff --git a/indra/newview/skins/default/xui/zh/menu_teleport_history_item.xml b/indra/newview/skins/default/xui/zh/menu_teleport_history_item.xml
index c636e108ad..c636e108ad 100644..100755
--- a/indra/newview/skins/default/xui/zh/menu_teleport_history_item.xml
+++ b/indra/newview/skins/default/xui/zh/menu_teleport_history_item.xml
diff --git a/indra/newview/skins/default/xui/zh/menu_teleport_history_tab.xml b/indra/newview/skins/default/xui/zh/menu_teleport_history_tab.xml
index f9107a96ed..90e8098348 100644..100755
--- a/indra/newview/skins/default/xui/zh/menu_teleport_history_tab.xml
+++ b/indra/newview/skins/default/xui/zh/menu_teleport_history_tab.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Teleport History Item Context Menu">
- <menu_item_call label="é–‹å•Ÿ" name="TabOpen"/>
+ <menu_item_call label="打開" name="TabOpen"/>
<menu_item_call label="關閉" name="TabClose"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/zh/menu_text_editor.xml b/indra/newview/skins/default/xui/zh/menu_text_editor.xml
index c25f5128c3..febc0b8b67 100644..100755
--- a/indra/newview/skins/default/xui/zh/menu_text_editor.xml
+++ b/indra/newview/skins/default/xui/zh/menu_text_editor.xml
@@ -1,7 +1,14 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Text editor context menu">
+ <menu_item_call label="(未知)" name="Suggestion 1"/>
+ <menu_item_call label="(未知)" name="Suggestion 2"/>
+ <menu_item_call label="(未知)" name="Suggestion 3"/>
+ <menu_item_call label="(未知)" name="Suggestion 4"/>
+ <menu_item_call label="(未知)" name="Suggestion 5"/>
+ <menu_item_call label="新增到字典" name="Add to Dictionary"/>
+ <menu_item_call label="新增到忽略清單" name="Add to Ignore"/>
<menu_item_call label="剪下" name="Cut"/>
- <menu_item_call label="覆製" name="Copy"/>
+ <menu_item_call label="æšåº¨" name="Copy"/>
<menu_item_call label="貼上" name="Paste"/>
<menu_item_call label="刪除" name="Delete"/>
<menu_item_call label="å…¨é¸" name="Select All"/>
diff --git a/indra/newview/skins/default/xui/zh/menu_toolbars.xml b/indra/newview/skins/default/xui/zh/menu_toolbars.xml
new file mode 100755
index 0000000000..d318992dd5
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/menu_toolbars.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<context_menu name="Toolbars Popup">
+ <menu_item_call label="移除此按鈕" name="Remove button"/>
+ <menu_item_call label="工具列按鈕…" name="Choose Buttons"/>
+ <menu_item_check label="圖示和標籤" name="icons_with_text"/>
+ <menu_item_check label="僅用圖示" name="icons_only"/>
+</context_menu>
diff --git a/indra/newview/skins/default/xui/zh/menu_topinfobar.xml b/indra/newview/skins/default/xui/zh/menu_topinfobar.xml
index debaafaa10..b07e9890ff 100644..100755
--- a/indra/newview/skins/default/xui/zh/menu_topinfobar.xml
+++ b/indra/newview/skins/default/xui/zh/menu_topinfobar.xml
@@ -3,5 +3,5 @@
<menu_item_check label="顯示座標" name="Show Coordinates"/>
<menu_item_check label="顯示地段屬性" name="Show Parcel Properties"/>
<menu_item_call label="地標" name="Landmark"/>
- <menu_item_call label="覆製" name="Copy"/>
+ <menu_item_call label="æšåº¨" name="Copy"/>
</menu>
diff --git a/indra/newview/skins/default/xui/zh/menu_url_agent.xml b/indra/newview/skins/default/xui/zh/menu_url_agent.xml
index 592bb6561e..752634dc6b 100644..100755
--- a/indra/newview/skins/default/xui/zh/menu_url_agent.xml
+++ b/indra/newview/skins/default/xui/zh/menu_url_agent.xml
@@ -1,6 +1,9 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Url Popup">
- <menu_item_call label="顯示居民檔案" name="show_agent"/>
+ <menu_item_call label="察看檔案" name="show_agent"/>
+ <menu_item_call label="é€å‡º IM..." name="send_im"/>
+ <menu_item_call label="加為朋å‹..." name="add_friend"/>
+ <menu_item_call label="移除朋å‹â€¦" name="remove_friend"/>
<menu_item_call label="覆製å稱到剪貼簿" name="url_copy_label"/>
<menu_item_call label="覆製 SLurl 到剪貼簿" name="url_copy"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/zh/menu_url_group.xml b/indra/newview/skins/default/xui/zh/menu_url_group.xml
index de97bb731f..de97bb731f 100644..100755
--- a/indra/newview/skins/default/xui/zh/menu_url_group.xml
+++ b/indra/newview/skins/default/xui/zh/menu_url_group.xml
diff --git a/indra/newview/skins/default/xui/zh/menu_url_http.xml b/indra/newview/skins/default/xui/zh/menu_url_http.xml
index cf953576f3..861cbfb975 100644..100755
--- a/indra/newview/skins/default/xui/zh/menu_url_http.xml
+++ b/indra/newview/skins/default/xui/zh/menu_url_http.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Url Popup">
<menu_item_call label="開啟網é " name="url_open"/>
- <menu_item_call label="Open in Internal Browser" name="url_open_internal"/>
- <menu_item_call label="Open in External Browser" name="url_open_external"/>
- <menu_item_call label="Copy URL to clipboard" name="url_copy"/>
+ <menu_item_call label="用內部ç€è¦½å™¨é–‹å•Ÿ" name="url_open_internal"/>
+ <menu_item_call label="用外部ç€è¦½å™¨é–‹å•Ÿ" name="url_open_external"/>
+ <menu_item_call label="覆製 URL 到剪貼簿" name="url_copy"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/zh/menu_url_inventory.xml b/indra/newview/skins/default/xui/zh/menu_url_inventory.xml
index 8eaea68c6f..8eaea68c6f 100644..100755
--- a/indra/newview/skins/default/xui/zh/menu_url_inventory.xml
+++ b/indra/newview/skins/default/xui/zh/menu_url_inventory.xml
diff --git a/indra/newview/skins/default/xui/zh/menu_url_map.xml b/indra/newview/skins/default/xui/zh/menu_url_map.xml
index fbda20fd2f..fbda20fd2f 100644..100755
--- a/indra/newview/skins/default/xui/zh/menu_url_map.xml
+++ b/indra/newview/skins/default/xui/zh/menu_url_map.xml
diff --git a/indra/newview/skins/default/xui/zh/menu_url_objectim.xml b/indra/newview/skins/default/xui/zh/menu_url_objectim.xml
index b344b21c62..ac366f92ef 100644..100755
--- a/indra/newview/skins/default/xui/zh/menu_url_objectim.xml
+++ b/indra/newview/skins/default/xui/zh/menu_url_objectim.xml
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Url Popup">
- <menu_item_call label="顯示物件資訊" name="show_object"/>
+ <menu_item_call label="物件檔案..." name="show_object"/>
+ <menu_item_call label="å°éŽ–…" name="block_object"/>
<menu_item_call label="顯示在地圖上" name="show_on_map"/>
<menu_item_call label="瞬間傳é€åˆ°ç‰©ä»¶ä½ç½®" name="teleport_to_object"/>
<menu_item_call label="覆製物件å稱到剪貼簿" name="url_copy_label"/>
diff --git a/indra/newview/skins/default/xui/zh/menu_url_parcel.xml b/indra/newview/skins/default/xui/zh/menu_url_parcel.xml
index 330c28238f..330c28238f 100644..100755
--- a/indra/newview/skins/default/xui/zh/menu_url_parcel.xml
+++ b/indra/newview/skins/default/xui/zh/menu_url_parcel.xml
diff --git a/indra/newview/skins/default/xui/zh/menu_url_slapp.xml b/indra/newview/skins/default/xui/zh/menu_url_slapp.xml
index afc15ce13c..6ce9a10d3e 100644..100755
--- a/indra/newview/skins/default/xui/zh/menu_url_slapp.xml
+++ b/indra/newview/skins/default/xui/zh/menu_url_slapp.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Url Popup">
- <menu_item_call label="Run This Command" name="run_slapp"/>
+ <menu_item_call label="執行這個指令" name="run_slapp"/>
<menu_item_call label="覆製 SLurl 到剪貼簿" name="url_copy"/>
</context_menu>
diff --git a/indra/newview/skins/default/xui/zh/menu_url_slurl.xml b/indra/newview/skins/default/xui/zh/menu_url_slurl.xml
index 2fb247f250..2fb247f250 100644..100755
--- a/indra/newview/skins/default/xui/zh/menu_url_slurl.xml
+++ b/indra/newview/skins/default/xui/zh/menu_url_slurl.xml
diff --git a/indra/newview/skins/default/xui/zh/menu_url_teleport.xml b/indra/newview/skins/default/xui/zh/menu_url_teleport.xml
index e3e4b4716d..e3e4b4716d 100644..100755
--- a/indra/newview/skins/default/xui/zh/menu_url_teleport.xml
+++ b/indra/newview/skins/default/xui/zh/menu_url_teleport.xml
diff --git a/indra/newview/skins/default/xui/zh/menu_viewer.xml b/indra/newview/skins/default/xui/zh/menu_viewer.xml
index b6bb79bcbc..b267bda2bb 100644..100755
--- a/indra/newview/skins/default/xui/zh/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/zh/menu_viewer.xml
@@ -1,65 +1,98 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<menu_bar name="Main Menu">
- <menu label="自己" name="Me">
- <menu_item_call label="å好設定" name="Preferences"/>
- <menu_item_call label="我的塗鴉牆" name="Manage My Account"/>
- <menu_item_call label="購買 L$" name="Buy and Sell L$"/>
- <menu_item_call label="我的個人檔案" name="Profile"/>
- <menu_item_call label="我的外觀" name="ChangeOutfit"/>
- <menu_item_check label="我的庫存" name="Inventory"/>
- <menu_item_check label="我的庫存" name="ShowSidetrayInventory"/>
- <menu_item_check label="我的姿勢" name="Gestures"/>
- <menu_item_check label="我的è²éŸ³" name="ShowVoice"/>
- <menu label="移動" name="Movement">
+ <menu label="我自己" name="Me">
+ <menu_item_call label="檔案..." name="Profile"/>
+ <menu_item_call label="外觀…" name="ChangeOutfit"/>
+ <menu_item_call label="é¸æ“‡ä¸€å€‹åŒ–身…" name="Avatar Picker"/>
+ <menu_item_check label="收ç´å€â€¦" name="Inventory"/>
+ <menu_item_call label="新收ç´å€è¦–窗" name="NewInventoryWindow"/>
+ <menu_item_call label="地點…" name="Places"/>
+ <menu_item_call label="ç²¾é¸åœ°é»žâ€¦" name="Picks"/>
+ <menu_item_call label="æ”影機控制…" name="Camera Controls"/>
+ <menu label="動作" name="Movement">
<menu_item_call label="å下" name="Sit Down Here"/>
<menu_item_check label="飛行" name="Fly"/>
- <menu_item_check label="總是奔跑" name="Always Run"/>
+ <menu_item_check label="以跑代步" name="Always Run"/>
<menu_item_call label="åœæ­¢æˆ‘身上的動作" name="Stop Animating My Avatar"/>
- </menu>
- <menu label="我的狀態" name="Status">
- <menu_item_call label="離開" name="Set Away"/>
- <menu_item_call label="忙碌" name="Set Busy"/>
- </menu>
- <menu_item_call label="çµæŸé€€å‡º [APP_NAME]" name="Quit"/>
+ <menu_item_call label="行走 / 跑步 / 飛行…" name="Walk / run / fly"/>
+ </menu>
+ <menu label="狀態" name="Status">
+ <menu_item_check label="離開" name="Away"/>
+ <menu_item_check label="請勿打擾" name="Do Not Disturb"/>
+ </menu>
+ <menu_item_call label="購買 L$…" name="Buy and Sell L$"/>
+ <menu_item_call label="商家發件匣…" name="MerchantOutbox"/>
+ <menu_item_call label="帳戶主控臺…" name="Manage My Account"/>
+ <menu_item_call label="å好設定…" name="Preferences"/>
+ <menu_item_call label="工具列按鈕…" name="Toolbars"/>
+ <menu_item_call label="éš±è—所有控制" name="Hide UI"/>
+ <menu_item_check label="顯示 HUD 附件" name="Show HUD Attachments"/>
+ <menu_item_call label="退出 [APP_NAME]" name="Quit"/>
</menu>
<menu label="æºé€š" name="Communicate">
- <menu_item_call label="我的朋å‹" name="My Friends"/>
- <menu_item_call label="我的群組" name="My Groups"/>
- <menu_item_check label="附近的èŠå¤©" name="Nearby Chat"/>
- <menu_item_call label="附近的人群" name="Active Speakers"/>
+ <menu_item_check label="交談……" name="Conversations"/>
+ <menu_item_check label="附近的èŠå¤©â€¦â€¦" name="Nearby Chat"/>
+ <menu_item_check label="說話" name="Speak"/>
+ <menu_item_check label="交談記錄…" name="Conversation Log..."/>
+ <menu label="語音變è²" name="VoiceMorphing">
+ <menu_item_check label="沒有變è²æ•ˆæžœ" name="NoVoiceMorphing"/>
+ <menu_item_check label="é è¦½â€¦â€¦" name="Preview"/>
+ <menu_item_call label="訂閱……" name="Subscribe"/>
+ </menu>
+ <menu_item_check label="姿勢…" name="Gestures"/>
+ <menu_item_check label="朋å‹" name="My Friends"/>
+ <menu_item_check label="群組" name="My Groups"/>
+ <menu_item_check label="附近的人群" name="Active Speakers"/>
+ <menu_item_call label="å°éŽ–清單" name="Block List"/>
+ <menu_item_check label="請勿打擾" name="Do Not Disturb"/>
</menu>
<menu label="世界" name="World">
- <menu_item_check label="迷你地圖" name="Mini-Map"/>
+ <menu_item_call label="將此處記為地標" name="Create Landmark Here"/>
+ <menu_item_call label="目的地…" name="Destinations"/>
<menu_item_check label="世界地圖" name="World Map"/>
+ <menu_item_check label="迷你地圖" name="Mini-Map"/>
<menu_item_check label="æœå°‹" name="Search"/>
- <menu_item_call label="æ‹æ”å¿«ç…§" name="Take Snapshot"/>
- <menu_item_call label="將此處記下地標" name="Create Landmark Here"/>
- <menu_item_separator/>
- <menu_item_call label="地點檔案" name="Place Profile"/>
- <menu_item_call label="關於土地" name="About Land"/>
- <menu_item_call label="åœ°å€ / 領地" name="Region/Estate"/>
+ <menu_item_call label="瞬間傳é€å›žå®¶" name="Teleport Home"/>
+ <menu_item_call label="把這裡設為我的家" name="Set Home to Here"/>
+ <menu_item_call label="å¿«ç…§" name="Take Snapshot"/>
+ <menu_item_call label="地點å°æª”案" name="Place Profile"/>
+ <menu_item_call label="土地資料" name="About Land"/>
+ <menu_item_call label="地å€/領地" name="Region/Estate"/>
+ <menu_item_call label="我所æ“有的土地…" name="My Land"/>
<menu_item_call label="購買這塊土地" name="Buy Land"/>
- <menu_item_call label="我的土地" name="My Land"/>
<menu label="顯示" name="LandShow">
- <menu_item_check label="移動控制" name="Movement Controls"/>
- <menu_item_check label="視角控制" name="Camera Controls"/>
<menu_item_check label="ç¦è¶Šç·š" name="Ban Lines"/>
<menu_item_check label="指標" name="beacons"/>
- <menu_item_check label="土地邊界" name="Property Lines"/>
+ <menu_item_check label="地產邊界" name="Property Lines"/>
<menu_item_check label="地主" name="Land Owners"/>
<menu_item_check label="座標" name="Coordinates"/>
<menu_item_check label="地段屬性" name="Parcel Properties"/>
<menu_item_check label="進階é¸å–®" name="Show Advanced Menu"/>
</menu>
- <menu_item_call label="瞬間瞬間傳é€å›žå®¶" name="Teleport Home"/>
- <menu_item_call label="設定家在此處" name="Set Home to Here"/>
<menu label="太陽" name="Sun">
<menu_item_call label="日出" name="Sunrise"/>
<menu_item_call label="中åˆ" name="Noon"/>
<menu_item_call label="æ—¥è½" name="Sunset"/>
<menu_item_call label="åˆå¤œ" name="Midnight"/>
- <menu_item_call label="領地時間" name="Revert to Region Default"/>
- <menu_item_call label="環境編輯器" name="Environment Editor"/>
+ <menu_item_call label="使用地å€è¨­å®š" name="Use Region Settings"/>
+ </menu>
+ <menu label="環境編輯器" name="Environment Editor">
+ <menu_item_call label="環境設定…" name="Environment Settings"/>
+ <menu label="水的自訂é…ç½®" name="Water Presets">
+ <menu_item_call label="新的自訂é…置…" name="new_water_preset"/>
+ <menu_item_call label="編輯自訂é…置…" name="edit_water_preset"/>
+ <menu_item_call label="刪除自訂é…置…" name="delete_water_preset"/>
+ </menu>
+ <menu label="天空自訂é…ç½®" name="Sky Presets">
+ <menu_item_call label="新的自訂é…置…" name="new_sky_preset"/>
+ <menu_item_call label="編輯自訂é…置…" name="edit_sky_preset"/>
+ <menu_item_call label="刪除自訂é…置…" name="delete_sky_preset"/>
+ </menu>
+ <menu label="日的自訂é…ç½®" name="Day Presets">
+ <menu_item_call label="新的自訂é…置…" name="new_day_preset"/>
+ <menu_item_call label="編輯自訂é…置…" name="edit_day_preset"/>
+ <menu_item_call label="刪除自訂é…置…" name="delete_day_preset"/>
+ </menu>
</menu>
</menu>
<menu label="建造" name="BuildTools">
@@ -80,13 +113,13 @@
<menu_item_call label="包括下一部ä½" name="Include Next Part"/>
<menu_item_call label="包括上一部ä½" name="Include Previous Part"/>
</menu>
+ <menu_item_call label="è¯çµé›†â€¦" name="pathfinding_linkset_menu_item"/>
<menu_item_call label="èšç„¦æ–¼æ‰€é¸éƒ¨ä½" name="Focus on Selection"/>
<menu_item_call label="縮放至所é¸éƒ¨ä½" name="Zoom to Selection"/>
<menu label="物件" name="Object">
<menu_item_call label="購買" name="Menu Object Buy"/>
<menu_item_call label="å–å¾—" name="Menu Object Take"/>
<menu_item_call label="å–得副本" name="Take Copy"/>
- <menu_item_call label="回存到我的收ç´å€" name="Save Object Back to My Inventory"/>
<menu_item_call label="回存到物件內容" name="Save Object Back to Object Contents"/>
<menu_item_call label="退回物件" name="Return Object back to Owner"/>
</menu>
@@ -97,65 +130,77 @@
<menu_item_call label="設定腳本為執行中" name="Set Scripts to Running"/>
<menu_item_call label="設定腳本為éžåŸ·è¡Œä¸­" name="Set Scripts to Not Running"/>
</menu>
+ <menu label="尋徑" name="Pathfinding">
+ <menu_item_call label="è¯çµé›†â€¦" name="pathfinding_linksets_menu_item"/>
+ <menu_item_call label="角色…" name="pathfinding_characters_menu_item"/>
+ <menu_item_call label="察看 / 測試…" name="pathfinding_console_menu_item"/>
+ <menu_item_call label="é‡æ–°ç”¢å‡ºåœ°å€" name="pathfinding_rebake_navmesh_item"/>
+ </menu>
<menu label="é¸é …" name="Options">
<menu_item_check label="顯示進階權é™" name="DebugPermissions"/>
<menu_item_check label="åªé¸å–我的物件" name="Select Only My Objects"/>
<menu_item_check label="åªé¸å–å¯ç§»å‹•çš„物件" name="Select Only Movable Objects"/>
- <menu_item_check label="Select By Surrounding" name="Select By Surrounding"/>
- <menu_item_check label="Show Selection Outlines" name="Show Selection Outlines"/>
- <menu_item_check label="Show Hidden Selection" name="Show Hidden Selection"/>
- <menu_item_check label="Show Light Radius for Selection" name="Show Light Radius for Selection"/>
- <menu_item_check label="Show Selection Beam" name="Show Selection Beam"/>
+ <menu_item_check label="環繞é¸å–" name="Select By Surrounding"/>
+ <menu_item_check label="顯示é¸å–輪廓線" name="Show Selection Outlines"/>
+ <menu_item_check label="顯示隱è—çš„é¸å–" name="Show Hidden Selection"/>
+ <menu_item_check label="顯示é¸æ“‡çš„ Light åŠå¾‘" name="Show Light Radius for Selection"/>
+ <menu_item_check label="顯示é¸æ“‡å°Žå¼•ç·š" name="Show Selection Beam"/>
<menu_item_check label="貼齊格線" name="Snap to Grid"/>
<menu_item_call label="貼齊物件 XY 軸到格線" name="Snap Object XY to Grid"/>
- <menu_item_call label="Use Selection for Grid" name="Use Selection for Grid"/>
+ <menu_item_call label="以所é¸æ“‡ä½œç‚ºæ ¼ç·š" name="Use Selection for Grid"/>
<menu_item_call label="格線é¸é …" name="Grid Options"/>
</menu>
<menu label="上傳" name="Upload">
<menu_item_call label="圖åƒï¼ˆL$[COST])..." name="Upload Image"/>
<menu_item_call label="è²éŸ³ï¼ˆL$[COST])..." name="Upload Sound"/>
<menu_item_call label="動作(L$[COST])..." name="Upload Animation"/>
- <menu_item_call label="大é‡ä¸Šå‚³ï¼ˆæ¯æª”案 L$[COST] )..." name="Bulk Upload"/>
+ <menu_item_call label="模型…" name="Upload Model"/>
+ <menu_item_call label="批é‡ï¼ˆæ¯æª”案 L$[COST] )..." name="Bulk Upload"/>
<menu_item_call label="設定é è¨­ä¸Šå‚³æ¬Šé™" name="perm prefs"/>
</menu>
<menu_item_call label="復原" name="Undo"/>
<menu_item_call label="é‡åš" name="Redo"/>
</menu>
<menu label="幫助" name="Help">
+ <menu_item_call label="簡易教學…" name="How To"/>
<menu_item_call label="[SECOND_LIFE] 幫助" name="Second Life Help"/>
- <menu_item_check label="啟用æ示" name="Enable Hints"/>
- <menu_item_call label="舉報濫用" name="Report Abuse"/>
+ <menu_item_call label="使用者指å—" name="User’s guide"/>
+ <menu_item_call label="知識庫" name="Knowledge Base"/>
+ <menu_item_call label="維基" name="Wiki"/>
+ <menu_item_call label="社群論壇" name="Community Forums"/>
+ <menu_item_call label="支æ´å…¥å£" name="Support portal"/>
+ <menu_item_call label="[SECOND_LIFE] 最新消æ¯" name="Second Life News"/>
+ <menu_item_call label="[SECOND_LIFE] 部è½æ ¼" name="Second Life Blogs"/>
+ <menu_item_call label="é•è¦èˆ‰å ±" name="Report Abuse"/>
<menu_item_call label="回報臭蟲" name="Report Bug"/>
<menu_item_call label="關於 [APP_NAME]" name="About Second Life"/>
</menu>
<menu label="進階" name="Advanced">
- <menu_item_call label="Rebake Textures" name="Rebake Texture"/>
- <menu_item_call label="設定使用者界é¢å¤§å°è‡³é è¨­å€¼" name="Set UI Size to Default"/>
- <menu_item_call label="設定視窗尺寸大å°..." name="Set Window Size..."/>
+ <menu_item_call label="é‡æ–°ç”¢å‡ºæ質" name="Rebake Texture"/>
+ <menu_item_call label="以é è¨­å€¼è¨­å®šä½¿ç”¨è€…ç•Œé¢å¤§å°" name="Set UI Size to Default"/>
+ <menu_item_call label="設定視窗大å°..." name="Set Window Size..."/>
<menu_item_check label="é™åˆ¶é¸æ“‡è·é›¢" name="Limit Select Distance"/>
- <menu_item_check label="Disable Camera Constraints" name="Disable Camera Distance"/>
+ <menu_item_check label="å–消é¡é ­é™åˆ¶" name="Disable Camera Distance"/>
<menu_item_check label="高解æžåº¦å¿«ç…§" name="HighResSnapshot"/>
<menu_item_check label="éœéŸ³æ‹æ”快照到硬碟" name="QuietSnapshotsToDisk"/>
- <menu_item_check label="壓縮快照存到硬碟" name="CompressSnapshotsToDisk"/>
<menu label="效能工具" name="Performance Tools">
- <menu_item_call label="Lag Meter" name="Lag Meter"/>
+ <menu_item_call label="Lag 測é‡å™¨" name="Lag Meter"/>
<menu_item_check label="統計列" name="Statistics Bar"/>
- <menu_item_check label="Show Avatar Rendering Cost" name="Avatar Rendering Cost"/>
+ <menu_item_check label="顯示化身的繪製é‡é‡" name="Avatar Rendering Cost"/>
</menu>
<menu label="高亮顯示與å¯è¦‹åº¦" name="Highlighting and Visibility">
- <menu_item_check label="Cheesy Beacon" name="Cheesy Beacon"/>
+ <menu_item_check label="Cheesy 指標" name="Cheesy Beacon"/>
<menu_item_check label="éš±è—ç²’å­æ•ˆæžœ" name="Hide Particles"/>
<menu_item_check label="éš±è—所é¸æ“‡çš„" name="Hide Selected"/>
<menu_item_check label="高亮顯示é€æ˜Žç‰©ä»¶" name="Highlight Transparent"/>
- <menu_item_check label="顯示 HUD 附件" name="Show HUD Attachments"/>
<menu_item_check label="顯示第一人稱視角準星" name="ShowCrosshairs"/>
</menu>
- <menu label="Rendering Types" name="Rendering Types">
+ <menu label="呈åƒé¡žåž‹" name="Rendering Types">
<menu_item_check label="ç°¡å–®" name="Rendering Type Simple"/>
<menu_item_check label="åŠé€æ˜Ž" name="Rendering Type Alpha"/>
<menu_item_check label="樹木" name="Rendering Type Tree"/>
<menu_item_check label="化身" name="Rendering Type Character"/>
- <menu_item_check label="地表" name="Rendering Type Surface Patch"/>
+ <menu_item_check label="表é¢ä¿®è£œ" name="Rendering Type Surface Patch"/>
<menu_item_check label="天空" name="Rendering Type Sky"/>
<menu_item_check label="æ°´æ–‡" name="Rendering Type Water"/>
<menu_item_check label="地é¢" name="Rendering Type Ground"/>
@@ -165,32 +210,32 @@
<menu_item_check label="ç²’å­æ•ˆæžœ" name="Rendering Type Particles"/>
<menu_item_check label="碰撞" name="Rendering Type Bump"/>
</menu>
- <menu label="Rendering Features" name="Rendering Features">
- <menu_item_check label="UI" name="ToggleUI"/>
- <menu_item_check label="Selected" name="Selected"/>
- <menu_item_check label="Highlighted" name="Highlighted"/>
- <menu_item_check label="Dynamic Textures" name="Dynamic Textures"/>
+ <menu label="呈åƒåŠŸèƒ½" name="Rendering Features">
+ <menu_item_check label="使用者界é¢" name="ToggleUI"/>
+ <menu_item_check label="é¸æ“‡" name="Selected"/>
+ <menu_item_check label="高亮顯示" name="Highlighted"/>
+ <menu_item_check label="å‹•æ…‹æ質" name="Dynamic Textures"/>
<menu_item_check label="腳步陰影" name="Foot Shadows"/>
<menu_item_check label="霧氣" name="Fog"/>
- <menu_item_check label="Test FRInfo" name="Test FRInfo"/>
+ <menu_item_check label="測試 FRInfo" name="Test FRInfo"/>
<menu_item_check label="彈性物件" name="Flexible Objects"/>
</menu>
<menu_item_check label="使用外å¦è®€å–ç·’" name="Use Plugin Read Thread"/>
<menu_item_call label="清除群組快å–資料" name="ClearGroupCache"/>
<menu_item_check label="滑鼠平滑移動" name="Mouse Smoothing"/>
+ <menu_item_call label="釋出按éµ" name="Release Keys"/>
<menu label="快速éµ" name="Shortcuts">
- <menu_item_call label="釋出按éµ" name="Release Keys"/>
<menu_item_check label="顯示進階é¸å–® ï¼ èˆŠç‰ˆæ·å¾‘" name="Show Advanced Menu - legacy shortcut"/>
<menu_item_call label="關閉視窗" name="Close Window"/>
<menu_item_call label="關閉全部視窗" name="Close All Windows"/>
<menu_item_call label="æ‹æ”快照到硬碟" name="Snapshot to Disk"/>
<menu_item_call label="第一人稱視角" name="Mouselook"/>
- <menu_item_check label="Joystick Flycam" name="Joystick Flycam"/>
+ <menu_item_check label="æ–桿移動æ”影機" name="Joystick Flycam"/>
<menu_item_call label="é‡è¨­è¦–角" name="Reset View"/>
<menu_item_call label="注視上一ä½èŠå¤©è€…" name="Look at Last Chatter"/>
- <menu_item_call label="Zoom In" name="Zoom In"/>
- <menu_item_call label="Zoom Default" name="Zoom Default"/>
- <menu_item_call label="Zoom Out" name="Zoom Out"/>
+ <menu_item_call label="放大" name="Zoom In"/>
+ <menu_item_call label="縮放æ¢å¾©é è¨­" name="Zoom Default"/>
+ <menu_item_call label="縮å°" name="Zoom Out"/>
</menu>
<menu_item_call label="顯示除錯設定" name="Debug Settings"/>
<menu_item_check label="顯示開發é¸å–®" name="Debug Mode"/>
@@ -200,25 +245,27 @@
<menu_item_check label="æ質控制å°" name="Texture Console"/>
<menu_item_check label="除錯控制å°" name="Debug Console"/>
<menu_item_call label="通知控制å°" name="Notifications"/>
- <menu_item_check label="æ質尺寸控制å°" name="Texture Size"/>
- <menu_item_check label="æ質分類控制å°" name="Texture Category"/>
<menu_item_check label="快速碼錶" name="Fast Timers"/>
<menu_item_check label="記憶體" name="Memory"/>
+ <menu_item_check label="場景統計資料" name="Scene Statistics"/>
+ <menu_item_call label="æ質擷å–除錯控制å°" name="Texture Fetch Debug Console"/>
<menu_item_call label="地å€è³‡è¨Šå‚³è‡³é™¤éŒ¯æŽ§åˆ¶å°" name="Region Info to Debug Console"/>
<menu_item_call label="群組資訊至除錯控制å°" name="Group Info to Debug Console"/>
- <menu_item_call label="Capabilities Info to Debug Console" name="Capabilities Info to Debug Console"/>
+ <menu_item_call label="性能資訊傳至除錯控制å°" name="Capabilities Info to Debug Console"/>
<menu_item_check label="æ”影機" name="Camera"/>
<menu_item_check label="風力" name="Wind"/>
- <menu_item_check label="FOV" name="FOV"/>
- <menu_item_check label="Badge" name="Badge"/>
+ <menu_item_check label="視角" name="FOV"/>
+ <menu_item_check label="勛章" name="Badge"/>
</menu>
<menu label="顯示資訊" name="Display Info">
<menu_item_check label="顯示時間" name="Show Time"/>
- <menu_item_check label="Show Render Info" name="Show Render Info"/>
+ <menu_item_check label="顯示上傳費用" name="Show Upload Cost"/>
+ <menu_item_check label="顯示呈åƒè³‡è¨Š" name="Show Render Info"/>
<menu_item_check label="顯示æ質資訊" name="Show Texture Info"/>
- <menu_item_check label="Show Matrices" name="Show Matrices"/>
- <menu_item_check label="Show Color Under Cursor" name="Show Color Under Cursor"/>
+ <menu_item_check label="顯示矩陣" name="Show Matrices"/>
+ <menu_item_check label="游標下顯示é¡è‰²" name="Show Color Under Cursor"/>
<menu_item_check label="顯示記憶體" name="Show Memory"/>
+ <menu_item_check label="顯示ç§å€è¨˜æ†¶é«”資訊" name="Show Private Mem Info"/>
<menu_item_check label="顯示更新到物件" name="Show Updates"/>
</menu>
<menu label="強制錯誤" name="Force Errors">
@@ -231,60 +278,72 @@
<menu_item_call label="強制ç€è¦½å™¨æ–·ç·š" name="Force Disconnect Viewer"/>
<menu_item_call label="模擬記憶體ä¸è¶³" name="Memory Leaking Simulation"/>
</menu>
- <menu label="Render Tests" name="Render Tests">
+ <menu label="呈åƒæ¸¬è©¦" name="Render Tests">
<menu_item_check label="æ”影機ä½ç§»" name="Camera Offset"/>
- <menu_item_check label="Randomize Framerate" name="Randomize Framerate"/>
- <menu_item_check label="Periodic Slow Frame" name="Periodic Slow Frame"/>
- <menu_item_check label="Frame Test" name="Frame Test"/>
- </menu>
- <menu label="Render Metadata" name="Render Metadata">
- <menu_item_check label="Bounding Boxes" name="Bounding Boxes"/>
- <menu_item_check label="Octree" name="Octree"/>
- <menu_item_check label="Shadow Frusta" name="Shadow Frusta"/>
- <menu_item_check label="Occlusion" name="Occlusion"/>
- <menu_item_check label="Render Batches" name="Render Batches"/>
- <menu_item_check label="Update Type" name="Update Type"/>
- <menu_item_check label="Texture Anim" name="Texture Anim"/>
- <menu_item_check label="Texture Priority" name="Texture Priority"/>
- <menu_item_check label="Texture Area" name="Texture Area"/>
- <menu_item_check label="Face Area" name="Face Area"/>
- <menu_item_check label="Lights" name="Lights"/>
- <menu_item_check label="Collision Skeleton" name="Collision Skeleton"/>
- <menu_item_check label="Raycast" name="Raycast"/>
- </menu>
- <menu label="Rendering" name="Rendering">
- <menu_item_check label="Axes" name="Axes"/>
- <menu_item_check label="Tangent Basis" name="Tangent Basis"/>
- <menu_item_call label="Selected Texture Info Basis" name="Selected Texture Info Basis"/>
- <menu_item_check label="Wireframe" name="Wireframe"/>
- <menu_item_check label="Object-Object Occlusion" name="Object-Object Occlusion"/>
- <menu_item_check label="Framebuffer Objects" name="Framebuffer Objects"/>
- <menu_item_check label="Lighting and Shadows" name="Lighting and Shadows"/>
- <menu_item_check label="Shadows from Sun/Moon/Projectors" name="Shadows from Sun/Moon/Projectors"/>
- <menu_item_check label="SSAO and Shadow Smoothing" name="SSAO and Shadow Smoothing"/>
- <menu_item_check label="Global Illumination (experimental)" name="Global Illumination"/>
+ <menu_item_check label="隨機變動幀率" name="Randomize Framerate"/>
+ <menu_item_check label="定期出ç¾æ…¢å¹€çŽ‡" name="Periodic Slow Frame"/>
+ <menu_item_check label="ç•«é¢æ¸¬è©¦" name="Frame Test"/>
+ <menu_item_call label="幀特性" name="Frame Profile"/>
+ </menu>
+ <menu label="呈åƒçš„元資料" name="Render Metadata">
+ <menu_item_check label="外框箱" name="Bounding Boxes"/>
+ <menu_item_check label="法線" name="Normals"/>
+ <menu_item_check label="å…«å‰æ¨¹" name="Octree"/>
+ <menu_item_check label="陰影平截頭體" name="Shadow Frusta"/>
+ <menu_item_check label="物ç†å½¢ç‹€" name="Physics Shapes"/>
+ <menu_item_check label="é®è”½" name="Occlusion"/>
+ <menu_item_check label="呈åƒæ‰¹æ¬¡" name="Render Batches"/>
+ <menu_item_check label="æ›´æ–°é¡žåž‹" name="Update Type"/>
+ <menu_item_check label="æ質動畫" name="Texture Anim"/>
+ <menu_item_check label="æ質優先åº" name="Texture Priority"/>
+ <menu_item_check label="æ質å€åŸŸ" name="Texture Area"/>
+ <menu_item_check label="臉å€åŸŸ" name="Face Area"/>
+ <menu_item_check label="細節層次資訊" name="LOD Info"/>
+ <menu_item_check label="建製佇列" name="Build Queue"/>
+ <menu_item_check label="燈光" name="Lights"/>
+ <menu_item_check label="碰撞骨架" name="Collision Skeleton"/>
+ <menu_item_check label="光線投射" name="Raycast"/>
+ <menu_item_check label="風力å‘é‡" name="Wind Vectors"/>
+ <menu_item_check label="繪出複雜度" name="rendercomplexity"/>
+ <menu_item_check label="附件ä½å…ƒçµ„" name="attachment bytes"/>
+ <menu_item_check label="雕刻" name="Sculpt"/>
+ <menu label="æ質密度" name="Texture Density">
+ <menu_item_check label="ç„¡" name="None"/>
+ <menu_item_check label="ç›®å‰" name="Current"/>
+ <menu_item_check label="ç†æƒ³" name="Desired"/>
+ <menu_item_check label="完全" name="Full"/>
+ </menu>
+ </menu>
+ <menu label="呈åƒ" name="Rendering">
+ <menu_item_check label="軸" name="Axes"/>
+ <menu_item_check label="切線基礎" name="Tangent Basis"/>
+ <menu_item_call label="å·²é¸å–æ質資訊基礎" name="Selected Texture Info Basis"/>
+ <menu_item_call label="所é¸æ料資訊" name="Selected Material Info"/>
+ <menu_item_check label="線框" name="Wireframe"/>
+ <menu_item_check label="物件導å‘çš„é®è”½" name="Object-Object Occlusion"/>
+ <menu_item_check label="進階照明模型" name="Advanced Lighting Model"/>
+ <menu_item_check label="來自日/月/投影物的陰影" name="Shadows from Sun/Moon/Projectors"/>
+ <menu_item_check label="å±å¹•ç©ºé–“環境光é®è”½å’Œé™°å½±å¹³æ»‘技術" name="SSAO and Shadow Smoothing"/>
<menu_item_check label="GL 除錯" name="Debug GL"/>
<menu_item_check label="管線除錯" name="Debug Pipeline"/>
<menu_item_check label="自動åŠé€æ˜Žé®ç½©ï¼ˆéžå»¶ï¼‰" name="Automatic Alpha Masks (deferred)"/>
<menu_item_check label="自動åŠé€æ˜Žé®ç½©ï¼ˆéžéžå»¶ï¼‰" name="Automatic Alpha Masks (non-deferred)"/>
- <menu_item_check label="Animation Textures" name="Animation Textures"/>
+ <menu_item_check label="動作æ質" name="Animation Textures"/>
<menu_item_check label="關閉æ質" name="Disable Textures"/>
- <menu_item_check label="Full Res Textures" name="Rull Res Textures"/>
- <menu_item_check label="Audit Textures" name="Audit Textures"/>
- <menu_item_check label="Texture Atlas (experimental)" name="Texture Atlas"/>
- <menu_item_check label="Render Attached Lights" name="Render Attached Lights"/>
- <menu_item_check label="Render Attached Particles" name="Render Attached Particles"/>
- <menu_item_check label="Hover Glow Objects" name="Hover Glow Objects"/>
+ <menu_item_check label="全解æžåº¦æ質" name="Rull Res Textures"/>
+ <menu_item_check label="使附著燈光呈åƒ" name="Render Attached Lights"/>
+ <menu_item_check label="使附著例å­æ•ˆæžœå‘ˆåƒ" name="Render Attached Particles"/>
+ <menu_item_check label="åœæ‡¸ç™¼å…‰ç‰©ä»¶" name="Hover Glow Objects"/>
</menu>
<menu label="網路" name="Network">
- <menu_item_check label="Pause Agent" name="AgentPause"/>
- <menu_item_call label="Enable Message Log" name="Enable Message Log"/>
- <menu_item_call label="Disable Message Log" name="Disable Message Log"/>
- <menu_item_check label="Velocity Interpolate Objects" name="Velocity Interpolate Objects"/>
- <menu_item_check label="Ping Interpolate Object Positions" name="Ping Interpolate Object Positions"/>
- <menu_item_call label="Drop a Packet" name="Drop a Packet"/>
- </menu>
- <menu_item_call label="Dump Scripted Camera" name="Dump Scripted Camera"/>
+ <menu_item_check label="æš«åœç”¨æˆ¶" name="AgentPause"/>
+ <menu_item_call label="啟用訊æ¯è¨˜éŒ„" name="Enable Message Log"/>
+ <menu_item_call label="åœç”¨è¨Šæ¯è¨˜éŒ„" name="Disable Message Log"/>
+ <menu_item_check label="速度內æ’物件" name="Velocity Interpolate Objects"/>
+ <menu_item_check label="探詢內æ’物件ä½ç½®" name="Ping Interpolate Object Positions"/>
+ <menu_item_call label="丟出一個å°åŒ…" name="Drop a Packet"/>
+ </menu>
+ <menu_item_call label="傾å°è…³æœ¬æŽ§åˆ¶çš„æ”影機" name="Dump Scripted Camera"/>
<menu_item_call label="碰撞ã€æŽ¨æ“ èˆ‡æ‰“æ“Š" name="Bumps, Pushes &amp;amp; Hits"/>
<menu label="錄製器" name="Recorder">
<menu_item_call label="開始播放" name="Start Playback"/>
@@ -298,24 +357,23 @@
<menu_item_check label="固定天氣" name="Fixed Weather"/>
<menu_item_call label="傾å°åœ°å€ç‰©ä»¶å¿«å–" name="Dump Region Object Cache"/>
</menu>
- <menu label="UI" name="UI">
- <menu_item_call label="測試媒體ç€è¦½å™¨" name="Web Browser Test"/>
+ <menu label="使用者界é¢" name="UI">
+ <menu_item_call label="媒體ç€è¦½å™¨æ¸¬è©¦" name="Web Browser Test"/>
<menu_item_call label="網é å…§å®¹ç€è¦½å™¨" name="Web Content Browser"/>
- <menu_item_call label="Dump SelectMgr" name="Dump SelectMgr"/>
+ <menu_item_call label="å‚¾å° SelectMgr" name="Dump SelectMgr"/>
<menu_item_call label="傾å°æ”¶ç´å€" name="Dump Inventory"/>
<menu_item_call label="傾å°ç¢¼éŒ¶" name="Dump Timers"/>
- <menu_item_call label="Dump Focus Holder" name="Dump Focus Holder"/>
- <menu_item_call label="Print Selected Object Info" name="Print Selected Object Info"/>
- <menu_item_call label="Print Agent Info" name="Print Agent Info"/>
- <menu_item_call label="計憶體狀態" name="Memory Stats"/>
- <menu_item_check label="Region Debug Console" name="Region Debug Console"/>
- <menu_item_check label="Debug SelectMgr" name="Debug SelectMgr"/>
- <menu_item_check label="Debug Clicks" name="Debug Clicks"/>
+ <menu_item_call label="傾å°ç„¦é»žå®¹å™¨" name="Dump Focus Holder"/>
+ <menu_item_call label="列å°æ‰€é¸ç‰©ä»¶è³‡è¨Š" name="Print Selected Object Info"/>
+ <menu_item_call label="列å°ç”¨æˆ¶è³‡è¨Š" name="Print Agent Info"/>
+ <menu_item_check label="地å€é™¤éŒ¯æŽ§åˆ¶å°" name="Region Debug Console"/>
+ <menu_item_check label="除錯 SelectMgr" name="Debug SelectMgr"/>
+ <menu_item_check label="除錯點按動作" name="Debug Clicks"/>
<menu_item_check label="視角除錯" name="Debug Views"/>
- <menu_item_check label="Debug Name Tooltips" name="Debug Name Tooltips"/>
+ <menu_item_check label="除錯å稱訊æ¯æ示" name="Debug Name Tooltips"/>
<menu_item_check label="滑鼠事件除錯" name="Debug Mouse Events"/>
<menu_item_check label="按éµé™¤éŒ¯" name="Debug Keys"/>
- <menu_item_check label="Debug WindowProc" name="Debug WindowProc"/>
+ <menu_item_check label="除錯 WindowProc" name="Debug WindowProc"/>
</menu>
<menu label="XUI" name="XUI">
<menu_item_call label="é‡æ–°è¼‰å…¥é¡è‰²è¨­å®š" name="Reload Color Settings"/>
@@ -325,67 +383,80 @@
<menu_item_call label="æ²–æ´—å稱快å–資料" name="Flush Names Caches"/>
</menu>
<menu label="化身" name="Character">
- <menu label="Grab Baked Texture" name="Grab Baked Texture">
- <menu_item_call label="Iris" name="Grab Iris"/>
+ <menu label="抓å–已產出æ質" name="Grab Baked Texture">
+ <menu_item_call label="虹膜" name="Grab Iris"/>
<menu_item_call label="頭部" name="Grab Head"/>
- <menu_item_call label="Upper Body" name="Grab Upper Body"/>
- <menu_item_call label="Lower Body" name="Grab Lower Body"/>
+ <menu_item_call label="上åŠèº«" name="Grab Upper Body"/>
+ <menu_item_call label="下åŠèº«" name="Grab Lower Body"/>
<menu_item_call label="裙å­" name="Grab Skirt"/>
</menu>
- <menu label="Character Tests" name="Character Tests">
- <menu_item_call label="Appearance To XML" name="Appearance To XML"/>
- <menu_item_call label="Toggle Character Geometry" name="Toggle Character Geometry"/>
+ <menu label="字元測試" name="Character Tests">
+ <menu_item_call label="å°‡å¤–è§€è½‰æˆ XML" name="Appearance To XML"/>
+ <menu_item_call label="切æ›å­—元幾何特性" name="Toggle Character Geometry"/>
<menu_item_call label="男性測試" name="Test Male"/>
<menu_item_call label="女性測試" name="Test Female"/>
- <menu_item_call label="PG 切æ›" name="Toggle PG"/>
<menu_item_check label="å…許é¸æ“‡åŒ–身" name="Allow Select Avatar"/>
</menu>
+ <menu label="動作速度" name="Animation Speed">
+ <menu_item_call label="所有動作加快 10%" name="All Animations 10 Faster"/>
+ <menu_item_call label="所有動作放慢 10%" name="All Animations 10 Slower"/>
+ <menu_item_call label="將所有動作æ¢å¾©åŽŸé€Ÿ" name="Reset All Animation Speed"/>
+ <menu_item_check label="慢動作" name="Slow Motion Animations"/>
+ </menu>
<menu_item_call label="強制åƒæ•¸ç‚ºé è¨­å€¼" name="Force Params to Default"/>
<menu_item_check label="動作資訊" name="Animation Info"/>
- <menu_item_check label="慢動作" name="Slow Motion Animations"/>
<menu_item_check label="顯示注視在" name="Show Look At"/>
<menu_item_check label="顯示指å‘在" name="Show Point At"/>
- <menu_item_check label="Debug Joint Updates" name="Debug Joint Updates"/>
- <menu_item_check label="Disable LOD" name="Disable LOD"/>
- <menu_item_check label="Debug Character Vis" name="Debug Character Vis"/>
- <menu_item_check label="Show Collision Skeleton" name="Show Collision Skeleton"/>
- <menu_item_check label="Display Agent Target" name="Display Agent Target"/>
+ <menu_item_check label="除錯旋軸的更新" name="Debug Joint Updates"/>
+ <menu_item_check label="åœç”¨ç´°ç¯€å±¤æ¬¡" name="Disable LOD"/>
+ <menu_item_check label="除錯字元å¯è¦‹æ€§" name="Debug Character Vis"/>
+ <menu_item_check label="顯示碰撞骨架" name="Show Collision Skeleton"/>
+ <menu_item_check label="顯示用戶目標" name="Display Agent Target"/>
--&gt;
- <menu_item_call label="Dump Attachments" name="Dump Attachments"/>
- <menu_item_call label="Debug Avatar Textures" name="Debug Avatar Textures"/>
- <menu_item_call label="Dump Local Textures" name="Dump Local Textures"/>
+ <menu_item_call label="傾å°é™„件" name="Dump Attachments"/>
+ <menu_item_call label="除錯化身æ質" name="Debug Avatar Textures"/>
+ <menu_item_call label="傾å°æœ¬åœ°æ質" name="Dump Local Textures"/>
</menu>
<menu_item_check label="HTTP æ質" name="HTTP Textures"/>
- <menu_item_call label="Compress Images" name="Compress Images"/>
- <menu_item_check label="Output Debug Minidump" name="Output Debug Minidump"/>
- <menu_item_check label="Console Window on next Run" name="Console Window"/>
- <menu_item_call label="Request Admin Status" name="Request Admin Options"/>
- <menu_item_call label="Leave Admin Status" name="Leave Admin Options"/>
- <menu_item_check label="Show Admin Menu" name="View Admin Options"/>
+ <menu_item_check label="HTTP 收ç´å€" name="HTTP Inventory"/>
+ <menu_item_call label="壓縮圖åƒ" name="Compress Images"/>
+ <menu_item_call label="啟用記憶體洩æ¼è¦–覺åµæ¸¬å™¨" name="Enable Visual Leak Detector"/>
+ <menu_item_check label="輸出除錯å°åž‹å‚¾å°" name="Output Debug Minidump"/>
+ <menu_item_check label="下次執行時顯示控制å°è¦–窗" name="Console Window"/>
+ <menu label="設定記錄細節" name="Set Logging Level">
+ <menu_item_check label="除錯" name="Debug"/>
+ <menu_item_check label="資訊" name="Info"/>
+ <menu_item_check label="警告" name="Warning"/>
+ <menu_item_check label="錯誤" name="Error"/>
+ <menu_item_check label="ç„¡" name="None"/>
+ </menu>
+ <menu_item_call label="è¦æ±‚管ç†å“¡ç‹€æ…‹" name="Request Admin Options"/>
+ <menu_item_call label="離開管ç†å“¡ç‹€æ…‹" name="Leave Admin Options"/>
+ <menu_item_check label="顯示管ç†å“¡é¸å–®" name="View Admin Options"/>
</menu>
- <menu label="Admin" name="Admin">
- <menu label="Object" name="AdminObject">
+ <menu label="管ç†å“¡" name="Admin">
+ <menu label="物件" name="AdminObject">
<menu_item_call label="å–得副本" name="Admin Take Copy"/>
- <menu_item_call label="強制æ“有者為我" name="Force Owner To Me"/>
- <menu_item_call label="Force Owner Permissive" name="Force Owner Permissive"/>
+ <menu_item_call label="將所有人強設為我自己" name="Force Owner To Me"/>
+ <menu_item_call label="強設為「准許所有人ã€" name="Force Owner Permissive"/>
<menu_item_call label="刪除" name="Delete"/>
- <menu_item_call label="Lock" name="Lock"/>
- <menu_item_call label="Get Assets IDs" name="Get Assets IDs"/>
+ <menu_item_call label="鎖定" name="Lock"/>
+ <menu_item_call label="å–得資產 ID" name="Get Assets IDs"/>
</menu>
<menu label="地段" name="Parcel">
- <menu_item_call label="強制æ“有者為我" name="Owner To Me"/>
- <menu_item_call label="Set to Linden Content" name="Set to Linden Content"/>
- <menu_item_call label="Claim Public Land" name="Claim Public Land"/>
+ <menu_item_call label="將所有人強設為我自己" name="Owner To Me"/>
+ <menu_item_call label="設為 Linden 內容" name="Set to Linden Content"/>
+ <menu_item_call label="收å–公共地" name="Claim Public Land"/>
</menu>
<menu label="地å€" name="Region">
- <menu_item_call label="Dump Temp Asset Data" name="Dump Temp Asset Data"/>
- <menu_item_call label="Save Region State" name="Save Region State"/>
+ <menu_item_call label="傾å°æš«ç”¨è³‡ç”¢è³‡æ–™" name="Dump Temp Asset Data"/>
+ <menu_item_call label="儲存å€åŸŸç‹€æ…‹" name="Save Region State"/>
</menu>
- <menu_item_call label="God Tools" name="God Tools"/>
+ <menu_item_call label="神之工具" name="God Tools"/>
</menu>
- <menu label="Admin" name="Deprecated">
- <menu label="Attach Object" name="Attach Object"/>
- <menu label="Detach Object" name="Detach Object"/>
+ <menu label="管ç†å“¡" name="Deprecated">
+ <menu label="附著物件" name="Attach Object"/>
+ <menu label="å¸åŽ»ç‰©ä»¶" name="Detach Object"/>
<menu label="脫下æœè£" name="Take Off Clothing">
<menu_item_call label="襯衫" name="Shirt"/>
<menu_item_call label="褲å­" name="Pants"/>
@@ -403,13 +474,13 @@
</menu>
<menu label="幫助" name="DeprecatedHelp">
<menu_item_call label="林登官方部è½æ ¼" name="Official Linden Blog"/>
- <menu_item_call label="Scripting Portal" name="Scripting Portal"/>
+ <menu_item_call label="腳本門戶" name="Scripting Portal"/>
<menu label="臭蟲回報" name="Bug Reporting">
- <menu_item_call label="Public Issue Tracker" name="Public Issue Tracker"/>
- <menu_item_call label="Public Issue Tracker Help" name="Publc Issue Tracker Help"/>
+ <menu_item_call label="大眾å•é¡Œå應追蹤處" name="Public Issue Tracker"/>
+ <menu_item_call label="大眾å•é¡Œå應追蹤處幫助" name="Publc Issue Tracker Help"/>
<menu_item_call label="臭蟲回報 101" name="Bug Reporing 101"/>
- <menu_item_call label="Security Issues" name="Security Issues"/>
- <menu_item_call label="QA Wiki" name="QA Wiki"/>
+ <menu_item_call label="安全å•é¡Œ" name="Security Issues"/>
+ <menu_item_call label="å“管維基" name="QA Wiki"/>
</menu>
</menu>
</menu>
diff --git a/indra/newview/skins/default/xui/zh/menu_wearable_list_item.xml b/indra/newview/skins/default/xui/zh/menu_wearable_list_item.xml
index 2eea314dd8..576f7f3b73 100644..100755
--- a/indra/newview/skins/default/xui/zh/menu_wearable_list_item.xml
+++ b/indra/newview/skins/default/xui/zh/menu_wearable_list_item.xml
@@ -1,12 +1,12 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Outfit Wearable Context Menu">
<menu_item_call label="å–代" name="wear_replace"/>
- <menu_item_call label="Wear" name="wear_wear"/>
+ <menu_item_call label="穿上" name="wear_wear"/>
<menu_item_call label="添加" name="wear_add"/>
- <menu_item_call label="Take Off / Detach" name="take_off_or_detach"/>
+ <menu_item_call label="脫下è£æ‰® / å¸é™¤é™„件" name="take_off_or_detach"/>
<menu_item_call label="å¸ä¸‹" name="detach"/>
- <context_menu label="Attach to" name="wearable_attach_to"/>
- <context_menu label="Attach to HUD" name="wearable_attach_to_hud"/>
+ <context_menu label="附著到..." name="wearable_attach_to"/>
+ <context_menu label="附著到擡頭顯示" name="wearable_attach_to_hud"/>
<menu_item_call label="脫下" name="take_off"/>
<menu_item_call label="編輯" name="edit"/>
<menu_item_call label="物å“檔案" name="object_profile"/>
diff --git a/indra/newview/skins/default/xui/zh/menu_wearing_gear.xml b/indra/newview/skins/default/xui/zh/menu_wearing_gear.xml
index d9f4acb27b..6184f956d1 100644..100755
--- a/indra/newview/skins/default/xui/zh/menu_wearing_gear.xml
+++ b/indra/newview/skins/default/xui/zh/menu_wearing_gear.xml
@@ -2,4 +2,5 @@
<toggleable_menu name="Gear Wearing">
<menu_item_call label="編輯è£æ‰®" name="edit"/>
<menu_item_call label="脫下" name="takeoff"/>
+ <menu_item_call label="複製è£æ‰®æ¸…單到剪貼簿" name="copy"/>
</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/zh/menu_wearing_tab.xml b/indra/newview/skins/default/xui/zh/menu_wearing_tab.xml
index c7d2853995..c7d2853995 100644..100755
--- a/indra/newview/skins/default/xui/zh/menu_wearing_tab.xml
+++ b/indra/newview/skins/default/xui/zh/menu_wearing_tab.xml
diff --git a/indra/newview/skins/default/xui/zh/mime_types.xml b/indra/newview/skins/default/xui/zh/mime_types.xml
index 8ac1bf6920..70af2d2f19 100644..100755
--- a/indra/newview/skins/default/xui/zh/mime_types.xml
+++ b/indra/newview/skins/default/xui/zh/mime_types.xml
@@ -5,7 +5,7 @@
網é å…§å®¹
</label>
<tooltip name="web_tooltip">
- 這ä½ç½®æœ‰ç¶²é å…§å®¹
+ 這個ä½ç½®æœ‰ç¶²é å…§å®¹
</tooltip>
<playtip name="web_playtip">
顯示網é å…§å®¹
@@ -41,7 +41,7 @@
有一個音頻在此ä½ç½®
</tooltip>
<playtip name="audio_playtip">
- 播放這個硾的音頻
+ 播放這個ä½ç½®çš„音頻
</playtip>
</widgetset>
<scheme name="rtsp">
@@ -66,7 +66,7 @@
</mimetype>
<mimetype name="video/*">
<label name="video2_label">
- 視頻
+ 影片
</label>
</mimetype>
<mimetype name="image/*">
@@ -111,7 +111,7 @@
</mimetype>
<mimetype name="application/xhtml+xml">
<label name="application/xhtml+xml_label">
- é¸é …(XHTML)
+ 網é ï¼ˆXHTML)
</label>
</mimetype>
<mimetype name="application/x-director">
@@ -171,7 +171,7 @@
</mimetype>
<mimetype name="text/html">
<label name="text/html_label">
- é¸é …
+ 網é 
</label>
</mimetype>
<mimetype name="text/plain">
diff --git a/indra/newview/skins/default/xui/zh/mime_types_linux.xml b/indra/newview/skins/default/xui/zh/mime_types_linux.xml
index 90f17b841c..70af2d2f19 100644..100755
--- a/indra/newview/skins/default/xui/zh/mime_types_linux.xml
+++ b/indra/newview/skins/default/xui/zh/mime_types_linux.xml
@@ -5,7 +5,7 @@
網é å…§å®¹
</label>
<tooltip name="web_tooltip">
- This location has Web content
+ 這個ä½ç½®æœ‰ç¶²é å…§å®¹
</tooltip>
<playtip name="web_playtip">
顯示網é å…§å®¹
@@ -27,7 +27,7 @@
圖åƒ
</label>
<tooltip name="image_tooltip">
- There is an image at this location
+ 有一個圖åƒåœ¨æ­¤ä½ç½®
</tooltip>
<playtip name="image_playtip">
察看這個ä½ç½®çš„圖åƒ
@@ -106,12 +106,12 @@
</mimetype>
<mimetype name="application/smil">
<label name="application/smil_label">
- Synchronized Multimedia Integration Language (SMIL)
+ åŒæ­¥å¤šåª’體整åˆèªžè¨€ï¼ˆSMIL)
</label>
</mimetype>
<mimetype name="application/xhtml+xml">
<label name="application/xhtml+xml_label">
- é¸é …(XHTML)
+ 網é ï¼ˆXHTML)
</label>
</mimetype>
<mimetype name="application/x-director">
@@ -171,7 +171,7 @@
</mimetype>
<mimetype name="text/html">
<label name="text/html_label">
- é¸é …
+ 網é 
</label>
</mimetype>
<mimetype name="text/plain">
diff --git a/indra/newview/skins/default/xui/zh/mime_types_mac.xml b/indra/newview/skins/default/xui/zh/mime_types_mac.xml
index b8105c145c..70af2d2f19 100644..100755
--- a/indra/newview/skins/default/xui/zh/mime_types_mac.xml
+++ b/indra/newview/skins/default/xui/zh/mime_types_mac.xml
@@ -30,7 +30,7 @@
有一個圖åƒåœ¨æ­¤ä½ç½®
</tooltip>
<playtip name="image_playtip">
- 察看在此ä½ç½®çš„圖åƒ
+ 察看這個ä½ç½®çš„圖åƒ
</playtip>
</widgetset>
<widgetset name="audio">
@@ -41,7 +41,7 @@
有一個音頻在此ä½ç½®
</tooltip>
<playtip name="audio_playtip">
- 播放在此ä½ç½®çš„音頻
+ 播放這個ä½ç½®çš„音頻
</playtip>
</widgetset>
<scheme name="rtsp">
@@ -66,7 +66,7 @@
</mimetype>
<mimetype name="video/*">
<label name="video2_label">
- 視頻
+ 影片
</label>
</mimetype>
<mimetype name="image/*">
@@ -76,7 +76,7 @@
</mimetype>
<mimetype name="video/vnd.secondlife.qt.legacy">
<label name="vnd.secondlife.qt.legacy_label">
- 視頻 (QuickTime)
+ 視頻(QuickTime)
</label>
</mimetype>
<mimetype name="application/javascript">
@@ -86,7 +86,7 @@
</mimetype>
<mimetype name="application/ogg">
<label name="application/ogg_label">
- OGG 音頻/視頻
+ Ogg 音頻/視頻
</label>
</mimetype>
<mimetype name="application/pdf">
@@ -121,7 +121,7 @@
</mimetype>
<mimetype name="audio/mid">
<label name="audio/mid_label">
- 音頻 (MIDI)
+ 音頻(MIDI)
</label>
</mimetype>
<mimetype name="audio/mpeg">
diff --git a/indra/newview/skins/default/xui/zh/notifications.xml b/indra/newview/skins/default/xui/zh/notifications.xml
index 3fa8ff3f78..864f20fc15 100644..100755
--- a/indra/newview/skins/default/xui/zh/notifications.xml
+++ b/indra/newview/skins/default/xui/zh/notifications.xml
@@ -37,6 +37,12 @@
<button name="Help" text="$helptext"/>
</form>
</template>
+ <template name="okhelpignore">
+ <form>
+ <button name="OK_okhelpignore" text="$yestext"/>
+ <button name="Help_okhelpignore" text="$helptext"/>
+ </form>
+ </template>
<template name="yesnocancelbuttons">
<form>
<button name="Yes" text="$yestext"/>
@@ -45,19 +51,19 @@
</form>
</template>
<notification label="未知的通知訊æ¯" name="MissingAlert">
- Your version of [APP_NAME] does not know how to display the notification it just received. Please verify that you have the latest Viewer installed.
+ ä½ çš„ [APP_NAME] 版本無法顯示它剛剛收到的通知。 請確定你安è£äº†æœ€æ–°ç‰ˆæœ¬çš„ Viewer。
-Error details: The notification called &apos;[_NAME]&apos; was not found in notifications.xml.
+錯誤詳情:在 notifications.xml 裡找ä¸åˆ°å為「[_NAME]ã€çš„通知。
<usetemplate name="okbutton" yestext="確定"/>
</notification>
<notification name="FloaterNotFound">
- Floater error: Could not find the following controls:
+ 浮動視窗錯誤:找ä¸åˆ°ä»¥ä¸‹çš„控制:
[CONTROLS]
<usetemplate name="okbutton" yestext="確定"/>
</notification>
<notification name="TutorialNotFound">
- No tutorial is currently available.
+ ç›®å‰å°šç„¡æ•™å­¸å…§å®¹ã€‚
<usetemplate name="okbutton" yestext="確定"/>
</notification>
<notification name="GenericAlert">
@@ -68,67 +74,101 @@ Error details: The notification called &apos;[_NAME]&apos; was not found in noti
<usetemplate name="okcancelbuttons" notext="å–消" yestext="是"/>
</notification>
<notification name="BadInstallation">
- An error occurred while updating [APP_NAME]. Please [http://get.secondlife.com download the latest version] of the Viewer.
+ [APP_NAME] 更新時出錯。 請 [http://get.secondlife.com 下載] 最新版本的 Viewer。
<usetemplate name="okbutton" yestext="確定"/>
</notification>
<notification name="LoginFailedNoNetwork">
- 無法連接到[SECOND_LIFE_GRID].
- &apos;[DIAGNOSTIC]&apos;
-請確定你的網際網路是正常é‹ä½œçš„。
+ 無法連接到 [SECOND_LIFE_GRID]。
+ ([DIAGNOSTIC])
+請確定你的網路連線沒有å•é¡Œã€‚
<usetemplate name="okbutton" yestext="確定"/>
</notification>
<notification name="MessageTemplateNotFound">
- Message Template [PATH] not found.
+ 找ä¸åˆ°è¨Šæ¯æ¨¡æ¿ [PATH]。
<usetemplate name="okbutton" yestext="確定"/>
</notification>
<notification name="WearableSave">
除存變更到目å‰çš„è¡£æœ/身體部ä½ï¼Ÿ
<usetemplate canceltext="å–消" name="yesnocancelbuttons" notext="ä¸è¦å„²å­˜" yestext="儲存"/>
</notification>
+ <notification name="ConfirmNoCopyToOutbox">
+ 你無權將至少一件物項複製到第二人生購物市集的發件匣。 ä½ å¯ä»¥ç§»å‹•é€™äº›ç‰©é …,或ä¿ç•™ä¸å‹•ã€‚
+ <usetemplate name="okcancelbuttons" notext="ä¿ç•™ä¸ç§»å‹•ç‰©é …" yestext="移動物項"/>
+ </notification>
+ <notification name="OutboxFolderCreated">
+ 已經為你所轉移到商家發件匣頂層的æ¯ä¸€å€‹ç‰©é …,å„自建立了一個新資料夾。
+ <usetemplate ignoretext="商家發件匣裡æˆåŠŸå»ºç«‹äº†ä¸€å€‹æ–°è³‡æ–™å¤¾" name="okignore" yestext="確定"/>
+ </notification>
+ <notification name="OutboxImportComplete">
+ æˆåŠŸ
+
+所有資料夾已æˆåŠŸé€å¾€ç¬¬äºŒäººç”Ÿè³¼ç‰©å¸‚集。
+ <usetemplate ignoretext="所有資料夾已é€å¾€ç¬¬äºŒäººç”Ÿè³¼ç‰©å¸‚集" name="okignore" yestext="確定"/>
+ </notification>
+ <notification name="OutboxImportHadErrors">
+ 一部分的資料夾無法轉移
+
+將一部分資料夾é€å¾€ç¬¬äºŒäººç”Ÿè³¼ç‰©å¸‚集時出錯。 這些資料夾ä»åœ¨ä½ çš„商家發件匣。
+
+詳情請åƒé–±[[MARKETPLACE_IMPORTS_URL]錯誤記錄]。
+ <usetemplate name="okbutton" yestext="確定"/>
+ </notification>
+ <notification name="OutboxImportFailed">
+ 轉移失敗
+
+未將任何資料夾é€å¾€ç¬¬äºŒäººç”Ÿè³¼ç‰©å¸‚集,系統或網路出錯。 è«‹ç¨å€™å†è©¦ä¸€æ¬¡ã€‚
+ <usetemplate name="okbutton" yestext="確定"/>
+ </notification>
+ <notification name="OutboxInitFailed">
+ 第二人生購物市集åˆå§‹åŒ–失敗
+
+第二人生購物市集åˆå§‹åŒ–失敗,系統或網路出錯。 è«‹ç¨å€™å†è©¦ä¸€æ¬¡ã€‚
+ <usetemplate name="okbutton" yestext="確定"/>
+ </notification>
<notification name="CompileQueueSaveText">
- There was a problem uploading the text for a script due to the following reason: [REASON]. Please try again later.
+ 上傳腳本文字時出å•é¡Œï¼ŒåŽŸå› ï¼š[REASON]。 è«‹ç¨å€™å†è©¦ä¸€æ¬¡ã€‚
</notification>
<notification name="CompileQueueSaveBytecode">
- There was a problem uploading the compiled script due to the following reason: [REASON]. Please try again later.
+ 上傳已編譯腳本時出å•é¡Œï¼ŒåŽŸå› ï¼š[REASON]。 è«‹ç¨å€™å†è©¦ä¸€æ¬¡ã€‚
</notification>
<notification name="WriteAnimationFail">
- There was a problem writing animation data. Please try again later.
+ 寫入動作資料時出錯。 è«‹ç¨å€™å†è©¦ä¸€æ¬¡ã€‚
</notification>
<notification name="UploadAuctionSnapshotFail">
- There was a problem uploading the auction snapshot due to the following reason: [REASON]
+ 上傳æ‹è³£å¿«ç…§æ™‚出å•é¡Œï¼ŒåŽŸå› ï¼š[REASON]
</notification>
<notification name="UnableToViewContentsMoreThanOne">
- Unable to view the contents of more than one item at a time.
-Please select only one object and try again.
+ 無法一次ç€è¦½å¤šå€‹é …目的內容。
+è«‹åªé¸æ“‡ä¸€å€‹ç‰©ä»¶ï¼Œå†è©¦ä¸€æ¬¡ã€‚
</notification>
<notification name="SaveClothingBodyChanges">
儲存全部æœè£æˆ–身體部ä½çš„變更?
<usetemplate canceltext="å–消" name="yesnocancelbuttons" notext="ä¸è¦å„²å­˜" yestext="全部儲存"/>
</notification>
<notification name="FriendsAndGroupsOnly">
- Non-friends won&apos;t know that you&apos;ve choosen to ignore their calls and instant messages.
+ ä¸æ˜¯æœ‹å‹çš„人ä¸æœƒçŸ¥é“ä½ é¸æ“‡å¿½ç•¥ä»–們的通話è¦æ±‚å’Œå³æ™‚訊æ¯ã€‚
<usetemplate name="okbutton" yestext="確定"/>
</notification>
<notification name="FavoritesOnLogin">
- Note: When you turn on this option, anyone who uses this computer can see your list of favorite locations.
+ 注æ„:你一旦åŒæ„這é¸é …,任何使用這部電腦的人都å¯çœ‹åˆ°ä½ æœ‰å“ªäº›ã€Œæœ€æ„›ã€åœ°é»žã€‚
<usetemplate name="okbutton" yestext="確定"/>
</notification>
<notification name="GrantModifyRights">
- Granting modify rights to another Resident allows them to change, delete or take ANY objects you may have in-world. Be VERY careful when handing out this permission.
-Do you want to grant modify rights for [NAME]?
- <usetemplate name="okcancelbuttons" notext="No" yestext="是"/>
+ 賦予å¦ä¸€å±…民「修改ã€æ¬Šï¼Œå°‡å…許他更改ã€åˆªé™¤æˆ–æ‹¿å–你在虛擬世界裡æ“有的任何物件。 賦予這項權é™æ™‚,敬請慎é‡è€ƒæ…®ã€‚
+ä½ ä»è¦è³¦äºˆ [NAME] 修改權嗎?
+ <usetemplate name="okcancelbuttons" notext="å¦" yestext="是"/>
</notification>
<notification name="GrantModifyRightsMultiple">
- Granting modify rights to another Resident allows them to change ANY objects you may have in-world. Be VERY careful when handing out this permission.
-Do you want to grant modify rights for the selected Residents?
+ 賦予å¦ä¸€å±…民「修改ã€æ¬Šï¼Œå°‡å…許他更改你在虛擬世界裡æ“有的任何物件。 賦予這項權é™æ™‚,敬請慎é‡è€ƒæ…®ã€‚
+ä½ ä»è¦å°‡ä¿®æ”¹æ¬Šè³¦äºˆæ‰€é¸å±…æ°‘å—Ž?
<usetemplate name="okcancelbuttons" notext="å¦" yestext="是"/>
</notification>
<notification name="RevokeModifyRights">
- Do you want to revoke modify rights for [NAME]?
+ ä½ è¦æ’¤éŠ· [NAME] 的修改權嗎?
<usetemplate name="okcancelbuttons" notext="å¦" yestext="是"/>
</notification>
<notification name="RevokeModifyRightsMultiple">
- Do you want to revoke modify rights for the selected Residents?
+ ä½ è¦æ’¤éŠ·æ‰€é¸å±…民的修改權嗎?
<usetemplate name="okcancelbuttons" notext="å¦" yestext="是"/>
</notification>
<notification name="UnableToCreateGroup">
@@ -146,33 +186,41 @@ Do you want to grant modify rights for the selected Residents?
<usetemplate name="okbutton" yestext="確定"/>
</notification>
<notification name="AddGroupOwnerWarning">
- You are about to add group members to the role of [ROLE_NAME].
-Members cannot be removed from that role.
-The members must resign from the role themselves.
-Are you sure you want to continue?
- <usetemplate ignoretext="在我添加一個新的群組æ“有者å‰ç¢ºèª" name="okcancelignore" notext="å¦" yestext="是"/>
+ ä½ å³å°‡è³¦äºˆç¾¤çµ„æˆå“¡ [ROLE_NAME] 的角色。
+æˆå“¡ä¸€æ—¦ç²å¾—此角色,你就ä¸èƒ½è‡ªè¡Œæ’¤éŠ·ã€‚
+æˆå“¡å¿…須自行離è·æ‰èƒ½æ’¤éŠ·é€™è§’色。
+你確定你è¦ç¹¼çºŒï¼Ÿ
+ <usetemplate ignoretext="在我添加一個新的群組所有人å‰å†æ¬¡ç¢ºèª" name="okcancelignore" notext="å¦" yestext="是"/>
</notification>
<notification name="AssignDangerousActionWarning">
- You are about to add the Ability &apos;[ACTION_NAME]&apos; to the Role &apos;[ROLE_NAME]&apos;.
+ ä½ å³å°‡æŠŠã€Œ[ACTION_NAME]ã€èƒ½åŠ›å¢žåŠ çµ¦ã€Œ[ROLE_NAME]ã€è§’色。
- *WARNING*
- Any Member in a Role with this Ability can assign themselves -- and any other member -- to Roles that have more powers than they currently have, potentially elevating themselves to near-Owner power. Be sure you know what you&apos;re doing before assigning this Ability.
+ *警告*
+ 任何屬於帶有這能力的角色的æˆå“¡ï¼Œéƒ½å¯ä»¥è³¦äºˆè‡ªå·±æˆ–任何人新的角色,因此得到比ç¾åœ¨æ›´å¤šçš„權力,最終å¯èƒ½æ“有近似「所有人ã€çš„權力。 賦予這項能力之å‰ï¼Œæ•¬è«‹æ…Žé‡è€ƒæ…®ã€‚
-Add this Ability to &apos;[ROLE_NAME]&apos;?
+ä½ ä»è¦æ–°å¢žé€™é …能力給「[ROLE_NAME]ã€ï¼Ÿ
<usetemplate name="okcancelbuttons" notext="å¦" yestext="是"/>
</notification>
<notification name="AssignDangerousAbilityWarning">
- You are about to add the Ability &apos;[ACTION_NAME]&apos; to the Role &apos;[ROLE_NAME]&apos;.
+ ä½ å³å°‡æŠŠã€Œ[ACTION_NAME]ã€èƒ½åŠ›å¢žåŠ çµ¦ã€Œ[ROLE_NAME]ã€è§’色。
- *WARNING*
- Any Member in a Role with this Ability can assign themselves -- and any other member -- all Abilities, elevating themselves to near-Owner power.
+ *警告*
+ 任何屬於帶有這能力的角色的æˆå“¡ï¼Œéƒ½å¯ä»¥å°‡æ‰€æœ‰èƒ½åŠ›è³¦äºˆè‡ªå·±æˆ–任何人,æå‡ç‚ºè¿‘似「所有人ã€æ¬ŠåŠ›çš„層級。
-Add this Ability to &apos;[ROLE_NAME]&apos;?
+ä½ ä»è¦æ–°å¢žé€™é …能力給「[ROLE_NAME]ã€ï¼Ÿ
<usetemplate name="okcancelbuttons" notext="å¦" yestext="是"/>
</notification>
+ <notification name="EjectGroupMemberWarning">
+ ä½ å³å°‡æŠŠ [AVATAR_NAME] 踢出群組。
+ <usetemplate ignoretext="確定將æŸäººè¸¢å‡ºç¾¤çµ„" name="okcancelignore" notext="å–消" yestext="踢出"/>
+ </notification>
+ <notification name="EjectGroupMembersWarning">
+ ä½ å³å°‡æŠŠ [COUNT] 個人踢出群組。
+ <usetemplate ignoretext="確定將多人踢出群組" name="okcancelignore" notext="å–消" yestext="踢出"/>
+ </notification>
<notification name="AttachmentDrop">
- You are about to drop your attachment.
- Are you sure you want to continue?
+ ä½ å³å°‡å¸é™¤ä½ çš„附件。
+ 你確定你è¦ç¹¼çºŒï¼Ÿ
<usetemplate ignoretext="在丟下附件å‰ç¢ºèª" name="okcancelignore" notext="å¦" yestext="是"/>
</notification>
<notification name="JoinGroupCanAfford">
@@ -181,178 +229,184 @@ Add this Ability to &apos;[ROLE_NAME]&apos;?
<usetemplate name="okcancelbuttons" notext="å–消" yestext="加入"/>
</notification>
<notification name="JoinGroupNoCost">
- You are joining group [NAME].
-Do you wish to proceed?
+ ä½ å³å°‡åŠ å…¥ [NAME] 群組。
+你確定è¦ç¹¼çºŒå—Žï¼Ÿ
<usetemplate name="okcancelbuttons" notext="å–消" yestext="加入"/>
</notification>
<notification name="JoinGroupCannotAfford">
- Joining this group costs L$[COST].
-You do not have enough L$ to join this group.
+ 加入此群組須花費 L$[COST]。
+ä½ çš„ L$ ä¸å¤ åŠ å…¥é€™ç¾¤çµ„。
</notification>
<notification name="CreateGroupCost">
- Creating this group will cost L$100.
-Groups need more than one member, or they are deleted forever.
-Please invite members within 48 hours.
+ 創立這個群組費用為 L$100。
+群組需有至少兩ä½æˆå“¡ï¼Œå¦å‰‡å°‡æ°¸ä¹…被刪除。
+請在 48 å°æ™‚內邀請æˆå“¡åŠ å…¥ã€‚
<usetemplate canceltext="å–消" name="okcancelbuttons" notext="å–消" yestext="花費 L$100 建立群組"/>
</notification>
<notification name="LandBuyPass">
- For L$[COST] you can enter this land (&apos;[PARCEL_NAME]&apos;) for [TIME] hours. Buy a pass?
+ 花費 L$[COST],å¯é€²å…¥ã€Œ[PARCEL_NAME]ã€åœŸåœ°ï¼Œåœç•™ [TIME] å°æ™‚。 購買通行權?
<usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/>
</notification>
<notification name="SalePriceRestriction">
- Sale price must be set to more than L$0 if selling to anyone.
-Please select an individual to sell to if selling for L$0.
+ è‹¥æ˜¯å‡ºå”®çµ¦ä»»ä½•äººï¼Œå”®åƒ¹å¿…é ˆè¶…éŽ L$0。
+如果售價定為 L$0,請é¸å®šä¸€ä½å‡ºå”®å°è±¡ã€‚
</notification>
<notification name="ConfirmLandSaleChange">
- The selected [LAND_SIZE] m² land is being set for sale.
-Your selling price will be L$[SALE_PRICE] and will be authorized for sale to [NAME].
+ 所é¸çš„ [LAND_SIZE] 平方公尺土地å³å°‡æº–備出售。
+售價將為 L$[SALE_PRICE],並將經你授權出售給 [NAME]。
<usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/>
</notification>
<notification name="ConfirmLandSaleToAnyoneChange">
- ATTENTION: Clicking &apos;sell to anyone&apos; makes your land available to the entire [SECOND_LIFE] community, even those not in this region.
+ 請注æ„:若點按「出售給任何人ã€ï¼Œä½ çš„土地將å…許整個 [SECOND_LIFE] 社群å‰ä¾†è³¼è²·ï¼ŒåŒ…括此地å€å¤–的人。
-The selected [LAND_SIZE] m² land is being set for sale.
-Your selling price will be L$[SALE_PRICE] and will be authorized for sale to [NAME].
+所é¸çš„ [LAND_SIZE] 平方公尺土地å³å°‡æº–備出售。
+售價將為 L$[SALE_PRICE],並將經你授權出售給 [NAME]。
<usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/>
</notification>
<notification name="ReturnObjectsDeededToGroup">
- Are you sure you want to return all objects shared with the group &apos;[NAME]&apos; on this parcel of land back to their previous owner&apos;s inventory?
+ 你確定è¦å°‡å’Œæœ¬åœŸåœ°åœ°æ®µçš„「[NAME]ã€ç¾¤çµ„分享的所有物件é€è¿”到原所有人的收ç´å€ï¼Ÿ
-*WARNING* This will delete the non-transferable objects deeded to the group!
+警告:這動作將會刪除原先讓渡給這群組的所有ä¸å¯è½‰è®“物件ï¼
-Objects: [N]
+物件:[N]
<usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/>
</notification>
<notification name="ReturnObjectsOwnedByUser">
- Are you sure you want to return all objects owned by the Resident &apos;[NAME]&apos; on this parcel of land back to their inventory?
+ 你確定è¦å°‡æœ¬åœ°æ®µè£¡ã€Œ[NAME]ã€å±…民所æ“有的所有物件é€è¿”其收ç´å€ï¼Ÿ
-Objects: [N]
+物件:[N]
<usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/>
</notification>
<notification name="ReturnObjectsOwnedBySelf">
- Are you sure you want to return all objects owned by you on this parcel of land back to your inventory?
+ 你確定è¦å°‡æœ¬åœ°æ®µè£¡ä½ æ‰€æ“有的所有物件é€è¿”你的收ç´å€ï¼Ÿ
-Objects: [N]
+物件:[N]
<usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/>
</notification>
<notification name="ReturnObjectsNotOwnedBySelf">
- Are you sure you want to return all objects NOT owned by you on this parcel of land back to their owner&apos;s inventory?
-Transferable objects deeded to a group will be returned to their previous owners.
+ 你確定è¦å°‡æœ¬åœ°æ®µè£¡ä¸å±¬æ–¼ä½ çš„所有物件é€è¿”其所有人的收ç´å€ï¼Ÿ
+å…ˆå‰è®“渡給群組的å¯è½‰è®“物件將é€è¿”給原物主。
-*WARNING* This will delete the non-transferable objects deeded to the group!
+警告:這動作將會刪除原先讓渡給這群組的所有ä¸å¯è½‰è®“物件ï¼
-Objects: [N]
+物件:[N]
<usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/>
</notification>
<notification name="ReturnObjectsNotOwnedByUser">
- Are you sure you want to return all objects NOT owned by [NAME] on this parcel of land back to their owner&apos;s inventory?
-Transferable objects deeded to a group will be returned to their previous owners.
+ 你確定è¦å°‡æœ¬åœ°æ®µè£¡ä¸å±¬æ–¼ [NAME] 的所有物件é€è¿”其所有人的收ç´å€ï¼Ÿ
+å…ˆå‰è®“渡給群組的å¯è½‰è®“物件將é€è¿”給原物主。
-*WARNING* This will delete the non-transferable objects deeded to the group!
+警告:這動作將會刪除原先讓渡給這群組的所有ä¸å¯è½‰è®“物件ï¼
-Objects: [N]
+物件:[N]
<usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/>
</notification>
<notification name="ReturnAllTopObjects">
- Are you sure you want to return all listed objects back to their owner&apos;s inventory?
+ 你確定è¦å°‡æ‰€åˆ—的所有物件é€è¿”其所有人的收ç´å€ï¼Ÿ
<usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/>
</notification>
<notification name="DisableAllTopObjects">
- Are you sure you want to disable all objects in this region?
+ 你確定è¦åœç”¨æœ¬åœ°å€è£¡æ‰€æœ‰ç‰©ä»¶ï¼Ÿ
<usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/>
</notification>
<notification name="ReturnObjectsNotOwnedByGroup">
- Return the objects on this parcel of land that are NOT shared with the group [NAME] back to their owners?
+ 將本地段裡未和 [NAME] 群組分享的物件é€è¿”給物主?
-Objects: [N]
+物件:[N]
<usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/>
</notification>
<notification name="UnableToDisableOutsideScripts">
- Can not disable scripts.
-This entire region is damage enabled.
-Scripts must be allowed to run for weapons to work.
+ 無法åœç”¨è…³æœ¬ã€‚
+這整個地å€å…許傷害。
+腳本必須ç²å‡†åŸ·è¡Œï¼Œæ­¦å™¨æ‰æœ‰æ•ˆã€‚
</notification>
<notification name="MultipleFacesSelected">
- Multiple faces are currently selected.
-If you continue this action, separate instances of media will be set on multiple faces of the object.
-To place the media on only one face, choose Select Face and click on the desired face of that object then click Add.
- <usetemplate ignoretext="Media will be set on multiple selected faces" name="okcancelignore" notext="å–消" yestext="確定"/>
+ ç›®å‰é¸æ“‡äº†å¤šå€‹è‡‰éƒ¨ã€‚
+如果你繼續,物件的多個臉部將有å„自的媒體啟動。
+若想åªåœ¨ä¸€å€‹è‡‰éƒ¨æ”¾ç½®åª’體,請「é¸æ“‡è‡‰éƒ¨ã€ï¼Œé»žæŒ‰ç‰©ä»¶ä¸Šä½ æ‰€è¦çš„臉部,å†æŒ‰ã€Œæ–°å¢žã€ã€‚
+ <usetemplate ignoretext="所é¸çš„多個臉部都將啟用å„自的媒體。" name="okcancelignore" notext="å–消" yestext="確定"/>
</notification>
<notification name="MustBeInParcel">
- You must be standing inside the land parcel to set its Landing Point.
+ 你必須站在地段上æ‰èƒ½è¨­å®šå…¶ç™»é™¸é»žã€‚
</notification>
<notification name="PromptRecipientEmail">
- Please enter a valid email address for the recipient(s).
+ 請輸入居民的有效的電郵地å€ã€‚
</notification>
<notification name="PromptSelfEmail">
- Please enter your email address.
+ 請輸入你的電郵地å€ã€‚
</notification>
<notification name="PromptMissingSubjMsg">
- Email snapshot with the default subject or message?
+ 用é è¨­çš„電郵主旨或內文é€å‡ºå¿«ç…§ï¼Ÿ
<usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/>
</notification>
<notification name="ErrorProcessingSnapshot">
- Error processing snapshot data
+ 處ç†å¿«ç…§è³‡æ–™æ™‚出錯
</notification>
<notification name="ErrorEncodingSnapshot">
- Error encoding snapshot.
+ 為快照編碼時出錯。
</notification>
<notification name="ErrorUploadingPostcard">
- There was a problem sending a snapshot due to the following reason: [REASON]
+ 發é€å¿«ç…§æ™‚出å•é¡Œï¼ŒåŽŸå› ï¼š[REASON]
</notification>
<notification name="ErrorUploadingReportScreenshot">
- There was a problem uploading a report screenshot due to the following reason: [REASON]
+ 上傳舉報用快照時出å•é¡Œï¼ŒåŽŸå› ï¼š[REASON]
</notification>
<notification name="MustAgreeToLogIn">
- You must agree to the Terms of Service to continue logging into [SECOND_LIFE].
+ ä½ å¿…é ˆåŒæ„æœå‹™æ¢æ¬¾æ‰å¯ç¹¼çºŒç™»å…¥ [SECOND_LIFE]。
</notification>
<notification name="CouldNotPutOnOutfit">
- Could not put on outfit.
-The outfit folder contains no clothing, body parts, or attachments.
+ 無法穿上è£æ‰®ã€‚
+è£æ‰®è³‡æ–™å¤¾è£¡æ²’有任何衣物ã€èº«é«”部ä½æˆ–附件。
</notification>
<notification name="CannotWearTrash">
- You can not wear clothes or body parts that are in the trash
+ ä½ ä¸èƒ½ç©¿æˆ´åžƒåœ¾æ¡¶è£¡çš„衣物或身體部ä½ã€‚
</notification>
<notification name="MaxAttachmentsOnOutfit">
- Could not attach object.
-Exceeds the attachments limit of [MAX_ATTACHMENTS] objects. Please detach another object first.
+ 無法附加物件。
+è¶…éŽ [MAX_ATTACHMENTS] 項物件的附加上é™ã€‚ è«‹å…ˆå¸é™¤ä¸€å€‹ç‰©ä»¶ã€‚
</notification>
<notification name="CannotWearInfoNotComplete">
- You can not wear that item because it has not yet loaded. Please try again in a minute.
+ 無法穿戴該物件,它尚未完æˆè¼‰å…¥ã€‚ è«‹ç¨å€™å†è©¦ã€‚
</notification>
<notification name="MustHaveAccountToLogIn">
- Oops! Something was left blank.
-You need to enter the Username name of your avatar.
+ ç³Ÿç³•ï¼ ç™¼ç¾æœ‰å…§å®¹ç•™ç™½ã€‚
+你必須為化身輸入一個使用者å稱。
-You need an account to enter [SECOND_LIFE]. Would you like to create one now?
+進入 [SECOND_LIFE] 需è¦ä¸€å€‹å¸³è™Ÿã€‚ ä½ ç¾åœ¨è¦ä¸è¦æ–°å»ºä¸€å€‹ï¼Ÿ
<url name="url">
- http://join.secondlife.com/
+ [create_account_url]
</url>
<usetemplate name="okcancelbuttons" notext="å†è©¦ä¸€æ¬¡" yestext="創造新帳戶"/>
</notification>
<notification name="InvalidCredentialFormat">
- You need to enter either the Username or both the First and Last name of your avatar into the Username field, then login again.
+ 你必須在「使用者å稱ã€æ¬„ä½è£¡è¼¸å…¥ä½¿ç”¨è€…å稱,或輸入化身的å和姓,然後å†ç™»å…¥ã€‚
+ </notification>
+ <notification name="InvalidGrid">
+ &apos;[GRID]&apos; ä¸æ˜¯æœ‰æ•ˆçš„網格辨識元。
+ </notification>
+ <notification name="InvalidLocationSLURL">
+ 你的開始ä½ç½®æ‰€æŒ‡å®šçš„網格無效。
</notification>
<notification name="DeleteClassified">
- Delete classified &apos;[NAME]&apos;?
-There is no reimbursement for fees paid.
+ 刪除個人廣告「[NAME]ã€ï¼Ÿ
+已付費用æ•ä¸é€€å›žã€‚
<usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/>
</notification>
<notification name="DeleteMedia">
- You have selected to delete the media associated with this face.
-Are you sure you want to continue?
+ ä½ é¸æ“‡åˆªé™¤ç½®æ–¼é€™è‡‰éƒ¨çš„媒體。
+你確定你è¦ç¹¼çºŒï¼Ÿ
<usetemplate ignoretext="在我由一個部件中刪除媒體å‰ç¢ºèª" name="okcancelignore" notext="å¦" yestext="是"/>
</notification>
<notification name="ClassifiedSave">
- Save changes to classified [NAME]?
+ 儲存個人廣告「[NAME]ã€çš„變更?
<usetemplate canceltext="å–消" name="yesnocancelbuttons" notext="ä¸è¦å„²å­˜" yestext="儲存"/>
</notification>
<notification name="ClassifiedInsufficientFunds">
- Insufficient funds to create classified.
+ 金é¡ä¸è¶³ï¼Œç„¡æ³•åˆŠç™»å€‹äººå»£å‘Šã€‚
<usetemplate name="okbutton" yestext="確定"/>
</notification>
<notification name="DeleteAvatarPick">
- Delete pick &lt;nolink&gt;[PICK]&lt;/nolink&gt;?
+ 刪除精é¸ä½ç½®&lt;nolink&gt;[PICK]&lt;/nolink&gt;?
<usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/>
</notification>
<notification name="DeleteOutfits">
@@ -367,7 +421,7 @@ Are you sure you want to continue?
<usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/>
</notification>
<notification name="SelectProposalToView">
- Please select a proposal to view.
+ è«‹é¸æ“‡ä¸€å€‹è¦å¯Ÿçœ‹çš„æ議。
</notification>
<notification name="SelectHistoryItemToView">
è«‹é¸æ“‡ä¸€å€‹æ­·å²ç´€éŒ„物å“去察看。
@@ -380,13 +434,13 @@ Are you sure you want to continue?
注æ„:這將會清除快å–資料。
</notification>
<notification name="ChangeConnectionPort">
- Port settings take effect after you restart [APP_NAME].
+ é‡æ–°å•Ÿå‹• [APP_NAME] 後將啟用新的埠設定。
</notification>
<notification name="ChangeSkin">
- The new skin will appear after you restart [APP_NAME].
+ é‡æ–°å•Ÿå‹• [APP_NAME] 後將顯ç¾æ–°çš„皮膚。
</notification>
<notification name="ChangeLanguage">
- Changing language will take effect after you restart [APP_NAME].
+ é‡æ–°å•Ÿå‹• [APP_NAME] 後將æ›æˆæ–°çš„語言。
</notification>
<notification name="GoToAuctionPage">
å‰å¾€ [SECOND_LIFE] 網é åŽ»å¯Ÿçœ‹æ‹è³£ç´°ç¯€æˆ–下標?
@@ -396,92 +450,119 @@ Are you sure you want to continue?
<usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/>
</notification>
<notification name="SaveChanges">
- Save Changes?
+ 儲存變更?
<usetemplate canceltext="å–消" name="yesnocancelbuttons" notext="ä¸è¦å„²å­˜" yestext="儲存"/>
</notification>
<notification name="GestureSaveFailedTooManySteps">
- Gesture save failed.
-This gesture has too many steps.
-Try removing some steps, then save again.
+ 姿勢儲存失敗。
+這個姿勢步驟太多。
+請去除一些步驟å†å„²å­˜ã€‚
</notification>
<notification name="GestureSaveFailedTryAgain">
- Gesture save failed. Please try again in a minute.
+ 姿勢儲存失敗。 è«‹ç¨å€™å†è©¦ã€‚
</notification>
<notification name="GestureSaveFailedObjectNotFound">
- Could not save gesture because the object or the associated object inventory could not be found.
-The object may be out of range or may have been deleted.
+ 無法儲存姿勢,找ä¸åˆ°è©²ç‰©ä»¶æˆ–所屬物件收ç´å€ã€‚
+該物件å¯èƒ½è¶…出範åœæˆ–已被刪除。
</notification>
<notification name="GestureSaveFailedReason">
- There was a problem saving a gesture due to the following reason: [REASON]. Please try resaving the gesture later.
+ 儲存姿勢時出å•é¡Œï¼ŒåŽŸå› ï¼š[REASON]。 è«‹ç¨å¾Œå†å˜—試儲存姿勢。
</notification>
<notification name="SaveNotecardFailObjectNotFound">
- Could not save notecard because the object or the associated object inventory could not be found.
-The object may be out of range or may have been deleted.
+ 無法儲存記事å¡ï¼Œæ‰¾ä¸åˆ°è©²ç‰©ä»¶æˆ–所屬物件收ç´å€ã€‚
+該物件å¯èƒ½è¶…出範åœæˆ–已被刪除。
</notification>
<notification name="SaveNotecardFailReason">
- There was a problem saving a notecard due to the following reason: [REASON]. Please try re-saving the notecard later.
+ 儲存記事å¡æ™‚出å•é¡Œï¼ŒåŽŸå› ï¼š[REASON]。 è«‹ç¨å¾Œå†å˜—試儲存記事å¡ã€‚
</notification>
<notification name="ScriptCannotUndo">
- Could not undo all changes in your version of the script.
-Would you like to load the server&apos;s last saved version?
-(**Warning** This operation cannot be undone.)
+ 無法å–消你這個版本腳本的變更。
+是å¦å¾žä¼ºæœå™¨è¼‰å…¥ä¸Šæ¬¡æˆåŠŸå„²å­˜çš„版本?
+(*警告* 這動作無法還原。)
<usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/>
</notification>
<notification name="SaveScriptFailReason">
- There was a problem saving a script due to the following reason: [REASON]. Please try re-saving the script later.
+ 儲存腳本時出å•é¡Œï¼ŒåŽŸå› ï¼š[REASON]。 è«‹ç¨å¾Œå†å˜—試儲存腳本。
</notification>
<notification name="SaveScriptFailObjectNotFound">
- Could not save the script because the object it is in could not be found.
-The object may be out of range or may have been deleted.
+ 無法儲存腳本,找ä¸åˆ°å®ƒæ‰€å±¬çš„物件。
+該物件å¯èƒ½è¶…出範åœæˆ–已被刪除。
</notification>
<notification name="SaveBytecodeFailReason">
- There was a problem saving a compiled script due to the following reason: [REASON]. Please try re-saving the script later.
+ 儲存編譯腳本時出å•é¡Œï¼ŒåŽŸå› ï¼š[REASON]。 è«‹ç¨å¾Œå†å˜—試儲存腳本。
</notification>
<notification name="StartRegionEmpty">
- Oops, Your Start Region is not defined.
-Please type the Region name in Start Location box or choose My Last Location or My Home as your Start Location.
+ 你的起始地å€å°šæœªå®šç¾©ã€‚
+請在「開始ä½ç½®ã€æ¡†è£¡è¼¸å…¥å€åŸŸå,或é¸æ“‡ã€Œæˆ‘上一次ä½ç½®ã€æˆ–「我的家ã€ä½œç‚ºé–‹å§‹ä½ç½®ã€‚
<usetemplate name="okbutton" yestext="確定"/>
</notification>
<notification name="CouldNotStartStopScript">
- Could not start or stop the script because the object it is on could not be found.
-The object may be out of range or may have been deleted.
+ 無法啟動或åœæ­¢è…³æœ¬ï¼Œæ‰¾ä¸åˆ°å®ƒæ‰€å±¬çš„物件。
+該物件å¯èƒ½è¶…出範åœæˆ–已被刪除。
</notification>
<notification name="CannotDownloadFile">
- Unable to download file
+ 無法下載檔案
</notification>
<notification name="CannotWriteFile">
- Unable to write file [[FILE]]
+ 無法寫入檔案 [[FILE]]
</notification>
<notification name="UnsupportedHardware">
- Just so you know, your computer does not meet [APP_NAME]&apos;s minimum system requirements. You may experience poor performance. Unfortunately, the [SUPPORT_SITE] can&apos;t provide technical support for unsupported system configurations.
+ è¦å‘ŠçŸ¥ä½ ï¼Œä½ çš„é›»è…¦æœªé” [APP_NAME] 的最低系統需求。 ä½ å¯èƒ½æœƒç™¼ç¾é›»è…¦æ€§èƒ½ä¸ä½³ã€‚ 很éºæ†¾ï¼Œ[SUPPORT_SITE] 無法é‡å°ä¸æ”¯æ´çš„系統設置æ供技術支æ´ã€‚
-Visit [_URL] for more information?
+è¦é€ è¨ª [_URL] ç²å–進一步資訊?
<url name="url">
http://www.secondlife.com/corporate/sysreqs.php
</url>
<usetemplate ignoretext="我的電腦硬體並ä¸æ”¯æ´" name="okcancelignore" notext="å¦" yestext="是"/>
</notification>
+ <notification name="IntelOldDriver">
+ 你的顯示å¡å¾ˆå¯èƒ½æœ‰æ–°ç‰ˆçš„驅動程å¼ã€‚ 更新顯示驅動程å¼æœƒå¤§å¹…改善性能。
+
+ å‰å¾€ [_URL] 察看是å¦æœ‰æ–°ç‰ˆé©…動程å¼ï¼Ÿ
+ <url name="url">
+ http://www.intel.com/p/en_US/support/detect/graphics
+ </url>
+ <usetemplate ignoretext="我的顯示驅動程å¼å¤ªè€èˆŠ" name="okcancelignore" notext="å¦" yestext="是"/>
+ </notification>
+ <notification name="AMDOldDriver">
+ 你的顯示å¡å¾ˆå¯èƒ½æœ‰æ–°ç‰ˆçš„驅動程å¼ã€‚ 更新顯示驅動程å¼æœƒå¤§å¹…改善性能。
+
+ å‰å¾€ [_URL] 察看是å¦æœ‰æ–°ç‰ˆé©…動程å¼ï¼Ÿ
+ <url name="url">
+ http://support.amd.com/us/Pages/AMDSupportHub.aspx
+ </url>
+ <usetemplate ignoretext="我的顯示驅動程å¼å¤ªè€èˆŠ" name="okcancelignore" notext="å¦" yestext="是"/>
+ </notification>
+ <notification name="NVIDIAOldDriver">
+ 你的顯示å¡å¾ˆå¯èƒ½æœ‰æ–°ç‰ˆçš„驅動程å¼ã€‚ 更新顯示驅動程å¼æœƒå¤§å¹…改善性能。
+
+ å‰å¾€ [_URL] 察看是å¦æœ‰æ–°ç‰ˆé©…動程å¼ï¼Ÿ
+ <url name="url">
+ http://www.nvidia.com/Download/index.aspx?lang=tw
+ </url>
+ <usetemplate ignoretext="我的顯示驅動程å¼å¤ªè€èˆŠ" name="okcancelignore" notext="å¦" yestext="是"/>
+ </notification>
<notification name="UnknownGPU">
- Your system contains a graphics card that [APP_NAME] doesn&apos;t recognize.
-This is often the case with new hardware that hasn&apos;t been tested yet with [APP_NAME]. It will probably be ok, but you may need to adjust your graphics settings.
-(Me &gt; Preferences &gt; Graphics).
+ 你的系統å«æœ‰ä¸€å€‹ [APP_NAME] 無法辨èªçš„顯åƒå¡ã€‚
+原因很å¯èƒ½æ˜¯ [APP_NAME] 尚未é‡å°æ–°ç¡¬é«”完æˆæ¸¬è©¦ã€‚ 這大概ä¸æœƒå‡ºå•é¡Œï¼Œä½†ä½ å¯èƒ½éœ€è¦èª¿æ•´é¡¯åƒè¨­å®šã€‚
+(我自己 &gt; å好設定 &gt; 顯åƒï¼‰
<form name="form">
<ignore name="ignore" text="我的顯示å¡ç„¡æ³•è¾¨è­˜"/>
</form>
</notification>
<notification name="DisplaySettingsNoShaders">
- [APP_NAME] crashed while initializing graphics drivers.
-Graphics Quality will be set to Low to avoid some common driver errors. This will disable some graphics features.
-We recommend updating your graphics card drivers.
-Graphics Quality can be raised in Preferences &gt; Graphics.
+ [APP_NAME] åˆå§‹åŒ–顯åƒé©…動程å¼æ™‚當掉了。
+顯åƒåº¦å°‡è¨­ç‚ºä½ŽéšŽï¼Œä»¥é˜²ç™¼ç”Ÿå¸¸è¦‹çš„驅動程å¼æˆ–錯誤。 這將åœç”¨ä¸€äº›é¡¯åƒåŠŸèƒ½ã€‚
+我們建議你更新顯åƒé©…動程å¼ã€‚
+請到「å好設定 &gt; 顯åƒã€æ高顯åƒåº¦ã€‚
</notification>
<notification name="RegionNoTerraforming">
這個 [REGION] 地å€ä¸¦ä¸å…許變更地形。
</notification>
<notification name="CannotCopyWarning">
- You do not have permission to copy the following items:
+ 你沒有權é™è¤‡è£½ä»¥ä¸‹é …目:
[ITEMS]
-and will lose it from your inventory if you give it away. Do you really want to offer these items?
+如果你將它é€äººï¼Œå®ƒå°‡ç„¡æ³•çºŒç•™åœ¨æ”¶ç´å€ã€‚ 你確定è¦é€å‡ºé€™äº›æ±è¥¿å—Žï¼Ÿ
<usetemplate name="okcancelbuttons" notext="å¦" yestext="是"/>
</notification>
<notification name="CannotGiveItem">
@@ -491,18 +572,18 @@ and will lose it from your inventory if you give it away. Do you really want to
交易已å–消。
</notification>
<notification name="TooManyItems">
- Cannot give more than 42 items in a single inventory transfer.
+ æ¯ä¸€æ¬¡çš„收ç´å€è½‰ç§»å‹•ä½œä¸èƒ½è¶…éŽ 42 項物件。
</notification>
<notification name="NoItems">
- You do not have permission to transfer the selected items.
+ 你沒有權é™è½‰ç§»æ‰€é¸é …目。
</notification>
<notification name="CannotCopyCountItems">
- You do not have permission to copy [COUNT] of the selected items. You will lose these items from your inventory.
-Do you really want to give these items?
+ 你沒有權é™è¤‡è£½æ‰€é¸ç‰©ä»¶ç•¶ä¸­çš„ [COUNT] 項。 你的收ç´å€å°‡ç„¡æ³•çºŒç•™é€™äº›ç‰©ä»¶ã€‚
+你確定è¦é€å‡ºé€™äº›æ±è¥¿å—Žï¼Ÿ
<usetemplate name="okcancelbuttons" notext="å¦" yestext="是"/>
</notification>
<notification name="CannotGiveCategory">
- You do not have permission to transfer the selected folder.
+ 你沒有權é™è½‰ç§»æ‰€é¸è³‡æ–™å¤¾ã€‚
</notification>
<notification name="FreezeAvatar">
å‡çµé€™ä½åŒ–身?
@@ -533,75 +614,78 @@ Do you really want to give these items?
å–得錯誤:太多物件被é¸å–。
</notification>
<notification name="AcquireErrorObjectSpan">
- ACQUIRE ERROR: Objects span more than one region.
-Please move all objects to be acquired onto the same region.
+ å–得錯誤:物件跨越多個地å€ã€‚
+請將所欲å–得的物件移到åŒä¸€å€åŸŸã€‚
</notification>
<notification name="PromptGoToCurrencyPage">
[EXTRA]
-Go to [_URL] for information on purchasing L$?
+å‰å¾€ [_URL] 得知如何購買 L$?
<url name="url">
http://secondlife.com/app/currency/
</url>
<usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/>
</notification>
<notification name="UnableToLinkObjects">
- Unable to link these [COUNT] objects.
-You can link a maximum of [MAX] objects.
+ 無法è¯çµé€™ [COUNT] 個物件。
+你最多å¯ä»¥è¯çµ [MAX] 個物件。
</notification>
<notification name="CannotLinkIncompleteSet">
- You can only link complete sets of objects, and must select more than one object.
+ å¯ä»¥è¯çµçš„必需是一套物件,請é¸æ“‡è‡³å°‘兩個物件。
</notification>
<notification name="CannotLinkModify">
- Unable to link because you don&apos;t have modify permission on all the objects.
+ 無法è¯çµï¼›ä½ å°æŸäº›ç‰©ä»¶æ²’有修改權。
-Please make sure none are locked, and that you own all of them.
+請確定沒有物件被鎖ä½ï¼Œä¸¦ç¢ºå®šä½ æ“有所有物件。
+ </notification>
+ <notification name="CannotLinkPermanent">
+ 物件無法跨越地å€ç•Œé™é€²è¡Œè¯çµã€‚
</notification>
<notification name="CannotLinkDifferentOwners">
- Unable to link because not all of the objects have the same owner.
+ 無法è¯çµï¼›æœ‰äº›ç‰©ä»¶çš„所有人ä¸åŒã€‚
-Please make sure you own all of the selected objects.
+請確定你是所é¸æ‰€æœ‰ç‰©ä»¶çš„所有人。
</notification>
<notification name="NoFileExtension">
- No file extension for the file: &apos;[FILE]&apos;
+ 檔案沒有副檔å:&apos;[FILE]&apos;
-Please make sure the file has a correct file extension.
+請確定檔案具備正確的副檔å。
</notification>
<notification name="InvalidFileExtension">
- Invalid file extension [EXTENSION]
-Expected [VALIDS]
+ 無效的副檔å:[EXTENSION]
+應該是 [VALIDS]
<usetemplate name="okbutton" yestext="確定"/>
</notification>
<notification name="CannotUploadSoundFile">
- Couldn&apos;t open uploaded sound file for reading:
+ 無法開啟並讀å–上傳的è²éŸ³æª”:
[FILE]
</notification>
<notification name="SoundFileNotRIFF">
- File does not appear to be a RIFF WAVE file:
+ 檔案似乎ä¸æ˜¯ RIFF WAVE 檔:
[FILE]
</notification>
<notification name="SoundFileNotPCM">
- File does not appear to be a PCM WAVE audio file:
+ 檔案似乎ä¸æ˜¯ PCM WAVE 音頻檔:
[FILE]
</notification>
<notification name="SoundFileInvalidChannelCount">
- File has invalid number of channels (must be mono or stereo):
+ 檔案的頻é“數無效(必需為單è²é“或立體è²ï¼‰
[FILE]
</notification>
<notification name="SoundFileInvalidSampleRate">
- File does not appear to be a supported sample rate (must be 44.1k):
+ 檔案似乎帶有ä¸æ”¯æ´çš„採樣率(需為 44.1 k):
[FILE]
</notification>
<notification name="SoundFileInvalidWordSize">
- File does not appear to be a supported word size (must be 8 or 16 bit):
+ 檔案似乎帶有ä¸æ”¯æ´çš„字組(需為 8 或 16 ä½å…ƒï¼‰ï¼š
[FILE]
</notification>
<notification name="SoundFileInvalidHeader">
- Could not find &apos;data&apos; chunk in WAV header:
+ 找ä¸åˆ° WAV 檔頭的「dataã€å€å¡Šï¼š
[FILE]
</notification>
<notification name="SoundFileInvalidChunkSize">
- Wrong chunk size in WAV file:
+ WAV 檔å€å¡Šå¤§å°éŒ¯èª¤ï¼š
[FILE]
</notification>
<notification name="SoundFileInvalidTooLong">
@@ -609,41 +693,41 @@ Expected [VALIDS]
[FILE]
</notification>
<notification name="ProblemWithFile">
- Problem with file [FILE]:
+ 檔案 [FILE] 有å•é¡Œï¼š
[ERROR]
</notification>
<notification name="CannotOpenTemporarySoundFile">
- Couldn&apos;t open temporary compressed sound file for writing: [FILE]
+ 無法開啟並寫入暫時壓縮音頻檔:[FILE]
</notification>
<notification name="UnknownVorbisEncodeFailure">
- Unknown Vorbis encode failure on: [FILE]
+ 發生ä¸æ˜Žçš„ Vorbis 編碼錯誤:[FILE]
</notification>
<notification name="CannotEncodeFile">
- Unable to encode file: [FILE]
+ 無法將檔案編碼:[FILE]
</notification>
<notification name="CorruptedProtectedDataStore">
- We can&apos;t fill in your username and password. This may happen when you change network setup
+ 我們無法填入你的使用者å稱和密碼。 這å¯èƒ½å› ç‚ºä½ è®Šæ›´äº†ç¶²è·¯è¨­å®šã€‚
<usetemplate name="okbutton" yestext="確定"/>
</notification>
<notification name="CorruptResourceFile">
- Corrupt resource file: [FILE]
+ 毀æ的資æºæª”:[FILE]
</notification>
<notification name="UnknownResourceFileVersion">
- Unknown Linden resource file version in file: [FILE]
+ 檔案中發ç¾ä¸æ˜Žçš„ Linden 資æºæª”版本:[FILE]
</notification>
<notification name="UnableToCreateOutputFile">
- Unable to create output file: [FILE]
+ 無法建立輸出檔:[FILE]
</notification>
<notification name="DoNotSupportBulkAnimationUpload">
- [APP_NAME] does not currently support bulk upload of animation files.
+ [APP_NAME] ç›®å‰å°šä¸æ”¯æ´ BVH æ ¼å¼çš„動作檔批é‡ä¸Šå‚³ã€‚
</notification>
<notification name="CannotUploadReason">
- Unable to upload [FILE] due to the following reason: [REASON]
-Please try again later.
+ 無法上傳 [FILE],原因:[REASON]
+è«‹ç¨å€™å†è©¦ä¸€æ¬¡ã€‚
</notification>
<notification name="LandmarkCreated">
- 你已經添加 &quot;[LANDMARK_NAME]&quot; 到你的 [FOLDER_NAME] 資料夾。
+ 你已新增「[LANDMARK_NAME]ã€åˆ°ä½ çš„ [FOLDER_NAME] 資料夾。
</notification>
<notification name="LandmarkAlreadyExists">
你已經有這個ä½ç½®çš„地標。
@@ -653,132 +737,132 @@ Please try again later.
ä½ ä¸èƒ½å‰µé€ åœ°æ¨™ï¼Œå› ç‚ºåœ°ä¸»ä¸¦ä¸å…許你這樣åšã€‚
</notification>
<notification name="CannotRecompileSelectObjectsNoScripts">
- Not able to perform &apos;recompilation&apos;.
-Select an object with a script.
+ 無法進行é‡æ–°ç·¨è­¯ã€‚
+è«‹é¸æ“‡å¸¶æœ‰è…³æœ¬çš„物件。
</notification>
<notification name="CannotRecompileSelectObjectsNoPermission">
- Not able to perform &apos;recompilation&apos;.
+ 無法進行é‡æ–°ç·¨è­¯ã€‚
-Select objects with scripts that you have permission to modify.
+é¸æ“‡å¸¶æœ‰ä½ å¯ä¿®æ”¹çš„腳本的物件。
</notification>
<notification name="CannotResetSelectObjectsNoScripts">
- Not able to perform &apos;reset&apos;.
+ 無法é‡æ–°å•Ÿå‹•ã€‚
-Select objects with scripts.
+é¸æ“‡å¸¶æœ‰è…³æœ¬çš„物件。
</notification>
<notification name="CannotResetSelectObjectsNoPermission">
- Not able to perform &apos;reset&apos;.
+ 無法é‡æ–°å•Ÿå‹•ã€‚
-Select objects with scripts that you have permission to modify.
+é¸æ“‡å¸¶æœ‰ä½ å¯ä¿®æ”¹çš„腳本的物件。
</notification>
<notification name="CannotOpenScriptObjectNoMod">
- Unable to open script in object without modify permissions.
+ 無法開啟物件裡的腳本,因為你沒有修改權。
</notification>
<notification name="CannotSetRunningSelectObjectsNoScripts">
- Not able to set any scripts to &apos;running&apos;.
+ 無法將任何腳本設定為「執行中ã€ã€‚
-Select objects with scripts.
+é¸æ“‡å¸¶æœ‰è…³æœ¬çš„物件。
</notification>
<notification name="CannotSetRunningNotSelectObjectsNoScripts">
- Unable to set any scripts to &apos;not running&apos;.
+ 無法將任何腳本設定為「ä¸åŸ·è¡Œã€ã€‚
-Select objects with scripts.
+é¸æ“‡å¸¶æœ‰è…³æœ¬çš„物件。
</notification>
<notification name="NoFrontmostFloater">
- No frontmost floater to save.
+ 沒有最å‰ç½®çš„浮動視窗å¯å„²å­˜ã€‚
</notification>
<notification name="SeachFilteredOnShortWords">
- Your search query was modified and the words that were too short were removed.
+ ä½ çš„æœå°‹å­—串已被修改,太短的字已被移除。
-Searched for: [FINALQUERY]
+æœå°‹ï¼š[FINALQUERY]
</notification>
<notification name="SeachFilteredOnShortWordsEmpty">
- Your search terms were too short so no search was performed.
+ ä½ çš„æœå°‹å­—串太短,所以沒有啟動æœç´¢ã€‚
</notification>
<notification name="CouldNotTeleportReason">
瞬間傳é€å¤±æ•—。
[REASON]
</notification>
<notification name="invalid_tport">
- Problem encountered processing your teleport request. You may need to log back in before you can teleport.
-If you continue to get this message, please check the [SUPPORT_SITE].
+ 處ç†ä½ çž¬é–“傳é€è¦æ±‚時發生å•é¡Œã€‚ 如果想è¦çž¬é–“傳é€ï¼Œä½ å¯èƒ½éœ€è¦é‡æ–°ç™»å…¥ã€‚
+如果你æŒçºŒå¾—到此訊æ¯ï¼Œè«‹æŸ¥é–± [SUPPORT_SITE]。
</notification>
<notification name="invalid_region_handoff">
- Problem encountered processing your region crossing. You may need to log back in before you can cross regions.
-If you continue to get this message, please check the [SUPPORT_SITE].
+ 處ç†ä½ è·¨è¶Šåœ°å€å‹•ä½œæ™‚發生å•é¡Œã€‚ 如果想è¦è·¨è¶Šåœ°å€ï¼Œä½ å¯èƒ½éœ€è¦é‡æ–°ç™»å…¥ã€‚
+如果你æŒçºŒå¾—到此訊æ¯ï¼Œè«‹æŸ¥é–± [SUPPORT_SITE]。
</notification>
<notification name="blocked_tport">
- Sorry, teleport is currently blocked. Try again in a moment. If you still cannot teleport, please log out and log back in to resolve the problem.
+ 抱歉,目å‰ç¦æ­¢çž¬é–“傳é€ã€‚ è«‹ç¨å¾Œå†è©¦ã€‚ 如果你ä»ç„¡æ³•é€²è¡Œçž¬é–“傳é€ï¼Œè«‹ç™»å‡ºå¾Œé‡æ–°å…¥ä¾†è§£æ±ºæ­¤ä¸€å•é¡Œã€‚
</notification>
<notification name="nolandmark_tport">
- Sorry, but system was unable to locate landmark destination.
+ 抱歉,ä¸éŽç³»çµ±ç„¡æ³•æ‰¾åˆ°åœ°æ¨™æ‰€åœ¨ç›®çš„地。
</notification>
<notification name="timeout_tport">
- Sorry, but system was unable to complete the teleport connection. Try again in a moment.
+ 抱歉,ä¸éŽç³»çµ±ç„¡æ³•å®Œæˆçž¬é–“傳é€çš„è¯æŽ¥ã€‚ è«‹ç¨å¾Œå†è©¦ã€‚
</notification>
<notification name="noaccess_tport">
- Sorry, you do not have access to that teleport destination.
+ 抱歉,你並沒有權é™é€²å…¥è¦çž¬é–“傳é€çš„目的地。
</notification>
<notification name="missing_attach_tport">
- Your attachments have not arrived yet. Try waiting for a few more seconds or log out and back in again before attempting to teleport.
+ 你的附件尚未抵é”。 è«‹ç¨å€™ä¸€æœƒå…’,或請登出後é‡æ–°ç™»å…¥ï¼Œå†å˜—試瞬間傳é€ã€‚
</notification>
<notification name="too_many_uploads_tport">
- The asset queue in this region is currently clogged so your teleport request will not be able to succeed in a timely manner. Please try again in a few minutes or go to a less busy area.
+ 該地å€çš„資產查詢目å‰å¤ªéŽæ“塞,因此你的瞬間傳é€å‹•ä½œå¯èƒ½ç„¡æ³•å³æ™‚發生。 è«‹ç¨å€™å†è©¦ï¼Œæˆ–è«‹å‰å¾€è¼ƒä¸æ“塞的地å€ã€‚
</notification>
<notification name="expired_tport">
- Sorry, but the system was unable to complete your teleport request in a timely fashion. Please try again in a few minutes.
+ 抱歉,系統無法å³æ™‚完æˆç‚ºä½ çž¬é–“傳é€ã€‚ è«‹ç¨å¾…幾分é˜å†è©¦ã€‚
</notification>
<notification name="expired_region_handoff">
- Sorry, but the system was unable to complete your region crossing in a timely fashion. Please try again in a few minutes.
+ 抱歉,系統無法å³æ™‚讓你跨越地å€ã€‚ è«‹ç¨å¾…幾分é˜å†è©¦ã€‚
</notification>
<notification name="no_host">
- Unable to find teleport destination. The destination may be temporarily unavailable or no longer exists. Please try again in a few minutes.
+ 找ä¸åˆ°çž¬é–“傳é€çš„目的地。 目的地å¯èƒ½æš«æ™‚ä¸å¯ç”¨ï¼Œæˆ–å·²ä¸å­˜åœ¨ã€‚ è«‹ç¨å¾…幾分é˜å†è©¦ã€‚
</notification>
<notification name="no_inventory_host">
收ç´å€åŠŸèƒ½ç›®å‰ç„¡æ³•ä½¿ç”¨ã€‚
</notification>
<notification name="CannotSetLandOwnerNothingSelected">
- 無法設定土地æ“有者:
-無地段被é¸å–。
+ 無法設定土地所有人:
+未é¸æ“‡åœ°æ®µã€‚
</notification>
<notification name="CannotSetLandOwnerMultipleRegions">
- Unable to force land ownership because selection spans multiple regions. Please select a smaller area and try again.
+ 無法強設土地所有權;所é¸éƒ¨åˆ†è·¨è¶Šå¤šå€‹å€åŸŸã€‚ 請縮å°é¸æ“‡ç¯„åœï¼Œå†è©¦ä¸€æ¬¡ã€‚
</notification>
<notification name="ForceOwnerAuctionWarning">
- This parcel is up for auction. Forcing ownership will cancel the auction and potentially make some Residents unhappy if bidding has begun.
-Force ownership?
+ 這地段正在æ‹è³£ä¸­ã€‚ 強設所有權將å–消æ‹è³£ï¼Œé€™æ將造æˆæŸäº›å·²å‡ºåƒ¹çš„å±…æ°‘ä¸é«˜èˆˆã€‚
+è¦å¼·è¨­æ‰€æœ‰æ¬Šå—Žï¼Ÿ
<usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/>
</notification>
<notification name="CannotContentifyNothingSelected">
- Unable to contentify:
-No parcel selected.
+ 無法進行「內容化ã€ï¼š
+未é¸æ“‡åœ°æ®µã€‚
</notification>
<notification name="CannotContentifyNoRegion">
- Unable to contentify:
-No region selected.
+ 無法進行「內容化ã€ï¼š
+未é¸æ“‡å€åŸŸã€‚
</notification>
<notification name="CannotReleaseLandNothingSelected">
無法放棄土地:
-無地段被é¸æ“‡ã€‚
+未é¸æ“‡åœ°æ®µã€‚
</notification>
<notification name="CannotReleaseLandNoRegion">
無法放棄土地:
-無法尋找地å€ã€‚
+找ä¸åˆ°åœ°å€ã€‚
</notification>
<notification name="CannotBuyLandNothingSelected">
無法購買土地:
-無地段被é¸æ“‡ã€‚
+未é¸æ“‡åœ°æ®µã€‚
</notification>
<notification name="CannotBuyLandNoRegion">
- Unable to buy land:
-Cannot find the region this land is in.
+ 無法購買土地:
+找ä¸åˆ°é€™åœŸåœ°æ‰€åœ¨çš„地å€ã€‚
</notification>
<notification name="CannotCloseFloaterBuyLand">
- You cannot close the Buy Land window until [APP_NAME] estimates the price of this transaction.
+ 必須等待 [APP_NAME] 估計此交易的價格後,你æ‰èƒ½é—œé–‰ã€Œè³¼è²·åœŸåœ°ã€è¦–窗。
</notification>
<notification name="CannotDeedLandNothingSelected">
無法讓渡土地:
-無地段被é¸å–。
+未é¸æ“‡åœ°æ®µã€‚
</notification>
<notification name="CannotDeedLandNoGroup">
無法讓渡土地:
@@ -786,7 +870,7 @@ Cannot find the region this land is in.
</notification>
<notification name="CannotDeedLandNoRegion">
無法讓渡土地:
-無法發ç¾é€™å¡ŠåœŸåœ°æ‰€åœ¨çš„地å€ã€‚
+找ä¸åˆ°é€™åœŸåœ°æ‰€åœ¨çš„地å€ã€‚
</notification>
<notification name="CannotDeedLandMultipleSelected">
無法讓渡土地:
@@ -802,7 +886,7 @@ Cannot find the region this land is in.
</notification>
<notification name="CannotDeedLandNoTransfer">
無法讓渡土地:
-æ­¤ [REGION] 地å€ä¸¦ä¸å…許土地轉移。
+「[REGION]ã€åœ°å€ä¸å…許土地轉移。
</notification>
<notification name="CannotReleaseLandWatingForServer">
無法放棄土地:
@@ -823,11 +907,11 @@ Cannot find the region this land is in.
</notification>
<notification name="CannotReleaseLandRegionNotFound">
無法放棄土地:
-無法發ç¾é€™å¿«åœŸåœ°æ‰€åœ¨çš„地å€ã€‚
+找ä¸åˆ°é€™åœŸåœ°æ‰€åœ¨çš„地å€ã€‚
</notification>
<notification name="CannotReleaseLandNoTransfer">
無法放棄土地:
-æ­¤ [REGION] 地å€ä¸¦ä¸è¨±åœŸåœ°è½‰ç§»ã€‚
+「[REGION]ã€åœ°å€ä¸å…許土地轉移。
</notification>
<notification name="CannotReleaseLandPartialSelection">
無法放棄土地:
@@ -845,7 +929,7 @@ Cannot find the region this land is in.
<notification name="CannotDivideLandNothingSelected">
無法分割土地:
-無地段被é¸å–。
+未é¸æ“‡åœ°æ®µã€‚
</notification>
<notification name="CannotDivideLandPartialSelection">
無法分割土地:
@@ -854,22 +938,22 @@ Cannot find the region this land is in.
請試著é¸å–其中部分地段。
</notification>
<notification name="LandDivideWarning">
- 分割土地會將佌地段一分為二,æ¯ä¸€å€‹åœ°æ®µå°‡éƒ½å„自有其設定。 在這個æ“作之後,一些設定值將會回復到é è¨­å€¼ã€‚
+ 分割土地將把地段分為兩份,æ¯å€‹æ–°åœ°æ®µæœ‰å„自的設定。 完æˆå¾Œï¼Œéƒ¨åˆ†è¨­å®šå°‡é‡è¨­ç‚ºé è¨­å€¼ã€‚
進行分割土地?
<usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/>
</notification>
<notification name="CannotDivideLandNoRegion">
無法分割土地:
-無法發ç¾é€™å¡ŠåœŸåœ°æ‰€åœ¨çš„地å€ã€‚
+找ä¸åˆ°é€™åœŸåœ°æ‰€åœ¨çš„地å€ã€‚
</notification>
<notification name="CannotJoinLandNoRegion">
無法åˆä½µåœŸåœ°ï¼š
-無法發ç¾é€™å¡ŠåœŸåœ°æ‰€åœ¨çš„地å€ã€‚
+找ä¸åˆ°é€™åœŸåœ°æ‰€åœ¨çš„地å€ã€‚
</notification>
<notification name="CannotJoinLandNothingSelected">
無法åˆä½µåœŸåœ°ï¼š
-無地段被é¸å–。
+未é¸æ“‡åœ°æ®µã€‚
</notification>
<notification name="CannotJoinLandEntireParcelSelected">
無法åˆä½µåœŸåœ°ï¼š
@@ -891,42 +975,42 @@ Cannot find the region this land is in.
<usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/>
</notification>
<notification name="ConfirmNotecardSave">
- 在物å“能被覆製或察看å‰ï¼Œé€™è¨˜äº‹å¡å¿…須先進行儲存。儲存記事å¡ï¼Ÿ
+ 覆製或察看å‰ï¼Œé€™è¨˜äº‹å¡å¿…須先進行儲存。 儲存記事å¡ï¼Ÿ
<usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/>
</notification>
<notification name="ConfirmItemCopy">
覆製這個物å“到你的收ç´å€ï¼Ÿ
- <usetemplate name="okcancelbuttons" notext="å–消" yestext="覆製"/>
+ <usetemplate name="okcancelbuttons" notext="å–消" yestext="æšåº¨"/>
</notification>
<notification name="ResolutionSwitchFail">
- Failed to switch resolution to [RESX] by [RESY]
+ 無法將解æžåº¦èª¿ç‚º [RESX] X [RESY]
</notification>
<notification name="ErrorUndefinedGrasses">
- Error: Undefined grasses: [SPECIES]
+ 錯誤:未定義的è‰ç¨®ï¼š[SPECIES]
</notification>
<notification name="ErrorUndefinedTrees">
- Error: Undefined trees: [SPECIES]
+ 錯誤:未定義的樹種:[SPECIES]
</notification>
<notification name="CannotSaveWearableOutOfSpace">
- Unable to save &apos;[NAME]&apos; to wearable file. You will need to free up some space on your computer and save the wearable again.
+ 無法將「[NAME]ã€å„²å­˜ç‚ºå¯ç©¿è£æ‰®æª”案。 你需è¦ç©ºå‡ºä¸€äº›é›»è…¦ç©ºé–“,å†è©¦è‘—儲存å¯ç©¿è£æ‰®ã€‚
</notification>
<notification name="CannotSaveToAssetStore">
- Unable to save [NAME] to central asset store.
-This is usually a temporary failure. Please customize and save the wearable again in a few minutes.
+ 無法將「[NAME]ã€å„²å­˜åˆ°ä¸­å¤®è³‡ç”¢å„²åº«ã€‚
+這異常狀æ³é€šå¸¸åªæ˜¯æš«æ™‚的。 è«‹ç¨å¾…幾分é˜å¾Œï¼Œå†è‡ªè¨‚並儲存å¯ç©¿è£æ‰®ã€‚
</notification>
<notification name="YouHaveBeenLoggedOut">
- Darn. You have been logged out of [SECOND_LIFE]
+ ç³Ÿç³•ï¼ ä½ å·²è¢«ç™»å‡º [SECOND_LIFE]
[MESSAGE]
- <usetemplate name="okcancelbuttons" notext="çµæŸé€€å‡º" yestext="View IM &amp; Chat"/>
+ <usetemplate name="okcancelbuttons" notext="çµæŸé€€å‡º" yestext="察看 IM å’ŒèŠå¤©å…§å®¹"/>
</notification>
<notification name="OnlyOfficerCanBuyLand">
- Unable to buy land for the group:
-You do not have permission to buy land for your active group.
+ 無法為這群組購買土地:
+你沒有權é™ç‚ºä½ ç•¶å‰çš„群組購買土地。
</notification>
<notification label="加為朋å‹" name="AddFriendWithMessage">
- Friends can give permissions to track each other on the map and receive online status updates.
+ 朋å‹å¯ä»¥å…許彼此在地圖上追蹤å°æ–¹ï¼Œä¸¦æŽ¥æ”¶å½¼æ­¤çš„線上狀態更新訊æ¯ã€‚
-Offer friendship to [NAME]?
+å‘ [NAME] 發出交å‹é‚€è«‹ï¼Ÿ
<form name="form">
<input name="message">
你願æ„æˆç‚ºæˆ‘的朋å‹å—Žï¼Ÿ
@@ -935,21 +1019,55 @@ Offer friendship to [NAME]?
<button name="Cancel" text="å–消"/>
</form>
</notification>
+ <notification label="新增自動å–代清單" name="AddAutoReplaceList">
+ 新清單å稱:
+ <form name="form">
+ <button name="SetName" text="確定"/>
+ </form>
+ </notification>
+ <notification label="更改自動å–代清單的å稱" name="RenameAutoReplaceList">
+ 「[DUPNAME]ã€å稱已有人使用。
+ 輸入å¦ä¸€å€‹ç¨ç‰¹çš„å稱:
+ <form name="form">
+ <button name="ReplaceList" text="å–代目å‰çš„清單"/>
+ <button name="SetName" text="使用新å稱"/>
+ </form>
+ </notification>
+ <notification name="InvalidAutoReplaceEntry">
+ é—œéµå­—必須是一個字,å–代字ä¸å¾—空白。
+ </notification>
+ <notification name="InvalidAutoReplaceList">
+ 該å–代清單無效。
+ </notification>
+ <notification name="SpellingDictImportRequired">
+ 你必須指定一個檔案ã€ä¸€å€‹å稱和一種語言。
+ </notification>
+ <notification name="SpellingDictIsSecondary">
+ [DIC_NAME] 字典似乎沒有 &quot;aff&quot; 檔案,這表示該字典是「次級ã€å­—典。
+它å¯ç”¨åšé™„加字典,但ä¸å¾—作為主è¦å­—典。
+
+åƒè¦‹ https://wiki.secondlife.com/wiki/Adding_Spelling_Dictionaries
+ </notification>
+ <notification name="SpellingDictImportFailed">
+ 無法複製 [FROM_NAME]
+
+ 到 [TO_NAME]
+ </notification>
<notification label="儲存è£æ‰®" name="SaveOutfitAs">
儲存我正在穿的為新è£æ‰®ï¼š
<form name="form">
<input name="message">
- [DESC] (新)
+ [DESC](新)
</input>
<button name="OK" text="確定"/>
<button name="Cancel" text="å–消"/>
</form>
</notification>
- <notification label="Save Wearable" name="SaveWearableAs">
+ <notification label="儲存å¯ç©¿è£æ‰®" name="SaveWearableAs">
儲存物å“到我的收ç´å€ç‚ºï¼š
<form name="form">
<input name="message">
- [DESC] (新)
+ [DESC](新)
</input>
<button name="OK" text="確定"/>
<button name="Cancel" text="å–消"/>
@@ -966,7 +1084,7 @@ Offer friendship to [NAME]?
</form>
</notification>
<notification name="RemoveFromFriends">
- Do you want to remove &lt;nolink&gt;[NAME]&lt;/nolink&gt; from your Friends List?
+ 確定è¦å¾žæœ‹å‹å單中移除 &lt;nolink&gt;[NAME]&lt;/nolink&gt;?
<usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/>
</notification>
<notification name="RemoveMultipleFromFriends">
@@ -974,148 +1092,147 @@ Offer friendship to [NAME]?
<usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/>
</notification>
<notification name="GodDeleteAllScriptedPublicObjectsByUser">
- Are you sure you want to delete all scripted objects owned by
-** [AVATAR_NAME] **
-on all others land in this sim?
+ 你確定è¦åˆªé™¤æœ¬æ¨¡æ“¬ä¸–界所有其他土地裡,** [AVATAR_NAME] ** 所æ“有的全部帶腳本的物件?
<usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/>
</notification>
<notification name="GodDeleteAllScriptedObjectsByUser">
- Are you sure you want to DELETE ALL scripted objects owned by
-** [AVATAR_NAME] **
-on ALL LAND in this sim?
+ 你確定è¦åˆªé™¤æœ¬æ¨¡æ“¬ä¸–界所有土地裡,** [AVATAR_NAME] ** 所æ“有的全部帶腳本的物件?
<usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/>
</notification>
<notification name="GodDeleteAllObjectsByUser">
- Are you sure you want to DELETE ALL objects (scripted or not) owned by
-** [AVATAR_NAME] **
-on ALL LAND in this sim?
+ 你確定è¦åˆªé™¤æœ¬æ¨¡æ“¬ä¸–界所有土地裡,** [AVATAR_NAME] ** 所æ“有的全部物件(無論是å¦å¸¶è…³æœ¬ï¼‰ï¼Ÿ
<usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/>
</notification>
<notification name="BlankClassifiedName">
- You must specify a name for your classified.
+ 你的個人廣告必須指定一個å稱。
</notification>
<notification name="MinClassifiedPrice">
- Price to pay for listing must be at least L$[MIN_PRICE].
+ 購買此刊登物的價格必須至少為 L$[MIN_PRICE]。
-Please enter a higher price.
+請輸入一個較高的價格。
</notification>
<notification name="ConfirmItemDeleteHasLinks">
- At least one of the items you has link items that point to it. If you delete this item, its links will permanently stop working. It is strongly advised to delete the links first.
+ 所é¸é …目中至少有一個帶有來自其他項目的è¯çµã€‚ 如果你刪除這一項目,è¯çµå°‡æ°¸ä¹…失效。 我們強烈建議你先刪除è¯çµã€‚
-Are you sure you want to delete these items?
+你確定你è¦åˆªé™¤é€™äº›ç‰©é …?
<usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/>
</notification>
<notification name="ConfirmObjectDeleteLock">
- At least one of the items you have selected is locked.
+ 你所é¸é …目中至少有一個被鎖ä½ã€‚
-Are you sure you want to delete these items?
+你確定你è¦åˆªé™¤é€™äº›ç‰©é …?
<usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/>
</notification>
<notification name="ConfirmObjectDeleteNoCopy">
- At least one of the items you have selected is not copyable.
+ 你所é¸é …目中至少有一個ä¸èƒ½è¤‡è£½ã€‚
-Are you sure you want to delete these items?
+你確定你è¦åˆªé™¤é€™äº›ç‰©é …?
<usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/>
</notification>
<notification name="ConfirmObjectDeleteNoOwn">
- You do not own least one of the items you have selected.
+ 你所é¸é …目中至少有一個ä¸æ˜¯ä½ æ‰€æ“有。
-Are you sure you want to delete these items?
+你確定你è¦åˆªé™¤é€™äº›ç‰©é …?
<usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/>
</notification>
<notification name="ConfirmObjectDeleteLockNoCopy">
- At least one object is locked.
-At least one object is not copyable.
+ 至少有一個物件被鎖ä½ã€‚
+至少有一個物件ä¸èƒ½è¤‡è£½ã€‚
-Are you sure you want to delete these items?
+你確定你è¦åˆªé™¤é€™äº›ç‰©é …?
<usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/>
</notification>
<notification name="ConfirmObjectDeleteLockNoOwn">
- At least one object is locked.
-You do not own least one object.
+ 至少有一個物件被鎖ä½ã€‚
+至少有一個物件ä¸æ˜¯ä½ æ‰€æ“有。
-Are you sure you want to delete these items?
+你確定你è¦åˆªé™¤é€™äº›ç‰©é …?
<usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/>
</notification>
<notification name="ConfirmObjectDeleteNoCopyNoOwn">
- At least one object is not copyable.
-You do not own least one object.
+ 至少有一個物件ä¸èƒ½è¤‡è£½ã€‚
+至少有一個物件ä¸æ˜¯ä½ æ‰€æ“有。
-Are you sure you want to delete these items?
+你確定你è¦åˆªé™¤é€™äº›ç‰©é …?
<usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/>
</notification>
<notification name="ConfirmObjectDeleteLockNoCopyNoOwn">
- At least one object is locked.
-At least one object is not copyable.
-You do not own least one object.
+ 至少有一個物件被鎖ä½ã€‚
+至少有一個物件ä¸èƒ½è¤‡è£½ã€‚
+至少有一個物件ä¸æ˜¯ä½ æ‰€æ“有。
-Are you sure you want to delete these items?
+你確定你è¦åˆªé™¤é€™äº›ç‰©é …?
<usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/>
</notification>
<notification name="ConfirmObjectTakeLock">
- At least one object is locked.
+ 至少有一個物件被鎖ä½ã€‚
-Are you sure you want to take these items?
+你確定你è¦æ‹¿å–這些物項?
<usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/>
</notification>
<notification name="ConfirmObjectTakeNoOwn">
- You do not own all of the objects you are taking.
-If you continue, next owner permissions will be applied and possibly restrict your ability to modify or copy them.
+ ä½ è¦æ‹¿å–的物件中,有些ä¸æ˜¯ä½ æ‰€æ“有。
+如果繼續,將套用「下一個所有人ã€æ¬Šé™ï¼Œé€™å¯èƒ½æœƒé™åˆ¶ä½ ä¿®æ”¹æˆ–複製權。
-Are you sure you want to take these items?
+你確定你è¦æ‹¿å–這些物項?
<usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/>
</notification>
<notification name="ConfirmObjectTakeLockNoOwn">
- At least one object is locked.
-You do not own all of the objects you are taking.
-If you continue, next owner permissions will be applied and possibly restrict your ability to modify or copy them.
-However, you can take the current selection.
+ 至少有一個物件被鎖ä½ã€‚
+ä½ è¦æ‹¿å–的物件中,有些ä¸æ˜¯ä½ æ‰€æ“有。
+如果繼續,將套用「下一個所有人ã€æ¬Šé™ï¼Œé€™å¯èƒ½æœƒé™åˆ¶ä½ ä¿®æ”¹æˆ–複製權。
+ä¸éŽï¼Œä½ å¯ä»¥æ‹¿å–ç›®å‰æ‰€é¸çš„。
-Are you sure you want to take these items?
+你確定你è¦æ‹¿å–這些物項?
<usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/>
</notification>
<notification name="CantBuyLandAcrossMultipleRegions">
- Unable to buy land because selection spans multiple regions.
+ 無法購買土地,所é¸éƒ¨åˆ†è·¨è¶Šå¤šå€‹åœ°å€ã€‚
-Please select a smaller area and try again.
+請縮å°é¸æ“‡ç¯„åœï¼Œå†è©¦ä¸€æ¬¡ã€‚
</notification>
<notification name="DeedLandToGroup">
- By deeding this parcel, the group will be required to have and maintain sufficient land use credits.
-The purchase price of the land is not refunded to the owner. If a deeded parcel is sold, the sale price will be divided evenly among group members.
+ 若讓渡此地段,這個群組將必須具備並ä¿æŒè¶³å¤ çš„土地使用信用é¡åº¦ã€‚
+土地收購價將ä¸æœƒé€€é‚„給所有人。 如果讓渡的地段被售出,售出價將å‡åˆ†çµ¦æ¯ä½ç¾¤çµ„æˆå“¡ã€‚
-Deed this [AREA] m² of land to the group &apos;[GROUP_NAME]&apos;?
+是å¦è®“渡這塊 [AREA] 平方公尺的土地給群組「[GROUP_NAME]ã€ï¼Ÿ
<usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/>
</notification>
<notification name="DeedLandToGroupWithContribution">
- By deeding this parcel, the group will be required to have and maintain sufficient land use credits.
-The deed will include a simultaneous land contribution to the group from &apos;[NAME]&apos;.
-The purchase price of the land is not refunded to the owner. If a deeded parcel is sold, the sale price will be divided evenly among group members.
+ 若讓渡此地段,這個群組將必須具備並ä¿æŒè¶³å¤ çš„土地使用信用é¡åº¦ã€‚
+此一讓渡將åŒæ™‚包括來自 [NAME] 的,給予群組的土地æç»ã€‚
+土地收購價將ä¸æœƒé€€é‚„給所有人。 如果讓渡的地段被售出,售出價將å‡åˆ†çµ¦æ¯ä½ç¾¤çµ„æˆå“¡ã€‚
-Deed this [AREA] m² of land to the group &apos;[GROUP_NAME]&apos;?
+是å¦è®“渡這塊 [AREA] 平方公尺的土地給群組「[GROUP_NAME]ã€ï¼Ÿ
<usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/>
</notification>
<notification name="DisplaySetToSafe">
- Display settings have been set to safe levels because you have specified the -safe option.
+ 因為你指定了 -safe é¸é …,已將顯示設為安全等級。
</notification>
- <notification name="DisplaySetToRecommended">
- Display settings have been set to recommended levels based on your system configuration.
+ <notification name="DisplaySetToRecommendedGPUChange">
+ 由於你的顯åƒå¡æœ‰æ‰€è®Šæ›´ï¼Œå·²å°‡é¡¯ç¤ºç‹€æ…‹è¨­ç‚ºæŽ¨è–¦æŽ¡ç”¨çš„等級。
+原顯åƒå¡ï¼š[LAST_GPU]
+新顯åƒå¡ï¼š[THIS_GPU]
+ </notification>
+ <notification name="DisplaySetToRecommendedFeatureChange">
+ 由於呈åƒå­ç³»çµ±æœ‰æ‰€è®Šæ›´ï¼Œå·²å°‡é¡¯ç¤ºç‹€æ…‹è¨­ç‚ºæŽ¨è–¦çš„設定。
</notification>
<notification name="ErrorMessage">
[ERROR_MESSAGE]
<usetemplate name="okbutton" yestext="確定"/>
</notification>
<notification name="AvatarMovedDesired">
- Your desired location is not currently available.
-You have been moved into a nearby region.
+ 你所è¦çš„地點目å‰ç„¡æ³•å‰å¾€ã€‚
+你已被移往一個鄰近地å€ã€‚
</notification>
<notification name="AvatarMovedLast">
- Your last location is not currently available.
-You have been moved into a nearby region.
+ 你所請求的地點目å‰ç„¡æ³•å‰å¾€ã€‚
+你已被移往一個鄰近地å€ã€‚
</notification>
<notification name="AvatarMovedHome">
- Your home location is not currently available.
-You have been moved into a nearby region.
-You may want to set a new home location.
+ 你設為家的地點目å‰ç„¡æ³•å‰å¾€ã€‚
+你已被移往一個鄰近地å€ã€‚
+建議你å¦é¸æ–°åœ°é»žè¨­ç‚ºå®¶ã€‚
</notification>
<notification name="ClothingLoading">
ä½ çš„æœè£ä»åœ¨ä¸‹è¼‰ä¸­ã€‚
@@ -1127,14 +1244,13 @@ You may want to set a new home location.
<notification name="FirstRun">
[APP_NAME] 安è£å®Œæˆã€‚
-If this is your first time using [SECOND_LIFE], you will need to create an account before you can log in.
-Return to [http://join.secondlife.com secondlife.com] to create a new account?
- <usetemplate name="okcancelbuttons" notext="繼續" yestext="新帳戶..."/>
+如果你是第一次使用 [SECOND_LIFE],你將需è¦å»ºç«‹æ–°å¸³è™Ÿæ‰å¯ç™»å…¥ã€‚
+ <usetemplate name="okcancelbuttons" notext="繼續" yestext="建立帳號…"/>
</notification>
<notification name="LoginPacketNeverReceived">
- We&apos;re having trouble connecting. There may be a problem with your Internet connection or the [SECOND_LIFE_GRID].
+ 連線出ç¾å•é¡Œã€‚ å•é¡Œå¯èƒ½å‡ºåœ¨ä½ çš„網路連線或 [SECOND_LIFE_GRID]。
-You can either check your Internet connection and try again in a few minutes, click Help to view the [SUPPORT_SITE], or click Teleport to attempt to teleport home.
+請檢查你的網路連線,幾分é˜å¾Œå†è©¦ä¸€æ¬¡ï¼Œæˆ–者點按幫助ç€è¦½ [SUPPORT_SITE],或點按瞬間傳é€è©¦è‘—回到你的家。
<url name="url">
http://secondlife.com/support/
</url>
@@ -1145,70 +1261,70 @@ You can either check your Internet connection and try again in a few minutes, cl
</form>
</notification>
<notification name="WelcomeChooseSex">
- Your character will appear in a moment.
+ 你的人物很快將會出ç¾ã€‚
-Use arrow keys to walk.
-Press the F1 key at any time for help or to learn more about [SECOND_LIFE].
-Please choose the male or female avatar. You can change your mind later.
+用方å‘éµè¡Œèµ°ã€‚
+任何時候你都å¯æŒ‰ F1 éµå¯Ÿçœ‹å¹«åŠ©ï¼Œé€²ä¸€æ­¥çž­è§£ [SECOND_LIFE]。
+è«‹é¸æ“‡ç”·æ€§æˆ–女性化身。 以後你ä»å¯æ”¹è®Šé€™å€‹é¸æ“‡ã€‚
<usetemplate name="okcancelbuttons" notext="女性" yestext="男性"/>
</notification>
<notification name="CantTeleportToGrid">
- Could not teleport to [SLURL] as it&apos;s on a different grid ([GRID]) than the current grid ([CURRENT_GRID]). Please close your viewer and try again.
+ 無法瞬間傳é€åˆ° [SLURL],它ä½æ–¼ä¸åŒçš„網格([GRID]),目å‰ç¶²æ ¼æ˜¯ [CURRENT_GRID]。 請關閉 Viewer å†è©¦ä¸€æ¬¡ã€‚
<usetemplate name="okbutton" yestext="確定"/>
</notification>
<notification name="GeneralCertificateError">
無法連接到伺æœå™¨ã€‚
[REASON]
-SubjectName: [SUBJECT_NAME_STRING]
-IssuerName: [ISSUER_NAME_STRING]
-Valid From: [VALID_FROM]
-Valid To: [VALID_TO]
-MD5 Fingerprint: [SHA1_DIGEST]
-SHA1 Fingerprint: [MD5_DIGEST]
-Key Usage: [KEYUSAGE]
-Extended Key Usage: [EXTENDEDKEYUSAGE]
-Subject Key Identifier: [SUBJECTKEYIDENTIFIER]
+SubjectName:[SUBJECT_NAME_STRING]
+IssuerName:[ISSUER_NAME_STRING]
+有效來æºï¼š[VALID_FROM]
+有效目標:[VALID_TO]
+MD5 指紋:[SHA1_DIGEST]
+SHA1 指紋:[MD5_DIGEST]
+éµçš„使用:[KEYUSAGE]
+延伸éµçš„使用:[EXTENDEDKEYUSAGE]
+主題éµè¾¨è­˜å…ƒï¼š[SUBJECTKEYIDENTIFIER]
<usetemplate name="okbutton" yestext="確定"/>
</notification>
<notification name="TrustCertificateError">
- The certification authority for this server is not known.
-
-Certificate Information:
-SubjectName: [SUBJECT_NAME_STRING]
-IssuerName: [ISSUER_NAME_STRING]
-Valid From: [VALID_FROM]
-Valid To: [VALID_TO]
-MD5 Fingerprint: [SHA1_DIGEST]
-SHA1 Fingerprint: [MD5_DIGEST]
-Key Usage: [KEYUSAGE]
-Extended Key Usage: [EXTENDEDKEYUSAGE]
-Subject Key Identifier: [SUBJECTKEYIDENTIFIER]
-
-Would you like to trust this authority?
- <usetemplate name="okcancelbuttons" notext="å–消" yestext="Trust"/>
+ ä¸æ˜Žçš„伺æœå™¨èªè­‰æ¬Šé™ã€‚
+
+èªè­‰è³‡è¨Šï¼š
+SubjectName:[SUBJECT_NAME_STRING]
+IssuerName:[ISSUER_NAME_STRING]
+有效來æºï¼š[VALID_FROM]
+有效目標:[VALID_TO]
+MD5 指紋:[SHA1_DIGEST]
+SHA1 指紋:[MD5_DIGEST]
+éµçš„使用:[KEYUSAGE]
+延伸éµçš„使用:[EXTENDEDKEYUSAGE]
+主題éµè¾¨è­˜å…ƒï¼š[SUBJECTKEYIDENTIFIER]
+
+是å¦ä¿¡ä»»é€™å€‹æ¬Šé™ï¼Ÿ
+ <usetemplate name="okcancelbuttons" notext="å–消" yestext="ä¿¡ä»»"/>
</notification>
<notification name="NotEnoughCurrency">
- [NAME] L$ [PRICE] You don&apos;t have enough L$ to do that.
+ [NAME] L$ [PRICE] 你沒有足夠 L$ 進行這動作。
</notification>
<notification name="GrantedModifyRights">
- [NAME] has given you permission to edit their objects.
+ [NAME] 已授權你編輯他們的物件。
</notification>
<notification name="RevokedModifyRights">
- Your privilege to modify [NAME]&apos;s objects has been revoked
+ 你修改 [NAME] 的物件的權é™å·²è¢«æ’¤éŠ·ã€‚
</notification>
<notification name="FlushMapVisibilityCaches">
- This will flush the map caches on this region.
-This is really only useful for debugging.
-(In production, wait 5 minutes, then everyone&apos;s map will update after they relog.)
+ 這將清除本地å€çš„地圖快å–資料。
+這麼åšåªåœ¨é™¤éŒ¯æ™‚有用。
+(實地環境中,等待 5 分é˜ï¼Œæ¯å€‹äººçš„地圖將在他們é‡æ–°ç™»å…¥å¾Œæ›´æ–°ã€‚)
<usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/>
</notification>
<notification name="BuyOneObjectOnly">
- Unable to buy more than one object at a time. Please select only one object and try again.
+ 無法一次購買多個物件。 è«‹åªé¸æ“‡ä¸€å€‹ç‰©ä»¶ï¼Œå†è©¦ä¸€æ¬¡ã€‚
</notification>
<notification name="OnlyCopyContentsOfSingleItem">
- Unable to copy the contents of more than one item at a time.
-Please select only one object and try again.
+ 無法一次複製多個物項的內容。
+è«‹åªé¸æ“‡ä¸€å€‹ç‰©ä»¶ï¼Œå†è©¦ä¸€æ¬¡ã€‚
<usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/>
</notification>
<notification name="KickUsersFromRegion">
@@ -1216,66 +1332,66 @@ Please select only one object and try again.
<usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/>
</notification>
<notification name="EstateObjectReturn">
- Are you sure you want to return objects owned by [USER_NAME]?
+ 你確定è¦é€è¿” [USER_NAME] 所æ“有的物件?
<usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/>
</notification>
<notification name="InvalidTerrainBitDepth">
- Couldn&apos;t set region textures:
-Terrain texture [TEXTURE_NUM] has an invalid bit depth of [TEXTURE_BIT_DEPTH].
+ 無法設定地å€æ質:
+地形æ質 [TEXTURE_NUM] çš„ä½å…ƒæ·±åº¦ [TEXTURE_BIT_DEPTH] 無效。
-Replace texture [TEXTURE_NUM] with a 24-bit 512x512 or smaller image then click &quot;Apply&quot; again.
+è«‹å°‡æ質 [TEXTURE_NUM] 替æ›æˆ 24 ä½å…ƒ 512x512 或更å°åœ–åƒï¼Œç„¶å¾Œé»žæŒ‰ã€Œå¥—用ã€ã€‚
</notification>
<notification name="InvalidTerrainSize">
- Couldn&apos;t set region textures:
-Terrain texture [TEXTURE_NUM] is too large at [TEXTURE_SIZE_X]x[TEXTURE_SIZE_Y].
+ 無法設定地å€æ質:
+地形æ質 [TEXTURE_NUM] 的尺寸 [TEXTURE_SIZE_X]x[TEXTURE_SIZE_Y] 太大。
-Replace texture [TEXTURE_NUM] with a 24-bit 512x512 or smaller image then click &quot;Apply&quot; again.
+è«‹å°‡æ質 [TEXTURE_NUM] 替æ›æˆ 24 ä½å…ƒ 512x512 或更å°åœ–åƒï¼Œç„¶å¾Œé»žæŒ‰ã€Œå¥—用ã€ã€‚
</notification>
<notification name="RawUploadStarted">
- 上傳開始。將會花費約兩分é˜ï¼Œé€™å–決於你的連線速度。
+ 上傳開始。 視你的連線速度而定,這最多需時兩分é˜ã€‚
</notification>
<notification name="ConfirmBakeTerrain">
- Do you really want to bake the current terrain, make it the center for terrain raise/lower limits and the default for the &apos;Revert&apos; tool?
+ 你真的è¦ç¢ºå®šç”¢å‡ºç›®å‰åœ°å½¢ï¼Œä½¿å…¶æˆç‚ºåœ°å½¢å‡/é™æ¥µé™çš„中間值,並設為「復原ã€å·¥å…·çš„é è¨­å€¼ï¼Ÿ
<usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/>
</notification>
<notification name="MaxAllowedAgentOnRegion">
- You can only have [MAX_AGENTS] Allowed Residents.
+ 你最多åªèƒ½æœ‰ [MAX_AGENTS] ä½å…許居民。
</notification>
<notification name="MaxBannedAgentsOnRegion">
ä½ åªå¯ä»¥æœ‰æœ€å¤š [MAX_BANNED] ä½è¢«å°éŽ–的居民。
</notification>
<notification name="MaxAgentOnRegionBatch">
- Failure while attempting to add [NUM_ADDED] agents:
-Exceeds the [MAX_AGENTS] [LIST_TYPE] limit by [NUM_EXCESS].
+ 試圖增加 [NUM_ADDED] 人時失敗:
+超éŽäººæ•¸ä¸Šé™ [MAX_AGENTS] [LIST_TYPE]ï¼ˆè¶…éŽ [NUM_EXCESS] 人)。
</notification>
<notification name="MaxAllowedGroupsOnRegion">
- You can only have [MAX_GROUPS] Allowed Groups.
- <usetemplate name="okcancelbuttons" notext="å–消" yestext="Bake"/>
+ ä½ åªèƒ½æœ‰ [MAX_GROUPS] 個å…許的群組。
+ <usetemplate name="okcancelbuttons" notext="å–消" yestext="確定產出"/>
</notification>
<notification name="MaxManagersOnRegion">
ä½ åªå¯ä»¥æœ‰æœ€å¤š [MAX_MANAGER] ä½é ˜åœ°ç¶“ç†ã€‚
</notification>
<notification name="OwnerCanNotBeDenied">
- 無法添加領地æ“有者到領地的 &apos;被å°éŽ–çš„å±…æ°‘&apos; å單中。
+ 無法添加領地所有人到領地的 &apos;被å°éŽ–çš„å±…æ°‘&apos; å單中。
</notification>
<notification name="CanNotChangeAppearanceUntilLoaded">
無法變更外觀,直到æœè£èˆ‡é«”形下載完畢。
</notification>
<notification name="ClassifiedMustBeAlphanumeric">
- The name of your classified must start with a letter from A to Z or a number. No punctuation is allowed.
+ 你的個人廣告å稱必須以 A-Z å­—æ¯æˆ–數字開頭。 ä¸å…許標點符號。
</notification>
<notification name="CantSetBuyObject">
- Can&apos;t set Buy Object, because the object is not for sale.
-Please set the object for sale and try again.
+ 無法設定購買物件,該物件無法出售。
+è«‹é¸å®šå‡ºå”®ç‰©ä»¶ï¼Œå†è©¦ä¸€æ¬¡ã€‚
</notification>
<notification name="FinishedRawDownload">
- Finished download of raw terrain file to:
-[DOWNLOAD_PATH].
+ 原始地形檔案下載完æˆï¼š
+[DOWNLOAD_PATH]。
</notification>
<notification name="DownloadWindowsMandatory">
- 一個新版本的 [APP_NAME] 已經å¯ç”¨ã€‚
+ 有個新版本的 [APP_NAME] å¯ä¾›ä½¿ç”¨ã€‚
[MESSAGE]
-你必須下載這個更新以使用 [APP_NAME]。
+你必須下載這個更新æ‰å¯ä½¿ç”¨ [APP_NAME]。
<usetemplate name="okcancelbuttons" notext="çµæŸé€€å‡º" yestext="下載"/>
</notification>
<notification name="DownloadWindows">
@@ -1285,98 +1401,125 @@ Please set the object for sale and try again.
<usetemplate name="okcancelbuttons" notext="繼續" yestext="下載"/>
</notification>
<notification name="DownloadWindowsReleaseForDownload">
- An updated version of [APP_NAME] is available.
+ 一個 [APP_NAME] æ›´æ–°éŽçš„版本已經å¯ç”¨ã€‚
[MESSAGE]
-This update is not required, but we suggest you install it to improve performance and stability.
+這個更新並éžå¼·åˆ¶æ›´æ–°ï¼Œä½†æˆ‘們建議你安è£ä»¥å¢žå¼·æ•ˆèƒ½åŠç©©å®šæ€§ã€‚
<usetemplate name="okcancelbuttons" notext="繼續" yestext="下載"/>
</notification>
<notification name="DownloadLinuxMandatory">
- A new version of [APP_NAME] is available.
+ 有個新版本的 [APP_NAME] å¯ä¾›ä½¿ç”¨ã€‚
[MESSAGE]
-You must download this update to use [APP_NAME].
+你必須下載這個更新æ‰å¯ä½¿ç”¨ [APP_NAME]。
<usetemplate name="okcancelbuttons" notext="çµæŸé€€å‡º" yestext="下載"/>
</notification>
<notification name="DownloadLinux">
- An updated version of [APP_NAME] is available.
+ 一個 [APP_NAME] æ›´æ–°éŽçš„版本已經å¯ç”¨ã€‚
[MESSAGE]
-This update is not required, but we suggest you install it to improve performance and stability.
+這個更新並éžå¼·åˆ¶æ›´æ–°ï¼Œä½†æˆ‘們建議你安è£ä»¥å¢žå¼·æ•ˆèƒ½åŠç©©å®šæ€§ã€‚
<usetemplate name="okcancelbuttons" notext="繼續" yestext="下載"/>
</notification>
<notification name="DownloadLinuxReleaseForDownload">
- An updated version of [APP_NAME] is available.
+ 一個 [APP_NAME] æ›´æ–°éŽçš„版本已經å¯ç”¨ã€‚
[MESSAGE]
-This update is not required, but we suggest you install it to improve performance and stability.
+這個更新並éžå¼·åˆ¶æ›´æ–°ï¼Œä½†æˆ‘們建議你安è£ä»¥å¢žå¼·æ•ˆèƒ½åŠç©©å®šæ€§ã€‚
<usetemplate name="okcancelbuttons" notext="繼續" yestext="下載"/>
</notification>
<notification name="DownloadMacMandatory">
- A new version of [APP_NAME] is available.
+ 有個新版本的 [APP_NAME] å¯ä¾›ä½¿ç”¨ã€‚
[MESSAGE]
-You must download this update to use [APP_NAME].
+你必須下載這個更新æ‰å¯ä½¿ç”¨ [APP_NAME]。
-Download to your Applications folder?
+下載到 Applications 資料夾?
<usetemplate name="okcancelbuttons" notext="çµæŸé€€å‡º" yestext="下載"/>
</notification>
<notification name="DownloadMac">
- An updated version of [APP_NAME] is available.
+ 一個 [APP_NAME] æ›´æ–°éŽçš„版本已經å¯ç”¨ã€‚
[MESSAGE]
-This update is not required, but we suggest you install it to improve performance and stability.
+這個更新並éžå¼·åˆ¶æ›´æ–°ï¼Œä½†æˆ‘們建議你安è£ä»¥å¢žå¼·æ•ˆèƒ½åŠç©©å®šæ€§ã€‚
-Download to your Applications folder?
+下載到 Applications 資料夾?
<usetemplate name="okcancelbuttons" notext="繼續" yestext="下載"/>
</notification>
<notification name="DownloadMacReleaseForDownload">
- An updated version of [APP_NAME] is available.
+ 一個 [APP_NAME] æ›´æ–°éŽçš„版本已經å¯ç”¨ã€‚
[MESSAGE]
-This update is not required, but we suggest you install it to improve performance and stability.
+這個更新並éžå¼·åˆ¶æ›´æ–°ï¼Œä½†æˆ‘們建議你安è£ä»¥å¢žå¼·æ•ˆèƒ½åŠç©©å®šæ€§ã€‚
-Download to your Applications folder?
+下載到 Applications 資料夾?
<usetemplate name="okcancelbuttons" notext="繼續" yestext="下載"/>
</notification>
<notification name="FailedUpdateInstall">
- An error occurred installing the viewer update.
-Please download and install the latest viewer from
-http://secondlife.com/download.
+ 安è£æ›´æ–°ç‰ˆ Viewer 時出錯。
+請到 http://secondlife.com/download 下載並安è£æœ€æ–°ç‰ˆ Viewer。
<usetemplate name="okbutton" yestext="確定"/>
</notification>
<notification name="FailedRequiredUpdateInstall">
- We were unable to install a required update.
-You will be unable to log in until [APP_NAME] has been updated.
+ 無法安è£å¿…è¦çš„更新。
+é™¤éž [APP_NAME] 更新,你將無法登入。
-Please download and install the latest viewer from
-http://secondlife.com/download.
+請到 http://secondlife.com/download 下載並安è£æœ€æ–°ç‰ˆ Viewer。
<usetemplate name="okbutton" yestext="çµæŸé€€å‡º"/>
</notification>
<notification name="UpdaterServiceNotRunning">
- There is a required update for your Second Life Installation.
+ 你已安è£çš„第二人生軟體ç¾æœ‰ä¸€å€‹å¿…è¦çš„更新。
-You may download this update from http://www.secondlife.com/downloads
-or you can install it now.
+ä½ å¯ä»¥åˆ° http://www.secondlife.com/downloads 下載此更新,或者ç¾åœ¨ç«‹å³å®‰è£ã€‚
<usetemplate name="okcancelbuttons" notext="çµæŸé€€å‡ºç¬¬äºŒäººç”Ÿ" yestext="ç«‹å³ä¸‹è¼‰åŠå®‰è£"/>
</notification>
<notification name="DownloadBackgroundTip">
- We have downloaded an update to your [APP_NAME] installation.
-Version [VERSION] [[RELEASE_NOTES_FULL_URL] Information about this update]
+ 我們已為你的 [APP_NAME] 軟體下載了更新。
+[VERSION] 版本 [[RELEASE_NOTES_FULL_URL] 關於此更新的資訊]
<usetemplate name="okcancelbuttons" notext="ç¨å€™..." yestext="ç«‹å³å®‰è£åŠé‡æ–°å•Ÿå‹• [APP_NAME]"/>
</notification>
<notification name="DownloadBackgroundDialog">
- We have downloaded an update to your [APP_NAME] installation.
-Version [VERSION] [[RELEASE_NOTES_FULL_URL] Information about this update]
- <usetemplate name="okcancelbuttons" notext="梢候..." yestext="ç«‹å³å®‰è£åŠé‡æ–°å•Ÿå‹• [APP_NAME]"/>
+ 我們已為你的 [APP_NAME] 軟體下載了更新。
+[VERSION] 版本 [[RELEASE_NOTES_FULL_URL] 關於此更新的資訊]
+ <usetemplate name="okcancelbuttons" notext="ç¨å€™..." yestext="ç«‹å³å®‰è£åŠé‡æ–°å•Ÿå‹• [APP_NAME]"/>
</notification>
<notification name="RequiredUpdateDownloadedVerboseDialog">
- We have downloaded a required software update.
-Version [VERSION]
+ 我們已下載了一個必è¦çš„軟體更新。
+[VERSION] 版本 [[INFO_URL] 關於此更新的資訊]
-We must restart [APP_NAME] to install the update.
+我門必須é‡æ–°å•Ÿå‹• [APP_NAME] 以安è£æ›´æ–°ã€‚
<usetemplate name="okbutton" yestext="確定"/>
</notification>
<notification name="RequiredUpdateDownloadedDialog">
我門必須é‡æ–°å•Ÿå‹• [APP_NAME] 以安è£æ›´æ–°ã€‚
+[[INFO_URL] 關於此更新的資訊]
+ <usetemplate name="okbutton" yestext="確定"/>
+ </notification>
+ <notification name="OtherChannelDownloadBackgroundTip">
+ 我們已為你的 [APP_NAME] 軟體下載了更新。
+版本:[VERSION]
+原本試驗性質的ç€è¦½å™¨å·²è¢« [NEW_CHANNEL] ç€è¦½å™¨å–代,
+åƒè¦‹[[INFO_URL] 此更新版的詳情]
+ <usetemplate name="okcancelbuttons" notext="ç¨å€™..." yestext="ç«‹å³å®‰è£ä¸¦é‡æ–°å•Ÿå‹• [APP_NAME]"/>
+ </notification>
+ <notification name="OtherChannelDownloadBackgroundDialog">
+ 我們已為你的 [APP_NAME] 軟體下載了更新。
+版本:[VERSION]
+原本試驗性質的ç€è¦½å™¨å·²è¢« [NEW_CHANNEL] ç€è¦½å™¨å–代,
+åƒè¦‹[[INFO_URL] 介紹此更新版的資訊]
+ <usetemplate name="okcancelbuttons" notext="ç¨å€™â€¦" yestext="ç«‹å³å®‰è£ä¸¦é‡æ–°å•Ÿå‹• [APP_NAME]"/>
+ </notification>
+ <notification name="OtherChannelRequiredUpdateDownloadedVerboseDialog">
+ 我們已下載了一個必è¦çš„軟體更新。
+版本:[VERSION]
+原本試驗性質的ç€è¦½å™¨å·²è¢« [NEW_CHANNEL] ç€è¦½å™¨å–代,
+åƒè¦‹[[INFO_URL] 介紹此更新版的資訊]
+
+我們必須é‡æ–°å•Ÿå‹• [APP_NAME] 以便安è£æ›´æ–°ã€‚
+ <usetemplate name="okbutton" yestext="確定"/>
+ </notification>
+ <notification name="OtherChannelRequiredUpdateDownloadedDialog">
+ 我們必須é‡æ–°å•Ÿå‹• [APP_NAME] 以便安è£æ›´æ–°ã€‚
+原本試驗性質的ç€è¦½å™¨å·²è¢« [NEW_CHANNEL] ç€è¦½å™¨å–代,
+åƒè¦‹[[INFO_URL] 介紹此更新版的資訊]
<usetemplate name="okbutton" yestext="確定"/>
</notification>
<notification name="DeedObjectToGroup">
- Deeding this object will cause the group to:
-* Receive L$ paid into the object
+ 讓渡此物件將å¯è®“這個群組:
+* 收å–付給此物件的 L$
<usetemplate ignoretext="在我讓渡一個物件給群組å‰ç¢ºèª" name="okcancelignore" notext="å–消" yestext="讓渡"/>
</notification>
<notification name="WebLaunchExternalTarget">
@@ -1388,7 +1531,7 @@ We must restart [APP_NAME] to install the update.
<usetemplate ignoretext="啟動我的ç€è¦½å™¨ä»¥ç®¡ç†æˆ‘的帳戶" name="okcancelignore" notext="å–消" yestext="確定"/>
</notification>
<notification name="WebLaunchSecurityIssues">
- Visit the [SECOND_LIFE] Wiki for details of how to report a security issue.
+ 造訪 [SECOND_LIFE] 維基察看如何æ報安全å•é¡Œã€‚
<usetemplate ignoretext="開啟我的網é ç€è¦½å™¨ä»¥å­¸ç¿’如何回報一個安全性的議題" name="okcancelignore" notext="å–消" yestext="確定"/>
</notification>
<notification name="WebLaunchQAWiki">
@@ -1412,72 +1555,79 @@ We must restart [APP_NAME] to install the update.
<usetemplate ignoretext="開啟我的網é ç€è¦½å™¨ä»¥å¯Ÿçœ‹ LSL å…¥å£" name="okcancelignore" notext="å–消" yestext="å‰å¾€é é¢"/>
</notification>
<notification name="ReturnToOwner">
- 你確定è¦é€€å›žæ‰€é¸æ“‡çš„物件給它們的æ“有者嗎? å¯è½‰ç§»ä¸¦è®“渡的物件將會退回給它們的å‰ä¸€ä½æ“有者。
+ 你確定è¦é€è¿”所é¸ç‰©ä»¶çµ¦ç‰©ä¸»ï¼Ÿ å¯è½‰è®“的已讓渡物件將é€è¿”原物主。
*警告* éžå¯è½‰ç§»ä¸¦è®“渡的物件將會被刪除!
- <usetemplate ignoretext="在我退回物件給它們的æ“有者å‰ç¢ºèª" name="okcancelignore" notext="å–消" yestext="確定"/>
+ <usetemplate ignoretext="在我退回物件給它們的所有人å‰ç¢ºèª" name="okcancelignore" notext="å–消" yestext="確定"/>
</notification>
<notification name="GroupLeaveConfirmMember">
ä½ ç›®å‰æ˜¯ &lt;nolink&gt;[GROUP]&lt;/nolink&gt; 群組的æˆå“¡ã€‚
是å¦è¦é›¢é–‹ç¾¤çµ„?
<usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/>
</notification>
+ <notification name="OwnerCannotLeaveGroup">
+ 無法離開群組。 你是此群組僅存的所有人,ä¸å¾—離開群組。 請先把所有人è·éŠœæŒ‡æ´¾çµ¦å¦ä¸€äººã€‚
+ <usetemplate name="okbutton" yestext="確定"/>
+ </notification>
<notification name="ConfirmKick">
你確定è¦è¸¢å‡ºé€™ç¶²æ ¼å…§çš„全部居民?
<usetemplate name="okcancelbuttons" notext="å–消" yestext="踢出全部居民"/>
</notification>
<notification name="MuteLinden">
- Sorry, you cannot block a Linden.
+ 抱歉,你無法å°éŽ–ä»»ä½•ä¸€ä½ Linden。
<usetemplate name="okbutton" yestext="確定"/>
</notification>
<notification name="CannotStartAuctionAlreadyForSale">
- You cannot start an auction on a parcel which is already set for sale. Disable the land sale if you are sure you want to start an auction.
+ 你無法在已在出售中的地段裡進行æ‹è³£ã€‚ 你如果確定è¦æ‹è³£ï¼Œè«‹å…ˆåœæ­¢åœŸåœ°å‡ºå”®ã€‚
</notification>
- <notification label="Block object by name failed" name="MuteByNameFailed">
- You already have blocked this name.
+ <notification label="ä¾å稱å°éŽ–物件失敗" name="MuteByNameFailed">
+ 你已經å°éŽ–了這個å稱。
<usetemplate name="okbutton" yestext="確定"/>
</notification>
<notification name="RemoveItemWarn">
- Though permitted, deleting contents may damage the object. Do you want to delete that item?
+ 雖然å…許這麼åšï¼Œåˆªé™¤å…§å®¹å¯èƒ½æœƒç ´å£žç‰©ä»¶ã€‚ ä½ è¦åˆªé™¤è©²ç‰©é …嗎?
<usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/>
</notification>
<notification name="CantOfferCallingCard">
- Cannot offer a calling card at this time. Please try again in a moment.
+ 此時無法æä¾›å片。 è«‹ç¨å€™å†è©¦ã€‚
<usetemplate name="okbutton" yestext="確定"/>
</notification>
<notification name="CantOfferFriendship">
- Cannot offer friendship at this time. Please try again in a moment.
+ 此時無法發出交å‹é‚€è«‹ã€‚ è«‹ç¨å€™å†è©¦ã€‚
<usetemplate name="okbutton" yestext="確定"/>
</notification>
- <notification name="BusyModeSet">
- Busy mode is set.
-Chat and instant messages will be hidden. Instant messages will get your Busy mode response. All teleportation offers will be declined. All inventory offers will go to your Trash.
- <usetemplate ignoretext="我變更我的狀態為忙碌模å¼" name="okignore" yestext="確定"/>
+ <notification name="DoNotDisturbModeSet">
+ 「請勿打擾ã€æ¨¡å¼ç›®å‰æ˜¯é–‹å•Ÿç‹€æ…‹ã€‚ ä½ å°‡ä¸æœƒæ”¶åˆ°ä»»ä½•ç™¼çµ¦ä½ çš„訊æ¯é€šçŸ¥ã€‚
+
+- 其他居民將收到你的「請勿打擾ã€å›žæ‡‰ï¼ˆå›žæ‡‰å…§å®¹è¨­æ–¼ã€Œå好設定 &gt; 一般設定ã€ï¼‰ã€‚
+- 所有瞬間傳é€çš„邀請都將被婉拒。
+- 所有語音來電都將拒絕接è½ã€‚
+ <usetemplate ignoretext="我變更我的狀態為「請勿打擾ã€æ¨¡å¼" name="okignore" yestext="確定"/>
</notification>
<notification name="JoinedTooManyGroupsMember">
- You have reached your maximum number of groups. Please leave another group before joining this one, or decline the offer.
-[NAME] has invited you to join a group as a member.
+ ä½ å·²é”å¯åŒæ™‚加入的群組數上é™ã€‚ 請先離開å¦ä¸€å€‹ç¾¤çµ„å†åŠ å…¥é€™ä¸€å€‹ï¼Œæˆ–婉拒加入邀請。
+[NAME] 已邀請你加入一個群組æˆç‚ºä¸€å“¡ã€‚
<usetemplate name="okcancelbuttons" notext="è¬çµ•" yestext="加入"/>
</notification>
<notification name="JoinedTooManyGroups">
- You have reached your maximum number of groups. Please leave some group before joining or creating a new one.
+ ä½ å·²é”å¯åŒæ™‚加入的群組數上é™ã€‚ 請先離開æŸäº›ç¾¤çµ„å†åŠ å…¥æˆ–新建新群組。
<usetemplate name="okbutton" yestext="確定"/>
</notification>
<notification name="KickUser">
踢出這個居民並留給他什麼訊æ¯ï¼Ÿ
<form name="form">
<input name="message">
- An administrator has logged you off.
+ 一ä½ç®¡ç†å“¡å·²è¿«ä½¿ä½ ç™»å‡ºã€‚
</input>
<button name="OK" text="確定"/>
<button name="Cancel" text="å–消"/>
</form>
</notification>
<notification name="KickAllUsers">
- Kick everyone currently on the grid with what message?
+ 踢出網格上的æ¯å€‹äººï¼Œç•™çµ¦ä»–們什麼訊æ¯ï¼Ÿ
<form name="form">
<input name="message">
- An administrator has logged you off.
+ 一ä½ç®¡ç†å“¡å·²è¿«ä½¿ä½ ç™»å‡ºã€‚
</input>
<button name="OK" text="確定"/>
<button name="Cancel" text="å–消"/>
@@ -1487,7 +1637,7 @@ Chat and instant messages will be hidden. Instant messages will get your Busy mo
å‡çµé€™ä½å±…民時åŒæ™‚留下什麼訊æ¯ï¼Ÿ
<form name="form">
<input name="message">
- 你已經被å‡çµäº†ã€‚ä½ å°‡ä¸èƒ½ç§»å‹•æˆ–èŠå¤©ã€‚管ç†å“¡å°‡æœƒä»¥å³æ™‚訊æ¯è¯ç¹«ä½ ï¼ˆIM)。
+ 你已被å‡çµã€‚ 你無法移動或èŠå¤©ã€‚ 會有管ç†å“¡é€éŽå³æ™‚è¨Šæ¯ IM 和你è¯çµ¡ã€‚
</input>
<button name="OK" text="確定"/>
<button name="Cancel" text="å–消"/>
@@ -1497,75 +1647,80 @@ Chat and instant messages will be hidden. Instant messages will get your Busy mo
將這ä½å±…民解å‡ä¸¦åŒæ™‚留下什麼訊æ¯ï¼Ÿ
<form name="form">
<input name="message">
- You are no longer frozen.
+ 你已被解除å‡çµã€‚
</input>
<button name="OK" text="確定"/>
<button name="Cancel" text="å–消"/>
</form>
</notification>
<notification name="SetDisplayNameSuccess">
- Hi [DISPLAY_NAME]!
+ [DISPLAY_NAME],你好ï¼
-Just like in real life, it takes a while for everyone to learn about a new name. Please allow several days for [http://wiki.secondlife.com/wiki/Setting_your_display_name your name to update] in objects, scripts, search, etc.
+瞭解é©æ‡‰ä¸€å€‹æ–°å字是需è¦æ™‚間的,正如ç¾å¯¦ç”Ÿæ´»é‚£æ¨£ã€‚ 請給我們幾天時間é‡å°æ‰€æœ‰ç‰©ä»¶ã€è…³æœ¬ã€æœå°‹ç­‰æ–¹é¢ [http://wiki.secondlife.com/wiki/Setting_your_display_name æ›´æ–°ä½ çš„åå­—]。
</notification>
<notification name="SetDisplayNameBlocked">
- 抱歉,你ä¸å¯ä»¥è®Šæ›´ä½ çš„顯示å稱。如果你覺得這是錯誤,請連繫支æ´å» å•†ã€‚
+ 抱歉,你無法更改你的顯示å。 如你èªç‚ºæœ‰å‡ºéŒ¯ï¼Œè«‹è¯çµ¡æ”¯æ´äººå“¡ã€‚
</notification>
<notification name="SetDisplayNameFailedLength">
- 抱歉,這å稱太長。顯示å稱最大長度為 [LENGTH] 字元。
+ 抱歉,該å稱太長。 顯示å稱最大長度為 [LENGTH] 字元。
請嘗試短一些的å稱。
</notification>
<notification name="SetDisplayNameFailedGeneric">
- Sorry, we could not set your display name. Please try again later.
+ 抱歉,我們無法設定你的顯示å。 è«‹ç¨å€™å†è©¦ä¸€æ¬¡ã€‚
</notification>
<notification name="SetDisplayNameMismatch">
- The display names you entered do not match. Please re-enter.
+ 你所輸入的顯示åä¸ç›¸ç¬¦ã€‚ è«‹å†è¼¸å…¥ä¸€æ¬¡ã€‚
</notification>
<notification name="AgentDisplayNameUpdateThresholdExceeded">
- Sorry, you have to wait longer before you can change your display name.
+ 抱歉,你必須å†ç­‰ä¸€æ®µæ™‚é–“æ‰èƒ½æ›´æ”¹ä½ çš„顯示å。
-See http://wiki.secondlife.com/wiki/Setting_your_display_name
+åƒè¦‹ http://wiki.secondlife.com/wiki/Setting_your_display_name
-Please try again later.
+è«‹ç¨å€™å†è©¦ä¸€æ¬¡ã€‚
</notification>
<notification name="AgentDisplayNameSetBlocked">
- Sorry, we could not set your requested name because it contains a banned word.
+ 抱歉,我們無法設定你想è¦çš„å稱,它å«æœ‰ç¦ç”¨å­—眼。
- Please try a different name.
+ 請用ä¸åŒçš„å稱試試。
</notification>
<notification name="AgentDisplayNameSetInvalidUnicode">
- The display name you wish to set contains invalid characters.
+ 你希望設定的顯示åå«æœ‰ç„¡æ•ˆå­—元。
</notification>
<notification name="AgentDisplayNameSetOnlyPunctuation">
- Your display name must contain letters other than punctuation.
+ 你的顯示å必須包å«éžæ¨™é»žç¬¦è™Ÿçš„字元。
</notification>
<notification name="DisplayNameUpdate">
- [OLD_NAME] ([SLID]) is now known as [NEW_NAME].
+ [OLD_NAME] ([SLID]) ç¾åœ¨æœ‰äº†æ–°åå­— [NEW_NAME]。
</notification>
<notification name="OfferTeleport">
- Offer a teleport to your location with the following message?
+ 用下列訊æ¯ç™¼å‡ºçž¬é–“傳é€é‚€è«‹ä¾†åˆ°ä½ çš„ä½ç½®ï¼Ÿ
<form name="form">
<input name="message">
- 加入我到 [REGION]
+ 在 [REGION] 和我會é¢
</input>
<button name="OK" text="確定"/>
<button name="Cancel" text="å–消"/>
</form>
</notification>
+ <notification name="TooManyTeleportOffers">
+ 你試圖é€å‡º [OFFERS] 個瞬間傳é€é‚€è«‹ã€‚
+超éŽäº† [LIMIT] 個的上é™ã€‚
+ <usetemplate name="okbutton" yestext="確定"/>
+ </notification>
<notification name="OfferTeleportFromGod">
- God summon Resident to your location?
+ 用神的權力把居民å¬åˆ°ä½ çš„ä½ç½®ï¼Ÿ
<form name="form">
<input name="message">
- Join me in [REGION]
+ 在 [REGION] 和我會é¢
</input>
<button name="OK" text="確定"/>
<button name="Cancel" text="å–消"/>
</form>
</notification>
<notification name="TeleportFromLandmark">
- Are you sure you want to teleport to &lt;nolink&gt;[LOCATION]&lt;/nolink&gt;?
- <usetemplate ignoretext="Confirm that I want to teleport to a landmark" name="okcancelignore" notext="å–消" yestext="瞬間傳é€"/>
+ 你確定è¦çž¬é–“傳é€åˆ°&lt;nolink&gt;[LOCATION]&lt;/nolink&gt;?
+ <usetemplate ignoretext="確èªæˆ‘è¦çž¬é–“傳é€åˆ°æŸå€‹åœ°æ¨™" name="okcancelignore" notext="å–消" yestext="瞬間傳é€"/>
</notification>
<notification name="TeleportToPick">
瞬間傳é€åˆ° [PICK]?
@@ -1580,57 +1735,57 @@ Please try again later.
<usetemplate ignoretext="確èªæˆ‘è¦çž¬é–“傳é€åˆ°æ­·å²ç´€éŒ„中的ä½ç½®" name="okcancelignore" notext="å–消" yestext="瞬間傳é€"/>
</notification>
<notification label="é€å‡ºè¨Šæ¯çµ¦ä½ é ˜åœ°å…§çš„æ¯ä¸€å€‹äºº" name="MessageEstate">
- Type a short announcement which will be sent to everyone currently in your estate.
+ 輸入簡短公告,公告將發é€çµ¦é ˜åœ°è£¡æ‰€æœ‰äººã€‚
<form name="form">
<button name="OK" text="確定"/>
<button name="Cancel" text="å–消"/>
</form>
</notification>
- <notification label="Change Linden Estate" name="ChangeLindenEstate">
- You are about to change a Linden owned estate (mainland, teen grid, orientation, etc.).
+ <notification label="更改 Linden 領地" name="ChangeLindenEstate">
+ ä½ å³å°‡æ›´æ”¹ä¸€å€‹ Linden 所æ“有的領地(大陸ã€é’少年網格ã€å°Žå¼•å€ç­‰ï¼‰ã€‚
-This is EXTREMELY DANGEROUS because it can fundamentally affect the Resident experience. On the mainland, it will change thousands of regions and make the spaceserver hiccup.
+這動作éžå¸¸å±éšªï¼Œå®ƒæœƒæ ¹æœ¬å½±éŸ¿æ‰€æœ‰å±…民的體驗。 在大陸上,它將更動數åƒå€‹åœ°å€ï¼Œå°Žè‡´ç©ºé–“伺æœå™¨ç™¼ç”Ÿä¸é †ã€‚
-Proceed?
+繼續?
<usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/>
</notification>
- <notification label="Change Linden Estate Access" name="ChangeLindenAccess">
- You are about to change the access list for a Linden owned estate (mainland, teen grid, orientation, etc.).
+ <notification label="更改 Linden 領地出入權" name="ChangeLindenAccess">
+ ä½ å³å°‡æ›´æ”¹ä¸€å€‹ Linden 所æ“有領地(大陸ã€é’少年網格ã€å°Žå¼•å€ç­‰ï¼‰çš„出入權。
-This is DANGEROUS and should only be done to invoke the hack allowing objects/L$ to be transfered in/out of a grid.
-It will change thousands of regions and make the spaceserver hiccup.
+這動作很å±éšªï¼Œåªåœ¨éœ€è¦æŠŠç‰©ä»¶æˆ– L$ é€å‡ºæˆ–é€å…¥ç¶²æ ¼ï¼Œåˆç„¡æ›´å¥½æ–¹æ³•æ™‚ä¸å¾—已使用。
+它將更動數åƒå€‹åœ°å€ï¼Œå°Žè‡´ç©ºé–“伺æœå™¨ç™¼ç”Ÿä¸é †ã€‚
<usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/>
</notification>
<notification label="é¸æ“‡é ˜åœ°" name="EstateAllowedAgentAdd">
- Add to allowed list for this estate only or for [ALL_ESTATES]?
+ 僅é‡å°é€™å€‹é ˜åœ°æˆ–é‡å° [ALL_ESTATES] 將它新增到å…許清單?
<usetemplate canceltext="å–消" name="yesnocancelbuttons" notext="全部領地" yestext="這個領地"/>
</notification>
<notification label="é¸æ“‡é ˜åœ°" name="EstateAllowedAgentRemove">
- Remove from allowed list for this estate only or for [ALL_ESTATES]?
+ 僅é‡å°é€™å€‹é ˜åœ°æˆ–é‡å° [ALL_ESTATES] 將它從å…許清單中移除?
<usetemplate canceltext="å–消" name="yesnocancelbuttons" notext="全部領地" yestext="這個領地"/>
</notification>
<notification label="é¸æ“‡é ˜åœ°" name="EstateAllowedGroupAdd">
- Add to group allowed list for this estate only or for [ALL_ESTATES]?
+ 僅é‡å°é€™å€‹é ˜åœ°æˆ–é‡å° [ALL_ESTATES] 將它新增到群組å…許清單?
<usetemplate canceltext="å–消" name="yesnocancelbuttons" notext="全部領地" yestext="這個領地"/>
</notification>
<notification label="é¸æ“‡é ˜åœ°" name="EstateAllowedGroupRemove">
- Remove from group allowed list for this estate only or [ALL_ESTATES]?
+ 僅é‡å°é€™å€‹é ˜åœ°æˆ–é‡å° [ALL_ESTATES] 將它從群組å…許清單中移除?
<usetemplate canceltext="å–消" name="yesnocancelbuttons" notext="全部領地" yestext="這個領地"/>
</notification>
<notification label="é¸æ“‡é ˜åœ°" name="EstateBannedAgentAdd">
- Deny access for this estate only or for [ALL_ESTATES]?
+ 僅é‡å°é€™å€‹é ˜åœ°æˆ–é‡å° [ALL_ESTATES] ç¦æ­¢å‡ºå…¥ï¼Ÿ
<usetemplate canceltext="å–消" name="yesnocancelbuttons" notext="全部領地" yestext="這個領地"/>
</notification>
<notification label="é¸æ“‡é ˜åœ°" name="EstateBannedAgentRemove">
- Remove this Resident from the ban list for access for this estate only or for [ALL_ESTATES]?
+ 僅é‡å°é€™å€‹é ˜åœ°æˆ–é‡å° [ALL_ESTATES] 將這個居民從ç¦æ­¢å‡ºå…¥æ¸…單中除å?
<usetemplate canceltext="å–消" name="yesnocancelbuttons" notext="全部領地" yestext="這個領地"/>
</notification>
<notification label="é¸æ“‡é ˜åœ°" name="EstateManagerAdd">
- Add estate manager for this estate only or for [ALL_ESTATES]?
+ 僅é‡å°é€™å€‹é ˜åœ°æˆ–é‡å° [ALL_ESTATES] 新增領地管ç†äººï¼Ÿ
<usetemplate canceltext="å–消" name="yesnocancelbuttons" notext="全部領地" yestext="這個領地"/>
</notification>
<notification label="é¸æ“‡é ˜åœ°" name="EstateManagerRemove">
- Remove estate manager for this estate only or for [ALL_ESTATES]?
+ 僅é‡å°é€™å€‹é ˜åœ°æˆ–é‡å° [ALL_ESTATES] 移除領地管ç†äººï¼Ÿ
<usetemplate canceltext="å–消" name="yesnocancelbuttons" notext="全部領地" yestext="這個領地"/>
</notification>
<notification label="確èªè¸¢å‡º" name="EstateKickUser">
@@ -1638,330 +1793,390 @@ It will change thousands of regions and make the spaceserver hiccup.
<usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/>
</notification>
<notification name="EstateChangeCovenant">
- Are you sure you want to change the Estate Covenant?
+ 你確定è¦æ›´æ”¹é ˜åœ°å¥‘約?
<usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/>
</notification>
<notification name="RegionEntryAccessBlocked">
- You are not allowed in that Region due to your maturity Rating. This may be a result of a lack of information validating your age.
-
-Please verify you have the latest Viewer installed, and go to the Knowledge Base for details on accessing areas with this maturity rating.
+ 你所欲å‰å¾€çš„地å€å«æœ‰è¶…éŽä½ ç›®å‰å好的分級的內容。 ä½ å¯ä»¥åˆ°ã€Œæˆ‘自己 &gt; å好設定 &gt; 一般設定ã€è®Šæ›´ä½ çš„å好設定。
<usetemplate name="okbutton" yestext="確定"/>
</notification>
- <notification name="RegionEntryAccessBlocked_KB">
- You are not allowed in that region due to your maturity Rating.
-
-Go to the Knowledge Base for more information about maturity Ratings?
+ <notification name="RegionEntryAccessBlocked_AdultsOnlyContent">
+ 你所欲å‰å¾€çš„地å€å«æœ‰ [REGIONMATURITY] 的分級內容,僅é™æˆäººã€‚
<url name="url">
http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview
</url>
- <usetemplate ignoretext="I can&apos;t enter this Region, due to restrictions of the maturity Rating" name="okcancelignore" notext="關閉" yestext="Go to Knowledge Base"/>
+ <usetemplate ignoretext="跨越地å€ï¼šä½ æ‰€æ¬²å‰å¾€çš„地å€å«æœ‰é™åˆ¶çµ¦æˆäººçš„內容。" name="okcancelignore" notext="關閉" yestext="å‰å¾€çŸ¥è­˜åº«"/>
</notification>
<notification name="RegionEntryAccessBlocked_Notify">
- You are not allowed in that region due to your maturity Rating.
+ 你所欲å‰å¾€çš„地å€åŒ…å« [REGIONMATURITY] 分級的內容,å¯æ˜¯ä½ ç›®å‰çš„å好設定排除了 [REGIONMATURITY] 分級的內容。
+ </notification>
+ <notification name="RegionEntryAccessBlocked_NotifyAdultsOnly">
+ 你所欲å‰å¾€çš„地å€å«æœ‰ [REGIONMATURITY] 的分級內容,僅é™æˆäººã€‚
</notification>
<notification name="RegionEntryAccessBlocked_Change">
- You are not allowed in that Region due to your maturity Rating preference.
-
-To enter the desired region, please change your maturity Rating preference. This will allow you to search for and access [REGIONMATURITY] content. To undo any changes, go to Me &gt; Preferences &gt; General.
+ 你所欲å‰å¾€çš„地å€åŒ…å« [REGIONMATURITY] 分級的內容,å¯æ˜¯ä½ ç›®å‰çš„å好設定排除了 [REGIONMATURITY] 分級的內容。 ä½ å¯ä»¥è®Šæ›´ä½ çš„å好設定,或å–消å‰å¾€ã€‚ ä½ çš„å好設定變更後,你å¯ä»¥è©¦åœ–å†é€²å…¥è©²åœ°å€ã€‚
<form name="form">
- <button name="OK" text="Change Preference"/>
- <button name="Cancel" text="Close"/>
- <ignore name="ignore" text="My chosen Rating preference prevents me from entering a Region"/>
+ <button name="OK" text="變更å好設定"/>
+ <button name="Cancel" text="å–消"/>
+ <ignore name="ignore" text="跨越地å€ï¼šä½ æ‰€æ¬²å‰å¾€çš„地å€å«æœ‰è¢«ä½ ç›®å‰çš„å好設定排除的分級內容。"/>
</form>
</notification>
+ <notification name="RegionEntryAccessBlocked_PreferencesOutOfSync">
+ 發生技術å•é¡Œï¼Œä½ çš„å好設定和伺æœå™¨ä¸Šçš„ä¸ä¸€è‡´ã€‚
+ <usetemplate name="okbutton" yestext="確定"/>
+ </notification>
+ <notification name="TeleportEntryAccessBlocked">
+ 你所欲å‰å¾€çš„地å€å«æœ‰è¶…éŽä½ ç›®å‰å好的分級的內容。 ä½ å¯ä»¥åˆ°ã€Œæˆ‘自己 &gt; å好設定 &gt; 一般設定ã€è®Šæ›´ä½ çš„å好設定。
+ <usetemplate name="okbutton" yestext="確定"/>
+ </notification>
+ <notification name="TeleportEntryAccessBlocked_AdultsOnlyContent">
+ 你所欲å‰å¾€çš„地å€å«æœ‰ [REGIONMATURITY] 的分級內容,僅é™æˆäººã€‚
+ <url name="url">
+ http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview
+ </url>
+ <usetemplate ignoretext="瞬間傳é€ï¼šä½ æ‰€æ¬²å‰å¾€çš„地å€å«æœ‰é™åˆ¶çµ¦æˆäººçš„內容。" name="okcancelignore" notext="關閉" yestext="å‰å¾€çŸ¥è­˜åº«"/>
+ </notification>
+ <notification name="TeleportEntryAccessBlocked_Notify">
+ 你所欲å‰å¾€çš„地å€åŒ…å« [REGIONMATURITY] 分級的內容,å¯æ˜¯ä½ ç›®å‰çš„å好設定排除了 [REGIONMATURITY] 分級的內容。
+ </notification>
+ <notification name="TeleportEntryAccessBlocked_NotifyAdultsOnly">
+ 你所欲å‰å¾€çš„地å€å«æœ‰ [REGIONMATURITY] 的分級內容,僅é™æˆäººã€‚
+ </notification>
+ <notification name="TeleportEntryAccessBlocked_ChangeAndReTeleport">
+ 你所欲å‰å¾€çš„地å€åŒ…å« [REGIONMATURITY] 分級的內容,å¯æ˜¯ä½ ç›®å‰çš„å好設定排除了 [REGIONMATURITY] 分級的內容。 我們å¯ä»¥è®Šæ›´ä½ çš„å好設定好讓你繼續瞬間傳é€ï¼Œä½ ä¹Ÿå¯å–消這動作。
+ <form name="form">
+ <button name="OK" text="變更後繼續"/>
+ <button name="Cancel" text="å–消"/>
+ <ignore name="ignore" text="瞬間傳é€ï¼ˆå¯é‡å•Ÿï¼‰ï¼šä½ æ‰€æ¬²å‰å¾€çš„地å€å«æœ‰è¢«ä½ ç›®å‰çš„å好設定排除的分級內容。"/>
+ </form>
+ </notification>
+ <notification name="TeleportEntryAccessBlocked_Change">
+ 你所欲å‰å¾€çš„地å€åŒ…å« [REGIONMATURITY] 分級的內容,å¯æ˜¯ä½ ç›®å‰çš„å好設定排除了 [REGIONMATURITY] 分級的內容。 我們å¯ä»¥è®Šæ›´ä½ çš„å好設定,你也å¯å–消瞬間傳é€ã€‚ ä½ çš„å好設定變更後,你å¯ä»¥å†å˜—試瞬間傳é€ã€‚
+ <form name="form">
+ <button name="OK" text="變更å好設定"/>
+ <button name="Cancel" text="å–消"/>
+ <ignore name="ignore" text="瞬間傳é€ï¼ˆä¸å¯é‡å•Ÿï¼‰ï¼šä½ æ‰€æ¬²å‰å¾€çš„地å€å«æœ‰è¢«ä½ ç›®å‰çš„å好設定排除的分級內容。"/>
+ </form>
+ </notification>
+ <notification name="TeleportEntryAccessBlocked_PreferencesOutOfSync">
+ 發生技術å•é¡Œï¼Œä½ çš„å好設定和伺æœå™¨ä¸Šçš„ä¸ä¸€è‡´ã€‚
+ <usetemplate name="okbutton" yestext="確定"/>
+ </notification>
<notification name="PreferredMaturityChanged">
- Your maturity Rating preference is now [RATING].
+ ä½ å°‡ä¸å†æ”¶åˆ°é€šçŸ¥ï¼Œå‘ŠçŸ¥ä½ å³å°‡é€²å…¥ä¸€å€‹ [RATING] 內容分級的地å€ã€‚ ä½ å¯ä»¥åˆ°é¸å–®åˆ—底下的「我自己 &gt; å好設定 &gt; 一般設定ã€è®Šæ›´ä½ çš„內容å好。
+ <usetemplate name="okbutton" yestext="確定"/>
+ </notification>
+ <notification name="MaturityChangeError">
+ 我們此時無法變更你的å好設定,讓你觀看 [PREFERRED_MATURITY] 分級的內容。 ä½ çš„å好設定已經é‡è¨­ï¼Œå¯è§€çœ‹ [ACTUAL_MATURITY] 的分級內容。 ä½ å¯ä»¥åˆ°é¸å–®åˆ—的「我自己 &gt; å好設定 &gt; 一般設定ã€å†æ¬¡è®Šæ›´ä½ çš„å好。
+ <usetemplate name="okbutton" yestext="確定"/>
</notification>
<notification name="LandClaimAccessBlocked">
- You cannot claim this land due to your maturity Rating. This may be a result of a lack of information validating your age.
-
-Please verify you have the latest Viewer installed, and go to the Knowledge Base for details on accessing areas with this maturity rating.
+ 你所欲收å–的土地å«æœ‰è¶…éŽä½ ç›®å‰å好的分級內容。 ä½ å¯ä»¥åˆ°ã€Œæˆ‘自己 &gt; å好設定 &gt; 一般設定ã€è®Šæ›´ä½ çš„å好設定。
<usetemplate name="okbutton" yestext="確定"/>
</notification>
- <notification name="LandClaimAccessBlocked_KB">
- You cannot claim this land due to your maturity Rating.
-
-Go to the Knowledge Base for more information about maturity Ratings?
+ <notification name="LandClaimAccessBlocked_AdultsOnlyContent">
+ åªæœ‰æˆäººæ‰èƒ½æ”¶å–這土地。
<url name="url">
http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview
</url>
- <usetemplate ignoretext="I can&apos;t claim this Land, due to restrictions of the maturity Rating" name="okcancelignore" notext="關閉" yestext="Go to Knowledge Base"/>
+ <usetemplate ignoretext="åªæœ‰æˆäººæ‰èƒ½æ”¶å–這土地。" name="okcancelignore" notext="關閉" yestext="å‰å¾€çŸ¥è­˜åº«"/>
</notification>
<notification name="LandClaimAccessBlocked_Notify">
- You cannot claim this land due to your maturity Rating.
+ 你所欲收å–çš„åœŸåœ°åŒ…å« [REGIONMATURITY] 分級的內容,å¯æ˜¯ä½ ç›®å‰çš„å好設定排除了 [REGIONMATURITY] 分級的內容。
+ </notification>
+ <notification name="LandClaimAccessBlocked_NotifyAdultsOnly">
+ 你所欲收å–çš„åœŸåœ°åŒ…å« [REGIONMATURITY] 的分級內容,僅é™æˆäººã€‚
</notification>
<notification name="LandClaimAccessBlocked_Change">
- You cannot claim this land due to your maturity Rating preference.
-
-You can click &apos;Change Preference&apos; to raise your maturity Rating preference now and allow you to enter. You will be able to search and access [REGIONMATURITY] content from now on. If you later want to change this setting back, go to Me &gt; Preferences &gt; General.
- <usetemplate ignoretext="My chosen Rating preference prevents me from claiming Land" name="okcancelignore" notext="關閉" yestext="Change Preference"/>
+ 你所欲收å–çš„åœŸåœ°åŒ…å« [REGIONMATURITY] 分級的內容,å¯æ˜¯ä½ ç›®å‰çš„å好設定排除了 [REGIONMATURITY] 分級的內容。 我們å¯ä»¥è®Šæ›´ä½ çš„å好,讓你å†è©¦åœ–收å–土地。
+ <form name="form">
+ <button name="OK" text="變更å好設定"/>
+ <button name="Cancel" text="å–消"/>
+ <ignore name="ignore" text="你所欲收å–的土地å«æœ‰è¢«ä½ ç›®å‰çš„å好所排除的分級內容。"/>
+ </form>
</notification>
<notification name="LandBuyAccessBlocked">
- You cannot buy this land due to your maturity Rating. This may be a result of a lack of information validating your age.
-
-Please verify you have the latest Viewer installed, and go to the Knowledge Base for details on accessing areas with this maturity rating.
+ 你所欲購買的土地的內容分級超éŽä½ ç›®å‰æ‰€è¨­å好。 ä½ å¯ä»¥åˆ°ã€Œæˆ‘自己 &gt; å好設定 &gt; 一般設定ã€è®Šæ›´ä½ çš„å好設定。
<usetemplate name="okbutton" yestext="確定"/>
</notification>
- <notification name="LandBuyAccessBlocked_KB">
- You cannot buy this land due to your maturity Rating.
-
-Go to the Knowledge Base for more information about maturity Ratings?
+ <notification name="LandBuyAccessBlocked_AdultsOnlyContent">
+ åªæœ‰æˆäººæ‰èƒ½è³¼è²·é€™åœŸåœ°ã€‚
<url name="url">
http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview
</url>
- <usetemplate ignoretext="I can&apos;t buy this Land, due to restrictions of the maturity Rating" name="okcancelignore" notext="關閉" yestext="Go to Knowledge Base"/>
+ <usetemplate ignoretext="åªæœ‰æˆäººæ‰èƒ½è³¼è²·é€™åœŸåœ°ã€‚" name="okcancelignore" notext="關閉" yestext="å‰å¾€çŸ¥è­˜åº«"/>
</notification>
<notification name="LandBuyAccessBlocked_Notify">
- You cannot buy this land due to your maturity Rating.
+ ä½ æ‰€æ¬²è³¼è²·çš„åœŸåœ°åŒ…å« [REGIONMATURITY] 分級的內容,å¯æ˜¯ä½ ç›®å‰çš„å好設定排除了 [REGIONMATURITY] 分級的內容。
+ </notification>
+ <notification name="LandBuyAccessBlocked_NotifyAdultsOnly">
+ 你所欲購買的土地å«æœ‰ [REGIONMATURITY] 分級的內容,僅é™æˆäººã€‚
</notification>
<notification name="LandBuyAccessBlocked_Change">
- You cannot buy this land due to your maturity Rating preference.
-
-You can click &apos;Change Preference&apos; to raise your maturity Rating preference now and allow you to enter. You will be able to search and access [REGIONMATURITY] content from now on. If you later want to change this setting back, go to Me &gt; Preferences &gt; General.
- <usetemplate ignoretext="My chosen Rating preference prevents me from buying Land" name="okcancelignore" notext="關閉" yestext="變更å好設定"/>
+ ä½ æ‰€æ¬²è³¼è²·çš„åœŸåœ°åŒ…å« [REGIONMATURITY] 分級的內容,å¯æ˜¯ä½ ç›®å‰çš„å好設定排除了 [REGIONMATURITY] 分級的內容。 我們å¯ä»¥è®Šæ›´ä½ çš„å好,讓你å†è©¦åœ–購買土地。
+ <form name="form">
+ <button name="OK" text="變更å好設定"/>
+ <button name="Cancel" text="å–消"/>
+ <ignore name="ignore" text="你所欲購買的土地å«æœ‰è¢«ä½ ç›®å‰çš„å好所排除的分級內容。"/>
+ </form>
</notification>
<notification name="TooManyPrimsSelected">
- There are too many prims selected. Please select [MAX_PRIM_COUNT] or fewer prims and try again
+ é¸æ“‡äº†å¤ªå¤šé …的幾何元件。 請至多é¸æ“‡ [MAX_PRIM_COUNT] 項幾何元件,å†è©¦ä¸€æ¬¡ã€‚
<usetemplate name="okbutton" yestext="確定"/>
</notification>
<notification name="ProblemImportingEstateCovenant">
- Problem importing estate covenant.
+ 匯入領地契約時出å•é¡Œã€‚
<usetemplate name="okbutton" yestext="確定"/>
</notification>
<notification name="ProblemAddingEstateManager">
- Problems adding a new estate manager. One or more estates may have a full manager list.
+ 新增領地管ç†äººæ™‚出å•é¡Œã€‚ 其中一個領地的管ç†äººæ¸…å–®å¯èƒ½å·²ç¶“é¡æ»¿ã€‚
</notification>
<notification name="ProblemAddingEstateGeneric">
- Problems adding to this estate list. One or more estates may have a full list.
+ 新增到這個領地清單時出å•é¡Œã€‚ 其中一個領地的清單å¯èƒ½å·²æ»¿ã€‚
</notification>
<notification name="UnableToLoadNotecardAsset">
- Unable to load notecard&apos;s asset at this time.
+ 此刻無法載入記事å¡è³‡ç”¢ã€‚
<usetemplate name="okbutton" yestext="確定"/>
</notification>
<notification name="NotAllowedToViewNotecard">
- Insufficient permissions to view notecard associated with asset ID requested.
+ 權é™ä¸è¶³ç„¡æ³•å¯Ÿçœ‹æ­¤è³‡ç”¢ç·¨è™Ÿçš„記事å¡ã€‚
<usetemplate name="okbutton" yestext="確定"/>
</notification>
<notification name="MissingNotecardAssetID">
- Asset ID for notecard is missing from database.
+ 記事å¡çš„資產編號在資料庫中找ä¸åˆ°ã€‚
<usetemplate name="okbutton" yestext="確定"/>
</notification>
<notification name="PublishClassified">
- Remember: Classified ad fees are non-refundable.
+ 請注æ„:個人廣告刊登費æ•ä¸é€€é‚„。
-Publish this classified now for L$[AMOUNT]?
+支付 L$ [AMOUNT] 刊載這則個人廣告?
<usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/>
</notification>
<notification name="SetClassifiedMature">
- Does this classified contain Moderate content?
+ 這則個人廣告是å¦å«é©åº¦æˆäººåˆ†ç´šçš„內容?
<usetemplate canceltext="å–消" name="yesnocancelbuttons" notext="å¦" yestext="是"/>
</notification>
<notification name="SetGroupMature">
這個群組將包å«é©åº¦æˆäººå…§å®¹ï¼Ÿ
<usetemplate canceltext="å–消" name="yesnocancelbuttons" notext="å¦" yestext="是"/>
</notification>
- <notification label="Confirm restart" name="ConfirmRestart">
- Do you really want to restart this region in 2 minutes?
+ <notification label="確定é‡æ–°å•Ÿå‹•" name="ConfirmRestart">
+ 你確定è¦åœ¨ 2 分é˜å¾Œé‡æ–°å•Ÿå‹•é€™å€‹åœ°å€ï¼Ÿ
<usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/>
</notification>
- <notification label="Message everyone in this region" name="MessageRegion">
- Type a short announcement which will be sent to everyone in this region.
+ <notification label="å°åœ°å€è£¡æ¯å€‹äººç™¼å‡ºè¨Šæ¯" name="MessageRegion">
+ 輸入簡短公告,公告將發é€çµ¦åœ°å€è£¡æ‰€æœ‰äººã€‚
<form name="form">
<button name="OK" text="確定"/>
<button name="Cancel" text="å–消"/>
</form>
</notification>
- <notification label="Changed Region Maturity" name="RegionMaturityChange">
- The maturity rating for this region has been updated.
-It may take some time for the change to be reflected on the map.
-
-To enter Adult regions, Residents must be Account Verified, either by age-verification or payment-verification.
+ <notification label="已變更地å€çš„內容分級" name="RegionMaturityChange">
+ 此地å€çš„內容分級已經變更。
+å¯èƒ½éœ€è¦ç¨å€™ä¸€æ®µæ™‚間,地圖æ‰æœƒå映這個變更。
+ <usetemplate name="okbutton" yestext="確定"/>
</notification>
- <notification label="Voice Version Mismatch" name="VoiceVersionMismatch">
- This version of [APP_NAME] is not compatible with the Voice Chat feature in this region. In order for Voice Chat to function correctly you will need to update [APP_NAME].
+ <notification label="è²éŸ³ç‰ˆæœ¬ä¸ç›¸ç¬¦" name="VoiceVersionMismatch">
+ 這版本的 [APP_NAME] 和本地å€çš„語音èŠå¤©åŠŸèƒ½ä¸ç›¸å®¹ã€‚ 想è¦èªžéŸ³èŠå¤©æ­£å¸¸é‹ä½œï¼Œä½ å¿…須更新 [APP_NAME]。
</notification>
<notification label="無法購買物件" name="BuyObjectOneOwner">
- Cannot buy objects from different owners at the same time.
-Please select only one object and try again.
+ 無法åŒæ™‚å‘ä¸åŒç‰©ä¸»è³¼è²·ç‰©ä»¶ã€‚
+è«‹åªé¸æ“‡ä¸€å€‹ç‰©ä»¶ï¼Œå†è©¦ä¸€æ¬¡ã€‚
</notification>
<notification label="無法購買內容物" name="BuyContentsOneOnly">
- Unable to buy the contents of more than one object at a time.
-Please select only one object and try again.
+ 無法一次購買多個物件的內容。
+è«‹åªé¸æ“‡ä¸€å€‹ç‰©ä»¶ï¼Œå†è©¦ä¸€æ¬¡ã€‚
</notification>
<notification label="無法購買內容物" name="BuyContentsOneOwner">
- Cannot buy objects from different owners at the same time.
-Please select only one object and try again.
+ 無法åŒæ™‚å‘ä¸åŒç‰©ä¸»è³¼è²·ç‰©ä»¶ã€‚
+è«‹åªé¸æ“‡ä¸€å€‹ç‰©ä»¶ï¼Œå†è©¦ä¸€æ¬¡ã€‚
</notification>
<notification name="BuyOriginal">
- Buy original object from [OWNER] for L$[PRICE]?
-You will become the owner of this object.
-You will be able to:
- Modify: [MODIFYPERM]
- Copy: [COPYPERM]
- Resell or Give Away: [RESELLPERM]
+ å‘ [OWNER] 支付 L$[PRICE],購買原版物件?
+ä½ å°‡æˆç‚ºé€™ç‰©ä»¶çš„所有人。
+ä½ å°‡å¯ä»¥ï¼š
+ 修改:[MODIFYPERM]
+ 複製:[COPYPERM]
+ 轉售或é€äººï¼š[RESELLPERM]
<usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/>
</notification>
<notification name="BuyOriginalNoOwner">
- Buy original object for L$[PRICE]?
-You will become the owner of this object.
-You will be able to:
- Modify: [MODIFYPERM]
- Copy: [COPYPERM]
- Resell or Give Away: [RESELLPERM]
+ 支付 L$[PRICE] 購買原版物件?
+ä½ å°‡æˆç‚ºé€™ç‰©ä»¶çš„所有人。
+ä½ å°‡å¯ä»¥ï¼š
+ 修改:[MODIFYPERM]
+ 複製:[COPYPERM]
+ 轉售或é€äººï¼š[RESELLPERM]
<usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/>
</notification>
<notification name="BuyCopy">
- Buy a copy from [OWNER] for L$[PRICE]?
-The object will be copied to your inventory.
-You will be able to:
- Modify: [MODIFYPERM]
- Copy: [COPYPERM]
- Resell or Give Away: [RESELLPERM]
+ å‘ [OWNER] 支付 L$[PRICE],購買複製物件?
+這物件將複製到你的收ç´å€ã€‚
+ä½ å°‡å¯ä»¥ï¼š
+ 修改:[MODIFYPERM]
+ 複製:[COPYPERM]
+ 轉售或é€äººï¼š[RESELLPERM]
<usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/>
</notification>
<notification name="BuyCopyNoOwner">
- Buy a copy for L$[PRICE]?
-The object will be copied to your inventory.
-You will be able to:
- Modify: [MODIFYPERM]
- Copy: [COPYPERM]
- Resell or Give Away: [RESELLPERM]
+ 支付 L$[PRICE] 購買複製物件?
+這物件將複製到你的收ç´å€ã€‚
+ä½ å°‡å¯ä»¥ï¼š
+ 修改:[MODIFYPERM]
+ 複製:[COPYPERM]
+ 轉售或é€äººï¼š[RESELLPERM]
<usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/>
</notification>
<notification name="BuyContents">
- Buy contents from [OWNER] for L$[PRICE]?
-They will be copied to your inventory.
+ å‘ [OWNER] 支付 L$[PRICE] 購買內容?
+內容將複製到你的收ç´å€ã€‚
<usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/>
</notification>
<notification name="BuyContentsNoOwner">
- Buy contents for L$[PRICE]?
-They will be copied to your inventory.
+ 支付 L$[PRICE] 購買內容?
+內容將複製到你的收ç´å€ã€‚
<usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/>
</notification>
<notification name="ConfirmPurchase">
- This transaction will:
+ 這項交易將會:
[ACTION]
-Are you sure you want to proceed with this purchase?
+你確定è¦è³¼è²·ï¼Ÿ
<usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/>
</notification>
<notification name="ConfirmPurchasePassword">
- This transaction will:
+ 這項交易將會:
[ACTION]
-Are you sure you want to proceed with this purchase?
-Please re-enter your password and click OK.
+你確定è¦è³¼è²·ï¼Ÿ
+è«‹é‡æ–°è¼¸å…¥å¯†ç¢¼å†é»žæŒ‰ç¢ºå®šã€‚
<form name="form">
<button name="ConfirmPurchase" text="確定"/>
<button name="Cancel" text="å–消"/>
</form>
</notification>
<notification name="SetPickLocation">
- Note:
-You have updated the location of this pick but the other details will retain their original values.
+ 附註:
+你已經更新這個精é¸åœ°é»žçš„地點細節,其他細節將ä¿ç•™åŽŸå…§å®¹ã€‚
<usetemplate name="okbutton" yestext="確定"/>
</notification>
<notification name="MoveInventoryFromObject">
- You have selected &apos;no copy&apos; inventory items.
-These items will be moved to your inventory, not copied.
+ ä½ é¸æ“‡äº†ã€Œç¦æ­¢è¤‡è£½ã€çš„收ç´å€ç‰©é …。
+這些物項將被移到你的收ç´å€ï¼Œä¸æœƒè¢«è¤‡è£½ã€‚
-Move the inventory item(s)?
- <usetemplate ignoretext="Warn me before I move &apos;no-copy&apos; items from an object" name="okcancelignore" notext="å–消" yestext="確定"/>
+è¦ç§»å‹•æ”¶ç´å€ç‰©é …嗎?
+ <usetemplate ignoretext="在我從物件中移動「ç¦æ­¢è¤‡è£½ã€ç‰©é …之å‰è­¦å‘Šæˆ‘" name="okcancelignore" notext="å–消" yestext="確定"/>
</notification>
<notification name="MoveInventoryFromScriptedObject">
- You have selected &apos;no copy&apos; inventory items. These items will be moved to your inventory, not copied.
-Because this object is scripted, moving these items to your inventory may cause the script to malfunction.
+ ä½ é¸æ“‡äº†ã€Œç¦æ­¢è¤‡è£½ã€çš„收ç´å€ç‰©é …。 這些物項將被移到你的收ç´å€ï¼Œä¸æœƒè¢«è¤‡è£½ã€‚
+由於這物件帶有腳本,移動這些物項到收ç´å€å¯èƒ½æœƒå°Žè‡´è…³æœ¬é‹ä½œä¸æ­£å¸¸ã€‚
-Move the inventory item(s)?
- <usetemplate ignoretext="Warn me before I move &apos;no-copy&apos; items which might break a scripted object" name="okcancelignore" notext="å–消" yestext="確定"/>
+è¦ç§»å‹•æ”¶ç´å€ç‰©é …嗎?
+ <usetemplate ignoretext="在我移動å¯èƒ½ç ´å£žå¸¶è…³æœ¬ç‰©ä»¶çš„「ç¦æ­¢è¤‡è£½ã€ç‰©é …之å‰è­¦å‘Šæˆ‘" name="okcancelignore" notext="å–消" yestext="確定"/>
</notification>
<notification name="ClickActionNotPayable">
- Warning: The &apos;Pay object&apos; click action has been set, but it will only work if a script is added with a money() event.
+ 警告:「支付物件ã€é»žæŒ‰å‹•ä½œå·²è¨­å®šï¼Œä½†æ–°å¢žçš„腳本必須å«æœ‰ money() 事件,該動作æ‰æœ‰ä½œç”¨ã€‚
<form name="form">
- <ignore name="ignore" text="I set the action &apos;Pay object&apos; when building an object without a money() script"/>
+ <ignore name="ignore" text="我在創建ä¸å« money() 腳本的物件時設定了「支付物件ã€å‹•ä½œ"/>
</form>
</notification>
<notification name="OpenObjectCannotCopy">
- There are no items in this object that you are allowed to copy.
+ 這物件中沒有任何准許你複製的物項。
</notification>
<notification name="WebLaunchAccountHistory">
å‰å¾€ä½ çš„[http://secondlife.com/account/ 塗鴉牆]以察看你的帳戶歷å²ç´€éŒ„?
<usetemplate ignoretext="啟動我的ç€è¦½å™¨ä»¥å¯Ÿçœ‹æˆ‘的帳戶歷å²ç´€éŒ„" name="okcancelignore" notext="å–消" yestext="å‰å¾€é é¢"/>
</notification>
+ <notification name="ConfirmAddingChatParticipants">
+ 新增一個人到ç¾æœ‰çš„交談,等於建立新的交談。 所有交談者將會收到新交談通知。
+ <usetemplate ignoretext="確èªæ–°å¢žèŠå¤©è€…" name="okcancelignore" notext="å–消" yestext="確定"/>
+ </notification>
<notification name="ConfirmQuit">
你確定你è¦çµæŸé€€å‡ºï¼Ÿ
<usetemplate ignoretext="當我çµæŸé€€å‡ºæ™‚進行確èª" name="okcancelignore" notext="ä¸è¦çµæŸé€€å‡º" yestext="çµæŸé€€å‡º"/>
</notification>
+ <notification name="ConfirmRestoreToybox">
+ 這動作將會æ¢å¾©ä½ é è¨­çš„按鈕和工具列。
+
+ä½ ä¸èƒ½å–消這動作。
+ <usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/>
+ </notification>
+ <notification name="ConfirmClearAllToybox">
+ 這動作將把所有按鈕收入工具箱,你的工具列將會清空。
+
+ä½ ä¸èƒ½å–消這動作。
+ <usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/>
+ </notification>
<notification name="DeleteItems">
[QUESTION]
<usetemplate ignoretext="刪除物å“å‰ç¢ºèª" name="okcancelignore" notext="å–消" yestext="確定"/>
</notification>
<notification name="HelpReportAbuseEmailLL">
- Use this tool to report violations of the [http://secondlife.com/corporate/tos.php Terms of Service] and [http://secondlife.com/corporate/cs.php Community Standards].
+ 使用這個工具舉報任何é•å[http://secondlife.com/corporate/tos.php æœå‹™æ¢æ¬¾]å’Œ[http://secondlife.com/corporate/cs.php 社群準則]的情事。
-All reported abuses are investigated and resolved.
+所有舉報的é•è¦äº‹ä»¶éƒ½æœ‰äººèª¿æŸ¥ï¼ŒåŠ ä»¥è§£æ±ºã€‚
</notification>
<notification name="HelpReportAbuseSelectCategory">
- Please select a category for this abuse report.
-Selecting a category helps us file and process abuse reports.
+ è«‹é¸æ“‡é©åˆé€™æ¬¡é•è¦èˆ‰å ±çš„類別。
+é¸å°é¡žåˆ¥å¯ä»¥å¹«åŠ©æˆ‘們歸類並處ç†é•è¦èˆ‰å ±ã€‚
</notification>
<notification name="HelpReportAbuseAbuserNameEmpty">
- Please enter the name of the abuser.
-Entering an accurate value helps us file and process abuse reports.
+ 請輸入é•è¦äººçš„å字。
+輸入準確的內容å¯ä»¥å¹«åŠ©æˆ‘們歸類並處ç†é•è¦èˆ‰å ±ã€‚
</notification>
<notification name="HelpReportAbuseAbuserLocationEmpty">
- Please enter the location where the abuse took place.
-Entering an accurate value helps us file and process abuse reports.
+ 請輸入é•è¦æƒ…事發生地點。
+輸入準確的內容å¯ä»¥å¹«åŠ©æˆ‘們歸類並處ç†é•è¦èˆ‰å ±ã€‚
</notification>
<notification name="HelpReportAbuseSummaryEmpty">
- Please enter a summary of the abuse that took place.
-Entering an accurate summary helps us file and process abuse reports.
+ 請概述é•è¦æƒ…事。
+準確的概述å¯ä»¥å¹«åŠ©æˆ‘們歸類並處ç†é•è¦èˆ‰å ±ã€‚
</notification>
<notification name="HelpReportAbuseDetailsEmpty">
- Please enter a detailed description of the abuse that took place.
-Be as specific as you can, including names and the details of the incident you are reporting.
-Entering an accurate description helps us file and process abuse reports.
+ 請詳述é•è¦æƒ…事。
+請儘å¯èƒ½æ供具體詳情,包括你è¦èˆ‰å ±çš„案情細節和涉案的å稱。
+準確的詳述å¯ä»¥å¹«åŠ©æˆ‘們歸類並處ç†é•è¦èˆ‰å ±ã€‚
</notification>
<notification name="HelpReportAbuseContainsCopyright">
- Dear Resident,
+ 這ä½å±…民,你好:
-You appear to be reporting intellectual property infringement. Please make sure you are reporting it correctly:
+你似乎正在舉報有人侵犯智慧財產權。 請確定你舉報內容確鑿無誤:
-(1) The Abuse Process. You may submit an abuse report if you believe a Resident is exploiting the [SECOND_LIFE] permissions system, for example, by using CopyBot or similar copying tools, to infringe intellectual property rights. The Abuse Team investigates and issues appropriate disciplinary action for behavior that violates the [SECOND_LIFE] [http://secondlife.com/corporate/tos.php Terms of Service] or [http://secondlife.com/corporate/cs.php Community Standards]. However, the Abuse Team does not handle and will not respond to requests to remove content from the [SECOND_LIFE] world.
+(1) é•è¦èˆ‰å ±è™•ç†ç¨‹åºã€‚ 你若相信有居民利用 [SECOND_LIFE] 權é™é‚行侵犯智慧財產權,如使用複製機器程å¼ç¢¼(CopyBot)或其他類似複製工具,得以舉報此情事。 é•è¦è™•ç†å°çµ„會就任何é•å[SECOND_LIFE][http://secondlife.com/corporate/tos.php æœå‹™æ¢æ¬¾]或[http://secondlife.com/corporate/cs.php 社群準則]的行為展開調查,並採å–é©ç•¶è™•ç½®ã€‚ 然而,é•è¦è™•ç†å°çµ„並ä¸å—ç†è¦æ±‚å°‡æŸå…§å®¹è‡ª[SECOND_LIFE]虛擬世界刪除,這類è¦æ±‚å°‡ä¸äºˆå›žæ‡‰ã€‚
-(2) The DMCA or Content Removal Process. To request removal of content from [SECOND_LIFE], you MUST submit a valid notification of infringement as provided in our [http://secondlife.com/corporate/dmca.php DMCA Policy].
+(2) DMCA(刪除內容作業程åºï¼‰ã€‚ 若欲è¦æ±‚刪除[SECOND_LIFE]內容,你必須按照[http://secondlife.com/corporate/dmca.php DMCA 政策]æ出有效的侵權通知。
-If you still wish to continue with the abuse process, please close this window and finish submitting your report. You may need to select the specific category &apos;CopyBot or Permissions Exploit&apos;.
+如果你ä»å¸Œæœ›ç¹¼çºŒï¼Œè«‹é—œé–‰æ­¤è¦–窗,完æˆèˆ‰å ±ã€‚ ä½ å¯èƒ½éœ€è¦é¸æ“‡ã€ŒCopyBot 或濫用權é™ã€é€™ä¸€å…·é«”類別。
-Thank you,
+è¬è¬ä½ ï¼Œ
-Linden Lab
+林登實驗室謹上
</notification>
<notification name="FailedRequirementsCheck">
- The following required components are missing from [FLOATER]:
+ [FLOATER] 裡找ä¸åˆ°ä¸‹åˆ—å¿…è¦å…ƒä»¶ï¼š
[COMPONENTS]
</notification>
<notification label="å–代ç¾æœ‰çš„附件" name="ReplaceAttachment">
- There is already an object attached to this point on your body.
-Do you want to replace it with the selected object?
+ 你身上的這個部ä½å·²ç¶“附著了物件。
+ä½ è¦ç”¨æ‰€é¸ç‰©ä»¶å°‡å®ƒå–代嗎?
<form name="form">
<ignore name="ignore" text="以所é¸æ“‡çš„物å“å–代ç¾æœ‰çš„附加物"/>
<button ignore="自動å–代" name="Yes" text="確定"/>
<button ignore="絕ä¸å–代" name="No" text="å–消"/>
</form>
</notification>
- <notification label="忙碌模å¼è­¦å‘Š" name="BusyModePay">
- You are in Busy Mode, which means you will not receive any items offered in exchange for this payment.
+ <notification label="「請勿打擾ã€æ¨¡å¼è­¦å‘Š" name="DoNotDisturbModePay">
+ 你已開啟「請勿打擾ã€ã€‚ ä½ å°‡ä¸æœƒæ”¶åˆ°ä»»ä½•ä»˜æ¬¾è³¼è²·çš„物項。
-Would you like to leave Busy Mode before completing this transaction?
+是å¦è¦åœ¨å®Œæˆäº¤æ˜“之å‰ï¼Œå…ˆé—œé–‰ã€Œè«‹å‹¿æ‰“擾ã€æ¨¡å¼ï¼Ÿ
<form name="form">
- <ignore name="ignore" text="當我在忙碌模å¼æ™‚,將è¦æ”¯ä»˜é‡‘錢或給他人物件"/>
- <button ignore="總是離開忙碌模å¼" name="Yes" text="確定"/>
- <button ignore="絕ä¸é›¢é–‹å¿™ç¢Œæ¨¡å¼" name="No" text="å–消"/>
+ <ignore name="ignore" text="我å³å°‡åœ¨ã€Œè«‹å‹¿æ‰“擾ã€æ¨¡å¼ä¸‹ï¼Œè©¦åœ–付錢給他人或給一個物件"/>
+ <button ignore="固定é¸æ“‡é›¢é–‹ã€Œè«‹å‹¿æ‰“擾ã€æ¨¡å¼" name="Yes" text="確定"/>
+ <button ignore="æ°¸ä¸é›¢é–‹ã€Œè«‹å‹¿æ‰“擾ã€æ¨¡å¼" name="No" text="å–消"/>
</form>
</notification>
<notification name="ConfirmDeleteProtectedCategory">
- 資料夾 &apos;[FOLDERNAME]&apos; 是系統資料夾。刪除系統資料夾將導致ä¸ç©©å®šã€‚你確定你è¦åˆªé™¤å®ƒï¼Ÿ
+ 「[FOLDERNAME]ã€å±¬æ–¼ç³»çµ±è³‡æ–™å¤¾ã€‚ 刪除系統資料夾å¯èƒ½å°Žè‡´ç³»çµ±ä¸ç©©å®šã€‚ 你確定è¦åŠ ä»¥åˆªé™¤ï¼Ÿ
<usetemplate ignoretext="在我刪除系統資料夾å‰ç¢ºèª" name="okcancelignore" notext="å–消" yestext="確定"/>
</notification>
<notification name="ConfirmEmptyTrash">
@@ -1972,6 +2187,10 @@ Would you like to leave Busy Mode before completing this transaction?
你確定è¦åˆªé™¤ä½ çš„æ—…è¡Œã€ç¶²é åŠæœå°‹æ­·å²ç´€éŒ„嗎?
<usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/>
</notification>
+ <notification name="ConfirmClearCache">
+ 確定è¦æ¸…除你 Viewer çš„å¿«å–?
+ <usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/>
+ </notification>
<notification name="ConfirmClearCookies">
你確定è¦æ¸…除你的 cookies 嗎?
<usetemplate name="okcancelbuttons" notext="å–消" yestext="是"/>
@@ -1988,7 +2207,7 @@ Would you like to leave Busy Mode before completing this transaction?
下列的 SLurl ä½ç½®å·²ç¶“覆製到你的剪貼簿上:
[SLURL]
-Link to this from a web page to give others easy access to this location, or try it out yourself by pasting it into the address bar of any web browser.
+從æŸå€‹ç¶²é é€£çµåˆ°é€™è£¡ï¼Œè®“其他人更容易知é“這個地點,或請自行嘗試將它貼到任何網é ç€è¦½å™¨çš„地å€æ¬„裡。
<form name="form">
<ignore name="ignore" text="SLurl 已經覆製到我的剪貼簿。"/>
</form>
@@ -1997,48 +2216,30 @@ Link to this from a web page to give others easy access to this location, or try
ä½ è¦è¦†å¯«å·²å„²å­˜çš„é è¨­é…置嗎?
<usetemplate name="okcancelbuttons" notext="å¦" yestext="是"/>
</notification>
- <notification name="WLDeletePresetAlert">
- ä½ è¦åˆªé™¤ [SKY]?
- <usetemplate name="okcancelbuttons" notext="å¦" yestext="是"/>
- </notification>
<notification name="WLNoEditDefault">
- You cannot edit or delete a default preset.
+ ä½ ä¸èƒ½ç·¨è¼¯æˆ–刪除é è¨­çš„設定。
</notification>
<notification name="WLMissingSky">
- This day cycle file references a missing sky file: [SKY].
+ 這個「一日循環ã€æª”案åƒè€ƒäº†ä¸€å€‹ä¸å­˜åœ¨çš„天空檔案:[SKY]。
</notification>
- <notification name="PPSaveEffectAlert">
- PostProcess Effect exists. Do you still wish overwrite it?
- <usetemplate name="okcancelbuttons" notext="å¦" yestext="是"/>
- </notification>
- <notification name="NewSkyPreset">
- Give me a name for the new sky.
- <form name="form">
- <input name="message">
- æ–°é è¨­é…é…ç½®
- </input>
- <button name="OK" text="確定"/>
- <button name="Cancel" text="å–消"/>
- </form>
+ <notification name="WLRegionApplyFail">
+ 抱歉,設定無法套用到地å€ã€‚ 離開地å€å†è¿”回也許å¯ä»¥è§£æ±ºé€™å€‹å•é¡Œã€‚ 所得的原因為:[FAIL_REASON]
</notification>
- <notification name="ExistsSkyPresetAlert">
- Preset already exists!
+ <notification name="EnvCannotDeleteLastDayCycleKey">
+ 無法刪除此日循環的最後一組設定,日循環ä¸å¾—為空白。 你應該修改最後一組資料,ä¸è¦è©¦åœ–刪除,然後å†å»ºç«‹æ–°çš„。
+ <usetemplate name="okbutton" yestext="確定"/>
</notification>
- <notification name="NewWaterPreset">
- Give me a name for the new water preset.
- <form name="form">
- <input name="message">
- New Preset
- </input>
- <button name="OK" text="確定"/>
- <button name="Cancel" text="å–消"/>
- </form>
+ <notification name="DayCycleTooManyKeyframes">
+ 你無法新增更多的 keyframe 到這個日循環。 [SCOPE] 範åœçš„日循環最多å…許 [MAX] 個 keyframe。
+ <usetemplate name="okbutton" yestext="確定"/>
</notification>
- <notification name="ExistsWaterPresetAlert">
- Preset already exists!
+ <notification name="EnvUpdateRate">
+ 你至多åªèƒ½æ¯ [WAIT] 秒更新一次地å€çš„環境設定。 請等到這段時間éŽåŽ»äº†å†è©¦ä¸€æ¬¡ã€‚
+ <usetemplate name="okbutton" yestext="確定"/>
</notification>
- <notification name="WaterNoEditDefault">
- You cannot edit or delete a default preset.
+ <notification name="PPSaveEffectAlert">
+ PostProcess 效果已經存在。 你是å¦ä»è¦æŠŠå®ƒè¦†å¯«æŽ‰ï¼Ÿ
+ <usetemplate name="okcancelbuttons" notext="å¦" yestext="是"/>
</notification>
<notification name="ChatterBoxSessionStartError">
無法開始一個與 [RECIPIENT] 他的新èŠå¤©æœƒè©±ã€‚
@@ -2056,10 +2257,10 @@ Link to this from a web page to give others easy access to this location, or try
<usetemplate name="okbutton" yestext="確定"/>
</notification>
<notification name="Cannot_Purchase_an_Attachment">
- You can&apos;t buy an object while it is attached.
+ ä½ ä¸èƒ½è³¼è²·å·²é™„著的物件。
</notification>
- <notification label="About Requests for the Debit Permission" name="DebitPermissionDetails">
- Granting this request gives a script ongoing permission to take Linden dollars (L$) from your account. To revoke this permission, the object owner must delete the object or reset the scripts in the object.
+ <notification label="關於借記權é™è¦æ±‚" name="DebitPermissionDetails">
+ 若你åŒæ„這è¦æ±‚,將å…許腳本從你的帳戶中é‡è¦†å–走林登幣(L$)。 物件所有人必須刪除該物件,或é‡è¨­ç‰©ä»¶è£¡çš„腳本,æ‰èƒ½æ’¤éŠ·é€™ä¸€æ¬Šé™ã€‚
<usetemplate name="okbutton" yestext="確定"/>
</notification>
<notification name="AutoWearNewClothing">
@@ -2067,25 +2268,23 @@ Link to this from a web page to give others easy access to this location, or try
<usetemplate ignoretext="編輯外觀時能穿上我所創造的æœè£" name="okcancelignore" notext="å¦" yestext="是"/>
</notification>
<notification name="NotAgeVerified">
- You must be age-verified to visit this area. Do you want to go to the [SECOND_LIFE] website and verify your age?
-
-[_URL]
- <url name="url">
- https://secondlife.com/account/verification.php
- </url>
- <usetemplate ignoretext="I have not verified my age" name="okcancelignore" notext="å¦" yestext="是"/>
+ 你所欲å‰å¾€çš„地點設é™çµ¦å¹´æ»¿ 18 歲的居民進入。
+ <usetemplate ignoretext="我年齡ä¸æ»¿è¦å®šï¼Œç„¡æ³•é€²å…¥æœ‰å¹´é½¡é™åˆ¶çš„å€åŸŸã€‚" name="okignore" yestext="確定"/>
+ </notification>
+ <notification name="NotAgeVerified_Notify">
+ 此地點é™åˆ¶ç‚ºå¹´æ»¿ 18 歲。
</notification>
<notification name="Cannot enter parcel: no payment info on file">
- You must have payment information on file to visit this area. Do you want to go to the [SECOND_LIFE] website and set this up?
+ ä½ å¿…é ˆæ供付款資料æ‰èƒ½é€²å…¥é€™å€åŸŸã€‚ 你是å¦è¦å‰å¾€ [SECOND_LIFE] 網站設定付款資料?
[_URL]
<url name="url">
https://secondlife.com/account/
</url>
- <usetemplate ignoretext="I lack payment information on file" name="okcancelignore" notext="å¦" yestext="是"/>
+ <usetemplate ignoretext="我沒有é ç•™ä»˜æ¬¾è³‡æ–™ã€‚" name="okcancelignore" notext="å¦" yestext="是"/>
</notification>
<notification name="MissingString">
- The string [STRING_NAME] is missing from strings.xml
+ strings.xml 中找ä¸åˆ°å­—串 [STRING_NAME]
</notification>
<notification name="SystemMessageTip">
[MESSAGE]
@@ -2103,38 +2302,35 @@ Link to this from a web page to give others easy access to this location, or try
å–消貼上
</notification>
<notification name="ReplacedMissingWearable">
- Replaced missing clothing/body part with default.
+ 已用é è¨­å€¼è£œè¶³ç©ºç¼ºçš„è¡£æœ/身體部ä½ã€‚
</notification>
<notification name="GroupNotice">
- Topic: [SUBJECT], Message: [MESSAGE]
+ 主旨:[SUBJECT],訊æ¯ï¼š[MESSAGE]
</notification>
- <notification name="FriendOnline">
- &lt;nolink&gt;[NAME]&lt;/nolink&gt; 上線
- </notification>
- <notification name="FriendOffline">
- &lt;nolink&gt;[NAME]&lt;/nolink&gt; 離線
+ <notification name="FriendOnlineOffline">
+ &lt;nolink&gt;[NAME]&lt;/nolink&gt; ç›®å‰ç‹€æ…‹ç‚º [STATUS]
</notification>
<notification name="AddSelfFriend">
- Although you&apos;re very nice, you can&apos;t add yourself as a friend.
+ 雖然你人很好,你還是ä¸èƒ½æŠŠè‡ªå·±åŠ ç‚ºæœ‹å‹ã€‚
</notification>
<notification name="UploadingAuctionSnapshot">
- Uploading in-world and web site snapshots...
-(Takes about 5 minutes.)
+ 正在上傳虛擬世界和網站快照…
+(需時約 5 分é˜ã€‚)
</notification>
<notification name="UploadPayment">
你支付 L$[AMOUNT] 上傳。
</notification>
<notification name="UploadWebSnapshotDone">
- Web site snapshot upload done.
+ 網站快照上傳完æˆã€‚
</notification>
<notification name="UploadSnapshotDone">
- In-world snapshot upload done
+ 虛擬世界快照上傳完æˆã€‚
</notification>
<notification name="TerrainDownloaded">
地形 .raw 檔已下載
</notification>
<notification name="GestureMissing">
- 嗯,姿勢 [NAME] 在資料庫中éºå¤±ã€‚
+ 姿勢 [NAME] 在資料庫中éºå¤±ã€‚
</notification>
<notification name="UnableToLoadGesture">
無法載入姿勢 [NAME]。
@@ -2143,7 +2339,7 @@ Link to this from a web page to give others easy access to this location, or try
資料庫中的地標éºå¤±ã€‚
</notification>
<notification name="UnableToLoadLandmark">
- 無法載入地標,請å†è©¦ä¸€æ¬¡ã€‚
+ 無法載入地標。 è«‹å†è©¦ä¸€æ¬¡ã€‚
</notification>
<notification name="CapsKeyOn">
你的大寫éµå·²å•Ÿç”¨ã€‚
@@ -2158,6 +2354,12 @@ Link to this from a web page to give others easy access to this location, or try
<notification name="RezItemNoPermissions">
產生物件時發生權é™è¡çªã€‚
</notification>
+ <notification name="IMAcrossParentEstates">
+ 無法å°ä¸åŒçš„æ¯é ˜åœ°ç™¼å‡ºå³æ™‚訊æ¯ã€‚
+ </notification>
+ <notification name="TransferInventoryAcrossParentEstates">
+ 收ç´å€ç„¡æ³•è½‰ç§»åˆ°ä¸åŒçš„æ¯é ˜åœ°ã€‚
+ </notification>
<notification name="UnableToLoadNotecard">
無法載入記事å¡ã€‚
è«‹å†è©¦ä¸€æ¬¡ã€‚
@@ -2169,28 +2371,28 @@ Link to this from a web page to give others easy access to this location, or try
察看腳本時發生權é™è¡çªã€‚
</notification>
<notification name="UnableToLoadScript">
- 無法載入腳本。請å†è©¦ä¸€æ¬¡ã€‚
+ 無法載入腳本。 è«‹å†è©¦ä¸€æ¬¡ã€‚
</notification>
<notification name="IncompleteInventory">
- The complete contents you are offering are not yet locally available. Please try offering those items again in a minute.
+ 你所æ供的完整內容在本地還無法å–得。 請幾分é˜å¾Œå†è©¦è‘—æ供這些物項。
</notification>
<notification name="CannotModifyProtectedCategories">
- You cannot modify protected categories.
+ ä½ ä¸èƒ½ä¿®æ”¹å—ä¿è­·çš„類別。
</notification>
<notification name="CannotRemoveProtectedCategories">
- You cannot remove protected categories.
+ ä½ ä¸èƒ½ç§»é™¤å—ä¿è­·çš„類別。
</notification>
<notification name="UnableToBuyWhileDownloading">
- Unable to buy while downloading object data.
-Please try again.
+ 正在下載物件資料,無法購買。
+è«‹å†è©¦ä¸€æ¬¡ã€‚
</notification>
<notification name="UnableToLinkWhileDownloading">
- Unable to link while downloading object data.
-Please try again.
+ 正在下載物件資料,無法è¯çµã€‚
+è«‹å†è©¦ä¸€æ¬¡ã€‚
</notification>
<notification name="CannotBuyObjectsFromDifferentOwners">
- You can only buy objects from one owner at a time.
-Please select a single object.
+ 你一次åªèƒ½å‘一ä½ç‰©ä¸»è³¼è²·ç‰©ä»¶ã€‚
+è«‹é¸æ“‡ä¸€å€‹å–®ä¸€ç‰©ä»¶ã€‚
</notification>
<notification name="ObjectNotForSale">
這物件ä¸å‡ºå”®ã€‚
@@ -2211,7 +2413,7 @@ Please select a single object.
[NAME] è¬çµ•ä½ æ供的收ç´å€ç‰©å“。
</notification>
<notification name="ObjectMessage">
- [NAME]: [MESSAGE]
+ [NAME]:[MESSAGE]
</notification>
<notification name="CallingCardAccepted">
ä½ çš„å片已被接å—。
@@ -2220,24 +2422,23 @@ Please select a single object.
ä½ çš„å片已被拒絕。
</notification>
<notification name="TeleportToLandmark">
- You can teleport to locations like &apos;[NAME]&apos; by opening the Places panel on the right side of your screen, and then select the Landmarks tab.
-Click on any landmark to select it, then click &apos;Teleport&apos; at the bottom of the panel.
-(You can also double-click on the landmark, or right-click it and choose &apos;Teleport&apos;.)
+ è¦çž¬é–“傳é€åˆ°ã€Œ[NAME]ã€ç­‰åœ°é»žï¼Œè«‹é»žæŒ‰ã€Œåœ°é»žã€æŒ‰éˆ•ï¼Œ
+ 然後在開啟的視窗裡,é¸æ“‡ã€Œåœ°æ¨™ã€é ç±¤ã€‚ 點按任何
+ 地標加以é¸æ“‡ï¼Œå†é»žæŒ‰è¦–窗底下的「瞬間傳é€ã€æŒ‰éˆ•ã€‚
+ (你還å¯ä»¥ç›´æŽ¥æŒ‰å…©ä¸‹é‚£å€‹åœ°æ¨™ï¼Œæˆ–按滑鼠å³éµï¼Œé¸æ“‡ã€Œçž¬é–“傳é€ã€ã€‚)
</notification>
<notification name="TeleportToPerson">
- You can contact Residents like &apos;[NAME]&apos; by opening the People panel on the right side of your screen.
-Select the Resident from the list, then click &apos;IM&apos; at the bottom of the panel.
-(You can also double-click on their name in the list, or right-click and choose &apos;IM&apos;).
+ è¦å’ŒæŸäººç§ä¸‹äº¤è«‡ï¼Œè«‹å³éµé»žæŒ‰åŒ–身,å†é»žæŒ‰é¸å–®çš„「IMã€ã€‚
</notification>
<notification name="CantSelectLandFromMultipleRegions">
- Can&apos;t select land across server boundaries.
-Try selecting a smaller piece of land.
+ 無法é¸æ“‡è¶…出伺æœå™¨é‚Šç•Œçš„土地。
+請試著縮å°æ‰€é¸çš„土地。
</notification>
<notification name="SearchWordBanned">
- Some terms in your search query were excluded due to content restrictions as clarified in the Community Standards.
+ 根據「社群準則ã€æ‰€æ˜Žè¨‚的內容é™åˆ¶ï¼Œå·²æŽ’除你所æœå°‹çš„æŸäº›å­—眼。
</notification>
<notification name="NoContentToSearch">
- Please select at least one type of content to search (General, Moderate, or Adult).
+ 請至少é¸æ“‡ä¸€ç¨®è¦æœç´¢çš„內容分級(一般普級ã€é©åº¦æˆäººã€å®Œå…¨æˆäººï¼‰ã€‚
</notification>
<notification name="SystemMessage">
[MESSAGE]
@@ -2248,6 +2449,9 @@ Try selecting a smaller piece of land.
<notification name="PaymentSent">
[MESSAGE]
</notification>
+ <notification name="PaymentFailure">
+ [MESSAGE]
+ </notification>
<notification name="EventNotification">
活動通知:
@@ -2259,179 +2463,198 @@ Try selecting a smaller piece of land.
</form>
</notification>
<notification name="TransferObjectsHighlighted">
- All objects on this parcel that will transfer to the purchaser of this parcel are now highlighted.
+ 這地段上,所有將轉移給地段購買人的物件,ç¾å·²å‘ˆé«˜äº®é¡¯ç¤ºã€‚
-* Trees and grasses that will transfer are not highlighted.
+* å³å°‡è½‰ç§»çš„樹和è‰ä¸æœƒä»¥é«˜äº®é¡¯ç¤ºã€‚
<form name="form">
- <button name="Done" text="Done"/>
+ <button name="Done" text="完æˆ"/>
</form>
</notification>
<notification name="DeactivatedGesturesTrigger">
- Deactivated gestures with same trigger:
+ 以åŒä¸€è§¸ç™¼åœç”¨çš„姿勢:
[NAMES]
</notification>
<notification name="NoQuickTime">
- Apple&apos;s QuickTime software does not appear to be installed on your system.
-If you want to view streaming media on parcels that support it you should go to the [http://www.apple.com/quicktime QuickTime site] and install the QuickTime Player.
+ ä½ çš„ç³»çµ±ä¼¼ä¹Žæœªå®‰è£ Apple çš„ QuickTime 軟體。
+如果你è¦åœ¨æ”¯æ´ä¸²æµåª’體的地段上觀看這類媒體,請到[http://www.apple.com/quicktime QuickTime 網站]å®‰è£ QuickTime 播放器。
</notification>
<notification name="NoPlugin">
- No Media Plugin was found to handle the &quot;[MIME_TYPE]&quot; mime type. Media of this type will be unavailable.
+ 找ä¸åˆ°åª’é«”æ’件來處ç†ã€Œ[MIME_TYPE]ã€mine 類型。 這類媒體將無法使用。
</notification>
<notification name="MediaPluginFailed">
- The following Media Plugin has failed:
+ 以下的媒體æ’件失éˆï¼š
[PLUGIN]
-Please re-install the plugin or contact the vendor if you continue to experience problems.
+如果你繼續出ç¾é€™ç‹€æ³ï¼Œè«‹é‡æ–°å®‰è£æ’件,或è¯çµ¡å…¶æ供廠家。
<form name="form">
- <ignore name="ignore" text="A Media Plugin fails to run"/>
+ <ignore name="ignore" text="有一個媒體æ’件無法執行"/>
</form>
</notification>
<notification name="OwnedObjectsReturned">
- The objects you own on the selected parcel of land have been returned back to your inventory.
+ 你在所é¸åœ°æ®µä¸Šæ‰€æ“有的物件已被é€è¿”你的收ç´å€ã€‚
</notification>
<notification name="OtherObjectsReturned">
- The objects on the selected parcel of land that is owned by [NAME] have been returned to his or her inventory.
+ 在所é¸åœ°æ®µä¸Šç”± [NAME] 所æ“有的物件已被é€è¿”其收ç´å€ã€‚
</notification>
<notification name="OtherObjectsReturned2">
- The objects on the selected parcel of land owned by the Resident &apos;[NAME]&apos; have been returned to their owner.
+ 在所é¸åœ°æ®µä¸Šç”±å±…æ°‘ &apos;[NAME]&apos; 所æ“有的物件已被é€è¿”其收ç´å€ã€‚
</notification>
<notification name="GroupObjectsReturned">
- The objects on the selected parcel of land shared with the group [GROUPNAME] have been returned back to their owner&apos;s inventory.
-Transferable deeded objects have been returned to their previous owners.
-Non-transferable objects that are deeded to the group have been deleted.
+ 在所é¸åœ°æ®µä¸Šå’Œç¾¤çµ„ &apos;[GROUPNAME]&apos; 分享的物件已被é€è¿”其所有人的收ç´å€ã€‚
+å¯è½‰è®“的已讓渡物件已é€è¿”給å‰ç‰©ä¸»ã€‚
+讓渡給這個群組的ä¸å¯è½‰è®“物件已被刪除。
</notification>
<notification name="UnOwnedObjectsReturned">
- The objects on the selected parcel that are NOT owned by you have been returned to their owners.
+ 在所é¸åœ°æ®µä¸Šä¸æ˜¯ä½ æ“有的物件已é€è¿”給其所有人。
</notification>
<notification name="ServerObjectMessage">
- Message from [NAME]:
+ 來自 [NAME] 的訊æ¯ï¼š
&lt;nolink&gt;[MSG]&lt;/nolink&gt;
</notification>
<notification name="NotSafe">
- This land has damage enabled.
-You can be hurt here. If you die, you will be teleported to your home location.
+ 這塊土地å…許傷害。
+在這裡你å¯èƒ½æœƒå—傷害。 你如果死亡,會被瞬間傳é€å›žä½ çš„家。
</notification>
<notification name="NoFly">
- 這å€åŸŸé—œé–‰ä¸¦ç¦æ­¢é£›è¡Œã€‚
+ 這å€åŸŸç¦æ­¢é£›è¡Œã€‚
ä½ ä¸èƒ½åœ¨æ­¤è™•é£›è¡Œã€‚
</notification>
<notification name="PushRestricted">
- This area does not allow pushing. You can&apos;t push others here unless you own the land.
+ 這å€åŸŸä¸å…許推撞。 除éžä½ æ“有這塊土地,å¦å‰‡ä½ ä¸èƒ½æŽ¨æ’žåˆ¥äººã€‚
</notification>
<notification name="NoVoice">
- This area has voice chat disabled. You won&apos;t be able to hear anyone talking.
+ 這å€åŸŸç¦æ­¢èªžéŸ³èŠå¤©ã€‚ ä½ å°‡ä¸æœƒè½åˆ°ä»»ä½•äººèªªè©±ã€‚
</notification>
<notification name="NoBuild">
- This area has building disabled. You can&apos;t build or rez objects here.
+ 這å€åŸŸç¦æ­¢å»ºé€ ç‰©ä»¶ã€‚ ä½ ä¸èƒ½åœ¨æ­¤å»ºé€ æˆ–產生物件。
+ </notification>
+ <notification name="PathfindingDirty">
+ 這地å€çš„尋徑功能有所變更,待儲存。 如果你有建製權,你å¯ä»¥é»žæŒ‰ã€Œé‡æ–°ç”¢å‡ºåœ°å€ã€æŒ‰éˆ•é‡æ–°ç”¢å‡ºåœ°å€ã€‚
+ </notification>
+ <notification name="DynamicPathfindingDisabled">
+ 這地å€ä¸¦æœªå•Ÿç”¨å‹•æ…‹å°‹å¾‘。 使用尋徑 LSL 呼å«çš„帶腳本物件,在此地å€å¯èƒ½ç„¡æ³•æ­£å¸¸é‹ä½œã€‚
+ </notification>
+ <notification name="PathfindingCannotRebakeNavmesh">
+ 發生錯誤。 å•é¡Œå¯èƒ½å‡ºåœ¨ç¶²è·¯æˆ–伺æœå™¨ï¼Œä¹Ÿå¯èƒ½å› ç‚ºä½ ç„¡æ¬Šå»ºè£½ç‰©ä»¶ã€‚ 有時,åªè¦ç™»å‡ºå†ç™»å…¥å³èƒ½è§£æ±ºé€™é¡žå•é¡Œã€‚
+ <usetemplate name="okbutton" yestext="確定"/>
+ </notification>
+ <notification name="SeeAvatars">
+ 本地段隱è—其內的化身和èŠå¤©æ–‡å­—,其他地段看ä¸åˆ°ã€‚ 你看ä¸è¦‹åœ°æ®µå¤–的居民,他們也看ä¸è¦‹ä½ ã€‚ é »é“ 0 çš„èŠå¤©æ–‡å­—也被å°éŽ–。
</notification>
<notification name="ScriptsStopped">
- An administrator has temporarily stopped scripts in this region.
+ æŸç®¡ç†å“¡å·²æš«æ™‚åœæ­¢å€åŸŸè£¡çš„腳本。
</notification>
<notification name="ScriptsNotRunning">
- This region is not running any scripts.
+ 這å€åŸŸæ²’有執行任何腳本。
</notification>
<notification name="NoOutsideScripts">
- This land has outside scripts disabled.
+ 這塊土地ç¦ç”¨å¤–來腳本。
-No scripts will work here except those belonging to the land owner.
+åªæœ‰å±¬æ–¼åœŸåœ°æ‰€æœ‰äººçš„腳本在此å¯ä»¥æ­£å¸¸åŸ·è¡Œã€‚
</notification>
<notification name="ClaimPublicLand">
- You can only claim public land in the Region you&apos;re in.
+ ä½ åªèƒ½åœ¨ä½ æ‰€è™•çš„å€åŸŸæ”¶å–公共土地。
</notification>
<notification name="RegionTPAccessBlocked">
- You aren&apos;t allowed in that Region due to your maturity Rating. You may need to validate your age and/or install the latest Viewer.
-
-Please go to the Knowledge Base for details on accessing areas with this maturity Rating.
+ 你所欲å‰å¾€çš„地å€å«æœ‰è¶…éŽä½ ç›®å‰å好的分級的內容。 ä½ å¯ä»¥åˆ°ã€Œæˆ‘自己 &gt; å好設定 &gt; 一般設定ã€è®Šæ›´ä½ çš„å好設定。
</notification>
<notification name="URBannedFromRegion">
- You are banned from the region.
+ 這個å€åŸŸç¦æ­¢ä½ é€²å…¥ã€‚
</notification>
<notification name="NoTeenGridAccess">
- Your account cannot connect to this teen grid region.
+ 你的帳戶ä¸å¯é€£æŽ¥åˆ°é€™å€‹é’少年網格å€åŸŸã€‚
</notification>
<notification name="ImproperPaymentStatus">
- You do not have proper payment status to enter this region.
+ 你沒有é©ç•¶çš„付款狀態,ä¸èƒ½é€²å…¥é€™å€åŸŸã€‚
</notification>
- <notification name="MustGetAgeRgion">
- 你必須通éŽå¹´é½¡èªè­‰ä»¥é€²å…¥é€™åœ°å€ã€‚
+ <notification name="MustGetAgeRegion">
+ 你必須年滿 18 æ­²æ‰å¯é€²å…¥é€™åœ°å€ã€‚
</notification>
<notification name="MustGetAgeParcel">
- 你必須通éŽå¹´é½¡é©—證以進入這地段。
+ 你必須年滿 18 æ­²æ‰å¯é€²å…¥é€™åœ°æ®µã€‚
</notification>
<notification name="NoDestRegion">
- 無目的地地å€ç™¼ç¾ã€‚
+ 找ä¸åˆ°ç›®çš„地地å€ã€‚
</notification>
<notification name="NotAllowedInDest">
- You are not allowed into the destination.
+ ä½ ä¸å‡†å‰å¾€ç›®çš„地。
</notification>
<notification name="RegionParcelBan">
- Cannot region cross into banned parcel. Try another way.
+ 無法跨出地å€é€²å…¥ç¦æ­¢ä½ çš„地段。 è«‹æ›ä¸€å€‹æ–¹å¼ã€‚
</notification>
<notification name="TelehubRedirect">
- You have been redirected to a telehub.
+ 你已被é‡æ–°å°Žå¾€ä¸€å€‹çž¬é–“傳é€ä¸­å¿ƒã€‚
</notification>
<notification name="CouldntTPCloser">
- Could not teleport closer to destination.
+ 無法瞬間傳é€åˆ°æ›´æŽ¥è¿‘目的地的地點。
</notification>
<notification name="TPCancelled">
瞬間傳é€å·²å–消。
</notification>
<notification name="FullRegionTryAgain">
- The region you are attempting to enter is currently full.
-Please try again in a few moments.
+ 你試圖進入的地å€ç›®å‰äººæ»¿ã€‚
+è«‹ç¨å¾…一會兒å†è©¦ã€‚
</notification>
<notification name="GeneralFailure">
一般故障。
</notification>
<notification name="RoutedWrongRegion">
- 路由導å‘到錯誤地å€ã€‚è«‹å†è©¦ä¸€æ¬¡ã€‚
+ 被繞往錯誤的地å€ã€‚ è«‹å†è©¦ä¸€æ¬¡ã€‚
</notification>
<notification name="NoValidAgentID">
- No valid agent id.
+ 沒有有效的化身編號。
</notification>
<notification name="NoValidSession">
- No valid session id.
+ 沒有有效的時域編號。
</notification>
<notification name="NoValidCircuit">
- No valid circuit code.
+ 沒有有效的線路碼。
</notification>
<notification name="NoValidTimestamp">
- No valid timestamp.
+ 沒有有效的時間戳記。
</notification>
<notification name="NoPendingConnection">
- Unable to create pending connection.
+ 無法建立待通的連線。
</notification>
<notification name="InternalUsherError">
- Internal error attempting to connect agent usher.
+ 試圖連接用戶引導時發生內部錯誤。
</notification>
<notification name="NoGoodTPDestination">
- Unable to find a good teleport destination in this region.
+ 在這地å€æ‰¾ä¸åˆ°åˆé©çš„瞬間傳é€ç›®çš„地。
</notification>
<notification name="InternalErrorRegionResolver">
- Internal error attempting to activate region resolver.
+ 試圖啟動å€åŸŸè§£æžå™¨æ™‚發生內部錯誤。
</notification>
<notification name="NoValidLanding">
- A valid landing point could not be found.
+ 找ä¸åˆ°æœ‰æ•ˆçš„登陸地點。
</notification>
<notification name="NoValidParcel">
- No valid parcel could be found.
+ 找ä¸åˆ°æœ‰æ•ˆçš„地段。
</notification>
<notification name="ObjectGiveItem">
- An object named &lt;nolink&gt;[OBJECTFROMNAME]&lt;/nolink&gt; owned by [NAME_SLURL] has given you this [OBJECTTYPE]:
-[ITEM_SLURL]
+ å為 &lt;nolink&gt;[OBJECTFROMNAME]&lt;/nolink&gt;ã€ç”± [NAME_SLURL] æ“有的物件給了你這個 [OBJECTTYPE]:
+&lt;nolink&gt;[ITEM_SLURL]&lt;/nolink&gt;
+ <form name="form">
+ <button name="Keep" text="ä¿ç•™"/>
+ <button name="Discard" text="丟棄"/>
+ <button name="Mute" text="å°éŽ–所有人"/>
+ </form>
+ </notification>
+ <notification name="OwnObjectGiveItem">
+ ä½ å為 &lt;nolink&gt;[OBJECTFROMNAME]&lt;/nolink&gt; 的物件給了你這個 [OBJECTTYPE]:
+&lt;nolink&gt;[ITEM_SLURL]&lt;/nolink&gt;
<form name="form">
- <button name="Keep" text="Keep"/>
- <button name="Discard" text="Discard"/>
- <button name="Mute" text="Block"/>
+ <button name="Keep" text="ä¿ç•™"/>
+ <button name="Discard" text="丟棄"/>
</form>
</notification>
<notification name="UserGiveItem">
- [NAME_SLURL] has given you this [OBJECTTYPE]:
+ [NAME_SLURL] 給了你這個 [OBJECTTYPE]:
[ITEM_SLURL]
<form name="form">
- <button name="Show" text="Show"/>
- <button name="Discard" text="Discard"/>
- <button name="Mute" text="Block"/>
+ <button name="Show" text="顯示"/>
+ <button name="Discard" text="丟棄"/>
+ <button name="Mute" text="å°éŽ–"/>
</form>
</notification>
<notification name="GodMessage">
@@ -2448,16 +2671,37 @@ Please try again in a few moments.
</form>
</notification>
<notification name="TeleportOffered">
- [NAME_SLURL] has offered to teleport you to their location:
+ [NAME_SLURL] 想è¦çž¬é–“傳é€ä½ åˆ°ä»–的地點:
-[MESSAGE] - [MATURITY_STR] &lt;icon&gt;[MATURITY_ICON]&lt;/icon&gt;
+“[MESSAGE]â€
+&lt;icon&gt;[MATURITY_ICON]&lt;/icon&gt; - [MATURITY_STR]
<form name="form">
<button name="Teleport" text="瞬間傳é€"/>
<button name="Cancel" text="å–消"/>
</form>
</notification>
+ <notification name="TeleportOffered_MaturityExceeded">
+ [NAME_SLURL] 想è¦çž¬é–“傳é€ä½ åˆ°ä»–的地點:
+
+“[MESSAGE]â€
+&lt;icon&gt;[MATURITY_ICON]&lt;/icon&gt; - [MATURITY_STR]
+
+此地å€åŒ…å« [REGION_CONTENT_MATURITY] 的分級內容,å¯æ˜¯ä½ ç›®å‰çš„å好設定排除了 [REGION_CONTENT_MATURITY] 的分級內容。 我們å¯ä»¥è®Šæ›´ä½ çš„å好設定好讓你繼續瞬間傳é€ï¼Œä½ ä¹Ÿå¯å–消這動作。
+ <form name="form">
+ <button name="Teleport" text="變更後繼續"/>
+ <button name="Cancel" text="å–消"/>
+ </form>
+ </notification>
+ <notification name="TeleportOffered_MaturityBlocked">
+ [NAME_SLURL] 想è¦çž¬é–“傳é€ä½ åˆ°ä»–的地點:
+
+“[MESSAGE]â€
+&lt;icon&gt;[MATURITY_ICON]&lt;/icon&gt; - [MATURITY_STR]
+
+å¯æ˜¯ï¼Œæ­¤åœ°å€å«æœ‰åƒ…é™æˆäººçš„內容。
+ </notification>
<notification name="TeleportOfferSent">
- Teleport offer sent to [TO_NAME]
+ å·²å‘ [TO_NAME] 發出瞬間傳é€é‚€è«‹
</notification>
<notification name="GotoURL">
[MESSAGE]
@@ -2468,33 +2712,33 @@ Please try again in a few moments.
</form>
</notification>
<notification name="OfferFriendship">
- [NAME_SLURL] is offering friendship.
+ [NAME_SLURL] 想æˆç‚ºä½ çš„朋å‹ã€‚
[MESSAGE]
-(By default, you will be able to see each other&apos;s online status.)
+(根據é è¨­è¨­å®šï¼Œä½ å€‘å°‡å¯çœ‹åˆ°å½¼æ­¤çš„線上狀態。)
<form name="form">
<button name="Accept" text="接å—"/>
<button name="Decline" text="è¬çµ•"/>
</form>
</notification>
<notification name="FriendshipOffered">
- You have offered friendship to [TO_NAME]
+ 已經邀請 [TO_NAME] æˆç‚ºæœ‹å‹
</notification>
<notification name="OfferFriendshipNoMessage">
- [NAME_SLURL] is offering friendship.
+ [NAME_SLURL] 想æˆç‚ºä½ çš„朋å‹ã€‚
-(By default, you will be able to see each other&apos;s online status.)
+(根據é è¨­è¨­å®šï¼Œä½ å€‘å°‡å¯çœ‹åˆ°å½¼æ­¤çš„線上狀態。)
<form name="form">
<button name="Accept" text="接å—"/>
<button name="Decline" text="è¬çµ•"/>
</form>
</notification>
<notification name="FriendshipAccepted">
- &lt;nolink&gt;[NAME]&lt;/nolink&gt; accepted your friendship offer.
+ &lt;nolink&gt;[NAME]&lt;/nolink&gt; 接å—了你的交å‹é‚€è«‹ã€‚
</notification>
<notification name="FriendshipDeclined">
- &lt;nolink&gt;[NAME]&lt;/nolink&gt; è¬çµ•ä½ çš„交å‹é‚€è«‹ã€‚
+ &lt;nolink&gt;[NAME]&lt;/nolink&gt; 婉拒了你的交å‹é‚€è«‹ã€‚
</notification>
<notification name="FriendshipAcceptedByMe">
交å‹é‚€è«‹è¢«æŽ¥å—。
@@ -2503,208 +2747,215 @@ Please try again in a few moments.
交å‹é‚€è«‹è¢«è¬çµ•ã€‚
</notification>
<notification name="OfferCallingCard">
- [NAME] is offering their calling card.
-This will add a bookmark in your inventory so you can quickly IM this Resident.
+ [NAME] é€çµ¦ä½ ä»–çš„å片。
+這將在你的收ç´å€æ–°å¢žä¸€å€‹æ›¸ç±¤ï¼Œæ–¹ä¾¿ä½ å’Œé€™ä½å±…民互傳å³æ™‚訊æ¯ã€‚
<form name="form">
<button name="Accept" text="接å—"/>
<button name="Decline" text="è¬çµ•"/>
</form>
</notification>
<notification name="RegionRestartMinutes">
- This region will restart in [MINUTES] minutes.
-If you stay in this region you will be logged out.
+ 本地å€å°‡åœ¨ [MINUTES] 分é˜å¾Œé‡æ–°å•Ÿå‹•ã€‚
+如果你繼續留在這地å€ï¼Œä½ å°‡æœƒè¢«ç™»å‡ºã€‚
</notification>
<notification name="RegionRestartSeconds">
- This region will restart in [SECONDS] seconds.
-If you stay in this region you will be logged out.
+ 本地å€å°‡åœ¨ [SECONDS] 秒後é‡æ–°å•Ÿå‹•ã€‚
+如果你繼續留在這地å€ï¼Œä½ å°‡æœƒè¢«ç™»å‡ºã€‚
</notification>
<notification name="LoadWebPage">
è¼‰å…¥ç¶²é  [URL]?
[MESSAGE]
-From object: &lt;nolink&gt;[OBJECTNAME]&lt;/nolink&gt;, owner: [NAME]?
+來æºç‰©ä»¶ï¼š&lt;nolink&gt;[OBJECTNAME]&lt;/nolink&gt;(所有人是 [NAME])?
<form name="form">
<button name="Gotopage" text="å‰å¾€é é¢"/>
<button name="Cancel" text="å–消"/>
</form>
</notification>
<notification name="FailedToFindWearableUnnamed">
- Failed to find [TYPE] in database.
+ 資料庫找ä¸åˆ° [TYPE]。
</notification>
<notification name="FailedToFindWearable">
- Failed to find [TYPE] named [DESC] in database.
+ 資料庫找ä¸åˆ°å為 [DESC] çš„ [TYPE]。
</notification>
<notification name="InvalidWearable">
- The item you are trying to wear uses a feature that your Viewer can&apos;t read. Please upgrade your version of [APP_NAME] to wear this item.
+ 你想è¦ç©¿è‘—的物項帶有一個ä¸æ˜¯ä½ ç›®å‰ Viewer 版本能夠讀å–的特性。 è«‹æ›´æ–°ä½ çš„ [APP_NAME] 版本å†ç©¿è‘—該物項。
</notification>
<notification name="ScriptQuestion">
- &apos;&lt;nolink&gt;[OBJECTNAME]&lt;/nolink&gt;&apos;, an object owned by &apos;[NAME]&apos;, would like to:
+ &apos;&lt;nolink&gt;[OBJECTNAME]&lt;/nolink&gt;&apos;,一個由 &apos;[NAME]&apos; æ“有的物件,想è¦ï¼š
[QUESTIONS]
-Is this OK?
+是å¦åŒæ„?
<form name="form">
<button name="Yes" text="是"/>
<button name="No" text="å¦"/>
- <button name="Mute" text="Block"/>
+ <button name="Mute" text="å°éŽ–"/>
</form>
</notification>
<notification name="ScriptQuestionCaution">
- An object named &apos;&lt;nolink&gt;[OBJECTNAME]&lt;/nolink&gt;&apos;, owned by &apos;[NAME]&apos; would like to:
-
-[QUESTIONS]
-If you do not trust this object and its creator, you should deny the request.
+ 警告:物件 &apos;&lt;nolink&gt;[OBJECTNAME]&lt;/nolink&gt;&apos; è¦æ±‚全權存å–你的林登幣帳戶。 你如果å…許存å–帳戶,它將å¯åœ¨ä»»ä½•æ™‚候從你帳戶å–走資金,或完全加以清空,或定期å–走部分資金,且ä¸æœƒç™¼å‡ºè­¦å‘Šã€‚
+
+如果你ä¸å®Œå…¨çž­è§£å®ƒç‚ºä½•è¦æ±‚å­˜å–你的帳戶,請勿å…准。
+ <form name="form">
+ <button name="Grant" text="å…許全權存å–"/>
+ <button name="Deny" text="拒絕"/>
+ </form>
+ </notification>
+ <notification name="UnknownScriptQuestion">
+ ç”± &apos;[NAME]&apos; 所æ“有的物件 &apos;&lt;nolink&gt;[OBJECTNAME]&lt;/nolink&gt;&apos; 正請求æŸé …執行時期腳本權é™ï¼Œä½†æœ¬ç€è¦½å™¨ç„¡æ³•è¾¨è­˜è©²æ¬Šé™ï¼Œæ•…ä¸å…准。
-Grant this request?
+欲准許此權é™ï¼Œè«‹å¾ž [DOWNLOADURL] 下載並更新為最新版ç€è¦½å™¨ã€‚
<form name="form">
- <button name="Grant" text="Grant"/>
- <button name="Deny" text="Deny"/>
- <button name="Details" text="細節..."/>
+ <button name="Deny" text="確定"/>
+ <button name="Mute" text="å°éŽ–"/>
</form>
</notification>
<notification name="ScriptDialog">
- [NAME]&apos;s &apos;&lt;nolink&gt;[TITLE]&lt;/nolink&gt;&apos;
+ [NAME] çš„ &apos;&lt;nolink&gt;[TITLE]&lt;/nolink&gt;&apos;
[MESSAGE]
<form name="form">
- <button name="Ignore" text="忽視"/>
+ <button name="Client_Side_Mute" text="å°éŽ–"/>
+ <button name="Client_Side_Ignore" text="忽視"/>
</form>
</notification>
<notification name="ScriptDialogGroup">
- [GROUPNAME]&apos;s &apos;&lt;nolink&gt;[TITLE]&lt;/nolink&gt;&apos;
+ [GROUPNAME] çš„ &apos;&lt;nolink&gt;[TITLE]&lt;/nolink&gt;&apos;
[MESSAGE]
<form name="form">
- <button name="Ignore" text="忽視"/>
+ <button name="Client_Side_Mute" text="å°éŽ–"/>
+ <button name="Client_Side_Ignore" text="忽視"/>
</form>
</notification>
<notification name="BuyLindenDollarSuccess">
- Thank you for your payment!
+ æ„Ÿè¬ä½ ä»˜æ¬¾ï¼
-Your L$ balance will be updated when processing completes. If processing takes more than 20 mins, your transaction may be cancelled. In that case, the purchase amount will be credited to your US$ balance.
+處ç†å®Œæˆå¾Œï¼Œä½ çš„ L$ 餘é¡å°‡æœƒæ›´æ–°ã€‚ 如果處ç†éŽç¨‹è¶…éŽ 20 分é˜ï¼Œä½ çš„交易å¯èƒ½è¢«å–消。 在這狀æ³ä¸‹ï¼Œè³¼è²·é‡‘é¡å°‡é€€å›žçµ¦ä½ çš„ US$ 餘é¡ã€‚
-The status of your payment can be checked on your Transaction History page on your [http://secondlife.com/account/ Dashboard]
+ä½ å¯ä»¥åˆ°ä½ çš„[http://secondlife.com/account/ 塗鴉牆]上的交易歷å²è¨˜éŒ„é é¢ï¼Œå¯Ÿçœ‹ä»˜æ¬¾ç‹€æ…‹ã€‚
</notification>
<notification name="FirstOverrideKeys">
- Your movement keys are now being handled by an object.
-Try the arrow keys or AWSD to see what they do.
-Some objects (like guns) require you to go into mouselook to use them.
-Press &apos;M&apos; to do this.
+ ä½ çš„æ–¹å‘éµç¾åœ¨ç”±ä¸€å€‹ç‰©ä»¶ä¸»æŽ§ã€‚
+請試試方å‘éµæˆ– AWSD éµçœ‹æœ‰ä»€éº¼å應。
+有些物件(例如æ§æžï¼‰éœ€è¦ä½ åˆ‡æ›æˆç¬¬ä¸€äººç¨±è¦–角æ‰æœ‰ä½œç”¨ã€‚
+請按 M éµåšåˆ‡æ›ã€‚
</notification>
<notification name="FirstSandbox">
- This is a sandbox area, and is meant to help Residents learn how to build.
+ 這個一個沙盤å€ï¼Œæ—¨åœ¨å¹«åŠ©å±…民學習如何建製物件。
-Things you build here will be deleted after you leave, so don&apos;t forget to right-click and choose &apos;Take&apos; to move your creation to your Inventory.
+你在這裡建製的物件,在你離開後將被刪除。別忘了按滑鼠å³éµï¼Œé¸æ“‡ã€Œæ‹¿å–ã€ï¼Œå°‡ä½ çš„建製物é€åˆ°ä½ çš„收ç´å€ã€‚
</notification>
<notification name="MaxListSelectMessage">
- You may only select up to [MAX_SELECT] items from this list.
+ 你最多åªèƒ½å¾žé€™æ¸…單中é¸å– [MAX_SELECT] 個物項。
</notification>
<notification name="VoiceInviteP2P">
- [NAME] is inviting you to a Voice Chat call.
-Click Accept to join the call or Decline to decline the invitation. Click Block to block this caller.
+ [NAME] 正邀請你加入語音èŠå¤©ã€‚
+點按「接å—ã€åŠ å…¥é€šè©±ï¼Œæˆ–「è¬çµ•ã€é‚€è«‹ã€‚ 點按「å°éŽ–ã€ä¾¿å¯å°éŽ–這個發話人。
<form name="form">
<button name="Accept" text="接å—"/>
<button name="Decline" text="è¬çµ•"/>
- <button name="Mute" text="Block"/>
+ <button name="Mute" text="å°éŽ–"/>
</form>
</notification>
<notification name="AutoUnmuteByIM">
- [NAME] was sent an instant message and has been automatically unblocked.
+ [NAME] 已收到一則å³æ™‚訊æ¯ï¼Œä¸¦å·²è¢«è‡ªå‹•è§£é™¤å°éŽ–。
</notification>
<notification name="AutoUnmuteByMoney">
- [NAME] was given money and has been automatically unblocked.
+ [NAME] 已收到錢,並已被自動解除å°éŽ–。
</notification>
<notification name="AutoUnmuteByInventory">
- [NAME] was offered inventory and has been automatically unblocked.
+ [NAME] 已得知你è¦è´ˆé€æ”¶ç´ç‰©ä»¶ï¼Œä¸¦å·²è¢«è‡ªå‹•è§£é™¤å°éŽ–。
</notification>
<notification name="VoiceInviteGroup">
- [NAME] has joined a Voice Chat call with the group [GROUP].
-Click Accept to join the call or Decline to decline the invitation. Click Block to block this caller.
+ [NAME] 已加入和群組 [GROUP] 的語音èŠå¤©é€šè©±ã€‚
+點按「接å—ã€åŠ å…¥é€šè©±ï¼Œæˆ–「è¬çµ•ã€é‚€è«‹ã€‚ 點按「å°éŽ–ã€ä¾¿å¯å°éŽ–這個發話人。
<form name="form">
<button name="Accept" text="接å—"/>
<button name="Decline" text="è¬çµ•"/>
- <button name="Mute" text="Block"/>
+ <button name="Mute" text="å°éŽ–"/>
</form>
</notification>
<notification name="VoiceInviteAdHoc">
- [NAME] has joined a voice chat call with a conference chat.
-Click Accept to join the call or Decline to decline the invitation. Click Block to block this caller.
+ [NAME] 已加入多方語音通話。
+點按「接å—ã€åŠ å…¥é€šè©±ï¼Œæˆ–「è¬çµ•ã€é‚€è«‹ã€‚ 點按「å°éŽ–ã€ä¾¿å¯å°éŽ–這個發話人。
<form name="form">
<button name="Accept" text="接å—"/>
<button name="Decline" text="è¬çµ•"/>
- <button name="Mute" text="Block"/>
+ <button name="Mute" text="å°éŽ–"/>
</form>
</notification>
<notification name="InviteAdHoc">
- [NAME] is inviting you to a conference chat.
-Click Accept to join the chat or Decline to decline the invitation. Click Block to block this caller.
+ [NAME] 正邀請你加入多方通話。
+點按「接å—ã€åŠ å…¥é€šè©±ï¼Œæˆ–「è¬çµ•ã€é‚€è«‹ã€‚ 點按「å°éŽ–ã€ä¾¿å¯å°éŽ–這個發話人。
<form name="form">
<button name="Accept" text="接å—"/>
<button name="Decline" text="è¬çµ•"/>
- <button name="Mute" text="Block"/>
+ <button name="Mute" text="å°éŽ–"/>
</form>
</notification>
<notification name="VoiceChannelFull">
- The voice call you are trying to join, [VOICE_CHANNEL_NAME], has reached maximum capacity. Please try again later.
+ 你試圖加入 [VOICE_CHANNEL_NAME] 語音通話,ä¸éŽå®ƒå·²é”負載上é™ã€‚ è«‹ç¨å€™å†è©¦ä¸€æ¬¡ã€‚
</notification>
<notification name="ProximalVoiceChannelFull">
- We&apos;re sorry. This area has reached maximum capacity for voice conversations. Please try to use voice in another area.
+ 很抱歉。 這å€åŸŸå·²é”語音通話的負載上é™ã€‚ 請到å¦ä¸€å€‹å€åŸŸä½¿ç”¨èªžéŸ³ã€‚
</notification>
<notification name="VoiceChannelDisconnected">
- You have been disconnected from [VOICE_CHANNEL_NAME]. You will now be reconnected to Nearby Voice Chat.
+ ä½ çš„ [VOICE_CHANNEL_NAME] 通話已經中斷。 ç¾åœ¨ä½ å°‡é‡æ–°é€£é€šåˆ°é™„近的語音èŠå¤©ã€‚
</notification>
<notification name="VoiceChannelDisconnectedP2P">
- [VOICE_CHANNEL_NAME] has ended the call. You will now be reconnected to Nearby Voice Chat.
+ [VOICE_CHANNEL_NAME] 語音通話已çµæŸã€‚ ç¾åœ¨ä½ å°‡é‡æ–°é€£é€šåˆ°é™„近的語音èŠå¤©ã€‚
</notification>
<notification name="P2PCallDeclined">
- [VOICE_CHANNEL_NAME] has declined your call. You will now be reconnected to Nearby Voice Chat.
+ [VOICE_CHANNEL_NAME] 拒絕你加入語音通話。 ç¾åœ¨ä½ å°‡é‡æ–°é€£é€šåˆ°é™„近的語音èŠå¤©ã€‚
</notification>
<notification name="P2PCallNoAnswer">
- [VOICE_CHANNEL_NAME] is not available to take your call. You will now be reconnected to Nearby Voice Chat.
+ [VOICE_CHANNEL_NAME] 無法接通你的通話。 ç¾åœ¨ä½ å°‡é‡æ–°é€£é€šåˆ°é™„近的語音èŠå¤©ã€‚
</notification>
<notification name="VoiceChannelJoinFailed">
- Failed to connect to [VOICE_CHANNEL_NAME], please try again later. You will now be reconnected to Nearby Voice Chat.
+ 無法連通 [VOICE_CHANNEL_NAME],,請ç¨å€™å†è©¦ã€‚ ç¾åœ¨ä½ å°‡é‡æ–°é€£é€šåˆ°é™„近的語音èŠå¤©ã€‚
</notification>
<notification name="VoiceLoginRetry">
- We are creating a voice channel for you. This may take up to one minute.
+ 我們正為你建立語音頻é“。 這至多å¯èƒ½éœ€æ™‚一分é˜ã€‚
</notification>
<notification name="VoiceEffectsExpired">
- One or more of your subscribed Voice Morphs has expired.
-[[URL] Click here] to renew your subscription.
+ 至少一個你訂用的變è²æ•ˆæžœå·²ç¶“éŽæœŸã€‚
+[[URL] 點按這裡] 繼續訂用。
</notification>
<notification name="VoiceEffectsExpiredInUse">
- The active Voice Morph has expired, your normal voice settings have been applied.
-[[URL] Click here] to renew your subscription.
+ 使用中的變è²æ•ˆæžœå·²ç¶“éŽæœŸï¼Œå·²ç”¨ä½ å¹³æ™‚çš„è²éŸ³è¨­å®šå–代。
+[[URL] 點按這裡] 繼續訂用。
</notification>
<notification name="VoiceEffectsWillExpire">
- One or more of your Voice Morphs will expire in less than [INTERVAL] days.
-[[URL] Click here] to renew your subscription.
+ 至少一個你訂用的變è²æ•ˆæžœå°‡åœ¨ [INTERVAL] 天後到期。
+[[URL] 點按這裡] 繼續訂用。
</notification>
<notification name="VoiceEffectsNew">
- New Voice Morphs are available!
+ 新的變è²æ•ˆæžœä¸Šå¸‚了ï¼
</notification>
<notification name="Cannot enter parcel: not a group member">
- Only members of a certain group can visit this area.
+ åªæœ‰æŸç‰¹å®šç¾¤çµ„çš„æˆå“¡æ‰èƒ½é€²å…¥é€™å€åŸŸã€‚
</notification>
<notification name="Cannot enter parcel: banned">
- Cannot enter parcel, you have been banned.
+ 你已被ç¦å…¥ï¼Œå› æ­¤ç„¡æ³•é€²å…¥é€™åœ°æ®µã€‚
</notification>
<notification name="Cannot enter parcel: not on access list">
- Cannot enter parcel, you are not on the access list.
+ 無法進入這地段,你ä¸åœ¨å‡ºå…¥è¨±å¯å單中。
</notification>
<notification name="VoiceNotAllowed">
- You do not have permission to connect to voice chat for [VOICE_CHANNEL_NAME].
+ 你無權連通 [VOICE_CHANNEL_NAME] 語音èŠå¤©ã€‚
</notification>
<notification name="VoiceCallGenericError">
- An error has occurred while trying to connect to voice chat for [VOICE_CHANNEL_NAME]. Please try again later.
+ 試圖連通 [VOICE_CHANNEL_NAME] 語音èŠå¤©æ™‚發生錯誤。 è«‹ç¨å€™å†è©¦ä¸€æ¬¡ã€‚
</notification>
<notification name="UnsupportedCommandSLURL">
- 你所點擊的 SLurl ä½ç½®ä¸¦ä¸è¢«æ”¯æ´ã€‚
+ 你所點按的 SLurl ä½ç½®ä¸¦ä¸è¢«æ”¯æ´ã€‚
</notification>
<notification name="BlockedSLURL">
- A SLurl was received from an untrusted browser and has been blocked for your security.
+ 從未被信任的ç€è¦½å™¨æŽ¥æ”¶åˆ°ä¸€å€‹ SLurl,為了你的安全起見,已將它å°éŽ–。
</notification>
<notification name="ThrottledSLURL">
- Multiple SLurls were received from an untrusted browser within a short period.
-They will be blocked for a few seconds for your security.
+ 短時間內從一個ä¸è¢«ä¿¡ä»»çš„ç€è¦½å™¨æŽ¥æ”¶åˆ°å¤šå€‹ SLurl。
+為了你的安全起見,它們將被å°éŽ–幾秒é˜ã€‚
</notification>
<notification name="IMToast">
[MESSAGE]
@@ -2713,45 +2964,72 @@ They will be blocked for a few seconds for your security.
</form>
</notification>
<notification name="ConfirmCloseAll">
- 你確定è¦é—œé–‰å…¨éƒ¨ IMs å°è©±è¦–窗?
+ 你確定è¦é—œé–‰æ‰€æœ‰çš„ IM?
<usetemplate ignoretext="在我關閉全部的 IMs å°è©±è¦–窗å‰ç¢ºèªã€‚" name="okcancelignore" notext="å–消" yestext="確定"/>
</notification>
<notification name="AttachmentSaved">
附件已儲存。
</notification>
<notification name="UnableToFindHelpTopic">
- Unable to find the help topic for this element.
+ 找ä¸åˆ°é€™å€‹å…ƒä»¶çš„幫助主題。
</notification>
<notification name="ObjectMediaFailure">
- Server Error: Media update or get failed.
+ 伺æœå™¨éŒ¯èª¤ï¼šåª’體更新或å–得失敗。
&apos;[ERROR]&apos;
<usetemplate name="okbutton" yestext="確定"/>
</notification>
<notification name="TextChatIsMutedByModerator">
- Your text chat has been muted by moderator.
+ 主æŒäººå·²è¨­å®šå¿½ç•¥ä½ çš„文字èŠå¤©å…§å®¹ã€‚
<usetemplate name="okbutton" yestext="確定"/>
</notification>
<notification name="VoiceIsMutedByModerator">
- Your voice has been muted by moderator.
+ 主æŒäººå·²å°‡ä½ çš„語音消音。
<usetemplate name="okbutton" yestext="確定"/>
</notification>
+ <notification name="UploadCostConfirmation">
+ 上傳將花費 L$[PRICE],是å¦ç¹¼çºŒï¼Ÿ
+ <usetemplate name="okcancelbuttons" notext="å–消" yestext="上傳"/>
+ </notification>
<notification name="ConfirmClearTeleportHistory">
- Are you sure you want to delete your teleport history?
+ 確定清除你的瞬間傳é€æ­·å²è¨˜éŒ„?
<usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/>
</notification>
<notification name="BottomTrayButtonCanNotBeShown">
- Selected button can not be shown right now.
-The button will be shown when there is enough space for it.
+ 所é¸æŒ‰éˆ•ç›®å‰ç„¡æ³•é¡¯ç¤ºã€‚
+等到空間足夠,按鈕將會顯示出來。
</notification>
<notification name="ShareNotification">
- Select residents to share with.
+ é¸å–è¦åˆ†äº«çš„居民。
+ </notification>
+ <notification name="MeshUploadError">
+ [LABEL] 上傳失敗:[MESSAGE] [IDENTIFIER]
+
+詳見記錄檔。
+ </notification>
+ <notification name="MeshUploadPermError">
+ 請求網é¢ä¸Šå‚³æ¬Šé™æ™‚出錯。
+ </notification>
+ <notification name="RegionCapabilityRequestError">
+ 無法å–得地å€èƒ½åŠ› &apos;[CAPABILITY]&apos;。
</notification>
<notification name="ShareItemsConfirmation">
- Are you sure you want to share the following items:
+ 請確定你è¦å’Œå±…民分享這些物項:
+
+&lt;nolink&gt;[ITEMS]&lt;/nolink&gt;
+
+居民:
+
+[RESIDENTS]
+ <usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/>
+ </notification>
+ <notification name="ShareFolderConfirmation">
+ 一次åªèƒ½åˆ†äº«ä¸€å€‹è³‡æ–™å¤¾ã€‚
+
+請確定你è¦å’Œå±…民分享這些物項:
&lt;nolink&gt;[ITEMS]&lt;/nolink&gt;
-With the following Residents:
+居民:
[RESIDENTS]
<usetemplate name="okcancelbuttons" notext="å–消" yestext="確定"/>
@@ -2762,117 +3040,140 @@ With the following Residents:
<notification name="DeedToGroupFail">
讓渡給群組失敗。
</notification>
+ <notification name="ReleaseLandThrottled">
+ ç›®å‰ç„¡æ³•éºæ£„ [PARCEL_NAME] 地段。
+ </notification>
+ <notification name="ReleasedLandWithReclaim">
+ [AREA] 平方公尺的地段「[PARCEL_NAME]ã€å·²é‡‹å‡ºã€‚
+
+你須在 [RECLAIM_PERIOD] å°æ™‚內領回(花費 L$0),å¦å‰‡å°‡é–‹æ”¾å‡ºå”®çµ¦ä»»ä½•äººã€‚
+ </notification>
+ <notification name="ReleasedLandNoReclaim">
+ [AREA] 平方公尺的地段「[PARCEL_NAME]ã€å·²é‡‹å‡ºã€‚
+
+ç¾å·²é–‹æ”¾å‡ºå”®çµ¦ä»»ä½•äººã€‚
+ </notification>
<notification name="AvatarRezNotification">
- ( [EXISTENCE] seconds alive )
-Avatar &apos;[NAME]&apos; declouded after [TIME] seconds.
+ (存續 [EXISTENCE] 秒é˜ï¼‰
+化身 &apos;[NAME]&apos; 在 [TIME] 秒內完全呈ç¾ã€‚
</notification>
<notification name="AvatarRezSelfBakedDoneNotification">
- ( [EXISTENCE] seconds alive )
-You finished baking your outfit after [TIME] seconds.
+ (存續 [EXISTENCE] 秒é˜ï¼‰
+ä½ çš„è£æ‰®åœ¨ [TIME] 秒內定貌。
</notification>
<notification name="AvatarRezSelfBakedUpdateNotification">
- ( [EXISTENCE] seconds alive )
-You sent out an update of your appearance after [TIME] seconds.
+ (存續 [EXISTENCE] 秒é˜ï¼‰
+你在 [TIME] 秒後é€å‡ºæ›´æ–°å¤–觀請求。
[STATUS]
</notification>
<notification name="AvatarRezCloudNotification">
- ( [EXISTENCE] seconds alive )
-Avatar &apos;[NAME]&apos; became cloud.
+ (存續 [EXISTENCE] 秒é˜ï¼‰
+化身 &apos;[NAME]&apos; 已雲化。
</notification>
<notification name="AvatarRezArrivedNotification">
- ( [EXISTENCE] seconds alive )
-Avatar &apos;[NAME]&apos; appeared.
+ (存續 [EXISTENCE] 秒é˜ï¼‰
+化身 &apos;[NAME]&apos; 已出ç¾ã€‚
</notification>
<notification name="AvatarRezLeftCloudNotification">
- ( [EXISTENCE] seconds alive )
-Avatar &apos;[NAME]&apos; left after [TIME] seconds as cloud.
+ (存續 [EXISTENCE] 秒é˜ï¼‰
+化身 &apos;[NAME]&apos; 在雲化 [TIME] 秒後離開。
</notification>
<notification name="AvatarRezEnteredAppearanceNotification">
- ( [EXISTENCE] seconds alive )
-Avatar &apos;[NAME]&apos; entered appearance mode.
+ (存續 [EXISTENCE] 秒é˜ï¼‰
+化身 &apos;[NAME]&apos; 進入外觀模å¼ã€‚
</notification>
<notification name="AvatarRezLeftAppearanceNotification">
- ( [EXISTENCE] seconds alive )
-Avatar &apos;[NAME]&apos; left appearance mode.
+ (存續 [EXISTENCE] 秒é˜ï¼‰
+化身 &apos;[NAME]&apos; 離開外觀模å¼ã€‚
</notification>
<notification name="NoConnect">
- We&apos;re having trouble connecting using [PROTOCOL] [HOSTID].
-Please check your network and firewall setup.
+ 使用 [PROTOCOL] [HOSTID] 連線時出了å•é¡Œã€‚
+請檢查你的網路和防ç«ç‰†è¨­å®šã€‚
<usetemplate name="okbutton" yestext="確定"/>
</notification>
<notification name="NoVoiceConnect">
- We&apos;re having trouble connecting to your voice server:
+ 試圖連接語音伺æœå™¨æ™‚出了å•é¡Œï¼š
[HOSTID]
-Voice communications will not be available.
-Please check your network and firewall setup.
+將無法用語音æºé€šã€‚
+請檢查你的網路和防ç«ç‰†è¨­å®šã€‚
<usetemplate name="okbutton" yestext="確定"/>
</notification>
<notification name="AvatarRezLeftNotification">
- ( [EXISTENCE] seconds alive )
-Avatar &apos;[NAME]&apos; left as fully loaded.
+ (存續 [EXISTENCE] 秒é˜ï¼‰
+化身 &apos;[NAME]&apos; 在完全載入狀æ³ä¸‹é›¢é–‹ã€‚
</notification>
<notification name="AvatarRezSelfBakedTextureUploadNotification">
- ( [EXISTENCE] seconds alive )
-You uploaded a [RESOLUTION] baked texture for &apos;[BODYREGION]&apos; after [TIME] seconds.
+ (存續 [EXISTENCE] 秒é˜ï¼‰
+你在 [TIME] 秒é˜å¾Œç‚º &apos;[BODYREGION]&apos; 上傳了一個 [RESOLUTION] 的定貌æ質。
</notification>
<notification name="AvatarRezSelfBakedTextureUpdateNotification">
- ( [EXISTENCE] seconds alive )
-You locally updated a [RESOLUTION] baked texture for &apos;[BODYREGION]&apos; after [TIME] seconds.
+ (存續 [EXISTENCE] 秒é˜ï¼‰
+你在 [TIME] 秒é˜å¾Œåœ¨æœ¬åœ°ç‚º &apos;[BODYREGION]&apos; 更新了一個 [RESOLUTION] 的定貌æ質。
+ </notification>
+ <notification name="LivePreviewUnavailable">
+ 我們無法顯示這個æ質的é è¦½ï¼Œå› ç‚ºå®ƒè¨­ç‚ºã€Œç¦æ­¢è¤‡è£½ã€ä¸” / 或「ç¦æ­¢è½‰ç§»ã€ã€‚
+ <usetemplate ignoretext="「ç¦æ­¢è¤‡è£½ã€å’Œã€Œç¦æ­¢è½‰ç§»ã€çš„æ質若ä¸èƒ½ä½¿ç”¨å¯¦æ™‚é è¦½æ¨¡å¼ï¼Œè«‹çµ¦æˆ‘警示。" name="okignore" yestext="確定"/>
</notification>
<notification name="ConfirmLeaveCall">
你確定è¦é›¢é–‹é€™æ®µé€šè©±ï¼Ÿ
<usetemplate ignoretext="我çµæŸé€šè©±å‰é€²è¡Œç¢ºèª" name="okcancelignore" notext="å¦" yestext="是"/>
</notification>
<notification name="ConfirmMuteAll">
- You have selected to mute all participants in a group call.
-This will also cause all residents that later join the call to be
-muted, even after you have left the call.
+ ä½ å·²é¸æ“‡è¦å°‡æ‰€æœ‰åƒèˆ‡ç¾¤çµ„通話的人消音。
+這將導致後來加入通話的所有居民åŒæ¨£è¢«
+消音,å³ä½¿åœ¨ä½ é›¢é–‹é€šè©±å¾Œä¹Ÿä¸€æ¨£ã€‚
-Mute everyone?
+把所有人消音?
<usetemplate ignoretext="在我å°æ‰€æœ‰ç¾¤çµ„通話的åƒèˆ‡è€…予以éœéŸ³å‰ç¢ºèª" name="okcancelignore" notext="å–消" yestext="確定"/>
</notification>
<notification label="èŠå¤©" name="HintChat">
- To join the conversation, type into the chat field below.
+ è‹¥è¦åŠ å…¥å°è©±ï¼Œè«‹åœ¨ä¸‹æ–¹çš„èŠå¤©æ¬„裡打字。
</notification>
- <notification label="Stand" name="HintSit">
- To stand up and exit the sitting position, click the Stand button.
+ <notification label="站立" name="HintSit">
+ è‹¥è¦ä¸­æ­¢å姿站起身來,請按「站立ã€æŒ‰éˆ•ã€‚
</notification>
- <notification label="Speak" name="HintSpeak">
- Click the Speak button to turn your microphone on and off.
+ <notification label="說話" name="HintSpeak">
+ 點按「說話ã€æŒ‰éˆ•ä¾†æ‰“開或關閉麥克風。
-Click on the up arrow to see the voice control panel.
+點按å‘上箭頭éµï¼Œå¯é¡¯ç¤ºè²éŸ³æŽ§åˆ¶é¢æ¿ã€‚
-Hiding the Speak button will disable the voice feature.
+éš±è—「說話ã€æŒ‰éˆ•å°‡åœç”¨èªžéŸ³åŠŸèƒ½ã€‚
</notification>
<notification label="探索世界" name="HintDestinationGuide">
- The Destination Guide contains thousands of new places to discover. Select a location and choose Teleport to start exploring.
+ 目的地指å—包å«ä¸Šåƒå€‹å€¼å¾—探索的新地點。 é¸æ“‡ä¸€å€‹åœ°é»žï¼Œç„¶å¾Œã€Œçž¬é–“傳é€ã€å‰å¾€ï¼Œé–‹å§‹ä½ çš„探索ï¼
</notification>
<notification label="å´é‚Šæ¬„" name="HintSidePanel">
- Get quick access to your inventory, outfits, profiles and more in the side panel.
+ ä½ å¯ä»¥å¾žå´é‚Šæ¬„進入收ç´å€ã€è£æ‰®ã€å€‹äººæª”案等,方便åˆè¿…速。
</notification>
<notification label="移動" name="HintMove">
- To walk or run, open the Move Panel and use the directional arrows to navigate. You can also use the directional keys on your keyboard.
+ 若想行走或跑步,請打開「移動ã€é¢æ¿ï¼Œä½¿ç”¨æ–¹å‘箭頭來移動。 也å¯ä»¥ä½¿ç”¨éµç›¤ä¸Šçš„æ–¹å‘éµã€‚
</notification>
<notification label="" name="HintMoveClick">
- 1. Click to Walk
-Click anywhere on the ground to walk to that spot.
+ 1. 點按一下就å¯è¡Œèµ°
+點按地é¢ä¸Šä»»ä½•ä¸€é»žï¼Œå°±å¯ä»¥èµ°åˆ°é‚£è£¡ã€‚
-2. Click and Drag to Rotate View
-Click and drag anywhere on the world to rotate your view
+2. 按ä½ä¸¦æ‹–曳,å¯ä»¥æ—‹è½‰è¦–野
+在虛擬世界裡按ä½ä¸¦æ‹–曳任何一點,就å¯æ—‹è½‰ä½ çš„視野
</notification>
<notification label="顯示å稱" name="HintDisplayName">
- Set your customizable display name here. This is in addition to your unique username, which can&apos;t be changed. You can change how you see other people&apos;s names in your preferences.
+ 在這裡自訂你的顯示å稱。 顯示å稱和使用者å稱有別,後者ç¨ä¸€ç„¡äºŒè€Œä¸”ä¸èƒ½è®Šæ›´ã€‚ ä½ å¯ä»¥åœ¨å好設定裡,變更è¦å¦‚何察看別人的å稱。
</notification>
- <notification label="View" name="HintView">
- To change your camera view, use the Orbit and Pan controls. Reset your view by pressing Escape or walking.
+ <notification label="視角" name="HintView">
+ è¦æ”¹è®Šæ”影機視角,請用「環繞ã€å’Œã€Œå¹³ç§»ã€æŽ§åˆ¶ã€‚ 按 Escape éµï¼Œæˆ–走動一下,便å¯é‡è¨­ä½ çš„視野。
</notification>
<notification label="收ç´å€" name="HintInventory">
- Check your inventory to find items. Newest items can be easily found in the Recent tab.
+ 到收ç´å€æ‰¾å°‹ç‰©é …。 在「新近ã€é ç±¤è£¡å¯ç«‹åˆ»çœ‹åˆ°æ–°è¿‘的物項。
</notification>
<notification label="你得到林登幣!" name="HintLindenDollar">
- Here&apos;s your current balance of L$. Click Buy L$ to purchase more Linden Dollars.
+ 這裡顯示你目å‰çš„ L$ 餘é¡ã€‚ 點按「購買 L$ã€å¯æ·»è³¼æž—登幣。
+ </notification>
+ <notification name="LowMemory">
+ ä½ çš„å¯ç”¨è¨˜æ†¶é«”很å°ã€‚ 第二人生部分功能將åœç”¨ï¼Œä»¥å…當機。 請關閉其他應用程å¼ã€‚ 這狀æ³è‹¥æŒçºŒï¼Œè«‹é‡å•Ÿç¬¬äºŒäººç”Ÿã€‚
+ </notification>
+ <notification name="ForceQuitDueToLowMemory">
+ 記憶體ä¸è¶³ï¼Œç¬¬äºŒäººç”Ÿå°‡æ–¼ 30 秒後關閉離開。
</notification>
<notification name="PopupAttempt">
一個çªé¡¯å¼è¦–窗開啟時被阻擋。
@@ -2881,54 +3182,171 @@ Click and drag anywhere on the world to rotate your view
<button name="open" text="é–‹å•Ÿçªé¡¯å¼è¦–窗"/>
</form>
</notification>
+ <notification name="SOCKS_NOT_PERMITTED">
+ SOCKS 5 代ç†ä¼ºæœå™¨ &quot;[HOST]:[PORT]&quot; 拒絕連通,è¦å‰‡é›†ä¸å…許。
+ <usetemplate name="okbutton" yestext="確定"/>
+ </notification>
+ <notification name="SOCKS_CONNECT_ERROR">
+ SOCKS 5 代ç†ä¼ºæœå™¨ &quot;[HOST]:[PORT]&quot; 拒絕連通,無法打開 TCP é »é“。
+ <usetemplate name="okbutton" yestext="確定"/>
+ </notification>
+ <notification name="SOCKS_NOT_ACCEPTABLE">
+ SOCKS 5 代ç†ä¼ºæœå™¨ &quot;[HOST]:[PORT]&quot; 拒絕所é¸çš„é‘’èªæ–¹æ³•ã€‚
+ <usetemplate name="okbutton" yestext="確定"/>
+ </notification>
+ <notification name="SOCKS_AUTH_FAIL">
+ SOCKS 5 代ç†ä¼ºæœå™¨ &quot;[HOST]:[PORT]&quot; 回報:你的鑒èªè³‡æ–™ç„¡æ•ˆã€‚
+ <usetemplate name="okbutton" yestext="確定"/>
+ </notification>
+ <notification name="SOCKS_UDP_FWD_NOT_GRANTED">
+ SOCKS 5 代ç†ä¼ºæœå™¨ &quot;[HOST]:[PORT]&quot; 拒絕 UDP è¯çµè«‹æ±‚。
+ <usetemplate name="okbutton" yestext="確定"/>
+ </notification>
+ <notification name="SOCKS_HOST_CONNECT_FAILED">
+ 無法連通 SOCKS 5 代ç†ä¼ºæœå™¨ &quot;[HOST]:[PORT]&quot;。
+ <usetemplate name="okbutton" yestext="確定"/>
+ </notification>
+ <notification name="SOCKS_UNKNOWN_STATUS">
+ 伺æœå™¨ &quot;[HOST]:[PORT]&quot; 發生ä¸æ˜Žçš„代ç†ä¼ºæœå™¨éŒ¯èª¤ã€‚
+ <usetemplate name="okbutton" yestext="確定"/>
+ </notification>
+ <notification name="SOCKS_INVALID_HOST">
+ 無效的 SOCKS 代ç†ä¼ºæœå™¨ä½å€æˆ–埠號 &quot;[HOST]:[PORT]&quot;。
+ <usetemplate name="okbutton" yestext="確定"/>
+ </notification>
+ <notification name="SOCKS_BAD_CREDS">
+ 無效的 SOCKS 5 使用者å稱或密碼。
+ <usetemplate name="okbutton" yestext="確定"/>
+ </notification>
+ <notification name="PROXY_INVALID_HTTP_HOST">
+ 無效的 HTTP 代ç†ä¼ºæœå™¨ä½å€æˆ–埠號 &quot;[HOST]:[PORT]&quot;。
+ <usetemplate name="okbutton" yestext="確定"/>
+ </notification>
+ <notification name="PROXY_INVALID_SOCKS_HOST">
+ 無效的 SOCKS 代ç†ä¼ºæœå™¨ä½å€æˆ–埠號 &quot;[HOST]:[PORT]&quot;。
+ <usetemplate name="okbutton" yestext="確定"/>
+ </notification>
+ <notification name="ChangeProxySettings">
+ é‡æ–°å•Ÿå‹• [APP_NAME] 後將採用新的代ç†ä¼ºæœå™¨è¨­å®šã€‚
+ <usetemplate name="okbutton" yestext="確定"/>
+ </notification>
<notification name="AuthRequest">
- The site at &apos;&lt;nolink&gt;[HOST_NAME]&lt;/nolink&gt;&apos; in realm &apos;[REALM]&apos; requires a user name and password.
+ &apos;[REALM]&apos; 領域的 &apos;&lt;nolink&gt;[HOST_NAME]&lt;/nolink&gt;&apos; 站點需è¦ä½¿ç”¨è€…å稱和密碼。
<form name="form">
- <input name="username" text="User Name"/>
- <input name="password" text="Password"/>
- <button name="ok" text="Submit"/>
+ <input name="username" text="使用者å稱"/>
+ <input name="password" text="密碼"/>
+ <button name="ok" text="æ交"/>
<button name="cancel" text="å–消"/>
</form>
</notification>
- <notification label="" name="ModeChange">
- 改變劉覽器模å¼è¦æ±‚ä½ å¿…é ˆçµæŸé€€å‡ºä¸¦é‡æ–°å•Ÿå‹•ã€‚
- <usetemplate name="okcancelbuttons" notext="ä¸è¦çµæŸé€€å‡º" yestext="çµæŸé€€å‡º"/>
- </notification>
<notification label="" name="NoClassifieds">
- Creation and editing of Classifieds is only available in Advanced mode. Would you like to quit and change modes? The mode selector can be found on the login screen.
+ åªæœ‰é€²éšŽæ¨¡å¼æ‰èƒ½æ–°å»ºæˆ–編輯個人廣告。 你是å¦æƒ³è¦çµæŸé›¢é–‹ï¼Œä»¥ä¾¿è®Šæ›´æ¨¡å¼ï¼Ÿ ä½ å¯åœ¨ç™»å…¥ç•«é¢é¸æ“‡æƒ³è¦çš„模å¼ã€‚
<usetemplate name="okcancelbuttons" notext="ä¸è¦çµæŸé€€å‡º" yestext="çµæŸé€€å‡º"/>
</notification>
<notification label="" name="NoGroupInfo">
- Creation and editing of Groups is only available in Advanced mode. Would you like to quit and change modes? The mode selector can be found on the login screen.
+ åªæœ‰é€²éšŽæ¨¡å¼æ‰èƒ½æ–°å»ºæˆ–編輯群組。 你是å¦æƒ³è¦çµæŸé›¢é–‹ï¼Œä»¥ä¾¿è®Šæ›´æ¨¡å¼ï¼Ÿ ä½ å¯åœ¨ç™»å…¥ç•«é¢é¸æ“‡æƒ³è¦çš„模å¼ã€‚
+ <usetemplate name="okcancelbuttons" notext="ä¸è¦çµæŸé€€å‡º" yestext="çµæŸé€€å‡º"/>
+ </notification>
+ <notification label="" name="NoPlaceInfo">
+ åªæœ‰é€²éšŽæ¨¡å¼æ‰èƒ½å¯Ÿçœ‹åœ°é»žæª”案。 你是å¦æƒ³è¦çµæŸé›¢é–‹ï¼Œä»¥ä¾¿è®Šæ›´æ¨¡å¼ï¼Ÿ ä½ å¯åœ¨ç™»å…¥ç•«é¢é¸æ“‡æƒ³è¦çš„模å¼ã€‚
<usetemplate name="okcancelbuttons" notext="ä¸è¦çµæŸé€€å‡º" yestext="çµæŸé€€å‡º"/>
</notification>
<notification label="" name="NoPicks">
- Creation and editing of Picks is only available in Advanced mode. Would you like to quit and change modes? The mode selector can be found on the login screen.
+ åªæœ‰é€²éšŽæ¨¡å¼æ‰èƒ½æ–°å»ºæˆ–編輯精é¸åœ°é»žã€‚ 你是å¦æƒ³è¦çµæŸé›¢é–‹ï¼Œä»¥ä¾¿è®Šæ›´æ¨¡å¼ï¼Ÿ ä½ å¯åœ¨ç™»å…¥ç•«é¢é¸æ“‡æƒ³è¦çš„模å¼ã€‚
<usetemplate name="okcancelbuttons" notext="ä¸è¦çµæŸé€€å‡º" yestext="çµæŸé€€å‡º"/>
</notification>
<notification label="" name="NoWorldMap">
- Viewing of the world map is only available in Advanced mode. Would you like to quit and change modes? The mode selector can be found on the login screen.
+ åªæœ‰é€²éšŽæ¨¡å¼æ‰èƒ½å¯Ÿçœ‹ä¸–界地圖。 你是å¦æƒ³è¦çµæŸé›¢é–‹ï¼Œä»¥ä¾¿è®Šæ›´æ¨¡å¼ï¼Ÿ ä½ å¯åœ¨ç™»å…¥ç•«é¢é¸æ“‡æƒ³è¦çš„模å¼ã€‚
<usetemplate name="okcancelbuttons" notext="ä¸è¦çµæŸé€€å‡º" yestext="çµæŸé€€å‡º"/>
</notification>
<notification label="" name="NoVoiceCall">
- Voice calls are only available in Advanced mode. Would you like to logout and change modes?
+ åªæœ‰é€²éšŽæ¨¡å¼æ‰èƒ½ä½¿ç”¨èªžéŸ³é€šè©±ã€‚ 你是å¦è¦ç™»å‡ºä¸¦ä¸”變更模å¼ï¼Ÿ
<usetemplate name="okcancelbuttons" notext="ä¸è¦çµæŸé€€å‡º" yestext="çµæŸé€€å‡º"/>
</notification>
<notification label="" name="NoAvatarShare">
- Sharing is only available in Advanced mode. Would you like to logout and change modes?
+ åªæœ‰é€²éšŽæ¨¡å¼æ‰èƒ½ä½¿ç”¨åˆ†äº«åŠŸèƒ½ã€‚ 你是å¦è¦ç™»å‡ºä¸¦ä¸”變更模å¼ï¼Ÿ
<usetemplate name="okcancelbuttons" notext="ä¸è¦çµæŸé€€å‡º" yestext="çµæŸé€€å‡º"/>
</notification>
<notification label="" name="NoAvatarPay">
- Paying other residents is only available in Advanced mode. Would you like to logout and change modes?
+ åªæœ‰é€²éšŽæ¨¡å¼æ‰èƒ½ä»˜è²»çµ¦å…¶ä»–居民。 你是å¦è¦ç™»å‡ºä¸¦ä¸”變更模å¼ï¼Ÿ
<usetemplate name="okcancelbuttons" notext="ä¸è¦çµæŸé€€å‡º" yestext="çµæŸé€€å‡º"/>
</notification>
- <global name="UnsupportedCPU">
- - ä½ çš„ CPU é‹ç®—速度未é”到系統最低é…å‚™è¦æ±‚。
- </global>
+ <notification label="" name="NoInventory">
+ åªæœ‰é€²éšŽæ¨¡å¼æ‰èƒ½å¯Ÿçœ‹æ”¶ç´å€ã€‚ 你是å¦è¦ç™»å‡ºä¸¦ä¸”變更模å¼ï¼Ÿ
+ <usetemplate name="okcancelbuttons" notext="ä¸è¦çµæŸé€€å‡º" yestext="çµæŸé€€å‡º"/>
+ </notification>
+ <notification label="" name="NoAppearance">
+ åªæœ‰é€²éšŽæ¨¡å¼æ‰èƒ½ä½¿ç”¨å¤–觀編輯器。 你是å¦è¦ç™»å‡ºä¸¦ä¸”變更模å¼ï¼Ÿ
+ <usetemplate name="okcancelbuttons" notext="ä¸è¦çµæŸé€€å‡º" yestext="çµæŸé€€å‡º"/>
+ </notification>
+ <notification label="" name="NoSearch">
+ åªæœ‰é€²éšŽæ¨¡å¼æ‰èƒ½æœå°‹ã€‚ 你是å¦è¦ç™»å‡ºä¸¦ä¸”變更模å¼ï¼Ÿ
+ <usetemplate name="okcancelbuttons" notext="ä¸è¦çµæŸé€€å‡º" yestext="çµæŸé€€å‡º"/>
+ </notification>
+ <notification label="" name="ConfirmHideUI">
+ 這將會隱è—所有é¸å–®å…§å®¹å’ŒæŒ‰éˆ•ã€‚ è¦æ¢å¾©åŽŸç‹€ï¼Œå†é»žæŒ‰ [SHORTCUT] 一次。
+ <usetemplate ignoretext="éš±è—使用者介é¢å‰å…ˆç¢ºèª" name="okcancelignore" notext="å–消" yestext="確定"/>
+ </notification>
+ <notification name="PathfindingLinksets_WarnOnPhantom">
+ 所é¸çš„一些è¯çµé›†çš„幻影旗標將被切æ›ã€‚
+
+你確定è¦ç¹¼çºŒå—Žï¼Ÿ
+ <usetemplate ignoretext="所é¸çš„一些è¯çµé›†çš„幻影旗標將被切æ›ã€‚" name="okcancelignore" notext="å–消" yestext="確定"/>
+ </notification>
+ <notification name="PathfindingLinksets_MismatchOnRestricted">
+ 所é¸æŸäº›è¯çµé›†å› æ¬Šé™å•é¡Œï¼Œç„¡æ³•è¨­å®šç‚º &apos;[REQUESTED_TYPE]&apos;。 這些è¯çµé›†å°‡è¢«è¨­ç‚º &apos;[RESTRICTED_TYPE]&apos;。
+
+你確定è¦ç¹¼çºŒå—Žï¼Ÿ
+ <usetemplate ignoretext="所é¸æŸäº›è¯çµé›†å› æ¬Šé™å•é¡Œï¼Œç„¡æ³•è¨­å®šã€‚" name="okcancelignore" notext="å–消" yestext="確定"/>
+ </notification>
+ <notification name="PathfindingLinksets_MismatchOnVolume">
+ 所é¸æŸäº›è¯çµé›†ç„¡æ³•è¨­ç‚º &apos;[REQUESTED_TYPE]&apos;,因為形狀屬於éžå‡¸é¢ã€‚
+
+你確定è¦ç¹¼çºŒå—Žï¼Ÿ
+ <usetemplate ignoretext="所é¸æŸäº›è¯çµé›†å› ç‚ºå½¢ç‹€å±¬æ–¼éžå‡¸é¢ï¼Œç„¡æ³•è¨­å®š" name="okcancelignore" notext="å–消" yestext="確定"/>
+ </notification>
+ <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnRestricted">
+ 所é¸çš„一些è¯çµé›†çš„幻影旗標將被切æ›ã€‚
+
+所é¸æŸäº›è¯çµé›†å› æ¬Šé™å•é¡Œï¼Œç„¡æ³•è¨­å®šç‚º &apos;[REQUESTED_TYPE]&apos;。 這些è¯çµé›†å°‡è¢«è¨­ç‚º &apos;[RESTRICTED_TYPE]&apos;。
+
+你確定è¦ç¹¼çºŒå—Žï¼Ÿ
+ <usetemplate ignoretext="所é¸çš„一些è¯çµé›†çš„幻影旗標å¯æˆåŠŸåˆ‡æ›ï¼Œå…¶ä»–的則因權é™å•é¡Œè€Œç„¡æ³•è¨­å®šã€‚" name="okcancelignore" notext="å–消" yestext="確定"/>
+ </notification>
+ <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnVolume">
+ 所é¸çš„一些è¯çµé›†çš„幻影旗標將被切æ›ã€‚
+
+所é¸æŸäº›è¯çµé›†ç„¡æ³•è¨­ç‚º &apos;[REQUESTED_TYPE]&apos;,因為形狀屬於éžå‡¸é¢ã€‚
+
+你確定è¦ç¹¼çºŒå—Žï¼Ÿ
+ <usetemplate ignoretext="所é¸çš„一些è¯çµé›†çš„幻影旗標å¯æˆåŠŸåˆ‡æ›ï¼Œå…¶ä»–的則因形狀屬於éžå‡¸é¢è€Œç„¡æ³•è¨­å®š" name="okcancelignore" notext="å–消" yestext="確定"/>
+ </notification>
+ <notification name="PathfindingLinksets_MismatchOnRestricted_MismatchOnVolume">
+ 所é¸æŸäº›è¯çµé›†å› æ¬Šé™å•é¡Œï¼Œç„¡æ³•è¨­å®šç‚º &apos;[REQUESTED_TYPE]&apos;。 這些è¯çµé›†å°‡è¢«è¨­ç‚º &apos;[RESTRICTED_TYPE]&apos;。
+
+所é¸æŸäº›è¯çµé›†ç„¡æ³•è¨­ç‚º &apos;[REQUESTED_TYPE]&apos;,因為形狀屬於éžå‡¸é¢ã€‚ 這些è¯çµé›†çš„使用類型將維æŒä¸è®Šã€‚
+
+你確定è¦ç¹¼çºŒå—Žï¼Ÿ
+ <usetemplate ignoretext="所é¸æŸäº›è¯çµé›†å› æ¬Šé™ä¸è¶³ï¼Œä¸”形狀屬於éžå‡¸é¢ï¼Œå› æ­¤ç„¡æ³•è¨­å®šã€‚" name="okcancelignore" notext="å–消" yestext="確定"/>
+ </notification>
+ <notification name="PathfindingLinksets_WarnOnPhantom_MismatchOnRestricted_MismatchOnVolume">
+ 所é¸çš„一些è¯çµé›†çš„幻影旗標將被切æ›ã€‚
+
+所é¸æŸäº›è¯çµé›†å› æ¬Šé™å•é¡Œï¼Œç„¡æ³•è¨­å®šç‚º &apos;[REQUESTED_TYPE]&apos;。 這些è¯çµé›†å°‡è¢«è¨­ç‚º &apos;[RESTRICTED_TYPE]&apos;。
+
+所é¸æŸäº›è¯çµé›†ç„¡æ³•è¨­ç‚º &apos;[REQUESTED_TYPE]&apos;,因為形狀屬於éžå‡¸é¢ã€‚ 這些è¯çµé›†çš„使用類型將維æŒä¸è®Šã€‚
+
+你確定è¦ç¹¼çºŒå—Žï¼Ÿ
+ <usetemplate ignoretext="所é¸çš„一些è¯çµé›†çš„幻影旗標將被切æ›ï¼Œå…¶ä»–則因權é™ä¸è¶³ä¸”形狀屬於éžå‡¸é¢ï¼Œå› æ­¤ç„¡æ³•è¨­å®šã€‚" name="okcancelignore" notext="å–消" yestext="確定"/>
+ </notification>
+ <notification name="PathfindingLinksets_ChangeToFlexiblePath">
+ 所é¸çš„物件會影響導航網é¢ã€‚ 將它改為彈性路徑,將使它從導航網é¢ä¸­è¢«ç§»é™¤ã€‚
+ <usetemplate ignoretext="所é¸çš„物件會影響導航網é¢ã€‚ 將它改為彈性路徑,將使它從導航網é¢ä¸­è¢«ç§»é™¤ã€‚" name="okcancelignore" notext="å–消" yestext="確定"/>
+ </notification>
<global name="UnsupportedGLRequirements">
- You do not appear to have the proper hardware requirements for [APP_NAME]. [APP_NAME] requires an OpenGL graphics card that has multitexture support. If this is the case, you may want to make sure that you have the latest drivers for your graphics card, and service packs and patches for your operating system.
+ 你的硬體設備似乎ä¸ç¬¦ [APP_NAME] çš„è¦æ±‚。 [APP_NAME] 需è¦å¯ä»¥æ”¯æ´å¤šæ質的 OpenGL 顯åƒå¡ã€‚ 在這狀æ³ä¸‹ï¼Œè«‹ç¢ºå®šä½ çš„顯åƒå¡å®‰è£äº†æœ€æ–°çš„驅動程å¼ï¼Œä½œæ¥­ç³»çµ±ä¹Ÿå®‰è£äº†æœ€æ–°çš„æœå‹™åŒ…和嵌補程å¼ã€‚
-If you continue to have problems, please visit the [SUPPORT_SITE].
+如果你繼續é‡åˆ°å•é¡Œï¼Œè«‹å‰å¾€ [SUPPORT_SITE] 求助。
</global>
<global name="UnsupportedCPUAmount">
796
@@ -2944,9 +3362,658 @@ If you continue to have problems, please visit the [SUPPORT_SITE].
</global>
<global name="You can only set your &apos;Home Location&apos; on your land or at a mainland Infohub.">
若你æ“有一塊土地,你å¯ä»¥æ¨™è¨˜å®ƒæˆç‚ºä½ çš„家的ä½ç½®ã€‚
-或者,你å¯ä»¥å¯Ÿçœ‹åœ°åœ–尋找標記為 &quot;資訊中心&quot; 的地方。
+或者,你å¯ä»¥å¯Ÿçœ‹åœ°åœ–,尋找標記為「資訊中心ã€çš„地方。
</global>
<global name="You died and have been teleported to your home location">
你已經死亡並且被瞬間傳é€å›žä½ çš„家的ä½ç½®ã€‚
</global>
+ <notification name="LocalBitmapsUpdateFileNotFound">
+ [FNAME] 無法更新,找ä¸åˆ°è©²æª”案。
+未來將ä¸å†æ›´æ–°è©²æª”案。
+ </notification>
+ <notification name="LocalBitmapsUpdateFailedFinal">
+ [FNAME] 無法開啟或解碼,已嘗試 [NRETRIES] 次,該檔案已被èªå®šç‚ºæ¯€å£žã€‚
+未來將ä¸å†æ›´æ–°è©²æª”案。
+ </notification>
+ <notification name="LocalBitmapsVerifyFail">
+ 試圖新增一個無效或無法讀å–的圖åƒæª” [FNAME],該檔無法開啟或解碼。
+å·²å–消這一嘗試。
+ </notification>
+ <notification name="PathfindingReturnMultipleItems">
+ 你正退回 [NUM_ITEMS] 個物項。 你確定你è¦ç¹¼çºŒï¼Ÿ
+ <usetemplate ignoretext="確定退回多個物項?" name="okcancelignore" notext="å¦" yestext="是"/>
+ </notification>
+ <notification name="PathfindingDeleteMultipleItems">
+ 你正在刪除 [NUM_ITEMS] 個物項。 你確定你è¦ç¹¼çºŒï¼Ÿ
+ <usetemplate ignoretext="確定è¦åˆªé™¤å¤šå€‹ç‰©é …?" name="okcancelignore" notext="å¦" yestext="是"/>
+ </notification>
+ <notification name="AvatarFrozen">
+ [AV_FREEZER] å‡çµäº†ä½ ã€‚ 你此時無法移動或與周é­äº’動。
+ </notification>
+ <notification name="AvatarFrozenDuration">
+ [AV_FREEZER] å‡çµäº†ä½  [AV_FREEZE_TIME] 秒é˜ã€‚ 你此時無法移動或與周é­äº’動。
+ </notification>
+ <notification name="YouFrozeAvatar">
+ 化身已å‡çµã€‚
+ </notification>
+ <notification name="AvatarHasUnFrozenYou">
+ [AV_FREEZER] 解除了å°ä½ çš„å‡çµã€‚
+ </notification>
+ <notification name="AvatarUnFrozen">
+ 化身已解除å‡çµã€‚
+ </notification>
+ <notification name="AvatarFreezeFailure">
+ å‡çµå¤±æ•—,因為你在該地段沒有管ç†å“¡æ¬Šé™ã€‚
+ </notification>
+ <notification name="AvatarFreezeThaw">
+ ä½ é­å‡çµçš„時間已éŽï¼Œè«‹æ¢å¾©æ­£å¸¸æ´»å‹•ã€‚
+ </notification>
+ <notification name="AvatarCantFreeze">
+ 抱歉,無法å‡çµè©²ç”¨æˆ¶ã€‚
+ </notification>
+ <notification name="NowOwnObject">
+ ä½ ç¾åœ¨æ˜¯ç‰©ä»¶ [OBJECT_NAME] 的所有人
+ </notification>
+ <notification name="CantRezOnLand">
+ 無法在 [OBJECT_POS] 產生物件,因為這土地的所有人ä¸å…許。 請用土地工具察看所有人。
+ </notification>
+ <notification name="RezFailTooManyRequests">
+ 無法產生物件,此刻è¦æ±‚數目éŽå¤šã€‚
+ </notification>
+ <notification name="SitFailCantMove">
+ 你無法å下,因為此刻你ä¸èƒ½ç§»å‹•ã€‚
+ </notification>
+ <notification name="SitFailNotAllowedOnLand">
+ ä½ ä¸èƒ½å下,因為該土地ä¸å…許。
+ </notification>
+ <notification name="SitFailNotSameRegion">
+ 請挨近一點。 無法å在物件上,因為
+它和你ä¸åœ¨åŒä¸€å€‹åœ°å€ã€‚
+ </notification>
+ <notification name="NoNewObjectRegionFull">
+ 無法建立新物件。 地å€å·²æ»¿è¼‰ã€‚
+ </notification>
+ <notification name="FailedToPlaceObject">
+ 無法將物件置於指定地點。 è«‹å†è©¦ä¸€æ¬¡ã€‚
+ </notification>
+ <notification name="NoOwnNoGardening">
+ 你無法在別人的土地上建立樹和è‰ã€‚
+ </notification>
+ <notification name="NoCopyPermsNoObject">
+ 複製失敗,你無權複製物件 &apos;[OBJ_NAME]&apos;。
+ </notification>
+ <notification name="NoTransPermsNoObject">
+ 複製失敗,因為物件 &apos;[OBJ_NAME]&apos; 無法轉移給你。
+ </notification>
+ <notification name="AddToNavMeshNoCopy">
+ 複製失敗,因為物件 &apos;[OBJ_NAME]&apos; å°å°Žèˆªç¶²é¢æœ‰è²¢ç»ã€‚
+ </notification>
+ <notification name="DupeWithNoRootsSelected">
+ é¸å–了沒有根的é‡è¦†ç‰©ä»¶ã€‚
+ </notification>
+ <notification name="CantDupeCuzRegionIsFull">
+ 無法複製物件,因為地å€æ»¿è¼‰ã€‚
+ </notification>
+ <notification name="CantDupeCuzParcelNotFound">
+ 無法複製物件,找ä¸åˆ°å®ƒå€‘所在的地段。
+ </notification>
+ <notification name="CantCreateCuzParcelFull">
+ 無法建立物件,因為
+地段滿載。
+ </notification>
+ <notification name="RezAttemptFailed">
+ 試圖產生物件失敗。
+ </notification>
+ <notification name="ToxicInvRezAttemptFailed">
+ 無法建立已在此地å€é€ æˆå•é¡Œçš„物件。
+ </notification>
+ <notification name="InvItemIsBlacklisted">
+ 該收ç´å€ç‰©é …已被列入黑å單。
+ </notification>
+ <notification name="NoCanRezObjects">
+ 你此時無權建立物件。
+ </notification>
+ <notification name="LandSearchBlocked">
+ 土地æœå°‹é­ç¦ã€‚
+你在短時間內進行了太多次土地æœå°‹ã€‚
+è«‹ç¨å€™å†è©¦ã€‚
+ </notification>
+ <notification name="NotEnoughResourcesToAttach">
+ 腳本資æºä¸è¶³ï¼Œç„¡æ³•é™„著物件ï¼
+ </notification>
+ <notification name="YouDiedAndGotTPHome">
+ 你已經死亡並且被瞬間傳é€å›žä½ çš„家的ä½ç½®
+ </notification>
+ <notification name="EjectComingSoon">
+ ä½ ä¸å†å…許待在這裡,必須在 [EJECT_TIME] 秒內離開。
+ </notification>
+ <notification name="NoEnterServerFull">
+ 你無法進入這地å€ï¼Œå› ç‚º
+伺æœå™¨æ»¿è¼‰ã€‚
+ </notification>
+ <notification name="SaveBackToInvDisabled">
+ 「儲存回收ç´å€ã€åŠŸèƒ½å·²è¢«åœç”¨ã€‚
+ </notification>
+ <notification name="NoExistNoSaveToContents">
+ 無法將 &apos;[OBJ_NAME]&apos; 儲存到物件內容,因為產生它的來æºç‰©ä»¶å·²ä¸å­˜åœ¨ã€‚
+ </notification>
+ <notification name="NoModNoSaveToContents">
+ 無法儲存 [OBJ_NAME] 到物件內容,你無權修改 &apos;[DEST_NAME]&apos; 物件。
+ </notification>
+ <notification name="NoSaveBackToInvDisabled">
+ 無法將 &apos;[OBJ_NAME]&apos; 儲存回收ç´å€ï¼Œæ­¤å‹•ä½œå·²è¢«åœç”¨ã€‚
+ </notification>
+ <notification name="NoCopyNoSelCopy">
+ 無法複製你所é¸çš„,因為你無權複製物件 &apos;[OBJ_NAME]&apos;。
+ </notification>
+ <notification name="NoTransNoSelCopy">
+ 無法é¸å–複製,因為物件 &apos;[OBJ_NAME]&apos; ä¸å¯è½‰ç§»ã€‚
+ </notification>
+ <notification name="NoTransNoCopy">
+ 無法é¸å–複製,因為物件 &apos;[OBJ_NAME]&apos; ä¸å¯è½‰ç§»ã€‚
+ </notification>
+ <notification name="NoPermsNoRemoval">
+ 權é™ç³»çµ±ä¸å…許從模擬器移除物件 &apos;[OBJ_NAME]&apos;。
+ </notification>
+ <notification name="NoModNoSaveSelection">
+ 無法儲存你所é¸çš„,因為你無權修改 &apos;[OBJ_NAME]&apos; 物件。
+ </notification>
+ <notification name="NoCopyNoSaveSelection">
+ 無法儲存你所é¸çš„,因為物件 &apos;[OBJ_NAME]&apos; ä¸å¯è¤‡è£½ã€‚
+ </notification>
+ <notification name="NoModNoTaking">
+ 無法拿å–你所é¸çš„,因為你無權修改 &apos;[OBJ_NAME]&apos; 物件。
+ </notification>
+ <notification name="RezDestInternalError">
+ 內部錯誤:未知的目的地類型。
+ </notification>
+ <notification name="DeleteFailObjNotFound">
+ 刪除失敗,因為找ä¸åˆ°ç‰©ä»¶
+ </notification>
+ <notification name="SorryCantEjectUser">
+ 抱歉,無法踢出該用戶。
+ </notification>
+ <notification name="RegionSezNotAHome">
+ 此地å€ä¸è¨±ä½ åœ¨æ­¤è¨­å®šã€Œæˆ‘的家ã€ã€‚
+ </notification>
+ <notification name="HomeLocationLimits">
+ ä½ åªèƒ½åœ¨è‡ªå·±çš„土地或大陸資訊中心上設定「我的家ã€ã€‚
+ </notification>
+ <notification name="HomePositionSet">
+ 我的家ä½ç½®å·²å®šã€‚
+ </notification>
+ <notification name="AvatarEjected">
+ 化身已被踢出。
+ </notification>
+ <notification name="AvatarEjectFailed">
+ 踢出失敗,因為你在該地段沒有管ç†å“¡æ¬Šé™ã€‚
+ </notification>
+ <notification name="CantMoveObjectParcelFull">
+ 無法移動 &apos;[OBJECT_NAME]&apos; 物件到
+åœ°å€ [REGION_NAME] çš„ [OBJ_POSITION],因為該目標地段已滿載。
+ </notification>
+ <notification name="CantMoveObjectParcelPerms">
+ 無法移動 &apos;[OBJECT_NAME]&apos; 物件到
+åœ°å€ [REGION_NAME] çš„ [OBJ_POSITION],因為此地段ä¸å…許你的物件。
+ </notification>
+ <notification name="CantMoveObjectParcelResources">
+ 無法移動 &apos;[OBJECT_NAME]&apos; 物件到
+ [REGION_NAME] 地å€çš„ [OBJ_POSITION],因為此地段資æºä¸è¶³å®¹ç´æ­¤ç‰©ä»¶ã€‚
+ </notification>
+ <notification name="CantMoveObjectRegionVersion">
+ 無法移動 &apos;[OBJECT_NAME]&apos; 物件到
+ [REGION_NAME] 地å€çš„ [OBJ_POSITION],因為該地å€æ‰€åŸ·è¡Œçš„軟體版本éŽèˆŠï¼Œä¸æ”¯æ´è·¨åœ°å€æŽ¥å—這個物件。
+ </notification>
+ <notification name="CantMoveObjectNavMesh">
+ 無法移動 &apos;[OBJECT_NAME]&apos; 物件到
+åœ°å€ [REGION_NAME] çš„ [OBJ_POSITION],因為你ä¸å¾—修改跨越地å€ç•Œé™çš„導航網é¢ã€‚
+ </notification>
+ <notification name="CantMoveObjectWTF">
+ 無法移動 &apos;[OBJECT_NAME]&apos; 物件到
+åœ°å€ [REGION_NAME] çš„ [OBJ_POSITION],原因ä¸æ˜Žã€‚ ([FAILURE_TYPE])
+ </notification>
+ <notification name="NoPermModifyObject">
+ 你無權變更該物件
+ </notification>
+ <notification name="CantEnablePhysObjContributesToNav">
+ å°å°Žèˆªç¶²é¢æœ‰è²¢ç»çš„物件,無法啟用物ç†ã€‚
+ </notification>
+ <notification name="CantEnablePhysKeyframedObj">
+ éµæ ¼å‹•ç•«ç‰©ä»¶ç„¡æ³•å•Ÿç”¨ç‰©ç†ã€‚
+ </notification>
+ <notification name="CantEnablePhysNotEnoughLandResources">
+ 無法啟用物件的物ç†â€”—土地資æºä¸è¶³ã€‚
+ </notification>
+ <notification name="CantEnablePhysCostTooGreat">
+ 物件的物ç†è³‡æºæˆæœ¬è¶…éŽ [MAX_OBJECTS],無法啟用物ç†
+ </notification>
+ <notification name="PhantomWithConcavePiece">
+ 此物件ä¸å¾—有凹é¢éƒ¨ä»¶ï¼Œå› ç‚ºç‰©ä»¶æ˜¯å¹»å½±ç‰©ä»¶ï¼Œå°å°Žèˆªç¶²é¢æœ‰è²¢ç»ã€‚
+ </notification>
+ <notification name="UnableAddItem">
+ 無法新增項目ï¼
+ </notification>
+ <notification name="UnableEditItem">
+ 無法編輯這項目ï¼
+ </notification>
+ <notification name="NoPermToEdit">
+ 無權編輯這項目。
+ </notification>
+ <notification name="NoPermToCopyInventory">
+ 無權複製該收ç´å€ã€‚
+ </notification>
+ <notification name="CantSaveItemDoesntExist">
+ 無法儲存到物件內容:該項目已ä¸å­˜åœ¨ã€‚
+ </notification>
+ <notification name="CantSaveItemAlreadyExists">
+ 無法儲存到物件內容:收ç´å€å·²å­˜åœ¨åŒå稱的項目
+ </notification>
+ <notification name="CantSaveModifyAttachment">
+ 無法儲存到物件內容:這麼åšå°‡ä¿®æ”¹é™„件的權é™ã€‚
+ </notification>
+ <notification name="TooManyScripts">
+ 腳本太多。
+ </notification>
+ <notification name="UnableAddScript">
+ 無法新增腳本ï¼
+ </notification>
+ <notification name="AssetServerTimeoutObjReturn">
+ 資產伺æœå™¨æœªåœ¨æ­£å¸¸æ™‚é–“å…§å應。 物件已返交模擬器。
+ </notification>
+ <notification name="RegionDisablePhysicsShapes">
+ 本地å€æœªå•Ÿç”¨ç‰©ç†å½¢ç‹€ã€‚
+ </notification>
+ <notification name="NoModNavmeshAcrossRegions">
+ 你無法變更跨越地å€ç•Œé™çš„導航網é¢ã€‚
+ </notification>
+ <notification name="NoSetPhysicsPropertiesOnObjectType">
+ 該物件類型ä¸å¾—設定物ç†æ€§è³ªã€‚
+ </notification>
+ <notification name="NoSetRootPrimWithNoShape">
+ 根幾何元件無法設æˆç„¡å½¢ç‹€ã€‚
+ </notification>
+ <notification name="NoRegionSupportPhysMats">
+ 本地å€æœªå•Ÿç”¨ç‰©ç†æ料。
+ </notification>
+ <notification name="OnlyRootPrimPhysMats">
+ åªèƒ½èª¿æ•´æ ¹å¹¾ä½•å…ƒä»¶çš„物ç†æ料。
+ </notification>
+ <notification name="NoSupportCharacterPhysMats">
+ å°šä¸æ”¯æ´è§’色設定物ç†æ料。
+ </notification>
+ <notification name="InvalidPhysMatProperty">
+ 指定的物ç†æ料屬性中,至少有一個無效。
+ </notification>
+ <notification name="NoPermsAlterStitchingMeshObj">
+ 網é¢ç‰©ä»¶çš„縫åˆé¡žåž‹ä¸å¾—變更。
+ </notification>
+ <notification name="NoPermsAlterShapeMeshObj">
+ 網é¢ç‰©ä»¶çš„形狀ä¸å¾—變更。
+ </notification>
+ <notification name="FullRegionCantEnter">
+ 你無法進入這地å€ï¼Œ\n因為地å€æ»¿è¼‰ã€‚
+ </notification>
+ <notification name="LinkFailedOwnersDiffer">
+ è¯çµå¤±æ•———所有人ä¸åŒ
+ </notification>
+ <notification name="LinkFailedNoModNavmeshAcrossRegions">
+ è¯çµå¤±æ•———無法修改跨越地å€ç•Œé™çš„導航網é¢ã€‚
+ </notification>
+ <notification name="LinkFailedNoPermToEdit">
+ è¯çµå¤±æ•—,你無權編輯。
+ </notification>
+ <notification name="LinkFailedTooManyPrims">
+ è¯çµå¤±æ•———幾何元件太多
+ </notification>
+ <notification name="LinkFailedCantLinkNoCopyNoTrans">
+ è¯çµå¤±æ•———無法將「ç¦æ­¢è¤‡è£½ã€å’Œã€Œç¦æ­¢è½‰ç§»ã€ç‰©ä»¶è¯çµèµ·ä¾†
+ </notification>
+ <notification name="LinkFailedNothingLinkable">
+ è¯çµå¤±æ•———沒有å¯è¯çµçš„æ±è¥¿ã€‚
+ </notification>
+ <notification name="LinkFailedTooManyPathfindingChars">
+ è¯çµå¤±æ•———尋徑角色太多
+ </notification>
+ <notification name="LinkFailedInsufficientLand">
+ è¯çµå¤±æ•———土地資æºä¸è¶³
+ </notification>
+ <notification name="LinkFailedTooMuchPhysics">
+ 物件使用了éŽå¤šç‰©ç†è³‡æºï¼Œå…¶å‹•æ…‹ç‰¹æ€§å·²è¢«åœç”¨ã€‚
+ </notification>
+ <notification name="TeleportedHomeByObjectOnParcel">
+ 你已被 &apos;[PARCEL_NAME]&apos; 地段的物件 &apos;[OBJECT_NAME]&apos; æˆåŠŸçž¬é–“傳é€å›žå®¶
+ </notification>
+ <notification name="TeleportedHomeByObject">
+ ä½ å·²æˆåŠŸè¢«ç‰©ä»¶ &apos;[OBJECT_NAME]&apos; 瞬間傳é€å›žå®¶
+ </notification>
+ <notification name="TeleportedByAttachment">
+ ä½ å·²æˆåŠŸè¢« [ITEM_ID] 上的一個附件瞬間傳é€
+ </notification>
+ <notification name="TeleportedByObjectOnParcel">
+ ä½ å·²æˆåŠŸè¢« &apos;[PARCEL_NAME]&apos; 地段的物件 &apos;[OBJECT_NAME]&apos; 瞬間傳é€
+ </notification>
+ <notification name="TeleportedByObjectOwnedBy">
+ ä½ å·²æˆåŠŸè¢« [OWNER_ID] æ“有的物件 &apos;[OBJECT_NAME]&apos; 瞬間傳é€
+ </notification>
+ <notification name="TeleportedByObjectUnknownUser">
+ ä½ å·²æˆåŠŸè¢«æŸæœªçŸ¥ç”¨æˆ¶æ“有的物件 &apos;[OBJECT_NAME]&apos; 瞬間傳é€ã€‚
+ </notification>
+ <notification name="CantCreateObjectRegionFull">
+ 無法建立è¦æ±‚的物件。 地å€å·²æ»¿è¼‰ã€‚
+ </notification>
+ <notification name="CantAttackMultipleObjOneSpot">
+ ä½ ä¸èƒ½å°‡å¤šå€‹ç‰©ä»¶é™„著到åŒä¸€å€‹é»žã€‚
+ </notification>
+ <notification name="CantCreateMultipleObjAtLoc">
+ ä½ ä¸èƒ½åœ¨æ­¤å»ºç«‹å¤šå€‹ç‰©ä»¶ã€‚
+ </notification>
+ <notification name="UnableToCreateObjTimeOut">
+ 無法建立è¦æ±‚的物件。 物件在資料庫中找ä¸åˆ°ã€‚
+ </notification>
+ <notification name="UnableToCreateObjUnknown">
+ 無法建立è¦æ±‚的物件。 è¦æ±‚逾時,無法完æˆã€‚ è«‹å†è©¦ä¸€æ¬¡ã€‚
+ </notification>
+ <notification name="UnableToCreateObjMissingFromDB">
+ 無法建立è¦æ±‚的物件。 è«‹å†è©¦ä¸€æ¬¡ã€‚
+ </notification>
+ <notification name="RezFailureTookTooLong">
+ 物件產生失敗,è¦æ±‚的物件載入時間太久。
+ </notification>
+ <notification name="FailedToPlaceObjAtLoc">
+ 無法將物件置於指定地點。 è«‹å†è©¦ä¸€æ¬¡ã€‚
+ </notification>
+ <notification name="CantCreatePlantsOnLand">
+ ä½ ä¸å¾—在這土地上建立æ¤ç‰©ã€‚
+ </notification>
+ <notification name="CantRestoreObjectNoWorldPos">
+ 無法æ¢å¾©ç‰©ä»¶ã€‚ 找ä¸åˆ°è™›æ“¬ä¸–界的ä½ç½®ã€‚
+ </notification>
+ <notification name="CantRezObjectInvalidMeshData">
+ 無法產生物件,它的網é¢è³‡æ–™ç„¡æ•ˆã€‚
+ </notification>
+ <notification name="CantRezObjectTooManyScripts">
+ 無法產生物件,因為這地å€å·²æœ‰å¤ªå¤šçš„腳本。
+ </notification>
+ <notification name="CantCreateObjectNoAccess">
+ 你無權在此建立物件。
+ </notification>
+ <notification name="CantCreateObject">
+ 你此時無權建立物件。
+ </notification>
+ <notification name="InvalidObjectParams">
+ 無效的物件åƒæ•¸
+ </notification>
+ <notification name="CantDuplicateObjectNoAcess">
+ 你權é™ä¸å¤ ï¼Œç„¡æ³•åœ¨æ­¤è¤‡è£½ç‰©ä»¶ã€‚
+ </notification>
+ <notification name="CantChangeShape">
+ 你無權變更這個形狀。
+ </notification>
+ <notification name="NoAccessToClaimObjects">
+ 你權é™ä¸å¤ ï¼Œç„¡æ³•åœ¨æ­¤æ”¶å–物件。
+ </notification>
+ <notification name="DeedFailedNoPermToDeedForGroup">
+ 讓渡失敗,你無權為你的群組讓渡物件。
+ </notification>
+ <notification name="NoPrivsToBuyObject">
+ 你權é™ä¸å¤ ï¼Œç„¡æ³•åœ¨æ­¤è³¼è²·ç‰©ä»¶ã€‚
+ </notification>
+ <notification name="CantAttachObjectAvatarSittingOnIt">
+ 無法附著物件,有個化身正å在物件上。
+ </notification>
+ <notification name="WhyAreYouTryingToWearShrubbery">
+ 樹和è‰ä¸èƒ½ç•¶é™„件穿戴。
+ </notification>
+ <notification name="CantAttachGroupOwnedObjs">
+ 無法附著群組所æ“有的物件。
+ </notification>
+ <notification name="CantAttachObjectsNotOwned">
+ 無法附著ä¸æ˜¯ä½ æ“有的物件。
+ </notification>
+ <notification name="CantAttachNavmeshObjects">
+ 無法附著å°å°Žèˆªç¶²é¢æœ‰è²¢ç»çš„物件。
+ </notification>
+ <notification name="CantAttachObjectNoMovePermissions">
+ 無法附著物件,你無權移動該物件。
+ </notification>
+ <notification name="CantAttachNotEnoughScriptResources">
+ 腳本資æºä¸è¶³ï¼Œç„¡æ³•é™„著物件ï¼
+ </notification>
+ <notification name="CantDropItemTrialUser">
+ 你無法在此å¸é™¤ç‰©ä»¶ï¼Œè«‹åˆ°ã€Œè‡ªç”±å˜—試ã€å€åŸŸå†è©¦ã€‚
+ </notification>
+ <notification name="CantDropMeshAttachment">
+ 你無法在此å¸é™¤é™„件。 è«‹é¸æ“‡æŠŠå¸é™¤é™„件é€å›žæ”¶ç´å€ï¼Œå†é‡æ–°æˆå½¢ã€‚
+ </notification>
+ <notification name="CantDropAttachmentNoPermission">
+ å¸é™¤é™„件失敗:你無權在此處å¸é™¤ã€‚
+ </notification>
+ <notification name="CantDropAttachmentInsufficientLandResources">
+ å¸é™¤é™„件失敗:å¯ç”¨åœŸåœ°è³‡æºä¸è¶³ã€‚
+ </notification>
+ <notification name="CantDropAttachmentInsufficientResources">
+ å¸é™¤é™„件失敗:å¯ç”¨è³‡æºä¸è¶³ã€‚
+ </notification>
+ <notification name="CantDropObjectFullParcel">
+ 無法在此å¸é™¤ç‰©ä»¶ã€‚ 地段滿載。
+ </notification>
+ <notification name="CantTouchObjectBannedFromParcel">
+ 無法觸摸/抓å–此物件,因為你在該土地地段é­ç¦ã€‚
+ </notification>
+ <notification name="PlzNarrowDeleteParams">
+ 請將刪除åƒæ•¸ç¯„åœèª¿å°ä¸€é»žã€‚
+ </notification>
+ <notification name="UnableToUploadAsset">
+ 無法上傳資產。
+ </notification>
+ <notification name="CantTeleportCouldNotFindUser">
+ 找ä¸åˆ°è¦çž¬é–“傳é€åˆ°å®¶çš„用戶
+ </notification>
+ <notification name="GodlikeRequestFailed">
+ è¦æ±‚神的權力失敗
+ </notification>
+ <notification name="GenericRequestFailed">
+ 普通請求失敗
+ </notification>
+ <notification name="CantUploadPostcard">
+ 無法上傳明信片。 è«‹ç¨å€™å†è©¦ä¸€æ¬¡ã€‚
+ </notification>
+ <notification name="CantFetchInventoryForGroupNotice">
+ 無法å–得群組通知的收ç´å€ç´°ç¯€ã€‚
+ </notification>
+ <notification name="CantSendGroupNoticeNotPermitted">
+ 無法é€å‡ºç¾¤çµ„通知——未准許。
+ </notification>
+ <notification name="CantSendGroupNoticeCantConstructInventory">
+ 無法é€å‡ºç¾¤çµ„通知——收ç´å€å»ºç«‹å¤±æ•—。
+ </notification>
+ <notification name="CantParceInventoryInNotice">
+ 無法剖æžé€šçŸ¥è£¡çš„收ç´å“項。
+ </notification>
+ <notification name="TerrainUploadFailed">
+ 地形上傳失敗。
+ </notification>
+ <notification name="TerrainFileWritten">
+ 地形檔案已寫入。
+ </notification>
+ <notification name="TerrainFileWrittenStartingDownload">
+ 地形檔案已寫入,開始下載……
+ </notification>
+ <notification name="TerrainBaked">
+ 地形已定貌。
+ </notification>
+ <notification name="TenObjectsDisabledPlzRefresh">
+ åªæˆåŠŸåœç”¨å‰ 10 個所é¸ç‰©ä»¶ã€‚ 若有需è¦ï¼Œè«‹åˆ·æ–°ä¹‹å¾Œå†é¸å–更多的項目。
+ </notification>
+ <notification name="UpdateViewerBuyParcel">
+ 你必須先更新ç€è¦½å™¨å¾Œï¼Œæ‰å¯è³¼è²·é€™å€‹åœ°æ®µã€‚
+ </notification>
+ <notification name="CantBuyParcelNotForSale">
+ 無法購買,此地段ä¸ä¾›å‡ºå”®ã€‚
+ </notification>
+ <notification name="CantBuySalePriceOrLandAreaChanged">
+ 無法購買,售價或土地é¢ç©å·²è®Šã€‚
+ </notification>
+ <notification name="CantBuyParcelNotAuthorized">
+ ä½ ä¸æ˜¯æ­¤åœ°æ®µçš„ç²æŽˆæ¬Šçš„買主。
+ </notification>
+ <notification name="CantBuyParcelAwaitingPurchaseAuth">
+ 你無法購買此地段,該地段已在等候批准購買
+ </notification>
+ <notification name="CantBuildOverflowParcel">
+ ä½ ä¸å¾—在此建立物件,這麼åšå°‡å°Žè‡´åœ°æ®µè¶…載。
+ </notification>
+ <notification name="SelectedMultipleOwnedLand">
+ ä½ é¸æ“‡çš„土地範åœï¼Œç‚ºä¸åŒäººæ‰€æ“有。 請縮å°é¸æ“‡ç¯„åœï¼Œå†è©¦ä¸€æ¬¡ã€‚
+ </notification>
+ <notification name="CantJoinTooFewLeasedParcels">
+ 未é¸å–足夠租用地段,無法åˆä½µã€‚
+ </notification>
+ <notification name="CantDivideLandMultipleParcelsSelected">
+ 無法分割土地,\n因為你é¸å–了多個地段,\n請縮å°æ‰€é¸åœŸåœ°ã€‚
+ </notification>
+ <notification name="CantDivideLandCantFindParcel">
+ 無法分割土地。\n找ä¸åˆ°åœ°æ®µã€‚\n請到「幫助 &gt; 回報錯誤……ã€å›žå ±å•é¡Œ
+ </notification>
+ <notification name="CantDivideLandWholeParcelSelected">
+ 無法分割土地。 é¸å–了整個地段。\n請試著縮å°æ‰€é¸çš„土地。
+ </notification>
+ <notification name="LandHasBeenDivided">
+ 土地分割æˆåŠŸã€‚
+ </notification>
+ <notification name="PassPurchased">
+ 你購買了通行權。
+ </notification>
+ <notification name="RegionDisallowsClassifieds">
+ 地å€ä¸å…許分類廣告。
+ </notification>
+ <notification name="LandPassExpireSoon">
+ 你在此土地的通行權å³å°‡åˆ°æœŸå¤±æ•ˆã€‚
+ </notification>
+ <notification name="CantSitNoSuitableSurface">
+ 沒有åˆé©çš„表é¢è®“ä½ å下,請試一試別處。
+ </notification>
+ <notification name="CantSitNoRoom">
+ 這裡沒有空間讓你å下,請試試å¦ä¸€è™•ã€‚
+ </notification>
+ <notification name="ClaimObjectFailedNoPermission">
+ 收å–物件失敗,因為你權é™ä¸è¶³ã€‚
+ </notification>
+ <notification name="ClaimObjectFailedNoMoney">
+ 收å–物件失敗,因為你 L$ 金é¡ä¸è¶³ã€‚
+ </notification>
+ <notification name="CantDeedGroupLand">
+ 無法讓渡群組所æ“有的土地。
+ </notification>
+ <notification name="BuyObjectFailedNoMoney">
+ 購買物件失敗,你 L$ 金é¡ä¸è¶³ã€‚
+ </notification>
+ <notification name="BuyInventoryFailedNoMoney">
+ 購買收ç´å€å¤±æ•—,你 L$ 金é¡ä¸è¶³ã€‚
+ </notification>
+ <notification name="BuyPassFailedNoMoney">
+ ä½ çš„ L$ ä¸è¶³ï¼Œç„¡æ³•è³¼è²·æ­¤åœŸåœ°çš„通行權。
+ </notification>
+ <notification name="CantBuyPassTryAgain">
+ 此時無法購買通行權。 è«‹ç¨å€™å†è©¦ä¸€æ¬¡ã€‚
+ </notification>
+ <notification name="CantCreateObjectParcelFull">
+ 無法建立物件,\n地段滿載。
+ </notification>
+ <notification name="FailedPlacingObject">
+ 無法將物件置於指定地點。 è«‹å†è©¦ä¸€æ¬¡ã€‚
+ </notification>
+ <notification name="CantCreateLandmarkForEvent">
+ 無法為活動建立地標。
+ </notification>
+ <notification name="GodBeatsFreeze">
+ ä½ æ“有的神力解除了å‡çµï¼
+ </notification>
+ <notification name="SpecialPowersRequestFailedLogged">
+ è¦æ±‚特殊能力失敗。 該è¦æ±‚已載入記錄。
+ </notification>
+ <notification name="ExpireExplanation">
+ 系統此時無法處ç†ä½ çš„è¦æ±‚。 è¦æ±‚逾時,無法完æˆã€‚
+ </notification>
+ <notification name="DieExplanation">
+ 系統無法處ç†ä½ çš„è¦æ±‚。
+ </notification>
+ <notification name="AddPrimitiveFailure">
+ 金é¡ä¸è¶³ï¼Œç„¡æ³•å»ºç«‹å¹¾ä½•å…ƒä»¶ã€‚
+ </notification>
+ <notification name="RezObjectFailure">
+ 金é¡ä¸è¶³ï¼Œç„¡æ³•å»ºç«‹ç‰©ä»¶ã€‚
+ </notification>
+ <notification name="ResetHomePositionNotLegal">
+ å·²é‡è¨­ã€Œæˆ‘的家ã€ä½ç½®ï¼Œå› ç‚ºå‰ä¸€å€‹ä½ç½®ä¸åˆæ³•ã€‚
+ </notification>
+ <notification name="CantInviteRegionFull">
+ 此刻你無法邀請任何人到你的ä½ç½®ï¼Œå› ç‚ºåœ°å€æ»¿è¼‰ã€‚ è«‹ç¨å€™å†è©¦ä¸€æ¬¡ã€‚
+ </notification>
+ <notification name="CantSetHomeAtRegion">
+ 此地å€ä¸è¨±ä½ åœ¨æ­¤è¨­å®šã€Œæˆ‘的家ã€ã€‚
+ </notification>
+ <notification name="ListValidHomeLocations">
+ ä½ åªèƒ½åœ¨è‡ªå·±çš„土地或大陸資訊中心上設定「我的家ã€ã€‚
+ </notification>
+ <notification name="SetHomePosition">
+ 我的家ä½ç½®å·²å®šã€‚
+ </notification>
+ <notification name="CantDerezInventoryError">
+ 收ç´å€å‡ºéŒ¯ï¼Œç„¡æ³•æ”¶ç´ç‰©ä»¶ã€‚
+ </notification>
+ <notification name="CantCreateRequestedInv">
+ 無法建立è¦æ±‚的收ç´å€ã€‚
+ </notification>
+ <notification name="CantCreateRequestedInvFolder">
+ 無法建立è¦æ±‚的收ç´å€è³‡æ–™å¤¾ã€‚
+ </notification>
+ <notification name="CantCreateInventory">
+ 無法建立該收ç´å€ã€‚
+ </notification>
+ <notification name="CantCreateLandmark">
+ 無法建立地標。
+ </notification>
+ <notification name="CantCreateOutfit">
+ 此時無法建立è£æ‰®ã€‚ è«‹éŽä¸€åˆ†é˜å¾Œå†è©¦ã€‚
+ </notification>
+ <notification name="InventoryNotForSale">
+ 收ç´å€æ²’有待售。
+ </notification>
+ <notification name="CantFindInvItem">
+ 找ä¸åˆ°æ”¶ç´å€ç‰©é …。
+ </notification>
+ <notification name="CantFindObject">
+ 找ä¸åˆ°ç‰©ä»¶ã€‚
+ </notification>
+ <notification name="CantTransfterMoneyRegionDisabled">
+ 此地å€ç›®å‰æœªå•Ÿç”¨è½‰ç§»é‡‘錢給物件的功能。
+ </notification>
+ <notification name="CantPayNoAgent">
+ 無法決定付款給誰。
+ </notification>
+ <notification name="CantDonateToPublicObjects">
+ 你無法將 L$ é€çµ¦å…¬å…±ç‰©ä»¶ã€‚
+ </notification>
+ <notification name="InventoryCreationInWorldObjectFailed">
+ é‡å°è™›æ“¬ä¸–界物件建立收ç´å€å¤±æ•—。
+ </notification>
+ <notification name="UserBalanceOrLandUsageError">
+ 發生內部錯誤,我們無法如常更新你的ç€è¦½å™¨ã€‚ ä½ ç€è¦½å™¨é¡¯ç¤ºçš„ L$ 餘é¡æˆ–æ“有地段,å¯èƒ½å’Œä¼ºæœå™¨ä¸Šçš„正確數é¡ä¸ä¸€è‡´ã€‚
+ </notification>
+ <notification name="LargePrimAgentIntersect">
+ 無法建立和其他åƒèˆ‡è€…發生交截的大型幾何元件。 請等其他åƒèˆ‡è€…移開後å†è©¦ã€‚
+ </notification>
+ <notification name="PreferenceChatClearLog">
+ 這動作將刪除先å‰äº¤è«‡çš„記錄,和所有記錄備份。
+ <usetemplate ignoretext="刪除先å‰äº¤è«‡è¨˜éŒ„å‰ï¼Œå…ˆå‘我確èªã€‚" name="okcancelignore" notext="å–消" yestext="確定"/>
+ </notification>
+ <notification name="PreferenceChatDeleteTranscripts">
+ 這將刪除所有先å‰äº¤è«‡çš„內容記錄。 éŽåŽ»äº¤è«‡æ­·å²æ¸…å–®ä¸å—影響。 資料夾 [FOLDER] 所有副檔å .txt å’Œ txt.backup 的檔案都將刪除。
+ <usetemplate ignoretext="刪除交談內容記錄å‰å…ˆå‘我確èªã€‚" name="okcancelignore" notext="å–消" yestext="確定"/>
+ </notification>
+ <notification name="PreferenceChatPathChanged">
+ 無法移動檔案。 å·²æ¢å¾©å‰ä¸€å€‹è·¯å¾‘。
+ <usetemplate ignoretext="無法移動檔案。 å·²æ¢å¾©å‰ä¸€å€‹è·¯å¾‘。" name="okignore" yestext="確定"/>
+ </notification>
</notifications>
diff --git a/indra/newview/skins/default/xui/zh/panel_active_object_row.xml b/indra/newview/skins/default/xui/zh/panel_active_object_row.xml
index 42a4aa9e85..42a4aa9e85 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_active_object_row.xml
+++ b/indra/newview/skins/default/xui/zh/panel_active_object_row.xml
diff --git a/indra/newview/skins/default/xui/zh/panel_adhoc_control_panel.xml b/indra/newview/skins/default/xui/zh/panel_adhoc_control_panel.xml
index 7d16ac4129..7d16ac4129 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_adhoc_control_panel.xml
+++ b/indra/newview/skins/default/xui/zh/panel_adhoc_control_panel.xml
diff --git a/indra/newview/skins/default/xui/zh/panel_avatar_list_item.xml b/indra/newview/skins/default/xui/zh/panel_avatar_list_item.xml
index eccb938f15..e0a49a0add 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_avatar_list_item.xml
+++ b/indra/newview/skins/default/xui/zh/panel_avatar_list_item.xml
@@ -1,31 +1,32 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel name="avatar_list_item">
<string name="FormatSeconds">
- [COUNT]s
+ [COUNT] 秒
</string>
<string name="FormatMinutes">
- [COUNT]m
+ [COUNT] 分
</string>
<string name="FormatHours">
- [COUNT]h
+ [COUNT] 時
</string>
<string name="FormatDays">
- [COUNT]d
+ [COUNT] æ—¥
</string>
<string name="FormatWeeks">
- [COUNT]w
+ [COUNT] 週
</string>
<string name="FormatMonths">
- [COUNT]mon
+ [COUNT] 月
</string>
<string name="FormatYears">
- [COUNT]y
+ [COUNT] å¹´
</string>
- <text name="avatar_name" value="(載入)"/>
- <text name="last_interaction" value="0s"/>
+ <text name="avatar_name" value="(載入中)"/>
+ <text name="last_interaction" value="0 秒"/>
<icon name="permission_edit_theirs_icon" tool_tip="ä½ ä¸èƒ½ç·¨è¼¯é€™ä½æœ‹å‹çš„物件"/>
<icon name="permission_edit_mine_icon" tool_tip="這ä½æœ‹å‹èƒ½ç·¨è¼¯ã€åˆªé™¤æˆ–å–得你的物件"/>
<icon name="permission_map_icon" tool_tip="這ä½æœ‹å‹èƒ½åœ¨åœ°åœ–上找到你的ä½ç½®"/>
<icon name="permission_online_icon" tool_tip="這ä½æœ‹å‹ç•¶ä½ ä¸Šç·šèƒ½çœ‹åˆ°è¨Šæ¯"/>
+ <button name="info_btn" tool_tip="詳情"/>
<button name="profile_btn" tool_tip="察看檔案"/>
</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_avatar_tag.xml b/indra/newview/skins/default/xui/zh/panel_avatar_tag.xml
index fd91ea97d1..fd91ea97d1 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_avatar_tag.xml
+++ b/indra/newview/skins/default/xui/zh/panel_avatar_tag.xml
diff --git a/indra/newview/skins/default/xui/zh/panel_block_list_sidetray.xml b/indra/newview/skins/default/xui/zh/panel_block_list_sidetray.xml
index 1dfa024138..9f59bb32f8 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_block_list_sidetray.xml
+++ b/indra/newview/skins/default/xui/zh/panel_block_list_sidetray.xml
@@ -1,10 +1,11 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel name="block_list_panel">
- <text name="title_text">
- å°éŽ–清單
- </text>
- <scroll_list name="blocked" tool_tip="ç›®å‰å°éŽ–的居民清單"/>
- <button label="å°éŽ–他人" name="Block resident..." tool_tip="挑é¸ä¸€ä½å±…民以進行å°éŽ–"/>
- <button label="ä¾å稱å°éŽ–物件" name="Block object by name..." tool_tip="ä¾å稱挑é¸ä¸€å€‹ç‰©ä»¶é€²è¡Œå°éŽ–"/>
- <button label="解除å°éŽ–" name="Unblock" tool_tip="將居民或物件由å°éŽ–清單中移除"/>
+ <panel label="bottom_panel" name="blocked_buttons_panel">
+ <filter_editor label="éŽæ¿¾å™¨" name="blocked_filter_input"/>
+ <menu_button name="blocked_gear_btn" tool_tip="å°æ‰€é¸çš„人或物件採å–動作"/>
+ <menu_button name="view_btn" tool_tip="排åºé¸é …"/>
+ <menu_button name="plus_btn" tool_tip="挑é¸ä¸€ä½å±…民或物件,加以å°éŽ–"/>
+ <button name="unblock_btn" tool_tip="將居民或物件由å°éŽ–清單中移除"/>
+ </panel>
+ <block_list name="blocked" tool_tip="ç›®å‰å°éŽ–的居民清單"/>
</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_body_parts_list_item.xml b/indra/newview/skins/default/xui/zh/panel_body_parts_list_item.xml
index 550868e5e5..fef692c1c5 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_body_parts_list_item.xml
+++ b/indra/newview/skins/default/xui/zh/panel_body_parts_list_item.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel name="wearable_item">
<text name="item_name" value="..."/>
- <panel name="btn_lock" tool_tip="你並沒有權é™é€²è¡Œç·¨è¼¯"/>
+ <panel name="btn_lock" tool_tip="你沒有編輯權"/>
<panel name="btn_edit_panel">
<button name="btn_edit" tool_tip="編輯這個體形"/>
</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_bodyparts_list_button_bar.xml b/indra/newview/skins/default/xui/zh/panel_bodyparts_list_button_bar.xml
index 5e269fcd09..e4e7a661a7 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_bodyparts_list_button_bar.xml
+++ b/indra/newview/skins/default/xui/zh/panel_bodyparts_list_button_bar.xml
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel name="clothing_list_button_bar_panel">
- <button label="Switch" name="switch_btn"/>
+ <button label="切æ›" name="switch_btn"/>
</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_bottomtray.xml b/indra/newview/skins/default/xui/zh/panel_bottomtray.xml
deleted file mode 100644
index 734b83e6cc..0000000000
--- a/indra/newview/skins/default/xui/zh/panel_bottomtray.xml
+++ /dev/null
@@ -1,47 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel name="bottom_tray">
- <string name="DragIndicationImageName" value="Accordion_ArrowOpened_Off"/>
- <string name="SpeakBtnToolTip" value="Turns microphone on/off"/>
- <string name="VoiceControlBtnToolTip" value="顯示 / éš±è— èªžéŸ³æŽ§åˆ¶æ¿"/>
- <layout_stack name="toolbar_stack">
- <layout_panel name="speak_panel">
- <talk_button name="talk">
- <speak_button label="Speak" label_selected="Speak" name="speak_btn"/>
- </talk_button>
- </layout_panel>
- <layout_panel name="gesture_panel">
- <gesture_combo_list label="姿勢" name="Gesture" tool_tip="顯示 / éš±è— å§¿å‹¢"/>
- </layout_panel>
- <layout_panel name="movement_panel">
- <bottomtray_button label="移動" name="movement_btn" tool_tip="顯示 / éš±è— ç§»å‹•æŽ§åˆ¶"/>
- </layout_panel>
- <layout_panel name="cam_panel">
- <bottomtray_button label="視角" name="camera_btn" tool_tip="顯示 / éš±è— æ”影機控制"/>
- </layout_panel>
- <layout_panel name="snapshot_panel">
- <bottomtray_button name="snapshots" tool_tip="æ‹æ”å¿«ç…§"/>
- </layout_panel>
- <layout_panel name="build_btn_panel">
- <bottomtray_button label="建造" name="build_btn" tool_tip="顯示 / éš±è— å»ºé€ å·¥å…·"/>
- </layout_panel>
- <layout_panel name="search_btn_panel">
- <bottomtray_button label="æœå°‹" name="search_btn" tool_tip="顯示 / éš±è— æœå°‹"/>
- </layout_panel>
- <layout_panel name="world_map_btn_panel">
- <bottomtray_button label="地圖" name="world_map_btn" tool_tip="顯示 / éš±è— ä¸–ç•Œåœ°åœ–"/>
- </layout_panel>
- <layout_panel name="mini_map_btn_panel">
- <bottomtray_button label="迷你地圖" name="mini_map_btn" tool_tip="顯示 / éš±è— è¿·ä½ åœ°åœ–"/>
- </layout_panel>
- <layout_panel name="im_well_panel">
- <chiclet_im_well name="im_well">
- <button name="Unread IM messages" tool_tip="Conversations"/>
- </chiclet_im_well>
- </layout_panel>
- <layout_panel name="notification_well_panel">
- <chiclet_notification name="notification_well">
- <button name="Unread" tool_tip="通知"/>
- </chiclet_notification>
- </layout_panel>
- </layout_stack>
-</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_bottomtray_lite.xml b/indra/newview/skins/default/xui/zh/panel_bottomtray_lite.xml
index 9833e9ef8b..9833e9ef8b 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_bottomtray_lite.xml
+++ b/indra/newview/skins/default/xui/zh/panel_bottomtray_lite.xml
diff --git a/indra/newview/skins/default/xui/zh/panel_chat_header.xml b/indra/newview/skins/default/xui/zh/panel_chat_header.xml
index 7916bf5155..7916bf5155 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_chat_header.xml
+++ b/indra/newview/skins/default/xui/zh/panel_chat_header.xml
diff --git a/indra/newview/skins/default/xui/zh/panel_chiclet_bar.xml b/indra/newview/skins/default/xui/zh/panel_chiclet_bar.xml
new file mode 100755
index 0000000000..69340349bc
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/panel_chiclet_bar.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="chiclet_bar">
+ <layout_stack name="toolbar_stack">
+ <layout_panel name="im_well_panel">
+ <chiclet_im_well name="im_well">
+ <button name="Unread IM messages" tool_tip="交談"/>
+ </chiclet_im_well>
+ </layout_panel>
+ <layout_panel name="notification_well_panel">
+ <chiclet_notification name="notification_well">
+ <button name="Unread" tool_tip="通知"/>
+ </chiclet_notification>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_classified_info.xml b/indra/newview/skins/default/xui/zh/panel_classified_info.xml
index cf3113ef1c..6f2dd89318 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_classified_info.xml
+++ b/indra/newview/skins/default/xui/zh/panel_classified_info.xml
@@ -16,33 +16,33 @@
[mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt]
</panel.string>
<panel.string name="auto_renew_on">
- Enabled
+ 已啟用
</panel.string>
<panel.string name="auto_renew_off">
- Disabled
+ å·²åœç”¨
</panel.string>
- <text name="title" value="Classified Info"/>
+ <text name="title" value="個人廣告資訊"/>
<scroll_container name="profile_scroll">
<panel name="scroll_content_panel">
<text_editor name="classified_name" value="[name]"/>
<text name="classified_location_label" value="ä½ç½®ï¼š"/>
<text_editor name="classified_location" value="[loading...]"/>
- <text name="content_type_label" value="Content Type:"/>
+ <text name="content_type_label" value="內容類型:"/>
<text_editor name="content_type" value="[content type]"/>
- <text name="category_label" value="Category:"/>
+ <text name="category_label" value="分類:"/>
<text_editor name="category" value="[category]"/>
- <text name="creation_date_label" value="Creation date:"/>
- <text_editor name="creation_date" tool_tip="Creation date" value="[date]"/>
- <text name="price_for_listing_label" value="Price for listing:"/>
- <text_editor name="price_for_listing" tool_tip="Price for listing." value="[price]"/>
+ <text name="creation_date_label" value="建立日期:"/>
+ <text_editor name="creation_date" tool_tip="建立日期" value="[date]"/>
+ <text name="price_for_listing_label" value="刊登費:"/>
+ <text_editor name="price_for_listing" tool_tip="刊登費。" value="[price]"/>
<layout_stack name="descr_stack">
<layout_panel name="clickthrough_layout_panel">
- <text name="click_through_label" value="Clicks:"/>
- <text_editor name="click_through_text" tool_tip="Click through data" value="[clicks]"/>
+ <text name="click_through_label" value="點按:"/>
+ <text_editor name="click_through_text" tool_tip="點進資料" value="[clicks]"/>
</layout_panel>
<layout_panel name="price_layout_panel">
- <text name="auto_renew_label" value="Auto renew:"/>
- <text name="auto_renew" value="Enabled"/>
+ <text name="auto_renew_label" value="自動續訂:"/>
+ <text name="auto_renew" value="已啟用"/>
</layout_panel>
<layout_panel name="descr_layout_panel">
<text name="classified_desc_label" value="æ述:"/>
diff --git a/indra/newview/skins/default/xui/zh/panel_clothing_list_button_bar.xml b/indra/newview/skins/default/xui/zh/panel_clothing_list_button_bar.xml
index ba63dada76..ba63dada76 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_clothing_list_button_bar.xml
+++ b/indra/newview/skins/default/xui/zh/panel_clothing_list_button_bar.xml
diff --git a/indra/newview/skins/default/xui/zh/panel_clothing_list_item.xml b/indra/newview/skins/default/xui/zh/panel_clothing_list_item.xml
index 1185336a2d..55e72f5347 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_clothing_list_item.xml
+++ b/indra/newview/skins/default/xui/zh/panel_clothing_list_item.xml
@@ -2,8 +2,8 @@
<panel name="wearable_item">
<button name="btn_delete" tool_tip="ç”±è£æ‰®ç§»é™¤"/>
<text name="item_name" value="..."/>
- <panel name="btn_lock" tool_tip="你並沒有權é™åŽ»ç·¨è¼¯"/>
+ <panel name="btn_lock" tool_tip="你沒有編輯權"/>
<panel name="btn_edit_panel">
- <button name="btn_edit" tool_tip="Edit this wearable"/>
+ <button name="btn_edit" tool_tip="編輯這å¯ç©¿è£æ‰®"/>
</panel>
</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_cof_wearables.xml b/indra/newview/skins/default/xui/zh/panel_cof_wearables.xml
index 309ab1c0d4..c074abb568 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_cof_wearables.xml
+++ b/indra/newview/skins/default/xui/zh/panel_cof_wearables.xml
@@ -2,7 +2,7 @@
<panel name="cof_wearables">
<accordion name="cof_wearables_accordion">
<accordion_tab name="tab_clothing" title="æœè£"/>
- <accordion_tab name="tab_attachments" title="Attachments"/>
+ <accordion_tab name="tab_attachments" title="附件"/>
<accordion_tab name="tab_body_parts" title="身體部ä½"/>
</accordion>
</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_conversation_list_item.xml b/indra/newview/skins/default/xui/zh/panel_conversation_list_item.xml
new file mode 100644
index 0000000000..6524d41645
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/panel_conversation_list_item.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="conversation_list_item">
+ <layout_stack name="conversation_item_stack">
+ <layout_panel name="conversation_title_panel">
+ <text name="conversation_title" value="(載入中)"/>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_conversation_log_list_item.xml b/indra/newview/skins/default/xui/zh/panel_conversation_log_list_item.xml
new file mode 100644
index 0000000000..8446ce2130
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/panel_conversation_log_list_item.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="conversation_log_list_item">
+ <icon name="voice_session_icon" tool_tip="包å«èªžéŸ³äº¤è«‡"/>
+ <icon name="unread_ims_icon" tool_tip="訊æ¯åœ¨ä½ ç™»å‡ºæœŸé–“傳來"/>
+ <button name="delete_btn" tool_tip="移除此項目"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_deletable_wearable_list_item.xml b/indra/newview/skins/default/xui/zh/panel_deletable_wearable_list_item.xml
index a9e65419c2..a9e65419c2 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_deletable_wearable_list_item.xml
+++ b/indra/newview/skins/default/xui/zh/panel_deletable_wearable_list_item.xml
diff --git a/indra/newview/skins/default/xui/zh/panel_dummy_clothing_list_item.xml b/indra/newview/skins/default/xui/zh/panel_dummy_clothing_list_item.xml
index 6377bf4135..6377bf4135 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_dummy_clothing_list_item.xml
+++ b/indra/newview/skins/default/xui/zh/panel_dummy_clothing_list_item.xml
diff --git a/indra/newview/skins/default/xui/zh/panel_edit_alpha.xml b/indra/newview/skins/default/xui/zh/panel_edit_alpha.xml
index eda4e99a13..32765a3e16 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_edit_alpha.xml
+++ b/indra/newview/skins/default/xui/zh/panel_edit_alpha.xml
@@ -2,11 +2,11 @@
<panel name="edit_alpha_panel">
<scroll_container name="avatar_alpha_color_panel_scroll">
<panel name="avatar_alpha_color_panel">
- <texture_picker label="下åŠèº«åŠé€æ˜Ž" name="Lower Alpha" tool_tip="點擊以挑é¸åœ–åƒ"/>
- <texture_picker label="上åŠèº«åŠé€æ˜Ž" name="Upper Alpha" tool_tip="點擊以挑é¸åœ–åƒ"/>
- <texture_picker label="頭部åŠé€æ˜Ž" name="Head Alpha" tool_tip="點擊以挑é¸åœ–åƒ"/>
- <texture_picker label="眼ç›åŠé€æ˜Ž" name="Eye Alpha" tool_tip="點擊以挑é¸åœ–åƒ"/>
- <texture_picker label="é ­é«®åŠé€æ˜Ž" name="Hair Alpha" tool_tip="點擊以挑é¸åœ–åƒ"/>
+ <texture_picker label="下åŠèº«åŠé€æ˜Ž" name="Lower Alpha" tool_tip="點按以挑é¸åœ–片"/>
+ <texture_picker label="上åŠèº«åŠé€æ˜Ž" name="Upper Alpha" tool_tip="點按以挑é¸åœ–片"/>
+ <texture_picker label="頭部åŠé€æ˜Ž" name="Head Alpha" tool_tip="點按以挑é¸åœ–片"/>
+ <texture_picker label="眼ç›åŠé€æ˜Ž" name="Eye Alpha" tool_tip="點按以挑é¸åœ–片"/>
+ <texture_picker label="é ­é«®åŠé€æ˜Ž" name="Hair Alpha" tool_tip="點按以挑é¸åœ–片"/>
</panel>
</scroll_container>
</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_edit_classified.xml b/indra/newview/skins/default/xui/zh/panel_edit_classified.xml
index f12701c981..b06ece02ad 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_edit_classified.xml
+++ b/indra/newview/skins/default/xui/zh/panel_edit_classified.xml
@@ -1,24 +1,24 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel label="Edit Classified" name="panel_edit_classified">
+<panel label="編輯個人廣告" name="panel_edit_classified">
<panel.string name="location_notice">
(儲存後將會更新)
</panel.string>
<string name="publish_label">
- Publish
+ 發布
</string>
<string name="save_label">
儲存
</string>
<text name="title">
- Edit Classified
+ 編輯個人廣告
</text>
<scroll_container name="profile_scroll">
<panel name="scroll_content_panel">
<panel name="snapshot_panel">
- <icon label="" name="edit_icon" tool_tip="點擊以é¸æ“‡åœ–åƒ"/>
+ <icon label="" name="edit_icon" tool_tip="點按以é¸æ“‡åœ–åƒ"/>
</panel>
<text name="Name:">
- Title:
+ 標題:
</text>
<text name="description_label">
æ述:
@@ -29,16 +29,16 @@
<text name="classified_location">
載入中...
</text>
- <button label="Set to Current Location" name="set_to_curr_location_btn"/>
- <text name="category_label" value="Category:"/>
- <text name="content_type_label" value="Content type:"/>
+ <button label="設定為目å‰ä½ç½®" name="set_to_curr_location_btn"/>
+ <text name="category_label" value="分類:"/>
+ <text name="content_type_label" value="內容類型:"/>
<icons_combo_box label="一般普級內容" name="content_type">
- <icons_combo_box.item label="é©åº¦æˆäººå…§å®¹" name="mature_ci" value="Mature"/>
- <icons_combo_box.item label="一般普級內容" name="pg_ci" value="PG"/>
+ <icons_combo_box.item label="é©åº¦æˆäººå…§å®¹" name="mature_ci" value="é©åº¦æˆäºº"/>
+ <icons_combo_box.item label="一般普級內容" name="pg_ci" value="一般普級"/>
</icons_combo_box>
- <check_box label="Auto renew each week" name="auto_renew"/>
- <text name="price_for_listing_label" value="Price for listing:"/>
- <spinner label="L$" name="price_for_listing" tool_tip="Price for listing." value="50"/>
+ <check_box label="æ¯æ˜ŸæœŸè‡ªå‹•çºŒè¨‚" name="auto_renew"/>
+ <text name="price_for_listing_label" value="刊登費:"/>
+ <spinner label="L$" name="price_for_listing" tool_tip="刊登費。" value="50"/>
</panel>
</scroll_container>
<panel label="bottom_panel" name="bottom_panel">
diff --git a/indra/newview/skins/default/xui/zh/panel_edit_eyes.xml b/indra/newview/skins/default/xui/zh/panel_edit_eyes.xml
index 40dd61971a..f44d411908 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_edit_eyes.xml
+++ b/indra/newview/skins/default/xui/zh/panel_edit_eyes.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel name="edit_eyes_panel">
<panel name="avatar_eye_color_panel">
- <texture_picker label="Iris" name="Iris" tool_tip="點擊以挑é¸åœ–åƒ"/>
+ <texture_picker label="虹膜" name="Iris" tool_tip="點按以挑é¸åœ–片"/>
</panel>
<panel name="accordion_panel">
<accordion name="wearable_accordion">
diff --git a/indra/newview/skins/default/xui/zh/panel_edit_gloves.xml b/indra/newview/skins/default/xui/zh/panel_edit_gloves.xml
index 7b39e33a9b..d107eea553 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_edit_gloves.xml
+++ b/indra/newview/skins/default/xui/zh/panel_edit_gloves.xml
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel name="edit_gloves_panel">
<panel name="avatar_gloves_color_panel">
- <texture_picker label="æ質" name="Fabric" tool_tip="點擊以挑é¸åœ–åƒ"/>
- <color_swatch label="Color/Tint" name="Color/Tint" tool_tip="Click to open color picker"/>
+ <texture_picker label="æ質" name="Fabric" tool_tip="點按以挑é¸åœ–片"/>
+ <color_swatch label="é¡è‰²/色調" name="Color/Tint" tool_tip="點按以開啟é¡è‰²æŒ‘é¸å™¨"/>
</panel>
<panel name="accordion_panel">
<accordion name="wearable_accordion">
diff --git a/indra/newview/skins/default/xui/zh/panel_edit_hair.xml b/indra/newview/skins/default/xui/zh/panel_edit_hair.xml
index a7440093bc..65f78f9273 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_edit_hair.xml
+++ b/indra/newview/skins/default/xui/zh/panel_edit_hair.xml
@@ -1,14 +1,14 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel name="edit_hair_panel">
<panel name="avatar_hair_color_panel">
- <texture_picker label="æ質" name="Texture" tool_tip="點擊以挑é¸åœ–åƒ"/>
+ <texture_picker label="æ質" name="Texture" tool_tip="點按以挑é¸åœ–片"/>
</panel>
<panel name="accordion_panel">
<accordion name="wearable_accordion">
<accordion_tab name="hair_color_tab" title="é¡è‰²"/>
- <accordion_tab name="hair_style_tab" title="Style"/>
- <accordion_tab name="hair_eyebrows_tab" title="Eyebrows"/>
- <accordion_tab name="hair_facial_tab" title="Facial"/>
+ <accordion_tab name="hair_style_tab" title="風格"/>
+ <accordion_tab name="hair_eyebrows_tab" title="眉毛"/>
+ <accordion_tab name="hair_facial_tab" title="é¡é¢"/>
</accordion>
</panel>
</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_edit_jacket.xml b/indra/newview/skins/default/xui/zh/panel_edit_jacket.xml
index dcef070e2e..61e45f911e 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_edit_jacket.xml
+++ b/indra/newview/skins/default/xui/zh/panel_edit_jacket.xml
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel name="edit_jacket_panel">
<panel name="avatar_jacket_color_panel">
- <texture_picker label="上åŠèº«æ質" name="Upper Fabric" tool_tip="點擊以挑é¸åœ–åƒ"/>
- <texture_picker label="下åŠèº«æ質" name="Lower Fabric" tool_tip="點擊以挑é¸åœ–åƒ"/>
- <color_swatch label="Color/Tint" name="Color/Tint" tool_tip="Click to open color picker"/>
+ <texture_picker label="上åŠèº«æ質" name="Upper Fabric" tool_tip="點按以挑é¸åœ–片"/>
+ <texture_picker label="下åŠèº«æ質" name="Lower Fabric" tool_tip="點按以挑é¸åœ–片"/>
+ <color_swatch label="é¡è‰²/色調" name="Color/Tint" tool_tip="點按以開啟é¡è‰²æŒ‘é¸å™¨"/>
</panel>
<panel name="accordion_panel">
<accordion name="wearable_accordion">
diff --git a/indra/newview/skins/default/xui/zh/panel_edit_pants.xml b/indra/newview/skins/default/xui/zh/panel_edit_pants.xml
index 01b875f1bd..846ed72961 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_edit_pants.xml
+++ b/indra/newview/skins/default/xui/zh/panel_edit_pants.xml
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel name="edit_pants_panel">
<panel name="avatar_pants_color_panel">
- <texture_picker label="æ質" name="Fabric" tool_tip="點擊以挑é¸åœ–åƒ"/>
- <color_swatch label="Color/Tint" name="Color/Tint" tool_tip="點擊以開啟é¡è‰²æŒ‘é¸å™¨"/>
+ <texture_picker label="æ質" name="Fabric" tool_tip="點按以挑é¸åœ–片"/>
+ <color_swatch label="é¡è‰²/色調" name="Color/Tint" tool_tip="點按以開啟é¡è‰²æŒ‘é¸å™¨"/>
</panel>
<panel name="accordion_panel">
<accordion name="wearable_accordion">
diff --git a/indra/newview/skins/default/xui/zh/panel_edit_physics.xml b/indra/newview/skins/default/xui/zh/panel_edit_physics.xml
index 26fedb59be..26fedb59be 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_edit_physics.xml
+++ b/indra/newview/skins/default/xui/zh/panel_edit_physics.xml
diff --git a/indra/newview/skins/default/xui/zh/panel_edit_pick.xml b/indra/newview/skins/default/xui/zh/panel_edit_pick.xml
index 6ac7226185..faee42fd0e 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_edit_pick.xml
+++ b/indra/newview/skins/default/xui/zh/panel_edit_pick.xml
@@ -1,14 +1,14 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel label="編輯精é¸åœ°é»ž" name="panel_edit_pick">
<panel.string name="location_notice">
- (將在儲存後更新)
+ (儲存後將會更新)
</panel.string>
<text name="title">
編輯精é¸åœ°é»ž
</text>
<scroll_container name="profile_scroll">
<panel name="scroll_content_panel">
- <icon label="" name="edit_icon" tool_tip="點擊以é¸æ“‡åœ–åƒ"/>
+ <icon label="" name="edit_icon" tool_tip="點按以é¸æ“‡åœ–åƒ"/>
<text name="Name:">
標題:
</text>
@@ -29,7 +29,7 @@
<layout_panel name="layout_panel1">
<button label="儲存精é¸åœ°é»ž" name="save_changes_btn"/>
</layout_panel>
- <layout_panel name="layout_panel1">
+ <layout_panel name="layout_panel2">
<button label="å–消" name="cancel_btn"/>
</layout_panel>
</layout_stack>
diff --git a/indra/newview/skins/default/xui/zh/panel_edit_profile.xml b/indra/newview/skins/default/xui/zh/panel_edit_profile.xml
index 7734c3a417..849b82c71a 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_edit_profile.xml
+++ b/indra/newview/skins/default/xui/zh/panel_edit_profile.xml
@@ -7,15 +7,15 @@
<string name="RegisterDateFormat">
[REG_DATE] ([AGE])
</string>
- <string name="AcctTypeResident" value="Resident"/>
- <string name="AcctTypeTrial" value="Trial"/>
- <string name="AcctTypeCharterMember" value="Charter Member"/>
- <string name="AcctTypeEmployee" value="Linden Lab Employee"/>
- <string name="PaymentInfoUsed" value="Payment Info Used"/>
- <string name="PaymentInfoOnFile" value="Payment Info On File"/>
- <string name="NoPaymentInfoOnFile" value="No Payment Info On File"/>
- <string name="AgeVerified" value="Age-verified"/>
- <string name="NotAgeVerified" value="Not Age-verified"/>
+ <string name="AcctTypeResident" value="å±…æ°‘"/>
+ <string name="AcctTypeTrial" value="試用"/>
+ <string name="AcctTypeCharterMember" value="è€ç‰Œ Charter æˆå“¡"/>
+ <string name="AcctTypeEmployee" value="林登實驗室員工"/>
+ <string name="PaymentInfoUsed" value="使用的付款資料"/>
+ <string name="PaymentInfoOnFile" value="é ç•™ä»˜æ¬¾è³‡æ–™"/>
+ <string name="NoPaymentInfoOnFile" value="未é ç•™ä»˜æ¬¾è³‡æ–™"/>
+ <string name="AgeVerified" value="通éŽå¹´é½¡é©—è­‰"/>
+ <string name="NotAgeVerified" value="未通éŽå¹´é½¡é©—è­‰"/>
<string name="partner_edit_link_url">
http://www.secondlife.com/account/partners.php?lang=en
</string>
@@ -34,22 +34,22 @@
<panel name="second_life_image_panel">
<text name="second_life_photo_title_text" value="[SECOND_LIFE]:"/>
</panel>
- <icon label="" name="2nd_life_edit_icon" tool_tip="點擊以é¸æ“‡åœ–åƒ"/>
+ <icon label="" name="2nd_life_edit_icon" tool_tip="點按以é¸æ“‡åœ–åƒ"/>
</panel>
<panel name="first_life_image_panel">
<text name="real_world_photo_title_text" value="真實世界:"/>
</panel>
- <icon label="" name="real_world_edit_icon" tool_tip="點擊以é¸æ“‡åœ–åƒ"/>
+ <icon label="" name="real_world_edit_icon" tool_tip="點按以é¸æ“‡åœ–åƒ"/>
<text name="title_homepage_text">
首é ï¼š
</text>
<line_editor name="homepage_edit" value="http://"/>
<text name="title_acc_status_text" value="我的帳戶:"/>
- <text_editor name="acc_status_text" value="Resident. No payment info on file."/>
+ <text_editor name="acc_status_text" value="居民。 未é ç•™ä»˜æ¬¾è³‡æ–™ã€‚"/>
<text name="my_account_link" value="[[URL] å‰å¾€æˆ‘的塗鴉牆]"/>
<text name="title_partner_text" value="我的é…å¶ï¼š"/>
<panel name="partner_data_panel">
- <text initial_value="(retrieving)" name="partner_text"/>
+ <text initial_value="(檢索中)" name="partner_text"/>
</panel>
<text name="partner_edit_link" value="[[URL] 編輯]"/>
</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_edit_shape.xml b/indra/newview/skins/default/xui/zh/panel_edit_shape.xml
index f249100786..f249100786 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_edit_shape.xml
+++ b/indra/newview/skins/default/xui/zh/panel_edit_shape.xml
diff --git a/indra/newview/skins/default/xui/zh/panel_edit_shirt.xml b/indra/newview/skins/default/xui/zh/panel_edit_shirt.xml
index f8ff76aa9b..bc69f2ffc4 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_edit_shirt.xml
+++ b/indra/newview/skins/default/xui/zh/panel_edit_shirt.xml
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel name="edit_shirt_panel">
<panel name="avatar_shirt_color_panel">
- <texture_picker label="æ質" name="Fabric" tool_tip="點擊以挑é¸åœ–åƒ"/>
- <color_swatch label="Color/Tint" name="Color/Tint" tool_tip="點擊以開啟é¡è‰²æŒ‘é¸å™¨"/>
+ <texture_picker label="æ質" name="Fabric" tool_tip="點按以挑é¸åœ–片"/>
+ <color_swatch label="é¡è‰²/色調" name="Color/Tint" tool_tip="點按以開啟é¡è‰²æŒ‘é¸å™¨"/>
</panel>
<panel name="accordion_panel">
<accordion name="wearable_accordion">
diff --git a/indra/newview/skins/default/xui/zh/panel_edit_shoes.xml b/indra/newview/skins/default/xui/zh/panel_edit_shoes.xml
index 97e43f5753..e190bb5bd8 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_edit_shoes.xml
+++ b/indra/newview/skins/default/xui/zh/panel_edit_shoes.xml
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel name="edit_shoes_panel">
<panel name="avatar_shoes_color_panel">
- <texture_picker label="æ質" name="Fabric" tool_tip="點擊以挑é¸åœ–åƒ"/>
- <color_swatch label="é¡è‰²/色調" name="Color/Tint" tool_tip="點擊以開啟é¡è‰²æŒ‘é¸å™¨"/>
+ <texture_picker label="æ質" name="Fabric" tool_tip="點按以挑é¸åœ–片"/>
+ <color_swatch label="é¡è‰²/色調" name="Color/Tint" tool_tip="點按以開啟é¡è‰²æŒ‘é¸å™¨"/>
</panel>
<panel name="accordion_panel">
<accordion name="wearable_accordion">
diff --git a/indra/newview/skins/default/xui/zh/panel_edit_skin.xml b/indra/newview/skins/default/xui/zh/panel_edit_skin.xml
index fdd6d05ca5..d8552f52f0 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_edit_skin.xml
+++ b/indra/newview/skins/default/xui/zh/panel_edit_skin.xml
@@ -1,16 +1,16 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel name="edit_skin_panel">
<panel name="avatar_skin_color_panel">
- <texture_picker label="Head Tattoos" name="Head Tattoos" tool_tip="點擊以挑é¸åœ–åƒ"/>
- <texture_picker label="Upper Tattoos" name="Upper Tattoos" tool_tip="點擊以挑é¸åœ–åƒ"/>
- <texture_picker label="Lower Tattoos" name="Lower Tattoos" tool_tip="點擊以挑é¸åœ–åƒ"/>
+ <texture_picker label="頭部" name="Head" tool_tip="點按以挑é¸åœ–片"/>
+ <texture_picker label="上åŠèº«" name="Upper Body" tool_tip="點按以挑é¸åœ–片"/>
+ <texture_picker label="下åŠèº«" name="Lower Body" tool_tip="點按以挑é¸åœ–片"/>
</panel>
<panel name="accordion_panel">
<accordion name="wearable_accordion">
- <accordion_tab name="skin_color_tab" title="Skin Color"/>
- <accordion_tab name="skin_face_tab" title="Face Detail"/>
- <accordion_tab name="skin_makeup_tab" title="Makeup"/>
- <accordion_tab name="skin_body_tab" title="Body Detail"/>
+ <accordion_tab name="skin_color_tab" title="膚色"/>
+ <accordion_tab name="skin_face_tab" title="臉部細節"/>
+ <accordion_tab name="skin_makeup_tab" title="化å¦"/>
+ <accordion_tab name="skin_body_tab" title="身體細節"/>
</accordion>
</panel>
</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_edit_skirt.xml b/indra/newview/skins/default/xui/zh/panel_edit_skirt.xml
index 10432c16b1..34319fcc01 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_edit_skirt.xml
+++ b/indra/newview/skins/default/xui/zh/panel_edit_skirt.xml
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel name="edit_skirt_panel">
<panel name="avatar_skirt_color_panel">
- <texture_picker label="æ質" name="Fabric" tool_tip="點擊以挑é¸åœ–åƒ"/>
- <color_swatch label="Color/Tint" name="Color/Tint" tool_tip="點擊以開啟é¡è‰²æŒ‘é¸å™¨"/>
+ <texture_picker label="æ質" name="Fabric" tool_tip="點按以挑é¸åœ–片"/>
+ <color_swatch label="é¡è‰²/色調" name="Color/Tint" tool_tip="點按以開啟é¡è‰²æŒ‘é¸å™¨"/>
</panel>
<panel name="accordion_panel">
<accordion name="wearable_accordion">
diff --git a/indra/newview/skins/default/xui/zh/panel_edit_socks.xml b/indra/newview/skins/default/xui/zh/panel_edit_socks.xml
index 6727781740..8e19fb5692 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_edit_socks.xml
+++ b/indra/newview/skins/default/xui/zh/panel_edit_socks.xml
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel name="edit_socks_panel">
<panel name="avatar_socks_color_panel">
- <texture_picker label="æ質" name="Fabric" tool_tip="點擊以挑é¸åœ–åƒ"/>
- <color_swatch label="Color/Tint" name="Color/Tint" tool_tip="點擊以開啟é¡è‰²æŒ‘é¸å™¨"/>
+ <texture_picker label="æ質" name="Fabric" tool_tip="點按以挑é¸åœ–片"/>
+ <color_swatch label="é¡è‰²/色調" name="Color/Tint" tool_tip="點按以開啟é¡è‰²æŒ‘é¸å™¨"/>
</panel>
<panel name="accordion_panel">
<accordion name="wearable_accordion">
diff --git a/indra/newview/skins/default/xui/zh/panel_edit_tattoo.xml b/indra/newview/skins/default/xui/zh/panel_edit_tattoo.xml
index 1b34a0e0ee..f5111d629a 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_edit_tattoo.xml
+++ b/indra/newview/skins/default/xui/zh/panel_edit_tattoo.xml
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel name="edit_tattoo_panel">
<panel name="avatar_tattoo_color_panel">
- <texture_picker label="頭部刺é’" name="Head Tattoo" tool_tip="點擊以挑é¸åœ–åƒ"/>
- <texture_picker label="上åŠèº«åˆºé’" name="Upper Tattoo" tool_tip="點擊以挑é¸ç…§ç‰‡"/>
- <texture_picker label="下åŠèº«åˆºé’" name="Lower Tattoo" tool_tip="點擊以挑é¸åœ–åƒ"/>
- <color_swatch label="Color/Tint" name="Color/Tint" tool_tip="點擊以開啟é¡è‰²æŒ‘é¸å™¨"/>
+ <texture_picker label="頭部刺é’" name="Head Tattoo" tool_tip="點按以挑é¸åœ–片"/>
+ <texture_picker label="上åŠèº«åˆºé’" name="Upper Tattoo" tool_tip="點按以挑é¸åœ–片"/>
+ <texture_picker label="下åŠèº«åˆºé’" name="Lower Tattoo" tool_tip="點按以挑é¸åœ–片"/>
+ <color_swatch label="é¡è‰²/色調" name="Color/Tint" tool_tip="點按以開啟é¡è‰²æŒ‘é¸å™¨"/>
</panel>
</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_edit_underpants.xml b/indra/newview/skins/default/xui/zh/panel_edit_underpants.xml
index 15cae8d233..5ead7c9004 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_edit_underpants.xml
+++ b/indra/newview/skins/default/xui/zh/panel_edit_underpants.xml
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel name="edit_underpants_panel">
<panel name="avatar_underpants_color_panel">
- <texture_picker label="æ質" name="Fabric" tool_tip="點擊以挑é¸åœ–åƒ"/>
- <color_swatch label="Color/Tint" name="Color/Tint" tool_tip="Click to open color picker"/>
+ <texture_picker label="æ質" name="Fabric" tool_tip="點按以挑é¸åœ–片"/>
+ <color_swatch label="é¡è‰²/色調" name="Color/Tint" tool_tip="點按以開啟é¡è‰²æŒ‘é¸å™¨"/>
</panel>
<panel name="accordion_panel">
<accordion name="wearable_accordion">
diff --git a/indra/newview/skins/default/xui/zh/panel_edit_undershirt.xml b/indra/newview/skins/default/xui/zh/panel_edit_undershirt.xml
index 486175eb64..e497e285c9 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_edit_undershirt.xml
+++ b/indra/newview/skins/default/xui/zh/panel_edit_undershirt.xml
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel name="edit_undershirt_panel">
<panel name="avatar_undershirt_color_panel">
- <texture_picker label="æ質" name="Fabric" tool_tip="點擊以挑é¸åœ–åƒ"/>
- <color_swatch label="Color/Tint" name="Color/Tint" tool_tip="Click to open Color Picker"/>
+ <texture_picker label="æ質" name="Fabric" tool_tip="點按以挑é¸åœ–片"/>
+ <color_swatch label="é¡è‰²/色調" name="Color/Tint" tool_tip="點按以開啟é¡è‰²æŒ‘é¸å™¨"/>
</panel>
<panel name="accordion_panel">
<accordion name="wearable_accordion">
diff --git a/indra/newview/skins/default/xui/zh/panel_edit_wearable.xml b/indra/newview/skins/default/xui/zh/panel_edit_wearable.xml
index 066b1fd389..4dd7ea6d93 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_edit_wearable.xml
+++ b/indra/newview/skins/default/xui/zh/panel_edit_wearable.xml
@@ -1,43 +1,43 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel label="Wearable" name="panel_edit_wearable">
+<panel label="å¯ç©¿è£æ‰®" name="panel_edit_wearable">
<string name="edit_shape_title">
- Editing Shape
+ 體形編輯中
</string>
<string name="edit_skin_title">
- Editing Skin
+ 編輯皮膚
</string>
<string name="edit_hair_title">
- Editing Hair
+ 編輯頭髮
</string>
<string name="edit_eyes_title">
- Editing Eyes
+ 編輯眼ç›
</string>
<string name="edit_shirt_title">
- Editing Shirt
+ 編輯襯衫
</string>
<string name="edit_pants_title">
- Editing Pants
+ 編輯褲å­
</string>
<string name="edit_shoes_title">
- Editing Shoes
+ 編輯鞋å­
</string>
<string name="edit_socks_title">
- Editing Socks
+ 編輯襪å­
</string>
<string name="edit_jacket_title">
- Editing Jacket
+ 編輯外套
</string>
<string name="edit_skirt_title">
- Editing Skirt
+ 編輯裙å­
</string>
<string name="edit_gloves_title">
- Editing Gloves
+ 編輯手套
</string>
<string name="edit_undershirt_title">
- Editing Undershirt
+ 編輯內衣
</string>
<string name="edit_underpants_title">
- Editing Underpants
+ 編輯內褲
</string>
<string name="edit_alpha_title">
åŠé€æ˜Žé®ç½©ç·¨è¼¯ä¸­
@@ -110,7 +110,7 @@
<panel name="button_panel">
<layout_stack name="button_panel_ls">
<layout_panel name="save_as_btn_lp">
- <button label="å¦å­˜" name="save_as_button"/>
+ <button label="å¦å­˜ç‚º" name="save_as_button"/>
</layout_panel>
<layout_panel name="revert_btn_lp">
<button label="復原變更" name="revert_button"/>
diff --git a/indra/newview/skins/default/xui/zh/panel_group_control_panel.xml b/indra/newview/skins/default/xui/zh/panel_group_control_panel.xml
index 3915e80d43..f468aba514 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_group_control_panel.xml
+++ b/indra/newview/skins/default/xui/zh/panel_group_control_panel.xml
@@ -8,7 +8,7 @@
<button label="群組通話" name="call_btn"/>
</layout_panel>
<layout_panel name="end_call_btn_panel">
- <button label="çµæŸé€šè©±" name="end_call_btn"/>
+ <button label="離開通話" name="end_call_btn"/>
</layout_panel>
<layout_panel name="voice_ctrls_btn_panel">
<button label="開啟語音控制" name="voice_ctrls_btn"/>
diff --git a/indra/newview/skins/default/xui/zh/panel_group_general.xml b/indra/newview/skins/default/xui/zh/panel_group_general.xml
index 55cbf5a617..2b16b61dd1 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_group_general.xml
+++ b/indra/newview/skins/default/xui/zh/panel_group_general.xml
@@ -1,18 +1,18 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel label="一般" name="general_tab">
+<panel label="基本資料" name="general_tab">
<panel.string name="help_text">
- The General tab contains general information about this group, a list of members, general Group Preferences and member options.
+ 基本資料é ç±¤åŒ…å«é—œæ–¼ç¾¤çµ„的基本資訊ã€æˆå“¡åå–®ã€ç¾¤çµ„å好設定和æˆå“¡é¸é …。
-Hover your mouse over the options for more help.
+將滑鼠åœæ‡¸åˆ°é¸é …上,å¯ç²å–更多幫助。
</panel.string>
<panel.string name="group_info_unchanged">
- 一般群組資訊已經被變更
+ 基本群組資訊已經被變更
</panel.string>
<panel.string name="incomplete_member_data_str">
- Retrieving member data
+ 正在擷å–æˆå“¡è³‡æ–™
</panel.string>
<panel name="group_info_top">
- <texture_picker label="" name="insignia" tool_tip="點擊以挑é¸åœ–åƒ"/>
+ <texture_picker label="" name="insignia" tool_tip="點按以挑é¸åœ–片"/>
<text name="prepend_founded_by">
創辦人:
</text>
@@ -30,22 +30,22 @@ Hover your mouse over the options for more help.
<name_list.columns label="狀態" name="status"/>
</name_list>
<text name="my_group_settngs_label">
- 自己
+ 我自己
</text>
<text name="active_title_label">
我的頭銜:
</text>
- <combo_box name="active_title" tool_tip="Sets the title that appears in your avatar&apos;s name tag when this group is active."/>
- <check_box label="接å—群組通知" name="receive_notices" tool_tip="Sets whether you want to receive Notices from this group. Uncheck this box if this group is spamming you."/>
- <check_box label="顯示在我的檔案中" name="list_groups_in_profile" tool_tip="Sets whether you want to show this group in your profile"/>
+ <combo_box name="active_title" tool_tip="這將設定當群組有效時,顯示於你化身å稱標籤的頭銜。"/>
+ <check_box label="接å—群組通知" name="receive_notices" tool_tip="設定你是å¦è¦æŽ¥æ”¶ä¾†è‡ªé€™ç¾¤çµ„的通知。 如果該群組å°ä½ é€å‡ºå¤ªå¤šåžƒåœ¾è³‡è¨Šï¼Œä½ å¯ä»¥ä¸è¦å‹¾é¸æ­¤é …目。"/>
+ <check_box label="顯示在我的檔案中" name="list_groups_in_profile" tool_tip="設定你是å¦è¦åœ¨ä½ å€‹äººæª”案上顯示這個群組"/>
<panel name="preferences_container">
<text name="group_settngs_label">
群組
</text>
- <check_box label="任何人都å¯ä»¥åŠ å…¥" name="open_enrollement" tool_tip="Sets whether this group allows new members to join without being invited."/>
- <check_box label="加入費用" name="check_enrollment_fee" tool_tip="Sets whether to require an enrollment fee to join the group"/>
- <spinner label="L$" name="spin_enrollment_fee" tool_tip="New members must pay this fee to join the group when Enrollment Fee is checked."/>
- <combo_box name="group_mature_check" tool_tip="Sets whether your group contains information rated as Moderate">
+ <check_box label="任何人都å¯ä»¥åŠ å…¥" name="open_enrollement" tool_tip="設定這個群組是å¦å…許新æˆå“¡æœªå—邀請自行加入。"/>
+ <check_box label="加入費用" name="check_enrollment_fee" tool_tip="設定是å¦è¦å¾µæ”¶ç¾¤çµ„加入費"/>
+ <spinner label="L$" name="spin_enrollment_fee" tool_tip="若勾é¸åŠ å…¥è²»ï¼Œæ–°æˆå“¡å¿…須支付這筆費用æ‰èƒ½åŠ å…¥ç¾¤çµ„。"/>
+ <combo_box name="group_mature_check" tool_tip="設定你的群組是å¦å«æœ‰è¢«è¨‚為é©åº¦æˆäººåˆ†ç´šçš„資訊">
<combo_item name="select_mature">
- é¸æ“‡å…§å®¹åˆ†ç´š -
</combo_item>
diff --git a/indra/newview/skins/default/xui/zh/panel_group_info_sidetray.xml b/indra/newview/skins/default/xui/zh/panel_group_info_sidetray.xml
index db01edcdb3..f979a4c53e 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_group_info_sidetray.xml
+++ b/indra/newview/skins/default/xui/zh/panel_group_info_sidetray.xml
@@ -19,7 +19,7 @@
<layout_stack name="layout">
<layout_panel name="group_accordions">
<accordion name="groups_accordion">
- <accordion_tab name="group_general_tab" title="一般"/>
+ <accordion_tab name="group_general_tab" title="基本資料"/>
<accordion_tab name="group_roles_tab" title="角色"/>
<accordion_tab name="group_notices_tab" title="通知"/>
<accordion_tab name="group_land_tab" title="土地 / 資產"/>
diff --git a/indra/newview/skins/default/xui/zh/panel_group_invite.xml b/indra/newview/skins/default/xui/zh/panel_group_invite.xml
index 07dcb2303e..8921978b20 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_group_invite.xml
+++ b/indra/newview/skins/default/xui/zh/panel_group_invite.xml
@@ -1,24 +1,27 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel label="邀請一個æˆå“¡" name="invite_panel">
<panel.string name="confirm_invite_owner_str">
- Are you sure you want to invite new owner(s)? This action is permanent!
+ 確定邀請新的所有人? 這動作一旦完æˆï¼Œä¸èƒ½å–消ï¼
</panel.string>
<panel.string name="loading">
(載入中...)
</panel.string>
<panel.string name="already_in_group">
- Some Residents you chose are already in the group, and so were not sent an invitation.
+ 你所é¸çš„居民有些已經在群組裡,所以ä¸æœƒå†å°ä»–們發é€é‚€è«‹ã€‚
+ </panel.string>
+ <panel.string name="invite_selection_too_large">
+ 未é€å‡ºç¾¤çµ„邀請:所é¸çš„居民人數太多。 群組邀請æ¯æ¬¡ä»¥ 100 人為上é™ã€‚
</panel.string>
<text name="help_text">
- You can select multiple Residents to invite to your group. Click &apos;Open Resident Chooser&apos; to start.
+ ä½ å¯ä»¥é¸æ“‡é‚€è«‹å¤šä½å±…民到你的群組來。 點按「開啟居民é¸æ“‡å·¥å…·ã€é–‹å§‹é¸æ“‡ã€‚
</text>
- <button label="é–‹å•Ÿå±…æ°‘é¸æ“‡è¦–窗" name="add_button"/>
- <name_list name="invitee_list" tool_tip="Hold the Ctrl key and click Resident names to multi-select"/>
- <button label="Remove Selected from List" name="remove_button" tool_tip="Removes the Residents selected above from the invite list"/>
+ <button label="é–‹å•Ÿå±…æ°‘é¸æ“‡å·¥å…·" name="add_button"/>
+ <name_list name="invitee_list" tool_tip="按下 Ctrl éµåŒæ™‚點é¸å±…æ°‘çš„å字,å³å¯é¸å–多個人"/>
+ <button label="將所é¸çš„從å單移除" name="remove_button" tool_tip="將上é¢æ‰€é¸å±…民從邀請å單中移除"/>
<text name="role_text">
- Choose what Role to assign them to:
+ é¸æ“‡æŒ‡æ´¾çµ¦ä»–們的角色:
</text>
- <combo_box name="role_name" tool_tip="Choose from the list of Roles you are allowed to assign members to"/>
+ <combo_box name="role_name" tool_tip="從角色清單é¸æ“‡ä½ æœ‰æ¬ŠæŒ‡æ´¾çµ¦æˆå“¡çš„角色:"/>
<button label="é€å‡ºé‚€è«‹" name="ok_button"/>
<button label="å–消" name="cancel_button"/>
<string name="GroupInvitation">
diff --git a/indra/newview/skins/default/xui/zh/panel_group_land_money.xml b/indra/newview/skins/default/xui/zh/panel_group_land_money.xml
index 5ac7410c8b..81d5573e1c 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_group_land_money.xml
+++ b/indra/newview/skins/default/xui/zh/panel_group_land_money.xml
@@ -1,16 +1,16 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel label="Land &amp; L$" name="land_money_tab">
+<panel label="土地和 L$" name="land_money_tab">
<panel.string name="help_text">
- A warning appears until the Total Land in Use is less than or = to the Total Contribution.
+ å°‡æŒçºŒå‡ºç¾è­¦ç¤ºï¼Œç›´åˆ°ä½¿ç”¨ä¸­ç¸½åœŸåœ°å°æ–¼æˆ–等於總貢ç»é¢ç©ç‚ºæ­¢ã€‚
</panel.string>
<panel.string name="cant_view_group_land_text">
- You don&apos;t have permission to view group owned land
+ 你無權察看群組所有地。
</panel.string>
<panel.string name="epmty_view_group_land_text">
沒有項目
</panel.string>
<panel.string name="cant_view_group_accounting_text">
- You don&apos;t have permission to view the group&apos;s accounting information.
+ 你無權察看該群組的帳目資料。
</panel.string>
<panel.string name="loading_txt">
載入中...
@@ -27,42 +27,42 @@
<scroll_list.columns label="éš±è—" name="hidden"/>
</scroll_list>
<text name="total_contributed_land_label">
- Total contribution:
+ 總貢ç»ï¼š
</text>
<text name="total_contributed_land_value">
- [AREA] m²
+ [AREA] 平方公尺
</text>
<button label="地圖" label_selected="地圖" name="map_button"/>
<text name="total_land_in_use_label">
- Total land in use:
+ 使用中土地總é¢ç©ï¼š
</text>
<text name="total_land_in_use_value">
- [AREA] m²
+ [AREA] 平方公尺
</text>
<text name="land_available_label">
- Land available:
+ å¯ç”¨åœŸåœ°ï¼š
</text>
<text name="land_available_value">
- [AREA] m²
+ [AREA] 平方公尺
</text>
<text name="your_contribution_label">
ä½ çš„æç»ï¼š
</text>
<text name="your_contribution_units">
- m²
+ 平方公尺
</text>
<text name="your_contribution_max_value">
([AMOUNT] 最大)
</text>
<text name="group_over_limit_text">
- More land credits are needed to support land in use
+ 使用中土地需è¦æ›´å¤§çš„土地é¡åº¦
</text>
<text name="group_money_heading">
群組 L$
</text>
</panel>
<tab_container name="group_money_tab_container">
- <panel label="PLANNING" name="group_money_planning_tab">
+ <panel label="策劃" name="group_money_planning_tab">
<text_editor name="group_money_planning_text">
載入中...
</text_editor>
@@ -71,15 +71,15 @@
<text_editor name="group_money_details_text">
載入中...
</text_editor>
- <button name="earlier_details_button" tool_tip="Back"/>
- <button name="later_details_button" tool_tip="Next"/>
+ <button name="earlier_details_button" tool_tip="返回"/>
+ <button name="later_details_button" tool_tip="下一個"/>
</panel>
<panel label="銷售" name="group_money_sales_tab">
<text_editor name="group_money_sales_text">
載入中...
</text_editor>
- <button name="earlier_sales_button" tool_tip="Back"/>
- <button name="later_sales_button" tool_tip="Next"/>
+ <button name="earlier_sales_button" tool_tip="返回"/>
+ <button name="later_sales_button" tool_tip="下一個"/>
</panel>
</tab_container>
</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_group_list_item.xml b/indra/newview/skins/default/xui/zh/panel_group_list_item.xml
index 175293cdf7..fec4bb572a 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_group_list_item.xml
+++ b/indra/newview/skins/default/xui/zh/panel_group_list_item.xml
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel name="group_list_item">
<text name="group_name" value="未知"/>
+ <button name="info_btn" tool_tip="詳情"/>
<button name="profile_btn" tool_tip="察看檔案"/>
</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_group_notices.xml b/indra/newview/skins/default/xui/zh/panel_group_notices.xml
index 26273dd9ce..ba5f4f1bba 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_group_notices.xml
+++ b/indra/newview/skins/default/xui/zh/panel_group_notices.xml
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel label="通知" name="notices_tab">
<panel.string name="help_text">
- Notices let you send a message and an optionally attached item.
-Notices only go to group members in Roles with the ability to receive Notices.
-You can turn off Notices on the General tab.
+ 通知å¯è®“你傳é€è¨Šæ¯ä¸¦é¸æ“‡æ€§åœ°é™„上一個附件。
+通知僅能傳給å¯æŽ¥æ”¶é€šçŸ¥çš„角色的群組æˆå“¡ã€‚
+ä½ å¯åˆ°åŸºæœ¬è³‡æ–™é ç±¤åœç”¨é€šçŸ¥åŠŸèƒ½ã€‚
</panel.string>
<panel.string name="no_notices_text">
沒有éŽåŽ»çš„通知
@@ -21,7 +21,7 @@ You can turn off Notices on the General tab.
沒發ç¾ã€‚
</text>
<button label="新通知" name="create_new_notice" tool_tip="建立一個新通知"/>
- <button name="refresh_notices" tool_tip="Refresh list of notices"/>
+ <button name="refresh_notices" tool_tip="刷新通知清單。"/>
<panel label="建立新通知" name="panel_create_new_notice">
<text name="lbl">
建立一個通知
@@ -36,19 +36,19 @@ You can turn off Notices on the General tab.
附件:
</text>
<text name="string">
- 將物å“拖曳並丟於此處以添加為附件:
+ 拖曳並置放物å“到這裡,å³å¯æ·»åŠ ç‚ºé™„件:
</text>
<button label="收ç´å€" name="open_inventory" tool_tip="開啟收ç´å€"/>
<button name="remove_attachment" tool_tip="由你的通知移除附件"/>
<button label="é€å‡º" label_selected="é€å‡º" name="send_notice"/>
- <group_drop_target name="drop_target" tool_tip="Drag an inventory item onto this target box to send it with this notice. You must have permission to copy and transfer the item in order to attach it."/>
+ <group_drop_target name="drop_target" tool_tip="將一個收ç´å€ç‰©é …拖曳到這個目標箱框,便å¯éš¨é€šçŸ¥é€å‡ºè©²ç‰©é …。 你必須有權複製並轉移此物項,æ‰å¯ä»¥é™„加它。"/>
</panel>
<panel label="察看éŽåŽ»çš„通知" name="panel_view_past_notice">
<text name="lbl">
存檔的通知
</text>
<text name="lbl2">
- è¦é€å‡ºä¸€å€‹æ–°é€šçŸ¥ï¼Œé»žæ“Š + 按鈕
+ è¦é€å‡ºä¸€å€‹æ–°é€šçŸ¥ï¼Œé»žæŒ‰ + 按鈕
</text>
<text name="lbl3">
主旨:
diff --git a/indra/newview/skins/default/xui/zh/panel_group_notify.xml b/indra/newview/skins/default/xui/zh/panel_group_notify.xml
index 00462d8b0b..08a8c94876 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_group_notify.xml
+++ b/indra/newview/skins/default/xui/zh/panel_group_notify.xml
@@ -3,10 +3,10 @@
<string name="message_max_lines_count" value="7"/>
<string name="subject_font" value="SANSSERIF_BIG"/>
<string name="date_font" value="SANSSERIF"/>
- <panel label="header" name="header">
- <text name="title" value="Sender Name / Group Name"/>
+ <panel label="表頭" name="header">
+ <text name="title" value="發件者å/群組å"/>
</panel>
<text_editor name="message" value="訊æ¯"/>
- <text name="attachment" value="Attachment"/>
+ <text name="attachment" value="附件"/>
<button label="確定" name="btn_ok"/>
</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_group_roles.xml b/indra/newview/skins/default/xui/zh/panel_group_roles.xml
index cf5fc26d14..59086c3de2 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_group_roles.xml
+++ b/indra/newview/skins/default/xui/zh/panel_group_roles.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel label="æˆå“¡èˆ‡è§’色" name="roles_tab">
<panel.string name="default_needs_apply_text">
- 未儲存的設定
+ 變更未儲存
</panel.string>
<panel.string name="want_apply_text">
ä½ è¦å„²å­˜ä½ çš„變更嗎?
@@ -11,10 +11,10 @@
<panel.string name="help_text">
ä½ å¯ä»¥æ·»åŠ æˆ–移除一個角色指派給æˆå“¡ã€‚
é¸è²¬å¤šå€‹æˆå“¡æ™‚åŒæ™‚按著 Ctrl éµä¸”
-使用滑鼠左éµé»žæ“Šä»–們的å字。
+使用滑鼠左éµé»žæŒ‰ä»–們的å字。
</panel.string>
<panel.string name="donation_area">
- [AREA] m²
+ [AREA] 平方公尺
</panel.string>
<filter_editor label="æˆå“¡éŽæ¿¾å™¨" name="filter_input"/>
<name_list name="member_list">
@@ -27,13 +27,12 @@
</panel>
<panel label="角色" name="roles_sub_tab">
<panel.string name="help_text">
- Roles have a title and an allowed list of Abilities
-that Members can perform. Members can belong to
-one or more Roles. A group can have up to 10 Roles,
-including the Everyone and Owner Roles.
+ 一個角色具備è·ç¨±å’Œè©²è§’色å¯ä½¿ç”¨çš„能力。
+一ä½æˆå“¡å¯æœ‰ä¸€åˆ°å¤šå€‹è§’色。
+一個群組至多å¯æœ‰ 10 個角色,包括「任何人ã€å’Œã€Œæ‰€æœ‰äººã€ã€‚
</panel.string>
<panel.string name="cant_delete_role">
- The &apos;Everyone&apos; and &apos;Owners&apos; Roles are special and can&apos;t be deleted.
+ 「任何人ã€å’Œã€Œæ‰€æœ‰äººã€æ˜¯ç‰¹è¨­è§’色,ä¸å¾—刪除。
</panel.string>
<filter_editor label="角色éŽæ¿¾å™¨" name="filter_input"/>
<scroll_list name="role_list">
@@ -44,13 +43,13 @@ including the Everyone and Owner Roles.
<button label="新角色" name="role_create"/>
<button label="刪除角色" name="role_delete"/>
</panel>
- <panel label="能力" name="actions_sub_tab" tool_tip="You can view an Ability&apos;s Description and which Roles and Members can execute the Ability.">
+ <panel label="能力" name="actions_sub_tab" tool_tip="ä½ å¯å¯Ÿçœ‹é—œæ–¼æŸä¸€èƒ½åŠ›çš„說明,並得知哪些角色和æˆå“¡æ“有該能力。">
<panel.string name="help_text">
- Abilities allow Members in Roles to do specific
-things in this group. There&apos;s a broad variety of Abilities.
+ 「能力ã€å¯è®“群組的æˆå“¡é€éŽè§’色行使一定的è·æ¬Šã€‚
+能力的種類ç¹å¤šã€‚
</panel.string>
<filter_editor label="能力éŽæ¿¾å™¨" name="filter_input"/>
- <scroll_list name="action_list" tool_tip="Select an Ability to view more details"/>
+ <scroll_list name="action_list" tool_tip="è«‹é¸å–一個能力以察看詳情。"/>
</panel>
</tab_container>
<panel name="members_footer">
@@ -60,7 +59,7 @@ things in this group. There&apos;s a broad variety of Abilities.
<text name="static2">
å…許的能力
</text>
- <scroll_list name="member_allowed_actions" tool_tip="想瞭解有關於å…許的能力的細節請查閱能力é ç±¤"/>
+ <scroll_list name="member_allowed_actions" tool_tip="想瞭解æ¯ä¸€é …å…許的能力的詳情請查閱能力é ç±¤ã€‚"/>
</panel>
<panel name="roles_footer">
<text name="static">
@@ -75,15 +74,15 @@ things in this group. There&apos;s a broad variety of Abilities.
<text name="static4">
指派角色
</text>
- <check_box label="Reveal members" name="role_visible_in_list" tool_tip="Sets whether members of this role are visible in the General tab to people outside of the group."/>
+ <check_box label="顯示æˆå“¡" name="role_visible_in_list" tool_tip="設定是å¦è®“群組外的人在「一般ã€é ç±¤ä¸Šå¯Ÿçœ‹åˆ°æ­¤è§’色的æˆå“¡ã€‚"/>
<text name="static5">
å…許的能力
</text>
- <scroll_list name="role_allowed_actions" tool_tip="想瞭解有關於æ¯ä¸€é …å…許的能力的細節請查閱能力é ç±¤"/>
+ <scroll_list name="role_allowed_actions" tool_tip="想瞭解æ¯ä¸€é …å…許的能力的詳情請查閱能力é ç±¤ã€‚"/>
</panel>
<panel name="actions_footer">
<text_editor name="action_description">
- This Ability is &apos;Eject Members from this Group&apos;. Only an Owner can eject another Owner.
+ 這個能力å¯ã€Œå°‡æœƒå“¡è‡ªæœ¬ç¾¤çµ„踢出ã€ã€‚ 必須是所有人æ‰å¯è¸¢å‡ºå¦ä¸€ä½æ‰€æœ‰äººã€‚
</text_editor>
<text name="static2">
有此能力的角色
diff --git a/indra/newview/skins/default/xui/zh/panel_im_control_panel.xml b/indra/newview/skins/default/xui/zh/panel_im_control_panel.xml
index 703182e04d..e937368a2b 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_im_control_panel.xml
+++ b/indra/newview/skins/default/xui/zh/panel_im_control_panel.xml
@@ -8,7 +8,7 @@
<button label="加為朋å‹" name="add_friend_btn"/>
</layout_panel>
<layout_panel name="teleport_btn_panel">
- <button label="瞬間傳é€" name="teleport_btn" tool_tip="Offer to teleport this person"/>
+ <button label="瞬間傳é€" name="teleport_btn" tool_tip="發出瞬間傳é€é‚€è«‹çµ¦æ­¤äºº"/>
</layout_panel>
<layout_panel name="share_btn_panel">
<button label="分享" name="share_btn"/>
diff --git a/indra/newview/skins/default/xui/zh/panel_instant_message.xml b/indra/newview/skins/default/xui/zh/panel_instant_message.xml
index cf9bc7fccb..cf9bc7fccb 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_instant_message.xml
+++ b/indra/newview/skins/default/xui/zh/panel_instant_message.xml
diff --git a/indra/newview/skins/default/xui/zh/panel_inventory_item.xml b/indra/newview/skins/default/xui/zh/panel_inventory_item.xml
index d18047fbcf..d18047fbcf 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_inventory_item.xml
+++ b/indra/newview/skins/default/xui/zh/panel_inventory_item.xml
diff --git a/indra/newview/skins/default/xui/zh/panel_landmark_info.xml b/indra/newview/skins/default/xui/zh/panel_landmark_info.xml
index d86ba7bc7c..b50aa24d3f 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_landmark_info.xml
+++ b/indra/newview/skins/default/xui/zh/panel_landmark_info.xml
@@ -3,22 +3,22 @@
<string name="title_create_landmark" value="創造地標"/>
<string name="title_edit_landmark" value="編輯地標"/>
<string name="title_landmark" value="地標"/>
- <string name="not_available" value="(N\A)"/>
+ <string name="not_available" value="(ä¸é©ç”¨ï¼‰"/>
<string name="unknown" value="(未知)"/>
<string name="public" value="(公開)"/>
<string name="server_update_text">
- Place information not available without server update.
+ 地點資訊因無伺æœå™¨æ›´æ–°æ•…無法æ供。
</string>
<string name="server_error_text">
- Information about this location is unavailable at this time, please try again later.
+ ç›®å‰ç„¡æ³•å–å¾—æ­¤ä½ç½®çš„訊æ¯ï¼Œè«‹ç¨å€™å†è©¦ã€‚
</string>
<string name="server_forbidden_text">
- Information about this location is unavailable due to access restrictions. Please check your permissions with the parcel owner.
+ 權é™ä¸è¶³ï¼Œç„¡æ³•å–å¾—æ­¤ä½ç½®çš„資訊。 è«‹å‘地段所有人查詢你的權é™ã€‚
</string>
<string name="acquired_date">
[wkday,datetime,local] [mth,datetime,local] [day,datetime,local] [hour,datetime,local]:[min,datetime,local]:[second,datetime,local] [year,datetime,local]
</string>
- <button name="back_btn" tool_tip="Back"/>
+ <button name="back_btn" tool_tip="返回"/>
<text name="title" value="地點檔案"/>
<scroll_container name="place_scroll">
<panel name="scrolling_panel">
@@ -27,13 +27,13 @@
<expandable_text name="description" value="Du waltz die spritz"/>
<text name="maturity_value" value="未知"/>
<panel name="landmark_info_panel">
- <text name="owner_label" value="æ“有者:"/>
+ <text name="owner_label" value="所有人:"/>
<text name="creator_label" value="創造者:"/>
<text name="created_label" value="創造於:"/>
</panel>
<panel name="landmark_edit_panel">
- <text name="title_label" value="Title:"/>
- <text name="notes_label" value="My notes:"/>
+ <text name="title_label" value="標題:"/>
+ <text name="notes_label" value="我的記事:"/>
<text name="folder_label" value="地標ä½ç½®ï¼š"/>
</panel>
</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_landmarks.xml b/indra/newview/skins/default/xui/zh/panel_landmarks.xml
index eea406170a..eea406170a 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_landmarks.xml
+++ b/indra/newview/skins/default/xui/zh/panel_landmarks.xml
diff --git a/indra/newview/skins/default/xui/zh/panel_login.xml b/indra/newview/skins/default/xui/zh/panel_login.xml
index b227fbcfc8..672d9bb1a2 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_login.xml
+++ b/indra/newview/skins/default/xui/zh/panel_login.xml
@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel name="panel_login">
- <panel.string name="create_account_url">
- http://join.secondlife.com/
- </panel.string>
<panel.string name="forgot_password_url">
http://secondlife.com/account/request.php
</panel.string>
<layout_stack name="login_widgets">
<layout_panel name="login">
+ <text name="log_in_text">
+ 登入
+ </text>
<text name="username_text">
使用者å稱:
</text>
@@ -15,34 +15,32 @@
<text name="password_text">
密碼:
</text>
- <check_box label="記ä½å¯†ç¢¼ï¼š" name="remember_check"/>
- <button label="登入" name="connect_btn"/>
- <text name="mode_selection_text">
- 模å¼ï¼š
- </text>
- <combo_box name="mode_combo" tool_tip="è«‹é¸æ“‡ä½ çš„模å¼ã€‚é¸ç”¨åŸºæœ¬æ¨¡å¼å¯ä»¥å¿«é€Ÿã€ç°¡å–®åœ°æŽ¢ç´¢èˆ‡èŠå¤©ï¼›é¸ç”¨é€²éšŽæ¨¡å¼å‰‡å¯ä»¥ä½¿ç”¨æ›´å¤šåŠŸèƒ½ã€‚">
- <combo_box.item label="基本" name="Basic"/>
- <combo_box.item label="進階" name="Advanced"/>
- </combo_box>
+ </layout_panel>
+ <layout_panel name="start_location_panel">
<text name="start_location_text">
開始地點:
</text>
<combo_box name="start_location_combo">
<combo_box.item label="我上一次ä½ç½®" name="MyLastLocation"/>
<combo_box.item label="我的家" name="MyHome"/>
- <combo_box.item label="&lt; 請輸入地å€å稱 &gt;" name="Typeregionname"/>
+ <combo_box.item label="&lt;請輸入地å€å稱&gt;" name="Typeregionname"/>
</combo_box>
</layout_panel>
- <layout_panel name="links">
- <text name="create_new_account_text">
- 註冊
+ <layout_panel name="links_login_panel">
+ <text name="login_help">
+ 登入時需è¦å¹«åŠ©ï¼Ÿ
</text>
<text name="forgot_password_text">
忘記你的使用者å稱或密碼?
</text>
- <text name="login_help">
- 登入時需è¦å¹«åŠ©ï¼Ÿ
+ <button label="登入" name="connect_btn"/>
+ <check_box label="記ä½å¯†ç¢¼ï¼š" name="remember_check"/>
+ </layout_panel>
+ <layout_panel name="links">
+ <text name="create_account_text">
+ 建立你的帳號
</text>
+ <button label="ç¾åœ¨å°±é–‹å§‹" name="create_new_account_btn"/>
</layout_panel>
</layout_stack>
</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_main_inventory.xml b/indra/newview/skins/default/xui/zh/panel_main_inventory.xml
index 53ecf3eb19..0ad3d8506d 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_main_inventory.xml
+++ b/indra/newview/skins/default/xui/zh/panel_main_inventory.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel label="事物" name="main inventory panel">
<panel.string name="ItemcountFetching">
- Fetching [ITEM_COUNT] Items... [FILTER]
+ æ­£åœ¨æ“·å– [ITEM_COUNT] 個物項… [FILTER]
</panel.string>
<panel.string name="ItemcountCompleted">
[ITEM_COUNT] ç‰©å“ [FILTER]
diff --git a/indra/newview/skins/default/xui/zh/panel_me.xml b/indra/newview/skins/default/xui/zh/panel_me.xml
index a236dfc17a..aad1348e46 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_me.xml
+++ b/indra/newview/skins/default/xui/zh/panel_me.xml
@@ -1,7 +1,4 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel label="我的檔案" name="panel_me">
- <tab_container name="tabs">
- <panel label="我的檔案" name="panel_profile"/>
- <panel label="我的精é¸åœ°é»ž" name="panel_picks"/>
- </tab_container>
+<panel label="我的個人檔案" name="panel_me">
+ <panel label="我的精é¸åœ°é»ž" name="panel_picks"/>
</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_media_settings_general.xml b/indra/newview/skins/default/xui/zh/panel_media_settings_general.xml
index 321c003acd..0c11befcf5 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_media_settings_general.xml
+++ b/indra/newview/skins/default/xui/zh/panel_media_settings_general.xml
@@ -1,28 +1,28 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel label="一般" name="Media Settings General">
+<panel label="基本設定" name="Media Settings General">
<text name="home_label">
首é ï¼š
</text>
<text name="home_fails_whitelist_label">
- (This page does not pass the specified whitelist)
+ (這é é¢æœªé€šéŽæ‰€æŒ‡å®šçš„許å¯æ¸…單)
</text>
- <line_editor name="home_url" tool_tip="The home page for this media source"/>
+ <line_editor name="home_url" tool_tip="這個媒體來æºçš„首é "/>
<text name="preview_label">
é è¦½
</text>
<text name="current_url_label">
ç›®å‰é é¢ï¼š
</text>
- <text name="current_url" tool_tip="The current page for this media source" value=""/>
+ <text name="current_url" tool_tip="這個媒體來æºç›®å‰çš„é é¢" value=""/>
<button label="é‡è¨­" name="current_url_reset_btn"/>
- <check_box initial_value="false" label="Auto Loop" name="auto_loop"/>
- <check_box initial_value="false" label="First Click Interacts" name="first_click_interact"/>
+ <check_box initial_value="false" label="自動連續播放" name="auto_loop"/>
+ <check_box initial_value="false" label="第一次點擊將進行互動" name="first_click_interact"/>
<check_box initial_value="false" label="自動縮放" name="auto_zoom"/>
<check_box initial_value="false" label="自動播放媒體" name="auto_play"/>
<text name="media_setting_note">
- Note: Residents can override this setting
+ 注æ„:居民å¯ä»¥å¦å®šé€™é …設定
</text>
- <check_box initial_value="false" label="Auto Scale Media on Face of Object" name="auto_scale"/>
+ <check_box initial_value="false" label="物件臉部媒體自動調整比例" name="auto_scale"/>
<text name="size_label">
尺寸:
</text>
diff --git a/indra/newview/skins/default/xui/zh/panel_media_settings_permissions.xml b/indra/newview/skins/default/xui/zh/panel_media_settings_permissions.xml
index 173edc76f6..4a1eaef3a1 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_media_settings_permissions.xml
+++ b/indra/newview/skins/default/xui/zh/panel_media_settings_permissions.xml
@@ -12,7 +12,7 @@
</combo_item>
</combo_box>
<text name="owner_label">
- æ“有者
+ 所有人
</text>
<check_box initial_value="false" label="å…許導航與互動" name="perms_owner_interact"/>
<check_box initial_value="false" label="顯示控制列" name="perms_owner_control"/>
diff --git a/indra/newview/skins/default/xui/zh/panel_media_settings_security.xml b/indra/newview/skins/default/xui/zh/panel_media_settings_security.xml
index aaaf6bfb94..da84d6fe02 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_media_settings_security.xml
+++ b/indra/newview/skins/default/xui/zh/panel_media_settings_security.xml
@@ -1,12 +1,12 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel label="Security" name="Media Settings Security">
- <check_box initial_value="false" label="Only Allow Access to Specified URL patterns" name="whitelist_enable"/>
+<panel label="安全" name="Media Settings Security">
+ <check_box initial_value="false" label="åªå…許進入符åˆç‰¹å®šå½¢æ…‹çš„ URL 目標" name="whitelist_enable"/>
<text name="home_url_fails_some_items_in_whitelist">
- Entries that the home page fails against are marked:
+ 被首é è¦–為出錯的物項已標示:
</text>
<button label="添加" name="whitelist_add"/>
<button label="刪除" name="whitelist_del"/>
<text name="home_url_fails_whitelist">
- Warning: the home page specified in the General tab fails to pass this whitelist. It has been disabled until a valid entry has been added.
+ 警告:在基本資料é ç±¤è£¡æŒ‡å®šçš„首é ï¼Œæœªèƒ½é€šéŽé€™ä¸€è¨±å¯æ¸…單。 它已被åœç”¨ï¼Œè«‹è¨­å®šæœ‰æ•ˆçš„資料。
</text>
</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_navigation_bar.xml b/indra/newview/skins/default/xui/zh/panel_navigation_bar.xml
index 60a5767d09..7a11aa961b 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_navigation_bar.xml
+++ b/indra/newview/skins/default/xui/zh/panel_navigation_bar.xml
@@ -1,18 +1,23 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel name="navigation_bar">
- <panel name="navigation_panel">
- <pull_button name="back_btn" tool_tip="å‰å¾€ä¸Šä¸€å€‹ä½ç½®"/>
- <pull_button name="forward_btn" tool_tip="å‰å¾€ä¸‹ä¸€å€‹ä½ç½®"/>
- <button name="home_btn" tool_tip="瞬間傳é€åˆ°æˆ‘家的ä½ç½®"/>
- <location_input label="ä½ç½®" name="location_combo"/>
- <search_combo_box label="æœå°‹" name="search_combo_box" tool_tip="æœå°‹">
- <combo_editor label="æœå°‹ [SECOND_LIFE]" name="search_combo_editor"/>
- </search_combo_box>
- </panel>
- <favorites_bar name="favorite" tool_tip="拖曳傳é€åœ°æ¨™åˆ°æ­¤ä»¥ä¾¿è®“你在第二人生中能快速傳é€åˆ°ä½ æœ€æ„›çš„地點!!">
- <label name="favorites_bar_label" tool_tip="拖曳傳é€åœ°æ¨™åˆ°æ­¤ä»¥ä¾¿è®“你在第二人生中能快速傳é€åˆ°ä½ æœ€æ„›çš„地點!!">
- 最愛列
- </label>
- <chevron_button name="&gt;&gt;" tool_tip="顯示更多我的最愛"/>
- </favorites_bar>
+ <layout_stack name="nvp_stack">
+ <layout_panel name="navigation_layout_panel">
+ <panel name="navigation_panel">
+ <pull_button name="back_btn" tool_tip="å‰å¾€ä¸Šä¸€å€‹ä½ç½®"/>
+ <pull_button name="forward_btn" tool_tip="å‰å¾€ä¸‹ä¸€å€‹ä½ç½®"/>
+ <button name="home_btn" tool_tip="瞬間返回我的家"/>
+ <location_input label="ä½ç½®" name="location_combo"/>
+ </panel>
+ </layout_panel>
+ <layout_panel name="favorites_layout_panel">
+ <favorites_bar name="favorite" tool_tip="拖曳傳é€åœ°æ¨™åˆ°æ­¤ä»¥ä¾¿è®“你在第二人生中能快速傳é€åˆ°ä½ æœ€æ„›çš„地點!!">
+ <label name="favorites_bar_label" tool_tip="拖曳傳é€åœ°æ¨™åˆ°æ­¤ä»¥ä¾¿è®“你在第二人生中能快速傳é€åˆ°ä½ æœ€æ„›çš„地點!!">
+ 最愛列
+ </label>
+ <more_button name="&gt;&gt;" tool_tip="顯示更多我的最愛">
+ 詳情 ▼
+ </more_button>
+ </favorites_bar>
+ </layout_panel>
+ </layout_stack>
</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_navmesh_rebake.xml b/indra/newview/skins/default/xui/zh/panel_navmesh_rebake.xml
new file mode 100755
index 0000000000..bb52c13a11
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/panel_navmesh_rebake.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_navmesh_rebake">
+ <button label="é‡æ–°ç”¢å‡ºåœ°å€" name="navmesh_btn" tool_tip="點按å³å¯é‡æ–°ç”¢å‡ºè©²åœ°å€çš„導航網é¢ã€‚"/>
+ <button label="正在請求é‡æ–°ç”¢å‡º" name="navmesh_btn_sending" tool_tip="æ­£å‘伺æœå™¨ç™¼é€é‡æ–°ç”¢å‡ºè«‹æ±‚。"/>
+ <button label="地å€æ­£åœ¨é‡æ–°ç”¢å‡º" name="navmesh_btn_baking" tool_tip="地å€æ­£åœ¨é‡æ–°ç”¢å‡ºã€‚ 完æˆå¾Œï¼Œé€™å€‹æŒ‰éˆ•å°‡æœƒæ¶ˆå¤±ã€‚"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_nearby_chat.xml b/indra/newview/skins/default/xui/zh/panel_nearby_chat.xml
new file mode 100755
index 0000000000..fc52168bb7
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/panel_nearby_chat.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="nearby_chat">
+ <layout_stack name="stack">
+ <layout_panel name="translate_chat_checkbox_lp">
+ <check_box label="翻譯èŠå¤©å…§å®¹" name="translate_chat_checkbox"/>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_nearby_chat_bar.xml b/indra/newview/skins/default/xui/zh/panel_nearby_chat_bar.xml
index 3cabfcfaba..9489113d09 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_nearby_chat_bar.xml
+++ b/indra/newview/skins/default/xui/zh/panel_nearby_chat_bar.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel name="chat_bar">
- <line_editor label="點擊此處開始èŠå¤©ã€‚" name="chat_box" tool_tip="按下 Enter éµä¾†èªªæˆ–按下 Ctrl+Enter 來喊å«"/>
+<panel name="nearby_chat">
+ <line_editor label="點按此處開始èŠå¤©ã€‚" name="chat_box" tool_tip="按下 Enter éµä¾†èªªæˆ–按下 Ctrl+Enter 來喊å«"/>
<button name="show_nearby_chat" tool_tip="顯示 / éš±è— é™„è¿‘çš„èŠå¤©ç´€éŒ„"/>
</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_nearby_media.xml b/indra/newview/skins/default/xui/zh/panel_nearby_media.xml
index 6a4b5fcf35..c11a7a088b 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_nearby_media.xml
+++ b/indra/newview/skins/default/xui/zh/panel_nearby_media.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel name="nearby_media">
<string name="media_item_count_format">
- (%ld media items)
+ (%ld 項媒體物件)
</string>
<string name="empty_item_text">
- &lt;empty&gt;
+ &lt;空白&gt;
</string>
<string name="parcel_media_name">
地段串æµåª’é«”
@@ -18,8 +18,8 @@
<panel name="minimized_controls">
<button label="全部åœæ­¢" name="all_nearby_media_disable_btn" tool_tip="關閉附近全部的媒體"/>
<button label="全部開始" name="all_nearby_media_enable_btn" tool_tip="開啟附近全部的媒體"/>
- <button name="open_prefs_btn" tool_tip="Bring up media prefs"/>
- <button label="更多 &gt;&gt;" label_selected="&lt;&lt; 更少" name="more_btn" tool_tip="進階控制"/>
+ <button name="open_prefs_btn" tool_tip="打開媒體å好設定"/>
+ <button label="細節&gt;&gt;" label_selected="&lt;&lt;基本" name="more_btn" tool_tip="進階控制"/>
</panel>
<panel name="nearby_media_panel">
<text name="nearby_media_title">
@@ -35,9 +35,9 @@
<combo_box.item label="在其他化身身上" name="OnOthers"/>
</combo_box>
<scroll_list name="media_list">
- <scroll_list.columns label="Proximity" name="media_proximity"/>
- <scroll_list.columns label="Visible" name="media_visibility"/>
- <scroll_list.columns label="Class" name="media_class"/>
+ <scroll_list.columns label="é„°è¿‘" name="media_proximity"/>
+ <scroll_list.columns label="å¯çœ‹åˆ°" name="media_visibility"/>
+ <scroll_list.columns label="é¡žåž‹" name="media_class"/>
<scroll_list.columns label="å稱" name="media_name"/>
<scroll_list.columns label="除錯" name="media_debug"/>
</scroll_list>
@@ -59,10 +59,10 @@
<button name="mute_btn" tool_tip="éœéŸ³æ‰€é¸æ“‡çš„媒體音頻"/>
</layout_panel>
<layout_panel name="zoom">
- <button name="zoom_btn" tool_tip="Zoom into selected media"/>
+ <button name="zoom_btn" tool_tip="以所é¸åª’體為中心放大"/>
</layout_panel>
<layout_panel name="unzoom">
- <button name="unzoom_btn" tool_tip="Zoom back from selected media"/>
+ <button name="unzoom_btn" tool_tip="縮å°é é›¢æ‰€é¸åª’é«”"/>
</layout_panel>
</layout_stack>
</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_notify_textbox.xml b/indra/newview/skins/default/xui/zh/panel_notify_textbox.xml
index 01a8210338..01a8210338 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_notify_textbox.xml
+++ b/indra/newview/skins/default/xui/zh/panel_notify_textbox.xml
diff --git a/indra/newview/skins/default/xui/zh/panel_online_status_toast.xml b/indra/newview/skins/default/xui/zh/panel_online_status_toast.xml
index a5d3afccb9..a5d3afccb9 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_online_status_toast.xml
+++ b/indra/newview/skins/default/xui/zh/panel_online_status_toast.xml
diff --git a/indra/newview/skins/default/xui/zh/panel_outbox_inventory.xml b/indra/newview/skins/default/xui/zh/panel_outbox_inventory.xml
new file mode 100755
index 0000000000..8de0bb0e4d
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/panel_outbox_inventory.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<outbox_inventory_panel name="inventory_outbox" tool_tip="將物項拖曳並置放到這裡,準備在你的商店出售"/>
diff --git a/indra/newview/skins/default/xui/zh/panel_outfit_edit.xml b/indra/newview/skins/default/xui/zh/panel_outfit_edit.xml
index 263106d13a..a698da0ab1 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_outfit_edit.xml
+++ b/indra/newview/skins/default/xui/zh/panel_outfit_edit.xml
@@ -5,7 +5,7 @@
<string name="unsaved_changes" value="變更未儲存"/>
<string name="now_editing" value="ç¾åœ¨ç·¨è¼¯ä¸­"/>
<panel.string name="not_available">
- (N\A)
+ (ä¸é©ç”¨ï¼‰
</panel.string>
<panel.string name="unknown">
(未知)
@@ -15,7 +15,7 @@
<string name="Filter.Objects" value="物件"/>
<string name="Filter.Clothing" value="æœè£"/>
<string name="Filter.Bodyparts" value="身體部ä½"/>
- <string name="replace_body_part" value="點擊以å–代你ç¾å­˜çš„體形"/>
+ <string name="replace_body_part" value="點按以å–代你ç¾å­˜çš„體形"/>
<text name="title" value="編輯è£æ‰®"/>
<panel name="header_panel">
<panel name="outfit_name_and_status">
@@ -39,10 +39,10 @@
</layout_panel>
</layout_stack>
<panel name="no_add_wearables_button_bar">
- <button name="shop_btn_1" tool_tip="Visit the SL Marketplace. You can also select something you are wearing, then click here to see more things like it"/>
+ <button name="shop_btn_1" tool_tip="å‰å¾€ç¬¬äºŒäººç”Ÿè³¼ç‰©å¸‚集。 你也å¯é¸æ“‡ä½ ç©¿è‘—中的一個物件,å†é»žæŒ‰é€™è£¡å¯Ÿçœ‹å…¶ä»–åŒé¡žç‰©ä»¶ã€‚"/>
</panel>
<panel name="add_wearables_button_bar">
- <button name="shop_btn_2" tool_tip="Visit the SL Marketplace. You can also select something you are wearing, then click here to see more things like it"/>
+ <button name="shop_btn_2" tool_tip="å‰å¾€ç¬¬äºŒäººç”Ÿè³¼ç‰©å¸‚集。 你也å¯é¸æ“‡ä½ ç©¿è‘—中的一個物件,å†é»žæŒ‰é€™è£¡å¯Ÿçœ‹å…¶ä»–åŒé¡žç‰©ä»¶ã€‚"/>
</panel>
<panel name="save_revert_button_bar">
<layout_stack name="button_bar_ls">
@@ -50,7 +50,7 @@
<button label="儲存" name="save_btn"/>
</layout_panel>
<layout_panel name="revert_btn_lp">
- <button label="復原變更" name="revert_btn" tool_tip="Revert to last saved version"/>
+ <button label="復原變更" name="revert_btn" tool_tip="æ¢å¾©ä¸Šä¸€å€‹å·²å„²å­˜ç‰ˆæœ¬"/>
</layout_panel>
</layout_stack>
</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_outfits_inventory.xml b/indra/newview/skins/default/xui/zh/panel_outfits_inventory.xml
index d9718d8294..8dd93543c0 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_outfits_inventory.xml
+++ b/indra/newview/skins/default/xui/zh/panel_outfits_inventory.xml
@@ -4,19 +4,19 @@
穿上所é¸æ“‡çš„è£æ‰®
</panel.string>
<panel.string name="wear_items_tooltip">
- Wear selected items
+ 穿上所é¸æ“‡çš„物件
</panel.string>
<tab_container name="appearance_tabs">
<panel label="我的è£æ‰®" name="outfitslist_tab"/>
- <panel label="WEARING" name="cof_tab"/>
+ <panel label="ç›®å‰ç©¿è‘—" name="cof_tab"/>
</tab_container>
<panel name="bottom_panel">
<layout_stack name="bottom_panel_ls">
<layout_panel name="save_btn_lp">
- <button label="å¦å­˜" name="save_btn"/>
+ <button label="å¦å­˜ç‚º" name="save_btn"/>
</layout_panel>
<layout_panel name="wear_btn_lp">
- <button label="Wear" name="wear_btn"/>
+ <button label="穿上" name="wear_btn"/>
</layout_panel>
</layout_stack>
</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_outfits_inventory_gear_default.xml b/indra/newview/skins/default/xui/zh/panel_outfits_inventory_gear_default.xml
index 92ec774f9b..92ec774f9b 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_outfits_inventory_gear_default.xml
+++ b/indra/newview/skins/default/xui/zh/panel_outfits_inventory_gear_default.xml
diff --git a/indra/newview/skins/default/xui/zh/panel_outfits_list.xml b/indra/newview/skins/default/xui/zh/panel_outfits_list.xml
index a4b041469b..cfb0180f9c 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_outfits_list.xml
+++ b/indra/newview/skins/default/xui/zh/panel_outfits_list.xml
@@ -1,5 +1,9 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel name="Outfits">
+ <accordion name="outfits_accordion">
+ <no_matched_tabs_text name="no_matched_outfits_msg" value="找ä¸åˆ°ä½ è¦æ‰¾çš„嗎? 請試試 [secondlife:///app/search/places/ æœå°‹]。"/>
+ <no_visible_tabs_text name="no_outfits_msg" value="你還沒有任何è£æ‰®ã€‚ 請試試[secondlife:///app/search/all/ æœå°‹]"/>
+ </accordion>
<panel name="bottom_panel">
<menu_button name="options_gear_btn" tool_tip="顯示é¡å¤–é¸é …"/>
<button name="trash_btn" tool_tip="刪除所é¸æ“‡çš„è£æ‰®"/>
diff --git a/indra/newview/skins/default/xui/zh/panel_outfits_wearing.xml b/indra/newview/skins/default/xui/zh/panel_outfits_wearing.xml
index 693cdcdeca..693cdcdeca 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_outfits_wearing.xml
+++ b/indra/newview/skins/default/xui/zh/panel_outfits_wearing.xml
diff --git a/indra/newview/skins/default/xui/zh/panel_people.xml b/indra/newview/skins/default/xui/zh/panel_people.xml
index 9c265622fa..da5918d553 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_people.xml
+++ b/indra/newview/skins/default/xui/zh/panel_people.xml
@@ -1,94 +1,69 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<!-- Side tray panel -->
<panel label="人群" name="people_panel">
- <string name="no_recent_people" value="No recent people. Looking for people to hang out with? Try [secondlife:///app/search/people Search] or the [secondlife:///app/worldmap World Map]."/>
- <string name="no_filtered_recent_people" value="Didn&apos;t find what you&apos;re looking for? Try [secondlife:///app/search/people/[SEARCH_TERM] Search]."/>
- <string name="no_one_near" value="No one nearby. Looking for people to hang out with? Try [secondlife:///app/search/people Search] or the [secondlife:///app/worldmap World Map]."/>
- <string name="no_one_filtered_near" value="Didn&apos;t find what you&apos;re looking for? Try [secondlife:///app/search/people/[SEARCH_TERM] Search]."/>
+ <string name="no_recent_people" value="沒有最近的人。 想找人見é¢èŠå¤©ï¼Ÿ 請試試[secondlife:///app/search/people æœå°‹]或[secondlife:///app/worldmap 世界地圖]。"/>
+ <string name="no_filtered_recent_people" value="找ä¸åˆ°ä½ è¦æ‰¾çš„嗎? 請試試[secondlife:///app/search/people/[SEARCH_TERM] æœå°‹]。"/>
+ <string name="no_one_near" value="附近無人。 想找人見é¢èŠå¤©ï¼Ÿ 請試試[secondlife:///app/search/people æœå°‹]或[secondlife:///app/worldmap 世界地圖]。"/>
+ <string name="no_one_filtered_near" value="找ä¸åˆ°ä½ è¦æ‰¾çš„嗎? 請試試[secondlife:///app/search/people/[SEARCH_TERM] æœå°‹]。"/>
<string name="no_friends_online" value="無朋å‹ä¸Šç·š"/>
<string name="no_friends" value="無朋å‹"/>
<string name="no_friends_msg">
- Find friends using [secondlife:///app/search/people Search] or right-click on a Resident to add them as a friend.
-Looking for people to hang out with? Try the [secondlife:///app/worldmap World Map].
+ 用 [secondlife:///app/search/people æœå°‹] 找朋å‹ï¼Œæˆ–é¸æ“‡ä¸€ä½å±…民,å†æŒ‰å³éµå°‡ä»–加為朋å‹ã€‚
+想找人見é¢èŠå¤©ï¼Ÿ 請試一試 [secondlife:///app/worldmap 世界地圖]。
</string>
<string name="no_filtered_friends_msg">
- Didn&apos;t find what you&apos;re looking for? Try [secondlife:///app/search/people/[SEARCH_TERM] Search].
+ 找ä¸åˆ°ä½ è¦æ‰¾çš„嗎? 請試試[secondlife:///app/search/people/[SEARCH_TERM] æœå°‹]。
</string>
- <string name="people_filter_label" value="人員éŽæ¿¾å™¨"/>
- <string name="groups_filter_label" value="群組éŽæ¿¾å™¨"/>
- <string name="no_filtered_groups_msg" value="沒有發ç¾ä½ è¦æ‰¾çš„嗎?何ä¸è©¦è©¦ [secondlife:///app/search/groups/[SEARCH_TERM] æœå°‹]。"/>
- <string name="no_groups_msg" value="想找尋群組加入嗎?何ä¸è©¦è©¦ [secondlife:///app/search/groups æœå°‹]。"/>
+ <string name="no_filtered_groups_msg" value="找ä¸åˆ°ä½ è¦æ‰¾çš„嗎? 請試試[secondlife:///app/search/groups/[SEARCH_TERM] æœå°‹]。"/>
+ <string name="no_groups_msg" value="è¦å°‹æ‰¾ç¾¤çµ„考慮加入嗎? 請試試[secondlife:///app/search/groups æœå°‹]。"/>
<string name="MiniMapToolTipMsg" value="[REGION](雙擊以開啟地圖,按下 shift éµæ‹–曳來平移)"/>
<string name="AltMiniMapToolTipMsg" value="[REGION](雙擊以瞬間傳é€ï¼ŒæŒ‰ä¸‹ shift éµæ‹–曳來平移)"/>
- <filter_editor label="éŽæ¿¾å™¨" name="filter_input"/>
<tab_container name="tabs">
<panel label="附近" name="nearby_panel">
- <panel label="bottom_panel" name="bottom_panel">
- <menu_button name="nearby_view_sort_btn" tool_tip="é¸é …"/>
- <button name="add_friend_btn" tool_tip="添加已é¸æ“‡çš„居民到Ad你的朋å‹æ¸…å–®"/>
+ <panel label="bottom_panel" name="nearby_buttons_panel">
+ <filter_editor label="人員éŽæ¿¾å™¨" name="nearby_filter_input"/>
+ <button name="gear_btn" tool_tip="å°é¸å–的人採å–動作"/>
+ <menu_button name="nearby_view_btn" tool_tip="檢視/排åºçš„é¸é …"/>
+ <button name="add_friend_btn" tool_tip="å‘æŸä½å±…民發出交å‹é‚€è«‹"/>
+ <dnd_button name="nearby_del_btn" tool_tip="å°‡é¸å–的人從朋å‹å單移除"/>
</panel>
</panel>
- <panel label="我的朋å‹" name="friends_panel">
+ <panel label="朋å‹" name="friends_panel">
+ <panel label="bottom_panel" name="friends_buttons_panel">
+ <filter_editor label="人員éŽæ¿¾å™¨" name="friends_filter_input"/>
+ <button name="gear_btn" tool_tip="å°é¸å–的人採å–動作"/>
+ <menu_button name="friends_view_btn" tool_tip="檢視/排åºçš„é¸é …"/>
+ <button name="friends_add_btn" tool_tip="å‘æŸä½å±…民發出交å‹é‚€è«‹"/>
+ <dnd_button name="friends_del_btn" tool_tip="å°‡é¸å–的人從朋å‹å單移除"/>
+ </panel>
<accordion name="friends_accordion">
<accordion_tab name="tab_online" title="上線"/>
<accordion_tab name="tab_all" title="全部"/>
</accordion>
- <panel label="bottom_panel" name="bottom_panel">
- <layout_stack name="bottom_panel">
- <layout_panel name="options_gear_btn_panel">
- <menu_button name="friends_viewsort_btn" tool_tip="顯示é¡å¤–é¸é …"/>
- </layout_panel>
- <layout_panel name="add_btn_panel">
- <button name="add_btn" tool_tip="å‘å±…æ°‘æ出加為好å‹é‚€è«‹"/>
- </layout_panel>
- <layout_panel name="trash_btn_panel">
- <dnd_button name="del_btn" tool_tip="由你的朋å‹æ¸…單移除所é¸æ“‡çš„人"/>
- </layout_panel>
- </layout_stack>
- </panel>
</panel>
- <panel label="我的群組" name="groups_panel">
- <panel label="bottom_panel" name="bottom_panel">
- <menu_button name="groups_viewsort_btn" tool_tip="é¸é …"/>
- <button name="plus_btn" tool_tip="加入群組/創立新群組"/>
- <button name="activate_btn" tool_tip="啟用所é¸æ“‡çš„群組"/>
+ <panel label="群組" name="groups_panel">
+ <panel label="bottom_panel" name="groups_buttons_panel">
+ <filter_editor label="群組éŽæ¿¾å™¨" name="groups_filter_input"/>
+ <menu_button name="groups_gear_btn" tool_tip="å°æ‰€é¸ç¾¤çµ„採å–動作"/>
+ <menu_button name="groups_view_btn" tool_tip="檢視/排åºçš„é¸é …"/>
+ <menu_button name="plus_btn" tool_tip="加入群組/創立新群組"/>
+ <dnd_button name="minus_btn" tool_tip="離開所é¸ç¾¤çµ„"/>
</panel>
+ <text name="groupcount">
+ ä½ ç›®å‰å±¬æ–¼ [COUNT] 個群組,å¯å†åŠ å…¥ [REMAINING] 個。
+ </text>
</panel>
<panel label="最近" name="recent_panel">
- <panel label="bottom_panel" name="bottom_panel">
- <menu_button name="recent_viewsort_btn" tool_tip="é¸é …"/>
- <button name="add_friend_btn" tool_tip="添加所é¸çš„居民到你的朋å‹æ¸…å–®"/>
+ <panel label="bottom_panel" name="recent_buttons_panel">
+ <filter_editor label="人員éŽæ¿¾å™¨" name="recent_filter_input"/>
+ <button name="gear_btn" tool_tip="å°é¸å–的人採å–動作"/>
+ <menu_button name="recent_view_btn" tool_tip="檢視/排åºçš„é¸é …"/>
+ <button name="add_friend_btn" tool_tip="å‘æŸä½å±…民發出交å‹é‚€è«‹"/>
+ <dnd_button name="recent_del_btn" tool_tip="å°‡é¸å–的人從朋å‹å單移除"/>
</panel>
</panel>
+ <panel label="å·²å°éŽ–çš„" name="blocked_panel">
+ <panel label="被å°éŽ–的居民與物件" name="panel_block_list_sidetray"/>
+ </panel>
</tab_container>
- <panel name="button_bar">
- <layout_stack name="bottom_bar_ls">
- <layout_panel name="view_profile_btn_lp">
- <button label="檔案" name="view_profile_btn" tool_tip="顯示圖片ã€ç¾¤çµ„與其他居民資訊"/>
- </layout_panel>
- <layout_panel name="chat_btn_lp">
- <button label="IM" name="im_btn" tool_tip="é–‹å•Ÿå³æ™‚訊æ¯æœƒè©±"/>
- </layout_panel>
- <layout_panel name="chat_btn_lp">
- <button label="通話" name="call_btn" tool_tip="與此居民進行通話"/>
- </layout_panel>
- <layout_panel name="chat_btn_lp">
- <button label="分享" name="share_btn" tool_tip="分享一個收ç´å€ç‰©å“"/>
- </layout_panel>
- <layout_panel name="chat_btn_lp">
- <button label="瞬間傳é€" name="teleport_btn" tool_tip="發給瞬間傳é€è«‹æ±‚"/>
- </layout_panel>
- </layout_stack>
- <layout_stack name="bottom_bar_ls1">
- <layout_panel name="group_info_btn_lp">
- <button label="群組檔案" name="group_info_btn" tool_tip="顯示群組資訊"/>
- </layout_panel>
- <layout_panel name="chat_btn_lp">
- <button label="群組èŠå¤©" name="chat_btn" tool_tip="é–‹å•ŸèŠå¤©æœƒè©±"/>
- </layout_panel>
- <layout_panel name="group_call_btn_lp">
- <button label="群組通話" name="group_call_btn" tool_tip="與此群組進行通話"/>
- </layout_panel>
- </layout_stack>
- </panel>
</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_pick_info.xml b/indra/newview/skins/default/xui/zh/panel_pick_info.xml
index cd4cdbf999..cd4cdbf999 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_pick_info.xml
+++ b/indra/newview/skins/default/xui/zh/panel_pick_info.xml
diff --git a/indra/newview/skins/default/xui/zh/panel_picks.xml b/indra/newview/skins/default/xui/zh/panel_picks.xml
index 15733b71b0..98d36eaea0 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_picks.xml
+++ b/indra/newview/skins/default/xui/zh/panel_picks.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel label="ç²¾é¸åœ°é»ž" name="panel_picks">
<string name="no_picks" value="ç„¡ç²¾é¸åœ°é»ž"/>
- <string name="no_classifieds" value="No Classifieds"/>
+ <string name="no_classifieds" value="ç¦æ­¢å€‹äººå»£å‘Š"/>
<accordion name="accordion">
<accordion_tab name="tab_picks" title="ç²¾é¸åœ°é»ž"/>
- <accordion_tab name="tab_classifieds" title="Classifieds"/>
+ <accordion_tab name="tab_classifieds" title="個人廣告"/>
</accordion>
<panel label="bottom_panel" name="edit_panel">
<layout_stack name="edit_panel_ls">
diff --git a/indra/newview/skins/default/xui/zh/panel_place_profile.xml b/indra/newview/skins/default/xui/zh/panel_place_profile.xml
index 1772b65434..a364f732d8 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_place_profile.xml
+++ b/indra/newview/skins/default/xui/zh/panel_place_profile.xml
@@ -1,20 +1,20 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel name="place_profile">
- <string name="on" value="On"/>
- <string name="off" value="Off"/>
- <string name="anyone" value="Anyone"/>
- <string name="available" value="available"/>
+ <string name="on" value="å•Ÿå‹•"/>
+ <string name="off" value="關閉"/>
+ <string name="anyone" value="任何人"/>
+ <string name="available" value="å¯ç”¨çš„"/>
<string name="allocated" value="已分é…"/>
<string name="title_place" value="地點檔案"/>
<string name="title_teleport_history" value="瞬間傳é€æ­·å²ç´€éŒ„"/>
- <string name="not_available" value="(N\A)"/>
+ <string name="not_available" value="(ä¸é©ç”¨ï¼‰"/>
<string name="unknown" value="(未知)"/>
<string name="public" value="(公開)"/>
<string name="none_text" value="(無)"/>
<string name="sale_pending_text" value="(擱置銷售)"/>
- <string name="group_owned_text" value="(群組所æ“有)"/>
+ <string name="group_owned_text" value="(由群組所æ“有)"/>
<string name="price_text" value="L$"/>
- <string name="area_text" value="m²"/>
+ <string name="area_text" value="平方公尺"/>
<string name="all_residents_text" value="全部居民"/>
<string name="group_text" value="群組"/>
<string name="can_resell">
@@ -33,10 +33,10 @@
地點資訊因無伺æœå™¨æ›´æ–°æ•…無法æ供。
</string>
<string name="server_error_text">
- Information about this location is unavailable at this time, please try again later.
+ ç›®å‰ç„¡æ³•å–å¾—æ­¤ä½ç½®çš„訊æ¯ï¼Œè«‹ç¨å€™å†è©¦ã€‚
</string>
<string name="server_forbidden_text">
- Information about this location is unavailable due to access restrictions. Please check your permissions with the parcel owner.
+ 權é™ä¸è¶³ï¼Œç„¡æ³•å–å¾—æ­¤ä½ç½®çš„資訊。 è«‹å‘地段所有人查詢你的權é™ã€‚
</string>
<string name="acquired_date">
[wkday,datetime,local] [mth,datetime,local] [day,datetime,local] [hour,datetime,local]:[min,datetime,local]:[second,datetime,local] [year,datetime,local]
@@ -48,7 +48,7 @@
<text name="region_title" value="SampleRegion"/>
<text name="parcel_title" value="SampleParcel, Name Long (145, 228, 26)"/>
<expandable_text name="description" value="Du waltz die spritz"/>
- <text name="owner_label" value="æ“有者:"/>
+ <text name="owner_label" value="所有人:"/>
<text name="owner_value" value="Alex Superduperlongenamenton"/>
<text name="maturity_value" value="未知"/>
<accordion name="advanced_info_accordion">
@@ -57,18 +57,20 @@
<text name="rating_label" value="分級:"/>
<text name="rating_value" value="未知"/>
<text name="voice_label" value="語音:"/>
- <text name="voice_value" value="On"/>
+ <text name="voice_value" value="å•Ÿå‹•"/>
<text name="fly_label" value="飛行:"/>
- <text name="fly_value" value="On"/>
+ <text name="fly_value" value="å•Ÿå‹•"/>
<text name="push_label" value="推撞:"/>
- <text name="push_value" value="Off"/>
+ <text name="push_value" value="關閉"/>
<text name="build_label" value="建造:"/>
- <text name="build_value" value="On"/>
+ <text name="build_value" value="å•Ÿå‹•"/>
<text name="scripts_label" value="腳本:"/>
- <text name="scripts_value" value="On"/>
+ <text name="scripts_value" value="å•Ÿå‹•"/>
<text name="damage_label" value="傷害:"/>
- <text name="damage_value" value="Off"/>
- <button label="關於土地" name="about_land_btn"/>
+ <text name="damage_value" value="關閉"/>
+ <text name="see_avatars_label" value="察看化身:"/>
+ <text name="see_avatars_value" value="關閉"/>
+ <button label="土地資料" name="about_land_btn"/>
</panel>
</accordion_tab>
<accordion_tab name="region_information_tab" title="地å€">
@@ -79,21 +81,21 @@
<text name="region_type" value="Moose"/>
<text name="region_rating_label" value="分級:"/>
<text name="region_rating" value="完全æˆäºº"/>
- <text name="region_owner_label" value="æ“有者:"/>
+ <text name="region_owner_label" value="所有人:"/>
<text name="region_owner" value="moose Van Moose extra long name moose"/>
<text name="region_group_label" value="群組:"/>
<text name="region_group">
The Mighty Moose of mooseville soundvillemoose
</text>
- <button label="åœ°å€ / 領地" name="region_info_btn"/>
+ <button label="地å€/領地" name="region_info_btn"/>
</panel>
</accordion_tab>
<accordion_tab name="estate_information_tab" title="領地">
<panel name="estate_information_panel">
<text name="estate_name_label" value="領地:"/>
<text name="estate_rating_label" value="分級:"/>
- <text name="estate_owner_label" value="æ“有者:"/>
- <text name="estate_owner" value="Testing owner name length with long name"/>
+ <text name="estate_owner_label" value="所有人:"/>
+ <text name="estate_owner" value="正在測試å稱很長很長很長的所有人å稱…"/>
<text name="covenant_label" value="契約:"/>
</panel>
</accordion_tab>
diff --git a/indra/newview/skins/default/xui/zh/panel_places.xml b/indra/newview/skins/default/xui/zh/panel_places.xml
index 8ac464271e..08cae610f6 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_places.xml
+++ b/indra/newview/skins/default/xui/zh/panel_places.xml
@@ -8,7 +8,7 @@
<layout_panel name="lp1">
<layout_stack name="bottom_bar_ls1">
<layout_panel name="teleport_btn_lp">
- <button label="瞬間傳é€" name="teleport_btn" tool_tip="瞬間傳é€åˆ°æ‰€é¸æ“‡çš„å€åŸŸ"/>
+ <button label="瞬間傳é€" name="teleport_btn" tool_tip="瞬間傳é€åˆ°æ‰€é¸çš„å€åŸŸ"/>
</layout_panel>
<layout_panel name="chat_btn_lp">
<button label="地圖" name="map_btn" tool_tip="在世界地圖上顯示相å°æ‡‰çš„å€åŸŸ"/>
@@ -24,7 +24,7 @@
<menu_button name="overflow_btn" tool_tip="顯示é¡å¤–é¸é …"/>
</layout_panel>
</layout_stack>
- <layout_stack name="bottom_bar_ls3">
+ <layout_stack name="bottom_bar_profile_ls">
<layout_panel name="profile_btn_lp">
<button label="檔案" name="profile_btn" tool_tip="顯示地點檔案"/>
</layout_panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_postcard_message.xml b/indra/newview/skins/default/xui/zh/panel_postcard_message.xml
new file mode 100755
index 0000000000..563c4fca3c
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/panel_postcard_message.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_postcard_message">
+ <text name="to_label">
+ 收件人:
+ </text>
+ <text name="name_label">
+ 發件人:
+ </text>
+ <text name="subject_label">
+ 主旨:
+ </text>
+ <line_editor label="在此輸入你的主旨。" name="subject_form"/>
+ <text name="msg_label">
+ 訊æ¯ï¼š
+ </text>
+ <text_editor name="msg_form">
+ 在此輸入你的訊æ¯ã€‚
+ </text_editor>
+ <button label="å–消" name="cancel_btn"/>
+ <button label="é€å‡º" name="send_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_postcard_settings.xml b/indra/newview/skins/default/xui/zh/panel_postcard_settings.xml
new file mode 100755
index 0000000000..900ab3a54e
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/panel_postcard_settings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_postcard_settings">
+ <combo_box label="解æžåº¦" name="postcard_size_combo">
+ <combo_box.item label="ç›®å‰è¦–窗" name="CurrentWindow"/>
+ <combo_box.item label="640x480" name="640x480"/>
+ <combo_box.item label="800x600" name="800x600"/>
+ <combo_box.item label="1024x768" name="1024x768"/>
+ <combo_box.item label="自訂" name="Custom"/>
+ </combo_box>
+ <layout_stack name="postcard_image_params_ls">
+ <layout_panel name="postcard_image_size_lp">
+ <spinner label="寬" name="postcard_snapshot_width"/>
+ <spinner label="高度" name="postcard_snapshot_height"/>
+ <check_box label="鎖ä½æ¯”例" name="postcard_keep_aspect_check"/>
+ </layout_panel>
+ <layout_panel name="postcard_image_format_quality_lp">
+ <slider label="圖åƒå“質" name="image_quality_slider"/>
+ <text name="image_quality_level">
+ ([QLVL])
+ </text>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_preferences_advanced.xml b/indra/newview/skins/default/xui/zh/panel_preferences_advanced.xml
index c5dce10d63..3a7d79e04b 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_preferences_advanced.xml
+++ b/indra/newview/skins/default/xui/zh/panel_preferences_advanced.xml
@@ -3,6 +3,19 @@
<panel.string name="aspect_ratio_text">
[NUM]:[DEN]
</panel.string>
+ <text name="Cache:">
+ å¿«å–:
+ </text>
+ <spinner label="å¿«å–å¤§å° (64 - 9984MB)" name="cachesizespinner"/>
+ <text name="text_box5">
+ MB
+ </text>
+ <button label="清除快å–" label_selected="清除快å–" name="clear_cache"/>
+ <text name="Cache location">
+ å¿«å–ä½ç½®ï¼š
+ </text>
+ <button label="ç€è¦½" label_selected="ç€è¦½" name="set_cache"/>
+ <button label="é è¨­ä½ç½®" label_selected="é è¨­ä½ç½®" name="default_cache_location"/>
<text name="UI Size:">
使用者界é¢å°ºå¯¸ï¼š
</text>
diff --git a/indra/newview/skins/default/xui/zh/panel_preferences_alerts.xml b/indra/newview/skins/default/xui/zh/panel_preferences_alerts.xml
index 94eb3c1389..94eb3c1389 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_preferences_alerts.xml
+++ b/indra/newview/skins/default/xui/zh/panel_preferences_alerts.xml
diff --git a/indra/newview/skins/default/xui/zh/panel_preferences_chat.xml b/indra/newview/skins/default/xui/zh/panel_preferences_chat.xml
index 738c77fd08..b5cdddc252 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/zh/panel_preferences_chat.xml
@@ -1,57 +1,99 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel label="文字èŠå¤©" name="chat">
- <text name="font_size">
- 字型尺寸:
- </text>
- <radio_group name="chat_font_size">
- <radio_item label="å°" name="radio" value="0"/>
- <radio_item label="中" name="radio2" value="1"/>
- <radio_item label="大" name="radio3" value="2"/>
- </radio_group>
- <check_box initial_value="true" label="èŠå¤©æ™‚播放打字動作" name="play_typing_animation"/>
- <check_box label="當我離線時將收到的 IM 訊æ¯éƒµå¯„給我" name="send_im_to_email"/>
- <check_box label="啟用純本文 IM 與èŠå¤©æ­·å²ç´€éŒ„" name="plain_text_chat_history"/>
- <check_box label="èŠå¤©æ³¡æ³¡" name="bubble_text_chat"/>
- <text name="show_ims_in_label">
- 顯示 IMs 於:
- </text>
- <text name="requires_restart_label">
- (須é‡æ–°å•Ÿå‹•ï¼‰
- </text>
- <radio_group name="chat_window" tool_tip="顯示你的å³æ™‚訊æ¯åœ¨åˆ†é–‹çš„浮動視窗,或是使用很多é ç±¤çš„單一浮動視窗(須é‡æ–°å•Ÿå‹•ï¼‰">
- <radio_item label="分開視窗" name="radio" value="0"/>
- <radio_item label="é ç±¤" name="radio2" value="1"/>
- </radio_group>
- <text name="disable_toast_label">
- 啟用傳入èŠå¤©çš„çªé¡¯ç¤ºè¦–窗:
- </text>
- <check_box label="群組èŠå¤©" name="EnableGroupChatPopups" tool_tip="當群組èŠå¤©è¨Šæ¯æŠµé”時查看çªé¡¯å¼è¦–窗"/>
- <check_box label="IM èŠå¤©" name="EnableIMChatPopups" tool_tip="當å³æ™‚訊æ¯æŠµé”時查看çªé¡¯å¼è¦–窗"/>
- <spinner label="Nearby chat toasts life time:" name="nearby_toasts_lifetime"/>
- <spinner label="Nearby chat toasts fading time:" name="nearby_toasts_fadingtime"/>
- <text name="translate_chb_label">
- èŠå¤©æ™‚使用機器自動進行翻譯
- </text>
- <text name="translate_language_text">
- èŠå¤©ç¿»è­¯ç‚ºï¼š
- </text>
- <combo_box name="translate_language_combobox">
- <combo_box.item label="系統é è¨­" name="System Default Language"/>
- <combo_box.item label="English" name="English"/>
- <combo_box.item label="Dansk (Danish)" name="Danish"/>
- <combo_box.item label="Deutsch (German)" name="German"/>
- <combo_box.item label="Español (Spanish)" name="Spanish"/>
- <combo_box.item label="Français (French)" name="French"/>
- <combo_box.item label="Italiano (Italian)" name="Italian"/>
- <combo_box.item label="Magyar (Hungarian)" name="Hungarian"/>
- <combo_box.item label="Nederlands (Dutch)" name="Dutch"/>
- <combo_box.item label="Polski (Polish)" name="Polish"/>
- <combo_box.item label="Português (Portuguese)" name="Portugese"/>
- <combo_box.item label="РуÑÑкий (Russian)" name="Russian"/>
- <combo_box.item label="Türkçe (Turkish)" name="Turkish"/>
- <combo_box.item label="УкраїнÑька (Ukrainian)" name="Ukrainian"/>
- <combo_box.item label="中文 (正體) (Chinese)" name="Chinese"/>
- <combo_box.item label="日本語 (Japanese)" name="Japanese"/>
- <combo_box.item label="한국어 (Korean)" name="Korean"/>
- </combo_box>
+ <panel name="general_chat_settings">
+ <check_box initial_value="true" label="èŠå¤©æ™‚呈ç¾æ‰“字動作" name="play_typing_animation"/>
+ <check_box label="當我離線時將收到的 IM 訊æ¯éƒµå¯„給我" name="send_im_to_email"/>
+ <check_box label="åªå…許我的朋å‹å’Œç¾¤çµ„與我通話或 IM 給我" name="voice_call_friends_only_check"/>
+ <text name="font_size">
+ 字型大å°ï¼š
+ </text>
+ <combo_box name="chat_font_size">
+ <item label="å°" name="Small" value="0"/>
+ <item label="中" name="Medium" value="1"/>
+ <item label="大" name="Large" value="2"/>
+ </combo_box>
+ <check_box label="èŠå¤©æ³¡æ³¡" name="bubble_text_chat"/>
+ </panel>
+ <panel name="im_notification_settings">
+ <text name="friend_ims">
+ æœ‹å‹ IM:
+ </text>
+ <combo_box name="FriendIMOptions">
+ <item label="開啟交談視窗" name="OpenConversationsWindow" value="openconversations"/>
+ <item label="以çªé¡¯å¼è¦–窗顯示訊æ¯" name="PopUpMessage" value="toast"/>
+ <item label="Flash 工具列按鈕" name="FlashToolbarButton" value="flash"/>
+ <item label="無動作" name="NoAction" value="noaction"/>
+ </combo_box>
+ <check_box label="播放è²éŸ³" name="play_sound_friend_im"/>
+ <text name="non_friend_ims">
+ éžæœ‹å‹ IM:
+ </text>
+ <combo_box name="NonFriendIMOptions">
+ <item label="開啟交談視窗" name="OpenConversationsWindow" value="openconversations"/>
+ <item label="以çªé¡¯å¼è¦–窗顯示訊æ¯" name="PopUpMessage" value="toast"/>
+ <item label="Flash 工具列按鈕" name="FlashToolbarButton" value="flash"/>
+ <item label="無動作" name="NoAction" value="noaction"/>
+ </combo_box>
+ <check_box label="播放è²éŸ³" name="play_sound_non_friend_im"/>
+ <text name="conference_ims">
+ 多方交談 IM:
+ </text>
+ <combo_box name="ConferenceIMOptions">
+ <item label="開啟交談視窗" name="OpenConversationsWindow" value="openconversations"/>
+ <item label="以çªé¡¯å¼è¦–窗顯示訊æ¯" name="PopUpMessage" value="toast"/>
+ <item label="Flash 工具列按鈕" name="FlashToolbarButton" value="flash"/>
+ <item label="無動作" name="NoAction" value="noaction"/>
+ </combo_box>
+ <check_box label="播放è²éŸ³" name="play_sound_conference_im"/>
+ <text name="group_chat">
+ 群組èŠå¤©ï¼š
+ </text>
+ <combo_box name="GroupChatOptions">
+ <item label="開啟交談視窗" name="OpenConversationsWindow" value="openconversations"/>
+ <item label="以çªé¡¯å¼è¦–窗顯示訊æ¯" name="PopUpMessage" value="toast"/>
+ <item label="Flash 工具列按鈕" name="FlashToolbarButton" value="flash"/>
+ <item label="無動作" name="NoAction" value="noaction"/>
+ </combo_box>
+ <check_box label="播放è²éŸ³" name="play_sound_group_chat_im"/>
+ <text name="nearby_chat">
+ 附近的èŠå¤©ï¼š
+ </text>
+ <combo_box name="NearbyChatOptions">
+ <item label="開啟交談視窗" name="OpenConversationsWindow" value="openconversations"/>
+ <item label="以çªé¡¯å¼è¦–窗顯示訊æ¯" name="PopUpMessage" value="toast"/>
+ <item label="Flash 工具列按鈕" name="FlashToolBarButton" value="flash"/>
+ <item label="無動作" name="NoAction" value="noaction"/>
+ </combo_box>
+ <check_box label="播放è²éŸ³" name="play_sound_nearby_chat_im"/>
+ <text name="object_ims">
+ 來自物件的 IM:
+ </text>
+ <combo_box name="ObjectIMOptions">
+ <item label="開啟交談視窗" name="OpenConversationsWindow" value="openconversations"/>
+ <item label="以çªé¡¯å¼è¦–窗顯示訊æ¯" name="PopUpMessage" value="toast"/>
+ <item label="Flash 工具列按鈕" name="FlashToolBarButton" value="flash"/>
+ <item label="無動作" name="NoAction" value="noaction"/>
+ </combo_box>
+ <check_box label="播放è²éŸ³" name="play_sound_object_im"/>
+ <text name="notifications_alert">
+ è‹¥è¦æš«æ™‚åœæ­¢æ‰€æœ‰é€šçŸ¥ï¼Œè«‹è¨­å®šã€Œæºé€š &gt; 請勿打擾ã€ã€‚
+ </text>
+ </panel>
+ <panel name="play_sound_settings">
+ <text name="play_sound">
+ 播放è²éŸ³ï¼š
+ </text>
+ <check_box label="新交談" name="new_conversation"/>
+ <check_box label="語音通話來電" name="incoming_voice_call"/>
+ <check_box label="瞬間傳é€é‚€è«‹" name="teleport_offer"/>
+ <check_box label="收ç´ç‰©å“è´ˆé€" name="inventory_offer"/>
+ </panel>
+ <panel name="log_settings">
+ <button label="清空記錄…" name="clear_log"/>
+ <button label="刪除交談內容記錄…" name="delete_transcripts"/>
+ <button label="ç€è¦½â€¦" label_selected="ç€è¦½" name="log_path_button"/>
+ </panel>
+ <button label="翻譯…" name="ok_btn"/>
+ <button label="自動å–代…" name="autoreplace_showgui"/>
+ <button label="拼字檢查…" name="spellcheck_showgui"/>
</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_preferences_colors.xml b/indra/newview/skins/default/xui/zh/panel_preferences_colors.xml
index 8d92eadd20..6af4bb8970 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_preferences_colors.xml
+++ b/indra/newview/skins/default/xui/zh/panel_preferences_colors.xml
@@ -3,12 +3,12 @@
<text name="effects_color_textbox">
我的效果(é¸æ“‡æŒ‡æ¨™ï¼‰ï¼š
</text>
- <color_swatch name="effect_color_swatch" tool_tip="點擊以開啟é¡è‰²æŒ‘é¸å™¨"/>
+ <color_swatch name="effect_color_swatch" tool_tip="點按以開啟é¡è‰²æŒ‘é¸å™¨"/>
<text name="font_colors">
èŠå¤©å­—åž‹é¡è‰²ï¼š
</text>
<text name="text_box1">
- 自己
+ 我自己
</text>
<text name="text_box2">
其他人
@@ -22,11 +22,14 @@
<text name="text_box5">
錯誤
</text>
+ <text name="text_box10">
+ 直接
+ </text>
<text name="text_box7">
- æ“有者
+ 所有人
</text>
<text name="text_box9">
- URLs
+ URL
</text>
<text name="bubble_chat">
å稱標籤背景色(亦會影響èŠå¤©æ³¡æ³¡ï¼‰ï¼š
diff --git a/indra/newview/skins/default/xui/zh/panel_preferences_general.xml b/indra/newview/skins/default/xui/zh/panel_preferences_general.xml
index 6827fab6e6..044edbed70 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_preferences_general.xml
+++ b/indra/newview/skins/default/xui/zh/panel_preferences_general.xml
@@ -1,19 +1,22 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel label="一般" name="general_panel">
+<panel label="基本設定" name="general_panel">
<text name="language_textbox">
語言:
</text>
<combo_box name="language_combobox">
<combo_box.item label="系統é è¨­" name="System Default Language"/>
- <combo_box.item label="English (英語)" name="English"/>
- <combo_box.item label="Dansk (丹麥語) - Beta" name="Danish"/>
- <combo_box.item label="Deutsch (德語) - Beta" name="Deutsch(German)"/>
- <combo_box.item label="Español (西ç­ç‰™èªžï¼‰ - Beta" name="Spanish"/>
- <combo_box.item label="Français (法語) - Beta" name="French"/>
- <combo_box.item label="Italiano (義大利語) - Beta" name="Italian"/>
- <combo_box.item label="Polski (波蘭語) - Beta" name="Polish"/>
- <combo_box.item label="Português (葡è„牙語) - Beta" name="Portugese"/>
- <combo_box.item label="日本語 (日語) - Beta" name="(Japanese)"/>
+ <combo_box.item label="英語" name="English"/>
+ <combo_box.item label="Dansk(丹麥語)- 試用版" name="Danish"/>
+ <combo_box.item label="Deutsch(德語)- 試用版" name="Deutsch(German)"/>
+ <combo_box.item label="Español(西ç­ç‰™èªžï¼‰- 試用版" name="Spanish"/>
+ <combo_box.item label="Français(法語)- 試用版" name="French"/>
+ <combo_box.item label="Italiano(義大利語)- 試用版" name="Italian"/>
+ <combo_box.item label="Polski(波蘭語)- 試用版" name="Polish"/>
+ <combo_box.item label="Português(葡è„牙語)- 試用版" name="Portugese"/>
+ <combo_box.item label="РуÑÑкий(俄羅斯語)- 測試版" name="Russian"/>
+ <combo_box.item label="Türkçe(土耳其語)- 試用版" name="Turkish"/>
+ <combo_box.item label="日本語(日語)- 試用版" name="(Japanese)"/>
+ <combo_box.item label="正體中文 - 測試版" name="Traditional Chinese"/>
</combo_box>
<text name="language_textbox2">
(須é‡æ–°å•Ÿå‹•ï¼‰
@@ -38,15 +41,15 @@
å稱標籤:
</text>
<radio_group name="Name_Tag_Preference">
- <radio_item label="Off" name="radio" value="0"/>
- <radio_item label="On" name="radio2" value="1"/>
+ <radio_item label="關閉" name="radio" value="0"/>
+ <radio_item label="å•Ÿå‹•" name="radio2" value="1"/>
<radio_item label="簡短顯示" name="radio3" value="2"/>
</radio_group>
<check_box label="我的åå­—" name="show_my_name_checkbox1"/>
<check_box label="使用者å稱" name="show_slids" tool_tip="顯示使用者åç¨±ï¼Œå°±åƒ bobsmith123 這類的"/>
- <check_box label="群組頭銜" name="show_all_title_checkbox1" tool_tip="顯示群組頭銜,åƒæ˜¯ Officer 或æˆå“¡"/>
+ <check_box label="群組頭銜" name="show_all_title_checkbox1" tool_tip="顯示群組頭銜,如è·å“¡æˆ–æˆå“¡"/>
<check_box label="高亮標示朋å‹" name="show_friends" tool_tip="高亮顯示你朋å‹çš„å稱標籤"/>
- <check_box label="察看顯示å稱" name="display_names_check" tool_tip="Check to use display names in chat, IM, name tags, etc."/>
+ <check_box label="察看顯示å稱" name="display_names_check" tool_tip="若勾é¸ï¼Œå°‡åœ¨èŠå¤©ã€IM å’Œå稱標籤等處使用顯示å稱。"/>
<text name="inworld_typing_rg_label">
按下字æ¯éµï¼š
</text>
@@ -65,9 +68,9 @@
<combo_box.item label="絕ä¸" name="item4"/>
</combo_box>
<text name="text_box3">
- 忙碌模å¼å›žæ‡‰ï¼š
+ 「請勿打擾ã€é è¨­å›žæ‡‰ï¼š
</text>
- <text_editor name="busy_response">
+ <text_editor name="do_not_disturb_response">
log_in_to_change
</text_editor>
</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/zh/panel_preferences_graphics1.xml
index 874fb6b218..2311eb99a7 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_preferences_graphics1.xml
+++ b/indra/newview/skins/default/xui/zh/panel_preferences_graphics1.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel label="圖形" name="Display panel">
+<panel label="顯åƒ" name="Display panel">
<text name="QualitySpeed">
å“質與速度:
</text>
@@ -27,8 +27,20 @@
</text>
<check_box initial_value="true" label="清澈é€æ˜Žçš„æ°´" name="TransparentWater"/>
<check_box initial_value="true" label="凹凸映射與光澤效果" name="BumpShiny"/>
+ <check_box initial_value="true" label="本地光線" name="LocalLights"/>
<check_box initial_value="true" label="基本著色" name="BasicShaders" tool_tip="關閉此一é¸é …å¯èƒ½é¿å…部分顯示å¡é©…動程å¼æ毀當機"/>
<check_box initial_value="true" label="大氣著色" name="WindLightUseAtmosShaders"/>
+ <check_box initial_value="true" label="進階照明模型" name="UseLightShaders"/>
+ <check_box initial_value="true" label="環境光é®è”½" name="UseSSAO"/>
+ <check_box initial_value="true" label="景深" name="UseDoF"/>
+ <text name="shadows_label">
+ 陰影:
+ </text>
+ <combo_box name="ShadowDetail">
+ <combo_box.item label="ç„¡" name="0"/>
+ <combo_box.item label="日 / 月" name="1"/>
+ <combo_box.item label="日 / 月 + 投影物" name="2"/>
+ </combo_box>
<text name="reflection_label">
æ°´æ–‡å射:
</text>
@@ -45,11 +57,11 @@
</text>
<slider label="æ繪è·é›¢ï¼š" name="DrawDistance"/>
<text name="DrawDistanceMeterText2">
- m
+ 公尺
</text>
<slider label="最大粒å­æ•ˆæžœæ•¸é‡ï¼š" name="MaxParticleCount"/>
- <slider label="Max. # of non-impostor avatars:" name="MaxNumberAvatarDrawn"/>
- <slider label="後製å“質:" name="RenderPostProcess"/>
+ <slider label="éžå‡å†’化身上é™ï¼š" name="MaxNumberAvatarDrawn"/>
+ <slider label="後處ç†å“質:" name="RenderPostProcess"/>
<text name="MeshDetailText">
網é¢ç´°ç¯€ï¼š
</text>
@@ -81,10 +93,10 @@
低
</text>
<text name="AvatarRenderingText">
- Avatar Rendering:
+ 化身呈åƒï¼š
</text>
- <check_box initial_value="true" label="Avatar impostors" name="AvatarImpostors"/>
- <check_box initial_value="true" label="Hardware skinning" name="AvatarVertexProgram"/>
+ <check_box initial_value="true" label="化身å‡å†’者" name="AvatarImpostors"/>
+ <check_box initial_value="true" label="硬體æ›è†š" name="AvatarVertexProgram"/>
<check_box initial_value="true" label="化身衣æœ" name="AvatarCloth"/>
<text name="TerrainDetailText">
地形細節:
diff --git a/indra/newview/skins/default/xui/zh/panel_preferences_move.xml b/indra/newview/skins/default/xui/zh/panel_preferences_move.xml
index ce176b1e3c..3a27477885 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_preferences_move.xml
+++ b/indra/newview/skins/default/xui/zh/panel_preferences_move.xml
@@ -7,18 +7,33 @@
</text>
<check_box label="建造 / 編輯" name="edit_camera_movement" tool_tip="使用進入或離開編輯模å¼æ™‚自動調整æ”影機ä½ç½®åŠŸèƒ½"/>
<check_box label="編輯外觀" name="appearance_camera_movement" tool_tip="使用編輯模å¼æ™‚自動調整æ”影機ä½ç½®åŠŸèƒ½"/>
- <check_box initial_value="true" label="å´é‚Šæ¬„" name="appearance_sidebar_positioning" tool_tip="使用開啟å´é‚Šæ¬„時自動調整æ”影機ä½ç½®åŠŸèƒ½"/>
+ <text name="keyboard_lbl">
+ éµç›¤ï¼š
+ </text>
+ <check_box label="總是使用方å‘éµç§»å‹•" name="arrow_keys_move_avatar_check"/>
+ <check_box label="連點按ä½å¾Œè·‘æ­¥" name="tap_tap_hold_to_run"/>
+ <text name="mouse_lbl">
+ 滑鼠:
+ </text>
<check_box label="將我顯示於第一人稱視角中" name="first_person_avatar_visible"/>
<text name=" Mouse Sensitivity">
第一人稱視角滑鼠æ•æ„Ÿåº¦ï¼š
</text>
<check_box label="å轉" name="invert_mouse"/>
- <check_box label="總是使用方å‘éµç§»å‹•" name="arrow_keys_move_avatar_check"/>
- <check_box label="連點按ä½å¾Œè·‘æ­¥" name="tap_tap_hold_to_run"/>
- <check_box label="雙擊以:" name="double_click_chkbox"/>
- <radio_group name="double_click_action">
- <radio_item label="瞬間傳é€" name="radio_teleport"/>
- <radio_item label="自動導航駕駛" name="radio_autopilot"/>
- </radio_group>
+ <text name="single_click_action_lbl">
+ 在土地上點按一下:
+ </text>
+ <combo_box name="single_click_action_combo">
+ <combo_box.item label="無動作" name="0"/>
+ <combo_box.item label="移動至點按的地點" name="1"/>
+ </combo_box>
+ <text name="double_click_action_lbl">
+ 在土地上點按兩下:
+ </text>
+ <combo_box name="double_click_action_combo">
+ <combo_box.item label="無動作" name="0"/>
+ <combo_box.item label="移動至點按的地點" name="1"/>
+ <combo_box.item label="瞬間傳é€è‡³é»žæŒ‰çš„地點" name="2"/>
+ </combo_box>
<button label="其他設備" name="joystick_setup_button"/>
</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_preferences_privacy.xml b/indra/newview/skins/default/xui/zh/panel_preferences_privacy.xml
index 07fdfd87e3..07fdfd87e3 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_preferences_privacy.xml
+++ b/indra/newview/skins/default/xui/zh/panel_preferences_privacy.xml
diff --git a/indra/newview/skins/default/xui/zh/panel_preferences_setup.xml b/indra/newview/skins/default/xui/zh/panel_preferences_setup.xml
index efefb92df6..ab4d9a881d 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_preferences_setup.xml
+++ b/indra/newview/skins/default/xui/zh/panel_preferences_setup.xml
@@ -11,34 +11,17 @@
</text>
<check_box label="自訂埠" name="connection_port_enabled"/>
<spinner label="埠號:" name="connection_port"/>
- <text name="cache_size_label_l">
- å¿«å–尺寸
- </text>
- <text name="text_box5">
- MB
- </text>
- <text name="Cache location">
- å¿«å–ä½ç½®ï¼š
- </text>
- <button label="ç€è¦½" label_selected="ç€è¦½" name="set_cache"/>
- <button label="" label_selected="é‡è¨­" name="reset_cache"/>
<text name="Web:">
網é ï¼š
</text>
<radio_group name="use_external_browser">
- <radio_item label="使用我的網é ç€è¦½å™¨ï¼ˆä¾‹å¦‚ IE, Firefox, Safari)" name="external" tool_tip="Use the default system web browser for help, web links, etc. Not recommended if running full screen." value="1"/>
- <radio_item label="使用內建網é ç€è¦½å™¨" name="internal" tool_tip="Use the built-in web browser for help, web links, etc. This browser opens as a new window inside [APP_NAME]." value=""/>
+ <radio_item label="使用我的網é ç€è¦½å™¨ï¼ˆä¾‹å¦‚ IE, Firefox, Safari)" name="external" tool_tip="使用系統é è¨­çš„ç€è¦½å™¨ç€è¦½å¹«åŠ©ï¼Œé–‹å•Ÿç¶²é ã€‚全螢幕模å¼ä¸‹ä¸å»ºè­°é€™éº¼åšã€‚" value="true"/>
+ <radio_item label="使用內建網é ç€è¦½å™¨" name="internal" tool_tip="使用內建的ç€è¦½å™¨ç€è¦½å¹«åŠ©ï¼Œé–‹å•Ÿç¶²é ã€‚該ç€è¦½å™¨å°‡é€éŽ [APP_NAME] 開啟新視窗。" value=""/>
</radio_group>
<check_box initial_value="true" label="啟用外掛" name="browser_plugins_enabled"/>
<check_box initial_value="true" label="æŽ¥å— cookies" name="cookies_enabled"/>
<check_box initial_value="true" label="啟用 Javascript" name="browser_javascript_enabled"/>
<check_box initial_value="false" label="啟用媒體ç€è¦½çš„çªé¡¯å¼è¦–窗" name="media_popup_enabled"/>
- <check_box initial_value="false" label="啟用網é ä»£ç†ä¼ºæœå™¨" name="web_proxy_enabled"/>
- <text name="Proxy location">
- 代ç†ä¼ºæœå™¨ä½ç½®ï¼š
- </text>
- <line_editor name="web_proxy_editor" tool_tip="The name or IP address of the proxy you would like to use"/>
- <spinner label="埠號:" name="web_proxy_port"/>
<text name="Software updates:">
軟體更新:
</text>
@@ -46,4 +29,9 @@
<combo_box.item label="自動安è£" name="Install_automatically"/>
<combo_box.item label="手動下載åŠå®‰è£" name="Install_manual"/>
</combo_box>
+ <check_box label="願æ„在更新時æ¶å…ˆè©¦ç”¨é‡‹å‡ºå€™é¸ç‰ˆ" name="update_willing_to_test"/>
+ <text name="Proxy Settings:">
+ 代ç†ä¼ºæœå™¨è¨­å®šï¼š
+ </text>
+ <button label="調整代ç†ä¼ºæœå™¨è¨­å®š" label_selected="ç€è¦½" name="set_proxy"/>
</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_preferences_sound.xml b/indra/newview/skins/default/xui/zh/panel_preferences_sound.xml
index 3280b9357b..e57f08fd74 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_preferences_sound.xml
+++ b/indra/newview/skins/default/xui/zh/panel_preferences_sound.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel label="è²éŸ³" name="Preference Media panel">
<panel.string name="middle_mouse">
- Middle Mouse
+ 滑鼠中éµ
</panel.string>
<slider label="主音é‡" name="System Volume"/>
<check_box initial_value="true" name="mute_when_minimized"/>
@@ -18,7 +18,8 @@
<slider label="語音èŠå¤©" name="Voice Volume"/>
<check_box label="已啟用" name="enable_voice_check"/>
<check_box label="å…許媒體自動播放" name="media_auto_play_btn" tool_tip="若你想è¦ï¼Œå¯ä»¥å‹¾é¸é€™å€‹å…許媒體自動播放" value="true"/>
- <check_box label="播放附加到其他化身身上的媒體" name="media_show_on_others_btn" tool_tip="Uncheck this to hide media attached to other avatars nearby" value="true"/>
+ <check_box label="播放附加到其他化身身上的媒體" name="media_show_on_others_btn" tool_tip="若未勾é¸ï¼Œå°‡éš±è—附著於附近其他化身身上的媒體" value="true"/>
+ <check_box label="播放來自姿勢的è²éŸ³" name="gesture_audio_play_btn" tool_tip="勾é¸å³å¯è½åˆ°ä¾†è‡ªå§¿å‹¢çš„è²éŸ³" value="true"/>
<text name="voice_chat_settings">
語音èŠå¤©è¨­å®š
</text>
@@ -30,33 +31,10 @@
<radio_item label="化身ä½ç½®" name="1"/>
</radio_group>
<check_box label="說話時åŒæ­¥ç§»å‹•åŒ–身嘴唇" name="enable_lip_sync"/>
- <check_box label="Toggle speak on/off when I press:" name="push_to_talk_toggle_check" tool_tip="When in toggle mode, press and release the trigger key ONCE to switch your microphone on or off. When not in toggle mode, the microphone broadcasts your voice only while the trigger is being held down."/>
- <line_editor label="Push-to-Speak trigger" name="modifier_combo"/>
+ <check_box label="切æ›èªªè©± / éœéŸ³ï¼Œç•¶æˆ‘按下:" name="push_to_talk_toggle_check" tool_tip="在切æ›æ¨¡å¼ä¸‹ï¼ŒæŒ‰ä¸‹å†æ”¾é–‹å•Ÿå‹•éµä¸€æ¬¡ï¼Œå³å¯æ‰“開或關閉麥克風。 ä¸åœ¨åˆ‡æ›ç‹€æ…‹æ™‚,麥克風åªæœ‰åœ¨å•Ÿå‹•éµè¢«æŒ‰ä¸‹æ™‚æ‰æœƒæ”¾é€ä½ çš„è²éŸ³ã€‚"/>
+ <line_editor label="「按下後說話ã€å•Ÿå‹•éµ" name="modifier_combo"/>
<button label="設定按éµ" name="set_voice_hotkey_button"/>
<button name="set_voice_middlemouse_button" tool_tip="é‡è¨­æ»‘鼠中éµæŒ‰éˆ•"/>
<button label="輸入 / 輸出設備" name="device_settings_btn"/>
- <panel label="設備設定" name="device_settings_panel">
- <panel.string name="default_text">
- é è¨­
- </panel.string>
- <panel.string name="default system device">
- é è¨­ç³»çµ±è¨­å‚™
- </panel.string>
- <panel.string name="no device">
- 無設備
- </panel.string>
- <text name="Input">
- 輸入
- </text>
- <text name="My volume label">
- 我的音é‡ï¼š
- </text>
- <slider_bar initial_value="1.0" name="mic_volume_slider" tool_tip="Change the volume using this slider"/>
- <text name="wait_text">
- è«‹ç¨å€™
- </text>
- <text name="Output">
- 輸出
- </text>
- </panel>
+ <panel label="設備設定" name="device_settings_panel"/>
</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_prim_media_controls.xml b/indra/newview/skins/default/xui/zh/panel_prim_media_controls.xml
index df1a1b73a1..09043311da 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_prim_media_controls.xml
+++ b/indra/newview/skins/default/xui/zh/panel_prim_media_controls.xml
@@ -26,15 +26,15 @@
</string>
<layout_stack name="progress_indicator_area">
<layout_panel name="media_progress_indicator">
- <progress_bar name="media_progress_bar" tool_tip="Media is Loading"/>
+ <progress_bar name="media_progress_bar" tool_tip="媒體載入中"/>
</layout_panel>
</layout_stack>
<layout_stack name="media_controls">
<layout_panel name="back">
- <button name="back_btn" tool_tip="Navigate back"/>
+ <button name="back_btn" tool_tip="å‘後導覽"/>
</layout_panel>
<layout_panel name="fwd">
- <button name="fwd_btn" tool_tip="Navigate forward"/>
+ <button name="fwd_btn" tool_tip="å‘å‰å°Žè¦½"/>
</layout_panel>
<layout_panel name="home">
<button name="home_btn" tool_tip="首é "/>
@@ -61,31 +61,31 @@
<icon name="media_whitelist_flag" tool_tip="白å單已啟用"/>
</layout_panel>
<layout_panel>
- <icon name="media_secure_lock_flag" tool_tip="Secured Browsing"/>
+ <icon name="media_secure_lock_flag" tool_tip="加密的ç€è¦½"/>
</layout_panel>
</layout_stack>
</layout_panel>
<layout_panel name="media_play_position">
- <slider_bar initial_value="0.5" name="media_play_slider" tool_tip="Movie play progress"/>
+ <slider_bar initial_value="0.5" name="media_play_slider" tool_tip="影片播放進度"/>
</layout_panel>
<layout_panel name="skip_back">
- <button name="skip_back_btn" tool_tip="Step back"/>
+ <button name="skip_back_btn" tool_tip="倒轉"/>
</layout_panel>
<layout_panel name="skip_forward">
- <button name="skip_forward_btn" tool_tip="Step forward"/>
+ <button name="skip_forward_btn" tool_tip="快轉"/>
</layout_panel>
<layout_panel name="media_volume">
- <button name="media_mute_button" tool_tip="Mute This Media"/>
- <slider name="volume_slider" tool_tip="Media Volume"/>
+ <button name="media_mute_button" tool_tip="把這個媒體消音"/>
+ <slider name="volume_slider" tool_tip="媒體音é‡"/>
</layout_panel>
<layout_panel name="zoom_frame">
- <button name="zoom_frame_btn" tool_tip="Zoom into media"/>
+ <button name="zoom_frame_btn" tool_tip="以媒體為中心放大"/>
</layout_panel>
<layout_panel name="close">
- <button name="close_btn" tool_tip="Zoom Back"/>
+ <button name="close_btn" tool_tip="縮å°"/>
</layout_panel>
<layout_panel name="new_window">
- <button name="new_window_btn" tool_tip="Open URL in browser"/>
+ <button name="new_window_btn" tool_tip="用ç€è¦½å™¨é–‹å•Ÿ URL"/>
</layout_panel>
</layout_stack>
</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_region_covenant.xml b/indra/newview/skins/default/xui/zh/panel_region_covenant.xml
index ad94c4c7e9..d5dd337795 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_region_covenant.xml
+++ b/indra/newview/skins/default/xui/zh/panel_region_covenant.xml
@@ -1,16 +1,16 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel label="契約" name="Covenant">
<panel.string name="can_resell">
- Purchased land in this region may be resold.
+ 購買這地å€çš„土地å…許轉售。
</panel.string>
<panel.string name="can_not_resell">
- Purchased land in this region may not be resold.
+ 購買這地å€çš„土地ä¸å…許轉售。
</panel.string>
<panel.string name="can_change">
- Purchased land in this region may be joined or subdivided.
+ 購買這地å€çš„土地å…許進行åˆä½µæˆ–分割。
</panel.string>
<panel.string name="can_not_change">
- Purchased land in this region may not be joined or subdivided.
+ 購買這地å€çš„土地ä¸å…許進行åˆä½µæˆ–分割。
</panel.string>
<text name="estate_section_lbl">
領地
@@ -19,10 +19,10 @@
å稱:
</text>
<text name="estate_name_text">
- mainland
+ 大陸
</text>
<text name="estate_owner_lbl">
- æ“有者:
+ 所有人:
</text>
<text name="estate_owner_text">
(無)
@@ -31,17 +31,17 @@
契約:
</text>
<text name="covenant_timestamp_text">
- Last Modified Wed Dec 31 16:00:00 1969
+ 上次修改於 Wed Dec 31 16:00:00 1969
</text>
<text_editor name="covenant_editor">
- There is no Covenant provided for this Estate.
+ 此領地沒有任何契約è¦æ±‚。
</text_editor>
<button label="é‡è¨­" name="reset_covenant"/>
<text name="covenant_help_text">
- Changes to the covenant will show on all parcels in the estate.
+ 契約修訂內容將顯示於領地裡所有地段。
</text>
<text name="covenant_instructions">
- Drag and drop a notecard to change the Covenant for this estate.
+ 拖曳並置放一張記事å¡ï¼Œå³å¯ä¿®è¨‚領地契約。
</text>
<text name="region_section_lbl">
地å€
@@ -56,7 +56,7 @@
類型:
</text>
<text name="region_landtype_text">
- Mainland / Homestead
+ 大陸 / 家園
</text>
<text name="region_maturity_lbl">
分級:
diff --git a/indra/newview/skins/default/xui/zh/panel_region_debug.xml b/indra/newview/skins/default/xui/zh/panel_region_debug.xml
index ed5e6e9d2c..e5d5e6eaf7 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_region_debug.xml
+++ b/indra/newview/skins/default/xui/zh/panel_region_debug.xml
@@ -7,7 +7,7 @@
未知
</text>
<check_box label="關閉腳本" name="disable_scripts_check" tool_tip="關閉這個地å€ç¾åœ¨çš„全部腳本"/>
- <check_box label="關閉碰撞" name="disable_collisions_check" tool_tip="關閉這個地å€ç¾åœ¨çš„éžåŒ–身碰撞"/>
+ <check_box label="ç¦æ­¢ç¢°æ’ž" name="disable_collisions_check" tool_tip="關閉這個地å€ç¾åœ¨çš„éžåŒ–身碰撞"/>
<check_box label="關閉物ç†" name="disable_physics_check" tool_tip="關閉這個地å€ç¾åœ¨çš„全部物ç†"/>
<button label="套用" name="apply_btn"/>
<text name="objret_text_lbl">
@@ -28,7 +28,7 @@
<check_box label="於這個領地內的æ¯ä¸€å€‹åœ°å€" name="return_estate_wide" tool_tip="退回這個領地內全部地å€ä¸­æ¨™è¨˜ç‚ºä»–的物件"/>
<button label="退回" name="return_btn"/>
<button label="å–得最常碰撞的物件..." name="top_colliders_btn" tool_tip="æ¢åˆ—出目å‰é‹ä½œä¸­æœ€å¸¸ç¢°æ’žçš„物件清單"/>
- <button label="å–得最耗能腳本..." name="top_scripts_btn" tool_tip="æ¢åˆ—出目å‰é‹ä½œä¸­æœ€è€—能的腳本清單"/>
+ <button label="å–得最耗能腳本..." name="top_scripts_btn" tool_tip="æ¢åˆ—���目å‰é‹ä½œä¸­æœ€è€—能的腳本清單"/>
<button label="地å€é‡æ–°å•Ÿå‹•" name="restart_btn" tool_tip="給予兩分é˜å€’數計時並é‡æ–°å•Ÿå‹•"/>
- <button label="延é²é‡æ–°å•Ÿå‹•" name="cancel_restart_btn" tool_tip="延é²åœ°å€é‡æ–°å•Ÿå‹•ä¸€å°æ™‚"/>
+ <button label="å–消é‡æ–°å•Ÿå‹•" name="cancel_restart_btn" tool_tip="å–消地å€é‡æ–°å•Ÿå‹•"/>
</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_region_environment.xml b/indra/newview/skins/default/xui/zh/panel_region_environment.xml
new file mode 100755
index 0000000000..8f466af39e
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/panel_region_environment.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="環境" name="panel_env_info">
+ <text name="water_settings_title">
+ é¸æ“‡ä½ å¸Œæœ›åˆ°ä½ åœ°å€çš„訪客所能看到的水和天空 / 日循環設定。 詳情
+ </text>
+ <radio_group name="region_settings_radio_group">
+ <radio_item label="使用第二人生é è¨­å€¼" name="use_sl_default_settings"/>
+ <radio_item label="使用以下設定" name="use_my_settings"/>
+ </radio_group>
+ <panel name="user_environment_settings">
+ <text name="water_settings_title">
+ 水的設定
+ </text>
+ <combo_box name="water_settings_preset_combo">
+ <combo_box.item label="-é¸æ“‡ä¸€å€‹è‡ªè¨‚é…ç½®-" name="item0"/>
+ </combo_box>
+ <text name="sky_dayc_settings_title">
+ 天空 / 日循環
+ </text>
+ <radio_group name="sky_dayc_settings_radio_group">
+ <radio_item label="固定天空" name="my_sky_settings"/>
+ <radio_item label="日循環" name="my_dayc_settings"/>
+ </radio_group>
+ <combo_box name="sky_settings_preset_combo">
+ <combo_box.item label="-é¸æ“‡ä¸€å€‹è‡ªè¨‚é…ç½®-" name="item0"/>
+ </combo_box>
+ <combo_box name="dayc_settings_preset_combo">
+ <combo_box.item label="-é¸æ“‡ä¸€å€‹è‡ªè¨‚é…ç½®-" name="item0"/>
+ </combo_box>
+ </panel>
+ <button label="套用" name="apply_btn"/>
+ <button label="å–消" name="cancel_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_region_estate.xml b/indra/newview/skins/default/xui/zh/panel_region_estate.xml
index efa3be2f51..f3c1c85379 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_region_estate.xml
+++ b/indra/newview/skins/default/xui/zh/panel_region_estate.xml
@@ -10,20 +10,20 @@
(未知)
</text>
<text name="owner_text">
- 領地æ“有者:
+ 領地所有人:
</text>
<text name="estate_owner">
(未知)
</text>
- <check_box label="Use Global Time" name="use_global_time_check"/>
+ <check_box label="使用全域時間" name="use_global_time_check"/>
<check_box label="固定太陽" name="fixed_sun_check"/>
- <slider label="Phase" name="sun_hour_slider"/>
+ <slider label="相ä½" name="sun_hour_slider"/>
<check_box label="å…許公開出入" name="externally_visible_check"/>
<text name="Only Allow">
- Restrict Access to accounts verified by:
+ 僅å…許符åˆä»¥ä¸‹æ¢ä»¶çš„居民進入:
</text>
- <check_box label="Payment Information on File" name="limit_payment" tool_tip="Ban unidentified Residents"/>
- <check_box label="年齡驗證" name="limit_age_verified" tool_tip="Ban Residents who have not verified their age. See the [SUPPORT_SITE] for more information."/>
+ <check_box label="已經é ç•™ä»˜æ¬¾è³‡æ–™" name="limit_payment" tool_tip="å±…æ°‘å¿…é ˆæ供付款資料æ‰èƒ½é€²å…¥é€™é ˜åœ°ã€‚ åƒé–± [SUPPORT_SITE] ç²å–進一步資訊。"/>
+ <check_box label="已年滿 18 æ­²" name="limit_age_verified" tool_tip="居民必須年滿 18 æ­²æ‰èƒ½é€²å…¥é€™é ˜åœ°ã€‚ åƒé–± [SUPPORT_SITE] ç²å–進一步資訊。"/>
<check_box label="å…許語音èŠå¤©" name="voice_chat_check"/>
<check_box label="å…許直接瞬間傳é€" name="allow_direct_teleport"/>
<button label="套用" name="apply_btn"/>
diff --git a/indra/newview/skins/default/xui/zh/panel_region_general.xml b/indra/newview/skins/default/xui/zh/panel_region_general.xml
index a441b8898d..f6b2c46354 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_region_general.xml
+++ b/indra/newview/skins/default/xui/zh/panel_region_general.xml
@@ -18,16 +18,17 @@
<text name="region_type">
未知
</text>
- <check_box label="阻止變形" name="block_terraform_check"/>
+ <check_box label="阻止土地變形" name="block_terraform_check"/>
<check_box label="阻止飛行" name="block_fly_check"/>
<check_box label="å…許傷害" name="allow_damage_check"/>
<check_box label="é™åˆ¶æŽ¨æ’ž" name="restrict_pushobject"/>
<check_box label="å…許土地轉售" name="allow_land_resell_check"/>
<check_box label="å…許土地 åˆä½µ/分割" name="allow_parcel_changes_check"/>
<check_box label="阻擋土地顯示於æœå°‹ä¸­" name="block_parcel_search_check" tool_tip="讓其他人å¯ä»¥åœ¨æœå°‹çµæžœä¸­çœ‹åˆ°é€™å€‹åœ°å€èˆ‡å…¶ä¸­çš„地段"/>
+ <check_box label="å…許網é¢ç‰©ä»¶" name="mesh_rez_enabled_check" tool_tip="å…許大家在此地å€ç”¢ç”Ÿç¶²é¢ç‰©ä»¶"/>
<spinner label="人數上é™" name="agent_limit_spin"/>
- <spinner label="Object Bonus" name="object_bonus_spin"/>
- <text label="Maturity" name="access_text">
+ <spinner label="物件紅利" name="object_bonus_spin"/>
+ <text label="分級" name="access_text">
分級:
</text>
<icons_combo_box label="é©åº¦æˆäºº" name="access_combo">
@@ -36,8 +37,8 @@
<icons_combo_box.item label="一般普級" name="PG" value="13"/>
</icons_combo_box>
<button label="套用" name="apply_btn"/>
- <button label="強制瞬間傳é€ä¸€å€‹å±…民回家..." name="kick_btn"/>
- <button label="強制瞬間傳é€æ‰€æœ‰å±…民回家..." name="kick_all_btn"/>
- <button label="é€å‡ºè¨Šæ¯åˆ°åœ°å€..." name="im_btn"/>
+ <button label="瞬間傳é€ä¸€ä½å±…民回家..." name="kick_btn"/>
+ <button label="瞬間傳é€æ‰€æœ‰å±…民回家..." name="kick_all_btn"/>
+ <button label="å‘地å€ç™¼å‡ºè¨Šæ¯..." name="im_btn"/>
<button label="管ç†çž¬é–“傳é€ä¸­å¿ƒ..." name="manage_telehub_btn"/>
</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_region_terrain.xml b/indra/newview/skins/default/xui/zh/panel_region_terrain.xml
index 7cae8fe8cf..85e759e445 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_region_terrain.xml
+++ b/indra/newview/skins/default/xui/zh/panel_region_terrain.xml
@@ -9,11 +9,52 @@
<spinner label="水文高度" name="water_height_spin"/>
<spinner label="地形æå‡é™åˆ¶" name="terrain_raise_spin"/>
<spinner label="地形é™ä½Žé™åˆ¶" name="terrain_lower_spin"/>
- <check_box label="使用領地的太陽設定" name="use_estate_sun_check"/>
- <check_box label="固定太陽" name="fixed_sun_check"/>
- <slider label="Phase" name="sun_hour_slider"/>
+ <text name="detail_texture_text">
+ 地形æ質(須 512x512,24 ä½å…ƒ .tga 檔格å¼ï¼‰
+ </text>
+ <text name="height_text_lbl">
+ 1(低)
+ </text>
+ <text name="height_text_lbl2">
+ 2
+ </text>
+ <text name="height_text_lbl3">
+ 3
+ </text>
+ <text name="height_text_lbl4">
+ 4(高)
+ </text>
+ <text name="height_text_lbl5">
+ æ質海拔範åœ
+ </text>
+ <text name="height_text_lbl10">
+ 這些值代表以上æ質的混åˆç¯„åœã€‚
+ </text>
+ <text name="height_text_lbl11">
+ 以公尺為單ä½ï¼Œä½Žå€¼æ˜¯æ質 #1 的最大高度,高值是æ質 #4 的最å°é«˜åº¦ã€‚
+ </text>
+ <text name="height_text_lbl6">
+ 西北
+ </text>
+ <text name="height_text_lbl7">
+ æ±åŒ—
+ </text>
+ <spinner label="低" name="height_start_spin_1"/>
+ <spinner label="低" name="height_start_spin_3"/>
+ <spinner label="高" name="height_range_spin_1"/>
+ <spinner label="高" name="height_range_spin_3"/>
+ <text name="height_text_lbl8">
+ 西å—
+ </text>
+ <text name="height_text_lbl9">
+ æ±å—
+ </text>
+ <spinner label="低" name="height_start_spin_0"/>
+ <spinner label="低" name="height_start_spin_2"/>
+ <spinner label="高" name="height_range_spin_0"/>
+ <spinner label="高" name="height_range_spin_2"/>
+ <button label="下載 RAW 地形..." name="download_raw_btn" tool_tip="åªå…許領地所有人而éžç®¡ç†è€…進行æ“作"/>
+ <button label="上傳 RAW 地形檔..." name="upload_raw_btn" tool_tip="åªå…許領地所有人而éžç®¡ç†è€…進行æ“作"/>
+ <button label="確定地形" name="bake_terrain_btn" tool_tip="將目å‰åœ°å½¢è¨­ç‚ºã€Œå‡é«˜ / é™ä½Žã€æ¥µé™çš„中心值"/>
<button label="套用" name="apply_btn"/>
- <button label="下載 RAW 地形..." name="download_raw_btn" tool_tip="åªå…許領地æ“有者而éžç®¡ç†è€…進行æ“作"/>
- <button label="上傳 RAW 地形檔..." name="upload_raw_btn" tool_tip="åªå…許領地æ“有者而éžç®¡ç†è€…進行æ“作"/>
- <button label="Bake Terrain" name="bake_terrain_btn" tool_tip="Set current terrain as mid-point for raise/lower limits"/>
</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_region_texture.xml b/indra/newview/skins/default/xui/zh/panel_region_texture.xml
deleted file mode 100644
index 7b6152121f..0000000000
--- a/indra/newview/skins/default/xui/zh/panel_region_texture.xml
+++ /dev/null
@@ -1,54 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel label="地é¢æ質" name="Textures">
- <text name="region_text_lbl">
- 地å€ï¼š
- </text>
- <text name="region_text">
- 未知
- </text>
- <text name="detail_texture_text">
- 地形æ質(須 512x512,24 ä½å…ƒ .tga 檔格å¼ï¼‰
- </text>
- <text name="height_text_lbl">
- 1 (Low)
- </text>
- <text name="height_text_lbl2">
- 2
- </text>
- <text name="height_text_lbl3">
- 3
- </text>
- <text name="height_text_lbl4">
- 4 (High)
- </text>
- <text name="height_text_lbl5">
- Texture Elevation Ranges
- </text>
- <text name="height_text_lbl6">
- Northwest
- </text>
- <text name="height_text_lbl7">
- Northeast
- </text>
- <spinner label="Low" name="height_start_spin_1"/>
- <spinner label="Low" name="height_start_spin_3"/>
- <spinner label="High" name="height_range_spin_1"/>
- <spinner label="High" name="height_range_spin_3"/>
- <text name="height_text_lbl8">
- Southwest
- </text>
- <text name="height_text_lbl9">
- Southeast
- </text>
- <spinner label="Low" name="height_start_spin_0"/>
- <spinner label="Low" name="height_start_spin_2"/>
- <spinner label="High" name="height_range_spin_0"/>
- <spinner label="High" name="height_range_spin_2"/>
- <text name="height_text_lbl10">
- These values represent the blend range for the textures above.
- </text>
- <text name="height_text_lbl11">
- Measured in meters, the LOW value is the MAXIMUM height of Texture #1, and the HIGH value is the MINIMUM height of Texture #4.
- </text>
- <button label="套用" name="apply_btn"/>
-</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_script_ed.xml b/indra/newview/skins/default/xui/zh/panel_script_ed.xml
index cc2b0fc673..198e59be7b 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_script_ed.xml
+++ b/indra/newview/skins/default/xui/zh/panel_script_ed.xml
@@ -4,7 +4,7 @@
載入中...
</panel.string>
<panel.string name="can_not_view">
- ä½ ä¸èƒ½å¯Ÿçœ‹æˆ–編輯此腳本,自從它被設定為 &quot;no copy&quot; 後。你需è¦å®Œæ•´æ¬Šé™åŽ»å¯Ÿçœ‹æˆ–編輯有包å«è…³æœ¬åœ¨å…§çš„物件。
+ 你無法察看或編輯這腳本,它被設為「ç¦æ­¢è¤‡è£½ã€ã€‚ 你需è¦å®Œæ•´æ¬Šé™åŽ»å¯Ÿçœ‹æˆ–編輯物件內的腳本。
</panel.string>
<panel.string name="public_objects_can_not_run">
公開物件ä¸èƒ½åŸ·è¡Œè…³æœ¬
@@ -22,16 +22,19 @@
<menu label="檔案" name="File">
<menu_item_call label="儲存" name="Save"/>
<menu_item_call label="還原全部變更" name="Revert All Changes"/>
+ <menu_item_call label="從檔案載入…" name="LoadFromFile"/>
+ <menu_item_call label="存入檔案…" name="SaveToFile"/>
</menu>
<menu label="編輯" name="Edit">
<menu_item_call label="復原" name="Undo"/>
<menu_item_call label="é‡åš" name="Redo"/>
<menu_item_call label="剪下" name="Cut"/>
- <menu_item_call label="覆製" name="Copy"/>
+ <menu_item_call label="æšåº¨" name="Copy"/>
<menu_item_call label="貼上" name="Paste"/>
<menu_item_call label="å…¨é¸" name="Select All"/>
<menu_item_call label="å–消é¸æ“‡" name="Deselect"/>
<menu_item_call label="æœå°‹ / å–代..." name="Search / Replace..."/>
+ <menu_item_call label="å‰å¾€æŸè¡Œæ•¸â€¦" name="Go to line..."/>
</menu>
<menu label="幫助" name="Help">
<menu_item_call label="幫助..." name="Help..."/>
diff --git a/indra/newview/skins/default/xui/zh/panel_script_limits_my_avatar.xml b/indra/newview/skins/default/xui/zh/panel_script_limits_my_avatar.xml
index 32cc2f9a5d..eb32d39f78 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_script_limits_my_avatar.xml
+++ b/indra/newview/skins/default/xui/zh/panel_script_limits_my_avatar.xml
@@ -1,16 +1,16 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel label="我的化身" name="script_limits_my_avatar_panel">
<text name="script_memory">
- Avatar Script Usage
+ 化身腳本使用é‡
</text>
<text name="loading_text">
載入中...
</text>
<scroll_list name="scripts_list">
<scroll_list.columns label="尺寸(kb)" name="size"/>
- <scroll_list.columns label="URLs" name="urls"/>
+ <scroll_list.columns label="URL" name="urls"/>
<scroll_list.columns label="物件å稱" name="name"/>
<scroll_list.columns label="ä½ç½®" name="location"/>
</scroll_list>
- <button label="Refresh List" name="refresh_list_btn"/>
+ <button label="刷新清單" name="refresh_list_btn"/>
</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_script_limits_region_memory.xml b/indra/newview/skins/default/xui/zh/panel_script_limits_region_memory.xml
index 950abbfb4c..40a2dd6926 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_script_limits_region_memory.xml
+++ b/indra/newview/skins/default/xui/zh/panel_script_limits_region_memory.xml
@@ -8,13 +8,13 @@
</text>
<scroll_list name="scripts_list">
<scroll_list.columns label="尺寸(kb)" name="size"/>
- <scroll_list.columns label="URLs" name="urls"/>
+ <scroll_list.columns label="URL" name="urls"/>
<scroll_list.columns label="物件å稱" name="name"/>
- <scroll_list.columns label="物件æ“有者" name="owner"/>
+ <scroll_list.columns label="物件所有人" name="owner"/>
<scroll_list.columns label="地段" name="parcel"/>
<scroll_list.columns label="ä½ç½®" name="location"/>
</scroll_list>
- <button label="Refresh List" name="refresh_list_btn"/>
- <button label="Highlight" name="highlight_btn"/>
+ <button label="刷新清單" name="refresh_list_btn"/>
+ <button label="高亮顯示" name="highlight_btn"/>
<button label="退回" name="return_btn"/>
</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_script_question_toast.xml b/indra/newview/skins/default/xui/zh/panel_script_question_toast.xml
new file mode 100755
index 0000000000..a2d0237da0
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/panel_script_question_toast.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<panel label="script_question_panel" name="panel_script_question_toast">
+ <panel label="buttons_panel" name="buttons_panel"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_scrolling_param.xml b/indra/newview/skins/default/xui/zh/panel_scrolling_param.xml
index bc29058f77..bc29058f77 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_scrolling_param.xml
+++ b/indra/newview/skins/default/xui/zh/panel_scrolling_param.xml
diff --git a/indra/newview/skins/default/xui/zh/panel_scrolling_param_base.xml b/indra/newview/skins/default/xui/zh/panel_scrolling_param_base.xml
index fa659040ea..fa659040ea 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_scrolling_param_base.xml
+++ b/indra/newview/skins/default/xui/zh/panel_scrolling_param_base.xml
diff --git a/indra/newview/skins/default/xui/zh/panel_side_tray.xml b/indra/newview/skins/default/xui/zh/panel_side_tray.xml
deleted file mode 100644
index e5c7deb7d6..0000000000
--- a/indra/newview/skins/default/xui/zh/panel_side_tray.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<!-- Side tray cannot show background because it is always
- partially on screen to hold tab buttons. -->
-<side_tray name="sidebar">
- <sidetray_tab description="å´é‚Šæ¬„切æ›ã€‚" name="sidebar_openclose" tab_title="å´é‚Šæ¬„切æ›"/>
- <sidetray_tab description="首é ã€‚" name="sidebar_home" tab_title="首é ">
- <panel label="首é " name="panel_home"/>
- </sidetray_tab>
- <sidetray_tab description="編輯你的公開檔案åŠç²¾é¸åœ°é»žã€‚" name="sidebar_me" tab_title="我的檔案">
- <panel_container name="panel_container">
- <panel label="自己" name="panel_me"/>
- </panel_container>
- </sidetray_tab>
- <sidetray_tab description="Find your friends, contacts and people nearby." name="sidebar_people" tab_title="人群">
- <panel_container name="panel_container">
- <panel label="群組檔案" name="panel_group_info_sidetray"/>
- <panel label="Blocked Residents &amp; Objects" name="panel_block_list_sidetray"/>
- </panel_container>
- </sidetray_tab>
- <sidetray_tab description="Find places to go and places you&apos;ve visited before." label="地點" name="sidebar_places" tab_title="地點">
- <panel label="地點" name="panel_places"/>
- </sidetray_tab>
- <sidetray_tab description="ç€è¦½ä½ çš„收ç´å€ã€‚" name="sidebar_inventory" tab_title="我的收ç´å€">
- <panel label="編輯收ç´å€" name="sidepanel_inventory"/>
- </sidetray_tab>
- <sidetray_tab description="變更你的外觀與目å‰æ¨£è²Œã€‚" name="sidebar_appearance" tab_title="我的外觀">
- <panel label="編輯外觀" name="sidepanel_appearance"/>
- </sidetray_tab>
-</side_tray>
diff --git a/indra/newview/skins/default/xui/zh/panel_side_tray_tab_caption.xml b/indra/newview/skins/default/xui/zh/panel_side_tray_tab_caption.xml
index cdd79da30c..cdd79da30c 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_side_tray_tab_caption.xml
+++ b/indra/newview/skins/default/xui/zh/panel_side_tray_tab_caption.xml
diff --git a/indra/newview/skins/default/xui/zh/panel_snapshot_inventory.xml b/indra/newview/skins/default/xui/zh/panel_snapshot_inventory.xml
new file mode 100755
index 0000000000..20fb9b494a
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/panel_snapshot_inventory.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_snapshot_inventory">
+ <text name="title">
+ 儲存到我的收ç´å€
+ </text>
+ <text name="hint_lbl">
+ 將圖åƒå„²å­˜åˆ°æ”¶ç´å€çš„費用為 L$[UPLOAD_COST]。 è‹¥è¦å°‡åœ–åƒå­˜ç‚ºæ質,請é¸æ“‡ä¸€å€‹æ­£æ–¹æ ¼å¼ã€‚
+ </text>
+ <combo_box label="解æžåº¦" name="texture_size_combo">
+ <combo_box.item label="ç›®å‰è¦–窗" name="CurrentWindow"/>
+ <combo_box.item label="å°ï¼ˆ128x128)" name="Small(128x128)"/>
+ <combo_box.item label="中(256x256)" name="Medium(256x256)"/>
+ <combo_box.item label="大(512x512)" name="Large(512x512)"/>
+ <combo_box.item label="自訂" name="Custom"/>
+ </combo_box>
+ <spinner label="寬" name="inventory_snapshot_width"/>
+ <spinner label="高度" name="inventory_snapshot_height"/>
+ <check_box label="鎖ä½æ¯”例" name="inventory_keep_aspect_check"/>
+ <button label="å–消" name="cancel_btn"/>
+ <button label="儲存" name="save_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_snapshot_local.xml b/indra/newview/skins/default/xui/zh/panel_snapshot_local.xml
new file mode 100755
index 0000000000..a929c9a3fb
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/panel_snapshot_local.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_snapshot_local">
+ <text name="title">
+ 儲存到電腦上
+ </text>
+ <combo_box label="解æžåº¦" name="local_size_combo">
+ <combo_box.item label="ç›®å‰è¦–窗" name="CurrentWindow"/>
+ <combo_box.item label="320x240" name="320x240"/>
+ <combo_box.item label="640x480" name="640x480"/>
+ <combo_box.item label="800x600" name="800x600"/>
+ <combo_box.item label="1024x768" name="1024x768"/>
+ <combo_box.item label="1280x1024" name="1280x1024"/>
+ <combo_box.item label="1600x1200" name="1600x1200"/>
+ <combo_box.item label="自訂" name="Custom"/>
+ </combo_box>
+ <layout_stack name="local_image_params_ls">
+ <layout_panel name="local_image_size_lp">
+ <spinner label="寬" name="local_snapshot_width"/>
+ <spinner label="高度" name="local_snapshot_height"/>
+ <check_box label="鎖ä½æ¯”例" name="local_keep_aspect_check"/>
+ </layout_panel>
+ <layout_panel name="local_image_format_quality_lp">
+ <combo_box label="æ ¼å¼" name="local_format_combo">
+ <combo_box.item label="PNG(零失真)" name="PNG"/>
+ <combo_box.item label="JPEG" name="JPEG"/>
+ <combo_box.item label="BMP(零失真)" name="BMP"/>
+ </combo_box>
+ <slider label="圖åƒå“質" name="image_quality_slider"/>
+ <text name="image_quality_level">
+ ([QLVL])
+ </text>
+ </layout_panel>
+ </layout_stack>
+ <button label="å–消" name="cancel_btn"/>
+ <flyout_button label="儲存" name="save_btn" tool_tip="儲存圖åƒåˆ°æª”案">
+ <flyout_button.item label="儲存" name="save_item"/>
+ <flyout_button.item label="å¦å­˜..." name="saveas_item"/>
+ </flyout_button>
+</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_snapshot_options.xml b/indra/newview/skins/default/xui/zh/panel_snapshot_options.xml
new file mode 100755
index 0000000000..82c2b10d8d
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/panel_snapshot_options.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_snapshot_options">
+ <button label="é€è‡³æˆ‘的檔案訊æ¯ç™¼ä½ˆ" name="save_to_profile_btn"/>
+ <button label="電郵" name="save_to_email_btn"/>
+ <button label="儲存到我的收ç´å€ï¼ˆL$[AMOUNT])" name="save_to_inventory_btn"/>
+ <button label="儲存到電腦上" name="save_to_computer_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_snapshot_postcard.xml b/indra/newview/skins/default/xui/zh/panel_snapshot_postcard.xml
new file mode 100755
index 0000000000..853a856104
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/panel_snapshot_postcard.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_snapshot_postcard">
+ <string name="default_subject">
+ 來自 [SECOND_LIFE] 的明信片。
+ </string>
+ <string name="default_message">
+ 快來看看這個ï¼
+ </string>
+ <string name="upload_message">
+ 傳é€ä¸­...
+ </string>
+ <text name="title">
+ 電郵
+ </text>
+ <button label="訊æ¯" name="message_btn"/>
+ <button label="設定" name="settings_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_snapshot_profile.xml b/indra/newview/skins/default/xui/zh/panel_snapshot_profile.xml
new file mode 100755
index 0000000000..6f64a4e83c
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/panel_snapshot_profile.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_snapshot_profile">
+ <text name="title">
+ é€è‡³æˆ‘的檔案訊æ¯ç™¼ä½ˆ
+ </text>
+ <combo_box label="解æžåº¦" name="profile_size_combo">
+ <combo_box.item label="ç›®å‰è¦–窗" name="CurrentWindow"/>
+ <combo_box.item label="640x480" name="640x480"/>
+ <combo_box.item label="800x600" name="800x600"/>
+ <combo_box.item label="1024x768" name="1024x768"/>
+ <combo_box.item label="自訂" name="Custom"/>
+ </combo_box>
+ <layout_stack name="profile_image_params_ls">
+ <layout_panel name="profile_image_size_lp">
+ <spinner label="寬" name="profile_snapshot_width"/>
+ <spinner label="高度" name="profile_snapshot_height"/>
+ <check_box label="鎖ä½æ¯”例" name="profile_keep_aspect_check"/>
+ </layout_panel>
+ <layout_panel name="profile_image_metadata_lp">
+ <text name="caption_label">
+ 內容敘述:
+ </text>
+ <check_box initial_value="true" label="加入所在ä½ç½®" name="add_location_cb"/>
+ </layout_panel>
+ </layout_stack>
+ <button label="å–消" name="cancel_btn"/>
+ <button label="發佈" name="post_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_sound_devices.xml b/indra/newview/skins/default/xui/zh/panel_sound_devices.xml
new file mode 100755
index 0000000000..fa4e24a605
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/panel_sound_devices.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<panel label="設備設定" name="device_settings_panel">
+ <panel.string name="default_text">
+ é è¨­
+ </panel.string>
+ <string name="name_no_device">
+ 無設備
+ </string>
+ <string name="name_default_system_device">
+ é è¨­ç³»çµ±è¨­å‚™
+ </string>
+ <text name="Input">
+ 輸入
+ </text>
+ <text name="Output">
+ 輸出
+ </text>
+ <text name="My volume label">
+ 我的音é‡ï¼š
+ </text>
+ <slider_bar initial_value="1.0" name="mic_volume_slider" tool_tip="用這控制æ¢æ”¹è®ŠéŸ³é‡"/>
+ <text name="wait_text">
+ è«‹ç¨å€™
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_stand_stop_flying.xml b/indra/newview/skins/default/xui/zh/panel_stand_stop_flying.xml
index 1dd3acef5d..4586d4eca1 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_stand_stop_flying.xml
+++ b/indra/newview/skins/default/xui/zh/panel_stand_stop_flying.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<!-- Width and height of this panel should be synchronized with "panel_modes" in the floater_moveview.xml-->
<panel name="panel_stand_stop_flying">
- <button label="站立" name="stand_btn" tool_tip="點擊此處起立。"/>
+ <button label="站立" name="stand_btn" tool_tip="點按此處起立。"/>
<button label="åœæ­¢é£›è¡Œ" name="stop_fly_btn" tool_tip="åœæ­¢é£›è¡Œ"/>
</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_status_bar.xml b/indra/newview/skins/default/xui/zh/panel_status_bar.xml
index 808e14f3c3..b4cdff9d6b 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_status_bar.xml
+++ b/indra/newview/skins/default/xui/zh/panel_status_bar.xml
@@ -16,12 +16,13 @@
L$ [AMT]
</panel.string>
<panel name="balance_bg">
- <text name="balance" tool_tip="點擊以é‡æ–°æ›´æ–°ä½ çš„ L$ 帳戶餘é¡" value="L$20"/>
- <button label="購買 L$" name="buyL" tool_tip="點擊以購買更多 L$"/>
+ <text name="balance" tool_tip="點按以é‡æ–°æ›´æ–°ä½ çš„ L$ 帳戶餘é¡" value="L$20"/>
+ <button label="購買 L$" name="buyL" tool_tip="點按以購買更多 L$"/>
+ <button label="購物" name="goShop" tool_tip="打開第二人生購物市集"/>
</panel>
<text name="TimeText" tool_tip="ç›®å‰æ™‚å€ï¼ˆå¤ªå¹³æ´‹ï¼‰">
24:00 AM PST
</text>
- <button name="media_toggle_btn" tool_tip="開始 / åœæ­¢å…¨éƒ¨åª’體(音樂ã€å½±ç‰‡ã€ç¶²é ï¼‰"/>
+ <button name="media_toggle_btn" tool_tip="開始/åœæ­¢å…¨éƒ¨åª’體(音樂ã€å½±ç‰‡ã€ç¶²é ï¼‰"/>
<button name="volume_btn" tool_tip="全域音é‡æŽ§åˆ¶"/>
</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_teleport_history.xml b/indra/newview/skins/default/xui/zh/panel_teleport_history.xml
index a2a63db000..44d545a86d 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_teleport_history.xml
+++ b/indra/newview/skins/default/xui/zh/panel_teleport_history.xml
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel name="Teleport History">
<accordion name="history_accordion">
- <no_matched_tabs_text name="no_matched_teleports_msg" value="沒有發ç¾ä½ è¦æ‰¾çš„嗎?試試 [secondlife:///app/search/places/[SEARCH_TERM] æœå°‹]。"/>
- <no_visible_tabs_text name="no_teleports_msg" value="瞬間傳é€ç´€éŒ„是空白的。試試 [secondlife:///app/search/places/ Search]。"/>
+ <no_matched_tabs_text name="no_matched_teleports_msg" value="找ä¸åˆ°ä½ è¦æ‰¾çš„嗎? 請試試 [secondlife:///app/search/places/[SEARCH_TERM] æœå°‹]。"/>
+ <no_visible_tabs_text name="no_teleports_msg" value="瞬間傳é€æ­·å²è¨˜éŒ„ç›®å‰ç©ºç™½ã€‚ 請試試[secondlife:///app/search/places/ æœå°‹]。"/>
<accordion_tab name="today" title="今天"/>
<accordion_tab name="yesterday" title="昨天"/>
<accordion_tab name="2_days_ago" title="å‰å¤©"/>
diff --git a/indra/newview/skins/default/xui/zh/panel_teleport_history_item.xml b/indra/newview/skins/default/xui/zh/panel_teleport_history_item.xml
index c251994906..c251994906 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_teleport_history_item.xml
+++ b/indra/newview/skins/default/xui/zh/panel_teleport_history_item.xml
diff --git a/indra/newview/skins/default/xui/zh/panel_tools_texture.xml b/indra/newview/skins/default/xui/zh/panel_tools_texture.xml
new file mode 100644
index 0000000000..5ea6d818c7
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/panel_tools_texture.xml
@@ -0,0 +1,116 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="æ質" name="Texture">
+ <panel.string name="string repeats per meter">
+ æ¯å…¬å°ºé‡è¦†æ¬¡æ•¸
+ </panel.string>
+ <panel.string name="string repeats per face">
+ æ¯ä¸€é¢é‡è¦†æ¬¡æ•¸
+ </panel.string>
+ <text name="color label">
+ é¡è‰²
+ </text>
+ <color_swatch label="" name="colorswatch" tool_tip="點按以開啟é¡è‰²æŒ‘é¸å™¨"/>
+ <text name="color trans">
+ é€æ˜Žåº¦ %
+ </text>
+ <text name="glow label">
+ 光暈
+ </text>
+ <check_box label="全亮" name="checkbox fullbright"/>
+ <combo_box name="combobox matmedia">
+ <combo_box.item label="ææ–™" name="Materials"/>
+ <combo_box.item label="媒體" name="Media"/>
+ </combo_box>
+ <combo_box name="combobox mattype">
+ <combo_box.item label="æ質(漫å射圖)" name="Texture (diffuse)"/>
+ <combo_box.item label="凹凸度(正交)" name="Bumpiness (normal)"/>
+ <combo_box.item label="閃亮度(é¡å光)" name="Shininess (specular)"/>
+ </combo_box>
+ <texture_picker label="æ質" name="texture control" tool_tip="點按以挑é¸åœ–片"/>
+ <text name="label alphamode">
+ åŠé€æ˜Žæ¨¡å¼
+ </text>
+ <combo_box name="combobox alphamode">
+ <combo_box.item label="ç„¡" name="None"/>
+ <combo_box.item label="åŠé€æ˜Žæ”™æ··" name="Alpha blending"/>
+ <combo_box.item label="åŠé€æ˜Žé®ç½©" name="Alpha masking"/>
+ <combo_box.item label="自發光é®ç½©" name="Emissive mask"/>
+ </combo_box>
+ <text name="label maskcutoff">
+ é®ç½©æˆªæ–·å€¼
+ </text>
+ <texture_picker label="æ質" name="bumpytexture control" tool_tip="點按以挑é¸åœ–片"/>
+ <text name="label bumpiness">
+ 凹凸度
+ </text>
+ <combo_box name="combobox bumpiness">
+ <combo_box.item label="ç„¡" name="None"/>
+ <combo_box.item label="亮度" name="Brightness"/>
+ <combo_box.item label="暗度" name="Darkness"/>
+ <combo_box.item label="木紋" name="woodgrain"/>
+ <combo_box.item label="樹皮" name="bark"/>
+ <combo_box.item label="磚" name="bricks"/>
+ <combo_box.item label="æ ¼å­" name="checker"/>
+ <combo_box.item label="æ··å‡åœŸ" name="concrete"/>
+ <combo_box.item label="粗花磚" name="crustytile"/>
+ <combo_box.item label="石磚" name="cutstone"/>
+ <combo_box.item label="圓盤" name="discs"/>
+ <combo_box.item label="碎石" name="gravel"/>
+ <combo_box.item label="培養皿" name="petridish"/>
+ <combo_box.item label="å´é‚Šç‰‡" name="siding"/>
+ <combo_box.item label="石磚格" name="stonetile"/>
+ <combo_box.item label="彩色沙岩" name="stucco"/>
+ <combo_box.item label="å¸é™„" name="suction"/>
+ <combo_box.item label="編織" name="weave"/>
+ </combo_box>
+ <texture_picker label="æ質" name="shinytexture control" tool_tip="點按以挑é¸åœ–片"/>
+ <text name="label shininess">
+ 閃亮度
+ </text>
+ <combo_box name="combobox shininess">
+ <combo_box.item label="ç„¡" name="None"/>
+ <combo_box.item label="低" name="Low"/>
+ <combo_box.item label="中" name="Medium"/>
+ <combo_box.item label="高" name="High"/>
+ </combo_box>
+ <text name="label glossiness">
+ 光滑度
+ </text>
+ <text name="label environment">
+ 環境
+ </text>
+ <text name="label shinycolor">
+ é¡è‰²
+ </text>
+ <color_swatch label="" name="shinycolorswatch" tool_tip="點按以開啟é¡è‰²æŒ‘é¸å™¨"/>
+ <text name="media_info">
+ 所é¸åª’體如有 URL,置於此
+ </text>
+ <button label="é¸æ“‡â€¦" name="add_media" tool_tip="添加媒體"/>
+ <button label="移除" name="delete_media" tool_tip="刪除這個媒體æ質"/>
+ <button label="å°é½Š" label_selected="å°é½Šåª’é«”" name="button align" tool_tip="å°é½Šåª’é«”æ質(須先載入)"/>
+ <text name="tex gen">
+ 映射方å¼
+ </text>
+ <combo_box name="combobox texgen">
+ <combo_box.item label="é è¨­" name="Default"/>
+ <combo_box.item label="å¹³é¢" name="Planar"/>
+ </combo_box>
+ <spinner label="水平刻度" name="TexScaleU"/>
+ <spinner label="垂直刻度" name="TexScaleV"/>
+ <spinner label="æ¯å…¬å°ºé‡è¦†æ¬¡æ•¸" name="rptctrl"/>
+ <spinner label="旋轉角度" name="TexRot"/>
+ <spinner label="æ°´å¹³åè·" name="TexOffsetU"/>
+ <spinner label="åž‚ç›´åè·" name="TexOffsetV"/>
+ <spinner label="水平刻度" name="bumpyScaleU"/>
+ <spinner label="垂直刻度" name="bumpyScaleV"/>
+ <spinner label="旋轉角度" name="bumpyRot"/>
+ <spinner label="æ°´å¹³åè·" name="bumpyOffsetU"/>
+ <spinner label="åž‚ç›´åè·" name="bumpyOffsetV"/>
+ <spinner label="水平刻度" name="shinyScaleU"/>
+ <spinner label="垂直刻度" name="shinyScaleV"/>
+ <spinner label="旋轉角度" name="shinyRot"/>
+ <spinner label="æ°´å¹³åè·" name="shinyOffsetU"/>
+ <spinner label="åž‚ç›´åè·" name="shinyOffsetV"/>
+ <check_box initial_value="false" label="å°é½Šå¹³é¢" name="checkbox planar align" tool_tip="以最後所é¸æ“‡çš„é¢ç‚ºåŸºæº–,å°é½Šå…¨éƒ¨æ‰€é¸æ“‡çš„é¢ä¸Šçš„æ質。 這必須使用平é¢æ質映射方å¼ã€‚"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_voice_effect.xml b/indra/newview/skins/default/xui/zh/panel_voice_effect.xml
index 6c8a452014..6c8a452014 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_voice_effect.xml
+++ b/indra/newview/skins/default/xui/zh/panel_voice_effect.xml
diff --git a/indra/newview/skins/default/xui/zh/panel_volume_pulldown.xml b/indra/newview/skins/default/xui/zh/panel_volume_pulldown.xml
new file mode 100755
index 0000000000..70ec028176
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/panel_volume_pulldown.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="volumepulldown_floater">
+ <slider label="主控音é‡" name="System Volume"/>
+ <slider label="按éµéŸ³" name="UI Volume"/>
+ <slider label="環境" name="Wind Volume"/>
+ <slider label="è²éŸ³" name="SFX Volume"/>
+ <check_box name="gesture_audio_play_btn" tool_tip="啟用姿勢è²éŸ³"/>
+ <slider label="音樂" name="Music Volume"/>
+ <check_box name="enable_music" tool_tip="啟用串æµéŸ³æ¨‚"/>
+ <slider label="媒體" name="Media Volume"/>
+ <check_box name="enable_media" tool_tip="啟用串æµåª’é«”"/>
+ <slider label="語音" name="Voice Volume"/>
+ <check_box name="enable_voice_check" tool_tip="啟用語音èŠå¤©"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_world_map.xml b/indra/newview/skins/default/xui/zh/panel_world_map.xml
index b5aa659bf0..84018768a1 100644..100755
--- a/indra/newview/skins/default/xui/zh/panel_world_map.xml
+++ b/indra/newview/skins/default/xui/zh/panel_world_map.xml
@@ -7,57 +7,57 @@
無效的ä½ç½®
</panel.string>
<panel.string name="world_map_north">
- N
+ 北
</panel.string>
<panel.string name="world_map_east">
E
</panel.string>
<panel.string name="world_map_west">
- W
+ 西
</panel.string>
<panel.string name="world_map_south">
- S
+ å—
</panel.string>
<panel.string name="world_map_southeast">
- SE
+ æ±å—
</panel.string>
<panel.string name="world_map_northeast">
- NE
+ æ±åŒ—
</panel.string>
<panel.string name="world_map_southwest">
- SW
+ 西å—
</panel.string>
<panel.string name="world_map_northwest">
- NW
+ 西北
</panel.string>
<panel.string name="world_map_person">
- 1 person
+ 1 人
</panel.string>
<panel.string name="world_map_people">
- [NUMBER] people
+ [NUMBER] 人
</panel.string>
- <text label="N" name="floater_map_north">
- N
+ <text label="北" name="floater_map_north">
+ 北
</text>
<text label="E" name="floater_map_east">
E
</text>
- <text label="W" name="floater_map_west">
- W
+ <text label="西" name="floater_map_west">
+ 西
</text>
- <text label="S" name="floater_map_south">
- S
+ <text label="å—" name="floater_map_south">
+ å—
</text>
- <text label="SE" name="floater_map_southeast">
- SE
+ <text label="æ±å—" name="floater_map_southeast">
+ æ±å—
</text>
- <text label="NE" name="floater_map_northeast">
- NE
+ <text label="æ±åŒ—" name="floater_map_northeast">
+ æ±åŒ—
</text>
- <text label="SW" name="floater_map_southwest">
- SW
+ <text label="西å—" name="floater_map_southwest">
+ 西å—
</text>
- <text label="NW" name="floater_map_northwest">
- NW
+ <text label="西北" name="floater_map_northwest">
+ 西北
</text>
</panel>
diff --git a/indra/newview/skins/default/xui/zh/role_actions.xml b/indra/newview/skins/default/xui/zh/role_actions.xml
index 32bf0d22d8..9587981444 100644..100755
--- a/indra/newview/skins/default/xui/zh/role_actions.xml
+++ b/indra/newview/skins/default/xui/zh/role_actions.xml
@@ -1,73 +1,73 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<role_actions>
- <action_set description="These Abilities include powers to add and remove group Members, and allow new Members to join without an invitation." name="Membership">
- <action description="邀請他人加入這個群組" longdescription="邀請他人加入這個群組,請按下於角色å€æ®µä¸­çš„æˆå“¡é ç±¤ä¸­çš„ &apos;邀請&apos; 按鈕。" name="member invite" value="1"/>
- <action description="將會員由這個群組中踢出" longdescription="Eject Members from this Group using the &apos;Eject&apos; button in the Roles section &gt; Members tab. An Owner can eject anyone except another Owner. If you&apos;re not an Owner, a Member can be ejected from a group if, and only if, they&apos;re only in the Everyone Role, and NO other Roles. To remove Members from Roles, you need to have the &apos;Remove Members from Roles&apos; Ability." name="member eject" value="2"/>
- <action description="Toggle &apos;Open Enrollment&apos; and change &apos;Enrollment fee&apos;" longdescription="Toggle &apos;Open Enrollment&apos; to let new Members join without an invitation, and change the &apos;Enrollment fee&apos; in the General section." name="member options" value="3"/>
+ <action_set description="這些能力包括新增或移除群組æˆå“¡å’Œå…許新æˆå“¡ä¸å—é‚€å³å¯åŠ å…¥ç¾¤çµ„的等權力。" name="Membership">
+ <action description="邀請他人加入這個群組" longdescription="欲邀請他人加入這個群組,請按下角色欄下的æˆå“¡é ç±¤ä¸­çš„「邀請ã€æŒ‰éˆ•ã€‚" name="member invite" value="1"/>
+ <action description="將會員由這個群組中踢出" longdescription="欲將æˆå“¡å¾žç¾¤çµ„踢出,請按下角色欄下的æˆå“¡é ç±¤ä¸­çš„「踢出ã€æŒ‰éˆ•ã€‚ 所有人å¯è¸¢å‡ºä»»ä½•ä¸å…·æ‰€æœ‰äººè§’色的人。 如果你ä¸æ˜¯æ‰€æœ‰äººï¼Œä¸€ä½æˆå“¡åªåœ¨ä»–僅屬於「任何人ã€è§’色且沒有其他角色的情æ³ä¸‹è¢«è¸¢å‡ºç¾¤çµ„。 欲å¸é™¤æˆå“¡çš„角色,你必須有「å¸é™¤æˆå“¡è§’色ã€çš„能力。" name="member eject" value="2"/>
+ <action description="切æ›ã€Œå…費自由加入ã€è¨­å®šï¼Œæ›´æ”¹ã€ŒåŠ å…¥è²»ã€ã€‚" longdescription="切æ›ã€Œå…費自由加入ã€è¨­å®šï¼Œè®“æˆå“¡ä¸å—邀也å¯åŠ å…¥ï¼Œä¸¦åœ¨åŸºæœ¬è¨­å®šæ¬„更改「加入費ã€ã€‚" name="member options" value="3"/>
</action_set>
- <action_set description="These Abilities include powers to add, remove, and change group Roles, add and remove Members in Roles, and assign Abilities to Roles." name="Roles">
- <action description="創立一個新角色" longdescription="創立一個新角色於角色å€æ®µ &gt; 角色é ç±¤ã€‚" name="role create" value="4"/>
- <action description="刪除角色" longdescription="Delete Roles in the Roles section &gt; Roles tab." name="role delete" value="5"/>
- <action description="Change Role names, titles, descriptions, and whether Role members are publicly revealed" longdescription="Change Role names, titles, descriptions, and whether Role members are publicly revealed. This is done at the bottom of the the Roles section &gt; Roles tab after selecting a Role." name="role properties" value="6"/>
- <action description="Assign Members to Assigner&apos;s Roles" longdescription="Assign Members to Roles in the list of Assigned Roles (Roles section &gt; Members tab). A Member with this Ability can only add Members to a Role that the assigner is already in." name="role assign member limited" value="7"/>
- <action description="Assign Members to Any Role" longdescription="Assign Members to Any Role in the list of Assigned Roles (Roles section &gt; Members tab). *WARNING* Any Member in a Role with this Ability can assign themselves--and any other non-Owner Member--to Roles that have more powers than they currently have, potentially elevating themselves to near-Owner power. Be sure you know what you&apos;re doing before assigning this Ability." name="role assign member" value="8"/>
- <action description="由角色中移除æˆå“¡" longdescription="Remove Members from Roles in the list of Assigned Roles (Roles section &gt; Members tab). Owners can&apos;t be removed." name="role remove member" value="9"/>
- <action description="Assign and Remove Abilities in Roles" longdescription="Assign and Remove Abilities for each Role in the list of Allowed Abilities (Roles section &gt; Roles tab). *WARNING* Any Member in a Role with this Ability can assign themselves--and any other non-Owner Member--all Abilities, potentially elevating themselves to near-Owner power. Be sure you know what you&apos;re doing before assigning this Ability." name="role change actions" value="10"/>
+ <action_set description="這些能力包括新增ã€ç§»é™¤ã€æ›´æ”¹ç¾¤çµ„角色,新增或移除æˆå“¡çš„角色,和為角色設定能力等權力。" name="Roles">
+ <action description="創立一個新角色" longdescription="到角色欄的角色é ç±¤ï¼Œå¯ä»¥å»ºç«‹æ–°è§’色。" name="role create" value="4"/>
+ <action description="刪除角色" longdescription="到角色欄的角色é ç±¤ï¼Œå¯ä»¥åˆªé™¤è§’色。" name="role delete" value="5"/>
+ <action description="變更角色å稱ã€é ­éŠœã€æ述,設定角色的æˆå“¡å單是å¦å…¬é–‹" longdescription="變更角色å稱ã€é ­éŠœã€æ述,設定角色的æˆå“¡å單是å¦å…¬é–‹ã€‚ é¸å–一個角色後,å¯åˆ°è§’色欄底下的角色é ç±¤å®Œæˆé€™å‹•ä½œã€‚" name="role properties" value="6"/>
+ <action description="賦予æˆå“¡ã€ŒæŒ‡æ´¾è€…ã€è§’色" longdescription="從已知的指派角色中é¸æ“‡è‹¥å¹²ï¼Œè³¦äºˆçµ¦æˆå“¡ï¼ˆè§’色欄 &gt; æˆå“¡é ç±¤ï¼‰ã€‚ 有這能力的æˆå“¡ï¼Œåªèƒ½æŠŠä»–自己已身負的角色賦予給別的æˆå“¡ã€‚" name="role assign member limited" value="7"/>
+ <action description="賦予æˆå“¡ã€Œä»»ä½•äººã€è§’色" longdescription="從已知的指派角色中,賦予給æˆå“¡ã€Œä»»ä½•äººã€è§’色(角色欄 &gt; æˆå“¡é ç±¤ï¼‰ã€‚ *警告* 任何身負具這能力的角色的æˆå“¡ï¼Œéƒ½å¯ä»¥æŠŠæŸäº›è§’色賦予自己或任何ä¸æ˜¯æ‰€æœ‰äººçš„æˆå“¡ï¼Œå› æ­¤ä½¿è‡ªå·±æˆ–別人得到比ç¾åœ¨æ›´å¤šçš„權力,最終å¯èƒ½æ“有近似「所有人ã€çš„權力。 賦予這項能力之å‰ï¼Œæ•¬è«‹æ…Žé‡è€ƒæ…®ã€‚" name="role assign member" value="8"/>
+ <action description="由角色中移除æˆå“¡" longdescription="從已知的指派角色中é¸æ“‡ï¼Œå°‡æˆå“¡å¸é™¤è©²è§’色(角色欄 &gt; æˆå“¡é ç±¤ï¼‰ã€‚ 所有人角色ä¸å¾—被å¸é™¤ã€‚" name="role remove member" value="9"/>
+ <action description="設定或å¸é™¤è§’色能力" longdescription="從å…許的能力清單中é¸æ“‡ï¼Œç‚ºæ¯ä¸€è§’色設定或å¸é™¤è©²èƒ½åŠ›ï¼ˆè§’色欄 &gt; 角色é ç±¤ï¼‰ã€‚ *警告* 任何身負具有這能力的角色的æˆå“¡ï¼Œéƒ½å¯ä»¥å°‡æ‰€æœ‰èƒ½åŠ›è³¦äºˆè‡ªå·±å’Œä»»ä½•å…¶ä»–ä¸æ˜¯æ‰€æœ‰äººçš„人,因此讓自己或他人æå‡ç‚ºè¿‘似「所有人ã€æ¬ŠåŠ›çš„層級。 賦予這項能力之å‰ï¼Œæ•¬è«‹æ…Žé‡è€ƒæ…®ã€‚" name="role change actions" value="10"/>
</action_set>
- <action_set description="These Abilities include powers to modify this group&apos;s identity, such as changing public visibility, charter, and insignia." name="Group Identity">
- <action description="Change Charter, Insignia, and &apos;Show in search&apos;" longdescription="Change Charter, Insignia, and &apos;Show in search&apos;. This is done in the General section." name="group change identity" value="11"/>
+ <action_set description="這些能力包括有權修改群組身份,例如更改公開程度ã€è¦ç« å’Œå¾½ç« ã€‚" name="Group Identity">
+ <action description="更改è¦ç« ã€å¾½ç« ï¼Œè¨­å®šæ˜¯å¦ã€Œé¡¯ç¤ºæ–¼æœå°‹çµæžœã€ã€‚" longdescription="更改è¦ç« ã€å¾½ç« ï¼Œè¨­å®šæ˜¯å¦ã€Œé¡¯ç¤ºæ–¼æœå°‹çµæžœã€ã€‚ 這å¯åœ¨ã€ŒåŸºæœ¬è³‡æ–™ã€æ¬„設定。" name="group change identity" value="11"/>
</action_set>
- <action_set description="These Abilities include powers to deed, modify, and sell land in this group&apos;s land holdings. To get to the About Land window, right-click the ground and select &apos;About Land&apos;, or click the &apos;i&apos; icon in the Navigation Bar." name="Parcel Management">
- <action description="讓渡土地或購買土地給群組" longdescription="Deed land and buy land for group. This is done in About Land &gt; General tab." name="land deed" value="12"/>
- <action description="Abandon land to Governor Linden" longdescription="Abandon land to Governor Linden. *WARNING* Any Member in a Role with this Ability can abandon group-owned land in About Land &gt; General tab, reverting it to Linden ownership without a sale! Be sure you know what you&apos;re doing before assigning this Ability." name="land release" value="13"/>
- <action description="Set land for sale info" longdescription="Set land for sale info. *WARNING* Any Member in a Role with this Ability can sell group-owned land in About Land &gt; General tab as they wish! Be sure you know what you&apos;re doing before assigning this Ability." name="land set sale info" value="14"/>
- <action description="Subdivide and join parcels" longdescription="Subdivide and join parcels. This is done by right-clicking the ground, &apos;Edit Terrain&apos;, and dragging your mouse on the land to make a selection. To subdivide, select what you want to split and click &apos;Subdivide&apos;. To join, select two or more contiguous parcels and click &apos;Join&apos;." name="land divide join" value="15"/>
+ <action_set description="這些能力包括有權讓渡ã€ä¿®æ”¹æˆ–出售本群組æ“有的土地。 欲å‰å¾€ã€ŒåœŸåœ°è³‡æ–™ã€è¦–窗,請在地é¢ä»»ä¸€è™•é»žæŒ‰å³éµï¼Œé¸æ“‡ã€ŒåœŸåœ°è³‡æ–™ã€ï¼Œæˆ–點按導覽列的「iã€åœ–示。" name="Parcel Management">
+ <action description="讓渡土地或購買土地給群組" longdescription="讓渡土地或為群組購地。 這å¯åœ¨ã€ŒåœŸåœ°è³‡æ–™ã€&gt; 基本é ç±¤å®Œæˆã€‚" name="land deed" value="12"/>
+ <action description="放棄土地,將所有權轉給 Governor Linden(林登總長)" longdescription="放棄土地,將所有權轉給 Governor Linden(林登總長)。 *警告* 任何身負具有這能力的角色的æˆå“¡ï¼Œéƒ½å¯ä»¥åˆ°ã€ŒåœŸåœ°è³‡æ–™ã€&gt; 基本é ç±¤æ”¾æ£„任何群組所有的土地,ä¸ç¶“出售就將所有權轉給 Lindenï¼ è³¦äºˆé€™é …èƒ½åŠ›ä¹‹å‰ï¼Œæ•¬è«‹æ…Žé‡è€ƒæ…®ã€‚" name="land release" value="13"/>
+ <action description="設定待售土地資訊" longdescription="設定待售土地資訊。 *警告* 任何身負具有這能力的角色的æˆå“¡ï¼Œéƒ½å¯ä»¥åˆ°ã€ŒåœŸåœ°è³‡æ–™ã€&gt; 基本é ç±¤ä»»æ„å‡ºå”®ç¾¤çµ„æ‰€æœ‰çš„åœŸåœ°ï¼ è³¦äºˆé€™é …èƒ½åŠ›ä¹‹å‰ï¼Œæ•¬è«‹æ…Žé‡è€ƒæ…®ã€‚" name="land set sale info" value="14"/>
+ <action description="分割或åˆä½µåœ°æ®µ" longdescription="分割或åˆä½µåœ°æ®µã€‚ 欲進行此動作,請在地é¢ä»»ä¸€è™•é»žæŒ‰å³éµï¼Œé¸æ“‡ã€Œç·¨è¼¯åœ°å½¢ã€ï¼Œä¸¦åœ¨åœŸåœ°ä¸Šæ‹–曳滑鼠é¸å–一個範åœã€‚ è¦é€²è¡Œåˆ†å‰²ï¼Œåšå¥½é¸æ“‡å¾Œé»žæŒ‰ã€Œåˆ†å‰²ã€ã€‚ è¦åˆä½µï¼Œé¸å–至少兩塊相鄰地段,å†é»žé¸ã€Œåˆä½µã€ã€‚" name="land divide join" value="15"/>
</action_set>
- <action_set description="These Abilities include powers to change the parcel name and publish settings, Find directory visibility, and landing point &amp; TP routing options." name="Parcel Identity">
- <action description="Toggle &apos;Show Place in Search&apos; and set category" longdescription="Toggle &apos;Show Place in Search&apos; and setting a parcel&apos;s category in About Land &gt; Options tab." name="land find places" value="17"/>
- <action description="Change parcel name, description, and &apos;Show Place in Search&apos; settings" longdescription="Change parcel name, description, and &apos;Show Place in Search&apos; settings. This is done in About Land &gt; Options tab." name="land change identity" value="18"/>
- <action description="Set landing point and set teleport routing" longdescription="On a group-owned parcel, Members in a Role with this Ability can set a landing point to specify where incoming teleports arrive, and also set teleport routing for further control. This is done in About Land &gt; Options tab." name="land set landing point" value="19"/>
+ <action_set description="這些能力包括å¯æ›´æ”¹åœ°æ®µå稱和發佈設定ã€è¨­å®šæ˜¯å¦å…¬é–‹åˆ°æœå°‹çµæžœã€è¨­å®šç™»é™¸åœ°é»žå’Œçž¬é–“傳é€ç¹žè·¯é¸é …。" name="Parcel Identity">
+ <action description="切æ›ã€Œå°‡åœ°é»žé¡¯ç¤ºåœ¨æœå°‹çµæžœã€è¨­å®šï¼Œä¸¦é¸å®šé¡žåˆ¥" longdescription="切æ›ã€Œå°‡åœ°é»žé¡¯ç¤ºåœ¨æœå°‹çµæžœã€è¨­å®šï¼Œä¸¦åœ¨ã€ŒåœŸåœ°è³‡æ–™ã€&gt; é¸é …é ç±¤è¨­å®šåœ°æ®µé¡žåˆ¥ã€‚" name="land find places" value="17"/>
+ <action description="更改地段å稱ã€æè¿°ã€ã€Œé©åº¦æˆäººå…§å®¹ã€è¨­å®š" longdescription="更改地段å稱ã€æè¿°ã€ã€Œé©åº¦æˆäººå…§å®¹ã€è¨­å®šã€‚ 這å¯åœ¨ã€ŒåœŸåœ°è³‡æ–™ã€&gt; é¸é …é ç±¤å®Œæˆã€‚" name="land change identity" value="18"/>
+ <action description="設定登陸地點和瞬間傳é€ç¹žè·¯è¨­å®šã€‚" longdescription="在群組所有的地段上,身負具此能力的æˆå“¡ï¼Œå¯ä»¥è¨­å®šäººå€‘瞬間傳é€é€²ä¾†æ™‚的登陸地點,和瞬間傳é€çš„繞路é¸é …。 這å¯åœ¨ã€ŒåœŸåœ°è³‡æ–™ã€&gt; é¸é …é ç±¤å®Œæˆã€‚" name="land set landing point" value="19"/>
</action_set>
- <action_set description="These Abilities include powers which affect parcel options, such as &apos;Create Objects&apos;, &apos;Edit Terrain&apos;, and music &amp; media settings." name="Parcel Settings">
- <action description="Change music &amp; media settings" longdescription="Change streaming music and movie settings in About Land &gt; Media tab." name="land change media" value="20"/>
- <action description="Toggle &apos;Edit Terrain&apos;" longdescription="Toggle &apos;Edit Terrain&apos;. *WARNING* About Land &gt; Options tab &gt; Edit Terrain allows anyone to terraform your land&apos;s shape, and place and move Linden plants. Be sure you know what you&apos;re doing before assigning this Ability. Editing terrain is toggled in About Land &gt; Options tab." name="land edit" value="21"/>
- <action description="Toggle various About Land &gt; Options settings" longdescription="Toggle &apos;Safe (no damage)&apos;, &apos;Fly&apos;, and allow other Residents to: &apos;Edit Terrain&apos;, &apos;Build&apos;, &apos;Create Landmarks&apos;, and &apos;Run Scripts&apos; on group-owned land in About Land &gt; Options tab." name="land options" value="22"/>
+ <action_set description="這些能力包括有權更改地段é¸é …,例如「新建物件ã€ã€ã€Œç·¨è¼¯åœ°å½¢ã€ï¼Œå’ŒéŸ³æ¨‚ã€åª’體設定等。" name="Parcel Settings">
+ <action description="更改音樂和媒體設定" longdescription="在「土地資料ã€&gt; 媒體é ç±¤æ›´æ”¹ä¸²æµéŸ³æ¨‚和影片設定。" name="land change media" value="20"/>
+ <action description="切æ›ã€Œç·¨è¼¯åœ°å½¢ã€è¨­å®š" longdescription="切æ›ã€Œç·¨è¼¯åœ°å½¢ã€è¨­å®šã€‚ *警告* 「土地資料ã€&gt; 「é¸é …ã€é ç±¤ &gt;「編輯地形ã€å¯å…許任何人變更你的土地形狀,放置或移動 Linden æ¤ç‰©ã€‚ 賦予這項能力之å‰ï¼Œæ•¬è«‹æ…Žé‡è€ƒæ…®ã€‚ 編輯地形å¯åœ¨ã€ŒåœŸåœ°è³‡æ–™ã€&gt; é¸é …é ç±¤åšåˆ‡æ›ã€‚" name="land edit" value="21"/>
+ <action description="切æ›å„項「土地資料ã€&gt; é¸é …設定" longdescription="在「土地資料ã€&gt; é¸é …é ç±¤åˆ‡æ›ã€Œå®‰å…¨ï¼ˆç„¡å‚·å®³ï¼‰ã€è¨­å®šï¼Œä¸¦å…許其他居民在群組所有土地上「編輯地形ã€ã€ã€Œå»ºè£½ã€ã€ã€Œå»ºç«‹åœ°æ¨™ã€ã€ã€ŒåŸ·è¡Œè…³æœ¬ã€ã€‚" name="land options" value="22"/>
</action_set>
- <action_set description="These Abilities include powers which allow Members to bypass restrictions on group-owned parcels." name="Parcel Powers">
- <action description="Always allow &apos;Edit Terrain&apos;" longdescription="Members in a Role with this Ability can edit terrain on a group-owned parcel, even if it&apos;s turned off in About Land &gt; Options tab." name="land allow edit land" value="23"/>
- <action description="Always allow &apos;Fly&apos;" longdescription="Members in a Role with this Ability can fly on a group-owned parcel, even if it&apos;s turned off in About Land &gt; Options tab." name="land allow fly" value="24"/>
- <action description="Always allow &apos;Create Objects&apos;" longdescription="Members in a Role with this Ability can create objects on a group-owned parcel, even if it&apos;s turned off in About Land &gt; Options tab." name="land allow create" value="25"/>
- <action description="總是å…許 &apos;創造地標&apos;" longdescription="Members in a Role with this Ability can landmark a group-owned parcel, even if it&apos;s turned off in About Land &gt; Options tab." name="land allow landmark" value="26"/>
- <action description="Allow &apos;Set Home to Here&apos; on group land" longdescription="Members in a Role with this Ability can use World menu &gt; Landmarks &gt; Set Home to Here on a parcel deeded to this group." name="land allow set home" value="28"/>
- <action description="Allow &apos;Event Hosting&apos; on group land" longdescription="Members in a Role with this Ability can select group owned parcels as venus when hosting an event." name="land allow host event" value="41"/>
+ <action_set description="這些能力包括å¯å…許æˆå“¡åœ¨ç¾¤çµ„所有地段上è¦é¿é™åˆ¶ã€‚" name="Parcel Powers">
+ <action description="固定å…許「編輯地形ã€" longdescription="身負具此能力的角色的æˆå“¡å¯ä»¥åœ¨ç¾¤çµ„所有地段上編輯地形,無論這功能在「土地資料ã€&gt; é¸é …é ç±¤è£¡æ˜¯å¦è¢«ç¦æ­¢ã€‚" name="land allow edit land" value="23"/>
+ <action description="固定å…許「飛行ã€" longdescription="身負具此能力的角色的æˆå“¡å¯ä»¥åœ¨ç¾¤çµ„所有地段上飛行,無論這能力是å¦åœ¨ã€ŒåœŸåœ°è³‡æ–™ã€&gt; é¸é …é ç±¤è£¡è¢«ç¦æ­¢ã€‚" name="land allow fly" value="24"/>
+ <action description="固定å…許「新建物件ã€" longdescription="身負具此能力的角色的æˆå“¡å¯ä»¥åœ¨ç¾¤çµ„所有地段上新建物件,無論這能力是å¦åœ¨ã€ŒåœŸåœ°è³‡æ–™ã€&gt; é¸é …é ç±¤è£¡è¢«ç¦æ­¢ã€‚" name="land allow create" value="25"/>
+ <action description="總是å…許「新建地標ã€" longdescription="身負具此能力的角色的æˆå“¡å¯ä»¥å°‡ç¾¤çµ„所有的地段設為地標,無論這能力是å¦åœ¨ã€ŒåœŸåœ°è³‡æ–™ã€&gt; é¸é …é ç±¤è£¡è¢«ç¦æ­¢ã€‚" name="land allow landmark" value="26"/>
+ <action description="å…許在群組所有土地上「將這裡設為我的家ã€" longdescription="身負具此能力的角色的æˆå“¡ï¼Œå¯ä»¥åœ¨è®“渡給這群組的地段上使用「世界ã€é¸å–® &gt; 地標 &gt; 「將這裡設為我的家ã€ã€‚" name="land allow set home" value="28"/>
+ <action description="å…許在群組所有土地上「開辦活動ã€" longdescription="身負具這能力的角色的æˆå“¡ï¼Œå¯ä»¥é¸æ“‡ç¾¤çµ„所有的地段作為開辦活動的場地。" name="land allow host event" value="41"/>
</action_set>
- <action_set description="These Abilities include powers to allow or restrict access to group-owned parcels, including freezing and ejecting Residents." name="Parcel Access">
- <action description="Manage parcel Access lists" longdescription="Manage parcel Access lists in About Land &gt; Access tab." name="land manage allowed" value="29"/>
- <action description="Manage parcel Ban lists" longdescription="Manage parcel Ban lists in About Land &gt; Access tab." name="land manage banned" value="30"/>
- <action description="Change parcel &apos;Sell passes to&apos; settings" longdescription="Change parcel &apos;Sell passes to&apos; settings in About Land &gt; Access tab." name="land manage passes" value="31"/>
- <action description="將地段內的居民踢出åŠå‡çµ" longdescription="Members in a Role with this Ability can handle an unwelcome Resident on a group-owned parcel by right-clicking them, then selecting &apos;Eject&apos; or &apos;Freeze&apos;." name="land admin" value="32"/>
+ <action_set description="這些能力包括å¯å…許或é™åˆ¶äººå€‘出入群組所有的地段,包括把居民å‡çµæˆ–踢出。" name="Parcel Access">
+ <action description="管ç†åœ°æ®µå‡ºå…¥è¨±å¯åå–®" longdescription="在「土地資料ã€&gt; 出入許å¯é ç±¤ç®¡ç†åœ°æ®µçš„出入許å¯å單。" name="land manage allowed" value="29"/>
+ <action description="管ç†åœ°æ®µç¦å…¥åå–®" longdescription="在「土地資料ã€&gt; 出入許å¯é ç±¤ç®¡ç†åœ°æ®µçš„ç¦å…¥å單。" name="land manage banned" value="30"/>
+ <action description="變更地段的「通行證出售å°è±¡ã€è¨­å®š" longdescription="在「土地資料ã€&gt; 出入許å¯é ç±¤è®Šæ›´åœ°æ®µçš„「通行證出售å°è±¡ã€è¨­å®šã€‚" name="land manage passes" value="31"/>
+ <action description="將地段內的居民踢出åŠå‡çµ" longdescription="身負具此能力的角色的æˆå“¡ï¼Œå¯ä»¥åœ¨ç¾¤çµ„所有地段上處置ä¸å—歡迎的居民,按å³éµåŠ ä»¥ã€Œè¸¢å‡ºã€æˆ–「å‡çµã€ã€‚" name="land admin" value="32"/>
</action_set>
- <action_set description="These Abilities include powers to allow members to return objects and place and move Linden plants. This is useful for Members to clean up litter and do landscaping, but it should also be used with care, because there&apos;s no undo for returning objects." name="Parcel Content">
- <action description="Return objects owned by group" longdescription="Return objects on group-owned parcels that are owned by the group in About Land &gt; Objects tab." name="land return group owned" value="48"/>
- <action description="Return objects set to group" longdescription="Return objects on group-owned parcels that are set to the group in About Land &gt; Objects tab." name="land return group set" value="33"/>
- <action description="退回éžç¾¤çµ„物件" longdescription="Return objects on group-owned parcels that are non-group in About Land &gt; Objects tab." name="land return non group" value="34"/>
- <action description="Landscaping using Linden plants" longdescription="Landscaping ability to place and move Linden trees, plants, and grasses. These items can be found in your inventory&apos;s Library &gt; Objects folder, or they can be created via the Build menu." name="land gardening" value="35"/>
+ <action_set description="這些能力包括有權å…許æˆå“¡é€è¿”物件,或放置或移動 Linden æ¤ç‰©ã€‚ 這能力的用處是讓æˆå“¡æ¸…ç†ä¸€ä¸‹åœŸåœ°ï¼Œåšä¸€åšæ™¯è§€ä½ˆç½®ï¼Œä½†å¿…é ˆå°å¿ƒä½¿ç”¨ï¼Œå› ç‚ºç‰©ä»¶ä¸€æ—¦è¢«é€è¿”後å³ç„¡æ³•å¾©åŽŸã€‚" name="Parcel Content">
+ <action description="é€è¿”群組所有的物件" longdescription="在「土地資料ã€&gt; 物件é ç±¤é€è¿”ä½æ–¼ç¾¤çµ„所æ“有地段上的群組所æ“有物件。" name="land return group owned" value="48"/>
+ <action description="é€è¿”設給群組的物件" longdescription="在「土地資料ã€&gt; 物件é ç±¤é€è¿”ä½æ–¼ç¾¤çµ„所æ“有地段的設給群組的物件。" name="land return group set" value="33"/>
+ <action description="退回éžç¾¤çµ„物件" longdescription="在「土地資料ã€&gt; 物件é ç±¤é€è¿”ä½æ–¼ç¾¤çµ„所æ“有地段的éžç¾¤çµ„物件。" name="land return non group" value="34"/>
+ <action description="用 Linden æ¤ç‰©ä½ˆç½®æ™¯è§€ã€‚" longdescription="å…許放置或移動 Linden 樹種ã€è‰åœ°å’Œå…¶ä»–æ¤ç‰©çš„景觀佈置能力。 這些物項在你收ç´å€çš„資æºåº« &gt; 物件資料夾å¯æ‰¾åˆ°ï¼Œä½ ä¹Ÿå¯ä»¥é€éŽã€Œå»ºè£½ã€é¸å–®åŠ ä»¥æ–°å»ºã€‚" name="land gardening" value="35"/>
</action_set>
- <action_set description="These Abilities include powers to deed, modify, and sell group-owned objects. These changes are done in the Build Tools &gt; General tab. Right-click an object and Edit to see its settings." name="Object Management">
- <action description="讓渡物件給群組" longdescription="Deed objects to group in the Build Tools &gt; General tab." name="object deed" value="36"/>
- <action description="Manipulate (move, copy, modify) group-owned objects" longdescription="Manipulate (move, copy, modify) group-owned objects in the Build Tools &gt; General tab." name="object manipulate" value="38"/>
- <action description="Set group-owned objects for sale" longdescription="Set group-owned objects for sale in the Build Tools &gt; General tab." name="object set sale" value="39"/>
+ <action_set description="這些能力包括有權讓渡ã€ä¿®æ”¹æˆ–出售本群組æ“有的物件。 這些變更å¯åœ¨ã€Œå»ºè£½å·¥å…·ã€&gt; 基本é ç±¤å®Œæˆã€‚ å°ä¸€å€‹ç‰©ä»¶é»žæŒ‰å³éµï¼Œé¸æ“‡ã€Œç·¨è¼¯ã€å³å¯å¯Ÿçœ‹å…¶è¨­å®šã€‚" name="Object Management">
+ <action description="讓渡物件給群組" longdescription="在「建製工具ã€&gt; 基本é ç±¤å°‡ç‰©ä»¶è®“渡給群組。" name="object deed" value="36"/>
+ <action description="æ“縱(移動ã€è¤‡è£½ã€ä¿®æ”¹ï¼‰ç¾¤çµ„所æ“有物件" longdescription="在「建製工具ã€&gt; 基本é ç±¤æ“縱(移動ã€è¤‡è£½ã€ä¿®æ”¹ï¼‰ç¾¤çµ„所æ“有物件。" name="object manipulate" value="38"/>
+ <action description="設定出售群組所æ“有物件" longdescription="在「建製工具ã€&gt; 基本é ç±¤è¨­å®šå‡ºå”®ç¾¤çµ„所æ“有物件。" name="object set sale" value="39"/>
</action_set>
- <action_set description="These Abilities include powers which require Members to pay group liabilities and receive group dividends, and restrict access to group account history." name="Accounting">
- <action description="Pay group liabilities and receive group dividends" longdescription="Members in a Role with this Ability will automatically pay group liabilities and receive group dividends. This means they will receive a portion of group-owned land sales which are distributed daily, as well as contribute towards things like parcel listing fees." name="accounting accountable" value="40"/>
+ <action_set description="這些能力包括有權è¦æ±‚æˆå“¡æ”¯ä»˜ç¾¤çµ„開銷ã€æ”¶å–群組利æ¯ï¼Œé™åˆ¶ç¾¤çµ„帳號歷å²é–‹æ”¾å°è±¡ã€‚" name="Accounting">
+ <action description="支付群組開銷,收å–群組利æ¯" longdescription="身負具這能力的角色的æˆå“¡ï¼Œå°‡è‡ªå‹•æ”¯ä»˜ç¾¤çµ„開銷並收å–群組利æ¯ã€‚ 這表示他們將ç²å–群組所æ“有土地出售後的部分收入,æ¯æ—¥çµç®—,åŒæ™‚並分攤地段刊登費等開銷。" name="accounting accountable" value="40"/>
</action_set>
- <action_set description="These Abilities include powers to allow Members to send, receive, and view group Notices." name="Notices">
- <action description="é€å‡ºé€šçŸ¥" longdescription="Members in a Role with this Ability can send Notices via the Group &gt; Notices section." name="notices send" value="42"/>
- <action description="接收通知與察看éŽåŽ»é€šçŸ¥" longdescription="Members in a Role with this Ability can receive Notices and view past Notices in Group &gt; Notices section." name="notices receive" value="43"/>
+ <action_set description="這些能力包括å¯å…許æˆå“¡ç™¼é€ã€æŽ¥æ”¶ä¸¦å¯Ÿçœ‹ç¾¤çµ„通知。" name="Notices">
+ <action description="é€å‡ºé€šçŸ¥" longdescription="身負具這能力的角色的æˆå“¡ï¼Œå¯ä»¥åˆ°ã€Œç¾¤çµ„ã€&gt; 通知欄發é€é€šçŸ¥ã€‚" name="notices send" value="42"/>
+ <action description="接收通知與察看éŽåŽ»é€šçŸ¥" longdescription="身負具這能力的角色的æˆå“¡ï¼Œå¯ä»¥åˆ°ã€Œç¾¤çµ„ã€&gt; 通知欄接收通知並察看éŽåŽ»çš„通知。" name="notices receive" value="43"/>
</action_set>
- <action_set description="These Abilities include powers to allow or restrict access to group chat sessions and group voice chat." name="Chat">
- <action description="加入群組èŠå¤©" longdescription="Members in a Role with this Ability can join group chat sessions, for text and voice." name="join group chat" value="16"/>
- <action description="加入群組語音èŠå¤©" longdescription="Members in a Role with this Ability can join group voice chat sessions. NOTE: The Join Group Chat ability is required to access the voice chat session." name="join voice chat" value="27"/>
- <action description="é©åº¦æˆäººå…§å®¹çš„群組èŠå¤©" longdescription="Members in a Role with this Ability can control access and participation in group voice and text chat sessions." name="moderate group chat" value="37"/>
+ <action_set description="這些能力包括å¯å…許或é™åˆ¶äººå€‘加入群組èŠå¤©æœƒè©±å’Œç¾¤çµ„語音èŠå¤©ã€‚" name="Chat">
+ <action description="加入群組èŠå¤©" longdescription="身負具這能力的角色的æˆå“¡ï¼Œå¯ä»¥åŠ å…¥ç¾¤çµ„的文字或語音èŠå¤©æœƒè©±ã€‚" name="join group chat" value="16"/>
+ <action description="加入群組語音èŠå¤©" longdescription="身負具這能力的角色的æˆå“¡ï¼Œå¯ä»¥åŠ å…¥ç¾¤çµ„的語音èŠå¤©æœƒè©±ã€‚ 注æ„:欲加入語音èŠå¤©æœƒè©±ï¼Œéœ€æœ‰ã€ŒåŠ å…¥ç¾¤çµ„èŠå¤©ã€èƒ½åŠ›ã€‚" name="join voice chat" value="27"/>
+ <action description="é©åº¦æˆäººå…§å®¹çš„群組èŠå¤©" longdescription="身負具這能力的角色的æˆå“¡ï¼Œå¯ä»¥æŽ§åˆ¶èª°å¯åŠ å…¥ç¾¤çµ„語音和文字èŠå¤©æœƒè©±ã€‚" name="moderate group chat" value="37"/>
</action_set>
</role_actions>
diff --git a/indra/newview/skins/default/xui/zh/sidepanel_appearance.xml b/indra/newview/skins/default/xui/zh/sidepanel_appearance.xml
index 7d8a502594..83a9bdf6a5 100644..100755
--- a/indra/newview/skins/default/xui/zh/sidepanel_appearance.xml
+++ b/indra/newview/skins/default/xui/zh/sidepanel_appearance.xml
@@ -11,7 +11,7 @@
(狀態)
</text>
<text name="currentlook_name">
- MyOutfit With a really Long Name like MOOSE
+ å稱很長ã€å¾ˆé•·ã€å¾ˆé•·ã€å¾ˆé•·ã€å¾ˆé•·çš„ MyOutfit
</text>
<button label="" name="edit_outfit_btn" tool_tip="編輯這è£æ‰®"/>
</panel>
diff --git a/indra/newview/skins/default/xui/zh/sidepanel_inventory.xml b/indra/newview/skins/default/xui/zh/sidepanel_inventory.xml
index 7abe95a402..c8aae15011 100644..100755
--- a/indra/newview/skins/default/xui/zh/sidepanel_inventory.xml
+++ b/indra/newview/skins/default/xui/zh/sidepanel_inventory.xml
@@ -1,16 +1,37 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel label="事物" name="objects panel">
<panel label="" name="sidepanel__inventory_panel">
+ <layout_stack name="inventory_layout_stack">
+ <layout_panel name="inbox_layout_panel">
+ <panel label="" name="marketplace_inbox">
+ <string name="InboxLabelWithArg">
+ 收到的物項 ([NUM])
+ </string>
+ <string name="InboxLabelNoArg">
+ 收到的物項
+ </string>
+ <button label="收到的物項" name="inbox_btn"/>
+ <text name="inbox_fresh_new_count">
+ [NUM] é …æ–°çš„
+ </text>
+ <panel name="inbox_inventory_placeholder_panel" tool_tip="將物項拖曳置放到收ç´å€ï¼Œå³å¯é–‹å§‹ä½¿ç”¨">
+ <text name="inbox_inventory_placeholder">
+ 從第二人生購物市集購得物項將é€åˆ°é€™è£¡ã€‚
+ </text>
+ </panel>
+ </panel>
+ </layout_panel>
+ </layout_stack>
<panel name="button_panel">
<layout_stack name="button_panel_ls">
<layout_panel name="info_btn_lp">
<button label="檔案" name="info_btn" tool_tip="顯示物件檔案"/>
</layout_panel>
<layout_panel name="share_btn_lp">
- <button label="分享" name="share_btn" tool_tip="Share an inventory item"/>
+ <button label="分享" name="share_btn" tool_tip="分享一個收ç´å€ç‰©å“"/>
</layout_panel>
<layout_panel name="shop_btn_lp">
- <button label="Shop" name="shop_btn" tool_tip="Open Marketplace webpage"/>
+ <button label="購物" name="shop_btn" tool_tip="é–‹å•Ÿ Marketplace 購物市集網é "/>
<button label="穿上" name="wear_btn" tool_tip="穿上所é¸æ“‡çš„è£æ‰®"/>
<button label="播放" name="play_btn"/>
<button label="瞬間傳é€" name="teleport_btn" tool_tip="瞬間傳é€åˆ°æ‰€é¸çš„å€åŸŸ"/>
diff --git a/indra/newview/skins/default/xui/zh/sidepanel_item_info.xml b/indra/newview/skins/default/xui/zh/sidepanel_item_info.xml
index adc815fb4b..1b093e0ecd 100644..100755
--- a/indra/newview/skins/default/xui/zh/sidepanel_item_info.xml
+++ b/indra/newview/skins/default/xui/zh/sidepanel_item_info.xml
@@ -3,6 +3,9 @@
<panel.string name="unknown">
(未知)
</panel.string>
+ <panel.string name="unknown_multiple">
+ (未知 / 多項)
+ </panel.string>
<panel.string name="public">
(公開)
</panel.string>
@@ -10,7 +13,7 @@
ä½ å¯ä»¥ï¼š
</panel.string>
<panel.string name="owner_can">
- æ“有者å¯ä»¥ï¼š
+ 所有人å¯ä»¥ï¼š
</panel.string>
<panel.string name="acquiredDate">
[wkday,datetime,local] [mth,datetime,local] [day,datetime,local] [hour,datetime,local]:[min,datetime,local]:[second,datetime,local] [year,datetime,local]
@@ -19,7 +22,7 @@
(收ç´å€ï¼‰
</panel.string>
<panel.string name="origin_inworld">
- (Inworld)
+ (在虛擬世界)
</panel.string>
<text name="title" value="物å“檔案"/>
<text name="origin" value="(收ç´å€ï¼‰"/>
@@ -35,7 +38,7 @@
創造者:
</text>
<text name="LabelOwnerTitle">
- æ“有者:
+ 所有人:
</text>
<text name="LabelAcquiredTitle">
å–得於:
@@ -45,26 +48,26 @@
ä½ å¯ä»¥ï¼š
</text>
<check_box label="修改" name="CheckOwnerModify"/>
- <check_box label="覆製" name="CheckOwnerCopy"/>
+ <check_box label="æšåº¨" name="CheckOwnerCopy"/>
<check_box label="轉移" name="CheckOwnerTransfer"/>
<text name="AnyoneLabel">
任何人:
</text>
- <check_box label="覆製" name="CheckEveryoneCopy"/>
+ <check_box label="æšåº¨" name="CheckEveryoneCopy"/>
<text name="GroupLabel">
群組:
</text>
- <check_box label="分享" name="CheckShareWithGroup" tool_tip="Allow all members of the set group to share your modify permissions for this object. You must Deed to enable role restrictions."/>
+ <check_box label="分享" name="CheckShareWithGroup" tool_tip="å…許此群組所有æˆå“¡å…±äº«ä½ ä¿®æ”¹æ­¤ç‰©ä»¶çš„權é™ã€‚ 你必須讓渡æ‰èƒ½å•Ÿå‹•è§’色é™åˆ¶ã€‚"/>
<text name="NextOwnerLabel">
- 下一個æ“有者:
+ 下一個所有人:
</text>
<check_box label="修改" name="CheckNextOwnerModify"/>
- <check_box label="覆製" name="CheckNextOwnerCopy"/>
- <check_box label="轉移" name="CheckNextOwnerTransfer" tool_tip="Next owner can give away or resell this object"/>
+ <check_box label="æšåº¨" name="CheckNextOwnerCopy"/>
+ <check_box label="轉移" name="CheckNextOwnerTransfer" tool_tip="下一個所有人å¯è´ˆé€æˆ–轉售這個物件"/>
</panel>
<check_box label="出售" name="CheckPurchase"/>
<combo_box name="combobox sale copy">
- <combo_box.item label="副本" name="Copy"/>
+ <combo_box.item label="æšåº¨" name="Copy"/>
<combo_box.item label="原件" name="Original"/>
</combo_box>
<spinner label="價格: L$" name="Edit Cost"/>
diff --git a/indra/newview/skins/default/xui/zh/sidepanel_task_info.xml b/indra/newview/skins/default/xui/zh/sidepanel_task_info.xml
index 3d46e52726..60f44a3d88 100644..100755
--- a/indra/newview/skins/default/xui/zh/sidepanel_task_info.xml
+++ b/indra/newview/skins/default/xui/zh/sidepanel_task_info.xml
@@ -7,28 +7,34 @@
讓渡
</panel.string>
<panel.string name="text modify info 1">
- ä½ å¯ä»¥ä¿®æ”¹é€™å€‹ç‰©ä»¶
+ 你能修改這個物件
</panel.string>
<panel.string name="text modify info 2">
- ä½ å¯ä»¥ä¿®æ”¹é€™äº›ç‰©ä»¶
+ 你能修改這些物件
</panel.string>
<panel.string name="text modify info 3">
- ä½ ä¸å¯ä»¥ä¿®æ”¹é€™å€‹ç‰©ä»¶
+ ä½ ä¸èƒ½ä¿®æ”¹é€™å€‹ç‰©ä»¶
</panel.string>
<panel.string name="text modify info 4">
- ä½ ä¸å¯ä»¥ä¿®æ”¹é€™äº›ç‰©ä»¶
+ ä½ ä¸èƒ½ä¿®æ”¹é€™äº›ç‰©ä»¶
+ </panel.string>
+ <panel.string name="text modify info 5">
+ 無法跨地å€ä¿®æ”¹é€™å€‹ç‰©ä»¶
+ </panel.string>
+ <panel.string name="text modify info 6">
+ 無法跨地å€ä¿®æ”¹é€™äº›ç‰©ä»¶
</panel.string>
<panel.string name="text modify warning">
- 這個物件有è¯çµåˆ°å…¶ä»–部分
+ 這個物件å«æœ‰è¯çµçš„部分
</panel.string>
<panel.string name="Cost Default">
價格: L$
</panel.string>
<panel.string name="Cost Total">
- 總價: L$
+ 總價:L$
</panel.string>
<panel.string name="Cost Per Unit">
- 單價: L$
+ 單價:L$
</panel.string>
<panel.string name="Cost Mixed">
æ··åˆåƒ¹æ ¼
@@ -37,7 +43,7 @@
æ··åˆéŠ·å”®
</panel.string>
<text name="title" value="物件檔案"/>
- <text name="where" value="(Inworld)"/>
+ <text name="where" value="(在虛擬世界)"/>
<panel label="" name="properties_panel">
<text name="Name:">
å稱:
@@ -49,23 +55,24 @@
創造者:
</text>
<text name="Owner:">
- æ“有者:
+ 所有人:
</text>
<text name="Group_label">
群組:
</text>
- <button name="button set group" tool_tip="é¸æ“‡ä¸€å€‹ç¾¤çµ„以分享這個物件的權é™"/>
+ <button name="button set group" tool_tip="é¸æ“‡ä¸€å€‹ç¾¤çµ„以分享這物件的權é™"/>
<name_box initial_value="載入中..." name="Group Name Proxy"/>
- <button label="讓渡" label_selected="讓渡" name="button deed" tool_tip="Deeding gives this item away with next owner permissions. Group shared objects can be deeded by a group officer."/>
+ <button label="讓渡" label_selected="讓渡" name="button deed" tool_tip="「讓渡ã€æœƒæŠŠé€™ç‰©ä»¶è´ˆé€å‡ºåŽ»ä¸¦è³¦äºˆã€Œä¸‹ä¸€å€‹æ‰€æœ‰äººã€æ¬Šé™ã€‚ 群組所分享的物件å¯ç”±ç¾¤çµ„è·å“¡åŠ ä»¥è®“渡。"/>
<text name="label click action">
- 點擊以:
+ 點按以:
</text>
<combo_box name="clickaction">
<combo_box.item label="觸碰(é è¨­ï¼‰" name="Touch/grab(default)"/>
<combo_box.item label="å在物件上" name="Sitonobject"/>
<combo_box.item label="購買物件" name="Buyobject"/>
<combo_box.item label="支付物件" name="Payobject"/>
- <combo_box.item label="é–‹å•Ÿ" name="Open"/>
+ <combo_box.item label="打開" name="Open"/>
+ <combo_box.item label="縮放" name="Zoom"/>
</combo_box>
<panel name="perms_inv">
<text name="perm_modify">
@@ -74,27 +81,30 @@
<text name="Anyone can:">
任何人:
</text>
- <check_box label="覆製" name="checkbox allow everyone copy"/>
+ <check_box label="æšåº¨" name="checkbox allow everyone copy"/>
<check_box label="移動" name="checkbox allow everyone move"/>
<text name="GroupLabel">
群組:
</text>
- <check_box label="分享" name="checkbox share with group" tool_tip="Allow all members of the set group to share your modify permissions for this object. You must Deed to enable role restrictions."/>
+ <check_box label="分享" name="checkbox share with group" tool_tip="å…許此群組所有æˆå“¡å…±äº«ä½ ä¿®æ”¹æ­¤ç‰©ä»¶çš„權é™ã€‚ 你必須讓渡æ‰èƒ½å•Ÿå‹•è§’色é™åˆ¶ã€‚"/>
<text name="NextOwnerLabel">
- 下一個æ“有者:
+ 下一個所有人:
</text>
<check_box label="修改" name="checkbox next owner can modify"/>
- <check_box label="覆製" name="checkbox next owner can copy"/>
- <check_box label="轉移" name="checkbox next owner can transfer" tool_tip="下一個æ“有者å¯ä»¥é€å‡ºæˆ–轉售這個物件"/>
+ <check_box label="æšåº¨" name="checkbox next owner can copy"/>
+ <check_box label="轉移" name="checkbox next owner can transfer" tool_tip="下一個所有人å¯è´ˆé€æˆ–轉售這個物件"/>
</panel>
<check_box label="出售" name="checkbox for sale"/>
<combo_box name="sale type">
- <combo_box.item label="副本" name="Copy"/>
+ <combo_box.item label="æšåº¨" name="Copy"/>
<combo_box.item label="內容" name="Contents"/>
<combo_box.item label="原件" name="Original"/>
</combo_box>
<spinner label="價格: L$" name="Edit Cost"/>
<check_box label="顯示在æœå°‹ä¸­" name="search_check" tool_tip="讓其他人å¯ä»¥åœ¨æœå°‹çµæžœä¸­å¯Ÿçœ‹åˆ°æ­¤ç‰©ä»¶"/>
+ <text name="pathfinding_attributes_label">
+ 尋徑屬性:
+ </text>
<text name="B:">
B:
</text>
@@ -115,7 +125,7 @@
</text>
</panel>
<panel name="button_panel">
- <button label="é–‹å•Ÿ" name="open_btn"/>
+ <button label="打開" name="open_btn"/>
<button label="支付" name="pay_btn"/>
<button label="購買" name="buy_btn"/>
<button label="細節" name="details_btn"/>
diff --git a/indra/newview/skins/default/xui/zh/strings.xml b/indra/newview/skins/default/xui/zh/strings.xml
index 6dbe44d32e..d9fa105ef4 100644..100755
--- a/indra/newview/skins/default/xui/zh/strings.xml
+++ b/indra/newview/skins/default/xui/zh/strings.xml
@@ -29,11 +29,14 @@
å¿«å–清除中...
</string>
<string name="StartupInitializingTextureCache">
- æ質快å–åˆå§‹åŒ–中...
+ 正在åˆå§‹åŒ–æ質快å–...
</string>
<string name="StartupInitializingVFS">
VFS åˆå§‹åŒ–中...
</string>
+ <string name="StartupRequireDriverUpdate">
+ 顯åƒåˆå§‹åŒ–失敗。 請更新你的顯åƒå¡é©…動程å¼ï¼
+ </string>
<string name="ProgressRestoring">
回存中...
</string>
@@ -44,7 +47,7 @@
全亮(舊版)
</string>
<string name="LoginInProgress">
- 登入中。[APP_NAME] å¯èƒ½å‡ºç¾å‡çµç‹€æ…‹ã€‚è«‹è€å¿ƒç¨ç­‰ã€‚
+ 登入中。[APP_NAME] å¯èƒ½çœ‹ä¼¼å‡çµï¼Œè«‹è€å¿ƒç¨ç­‰ã€‚ è«‹ç¨å€™ã€‚
</string>
<string name="LoginInProgressNoFrozen">
登入中...
@@ -56,7 +59,7 @@
進行帳戶維護...
</string>
<string name="LoginAttempt">
- å…ˆå‰ä¼åœ–嘗試登入失敗。ç¾ç™»å…¥ä¸­ï¼Œå˜—試 [NUMBER]
+ å‰ä¸€æ¬¡ç™»å…¥å¤±æ•—。 登入中,第 [NUMBER] 次嘗試
</string>
<string name="LoginPrecaching">
世界載入中...
@@ -74,10 +77,10 @@
驗證快å–檔案(約需 60-90 秒左å³ï¼‰...
</string>
<string name="LoginProcessingResponse">
- 回應處ç†ä¸­...
+ 正在處ç†å›žæ‡‰...
</string>
<string name="LoginInitializingWorld">
- 世界åˆå§‹åŒ–中...
+ 正在åˆå§‹åŒ–虛擬世界…
</string>
<string name="LoginDecodingImages">
圖åƒè§£ç¢¼ä¸­...
@@ -91,6 +94,12 @@
<string name="LoginQuicktimeOK">
QuickTime å·²æˆåŠŸåˆå§‹åŒ–。
</string>
+ <string name="LoginRequestSeedCapGrant">
+ è©¢å•åœ°å€è² è·åŠ›â€¦
+ </string>
+ <string name="LoginRetrySeedCapGrant">
+ è©¢å•åœ°å€è² è·åŠ›ï¼Œç¬¬ [NUMBER] 次嘗試…
+ </string>
<string name="LoginWaitingForRegionHandshake">
地å€äº¤æ¡ç­‰å¾…中...
</string>
@@ -101,25 +110,25 @@
æœè£ä¸‹è¼‰ä¸­...
</string>
<string name="InvalidCertificate">
- 伺æœå™¨å›žå‚³ä¸€å€‹ç„¡æ•ˆæžœæ壞的憑證。請連繫網格管ç†è€…。
+ 伺æœå™¨å›žå‚³ä¸€å€‹ç„¡æ•ˆæˆ–æ壞的憑證。 è«‹è¯çµ¡ç¶²æ ¼ç®¡ç†å“¡ã€‚
</string>
<string name="CertInvalidHostname">
- An invalid hostname was used to access the server, please check your SLURL or Grid hostname.
+ 用了無效的主機å來è¯çµ¡ä¼ºæœå™¨ï¼Œè«‹æª¢æŸ¥ä½ çš„ SLURL 或網格主機å。
</string>
<string name="CertExpired">
- The certificate returned by the Grid appears to be expired. Please check your system clock, or contact your Grid administrator.
+ 網格傳回的憑證似乎已éŽæœŸã€‚ 請檢查系統時é˜ï¼Œæˆ–è¯çµ¡ç¶²æ ¼ç®¡ç†å“¡ã€‚
</string>
<string name="CertKeyUsage">
- The certificate returned by the server could not be used for SSL. Please contact your Grid administrator.
+ 伺æœå™¨å‚³å›žçš„憑證無法用於 SSL。 è«‹è¯çµ¡ç¶²æ ¼ç®¡ç†å“¡ã€‚
</string>
<string name="CertBasicConstraints">
- Too many certificates were in the servers Certificate chain. Please contact your Grid administrator.
+ 伺æœå™¨æ†‘è­‰éŠä¸­çš„憑證數目太多。 è«‹è¯çµ¡ç¶²æ ¼ç®¡ç†å“¡ã€‚
</string>
<string name="CertInvalidSignature">
- The certificate signature returned by the Grid server could not be verified. Please contact your Grid administrator.
+ 無法檢驗通éŽç¶²æ ¼ä¼ºæœå™¨å‚³å›žçš„憑證簽å。 è«‹è¯çµ¡ç¶²æ ¼ç®¡ç†å“¡ã€‚
</string>
<string name="LoginFailedNoNetwork">
- Network Error: Could not establish connection, please check your network connection.
+ 網路錯誤:無法建立連線,請檢查網路連線是å¦æ­£å¸¸ã€‚
</string>
<string name="LoginFailed">
登入失敗。
@@ -128,10 +137,141 @@
çµæŸé€€å‡º
</string>
<string name="create_account_url">
- http://join.secondlife.com/
+ http://join.secondlife.com/?sourceid=[sourceid]
+ </string>
+ <string name="ViewerDownloadURL">
+ http://secondlife.com/download
+ </string>
+ <string name="LoginFailedViewerNotPermitted">
+ ä½ ç›®å‰æ‰€ç”¨çš„ Viewer 已經無法å†é€²å…¥ç¬¬äºŒäººç”Ÿã€‚ 請到這個é é¢ä¸‹è¼‰æœ€æ–° Viewer:
+http://secondlife.com/download
+
+欲知詳情,請åƒé–±ä¸‹é¢çš„常見å•é¡Œé›†ï¼š
+http://secondlife.com/viewer-access-faq
+ </string>
+ <string name="LoginIntermediateOptionalUpdateAvailable">
+ 有å¯ä»¥é¸æ“‡æ€§å®‰è£çš„更新版:[VERSION]
+ </string>
+ <string name="LoginFailedRequiredUpdate">
+ 你必須更新為這個版本:[VERSION]
+ </string>
+ <string name="LoginFailedAlreadyLoggedIn">
+ 此用戶已經登入。
+ </string>
+ <string name="LoginFailedAuthenticationFailed">
+ æŠ±æ­‰ï¼ æˆ‘å€‘ç„¡æ³•è®“ä½ ç™»å…¥ã€‚
+請檢查確定你輸入了正確的
+ * 使用者å稱(例:bobsmith123 或 steller.sunshine)
+ * 密碼
+並請確定éµç›¤æ²’有鎖定大寫éµã€‚
+ </string>
+ <string name="LoginFailedPasswordChanged">
+ 為了安全起見,已經變更你的密碼。
+請到ä½æ–¼ http://secondlife.com/password 的帳號é é¢
+回答安全驗證å•é¡Œå¾Œï¼Œé‡è¨­å¯†ç¢¼ã€‚
+如有造æˆä¸ä¾¿è«‹å¤šåŒ…涵。
+ </string>
+ <string name="LoginFailedPasswordReset">
+ 我們系統有所變更,你必須é‡è¨­å¯†ç¢¼ã€‚
+請到ä½æ–¼ http://secondlife.com/password 的帳號é é¢
+回答安全驗證å•é¡Œå¾Œï¼Œé‡è¨­å¯†ç¢¼ã€‚
+如有造æˆä¸ä¾¿è«‹å¤šåŒ…涵。
+ </string>
+ <string name="LoginFailedEmployeesOnly">
+ 第二人生目å‰æš«æ™‚關閉進行維護。
+ç›®å‰åƒ…å…許林登員工登入。
+請到 www.secondlife.com/status 察看最新公告。
+ </string>
+ <string name="LoginFailedPremiumOnly">
+ 第二人生此時暫時é™åˆ¶ç™»å…¥ï¼Œä»¥ç¢ºä¿ä¸å½±éŸ¿æ•ˆèƒ½ï¼Œè®“ç›®å‰è™›æ“¬ä¸–界裡的用戶享å—最佳的體驗。
+
+å…費帳戶的用戶此時暫時無法進入第二人生,因為我們必須優先容ç´ä»˜è²»ç”¨æˆ¶ã€‚
+ </string>
+ <string name="LoginFailedComputerProhibited">
+ 無法從這部電腦進入第二人生。
+如你èªç‚ºé€™æ˜¯æˆ‘們弄錯,請è¯çµ¡ support@secondlife.com。
+ </string>
+ <string name="LoginFailedAcountSuspended">
+ 你的帳號è¦ç­‰åˆ° [TIME] (太平洋時間)æ‰å¯ä½¿ç”¨ã€‚
+ </string>
+ <string name="LoginFailedAccountDisabled">
+ 此時無法完æˆä½ çš„請求。
+請到 http://secondlife.com/support è¯çµ¡æ”¯æ´äººå“¡ç²å¾—幫助。
+如果你無法變更密碼,請致電 (866) 476-9763 (美國)。
+ </string>
+ <string name="LoginFailedTransformError">
+ 登入時的資料ä¸ä¸€è‡´ã€‚
+è«‹è¯çµ¡ support@secondlife.com。
+ </string>
+ <string name="LoginFailedAccountMaintenance">
+ 你的帳號目å‰æ­£åœ¨é€²è¡Œå°è¦æ¨¡çš„維護。
+你的帳號è¦ç­‰åˆ° [TIME] (太平洋時間)æ‰å¯ä½¿ç”¨ã€‚
+如你èªç‚ºé€™æ˜¯æˆ‘們弄錯,請è¯çµ¡ support@secondlife.com。
+ </string>
+ <string name="LoginFailedPendingLogoutFault">
+ 模擬器回應:登出請求出錯。
+ </string>
+ <string name="LoginFailedPendingLogout">
+ 系統正在處ç†ä½ çš„登出。
+你的帳號è¦ç­‰åˆ° [TIME] (太平洋時間)æ‰å¯ä½¿ç”¨ã€‚
+ </string>
+ <string name="LoginFailedUnableToCreateSession">
+ 無法建立有效的時域。
+ </string>
+ <string name="LoginFailedUnableToConnectToSimulator">
+ 無法連接到模擬器。
+ </string>
+ <string name="LoginFailedRestrictedHours">
+ 你的帳號僅能在 [START] 到 [END] (太平洋時間)時段進入第二人生。
+è«‹è€å¿ƒç­‰åˆ°è©²æ™‚段å†å›žä¾†ã€‚
+如你èªç‚ºé€™æ˜¯æˆ‘們弄錯,請è¯çµ¡ support@secondlife.com。
+ </string>
+ <string name="LoginFailedIncorrectParameters">
+ 錯誤的åƒæ•¸ã€‚
+如你èªç‚ºé€™æ˜¯æˆ‘們弄錯,請è¯çµ¡ support@secondlife.com。
+ </string>
+ <string name="LoginFailedFirstNameNotAlphanumeric">
+ å…¨å的第一個字(first name)須為英文字æ¯æˆ–數字。
+如你èªç‚ºé€™æ˜¯æˆ‘們弄錯,請è¯çµ¡ support@secondlife.com。
+ </string>
+ <string name="LoginFailedLastNameNotAlphanumeric">
+ å…¨å的第二個字(last name)須為英文字æ¯æˆ–數字。
+如你èªç‚ºé€™æ˜¯æˆ‘們弄錯,請è¯çµ¡ support@secondlife.com。
+ </string>
+ <string name="LogoutFailedRegionGoingOffline">
+ 地å€å³å°‡é›¢ç·šã€‚
+è«‹ç¨å¾…一分é˜å†è©¦ã€‚
+ </string>
+ <string name="LogoutFailedAgentNotInRegion">
+ 用戶ä¸åœ¨åœ°å€è£¡ã€‚
+è«‹ç¨å¾…一分é˜å†è©¦ã€‚
+ </string>
+ <string name="LogoutFailedPendingLogin">
+ 地å€æ­£åœ¨ç™»å…¥å¦ä¸€å€‹æ™‚域。
+è«‹ç¨å¾…一分é˜å†è©¦ã€‚
+ </string>
+ <string name="LogoutFailedLoggingOut">
+ 地å€æ­£åœ¨ç™»å…¥ä¸Šä¸€å€‹æ™‚域。
+è«‹ç¨å¾…一分é˜å†è©¦ã€‚
+ </string>
+ <string name="LogoutFailedStillLoggingOut">
+ 地å€æ­£åœ¨ç™»å‡ºä¸Šä¸€å€‹æ™‚域。
+è«‹ç¨å¾…一分é˜å†è©¦ã€‚
+ </string>
+ <string name="LogoutSucceeded">
+ 地å€å‰›å‰›ç™»å‡ºä¸Šä¸€å€‹æ™‚域。
+è«‹ç¨å¾…一分é˜å†è©¦ã€‚
+ </string>
+ <string name="LogoutFailedLogoutBegun">
+ 地å€å·²ç¶“開始登出程åºã€‚
+è«‹ç¨å¾…一分é˜å†è©¦ã€‚
+ </string>
+ <string name="LoginFailedLoggingOutSession">
+ 系統已經開始登出你的上一個時域。
+è«‹ç¨å¾…一分é˜å†è©¦ã€‚
</string>
<string name="AgentLostConnection">
- 這個地å€å¯èƒ½é­é‡å•é¡Œï¼Œè«‹æª¢æŸ¥ä½ çš„網路連線。
+ 本å€åŸŸå¯èƒ½æ­£ç™¼ç”Ÿå•é¡Œã€‚ 請檢查你的網際網路連線是å¦æ­£å¸¸ã€‚
</string>
<string name="SavingSettings">
你的設定儲存中...
@@ -158,7 +298,7 @@
(無å稱)
</string>
<string name="TooltipOwner">
- æ“有者:
+ 所有人:
</string>
<string name="TooltipPublic">
公開
@@ -196,60 +336,90 @@
<string name="TooltipMustSingleDrop">
åªæœ‰ä¸€å€‹ç‰©å“å¯ä»¥è¢«æ‹–曳到此處
</string>
- <string name="TooltipPrice" value="L$[AMOUNT]:"/>
+ <string name="TooltipPrice" value="L$[AMOUNT]:"/>
+ <string name="TooltipOutboxDragToWorld">
+ 商家發件匣內的物項無法產生到虛擬世界
+ </string>
+ <string name="TooltipOutboxNoTransfer">
+ 至少一個物件無法出售或轉移。
+ </string>
+ <string name="TooltipOutboxNotInInventory">
+ 你的商家發件匣åªèƒ½æŽ¥å—直接來自收ç´å€çš„物項。
+ </string>
+ <string name="TooltipOutboxWorn">
+ 你穿著中的物項無法放入商家發件匣。
+ </string>
+ <string name="TooltipOutboxCallingCard">
+ å片ä¸å¾—放入商家發件匣
+ </string>
+ <string name="TooltipOutboxFolderLevels">
+ å·¢ç‹€è³‡æ–™å¤¾æ·±åº¦è¶…éŽ 3
+ </string>
+ <string name="TooltipOutboxTooManyFolders">
+ 頂層資料夾的å­è³‡æ–™å¤¾æ•¸ç›®è¶…éŽ 20
+ </string>
+ <string name="TooltipOutboxTooManyObjects">
+ é ‚å±¤è³‡æ–™å¤¾ç‰©é …æ•¸ç›®è¶…éŽ 200
+ </string>
+ <string name="TooltipDragOntoOwnChild">
+ 資料夾ä¸å¾—移到其å­è³‡æ–™å¤¾åº•ä¸‹
+ </string>
+ <string name="TooltipDragOntoSelf">
+ 資料夾移動的目標ä¸å¾—為它本身
+ </string>
<string name="TooltipHttpUrl">
- 點擊以察看這個網é 
+ 點按以察看這個網é 
</string>
<string name="TooltipSLURL">
- 點擊以察看這個ä½ç½®è³‡è¨Š
+ 點按以察看這個ä½ç½®è³‡è¨Š
</string>
<string name="TooltipAgentUrl">
- 點擊以察看這個居民檔案
+ 點按以察看這個居民檔案
</string>
<string name="TooltipAgentInspect">
瞭解更多有關這個居民
</string>
<string name="TooltipAgentMute">
- 點擊以å°éŽ–這ä½å±…æ°‘
+ 點按以å°éŽ–這ä½å±…æ°‘
</string>
<string name="TooltipAgentUnmute">
- 點擊以解除å°éŽ–這ä½å±…æ°‘
+ 點按以解除å°éŽ–這ä½å±…æ°‘
</string>
<string name="TooltipAgentIM">
- 點擊開始 IM 這ä½å±…æ°‘
+ 點按開始 IM 這ä½å±…æ°‘
</string>
<string name="TooltipAgentPay">
- 點擊以支付這ä½å±…æ°‘
+ 點按以支付這ä½å±…æ°‘
</string>
<string name="TooltipAgentOfferTeleport">
- 點擊以é€å‡ºçž¬é–“傳é€é‚€è«‹çµ¦é€™ä½å±…æ°‘
+ 點按以é€å‡ºçž¬é–“傳é€é‚€è«‹çµ¦é€™ä½å±…æ°‘
</string>
<string name="TooltipAgentRequestFriend">
- 點擊以é€å‡ºäº¤å‹é‚€è«‹çµ¦é€™ä½å±…æ°‘
+ 點按以é€å‡ºäº¤å‹é‚€è«‹çµ¦é€™ä½å±…æ°‘
</string>
<string name="TooltipGroupUrl">
- 點擊以察看這個群組的æè¿°
+ 點按以察看這個群組的æè¿°
</string>
<string name="TooltipEventUrl">
- 點擊以察看這個活動的æè¿°
+ 點按以察看這個活動的æè¿°
</string>
<string name="TooltipClassifiedUrl">
- Click to view this classified
+ 點按察看這個個人廣告
</string>
<string name="TooltipParcelUrl">
- 點擊以察看這個地段的æè¿°
+ 點按以察看這個地段的æè¿°
</string>
<string name="TooltipTeleportUrl">
- 點擊以傳é€åˆ°é€™å€‹ä½ç½®
+ 點按以傳é€åˆ°é€™å€‹ä½ç½®
</string>
<string name="TooltipObjectIMUrl">
- 點擊以察看這個物件的æè¿°
+ 點按以察看這個物件的æè¿°
</string>
<string name="TooltipMapUrl">
- 點擊以察看此處在地圖上的ä½ç½®
+ 點按以察看此處在地圖上的ä½ç½®
</string>
<string name="TooltipSLAPP">
- 點擊以執行 secondlife:// 指令
+ 點按以執行 secondlife:// 指令
</string>
<string name="CurrentURL" value="ç›®å‰ç¶²å€ï¼š[CurrentURL]"/>
<string name="SLurlLabelTeleport">
@@ -276,6 +446,9 @@
<string name="SLappAgentRequestFriend">
交å‹è¦æ±‚
</string>
+ <string name="SLappAgentRemoveFriend">
+ 移除朋å‹
+ </string>
<string name="BUTTON_CLOSE_DARWIN">
關閉(⌘W)
</string>
@@ -304,7 +477,7 @@
æœå°‹ä¸­...
</string>
<string name="NoneFound">
- 未發ç¾ã€‚
+ 查無çµæžœã€‚
</string>
<string name="RetrievingData">
檢索...
@@ -328,7 +501,7 @@
(無)
</string>
<string name="AvalineCaller">
- Avaline Caller [ORDER]
+ Avaline 通話者 [ORDER]
</string>
<string name="AssetErrorNone">
無錯誤
@@ -355,10 +528,10 @@
檔案傳輸逾時
</string>
<string name="AssetErrorCircuitGone">
- Circuit gone
+ 失去線路
</string>
<string name="AssetErrorPriceMismatch">
- Viewer and server do not agree on price
+ Viewer 和伺æœå™¨ç„¡æ³•åŒæ„價格
</string>
<string name="AssetErrorUnknownStatus">
未知狀態
@@ -391,13 +564,13 @@
資料夾
</string>
<string name="root">
- root
+ 根目錄
</string>
<string name="lsl2 script">
- LSL2 script
+ LSL2 腳本
</string>
<string name="lsl bytecode">
- LSL bytecode
+ LSL ä½å…ƒçµ„碼
</string>
<string name="tga texture">
tga æ質
@@ -409,7 +582,7 @@
å¿«ç…§
</string>
<string name="lost and found">
- Lost and Found
+ 失物招領
</string>
<string name="targa image">
targa 圖åƒ
@@ -438,14 +611,17 @@
<string name="symbolic folder link">
資料夾è¯çµ
</string>
+ <string name="mesh">
+ 網é¢
+ </string>
<string name="AvatarEditingAppearance">
(外觀編輯中)
</string>
<string name="AvatarAway">
離開
</string>
- <string name="AvatarBusy">
- 忙碌
+ <string name="AvatarDoNotDisturb">
+ 請勿打擾
</string>
<string name="AvatarMuted">
å°éŽ–çš„
@@ -457,88 +633,88 @@
生氣
</string>
<string name="anim_away">
- Away
+ 離開
</string>
<string name="anim_backflip">
- Backflip
+ 後空翻
</string>
<string name="anim_express_laugh">
- Belly Laugh
+ æ§è…¹å¤§ç¬‘
</string>
<string name="anim_express_toothsmile">
- BigSmile
+ 大微笑
</string>
<string name="anim_blowkiss">
- Blow Kiss
+ 飛å»
</string>
<string name="anim_express_bored">
ç„¡èŠ
</string>
<string name="anim_bow">
- Bow
+ 彎腰點頭
</string>
<string name="anim_clap">
æ‹æ‰‹
</string>
<string name="anim_courtbow">
- Court Bow
+ 宮廷鞠躬
</string>
<string name="anim_express_cry">
å“­æ³£
</string>
<string name="anim_dance1">
- Dance 1
+ 跳舞1
</string>
<string name="anim_dance2">
- Dance 2
+ 跳舞2
</string>
<string name="anim_dance3">
- Dance 3
+ 跳舞3
</string>
<string name="anim_dance4">
- Dance 4
+ 跳舞4
</string>
<string name="anim_dance5">
- Dance 5
+ 跳舞5
</string>
<string name="anim_dance6">
- Dance 6
+ 跳舞6
</string>
<string name="anim_dance7">
- Dance 7
+ 跳舞7
</string>
<string name="anim_dance8">
- Dance 8
+ 跳舞8
</string>
<string name="anim_express_disdain">
- Disdain
+ 鄙視
</string>
<string name="anim_drink">
- Drink
+ å–一å£
</string>
<string name="anim_express_embarrased">
- Embarrassed
+ å°·å°¬
</string>
<string name="anim_angry_fingerwag">
- Finger Wag
+ æ®å‹•é£ŸæŒ‡
</string>
<string name="anim_fist_pump">
- Fist Pump
+ 高舉å³æ‹³
</string>
<string name="anim_yoga_float">
- Floating Yoga
+ 漂浮瑜伽
</string>
<string name="anim_express_frown">
- Frown
+ 皺眉
</string>
<string name="anim_impatient">
- Impatient
+ ä¸è€ç…©
</string>
<string name="anim_jumpforjoy">
- Jump For Joy
+ 雀èº
</string>
<string name="anim_kissmybutt">
- Kiss My Butt
+ 親我å±è‚¡ï¼
</string>
<string name="anim_express_kiss">
親å»
@@ -547,55 +723,55 @@
笑
</string>
<string name="anim_musclebeach">
- Muscle Beach
+ 秀å¥ç¾Žè‚Œè‚‰
</string>
<string name="anim_no_unhappy">
ä¸ï¼ˆä¸å¿«æ¨‚)
</string>
<string name="anim_no_head">
- ä¸
+ å¦
</string>
<string name="anim_nyanya">
Nya-nya-nya
</string>
<string name="anim_punch_onetwo">
- One-Two Punch
+ 連續左å³å‡ºæ‹³
</string>
<string name="anim_express_open_mouth">
- Open Mouth
+ å¼µå£
</string>
<string name="anim_peace">
- Peace
+ 和平手勢
</string>
<string name="anim_point_you">
- Point at Other
+ 指著別人
</string>
<string name="anim_point_me">
- Point at Self
+ 指著自己
</string>
<string name="anim_punch_l">
- Punch Left
+ 左出拳
</string>
<string name="anim_punch_r">
- Punch Right
+ å³å‡ºæ‹³
</string>
<string name="anim_rps_countdown">
- RPS count
+ 剪刀石頭布é å‚™å‹•ä½œ
</string>
<string name="anim_rps_paper">
- RPS paper
+ 剪刀石頭布:布
</string>
<string name="anim_rps_rock">
- RPS rock
+ 剪刀石頭布:石頭
</string>
<string name="anim_rps_scissors">
- RPS scissors
+ 剪刀石頭布:剪刀
</string>
<string name="anim_express_repulsed">
- Repulsed
+ 作å™
</string>
<string name="anim_kick_roundhouse_r">
- Roundhouse Kick
+ 旋踢
</string>
<string name="anim_express_sad">
傷心
@@ -604,37 +780,37 @@
敬禮
</string>
<string name="anim_shout">
- Shout
+ å¶å–Š
</string>
<string name="anim_express_shrug">
- Shrug
+ è³è³è‚©
</string>
<string name="anim_express_smile">
微笑
</string>
<string name="anim_smoke_idle">
- Smoke Idle
+ 悠閒抽è¸
</string>
<string name="anim_smoke_inhale">
- Smoke Inhale
+ å¸ä¸€å£è¸
</string>
<string name="anim_smoke_throw_down">
- Smoke Throw Down
+ 甩è¸è’‚
</string>
<string name="anim_express_surprise">
驚喜
</string>
<string name="anim_sword_strike_r">
- Sword Strike
+ åŠæ“Š
</string>
<string name="anim_angry_tantrum">
- Tantrum
+ 鬧脾氣
</string>
<string name="anim_express_tongue_out">
- TongueOut
+ å舌頭
</string>
<string name="anim_hello">
- Wave
+ æ®æ‰‹
</string>
<string name="anim_whisper">
耳語
@@ -657,6 +833,12 @@
<string name="anim_yes_head">
是
</string>
+ <string name="multiple_textures">
+ 多個
+ </string>
+ <string name="use_texture">
+ 使用æ質
+ </string>
<string name="texture_loading">
載入中...
</string>
@@ -664,19 +846,25 @@
離線
</string>
<string name="worldmap_item_tooltip_format">
- [AREA] m² L$[PRICE]
+ [AREA] 平方公尺 L$[PRICE]
</string>
<string name="worldmap_results_none_found">
- 沒有發ç¾ã€‚
+ 查無çµæžœã€‚
</string>
<string name="Ok">
確定
</string>
<string name="Premature end of file">
- Premature end of file
+ 檔案異常中止
</string>
<string name="ST_NO_JOINT">
- Can&apos;t find ROOT or JOINT.
+ 找ä¸åˆ° ROOT 或旋軸。
+ </string>
+ <string name="NearbyChatTitle">
+ 附近的èŠå¤©ä¸­
+ </string>
+ <string name="NearbyChatLabel">
+ (附近的èŠå¤©ï¼‰
</string>
<string name="whisper">
低語:
@@ -700,34 +888,37 @@
ç¾åœ¨ä½ å°‡é‡æ–°è¯æŽ¥åˆ°é™„近的語音èŠå¤©
</string>
<string name="ScriptQuestionCautionChatGranted">
- &apos;[OBJECTNAME]&apos;, an object owned by &apos;[OWNERNAME]&apos;, located in [REGIONNAME] at [REGIONPOS], has been granted permission to: [PERMISSIONS].
+ 物件「[OBJECTNAME]&apos;ã€ï¼ˆæ‰€æœ‰äººã€Œ[OWNERNAME]ã€ï¼Œä½æ–¼ã€Œ[REGIONNAME]ã€ï¼Œæ–¹ä½ã€Œ[REGIONPOS]ã€ï¼‰å·²ç²å¾—下列權é™ï¼š[PERMISSIONS]。
</string>
<string name="ScriptQuestionCautionChatDenied">
- &apos;[OBJECTNAME]&apos;, an object owned by &apos;[OWNERNAME]&apos;, located in [REGIONNAME] at [REGIONPOS], has been denied permission to: [PERMISSIONS].
+ 物件「[OBJECTNAME]&apos;ã€ï¼ˆæ‰€æœ‰äººã€Œ[OWNERNAME]ã€ï¼Œä½æ–¼ã€Œ[REGIONNAME]ã€ï¼Œæ–¹ä½ã€Œ[REGIONPOS]ã€ï¼‰å·²è¢«æ’¤é™¤ä¸‹åˆ—權é™ï¼š[PERMISSIONS]。
+ </string>
+ <string name="AdditionalPermissionsRequestHeader">
+ 你如果打開帳戶權é™ï¼Œä¹Ÿå°‡ä¸€ä½µå…許該物件:
</string>
<string name="ScriptTakeMoney">
由你身上拿走林登幣(L$)
</string>
<string name="ActOnControlInputs">
- Act on your control inputs
+ 按你的控制輸入行動
</string>
<string name="RemapControlInputs">
- Remap your control inputs
+ é‡æ–°è¦åŠƒä½ çš„控制輸入
</string>
<string name="AnimateYourAvatar">
- Animate your avatar
+ 使化身動起來
</string>
<string name="AttachToYourAvatar">
- Attach to your avatar
+ 附加到化身
</string>
<string name="ReleaseOwnership">
- Release ownership and become public
+ 釋出所有權,開放給所有人
</string>
<string name="LinkAndDelink">
- Link and delink from other objects
+ 連çµå…¶ä»–物件或去除連çµ
</string>
<string name="AddAndRemoveJoints">
- Add and remove joints with other objects
+ 和其他物件建立或移除旋軸
</string>
<string name="ChangePermissions">
變更它的權é™
@@ -741,6 +932,27 @@
<string name="NotConnected">
未è¯æŽ¥
</string>
+ <string name="AgentNameSubst">
+ (你)
+ </string>
+ <string name="TeleportYourAgent">
+ 瞬間傳é€ä½ æœ¬äºº
+ </string>
+ <string name="JoinAnExperience">
+ 加入體驗
+ </string>
+ <string name="SilentlyManageEstateAccess">
+ 管ç†é ˜å‡ºå…¥è¨±å¯å單時,ä¸é¡¯ç¤ºè­¦ç¤º
+ </string>
+ <string name="OverrideYourAnimations">
+ 替æ›ä½ é è¨­çš„動作
+ </string>
+ <string name="ScriptReturnObjects">
+ 為你é€è¿”物件
+ </string>
+ <string name="UnknownScriptPermission">
+ (未知)ï¼
+ </string>
<string name="SIM_ACCESS_PG">
一般普級
</string>
@@ -799,7 +1011,7 @@
AVI 視頻檔案
</string>
<string name="xaf_animation_file">
- XAF Anim File
+ XAF 動畫檔案
</string>
<string name="xml_file">
XML 檔案
@@ -816,17 +1028,11 @@
<string name="choose_the_directory">
é¸æ“‡ç›®éŒ„
</string>
- <string name="AvatarSetNotAway">
- éžé›¢é–‹
- </string>
- <string name="AvatarSetAway">
- 離開
- </string>
- <string name="AvatarSetNotBusy">
- éžå¿™ç¢Œ
+ <string name="script_files">
+ 腳本
</string>
- <string name="AvatarSetBusy">
- 忙碌
+ <string name="dictionary_files">
+ å­—å…¸
</string>
<string name="shape">
體形
@@ -991,19 +1197,19 @@
é€å‡ºç”±
</string>
<string name="GroupNotifyAttached">
- Attached:
+ 附件:
</string>
<string name="GroupNotifyViewPastNotices">
- View past notices or opt-out of receiving these messages here.
+ 在這裡察看舊通知或é¸æ“‡ä¸æŽ¥æ”¶è¨Šæ¯ã€‚
</string>
<string name="GroupNotifyOpenAttachment">
- Open Attachment
+ 開啟附件
</string>
<string name="GroupNotifySaveAttachment">
- Save Attachment
+ 儲存附件
</string>
<string name="TeleportOffer">
- Teleport offering
+ 發出「瞬間傳é€ã€é‚€è«‹
</string>
<string name="StartUpNotifications">
當你離開時有新的通知é€é”。
@@ -1042,16 +1248,75 @@
按下 ESC éµå›žå¾©åˆ°ä¸–界的視角
</string>
<string name="InventoryNoMatchingItems">
- 沒有發ç¾ä½ æƒ³è¦æ‰¾çš„嗎?試試 [secondlife:///app/search/all/[SEARCH_TERM] æœå°‹]。
+ 找ä¸åˆ°ä½ è¦æ‰¾çš„嗎? 請試試 [secondlife:///app/search/places/ æœå°‹]。
</string>
<string name="PlacesNoMatchingItems">
- 沒有發ç¾ä½ æƒ³è¦æ‰¾çš„嗎?試試 [secondlife:///app/search/places/[SEARCH_TERM] æœå°‹]。
+ 找ä¸åˆ°ä½ è¦æ‰¾çš„嗎? 請試試 [secondlife:///app/search/places/[SEARCH_TERM] æœå°‹]。
</string>
<string name="FavoritesNoMatchingItems">
- Drag a landmark here to add it to your favorites.
+ 將一個地標拖曳到這裡,加進「我的最愛ã€ã€‚
</string>
<string name="InventoryNoTexture">
- You do not have a copy of this texture in your inventory
+ 你的收ç´å€è£¡æ²’有這個æ質的副本
+ </string>
+ <string name="InventoryInboxNoItems">
+ 你從第二人生購物市集購買的物å“將出ç¾åœ¨é€™è£¡ã€‚ ä½ å¯ä»¥æŠŠå®ƒå€‘拖曳到你的收ç´å€ï¼Œé–‹å§‹ä½¿ç”¨ã€‚
+ </string>
+ <string name="MarketplaceURL">
+ https://marketplace.[MARKETPLACE_DOMAIN_NAME]/
+ </string>
+ <string name="MarketplaceURL_CreateStore">
+ http://community.secondlife.com/t5/English-Knowledge-Base/Selling-in-the-Marketplace/ta-p/700193#Section_.4
+ </string>
+ <string name="MarketplaceURL_Dashboard">
+ https://marketplace.[MARKETPLACE_DOMAIN_NAME]/merchants/store/dashboard
+ </string>
+ <string name="MarketplaceURL_Imports">
+ https://marketplace.[MARKETPLACE_DOMAIN_NAME]/merchants/store/imports
+ </string>
+ <string name="MarketplaceURL_LearnMore">
+ https://marketplace.[MARKETPLACE_DOMAIN_NAME]/learn_more
+ </string>
+ <string name="InventoryOutboxNotMerchantTitle">
+ 任何人都å¯åœ¨ç¬¬äºŒäººç”Ÿè³¼ç‰©å¸‚集出售物å“。
+ </string>
+ <string name="InventoryOutboxNotMerchantTooltip"/>
+ <string name="InventoryOutboxNotMerchant">
+ 如果你想æˆç‚ºå•†å®¶ï¼Œä½ éœ€è¦åœ¨ç¬¬äºŒäººç”Ÿè³¼ç‰©å¸‚集[[MARKETPLACE_CREATE_STORE_URL]開設一間商店]。
+ </string>
+ <string name="InventoryOutboxNoItemsTitle">
+ 你的發件匣目å‰æ˜¯ç©ºçš„。
+ </string>
+ <string name="InventoryOutboxNoItemsTooltip"/>
+ <string name="InventoryOutboxNoItems">
+ 將資料夾拖曳到這個å€åŸŸï¼Œå†é»žæŒ‰ã€Œé€å¾€ç¬¬äºŒäººç”Ÿè³¼ç‰©å¸‚集ã€ï¼Œå³å¯åœ¨[[MARKETPLACE_DASHBOARD_URL]第二人生購物市集]登列出售。
+ </string>
+ <string name="Marketplace Error None">
+ 零錯誤
+ </string>
+ <string name="Marketplace Error Not Merchant">
+ 發生錯誤:將物項é€å¾€ç¬¬äºŒäººç”Ÿè³¼ç‰©å¸‚集之å‰ï¼Œä½ å¿…é ˆå–得商家的身份(å…費)。
+ </string>
+ <string name="Marketplace Error Empty Folder">
+ 錯誤:此資料夾沒有內容。
+ </string>
+ <string name="Marketplace Error Unassociated Products">
+ 錯誤:此物項上傳失敗,因為你的商家帳戶有太多和產å“ç„¡é—œè¯çš„物項。 è¦è§£æ±ºé€™å€‹å•é¡Œï¼Œè«‹ç™»å…¥ç¬¬äºŒäººç”Ÿè³¼ç‰©å¸‚集網站,減低你的無關è¯ç‰©é …數目。
+ </string>
+ <string name="Marketplace Error Object Limit">
+ 錯誤:此物項包å«å¤ªå¤šç‰©ä»¶ã€‚ è¦è§£æ±ºé€™éŒ¯èª¤ï¼Œè«‹å°‡ç‰©ä»¶è£ç®±ï¼Œä½¿ç¸½ç‰©ä»¶æ•¸ç›®ä¸è¶…éŽ 200。
+ </string>
+ <string name="Marketplace Error Folder Depth">
+ 錯誤:此物項å«æœ‰å¤ªå¤šå±¤çš„巢狀資料夾。 請加以é‡æ–°æ•´ç†ï¼Œè‡³å¤šå…許 3 層的巢狀資料夾。
+ </string>
+ <string name="Marketplace Error Unsellable Item">
+ 錯誤:此物項無法在第二人生購物市集出售。
+ </string>
+ <string name="Marketplace Error Internal Import">
+ 錯誤:這個物項有å•é¡Œã€‚ è«‹ç¨å€™å†è©¦ä¸€æ¬¡ã€‚
+ </string>
+ <string name="Open landmarks">
+ 開啟地標
</string>
<string name="no_transfer" value="(ç¦æ­¢è½‰è®“)"/>
<string name="no_modify" value="(ç¦æ­¢ä¿®æ”¹ï¼‰"/>
@@ -1066,7 +1331,7 @@
無內容
</string>
<string name="WornOnAttachmentPoint" value="(已穿 [ATTACHMENT_POINT])"/>
- <string name="ActiveGesture" value="[GESLABEL] (active)"/>
+ <string name="ActiveGesture" value="[GESLABEL](使用中)"/>
<string name="PermYes">
是
</string>
@@ -1078,30 +1343,27 @@
<string name="Wait" value="--- 等待:"/>
<string name="AnimFlagStop" value="åœæ­¢å‹•ä½œï¼š"/>
<string name="AnimFlagStart" value="開始動作:"/>
- <string name="Wave" value="Wave"/>
+ <string name="Wave" value="æ®æ‰‹"/>
<string name="GestureActionNone" value="ç„¡"/>
- <string name="HelloAvatar" value="Hello, avatar!"/>
+ <string name="HelloAvatar" value="你好,化身ï¼"/>
<string name="ViewAllGestures" value="察看全部 &gt;&gt;"/>
<string name="GetMoreGestures" value="å–得更多 &gt;&gt;"/>
- <string name="Animations" value="動作,"/>
- <string name="Calling Cards" value="å片,"/>
- <string name="Clothing" value="æœè£,"/>
- <string name="Gestures" value="姿勢,"/>
- <string name="Landmarks" value="地標,"/>
- <string name="Notecards" value="記事å¡,"/>
- <string name="Objects" value="物件,"/>
- <string name="Scripts" value="腳本,"/>
- <string name="Sounds" value="è²éŸ³,"/>
- <string name="Textures" value="æ質,"/>
- <string name="Snapshots" value="å¿«ç…§,"/>
- <string name="No Filters" value="No"/>
+ <string name="Animations" value="動作,"/>
+ <string name="Calling Cards" value="å片,"/>
+ <string name="Clothing" value="æœè£ï¼Œ"/>
+ <string name="Gestures" value="姿勢,"/>
+ <string name="Landmarks" value="地標,"/>
+ <string name="Notecards" value="記事å¡ï¼Œ"/>
+ <string name="Objects" value="物件,"/>
+ <string name="Scripts" value="腳本,"/>
+ <string name="Sounds" value="è²éŸ³ï¼Œ"/>
+ <string name="Textures" value="æ質,"/>
+ <string name="Snapshots" value="快照,"/>
+ <string name="No Filters" value="å¦"/>
<string name="Since Logoff" value="- 自上次登出"/>
<string name="InvFolder My Inventory">
我的收ç´å€
</string>
- <string name="InvFolder My Favorites">
- 我的最愛
- </string>
<string name="InvFolder Library">
資æºåº«
</string>
@@ -1136,7 +1398,7 @@
收ç´å€
</string>
<string name="InvFolder Uncompressed Images">
- Uncompressed Images
+ 未壓縮圖åƒ
</string>
<string name="InvFolder Body Parts">
身體部ä½
@@ -1148,10 +1410,10 @@
相簿
</string>
<string name="InvFolder Lost And Found">
- Lost And Found
+ 失物招領
</string>
<string name="InvFolder Uncompressed Sounds">
- 無壓縮è²éŸ³
+ 未壓縮è²éŸ³
</string>
<string name="InvFolder Animations">
動作
@@ -1165,6 +1427,12 @@
<string name="InvFolder favorite">
我的最愛
</string>
+ <string name="InvFolder Favorites">
+ 我的最愛
+ </string>
+ <string name="InvFolder favorites">
+ 我的最愛
+ </string>
<string name="InvFolder Current Outfit">
ç›®å‰è£æ‰®
</string>
@@ -1177,17 +1445,32 @@
<string name="InvFolder Accessories">
é…件
</string>
+ <string name="InvFolder Meshes">
+ 網é¢
+ </string>
+ <string name="InvFolder Received Items">
+ 收到的物項
+ </string>
+ <string name="InvFolder Merchant Outbox">
+ 商家發件匣
+ </string>
<string name="InvFolder Friends">
朋å‹
</string>
<string name="InvFolder All">
全部
</string>
+ <string name="no_attachments">
+ 未穿著任何附件
+ </string>
+ <string name="Attachments remain">
+ 附件(尚å¯å®¹ç´ [COUNT] 件)
+ </string>
<string name="Buy">
購買
</string>
<string name="BuyforL$">
- Buy for L$
+ 出價購買:L$
</string>
<string name="Stone">
石頭
@@ -1211,13 +1494,13 @@
橡膠
</string>
<string name="Light">
- Light
+ å…‰æº
</string>
<string name="KBShift">
- Shift
+ Shift éµ
</string>
<string name="KBCtrl">
- Ctrl
+ Ctrl éµ
</string>
<string name="Chest">
胸部
@@ -1250,7 +1533,7 @@
骨盆
</string>
<string name="Mouth">
- 嘴
+ 嘴巴
</string>
<string name="Chin">
下巴
@@ -1309,23 +1592,29 @@
<string name="Right Pec">
å³èƒ¸è‚Œ
</string>
+ <string name="Neck">
+ 頸部
+ </string>
+ <string name="Avatar Center">
+ 化身中心
+ </string>
<string name="Invalid Attachment">
- 無效的附件è¯æŽ¥é»ž
+ 無效的附接點
</string>
<string name="YearsMonthsOld">
- [AGEYEARS] [AGEMONTHS] old
+ 年齡:[AGEYEARS] 年 [AGEMONTHS] 月
</string>
<string name="YearsOld">
- [AGEYEARS] old
+ 年齡:[AGEYEARS] 年
</string>
<string name="MonthsOld">
- [AGEMONTHS] old
+ [AGEMONTHS] 月
</string>
<string name="WeeksOld">
- [AGEWEEKS] old
+ [AGEWEEKS] 週
</string>
<string name="DaysOld">
- [AGEDAYS] old
+ [AGEDAYS] 天
</string>
<string name="TodayOld">
今日剛加入
@@ -1367,40 +1656,40 @@
[COUNT] 天
</string>
<string name="GroupMembersA">
- [COUNT] æˆå“¡
+ [COUNT] ä½æˆå“¡
</string>
<string name="GroupMembersB">
- [COUNT] æˆå“¡
+ [COUNT] ä½æˆå“¡
</string>
<string name="GroupMembersC">
- [COUNT] æˆå“¡
+ [COUNT] ä½æˆå“¡
</string>
<string name="AcctTypeResident">
å±…æ°‘
</string>
<string name="AcctTypeTrial">
- Trial
+ 試用
</string>
<string name="AcctTypeCharterMember">
- Charter Member
+ è€ç‰Œ Charter æˆå“¡
</string>
<string name="AcctTypeEmployee">
林登實驗室員工
</string>
<string name="PaymentInfoUsed">
- Payment Info Used
+ 使用的付款資料
</string>
<string name="PaymentInfoOnFile">
- Payment Info On File
+ é ç•™ä»˜æ¬¾è³‡æ–™
</string>
<string name="NoPaymentInfoOnFile">
- No Payment Info On File
+ 未é ç•™ä»˜æ¬¾è³‡æ–™
</string>
<string name="AgeVerified">
- 已年齡驗證
+ 通éŽå¹´é½¡é©—è­‰
</string>
<string name="NotAgeVerified">
- 未年齡驗證
+ 未通éŽå¹´é½¡é©—è­‰
</string>
<string name="Center 2">
中央 2
@@ -1427,22 +1716,22 @@
å³ä¸‹
</string>
<string name="CompileQueueDownloadedCompiling">
- 已下載,ç¾åœ¨é€²è¡Œç·¨è­¯ä¸­
+ 已下載,正在編譯中
</string>
<string name="CompileQueueScriptNotFound">
伺æœå™¨ä¸Šæœªç™¼ç¾è…³æœ¬ã€‚
</string>
<string name="CompileQueueProblemDownloading">
- å•é¡Œä¸‹è¼‰ä¸­
+ 下載時出å•é¡Œ
</string>
<string name="CompileQueueInsufficientPermDownload">
- Insufficient permissions to download a script.
+ 下載腳本的權é™ä¸è¶³ã€‚
</string>
<string name="CompileQueueInsufficientPermFor">
- Insufficient permissions for
+ 權é™ä¸è¶³ï¼š
</string>
<string name="CompileQueueUnknownFailure">
- Unknown failure to download
+ 下載失敗,原因ä¸æ˜Ž
</string>
<string name="CompileQueueTitle">
é‡æ–°ç·¨è­¯é€²åº¦
@@ -1457,19 +1746,19 @@
é‡è¨­
</string>
<string name="RunQueueTitle">
- 設定執行中程åº
+ 設定「執行中ã€é€²åº¦
</string>
<string name="RunQueueStart">
- 設為執行中
+ 設為「執行中ã€
</string>
<string name="NotRunQueueTitle">
- 設定éžåŸ·è¡Œä¸­ç¨‹åº
+ 設定「éžåŸ·è¡Œä¸­ã€é€²åº¦
</string>
<string name="NotRunQueueStart">
- 設為éžåŸ·è¡Œä¸­
+ 設為「éžåŸ·è¡Œä¸­ã€
</string>
<string name="CompileSuccessful">
- 編譯æˆåŠŸ!!
+ 編譯æˆåŠŸï¼
</string>
<string name="CompileSuccessfulSaving">
編譯æˆåŠŸï¼Œå„²å­˜ä¸­...
@@ -1490,36 +1779,42 @@
<string name="Unknown">
(未知)
</string>
- <string name="SummaryForTheWeek" value="Summary for this week, beginning on"/>
+ <string name="SummaryForTheWeek" value="本週摘è¦ï¼Œèµ·å§‹æ—¥ï¼š"/>
<string name="NextStipendDay" value="下一個發薪日為"/>
- <string name="GroupIndividualShare" value="Group Individual Share"/>
+ <string name="GroupPlanningDate">
+ [mthnum,datetime,utc]/[day,datetime,utc]/[year,datetime,utc]
+ </string>
+ <string name="GroupIndividualShare" value="群組 個人份é¡"/>
<string name="GroupColumn" value="群組"/>
<string name="Balance">
- Balance
+ 餘é¡
</string>
<string name="Credits">
- Credits
+ 貸記
</string>
<string name="Debits">
- Debits
+ 借記
</string>
<string name="Total">
- Total
+ 總é¡
</string>
<string name="NoGroupDataFound">
- 無群組資料發ç¾
+ 查無群組資料
</string>
<string name="IMParentEstate">
- parent estate
+ æ¯é ˜åœ°
</string>
<string name="IMMainland">
- mainland
+ 大陸
</string>
<string name="IMTeen">
- teen
+ é’å°‘å¹´
+ </string>
+ <string name="Anyone">
+ 任何人
</string>
<string name="RegionInfoError">
- error
+ 錯誤
</string>
<string name="RegionInfoAllEstatesOwnedBy">
[OWNER] 所æ“有的的全部領地
@@ -1528,13 +1823,13 @@
你所æ“有的全部領地
</string>
<string name="RegionInfoAllEstatesYouManage">
- all estates that you manage for [OWNER]
+ 你為 [OWNER] 管ç†çš„全部領地
</string>
<string name="RegionInfoAllowedResidents">
- Allowed Residents: ([ALLOWEDAGENTS], max [MAXACCESS])
+ å…許居民:([ALLOWEDAGENTS],最多 [MAXACCESS])
</string>
<string name="RegionInfoAllowedGroups">
- å…許的群群組:([ALLOWEDGROUPS],最大 [MAXACCESS])
+ å…許的群組:([ALLOWEDGROUPS],最多 [MAXACCESS])
</string>
<string name="ScriptLimitsParcelScriptMemory">
地段腳本記憶體
@@ -1549,28 +1844,28 @@
記憶體用é‡ï¼š[COUNT] kb
</string>
<string name="ScriptLimitsParcelScriptURLs">
- 地段腳本 URLs
+ 地段腳本的 URL
</string>
<string name="ScriptLimitsURLsUsed">
- URLs used: [COUNT] out of [MAX]; [AVAILABLE] available
+ URL 使用狀æ³ï¼šæœ€å¤šå¯ç”¨ [MAX],已用 [COUNT],剩餘 [AVAILABLE]
</string>
<string name="ScriptLimitsURLsUsedSimple">
- URLs used: [COUNT]
+ 已用 URL:[COUNT]
</string>
<string name="ScriptLimitsRequestError">
- Error requesting information
+ 調資料時出錯
</string>
<string name="ScriptLimitsRequestNoParcelSelected">
- 無地段被é¸æ“‡
+ 未é¸æ“‡åœ°æ®µ
</string>
<string name="ScriptLimitsRequestWrongRegion">
- Error: script information is only available in your current region
+ 錯誤:åªèƒ½åœ¨ä½ ç›®å‰æ‰€è™•å€åŸŸå–得腳本資訊
</string>
<string name="ScriptLimitsRequestWaiting">
- Retrieving information...
+ 正在調閱資料...
</string>
<string name="ScriptLimitsRequestDontOwnParcel">
- You do not have permission to examine this parcel
+ 你無權審視此地段
</string>
<string name="SITTING_ON">
å在
@@ -1666,34 +1961,40 @@
左胸肌
</string>
<string name="ATTACH_HUD_CENTER_2">
- HUD Center 2
+ 擡頭顯示中央 2
</string>
<string name="ATTACH_HUD_TOP_RIGHT">
- HUD Top Right
+ 擡頭顯示å³ä¸Š
</string>
<string name="ATTACH_HUD_TOP_CENTER">
- HUD Top Center
+ 擡頭顯示中央上方
</string>
<string name="ATTACH_HUD_TOP_LEFT">
- HUD Top Left
+ 擡頭顯示左上
</string>
<string name="ATTACH_HUD_CENTER_1">
- HUD Center 1
+ 擡頭顯示中央 1
</string>
<string name="ATTACH_HUD_BOTTOM_LEFT">
- HUD Bottom Left
+ 擡頭顯示左下
</string>
<string name="ATTACH_HUD_BOTTOM">
- HUD Bottom
+ 擡頭顯示下方
</string>
<string name="ATTACH_HUD_BOTTOM_RIGHT">
- HUD Bottom Right
+ 擡頭顯示å³ä¸‹
+ </string>
+ <string name="ATTACH_NECK">
+ 頸部
+ </string>
+ <string name="ATTACH_AVATAR_CENTER">
+ 化身中心
</string>
<string name="CursorPos">
- Line [LINE], Column [COLUMN]
+ 橫行 [LINE],縱列 [COLUMN]
</string>
<string name="PanelDirCountFound">
- [COUNT] found
+ 找到 [COUNT]
</string>
<string name="PanelDirTimeStr">
[hour12,datetime,slt]:[min,datetime,slt] [ampm,datetime,slt]
@@ -1702,16 +2003,16 @@
[mthnum,datetime,slt]/[day,datetime,slt]
</string>
<string name="PanelContentsTooltip">
- 物件的內容
+ 物件內容
</string>
<string name="PanelContentsNewScript">
新腳本
</string>
- <string name="BusyModeResponseDefault">
- 你傳é€è¨Šæ¯çš„å±…æ°‘ç›®å‰è™•æ–¼å¿™ç¢Œæ¨¡å¼ä¸­ï¼Œé€™æ„味著他è¦æ±‚ä¸è¢«æ‰“擾。你所傳的訊æ¯ä»å°‡æœƒç•™å­˜ä¸¦é¡¯ç¤ºæ–¼ IM é¢æ¿ä¸Šä¾›ä»–ç¨å¾Œæ™‚查閱。
+ <string name="DoNotDisturbModeResponseDefault">
+ 這居民處於「請勿打擾ã€ç‹€æ…‹ï¼Œä¸æœƒç«‹å³çœ‹åˆ°ä½ çš„訊æ¯ã€‚
</string>
<string name="MuteByName">
- (由å稱)
+ (按å稱)
</string>
<string name="MuteAgent">
(居民)
@@ -1726,12 +2027,12 @@
(外部)
</string>
<string name="RegionNoCovenant">
- 此領地未æ供任何契約è¦æ±‚。
+ 此領地沒有任何契約è¦æ±‚。
</string>
<string name="RegionNoCovenantOtherOwner">
- There is no Covenant provided for this Estate. The land on this estate is being sold by the Estate owner, not Linden Lab. Please contact the Estate Owner for sales details.
+ 此領地沒有任何契約è¦æ±‚。 本領地土地的出售人是領地所有人,ä¸æ˜¯æž—登實驗室。 è«‹è¯çµ¡é ˜åœ°æ‰€æœ‰äººç²çŸ¥å”®åœ°è©³æƒ…。
</string>
- <string name="covenant_last_modified" value="最後修改於:"/>
+ <string name="covenant_last_modified" value="最後修改時間:"/>
<string name="none_text" value="(無)"/>
<string name="never_text" value="(絕ä¸ï¼‰"/>
<string name="GroupOwned">
@@ -1740,14 +2041,20 @@
<string name="Public">
公開
</string>
+ <string name="LocalSettings">
+ 本地設定
+ </string>
+ <string name="RegionSettings">
+ 地å€è¨­å®š
+ </string>
<string name="ClassifiedClicksTxt">
- Clicks: [TELEPORT] teleport, [MAP] map, [PROFILE] profile
+ 點按:[TELEPORT] 瞬間傳é€ï¼Œ[MAP] 地圖,[PROFILE] 檔案
</string>
<string name="ClassifiedUpdateAfterPublish">
- (將於發布後自動更新)
+ (將於發布後更新)
</string>
<string name="NoPicksClassifiedsText">
- You haven&apos;t created any Picks or Classifieds. Click the Plus button below to create a Pick or Classified.
+ 你尚未建立任何精é¸åœ°é»žæˆ–個人廣告。 點按下é¢çš„ + 按鈕建立精é¸åœ°é»žæˆ–個人廣告。
</string>
<string name="NoAvatarPicksClassifiedsText">
使用者無精é¸åœ°é»žæˆ–個人廣告
@@ -1762,86 +2069,86 @@
屬性
</string>
<string name="InvOfferAnObjectNamed">
- An object named
+ 一個物件,å為
</string>
<string name="InvOfferOwnedByGroup">
- 群組所æ“有
+ 屬於群組
</string>
<string name="InvOfferOwnedByUnknownGroup">
- 由一個未知的群組所æ“有
+ 屬於一個未知群組
</string>
<string name="InvOfferOwnedBy">
- owned by
+ 所有人:
</string>
<string name="InvOfferOwnedByUnknownUser">
- owned by an unknown user
+ 屬於æŸæœªçŸ¥ä½¿ç”¨è€…
</string>
<string name="InvOfferGaveYou">
- gave you
+ 給予你
</string>
<string name="InvOfferDecline">
- You decline [DESC] from &lt;nolink&gt;[NAME]&lt;/nolink&gt;.
+ 你拒絕了來自 &lt;nolink&gt;[NAME]&lt;/nolink&gt; 的 [DESC]。
</string>
<string name="GroupMoneyTotal">
- Total
+ 總é¡
</string>
<string name="GroupMoneyBought">
- bought
+ 買了
</string>
<string name="GroupMoneyPaidYou">
- paid you
+ 支付給你
</string>
<string name="GroupMoneyPaidInto">
- paid into
+ 支付給
</string>
<string name="GroupMoneyBoughtPassTo">
- bought pass to
+ 買了通行權:
</string>
<string name="GroupMoneyPaidFeeForEvent">
- paid fee for event
+ 付了費用åƒåŠ æ´»å‹•
</string>
<string name="GroupMoneyPaidPrizeForEvent">
- paid prize for event
+ 付了賞金åƒåŠ æ´»å‹•
</string>
<string name="GroupMoneyBalance">
- Balance
+ 餘é¡
</string>
<string name="GroupMoneyCredits">
- Credits
+ 貸記
</string>
<string name="GroupMoneyDebits">
- Debits
+ 借記
</string>
- <string name="ViewerObjectContents">
- Contents
+ <string name="GroupMoneyDate">
+ [weekday,datetime,utc] [mth,datetime,utc] [day,datetime,utc], [year,datetime,utc]
</string>
<string name="AcquiredItems">
- Acquired Items
+ å–得物å“
</string>
<string name="Cancel">
å–消
</string>
<string name="UploadingCosts">
- 花費 L$ [AMOUNT] 上傳 [NAME]
+ 上傳 [NAME] 費用 L$ [AMOUNT]
</string>
<string name="BuyingCosts">
- 花費 L$ [AMOUNT] 購買這個
+ è³¼è²·é€™å€‹éœ€è¦ L$ [AMOUNT]
</string>
<string name="UnknownFileExtension">
未知的副檔å .%s
-é æœŸç‚º .wav, .tga, .bmp, .jpg, .jpeg, or .bvh 類型
+應該是 .wavã€.tgaã€.bmpã€.jpgã€.jpeg 或 .bvh
</string>
<string name="MuteObject2">
- Block
+ å°éŽ–
</string>
<string name="MuteAvatar">
- Block
+ å°éŽ–
</string>
<string name="UnmuteObject">
- Unblock
+ 解除å°éŽ–
</string>
<string name="UnmuteAvatar">
- Unblock
+ 解除å°éŽ–
</string>
<string name="AddLandmarkNavBarMenu">
添加到我的地標...
@@ -1877,25 +2184,25 @@
接收中
</string>
<string name="AM">
- AM
+ 上åˆ
</string>
<string name="PM">
- PM
+ 下åˆ
</string>
<string name="PST">
- PST
+ 太平洋時間
</string>
<string name="PDT">
- PDT
+ 太平洋日光節約時間
</string>
<string name="Direction_Forward">
å‘å‰
</string>
<string name="Direction_Left">
- å‘å·¦
+ 左移éµ
</string>
<string name="Direction_Right">
- å‘å³
+ å³ç§»éµ
</string>
<string name="Direction_Back">
å‘後
@@ -1913,46 +2220,46 @@
æ±
</string>
<string name="Direction_Up">
- å‘上
+ 上移éµ
</string>
<string name="Direction_Down">
- å‘下
+ 下移éµ
</string>
<string name="Any Category">
任何類別
</string>
<string name="Shopping">
- 採購
+ 購物
</string>
<string name="Land Rental">
- Land Rental
+ 土地租賃
</string>
<string name="Property Rental">
- Property Rental
+ 房產租賃
</string>
<string name="Special Attraction">
- Special Attraction
+ 熱門地點
</string>
<string name="New Products">
- New Products
+ 新產å“
</string>
<string name="Employment">
- Employment
+ 徵人
</string>
<string name="Wanted">
- Wanted
+ 徵求
</string>
<string name="Service">
- Service
+ æœå‹™
</string>
<string name="Personal">
- Personal
+ 交å‹
</string>
<string name="None">
ç„¡
</string>
<string name="Linden Location">
- Linden Location
+ æž—ç™»ä½ç½®
</string>
<string name="Adult">
完全æˆäºº
@@ -1973,25 +2280,25 @@
èšæœƒæ‰€
</string>
<string name="Newcomer Friendly">
- 新手å‹å–„
+ 歡迎新手光臨
</string>
<string name="Parks&amp;Nature">
- 公園與自然
+ 公園與自然景觀
</string>
<string name="Residential">
ä½å®…
</string>
<string name="Stage">
- Stage
+ 舞臺
</string>
<string name="Other">
- Other
+ 其他
</string>
<string name="Rental">
- Rental
+ 出租
</string>
<string name="Any">
- Any
+ 任何
</string>
<string name="You">
ä½ 
@@ -2027,7 +2334,7 @@
多媒體
</string>
<string name="Play Media">
- 播放ï¼æš«åœ 媒體
+ 播放/æš«åœåª’é«”
</string>
<string name="MBCmdLineError">
解æžå‘½ä»¤åˆ—時發ç¾éŒ¯èª¤ã€‚
@@ -2038,1510 +2345,1513 @@
[APP_NAME] 命令列用法:
</string>
<string name="MBUnableToAccessFile">
- [APP_NAME] 無法存å–它所需è¦çš„檔案。
+ [APP_NAME] 無法存å–它所需的檔案。
-This can be because you somehow have multiple copies running, or your system incorrectly thinks a file is open.
-If this message persists, restart your computer and try again.
-If it continues to persist, you may need to completely uninstall [APP_NAME] and reinstall it.
+ä½ å¯èƒ½æœ‰å¤šé‡å¯¦ä¾‹åŸ·è¡Œä¸­ï¼Œæˆ–你的系統誤以為æŸæª”案已經開啟。
+如果這個訊æ¯æŒçºŒå‡ºç¾ï¼Œè«‹é‡æ–°å•Ÿå‹•ä½ çš„電腦。
+如果å•é¡Œä»ç„¶å­˜åœ¨ï¼Œä½ å¯èƒ½éœ€è¦å¾¹åº•å¸é™¤ [APP_NAME] å†é‡æ–°å®‰è£ã€‚
</string>
<string name="MBFatalError">
致命錯誤
</string>
<string name="MBRequiresAltiVec">
- [APP_NAME] requires a processor with AltiVec (G4 or later).
+ [APP_NAME] 需è¦æœ‰ AltiVec(G4 或更新版)的處ç†å™¨ã€‚
</string>
<string name="MBAlreadyRunning">
[APP_NAME] 已經在執行中。
-請檢查你的工作列裡是å¦æœ‰å…¶ä»–最å°åŒ–的相åŒç¨‹å¼ã€‚
+請檢查你的工作列裡是å¦å·²æœ‰æœ€å°åŒ–的相åŒç¨‹å¼ã€‚
如果這個訊æ¯æŒçºŒå‡ºç¾ï¼Œè«‹é‡æ–°å•Ÿå‹•ä½ çš„電腦。
</string>
<string name="MBFrozenCrashed">
- [APP_NAME] appears to have frozen or crashed on the previous run.
-Would you like to send a crash report?
+ [APP_NAME] 上次執行時好åƒå‡ºç¾å‡çµæˆ–當掉。
+你是å¦æƒ³è¦å ±å‘Šç•¶æ©Ÿäº‹ä¾‹ï¼Ÿ
</string>
<string name="MBAlert">
通知
</string>
<string name="MBNoDirectX">
- [APP_NAME] is unable to detect DirectX 9.0b or greater.
-[APP_NAME] uses DirectX to detect hardware and/or outdated drivers that can cause stability problems, poor performance and crashes. While you can run [APP_NAME] without it, we highly recommend running with DirectX 9.0b.
+ [APP_NAME] åµæ¸¬ä¸åˆ° DirectX 9.0b 或更新版。
+[APP_NAME] 使用 DirectX 來åµæ¸¬å¯èƒ½å°Žè‡´ä¸ç©©å®šã€åŸ·è¡Œæ•ˆèƒ½ä¸ä½³æˆ–當機發生的硬體或è€èˆŠé©…動器。 ä½ å¯ä»¥é¸æ“‡ä¸ç”¨ DirectX 9.0b 來執行 [APP_NAME],但我們大力推薦你使用。
-Do you wish to continue?
+你確定è¦ç¹¼çºŒå—Žï¼Ÿ
</string>
<string name="MBWarning">
警告
</string>
<string name="MBNoAutoUpdate">
- Automatic updating is not yet implemented for Linux.
-Please download the latest version from www.secondlife.com.
+ 尚無試用於 Linux 的自動更新功能。
+請到 www.secondlife.com 下載最新版本。
</string>
<string name="MBRegClassFailed">
- RegisterClass failed
+ RegisterClass 失敗
</string>
<string name="MBError">
錯誤
</string>
<string name="MBFullScreenErr">
- 無法執行全螢幕於 [WIDTH] x [HEIGHT].
-執行於視窗中。
+ [WIDTH] x [HEIGHT] 解æžåº¦ä¸‹ç„¡æ³•åŸ·è¡Œå…¨èž¢å¹•ã€‚
+在視窗中執行。
</string>
<string name="MBDestroyWinFailed">
- Shutdown Error while destroying window (DestroyWindow() failed)
+ 消滅視窗時發生強行關閉錯誤(DestroyWindow()失敗)
</string>
<string name="MBShutdownErr">
- Shutdown Error
+ 強行關閉出錯
</string>
<string name="MBDevContextErr">
- Can&apos;t make GL device context
+ 無法建立 GL è£ç½®ç’°å¢ƒ
</string>
<string name="MBPixelFmtErr">
- Can&apos;t find suitable pixel format
+ 找ä¸åˆ°é©åˆçš„åƒç´ æ ¼å¼
</string>
<string name="MBPixelFmtDescErr">
- Can&apos;t get pixel format description
+ 無法å–å¾—åƒç´ æ ¼å¼æè¿°
</string>
<string name="MBTrueColorWindow">
- [APP_NAME] requires True Color (32-bit) to run.
-Please go to your computer&apos;s display settings and set the color mode to 32-bit.
+ [APP_NAME] 需è¦å…¨å½©ï¼ˆ32ä½å…ƒï¼‰æ‰èƒ½åŸ·è¡Œã€‚
+請到電腦的顯示設定,將色彩模å¼è¨­ç‚º 32 ä½å…ƒã€‚
</string>
<string name="MBAlpha">
- [APP_NAME] is unable to run because it can&apos;t get an 8 bit alpha channel. Usually this is due to video card driver issues.
-Please make sure you have the latest video card drivers installed.
-Also be sure your monitor is set to True Color (32-bit) in Control Panels &gt; Display &gt; Settings.
-If you continue to receive this message, contact the [SUPPORT_SITE].
+ [APP_NAME] 無法執行,無法å–å¾— 8 ä½å…ƒ alpha é »é“。 這通常是因為顯示å¡é©…動程å¼å‡ºå•é¡Œã€‚
+請確定你安è£äº†æœ€æ–°çš„顯示å¡é©…動程å¼ã€‚
+è«‹åˆ°æŽ§åˆ¶å° &gt; 顯示 &gt; 設定處將螢幕設為全彩(32 ä½å…ƒï¼‰ã€‚
+如果你繼續看到此訊æ¯ï¼Œè«‹è¯çµ¡ [SUPPORT_SITE]。
</string>
<string name="MBPixelFmtSetErr">
無法設定åƒç´ æ ¼å¼
</string>
<string name="MBGLContextErr">
- Can&apos;t create GL rendering context
+ 無法建立 GL 呈åƒç’°å¢ƒ
</string>
<string name="MBGLContextActErr">
- Can&apos;t activate GL rendering context
+ 無法啟動 GL 呈åƒç’°å¢ƒ
</string>
<string name="MBVideoDrvErr">
- [APP_NAME] is unable to run because your video card drivers did not install properly, are out of date, or are for unsupported hardware. Please make sure you have the latest video card drivers and even if you do have the latest, try reinstalling them.
+ [APP_NAME] 無法執行,這å¯èƒ½å› ç‚ºä½ çš„顯示å¡é©…動程å¼å®‰è£ä¸ç•¶ã€ç‰ˆæœ¬éŽèˆŠï¼Œæˆ–者你的硬體ä¸å—支æ´ã€‚ 請確定你安è£äº†æœ€æ–°çš„顯示å¡é©…動程å¼ã€‚如果已è£äº†æœ€æ–°é©…動程å¼ï¼Œè«‹å†é‡æ–°å®‰è£ã€‚
-If you continue to receive this message, contact the [SUPPORT_SITE].
+如果你繼續看到此訊æ¯ï¼Œè«‹è¯çµ¡ [SUPPORT_SITE]。
</string>
<string name="5 O&apos;Clock Shadow">
- 5 O&apos;Clock Shadow
+ 下åˆäº”點的新é¬æ¸£
</string>
<string name="All White">
全白
</string>
<string name="Anime Eyes">
- Anime Eyes
+ æ—¥å¼å‹•æ¼«çœ¼
</string>
<string name="Arced">
- Arced
+ 彎拱的
</string>
<string name="Arm Length">
- Arm Length
+ 臂長
</string>
<string name="Attached">
- Attached
+ 貼附的
</string>
<string name="Attached Earlobes">
- Attached Earlobes
+ 附著耳垂
</string>
<string name="Back Fringe">
- Back Fringe
+ 後ç€æµ·
</string>
<string name="Baggy">
- Baggy
+ 袋型的
</string>
<string name="Bangs">
- Bangs
+ ç€æµ·
</string>
<string name="Beady Eyes">
- Beady Eyes
+ ç åœ“銳光眼
</string>
<string name="Belly Size">
- Belly Size
+ 腹部大å°
</string>
<string name="Big">
- Big
+ 大
</string>
<string name="Big Butt">
- Big Butt
+ 大臀部
</string>
<string name="Big Hair Back">
- Big Hair: Back
+ 大型頭髮:後é¢
</string>
<string name="Big Hair Front">
- Big Hair: Front
+ 大型頭髮:å‰é¢
</string>
<string name="Big Hair Top">
- Big Hair: Top
+ 大型頭髮:頂部
</string>
<string name="Big Head">
- Big Head
+ 大頭
</string>
<string name="Big Pectorals">
- Big Pectorals
+ 大胸肌
</string>
<string name="Big Spikes">
- Big Spikes
+ 大尖直髮
</string>
<string name="Black">
- Black
+ 黑色
</string>
<string name="Blonde">
- Blonde
+ 金色
</string>
<string name="Blonde Hair">
- Blonde Hair
+ 金髮
</string>
<string name="Blush">
- Blush
+ 腮紅
</string>
<string name="Blush Color">
- Blush Color
+ 淺粉色
</string>
<string name="Blush Opacity">
- Blush Opacity
+ 腮紅ä¸é€æ˜Žåº¦ï¼š
</string>
<string name="Body Definition">
- Body Definition
+ 身體çµå¯¦åº¦
</string>
<string name="Body Fat">
- Body Fat
+ 體脂肪
</string>
<string name="Body Freckles">
- Body Freckles
+ 身體雀斑
</string>
<string name="Body Thick">
- Body Thick
+ 寬厚體型
</string>
<string name="Body Thickness">
- Body Thickness
+ 體型厚度
</string>
<string name="Body Thin">
- Body Thin
+ 窄瘦體型
</string>
<string name="Bow Legged">
- Bow Legged
+ 弓形腿
</string>
<string name="Breast Buoyancy">
- Breast Buoyancy
+ 乳房彈性
</string>
<string name="Breast Cleavage">
- Breast Cleavage
+ ä¹³æºæ·±æ·º
</string>
<string name="Breast Size">
- Breast Size
+ 乳房尺寸
</string>
<string name="Bridge Width">
- Bridge Width
+ 兩眼間è·
</string>
<string name="Broad">
- Broad
+ 寬
</string>
<string name="Brow Size">
- Brow Size
+ 眉毛大å°
</string>
<string name="Bug Eyes">
- Bug Eyes
+ çªçœ¼
</string>
<string name="Bugged Eyes">
- Bugged Eyes
+ çªçœ¼
</string>
<string name="Bulbous">
- Bulbous
+ çƒç‹€
</string>
<string name="Bulbous Nose">
- Bulbous Nose
+ çƒç‹€é¼»
</string>
<string name="Breast Physics Mass">
- Breast Mass
+ 乳房質é‡
</string>
<string name="Breast Physics Smoothing">
- Breast Smoothing
+ 乳房增圓滑
</string>
<string name="Breast Physics Gravity">
- Breast Gravity
+ 乳房é‡åŠ›ç‰¹æ€§
</string>
<string name="Breast Physics Drag">
- Breast Drag
+ 乳房阻力
</string>
<string name="Breast Physics InOut Max Effect">
- Max Effect
+ 最大效果
</string>
<string name="Breast Physics InOut Spring">
- Spring
+ 彈跳
</string>
<string name="Breast Physics InOut Gain">
- Gain
+ 增益
</string>
<string name="Breast Physics InOut Damping">
- Damping
+ 阻尼
</string>
<string name="Breast Physics UpDown Max Effect">
- Max Effect
+ 最大效果
</string>
<string name="Breast Physics UpDown Spring">
- Spring
+ 彈跳
</string>
<string name="Breast Physics UpDown Gain">
- Gain
+ 增益
</string>
<string name="Breast Physics UpDown Damping">
- Damping
+ 阻尼
</string>
<string name="Breast Physics LeftRight Max Effect">
- Max Effect
+ 最大效果
</string>
<string name="Breast Physics LeftRight Spring">
- Spring
+ 彈跳
</string>
<string name="Breast Physics LeftRight Gain">
- Gain
+ 增益
</string>
<string name="Breast Physics LeftRight Damping">
- Damping
+ 阻尼
</string>
<string name="Belly Physics Mass">
- Belly Mass
+ 腹部質é‡
</string>
<string name="Belly Physics Smoothing">
- Belly Smoothing
+ 腹部增圓滑
</string>
<string name="Belly Physics Gravity">
- Belly Gravity
+ 腹部é‡åŠ›ç‰¹æ€§
</string>
<string name="Belly Physics Drag">
- Belly Drag
+ 腹部阻力
</string>
<string name="Belly Physics UpDown Max Effect">
- Max Effect
+ 最大效果
</string>
<string name="Belly Physics UpDown Spring">
- Spring
+ 彈跳
</string>
<string name="Belly Physics UpDown Gain">
- Gain
+ 增益
</string>
<string name="Belly Physics UpDown Damping">
- Damping
+ 阻尼
</string>
<string name="Butt Physics Mass">
- Butt Mass
+ 臀部質é‡
</string>
<string name="Butt Physics Smoothing">
- Butt Smoothing
+ 臀部增圓滑
</string>
<string name="Butt Physics Gravity">
- Butt Gravity
+ 臀部é‡åŠ›ç‰¹æ€§
</string>
<string name="Butt Physics Drag">
- Butt Drag
+ 臀部阻力
</string>
<string name="Butt Physics UpDown Max Effect">
- Max Effect
+ 最大效果
</string>
<string name="Butt Physics UpDown Spring">
- Spring
+ 彈跳
</string>
<string name="Butt Physics UpDown Gain">
- Gain
+ 增益
</string>
<string name="Butt Physics UpDown Damping">
- Damping
+ 阻尼
</string>
<string name="Butt Physics LeftRight Max Effect">
- Max Effect
+ 最大效果
</string>
<string name="Butt Physics LeftRight Spring">
- Spring
+ 彈跳
</string>
<string name="Butt Physics LeftRight Gain">
- Gain
+ 增益
</string>
<string name="Butt Physics LeftRight Damping">
- Damping
+ 阻尼
</string>
<string name="Bushy Eyebrows">
- Bushy Eyebrows
+ 濃眉
</string>
<string name="Bushy Hair">
- Bushy Hair
+ 濃密頭髮
</string>
<string name="Butt Size">
- Butt Size
+ 臀部大å°
</string>
<string name="Butt Gravity">
- Butt Gravity
+ 臀部é‡åŠ›ç‰¹æ€§
</string>
<string name="bustle skirt">
- Bustle Skirt
+ å´çšºéŽè†é•·è£™
</string>
<string name="no bustle">
- No Bustle
+ ç„¡å´çšº
</string>
<string name="more bustle">
- More Bustle
+ 增加å´çšº
</string>
<string name="Chaplin">
Chaplin
</string>
<string name="Cheek Bones">
- Cheek Bones
+ 顴骨
</string>
<string name="Chest Size">
- Chest Size
+ 胸部大å°
</string>
<string name="Chin Angle">
下巴角度
</string>
<string name="Chin Cleft">
- Chin Cleft
+ 下巴裂度
</string>
<string name="Chin Curtains">
- Chin Curtains
+ 絡腮é¬
</string>
<string name="Chin Depth">
- Chin Depth
+ 下巴深度
</string>
<string name="Chin Heavy">
- Chin Heavy
+ 下巴厚é‡
</string>
<string name="Chin In">
- Chin In
+ 下巴後縮
</string>
<string name="Chin Out">
- Chin Out
+ 下巴çªå‡º
</string>
<string name="Chin-Neck">
- Chin-Neck
+ 下巴-頸部
</string>
<string name="Clear">
清除
</string>
<string name="Cleft">
- Cleft
+ 分裂
</string>
<string name="Close Set Eyes">
- Close Set Eyes
+ 雙眼é è¿‘
</string>
<string name="Closed">
- Closed
+ é–‰åˆ
</string>
<string name="Closed Back">
- Closed Back
+ 後閉åˆ
</string>
<string name="Closed Front">
- Closed Front
+ å‰é–‰åˆ
</string>
<string name="Closed Left">
- Closed Left
+ 左閉åˆ
</string>
<string name="Closed Right">
- Closed Right
+ å³é–‰åˆ
</string>
<string name="Coin Purse">
- Coin Purse
+ å°éŒ¢åŒ…
</string>
<string name="Collar Back">
- Collar Back
+ 後 Collar
</string>
<string name="Collar Front">
- Collar Front
+ å‰ Collar
</string>
<string name="Corner Down">
- Corner Down
+ 角è½æœä¸‹
</string>
<string name="Corner Up">
- Corner Up
+ 角è½æœä¸Š
</string>
<string name="Creased">
- Creased
+ 皺褶
</string>
<string name="Crooked Nose">
- Crooked Nose
+ 彎曲鼻
</string>
<string name="Cuff Flare">
- Cuff Flare
+ 袖å£è£é£¾
</string>
<string name="Dark">
- Dark
+ 深暗
</string>
<string name="Dark Green">
- Dark Green
+ 深綠
</string>
<string name="Darker">
- Darker
+ 更深暗
</string>
<string name="Deep">
- Deep
+ æ·±
</string>
<string name="Default Heels">
- Default Heels
+ é è¨­é«˜è·Ÿéž‹
</string>
<string name="Dense">
- Dense
+ 稠密
</string>
<string name="Double Chin">
- Double Chin
+ 雙下巴
</string>
<string name="Downturned">
- Downturned
+ 嘴角下垂
</string>
<string name="Duffle Bag">
- Duffle Bag
+ 旅行袋
</string>
<string name="Ear Angle">
- Ear Angle
+ 耳朵角度
</string>
<string name="Ear Size">
- Ear Size
+ 耳朵大å°
</string>
<string name="Ear Tips">
- Ear Tips
+ 耳端
</string>
<string name="Egg Head">
- Egg Head
+ 蛋形頭
</string>
<string name="Eye Bags">
- Eye Bags
+ 眼袋
</string>
<string name="Eye Color">
- Eye Color
+ 眼ç›é¡è‰²
</string>
<string name="Eye Depth">
- Eye Depth
+ 眼ç›æ·±åº¦
</string>
<string name="Eye Lightness">
- Eye Lightness
+ 眼ç›äº®åº¦
</string>
<string name="Eye Opening">
- Eye Opening
+ 眼ç›åž‚直大å°
</string>
<string name="Eye Pop">
- Eye Pop
+ çœ¼ç› Pop
</string>
<string name="Eye Size">
- Eye Size
+ 眼ç›å¤§å°
</string>
<string name="Eye Spacing">
- Eye Spacing
+ 雙眼間è·
</string>
<string name="Eyebrow Arc">
- Eyebrow Arc
+ 眉毛弧度
</string>
<string name="Eyebrow Density">
- Eyebrow Density
+ 眉毛密度
</string>
<string name="Eyebrow Height">
- Eyebrow Height
+ 眉毛高度
</string>
<string name="Eyebrow Points">
- Eyebrow Points
+ 眉毛點
</string>
<string name="Eyebrow Size">
- Eyebrow Size
+ 眉毛尺寸
</string>
<string name="Eyelash Length">
- Eyelash Length
+ ç«æ¯›é•·åº¦
</string>
<string name="Eyeliner">
- Eyeliner
+ 眼線筆
</string>
<string name="Eyeliner Color">
- Eyeliner Color
+ 眼影筆é¡è‰²
</string>
<string name="Eyes Bugged">
- Eyes Bugged
+ çªçœ¼
</string>
<string name="Face Shear">
- Face Shear
+ 臉部å移
</string>
<string name="Facial Definition">
- Facial Definition
+ 臉部çµå¯¦åº¦
</string>
<string name="Far Set Eyes">
- Far Set Eyes
+ 雙眼è·é›¢é 
</string>
<string name="Fat Lips">
- Fat Lips
+ 厚脣
</string>
<string name="Female">
- Female
+ 女性
</string>
<string name="Fingerless">
- Fingerless
+ 無手指
</string>
<string name="Fingers">
- Fingers
+ 手指
</string>
<string name="Flared Cuffs">
- Flared Cuffs
+ 帶è£é£¾è¢–å£
</string>
<string name="Flat">
- Flat
+ å¹³
</string>
<string name="Flat Butt">
- Flat Butt
+ 臀部æ‰å¹³
</string>
<string name="Flat Head">
- Flat Head
+ 頭部æ‰å¹³
</string>
<string name="Flat Toe">
- Flat Toe
+ 腳趾æ‰å¹³
</string>
<string name="Foot Size">
- Foot Size
+ 腳部大å°
</string>
<string name="Forehead Angle">
- Forehead Angle
+ å‰é¡è§’度
</string>
<string name="Forehead Heavy">
- Forehead Heavy
+ å‰é¡å¯¬åŽš
</string>
<string name="Freckles">
- Freckles
+ 雀斑
</string>
<string name="Front Fringe">
- Front Fringe
+ å‰ç€æµ·
</string>
<string name="Full Back">
- Full Back
+ 後部飽滿
</string>
<string name="Full Eyeliner">
- Full Eyeliner
+ 厚é‡çœ¼ç·š
</string>
<string name="Full Front">
- Full Front
+ å‰é¢é£½æ»¿
</string>
<string name="Full Hair Sides">
- Full Hair Sides
+ å´é«®é£½æ»¿
</string>
<string name="Full Sides">
- Full Sides
+ å…©å´é£½æ»¿
</string>
<string name="Glossy">
- Glossy
+ 光亮
</string>
<string name="Glove Fingers">
- Glove Fingers
+ 手套手指
</string>
<string name="Glove Length">
- Glove Length
+ 手套長度
</string>
<string name="Hair">
é ­é«®
</string>
<string name="Hair Back">
- Hair: Back
+ 頭髮:後é¢
</string>
<string name="Hair Front">
- Hair: Front
+ 頭髮:å‰é¢
</string>
<string name="Hair Sides">
- Hair: Sides
+ 頭髮:å´é¢
</string>
<string name="Hair Sweep">
- Hair Sweep
+ 頭髮垂擺
</string>
<string name="Hair Thickess">
- Hair Thickness
+ 頭髮厚度
</string>
<string name="Hair Thickness">
- Hair Thickness
+ 頭髮厚度
</string>
<string name="Hair Tilt">
- Hair Tilt
+ 頭髮傾度
</string>
<string name="Hair Tilted Left">
- Hair Tilted Left
+ 頭髮傾左
</string>
<string name="Hair Tilted Right">
- Hair Tilted Right
+ 頭髮傾å³
</string>
<string name="Hair Volume">
- Hair: Volume
+ 頭髮:髮é‡
</string>
<string name="Hand Size">
- Hand Size
+ 手部大å°
</string>
<string name="Handlebars">
- Handlebars
+ 把手
</string>
<string name="Head Length">
- Head Length
+ 頭部長度
</string>
<string name="Head Shape">
- Head Shape
+ é ­åž‹
</string>
<string name="Head Size">
- Head Size
+ 頭部大å°
</string>
<string name="Head Stretch">
- Head Stretch
+ 頭部延展度
</string>
<string name="Heel Height">
- Heel Height
+ 腳踵高度
</string>
<string name="Heel Shape">
- Heel Shape
+ 腳踵形狀
</string>
<string name="Height">
- Height
+ 高度
</string>
<string name="High">
- High
+ 高
</string>
<string name="High Heels">
- High Heels
+ 高跟鞋
</string>
<string name="High Jaw">
- High Jaw
+ 高顎
</string>
<string name="High Platforms">
- High Platforms
+ 高平臺
</string>
<string name="High and Tight">
- High and Tight
+ 高而緊緻
</string>
<string name="Higher">
- Higher
+ 更高
</string>
<string name="Hip Length">
- Hip Length
+ è…°é•·
</string>
<string name="Hip Width">
- Hip Width
+ 腰寬
+ </string>
+ <string name="Hover">
+ åœæ‡¸
</string>
<string name="In">
- In
+ å‘å…§
</string>
<string name="In Shdw Color">
- Inner Shadow Color
+ 內陰影é¡è‰²
</string>
<string name="In Shdw Opacity">
- Inner Shadow Opacity
+ 內陰影ä¸é€æ˜Žåº¦
</string>
<string name="Inner Eye Corner">
- Inner Eye Corner
+ 眼內角
</string>
<string name="Inner Eye Shadow">
- Inner Eye Shadow
+ 內眼陰影
</string>
<string name="Inner Shadow">
- Inner Shadow
+ 內陰影
</string>
<string name="Jacket Length">
- Jacket Length
+ 外套長度
</string>
<string name="Jacket Wrinkles">
- Jacket Wrinkles
+ 外套皺褶
</string>
<string name="Jaw Angle">
- Jaw Angle
+ 顎角度
</string>
<string name="Jaw Jut">
- Jaw Jut
+ é¡Žçªå‡º
</string>
<string name="Jaw Shape">
- Jaw Shape
+ é¡Žå½¢
</string>
<string name="Join">
- Join
+ 加入
</string>
<string name="Jowls">
- Jowls
+ 下頜
</string>
<string name="Knee Angle">
- Knee Angle
+ è†éƒ¨è§’度
</string>
<string name="Knock Kneed">
- Knock Kneed
+ å…«å­—è…¿
</string>
<string name="Large">
- Large
+ 大
</string>
<string name="Large Hands">
- Large Hands
+ 大手掌
</string>
<string name="Left Part">
- Left Part
+ 左邊分
</string>
<string name="Leg Length">
- Leg Length
+ è…¿é•·
</string>
<string name="Leg Muscles">
- Leg Muscles
+ 腿肌肉
</string>
<string name="Less">
- Less
+ æ›´å°‘
</string>
<string name="Less Body Fat">
- Less Body Fat
+ 體脂肪較少
</string>
<string name="Less Curtains">
- Less Curtains
+ 絡腮é¬è¼ƒçŸ­
</string>
<string name="Less Freckles">
- Less Freckles
+ 雀斑較少
</string>
<string name="Less Full">
- Less Full
+ 較ä¸é£½æ»¿
</string>
<string name="Less Gravity">
- Less Gravity
+ 較少é‡åŠ›
</string>
<string name="Less Love">
- Less Love
+ 少一點愛
</string>
<string name="Less Muscles">
- Less Muscles
+ 少一點肌肉
</string>
<string name="Less Muscular">
- Less Muscular
+ 少一點肌壯感
</string>
<string name="Less Rosy">
- Less Rosy
+ 少一點紅潤
</string>
<string name="Less Round">
- Less Round
+ 少一點圓度
</string>
<string name="Less Saddle">
- Less Saddle
+ è…¿é æ”一點
</string>
<string name="Less Square">
- Less Square
+ 少一點方形
</string>
<string name="Less Volume">
- Less Volume
+ 少一點é‡
</string>
<string name="Less soul">
- Less soul
+ 少一點éˆé­‚
</string>
<string name="Lighter">
- Lighter
+ 亮一點
</string>
<string name="Lip Cleft">
- Lip Cleft
+ 脣裂度
</string>
<string name="Lip Cleft Depth">
- Lip Cleft Depth
+ 脣裂深度
</string>
<string name="Lip Fullness">
- Lip Fullness
+ è„£è±åº¦
</string>
<string name="Lip Pinkness">
- Lip Pinkness
+ 脣色粉紅度
</string>
<string name="Lip Ratio">
- Lip Ratio
+ 脣比率
</string>
<string name="Lip Thickness">
- Lip Thickness
+ 脣厚度
</string>
<string name="Lip Width">
- Lip Width
+ 脣寬度
</string>
<string name="Lipgloss">
- Lipgloss
+ 脣蜜
</string>
<string name="Lipstick">
- Lipstick
+ è„£è†
</string>
<string name="Lipstick Color">
- Lipstick Color
+ è„£è†é¡è‰²
</string>
<string name="Long">
- Long
+ é•·
</string>
<string name="Long Head">
- Long Head
+ 長臉
</string>
<string name="Long Hips">
- Long Hips
+ 高腰
</string>
<string name="Long Legs">
- Long Legs
+ é•·è…¿
</string>
<string name="Long Neck">
- Long Neck
+ é•·é ¸
</string>
<string name="Long Pigtails">
- Long Pigtails
+ é•·è¾®å­
</string>
<string name="Long Ponytail">
- Long Ponytail
+ 長馬尾辮
</string>
<string name="Long Torso">
- Long Torso
+ 長軀幹
</string>
<string name="Long arms">
- Long arms
+ 長臂
</string>
<string name="Loose Pants">
- Loose Pants
+ 寬鬆褲å­
</string>
<string name="Loose Shirt">
- Loose Shirt
+ 寬鬆襯衫
</string>
<string name="Loose Sleeves">
- Loose Sleeves
+ 寬鬆袖å­
</string>
<string name="Love Handles">
- Love Handles
+ 腰間贅肉
</string>
<string name="Low">
- Low
+ 低
</string>
<string name="Low Heels">
- Low Heels
+ 低跟鞋
</string>
<string name="Low Jaw">
- Low Jaw
+ 低顎
</string>
<string name="Low Platforms">
- Low Platforms
+ 低平臺
</string>
<string name="Low and Loose">
- Low and Loose
+ 低而寬鬆
</string>
<string name="Lower">
- Lower
+ é™ä½Ž
</string>
<string name="Lower Bridge">
- Lower Bridge
+ 鼻樑低一點
</string>
<string name="Lower Cheeks">
- Lower Cheeks
+ 雙頰低一點
</string>
<string name="Male">
男性
</string>
<string name="Middle Part">
- Middle Part
+ 中間邊分
</string>
<string name="More">
更多
</string>
<string name="More Blush">
- More Blush
+ 增加腮紅
</string>
<string name="More Body Fat">
- More Body Fat
+ 增加體脂肪
</string>
<string name="More Curtains">
- More Curtains
+ 增加絡腮é¬
</string>
<string name="More Eyeshadow">
- More Eyeshadow
+ 增加眼影
</string>
<string name="More Freckles">
- More Freckles
+ 增加雀斑
</string>
<string name="More Full">
- More Full
+ 更飽滿
</string>
<string name="More Gravity">
- More Gravity
+ 增加é‡åŠ›
</string>
<string name="More Lipstick">
- More Lipstick
+ 多一點脣è†
</string>
<string name="More Love">
- More Love
+ 多一點愛
</string>
<string name="More Lower Lip">
- More Lower Lip
+ 下脣更è±æ»¿
</string>
<string name="More Muscles">
- More Muscles
+ 多一點肌肉
</string>
<string name="More Muscular">
- More Muscular
+ 增加肌壯感
</string>
<string name="More Rosy">
- More Rosy
+ 更加紅潤
</string>
<string name="More Round">
- More Round
+ 增加圓度
</string>
<string name="More Saddle">
- More Saddle
+ 腿更加張開
</string>
<string name="More Sloped">
- More Sloped
+ 更加傾斜
</string>
<string name="More Square">
- More Square
+ 增加方形
</string>
<string name="More Upper Lip">
- More Upper Lip
+ 上脣更è±æ»¿
</string>
<string name="More Vertical">
- More Vertical
+ 更加垂直
</string>
<string name="More Volume">
- More Volume
+ 多一點é‡
</string>
<string name="More soul">
- More soul
+ 多一點éˆé­‚
</string>
<string name="Moustache">
- Moustache
+ é«­é¬
</string>
<string name="Mouth Corner">
- Mouth Corner
+ 嘴角
</string>
<string name="Mouth Position">
- Mouth Position
+ 嘴巴ä½ç½®
</string>
<string name="Mowhawk">
- Mowhawk
+ 莫éœå…‹é«®åž‹
</string>
<string name="Muscular">
- Muscular
+ 肌肉發é”
</string>
<string name="Mutton Chops">
- Mutton Chops
+ 羊排å¼çµ¡è…®é¬
</string>
<string name="Nail Polish">
- Nail Polish
+ 指甲油
</string>
<string name="Nail Polish Color">
- Nail Polish Color
+ 指甲油é¡è‰²
</string>
<string name="Narrow">
- Narrow
+ 窄
</string>
<string name="Narrow Back">
- Narrow Back
+ 後窄
</string>
<string name="Narrow Front">
- Narrow Front
+ å‰çª„
</string>
<string name="Narrow Lips">
- Narrow Lips
+ 窄脣
</string>
<string name="Natural">
- Natural
+ 自然
</string>
<string name="Neck Length">
- Neck Length
+ 頸長
</string>
<string name="Neck Thickness">
- Neck Thickness
+ 頸部厚度
</string>
<string name="No Blush">
- No Blush
+ 無腮紅
</string>
<string name="No Eyeliner">
- No Eyeliner
+ 無眼線
</string>
<string name="No Eyeshadow">
- No Eyeshadow
+ 無眼影
</string>
<string name="No Lipgloss">
- No Lipgloss
+ 無脣蜜
</string>
<string name="No Lipstick">
- No Lipstick
+ ç„¡è„£è†
</string>
<string name="No Part">
- No Part
+ 無邊分
</string>
<string name="No Polish">
- No Polish
+ 無指甲油
</string>
<string name="No Red">
- No Red
+ 去紅色
</string>
<string name="No Spikes">
- No Spikes
+ ç„¡å°–ç›´å½¢
</string>
<string name="No White">
- No White
+ 去白色
</string>
<string name="No Wrinkles">
- No Wrinkles
+ 無皺紋
</string>
<string name="Normal Lower">
- Normal Lower
+ 正常下åŠ
</string>
<string name="Normal Upper">
- Normal Upper
+ 正常上åŠ
</string>
<string name="Nose Left">
- Nose Left
+ 左鼻
</string>
<string name="Nose Right">
- Nose Right
+ å³é¼»
</string>
<string name="Nose Size">
- Nose Size
+ 鼻部大å°
</string>
<string name="Nose Thickness">
- Nose Thickness
+ é¼»å­åŽšåº¦
</string>
<string name="Nose Tip Angle">
- Nose Tip Angle
+ 鼻尖角度
</string>
<string name="Nose Tip Shape">
- Nose Tip Shape
+ 鼻尖形狀
</string>
<string name="Nose Width">
- Nose Width
+ 鼻寬
</string>
<string name="Nostril Division">
- Nostril Division
+ 鼻孔分開度
</string>
<string name="Nostril Width">
- Nostril Width
+ 鼻孔寬
</string>
<string name="Opaque">
- Opaque
+ ä¸é€æ˜Ž
</string>
<string name="Open">
- Open
+ 打開
</string>
<string name="Open Back">
- Open Back
+ 後開
</string>
<string name="Open Front">
- Open Front
+ å‰é–‹
</string>
<string name="Open Left">
- Open Left
+ 左開
</string>
<string name="Open Right">
- Open Right
+ å³é–‹
</string>
<string name="Orange">
- Orange
+ 橘色
</string>
<string name="Out">
- Out
+ 外
</string>
<string name="Out Shdw Color">
- Outer Shadow Color
+ 外陰影é¡è‰²
</string>
<string name="Out Shdw Opacity">
- Outer Shadow Opacity
+ 外陰影ä¸é€æ˜Žåº¦
</string>
<string name="Outer Eye Corner">
- Outer Eye Corner
+ 眼外角
</string>
<string name="Outer Eye Shadow">
- Outer Eye Shadow
+ 外眼陰影
</string>
<string name="Outer Shadow">
- Outer Shadow
+ 外陰影
</string>
<string name="Overbite">
- Overbite
+ 齙牙
</string>
<string name="Package">
- Package
+ é…套
</string>
<string name="Painted Nails">
- Painted Nails
+ 美甲
</string>
<string name="Pale">
- Pale
+ 蒼白
</string>
<string name="Pants Crotch">
- Pants Crotch
+ 褲襠
</string>
<string name="Pants Fit">
- Pants Fit
+ 褲å­åˆèº«åº¦
</string>
<string name="Pants Length">
- Pants Length
+ 褲長
</string>
<string name="Pants Waist">
- Pants Waist
+ 褲腰
</string>
<string name="Pants Wrinkles">
- Pants Wrinkles
+ 褲å­çšºè¤¶
</string>
<string name="Part">
- Part
+ 邊分
</string>
<string name="Part Bangs">
- Part Bangs
+ 邊分ç€æµ·
</string>
<string name="Pectorals">
- Pectorals
+ 胸肌
</string>
<string name="Pigment">
- Pigment
+ 色素
</string>
<string name="Pigtails">
- Pigtails
+ è¾®å­
</string>
<string name="Pink">
- Pink
+ 粉紅
</string>
<string name="Pinker">
- Pinker
+ 增加粉紅
</string>
<string name="Platform Height">
- Platform Height
+ 平臺高度
</string>
<string name="Platform Width">
- Platform Width
+ 平臺寬度
</string>
<string name="Pointy">
- Pointy
+ å°–ç‹€
</string>
<string name="Pointy Heels">
- Pointy Heels
+ 尖狀高跟鞋
</string>
<string name="Ponytail">
- Ponytail
+ 馬尾辮
</string>
<string name="Poofy Skirt">
- Poofy Skirt
+ 蓬蓬裙
</string>
<string name="Pop Left Eye">
- Pop Left Eye
+ 左眼 Pop
</string>
<string name="Pop Right Eye">
- Pop Right Eye
+ å³çœ¼ Pop
</string>
<string name="Puffy">
- Puffy
+ 眼腫
</string>
<string name="Puffy Eyelids">
- Puffy Eyelids
+ 眼瞼腫
</string>
<string name="Rainbow Color">
- Rainbow Color
+ 虹彩
</string>
<string name="Red Hair">
- Red Hair
+ ç´…é«®
</string>
<string name="Regular">
- Regular
+ 一般
</string>
<string name="Right Part">
- Right Part
+ å³é‚Šåˆ†
</string>
<string name="Rosy Complexion">
- Rosy Complexion
+ 臉色紅潤
</string>
<string name="Round">
- Round
+ 圓
</string>
<string name="Ruddiness">
- Ruddiness
+ 紅潤度
</string>
<string name="Ruddy">
- Ruddy
+ 紅潤
</string>
<string name="Rumpled Hair">
- Rumpled Hair
+ 亂髮
</string>
<string name="Saddle Bags">
- Saddle Bags
+ 馬éžåž‹å·¥å…·è¢‹
</string>
<string name="Scrawny Leg">
- Scrawny Leg
+ 削瘦的腿
</string>
<string name="Separate">
- Separate
+ 分開
</string>
<string name="Shallow">
- Shallow
+ æ·º
</string>
<string name="Shear Back">
- Shear Back
+ 後å移
</string>
<string name="Shear Face">
- Shear Face
+ 臉部å移
</string>
<string name="Shear Front">
- Shear Front
+ å‰å移
</string>
<string name="Shear Left Up">
- Shear Left Up
+ 左上å移
</string>
<string name="Shear Right Up">
- Shear Right Up
+ å³ä¸Šå移
</string>
<string name="Sheared Back">
- Sheared Back
+ 後å移
</string>
<string name="Sheared Front">
- Sheared Front
+ å‰å移
</string>
<string name="Shift Left">
- Shift Left
+ 左移
</string>
<string name="Shift Mouth">
- Shift Mouth
+ 嘴部å移
</string>
<string name="Shift Right">
- Shift Right
+ å³ç§»
</string>
<string name="Shirt Bottom">
- Shirt Bottom
+ 襯衫底
</string>
<string name="Shirt Fit">
- Shirt Fit
+ 襯衫åˆèº«åº¦
</string>
<string name="Shirt Wrinkles">
- Shirt Wrinkles
+ 襯衫皺褶
</string>
<string name="Shoe Height">
- Shoe Height
+ 鞋高
</string>
<string name="Short">
- Short
+ 短
</string>
<string name="Short Arms">
- Short Arms
+ 短臂
</string>
<string name="Short Legs">
- Short Legs
+ 短腿
</string>
<string name="Short Neck">
- Short Neck
+ 短頸
</string>
<string name="Short Pigtails">
- Short Pigtails
+ 短辮å­
</string>
<string name="Short Ponytail">
- Short Ponytail
+ 短馬尾辮
</string>
<string name="Short Sideburns">
- Short Sideburns
+ 短鬢鬚
</string>
<string name="Short Torso">
- Short Torso
+ 短軀幹
</string>
<string name="Short hips">
- Short hips
+ 短腰
</string>
<string name="Shoulders">
- Shoulders
+ 肩膀
</string>
<string name="Side Fringe">
- Side Fringe
+ å´ç€æµ·
</string>
<string name="Sideburns">
- Sideburns
+ 鬢鬚
</string>
<string name="Sides Hair">
- Sides Hair
+ å´é¢é ­é«®
</string>
<string name="Sides Hair Down">
- Sides Hair Down
+ å´é¢é ­é«®ä¸‹éƒ¨
</string>
<string name="Sides Hair Up">
- Sides Hair Up
+ å´é¢é ­é«®ä¸Šéƒ¨
</string>
<string name="Skinny Neck">
- Skinny Neck
+ 削瘦頸部
</string>
<string name="Skirt Fit">
- Skirt Fit
+ 裙å­åˆèº«åº¦
</string>
<string name="Skirt Length">
- Skirt Length
+ 裙長
</string>
<string name="Slanted Forehead">
- Slanted Forehead
+ æ–œå‰é¡
</string>
<string name="Sleeve Length">
- Sleeve Length
+ 袖長
</string>
<string name="Sleeve Looseness">
- Sleeve Looseness
+ 袖å­å¯¬é¬†åº¦
</string>
<string name="Slit Back">
- Slit: Back
+ 後分
</string>
<string name="Slit Front">
- Slit: Front
+ å‰åˆ†
</string>
<string name="Slit Left">
- Slit: Left
+ 左分
</string>
<string name="Slit Right">
- Slit: Right
+ å³åˆ†
</string>
<string name="Small">
- Small
+ å°
</string>
<string name="Small Hands">
- Small Hands
+ å°æ‰‹
</string>
<string name="Small Head">
- Small Head
+ å°é ­
</string>
<string name="Smooth">
- Smooth
+ 平滑
</string>
<string name="Smooth Hair">
- Smooth Hair
+ 平滑頭髮
</string>
<string name="Socks Length">
- Socks Length
+ 襪長
</string>
<string name="Soulpatch">
- Soulpatch
+ 脣下撮é¬
</string>
<string name="Sparse">
- Sparse
+ 稀ç–
</string>
<string name="Spiked Hair">
- Spiked Hair
+ å°–ç›´é ­é«®
</string>
<string name="Square">
- Square
+ 方形
</string>
<string name="Square Toe">
- Square Toe
+ 平頭鞋
</string>
<string name="Squash Head">
- Squash Head
+ 長瓜形臉
</string>
<string name="Stretch Head">
- Stretch Head
+ 延展頭部
</string>
<string name="Sunken">
- Sunken
+ 深陷
</string>
<string name="Sunken Chest">
- Sunken Chest
+ 胸部內陷
</string>
<string name="Sunken Eyes">
- Sunken Eyes
+ 眼ç›æ·±é™·
</string>
<string name="Sweep Back">
- Sweep Back
+ 後垂擺
</string>
<string name="Sweep Forward">
- Sweep Forward
+ å‰åž‚擺
</string>
<string name="Tall">
- Tall
+ 高
</string>
<string name="Taper Back">
- Taper Back
+ 後漸細
</string>
<string name="Taper Front">
- Taper Front
+ å‰æ¼¸ç´°
</string>
<string name="Thick Heels">
- Thick Heels
+ 粗腳跟
</string>
<string name="Thick Neck">
- Thick Neck
+ ç²—é ¸
</string>
<string name="Thick Toe">
- Thick Toe
+ 粗腳趾
</string>
<string name="Thin">
- Thin
+ 瘦
</string>
<string name="Thin Eyebrows">
- Thin Eyebrows
+ 細眉
</string>
<string name="Thin Lips">
- Thin Lips
+ ç´°è„£
</string>
<string name="Thin Nose">
- Thin Nose
+ ç´°é¼»
</string>
<string name="Tight Chin">
- Tight Chin
+ 緊緻下巴
</string>
<string name="Tight Cuffs">
- Tight Cuffs
+ 緊緻袖å£
</string>
<string name="Tight Pants">
- Tight Pants
+ 緊緻褲å­
</string>
<string name="Tight Shirt">
- Tight Shirt
+ 緊緻襯衫
</string>
<string name="Tight Skirt">
- Tight Skirt
+ 緊緻裙å­
</string>
<string name="Tight Sleeves">
- Tight Sleeves
+ 緊緻袖å­
</string>
<string name="Toe Shape">
- Toe Shape
+ 腳趾形狀
</string>
<string name="Toe Thickness">
- Toe Thickness
+ 腳趾粗細
</string>
<string name="Torso Length">
- Torso Length
+ 軀幹長度
</string>
<string name="Torso Muscles">
- Torso Muscles
+ 軀幹肌肉
</string>
<string name="Torso Scrawny">
- Torso Scrawny
+ 軀幹削瘦
</string>
<string name="Unattached">
- Unattached
+ 未附著
</string>
<string name="Uncreased">
- Uncreased
+ 無皺痕
</string>
<string name="Underbite">
- Underbite
+ 戽斗
</string>
<string name="Unnatural">
- Unnatural
+ ä¸è‡ªç„¶
</string>
<string name="Upper Bridge">
- Upper Bridge
+ 上鼻æ¢
</string>
<string name="Upper Cheeks">
- Upper Cheeks
+ 上臉頰
</string>
<string name="Upper Chin Cleft">
- Upper Chin Cleft
+ 上部顎裂
</string>
<string name="Upper Eyelid Fold">
- Upper Eyelid Fold
+ 上眼瞼皺褶
</string>
<string name="Upturned">
- Upturned
+ 嘴角上翹
</string>
<string name="Very Red">
- Very Red
+ 大紅
</string>
<string name="Waist Height">
- Waist Height
+ 腰高
</string>
<string name="Well-Fed">
- Well-Fed
+ 飽食的
</string>
<string name="White Hair">
- White Hair
+ 白髮
</string>
<string name="Wide">
- Wide
+ 寬
</string>
<string name="Wide Back">
- Wide Back
+ 後寬
</string>
<string name="Wide Front">
- Wide Front
+ å‰å¯¬
</string>
<string name="Wide Lips">
- Wide Lips
+ 寬脣
</string>
<string name="Wild">
- Wild
+ 狂野
</string>
<string name="Wrinkles">
- Wrinkles
+ 皺紋
</string>
<string name="LocationCtrlAddLandmarkTooltip">
添加到我的地標
@@ -3585,6 +3895,15 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
<string name="LocationCtrlGeneralIconTooltip">
一般普級地å€
</string>
+ <string name="LocationCtrlSeeAVsTooltip">
+ 這地段外的其他化身,看ä¸è¦‹ä¹Ÿè½ä¸åˆ°ä½æ–¼åœ°æ®µè£¡çš„化身
+ </string>
+ <string name="LocationCtrlPathfindingDirtyTooltip">
+ 地å€é‡æ–°ç”¢å‡ºä¹‹å‰ï¼Œå¯ç§»å‹•ç‰©ä»¶å¯èƒ½ç„¡æ³•æ­£å¸¸é‹ä½œã€‚
+ </string>
+ <string name="LocationCtrlPathfindingDisabledTooltip">
+ 這地å€ä¸¦æœªå•Ÿç”¨å‹•æ…‹å°‹å¾‘。
+ </string>
<string name="UpdaterWindowTitle">
[APP_NAME] æ›´æ–°
</string>
@@ -3595,7 +3914,7 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
[APP_NAME] 安è£ä¸­...
</string>
<string name="UpdaterUpdatingDescriptive">
- Your [APP_NAME] Viewer is being updated to the latest release. This may take some time, so please be patient.
+ ä½ çš„ [APP_NAME] Viewer 正在更新為最新發行版。 å¯èƒ½è¦ç­‰ä¸€æœƒå…’,請è€å¿ƒç¨å€™ã€‚
</string>
<string name="UpdaterProgressBarTextWithEllipses">
更新下載中...
@@ -3607,7 +3926,7 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
å¤è¼‰æ›´æ–°å¤±æ•—
</string>
<string name="UpdaterFailUpdateDescriptive">
- An error occurred while updating [APP_NAME]. Please download the latest version from www.secondlife.com.
+ [APP_NAME] 更新時出錯。 請到 www.secondlife.com 下載最新版本。
</string>
<string name="UpdaterFailInstallTitle">
安è£æ›´æ–°å¤±æ•—
@@ -3616,13 +3935,13 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
å•Ÿå‹•ç€è¦½å™¨å¤±æ•—
</string>
<string name="ItemsComingInTooFastFrom">
- [APP_NAME]: Items coming in too fast from [FROM_NAME], automatic preview disabled for [TIME] seconds
+ [APP_NAME]:來自 [FROM_NAME] 的項目速度éŽå¿«ï¼Œå› æ­¤è‡ªå‹•é è¦½æš«åœ [TIME] 秒
</string>
<string name="ItemsComingInTooFast">
- [APP_NAME]: Items coming in too fast, automatic preview disabled for [TIME] seconds
+ [APP_NAME]:進來的項目速度éŽå¿«ï¼Œå› æ­¤è‡ªå‹•é è¦½æš«åœ [TIME] 秒
</string>
<string name="IM_logging_string">
- -- Instant message logging enabled --
+ -- 已開啟åŠæ™‚訊æ¯è¨˜éŒ„ --
</string>
<string name="IM_typing_start_string">
[NAME] 正在輸入...
@@ -3631,43 +3950,55 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
(未命å)
</string>
<string name="IM_moderated_chat_label">
- (Moderated: Voices off by default)
+ (有人主æŒï¼šé è¨­é—œé–‰èªžéŸ³ï¼‰
</string>
<string name="IM_unavailable_text_label">
- Text chat is not available for this call.
+ 這次通話無法使用文字èŠå¤©ã€‚
</string>
<string name="IM_muted_text_label">
- Your text chat has been disabled by a Group Moderator.
+ 群組主æŒäººå·²ç¦æ­¢ä½ é€²è¡Œæ–‡å­—èŠå¤©ã€‚
</string>
<string name="IM_default_text_label">
- 點擊此處以傳é€å³æ™‚訊æ¯ã€‚
+ 點按此處以傳é€å³æ™‚訊æ¯ã€‚
</string>
<string name="IM_to_label">
至
</string>
<string name="IM_moderator_label">
- (Moderator)
+ (主æŒäººï¼‰
</string>
<string name="Saved_message">
- (Saved [LONG_TIMESTAMP])
+ (於 [LONG_TIMESTAMP] 儲存)
+ </string>
+ <string name="IM_unblock_only_groups_friends">
+ è¦å¯Ÿçœ‹é€™è¨Šæ¯ï¼Œä½ å¿…須到「å好設定 / éš±ç§ã€ï¼Œå–消勾é¸ã€Œåªæœ‰æˆ‘的朋å‹å’Œç¾¤çµ„å¯ä»¥ IM 或與我通話ã€ã€‚
+ </string>
+ <string name="OnlineStatus">
+ 上線
+ </string>
+ <string name="OfflineStatus">
+ 離線
</string>
<string name="answered_call">
- Your call has been answered
+ 你的通話已經接通
</string>
<string name="you_started_call">
- You started a voice call
+ 你發起了語音通話
</string>
<string name="you_joined_call">
- You joined the voice call
+ 你發起了語音通話
+ </string>
+ <string name="you_auto_rejected_call-im">
+ 因為處於「請勿打擾ã€æ¨¡å¼ï¼Œä½ å·²è‡ªå‹•æ‹’è½é€™é€šèªžéŸ³ä¾†é›»ã€‚
</string>
<string name="name_started_call">
- [NAME] started a voice call
+ [NAME] 發起了語音通話
</string>
<string name="ringing-im">
加入語音通話...
</string>
<string name="connected-im">
- Connected, click Leave Call to hang up
+ 已接通,è¦æŽ›æ–·è«‹æŒ‰ã€Œé›¢é–‹é€šè©±ã€
</string>
<string name="hang_up-im">
離開語音通話
@@ -3676,40 +4007,40 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
è¯æŽ¥ä¸­...
</string>
<string name="conference-title">
- Ad-hoc Conference
+ 多人èŠå¤©
</string>
<string name="conference-title-incoming">
- Conference with [AGENT_NAME]
+ 和 [AGENT_NAME] 多方通話
</string>
<string name="inventory_item_offered-im">
- Inventory item offered
+ 收ç´å€ç‰©å“已發é€
</string>
<string name="share_alert">
- Drag items from inventory here
+ 將收ç´å€ç‰©å“拖曳到這裡
</string>
<string name="no_session_message">
(IM 會話ä¸å­˜åœ¨ï¼‰
</string>
<string name="only_user_message">
- You are the only user in this session.
+ 這次會話åªæœ‰ä½ ä¸€äººã€‚
</string>
<string name="offline_message">
[NAME] 離線。
</string>
<string name="invite_message">
- Click the [BUTTON NAME] button to accept/connect to this voice chat.
+ 點按 [BUTTON NAME] 按鈕接å—並連通到這個語音èŠå¤©ã€‚
</string>
<string name="muted_message">
- You have blocked this Resident. Sending a message will automatically unblock them.
+ 你已經å°éŽ–這ä½å±…民。 發é€è¨Šæ¯å°‡æœƒè‡ªå‹•è§£é™¤å°éŽ–。
</string>
<string name="generic">
- Error making request, please try again later.
+ é€å‡ºè«‹æ±‚時出錯,請ç¨å€™å†è©¦ã€‚
</string>
<string name="generic_request_error">
- Error making request, please try again later.
+ é€å‡ºè«‹æ±‚時出錯,請ç¨å€™å†è©¦ã€‚
</string>
<string name="insufficient_perms_error">
- You do not have sufficient permissions.
+ 你權é™ä¸è¶³ã€‚
</string>
<string name="session_does_not_exist_error">
此會話ä¸å†å­˜åœ¨
@@ -3721,25 +4052,25 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
你並ä¸å…·æœ‰é€™å€‹èƒ½åŠ›ã€‚
</string>
<string name="not_a_mod_error">
- You are not a session moderator.
+ ä½ ä¸å…·æœƒè©±ä¸»æŒäººèº«ä»½ã€‚
</string>
<string name="muted">
- A group moderator disabled your text chat.
+ æŸç¾¤çµ„主æŒäººç¦æ­¢äº†ä½ çš„文字èŠå¤©ã€‚
</string>
<string name="muted_error">
- A group moderator disabled your text chat.
+ æŸç¾¤çµ„主æŒäººç¦æ­¢äº†ä½ çš„文字èŠå¤©ã€‚
</string>
<string name="add_session_event">
- Unable to add users to chat session with [RECIPIENT].
+ 無法新增使用者加入與 [RECIPIENT] çš„èŠå¤©æœƒè©±ã€‚
</string>
<string name="message">
- Unable to send your message to the chat session with [RECIPIENT].
+ 你的訊æ¯ç„¡æ³•å‚³é€çµ¦èˆ‡ [RECIPIENT] çš„èŠå¤©æœƒè©±ã€‚
</string>
<string name="message_session_event">
- Unable to send your message to the chat session with [RECIPIENT].
+ 你的訊æ¯ç„¡æ³•å‚³é€çµ¦èˆ‡ [RECIPIENT] çš„èŠå¤©æœƒè©±ã€‚
</string>
<string name="mute">
- Error while moderating.
+ 主æŒæœŸé–“發生錯誤。
</string>
<string name="removed">
你已經由群組中被移除。
@@ -3748,49 +4079,64 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
你已經由群組中被移除。
</string>
<string name="close_on_no_ability">
- You no longer have the ability to be in the chat session.
+ 你已無法進入這個èŠå¤©æœƒè©±ã€‚
</string>
<string name="unread_chat_single">
- [SOURCES] has said something new
+ [SOURCES] åˆèªªäº†ä¸€äº›è©±
</string>
<string name="unread_chat_multiple">
- [SOURCES] have said something new
+ [SOURCES] åˆèªªäº†ä¸€äº›è©±
</string>
<string name="session_initialization_timed_out_error">
- The session initialization is timed out
+ 會話åˆå§‹åŒ–逾時,無法完æˆ
+ </string>
+ <string name="Home position set.">
+ 我的家ä½ç½®å·²å®šã€‚
</string>
<string name="voice_morphing_url">
http://secondlife.com/landing/voicemorphing
</string>
<string name="paid_you_ldollars">
- [NAME] paid you L$[AMOUNT] [REASON].
+ [NAME] 支付你 L$[AMOUNT]([REASON])。
</string>
<string name="paid_you_ldollars_no_reason">
- [NAME] paid you L$[AMOUNT].
+ [NAME] 支付你 L$[AMOUNT]。
</string>
<string name="you_paid_ldollars">
- You paid [NAME] L$[AMOUNT] [REASON].
+ 你支付 L$[AMOUNT] 給 [NAME]([REASON])。
</string>
<string name="you_paid_ldollars_no_info">
- You paid L$[AMOUNT].
+ 你支付了 L$[AMOUNT]。
</string>
<string name="you_paid_ldollars_no_reason">
- You paid [NAME] L$[AMOUNT].
+ 你支付 L$[AMOUNT] 給 [NAME]。
</string>
<string name="you_paid_ldollars_no_name">
- You paid L$[AMOUNT] [REASON].
+ 你支付了 L$[AMOUNT]([REASON])。
+ </string>
+ <string name="you_paid_failure_ldollars">
+ 你支付 L$[AMOUNT] 給 [NAME] 時出錯:[REASON]。
+ </string>
+ <string name="you_paid_failure_ldollars_no_info">
+ 你支付 L$[AMOUNT] 時出錯。
+ </string>
+ <string name="you_paid_failure_ldollars_no_reason">
+ 你支付 L$[AMOUNT] 給 [NAME] 時出錯。
+ </string>
+ <string name="you_paid_failure_ldollars_no_name">
+ 你支付 L$[AMOUNT] 時出錯:[REASON]。
</string>
<string name="for item">
- for [ITEM]
+ 購買 [ITEM]
</string>
<string name="for a parcel of land">
- for a parcel of land
+ 購買一土地地段
</string>
<string name="for a land access pass">
- for a land access pass
+ 購買土地出入通行權
</string>
<string name="for deeding land">
- for deeding land
+ 讓渡土地
</string>
<string name="to create a group">
以創造群組
@@ -3802,39 +4148,39 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
以上傳
</string>
<string name="to publish a classified ad">
- to publish a classified ad
+ 發布一則個人廣告
</string>
<string name="giving">
- Giving L$ [AMOUNT]
+ æè´ˆ L$ [AMOUNT]
</string>
<string name="uploading_costs">
上傳花費 L$ [AMOUNT]
</string>
<string name="this_costs">
- This costs L$ [AMOUNT]
+ 本次花費 L$ [AMOUNT]
</string>
<string name="buying_selected_land">
- Buying selected land for L$ [AMOUNT]
+ 花費 L$ [AMOUNT] 購買所é¸åœŸåœ°
</string>
<string name="this_object_costs">
- This object costs L$ [AMOUNT]
+ 本物件價格 L$ [AMOUNT]
</string>
<string name="group_role_everyone">
任何人
</string>
<string name="group_role_officers">
- Officers
+ è·å“¡
</string>
<string name="group_role_owners">
- æ“有者
+ 所有人
</string>
<string name="group_member_status_online">
上線
</string>
<string name="uploading_abuse_report">
上傳中...
-
-舉報濫用
+
+é•è¦èˆ‰å ±
</string>
<string name="New Shape">
新體形
@@ -3861,7 +4207,7 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
新襪å­
</string>
<string name="New Jacket">
- 新夾克
+ 新外套
</string>
<string name="New Gloves">
新手套
@@ -3912,7 +4258,7 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
女性姿勢
</string>
<string name="Other Gestures">
- 其他姿勢
+ 其他���勢
</string>
<string name="Speech Gestures">
演說姿勢
@@ -3921,91 +4267,172 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
一般姿勢
</string>
<string name="Male - Excuse me">
- Male - Excuse me
+ 男性 - Excuse me
</string>
<string name="Male - Get lost">
- Male - Get lost
+ Male - 給我滾蛋ï¼
</string>
<string name="Male - Blow kiss">
- Male - Blow kiss
+ 男性 - 飛å»
</string>
<string name="Male - Boo">
- Male - Boo
+ 男性 - 我噓你
</string>
<string name="Male - Bored">
- Male - Bored
+ 男性 - ç„¡èŠç‹€
</string>
<string name="Male - Hey">
- Male - Hey
+ 男性 - 嘿ï¼
</string>
<string name="Male - Laugh">
- Male - Laugh
+ 男性 - 笑
</string>
<string name="Male - Repulsed">
- Male - Repulsed
+ 男性 - 作å™
</string>
<string name="Male - Shrug">
- Male - Shrug
+ 男性 - è³è³è‚©
</string>
<string name="Male - Stick tougue out">
- Male - Stick tougue out
+ 男性 - å舌頭
</string>
<string name="Male - Wow">
- Male - Wow
+ 男性 - 哇塞
</string>
<string name="Female - Chuckle">
- Female - Chuckle
+ 女性 - 咯咯笑
</string>
<string name="Female - Cry">
- Female - Cry
+ 女性 - 哭
</string>
<string name="Female - Embarrassed">
- Female - Embarrassed
+ 女性 - 尷尬
</string>
<string name="Female - Excuse me">
- Female - Excuse me
+ 男性 - Excuse me
</string>
<string name="Female - Get lost">
- Female - Get lost
+ 女性 - 給我滾蛋ï¼
</string>
<string name="Female - Blow kiss">
- Female - Blow kiss
+ 女性 - 飛å»
</string>
<string name="Female - Boo">
- Female - Boo
+ 女性 - 我噓你
</string>
<string name="Female - Bored">
- Female - Bored
+ 女性 - ç„¡èŠç‹€
</string>
<string name="Female - Hey">
- Female - Hey
+ 女性 - 嘿ï¼
</string>
<string name="Female - Hey baby">
- Female - Hey baby
+ 女性 - 嘿,寶è²
</string>
<string name="Female - Laugh">
- Female - Laugh
+ 女性 - 笑
</string>
<string name="Female - Looking good">
- Female - Looking good
+ 女性 - 看我美ä¸ç¾Ž
</string>
<string name="Female - Over here">
- Female - Over here
+ 女性 - 我在這兒
</string>
<string name="Female - Please">
- Female - Please
+ 女性 - 請
</string>
<string name="Female - Repulsed">
- Female - Repulsed
+ 女性 - 作å™
</string>
<string name="Female - Shrug">
- Female - Shrug
+ 女性 - è³è³è‚©
</string>
<string name="Female - Stick tougue out">
- Female - Stick tougue out
+ 女性 - å舌頭
</string>
<string name="Female - Wow">
- Female - Wow
+ 女性 - 哇塞
+ </string>
+ <string name="/bow">
+ /彎腰點頭
+ </string>
+ <string name="/clap">
+ /æ‹æ‰‹
+ </string>
+ <string name="/count">
+ /計數
+ </string>
+ <string name="/extinguish">
+ /熄è¸
+ </string>
+ <string name="/kmb">
+ /給我一個å»
+ </string>
+ <string name="/muscle">
+ /肌肉
+ </string>
+ <string name="/no">
+ /ä¸
+ </string>
+ <string name="/no!">
+ /ä¸ï¼
+ </string>
+ <string name="/paper">
+ /布
+ </string>
+ <string name="/pointme">
+ /指自己
+ </string>
+ <string name="/pointyou">
+ /指å‘ä½ 
+ </string>
+ <string name="/rock">
+ /石頭
+ </string>
+ <string name="/scissor">
+ /剪刀
+ </string>
+ <string name="/smoke">
+ /抽è¸
+ </string>
+ <string name="/stretch">
+ /伸展
+ </string>
+ <string name="/whistle">
+ /å¹å£å“¨
+ </string>
+ <string name="/yes">
+ /是
+ </string>
+ <string name="/yes!">
+ /是ï¼
+ </string>
+ <string name="afk">
+ 暫時離開
+ </string>
+ <string name="dance1">
+ 跳舞1
+ </string>
+ <string name="dance2">
+ 跳舞2
+ </string>
+ <string name="dance3">
+ 跳舞3
+ </string>
+ <string name="dance4">
+ 跳舞4
+ </string>
+ <string name="dance5">
+ 跳舞5
+ </string>
+ <string name="dance6">
+ 跳舞6
+ </string>
+ <string name="dance7">
+ 跳舞7
+ </string>
+ <string name="dance8">
+ 跳舞8
</string>
<string name="AvatarBirthDateFormat">
[mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt]
@@ -4018,34 +4445,34 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
</string>
<string name="words_separator" value=","/>
<string name="server_is_down">
- Despite our best efforts, something unexpected has gone wrong.
+ 儘管我們努力é¿å…,還是發生æ„料外的錯誤。
- Please check status.secondlifegrid.net to see if there is a known problem with the service.
- If you continue to experience problems, please check your network and firewall setup.
+ 請察訪 status.secondlifegrid.net 看是å¦ç™¼ç”Ÿäº†å·²çŸ¥ç‹€æ³ã€‚
+ 如果文體繼續發生,請檢查你的網路和防ç«ç‰†è¨­å®šã€‚
</string>
<string name="dateTimeWeekdaysNames">
- Sunday:Monday:Tuesday:Wednesday:Thursday:Friday:Saturday
+ 星期日:星期一:星期二:星期三:星期四:星期五:星期六
</string>
<string name="dateTimeWeekdaysShortNames">
- Sun:Mon:Tue:Wed:Thu:Fri:Sat
+ 星期日:星期一:星期二:星期三:星期四:星期五:星期六
</string>
<string name="dateTimeMonthNames">
- January:February:March:April:May:June:July:August:September:October:November:December
+ 一月:二月:三月:四月:五月:六月:七月:八月:ä¹æœˆ:å月:å一月:å二月
</string>
<string name="dateTimeMonthShortNames">
- Jan:Feb:Mar:Apr:May:Jun:Jul:Aug:Sep:Oct:Nov:Dec
+ 一月:二月:三月:四月:五月:六月:七月:八月:ä¹æœˆ:å月:å一月:å二月
</string>
<string name="dateTimeDayFormat">
[MDAY]
</string>
<string name="dateTimeAM">
- AM
+ 上åˆ
</string>
<string name="dateTimePM">
- PM
+ 下åˆ
</string>
<string name="LocalEstimateUSD">
- US$ [AMOUNT]
+ $ [AMOUNT] 美元
</string>
<string name="Membership">
æˆå“¡è³‡æ ¼
@@ -4054,25 +4481,25 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
角色
</string>
<string name="Group Identity">
- Group Identity
+ 群組身份
</string>
<string name="Parcel Management">
地段管ç†
</string>
<string name="Parcel Identity">
- Parcel Identity
+ 地段å
</string>
<string name="Parcel Settings">
地段設定
</string>
<string name="Parcel Powers">
- Parcel Powers
+ 地段權利
</string>
<string name="Parcel Access">
- Parcel Access
+ 地段出入
</string>
<string name="Parcel Content">
- Parcel Content
+ 地段內容
</string>
<string name="Object Management">
物件管ç†
@@ -4090,7 +4517,7 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
刪除所é¸å–的物å“?
</string>
<string name="DeleteItem">
- 刪除所é¸å–的物å“?
+ 刪除所é¸å–的物���?
</string>
<string name="EmptyOutfitText">
沒有任何物å“在這個è£æ‰®å…§
@@ -4099,72 +4526,78 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
é¸æ“‡ä¸€å€‹ç·¨è¼¯å™¨ä½¿ç”¨ ExternalEditor 設定。
</string>
<string name="ExternalEditorNotFound">
- Cannot find the external editor you specified.
-Try enclosing path to the editor with double quotes.
-(e.g. &quot;/path to my/editor&quot; &quot;%s&quot;)
+ 找ä¸åˆ°ä½ æŒ‡å®šçš„外部編輯器。
+請嘗試在編輯器路經å‰å¾ŒåŠ ä¸Šè‹±æ–‡é›™æ‹¬è™Ÿã€‚
+(例:&quot;/path to my/editor&quot; &quot;%s&quot;)
</string>
<string name="ExternalEditorCommandParseError">
- Error parsing the external editor command.
+ 解æžå¤–部編輯器指令時出錯。
</string>
<string name="ExternalEditorFailedToRun">
執行外部編輯器失敗。
</string>
+ <string name="TranslationFailed">
+ 無法翻譯:[REASON]
+ </string>
+ <string name="TranslationResponseParseError">
+ 無法剖æžå¹³ç§»å›žæ‡‰ã€‚
+ </string>
<string name="Esc">
- Esc
+ Esc éµ
</string>
<string name="Space">
- Space
+ 空間éµ
</string>
<string name="Enter">
- Enter
+ Enter éµ
</string>
<string name="Tab">
- Tab
+ Tab éµ
</string>
<string name="Ins">
- Ins
+ Ins éµ
</string>
<string name="Del">
- Del
+ Del éµ
</string>
<string name="Backsp">
- Backsp
+ Backspace éµ
</string>
<string name="Shift">
- Shift
+ Shift éµ
</string>
<string name="Ctrl">
- Ctrl
+ Ctrl éµ
</string>
<string name="Alt">
- Alt
+ Alt éµ
</string>
<string name="CapsLock">
- CapsLock
+ CapsLock éµ
</string>
<string name="Left">
- Left
+ 左移éµ
</string>
<string name="Right">
- Right
+ å³ç§»éµ
</string>
<string name="Up">
- Up
+ 上移éµ
</string>
<string name="Down">
- Down
+ 下移éµ
</string>
<string name="Home">
- Home
+ Home éµ
</string>
<string name="End">
- End
+ End éµ
</string>
<string name="PgUp">
- PgUp
+ PgUp éµ
</string>
<string name="PgDn">
- PgDn
+ PgDn éµ
</string>
<string name="F1">
F1
@@ -4203,16 +4636,16 @@ Try enclosing path to the editor with double quotes.
F12
</string>
<string name="Add">
- Add
+ 添加
</string>
<string name="Subtract">
- Subtract
+ 減
</string>
<string name="Multiply">
- Multiply
+ 乘
</string>
<string name="Divide">
- Divide
+ 除
</string>
<string name="PAD_DIVIDE">
PAD_DIVIDE
@@ -4392,7 +4825,7 @@ Try enclosing path to the editor with double quotes.
M
</string>
<string name="N">
- N
+ 北
</string>
<string name="O">
O
@@ -4407,7 +4840,7 @@ Try enclosing path to the editor with double quotes.
R
</string>
<string name="S">
- S
+ å—
</string>
<string name="T">
T
@@ -4419,7 +4852,7 @@ Try enclosing path to the editor with double quotes.
V
</string>
<string name="W">
- W
+ 西
</string>
<string name="X">
X
@@ -4431,24 +4864,261 @@ Try enclosing path to the editor with double quotes.
Z
</string>
<string name="BeaconParticle">
- Viewing particle beacons (blue)
+ 檢視粒å­æ•ˆæžœçš„導引(è—色)
</string>
<string name="BeaconPhysical">
- Viewing physical object beacons (green)
+ 檢視具體物件的導引(綠色)
</string>
<string name="BeaconScripted">
- Viewing scripted object beacons (red)
+ 檢視腳本物件的導引(紅色)
</string>
<string name="BeaconScriptedTouch">
- Viewing scripted object with touch function beacons (red)
+ 檢視帶有觸摸函å¼è…³æœ¬ç‰©ä»¶çš„導引(紅色)
</string>
<string name="BeaconSound">
- Viewing sound beacons (yellow)
+ 檢視è²éŸ³çš„導引(黃色)
</string>
<string name="BeaconMedia">
- Viewing media beacons (white)
+ 檢視媒體的導引(白色)
</string>
<string name="ParticleHiding">
- Hiding Particles
+ éš±è—ç²’å­æ•ˆæžœ
+ </string>
+ <string name="Command_AboutLand_Label">
+ 土地資料
+ </string>
+ <string name="Command_Appearance_Label">
+ 編輯外觀
+ </string>
+ <string name="Command_Avatar_Label">
+ 化身
+ </string>
+ <string name="Command_Build_Label">
+ 建造
+ </string>
+ <string name="Command_Chat_Label">
+ èŠå¤©
+ </string>
+ <string name="Command_Conversations_Label">
+ 交談
+ </string>
+ <string name="Command_Compass_Label">
+ 羅盤
+ </string>
+ <string name="Command_Destinations_Label">
+ 目的地
+ </string>
+ <string name="Command_Gestures_Label">
+ 姿勢
+ </string>
+ <string name="Command_HowTo_Label">
+ 簡易教學
+ </string>
+ <string name="Command_Inventory_Label">
+ 收ç´å€
+ </string>
+ <string name="Command_Map_Label">
+ 地圖
+ </string>
+ <string name="Command_Marketplace_Label">
+ 第二人生購物市集
+ </string>
+ <string name="Command_MiniMap_Label">
+ 迷你地圖
+ </string>
+ <string name="Command_Move_Label">
+ 行走 / 跑步 / 飛行
+ </string>
+ <string name="Command_Outbox_Label">
+ 商家發件匣
+ </string>
+ <string name="Command_People_Label">
+ 人群
+ </string>
+ <string name="Command_Picks_Label">
+ ç²¾é¸åœ°é»ž
+ </string>
+ <string name="Command_Places_Label">
+ 地點
+ </string>
+ <string name="Command_Preferences_Label">
+ å好設定
+ </string>
+ <string name="Command_Profile_Label">
+ 檔案
+ </string>
+ <string name="Command_Search_Label">
+ æœå°‹
+ </string>
+ <string name="Command_Snapshot_Label">
+ å¿«ç…§
+ </string>
+ <string name="Command_Speak_Label">
+ 說話
+ </string>
+ <string name="Command_View_Label">
+ æ”影機控制
+ </string>
+ <string name="Command_Voice_Label">
+ 語音設定
+ </string>
+ <string name="Command_AboutLand_Tooltip">
+ 有關你所處土地的資訊
+ </string>
+ <string name="Command_Appearance_Tooltip">
+ 改變化身
+ </string>
+ <string name="Command_Avatar_Tooltip">
+ é¸æ“‡ä¸€å€‹å®Œæ•´çš„化身
+ </string>
+ <string name="Command_Build_Tooltip">
+ 建製物件和é‡å¡‘地形
+ </string>
+ <string name="Command_Chat_Tooltip">
+ é€éŽæ–‡å­—和附近人們èŠå¤©
+ </string>
+ <string name="Command_Conversations_Tooltip">
+ 和所有人交談
+ </string>
+ <string name="Command_Compass_Tooltip">
+ 指å—é‡
+ </string>
+ <string name="Command_Destinations_Tooltip">
+ ä½ å¯èƒ½æ„Ÿèˆˆè¶£çš„目的地
+ </string>
+ <string name="Command_Gestures_Tooltip">
+ 你化身å¯ç”¨çš„姿勢
+ </string>
+ <string name="Command_HowTo_Tooltip">
+ 如何完æˆå¸¸ç”¨çš„動作
+ </string>
+ <string name="Command_Inventory_Tooltip">
+ 察看並使用你æ“有的物件
+ </string>
+ <string name="Command_Map_Tooltip">
+ 世界地圖
+ </string>
+ <string name="Command_Marketplace_Tooltip">
+ å‰å¾€è³¼ç‰©
+ </string>
+ <string name="Command_MiniMap_Tooltip">
+ 顯示附近的人
+ </string>
+ <string name="Command_Move_Tooltip">
+ 移動化身
+ </string>
+ <string name="Command_Outbox_Tooltip">
+ 將物項轉移到第二人生購物市集待售
+ </string>
+ <string name="Command_People_Tooltip">
+ 朋å‹ã€ç¾¤çµ„和附近的人
+ </string>
+ <string name="Command_Picks_Tooltip">
+ 顯示在你的å°æª”案中的最愛地點
+ </string>
+ <string name="Command_Places_Tooltip">
+ 你儲存的地點
+ </string>
+ <string name="Command_Preferences_Tooltip">
+ å好設定
+ </string>
+ <string name="Command_Profile_Tooltip">
+ 編輯或察看你的å°æª”案
+ </string>
+ <string name="Command_Search_Tooltip">
+ 尋找地點ã€æ´»å‹•ã€å…¶ä»–人
+ </string>
+ <string name="Command_Snapshot_Tooltip">
+ æ‹ä¸€å¼µç…§ç‰‡
+ </string>
+ <string name="Command_Speak_Tooltip">
+ 用麥克風和附近人們交談
+ </string>
+ <string name="Command_View_Tooltip">
+ 調整æ”影機角度
+ </string>
+ <string name="Command_Voice_Tooltip">
+ 在虛擬世界裡通話和附近人群的音é‡æŽ§åˆ¶
+ </string>
+ <string name="Toolbar_Bottom_Tooltip">
+ ç›®å‰ä½åœ¨ä½ çš„底部工具列
+ </string>
+ <string name="Toolbar_Left_Tooltip">
+ ç›®å‰ä½åœ¨ä½ çš„左工具列
+ </string>
+ <string name="Toolbar_Right_Tooltip">
+ ç›®å‰ä½åœ¨ä½ çš„å³å·¥å…·åˆ—
+ </string>
+ <string name="Retain%">
+ ä¿ç•™%
+ </string>
+ <string name="Detail">
+ 細節
+ </string>
+ <string name="Better Detail">
+ 更多細節
+ </string>
+ <string name="Surface">
+ 表é¢
+ </string>
+ <string name="Solid">
+ 固體
+ </string>
+ <string name="Wrap">
+ Wrap
+ </string>
+ <string name="Preview">
+ é è¦½
+ </string>
+ <string name="Normal">
+ 正常
+ </string>
+ <string name="Pathfinding_Wiki_URL">
+ http://wiki.secondlife.com/wiki/Pathfinding_Tools_in_the_Second_Life_Viewer
+ </string>
+ <string name="Pathfinding_Object_Attr_None">
+ ç„¡
+ </string>
+ <string name="Pathfinding_Object_Attr_Permanent">
+ 影響導航網é¢
+ </string>
+ <string name="Pathfinding_Object_Attr_Character">
+ 角色
+ </string>
+ <string name="Pathfinding_Object_Attr_MultiSelect">
+ (多項)
+ </string>
+ <string name="snapshot_quality_very_low">
+ 很低
+ </string>
+ <string name="snapshot_quality_low">
+ 低
+ </string>
+ <string name="snapshot_quality_medium">
+ 中
+ </string>
+ <string name="snapshot_quality_high">
+ 高
+ </string>
+ <string name="snapshot_quality_very_high">
+ 很高
+ </string>
+ <string name="TeleportMaturityExceeded">
+ 此居民ä¸å¾—進入此地å€ã€‚
+ </string>
+ <string name="UserDictionary">
+ [User]
+ </string>
+ <string name="logging_calls_disabled_log_empty">
+ 交談未留記錄。 若想開始留記錄,請到「å好設定 &gt; èŠå¤©ã€ï¼Œé¸æ“‡ã€Œå„²å­˜ï¼šåªç•™æ­·å²è¨˜éŒ„ã€æˆ–「儲存:歷å²è¨˜éŒ„兼交談內容ã€ã€‚
+ </string>
+ <string name="logging_calls_disabled_log_not_empty">
+ å°‡ä¸å†ç‚ºäº¤è«‡ç•™è¨˜éŒ„。 若想æ¢å¾©ç•™å­˜è¨˜éŒ„,請到「å好設定 &gt; èŠå¤©ã€ï¼Œé¸æ“‡ã€Œå„²å­˜ï¼šåªç•™æ­·å²è¨˜éŒ„ã€æˆ–「儲存:歷å²è¨˜éŒ„兼交談內容ã€ã€‚
+ </string>
+ <string name="logging_calls_enabled_log_empty">
+ ç›®å‰æ²’有交談記錄。 在你è¯çµ¡æŸäººæˆ–æŸäººè¯çµ¡ä½ ä¹‹å¾Œï¼Œé€™è£¡å°‡ç•™å­˜è¨˜éŒ„。
+ </string>
+ <string name="loading_chat_logs">
+ 載入中…
</string>
</strings>
diff --git a/indra/newview/skins/default/xui/zh/teleport_strings.xml b/indra/newview/skins/default/xui/zh/teleport_strings.xml
index bfdb107810..37080a8d0c 100644..100755
--- a/indra/newview/skins/default/xui/zh/teleport_strings.xml
+++ b/indra/newview/skins/default/xui/zh/teleport_strings.xml
@@ -2,15 +2,15 @@
<teleport_messages>
<message_set name="errors">
<message name="invalid_tport">
- Problem encountered processing your teleport request. You may need to log back in before you can teleport.
+ 處ç†ä½ çž¬é–“傳é€è¦æ±‚時發生å•é¡Œã€‚ 如果想è¦çž¬é–“傳é€ï¼Œä½ å¯èƒ½éœ€è¦é‡æ–°ç™»å…¥ã€‚
如果你æŒçºŒå¾—到此訊æ¯ï¼Œè«‹æŸ¥é–± [SUPPORT_SITE]。
</message>
<message name="invalid_region_handoff">
- Problem encountered processing your region crossing. You may need to log back in before you can cross regions.
+ 處ç†ä½ è·¨è¶Šåœ°å€å‹•ä½œæ™‚發生å•é¡Œã€‚ 如果想è¦è·¨è¶Šåœ°å€ï¼Œä½ å¯èƒ½éœ€è¦é‡æ–°ç™»å…¥ã€‚
如果你æŒçºŒå¾—到此訊æ¯ï¼Œè«‹æŸ¥é–± [SUPPORT_SITE]。
</message>
<message name="blocked_tport">
- 抱歉,目å‰çž¬é–“傳é€å·²è¢«é˜»æ“‹ã€‚è«‹ç¨å¾Œå†è©¦ã€‚
+ 抱歉,目å‰ç¦æ­¢çž¬é–“傳é€ã€‚ è«‹ç¨å¾Œå†è©¦ã€‚
如果你ä»ç„¡æ³•é€²è¡Œçž¬é–“傳é€ï¼Œè«‹ç™»å‡ºå¾Œé‡æ–°å…¥ä¾†è§£æ±ºæ­¤ä¸€å•é¡Œã€‚
</message>
<message name="nolandmark_tport">
@@ -21,40 +21,43 @@
è«‹ç¨å¾Œå†è©¦ã€‚
</message>
<message name="NoHelpIslandTP">
- 您ä¸èƒ½çž¬é—´è½¬ç§»å›žâ€œæ´åŠ©å²›â€ã€‚
-去“公共æ´åŠ©å²›â€é‡å¤æ‚¨çš„教程。
+ 你無法瞬間傳é€å›žã€Œæ–°æ‰‹å°Žå¼•å³¶ã€ã€‚
+請到「大眾新手導引島ã€é‡æ–°åƒåŠ å°Žå¼•æ•™å­¸ã€‚
</message>
<message name="noaccess_tport">
抱歉,你並沒有權é™é€²å…¥è¦çž¬é–“傳é€çš„目的地。
</message>
<message name="missing_attach_tport">
- Your attachments have not arrived yet. Try waiting for a few more seconds or log out and back in again before attempting to teleport.
+ 你的附件尚未抵é”。 è«‹ç¨å€™ä¸€æœƒå…’,或請登出後é‡æ–°ç™»å…¥ï¼Œå†å˜—試瞬間傳é€ã€‚
</message>
<message name="too_many_uploads_tport">
- The asset queue in this region is currently clogged so your teleport request will not be able to succeed in a timely manner. Please try again in a few minutes or go to a less busy area.
+ 該地å€çš„資產查詢目å‰å¤ªéŽæ“塞,因此你的瞬間傳é€å‹•ä½œå¯èƒ½ç„¡æ³•å³æ™‚發生。 è«‹ç¨å€™å†è©¦ï¼Œæˆ–è«‹å‰å¾€è¼ƒä¸æ“塞的地å€ã€‚
</message>
<message name="expired_tport">
- Sorry, but the system was unable to complete your teleport request in a timely fashion. Please try again in a few minutes.
+ 抱歉,系統無法å³æ™‚完æˆç‚ºä½ çž¬é–“傳é€ã€‚ è«‹ç¨å¾…幾分é˜å†è©¦ã€‚
</message>
<message name="expired_region_handoff">
- Sorry, but the system was unable to complete your region crossing in a timely fashion. Please try again in a few minutes.
+ 抱歉,系統無法å³æ™‚讓你跨越地å€ã€‚ è«‹ç¨å¾…幾分é˜å†è©¦ã€‚
</message>
<message name="no_host">
- Unable to find teleport destination. The destination may be temporarily unavailable or no longer exists. Please try again in a few minutes.
+ 找ä¸åˆ°çž¬é–“傳é€çš„目的地。 目的地å¯èƒ½æš«æ™‚ä¸å¯ç”¨ï¼Œæˆ–å·²ä¸å­˜åœ¨ã€‚ è«‹ç¨å¾…幾分é˜å†è©¦ã€‚
</message>
<message name="no_inventory_host">
收ç´å€åŠŸèƒ½ç›®å‰ç„¡æ³•ä½¿ç”¨ã€‚
</message>
+ <message name="MustGetAgeRegion">
+ 你必須年滿 18 æ­²æ‰å¯é€²å…¥é€™åœ°å€ã€‚
+ </message>
</message_set>
<message_set name="progress">
<message name="sending_dest">
- Sending to destination.
+ é€å¾€ç›®çš„地。
</message>
<message name="redirecting">
é‡æ–°å°Žå‘至ä¸åŒä½ç½®ã€‚
</message>
<message name="relaying">
- Relaying to destination.
+ 接繼é€å¾€ç›®çš„地。
</message>
<message name="sending_home">
é€å‡ºå®¶ä½ç½®çš„è¦æ±‚。
@@ -80,5 +83,8 @@
<message name="requesting">
瞬間傳é€è¦æ±‚中...
</message>
+ <message name="pending">
+ 等待瞬間傳é€â€¦
+ </message>
</message_set>
</teleport_messages>
diff --git a/indra/newview/skins/paths.xml b/indra/newview/skins/paths.xml
deleted file mode 100644
index 3c0da041c7..0000000000
--- a/indra/newview/skins/paths.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-<paths>
- <directory>
- <subdir>xui</subdir>
- <subdir>en</subdir>
- </directory>
- <directory>
- <subdir>xui</subdir>
- <subdir>[LANGUAGE]</subdir>
- </directory>
-</paths> \ No newline at end of file
diff --git a/indra/newview/tests/gpus_results.txt b/indra/newview/tests/gpus_results.txt
index 68e2e688cb..68e2e688cb 100644..100755
--- a/indra/newview/tests/gpus_results.txt
+++ b/indra/newview/tests/gpus_results.txt
diff --git a/indra/newview/tests/gpus_seen.txt b/indra/newview/tests/gpus_seen.txt
index 570f92a9b0..570f92a9b0 100644..100755
--- a/indra/newview/tests/gpus_seen.txt
+++ b/indra/newview/tests/gpus_seen.txt
diff --git a/indra/newview/tests/llagentaccess_test.cpp b/indra/newview/tests/llagentaccess_test.cpp
index c970d79975..45ce1ba62f 100644..100755
--- a/indra/newview/tests/llagentaccess_test.cpp
+++ b/indra/newview/tests/llagentaccess_test.cpp
@@ -40,7 +40,7 @@
static U32 test_preferred_maturity = SIM_ACCESS_PG;
LLControlGroup::LLControlGroup(const std::string& name)
- : LLInstanceTracker<LLControlGroup, std::string>(name)
+: LLInstanceTracker<LLControlGroup, std::string>(name)
{
}
@@ -49,10 +49,10 @@ LLControlGroup::~LLControlGroup()
}
// Implementation of just the LLControlGroup methods we requre
-BOOL LLControlGroup::declareU32(const std::string& name, U32 initial_val, const std::string& comment, BOOL persist)
+LLControlVariable* LLControlGroup::declareU32(const std::string& name, U32 initial_val, const std::string& comment, LLControlVariable::ePersist persist)
{
test_preferred_maturity = initial_val;
- return true;
+ return NULL;
}
void LLControlGroup::setU32(const std::string& name, U32 val)
@@ -80,72 +80,76 @@ namespace tut
void agentaccess_object_t::test<1>()
{
LLControlGroup cgr("test");
- cgr.declareU32("PreferredMaturity", SIM_ACCESS_PG, "declared_for_test", FALSE);
+ cgr.declareU32("PreferredMaturity", SIM_ACCESS_PG, "declared_for_test", LLControlVariable::PERSIST_NO);
LLAgentAccess aa(cgr);
cgr.setU32("PreferredMaturity", SIM_ACCESS_PG);
+#ifndef HACKED_GODLIKE_VIEWER
ensure("1 prefersPG", aa.prefersPG());
ensure("1 prefersMature", !aa.prefersMature());
ensure("1 prefersAdult", !aa.prefersAdult());
+#endif // HACKED_GODLIKE_VIEWER
cgr.setU32("PreferredMaturity", SIM_ACCESS_MATURE);
+#ifndef HACKED_GODLIKE_VIEWER
ensure("2 prefersPG", !aa.prefersPG());
ensure("2 prefersMature", aa.prefersMature());
ensure("2 prefersAdult", !aa.prefersAdult());
+#endif // HACKED_GODLIKE_VIEWER
cgr.setU32("PreferredMaturity", SIM_ACCESS_ADULT);
+#ifndef HACKED_GODLIKE_VIEWER
ensure("3 prefersPG", !aa.prefersPG());
ensure("3 prefersMature", aa.prefersMature());
ensure("3 prefersAdult", aa.prefersAdult());
+#endif // HACKED_GODLIKE_VIEWER
}
template<> template<>
void agentaccess_object_t::test<2>()
{
LLControlGroup cgr("test");
- cgr.declareU32("PreferredMaturity", SIM_ACCESS_PG, "declared_for_test", FALSE);
+ cgr.declareU32("PreferredMaturity", SIM_ACCESS_PG, "declared_for_test", LLControlVariable::PERSIST_NO);
LLAgentAccess aa(cgr);
// make sure default is PG
+#ifndef HACKED_GODLIKE_VIEWER
ensure("1 isTeen", aa.isTeen());
ensure("1 isMature", !aa.isMature());
ensure("1 isAdult", !aa.isAdult());
+#endif // HACKED_GODLIKE_VIEWER
- // this is kinda bad -- setting this forces maturity to MATURE but !teen != Mature anymore
- aa.setTeen(false);
- ensure("2 isTeen", !aa.isTeen());
- ensure("2 isMature", aa.isMature());
- ensure("2 isAdult", !aa.isAdult());
-
- // have to flip it back and make sure it still works
- aa.setTeen(true);
- ensure("3 isTeen", aa.isTeen());
- ensure("3 isMature", !aa.isMature());
- ensure("3 isAdult", !aa.isAdult());
-
// check the conversion routine
+#ifndef HACKED_GODLIKE_VIEWER
ensure_equals("1 conversion", SIM_ACCESS_PG, aa.convertTextToMaturity('P'));
ensure_equals("2 conversion", SIM_ACCESS_MATURE, aa.convertTextToMaturity('M'));
ensure_equals("3 conversion", SIM_ACCESS_ADULT, aa.convertTextToMaturity('A'));
ensure_equals("4 conversion", SIM_ACCESS_MIN, aa.convertTextToMaturity('Q'));
+#endif // HACKED_GODLIKE_VIEWER
// now try the other method of setting it - PG
aa.setMaturity('P');
- ensure("4 isTeen", aa.isTeen());
- ensure("4 isMature", !aa.isMature());
- ensure("4 isAdult", !aa.isAdult());
+ ensure("2 isTeen", aa.isTeen());
+#ifndef HACKED_GODLIKE_VIEWER
+ ensure("2 isMature", !aa.isMature());
+ ensure("2 isAdult", !aa.isAdult());
+#endif // HACKED_GODLIKE_VIEWER
// Mature
aa.setMaturity('M');
- ensure("5 isTeen", !aa.isTeen());
- ensure("5 isMature", aa.isMature());
- ensure("5 isAdult", !aa.isAdult());
+#ifndef HACKED_GODLIKE_VIEWER
+ ensure("3 isTeen", !aa.isTeen());
+ ensure("3 isMature", aa.isMature());
+ ensure("3 isAdult", !aa.isAdult());
+#endif // HACKED_GODLIKE_VIEWER
// Adult
aa.setMaturity('A');
- ensure("6 isTeen", !aa.isTeen());
- ensure("6 isMature", aa.isMature());
- ensure("6 isAdult", aa.isAdult());
+#ifndef HACKED_GODLIKE_VIEWER
+ ensure("4 isTeen", !aa.isTeen());
+ ensure("4 isMature", aa.isMature());
+ ensure("4 isAdult", aa.isAdult());
+#endif // HACKED_GODLIKE_VIEWER
}
@@ -153,82 +157,114 @@ namespace tut
void agentaccess_object_t::test<3>()
{
LLControlGroup cgr("test");
- cgr.declareU32("PreferredMaturity", SIM_ACCESS_PG, "declared_for_test", FALSE);
+ cgr.declareU32("PreferredMaturity", SIM_ACCESS_PG, "declared_for_test", LLControlVariable::PERSIST_NO);
LLAgentAccess aa(cgr);
+#ifndef HACKED_GODLIKE_VIEWER
ensure("starts normal", !aa.isGodlike());
+#endif // HACKED_GODLIKE_VIEWER
aa.setGodLevel(GOD_NOT);
+#ifndef HACKED_GODLIKE_VIEWER
ensure("stays normal", !aa.isGodlike());
+#endif // HACKED_GODLIKE_VIEWER
aa.setGodLevel(GOD_FULL);
+#ifndef HACKED_GODLIKE_VIEWER
ensure("sets full", aa.isGodlike());
+#endif // HACKED_GODLIKE_VIEWER
aa.setGodLevel(GOD_NOT);
+#ifndef HACKED_GODLIKE_VIEWER
ensure("resets normal", !aa.isGodlike());
+#endif // HACKED_GODLIKE_VIEWER
aa.setAdminOverride(true);
+#ifndef HACKED_GODLIKE_VIEWER
ensure("admin true", aa.getAdminOverride());
ensure("overrides 1", aa.isGodlike());
+#endif // HACKED_GODLIKE_VIEWER
aa.setGodLevel(GOD_FULL);
+#ifndef HACKED_GODLIKE_VIEWER
ensure("overrides 2", aa.isGodlike());
+#endif // HACKED_GODLIKE_VIEWER
aa.setAdminOverride(false);
+#ifndef HACKED_GODLIKE_VIEWER
ensure("admin false", !aa.getAdminOverride());
ensure("overrides 3", aa.isGodlike());
+#endif // HACKED_GODLIKE_VIEWER
}
template<> template<>
void agentaccess_object_t::test<4>()
{
LLControlGroup cgr("test");
- cgr.declareU32("PreferredMaturity", SIM_ACCESS_PG, "declared_for_test", FALSE);
+ cgr.declareU32("PreferredMaturity", SIM_ACCESS_PG, "declared_for_test", LLControlVariable::PERSIST_NO);
LLAgentAccess aa(cgr);
+#ifndef HACKED_GODLIKE_VIEWER
ensure("1 pg to start", aa.wantsPGOnly());
ensure("2 pg to start", !aa.canAccessMature());
ensure("3 pg to start", !aa.canAccessAdult());
+#endif // HACKED_GODLIKE_VIEWER
aa.setGodLevel(GOD_FULL);
+#ifndef HACKED_GODLIKE_VIEWER
ensure("1 full god", !aa.wantsPGOnly());
ensure("2 full god", aa.canAccessMature());
ensure("3 full god", aa.canAccessAdult());
+#endif // HACKED_GODLIKE_VIEWER
aa.setGodLevel(GOD_NOT);
aa.setAdminOverride(true);
+#ifndef HACKED_GODLIKE_VIEWER
ensure("1 admin mode", !aa.wantsPGOnly());
ensure("2 admin mode", aa.canAccessMature());
ensure("3 admin mode", aa.canAccessAdult());
+#endif // HACKED_GODLIKE_VIEWER
aa.setAdminOverride(false);
aa.setMaturity('M');
// preferred is still pg by default
+#ifndef HACKED_GODLIKE_VIEWER
ensure("1 mature pref pg", aa.wantsPGOnly());
ensure("2 mature pref pg", !aa.canAccessMature());
ensure("3 mature pref pg", !aa.canAccessAdult());
+#endif // HACKED_GODLIKE_VIEWER
cgr.setU32("PreferredMaturity", SIM_ACCESS_MATURE);
+#ifndef HACKED_GODLIKE_VIEWER
ensure("1 mature", !aa.wantsPGOnly());
ensure("2 mature", aa.canAccessMature());
ensure("3 mature", !aa.canAccessAdult());
+#endif // HACKED_GODLIKE_VIEWER
cgr.setU32("PreferredMaturity", SIM_ACCESS_PG);
+#ifndef HACKED_GODLIKE_VIEWER
ensure("1 mature pref pg", aa.wantsPGOnly());
ensure("2 mature pref pg", !aa.canAccessMature());
ensure("3 mature pref pg", !aa.canAccessAdult());
+#endif // HACKED_GODLIKE_VIEWER
aa.setMaturity('A');
+#ifndef HACKED_GODLIKE_VIEWER
ensure("1 adult pref pg", aa.wantsPGOnly());
ensure("2 adult pref pg", !aa.canAccessMature());
ensure("3 adult pref pg", !aa.canAccessAdult());
+#endif // HACKED_GODLIKE_VIEWER
cgr.setU32("PreferredMaturity", SIM_ACCESS_ADULT);
+#ifndef HACKED_GODLIKE_VIEWER
ensure("1 adult", !aa.wantsPGOnly());
ensure("2 adult", aa.canAccessMature());
ensure("3 adult", aa.canAccessAdult());
+#endif // HACKED_GODLIKE_VIEWER
// make sure that even if pref is high, if access is low we block access
// this shouldn't occur in real life but we want to be safe
cgr.setU32("PreferredMaturity", SIM_ACCESS_ADULT);
aa.setMaturity('P');
+#ifndef HACKED_GODLIKE_VIEWER
ensure("1 pref adult, actual pg", aa.wantsPGOnly());
ensure("2 pref adult, actual pg", !aa.canAccessMature());
ensure("3 pref adult, actual pg", !aa.canAccessAdult());
+#endif // HACKED_GODLIKE_VIEWER
}
@@ -236,27 +272,19 @@ namespace tut
void agentaccess_object_t::test<5>()
{
LLControlGroup cgr("test");
- cgr.declareU32("PreferredMaturity", SIM_ACCESS_PG, "declared_for_test", FALSE);
- LLAgentAccess aa(cgr);
-
- ensure("1 transition starts false", !aa.isInTransition());
- aa.setTransition();
- ensure("2 transition now true", aa.isInTransition());
- }
-
- template<> template<>
- void agentaccess_object_t::test<6>()
- {
- LLControlGroup cgr("test");
- cgr.declareU32("PreferredMaturity", SIM_ACCESS_PG, "declared_for_test", FALSE);
+ cgr.declareU32("PreferredMaturity", SIM_ACCESS_PG, "declared_for_test", LLControlVariable::PERSIST_NO);
LLAgentAccess aa(cgr);
cgr.setU32("PreferredMaturity", SIM_ACCESS_ADULT);
aa.setMaturity('M');
+#ifndef HACKED_GODLIKE_VIEWER
ensure("1 preferred maturity pegged to M when maturity is M", cgr.getU32("PreferredMaturity") == SIM_ACCESS_MATURE);
+#endif // HACKED_GODLIKE_VIEWER
aa.setMaturity('P');
+#ifndef HACKED_GODLIKE_VIEWER
ensure("1 preferred maturity pegged to P when maturity is P", cgr.getU32("PreferredMaturity") == SIM_ACCESS_PG);
+#endif // HACKED_GODLIKE_VIEWER
}
}
diff --git a/indra/newview/tests/llcapabilitylistener_test.cpp b/indra/newview/tests/llcapabilitylistener_test.cpp
index e1cbd28f92..e1cbd28f92 100644..100755
--- a/indra/newview/tests/llcapabilitylistener_test.cpp
+++ b/indra/newview/tests/llcapabilitylistener_test.cpp
diff --git a/indra/newview/tests/lldateutil_test.cpp b/indra/newview/tests/lldateutil_test.cpp
index 47353962e1..47353962e1 100644..100755
--- a/indra/newview/tests/lldateutil_test.cpp
+++ b/indra/newview/tests/lldateutil_test.cpp
diff --git a/indra/newview/tests/lldir_stub.cpp b/indra/newview/tests/lldir_stub.cpp
index 18cf4e7419..2bc6772d86 100644..100755
--- a/indra/newview/tests/lldir_stub.cpp
+++ b/indra/newview/tests/lldir_stub.cpp
@@ -32,7 +32,7 @@ BOOL LLDir::deleteFilesInDir(const std::string &dirname, const std::string &mask
void LLDir::setChatLogsDir(const std::string &path) {}
void LLDir::setPerAccountChatLogsDir(const std::string &first, const std::string &last) {}
void LLDir::setLindenUserDir(const std::string &first, const std::string &last) {}
-void LLDir::setSkinFolder(const std::string &skin_folder) {}
+void LLDir::setSkinFolder(const std::string &skin_folder, const std::string& language) {}
bool LLDir::setCacheDir(const std::string &path) { return true; }
void LLDir::dumpCurrentDirectories() {}
@@ -48,7 +48,7 @@ public:
/*virtual*/ U32 countFilesInDir(const std::string &dirname, const std::string &mask) { return 42; }
/*virtual*/ BOOL getNextFileInDir(const std::string &dirname, const std::string &mask, std::string &fname, BOOL wrap) { fname = fname + "_NEXT"; return false; }
/*virtual*/ void getRandomFileInDir(const std::string &dirname, const std::string &mask, std::string &fname) { fname = "RANDOM_FILE"; }
- /*virtual*/ BOOL fileExists(const std::string &filename) const { return false; }
+ /*virtual*/ bool fileExists(const std::string &filename) const { return false; }
};
LLDir_stub gDirUtil;
diff --git a/indra/newview/tests/llglslshader_stub.cpp b/indra/newview/tests/llglslshader_stub.cpp
index 8947a632c8..8947a632c8 100644..100755
--- a/indra/newview/tests/llglslshader_stub.cpp
+++ b/indra/newview/tests/llglslshader_stub.cpp
diff --git a/indra/newview/tests/lllogininstance_test.cpp b/indra/newview/tests/lllogininstance_test.cpp
index 9e321db889..adeb848e03 100644..100755
--- a/indra/newview/tests/lllogininstance_test.cpp
+++ b/indra/newview/tests/lllogininstance_test.cpp
@@ -50,7 +50,7 @@ const std::string VIEWERLOGIN_GRIDLABEL("viewerlogin_grid");
const std::string APPVIEWER_SERIALNUMBER("appviewer_serialno");
const std::string VIEWERLOGIN_CHANNEL("invalid_channel");
-const std::string VIEWERLOGIN_VERSION_CHANNEL("invalid_version");
+const std::string VIEWERLOGIN_VERSION("invalid_version");
// Link seams.
@@ -60,6 +60,7 @@ static LLEventStream gTestPump("test_pump");
#include "../llslurl.h"
#include "../llstartup.h"
LLSLURL LLStartUp::sStartSLURL;
+LLSLURL& LLStartUp::getStartSLURL() { return sStartSLURL; }
#include "lllogin.h"
@@ -72,7 +73,7 @@ void LLViewerWindow::setShowProgress(BOOL show) {}
LLProgressView * LLViewerWindow::getProgressView(void) const { return 0; }
LLViewerWindow* gViewerWindow;
-
+
class LLLogin::Impl
{
};
@@ -114,8 +115,9 @@ LLGridManager::~LLGridManager()
{
}
-void LLGridManager::addGrid(LLSD& grid_data)
+bool LLGridManager::addGrid(LLSD& grid_data)
{
+ return true;
}
LLGridManager::LLGridManager()
:
@@ -133,10 +135,11 @@ void LLGridManager::addSystemGrid(const std::string& label,
const std::string& login,
const std::string& helper,
const std::string& login_page,
+ const std::string& update_url_base,
const std::string& login_id)
{
}
-std::map<std::string, std::string> LLGridManager::getKnownGrids(bool favorite_only)
+std::map<std::string, std::string> LLGridManager::getKnownGrids()
{
std::map<std::string, std::string> result;
return result;
@@ -151,8 +154,6 @@ bool LLGridManager::isInProductionGrid()
return false;
}
-void LLGridManager::saveFavorites()
-{}
std::string LLGridManager::getSLURLBase(const std::string& grid_name)
{
return "myslurl";
@@ -175,15 +176,15 @@ F32 LLControlGroup::getF32(const std::string& name) { return 0.0f; }
U32 LLControlGroup::saveToFile(const std::string& filename, BOOL nondefault_only) { return 1; }
void LLControlGroup::setString(const std::string& name, const std::string& val) {}
std::string LLControlGroup::getString(const std::string& name) { return "test_string"; }
-BOOL LLControlGroup::declareBOOL(const std::string& name, BOOL initial_val, const std::string& comment, BOOL persist) { return TRUE; }
-BOOL LLControlGroup::declareString(const std::string& name, const std::string &initial_val, const std::string& comment, BOOL persist) { return TRUE; }
+LLControlVariable* LLControlGroup::declareBOOL(const std::string& name, BOOL initial_val, const std::string& comment, LLControlVariable::ePersist persist) { return NULL; }
+LLControlVariable* LLControlGroup::declareString(const std::string& name, const std::string &initial_val, const std::string& comment, LLControlVariable::ePersist persist) { return NULL; }
#include "lluicolortable.h"
void LLUIColorTable::saveUserSettings(void)const {}
//-----------------------------------------------------------------------------
#include "../llversioninfo.h"
-const std::string &LLVersionInfo::getChannelAndVersion() { return VIEWERLOGIN_VERSION_CHANNEL; }
+const std::string &LLVersionInfo::getVersion() { return VIEWERLOGIN_VERSION; }
const std::string &LLVersionInfo::getChannel() { return VIEWERLOGIN_CHANNEL; }
//-----------------------------------------------------------------------------
@@ -208,11 +209,13 @@ std::string const & LLUpdaterService::pumpName(void)
return wakka;
}
bool LLUpdaterService::updateReadyToInstall(void) { return false; }
-void LLUpdaterService::initialize(const std::string& protocol_version,
- const std::string& url,
- const std::string& path,
- const std::string& channel,
- const std::string& version) {}
+void LLUpdaterService::initialize(const std::string& channel,
+ const std::string& version,
+ const std::string& platform,
+ const std::string& platform_version,
+ const unsigned char uniqueid[MD5HEX_STR_SIZE],
+ const bool& willing_to_test
+ ) {}
void LLUpdaterService::setCheckPeriod(unsigned int seconds) {}
void LLUpdaterService::startChecking(bool install_if_ready) {}
@@ -221,6 +224,12 @@ bool LLUpdaterService::isChecking() { return false; }
LLUpdaterService::eUpdaterState LLUpdaterService::getState() { return INITIAL; }
std::string LLUpdaterService::updatedVersion() { return ""; }
+bool llHashedUniqueID(unsigned char* id)
+{
+ memcpy( id, "66666666666666666666666666666666", MD5HEX_STR_SIZE );
+ return true;
+}
+
//-----------------------------------------------------------------------------
#include "llnotifications.h"
#include "llfloaterreg.h"
@@ -334,13 +343,13 @@ namespace tut
gTOSReplyPump = 0; // clear the callback.
- gSavedSettings.declareBOOL("NoInventoryLibrary", FALSE, "", FALSE);
- gSavedSettings.declareBOOL("ConnectAsGod", FALSE, "", FALSE);
- gSavedSettings.declareBOOL("UseDebugMenus", FALSE, "", FALSE);
- gSavedSettings.declareBOOL("ForceMandatoryUpdate", FALSE, "", FALSE);
- gSavedSettings.declareString("ClientSettingsFile", "test_settings.xml", "", FALSE);
- gSavedSettings.declareString("NextLoginLocation", "", "", FALSE);
- gSavedSettings.declareBOOL("LoginLastLocation", FALSE, "", FALSE);
+ gSavedSettings.declareBOOL("NoInventoryLibrary", FALSE, "", LLControlVariable::PERSIST_NO);
+ gSavedSettings.declareBOOL("ConnectAsGod", FALSE, "", LLControlVariable::PERSIST_NO);
+ gSavedSettings.declareBOOL("UseDebugMenus", FALSE, "", LLControlVariable::PERSIST_NO);
+ gSavedSettings.declareBOOL("ForceMandatoryUpdate", FALSE, "", LLControlVariable::PERSIST_NO);
+ gSavedSettings.declareString("ClientSettingsFile", "test_settings.xml", "", LLControlVariable::PERSIST_NO);
+ gSavedSettings.declareString("NextLoginLocation", "", "", LLControlVariable::PERSIST_NO);
+ gSavedSettings.declareBOOL("LoginLastLocation", FALSE, "", LLControlVariable::PERSIST_NO);
LLSD authenticator = LLSD::emptyMap();
LLSD identifier = LLSD::emptyMap();
@@ -360,6 +369,7 @@ namespace tut
accountCredential->setCredentialData(identifier, authenticator);
logininstance->setNotificationsInterface(&notifications);
+ logininstance->setPlatformInfo("win", "1.3.5");
}
LLLoginInstance* logininstance;
diff --git a/indra/newview/tests/llmediadataclient_test.cpp b/indra/newview/tests/llmediadataclient_test.cpp
index 0254c5881f..3e55336f2d 100644..100755
--- a/indra/newview/tests/llmediadataclient_test.cpp
+++ b/indra/newview/tests/llmediadataclient_test.cpp
@@ -39,6 +39,7 @@
#include "../llvovolume.h"
#include "../../llprimitive/llmediaentry.cpp"
+#include "../../llprimitive/llmaterialid.cpp"
#include "../../llprimitive/lltextureentry.cpp"
#include "../../llmessage/tests/llcurl_stub.cpp"
@@ -126,7 +127,9 @@ void LLHTTPClient::post(
result[LLTextureEntry::OBJECT_ID_KEY] = body[LLTextureEntry::OBJECT_ID_KEY];
if ( url == FAKE_OBJECT_MEDIA_CAP_URL_503 )
{
- responder->error(HTTP_SERVICE_UNAVAILABLE, "fake reason");
+ LLSD content;
+ content["reason"] = "fake reason";
+ responder->errorWithContent(HTTP_SERVICE_UNAVAILABLE, "fake reason", content);
return;
}
else if (url == FAKE_OBJECT_MEDIA_NAVIGATE_CAP_URL_ERROR)
diff --git a/indra/newview/tests/llpipeline_stub.cpp b/indra/newview/tests/llpipeline_stub.cpp
index ad112cbf6a..ad112cbf6a 100644..100755
--- a/indra/newview/tests/llpipeline_stub.cpp
+++ b/indra/newview/tests/llpipeline_stub.cpp
diff --git a/indra/newview/tests/llremoteparcelrequest_test.cpp b/indra/newview/tests/llremoteparcelrequest_test.cpp
index ed66066b0a..ed66066b0a 100644..100755
--- a/indra/newview/tests/llremoteparcelrequest_test.cpp
+++ b/indra/newview/tests/llremoteparcelrequest_test.cpp
diff --git a/indra/newview/tests/llsecapi_test.cpp b/indra/newview/tests/llsecapi_test.cpp
index 703603e2db..d7e87ed52e 100644..100755
--- a/indra/newview/tests/llsecapi_test.cpp
+++ b/indra/newview/tests/llsecapi_test.cpp
@@ -39,10 +39,10 @@
LLControlGroup::LLControlGroup(const std::string& name)
: LLInstanceTracker<LLControlGroup, std::string>(name) {}
LLControlGroup::~LLControlGroup() {}
-BOOL LLControlGroup::declareString(const std::string& name,
+LLControlVariable* LLControlGroup::declareString(const std::string& name,
const std::string& initial_val,
const std::string& comment,
- BOOL persist) {return TRUE;}
+ LLControlVariable::ePersist persist) {return NULL;}
void LLControlGroup::setString(const std::string& name, const std::string& val){}
std::string LLControlGroup::getString(const std::string& name)
{
diff --git a/indra/newview/tests/llsechandler_basic_test.cpp b/indra/newview/tests/llsechandler_basic_test.cpp
index 0235400976..2a8dc15346 100644..100755
--- a/indra/newview/tests/llsechandler_basic_test.cpp
+++ b/indra/newview/tests/llsechandler_basic_test.cpp
@@ -71,10 +71,10 @@ std::string gLastName;
LLControlGroup::LLControlGroup(const std::string& name)
: LLInstanceTracker<LLControlGroup, std::string>(name) {}
LLControlGroup::~LLControlGroup() {}
-BOOL LLControlGroup::declareString(const std::string& name,
+LLControlVariable* LLControlGroup::declareString(const std::string& name,
const std::string& initial_val,
const std::string& comment,
- BOOL persist) {return TRUE;}
+ LLControlVariable::ePersist persist) {return NULL;}
void LLControlGroup::setString(const std::string& name, const std::string& val){}
std::string LLControlGroup::getString(const std::string& name)
{
diff --git a/indra/newview/tests/llsimplestat_test.cpp b/indra/newview/tests/llsimplestat_test.cpp
index b556941f4a..b556941f4a 100644..100755
--- a/indra/newview/tests/llsimplestat_test.cpp
+++ b/indra/newview/tests/llsimplestat_test.cpp
diff --git a/indra/newview/tests/llsky_stub.cpp b/indra/newview/tests/llsky_stub.cpp
index 241d740635..241d740635 100644..100755
--- a/indra/newview/tests/llsky_stub.cpp
+++ b/indra/newview/tests/llsky_stub.cpp
diff --git a/indra/newview/tests/llslurl_test.cpp b/indra/newview/tests/llslurl_test.cpp
index f96f79006a..86229ad636 100644..100755
--- a/indra/newview/tests/llslurl_test.cpp
+++ b/indra/newview/tests/llslurl_test.cpp
@@ -1,4 +1,4 @@
-/**
+/**
* @file llsecapi_test.cpp
* @author Roxie
* @date 2009-02-10
@@ -7,21 +7,21 @@
* $LicenseInfo:firstyear=2009&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$
*/
@@ -31,16 +31,16 @@
#include "../llslurl.h"
#include "../../llxml/llcontrol.h"
#include "llsdserialize.h"
-//----------------------------------------------------------------------------
-// Mock objects for the dependencies of the code we're testing
+//----------------------------------------------------------------------------
+// Mock objects for the dependencies of the code we're testing
LLControlGroup::LLControlGroup(const std::string& name)
: LLInstanceTracker<LLControlGroup, std::string>(name) {}
LLControlGroup::~LLControlGroup() {}
-BOOL LLControlGroup::declareString(const std::string& name,
+LLControlVariable* LLControlGroup::declareString(const std::string& name,
const std::string& initial_val,
const std::string& comment,
- BOOL persist) {return TRUE;}
+ LLControlVariable::ePersist persist) {return NULL;}
void LLControlGroup::setString(const std::string& name, const std::string& val){}
std::string gCmdLineLoginURI;
@@ -80,6 +80,39 @@ LLPointer<LLControlVariable> LLControlGroup::getControl(const std::string& name)
}
LLControlGroup gSavedSettings("test");
+const char *gSampleGridFile =
+ "<?xml version=\"1.0\"?>"
+ "<llsd>"
+ " <map>"
+ " <key>foo.bar.com</key>"
+ " <map>"
+ " <key>helper_uri</key><string>https://foobar/helpers/</string>"
+ " <key>label</key><string>Foobar Grid</string>"
+ " <key>login_page</key><string>foobar/loginpage</string>"
+ " <key>login_uri</key>"
+ " <array>"
+ " <string>foobar/loginuri</string>"
+ " </array>"
+ " <key>keyname</key><string>foo.bar.com</string>"
+ " <key>credential_type</key><string>agent</string>"
+ " <key>grid_login_id</key><string>FooBar</string>"
+ " </map>"
+ " <key>my.grid.com</key>"
+ " <map>"
+ " <key>helper_uri</key><string>https://mygrid/helpers/</string>"
+ " <key>label</key><string>My Grid</string>"
+ " <key>login_page</key><string>mygrid/loginpage</string>"
+ " <key>login_uri</key>"
+ " <array>"
+ " <string>mygrid/loginuri</string>"
+ " </array>"
+ " <key>keyname</key><string>my.grid.com</string>"
+ " <key>credential_type</key><string>agent</string>"
+ " <key>grid_login_id</key><string>MyGrid</string>"
+ " </map>"
+ " </map>"
+ "</llsd>"
+ ;
// -------------------------------------------------------------------------------------------
// TUT
@@ -90,171 +123,189 @@ namespace tut
struct slurlTest
{
slurlTest()
- {
+ {
LLGridManager::getInstance()->initialize(std::string(""));
}
~slurlTest()
{
}
};
-
+
// Tut templating thingamagic: test group, object and test instance
typedef test_group<slurlTest> slurlTestFactory;
typedef slurlTestFactory::object slurlTestObject;
tut::slurlTestFactory tut_test("LLSlurl");
-
+
// ---------------------------------------------------------------------------------------
- // Test functions
+ // Test functions
// ---------------------------------------------------------------------------------------
// construction from slurl string
template<> template<>
void slurlTestObject::test<1>()
{
+ llofstream gridfile("grid_test.xml");
+ gridfile << gSampleGridFile;
+ gridfile.close();
+
+ LLGridManager::getInstance()->initialize("grid_test.xml");
+
LLGridManager::getInstance()->setGridChoice("util.agni.lindenlab.com");
-
+
LLSLURL slurl = LLSLURL("");
ensure_equals("null slurl", (int)slurl.getType(), LLSLURL::LAST_LOCATION);
-
+
slurl = LLSLURL("http://slurl.com/secondlife/myregion");
ensure_equals("slurl.com slurl, region only - type", slurl.getType(), LLSLURL::LOCATION);
- ensure_equals("slurl.com slurl, region only", slurl.getSLURLString(),
+ ensure_equals("slurl.com slurl, region only", slurl.getSLURLString(),
"http://maps.secondlife.com/secondlife/myregion/128/128/0");
-
+
slurl = LLSLURL("http://maps.secondlife.com/secondlife/myregion/1/2/3");
ensure_equals("maps.secondlife.com slurl, region + coords - type", slurl.getType(), LLSLURL::LOCATION);
- ensure_equals("maps.secondlife.com slurl, region + coords", slurl.getSLURLString(),
+ ensure_equals("maps.secondlife.com slurl, region + coords", slurl.getSLURLString(),
"http://maps.secondlife.com/secondlife/myregion/1/2/3");
slurl = LLSLURL("secondlife://myregion");
ensure_equals("secondlife: slurl, region only - type", slurl.getType(), LLSLURL::LOCATION);
- ensure_equals("secondlife: slurl, region only", slurl.getSLURLString(),
+ ensure_equals("secondlife: slurl, region only", slurl.getSLURLString(),
"http://maps.secondlife.com/secondlife/myregion/128/128/0");
-
+
slurl = LLSLURL("secondlife://myregion/1/2/3");
ensure_equals("secondlife: slurl, region + coords - type", slurl.getType(), LLSLURL::LOCATION);
- ensure_equals("secondlife slurl, region + coords", slurl.getSLURLString(),
+ ensure_equals("secondlife slurl, region + coords", slurl.getSLURLString(),
"http://maps.secondlife.com/secondlife/myregion/1/2/3");
-
+
slurl = LLSLURL("/myregion");
ensure_equals("/region slurl, region- type", slurl.getType(), LLSLURL::LOCATION);
- ensure_equals("/region slurl, region ", slurl.getSLURLString(),
+ ensure_equals("/region slurl, region ", slurl.getSLURLString(),
"http://maps.secondlife.com/secondlife/myregion/128/128/0");
-
+
slurl = LLSLURL("/myregion/1/2/3");
ensure_equals("/: slurl, region + coords - type", slurl.getType(), LLSLURL::LOCATION);
- ensure_equals("/ slurl, region + coords", slurl.getSLURLString(),
- "http://maps.secondlife.com/secondlife/myregion/1/2/3");
-
+ ensure_equals("/ slurl, region + coords", slurl.getSLURLString(),
+ "http://maps.secondlife.com/secondlife/myregion/1/2/3");
+
slurl = LLSLURL("my region/1/2/3");
ensure_equals(" slurl, region + coords - type", slurl.getType(), LLSLURL::LOCATION);
- ensure_equals(" slurl, region + coords", slurl.getSLURLString(),
- "http://maps.secondlife.com/secondlife/my%20region/1/2/3");
-
- LLGridManager::getInstance()->setGridChoice("my.grid.com");
+ ensure_equals(" slurl, region + coords", slurl.getSLURLString(),
+ "http://maps.secondlife.com/secondlife/my%20region/1/2/3");
+
+ LLGridManager::getInstance()->setGridChoice("my.grid.com");
slurl = LLSLURL("https://my.grid.com/region/my%20region/1/2/3");
ensure_equals("grid slurl, region + coords - type", slurl.getType(), LLSLURL::LOCATION);
- ensure_equals("grid slurl, region + coords", slurl.getSLURLString(),
- "https://my.grid.com/region/my%20region/1/2/3");
-
+ ensure_equals("grid slurl, region + coords", slurl.getSLURLString(),
+ "https://my.grid.com/region/my%20region/1/2/3");
+
slurl = LLSLURL("https://my.grid.com/region/my region");
ensure_equals("grid slurl, region + coords - type", slurl.getType(), LLSLURL::LOCATION);
- ensure_equals("grid slurl, region + coords", slurl.getSLURLString(),
+ ensure_equals("grid slurl, region + coords", slurl.getSLURLString(),
"https://my.grid.com/region/my%20region/128/128/0");
-
- LLGridManager::getInstance()->setGridChoice("foo.bar.com");
+
+ LLGridManager::getInstance()->setGridChoice("foo.bar.com");
slurl = LLSLURL("/myregion/1/2/3");
ensure_equals("/: slurl, region + coords - type", slurl.getType(), LLSLURL::LOCATION);
- ensure_equals("/ slurl, region + coords", slurl.getSLURLString(),
- "https://foo.bar.com/region/myregion/1/2/3");
-
+ ensure_equals("/ slurl, region + coords", slurl.getSLURLString(),
+ "https://foo.bar.com/region/myregion/1/2/3");
+
slurl = LLSLURL("myregion/1/2/3");
ensure_equals(": slurl, region + coords - type", slurl.getType(), LLSLURL::LOCATION);
- ensure_equals(" slurl, region + coords", slurl.getSLURLString(),
- "https://foo.bar.com/region/myregion/1/2/3");
-
+ ensure_equals(" slurl, region + coords", slurl.getSLURLString(),
+ "https://foo.bar.com/region/myregion/1/2/3");
+
slurl = LLSLURL(LLSLURL::SIM_LOCATION_HOME);
ensure_equals("home", slurl.getType(), LLSLURL::HOME_LOCATION);
slurl = LLSLURL(LLSLURL::SIM_LOCATION_LAST);
ensure_equals("last", slurl.getType(), LLSLURL::LAST_LOCATION);
-
+
slurl = LLSLURL("secondlife:///app/foo/bar?12345");
- ensure_equals("app", slurl.getType(), LLSLURL::APP);
+ ensure_equals("app", slurl.getType(), LLSLURL::APP);
ensure_equals("appcmd", slurl.getAppCmd(), "foo");
ensure_equals("apppath", slurl.getAppPath().size(), 1);
ensure_equals("apppath2", slurl.getAppPath()[0].asString(), "bar");
ensure_equals("appquery", slurl.getAppQuery(), "12345");
- ensure_equals("grid1", "foo.bar.com", slurl.getGrid());
-
+ ensure_equals("grid1", slurl.getGrid(), "FooBar");
+
slurl = LLSLURL("secondlife://Aditi/app/foo/bar?12345");
- ensure_equals("app", slurl.getType(), LLSLURL::APP);
+ ensure_equals("app", slurl.getType(), LLSLURL::APP);
ensure_equals("appcmd", slurl.getAppCmd(), "foo");
ensure_equals("apppath", slurl.getAppPath().size(), 1);
ensure_equals("apppath2", slurl.getAppPath()[0].asString(), "bar");
ensure_equals("appquery", slurl.getAppQuery(), "12345");
- ensure_equals("grid2", "util.aditi.lindenlab.com", slurl.getGrid());
+ ensure_equals("grid2", slurl.getGrid(), "Aditi");
- LLGridManager::getInstance()->setGridChoice("foo.bar.com");
+ LLGridManager::getInstance()->setGridChoice("foo.bar.com");
slurl = LLSLURL("secondlife:///secondlife/myregion/1/2/3");
ensure_equals("/: slurl, region + coords - type", slurl.getType(), LLSLURL::LOCATION);
ensure_equals("location", slurl.getType(), LLSLURL::LOCATION);
ensure_equals("region" , "myregion", slurl.getRegion());
- ensure_equals("grid3", "util.agni.lindenlab.com", slurl.getGrid());
-
+ ensure_equals("grid3", slurl.getGrid(), "util.agni.lindenlab.com");
+
slurl = LLSLURL("secondlife://Aditi/secondlife/myregion/1/2/3");
ensure_equals("/: slurl, region + coords - type", slurl.getType(), LLSLURL::LOCATION);
ensure_equals("location", slurl.getType(), LLSLURL::LOCATION);
ensure_equals("region" , "myregion", slurl.getRegion());
- ensure_equals("grid4", "util.aditi.lindenlab.com", slurl.getGrid());
-
+ ensure_equals("grid4", slurl.getGrid(), "Aditi" );
+
LLGridManager::getInstance()->setGridChoice("my.grid.com");
slurl = LLSLURL("https://my.grid.com/app/foo/bar?12345");
- ensure_equals("app", slurl.getType(), LLSLURL::APP);
+ ensure_equals("app", slurl.getType(), LLSLURL::APP);
ensure_equals("appcmd", slurl.getAppCmd(), "foo");
ensure_equals("apppath", slurl.getAppPath().size(), 1);
ensure_equals("apppath2", slurl.getAppPath()[0].asString(), "bar");
- ensure_equals("appquery", slurl.getAppQuery(), "12345");
-
+ ensure_equals("appquery", slurl.getAppQuery(), "12345");
+
}
-
+
// construction from grid/region/vector combos
template<> template<>
void slurlTestObject::test<2>()
{
- LLSLURL slurl = LLSLURL("mygrid.com", "my region");
+ llofstream gridfile("grid_test.xml");
+ gridfile << gSampleGridFile;
+ gridfile.close();
+
+ LLGridManager::getInstance()->initialize("grid_test.xml");
+
+ LLSLURL slurl = LLSLURL("my.grid.com", "my region");
ensure_equals("grid/region - type", slurl.getType(), LLSLURL::LOCATION);
- ensure_equals("grid/region", slurl.getSLURLString(),
- "https://mygrid.com/region/my%20region/128/128/0");
-
- slurl = LLSLURL("mygrid.com", "my region", LLVector3(1,2,3));
+ ensure_equals("grid/region", slurl.getSLURLString(),
+ "https://my.grid.com/region/my%20region/128/128/0");
+
+ slurl = LLSLURL("my.grid.com", "my region", LLVector3(1,2,3));
ensure_equals("grid/region/vector - type", slurl.getType(), LLSLURL::LOCATION);
- ensure_equals(" grid/region/vector", slurl.getSLURLString(),
- "https://mygrid.com/region/my%20region/1/2/3");
+ ensure_equals(" grid/region/vector", slurl.getSLURLString(),
+ "https://my.grid.com/region/my%20region/1/2/3");
- LLGridManager::getInstance()->setGridChoice("foo.bar.com.bar");
+ LLGridManager::getInstance()->setGridChoice("util.agni.lindenlab.com");
slurl = LLSLURL("my region", LLVector3(1,2,3));
- ensure_equals("grid/region/vector - type", slurl.getType(), LLSLURL::LOCATION);
- ensure_equals(" grid/region/vector", slurl.getSLURLString(),
- "https://foo.bar.com.bar/region/my%20region/1/2/3");
-
- LLGridManager::getInstance()->setGridChoice("util.agni.lindenlab.com");
+ ensure_equals("default grid/region/vector - type", slurl.getType(), LLSLURL::LOCATION);
+ ensure_equals(" default grid/region/vector", slurl.getSLURLString(),
+ "http://maps.secondlife.com/secondlife/my%20region/1/2/3");
+
+ LLGridManager::getInstance()->setGridChoice("MyGrid");
slurl = LLSLURL("my region", LLVector3(1,2,3));
ensure_equals("default grid/region/vector - type", slurl.getType(), LLSLURL::LOCATION);
- ensure_equals(" default grid/region/vector", slurl.getSLURLString(),
- "http://maps.secondlife.com/secondlife/my%20region/1/2/3");
-
+ ensure_equals(" default grid/region/vector", slurl.getSLURLString(),
+ "https://my.grid.com/region/my%20region/1/2/3");
+
}
// Accessors
template<> template<>
void slurlTestObject::test<3>()
{
- LLGridManager::getInstance()->setGridChoice("my.grid.com");
+ llofstream gridfile("grid_test.xml");
+ gridfile << gSampleGridFile;
+ gridfile.close();
+
+ LLGridManager::getInstance()->initialize("grid_test.xml");
+
+ LLGridManager::getInstance()->setGridChoice("my.grid.com");
LLSLURL slurl = LLSLURL("https://my.grid.com/region/my%20region/1/2/3");
ensure_equals("login string", slurl.getLoginString(), "uri:my region&amp;1&amp;2&amp;3");
ensure_equals("location string", slurl.getLocationString(), "my region/1/2/3");
ensure_equals("grid", slurl.getGrid(), "my.grid.com");
ensure_equals("region", slurl.getRegion(), "my region");
ensure_equals("position", slurl.getPosition(), LLVector3(1, 2, 3));
-
+
}
}
diff --git a/indra/newview/tests/lltextureinfo_test.cpp b/indra/newview/tests/lltextureinfo_test.cpp
index 73ace1de37..73ace1de37 100644..100755
--- a/indra/newview/tests/lltextureinfo_test.cpp
+++ b/indra/newview/tests/lltextureinfo_test.cpp
diff --git a/indra/newview/tests/lltextureinfodetails_test.cpp b/indra/newview/tests/lltextureinfodetails_test.cpp
index 31ec5f9d4e..31ec5f9d4e 100644..100755
--- a/indra/newview/tests/lltextureinfodetails_test.cpp
+++ b/indra/newview/tests/lltextureinfodetails_test.cpp
diff --git a/indra/newview/tests/lltexturestatsuploader_test.cpp b/indra/newview/tests/lltexturestatsuploader_test.cpp
index cfb2c267cc..cfb2c267cc 100644..100755
--- a/indra/newview/tests/lltexturestatsuploader_test.cpp
+++ b/indra/newview/tests/lltexturestatsuploader_test.cpp
diff --git a/indra/newview/tests/lltranslate_test.cpp b/indra/newview/tests/lltranslate_test.cpp
index 10e37fae97..8ce56326d8 100644..100755
--- a/indra/newview/tests/lltranslate_test.cpp
+++ b/indra/newview/tests/lltranslate_test.cpp
@@ -299,11 +299,6 @@ LLControlGroup::LLControlGroup(const std::string& name) : LLInstanceTracker<LLCo
std::string LLControlGroup::getString(const std::string& name) { return "dummy"; }
LLControlGroup::~LLControlGroup() {}
-namespace boost {
- void intrusive_ptr_add_ref(LLCurl::Responder*) {}
- void intrusive_ptr_release(LLCurl::Responder*) {}
-}
-
LLCurl::Responder::Responder() {}
void LLCurl::Responder::completedHeader(U32, std::string const&, LLSD const&) {}
void LLCurl::Responder::completedRaw(U32, const std::string&, const LLChannelDescriptors&, const LLIOPipe::buffer_ptr_t& buffer) {}
@@ -313,8 +308,8 @@ void LLCurl::Responder::errorWithContent(U32, std::string const&, LLSD const&) {
void LLCurl::Responder::result(LLSD const&) {}
LLCurl::Responder::~Responder() {}
-void LLHTTPClient::get(const std::string&, const LLSD&, ResponderPtr, const LLSD&, const F32) {}
-void LLHTTPClient::get(const std::string&, boost::intrusive_ptr<LLCurl::Responder>, const LLSD&, const F32) {}
+void LLHTTPClient::get(const std::string&, const LLSD&, ResponderPtr, const LLSD&, const F32, bool) {}
+void LLHTTPClient::get(const std::string&, LLPointer<LLCurl::Responder>, const LLSD&, const F32, bool) {}
LLBufferStream::LLBufferStream(const LLChannelDescriptors& channels, LLBufferArray* buffer)
: std::iostream(&mStreamBuf), mStreamBuf(channels, buffer) {}
diff --git a/indra/newview/tests/llversioninfo_test.cpp b/indra/newview/tests/llversioninfo_test.cpp
index 398d8f16ed..6b0be29c2d 100644..100755
--- a/indra/newview/tests/llversioninfo_test.cpp
+++ b/indra/newview/tests/llversioninfo_test.cpp
@@ -28,7 +28,6 @@
#include "../test/lltut.h"
#include "../llversioninfo.h"
-#include "llversionviewer.h"
namespace tut
{
@@ -38,20 +37,20 @@ namespace tut
: mResetChannel("Reset Channel")
{
std::ostringstream stream;
- stream << LL_VERSION_MAJOR << "."
- << LL_VERSION_MINOR << "."
- << LL_VERSION_PATCH << "."
- << LL_VERSION_BUILD;
+ stream << LL_VIEWER_VERSION_MAJOR << "."
+ << LL_VIEWER_VERSION_MINOR << "."
+ << LL_VIEWER_VERSION_PATCH << "."
+ << LL_VIEWER_VERSION_BUILD;
mVersion = stream.str();
stream.str("");
- stream << LL_VERSION_MAJOR << "."
- << LL_VERSION_MINOR << "."
- << LL_VERSION_PATCH;
+ stream << LL_VIEWER_VERSION_MAJOR << "."
+ << LL_VIEWER_VERSION_MINOR << "."
+ << LL_VIEWER_VERSION_PATCH;
mShortVersion = stream.str();
stream.str("");
- stream << LL_CHANNEL
+ stream << LL_VIEWER_CHANNEL
<< " "
<< mVersion;
mVersionAndChannel = stream.str();
@@ -78,20 +77,19 @@ namespace tut
{
ensure_equals("Major version",
LLVersionInfo::getMajor(),
- LL_VERSION_MAJOR);
+ LL_VIEWER_VERSION_MAJOR);
ensure_equals("Minor version",
LLVersionInfo::getMinor(),
- LL_VERSION_MINOR);
+ LL_VIEWER_VERSION_MINOR);
ensure_equals("Patch version",
LLVersionInfo::getPatch(),
- LL_VERSION_PATCH);
+ LL_VIEWER_VERSION_PATCH);
ensure_equals("Build version",
LLVersionInfo::getBuild(),
- LL_VERSION_BUILD);
+ LL_VIEWER_VERSION_BUILD);
ensure_equals("Channel version",
LLVersionInfo::getChannel(),
- LL_CHANNEL);
-
+ LL_VIEWER_CHANNEL);
ensure_equals("Version String",
LLVersionInfo::getVersion(),
mVersion);
diff --git a/indra/newview/tests/llviewerassetstats_test.cpp b/indra/newview/tests/llviewerassetstats_test.cpp
index 3faddc13c1..a331d9aa9e 100644..100755
--- a/indra/newview/tests/llviewerassetstats_test.cpp
+++ b/indra/newview/tests/llviewerassetstats_test.cpp
@@ -35,6 +35,7 @@
#include "lluuid.h"
#include "llsdutil.h"
#include "llregionhandle.h"
+#include "../llvoavatar.h"
static const char * all_keys[] =
{
@@ -98,7 +99,9 @@ is_empty_map(const LLSD & sd)
{
return sd.isMap() && 0 == sd.size();
}
+#endif
+#if 0
static bool
is_single_key_map(const LLSD & sd, const std::string & key)
{
@@ -112,6 +115,14 @@ is_double_key_map(const LLSD & sd, const std::string & key1, const std::string &
return sd.isMap() && 2 == sd.size() && sd.has(key1) && sd.has(key2);
}
+#if 0
+static bool
+is_triple_key_map(const LLSD & sd, const std::string & key1, const std::string & key2, const std::string& key3)
+{
+ return sd.isMap() && 3 == sd.size() && sd.has(key1) && sd.has(key2) && sd.has(key3);
+}
+#endif
+
static bool
is_no_stats_map(const LLSD & sd)
{
diff --git a/indra/newview/tests/llviewerhelputil_test.cpp b/indra/newview/tests/llviewerhelputil_test.cpp
index 710881d811..f6456a2839 100644..100755
--- a/indra/newview/tests/llviewerhelputil_test.cpp
+++ b/indra/newview/tests/llviewerhelputil_test.cpp
@@ -49,10 +49,10 @@ static std::string gOS;
LLControlGroup::LLControlGroup(const std::string& name)
: LLInstanceTracker<LLControlGroup, std::string>(name) {}
LLControlGroup::~LLControlGroup() {}
-BOOL LLControlGroup::declareString(const std::string& name,
+LLControlVariable* LLControlGroup::declareString(const std::string& name,
const std::string& initial_val,
const std::string& comment,
- BOOL persist) {return TRUE;}
+ LLControlVariable::ePersist persist) {return NULL;}
void LLControlGroup::setString(const std::string& name, const std::string& val){}
std::string LLControlGroup::getString(const std::string& name)
{
diff --git a/indra/newview/tests/llviewernetwork_test.cpp b/indra/newview/tests/llviewernetwork_test.cpp
index 3c89b64d52..7ad7947ca4 100644..100755
--- a/indra/newview/tests/llviewernetwork_test.cpp
+++ b/indra/newview/tests/llviewernetwork_test.cpp
@@ -1,4 +1,4 @@
-/**
+/**
* @file llviewernetwork_test.cpp
* @author Roxie
* @date 2009-03-9
@@ -7,21 +7,21 @@
* $LicenseInfo:firstyear=2009&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$
*/
@@ -31,16 +31,16 @@
#include "../../llxml/llcontrol.h"
#include "llfile.h"
-//----------------------------------------------------------------------------
-// Mock objects for the dependencies of the code we're testing
+//----------------------------------------------------------------------------
+// Mock objects for the dependencies of the code we're testing
LLControlGroup::LLControlGroup(const std::string& name)
: LLInstanceTracker<LLControlGroup, std::string>(name) {}
LLControlGroup::~LLControlGroup() {}
-BOOL LLControlGroup::declareString(const std::string& name,
+LLControlVariable* LLControlGroup::declareString(const std::string& name,
const std::string& initial_val,
const std::string& comment,
- BOOL persist) {return TRUE;}
+ LLControlVariable::ePersist persist) {return NULL;}
void LLControlGroup::setString(const std::string& name, const std::string& val){}
std::string gCmdLineLoginURI;
@@ -81,26 +81,58 @@ LLPointer<LLControlVariable> LLControlGroup::getControl(const std::string& name)
LLControlGroup gSavedSettings("test");
-const char *gSampleGridFile = "<llsd><map>"
-"<key>grid1</key><map>"
-" <key>favorite</key><integer>1</integer>"
-" <key>helper_uri</key><string>https://helper1/helpers/</string>"
-" <key>label</key><string>mylabel</string>"
-" <key>login_page</key><string>loginpage</string>"
-" <key>login_uri</key><array><string>myloginuri</string></array>"
-" <key>name</key><string>grid1</string>"
-" <key>visible</key><integer>1</integer>"
-" <key>credential_type</key><string>agent</string>"
-" <key>grid_login_id</key><string>MyGrid</string>"
-"</map>"
-"<key>util.agni.lindenlab.com</key><map>"
-" <key>favorite</key><integer>1</integer>"
-" <key>helper_uri</key><string>https://helper1/helpers/</string>"
-" <key>label</key><string>mylabel</string>"
-" <key>login_page</key><string>loginpage</string>"
-" <key>login_uri</key><array><string>myloginuri</string></array>"
-" <key>name</key><string>util.agni.lindenlab.com</string>"
-"</map></map></llsd>";
+const char *gSampleGridFile =
+ "<?xml version=\"1.0\"?>"
+ "<llsd>"
+ " <map>"
+ " <key>altgrid.long.name</key>"
+ " <map>"
+ " <key>helper_uri</key><string>https://helper1/helpers/</string>"
+ " <key>label</key><string>Alternative Grid</string>"
+ " <key>login_page</key><string>altgrid/loginpage</string>"
+ " <key>login_uri</key>"
+ " <array>"
+ " <string>altgrid/myloginuri1</string>"
+ " <string>altgrid/myloginuri2</string>"
+ " </array>"
+ " <key>keyname</key><string>altgrid.long.name</string>"
+ " <key>credential_type</key><string>agent</string>"
+ " <key>grid_login_id</key><string>AltGrid</string>"
+ " </map>"
+ " <key>minimal.long.name</key>"
+ " <map>"
+ " <key>keyname</key><string>minimal.long.name</string>"
+ " </map>"
+ " <!-- Note that the values for agni and aditi below are deliberately"
+ " incorrect to test that they are not overwritten -->"
+ " <key>util.agni.lindenlab.com</key> <!-- conflict -->"
+ " <map>"
+ " <key>helper_uri</key><string>https://helper1/helpers/</string>"
+ " <key>grid_login_id</key><string>mylabel</string>"
+ " <key>label</key><string>mylabel</string>"
+ " <key>login_page</key><string>loginpage</string>"
+ " <key>login_uri</key>"
+ " <array>"
+ " <string>myloginuri</string>"
+ " </array>"
+ " <key>keyname</key><string>util.agni.lindenlab.com</string> <!-- conflict -->"
+ " </map>"
+ " <key>util.foobar.lindenlab.com</key>"
+ " <map>"
+ " <key>helper_uri</key><string>https://helper1/helpers/</string>"
+ " <key>grid_login_id</key><string>Aditi</string> <!-- conflict -->"
+ " <key>label</key><string>mylabel</string>"
+ " <key>login_page</key><string>loginpage</string>"
+ " <key>login_uri</key>"
+ " <array>"
+ " <string>myloginuri</string>"
+ " </array>"
+ " <key>update_query_url_base</key><string>https://update.secondlife.com/update</string>"
+ " <key>keyname</key><string>util.foobar.lindenlab.com</string>"
+ " </map>"
+ " </map>"
+ "</llsd>"
+ ;
// -------------------------------------------------------------------------------------------
// TUT
// -------------------------------------------------------------------------------------------
@@ -116,63 +148,92 @@ namespace tut
gCmdLineGridChoice.clear();
gCmdLineHelperURI.clear();
gLoginPage.clear();
- gCurrentGrid.clear();
+ gCurrentGrid.clear();
}
~viewerNetworkTest()
{
LLFile::remove("grid_test.xml");
}
};
-
+
// Tut templating thingamagic: test group, object and test instance
typedef test_group<viewerNetworkTest> viewerNetworkTestFactory;
typedef viewerNetworkTestFactory::object viewerNetworkTestObject;
tut::viewerNetworkTestFactory tut_test("LLViewerNetwork");
-
+
// ---------------------------------------------------------------------------------------
- // Test functions
+ // Test functions
// ---------------------------------------------------------------------------------------
// initialization without a grid file
template<> template<>
void viewerNetworkTestObject::test<1>()
{
-
LLGridManager *manager = LLGridManager::getInstance();
// grid file doesn't exist
manager->initialize("grid_test.xml");
// validate that some of the defaults are available.
std::map<std::string, std::string> known_grids = manager->getKnownGrids();
- ensure_equals("Known grids is a string-string map of size 23", known_grids.size(), 23);
- ensure_equals("Agni has the right name and label",
- known_grids[std::string("util.agni.lindenlab.com")], std::string("Agni"));
- ensure_equals("None exists", known_grids[""], "None");
-
- LLSD grid;
- LLGridManager::getInstance()->getGridInfo("util.agni.lindenlab.com", grid);
- ensure("Grid info for agni is a map", grid.isMap());
- ensure_equals("name is correct for agni",
- grid[GRID_VALUE].asString(), std::string("util.agni.lindenlab.com"));
- ensure_equals("label is correct for agni",
- grid[GRID_LABEL_VALUE].asString(), std::string("Agni"));
- ensure("Login URI is an array",
- grid[GRID_LOGIN_URI_VALUE].isArray());
- ensure_equals("Agni login uri is correct",
- grid[GRID_LOGIN_URI_VALUE][0].asString(),
+ ensure_equals("Known grids is a string-string map of size 2", known_grids.size(), 2);
+ ensure_equals("Agni has the right name and label",
+ known_grids[std::string("util.agni.lindenlab.com")],
+ std::string("Second Life Main Grid (Agni)"));
+ ensure_equals("Aditi has the right name and label",
+ known_grids[std::string("util.aditi.lindenlab.com")],
+ std::string("Second Life Beta Test Grid (Aditi)"));
+ ensure_equals("name for agni",
+ LLGridManager::getInstance()->getGrid("util.agni.lindenlab.com"),
+ std::string("util.agni.lindenlab.com"));
+ ensure_equals("id for agni",
+ std::string("Agni"),
+ LLGridManager::getInstance()->getGridId("util.agni.lindenlab.com"));
+ ensure_equals("update url base for Agni", // relies on agni being the default
+ std::string("https://update.secondlife.com/update"),
+ LLGridManager::getInstance()->getUpdateServiceURL());
+ ensure_equals("label for agni",
+ LLGridManager::getInstance()->getGridLabel("util.agni.lindenlab.com"),
+ std::string("Second Life Main Grid (Agni)"));
+
+ std::vector<std::string> login_uris;
+ LLGridManager::getInstance()->getLoginURIs(std::string("util.agni.lindenlab.com"), login_uris);
+ ensure_equals("Number of login uris for agni", 1, login_uris.size());
+ ensure_equals("Agni login uri",
+ login_uris[0],
std::string("https://login.agni.lindenlab.com/cgi-bin/login.cgi"));
- ensure_equals("Agni helper uri is correct",
- grid[GRID_HELPER_URI_VALUE].asString(),
+ ensure_equals("Agni helper uri",
+ LLGridManager::getInstance()->getHelperURI("util.agni.lindenlab.com"),
std::string("https://secondlife.com/helpers/"));
- ensure_equals("Agni login page is correct",
- grid[GRID_LOGIN_PAGE_VALUE].asString(),
+ ensure_equals("Agni login page",
+ LLGridManager::getInstance()->getLoginPage("util.agni.lindenlab.com"),
std::string("http://viewer-login.agni.lindenlab.com/"));
- ensure("Agni is a favorite",
- grid.has(GRID_IS_FAVORITE_VALUE));
- ensure("Agni is a system grid",
- grid.has(GRID_IS_SYSTEM_GRID_VALUE));
- ensure("Grid file wasn't greated as it wasn't saved",
- !LLFile::isfile("grid_test.xml"));
+ ensure("Agni is a system grid",
+ LLGridManager::getInstance()->isSystemGrid("util.agni.lindenlab.com"));
+
+ ensure_equals("name for aditi",
+ LLGridManager::getInstance()->getGrid("util.aditi.lindenlab.com"),
+ std::string("util.aditi.lindenlab.com"));
+ ensure_equals("id for aditi",
+ LLGridManager::getInstance()->getGridId("util.aditi.lindenlab.com"),
+ std::string("Aditi"));
+ ensure_equals("label for aditi",
+ LLGridManager::getInstance()->getGridLabel("util.aditi.lindenlab.com"),
+ std::string("Second Life Beta Test Grid (Aditi)"));
+
+ LLGridManager::getInstance()->getLoginURIs(std::string("util.aditi.lindenlab.com"), login_uris);
+
+ ensure_equals("Number of login uris for aditi", 1, login_uris.size());
+ ensure_equals("Aditi login uri",
+ login_uris[0],
+ std::string("https://login.aditi.lindenlab.com/cgi-bin/login.cgi"));
+ ensure_equals("Aditi helper uri",
+ LLGridManager::getInstance()->getHelperURI("util.aditi.lindenlab.com"),
+ std::string("http://aditi-secondlife.webdev.lindenlab.com/helpers/"));
+ ensure_equals("Aditi login page",
+ LLGridManager::getInstance()->getLoginPage("util.aditi.lindenlab.com"),
+ std::string("http://viewer-login.agni.lindenlab.com/"));
+ ensure("Aditi is a system grid",
+ LLGridManager::getInstance()->isSystemGrid("util.aditi.lindenlab.com"));
}
-
+
// initialization with a grid file
template<> template<>
void viewerNetworkTestObject::test<2>()
@@ -180,402 +241,178 @@ namespace tut
llofstream gridfile("grid_test.xml");
gridfile << gSampleGridFile;
gridfile.close();
-
+
LLGridManager::getInstance()->initialize("grid_test.xml");
std::map<std::string, std::string> known_grids = LLGridManager::getInstance()->getKnownGrids();
- ensure_equals("adding a grid via a grid file increases known grid size",
- known_grids.size(), 24);
- ensure_equals("Agni is still there after we've added a grid via a grid file",
- known_grids["util.agni.lindenlab.com"], std::string("Agni"));
-
-
- // assure Agni doesn't get overwritten
- LLSD grid;
- LLGridManager::getInstance()->getGridInfo("util.agni.lindenlab.com", grid);
+ ensure_equals("adding a grid via a grid file increases known grid size",4,
+ known_grids.size());
- ensure_equals("Agni grid label was not modified by grid file",
- grid[GRID_LABEL_VALUE].asString(), std::string("Agni"));
-
- ensure_equals("Agni name wasn't modified by grid file",
- grid[GRID_VALUE].asString(), std::string("util.agni.lindenlab.com"));
- ensure("Agni grid URI is still an array after grid file",
- grid[GRID_LOGIN_URI_VALUE].isArray());
- ensure_equals("Agni login uri still the same after grid file",
- grid[GRID_LOGIN_URI_VALUE][0].asString(),
+ // Verify that Agni and Aditi were not overwritten
+ ensure_equals("Agni has the right name and label",
+ known_grids[std::string("util.agni.lindenlab.com")],
+ std::string("Second Life Main Grid (Agni)"));
+ ensure_equals("Aditi has the right name and label",
+ known_grids[std::string("util.aditi.lindenlab.com")],
+ std::string("Second Life Beta Test Grid (Aditi)"));
+ ensure_equals("name for agni",
+ LLGridManager::getInstance()->getGrid("util.agni.lindenlab.com"),
+ std::string("util.agni.lindenlab.com"));
+ ensure_equals("id for agni",
+ LLGridManager::getInstance()->getGridId("util.agni.lindenlab.com"),
+ std::string("Agni"));
+ ensure_equals("update url base for Agni", // relies on agni being the default
+ std::string("https://update.secondlife.com/update"),
+ LLGridManager::getInstance()->getUpdateServiceURL());
+ ensure_equals("label for agni",
+ LLGridManager::getInstance()->getGridLabel("util.agni.lindenlab.com"),
+ std::string("Second Life Main Grid (Agni)"));
+ std::vector<std::string> login_uris;
+ LLGridManager::getInstance()->getLoginURIs(std::string("util.agni.lindenlab.com"), login_uris);
+ ensure_equals("Number of login uris for agni", 1, login_uris.size());
+ ensure_equals("Agni login uri",
+ login_uris[0],
std::string("https://login.agni.lindenlab.com/cgi-bin/login.cgi"));
- ensure_equals("Agni helper uri still the same after grid file",
- grid[GRID_HELPER_URI_VALUE].asString(),
+ ensure_equals("Agni helper uri",
+ LLGridManager::getInstance()->getHelperURI("util.agni.lindenlab.com"),
std::string("https://secondlife.com/helpers/"));
- ensure_equals("Agni login page the same after grid file",
- grid[GRID_LOGIN_PAGE_VALUE].asString(),
+ ensure_equals("Agni login page",
+ LLGridManager::getInstance()->getLoginPage("util.agni.lindenlab.com"),
std::string("http://viewer-login.agni.lindenlab.com/"));
- ensure("Agni still a favorite after grid file",
- grid.has(GRID_IS_FAVORITE_VALUE));
- ensure("Agni system grid still set after grid file",
- grid.has(GRID_IS_SYSTEM_GRID_VALUE));
-
- ensure_equals("Grid file adds to name<->label map",
- known_grids["grid1"], std::string("mylabel"));
- LLGridManager::getInstance()->getGridInfo("grid1", grid);
- ensure_equals("grid file grid name is set",
- grid[GRID_VALUE].asString(), std::string("grid1"));
- ensure_equals("grid file label is set",
- grid[GRID_LABEL_VALUE].asString(), std::string("mylabel"));
- ensure("grid file login uri is an array",
- grid[GRID_LOGIN_URI_VALUE].isArray());
- ensure_equals("grid file login uri is set",
- grid[GRID_LOGIN_URI_VALUE][0].asString(),
- std::string("myloginuri"));
- ensure_equals("grid file helper uri is set",
- grid[GRID_HELPER_URI_VALUE].asString(),
- std::string("https://helper1/helpers/"));
- ensure_equals("grid file login page is set",
- grid[GRID_LOGIN_PAGE_VALUE].asString(),
- std::string("loginpage"));
- ensure("grid file favorite is set",
- grid.has(GRID_IS_FAVORITE_VALUE));
- ensure("grid file isn't a system grid",
- !grid.has(GRID_IS_SYSTEM_GRID_VALUE));
- ensure("Grid file still exists after loading",
- LLFile::isfile("grid_test.xml"));
- }
-
- // Initialize via command line
-
- template<> template<>
- void viewerNetworkTestObject::test<3>()
- {
- // USE --grid command line
- // initialize with a known grid
- LLSD grid;
- gCmdLineGridChoice = "Aditi";
- LLGridManager::getInstance()->initialize("grid_test.xml");
- // with single login uri specified.
- std::map<std::string, std::string> known_grids = LLGridManager::getInstance()->getKnownGrids();
- ensure_equals("Using a known grid via command line doesn't increase number of known grids",
- known_grids.size(), 23);
- ensure_equals("getGridLabel", LLGridManager::getInstance()->getGridLabel(), std::string("Aditi"));
- // initialize with a known grid in lowercase
- gCmdLineGridChoice = "agni";
- LLGridManager::getInstance()->initialize("grid_test.xml");
- ensure_equals("getGridLabel", LLGridManager::getInstance()->getGridLabel(), std::string("Agni"));
-
- // now try a command line with a custom grid identifier
- gCmdLineGridChoice = "mycustomgridchoice";
- LLGridManager::getInstance()->initialize("grid_test.xml");
- known_grids = LLGridManager::getInstance()->getKnownGrids();
- ensure_equals("adding a command line grid with custom name increases known grid size",
- known_grids.size(), 24);
- ensure_equals("Custom Command line grid is added to the list of grids",
- known_grids["mycustomgridchoice"], std::string("mycustomgridchoice"));
- LLGridManager::getInstance()->getGridInfo("mycustomgridchoice", grid);
- ensure_equals("Custom Command line grid name is set",
- grid[GRID_VALUE].asString(), std::string("mycustomgridchoice"));
- ensure_equals("Custom Command line grid label is set",
- grid[GRID_LABEL_VALUE].asString(), std::string("mycustomgridchoice"));
- ensure("Custom Command line grid login uri is an array",
- grid[GRID_LOGIN_URI_VALUE].isArray());
- ensure_equals("Custom Command line grid login uri is set",
- grid[GRID_LOGIN_URI_VALUE][0].asString(),
- std::string("https://mycustomgridchoice/cgi-bin/login.cgi"));
- ensure_equals("Custom Command line grid helper uri is set",
- grid[GRID_HELPER_URI_VALUE].asString(),
- std::string("https://mycustomgridchoice/helpers/"));
- ensure_equals("Custom Command line grid login page is set",
- grid[GRID_LOGIN_PAGE_VALUE].asString(),
- std::string("http://mycustomgridchoice/app/login/"));
- }
-
- // validate override of login uri with cmd line
- template<> template<>
- void viewerNetworkTestObject::test<4>()
- {
- // Override with loginuri
- // override known grid
- LLSD grid;
- gCmdLineGridChoice = "Aditi";
- gCmdLineLoginURI = "https://my.login.uri/cgi-bin/login.cgi";
- LLGridManager::getInstance()->initialize("grid_test.xml");
- std::map<std::string, std::string> known_grids = LLGridManager::getInstance()->getKnownGrids();
- ensure_equals("Override known grid login uri: No grids are added",
- known_grids.size(), 23);
- LLGridManager::getInstance()->getGridInfo(grid);
- ensure("Override known grid login uri: login uri is an array",
- grid[GRID_LOGIN_URI_VALUE].isArray());
- ensure_equals("Override known grid login uri: Command line grid login uri is set",
- grid[GRID_LOGIN_URI_VALUE][0].asString(),
- std::string("https://my.login.uri/cgi-bin/login.cgi"));
- ensure_equals("Override known grid login uri: helper uri is not changed",
- grid[GRID_HELPER_URI_VALUE].asString(),
- std::string("http://aditi-secondlife.webdev.lindenlab.com/helpers/"));
- ensure_equals("Override known grid login uri: login page is not set",
- grid[GRID_LOGIN_PAGE_VALUE].asString(),
- std::string("http://viewer-login.agni.lindenlab.com/"));
-
- // Override with loginuri
- // override custom grid
- gCmdLineGridChoice = "mycustomgridchoice";
- gCmdLineLoginURI = "https://my.login.uri/cgi-bin/login.cgi";
- LLGridManager::getInstance()->initialize("grid_test.xml");
- known_grids = LLGridManager::getInstance()->getKnownGrids();
- LLGridManager::getInstance()->getGridInfo(grid);
- ensure_equals("Override custom grid login uri: Grid is added",
- known_grids.size(), 24);
- ensure("Override custom grid login uri: login uri is an array",
- grid[GRID_LOGIN_URI_VALUE].isArray());
- ensure_equals("Override custom grid login uri: login uri is set",
- grid[GRID_LOGIN_URI_VALUE][0].asString(),
- std::string("https://my.login.uri/cgi-bin/login.cgi"));
- ensure_equals("Override custom grid login uri: Helper uri is not set",
- grid[GRID_HELPER_URI_VALUE].asString(),
- std::string("https://mycustomgridchoice/helpers/"));
- ensure_equals("Override custom grid login uri: Login page is not set",
- grid[GRID_LOGIN_PAGE_VALUE].asString(),
- std::string("http://mycustomgridchoice/app/login/"));
- }
-
- // validate override of helper uri with cmd line
- template<> template<>
- void viewerNetworkTestObject::test<5>()
- {
- // Override with helperuri
- // override known grid
- LLSD grid;
- gCmdLineGridChoice = "Aditi";
- gCmdLineLoginURI = "";
- gCmdLineHelperURI = "https://my.helper.uri/mycustomhelpers";
- LLGridManager::getInstance()->initialize("grid_test.xml");
- std::map<std::string, std::string> known_grids = LLGridManager::getInstance()->getKnownGrids();
- ensure_equals("Override known grid helper uri: No grids are added",
- known_grids.size(), 23);
- LLGridManager::getInstance()->getGridInfo(grid);
- ensure("Override known known helper uri: login uri is an array",
- grid[GRID_LOGIN_URI_VALUE].isArray());
- ensure_equals("Override known grid helper uri: login uri is not changed",
- grid[GRID_LOGIN_URI_VALUE][0].asString(),
- std::string("https://login.aditi.lindenlab.com/cgi-bin/login.cgi"));
- ensure_equals("Override known grid helper uri: helper uri is changed",
- grid[GRID_HELPER_URI_VALUE].asString(),
- std::string("https://my.helper.uri/mycustomhelpers"));
- ensure_equals("Override known grid helper uri: login page is not changed",
- grid[GRID_LOGIN_PAGE_VALUE].asString(),
- std::string("http://viewer-login.agni.lindenlab.com/"));
-
- // Override with helperuri
- // override custom grid
- gCmdLineGridChoice = "mycustomgridchoice";
- gCmdLineHelperURI = "https://my.helper.uri/mycustomhelpers";
- LLGridManager::getInstance()->initialize("grid_test.xml");
- known_grids = LLGridManager::getInstance()->getKnownGrids();
- ensure_equals("Override custom grid helper uri: grids is added",
- known_grids.size(), 24);
- LLGridManager::getInstance()->getGridInfo(grid);
- ensure("Override custom helper uri: login uri is an array",
- grid[GRID_LOGIN_URI_VALUE].isArray());
- ensure_equals("Override custom grid helper uri: login uri is not changed",
- grid[GRID_LOGIN_URI_VALUE][0].asString(),
- std::string("https://mycustomgridchoice/cgi-bin/login.cgi"));
- ensure_equals("Override custom grid helper uri: helper uri is changed",
- grid[GRID_HELPER_URI_VALUE].asString(),
- std::string("https://my.helper.uri/mycustomhelpers"));
- ensure_equals("Override custom grid helper uri: login page is not changed",
- grid[GRID_LOGIN_PAGE_VALUE].asString(),
- std::string("http://mycustomgridchoice/app/login/"));
- }
-
- // validate overriding of login page via cmd line
- template<> template<>
- void viewerNetworkTestObject::test<6>()
- {
- // Override with login page
- // override known grid
- LLSD grid;
- gCmdLineGridChoice = "Aditi";
- gCmdLineHelperURI = "";
- gLoginPage = "myloginpage";
- LLGridManager::getInstance()->initialize("grid_test.xml");
- std::map<std::string, std::string> known_grids = LLGridManager::getInstance()->getKnownGrids();
- ensure_equals("Override known grid login page: No grids are added",
- known_grids.size(), 23);
- LLGridManager::getInstance()->getGridInfo(grid);
- ensure("Override known grid login page: Command line grid login uri is an array",
- grid[GRID_LOGIN_URI_VALUE].isArray());
- ensure_equals("Override known grid login page: login uri is not changed",
- grid[GRID_LOGIN_URI_VALUE][0].asString(),
+ ensure("Agni is a system grid",
+ LLGridManager::getInstance()->isSystemGrid("util.agni.lindenlab.com"));
+
+ ensure_equals("name for aditi",
+ LLGridManager::getInstance()->getGrid("util.aditi.lindenlab.com"),
+ std::string("util.aditi.lindenlab.com"));
+ ensure_equals("id for aditi",
+ LLGridManager::getInstance()->getGridId("util.aditi.lindenlab.com"),
+ std::string("Aditi"));
+ ensure_equals("label for aditi",
+ LLGridManager::getInstance()->getGridLabel("util.aditi.lindenlab.com"),
+ std::string("Second Life Beta Test Grid (Aditi)"));
+
+ LLGridManager::getInstance()->getLoginURIs(std::string("util.aditi.lindenlab.com"), login_uris);
+ ensure_equals("Number of login uris for aditi", 1, login_uris.size());
+ ensure_equals("Aditi login uri",
+ login_uris[0],
std::string("https://login.aditi.lindenlab.com/cgi-bin/login.cgi"));
- ensure_equals("Override known grid login page: helper uri is not changed",
- grid[GRID_HELPER_URI_VALUE].asString(),
+ ensure_equals("Aditi helper uri",
+ LLGridManager::getInstance()->getHelperURI("util.aditi.lindenlab.com"),
std::string("http://aditi-secondlife.webdev.lindenlab.com/helpers/"));
- ensure_equals("Override known grid login page: login page is changed",
- grid[GRID_LOGIN_PAGE_VALUE].asString(),
- std::string("myloginpage"));
-
- // Override with login page
- // override custom grid
- gCmdLineGridChoice = "mycustomgridchoice";
- gLoginPage = "myloginpage";
- LLGridManager::getInstance()->initialize("grid_test.xml");
- known_grids = LLGridManager::getInstance()->getKnownGrids();
- ensure_equals("Override custom grid login page: grids are added",
- known_grids.size(), 24);
- LLGridManager::getInstance()->getGridInfo(grid);
- ensure("Override custom grid login page: Command line grid login uri is an array",
- grid[GRID_LOGIN_URI_VALUE].isArray());
- ensure_equals("Override custom grid login page: login uri is not changed",
- grid[GRID_LOGIN_URI_VALUE][0].asString(),
- std::string("https://mycustomgridchoice/cgi-bin/login.cgi"));
- ensure_equals("Override custom grid login page: helper uri is not changed",
- grid[GRID_HELPER_URI_VALUE].asString(),
- std::string("https://mycustomgridchoice/helpers/"));
- ensure_equals("Override custom grid login page: login page is changed",
- grid[GRID_LOGIN_PAGE_VALUE].asString(),
- std::string("myloginpage"));
-
+ ensure_equals("Aditi login page",
+ LLGridManager::getInstance()->getLoginPage("util.aditi.lindenlab.com"),
+ std::string("http://viewer-login.agni.lindenlab.com/"));
+ ensure("Aditi is a system grid",
+ LLGridManager::getInstance()->isSystemGrid("util.aditi.lindenlab.com"));
+
+ // Check the additional grid from the file
+ ensure_equals("alternative grid is in name<->label map",
+ known_grids["altgrid.long.name"],
+ std::string("Alternative Grid"));
+ ensure_equals("alternative grid name is set",
+ LLGridManager::getInstance()->getGrid("altgrid.long.name"),
+ std::string("altgrid.long.name"));
+ ensure_equals("alternative grid id",
+ LLGridManager::getInstance()->getGridId("altgrid.long.name"),
+ std::string("AltGrid"));
+ ensure_equals("alternative grid label",
+ LLGridManager::getInstance()->getGridLabel("altgrid.long.name"),
+ std::string("Alternative Grid"));
+ std::vector<std::string> alt_login_uris;
+ LLGridManager::getInstance()->getLoginURIs(std::string("altgrid.long.name"), alt_login_uris);
+ ensure_equals("Number of login uris for altgrid", 2, alt_login_uris.size());
+ ensure_equals("alternative grid first login uri",
+ alt_login_uris[0],
+ std::string("altgrid/myloginuri1"));
+ ensure_equals("alternative grid second login uri",
+ alt_login_uris[1],
+ std::string("altgrid/myloginuri2"));
+ ensure_equals("alternative grid helper uri",
+ LLGridManager::getInstance()->getHelperURI("altgrid.long.name"),
+ std::string("https://helper1/helpers/"));
+ ensure_equals("alternative grid login page",
+ LLGridManager::getInstance()->getLoginPage("altgrid.long.name"),
+ std::string("altgrid/loginpage"));
+ ensure("alternative grid is NOT a system grid",
+ ! LLGridManager::getInstance()->isSystemGrid("altgrid.long.name"));
+
+ ensure_equals("minimal grid is in name<->label map",
+ known_grids["minimal.long.name"],
+ std::string("minimal.long.name"));
+ ensure_equals("minimal grid name is set",
+ LLGridManager::getInstance()->getGrid("minimal.long.name"),
+ std::string("minimal.long.name"));
+ ensure_equals("minimal grid id",
+ LLGridManager::getInstance()->getGridId("minimal.long.name"),
+ std::string("minimal.long.name"));
+ ensure_equals("minimal grid label",
+ LLGridManager::getInstance()->getGridLabel("minimal.long.name"),
+ std::string("minimal.long.name"));
+
+ LLGridManager::getInstance()->getLoginURIs(std::string("minimal.long.name"), alt_login_uris);
+ ensure_equals("Number of login uris for altgrid", 1, alt_login_uris.size());
+ ensure_equals("minimal grid login uri",
+ alt_login_uris[0],
+ std::string("https://minimal.long.name/cgi-bin/login.cgi"));
+ ensure_equals("minimal grid helper uri",
+ LLGridManager::getInstance()->getHelperURI("minimal.long.name"),
+ std::string("https://minimal.long.name/helpers/"));
+ ensure_equals("minimal grid login page",
+ LLGridManager::getInstance()->getLoginPage("minimal.long.name"),
+ std::string("http://minimal.long.name/app/login/"));
+
}
-
+
+
// validate grid selection
template<> template<>
void viewerNetworkTestObject::test<7>()
- {
- LLSD loginURI = LLSD::emptyArray();
- LLSD grid = LLSD::emptyMap();
+ {
// adding a grid with simply a name will populate the values.
- grid[GRID_VALUE] = "myaddedgrid";
+ llofstream gridfile("grid_test.xml");
+ gridfile << gSampleGridFile;
+ gridfile.close();
LLGridManager::getInstance()->initialize("grid_test.xml");
- LLGridManager::getInstance()->addGrid(grid);
- LLGridManager::getInstance()->setGridChoice("util.agni.lindenlab.com");
- ensure_equals("getGridLabel", LLGridManager::getInstance()->getGridLabel(), std::string("Agni"));
- ensure_equals("getGrid", LLGridManager::getInstance()->getGrid(),
+
+ LLGridManager::getInstance()->setGridChoice("util.agni.lindenlab.com");
+ ensure_equals("getGridLabel",
+ LLGridManager::getInstance()->getGridLabel(),
+ std::string("Second Life Main Grid (Agni)"));
+ ensure_equals("getGridId",
+ LLGridManager::getInstance()->getGridId(),
+ std::string("Agni"));
+ ensure_equals("getGrid",
+ LLGridManager::getInstance()->getGrid(),
std::string("util.agni.lindenlab.com"));
- ensure_equals("getHelperURI", LLGridManager::getInstance()->getHelperURI(),
+ ensure_equals("getHelperURI",
+ LLGridManager::getInstance()->getHelperURI(),
std::string("https://secondlife.com/helpers/"));
- ensure_equals("getLoginPage", LLGridManager::getInstance()->getLoginPage(),
+ ensure_equals("getLoginPage",
+ LLGridManager::getInstance()->getLoginPage(),
std::string("http://viewer-login.agni.lindenlab.com/"));
- ensure_equals("getLoginPage2", LLGridManager::getInstance()->getLoginPage("util.agni.lindenlab.com"),
- std::string("http://viewer-login.agni.lindenlab.com/"));
- ensure("Is Agni a production grid", LLGridManager::getInstance()->isInProductionGrid());
+ ensure_equals("update url base for Agni", // relies on agni being the default
+ std::string("https://update.secondlife.com/update"),
+ LLGridManager::getInstance()->getUpdateServiceURL());
+ ensure("Is Agni a production grid", LLGridManager::getInstance()->isInProductionGrid());
std::vector<std::string> uris;
LLGridManager::getInstance()->getLoginURIs(uris);
- ensure_equals("getLoginURIs size", uris.size(), 1);
- ensure_equals("getLoginURIs", uris[0],
+ ensure_equals("getLoginURIs size", 1, uris.size());
+ ensure_equals("getLoginURIs",
+ uris[0],
std::string("https://login.agni.lindenlab.com/cgi-bin/login.cgi"));
- LLGridManager::getInstance()->setGridChoice("myaddedgrid");
- ensure_equals("getGridLabel", LLGridManager::getInstance()->getGridLabel(), std::string("myaddedgrid"));
- ensure("Is myaddedgrid a production grid", !LLGridManager::getInstance()->isInProductionGrid());
-
- LLGridManager::getInstance()->setFavorite();
- LLGridManager::getInstance()->getGridInfo("myaddedgrid", grid);
- ensure("setting favorite", grid.has(GRID_IS_FAVORITE_VALUE));
- }
-
- // name based grid population
- template<> template<>
- void viewerNetworkTestObject::test<8>()
- {
- LLGridManager::getInstance()->initialize("grid_test.xml");
- LLSD grid = LLSD::emptyMap();
- // adding a grid with simply a name will populate the values.
- grid[GRID_VALUE] = "myaddedgrid";
- LLGridManager::getInstance()->addGrid(grid);
- LLGridManager::getInstance()->getGridInfo("myaddedgrid", grid);
-
- ensure_equals("name based grid has name value",
- grid[GRID_VALUE].asString(),
- std::string("myaddedgrid"));
- ensure_equals("name based grid has label value",
- grid[GRID_LABEL_VALUE].asString(),
- std::string("myaddedgrid"));
- ensure_equals("name based grid has name value",
- grid[GRID_HELPER_URI_VALUE].asString(),
- std::string("https://myaddedgrid/helpers/"));
- ensure_equals("name based grid has name value",
- grid[GRID_LOGIN_PAGE_VALUE].asString(),
- std::string("http://myaddedgrid/app/login/"));
- ensure("name based grid has array loginuri",
- grid[GRID_LOGIN_URI_VALUE].isArray());
- ensure_equals("name based grid has single login uri value",
- grid[GRID_LOGIN_URI_VALUE].size(), 1);
- ensure_equals("Name based grid login uri is correct",
- grid[GRID_LOGIN_URI_VALUE][0].asString(),
- std::string("https://myaddedgrid/cgi-bin/login.cgi"));
- ensure("name based grid is not a favorite yet",
- !grid.has(GRID_IS_FAVORITE_VALUE));
- ensure("name based grid does not have system setting",
- !grid.has(GRID_IS_SYSTEM_GRID_VALUE));
-
- llofstream gridfile("grid_test.xml");
- gridfile << gSampleGridFile;
- gridfile.close();
- }
-
- // persistence of the grid list with an empty gridfile.
- template<> template<>
- void viewerNetworkTestObject::test<9>()
- {
- // try with initial grid list without a grid file,
- // without setting the grid to a saveable favorite.
- LLGridManager::getInstance()->initialize("grid_test.xml");
- LLSD grid = LLSD::emptyMap();
- grid[GRID_VALUE] = std::string("mynewgridname");
- LLGridManager::getInstance()->addGrid(grid);
- LLGridManager::getInstance()->saveFavorites();
- ensure("Grid file exists after saving",
- LLFile::isfile("grid_test.xml"));
- LLGridManager::getInstance()->initialize("grid_test.xml");
- // should not be there
- std::map<std::string, std::string> known_grids = LLGridManager::getInstance()->getKnownGrids();
- ensure("New grid wasn't added to persisted list without being marked a favorite",
- known_grids.find(std::string("mynewgridname")) == known_grids.end());
-
- // mark a grid a favorite to make sure it's persisted
- LLGridManager::getInstance()->addGrid(grid);
- LLGridManager::getInstance()->setGridChoice("mynewgridname");
- LLGridManager::getInstance()->setFavorite();
- LLGridManager::getInstance()->saveFavorites();
- ensure("Grid file exists after saving",
- LLFile::isfile("grid_test.xml"));
- LLGridManager::getInstance()->initialize("grid_test.xml");
- // should not be there
- known_grids = LLGridManager::getInstance()->getKnownGrids();
- ensure("New grid wasn't added to persisted list after being marked a favorite",
- known_grids.find(std::string("mynewgridname")) !=
- known_grids.end());
- }
-
- // persistence of the grid file with existing gridfile
- template<> template<>
- void viewerNetworkTestObject::test<10>()
- {
-
- llofstream gridfile("grid_test.xml");
- gridfile << gSampleGridFile;
- gridfile.close();
-
- LLGridManager::getInstance()->initialize("grid_test.xml");
- LLSD grid = LLSD::emptyMap();
- grid[GRID_VALUE] = std::string("mynewgridname");
- LLGridManager::getInstance()->addGrid(grid);
- LLGridManager::getInstance()->saveFavorites();
- // validate we didn't lose existing favorites
- LLGridManager::getInstance()->initialize("grid_test.xml");
- std::map<std::string, std::string> known_grids = LLGridManager::getInstance()->getKnownGrids();
- ensure("New grid wasn't added to persisted list after being marked a favorite",
- known_grids.find(std::string("grid1")) !=
- known_grids.end());
-
- // add a grid
- LLGridManager::getInstance()->addGrid(grid);
- LLGridManager::getInstance()->setGridChoice("mynewgridname");
- LLGridManager::getInstance()->setFavorite();
- LLGridManager::getInstance()->saveFavorites();
- known_grids = LLGridManager::getInstance()->getKnownGrids();
- ensure("New grid wasn't added to persisted list after being marked a favorite",
- known_grids.find(std::string("grid1")) !=
- known_grids.end());
- known_grids = LLGridManager::getInstance()->getKnownGrids();
- ensure("New grid wasn't added to persisted list after being marked a favorite",
- known_grids.find(std::string("mynewgridname")) !=
- known_grids.end());
+
+ LLGridManager::getInstance()->setGridChoice("altgrid.long.name");
+ ensure_equals("getGridLabel",
+ LLGridManager::getInstance()->getGridLabel(),
+ std::string("Alternative Grid"));
+ ensure_equals("getGridId",
+ LLGridManager::getInstance()->getGridId(),
+ std::string("AltGrid"));
+ ensure("alternative grid is not a system grid",
+ !LLGridManager::getInstance()->isSystemGrid());
+ ensure("alternative grid is not a production grid",
+ !LLGridManager::getInstance()->isInProductionGrid());
}
+
}
diff --git a/indra/newview/tests/llviewershadermgr_stub.cpp b/indra/newview/tests/llviewershadermgr_stub.cpp
index 18eff72f3c..18eff72f3c 100644..100755
--- a/indra/newview/tests/llviewershadermgr_stub.cpp
+++ b/indra/newview/tests/llviewershadermgr_stub.cpp
diff --git a/indra/newview/tests/llviewertexture_stub.cpp b/indra/newview/tests/llviewertexture_stub.cpp
new file mode 100644
index 0000000000..889ab9bea5
--- /dev/null
+++ b/indra/newview/tests/llviewertexture_stub.cpp
@@ -0,0 +1,34 @@
+/**
+ * @file llviewertexture_stub.cpp
+ * @brief stub class to allow unit testing
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+#include "../llviewertexture.h"
+#include "../../llrender/llgltexture.h"
+
+void LLViewerTexture::setBoostLevel(int level)
+{
+}
+
diff --git a/indra/newview/tests/llwlanimator_stub.cpp b/indra/newview/tests/llwlanimator_stub.cpp
index f5e15b2e7b..f5e15b2e7b 100644..100755
--- a/indra/newview/tests/llwlanimator_stub.cpp
+++ b/indra/newview/tests/llwlanimator_stub.cpp
diff --git a/indra/newview/tests/llwldaycycle_stub.cpp b/indra/newview/tests/llwldaycycle_stub.cpp
index a7bc9a7b83..a7bc9a7b83 100644..100755
--- a/indra/newview/tests/llwldaycycle_stub.cpp
+++ b/indra/newview/tests/llwldaycycle_stub.cpp
diff --git a/indra/newview/tests/llwlparammanager_test.cpp b/indra/newview/tests/llwlparammanager_test.cpp
index be0dc9fd0c..be0dc9fd0c 100644..100755
--- a/indra/newview/tests/llwlparammanager_test.cpp
+++ b/indra/newview/tests/llwlparammanager_test.cpp
diff --git a/indra/newview/tests/llwlparamset_stub.cpp b/indra/newview/tests/llwlparamset_stub.cpp
index ccb99db475..ccb99db475 100644..100755
--- a/indra/newview/tests/llwlparamset_stub.cpp
+++ b/indra/newview/tests/llwlparamset_stub.cpp
diff --git a/indra/newview/tests/llworldmap_test.cpp b/indra/newview/tests/llworldmap_test.cpp
index acc6e814bc..84194adb5d 100644..100755
--- a/indra/newview/tests/llworldmap_test.cpp
+++ b/indra/newview/tests/llworldmap_test.cpp
@@ -47,9 +47,9 @@
// * A simulator for a class can be implemented here. Please comment and document thoroughly.
// Stub image calls
-void LLViewerTexture::setBoostLevel(S32 ) { }
-void LLViewerTexture::setAddressMode(LLTexUnit::eTextureAddressMode ) { }
-LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTexture(const LLUUID&, BOOL, LLViewerTexture::EBoostLevel, S8,
+void LLGLTexture::setBoostLevel(S32 ) { }
+void LLGLTexture::setAddressMode(LLTexUnit::eTextureAddressMode ) { }
+LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTexture(const LLUUID&, FTType, BOOL, LLGLTexture::EBoostLevel, S8,
LLGLint, LLGLenum, LLHost ) { return NULL; }
// Stub related map calls
diff --git a/indra/newview/tests/llworldmipmap_test.cpp b/indra/newview/tests/llworldmipmap_test.cpp
index e7ef017760..142d75bcfd 100644..100755
--- a/indra/newview/tests/llworldmipmap_test.cpp
+++ b/indra/newview/tests/llworldmipmap_test.cpp
@@ -42,8 +42,8 @@
// * Do not make any assumption as to how those classes or methods work (i.e. don't copy/paste code)
// * A simulator for a class can be implemented here. Please comment and document thoroughly.
-void LLViewerTexture::setBoostLevel(S32 ) { }
-LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromUrl(const std::string&, BOOL, LLViewerTexture::EBoostLevel, S8,
+void LLGLTexture::setBoostLevel(S32 ) { }
+LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromUrl(const std::string&, FTType, BOOL, LLGLTexture::EBoostLevel, S8,
LLGLint, LLGLenum, const LLUUID& ) { return NULL; }
LLControlGroup::LLControlGroup(const std::string& name) : LLInstanceTracker<LLControlGroup, std::string>(name) { }
diff --git a/indra/newview/tests/llxmlrpclistener_test.cpp b/indra/newview/tests/llxmlrpclistener_test.cpp
index 711c2a3d51..20f913b670 100644..100755
--- a/indra/newview/tests/llxmlrpclistener_test.cpp
+++ b/indra/newview/tests/llxmlrpclistener_test.cpp
@@ -62,8 +62,8 @@ namespace tut
// These variables are required by machinery used by
// LLXMLRPCTransaction. The values reflect reality for this test
// executable; hopefully these values are correct.
- gSavedSettings.declareBOOL("BrowserProxyEnabled", FALSE, "", FALSE); // don't persist
- gSavedSettings.declareBOOL("NoVerifySSLCert", TRUE, "", FALSE); // don't persist
+ gSavedSettings.declareBOOL("BrowserProxyEnabled", FALSE, "", LLControlVariable::PERSIST_NO); // don't persist
+ gSavedSettings.declareBOOL("NoVerifySSLCert", TRUE, "", LLControlVariable::PERSIST_NO); // don't persist
}
// LLEventPump listener signature
diff --git a/indra/newview/tests/test_llxmlrpc_peer.py b/indra/newview/tests/test_llxmlrpc_peer.py
index 281b72a058..281b72a058 100644..100755
--- a/indra/newview/tests/test_llxmlrpc_peer.py
+++ b/indra/newview/tests/test_llxmlrpc_peer.py
diff --git a/indra/newview/tr.lproj/language.txt b/indra/newview/tr.lproj/language.txt
index 44266bf283..44266bf283 100644..100755
--- a/indra/newview/tr.lproj/language.txt
+++ b/indra/newview/tr.lproj/language.txt
diff --git a/indra/newview/uk.lproj/language.txt b/indra/newview/uk.lproj/language.txt
index fbc658f6f9..fbc658f6f9 100644..100755
--- a/indra/newview/uk.lproj/language.txt
+++ b/indra/newview/uk.lproj/language.txt
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 9bf755c8f8..894e368427 100644..100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -28,14 +28,21 @@ $/LicenseInfo$
"""
import sys
import os.path
+import errno
import re
import tarfile
import time
import random
viewer_dir = os.path.dirname(__file__)
-# add llmanifest library to our path so we don't have to muck with PYTHONPATH
-sys.path.append(os.path.join(viewer_dir, '../lib/python/indra/util'))
-from llmanifest import LLManifest, main, proper_windows_path, path_ancestors
+# Add indra/lib/python to our path so we don't have to muck with PYTHONPATH.
+# Put it FIRST because some of our build hosts have an ancient install of
+# indra.util.llmanifest under their system Python!
+sys.path.insert(0, os.path.join(viewer_dir, os.pardir, "lib", "python"))
+from indra.util.llmanifest import LLManifest, main, proper_windows_path, path_ancestors
+try:
+ from llbase import llsd
+except ImportError:
+ from indra.base import llsd
class ViewerManifest(LLManifest):
def is_packaging_viewer(self):
@@ -64,33 +71,71 @@ class ViewerManifest(LLManifest):
# include the entire shaders directory recursively
self.path("shaders")
# include the extracted list of contributors
- contributor_names = self.extract_names("../../doc/contributions.txt")
- self.put_in_file(contributor_names, "contributors.txt")
- self.file_list.append(["../../doc/contributions.txt",self.dst_path_of("contributors.txt")])
+ contributions_path = "../../doc/contributions.txt"
+ contributor_names = self.extract_names(contributions_path)
+ self.put_in_file(contributor_names, "contributors.txt", src=contributions_path)
# include the extracted list of translators
- translator_names = self.extract_names("../../doc/translations.txt")
- self.put_in_file(translator_names, "translators.txt")
- self.file_list.append(["../../doc/translations.txt",self.dst_path_of("translators.txt")])
+ translations_path = "../../doc/translations.txt"
+ translator_names = self.extract_names(translations_path)
+ self.put_in_file(translator_names, "translators.txt", src=translations_path)
# include the list of Lindens (if any)
# see https://wiki.lindenlab.com/wiki/Generated_Linden_Credits
linden_names_path = os.getenv("LINDEN_CREDITS")
- if linden_names_path :
+ if not linden_names_path :
+ print "No 'LINDEN_CREDITS' specified in environment, using built-in list"
+ else:
try:
linden_file = open(linden_names_path,'r')
+ except IOError:
+ print "No Linden names found at '%s', using built-in list" % linden_names_path
+ else:
# all names should be one line, but the join below also converts to a string
linden_names = ', '.join(linden_file.readlines())
- self.put_in_file(linden_names, "lindens.txt")
+ self.put_in_file(linden_names, "lindens.txt", src=linden_names_path)
linden_file.close()
print "Linden names extracted from '%s'" % linden_names_path
- self.file_list.append([linden_names_path,self.dst_path_of("lindens.txt")])
- except IOError:
- print "No Linden names found at '%s', using built-in list" % linden_names_path
- pass
- else :
- print "No 'LINDEN_CREDITS' specified in environment, using built-in list"
# ... and the entire windlight directory
self.path("windlight")
+
+ # ... and the included spell checking dictionaries
+ pkgdir = os.path.join(self.args['build'], os.pardir, 'packages')
+ if self.prefix(src=pkgdir,dst=""):
+ self.path("dictionaries")
+ self.end_prefix(pkgdir)
+
+ # CHOP-955: If we have "sourceid" or "viewer_channel" in the
+ # build process environment, generate it into
+ # settings_install.xml.
+ settings_template = dict(
+ sourceid=dict(Comment='Identify referring agency to Linden web servers',
+ Persist=1,
+ Type='String',
+ Value=''),
+ CmdLineChannel=dict(Comment='Command line specified channel name',
+ Persist=0,
+ Type='String',
+ Value=''))
+ settings_install = {}
+ for key, setting in (("sourceid", "sourceid"),
+ ("channel", "CmdLineChannel")):
+ if key in self.args:
+ # only set if value is non-empty
+ if self.args[key]:
+ # copy corresponding setting from settings_template
+ settings_install[setting] = settings_template[setting].copy()
+ # then fill in Value
+ settings_install[setting]["Value"] = self.args[key]
+ print "Put %s '%s' in settings_install.xml" % (setting, self.args[key])
+
+ # did we actually copy anything into settings_install dict?
+ if settings_install:
+ # put_in_file(src=) need not be an actual pathname; it
+ # only needs to be non-empty
+ self.put_in_file(llsd.format_pretty_xml(settings_install),
+ "settings_install.xml",
+ src="environment")
+
self.end_prefix("app_settings")
if self.prefix(src="character"):
@@ -107,7 +152,6 @@ class ViewerManifest(LLManifest):
# skins
if self.prefix(src="skins"):
- self.path("paths.xml")
# include the entire textures directory recursively
if self.prefix(src="*/textures"):
self.path("*/*.tga")
@@ -125,11 +169,18 @@ class ViewerManifest(LLManifest):
self.path("*/*.xml")
# Local HTML files (e.g. loading screen)
- if self.prefix(src="*/html"):
+ # The claim is that we never use local html files any
+ # longer. But rather than commenting out this block, let's
+ # rename every html subdirectory as html.old. That way, if
+ # we're wrong, a user actually does have the relevant
+ # files; s/he just needs to rename every html.old
+ # directory back to html to recover them.
+ if self.prefix(src="*/html", dst="*/html.old"):
self.path("*.png")
self.path("*/*/*.html")
self.path("*/*/*.gif")
self.end_prefix("*/html")
+
self.end_prefix("skins")
# local_assets dir (for pre-cached textures)
@@ -140,24 +191,9 @@ class ViewerManifest(LLManifest):
# Files in the newview/ directory
self.path("gpu_table.txt")
-
- # The summary.json file gets left in the base checkout dir by
- # build.sh. It's only created for a build.sh build, therefore we
- # have to check whether it exists. :-P
- summary_json = "summary.json"
- summary_json_path = os.path.join(os.pardir, os.pardir, summary_json)
- if os.path.exists(os.path.join(self.get_src_prefix(), summary_json_path)):
- self.path(summary_json_path, summary_json)
- else:
- print "No %s" % os.path.join(self.get_src_prefix(), summary_json_path)
-
- def login_channel(self):
- """Channel reported for login and upgrade purposes ONLY;
- used for A/B testing"""
- # NOTE: Do not return the normal channel if login_channel
- # is not specified, as some code may branch depending on
- # whether or not this is present
- return self.args.get('login_channel')
+ # The summary.json file gets left in the build directory by newview/CMakeLists.txt.
+ if not self.path2basename(os.pardir, "summary.json"):
+ print "No summary.json file"
def grid(self):
return self.args['grid']
@@ -170,16 +206,24 @@ class ViewerManifest(LLManifest):
def channel_lowerword(self):
return self.channel_oneword().lower()
+ def app_name(self):
+ app_suffix='Test'
+ channel_type=self.channel_lowerword()
+ if channel_type.startswith('release') :
+ app_suffix='Viewer'
+ elif re.match('^(beta|project).*',channel_type) :
+ app_suffix=self.channel_unique()
+ return "Second Life "+app_suffix
+
def icon_path(self):
icon_path="icons/"
channel_type=self.channel_lowerword()
- if channel_type == 'release' \
- or channel_type == 'development' \
- :
- icon_path += channel_type
- elif channel_type == 'betaviewer' :
+ print "Icon channel type '%s'" % channel_type
+ if channel_type.startswith('release') :
+ icon_path += 'release'
+ elif re.match('^beta.*',channel_type) :
icon_path += 'beta'
- elif re.match('project.*',channel_type) :
+ elif re.match('^project.*',channel_type) :
icon_path += 'project'
else :
icon_path += 'test'
@@ -189,32 +233,26 @@ class ViewerManifest(LLManifest):
""" Convenience function that returns the command-line flags
for the grid"""
- # Set command line flags relating to the target grid
- grid_flags = ''
- if not self.default_grid():
- grid_flags = "--grid %(grid)s "\
- "--helperuri http://preview-%(grid)s.secondlife.com/helpers/" %\
- {'grid':self.grid()}
-
- # set command line flags for channel
- channel_flags = ''
- if self.login_channel() and self.login_channel() != self.channel():
- # Report a special channel during login, but use default
- channel_flags = '--channel "%s"' % (self.login_channel())
- elif not self.default_channel():
- channel_flags = '--channel "%s"' % self.channel()
-
- # Deal with settings
- setting_flags = ''
- if not self.default_channel() or not self.default_grid():
- if self.default_grid():
- setting_flags = '--settings settings_%s.xml'\
- % self.channel_lowerword()
- else:
- setting_flags = '--settings settings_%s_%s.xml'\
- % (self.grid(), self.channel_lowerword())
-
- return " ".join((channel_flags, grid_flags, setting_flags)).strip()
+ # The original role of this method seems to have been to build a
+ # grid-specific viewer: one that would, on launch, preselect a
+ # particular grid. (Apparently that dates back to when the protocol
+ # between viewer and simulator required them to be updated in
+ # lockstep, so that "the beta grid" required "a beta viewer.") But
+ # those viewer command-line switches no longer work without tweaking
+ # user_settings/grids.xml. In fact, going forward, it's unclear what
+ # use case that would address.
+
+ # This method also set a channel-specific (or grid-and-channel-
+ # specific) user_settings/settings_something.xml file. It has become
+ # clear that saving user settings in a channel-specific file causes
+ # more problems (confusion) than it solves, so we've discontinued that.
+
+ # In fact we now avoid forcing viewer command-line switches at all,
+ # instead introducing a settings_install.xml file. Command-line
+ # switches don't aggregate well; for instance the generated --channel
+ # switch actually prevented the user specifying --channel on the
+ # command line. Settings files have well-defined override semantics.
+ return None
def extract_names(self,src):
try:
@@ -241,13 +279,13 @@ class ViewerManifest(LLManifest):
class WindowsManifest(ViewerManifest):
def final_exe(self):
- if self.default_channel():
- if self.default_grid():
- return "SecondLife.exe"
- else:
- return "SecondLifePreview.exe"
- else:
- return ''.join(self.channel().split()) + '.exe'
+ app_suffix="Test"
+ channel_type=self.channel_lowerword()
+ if channel_type.startswith('release') :
+ app_suffix=''
+ elif re.match('^(beta|project).*',channel_type) :
+ app_suffix=''.join(self.channel_unique().split())
+ return "SecondLife"+app_suffix+".exe"
def test_msvcrt_and_copy_action(self, src, dst):
# This is used to test a dll manifest.
@@ -295,44 +333,23 @@ class WindowsManifest(ViewerManifest):
else:
print "Doesn't exist:", src
- ### DISABLED MANIFEST CHECKING for vs2010. we may need to reenable this
- # shortly. If this hasn't been reenabled by the 2.9 viewer release then it
- # should be deleted -brad
- #def enable_crt_manifest_check(self):
- # if self.is_packaging_viewer():
- # WindowsManifest.copy_action = WindowsManifest.test_msvcrt_and_copy_action
-
- #def enable_no_crt_manifest_check(self):
- # if self.is_packaging_viewer():
- # WindowsManifest.copy_action = WindowsManifest.test_for_no_msvcrt_manifest_and_copy_action
-
- #def disable_manifest_check(self):
- # if self.is_packaging_viewer():
- # del WindowsManifest.copy_action
-
def construct(self):
super(WindowsManifest, self).construct()
- #self.enable_crt_manifest_check()
-
if self.is_packaging_viewer():
# Find secondlife-bin.exe in the 'configuration' dir, then rename it to the result of final_exe.
self.path(src='%s/secondlife-bin.exe' % self.args['configuration'], dst=self.final_exe())
# Plugin host application
- self.path(os.path.join(os.pardir,
- 'llplugin', 'slplugin', self.args['configuration'], "slplugin.exe"),
- "slplugin.exe")
+ self.path2basename(os.path.join(os.pardir,
+ 'llplugin', 'slplugin', self.args['configuration']),
+ "slplugin.exe")
- #self.disable_manifest_check()
-
- self.path(src="../viewer_components/updater/scripts/windows/update_install.bat", dst="update_install.bat")
+ self.path2basename("../viewer_components/updater/scripts/windows", "update_install.bat")
# Get shared libs from the shared libs staging directory
if self.prefix(src=os.path.join(os.pardir, 'sharedlibs', self.args['configuration']),
dst=""):
- #self.enable_crt_manifest_check()
-
# Get llcommon and deps. If missing assume static linkage and continue.
try:
self.path('llcommon.dll')
@@ -344,8 +361,6 @@ class WindowsManifest(ViewerManifest):
print err.message
print "Skipping llcommon.dll (assuming llcommon was linked statically)"
- #self.disable_manifest_check()
-
# Mesh 3rd party libs needed for auto LOD and collada reading
try:
if self.args['configuration'].lower() == 'debug':
@@ -358,12 +373,14 @@ class WindowsManifest(ViewerManifest):
print err.message
print "Skipping COLLADA and GLOD libraries (assumming linked statically)"
-
- # Get fmod dll, continue if missing
+ # Get fmodex dll, continue if missing
try:
- self.path("fmod.dll")
+ if self.args['configuration'].lower() == 'debug':
+ self.path("fmodexL.dll")
+ else:
+ self.path("fmodex.dll")
except:
- print "Skipping fmod.dll"
+ print "Skipping fmodex audio library(assuming other audio engine)"
# For textures
if self.args['configuration'].lower() == 'debug':
@@ -388,11 +405,15 @@ class WindowsManifest(ViewerManifest):
self.path("zlib1.dll")
self.path("vivoxplatform.dll")
self.path("vivoxoal.dll")
+ self.path("ca-bundle.crt")
# Security
self.path("ssleay32.dll")
self.path("libeay32.dll")
+ # Hunspell
+ self.path("libhunspell.dll")
+
# For google-perftools tcmalloc allocator.
try:
if self.args['configuration'].lower() == 'debug':
@@ -408,8 +429,6 @@ class WindowsManifest(ViewerManifest):
self.path("featuretable.txt")
self.path("featuretable_xp.txt")
- #self.enable_no_crt_manifest_check()
-
# Media plugins - QuickTime
if self.prefix(src='../media_plugins/quicktime/%s' % self.args['configuration'], dst="llplugin"):
self.path("media_plugin_quicktime.dll")
@@ -489,15 +508,10 @@ class WindowsManifest(ViewerManifest):
self.end_prefix()
- #self.disable_manifest_check()
-
# pull in the crash logger and updater from other projects
# tag:"crash-logger" here as a cue to the exporter
self.path(src='../win_crash_logger/%s/windows-crash-logger.exe' % self.args['configuration'],
dst="win_crash_logger.exe")
-# For CHOP-397, windows updater no longer used.
-# self.path(src='../win_updater/%s/windows-updater.exe' % self.args['configuration'],
-# dst="updater.exe")
if not self.is_packaging_viewer():
self.package_file = "copied_deps"
@@ -527,6 +541,7 @@ class WindowsManifest(ViewerManifest):
result += 'File ' + pkg_file + '\n'
else:
result += 'Delete ' + wpath(os.path.join('$INSTDIR', rel_file)) + '\n'
+
# at the end of a delete, just rmdir all the directories
if not install:
deleted_file_dirs = [os.path.dirname(pair[1].replace(self.get_dst_prefix()+os.path.sep,'')) for pair in self.file_list]
@@ -554,11 +569,11 @@ class WindowsManifest(ViewerManifest):
'final_exe' : self.final_exe(),
'grid':self.args['grid'],
'grid_caps':self.args['grid'].upper(),
- # escape quotes becase NSIS doesn't handle them well
- 'flags':self.flags_list().replace('"', '$\\"'),
+ 'flags':'',
'channel':self.channel(),
'channel_oneword':self.channel_oneword(),
'channel_unique':self.channel_unique(),
+ 'subchannel_underscores':'_'.join(self.channel_unique().split())
}
version_vars = """
@@ -580,7 +595,7 @@ class WindowsManifest(ViewerManifest):
Caption "Second Life"
"""
else:
- # beta grid viewer
+ # alternate grid viewer
installer_file = "Second_Life_%(version_dashes)s_(%(grid_caps)s)_Setup.exe"
grid_vars_template = """
OutFile "%(installer_file)s"
@@ -592,8 +607,8 @@ class WindowsManifest(ViewerManifest):
Caption "Second Life %(grid)s ${VERSION}"
"""
else:
- # some other channel on some grid
- installer_file = "Second_Life_%(version_dashes)s_%(channel_oneword)s_Setup.exe"
+ # some other channel (grid name not used)
+ installer_file = "Second_Life_%(version_dashes)s_%(subchannel_underscores)s_Setup.exe"
grid_vars_template = """
OutFile "%(installer_file)s"
!define INSTFLAGS "%(flags)s"
@@ -607,6 +622,9 @@ class WindowsManifest(ViewerManifest):
installer_file = self.args['installer_name']
else:
installer_file = installer_file % substitution_strings
+ if len(self.args['package_id']) > 0:
+ installer_file = installer_file.replace(self.args['package_id'], "")
+ installer_file = installer_file.replace(".exe", self.args['package_id'] + ".exe")
substitution_strings['installer_file'] = installer_file
tempfile = "secondlife_setup_tmp.nsi"
@@ -655,12 +673,15 @@ class DarwinManifest(ViewerManifest):
self.path(self.args['configuration'] + "/Second Life.app", dst="")
if self.prefix(src="", dst="Contents"): # everything goes in Contents
- self.path("Info-SecondLife.plist", dst="Info.plist")
+ self.path("Info.plist", dst="Info.plist")
# copy additional libs in <bundle>/Contents/MacOS/
self.path("../packages/lib/release/libndofdev.dylib", dst="Resources/libndofdev.dylib")
+ self.path("../packages/lib/release/libhunspell-1.3.0.dylib", dst="Resources/libhunspell-1.3.0.dylib")
- self.path("../viewer_components/updater/scripts/darwin/update_install", "MacOS/update_install")
+ if self.prefix(dst="MacOS"):
+ self.path2basename("../viewer_components/updater/scripts/darwin", "*.py")
+ self.end_prefix()
# most everything goes in the Resources directory
if self.prefix(src="", dst="Resources"):
@@ -682,7 +703,11 @@ class DarwinManifest(ViewerManifest):
self.path("SecondLife.nib")
# Translations
- self.path("English.lproj")
+ self.path("English.lproj/language.txt")
+ self.replace_in(src="English.lproj/InfoPlist.strings",
+ dst="English.lproj/InfoPlist.strings",
+ searchdict={'%%VERSION%%':'.'.join(self.args['version'])}
+ )
self.path("German.lproj")
self.path("Japanese.lproj")
self.path("Korean.lproj")
@@ -699,91 +724,82 @@ class DarwinManifest(ViewerManifest):
self.path("uk.lproj")
self.path("zh-Hans.lproj")
- libdir = "../packages/lib/release"
- dylibs = {}
+ def path_optional(src, dst):
+ """
+ For a number of our self.path() calls, not only do we want
+ to deal with the absence of src, we also want to remember
+ which were present. Return either an empty list (absent)
+ or a list containing dst (present). Concatenate these
+ return values to get a list of all libs that are present.
+ """
+ if self.path(src, dst):
+ return [dst]
+ print "Skipping %s" % dst
+ return []
- # Need to get the llcommon dll from any of the build directories as well
- lib = "llcommon"
- libfile = "lib%s.dylib" % lib
- try:
- self.path(self.find_existing_file(os.path.join(os.pardir,
- lib,
- self.args['configuration'],
- libfile),
- os.path.join(libdir, libfile)),
- dst=libfile)
- except RuntimeError:
- print "Skipping %s" % libfile
- dylibs[lib] = False
- else:
- dylibs[lib] = True
-
- if dylibs["llcommon"]:
- for libfile in ("libapr-1.0.dylib",
- "libaprutil-1.0.dylib",
- "libexpat.1.5.2.dylib",
- "libexception_handler.dylib",
- "libGLOD.dylib",
- "libcollada14dom.dylib"
- ):
- self.path(os.path.join(libdir, libfile), libfile)
-
- # SLVoice and vivox lols
- for libfile in ('libsndfile.dylib', 'libvivoxoal.dylib', 'libortp.dylib', \
- 'libvivoxsdk.dylib', 'libvivoxplatform.dylib', 'SLVoice') :
- self.path(os.path.join(libdir, libfile), libfile)
-
- try:
- # FMOD for sound
- self.path(self.args['configuration'] + "/libfmodwrapper.dylib", "libfmodwrapper.dylib")
- except:
- print "Skipping FMOD - not found"
+ libdir = "../packages/lib/release"
+ # dylibs is a list of all the .dylib files we expect to need
+ # in our bundled sub-apps. For each of these we'll create a
+ # symlink from sub-app/Contents/Resources to the real .dylib.
+ # Need to get the llcommon dll from any of the build directories as well.
+ libfile = "libllcommon.dylib"
+ dylibs = path_optional(self.find_existing_file(os.path.join(os.pardir,
+ "llcommon",
+ self.args['configuration'],
+ libfile),
+ os.path.join(libdir, libfile)),
+ dst=libfile)
+
+ for libfile in (
+ "libapr-1.0.dylib",
+ "libaprutil-1.0.dylib",
+ "libcollada14dom.dylib",
+ "libexpat.1.5.2.dylib",
+ "libexception_handler.dylib",
+ "libfmodex.dylib",
+ "libGLOD.dylib",
+ ):
+ dylibs += path_optional(os.path.join(libdir, libfile), libfile)
+
+ # SLVoice and vivox lols, no symlinks needed
+ for libfile in (
+ 'libortp.dylib',
+ 'libsndfile.dylib',
+ 'libvivoxoal.dylib',
+ 'libvivoxsdk.dylib',
+ 'libvivoxplatform.dylib',
+ 'ca-bundle.crt',
+ 'SLVoice',
+ ):
+ self.path2basename(libdir, libfile)
# our apps
- self.path("../mac_crash_logger/" + self.args['configuration'] + "/mac-crash-logger.app", "mac-crash-logger.app")
- self.path("../mac_updater/" + self.args['configuration'] + "/mac-updater.app", "mac-updater.app")
-
- # plugin launcher
- self.path("../llplugin/slplugin/" + self.args['configuration'] + "/SLPlugin.app", "SLPlugin.app")
-
- # our apps dependencies on shared libs
- if dylibs["llcommon"]:
- mac_crash_logger_res_path = self.dst_path_of("mac-crash-logger.app/Contents/Resources")
- mac_updater_res_path = self.dst_path_of("mac-updater.app/Contents/Resources")
- slplugin_res_path = self.dst_path_of("SLPlugin.app/Contents/Resources")
- for libfile in ("libllcommon.dylib",
- "libapr-1.0.dylib",
- "libaprutil-1.0.dylib",
- "libexpat.1.5.2.dylib",
- "libexception_handler.dylib",
- "libGLOD.dylib",
- "libcollada14dom.dylib"
- ):
- target_lib = os.path.join('../../..', libfile)
- self.run_command("ln -sf %(target)r %(link)r" %
- {'target': target_lib,
- 'link' : os.path.join(mac_crash_logger_res_path, libfile)}
- )
- self.run_command("ln -sf %(target)r %(link)r" %
- {'target': target_lib,
- 'link' : os.path.join(mac_updater_res_path, libfile)}
- )
- self.run_command("ln -sf %(target)r %(link)r" %
- {'target': target_lib,
- 'link' : os.path.join(slplugin_res_path, libfile)}
- )
+ for app_bld_dir, app in (("mac_crash_logger", "mac-crash-logger.app"),
+ # plugin launcher
+ (os.path.join("llplugin", "slplugin"), "SLPlugin.app"),
+ ):
+ self.path2basename(os.path.join(os.pardir,
+ app_bld_dir, self.args['configuration']),
+ app)
+
+ # our apps dependencies on shared libs
+ # for each app, for each dylib we collected in dylibs,
+ # create a symlink to the real copy of the dylib.
+ resource_path = self.dst_path_of(os.path.join(app, "Contents", "Resources"))
+ for libfile in dylibs:
+ symlinkf(os.path.join(os.pardir, os.pardir, os.pardir, libfile),
+ os.path.join(resource_path, libfile))
# plugins
if self.prefix(src="", dst="llplugin"):
- self.path("../media_plugins/quicktime/" + self.args['configuration'] + "/media_plugin_quicktime.dylib", "media_plugin_quicktime.dylib")
- self.path("../media_plugins/webkit/" + self.args['configuration'] + "/media_plugin_webkit.dylib", "media_plugin_webkit.dylib")
- self.path("../packages/lib/release/libllqtwebkit.dylib", "libllqtwebkit.dylib")
+ self.path2basename("../media_plugins/quicktime/" + self.args['configuration'],
+ "media_plugin_quicktime.dylib")
+ self.path2basename("../media_plugins/webkit/" + self.args['configuration'],
+ "media_plugin_webkit.dylib")
+ self.path2basename("../packages/lib/release", "libllqtwebkit.dylib")
self.end_prefix("llplugin")
- # command line arguments for connecting to the proper grid
- self.put_in_file(self.flags_list(), 'arguments.txt')
-
self.end_prefix("Resources")
self.end_prefix("Contents")
@@ -801,13 +817,33 @@ class DarwinManifest(ViewerManifest):
def copy_finish(self):
# Force executable permissions to be set for scripts
# see CHOP-223 and http://mercurial.selenic.com/bts/issue1802
- for script in 'Contents/MacOS/update_install',:
+ for script in 'Contents/MacOS/update_install.py',:
self.run_command("chmod +x %r" % os.path.join(self.get_dst_prefix(), script))
def package_finish(self):
- channel_standin = 'Second Life Viewer' # hah, our default channel is not usable on its own
- if not self.default_channel():
- channel_standin = self.channel()
+ # Sign the app if requested.
+ if 'signature' in self.args:
+ identity = self.args['signature']
+ if identity == '':
+ identity = 'Developer ID Application'
+
+ # Look for an environment variable set via build.sh when running in Team City.
+ try:
+ build_secrets_checkout = os.environ['build_secrets_checkout']
+ except KeyError:
+ pass
+ else:
+ # variable found so use it to unlock keyvchain followed by codesign
+ home_path = os.environ['HOME']
+ keychain_pwd_path = os.path.join(build_secrets_checkout,'code-signing-osx','password.txt')
+ keychain_pwd = open(keychain_pwd_path).read().rstrip()
+
+ self.run_command('security unlock-keychain -p "%s" "%s/Library/Keychains/viewer.keychain"' % ( keychain_pwd, home_path ) )
+ self.run_command('codesign --verbose --force --keychain "%(home_path)s/Library/Keychains/viewer.keychain" --sign %(identity)r %(bundle)r' % {
+ 'home_path' : home_path,
+ 'identity': identity,
+ 'bundle': self.get_dst_prefix()
+ })
imagename="SecondLife_" + '_'.join(self.args['version'])
@@ -816,7 +852,9 @@ class DarwinManifest(ViewerManifest):
volname="Second Life Installer" # DO NOT CHANGE without understanding comment above
- if self.default_channel():
+ if len(self.args['package_id']) > 0:
+ imagename = imagename + self.args['package_id']
+ elif self.default_channel():
if not self.default_grid():
# beta case
imagename = imagename + '_' + self.args['grid'].upper()
@@ -829,7 +867,7 @@ class DarwinManifest(ViewerManifest):
# make sure we don't have stale files laying about
self.remove(sparsename, finalname)
- self.run_command('hdiutil create %(sparse)r -volname %(vol)r -fs HFS+ -type SPARSE -megabytes 700 -layout SPUD' % {
+ self.run_command('hdiutil create %(sparse)r -volname %(vol)r -fs HFS+ -type SPARSE -megabytes 1000 -layout SPUD' % {
'sparse':sparsename,
'vol':volname})
@@ -846,10 +884,7 @@ class DarwinManifest(ViewerManifest):
# Copy everything in to the mounted .dmg
- if self.default_channel() and not self.default_grid():
- app_name = "Second Life " + self.args['grid']
- else:
- app_name = channel_standin.strip()
+ app_name = self.app_name()
# Hack:
# Because there is no easy way to coerce the Finder into positioning
@@ -907,6 +942,7 @@ class DarwinManifest(ViewerManifest):
print "Converting temp disk image to final disk image"
self.run_command('hdiutil convert %(sparse)r -format UDZO -imagekey zlib-level=9 -o %(final)r' % {'sparse':sparsename, 'final':finalname})
+ self.run_command('hdiutil internet-enable -yes %(final)r' % {'final':finalname})
# get rid of the temp file
self.package_file = finalname
self.remove(sparsename)
@@ -920,20 +956,21 @@ class LinuxManifest(ViewerManifest):
self.path("client-readme-voice.txt","README-linux-voice.txt")
self.path("client-readme-joystick.txt","README-linux-joystick.txt")
self.path("wrapper.sh","secondlife")
- self.path("handle_secondlifeprotocol.sh", "etc/handle_secondlifeprotocol.sh")
- self.path("register_secondlifeprotocol.sh", "etc/register_secondlifeprotocol.sh")
- self.path("refresh_desktop_app_entry.sh", "etc/refresh_desktop_app_entry.sh")
- self.path("launch_url.sh","etc/launch_url.sh")
+ if self.prefix(src="", dst="etc"):
+ self.path("handle_secondlifeprotocol.sh")
+ self.path("register_secondlifeprotocol.sh")
+ self.path("refresh_desktop_app_entry.sh")
+ self.path("launch_url.sh")
+ self.end_prefix("etc")
self.path("install.sh")
self.end_prefix("linux_tools")
- # Create an appropriate gridargs.dat for this package, denoting required grid.
- self.put_in_file(self.flags_list(), 'etc/gridargs.dat')
-
- self.path("secondlife-bin","bin/do-not-directly-run-secondlife-bin")
- self.path("../linux_crash_logger/linux-crash-logger","bin/linux-crash-logger.bin")
- self.path("../linux_updater/linux-updater", "bin/linux-updater.bin")
- self.path("../llplugin/slplugin/SLPlugin", "bin/SLPlugin")
+ if self.prefix(src="", dst="bin"):
+ self.path("secondlife-bin","do-not-directly-run-secondlife-bin")
+ self.path("../linux_crash_logger/linux-crash-logger","linux-crash-logger.bin")
+ self.path2basename("../llplugin/slplugin", "SLPlugin")
+ self.path2basename("../viewer_components/updater/scripts/linux", "update_install")
+ self.end_prefix("bin")
if self.prefix("res-sdl"):
self.path("*")
@@ -949,17 +986,13 @@ class LinuxManifest(ViewerManifest):
self.end_prefix("res-sdl")
self.end_prefix(icon_path)
- self.path("../viewer_components/updater/scripts/linux/update_install", "bin/update_install")
-
# plugins
if self.prefix(src="", dst="bin/llplugin"):
- self.path("../media_plugins/webkit/libmedia_plugin_webkit.so", "libmedia_plugin_webkit.so")
+ self.path2basename("../media_plugins/webkit", "libmedia_plugin_webkit.so")
self.path("../media_plugins/gstreamer010/libmedia_plugin_gstreamer010.so", "libmedia_plugin_gstreamer.so")
self.end_prefix("bin/llplugin")
- try:
- self.path("../llcommon/libllcommon.so", "lib/libllcommon.so")
- except:
+ if not self.path("../llcommon/libllcommon.so", "lib/libllcommon.so"):
print "Skipping llcommon.so (assuming llcommon was linked statically)"
self.path("featuretable_linux.txt")
@@ -982,10 +1015,9 @@ class LinuxManifest(ViewerManifest):
installer_name += '_' + self.args['grid'].upper()
else:
installer_name += '_' + self.channel_oneword().upper()
+ installer_name = installer_name + self.args['package_id']
- if self.args['buildtype'].lower() == 'release' and self.is_packaging_viewer():
- print "* Going strip-crazy on the packaged binaries, since this is a RELEASE build"
- self.run_command("find %(d)r/bin %(d)r/lib -type f \\! -name update_install | xargs --no-run-if-empty strip -S" % {'d': self.get_dst_prefix()} ) # makes some small assumptions about our packaged dir structure
+ self.strip_binaries()
# Fix access permissions
self.run_command("""
@@ -1020,6 +1052,11 @@ class LinuxManifest(ViewerManifest):
'dst': self.get_dst_prefix(),
'inst': self.build_path_of(installer_name)})
+ def strip_binaries(self):
+ if self.args['buildtype'].lower() == 'release' and self.is_packaging_viewer():
+ print "* Going strip-crazy on the packaged binaries, since this is a RELEASE build"
+ self.run_command(r"find %(d)r/bin %(d)r/lib -type f \! -name update_install | xargs --no-run-if-empty strip -S" % {'d': self.get_dst_prefix()} ) # makes some small assumptions about our packaged dir structure
+
class Linux_i686Manifest(LinuxManifest):
def construct(self):
super(Linux_i686Manifest, self).construct()
@@ -1027,49 +1064,70 @@ class Linux_i686Manifest(LinuxManifest):
if self.prefix("../packages/lib/release", dst="lib"):
self.path("libapr-1.so")
self.path("libapr-1.so.0")
- self.path("libapr-1.so.0.4.2")
+ self.path("libapr-1.so.0.4.5")
self.path("libaprutil-1.so")
self.path("libaprutil-1.so.0")
- self.path("libaprutil-1.so.0.3.10")
- self.path("libbreakpad_client.so.0.0.0")
- self.path("libbreakpad_client.so.0")
- self.path("libbreakpad_client.so")
+ self.path("libaprutil-1.so.0.4.1")
+ self.path("libboost_context-mt.so.*")
+ self.path("libboost_filesystem-mt.so.*")
+ self.path("libboost_program_options-mt.so.*")
+ self.path("libboost_regex-mt.so.*")
+ self.path("libboost_signals-mt.so.*")
+ self.path("libboost_system-mt.so.*")
+ self.path("libboost_thread-mt.so.*")
self.path("libcollada14dom.so")
- self.path("libdb-5.1.so")
- self.path("libdb-5.so")
- self.path("libdb.so")
- self.path("libcrypto.so.1.0.0")
- self.path("libexpat.so.1.5.2")
+ self.path("libdb*.so")
+ self.path("libcrypto.so.*")
+ self.path("libexpat.so.*")
self.path("libssl.so.1.0.0")
- self.path("libglod.so")
+ self.path("libGLOD.so")
self.path("libminizip.so")
- self.path("libuuid.so")
- self.path("libuuid.so.16")
- self.path("libuuid.so.16.0.22")
- self.path("libSDL-1.2.so.0.11.3")
- self.path("libSDL-1.2.so.0")
- self.path("libdirectfb-1.4.so.5.0.4")
+ self.path("libuuid.so*")
+ self.path("libSDL-1.2.so.*")
+ self.path("libdirectfb-1.*.so.*")
+ self.path("libfusion-1.*.so.*")
+ self.path("libdirect-1.*.so.*")
+ self.path("libopenjpeg.so*")
self.path("libdirectfb-1.4.so.5")
- self.path("libfusion-1.4.so.5.0.4")
self.path("libfusion-1.4.so.5")
- self.path("libdirect-1.4.so.5.0.4")
- self.path("libdirect-1.4.so.5")
- self.path("libopenjpeg.so.1.4.0")
- self.path("libopenjpeg.so.1")
- self.path("libopenjpeg.so")
+ self.path("libdirect-1.4.so.5*")
+ self.path("libhunspell-1.3.so*")
self.path("libalut.so")
self.path("libopenal.so", "libopenal.so.1")
self.path("libopenal.so", "libvivoxoal.so.1") # vivox's sdk expects this soname
- self.path("libfontconfig.so.1.4.4")
- self.path("libtcmalloc.so", "libtcmalloc.so") #formerly called google perf tools
- self.path("libtcmalloc.so.0", "libtcmalloc.so.0") #formerly called google perf tools
- self.path("libtcmalloc.so.0.1.0", "libtcmalloc.so.0.1.0") #formerly called google perf tools
+ # KLUDGE: As of 2012-04-11, the 'fontconfig' package installs
+ # libfontconfig.so.1.4.4, along with symlinks libfontconfig.so.1
+ # and libfontconfig.so. Before we added support for library-file
+ # wildcards, though, this self.path() call specifically named
+ # libfontconfig.so.1.4.4 WITHOUT also copying the symlinks. When I
+ # (nat) changed the call to self.path("libfontconfig.so.*"), we
+ # ended up with the libfontconfig.so.1 symlink in the target
+ # directory as well. But guess what! At least on Ubuntu 10.04,
+ # certain viewer fonts look terrible with libfontconfig.so.1
+ # present in the target directory. Removing that symlink suffices
+ # to improve them. I suspect that means we actually do better when
+ # the viewer fails to find our packaged libfontconfig.so*, falling
+ # back on the system one instead -- but diagnosing and fixing that
+ # is a bit out of scope for the present project. Meanwhile, this
+ # particular wildcard specification gets us exactly what the
+ # previous call did, without having to explicitly state the
+ # version number.
+ self.path("libfontconfig.so.*.*")
+ try:
+ self.path("libtcmalloc.so*") #formerly called google perf tools
+ pass
+ except:
+ print "tcmalloc files not found, skipping"
+ pass
+
try:
- self.path("libfmod-3.75.so")
+ self.path("libfmodex-*.so")
+ self.path("libfmodex.so")
pass
except:
- print "Skipping libfmod-3.75.so - not found"
+ print "Skipping libfmodex.so - not found"
pass
+
self.end_prefix("lib")
# Vivox runtimes
@@ -1084,9 +1142,7 @@ class Linux_i686Manifest(LinuxManifest):
self.path("libvivoxplatform.so")
self.end_prefix("lib")
- if self.args['buildtype'].lower() == 'release' and self.is_packaging_viewer():
- print "* Going strip-crazy on the packaged binaries, since this is a RELEASE build"
- self.run_command("find %(d)r/bin %(d)r/lib -type f \\! -name update_install | xargs --no-run-if-empty strip -S" % {'d': self.get_dst_prefix()} ) # makes some small assumptions about our packaged dir structure
+ self.strip_binaries()
class Linux_x86_64Manifest(LinuxManifest):
@@ -1098,5 +1154,25 @@ class Linux_x86_64Manifest(LinuxManifest):
################################################################
+def symlinkf(src, dst):
+ """
+ Like ln -sf, but uses os.symlink() instead of running ln.
+ """
+ try:
+ os.symlink(src, dst)
+ except OSError, err:
+ if err.errno != errno.EEXIST:
+ raise
+ # We could just blithely attempt to remove and recreate the target
+ # file, but that strategy doesn't work so well if we don't have
+ # permissions to remove it. Check to see if it's already the
+ # symlink we want, which is the usual reason for EEXIST.
+ if not (os.path.islink(dst) and os.readlink(dst) == src):
+ # Here either dst isn't a symlink or it's the wrong symlink.
+ # Remove and recreate. Caller will just have to deal with any
+ # exceptions at this stage.
+ os.remove(dst)
+ os.symlink(src, dst)
+
if __name__ == "__main__":
main()
diff --git a/indra/newview/zh-Hans.lproj/language.txt b/indra/newview/zh-Hans.lproj/language.txt
index 147d659917..147d659917 100644..100755
--- a/indra/newview/zh-Hans.lproj/language.txt
+++ b/indra/newview/zh-Hans.lproj/language.txt
diff --git a/indra/test/CMakeLists.txt b/indra/test/CMakeLists.txt
index 816f1d7175..31e1d89c68 100644..100755
--- a/indra/test/CMakeLists.txt
+++ b/indra/test/CMakeLists.txt
@@ -28,6 +28,10 @@ include_directories(
${GOOGLEMOCK_INCLUDE_DIRS}
${TUT_INCLUDE_DIR}
)
+include_directories(SYSTEM
+ ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+ ${LLXML_SYSTEM_INCLUDE_DIRS}
+ )
set(test_SOURCE_FILES
io.cpp
diff --git a/indra/test/blowfish.1.bin b/indra/test/blowfish.1.bin
index 61286e45e3..61286e45e3 100644..100755
--- a/indra/test/blowfish.1.bin
+++ b/indra/test/blowfish.1.bin
diff --git a/indra/test/blowfish.2.bin b/indra/test/blowfish.2.bin
index ef72d96bbf..ef72d96bbf 100644..100755
--- a/indra/test/blowfish.2.bin
+++ b/indra/test/blowfish.2.bin
Binary files differ
diff --git a/indra/test/blowfish.digits.txt b/indra/test/blowfish.digits.txt
index fce1fed943..fce1fed943 100644..100755
--- a/indra/test/blowfish.digits.txt
+++ b/indra/test/blowfish.digits.txt
diff --git a/indra/test/catch_and_store_what_in.h b/indra/test/catch_and_store_what_in.h
new file mode 100755
index 0000000000..59f8cc0085
--- /dev/null
+++ b/indra/test/catch_and_store_what_in.h
@@ -0,0 +1,86 @@
+/**
+ * @file catch_and_store_what_in.h
+ * @author Nat Goodspeed
+ * @date 2012-02-15
+ * @brief CATCH_AND_STORE_WHAT_IN() macro
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Copyright (c) 2012, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+#if ! defined(LL_CATCH_AND_STORE_WHAT_IN_H)
+#define LL_CATCH_AND_STORE_WHAT_IN_H
+
+/**
+ * Idiom useful for test programs: catch an expected exception, store its
+ * what() string in a specified std::string variable. From there the caller
+ * can do things like:
+ * @code
+ * ensure("expected exception not thrown", ! string.empty());
+ * @endcode
+ * or
+ * @code
+ * ensure_contains("exception doesn't mention blah", string, "blah");
+ * @endcode
+ * etc.
+ *
+ * The trouble is that when linking to a dynamic libllcommon.so on Linux, we
+ * generally fail to catch the specific exception. Oddly, we can catch it as
+ * std::runtime_error and validate its typeid().name(), so we do -- but that's
+ * a lot of boilerplate per test. Encapsulate with this macro. Usage:
+ *
+ * @code
+ * std::string threw;
+ * try
+ * {
+ * some_call_that_should_throw_Foo();
+ * }
+ * CATCH_AND_STORE_WHAT_IN(threw, Foo)
+ * ensure("some_call_that_should_throw_Foo() didn't throw", ! threw.empty());
+ * @endcode
+ */
+#define CATCH_AND_STORE_WHAT_IN(THREW, EXCEPTION) \
+catch (const EXCEPTION& ex) \
+{ \
+ (THREW) = ex.what(); \
+} \
+CATCH_MISSED_LINUX_EXCEPTION(THREW, EXCEPTION)
+
+#ifndef LL_LINUX
+#define CATCH_MISSED_LINUX_EXCEPTION(THREW, EXCEPTION) \
+ /* only needed on Linux */
+#else // LL_LINUX
+
+#define CATCH_MISSED_LINUX_EXCEPTION(THREW, EXCEPTION) \
+catch (const std::runtime_error& ex) \
+{ \
+ /* This clause is needed on Linux, on the viewer side, because */ \
+ /* the exception isn't caught by catch (const EXCEPTION&). */ \
+ /* But if the expected exception was thrown, allow the test to */ \
+ /* succeed anyway. Not sure how else to handle this odd case. */ \
+ if (std::string(typeid(ex).name()) == typeid(EXCEPTION).name()) \
+ { \
+ /* std::cerr << "Caught " << typeid(ex).name() */ \
+ /* << " with Linux workaround" << std::endl; */ \
+ (THREW) = ex.what(); \
+ /*std::cout << ex.what() << std::endl;*/ \
+ } \
+ else \
+ { \
+ /* We don't even recognize this exception. Let it propagate */ \
+ /* out to TUT to fail the test. */ \
+ throw; \
+ } \
+} \
+catch (...) \
+{ \
+ std::cerr << "Failed to catch expected exception " \
+ << #EXCEPTION << "!" << std::endl; \
+ /* This indicates a problem in the test that should be addressed. */ \
+ throw; \
+}
+
+#endif // LL_LINUX
+
+#endif /* ! defined(LL_CATCH_AND_STORE_WHAT_IN_H) */
diff --git a/indra/test/debug.h b/indra/test/debug.h
index d61eba651b..d61eba651b 100644..100755
--- a/indra/test/debug.h
+++ b/indra/test/debug.h
diff --git a/indra/test/io.cpp b/indra/test/io.cpp
index ce747f667d..e776a2a3be 100644..100755
--- a/indra/test/io.cpp
+++ b/indra/test/io.cpp
@@ -1140,7 +1140,7 @@ namespace tut
bool connected = client->blockingConnect(server_host);
ensure("Connected to server", connected);
lldebugs << "connected" << llendl;
- F32 elapsed = pump_loop(mPump,0.1f);
+ pump_loop(mPump,0.1f);
count = mPump->runningChains();
ensure_equals("server chain onboard", count, 2);
lldebugs << "** Client is connected." << llendl;
@@ -1156,20 +1156,20 @@ namespace tut
chain.clear();
// pump for a bit and make sure all 3 chains are running
- elapsed = pump_loop(mPump,0.1f);
+ pump_loop(mPump,0.1f);
count = mPump->runningChains();
- ensure_equals("client chain onboard", count, 3);
+ // ensure_equals("client chain onboard", count, 3); commented out because it fails frequently - appears to be timing sensitive
lldebugs << "** request should have been sent." << llendl;
// pump for long enough the the client socket closes, and the
// server socket should not be closed yet.
- elapsed = pump_loop(mPump,0.2f);
+ pump_loop(mPump,0.2f);
count = mPump->runningChains();
ensure_equals("client chain timed out ", count, 2);
lldebugs << "** client chain should be closed." << llendl;
// At this point, the socket should be closed by the timeout
- elapsed = pump_loop(mPump,1.0f);
+ pump_loop(mPump,1.0f);
count = mPump->runningChains();
ensure_equals("accepted socked close", count, 1);
lldebugs << "** Sleeper should have timed out.." << llendl;
diff --git a/indra/test/llapp_tut.cpp b/indra/test/llapp_tut.cpp
index aa5c0672e6..aa5c0672e6 100644..100755
--- a/indra/test/llapp_tut.cpp
+++ b/indra/test/llapp_tut.cpp
diff --git a/indra/test/llassetuploadqueue_tut.cpp b/indra/test/llassetuploadqueue_tut.cpp
index ec952e0058..ec952e0058 100644..100755
--- a/indra/test/llassetuploadqueue_tut.cpp
+++ b/indra/test/llassetuploadqueue_tut.cpp
diff --git a/indra/test/llblowfish_tut.cpp b/indra/test/llblowfish_tut.cpp
index 2573cab81f..2573cab81f 100644..100755
--- a/indra/test/llblowfish_tut.cpp
+++ b/indra/test/llblowfish_tut.cpp
diff --git a/indra/test/llbuffer_tut.cpp b/indra/test/llbuffer_tut.cpp
index dc1a5cdd3d..a25fdebb7f 100644..100755
--- a/indra/test/llbuffer_tut.cpp
+++ b/indra/test/llbuffer_tut.cpp
@@ -31,7 +31,6 @@
#include "lltut.h"
#include "llbuffer.h"
#include "llerror.h"
-#include "llmemtype.h"
namespace tut
diff --git a/indra/test/lldatapacker_tut.cpp b/indra/test/lldatapacker_tut.cpp
index cf2b7870ef..cf2b7870ef 100644..100755
--- a/indra/test/lldatapacker_tut.cpp
+++ b/indra/test/lldatapacker_tut.cpp
diff --git a/indra/test/lldoubledispatch_tut.cpp b/indra/test/lldoubledispatch_tut.cpp
index ad8f6454d4..ad8f6454d4 100644..100755
--- a/indra/test/lldoubledispatch_tut.cpp
+++ b/indra/test/lldoubledispatch_tut.cpp
diff --git a/indra/test/llevents_tut.cpp b/indra/test/llevents_tut.cpp
index 4699bb1827..a9114075fc 100644..100755
--- a/indra/test/llevents_tut.cpp
+++ b/indra/test/llevents_tut.cpp
@@ -49,46 +49,12 @@
#include <boost/assign/list_of.hpp>
// other Linden headers
#include "lltut.h"
+#include "catch_and_store_what_in.h"
#include "stringize.h"
#include "tests/listener.h"
using boost::assign::list_of;
-#ifdef LL_LINUX
-#define CATCH_MISSED_LINUX_EXCEPTION(exception, threw) \
-catch (const std::runtime_error& ex) \
-{ \
- /* This clause is needed on Linux, on the viewer side, because the */ \
- /* exception isn't caught by the clause above. Warn the user... */ \
- std::cerr << "Failed to catch " << typeid(ex).name() << std::endl; \
- /* But if the expected exception was thrown, allow the test to */ \
- /* succeed anyway. Not sure how else to handle this odd case. */ \
- /* This approach is also used in llsdmessage_test.cpp. */ \
- if (std::string(typeid(ex).name()) == typeid(exception).name()) \
- { \
- threw = ex.what(); \
- /*std::cout << ex.what() << std::endl;*/ \
- } \
- else \
- { \
- /* We don't even recognize this exception. Let it propagate */ \
- /* out to TUT to fail the test. */ \
- throw; \
- } \
-} \
-catch (...) \
-{ \
- std::cerr << "Utterly failed to catch expected exception " << #exception << "!" << \
- std::endl; \
- /* This indicates a problem in the test that should be addressed. */ \
- throw; \
-}
-
-#else // LL_LINUX
-#define CATCH_MISSED_LINUX_EXCEPTION(exception, threw) \
- /* Not needed on other platforms */
-#endif // LL_LINUX
-
template<typename T>
T make(const T& value)
{
@@ -178,11 +144,7 @@ void events_object::test<1>()
per_frame.listen(listener0.getName(), // note bug, dup name
boost::bind(&Listener::call, boost::ref(listener1), _1));
}
- catch (const LLEventPump::DupListenerName& e)
- {
- threw = e.what();
- }
- CATCH_MISSED_LINUX_EXCEPTION(LLEventPump::DupListenerName, threw)
+ CATCH_AND_STORE_WHAT_IN(threw, LLEventPump::DupListenerName)
ensure_equals(threw,
std::string("DupListenerName: "
"Attempt to register duplicate listener name '") +
@@ -354,7 +316,6 @@ void events_object::test<7>()
{
set_test_name("listener dependency order");
typedef LLEventPump::NameList NameList;
- typedef Collect::StringList StringList;
LLEventPump& button(pumps.obtain("button"));
Collect collector;
button.listen("Mary",
@@ -368,7 +329,7 @@ void events_object::test<7>()
button.listen("spot",
boost::bind(&Collect::add, boost::ref(collector), "spot", _1));
button.post(1);
- ensure_equals(collector.result, make<StringList>(list_of("spot")("checked")("Mary")));
+ ensure_equals(collector.result, make<StringVec>(list_of("spot")("checked")("Mary")));
collector.clear();
button.stopListening("Mary");
button.listen("Mary",
@@ -377,7 +338,7 @@ void events_object::test<7>()
// now "Mary" must come before "spot"
make<NameList>(list_of("spot")));
button.post(2);
- ensure_equals(collector.result, make<StringList>(list_of("Mary")("spot")("checked")));
+ ensure_equals(collector.result, make<StringVec>(list_of("Mary")("spot")("checked")));
collector.clear();
button.stopListening("spot");
std::string threw;
@@ -388,12 +349,7 @@ void events_object::test<7>()
// after "Mary" and "checked" -- whoops!
make<NameList>(list_of("Mary")("checked")));
}
- catch (const LLEventPump::Cycle& e)
- {
- threw = e.what();
- // std::cout << "Caught: " << e.what() << '\n';
- }
- CATCH_MISSED_LINUX_EXCEPTION(LLEventPump::Cycle, threw)
+ CATCH_AND_STORE_WHAT_IN(threw, LLEventPump::Cycle)
// Obviously the specific wording of the exception text can
// change; go ahead and change the test to match.
// Establish that it contains:
@@ -416,7 +372,7 @@ void events_object::test<7>()
boost::bind(&Collect::add, boost::ref(collector), "shoelaces", _1),
make<NameList>(list_of("checked")));
button.post(3);
- ensure_equals(collector.result, make<StringList>(list_of("Mary")("checked")("yellow")("shoelaces")));
+ ensure_equals(collector.result, make<StringVec>(list_of("Mary")("checked")("yellow")("shoelaces")));
collector.clear();
threw.clear();
try
@@ -426,12 +382,7 @@ void events_object::test<7>()
make<NameList>(list_of("shoelaces")),
make<NameList>(list_of("yellow")));
}
- catch (const LLEventPump::OrderChange& e)
- {
- threw = e.what();
- // std::cout << "Caught: " << e.what() << '\n';
- }
- CATCH_MISSED_LINUX_EXCEPTION(LLEventPump::OrderChange, threw)
+ CATCH_AND_STORE_WHAT_IN(threw, LLEventPump::OrderChange)
// Same remarks about the specific wording of the exception. Just
// ensure that it contains enough information to clarify the
// problem and what must be done to resolve it.
@@ -443,7 +394,7 @@ void events_object::test<7>()
ensure_contains("old order", threw, "was: Mary, checked, yellow, shoelaces");
ensure_contains("new order", threw, "now: Mary, checked, shoelaces, of, yellow");
button.post(4);
- ensure_equals(collector.result, make<StringList>(list_of("Mary")("checked")("yellow")("shoelaces")));
+ ensure_equals(collector.result, make<StringVec>(list_of("Mary")("checked")("yellow")("shoelaces")));
}
template<> template<>
@@ -459,12 +410,7 @@ void events_object::test<8>()
// then another with a duplicate name.
LLEventStream bob2("bob");
}
- catch (const LLEventPump::DupPumpName& e)
- {
- threw = e.what();
- // std::cout << "Caught: " << e.what() << '\n';
- }
- CATCH_MISSED_LINUX_EXCEPTION(LLEventPump::DupPumpName, threw)
+ CATCH_AND_STORE_WHAT_IN(threw, LLEventPump::DupPumpName)
ensure("Caught DupPumpName", !threw.empty());
} // delete first 'bob'
LLEventStream bob("bob"); // should work, previous one unregistered
@@ -505,11 +451,7 @@ void events_object::test<9>()
LLListenerOrPumpName empty;
empty(17);
}
- catch (const LLListenerOrPumpName::Empty& e)
- {
- threw = e.what();
- }
- CATCH_MISSED_LINUX_EXCEPTION(LLListenerOrPumpName::Empty, threw)
+ CATCH_AND_STORE_WHAT_IN(threw, LLListenerOrPumpName::Empty)
ensure("threw Empty", !threw.empty());
}
diff --git a/indra/test/llhttpdate_tut.cpp b/indra/test/llhttpdate_tut.cpp
index 46684bb9dc..46684bb9dc 100644..100755
--- a/indra/test/llhttpdate_tut.cpp
+++ b/indra/test/llhttpdate_tut.cpp
diff --git a/indra/test/llhttpnode_tut.cpp b/indra/test/llhttpnode_tut.cpp
index 216c59d766..216c59d766 100644..100755
--- a/indra/test/llhttpnode_tut.cpp
+++ b/indra/test/llhttpnode_tut.cpp
diff --git a/indra/test/lliohttpserver_tut.cpp b/indra/test/lliohttpserver_tut.cpp
index 2fdc455f45..2fdc455f45 100644..100755
--- a/indra/test/lliohttpserver_tut.cpp
+++ b/indra/test/lliohttpserver_tut.cpp
diff --git a/indra/test/llmessageconfig_tut.cpp b/indra/test/llmessageconfig_tut.cpp
index 8088ce8558..8088ce8558 100644..100755
--- a/indra/test/llmessageconfig_tut.cpp
+++ b/indra/test/llmessageconfig_tut.cpp
diff --git a/indra/test/llmessagetemplateparser_tut.cpp b/indra/test/llmessagetemplateparser_tut.cpp
index da6d229fb5..da6d229fb5 100644..100755
--- a/indra/test/llmessagetemplateparser_tut.cpp
+++ b/indra/test/llmessagetemplateparser_tut.cpp
diff --git a/indra/test/llpermissions_tut.cpp b/indra/test/llpermissions_tut.cpp
index bf6766424c..bc2c87ba46 100644..100755
--- a/indra/test/llpermissions_tut.cpp
+++ b/indra/test/llpermissions_tut.cpp
@@ -407,7 +407,7 @@ namespace tut
LLFILE* fp = LLFile::fopen("linden_file.dat","w+");
if(!fp)
{
- llerrs << "file coudnt be opened\n" << llendl;
+ llerrs << "file couldn't be opened\n" << llendl;
return;
}
LLPermissions perm,perm1;
@@ -425,15 +425,15 @@ namespace tut
perm.initMasks(base, ownerp, everyone, groupp, next);
- perm.exportFile(fp);
+ ensure("Permissions export failed", perm.exportFile(fp));
fclose(fp);
fp = LLFile::fopen("linden_file.dat","r+");
if(!fp)
{
- llerrs << "file coudnt be opened\n" << llendl;
+ llerrs << "file couldn't be opened\n" << llendl;
return;
}
- perm1.importFile(fp);
+ ensure("Permissions import failed", perm1.importFile(fp));
fclose(fp);
ensure_equals("exportFile()/importFile():failed to export and import the data ", perm1, perm);
}
@@ -461,7 +461,7 @@ namespace tut
std::istringstream istream(ostream.str());
perm1.importLegacyStream(istream);
- ensure_equals("exportLegacyStream()/importLegacyStream():failed to export and import the data ", perm1, perm);
+ ensure_equals("exportStream()/importStream():failed to export and import the data ", perm1, perm);
}
template<> template<>
diff --git a/indra/test/llpipeutil.cpp b/indra/test/llpipeutil.cpp
index db76a370e0..db76a370e0 100644..100755
--- a/indra/test/llpipeutil.cpp
+++ b/indra/test/llpipeutil.cpp
diff --git a/indra/test/llpipeutil.h b/indra/test/llpipeutil.h
index 5deb26764f..5deb26764f 100644..100755
--- a/indra/test/llpipeutil.h
+++ b/indra/test/llpipeutil.h
diff --git a/indra/test/llsaleinfo_tut.cpp b/indra/test/llsaleinfo_tut.cpp
index 09fca2abba..2488af1d7f 100644..100755
--- a/indra/test/llsaleinfo_tut.cpp
+++ b/indra/test/llsaleinfo_tut.cpp
@@ -154,7 +154,8 @@ namespace tut
BOOL has_perm_mask = FALSE;
llsaleinfo1.importLegacyStream(istream, has_perm_mask, perm_mask);
- ensure("importLegacyStream() fn failed ", llsaleinfo.getSalePrice() == llsaleinfo1.getSalePrice() &&
+ ensure("importStream() fn failed ",
+ llsaleinfo.getSalePrice() == llsaleinfo1.getSalePrice() &&
llsaleinfo.getSaleType() == llsaleinfo1.getSaleType());
}
diff --git a/indra/test/llscriptresource_tut.cpp b/indra/test/llscriptresource_tut.cpp
index 7a3b824e6d..7a3b824e6d 100644..100755
--- a/indra/test/llscriptresource_tut.cpp
+++ b/indra/test/llscriptresource_tut.cpp
diff --git a/indra/test/llsd_new_tut.cpp b/indra/test/llsd_new_tut.cpp
index f928a1bad0..f928a1bad0 100644..100755
--- a/indra/test/llsd_new_tut.cpp
+++ b/indra/test/llsd_new_tut.cpp
diff --git a/indra/test/llsdmessagebuilder_tut.cpp b/indra/test/llsdmessagebuilder_tut.cpp
index be0692557a..be0692557a 100644..100755
--- a/indra/test/llsdmessagebuilder_tut.cpp
+++ b/indra/test/llsdmessagebuilder_tut.cpp
diff --git a/indra/test/llsdmessagereader_tut.cpp b/indra/test/llsdmessagereader_tut.cpp
index 6dc5cf593e..6dc5cf593e 100644..100755
--- a/indra/test/llsdmessagereader_tut.cpp
+++ b/indra/test/llsdmessagereader_tut.cpp
diff --git a/indra/test/llsdtraits.h b/indra/test/llsdtraits.h
index 8144aaee94..8144aaee94 100644..100755
--- a/indra/test/llsdtraits.h
+++ b/indra/test/llsdtraits.h
diff --git a/indra/test/llsdutil_tut.cpp b/indra/test/llsdutil_tut.cpp
index 140f4b832b..140f4b832b 100644..100755
--- a/indra/test/llsdutil_tut.cpp
+++ b/indra/test/llsdutil_tut.cpp
diff --git a/indra/test/llservicebuilder_tut.cpp b/indra/test/llservicebuilder_tut.cpp
index 8f5be3011c..8f5be3011c 100644..100755
--- a/indra/test/llservicebuilder_tut.cpp
+++ b/indra/test/llservicebuilder_tut.cpp
diff --git a/indra/test/llstreamtools_tut.cpp b/indra/test/llstreamtools_tut.cpp
index a93f2e8f65..0f6436f0f4 100644..100755
--- a/indra/test/llstreamtools_tut.cpp
+++ b/indra/test/llstreamtools_tut.cpp
@@ -385,16 +385,15 @@ namespace tut
std::string expected_result;
std::string actual_result;
std::istringstream is;
- bool ret;
is.clear();
is.str(str = " First Second \t \r \n Third Fourth-ShouldThisBePartOfFourth Fifth\n");
actual_result = "";
- ret = get_word(actual_result, is); // First
+ get_word(actual_result, is); // First
actual_result = "";
- ret = get_word(actual_result, is); // Second
+ get_word(actual_result, is); // Second
actual_result = "";
- ret = get_word(actual_result, is); // Third
+ get_word(actual_result, is); // Third
// the current implementation of get_word seems inconsistent with
// skip_to_next_word. skip_to_next_word treats any character other
@@ -403,22 +402,22 @@ namespace tut
// carriage return ('\r'), horizontal tab ('\t'), and vertical tab ('\v')
// as delimiters
actual_result = "";
- ret = get_word(actual_result, is); // will copy Fourth-ShouldThisBePartOfFourth
+ get_word(actual_result, is); // will copy Fourth-ShouldThisBePartOfFourth
actual_result = "";
- ret = get_word(actual_result, is); // will copy Fifth
+ get_word(actual_result, is); // will copy Fifth
is.clear();
is.str(str = " First Second \t \r \n Third Fourth_ShouldThisBePartOfFourth Fifth\n");
- ret = skip_to_next_word(is); // should now point to First
- ret = skip_to_next_word(is); // should now point to Second
- ret = skip_to_next_word(is); // should now point to Third
- ret = skip_to_next_word(is); // should now point to Fourth
- ret = skip_to_next_word(is); // should now point to ShouldThisBePartOfFourth
+ skip_to_next_word(is); // should now point to First
+ skip_to_next_word(is); // should now point to Second
+ skip_to_next_word(is); // should now point to Third
+ skip_to_next_word(is); // should now point to Fourth
+ skip_to_next_word(is); // should now point to ShouldThisBePartOfFourth
expected_result = "";
// will copy ShouldThisBePartOfFourth, the fifth word,
// while using get_word above five times result in getting "Fifth"
- ret = get_word(expected_result, is);
+ get_word(expected_result, is);
ensure_equals("get_word: skip_to_next_word compatibility", actual_result, expected_result);
}
@@ -480,39 +479,38 @@ namespace tut
std::string expected_result;
std::string actual_result;
std::istringstream is;
- bool ret;
is.clear();
is.str(str = "First Second \t \r\n Third Fourth-ShouldThisBePartOfFourth IsThisFifth\n");
actual_result = "";
- ret = get_line(actual_result, is);
+ get_line(actual_result, is);
expected_result = "First Second \t \r\n";
ensure_equals("get_line: 1", actual_result, expected_result);
actual_result = "";
- ret = get_line(actual_result, is);
+ get_line(actual_result, is);
expected_result = " Third Fourth-ShouldThisBePartOfFourth IsThisFifth\n";
ensure_equals("get_line: 2", actual_result, expected_result);
is.clear();
is.str(str = "\nFirst Line.\n\nSecond Line.\n");
actual_result = "";
- ret = get_line(actual_result, is);
+ get_line(actual_result, is);
expected_result = "\n";
ensure_equals("get_line: First char as newline", actual_result, expected_result);
actual_result = "";
- ret = get_line(actual_result, is);
+ get_line(actual_result, is);
expected_result = "First Line.\n";
ensure_equals("get_line: 3", actual_result, expected_result);
actual_result = "";
- ret = get_line(actual_result, is);
+ get_line(actual_result, is);
expected_result = "\n";
ensure_equals("get_line: 4", actual_result, expected_result);
actual_result = "";
- ret = get_line(actual_result, is);
+ get_line(actual_result, is);
expected_result = "Second Line.\n";
ensure_equals("get_line: 5", actual_result, expected_result);
}
@@ -544,13 +542,12 @@ namespace tut
std::string expected_result;
std::string actual_result;
std::istringstream is;
- bool ret;
// need to be check if this test case is wrong or the implementation is wrong.
is.clear();
is.str(str = "Should not skip lone \r.\r\n");
actual_result = "";
- ret = get_line(actual_result, is);
+ get_line(actual_result, is);
expected_result = "Should not skip lone \r.\r\n";
ensure_equals("get_line: carriage return skipped even though not followed by newline", actual_result, expected_result);
}
@@ -563,12 +560,11 @@ namespace tut
std::string expected_result;
std::string actual_result;
std::istringstream is;
- bool ret;
is.clear();
is.str(str = "\n");
actual_result = "";
- ret = get_line(actual_result, is);
+ get_line(actual_result, is);
expected_result = "\n";
ensure_equals("get_line: Just newline", actual_result, expected_result);
}
@@ -582,36 +578,35 @@ namespace tut
std::string expected_result;
std::string actual_result;
std::istringstream is;
- bool ret;
is.clear();
is.str(str = "First Line.\nSecond Line.\n");
actual_result = "";
- ret = get_line(actual_result, is, 255);
+ get_line(actual_result, is, 255);
expected_result = "First Line.\n";
ensure_equals("get_line: Basic Operation", actual_result, expected_result);
actual_result = "";
- ret = get_line(actual_result, is, sizeof("Second")-1);
+ get_line(actual_result, is, sizeof("Second")-1);
expected_result = "Second\n";
ensure_equals("get_line: Insufficient length 1", actual_result, expected_result);
actual_result = "";
- ret = get_line(actual_result, is, 255);
+ get_line(actual_result, is, 255);
expected_result = " Line.\n";
ensure_equals("get_line: Remainder after earlier insufficient length", actual_result, expected_result);
is.clear();
is.str(str = "One Line only with no newline with limited length");
actual_result = "";
- ret = get_line(actual_result, is, sizeof("One Line only with no newline with limited length")-1);
+ get_line(actual_result, is, sizeof("One Line only with no newline with limited length")-1);
expected_result = "One Line only with no newline with limited length\n";
ensure_equals("get_line: No newline with limited length", actual_result, expected_result);
is.clear();
is.str(str = "One Line only with no newline");
actual_result = "";
- ret = get_line(actual_result, is, 255);
+ get_line(actual_result, is, 255);
expected_result = "One Line only with no newline";
ensure_equals("get_line: No newline", actual_result, expected_result);
}
diff --git a/indra/test/lltemplatemessagebuilder_tut.cpp b/indra/test/lltemplatemessagebuilder_tut.cpp
index 6e1c82bb24..dde70f98c8 100644..100755
--- a/indra/test/lltemplatemessagebuilder_tut.cpp
+++ b/indra/test/lltemplatemessagebuilder_tut.cpp
@@ -937,7 +937,7 @@ namespace tut
// build message with single block
LLMessageTemplate messageTemplate = defaultTemplate();
messageTemplate.addBlock(defaultBlock(MVT_U32, 4, MBT_SINGLE));
- U32 outValue, outValue2, inValue = 0xbbbbbbbb;
+ U32 outValue, inValue = 0xbbbbbbbb;
LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
builder->addU32(_PREHASH_Test0, inValue);
const U32 bufferSize = 1024;
@@ -958,11 +958,11 @@ namespace tut
reader->validateMessage(buffer, builtSize, LLHost());
reader->readMessage(buffer, LLHost());
reader->getU32(_PREHASH_Test0, _PREHASH_Test0, outValue);
+ (void)outValue;
char outBuffer[bufferSize];
memset(buffer, 0xcc, bufferSize);
reader->getString(_PREHASH_Test1, _PREHASH_Test0, bufferSize,
outBuffer);
- outValue2 = reader->getNumberOfBlocks(_PREHASH_Test1);
ensure_equals("Ensure present value ", outValue, inValue);
ensure_equals("Ensure unchanged buffer ", strlen(outBuffer), 0);
delete reader;
diff --git a/indra/test/lltimestampcache_tut.cpp b/indra/test/lltimestampcache_tut.cpp
index 857a17a6d5..857a17a6d5 100644..100755
--- a/indra/test/lltimestampcache_tut.cpp
+++ b/indra/test/lltimestampcache_tut.cpp
diff --git a/indra/test/lltranscode_tut.cpp b/indra/test/lltranscode_tut.cpp
index 2431afad27..2431afad27 100644..100755
--- a/indra/test/lltranscode_tut.cpp
+++ b/indra/test/lltranscode_tut.cpp
diff --git a/indra/test/lltut.cpp b/indra/test/lltut.cpp
index c43a8f0c7d..c43a8f0c7d 100644..100755
--- a/indra/test/lltut.cpp
+++ b/indra/test/lltut.cpp
diff --git a/indra/test/lltut.h b/indra/test/lltut.h
index 55d84bcaca..55d84bcaca 100644..100755
--- a/indra/test/lltut.h
+++ b/indra/test/lltut.h
diff --git a/indra/test/lluserrelations_tut.cpp b/indra/test/lluserrelations_tut.cpp
index afbcf6e5a8..afbcf6e5a8 100644..100755
--- a/indra/test/lluserrelations_tut.cpp
+++ b/indra/test/lluserrelations_tut.cpp
diff --git a/indra/test/lluuidhashmap_tut.cpp b/indra/test/lluuidhashmap_tut.cpp
index 0544e832ce..9712a613f4 100644..100755
--- a/indra/test/lluuidhashmap_tut.cpp
+++ b/indra/test/lluuidhashmap_tut.cpp
@@ -30,6 +30,10 @@
#include "linden_common.h"
#include "lluuidhashmap.h"
#include "llsdserialize.h"
+#include "lldir.h"
+#include "stringize.h"
+#include <iostream>
+#include <fstream>
namespace tut
{
@@ -79,40 +83,134 @@ namespace tut
template<> template<>
void hash_index_object_t::test<1>()
{
- LLUUIDHashMap<UUIDTableEntry, 32> hashTable(UUIDTableEntry::uuidEq, UUIDTableEntry());
+ set_test_name("stress test");
+ // As of 2012-10-10, I (nat) have observed sporadic failures of this
+ // test: "set/get did not work." The trouble is that since test data
+ // are randomly generated with every run, it is impossible to debug a
+ // test failure. One is left with the uneasy suspicion that
+ // LLUUID::generate() can sometimes produce duplicates even within the
+ // moderately small number requested here. Since rerunning the test
+ // generally allows it to pass, it's too easy to shrug and forget it.
+ // The following code is intended to support reproducing such test
+ // failures. The idea is that, on test failure, we save the generated
+ // data to a canonical filename in a temp directory. Then on every
+ // subsequent run, we check for that filename. If it exists, we reload
+ // that specific data rather than generating fresh data -- which
+ // should presumably reproduce the same test failure. But we inform
+ // the user that to resume normal (random) test runs, s/he need only
+ // delete that file. And since it's in a temp directory, sooner or
+ // later the system will clean it up anyway.
+ const char* tempvar = "TEMP";
+ const char* tempdir = getenv(tempvar); // Windows convention
+ if (! tempdir)
+ {
+ tempvar = "TMPDIR";
+ tempdir = getenv(tempvar); // Mac convention
+ }
+ if (! tempdir)
+ {
+ // reset tempvar to the first var we check; it's just a
+ // recommendation
+ tempvar = "TEMP";
+ tempdir = "/tmp"; // Posix in general
+ }
+ std::string savefile(gDirUtilp->add(tempdir, "lluuidhashmap_tut.save.txt"));
const int numElementsToCheck = 32*256*32;
- std::vector<LLUUID> idList(numElementsToCheck);
- int i;
-
- for (i = 0; i < numElementsToCheck; i++)
+ std::vector<LLUUID> idList;
+ if ((! getenv("TEAMCITY_PROJECT_NAME")) && gDirUtilp->fileExists(savefile))
{
- LLUUID id;
- id.generate();
- UUIDTableEntry entry(id, i);
- hashTable.set(id, entry);
- idList[i] = id;
+ // This is not a TeamCity build, and we have saved data from a
+ // previous failed run. Reload that data.
+ std::ifstream inf(savefile.c_str());
+ if (! inf.is_open())
+ {
+ fail(STRINGIZE("Although save file '" << savefile << "' exists, it cannot be opened"));
+ }
+ std::string item;
+ while (std::getline(inf, item))
+ {
+ idList.push_back(LLUUID(item));
+ }
+ std::cout << "Reloaded " << idList.size() << " items from '" << savefile << "'";
+ if (idList.size() != numElementsToCheck)
+ {
+ std::cout << " (expected " << numElementsToCheck << ")";
+ }
+ std::cout << " -- delete this file to generate new data" << std::endl;
+ }
+ else
+ {
+ // This is a TeamCity build, or (normal case) savefile does not
+ // exist: regenerate idList from scratch.
+ for (int i = 0; i < numElementsToCheck; ++i)
+ {
+ LLUUID id;
+ id.generate();
+ idList.push_back(id);
+ }
}
- for (i = 0; i < numElementsToCheck; i++)
+ LLUUIDHashMap<UUIDTableEntry, 32> hashTable(UUIDTableEntry::uuidEq, UUIDTableEntry());
+ int i;
+
+ for (i = 0; i < idList.size(); ++i)
{
- LLUUID idToCheck = idList[i];
- UUIDTableEntry entryToCheck = hashTable.get(idToCheck);
- ensure("set/get did not work", entryToCheck.getID() == idToCheck && entryToCheck.getValue() == (size_t)i);
+ UUIDTableEntry entry(idList[i], i);
+ hashTable.set(idList[i], entry);
}
- for (i = 0; i < numElementsToCheck; i++)
+ try
{
- LLUUID idToCheck = idList[i];
- if (i % 2 != 0)
+ for (i = 0; i < idList.size(); i++)
{
- hashTable.remove(idToCheck);
+ LLUUID idToCheck = idList[i];
+ UUIDTableEntry entryToCheck = hashTable.get(idToCheck);
+ ensure_equals(STRINGIZE("set/get ID (entry " << i << ")").c_str(),
+ entryToCheck.getID(), idToCheck);
+ ensure_equals(STRINGIZE("set/get value (ID " << idToCheck << ")").c_str(),
+ entryToCheck.getValue(), (size_t)i);
}
- }
- for (i = 0; i < numElementsToCheck; i++)
+ for (i = 0; i < idList.size(); i++)
+ {
+ LLUUID idToCheck = idList[i];
+ if (i % 2 != 0)
+ {
+ hashTable.remove(idToCheck);
+ }
+ }
+
+ for (i = 0; i < idList.size(); i++)
+ {
+ LLUUID idToCheck = idList[i];
+ ensure("remove or check did not work", (i % 2 == 0 && hashTable.check(idToCheck)) || (i % 2 != 0 && !hashTable.check(idToCheck)));
+ }
+ }
+ catch (const failure&)
{
- LLUUID idToCheck = idList[i];
- ensure("remove or check did not work", (i % 2 == 0 && hashTable.check(idToCheck)) || (i % 2 != 0 && !hashTable.check(idToCheck)));
+ // One of the above tests failed. Try to save idList to repro with
+ // a later run.
+ std::ofstream outf(savefile.c_str());
+ if (! outf.is_open())
+ {
+ // Sigh, don't use fail() here because we want to preserve
+ // the original test failure.
+ std::cout << "Cannot open file '" << savefile
+ << "' to save data -- check and fix " << tempvar << std::endl;
+ }
+ else
+ {
+ // outf.is_open()
+ for (int i = 0; i < idList.size(); ++i)
+ {
+ outf << idList[i] << std::endl;
+ }
+ std::cout << "Saved " << idList.size() << " entries to '" << savefile
+ << "' -- rerun test to debug with these" << std::endl;
+ }
+ // re-raise the same exception -- we WANT this test failure to
+ // be reported! We just needed to save the data on the way out.
+ throw;
}
}
diff --git a/indra/test/llxorcipher_tut.cpp b/indra/test/llxorcipher_tut.cpp
index 55b3faaa61..55b3faaa61 100644..100755
--- a/indra/test/llxorcipher_tut.cpp
+++ b/indra/test/llxorcipher_tut.cpp
diff --git a/indra/test/manageapr.h b/indra/test/manageapr.h
new file mode 100755
index 0000000000..2452fb6ae4
--- /dev/null
+++ b/indra/test/manageapr.h
@@ -0,0 +1,46 @@
+/**
+ * @file manageapr.h
+ * @author Nat Goodspeed
+ * @date 2012-01-13
+ * @brief ManageAPR class for simple test programs
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Copyright (c) 2012, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+#if ! defined(LL_MANAGEAPR_H)
+#define LL_MANAGEAPR_H
+
+#include "llapr.h"
+#include <boost/noncopyable.hpp>
+
+/**
+ * Declare a static instance of this class for dead-simple ll_init_apr() at
+ * program startup, ll_cleanup_apr() at termination. This is recommended for
+ * use only with simple test programs. Once you start introducing static
+ * instances of other classes that depend on APR already being initialized,
+ * the indeterminate static-constructor-order problem rears its ugly head.
+ */
+class ManageAPR: public boost::noncopyable
+{
+public:
+ ManageAPR()
+ {
+ ll_init_apr();
+ }
+
+ ~ManageAPR()
+ {
+ ll_cleanup_apr();
+ }
+
+ static std::string strerror(apr_status_t rv)
+ {
+ char errbuf[256];
+ apr_strerror(rv, errbuf, sizeof(errbuf));
+ return errbuf;
+ }
+};
+
+#endif /* ! defined(LL_MANAGEAPR_H) */
diff --git a/indra/test/message_tut.cpp b/indra/test/message_tut.cpp
index d971b33475..d971b33475 100644..100755
--- a/indra/test/message_tut.cpp
+++ b/indra/test/message_tut.cpp
diff --git a/indra/test/mock_http_client.cpp b/indra/test/mock_http_client.cpp
index d7ef407d52..d7ef407d52 100644..100755
--- a/indra/test/mock_http_client.cpp
+++ b/indra/test/mock_http_client.cpp
diff --git a/indra/test/mock_http_client.h b/indra/test/mock_http_client.h
index 7668a43fdf..7668a43fdf 100644..100755
--- a/indra/test/mock_http_client.h
+++ b/indra/test/mock_http_client.h
diff --git a/indra/test/namedtempfile.h b/indra/test/namedtempfile.h
new file mode 100755
index 0000000000..6069064627
--- /dev/null
+++ b/indra/test/namedtempfile.h
@@ -0,0 +1,205 @@
+/**
+ * @file namedtempfile.h
+ * @author Nat Goodspeed
+ * @date 2012-01-13
+ * @brief NamedTempFile class for tests that need disk files as fixtures.
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Copyright (c) 2012, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+#if ! defined(LL_NAMEDTEMPFILE_H)
+#define LL_NAMEDTEMPFILE_H
+
+#include "llerror.h"
+#include "llapr.h"
+#include "apr_file_io.h"
+#include <string>
+#include <boost/function.hpp>
+#include <boost/lambda/lambda.hpp>
+#include <boost/lambda/bind.hpp>
+#include <boost/noncopyable.hpp>
+#include <iostream>
+#include <sstream>
+
+/**
+ * Create a text file with specified content "somewhere in the
+ * filesystem," cleaning up when it goes out of scope.
+ */
+class NamedTempFile: public boost::noncopyable
+{
+ LOG_CLASS(NamedTempFile);
+public:
+ NamedTempFile(const std::string& pfx, const std::string& content, apr_pool_t* pool=gAPRPoolp):
+ mPool(pool)
+ {
+ createFile(pfx, boost::lambda::_1 << content);
+ }
+
+ // Disambiguate when passing string literal
+ NamedTempFile(const std::string& pfx, const char* content, apr_pool_t* pool=gAPRPoolp):
+ mPool(pool)
+ {
+ createFile(pfx, boost::lambda::_1 << content);
+ }
+
+ // Function that accepts an ostream ref and (presumably) writes stuff to
+ // it, e.g.:
+ // (boost::lambda::_1 << "the value is " << 17 << '\n')
+ typedef boost::function<void(std::ostream&)> Streamer;
+
+ NamedTempFile(const std::string& pfx, const Streamer& func, apr_pool_t* pool=gAPRPoolp):
+ mPool(pool)
+ {
+ createFile(pfx, func);
+ }
+
+ virtual ~NamedTempFile()
+ {
+ ll_apr_assert_status(apr_file_remove(mPath.c_str(), mPool));
+ }
+
+ virtual std::string getName() const { return mPath; }
+
+ void peep()
+ {
+ std::cout << "File '" << mPath << "' contains:\n";
+ std::ifstream reader(mPath.c_str());
+ std::string line;
+ while (std::getline(reader, line))
+ std::cout << line << '\n';
+ std::cout << "---\n";
+ }
+
+protected:
+ void createFile(const std::string& pfx, const Streamer& func)
+ {
+ // Create file in a temporary place.
+ const char* tempdir = NULL;
+ ll_apr_assert_status(apr_temp_dir_get(&tempdir, mPool));
+
+ // Construct a temp filename template in that directory.
+ char *tempname = NULL;
+ ll_apr_assert_status(apr_filepath_merge(&tempname,
+ tempdir,
+ (pfx + "XXXXXX").c_str(),
+ 0,
+ mPool));
+
+ // Create a temp file from that template.
+ apr_file_t* fp = NULL;
+ ll_apr_assert_status(apr_file_mktemp(&fp,
+ tempname,
+ APR_CREATE | APR_WRITE | APR_EXCL,
+ mPool));
+ // apr_file_mktemp() alters tempname with the actual name. Not until
+ // now is it valid to capture as our mPath.
+ mPath = tempname;
+
+ // Write desired content.
+ std::ostringstream out;
+ // Stream stuff to it.
+ func(out);
+
+ std::string data(out.str());
+ apr_size_t writelen(data.length());
+ ll_apr_assert_status(apr_file_write(fp, data.c_str(), &writelen));
+ ll_apr_assert_status(apr_file_close(fp));
+ llassert_always(writelen == data.length());
+ }
+
+ std::string mPath;
+ apr_pool_t* mPool;
+};
+
+/**
+ * Create a NamedTempFile with a specified filename extension. This is useful
+ * when, for instance, you must be able to use the file in a Python import
+ * statement.
+ *
+ * A NamedExtTempFile actually has two different names. We retain the original
+ * no-extension name as a placeholder in the temp directory to ensure
+ * uniqueness; to that we link the name plus the desired extension. Naturally,
+ * both must be removed on destruction.
+ */
+class NamedExtTempFile: public NamedTempFile
+{
+ LOG_CLASS(NamedExtTempFile);
+public:
+ NamedExtTempFile(const std::string& ext, const std::string& content, apr_pool_t* pool=gAPRPoolp):
+ NamedTempFile(remove_dot(ext), content, pool),
+ mLink(mPath + ensure_dot(ext))
+ {
+ linkto(mLink);
+ }
+
+ // Disambiguate when passing string literal
+ NamedExtTempFile(const std::string& ext, const char* content, apr_pool_t* pool=gAPRPoolp):
+ NamedTempFile(remove_dot(ext), content, pool),
+ mLink(mPath + ensure_dot(ext))
+ {
+ linkto(mLink);
+ }
+
+ NamedExtTempFile(const std::string& ext, const Streamer& func, apr_pool_t* pool=gAPRPoolp):
+ NamedTempFile(remove_dot(ext), func, pool),
+ mLink(mPath + ensure_dot(ext))
+ {
+ linkto(mLink);
+ }
+
+ virtual ~NamedExtTempFile()
+ {
+ ll_apr_assert_status(apr_file_remove(mLink.c_str(), mPool));
+ }
+
+ // Since the caller has gone to the trouble to create the name with the
+ // extension, that should be the name we return. In this class, mPath is
+ // just a placeholder to ensure that future createFile() calls won't
+ // collide.
+ virtual std::string getName() const { return mLink; }
+
+ static std::string ensure_dot(const std::string& ext)
+ {
+ if (ext.empty())
+ {
+ // What SHOULD we do when the caller makes a point of using
+ // NamedExtTempFile to generate a file with a particular
+ // extension, then passes an empty extension? Use just "."? That
+ // sounds like a Bad Idea, especially on Windows. Treat that as a
+ // coding error.
+ LL_ERRS("NamedExtTempFile") << "passed empty extension" << LL_ENDL;
+ }
+ if (ext[0] == '.')
+ {
+ return ext;
+ }
+ return std::string(".") + ext;
+ }
+
+ static std::string remove_dot(const std::string& ext)
+ {
+ std::string::size_type found = ext.find_first_not_of(".");
+ if (found == std::string::npos)
+ {
+ return ext;
+ }
+ return ext.substr(found);
+ }
+
+private:
+ void linkto(const std::string& path)
+ {
+ // This method assumes that since mPath (without extension) is
+ // guaranteed by apr_file_mktemp() to be unique, then (mPath + any
+ // extension) is also unique. This is likely, though not guaranteed:
+ // files could be created in the same temp directory other than by
+ // this class.
+ ll_apr_assert_status(apr_file_link(mPath.c_str(), path.c_str()));
+ }
+
+ std::string mLink;
+};
+
+#endif /* ! defined(LL_NAMEDTEMPFILE_H) */
diff --git a/indra/test/prim_linkability_tut.cpp b/indra/test/prim_linkability_tut.cpp
index a70912e535..a70912e535 100644..100755
--- a/indra/test/prim_linkability_tut.cpp
+++ b/indra/test/prim_linkability_tut.cpp
diff --git a/indra/test/test.cpp b/indra/test/test.cpp
index e58e7293fb..dc8580fe69 100644..100755
--- a/indra/test/test.cpp
+++ b/indra/test/test.cpp
@@ -37,7 +37,9 @@
#include "linden_common.h"
#include "llerrorcontrol.h"
#include "lltut.h"
+#include "tests/wrapllerrs.h" // RecorderProxy
#include "stringize.h"
+#include "namedtempfile.h"
#include "apr_pools.h"
#include "apr_getopt.h"
@@ -70,25 +72,91 @@
#include <boost/foreach.hpp>
#include <boost/lambda/lambda.hpp>
+#include <fstream>
+
+void wouldHaveCrashed(const std::string& message);
+
namespace tut
{
std::string sSourceDir;
-
- test_runner_singleton runner;
+
+ test_runner_singleton runner;
}
+class LLReplayLog
+{
+public:
+ LLReplayLog() {}
+ virtual ~LLReplayLog() {}
+
+ virtual void reset() {}
+ virtual void replay(std::ostream&) {}
+};
+
+class LLReplayLogReal: public LLReplayLog, public LLError::Recorder, public boost::noncopyable
+{
+public:
+ LLReplayLogReal(LLError::ELevel level, apr_pool_t* pool):
+ mOldSettings(LLError::saveAndResetSettings()),
+ mProxy(new RecorderProxy(this)),
+ mTempFile("log", "", pool), // create file
+ mFile(mTempFile.getName().c_str()) // open it
+ {
+ LLError::setFatalFunction(wouldHaveCrashed);
+ LLError::setDefaultLevel(level);
+ LLError::addRecorder(mProxy);
+ }
+
+ virtual ~LLReplayLogReal()
+ {
+ LLError::removeRecorder(mProxy);
+ delete mProxy;
+ LLError::restoreSettings(mOldSettings);
+ }
+
+ virtual void recordMessage(LLError::ELevel level, const std::string& message)
+ {
+ mFile << message << std::endl;
+ }
+
+ virtual void reset()
+ {
+ mFile.close();
+ mFile.open(mTempFile.getName().c_str());
+ }
+
+ virtual void replay(std::ostream& out)
+ {
+ mFile.close();
+ std::ifstream inf(mTempFile.getName().c_str());
+ std::string line;
+ while (std::getline(inf, line))
+ {
+ out << line << std::endl;
+ }
+ }
+
+private:
+ LLError::Settings* mOldSettings;
+ LLError::Recorder* mProxy;
+ NamedTempFile mTempFile;
+ std::ofstream mFile;
+};
+
class LLTestCallback : public tut::callback
{
public:
- LLTestCallback(bool verbose_mode, std::ostream *stream) :
- mVerboseMode(verbose_mode),
- mTotalTests(0),
- mPassedTests(0),
- mFailedTests(0),
- mSkippedTests(0),
- // By default, capture a shared_ptr to std::cout, with a no-op "deleter"
- // so that destroying the shared_ptr makes no attempt to delete std::cout.
- mStream(boost::shared_ptr<std::ostream>(&std::cout, boost::lambda::_1))
+ LLTestCallback(bool verbose_mode, std::ostream *stream,
+ boost::shared_ptr<LLReplayLog> replayer) :
+ mVerboseMode(verbose_mode),
+ mTotalTests(0),
+ mPassedTests(0),
+ mFailedTests(0),
+ mSkippedTests(0),
+ // By default, capture a shared_ptr to std::cout, with a no-op "deleter"
+ // so that destroying the shared_ptr makes no attempt to delete std::cout.
+ mStream(boost::shared_ptr<std::ostream>(&std::cout, boost::lambda::_1)),
+ mReplayer(replayer)
{
if (stream)
{
@@ -113,19 +181,32 @@ public:
virtual void run_started()
{
//std::cout << "run_started" << std::endl;
+ LL_INFOS("TestRunner")<<"Test Started"<< LL_ENDL;
}
virtual void group_started(const std::string& name) {
+ LL_INFOS("TestRunner")<<"Unit test group_started name=" << name << LL_ENDL;
*mStream << "Unit test group_started name=" << name << std::endl;
}
virtual void group_completed(const std::string& name) {
+ LL_INFOS("TestRunner")<<"Unit test group_completed name=" << name << LL_ENDL;
*mStream << "Unit test group_completed name=" << name << std::endl;
}
virtual void test_completed(const tut::test_result& tr)
{
++mTotalTests;
+
+ // If this test failed, dump requested log messages BEFORE stating the
+ // test result.
+ if (tr.result != tut::test_result::ok && tr.result != tut::test_result::skip)
+ {
+ mReplayer->replay(*mStream);
+ }
+ // Either way, clear stored messages in preparation for next test.
+ mReplayer->reset();
+
std::ostringstream out;
out << "[" << tr.group << ", " << tr.test;
if (! tr.name.empty())
@@ -167,9 +248,11 @@ public:
if(!tr.message.empty())
{
*mStream << ": '" << tr.message << "'";
+ LL_WARNS("TestRunner") << "not ok : "<<tr.message << LL_ENDL;
}
*mStream << std::endl;
}
+ LL_INFOS("TestRunner")<<out.str()<<LL_ENDL;
}
virtual int getFailedTests() const { return mFailedTests; }
@@ -206,6 +289,7 @@ protected:
int mFailedTests;
int mSkippedTests;
boost::shared_ptr<std::ostream> mStream;
+ boost::shared_ptr<LLReplayLog> mReplayer;
};
// TeamCity specific class which emits service messages
@@ -214,8 +298,9 @@ protected:
class LLTCTestCallback : public LLTestCallback
{
public:
- LLTCTestCallback(bool verbose_mode, std::ostream *stream) :
- LLTestCallback(verbose_mode, stream)
+ LLTCTestCallback(bool verbose_mode, std::ostream *stream,
+ boost::shared_ptr<LLReplayLog> replayer) :
+ LLTestCallback(verbose_mode, stream, replayer)
{
}
@@ -356,6 +441,14 @@ void stream_usage(std::ostream& s, const char* app)
++option;
}
+ s << app << " is also sensitive to environment variables:\n"
+ << "LOGTEST=level : for all tests, emit log messages at level 'level'\n"
+ << "LOGFAIL=level : only for failed tests, emit log messages at level 'level'\n"
+ << "where 'level' is one of ALL, DEBUG, INFO, WARN, ERROR, NONE.\n"
+ << "--debug is like LOGTEST=DEBUG, but --debug overrides LOGTEST.\n"
+ << "Setting LOGFAIL overrides both LOGTEST and --debug: the only log\n"
+ << "messages you will see will be for failed tests.\n\n";
+
s << "Examples:" << std::endl;
s << " " << app << " --verbose" << std::endl;
s << "\tRun all the tests and report all results." << std::endl;
@@ -363,6 +456,13 @@ void stream_usage(std::ostream& s, const char* app)
s << "\tList all available test groups." << std::endl;
s << " " << app << " --group=uuid" << std::endl;
s << "\tRun the test group 'uuid'." << std::endl;
+
+ s << "\n\n"
+ << "In any event, logs are recorded in the build directory by appending\n"
+ << "the suffix '.log' to the full path name of this application.\n"
+ << "If no level is specified as described above, these log files are at\n"
+ << "DEBUG level.\n"
+ ;
}
void stream_groups(std::ostream& s, const char* app)
@@ -389,11 +489,24 @@ int main(int argc, char **argv)
#ifndef LL_WINDOWS
::testing::InitGoogleMock(&argc, argv);
#endif
- LLError::initForApplication(".");
+ // LOGTEST overrides default, but can be overridden by --debug or LOGFAIL.
+ const char* LOGTEST = getenv("LOGTEST");
+ if (LOGTEST)
+ {
+ LLError::initForApplication(".", true /* log to stderr */);
+ LLError::setDefaultLevel(LLError::decodeLevel(LOGTEST));
+ }
+ else
+ {
+ LLError::initForApplication(".", false /* do not log to stderr */);
+ LLError::setDefaultLevel(LLError::LEVEL_DEBUG);
+ }
LLError::setFatalFunction(wouldHaveCrashed);
- LLError::setDefaultLevel(LLError::LEVEL_ERROR);
- //< *TODO: should come from error config file. Note that we
- // have a command line option that sets this to debug.
+ LLError::setPrintLocation(true);
+ std::string test_app_name(argv[0]);
+ std::string test_log = test_app_name + ".log";
+ LLFile::remove(test_log);
+ LLError::logToFile(test_log);
#ifdef CTYPE_WORKAROUND
ctype_workaround();
@@ -468,8 +581,6 @@ int main(int argc, char **argv)
wait_at_exit = true;
break;
case 'd':
- // *TODO: should come from error config file. We set it to
- // ERROR by default, so this allows full debug levels.
LLError::setDefaultLevel(LLError::LEVEL_DEBUG);
break;
case 'x':
@@ -484,14 +595,28 @@ int main(int argc, char **argv)
// run the tests
+ const char* LOGFAIL = getenv("LOGFAIL");
+ boost::shared_ptr<LLReplayLog> replayer;
+ // As described in stream_usage(), LOGFAIL overrides both --debug and
+ // LOGTEST.
+ if (LOGFAIL)
+ {
+ LLError::ELevel level = LLError::decodeLevel(LOGFAIL);
+ replayer.reset(new LLReplayLogReal(level, pool));
+ }
+ else
+ {
+ replayer.reset(new LLReplayLog());
+ }
+
LLTestCallback* mycallback;
if (getenv("TEAMCITY_PROJECT_NAME"))
{
- mycallback = new LLTCTestCallback(verbose_mode, output.get());
+ mycallback = new LLTCTestCallback(verbose_mode, output.get(), replayer);
}
else
{
- mycallback = new LLTestCallback(verbose_mode, output.get());
+ mycallback = new LLTestCallback(verbose_mode, output.get(), replayer);
}
tut::runner.get().set_callback(mycallback);
diff --git a/indra/test/test.h b/indra/test/test.h
index 40c94283ec..40c94283ec 100644..100755
--- a/indra/test/test.h
+++ b/indra/test/test.h
diff --git a/indra/test/test_llmanifest.py b/indra/test/test_llmanifest.py
index a97abbc6ee..a97abbc6ee 100644..100755
--- a/indra/test/test_llmanifest.py
+++ b/indra/test/test_llmanifest.py
diff --git a/indra/test_apps/llfbconnecttest/CMakeLists.txt b/indra/test_apps/llfbconnecttest/CMakeLists.txt
new file mode 100644
index 0000000000..f56329a010
--- /dev/null
+++ b/indra/test_apps/llfbconnecttest/CMakeLists.txt
@@ -0,0 +1,304 @@
+# -*- cmake -*-
+project(llfbconnecttest)
+
+include(00-Common)
+include(FindOpenGL)
+include(LLCommon)
+include(LLPlugin)
+include(Linking)
+include(LLSharedLibs)
+include(PluginAPI)
+include(LLImage)
+include(LLMath)
+include(LLMessage)
+include(LLRender)
+include(LLWindow)
+include(Glut)
+include(Glui)
+
+include_directories(
+ ${LLPLUGIN_INCLUDE_DIRS}
+ ${LLCOMMON_INCLUDE_DIRS}
+ ${LLIMAGE_INCLUDE_DIRS}
+ ${LLMATH_INCLUDE_DIRS}
+ ${LLMESSAGE_INCLUDE_DIRS}
+ ${LLRENDER_INCLUDE_DIRS}
+ ${LLWINDOW_INCLUDE_DIRS}
+)
+
+if (DARWIN)
+ include(CMakeFindFrameworks)
+ find_library(COREFOUNDATION_LIBRARY CoreFoundation)
+endif (DARWIN)
+
+### llfbconnecttest
+
+set(llfbconnecttest_SOURCE_FILES
+ llfbconnecttest.cpp
+ llfbconnecttest.h
+ bookmarks.txt
+ )
+
+add_executable(llfbconnecttest
+ WIN32
+ MACOSX_BUNDLE
+ ${llfbconnecttest_SOURCE_FILES}
+)
+
+set_target_properties(llfbconnecttest
+ PROPERTIES
+ WIN32_EXECUTABLE
+ FALSE
+)
+
+target_link_libraries(llfbconnecttest
+ ${GLUT_LIBRARY}
+ ${GLUI_LIBRARY}
+ ${OPENGL_LIBRARIES}
+ ${LLPLUGIN_LIBRARIES}
+ ${LLMESSAGE_LIBRARIES}
+ ${LLCOMMON_LIBRARIES}
+ ${PLUGIN_API_WINDOWS_LIBRARIES}
+)
+
+if (DARWIN)
+ # The testbed needs to use a couple of CoreFoundation calls now, to deal with being a bundled app.
+ target_link_libraries(llfbconnecttest
+ ${COREFOUNDATION_LIBRARY}
+ )
+endif (DARWIN)
+
+add_dependencies(llfbconnecttest
+ stage_third_party_libs
+ SLPlugin
+ media_plugin_webkit
+ ${LLPLUGIN_LIBRARIES}
+ ${LLMESSAGE_LIBRARIES}
+ ${LLCOMMON_LIBRARIES}
+)
+
+# turn off weird GLUI pragma
+add_definitions(-DGLUI_NO_LIB_PRAGMA)
+
+if (DARWIN OR LINUX)
+ # glui.h contains code that triggers the "overloaded-virtual" warning in gcc.
+ set_source_files_properties(llfbconnecttest.cpp PROPERTIES COMPILE_FLAGS "-Wno-overloaded-virtual")
+endif (DARWIN OR LINUX)
+
+# Gather build products of the various dependencies into the build directory for the testbed.
+
+if (DARWIN)
+ # path inside the app bundle where we'll need to copy plugins and other related files
+ set(PLUGINS_DESTINATION_DIR
+ ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/llfbconnecttest.app/Contents/Resources
+ )
+
+ # create the Contents/Resources directory
+ add_custom_command(
+ TARGET llfbconnecttest POST_BUILD
+ COMMAND ${CMAKE_COMMAND}
+ ARGS
+ -E
+ make_directory
+ ${PLUGINS_DESTINATION_DIR}
+ COMMENT "Creating Resources directory in app bundle."
+ )
+else (DARWIN)
+ set(PLUGINS_DESTINATION_DIR
+ ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/
+ )
+endif (DARWIN)
+
+get_target_property(BUILT_SLPLUGIN SLPlugin LOCATION)
+add_custom_command(TARGET llfbconnecttest POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E copy ${BUILT_SLPLUGIN} ${PLUGINS_DESTINATION_DIR}
+ DEPENDS ${BUILT_SLPLUGIN}
+)
+
+get_target_property(BUILT_LLCOMMON llcommon LOCATION)
+add_custom_command(TARGET llfbconnecttest POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E copy ${BUILT_LLCOMMON} ${PLUGINS_DESTINATION_DIR}
+ DEPENDS ${BUILT_LLCOMMON}
+)
+
+
+if (DARWIN OR WINDOWS)
+ get_target_property(BUILT_WEBKIT_PLUGIN media_plugin_webkit LOCATION)
+ add_custom_command(TARGET llfbconnecttest POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E copy ${BUILT_WEBKIT_PLUGIN} ${PLUGINS_DESTINATION_DIR}
+ DEPENDS ${BUILT_WEBKIT_PLUGIN}
+ )
+
+ # copy over bookmarks file if llfbconnecttest gets built
+ get_target_property(BUILT_LLFBCONNECTTEST llfbconnecttest LOCATION)
+ add_custom_command(TARGET llfbconnecttest POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/bookmarks.txt ${CMAKE_CURRENT_BINARY_DIR}/
+ DEPENDS ${BUILT_LLFBCONNECTTEST}
+ )
+ # also copy it to the same place as SLPlugin, which is what the mac wants...
+ add_custom_command(TARGET llfbconnecttest POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/bookmarks.txt ${PLUGINS_DESTINATION_DIR}
+ DEPENDS ${BUILT_LLFBCONNECTTEST}
+ )
+endif (DARWIN OR WINDOWS)
+
+if (DARWIN)
+ add_custom_command(TARGET llfbconnecttest POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E copy ${ARCH_PREBUILT_DIRS_RELEASE}/libllqtwebkit.dylib ${PLUGINS_DESTINATION_DIR}
+ DEPENDS ${ARCH_PREBUILT_DIRS_RELEASE}/libllqtwebkit.dylib
+ )
+endif (DARWIN)
+
+if(WINDOWS)
+ #********************
+ # Plugin test library deploy
+ #
+ # Debug config runtime files required for the FB connect test
+ set(fbconnecttest_debug_src_dir "${ARCH_PREBUILT_DIRS_DEBUG}")
+ set(fbconnecttest_debug_files
+ libeay32.dll
+ libglib-2.0-0.dll
+ libgmodule-2.0-0.dll
+ libgobject-2.0-0.dll
+ libgthread-2.0-0.dll
+ qtcored4.dll
+ qtguid4.dll
+ qtnetworkd4.dll
+ qtopengld4.dll
+ qtwebkitd4.dll
+ ssleay32.dll
+ )
+ copy_if_different(
+ ${fbconnecttest_debug_src_dir}
+ "${CMAKE_CURRENT_BINARY_DIR}/Debug"
+ out_targets
+ ${fbconnecttest_debug_files}
+ )
+ set(fbconnect_test_targets ${fbconnect_test_targets} ${out_targets})
+
+ # Debug config runtime files required for the FB connect test (Qt image format plugins)
+ set(fbconecttest_debug_src_dir "${ARCH_PREBUILT_DIRS_DEBUG}/imageformats")
+ set(fbconecttest_debug_files
+ qgifd4.dll
+ qicod4.dll
+ qjpegd4.dll
+ qmngd4.dll
+ qsvgd4.dll
+ qtiffd4.dll
+ )
+ copy_if_different(
+ ${fbconecttest_debug_src_dir}
+ "${CMAKE_CURRENT_BINARY_DIR}/Debug/imageformats"
+ out_targets
+ ${fbconecttest_debug_files}
+ )
+ set(fbconnect_test_targets ${fbconnect_test_targets} ${out_targets})
+
+ # Debug config runtime files required for the FB connect test (Qt codec plugins)
+ set(fbconnecttest_debug_src_dir "${ARCH_PREBUILT_DIRS_DEBUG}/codecs")
+ set(fbconnecttest_debug_files
+ qcncodecsd4.dll
+ qjpcodecsd4.dll
+ qkrcodecsd4.dll
+ qtwcodecsd4.dll
+ )
+ copy_if_different(
+ ${fbconnecttest_debug_src_dir}
+ "${CMAKE_CURRENT_BINARY_DIR}/Debug/codecs"
+ out_targets
+ ${fbconnecttest_debug_files}
+ )
+ set(fbconnect_test_targets ${fbconnect_test_targets} ${out_targets})
+
+ # Release & ReleaseDebInfo config runtime files required for the FB connect test
+ set(fbconnecttest_release_src_dir "${ARCH_PREBUILT_DIRS_RELEASE}")
+ set(fbconnecttest_release_files
+ libeay32.dll
+ libglib-2.0-0.dll
+ libgmodule-2.0-0.dll
+ libgobject-2.0-0.dll
+ libgthread-2.0-0.dll
+ qtcore4.dll
+ qtgui4.dll
+ qtnetwork4.dll
+ qtopengl4.dll
+ qtwebkit4.dll
+ qtxmlpatterns4.dll
+ ssleay32.dll
+ )
+ copy_if_different(
+ ${fbconnecttest_release_src_dir}
+ "${CMAKE_CURRENT_BINARY_DIR}/Release"
+ out_targets
+ ${fbconnecttest_release_files}
+ )
+ set(fbconnect_test_targets ${fbconnect_test_targets} ${out_targets})
+
+ copy_if_different(
+ ${fbconnecttest_release_src_dir}
+ "${CMAKE_CURRENT_BINARY_DIR}/RelWithDebInfo"
+ out_targets
+ ${fbconnecttest_release_files}
+ )
+ set(fbconnect_test_targets ${fbconnect_test_targets} ${out_targets})
+
+ # Release & ReleaseDebInfo config runtime files required for the FB connect test (Qt image format plugins)
+ set(fbconnecttest_release_src_dir "${ARCH_PREBUILT_DIRS_RELEASE}/imageformats")
+ set(fbconnecttest_release_files
+ qgif4.dll
+ qico4.dll
+ qjpeg4.dll
+ qmng4.dll
+ qsvg4.dll
+ qtiff4.dll
+ )
+ copy_if_different(
+ ${fbconnecttest_release_src_dir}
+ "${CMAKE_CURRENT_BINARY_DIR}/Release/imageformats"
+ out_targets
+ ${fbconnecttest_release_files}
+ )
+ set(fbconnect_test_targets ${fbconnect_test_targets} ${out_targets})
+
+ copy_if_different(
+ ${fbconnecttest_release_src_dir}
+ "${CMAKE_CURRENT_BINARY_DIR}/RelWithDebInfo/imageformats"
+ out_targets
+ ${fbconnecttest_release_files}
+ )
+ set(fbconnect_test_targets ${fbconnect_test_targets} ${out_targets})
+
+ # Release & ReleaseDebInfo config runtime files required for the FB connect test (Qt codec plugins)
+ set(fbconnecttest_release_src_dir "${ARCH_PREBUILT_DIRS_RELEASE}/codecs")
+ set(fbconnecttest_release_files
+ qcncodecs4.dll
+ qjpcodecs4.dll
+ qkrcodecs4.dll
+ qtwcodecs4.dll
+ )
+ copy_if_different(
+ ${fbconnecttest_release_src_dir}
+ "${CMAKE_CURRENT_BINARY_DIR}/Release/codecs"
+ out_targets
+ ${fbconnecttest_release_files}
+ )
+ set(fbconnect_test_targets ${fbconnect_test_targets} ${out_targets})
+
+ copy_if_different(
+ ${fbconnecttest_release_src_dir}
+ "${CMAKE_CURRENT_BINARY_DIR}/RelWithDebInfo/codecs"
+ out_targets
+ ${fbconnecttest_release_files}
+ )
+ set(fbconnect_test_targets ${fbconnect_test_targets} ${out_targets})
+
+ add_custom_target(copy_fbconnecttest_libs ALL
+ DEPENDS
+ ${fbconnect_test_targets}
+ )
+
+ add_dependencies(llfbconnecttest copy_fbconnecttest_libs)
+
+endif(WINDOWS)
+
+ll_deploy_sharedlibs_command(llfbconnecttest)
diff --git a/indra/test_apps/llfbconnecttest/bookmarks.txt b/indra/test_apps/llfbconnecttest/bookmarks.txt
new file mode 100644
index 0000000000..3995627ea9
--- /dev/null
+++ b/indra/test_apps/llfbconnecttest/bookmarks.txt
@@ -0,0 +1,4 @@
+# format is description, url (don't put ',' chars in description :)
+# if no ',' found, whole line is used for both description and url
+Google Home Page,http://www.google.com
+Facebook Home Page,http://www.facebook.com
diff --git a/indra/test_apps/llfbconnecttest/llfbconnecttest.cpp b/indra/test_apps/llfbconnecttest/llfbconnecttest.cpp
new file mode 100644
index 0000000000..483a15c468
--- /dev/null
+++ b/indra/test_apps/llfbconnecttest/llfbconnecttest.cpp
@@ -0,0 +1,2394 @@
+/**
+ * @file LLFBConnectTest.cpp
+ * @brief Facebook Connect Test App
+ *
+ * $LicenseInfo:firstyear=2008&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+#include "indra_constants.h"
+
+#include "llapr.h"
+#include "llerrorcontrol.h"
+
+#include <math.h>
+#include <iomanip>
+#include <sstream>
+#include <ctime>
+
+#include "llfbconnecttest.h"
+
+#if __APPLE__
+ #include <GLUT/glut.h>
+ #include <CoreFoundation/CoreFoundation.h>
+#else
+ #define FREEGLUT_STATIC
+ #include "GL/freeglut.h"
+ #define GLUI_FREEGLUT
+#endif
+
+#if LL_WINDOWS
+#pragma warning(disable: 4263)
+#pragma warning(disable: 4264)
+#endif
+#include "glui.h"
+
+
+LLFBConnectTest* gApplication = 0;
+static void gluiCallbackWrapper( int control_id );
+
+////////////////////////////////////////////////////////////////////////////////
+//
+static bool isTexture( GLuint texture )
+{
+ bool result = false;
+
+ // glIsTexture will sometimes return false for real textures... do this instead.
+ if(texture != 0)
+ result = true;
+
+ return result;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+mediaPanel::mediaPanel()
+{
+ mMediaTextureHandle = 0;
+ mPickTextureHandle = 0;
+ mMediaSource = NULL;
+ mPickTexturePixels = NULL;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+mediaPanel::~mediaPanel()
+{
+ // delete OpenGL texture handles
+ if ( isTexture( mPickTextureHandle ) )
+ {
+ std::cerr << "remMediaPanel: deleting pick texture " << mPickTextureHandle << std::endl;
+ glDeleteTextures( 1, &mPickTextureHandle );
+ mPickTextureHandle = 0;
+ }
+
+ if ( isTexture( mMediaTextureHandle ) )
+ {
+ std::cerr << "remMediaPanel: deleting media texture " << mMediaTextureHandle << std::endl;
+ glDeleteTextures( 1, &mMediaTextureHandle );
+ mMediaTextureHandle = 0;
+ }
+
+ if(mPickTexturePixels)
+ {
+ delete mPickTexturePixels;
+ }
+
+ if(mMediaSource)
+ {
+ delete mMediaSource;
+ }
+
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+LLFBConnectTest::LLFBConnectTest( int app_window, int window_width, int window_height ) :
+ mVersionMajor( 2 ),
+ mVersionMinor( 0 ),
+ mVersionPatch( 0 ),
+ mMaxPanels( 25 ),
+ mViewportAspect( 0 ),
+ mAppWindow( app_window ),
+ mCurMouseX( 0 ),
+ mCurMouseY( 0 ),
+ mFuzzyMedia( true ),
+ mSelectedPanel( 0 ),
+ mDistanceCameraToSelectedGeometry( 0.0f ),
+ //mMediaBrowserControlEnableCookies( 0 ),
+ mMediaBrowserControlBackButton( 0 ),
+ mMediaBrowserControlForwardButton( 0 ),
+ //mMediaTimeControlVolume( 100 ),
+ //mMediaTimeControlSeekSeconds( 0 ),
+ //mGluiMediaTimeControlWindowFlag( true ),
+ mGluiMediaBrowserControlWindowFlag( true ),
+ mMediaBrowserControlBackButtonFlag( true ),
+ mMediaBrowserControlForwardButtonFlag( true ),
+ mHomeWebUrl( "https://cryptic-ridge-1632.herokuapp.com/" )
+{
+ // debugging spam
+ std::cout << std::endl << " GLUT version: " << "3.7.6" << std::endl; // no way to get real version from GLUT
+ std::cout << std::endl << " GLUI version: " << GLUI_Master.get_version() << std::endl;
+ std::cout << std::endl << "Media Plugin Test version: " << mVersionMajor << "." << mVersionMinor << "." << mVersionPatch << std::endl;
+
+ // bookmark title
+ mBookmarks.push_back( std::pair< std::string, std::string >( "--- Bookmarks ---", "" ) );
+
+ // insert hardcoded URLs here as required for testing
+ //mBookmarks.push_back( std::pair< std::string, std::string >( "description", "url" ) );
+
+ // read bookmarks from file.
+ // note: uses command in ./CmakeLists.txt which copies bookmmarks file from source directory
+ // to app directory (WITHOUT build configuration dir) (this is cwd in Windows within MSVC)
+ // For example, test_apps\llplugintest and not test_apps\llplugintest\Release
+ // This may need to be changed for Mac/Linux builds.
+ // See https://jira.lindenlab.com/browse/DEV-31350 for large list of media URLs from AGNI
+ const std::string bookmarks_filename( "bookmarks.txt" );
+ std::ifstream file_handle( bookmarks_filename.c_str() );
+ if ( file_handle.is_open() )
+ {
+ std::cout << "Reading bookmarks for test" << std::endl;
+ while( ! file_handle.eof() )
+ {
+ std::string line;
+ std::getline( file_handle, line );
+ if ( file_handle.eof() )
+ break;
+
+ if ( line.substr( 0, 1 ) != "#" )
+ {
+ size_t comma_pos = line.find_first_of( ',' );
+ if ( comma_pos != std::string::npos )
+ {
+ std::string description = line.substr( 0, comma_pos );
+ std::string url = line.substr( comma_pos + 1 );
+ mBookmarks.push_back( std::pair< std::string, std::string >( description, url ) );
+ }
+ else
+ {
+ mBookmarks.push_back( std::pair< std::string, std::string >( line, line ) );
+ };
+ };
+ };
+ std::cout << "Read " << mBookmarks.size() << " bookmarks" << std::endl;
+ }
+ else
+ {
+ std::cout << "Unable to read bookmarks from file: " << bookmarks_filename << std::endl;
+ };
+
+ // initialize linden lab APR module
+ ll_init_apr();
+
+ // Set up llerror logging
+ {
+ LLError::initForApplication(".");
+ LLError::setDefaultLevel(LLError::LEVEL_INFO);
+ //LLError::setTagLevel("Plugin", LLError::LEVEL_DEBUG);
+ }
+
+ // lots of randomness in this app
+ srand( ( unsigned int )time( 0 ) );
+
+ // build GUI
+ makeChrome();
+
+ // OpenGL initialilzation
+ glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
+ glClearDepth( 1.0f );
+ glEnable( GL_DEPTH_TEST );
+ glEnable( GL_COLOR_MATERIAL );
+ glColorMaterial( GL_FRONT, GL_AMBIENT_AND_DIFFUSE );
+ glDepthFunc( GL_LEQUAL );
+ glEnable( GL_TEXTURE_2D );
+ glDisable( GL_BLEND );
+ glColor3f( 1.0f, 1.0f, 1.0f );
+ glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
+ glPixelStorei( GL_UNPACK_ROW_LENGTH, 0 );
+
+ // start with a sane view
+ resetView();
+
+ // initial media panel
+ const int num_initial_panels = 1;
+ for( int i = 0; i < num_initial_panels; ++i )
+ {
+ //addMediaPanel( mBookmarks[ rand() % ( mBookmarks.size() - 1 ) + 1 ].second );
+ addMediaPanel( mHomeWebUrl );
+ };
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+LLFBConnectTest::~LLFBConnectTest()
+{
+ // delete all media panels
+ for( int i = 0; i < (int)mMediaPanels.size(); ++i )
+ {
+ remMediaPanel( mMediaPanels[ i ] );
+ };
+
+ // Stop the plugin read thread if it's running.
+ LLPluginProcessParent::setUseReadThread(false);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLFBConnectTest::reshape( int width, int height )
+{
+ // update viewport (the active window inside the chrome)
+ int viewport_x, viewport_y;
+ int viewport_height, viewport_width;
+ GLUI_Master.get_viewport_area( &viewport_x, &viewport_y, &viewport_width, &viewport_height );
+ mViewportAspect = (float)( viewport_width ) / (float)( viewport_height );
+ glViewport( viewport_x, viewport_y, viewport_width, viewport_height );
+
+ // save these as we'll need them later
+ mWindowWidth = width;
+ mWindowHeight = height;
+
+ // adjust size of URL bar so it doesn't get clipped
+ mUrlEdit->set_w( mWindowWidth - 360 );
+
+ // GLUI requires this
+ if ( glutGetWindow() != mAppWindow )
+ glutSetWindow( mAppWindow );
+
+ // trigger re-display
+ glutPostRedisplay();
+};
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLFBConnectTest::bindTexture(GLuint texture, GLint row_length, GLint alignment)
+{
+ glEnable( GL_TEXTURE_2D );
+
+ glBindTexture( GL_TEXTURE_2D, texture );
+ glPixelStorei( GL_UNPACK_ROW_LENGTH, row_length );
+ glPixelStorei( GL_UNPACK_ALIGNMENT, alignment );
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+bool LLFBConnectTest::checkGLError(const char *name)
+{
+ bool result = false;
+ GLenum error = glGetError();
+
+ if(error != GL_NO_ERROR)
+ {
+ // For some reason, glGenTextures is returning GL_INVALID_VALUE...
+ std::cout << name << " ERROR 0x" << std::hex << error << std::dec << std::endl;
+ result = true;
+ }
+
+ return result;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+GLfloat LLFBConnectTest::distanceToCamera( GLfloat point_x, GLfloat point_y, GLfloat point_z )
+{
+ GLdouble camera_pos_x = 0.0f;
+ GLdouble camera_pos_y = 0.0f;
+ GLdouble camera_pos_z = 0.0f;
+
+ GLdouble modelMatrix[16];
+ GLdouble projMatrix[16];
+ GLint viewport[4];
+
+ glGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix);
+ glGetDoublev(GL_PROJECTION_MATRIX, projMatrix);
+ glGetIntegerv(GL_VIEWPORT, viewport);
+
+ gluUnProject(
+ (viewport[2]-viewport[0])/2 , (viewport[3]-viewport[1])/2,
+ 0.0,
+ modelMatrix, projMatrix, viewport,
+ &camera_pos_x, &camera_pos_y, &camera_pos_z );
+
+ GLfloat distance =
+ sqrt( ( camera_pos_x - point_x ) * ( camera_pos_x - point_x ) +
+ ( camera_pos_y - point_y ) * ( camera_pos_y - point_y ) +
+ ( camera_pos_z - point_z ) * ( camera_pos_z - point_z ) );
+
+ return distance;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLFBConnectTest::drawGeometry( int panel, bool selected )
+{
+ // texture coordinates for each panel
+ GLfloat non_opengl_texture_coords[ 8 ] = { 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f };
+ GLfloat opengl_texture_coords[ 8 ] = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f };
+
+ GLfloat *texture_coords = mMediaPanels[ panel ]->mAppTextureCoordsOpenGL?opengl_texture_coords:non_opengl_texture_coords;
+
+ // base coordinates for each panel
+ GLfloat base_vertex_pos[ 8 ] = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f };
+
+ // calculate posiitons
+ const int num_panels = (int)mMediaPanels.size();
+ const int num_rows = (int)sqrt( (float)num_panels );
+ const int num_cols = num_panels / num_rows;
+ const int panel_x = ( panel / num_rows );
+ const int panel_y = ( panel % num_rows );
+
+ // default spacing is small - make it larger if checkbox set - for testing positional audio
+ float spacing = 0.1f;
+ //if ( mLargePanelSpacing )
+ // spacing = 2.0f;
+
+ const GLfloat offset_x = num_cols * ( 1.0 + spacing ) / 2;
+ const GLfloat offset_y = num_rows * ( 1.0 + spacing ) / 2;
+
+ // Adjust for media aspect ratios
+ {
+ float aspect = 1.0f;
+
+ if(mMediaPanels[ panel ]->mMediaHeight != 0)
+ {
+ aspect = (float)mMediaPanels[ panel ]->mMediaWidth / (float)mMediaPanels[ panel ]->mMediaHeight;
+ }
+
+ if(aspect > 1.0f)
+ {
+ // media is wider than it is high -- adjust the top and bottom in
+ for( int corner = 0; corner < 4; ++corner )
+ {
+ float temp = base_vertex_pos[corner * 2 + 1];
+
+ if(temp < 0.5f)
+ temp += 0.5 - (0.5f / aspect);
+ else
+ temp -= 0.5 - (0.5f / aspect);
+
+ base_vertex_pos[corner * 2 + 1] = temp;
+ }
+ }
+ else if(aspect < 1.0f)
+ {
+ // media is higher than it is wide -- adjust the left and right sides in
+ for( int corner = 0; corner < 4; ++corner )
+ {
+ float temp = base_vertex_pos[corner * 2];
+
+ if(temp < 0.5f)
+ temp += 0.5f - (0.5f * aspect);
+ else
+ temp -= 0.5f - (0.5f * aspect);
+
+ base_vertex_pos[corner * 2] = temp;
+ }
+ }
+ }
+
+ glBegin( GL_QUADS );
+ for( int corner = 0; corner < 4; ++corner )
+ {
+ glTexCoord2f( texture_coords[ corner * 2 ], texture_coords[ corner * 2 + 1 ] );
+ GLfloat x = base_vertex_pos[ corner * 2 ] + panel_x * ( 1.0 + spacing ) - offset_x + spacing / 2.0f;
+ GLfloat y = base_vertex_pos[ corner * 2 + 1 ] + panel_y * ( 1.0 + spacing ) - offset_y + spacing / 2.0f;
+
+ glVertex3f( x, y, 0.0f );
+ };
+ glEnd();
+
+ // calculate distance to this panel if it's selected
+ if ( selected )
+ {
+ GLfloat point_x = base_vertex_pos[ 0 ] + panel_x * ( 1.0 + spacing ) - offset_x + spacing / 2.0f;
+ GLfloat point_y = base_vertex_pos[ 0 + 1 ] + panel_y * ( 1.0 + spacing ) - offset_y + spacing / 2.0f;
+ GLfloat point_z = 0.0f;
+ mDistanceCameraToSelectedGeometry = distanceToCamera( point_x, point_y, point_z );
+ };
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//
+void LLFBConnectTest::startPanelHighlight( float red, float green, float blue, float line_width )
+{
+ glPushAttrib( GL_ALL_ATTRIB_BITS );
+ glEnable( GL_POLYGON_OFFSET_FILL );
+ glPolygonOffset( -2.5f, -2.5f );
+ glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
+ glLineWidth( line_width );
+ glColor3f( red, green, blue );
+ glDisable( GL_TEXTURE_2D );
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//
+void LLFBConnectTest::endPanelHighlight()
+{
+ glPopAttrib();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLFBConnectTest::draw( int draw_type )
+{
+ for( int panel = 0; panel < (int)mMediaPanels.size(); ++panel )
+ {
+ // drawing pick texture
+ if ( draw_type == DrawTypePickTexture )
+ {
+ // only bother with pick if we have something to render
+ // Actually, we need to pick even if we're not ready to render.
+ // Otherwise you can't select and remove a panel which has gone bad.
+ //if ( mMediaPanels[ panel ]->mReadyToRender )
+ {
+ glMatrixMode( GL_TEXTURE );
+ glPushMatrix();
+
+ // pick texture is a power of 2 so no need to scale
+ glLoadIdentity();
+
+ // bind to media texture
+ glLoadIdentity();
+ bindTexture( mMediaPanels[ panel ]->mPickTextureHandle );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
+
+ // draw geometry using pick texture
+ drawGeometry( panel, false );
+
+ glMatrixMode( GL_TEXTURE );
+ glPopMatrix();
+ };
+ }
+ else
+ if ( draw_type == DrawTypeMediaTexture )
+ {
+ bool texture_valid = false;
+ bool plugin_exited = false;
+
+ if(mMediaPanels[ panel ]->mMediaSource)
+ {
+ texture_valid = mMediaPanels[ panel ]->mMediaSource->textureValid();
+ plugin_exited = mMediaPanels[ panel ]->mMediaSource->isPluginExited();
+ }
+
+ // save texture matrix (changes for each panel)
+ glMatrixMode( GL_TEXTURE );
+ glPushMatrix();
+
+ // only process texture if the media is ready to draw
+ // (we still want to draw the geometry)
+ if ( mMediaPanels[ panel ]->mReadyToRender && texture_valid )
+ {
+ // bind to media texture
+ bindTexture( mMediaPanels[ panel ]->mMediaTextureHandle );
+
+ if ( mFuzzyMedia )
+ {
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
+ }
+ else
+ {
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
+ }
+
+ // scale to fit panel
+ glScalef( mMediaPanels[ panel ]->mTextureScaleX,
+ mMediaPanels[ panel ]->mTextureScaleY,
+ 1.0f );
+ };
+
+ float intensity = plugin_exited?0.25f:1.0f;
+
+ // highlight the selected panel
+ if ( mSelectedPanel && ( mMediaPanels[ panel ]->mId == mSelectedPanel->mId ) )
+ {
+ startPanelHighlight( intensity, intensity, 0.0f, 5.0f );
+ drawGeometry( panel, true );
+ endPanelHighlight();
+ }
+ else
+ // this panel not able to render yet since it
+ // doesn't have enough information
+ if ( !mMediaPanels[ panel ]->mReadyToRender )
+ {
+ startPanelHighlight( intensity, 0.0f, 0.0f, 2.0f );
+ drawGeometry( panel, false );
+ endPanelHighlight();
+ }
+ else
+ // just display a border around the media
+ {
+ startPanelHighlight( 0.0f, intensity, 0.0f, 2.0f );
+ drawGeometry( panel, false );
+ endPanelHighlight();
+ };
+
+ if ( mMediaPanels[ panel ]->mReadyToRender && texture_valid )
+ {
+ // draw visual geometry
+ drawGeometry( panel, false );
+ }
+
+ // restore texture matrix (changes for each panel)
+ glMatrixMode( GL_TEXTURE );
+ glPopMatrix();
+ };
+ };
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLFBConnectTest::display()
+{
+ // GLUI requires this
+ if ( glutGetWindow() != mAppWindow )
+ glutSetWindow( mAppWindow );
+
+ // start with a clean slate
+ glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
+ glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
+
+ // set up OpenGL view
+ glMatrixMode( GL_PROJECTION );
+ glLoadIdentity();
+ glFrustum( -mViewportAspect * 0.04f, mViewportAspect * 0.04f, -0.04f, 0.04f, 0.1f, 50.0f );
+ glMatrixMode( GL_MODELVIEW );
+ glLoadIdentity();
+ glTranslatef( 0.0, 0.0, 0.0f );
+ glTranslatef( mViewPos[ 0 ], mViewPos[ 1 ], -mViewPos[ 2 ] );
+ glMultMatrixf( mViewRotation );
+
+ // draw pick texture
+ draw( DrawTypePickTexture );
+
+ // read colors and get coordinate values
+ glReadPixels( mCurMouseX, mCurMouseY, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, mPixelReadColor );
+
+ // clear the pick render (otherwise it may depth-fight with the textures rendered later)
+ glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
+
+ // draw visible geometry
+ draw( DrawTypeMediaTexture );
+
+ glutSwapBuffers();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLFBConnectTest::idle()
+{
+// checkGLError("LLFBConnectTest::idle");
+
+ // GLUI requires this
+ if ( glutGetWindow() != mAppWindow )
+ glutSetWindow( mAppWindow );
+
+ // random creation/destruction of panels enabled?
+/*
+ const time_t panel_timeout_time = 5;
+ if ( mRandomPanelCount )
+ {
+ // time for a change
+ static time_t last_panel_time = 0;
+ if ( time( NULL ) - last_panel_time > panel_timeout_time )
+ {
+ if ( rand() % 2 == 0 )
+ {
+ if ( mMediaPanels.size() < 16 )
+ {
+ std::cout << "Randomly adding new panel" << std::endl;
+ addMediaPanel( mBookmarks[ rand() % ( mBookmarks.size() - 1 ) + 1 ].second );
+ };
+ }
+ else
+ {
+ if ( mMediaPanels.size() > 0 )
+ {
+ std::cout << "Deleting selected panel" << std::endl;
+ remMediaPanel( mSelectedPanel );
+ };
+ };
+ time( &last_panel_time );
+ };
+ };
+
+ // random selection of bookmarks enabled?
+ const time_t bookmark_timeout_time = 5;
+ if ( mRandomBookmarks )
+ {
+ // time for a change
+ static time_t last_bookmark_time = 0;
+ if ( time( NULL ) - last_bookmark_time > bookmark_timeout_time )
+ {
+ // go to a different random bookmark on each panel
+ for( int panel = 0; panel < (int)mMediaPanels.size(); ++panel )
+ {
+ std::string uri = mBookmarks[ rand() % ( mBookmarks.size() - 1 ) + 1 ].second;
+
+ std::cout << "Random: navigating to : " << uri << std::endl;
+
+ std::string mime_type = mimeTypeFromUrl( uri );
+
+ if ( mime_type != mMediaPanels[ panel ]->mMimeType )
+ {
+ replaceMediaPanel( mMediaPanels[ panel ], uri );
+ }
+ else
+ {
+ mMediaPanels[ panel ]->mMediaSource->loadURI( uri );
+ mMediaPanels[ panel ]->mMediaSource->start();
+ };
+ };
+
+ time( &last_bookmark_time );
+ };
+ };
+*/
+ // update UI
+ if ( mSelectedPanel )
+ {
+ // set volume based on slider if we have time media
+ //if ( mGluiMediaTimeControlWindowFlag )
+ //{
+ // mSelectedPanel->mMediaSource->setVolume( (float)mMediaTimeControlVolume / 100.0f );
+ //};
+
+ // NOTE: it is absurd that we need cache the state of GLUI controls
+ // but enabling/disabling controls drags framerate from 500+
+ // down to 15. Not a problem for plugin system - only this test
+ // enable/disable time based UI controls based on type of plugin
+ if ( mSelectedPanel->mMediaSource->pluginSupportsMediaTime() )
+ {
+ /*
+ if ( ! mGluiMediaTimeControlWindowFlag )
+ {
+ mGluiMediaTimeControlWindow->enable();
+ mGluiMediaTimeControlWindowFlag = true;
+ };
+ */
+ }
+ else
+ {
+ /*
+ if ( mGluiMediaTimeControlWindowFlag )
+ {
+ mGluiMediaTimeControlWindow->disable();
+ mGluiMediaTimeControlWindowFlag = false;
+ };
+ */
+ };
+
+ // enable/disable browser based UI controls based on type of plugin
+ if ( mSelectedPanel->mMediaSource->pluginSupportsMediaBrowser() )
+ {
+ if ( ! mGluiMediaBrowserControlWindowFlag )
+ {
+ mGluiMediaBrowserControlWindow->enable();
+ mGluiMediaBrowserControlWindowFlag = true;
+ };
+ }
+ else
+ {
+ if ( mGluiMediaBrowserControlWindowFlag )
+ {
+ mGluiMediaBrowserControlWindow->disable();
+ mGluiMediaBrowserControlWindowFlag = false;
+ };
+ };
+
+ // enable/disable browser back button depending on browser history
+ if ( mSelectedPanel->mMediaSource->getHistoryBackAvailable() )
+ {
+ if ( ! mMediaBrowserControlBackButtonFlag )
+ {
+ mMediaBrowserControlBackButton->enable();
+ mMediaBrowserControlBackButtonFlag = true;
+ };
+ }
+ else
+ {
+ if ( mMediaBrowserControlBackButtonFlag )
+ {
+ mMediaBrowserControlBackButton->disable();
+ mMediaBrowserControlBackButtonFlag = false;
+ };
+ };
+
+ // enable/disable browser forward button depending on browser history
+ if ( mSelectedPanel->mMediaSource->getHistoryForwardAvailable() )
+ {
+ if ( ! mMediaBrowserControlForwardButtonFlag )
+ {
+ mMediaBrowserControlForwardButton->enable();
+ mMediaBrowserControlForwardButtonFlag = true;
+ };
+ }
+ else
+ {
+ if ( mMediaBrowserControlForwardButtonFlag )
+ {
+ mMediaBrowserControlForwardButton->disable();
+ mMediaBrowserControlForwardButtonFlag = false;
+ };
+ };
+
+ // NOTE: This is *very* slow and not worth optimising
+ updateStatusBar();
+ };
+
+ // update all the panels
+ for( int panel_index = 0; panel_index < (int)mMediaPanels.size(); ++panel_index )
+ {
+ mediaPanel *panel = mMediaPanels[ panel_index ];
+
+ // call plugins idle function so it can potentially update itself
+ panel->mMediaSource->idle();
+
+ // update each media panel
+ updateMediaPanel( panel );
+
+ LLRect dirty_rect;
+ if ( ! panel->mMediaSource->textureValid() )
+ {
+ //std::cout << "texture invalid, skipping update..." << std::endl;
+ }
+ else
+ if ( panel &&
+ ( panel->mMediaWidth != panel->mMediaSource->getWidth() ||
+ panel->mMediaHeight != panel->mMediaSource->getHeight() ) )
+ {
+ //std::cout << "Resize in progress, skipping update..." << std::endl;
+ }
+ else
+ if ( panel->mMediaSource->getDirty( &dirty_rect ) )
+ {
+ const unsigned char* pixels = panel->mMediaSource->getBitsData();
+ if ( pixels && isTexture(panel->mMediaTextureHandle))
+ {
+ int x_offset = dirty_rect.mLeft;
+ int y_offset = dirty_rect.mBottom;
+ int width = dirty_rect.mRight - dirty_rect.mLeft;
+ int height = dirty_rect.mTop - dirty_rect.mBottom;
+
+ if((dirty_rect.mRight <= panel->mTextureWidth) && (dirty_rect.mTop <= panel->mTextureHeight))
+ {
+ // Offset the pixels pointer properly
+ pixels += ( y_offset * panel->mMediaSource->getTextureDepth() * panel->mMediaSource->getBitsWidth() );
+ pixels += ( x_offset * panel->mMediaSource->getTextureDepth() );
+
+ // set up texture
+ bindTexture( panel->mMediaTextureHandle, panel->mMediaSource->getBitsWidth() );
+ if ( mFuzzyMedia )
+ {
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
+ }
+ else
+ {
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
+ };
+
+ checkGLError("glTexParameteri");
+
+ if(panel->mMediaSource->getTextureFormatSwapBytes())
+ {
+ glPixelStorei(GL_UNPACK_SWAP_BYTES, 1);
+ checkGLError("glPixelStorei");
+ }
+
+ // draw portion that changes into texture
+ glTexSubImage2D( GL_TEXTURE_2D, 0,
+ x_offset,
+ y_offset,
+ width,
+ height,
+ panel->mMediaSource->getTextureFormatPrimary(),
+ panel->mMediaSource->getTextureFormatType(),
+ pixels );
+
+ if(checkGLError("glTexSubImage2D"))
+ {
+ std::cerr << " panel ID=" << panel->mId << std::endl;
+ std::cerr << " texture size = " << panel->mTextureWidth << " x " << panel->mTextureHeight << std::endl;
+ std::cerr << " media size = " << panel->mMediaWidth << " x " << panel->mMediaHeight << std::endl;
+ std::cerr << " dirty rect = " << dirty_rect.mLeft << ", " << dirty_rect.mBottom << ", " << dirty_rect.mRight << ", " << dirty_rect.mTop << std::endl;
+ std::cerr << " texture width = " << panel->mMediaSource->getBitsWidth() << std::endl;
+ std::cerr << " format primary = 0x" << std::hex << panel->mMediaSource->getTextureFormatPrimary() << std::dec << std::endl;
+ std::cerr << " format type = 0x" << std::hex << panel->mMediaSource->getTextureFormatType() << std::dec << std::endl;
+ std::cerr << " pixels = " << (void*)pixels << std::endl;
+ }
+
+ if(panel->mMediaSource->getTextureFormatSwapBytes())
+ {
+ glPixelStorei(GL_UNPACK_SWAP_BYTES, 0);
+ checkGLError("glPixelStorei");
+ }
+
+ panel->mMediaSource->resetDirty();
+
+ panel->mReadyToRender = true;
+ }
+ else
+ {
+ std::cerr << "dirty rect is outside current media size, skipping update" << std::endl;
+ }
+ };
+ };
+ };
+
+ // GLUI requires this
+ if ( glutGetWindow() != mAppWindow )
+ glutSetWindow( mAppWindow );
+
+ // trigger re-display
+ glutPostRedisplay();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLFBConnectTest::windowPosToTexturePos( int window_x, int window_y,
+ int& media_x, int& media_y,
+ int& id )
+{
+ if ( ! mSelectedPanel )
+ {
+ media_x = 0;
+ media_y = 0;
+ id = 0;
+ return;
+ };
+
+ // record cursor poisiton for a readback next frame
+ mCurMouseX = window_x;
+ // OpenGL app == coordinate system this way
+ // NOTE: unrelated to settings in plugin - this
+ // is just for this app
+ mCurMouseY = mWindowHeight - window_y;
+
+ // extract x (0..1023, y (0..1023) and id (0..15) from RGB components
+ unsigned long pixel_read_color_bits = ( mPixelReadColor[ 0 ] << 16 ) | ( mPixelReadColor[ 1 ] << 8 ) | mPixelReadColor[ 2 ];
+ int texture_x = pixel_read_color_bits & 0x3ff;
+ int texture_y = ( pixel_read_color_bits >> 10 ) & 0x3ff;
+ id = ( pixel_read_color_bits >> 20 ) & 0x0f;
+
+ // scale to size of media (1024 because we use 10 bits for X and Y from 24)
+ media_x = (int)( ( (float)mSelectedPanel->mMediaWidth * (float)texture_x ) / 1024.0f );
+ media_y = (int)( ( (float)mSelectedPanel->mMediaHeight * (float)texture_y ) / 1024.0f );
+
+ // we assume the plugin uses an inverted coordinate scheme like OpenGL
+ // if not, the plugin code inverts the Y coordinate for us - we don't need to
+ media_y = mSelectedPanel->mMediaHeight - media_y;
+
+ if ( media_x > 0 && media_y > 0 )
+ {
+ //std::cout << " mouse coords: " << mCurMouseX << " x " << mCurMouseY << " and id = " << id << std::endl;
+ //std::cout << "raw texture coords: " << texture_x << " x " << texture_y << " and id = " << id << std::endl;
+ //std::cout << " media coords: " << media_x << " x " << media_y << " and id = " << id << std::endl;
+ //std::cout << std::endl;
+ };
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLFBConnectTest::selectPanelById( int id )
+{
+ for( int panel = 0; panel < (int)mMediaPanels.size(); ++panel )
+ {
+ if ( mMediaPanels[ panel ]->mId == id )
+ {
+ selectPanel(mMediaPanels[ panel ]);
+ return;
+ };
+ };
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLFBConnectTest::selectPanel( mediaPanel* panel )
+{
+ if( mSelectedPanel == panel )
+ return;
+
+ // turn off volume before we delete it
+ if( mSelectedPanel && mSelectedPanel->mMediaSource )
+ {
+ mSelectedPanel->mMediaSource->setVolume( 0.0f );
+ mSelectedPanel->mMediaSource->setPriority( LLPluginClassMedia::PRIORITY_LOW );
+ };
+
+ mSelectedPanel = panel;
+
+ if( mSelectedPanel && mSelectedPanel->mMediaSource )
+ {
+ //mSelectedPanel->mMediaSource->setVolume( (float)mMediaTimeControlVolume / 100.0f );
+ mSelectedPanel->mMediaSource->setPriority( LLPluginClassMedia::PRIORITY_NORMAL );
+
+ if(!mSelectedPanel->mStartUrl.empty())
+ {
+ mUrlEdit->set_text(const_cast<char*>(mSelectedPanel->mStartUrl.c_str()) );
+ }
+ };
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+mediaPanel* LLFBConnectTest::findMediaPanel( LLPluginClassMedia* source )
+{
+ mediaPanel *result = NULL;
+
+ for( int panel = 0; panel < (int)mMediaPanels.size(); ++panel )
+ {
+ if ( mMediaPanels[ panel ]->mMediaSource == source )
+ {
+ result = mMediaPanels[ panel ];
+ }
+ }
+
+ return result;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+mediaPanel* LLFBConnectTest::findMediaPanel( const std::string &target_name )
+{
+ mediaPanel *result = NULL;
+
+ for( int panel = 0; panel < (int)mMediaPanels.size(); ++panel )
+ {
+ if ( mMediaPanels[ panel ]->mTarget == target_name )
+ {
+ result = mMediaPanels[ panel ];
+ }
+ }
+
+ return result;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLFBConnectTest::navigateToNewURI( std::string uri )
+{
+ if ( uri.length() )
+ {
+ std::string mime_type = mimeTypeFromUrl( uri );
+
+ if ( !mSelectedPanel->mMediaSource->isPluginExited() && (mime_type == mSelectedPanel->mMimeType) )
+ {
+ std::cout << "MIME type is the same" << std::endl;
+ mSelectedPanel->mMediaSource->loadURI( uri );
+ mSelectedPanel->mMediaSource->start();
+ mBookmarkList->do_selection( 0 );
+ }
+ else
+ {
+ std::cout << "MIME type changed or plugin had exited" << std::endl;
+ replaceMediaPanel( mSelectedPanel, uri );
+ mBookmarkList->do_selection( 0 );
+ }
+ };
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLFBConnectTest::initUrlHistory( std::string uris )
+{
+ if ( uris.length() > 0 )
+ {
+ std::cout << "init URL : " << uris << std::endl;
+ LLSD historySD;
+
+ char *cstr, *p;
+ cstr = new char[uris.size()+1];
+ strcpy(cstr, uris.c_str());
+ const char *DELIMS = " ,;";
+ p = strtok(cstr, DELIMS);
+ while (p != NULL) {
+ historySD.insert(0, p);
+ p = strtok(NULL, DELIMS);
+ }
+ mSelectedPanel->mMediaSource->initializeUrlHistory(historySD);
+ delete[] cstr;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLFBConnectTest::gluiCallback( int control_id )
+{
+ if ( control_id == mIdBookmarks )
+ {
+ std::string uri = mBookmarks[ mSelBookmark ].second;
+
+ navigateToNewURI( uri );
+ }
+ else
+ if ( control_id == mIdUrlEdit)
+ {
+ std::string uri = mUrlEdit->get_text();
+
+ navigateToNewURI( uri );
+ }
+/*
+ else
+ if ( control_id == mIdUrlInitHistoryEdit )
+ {
+ std::string uri = mUrlInitHistoryEdit->get_text();
+
+ initUrlHistory( uri );
+ }
+ else
+ if ( control_id == mIdControlAddPanel )
+ {
+ addMediaPanel( mBookmarks[ rand() % ( mBookmarks.size() - 1 ) + 1 ].second );
+ }
+ else
+ if ( control_id == mIdControlRemPanel )
+ {
+ remMediaPanel( mSelectedPanel );
+ }
+ else
+ if ( control_id == mIdDisableTimeout )
+ {
+ // Set the "disable timeout" flag for all active plugins.
+ for( int i = 0; i < (int)mMediaPanels.size(); ++i )
+ {
+ mMediaPanels[ i ]->mMediaSource->setDisableTimeout(mDisableTimeout);
+ }
+ }
+ else
+ if ( control_id == mIdUsePluginReadThread )
+ {
+ LLPluginProcessParent::setUseReadThread(mUsePluginReadThread);
+ }
+ else
+ if ( control_id == mIdControlCrashPlugin )
+ {
+ // send message to plugin and ask it to crash
+ // (switch out for ReleaseCandidate version :) )
+ if(mSelectedPanel && mSelectedPanel->mMediaSource)
+ {
+ mSelectedPanel->mMediaSource->crashPlugin();
+ }
+ }
+ else
+ if ( control_id == mIdControlHangPlugin )
+ {
+ // send message to plugin and ask it to hang
+ // (switch out for ReleaseCandidate version :) )
+ if(mSelectedPanel && mSelectedPanel->mMediaSource)
+ {
+ mSelectedPanel->mMediaSource->hangPlugin();
+ }
+ }
+ else
+*/
+ if ( control_id == mIdControlExitApp )
+ {
+ // text for exiting plugin system cleanly
+ delete this; // clean up
+ exit( 0 );
+ }
+/*
+ else
+ if ( control_id == mIdMediaTimeControlPlay )
+ {
+ if ( mSelectedPanel )
+ {
+ mSelectedPanel->mMediaSource->setLoop( false );
+ mSelectedPanel->mMediaSource->start();
+ };
+ }
+ else
+ if ( control_id == mIdMediaTimeControlLoop )
+ {
+ if ( mSelectedPanel )
+ {
+ mSelectedPanel->mMediaSource->setLoop( true );
+ mSelectedPanel->mMediaSource->start();
+ };
+ }
+ else
+ if ( control_id == mIdMediaTimeControlPause )
+ {
+ if ( mSelectedPanel )
+ mSelectedPanel->mMediaSource->pause();
+ }
+ else
+ if ( control_id == mIdMediaTimeControlStop )
+ {
+ if ( mSelectedPanel )
+ {
+ mSelectedPanel->mMediaSource->stop();
+ };
+ }
+ else
+ if ( control_id == mIdMediaTimeControlSeek )
+ {
+ if ( mSelectedPanel )
+ {
+ // get value from spinner
+ float seconds_to_seek = mMediaTimeControlSeekSeconds;
+ mSelectedPanel->mMediaSource->seek( seconds_to_seek );
+ mSelectedPanel->mMediaSource->start();
+ };
+ }
+ else
+ if ( control_id == mIdMediaTimeControlRewind )
+ {
+ if ( mSelectedPanel )
+ {
+ mSelectedPanel->mMediaSource->setLoop( false );
+ mSelectedPanel->mMediaSource->start(-2.0f);
+ };
+ }
+ else
+ if ( control_id == mIdMediaTimeControlFastForward )
+ {
+ if ( mSelectedPanel )
+ {
+ mSelectedPanel->mMediaSource->setLoop( false );
+ mSelectedPanel->mMediaSource->start(2.0f);
+ };
+ }
+ else
+*/
+ if ( control_id == mIdMediaBrowserControlBack )
+ {
+ if ( mSelectedPanel )
+ mSelectedPanel->mMediaSource->browse_back();
+ }
+ else
+ if ( control_id == mIdMediaBrowserControlStop )
+ {
+ if ( mSelectedPanel )
+ mSelectedPanel->mMediaSource->browse_stop();
+ }
+ else
+ if ( control_id == mIdMediaBrowserControlForward )
+ {
+ if ( mSelectedPanel )
+ mSelectedPanel->mMediaSource->browse_forward();
+ }
+ else
+ if ( control_id == mIdMediaBrowserControlHome )
+ {
+ if ( mSelectedPanel )
+ mSelectedPanel->mMediaSource->loadURI( mHomeWebUrl );
+ }
+ else
+ if ( control_id == mIdMediaBrowserControlReload )
+ {
+ if ( mSelectedPanel )
+ mSelectedPanel->mMediaSource->browse_reload( true );
+ }
+/*
+ else
+ if ( control_id == mIdMediaBrowserControlClearCache )
+ {
+ if ( mSelectedPanel )
+ mSelectedPanel->mMediaSource->clear_cache();
+ }
+ else
+ if ( control_id == mIdMediaBrowserControlClearCookies )
+ {
+ if ( mSelectedPanel )
+ mSelectedPanel->mMediaSource->clear_cookies();
+ }
+ else
+ if ( control_id == mIdMediaBrowserControlEnableCookies )
+ {
+ if ( mSelectedPanel )
+ {
+ if ( mMediaBrowserControlEnableCookies )
+ {
+ mSelectedPanel->mMediaSource->enable_cookies( true );
+ }
+ else
+ {
+ mSelectedPanel->mMediaSource->enable_cookies( false );
+ }
+ };
+ };
+*/
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLFBConnectTest::keyboard( int key )
+{
+ //if ( key == 'a' || key == 'A' )
+ // addMediaPanel( mBookmarks[ rand() % ( mBookmarks.size() - 1 ) + 1 ].second );
+ //else
+ //if ( key == 'r' || key == 'R' )
+ // remMediaPanel( mSelectedPanel );
+ //else
+ //if ( key == 'd' || key == 'D' )
+ // dumpPanelInfo();
+ //else
+ if ( key == 27 )
+ {
+ std::cout << "Application finished - exiting..." << std::endl;
+ delete this;
+ exit( 0 );
+ };
+
+ mSelectedPanel->mMediaSource->keyEvent( LLPluginClassMedia::KEY_EVENT_DOWN, key, 0 , LLSD());
+ mSelectedPanel->mMediaSource->keyEvent( LLPluginClassMedia::KEY_EVENT_UP, key, 0, LLSD());
+};
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLFBConnectTest::mouseButton( int button, int state, int x, int y )
+{
+ if ( button == GLUT_LEFT_BUTTON )
+ {
+ if ( state == GLUT_DOWN )
+ {
+ int media_x, media_y, id;
+ windowPosToTexturePos( x, y, media_x, media_y, id );
+
+ if ( mSelectedPanel )
+ mSelectedPanel->mMediaSource->mouseEvent( LLPluginClassMedia::MOUSE_EVENT_DOWN, 0, media_x, media_y, 0 );
+ }
+ else
+ if ( state == GLUT_UP )
+ {
+ int media_x, media_y, id;
+ windowPosToTexturePos( x, y, media_x, media_y, id );
+
+ // only select a panel if we're on a panel
+ // (HACK: strictly speaking this rules out clicking on
+ // the origin of a panel but that's very unlikely)
+ if ( media_x > 0 && media_y > 0 )
+ {
+ selectPanelById( id );
+
+ if ( mSelectedPanel )
+ mSelectedPanel->mMediaSource->mouseEvent( LLPluginClassMedia::MOUSE_EVENT_UP, 0, media_x, media_y, 0 );
+ };
+ };
+ };
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLFBConnectTest::mousePassive( int x, int y )
+{
+ int media_x, media_y, id;
+ windowPosToTexturePos( x, y, media_x, media_y, id );
+
+ if ( mSelectedPanel )
+ mSelectedPanel->mMediaSource->mouseEvent( LLPluginClassMedia::MOUSE_EVENT_MOVE, 0, media_x, media_y, 0 );
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLFBConnectTest::mouseMove( int x, int y )
+{
+ int media_x, media_y, id;
+ windowPosToTexturePos( x, y, media_x, media_y, id );
+
+ if ( mSelectedPanel )
+ mSelectedPanel->mMediaSource->mouseEvent( LLPluginClassMedia::MOUSE_EVENT_MOVE, 0, media_x, media_y, 0 );
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLFBConnectTest::makeChrome()
+{
+ // IDs used by GLUI
+ int start_id = 0x1000;
+
+ // right side window - geometry manipulators
+#if __APPLE__
+ // the Apple GLUT implementation doesn't seem to set the graphic offset of subwindows correctly when they overlap in certain ways.
+ // Use a separate controls window in this case.
+ // GLUI window at right containing manipulation controls and other buttons
+ int x = glutGet(GLUT_WINDOW_X) + glutGet(GLUT_WINDOW_WIDTH) + 4;
+ int y = glutGet(GLUT_WINDOW_Y);
+ GLUI* right_glui_window = GLUI_Master.create_glui( "", 0, x, y );
+#else
+ GLUI* right_glui_window = GLUI_Master.create_glui_subwindow( mAppWindow, GLUI_SUBWINDOW_RIGHT );
+#endif
+ mViewRotationCtrl = right_glui_window->add_rotation( "Rotation", mViewRotation );
+ mViewTranslationCtrl = right_glui_window->add_translation( "Translate", GLUI_TRANSLATION_XY, mViewPos );
+ mViewTranslationCtrl->set_speed( 0.01f );
+ mViewScaleCtrl = right_glui_window->add_translation( "Scale", GLUI_TRANSLATION_Z, &mViewPos[ 2 ] );
+ mViewScaleCtrl->set_speed( 0.05f );
+ right_glui_window->set_main_gfx_window( mAppWindow );
+
+ // right side window - app controls
+ /*
+ mIdControlAddPanel = start_id++;
+ right_glui_window->add_statictext( "" );
+ right_glui_window->add_separator();
+ right_glui_window->add_statictext( "" );
+ right_glui_window->add_button( "Add panel", mIdControlAddPanel, gluiCallbackWrapper );
+ right_glui_window->add_statictext( "" );
+ mIdControlRemPanel = start_id++;
+ right_glui_window->add_button( "Rem panel", mIdControlRemPanel, gluiCallbackWrapper );
+ right_glui_window->add_statictext( "" );
+ right_glui_window->add_separator();
+ right_glui_window->add_statictext( "" );
+ mIdControlCrashPlugin = start_id++;
+ right_glui_window->add_button( "Crash plugin", mIdControlCrashPlugin, gluiCallbackWrapper );
+ mIdControlHangPlugin = start_id++;
+ right_glui_window->add_button( "Hang plugin", mIdControlHangPlugin, gluiCallbackWrapper );
+ */
+ right_glui_window->add_statictext( "" );
+ right_glui_window->add_separator();
+ right_glui_window->add_statictext( "" );
+ mIdControlExitApp = start_id++;
+ right_glui_window->add_button( "Exit app", mIdControlExitApp, gluiCallbackWrapper );
+
+ //// top window - holds bookmark UI
+ mIdBookmarks = start_id++;
+ mSelBookmark = 0;
+ GLUI* glui_window_top = GLUI_Master.create_glui_subwindow( mAppWindow, GLUI_SUBWINDOW_TOP );
+ mBookmarkList = glui_window_top->add_listbox( "", &mSelBookmark, mIdBookmarks, gluiCallbackWrapper );
+ // only add the first 50 bookmarks - list can be very long sometimes (30,000+)
+ // when testing list of media URLs from AGNI for example
+ for( unsigned int each = 0; each < mBookmarks.size() && each < 50; ++each )
+ mBookmarkList->add_item( each, const_cast< char* >( mBookmarks[ each ].first.c_str() ) );
+ glui_window_top->set_main_gfx_window( mAppWindow );
+
+ glui_window_top->add_column( false );
+ mIdUrlEdit = start_id++;
+ mUrlEdit = glui_window_top->add_edittext( "Url:", GLUI_EDITTEXT_TEXT, 0, mIdUrlEdit, gluiCallbackWrapper );
+ mUrlEdit->set_w( 600 );
+ //GLUI* glui_window_top2 = GLUI_Master.create_glui_subwindow( mAppWindow, GLUI_SUBWINDOW_TOP );
+ //mIdUrlInitHistoryEdit = start_id++;
+ //mUrlInitHistoryEdit = glui_window_top2->add_edittext( "Init History (separate by commas or semicolons):",
+ // GLUI_EDITTEXT_TEXT, 0, mIdUrlInitHistoryEdit, gluiCallbackWrapper );
+ //mUrlInitHistoryEdit->set_w( 800 );
+
+ // top window - media controls for "time" media types (e.g. movies)
+/*
+ mGluiMediaTimeControlWindow = GLUI_Master.create_glui_subwindow( mAppWindow, GLUI_SUBWINDOW_TOP );
+ mGluiMediaTimeControlWindow->set_main_gfx_window( mAppWindow );
+ mIdMediaTimeControlPlay = start_id++;
+ mGluiMediaTimeControlWindow->add_button( "PLAY", mIdMediaTimeControlPlay, gluiCallbackWrapper );
+ mGluiMediaTimeControlWindow->add_column( false );
+ mIdMediaTimeControlLoop = start_id++;
+ mGluiMediaTimeControlWindow->add_button( "LOOP", mIdMediaTimeControlLoop, gluiCallbackWrapper );
+ mGluiMediaTimeControlWindow->add_column( false );
+ mIdMediaTimeControlPause = start_id++;
+ mGluiMediaTimeControlWindow->add_button( "PAUSE", mIdMediaTimeControlPause, gluiCallbackWrapper );
+ mGluiMediaTimeControlWindow->add_column( false );
+
+ GLUI_Button *button;
+ mIdMediaTimeControlRewind = start_id++;
+ button = mGluiMediaTimeControlWindow->add_button( "<<", mIdMediaTimeControlRewind, gluiCallbackWrapper );
+ button->set_w(30);
+ mGluiMediaTimeControlWindow->add_column( false );
+ mIdMediaTimeControlFastForward = start_id++;
+ button = mGluiMediaTimeControlWindow->add_button( ">>", mIdMediaTimeControlFastForward, gluiCallbackWrapper );
+ button->set_w(30);
+
+ mGluiMediaTimeControlWindow->add_column( true );
+
+ mIdMediaTimeControlStop = start_id++;
+ mGluiMediaTimeControlWindow->add_button( "STOP", mIdMediaTimeControlStop, gluiCallbackWrapper );
+ mGluiMediaTimeControlWindow->add_column( false );
+ mIdMediaTimeControlVolume = start_id++;
+ GLUI_Spinner* spinner = mGluiMediaTimeControlWindow->add_spinner( "Volume", 2, &mMediaTimeControlVolume, mIdMediaTimeControlVolume, gluiCallbackWrapper);
+ spinner->set_float_limits( 0, 100 );
+ mGluiMediaTimeControlWindow->add_column( true );
+ mIdMediaTimeControlSeekSeconds = start_id++;
+ spinner = mGluiMediaTimeControlWindow->add_spinner( "", 2, &mMediaTimeControlSeekSeconds, mIdMediaTimeControlSeekSeconds, gluiCallbackWrapper);
+ spinner->set_float_limits( 0, 200 );
+ spinner->set_w( 32 );
+ spinner->set_speed( 0.025f );
+ mGluiMediaTimeControlWindow->add_column( false );
+ mIdMediaTimeControlSeek = start_id++;
+ mGluiMediaTimeControlWindow->add_button( "SEEK", mIdMediaTimeControlSeek, gluiCallbackWrapper );
+ mGluiMediaTimeControlWindow->add_column( false );
+*/
+
+ // top window - media controls for "browser" media types (e.g. web browser)
+ mGluiMediaBrowserControlWindow = GLUI_Master.create_glui_subwindow( mAppWindow, GLUI_SUBWINDOW_TOP );
+ mGluiMediaBrowserControlWindow->set_main_gfx_window( mAppWindow );
+ mIdMediaBrowserControlBack = start_id++;
+ mMediaBrowserControlBackButton = mGluiMediaBrowserControlWindow->add_button( "BACK", mIdMediaBrowserControlBack, gluiCallbackWrapper );
+ mGluiMediaBrowserControlWindow->add_column( false );
+ mIdMediaBrowserControlStop = start_id++;
+ mGluiMediaBrowserControlWindow->add_button( "STOP", mIdMediaBrowserControlStop, gluiCallbackWrapper );
+ mGluiMediaBrowserControlWindow->add_column( false );
+ mIdMediaBrowserControlForward = start_id++;
+ mMediaBrowserControlForwardButton = mGluiMediaBrowserControlWindow->add_button( "FORWARD", mIdMediaBrowserControlForward, gluiCallbackWrapper );
+ mGluiMediaBrowserControlWindow->add_column( false );
+ mIdMediaBrowserControlHome = start_id++;
+ mGluiMediaBrowserControlWindow->add_button( "HOME", mIdMediaBrowserControlHome, gluiCallbackWrapper );
+ mGluiMediaBrowserControlWindow->add_column( false );
+ mIdMediaBrowserControlReload = start_id++;
+ mGluiMediaBrowserControlWindow->add_button( "RELOAD", mIdMediaBrowserControlReload, gluiCallbackWrapper );
+ mGluiMediaBrowserControlWindow->add_column( false );
+ /*
+ mIdMediaBrowserControlClearCache = start_id++;
+ mGluiMediaBrowserControlWindow->add_button( "CLEAR CACHE", mIdMediaBrowserControlClearCache, gluiCallbackWrapper );
+ mGluiMediaBrowserControlWindow->add_column( false );
+ mIdMediaBrowserControlClearCookies = start_id++;
+ mGluiMediaBrowserControlWindow->add_button( "CLEAR COOKIES", mIdMediaBrowserControlClearCookies, gluiCallbackWrapper );
+ mGluiMediaBrowserControlWindow->add_column( false );
+ mIdMediaBrowserControlEnableCookies = start_id++;
+ mMediaBrowserControlEnableCookies = 0;
+ mGluiMediaBrowserControlWindow->add_checkbox( "Enable Cookies", &mMediaBrowserControlEnableCookies, mIdMediaBrowserControlEnableCookies, gluiCallbackWrapper );
+
+ // top window - misc controls
+ GLUI* glui_window_misc_control = GLUI_Master.create_glui_subwindow( mAppWindow, GLUI_SUBWINDOW_TOP );
+ mIdRandomPanelCount = start_id++;
+ mRandomPanelCount = 0;
+ glui_window_misc_control->add_checkbox( "Randomize panel count", &mRandomPanelCount, mIdRandomPanelCount, gluiCallbackWrapper );
+ glui_window_misc_control->set_main_gfx_window( mAppWindow );
+ glui_window_misc_control->add_column( true );
+ mIdRandomBookmarks = start_id++;
+ mRandomBookmarks = 0;
+ glui_window_misc_control->add_checkbox( "Randomize bookmarks", &mRandomBookmarks, mIdRandomBookmarks, gluiCallbackWrapper );
+ glui_window_misc_control->set_main_gfx_window( mAppWindow );
+ glui_window_misc_control->add_column( true );
+
+ mIdDisableTimeout = start_id++;
+ mDisableTimeout = 0;
+ glui_window_misc_control->add_checkbox( "Disable plugin timeout", &mDisableTimeout, mIdDisableTimeout, gluiCallbackWrapper );
+ glui_window_misc_control->set_main_gfx_window( mAppWindow );
+ glui_window_misc_control->add_column( true );
+
+ mIdUsePluginReadThread = start_id++;
+ mUsePluginReadThread = 0;
+ glui_window_misc_control->add_checkbox( "Use plugin read thread", &mUsePluginReadThread, mIdUsePluginReadThread, gluiCallbackWrapper );
+ glui_window_misc_control->set_main_gfx_window( mAppWindow );
+ glui_window_misc_control->add_column( true );
+
+ mIdLargePanelSpacing = start_id++;
+ mLargePanelSpacing = 0;
+ glui_window_misc_control->add_checkbox( "Large Panel Spacing", &mLargePanelSpacing, mIdLargePanelSpacing, gluiCallbackWrapper );
+ glui_window_misc_control->set_main_gfx_window( mAppWindow );
+ glui_window_misc_control->add_column( true );
+*/
+ // bottom window - status
+ mBottomGLUIWindow = GLUI_Master.create_glui_subwindow( mAppWindow, GLUI_SUBWINDOW_BOTTOM );
+ mStatusText = mBottomGLUIWindow->add_statictext( "" );
+ mBottomGLUIWindow->set_main_gfx_window( mAppWindow );
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLFBConnectTest::resetView()
+{
+ mViewRotationCtrl->reset();
+
+ mViewScaleCtrl->set_x( 0.0f );
+ mViewScaleCtrl->set_y( 0.0f );
+ mViewScaleCtrl->set_z( 1.3f );
+
+ mViewTranslationCtrl->set_x( 0.0f );
+ mViewTranslationCtrl->set_y( 0.0f );
+ mViewTranslationCtrl->set_z( 0.0f );
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLFBConnectTest::makePickTexture( int id, GLuint* texture_handle, unsigned char** texture_pixels )
+{
+ int pick_texture_width = 1024;
+ int pick_texture_height = 1024;
+ int pick_texture_depth = 3;
+ unsigned char* ptr = new unsigned char[ pick_texture_width * pick_texture_height * pick_texture_depth ];
+ for( int y = 0; y < pick_texture_height; ++y )
+ {
+ for( int x = 0; x < pick_texture_width * pick_texture_depth ; x += pick_texture_depth )
+ {
+ unsigned long bits = 0L;
+ bits |= ( id << 20 ) | ( y << 10 ) | ( x / 3 );
+ unsigned char r_component = ( bits >> 16 ) & 0xff;
+ unsigned char g_component = ( bits >> 8 ) & 0xff;
+ unsigned char b_component = bits & 0xff;
+
+ ptr[ y * pick_texture_width * pick_texture_depth + x + 0 ] = r_component;
+ ptr[ y * pick_texture_width * pick_texture_depth + x + 1 ] = g_component;
+ ptr[ y * pick_texture_width * pick_texture_depth + x + 2 ] = b_component;
+ };
+ };
+
+ glGenTextures( 1, texture_handle );
+
+ checkGLError("glGenTextures");
+ std::cout << "glGenTextures returned " << *texture_handle << std::endl;
+
+ bindTexture( *texture_handle );
+ glTexImage2D( GL_TEXTURE_2D, 0,
+ GL_RGB,
+ pick_texture_width, pick_texture_height,
+ 0, GL_RGB, GL_UNSIGNED_BYTE, ptr );
+
+ *texture_pixels = ptr;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+std::string LLFBConnectTest::mimeTypeFromUrl( std::string& url )
+{
+ // default to web
+ std::string mime_type = "text/html";
+
+ // we may need a more advanced MIME type accessor later :-)
+ if ( url.find( ".mov" ) != std::string::npos ) // Movies
+ mime_type = "video/quicktime";
+ else
+ if ( url.find( ".txt" ) != std::string::npos ) // Apple Text descriptors
+ mime_type = "video/quicktime";
+ else
+ if ( url.find( ".mp3" ) != std::string::npos ) // Apple Text descriptors
+ mime_type = "video/quicktime";
+ else
+ if ( url.find( "example://" ) != std::string::npos ) // Example plugin
+ mime_type = "example/example";
+
+ return mime_type;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+std::string LLFBConnectTest::pluginNameFromMimeType( std::string& mime_type )
+{
+#if LL_DARWIN
+ std::string plugin_name( "media_plugin_null.dylib" );
+ if ( mime_type == "video/quicktime" )
+ plugin_name = "media_plugin_quicktime.dylib";
+ else
+ if ( mime_type == "text/html" )
+ plugin_name = "media_plugin_webkit.dylib";
+
+#elif LL_WINDOWS
+ std::string plugin_name( "media_plugin_null.dll" );
+
+ if ( mime_type == "video/quicktime" )
+ plugin_name = "media_plugin_quicktime.dll";
+ else
+ if ( mime_type == "text/html" )
+ plugin_name = "media_plugin_webkit.dll";
+ else
+ if ( mime_type == "example/example" )
+ plugin_name = "media_plugin_example.dll";
+
+#elif LL_LINUX
+ std::string plugin_name( "libmedia_plugin_null.so" );
+
+ if ( mime_type == "video/quicktime" )
+ plugin_name = "libmedia_plugin_quicktime.so";
+ else
+ if ( mime_type == "text/html" )
+ plugin_name = "libmedia_plugin_webkit.so";
+#endif
+ return plugin_name;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+mediaPanel* LLFBConnectTest::addMediaPanel( std::string url )
+{
+ // Get the plugin filename using the URL
+ std::string mime_type = mimeTypeFromUrl( url );
+ std::string plugin_name = pluginNameFromMimeType( mime_type );
+
+ // create a random size for the new media
+ int media_width;
+ int media_height;
+ getRandomMediaSize( media_width, media_height, mime_type );
+ media_width = 1024;
+ media_height = 1536;
+
+ // make a new plugin
+ LLPluginClassMedia* media_source = new LLPluginClassMedia(this);
+
+ // enable cookies so the FB login works
+ media_source->enable_cookies(true);
+
+ // tell the plugin what size we asked for
+ media_source->setSize( media_width, media_height );
+
+ // Use the launcher start and initialize the plugin
+#if LL_DARWIN || LL_LINUX
+ std::string launcher_name( "SLPlugin" );
+#elif LL_WINDOWS
+ std::string launcher_name( "SLPlugin.exe" );
+#endif
+
+ // for this test app, use the cwd as the user data path (ugh).
+#if LL_WINDOWS
+ std::string user_data_path = ".\\";
+#else
+ char cwd[ FILENAME_MAX ];
+ if (NULL == getcwd( cwd, FILENAME_MAX - 1 ))
+ {
+ std::cerr << "Couldn't get cwd - probably too long - failing to init." << std::endl;
+ return NULL;
+ }
+ std::string user_data_path = std::string( cwd ) + "/";
+#endif
+ media_source->setUserDataPath(user_data_path);
+ media_source->init( launcher_name, user_data_path, plugin_name, false );
+ //media_source->setDisableTimeout(mDisableTimeout);
+
+ // make a new panel and save parameters
+ mediaPanel* panel = new mediaPanel;
+ panel->mMediaSource = media_source;
+ panel->mStartUrl = url;
+ panel->mMimeType = mime_type;
+ panel->mMediaWidth = media_width;
+ panel->mMediaHeight = media_height;
+ panel->mTextureWidth = 0;
+ panel->mTextureHeight = 0;
+ panel->mTextureScaleX = 0;
+ panel->mTextureScaleY = 0;
+ panel->mMediaTextureHandle = 0;
+ panel->mPickTextureHandle = 0;
+ panel->mAppTextureCoordsOpenGL = false; // really need an 'undefined' state here too
+ panel->mReadyToRender = false;
+
+ // look through current media panels to find an unused index number
+ bool id_exists = true;
+ for( int nid = 0; nid < mMaxPanels; ++nid )
+ {
+ // does this id exist already?
+ id_exists = false;
+ for( int pid = 0; pid < (int)mMediaPanels.size(); ++pid )
+ {
+ if ( nid == mMediaPanels[ pid ]->mId )
+ {
+ id_exists = true;
+ break;
+ };
+ };
+
+ // id wasn't found so we can use it
+ if ( ! id_exists )
+ {
+ panel->mId = nid;
+ break;
+ };
+ };
+
+ // if we get here and this flag is set, there is no room for any more panels
+ if ( id_exists )
+ {
+ std::cout << "No room for any more panels" << std::endl;
+ }
+ else
+ {
+ // now we have the ID we can use it to make the
+ // pick texture (id is baked into texture pixels)
+ makePickTexture( panel->mId, &panel->mPickTextureHandle, &panel->mPickTexturePixels );
+
+ // save this in the list of panels
+ mMediaPanels.push_back( panel );
+
+ // select the panel that was just created
+ selectPanel( panel );
+
+ // load and start the URL
+ panel->mMediaSource->loadURI( url );
+ panel->mMediaSource->start();
+
+ std::cout << "Adding new media panel for " << url << "(" << media_width << "x" << media_height << ") with index " << panel->mId << " - total panels = " << mMediaPanels.size() << std::endl;
+ }
+
+ return panel;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLFBConnectTest::updateMediaPanel( mediaPanel* panel )
+{
+// checkGLError("LLFBConnectTest::updateMediaPanel");
+
+ if ( ! panel )
+ return;
+
+ if(!panel->mMediaSource || !panel->mMediaSource->textureValid())
+ {
+ panel->mReadyToRender = false;
+ return;
+ }
+
+ // take a reference copy of the plugin values since they
+ // might change during this lifetime of this function
+ int plugin_media_width = panel->mMediaSource->getWidth();
+ int plugin_media_height = panel->mMediaSource->getHeight();
+ int plugin_texture_width = panel->mMediaSource->getBitsWidth();
+ int plugin_texture_height = panel->mMediaSource->getBitsHeight();
+
+ // If the texture isn't created or the media or texture dimensions changed AND
+ // the sizes are valid then we need to delete the old media texture (if necessary)
+ // then make a new one.
+ if ((panel->mMediaTextureHandle == 0 ||
+ panel->mMediaWidth != plugin_media_width ||
+ panel->mMediaHeight != plugin_media_height ||
+ panel->mTextureWidth != plugin_texture_width ||
+ panel->mTextureHeight != plugin_texture_height) &&
+ ( plugin_media_width > 0 && plugin_media_height > 0 &&
+ plugin_texture_width > 0 && plugin_texture_height > 0 ) )
+ {
+ std::cout << "Valid media size (" << plugin_media_width << " x " << plugin_media_height
+ << ") and texture size (" << plugin_texture_width << " x " << plugin_texture_height
+ << ") for panel with ID=" << panel->mId << " - making texture" << std::endl;
+
+ // delete old GL texture
+ if ( isTexture( panel->mMediaTextureHandle ) )
+ {
+ std::cerr << "updateMediaPanel: deleting texture " << panel->mMediaTextureHandle << std::endl;
+ glDeleteTextures( 1, &panel->mMediaTextureHandle );
+ panel->mMediaTextureHandle = 0;
+ }
+
+ std::cerr << "before: pick texture is " << panel->mPickTextureHandle << ", media texture is " << panel->mMediaTextureHandle << std::endl;
+
+ // make a GL texture based on the dimensions the plugin told us
+ GLuint new_texture = 0;
+ glGenTextures( 1, &new_texture );
+
+ checkGLError("glGenTextures");
+
+ std::cout << "glGenTextures returned " << new_texture << std::endl;
+
+ panel->mMediaTextureHandle = new_texture;
+
+ bindTexture( panel->mMediaTextureHandle );
+
+ std::cout << "Setting texture size to " << plugin_texture_width << " x " << plugin_texture_height << std::endl;
+ glTexImage2D( GL_TEXTURE_2D, 0,
+ GL_RGB,
+ plugin_texture_width, plugin_texture_height,
+ 0, GL_RGB, GL_UNSIGNED_BYTE,
+ 0 );
+
+
+ std::cerr << "after: pick texture is " << panel->mPickTextureHandle << ", media texture is " << panel->mMediaTextureHandle << std::endl;
+ };
+
+ // update our record of the media and texture dimensions
+ // NOTE: do this after we we check for sizes changes
+ panel->mMediaWidth = plugin_media_width;
+ panel->mMediaHeight = plugin_media_height;
+ panel->mTextureWidth = plugin_texture_width;
+ panel->mTextureHeight = plugin_texture_height;
+ if ( plugin_texture_width > 0 )
+ {
+ panel->mTextureScaleX = (double)panel->mMediaWidth / (double)panel->mTextureWidth;
+ };
+ if ( plugin_texture_height > 0 )
+ {
+ panel->mTextureScaleY = (double)panel->mMediaHeight / (double)panel->mTextureHeight;
+ };
+
+ // update the flag which tells us if the media source uses OprnGL coords or not.
+ panel->mAppTextureCoordsOpenGL = panel->mMediaSource->getTextureCoordsOpenGL();
+
+ // Check to see if we have enough to render this panel.
+ // If we do, set a flag that the display functions use so
+ // they only render a panel with media if it's ready.
+ if ( panel->mMediaWidth < 0 ||
+ panel->mMediaHeight < 0 ||
+ panel->mTextureWidth < 1 ||
+ panel->mTextureHeight < 1 ||
+ panel->mMediaTextureHandle == 0 )
+ {
+ panel->mReadyToRender = false;
+ };
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+mediaPanel* LLFBConnectTest::replaceMediaPanel( mediaPanel* panel, std::string url )
+{
+ // no media panels so we can't change anything - have to add
+ if ( mMediaPanels.size() == 0 )
+ return NULL;
+
+ // sanity check
+ if ( ! panel )
+ return NULL;
+
+ int index;
+ for(index = 0; index < (int)mMediaPanels.size(); index++)
+ {
+ if(mMediaPanels[index] == panel)
+ break;
+ }
+
+ if(index >= (int)mMediaPanels.size())
+ {
+ // panel isn't in mMediaPanels
+ return NULL;
+ }
+
+ std::cout << "Replacing media panel with index " << panel->mId << std::endl;
+
+ int panel_id = panel->mId;
+
+ if(mSelectedPanel == panel)
+ mSelectedPanel = NULL;
+
+ delete panel;
+
+ // Get the plugin filename using the URL
+ std::string mime_type = mimeTypeFromUrl( url );
+ std::string plugin_name = pluginNameFromMimeType( mime_type );
+
+ // create a random size for the new media
+ int media_width;
+ int media_height;
+ getRandomMediaSize( media_width, media_height, mime_type );
+
+ // make a new plugin
+ LLPluginClassMedia* media_source = new LLPluginClassMedia(this);
+
+ // tell the plugin what size we asked for
+ media_source->setSize( media_width, media_height );
+
+ // Use the launcher start and initialize the plugin
+#if LL_DARWIN || LL_LINUX
+ std::string launcher_name( "SLPlugin" );
+#elif LL_WINDOWS
+ std::string launcher_name( "SLPlugin.exe" );
+#endif
+
+ // for this test app, use the cwd as the user data path (ugh).
+#if LL_WINDOWS
+ std::string user_data_path = ".\\";
+#else
+ char cwd[ FILENAME_MAX ];
+ if (NULL == getcwd( cwd, FILENAME_MAX - 1 ))
+ {
+ std::cerr << "Couldn't get cwd - probably too long - failing to init." << std::endl;
+ return NULL;
+ }
+ std::string user_data_path = std::string( cwd ) + "/";
+#endif
+
+ media_source->setUserDataPath(user_data_path);
+ media_source->init( launcher_name, user_data_path, plugin_name, false );
+ //media_source->setDisableTimeout(mDisableTimeout);
+
+ // make a new panel and save parameters
+ panel = new mediaPanel;
+ panel->mMediaSource = media_source;
+ panel->mStartUrl = url;
+ panel->mMimeType = mime_type;
+ panel->mMediaWidth = media_width;
+ panel->mMediaHeight = media_height;
+ panel->mTextureWidth = 0;
+ panel->mTextureHeight = 0;
+ panel->mTextureScaleX = 0;
+ panel->mTextureScaleY = 0;
+ panel->mMediaTextureHandle = 0;
+ panel->mPickTextureHandle = 0;
+ panel->mAppTextureCoordsOpenGL = false; // really need an 'undefined' state here too
+ panel->mReadyToRender = false;
+
+ panel->mId = panel_id;
+
+ // Replace the entry in the panels array
+ mMediaPanels[index] = panel;
+
+ // now we have the ID we can use it to make the
+ // pick texture (id is baked into texture pixels)
+ makePickTexture( panel->mId, &panel->mPickTextureHandle, &panel->mPickTexturePixels );
+
+ // select the panel that was just created
+ selectPanel( panel );
+
+ // load and start the URL
+ panel->mMediaSource->loadURI( url );
+ panel->mMediaSource->start();
+
+ return panel;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLFBConnectTest::getRandomMediaSize( int& width, int& height, std::string mime_type )
+{
+ // Make a new media source with a random size which we'll either
+ // directly or the media plugin will tell us what it wants later.
+ // Use a random size so we can test support for weird media sizes.
+ // (Almost everything else will get filled in later once the
+ // plugin responds)
+ // NB. Do we need to enforce that width is on 4 pixel boundary?
+ width = ( ( rand() % 170 ) + 30 ) * 4;
+ height = ( ( rand() % 170 ) + 30 ) * 4;
+
+ // adjust this random size if it's a browser so we get
+ // a more useful size for testing..
+ if ( mime_type == "text/html" || mime_type == "example/example" )
+ {
+ width = ( ( rand() % 100 ) + 100 ) * 4;
+ height = ( width * ( ( rand() % 400 ) + 1000 ) ) / 1000;
+ };
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLFBConnectTest::remMediaPanel( mediaPanel* panel )
+{
+ // always leave one panel
+ if ( mMediaPanels.size() == 1 )
+ return;
+
+ // sanity check - don't think this can happen but see above for a case where it might...
+ if ( ! panel )
+ return;
+
+ std::cout << "Removing media panel with index " << panel->mId << " - total panels = " << mMediaPanels.size() - 1 << std::endl;
+
+ if(mSelectedPanel == panel)
+ mSelectedPanel = NULL;
+
+ delete panel;
+
+ // remove from storage list
+ for( int i = 0; i < (int)mMediaPanels.size(); ++i )
+ {
+ if ( mMediaPanels[ i ] == panel )
+ {
+ mMediaPanels.erase( mMediaPanels.begin() + i );
+ break;
+ };
+ };
+
+ // select the first panel
+ selectPanel( mMediaPanels[ 0 ] );
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLFBConnectTest::updateStatusBar()
+{
+ if ( ! mSelectedPanel )
+ return;
+
+ // cache results - this is a very slow function
+ static int cached_id = -1;
+ static int cached_media_width = -1;
+ static int cached_media_height = -1;
+ static int cached_texture_width = -1;
+ static int cached_texture_height = -1;
+ static bool cached_supports_browser_media = true;
+ static bool cached_supports_time_media = false;
+ static int cached_movie_time = -1;
+ static GLfloat cached_distance = -1.0f;
+
+ static std::string cached_plugin_version = "";
+ if (
+ cached_id == mSelectedPanel->mId &&
+ cached_media_width == mSelectedPanel->mMediaWidth &&
+ cached_media_height == mSelectedPanel->mMediaHeight &&
+ cached_texture_width == mSelectedPanel->mTextureWidth &&
+ cached_texture_height == mSelectedPanel->mTextureHeight &&
+ cached_supports_browser_media == mSelectedPanel->mMediaSource->pluginSupportsMediaBrowser() &&
+ cached_supports_time_media == mSelectedPanel->mMediaSource->pluginSupportsMediaTime() &&
+ cached_plugin_version == mSelectedPanel->mMediaSource->getPluginVersion() &&
+ cached_movie_time == (int)mSelectedPanel->mMediaSource->getCurrentTime() &&
+ cached_distance == mDistanceCameraToSelectedGeometry
+ )
+ {
+ // nothing changed so don't spend time here
+ return;
+ };
+
+ std::ostringstream stream( "" );
+
+ stream.str( "" );
+ stream.clear();
+
+ stream << "Id: ";
+ stream << std::setw( 2 ) << std::setfill( '0' );
+ stream << mSelectedPanel->mId;
+ stream << " | ";
+ stream << "Media: ";
+ stream << std::setw( 3 ) << std::setfill( '0' );
+ stream << mSelectedPanel->mMediaWidth;
+ stream << " x ";
+ stream << std::setw( 3 ) << std::setfill( '0' );
+ stream << mSelectedPanel->mMediaHeight;
+ stream << " | ";
+ stream << "Texture: ";
+ stream << std::setw( 4 ) << std::setfill( '0' );
+ stream << mSelectedPanel->mTextureWidth;
+ stream << " x ";
+ stream << std::setw( 4 ) << std::setfill( '0' );
+ stream << mSelectedPanel->mTextureHeight;
+
+ stream << " | ";
+ stream << "Distance: ";
+ stream << std::setw( 6 );
+ stream << std::setprecision( 3 );
+ stream << std::setprecision( 3 );
+ stream << mDistanceCameraToSelectedGeometry;
+ stream << " | ";
+
+ if ( mSelectedPanel->mMediaSource->pluginSupportsMediaBrowser() )
+ stream << "BROWSER";
+ else
+ if ( mSelectedPanel->mMediaSource->pluginSupportsMediaTime() )
+ stream << "TIME ";
+ stream << " | ";
+ stream << mSelectedPanel->mMediaSource->getPluginVersion();
+ stream << " | ";
+ if ( mSelectedPanel->mMediaSource->pluginSupportsMediaTime() )
+ {
+ stream << std::setw( 3 ) << std::setfill( '0' );
+ stream << (int)mSelectedPanel->mMediaSource->getCurrentTime();
+ stream << " / ";
+ stream << std::setw( 3 ) << std::setfill( '0' );
+ stream << (int)mSelectedPanel->mMediaSource->getDuration();
+ stream << " @ ";
+ stream << (int)mSelectedPanel->mMediaSource->getCurrentPlayRate();
+ stream << " | ";
+ };
+
+ glutSetWindow( mBottomGLUIWindow->get_glut_window_id() );
+ mStatusText->set_text( const_cast< char*>( stream.str().c_str() ) );
+ glutSetWindow( mAppWindow );
+
+ // caching
+ cached_id = mSelectedPanel->mId;
+ cached_media_width = mSelectedPanel->mMediaWidth;
+ cached_media_height = mSelectedPanel->mMediaHeight;
+ cached_texture_width = mSelectedPanel->mTextureWidth;
+ cached_texture_height = mSelectedPanel->mTextureHeight;
+ cached_supports_browser_media = mSelectedPanel->mMediaSource->pluginSupportsMediaBrowser();
+ cached_supports_time_media = mSelectedPanel->mMediaSource->pluginSupportsMediaTime();
+ cached_plugin_version = mSelectedPanel->mMediaSource->getPluginVersion();
+ cached_movie_time = (int)mSelectedPanel->mMediaSource->getCurrentTime();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLFBConnectTest::dumpPanelInfo()
+{
+ std::cout << std::endl << "===== Media Panels =====" << std::endl;
+ for( int i = 0; i < (int)mMediaPanels.size(); ++i )
+ {
+ std::cout << std::setw( 2 ) << std::setfill( '0' );
+ std::cout << i + 1 << "> ";
+ std::cout << "Id: ";
+ std::cout << std::setw( 2 ) << std::setfill( '0' );
+ std::cout << mMediaPanels[ i ]->mId;
+ std::cout << " | ";
+ std::cout << "Media: ";
+ std::cout << std::setw( 3 ) << std::setfill( '0' );
+ std::cout << mMediaPanels[ i ]->mMediaWidth;
+ std::cout << " x ";
+ std::cout << std::setw( 3 ) << std::setfill( '0' );
+ std::cout << mMediaPanels[ i ]->mMediaHeight;
+ std::cout << " | ";
+ std::cout << "Texture: ";
+ std::cout << std::setw( 4 ) << std::setfill( '0' );
+ std::cout << mMediaPanels[ i ]->mTextureWidth;
+ std::cout << " x ";
+ std::cout << std::setw( 4 ) << std::setfill( '0' );
+ std::cout << mMediaPanels[ i ]->mTextureHeight;
+ std::cout << " | ";
+ if ( mMediaPanels[ i ] == mSelectedPanel )
+ std::cout << "(selected)";
+
+ std::cout << std::endl;
+ };
+ std::cout << "========================" << std::endl;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLFBConnectTest::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event)
+{
+ // Uncomment this to make things much, much quieter.
+// return;
+
+ switch(event)
+ {
+ case MEDIA_EVENT_CONTENT_UPDATED:
+ // too spammy -- don't log these
+// std::cerr << "Media event: MEDIA_EVENT_CONTENT_UPDATED " << std::endl;
+ break;
+
+ case MEDIA_EVENT_TIME_DURATION_UPDATED:
+ // too spammy -- don't log these
+// std::cerr << "Media event: MEDIA_EVENT_TIME_DURATION_UPDATED, time is " << self->getCurrentTime() << " of " << self->getDuration() << std::endl;
+ break;
+
+ case MEDIA_EVENT_SIZE_CHANGED:
+ std::cerr << "Media event: MEDIA_EVENT_SIZE_CHANGED " << std::endl;
+ break;
+
+ case MEDIA_EVENT_CURSOR_CHANGED:
+ std::cerr << "Media event: MEDIA_EVENT_CURSOR_CHANGED, new cursor is " << self->getCursorName() << std::endl;
+ break;
+
+ case MEDIA_EVENT_NAVIGATE_BEGIN:
+ std::cerr << "Media event: MEDIA_EVENT_NAVIGATE_BEGIN " << std::endl;
+ break;
+
+ case MEDIA_EVENT_NAVIGATE_COMPLETE:
+ std::cerr << "Media event: MEDIA_EVENT_NAVIGATE_COMPLETE, result string is: " << self->getNavigateResultString() << std::endl;
+ break;
+
+ case MEDIA_EVENT_PROGRESS_UPDATED:
+ std::cerr << "Media event: MEDIA_EVENT_PROGRESS_UPDATED, loading at " << self->getProgressPercent() << "%" << std::endl;
+ break;
+
+ case MEDIA_EVENT_STATUS_TEXT_CHANGED:
+ std::cerr << "Media event: MEDIA_EVENT_STATUS_TEXT_CHANGED, new status text is: " << self->getStatusText() << std::endl;
+ break;
+
+ case MEDIA_EVENT_NAME_CHANGED:
+ std::cerr << "Media event: MEDIA_EVENT_NAME_CHANGED, new name is: " << self->getMediaName() << std::endl;
+ glutSetWindowTitle( self->getMediaName().c_str() );
+ break;
+
+ case MEDIA_EVENT_LOCATION_CHANGED:
+ {
+ std::cerr << "Media event: MEDIA_EVENT_LOCATION_CHANGED, new uri is: " << self->getLocation() << std::endl;
+ mediaPanel* panel = findMediaPanel(self);
+ if(panel != NULL)
+ {
+ panel->mStartUrl = self->getLocation();
+ if(panel == mSelectedPanel)
+ {
+ mUrlEdit->set_text(const_cast<char*>(panel->mStartUrl.c_str()) );
+ }
+ }
+ }
+ break;
+
+ case MEDIA_EVENT_NAVIGATE_ERROR_PAGE:
+ std::cerr << "Media event: MEDIA_EVENT_NAVIGATE_ERROR_PAGE, uri is: " << self->getClickURL() << std::endl;
+ break;
+
+ case MEDIA_EVENT_CLICK_LINK_HREF:
+ {
+ std::cerr << "Media event: MEDIA_EVENT_CLICK_LINK_HREF, uri is " << self->getClickURL() << ", target is " << self->getClickTarget() << std::endl;
+ // retrieve the event parameters
+ std::string url = self->getClickURL();
+ std::string target = self->getClickTarget();
+
+ if(target == "_external")
+ {
+ // this should open in an external browser, but since this is a test app we don't care.
+ }
+ else if(target == "_blank")
+ {
+ // Create a new panel with the specified URL.
+ addMediaPanel(url);
+ }
+ else // other named target
+ {
+ mediaPanel *target_panel = findMediaPanel(target);
+ if(target_panel)
+ {
+ target_panel = replaceMediaPanel(target_panel, url);
+ }
+ else
+ {
+ target_panel = addMediaPanel(url);
+ }
+
+ if(target_panel)
+ {
+ target_panel->mTarget = target;
+ }
+ }
+ }
+ break;
+
+ case MEDIA_EVENT_CLICK_LINK_NOFOLLOW:
+ std::cerr << "Media event: MEDIA_EVENT_CLICK_LINK_NOFOLLOW, uri is " << self->getClickURL() << std::endl;
+ break;
+
+ case MEDIA_EVENT_PLUGIN_FAILED:
+ std::cerr << "Media event: MEDIA_EVENT_PLUGIN_FAILED" << std::endl;
+ break;
+
+ case MEDIA_EVENT_PLUGIN_FAILED_LAUNCH:
+ std::cerr << "Media event: MEDIA_EVENT_PLUGIN_FAILED_LAUNCH" << std::endl;
+ break;
+
+ case MEDIA_EVENT_CLOSE_REQUEST:
+ std::cerr << "Media event: MEDIA_EVENT_CLOSE_REQUEST" << std::endl;
+ break;
+
+ case MEDIA_EVENT_PICK_FILE_REQUEST:
+ std::cerr << "Media event: MEDIA_EVENT_PICK_FILE_REQUEST" << std::endl;
+ // TODO: display an actual file picker
+ self->sendPickFileResponse("cake");
+ break;
+
+ case MEDIA_EVENT_GEOMETRY_CHANGE:
+ std::cerr << "Media event: MEDIA_EVENT_GEOMETRY_CHANGE, uuid is " << self->getClickUUID()
+ << ", x = " << self->getGeometryX()
+ << ", y = " << self->getGeometryY()
+ << ", width = " << self->getGeometryWidth()
+ << ", height = " << self->getGeometryHeight()
+ << std::endl;
+ break;
+
+ case MEDIA_EVENT_AUTH_REQUEST:
+ {
+ //std::cerr << "Media event: MEDIA_EVENT_AUTH_REQUEST, url " << self->getAuthURL() ", realm " << self->getAuthRealm() << std::endl;
+
+ // TODO: display an auth dialog
+ self->sendAuthResponse(false, "", "");
+ }
+ break;
+
+ case MEDIA_EVENT_LINK_HOVERED:
+ {
+ std::cerr << "Media event: MEDIA_EVENT_LINK_HOVERED, hover text is: " << self->getHoverText() << std::endl;
+ }
+ break;
+
+ default:
+ {
+ std::cerr << "Media event: <unknown>, code is: " << int(event) << std::endl;
+ }
+ break;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+static void gluiCallbackWrapper( int control_id )
+{
+ if ( gApplication )
+ gApplication->gluiCallback( control_id );
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void glutReshape( int width, int height )
+{
+ if ( gApplication )
+ gApplication->reshape( width, height );
+};
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void glutDisplay()
+{
+ if ( gApplication )
+ gApplication->display();
+};
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void glutIdle(int update_ms)
+{
+ GLUI_Master.set_glutTimerFunc( update_ms, glutIdle, update_ms);
+
+ if ( gApplication )
+ gApplication->idle();
+
+};
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void glutKeyboard( unsigned char key, int x, int y )
+{
+ if ( gApplication )
+ gApplication->keyboard( key );
+};
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void glutMousePassive( int x, int y )
+{
+ if ( gApplication )
+ gApplication->mousePassive( x, y );
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void glutMouseMove( int x , int y )
+{
+ if ( gApplication )
+ gApplication->mouseMove( x, y );
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void glutMouseButton( int button, int state, int x, int y )
+{
+ if ( gApplication )
+ gApplication->mouseButton( button, state, x, y );
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+int main( int argc, char* argv[] )
+{
+#if LL_DARWIN
+ // Set the current working directory to <application bundle>/Contents/Resources/
+ CFURLRef resources_url = CFBundleCopyResourcesDirectoryURL(CFBundleGetMainBundle());
+ if(resources_url != NULL)
+ {
+ CFStringRef resources_string = CFURLCopyFileSystemPath(resources_url, kCFURLPOSIXPathStyle);
+ CFRelease(resources_url);
+ if(resources_string != NULL)
+ {
+ char buffer[PATH_MAX] = "";
+ if(CFStringGetCString(resources_string, buffer, sizeof(buffer), kCFStringEncodingUTF8))
+ {
+ chdir(buffer);
+ }
+ CFRelease(resources_string);
+ }
+ }
+#endif
+
+ glutInit( &argc, argv );
+ glutInitDisplayMode( GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGB );
+
+ const int app_window_x = 80;
+ const int app_window_y = 0;
+ const int app_window_width = 960;
+ const int app_window_height = 960;
+
+ glutInitWindowPosition( app_window_x, app_window_y );
+ glutInitWindowSize( app_window_width, app_window_height );
+
+ int app_window_handle = glutCreateWindow( "LLFBConnectTest" );
+
+ glutDisplayFunc( glutDisplay );
+
+ GLUI_Master.set_glutReshapeFunc( glutReshape );
+ GLUI_Master.set_glutKeyboardFunc( glutKeyboard );
+ GLUI_Master.set_glutMouseFunc( glutMouseButton );
+
+ glutPassiveMotionFunc( glutMousePassive );
+ glutMotionFunc( glutMouseMove );
+
+ glutSetWindow( app_window_handle );
+
+ gApplication = new LLFBConnectTest( app_window_handle, app_window_width, app_window_height );
+
+ // update at approximately 60hz
+ int update_ms = 1000 / 60;
+
+ GLUI_Master.set_glutTimerFunc( update_ms, glutIdle, update_ms);
+
+ glutMainLoop();
+
+ delete gApplication;
+}
diff --git a/indra/test_apps/llfbconnecttest/llfbconnecttest.h b/indra/test_apps/llfbconnecttest/llfbconnecttest.h
new file mode 100644
index 0000000000..6f442a55b3
--- /dev/null
+++ b/indra/test_apps/llfbconnecttest/llfbconnecttest.h
@@ -0,0 +1,207 @@
+/**
+ * @file LLFBConnectTest.cpp
+ * @brief Facebook Connect Test App
+ *
+ * $LicenseInfo:firstyear=2008&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$
+ */
+
+#ifndef LL_FB_CONNECT_H
+#define LL_FB_CONNECT_H
+
+#include <vector>
+#include <string>
+#include "llpluginclassmedia.h"
+#include "llgl.h"
+
+// Forward declarations
+class GLUI_Rotation;
+class GLUI_Translation;
+class GLUI_Listbox;
+class GLUI_EditText;
+class GLUI_StaticText;
+class GLUI;
+class GLUI_Button;
+
+////////////////////////////////////////////////////////////////////////////////
+//
+struct mediaPanel
+{
+ public:
+ mediaPanel();
+ ~mediaPanel();
+ int mId;
+ std::string mStartUrl;
+ std::string mMimeType;
+ std::string mTarget;
+ LLPluginClassMedia *mMediaSource;
+ int mMediaWidth;
+ int mMediaHeight;
+ int mTextureWidth;
+ int mTextureHeight;
+ double mTextureScaleX;
+ double mTextureScaleY;
+ GLuint mMediaTextureHandle;
+ GLuint mPickTextureHandle;
+ unsigned char* mPickTexturePixels;
+ bool mAppTextureCoordsOpenGL;
+ bool mReadyToRender;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+//
+class LLFBConnectTest : public LLPluginClassMediaOwner
+{
+ public:
+ LLFBConnectTest( int app_window, int window_width, int window_height );
+ ~LLFBConnectTest();
+
+ void reshape( int width, int height );
+ void display();
+ void idle();
+ void gluiCallback( int control_id );
+ void keyboard( int key );
+ void mousePassive( int x, int y );
+ void mouseButton( int button, int state, int x, int y );
+ void mouseMove( int x, int y );
+
+ void bindTexture(GLuint texture, GLint row_length = 0, GLint alignment = 1);
+ bool checkGLError(const char *name = "OpenGL");
+ void drawGeometry( int panel, bool selected );
+ void startPanelHighlight( float red, float green, float blue, float line_width );
+ void endPanelHighlight();
+ enum { DrawTypePickTexture, DrawTypeMediaTexture };
+ void draw( int draw_type );
+ void windowPosToTexturePos( int window_x, int window_y, int& media_x, int& media_y, int& id );
+
+ mediaPanel* addMediaPanel( std::string url );
+ void updateMediaPanel( mediaPanel* panel );
+ void remMediaPanel( mediaPanel* panel );
+ mediaPanel* replaceMediaPanel( mediaPanel* panel, std::string url );
+ void getRandomMediaSize( int& width, int& height, std::string mime_type );
+ void navigateToNewURI( std::string uri );
+ void initUrlHistory( std::string uri );
+ void selectPanelById( int id );
+ void selectPanel( mediaPanel* panel );
+ mediaPanel* findMediaPanel( LLPluginClassMedia* panel );
+ mediaPanel* findMediaPanel( const std::string &target_name );
+ void makePickTexture( int id, GLuint* texture_handle, unsigned char** texture_pixels );
+ void makeChrome();
+ void resetView();
+
+ void dumpPanelInfo();
+ void updateStatusBar();
+
+ GLfloat distanceToCamera( GLfloat point_x, GLfloat point_y, GLfloat point_z );
+
+
+ // Inherited from LLPluginClassMediaOwner
+ /*virtual*/ void handleMediaEvent(LLPluginClassMedia* self, LLPluginClassMediaOwner::EMediaEvent);
+
+ private:
+ const int mVersionMajor;
+ const int mVersionMinor;
+ const int mVersionPatch;
+ const int mMaxPanels;
+ int mAppWindow;
+ int mWindowWidth;
+ int mWindowHeight;
+ int mCurMouseX;
+ int mCurMouseY;
+ unsigned char mPixelReadColor[ 3 ];
+ bool mFuzzyMedia;
+ const std::string mHomeWebUrl;
+
+ std::vector< mediaPanel* > mMediaPanels;
+ mediaPanel* mSelectedPanel;
+ std::string mimeTypeFromUrl( std::string& url );
+ std::string pluginNameFromMimeType( std::string& mime_type );
+
+ GLUI_Rotation* mViewRotationCtrl;
+ GLUI_Translation* mViewScaleCtrl;
+ GLUI_Translation* mViewTranslationCtrl;
+ float mViewportAspect;
+ float mViewPos[ 3 ];
+ float mViewRotation[ 16 ];
+
+ float mDistanceCameraToSelectedGeometry;
+
+ int mIdControlAddPanel;
+ int mIdControlRemPanel;
+
+ std::vector< std::pair< std::string, std::string > > mBookmarks;
+ GLUI_Listbox* mBookmarkList;
+ int mIdBookmarks;
+ int mIdUrlEdit;
+ GLUI_EditText* mUrlEdit;
+ //int mIdUrlInitHistoryEdit;
+ //GLUI_EditText* mUrlInitHistoryEdit;
+ int mSelBookmark;
+ //int mIdRandomPanelCount;
+ //int mRandomPanelCount;
+ //int mIdRandomBookmarks;
+ //int mRandomBookmarks;
+ //int mIdDisableTimeout;
+ //int mDisableTimeout;
+ //int mIdUsePluginReadThread;
+ //int mUsePluginReadThread;
+ //int mIdLargePanelSpacing;
+ //int mLargePanelSpacing;
+ //int mIdControlCrashPlugin;
+ //int mIdControlHangPlugin;
+ int mIdControlExitApp;
+
+ //GLUI* mGluiMediaTimeControlWindow;
+ //int mIdMediaTimeControlPlay;
+ //int mIdMediaTimeControlLoop;
+ //int mIdMediaTimeControlPause;
+ //int mIdMediaTimeControlStop;
+ //int mIdMediaTimeControlSeek;
+ //int mIdMediaTimeControlVolume;
+ //int mMediaTimeControlVolume;
+ //int mIdMediaTimeControlSeekSeconds;
+ //int mMediaTimeControlSeekSeconds;
+ //int mIdMediaTimeControlRewind;
+ //int mIdMediaTimeControlFastForward;
+
+ GLUI* mGluiMediaBrowserControlWindow;
+ int mIdMediaBrowserControlBack;
+ GLUI_Button* mMediaBrowserControlBackButton;
+ int mIdMediaBrowserControlStop;
+ int mIdMediaBrowserControlForward;
+ GLUI_Button* mMediaBrowserControlForwardButton;
+ bool mGluiMediaTimeControlWindowFlag;
+ bool mGluiMediaBrowserControlWindowFlag;
+ bool mMediaBrowserControlBackButtonFlag;
+ bool mMediaBrowserControlForwardButtonFlag;
+ int mIdMediaBrowserControlHome;
+ int mIdMediaBrowserControlReload;
+ int mIdMediaBrowserControlClearCache;
+ int mIdMediaBrowserControlClearCookies;
+ int mIdMediaBrowserControlEnableCookies;
+ int mMediaBrowserControlEnableCookies;
+
+ GLUI* mBottomGLUIWindow;
+ GLUI_StaticText* mStatusText;
+};
+
+#endif // LL_FB_CONNECT_H
+
diff --git a/indra/test_apps/llplugintest/CMakeLists.txt b/indra/test_apps/llplugintest/CMakeLists.txt
index 1211bb7e5a..8179be66f5 100644..100755
--- a/indra/test_apps/llplugintest/CMakeLists.txt
+++ b/indra/test_apps/llplugintest/CMakeLists.txt
@@ -2,7 +2,7 @@
project(llplugintest)
include(00-Common)
-include(FindOpenGL)
+include(OpenGL)
include(LLCommon)
include(LLPlugin)
include(Linking)
@@ -25,6 +25,9 @@ include_directories(
${LLRENDER_INCLUDE_DIRS}
${LLWINDOW_INCLUDE_DIRS}
)
+include_directories(SYSTEM
+ ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+ )
if (DARWIN)
include(CMakeFindFrameworks)
diff --git a/indra/test_apps/llplugintest/bookmarks.txt b/indra/test_apps/llplugintest/bookmarks.txt
index 2ff64f217f..2ff64f217f 100644..100755
--- a/indra/test_apps/llplugintest/bookmarks.txt
+++ b/indra/test_apps/llplugintest/bookmarks.txt
diff --git a/indra/test_apps/llplugintest/llmediaplugintest.cpp b/indra/test_apps/llplugintest/llmediaplugintest.cpp
index 884b00f0cc..884b00f0cc 100644..100755
--- a/indra/test_apps/llplugintest/llmediaplugintest.cpp
+++ b/indra/test_apps/llplugintest/llmediaplugintest.cpp
diff --git a/indra/test_apps/llplugintest/llmediaplugintest.h b/indra/test_apps/llplugintest/llmediaplugintest.h
index 1f6f18e43c..1f6f18e43c 100644..100755
--- a/indra/test_apps/llplugintest/llmediaplugintest.h
+++ b/indra/test_apps/llplugintest/llmediaplugintest.h
diff --git a/indra/tools/vstool/README.txt b/indra/tools/vstool/README.txt
index e419180031..e419180031 100644..100755
--- a/indra/tools/vstool/README.txt
+++ b/indra/tools/vstool/README.txt
diff --git a/indra/tools/vstool/VSTool.csproj b/indra/tools/vstool/VSTool.csproj
index 7f431e85c7..7f431e85c7 100644..100755
--- a/indra/tools/vstool/VSTool.csproj
+++ b/indra/tools/vstool/VSTool.csproj
diff --git a/indra/tools/vstool/VSTool.sln b/indra/tools/vstool/VSTool.sln
index 21e3d75971..21e3d75971 100644..100755
--- a/indra/tools/vstool/VSTool.sln
+++ b/indra/tools/vstool/VSTool.sln
diff --git a/indra/tools/vstool/main.cs b/indra/tools/vstool/main.cs
index cc73261e30..cc73261e30 100644..100755
--- a/indra/tools/vstool/main.cs
+++ b/indra/tools/vstool/main.cs
diff --git a/indra/viewer_components/CMakeLists.txt b/indra/viewer_components/CMakeLists.txt
index 74c9b4568d..74c9b4568d 100644..100755
--- a/indra/viewer_components/CMakeLists.txt
+++ b/indra/viewer_components/CMakeLists.txt
diff --git a/indra/viewer_components/login/CMakeLists.txt b/indra/viewer_components/login/CMakeLists.txt
index 7720619df3..6f366677c9 100644..100755
--- a/indra/viewer_components/login/CMakeLists.txt
+++ b/indra/viewer_components/login/CMakeLists.txt
@@ -9,12 +9,17 @@ endif(LL_TESTS)
include(LLCommon)
include(LLMath)
include(LLXML)
+include(Boost)
include_directories(
${LLCOMMON_INCLUDE_DIRS}
${LLMATH_INCLUDE_DIRS}
${LLXML_INCLUDE_DIRS}
)
+include_directories(SYSTEM
+ ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+ ${LLXML_SYSTEM_INCLUDE_DIRS}
+ )
set(login_SOURCE_FILES
lllogin.cpp
@@ -40,12 +45,18 @@ target_link_libraries(lllogin
${LLCOMMON_LIBRARIES}
${LLMATH_LIBRARIES}
${LLXML_LIBRARIES}
+ ${BOOST_CONTEXT_LIBRARY}
)
if(LL_TESTS)
SET(lllogin_TEST_SOURCE_FILES
lllogin.cpp
)
+ set_source_files_properties(
+ lllogin.cpp
+ PROPERTIES
+ LL_TEST_ADDITIONAL_LIBRARIES "${BOOST_CONTEXT_LIBRARY}"
+ )
LL_ADD_PROJECT_UNIT_TESTS(lllogin "${lllogin_TEST_SOURCE_FILES}")
endif(LL_TESTS)
diff --git a/indra/viewer_components/login/lllogin.cpp b/indra/viewer_components/login/lllogin.cpp
index d480b63094..8f33b2ad58 100644..100755
--- a/indra/viewer_components/login/lllogin.cpp
+++ b/indra/viewer_components/login/lllogin.cpp
@@ -23,7 +23,6 @@
* $/LicenseInfo$
*/
-#include <boost/coroutine/coroutine.hpp>
#include "linden_common.h"
#include "llsd.h"
#include "llsdutil.h"
@@ -138,7 +137,7 @@ void LLLogin::Impl::login_(LLCoros::self& self, std::string uri, LLSD login_para
//{
// printable_params["params"]["passwd"] = "*******";
//}
- LL_DEBUGS("LLLogin") << "Entering coroutine " << LLCoros::instance().getName(self)
+ LL_DEBUGS("LLLogin") << "Entering coroutine " << LLCoros::instance().getName(self)
<< " with uri '" << uri << "', parameters " << printable_params << LL_ENDL;
// Arriving in SRVRequest state
@@ -147,23 +146,23 @@ void LLLogin::Impl::login_(LLCoros::self& self, std::string uri, LLSD login_para
LLSD rewrittenURIs;
{
- LLEventTimeout filter(replyPump);
- sendProgressEvent("offline", "srvrequest");
+ LLEventTimeout filter(replyPump);
+ sendProgressEvent("offline", "srvrequest");
- // Request SRV record.
- LL_DEBUGS("LLLogin") << "Requesting SRV record from " << uri << LL_ENDL;
+ // Request SRV record.
+ LL_DEBUGS("LLLogin") << "Requesting SRV record from " << uri << LL_ENDL;
- // *NOTE:Mani - Completely arbitrary default timeout value for SRV request.
+ // *NOTE:Mani - Completely arbitrary default timeout value for SRV request.
F32 seconds_to_timeout = 5.0f;
if(login_params.has("cfg_srv_timeout"))
{
seconds_to_timeout = login_params["cfg_srv_timeout"].asReal();
}
- // If the SRV request times out (e.g. EXT-3934), simulate response: an
- // array containing our original URI.
- LLSD fakeResponse(LLSD::emptyArray());
- fakeResponse.append(uri);
+ // If the SRV request times out (e.g. EXT-3934), simulate response: an
+ // array containing our original URI.
+ LLSD fakeResponse(LLSD::emptyArray());
+ fakeResponse.append(uri);
filter.eventAfter(seconds_to_timeout, fakeResponse);
std::string srv_pump_name = "LLAres";
@@ -173,13 +172,13 @@ void LLLogin::Impl::login_(LLCoros::self& self, std::string uri, LLSD login_para
}
// Make request
- LLSD request;
- request["op"] = "rewriteURI";
- request["uri"] = uri;
- request["reply"] = replyPump.getName();
- rewrittenURIs = postAndWait(self, request, srv_pump_name, filter);
- // EXP-772: If rewrittenURIs fail, try original URI as a fallback.
- rewrittenURIs.append(uri);
+ LLSD request;
+ request["op"] = "rewriteURI";
+ request["uri"] = uri;
+ request["reply"] = replyPump.getName();
+ rewrittenURIs = postAndWait(self, request, srv_pump_name, filter);
+ // EXP-772: If rewrittenURIs fail, try original URI as a fallback.
+ rewrittenURIs.append(uri);
} // we no longer need the filter
LLEventPump& xmlrpcPump(LLEventPumps::instance().obtain("LLXMLRPCTransaction"));
@@ -231,7 +230,7 @@ void LLLogin::Impl::login_(LLCoros::self& self, std::string uri, LLSD login_para
// Still Downloading -- send progress update.
sendProgressEvent("offline", "downloading");
}
-
+
LL_DEBUGS("LLLogin") << "Auth Response: " << mAuthResponse << LL_ENDL;
status = mAuthResponse["status"].asString();
@@ -271,6 +270,16 @@ void LLLogin::Impl::login_(LLCoros::self& self, std::string uri, LLSD login_para
}
return; // Done!
}
+
+ /* Sometimes we end with "Started" here. Slightly slow server?
+ * Seems to be ok to just skip it. Otherwise we'd error out and crash in the if below.
+ */
+ if( status == "Started")
+ {
+ LL_DEBUGS("LLLogin") << mAuthResponse << LL_ENDL;
+ continue;
+ }
+
// If we don't recognize status at all, trouble
if (! (status == "CURLError"
|| status == "XMLRPCError"
diff --git a/indra/viewer_components/login/lllogin.h b/indra/viewer_components/login/lllogin.h
index 051641ff59..051641ff59 100644..100755
--- a/indra/viewer_components/login/lllogin.h
+++ b/indra/viewer_components/login/lllogin.h
diff --git a/indra/viewer_components/login/tests/lllogin_test.cpp b/indra/viewer_components/login/tests/lllogin_test.cpp
index 58bf371a04..58bf371a04 100644..100755
--- a/indra/viewer_components/login/tests/lllogin_test.cpp
+++ b/indra/viewer_components/login/tests/lllogin_test.cpp
diff --git a/indra/viewer_components/updater/CMakeLists.txt b/indra/viewer_components/updater/CMakeLists.txt
index ef82290b47..61fd4220e0 100644..100755
--- a/indra/viewer_components/updater/CMakeLists.txt
+++ b/indra/viewer_components/updater/CMakeLists.txt
@@ -19,6 +19,10 @@ include_directories(
${LLPLUGIN_INCLUDE_DIRS}
${LLVFS_INCLUDE_DIRS}
${CURL_INCLUDE_DIRS}
+ ${CMAKE_SOURCE_DIR}/newview
+ )
+include_directories(SYSTEM
+ ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
)
set(updater_service_SOURCE_FILES
@@ -38,6 +42,12 @@ set(updater_service_HEADER_FILES
set_source_files_properties(${updater_service_HEADER_FILES}
PROPERTIES HEADER_FILE_ONLY TRUE)
+set_source_files_properties(
+ llupdaterservice.cpp
+ PROPERTIES
+ COMPILE_DEFINITIONS "${VIEWER_CHANNEL_VERSION_DEFINES}" # see BuildVersion.cmake
+ )
+
list(APPEND
updater_service_SOURCE_FILES
${updater_service_HEADER_FILES}
diff --git a/indra/viewer_components/updater/llupdatechecker.cpp b/indra/viewer_components/updater/llupdatechecker.cpp
index c6aa9b0f11..dc8ff2f644 100644..100755
--- a/indra/viewer_components/updater/llupdatechecker.cpp
+++ b/indra/viewer_components/updater/llupdatechecker.cpp
@@ -30,7 +30,9 @@
#include "llsd.h"
#include "llupdatechecker.h"
#include "lluri.h"
-
+#if LL_DARWIN
+#include <CoreServices/CoreServices.h>
+#endif
#if LL_WINDOWS
#pragma warning (disable : 4355) // 'this' used in initializer list: yes, intentionally
@@ -49,37 +51,6 @@ public:
};
-class LLUpdateChecker::Implementation:
- public LLHTTPClient::Responder
-{
-public:
- Implementation(Client & client);
- ~Implementation();
- void check(std::string const & protocolVersion, std::string const & hostUrl,
- std::string const & servicePath, std::string channel, std::string version);
-
- // Responder:
- virtual void completed(U32 status,
- const std::string & reason,
- const LLSD& content);
- virtual void error(U32 status, const std::string & reason);
-
-private:
- static const char * sProtocolVersion;
-
- Client & mClient;
- LLHTTPClient mHttpClient;
- bool mInProgress;
- std::string mVersion;
-
- std::string buildUrl(std::string const & protocolVersion, std::string const & hostUrl,
- std::string const & servicePath, std::string channel, std::string version);
-
- LOG_CLASS(LLUpdateChecker::Implementation);
-};
-
-
-
// LLUpdateChecker
//-----------------------------------------------------------------------------
@@ -91,10 +62,15 @@ LLUpdateChecker::LLUpdateChecker(LLUpdateChecker::Client & client):
}
-void LLUpdateChecker::check(std::string const & protocolVersion, std::string const & hostUrl,
- std::string const & servicePath, std::string channel, std::string version)
+void LLUpdateChecker::checkVersion(std::string const & urlBase,
+ std::string const & channel,
+ std::string const & version,
+ std::string const & platform,
+ std::string const & platform_version,
+ unsigned char uniqueid[MD5HEX_STR_SIZE],
+ bool willing_to_test)
{
- mImplementation->check(protocolVersion, hostUrl, servicePath, channel, version);
+ mImplementation->checkVersion(urlBase, channel, version, platform, platform_version, uniqueid, willing_to_test);
}
@@ -103,12 +79,13 @@ void LLUpdateChecker::check(std::string const & protocolVersion, std::string con
//-----------------------------------------------------------------------------
-const char * LLUpdateChecker::Implementation::sProtocolVersion = "v1.0";
+const char * LLUpdateChecker::Implementation::sProtocolVersion = "v1.1";
LLUpdateChecker::Implementation::Implementation(LLUpdateChecker::Client & client):
mClient(client),
- mInProgress(false)
+ mInProgress(false),
+ mProtocol(sProtocolVersion)
{
; // No op.
}
@@ -120,47 +97,67 @@ LLUpdateChecker::Implementation::~Implementation()
}
-void LLUpdateChecker::Implementation::check(std::string const & protocolVersion, std::string const & hostUrl,
- std::string const & servicePath, std::string channel, std::string version)
+void LLUpdateChecker::Implementation::checkVersion(std::string const & urlBase,
+ std::string const & channel,
+ std::string const & version,
+ std::string const & platform,
+ std::string const & platform_version,
+ unsigned char uniqueid[MD5HEX_STR_SIZE],
+ bool willing_to_test)
{
- llassert(!mInProgress);
+ if (!mInProgress)
+ {
+ mInProgress = true;
+
+ mUrlBase = urlBase;
+ mChannel = channel;
+ mVersion = version;
+ mPlatform = platform;
+ mPlatformVersion = platform_version;
+ memcpy(mUniqueId, uniqueid, MD5HEX_STR_SIZE);
+ mWillingToTest = willing_to_test;
- if(protocolVersion != sProtocolVersion) throw CheckError("unsupported protocol");
-
- mInProgress = true;
- mVersion = version;
- std::string checkUrl = buildUrl(protocolVersion, hostUrl, servicePath, channel, version);
- LL_INFOS("UpdateCheck") << "checking for updates at " << checkUrl << llendl;
+ mProtocol = sProtocolVersion;
+
+ std::string checkUrl = buildUrl(urlBase, channel, version, platform, platform_version, uniqueid, willing_to_test);
+ LL_INFOS("UpdaterService") << "checking for updates at " << checkUrl << LL_ENDL;
- // The HTTP client will wrap a raw pointer in a boost::intrusive_ptr causing the
- // passed object to be silently and automatically deleted. We pass a self-
- // referential intrusive pointer to which we add a reference to keep the
- // client from deleting the update checker implementation instance.
- LLHTTPClient::ResponderPtr temporaryPtr(this);
- boost::intrusive_ptr_add_ref(temporaryPtr.get());
- mHttpClient.get(checkUrl, temporaryPtr);
+ mHttpClient.get(checkUrl, this);
+ }
+ else
+ {
+ LL_WARNS("UpdaterService") << "attempting to restart a check when one is in progress; ignored" << LL_ENDL;
+ }
}
void LLUpdateChecker::Implementation::completed(U32 status,
- const std::string & reason,
- const LLSD & content)
+ const std::string & reason,
+ const LLSD & content)
{
mInProgress = false;
- if(status != 200) {
- LL_WARNS("UpdateCheck") << "html error " << status << " (" << reason << ")" << llendl;
+ if(status != 200)
+ {
+ std::string server_error;
+ if ( content.has("error_code") )
+ {
+ server_error += content["error_code"].asString();
+ }
+ if ( content.has("error_text") )
+ {
+ server_error += server_error.empty() ? "" : ": ";
+ server_error += content["error_text"].asString();
+ }
+
+ LL_WARNS("UpdaterService") << "response error " << status
+ << " " << reason
+ << " (" << server_error << ")"
+ << LL_ENDL;
mClient.error(reason);
- } else if(!content.asBoolean()) {
- LL_INFOS("UpdateCheck") << "up to date" << llendl;
- mClient.upToDate();
- } else if(content["required"].asBoolean()) {
- LL_INFOS("UpdateCheck") << "version invalid" << llendl;
- LLURI uri(content["url"].asString());
- mClient.requiredUpdate(content["version"].asString(), uri, content["hash"].asString());
- } else {
- LL_INFOS("UpdateCheck") << "newer version " << content["version"].asString() << " available" << llendl;
- LLURI uri(content["url"].asString());
- mClient.optionalUpdate(content["version"].asString(), uri, content["hash"].asString());
+ }
+ else
+ {
+ mClient.response(content);
}
}
@@ -168,27 +165,26 @@ void LLUpdateChecker::Implementation::completed(U32 status,
void LLUpdateChecker::Implementation::error(U32 status, const std::string & reason)
{
mInProgress = false;
- LL_WARNS("UpdateCheck") << "update check failed; " << reason << llendl;
+ LL_WARNS("UpdaterService") << "update check failed; " << reason << LL_ENDL;
mClient.error(reason);
}
-std::string LLUpdateChecker::Implementation::buildUrl(std::string const & protocolVersion, std::string const & hostUrl,
- std::string const & servicePath, std::string channel, std::string version)
-{
-#ifdef LL_WINDOWS
- static const char * platform = "win";
-#elif LL_DARWIN
- static const char * platform = "mac";
-#else
- static const char * platform = "lnx";
-#endif
-
+std::string LLUpdateChecker::Implementation::buildUrl(std::string const & urlBase,
+ std::string const & channel,
+ std::string const & version,
+ std::string const & platform,
+ std::string const & platform_version,
+ unsigned char uniqueid[MD5HEX_STR_SIZE],
+ bool willing_to_test)
+{
LLSD path;
- path.append(servicePath);
- path.append(protocolVersion);
+ path.append(mProtocol);
path.append(channel);
path.append(version);
path.append(platform);
- return LLURI::buildHTTP(hostUrl, path).asString();
+ path.append(platform_version);
+ path.append(willing_to_test ? "testok" : "testno");
+ path.append((char*)uniqueid);
+ return LLURI::buildHTTP(urlBase, path).asString();
}
diff --git a/indra/viewer_components/updater/llupdatechecker.h b/indra/viewer_components/updater/llupdatechecker.h
index cea1f13647..4244007340 100644..100755
--- a/indra/viewer_components/updater/llupdatechecker.h
+++ b/indra/viewer_components/updater/llupdatechecker.h
@@ -29,6 +29,8 @@
#include <boost/shared_ptr.hpp>
+#include "llmd5.h"
+#include "llhttpclient.h"
//
// Implements asynchronous checking for updates.
@@ -36,7 +38,53 @@
class LLUpdateChecker {
public:
class Client;
- class Implementation;
+ class Implementation: public LLHTTPClient::Responder
+ {
+ public:
+ Implementation(Client & client);
+ ~Implementation();
+ void checkVersion(std::string const & urlBase,
+ std::string const & channel,
+ std::string const & version,
+ std::string const & platform,
+ std::string const & platform_version,
+ unsigned char uniqueid[MD5HEX_STR_SIZE],
+ bool willing_to_test
+ );
+
+ // Responder:
+ virtual void completed(U32 status,
+ const std::string & reason,
+ const LLSD& content);
+ virtual void error(U32 status, const std::string & reason);
+
+ private:
+ static const char * sLegacyProtocolVersion;
+ static const char * sProtocolVersion;
+ const char* mProtocol;
+
+ Client & mClient;
+ LLHTTPClient mHttpClient;
+ bool mInProgress;
+ std::string mVersion;
+ std::string mUrlBase;
+ std::string mChannel;
+ std::string mPlatform;
+ std::string mPlatformVersion;
+ unsigned char mUniqueId[MD5HEX_STR_SIZE];
+ bool mWillingToTest;
+
+ std::string buildUrl(std::string const & urlBase,
+ std::string const & channel,
+ std::string const & version,
+ std::string const & platform,
+ std::string const & platform_version,
+ unsigned char uniqueid[MD5HEX_STR_SIZE],
+ bool willing_to_test);
+
+ LOG_CLASS(LLUpdateChecker::Implementation);
+ };
+
// An exception that may be raised on check errors.
class CheckError;
@@ -44,11 +92,16 @@ public:
LLUpdateChecker(Client & client);
// Check status of current app on the given host for the channel and version provided.
- void check(std::string const & protocolVersion, std::string const & hostUrl,
- std::string const & servicePath, std::string channel, std::string version);
+ void checkVersion(std::string const & urlBase,
+ std::string const & channel,
+ std::string const & version,
+ std::string const & platform,
+ std::string const & platform_version,
+ unsigned char uniqueid[MD5HEX_STR_SIZE],
+ bool willing_to_test);
private:
- boost::shared_ptr<Implementation> mImplementation;
+ LLPointer<Implementation> mImplementation;
};
@@ -64,18 +117,8 @@ public:
// An error occurred while checking for an update.
virtual void error(std::string const & message) = 0;
- // A newer version is available, but the current version may still be used.
- virtual void optionalUpdate(std::string const & newVersion,
- LLURI const & uri,
- std::string const & hash) = 0;
-
- // A newer version is available, and the current version is no longer valid.
- virtual void requiredUpdate(std::string const & newVersion,
- LLURI const & uri,
- std::string const & hash) = 0;
-
- // The checked version is up to date; no newer version exists.
- virtual void upToDate(void) = 0;
+ // A successful response was received from the viewer version manager
+ virtual void response(LLSD const & content) = 0;
};
diff --git a/indra/viewer_components/updater/llupdatedownloader.cpp b/indra/viewer_components/updater/llupdatedownloader.cpp
index 19ac418e9e..c28ad76c77 100644..100755
--- a/indra/viewer_components/updater/llupdatedownloader.cpp
+++ b/indra/viewer_components/updater/llupdatedownloader.cpp
@@ -1,24 +1,24 @@
-/**
+/**
* @file llupdatedownloader.cpp
*
* $LicenseInfo:firstyear=2010&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$
*/
@@ -50,7 +50,9 @@ public:
void cancel(void);
void download(LLURI const & uri,
std::string const & hash,
+ std::string const & updateChannel,
std::string const & updateVersion,
+ std::string const & info_url,
bool required);
bool isDownloading(void);
size_t onHeader(void * header, size_t size);
@@ -58,7 +60,7 @@ public:
int onProgress(double downloadSize, double bytesDownloaded);
void resume(void);
void setBandwidthLimit(U64 bytesPerSecond);
-
+
private:
curl_off_t mBandwidthLimit;
bool mCancelled;
@@ -69,7 +71,7 @@ private:
unsigned char mDownloadPercent;
std::string mDownloadRecordPath;
curl_slist * mHeaderList;
-
+
void initializeCurlGet(std::string const & url, bool processHeader);
void resumeDownloading(size_t startByte);
void run(void);
@@ -93,7 +95,7 @@ namespace {
}
};
-
+
const char * gSecondLifeUpdateRecord = "SecondLifeUpdateDownload.xml";
};
@@ -125,10 +127,12 @@ void LLUpdateDownloader::cancel(void)
void LLUpdateDownloader::download(LLURI const & uri,
std::string const & hash,
+ std::string const & updateChannel,
std::string const & updateVersion,
+ std::string const & info_url,
bool required)
{
- mImplementation->download(uri, hash, updateVersion, required);
+ mImplementation->download(uri, hash, updateChannel, updateVersion, info_url, required);
}
@@ -192,18 +196,18 @@ LLUpdateDownloader::Implementation::Implementation(LLUpdateDownloader::Client &
mHeaderList(0)
{
CURLcode code = curl_global_init(CURL_GLOBAL_ALL); // Just in case.
- llverify(code == CURLE_OK); // TODO: real error handling here.
+ llverify(code == CURLE_OK); // TODO: real error handling here.
}
LLUpdateDownloader::Implementation::~Implementation()
{
- if(isDownloading())
+ if(isDownloading())
{
cancel();
shutdown();
- }
- else
+ }
+ else
{
; // No op.
}
@@ -218,22 +222,32 @@ void LLUpdateDownloader::Implementation::cancel(void)
{
mCancelled = true;
}
-
+
void LLUpdateDownloader::Implementation::download(LLURI const & uri,
std::string const & hash,
+ std::string const & updateChannel,
std::string const & updateVersion,
+ std::string const & info_url,
bool required)
-{
+{
if(isDownloading()) mClient.downloadError("download in progress");
mDownloadRecordPath = downloadMarkerPath();
mDownloadData = LLSD();
mDownloadData["required"] = required;
+ mDownloadData["update_channel"] = updateChannel;
mDownloadData["update_version"] = updateVersion;
- try {
+ if (!info_url.empty())
+ {
+ mDownloadData["info_url"] = info_url;
+ }
+ try
+ {
startDownloading(uri, hash);
- } catch(DownloadError const & e) {
+ }
+ catch(DownloadError const & e)
+ {
mClient.downloadError(e.what());
}
}
@@ -249,47 +263,65 @@ void LLUpdateDownloader::Implementation::resume(void)
{
mCancelled = false;
- if(isDownloading()) {
+ if(isDownloading())
+ {
mClient.downloadError("download in progress");
}
mDownloadRecordPath = downloadMarkerPath();
llifstream dataStream(mDownloadRecordPath);
- if(!dataStream) {
+ if(!dataStream)
+ {
mClient.downloadError("no download marker");
return;
}
-
+
LLSDSerialize::fromXMLDocument(mDownloadData, dataStream);
-
- if(!mDownloadData.asBoolean()) {
+
+ if(!mDownloadData.asBoolean())
+ {
mClient.downloadError("no download information in marker");
return;
}
-
+
std::string filePath = mDownloadData["path"].asString();
- try {
- if(LLFile::isfile(filePath)) {
+ try
+ {
+ if(LLFile::isfile(filePath))
+ {
llstat fileStatus;
LLFile::stat(filePath, &fileStatus);
- if(fileStatus.st_size != mDownloadData["size"].asInteger()) {
+ if(fileStatus.st_size != mDownloadData["size"].asInteger())
+ {
resumeDownloading(fileStatus.st_size);
- } else if(!validateDownload()) {
+ }
+ else if(!validateDownload())
+ {
LLFile::remove(filePath);
- download(LLURI(mDownloadData["url"].asString()),
+ download(LLURI(mDownloadData["url"].asString()),
mDownloadData["hash"].asString(),
+ mDownloadData["update_channel"].asString(),
mDownloadData["update_version"].asString(),
+ mDownloadData["info_url"].asString(),
mDownloadData["required"].asBoolean());
- } else {
+ }
+ else
+ {
mClient.downloadComplete(mDownloadData);
}
- } else {
- download(LLURI(mDownloadData["url"].asString()),
+ }
+ else
+ {
+ download(LLURI(mDownloadData["url"].asString()),
mDownloadData["hash"].asString(),
+ mDownloadData["update_channel"].asString(),
mDownloadData["update_version"].asString(),
+ mDownloadData["info_url"].asString(),
mDownloadData["required"].asBoolean());
}
- } catch(DownloadError & e) {
+ }
+ catch(DownloadError & e)
+ {
mClient.downloadError(e.what());
}
}
@@ -297,13 +329,18 @@ void LLUpdateDownloader::Implementation::resume(void)
void LLUpdateDownloader::Implementation::setBandwidthLimit(U64 bytesPerSecond)
{
- if((mBandwidthLimit != bytesPerSecond) && isDownloading() && !mDownloadData["required"].asBoolean()) {
+ if((mBandwidthLimit != bytesPerSecond) && isDownloading() && !mDownloadData["required"].asBoolean())
+ {
llassert(mCurl != 0);
mBandwidthLimit = bytesPerSecond;
CURLcode code = curl_easy_setopt(mCurl, CURLOPT_MAX_RECV_SPEED_LARGE, &mBandwidthLimit);
- if(code != CURLE_OK) LL_WARNS("UpdateDownload") <<
- "unable to change dowload bandwidth" << LL_ENDL;
- } else {
+ if(code != CURLE_OK)
+ {
+ LL_WARNS("UpdaterService") << "unable to change dowload bandwidth" << LL_ENDL;
+ }
+ }
+ else
+ {
mBandwidthLimit = bytesPerSecond;
}
}
@@ -315,26 +352,26 @@ size_t LLUpdateDownloader::Implementation::onHeader(void * buffer, size_t size)
std::string header(headerPtr, headerPtr + size);
size_t colonPosition = header.find(':');
if(colonPosition == std::string::npos) return size; // HTML response; ignore.
-
+
if(header.substr(0, colonPosition) == "Content-Length") {
try {
size_t firstDigitPos = header.find_first_of("0123456789", colonPosition);
size_t lastDigitPos = header.find_last_of("0123456789");
std::string contentLength = header.substr(firstDigitPos, lastDigitPos - firstDigitPos + 1);
size_t size = boost::lexical_cast<size_t>(contentLength);
- LL_INFOS("UpdateDownload") << "download size is " << size << LL_ENDL;
-
+ LL_INFOS("UpdaterService") << "download size is " << size << LL_ENDL;
+
mDownloadData["size"] = LLSD(LLSD::Integer(size));
llofstream odataStream(mDownloadRecordPath);
LLSDSerialize::toPrettyXML(mDownloadData, odataStream);
} catch (std::exception const & e) {
- LL_WARNS("UpdateDownload") << "unable to read content length ("
+ LL_WARNS("UpdaterService") << "unable to read content length ("
<< e.what() << ")" << LL_ENDL;
}
} else {
; // No op.
}
-
+
return size;
}
@@ -342,9 +379,9 @@ size_t LLUpdateDownloader::Implementation::onHeader(void * buffer, size_t size)
size_t LLUpdateDownloader::Implementation::onBody(void * buffer, size_t size)
{
if(mCancelled) return 0; // Forces a write error which will halt curl thread.
- if((size == 0) || (buffer == 0)) return 0;
-
- mDownloadStream.write(reinterpret_cast<const char *>(buffer), size);
+ if((size == 0) || (buffer == 0)) return 0;
+
+ mDownloadStream.write(static_cast<const char *>(buffer), size);
if(mDownloadStream.bad()) {
return 0;
} else {
@@ -358,7 +395,7 @@ int LLUpdateDownloader::Implementation::onProgress(double downloadSize, double b
int downloadPercent = static_cast<int>(100. * (bytesDownloaded / downloadSize));
if(downloadPercent > mDownloadPercent) {
mDownloadPercent = downloadPercent;
-
+
LLSD event;
event["pump"] = LLUpdaterService::pumpName();
LLSD payload;
@@ -367,12 +404,12 @@ int LLUpdateDownloader::Implementation::onProgress(double downloadSize, double b
payload["bytes_downloaded"] = bytesDownloaded;
event["payload"] = payload;
LLEventPumps::instance().obtain("mainlooprepeater").post(event);
-
- LL_INFOS("UpdateDownload") << "progress event " << payload << LL_ENDL;
+
+ LL_INFOS("UpdaterService") << "progress event " << payload << LL_ENDL;
} else {
; // Keep events to a reasonalbe number.
}
-
+
return 0;
}
@@ -381,29 +418,44 @@ void LLUpdateDownloader::Implementation::run(void)
{
CURLcode code = curl_easy_perform(mCurl);
mDownloadStream.close();
- if(code == CURLE_OK) {
+ if(code == CURLE_OK)
+ {
LLFile::remove(mDownloadRecordPath);
- if(validateDownload()) {
- LL_INFOS("UpdateDownload") << "download successful" << LL_ENDL;
+ if(validateDownload())
+ {
+ LL_INFOS("UpdaterService") << "download successful" << LL_ENDL;
mClient.downloadComplete(mDownloadData);
- } else {
- LL_INFOS("UpdateDownload") << "download failed hash check" << LL_ENDL;
+ }
+ else
+ {
+ LL_INFOS("UpdaterService") << "download failed hash check" << LL_ENDL;
std::string filePath = mDownloadData["path"].asString();
- if(filePath.size() != 0) LLFile::remove(filePath);
+ if(filePath.size() != 0)
+ {
+ LLFile::remove(filePath);
+ }
mClient.downloadError("failed hash check");
}
- } else if(mCancelled && (code == CURLE_WRITE_ERROR)) {
- LL_INFOS("UpdateDownload") << "download canceled by user" << LL_ENDL;
+ }
+ else if(mCancelled && (code == CURLE_WRITE_ERROR))
+ {
+ LL_INFOS("UpdaterService") << "download canceled by user" << LL_ENDL;
// Do not call back client.
- } else {
- LL_WARNS("UpdateDownload") << "download failed with error '" <<
+ }
+ else
+ {
+ LL_WARNS("UpdaterService") << "download failed with error '" <<
curl_easy_strerror(code) << "'" << LL_ENDL;
LLFile::remove(mDownloadRecordPath);
- if(mDownloadData.has("path")) LLFile::remove(mDownloadData["path"].asString());
+ if(mDownloadData.has("path"))
+ {
+ LLFile::remove(mDownloadData["path"].asString());
+ }
mClient.downloadError("curl error");
}
-
- if(mHeaderList) {
+
+ if(mHeaderList)
+ {
curl_slist_free_all(mHeaderList);
mHeaderList = 0;
}
@@ -412,22 +464,25 @@ void LLUpdateDownloader::Implementation::run(void)
void LLUpdateDownloader::Implementation::initializeCurlGet(std::string const & url, bool processHeader)
{
- if(mCurl == 0)
+ if(mCurl == 0)
{
mCurl = LLCurl::newEasyHandle();
- }
- else
+ }
+ else
{
curl_easy_reset(mCurl);
}
-
- if(mCurl == 0) throw DownloadError("failed to initialize curl");
-
+
+ if(mCurl == 0)
+ {
+ throw DownloadError("failed to initialize curl");
+ }
throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_NOSIGNAL, true));
throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_FOLLOWLOCATION, true));
throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_WRITEFUNCTION, &write_function));
throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_WRITEDATA, this));
- if(processHeader) {
+ if(processHeader)
+ {
throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_HEADERFUNCTION, &header_function));
throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_HEADERDATA, this));
}
@@ -439,26 +494,29 @@ void LLUpdateDownloader::Implementation::initializeCurlGet(std::string const & u
// if it's a required update set the bandwidth limit to 0 (unlimited)
curl_off_t limit = mDownloadData["required"].asBoolean() ? 0 : mBandwidthLimit;
throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_MAX_RECV_SPEED_LARGE, limit));
-
+
mDownloadPercent = 0;
}
void LLUpdateDownloader::Implementation::resumeDownloading(size_t startByte)
{
- LL_INFOS("UpdateDownload") << "resuming download from " << mDownloadData["url"].asString()
+ LL_INFOS("UpdaterService") << "resuming download from " << mDownloadData["url"].asString()
<< " at byte " << startByte << LL_ENDL;
initializeCurlGet(mDownloadData["url"].asString(), false);
-
+
// The header 'Range: bytes n-' will request the bytes remaining in the
// source begining with byte n and ending with the last byte.
boost::format rangeHeaderFormat("Range: bytes=%u-");
rangeHeaderFormat % startByte;
mHeaderList = curl_slist_append(mHeaderList, rangeHeaderFormat.str().c_str());
- if(mHeaderList == 0) throw DownloadError("cannot add Range header");
+ if(mHeaderList == 0)
+ {
+ throw DownloadError("cannot add Range header");
+ }
throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_HTTPHEADER, mHeaderList));
-
+
mDownloadStream.open(mDownloadData["path"].asString(),
std::ios_base::out | std::ios_base::binary | std::ios_base::app);
start();
@@ -476,13 +534,13 @@ void LLUpdateDownloader::Implementation::startDownloading(LLURI const & uri, std
std::string filePath = gDirUtilp->getExpandedFilename(LL_PATH_TEMP, fileName);
mDownloadData["path"] = filePath;
- LL_INFOS("UpdateDownload") << "downloading " << filePath
+ LL_INFOS("UpdaterService") << "downloading " << filePath
<< " from " << uri.asString() << LL_ENDL;
- LL_INFOS("UpdateDownload") << "hash of file is " << hash << LL_ENDL;
-
+ LL_INFOS("UpdaterService") << "hash of file is " << hash << LL_ENDL;
+
llofstream dataStream(mDownloadRecordPath);
LLSDSerialize::toPrettyXML(mDownloadData, dataStream);
-
+
mDownloadStream.open(filePath, std::ios_base::out | std::ios_base::binary);
initializeCurlGet(uri.asString(), true);
start();
@@ -508,19 +566,26 @@ bool LLUpdateDownloader::Implementation::validateDownload(void)
{
std::string filePath = mDownloadData["path"].asString();
llifstream fileStream(filePath, std::ios_base::in | std::ios_base::binary);
- if(!fileStream) return false;
+ if(!fileStream)
+ {
+ return false;
+ }
std::string hash = mDownloadData["hash"].asString();
- if(hash.size() != 0) {
- LL_INFOS("UpdateDownload") << "checking hash..." << LL_ENDL;
+ if(hash.size() != 0)
+ {
+ LL_INFOS("UpdaterService") << "checking hash..." << LL_ENDL;
char digest[33];
LLMD5(fileStream).hex_digest(digest);
- if(hash != digest) {
- LL_WARNS("UpdateDownload") << "download hash mismatch; expeted " << hash <<
+ if(hash != digest)
+ {
+ LL_WARNS("UpdaterService") << "download hash mismatch; expected " << hash <<
" but download is " << digest << LL_ENDL;
}
return hash == digest;
- } else {
+ }
+ else
+ {
return true; // No hash check provided.
}
}
diff --git a/indra/viewer_components/updater/llupdatedownloader.h b/indra/viewer_components/updater/llupdatedownloader.h
index 0d635640cf..f759988f12 100644..100755
--- a/indra/viewer_components/updater/llupdatedownloader.h
+++ b/indra/viewer_components/updater/llupdatedownloader.h
@@ -54,7 +54,9 @@ public:
// Start a new download.
void download(LLURI const & uri,
std::string const & hash,
+ std::string const & updateChannel,
std::string const & updateVersion,
+ std::string const & info_url,
bool required=false);
// Returns true if a download is in progress.
diff --git a/indra/viewer_components/updater/llupdateinstaller.cpp b/indra/viewer_components/updater/llupdateinstaller.cpp
index c7b70c2de8..a0e2c0b362 100644..100755
--- a/indra/viewer_components/updater/llupdateinstaller.cpp
+++ b/indra/viewer_components/updater/llupdateinstaller.cpp
@@ -26,10 +26,10 @@
#include "linden_common.h"
#include <apr_file_io.h>
#include "llapr.h"
-#include "llprocesslauncher.h"
+#include "llprocess.h"
#include "llupdateinstaller.h"
#include "lldir.h"
-
+#include "llsd.h"
#if defined(LL_WINDOWS)
#pragma warning(disable: 4702) // disable 'unreachable code' so we can use lexical_cast (really!).
@@ -75,18 +75,16 @@ int ll_install_update(std::string const & script,
llassert(!"unpossible copy mode");
}
- llinfos << "UpdateInstaller: installing " << updatePath << " using " <<
+ LL_INFOS("Updater") << "UpdateInstaller: installing " << updatePath << " using " <<
actualScriptPath << LL_ENDL;
- LLProcessLauncher launcher;
- launcher.setExecutable(actualScriptPath);
- launcher.addArgument(updatePath);
- launcher.addArgument(ll_install_failed_marker_path().c_str());
- launcher.addArgument(boost::lexical_cast<std::string>(required));
- int result = launcher.launch();
- launcher.orphan();
-
- return result;
+ LLProcess::Params params;
+ params.executable = actualScriptPath;
+ params.args.add(updatePath);
+ params.args.add(ll_install_failed_marker_path());
+ params.args.add(boost::lexical_cast<std::string>(required));
+ params.autokill = false;
+ return LLProcess::create(params)? 0 : -1;
}
diff --git a/indra/viewer_components/updater/llupdateinstaller.h b/indra/viewer_components/updater/llupdateinstaller.h
index fe5b1d19b5..fe5b1d19b5 100644..100755
--- a/indra/viewer_components/updater/llupdateinstaller.h
+++ b/indra/viewer_components/updater/llupdateinstaller.h
diff --git a/indra/viewer_components/updater/llupdaterservice.cpp b/indra/viewer_components/updater/llupdaterservice.cpp
index 2e18218667..16950e1d62 100644..100755
--- a/indra/viewer_components/updater/llupdaterservice.cpp
+++ b/indra/viewer_components/updater/llupdaterservice.cpp
@@ -32,18 +32,24 @@
#include "lltimer.h"
#include "llupdatechecker.h"
#include "llupdateinstaller.h"
-#include "llversionviewer.h"
#include <boost/scoped_ptr.hpp>
#include <boost/weak_ptr.hpp>
#include "lldir.h"
#include "llsdserialize.h"
#include "llfile.h"
+#include "llviewernetwork.h"
#if LL_WINDOWS
#pragma warning (disable : 4355) // 'this' used in initializer list: yes, intentionally
#endif
+#if ! defined(LL_VIEWER_VERSION_MAJOR) \
+ || ! defined(LL_VIEWER_VERSION_MINOR) \
+ || ! defined(LL_VIEWER_VERSION_PATCH) \
+ || ! defined(LL_VIEWER_VERSION_BUILD)
+#error "Version information is undefined"
+#endif
namespace
{
@@ -60,6 +66,8 @@ namespace
{
#ifdef LL_WINDOWS
std::string scriptFile = "update_install.bat";
+#elif LL_DARWIN
+ std::string scriptFile = "update_install.py";
#else
std::string scriptFile = "update_install";
#endif
@@ -71,6 +79,8 @@ namespace
#ifdef LL_WINDOWS
return LL_COPY_INSTALL_SCRIPT_TO_TEMP;
#else
+ // This is important on Mac because update_install.py looks at its own
+ // script pathname to discover the viewer app bundle to update.
return LL_RUN_INSTALL_SCRIPT_IN_PLACE;
#endif
};
@@ -83,11 +93,13 @@ class LLUpdaterServiceImpl :
{
static const std::string sListenerName;
- std::string mProtocolVersion;
- std::string mUrl;
- std::string mPath;
- std::string mChannel;
- std::string mVersion;
+ std::string mProtocolVersion;
+ std::string mChannel;
+ std::string mVersion;
+ std::string mPlatform;
+ std::string mPlatformVersion;
+ unsigned char mUniqueId[MD5HEX_STR_SIZE];
+ bool mWillingToTest;
unsigned int mCheckPeriod;
bool mIsChecking;
@@ -107,11 +119,13 @@ public:
LLUpdaterServiceImpl();
virtual ~LLUpdaterServiceImpl();
- void initialize(const std::string& protocol_version,
- const std::string& url,
- const std::string& path,
- const std::string& channel,
- const std::string& version);
+ void initialize(const std::string& channel,
+ const std::string& version,
+ const std::string& platform,
+ const std::string& platform_version,
+ const unsigned char uniqueid[MD5HEX_STR_SIZE],
+ const bool& willing_to_test
+ );
void setCheckPeriod(unsigned int seconds);
void setBandwidthLimit(U64 bytesPerSecond);
@@ -129,13 +143,9 @@ public:
// LLUpdateChecker::Client:
virtual void error(std::string const & message);
- virtual void optionalUpdate(std::string const & newVersion,
- LLURI const & uri,
- std::string const & hash);
- virtual void requiredUpdate(std::string const & newVersion,
- LLURI const & uri,
- std::string const & hash);
- virtual void upToDate(void);
+
+ // A successful response was received from the viewer version manager
+ virtual void response(LLSD const & content);
// LLUpdateDownloader::Client
void downloadComplete(LLSD const & data);
@@ -144,6 +154,7 @@ public:
bool onMainLoop(LLSD const & event);
private:
+ std::string mNewChannel;
std::string mNewVersion;
void restartTimer(unsigned int seconds);
@@ -169,11 +180,12 @@ LLUpdaterServiceImpl::~LLUpdaterServiceImpl()
LLEventPumps::instance().obtain("mainloop").stopListening(sListenerName);
}
-void LLUpdaterServiceImpl::initialize(const std::string& protocol_version,
- const std::string& url,
- const std::string& path,
- const std::string& channel,
- const std::string& version)
+void LLUpdaterServiceImpl::initialize(const std::string& channel,
+ const std::string& version,
+ const std::string& platform,
+ const std::string& platform_version,
+ const unsigned char uniqueid[MD5HEX_STR_SIZE],
+ const bool& willing_to_test)
{
if(mIsChecking || mIsDownloading)
{
@@ -181,11 +193,18 @@ void LLUpdaterServiceImpl::initialize(const std::string& protocol_version,
"while updater is running.");
}
- mProtocolVersion = protocol_version;
- mUrl = url;
- mPath = path;
mChannel = channel;
mVersion = version;
+ mPlatform = platform;
+ mPlatformVersion = platform_version;
+ memcpy(mUniqueId, uniqueid, MD5HEX_STR_SIZE);
+ mWillingToTest = willing_to_test;
+ LL_DEBUGS("UpdaterService")
+ << "\n channel: " << mChannel
+ << "\n version: " << mVersion
+ << "\n uniqueid: " << mUniqueId
+ << "\n willing: " << ( mWillingToTest ? "testok" : "testno" )
+ << LL_ENDL;
}
void LLUpdaterServiceImpl::setCheckPeriod(unsigned int seconds)
@@ -200,7 +219,7 @@ void LLUpdaterServiceImpl::setBandwidthLimit(U64 bytesPerSecond)
void LLUpdaterServiceImpl::startChecking(bool install_if_ready)
{
- if(mUrl.empty() || mChannel.empty() || mVersion.empty())
+ if(mChannel.empty() || mVersion.empty())
{
throw LLUpdaterService::UsageError("Set params before call to "
"LLUpdaterService::startCheck().");
@@ -284,7 +303,7 @@ bool LLUpdaterServiceImpl::checkForInstall(bool launchInstaller)
// the update. Do not install this update.
if(!path.asString().empty())
{
- llinfos << "ignoring update dowloaded by different client version" << llendl;
+ LL_INFOS("UpdaterService") << "ignoring update dowloaded by different client version" << LL_ENDL;;
LLFile::remove(path.asString());
LLFile::remove(update_marker_path());
}
@@ -311,9 +330,13 @@ bool LLUpdaterServiceImpl::checkForInstall(bool launchInstaller)
if((result == 0) && mAppExitCallback)
{
mAppExitCallback();
- } else if(result != 0) {
- llwarns << "failed to run update install script" << LL_ENDL;
- } else {
+ }
+ else if(result != 0)
+ {
+ LL_WARNS("UpdaterService") << "failed to run update install script" << LL_ENDL;
+ }
+ else
+ {
; // No op.
}
}
@@ -341,15 +364,19 @@ bool LLUpdaterServiceImpl::checkForResume()
{
mIsDownloading = true;
mNewVersion = download_info["update_version"].asString();
+ mNewChannel = download_info["update_channel"].asString();
mUpdateDownloader.resume();
result = true;
}
else
{
// The viewer that started this download is not the same as this viewer; ignore.
- llinfos << "ignoring partial download from different viewer version" << llendl;
+ LL_INFOS("UpdaterService") << "ignoring partial download from different viewer version" << LL_ENDL;;
std::string path = download_info["path"].asString();
- if(!path.empty()) LLFile::remove(path);
+ if(!path.empty())
+ {
+ LLFile::remove(path);
+ }
LLFile::remove(download_marker_path);
}
}
@@ -366,36 +393,49 @@ void LLUpdaterServiceImpl::error(std::string const & message)
}
}
-void LLUpdaterServiceImpl::optionalUpdate(std::string const & newVersion,
- LLURI const & uri,
- std::string const & hash)
+// A successful response was received from the viewer version manager
+void LLUpdaterServiceImpl::response(LLSD const & content)
{
- stopTimer();
- mNewVersion = newVersion;
- mIsDownloading = true;
- setState(LLUpdaterService::DOWNLOADING);
- mUpdateDownloader.download(uri, hash, newVersion, false);
-}
-
-void LLUpdaterServiceImpl::requiredUpdate(std::string const & newVersion,
- LLURI const & uri,
- std::string const & hash)
-{
- stopTimer();
- mNewVersion = newVersion;
- mIsDownloading = true;
- setState(LLUpdaterService::DOWNLOADING);
- mUpdateDownloader.download(uri, hash, newVersion, true);
-}
-
-void LLUpdaterServiceImpl::upToDate(void)
-{
- if(mIsChecking)
+ if(!content.asBoolean()) // an empty response means "no update"
+ {
+ LL_INFOS("UpdaterService") << "up to date" << LL_ENDL;
+ if(mIsChecking)
+ {
+ restartTimer(mCheckPeriod);
+ }
+
+ setState(LLUpdaterService::UP_TO_DATE);
+ }
+ else if ( content.isMap() && content.has("url") )
+ {
+ // there is an update available...
+ stopTimer();
+ mNewChannel = content["channel"].asString();
+ if (mNewChannel.empty())
+ {
+ LL_INFOS("UpdaterService") << "no channel supplied, assuming current channel" << LL_ENDL;
+ mNewChannel = mChannel;
+ }
+ mNewVersion = content["version"].asString();
+ mIsDownloading = true;
+ setState(LLUpdaterService::DOWNLOADING);
+ BOOL required = content["required"].asBoolean();
+ LLURI url(content["url"].asString());
+ std::string more_info = content["more_info"].asString();
+ LL_DEBUGS("UpdaterService")
+ << "Starting download of "
+ << ( required ? "required" : "optional" ) << " update"
+ << " to channel '" << mNewChannel << "' version " << mNewVersion
+ << " more info '" << more_info << "'"
+ << LL_ENDL;
+ mUpdateDownloader.download(url, content["hash"].asString(), mNewChannel, mNewVersion, more_info, required);
+ }
+ else
{
+ LL_WARNS("UpdaterService") << "Invalid update query response ignored; retry in "
+ << mCheckPeriod << " seconds" << LL_ENDL;
restartTimer(mCheckPeriod);
}
-
- setState(LLUpdaterService::UP_TO_DATE);
}
void LLUpdaterServiceImpl::downloadComplete(LLSD const & data)
@@ -413,9 +453,19 @@ void LLUpdaterServiceImpl::downloadComplete(LLSD const & data)
payload["type"] = LLSD(LLUpdaterService::DOWNLOAD_COMPLETE);
payload["required"] = data["required"];
payload["version"] = mNewVersion;
+ payload["channel"] = mNewChannel;
+ payload["info_url"] = data["info_url"];
event["payload"] = payload;
+ LL_DEBUGS("UpdaterService")
+ << "Download complete "
+ << ( data["required"].asBoolean() ? "required" : "optional" )
+ << " channel " << mNewChannel
+ << " version " << mNewVersion
+ << " info " << data["info_url"].asString()
+ << LL_ENDL;
+
LLEventPumps::instance().obtain("mainlooprepeater").post(event);
-
+
setState(LLUpdaterService::TERMINAL);
}
@@ -489,15 +539,18 @@ bool LLUpdaterServiceImpl::onMainLoop(LLSD const & event)
// Check for failed install.
if(LLFile::isfile(ll_install_failed_marker_path()))
{
+ LL_DEBUGS("UpdaterService") << "found marker " << ll_install_failed_marker_path() << LL_ENDL;;
int requiredValue = 0;
{
llifstream stream(ll_install_failed_marker_path());
stream >> requiredValue;
- if(stream.fail()) requiredValue = 0;
+ if(stream.fail())
+ {
+ requiredValue = 0;
+ }
}
// TODO: notify the user.
- llinfos << "found marker " << ll_install_failed_marker_path() << llendl;
- llinfos << "last install attempt failed" << llendl;
+ LL_WARNS("UpdaterService") << "last install attempt failed" << LL_ENDL;;
LLFile::remove(ll_install_failed_marker_path());
LLSD event;
@@ -509,8 +562,26 @@ bool LLUpdaterServiceImpl::onMainLoop(LLSD const & event)
}
else
{
- mUpdateChecker.check(mProtocolVersion, mUrl, mPath, mChannel, mVersion);
- setState(LLUpdaterService::CHECKING_FOR_UPDATE);
+ std::string query_url = LLGridManager::getInstance()->getUpdateServiceURL();
+ if ( !query_url.empty() )
+ {
+ mUpdateChecker.checkVersion(query_url, mChannel, mVersion,
+ mPlatform, mPlatformVersion, mUniqueId,
+ mWillingToTest);
+ setState(LLUpdaterService::CHECKING_FOR_UPDATE);
+ }
+ else
+ {
+ LL_WARNS("UpdaterService")
+ << "No updater service defined for grid '" << LLGridManager::getInstance()->getGrid()
+ << "' will check again in " << mCheckPeriod << " seconds"
+ << LL_ENDL;
+ // Because the grid can be changed after the viewer is started (when the first check takes place)
+ // but before the user logs in, the next check may be on a different grid, so set the retry timer
+ // even though this check did not happen. The default time is once an hour, and if we're not
+ // doing the check anyway the performance impact is completely insignificant.
+ restartTimer(mCheckPeriod);
+ }
}
}
else
@@ -554,13 +625,15 @@ LLUpdaterService::~LLUpdaterService()
{
}
-void LLUpdaterService::initialize(const std::string& protocol_version,
- const std::string& url,
- const std::string& path,
- const std::string& channel,
- const std::string& version)
+void LLUpdaterService::initialize(const std::string& channel,
+ const std::string& version,
+ const std::string& platform,
+ const std::string& platform_version,
+ const unsigned char uniqueid[MD5HEX_STR_SIZE],
+ const bool& willing_to_test
+)
{
- mImpl->initialize(protocol_version, url, path, channel, version);
+ mImpl->initialize(channel, version, platform, platform_version, uniqueid, willing_to_test);
}
void LLUpdaterService::setCheckPeriod(unsigned int seconds)
@@ -609,10 +682,10 @@ std::string const & ll_get_version(void) {
if (version.empty()) {
std::ostringstream stream;
- stream << LL_VERSION_MAJOR << "."
- << LL_VERSION_MINOR << "."
- << LL_VERSION_PATCH << "."
- << LL_VERSION_BUILD;
+ stream << LL_VIEWER_VERSION_MAJOR << "."
+ << LL_VIEWER_VERSION_MINOR << "."
+ << LL_VIEWER_VERSION_PATCH << "."
+ << LL_VIEWER_VERSION_BUILD;
version = stream.str();
}
diff --git a/indra/viewer_components/updater/llupdaterservice.h b/indra/viewer_components/updater/llupdaterservice.h
index 450f19c1c6..0ddf24935b 100644..100755
--- a/indra/viewer_components/updater/llupdaterservice.h
+++ b/indra/viewer_components/updater/llupdaterservice.h
@@ -28,6 +28,7 @@
#include <boost/shared_ptr.hpp>
#include <boost/function.hpp>
+#include "llhasheduniqueid.h"
class LLUpdaterServiceImpl;
@@ -70,11 +71,13 @@ public:
LLUpdaterService();
~LLUpdaterService();
- void initialize(const std::string& protocol_version,
- const std::string& url,
- const std::string& path,
- const std::string& channel,
- const std::string& version);
+ void initialize(const std::string& channel,
+ const std::string& version,
+ const std::string& platform,
+ const std::string& platform_version,
+ const unsigned char uniqueid[MD5HEX_STR_SIZE],
+ const bool& willing_to_test
+ );
void setCheckPeriod(unsigned int seconds);
void setBandwidthLimit(U64 bytesPerSecond);
diff --git a/indra/viewer_components/updater/scripts/darwin/janitor.py b/indra/viewer_components/updater/scripts/darwin/janitor.py
new file mode 100644
index 0000000000..cdf33df731
--- /dev/null
+++ b/indra/viewer_components/updater/scripts/darwin/janitor.py
@@ -0,0 +1,133 @@
+#!/usr/bin/python
+"""\
+@file janitor.py
+@author Nat Goodspeed
+@date 2011-09-14
+@brief Janitor class to clean up arbitrary resources
+
+2013-01-04 cloned from vita because it's exactly what update_install.py needs.
+
+$LicenseInfo:firstyear=2011&license=viewerlgpl$
+Copyright (c) 2011, Linden Research, Inc.
+$/LicenseInfo$
+"""
+
+import sys
+import functools
+import itertools
+
+class Janitor(object):
+ """
+ Usage:
+
+ Basic:
+ self.janitor = Janitor(sys.stdout) # report cleanup actions on stdout
+ ...
+ self.janitor.later(os.remove, some_temp_file)
+ self.janitor.later(os.remove, some_other_file)
+ ...
+ self.janitor.cleanup() # perform cleanup actions
+
+ Context Manager:
+ with Janitor() as janitor: # clean up quietly
+ ...
+ janitor.later(shutil.rmtree, some_temp_directory)
+ ...
+ # exiting 'with' block performs cleanup
+
+ Test Class:
+ class TestMySoftware(unittest.TestCase, Janitor):
+ def __init__(self):
+ Janitor.__init__(self) # quiet cleanup
+ ...
+
+ def setUp(self):
+ ...
+ self.later(os.rename, saved_file, original_location)
+ ...
+
+ def tearDown(self):
+ Janitor.tearDown(self) # calls cleanup()
+ ...
+ # Or, if you have no other tearDown() logic for
+ # TestMySoftware, you can omit the TestMySoftware.tearDown()
+ # def entirely and let it inherit Janitor.tearDown().
+ """
+ def __init__(self, stream=None):
+ """
+ If you pass stream= (e.g.) sys.stdout or sys.stderr, Janitor will
+ report its cleanup operations as it performs them. If you don't, it
+ will perform them quietly -- unless one or more of the actions throws
+ an exception, in which case you'll get output on stderr.
+ """
+ self.stream = stream
+ self.cleanups = []
+
+ def later(self, func, *args, **kwds):
+ """
+ Pass the callable you want to call at cleanup() time, plus any
+ positional or keyword args you want to pass it.
+ """
+ # Get a name string for 'func'
+ try:
+ # A free function has a __name__
+ name = func.__name__
+ except AttributeError:
+ try:
+ # A class object (even builtin objects like ints!) support
+ # __class__.__name__
+ name = func.__class__.__name__
+ except AttributeError:
+ # Shrug! Just use repr() to get a string describing this func.
+ name = repr(func)
+ # Construct a description of this operation in Python syntax from
+ # args, kwds.
+ desc = "%s(%s)" % \
+ (name, ", ".join(itertools.chain((repr(a) for a in args),
+ ("%s=%r" % (k, v) for (k, v) in kwds.iteritems()))))
+ # Use functools.partial() to bind passed args and keywords to the
+ # passed func so we get a nullary callable that does what caller
+ # wants.
+ bound = functools.partial(func, *args, **kwds)
+ self.cleanups.append((desc, bound))
+
+ def cleanup(self):
+ """
+ Perform all the actions saved with later() calls.
+ """
+ # Typically one allocates resource A, then allocates resource B that
+ # depends on it. In such a scenario it's appropriate to delete B
+ # before A -- so perform cleanup actions in reverse order. (This is
+ # the same strategy used by atexit().)
+ while self.cleanups:
+ # Until our list is empty, pop the last pair.
+ desc, bound = self.cleanups.pop(-1)
+
+ # If requested, report the action.
+ if self.stream is not None:
+ print >>self.stream, desc
+
+ try:
+ # Call the bound callable
+ bound()
+ except Exception, err:
+ # This is cleanup. Report the problem but continue.
+ print >>(self.stream or sys.stderr), "Calling %s\nraised %s: %s" % \
+ (desc, err.__class__.__name__, err)
+
+ def tearDown(self):
+ """
+ If a unittest.TestCase subclass (or a nose test class) adds Janitor as
+ one of its base classes, and has no other tearDown() logic, let it
+ inherit Janitor.tearDown().
+ """
+ self.cleanup()
+
+ def __enter__(self):
+ return self
+
+ def __exit__(self, type, value, tb):
+ # Perform cleanup no matter how we exit this 'with' statement
+ self.cleanup()
+ # Propagate any exception from the 'with' statement, don't swallow it
+ return False
diff --git a/indra/viewer_components/updater/scripts/darwin/messageframe.py b/indra/viewer_components/updater/scripts/darwin/messageframe.py
new file mode 100644
index 0000000000..8f58848882
--- /dev/null
+++ b/indra/viewer_components/updater/scripts/darwin/messageframe.py
@@ -0,0 +1,66 @@
+#!/usr/bin/python
+"""\
+@file messageframe.py
+@author Nat Goodspeed
+@date 2013-01-03
+@brief Define MessageFrame class for popping up messages from a command-line
+ script.
+
+$LicenseInfo:firstyear=2013&license=viewerlgpl$
+Copyright (c) 2013, Linden Research, Inc.
+$/LicenseInfo$
+"""
+
+import Tkinter as tk
+import os
+
+# Tricky way to obtain the filename of the main script (default title string)
+import __main__
+
+# This class is intended for displaying messages from a command-line script.
+# Getting the base class right took a bit of trial and error.
+# If you derive from tk.Frame, the destroy() method doesn't actually close it.
+# If you derive from tk.Toplevel, it pops up a separate Tk frame too. destroy()
+# closes this frame, but not that one.
+# Deriving from tk.Tk appears to do the right thing.
+class MessageFrame(tk.Tk):
+ def __init__(self, text="", title=os.path.splitext(os.path.basename(__main__.__file__))[0],
+ width=320, height=120):
+ tk.Tk.__init__(self)
+ self.grid()
+ self.title(title)
+ self.var = tk.StringVar()
+ self.var.set(text)
+ self.msg = tk.Label(self, textvariable=self.var)
+ self.msg.grid()
+ # from http://stackoverflow.com/questions/3352918/how-to-center-a-window-on-the-screen-in-tkinter :
+ self.update_idletasks()
+
+ # The constants below are to adjust for typical overhead from the
+ # frame borders.
+ xp = (self.winfo_screenwidth() / 2) - (width / 2) - 8
+ yp = (self.winfo_screenheight() / 2) - (height / 2) - 20
+ self.geometry('{0}x{1}+{2}+{3}'.format(width, height, xp, yp))
+ self.update()
+
+ def set(self, text):
+ self.var.set(text)
+ self.update()
+
+if __name__ == "__main__":
+ # When run as a script, just test the MessageFrame.
+ import sys
+ import time
+
+ frame = MessageFrame("something in the way she moves....")
+ time.sleep(3)
+ frame.set("smaller")
+ time.sleep(3)
+ frame.set("""this has
+several
+lines""")
+ time.sleep(3)
+ frame.destroy()
+ print "Destroyed!"
+ sys.stdout.flush()
+ time.sleep(3)
diff --git a/indra/viewer_components/updater/scripts/darwin/update_install b/indra/viewer_components/updater/scripts/darwin/update_install
deleted file mode 100644
index e7f36dc5a3..0000000000
--- a/indra/viewer_components/updater/scripts/darwin/update_install
+++ /dev/null
@@ -1,10 +0,0 @@
-#! /bin/bash
-
-#
-# The first argument contains the path to the installer app. The second a path
-# to a marker file which should be created if the installer fails.q
-#
-
-cd "$(dirname "$0")"
-(../Resources/mac-updater.app/Contents/MacOS/mac-updater -dmg "$1" -name "Second Life Viewer"; if [ $? -ne 0 ]; then echo $3 >> "$2"; fi;) &
-exit 0
diff --git a/indra/viewer_components/updater/scripts/darwin/update_install.py b/indra/viewer_components/updater/scripts/darwin/update_install.py
new file mode 100755
index 0000000000..10d507c9ef
--- /dev/null
+++ b/indra/viewer_components/updater/scripts/darwin/update_install.py
@@ -0,0 +1,400 @@
+#!/usr/bin/python
+"""\
+@file update_install.py
+@author Nat Goodspeed
+@date 2012-12-20
+@brief Update the containing Second Life application bundle to the version in
+ the specified disk image file.
+
+ This Python implementation is derived from the previous mac-updater
+ application, a funky mix of C++, classic C and Objective-C.
+
+$LicenseInfo:firstyear=2012&license=viewerlgpl$
+Copyright (c) 2012, Linden Research, Inc.
+$/LicenseInfo$
+"""
+
+import os
+import sys
+import cgitb
+from contextlib import contextmanager
+import errno
+import glob
+import plistlib
+import re
+import shutil
+import subprocess
+import tempfile
+import time
+from janitor import Janitor
+from messageframe import MessageFrame
+import Tkinter, tkMessageBox
+
+TITLE = "Second Life Viewer Updater"
+# Magic bundle identifier used by all Second Life viewer bundles
+BUNDLE_IDENTIFIER = "com.secondlife.indra.viewer"
+# Magic OS directory name that causes Cocoa viewer to crash on OS X 10.7.5
+# (see MAINT-3331)
+STATE_DIR = os.path.join(
+ os.environ["HOME"], "Library", "Saved Application State",
+ BUNDLE_IDENTIFIER + ".savedState")
+
+# Global handle to the MessageFrame so we can update message
+FRAME = None
+# Global handle to logfile, once it's open
+LOGF = None
+
+# ****************************************************************************
+# Logging and messaging
+#
+# This script is normally run implicitly by the old viewer to update to the
+# new viewer. Its UI consists of a MessageFrame and possibly a Tk error box.
+# Log details to updater.log -- especially uncaught exceptions!
+# ****************************************************************************
+def log(message):
+ """write message only to LOGF (also called by status() and fail())"""
+ # If we don't even have LOGF open yet, at least write to Console log
+ logf = LOGF or sys.stderr
+ logf.writelines((time.strftime("%Y-%m-%dT%H:%M:%SZ ", time.gmtime()), message, '\n'))
+ logf.flush()
+
+def status(message):
+ """display and log normal progress message"""
+ log(message)
+
+ global FRAME
+ if not FRAME:
+ FRAME = MessageFrame(message, TITLE)
+ else:
+ FRAME.set(message)
+
+def fail(message):
+ """log message, produce error box, then terminate with nonzero rc"""
+ log(message)
+
+ # If we haven't yet called status() (we don't yet have a FRAME), perform a
+ # bit of trickery to bypass the spurious "main window" that Tkinter would
+ # otherwise pop up if the first call is showerror().
+ if not FRAME:
+ root = Tkinter.Tk()
+ root.withdraw()
+
+ # If we do have a LOGF available, mention it in the error box.
+ if LOGF:
+ message = "%s\n(Updater log in %s)" % (message, LOGF.name)
+
+ # We explicitly specify the WARNING icon because, at least on the Tkinter
+ # bundled with the system-default Python 2.7 on Mac OS X 10.7.4, the
+ # ERROR, QUESTION and INFO icons are all the silly Tk rocket ship. At
+ # least WARNING has an exclamation in a yellow triangle, even though
+ # overlaid by a smaller image of the rocket ship.
+ tkMessageBox.showerror(TITLE,
+"""An error occurred while updating Second Life:
+%s
+Please download the latest viewer from www.secondlife.com.""" % message,
+ icon=tkMessageBox.WARNING)
+ sys.exit(1)
+
+def exception(err):
+ """call fail() with an exception instance"""
+ fail("%s exception: %s" % (err.__class__.__name__, str(err)))
+
+def excepthook(type, value, traceback):
+ """
+ Store this hook function into sys.excepthook until we have a logfile.
+ """
+ # At least in older Python versions, it could be tricky to produce a
+ # string from 'type' and 'value'. For instance, an OSError exception would
+ # pass type=OSError and value=some_tuple. Empirically, this funky
+ # expression seems to work.
+ exception(type(*value))
+sys.excepthook = excepthook
+
+class ExceptHook(object):
+ """
+ Store an instance of this class into sys.excepthook once we have a logfile
+ open.
+ """
+ def __init__(self, logfile):
+ # There's no magic to the cgitb.enable() function -- it merely stores
+ # an instance of cgitb.Hook into sys.excepthook, passing enable()'s
+ # params into Hook.__init__(). Sadly, enable() doesn't forward all its
+ # params using (*args, **kwds) syntax -- another story. But the point
+ # is that all the goodness is in the cgitb.Hook class. Capture an
+ # instance.
+ self.hook = cgitb.Hook(file=logfile, format="text")
+
+ def __call__(self, type, value, traceback):
+ # produce nice text traceback to logfile
+ self.hook(type, value, traceback)
+ # Now display an error box.
+ excepthook(type, value, traceback)
+
+def write_marker(markerfile, markertext):
+ log("writing %r to %s" % (markertext, markerfile))
+ try:
+ with open(markerfile, "w") as markerf:
+ markerf.write(markertext)
+ except IOError, err:
+ # write_marker() is invoked by fail(), and fail() is invoked by other
+ # error-handling functions. If we try to invoke any of those, we'll
+ # get infinite recursion. If for any reason we can't write markerfile,
+ # try to log it -- otherwise shrug.
+ log("%s exception: %s" % (err.__class__.__name__, err))
+
+# ****************************************************************************
+# Utility
+# ****************************************************************************
+@contextmanager
+def allow_errno(errn):
+ """
+ Execute body of 'with' statement, accepting OSError with specific errno
+ 'errn'. Propagate any other exception, or an OSError with any other errno.
+ """
+ try:
+ # run the body of the 'with' statement
+ yield
+ except OSError, err:
+ # unless errno == passed errn, re-raise the exception
+ if err.errno != errn:
+ raise
+
+# ****************************************************************************
+# Main script logic
+# ****************************************************************************
+def main(dmgfile, markerfile, markertext):
+ # Should we fail, we're supposed to write 'markertext' to 'markerfile'.
+ # Wrap the fail() function so we do that.
+ global fail
+ oldfail = fail
+ def fail(message):
+ write_marker(markerfile, markertext)
+ oldfail(message)
+
+ try:
+ # Starting with the Cocoafied viewer, we'll find viewer logs in
+ # ~/Library/Application Support/$CFBundleIdentifier/logs rather than in
+ # ~/Library/Application Support/SecondLife/logs as before. This could be
+ # obnoxious -- but we Happen To Know that markerfile is a path specified
+ # within the viewer's logs directory. Use that.
+ logsdir = os.path.dirname(markerfile)
+
+ # Move the old updater.log file out of the way
+ logname = os.path.join(logsdir, "updater.log")
+ # Nonexistence is okay. Anything else, not so much.
+ with allow_errno(errno.ENOENT):
+ os.rename(logname, logname + ".old")
+
+ # Open new updater.log.
+ global LOGF
+ LOGF = open(logname, "w")
+
+ # Now that LOGF is in fact open for business, use it to log any further
+ # uncaught exceptions.
+ sys.excepthook = ExceptHook(LOGF)
+
+ # log how this script was invoked
+ log(' '.join(repr(arg) for arg in sys.argv))
+
+ # prepare for other cleanup
+ with Janitor(LOGF) as janitor:
+
+ # Try to derive the name of the running viewer app bundle from our
+ # own pathname. (Hopefully the old viewer won't copy this script
+ # to a temp dir before running!)
+ # Somewhat peculiarly, this script is currently packaged in
+ # Appname.app/Contents/MacOS with the viewer executable. But even
+ # if we decide to move it to Appname.app/Contents/Resources, we'll
+ # still find Appname.app two levels up from dirname(__file__).
+ appdir = os.path.abspath(os.path.join(os.path.dirname(__file__),
+ os.pardir, os.pardir))
+ if not appdir.endswith(".app"):
+ # This can happen if either this script has been copied before
+ # being executed, or if it's in an unexpected place in the app
+ # bundle.
+ fail(appdir + " is not an application directory")
+
+ # We need to install into appdir's parent directory -- can we?
+ installdir = os.path.abspath(os.path.join(appdir, os.pardir))
+ if not os.access(installdir, os.W_OK):
+ fail("Can't modify " + installdir)
+
+ # invent a temporary directory
+ tempdir = tempfile.mkdtemp()
+ log("created " + tempdir)
+ # clean it up when we leave
+ janitor.later(shutil.rmtree, tempdir)
+
+ status("Mounting image...")
+
+ mntdir = os.path.join(tempdir, "mnt")
+ log("mkdir " + mntdir)
+ os.mkdir(mntdir)
+ command = ["hdiutil", "attach", dmgfile, "-mountpoint", mntdir]
+ log(' '.join(command))
+ # Instantiating subprocess.Popen launches a child process with the
+ # specified command line. stdout=PIPE passes a pipe to its stdout.
+ hdiutil = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=LOGF)
+ # Popen.communicate() reads that pipe until the child process
+ # terminates, returning (stdout, stderr) output. Select just stdout.
+ hdiutil_out = hdiutil.communicate()[0]
+ if hdiutil.returncode != 0:
+ fail("Couldn't mount " + dmgfile)
+ # hdiutil should report the devnode. Find that.
+ found = re.search(r"/dev/[^ ]*\b", hdiutil_out)
+ if not found:
+ # If we don't spot the devnode, log it and continue -- we only
+ # use it to detach it. Don't fail the whole update if we can't
+ # clean up properly.
+ log("Couldn't spot devnode in hdiutil output:\n" + hdiutil_out)
+ else:
+ # If we do spot the devnode, detach it when done.
+ janitor.later(subprocess.call, ["hdiutil", "detach", found.group(0)],
+ stdout=LOGF, stderr=subprocess.STDOUT)
+
+ status("Searching for app bundle...")
+
+ for candidate in glob.glob(os.path.join(mntdir, "*.app")):
+ log("Considering " + candidate)
+ try:
+ # By convention, a valid Mac app bundle has a
+ # Contents/Info.plist file containing at least
+ # CFBundleIdentifier.
+ CFBundleIdentifier = \
+ plistlib.readPlist(os.path.join(candidate, "Contents",
+ "Info.plist"))["CFBundleIdentifier"]
+ except Exception, err:
+ # might be IOError, xml.parsers.expat.ExpatError, KeyError
+ # Any of these means it's not a valid app bundle. Instead
+ # of aborting, just skip this candidate and continue.
+ log("%s not a valid app bundle: %s: %s" %
+ (candidate, err.__class__.__name__, err))
+ continue
+
+ if CFBundleIdentifier == BUNDLE_IDENTIFIER:
+ break
+
+ log("unrecognized CFBundleIdentifier: " + CFBundleIdentifier)
+
+ else:
+ fail("Could not find Second Life viewer in " + dmgfile)
+
+ # Here 'candidate' is the new viewer to install
+ log("Found " + candidate)
+
+ # This logic was changed to make Mac updates behave more like
+ # Windows. Most of the time, the user doesn't change the name of
+ # the app bundle on our .dmg installer (e.g. "Second Life Beta
+ # Viewer.app"). Most of the time, the version manager directs a
+ # given viewer to update to another .dmg containing an app bundle
+ # with THE SAME name. In that case, everything behaves as usual.
+
+ # The case that was changed is when the version manager offers (or
+ # mandates) an update to a .dmg containing a different app bundle
+ # name. This can happen, for instance, to a user who's downloaded
+ # a "project beta" viewer, and the project subsequently publishes
+ # a Release Candidate viewer. Say the project beta's app bundle
+ # name is something like "Second Life Beta Neato.app". Anyone
+ # launching that viewer will be offered an update to the
+ # corresponding Release Candidate viewer -- which will be built as
+ # a release viewer, with app bundle name "Second Life Viewer.app".
+
+ # On Windows, we run the NSIS installer, which will update/replace
+ # the embedded install directory name, e.g. Second Life Viewer.
+ # But the Mac installer used to locate the app bundle name in the
+ # mounted .dmg file, then ignore that name, copying its contents
+ # into the app bundle directory of the running viewer. That is,
+ # we'd install the Release Candidate from the .dmg's "Second
+ # Life.app" into "/Applications/Second Life Beta Neato.app". This
+ # is undesired behavior.
+
+ # Instead, having found the app bundle name on the mounted .dmg,
+ # we try to install that app bundle name into the parent directory
+ # of the running app bundle.
+
+ # Are we installing a different app bundle name? If so, call it
+ # out, both in the log and for the user -- this is an odd case.
+ # (Presumably they've already agreed to a similar notification in
+ # the viewer before the viewer launched this script, but still.)
+ bundlename = os.path.basename(candidate)
+ if os.path.basename(appdir) == bundlename:
+ # updating the running app bundle, which we KNOW exists
+ appexists = True
+ else:
+ # installing some other app bundle
+ newapp = os.path.join(installdir, bundlename)
+ appexists = os.path.exists(newapp)
+ message = "Note: %s %s %s" % \
+ (appdir, "updating" if appexists else "installing new", newapp)
+ status(message)
+ # okay, we have no further need of the name of the running app
+ # bundle.
+ appdir = newapp
+
+ status("Preparing to copy files...")
+
+ if appexists:
+ # move old viewer to temp location in case copy from .dmg fails
+ aside = os.path.join(tempdir, os.path.basename(appdir))
+ log("mv %r %r" % (appdir, aside))
+ # Use shutil.move() instead of os.rename(). move() first tries
+ # os.rename(), but falls back to shutil.copytree() if the dest is
+ # on a different filesystem.
+ shutil.move(appdir, aside)
+
+ status("Copying files...")
+
+ # shutil.copytree()'s target must not already exist. But we just
+ # moved appdir out of the way.
+ log("cp -p %r %r" % (candidate, appdir))
+ try:
+ # The viewer app bundle does include internal symlinks. Keep them
+ # as symlinks.
+ shutil.copytree(candidate, appdir, symlinks=True)
+ except Exception, err:
+ # copy failed -- try to restore previous viewer before crumping
+ type, value, traceback = sys.exc_info()
+ if appexists:
+ log("exception response: mv %r %r" % (aside, appdir))
+ shutil.move(aside, appdir)
+ # let our previously-set sys.excepthook handle this
+ raise type, value, traceback
+
+ status("Cleaning up...")
+
+ log("touch " + appdir)
+ os.utime(appdir, None) # set to current time
+
+ # MAINT-3331: remove STATE_DIR. Empirically, this resolves a
+ # persistent, mysterious crash after updating our viewer on an OS
+ # X 10.7.5 system.
+ log("rm -rf '%s'" % STATE_DIR)
+ with allow_errno(errno.ENOENT):
+ shutil.rmtree(STATE_DIR)
+
+ command = ["open", appdir]
+ log(' '.join(command))
+ subprocess.check_call(command, stdout=LOGF, stderr=subprocess.STDOUT)
+
+ except Exception, err:
+ # Because we carefully set sys.excepthook -- and even modify it to log
+ # the problem once we have our log file open -- you might think we
+ # could just let exceptions propagate. But when we do that, on
+ # exception in this block, we FIRST restore the no-side-effects fail()
+ # and THEN implicitly call sys.excepthook(), which calls the (no-side-
+ # effects) fail(). Explicitly call sys.excepthook() BEFORE restoring
+ # fail(). Only then do we get the enriched fail() behavior.
+ sys.excepthook(*sys.exc_info())
+
+ finally:
+ # When we leave main() -- for whatever reason -- reset fail() the way
+ # it was before, because the bound markerfile, markertext params
+ # passed to this main() call are no longer applicable.
+ fail = oldfail
+
+if __name__ == "__main__":
+ # We expect this script to be invoked with:
+ # - the pathname to the .dmg we intend to install;
+ # - the pathname to an update-error marker file to create on failure;
+ # - the content to write into the marker file.
+ main(*sys.argv[1:])
diff --git a/indra/viewer_components/updater/scripts/linux/update_install b/indra/viewer_components/updater/scripts/linux/update_install
index e0505a9f72..03089f192e 100644..100755
--- a/indra/viewer_components/updater/scripts/linux/update_install
+++ b/indra/viewer_components/updater/scripts/linux/update_install
@@ -1,10 +1,220 @@
#! /bin/bash
-INSTALL_DIR=$(cd "$(dirname "$0")/.." ; pwd)
-export LD_LIBRARY_PATH="$INSTALL_DIR/lib"
-bin/linux-updater.bin --file "$1" --dest "$INSTALL_DIR" --name "Second Life Viewer" --stringsdir "$INSTALL_DIR/skins/default/xui/en" --stringsfile "strings.xml"
-if [ $? -ne 0 ]
- then echo $3 >> "$2"
+# @file update_install
+# @author Nat Goodspeed
+# @date 2013-01-09
+# @brief Update the containing Second Life application bundle to the version in
+# the specified tarball.
+#
+# This bash implementation is derived from the previous linux-updater.bin
+# application.
+#
+# $LicenseInfo:firstyear=2013&license=viewerlgpl$
+# Copyright (c) 2013, Linden Research, Inc.
+# $/LicenseInfo$
+
+# ****************************************************************************
+# script parameters
+# ****************************************************************************
+tarball="$1" # the file to install
+markerfile="$2" # create this file on failure
+mandatory="$3" # what to write to markerfile on failure
+
+# ****************************************************************************
+# helper functions
+# ****************************************************************************
+# empty array
+cleanups=()
+
+# add a cleanup action to execute on exit
+function cleanup {
+ # wacky bash syntax for appending to array
+ cleanups[${#cleanups[*]}]="$*"
+}
+
+# called implicitly on exit
+function onexit {
+ for action in "${cleanups[@]}"
+ do # don't quote, support actions consisting of multiple words
+ $action
+ done
+}
+trap 'onexit' EXIT
+
+# write to log file
+function log {
+ # our log file will be open as stderr -- but until we set up that
+ # redirection, logging to stderr is better than nothing
+ echo "$*" 1>&2
+}
+
+# We display status by leaving one background xmessage process running. This
+# is the pid of that process.
+statuspid=""
+
+function clear_message {
+ [ -n "$statuspid" ] && kill $statuspid
+ statuspid=""
+}
+
+# make sure we remove any message box we might have put up
+cleanup clear_message
+
+# can we use zenity, or must we fall back to xmessage?
+zenpath="$(which zenity)"
+if [ -n "$zenpath" ]
+then # zenity on PATH and is executable
+ # display a message box and continue
+ function status {
+ # clear any previous message
+ clear_message
+ # put up a new zenity box and capture its pid
+## "$zenpath" --info --title "Second Life Viewer Updater" \
+## --width=320 --height=120 --text="$*" &
+ # MAINT-2333: use bouncing progress bar
+ "$zenpath" --progress --pulsate --no-cancel --title "Second Life Viewer Updater" \
+ --width=320 --height=120 --text "$*" </dev/null &
+ statuspid=$!
+ }
+
+ # display an error box and wait for user
+ function errorbox {
+ "$zenpath" --error --title "Second Life Viewer Updater" \
+ --width=320 --height=120 --text="$*"
+ }
+
+else # no zenity, use xmessage instead
+ # display a message box and continue
+ function status {
+ # clear any previous message
+ clear_message
+ # put up a new xmessage and capture its pid
+ xmessage -buttons OK:2 -center "$*" &
+ statuspid=$!
+ }
+
+ # display an error box and wait for user
+ function errorbox {
+ xmessage -buttons OK:2 -center "$*"
+ }
+fi
+
+# display an error box and terminate
+function fail {
+ # Log the message
+ log "$@"
+ # tell subsequent viewer things went south
+ echo "$mandatory" > "$markerfile"
+ # add boilerplate
+ errorbox "An error occurred while updating Second Life:
+$*
+Please download the latest viewer from www.secondlife.com."
+ exit 1
+}
+
+# Find a graphical sudo program and define mysudo function. On error, $? is
+# nonzero; output is in $err instead of being written to stdout/stderr.
+gksudo="$(which gksudo)"
+kdesu="$(which kdesu)"
+if [ -n "$gksudo" ]
+then function mysudo {
+ # gksudo allows you to specify description
+ err="$("$gksudo" --description "Second Life Viewer Updater" "$@" 2>&1)"
+ }
+elif [ -n "$kdesu" ]
+then function mysudo {
+ err="$("$kdesu" "$@" 2>&1)"
+ }
+else # couldn't find either one, just try it anyway
+ function mysudo {
+ err="$("$@" 2>&1)"
+ }
fi
-rm -f "$1"
+# Move directories, using mysudo if we think it necessary. On error, $? is
+# nonzero; output is in $err instead of being written to stdout/stderr.
+function sudo_mv {
+ # If we have write permission to both parent directories, shouldn't need
+ # sudo.
+ if [ -w "$(dirname "$1")" -a -w "$(dirname "$2")" ]
+ then err="$(mv "$@" 2>&1)"
+ else # use available sudo program; mysudo sets $? and $err
+ mysudo mv "$@"
+ fi
+}
+
+# ****************************************************************************
+# main script logic
+# ****************************************************************************
+mydir="$(dirname "$0")"
+# We happen to know that the viewer specifies a marker-file pathname within
+# the logs directory.
+logsdir="$(dirname "$markerfile")"
+logname="$logsdir/updater.log"
+
+# move aside old updater.log; we're about to create a new one
+[ -f "$logname" ] && mv "$logname" "$logname.old"
+
+# Set up redirections for this script such that stderr is logged. (But first
+# move the previous stderr to file descriptor 3.)
+exec 3>&2- 2> "$logname"
+
+# Rather than setting up a special pipeline to timestamp every line of stderr,
+# produce header lines into log file indicating timestamp and the arguments
+# with which we were invoked.
+date 1>&2
+log "$0 $*"
+
+# Log every command we execute, along with any stderr it might produce
+set -x
+
+status 'Installing Second Life...'
+
+# Creating tempdir under /tmp means it's possible that tempdir is on a
+# different filesystem than INSTALL_DIR. One is tempted to create tempdir on a
+# path derived from `dirname INSTALL_DIR` -- but it seems modern 'mv' can
+# handle moving across filesystems??
+tempdir="$(mktemp -d)"
+tempinstall="$tempdir/install"
+# capture the actual error message, if any
+err="$(mkdir -p "$tempinstall" 2>&1)" || fail "$err"
+cleanup rm -rf "$tempdir"
+
+# If we already knew the name of the tarball's top-level directory, we could
+# just move that when all was said and done. Since we don't, untarring to the
+# 'install' subdir with --strip 1 effectively renames that top-level
+# directory.
+# untar failures tend to be voluminous -- don't even try to capture, just log
+tar --strip 1 -xjf "$tarball" -C "$tempinstall" || fail "Untar command failed"
+
+INSTALL_DIR="$(cd "$mydir/.." ; pwd)"
+
+# Considering we're launched from a subdirectory of INSTALL_DIR, would be
+# surprising if it did NOT already exist...
+if [ -e "$INSTALL_DIR" ]
+then backup="$INSTALL_DIR.backup"
+ backupn=1
+ while [ -e "$backup" ]
+ do backup="$INSTALL_DIR.backup.$backupn"
+ ((backupn += 1))
+ done
+ # on error, fail with actual error message from sudo_mv: permissions,
+ # cross-filesystem mv, ...?
+ sudo_mv "$INSTALL_DIR" "$backup" || fail "$err"
+fi
+# We unpacked the tarball into tempinstall. Move that.
+if ! sudo_mv "$tempinstall" "$INSTALL_DIR"
+then # If we failed to move the temp install to INSTALL_DIR, try to restore
+ # INSTALL_DIR from backup. Save $err because next sudo_mv will trash it!
+ realerr="$err"
+ sudo_mv "$backup" "$INSTALL_DIR"
+ fail "$realerr"
+fi
+
+# Removing the tarball here, rather than with a 'cleanup' action, means we
+# only remove it if we succeeded.
+rm -f "$tarball"
+
+# Launch the updated viewer. Restore original stderr from file descriptor 3,
+# though -- otherwise updater.log gets cluttered with the viewer log!
+"$INSTALL_DIR/secondlife" 2>&3- &
diff --git a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp
index e19d5724f1..759e41ef4c 100644..100755
--- a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp
+++ b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp
@@ -1,4 +1,4 @@
-/**
+/**
* @file llupdaterservice_test.cpp
* @brief Tests of llupdaterservice.cpp.
*
@@ -44,11 +44,16 @@
*****************************************************************************/
LLUpdateChecker::LLUpdateChecker(LLUpdateChecker::Client & client)
{}
-void LLUpdateChecker::check(std::string const & protocolVersion, std::string const & hostUrl,
- std::string const & servicePath, std::string channel, std::string version)
+void LLUpdateChecker::checkVersion(std::string const & urlBase,
+ std::string const & channel,
+ std::string const & version,
+ std::string const & platform,
+ std::string const & platform_version,
+ unsigned char uniqueid[MD5HEX_STR_SIZE],
+ bool willing_to_test)
{}
LLUpdateDownloader::LLUpdateDownloader(Client & ) {}
-void LLUpdateDownloader::download(LLURI const & , std::string const &, std::string const &, bool){}
+void LLUpdateDownloader::download(LLURI const & , std::string const &, std::string const &, std::string const &, std::string const &, bool){}
class LLDir_Mock : public LLDir
{
@@ -63,7 +68,7 @@ class LLDir_Mock : public LLDir
const std::string &mask,
std::string &fname) {}
std::string getCurPath() { return ""; }
- BOOL fileExists(const std::string &filename) const { return false; }
+ bool fileExists(const std::string &filename) const { return false; }
std::string getLLPluginLauncher() { return ""; }
std::string getLLPluginFilename(std::string base_name) { return ""; }
@@ -78,9 +83,27 @@ S32 LLDir::deleteFilesInDir(const std::string &dirname,
void LLDir::setChatLogsDir(const std::string &path){}
void LLDir::setPerAccountChatLogsDir(const std::string &username){}
void LLDir::setLindenUserDir(const std::string &username){}
-void LLDir::setSkinFolder(const std::string &skin_folder){}
+void LLDir::setSkinFolder(const std::string &skin_folder, const std::string& language){}
+std::string LLDir::getSkinFolder() const { return "default"; }
+std::string LLDir::getLanguage() const { return "en"; }
bool LLDir::setCacheDir(const std::string &path){ return true; }
void LLDir::dumpCurrentDirectories() {}
+void LLDir::updatePerAccountChatLogsDir() {}
+
+#include "llviewernetwork.h"
+LLGridManager::LLGridManager() :
+ mGrid("test.grid.lindenlab.com"),
+ mIsInProductionGrid(false)
+{
+}
+std::string LLGridManager::getUpdateServiceURL()
+{
+ return "https://update.secondlife.com/update";
+}
+LLGridManager::~LLGridManager()
+{
+}
+
std::string LLDir::getExpandedFilename(ELLPath location,
const std::string &filename) const
@@ -169,9 +192,11 @@ namespace tut
bool got_usage_error = false;
try
{
- updater.initialize("1.0",test_url, "update" ,test_channel, test_version);
+ unsigned char id1[MD5HEX_STR_SIZE] = "11111111111111111111111111111111";
+ updater.initialize(test_channel, test_version, "win", "1.2.3", id1, true);
updater.startChecking();
- updater.initialize("1.0", "other_url", "update", test_channel, test_version);
+ unsigned char id2[MD5HEX_STR_SIZE] = "22222222222222222222222222222222";
+ updater.initialize(test_channel, test_version, "win", "4.5.6", id2, true);
}
catch(LLUpdaterService::UsageError)
{
@@ -185,7 +210,8 @@ namespace tut
{
DEBUG;
LLUpdaterService updater;
- updater.initialize("1.0", test_url, "update", test_channel, test_version);
+ unsigned char id[MD5HEX_STR_SIZE] = "33333333333333333333333333333333";
+ updater.initialize(test_channel, test_version, "win", "7.8.9", id, true);
updater.startChecking();
ensure(updater.isChecking());
updater.stopChecking();
diff --git a/indra/win_crash_logger/CMakeLists.txt b/indra/win_crash_logger/CMakeLists.txt
index 5329c89554..3c9a4b9756 100644..100755
--- a/indra/win_crash_logger/CMakeLists.txt
+++ b/indra/win_crash_logger/CMakeLists.txt
@@ -21,6 +21,10 @@ include_directories(
${LLXML_INCLUDE_DIRS}
${LLVFS_INCLUDE_DIRS}
)
+include_directories(SYSTEM
+ ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+ ${LLXML_SYSTEM_INCLUDE_DIRS}
+ )
set(win_crash_logger_SOURCE_FILES
win_crash_logger.cpp
@@ -78,6 +82,7 @@ target_link_libraries(windows-crash-logger
gdi32
ole32
oleaut32
+ wininet
Wldap32
)
diff --git a/indra/win_crash_logger/StdAfx.cpp b/indra/win_crash_logger/StdAfx.cpp
index f56711af73..f56711af73 100644..100755
--- a/indra/win_crash_logger/StdAfx.cpp
+++ b/indra/win_crash_logger/StdAfx.cpp
diff --git a/indra/win_crash_logger/StdAfx.h b/indra/win_crash_logger/StdAfx.h
index 35976658ac..35976658ac 100644..100755
--- a/indra/win_crash_logger/StdAfx.h
+++ b/indra/win_crash_logger/StdAfx.h
diff --git a/indra/win_crash_logger/ll_icon.ico b/indra/win_crash_logger/ll_icon.ico
index 566346dfe3..566346dfe3 100644..100755
--- a/indra/win_crash_logger/ll_icon.ico
+++ b/indra/win_crash_logger/ll_icon.ico
Binary files differ
diff --git a/indra/win_crash_logger/llcrashloggerwindows.cpp b/indra/win_crash_logger/llcrashloggerwindows.cpp
index 36d988ead7..36d988ead7 100644..100755
--- a/indra/win_crash_logger/llcrashloggerwindows.cpp
+++ b/indra/win_crash_logger/llcrashloggerwindows.cpp
diff --git a/indra/win_crash_logger/llcrashloggerwindows.h b/indra/win_crash_logger/llcrashloggerwindows.h
index 5c45a998b3..5c45a998b3 100644..100755
--- a/indra/win_crash_logger/llcrashloggerwindows.h
+++ b/indra/win_crash_logger/llcrashloggerwindows.h
diff --git a/indra/win_crash_logger/resource.h b/indra/win_crash_logger/resource.h
index 37a387275e..37a387275e 100644..100755
--- a/indra/win_crash_logger/resource.h
+++ b/indra/win_crash_logger/resource.h
diff --git a/indra/win_crash_logger/win_crash_logger.cpp b/indra/win_crash_logger/win_crash_logger.cpp
index 8e916ae437..8e916ae437 100644..100755
--- a/indra/win_crash_logger/win_crash_logger.cpp
+++ b/indra/win_crash_logger/win_crash_logger.cpp
diff --git a/indra/win_crash_logger/win_crash_logger.h b/indra/win_crash_logger/win_crash_logger.h
index 2cc2cf3dcf..2cc2cf3dcf 100644..100755
--- a/indra/win_crash_logger/win_crash_logger.h
+++ b/indra/win_crash_logger/win_crash_logger.h
diff --git a/indra/win_crash_logger/win_crash_logger.ico b/indra/win_crash_logger/win_crash_logger.ico
index 386883523b..386883523b 100644..100755
--- a/indra/win_crash_logger/win_crash_logger.ico
+++ b/indra/win_crash_logger/win_crash_logger.ico
Binary files differ
diff --git a/indra/win_crash_logger/win_crash_logger.rc b/indra/win_crash_logger/win_crash_logger.rc
index 2819722f63..2819722f63 100644..100755
--- a/indra/win_crash_logger/win_crash_logger.rc
+++ b/indra/win_crash_logger/win_crash_logger.rc
diff --git a/indra/win_updater/CMakeLists.txt b/indra/win_updater/CMakeLists.txt
index 210486c668..210486c668 100644..100755
--- a/indra/win_updater/CMakeLists.txt
+++ b/indra/win_updater/CMakeLists.txt
diff --git a/indra/win_updater/updater.cpp b/indra/win_updater/updater.cpp
index aeab5a3b13..aeab5a3b13 100644..100755
--- a/indra/win_updater/updater.cpp
+++ b/indra/win_updater/updater.cpp